summaryrefslogtreecommitdiffstats
path: root/security/nss/lib/ssl/sslsock.c
diff options
context:
space:
mode:
Diffstat (limited to 'security/nss/lib/ssl/sslsock.c')
-rw-r--r--security/nss/lib/ssl/sslsock.c97
1 files changed, 78 insertions, 19 deletions
diff --git a/security/nss/lib/ssl/sslsock.c b/security/nss/lib/ssl/sslsock.c
index 33595ffae..ae904e29b 100644
--- a/security/nss/lib/ssl/sslsock.c
+++ b/security/nss/lib/ssl/sslsock.c
@@ -18,6 +18,8 @@
#include "private/pprio.h"
#include "nss.h"
#include "pk11pqg.h"
+#include "pk11pub.h"
+#include "tls13esni.h"
static const sslSocketOps ssl_default_ops = { /* No SSL. */
ssl_DefConnect,
@@ -82,7 +84,9 @@ static sslOptions ssl_defaults = {
.requireDHENamedGroups = PR_FALSE,
.enable0RttData = PR_FALSE,
.enableTls13CompatMode = PR_FALSE,
- .enableDtlsShortHeader = PR_FALSE
+ .enableDtlsShortHeader = PR_FALSE,
+ .enableHelloDowngradeCheck = PR_FALSE,
+ .enableV2CompatibleHello = PR_FALSE
};
/*
@@ -359,6 +363,13 @@ ssl_DupSocket(sslSocket *os)
ss->resumptionTokenCallback = os->resumptionTokenCallback;
ss->resumptionTokenContext = os->resumptionTokenContext;
+ if (os->esniKeys) {
+ ss->esniKeys = tls13_CopyESNIKeys(os->esniKeys);
+ if (!ss->esniKeys) {
+ goto loser;
+ }
+ }
+
/* Create security data */
rv = ssl_CopySecurityInfo(ss, os);
if (rv != SECSuccess) {
@@ -444,6 +455,8 @@ ssl_DestroySocketContents(sslSocket *ss)
ssl_ClearPRCList(&ss->ssl3.hs.dtlsSentHandshake, NULL);
ssl_ClearPRCList(&ss->ssl3.hs.dtlsRcvdHandshake, NULL);
+
+ tls13_DestroyESNIKeys(ss->esniKeys);
}
/*
@@ -821,6 +834,14 @@ SSL_OptionSet(PRFileDesc *fd, PRInt32 which, PRIntn val)
ss->opt.enableDtlsShortHeader = val;
break;
+ case SSL_ENABLE_HELLO_DOWNGRADE_CHECK:
+ ss->opt.enableHelloDowngradeCheck = val;
+ break;
+
+ case SSL_ENABLE_V2_COMPATIBLE_HELLO:
+ ss->opt.enableV2CompatibleHello = val;
+ break;
+
default:
PORT_SetError(SEC_ERROR_INVALID_ARGS);
rv = SECFailure;
@@ -963,6 +984,12 @@ SSL_OptionGet(PRFileDesc *fd, PRInt32 which, PRIntn *pVal)
case SSL_ENABLE_DTLS_SHORT_HEADER:
val = ss->opt.enableDtlsShortHeader;
break;
+ case SSL_ENABLE_HELLO_DOWNGRADE_CHECK:
+ val = ss->opt.enableHelloDowngradeCheck;
+ break;
+ case SSL_ENABLE_V2_COMPATIBLE_HELLO:
+ val = ss->opt.enableV2CompatibleHello;
+ break;
default:
PORT_SetError(SEC_ERROR_INVALID_ARGS);
rv = SECFailure;
@@ -1089,6 +1116,12 @@ SSL_OptionGetDefault(PRInt32 which, PRIntn *pVal)
case SSL_ENABLE_DTLS_SHORT_HEADER:
val = ssl_defaults.enableDtlsShortHeader;
break;
+ case SSL_ENABLE_HELLO_DOWNGRADE_CHECK:
+ val = ssl_defaults.enableHelloDowngradeCheck;
+ break;
+ case SSL_ENABLE_V2_COMPATIBLE_HELLO:
+ val = ssl_defaults.enableV2CompatibleHello;
+ break;
default:
PORT_SetError(SEC_ERROR_INVALID_ARGS);
rv = SECFailure;
@@ -1284,6 +1317,14 @@ SSL_OptionSetDefault(PRInt32 which, PRIntn val)
ssl_defaults.enableDtlsShortHeader = val;
break;
+ case SSL_ENABLE_HELLO_DOWNGRADE_CHECK:
+ ssl_defaults.enableHelloDowngradeCheck = val;
+ break;
+
+ case SSL_ENABLE_V2_COMPATIBLE_HELLO:
+ ssl_defaults.enableV2CompatibleHello = val;
+ break;
+
default:
PORT_SetError(SEC_ERROR_INVALID_ARGS);
return SECFailure;
@@ -3742,6 +3783,10 @@ ssl_GetKeyPairRef(sslKeyPair *keyPair)
void
ssl_FreeKeyPair(sslKeyPair *keyPair)
{
+ if (!keyPair) {
+ return;
+ }
+
PRInt32 newCount = PR_ATOMIC_DECREMENT(&keyPair->refCount);
if (!newCount) {
SECKEY_DestroyPrivateKey(keyPair->privKey);
@@ -3801,6 +3846,10 @@ ssl_CopyEphemeralKeyPair(sslEphemeralKeyPair *keyPair)
void
ssl_FreeEphemeralKeyPair(sslEphemeralKeyPair *keyPair)
{
+ if (!keyPair) {
+ return;
+ }
+
ssl_FreeKeyPair(keyPair->keys);
PR_REMOVE_LINK(&keyPair->link);
PORT_Free(keyPair);
@@ -3908,6 +3957,8 @@ ssl_NewSocket(PRBool makeLocks, SSLProtocolVariant protocolVariant)
PR_INIT_CLIST(&ss->ssl3.hs.dtlsRcvdHandshake);
dtls_InitTimers(ss);
+ ss->esniKeys = NULL;
+
if (makeLocks) {
rv = ssl_MakeLocks(ss);
if (rv != SECSuccess)
@@ -3984,6 +4035,9 @@ struct {
EXP(SetResumptionToken),
EXP(GetResumptionTokenInfo),
EXP(DestroyResumptionTokenInfo),
+ EXP(SetESNIKeyPair),
+ EXP(EncodeESNIKeys),
+ EXP(EnableESNI),
#endif
{ "", NULL }
};
@@ -4049,6 +4103,7 @@ SSLExp_SetResumptionToken(PRFileDesc *fd, const PRUint8 *token,
unsigned int len)
{
sslSocket *ss = ssl_FindSocket(fd);
+ sslSessionID *sid = NULL;
if (!ss) {
SSL_DBG(("%d: SSL[%d]: bad socket in SSL_SetResumptionToken",
@@ -4062,7 +4117,7 @@ SSLExp_SetResumptionToken(PRFileDesc *fd, const PRUint8 *token,
if (ss->firstHsDone || ss->ssl3.hs.ws != idle_handshake ||
ss->sec.isServer || len == 0 || !token) {
PORT_SetError(SEC_ERROR_INVALID_ARGS);
- goto done;
+ goto loser;
}
// We override any previously set session.
@@ -4073,41 +4128,44 @@ SSLExp_SetResumptionToken(PRFileDesc *fd, const PRUint8 *token,
PRINT_BUF(50, (ss, "incoming resumption token", token, len));
- ss->sec.ci.sid = ssl3_NewSessionID(ss, PR_FALSE);
- if (!ss->sec.ci.sid) {
- goto done;
+ sid = ssl3_NewSessionID(ss, PR_FALSE);
+ if (!sid) {
+ goto loser;
}
/* Populate NewSessionTicket values */
- SECStatus rv = ssl_DecodeResumptionToken(ss->sec.ci.sid, token, len);
+ SECStatus rv = ssl_DecodeResumptionToken(sid, token, len);
if (rv != SECSuccess) {
// If decoding fails, we assume the token is bad.
PORT_SetError(SSL_ERROR_BAD_RESUMPTION_TOKEN_ERROR);
- ssl_FreeSID(ss->sec.ci.sid);
- ss->sec.ci.sid = NULL;
- goto done;
+ goto loser;
}
- // Make sure that the token is valid.
- if (!ssl_IsResumptionTokenValid(ss)) {
- ssl_FreeSID(ss->sec.ci.sid);
- ss->sec.ci.sid = NULL;
+ // Make sure that the token is currently usable.
+ if (!ssl_IsResumptionTokenUsable(ss, sid)) {
PORT_SetError(SSL_ERROR_BAD_RESUMPTION_TOKEN_ERROR);
- goto done;
+ goto loser;
}
+ // Generate a new random session ID for this ticket.
+ rv = PK11_GenerateRandom(sid->u.ssl3.sessionID, SSL3_SESSIONID_BYTES);
+ if (rv != SECSuccess) {
+ goto loser; // Code set by PK11_GenerateRandom.
+ }
+ sid->u.ssl3.sessionIDLength = SSL3_SESSIONID_BYTES;
/* Use the sid->cached as marker that this is from an external cache and
* we don't have to look up anything in the NSS internal cache. */
- ss->sec.ci.sid->cached = in_external_cache;
- // This has to be 2 to not free this in sendClientHello.
- ss->sec.ci.sid->references = 2;
- ss->sec.ci.sid->lastAccessTime = ssl_TimeSec();
+ sid->cached = in_external_cache;
+ sid->lastAccessTime = ssl_TimeSec();
+
+ ss->sec.ci.sid = sid;
ssl_ReleaseSSL3HandshakeLock(ss);
ssl_Release1stHandshakeLock(ss);
return SECSuccess;
-done:
+loser:
+ ssl_FreeSID(sid);
ssl_ReleaseSSL3HandshakeLock(ss);
ssl_Release1stHandshakeLock(ss);
@@ -4164,6 +4222,7 @@ SSLExp_GetResumptionTokenInfo(const PRUint8 *tokenData, unsigned int tokenLen,
} else {
token.maxEarlyDataSize = 0;
}
+ token.expirationTime = sid.expirationTime;
token.length = PR_MIN(sizeof(SSLResumptionTokenInfo), len);
PORT_Memcpy(tokenOut, &token, token.length);