boost::asio provides a very convenient way of using SSL sockets. However, the information about the peer certificate provided is rather limited (read: non-existant) and there is only the option to either accept trusted certificates, or accept any certificate.

If you want to give feedback to the user and/or check the certificate digest (fingerprint), you have to resort to plain OpenSSL (given that OpenSSL is used as backend). For a ssl-socket, the following snipplet prints the issuer and fingerprints. Good idea would be to add a custom verification here as well.

Beware of very hackish code:

 1 #include <openssl/ssl.h>
 2 #include <openssl/x509.h>
 3 #include <openssl/evp.h>
 4 ...
 5 boost::asio::ssl::stream<boost::asio::ip::tcp::socket> ssl_socket_(io_service, ctx);
 6 ...
 7 bool connection::check_peer_certificate() {
 8 	// impl() provides access to the underlying SSL*
 9 	// struct from OpenSSL!
10 	SSL *ssl = ssl_socket_.impl()->ssl;
11 
12 	// Use OpenSSL API do get what you desire
13 	X509 *cert = SSL_get_peer_certificate(ssl);
14 
15 	printf("ISSUER: "); X509_NAME_print_ex_fp(stdout, X509_get_issuer_name(cert), 0, 0); printf("\n");
16 	printf("SUBJECT: "); X509_NAME_print_ex_fp(stdout, X509_get_subject_name(cert), 0, 0); printf("\n");
17 
18 
19 	unsigned int md5_size;
20 	unsigned char md5[EVP_MAX_MD_SIZE];
21 	X509_digest(cert, EVP_md5(), md5, &md5_size);
22 	printf("MD5: ");
23 	for(unsigned i=0; i<md5_size; ++i) printf("%02X ", md5[i]);
24 	printf("\n");
25 
26 	unsigned int sha1_size;
27 	unsigned char sha1[EVP_MAX_MD_SIZE];
28 	X509_digest(cert, EVP_sha1(), sha1, &sha1_size);
29 	printf("SHA1: ");
30 	for(unsigned i=0; i<sha1_size; ++i) printf("%02X ", sha1[i]);
31 	printf("\n");
32 
33 	X509_free(cert);
34 	// Better would be to validate cert, export fingerprints and
35 	// information so they can be presented to user and
36 	// return false if it does not validate ;)
37 	return true;
38 }