Pregunta

I need some help ensuring that our PKI infrastructure is secure. This is how it works:

  • We have one (self-signed) CA cert that our server has full control over.
  • All clients (written in Java) are configured with a trust-store that only contains this CA-cert.
  • During installation of a client the server issues a client certificate (with it's client-id as CN) that is signed by our CA cert.
  • The clients are then able to connect to each other and when the connection is established a mutual client authentication is performed by validating the clients' respective cert. We initialize the TrustManager that handles the clients' authentication like this:

.

private TrustManager[] getClientCATrustManagers() throws NoSuchAlgorithmException, IOException, KeyStoreException, CertificateException {       
    TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance("PKIX");
    KeyStore trustStore = getClientCATrustStore();
    trustManagerFactory.init(trustStore);

    return trustManagerFactory.getTrustManagers();
}

getClientCATrustStore() returns the trust-store that only contains our CA.

This leads me to my question. My understanding of chain validation is that as long as the root of the chain is trusted and none of the certs along the chain have expired the chain is considered valid. What concerns me about this is that I then see the risk that the client will be able to use it's own cert to issue new certs. Is that a potential risk and if so, how do I prevent it? I see the two potential solutions:

  1. I create my own TrustManager that prevents this. Are there any implementations that already does this?
  2. When the client cert is issued by the server I somehow specify that the client cert is not allowed to issue it's own certs. Is this possible and if so, how?
¿Fue útil?

Solución

You are correct about a certificate chain being valid and trusted if the root is trusted, and all the intermediate certs are present and valid.

And you are also correct about the potential risk of a client issuing another cert under their own. But there are ways to mitigate this risk.

X509 certificates (version 3) contain extensions that indicate what they are allowed to do or not do.

For example there are 2 specific sections that you would probably be interested in:

  • Basic Constraints

  • Key Usage

The Basic Constraints identifies if the certificate is a CA or not, which means it can only be used to verify a certificate signature if it is designated as a CA itself. It also specifies a path length. This limits the number of CA intermediate certs this CA can sign/issue. A good explanation of this path length is in this SO question. It sounds like you would want a path length of 0 on the CA certificate.

Key Usage indicates what this entity is allowed to do. Typically, CA certs have the following key usage attributes: Certificate Signing, CRL Signing. Whereas non-CA or "End entity" certificates can have: Digital Signature, Non-Repudiation, Key Encipherment, Data Encipherment.

These extensions are all governed by RFC5280.

And here is the important part. For these certificate extensions to mean anything, they have to be checked and enforced by the application using them.

Your client app can look at the extensions and verify that the path length of the other client's cert is 0 (meaning there are no intermediate certs between the CA and the client cert).

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top