Search code examples
javasslx509certificatebouncycastle

org.bouncycastle.tls.crypto.TlsCertificate getSubject() and other getters


I have a client that connects to https servers using bouncycastle (ver 1.66)

tlsClientProtocol.connect(new DefaultTlsClient(new BcTlsCrypto(new SecureRandom())) {

                @Override
                public TlsAuthentication getAuthentication() throws IOException {
                    return new ServerOnlyTlsAuthentication() {
                        @Override
                        public void notifyServerCertificate(TlsServerCertificate tsc) throws IOException {
                                 // validate srvCert here. here is the problem
                                 TlsCertificate srvCert = tsc.getCertificate().getCertificateAt(0);
                        }
                    };
                }
            });

"srvCert" is an instance of org.bouncycastle.tls.crypto.TlsCertificate, how can I convert it to org.bouncycastle.asn1.x509.Certificate like the old version of BouncyCastle or how can I get "NotBefore", "NotAfter", "Subject"...etc.

PS: I don't care about the issuer chain for now, I just want to print out all the details of the end certificate, also BcTlsCertificate is just as useless as the interface TlsCertificate.

The BouncyCastle docs are no help, and I'm new to this library, and the examples on the internet are old (before the changes of 1.6 if I'm not wrong)

Edit: Just to be clear, the interface org.bouncycastle.tls.crypto.TlsCertificate does not have the methods I need, this class does: org.bouncycastle.asn1.x509.Certificate. But in the last version the method signature was changed to give you the useless class instead.


Solution

  • BouncyCastle has a lot of getInstance(Object) methods, which allow you to transform an object into another if it makes sense. To find which transformations are supported the easiest way is to look at the source code.

    In your case if tlsCertificate contains your instance of org.bouncycastle.tls.crypto.TlsCertificate, you can get a org.bouncycastle.asn1.x509.Certificate with:

    final Certificate certificate = Certificate.getInstance(tlsCertificate.getEncoded());
    

    However instead of transforming the TlsCertificate into an ASN.1 structure representation I would rather transform it into JCE's java.security.cert.X509Certificate:

    final X509Certificate x509Certificate;
    if (tlsCertificate instanceof JcaTlsCertificate) {
        x509Certificate = ((JcaTlsCertificate) tlsCertificate).getX509Certificate();
    } else {
        final CertificateFactory factory = CertificateFactory.getInstance("X.509");
        x509Certificate = (X509Certificate) factory.generateCertificate(new ByteArrayInputStream(tlsCertificate.getEncoded()));
    }