1diff --git a/nss/lib/ssl/ssl3con.c b/nss/lib/ssl/ssl3con.c 2index 8b8b758..882e356 100644 3--- a/nss/lib/ssl/ssl3con.c 4+++ b/nss/lib/ssl/ssl3con.c 5@@ -4975,6 +4975,7 @@ ssl3_SendClientHello(sslSocket *ss, PRBool resending) 6 PRBool isTLS = PR_FALSE; 7 PRBool requestingResume = PR_FALSE; 8 PRInt32 total_exten_len = 0; 9+ unsigned paddingExtensionLen; 10 unsigned numCompressionMethods; 11 PRInt32 flags; 12 13@@ -5241,6 +5242,20 @@ ssl3_SendClientHello(sslSocket *ss, PRBool resending) 14 length += 1 + ss->ssl3.hs.cookieLen; 15 } 16 17+ /* A padding extension may be included to ensure that the record containing 18+ * the ClientHello doesn't have a length between 256 and 511 bytes 19+ * (inclusive). Initial, ClientHello records with such lengths trigger bugs 20+ * in F5 devices. 21+ * 22+ * This is not done for DTLS nor for renegotiation. */ 23+ if (!IS_DTLS(ss) && isTLS && !ss->firstHsDone) { 24+ paddingExtensionLen = ssl3_CalculatePaddingExtensionLength(length); 25+ total_exten_len += paddingExtensionLen; 26+ length += paddingExtensionLen; 27+ } else { 28+ paddingExtensionLen = 0; 29+ } 30+ 31 rv = ssl3_AppendHandshakeHeader(ss, client_hello, length); 32 if (rv != SECSuccess) { 33 return rv; /* err set by ssl3_AppendHandshake* */ 34@@ -5360,6 +5375,13 @@ ssl3_SendClientHello(sslSocket *ss, PRBool resending) 35 return SECFailure; 36 } 37 maxBytes -= extLen; 38+ 39+ extLen = ssl3_AppendPaddingExtension(ss, paddingExtensionLen, maxBytes); 40+ if (extLen < 0) { 41+ return SECFailure; 42+ } 43+ maxBytes -= extLen; 44+ 45 PORT_Assert(!maxBytes); 46 } 47 if (ss->ssl3.hs.sendingSCSV) { 48diff --git a/nss/lib/ssl/ssl3ext.c b/nss/lib/ssl/ssl3ext.c 49index 0415770..cdebcc9 100644 50--- a/nss/lib/ssl/ssl3ext.c 51+++ b/nss/lib/ssl/ssl3ext.c 52@@ -2297,3 +2297,56 @@ ssl3_ClientSendSigAlgsXtn(sslSocket * ss, PRBool append, PRUint32 maxBytes) 53 loser: 54 return -1; 55 } 56+ 57+unsigned int 58+ssl3_CalculatePaddingExtensionLength(unsigned int clientHelloLength) 59+{ 60+ unsigned int recordLength = 1 /* handshake message type */ + 61+ 3 /* handshake message length */ + 62+ clientHelloLength; 63+ unsigned int extensionLength; 64+ 65+ if (recordLength < 256 || recordLength >= 512) { 66+ return 0; 67+ } 68+ 69+ extensionLength = 512 - recordLength; 70+ /* Extensions take at least four bytes to encode. */ 71+ if (extensionLength < 4) { 72+ extensionLength = 4; 73+ } 74+ 75+ return extensionLength; 76+} 77+ 78+/* ssl3_AppendPaddingExtension possibly adds an extension which ensures that a 79+ * ClientHello record is either < 256 bytes or is >= 512 bytes. This ensures 80+ * that we don't trigger bugs in F5 products. */ 81+PRInt32 82+ssl3_AppendPaddingExtension(sslSocket *ss, unsigned int extensionLen, 83+ PRUint32 maxBytes) 84+{ 85+ unsigned int paddingLen = extensionLen - 4; 86+ unsigned char padding[256]; 87+ 88+ if (extensionLen == 0) { 89+ return 0; 90+ } 91+ 92+ if (extensionLen < 4 || 93+ extensionLen > maxBytes || 94+ paddingLen > sizeof(padding)) { 95+ PORT_Assert(0); 96+ return -1; 97+ } 98+ 99+ if (SECSuccess != ssl3_AppendHandshakeNumber(ss, ssl_padding_xtn, 2)) 100+ return -1; 101+ if (SECSuccess != ssl3_AppendHandshakeNumber(ss, paddingLen, 2)) 102+ return -1; 103+ memset(padding, 0, paddingLen); 104+ if (SECSuccess != ssl3_AppendHandshake(ss, padding, paddingLen)) 105+ return -1; 106+ 107+ return extensionLen; 108+} 109diff --git a/nss/lib/ssl/sslimpl.h b/nss/lib/ssl/sslimpl.h 110index 614eed1..9c789bf 100644 111--- a/nss/lib/ssl/sslimpl.h 112+++ b/nss/lib/ssl/sslimpl.h 113@@ -237,6 +237,13 @@ extern PRInt32 114 ssl3_CallHelloExtensionSenders(sslSocket *ss, PRBool append, PRUint32 maxBytes, 115 const ssl3HelloExtensionSender *sender); 116 117+extern unsigned int 118+ssl3_CalculatePaddingExtensionLength(unsigned int clientHelloLength); 119+ 120+extern PRInt32 121+ssl3_AppendPaddingExtension(sslSocket *ss, unsigned int extensionLen, 122+ PRUint32 maxBytes); 123+ 124 /* Socket ops */ 125 struct sslSocketOpsStr { 126 int (*connect) (sslSocket *, const PRNetAddr *); 127diff --git a/nss/lib/ssl/sslt.h b/nss/lib/ssl/sslt.h 128index a8007d8..e4d188f 100644 129--- a/nss/lib/ssl/sslt.h 130+++ b/nss/lib/ssl/sslt.h 131@@ -205,9 +205,10 @@ typedef enum { 132 ssl_session_ticket_xtn = 35, 133 ssl_next_proto_nego_xtn = 13172, 134 ssl_channel_id_xtn = 30031, 135+ ssl_padding_xtn = 35655, 136 ssl_renegotiation_info_xtn = 0xff01 /* experimental number */ 137 } SSLExtensionType; 138 139-#define SSL_MAX_EXTENSIONS 11 140+#define SSL_MAX_EXTENSIONS 11 /* doesn't include ssl_padding_xtn. */ 141 142 #endif /* __sslt_h_ */ 143