summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Stenberg <daniel@haxx.se>2020-06-26 23:26:01 +0200
committerDaniel Stenberg <daniel@haxx.se>2020-06-28 23:27:37 +0200
commitb25574367cf094e912d8ae6ccaf1d255d454869f (patch)
tree5fb64231850f2ae37579848b67c86b066904c76d
parent40b4fdb88fdec3627147129d1f71a815842ec638 (diff)
downloadcurl-bagder/ssl-compare-blobs.tar.gz
vtls: compare blobs when finding a connection to reusebagder/ssl-compare-blobs
Reported-by: Gergely Nagy Fixes #5617 Closes #5619
-rw-r--r--lib/url.c4
-rw-r--r--lib/urldata.h1
-rw-r--r--lib/vtls/vtls.c42
3 files changed, 46 insertions, 1 deletions
diff --git a/lib/url.c b/lib/url.c
index 4e5587d34..a1a6b6910 100644
--- a/lib/url.c
+++ b/lib/url.c
@@ -3609,6 +3609,7 @@ static CURLcode create_conn(struct Curl_easy *data,
data->set.str[STRING_SSL_CIPHER13_LIST_ORIG];
data->set.ssl.primary.pinned_key =
data->set.str[STRING_SSL_PINNEDPUBLICKEY_ORIG];
+ data->set.ssl.primary.cert_blob = data->set.blobs[BLOB_CERT_ORIG];
#ifndef CURL_DISABLE_PROXY
data->set.proxy_ssl.primary.CApath = data->set.str[STRING_SSL_CAPATH_PROXY];
@@ -3622,6 +3623,7 @@ static CURLcode create_conn(struct Curl_easy *data,
data->set.str[STRING_SSL_CIPHER13_LIST_PROXY];
data->set.proxy_ssl.primary.pinned_key =
data->set.str[STRING_SSL_PINNEDPUBLICKEY_PROXY];
+ data->set.proxy_ssl.primary.cert_blob = data->set.blobs[BLOB_CERT_PROXY];
data->set.proxy_ssl.CRLfile = data->set.str[STRING_SSL_CRLFILE_PROXY];
data->set.proxy_ssl.issuercert = data->set.str[STRING_SSL_ISSUERCERT_PROXY];
data->set.proxy_ssl.cert = data->set.str[STRING_CERT_PROXY];
@@ -3655,7 +3657,7 @@ static CURLcode create_conn(struct Curl_easy *data,
data->set.ssl.issuercert_blob = data->set.blobs[BLOB_SSL_ISSUERCERT_ORIG];
if(!Curl_clone_primary_ssl_config(&data->set.ssl.primary,
- &conn->ssl_config)) {
+ &conn->ssl_config)) {
result = CURLE_OUT_OF_MEMORY;
goto out;
}
diff --git a/lib/urldata.h b/lib/urldata.h
index 1fc25196a..f80a02def 100644
--- a/lib/urldata.h
+++ b/lib/urldata.h
@@ -229,6 +229,7 @@ struct ssl_primary_config {
char *cipher_list; /* list of ciphers to use */
char *cipher_list13; /* list of TLS 1.3 cipher suites to use */
char *pinned_key;
+ struct curl_blob *cert_blob;
BIT(verifypeer); /* set TRUE if this is desired */
BIT(verifyhost); /* set TRUE if CN/SAN must match hostname */
BIT(verifystatus); /* set TRUE if certificate status must be checked */
diff --git a/lib/vtls/vtls.c b/lib/vtls/vtls.c
index 1cce961a6..c3a55fb1c 100644
--- a/lib/vtls/vtls.c
+++ b/lib/vtls/vtls.c
@@ -63,6 +63,7 @@
#include "warnless.h"
#include "curl_base64.h"
#include "curl_printf.h"
+#include "strdup.h"
/* The last #include files should be: */
#include "curl_memory.h"
@@ -82,6 +83,44 @@
else \
dest->var = NULL;
+#define CLONE_BLOB(var) \
+ if(blobdup(&dest->var, source->var)) \
+ return FALSE;
+
+static CURLcode blobdup(struct curl_blob **dest,
+ struct curl_blob *src)
+{
+ DEBUGASSERT(dest);
+ DEBUGASSERT(!*dest);
+ if(src) {
+ /* only if there's data to dupe! */
+ struct curl_blob *d;
+ d = malloc(sizeof(struct curl_blob) + src->len);
+ if(!d)
+ return CURLE_OUT_OF_MEMORY;
+ d->len = src->len;
+ /* Always duplicate because the connection may survive longer than the
+ handle that passed in the blob. */
+ d->flags = CURL_BLOB_COPY;
+ d->data = (void *)((char *)d + sizeof(struct curl_blob));
+ memcpy(d->data, src->data, src->len);
+ *dest = d;
+ }
+ return CURLE_OK;
+}
+
+/* returns TRUE if the blobs are identical */
+static bool blobcmp(struct curl_blob *first, struct curl_blob *second)
+{
+ if(!first && !second) /* both are NULL */
+ return TRUE;
+ if(!first || !second) /* one is NULL */
+ return FALSE;
+ if(first->len != second->len) /* different sizes */
+ return FALSE;
+ return !memcmp(first->data, second->data, first->len); /* same data */
+}
+
bool
Curl_ssl_config_matches(struct ssl_primary_config *data,
struct ssl_primary_config *needle)
@@ -91,6 +130,7 @@ Curl_ssl_config_matches(struct ssl_primary_config *data,
(data->verifypeer == needle->verifypeer) &&
(data->verifyhost == needle->verifyhost) &&
(data->verifystatus == needle->verifystatus) &&
+ blobcmp(data->cert_blob, needle->cert_blob) &&
Curl_safe_strcasecompare(data->CApath, needle->CApath) &&
Curl_safe_strcasecompare(data->CAfile, needle->CAfile) &&
Curl_safe_strcasecompare(data->clientcert, needle->clientcert) &&
@@ -115,6 +155,7 @@ Curl_clone_primary_ssl_config(struct ssl_primary_config *source,
dest->verifystatus = source->verifystatus;
dest->sessionid = source->sessionid;
+ CLONE_BLOB(cert_blob);
CLONE_STRING(CApath);
CLONE_STRING(CAfile);
CLONE_STRING(clientcert);
@@ -137,6 +178,7 @@ void Curl_free_primary_ssl_config(struct ssl_primary_config *sslc)
Curl_safefree(sslc->cipher_list);
Curl_safefree(sslc->cipher_list13);
Curl_safefree(sslc->pinned_key);
+ Curl_safefree(sslc->cert_blob);
}
#ifdef USE_SSL