bc-java icon indicating copy to clipboard operation
bc-java copied to clipboard

The value of the authorityCertSerialNumber field was incorrectly parsed by Bouncy Castle 1.80.

Open onepeople158 opened this issue 9 months ago • 2 comments

Hello Developer,

I have a CRL file, and the value of the authorityCertSerialNumber field in its AKI extension is -36. However, when I use Bouncy Castle 1.80 to parse this CRL file, the value returned is the hexadecimal number dc, which corresponds to the decimal number 220. This is completely different from -36, so is this a parsing bug?

Test Case:

crl_aki_serial-36.zip

Code:

import java.io.InputStream;
import java.io.FileInputStream;
import org.bouncycastle.asn1.x509.CertificateList;
import org.bouncycastle.cert.X509CRLHolder;
import org.bouncycastle.asn1.ASN1ObjectIdentifier;
import org.bouncycastle.asn1.x509.Extension;
import org.bouncycastle.asn1.*;

public class CRLParserExample_CRL_aki_serial {
    public static void main(String[] args) throws Exception {
        if (args.length != 1) {
            System.out.println("Usage: java CRLParserExample3 <path-to-crl-file>");
            return;
        }
        String crlPath = args[0];
        
        InputStream inputStream = new FileInputStream(crlPath);

        X509CRLHolder crlHolder = new X509CRLHolder(inputStream);

        ASN1ObjectIdentifier oid = new ASN1ObjectIdentifier("2.5.29.35"); 

        Extension extension = crlHolder.getExtension(oid);
        
        ASN1Encodable parsedValue =extension.getParsedValue();
        ASN1Sequence sequence = (ASN1Sequence) parsedValue;
        System.out.println(sequence.getObjectAt(2));
        
    } 
}

onepeople158 avatar Apr 14 '25 02:04 onepeople158

The issue here is really with the incomplete ASN.1 parsing. Element 2 of the sequence still has an unresolved tag, which in this example is a DLTaggedObject holding a DEROctetString. The parser cannot resolve tags until user code tells it how to do so; until then it holds (e.g. in this case) the contents as an OCTET STRING internally. So your example prints "[CONTEXT 2]#dc", with the #dc being the raw contents bytes.

Once the tag is resolved as an INTEGER the value will be interpreted correctly. e.g.:

//        Object authCertSerial = sequence.getObjectAt(2);
        AuthorityKeyIdentifier aki = AuthorityKeyIdentifier.getInstance(sequence);
        Object authCertSerial = aki.getAuthorityCertSerialNumber();

        System.out.println(authCertSerial);

which prints "-36" as expected.

peterdettman avatar Apr 14 '25 09:04 peterdettman

The issue here is really with the incomplete ASN.1 parsing. Element 2 of the sequence still has an unresolved tag, which in this example is a DLTaggedObject holding a DEROctetString. The parser cannot resolve tags until user code tells it how to do so; until then it holds (e.g. in this case) the contents as an OCTET STRING internally. So your example prints "[CONTEXT 2]#dc", with the #dc being the raw contents bytes.

Once the tag is resolved as an INTEGER the value will be interpreted correctly. e.g.:

//        Object authCertSerial = sequence.getObjectAt(2);
        AuthorityKeyIdentifier aki = AuthorityKeyIdentifier.getInstance(sequence);
        Object authCertSerial = aki.getAuthorityCertSerialNumber();

        System.out.println(authCertSerial);

which prints "-36" as expected.

Thank you for your reply, I understand now.

onepeople158 avatar Apr 14 '25 11:04 onepeople158

Resolved.

dghgit avatar Aug 11 '25 04:08 dghgit