How to create a parseable instance of BouncyCastle Extension object?
The BouncyCastle libraries provide a systematic and simple set of APIs and tools to work with encryption and encoding of data to be used in secure communication channels like HTTPS. The X.509 standard is the standard for creating certificates issued to Certificate Authorities (CA) and End Entities.
The solution is to pass the OID, isCritical and Value fields of the org.bouncycastle.asn1.x509.Extension object.
But oh wait, you see that org.bouncycastle.asn1.x509.Extension provides two methods that return value, namely:
The getParsedValue() should be used instead to get the extension properly loaded into the java.security.cert.X509Certificate object as shown below:
Please leave your comments on this article.
Jave provides the X509Certificate class to create X.509 certificates. It also provides the concept of Certificate Extensions to supply additional information about the subject (often called "Subject Principal") for which the certificate has been issued.
The BouncyCastle libraries provide a convenient way to add a Certificate Extension to an instance of X509Certificate class as shown below:
import org.bouncycastle.asn1.x509.Extension;But in the above code snippet, instead of passing the values to the addExtension method, if you have an instance of org.bouncycastle.asn1.x509.Extension object, how would you use it? Unfortunately the org.bouncycastle.cert.X509V3CertificateBuilder does not provide a
import org.bouncycastle.cert.X509V3CertificateBuilder;
....
...
String caName = ...
String subjectName = ...
KeyPair pair = KeyGenerator.getInstance("RSA").generateKeyPair();
X509v3CertificateBuilder builder = new X509v3CertificateBuilder(
createSimpleDN(caName), valueOf(System.currentTimeMillis()),
notBefore, notAfter, createSimpleDN(subjectName),
getInstance(pair.getPublic().getEncoded()));
builder.addExtension("1.3.6.1.5.5.7.48.1", false, new DERIA5String("http://crl.cacert.org/revoke.crl") // Sample CRL
builder.addExtension(<extension object>) // not available, oops!!variant.
The solution is to pass the OID, isCritical and Value fields of the org.bouncycastle.asn1.x509.Extension object.
But oh wait, you see that org.bouncycastle.asn1.x509.Extension provides two methods that return value, namely:
- getExtValue - this returns the ASN1OctetString corresponding to the value used when creating the instance of org.bouncycastle.asn1.x509.Extensio)
- getParsedValue - this returns the corresponding ASN1Primitive of the value set during object construction
Both seem to be equally applicable/correct. Which one do you use?
Turns out that if you use getExtValue(), you will see the
Invalid encoding exceptionwhen the extension is stored in the java.security.cert.X509Certificate object (i.e. if you try to fetch the extension value from the object)
The getParsedValue() should be used instead to get the extension properly loaded into the java.security.cert.X509Certificate object as shown below:
builder.addExtension(extension.getExtOid(), extension.isCritical(), extension.getParsedValue());Hope that this article helps when you are stuck with a similar encoding exception as I faced.
Please leave your comments on this article.