35

While running the below command openssl s_client -host example.xyz -port 9093

I get the following error:

139810559764296:error:14094412:SSL routines:SSL3_READ_BYTES:sslv3 alert bad certificate:s3_pkt.c:1259:SSL alert number 42
39810559764296:error:140790E5:SSL routines:SSL23_WRITE:ssl handshake failure:s23_lib.c:184:

But at the end i get "Verify return code: 0 (ok)" message.

My question is what does the above alert signify, and if the SSL was actually successful.

SSL handshake has read 6648 bytes and written 354 bytes
New, TLSv1/SSLv3, Cipher is AES128-SHA
Server public key is 2048 bit
Secure Renegotiation IS supported
Compression: NONE
Expansion: NONE
SSL-Session:
Protocol  : TLSv1.2
Cipher    : AES128-SHA
Session-ID: xx
Session-ID-ctx:
Master-Key: xx
Key-Arg   : None
Krb5 Principal: None
PSK identity: None
PSK identity hint: None
Start Time: 1475096098
Timeout   : 300 (sec)
**Verify return code: 0 (ok)**

4 Answers 4

46

"Handshake failure" means the handshake failed, and there is no SSL/TLS connection. You should see that openssl exits to the shell (or CMD etc) and does not wait for input data to be sent to the server. "Verify return code 0" means that no problem was found in the server's certificate, either because it wasn't checked at all or because it was checked and was good (as far as OpenSSL's checks go, which doesn't cover everything); in this case by knowing the protocol we can deduce the latter case applies.

Receiving alert bad certificate (code 42) means the server demands you authenticate with a certificate, and you did not do so, and that caused the handshake failure. A few lines before the line SSL handshake has read ... and written ... you should see a line Acceptable client certificate CA names usually followed by several lines identifying CAs, possibly followed by a line beginning Client Certificate Types and maybe some about Requested Signature Algorithms depending on your OpenSSL version and the negotiated protocol.

Find a certificate issued by a CA in the 'acceptable' list, or if it was empty look for documentation on or about the server saying which CAs it trusts or contact the server operators or owners and ask them, plus the matching private key, both in PEM format, and specify them with -cert $file -key $file; if you have both in one file, as is possible with PEM, just use -cert $file. If you have them in a different format, either specify it, or search here and perhaps superuser and security.SX; there are already many Q&As about converting various certificate and privatekey formats. If your cert needs a "chain" or "intermediate" cert (or even more than one) to be verified, as is often the case for a cert from a public CA (versus an inhouse one) depending on how the server is configured, s_client requires a trick: either add the chain cert(s) to your system truststore, or create a local/temporary truststore containing the CA cert(s) you need to verify the server PLUS the chain cert(s) you need to send.

If you don't have such a certificate you either need to get one, which is a different question that requires much more detail to answer, or you need to find a way to connect to the server without using certificate authentication; again check the documentation and/or ask the operators/owners.

EDIT: It appears from comment you may have the client key and cert chain as well as server anchor(s?) in Java. On checking I don't see a good existing answer fully covering that case, so even though this probably won't search well:

# Assume Java keystore is type JKS (the default but not only possibility)
# named key.jks and the privatekey entry is named mykey (ditto)
# and the verify certs are in trust.jks in entries named trust1 trust2 etc.

# convert Java key entry to PKCS12 then PKCS12 to PEM files
keytool -importkeystore -srckeystore key.jks -destkeystore key.p12 -deststoretype pkcs12 -srcalias mykey 
openssl pkcs12 -in key.p12 -nocerts -out key.pem
openssl pkcs12 -in key.p12 -nokeys -clcerts -out cert.pem
openssl pkcs12 -in key.p12 -nokeys -cacerts -out chain.pem
# extract verify certs to individual PEM files
# (or if you 'uploaded' PEM files and still have them just use those)
keytool -keystore trust.jks -export -alias trust1 -rfc -file trust1.pem
keytool -keystore trust.jks -export -alias trust2 -rfc -file trust2.pem
... more if needed ...
# combine for s_client 
cat chain.pem trust*.pem >combined.pem
openssl s_client -connect host:port -key key.pem -cert cert.pem -CAfile combined.pem
4
  • hi Dave; below is the procedure we followed. 1: Upload the root CA, and intermediate certifiactes into the keystore. 2: Upload the signed Comodo certificate into the keystore. 3: Upload the root CA, and the intermediate certificates into the truststore. 4: Copy the keystore and trustore files to every node in the cluster (cassandra). The nodes use SSL for communication, and they seem to excahnge data without issues. However when i run the above mentioned SSL command, the issue rises.
    – kris433
    Sep 29, 2016 at 18:21
  • @kris433: what keystore is that? The procedure you describe sounds like the one for Java if (and only if) it already has generated a privatekey for which you obtain(ed) the 'signed Comodo cert', although if you're using a standard Java install it has a default truststore that includes Comodo, so you shouldn't need to change that. OpenSSL doesn't use any Java keystore or truststore and by default it doesn't use any keystore at all, which is why you need to specify files with -cert [-key]. If I have correctly interpreted your comment, see edit. Sep 30, 2016 at 7:57
  • Thanks a lot Dave. This worked perfectly. You saved my week. If you ever come to Philadelphia, the cheese-steak and Gelato are on me ;). Thank you again.
    – kris433
    Sep 30, 2016 at 17:07
  • @kris433: you're welcome, but the StackExchange Official Way is to accept a helpful answer using the checkmark, so the system can automatically use this information in displaying results to other querents; see the 'tour' you were supposed to look at when you came to this site, or more specifically serverfault.com/help/someone-answers . Oct 1, 2016 at 6:25
2

In my case I got this error when the private key did not match the cert. I had updated the cert when mine expired and needed to create a new private key. However, I forgot to reference that in my app. When I pointed to the new private key - this error went away.

1

I got that same error when running ssl_test from the testsuite on an embedded target with the wrong date and time setting. The target time was set to the year 2000, which was older than the supplied test certificates. Setting the target time/year to 2020 fixed the problem.

1
  • I got this when accessing a site from a VirtualBox VM that had been powered off (saved) since 2021, and not running NTP.
    – Kaz
    Apr 28, 2022 at 21:05
0

This error can also appear if you're trying to connect to a [misconfigured] machine that doesn't actually need a client certificate to connect.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .