From d33a389bf256821f22cf80a9d630c18cef42870d Mon Sep 17 00:00:00 2001
From: Lars-Dominik Braun <lars@6xq.net>
Date: Sat, 1 Dec 2012 13:25:09 +0100
Subject: waitress: Add TLS fingerprint mismatch error code

---
 src/libwaitress/waitress.c | 30 ++++++++++++++++--------------
 src/libwaitress/waitress.h |  5 ++---
 2 files changed, 18 insertions(+), 17 deletions(-)

diff --git a/src/libwaitress/waitress.c b/src/libwaitress/waitress.c
index 8a8315f..efb76a9 100644
--- a/src/libwaitress/waitress.c
+++ b/src/libwaitress/waitress.c
@@ -1,5 +1,5 @@
 /*
-Copyright (c) 2009-2011
+Copyright (c) 2009-2012
 	Lars-Dominik Braun <lars@6xq.net>
 
 Permission is hereby granted, free of charge, to any person obtaining a copy
@@ -725,44 +725,45 @@ static int WaitressParseStatusline (const char * const line) {
 
 /*	verify server certificate
  */
-static int WaitressTlsVerify (const WaitressHandle_t *waith) {
+static WaitressReturn_t WaitressTlsVerify (const WaitressHandle_t *waith) {
 	gnutls_session_t session = waith->request.tlsSession;
 	unsigned int certListSize;
 	const gnutls_datum_t *certList;
 	gnutls_x509_crt_t cert;
 
 	if (gnutls_certificate_type_get (session) != GNUTLS_CRT_X509) {
-		return GNUTLS_E_CERTIFICATE_ERROR;
+		return WAITRESS_RET_TLS_HANDSHAKE_ERR;
 	}
 
 	if ((certList = gnutls_certificate_get_peers (session,
 			&certListSize)) == NULL) {
-		return GNUTLS_E_CERTIFICATE_ERROR;
+		return WAITRESS_RET_TLS_HANDSHAKE_ERR;
 	}
 
 	if (gnutls_x509_crt_init (&cert) != GNUTLS_E_SUCCESS) {
-		return GNUTLS_E_CERTIFICATE_ERROR;
+		return WAITRESS_RET_TLS_HANDSHAKE_ERR;
 	}
 
 	if (gnutls_x509_crt_import (cert, &certList[0],
 			GNUTLS_X509_FMT_DER) != GNUTLS_E_SUCCESS) {
-		return GNUTLS_E_CERTIFICATE_ERROR;
+		return WAITRESS_RET_TLS_HANDSHAKE_ERR;
 	}
 
 	char fingerprint[20];
 	size_t fingerprintSize = sizeof (fingerprint);
 	if (gnutls_x509_crt_get_fingerprint (cert, GNUTLS_DIG_SHA1, fingerprint,
 			&fingerprintSize) != 0) {
-		return GNUTLS_E_CERTIFICATE_ERROR;
+		return WAITRESS_RET_TLS_HANDSHAKE_ERR;
 	}
 
+	assert (waith->tlsFingerprint != NULL);
 	if (memcmp (fingerprint, waith->tlsFingerprint, sizeof (fingerprint)) != 0) {
-		return GNUTLS_E_CERTIFICATE_ERROR;
+		return WAITRESS_RET_TLS_FINGERPRINT_MISMATCH;
 	}
 
 	gnutls_x509_crt_deinit (cert);
 
-	return 0;
+	return WAITRESS_RET_OK;
 }
 
 /*	Connect to server
@@ -823,11 +824,12 @@ static WaitressReturn_t WaitressConnect (WaitressHandle_t *waith) {
 	}
 
 	if (waith->url.tls) {
+		WaitressReturn_t wRet;
+
 		/* set up proxy tunnel */
 		if (WaitressProxyEnabled (waith)) {
 			char buf[256];
 			size_t size;
-			WaitressReturn_t wRet;
 
 			snprintf (buf, sizeof (buf), "CONNECT %s:%s HTTP/"
 					WAITRESS_HTTP_VERSION "\r\n"
@@ -855,8 +857,8 @@ static WaitressReturn_t WaitressConnect (WaitressHandle_t *waith) {
 			return WAITRESS_RET_TLS_HANDSHAKE_ERR;
 		}
 
-		if (WaitressTlsVerify (waith) != 0) {
-			return WAITRESS_RET_TLS_HANDSHAKE_ERR;
+		if ((wRet = WaitressTlsVerify (waith)) != WAITRESS_RET_OK) {
+			return wRet;
 		}
 
 		/* now we can talk encrypted */
@@ -1199,8 +1201,8 @@ const char *WaitressErrorToStr (WaitressReturn_t wRet) {
 			return "TLS handshake failed.";
 			break;
 
-		case WAITRESS_RET_TLS_TRUSTFILE_ERR:
-			return "Loading root certificates failed.";
+		case WAITRESS_RET_TLS_FINGERPRINT_MISMATCH:
+			return "TLS fingerprint mismatch.";
 			break;
 
 		default:
diff --git a/src/libwaitress/waitress.h b/src/libwaitress/waitress.h
index da516bb..6a0a66f 100644
--- a/src/libwaitress/waitress.h
+++ b/src/libwaitress/waitress.h
@@ -1,5 +1,5 @@
 /*
-Copyright (c) 2009-2011
+Copyright (c) 2009-2012
 	Lars-Dominik Braun <lars@6xq.net>
 
 Permission is hereby granted, free of charge, to any person obtaining a copy
@@ -74,11 +74,10 @@ typedef enum {
 	WAITRESS_RET_READ_ERR,
 	WAITRESS_RET_CONNECTION_CLOSED,
 	WAITRESS_RET_DECODING_ERR,
-	WAITRESS_RET_TLS_DISABLED,
 	WAITRESS_RET_TLS_WRITE_ERR,
 	WAITRESS_RET_TLS_READ_ERR,
 	WAITRESS_RET_TLS_HANDSHAKE_ERR,
-	WAITRESS_RET_TLS_TRUSTFILE_ERR,
+	WAITRESS_RET_TLS_FINGERPRINT_MISMATCH,
 } WaitressReturn_t;
 
 /*	reusable handle
-- 
cgit v1.2.3