- marked as enhancement
Handle X509 certificates in base64 without prefix/suffix
The method fromBase64Der
https://bitbucket.org/b_c/jose4j/src/master/src/main/java/org/jose4j/keys/X509Util.java#lines-108 tries to parse base64 certificate to X509Certificate
using https://docs.oracle.com/javase/7/docs/api/java/security/cert/CertificateFactory.html#generateCertificate(java.io.InputStream).
If the remote base64 certificate does not start with “-----BEGIN CERTIFICATE-----” and ends with “-----END CERTIFICATE-----” the parsing fails with:
Unable to convert <X> value to X509Certificate: java.security.cert.CertificateException: Unable to initialize, java.io.IOException: Short read of DER length; caused by: java.security.cert.CertificateException: Unable to initialize, java.io.IOException: Short read of DER length; caused by: java.io.IOException: Short read of DER length).
Can we check in this method if the string has the necesarry prefix/suffix and add them otherwise?
Thanks
Comments (8)
-
reporter -
Hi Fabricio,
That method
fromBase64Der
decodes the base64 first (https://bitbucket.org/b_c/jose4j/src/dad416151f06bcffb8ffc1a2c31b1fe741c29256/src/main/java/org/jose4j/keys/X509Util.java#lines-110) and passes the binary togenerateCertificate
, which does not need the “-----BEGIN/END CERTIFICATE-----” header/footer - the CertificateFactory.generateCertificate javadoc says that only applies to printable (Base64) encoding not binary. In fact, thefromBase64Der
method only will parse encoded certs without the header/footer. The method is meant to help processing of the JOSE’sx5c
, which has base64-encoded DER certs - see https://www.rfc-editor.org/rfc/rfc7517#section-4.7 and an example at https://www.rfc-editor.org/rfc/rfc7517#appendix-BThis unit test also shows
fromBase64Der
processing input without the header/footer https://bitbucket.org/b_c/jose4j/src/master/src/test/java/org/jose4j/keys/X509UtilTest.java#lines-37So I’m not sure what’s causing the issue you are running into (probably some kind of encoding something) but what you’ve described here isn’t it.
And changing the
fromBase64Der
method to do something different/more than working withx5c
values isn’t really in scope.
-
reporter Thank you for your response! You are right. It seems that the service I am consuming is exposing the base64 public key in the x5c field, instead of the certificate. Is the service wrong?
-
Yeah, x5c is defined as follows (which is definitely not the base64 public key)
https://www.rfc-editor.org/rfc/rfc7517#section-4.7 :
4.7. "x5c" (X.509 Certificate Chain) Parameter
The "x5c" (X.509 certificate chain) parameter contains a chain of one
or more PKIX certificates [RFC5280]. The certificate chain is
represented as a JSON array of certificate value strings. Each
string in the array is a base64-encoded (Section 4 of [RFC4648] --
not base64url-encoded) DER [ITU.X690.1994] PKIX certificate value.
The PKIX certificate containing the key value MUST be the first
certificate. This MAY be followed by additional certificates, with
each subsequent certificate being the one used to certify the
previous one. The key in the first certificate MUST match the public
key represented by other members of the JWK. Use of this member is
OPTIONAL.
-
reporter - changed status to resolved
-
reporter As a workaround, I am using the JwksVerificationKeyResolver like this:
byte[] byteKey = Base64.getDecoder().decode(key.getX5c()[0]); //I have the public key here X509EncodedKeySpec X509publicKey = new X509EncodedKeySpec(byteKey); KeyFactory kf = KeyFactory.getInstance(key.getKty()); Key k = kf.generatePublic(X509publicKey); JsonWebKey jwk = JsonWebKey.Factory.newJwk(k); jwk.setKeyId(key.getKid()); jwk.setAlgorithm(key.getKty()); jwk.setUse(key.getUse()); JsonWebKeySet jsonWebKeySet = new JsonWebKeySet(jwk); JwksVerificationKeyResolver jwksResolver = new JwksVerificationKeyResolver(jsonWebKeySet.getJsonWebKeys());
This way, I can generate a resolver without having a certificate. Is there a way of generating a HttpsJwksVerificationKeyResolver without the certificate and only with the public key?
Thanks
-
HttpsJwksVerificationKeyResolver doesn’t need certificates at all - it uses the public keys from JWKs. But a malformed x5c in the JWKs might cause problems. I’m not sure, to be honest.
-
reporter Thank you very much for your help
- Log in to comment