TLS Handshake Steps - ssl

I know basic steps of a TLS Handshake but I don't have knowledge about detailed verification steps of certificates during TLS. My question is at below;
Let us assume that our system supports OCSP/CRLs verification. In this case, is the first step to verify incoming certificate using CRLs or OCSP Responder? Or look for the incoming certificate is in TrustStore or not, at first?
Thanks four your help

You will probably not find a definitive document on that, in part because people have shifted away from these 2 methods of revocation check (they are disabled by default in some browsers or when enabled do not produce very useful UI)
Nowadays people prefer OCSP Stapling (see https://casecurity.org/2013/02/14/certificate-revocation-and-ocsp-stapling/ for some reasons) over CRLs or OCSP.
But to go back precisely to your question, since both CRLs and OCSP typically mean going to fetch something remotely, this needs network access and can create delays. So if you have a local TrustStore with all the certificates you should first check that, before having to do a remote call.
Also the CABForum Baseline Requirements (at https://cabforum.org/baseline-requirements-certificate-contents/) specify that CRLs endpoints MAY be present in a certificate but OCSP endpoint MUST be present, except if you are doing OCSP Stapling instead.
On top of that EV certificates mandate OCSP.
So, in short it may make sense to do things in this order:
Check in local TrustStore
Do an OCSP query
Download a CRL
Note that nowadays you have also other options:
DANE, hence checking DNS TLSA records
Certificate Transparency Logs
oneCRL / CRLset

Related

Force Chrome to send all certificates in chain during TLS

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.
How can I force client to send all nodes of the certificate chain?
Thanks
I realized that Google Chrome as client has been sending certificate chain without root.
That is perfectly normal and the only correct behavior.
The root certificate is the trust anchor which has to be local to the party validating the certificate. Even if it is send it should be ignored when validating the certificate, i.e. only a local trust anchor should be used - otherwise a man in the middle could just provide his own certificate chain including his own root certificte. This means that in this case the server must have the root certificate already locally and thus there is no need for the client to send it.
In other words: don't try to change how Chrome behaves but instead adjust your expectations (and your code) on what the correct behavior is.
I agree with Steffen but to give some more facts, here is what TLS 1.3 explicitly says:
certificate_list: A sequence (chain) of CertificateEntry structures,
each containing a single certificate and set of extensions.
and
The sender's certificate MUST come in the first
CertificateEntry in the list. Each following certificate SHOULD
directly certify the one immediately preceding it. Because
certificate validation requires that trust anchors be distributed
independently, a certificate that specifies a trust anchor MAY be
omitted from the chain, provided that supported peers are known to
possess any omitted certificates.
and finally about ordering:
Note: Prior to TLS 1.3, "certificate_list" ordering required each
certificate to certify the one immediately preceding it; however,
some implementations allowed some flexibility. Servers sometimes
send both a current and deprecated intermediate for transitional
purposes, and others are simply configured incorrectly, but these
cases can nonetheless be validated properly. 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.
So Chrome is correctly applying this specification. You need to change your end to cope with it.

HAProxy SSL Termination - Client certificate Extended Key usage extension validation

We're using HAProxy (v1.6.9) to verify client certificates(X.509 v3) and do SSL termination. We want to validate the Extended key usage and the basic constraints extensions in the client certificate. By looking at the HAProxy source code and OpenSSL verify documentation, I guess the keyUsage extension would be validated. But, does it do validation of the Extended Key Usage as well as Basic constraints extensions? If not, then is there a way to set this information in the request header and forward it to the application, so that the application can validate it?
Based on my understanding of OpenSSL documentation, we need to set the "purpose" option in verify to validate these extensions and I couldn't find this option being set in HAProxy's source code. Please correct me, if I'm wrong.
Thank you.
When you use commandline verify or call X509_verify_cert you do need to specify 'purpose' if you want it checked, because these operations can handle cert chains used for any purpose (or combination of purposes). For SSL/TLS protocols this is handled automatically, because the libssl code knows that it received and is checking a cert/chain for an 'SSL' (including TLS) server or client; see function ssl_validate_cert_chain in ssl/ssl_cert.c -- this line has the effect of specifying 'purpose'. For release 1.1.0 only (so far) the purpose is also checked against optional local trust attributes for the anchor/root (in addition to ExtendedKeyUsage extension(s)).
The statement on the man page that "If the -purpose option is not included then no checks [of untrusted cert extensions] are done." may be misleading. If purpose is not specified no checks for purpose are done, but some checks of extensions are always done regardless of purpose -- at least always for a proper chain with CA cert(s) distinct from the EE cert; for a selfsigned EE cert, which acts as its own anchor and effectively its own CA, some checks are inapplicable.
In particular, as mentioned a few paragraphs earlier, during the build phase CA (aka issuer) certs are checked for KeyUsage.certSign and SKI/issuer/serial matching AKI. During the second phase all untrusted certs are checked for BasicConstraints (and the now-rare NetscapeCertType) and KeyUsage.certSign (again), and NameConstraints (since 1.0.0), and the EE SAN or Subject is matched if a peer id was configured (which generally makes sense only if the peer is the server, hence not your case, and only since 1.0.2); also revocation checking (which may involve extensions) if configured (not the default); and if purpose checking is configured (which it is for libssl) in addition to ExtKeyUsage on all untrusted certs it checks KeyUsage and NetscapeCertType of the EE cert. Although the EE KeyUsage check here is not specific to the ciphersuite and thus keyexchange method negotiated; that is checked separately in libssl.
And the final phase in addition to checking signatures and validityperiod (as stated) also checks the RFC3779 extensions if used (almost never?) and if configured (probably rare) CertificatePolicies plus PolicyMappings, PolicyConstraints, and InhibitAnyPolicy.
Do note extension checks only fail if the extension is present with an inconsistent value; if an extension is omitted (by the CA) from a given cert it effectively permits everything related to that extension.
HTH.

Can server send multiple certificates to client?

I have written small Java 7 Client and Server application. I have keystore with 3 Self-signed X.509 RSA Certificates. When client connects through SSL, server sends SSL Certificate message with only one certificate. I am bit new to SSL/TLS. I also looked at JSSE code sun.security.ssl.X509KeyManagerImpl, and found below comments:
/*
* Return the best alias that fits the given parameters.
* The algorithm we use is:
* . scan through all the aliases in all builders in order
* . as soon as we find a perfect match, return
* (i.e. a match with a cert that has appropriate key usage
* and is not expired).
* . if we do not find a perfect match, keep looping and remember
* the imperfect matches
* . at the end, sort the imperfect matches. we prefer expired certs
* with appropriate key usage to certs with the wrong key usage.
* return the first one of them.
*/
private String More ...chooseAlias(List<KeyType> keyTypeList,
Principal[] issuers, CheckType checkType)
Comment is pretty clear that server will send single best matching certificate but I don't seem to understand the reason. Like in my case, I want server to send all 3 certificates, so client can pick one and validate the chain. And also, if my client doesn't have the certificate that server sends, the connection is dropped with SSLHandshakeException 'No trusted certificate found'. So my question is that why can't server send all 3 certificates if the client requested information (from ClientHello) matches with all 3 certificates ? Is it something to do with TLS 1.0 vs TLS 1.2 ?
The TLS handshake protocol only provides for the transmission of one client end-entity certificate (this is also the case for server certificates). Intermediate certificates can be transmitted, but what you seem to want - transmission of multiple end-entity certificates - is not possible.
The structure of the TLS Server / Client Certificate message is defined in RFC 5246 (TLS 1.2) section 7.4.2:
Structure of this message:
opaque ASN.1Cert<1..2^24-1>;
struct {
ASN.1Cert certificate_list<0..2^24-1>;
} 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.
In regards to which certificate the client selects to present, if you configure your server to advertise its trusted CAs for client certificate validation (the certificate_authorities field of the CertificateRequest message; see below), then the client-side code that selects the certificate to present ought to select a certificate that is certified by one of the advertised CAs.
7.4.4. Certificate Request
...
Structure of this message:
enum {
rsa_sign(1), dss_sign(2), rsa_fixed_dh(3), dss_fixed_dh(4),
rsa_ephemeral_dh_RESERVED(5), dss_ephemeral_dh_RESERVED(6),
fortezza_dms_RESERVED(20), (255)
} ClientCertificateType;
opaque DistinguishedName<1..2^16-1>;
struct {
ClientCertificateType certificate_types<1..2^8-1>;
SignatureAndHashAlgorithm
supported_signature_algorithms<2^16-1>;
DistinguishedName certificate_authorities<0..2^16-1>;
} CertificateRequest;
...
certificate_authorities
A list of the distinguished names [X501] of acceptable
certificate_authorities, represented in DER-encoded format. These
distinguished names may specify a desired distinguished name for a
root CA or for a subordinate CA; thus, this message can be used to
describe known roots as well as a desired authorization space. If
the certificate_authorities list is empty, then the client MAY
send any certificate of the appropriate ClientCertificateType,
unless there is some external arrangement to the contrary.
And, from section 7.4.6:
If the certificate_authorities list in the certificate request
message was non-empty, one of the certificates in the certificate
chain SHOULD be issued by one of the listed CAs.
Bad luck, you can only send one. See RFC 2616 &ff.

Does the certificate need to be official or self signed?

I am putting a web test up for clients that visit "https://oursite.com/poodlesecurityfailed.js"
Question,
Do I need a valid certificate even though its on a test domain for certificate negotiation? If client can visit it, they failed the poodle test. (SSLv3 is enabled) on that host.
Ideas?
Do I need a valid certificate even though its on a test domain for certificate negotiation? If client can visit it, they failed the poodle test. (SSLv3 is enabled) on that host.
Depends on the client.
If the clients is has enough knowledge to understand, that "invalid certificate" when accessing the site means in reality that the client has still SSL 3.0 enabled, then a self-signed certificate would be enough.
If you instead want to provide an explanation of the problem at this site and don't expect the client to explicitly accept an invalid certificate just to see this explanation, then you should better use a properly trusted certificate.

Certificate Validation is SSL Handshake using memcmp or Strcmp?

Wanted to know about the pros and cons of using either "memcmp" or "strcmp" for validating the certificates exchanged during SSL Handshake.
My code converts the X509 certificates into PEM format and then do the string comparison to validate the certificates.
Are there any issues which are associated with using strcmp OVER memcmp for validating the certificate received during handshake against a verified certificate already placed on the server?
From your description it is hard to know what you do with memcmp or strcmp, but I assume, that you want to check the common name or subject alternative names against the hostname. There were others which used strcmp instead of memcmp for this which resulted in lots of security reports in 2009, see CVE-2009-2408 (firefox), CVE-2009-2702 (KDE), CVE-2009-3767 (OpenLDAP) and some more.