OLD | NEW |
(Empty) | |
| 1 Index: net/third_party/nss/ssl/ssl.h |
| 2 =================================================================== |
| 3 --- net/third_party/nss/ssl/ssl.h (revision 227363) |
| 4 +++ net/third_party/nss/ssl/ssl.h (working copy) |
| 5 @@ -121,14 +121,22 @@ |
| 6 #define SSL_ENABLE_FALSE_START 22 /* Enable SSL false start (off by */ |
| 7 /* default, applies only to */ |
| 8 /* clients). False start is a */ |
| 9 -/* mode where an SSL client will start sending application data before */ |
| 10 -/* verifying the server's Finished message. This means that we could end up */ |
| 11 -/* sending data to an imposter. However, the data will be encrypted and */ |
| 12 -/* only the true server can derive the session key. Thus, so long as the */ |
| 13 -/* cipher isn't broken this is safe. Because of this, False Start will only */ |
| 14 -/* occur on RSA or DH ciphersuites where the cipher's key length is >= 80 */ |
| 15 -/* bits. The advantage of False Start is that it saves a round trip for */ |
| 16 -/* client-speaks-first protocols when performing a full handshake. */ |
| 17 +/* mode where an SSL client will start sending application data before |
| 18 + * verifying the server's Finished message. This means that we could end up |
| 19 + * sending data to an imposter. However, the data will be encrypted and |
| 20 + * only the true server can derive the session key. Thus, so long as the |
| 21 + * cipher isn't broken this is safe. The advantage of false start is that |
| 22 + * it saves a round trip for client-speaks-first protocols when performing a |
| 23 + * full handshake. |
| 24 + * |
| 25 + * See SSL_DefaultCanFalseStart for the default criteria that NSS uses to |
| 26 + * determine whether to false start or not. See SSL_SetCanFalseStartCallback |
| 27 + * for how to change that criteria. In addition to those criteria, false start |
| 28 + * will only be done when the server selects a cipher suite with an effective |
| 29 + * key length of 80 bits or more (including RC4-128). Also, see |
| 30 + * SSL_HandshakeCallback for a description on how false start affects when the |
| 31 + * handshake callback gets called. |
| 32 + */ |
| 33 |
| 34 /* For SSL 3.0 and TLS 1.0, by default we prevent chosen plaintext attacks |
| 35 * on SSL CBC mode cipher suites (see RFC 4346 Section F.3) by splitting |
| 36 @@ -741,14 +749,59 @@ |
| 37 SSL_IMPORT SECStatus SSL_InheritMPServerSIDCache(const char * envString); |
| 38 |
| 39 /* |
| 40 -** Set the callback on a particular socket that gets called when we finish |
| 41 -** performing a handshake. |
| 42 +** Set the callback that normally gets called when the TLS handshake |
| 43 +** is complete. If false start is not enabled, then the handshake callback is |
| 44 +** called after verifying the peer's Finished message and before sending |
| 45 +** outgoing application data and before processing incoming application data. |
| 46 +** |
| 47 +** If false start is enabled and there is a custom CanFalseStartCallback |
| 48 +** callback set, then the handshake callback gets called after the peer's |
| 49 +** Finished message has been verified, which may be after application data is |
| 50 +** sent. |
| 51 +** |
| 52 +** If false start is enabled and there is not a custom CanFalseStartCallback |
| 53 +** callback established with SSL_SetCanFalseStartCallback then the handshake |
| 54 +** callback gets called before any application data is sent, which may be |
| 55 +** before the peer's Finished message has been verified. |
| 56 */ |
| 57 typedef void (PR_CALLBACK *SSLHandshakeCallback)(PRFileDesc *fd, |
| 58 void *client_data); |
| 59 SSL_IMPORT SECStatus SSL_HandshakeCallback(PRFileDesc *fd, |
| 60 SSLHandshakeCallback cb, void *client_data); |
| 61 |
| 62 +/* Applications that wish to customize TLS false start should set this callback |
| 63 +** function. NSS will invoke the functon to determine if a particular |
| 64 +** connection should use false start or not. SECSuccess indicates that the |
| 65 +** callback completed successfully, and if so *canFalseStart indicates if false |
| 66 +** start can be used. If the callback does not return SECSuccess then the |
| 67 +** handshake will be canceled. |
| 68 +** |
| 69 +** Applications that do not set the callback will use an internal set of |
| 70 +** criteria to determine if the connection should false start. If |
| 71 +** the callback is set false start will never be used without invoking the |
| 72 +** callback function, but some connections (e.g. resumed connections) will |
| 73 +** never use false start and therefore will not invoke the callback. |
| 74 +** |
| 75 +** NSS's internal criteria for this connection can be evaluated by calling |
| 76 +** SSL_DefaultCanFalseStart() from the custom callback. |
| 77 +** |
| 78 +** See the description of SSL_HandshakeCallback for important information on |
| 79 +** how registering a custom false start callback affects when the handshake |
| 80 +** callback gets called. |
| 81 +**/ |
| 82 +typedef SECStatus (PR_CALLBACK *SSLCanFalseStartCallback)( |
| 83 + PRFileDesc *fd, void *arg, PRBool *canFalseStart); |
| 84 + |
| 85 +SSL_IMPORT SECStatus SSL_SetCanFalseStartCallback( |
| 86 + PRFileDesc *fd, SSLCanFalseStartCallback callback, void *arg); |
| 87 + |
| 88 +/* A utility function that can be called from a custom CanFalseStartCallback |
| 89 +** function to determine what NSS would have done for this connection if the |
| 90 +** custom callback was not implemented. |
| 91 +**/ |
| 92 +SSL_IMPORT SECStatus SSL_DefaultCanFalseStart(PRFileDesc *fd, |
| 93 + PRBool *canFalseStart); |
| 94 + |
| 95 /* |
| 96 ** For the server, request a new handshake. For the client, begin a new |
| 97 ** handshake. If flushCache is non-zero, the SSL3 cache entry will be |
| 98 Index: net/third_party/nss/ssl/ssl3gthr.c |
| 99 =================================================================== |
| 100 --- net/third_party/nss/ssl/ssl3gthr.c (revision 227363) |
| 101 +++ net/third_party/nss/ssl/ssl3gthr.c (working copy) |
| 102 @@ -374,9 +374,7 @@ |
| 103 */ |
| 104 if (ss->opt.enableFalseStart) { |
| 105 ssl_GetSSL3HandshakeLock(ss); |
| 106 - canFalseStart = (ss->ssl3.hs.ws == wait_change_cipher || |
| 107 - ss->ssl3.hs.ws == wait_new_session_ticket) && |
| 108 - ssl3_CanFalseStart(ss); |
| 109 + canFalseStart = ss->ssl3.hs.canFalseStart; |
| 110 ssl_ReleaseSSL3HandshakeLock(ss); |
| 111 } |
| 112 } while (ss->ssl3.hs.ws != idle_handshake && |
| 113 Index: net/third_party/nss/ssl/sslinfo.c |
| 114 =================================================================== |
| 115 --- net/third_party/nss/ssl/sslinfo.c (revision 227363) |
| 116 +++ net/third_party/nss/ssl/sslinfo.c (working copy) |
| 117 @@ -26,7 +26,6 @@ |
| 118 sslSocket * ss; |
| 119 SSLChannelInfo inf; |
| 120 sslSessionID * sid; |
| 121 - PRBool enoughFirstHsDone = PR_FALSE; |
| 122 |
| 123 if (!info || len < sizeof inf.length) { |
| 124 PORT_SetError(SEC_ERROR_INVALID_ARGS); |
| 125 @@ -43,14 +42,7 @@ |
| 126 memset(&inf, 0, sizeof inf); |
| 127 inf.length = PR_MIN(sizeof inf, len); |
| 128 |
| 129 - if (ss->firstHsDone) { |
| 130 - enoughFirstHsDone = PR_TRUE; |
| 131 - } else if (ss->version >= SSL_LIBRARY_VERSION_3_0 && |
| 132 - ssl3_CanFalseStart(ss)) { |
| 133 - enoughFirstHsDone = PR_TRUE; |
| 134 - } |
| 135 - |
| 136 - if (ss->opt.useSecurity && enoughFirstHsDone) { |
| 137 + if (ss->opt.useSecurity && ss->enoughFirstHsDone) { |
| 138 sid = ss->sec.ci.sid; |
| 139 inf.protocolVersion = ss->version; |
| 140 inf.authKeyBits = ss->sec.authKeyBits; |
| 141 Index: net/third_party/nss/ssl/sslauth.c |
| 142 =================================================================== |
| 143 --- net/third_party/nss/ssl/sslauth.c (revision 227363) |
| 144 +++ net/third_party/nss/ssl/sslauth.c (working copy) |
| 145 @@ -100,7 +100,6 @@ |
| 146 sslSocket *ss; |
| 147 const char *cipherName; |
| 148 PRBool isDes = PR_FALSE; |
| 149 - PRBool enoughFirstHsDone = PR_FALSE; |
| 150 |
| 151 ss = ssl_FindSocket(fd); |
| 152 if (!ss) { |
| 153 @@ -118,14 +117,7 @@ |
| 154 *op = SSL_SECURITY_STATUS_OFF; |
| 155 } |
| 156 |
| 157 - if (ss->firstHsDone) { |
| 158 - enoughFirstHsDone = PR_TRUE; |
| 159 - } else if (ss->version >= SSL_LIBRARY_VERSION_3_0 && |
| 160 - ssl3_CanFalseStart(ss)) { |
| 161 - enoughFirstHsDone = PR_TRUE; |
| 162 - } |
| 163 - |
| 164 - if (ss->opt.useSecurity && enoughFirstHsDone) { |
| 165 + if (ss->opt.useSecurity && ss->enoughFirstHsDone) { |
| 166 if (ss->version < SSL_LIBRARY_VERSION_3_0) { |
| 167 cipherName = ssl_cipherName[ss->sec.cipherType]; |
| 168 } else { |
| 169 Index: net/third_party/nss/ssl/sslimpl.h |
| 170 =================================================================== |
| 171 --- net/third_party/nss/ssl/sslimpl.h (revision 227363) |
| 172 +++ net/third_party/nss/ssl/sslimpl.h (working copy) |
| 173 @@ -881,6 +881,8 @@ |
| 174 /* Shared state between ssl3_HandleFinished and ssl3_FinishHandshake */ |
| 175 PRBool cacheSID; |
| 176 |
| 177 + PRBool canFalseStart; /* Can/did we False Start */ |
| 178 + |
| 179 /* clientSigAndHash contains the contents of the signature_algorithms |
| 180 * extension (if any) from the client. This is only valid for TLS 1.2 |
| 181 * or later. */ |
| 182 @@ -1162,6 +1164,10 @@ |
| 183 unsigned long clientAuthRequested; |
| 184 unsigned long delayDisabled; /* Nagle delay disabled */ |
| 185 unsigned long firstHsDone; /* first handshake is complete. */ |
| 186 + unsigned long enoughFirstHsDone; /* enough of the first handshake is |
| 187 + * done for callbacks to be able to |
| 188 + * retrieve channel security |
| 189 + * parameters from the SSL socket. */ |
| 190 unsigned long handshakeBegun; |
| 191 unsigned long lastWriteBlocked; |
| 192 unsigned long recvdCloseNotify; /* received SSL EOF. */ |
| 193 @@ -1210,6 +1216,8 @@ |
| 194 void *badCertArg; |
| 195 SSLHandshakeCallback handshakeCallback; |
| 196 void *handshakeCallbackData; |
| 197 + SSLCanFalseStartCallback canFalseStartCallback; |
| 198 + void *canFalseStartCallbackData; |
| 199 void *pkcs11PinArg; |
| 200 SSLNextProtoCallback nextProtoCallback; |
| 201 void *nextProtoArg; |
| 202 @@ -1423,7 +1431,6 @@ |
| 203 |
| 204 extern SECStatus ssl_EnableNagleDelay(sslSocket *ss, PRBool enabled); |
| 205 |
| 206 -extern PRBool ssl3_CanFalseStart(sslSocket *ss); |
| 207 extern SECStatus |
| 208 ssl3_CompressMACEncryptRecord(ssl3CipherSpec * cwSpec, |
| 209 PRBool isServer, |
| 210 Index: net/third_party/nss/ssl/sslsecur.c |
| 211 =================================================================== |
| 212 --- net/third_party/nss/ssl/sslsecur.c (revision 227363) |
| 213 +++ net/third_party/nss/ssl/sslsecur.c (working copy) |
| 214 @@ -99,21 +99,12 @@ |
| 215 if (ss->handshake == 0) { |
| 216 ssl_GetRecvBufLock(ss); |
| 217 ss->gs.recordLen = 0; |
| 218 + ss->gs.writeOffset = 0; |
| 219 + ss->gs.readOffset = 0; |
| 220 ssl_ReleaseRecvBufLock(ss); |
| 221 |
| 222 SSL_TRC(3, ("%d: SSL[%d]: handshake is completed", |
| 223 SSL_GETPID(), ss->fd)); |
| 224 - /* call handshake callback for ssl v2 */ |
| 225 - /* for v3 this is done in ssl3_HandleFinished() */ |
| 226 - if ((ss->handshakeCallback != NULL) && /* has callback */ |
| 227 - (!ss->firstHsDone) && /* only first time */ |
| 228 - (ss->version < SSL_LIBRARY_VERSION_3_0)) { /* not ssl3 */ |
| 229 - ss->firstHsDone = PR_TRUE; |
| 230 - (ss->handshakeCallback)(ss->fd, ss->handshakeCallbackData); |
| 231 - } |
| 232 - ss->firstHsDone = PR_TRUE; |
| 233 - ss->gs.writeOffset = 0; |
| 234 - ss->gs.readOffset = 0; |
| 235 break; |
| 236 } |
| 237 rv = (*ss->handshake)(ss); |
| 238 @@ -206,6 +197,7 @@ |
| 239 ssl_Get1stHandshakeLock(ss); |
| 240 |
| 241 ss->firstHsDone = PR_FALSE; |
| 242 + ss->enoughFirstHsDone = PR_FALSE; |
| 243 if ( asServer ) { |
| 244 ss->handshake = ssl2_BeginServerHandshake; |
| 245 ss->handshaking = sslHandshakingAsServer; |
| 246 @@ -221,6 +213,8 @@ |
| 247 ssl_ReleaseRecvBufLock(ss); |
| 248 |
| 249 ssl_GetSSL3HandshakeLock(ss); |
| 250 + ss->ssl3.hs.canFalseStart = PR_FALSE; |
| 251 + ss->ssl3.hs.restartTarget = NULL; |
| 252 |
| 253 /* |
| 254 ** Blow away old security state and get a fresh setup. |
| 255 @@ -266,7 +260,7 @@ |
| 256 |
| 257 /* SSL v2 protocol does not support subsequent handshakes. */ |
| 258 if (ss->version < SSL_LIBRARY_VERSION_3_0) { |
| 259 - PORT_SetError(SEC_ERROR_INVALID_ARGS); |
| 260 + PORT_SetError(SSL_ERROR_FEATURE_NOT_SUPPORTED_FOR_SSL2); |
| 261 rv = SECFailure; |
| 262 } else { |
| 263 ssl_GetSSL3HandshakeLock(ss); |
| 264 @@ -331,6 +325,75 @@ |
| 265 return SECSuccess; |
| 266 } |
| 267 |
| 268 +/* Register an application callback to be called when false start may happen. |
| 269 +** Acquires and releases HandshakeLock. |
| 270 +*/ |
| 271 +SECStatus |
| 272 +SSL_SetCanFalseStartCallback(PRFileDesc *fd, SSLCanFalseStartCallback cb, |
| 273 + void *client_data) |
| 274 +{ |
| 275 + sslSocket *ss; |
| 276 + |
| 277 + ss = ssl_FindSocket(fd); |
| 278 + if (!ss) { |
| 279 + SSL_DBG(("%d: SSL[%d]: bad socket in SSL_SetCanFalseStartCallback", |
| 280 + SSL_GETPID(), fd)); |
| 281 + return SECFailure; |
| 282 + } |
| 283 + |
| 284 + if (!ss->opt.useSecurity) { |
| 285 + PORT_SetError(SEC_ERROR_INVALID_ARGS); |
| 286 + return SECFailure; |
| 287 + } |
| 288 + |
| 289 + ssl_Get1stHandshakeLock(ss); |
| 290 + ssl_GetSSL3HandshakeLock(ss); |
| 291 + |
| 292 + ss->canFalseStartCallback = cb; |
| 293 + ss->canFalseStartCallbackData = client_data; |
| 294 + |
| 295 + ssl_ReleaseSSL3HandshakeLock(ss); |
| 296 + ssl_Release1stHandshakeLock(ss); |
| 297 + |
| 298 + return SECSuccess; |
| 299 +} |
| 300 + |
| 301 +/* A utility function that can be called from a custom SSLCanFalseStartCallback |
| 302 +** function to determine what NSS would have done for this connection if the |
| 303 +** custom callback was not implemented. |
| 304 +*/ |
| 305 +SECStatus |
| 306 +SSL_DefaultCanFalseStart(PRFileDesc *fd, PRBool *canFalseStart) |
| 307 +{ |
| 308 + sslSocket *ss; |
| 309 + |
| 310 + *canFalseStart = PR_FALSE; |
| 311 + ss = ssl_FindSocket(fd); |
| 312 + if (!ss) { |
| 313 + SSL_DBG(("%d: SSL[%d]: bad socket in SSL_DefaultCanFalseStart", |
| 314 + SSL_GETPID(), fd)); |
| 315 + return SECFailure; |
| 316 + } |
| 317 + |
| 318 + if (!ss->ssl3.initialized) { |
| 319 + PORT_SetError(SEC_ERROR_INVALID_ARGS); |
| 320 + return SECFailure; |
| 321 + } |
| 322 + |
| 323 + if (ss->version < SSL_LIBRARY_VERSION_3_0) { |
| 324 + PORT_SetError(SSL_ERROR_FEATURE_NOT_SUPPORTED_FOR_SSL2); |
| 325 + return SECFailure; |
| 326 + } |
| 327 + |
| 328 + /* Require a forward-secret key exchange. */ |
| 329 + *canFalseStart = ss->ssl3.hs.kea_def->kea == kea_dhe_dss || |
| 330 + ss->ssl3.hs.kea_def->kea == kea_dhe_rsa || |
| 331 + ss->ssl3.hs.kea_def->kea == kea_ecdhe_ecdsa || |
| 332 + ss->ssl3.hs.kea_def->kea == kea_ecdhe_rsa; |
| 333 + |
| 334 + return SECSuccess; |
| 335 +} |
| 336 + |
| 337 /* Try to make progress on an SSL handshake by attempting to read the |
| 338 ** next handshake from the peer, and sending any responses. |
| 339 ** For non-blocking sockets, returns PR_ERROR_WOULD_BLOCK if it cannot |
| 340 @@ -1195,12 +1258,7 @@ |
| 341 ssl_Get1stHandshakeLock(ss); |
| 342 if (ss->version >= SSL_LIBRARY_VERSION_3_0) { |
| 343 ssl_GetSSL3HandshakeLock(ss); |
| 344 - if ((ss->ssl3.hs.ws == wait_change_cipher || |
| 345 - ss->ssl3.hs.ws == wait_finished || |
| 346 - ss->ssl3.hs.ws == wait_new_session_ticket) && |
| 347 - ssl3_CanFalseStart(ss)) { |
| 348 - canFalseStart = PR_TRUE; |
| 349 - } |
| 350 + canFalseStart = ss->ssl3.hs.canFalseStart; |
| 351 ssl_ReleaseSSL3HandshakeLock(ss); |
| 352 } |
| 353 if (!canFalseStart && |
| 354 Index: net/third_party/nss/ssl/sslsock.c |
| 355 =================================================================== |
| 356 --- net/third_party/nss/ssl/sslsock.c (revision 227363) |
| 357 +++ net/third_party/nss/ssl/sslsock.c (working copy) |
| 358 @@ -2457,10 +2457,14 @@ |
| 359 } else if (new_flags & PR_POLL_WRITE) { |
| 360 /* The caller is trying to write, but the handshake is |
| 361 ** blocked waiting for data to read, and the first |
| 362 - ** handshake has been sent. so do NOT to poll on write. |
| 363 + ** handshake has been sent. So do NOT to poll on write |
| 364 + ** unless we did false start. |
| 365 */ |
| 366 - new_flags ^= PR_POLL_WRITE; /* don't select on write. */ |
| 367 - new_flags |= PR_POLL_READ; /* do select on read. */ |
| 368 + if (!(ss->version >= SSL_LIBRARY_VERSION_3_0 && |
| 369 + ss->ssl3.hs.canFalseStart)) { |
| 370 + new_flags ^= PR_POLL_WRITE; /* don't select on write. */ |
| 371 + } |
| 372 + new_flags |= PR_POLL_READ; /* do select on read. */ |
| 373 } |
| 374 } |
| 375 } else if ((new_flags & PR_POLL_READ) && (SSL_DataPending(fd) > 0)) { |
| 376 Index: net/third_party/nss/ssl/ssl3con.c |
| 377 =================================================================== |
| 378 --- net/third_party/nss/ssl/ssl3con.c (revision 227363) |
| 379 +++ net/third_party/nss/ssl/ssl3con.c (working copy) |
| 380 @@ -2890,7 +2890,7 @@ |
| 381 SSL_TRC(3, ("%d: SSL3[%d] SendRecord type: %s nIn=%d", |
| 382 SSL_GETPID(), ss->fd, ssl3_DecodeContentType(type), |
| 383 nIn)); |
| 384 - PRINT_BUF(3, (ss, "Send record (plain text)", pIn, nIn)); |
| 385 + PRINT_BUF(50, (ss, "Send record (plain text)", pIn, nIn)); |
| 386 |
| 387 PORT_Assert( ss->opt.noLocks || ssl_HaveXmitBufLock(ss) ); |
| 388 |
| 389 @@ -7344,35 +7344,42 @@ |
| 390 return rv; |
| 391 } |
| 392 |
| 393 -PRBool |
| 394 -ssl3_CanFalseStart(sslSocket *ss) { |
| 395 - PRBool rv; |
| 396 +static SECStatus |
| 397 +ssl3_CheckFalseStart(sslSocket *ss) |
| 398 +{ |
| 399 + SECStatus rv; |
| 400 + PRBool maybeFalseStart = PR_TRUE; |
| 401 |
| 402 PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss) ); |
| 403 + PORT_Assert( !ss->ssl3.hs.authCertificatePending ); |
| 404 |
| 405 - /* XXX: does not take into account whether we are waiting for |
| 406 - * SSL_AuthCertificateComplete or SSL_RestartHandshakeAfterCertReq. If/when |
| 407 - * that is done, this function could return different results each time it |
| 408 - * would be called. |
| 409 - */ |
| 410 + /* An attacker can control the selected ciphersuite so we only wish to |
| 411 + * do False Start in the case that the selected ciphersuite is |
| 412 + * sufficiently strong that the attack can gain no advantage. |
| 413 + * Therefore we always require an 80-bit cipher. */ |
| 414 |
| 415 ssl_GetSpecReadLock(ss); |
| 416 - rv = ss->opt.enableFalseStart && |
| 417 - !ss->sec.isServer && |
| 418 - !ss->ssl3.hs.isResuming && |
| 419 - ss->ssl3.cwSpec && |
| 420 + if (ss->ssl3.cwSpec->cipher_def->secret_key_size < 10) { |
| 421 + ss->ssl3.hs.canFalseStart = PR_FALSE; |
| 422 + maybeFalseStart = PR_FALSE; |
| 423 + } |
| 424 + ssl_ReleaseSpecReadLock(ss); |
| 425 + if (!maybeFalseStart) { |
| 426 + return SECSuccess; |
| 427 + } |
| 428 |
| 429 - /* An attacker can control the selected ciphersuite so we only wish to |
| 430 - * do False Start in the case that the selected ciphersuite is |
| 431 - * sufficiently strong that the attack can gain no advantage. |
| 432 - * Therefore we require an 80-bit cipher and a forward-secret key |
| 433 - * exchange. */ |
| 434 - ss->ssl3.cwSpec->cipher_def->secret_key_size >= 10 && |
| 435 - (ss->ssl3.hs.kea_def->kea == kea_dhe_dss || |
| 436 - ss->ssl3.hs.kea_def->kea == kea_dhe_rsa || |
| 437 - ss->ssl3.hs.kea_def->kea == kea_ecdhe_ecdsa || |
| 438 - ss->ssl3.hs.kea_def->kea == kea_ecdhe_rsa); |
| 439 - ssl_ReleaseSpecReadLock(ss); |
| 440 + if (!ss->canFalseStartCallback) { |
| 441 + rv = SSL_DefaultCanFalseStart(ss->fd, &ss->ssl3.hs.canFalseStart); |
| 442 + } else { |
| 443 + rv = (ss->canFalseStartCallback)(ss->fd, |
| 444 + ss->canFalseStartCallbackData, |
| 445 + &ss->ssl3.hs.canFalseStart); |
| 446 + } |
| 447 + |
| 448 + if (rv != SECSuccess) { |
| 449 + ss->ssl3.hs.canFalseStart = PR_FALSE; |
| 450 + } |
| 451 + |
| 452 return rv; |
| 453 } |
| 454 |
| 455 @@ -7500,20 +7507,59 @@ |
| 456 goto loser; /* err code was set. */ |
| 457 } |
| 458 |
| 459 - /* XXX: If the server's certificate hasn't been authenticated by this |
| 460 - * point, then we may be leaking this NPN message to an attacker. |
| 461 + /* This must be done after we've set ss->ssl3.cwSpec in |
| 462 + * ssl3_SendChangeCipherSpecs because SSL_GetChannelInfo uses information |
| 463 + * from cwSpec. This must be done before we call ssl3_CheckFalseStart |
| 464 + * because the false start callback (if any) may need the information from |
| 465 + * the functions that depend on this being set. |
| 466 */ |
| 467 + ss->enoughFirstHsDone = PR_TRUE; |
| 468 + |
| 469 if (!ss->firstHsDone) { |
| 470 + /* XXX: If the server's certificate hasn't been authenticated by this |
| 471 + * point, then we may be leaking this NPN message to an attacker. |
| 472 + */ |
| 473 rv = ssl3_SendNextProto(ss); |
| 474 if (rv != SECSuccess) { |
| 475 goto loser; /* err code was set. */ |
| 476 } |
| 477 } |
| 478 + |
| 479 rv = ssl3_SendEncryptedExtensions(ss); |
| 480 if (rv != SECSuccess) { |
| 481 goto loser; /* err code was set. */ |
| 482 } |
| 483 |
| 484 + if (!ss->firstHsDone) { |
| 485 + if (ss->opt.enableFalseStart) { |
| 486 + if (!ss->ssl3.hs.authCertificatePending) { |
| 487 + /* When we fix bug 589047, we will need to know whether we are |
| 488 + * false starting before we try to flush the client second |
| 489 + * round to the network. With that in mind, we purposefully |
| 490 + * call ssl3_CheckFalseStart before calling ssl3_SendFinished, |
| 491 + * which includes a call to ssl3_FlushHandshake, so that |
| 492 + * no application develops a reliance on such flushing being |
| 493 + * done before its false start callback is called. |
| 494 + */ |
| 495 + ssl_ReleaseXmitBufLock(ss); |
| 496 + rv = ssl3_CheckFalseStart(ss); |
| 497 + ssl_GetXmitBufLock(ss); |
| 498 + if (rv != SECSuccess) { |
| 499 + goto loser; |
| 500 + } |
| 501 + } else { |
| 502 + /* The certificate authentication and the server's Finished |
| 503 + * message are racing each other. If the certificate |
| 504 + * authentication wins, then we will try to false start in |
| 505 + * ssl3_AuthCertificateComplete. |
| 506 + */ |
| 507 + SSL_TRC(3, ("%d: SSL3[%p]: deferring false start check because" |
| 508 + " certificate authentication is still pending.", |
| 509 + SSL_GETPID(), ss->fd)); |
| 510 + } |
| 511 + } |
| 512 + } |
| 513 + |
| 514 rv = ssl3_SendFinished(ss, 0); |
| 515 if (rv != SECSuccess) { |
| 516 goto loser; /* err code was set. */ |
| 517 @@ -7526,8 +7572,16 @@ |
| 518 else |
| 519 ss->ssl3.hs.ws = wait_change_cipher; |
| 520 |
| 521 - /* Do the handshake callback for sslv3 here, if we can false start. */ |
| 522 - if (ss->handshakeCallback != NULL && ssl3_CanFalseStart(ss)) { |
| 523 + if (ss->handshakeCallback && |
| 524 + (ss->ssl3.hs.canFalseStart && !ss->canFalseStartCallback)) { |
| 525 + /* Call the handshake callback here for backwards compatibility with |
| 526 + * applications that were using false start before |
| 527 + * canFalseStartCallback was added. Note that we do this after calling |
| 528 + * ssl3_SendFinished, which includes a call to ssl3_FlushHandshake, |
| 529 + * just in case the application is relying on having the handshake |
| 530 + * messages flushed to the network before its handshake callback is |
| 531 + * called. |
| 532 + */ |
| 533 (ss->handshakeCallback)(ss->fd, ss->handshakeCallbackData); |
| 534 } |
| 535 |
| 536 @@ -10147,13 +10201,6 @@ |
| 537 |
| 538 ss->ssl3.hs.authCertificatePending = PR_TRUE; |
| 539 rv = SECSuccess; |
| 540 - |
| 541 - /* XXX: Async cert validation and False Start don't work together |
| 542 - * safely yet; if we leave False Start enabled, we may end up false |
| 543 - * starting (sending application data) before we |
| 544 - * SSL_AuthCertificateComplete has been called. |
| 545 - */ |
| 546 - ss->opt.enableFalseStart = PR_FALSE; |
| 547 } |
| 548 |
| 549 if (rv != SECSuccess) { |
| 550 @@ -10278,6 +10325,12 @@ |
| 551 } else if (ss->ssl3.hs.restartTarget != NULL) { |
| 552 sslRestartTarget target = ss->ssl3.hs.restartTarget; |
| 553 ss->ssl3.hs.restartTarget = NULL; |
| 554 + |
| 555 + if (target == ssl3_FinishHandshake) { |
| 556 + SSL_TRC(3,("%d: SSL3[%p]: certificate authentication lost the race" |
| 557 + " with peer's finished message", SSL_GETPID(), ss->fd)); |
| 558 + } |
| 559 + |
| 560 rv = target(ss); |
| 561 /* Even if we blocked here, we have accomplished enough to claim |
| 562 * success. Any remaining work will be taken care of by subsequent |
| 563 @@ -10287,7 +10340,39 @@ |
| 564 rv = SECSuccess; |
| 565 } |
| 566 } else { |
| 567 - rv = SECSuccess; |
| 568 + SSL_TRC(3, ("%d: SSL3[%p]: certificate authentication won the race" |
| 569 + " with peer's finished message", SSL_GETPID(), ss->fd)); |
| 570 + |
| 571 + PORT_Assert(!ss->firstHsDone); |
| 572 + PORT_Assert(!ss->sec.isServer); |
| 573 + PORT_Assert(!ss->ssl3.hs.isResuming); |
| 574 + PORT_Assert(ss->ssl3.hs.ws == wait_change_cipher || |
| 575 + ss->ssl3.hs.ws == wait_finished || |
| 576 + ss->ssl3.hs.ws == wait_new_session_ticket); |
| 577 + |
| 578 + /* ssl3_SendClientSecondRound deferred the false start check because |
| 579 + * certificate authentication was pending, so we have to do it now. |
| 580 + */ |
| 581 + if (ss->opt.enableFalseStart && |
| 582 + !ss->firstHsDone && |
| 583 + !ss->sec.isServer && |
| 584 + !ss->ssl3.hs.isResuming && |
| 585 + (ss->ssl3.hs.ws == wait_change_cipher || |
| 586 + ss->ssl3.hs.ws == wait_finished || |
| 587 + ss->ssl3.hs.ws == wait_new_session_ticket)) { |
| 588 + rv = ssl3_CheckFalseStart(ss); |
| 589 + if (rv == SECSuccess && |
| 590 + ss->handshakeCallback && |
| 591 + (ss->ssl3.hs.canFalseStart && !ss->canFalseStartCallback)) { |
| 592 + /* Call the handshake callback here for backwards compatibility |
| 593 + * with applications that were using false start before |
| 594 + * canFalseStartCallback was added. |
| 595 + */ |
| 596 + (ss->handshakeCallback)(ss->fd, ss->handshakeCallbackData); |
| 597 + } |
| 598 + } else { |
| 599 + rv = SECSuccess; |
| 600 + } |
| 601 } |
| 602 |
| 603 done: |
| 604 @@ -10983,6 +11068,8 @@ |
| 605 SECStatus |
| 606 ssl3_FinishHandshake(sslSocket * ss) |
| 607 { |
| 608 + PRBool falseStarted; |
| 609 + |
| 610 PORT_Assert( ss->opt.noLocks || ssl_HaveRecvBufLock(ss) ); |
| 611 PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss) ); |
| 612 PORT_Assert( ss->ssl3.hs.restartTarget == NULL ); |
| 613 @@ -10990,6 +11077,7 @@ |
| 614 /* The first handshake is now completed. */ |
| 615 ss->handshake = NULL; |
| 616 ss->firstHsDone = PR_TRUE; |
| 617 + ss->enoughFirstHsDone = PR_TRUE; |
| 618 |
| 619 if (ss->ssl3.hs.cacheSID) { |
| 620 (*ss->sec.cache)(ss->sec.ci.sid); |
| 621 @@ -10997,9 +11085,14 @@ |
| 622 } |
| 623 |
| 624 ss->ssl3.hs.ws = idle_handshake; |
| 625 + falseStarted = ss->ssl3.hs.canFalseStart; |
| 626 + ss->ssl3.hs.canFalseStart = PR_FALSE; /* False Start phase is complete */ |
| 627 |
| 628 - /* Do the handshake callback for sslv3 here, if we cannot false start. */ |
| 629 - if (ss->handshakeCallback != NULL && !ssl3_CanFalseStart(ss)) { |
| 630 + /* Call the handshake callback for sslv3 here, unless we called it already |
| 631 + * for the case where false start was done without a canFalseStartCallback. |
| 632 + */ |
| 633 + if (ss->handshakeCallback && |
| 634 + !(falseStarted && !ss->canFalseStartCallback)) { |
| 635 (ss->handshakeCallback)(ss->fd, ss->handshakeCallbackData); |
| 636 } |
| 637 |
OLD | NEW |