summaryrefslogtreecommitdiffstats
path: root/security/nss/lib/ssl/sslsecur.c
diff options
context:
space:
mode:
Diffstat (limited to 'security/nss/lib/ssl/sslsecur.c')
-rw-r--r--security/nss/lib/ssl/sslsecur.c141
1 files changed, 70 insertions, 71 deletions
diff --git a/security/nss/lib/ssl/sslsecur.c b/security/nss/lib/ssl/sslsecur.c
index 3f7060f22..8bec3d327 100644
--- a/security/nss/lib/ssl/sslsecur.c
+++ b/security/nss/lib/ssl/sslsecur.c
@@ -1,4 +1,3 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
* Various SSL functions.
*
@@ -201,7 +200,7 @@ SSL_ResetHandshake(PRFileDesc *s, PRBool asServer)
ssl_Release1stHandshakeLock(ss);
ssl3_DestroyRemoteExtensions(&ss->ssl3.hs.remoteExtensions);
- ssl3_ResetExtensionData(&ss->xtnData, ss);
+ ssl3_ResetExtensionData(&ss->xtnData);
if (!ss->TCPconnected)
ss->TCPconnected = (PR_SUCCESS == ssl_DefGetpeername(ss, &addr));
@@ -343,6 +342,11 @@ SSL_RecommendedCanFalseStart(PRFileDesc *fd, PRBool *canFalseStart)
return SECFailure;
}
+ if (!ss->ssl3.initialized) {
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ 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 ||
@@ -431,6 +435,58 @@ SSL_ForceHandshakeWithTimeout(PRFileDesc *fd,
/************************************************************************/
/*
+** Grow a buffer to hold newLen bytes of data.
+** Called for both recv buffers and xmit buffers.
+** Caller must hold xmitBufLock or recvBufLock, as appropriate.
+*/
+SECStatus
+sslBuffer_Grow(sslBuffer *b, unsigned int newLen)
+{
+ newLen = PR_MAX(newLen, MAX_FRAGMENT_LENGTH + 2048);
+ if (newLen > b->space) {
+ unsigned char *newBuf;
+ if (b->buf) {
+ newBuf = (unsigned char *)PORT_Realloc(b->buf, newLen);
+ } else {
+ newBuf = (unsigned char *)PORT_Alloc(newLen);
+ }
+ if (!newBuf) {
+ return SECFailure;
+ }
+ SSL_TRC(10, ("%d: SSL: grow buffer from %d to %d",
+ SSL_GETPID(), b->space, newLen));
+ b->buf = newBuf;
+ b->space = newLen;
+ }
+ return SECSuccess;
+}
+
+SECStatus
+sslBuffer_Append(sslBuffer *b, const void *data, unsigned int len)
+{
+ unsigned int newLen = b->len + len;
+ SECStatus rv;
+
+ rv = sslBuffer_Grow(b, newLen);
+ if (rv != SECSuccess)
+ return rv;
+ PORT_Memcpy(b->buf + b->len, data, len);
+ b->len += len;
+ return SECSuccess;
+}
+
+void
+sslBuffer_Clear(sslBuffer *b)
+{
+ if (b->buf) {
+ PORT_Free(b->buf);
+ b->buf = NULL;
+ b->len = 0;
+ b->space = 0;
+ }
+}
+
+/*
** Save away write data that is trying to be written before the security
** handshake has been completed. When the handshake is completed, we will
** flush this data out.
@@ -718,7 +774,8 @@ ssl_SecureClose(sslSocket *ss)
if (!(ss->shutdownHow & ssl_SHUTDOWN_SEND) &&
ss->firstHsDone &&
- !ss->recvdCloseNotify) {
+ !ss->recvdCloseNotify &&
+ ss->ssl3.initialized) {
/* We don't want the final alert to be Nagle delayed. */
if (!ss->delayDisabled) {
@@ -748,7 +805,8 @@ ssl_SecureShutdown(sslSocket *ss, int nsprHow)
if ((sslHow & ssl_SHUTDOWN_SEND) != 0 &&
!(ss->shutdownHow & ssl_SHUTDOWN_SEND) &&
ss->firstHsDone &&
- !ss->recvdCloseNotify) {
+ !ss->recvdCloseNotify &&
+ ss->ssl3.initialized) {
(void)SSL3_SendAlert(ss, alert_warning, close_notify);
}
@@ -762,55 +820,6 @@ ssl_SecureShutdown(sslSocket *ss, int nsprHow)
/************************************************************************/
-static SECStatus
-tls13_CheckKeyUpdate(sslSocket *ss, CipherSpecDirection dir)
-{
- PRBool keyUpdate;
- ssl3CipherSpec *spec;
- sslSequenceNumber seqNum;
- sslSequenceNumber margin;
- SECStatus rv;
-
- /* Bug 1413368: enable for DTLS */
- if (ss->version < SSL_LIBRARY_VERSION_TLS_1_3 || IS_DTLS(ss)) {
- return SECSuccess;
- }
-
- /* If both sides update at the same number, then this will cause two updates
- * to happen at once. The problem is that the KeyUpdate itself consumes a
- * sequence number, and that will trigger the reading side to request an
- * update.
- *
- * If we have the writing side update first, the writer will be the one that
- * drives the update. An update by the writer doesn't need a response, so
- * it is more efficient overall. The margins here are pretty arbitrary, but
- * having the write margin larger reduces the number of times that a
- * KeyUpdate is sent by a reader. */
- ssl_GetSpecReadLock(ss);
- if (dir == CipherSpecRead) {
- spec = ss->ssl3.crSpec;
- margin = spec->cipherDef->max_records / 8;
- } else {
- spec = ss->ssl3.cwSpec;
- margin = spec->cipherDef->max_records / 4;
- }
- seqNum = spec->seqNum;
- keyUpdate = seqNum > spec->cipherDef->max_records - margin;
- ssl_ReleaseSpecReadLock(ss);
- if (!keyUpdate) {
- return SECSuccess;
- }
-
- SSL_TRC(5, ("%d: SSL[%d]: automatic key update at %llx for %s cipher spec",
- SSL_GETPID(), ss->fd, seqNum,
- (dir == CipherSpecRead) ? "read" : "write"));
- ssl_GetSSL3HandshakeLock(ss);
- rv = tls13_SendKeyUpdate(ss, (dir == CipherSpecRead) ? update_requested : update_not_requested,
- dir == CipherSpecWrite /* buffer */);
- ssl_ReleaseSSL3HandshakeLock(ss);
- return rv;
-}
-
int
ssl_SecureRecv(sslSocket *ss, unsigned char *buf, int len, int flags)
{
@@ -850,17 +859,8 @@ ssl_SecureRecv(sslSocket *ss, unsigned char *buf, int len, int flags)
rv = ssl_Do1stHandshake(ss);
}
ssl_Release1stHandshakeLock(ss);
- } else {
- if (tls13_CheckKeyUpdate(ss, CipherSpecRead) != SECSuccess) {
- rv = PR_FAILURE;
- }
}
if (rv < 0) {
- if (PORT_GetError() == PR_WOULD_BLOCK_ERROR &&
- !PR_CLIST_IS_EMPTY(&ss->ssl3.hs.bufferedEarlyData)) {
- PORT_Assert(ss->version >= SSL_LIBRARY_VERSION_TLS_1_3);
- return tls13_Read0RttData(ss, buf, len);
- }
return rv;
}
@@ -942,19 +942,11 @@ ssl_SecureSend(sslSocket *ss, const unsigned char *buf, int len, int flags)
}
ssl_Release1stHandshakeLock(ss);
}
-
if (rv < 0) {
ss->writerThread = NULL;
goto done;
}
- if (ss->firstHsDone) {
- if (tls13_CheckKeyUpdate(ss, CipherSpecWrite) != SECSuccess) {
- rv = PR_FAILURE;
- goto done;
- }
- }
-
if (zeroRtt) {
/* There's a limit to the number of early data octets we can send.
*
@@ -1249,7 +1241,14 @@ SSL_AuthCertificateComplete(PRFileDesc *fd, PRErrorCode error)
}
ssl_Get1stHandshakeLock(ss);
- rv = ssl3_AuthCertificateComplete(ss, error);
+
+ if (!ss->ssl3.initialized) {
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ rv = SECFailure;
+ } else {
+ rv = ssl3_AuthCertificateComplete(ss, error);
+ }
+
ssl_Release1stHandshakeLock(ss);
return rv;