diff -up jss/org/mozilla/jss/ssl/common.c.26 jss/org/mozilla/jss/ssl/common.c --- jss/org/mozilla/jss/ssl/common.c.26 2016-09-05 18:12:55.993519526 -0700 +++ jss/org/mozilla/jss/ssl/common.c 2016-09-05 18:12:56.010519265 -0700 @@ -7,6 +7,7 @@ #include #include #include +#include #include #include @@ -383,6 +384,13 @@ PRInt32 JSSL_enums[] = { SSL_RENEGOTIATE_REQUIRES_XTN, /* 26 */ /* ssl.h */ SSL_RENEGOTIATE_TRANSITIONAL, /* 27 */ /* ssl.h */ SSL_REQUIRE_SAFE_NEGOTIATION, /* 28 */ /* ssl.h */ + SSL_LIBRARY_VERSION_2, /* 29 */ /* sslproto.h */ + SSL_LIBRARY_VERSION_3_0, /* 30 */ /* sslproto.h */ + SSL_LIBRARY_VERSION_TLS_1_0, /* 31 */ /* sslproto.h */ + SSL_LIBRARY_VERSION_TLS_1_1, /* 32 */ /* sslproto.h */ + SSL_LIBRARY_VERSION_TLS_1_2, /* 33 */ /* sslproto.h */ + ssl_variant_stream, /* 34 */ /* sslt.h */ + ssl_variant_datagram, /* 35 */ /* sslt.h */ 0 }; diff -up jss/org/mozilla/jss/ssl/jssl.h.26 jss/org/mozilla/jss/ssl/jssl.h --- jss/org/mozilla/jss/ssl/jssl.h.26 2015-03-16 01:55:53.000000000 -0700 +++ jss/org/mozilla/jss/ssl/jssl.h 2016-09-05 18:12:56.010519265 -0700 @@ -79,6 +79,7 @@ JSSL_DestroySocketData(JNIEnv *env, JSSL extern PRInt32 JSSL_enums[]; +#define JSSL_enums_size 36 JSSL_SocketData* JSSL_CreateSocketData(JNIEnv *env, jobject sockObj, PRFileDesc* newFD, diff -up jss/org/mozilla/jss/ssl/SocketBase.java.26 jss/org/mozilla/jss/ssl/SocketBase.java --- jss/org/mozilla/jss/ssl/SocketBase.java.26 2016-09-05 18:12:55.979519742 -0700 +++ jss/org/mozilla/jss/ssl/SocketBase.java 2016-09-05 18:14:12.020349338 -0700 @@ -43,11 +43,11 @@ class SocketBase { byte[] socketCreate(Object socketObject, SSLCertificateApprovalCallback certApprovalCallback, - SSLClientCertificateSelectionCallback clientCertSelectionCallback,int family) + SSLClientCertificateSelectionCallback clientCertSelectionCallback, int family) throws SocketException { return socketCreate(socketObject, certApprovalCallback, - clientCertSelectionCallback, null, null,family); + clientCertSelectionCallback, null, null, family); } native void socketBind(byte[] addrBA, int port) throws SocketException; @@ -89,6 +89,15 @@ class SocketBase { static final int SSL_RENEGOTIATE_REQUIRES_XTN = 26; static final int SSL_RENEGOTIATE_TRANSITIONAL = 27; static final int SSL_REQUIRE_SAFE_NEGOTIATION = 28; + /* ssl/sslproto.h for supporting SSLVersionRange */ + static final int SSL_LIBRARY_VERSION_2 = 29; + static final int SSL_LIBRARY_VERSION_3_0 = 30; + static final int SSL_LIBRARY_VERSION_TLS_1_0 = 31; + static final int SSL_LIBRARY_VERSION_TLS_1_1 = 32; + static final int SSL_LIBRARY_VERSION_TLS_1_2 = 33; + /* ssl/sslt.h */ + static final int SSL_Variant_Stream = 34; + static final int SSL_Variant_Datagram = 35; static final int SSL_AF_INET = 50; @@ -179,6 +188,18 @@ class SocketBase { native void setSSLOption(int option, int on) throws SocketException; + void setSSLVersionRange(org.mozilla.jss.ssl.SSLSocket.SSLVersionRange range) + throws SocketException + { + setSSLVersionRange(range.getMinEnum(), range.getMaxEnum()); + } + + /** + * Sets SSL Version Range for this socket to support TLS v1.1 and v1.2 + */ + native void setSSLVersionRange(int min, int max) + throws SocketException; + /** * Sets the SSL option setting mode value use for options * that have more values than just enable/disable. diff -up jss/org/mozilla/jss/ssl/SSLSocket.c.26 jss/org/mozilla/jss/ssl/SSLSocket.c --- jss/org/mozilla/jss/ssl/SSLSocket.c.26 2016-09-05 18:12:56.000519419 -0700 +++ jss/org/mozilla/jss/ssl/SSLSocket.c 2016-09-05 18:12:56.010519265 -0700 @@ -17,13 +17,114 @@ #ifdef WINNT #include +#define AF_INET6 23 #endif #ifdef WIN32 #include +#define AF_INET6 23 #endif +/* + * support TLS v1.1 and v1.2 + * sets default SSL version range for sockets created after this call + */ +JNIEXPORT void JNICALL +Java_org_mozilla_jss_ssl_SSLSocket_setSSLVersionRangeDefault(JNIEnv *env, + jclass clazz, jint ssl_variant, jint min, jint max) +{ + SECStatus status; + SSLVersionRange vrange; + + if (ssl_variant <0 || ssl_variant >= JSSL_enums_size|| + min <0 || min >= JSSL_enums_size || + max <0 || max >= JSSL_enums_size) { + char buf[128]; + PR_snprintf(buf, 128, "JSS setSSLVersionRangeDefault(): for variant=%d min=%d max=%d failed - out of range for array JSSL_enums size: %d", JSSL_enums[ssl_variant], min, max, JSSL_enums_size); + JSSL_throwSSLSocketException(env, buf); + goto finish; + } + + vrange.min = JSSL_enums[min]; + vrange.max = JSSL_enums[max]; + + /* get supported range */ + SSLVersionRange supported_range; + status = SSL_VersionRangeGetSupported(JSSL_enums[ssl_variant], + &supported_range); + if( status != SECSuccess ) { + char buf[128]; + PR_snprintf(buf, 128, "SSL_VersionRangeGetSupported() for variant=%d failed: %d", JSSL_enums[ssl_variant], PR_GetError()); + JSSL_throwSSLSocketException(env, buf); + goto finish; + } + /* now check the min and max */ + if (vrange.min < supported_range.min || + vrange.max > supported_range.max) { + char buf[128]; + PR_snprintf(buf, 128, "SSL_VersionRangeSetDefault() for variant=%d with min=%d max=%d out of range (%d:%d): %d", JSSL_enums[ssl_variant], vrange.min, vrange.max, supported_range.min, supported_range.max, PR_GetError()); + JSSL_throwSSLSocketException(env, buf); + goto finish; + } + + /* set the default SSL Version Range */ + status = SSL_VersionRangeSetDefault(JSSL_enums[ssl_variant], + &vrange); + if( status != SECSuccess ) { + char buf[128]; + PR_snprintf(buf, 128, "SSL_VersionRangeSetDefault() for variant=%d with min=%d max=%d failed: %d", JSSL_enums[ssl_variant], vrange.min, vrange.max, PR_GetError()); + JSSL_throwSSLSocketException(env, buf); + goto finish; + } + +finish: + return; +} + +/* + * support TLS v1.1 and v1.2 + * sets SSL version range for this socket + */ +JNIEXPORT void JNICALL +Java_org_mozilla_jss_ssl_SocketBase_setSSLVersionRange + (JNIEnv *env, jobject self, jint min, jint max) +{ + SECStatus status; + JSSL_SocketData *sock = NULL; + SSLVersionRange vrange; + + if ( min <0 || min >= JSSL_enums_size || + max <0 || max >= JSSL_enums_size) { + char buf[128]; + PR_snprintf(buf, 128, "JSS setSSLVersionRange(): for max=%d failed - out of range for array JSSL_enums size: %d", min, max, JSSL_enums_size); + JSSL_throwSSLSocketException(env, buf); + goto finish; + } + + /* get my fd */ + if( JSSL_getSockData(env, self, &sock) != PR_SUCCESS ) { + goto finish; + } + + vrange.min = JSSL_enums[min]; + vrange.max = JSSL_enums[max]; + + /* + * set the SSL Version Range + * The validity of the range will be checked by this NSS call + */ + status = SSL_VersionRangeSet(sock->fd, &vrange); + if( status != SECSuccess ) { + JSSL_throwSSLSocketException(env, "SSL_VersionRangeSet failed"); + goto finish; + } + +finish: + EXCEPTION_CHECK(env, sock) + return; +} + JNIEXPORT void JNICALL Java_org_mozilla_jss_ssl_SSLSocket_setSSLDefaultOption(JNIEnv *env, jclass clazz, jint joption, jint on)