It looks like boost just uses the OpenSSL interface.
I don't know boost much but I've implemented lots of OpenSSL internals for Perl and came to the following conclusions after reading the relevant parts of the boost source code:
To have mutual authentication with OpenSSL you have to use SSL_VERIFY_PEER
on the client side and SSL_VERIFY_PEER|SSL_VERIFY_FAIL_IF_NO_PEER_CERT
on the server side. If you use only SSL_VERIFY_PEER
on the server side it will only send the certificate request to the client, but silently accept if the client sends no certificate back.
With boost this would probably be:
ctx.set_verify_mode(ssl::verify_peer); // client side
ctx.set_verify_mode(ssl::verify_peer|ssl::verify_fail_if_no_peer_cert); // server side
If you set verify_mode this way it will verify the certificates against the configured trusted CAs (set with ctx.load_verify_file
or ctx.load_verify_path
).
If you have full control over the CA which signed the certificates (i.e. its your own CA) it might be enough for you to accept any certificates signed by this CA. But if you use a CA which also signed certificates you don't want to accept, like typically the case with public CAs, you also need to verify the contents of the certificate. Details how to do this depends on your protocol, but for the usual internet protocols like HTTP or SMTP this involves checking commonName and/or subjectAltNames of the certificate. Details like wildcard handling vary between the protocols.
Boost provides rfc2818_verification to help you with HTTP-style validation, although from reading the code I think the implementation is slightly wrong (multiple wildcards accepted, IDN wildcards allowed - see RFC6125 for requirements).
I don't know of any standards for verifying client certificates. Often just any certificate signed by a specific (private) CA will be accepted. Other times certificates from a public CA matching a specific e-mail pattern. It looks like boost does not help you much in this case, so you probably have to get OpenSSL SSL*
handle with sock.native_handle()
and then use OpenSSL functions to extract certificate (SSL_get_peer_certificate
) and to check the contents of the certificate (various X509_*
functions).
At least if public CAs are involved you should also check the revocation status of the certificates. It looks like boost does not provide a direct interface to CRL (certificate revocation list) so you have to use ctx.native_handle()
with the appropriate OpenSSL functions (X509_STORE_add_crl
etc). Using OCSP (online status revocation protocol) is way more complex and relevant OpenSSL functions are mostly undocumented, which means you have to read the OpenSSL source code to use them :(