nss: use a better API for controlling SSL version

This change introduces a dependency on NSS 3.14+.
This commit is contained in:
Kamil Dudka
2013-11-25 16:03:52 +01:00
parent f58f843f66
commit 30e7e7552b
3 changed files with 22 additions and 24 deletions

View File

@@ -2071,8 +2071,8 @@ if test "$curl_ssl_msg" = "$init_ssl_msg"; then
CPPFLAGS="$CPPFLAGS $addcflags" CPPFLAGS="$CPPFLAGS $addcflags"
fi fi
dnl The function PK11_CreateGenericObject is needed to load libnsspem.so dnl The function SSL_VersionRangeSet() is needed to enable TLS > 1.0
AC_CHECK_LIB(nss3, PK11_CreateGenericObject, AC_CHECK_LIB(nss3, SSL_VersionRangeSet,
[ [
AC_DEFINE(USE_NSS, 1, [if NSS is enabled]) AC_DEFINE(USE_NSS, 1, [if NSS is enabled])
AC_SUBST(USE_NSS, [1]) AC_SUBST(USE_NSS, [1])

View File

@@ -43,7 +43,7 @@ Portability
openldap 2.0 openldap 2.0
MIT krb5 lib 1.2.4 MIT krb5 lib 1.2.4
qsossl V5R3M0 qsossl V5R3M0
NSS 3.12.x NSS 3.14.x
axTLS 1.2.7 axTLS 1.2.7
Heimdal ? Heimdal ?

View File

@@ -1215,9 +1215,7 @@ CURLcode Curl_nss_connect(struct connectdata *conn, int sockindex)
{ {
PRErrorCode err = 0; PRErrorCode err = 0;
PRFileDesc *model = NULL; PRFileDesc *model = NULL;
PRBool ssl2 = PR_FALSE; SSLVersionRange sslver;
PRBool ssl3 = PR_FALSE;
PRBool tlsv1 = PR_FALSE;
PRBool ssl_no_cache; PRBool ssl_no_cache;
PRBool ssl_cbc_random_iv; PRBool ssl_cbc_random_iv;
struct SessionHandle *data = conn->data; struct SessionHandle *data = conn->data;
@@ -1292,20 +1290,25 @@ CURLcode Curl_nss_connect(struct connectdata *conn, int sockindex)
switch (data->set.ssl.version) { switch (data->set.ssl.version) {
default: default:
case CURL_SSLVERSION_DEFAULT: case CURL_SSLVERSION_DEFAULT:
ssl3 = PR_TRUE; sslver.min = SSL_LIBRARY_VERSION_3_0;
if(data->state.ssl_connect_retry) if(data->state.ssl_connect_retry) {
infof(data, "TLS disabled due to previous handshake failure\n"); infof(data, "TLS disabled due to previous handshake failure\n");
sslver.max = SSL_LIBRARY_VERSION_3_0;
}
else else
tlsv1 = PR_TRUE; sslver.max = SSL_LIBRARY_VERSION_TLS_1_0;
break; break;
case CURL_SSLVERSION_TLSv1: case CURL_SSLVERSION_TLSv1:
tlsv1 = PR_TRUE; sslver.min = SSL_LIBRARY_VERSION_TLS_1_0;
sslver.max = SSL_LIBRARY_VERSION_TLS_1_0;
break; break;
case CURL_SSLVERSION_SSLv2: case CURL_SSLVERSION_SSLv2:
ssl2 = PR_TRUE; sslver.min = SSL_LIBRARY_VERSION_2;
sslver.max = SSL_LIBRARY_VERSION_2;
break; break;
case CURL_SSLVERSION_SSLv3: case CURL_SSLVERSION_SSLv3:
ssl3 = PR_TRUE; sslver.min = SSL_LIBRARY_VERSION_3_0;
sslver.max = SSL_LIBRARY_VERSION_3_0;
break; break;
case CURL_SSLVERSION_TLSv1_0: case CURL_SSLVERSION_TLSv1_0:
case CURL_SSLVERSION_TLSv1_1: case CURL_SSLVERSION_TLSv1_1:
@@ -1315,14 +1318,7 @@ CURLcode Curl_nss_connect(struct connectdata *conn, int sockindex)
goto error; goto error;
} }
if(SSL_OptionSet(model, SSL_ENABLE_SSL2, ssl2) != SECSuccess) if(SSL_VersionRangeSet(model, &sslver) != SECSuccess)
goto error;
if(SSL_OptionSet(model, SSL_ENABLE_SSL3, ssl3) != SECSuccess)
goto error;
if(SSL_OptionSet(model, SSL_ENABLE_TLS, tlsv1) != SECSuccess)
goto error;
if(SSL_OptionSet(model, SSL_V2_COMPATIBLE_HELLO, ssl2) != SECSuccess)
goto error; goto error;
ssl_cbc_random_iv = !data->set.ssl_enable_beast; ssl_cbc_random_iv = !data->set.ssl_enable_beast;
@@ -1508,11 +1504,13 @@ CURLcode Curl_nss_connect(struct connectdata *conn, int sockindex)
if(model) if(model)
PR_Close(model); PR_Close(model);
/* cleanup on connection failure */ /* cleanup on connection failure */
Curl_llist_destroy(connssl->obj_list, NULL); Curl_llist_destroy(connssl->obj_list, NULL);
connssl->obj_list = NULL; connssl->obj_list = NULL;
if(ssl3 && tlsv1 && isTLSIntoleranceError(err)) { if((sslver.min == SSL_LIBRARY_VERSION_3_0)
&& (sslver.max == SSL_LIBRARY_VERSION_TLS_1_0)
&& isTLSIntoleranceError(err)) {
/* schedule reconnect through Curl_retry_request() */ /* schedule reconnect through Curl_retry_request() */
data->state.ssl_connect_retry = TRUE; data->state.ssl_connect_retry = TRUE;
infof(data, "Error in TLS handshake, trying SSLv3...\n"); infof(data, "Error in TLS handshake, trying SSLv3...\n");