Join the Stack Overflow Community
Stack Overflow is a community of 6.3 million programmers, just like you, helping each other.
Join them; it only takes a minute:
Sign up

I would want my C/C++ client to authenticate the server via SSL. I first downloaded the certificate file from the server with
openssl s_client -showcerts -connect www.openssl.org:443 </dev/null 2>/dev/null | openssl x509 -outform PEM > mycertfile.pem

Then in my application I do the following API invocations (pseudo code):


// Register the error strings for libcrypto & libssl
SSL_load_error_strings();
// Register the available ciphers and digests
SSL_library_init();
// New context saying we are a client, and using SSL 2 or 3
ctx = SSL_CTX_new(SSLv23_client_method());
// load the certificate
if(!SSL_CTX_load_verify_locations(ctx, "mycertfile.pem", 0))
  ...
// Create an SSL struct for the connection
ssl = SSL_new(ctx);
// Connect the SSL struct to our pre-existing TCP/IP socket connection
if (!SSL_set_fd(ssl, sd))
  ...
// Initiate SSL handshake
if(SSL_connect(ssl) != 1)
  ...
// form this point onwards the SSL connection is established and works
// perfectly, I would be able to send and receive encrypted data
// **Crucial point now**
// Get certificate (it works)
X509 *cert = SSL_get_peer_certificate(ssl);
if(cert) {
  // the below API returns code 19
  const long cert_res = SSL_get_verify_result(ssl);
  if(cert_res == X509_V_OK) {
    printf("Certificate verified!\n");
  }
  X509_free(cert);
}

Above code works fine if I don't mind checking the certificate and I'm just interested in an encrypted connection.
Problem with it is that when I try to verify the authenticity of the server, I do get the certificate from SSL_get_peer_certificate but then the verification of results doesn't work even if I've just downloaded the certificate 5 minutes before.

What am I doing wrong?

All this is on Ubuntu 12.04.03 x86-64 with gcc and openssl.

Thanks, Ema

share|improve this question
up vote 1 down vote accepted

You should only call SSL_CTX_load_verify_locations() if you have a more complete set of CA certificates than what OpenSSL already provides, or if you are connecting to a server that has used a non-standard CA to sign its cert, and for which you have the CA certificate to verify the server cert. Otherwise, you should call SSL_CTX_set_default_verify_paths() instead.

// load the certificate^H^H^H^H^H^H^H^H^H^H^H^H CA trust-store
if(!SSL_CTX_set_default_verify_paths(ctx))
  ...

On a side note, your program had another error. You passed the wrong pointer to SSL_get_verify_result(). Instead of passing in a SSL_CTX *, you should pass in the SSL *. The compiler should have warned you about this error.

  const long cert_res = SSL_get_verify_result(ssl);
share|improve this answer
    
A pastebin of a simplified version of your program that I used for testing. – jxh Sep 19 '13 at 18:29

The certificate you just downloaded should have been signed by a certificate authority (CA). You need to load the certificate of the CA (or the root CA) and not the certificate itself. Since you loaded the server's certificate directly into the SSL_CTX_load_verify_locations, the verification routine SSL_get_verify_result returned with a failure code. Most likely the verification code must have been 19 (X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN).

That said, OpenSSL comes with a built-in set of CAs (and root CAs) that you can use in your client application. The path to these certificates, on a Linux distribution, is typically /etc/ssl/certs. So, you can try changing your SSL_CTX_load_verify_locations as below:

if (!SSL_CTX_load_verify_locations(ctx, NULL, "/etc/ssl/certs"))
   ...

Of course, this assumes that /etc/ssl/certs exists and has the relevant certificates (one of which signed the server certificate). If you are authenticating a well known host, you will most likely find the CA in /etc/ssl/certs.

share|improve this answer
    
it works as per below. I'll tick below's given seems a bit more standard... – Emanuele Sep 19 '13 at 18:33

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.