[PATCH 2 of 2] (issue90) Add curl patches for the problems we had with curl
Wald Commits
scm-commit at wald.intevation.org
Mon Sep 1 19:48:59 CEST 2014
# HG changeset patch
# User Andre Heinecke <andre.heinecke at intevation.de>
# Date 1409593733 -7200
# Node ID 0570b1e562c21450dd39002690520b8f6aac5b9a
# Parent 405c97ca4ab072c95d0e0146afa55d1d66deb042
(issue90) Add curl patches for the problems we had with curl.
diff -r 405c97ca4ab0 -r 0570b1e562c2 INSTALL
--- a/INSTALL Mon Sep 01 16:18:10 2014 +0200
+++ b/INSTALL Mon Sep 01 19:48:53 2014 +0200
@@ -61,12 +61,21 @@
cmake .. -DCMAKE_C_FLAGS=-fpic -DCMAKE_INSTALL_PREFIX=$YOURPREFIX
make && make test && make install
+Trustbridge checkout:
+At this point you need a trustbridge checkout as curl needs to be patched
+to enable the certificate pinning and the force of SSL Ciphersuites when
+using polarssl.
+
+ hg clone https://wald.intevation.org/hg/trustbridge/
+
Libcurl:
+
wget http://curl.haxx.se/download/curl-7.37.1.tar.gz
a32492a38c10a097344892f5fd2041e54698cb909696852311b1161e4aa979f3 curl-7.37.1.tar.gz
tar -xf curl-7.37.1.tar.gz
cd curl-7.37.1/
+ patch -p1 < ../trustbridge/patches/*.patch
mkdir build
cd build
@@ -84,7 +93,6 @@
To compile the software you can use plain cmake. An out of source build is
highly suggested. For build options see CMakeList.txt
- hg clone https://wald.intevation.org/hg/trustbridge/
cd trustbridge
hg clone https://wald.intevation.org/hg/trustbridge/nss-cmake-static
mkdir build-linux
@@ -171,13 +179,15 @@
cp polarssl-1.3.7-gpl.tgz hiawatha-9.5/polarssl/polarssl.tgz
cd hiawatha-9.5/polarssl
sed -i 's/wget.*//' upgrade
- ./upgrade 1.3.7
+ ./upgrade 1.3.8
cd ..
mkdir build
cd build
cmake .. -DCMAKE_INSTALL_PREFIX=$YOURPREFIX
make && make install
+
+
Osslsigncode (for binverify unit test)
======================================
Osslsigncode is used to create PKCS#7 embedded signatures for Windows Authenticode
@@ -232,7 +242,7 @@
cmake .. \
-DCMAKE_PREFIX_PATH="$MXETARGET/qt5;$MXETARGET;" \
-DCMAKE_TOOLCHAIN_FILE="$MXETARGET/share/cmake/mxe-conf.cmake" \
- -DCMAKE_VERBOSE_MAKEFILE=True
+ -DCMAKE_VERBOSE_MAKEFILE=True -DUSE_CURL=OFF
Runtime Depdendencies
=====================
diff -r 405c97ca4ab0 -r 0570b1e562c2 patches/0001-Implement-CURLOPT_SSLVERSION-for-polarssl.patch
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/patches/0001-Implement-CURLOPT_SSLVERSION-for-polarssl.patch Mon Sep 01 19:48:53 2014 +0200
@@ -0,0 +1,47 @@
+From bebf7d617091042828fc5838170b35c42ab60396 Mon Sep 17 00:00:00 2001
+From: Andre Heinecke <aheinecke at intevation.de>
+Date: Mon, 1 Sep 2014 16:06:03 +0200
+Subject: [PATCH 1/3] Implement CURLOPT_SSLVERSION for polarssl
+
+ Forwards the setting as minimum ssl version to polarssl.
+ If the server does not support the requested version the
+ SSL Handshake will fail.
+---
+ lib/vtls/polarssl.c | 21 +++++++++++++++++++++
+ 1 file changed, 21 insertions(+)
+
+diff --git a/lib/vtls/polarssl.c b/lib/vtls/polarssl.c
+index f948486..e18cadf 100644
+--- a/lib/vtls/polarssl.c
++++ b/lib/vtls/polarssl.c
+@@ -270,6 +270,27 @@ polarssl_connect_step1(struct connectdata *conn,
+ return CURLE_SSL_CONNECT_ERROR;
+ }
+
++ if(data->set.ssl.version == CURL_SSLVERSION_SSLv3) {
++ ssl_set_min_version(&connssl->ssl, SSL_MAJOR_VERSION_3,
++ SSL_MINOR_VERSION_0);
++ infof(data, "PolarSSL: Forced min. SSL Version to be SSLv3\n");
++ }
++ else if(data->set.ssl.version == CURL_SSLVERSION_TLSv1_0) {
++ ssl_set_min_version(&connssl->ssl, SSL_MAJOR_VERSION_3,
++ SSL_MINOR_VERSION_1);
++ infof(data, "PolarSSL: Forced min. SSL Version to be TLS 1.0\n");
++ }
++ else if(data->set.ssl.version == CURL_SSLVERSION_TLSv1_1) {
++ ssl_set_min_version(&connssl->ssl, SSL_MAJOR_VERSION_3,
++ SSL_MINOR_VERSION_2);
++ infof(data, "PolarSSL: Forced min. SSL Version to be TLS 1.1\n");
++ }
++ else if(data->set.ssl.version == CURL_SSLVERSION_TLSv1_2) {
++ ssl_set_min_version(&connssl->ssl, SSL_MAJOR_VERSION_3,
++ SSL_MINOR_VERSION_3);
++ infof(data, "PolarSSL: Forced min. SSL Version to be TLS 1.2\n");
++ }
++
+ ssl_set_endpoint(&connssl->ssl, SSL_IS_CLIENT);
+ ssl_set_authmode(&connssl->ssl, SSL_VERIFY_OPTIONAL);
+
+--
+1.9.1
+
diff -r 405c97ca4ab0 -r 0570b1e562c2 patches/0002-Add-CURLOPT_PEERCERT-option-to-pin-a-peer-cert.patch
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/patches/0002-Add-CURLOPT_PEERCERT-option-to-pin-a-peer-cert.patch Mon Sep 01 19:48:53 2014 +0200
@@ -0,0 +1,138 @@
+From c57d951c3bda8b1ca66cac45dfd6270fa34b01d3 Mon Sep 17 00:00:00 2001
+From: Andre Heinecke <aheinecke at intevation.de>
+Date: Mon, 1 Sep 2014 16:55:40 +0200
+Subject: [PATCH 2/3] Add CURLOPT_PEERCERT option to pin a peer cert
+
+ 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 | 42 ++++++++++++++++++++++++++++++++++++++++--
+ 5 files changed, 53 insertions(+), 2 deletions(-)
+
+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 89c3fd5..b089cdf 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 e18cadf..2c40e36 100644
+--- a/lib/vtls/polarssl.c
++++ b/lib/vtls/polarssl.c
+@@ -360,6 +360,7 @@ polarssl_connect_step2(struct connectdata *conn,
+ #ifdef HAS_ALPN
+ const char* next_protocol;
+ #endif
++ const x509_crt *peer_cert = NULL;
+
+ char errorbuf[128];
+ memset(errorbuf, 0, sizeof(errorbuf));
+@@ -419,12 +420,49 @@ polarssl_connect_step2(struct connectdata *conn,
+ return CURLE_PEER_FAILED_VERIFICATION;
+ }
+
+- if(ssl_get_peer_cert(&(connssl->ssl))) {
++ peer_cert = ssl_get_peer_cert(&(connssl->ssl));
++ if(peer_cert) {
++ if(data->set.str[STRING_SSL_PEERCERT]) {
++ x509_crt pinned_cert;
++ unsigned int i;
++
++ /* Handle pinned certificate */
++ x509_crt_init(&pinned_cert);
++ ret = x509_crt_parse_file(&pinned_cert,
++ data->set.str[STRING_SSL_PEERCERT]);
++
++ if(ret) {
++#ifdef POLARSSL_ERROR_C
++ error_strerror(ret, errorbuf, sizeof(errorbuf));
++#endif /* POLARSSL_ERROR_C */
++ failf(data, "Error reading peer cert file %s - PolarSSL: (-0x%04X) %s",
++ data->set.str[STRING_SSL_PEERCERT], -ret, errorbuf);
++
++ x509_crt_free(&pinned_cert);
++ return CURLE_PEER_FAILED_VERIFICATION;
++ }
++
++ if (peer_cert->raw.len == 0 ||
++ peer_cert->raw.len != pinned_cert.raw.len) {
++ failf(data, "Error validating peer certificate. Size does "
++ "not match the certificate set with PEERCERT option.\n");
++ x509_crt_free(&pinned_cert);
++ return CURLE_PEER_FAILED_VERIFICATION;
++ }
++ for (i = 0; i < peer_cert->raw.len; i++) {
++ if (peer_cert->raw.p[i] != pinned_cert.raw.p[i]) {
++ failf(data, "Error validating peer certificate. Does "
++ "not match the certificate set with PEERCERT option.\n");
++ return CURLE_PEER_FAILED_VERIFICATION;
++ }
++ }
++ }
++
+ /* If the session was resumed, there will be no peer certs */
+ memset(buffer, 0, sizeof(buffer));
+
+ if(x509_crt_info(buffer, sizeof(buffer), (char *)"* ",
+- ssl_get_peer_cert(&(connssl->ssl))) != -1)
++ peer_cert) != -1)
+ infof(data, "Dumping cert info:\n%s\n", buffer);
+ }
+
+--
+1.9.1
+
diff -r 405c97ca4ab0 -r 0570b1e562c2 patches/0003-Add-possibility-to-fore-polarssl-ciphersuites.patch
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/patches/0003-Add-possibility-to-fore-polarssl-ciphersuites.patch Mon Sep 01 19:48:53 2014 +0200
@@ -0,0 +1,77 @@
+From 3dc7ab77759878778ae440a31304c736c1ef8cba Mon Sep 17 00:00:00 2001
+From: Andre Heinecke <aheinecke at intevation.de>
+Date: Mon, 1 Sep 2014 19:43:55 +0200
+Subject: [PATCH 3/3] Add possibility to fore polarssl ciphersuites.
+
+---
+ lib/vtls/polarssl.c | 40 ++++++++++++++++++++++++++++++++++++++--
+ 1 file changed, 38 insertions(+), 2 deletions(-)
+
+diff --git a/lib/vtls/polarssl.c b/lib/vtls/polarssl.c
+index 2c40e36..7e806bf 100644
+--- a/lib/vtls/polarssl.c
++++ b/lib/vtls/polarssl.c
+@@ -67,6 +67,8 @@
+ #define THREADING_SUPPORT
+ #endif
+
++#define MAX_CIPHERSUITES 255
++
+ #if defined(THREADING_SUPPORT)
+ static entropy_context entropy;
+
+@@ -129,7 +131,7 @@ static void polarssl_debug(void *context, int level, const char *line)
+
+ static Curl_recv polarssl_recv;
+ static Curl_send polarssl_send;
+-
++static int ciphersuites[MAX_CIPHERSUITES + 1];
+
+ static CURLcode
+ polarssl_connect_step1(struct connectdata *conn,
+@@ -300,7 +302,41 @@ polarssl_connect_step1(struct connectdata *conn,
+ net_recv, &conn->sock[sockindex],
+ net_send, &conn->sock[sockindex]);
+
+- ssl_set_ciphersuites(&connssl->ssl, ssl_list_ciphersuites());
++ if(!data->set.str[STRING_SSL_CIPHER_LIST])
++ ssl_set_ciphersuites(&connssl->ssl, ssl_list_ciphersuites());
++ else {
++ /* Convert string input to polarssl cipher id's */
++ char *tmp,
++ *token,
++ *tok_buf;
++
++ memset(ciphersuites, 0, MAX_CIPHERSUITES + 1);
++
++ tmp = strdup (data->set.str[STRING_SSL_CIPHER_LIST]);
++ if(!tmp)
++ return CURLE_OUT_OF_MEMORY;
++
++ i = 0;
++ for (token = strtok_r(tmp, ":", &tok_buf);
++ token != NULL;
++ token = strtok_r(NULL, ":", &tok_buf)) {
++
++ ciphersuites[i] = ssl_get_ciphersuite_id(token);
++ if (!ciphersuites[i]) {
++ infof(data, "WARNING: failed to set cipher: %s\n", token);
++ /* Do not increase i as the first 0 is the end
++ of the list so we overwrite it with the next
++ valid cipher. Maybe we should fail? */
++ continue;
++ }
++ i++;
++ }
++ free(tmp);
++ /* Beware, polarssl does not make a copy of the ciphersuites
++ so the data needs to be valid during the call. */
++ ssl_set_ciphersuites(&connssl->ssl, ciphersuites);
++ }
++
+ if(!Curl_ssl_getsessionid(conn, &old_session, &old_session_size)) {
+ memcpy(&connssl->ssn, old_session, old_session_size);
+ infof(data, "PolarSSL re-using session\n");
+--
+1.9.1
+
More information about the Trustbridge-commits
mailing list