views:

106

answers:

2

I'm currently rewriting some existing technologies that were once using RSA Security's libraries into OpenSSL, but I'm starting to run into a few issues. Currently, all of the certificate verification code appears to be running without a hitch, until that is, I call SSL_connect().

Before, the call to SSL_connect() would produce SSL_ERROR_WANT_READ.

An answer to this issue on another forum suggested to me that SSL_connect() should be called until it stops producing SSL_ERROR_WANT_READ errors. Unforunately, this only produces something more confusing:

error:14090086:SSL routines:SSL3_GET_SERVER_CERTIFICATE:certificate verify failed

even though SSL_CTX_load_verify_locations() succeeds. Does anyone have any idea as to why a verification error wouldn't register with certificate methods and wait until SSL_connect() is triggered?

+2  A: 

Usually this error means that the server certificate your client received in response to SSL_connect() couldn't be verified.

This can happen for different reasons:

  • If the server certificate is self-signed, you'll have to authorize that on your SSL_CONTEXT.
  • If the server certificate was signed by a certificate authority that is not in the list of trusted CA certificates
  • If the server certificate is not valid yet or not valid anymore

Actually, you should set a callback for certificate verification and make it accept any certificate, so you can focus on the connection part. Once it works, just tweak your callback or check your certificates to be valid.

At any time you get a failure, you can call some SSL_get_error() function that will indicate you why the certificate was rejected.

(Unfortunately, I can't access my code base right now, so I cannot give concrete examples)


Here are some code samples from my own SSL Socket wrapper class, adapted for you:

// ctx is a SSL_CONTEXT
// internalCertificateVerificationCallback is a callback static method (or function)
ctx->setVerify(SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT, internalCertificateVerificationCallback);

Here is the definition for internalCertificateVerificationCallback:

int SecureSocket::internalCertificateVerificationCallback(int preverify_ok, X509_STORE_CTX* x509_ctx)
{
  //preverify_ok contains 1 if the pre-verification succeeded, 0 otherwise.

  return 1; // This accepts every certificate
}
ereOn
Thanks for the response, but I think I'm still a little confused. How do I "accept any certificate"? I tried using SSL_VERIFY_NONE in my SSL_CTX_set_verify() method call, but I don't think this is the route I want to take.Also, how to I attach a callback to the SSL_CTX_load_verify_locations() call? I thought it didn't accept a callback function. er, at least in C++~
kelly.dunn
@kelly.dunn: I added a few code samples that can probably help.I don't understand your remark about callback functions and `C++`: You can write and use `C` callbacks in `C++` without any issue. Just be careful that you specify either a function, or a **static** method, not a method (their signatures differ, due to the hidden `this` parameter).
ereOn
Oh I was just confused as to where you were saying to attach the callback function~ I forgot that SSL_set_verify() accepts one as its final paramater. Thanks a lot! I'll implement this shortly and see if it helps out :D
kelly.dunn
@kelly.dunn: If my answer satisfies your needs, don't forget to accept it ;)
ereOn
@ereOn My mistake, been so busy :P. Thanks for all your help :D
kelly.dunn
A: 

Even I am facing the same issue. I have used SSL_CTX_set_verify() function to set my static C callback function. During HTTPS transaction, my callback is also getting called with first parameter 0 or 1 (depending upon of the certificate verification is success or failure). But even if my certification verification is failure I want to continue. So I have hard coded to return value as 1 always from my callback function. But still I see the certification error and I don't get the page. Any suggestion please?

Manjunath