diff options
author | Adam Langley <agl@chromium.org> | 2014-01-13 19:47:44 -0800 |
---|---|---|
committer | Adam Langley <agl@chromium.org> | 2014-01-13 19:47:44 -0800 |
commit | ee4467cf05108949099bc3faad71187c7e508975 (patch) | |
tree | 0bd7ac9d897165f576b6319265fd3527986ed175 | |
parent | d7fcd4f1d234e9c3d5a54f9e0045ed39ec74617c (diff) | |
download | nss-hg-ee4467cf05108949099bc3faad71187c7e508975.tar.gz |
Bug 944157: Implement the TLS padding extension, r=briansmith, r=wtc
-rw-r--r-- | lib/ssl/ssl3con.c | 22 | ||||
-rw-r--r-- | lib/ssl/ssl3ext.c | 52 | ||||
-rw-r--r-- | lib/ssl/sslimpl.h | 7 | ||||
-rw-r--r-- | lib/ssl/sslt.h | 3 |
4 files changed, 83 insertions, 1 deletions
diff --git a/lib/ssl/ssl3con.c b/lib/ssl/ssl3con.c index a7144ea9a..4509ba581 100644 --- a/lib/ssl/ssl3con.c +++ b/lib/ssl/ssl3con.c @@ -4840,6 +4840,7 @@ ssl3_SendClientHello(sslSocket *ss, PRBool resending) int actual_count = 0; PRBool isTLS = PR_FALSE; PRInt32 total_exten_len = 0; + unsigned paddingExtensionLen; unsigned numCompressionMethods; PRInt32 flags; @@ -5113,6 +5114,20 @@ ssl3_SendClientHello(sslSocket *ss, PRBool resending) 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); } @@ -5247,6 +5262,13 @@ ssl3_SendClientHello(sslSocket *ss, PRBool resending) return SECFailure; } maxBytes -= extLen; + + extLen = ssl3_AppendPaddingExtension(ss, paddingExtensionLen, maxBytes); + if (extLen < 0) { + return SECFailure; + } + maxBytes -= extLen; + PORT_Assert(!maxBytes); } diff --git a/lib/ssl/ssl3ext.c b/lib/ssl/ssl3ext.c index da42bfd48..d75d458b6 100644 --- a/lib/ssl/ssl3ext.c +++ b/lib/ssl/ssl3ext.c @@ -2141,3 +2141,55 @@ ssl3_ClientSendSigAlgsXtn(sslSocket * ss, PRBool append, PRUint32 maxBytes) 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; +} diff --git a/lib/ssl/sslimpl.h b/lib/ssl/sslimpl.h index eaf17af3f..3750c2134 100644 --- a/lib/ssl/sslimpl.h +++ b/lib/ssl/sslimpl.h @@ -226,6 +226,13 @@ 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 *); diff --git a/lib/ssl/sslt.h b/lib/ssl/sslt.h index 6b9362934..350c1bbd7 100644 --- a/lib/ssl/sslt.h +++ b/lib/ssl/sslt.h @@ -189,9 +189,10 @@ typedef enum { ssl_use_srtp_xtn = 14, 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 9 /* doesn't include ssl_padding_xtn. */ #endif /* __sslt_h_ */ |