Obtain root and intermediate certificates from end entities


uprising:

Still new to cryptography, I stumble across something simple every day. Today is just one of those days.

I want to validate smime messages in Java using the bouncy castle library, I think I almost got it, but the current problem is the construction of the PKIXparameters object. Suppose, I have an end-entity x509 certificate with the following structure:

root certificate
 +->intermediate certificate
    +->end-entity certificate

In order to validate the message, I need to establish the chain of trust first, but I can't figure out how to extract the root and intermediate certificates from the end entity.

I tried using the terminal entity as root, but it didn't work:

InputStream isCert = GetFISCertificate();

List list = new ArrayList();
X509Certificate rootCert = (X509Certificate) certificateFactory.generateCertificate(isCert);
list.add(rootCert);
CollectionCertStoreParameters params = new CollectionCertStoreParameters(list);
CertStore store = CertStore.getInstance("Collection", params, BC);

//create cert path
List certChain = new ArrayList();
certChain.add(rootCert);
CertPath certPath = certificateFactory.generateCertPath(certChain);
Set trust = Collections.singleton(new TrustAnchor(rootCert, null));

//validation
CertPathValidator certPathValidator = CertPathValidator.getInstance("PKIX", BC);
PKIXParameters pKIXParameters = new PKIXParameters(trust);
pKIXParameters.addCertStore(store);
pKIXParameters.setDate(new Date());
try {
CertPathValidatorResult result = certPathValidator.validate(certPath, pKIXParameters);
System.out.println("certificate path validated");

} catch (CertPathValidatorException e) {
System.out.println("validation failed on certificate number " + e.getIndex() + ", details: " + e.getMessage());
}

Got this exception:

validation failed on certificate number -1, details: Trust anchor for certification path not found.

By the way, can I just use the end-entity certificate to verify the message as if it were a self-signed certificate?

user7605325:

I have used BouncyCastle 1.56 for this test .

One way to obtain an issuer certificate from an end entity is to look for the " Authorized Information Access" extension .

This extension MAY be present (not mandatory) and MAY contain a URL for obtaining an issuer certificate (the issuer is a certificate "on top" of the current certificate, so the issuer of the end entity is the intermediary and the intermediary entity's The issuer is the root).

You can get this expanded value via BouncyCastle:

import java.security.cert.X509Certificate;
import org.bouncycastle.asn1.x509.AccessDescription;
import org.bouncycastle.asn1.x509.AuthorityInformationAccess;
import org.bouncycastle.asn1.x509.Extension;
import org.bouncycastle.asn1.x509.GeneralName;
import org.bouncycastle.asn1.x509.X509ObjectIdentifiers;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.x509.extension.X509ExtensionUtil;

X509Certificate cert = // end entity certificate

// get Authority Information Access extension (will be null if extension is not present)
byte[] extVal = cert.getExtensionValue(Extension.authorityInfoAccess.getId());
AuthorityInformationAccess aia = AuthorityInformationAccess.getInstance(X509ExtensionUtil.fromExtensionValue(extVal));

// check if there is a URL to issuer's certificate
AccessDescription[] descriptions = aia.getAccessDescriptions();
for (AccessDescription ad : descriptions) {
    // check if it's a URL to issuer's certificate
    if (ad.getAccessMethod().equals(X509ObjectIdentifiers.id_ad_caIssuers)) {
        GeneralName location = ad.getAccessLocation();
        if (location.getTagNo() == GeneralName.uniformResourceIdentifier) {
            String issuerUrl = location.getName().toString();
            // http URL to issuer (test in your browser to see if it's a valid certificate)
            // you can use java.net.URL.openStream() to create a InputStream and create
            // the certificate with your CertificateFactory
            URL url = new URL(issuerUrl);
            X509Certificate issuer = (X509Certificate) certificateFactory.generateCertificate(url.openStream());
        }
    }
}

So you can use this code with end entity certificate to get intermediate certificate. Then, use it again with the intermediate to get the root.

Then, add the root directory to your directory and verify it works.TrustAnchor


Note: However, as I said, this extension is not mandatory and may not exist. In this case, getExtensionValuewill return null, and the only alternative I know of is to search google for certificates and download them (these certificate chains are usually public and not hard to find)

Related


Obtain root and intermediate certificates from end entities

uprising: Still new to cryptography, I stumble across something simple every day. Today is just one of those days. I want to validate smime messages in Java using the bouncy castle library, I think I almost got it, but the current problem is the construction o

Chain get all certificates; intermediate and root

Neil Traft: I'm using Apache's HTTPClient in Java and trying to connect to graph.facebook.com. I get the "SSLPeerUnverifiedException: No peer certificate" error, so I guess Facebook's CA is not in the default keystore. So I need to create my own keystore with

Chain get all certificates; intermediate and root

Neil Traft: I'm using Apache's HTTPClient in Java and trying to connect to graph.facebook.com. I get the "SSLPeerUnverifiedException: No peer certificate" error, so I guess Facebook's CA is not in the default keystore. So I need to create my own keystore with

Chain get all certificates; intermediate and root

Neil Traft: I'm using Apache's HTTPClient in Java and trying to connect to graph.facebook.com. I get the "SSLPeerUnverifiedException: No peer certificate" error, so I guess Facebook's CA is not in the default keystore. So I need to create my own keystore with

Install intermediate CA certificates

Harvey I have a Kubernetes cluster hosting my own docker registry built with the following docs : https://github.com/kubernetes/kubernetes/tree/master/cluster/addons/registry and https://github.com/kubernetes/kubernetes /blob/master/cluster/addons/registry/tls

Are intermediate certificates cached in Firefox?

Kit Sunde If someone visits Site A with a GoDaddy-issued certificate that also provides an intermediate certificate between GoDaddy and its CA, then Firefox will cache that intermediate certificate and compare it with a site that also has a GoDaddy-issued cert

Are intermediate certificates cached in Firefox?

Kit Sunde If someone visits Site A with a GoDaddy-issued certificate that also provides an intermediate certificate between GoDaddy and its CA, then Firefox will cache that intermediate certificate and compare it with a site that also has a GoDaddy-issued cert

Verify signature without intermediate certificates

Lexicore Is it possible to verify signatures with only ancestor or root certificates in the hierarchy? Disclaimer: I'm new to certificate handling, so please forgive the simplistic terminology. Consider the following situation. We have two parties ( for the id

Verify signature without intermediate certificates

Lexicore Is it possible to verify signatures with only ancestor or root certificates in the hierarchy? Disclaimer: I'm new to certificate handling, so please forgive the simplistic terminology. Consider the following situation. We have two parties ( for the id

Heroku SSL: Install intermediate certificates?

Paul Sanwald My registrar gandi gave me the intermediate certificate to install, so I have 3 files: Private key file (server.key) Certificate file (mycert.crt) Intermediate Certificate (GandiSomething.pem) I am using SSL Beta service on heroku . heroku CLI her

Heroku SSL: Install intermediate certificates?

Paul Sanwald My registrar gandi gave me the intermediate certificate to install, so I have 3 files: Private key file (server.key) Certificate file (mycert.crt) Intermediate Certificate (GandiSomething.pem) I am using SSL Beta service on heroku . heroku CLI her

Verify signature without intermediate certificates

Lexicore Is it possible to verify signatures with only ancestor or root certificates in the hierarchy? Disclaimer: I'm new to certificate handling, so please forgive the simplistic terminology. Consider the following situation. We have two parties ( for the id

Nginx does not provide intermediate certificates

User 1094128 I'm trying to install a ssl certificate on Nginx (Laravel Forge actually). I have connected the certificate with intermediate and there are no errors in the Nginx error log. However, it's not trusted in mobile Chrome - desktop only. Looking at the

Verify signature without intermediate certificates

Lexicore Is it possible to verify signatures with only ancestor or root certificates in the hierarchy? Disclaimer: I'm new to certificate handling, so please forgive the simplistic terminology. Consider the following situation. We have two parties ( for the id

HTML entities for intermediate points

French I am looking for the html code for that point. Not a dot at the end of a sentence, but a dot used to separate items horizontally. Item 1 . Item 2 . Item 3 The traditional dot is at the bottom of the row, while the dot I'm looking for is in the middle.