Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(769)

Unified Diff: net/third_party/nss/ssl/sslsecur.c

Issue 27254004: Make SSL False Start work with asynchronous certificate validation (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: Resolve merge conflict in ssl3_SendClientSecondRound Created 7 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: net/third_party/nss/ssl/sslsecur.c
===================================================================
--- net/third_party/nss/ssl/sslsecur.c (revision 227672)
+++ net/third_party/nss/ssl/sslsecur.c (working copy)
@@ -97,23 +97,13 @@
ss->securityHandshake = 0;
}
if (ss->handshake == 0) {
- ssl_GetRecvBufLock(ss);
- ss->gs.recordLen = 0;
- ssl_ReleaseRecvBufLock(ss);
-
- SSL_TRC(3, ("%d: SSL[%d]: handshake is completed",
- SSL_GETPID(), ss->fd));
- /* call handshake callback for ssl v2 */
- /* for v3 this is done in ssl3_HandleFinished() */
- if ((ss->handshakeCallback != NULL) && /* has callback */
- (!ss->firstHsDone) && /* only first time */
- (ss->version < SSL_LIBRARY_VERSION_3_0)) { /* not ssl3 */
- ss->firstHsDone = PR_TRUE;
- (ss->handshakeCallback)(ss->fd, ss->handshakeCallbackData);
+ /* for v3 this is done in ssl3_FinishHandshake */
+ if (!ss->firstHsDone && ss->version < SSL_LIBRARY_VERSION_3_0) {
+ ssl_GetRecvBufLock(ss);
+ ss->gs.recordLen = 0;
+ ssl_ReleaseRecvBufLock(ss);
wtc 2013/10/17 00:10:53 Why do we only need to set ss->gs.recordLen to 0 f
briansmith 2013/10/17 01:42:40 recordLen is only used for SSL 2.0: unsigned int
+ ssl_FinishHandshake(ss);
}
- ss->firstHsDone = PR_TRUE;
- ss->gs.writeOffset = 0;
- ss->gs.readOffset = 0;
break;
}
rv = (*ss->handshake)(ss);
@@ -134,6 +124,23 @@
return rv;
}
+void
+ssl_FinishHandshake(sslSocket *ss)
wtc 2013/10/17 00:10:53 Should we move this function to sslcon.c, since it
briansmith 2013/10/17 01:42:40 This is not SSL-2.0-only. This is the functionalit
+{
+ PORT_Assert( ss->opt.noLocks || ssl_Have1stHandshakeLock(ss) );
briansmith 2013/10/17 19:09:01 Wan-Teh, do you agree that this assertion is corre
wtc 2013/10/17 23:13:01 This seems very reasonable, but I didn't find this
+
+ SSL_TRC(3, ("%d: SSL[%d]: handshake is completed", SSL_GETPID(), ss->fd));
+
+ ss->firstHsDone = PR_TRUE;
+ ss->enoughFirstHsDone = PR_TRUE;
+ ss->gs.writeOffset = 0;
+ ss->gs.readOffset = 0;
+
+ if (ss->handshakeCallback) {
+ (ss->handshakeCallback)(ss->fd, ss->handshakeCallbackData);
+ }
+}
+
/*
* Handshake function that blocks. Used to force a
* retry on a connection on the next read/write.
@@ -206,6 +213,7 @@
ssl_Get1stHandshakeLock(ss);
ss->firstHsDone = PR_FALSE;
+ ss->enoughFirstHsDone = PR_FALSE;
if ( asServer ) {
ss->handshake = ssl2_BeginServerHandshake;
ss->handshaking = sslHandshakingAsServer;
@@ -221,6 +229,8 @@
ssl_ReleaseRecvBufLock(ss);
ssl_GetSSL3HandshakeLock(ss);
+ ss->ssl3.hs.canFalseStart = PR_FALSE;
+ ss->ssl3.hs.restartTarget = NULL;
/*
** Blow away old security state and get a fresh setup.
@@ -331,6 +341,71 @@
return SECSuccess;
}
+/* Register an application callback to be called when false start may happen.
+** Acquires and releases HandshakeLock.
+*/
+SECStatus
+SSL_SetCanFalseStartCallback(PRFileDesc *fd, SSLCanFalseStartCallback cb,
+ void *client_data)
+{
+ sslSocket *ss;
+
+ ss = ssl_FindSocket(fd);
+ if (!ss) {
+ SSL_DBG(("%d: SSL[%d]: bad socket in SSL_SetCanFalseStartCallback",
+ SSL_GETPID(), fd));
+ return SECFailure;
+ }
+
+ if (!ss->opt.useSecurity) {
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ return SECFailure;
+ }
+
+ ssl_Get1stHandshakeLock(ss);
+ ssl_GetSSL3HandshakeLock(ss);
+
+ ss->canFalseStartCallback = cb;
+ ss->canFalseStartCallbackData = client_data;
+
+ ssl_ReleaseSSL3HandshakeLock(ss);
+ ssl_Release1stHandshakeLock(ss);
+
+ return SECSuccess;
+}
+
+SECStatus
+SSL_RecommendedCanFalseStart(PRFileDesc *fd, PRBool *canFalseStart)
+{
+ sslSocket *ss;
+
+ *canFalseStart = PR_FALSE;
+ ss = ssl_FindSocket(fd);
+ if (!ss) {
+ SSL_DBG(("%d: SSL[%d]: bad socket in SSL_DefaultCanFalseStart",
wtc 2013/10/17 00:10:53 SSL_DefaultCanFalseStart => SSL_RecommendedCanFals
briansmith 2013/10/17 01:42:40 Done.
+ SSL_GETPID(), fd));
+ return SECFailure;
+ }
+
+ if (!ss->ssl3.initialized) {
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ return SECFailure;
+ }
+
+ if (ss->version < SSL_LIBRARY_VERSION_3_0) {
+ PORT_SetError(SSL_ERROR_FEATURE_NOT_SUPPORTED_FOR_SSL2);
+ return SECFailure;
+ }
+
+ /* Require a forward-secret key exchange. */
+ *canFalseStart = ss->ssl3.hs.kea_def->kea == kea_dhe_dss ||
+ ss->ssl3.hs.kea_def->kea == kea_dhe_rsa ||
+ ss->ssl3.hs.kea_def->kea == kea_ecdhe_ecdsa ||
+ ss->ssl3.hs.kea_def->kea == kea_ecdhe_rsa;
+
+ return SECSuccess;
+}
+
/* Try to make progress on an SSL handshake by attempting to read the
** next handshake from the peer, and sending any responses.
** For non-blocking sockets, returns PR_ERROR_WOULD_BLOCK if it cannot
@@ -524,6 +599,7 @@
int amount;
int available;
+ ssl_Get1stHandshakeLock(ss);
wtc 2013/10/17 00:10:53 Why does DoRecv() need to get the 1stHandshakeLock
briansmith 2013/10/17 01:42:40 It calls ssl3_GatherAppDataRecord and ssl3_GatherA
wtc 2013/10/17 15:28:14 I'm sorry that I still don't understand this. Coul
ssl_GetRecvBufLock(ss);
available = ss->gs.writeOffset - ss->gs.readOffset;
@@ -590,6 +666,7 @@
done:
ssl_ReleaseRecvBufLock(ss);
+ ssl_Release1stHandshakeLock(ss);
return rv;
}
@@ -1156,7 +1233,8 @@
int
ssl_SecureSend(sslSocket *ss, const unsigned char *buf, int len, int flags)
{
- int rv = 0;
+ int rv = 0;
+ PRBool falseStart = PR_FALSE;
SSL_TRC(2, ("%d: SSL[%d]: SecureSend: sending %d bytes",
SSL_GETPID(), ss->fd, len));
@@ -1191,19 +1269,14 @@
ss->writerThread = PR_GetCurrentThread();
/* If any of these is non-zero, the initial handshake is not done. */
if (!ss->firstHsDone) {
- PRBool canFalseStart = PR_FALSE;
ssl_Get1stHandshakeLock(ss);
- if (ss->version >= SSL_LIBRARY_VERSION_3_0) {
+ if (ss->opt.enableFalseStart &&
wtc 2013/10/17 00:10:53 Why do you check ss->opt.enableFalseStart? I gues
briansmith 2013/10/17 01:42:40 Yes
+ ss->version >= SSL_LIBRARY_VERSION_3_0) {
ssl_GetSSL3HandshakeLock(ss);
- if ((ss->ssl3.hs.ws == wait_change_cipher ||
- ss->ssl3.hs.ws == wait_finished ||
- ss->ssl3.hs.ws == wait_new_session_ticket) &&
- ssl3_CanFalseStart(ss)) {
- canFalseStart = PR_TRUE;
- }
+ falseStart = ss->ssl3.hs.canFalseStart;
ssl_ReleaseSSL3HandshakeLock(ss);
}
- if (!canFalseStart &&
+ if (!falseStart &&
(ss->handshake || ss->nextHandshake || ss->securityHandshake)) {
wtc 2013/10/17 15:28:14 Hmm... If we false started, ss->handshake etc. sho
rv = ssl_Do1stHandshake(ss);
}
@@ -1228,6 +1301,21 @@
goto done;
}
+ if (ssl_trace >= 2 &&
+ !ss->firstHsDone && !falseStart &&
+ ss->opt.enableFalseStart && ss->version >= SSL_LIBRARY_VERSION_3_0) {
+ /* We need to check ss->ssl3.hs.canFalseStart again in case we called
+ * ssl_Do1stHandshake, because ssl_Do1stHandshake might have changed
+ * it.
+ */
+ ssl_GetSSL3HandshakeLock(ss);
+ falseStart = ss->ssl3.hs.canFalseStart;
+ ssl_ReleaseSSL3HandshakeLock(ss);
wtc 2013/10/17 00:10:53 falseStart is set here but never used again. So li
briansmith 2013/10/17 01:42:40 You are right that this complicated code can be de
+
+ SSL_TRC(2, ("%d: SSL[%d]: SecureSend: sending data due to false start",
+ SSL_GETPID(), ss->fd));
+ }
+
/* Send out the data using one of these functions:
* ssl2_SendClear, ssl2_SendStream, ssl2_SendBlock,
* ssl3_SendApplicationData

Powered by Google App Engine
This is Rietveld 408576698