2

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.

Stine
  • 1,605
  • 5
  • 23
  • 44
  • 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 http://hc.apache.org/httpcomponents-client-4.4.x/index.html http://hc.apache.org/httpcomponents-client-4.4.x/httpclient/examples/org/apache/http/examples/client/ClientCustomSSL.java – EpicPandaForce Mar 29 '15 at 12:14
  • 3
    There is a nice blog article [Client Certificates V/s Server Certificates](http://blogs.msdn.com/b/kaushal/archive/2012/02/18/client-certificates-v-s-server-certificates.aspx) 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](http://tools.ietf.org/html/rfc5280#page-44). 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 Mar 29 '15 at 12:37
  • @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 Mar 29 '15 at 12:53
  • 1
    @halfbit: Thanks, that is what I understand as well! :) I will take a look at the blog article you recommend. – Stine Mar 29 '15 at 12:57
  • @halfbit: I have just noticed that Extended Key Usage extension is marked non-critical in the client certificate: `[5]: ObjectId: 2.5.29.37 Criticality=false ExtendedKeyUsages [ serverAuth ]`. Can it then still be the case that the missing clientAuth purpose is a show stopper? – Stine Apr 01 '15 at 07:36
  • 1
    @Stine: Yes, [section "Certificate Extensions" of RFC5280](http://tools.ietf.org/html/rfc5280#page-26) 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](https://en.wikipedia.org/wiki/Forward_compatibility). – halfbit Apr 01 '15 at 21:06
  • @halfbit: Cool, thanks for making this clear! :) – Stine Apr 02 '15 at 05:28

2 Answers2

4

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.

Community
  • 1
  • 1
frasertweedale
  • 5,424
  • 3
  • 26
  • 38
  • Thanks a lot for your input! :) I might take a look into how to use the OpenSSL s_server. – Stine Mar 31 '15 at 07:29
2

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.

user207421
  • 305,947
  • 44
  • 307
  • 483
  • Thanks a lot for your thorough input! :) I agree that it is completely nonsense that the customer won't accept that we use our own fine GeoTrust certificate! This is what I see in the SSL handshake logs regarding their CertificateRequest btw: `*** CertificateRequest Cert Types: RSA, DSS, ECDSA Cert Authorities: *** ServerHelloDone`. I also see that we actually send back the certificate from the keystore anyway. – Stine Mar 31 '15 at 07:26
  • 1
    @Stine That message tells you all you need to need to know. Show it to them. It wouldn't matter what certificate you sent to them, and from what source. They wouldn't accept it. By the content of that message, RFC 2246 doesn't permit your software to send any certificate whatsoever. They have fouled up big-time here. Don't get involved in any solution that requires time or money expended by you. – user207421 Mar 31 '15 at 08:48
  • I am so glad that you agree about that CA list being a problem! I have tried to tell the customer about it, but they are stuck on telling us that we should just fix our formatting problem. And as described, I have no idea what formatting problem they are talking about... ;D – Stine Mar 31 '15 at 08:53
  • EJP, I notice that you write that my client software should not be permitted to send back a certificate in response to a CertificateRequest with an empty list of CAs. When I look in my SSL handshake logs it seems as if a certificate is actually being sent back: `*** CertificateRequest Cert Types: RSA, DSS, ECDSA Cert Authorities: *** ServerHelloDone matching alias: xxx *** Certificate chain chain [0] = [ [ Version: V3 Subject: ...`. Do you have any idea how that can be? – Stine Apr 01 '15 at 07:11
  • 1
    @Stine 2246 specifies certificate_authorities nonempty with client handling of empty unspecified, but 4346 and 5246 allow empty and explicitly say in that case "the client MAY send any certificate of the appropriate ClientCertificateType, unless there is some external arrangement to the contrary." OpenSSL (1.0.1h) and Java/JSSE (7u72) clients do accept empty and continue -- even for 1.0 and SSL3, very Postelian. openssl (library) server, apparently used here, can send empty CAlist in all protocols, and accepts a cert in response subject to the usual chain validation. ... – dave_thompson_085 Apr 02 '15 at 15:48
  • 1
    ... Thus I doubt this is your problem, but I don't know what is. Oh PS: before client Cert, server should have sent ServerHello Cert CertReq ServerHelloDone. – dave_thompson_085 Apr 02 '15 at 15:54
  • @dave_thompson_085: nice to "talk" to people not just talking nonsense like the customer I am struggling with! Thanks a lot for you input! :) – Stine Apr 02 '15 at 19:40