Are certificate chains required in the Truststore for Mutual TLS?

In regards to the role of Truststores in the Mutual TLS process in the context of Apigee, I'd like to confirm my understanding of how the Truststore works. For this example Mutual TLS will be implemented with Apigee serving as the server.

Let's say I have client cert (alice.crt) that has been signed by a certificate authority (CA.crt). Three scenarios come to mind for how to configure the Truststore:

1) Add client cert (alice.crt) to the Truststore

2) Add CA cert to the Truststore

3) Add both client cert (alice.crt) and CA cert to the Truststore.

My understanding is that only 2 and 3 will work to verify the client certificate. Option 1 will lead to a certificate error. The reason being that Apigee sees that the cert is signed, looks for the signer in the Truststore and does not accept the cert if it is not found.

If my understanding is correct then, as a consequence, if we have a second client cert (bob.crt) that is signed by the same CA as alice.crt and either option 2 or 3 is implemented, bob.crt will always be accepted. This is because in both option 2 or 3 the CA is present in the current truststore. Note that bob.crt is accepted even though bob.crt is not currently present in the truststore.

I reviewed the explanation at: https://community.apigee.com/questions/70981/tls-keystore-truststore.html

The bit about "you configure Apigee Edge with a Truststore TS1. You load exactly one cert into that truststore: the one for www.upstream.com. Apigee Edge will trust it." has thrown me off a bit as it seems to go counter to the notion that a cert is only accepted when a cert that has signed it is trusted (present in the truststore).

Is there a way to configure Apigee to place a single client cert (alice.crt) in the truststore and have Apigee verify and accept only that cert without also accepting (bob.crt) that was signed by the same CA? I'm familiar with the concept of pulling client.cn and whitelisting using a policy. I just wanted to double check my understanding and make sure that this isn't possible to implement using just the truststore.

Solved Solved
1 2 4,875
1 ACCEPTED SOLUTION

First: The certs in a Truststore are _trust anchors_ from Apigee's perspective.

That means they terminate the trust chain. If you put alice.crt in the TrustStore, then Apigee will treat that cert as trusted, period. It does not matter if alice.crt was self-signed by alice, or if it was signed by Some-Good-CA, or signed by Obviously-Bad-CA. Apigee will trust it, if you put that cert in the truststore.

has thrown me off a bit as it seems to go counter to the notion that a cert is only accepted when a cert that has signed it is trusted (present in the truststore).

Your intuition is in line with how things are intended to work. The intention is that there are very very few trusted root CAs, and then lots of intermediate CAs (sometimes in multiple layers), and then millions and billions of leaf certificates. Trust the roots, and you can have transitive trust to anything the root has signed (directly or indirectly). But the way you wrote it ... "a cert is accepted only when a cert that has signed it is trusted" is not how it actually works. The way it actually works: A cert is accepted when it, or something in its signing chain is trusted.

Normally it is good practice to place only root certs in a truststore. "Root certs" means, certs that are self-signed, and the signer is a well-known, trusted, vetted CA. But Apigee does not restrict which certs you place into your Truststore. If you place an intermediate cert in the trust store, it will be trusted as a certificate authority, or CA.  That means any peer cert signed by that cert, will be trusted. 

Now, as regards to bob.crt, yes, I think you understand it correctly. Suppose you place a CA cert into your truststore. Suppose later that the CA issues certs to bob, alice, and mallory. Apigee will trust all of those certs, because Apigee trusts the CA, by virtue of the CA's cert in the Truststore. (Revocation is a different topic)

All of this assumes that the TLS peers are behaving correctly. Normally a TLS peer will send its cert and the chain of all signing certs down to the root, to the other peer. In some cases a peer may send only its own ("leaf") cert, rather than the full chain. I see this often with Java (or other) application clients that connect into Apigee using a misconfigured keystore. In that case, Apigee will receive only the client's cert (a leaf cert), which is signed by an intermediate CA.  Apigee will then look in the Truststore to try to find a validation path for the client.... . If only the cert for the root (signing) CA is in the Truststore, then Apigee will reject the inbound call as untrusted (as appropriate). The solution is to configure the client's keystore correctly, so that the Java client application will send the full chain of certs during TLS handshake.

Is there a way to configure Apigee to place a single client cert (alice.crt) in the truststore and have Apigee verify and accept only that cert without also accepting (bob.crt) that was signed by the same CA?

Yes, put the cert you would like to trust (eg alice.crt) into the trust store.  And then insure that THAT CERT is never used to sign any other certificates. 

View solution in original post

2 REPLIES 2

First: The certs in a Truststore are _trust anchors_ from Apigee's perspective.

That means they terminate the trust chain. If you put alice.crt in the TrustStore, then Apigee will treat that cert as trusted, period. It does not matter if alice.crt was self-signed by alice, or if it was signed by Some-Good-CA, or signed by Obviously-Bad-CA. Apigee will trust it, if you put that cert in the truststore.

has thrown me off a bit as it seems to go counter to the notion that a cert is only accepted when a cert that has signed it is trusted (present in the truststore).

Your intuition is in line with how things are intended to work. The intention is that there are very very few trusted root CAs, and then lots of intermediate CAs (sometimes in multiple layers), and then millions and billions of leaf certificates. Trust the roots, and you can have transitive trust to anything the root has signed (directly or indirectly). But the way you wrote it ... "a cert is accepted only when a cert that has signed it is trusted" is not how it actually works. The way it actually works: A cert is accepted when it, or something in its signing chain is trusted.

Normally it is good practice to place only root certs in a truststore. "Root certs" means, certs that are self-signed, and the signer is a well-known, trusted, vetted CA. But Apigee does not restrict which certs you place into your Truststore. If you place an intermediate cert in the trust store, it will be trusted as a certificate authority, or CA.  That means any peer cert signed by that cert, will be trusted. 

Now, as regards to bob.crt, yes, I think you understand it correctly. Suppose you place a CA cert into your truststore. Suppose later that the CA issues certs to bob, alice, and mallory. Apigee will trust all of those certs, because Apigee trusts the CA, by virtue of the CA's cert in the Truststore. (Revocation is a different topic)

All of this assumes that the TLS peers are behaving correctly. Normally a TLS peer will send its cert and the chain of all signing certs down to the root, to the other peer. In some cases a peer may send only its own ("leaf") cert, rather than the full chain. I see this often with Java (or other) application clients that connect into Apigee using a misconfigured keystore. In that case, Apigee will receive only the client's cert (a leaf cert), which is signed by an intermediate CA.  Apigee will then look in the Truststore to try to find a validation path for the client.... . If only the cert for the root (signing) CA is in the Truststore, then Apigee will reject the inbound call as untrusted (as appropriate). The solution is to configure the client's keystore correctly, so that the Java client application will send the full chain of certs during TLS handshake.

Is there a way to configure Apigee to place a single client cert (alice.crt) in the truststore and have Apigee verify and accept only that cert without also accepting (bob.crt) that was signed by the same CA?

Yes, put the cert you would like to trust (eg alice.crt) into the trust store.  And then insure that THAT CERT is never used to sign any other certificates. 

For anyone getting an error when adding a single client cert to the Truststore see follow up question here:

https://community.apigee.com/questions/80304/mutual-tls-certificate-error-when-single-signed-ce.html