A kinder, gentler verification --#-- The code we have so far is pretty harsh. If the verification fails for any reason, you can't connect. It might be a good idea to check the reason why the authentication failed, and perhaps to allow the connection to go ahead even if it did. (You could always just ignore the result from ssl_verify_cert_chain, but what's the point in that?)

We can modify OpenSSL's verification by specifying our own callback function that will be used internally by the verification code. Note that this callback will only be called if the cert chain fails the internal OpenSSL verification function. If the cert chain is good, the callback never runs.

int my_verify_callback(int ok, X509_STORE_CTX *ctx) { X509 *cert; int err; char c; /* the variable ok will be 0 here because the callback */ /* doesn't get called unless the chain is !ok */ cert = X509_STORE_CTX_get_current_cert(ctx); err = X509_STORE_CTX_get_error(ctx); printf("Error verifying %s\n", X509_NAME_oneline(X509_get_subject_name(cert), 0, 0)); printf("Error: number %d: %s\n", err, X509_verify_cert_error_string(err)); printf("Accept it anyway? (y/n) "); c = getchar(); if (c == 'y') ok = 1; return ok; }
To see all the possible errors you can encounter in this callback, look at the source code for the X509_verify_cert_error_string function. It's in a file called x509_text.c in the source distribution.

This implementation requires user intervention if the cert chain is bad. Of course, you might be using similar code in a robot or other automatonic code, in which case you'd want to put some decision logic in here.

Integrate this callback into your code this way:

SSL_CTX_load_verify_locations(ssl_ctx, "thawte.der", 0); -###SSL_CTX_set_verify(ssl_ctx, SSL_VERIFY_PEER, &my_verify_callback); ###- ssl = SSL_new(ssl_ctx); result = SSLsocket(ssl, hostName, port); if (result < 0) { sprintf(dieString, "Could not get secure socket on %s:%d", hostName, port); die(dieString); } chain = SSL_get_peer_cert_chain(ssl); result = ssl_verify_cert_chain(ssl, chain);