OCSP query for intermediate certificate without issuer certificate - ssl

I have written a TLS code which is doing mutual authentication at Java, so client is sending its certificate after server sends its certificate. I would like to validate all the certificates in certificate chain by OCSP which is coming from client side to server side.
I have written my loop logic as assuming that last certificate is root(CA) certificate in the chain and not to send any OCSP query for it;
int certificateChainSize= x509Certificates.length;
// Verifies certificate chain respectively (issuer certificate required).
CertificateResult response = null;
try {
for (int i = 0; i < certificateChainSize-1 ; i++) {
response = client.verify(x509Certificates[i], x509Certificates[i+1]);
}
} catch (OcspException e) {
e.printStackTrace();
}
When I test TLS and get Wireshark capture, I realized that Google Chrome as client has been sending certificate chain without root. As a result; intermediate certificate is not queried because of loop logic, because my code assumed the intermedite certificate is root. I need issuer certificate for validation to any certificate in chain. Is there any mechanism validation without issuer certificate(in case: root certificate).

I think, your design is flawed.
There is no need to validate certificate against OCSP server when you don't have root certificate, because the chain is untrusted and OCSP validation makes zero sense.
In major cryptographic libraries, revocation checking occurs as a last step when all possible certificate chains are constructed, best chain is selected and it is successfully validated against various validation rules (most of them are described in ยง6 of RFC 5280 ). Only when all checks are successful, client attempts revocation checking for each certificate in the chain. And successful chain building and validation will imply that you already have trusted root certificate, because valid chains are built up to root certificate.
In addition, as it was said in your previous thread Force Chrome to send all certificates in chain during TLS :
For maximum compatibility, all implementations SHOULD be prepared to handle potentially extraneous certificates and arbitrary orderings from any TLS version, with the exception of the end-entity certificate which MUST be first.
This statement implies that subsequent i+1 certificate may not be necessary an issuer of the current i certificate. As the result, this line:
response = client.verify(x509Certificates[i], x509Certificates[i+1]);
will return unexpected results, because its input is wrong.
what you really should do: let the OS cryptographic library (which is shipped as a part of operating system) to do the hardest work. I strongly encourage to not invent your own crypto and use proven tools. Every OS has APIs that will build, arrange and validate certificate chains and return you best one. You should use this chain as an input of your OCSP validation code and your for loop will be considered reliable (depening on internal logic of verify method).
Like I said, if chain building process fails, there is no much reason to perform OCSP validation.

Related

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.

In SSL trust hierarchies, what is used to sign an intermediate certificate and how does this relate to the root certificate?

I'm completing an assignment on SSL and I feel I understand the basics of how certs are used with asymmetric and symmetric encryption. But I'm having difficulty understanding some details of how exactly trust hierarchies work.
Specifically, what is used to sign an intermediate certificate? All the guides I've looked at state that the CA root cert is used to sign the intermediate cert. But what exactly does "sign" mean here? In other words, how does a server prove that its intermediate certificate is authenticated by the CA root cert?
My guess is that the public key or signature of the root cert are used when generating the signature of intermediate cert the but I'm not sure if this is accurate.
I would really appreciate any info to improve my understanding.
If there is exactly one intermediate, which is often but not always the case, the intermediate cert is signed by the root in exactly the same way an end-entity cert (for SSL/TLS mostly a server cert) is signed by the intermediate. In both cases this is a shorthand; signing is actually done using the private key of an asymmetric keypair, and the cert contains the public key of the same keypair which is used to verify signatures made with the private key. Since the private keys are private and all of us who use the CAs see only their public keys, we focus on that. Thus:
the server cert is signed using the private key belonging to the intermediate CA; the intermediate cert contains the matching public key. As part of verifying the server cert, the relier (e.g. browser) finds or confirms the intermediate cert using the Isssuer name in the server cert, and uses the public key from the intermediate cert to verify the signature on the server cert; this assures that the server cert was actually issued by the intermediate CA and has not been tampered with.
According to SSL/TLS standards the server should always send the intermediate cert (or certs, in order) following the server cert in the handshake, although if it fails to do so, some clients may use AIA from the certificate or other heuristic means to obtain the cert, or may have it already cached or even configured.
the intermediate cert is signed using the private key belonging to the root CA; the root cert contains the matching public key. As part of verifying the intermediate cert, the relier finds the root cert using the Issuer name in the intermediate cert, and uses the public key from the root cert to verify the signature on the intermediate cert; this assures that the intermediate cert was actually issued by the root CA and has not been tampered with.
The root cert normally must (already) be in the relier's local 'trust store' and the server does not need to send it; normally the trust store is provided either by the browser developer (Firefox) or by the OS/platform developer (IE/Edge, Chrome, Safari).
Notice the close parallel between these two statements with the (notable) exception of how the relier finds the parent cert. Also note that validating a server cert chain for an SSL/TLS connection involves much more than just verifying the signatures, although verifying the signatures is a critical part and without it the other validation criteria could not be assured.
One intermediate CA, and intermediate cert, will generally be used by a large number (thousands to millions) of server certs and servers. The server isn't responsible for 'proving' anything about the intermediate cert, only passing it on to the client, which validates the entire chain.
Cross-stack see also
https://security.stackexchange.com/questions/56389/ssl-certificate-framework-101-how-does-the-browser-actually-verify-the-validity
which has a nice graphic of this relationship.

WCF: Using Secure Message with Certificate Revokation List checking

I have an enterprise issued certificate that I want to use to secure a WCF message channel. The certutil program tells me that both the CRL and delta CRL are valid (status = "Verified"). I'm using the sample WCF programs from (https://www.microsoft.com/en-us/download/details.aspx?id=21459); specifically the MessageSecurity.sln test. When I replace the self-signed certificate with the Enterprise CA-generated certificate, I get the error:
The X.509 certificate CN=localhost chain building failed. The certificate that was used has a trust chain that cannot be verified. Replace the certificate or change the certificateValidationMode. The revocation function was unable to check revocation because the revocation server was offline.
Has anyone got message based channels working with anything other than self-signed certificates (i.e. with a valid CRL distribution point)? Any ideas what to try next?
Fun fact! The client maintains a cache of CRLs. After properly configuring the CRL distribution point, the cache with the erroneous CRL locations prevented the WCF sample from running. When it magically started working two days later, I did some digging and found out that the lists are cached. You can clear the lists manually with:
certutil -urlcache crl delete
After using this command I was able to predictably and reliably use my Enterprise CA generated cert to establish Message and TransportWithMessageCredentials channels.

Where are the Certificate Revocation List (CRL) stores?

As far as I know and as it is mentioned here there are two main technologies for browsers to check the revocation status of a particular certificate: using the Online Certificate Status Protocol (OCSP) or looking up the certificate in a Certificate Revocation List (CRL).
Well, I know that there is some online OCSP servers or the OCSP method and the browser send a request there to check if the incoming certificate is revoked, but I don't have any idea about the CRL.
Where is the CRL? Is it a file in my system that updated after OCSP requests or it is a list in the web server that I'm trying to connect to?
Who updates it?
How do OCSP server check revocation? (I mean how does it update its database of revoked certificates?)
Note that I know I can see a cache of CRL using certutil -urlcache crl in command line. But it is a cache of it! Where is the real file?
Where is CRL? Is it a file in my system that updated after OCSP requests or it is a list in the web server that I'm trying to connect to?
CRL is a list provided by the certificate issuer. The list contains the serial numbers and the reason for revocation of the revoked certificates and is signed by the issuer (or some other directly or indirectly trusted CA). The original CRL file is created and stored at the issuer. It gets provided usually via http/https but other mechanism exists. To know which URL provides the CRL for a specific certificate look at the 'CRL Distribution Points' property of the certificate. Note that lots of certificates issued by the same CA share the same CRL distribution point.
Where the local copy of the CRL is on your system, in which format it is stored there etc depends on the OS, browser, libraries... I doubt that it will be updated based on OCSP responses because OCSP and CRL are independent mechanism to check for revocation and a client usually only uses one of these to check for revocation of specific certificates. But it might use OCSP in some cases and CRL in other cases (where no OCSP is provided).
Who it updates?
It depends. Browsers usually don't use CRL's anymore but moved to OCSP, skip revocation checks completely or moved to some other mechanism like CRLSets. If any other application use CRL for the certificates - it probably depends on the application.
How OCSP server check revocation? (I mean how it update its database of revoked certificates?)
It does not check for revocation. Either the OCSP server is provided by the certificate issuer itself which already has the list of revoked certificates (since the issuer revoked these itself) or in case of OCSP stapling the web server gets the (signed) OCSP response from the issuer and includes it unchanged inside the TLS handshake.
In theory one could build some OCSP proxy which provides OCSP responses based on existing CRL files but since the OCSP responses are signed too this proxy must have a certificate which is explicitly trusted for signing OCSP responses.

mTLS ( mutual TLS) details

I know that for MTLS , both parties , Client and server exchange certificates. These certificates should be signed by a CA that both parties can trust in order to validate the certificate.
My question is , does MTLS also means in addition to verifying the certificate (if CA is trusted, leaf certificate is trusted) , either side (Server or client) can also do some additional checks like Hostname check or Whether the client connecting to the server is in the list of approved trusted entities?
Can anyone point me to the mTLS specification and what are the overheads in mTLS?
Besides what EJP has said about "MTLS" term, the TLS 1.2 specification doesn't have strict requirements regarding what information is to be checked and in which way.
It's up to the receiving party to decide if the presented certificate is to be trusted or not. This means that for example it's ok for the server to accept only certificates issued by the CA that belongs to the company that owns the server. This is how client-bank access systems often work - they accept only certificates issued by the bank and the common name of such certificate must correspond to the username provided in a web form.
Both parties are free to check any information in the certificate including direct comparison of public key hash (thus only particular keypairs will work no matter what is contained in other certificate properties).
The most up todate RFC regarding this subject is:
https://datatracker.ietf.org/doc/draft-ietf-oauth-mtls/
this is an extension to OAuth 2.0
The purpose of this document is to define a mechanism how TLS certificate is used in a context of replacing Client ID and Secret (aka, Client Credentials)
The standard establishes two mechanisms how a TLS Certificate is used as a client credential, and the associated token flows, and attributes.
The general summary of this is:
(a) Authorization Server: checks the certificate either according to PKI (signed by a valid root) The RFC does not define the options, but they are pretty self-explanatory and depend on the use case. But it can be (1) certificate is signed by a trusted root and, is not revoked, (2) individually recognize each certificate based on some logic.
(b) Resource server checks the token and client certificate (client credential, or CC), and used in the underlying TLS session. Please note that there are no validation checks concerning the certificate or its origin at TLS layer, all checks are performed at an Application layer. The resource server should, therefore, configure the TLS stack in a way that it does not verify whether the certificate presented by the client during the handshake is signed by a trusted CA certificate.
This mechanism becomes particularly interesting in some GDPR context, as it makes it impossible to share tokens between client and the server.
Overall a great feature for privacy, and improved security.
mTLS can be implemented by issuing all parties a CA certificate and adding these to all communicating parties, which is a sort of an access control list. Whoever has their CA certificate in your app's trust store is able to connect.
The trust system however is the same as with TLS in the case of a https connection - you can issue several certificates from the same CA and add the root CA certificate to the trust store of your app. It will trust all certificates issued from the same root. This is arguably easier to set up as you only have to add the app's own certificate and the CA root. However, if you want to revoke a certificate, it becomes a little more complicated.
I wrote a guide to generate certificates here:
https://thoughts-about-code.blogspot.com/2021/12/creating-a-ca-for-mtls-with-openssl.html
First:
Both server and client certificates have to be built with the same CA certificate and key
see : https://github.com/ysimonx/mtls-ssl-generator/blob/main/generate_certificates.sh
So you have to store the CA certificate on both sides :
On the server side : you can allow (this is optional) a client that provides client cert built with the same CA than its own certificate. (see rejectUnauthorized: true)
https: {
requestCert: true,
rejectUnauthorized: true,
key: fs.readFileSync("./certificates/server/serverKey.pem"),
cert: fs.readFileSync("./certificates/server/serverCrt.pem") ,
ca: [fs.readFileSync("./certificates/ca/caCrt.pem")]
}
(exemple for a fastify nodejs https self-signed certificate server)
On the client side : you can allow (this is optional too) a server that provides (or not) the same CA certificate as the client knows
curl -k --cert ./certificates/client/clientCrt.pem --key ./certificates/client/clientKey.pem https://localhost:3000/
(parameter -k : do not verify the server certificate based upon a CA authority)
or
curl --cacert ./certificates/ca/caCrt.pem --cert ./certificates/client/clientCrt.pem --key ./certificates/client/clientKey.pem https://localhost:3000/
if you want the client to match the correct CA cert used by the server
There is no 'MTLS Specification', for the very good reason that there is no such thing as 'MTLS'. You just made it up. The TLS specification, including mutual authentication, is to be found in RFC 2246 as amended.
The TLS APIs should make the peer certificate chain available to the application, so it can do any additional checking it likes.
'MTLS', insofar as it exists at all, refers to an Internet Draft for multiplexed TLS.