view patches/0002-Add-CURLOPT_PEERCERT-option-to-pin-a-peer-cert.patch @ 1316:ff9cd05e861e

(issue166) Fix certificiate removal The index that should be removed came from the filter proxy model and did not map to the real index. This was broken.
author Andre Heinecke <andre.heinecke@intevation.de>
date Mon, 13 Oct 2014 17:23:35 +0200
parents 93325618ac7b
children
line wrap: on
line source
From e5c7feec5151299975fe03184cc322ea51fb45c2 Mon Sep 17 00:00:00 2001
From: Andre Heinecke <aheinecke@intevation.de>
Date: Fri, 12 Sep 2014 13:01:07 +0200
Subject: [PATCH 2/2] Add CURLOPT_PEERCERT option to pin a peer cert

    This is only implemented for a specific usecase with polarssl
---
 include/curl/curl.h          |  3 +++
 include/curl/typecheck-gcc.h |  1 +
 lib/url.c                    |  8 ++++++++
 lib/urldata.h                |  1 +
 lib/vtls/polarssl.c          | 41 +++++++++++++++++++++++++++++++++++++++++
 5 files changed, 54 insertions(+)

diff --git a/include/curl/curl.h b/include/curl/curl.h
index d40b2db..20a9d82 100644
--- a/include/curl/curl.h
+++ b/include/curl/curl.h
@@ -1611,6 +1611,9 @@ typedef enum {
   /* Pass in a bitmask of "header options" */
   CINIT(HEADEROPT, LONG, 229),
 
+  /* Peer certificate */
+  CINIT(PEERCERT, OBJECTPOINT, 230),
+
   CURLOPT_LASTENTRY /* the last unused */
 } CURLoption;
 
diff --git a/include/curl/typecheck-gcc.h b/include/curl/typecheck-gcc.h
index 69d41a2..241529d 100644
--- a/include/curl/typecheck-gcc.h
+++ b/include/curl/typecheck-gcc.h
@@ -258,6 +258,7 @@ _CURL_WARNING(_curl_easy_getinfo_err_curl_slist,
    (option) == CURLOPT_SSH_PRIVATE_KEYFILE ||                                 \
    (option) == CURLOPT_CRLFILE ||                                             \
    (option) == CURLOPT_ISSUERCERT ||                                          \
+   (option) == CURLOPT_PEERCERT ||                                            \
    (option) == CURLOPT_SOCKS5_GSSAPI_SERVICE ||                               \
    (option) == CURLOPT_SSH_KNOWNHOSTS ||                                      \
    (option) == CURLOPT_MAIL_FROM ||                                           \
diff --git a/lib/url.c b/lib/url.c
index 67126ab3..5721ee2 100644
--- a/lib/url.c
+++ b/lib/url.c
@@ -2015,6 +2015,14 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option,
     result = setstropt(&data->set.str[STRING_SSL_ISSUERCERT],
                        va_arg(param, char *));
     break;
+  case CURLOPT_PEERCERT:
+    /*
+     * Set peer certificate file
+     * to check peer certificate against
+     */
+    result = setstropt(&data->set.str[STRING_SSL_PEERCERT],
+                       va_arg(param, char *));
+    break;
   case CURLOPT_TELNETOPTIONS:
     /*
      * Set a linked list of telnet options
diff --git a/lib/urldata.h b/lib/urldata.h
index 8594c2f..a6dc1ae 100644
--- a/lib/urldata.h
+++ b/lib/urldata.h
@@ -1391,6 +1391,7 @@ enum dupstring {
   STRING_USERAGENT,       /* User-Agent string */
   STRING_SSL_CRLFILE,     /* crl file to check certificate */
   STRING_SSL_ISSUERCERT,  /* issuer cert file to check certificate */
+  STRING_SSL_PEERCERT,  /* issuer cert file to check certificate */
   STRING_USERNAME,        /* <username>, if used */
   STRING_PASSWORD,        /* <password>, if used */
   STRING_OPTIONS,         /* <options>, if used */
diff --git a/lib/vtls/polarssl.c b/lib/vtls/polarssl.c
index 08dc4c6..8f34901 100644
--- a/lib/vtls/polarssl.c
+++ b/lib/vtls/polarssl.c
@@ -403,6 +403,44 @@ polarssl_connect_step1(struct connectdata *conn,
   return CURLE_OK;
 }
 
+static int
+pinned_verify(void *pinned_cert_file_name, x509_crt *crt,
+              int depth, int *flags)
+{
+  x509_crt pinned_cert;
+  x509_crt *leaf = crt;
+  unsigned int i;
+  int ret;
+
+  if (pinned_cert_file_name == NULL || crt == NULL) {
+    *flags |= BADCERT_NOT_TRUSTED;
+    return *flags;
+  }
+
+  x509_crt_init(&pinned_cert);
+  ret = x509_crt_parse_file(&pinned_cert, pinned_cert_file_name);
+
+  if(ret) {
+    x509_crt_free(&pinned_cert);
+    *flags |= BADCERT_NOT_TRUSTED;
+    return *flags;
+  }
+
+  while (leaf->next) {
+    leaf = leaf->next;
+  }
+
+  ret = memcmp(pinned_cert.raw.p, leaf->raw.p, pinned_cert.raw.len);
+  x509_crt_free(&pinned_cert);
+  if (ret == 0) {
+    *flags = 0;
+    return 0;
+  }
+
+  *flags |= BADCERT_NOT_TRUSTED;
+  return *flags;
+}
+
 static CURLcode
 polarssl_connect_step2(struct connectdata *conn,
                      int sockindex)
@@ -422,6 +460,9 @@ polarssl_connect_step2(struct connectdata *conn,
   conn->recv[sockindex] = polarssl_recv;
   conn->send[sockindex] = polarssl_send;
 
+  if(data->set.str[STRING_SSL_PEERCERT])
+    ssl_set_verify (&connssl->ssl, pinned_verify, data->set.str[STRING_SSL_PEERCERT]);
+
   for(;;) {
     if(!(ret = ssl_handshake(&connssl->ssl)))
       break;
-- 
1.9.1

http://wald.intevation.org/projects/trustbridge/