2
votes

I have been told to connect to a customer's server using two-way authentication. The server authentication is working smoothly but we are having huge troubles getting the client authentication in place. Let me try to explain our hassles.

Some time ago my company bought a certificate at GeoTrust, a certificate which should be perfectly valid to use as our client certificate. Apparently the customer did not manage to add this GeoTrust certificate appropriately to their truststore and we therefore saw the error unknown_ca in our SSL handshake logs every time we tried to connect to their server.

Instead the customer asked us to send them a certificate signing request (csr) and we received back a root certificate as well as a certificate which should be used as our client certificate. After having updated our keystore accordingly we are now seeing the error unsupported_certificate in our SSL handshake logs instead. A closer look at the customer signed client certificate reveals that the new certificate is explicitly having the Server Authentication extension but does not have the Client Authentication extension. I find the correlation between the unsupported_certificate and the missing Client Authentication extension quite obvious, but the customer refuses to accept the missing Client Authentication as a valid explanation (and therefore refuses to create a new and properly extended client certificate for us). This is what the customer argues:

The customer has sent me a screen shot of a no certificate returned from his logs and claims that this log entry means that I am passing the client certificate over the wire in a wrong format:

enter image description here

In order to strengthen his assertion about me submitting the client certificate in a wrong format, the customer has sent me the following TCP dump screen shot where a pkcs has been circled:

enter image description here

As I see it, the pkcs-9-at-emailAddress is just the standard way of including email address information in a certificate and has nothing to do with the certificate being submitted in a wrong format. Also I have found a place in Google where it is mentioned that the no certificate returned log entry can occur in cases where a client certificate is missing the Client Authentication extension.

In order to rule out that it is the keystore.jks and truststore.jks being used by our Java codes which are malformed, I have tried to connect to their server using just an OpenSSL command:

openssl s_client -CAfile caroot.cer -cert client.cer -key client.key -connect <host>:<port>

Execution of this OpenSSL command results in the exact same unsupported_certificate error.

I would greatly appreciate if someone could help me understand whether we are right or the customer is right. Thanks a lot.

2
How are you using the TrustStore and the KeyStore for establishing connection? How was the PKCS12 keystore generated? Does it contain the private key and certificate of the client? Does the trust store contain the certificate of the server? Try using Apache HttpClient hc.apache.org/httpcomponents-client-4.4.x/index.html hc.apache.org/httpcomponents-client-4.4.x/httpclient/examples/… - EpicPandaForce
There is a nice blog article Client Certificates V/s Server Certificates which also links to and cites RFC 3280: If the extension is present, then the certificate MUST only be used for one of the purposes indicated. The same text appears in the superseding RFC 5280. From my understanding, this means that tools adhering to the X.509v3 standard will not let you use the customer-provided certificate for client authentication. - halfbit
@EpicPandaForce: We have been creating the files keystore.jks and truststore.jks using Java's keytool. The keystore.jks contains a privateKeyEntry combining our private key and the client certificate signed by the customer. The truststore.jks contains the server certificate as trustedCertEntry. Note though, that Java is removed from the equation when executing the OpenSSL s_client command. - Stine
@halfbit: Thanks, that is what I understand as well! :) I will take a look at the blog article you recommend. - Stine
@Stine: Yes, section "Certificate Extensions" of RFC5280 reads A non-critical extension MAY be ignored if it is not recognized, but MUST be processed if it is recognized. Each tool that understands ExtendedKeyUsage definitely has to restrict certificate usage accordingly. Put the other way: Criticality=false tells (too old) tools which do not (yet) understand what some extension is, that they can ignore it. It seems criticality flags are just a means to achieve forward compatibility. - halfbit

2 Answers

4
votes

Certainly OpenSSL s_client will be transmitting the certificate in the correct format (or else it will fail before connecting to the server). Let us examine the Error Alerts defined for TLS 1.2 (RFC 5246).

bad_certificate
   A certificate was corrupt, contained signatures that did not
   verify correctly, etc.

unsupported_certificate
   A certificate was of an unsupported type.

There are several more alerts but these are the most interesting two. From this we might infer that a failure to parse a certificate e.g. due to incorrect format would result in bad_certificate, and than unsupported certificate might be returned in cases such as unsuitable key usage information.

If your customer requires further evidence, you could use the s_server(1) program together with s_client to show that in this setup the client certificate is rejected in the same way.

2
votes

The customer has sent me a screen shot of a no certificate returned from his logs and claims that this log entry means that I am passing the client certificate over the wire in a wrong format.

Wrong. It means exactly what it says.

No certificate was returned. That happens when, err, you don't return a certificate. That in turn happens because your SSL software didn't find a certificate that is signed by one of the certificate types or trusted signers that were specified by the server in the CertificateRequest message.

That in turn means one of two things:

  1. You didn't install the signed certificate correctly in your keystore. The steps to do this are (1) install the root certificates they supplied, using the -trustcacerts option, into the keystore, and (2) install the signed certificate using the same alias you used when generating the keypair and the CSR.

OR

  1. They don't trust their own root certificate, so they didn't send their own root CA as a trusted signer in the CertificateRequest message, or didn't include its type.

My money is on both (1) and (2), but the whole business of the customer signing your certificate is ridiculous. If his truststores don't recognize a recognized CA, that is their problem to fix, not changing to a different signer, which just moves the problem. Do you trust their signer, for example? I don't just mean in the truststore sense but in the corporate security sense?

And if it is (2) it means the customer's software isn't recognizing a certificate that he issued himself, so I don't see why you need to be involved at all.

Any comments on the customer's claim about wrongly formatted client certificate being submitted?

My comment is that this does not inspire confidence.

I have found a place in Google where it is mentioned that the no certificate returned log entry can occur in cases where a client certificate is missing the Client Authentication extension.

In other words they didn't sign it correctly.

I don't have any confidence in 'the following TCP dump screen shot where a pkcs has been circled' either, unless there is first a CertificateRequest and then a Certificate message immediately above. If it's all true the customer appears to have issued an incorrect certificate.

Any allegation that you have corrupted it can be discounted, as it would have failed verification at both ends. Equally, any allegation that your software is corrupting it in transit can also be discounted, as you are using Java, not your own code, to do this.

All this only shows even more strongly that you should forgot about the customer signing the certificate and get them to solve the original problem with the GeoTrust root CA certificate. It's much simpler, and it doesn't involve you.