Bug 713933: Make SSL False Start work with asynchronous certificate validation, r=wtc
authorBrian Smith <brian@briansmith.org>
Thu, 31 Oct 2013 15:40:42 -0700
changeset 108981b9c43d28713
parent 10897 834ca86eaa63
child 10899 b45c9b1101aa
push id195
push userbrian@briansmith.org
push date2013-11-01 09:42 +0000
reviewerswtc
bugs713933
Bug 713933: Make SSL False Start work with asynchronous certificate validation, r=wtc
lib/ssl/ssl.def
lib/ssl/ssl.h
lib/ssl/ssl3con.c
lib/ssl/ssl3gthr.c
lib/ssl/sslauth.c
lib/ssl/sslimpl.h
lib/ssl/sslinfo.c
lib/ssl/sslsecur.c
lib/ssl/sslsock.c
     1.1 --- a/lib/ssl/ssl.def
     1.2 +++ b/lib/ssl/ssl.def
     1.3 @@ -161,11 +161,13 @@ SSL_SetSRTPCiphers;
     1.4  SSL_PeerStapledOCSPResponses;
     1.5  SSL_SetStapledOCSPResponses;
     1.6  ;+    local:
     1.7  ;+*;
     1.8  ;+};
     1.9  ;+NSS_3.15.3 {    # NSS 3.15.3 release
    1.10  ;+    global:
    1.11  SSL_PeerCertificateChain;
    1.12 +SSL_RecommendedCanFalseStart;
    1.13 +SSL_SetCanFalseStartCallback;
    1.14  ;+    local:
    1.15  ;+*;
    1.16  ;+};
     2.1 --- a/lib/ssl/ssl.h
     2.2 +++ b/lib/ssl/ssl.h
     2.3 @@ -116,24 +116,27 @@ SSL_IMPORT PRFileDesc *DTLS_ImportFD(PRF
     2.4  #define SSL_REQUIRE_SAFE_NEGOTIATION   21 /* Peer must send Signaling       */
     2.5  					  /* Cipher Suite Value (SCSV) or   */
     2.6                                            /* Renegotiation  Info (RI)       */
     2.7  					  /* extension in ALL handshakes.   */
     2.8                                            /* default: off                   */
     2.9  #define SSL_ENABLE_FALSE_START         22 /* Enable SSL false start (off by */
    2.10                                            /* default, applies only to       */
    2.11                                            /* clients). False start is a     */
    2.12 -/* mode where an SSL client will start sending application data before      */
    2.13 -/* verifying the server's Finished message. This means that we could end up */
    2.14 -/* sending data to an imposter. However, the data will be encrypted and     */
    2.15 -/* only the true server can derive the session key. Thus, so long as the    */
    2.16 -/* cipher isn't broken this is safe. Because of this, False Start will only */
    2.17 -/* occur on RSA or DH ciphersuites where the cipher's key length is >= 80   */
    2.18 -/* bits. The advantage of False Start is that it saves a round trip for     */
    2.19 -/* client-speaks-first protocols when performing a full handshake.          */
    2.20 +/* mode where an SSL client will start sending application data before
    2.21 + * verifying the server's Finished message. This means that we could end up
    2.22 + * sending data to an imposter. However, the data will be encrypted and
    2.23 + * only the true server can derive the session key. Thus, so long as the
    2.24 + * cipher isn't broken this is safe. The advantage of false start is that
    2.25 + * it saves a round trip for client-speaks-first protocols when performing a
    2.26 + * full handshake.
    2.27 + *
    2.28 + * In addition to enabling this option, the application must register a
    2.29 + * callback using the SSL_SetCanFalseStartCallback function.
    2.30 + */
    2.31  
    2.32  /* For SSL 3.0 and TLS 1.0, by default we prevent chosen plaintext attacks
    2.33   * on SSL CBC mode cipher suites (see RFC 4346 Section F.3) by splitting
    2.34   * non-empty application_data records into two records; the first record has
    2.35   * only the first byte of plaintext, and the second has the rest.
    2.36   *
    2.37   * This only prevents the attack in the sending direction; the connection may
    2.38   * still be vulnerable to such attacks if the peer does not implement a similar
    2.39 @@ -657,24 +660,55 @@ SSL_IMPORT SECStatus SSL_SetMaxServerCac
    2.40  /* called in child to inherit SID Cache variables. 
    2.41   * If envString is NULL, this function will use the value of the environment
    2.42   * variable "SSL_INHERITANCE", otherwise the string value passed in will be 
    2.43   * used.
    2.44   */
    2.45  SSL_IMPORT SECStatus SSL_InheritMPServerSIDCache(const char * envString);
    2.46  
    2.47  /*
    2.48 -** Set the callback on a particular socket that gets called when we finish
    2.49 -** performing a handshake.
    2.50 +** Set the callback that gets called when a TLS handshake is complete. The
    2.51 +** handshake callback is called after verifying the peer's Finished message and
    2.52 +** before processing incoming application data.
    2.53 +**
    2.54 +** For the initial handshake: If the handshake false started (see
    2.55 +** SSL_ENABLE_FALSE_START), then application data may already have been sent
    2.56 +** before the handshake callback is called. If we did not false start then the
    2.57 +** callback will get called before any application data is sent.
    2.58  */
    2.59  typedef void (PR_CALLBACK *SSLHandshakeCallback)(PRFileDesc *fd,
    2.60                                                   void *client_data);
    2.61  SSL_IMPORT SECStatus SSL_HandshakeCallback(PRFileDesc *fd, 
    2.62  			          SSLHandshakeCallback cb, void *client_data);
    2.63  
    2.64 +/* Applications that wish to enable TLS false start must set this callback
    2.65 +** function. NSS will invoke the functon to determine if a particular
    2.66 +** connection should use false start or not. SECSuccess indicates that the
    2.67 +** callback completed successfully, and if so *canFalseStart indicates if false
    2.68 +** start can be used. If the callback does not return SECSuccess then the
    2.69 +** handshake will be canceled. NSS's recommended criteria can be evaluated by
    2.70 +** calling SSL_RecommendedCanFalseStart.
    2.71 +**
    2.72 +** If no false start callback is registered then false start will never be
    2.73 +** done, even if the SSL_ENABLE_FALSE_START option is enabled.
    2.74 +**/
    2.75 +typedef SECStatus (PR_CALLBACK *SSLCanFalseStartCallback)(
    2.76 +    PRFileDesc *fd, void *arg, PRBool *canFalseStart);
    2.77 +
    2.78 +SSL_IMPORT SECStatus SSL_SetCanFalseStartCallback(
    2.79 +    PRFileDesc *fd, SSLCanFalseStartCallback callback, void *arg);
    2.80 +
    2.81 +/* This function sets *canFalseStart according to the recommended criteria for
    2.82 +** false start. These criteria may change from release to release and may depend
    2.83 +** on which handshake features have been negotiated and/or properties of the
    2.84 +** certifciates/keys used on the connection.
    2.85 +*/
    2.86 +SSL_IMPORT SECStatus SSL_RecommendedCanFalseStart(PRFileDesc *fd,
    2.87 +                                                  PRBool *canFalseStart);
    2.88 +
    2.89  /*
    2.90  ** For the server, request a new handshake.  For the client, begin a new
    2.91  ** handshake.  If flushCache is non-zero, the SSL3 cache entry will be 
    2.92  ** flushed first, ensuring that a full SSL handshake will be done.
    2.93  ** If flushCache is zero, and an SSL connection is established, it will 
    2.94  ** do the much faster session restart handshake.  This will change the 
    2.95  ** session keys without doing another private key operation.
    2.96  */
     3.1 --- a/lib/ssl/ssl3con.c
     3.2 +++ b/lib/ssl/ssl3con.c
     3.3 @@ -2727,17 +2727,17 @@ ssl3_SendRecord(   sslSocket *        ss
     3.4      sslBuffer      *          wrBuf 	  = &ss->sec.writeBuf;
     3.5      SECStatus                 rv;
     3.6      PRInt32                   totalSent   = 0;
     3.7      PRBool                    capRecordVersion;
     3.8  
     3.9      SSL_TRC(3, ("%d: SSL3[%d] SendRecord type: %s nIn=%d",
    3.10  		SSL_GETPID(), ss->fd, ssl3_DecodeContentType(type),
    3.11  		nIn));
    3.12 -    PRINT_BUF(3, (ss, "Send record (plain text)", pIn, nIn));
    3.13 +    PRINT_BUF(50, (ss, "Send record (plain text)", pIn, nIn));
    3.14  
    3.15      PORT_Assert( ss->opt.noLocks || ssl_HaveXmitBufLock(ss) );
    3.16  
    3.17      capRecordVersion = ((flags & ssl_SEND_FLAG_CAP_RECORD_VERSION) != 0);
    3.18  
    3.19      if (capRecordVersion) {
    3.20  	/* ssl_SEND_FLAG_CAP_RECORD_VERSION can only be used with the
    3.21  	 * TLS initial ClientHello. */
    3.22 @@ -6984,46 +6984,83 @@ loser:
    3.23      PORT_SetError(errCode);
    3.24      rv = SECFailure;
    3.25  done:
    3.26      if (arena != NULL)
    3.27      	PORT_FreeArena(arena, PR_FALSE);
    3.28      return rv;
    3.29  }
    3.30  
    3.31 +static SECStatus
    3.32 +ssl3_CheckFalseStart(sslSocket *ss)
    3.33 +{
    3.34 +    PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss) );
    3.35 +    PORT_Assert( !ss->ssl3.hs.authCertificatePending );
    3.36 +    PORT_Assert( !ss->ssl3.hs.canFalseStart );
    3.37 +
    3.38 +    if (!ss->canFalseStartCallback) {
    3.39 +	SSL_TRC(3, ("%d: SSL[%d]: no false start callback so no false start",
    3.40 +		    SSL_GETPID(), ss->fd));
    3.41 +    } else {
    3.42 +	PRBool maybeFalseStart;
    3.43 +	SECStatus rv;
    3.44 +
    3.45 +	/* An attacker can control the selected ciphersuite so we only wish to
    3.46 +	 * do False Start in the case that the selected ciphersuite is
    3.47 +	 * sufficiently strong that the attack can gain no advantage.
    3.48 +	 * Therefore we always require an 80-bit cipher. */
    3.49 +        ssl_GetSpecReadLock(ss);
    3.50 +        maybeFalseStart = ss->ssl3.cwSpec->cipher_def->secret_key_size >= 10;
    3.51 +        ssl_ReleaseSpecReadLock(ss);
    3.52 +
    3.53 +	if (!maybeFalseStart) {
    3.54 +	    SSL_TRC(3, ("%d: SSL[%d]: no false start due to weak cipher",
    3.55 +			SSL_GETPID(), ss->fd));
    3.56 +	} else {
    3.57 +	    rv = (ss->canFalseStartCallback)(ss->fd,
    3.58 +					     ss->canFalseStartCallbackData,
    3.59 +					     &ss->ssl3.hs.canFalseStart);
    3.60 +	    if (rv == SECSuccess) {
    3.61 +		SSL_TRC(3, ("%d: SSL[%d]: false start callback returned %s",
    3.62 +			    SSL_GETPID(), ss->fd,
    3.63 +			    ss->ssl3.hs.canFalseStart ? "TRUE" : "FALSE"));
    3.64 +	    } else {
    3.65 +		SSL_TRC(3, ("%d: SSL[%d]: false start callback failed (%s)",
    3.66 +			    SSL_GETPID(), ss->fd,
    3.67 +			    PR_ErrorToName(PR_GetError())));
    3.68 +	    }
    3.69 +	    return rv;
    3.70 +	}
    3.71 +    }
    3.72 +
    3.73 +    ss->ssl3.hs.canFalseStart = PR_FALSE;
    3.74 +    return SECSuccess;
    3.75 +}
    3.76 +
    3.77  PRBool
    3.78 -ssl3_CanFalseStart(sslSocket *ss) {
    3.79 -    PRBool rv;
    3.80 +ssl3_WaitingForStartOfServerSecondRound(sslSocket *ss)
    3.81 +{
    3.82 +    PRBool result = PR_FALSE;
    3.83  
    3.84      PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss) );
    3.85  
    3.86 -    /* XXX: does not take into account whether we are waiting for
    3.87 -     * SSL_AuthCertificateComplete or SSL_RestartHandshakeAfterCertReq. If/when
    3.88 -     * that is done, this function could return different results each time it
    3.89 -     * would be called.
    3.90 -     */
    3.91 -
    3.92 -    ssl_GetSpecReadLock(ss);
    3.93 -    rv = ss->opt.enableFalseStart &&
    3.94 -	 !ss->sec.isServer &&
    3.95 -	 !ss->ssl3.hs.isResuming &&
    3.96 -	 ss->ssl3.cwSpec &&
    3.97 -
    3.98 -	 /* An attacker can control the selected ciphersuite so we only wish to
    3.99 -	  * do False Start in the case that the selected ciphersuite is
   3.100 -	  * sufficiently strong that the attack can gain no advantage.
   3.101 -	  * Therefore we require an 80-bit cipher and a forward-secret key
   3.102 -	  * exchange. */
   3.103 -	 ss->ssl3.cwSpec->cipher_def->secret_key_size >= 10 &&
   3.104 -	(ss->ssl3.hs.kea_def->kea == kea_dhe_dss ||
   3.105 -	 ss->ssl3.hs.kea_def->kea == kea_dhe_rsa ||
   3.106 -	 ss->ssl3.hs.kea_def->kea == kea_ecdhe_ecdsa ||
   3.107 -	 ss->ssl3.hs.kea_def->kea == kea_ecdhe_rsa);
   3.108 -    ssl_ReleaseSpecReadLock(ss);
   3.109 -    return rv;
   3.110 +    switch (ss->ssl3.hs.ws) {
   3.111 +    case wait_new_session_ticket:
   3.112 +        result = PR_TRUE;
   3.113 +        break;
   3.114 +    case wait_change_cipher:
   3.115 +        result = !ssl3_ExtensionNegotiated(ss, ssl_session_ticket_xtn);
   3.116 +        break;
   3.117 +    case wait_finished:
   3.118 +        break;
   3.119 +    default:
   3.120 +        PR_NOT_REACHED("ssl3_WaitingForStartOfServerSecondRound");
   3.121 +    }
   3.122 +
   3.123 +    return result;
   3.124  }
   3.125  
   3.126  static SECStatus ssl3_SendClientSecondRound(sslSocket *ss);
   3.127  
   3.128  /* Called from ssl3_HandleHandshakeMessage() when it has deciphered a complete
   3.129   * ssl3 Server Hello Done message.
   3.130   * Caller must hold Handshake and RecvBuf locks.
   3.131   */
   3.132 @@ -7103,16 +7140,19 @@ ssl3_SendClientSecondRound(sslSocket *ss
   3.133       */
   3.134      if (ss->ssl3.hs.restartTarget) {
   3.135  	PR_NOT_REACHED("unexpected ss->ssl3.hs.restartTarget");
   3.136  	PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
   3.137  	return SECFailure;
   3.138      }
   3.139      if (ss->ssl3.hs.authCertificatePending &&
   3.140  	(sendClientCert || ss->ssl3.sendEmptyCert || ss->firstHsDone)) {
   3.141 +	SSL_TRC(3, ("%d: SSL3[%p]: deferring ssl3_SendClientSecondRound because"
   3.142 +		    " certificate authentication is still pending.",
   3.143 +		    SSL_GETPID(), ss->fd));
   3.144  	ss->ssl3.hs.restartTarget = ssl3_SendClientSecondRound;
   3.145  	return SECWouldBlock;
   3.146      }
   3.147  
   3.148      ssl_GetXmitBufLock(ss);		/*******************************/
   3.149  
   3.150      if (ss->ssl3.sendEmptyCert) {
   3.151  	ss->ssl3.sendEmptyCert = PR_FALSE;
   3.152 @@ -7140,42 +7180,75 @@ ssl3_SendClientSecondRound(sslSocket *ss
   3.153          }
   3.154      }
   3.155  
   3.156      rv = ssl3_SendChangeCipherSpecs(ss);
   3.157      if (rv != SECSuccess) {
   3.158  	goto loser;	/* err code was set. */
   3.159      }
   3.160  
   3.161 -    /* XXX: If the server's certificate hasn't been authenticated by this
   3.162 -     * point, then we may be leaking this NPN message to an attacker.
   3.163 +    /* This must be done after we've set ss->ssl3.cwSpec in
   3.164 +     * ssl3_SendChangeCipherSpecs because SSL_GetChannelInfo uses information
   3.165 +     * from cwSpec. This must be done before we call ssl3_CheckFalseStart
   3.166 +     * because the false start callback (if any) may need the information from
   3.167 +     * the functions that depend on this being set.
   3.168       */
   3.169 +    ss->enoughFirstHsDone = PR_TRUE;
   3.170 +
   3.171      if (!ss->firstHsDone) {
   3.172 +	/* XXX: If the server's certificate hasn't been authenticated by this
   3.173 +	 * point, then we may be leaking this NPN message to an attacker.
   3.174 +	 */
   3.175  	rv = ssl3_SendNextProto(ss);
   3.176  	if (rv != SECSuccess) {
   3.177  	    goto loser;	/* err code was set. */
   3.178  	}
   3.179 +
   3.180 +	if (ss->opt.enableFalseStart) {
   3.181 +	    if (!ss->ssl3.hs.authCertificatePending) {
   3.182 +		/* When we fix bug 589047, we will need to know whether we are
   3.183 +		 * false starting before we try to flush the client second
   3.184 +		 * round to the network. With that in mind, we purposefully
   3.185 +		 * call ssl3_CheckFalseStart before calling ssl3_SendFinished,
   3.186 +		 * which includes a call to ssl3_FlushHandshake, so that
   3.187 +		 * no application develops a reliance on such flushing being
   3.188 +		 * done before its false start callback is called.
   3.189 +		 */
   3.190 +		ssl_ReleaseXmitBufLock(ss);
   3.191 +		rv = ssl3_CheckFalseStart(ss);
   3.192 +		ssl_GetXmitBufLock(ss);
   3.193 +		if (rv != SECSuccess) {
   3.194 +		    goto loser;
   3.195 +		}
   3.196 +	    } else {
   3.197 +		/* The certificate authentication and the server's Finished
   3.198 +		 * message are racing each other. If the certificate
   3.199 +		 * authentication wins, then we will try to false start in
   3.200 +		 * ssl3_AuthCertificateComplete.
   3.201 +		 */
   3.202 +		SSL_TRC(3, ("%d: SSL3[%p]: deferring false start check because"
   3.203 +			    " certificate authentication is still pending.",
   3.204 +			    SSL_GETPID(), ss->fd));
   3.205 +	    }
   3.206 +	}
   3.207      }
   3.208  
   3.209      rv = ssl3_SendFinished(ss, 0);
   3.210      if (rv != SECSuccess) {
   3.211  	goto loser;	/* err code was set. */
   3.212      }
   3.213  
   3.214      ssl_ReleaseXmitBufLock(ss);		/*******************************/
   3.215  
   3.216      if (ssl3_ExtensionNegotiated(ss, ssl_session_ticket_xtn))
   3.217  	ss->ssl3.hs.ws = wait_new_session_ticket;
   3.218      else
   3.219  	ss->ssl3.hs.ws = wait_change_cipher;
   3.220  
   3.221 -    /* Do the handshake callback for sslv3 here, if we can false start. */
   3.222 -    if (ss->handshakeCallback != NULL && ssl3_CanFalseStart(ss)) {
   3.223 -	(ss->handshakeCallback)(ss->fd, ss->handshakeCallbackData);
   3.224 -    }
   3.225 +    PORT_Assert(ssl3_WaitingForStartOfServerSecondRound(ss));
   3.226  
   3.227      return SECSuccess;
   3.228  
   3.229  loser:
   3.230      ssl_ReleaseXmitBufLock(ss);
   3.231      return rv;
   3.232  }
   3.233  
   3.234 @@ -9740,23 +9813,16 @@ ssl3_AuthCertificate(sslSocket *ss)
   3.235  	    if (ss->sec.isServer) {
   3.236  		errCode = SSL_ERROR_FEATURE_NOT_SUPPORTED_FOR_SERVERS;
   3.237  		rv = SECFailure;
   3.238  		goto loser;
   3.239  	    }
   3.240  
   3.241  	    ss->ssl3.hs.authCertificatePending = PR_TRUE;
   3.242  	    rv = SECSuccess;
   3.243 -
   3.244 -	    /* XXX: Async cert validation and False Start don't work together
   3.245 -	     * safely yet; if we leave False Start enabled, we may end up false
   3.246 -	     * starting (sending application data) before we
   3.247 -	     * SSL_AuthCertificateComplete has been called.
   3.248 -	     */
   3.249 -	    ss->opt.enableFalseStart = PR_FALSE;
   3.250  	}
   3.251  
   3.252  	if (rv != SECSuccess) {
   3.253  	    ssl3_SendAlertForCertError(ss, errCode);
   3.254  	    goto loser;
   3.255  	}
   3.256      }
   3.257  
   3.258 @@ -9870,26 +9936,54 @@ ssl3_AuthCertificateComplete(sslSocket *
   3.259  
   3.260      if (error != 0) {
   3.261  	ss->ssl3.hs.restartTarget = ssl3_AlwaysFail;
   3.262  	ssl3_SendAlertForCertError(ss, error);
   3.263  	rv = SECSuccess;
   3.264      } else if (ss->ssl3.hs.restartTarget != NULL) {
   3.265  	sslRestartTarget target = ss->ssl3.hs.restartTarget;
   3.266  	ss->ssl3.hs.restartTarget = NULL;
   3.267 +
   3.268 +	if (target == ssl3_FinishHandshake) {
   3.269 +	    SSL_TRC(3,("%d: SSL3[%p]: certificate authentication lost the race"
   3.270 +		       " with peer's finished message", SSL_GETPID(), ss->fd));
   3.271 +	}
   3.272 +
   3.273  	rv = target(ss);
   3.274  	/* Even if we blocked here, we have accomplished enough to claim
   3.275  	 * success. Any remaining work will be taken care of by subsequent
   3.276  	 * calls to SSL_ForceHandshake/PR_Send/PR_Read/etc. 
   3.277  	 */
   3.278  	if (rv == SECWouldBlock) {
   3.279  	    rv = SECSuccess;
   3.280  	}
   3.281      } else {
   3.282 -	rv = SECSuccess;
   3.283 +	SSL_TRC(3, ("%d: SSL3[%p]: certificate authentication won the race with"
   3.284 +        	    " peer's finished message", SSL_GETPID(), ss->fd));
   3.285 +
   3.286 +	PORT_Assert(!ss->firstHsDone);
   3.287 +	PORT_Assert(!ss->sec.isServer);
   3.288 +	PORT_Assert(!ss->ssl3.hs.isResuming);
   3.289 +	PORT_Assert(ss->ssl3.hs.ws == wait_new_session_ticket ||
   3.290 +		    ss->ssl3.hs.ws == wait_change_cipher ||
   3.291 +		    ss->ssl3.hs.ws == wait_finished);
   3.292 +
   3.293 +	/* ssl3_SendClientSecondRound deferred the false start check because
   3.294 +	 * certificate authentication was pending, so we do it now if we still
   3.295 +         * haven't received any of the server's second round yet.
   3.296 +	 */
   3.297 +	if (ss->opt.enableFalseStart &&
   3.298 +	    !ss->firstHsDone &&
   3.299 +	    !ss->sec.isServer &&
   3.300 +	    !ss->ssl3.hs.isResuming &&
   3.301 +	    ssl3_WaitingForStartOfServerSecondRound(ss)) {
   3.302 +	    rv = ssl3_CheckFalseStart(ss);
   3.303 +	} else {
   3.304 +	    rv = SECSuccess;
   3.305 +	}
   3.306      }
   3.307  
   3.308  done:
   3.309      ssl_ReleaseSSL3HandshakeLock(ss);
   3.310      ssl_ReleaseRecvBufLock(ss);
   3.311  
   3.312      return rv;
   3.313  }
   3.314 @@ -10340,19 +10434,16 @@ ssl3_HandleFinished(sslSocket *ss, SSL3O
   3.315      }
   3.316  
   3.317  xmit_loser:
   3.318      ssl_ReleaseXmitBufLock(ss);	/*************************************/
   3.319      if (rv != SECSuccess) {
   3.320          return rv;
   3.321      }
   3.322  
   3.323 -    ss->gs.writeOffset = 0;
   3.324 -    ss->gs.readOffset  = 0;
   3.325 -
   3.326      if (ss->ssl3.hs.kea_def->kea == kea_ecdhe_rsa) {
   3.327  	effectiveExchKeyType = kt_rsa;
   3.328      } else {
   3.329  	effectiveExchKeyType = ss->ssl3.hs.kea_def->exchKeyType;
   3.330      }
   3.331  
   3.332      if (sid->cached == never_cached && !ss->opt.noCache && ss->sec.cache) {
   3.333  	/* fill in the sid */
   3.334 @@ -10407,38 +10498,38 @@ xmit_loser:
   3.335  	ss->ssl3.hs.restartTarget = ssl3_FinishHandshake;
   3.336  	return SECWouldBlock;
   3.337      }
   3.338  
   3.339      rv = ssl3_FinishHandshake(ss);
   3.340      return rv;
   3.341  }
   3.342  
   3.343 +/* The return type is SECStatus instead of void because this function needs
   3.344 + * to have type sslRestartTarget.
   3.345 + */
   3.346  SECStatus
   3.347  ssl3_FinishHandshake(sslSocket * ss)
   3.348  {
   3.349      PORT_Assert( ss->opt.noLocks || ssl_HaveRecvBufLock(ss) );
   3.350      PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss) );
   3.351      PORT_Assert( ss->ssl3.hs.restartTarget == NULL );
   3.352  
   3.353      /* The first handshake is now completed. */
   3.354      ss->handshake           = NULL;
   3.355 -    ss->firstHsDone         = PR_TRUE;
   3.356  
   3.357      if (ss->ssl3.hs.cacheSID) {
   3.358  	(*ss->sec.cache)(ss->sec.ci.sid);
   3.359  	ss->ssl3.hs.cacheSID = PR_FALSE;
   3.360      }
   3.361  
   3.362 +    ss->ssl3.hs.canFalseStart = PR_FALSE; /* False Start phase is complete */
   3.363      ss->ssl3.hs.ws = idle_handshake;
   3.364  
   3.365 -    /* Do the handshake callback for sslv3 here, if we cannot false start. */
   3.366 -    if (ss->handshakeCallback != NULL && !ssl3_CanFalseStart(ss)) {
   3.367 -	(ss->handshakeCallback)(ss->fd, ss->handshakeCallbackData);
   3.368 -    }
   3.369 +    ssl_FinishHandshake(ss);
   3.370  
   3.371      return SECSuccess;
   3.372  }
   3.373  
   3.374  /* Called from ssl3_HandleHandshake() when it has gathered a complete ssl3
   3.375   * hanshake message.
   3.376   * Caller must hold Handshake and RecvBuf locks.
   3.377   */
   3.378 @@ -11393,17 +11484,16 @@ process_it:
   3.379  	/* XXX Send an alert ???  */
   3.380  	PORT_SetError(SSL_ERROR_RX_UNKNOWN_RECORD_TYPE);
   3.381  	rv = SECFailure;
   3.382  	break;
   3.383      }
   3.384  
   3.385      ssl_ReleaseSSL3HandshakeLock(ss);
   3.386      return rv;
   3.387 -
   3.388  }
   3.389  
   3.390  /*
   3.391   * Initialization functions
   3.392   */
   3.393  
   3.394  /* Called from ssl3_InitState, immediately below. */
   3.395  /* Caller must hold the SpecWriteLock. */
     4.1 --- a/lib/ssl/ssl3gthr.c
     4.2 +++ b/lib/ssl/ssl3gthr.c
     4.3 @@ -270,21 +270,27 @@ dtls_GatherData(sslSocket *ss, sslGather
     4.4   *
     4.5   * Caller must hold the recv buf lock.
     4.6   */
     4.7  int
     4.8  ssl3_GatherCompleteHandshake(sslSocket *ss, int flags)
     4.9  {
    4.10      SSL3Ciphertext cText;
    4.11      int            rv;
    4.12 -    PRBool         canFalseStart = PR_FALSE;
    4.13 +    PRBool         keepGoing = PR_TRUE;
    4.14  
    4.15      SSL_TRC(30, ("ssl3_GatherCompleteHandshake"));
    4.16  
    4.17 +    /* ssl3_HandleRecord may end up eventually calling ssl_FinishHandshake,
    4.18 +     * which requires the 1stHandshakeLock, which must be acquired before the
    4.19 +     * RecvBufLock.
    4.20 +     */
    4.21 +    PORT_Assert( ss->opt.noLocks || ssl_Have1stHandshakeLock(ss) );
    4.22      PORT_Assert( ss->opt.noLocks || ssl_HaveRecvBufLock(ss) );
    4.23 +
    4.24      do {
    4.25  	PRBool handleRecordNow = PR_FALSE;
    4.26  
    4.27  	ssl_GetSSL3HandshakeLock(ss);
    4.28  
    4.29  	/* Without this, we may end up wrongly reporting
    4.30  	 * SSL_ERROR_RX_UNEXPECTED_* errors if we receive any records from the
    4.31  	 * peer while we are waiting to be restarted.
    4.32 @@ -359,34 +365,62 @@ ssl3_GatherCompleteHandshake(sslSocket *
    4.33  		    cText.seq_num.high <<= 8; cText.seq_num.low <<= 8;
    4.34  		    cText.seq_num.high |= ss->gs.hdr[3 + i];
    4.35  		    cText.seq_num.low |= ss->gs.hdr[7 + i];
    4.36  		}
    4.37  	    }
    4.38  
    4.39  	    cText.buf     = &ss->gs.inbuf;
    4.40  	    rv = ssl3_HandleRecord(ss, &cText, &ss->gs.buf);
    4.41 +
    4.42 +	    if (rv == (int) SECSuccess && ss->gs.buf.len > 0) {
    4.43 +		/* We have application data to return to the application. This
    4.44 +		 * prioritizes returning application data to the application over
    4.45 +		 * completing any renegotiation handshake we may be doing.
    4.46 +		 */
    4.47 +		PORT_Assert(ss->firstHsDone);
    4.48 +		PORT_Assert(cText.type == content_application_data);
    4.49 +		break;
    4.50 +	    }
    4.51  	}
    4.52  	if (rv < 0) {
    4.53  	    return ss->recvdCloseNotify ? 0 : rv;
    4.54  	}
    4.55  
    4.56 -	/* If we kicked off a false start in ssl3_HandleServerHelloDone, break
    4.57 -	 * out of this loop early without finishing the handshake.
    4.58 -	 */
    4.59 -	if (ss->opt.enableFalseStart) {
    4.60 -	    ssl_GetSSL3HandshakeLock(ss);
    4.61 -	    canFalseStart = (ss->ssl3.hs.ws == wait_change_cipher ||
    4.62 -			     ss->ssl3.hs.ws == wait_new_session_ticket) &&
    4.63 -		            ssl3_CanFalseStart(ss);
    4.64 -	    ssl_ReleaseSSL3HandshakeLock(ss);
    4.65 +	PORT_Assert(keepGoing);
    4.66 +	ssl_GetSSL3HandshakeLock(ss);
    4.67 +	if (ss->ssl3.hs.ws == idle_handshake) {
    4.68 +	    /* We are done with the current handshake so stop trying to
    4.69 +	     * handshake. Note that it would be safe to test ss->firstHsDone
    4.70 +	     * instead of ss->ssl3.hs.ws. By testing ss->ssl3.hs.ws instead,
    4.71 +	     * we prioritize completing a renegotiation handshake over sending
    4.72 +	     * application data.
    4.73 +	     */
    4.74 +	    PORT_Assert(ss->firstHsDone);
    4.75 +	    PORT_Assert(!ss->ssl3.hs.canFalseStart);
    4.76 +	    keepGoing = PR_FALSE;
    4.77 +	} else if (ss->ssl3.hs.canFalseStart) {
    4.78 +	    /* Prioritize sending application data over trying to complete
    4.79 +	     * the handshake if we're false starting.
    4.80 +	     *
    4.81 +	     * If we were to do this check at the beginning of the loop instead
    4.82 +	     * of here, then this function would become be a no-op after
    4.83 +	     * receiving the ServerHelloDone in the false start case, and we
    4.84 +	     * would never complete the handshake.
    4.85 +	     */
    4.86 +	    PORT_Assert(!ss->firstHsDone);
    4.87 +
    4.88 +	    if (ssl3_WaitingForStartOfServerSecondRound(ss)) {
    4.89 +		keepGoing = PR_FALSE;
    4.90 +	    } else {
    4.91 +		ss->ssl3.hs.canFalseStart = PR_FALSE;
    4.92 +	    }
    4.93  	}
    4.94 -    } while (ss->ssl3.hs.ws != idle_handshake &&
    4.95 -             !canFalseStart &&
    4.96 -             ss->gs.buf.len == 0);
    4.97 +	ssl_ReleaseSSL3HandshakeLock(ss);
    4.98 +    } while (keepGoing);
    4.99  
   4.100      ss->gs.readOffset = 0;
   4.101      ss->gs.writeOffset = ss->gs.buf.len;
   4.102      return 1;
   4.103  }
   4.104  
   4.105  /* Repeatedly gather in a record and when complete, Handle that record.
   4.106   * Repeat this until some application data is received.
   4.107 @@ -399,15 +433,18 @@ ssl3_GatherCompleteHandshake(sslSocket *
   4.108   * Called from DoRecv in sslsecur.c
   4.109   * Caller must hold the recv buf lock.
   4.110   */
   4.111  int
   4.112  ssl3_GatherAppDataRecord(sslSocket *ss, int flags)
   4.113  {
   4.114      int            rv;
   4.115  
   4.116 +    /* ssl3_GatherCompleteHandshake requires both of these locks. */
   4.117 +    PORT_Assert( ss->opt.noLocks || ssl_Have1stHandshakeLock(ss) );
   4.118      PORT_Assert( ss->opt.noLocks || ssl_HaveRecvBufLock(ss) );
   4.119 +
   4.120      do {
   4.121  	rv = ssl3_GatherCompleteHandshake(ss, flags);
   4.122      } while (rv > 0 && ss->gs.buf.len == 0);
   4.123  
   4.124      return rv;
   4.125  }
     5.1 --- a/lib/ssl/sslauth.c
     5.2 +++ b/lib/ssl/sslauth.c
     5.3 @@ -95,17 +95,16 @@ SSL_LocalCertificate(PRFileDesc *fd)
     5.4  /* NEED LOCKS IN HERE.  */
     5.5  SECStatus
     5.6  SSL_SecurityStatus(PRFileDesc *fd, int *op, char **cp, int *kp0, int *kp1,
     5.7  		   char **ip, char **sp)
     5.8  {
     5.9      sslSocket *ss;
    5.10      const char *cipherName;
    5.11      PRBool isDes = PR_FALSE;
    5.12 -    PRBool enoughFirstHsDone = PR_FALSE;
    5.13  
    5.14      ss = ssl_FindSocket(fd);
    5.15      if (!ss) {
    5.16  	SSL_DBG(("%d: SSL[%d]: bad socket in SecurityStatus",
    5.17  		 SSL_GETPID(), fd));
    5.18  	return SECFailure;
    5.19      }
    5.20  
    5.21 @@ -113,24 +112,17 @@ SSL_SecurityStatus(PRFileDesc *fd, int *
    5.22      if (kp0) *kp0 = 0;
    5.23      if (kp1) *kp1 = 0;
    5.24      if (ip) *ip = 0;
    5.25      if (sp) *sp = 0;
    5.26      if (op) {
    5.27  	*op = SSL_SECURITY_STATUS_OFF;
    5.28      }
    5.29  
    5.30 -    if (ss->firstHsDone) {
    5.31 -	enoughFirstHsDone = PR_TRUE;
    5.32 -    } else if (ss->version >= SSL_LIBRARY_VERSION_3_0 &&
    5.33 -	       ssl3_CanFalseStart(ss)) {
    5.34 -	enoughFirstHsDone = PR_TRUE;
    5.35 -    }
    5.36 -
    5.37 -    if (ss->opt.useSecurity && enoughFirstHsDone) {
    5.38 +    if (ss->opt.useSecurity && ss->enoughFirstHsDone) {
    5.39  	if (ss->version < SSL_LIBRARY_VERSION_3_0) {
    5.40  	    cipherName = ssl_cipherName[ss->sec.cipherType];
    5.41  	} else {
    5.42  	    cipherName = ssl3_cipherName[ss->sec.cipherType];
    5.43  	}
    5.44  	PORT_Assert(cipherName);
    5.45  	if (cipherName) {
    5.46              if (PORT_Strstr(cipherName, "DES")) isDes = PR_TRUE;
     6.1 --- a/lib/ssl/sslimpl.h
     6.2 +++ b/lib/ssl/sslimpl.h
     6.3 @@ -854,16 +854,18 @@ const ssl3CipherSuiteDef *suite_def;
     6.4      PRBool                authCertificatePending;
     6.5      /* Which function should SSL_RestartHandshake* call if we're blocked?
     6.6       * One of NULL, ssl3_SendClientSecondRound, ssl3_FinishHandshake,
     6.7       * or ssl3_AlwaysFail */
     6.8      sslRestartTarget      restartTarget;
     6.9      /* Shared state between ssl3_HandleFinished and ssl3_FinishHandshake */
    6.10      PRBool                cacheSID;
    6.11  
    6.12 +    PRBool                canFalseStart;   /* Can/did we False Start */
    6.13 +
    6.14      /* clientSigAndHash contains the contents of the signature_algorithms
    6.15       * extension (if any) from the client. This is only valid for TLS 1.2
    6.16       * or later. */
    6.17      SSL3SignatureAndHashAlgorithm *clientSigAndHash;
    6.18      unsigned int          numClientSigAndHash;
    6.19  
    6.20      /* This group of values is used for DTLS */
    6.21      PRUint16              sendMessageSeq;  /* The sending message sequence
    6.22 @@ -1128,16 +1130,20 @@ struct sslSocketStr {
    6.23      sslOptions       opt;
    6.24      /* Enabled version range */
    6.25      SSLVersionRange  vrange;
    6.26  
    6.27      /* State flags */
    6.28      unsigned long    clientAuthRequested;
    6.29      unsigned long    delayDisabled;       /* Nagle delay disabled */
    6.30      unsigned long    firstHsDone;         /* first handshake is complete. */
    6.31 +    unsigned long    enoughFirstHsDone;   /* enough of the first handshake is
    6.32 +					   * done for callbacks to be able to
    6.33 +					   * retrieve channel security
    6.34 +					   * parameters from the SSL socket. */
    6.35      unsigned long    handshakeBegun;     
    6.36      unsigned long    lastWriteBlocked;   
    6.37      unsigned long    recvdCloseNotify;    /* received SSL EOF. */
    6.38      unsigned long    TCPconnected;       
    6.39      unsigned long    appDataBuffered;
    6.40      unsigned long    peerRequestedProtection; /* from old renegotiation */
    6.41  
    6.42      /* version of the protocol to use */
    6.43 @@ -1168,16 +1174,18 @@ const unsigned char *  preferredCipher;
    6.44      SSLGetClientAuthData      getClientAuthData;
    6.45      void                     *getClientAuthDataArg;
    6.46      SSLSNISocketConfig        sniSocketConfig;
    6.47      void                     *sniSocketConfigArg;
    6.48      SSLBadCertHandler         handleBadCert;
    6.49      void                     *badCertArg;
    6.50      SSLHandshakeCallback      handshakeCallback;
    6.51      void                     *handshakeCallbackData;
    6.52 +    SSLCanFalseStartCallback  canFalseStartCallback;
    6.53 +    void                     *canFalseStartCallbackData;
    6.54      void                     *pkcs11PinArg;
    6.55      SSLNextProtoCallback      nextProtoCallback;
    6.56      void                     *nextProtoArg;
    6.57  
    6.58      PRIntervalTime            rTimeout; /* timeout for NSPR I/O */
    6.59      PRIntervalTime            wTimeout; /* timeout for NSPR I/O */
    6.60      PRIntervalTime            cTimeout; /* timeout for NSPR I/O */
    6.61  
    6.62 @@ -1370,17 +1378,29 @@ extern int       ssl3_SendApplicationDat
    6.63  extern PRBool    ssl_FdIsBlocking(PRFileDesc *fd);
    6.64  
    6.65  extern PRBool    ssl_SocketIsBlocking(sslSocket *ss);
    6.66  
    6.67  extern void      ssl3_SetAlwaysBlock(sslSocket *ss);
    6.68  
    6.69  extern SECStatus ssl_EnableNagleDelay(sslSocket *ss, PRBool enabled);
    6.70  
    6.71 -extern PRBool    ssl3_CanFalseStart(sslSocket *ss);
    6.72 +extern void      ssl_FinishHandshake(sslSocket *ss);
    6.73 +
    6.74 +/* Returns PR_TRUE if we are still waiting for the server to respond to our
    6.75 + * client second round. Once we've received any part of the server's second
    6.76 + * round then we don't bother trying to false start since it is almost always
    6.77 + * the case that the NewSessionTicket, ChangeCipherSoec, and Finished messages
    6.78 + * were sent in the same packet and we want to process them all at the same
    6.79 + * time. If we were to try to false start in the middle of the server's second
    6.80 + * round, then we would increase the number of I/O operations
    6.81 + * (SSL_ForceHandshake/PR_Recv/PR_Send/etc.) needed to finish the handshake.
    6.82 + */
    6.83 +extern PRBool    ssl3_WaitingForStartOfServerSecondRound(sslSocket *ss);
    6.84 +
    6.85  extern SECStatus
    6.86  ssl3_CompressMACEncryptRecord(ssl3CipherSpec *   cwSpec,
    6.87  		              PRBool             isServer,
    6.88  			      PRBool             isDTLS,
    6.89  			      PRBool             capRecordVersion,
    6.90                                SSL3ContentType    type,
    6.91  		              const SSL3Opaque * pIn,
    6.92  		              PRUint32           contentLen,
     7.1 --- a/lib/ssl/sslinfo.c
     7.2 +++ b/lib/ssl/sslinfo.c
     7.3 @@ -21,41 +21,33 @@ ssl_GetCompressionMethodName(SSLCompress
     7.4  }
     7.5  
     7.6  SECStatus 
     7.7  SSL_GetChannelInfo(PRFileDesc *fd, SSLChannelInfo *info, PRUintn len)
     7.8  {
     7.9      sslSocket *      ss;
    7.10      SSLChannelInfo   inf;
    7.11      sslSessionID *   sid;
    7.12 -    PRBool           enoughFirstHsDone = PR_FALSE;
    7.13  
    7.14      if (!info || len < sizeof inf.length) { 
    7.15  	PORT_SetError(SEC_ERROR_INVALID_ARGS);
    7.16  	return SECFailure;
    7.17      }
    7.18  
    7.19      ss = ssl_FindSocket(fd);
    7.20      if (!ss) {
    7.21  	SSL_DBG(("%d: SSL[%d]: bad socket in SSL_GetChannelInfo",
    7.22  		 SSL_GETPID(), fd));
    7.23  	return SECFailure;
    7.24      }
    7.25  
    7.26      memset(&inf, 0, sizeof inf);
    7.27      inf.length = PR_MIN(sizeof inf, len);
    7.28  
    7.29 -    if (ss->firstHsDone) {
    7.30 -	enoughFirstHsDone = PR_TRUE;
    7.31 -    } else if (ss->version >= SSL_LIBRARY_VERSION_3_0 &&
    7.32 -	       ssl3_CanFalseStart(ss)) {
    7.33 -	enoughFirstHsDone = PR_TRUE;
    7.34 -    }
    7.35 -
    7.36 -    if (ss->opt.useSecurity && enoughFirstHsDone) {
    7.37 +    if (ss->opt.useSecurity && ss->enoughFirstHsDone) {
    7.38          sid = ss->sec.ci.sid;
    7.39  	inf.protocolVersion  = ss->version;
    7.40  	inf.authKeyBits      = ss->sec.authKeyBits;
    7.41  	inf.keaKeyBits       = ss->sec.keaKeyBits;
    7.42  	if (ss->version < SSL_LIBRARY_VERSION_3_0) { /* SSL2 */
    7.43  	    inf.cipherSuite           = ss->sec.cipherType | 0xff00;
    7.44  	    inf.compressionMethod     = ssl_compression_null;
    7.45  	    inf.compressionMethodName = "N/A";
     8.1 --- a/lib/ssl/sslsecur.c
     8.2 +++ b/lib/ssl/sslsecur.c
     8.3 @@ -92,33 +92,23 @@ ssl_Do1stHandshake(sslSocket *ss)
     8.4  	    ss->nextHandshake = 0;
     8.5  	}
     8.6  	if (ss->handshake == 0) {
     8.7  	    /* Previous handshake finished. Switch to security handshake */
     8.8  	    ss->handshake = ss->securityHandshake;
     8.9  	    ss->securityHandshake = 0;
    8.10  	}
    8.11  	if (ss->handshake == 0) {
    8.12 -	    ssl_GetRecvBufLock(ss);
    8.13 -	    ss->gs.recordLen = 0;
    8.14 -	    ssl_ReleaseRecvBufLock(ss);
    8.15 -
    8.16 -	    SSL_TRC(3, ("%d: SSL[%d]: handshake is completed",
    8.17 -			SSL_GETPID(), ss->fd));
    8.18 -            /* call handshake callback for ssl v2 */
    8.19 -	    /* for v3 this is done in ssl3_HandleFinished() */
    8.20 -	    if ((ss->handshakeCallback != NULL) && /* has callback */
    8.21 -		(!ss->firstHsDone) &&              /* only first time */
    8.22 -		(ss->version < SSL_LIBRARY_VERSION_3_0)) {  /* not ssl3 */
    8.23 -		ss->firstHsDone     = PR_TRUE;
    8.24 -		(ss->handshakeCallback)(ss->fd, ss->handshakeCallbackData);
    8.25 +	    /* for v3 this is done in ssl3_FinishHandshake */
    8.26 +	    if (!ss->firstHsDone && ss->version < SSL_LIBRARY_VERSION_3_0) {
    8.27 +		ssl_GetRecvBufLock(ss);
    8.28 +		ss->gs.recordLen = 0;
    8.29 +		ssl_FinishHandshake(ss);
    8.30 +		ssl_ReleaseRecvBufLock(ss);
    8.31  	    }
    8.32 -	    ss->firstHsDone         = PR_TRUE;
    8.33 -	    ss->gs.writeOffset = 0;
    8.34 -	    ss->gs.readOffset  = 0;
    8.35  	    break;
    8.36  	}
    8.37  	rv = (*ss->handshake)(ss);
    8.38  	++loopCount;
    8.39      /* This code must continue to loop on SECWouldBlock, 
    8.40       * or any positive value.	See XXX_1 comments.
    8.41       */
    8.42      } while (rv != SECFailure);  	/* was (rv >= 0); XXX_1 */
    8.43 @@ -129,16 +119,34 @@ ssl_Do1stHandshake(sslSocket *ss)
    8.44  
    8.45      if (rv == SECWouldBlock) {
    8.46  	PORT_SetError(PR_WOULD_BLOCK_ERROR);
    8.47  	rv = SECFailure;
    8.48      }
    8.49      return rv;
    8.50  }
    8.51  
    8.52 +void
    8.53 +ssl_FinishHandshake(sslSocket *ss)
    8.54 +{
    8.55 +    PORT_Assert( ss->opt.noLocks || ssl_Have1stHandshakeLock(ss) );
    8.56 +    PORT_Assert( ss->opt.noLocks || ssl_HaveRecvBufLock(ss) );
    8.57 +
    8.58 +    SSL_TRC(3, ("%d: SSL[%d]: handshake is completed", SSL_GETPID(), ss->fd));
    8.59 +
    8.60 +    ss->firstHsDone = PR_TRUE;
    8.61 +    ss->enoughFirstHsDone = PR_TRUE;
    8.62 +    ss->gs.writeOffset = 0;
    8.63 +    ss->gs.readOffset  = 0;
    8.64 +
    8.65 +    if (ss->handshakeCallback) {
    8.66 +	(ss->handshakeCallback)(ss->fd, ss->handshakeCallbackData);
    8.67 +    }
    8.68 +}
    8.69 +
    8.70  /*
    8.71   * Handshake function that blocks.  Used to force a
    8.72   * retry on a connection on the next read/write.
    8.73   */
    8.74  static SECStatus
    8.75  ssl3_AlwaysBlock(sslSocket *ss)
    8.76  {
    8.77      PORT_SetError(PR_WOULD_BLOCK_ERROR);	/* perhaps redundant. */
    8.78 @@ -201,31 +209,34 @@ SSL_ResetHandshake(PRFileDesc *s, PRBool
    8.79  
    8.80      SSL_LOCK_READER(ss);
    8.81      SSL_LOCK_WRITER(ss);
    8.82  
    8.83      /* Reset handshake state */
    8.84      ssl_Get1stHandshakeLock(ss);
    8.85  
    8.86      ss->firstHsDone = PR_FALSE;
    8.87 +    ss->enoughFirstHsDone = PR_FALSE;
    8.88      if ( asServer ) {
    8.89  	ss->handshake = ssl2_BeginServerHandshake;
    8.90  	ss->handshaking = sslHandshakingAsServer;
    8.91      } else {
    8.92  	ss->handshake = ssl2_BeginClientHandshake;
    8.93  	ss->handshaking = sslHandshakingAsClient;
    8.94      }
    8.95      ss->nextHandshake       = 0;
    8.96      ss->securityHandshake   = 0;
    8.97  
    8.98      ssl_GetRecvBufLock(ss);
    8.99      status = ssl_InitGather(&ss->gs);
   8.100      ssl_ReleaseRecvBufLock(ss);
   8.101  
   8.102      ssl_GetSSL3HandshakeLock(ss);
   8.103 +    ss->ssl3.hs.canFalseStart = PR_FALSE;
   8.104 +    ss->ssl3.hs.restartTarget = NULL;
   8.105  
   8.106      /*
   8.107      ** Blow away old security state and get a fresh setup.
   8.108      */
   8.109      ssl_GetXmitBufLock(ss); 
   8.110      ssl_ResetSecurityInfo(&ss->sec, PR_TRUE);
   8.111      status = ssl_CreateSecurityInfo(ss);
   8.112      ssl_ReleaseXmitBufLock(ss); 
   8.113 @@ -326,16 +337,81 @@ SSL_HandshakeCallback(PRFileDesc *fd, SS
   8.114      ss->handshakeCallbackData = client_data;
   8.115  
   8.116      ssl_ReleaseSSL3HandshakeLock(ss);
   8.117      ssl_Release1stHandshakeLock(ss);
   8.118  
   8.119      return SECSuccess;
   8.120  }
   8.121  
   8.122 +/* Register an application callback to be called when false start may happen.
   8.123 +** Acquires and releases HandshakeLock.
   8.124 +*/
   8.125 +SECStatus
   8.126 +SSL_SetCanFalseStartCallback(PRFileDesc *fd, SSLCanFalseStartCallback cb,
   8.127 +			     void *arg)
   8.128 +{
   8.129 +    sslSocket *ss;
   8.130 +
   8.131 +    ss = ssl_FindSocket(fd);
   8.132 +    if (!ss) {
   8.133 +	SSL_DBG(("%d: SSL[%d]: bad socket in SSL_SetCanFalseStartCallback",
   8.134 +		 SSL_GETPID(), fd));
   8.135 +	return SECFailure;
   8.136 +    }
   8.137 +
   8.138 +    if (!ss->opt.useSecurity) {
   8.139 +	PORT_SetError(SEC_ERROR_INVALID_ARGS);
   8.140 +	return SECFailure;
   8.141 +    }
   8.142 +
   8.143 +    ssl_Get1stHandshakeLock(ss);
   8.144 +    ssl_GetSSL3HandshakeLock(ss);
   8.145 +
   8.146 +    ss->canFalseStartCallback     = cb;
   8.147 +    ss->canFalseStartCallbackData = arg;
   8.148 +
   8.149 +    ssl_ReleaseSSL3HandshakeLock(ss);
   8.150 +    ssl_Release1stHandshakeLock(ss);
   8.151 +
   8.152 +    return SECSuccess;
   8.153 +}
   8.154 +
   8.155 +SECStatus
   8.156 +SSL_RecommendedCanFalseStart(PRFileDesc *fd, PRBool *canFalseStart)
   8.157 +{
   8.158 +    sslSocket *ss;
   8.159 +
   8.160 +    *canFalseStart = PR_FALSE;
   8.161 +    ss = ssl_FindSocket(fd);
   8.162 +    if (!ss) {
   8.163 +	SSL_DBG(("%d: SSL[%d]: bad socket in SSL_RecommendedCanFalseStart",
   8.164 +		 SSL_GETPID(), fd));
   8.165 +	return SECFailure;
   8.166 +    }
   8.167 +
   8.168 +    if (!ss->ssl3.initialized) {
   8.169 +	PORT_SetError(SEC_ERROR_INVALID_ARGS);
   8.170 +	return SECFailure;
   8.171 +    }
   8.172 +
   8.173 +    if (ss->version < SSL_LIBRARY_VERSION_3_0) {
   8.174 +	PORT_SetError(SSL_ERROR_FEATURE_NOT_SUPPORTED_FOR_SSL2);
   8.175 +	return SECFailure;
   8.176 +    }
   8.177 +
   8.178 +    /* Require a forward-secret key exchange. */
   8.179 +    *canFalseStart = ss->ssl3.hs.kea_def->kea == kea_dhe_dss ||
   8.180 +		     ss->ssl3.hs.kea_def->kea == kea_dhe_rsa ||
   8.181 +		     ss->ssl3.hs.kea_def->kea == kea_ecdhe_ecdsa ||
   8.182 +		     ss->ssl3.hs.kea_def->kea == kea_ecdhe_rsa;
   8.183 +
   8.184 +    return SECSuccess;
   8.185 +}
   8.186 +
   8.187  /* Try to make progress on an SSL handshake by attempting to read the 
   8.188  ** next handshake from the peer, and sending any responses.
   8.189  ** For non-blocking sockets, returns PR_ERROR_WOULD_BLOCK  if it cannot 
   8.190  ** read the next handshake from the underlying socket.
   8.191  ** For SSLv2, returns when handshake is complete or fatal error occurs.
   8.192  ** For SSLv3, returns when handshake is complete, or application data has
   8.193  ** arrived that must be taken by application before handshake can continue, 
   8.194  ** or a fatal error occurs.
   8.195 @@ -519,16 +595,19 @@ ssl_SendSavedWriteData(sslSocket *ss)
   8.196  */
   8.197  static int 
   8.198  DoRecv(sslSocket *ss, unsigned char *out, int len, int flags)
   8.199  {
   8.200      int              rv;
   8.201      int              amount;
   8.202      int              available;
   8.203  
   8.204 +    /* ssl3_GatherAppDataRecord may call ssl_FinishHandshake, which needs the
   8.205 +     * 1stHandshakeLock. */
   8.206 +    ssl_Get1stHandshakeLock(ss);
   8.207      ssl_GetRecvBufLock(ss);
   8.208  
   8.209      available = ss->gs.writeOffset - ss->gs.readOffset;
   8.210      if (available == 0) {
   8.211  	/* Get some more data */
   8.212  	if (ss->version >= SSL_LIBRARY_VERSION_3_0) {
   8.213  	    /* Wait for application data to arrive.  */
   8.214  	    rv = ssl3_GatherAppDataRecord(ss, 0);
   8.215 @@ -585,16 +664,17 @@ DoRecv(sslSocket *ss, unsigned char *out
   8.216      rv = amount;
   8.217  
   8.218      SSL_TRC(30, ("%d: SSL[%d]: amount=%d available=%d",
   8.219  		 SSL_GETPID(), ss->fd, amount, available));
   8.220      PRINT_BUF(4, (ss, "DoRecv receiving plaintext:", out, amount));
   8.221  
   8.222  done:
   8.223      ssl_ReleaseRecvBufLock(ss);
   8.224 +    ssl_Release1stHandshakeLock(ss);
   8.225      return rv;
   8.226  }
   8.227  
   8.228  /************************************************************************/
   8.229  
   8.230  /*
   8.231  ** Return SSLKEAType derived from cert's Public Key algorithm info.
   8.232  */
   8.233 @@ -1151,17 +1231,18 @@ ssl_SecureRead(sslSocket *ss, unsigned c
   8.234  {
   8.235      return ssl_SecureRecv(ss, buf, len, 0);
   8.236  }
   8.237  
   8.238  /* Caller holds the SSL Socket's write lock. SSL_LOCK_WRITER(ss) */
   8.239  int
   8.240  ssl_SecureSend(sslSocket *ss, const unsigned char *buf, int len, int flags)
   8.241  {
   8.242 -    int              rv		= 0;
   8.243 +    int rv = 0;
   8.244 +    PRBool falseStart = PR_FALSE;
   8.245  
   8.246      SSL_TRC(2, ("%d: SSL[%d]: SecureSend: sending %d bytes",
   8.247  		SSL_GETPID(), ss->fd, len));
   8.248  
   8.249      if (ss->shutdownHow & ssl_SHUTDOWN_SEND) {
   8.250  	PORT_SetError(PR_SOCKET_SHUTDOWN_ERROR);
   8.251      	rv = PR_FAILURE;
   8.252  	goto done;
   8.253 @@ -1186,29 +1267,24 @@ ssl_SecureSend(sslSocket *ss, const unsi
   8.254      if (rv < 0) {
   8.255  	goto done;
   8.256      }
   8.257  
   8.258      if (len > 0) 
   8.259      	ss->writerThread = PR_GetCurrentThread();
   8.260      /* If any of these is non-zero, the initial handshake is not done. */
   8.261      if (!ss->firstHsDone) {
   8.262 -	PRBool canFalseStart = PR_FALSE;
   8.263  	ssl_Get1stHandshakeLock(ss);
   8.264 -	if (ss->version >= SSL_LIBRARY_VERSION_3_0) {
   8.265 +	if (ss->opt.enableFalseStart &&
   8.266 +	    ss->version >= SSL_LIBRARY_VERSION_3_0) {
   8.267  	    ssl_GetSSL3HandshakeLock(ss);
   8.268 -	    if ((ss->ssl3.hs.ws == wait_change_cipher ||
   8.269 -		ss->ssl3.hs.ws == wait_finished ||
   8.270 -		ss->ssl3.hs.ws == wait_new_session_ticket) &&
   8.271 -		ssl3_CanFalseStart(ss)) {
   8.272 -		canFalseStart = PR_TRUE;
   8.273 -	    }
   8.274 +	    falseStart = ss->ssl3.hs.canFalseStart;
   8.275  	    ssl_ReleaseSSL3HandshakeLock(ss);
   8.276  	}
   8.277 -	if (!canFalseStart &&
   8.278 +	if (!falseStart &&
   8.279  	    (ss->handshake || ss->nextHandshake || ss->securityHandshake)) {
   8.280  	    rv = ssl_Do1stHandshake(ss);
   8.281  	}
   8.282  	ssl_Release1stHandshakeLock(ss);
   8.283      }
   8.284      if (rv < 0) {
   8.285      	ss->writerThread = NULL;
   8.286  	goto done;
   8.287 @@ -1223,16 +1299,27 @@ ssl_SecureSend(sslSocket *ss, const unsi
   8.288      }
   8.289      PORT_Assert(buf != NULL);
   8.290      if (!buf) {
   8.291  	PORT_SetError(PR_INVALID_ARGUMENT_ERROR);
   8.292      	rv = PR_FAILURE;
   8.293  	goto done;
   8.294      }
   8.295  
   8.296 +    if (!ss->firstHsDone) {
   8.297 +	PORT_Assert(ss->version >= SSL_LIBRARY_VERSION_3_0);
   8.298 +#ifdef DEBUG
   8.299 +	ssl_GetSSL3HandshakeLock(ss);
   8.300 +	PORT_Assert(ss->ssl3.hs.canFalseStart);
   8.301 +	ssl_ReleaseSSL3HandshakeLock(ss);
   8.302 +#endif
   8.303 +	SSL_TRC(3, ("%d: SSL[%d]: SecureSend: sending data due to false start",
   8.304 +		    SSL_GETPID(), ss->fd));
   8.305 +    }
   8.306 +
   8.307      /* Send out the data using one of these functions:
   8.308       *	ssl2_SendClear, ssl2_SendStream, ssl2_SendBlock, 
   8.309       *  ssl3_SendApplicationData
   8.310       */
   8.311      ssl_GetXmitBufLock(ss);
   8.312      rv = (*ss->sec.send)(ss, buf, len, flags);
   8.313      ssl_ReleaseXmitBufLock(ss);
   8.314      ss->writerThread = NULL;
     9.1 --- a/lib/ssl/sslsock.c
     9.2 +++ b/lib/ssl/sslsock.c
     9.3 @@ -262,16 +262,18 @@ ssl_DupSocket(sslSocket *os)
     9.4  	    ss->getClientAuthData     = os->getClientAuthData;
     9.5  	    ss->getClientAuthDataArg  = os->getClientAuthDataArg;
     9.6              ss->sniSocketConfig       = os->sniSocketConfig;
     9.7              ss->sniSocketConfigArg    = os->sniSocketConfigArg;
     9.8  	    ss->handleBadCert         = os->handleBadCert;
     9.9  	    ss->badCertArg            = os->badCertArg;
    9.10  	    ss->handshakeCallback     = os->handshakeCallback;
    9.11  	    ss->handshakeCallbackData = os->handshakeCallbackData;
    9.12 +	    ss->canFalseStartCallback = os->canFalseStartCallback;
    9.13 +	    ss->canFalseStartCallbackData = os->canFalseStartCallbackData;
    9.14  	    ss->pkcs11PinArg          = os->pkcs11PinArg;
    9.15      
    9.16  	    /* Create security data */
    9.17  	    rv = ssl_CopySecurityInfo(ss, os);
    9.18  	    if (rv != SECSuccess) {
    9.19  		goto loser;
    9.20  	    }
    9.21  	}
    9.22 @@ -2254,20 +2256,24 @@ ssl_Poll(PRFileDesc *fd, PRInt16 how_fla
    9.23  		    ** The code should select on write, not read.
    9.24  		    */
    9.25  		    new_flags ^=  PR_POLL_READ;	   /* don't select on read. */
    9.26  		    new_flags |=  PR_POLL_WRITE;   /* do    select on write. */
    9.27  		}
    9.28  	    } else if (new_flags & PR_POLL_WRITE) {
    9.29  		    /* The caller is trying to write, but the handshake is 
    9.30  		    ** blocked waiting for data to read, and the first 
    9.31 -		    ** handshake has been sent.  so do NOT to poll on write.
    9.32 +		    ** handshake has been sent.  So do NOT to poll on write
    9.33 +		    ** unless we did false start.
    9.34  		    */
    9.35 -		    new_flags ^=  PR_POLL_WRITE;   /* don't select on write. */
    9.36 -		    new_flags |=  PR_POLL_READ;	   /* do    select on read. */
    9.37 +		    if (!(ss->version >= SSL_LIBRARY_VERSION_3_0 &&
    9.38 +			ss->ssl3.hs.canFalseStart)) {
    9.39 +			new_flags ^= PR_POLL_WRITE; /* don't select on write. */
    9.40 +		    }
    9.41 +		    new_flags |= PR_POLL_READ;      /* do    select on read. */
    9.42  	    }
    9.43  	}
    9.44      } else if ((new_flags & PR_POLL_READ) && (SSL_DataPending(fd) > 0)) {
    9.45  	*p_out_flags = PR_POLL_READ;	/* it's ready already. */
    9.46  	return new_flags;
    9.47      } else if ((ss->lastWriteBlocked) && (how_flags & PR_POLL_READ) &&
    9.48  	       (ss->pendingBuf.len != 0)) { /* write data waiting to be sent */
    9.49  	new_flags |=  PR_POLL_WRITE;   /* also select on write. */