blob: 3da0a7910e241321ab7ace80b063e8c764e4b2db [file] [log] [blame]
import 'dart:convert';
import 'dart:typed_data';
import 'package:pointycastle/asn1.dart';
import 'package:pointycastle/asn1/asn1_object.dart';
import 'package:pointycastle/asn1/asn1_parser.dart';
import 'package:pointycastle/asn1/primitives/asn1_bit_string.dart';
import 'package:pointycastle/asn1/primitives/asn1_integer.dart';
import 'package:pointycastle/asn1/primitives/asn1_null.dart';
import 'package:pointycastle/asn1/primitives/asn1_object_identifier.dart';
import 'package:pointycastle/asn1/primitives/asn1_printable_string.dart';
import 'package:pointycastle/asn1/primitives/asn1_sequence.dart';
import 'package:pointycastle/asn1/primitives/asn1_set.dart';
import 'package:test/test.dart';
void main() {
///
/// Test simple structur
///
/// ```
/// SEQUENCE (2 elem)
/// OBJECT IDENTIFIER 1.2.840.113549.1.1.11 sha256WithRSAEncryption (PKCS #1)
/// NULL
/// ```
///
test('Test nextObject 1', () {
var bytes = Uint8List.fromList([
0x30,
0x0D,
0x06,
0x09,
0x2A,
0x86,
0x48,
0x86,
0xF7,
0x0D,
0x01,
0x01,
0x0B,
0x05,
0x00
]);
var parser = ASN1Parser(bytes);
var sequence = parser.nextObject() as ASN1Sequence;
expect(sequence.encodedBytes!.length, sequence.totalEncodedByteLength);
expect(sequence.elements!.length, 2);
expect(sequence.elements!.elementAt(0) is ASN1ObjectIdentifier, true);
expect(sequence.elements!.elementAt(1) is ASN1Null, true);
});
///
/// Test simple structur
///
/// ```
/// SEQUENCE (4 elem)
/// SET (1 elem)
/// SEQUENCE (2 elem)
/// OBJECT IDENTIFIER 2.5.4.6 countryName (X.520 DN component)
/// PrintableString US
/// SET (1 elem)
/// SEQUENCE (2 elem)
/// OBJECT IDENTIFIER 2.5.4.10 organizationName (X.520 DN component)
/// PrintableString DigiCert Inc
/// SET (1 elem)
/// SEQUENCE (2 elem)
/// OBJECT IDENTIFIER 2.5.4.11 organizationalUnitName (X.520 DN component)
/// PrintableString www.digicert.com
/// SET (1 elem)
/// SEQUENCE (2 elem)
/// OBJECT IDENTIFIER 2.5.4.3 commonName (X.520 DN component)
/// PrintableString Thawte RSA CA 2018
/// ```
///
test('Test nextObject 2', () {
var bytes = Uint8List.fromList([
0x30,
0x5C,
0x31,
0x0B,
0x30,
0x09,
0x06,
0x03,
0x55,
0x04,
0x06,
0x13,
0x02,
0x55,
0x53,
0x31,
0x15,
0x30,
0x13,
0x06,
0x03,
0x55,
0x04,
0x0A,
0x13,
0x0C,
0x44,
0x69,
0x67,
0x69,
0x43,
0x65,
0x72,
0x74,
0x20,
0x49,
0x6E,
0x63,
0x31,
0x19,
0x30,
0x17,
0x06,
0x03,
0x55,
0x04,
0x0B,
0x13,
0x10,
0x77,
0x77,
0x77,
0x2E,
0x64,
0x69,
0x67,
0x69,
0x63,
0x65,
0x72,
0x74,
0x2E,
0x63,
0x6F,
0x6D,
0x31,
0x1B,
0x30,
0x19,
0x06,
0x03,
0x55,
0x04,
0x03,
0x13,
0x12,
0x54,
0x68,
0x61,
0x77,
0x74,
0x65,
0x20,
0x52,
0x53,
0x41,
0x20,
0x43,
0x41,
0x20,
0x32,
0x30,
0x31,
0x38
]);
var parser = ASN1Parser(bytes);
var sequence = parser.nextObject() as ASN1Sequence;
expect(sequence.encodedBytes!.length, sequence.totalEncodedByteLength);
expect(sequence.elements!.length, 4);
expect(sequence.elements!.elementAt(0) is ASN1Set, true);
expect(sequence.elements!.elementAt(1) is ASN1Set, true);
expect(sequence.elements!.elementAt(2) is ASN1Set, true);
expect(sequence.elements!.elementAt(3) is ASN1Set, true);
var set1 = sequence.elements!.elementAt(0) as ASN1Set;
expect(set1.elements!.length, 1);
expect(set1.elements!.elementAt(0) is ASN1Sequence, true);
var seq1 = set1.elements!.elementAt(0) as ASN1Sequence;
expect(seq1.elements!.length, 2);
expect(seq1.elements!.elementAt(0) is ASN1ObjectIdentifier, true);
expect(seq1.elements!.elementAt(1) is ASN1PrintableString, true);
var oi1 = seq1.elements!.elementAt(0) as ASN1ObjectIdentifier;
var string1 = seq1.elements!.elementAt(1) as ASN1PrintableString;
expect(oi1.objectIdentifierAsString, '2.5.4.6');
expect(string1.stringValue, 'US');
var set2 = sequence.elements!.elementAt(1) as ASN1Set;
expect(set2.elements!.length, 1);
expect(set2.elements!.elementAt(0) is ASN1Sequence, true);
var seq2 = set2.elements!.elementAt(0) as ASN1Sequence;
expect(seq2.elements!.length, 2);
expect(seq2.elements!.elementAt(0) is ASN1ObjectIdentifier, true);
expect(seq2.elements!.elementAt(1) is ASN1PrintableString, true);
var oi2 = seq2.elements!.elementAt(0) as ASN1ObjectIdentifier;
var string2 = seq2.elements!.elementAt(1) as ASN1PrintableString;
expect(oi2.objectIdentifierAsString, '2.5.4.10');
expect(string2.stringValue, 'DigiCert Inc');
var set3 = sequence.elements!.elementAt(2) as ASN1Set;
expect(set3.elements!.length, 1);
expect(set3.elements!.elementAt(0) is ASN1Sequence, true);
var seq3 = set3.elements!.elementAt(0) as ASN1Sequence;
expect(seq3.elements!.length, 2);
expect(seq3.elements!.elementAt(0) is ASN1ObjectIdentifier, true);
expect(seq3.elements!.elementAt(1) is ASN1PrintableString, true);
var oi3 = seq3.elements!.elementAt(0) as ASN1ObjectIdentifier;
var string3 = seq3.elements!.elementAt(1) as ASN1PrintableString;
expect(oi3.objectIdentifierAsString, '2.5.4.11');
expect(string3.stringValue, 'www.digicert.com');
var set4 = sequence.elements!.elementAt(3) as ASN1Set;
expect(set4.elements!.length, 1);
expect(set4.elements!.elementAt(0) is ASN1Sequence, true);
var seq4 = set4.elements!.elementAt(0) as ASN1Sequence;
expect(seq4.elements!.length, 2);
expect(seq4.elements!.elementAt(0) is ASN1ObjectIdentifier, true);
expect(seq4.elements!.elementAt(1) is ASN1PrintableString, true);
var oi4 = seq4.elements!.elementAt(0) as ASN1ObjectIdentifier;
var string4 = seq4.elements!.elementAt(1) as ASN1PrintableString;
expect(oi4.objectIdentifierAsString, '2.5.4.3');
expect(string4.stringValue, 'Thawte RSA CA 2018');
});
test('Test parse X509', () {
var pem = '''-----BEGIN CERTIFICATE-----
MIIGuDCCBaCgAwIBAgIQJWoxbMUUPa7apOL527blFzANBgkqhkiG9w0BAQsFADCB
sDELMAkGA1UEBhMCVVMxHTAbBgNVBAoTFFN5bWFudGVjIENvcnBvcmF0aW9uMR8w
HQYDVQQLExZGT1IgVEVTVCBQVVJQT1NFUyBPTkxZMR8wHQYDVQQLExZTeW1hbnRl
YyBUcnVzdCBOZXR3b3JrMUAwPgYDVQQDEzdTeW1hbnRlYyBDbGFzcyAzIEV4dGVu
ZGVkIFZhbGlkYXRpb24gU0hBMjU2IFNTTCBURVNUIENBMB4XDTE2MTExODAwMDAw
MFoXDTE2MTEyNTIzNTk1OVowge8xEzARBgsrBgEEAYI3PAIBAxMCREUxFzAVBgsr
BgEEAYI3PAIBAhMGQmF5ZXJuMRswGQYLKwYBBAGCNzwCAQETClJlZ2Vuc2J1cmcx
HTAbBgNVBA8TFFByaXZhdGUgT3JnYW5pemF0aW9uMRAwDgYDVQQFEwczNDY2NTY1
MQswCQYDVQQGEwJERTENMAsGA1UECAwESGllcjETMBEGA1UEBwwKVGVzdGhhdXNl
bjESMBAGA1UECgwJVGVzdGZpcm1hMRQwEgYDVQQLDAtFbnR3aWNrbHVuZzEWMBQG
A1UEAwwNZXBoZW5vZHJvbS5kZTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC
ggEBALHYKBMxalQNBwqQVS/NE/Y5eTBORjxqY7jC/vZ881G4uMM+AFvt5iFKabjN
wLT9itYFuJ/k5o7kVn93f0eirxrP0e3wPkzwELJIR6AdZo1EsTzGPW0p41PGOjGv
/GPZwFWEfb7C0Wz4v3b3LtBrWYNJ12RswQAtKdNey/1nxZT2UwGdwESBK0Rvh3qt
33Wqkf1t8X627XTD91dkB/brq6oO3m2ZDyhbqDfMiWqUWl2CVnO0A+eFZ5uFFVdm
NPFuhNqgCmZ6TfFkQJQEKuBadHDTj47qjU27lTJjksCHVDs9PzJzkH49zStjk9D4
UkPw7y37xJ/gUK27VhkIC6QBTuECAwEAAaOCAoswggKHMCsGA1UdEQQkMCKCDWVw
aGVub2Ryb20uZGWCEXd3dy5lcGhlbm9kcm9tLmRlMAkGA1UdEwQCMAAwDgYDVR0P
AQH/BAQDAgWgMG8GA1UdIARoMGYwWwYLYIZIAYb4RQEHFwYwTDAjBggrBgEFBQcC
ARYXaHR0cHM6Ly9kLnN5bWNiLmNvbS9jcHMwJQYIKwYBBQUHAgIwGQwXaHR0cHM6
Ly9kLnN5bWNiLmNvbS9ycGEwBwYFZ4EMAQEwKwYDVR0fBCQwIjAgoB6gHIYaaHR0
cDovL3NoLnN5bWNiLmNvbS9zaC5jcmwwHQYDVR0lBBYwFAYIKwYBBQUHAwEGCCsG
AQUFBwMCMB8GA1UdIwQYMBaAFERiHdf3UpjAQwNcU+bmv+ZDJ+tjMFcGCCsGAQUF
BwEBBEswSTAfBggrBgEFBQcwAYYTaHR0cDovL3NoLnN5bWNkLmNvbTAmBggrBgEF
BQcwAoYaaHR0cDovL3NoLnN5bWNiLmNvbS9zaC5jcnQwggEEBgorBgEEAdZ5AgQC
BIH1BIHyAPAAdgAR0wud4RKWE7VpXG+auxQlNw9ew3QWYeKO2GKv4jEwuQAAAVh3
IQXYAAAEAwBHMEUCIAWDOM8fYWHm95CEg8eDf85KvCVzPbTKm2ZcS/7Dx5w7AiEA
k/4u83CLUFizih+iJevMVXPHI99yeb6NT0lQnIZ8MFMAdgCRLn+OXTXy73s/VluY
uYC5VyaVUxTiFkYL1+xTql7swQAAAVh3IQXYAAAEAwBHMEUCIHQR9Geg7t98Gk2t
BSPlHIHDFG+XP5UUKa2eUahE973oAiEA6i8/T8IlppNUXcrMbcjjLLPsaSqd158U
BC44Pr90Nw4wDQYJKoZIhvcNAQELBQADggEBACJqJMVEKtBfmB0mvhFtd5GV7818
G/THYsf1AtMuCt80Rtzm+EXAyBupIhRERa+/J40pAE/ZyhmS5lSOjTzViR1RsIUg
bo190CLpEvKHA7ckBssJRySMFQ6RSPavsOkpHvduCqVS2PSb9W1APFzDJPeC9gaM
/EKIy7iLp2fiBZrYkTCaxYEy0SZGaFkXeHC20/d5PXhnylEXEIPR2aogIlbgzaNg
RVTxIJddHhpHfW5c2lX+ERf3Ni0fcJqcCZBPyGHUDSYqNrDwRLQ6dyVxz1Jl0oAc
+IHuDDDKJ0ewjoXgV+KRXqa7URuonqA5stUl/susZzd4BlT2k/XnuS8+iQc=
-----END CERTIFICATE-----''';
var lines = LineSplitter.split(pem)
.map((line) => line.trim())
.where((line) => line.isNotEmpty)
.toList();
var base64 = lines.sublist(1, lines.length - 1).join('');
var bytes = Uint8List.fromList(base64Decode(base64));
var asn1Parser = ASN1Parser(bytes);
var topLevelSeq = asn1Parser.nextObject() as ASN1Sequence;
expect(topLevelSeq.elements!.length, 3);
expect(topLevelSeq.totalEncodedByteLength, 1724);
expect(topLevelSeq.valueByteLength, 1720);
expect(topLevelSeq.elements!.elementAt(0) is ASN1Sequence, true);
expect(topLevelSeq.elements!.elementAt(1) is ASN1Sequence, true);
expect(topLevelSeq.elements!.elementAt(2) is ASN1BitString, true);
var e1 = topLevelSeq.elements!.elementAt(0) as ASN1Sequence;
var e2 = topLevelSeq.elements!.elementAt(1) as ASN1Sequence;
var e3 = topLevelSeq.elements!.elementAt(2) as ASN1BitString;
expect(e1.elements!.length, 8);
expect(e1.totalEncodedByteLength, 1444);
expect(e1.valueByteLength, 1440);
expect(e1.elements!.elementAt(0) is ASN1Object, true); // 0xA0
expect(e1.elements!.elementAt(1) is ASN1Integer, true);
expect(e1.elements!.elementAt(2) is ASN1Sequence, true);
expect(e1.elements!.elementAt(3) is ASN1Sequence, true);
expect(e1.elements!.elementAt(4) is ASN1Sequence, true);
expect(e1.elements!.elementAt(5) is ASN1Sequence, true);
expect(e1.elements!.elementAt(6) is ASN1Sequence, true);
expect(e1.elements!.elementAt(7) is ASN1Object, true); // 0xA3
var asn1Object = e1.elements!.elementAt(0);
var integer1 =
ASN1Parser(asn1Object.valueBytes).nextObject() as ASN1Integer;
expect(integer1.totalEncodedByteLength, 3);
expect(integer1.valueByteLength, 1);
expect(integer1.integer.toString(), '2');
var integer2 = e1.elements!.elementAt(1) as ASN1Integer;
expect(integer2.totalEncodedByteLength, 18);
expect(integer2.valueByteLength, 16);
expect(
integer2.integer.toString(), '49732821766751726239505489314635506967');
expect(e2.elements!.length, 2);
expect(e2.totalEncodedByteLength, 15);
expect(e2.valueByteLength, 13);
expect(e2.elements!.elementAt(0) is ASN1ObjectIdentifier, true);
expect(e2.elements!.elementAt(1) is ASN1Null, true);
expect(e3.elements, null);
expect(e3.isConstructed, false);
expect(e3.encodedBytes!.length, 261);
expect(e3.valueByteLength, 257);
expect(e3.stringValues!.length, 256);
});
}