diff options
Diffstat (limited to 'security/nss/lib/ssl/sslsock.c')
-rw-r--r-- | security/nss/lib/ssl/sslsock.c | 97 |
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); |