Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

boost asio SSL two way authentication

I need a snippet of code for a program i am writing with Boost Asio SSL. I have a system of two clients, that connect with each other. I require them to do a mutual authentication, so, that at the end of the handshake() command, both clients can be certain that the other client has the private key to the certificate they supplied. Both clients have a context object, lets call them ctx1and ctx2 and each client has a public certificate and a private key.

Is it possible to set up the context objects so, that when i call socket.handshake() the clients will do a two-way authentication. If not, what would be the correct way to go about to achieve my goal ?

like image 210
user3796577 Avatar asked Dec 14 '22 20:12

user3796577


1 Answers

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 :(

like image 52
Steffen Ullrich Avatar answered Dec 27 '22 06:12

Steffen Ullrich