diff options
| author | Lars-Dominik Braun <lars@6xq.net> | 2011-09-26 16:04:51 +0200 | 
|---|---|---|
| committer | Lars-Dominik Braun <lars@6xq.net> | 2011-11-09 20:10:16 +0100 | 
| commit | d55bc3b41b6dd5e23a1c0c5c20d2a507864d5367 (patch) | |
| tree | dca98d5ecb32e84fd059bd6ebb4a55b2a001d75c /src | |
| parent | 50a5cac2445bc0c199958ac04d5127e4be09fb1e (diff) | |
| download | pianobar-windows-d55bc3b41b6dd5e23a1c0c5c20d2a507864d5367.tar.gz pianobar-windows-d55bc3b41b6dd5e23a1c0c5c20d2a507864d5367.tar.bz2 pianobar-windows-d55bc3b41b6dd5e23a1c0c5c20d2a507864d5367.zip | |
waitress: Server certificate verification
Diffstat (limited to 'src')
| -rw-r--r-- | src/libwaitress/waitress.c | 62 | 
1 files changed, 62 insertions, 0 deletions
| diff --git a/src/libwaitress/waitress.c b/src/libwaitress/waitress.c index c7ae583..aff023b 100644 --- a/src/libwaitress/waitress.c +++ b/src/libwaitress/waitress.c @@ -40,6 +40,10 @@ THE SOFTWARE.  #include <errno.h>  #include <assert.h> +#ifdef ENABLE_TLS +#include <gnutls/x509.h> +#endif +  #include "config.h"  #include "waitress.h" @@ -687,6 +691,58 @@ static int WaitressParseStatusline (const char * const line) {  	return -1;  } +#ifdef ENABLE_TLS +/*	verify server certificate + */ +static int WaitressTlsVerify (gnutls_session_t session) { +	unsigned int status, certListSize; +	const gnutls_datum_t *certList; +	gnutls_x509_crt_t cert; +	const WaitressHandle_t *waith; + +	waith = gnutls_session_get_ptr (session); +	assert (waith != NULL); + +	if (gnutls_certificate_verify_peers2 (session, &status) != GNUTLS_E_SUCCESS) { +		return GNUTLS_E_CERTIFICATE_ERROR; +	} + +	/* don't accept invalid certs */ +	if (status & (GNUTLS_CERT_INVALID | GNUTLS_CERT_SIGNER_NOT_FOUND | +			GNUTLS_CERT_REVOKED | GNUTLS_CERT_EXPIRED | +			GNUTLS_CERT_NOT_ACTIVATED)) { +		return GNUTLS_E_CERTIFICATE_ERROR; +	} + +	if (gnutls_certificate_type_get (session) != GNUTLS_CRT_X509) { +		return GNUTLS_E_CERTIFICATE_ERROR; +	} + +	/* check hostname */ +	if ((certList = gnutls_certificate_get_peers (session, +			&certListSize)) == NULL) { +		return GNUTLS_E_CERTIFICATE_ERROR; +	} + +	if (gnutls_x509_crt_init (&cert) != GNUTLS_E_SUCCESS) { +		return GNUTLS_E_CERTIFICATE_ERROR; +	} + +	if (gnutls_x509_crt_import (cert, &certList[0], +			GNUTLS_X509_FMT_DER) != GNUTLS_E_SUCCESS) { +		return GNUTLS_E_CERTIFICATE_ERROR; +	} + +	if (gnutls_x509_crt_check_hostname (cert, waith->url.host) == 0) { +		return GNUTLS_E_CERTIFICATE_ERROR; +	} + +	gnutls_x509_crt_deinit (cert); + +	return 0; +} +#endif +  /*	Connect to server   */  static WaitressReturn_t WaitressConnect (WaitressHandle_t *waith) { @@ -987,6 +1043,12 @@ WaitressReturn_t WaitressFetchCall (WaitressHandle_t *waith) {  				WaitressPollRead);  		gnutls_transport_set_push_function (waith->request.tlsSession,  				WaitressPollWrite); + +		/* certificate verification function */ +		gnutls_session_set_ptr (waith->request.tlsSession, +				(gnutls_transport_ptr_t) waith); +		gnutls_certificate_set_verify_function (waith->request.tlsCred, +				WaitressTlsVerify);  	}  #else  	if (waith->url.tls) { | 
