Bug 958916: Update NSS to NSS 3.15.5 beta 2 (NSS_3_15_5_BETA2) plus private patch for bug 950129, CLOBBER, r=me
authorBrian Smith <brian@briansmith.org>
Thu, 16 Jan 2014 13:18:55 -0800
changeset 163884 cbed774ff9c0050dcc1eecded386bd95538abad4
parent 163857 c040b200b336b3054f221bbda150b4c0d7321fc6
child 163885 6a0e66cae4f8644a4e679069dc056cdb833279a4
push idunknown
push userunknown
push dateunknown
reviewersme
bugs958916, 950129
milestone29.0a1
Bug 958916: Update NSS to NSS 3.15.5 beta 2 (NSS_3_15_5_BETA2) plus private patch for bug 950129, CLOBBER, r=me
CLOBBER
security/nss/TAG-INFO
security/nss/coreconf/WIN32.mk
security/nss/coreconf/coreconf.dep
security/nss/lib/libpkix/pkix_pl_nss/module/pkix_pl_aiamgr.c
security/nss/lib/ssl/ssl.h
security/nss/lib/ssl/ssl3con.c
security/nss/lib/ssl/ssl3ext.c
security/nss/lib/ssl/sslimpl.h
security/nss/lib/ssl/sslsock.c
security/nss/lib/ssl/sslt.h
--- a/CLOBBER
+++ b/CLOBBER
@@ -17,9 +17,9 @@
 #
 # Modifying this file will now automatically clobber the buildbot machines \o/
 #
 
 # Are you updating CLOBBER because you think it's needed for your WebIDL
 # changes to stick? As of bug 928195, this shouldn't be necessary! Please
 # don't change CLOBBER for WebIDL changes any more.
 
-Bug 897735 requires a clobber due to mass mochitest bustage otherwise
+Updates to NSS seem to require a clobber due bug 959928.
--- a/security/nss/TAG-INFO
+++ b/security/nss/TAG-INFO
@@ -1,1 +1,1 @@
-NSS_3_15_5_BETA1
+NSS_3_15_5_BETA2
--- a/security/nss/coreconf/WIN32.mk
+++ b/security/nss/coreconf/WIN32.mk
@@ -36,17 +36,17 @@ else
 	# Change the dots to spaces.
 	_CC_VERSION_WORDS := $(subst ., ,$(CC_VERSION))
 	_CC_VMAJOR  := $(word 1,$(_CC_VERSION_WORDS))
 	_CC_VMINOR  := $(word 2,$(_CC_VERSION_WORDS))
 	_CC_RELEASE := $(word 3,$(_CC_VERSION_WORDS))
 	_CC_BUILD   := $(word 4,$(_CC_VERSION_WORDS))
 	_MSC_VER     = $(_CC_VMAJOR)$(_CC_VMINOR)
 	_MSC_VER_6   = 1200
-	_MSC_VER_GTE18 := $(shell expr $(_MSC_VER) \>= 1800)
+	_MSC_VER_GE_18 := $(shell expr $(_MSC_VER) \>= 1800)
 	ifeq ($(_CC_VMAJOR),14)
 	    # -DYNAMICBASE is only supported on VC8SP1 or newer,
 	    # so be very specific here!
 	    # VC8 is 14.00.50727.42, VC8SP1 is 14.00.50727.762
 	    ifeq ($(_CC_RELEASE).$(_CC_BUILD),50727.42)
 		USE_DYNAMICBASE =
 	    else
 	    ifeq ($(_CC_RELEASE).$(_CC_BUILD),50727.762)
@@ -168,19 +168,19 @@ endif
 	LDFLAGS    += /FIXED:NO
     endif
 ifneq ($(_MSC_VER),$(_MSC_VER_6))
     # Convert certain deadly warnings to errors (see list at end of file)
     OS_CFLAGS += -we4002 -we4003 -we4004 -we4006 -we4009 -we4013 \
      -we4015 -we4028 -we4033 -we4035 -we4045 -we4047 -we4053 -we4054 -we4063 \
      -we4064 -we4078 -we4087 -we4090 -we4098 -we4390 -we4551 -we4553 -we4715
 
-	ifeq ($(_MSC_VER_GTE18),1)
-		OS_CFLAGS += -FS
-	endif
+    ifeq ($(_MSC_VER_GE_18),1)
+	OS_CFLAGS += -FS
+    endif
 endif # !MSVC6
 endif # NS_USE_GCC
 
 ifdef USE_64
 DEFINES += -DWIN64
 else
 DEFINES += -DWIN32
 endif
--- a/security/nss/coreconf/coreconf.dep
+++ b/security/nss/coreconf/coreconf.dep
@@ -5,8 +5,9 @@
 
 /*
  * 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/libpkix/pkix_pl_nss/module/pkix_pl_aiamgr.c
+++ b/security/nss/lib/libpkix/pkix_pl_nss/module/pkix_pl_aiamgr.c
@@ -126,16 +126,18 @@ pkix_pl_AIAMgr_RegisterSelf(void *plCont
  *  collection, and then stored at "pClient".
  *
  * PARAMETERS:
  *  "aiaMgr"
  *      The AIAMgr whose LDAPClient connected are to be managed. Must be
  *      non-NULL.
  *  "domainName"
  *      Address of a string pointing to a server name. Must be non-NULL.
+ *      An empty string (which means no <host> is given in the LDAP URL) is
+ *      not supported.
  *  "pClient"
  *      Address at which the returned LDAPClient is stored. Must be non-NULL.
  *  "plContext"
  *      Platform-specific context pointer.
  * THREAD SAFETY:
  *  Thread Safe (see Thread Safety Definitions in Programmer's Guide)
  * RETURNS:
  *  Returns NULL if the function succeeds.
@@ -150,16 +152,27 @@ pkix_pl_AiaMgr_FindLDAPClient(
         void *plContext)
 {
         PKIX_PL_String *domainString = NULL;
         PKIX_PL_LdapDefaultClient *client = NULL;
 
         PKIX_ENTER(AIAMGR, "pkix_pl_AiaMgr_FindLDAPClient");
         PKIX_NULLCHECK_THREE(aiaMgr, domainName, pClient);
 
+        /*
+         * An LDAP URL may not have a <host> part, for example,
+         *     ldap:///o=University%20of%20Michigan,c=US
+         * PKIX_PL_LdapDefaultClient doesn't know how to discover the default
+         * LDAP server, so we don't support this kind of LDAP URL.
+         */
+        if (*domainName == '\0') {
+                /* Simulate a PKIX_PL_LdapDefaultClient_CreateByName failure. */
+                PKIX_ERROR(PKIX_LDAPDEFAULTCLIENTCREATEBYNAMEFAILED);
+        }
+
         /* create PKIX_PL_String from domain name */
         PKIX_CHECK(PKIX_PL_String_Create
                 (PKIX_ESCASCII, domainName, 0, &domainString, plContext),
                 PKIX_STRINGCREATEFAILED);
 
         /* Is this domainName already in cache? */
         PKIX_CHECK(PKIX_PL_HashTable_Lookup
                 (aiaConnectionCache,
--- a/security/nss/lib/ssl/ssl.h
+++ b/security/nss/lib/ssl/ssl.h
@@ -157,16 +157,35 @@ SSL_IMPORT PRFileDesc *DTLS_ImportFD(PRF
  * application_data records. Also, we only split application_data records and
  * not other types of records, because some implementations will not accept
  * fragmented records of some other types (e.g. some versions of NSS do not
  * accept fragmented alerts).
  */
 #define SSL_CBC_RANDOM_IV 23
 #define SSL_ENABLE_OCSP_STAPLING       24 /* Request OCSP stapling (client) */
 
+/* SSL_ENABLE_NPN controls whether the NPN extension is enabled for the initial
+ * handshake when protocol negotiation is used. SSL_SetNextProtoCallback
+ * or SSL_SetNextProtoNego must be used to control the protocol negotiation;
+ * otherwise, the NPN extension will not be negotiated. SSL_ENABLE_NPN is
+ * currently enabled by default but this may change in future versions.
+ */
+#define SSL_ENABLE_NPN 25
+
+/* SSL_ENABLE_ALPN controls whether the ALPN extension is enabled for the
+ * initial handshake when protocol negotiation is used. SSL_SetNextProtoNego
+ * (not SSL_SetNextProtoCallback) must be used to control the protocol
+ * negotiation; otherwise, the ALPN extension will not be negotiated. ALPN is
+ * not negotiated for renegotiation handshakes, even though the ALPN
+ * specification defines a way to use ALPN during renegotiations.
+ * SSL_ENABLE_ALPN is currently disabled by default, but this may change in
+ * future versions.
+ */
+#define SSL_ENABLE_ALPN 26
+
 #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);
@@ -201,26 +220,37 @@ SSL_IMPORT SECStatus SSL_SetNextProtoCal
                                               void *arg);
 
 /* SSL_SetNextProtoNego can be used as an alternative to
  * SSL_SetNextProtoCallback. It also causes a client to advertise NPN and
  * installs a default callback function which selects the first supported
  * protocol in server-preference order. If no matching protocol is found it
  * selects the first supported protocol.
  *
+ * Using this function also allows the client to transparently support ALPN.
+ * The same set of protocols will be advertised via ALPN and, if the server
+ * uses ALPN to select a protocol, SSL_GetNextProto will return
+ * SSL_NEXT_PROTO_SELECTED as the state.
+ *
+ * Since NPN uses the first protocol as the fallback protocol, when sending an
+ * ALPN extension, the first protocol is moved to the end of the list. This
+ * indicates that the fallback protocol is the least preferred. The other
+ * protocols should be in preference order.
+ *
  * The supported protocols are specified in |data| in wire-format (8-bit
  * length-prefixed). For example: "\010http/1.1\006spdy/2". */
 SSL_IMPORT SECStatus SSL_SetNextProtoNego(PRFileDesc *fd,
 					  const unsigned char *data,
 					  unsigned int length);
 
 typedef enum SSLNextProtoState { 
   SSL_NEXT_PROTO_NO_SUPPORT = 0, /* No peer support                */
   SSL_NEXT_PROTO_NEGOTIATED = 1, /* Mutual agreement               */
-  SSL_NEXT_PROTO_NO_OVERLAP = 2  /* No protocol overlap found      */
+  SSL_NEXT_PROTO_NO_OVERLAP = 2, /* No protocol overlap found      */
+  SSL_NEXT_PROTO_SELECTED   = 3  /* Server selected proto (ALPN)   */
 } SSLNextProtoState;
 
 /* SSL_GetNextProto can be used in the HandshakeCallback or any time after
  * a handshake to retrieve the result of the Next Protocol negotiation.
  *
  * The length of the negotiated protocol, if any, is written into *bufLen.
  * If the negotiated protocol is longer than bufLenMax, then SECFailure is
  * returned. Otherwise, the negotiated protocol, if any, is written into buf,
--- a/security/nss/lib/ssl/ssl3con.c
+++ b/security/nss/lib/ssl/ssl3con.c
@@ -4835,16 +4835,17 @@ ssl3_SendClientHello(sslSocket *ss, PRBo
     ssl3CipherSpec * cwSpec;
     SECStatus        rv;
     int              i;
     int              length;
     int              num_suites;
     int              actual_count = 0;
     PRBool           isTLS = 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));
 
     PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss) );
     PORT_Assert( ss->opt.noLocks || ssl_HaveXmitBufLock(ss) );
@@ -5108,16 +5109,30 @@ ssl3_SendClientHello(sslSocket *ss, PRBo
     length = sizeof(SSL3ProtocolVersion) + SSL3_RANDOM_LENGTH +
 	1 + ((sid == NULL) ? 0 : sid->u.ssl3.sessionIDLength) +
 	2 + num_suites*sizeof(ssl3CipherSuite) +
 	1 + numCompressionMethods + total_exten_len;
     if (IS_DTLS(ss)) {
 	length += 1 + ss->ssl3.hs.cookieLen;
     }
 
+    /* A padding extension may be included to ensure that the record containing
+     * the ClientHello doesn't have a length between 256 and 511 bytes
+     * (inclusive). Initial, ClientHello records with such lengths trigger bugs
+     * in F5 devices.
+     *
+     * This is not done for DTLS nor for renegotiation. */
+    if (!IS_DTLS(ss) && isTLS && !ss->firstHsDone) {
+        paddingExtensionLen = ssl3_CalculatePaddingExtensionLength(length);
+        total_exten_len += paddingExtensionLen;
+        length += paddingExtensionLen;
+    } else {
+        paddingExtensionLen = 0;
+    }
+
     rv = ssl3_AppendHandshakeHeader(ss, client_hello, length);
     if (rv != SECSuccess) {
 	if (sid->u.ssl3.lock) { PR_RWLock_Unlock(sid->u.ssl3.lock); }
 	return rv;	/* err set by ssl3_AppendHandshake* */
     }
 
     if (ss->firstHsDone) {
 	/* The client hello version must stay unchanged to work around
@@ -5242,16 +5257,24 @@ ssl3_SendClientHello(sslSocket *ss, PRBo
 	}
 
 	extLen = ssl3_CallHelloExtensionSenders(ss, PR_TRUE, maxBytes, NULL);
 	if (extLen < 0) {
 	    if (sid->u.ssl3.lock) { PR_RWLock_Unlock(sid->u.ssl3.lock); }
 	    return SECFailure;
 	}
 	maxBytes -= extLen;
+
+	extLen = ssl3_AppendPaddingExtension(ss, paddingExtensionLen, maxBytes);
+	if (extLen < 0) {
+	    if (sid->u.ssl3.lock) { PR_RWLock_Unlock(sid->u.ssl3.lock); }
+	    return SECFailure;
+	}
+	maxBytes -= extLen;
+
 	PORT_Assert(!maxBytes);
     } 
 
     if (sid->u.ssl3.lock) {
         PR_RWLock_Unlock(sid->u.ssl3.lock);
     }
 
     if (ss->xtnData.sentSessionTicketInClientHello) {
@@ -10157,18 +10180,20 @@ ssl3_TLSPRFWithMasterSecret(ssl3CipherSp
  */
 static SECStatus
 ssl3_SendNextProto(sslSocket *ss)
 {
     SECStatus rv;
     int padding_len;
     static const unsigned char padding[32] = {0};
 
-    if (ss->ssl3.nextProto.len == 0)
+    if (ss->ssl3.nextProto.len == 0 ||
+	ss->ssl3.nextProtoState == SSL_NEXT_PROTO_SELECTED) {
 	return SECSuccess;
+    }
 
     PORT_Assert( ss->opt.noLocks || ssl_HaveXmitBufLock(ss));
     PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss));
 
     padding_len = 32 - ((ss->ssl3.nextProto.len + 2) % 32);
 
     rv = ssl3_AppendHandshakeHeader(ss, next_proto, ss->ssl3.nextProto.len +
 						    2 + padding_len);
--- a/security/nss/lib/ssl/ssl3ext.c
+++ b/security/nss/lib/ssl/ssl3ext.c
@@ -47,18 +47,22 @@ static SECStatus ssl3_GetSessionTicketKe
     PRUint32 *mac_key_length);
 #endif
 static PRInt32 ssl3_SendRenegotiationInfoXtn(sslSocket * ss,
     PRBool append, PRUint32 maxBytes);
 static SECStatus ssl3_HandleRenegotiationInfoXtn(sslSocket *ss, 
     PRUint16 ex_type, SECItem *data);
 static SECStatus ssl3_ClientHandleNextProtoNegoXtn(sslSocket *ss,
 			PRUint16 ex_type, SECItem *data);
+static SECStatus ssl3_ClientHandleAppProtoXtn(sslSocket *ss,
+			PRUint16 ex_type, SECItem *data);
 static SECStatus ssl3_ServerHandleNextProtoNegoXtn(sslSocket *ss,
 			PRUint16 ex_type, SECItem *data);
+static PRInt32 ssl3_ClientSendAppProtoXtn(sslSocket *ss, PRBool append,
+					  PRUint32 maxBytes);
 static PRInt32 ssl3_ClientSendNextProtoNegoXtn(sslSocket *ss, PRBool append,
 					       PRUint32 maxBytes);
 static PRInt32 ssl3_SendUseSRTPXtn(sslSocket *ss, PRBool append,
     PRUint32 maxBytes);
 static SECStatus ssl3_HandleUseSRTPXtn(sslSocket * ss, PRUint16 ex_type,
     SECItem *data);
 static SECStatus ssl3_ServerSendStatusRequestXtn(sslSocket * ss,
     PRBool append, PRUint32 maxBytes);
@@ -242,16 +246,17 @@ static const ssl3HelloExtensionHandler c
 /* 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 */
     { ssl_session_ticket_xtn,     &ssl3_ClientHandleSessionTicketXtn },
     { ssl_renegotiation_info_xtn, &ssl3_HandleRenegotiationInfoXtn },
     { ssl_next_proto_nego_xtn,    &ssl3_ClientHandleNextProtoNegoXtn },
+    { ssl_app_layer_protocol_xtn, &ssl3_ClientHandleAppProtoXtn },
     { ssl_use_srtp_xtn,           &ssl3_HandleUseSRTPXtn },
     { ssl_cert_status_xtn,        &ssl3_ClientHandleStatusRequestXtn },
     { -1, NULL }
 };
 
 static const ssl3HelloExtensionHandler serverHelloHandlersSSL3[] = {
     { ssl_renegotiation_info_xtn, &ssl3_HandleRenegotiationInfoXtn },
     { -1, NULL }
@@ -268,16 +273,17 @@ ssl3HelloExtensionSender clientHelloSend
     { ssl_server_name_xtn,        &ssl3_SendServerNameXtn        },
     { ssl_renegotiation_info_xtn, &ssl3_SendRenegotiationInfoXtn },
 #ifdef NSS_ENABLE_ECC
     { 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 }
     /* any extra entries will appear as { 0, NULL }    */
 };
 
 static const 
 ssl3HelloExtensionSender clientHelloSendersSSL3[SSL_MAX_EXTENSIONS] = {
@@ -603,16 +609,26 @@ ssl3_ClientHandleNextProtoNegoXtn(sslSoc
 				  SECItem *data)
 {
     SECStatus rv;
     unsigned char resultBuffer[255];
     SECItem result = { siBuffer, resultBuffer, 0 };
 
     PORT_Assert(!ss->firstHsDone);
 
+    if (ssl3_ExtensionNegotiated(ss, ssl_app_layer_protocol_xtn)) {
+	/* If the server negotiated ALPN then it has already told us what protocol
+	 * to use, so it doesn't make sense for us to try to negotiate a different
+	 * one by sending the NPN handshake message. However, if we've negotiated
+	 * NPN then we're required to send the NPN handshake message. Thus, these
+	 * two extensions cannot both be negotiated on the same connection. */
+	PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
+	return SECFailure;
+    }
+
     rv = ssl3_ValidateNextProtoNego(data->data, data->len);
     if (rv != SECSuccess)
 	return rv;
 
     /* ss->nextProtoCallback cannot normally be NULL if we negotiated the
      * extension. However, It is possible that an application erroneously
      * cleared the callback between the time we sent the ClientHello and now.
      */
@@ -636,24 +652,61 @@ ssl3_ClientHandleNextProtoNegoXtn(sslSoc
     }
 
     ss->xtnData.negotiated[ss->xtnData.numNegotiated++] = ex_type;
 
     SECITEM_FreeItem(&ss->ssl3.nextProto, PR_FALSE);
     return SECITEM_CopyItem(NULL, &ss->ssl3.nextProto, &result);
 }
 
+static SECStatus
+ssl3_ClientHandleAppProtoXtn(sslSocket *ss, PRUint16 ex_type, SECItem *data)
+{
+    const unsigned char* d = data->data;
+    PRUint16 name_list_len;
+    SECItem protocol_name;
+
+    if (ssl3_ExtensionNegotiated(ss, ssl_next_proto_nego_xtn)) {
+	PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
+	return SECFailure;
+    }
+
+    /* The extension data from the server has the following format:
+     *   uint16 name_list_len;
+     *   uint8 len;
+     *   uint8 protocol_name[len]; */
+    if (data->len < 4 || data->len > 2 + 1 + 255) {
+	PORT_SetError(SSL_ERROR_NEXT_PROTOCOL_DATA_INVALID);
+	return SECFailure;
+    }
+
+    name_list_len = ((PRUint16) d[0]) << 8 |
+	            ((PRUint16) d[1]);
+    if (name_list_len != data->len - 2 || d[2] != data->len - 3) {
+	PORT_SetError(SSL_ERROR_NEXT_PROTOCOL_DATA_INVALID);
+	return SECFailure;
+    }
+
+    protocol_name.data = data->data + 3;
+    protocol_name.len = data->len - 3;
+
+    SECITEM_FreeItem(&ss->ssl3.nextProto, PR_FALSE);
+    ss->ssl3.nextProtoState = SSL_NEXT_PROTO_SELECTED;
+    ss->xtnData.negotiated[ss->xtnData.numNegotiated++] = ex_type;
+    return SECITEM_CopyItem(NULL, &ss->ssl3.nextProto, &protocol_name);
+}
+
 static PRInt32
 ssl3_ClientSendNextProtoNegoXtn(sslSocket * ss, PRBool append,
 				PRUint32 maxBytes)
 {
     PRInt32 extension_length;
 
     /* Renegotiations do not send this extension. */
-    if (!ss->nextProtoCallback || ss->firstHsDone) {
+    if (!ss->opt.enableNPN || !ss->nextProtoCallback || ss->firstHsDone) {
 	return 0;
     }
 
     extension_length = 4;
 
     if (append && maxBytes >= extension_length) {
 	SECStatus rv;
 	rv = ssl3_AppendHandshakeNumber(ss, ssl_next_proto_nego_xtn, 2);
@@ -669,16 +722,84 @@ ssl3_ClientSendNextProtoNegoXtn(sslSocke
     }
 
     return extension_length;
 
 loser:
     return -1;
 }
 
+static PRInt32
+ssl3_ClientSendAppProtoXtn(sslSocket * ss, PRBool append, PRUint32 maxBytes)
+{
+    PRInt32 extension_length;
+    unsigned char *alpn_protos = NULL;
+
+    /* Renegotiations do not send this extension. */
+    if (!ss->opt.enableALPN || !ss->opt.nextProtoNego.data || ss->firstHsDone) {
+	return 0;
+    }
+
+    extension_length = 2 /* extension type */ + 2 /* extension length */ +
+		       2 /* protocol name list length */ +
+		       ss->opt.nextProtoNego.len;
+
+    if (append && maxBytes >= extension_length) {
+	/* NPN requires that the client's fallback protocol is first in the
+	 * list. However, ALPN sends protocols in preference order. So we
+	 * allocate a buffer and move the first protocol to the end of the
+	 * list. */
+	SECStatus rv;
+	const unsigned int len = ss->opt.nextProtoNego.len;
+
+	alpn_protos = PORT_Alloc(len);
+	if (alpn_protos == NULL) {
+	    return SECFailure;
+	}
+	if (len > 0) {
+	    /* Each protocol string is prefixed with a single byte length. */
+	    unsigned int i = ss->opt.nextProtoNego.data[0] + 1;
+	    if (i <= len) {
+		memcpy(alpn_protos, &ss->opt.nextProtoNego.data[i], len - i);
+		memcpy(alpn_protos + len - i, ss->opt.nextProtoNego.data, i);
+	    } else {
+		/* This seems to be invalid data so we'll send as-is. */
+		memcpy(alpn_protos, ss->opt.nextProtoNego.data, len);
+	    }
+	}
+
+	rv = ssl3_AppendHandshakeNumber(ss, ssl_app_layer_protocol_xtn, 2);
+	if (rv != SECSuccess) {
+	    goto loser;
+	}
+	rv = ssl3_AppendHandshakeNumber(ss, extension_length - 4, 2);
+	if (rv != SECSuccess) {
+	    goto loser;
+	}
+	rv = ssl3_AppendHandshakeVariable(ss, alpn_protos, len, 2);
+	PORT_Free(alpn_protos);
+	alpn_protos = NULL;
+	if (rv != SECSuccess) {
+	    goto loser;
+	}
+	ss->xtnData.advertised[ss->xtnData.numAdvertised++] =
+		ssl_app_layer_protocol_xtn;
+    } else if (maxBytes < extension_length) {
+	return 0;
+    }
+
+    return extension_length;
+
+loser:
+    if (alpn_protos) {
+	PORT_Free(alpn_protos);
+    }
+    return -1;
+}
+
 static SECStatus
 ssl3_ClientHandleStatusRequestXtn(sslSocket *ss, PRUint16 ex_type,
                                  SECItem *data)
 {
     /* The echoed extension must be empty. */
     if (data->len != 0)
        return SECFailure;
 
@@ -2136,8 +2257,60 @@ ssl3_ClientSendSigAlgsXtn(sslSocket * ss
 	return 0;
     }
 
     return extension_length;
 
 loser:
     return -1;
 }
+
+unsigned int
+ssl3_CalculatePaddingExtensionLength(unsigned int clientHelloLength)
+{
+    unsigned int recordLength = 1 /* handshake message type */ +
+				3 /* handshake message length */ +
+				clientHelloLength;
+    unsigned int extensionLength;
+
+    if (recordLength < 256 || recordLength >= 512) {
+	return 0;
+    }
+
+    extensionLength = 512 - recordLength;
+    /* Extensions take at least four bytes to encode. */
+    if (extensionLength < 4) {
+	extensionLength = 4;
+    }
+
+    return extensionLength;
+}
+
+/* ssl3_AppendPaddingExtension possibly adds an extension which ensures that a
+ * ClientHello record is either < 256 bytes or is >= 512 bytes. This ensures
+ * that we don't trigger bugs in F5 products. */
+PRInt32
+ssl3_AppendPaddingExtension(sslSocket *ss, unsigned int extensionLen,
+			    PRUint32 maxBytes)
+{
+    unsigned int paddingLen = extensionLen - 4;
+    static unsigned char padding[256];
+
+    if (extensionLen == 0) {
+	return 0;
+    }
+
+    if (extensionLen < 4 ||
+	extensionLen > maxBytes ||
+	paddingLen > sizeof(padding)) {
+	PORT_Assert(0);
+	return -1;
+    }
+
+    if (SECSuccess != ssl3_AppendHandshakeNumber(ss, ssl_padding_xtn, 2))
+	return -1;
+    if (SECSuccess != ssl3_AppendHandshakeNumber(ss, paddingLen, 2))
+	return -1;
+    if (SECSuccess != ssl3_AppendHandshake(ss, padding, paddingLen))
+	return -1;
+
+    return extensionLen;
+}
--- a/security/nss/lib/ssl/sslimpl.h
+++ b/security/nss/lib/ssl/sslimpl.h
@@ -221,16 +221,23 @@ typedef struct {
 extern SECStatus 
 ssl3_RegisterServerHelloExtensionSender(sslSocket *ss, PRUint16 ex_type,
 				        ssl3HelloExtensionSenderFunc cb);
 
 extern PRInt32
 ssl3_CallHelloExtensionSenders(sslSocket *ss, PRBool append, PRUint32 maxBytes,
                                const ssl3HelloExtensionSender *sender);
 
+extern unsigned int
+ssl3_CalculatePaddingExtensionLength(unsigned int clientHelloLength);
+
+extern PRInt32
+ssl3_AppendPaddingExtension(sslSocket *ss, unsigned int extensionLen,
+			    PRUint32 maxBytes);
+
 /* Socket ops */
 struct sslSocketOpsStr {
     int         (*connect) (sslSocket *, const PRNetAddr *);
     PRFileDesc *(*accept)  (sslSocket *, PRNetAddr *);
     int         (*bind)    (sslSocket *, const PRNetAddr *);
     int         (*listen)  (sslSocket *, int);
     int         (*shutdown)(sslSocket *, int);
     int         (*close)   (sslSocket *);
@@ -312,16 +319,18 @@ typedef struct sslOptionsStr {
     unsigned int noLocks                : 1;  /* 17 */
     unsigned int enableSessionTickets   : 1;  /* 18 */
     unsigned int enableDeflate          : 1;  /* 19 */
     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 */
 } sslOptions;
 
 typedef enum { sslHandshakingUndetermined = 0,
 	       sslHandshakingAsClient,
 	       sslHandshakingAsServer 
 } sslHandshakingType;
 
 typedef struct sslServerCertsStr {
--- a/security/nss/lib/ssl/sslsock.c
+++ b/security/nss/lib/ssl/sslsock.c
@@ -73,17 +73,19 @@ static sslOptions ssl_defaults = {
     PR_FALSE,   /* bypassPKCS11       */
     PR_FALSE,   /* noLocks            */
     PR_FALSE,   /* enableSessionTickets */
     PR_FALSE,   /* enableDeflate      */
     2,          /* enableRenegotiation (default: requires extension) */
     PR_FALSE,   /* requireSafeNegotiation */
     PR_FALSE,   /* enableFalseStart   */
     PR_TRUE,    /* cbcRandomIV        */
-    PR_FALSE    /* enableOCSPStapling */
+    PR_FALSE,   /* enableOCSPStapling */
+    PR_TRUE,    /* enableNPN          */
+    PR_FALSE    /* enableALPN         */
 };
 
 /*
  * default range of enabled SSL/TLS protocols
  */
 static SSLVersionRange versions_defaults_stream = {
     SSL_LIBRARY_VERSION_3_0,
     SSL_LIBRARY_VERSION_TLS_1_0
@@ -759,16 +761,24 @@ SSL_OptionSet(PRFileDesc *fd, PRInt32 wh
       case SSL_CBC_RANDOM_IV:
 	ss->opt.cbcRandomIV = on;
 	break;
 
       case SSL_ENABLE_OCSP_STAPLING:
        ss->opt.enableOCSPStapling = on;
        break;
 
+      case SSL_ENABLE_NPN:
+	ss->opt.enableNPN = on;
+	break;
+
+      case SSL_ENABLE_ALPN:
+	ss->opt.enableALPN = 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,
@@ -829,16 +839,18 @@ SSL_OptionGet(PRFileDesc *fd, PRInt32 wh
     case SSL_ENABLE_DEFLATE:      on = ss->opt.enableDeflate;      break;
     case SSL_ENABLE_RENEGOTIATION:     
                                   on = ss->opt.enableRenegotiation; break;
     case SSL_REQUIRE_SAFE_NEGOTIATION: 
                                   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;
 
     default:
 	PORT_SetError(SEC_ERROR_INVALID_ARGS);
 	rv = SECFailure;
     }
 
     ssl_ReleaseSSL3HandshakeLock(ss);
     ssl_Release1stHandshakeLock(ss);
@@ -890,16 +902,18 @@ SSL_OptionGetDefault(PRInt32 which, PRBo
     case SSL_REQUIRE_SAFE_NEGOTIATION: 
                                   on = ssl_defaults.requireSafeNegotiation; 
 				  break;
     case SSL_ENABLE_FALSE_START:  on = ssl_defaults.enableFalseStart;   break;
     case SSL_CBC_RANDOM_IV:       on = ssl_defaults.cbcRandomIV;        break;
     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;
 
     default:
 	PORT_SetError(SEC_ERROR_INVALID_ARGS);
 	rv = SECFailure;
     }
 
     *pOn = on;
     return rv;
@@ -1057,16 +1071,24 @@ SSL_OptionSetDefault(PRInt32 which, PRBo
       case SSL_CBC_RANDOM_IV:
 	ssl_defaults.cbcRandomIV = on;
 	break;
 
       case SSL_ENABLE_OCSP_STAPLING:
        ssl_defaults.enableOCSPStapling = on;
        break;
 
+      case SSL_ENABLE_NPN:
+	ssl_defaults.enableNPN = on;
+	break;
+
+      case SSL_ENABLE_ALPN:
+	ssl_defaults.enableALPN = 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
@@ -182,16 +182,18 @@ typedef enum {
     ssl_server_name_xtn              = 0,
     ssl_cert_status_xtn              = 5,
 #ifdef NSS_ENABLE_ECC
     ssl_elliptic_curves_xtn          = 10,
     ssl_ec_point_formats_xtn         = 11,
 #endif
     ssl_signature_algorithms_xtn     = 13,
     ssl_use_srtp_xtn                 = 14,
+    ssl_app_layer_protocol_xtn       = 16,
     ssl_session_ticket_xtn           = 35,
     ssl_next_proto_nego_xtn          = 13172,
+    ssl_padding_xtn                  = 35655,
     ssl_renegotiation_info_xtn       = 0xff01	/* experimental number */
 } SSLExtensionType;
 
-#define SSL_MAX_EXTENSIONS             9
+#define SSL_MAX_EXTENSIONS             10 /* doesn't include ssl_padding_xtn. */
 
 #endif /* __sslt_h_ */