Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Boost, asio, https, and host/certificate verifcation

I'm looking at Boost's SSL Client. There's a reference to OpenSSL in the comments (sorry, no line numbers):

// The verify callback can be used to check whether the certificate that is
// being presented is valid for the peer. For example, RFC 2818 describes
// the steps involved in doing this for HTTPS. Consult the OpenSSL
// documentation for more details. Note that the callback is called once
// for each certificate in the certificate chain, starting from the root
// certificate authority.

Proper OpenSSL use and verification can be tricky. From experience, I know I have to perform the following to use the library correctly:

  • Disable SSLv2, SSLv3, and Compression on the Context object
  • Provide the proper root certificate for chain building and checking
  • Call SSL_get_peer_certificate and verify the certificate is non-NULL
  • Call SSL_get_verify_result and verify the result is X509_V_OK
  • Perform name matching (CN or SAN must match requested host)

OpenSSL 1.1.0 will provide name checking, but its only in HEAD at this point in time. From the OpenSSL Change Log:

Integrate hostname, email address and IP address checking with certificate
verification. New verify options supporting checking in opensl utility.

And:

New functions to check a hostname email or IP address against a
certificate. Add options x509 utility to print results of checks against
a certificate.

I don't see where Boost is performing any of the configurations or checks in the client code.

What precisely is Boost configuring, and what is it checking or verifying in its asio library component when using SSL?

like image 635
jww Avatar asked Sep 29 '13 03:09

jww


1 Answers

Short answer: The Boost callback function, from the link you cited, doesn't verify anything. It returns whatever preliminary verification result was supplied to it by OpenSSL (via bool preverified). If there is any fine grained verification required (like the CN match, etc.), it has to be done explicitly by the callback.

Long answer: By the time the OpenSSL (or the Boost wrapper for OpenSSL) calls the verification function, in this case, bool verify_certificate(bool preverified, boost::asio::ssl::verify_context& ctx), a set of preliminary (or mandatory) verification is already done by OpenSSL. This is explained in the documentation.

The certificate chain is checked starting with the deepest nesting level (the root CA certificate) and worked upward to the peer's certificate. At each level signatures and issuer attributes are checked. Whenever a verification error is found, the error number is stored in x509_ctx and verify_callback is called with preverify_ok=0. By applying X509_CTX_store_* functions verify_callback can locate the certificate in question and perform additional steps (see EXAMPLES). If no error is found for a certificate, verify_callback is called with preverify_ok=1 before advancing to the next level.

The documentation also cites an example of how a more fine-grained verification callback could be written. You can draw inspiration from that depending on what your needs are.

EDIT: To be sure that Boost's internal callback function doesn't do anything special other than calling the application callback function, I took a look at engine.ipp, the C++ module that invokes OpenSSL's SSL_set_verify to set up callback functions. Take a look at how verify_callback_function is implemented. It simply invokes the application callback.

like image 124
Karthik Avatar answered Oct 25 '22 20:10

Karthik