Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Loading…

Adding RFC2818 compliance to axTLS, CyaSSL and other SSL-backend related fixes. #47

Closed
wants to merge 26 commits into from

2 participants

@okoeroo

axTLS:
This will make the axTLS backend perform the RFC2818 checks, honoring the VERIFYHOST setting similar to the OpenSSL backend.

Generic for OpenSSL and axTLS:
Also move the hostcheck and cert_hostcheck functions from the lib/ssluse.c files to make them genericly available for both the OpenSSL, axTLS and other SSL backends in the near future. Currently these are now in the lib/rawstr.c but will be moved later in a separate file.

CyaSSL:
CyaSSL has the RFC2818 checks also enabled now by default. There is a limitation that the verifyhost can not be enabled exclusively on the Subject CN field comparison. This SSL backend will thus behave like the NSS and the GnuTLS (meaning: RFC2818 ok, or bust). In other words: setting verifyhost to 0 or 1 will disable the Subject Alt Names checks too.

Schannel:
Updated the schannel information messages: Split the IP address usage message from the verifyhost setting and changed the message about disabling SNI (Server Name Indication, used in HTTP virtual hosting) into a message stating that the Subject Alternative Names checks are being disabled when verifyhost is set to 0 or 1. As a side effect of switching off the RFC2818 related servername checks with SCH_CRED_NO_SERVERNAME_CHECK (http://msdn.microsoft.com/en-us/library/aa923430.aspx) the SNI feature is being disabled. This effect is not documented in MSDN, but Wireshark output clearly shows the effect (details on the libcurl maillist).

PolarSSL:
Fix the prototype change in PolarSSL of ssl_set_session() and the move of the peer_cert from the ssl_context to the ssl_session. Found this change in the PolarSSL SVN between r1316 and r1317 where the POLARSSL_VERSION_NUMBER was at 0x01010100. But to accommodate the Ubuntu PolarSSL version 1.1.4 the check is to discriminate between lower then PolarSSL version 1.2.0 and 1.2.0 and higher. Note: The PolarSSL SVN trunk jumped from version 1.1.1 to 1.2.0.

curl tool:
Sets a CURLOPT_SSL_VERIFYHOST value of 0L.

Generic:
All the SSL backends are fixed and checked to work with the ssl.verifyhost as a boolean, which is an internal API change.

okoeroo added some commits
@okoeroo okoeroo Adding RFC2818 compliance checks to axTLS. Completely new are the Sub…
…jectAltName checks. The peer CN field fallback is implemented matching the OpenSSL behaviour. VERIFYHOST 0 == 1.
1bc4e22
@okoeroo okoeroo Moved the hostcheck and cert_hostcheck static functions from lib/sslu…
…se.c to rawstr.c to make them usable by the axTLS and other SSL backends. Also prefixed the functions with Curl_
0ddef25
@okoeroo okoeroo Adding RFC2818 checks for CyaSSL. This implementation will work simil…
…ar to GnuTLS and NSS, meaning that you can't distinghuish between a SubjectAltName failure and CN failure
f1e5d4c
@okoeroo okoeroo Split the IP address usage message from the verifyhost setting and ch…
…anging the wrong message about disabling SNI (Server Name Indication, used in HTTP virtual hosting) where SAN (Subject Alternative Name) is meant according to http://msdn.microsoft.com/en-us/library/aa923430.aspx about the flag SCH_CRED_NO_SERVERNAME_CHECK
971b13c
@okoeroo okoeroo Moved the hostmatch and cert_hostcheck function out of the rawstr.c a…
…nd into new files hostcheck.c and hostcheck.h. The OpenSSL and axTLS SSL backend code is now adjusted to use the hostcheck.h header for the prototypes. The Makefile.inc is updated with these two new files and everything builds and tests nicely.
ebbf7d8
@okoeroo okoeroo Improved the Schannel informational texts to indicate that SNI usages…
… is disabled together with disabling the servername check against the subject name(s) with the flag SCH_CRED_NO_SERVERNAME_CHECK.
fbff64b
@okoeroo okoeroo Fix the prototype change of ssl_set_session and the move of the peer_…
…cert from the ssl_context to the ssl_session. Found in the PolarSSL SVN between r1316 and r1317 where the POLARSSL_VERSION_NUMBER was at 0x01010100.
1e3aea9
@okoeroo okoeroo It seems Ubuntu 12.10 has a slight offset to what I found in SVN. Thi…
…s needs further attention, this works now with Ubuntu's libpolarssl
4d04589
@okoeroo okoeroo Ubuntu's PolarSSL version 1.1.4 doesn't exist in the PolarSSL SVN tru…
…nk. Assuming 1.2.x as a different release compared to 1.1.x, changing the #if POLARSSL_VERSION_NUMBER<=0x01010400 to POLARSSL_VERSION_NUMBER<0x01020000.
5e85cea
@okoeroo okoeroo Remote unused code and added an explicit errSSLHostNameMismatch error…
… switch-case that changes curl's generic failure on an SSL issue (CURLE_SSL_CONNECT_ERROR) to the explicit error code CURLE_PEER_FAILED_VERIFICATION which is used in all the other SSL backends for the same situation.
c70617a
@okoeroo okoeroo For the PolarSSL version 1.2.0 and up now getting the peer certificat…
…e via the function ssl_get_peer_cert() with thanks the PolarSSL twitter account for feedback.
81e0496
@okoeroo okoeroo Patched the Darwin, Schannel and OpenSSL interfaces. Also adjusted in…
… the curl tool sets a CURLOPT_SSL_VERIFYHOST of value 0.
9d3e503
@okoeroo okoeroo Merge branch 'master' of github.com:okoeroo/curl 9eb04b7
@okoeroo okoeroo Adding RFC2818 compliance checks to axTLS. Completely new are the Sub…
…jectAltName checks. The peer CN field fallback is implemented matching the OpenSSL behaviour. VERIFYHOST 0 == 1.
a46e66e
@okoeroo okoeroo Resolving conflict after rebase ab20e7c
@okoeroo okoeroo Moved the hostcheck and cert_hostcheck static functions from lib/sslu…
…se.c to rawstr.c to make them usable by the axTLS and other SSL backends. Also prefixed the functions with Curl_
d4386ef
@okoeroo okoeroo Adding RFC2818 checks for CyaSSL. This implementation will work simil…
…ar to GnuTLS and NSS, meaning that you can't distinghuish between a SubjectAltName failure and CN failure
2ca36e7
@okoeroo okoeroo Merged after rebase d09c88e
@okoeroo okoeroo Moved the hostmatch and cert_hostcheck function out of the rawstr.c a…
…nd into new files hostcheck.c and hostcheck.h. The OpenSSL and axTLS SSL backend code is now adjusted to use the hostcheck.h header for the prototypes. The Makefile.inc is updated with these two new files and everything builds and tests nicely.
f2eaa70
@okoeroo okoeroo Fix the prototype change of ssl_set_session and the move of the peer_…
…cert from the ssl_context to the ssl_session. Found in the PolarSSL SVN between r1316 and r1317 where the POLARSSL_VERSION_NUMBER was at 0x01010100.
7748dc7
@okoeroo okoeroo It seems Ubuntu 12.10 has a slight offset to what I found in SVN. Thi…
…s needs further attention, this works now with Ubuntu's libpolarssl
4bfd2fa
@okoeroo okoeroo Ubuntu's PolarSSL version 1.1.4 doesn't exist in the PolarSSL SVN tru…
…nk. Assuming 1.2.x as a different release compared to 1.1.x, changing the #if POLARSSL_VERSION_NUMBER<=0x01010400 to POLARSSL_VERSION_NUMBER<0x01020000.
5dae9ab
@okoeroo okoeroo Merge after rebase 573b4a1
@okoeroo okoeroo Merge branch 'master' of github.com:okoeroo/curl 24e8f9a
@okoeroo okoeroo Manually reapplying a recent diff between the main repo and my repo d565b38
@okoeroo okoeroo Compensating in the axTLS and CyaSSL code for the internal change of …
…the set.ssl.verifyhost from an int to a boolean.
029f8f1
@okoeroo

Granted, there are a lot of individual commits, but the file changes are even readable now diffed from your latest state.

@bagder
Owner

You're still providing a long history and not just the necessary (squashed) patches:

$ curl https://github.com/bagder/curl/pull/47.patch | git am
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 87670 100 87670 0 0 90410 0 --:--:-- --:--:-- --:--:-- 100k
Applying: Adding RFC2818 compliance checks to axTLS. Completely new are the SubjectAltName checks. The peer CN field fallback is implemented matching the OpenSSL behaviour. VERIFYHOST 0 == 1.
Applying: Moved the hostcheck and cert_hostcheck static functions from lib/ssluse.c to rawstr.c to make them usable by the axTLS and other SSL backends. Also prefixed the functions with Curl_
/home/daniel/src/curl/.git/rebase-apply/patch:170: new blank line at EOF.
+
error: patch failed: lib/ssluse.c:1291
error: lib/ssluse.c: patch does not apply
Patch failed at 0002 Moved the hostcheck and cert_hostcheck static functions from lib/ssluse.c to rawstr.c to make them usable by the axTLS and other SSL backends. Also prefixed the functions with Curl_
When you have resolved this problem run "git am --resolved".
If you would prefer to skip this patch, instead run "git am --skip".
To restore the original branch and stop patching run "git am --abort".

@okoeroo

I see what you mean while rebasing. It's a huge load of work, while I know the outcome already. So I'm going to take a shortcut here to ease it, which is to reclone cleanly and apply a classic patch.

@okoeroo okoeroo closed this
@aguasonic aguasonic referenced this pull request
Closed

building 7.42 #233

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on Nov 3, 2012
  1. @okoeroo

    Adding RFC2818 compliance checks to axTLS. Completely new are the Sub…

    okoeroo authored
    …jectAltName checks. The peer CN field fallback is implemented matching the OpenSSL behaviour. VERIFYHOST 0 == 1.
  2. @okoeroo

    Moved the hostcheck and cert_hostcheck static functions from lib/sslu…

    okoeroo authored
    …se.c to rawstr.c to make them usable by the axTLS and other SSL backends. Also prefixed the functions with Curl_
  3. @okoeroo

    Adding RFC2818 checks for CyaSSL. This implementation will work simil…

    okoeroo authored
    …ar to GnuTLS and NSS, meaning that you can't distinghuish between a SubjectAltName failure and CN failure
  4. @okoeroo

    Split the IP address usage message from the verifyhost setting and ch…

    okoeroo authored
    …anging the wrong message about disabling SNI (Server Name Indication, used in HTTP virtual hosting) where SAN (Subject Alternative Name) is meant according to http://msdn.microsoft.com/en-us/library/aa923430.aspx about the flag SCH_CRED_NO_SERVERNAME_CHECK
  5. @okoeroo

    Moved the hostmatch and cert_hostcheck function out of the rawstr.c a…

    okoeroo authored
    …nd into new files hostcheck.c and hostcheck.h. The OpenSSL and axTLS SSL backend code is now adjusted to use the hostcheck.h header for the prototypes. The Makefile.inc is updated with these two new files and everything builds and tests nicely.
  6. @okoeroo

    Improved the Schannel informational texts to indicate that SNI usages…

    okoeroo authored
    … is disabled together with disabling the servername check against the subject name(s) with the flag SCH_CRED_NO_SERVERNAME_CHECK.
  7. @okoeroo

    Fix the prototype change of ssl_set_session and the move of the peer_…

    okoeroo authored
    …cert from the ssl_context to the ssl_session. Found in the PolarSSL SVN between r1316 and r1317 where the POLARSSL_VERSION_NUMBER was at 0x01010100.
  8. @okoeroo

    It seems Ubuntu 12.10 has a slight offset to what I found in SVN. Thi…

    okoeroo authored
    …s needs further attention, this works now with Ubuntu's libpolarssl
  9. @okoeroo

    Ubuntu's PolarSSL version 1.1.4 doesn't exist in the PolarSSL SVN tru…

    okoeroo authored
    …nk. Assuming 1.2.x as a different release compared to 1.1.x, changing the #if POLARSSL_VERSION_NUMBER<=0x01010400 to POLARSSL_VERSION_NUMBER<0x01020000.
Commits on Nov 4, 2012
  1. @okoeroo

    Remote unused code and added an explicit errSSLHostNameMismatch error…

    okoeroo authored
    … switch-case that changes curl's generic failure on an SSL issue (CURLE_SSL_CONNECT_ERROR) to the explicit error code CURLE_PEER_FAILED_VERIFICATION which is used in all the other SSL backends for the same situation.
Commits on Nov 5, 2012
  1. @okoeroo

    For the PolarSSL version 1.2.0 and up now getting the peer certificat…

    okoeroo authored
    …e via the function ssl_get_peer_cert() with thanks the PolarSSL twitter account for feedback.
Commits on Nov 6, 2012
  1. @okoeroo

    Patched the Darwin, Schannel and OpenSSL interfaces. Also adjusted in…

    okoeroo authored
    … the curl tool sets a CURLOPT_SSL_VERIFYHOST of value 0.
  2. @okoeroo
Commits on Nov 7, 2012
  1. @okoeroo

    Adding RFC2818 compliance checks to axTLS. Completely new are the Sub…

    okoeroo authored
    …jectAltName checks. The peer CN field fallback is implemented matching the OpenSSL behaviour. VERIFYHOST 0 == 1.
  2. @okoeroo
  3. @okoeroo

    Moved the hostcheck and cert_hostcheck static functions from lib/sslu…

    okoeroo authored
    …se.c to rawstr.c to make them usable by the axTLS and other SSL backends. Also prefixed the functions with Curl_
  4. @okoeroo

    Adding RFC2818 checks for CyaSSL. This implementation will work simil…

    okoeroo authored
    …ar to GnuTLS and NSS, meaning that you can't distinghuish between a SubjectAltName failure and CN failure
  5. @okoeroo

    Merged after rebase

    okoeroo authored
  6. @okoeroo

    Moved the hostmatch and cert_hostcheck function out of the rawstr.c a…

    okoeroo authored
    …nd into new files hostcheck.c and hostcheck.h. The OpenSSL and axTLS SSL backend code is now adjusted to use the hostcheck.h header for the prototypes. The Makefile.inc is updated with these two new files and everything builds and tests nicely.
  7. @okoeroo

    Fix the prototype change of ssl_set_session and the move of the peer_…

    okoeroo authored
    …cert from the ssl_context to the ssl_session. Found in the PolarSSL SVN between r1316 and r1317 where the POLARSSL_VERSION_NUMBER was at 0x01010100.
  8. @okoeroo

    It seems Ubuntu 12.10 has a slight offset to what I found in SVN. Thi…

    okoeroo authored
    …s needs further attention, this works now with Ubuntu's libpolarssl
  9. @okoeroo

    Ubuntu's PolarSSL version 1.1.4 doesn't exist in the PolarSSL SVN tru…

    okoeroo authored
    …nk. Assuming 1.2.x as a different release compared to 1.1.x, changing the #if POLARSSL_VERSION_NUMBER<=0x01010400 to POLARSSL_VERSION_NUMBER<0x01020000.
  10. @okoeroo

    Merge after rebase

    okoeroo authored
  11. @okoeroo
  12. @okoeroo
  13. @okoeroo

    Compensating in the axTLS and CyaSSL code for the internal change of …

    okoeroo authored
    …the set.ssl.verifyhost from an int to a boolean.
This page is out of date. Refresh to see the latest.
View
5 lib/Makefile.inc
@@ -24,7 +24,7 @@ CSOURCES = file.c timeval.c base64.c hostip.c progress.c formdata.c \
idn_win32.c http_negotiate_sspi.c cyassl.c http_proxy.c non-ascii.c \
asyn-ares.c asyn-thread.c curl_gssapi.c curl_ntlm.c curl_ntlm_wb.c \
curl_ntlm_core.c curl_ntlm_msgs.c curl_sasl.c curl_schannel.c \
- curl_multibyte.c curl_darwinssl.c
+ curl_multibyte.c curl_darwinssl.c hostcheck.c
HHEADERS = arpa_telnet.h netrc.h file.h timeval.h qssl.h hostip.h \
progress.h formdata.h cookie.h http.h sendf.h ftp.h url.h dict.h \
@@ -41,4 +41,5 @@ HHEADERS = arpa_telnet.h netrc.h file.h timeval.h qssl.h hostip.h \
warnless.h curl_hmac.h polarssl.h curl_rtmp.h curl_gethostname.h \
gopher.h axtls.h cyassl.h http_proxy.h non-ascii.h asyn.h curl_ntlm.h \
curl_gssapi.h curl_ntlm_wb.h curl_ntlm_core.h curl_ntlm_msgs.h \
- curl_sasl.h curl_schannel.h curl_multibyte.h curl_darwinssl.h
+ curl_sasl.h curl_schannel.h curl_multibyte.h curl_darwinssl.h \
+ hostcheck.h
View
61 lib/axtls.c
@@ -47,6 +47,8 @@
#include "curl_memory.h"
/* The last #include file should be: */
#include "memdebug.h"
+#include "hostcheck.h"
+
/* SSL_read is opied from axTLS compat layer */
static int SSL_read(SSL *ssl, void *buf, int num)
@@ -150,7 +152,11 @@ Curl_axtls_connect(struct connectdata *conn,
int i, ssl_fcn_return;
const uint8_t *ssl_sessionid;
size_t ssl_idsize;
- const char *x509;
+ const char *peer_CN;
+ uint32_t dns_altname_index;
+ const char *dns_altname;
+ int8_t found_subject_alt_names = 0;
+ int8_t found_subject_alt_name_matching_conn = 0;
/* Assuming users will not compile in custom key/cert to axTLS */
uint32_t client_option = SSL_NO_DEFAULT_KEY|SSL_SERVER_VERIFY_LATER;
@@ -296,19 +302,60 @@ Curl_axtls_connect(struct connectdata *conn,
/* Here, gtls.c does issuer verification. axTLS has no straightforward
* equivalent, so omitting for now.*/
- /* See if common name was set in server certificate */
- x509 = ssl_get_cert_dn(ssl, SSL_X509_CERT_COMMON_NAME);
- if(x509 == NULL)
- infof(data, "error fetching CN from cert\n");
-
/* Here, gtls.c does the following
* 1) x509 hostname checking per RFC2818. axTLS doesn't support this, but
- * it seems useful. Omitting for now.
+ * it seems useful. This is now implemented, by Oscar Koeroo
* 2) checks cert validity based on time. axTLS does this in ssl_verify_cert
* 3) displays a bunch of cert information. axTLS doesn't support most of
* this, but a couple fields are available.
*/
+
+ /* There is no (DNS) Altnames count in the version 1.4.8 API. There is a risk of an inifite loop */
+ for (dns_altname_index = 0; ; dns_altname_index++) {
+ dns_altname = ssl_get_cert_subject_alt_dnsname(ssl, dns_altname_index);
+ if (dns_altname == NULL) {
+ break;
+ }
+ found_subject_alt_names = 1;
+
+ infof(data, "\tComparing subject alt name DNS with hostname: %s <-> %s\n", dns_altname, conn->host.name);
+ if (Curl_cert_hostcheck(dns_altname, conn->host.name)) {
+ found_subject_alt_name_matching_conn = 1;
+ break;
+ }
+ }
+
+ /* RFC2818 checks */
+ if (found_subject_alt_names && !found_subject_alt_name_matching_conn) {
+ /* Break connection ! */
+ Curl_axtls_close(conn, sockindex);
+ failf(data, "\tsubjectAltName(s) do not match %s\n", conn->host.dispname);
+ return CURLE_PEER_FAILED_VERIFICATION;
+ }
+ else if (found_subject_alt_names == 0) {
+ /* Per RFC2818, when no Subject Alt Names were available, examine the peer CN as a legacy fallback */
+ peer_CN = ssl_get_cert_dn(ssl, SSL_X509_CERT_COMMON_NAME);
+ if(peer_CN == NULL) {
+ /* Similar behaviour to the OpenSSL interface */
+ Curl_axtls_close(conn, sockindex);
+ failf(data, "unable to obtain common name from peer certificate");
+ return CURLE_PEER_FAILED_VERIFICATION;
+ }
+ else {
+ if(!Curl_cert_hostcheck((const char *)peer_CN, conn->host.name)) {
+ if(data->set.ssl.verifyhost) {
+ /* Break connection ! */
+ Curl_axtls_close(conn, sockindex);
+ failf(data, "\tcommon name \"%s\" does not match \"%s\"\n", peer_CN, conn->host.dispname);
+ return CURLE_PEER_FAILED_VERIFICATION;
+ }
+ else
+ infof(data, "\tcommon name \"%s\" does not match \"%s\"\n", peer_CN, conn->host.dispname);
+ }
+ }
+ }
+
/* General housekeeping */
conn->ssl[sockindex].state = ssl_connection_complete;
conn->ssl[sockindex].ssl = ssl;
View
17 lib/curl_darwinssl.c
@@ -803,12 +803,13 @@ static CURLcode darwinssl_connect_step1(struct connectdata *conn,
}
#endif /* defined(__MAC_10_6) || defined(__IPHONE_5_0) */
- /* If this is a domain name and not an IP address, then configure SNI: */
- if((0 == Curl_inet_pton(AF_INET, conn->host.name, &addr)) &&
+ /* If this is a domain name and not an IP address, then configure SNI.
+ * Also: the verifyhost setting influences SNI usage */
+ if((0 == Curl_inet_pton(AF_INET, conn->host.name, &addr))
#ifdef ENABLE_IPV6
- (0 == Curl_inet_pton(AF_INET6, conn->host.name, &addr)) &&
+ && (0 == Curl_inet_pton(AF_INET6, conn->host.name, &addr))
#endif
- data->set.ssl.verifyhost) {
+ && data->set.ssl.verifyhost) {
err = SSLSetPeerDomainName(connssl->ssl_ctx, conn->host.name,
strlen(conn->host.name));
if(err != noErr) {
@@ -862,7 +863,6 @@ darwinssl_connect_step2(struct connectdata *conn, int sockindex)
connssl->connecting_state = connssl->ssl_direction ?
ssl_connect_2_writing : ssl_connect_2_reading;
return CURLE_OK;
- break;
case errSSLServerAuthCompleted:
/* the documentation says we need to call SSLHandshake() again */
@@ -874,13 +874,16 @@ darwinssl_connect_step2(struct connectdata *conn, int sockindex)
case errSSLCertExpired:
failf(data, "SSL certificate problem: OSStatus %d", err);
return CURLE_SSL_CACERT;
- break;
+
+ case errSSLHostNameMismatch:
+ failf(data, "SSL certificate peer verification failed, the certificate did "
+ "not match \"%s\"\n", conn->host.dispname);
+ return CURLE_PEER_FAILED_VERIFICATION;
default:
failf(data, "Unknown SSL protocol error in connection to %s:%d",
conn->host.name, err);
return CURLE_SSL_CONNECT_ERROR;
- break;
}
}
else {
View
18 lib/curl_schannel.c
@@ -156,14 +156,22 @@ schannel_connect_step1(struct connectdata *conn, int sockindex)
infof(data, "schannel: disable server certificate revocation checks\n");
}
- if(Curl_inet_pton(AF_INET, conn->host.name, &addr) ||
+ if(Curl_inet_pton(AF_INET, conn->host.name, &addr)
#ifdef ENABLE_IPV6
- Curl_inet_pton(AF_INET6, conn->host.name, &addr6) ||
+ || Curl_inet_pton(AF_INET6, conn->host.name, &addr6)
#endif
- !data->set.ssl.verifyhost) {
+ ) {
schannel_cred.dwFlags |= SCH_CRED_NO_SERVERNAME_CHECK;
- infof(data, "schannel: using IP address, disable SNI servername "
- "check\n");
+ infof(data, "schannel: using IP address, SNI is being disabled by "
+ "disabling the servername check against the "
+ "subject names in server certificates.\n");
+ }
+
+ if(!data->set.ssl.verifyhost) {
+ schannel_cred.dwFlags |= SCH_CRED_NO_SERVERNAME_CHECK;
+ infof(data, "schannel: verifyhost setting prevents Schannel from "
+ "comparing the supplied target name with the subject "
+ "names in server certificates. Also disables SNI.\n");
}
switch(data->set.ssl.version) {
View
43 lib/cyassl.c
@@ -53,6 +53,8 @@
#include "curl_memory.h"
/* The last #include file should be: */
#include "memdebug.h"
+#include <cyassl/ssl.h>
+#include <cyassl/error.h>
static Curl_recv cyassl_recv;
@@ -237,6 +239,14 @@ cyassl_connect_step2(struct connectdata *conn,
conn->recv[sockindex] = cyassl_recv;
conn->send[sockindex] = cyassl_send;
+ /* Enable RFC2818 checks */
+ if(data->set.ssl.verifyhost) {
+ ret = CyaSSL_check_domain_name(conssl->handle, conn->host.name);
+ if (ret == SSL_FAILURE) {
+ return CURLE_OUT_OF_MEMORY;
+ }
+ }
+
ret = SSL_connect(conssl->handle);
if(ret != 1) {
char error_buffer[80];
@@ -246,15 +256,38 @@ cyassl_connect_step2(struct connectdata *conn,
conssl->connecting_state = ssl_connect_2_reading;
return CURLE_OK;
}
-
- if(SSL_ERROR_WANT_WRITE == detail) {
+ else if(SSL_ERROR_WANT_WRITE == detail) {
conssl->connecting_state = ssl_connect_2_writing;
return CURLE_OK;
}
-
- failf(data, "SSL_connect failed with error %d: %s", detail,
+ /* There is no easy way to override only the CN matching.
+ * This will enable the override of both mismatching SubjectAltNames
+ * as also mismatching CN fields */
+ else if(DOMAIN_NAME_MISMATCH == detail) {
+#if 1
+ failf(data, "\tsubject alt name(s) and/or common name do not match \"%s\"\n", conn->host.dispname);
+ return CURLE_PEER_FAILED_VERIFICATION;
+#else
+ /* When the CyaSSL_check_domain_name() is used and you desire to continue
+ * on a DOMAIN_NAME_MISMATCH, i.e. 'data->set.ssl.verifyhost == 0',
+ * CyaSSL version 2.4.0 will fail with an INCOMPLETE_DATA error. The only
+ * way to do this is currently to switch the CyaSSL_check_domain_name()
+ * in and out based on the 'data->set.ssl.verifyhost' value. */
+ if(data->set.ssl.verifyhost) {
+ failf(data, "\tsubject alt name(s) and/or common name do not match \"%s\"\n", conn->host.dispname);
+ return CURLE_PEER_FAILED_VERIFICATION;
+ }
+ else {
+ infof(data, "\tsubject alt name(s) and/or common name do not match \"%s\"\n", conn->host.dispname);
+ return CURLE_OK;
+ }
+#endif
+ }
+ else {
+ failf(data, "SSL_connect failed with error %d: %s", detail,
ERR_error_string(detail, error_buffer));
- return CURLE_SSL_CONNECT_ERROR;
+ return CURLE_SSL_CONNECT_ERROR;
+ }
}
conssl->connecting_state = ssl_connect_3;
View
92 lib/hostcheck.c
@@ -0,0 +1,92 @@
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2012, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "setup.h"
+
+#include "hostcheck.h"
+#include "rawstr.h"
+
+
+/*
+ * Match a hostname against a wildcard pattern.
+ * E.g.
+ * "foo.host.com" matches "*.host.com".
+ *
+ * We use the matching rule described in RFC6125, section 6.4.3.
+ * http://tools.ietf.org/html/rfc6125#section-6.4.3
+ */
+
+int Curl_hostmatch(const char *hostname, const char *pattern)
+{
+ const char *pattern_label_end, *pattern_wildcard, *hostname_label_end;
+ int wildcard_enabled;
+ size_t prefixlen, suffixlen;
+ pattern_wildcard = strchr(pattern, '*');
+ if(pattern_wildcard == NULL) {
+ return Curl_raw_equal(pattern, hostname) ? CURL_HOST_MATCH : CURL_HOST_NOMATCH;
+ }
+ /* We require at least 2 dots in pattern to avoid too wide wildcard
+ match. */
+ wildcard_enabled = 1;
+ pattern_label_end = strchr(pattern, '.');
+ if(pattern_label_end == NULL || strchr(pattern_label_end+1, '.') == NULL ||
+ pattern_wildcard > pattern_label_end ||
+ Curl_raw_nequal(pattern, "xn--", 4)) {
+ wildcard_enabled = 0;
+ }
+ if(!wildcard_enabled) {
+ return Curl_raw_equal(pattern, hostname) ? CURL_HOST_MATCH : CURL_HOST_NOMATCH;
+ }
+ hostname_label_end = strchr(hostname, '.');
+ if(hostname_label_end == NULL ||
+ !Curl_raw_equal(pattern_label_end, hostname_label_end)) {
+ return CURL_HOST_NOMATCH;
+ }
+ /* The wildcard must match at least one character, so the left-most
+ label of the hostname is at least as large as the left-most label
+ of the pattern. */
+ if(hostname_label_end - hostname < pattern_label_end - pattern) {
+ return CURL_HOST_NOMATCH;
+ }
+ prefixlen = pattern_wildcard - pattern;
+ suffixlen = pattern_label_end - (pattern_wildcard+1);
+ return Curl_raw_nequal(pattern, hostname, prefixlen) &&
+ Curl_raw_nequal(pattern_wildcard+1, hostname_label_end - suffixlen,
+ suffixlen) ?
+ CURL_HOST_MATCH : CURL_HOST_NOMATCH;
+}
+
+int Curl_cert_hostcheck(const char *match_pattern, const char *hostname)
+{
+ if(!match_pattern || !*match_pattern ||
+ !hostname || !*hostname) /* sanity check */
+ return 0;
+
+ if(Curl_raw_equal(hostname, match_pattern)) /* trivial case */
+ return 1;
+
+ if(Curl_hostmatch(hostname,match_pattern) == CURL_HOST_MATCH)
+ return 1;
+ return 0;
+}
+
+
View
33 lib/hostcheck.h
@@ -0,0 +1,33 @@
+#ifndef __HOSTCHECK_H
+#define __HOSTCHECK_H
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2012, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include <curl/curl.h>
+
+#define CURL_HOST_NOMATCH 0
+#define CURL_HOST_MATCH 1
+int Curl_hostmatch(const char *hostname, const char *pattern);
+int Curl_cert_hostcheck(const char *match_pattern, const char *hostname);
+
+#endif
+
View
17 lib/polarssl.c
@@ -212,8 +212,14 @@ polarssl_connect_step1(struct connectdata *conn,
infof(data, "PolarSSL re-using session\n");
}
+/* PolarSSL SVN revision r1316 to r1317, matching <1.2.0 is to cover Ubuntu's 1.1.4 version and the like */
+#if POLARSSL_VERSION_NUMBER<0x01020000
ssl_set_session(&connssl->ssl, 1, 600,
&connssl->ssn);
+#else
+ ssl_set_session(&connssl->ssl,
+ &connssl->ssn);
+#endif
ssl_set_ca_chain(&connssl->ssl,
&connssl->cacert,
@@ -306,12 +312,23 @@ polarssl_connect_step2(struct connectdata *conn,
return CURLE_PEER_FAILED_VERIFICATION;
}
+/* PolarSSL SVN revision r1316 to r1317, matching <1.2.0 is to cover Ubuntu's 1.1.4 version and the like */
+#if POLARSSL_VERSION_NUMBER<0x01020000
if(conn->ssl[sockindex].ssl.peer_cert) {
+#else
+ if(ssl_get_peer_cert(&(connssl->ssl))) {
+#endif
/* If the session was resumed, there will be no peer certs */
memset(buffer, 0, sizeof(buffer));
+/* PolarSSL SVN revision r1316 to r1317, matching <1.2.0 is to cover Ubuntu's 1.1.4 version and the like */
+#if POLARSSL_VERSION_NUMBER<0x01020000
if(x509parse_cert_info(buffer, sizeof(buffer), (char *)"* ",
conn->ssl[sockindex].ssl.peer_cert) != -1)
+#else
+ if(x509parse_cert_info(buffer, sizeof(buffer), (char *)"* ",
+ ssl_get_peer_cert(&(connssl->ssl))) != -1)
+#endif
infof(data, "Dumping cert info:\n%s\n", buffer);
}
View
2  lib/rawstr.c
@@ -140,3 +140,5 @@ void Curl_strntoupper(char *dest, const char *src, size_t n)
*dest++ = Curl_raw_toupper(*src);
} while(*src++ && --n);
}
+
+
View
1  lib/rawstr.h
@@ -42,4 +42,5 @@ char Curl_raw_toupper(char in);
#define checkprefix(a,b) Curl_raw_nequal(a,b,strlen(a))
void Curl_strntoupper(char *dest, const char *src, size_t n);
+
#endif
View
70 lib/ssluse.c
@@ -50,6 +50,7 @@
#include "select.h"
#include "sslgen.h"
#include "rawstr.h"
+#include "hostcheck.h"
#define _MPRINTF_REPLACE /* use the internal *printf() functions */
#include <curl/mprintf.h>
@@ -1039,71 +1040,6 @@ static int asn1_output(const ASN1_UTCTIME *tm,
/* ====================================================== */
-/*
- * Match a hostname against a wildcard pattern.
- * E.g.
- * "foo.host.com" matches "*.host.com".
- *
- * We use the matching rule described in RFC6125, section 6.4.3.
- * http://tools.ietf.org/html/rfc6125#section-6.4.3
- */
-#define HOST_NOMATCH 0
-#define HOST_MATCH 1
-
-static int hostmatch(const char *hostname, const char *pattern)
-{
- const char *pattern_label_end, *pattern_wildcard, *hostname_label_end;
- int wildcard_enabled;
- size_t prefixlen, suffixlen;
- pattern_wildcard = strchr(pattern, '*');
- if(pattern_wildcard == NULL) {
- return Curl_raw_equal(pattern, hostname) ? HOST_MATCH : HOST_NOMATCH;
- }
- /* We require at least 2 dots in pattern to avoid too wide wildcard
- match. */
- wildcard_enabled = 1;
- pattern_label_end = strchr(pattern, '.');
- if(pattern_label_end == NULL || strchr(pattern_label_end+1, '.') == NULL ||
- pattern_wildcard > pattern_label_end ||
- Curl_raw_nequal(pattern, "xn--", 4)) {
- wildcard_enabled = 0;
- }
- if(!wildcard_enabled) {
- return Curl_raw_equal(pattern, hostname) ? HOST_MATCH : HOST_NOMATCH;
- }
- hostname_label_end = strchr(hostname, '.');
- if(hostname_label_end == NULL ||
- !Curl_raw_equal(pattern_label_end, hostname_label_end)) {
- return HOST_NOMATCH;
- }
- /* The wildcard must match at least one character, so the left-most
- label of the hostname is at least as large as the left-most label
- of the pattern. */
- if(hostname_label_end - hostname < pattern_label_end - pattern) {
- return HOST_NOMATCH;
- }
- prefixlen = pattern_wildcard - pattern;
- suffixlen = pattern_label_end - (pattern_wildcard+1);
- return Curl_raw_nequal(pattern, hostname, prefixlen) &&
- Curl_raw_nequal(pattern_wildcard+1, hostname_label_end - suffixlen,
- suffixlen) ?
- HOST_MATCH : HOST_NOMATCH;
-}
-
-static int
-cert_hostcheck(const char *match_pattern, const char *hostname)
-{
- if(!match_pattern || !*match_pattern ||
- !hostname || !*hostname) /* sanity check */
- return 0;
-
- if(Curl_raw_equal(hostname, match_pattern)) /* trivial case */
- return 1;
-
- if(hostmatch(hostname,match_pattern) == HOST_MATCH)
- return 1;
- return 0;
-}
/* Quote from RFC2818 section 3.1 "Server Identity"
@@ -1192,7 +1128,7 @@ static CURLcode verifyhost(struct connectdata *conn,
if((altlen == strlen(altptr)) &&
/* if this isn't true, there was an embedded zero in the name
string and we cannot match it. */
- cert_hostcheck(altptr, conn->host.name))
+ Curl_cert_hostcheck(altptr, conn->host.name))
matched = 1;
else
matched = 0;
@@ -1291,7 +1227,7 @@ static CURLcode verifyhost(struct connectdata *conn,
"SSL: unable to obtain common name from peer certificate");
res = CURLE_PEER_FAILED_VERIFICATION;
}
- else if(!cert_hostcheck((const char *)peer_CN, conn->host.name)) {
+ else if(!Curl_cert_hostcheck((const char *)peer_CN, conn->host.name)) {
failf(data, "SSL: certificate subject name '%s' does not match "
"target host name '%s'", peer_CN, conn->host.dispname);
res = CURLE_PEER_FAILED_VERIFICATION;
Something went wrong with that request. Please try again.