OpenSSL identify reason for "bad certificate" - ssl

I'm using pyOpenSSL which is a wrapper for OpenSSL. I had a client program trying to connect to my server and repeatedly was getting sslv3 alert bad certificate on the server. It wasn't until I realized it was due to the client's clock being improperly set that I was able to figure out the issue. I'm guessing that the client saw the server's certs as being dated in the "future" and somehow that resulted in a sslv3 alert bad certificate on the server.
Is there any way to get better descriptions as to why a particular cert failed? I'm assuming in this case the verification failed on the client side due to the clock not being set right, but the error on the server side is the same as if a bad certificate was sent and the verification failed on the server side.

Unfortunately the problem descriptions are fairly limited. Errors are transmitted with TLS alerts. Each alert is only a number without any additional information and there are only few alerts defined, see http://en.wikipedia.org/wiki/Transport_Layer_Security#Alert_protocol. For example there is an alert for an expired certificate, but no alert for a certificate which is not yet valid which would be necessary in your case. So all the client could send back is that the certificate is bad.

In most cases sslv3 alert bad certificate means that CA information is not provided at all or is wrong. In curl there is a parameter --cacert , for openssl s_client use -CAfile.

Related

Get TLS certificate chain after failed connection

I have a Go program that uses tls.Server to accept TLS connections from clients. When a particular client connects, I'm getting the error "tls: failed to verify client's certificate: x509: certificate signed by unknown authority".
I'd like to see the certificate chain that was presented (and failed to verify) so that I can figure out what the client is doing wrong. Is there a way to do that using Go's tls package? The obvious answer - to use the ConnectionState method - doesn't work because the ConnectionState's PeerCertificates field is only populated after the handshake has completed successfully.

Does haproxy support OCSP for client certificate validation

We are configuring HAProxy to force require Client Certificate Validation. This works well. However, we couldn't find much information about OCSP support specifically for client certificate validation. There are information about Certificate Revocation list and OCSP Stapling (which I believe is for server certificates).
So my questions are
1. Does HAProxy supports OCSP during client certificate validation?
and
2. If it is supported, can this be manually configured without requiring the OCSP URL included in the client certificate itself or possibly overriding the url on the server?
We are configuring HAProxy to force require Client Certificate Validation.
Please define exactly what Client Certificate Validation means to you. You say it works well, so my best guess is that you're generating client certificates and you have configured haproxy to require valid client certificates in order to access resources that haproxy is in front of.
However, we couldn't find much information about OCSP support specifically for client certificate validation. ... 1. Does HAProxy supports OCSP during client certificate validation?
No. That's quite simply "out of scope" for a server like haproxy. HAproxy only does OCSP stapling, and only then if you supply the OCSP response in the form of .ocsp files in the certificate directory. It's unusual to want haproxy to block TLS connections while it tries to get HTTP responses from each TLS certificate for all the reasons that OCSP stapling exists. Along those same lines, having haproxy block TLS connections from your clients while it tries to validate their certs via OCSP (or for that matter, CRLs) is not a good idea.
Update: See this thread on in the haproxy forums.

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.

Using self-signed SSL certificate works, but CA signed certificate results in handshake alert failure 40 in response to client hello

So far, I've used openssl, sslyze, keystore utilities, and some of the standard Windows diagnostics commands to try and characterize this problem. The summary is that as soon as I attempt to use a keystore that has the CA signed certificate in it, I get an immediate handshake failure 40 after the client hello. The connection never gets as far as a server hello with the CA cert in place.
On the same machine (Windows Server 2012), if I use a self signed certificate, the connection works as expected.
Openssl shows the handshake failure with the CA certificate in place.
sslyze shows all ciphers rejected with either no ciphers available or TLS / Alert handshake failure.
The fact that this is successful with a self-signed certificate tends to indicate that the "basics" are there, that the client and server have the necessary ciphers and so on to connect, and that server.xml is configured properly.
There were no error messages when importing the certificates, and everything seems to be configured correctly with the CA certs based on keytool checks. There are no error messages given during server start to indicate any problems processing the certificate.
Is there something I should be looking more closely at in regards to the keystore with the CA cert that could cause this complete rejection of the client hello? How would a different keystore or CA certs within aaffect the earliest steps of the handshake?
Thank you for information provided.
I assume that you are talking about a server side certificate and a server side key store, since the error happens at a state where no client certificates are yet involved. If the server is able to send the self-signed certificate to the client, but is not able to send the CA signed certificate to the client, then it must be something wrong with the certificate you are trying to send or that the certificate can not be used together with the ciphers offered by the client.
Since the problem is obviously on the server side you should first check all logs written on the server side for hints what the error might be. Typical problems are non-existing files, wrong files, password protected client key w/o providing a password or that the key does not belong to the certificate.

Browser doesn't apply client certificate: 403.7

I'm trying to set up client certificate authentication. I was able to generate a CA-, server- and client-certificate. As long as I use Fiddler everything works as expected. However, as soon as I start using a browser it doesn't work anymore (HTTP Error 403.7 - Forbidden).
Of course I imported the client certificate in the Personal store and I made sure Client Certificate Negotiation is enabled.
I also tried openssl s_client -connect 127.0.0.1:443 -state -debug but I couldn't really make sense of the result... The only thing what's weird is that my CA doesn't show up in the Acceptable client certificate CA names section.
Anything else I could try?
Update:
I think it doesn't matter but my server certificate is set up for 127.0.0.1. Therefore I'm using https://127.0.0.1/... in my browsers.
Update2:
Using Wireshark I noticed that my servers' response depends on the client:
Fiddler (OK):
Client Hello
Server Hello, Certificate, Server Hello Done
Browser (Not OK):
Client Hello
Server Hello, Change Cipher Spec, Encrypted Handshake Message
Update3:
After enabling clientcertnegotiation the server response is different but still doesn't work:
Server Hello, Certificate
Certificate Request
Certificate, Client Key Exchange, Change Cipher Spec, Encrypted Handshake Message
My self-signed CA doesn't seem to be in the Distinguished Names list...
Update4:
SSL Settings: Checked Require SSL and Client certificates set as Required. Client cert shows up in Personal and the intended purpose is Client Authentication.
I finally found the issue and a workaround:
As mentioned in Update3, Distinguished Names doesn't contain my CA. This is because Distinguished Names has a limit of 2^14 bytes (16384 bytes). Because I do have a lot of CA installed on my machine my CA simply didn't make it in. The TLS standard would allow to send multiple messages but unfortunately Windows doesn't support this!
As mentioned here you have a few possibilities. The simplest one is this:
At your server add a DWORD (not QWORD!) value called SendTrustedIssuerList in your registry under HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL and set it to 0. This will prevent your server from sending a list at all, letting the client choose from any installed client certificate.
Unfortunately I couldn't see any traces in the Event Viewer (as reported elsewhere). Therefore the issue wasn't easy to spot (I had to use Wireshark in order to check Distinguished Names).
Use the Accept option instead of the Require option of the "Client certificates" feature.
In IIS Manager, locate the Web application for which you want to change the SSL setting.
In Features View, double-click SSL Settings.
On the SSL Settings page, select the Accept option under Client certificates.
In the Actions pane, click Apply.
More info here
Client certificate should be imported in CurrentUser\My store with private key (i.e. p12 or pfx file usually).
CA certificate should be in LocalMachine\Root store so that IIS trusts all certificates issued by the CA and the CA is trusted for every user on the computer.
CRL issued by the CA should be either available through URL (specified in every end entity certificate that CA issued) or imported in LocalMachine\My store.
NOTE: openssl doesn't use windows certificate store so this will have no efect on openssl s_client -connect 127.0.0.1:443 -state