1

I have been trying to implement a very basic Boost SSL implementation to try and learn the basics. The server I want to communicate with had already given me their public key in plain text. I already put a lot of the other code (asynchronous connection, handshaking, etc) in.

I first tried to implement SSL without verification of their certificate using the following setup of the Boost SSL stream:

boost::asio::ssl::context ctxt(boost::asio::ssl::context::sslv23);
ctxt.set_verify_mode(boost::asio::ssl::verify_none);

This implementation worked fine and I was able to connect with the server. When I tried to implement the verification of the peer certificate, however, the handshaking fails. I tried using the following code:

boost::asio::ssl::context ctxt(boost::asio::ssl::context::sslv23);
ctxt.set_verify_mode(boost::asio::ssl::verify_peer);
ctxt.load_verify_file("peer.crt");

I put the "peer.crt" containing the public key (along with the -----BEGIN CERTIFICATE----- and -----END CERTIFICATE----- tags) in the directory where I am running my executable. For whatever reason the handshake now fails with the error code 336134278: certificate verify failed. I also tried putting the full path to the verify file in there but with no luck.

My questions are the following:

  1. Where should I be specifying the file name for the verify file in load_verify_file? Is it simply in the directory where I am running my executable?
  2. Am I not setting up the handshaking process with peer verification properly? I do not have my own verify callback as I assumed the peer verification would happen automatically if I specified it as such.
  3. Should I be handling the certificate in a certain way by installing it or something like that?
  4. Is there a better way of debugging this functionality? I am using VS10 and can only get to the ipp so I cannot actually view the verification taking place.

Any help is appreciated, thanks!

Tanner Sansbury
  • 51,153
  • 9
  • 112
  • 169
qubit
  • 25
  • 1
  • 6
  • I also tried passing in an error code in to the load_verify_file, but it did not come back with any errors. – qubit May 08 '14 at 14:23
  • You shouldn't need a callback (a default is provided) and either a relative or absolute path should work. I have successfully used `set_verify_mode()` and `load_verify_file()` as you have. My guess would be that your server's certificate is not self-signed (i.e. it has a chain depth of more than 1) and you don't have the entire chain of certificates in your `peer.crt` file. See [this page](https://www.openssl.org/docs/ssl/SSL_CTX_set_verify.html) for what is going on behind these calls. – rhashimoto May 08 '14 at 14:58
  • Yes I do believe the server certificate is not self-signed. This may be answered somewhere else, but how do I go about getting the entire chain of certificates needed other than asking the server host themselves? Or is there a way to just verify the top certificate? Thanks! – qubit May 08 '14 at 15:03

2 Answers2

1
  1. You should be able to use either a relative or absolute path.
  2. Your use of set_verify_mode() and load_verify_file() looks fine. I have done exactly this in my own code. A default verify callback is used if you do not specify one.
  3. You don't need to "install" the certificate.
  4. I don't know of easy ways to debug boost::asio SSL connections, but you can use OpenSSL command line tools, such as s_client, to test connections. boost::asio uses OpenSSL under the hood.

I suspect that you don't have the entire certificate chain of certificates in your file. You can extract them from your server with (replace www.google.com:443 with your server and port):

openssl s_client -connect www.google.com:443 -showcerts

If you only wish to check some of the certificates, e.g. only the leaf certificate, you can use your own verify callback. An example of a custom callback, as well as a description of the verification modes and options are on this page.

rhashimoto
  • 15,650
  • 2
  • 52
  • 80
  • You were right in that they did not provide me the entire certificate chain. After using the s_client command you provided on the host it worked perfect, thank you! – qubit May 08 '14 at 16:35
0

A good place to start is the HTTP Client in asio examples.

Are you calling set_verify_callback on the socket with the callback function to verify the certificate? E.g.:

bool verify_certificate(bool preverified, boost::asio::ssl::verify_context& ctx)
{
  char subject_name[256];
  X509* cert = X509_STORE_CTX_get_current_cert(ctx.native_handle());
  X509_NAME_oneline(X509_get_subject_name(cert), subject_name, 256);
  return preverified;
}
kenba
  • 4,303
  • 1
  • 23
  • 40
  • I am not, is it required that I must have a verification callback if I want to verify the certificate? If so, does the code you have listed above (and also in the boost client.cpp examples) verify the certificate? – qubit May 08 '14 at 14:39