21.03.2013 Views

Problem - Kevin Tafuro

Problem - Kevin Tafuro

Problem - Kevin Tafuro

SHOW MORE
SHOW LESS

Create successful ePaper yourself

Turn your PDF publications into a flip-book with our unique Google optimized e-Paper software.

You can use a whitelist in place of normal certificate verification routines. Whitelists<br />

are most often useful in servers that want to authenticate clients, rather than the<br />

other way around, but they can be used either way. In server mode, you can use the<br />

SSL_VERIFY_PEER flag to request a certificate from the client, but remember that the<br />

client does not have to supply a certificate in response to a request. If you want to<br />

require that the client respond, you also need to use the SSL_VERIFY_FAIL_IF_NO_<br />

PEER_CERT flag so that the connection is terminated if the client does not send a certificate.<br />

The downside to using these flags is that OpenSSLwill attempt to verify the certificate<br />

on its own. With a little trickery, we can short-circuit OpenSSL’s certificate verification<br />

routines and do a little post-connection verification of our own. We will do<br />

this by setting up a verify callback function that always returns success. The verify<br />

callback is called for each certificate in the chain when verifying a certificate. It is<br />

called with the X509_STORE_CTX containing everything relevant, as well as a boolean<br />

indicator of whether OpenSSLhas determined the certificate to be valid or not. Typically,<br />

the callback will return the same verification status, but it is not required. The<br />

callback can reverse the decision that OpenSSL has made.<br />

int spc_whitelist_callback(int ok, X509_STORE_CTX *store) {<br />

return 1;<br />

}<br />

Once the connection has been established, we can get a copy of the peer’s certificate,<br />

compute its fingerprint, and compare it against the fingerprints we have in our<br />

list. The list can be stored in memory, in a disk file, on a flash memory card, or on<br />

some other medium. How the list is stored is irrelevant; what is important is the<br />

comparison of fingerprints. The functions shown in the previous code are flexible in<br />

that they allow you to choose any message digest algorithm you like. Note, though,<br />

that if you are always using the same ones, the functions can be simplified, and you<br />

need not keep track of the fingerprint length because you know that a message digest<br />

is a fixed size (MD5 is 16 bytes; SHA1 is 20 bytes). The following snippet of code<br />

roughly demonstrates the work that needs to be done to employ whitelist-based certificate<br />

verification:<br />

int fingerprint_length;<br />

SSL *ssl;<br />

EVP_MD *digest;<br />

SSL_CTX *ctx;<br />

unsigned char fingerprint[EVP_MAX_MD_SIZE];<br />

spc_x509store_t spc_store;<br />

spc_init_x509store(&spc_store);<br />

spc_x509store_setcallback(&spc_store, spc_whitelist_callback);<br />

spc_x509store_setflags(&spc_store, SPC_X509STORE_SSL_VERIFY_PEER |<br />

SPC_X509STORE_SSL_VERIFY_FAIL_IF_NO_PEER_CERT);<br />

ctx = spc_create_sslctx(&spc_store);<br />

/* use the ctx to establish a connection. This will yield an SSL object */<br />

cert = SSL_get_peer_certificate(ssl);<br />

546 | Chapter 10: Public Key Infrastructure<br />

This is the Title of the Book, eMatter Edition<br />

Copyright © 2007 O’Reilly & Associates, Inc. All rights reserved.

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!