Skip to content

Instantly share code, notes, and snippets.

@agl
Created October 15, 2009 23:03
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save agl/211370 to your computer and use it in GitHub Desktop.
Save agl/211370 to your computer and use it in GitHub Desktop.
diff --git a/mozilla/security/nss/lib/ssl/ssl.h b/mozilla/security/nss/lib/ssl/ssl.h
index 3026b48..94935a0 100644
--- a/mozilla/security/nss/lib/ssl/ssl.h
+++ b/mozilla/security/nss/lib/ssl/ssl.h
@@ -97,40 +97,42 @@ SSL_IMPORT PRFileDesc *SSL_ImportFD(PRFileDesc *model, PRFileDesc *fd);
#define SSL_ENABLE_SSL2 7 /* enable ssl v2 (on by default) */
#define SSL_ENABLE_SSL3 8 /* enable ssl v3 (on by default) */
#define SSL_NO_CACHE 9 /* don't use the session cache */
/* (off by default) */
#define SSL_REQUIRE_CERTIFICATE 10 /* (SSL_REQUIRE_FIRST_HANDSHAKE */
/* by default) */
#define SSL_ENABLE_FDX 11 /* permit simultaneous read/write */
/* (off by default) */
#define SSL_V2_COMPATIBLE_HELLO 12 /* send v3 client hello in v2 fmt */
/* (on by default) */
#define SSL_ENABLE_TLS 13 /* enable TLS (on by default) */
#define SSL_ROLLBACK_DETECTION 14 /* for compatibility, default: on */
#define SSL_NO_STEP_DOWN 15 /* Disable export cipher suites */
/* if step-down keys are needed. */
/* default: off, generate */
/* step-down keys if needed. */
#define SSL_BYPASS_PKCS11 16 /* use PKCS#11 for pub key only */
#define SSL_NO_LOCKS 17 /* Don't use locks for protection */
#define SSL_ENABLE_SESSION_TICKETS 18 /* Enable TLS SessionTicket */
/* extension (off by default) */
+#define SSL_ENABLE_CUT_THROUGH 19 /* Enable TLS cut through (off by */
+ /* default) */
#ifdef SSL_DEPRECATED_FUNCTION
/* Old deprecated function names */
SSL_IMPORT SECStatus SSL_Enable(PRFileDesc *fd, int option, PRBool on);
SSL_IMPORT SECStatus SSL_EnableDefault(int option, PRBool on);
#endif
/* New function names */
SSL_IMPORT SECStatus SSL_OptionSet(PRFileDesc *fd, PRInt32 option, PRBool on);
SSL_IMPORT SECStatus SSL_OptionGet(PRFileDesc *fd, PRInt32 option, PRBool *on);
SSL_IMPORT SECStatus SSL_OptionSetDefault(PRInt32 option, PRBool on);
SSL_IMPORT SECStatus SSL_OptionGetDefault(PRInt32 option, PRBool *on);
SSL_IMPORT SECStatus SSL_CertDBHandleSet(PRFileDesc *fd, CERTCertDBHandle *dbHandle);
/*
** Control ciphers that SSL uses. If on is non-zero then the named cipher
** is enabled, otherwise it is disabled.
** The "cipher" values are defined in sslproto.h (the SSL_EN_* values).
** EnableCipher records user preferences.
** SetPolicy sets the policy according to the policy module.
diff --git a/mozilla/security/nss/lib/ssl/ssl3con.c b/mozilla/security/nss/lib/ssl/ssl3con.c
index 7f332e9..0c70beb 100644
--- a/mozilla/security/nss/lib/ssl/ssl3con.c
+++ b/mozilla/security/nss/lib/ssl/ssl3con.c
@@ -5389,40 +5389,42 @@ ssl3_HandleServerHelloDone(sslSocket *ss)
rv = ssl3_SendClientKeyExchange(ss);
if (rv != SECSuccess) {
goto loser; /* err is set. */
}
if (send_verify) {
rv = ssl3_SendCertificateVerify(ss);
if (rv != SECSuccess) {
goto loser; /* err is set. */
}
}
rv = ssl3_SendChangeCipherSpecs(ss);
if (rv != SECSuccess) {
goto loser; /* err code was set. */
}
rv = ssl3_SendFinished(ss, 0);
if (rv != SECSuccess) {
goto loser; /* err code was set. */
}
+ ss->finishedSent = 1;
+
ssl_ReleaseXmitBufLock(ss); /*******************************/
if (ssl3_ExtensionNegotiated(ss, session_ticket_xtn))
ss->ssl3.hs.ws = wait_new_session_ticket;
else
ss->ssl3.hs.ws = wait_change_cipher;
return SECSuccess;
loser:
ssl_ReleaseXmitBufLock(ss);
return rv;
}
/*
* Routines used by servers
*/
static SECStatus
ssl3_SendHelloRequest(sslSocket *ss)
{
SECStatus rv;
diff --git a/mozilla/security/nss/lib/ssl/ssl3gthr.c b/mozilla/security/nss/lib/ssl/ssl3gthr.c
index bdd2958..432aacb 100644
--- a/mozilla/security/nss/lib/ssl/ssl3gthr.c
+++ b/mozilla/security/nss/lib/ssl/ssl3gthr.c
@@ -190,41 +190,44 @@ ssl3_GatherCompleteHandshake(sslSocket *ss, int flags)
int rv;
PORT_Assert( ss->opt.noLocks || ssl_HaveRecvBufLock(ss) );
do {
/* bring in the next sslv3 record. */
rv = ssl3_GatherData(ss, &ss->gs, flags);
if (rv <= 0) {
return rv;
}
/* decipher it, and handle it if it's a handshake.
* If it's application data, ss->gs.buf will not be empty upon return.
*/
cText.type = (SSL3ContentType)ss->gs.hdr[0];
cText.version = (ss->gs.hdr[1] << 8) | ss->gs.hdr[2];
cText.buf = &ss->gs.inbuf;
rv = ssl3_HandleRecord(ss, &cText, &ss->gs.buf);
if (rv < 0) {
return ss->recvdCloseNotify ? 0 : rv;
}
- } while (ss->ssl3.hs.ws != idle_handshake && ss->gs.buf.len == 0);
+ } while (ss->ssl3.hs.ws != idle_handshake &&
+ (!ss->opt.enableCutThrough ||
+ ss->ssl3.hs.ws != wait_change_cipher) &&
+ ss->gs.buf.len == 0);
ss->gs.readOffset = 0;
ss->gs.writeOffset = ss->gs.buf.len;
return 1;
}
/* Repeatedly gather in a record and when complete, Handle that record.
* Repeat this until some application data is received.
*
* Returns 1 when application data is available.
* Returns 0 if ssl3_GatherData hits EOF.
* Returns -1 on read error, or PR_WOULD_BLOCK_ERROR, or handleRecord error.
* Returns -2 on SECWouldBlock return from ssl3_HandleRecord.
*
* Called from DoRecv in sslsecur.c
* Caller must hold the recv buf lock.
*/
int
ssl3_GatherAppDataRecord(sslSocket *ss, int flags)
{
diff --git a/mozilla/security/nss/lib/ssl/sslimpl.h b/mozilla/security/nss/lib/ssl/sslimpl.h
index cae46a9..1185c93 100644
--- a/mozilla/security/nss/lib/ssl/sslimpl.h
+++ b/mozilla/security/nss/lib/ssl/sslimpl.h
@@ -317,40 +317,41 @@ typedef struct {
#endif /* NSS_ENABLE_ECC */
typedef struct sslOptionsStr {
unsigned int useSecurity : 1; /* 1 */
unsigned int useSocks : 1; /* 2 */
unsigned int requestCertificate : 1; /* 3 */
unsigned int requireCertificate : 2; /* 4-5 */
unsigned int handshakeAsClient : 1; /* 6 */
unsigned int handshakeAsServer : 1; /* 7 */
unsigned int enableSSL2 : 1; /* 8 */
unsigned int enableSSL3 : 1; /* 9 */
unsigned int enableTLS : 1; /* 10 */
unsigned int noCache : 1; /* 11 */
unsigned int fdx : 1; /* 12 */
unsigned int v2CompatibleHello : 1; /* 13 */
unsigned int detectRollBack : 1; /* 14 */
unsigned int noStepDown : 1; /* 15 */
unsigned int bypassPKCS11 : 1; /* 16 */
unsigned int noLocks : 1; /* 17 */
unsigned int enableSessionTickets : 1; /* 18 */
+ unsigned int enableCutThrough : 1; /* 19 */
} sslOptions;
typedef enum { sslHandshakingUndetermined = 0,
sslHandshakingAsClient,
sslHandshakingAsServer
} sslHandshakingType;
typedef struct sslServerCertsStr {
/* Configuration state for server sockets */
CERTCertificate * serverCert;
CERTCertificateList * serverCertChain;
ssl3KeyPair * serverKeyPair;
unsigned int serverKeyBits;
} sslServerCerts;
#define SERVERKEY serverKeyPair->privKey
#define SSL_LOCK_RANK_SPEC 255
#define SSL_LOCK_RANK_GLOBAL NSS_RWLOCK_RANK_NONE
@@ -967,40 +968,41 @@ struct sslSecurityInfoStr {
/*
** SSL Socket struct
**
** Protection: XXX
*/
struct sslSocketStr {
PRFileDesc * fd;
/* Pointer to operations vector for this socket */
const sslSocketOps * ops;
/* SSL socket options */
sslOptions opt;
/* State flags */
unsigned long clientAuthRequested;
unsigned long delayDisabled; /* Nagle delay disabled */
unsigned long firstHsDone; /* first handshake is complete. */
+ unsigned long finishedSent;
unsigned long handshakeBegun;
unsigned long lastWriteBlocked;
unsigned long recvdCloseNotify; /* received SSL EOF. */
unsigned long TCPconnected;
unsigned long appDataBuffered;
/* version of the protocol to use */
SSL3ProtocolVersion version;
SSL3ProtocolVersion clientHelloVersion; /* version sent in client hello. */
sslSecurityInfo sec; /* not a pointer any more */
/* protected by firstHandshakeLock AND (in ssl3) ssl3HandshakeLock. */
const char *url; /* ssl 2 & 3 */
sslHandshakeFunc handshake; /*firstHandshakeLock*/
sslHandshakeFunc nextHandshake; /*firstHandshakeLock*/
sslHandshakeFunc securityHandshake; /*firstHandshakeLock*/
/* the following variable is only used with socks or other proxies. */
diff --git a/mozilla/security/nss/lib/ssl/sslsecur.c b/mozilla/security/nss/lib/ssl/sslsecur.c
index c13100a..8e9d28c 100644
--- a/mozilla/security/nss/lib/ssl/sslsecur.c
+++ b/mozilla/security/nss/lib/ssl/sslsecur.c
@@ -131,40 +131,43 @@ ssl_Do1stHandshake(sslSocket *ss)
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);
}
ss->firstHsDone = PR_TRUE;
ss->gs.writeOffset = 0;
ss->gs.readOffset = 0;
break;
}
+ if (ss->finishedSent) {
+ break;
+ }
rv = (*ss->handshake)(ss);
++loopCount;
/* This code must continue to loop on SECWouldBlock,
* or any positive value. See XXX_1 comments.
*/
} while (rv != SECFailure); /* was (rv >= 0); XXX_1 */
PORT_Assert(ss->opt.noLocks || !ssl_HaveRecvBufLock(ss));
PORT_Assert(ss->opt.noLocks || !ssl_HaveXmitBufLock(ss));
if (rv == SECWouldBlock) {
PORT_SetError(PR_WOULD_BLOCK_ERROR);
rv = SECFailure;
}
return rv;
}
/*
* Handshake function that blocks. Used to force a
* retry on a connection on the next read/write.
diff --git a/mozilla/security/nss/lib/ssl/sslsock.c b/mozilla/security/nss/lib/ssl/sslsock.c
index 39e0f57..4676057 100644
--- a/mozilla/security/nss/lib/ssl/sslsock.c
+++ b/mozilla/security/nss/lib/ssl/sslsock.c
@@ -163,40 +163,41 @@ static const sslSocketOps ssl_secure_ops = { /* SSL. */
** default settings for socket enables
*/
static sslOptions ssl_defaults = {
PR_TRUE, /* useSecurity */
PR_FALSE, /* useSocks */
PR_FALSE, /* requestCertificate */
2, /* requireCertificate */
PR_FALSE, /* handshakeAsClient */
PR_FALSE, /* handshakeAsServer */
PR_TRUE, /* enableSSL2 */
PR_TRUE, /* enableSSL3 */
PR_TRUE, /* enableTLS */ /* now defaults to on in NSS 3.0 */
PR_FALSE, /* noCache */
PR_FALSE, /* fdx */
PR_TRUE, /* v2CompatibleHello */
PR_TRUE, /* detectRollBack */
PR_FALSE, /* noStepDown */
PR_FALSE, /* bypassPKCS11 */
PR_FALSE, /* noLocks */
PR_FALSE, /* enableSessionTickets */
+ PR_FALSE, /* enableCutThrough */
};
sslSessionIDLookupFunc ssl_sid_lookup;
sslSessionIDCacheFunc ssl_sid_cache;
sslSessionIDUncacheFunc ssl_sid_uncache;
static PRBool ssl_inited = PR_FALSE;
static PRDescIdentity ssl_layer_id;
PRBool locksEverDisabled; /* implicitly PR_FALSE */
PRBool ssl_force_locks; /* implicitly PR_FALSE */
int ssl_lock_readers = 1; /* default true. */
char ssl_debug;
char ssl_trace;
FILE * ssl_trace_iob;
char lockStatus[] = "Locks are ENABLED. ";
#define LOCKSTATUS_OFFSET 10 /* offset of ENABLED */
/* forward declarations. */
static sslSocket *ssl_NewSocket(PRBool makeLocks);
@@ -688,40 +689,44 @@ SSL_OptionSet(PRFileDesc *fd, PRInt32 which, PRBool on)
rv = SECFailure;
}
if (on && ssl_force_locks)
on = PR_FALSE; /* silent override */
ss->opt.noLocks = on;
if (on) {
locksEverDisabled = PR_TRUE;
strcpy(lockStatus + LOCKSTATUS_OFFSET, "DISABLED.");
} else if (!holdingLocks) {
rv = ssl_MakeLocks(ss);
if (rv != SECSuccess) {
ss->opt.noLocks = PR_TRUE;
}
}
break;
case SSL_ENABLE_SESSION_TICKETS:
ss->opt.enableSessionTickets = on;
break;
+ case SSL_ENABLE_CUT_THROUGH:
+ ss->opt.enableCutThrough = on;
+ break;
+
default:
PORT_SetError(SEC_ERROR_INVALID_ARGS);
rv = SECFailure;
}
/* We can't use the macros for releasing the locks here,
* because ss->opt.noLocks might have changed just above.
* We must release these locks (monitors) here, if we aquired them above,
* regardless of the current value of ss->opt.noLocks.
*/
if (holdingLocks) {
PZ_ExitMonitor((ss)->ssl3HandshakeLock);
PZ_ExitMonitor((ss)->firstHandshakeLock);
}
return rv;
}
SECStatus
SSL_OptionGet(PRFileDesc *fd, PRInt32 which, PRBool *pOn)
@@ -746,40 +751,41 @@ SSL_OptionGet(PRFileDesc *fd, PRInt32 which, PRBool *pOn)
switch (which) {
case SSL_SOCKS: on = PR_FALSE; break;
case SSL_SECURITY: on = ss->opt.useSecurity; break;
case SSL_REQUEST_CERTIFICATE: on = ss->opt.requestCertificate; break;
case SSL_REQUIRE_CERTIFICATE: on = ss->opt.requireCertificate; break;
case SSL_HANDSHAKE_AS_CLIENT: on = ss->opt.handshakeAsClient; break;
case SSL_HANDSHAKE_AS_SERVER: on = ss->opt.handshakeAsServer; break;
case SSL_ENABLE_TLS: on = ss->opt.enableTLS; break;
case SSL_ENABLE_SSL3: on = ss->opt.enableSSL3; break;
case SSL_ENABLE_SSL2: on = ss->opt.enableSSL2; break;
case SSL_NO_CACHE: on = ss->opt.noCache; break;
case SSL_ENABLE_FDX: on = ss->opt.fdx; break;
case SSL_V2_COMPATIBLE_HELLO: on = ss->opt.v2CompatibleHello; break;
case SSL_ROLLBACK_DETECTION: on = ss->opt.detectRollBack; break;
case SSL_NO_STEP_DOWN: on = ss->opt.noStepDown; break;
case SSL_BYPASS_PKCS11: on = ss->opt.bypassPKCS11; break;
case SSL_NO_LOCKS: on = ss->opt.noLocks; break;
case SSL_ENABLE_SESSION_TICKETS:
on = ss->opt.enableSessionTickets;
break;
+ case SSL_ENABLE_CUT_THROUGH: on = ss->opt.enableCutThrough; break;
default:
PORT_SetError(SEC_ERROR_INVALID_ARGS);
rv = SECFailure;
}
ssl_ReleaseSSL3HandshakeLock(ss);
ssl_Release1stHandshakeLock(ss);
*pOn = on;
return rv;
}
SECStatus
SSL_OptionGetDefault(PRInt32 which, PRBool *pOn)
{
SECStatus rv = SECSuccess;
PRBool on = PR_FALSE;
if (!pOn) {
@@ -790,40 +796,41 @@ SSL_OptionGetDefault(PRInt32 which, PRBool *pOn)
switch (which) {
case SSL_SOCKS: on = PR_FALSE; break;
case SSL_SECURITY: on = ssl_defaults.useSecurity; break;
case SSL_REQUEST_CERTIFICATE: on = ssl_defaults.requestCertificate; break;
case SSL_REQUIRE_CERTIFICATE: on = ssl_defaults.requireCertificate; break;
case SSL_HANDSHAKE_AS_CLIENT: on = ssl_defaults.handshakeAsClient; break;
case SSL_HANDSHAKE_AS_SERVER: on = ssl_defaults.handshakeAsServer; break;
case SSL_ENABLE_TLS: on = ssl_defaults.enableTLS; break;
case SSL_ENABLE_SSL3: on = ssl_defaults.enableSSL3; break;
case SSL_ENABLE_SSL2: on = ssl_defaults.enableSSL2; break;
case SSL_NO_CACHE: on = ssl_defaults.noCache; break;
case SSL_ENABLE_FDX: on = ssl_defaults.fdx; break;
case SSL_V2_COMPATIBLE_HELLO: on = ssl_defaults.v2CompatibleHello; break;
case SSL_ROLLBACK_DETECTION: on = ssl_defaults.detectRollBack; break;
case SSL_NO_STEP_DOWN: on = ssl_defaults.noStepDown; break;
case SSL_BYPASS_PKCS11: on = ssl_defaults.bypassPKCS11; break;
case SSL_NO_LOCKS: on = ssl_defaults.noLocks; break;
case SSL_ENABLE_SESSION_TICKETS:
on = ssl_defaults.enableSessionTickets;
break;
+ case SSL_ENABLE_CUT_THROUGH: on = ssl_defaults.enableCutThrough; break;
default:
PORT_SetError(SEC_ERROR_INVALID_ARGS);
rv = SECFailure;
}
*pOn = on;
return rv;
}
/* XXX Use Global Lock to protect this stuff. */
SECStatus
SSL_EnableDefault(int which, PRBool on)
{
return SSL_OptionSetDefault(which, on);
}
SECStatus
SSL_OptionSetDefault(PRInt32 which, PRBool on)
{
@@ -921,40 +928,44 @@ SSL_OptionSetDefault(PRInt32 which, PRBool on)
break;
case SSL_NO_LOCKS:
if (on && ssl_defaults.fdx) {
PORT_SetError(SEC_ERROR_INVALID_ARGS);
return SECFailure;
}
if (on && ssl_force_locks)
on = PR_FALSE; /* silent override */
ssl_defaults.noLocks = on;
if (on) {
locksEverDisabled = PR_TRUE;
strcpy(lockStatus + LOCKSTATUS_OFFSET, "DISABLED.");
}
break;
case SSL_ENABLE_SESSION_TICKETS:
ssl_defaults.enableSessionTickets = on;
break;
+ case SSL_ENABLE_CUT_THROUGH:
+ ssl_defaults.enableCutThrough = on;
+ break;
+
default:
PORT_SetError(SEC_ERROR_INVALID_ARGS);
return SECFailure;
}
return SECSuccess;
}
/* function tells us if the cipher suite is one that we no longer support. */
static PRBool
ssl_IsRemovedCipherSuite(PRInt32 suite)
{
switch (suite) {
case SSL_FORTEZZA_DMS_WITH_NULL_SHA:
case SSL_FORTEZZA_DMS_WITH_FORTEZZA_CBC_SHA:
case SSL_FORTEZZA_DMS_WITH_RC4_128_SHA:
return PR_TRUE;
default:
return PR_FALSE;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment