why don't trust valid intermediate x509 certificates? - ssl

A
/ \
B C
| |
D E
when E (or C) is verifying D's certificate he needs to trust B also.
is there a way to avoid having to explicitly add B's cert to E's CA store?
using openssl, is there the way to automate the retrieval of B's cert either from the client or another source (maybe a field like issuerDistributionPoint in D's certificate)?

is there a way to avoid having to explicitly add B's cert to E's CA store?
The common way is to send all intermediate certificates along with the leaf certificate inside the TLS handshake. For instance if you connect to google.com you get the following certificate chain provided by the server within the TLS handshake:
0 s:/C=US/ST=California/L=Mountain View/O=Google Inc/CN=*.google.com
1 s:/C=US/O=Google Inc/CN=Google Internet Authority G2
2 s:/C=US/O=GeoTrust Inc./CN=GeoTrust Global CA
Using the intermediate certificates (1,2) the client then can build the trust chain from the leaf certificate (0) up to the locally stored trusted CA (/C=US/O=Equifax/OU=Equifax Secure Certificate Authority in this case).
Of course you might also add the intermediate certificates as trusted in the clients. But since there are a lot more which also change more often than the trusted root certificates you would need a bit more memory but you would also update your clients regularly with the new intermediate certificates.
using openssl, is there the way to automate the retrieval of B's cert either from the client or another source (maybe a field like issuerDistributionPoint in D's certificate)?
openssl does not provide specific tools to deal with this. The desktop browser Google Chrome will actually try to download missing intermediate certificates from the internet, probably based on the information in the Authority Information Access part of the certificate. But I'm not aware of other browsers (apart from other Chromium derivates like Opera) doing this.

Related

Does a non-self-signed certificate, imported into root store, require a (self-signed) issuer to also be imported into the root store?

Does a non-self-signed certificate, imported into root store, require a (self-signed) issuer to also be imported into the root store?
Suppose I've a certificate A that is signed by another certificate B. Is it then sufficient to only import A into the root store, i.e. certificate validation stops at A, or should B also be imported into the root store for proper certificate validation?
The reason I'm asking this question, is that I've encountered different results with different products (e.g. web browser or system), and so I want to know the right way.
You should include Cert B in truststore. As mentioned in the comments, your mileage may vary as clients, as well as servers, implement RFC differently.
In terms of rules, spec for x.509 certs is in IETF RFC 5280. The key information is that for SSL handshake to happen client should do a full cert chain validation, which ends up with a self-signed certificate that is in your trust store.
Your Cert is not self-signed, it is issued by a different CA (cert B). If you do not have B in your truststore, then trust chain is broken. However, again as mentioned above, it is possible that client will not validate the full cert chain.
Think of it this way. Your client is presented with Cert A, which is signed by "B". Client should verify that signature on A is fine, which means it needs (certificate of) "B". If B is a "root" CA or self-signed, its "issuer" and "subject" fields will match. And if that Cert B is in your TrustStore, you are golden.
It's the job of the server to send you a certificate list for TLS.
This is a sequence (chain) of certificates. The sender's
certificate MUST come first in the list. Each following
certificate MUST directly certify the one preceding it.
There is a visual representation of certificate chain verification here. Hope it helps.

Does a TLS client needs to have intermediate CA in the trust store?

When a TLS handshake takes place, the server sends in his ServerHello message, his digital certificate. This digital certificate is digitally signed by a intermediate CA named A and CA A also has a certificate which is signed by CA named root whose certificate is self signed, thus forming a certificate chain. The client then has to establish a trust, validating the server certificate. To perform that validation the client has to validate the entire chain correct?
Must the client have in a truststore all the certificates (A and Root) or the client will download them?
The client usually has only the root CA in the local trust store. The leaf certificate and the intermediate certificate leading to the root CA need to be provided by the server. The intermediate certificates are usually send in addition to the leaf certificate within the TLS handshake.
But it is a typical misconfiguration to only have the leaf certificate send by the server. In this case the certificate validation will fail unless the client has already knowledge of the intermediate certificates or can obtain these somehow. Since often the same intermediate certificates are used, some browsers like Firefox will cache the intermediate certificates they'll got when communicating with server A and fill these in when a broken server B is not sending the required intermediate certificates. Other browsers (like Google Chrome) will try to download the missing intermediate certificates from the internet. Most simpler clients (i.e. apps written in Python, Java ... or curl) will instead just fail with a certificate validation error.

Should the trusted Root CA be a part of the certificate chain?

I'm setting up 2-way SSL communication between services on different hosts. Let's say I have my own CA called A. A is trusted by all of my services through a centralized jks. Now let's say I have certificate B signed by A. When services send the certificate should they be sending the entire chain B - A, or just B? I believe both tend to work with most implementations.
I tried to find canonical information about this online, but I'm coming up with nothing.
Thanks for the help
As per tls - Validating an SSL certificate chain according to RFC 5280: Am I understanding this correctly? - Information Security Stack Exchange:
the server should send the exact chain that is to be used; the server
is explicitly allowed to omit the root CA, but that's all.
Reference (RFC 5246 - TLS v1.2, sec. 7.4.2. - Server Certificate):
certificate_list
This is a sequence (chain) of certificates. The sender's
certificate MUST come first in the list. Each following certificate
MUST directly certify the one preceding it. Because certificate
validation requires that root keys be distributed independently, the
self-signed certificate that specifies the root certificate
authority MAY be omitted from the chain, under the assumption that
the remote end must already possess it in order to validate it in
any case.
The idea behind the trusted root CA is that it is trusted. Would you expect the browser to trust anything sent by the server just because it includes a root CA? No!
Therefore the root CA must be already at the client and must be trusted there. It should not be included in the certificate chain by the server, but if you do it anyway browsers will simply ignore it.

Renew SSL root CA cert - client programs in the wild need update?

Here is my situation:
I have a client application that I'm going to distribute - we'll call it MyClient.
MyClient does some SSL communication with one of our servers.
MyClient has the root CA embedded in it, so it can do proper verification of the server certificate.
Now, suppose some years go by, the root CA expires, and is renewed.
Does that mean I need to patch MyClient in the wild?
In other words, will a change to the validity dates on the certificate cause it to no longer match the baked-in root CA in MyClient?
Addendum: Suppose I write my client to not validate the date of the cert (but everything else). Then, when the root CA expires and is re-issued, do I still need to patch? Will other parts that play into the validation change, other than the date?
If your client is ensuring an SSL server certificate is issued by a particular root CA and that root CA is included in the client then yes, you will need to patch your client to replace the root CA certificate.
There are few good ways of doing this. What tends to happen is that root CA certificates are very long lived and use shorter lived intermediate CAs to issue SSL certificates but it sounds like this is not the case here.
Looking on the bright side, I do not know what algorithms were used with the old root CA certificate but, hopefully, The new root CA certificate will hopefully use a larger key (2048-bit RSA rather than 1024-bit or 512-bit) and a better hashing algorithm (SHA1 or better rather than MD5) so it may be a good opportunity to increase security.

How to determine a server's list of CA certificates that it will accept from client?

According to https://wiki.jasig.org/display/CASUM/X.509+Certificates,
After the Server sends the certificate that identifies itself, it then can then send a list of names of Certificate Authorities from which it is willing to accept certificates.
I am wondering how to determine what this list is, and how to modify it.
The reason I am asking is that I am getting an infinite redirect between my server and my client after successful validation (i.e., the ticket stage), and I think it has to do with the CAS server not recognizing the CAS client's certificate (the client's certificate is self-signed).
If you want to see what this list is, you can use OpenSSL:
echo "" | openssl s_client -connect your.server:port
This will show various messages regarding the handshake, including the certificates and the list of CAs in the CertificateRequest message.
Ultimately, it's determined by the active X509TrustManager's getAcceptedIssuers() method. By default, this will be the list of Subject DNs of all your trust anchors (that is, the Subject DNs of all the certificates in your trust store).
Your client certificate will have to be verified by the server. This is normally done during the handshake by the trust manager, which (unless tweaked) will build a chain to a known CA (or at least known cert if it's the user cert itself) in the trust store.
Adding your self-signed certificate to your trust store should be sufficient. It doesn't have to be the cacerts file bundled with the JVM, you could make a copy of it and use the trust store settings of Apache Tomcat's connector to set it up.