summaryrefslogtreecommitdiff
path: root/src/libwaitress
diff options
context:
space:
mode:
authorLars-Dominik Braun <lars@6xq.net>2011-11-11 14:45:21 +0100
committerLars-Dominik Braun <lars@6xq.net>2011-11-11 15:24:50 +0100
commita0e4f1e0f5989505f4aab10d64194b635f9af53c (patch)
tree6a7fe01f25d632b8fe40859af96ab96a3576022b /src/libwaitress
parentfb1b9c541346b3cfc80305ef12ee87ced70d5037 (diff)
downloadpianobar-a0e4f1e0f5989505f4aab10d64194b635f9af53c.tar.gz
pianobar-a0e4f1e0f5989505f4aab10d64194b635f9af53c.tar.bz2
pianobar-a0e4f1e0f5989505f4aab10d64194b635f9af53c.zip
waitress: Fingerprint check
Reduces memory usage, protects against 0wned CA's and avoids ca-bundle confusion. Closes #175
Diffstat (limited to 'src/libwaitress')
-rw-r--r--src/libwaitress/waitress.c40
-rw-r--r--src/libwaitress/waitress.h4
2 files changed, 13 insertions, 31 deletions
diff --git a/src/libwaitress/waitress.c b/src/libwaitress/waitress.c
index 8bb519a..7082ffd 100644
--- a/src/libwaitress/waitress.c
+++ b/src/libwaitress/waitress.c
@@ -53,21 +53,11 @@ typedef struct {
size_t pos;
} WaitressFetchBufCbBuffer_t;
-WaitressReturn_t WaitressInit (WaitressHandle_t *waith, const char *caPath) {
+void WaitressInit (WaitressHandle_t *waith) {
assert (waith != NULL);
memset (waith, 0, sizeof (*waith));
waith->timeout = 30000;
- if (caPath != NULL) {
- gnutls_certificate_allocate_credentials (&waith->tlsCred);
- if (gnutls_certificate_set_x509_trust_file (waith->tlsCred, caPath,
- GNUTLS_X509_FMT_PEM) <= 0) {
- return WAITRESS_RET_TLS_TRUSTFILE_ERR;
- }
- waith->tlsInitialized = true;
- }
-
- return WAITRESS_RET_OK;
}
void WaitressFree (WaitressHandle_t *waith) {
@@ -75,9 +65,6 @@ void WaitressFree (WaitressHandle_t *waith) {
free (waith->url.url);
free (waith->proxy.url);
- if (waith->tlsInitialized) {
- gnutls_certificate_free_credentials (waith->tlsCred);
- }
memset (waith, 0, sizeof (*waith));
}
@@ -709,22 +696,10 @@ static int WaitressTlsVerify (gnutls_session_t session) {
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;
@@ -739,7 +714,14 @@ static int WaitressTlsVerify (gnutls_session_t session) {
return GNUTLS_E_CERTIFICATE_ERROR;
}
- if (gnutls_x509_crt_check_hostname (cert, waith->url.host) == 0) {
+ 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;
+ }
+
+ if (memcmp (fingerprint, waith->tlsFingerprint, sizeof (fingerprint)) != 0) {
return GNUTLS_E_CERTIFICATE_ERROR;
}
@@ -1036,8 +1018,6 @@ WaitressReturn_t WaitressFetchCall (WaitressHandle_t *waith) {
waith->request.write = WaitressOrdinaryWrite;
if (waith->url.tls) {
- assert (waith->tlsInitialized);
-
waith->request.read = WaitressGnutlsRead;
waith->request.write = WaitressGnutlsWrite;
gnutls_init (&waith->request.tlsSession, GNUTLS_CLIENT);
@@ -1046,6 +1026,7 @@ WaitressReturn_t WaitressFetchCall (WaitressHandle_t *waith) {
"PERFORMANCE", &err) != GNUTLS_E_SUCCESS) {
return WAITRESS_RET_ERR;
}
+ gnutls_certificate_allocate_credentials (&waith->tlsCred);
if (gnutls_credentials_set (waith->request.tlsSession,
GNUTLS_CRD_CERTIFICATE,
waith->tlsCred) != GNUTLS_E_SUCCESS) {
@@ -1083,6 +1064,7 @@ WaitressReturn_t WaitressFetchCall (WaitressHandle_t *waith) {
if (waith->url.tls) {
gnutls_bye (waith->request.tlsSession, GNUTLS_SHUT_RDWR);
gnutls_deinit (waith->request.tlsSession);
+ gnutls_certificate_free_credentials (waith->tlsCred);
}
close (waith->request.sockfd);
diff --git a/src/libwaitress/waitress.h b/src/libwaitress/waitress.h
index e1cf303..7e4401a 100644
--- a/src/libwaitress/waitress.h
+++ b/src/libwaitress/waitress.h
@@ -92,8 +92,8 @@ typedef struct {
void *data;
WaitressCbReturn_t (*callback) (void *, size_t, void *);
int timeout;
+ const char *tlsFingerprint;
gnutls_certificate_credentials_t tlsCred;
- bool tlsInitialized;
/* per-request data */
struct {
@@ -110,7 +110,7 @@ typedef struct {
} request;
} WaitressHandle_t;
-WaitressReturn_t WaitressInit (WaitressHandle_t *, const char *);
+void WaitressInit (WaitressHandle_t *);
void WaitressFree (WaitressHandle_t *);
bool WaitressSetProxy (WaitressHandle_t *, const char *);
char *WaitressUrlEncode (const char *);