Is the alert “SSL3_READ_BYTES:sslv3 alert bad certificate” indicating that the SSL failed
"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.
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
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.