Bug 1036735: Update NSS to NSS 3.17.1 Beta 1. Also includes the fixes
authorWan-Teh Chang <wtc@google.com>
Wed, 27 Aug 2014 15:42:41 -0700
changeset 224974 102eaae71580397d34ef0b2dabbe7d31dbf3f32f
parent 224973 234a992d68ebb3fe041f273d2efb4283c061b5c3
child 224975 632d5a8709cbd78fe679de85eb7776bd863ebbb2
push id583
push userbhearsum@mozilla.com
push dateMon, 24 Nov 2014 19:04:58 +0000
treeherdermozilla-release@c107e74250f4 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
bugs1036735, 1046718, 1050107, 1054625, 1057465, 1057476
milestone34.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1036735: Update NSS to NSS 3.17.1 Beta 1. Also includes the fixes for bug 1046718, bug 1050107, bug 1054625, bug 1057465, bug 1057476.
security/nss/TAG-INFO
security/nss/coreconf/coreconf.dep
security/nss/lib/certhigh/certvfypkix.c
security/nss/lib/certhigh/certvfypkixprint.c
security/nss/lib/certhigh/manifest.mn
security/nss/lib/nss/nss.h
security/nss/lib/pk11wrap/dev3hack.c
security/nss/lib/softoken/softkver.h
security/nss/lib/ssl/SSLerrs.h
security/nss/lib/ssl/config.mk
security/nss/lib/ssl/dtlscon.c
security/nss/lib/ssl/ssl.h
security/nss/lib/ssl/ssl3con.c
security/nss/lib/ssl/ssl3ext.c
security/nss/lib/ssl/ssl3prot.h
security/nss/lib/ssl/sslerr.h
security/nss/lib/ssl/sslimpl.h
security/nss/lib/ssl/sslproto.h
security/nss/lib/ssl/sslsock.c
security/nss/lib/ssl/sslt.h
security/nss/lib/util/nssutil.h
security/nss/tests/pkcs11/netscape/suites/security/ssl/sslt.c
--- a/security/nss/TAG-INFO
+++ b/security/nss/TAG-INFO
@@ -1,1 +1,1 @@
-NSS_3_17_RTM
+NSS_3_17_1_BETA1
--- a/security/nss/coreconf/coreconf.dep
+++ b/security/nss/coreconf/coreconf.dep
@@ -5,9 +5,8 @@
 
 /*
  * A dummy header file that is a dependency for all the object files.
  * Used to force a full recompilation of NSS in Mozilla's Tinderbox
  * depend builds.  See comments in rules.mk.
  */
 
 #error "Do not include this header file."
-
--- a/security/nss/lib/certhigh/certvfypkix.c
+++ b/security/nss/lib/certhigh/certvfypkix.c
@@ -22,30 +22,16 @@
 #include "secasn1.h"
 #include "secder.h"
 #include "pkit.h"
 
 #include "pkix_pl_common.h"
 
 extern PRLogModuleInfo *pkixLog;
 
-#ifdef DEBUG_volkov
-/* Temporary declarations of functioins. Will be removed with fix for
- * 391183 */
-extern char *
-pkix_Error2ASCII(PKIX_Error *error, void *plContext);
-
-extern void
-cert_PrintCert(PKIX_PL_Cert *pkixCert, void *plContext);
-
-extern PKIX_Error *
-cert_PrintCertChain(PKIX_List *pkixCertChain, void *plContext);
-
-#endif /* DEBUG */
-
 #ifdef PKIX_OBJECT_LEAK_TEST
 
 extern PKIX_UInt32
 pkix_pl_lifecycle_ObjectLeakCheck(int *);
 
 extern SECStatus
 pkix_pl_lifecycle_ObjectTableUpdate(int *objCountTable);
 
@@ -893,21 +879,16 @@ cert_GetLogFromVerifyNode(
 
     PKIX_ENTER(CERTVFYPKIX, "cert_GetLogFromVerifyNode");
 
     children = node->children;
 
     if (children == NULL) {
         PKIX_ERRORCODE errCode = PKIX_ANCHORDIDNOTCHAINTOCERT;
         if (node->error && node->error->errCode != errCode) {
-#ifdef DEBUG_volkov
-            char *string = pkix_Error2ASCII(node->error, plContext);
-            fprintf(stderr, "Branch search finished with error: \t%s\n", string);
-            PKIX_PL_Free(string, NULL);
-#endif
             if (log != NULL) {
                 SECErrorCodes nssErrorCode = 0;
                 CERTCertificate *cert = NULL;
 
                 cert = node->verifyCert->nssCert;
 
                 PKIX_CHECK(
                     cert_PkixErrorToNssCode(node->error, &nssErrorCode,
@@ -998,32 +979,24 @@ cert_GetBuildResults(
     void             *plContext)
 {
     PKIX_ValidateResult *validResult = NULL;
     CERTCertList        *validChain = NULL;
     CERTCertificate     *trustedRoot = NULL;
     PKIX_TrustAnchor    *trustAnchor = NULL;
     PKIX_PL_Cert        *trustedCert = NULL;
     PKIX_List           *pkixCertChain = NULL;
-#ifdef DEBUG_volkov
-    PKIX_Error          *tmpPkixError = NULL;
-#endif /* DEBUG */
             
     PKIX_ENTER(CERTVFYPKIX, "cert_GetBuildResults");
     if (buildResult == NULL && error == NULL) {
         PKIX_ERROR(PKIX_NULLARGUMENT);
     }
 
     if (error) {
         SECErrorCodes nssErrorCode = 0;
-#ifdef DEBUG_volkov        
-        char *temp = pkix_Error2ASCII(error, plContext);
-        fprintf(stderr, "BUILD ERROR:\n%s\n", temp);
-        PKIX_PL_Free(temp, NULL);
-#endif /* DEBUG */
         if (verifyNode) {
             PKIX_Error *tmpError =
                 cert_GetLogFromVerifyNode(log, verifyNode, plContext);
             if (tmpError) {
                 PKIX_PL_Object_DecRef((PKIX_PL_Object *)tmpError, plContext);
             }
         }
         cert_PkixErrorToNssCode(error, &nssErrorCode, plContext);
@@ -1032,23 +1005,16 @@ cert_GetBuildResults(
     }
 
     if (pvalidChain) {
         PKIX_CHECK(
             PKIX_BuildResult_GetCertChain(buildResult, &pkixCertChain,
                                           plContext),
             PKIX_BUILDRESULTGETCERTCHAINFAILED);
 
-#ifdef DEBUG_volkov
-        tmpPkixError = cert_PrintCertChain(pkixCertChain, plContext);
-        if (tmpPkixError) {
-            PKIX_PL_Object_DecRef((PKIX_PL_Object*)tmpPkixError, plContext);
-        }
-#endif        
-
         PKIX_CHECK(
             cert_PkixToNssCertsChain(pkixCertChain, &validChain, plContext),
             PKIX_CERTCHAINTONSSCHAINFAILED);
     }
 
     if (ptrustedRoot) {
         PKIX_CHECK(
             PKIX_BuildResult_GetValidateResult(buildResult, &validResult,
@@ -1060,23 +1026,17 @@ cert_GetBuildResults(
                                                plContext),
             PKIX_VALIDATERESULTGETTRUSTANCHORFAILED);
 
         PKIX_CHECK(
             PKIX_TrustAnchor_GetTrustedCert(trustAnchor, &trustedCert,
                                             plContext),
             PKIX_TRUSTANCHORGETTRUSTEDCERTFAILED);
 
-#ifdef DEBUG_volkov
-        if (pvalidChain == NULL) {
-            cert_PrintCert(trustedCert, plContext);
-        }
-#endif        
-
-       PKIX_CHECK(
+        PKIX_CHECK(
             PKIX_PL_Cert_GetCERTCertificate(trustedCert, &trustedRoot,
                                             plContext),
             PKIX_CERTGETCERTCERTIFICATEFAILED);
     }
  
     PORT_Assert(!PKIX_ERROR_RECEIVED);
 
     if (trustedRoot) {
@@ -1153,20 +1113,16 @@ cert_VerifyCertChainPkix(
 {
     PKIX_ProcessingParams *procParams = NULL;
     PKIX_BuildResult      *result = NULL;
     PKIX_VerifyNode       *verifyNode = NULL;
     PKIX_Error            *error = NULL;
 
     SECStatus              rv = SECFailure;
     void                  *plContext = NULL;
-#ifdef DEBUG_volkov
-    CERTCertificate       *trustedRoot = NULL;
-    CERTCertList          *validChain = NULL;
-#endif /* DEBUG */
 
 #ifdef PKIX_OBJECT_LEAK_TEST
     int  leakedObjNum = 0;
     int  memLeakLoopCount = 0;
     int  objCountTable[PKIX_NUMTYPES]; 
     int  fnInvLocalCount = 0;
     PKIX_Boolean savedUsePkixEngFlag = usePKIXValidationEngine;
 
@@ -1191,20 +1147,16 @@ cert_VerifyCertChainPkix(
 
 do {
     rv = SECFailure;
     plContext = NULL;
     procParams = NULL;
     result = NULL;
     verifyNode = NULL;
     error = NULL;
-#ifdef DEBUG_volkov
-    trustedRoot = NULL;
-    validChain = NULL;
-#endif /* DEBUG */
     errorGenerated = PKIX_FALSE;
     stackPosition = 0;
 
     if (leakedObjNum) {
         pkix_pl_lifecycle_ObjectTableUpdate(objCountTable); 
     }
     memLeakLoopCount += 1;
 #endif /* PKIX_OBJECT_LEAK_TEST */
@@ -1237,39 +1189,21 @@ do {
     }
     if (pSigerror) {
         /* Currently always PR_FALSE. Will be fixed as a part of 394077 */
         *pSigerror = PR_FALSE;
     }
     rv = SECSuccess;
 
 cleanup:
-    error = cert_GetBuildResults(result, verifyNode, error, log,
-#ifdef DEBUG_volkov                                 
-                                 &trustedRoot, &validChain,
-#else
-                                 NULL, NULL,
-#endif /* DEBUG */
+    error = cert_GetBuildResults(result, verifyNode, error, log, NULL, NULL,
                                  plContext);
     if (error) {
-#ifdef DEBUG_volkov        
-        char *temp = pkix_Error2ASCII(error, plContext);
-        fprintf(stderr, "GET BUILD RES ERRORS:\n%s\n", temp);
-        PKIX_PL_Free(temp, NULL);
-#endif /* DEBUG */
         PKIX_PL_Object_DecRef((PKIX_PL_Object *)error, plContext);
     }
-#ifdef DEBUG_volkov
-    if (trustedRoot) {
-        CERT_DestroyCertificate(trustedRoot);
-    }
-    if (validChain) {
-        CERT_DestroyCertList(validChain);
-    }
-#endif /* DEBUG */
     if (procParams) {
         PKIX_PL_Object_DecRef((PKIX_PL_Object *)procParams, plContext);
     }
     if (plContext) {
         PKIX_PL_NssContext_Destroy(plContext);
     }
 
 #ifdef PKIX_OBJECT_LEAK_TEST
deleted file mode 100644
--- a/security/nss/lib/certhigh/certvfypkixprint.c
+++ /dev/null
@@ -1,206 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/*
- * nss_pkix_proxy.h
- *
- * PKIX - NSS proxy functions
- *
- */
-#include "cert.h"
-#include "pkix_pl_common.h"
-
-#ifdef DEBUG
-
-char *
-pkix_Error2ASCII(PKIX_Error *error, void *plContext)
-{
-        PKIX_UInt32 length;
-        char *asciiString = NULL;
-        PKIX_PL_String *pkixString = NULL;
-        PKIX_Error *errorResult = NULL;
-
-        errorResult = PKIX_PL_Object_ToString
-                ((PKIX_PL_Object*)error, &pkixString, plContext);
-        if (errorResult) goto cleanup;
-
-        errorResult = PKIX_PL_String_GetEncoded
-                (pkixString,
-                PKIX_ESCASCII,
-                (void **)&asciiString,
-                &length,
-                plContext);
-
-cleanup:
-
-        if (pkixString){
-                if (PKIX_PL_Object_DecRef
-                    ((PKIX_PL_Object*)pkixString, plContext)){
-                        return (NULL);
-                }
-        }
-
-        if (errorResult){
-            PKIX_PL_Object_DecRef((PKIX_PL_Object*)errorResult, plContext);
-            return (NULL);
-        }
-
-        return (asciiString);
-}
-
-char *
-pkix_Object2ASCII(PKIX_PL_Object *object)
-{
-        PKIX_UInt32 length;
-        char *asciiString = NULL;
-        PKIX_PL_String *pkixString = NULL;
-        PKIX_Error *errorResult = NULL;
-
-        errorResult = PKIX_PL_Object_ToString
-                (object, &pkixString, NULL);
-        if (errorResult) goto cleanup;
-
-        errorResult = PKIX_PL_String_GetEncoded
-            (pkixString, PKIX_ESCASCII, (void **)&asciiString, &length, NULL);
-
-cleanup:
-
-        if (pkixString){
-                if (PKIX_PL_Object_DecRef((PKIX_PL_Object*)pkixString, NULL)){
-                        return (NULL);
-                }
-        }
-
-        if (errorResult){
-                return (NULL);
-        }
-
-        return (asciiString);
-}
-
-char *
-pkix_Cert2ASCII(PKIX_PL_Cert *cert)
-{
-        PKIX_PL_X500Name *issuer = NULL;
-        void *issuerAscii = NULL;
-        PKIX_PL_X500Name *subject = NULL;
-        void *subjectAscii = NULL;
-        void *asciiString = NULL;
-        PKIX_Error *errorResult = NULL;
-        PKIX_UInt32 numChars;
-        PKIX_UInt32 refCount = 0;
-
-        /* Issuer */
-        errorResult = PKIX_PL_Cert_GetIssuer(cert, &issuer, NULL);
-        if (errorResult) goto cleanup;
-
-        issuerAscii = pkix_Object2ASCII((PKIX_PL_Object*)issuer);
-
-        /* Subject */
-        errorResult = PKIX_PL_Cert_GetSubject(cert, &subject, NULL);
-        if (errorResult) goto cleanup;
-
-        if (subject){
-                subjectAscii = pkix_Object2ASCII((PKIX_PL_Object*)subject);
-        }
-
-/*         errorResult = PKIX_PL_Object_GetRefCount((PKIX_PL_Object*)cert, &refCount, NULL); */
-        if (errorResult) goto cleanup;
-
-        errorResult = PKIX_PL_Malloc(200, &asciiString, NULL);
-        if (errorResult) goto cleanup;
-
-        numChars =
-                PR_snprintf
-                (asciiString,
-                200,
-                "Ref: %d   Subject=%s\nIssuer=%s\n",
-                 refCount,
-                subjectAscii,
-                issuerAscii);
-
-        if (!numChars) goto cleanup;
-
-cleanup:
-
-        if (issuer){
-                if (PKIX_PL_Object_DecRef((PKIX_PL_Object*)issuer, NULL)){
-                        return (NULL);
-                }
-        }
-
-        if (subject){
-                if (PKIX_PL_Object_DecRef((PKIX_PL_Object*)subject, NULL)){
-                        return (NULL);
-                }
-        }
-
-        if (PKIX_PL_Free((PKIX_PL_Object*)issuerAscii, NULL)){
-                return (NULL);
-        }
-
-        if (PKIX_PL_Free((PKIX_PL_Object*)subjectAscii, NULL)){
-                return (NULL);
-        }
-
-        if (errorResult){
-                return (NULL);
-        }
-
-        return (asciiString);
-}
-
-PKIX_Error *
-cert_PrintCertChain(
-    PKIX_List *pkixCertChain,
-    void *plContext)
-{
-    PKIX_PL_Cert *cert = NULL;
-    PKIX_UInt32 numCerts = 0, i = 0;
-    char *asciiResult = NULL;
-    
-    PKIX_ENTER(CERTVFYPKIX, "cert_PrintCertChain");
-
-    PKIX_CHECK(
-        PKIX_List_GetLength(pkixCertChain, &numCerts, plContext),
-        PKIX_LISTGETLENGTHFAILED);
-    
-    fprintf(stderr, "\n");
-    
-    for (i = 0; i < numCerts; i++){
-        PKIX_CHECK
-            (PKIX_List_GetItem
-             (pkixCertChain, i, (PKIX_PL_Object**)&cert, plContext),
-             PKIX_LISTGETITEMFAILED);
-        
-        asciiResult = pkix_Cert2ASCII(cert);
-        
-        fprintf(stderr, "CERT[%d]:\n%s\n", i, asciiResult);
-        
-        PKIX_PL_Free(asciiResult, plContext);
-        asciiResult = NULL;
-        
-        PKIX_DECREF(cert);
-    }
-
-cleanup:
-    PKIX_DECREF(cert);
-
-    PKIX_RETURN(CERTVFYPKIX);
-}
-
-void
-cert_PrintCert(
-    PKIX_PL_Cert *pkixCert,
-    void *plContext)
-{
-    char *asciiResult = NULL;
-    
-    asciiResult = pkix_Cert2ASCII(pkixCert);
-    
-    fprintf(stderr, "CERT[0]:\n%s\n", asciiResult);
-    
-    PKIX_PL_Free(asciiResult, plContext);
-}
-
-#endif /* DEBUG */
--- a/security/nss/lib/certhigh/manifest.mn
+++ b/security/nss/lib/certhigh/manifest.mn
@@ -20,16 +20,15 @@ CSRCS = \
 	certhtml.c \
 	certreq.c \
 	crlv2.c \
 	ocsp.c \
 	ocspsig.c \
 	certhigh.c \
  	certvfy.c \
  	certvfypkix.c \
- 	certvfypkixprint.c \
  	xcrldist.c \
 	$(NULL)
 
 LIBRARY_NAME = certhi
 
 # This part of the code, including all sub-dirs, can be optimized for size
 export ALLOW_OPT_CODE_SIZE = 1
--- a/security/nss/lib/nss/nss.h
+++ b/security/nss/lib/nss/nss.h
@@ -28,22 +28,22 @@
 
 /*
  * NSS's major version, minor version, patch level, build number, and whether
  * this is a beta release.
  *
  * The format of the version string should be
  *     "<major version>.<minor version>[.<patch level>[.<build number>]][ <ECC>][ <Beta>]"
  */
-#define NSS_VERSION  "3.17" _NSS_ECC_STRING _NSS_CUSTOMIZED
+#define NSS_VERSION  "3.17.1" _NSS_ECC_STRING _NSS_CUSTOMIZED " Beta"
 #define NSS_VMAJOR   3
 #define NSS_VMINOR   17
-#define NSS_VPATCH   0
+#define NSS_VPATCH   1
 #define NSS_VBUILD   0
-#define NSS_BETA     PR_FALSE
+#define NSS_BETA     PR_TRUE
 
 #ifndef RC_INVOKED
 
 #include "seccomon.h"
 
 typedef struct NSSInitParametersStr NSSInitParameters;
 
 /*
--- a/security/nss/lib/pk11wrap/dev3hack.c
+++ b/security/nss/lib/pk11wrap/dev3hack.c
@@ -87,24 +87,24 @@ nssSlot_CreateSession
 }
 
 NSS_IMPLEMENT PRStatus
 nssSession_Destroy
 (
   nssSession *s
 )
 {
-    CK_RV ckrv = CKR_OK;
+    PRStatus rv = PR_SUCCESS;
     if (s) {
 	if (s->isRW) {
 	    PK11_RestoreROSession(s->slot->pk11slot, s->handle);
 	}
-	nss_ZFreeIf(s);
+	rv = nss_ZFreeIf(s);
     }
-    return (ckrv == CKR_OK) ? PR_SUCCESS : PR_FAILURE;
+    return rv;
 }
 
 static NSSSlot *
 nssSlot_CreateFromPK11SlotInfo(NSSTrustDomain *td, PK11SlotInfo *nss3slot)
 {
     NSSSlot *rvSlot;
     NSSArena *arena;
     arena = nssArena_Create();
--- a/security/nss/lib/softoken/softkver.h
+++ b/security/nss/lib/softoken/softkver.h
@@ -20,16 +20,16 @@
 
 /*
  * Softoken's major version, minor version, patch level, build number,
  * and whether this is a beta release.
  *
  * The format of the version string should be
  *     "<major version>.<minor version>[.<patch level>[.<build number>]][ <ECC>][ <Beta>]"
  */
-#define SOFTOKEN_VERSION  "3.17" SOFTOKEN_ECC_STRING
+#define SOFTOKEN_VERSION  "3.17.1" SOFTOKEN_ECC_STRING " Beta"
 #define SOFTOKEN_VMAJOR   3
 #define SOFTOKEN_VMINOR   17
-#define SOFTOKEN_VPATCH   0
+#define SOFTOKEN_VPATCH   1
 #define SOFTOKEN_VBUILD   0
-#define SOFTOKEN_BETA     PR_FALSE
+#define SOFTOKEN_BETA     PR_TRUE
 
 #endif /* _SOFTKVER_H_ */
--- a/security/nss/lib/ssl/SSLerrs.h
+++ b/security/nss/lib/ssl/SSLerrs.h
@@ -413,8 +413,12 @@ ER3(SSL_ERROR_DIGEST_FAILURE, (SSL_ERROR
 ER3(SSL_ERROR_INCORRECT_SIGNATURE_ALGORITHM, (SSL_ERROR_BASE + 128),
 "Incorrect signature algorithm specified in a digitally-signed element.")
 
 ER3(SSL_ERROR_NEXT_PROTOCOL_NO_CALLBACK, (SSL_ERROR_BASE + 129),
 "The next protocol negotiation extension was enabled, but the callback was cleared prior to being needed.")
 
 ER3(SSL_ERROR_NEXT_PROTOCOL_NO_PROTOCOL, (SSL_ERROR_BASE + 130),
 "The server supports no protocols that the client advertises in the ALPN extension.")
+
+ER3(SSL_ERROR_INAPPROPRIATE_FALLBACK_ALERT, (SSL_ERROR_BASE + 131),
+"The server rejected the handshake because the client downgraded to a lower "
+"TLS version than the server supports.")
--- a/security/nss/lib/ssl/config.mk
+++ b/security/nss/lib/ssl/config.mk
@@ -2,16 +2,21 @@
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
 ifdef NISCC_TEST
 DEFINES += -DNISCC_TEST
 endif
 
+# Allow build-time configuration of TLS 1.3 (Experimental)
+ifdef NSS_ENABLE_TLS_1_3
+DEFINES += -DNSS_ENABLE_TLS_1_3
+endif
+
 ifdef NSS_NO_PKCS11_BYPASS
 DEFINES += -DNO_PKCS11_BYPASS
 else
 CRYPTOLIB=$(SOFTOKEN_LIB_DIR)/$(LIB_PREFIX)freebl.$(LIB_SUFFIX)
 
 EXTRA_LIBS += \
 	$(CRYPTOLIB) \
 	$(NULL)
--- a/security/nss/lib/ssl/dtlscon.c
+++ b/security/nss/lib/ssl/dtlscon.c
@@ -47,26 +47,30 @@ static const ssl3CipherSuite nonDTLSSuit
 };
 
 /* Map back and forth between TLS and DTLS versions in wire format.
  * Mapping table is:
  *
  * TLS             DTLS
  * 1.1 (0302)      1.0 (feff)
  * 1.2 (0303)      1.2 (fefd)
+ * 1.3 (0304)      1.3 (fefc)
  */
 SSL3ProtocolVersion
 dtls_TLSVersionToDTLSVersion(SSL3ProtocolVersion tlsv)
 {
     if (tlsv == SSL_LIBRARY_VERSION_TLS_1_1) {
         return SSL_LIBRARY_VERSION_DTLS_1_0_WIRE;
     }
     if (tlsv == SSL_LIBRARY_VERSION_TLS_1_2) {
         return SSL_LIBRARY_VERSION_DTLS_1_2_WIRE;
     }
+    if (tlsv == SSL_LIBRARY_VERSION_TLS_1_3) {
+        return SSL_LIBRARY_VERSION_DTLS_1_3_WIRE;
+    }
 
     /* Anything other than TLS 1.1 or 1.2 is an error, so return
      * the invalid version 0xffff. */
     return 0xffff;
 }
 
 /* Map known DTLS versions to known TLS versions.
  * - Invalid versions (< 1.0) return a version of 0
@@ -80,16 +84,19 @@ dtls_DTLSVersionToTLSVersion(SSL3Protoco
     }
 
     if (dtlsv == SSL_LIBRARY_VERSION_DTLS_1_0_WIRE) {
         return SSL_LIBRARY_VERSION_TLS_1_1;
     }
     if (dtlsv == SSL_LIBRARY_VERSION_DTLS_1_2_WIRE) {
         return SSL_LIBRARY_VERSION_TLS_1_2;
     }
+    if (dtlsv == SSL_LIBRARY_VERSION_DTLS_1_3_WIRE) {
+        return SSL_LIBRARY_VERSION_TLS_1_3;
+    }
 
     /* Return a fictional higher version than we know of */
     return SSL_LIBRARY_VERSION_TLS_1_2 + 1;
 }
 
 /* On this socket, Disable non-DTLS cipher suites in the argument's list */
 SECStatus
 ssl3_DisableNonDTLSSuites(sslSocket * ss)
--- a/security/nss/lib/ssl/ssl.h
+++ b/security/nss/lib/ssl/ssl.h
@@ -183,16 +183,19 @@ SSL_IMPORT PRFileDesc *DTLS_ImportFD(PRF
 #define SSL_ENABLE_ALPN 26
 
 /* SSL_REUSE_SERVER_ECDHE_KEY controls whether the ECDHE server key is
  * reused for multiple handshakes or generated each time.
  * SSL_REUSE_SERVER_ECDHE_KEY is currently enabled by default.
  */
 #define SSL_REUSE_SERVER_ECDHE_KEY 27
 
+#define SSL_ENABLE_FALLBACK_SCSV       28 /* Send fallback SCSV in
+                                           * handshakes. */
+
 #ifdef SSL_DEPRECATED_FUNCTION 
 /* Old deprecated function names */
 SSL_IMPORT SECStatus SSL_Enable(PRFileDesc *fd, int option, PRBool on);
 SSL_IMPORT SECStatus SSL_EnableDefault(int option, PRBool on);
 #endif
 
 /* New function names */
 SSL_IMPORT SECStatus SSL_OptionSet(PRFileDesc *fd, PRInt32 option, PRBool on);
--- a/security/nss/lib/ssl/ssl3con.c
+++ b/security/nss/lib/ssl/ssl3con.c
@@ -210,17 +210,20 @@ static const int compressionMethodsCount
 static PRBool
 compressionEnabled(sslSocket *ss, SSLCompressionMethod compression)
 {
     switch (compression) {
     case ssl_compression_null:
 	return PR_TRUE;  /* Always enabled */
 #ifdef NSS_ENABLE_ZLIB
     case ssl_compression_deflate:
-	return ss->opt.enableDeflate;
+        if (ss->version < SSL_LIBRARY_VERSION_TLS_1_3) {
+            return ss->opt.enableDeflate;
+        }
+        return PR_FALSE;
 #endif
     default:
 	return PR_FALSE;
     }
 }
 
 static const /*SSL3ClientCertificateType */ PRUint8 certificate_types [] = {
     ct_RSA_sign,
@@ -632,24 +635,26 @@ ssl3_CipherSuiteAllowedForVersionRange(
      *   TLS_DH_anon_EXPORT_WITH_RC4_40_MD5:     never implemented
      *   TLS_DH_anon_EXPORT_WITH_DES40_CBC_SHA:  never implemented
      */
 	return vrange->min <= SSL_LIBRARY_VERSION_TLS_1_0;
 
     case TLS_DHE_RSA_WITH_AES_256_CBC_SHA256:
     case TLS_RSA_WITH_AES_256_CBC_SHA256:
     case TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256:
-    case TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256:
     case TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256:
-    case TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256:
     case TLS_DHE_RSA_WITH_AES_128_CBC_SHA256:
-    case TLS_DHE_RSA_WITH_AES_128_GCM_SHA256:
     case TLS_RSA_WITH_AES_128_CBC_SHA256:
     case TLS_RSA_WITH_AES_128_GCM_SHA256:
     case TLS_RSA_WITH_NULL_SHA256:
+        return vrange->max == SSL_LIBRARY_VERSION_TLS_1_2;
+
+    case TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256:
+    case TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256:
+    case TLS_DHE_RSA_WITH_AES_128_GCM_SHA256:
 	return vrange->max >= SSL_LIBRARY_VERSION_TLS_1_2;
 
     /* RFC 4492: ECC cipher suites need TLS extensions to negotiate curves and
      * point formats.*/
     case TLS_ECDH_ECDSA_WITH_NULL_SHA:
     case TLS_ECDH_ECDSA_WITH_RC4_128_SHA:
     case TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA:
     case TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA:
@@ -664,20 +669,21 @@ ssl3_CipherSuiteAllowedForVersionRange(
     case TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA:
     case TLS_ECDH_RSA_WITH_AES_128_CBC_SHA:
     case TLS_ECDH_RSA_WITH_AES_256_CBC_SHA:
     case TLS_ECDHE_RSA_WITH_NULL_SHA:
     case TLS_ECDHE_RSA_WITH_RC4_128_SHA:
     case TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA:
     case TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA:
     case TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA:
-	return vrange->max >= SSL_LIBRARY_VERSION_TLS_1_0;
+        return vrange->max >= SSL_LIBRARY_VERSION_TLS_1_0 &&
+               vrange->min < SSL_LIBRARY_VERSION_TLS_1_3;
 
     default:
-	return PR_TRUE;
+        return vrange->min < SSL_LIBRARY_VERSION_TLS_1_3;
     }
 }
 
 /* return pointer to ssl3CipherSuiteDef for suite, or NULL */
 /* XXX This does a linear search.  A binary search would be better. */
 static const ssl3CipherSuiteDef *
 ssl_LookupCipherSuiteDef(ssl3CipherSuite suite)
 {
@@ -3347,16 +3353,19 @@ ssl3_HandleAlert(sslSocket *ss, sslBuffe
     case no_certificate: 	error = SSL_ERROR_NO_CERTIFICATE;	  break;
     case bad_certificate: 	error = SSL_ERROR_BAD_CERT_ALERT; 	  break;
     case unsupported_certificate:error = SSL_ERROR_UNSUPPORTED_CERT_ALERT;break;
     case certificate_revoked: 	error = SSL_ERROR_REVOKED_CERT_ALERT; 	  break;
     case certificate_expired: 	error = SSL_ERROR_EXPIRED_CERT_ALERT; 	  break;
     case certificate_unknown: 	error = SSL_ERROR_CERTIFICATE_UNKNOWN_ALERT;
 			        					  break;
     case illegal_parameter: 	error = SSL_ERROR_ILLEGAL_PARAMETER_ALERT;break;
+    case inappropriate_fallback:
+        error = SSL_ERROR_INAPPROPRIATE_FALLBACK_ALERT;
+        break;
 
     /* All alerts below are TLS only. */
     case unknown_ca: 		error = SSL_ERROR_UNKNOWN_CA_ALERT;       break;
     case access_denied: 	error = SSL_ERROR_ACCESS_DENIED_ALERT;    break;
     case decode_error: 		error = SSL_ERROR_DECODE_ERROR_ALERT;     break;
     case decrypt_error: 	error = SSL_ERROR_DECRYPT_ERROR_ALERT;    break;
     case export_restriction: 	error = SSL_ERROR_EXPORT_RESTRICTION_ALERT; 
     									  break;
@@ -4868,16 +4877,17 @@ ssl3_SendClientHello(sslSocket *ss, PRBo
     sslSessionID *   sid;
     ssl3CipherSpec * cwSpec;
     SECStatus        rv;
     int              i;
     int              length;
     int              num_suites;
     int              actual_count = 0;
     PRBool           isTLS = PR_FALSE;
+    PRBool           requestingResume = PR_FALSE, fallbackSCSV = PR_FALSE;
     PRInt32          total_exten_len = 0;
     unsigned         paddingExtensionLen;
     unsigned         numCompressionMethods;
     PRInt32          flags;
 
     SSL_TRC(3, ("%d: SSL3[%d]: send client_hello handshake", SSL_GETPID(),
 		ss->fd));
 
@@ -5010,16 +5020,17 @@ ssl3_SendClientHello(sslSocket *ss, PRBo
 	    if (ss->sec.uncache)
                 (*ss->sec.uncache)(sid);
 	    ssl_FreeSID(sid);
 	    sid = NULL;
 	}
     }
 
     if (sid) {
+	requestingResume = PR_TRUE;
 	SSL_AtomicIncrementLong(& ssl3stats.sch_sid_cache_hits );
 
 	PRINT_BUF(4, (ss, "client, found session-id:", sid->u.ssl3.sessionID,
 		      sid->u.ssl3.sessionIDLength));
 
 	ss->ssl3.policy = sid->u.ssl3.policy;
     } else {
 	SSL_AtomicIncrementLong(& ssl3stats.sch_sid_cache_misses );
@@ -5124,18 +5135,25 @@ ssl3_SendClientHello(sslSocket *ss, PRBo
     }
 
     /* how many suites are permitted by policy and user preference? */
     num_suites = count_cipher_suites(ss, ss->ssl3.policy, PR_TRUE);
     if (!num_suites) {
     	if (sid->u.ssl3.lock) { PR_RWLock_Unlock(sid->u.ssl3.lock); }
     	return SECFailure;	/* count_cipher_suites has set error code. */
     }
+
+    fallbackSCSV = ss->opt.enableFallbackSCSV && (!requestingResume ||
+						  ss->version < sid->version);
+    /* make room for SCSV */
     if (ss->ssl3.hs.sendingSCSV) {
-	++num_suites;   /* make room for SCSV */
+	++num_suites;
+    }
+    if (fallbackSCSV) {
+	++num_suites;
     }
 
     /* count compression methods */
     numCompressionMethods = 0;
     for (i = 0; i < compressionMethodsCount; i++) {
 	if (compressionEnabled(ss, compressions[i]))
 	    numCompressionMethods++;
     }
@@ -5231,16 +5249,25 @@ ssl3_SendClientHello(sslSocket *ss, PRBo
 	rv = ssl3_AppendHandshakeNumber(ss, TLS_EMPTY_RENEGOTIATION_INFO_SCSV,
 					sizeof(ssl3CipherSuite));
 	if (rv != SECSuccess) {
 	    if (sid->u.ssl3.lock) { PR_RWLock_Unlock(sid->u.ssl3.lock); }
 	    return rv;	/* err set by ssl3_AppendHandshake* */
 	}
 	actual_count++;
     }
+    if (fallbackSCSV) {
+	rv = ssl3_AppendHandshakeNumber(ss, TLS_FALLBACK_SCSV,
+					sizeof(ssl3CipherSuite));
+	if (rv != SECSuccess) {
+	    if (sid->u.ssl3.lock) { PR_RWLock_Unlock(sid->u.ssl3.lock); }
+	    return rv;	/* err set by ssl3_AppendHandshake* */
+	}
+	actual_count++;
+    }
     for (i = 0; i < ssl_V3_SUITES_IMPLEMENTED; i++) {
 	ssl3CipherSuiteCfg *suite = &ss->cipherSuites[i];
 	if (config_match(suite, ss->ssl3.policy, PR_TRUE, &ss->vrange)) {
 	    actual_count++;
 	    if (actual_count > num_suites) {
 		if (sid->u.ssl3.lock) { PR_RWLock_Unlock(sid->u.ssl3.lock); }
 		/* set error card removal/insertion error */
 		PORT_SetError(SSL_ERROR_TOKEN_INSERTION_REMOVAL);
@@ -7706,22 +7733,41 @@ ssl3_HandleClientHello(sslSocket *ss, SS
     }
 
     /* grab the list of cipher suites. */
     rv = ssl3_ConsumeHandshakeVariable(ss, &suites, 2, &b, &length);
     if (rv != SECSuccess) {
 	goto loser;		/* malformed */
     }
 
+    /* If the ClientHello version is less than our maximum version, check for a
+     * TLS_FALLBACK_SCSV and reject the connection if found. */
+    if (ss->vrange.max > ss->clientHelloVersion) {
+	for (i = 0; i + 1 < suites.len; i += 2) {
+	    PRUint16 suite_i = (suites.data[i] << 8) | suites.data[i + 1];
+	    if (suite_i != TLS_FALLBACK_SCSV)
+		continue;
+	    desc = inappropriate_fallback;
+	    errCode = SSL_ERROR_INAPPROPRIATE_FALLBACK_ALERT;
+	    goto alert_loser;
+	}
+    }
+
     /* grab the list of compression methods. */
     rv = ssl3_ConsumeHandshakeVariable(ss, &comps, 1, &b, &length);
     if (rv != SECSuccess) {
 	goto loser;		/* malformed */
     }
 
+    /* TLS 1.3 requires that compression be empty */
+    if (ss->version >= SSL_LIBRARY_VERSION_TLS_1_3) {
+        if (comps.len != 1 || comps.data[0] != ssl_compression_null) {
+            goto loser;
+        }
+    }
     desc = handshake_failure;
 
     /* Handle TLS hello extensions for SSL3 & TLS. We do not know if
      * we are restarting a previous session until extensions have been
      * parsed, since we might have received a SessionTicket extension.
      * Note: we allow extensions even when negotiating SSL3 for the sake
      * of interoperability (and backwards compatibility).
      */
--- a/security/nss/lib/ssl/ssl3ext.c
+++ b/security/nss/lib/ssl/ssl3ext.c
@@ -77,16 +77,21 @@ static SECStatus ssl3_ClientHandleStatus
                                                    SECItem *data);
 static PRInt32 ssl3_ClientSendStatusRequestXtn(sslSocket * ss, PRBool append,
                                                PRUint32 maxBytes);
 static PRInt32 ssl3_ClientSendSigAlgsXtn(sslSocket *ss, PRBool append,
                                          PRUint32 maxBytes);
 static SECStatus ssl3_ServerHandleSigAlgsXtn(sslSocket *ss, PRUint16 ex_type,
                                              SECItem *data);
 
+static PRInt32 ssl3_ClientSendDraftVersionXtn(sslSocket *ss, PRBool append,
+                                              PRUint32 maxBytes);
+static SECStatus ssl3_ServerHandleDraftVersionXtn(sslSocket *ss, PRUint16 ex_type,
+                                                  SECItem *data);
+
 /*
  * Write bytes.  Using this function means the SECItem structure
  * cannot be freed.  The caller is expected to call this function
  * on a shallow copy of the structure.
  */
 static SECStatus
 ssl3_AppendToItem(SECItem *item, const unsigned char *buf, PRUint32 bytes)
 {
@@ -240,16 +245,17 @@ static const ssl3HelloExtensionHandler c
 #endif
     { ssl_session_ticket_xtn,     &ssl3_ServerHandleSessionTicketXtn },
     { ssl_renegotiation_info_xtn, &ssl3_HandleRenegotiationInfoXtn },
     { ssl_next_proto_nego_xtn,    &ssl3_ServerHandleNextProtoNegoXtn },
     { ssl_app_layer_protocol_xtn, &ssl3_ServerHandleAppProtoXtn },
     { ssl_use_srtp_xtn,           &ssl3_HandleUseSRTPXtn },
     { ssl_cert_status_xtn,        &ssl3_ServerHandleStatusRequestXtn },
     { ssl_signature_algorithms_xtn, &ssl3_ServerHandleSigAlgsXtn },
+    { ssl_tls13_draft_version_xtn, &ssl3_ServerHandleDraftVersionXtn },
     { -1, NULL }
 };
 
 /* These two tables are used by the client, to handle server hello
  * extensions. */
 static const ssl3HelloExtensionHandler serverHelloHandlersTLS[] = {
     { ssl_server_name_xtn,        &ssl3_HandleServerNameXtn },
     /* TODO: add a handler for ssl_ec_point_formats_xtn */
@@ -281,17 +287,18 @@ ssl3HelloExtensionSender clientHelloSend
     { ssl_elliptic_curves_xtn,    &ssl3_SendSupportedCurvesXtn },
     { ssl_ec_point_formats_xtn,   &ssl3_SendSupportedPointFormatsXtn },
 #endif
     { ssl_session_ticket_xtn,     &ssl3_SendSessionTicketXtn },
     { ssl_next_proto_nego_xtn,    &ssl3_ClientSendNextProtoNegoXtn },
     { ssl_app_layer_protocol_xtn, &ssl3_ClientSendAppProtoXtn },
     { ssl_use_srtp_xtn,           &ssl3_SendUseSRTPXtn },
     { ssl_cert_status_xtn,        &ssl3_ClientSendStatusRequestXtn },
-    { ssl_signature_algorithms_xtn, &ssl3_ClientSendSigAlgsXtn }
+    { ssl_signature_algorithms_xtn, &ssl3_ClientSendSigAlgsXtn },
+    { ssl_tls13_draft_version_xtn, &ssl3_ClientSendDraftVersionXtn },
     /* any extra entries will appear as { 0, NULL }    */
 };
 
 static const
 ssl3HelloExtensionSender clientHelloSendersSSL3[SSL_MAX_EXTENSIONS] = {
     { ssl_renegotiation_info_xtn, &ssl3_SendRenegotiationInfoXtn }
     /* any extra entries will appear as { 0, NULL }    */
 };
@@ -2416,8 +2423,98 @@ ssl3_AppendPaddingExtension(sslSocket *s
         return -1;
     if (SECSuccess != ssl3_AppendHandshakeNumber(ss, paddingLen, 2))
         return -1;
     if (SECSuccess != ssl3_AppendHandshake(ss, padding, paddingLen))
         return -1;
 
     return extensionLen;
 }
+
+/* ssl3_ClientSendDraftVersionXtn sends the TLS 1.3 temporary draft
+ * version extension.
+ * TODO(ekr@rtfm.com): Remove when TLS 1.3 is published. */
+static PRInt32
+ssl3_ClientSendDraftVersionXtn(sslSocket * ss, PRBool append, PRUint32 maxBytes)
+{
+    PRInt32 extension_length;
+
+    if (ss->version != SSL_LIBRARY_VERSION_TLS_1_3) {
+        return 0;
+    }
+
+    extension_length = 6;  /* Type + length + number */
+    if (append && maxBytes >= extension_length) {
+        SECStatus rv;
+        rv = ssl3_AppendHandshakeNumber(ss, ssl_tls13_draft_version_xtn, 2);
+        if (rv != SECSuccess)
+            goto loser;
+        rv = ssl3_AppendHandshakeNumber(ss, extension_length - 4, 2);
+        if (rv != SECSuccess)
+            goto loser;
+        rv = ssl3_AppendHandshakeNumber(ss, TLS_1_3_DRAFT_VERSION, 2);
+        if (rv != SECSuccess)
+            goto loser;
+        ss->xtnData.advertised[ss->xtnData.numAdvertised++] =
+                ssl_tls13_draft_version_xtn;
+    } else if (maxBytes < extension_length) {
+        PORT_Assert(0);
+        return 0;
+    }
+
+    return extension_length;
+
+loser:
+    return -1;
+}
+
+/* ssl3_ServerHandleDraftVersionXtn handles the TLS 1.3 temporary draft
+ * version extension.
+ * TODO(ekr@rtfm.com): Remove when TLS 1.3 is published. */
+static SECStatus
+ssl3_ServerHandleDraftVersionXtn(sslSocket * ss, PRUint16 ex_type,
+                                 SECItem *data)
+{
+    PRInt32 draft_version;
+
+    /* Ignore this extension if we aren't doing TLS 1.3 */
+    if (ss->version != SSL_LIBRARY_VERSION_TLS_1_3) {
+        return SECSuccess;
+    }
+
+    if (data->len != 2)
+        goto loser;
+
+    /* Get the draft version out of the handshake */
+    draft_version = ssl3_ConsumeHandshakeNumber(ss, 2,
+                                                &data->data, &data->len);
+    if (draft_version < 0) {
+        goto loser;
+    }
+
+    /*  Keep track of negotiated extensions. */
+    ss->xtnData.negotiated[ss->xtnData.numNegotiated++] = ex_type;
+
+    /* Compare the version */
+    if (draft_version != TLS_1_3_DRAFT_VERSION) {
+        SSL_TRC(30, ("%d: SSL3[%d]: Incompatible version of TLS 1.3 (%d), "
+                     "expected %d",
+                     SSL_GETPID(), ss->fd, draft_version, TLS_1_3_DRAFT_VERSION));
+        goto loser;
+    }
+
+    return SECSuccess;
+
+loser:
+    /*
+     * Incompatible/broken TLS 1.3 implementation. Fall back to TLS 1.2.
+     * TODO(ekr@rtfm.com): It's not entirely clear it's safe to roll back
+     * here. Need to double-check.
+     * TODO(ekr@rtfm.com): Currently we fall back even on broken extensions.
+     * because SECFailure does not cause handshake failures. See bug
+     * 753136.
+     */
+    SSL_TRC(30, ("%d: SSL3[%d]: Rolling back to TLS 1.2", SSL_GETPID(), ss->fd));
+    ss->version = SSL_LIBRARY_VERSION_TLS_1_2;
+
+    return SECSuccess;
+}
+
--- a/security/nss/lib/ssl/ssl3prot.h
+++ b/security/nss/lib/ssl/ssl3prot.h
@@ -9,16 +9,21 @@
 #ifndef __ssl3proto_h_
 #define __ssl3proto_h_
 
 typedef PRUint8 SSL3Opaque;
 
 typedef PRUint16 SSL3ProtocolVersion;
 /* version numbers are defined in sslproto.h */
 
+/* The TLS 1.3 draft version. Used to avoid negotiating
+ * between incompatible pre-standard TLS 1.3 drafts.
+ * TODO(ekr@rtfm.com): Remove when TLS 1.3 is published. */
+#define TLS_1_3_DRAFT_VERSION  3
+
 typedef PRUint16 ssl3CipherSuite;
 /* The cipher suites are defined in sslproto.h */
 
 #define MAX_CERT_TYPES                  10
 #define MAX_COMPRESSION_METHODS         10
 #define MAX_MAC_LENGTH                  64
 #define MAX_PADDING_LENGTH              64
 #define MAX_KEY_LENGTH                  64
@@ -93,16 +98,17 @@ typedef enum {
     unknown_ca              = 48,
     access_denied           = 49,
     decode_error            = 50,
     decrypt_error           = 51,
     export_restriction      = 60,
     protocol_version        = 70,
     insufficient_security   = 71,
     internal_error          = 80,
+    inappropriate_fallback  = 86,	/* could also be sent for SSLv3 */
     user_canceled           = 90,
     no_renegotiation        = 100,
 
 /* Alerts for client hello extensions */
     unsupported_extension           = 110,
     certificate_unobtainable        = 111,
     unrecognized_name               = 112,
     bad_certificate_status_response = 113,
--- a/security/nss/lib/ssl/sslerr.h
+++ b/security/nss/lib/ssl/sslerr.h
@@ -191,13 +191,15 @@ SSL_ERROR_RX_UNEXPECTED_CERT_STATUS     
 
 SSL_ERROR_UNSUPPORTED_HASH_ALGORITHM    = (SSL_ERROR_BASE + 126),
 SSL_ERROR_DIGEST_FAILURE                = (SSL_ERROR_BASE + 127),
 SSL_ERROR_INCORRECT_SIGNATURE_ALGORITHM = (SSL_ERROR_BASE + 128),
 
 SSL_ERROR_NEXT_PROTOCOL_NO_CALLBACK     = (SSL_ERROR_BASE + 129),
 SSL_ERROR_NEXT_PROTOCOL_NO_PROTOCOL     = (SSL_ERROR_BASE + 130),
 
+SSL_ERROR_INAPPROPRIATE_FALLBACK_ALERT  = (SSL_ERROR_BASE + 131),
+
 SSL_ERROR_END_OF_LIST   /* let the c compiler determine the value of this. */
 } SSLErrorCodes;
 #endif /* NO_SECURITY_ERROR_ENUM */
 
 #endif /* __SSL_ERR_H_ */
--- a/security/nss/lib/ssl/sslimpl.h
+++ b/security/nss/lib/ssl/sslimpl.h
@@ -322,16 +322,17 @@ typedef struct sslOptionsStr {
     unsigned int enableRenegotiation    : 2;  /* 20-21 */
     unsigned int requireSafeNegotiation : 1;  /* 22 */
     unsigned int enableFalseStart       : 1;  /* 23 */
     unsigned int cbcRandomIV            : 1;  /* 24 */
     unsigned int enableOCSPStapling     : 1;  /* 25 */
     unsigned int enableNPN              : 1;  /* 26 */
     unsigned int enableALPN             : 1;  /* 27 */
     unsigned int reuseServerECDHEKey    : 1;  /* 28 */
+    unsigned int enableFallbackSCSV     : 1;  /* 29 */
 } sslOptions;
 
 typedef enum { sslHandshakingUndetermined = 0,
 	       sslHandshakingAsClient,
 	       sslHandshakingAsServer 
 } sslHandshakingType;
 
 typedef struct sslServerCertsStr {
@@ -1530,17 +1531,21 @@ extern PRInt32   ssl3_SendRecord(sslSock
  */
 #define SSL_LIBRARY_VERSION_NONE 0
 
 /* SSL_LIBRARY_VERSION_MAX_SUPPORTED is the maximum version that this version 
  * of libssl supports. Applications should use SSL_VersionRangeGetSupported at
  * runtime to determine which versions are supported by the version of libssl
  * in use.
  */
+#ifdef NSS_ENABLE_TLS_1_3
+#define SSL_LIBRARY_VERSION_MAX_SUPPORTED SSL_LIBRARY_VERSION_TLS_1_3
+#else
 #define SSL_LIBRARY_VERSION_MAX_SUPPORTED SSL_LIBRARY_VERSION_TLS_1_2
+#endif
 
 /* Rename this macro SSL_ALL_VERSIONS_DISABLED when SSL 2.0 is removed. */
 #define SSL3_ALL_VERSIONS_DISABLED(vrange) \
     ((vrange)->min == SSL_LIBRARY_VERSION_NONE)
 
 extern PRBool ssl3_VersionIsSupported(SSLProtocolVariant protocolVariant,
 				      SSL3ProtocolVersion version);
 
--- a/security/nss/lib/ssl/sslproto.h
+++ b/security/nss/lib/ssl/sslproto.h
@@ -11,26 +11,30 @@
 #define __sslproto_h_
 
 /* All versions less than 3_0 are treated as SSL version 2 */
 #define SSL_LIBRARY_VERSION_2                   0x0002
 #define SSL_LIBRARY_VERSION_3_0                 0x0300
 #define SSL_LIBRARY_VERSION_TLS_1_0             0x0301
 #define SSL_LIBRARY_VERSION_TLS_1_1             0x0302
 #define SSL_LIBRARY_VERSION_TLS_1_2             0x0303
+#define SSL_LIBRARY_VERSION_TLS_1_3             0x0304
+
 /* Note: this is the internal format, not the wire format */
 #define SSL_LIBRARY_VERSION_DTLS_1_0            0x0302
 #define SSL_LIBRARY_VERSION_DTLS_1_2            0x0303
+#define SSL_LIBRARY_VERSION_DTLS_1_3            0x0304
 
 /* deprecated old name */
 #define SSL_LIBRARY_VERSION_3_1_TLS SSL_LIBRARY_VERSION_TLS_1_0
 
 /* The DTLS versions used in the spec */
 #define SSL_LIBRARY_VERSION_DTLS_1_0_WIRE       ((~0x0100) & 0xffff)
 #define SSL_LIBRARY_VERSION_DTLS_1_2_WIRE       ((~0x0102) & 0xffff)
+#define SSL_LIBRARY_VERSION_DTLS_1_3_WIRE       ((~0x0103) & 0xffff)
 
 /* Header lengths of some of the messages */
 #define SSL_HL_ERROR_HBYTES                     3
 #define SSL_HL_CLIENT_HELLO_HBYTES              9
 #define SSL_HL_CLIENT_MASTER_KEY_HBYTES         10
 #define SSL_HL_CLIENT_FINISHED_HBYTES           1
 #define SSL_HL_SERVER_HELLO_HBYTES              11
 #define SSL_HL_SERVER_VERIFY_HBYTES             1
@@ -203,16 +207,21 @@
 #define TLS_DHE_DSS_WITH_AES_128_GCM_SHA256     0x00A2
 
 /* TLS "Signaling Cipher Suite Value" (SCSV). May be requested by client.
  * Must NEVER be chosen by server.  SSL 3.0 server acknowledges by sending
  * back an empty Renegotiation Info (RI) server hello extension.
  */
 #define TLS_EMPTY_RENEGOTIATION_INFO_SCSV       0x00FF
 
+/* TLS_FALLBACK_SCSV is a signaling cipher suite value that indicates that a
+ * handshake is the result of TLS version fallback.
+ */
+#define TLS_FALLBACK_SCSV                       0x5600
+
 /* Cipher Suite Values starting with 0xC000 are defined in informational
  * RFCs.
  */
 #define TLS_ECDH_ECDSA_WITH_NULL_SHA            0xC001
 #define TLS_ECDH_ECDSA_WITH_RC4_128_SHA         0xC002
 #define TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA    0xC003
 #define TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA     0xC004
 #define TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA     0xC005
--- a/security/nss/lib/ssl/sslsock.c
+++ b/security/nss/lib/ssl/sslsock.c
@@ -76,17 +76,18 @@ static sslOptions ssl_defaults = {
     PR_FALSE,   /* enableDeflate      */
     2,          /* enableRenegotiation (default: requires extension) */
     PR_FALSE,   /* requireSafeNegotiation */
     PR_FALSE,   /* enableFalseStart   */
     PR_TRUE,    /* cbcRandomIV        */
     PR_FALSE,   /* enableOCSPStapling */
     PR_TRUE,    /* enableNPN          */
     PR_FALSE,   /* enableALPN         */
-    PR_TRUE     /* reuseServerECDHEKey */
+    PR_TRUE,    /* reuseServerECDHEKey */
+    PR_FALSE    /* enableFallbackSCSV */
 };
 
 /*
  * default range of enabled SSL/TLS protocols
  */
 static SSLVersionRange versions_defaults_stream = {
     SSL_LIBRARY_VERSION_3_0,
     SSL_LIBRARY_VERSION_TLS_1_0
@@ -784,16 +785,20 @@ SSL_OptionSet(PRFileDesc *fd, PRInt32 wh
       case SSL_ENABLE_ALPN:
         ss->opt.enableALPN = on;
         break;
 
       case SSL_REUSE_SERVER_ECDHE_KEY:
         ss->opt.reuseServerECDHEKey = on;
         break;
 
+      case SSL_ENABLE_FALLBACK_SCSV:
+        ss->opt.enableFallbackSCSV = on;
+        break;
+
       default:
         PORT_SetError(SEC_ERROR_INVALID_ARGS);
         rv = SECFailure;
     }
 
     /* We can't use the macros for releasing the locks here,
      * because ss->opt.noLocks might have changed just above.
      * We must release these locks (monitors) here, if we aquired them above,
@@ -858,16 +863,17 @@ SSL_OptionGet(PRFileDesc *fd, PRInt32 wh
                                   on = ss->opt.requireSafeNegotiation; break;
     case SSL_ENABLE_FALSE_START:  on = ss->opt.enableFalseStart;   break;
     case SSL_CBC_RANDOM_IV:       on = ss->opt.cbcRandomIV;        break;
     case SSL_ENABLE_OCSP_STAPLING: on = ss->opt.enableOCSPStapling; break;
     case SSL_ENABLE_NPN:          on = ss->opt.enableNPN;          break;
     case SSL_ENABLE_ALPN:         on = ss->opt.enableALPN;         break;
     case SSL_REUSE_SERVER_ECDHE_KEY:
                                   on = ss->opt.reuseServerECDHEKey; break;
+    case SSL_ENABLE_FALLBACK_SCSV: on = ss->opt.enableFallbackSCSV; break;
 
     default:
         PORT_SetError(SEC_ERROR_INVALID_ARGS);
         rv = SECFailure;
     }
 
     ssl_ReleaseSSL3HandshakeLock(ss);
     ssl_Release1stHandshakeLock(ss);
@@ -924,16 +930,19 @@ SSL_OptionGetDefault(PRInt32 which, PRBo
     case SSL_ENABLE_OCSP_STAPLING:
        on = ssl_defaults.enableOCSPStapling;
        break;
     case SSL_ENABLE_NPN:          on = ssl_defaults.enableNPN;          break;
     case SSL_ENABLE_ALPN:         on = ssl_defaults.enableALPN;         break;
     case SSL_REUSE_SERVER_ECDHE_KEY:
        on = ssl_defaults.reuseServerECDHEKey;
        break;
+    case SSL_ENABLE_FALLBACK_SCSV:
+       on = ssl_defaults.enableFallbackSCSV;
+       break;
 
     default:
         PORT_SetError(SEC_ERROR_INVALID_ARGS);
         rv = SECFailure;
     }
 
     *pOn = on;
     return rv;
@@ -1103,16 +1112,20 @@ SSL_OptionSetDefault(PRInt32 which, PRBo
       case SSL_ENABLE_ALPN:
         ssl_defaults.enableALPN = on;
         break;
 
       case SSL_REUSE_SERVER_ECDHE_KEY:
         ssl_defaults.reuseServerECDHEKey = on;
         break;
 
+      case SSL_ENABLE_FALLBACK_SCSV:
+        ssl_defaults.enableFallbackSCSV = on;
+        break;
+
       default:
         PORT_SetError(SEC_ERROR_INVALID_ARGS);
         return SECFailure;
     }
     return SECSuccess;
 }
 
 /* function tells us if the cipher suite is one that we no longer support. */
--- a/security/nss/lib/ssl/sslt.h
+++ b/security/nss/lib/ssl/sslt.h
@@ -186,14 +186,15 @@ typedef enum {
     ssl_ec_point_formats_xtn         = 11,
 #endif
     ssl_signature_algorithms_xtn     = 13,
     ssl_use_srtp_xtn                 = 14,
     ssl_app_layer_protocol_xtn       = 16,
     ssl_padding_xtn                  = 21,
     ssl_session_ticket_xtn           = 35,
     ssl_next_proto_nego_xtn          = 13172,
-    ssl_renegotiation_info_xtn       = 0xff01	/* experimental number */
+    ssl_renegotiation_info_xtn       = 0xff01,
+    ssl_tls13_draft_version_xtn      = 0xff02   /* experimental number */
 } SSLExtensionType;
 
-#define SSL_MAX_EXTENSIONS             10 /* doesn't include ssl_padding_xtn. */
+#define SSL_MAX_EXTENSIONS             11 /* doesn't include ssl_padding_xtn. */
 
 #endif /* __sslt_h_ */
--- a/security/nss/lib/util/nssutil.h
+++ b/security/nss/lib/util/nssutil.h
@@ -14,22 +14,22 @@
 
 /*
  * NSS utilities's major version, minor version, patch level, build number,
  * and whether this is a beta release.
  *
  * The format of the version string should be
  *     "<major version>.<minor version>[.<patch level>[.<build number>]][ <Beta>]"
  */
-#define NSSUTIL_VERSION  "3.17"
+#define NSSUTIL_VERSION  "3.17.1 Beta"
 #define NSSUTIL_VMAJOR   3
 #define NSSUTIL_VMINOR   17
-#define NSSUTIL_VPATCH   0
+#define NSSUTIL_VPATCH   1
 #define NSSUTIL_VBUILD   0
-#define NSSUTIL_BETA     PR_FALSE
+#define NSSUTIL_BETA     PR_TRUE
 
 SEC_BEGIN_PROTOS
 
 /*
  * Returns a const string of the UTIL library version.
  */
 extern const char *NSSUTIL_GetVersion(void);
 
--- a/security/nss/tests/pkcs11/netscape/suites/security/ssl/sslt.c
+++ b/security/nss/tests/pkcs11/netscape/suites/security/ssl/sslt.c
@@ -1,14 +1,14 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
-#define VERION_MAJOR 1
-#define VERION_MINOR 0
+#define VERSION_MAJOR 1
+#define VERSION_MINOR 0
 #define VERSION_POINT 7
 /* NSPR header files */
 #include <prinit.h>
 #include <prprf.h>
 #include <prsystem.h>
 #include <prmem.h>
 #include <plstr.h>
 #include <prnetdb.h>
@@ -169,17 +169,17 @@ PRIntn main(PRIntn ac, char **av, char *
   int c;
   
 
   if( ac == 1 ) {
      PR_fprintf(PR_STDERR,
 "\nSSL Test Suite Version %d.%d.%d\n\
 All Rights Reserved\n\
 Usage: sslt [-c client_nickname] [-n server_nickname] [-p passwd] [-d] testid\n",
-VERION_MAJOR, VERION_MINOR, VERSION_POINT);
+VERSION_MAJOR, VERSION_MINOR, VERSION_POINT);
 
     exit(0);
   }
 
   for (c = 1; c<ac; c++) {
 	if (!PL_strcmp(av[c],"-c")) {
 	
 		  c++;