| OLD | NEW |
| (Empty) | |
| 1 Index: net/third_party/nss/ssl/sslimpl.h |
| 2 =================================================================== |
| 3 --- net/third_party/nss/ssl/sslimpl.h (revision 146623) |
| 4 +++ net/third_party/nss/ssl/sslimpl.h (working copy) |
| 5 @@ -294,6 +294,8 @@ |
| 6 #define ssl_SEND_FLAG_NO_BUFFER 0x20000000 |
| 7 #define ssl_SEND_FLAG_USE_EPOCH 0x10000000 /* DTLS only */ |
| 8 #define ssl_SEND_FLAG_NO_RETRANSMIT 0x08000000 /* DTLS only */ |
| 9 +#define ssl_SEND_FLAG_CAP_RECORD_VERSION \ |
| 10 + 0x04000000 /* TLS only */ |
| 11 #define ssl_SEND_FLAG_MASK 0x7f000000 |
| 12 |
| 13 /* |
| 14 @@ -1414,6 +1416,7 @@ |
| 15 ssl3_CompressMACEncryptRecord(ssl3CipherSpec * cwSpec, |
| 16 PRBool isServer, |
| 17 PRBool isDTLS, |
| 18 + PRBool capRecordVersion, |
| 19 SSL3ContentType type, |
| 20 const SSL3Opaque * pIn, |
| 21 PRUint32 contentLen, |
| 22 Index: net/third_party/nss/ssl/ssl3con.c |
| 23 =================================================================== |
| 24 --- net/third_party/nss/ssl/ssl3con.c (revision 146623) |
| 25 +++ net/third_party/nss/ssl/ssl3con.c (working copy) |
| 26 @@ -2057,6 +2057,7 @@ |
| 27 ssl3_CompressMACEncryptRecord(ssl3CipherSpec * cwSpec, |
| 28 PRBool isServer, |
| 29 PRBool isDTLS, |
| 30 + PRBool capRecordVersion, |
| 31 SSL3ContentType type, |
| 32 const SSL3Opaque * pIn, |
| 33 PRUint32 contentLen, |
| 34 @@ -2216,8 +2217,13 @@ |
| 35 wrBuf->buf[11] = MSB(cipherBytes); |
| 36 wrBuf->buf[12] = LSB(cipherBytes); |
| 37 } else { |
| 38 - wrBuf->buf[1] = MSB(cwSpec->version); |
| 39 - wrBuf->buf[2] = LSB(cwSpec->version); |
| 40 + SSL3ProtocolVersion version = cwSpec->version; |
| 41 + |
| 42 + if (capRecordVersion) { |
| 43 + version = PR_MIN(SSL_LIBRARY_VERSION_TLS_1_0, version); |
| 44 + } |
| 45 + wrBuf->buf[1] = MSB(version); |
| 46 + wrBuf->buf[2] = LSB(version); |
| 47 wrBuf->buf[3] = MSB(cipherBytes); |
| 48 wrBuf->buf[4] = LSB(cipherBytes); |
| 49 } |
| 50 @@ -2247,7 +2253,14 @@ |
| 51 * all ciphertext into the pending ciphertext buffer. |
| 52 * ssl_SEND_FLAG_USE_EPOCH (for DTLS) |
| 53 * Forces the use of the provided epoch |
| 54 - * |
| 55 + * ssl_SEND_FLAG_CAP_RECORD_VERSION |
| 56 + * Caps the record layer version number of TLS ClientHello to { 3, 1 } |
| 57 + * (TLS 1.0). Some TLS 1.0 servers (which seem to use F5 BIG-IP) ignore |
| 58 + * ClientHello.client_version and use the record layer version number |
| 59 + * (TLSPlaintext.version) instead when negotiating protocol versions. In |
| 60 + * addition, if the record layer version number of ClientHello is { 3, 2 } |
| 61 + * (TLS 1.1) or higher, these servers reset the TCP connections. Set this |
| 62 + * flag to work around such servers. |
| 63 */ |
| 64 PRInt32 |
| 65 ssl3_SendRecord( sslSocket * ss, |
| 66 @@ -2260,6 +2273,7 @@ |
| 67 sslBuffer * wrBuf = &ss->sec.writeBuf; |
| 68 SECStatus rv; |
| 69 PRInt32 totalSent = 0; |
| 70 + PRBool capRecordVersion; |
| 71 |
| 72 SSL_TRC(3, ("%d: SSL3[%d] SendRecord type: %s nIn=%d", |
| 73 SSL_GETPID(), ss->fd, ssl3_DecodeContentType(type), |
| 74 @@ -2268,6 +2282,16 @@ |
| 75 |
| 76 PORT_Assert( ss->opt.noLocks || ssl_HaveXmitBufLock(ss) ); |
| 77 |
| 78 + capRecordVersion = ((flags & ssl_SEND_FLAG_CAP_RECORD_VERSION) != 0); |
| 79 + |
| 80 + if (capRecordVersion) { |
| 81 + /* ssl_SEND_FLAG_CAP_RECORD_VERSION can only be used with |
| 82 + * TLS ClientHello. */ |
| 83 + PORT_Assert(!IS_DTLS(ss)); |
| 84 + PORT_Assert(type == content_handshake); |
| 85 + PORT_Assert(ss->ssl3.hs.ws == wait_server_hello); |
| 86 + } |
| 87 + |
| 88 if (ss->ssl3.initialized == PR_FALSE) { |
| 89 /* This can happen on a server if the very first incoming record |
| 90 ** looks like a defective ssl3 record (e.g. too long), and we're |
| 91 @@ -2324,7 +2348,8 @@ |
| 92 |
| 93 rv = ssl3_CompressMACEncryptRecord(ss->ssl3.cwSpec, |
| 94 ss->sec.isServer, IS_DTLS(ss), |
| 95 - type, pIn, 1, wrBuf); |
| 96 + capRecordVersion, type, pIn, |
| 97 + 1, wrBuf); |
| 98 if (rv != SECSuccess) |
| 99 goto spec_locked_loser; |
| 100 |
| 101 @@ -2337,7 +2362,8 @@ |
| 102 |
| 103 rv = ssl3_CompressMACEncryptRecord(ss->ssl3.cwSpec, |
| 104 ss->sec.isServer, IS_DTLS(ss), |
| 105 - type, pIn + 1, contentLen - 1, |
| 106 + capRecordVersion, type, |
| 107 + pIn + 1, contentLen - 1, |
| 108 &secondRecord); |
| 109 if (rv == SECSuccess) { |
| 110 PRINT_BUF(50, (ss, "send (encrypted) record data [2/2]:", |
| 111 @@ -2349,6 +2375,7 @@ |
| 112 rv = ssl3_CompressMACEncryptRecord(ss->ssl3.cwSpec, |
| 113 ss->sec.isServer, |
| 114 IS_DTLS(ss), |
| 115 + capRecordVersion, |
| 116 type, pIn, |
| 117 contentLen, wrBuf); |
| 118 } else { |
| 119 @@ -2560,6 +2587,8 @@ |
| 120 static SECStatus |
| 121 ssl3_FlushHandshakeMessages(sslSocket *ss, PRInt32 flags) |
| 122 { |
| 123 + static const PRInt32 allowedFlags = ssl_SEND_FLAG_FORCE_INTO_BUFFER | |
| 124 + ssl_SEND_FLAG_CAP_RECORD_VERSION; |
| 125 PRInt32 rv = SECSuccess; |
| 126 |
| 127 PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss)); |
| 128 @@ -2568,9 +2597,9 @@ |
| 129 if (!ss->sec.ci.sendBuf.buf || !ss->sec.ci.sendBuf.len) |
| 130 return rv; |
| 131 |
| 132 - /* only this flag is allowed */ |
| 133 - PORT_Assert(!(flags & ~ssl_SEND_FLAG_FORCE_INTO_BUFFER)); |
| 134 - if ((flags & ~ssl_SEND_FLAG_FORCE_INTO_BUFFER) != 0) { |
| 135 + /* only these flags are allowed */ |
| 136 + PORT_Assert(!(flags & ~allowedFlags)); |
| 137 + if ((flags & ~allowedFlags) != 0) { |
| 138 PORT_SetError(SEC_ERROR_INVALID_ARGS); |
| 139 rv = SECFailure; |
| 140 } else { |
| 141 @@ -3981,8 +4010,10 @@ |
| 142 int num_suites; |
| 143 int actual_count = 0; |
| 144 PRBool isTLS = PR_FALSE; |
| 145 + PRBool serverVersionKnown = PR_FALSE; |
| 146 PRInt32 total_exten_len = 0; |
| 147 unsigned numCompressionMethods; |
| 148 + PRInt32 flags; |
| 149 |
| 150 SSL_TRC(3, ("%d: SSL3[%d]: send client_hello handshake", SSL_GETPID(), |
| 151 ss->fd)); |
| 152 @@ -4070,6 +4101,7 @@ |
| 153 } |
| 154 |
| 155 if (sid) { |
| 156 + serverVersionKnown = PR_TRUE; |
| 157 SSL_AtomicIncrementLong(& ssl3stats.sch_sid_cache_hits ); |
| 158 |
| 159 /* Are we attempting a stateless session resume? */ |
| 160 @@ -4305,7 +4337,11 @@ |
| 161 ssl_renegotiation_info_xtn; |
| 162 } |
| 163 |
| 164 - rv = ssl3_FlushHandshake(ss, 0); |
| 165 + flags = 0; |
| 166 + if (!serverVersionKnown && !IS_DTLS(ss)) { |
| 167 + flags |= ssl_SEND_FLAG_CAP_RECORD_VERSION; |
| 168 + } |
| 169 + rv = ssl3_FlushHandshake(ss, flags); |
| 170 if (rv != SECSuccess) { |
| 171 return rv; /* error code set by ssl3_FlushHandshake */ |
| 172 } |
| 173 Index: net/third_party/nss/ssl/dtls1con.c |
| 174 =================================================================== |
| 175 --- net/third_party/nss/ssl/dtls1con.c (revision 146623) |
| 176 +++ net/third_party/nss/ssl/dtls1con.c (working copy) |
| 177 @@ -834,7 +834,8 @@ |
| 178 |
| 179 if (cwSpec) { |
| 180 rv = ssl3_CompressMACEncryptRecord(cwSpec, ss->sec.isServer, PR_TRUE, |
| 181 - type, pIn, contentLen, wrBuf); |
| 182 + PR_FALSE, type, pIn, contentLen, |
| 183 + wrBuf); |
| 184 } else { |
| 185 PR_NOT_REACHED("Couldn't find a cipher spec matching epoch"); |
| 186 PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); |
| OLD | NEW |