wstrange / asn1lib

Dart ASN1 Encoder / Decoder
BSD 2-Clause "Simplified" License
30 stars 31 forks source link

Re-parsing an OCTET STRING with object identifiers results in invalid OIDs #57

Closed JChrist closed 2 years ago

JChrist commented 3 years ago

Trying to parse the extKeyUsage OIDs of a key, I attempt to re-parse the OCTET STRING in order to get the sequence of the contained OIDs. However, one of the resulting OIDs is invalid, it seems to carry extra characters.

The public key I'm trying to parse is the one specified here. The PEM encoded string is the one under the field CERTIFICATE.

Examining the key online here shows that it contains 3 OIDs under extKeyUsage

A sample test case to demonstrate this is:

test('test key ext key usage decoding', () async {
    final pem = r'MIICozCCAkqgAwIBAgIJAJQcWeYoxjoUMAoGCCqGSM49BAMCMIGMMQswCQYDVQQGEwJDWTEQMA4GA1UECAwHTmljb3NpYTEQMA4GA1UEBwwHTmljb3NpYTEbMBkGA1UECgwSTWluaXN0cnkgb2YgSGVhbHRoMSMwIQYDVQQLDBpOYXRpb25hbCBlSGVhbHRoIEF1dGhvcml0eTEXMBUGA1UEAwwOQ1NDQV9ER0NfQ1lfMDEwHhcNMjEwNjAyMTAzMjUxWhcNMjMwNTIzMTAzMjUxWjCBiDELMAkGA1UEBhMCQ1kxEDAOBgNVBAgMB05pY29zaWExEDAOBgNVBAcMB05pY29zaWExIzAhBgNVBAoMGk5hdGlvbmFsIGVIZWFsdGggQXV0aG9yaXR5MRYwFAYDVQQLDA1JVCBEZXBhcnRtZW50MRgwFgYDVQQDDA9EU0NfRVVEQ0NfQ1lfMDMwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAATjp3KNE+tnRdM1roEggJfIAPeQm8VFcbdBLfaItNCTJTlMBsY1eqdMzhXDkzxSRXpYC0HESHjEseG+EF8otEHDo4GWMIGTMC8GA1UdHwQoMCYwJKAioCCGHmh0dHA6Ly9jcmwubmVoYS5nb3YuY3kvZHNjLmNybDAzBgNVHSUELDAqBgwrBgEEAQCON49lAQEGDCsGAQQBAI43j2UBAgYMKwYBBAEAjjePZQEDMCsGA1UdEAQkMCKADzIwMjEwNjA2MDAwMDAwWoEPMjAyMzA2MDYwMDAwMDBaMAoGCCqGSM49BAMCA0cAMEQCICdei2wUg1ze7RsTr+nvuhf9NgrPqQefbGYDcnHaCQZYAiBuHa0onvEeo7ViG6kYXW1r45AwIDaiHBjMNeOzmFeBTg==';
    final parser = ASN1Parser(base64Decode(pem));
    final seq = parser.nextObject() as ASN1Sequence;
    final ekuObj = (seq.elements[0] as ASN1Sequence).elements[7];
    final ekuParse = ASN1Parser(ekuObj.valueBytes());
    final ekuSeq = (ekuParse.nextObject() as ASN1Sequence).elements[1] as ASN1Sequence;
    final ekuOctet = ekuSeq.elements[1] as ASN1OctetString;
    final octetParse = ASN1Parser(ekuOctet.valueBytes());
    final octetSeq = octetParse.nextObject() as ASN1Sequence;
    print("octetSeq is: $octetSeq");
    expect((octetSeq.elements[0] as ASN1ObjectIdentifier).identifier, '1.3.6.1.4.1.0.1847.2021.1.1');
    expect((octetSeq.elements[1] as ASN1ObjectIdentifier).identifier, '1.3.6.1.4.1.0.1847.2021.1.2');
    expect((octetSeq.elements[2] as ASN1ObjectIdentifier).identifier, '1.3.6.1.4.1.0.1847.2021.1.3');
  });

This test will fail on the second expectation, with:

Expected: '1.3.6.1.4.1.0.1847.2021.1.2'
  Actual: '1.3.6.1.4.1.0.1847.2021.1.2.6.12.43.6.1.4.1.0.1847.2021.1.3'
wstrange commented 3 years ago

I think you will need to step through this with a debugger. It seems like some sequence is not delimited correctly.

I assume you have tried different certs, to rule out an issue with the cert itself?

JChrist commented 3 years ago

When parsing this with asn1 from pointycastle, it returns the 3 OIDs exactly as expected, this is what made me think there's something wrong with asn1lib.

wstrange commented 2 years ago

@JChrist Better late than never, but I just pushed v1.2.1 which fixes your test case.