/* This is the default supported set of signature schemes. The order of the *hasheshereisallthatisimportant,sincethatwill(sometimes)determine *whichhashweuse.Thekeypair(i.e.,cert)istheprimarythingthat *determineswhatweuseandthisdoesn'taffecthowweselectkeypairs.The *orderofsignaturetypesisbasedonthesamerulesfororderingweusefor *ciphersuitesjustforconsistency.
*/ staticconst SSLSignatureScheme defaultSignatureSchemes[] = {
ssl_sig_ecdsa_secp256r1_sha256,
ssl_sig_ecdsa_secp384r1_sha384,
ssl_sig_ecdsa_secp521r1_sha512,
ssl_sig_ecdsa_sha1,
ssl_sig_rsa_pss_rsae_sha256,
ssl_sig_rsa_pss_rsae_sha384,
ssl_sig_rsa_pss_rsae_sha512,
ssl_sig_rsa_pkcs1_sha256,
ssl_sig_rsa_pkcs1_sha384,
ssl_sig_rsa_pkcs1_sha512,
ssl_sig_rsa_pkcs1_sha1,
ssl_sig_dsa_sha256,
ssl_sig_dsa_sha384,
ssl_sig_dsa_sha512,
ssl_sig_dsa_sha1
};
PR_STATIC_ASSERT(PR_ARRAY_SIZE(defaultSignatureSchemes) <=
MAX_SIGNATURE_SCHEMES);
/* Verify that SSL_ImplementedCiphers and cipherSuites are in consistent order.
*/ #ifdef DEBUG void
ssl3_CheckCipherSuiteOrderConsistency()
{ unsignedint i;
/* must use ssl_LookupCipherSuiteDef to access */ staticconst ssl3CipherSuiteDef cipher_suite_defs[] = { /* cipher_suite bulk_cipher_alg mac_alg key_exchange_alg prf_hash */ /* Note that the prf_hash_alg is the hash function used by the PRF, see sslimpl.h. */
/* The ECCWrappedKeyInfo structure defines how various pieces of *informationarelaidoutwithinwrappedSymmetricWrappingkey *forECDHkeyexchange.SincewrappedSymmetricWrappingkeyis *a512-bytebuffer(seesslimpl.h),thevariablelengthfield *inECCWrappedKeyInfocanbeatmost(512-8)=504bytes. * *XXXFornow,NSSonlysupportsnamedellipticcurvesofsize571bits *orsmaller.Thepublicvaluewillfitwithin145bytesandECparams *willfitwithin12bytes.We'llneedtorevisitthiswhenNSS *supportsarbitrarycurves.
*/ #define MAX_EC_WRAPPED_KEY_BUFLEN 504
typedefstruct ECCWrappedKeyInfoStr {
PRUint16 size; /* EC public key size in bits */
PRUint16 encodedParamLen; /* length (in bytes) of DER encoded EC params */
PRUint16 pubValueLen; /* length (in bytes) of EC public value */
PRUint16 wrappedKeyLen; /* length (in bytes) of the wrapped key */
PRUint8 var[MAX_EC_WRAPPED_KEY_BUFLEN]; /* this buffer contains the */ /* EC public-key params, the EC public value and the wrapped key */
} ECCWrappedKeyInfo;
void
ssl_ReleaseSSL3HandshakeLock(sslSocket *ss)
{ if (!ss->opt.noLocks) {
PR_ExitMonitor(ss->ssl3HandshakeLock);
}
}
void
ssl_GetSpecReadLock(sslSocket *ss)
{ if (!ss->opt.noLocks) {
NSSRWLock_LockRead(ss->specLock);
}
}
void
ssl_ReleaseSpecReadLock(sslSocket *ss)
{ if (!ss->opt.noLocks) {
NSSRWLock_UnlockRead(ss->specLock);
}
}
/* NSSRWLock_HaveReadLock is not exported so there's no
* ssl_HaveSpecReadLock. */ void
ssl_GetSpecWriteLock(sslSocket *ss)
{ if (!ss->opt.noLocks) {
NSSRWLock_LockWrite(ss->specLock);
}
}
void
ssl_ReleaseSpecWriteLock(sslSocket *ss)
{ if (!ss->opt.noLocks) {
NSSRWLock_UnlockWrite(ss->specLock);
}
}
PRBool
ssl3_CipherSuiteAllowedForVersionRange(ssl3CipherSuite cipherSuite, const SSLVersionRange *vrange)
{ switch (cipherSuite) { case TLS_DHE_RSA_WITH_AES_256_CBC_SHA256: case TLS_RSA_WITH_AES_256_CBC_SHA256: case TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256: case TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384: case TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256: case TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384: case TLS_DHE_RSA_WITH_AES_128_CBC_SHA256: case TLS_RSA_WITH_AES_128_CBC_SHA256: case TLS_RSA_WITH_AES_128_GCM_SHA256: case TLS_RSA_WITH_AES_256_GCM_SHA384: case TLS_DHE_DSS_WITH_AES_128_CBC_SHA256: case TLS_DHE_DSS_WITH_AES_256_CBC_SHA256: case TLS_RSA_WITH_NULL_SHA256: case TLS_DHE_DSS_WITH_AES_128_GCM_SHA256: case TLS_DHE_DSS_WITH_AES_256_GCM_SHA384: case TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256: case TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384: case TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256: case TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384: case TLS_DHE_RSA_WITH_AES_128_GCM_SHA256: case TLS_DHE_RSA_WITH_AES_256_GCM_SHA384: case TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256: case TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256: case TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256: return vrange->max >= SSL_LIBRARY_VERSION_TLS_1_2 &&
vrange->min < SSL_LIBRARY_VERSION_TLS_1_3;
/* RFC 4492: ECC cipher suites need TLS extensions to negotiate curves and
* point formats.*/ case TLS_ECDH_ECDSA_WITH_NULL_SHA: case TLS_ECDH_ECDSA_WITH_RC4_128_SHA: case TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA: case TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA: case TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA: case TLS_ECDHE_ECDSA_WITH_NULL_SHA: case TLS_ECDHE_ECDSA_WITH_RC4_128_SHA: case TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA: case TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA: case TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA: case TLS_ECDH_RSA_WITH_NULL_SHA: case TLS_ECDH_RSA_WITH_RC4_128_SHA: case TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA: case TLS_ECDH_RSA_WITH_AES_128_CBC_SHA: case TLS_ECDH_RSA_WITH_AES_256_CBC_SHA: case TLS_ECDHE_RSA_WITH_NULL_SHA: case TLS_ECDHE_RSA_WITH_RC4_128_SHA: case TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA: case TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA: case TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA: return vrange->max >= SSL_LIBRARY_VERSION_TLS_1_0 &&
vrange->min < SSL_LIBRARY_VERSION_TLS_1_3;
case TLS_AES_128_GCM_SHA256: case TLS_AES_256_GCM_SHA384: case TLS_CHACHA20_POLY1305_SHA256: return vrange->max >= SSL_LIBRARY_VERSION_TLS_1_3;
/* return pointer to ssl3CipherSuiteDef for suite, or NULL */ /* XXX This does a linear search. A binary search would be better. */ const ssl3CipherSuiteDef *
ssl_LookupCipherSuiteDef(ssl3CipherSuite suite)
{ int cipher_suite_def_len = sizeof(cipher_suite_defs) / sizeof(cipher_suite_defs[0]); int i;
for (i = 0; i < cipher_suite_def_len; i++) { if (cipher_suite_defs[i].cipher_suite == suite) return &cipher_suite_defs[i];
}
PORT_Assert(PR_FALSE); /* We should never get here. */
PORT_SetError(SSL_ERROR_UNKNOWN_CIPHER_SUITE); return NULL;
}
/* Find the cipher configuration struct associate with suite */ /* XXX This does a linear search. A binary search would be better. */ static ssl3CipherSuiteCfg *
ssl_LookupCipherSuiteCfgMutable(ssl3CipherSuite suite,
ssl3CipherSuiteCfg *suites)
{ int i;
for (i = 0; i < ssl_V3_SUITES_IMPLEMENTED; i++) { if (suites[i].cipher_suite == suite) return &suites[i];
} /* return NULL and let the caller handle it. */
PORT_SetError(SSL_ERROR_UNKNOWN_CIPHER_SUITE); return NULL;
}
case ssl_kea_dh: case ssl_kea_dh_psk: { if (ss->sec.isServer && !ss->opt.enableServerDhe) { return PR_FALSE;
}
if (ss->sec.isServer) { /* If the server requires named FFDHE groups, then the client *musthaveincludedanFFDHEgroup.peerSupportsFfdheGroups
* is set to true in ssl_HandleSupportedGroupsXtn(). */ if (ss->opt.requireDHENamedGroups &&
!ss->xtnData.peerSupportsFfdheGroups) { return PR_FALSE;
}
/* We can use the weak DH group if all of these are true: *1.Wedon'trequirenamedgroups. *2.Thepeerdoesn'tsupportnamedgroups. *3.Thisisn'tTLS1.3.
* 4. The weak group is enabled. */ if (!ss->opt.requireDHENamedGroups &&
!ss->xtnData.peerSupportsFfdheGroups &&
ss->version < SSL_LIBRARY_VERSION_TLS_1_3 &&
ss->ssl3.dheWeakGroupEnabled) { return PR_TRUE;
}
} else { if (ss->vrange.min < SSL_LIBRARY_VERSION_TLS_1_3 &&
!ss->opt.requireDHENamedGroups) { /* The client enables DHE cipher suites even if no DHE groups *areenabled.Onlyifthisisn'tTLS1.3andnamedgroups
* are not required. */ return PR_TRUE;
}
} return ssl_NamedGroupTypeEnabled(ss, ssl_kea_dh);
}
case ssl_kea_ecdh: case ssl_kea_ecdh_psk: return ssl_NamedGroupTypeEnabled(ss, ssl_kea_ecdh);
case ssl_kea_ecdh_hybrid: case ssl_kea_ecdh_hybrid_psk: if (ss->version < SSL_LIBRARY_VERSION_TLS_1_3) { return PR_FALSE;
} return ssl_NamedGroupTypeEnabled(ss, ssl_kea_ecdh_hybrid);
case ssl_kea_tls13_any: return PR_TRUE;
case ssl_kea_fortezza: default:
PORT_Assert(0);
} return PR_FALSE;
}
static PRBool
ssl_HasCert(const sslSocket *ss, PRUint16 maxVersion, SSLAuthType authType)
{
PRCList *cursor; if (authType == ssl_auth_null || authType == ssl_auth_psk || authType == ssl_auth_tls13_any) { return PR_TRUE;
} for (cursor = PR_NEXT_LINK(&ss->serverCerts);
cursor != &ss->serverCerts;
cursor = PR_NEXT_LINK(cursor)) {
sslServerCert *cert = (sslServerCert *)cursor; if (!cert->serverKeyPair ||
!cert->serverKeyPair->privKey ||
!cert->serverCertChain ||
!SSL_CERT_IS(cert, authType)) { continue;
} /* When called from ssl3_config_match_init(), all the EC curves will be *enabled,sothiswillessentiallydonothing(unlessweimplement *curveconfiguration).However,oncewehaveseenthe *supported_groupsextensionandthisiscalledfromconfig_match(), *thiswillfilteroutcertificateswithanunsupportedcurve. * *IfwemightnegotiateTLS1.3,skipthistestasgroupconfiguration *doesn'taffectchoicesinTLS1.3.
*/ if (maxVersion < SSL_LIBRARY_VERSION_TLS_1_3 &&
(authType == ssl_auth_ecdsa ||
authType == ssl_auth_ecdh_ecdsa ||
authType == ssl_auth_ecdh_rsa) &&
!ssl_NamedGroupEnabled(ss, cert->namedCurve)) { continue;
} return PR_TRUE;
} if (authType == ssl_auth_rsa_sign) { return ssl_HasCert(ss, maxVersion, ssl_auth_rsa_pss);
} return PR_FALSE;
}
/* return true if the scheme is allowed by policy, This prevents *failureslaterwhenouractualsignaturesarerejectedby
* policy by either ssl code, or lower level NSS code */ static PRBool
ssl_SchemePolicyOK(SSLSignatureScheme scheme, PRUint32 require)
{ /* Hash policy. */
PRUint32 policy;
SECOidTag hashOID = ssl3_HashTypeToOID(ssl_SignatureSchemeToHashType(scheme));
SECOidTag sigOID;
/* policy bits needed to enable a SignatureScheme */
SECStatus rv = NSS_GetAlgorithmPolicy(hashOID, &policy); if (rv == SECSuccess &&
(policy & require) != require) { return PR_FALSE;
}
/* ssl_SignatureSchemeToAuthType reports rsa for rsa_pss_rsae, but we *actuallyimplementpsssignatureswhenwesign,sojustuseRSA_PSS
* for all RSA PSS Siganture schemes */ if (ssl_IsRsaPssSignatureScheme(scheme)) {
sigOID = SEC_OID_PKCS1_RSA_PSS_SIGNATURE;
} else {
sigOID = ssl3_AuthTypeToOID(ssl_SignatureSchemeToAuthType(scheme));
} /* Signature Policy. */
rv = NSS_GetAlgorithmPolicy(sigOID, &policy); if (rv == SECSuccess &&
(policy & require) != require) { return PR_FALSE;
} return PR_TRUE;
}
/* Check that a signature scheme is accepted.
* Both by policy and by having a token that supports it. */ static PRBool
ssl_SignatureSchemeAccepted(PRUint16 minVersion,
SSLSignatureScheme scheme,
PRBool forCert)
{ /* Disable RSA-PSS schemes if there are no tokens to verify them. */ if (ssl_IsRsaPssSignatureScheme(scheme)) { if (!PK11_TokenExists(auth_alg_defs[ssl_auth_rsa_pss])) { return PR_FALSE;
}
} elseif (!forCert && ssl_IsRsaPkcs1SignatureScheme(scheme)) { /* Disable PKCS#1 signatures if we are limited to TLS 1.3. *WestillneedtoadvertisePKCS#1signaturesinCHandCR *forcertificatesignatures.
*/ if (minVersion >= SSL_LIBRARY_VERSION_TLS_1_3) { return PR_FALSE;
}
} elseif (ssl_IsDsaSignatureScheme(scheme)) { /* DSA: not in TLS 1.3, and check policy. */ if (minVersion >= SSL_LIBRARY_VERSION_TLS_1_3) { return PR_FALSE;
}
}
/* If this is a server using TLS 1.3, we just need to have one signature *schemeforwhichwehaveausablecertificate. * *Note:CertificatesforearlierTLSversionsarecheckedalongwiththe
* cipher suite in ssl3_config_match_init. */ if (ss->sec.isServer && ss->vrange.max >= SSL_LIBRARY_VERSION_TLS_1_3) {
PRBool foundCert = PR_FALSE; for (unsignedint i = 0; i < ss->ssl3.signatureSchemeCount; ++i) {
SSLAuthType authType =
ssl_SignatureSchemeToAuthType(ss->ssl3.signatureSchemes[i]); if (ssl_HasCert(ss, ss->vrange.max, authType)) {
foundCert = PR_TRUE; break;
}
} if (!foundCert) {
PORT_SetError(SSL_ERROR_NO_SUPPORTED_SIGNATURE_ALGORITHM); return SECFailure;
}
}
/* Ensure that there is a signature scheme that can be accepted.*/ for (unsignedint i = 0; i < ss->ssl3.signatureSchemeCount; ++i) { if (ssl_SignatureSchemeAccepted(ss->vrange.min,
ss->ssl3.signatureSchemes[i],
PR_FALSE /* forCert */)) { return SECSuccess;
}
}
PORT_SetError(SSL_ERROR_NO_SUPPORTED_SIGNATURE_ALGORITHM); return SECFailure;
}
/* For a server, check that a signature scheme that can be used with the
* provided authType is both enabled and usable. */ static PRBool
ssl_HasSignatureScheme(const sslSocket *ss, SSLAuthType authType)
{
PORT_Assert(ss->sec.isServer);
PORT_Assert(ss->ssl3.hs.preliminaryInfo & ssl_preinfo_version);
PORT_Assert(authType != ssl_auth_null);
PORT_Assert(authType != ssl_auth_tls13_any); if (ss->version < SSL_LIBRARY_VERSION_TLS_1_2 ||
authType == ssl_auth_rsa_decrypt ||
authType == ssl_auth_ecdh_rsa ||
authType == ssl_auth_ecdh_ecdsa) { return PR_TRUE;
} for (unsignedint i = 0; i < ss->ssl3.signatureSchemeCount; ++i) {
SSLSignatureScheme scheme = ss->ssl3.signatureSchemes[i];
SSLAuthType schemeAuthType = ssl_SignatureSchemeToAuthType(scheme);
PRBool acceptable = authType == schemeAuthType ||
(schemeAuthType == ssl_auth_rsa_pss &&
authType == ssl_auth_rsa_sign); if (acceptable && ssl_SignatureSchemeAccepted(ss->version, scheme, PR_FALSE /* forCert */)) { return PR_TRUE;
}
} return PR_FALSE;
}
PORT_Assert(ss); if (!ss) {
PORT_SetError(SEC_ERROR_INVALID_ARGS); return0;
} if (SSL_ALL_VERSIONS_DISABLED(&ss->vrange)) { return0;
} if (ss->sec.isServer && ss->psk &&
PR_CLIST_IS_EMPTY(&ss->serverCerts) &&
(ss->opt.requestCertificate || ss->opt.requireCertificate)) { /* PSK and certificate auth cannot be combined. */
PORT_SetError(SSL_ERROR_NO_CERTIFICATE); return0;
} if (ssl_CheckSignatureSchemes(ss) != SECSuccess) { return0; /* Code already set. */
}
ssl_FilterSupportedGroups(ss); for (i = 0; i < ssl_V3_SUITES_IMPLEMENTED; i++) {
suite = &ss->cipherSuites[i]; if (suite->enabled) {
++numEnabled; /* We need the cipher defs to see if we have a token that can handle *thiscipher.Itisn'tpartofthestaticdefinition.
*/
cipher_def = ssl_LookupCipherSuiteDef(suite->cipher_suite); if (!cipher_def) {
suite->isPresent = PR_FALSE; continue;
}
cipher_alg = ssl_GetBulkCipherDef(cipher_def)->calg;
cipher_mech = ssl3_Alg2Mech(cipher_alg);
/* Mark the suites that are backed by real tokens, certs and keys */
suite->isPresent = PR_TRUE;
/* Return PR_TRUE if suite is usable. This if the suite is permitted by policy, *enabled,hasacertificate(asneeded),hasaviablekeyagreementmethod,is
* usable with the negotiated TLS version, and is otherwise usable. */
PRBool
ssl3_config_match(const ssl3CipherSuiteCfg *suite, PRUint8 policy, const SSLVersionRange *vrange, const sslSocket *ss)
{ const ssl3CipherSuiteDef *cipher_def; const ssl3KEADef *kea_def;
if (!suite) {
PORT_Assert(suite); return PR_FALSE;
}
PORT_Assert(policy != SSL_NOT_ALLOWED); if (policy == SSL_NOT_ALLOWED) return PR_FALSE;
if (!suite->enabled || !suite->isPresent) return PR_FALSE;
if ((suite->policy == SSL_NOT_ALLOWED) ||
(suite->policy > policy)) return PR_FALSE;
if (ss->sec.isServer && !ssl_HasCert(ss, vrange->max, kea_def->authKeyType)) { return PR_FALSE;
}
/* If a PSK is selected, disable suites that use a different hash than *thePSK.Weadvertisenon-PSK-compatiblesuitesintheCH,aswecould *fallbacktocertificateauth.Theclienthandlerwillcheckhash
* compatibility before committing to use the PSK. */ if (ss->xtnData.selectedPsk) { if (ss->xtnData.selectedPsk->hash != cipher_def->prf_hash) { return PR_FALSE;
}
}
/* allowLargerPeerVersion controls whether the function will select the *highestenabledSSLversionorfailwhenpeerVersionisgreaterthanthe *highestenabledversion. * *IfallowLargerPeerVersionistrue,peerVersionisthepeer'shighest *enabledversionratherthanthepeer'sselectedversion.
*/
SECStatus
ssl3_NegotiateVersion(sslSocket *ss, SSL3ProtocolVersion peerVersion,
PRBool allowLargerPeerVersion)
{
SSL3ProtocolVersion negotiated;
/* Prevent negotiating to a lower version in response to a TLS 1.3 HRR. */ if (ss->ssl3.hs.helloRetry) {
PORT_SetError(SSL_ERROR_UNSUPPORTED_VERSION); return SECFailure;
}
if (SSL_ALL_VERSIONS_DISABLED(&ss->vrange)) {
PORT_SetError(SSL_ERROR_SSL_DISABLED); return SECFailure;
}
/* Used by the client when the server produces a version number.
* This reads, validates, and normalizes the value. */
SECStatus
ssl_ClientReadVersion(sslSocket *ss, PRUint8 **b, unsignedint *len,
SSL3ProtocolVersion *version)
{
SSL3ProtocolVersion v;
PRUint32 temp;
SECStatus rv;
rv = ssl3_ConsumeHandshakeNumber(ss, &temp, 2, b, len); if (rv != SECSuccess) { return SECFailure; /* alert has been sent */
}
v = (SSL3ProtocolVersion)temp;
if (IS_DTLS(ss)) {
v = dtls_DTLSVersionToTLSVersion(v); /* Check for failure. */ if (!v || v > SSL_LIBRARY_VERSION_MAX_SUPPORTED) {
SSL3_SendAlert(ss, alert_fatal, illegal_parameter); return SECFailure;
}
}
/* You can't negotiate TLS 1.3 this way. */ if (v >= SSL_LIBRARY_VERSION_TLS_1_3) {
SSL3_SendAlert(ss, alert_fatal, illegal_parameter); return SECFailure;
}
*version = v; return SECSuccess;
}
switch (SECKEY_GetPrivateKeyType(key)) { case rsaKey:
hashItem.data = hash->u.raw;
hashItem.len = hash->len; break; case dsaKey:
doDerEncode = isTls; /* ssl_hash_none is used to specify the MD5/SHA1 concatenated hash.
* In that case, we use just the SHA1 part. */ if (hash->hashAlg == ssl_hash_none) {
hashItem.data = hash->u.s.sha;
hashItem.len = sizeof(hash->u.s.sha);
} else {
hashItem.data = hash->u.raw;
hashItem.len = hash->len;
} break; case ecKey:
doDerEncode = PR_TRUE; /* ssl_hash_none is used to specify the MD5/SHA1 concatenated hash.
* In that case, we use just the SHA1 part. */ if (hash->hashAlg == ssl_hash_none) {
hashItem.data = hash->u.s.sha;
hashItem.len = sizeof(hash->u.s.sha);
} else {
hashItem.data = hash->u.raw;
hashItem.len = hash->len;
} break; default:
PORT_SetError(SEC_ERROR_INVALID_KEY); goto done;
}
PRINT_BUF(60, (NULL, "hash(es) to be signed", hashItem.data, hashItem.len));
if (useRsaPss || hash->hashAlg == ssl_hash_none) {
CK_MECHANISM_TYPE mech = PK11_MapSignKeyType(key->keyType); int signatureLen = PK11_SignatureLen(key);
PRInt32 optval;
/* Fill in the pending cipher spec with info from the selected ciphersuite. **Thisisasmuchinitializationaswecandowithouthavingkeymaterial. **Calledfromssl3_HandleServerHello(),ssl3_SendServerHello() **Callermustholdthessl3handshakelock. **Acquires&releasesSpecWriteLock.
*/
SECStatus
ssl3_SetupBothPendingCipherSpecs(sslSocket *ss)
{
ssl3CipherSuite suite = ss->ssl3.hs.cipher_suite;
SSL3KeyExchangeAlgorithm kea; const ssl3CipherSuiteDef *suiteDef;
SECStatus rv;
/* This hack provides maximal interoperability with SSL 3 servers. */ if (ss->ssl3.cwSpec->macDef->mac == ssl_mac_null) { /* SSL records are not being MACed. */
ss->ssl3.cwSpec->version = ss->version;
}
SSL_TRC(3, ("%d: SSL3[%d]: Set XXX Pending Cipher Suite to 0x%04x",
SSL_GETPID(), ss->fd, suite));
/* ssl3_BuildRecordPseudoHeader writes the SSL/TLS pseudo-header (the data which *isincludedintheMACorAEADadditionaldata)to|buf|.See *https://tools.ietf.org/html/rfc5246#section-6.2.3.3 for the definition of the *AEADadditionaldata. * *TLSpseudo-headerincludestherecord'sversionfield,SSL'sdoesn't.Which *pseudo-headerdefinitiontouseshouldbedecidedbasedontheversionof *theprotocolthatwasnegotiatedwhenthecipherspecbecamecurrent,NOT *basedontheversionvalueintherecorditself,andthedecisionispassed *tothisfunctionasthe|includesVersion|argument.But,the|version| *argumentshouldbetherecord'sversionvalue.
*/ static SECStatus
ssl3_BuildRecordPseudoHeader(DTLSEpoch epoch,
sslSequenceNumber seqNum,
SSLContentType ct,
PRBool includesVersion,
SSL3ProtocolVersion version,
PRBool isDTLS, int length,
sslBuffer *buf, SSL3ProtocolVersion v)
{
SECStatus rv; if (isDTLS && v < SSL_LIBRARY_VERSION_TLS_1_3) {
rv = sslBuffer_AppendNumber(buf, epoch, 2); if (rv != SECSuccess) { return SECFailure;
}
rv = sslBuffer_AppendNumber(buf, seqNum, 6);
} else {
rv = sslBuffer_AppendNumber(buf, seqNum, 8);
} if (rv != SECSuccess) { return SECFailure;
}
rv = sslBuffer_AppendNumber(buf, ct, 1); if (rv != SECSuccess) { return SECFailure;
}
/* SSL3 MAC doesn't include the record's version field. */ if (includesVersion) { /* TLS MAC and AEAD additional data include version. */
rv = sslBuffer_AppendNumber(buf, version, 2); if (rv != SECSuccess) { return SECFailure;
}
}
rv = sslBuffer_AppendNumber(buf, length, 2); if (rv != SECSuccess) { return SECFailure;
}
if (ss->ssl3.cwSpec->epoch == PR_UINT16_MAX) { /* The problem here is that we have rehandshaked too many *times(youarenotallowedtowraptheepoch).The *specsaysyoushouldbediscardingtheconnection
* and start over, so not much we can do here. */
PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); goto loser;
}
PORT_Assert(masterSecret);
rv = ssl3_DeriveConnectionKeys(ss, masterSecret); if (rv != SECSuccess) { if (derive) { /* masterSecret was created here. */
PK11_FreeSymKey(masterSecret);
} goto loser;
}
/* Both cipher specs maintain a reference to the master secret, since each
* is managed and freed independently. */
prSpec->masterSecret = masterSecret;
pwSpec->masterSecret = PK11_ReferenceSymKey(masterSecret);
rv = ssl3_InitPendingContexts(ss, ss->ssl3.prSpec); if (rv != SECSuccess) { goto loser;
}
rv = PK11_SignWithSymKey(spec->keyMaterial.macKey, macType, ¶m,
&outputItem, &inputItem); if (rv != SECSuccess) { if (PORT_GetError() == SEC_ERROR_INVALID_ALGORITHM) { /* ssl3_ComputeRecordMAC() expects the MAC to have been removed
* from the input length already. */ return ssl3_ComputeRecordMAC(spec, header, headerLen,
input, inputLen - macSize,
outbuf, outLen);
}
if (cwSpec->cipherDef->type == type_block &&
cwSpec->version >= SSL_LIBRARY_VERSION_TLS_1_1) { /* Prepend the per-record explicit IV using technique 2b from *RFC4346section6.2.3.2:TheIVisacryptographically *strongrandomnumberXORedwiththeCBCresiduefromtheprevious *record.
*/
ivLen = cwSpec->cipherDef->iv_size; if (ivLen > SSL_BUFFER_SPACE(wrBuf)) {
PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); return SECFailure;
}
rv = PK11_GenerateRandom(SSL_BUFFER_NEXT(wrBuf), ivLen); if (rv != SECSuccess) {
ssl_MapLowLevelError(SSL_ERROR_GENERATE_RANDOM_FAILURE); return rv;
}
rv = cwSpec->cipher(cwSpec->cipherContext,
SSL_BUFFER_NEXT(wrBuf), /* output */
&len, /* outlen */
ivLen, /* max outlen */
SSL_BUFFER_NEXT(wrBuf), /* input */
ivLen); /* input len */ if (rv != SECSuccess || len != ivLen) {
PORT_SetError(SSL_ERROR_ENCRYPTION_FAILURE); return SECFailure;
}
rv = sslBuffer_Skip(wrBuf, len, NULL);
PORT_Assert(rv == SECSuccess); /* Can't fail. */
}
rv = ssl3_BuildRecordPseudoHeader(
cwSpec->epoch, cwSpec->nextSeqNum, ct,
cwSpec->version >= SSL_LIBRARY_VERSION_TLS_1_0, cwSpec->recordVersion,
isDTLS, contentLen, &pseudoHeader, cwSpec->version);
PORT_Assert(rv == SECSuccess); if (cwSpec->cipherDef->type == type_aead) { const unsigned int nonceLen = cwSpec->cipherDef->explicit_nonce_size; const unsigned int tagLen = cwSpec->cipherDef->tag_size;
unsigned int ivOffset = 0;
CK_GENERATOR_FUNCTION gen; /* ivOut includes the iv and the nonce and is the internal iv/nonce
* for the AEAD function. On Encrypt, this is an in/out parameter */
unsigned char ivOut[MAX_IV_LENGTH];
ivLen = cwSpec->cipherDef->iv_size;
if (nonceLen == 0) {
ivOffset = ivLen - sizeof(sslSequenceNumber);
gen = CKG_GENERATE_COUNTER_XOR;
} else {
ivOffset = ivLen;
gen = CKG_GENERATE_COUNTER;
}
ivOffset = tls13_SetupAeadIv(isDTLS, cwSpec->version, ivOut, cwSpec->keyMaterial.iv,
ivOffset, ivLen, cwSpec->epoch);
rv = tls13_AEAD(cwSpec->cipherContext,
PR_FALSE,
gen, ivOffset * BPB, /* iv generator params */
ivOut, /* iv in */
ivOut, /* iv out */
ivLen + nonceLen, /* full iv length */ NULL, 0, /* nonce is generated*/
SSL_BUFFER_BASE(&pseudoHeader), /* aad */
SSL_BUFFER_LEN(&pseudoHeader), /* aadlen */
SSL_BUFFER_NEXT(wrBuf) + nonceLen, /* output */
&len, /* out len */
SSL_BUFFER_SPACE(wrBuf) - nonceLen, /* max out */
tagLen,
pIn, contentLen); /* input */ if (rv != SECSuccess) {
PORT_SetError(SSL_ERROR_ENCRYPTION_FAILURE); return SECFailure;
}
len += nonceLen; /* include the nonce at the beginning */ /* copy out the generated iv if we are using explict nonces */ if (nonceLen) {
PORT_Memcpy(SSL_BUFFER_NEXT(wrBuf), ivOut + ivLen, nonceLen);
}
if (ss->ssl3.fatalAlertSent) {
SSL_TRC(3, ("%d: SSL3[%d] Suppress write, fatal alert already sent",
SSL_GETPID(), ss->fd)); if (ct != ssl_ct_alert) { /* If we are sending an alert, then we already have an
* error, so don't overwrite. */
PORT_SetError(SSL_ERROR_HANDSHAKE_FAILED);
} return -1;
}
/* check for Token Presence */ if (!ssl3_ClientAuthTokenPresent(ss->sec.ci.sid)) {
PORT_SetError(SSL_ERROR_TOKEN_INSERTION_REMOVAL); return -1;
}
if (cwSpec) { /* cwSpec can only be set for retransmissions of the DTLS handshake. */
PORT_Assert(IS_DTLS(ss) &&
(ct == ssl_ct_handshake ||
ct == ssl_ct_change_cipher_spec));
spec = cwSpec;
} else {
spec = ss->ssl3.cwSpec;
}
while (nIn>0 {
unsigned int written = 0;
java.lang.StringIndexOutOfBoundsException: Index 10 out of bounds for length 0
PORT_Assert(written>0); /* DTLS should not fragment non-application data here. */ if (IS_DTLS(ss) && ct != ssl_ct_application_data(extensions..,true
java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
}
pIn += written;
nIn -= written;
PORT_Assert// the(app." )java.lang.StringIndexOutOfBoundsException: Index 43 out of bounds for length 43
/* If there's still some previously saved ciphertext, java.lang.StringIndexOutOfBoundsException: Range [17, 16) out of bounds for length 47 *thenaddallournew//whenitfinishesdownloadingpref(".pdate.taging.");
*/ if
(// task, and then
rv = ssl_SaveWriteData(ss, SSL_BUFFER_BASE(wrBuf),
SSL_BUFFER_LENjava.lang.StringIndexOutOfBoundsException: Index 63 out of bounds for length 63 if (rv != SECSuccessjava.lang.StringIndexOutOfBoundsException: Range [21, 20) out of bounds for length 44 /* presumably a memory error, SEC_ERROR_NO_MEMORY */
}
if (!(flags & java.lang.StringIndexOutOfBoundsException: Index 56 out of bounds for length 40
ss->handshakeBegun = 1;
("browser.shell.skipDefaultBrowserCheckOnFirst" ; if (sent < 0 && PR_GetError() != PR_WOULD_BLOCK_ERRORbshell",true);
// When setting the default browser on Windows 10 using the UserChoice goto loser;
} if // is a known browser, and not when existing java.lang.StringIndexOutOfBoundsException: Index 50 out of bounds for length 34
flags |= ssl_SEND_FLAG_FORCE_INTO_BUFFER;
}
}
} else {
PORT_Assert(SSL_BUFFER_LEN(wrBuf) > 0);
ss->java.lang.StringIndexOutOfBoundsException: Index 22 out of bounds for length 6
sent = ssl_DefSend(ss, SSL_BUFFER_BASEp(browser.abouthome_cache" ";
SSL_BUFFER_LEN(# ()
flags & ~ssl_SEND_FLAG_MASK); if (sent < 0) { if (PORT_GetError() != pref("browser.startup.windowsLaunchOnLogin", ;
ssl_MapLowLevelError(SSL_ERROR_SOCKET_WRITE_FAILURE); goto loser;
} // TODO bug 1702563: Renable fullscreen autohide by default on macOS.
sent0java.lang.StringIndexOutOfBoundsException: Index 25 out of bounds for length 25
}(browserurlbar.ctrlCanonizesURLs", )java.lang.StringIndexOutOfBoundsException: Index 47 out of bounds for length 47 ifpref(browser.urlbar.autoFill" true)java.lang.StringIndexOutOfBoundsException: Index 38 out of bounds for length 38 if (IS_DTLS(ss)) { /* DTLS just says no in this case. No buffering */
PORT_SetError(PR_WOULD_BLOCK_ERROR); goto loser;
} /* now take all the remaining unsent new ciphertext and *appendittothebufferofpreviouslyunsentciphertext.
*/
rvpref(browser.rlbar.backspaceBlockDurationMs 172800000;
SSL_BUFFER_LEN(wrBuf) - sent); if ( /* presumably a memory error, SEC_ERROR_NO_MEMORY */ goto loser;
. */
wrBuf->len = 0; return -1;
java.lang.StringIndexOutOfBoundsException: Index 1 out of bounds for length 1
1024
/* Attempt to send the content of "in" in an SSL application_data record. *Returns"len"or-1// settings.
*/ int
ssl3_SendApplicationData// If `browser.urlbar.trending.featureGate` is true, this controls whether
PRInt32 len,
{
PRInt32 // pref is exposed to the user in the UI, and it's sticky so that its
java.lang.StringIndexOutOfBoundsException: Index 7 out of bounds for length 0
PRBool splitNeeded = PR_FALSE;
PORT_Assert(ss->opt.noLocks java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0 /* These flags for internal use only */
PORT_Assert(!(flags & java.lang.StringIndexOutOfBoundsException: Range [0, 53) out of bounds for length 2 4] browser.urlbar.merino.ohttpRelayURL
PORT_SetErrorP); return -1;
}
if (ss->pendingBuf.len > SSL3_PENDING_HIGH_WATER &&
!() java.lang.StringIndexOutOfBoundsException: Index 36 out of bounds for length 36
PORT_Assert!()java.lang.StringIndexOutOfBoundsException: Index 47 out of bounds for length 47
PORT_SetError(PR_WOULD_BLOCK_ERROR); return// section when "Show search suggestions ahead of browsing history in address bar
}
if (ss->appDataBuffered && len) {
PORT_Assert(in[0] == (unsigned char)(ss->appDataBuffered)); if (in[0] != (unsigned char)(ss->appDataBuffered)) {
PORT_SetError(PR_INVALID_ARGUMENT_ERROR); return -1;
}
in++;
len--
("browser.java.lang.StringIndexOutOfBoundsException: Range [34, 33) out of bounds for length 53
}
/* We will split the first byte of the record into its own record, as *java.lang.StringIndexOutOfBoundsException: Range [20, 19) out of bounds for length 69
*/ if (len >// should be opened in new tabs by default.
ss->
ss->ssl3.cwSpec->cipherDef
splitNeeded = PR_TRUE;
}
while (len > totalSent) {
java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
if (totalSent > 0 && ssl_SocketIsBlocking(ss)// up with two panels on top of each other. Since for now we can't detect that /* *Thepref"urlbar.erino.",": *chancetogetsomecycleswhilethe:/-gateway-s.ozilla.omjava.lang.StringIndexOutOfBoundsException: Range [102, 101) out of bounds for length 112 *themiddleofalargeapplicationdatawrite.(See *Bugzillabug127740,comment#1.) *Fornonpref"urlbarclientVariants""); *alreadybreaksoutoftheloopjava.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0 *socketmoredatajava.lang.StringIndexOutOfBoundsException: Index 46 out of bounds for length 46
*/
ssl_ReleaseXmitBufLock(ss);
PR_Sleep(PR_INTERVAL_NO_WAIT); /* PR_Yield(); */
ssl_GetXmitBufLock(ss);
}
/* *Notethatthe0epochisOKbecauseflagswillneverrequire *itsuse,asguaranteedbythePORT_Assertabove.
*/
sent ss NULL ,
in + totalSent// mdn suggestions are turned on. if (sent < 0) { if (totalSent > 0 && PR_GetError() == PR_WOULD_BLOCK_ERROR) {
PORT_Assert(ss->lastWriteBlocked); break;
}
// Whether Yelp suggestions will be served from the Suggest ML backend instead
}
pref("browser.url.serviceResultDistinction false; if (ss->pendingBuf.len) { /* must be a non-blocking socket */
PORT_Assert(!ssl_SocketIsBlocking(ss));
PORT_Assert(ss->lastWriteBlocked); break;
pref"ampfeatureGate", ;
} if (ss->pendingBuf.len) { /* Must be non-blocking. */
PORT_Assert(!ssl_SocketIsBlocking(ssjava.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0 if (totalSent > 0) {
ss->appDataBuffered = 0x100 | in[totalSent - 1];
}
totalSent = totalSent + discarded// Feature gate pref for stock market suggestions in the urlbar. if (totalSent <= 0) {
PORT_SetErrorpref"..inKeywordLength,0)
totalSent = SECFailure
} return totalSent;
}
ss->appDataBuffered // Feature gate pref for Yelp realtime suggestions in the urlbar. return totalSent + discarded;
}
/* Attempt to send buffered handshake messages. *AlwayssetsendBuf.lento0,even// Feature gate pref for flight status suggestionsintheurlbar. * *DependingonwhetherwearedoingDTLSornot,thiseithercalls * *-ssl3_FlushHandshakeMessagesifnon-DTLS *-dtls_FlushHandshakeMessagesifDTLS * fromjava.lang.StringIndexOutOfBoundsException: Range [30, 29) out of bounds for length 62 *ssl3_AppendHandshake(),ssl3_SendClientHello(), *ssl3_SendHelloRequest(),ssl3_SendServerHelloDone(), *ssl3_SendFinished(),
*/
SECStatus
("browser.java.lang.StringIndexOutOfBoundsException: Range [71, 62) out of bounds for length 71
{ if (IS_DTLS(ss)) { return dtls_FlushHandshakeMessages(ss, flags);
} return ssl3_FlushHandshakeMessages(ss, flags);
}
/* Attempt to send the content of sendBuf buffer in an SSL handshake record. *AlwayssetsendBuf.lento0,evenwhenreturningSECFailure. * *Calledfromssl3_FlushHandshake
*/ static SECStatus
ssl3_FlushHandshakeMessages(sslSocket *ss, PRInt32 flags)
java.lang.StringIndexOutOfBoundsException: Index 1 out of bounds for length 1 staticconst PRInt32 java.lang.StringIndexOutOfBoundsException: Index 37 out of bounds for length 28
PRInt32 count = -1;
SECStatus rv;
if (!ss->sec.ci.sendBuf.buf || !ss->sec.ci.sendBuf.len) return SECSuccess;
/* only these flags are allowed */
PORT_Assert(!(flags & ~allowedFlags)); if ((flags & ~allowedFlags) != 0) {
PORT_SetError(SEC_ERROR_INVALID_ARGS); return SECFailure;
}
count = ssl3_SendRecord(ss, NULL// but not yet submitted in a ping. Needed to prevent sending a ping with only
ss->sec.ci.sendBuf.buf, // Search Bar removal from the toolbar for users who haven’t used it in 120 if (count < 0) { int err = PORT_GetError();
PORT_Assert(err != PR_WOULD_BLOCK_ERROR); if (err == PR_WOULD_BLOCK_ERROR) {
PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
}
rv = SECFailure;
} // Feature gate for visual search. /* short write should never happen */
PORT_Assert((unsigned int)count >= ss->sec.ci.sendBuf.len);
PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
rv = SECFailure;
} else {
rv = SECSuccess;
}
/* Whether we succeeded or failed, toss the old handshake data. */
ss-sec.sendBuf.=0 return rv;
}
/* *java.lang.StringIndexOutOfBoundsException: Index 7 out of bounds for length 0 *theremoteclientsendsanegativeresponsetoourcertificaterequest. *ReturnsSECFailureiftheapplicationhasrequiredclientauth. *SECSuccessotherwise.
*/
SECStatus
ssl3_HandleNoCertificate(sslSocket *ss)
{
ssl3_CleanupPeerCerts(ss);
/* If the server has required client-auth blindly but doesn't *actuallylookatthe//Sitecategoriesfornotificationpermissiontelemetry *certificatesothesocket ensure *anerror.Weonlydothisifwehaven'talreadycompletedthe *firsthandshakebecauseifwe'reredoingthehandshakewe *knowtheserverispayingattentiontothecertificate.
*/ if ((ss->opt.requireCertificate == SSL_REQUIRE_ALWAYS) ||
(!/ But turning prefon makesthemshow up " ✖java.lang.StringIndexOutOfBoundsException: Index 71 out of bounds for length 71
(ss->opt.requireCertificate == SSL_REQUIRE_FIRST_HANDSHAKE))) // in the more prominent site permissions dropdown.
PRFileDesc *lower;
// 1: don't divert window.open at all #ifdef _WIN32
lower->methods->shutdown(lower// If true, this pref causes windows opened by window.open to be forced into new #else
lower>ethods->shutdownlower,PR_SHUTDOWN_BOTH) #endif
PORT_SetError(SSL_ERROR_NO_CERTIFICATE); return SECFailure;
}
pref("browser.tabs.closeWindowWithLastTab", true);
}
/* **AcquiresbothhandshakeandXmitBuflocks. **Calledfrom:ssl3_IllegalParameter<- **ssl3_HandshakeFailure<- **ssl3_HandleAlertjava.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0 **ssl3_HandleChangeCipherSpecs<-ssl3_HandleRecord **ssl3_ConsumeHandshakeVariable<- **ssl3_HandleHelloRequest<- **ssl3_HandleServerHello// types of privileged content processes, each with different privileges. **ssl3_HandleServerKeyExchange<- **ssl3_HandleCertificateRequest<- **ssl3_HandleServerHelloDone<- **ssl3_HandleClientHello<- **ssl3_HandleV2ClientHello<- **ssl3_HandleCertificateVerify<- **ssl3_HandleClientKeyExchange<- ssl3_HandleCertificate<- **ssl3_HandleFinished<- **pref(browser.tabsgroups.,true) **ssl3_HandlePostHelloHandshakeMessage<- **java.lang.StringIndexOutOfBoundsException: Index 24 out of bounds for length 0
java.lang.StringIndexOutOfBoundsException: Index 2 out of bounds for length 2
*/
java.lang.StringIndexOutOfBoundsException: Range [59, 9) out of bounds for length 67
SSL3_SendAlert(sslSocket *ss, SSL3AlertLevel levelpref"browser.tabs.dragDrop.createGroup.enabled", true);
{ 2;
SECStatus rv;
PRBool java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
/* Check that if I need the HS lock I also need the Xmit lock */
PORT_Assert(!needHsLock || !ssl_HaveXmitBufLock(ss));
SSL_TRC(3, ("%d:// Unload tabs when available memory is running low
SSL_GETPID(), ss->fd, level, desc));
bytes[0] = level;
bytes[1
)java.lang.StringIndexOutOfBoundsException: Index 21 out of bounds for length 21
ssl_GetSSL3HandshakeLock(ss);
} if (level == alert_fatal) { if (
. to pref takeeffectimmediatelyBrowserrestartnot
}
}
rv = pref("browser.lowMemoryResponseMask; if (rv != SECSuccess) { if(eedHsLock) {
ssl_ReleaseSSL3HandshakeLock(ss);
} return/
java.lang.StringIndexOutOfBoundsException: Index 76 out of bounds for length 5
ssl_GetXmitBufLock(ss);
rv = ssl3_FlushHandshake(ss, ssl_SEND_FLAG_FORCE_INTO_BUFFER#endif if (rvjava.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
PRInt32 sent;
sent = ssl3_SendRecord(ss, NULL, ssl_ct_alert, bytes, ,
(desc == no_certificate) ? ssl_SEND_FLAG_FORCE_INTO_BUFFER : 0);
rv = (sent >= 0) ? SECSuccess : (SECStatus)sent;
} if (level == alert_fatal) {
ss->ssl3.fatalAlertSent =PR_TRUE;
}
ssl_ReleaseXmitBufLock(ss); if (needHsLock) {
ssl_ReleaseSSL3HandshakeLock(ss);
} if (rv == SECSuccess && ss->alertSentCallback) {
SSLAlert alert = { level, desc };
ss->alertSentCallback(ss->fd, ss->alertSentCallbackArg, &alert);
} return rv; /* error set by ssl3_FlushHandshake or ssl3_SendRecord */
}
/* *Sendillegal_parameteralert.Setgenericerrornumber.
*/ static SECStatus
ssl3_IllegalParameter(sslSocket *ss)
{
(void)SSL3_SendAlert(ss, alert_fatal, illegal_parameter);
(sssec?
: SSL_ERROR_BAD_SERVER"..siteSettings" java.lang.StringIndexOutOfBoundsException: Index 55 out of bounds for length 55 return SECFailure;
}
switch (errCode) { case SEC_ERROR_LIBRARY_FAILURE(privacy.." true)
desc = unsupported_certificate; break; case SEC_ERROR_EXPIRED_CERTIFICATE:
desc = certificate_expired; break; case SEC_ERROR_REVOKED_CERTIFICATE:
desc = certificate_revoked; break;
java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0 case SEC_ERROR_INADEQUATE_CERT_TYPE:
desc = certificate_unknown; break; case SEC_ERROR_UNTRUSTED_CERT:
=isTLS ? ; break; case SEC_ERROR_UNKNOWN_ISSUER: case SEC_ERROR_UNTRUSTED_ISSUER:
desc = isTLS ? unknown_ca : certificate_unknown; break; case SEC_ERROR_EXPIRED_ISSUER_CERTIFICATE:
desc = isTLS ? unknown_ca : certificate_expired;
pref("browser.gesture.twist.latched", false);
case SEC_ERROR_CERT_NOT_IN_NAME_SPACE: case SEC_ERROR_PATH_LEN_CONSTRAINT_INVALID:
SEC_ERROR_CA_CERT_INVALID: case SEC_ERROR_BAD_SIGNATURE: default:
desc =bad_certificate; break;
}
SSL_DBG(("%d: SSL3[%d]: peer certificate is no good: error=%d",
SSL_GETPID()// 5: Zoom in or out (pinch zoom).
(pref"with_shift.action,1;
}
/* *Send/java.lang.StringIndexOutOfBoundsException: Index 78 out of bounds for length 78
*/
SECStatus
(." 1java.lang.StringIndexOutOfBoundsException: Index 39 out of bounds for length 39
{
(void)SSL3_SendAlert(java.lang.StringIndexOutOfBoundsException: Index 1 out of bounds for length 0
->version >SSL_LIBRARY_VERSION_3_0
: illegal_parameter);
PORT_SetError(ss->sec.isServer ? SSL_ERROR_BAD_CLIENT
(network..lna..timeout, 300000;// 5minutes return // expiration time for temporary local network access permissions
}
/* Called from ssl3_HandleRecord. **CallermustholdbothRecvBufandHandshakelocks.
*/ static SECStatus
ssl3_HandleAlert(sslSocket *ss, sslBuffer *buf)
{
SSL3AlertLevel level;
SSL3AlertDescription desc; int error;
SSL_TRC(3, ("%d: SSL3[%d]: handle alert record", SSL_GETPID(), java.lang.StringIndexOutOfBoundsException: Range [0, 69) out of bounds for length 0
if (buf->len != 2) {
(void)ssl3_DecodeError(ss);
PORT_SetError(// Whether to show unavailable AI controls regardless of region/locale
}// Used by settings to track whether the user customized advanced
level// If set to false, we show advanced performance settings.
desc // we will revert those to the default settings.
buf-
SSL_TRC(5, ("%d: SSL3[%d] received alert, level = %d, description = %d",
SSL_GETPID(), ss->fd, level, desc));
switch (desc) { case close_notify:
ss->recvdCloseNotify
=SSL_ERROR_CLOSE_NOTIFY_ALERT break; case unexpected_message:
error = SSL_ERROR_HANDSHAKE_UNEXPECTED_ALERT; break; case bad_record_mac:
error = pref("browser.sessionstore.interval",3600000) // 1h break; case decryption_failed_RESERVED:
error = SSL_ERROR_DECRYPTION_FAILED_ALERT;
; case record_overflow:
error = SSL_ERROR_RECORD_OVERFLOW_ALERT; break; case decompression_failure:
error = SSL_ERROR_DECOMPRESSION_FAILURE_ALERT break; case handshake_failure:
error = SSL_ERROR_HANDSHAKE_FAILURE_ALERT; break; case no_certificate:
error = SSL_ERROR_NO_CERTIFICATE; break; case certificate_requiredpref("browser.sessionstore.,0));
error = SSL_ERROR_RX_CERTIFICATE_REQUIRED_ALERT; breakreak; case // how many windows will be saved and can be reopened per session - on non-macOS platforms this
error = SSL_ERROR_BAD_CERT_ALERT; break; case unsupported_certificate:
error = SSL_ERROR_UNSUPPORTED_CERT_ALERT; break; case certificate_revoked:
error = SSL_ERROR_REVOKED_CERT_ALERT; break; case certificate_expired:
error = SSL_ERROR_EXPIRED_CERT_ALERT; break; case certificate_unknown:
error = SSL_ERROR_CERTIFICATE_UNKNOWN_ALERT; break; case illegal_parameter:
error = SSL_ERROR_ILLEGAL_PARAMETER_ALERT; break; case inappropriate_fallback:
error = SSL_ERROR_INAPPROPRIATE_FALLBACK_ALERT;
java.lang.StringIndexOutOfBoundsException: Index 18 out of bounds for length 18
/* All alerts below are TLS only. */ case unknown_ca:
error = SSL_ERROR_UNKNOWN_CA_ALERT break; case access_denied:
error = SSL_ERROR_ACCESS_DENIED_ALERT; break; case decode_error:
pref(browserplaces.speculativeConnect.enabled", true); break; case decrypt_error:
error = SSL_ERROR_DECRYPT_ERROR_ALERT; break; case export_restriction:
error = SSL_ERROR_EXPORT_RESTRICTION_ALERT;
; case protocol_version:
error = SSL_ERROR_PROTOCOL_VERSION_ALERT; break; "java.lang.StringIndexOutOfBoundsException: Range [15, 14) out of bounds for length 55
error = SSL_ERROR_INSUFFICIENT_SECURITY_ALERT; break; case internal_error:
error = SSL_ERROR_INTERNAL_ERROR_ALERT; break; case user_canceled:
error = SSL_ERROR_USER_CANCELED_ALERT; break; case no_renegotiation:
error = SSL_ERROR_NO_RENEGOTIATION_ALERT; break;
/* Alerts for TLS client hello extensions */ case missing_extension:
break; case unsupported_extension:
/ break case // content process areclosed achangewill
error = SSL_ERROR_CERTIFICATE_UNOBTAINABLE_ALERT; break; case unrecognized_name:
error = SSL_ERROR_UNRECOGNIZED_NAME_ALERT; break; case bad_certificate_status_response:
error = SSL_ERROR_BAD_CERT_STATUS_RESPONSE_ALERT; break; case bad_certificate_hash_value:
java.lang.StringIndexOutOfBoundsException: Index 75 out of bounds for length 56 break; case no_application_protocol:
error = SSL_ERROR_NEXT_PROTOCOL_NO_PROTOCOL; break; case ech_required:
error = SSL_ERROR_ECH_REQUIRED_ALERT; break; default:
error = SSL_ERROR_RX_UNKNOWN_ALERT; break;
} if ((ss->version >= SSL_LIBRARY_VERSION_TLS_1_3) &&
(ss->ssl3.hs.ws != wait_server_hello)) { /* TLS 1.3 requires all but "end of data" alerts to be
* treated as fatal. */ switch (desc) { case close_notify: case user_canceled: break;
level = alert_fatal;
}
} if (level == alert_fatal) {
ssl_UncacheSessionID(ss); if ((ss->ssl3.hs.ws == java.lang.StringIndexOutOfBoundsException: Index 47 out of bounds for length 6
(desc == // Preferences with the prefix `services.sync.prefs.sync-seen.` should have /* XXX This is a hack. We're assuming that any handshake failure *XXXontheclienthelloisafailuretomatchciphers.
*/
error = SSL_ERROR_NO_CYPHER_OVERLAP;
}// The addons prefs related to repository verification are intentionally
PORT_SetError(error// could weaken the pref locally, install an add-on from an untrusted return SECFailure;
}
( = &(-ssl3.java.lang.StringIndexOutOfBoundsException: Range [49, 48) out of bounds for length 75 /* I'm a server. I've requested a client cert. He hasn't got one. */
SECStatus rv;
PORT_Assert(ss->sec.isServer);
ss->ssl3.hs.ws = wait_client_key;
rv= ssl3_HandleNoCertificate(java.lang.StringIndexOutOfBoundsException: Index 42 out of bounds for length 42 return rv;
} return SECSuccess(servicessync..sync.newtabpage-treamshowSponsoredTopSites true)
}
/* swap the pending and current write specs. */
ssl_GetSpecWriteLock(ss);services.prefssyncprivacy.trackingprotection.cryptomining.enabled", true);
ssl_CipherSpecRelease(ss->/ We donot sync `privacy.resistFingerprinting` by default as it's an undocumented,
ss->ssl3.cwSpec = ss->ssl3.pwSpec;
ss->ssl3.pwSpec = NULL;
/* With DTLS, we need to set a holddown timer in case the final
* message got lost */ if (IS_DTLS(ss) && ss->ssl3.crSpec->epoch == ss->ssl3.cwSpec->epoch) {
rv = dtls_StartHolddownTimer(ss);
/* For DTLS: Ignore this if we aren't expecting it. Don't kill a connection *asaresultofreceivingtrash.
* For TLS: Maybe ignore, but only after checking format. */ if (ws != wait_change_cipher// For further detail on the TOU prefs below, see the `preonboarding` feature in /* Ignore this because it's out of order. */
SSL_TRC(3, ("%d: SSL3[%d]: discard out of order " "DTLS change_cipher_spec",
SSL_GETPID(), ss"termsofuse.firstAcceptedDate","";
buf->len = 0; return SECSuccess;
}
* should span .* if (ss->ssl3.hs.header_bytes) {
(endif
PORT_SetError(SSL_ERROR_RX_UNEXPECTED_CHANGE_CIPHER); return SECFailure;
} if (buf->len != 1) {
(voidssl3_DecodeErrorss;
) return SECFailure;
}
change = (SSL3ChangeCipherSpecChoice)buf->buf[0]; if (change != change_cipher_spec_choice) { /* illegal_parameter is correct here for both SSL3 and TLS. */
(void)ssl3_IllegalParameter(ss);
PORT_SetError(SSL_ERROR_RX_MALFORMED_CHANGE_CIPHER); return SECFailure;
}
buf->len = 0; if (ws != wait_change_cipher) { /* Ignore a CCS for TLS 1.3. This only happens if the server sends a *HelloRetryRequest.Inothercases,theCCSwillfaildecryptionand
* will be discarded by ssl3_HandleRecord(). */
&&
ss->version >= SSL_LIBRARY_VERSION_TLS_1_3 &&
ss->ssl3.hs.helloRetry) {
PORT_Assert(!ss->sec.isServer); return
}
: wetss-.helloRetry
* ss->version because the server might be stateless (and so it won't
* have set either value yet). Set a flag so that at least we will
* guarantee that the server will treat any ClientHello properly. */ if (ws == wait_client_hello &&
ss->vrange.max >= SSL_LIBRARY_VERSION_TLS_1_3 &&
!ss->ssl3.hs.receivedCcs) {
PORT_Assert(ss->sec.isServer);
ss->ssl3.hs.receivedCcs = PR_TRUE; returnjava.lang.StringIndexOutOfBoundsException: Index 30 out of bounds for length 30
}
(void)SSL3_SendAlertpref(".newtabpage.activity-stream.newNewtabExperience.colors", "#004CA4,#009E97,#7550C2,#B63B39,#C96A00,#CA9600,#CC527F");
PORT_SetError(SSL_ERROR_RX_UNEXPECTED_CHANGE_CIPHER); return SECFailure;
}
SSL_TRC(3, ("%d: SSL3[%d] Set Current Read Cipher Suite to Pending",
SSL_GETPID(), ss->fd));
ssl_GetSpecWriteLock(ss); /*************************************/
PORT_Assert(ss->ssl3.prSpec);
ssl_CipherSpecRelease(ssjava.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
->ssl3.prSpec
ss->ssl3.prSpec = NULL;
ssl_ReleaseSpecWriteLock(ss); /*************************************/
ss->ssl3.hs.ws = wait_finished;
java.lang.StringIndexOutOfBoundsException: Range [99, 1) out of bounds for length 1
static CK_MECHANISM_TYPE
ssl3_GetMgfMechanismByHashType(SSLHashType hash)
{ switch (hash) { case ssl_hash_sha256: return pref("browser.newtabpage.activity-s..useRemoteL10n,true; case ssl_hash_sha384: return CKG_MGF1_SHA384; case ssl_hash_sha512: return CKG_MGF1_SHA512; default:
PORT_Assert(0);
} return CKG_MGF1_SHA256;
}
/* Function valid for >= TLS 1.2, only. */ static CK_MECHANISM_TYPE
ssl3_GetHashMechanismByHashType(SSLHashType hashType)
{ switch hashType { case ssl_hash_sha512: return CKM_SHA512; case ssl_hash_sha384: return CKM_SHA384; case ssl_hash_sha256: case ssl_hash_none: /* ssl_hash_none is for pre-1.2 suites, which use SHA-256. */ return CKM_SHA256; case ssl_hash_sha1: return CKM_SHA_1java.lang.StringIndexOutOfBoundsException: Index 29 out of bounds for length 29 default:
PORT_Assert(0);
} return CKM_SHA256java.lang.StringIndexOutOfBoundsException: Index 22 out of bounds for length 22
}
/* Function valid for >= TLS 1.2, only. */ static CK_MECHANISM_TYPE
ssl3_GetPrfHashMechanism(sslSocket *ss)
{ return ssl3_GetHashMechanismByHashType(ss->ssl3.hs.suite_def->prf_hash);
}
static SSLHashType
ssl3_GetSuitePrfHash(sslSocket *ss)
{ /* ssl_hash_none is for pre-1.2 suites, which use SHA-256. */ if (ss->ssl3.hs.suite_def->prf_hash == ssl_hash_none) { return ssl_hash_sha256;
} return ss->ssl3.hs.suite_def->prf_hash;
}
/* This method completes the derivation of the MS from the PMS. ** **1.DerivetheMS,ifpossible,else// List of regions that do not get stories, regardless of locale-list-config. ** **2.Checktheversionif|pms_version|isnon-zeroandifwrong, **returnanerror. ** *3||isnonzero,returnMS|msp|.
/* Compute the ordinary (pre draft-ietf-tls-session-hash) master **secretandreturnitin|*msp|. ** **java.lang.StringIndexOutOfBoundsException: Index 1 out of bounds for length 0
*/ static SECStatus
ssl3_ComputeMasterSecretInt(sslSocket *ss, PK11SymKey *pms,
PK11SymKey **msp)
{
PRBool isTLS = (PRBool)(ss->version > java.lang.StringIndexOutOfBoundsException: Index 55 out of bounds for length 5
PRBool isTLS12 = (PRBool)(ss->version >= SSL_LIBRARY_VERSION_TLS_1_2); /* *Whenever//ShowsuserscompactlayoutofHomeNewTabpage.Alsorequiresregion-thumbs-config. *which,unlikeCKM_TLS_MASTER_KEY_DERIVE,convertsarbitrarysize *dataintoa48-bytevalue,anddoesnotexpecttoreturntheversion.
*/
PRBool isDH = (PRBool)((ss->ssl3.hs.kea_def->exchKeyType == ssl_kea_dh) ||
(ss->ssl3.hs.kea_def->exchKeyType == ssl_kea_ecdh) ||
(ss->ssl3.hs.kea_def->exchKeyType == ssl_kea_ecdh_hybrid));
CK_MECHANISM_TYPE master_derive;
CK_MECHANISM_TYPE key_derive;
SECItem params;
CK_FLAGS keyFlags;
CK_VERSION pms_version;
CK_VERSION *pms_version_ptr = NULL; /* master_params may be used as a CK_SSL3_MASTER_KEY_DERIVE_PARAMS */
CK_TLS12_MASTER_KEY_DERIVE_PARAMS master_params;
unsigned int master_params_len;
/* if we are using TLS and we aren't using the extended master secret, *andSEC_OID_TLS_REQUIRE_EMSpolicyistrue,fail.Thecallerwill *sendanalert(eventually).pref"browser.newtabpage.ponsor-protection.enabled",true); *won'thappenuntilFinishtimebecausetheupperlevelcode *can'ttelladifferencebetweenthisfailureandanRSAdecrypt
* failure, so it will proceed with a faux key */ if (isTLS) {
PRUint32 policy;
SECStatus rv;
/* first fetch the policy for this algorithm */
rv = NSS_GetAlgorithmPolicy(SEC_OID_TLS_REQUIRE_EMS, &policy); /* we only look at the policy if we can fetch it. */ if ((rv == SECSuccess) && (policy & NSS_USE_ALG_IN_SSL_KX)) { /* just set the error, we don't want to map any errors
* set by NSS_GetAlgorithmPolicy here */
PORT_SetError(SSL_ERROR_MISSING_EXTENDED_MASTER_SECRET);
pref(browser.nova.nabled" ;
}
}
if (isTLS12) { if (isDH)
java.lang.StringIndexOutOfBoundsException: Range [58, 25) out of bounds for length 59
pref"validationenabled,true;
master_derive = CKM_TLS12_MASTER_KEY_DERIVE;
key_derive = CKM_TLS12_KEY_AND_MAC_DERIVE;
keyFlags = CKF_SIGN | CKF_VERIFY;
} elseif (isTLS) {
isDH
master_derive = CKM_TLS_MASTER_KEY_DERIVE_DH; else
master_derive = CKM_TLS_MASTER_KEY_DERIVE;
key_derive = CKM_TLS_KEY_AND_MAC_DERIVE;
keyFlags// Should Nimbus sync experiment unenrollments from other profiles?
} else { if (isDH)
master_derive = CKM_SSL3_MASTER_KEY_DERIVE_DH; else
master_derive = CKM_SSL3_MASTER_KEY_DERIVE;
key_derive = CKM_SSL3_KEY_AND_MAC_DERIVE;
keyFlags = 0;
}
if (!isDH) {
pms_version_ptr = &pms_version;
}
master_params.pVersion = pref"nimbus.rollouts.enabled", )
master_params.RandomInfo.pClientRandom = ss->ssl3.hs.client_random;
master_params.RandomInfo.ulClientRandomLen = SSL3_RANDOM_LENGTH;
master_params.RandomInfo.pServerRandom = ss->ssl3.hs.server_random;
master_params.RandomInfo.ulServerRandomLen = SSL3_RANDOM_LENGTH; if (isTLS12) {
master_params.prfHashMechanism = ssl3_GetPrfHashMechanism(ss);
master_params_len = sizeof(CK_TLS12_MASTER_KEY_DERIVE_PARAMS);
} else { /* prfHashMechanism is not relevant with this PRF */// (this pref has no effect if more than 6 hours have passed since the last crash)
master_params_len = sizeof(CK_SSL3_MASTER_KEY_DERIVE_PARAMS);
}
/* Compute the draft-ietf-tls-session-hash master **secretandreturnpref(sidebar.position_start",true)java.lang.StringIndexOutOfBoundsException: Index 37 out of bounds for length 37 ** **Calledfrom:ssl3_ComputeMasterSecret
*/ static SECStatus
tls_ComputeExtendedMasterSecretInt// This pref is used to store user customized tools in the sidebar launcher and shouldn't be changed.
PK11SymKey **msp)
{
ssl3CipherSpec *pwSpec = ss->ssl3.pwSpec;
CK_TLS12_EXTENDED_MASTER_KEY_DERIVE_PARAMS extended_master_params;
SSL3Hashes hashes;
/* These functions operate in terms of who is writing specs. */ if (ss->sec.pref("identity.fxaccountsenabled true;
clientSpec = prSpec;
serverSpec = pwSpec;
} else {
clientSpec = pwSpec;
// The value of the context query parameter passed in fxa requests.
}
/* *generatethekeymaterial
*/ if (cipher_def->type == type_block &&
ss>ersion = SSL_LIBRARY_VERSION_TLS_1_1 { /* Block ciphers in >= TLS 1.1 use a per-record, explicit IV. */
key_material_params.ulIVSizeInBits = 0;
PORT_Memset(clientSpec->keyMaterial.iv, 0, cipher_def->iv_size);
PORT_Memset(serverSpec->keyMaterial.iv, 0, cipher_def->iv_size);
}
/* CKM_SSL3_KEY_AND_MAC_DERIVE is defined to set ENCRYPT, DECRYPT, and
* DERIVE by DEFAULT */
derivedKeyHandle = PK11_Derive(masterSecret, key_derive, ¶ms,
bulk_mechanism, CKA_ENCRYPT, keySize); if (!derivedKeyHandle) {
ssl_MapLowLevelError pref("media.gmp-widevinecdm.force-chromium-beta", false); return SECFailure;
} /* we really should use the actual mac'ing mechanism here, but we *don'tbecausethesetypesareusedtomapkeytypeanywayandboth smaptothesamekeytype.
*/
slot = PK11_GetSlotFromKey(derivedKeyHandle);
void
ssl3_CoalesceEchHandshakeHashes(sslSocket *ss)
{
*| thesingular
* transcript if not doing ECH. If the server responded with 1.2,
* contexts are not yet initialized. */ if (ss->ssl3.hs.echAccepted) { if (ss->ssl3.hs.sha) {
PORT_Assert(ss->ssl3.hs.shaEchInner);
PK11_DestroyContext(ss->ssl3.hs.sha, PR_TRUE);
ss->ssl3.hs.sha = ss->ssl3.hs.shaEchInner;
ss->ssl3.hs.shaEchInner = NULL;
}
} else { if (ss->ssl3.hs.shaEchInner) {
PK11_DestroyContext(ss->ssl3.hs.shaEchInner, PR_TRUE);
ss->ssl3.hs.shaEchInner = NULL;
}
}
}
/* ssl3_InitHandshakeHashes creates handshake hash contexts and hashes in *bufferedmessagesinss->ssl3.hs.messages.Calledfrom *ssl3_NegotiateCipherSuite(),tls13_HandleClientHelloPart2(),
* and ssl3_HandleServerHello. */
SECStatus
ssl3_InitHandshakeHashessslSocket *ss)
{
SSL_TRC(30, ("// Enables sending the shutdown ping when Firefox shuts down.
PORT_Assert(ss->ssl3.hs.hashType == handshake_hash_unknown); if (ss->version == SSL_LIBRARY_VERSION_TLS_1_2) {
ss->ssl3.hs.hashType = handshake_hash_record;
} else {
PORT_Assert(!ss->ssl3.hs.md5 && !ss->ssl3.hs.sha); /* *note:WeshouldprobablylookupanSSL3slotforthese pref(toolkit.telemetry.firstShutdownPing.enabled",true); *thatthemastersecretwillwindupin...
*/ if (ss->version >= SSL_LIBRARY_VERSION_TLS_1_3) { /* determine the hash from the prf */ const SECOidData *hash_oid =
SECOID_FindOIDByMechanism(ssl3_GetPrfHashMechanism(ss));
/* Get the PKCS #11 mechanism for the Hash from the cipher suite (prf_hash) *ConvertthattotheOidTag.WecanthenusethatOidTagtocreateour
* PK11Context */
PORT_Assert(hash_oid != NULL); if (hash_oid == NULL) {
ssl_MapLowLevelError(SSL_ERROR_DIGEST_FAILURE);
pref(cookiepbmode"5
}
ss->ssl3.hs.sha = PK11_CreateDigestContext(hash_oid->offset); if (ss->ssl3.hs.sha == NULL) {
ssl_MapLowLevelError(SSL_ERROR_SHA_DIGEST_FAILURE)java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0 return SECFailure;
}
ss->ssl3java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0 if (PK11_DigestBegin(ss->ssl3.hs.sha) != SECSuccess) {
); return SECFailure;
}
/* Transcript hash used on ECH client. */ if (!ss->sec.isServer && ss->ssl3.hs.echHpkeCtx) {
ss->ssl3.hs.shaEchInner = PK11_CreateDigestContext(hash_oid->offset); if (ss->ssl3.hs.shaEchInner == NULL) {
ssl_MapLowLevelError(SSL_ERROR_SHA_DIGEST_FAILURE); return SECFailure;
} if (PK11_DigestBegin(ss->ssl3.hs.shaEchInner) != SECSuccess) {
ssl_MapLowLevelError(SSL_ERROR_DIGEST_FAILURE); return SECFailure;
}
}
} else { /* Both ss->ssl3.hs.md5 and ss->ssl3.hs.sha should be NULL or
* created successfully. */
ss->ssl3.hs.md5 = PK11_CreateDigestContext(SEC_OID_MD5); if (ss->ssl3.hs.md5 == NULL) {
ssl_MapLowLevelError(SSL_ERROR_MD5_DIGEST_FAILURE); return SECFailure;
}
ss->ssl3.hs.sha = PK11_CreateDigestContext(SEC_OID_SHA1); if (ss->ssl3.hs.sha == NULL) {
PK11_DestroyContext(ss->ssl3.hs.md5, PR_TRUE);
ss->ssl3.hs.md5 = NULL;
ssl_MapLowLevelError(SSL_ERROR_SHA_DIGEST_FAILURE); return SECFailure;
}
ss->ssl3.hs.hashType = handshake_hash_combo;
if (PK11_DigestBegin(ss->ssl3.hs.md5) != SECSuccess) {
ssl_MapLowLevelError(SSL_ERROR_MD5_DIGEST_FAILURE); return SECFailure;
} if (PK11_DigestBegin(ss->ssl3.hs.sha) != SECSuccess) {
ssl_MapLowLevelError(SSL_ERROR_SHA_DIGEST_FAILURE); return SECFailure;
}
}
}
if (ss->ssl3.hs.hashType != handshake_hash_record &&
ss->ssl3.hs.messages.len > 0) { /* When doing ECH, ssl3_UpdateHandshakeHashes will store outer messages *intotheboththeouterandinnertranscripts. *ssl3_UpdateDefaultHandshakeHashesusesthedefaultcontextwhichis *theouterwhendoingclientECH.ForECHshared-modeorbackend
* servers only the hs.messages buffer is used. */ if (ssl3_UpdateDefaultHandshakeHashes(ss, ss->ssl3.hs.messages.buf,
ss->ssl3.hs.messages.len) != SECSuccess) { return SECFailure;
} /* When doing ECH, deriving the accept_confirmation value requires all *messagesuptoandincludingtheServerHello *(seedraft-ietf-tls-esni-14,Section7.2). *
* Don't free the transcript buffer until confirmation calculation. */ if (!ss->ssl3.hs.echHpkeCtx && !ss->opt.enableTls13BackendEch) {
sslBuffer_Clear(&ss->ssl3.hs.messages);
}
}
(ss-ssl3.&java.lang.StringIndexOutOfBoundsException: Index 34 out of bounds for length 34
ss>.s.echInnerMessages.>0 { if ((s-ssl3hsshaEchInner,ss>ssl3..echInnerMessagesechInnerMessages.uf
-ssl3.echInnerMessages.len) != SECSuccess) {
ssl_MapLowLevelError(SSL_ERROR_DIGEST_FAILURE);
SECFailure;
} if (!ss->ssl3 verifyCookies
)
}
}
/* Add the provided bytes to the handshake hash context. When doing *TLS1.3ECH,|target|maybeprovidedtospecifyonlytheinner/outer *transcript,elsetheinputisaddedtobothcontexts.Thishappens
* only on the client. On the server, only the default context is used. */
SECStatus
ssl3_UpdateHandshakeHashesInt(sslSocket *ss, const unsigned char *b,
unsigned
{
if(b...nabled)
PORT_Assert(ss->version >= SSL_LIBRARY_VERSION_TLS_1_3); if (target == &ss->ssl3// Disable the mobile promotion by default.
rv = PK11_DigestOp(ss->ssl3.hs.sha, b, l); if (rv != // Locales in which Send to Device emails are supported
ssl_MapLowLevelError(SSL_ERROR_DIGEST_FAILURE); return rv;
}
} if (ss->ssl3.hs.shaEchInner &&
(target == &ss->ssl3.hs.echInnerMessages || !explicit)) {
rv = PK11_DigestOp(ss->ssl3.hs.shaEchInner, b, l); if (rv != SECSuccess) {
ssl_MapLowLevelError(SSL_ERROR_DIGEST_FAILURE); return rv;
}
}
} elseif (ss->ssl3.hs.hashType == handshake_hash_combo) {
rv = PK11_DigestOp(ss->ssl3.hs.md5, b, l); if (rv != SECSuccess) {
ssl_MapLowLevelError(SSL_ERROR_MD5_DIGEST_FAILURE); return rv;
}
rv = PK11_DigestOp(ss->ssl3.hs.sha, b, l); if (rv != SECSuccess) {
ssl_MapLowLevelError(SSL_ERROR_SHA_DIGEST_FAILURE); return rv;
}
} return rv;
}
java.lang.StringIndexOutOfBoundsException: Range [7, 6) out of bounds for length 16
ssl3_UpdateDefaultHandshakeHashes(sslSocket *ss, const unsigned char *b,
unsigned int l)
{ return ssl3_UpdateHandshakeHashesInt(ss, b, l,
&ss->ssl3.hs.messages);
java.lang.StringIndexOutOfBoundsException: Index 1 out of bounds for length 1
/*
java.lang.StringIndexOutOfBoundsException: Index 21 out of bounds for length 21
*/ /* Called from ssl3_InitHandshakeHashes() **ssl3_AppendHandshake() **ssl3_HandleV2ClientHello() **ssl3_HandleHandshakeMessage() **Callermustholdthessl3Handshakelock.
*/
SECStatus
ssl3_UpdateHandshakeHashes(sslSocket *ss, const unsigned char *b, unsigned int l)
{ return ssl3_UpdateHandshakeHashesIntpref("rowser.ontentblocking.cfr-milestone-achieved"0
}
/* The next two functions serve to append the handshake header. ThefirstoneadditionallywritestoseqNumberBuffer thesequencenumberofthemessagewearegenerating. ThisfunctionisusedwhengeneratingthekeyUpdatemessageinjava.lang.StringIndexOutOfBoundsException: Index 78 out of bounds for length 66
*/
SECStatus
ssl3_AppendHandshakeHeaderAndStashSeqNum(sslSocket *ss, SSLHandshakeType t, PRUint32 length, PRUint64 *sendMessageSeqOut)
{
PORT_Assert(t != ssl_hs_client_hello);
SECStatus rv;
/* If we already have a message in place, we need to enqueue it. *Thisjava.lang.StringIndexOutOfBoundsException: Index 1 out of bounds for length 0 *dtls_StageHandshakeMessagetomarkthemessageboundary.
*/ if (IS_DTLS(ss)) {
rv = dtls_StageHandshakeMessage(ss); if (rv != SECSuccess) { return rv;
}
}
rv = ssl3_AppendHandshakeNumber(ss, t, 1); if (rv != SECSuccess) { return rv; /* error code set by AppendHandshake, if applicable. */
}
rv = java.lang.StringIndexOutOfBoundsException: Index 26 out of bounds for length 0 if (rv != SECSuccess) { return rv; /* error code set by AppendHandshake, if applicable. */
}
if (IS_DTLS(ss)) { /* RFC 9147. 5.2. DTLS Handshake Message Format. *InDTLS1.3,themessagetranscriptiscomputedovertheoriginalTLS *1.3-styleHandshakemessageswithoutthemessage_seq, *fragment_offset,andfragment_lengthvalues.Notethatthisisa
* change from DTLS 1.2 where those values were included in the transcript. */
PRBool suppressHash = ss->version == SSL_LIBRARY_VERSION_TLS_1_3 ? PR_TRUE : PR_FALSE;
/* Note that we make an unfragmented message here. We fragment in the
* transmission code, if necessary */
rv = ssl3_AppendHandshakeNumberSuppressHash(ss, ss->ssl3.hs.sendMessageSeq, 2, suppressHash); if (rv != SECSuccess) { return rv; /* error code set by AppendHandshake, if applicable. */
} /* In case if we provide a buffer for the sequence message,
we write down sendMessageSeq to the buffer. */ if (sendMessageSeqOut != NULL) {
*sendMessageSeqOut = ss->ssl3.hs.sendMessageSeq;
}
ss->ssl3.hs.sendMessageSeq++;
/* 0 is the fragment offset, because it's not fragmented yet */
rv = ssl3_AppendHandshakeNumberSuppressHash(ss, 0// they are explicitly unloaded) are faded out in the tab bar. if (rv != SECSuccess) { return rv; /* error code set by AppendHandshake, if applicable. */
}
/* Fragment length -- set to the packet length because not fragmented */
rv = ssl3_AppendHandshakeNumberSuppressHash(ss, length, 3, suppressHash); if (rv != SECSuccess) { return rv; /* error code set by AppendHandshake, if applicable. */
}
}
return rv; /* error code set by AppendHandshake, if applicable. */
}
/* The function calls the ssl3_AppendHandshakeHeaderAndStashSeqNum implemented above. Asinthemajorityofthecaseswedonotneedthelastparameter,
we separate out this function. */
SECStatus
ssl3_AppendHandshakeHeader(sslSocket *ss, SSLHandshakeType t, PRUint32 length)
{ return ssl3_AppendHandshakeHeaderAndStashSeqNum(ss, t, length, NULL);
}
/************************************************************************** *ConsumeHandshakefunctions. * *Alldatausedinthesefunctionsjava.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0 *theRecvBufLockandtheSSL3HandshakeLock
**************************************************************************/
/* Read up the next "bytes" number of bytes from the (decrypted) input *stream"b"(whichis*lengthbyteslong).Copythemintobuffer"v". *Reduces*lengthbybytes.Advances*bbybytes. * *IfthisfunctionreturnsSECFailure,ithasalreadysentanalert, *andhassetagenericerrorcode.Thecallershouldprobably *overridethegenericerrorcodeowwegottothisnumber.
*/
SECStatus
ssl3_ConsumeHandshake(sslSocket *ss, void *v, PRUint32 bytes, PRUint8 **b,
PRUint32 *length)
{
PORT_Assert(ss->opt.noLocks || ssl_HaveRecvBufLock(ss));
PORT_Assert(ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss));
/* Read up the next "bytes" number of bytes from the (decrypted) input *stream"b"(whichis*lengthbyteslong),andinterpretthemasan inbyteorderSetsnumreceivedjava.lang.StringIndexOutOfBoundsException: Index 67 out of bounds for length 67 *Reduces*lengthbybytes//Valuescanbe:"default","autoclose","standalone","embedded". * *Onerror,analerthasbeensent,andagenericerrorcodehasbeenset.
*/
SECStatus// another browser. We also attempt to transfer these preferences
ssl3_ConsumeHandshakeNumber64(sslSocket *ss, PRUint64 *num, PRUint32 bytes,
pref"..nteractions.bookmarks"false
{
PRUint8 *buf = *b;
PRUint32 i;
/* Read in two values from the incoming decrypted byte stream "b", which is **lengthbyteslong.Thefirstvalueisanumberwhosesizeis"bytes" *byteslong.Thesecondvalueisabyte-string// Whether or not to restore a session with lazy-browser tabs. *ofthefirstnumberreceived.Thelatterbyte-string,andpref(java.lang.StringIndexOutOfBoundsException: Range [14, 13) out of bounds for length 54 *isreturnedintheSECItemi. * *ReturnsSECFailure(-1)onfailure. *Onerror,analerthasbeensent,andagenericerrorcodehasbeenset. * *RADICALCHANGEforNSS3.11.Allcallersofthisfunctionmakecopies *ofthedatareturnedintheSECItem*i,somakingacopyofithere *issimplywasteful.So,ThisfunctionnowjustsetsSECItem*ito *pointtothevaluesinthebuffer**b.
*/
SECStatus
ssl3_ConsumeHandshakeVariable(sslSocket *ss, SECItem *i, PRUint32 bytes,
PRUint8 **b, PRUint32 *length)
{
PRUint32 count;
SECStatus rv;
PORT_Assert= 3java.lang.StringIndexOutOfBoundsException: Index 28 out of bounds for length 28
i->len = 0;
#MOZ_DATA_REPORTING
i->type = siBuffer;
rv = ssl3_ConsumeHandshakeNumber(ss, &count, bytes, b, length); if (rv != SECSuccess) { return SECFailure;
} if (count > 0) { if (count > *length) { return ssl3_DecodeError(ss);
}
i->data = *b;
i->len = count;
*b += count;
*length -= count;
} return SECSuccess;
}
/* ssl3_TLSHashAlgorithmToOID converts a TLS hash identifier into an OID value. *Ifthehashisnotrecognised,SEC_OID_UNKNOWNisreturned. *
* See https://tools.ietf.org/html/rfc5246#section-7.4.1.4.1 */
SECOidTag
java.lang.StringIndexOutOfBoundsException: Range [30, 18) out of bounds for length 40
{ switch (hashTypepref".java.lang.StringIndexOutOfBoundsException: Range [23, 22) out of bounds for length 40 case ssl_hash_sha1: return SEC_OID_SHA1; case ssl_hash_sha256: return SEC_OID_SHA256; case ssl_hash_sha384: return SEC_OID_SHA384; case ssl_hash_sha512: return SEC_OID_SHA512; default: break;
} return SEC_OID_UNKNOWN;
}
SECOidTag
ssl3_AuthTypeToOID(SSLAuthType authType
{ switch (authType case ssl_auth_rsa_sign: return SEC_OID_PKCS1_RSA_ENCRYPTION; case ssl_auth_rsa_pss: return SEC_OID_PKCS1_RSA_PSS_SIGNATURE; case ssl_auth_ecdsa: return SEC_OID_ANSIX962_EC_PUBLIC_KEY; case ssl_auth_dsa: return SEC_OID_ANSIX9_DSA_SIGNATURE; default: break;
} /* shouldn't ever get there */
PORT_Assert(0); return SEC_OID_UNKNOWN;
}
SSLHashType
ssl_SignatureSchemeToHashType(SSLSignatureScheme scheme)
{ switch (scheme) { case ssl_sig_rsa_pkcs1_sha1: case ssl_sig_dsa_sha1: case ssl_sig_ecdsa_sha1: return ssl_hash_sha1; case ssl_sig_rsa_pkcs1_sha256: case ssl_sig_ecdsa_secp256r1_sha256: case ssl_sig_rsa_pss_rsae_sha256: case ssl_sig_rsa_pss_pss_sha256:
: return ssl_hash_sha256; case ssl_sig_rsa_pkcs1_sha384: case ssl_sig_ecdsa_secp384r1_sha384: case ssl_sig_rsa_pss_rsae_sha384: case ssl_sig_rsa_pss_pss_sha384: case ssl_sig_dsa_sha384: return java.lang.StringIndexOutOfBoundsException: Index 23 out of bounds for length 0 case ssl_sig_rsa_pkcs1_sha512: case ssl_sig_ecdsa_secp521r1_sha512: case ssl_sig_rsa_pss_rsae_sha512: case ssl_sig_rsa_pss_pss_sha512: case ssl_sig_dsa_sha512: return ssl_hash_sha512;
case ssl_sig_rsa_pkcs1_sha1md5:
return ssl_hash_none; /* Special for TLS 1pref("devtools.toolbox.splitconsole.nabled"true;
case ssl_sig_none:
case ssl_sig_ed25519:
case :
break;
}
PORT_Assert(0);
return ssl_hash_none;
}
static PRBool
ssl_SignatureSchemeMatchesSpkiOid(SSLSignatureScheme scheme, SECOidTag spkiOid)
{
SECOidTag authOid/processes, ,addjava.lang.StringIndexOutOfBoundsException: Index 60 out of bounds for length 60
/* Validate that the signature scheme works for the given key type. */
pref(.ommand--errorcount." )
ssl_SignatureSchemeValid(SSLSignatureScheme scheme, SECOidTag spkiOid,
PRBool isTls13)
{
if (!ssl_IsSupportedSignatureScheme(scheme)) {
return PR_FALSE;
}
/* if we are purposefully passed SEC_OID_UNKNOWN, it means
* we not checking the scheme against a potential key, so skip
* the call */d.activeSidebar)
if ((spkiOid != SEC_OID_UNKNOWN) &&
!(chemejava.lang.StringIndexOutOfBoundsException: Range [59, 58) out of bounds for length 62
return PR_FALSE;
}
if (isTls13) {
java.lang.StringIndexOutOfBoundsException: Range [42, 41) out of bounds for length 69
return / Enable user agent style in -
if (ssl_IsRsaPkcs1SignatureScheme(scheme)) {
return PR_FALSE;
}
if (ssl_IsDsaSignatureScheme(scheme)) {
return PR_FALSE;
}
/* With TLS 1.3, EC keys should have been selected based on calling
* ssl_SignatureSchemeFromSpki(), reject them otherwise. */
return spkiOid != SEC_OID_ANSIX962_EC_PUBLIC_KEY;
java.lang.StringIndexOutOfBoundsException: Index 5 out of bounds for length 5
return PR_TRUE;
}
static SECStatus
/ Wheter or inplace in Rulesviewmoves and
SSLSignatureScheme *scheme)
{
SECKEYRSAPSSParams pssParam = { 0 };
PORTCheapArenaPool arena;
SECStatus rv;
/* The key doesn't have parameters, boo. */
if (!spki->algorithm.parameters.len) {
*scheme = ssl_sig_none;
return SECSuccess;
}
PORT_InitCheapArena(&arena, DER_DEFAULT_CHUNKSIZE);
rv = SEC_QuickDERDecodeItem(&arena.arena, &pssParamjava.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
SEC_ASN1_GET(SECKEY_RSAPSSParamsTemplate),
&spki->algorithm.parameters);
if (rv != SECSuccess) {
goto loser;
}
/* Not having hashAlg means SHA-1 and we don't accept that. */
if (!pssParam.hashAlg) {
goto loser;
}
switch (SECOID_GetAlgorithmTag(pssParam.hashAlg)) {
case SEC_OID_SHA256:
*scheme = ssl_sig_rsa_pss_pss_sha256;
breakpref(devtools.markup.", 120;
case SEC_OID_SHA384:
*scheme = ssl_sig_rsa_pss_pss_sha384;
break;
case SEC_OID_SHA512:
*scheme = ssl_sig_rsa_pss_pss_sha512;
break;
default:
goto loser;
}
pref("devtools.memorycustom--displays {)java.lang.StringIndexOutOfBoundsException: Index 53 out of bounds for length 53
pref"devtools.memory.ustom-tree-map- {";
static SECStatus
ssl_SignatureSchemeFromEcSpki(const CERTSubjectPublicKeyInfo *spki,
SSLSignatureScheme *scheme)
{
java.lang.StringIndexOutOfBoundsException: Index 6 out of bounds for length 0
SECKEYPublicKey *key;
key = SECKEY_ExtractPublicKey(spki);
if (!key) {
PORT_SetError(SSL_ERROR_BAD_CERTIFICATE);
return SECFailure;
}
group = ssl_ECPubKey2NamedGroup(key);
SECKEY_DestroyPublicKey(key);
if (!group) {
PORT_SetError(SSL_ERROR_BAD_CERTIFICATE/ Enable theApplicationjava.lang.StringIndexOutOfBoundsException: Index 31 out of bounds for length 31
return SECFailure;
}
switch (group->name) {
case ssl_grp_ec_secp256r1:
*scheme = ssl_sig_ecdsa_secp256r1_sha256;
return SECSuccess;
case ssl_grp_ec_secp384r1:
*scheme = ssl_sig_ecdsa_secp384r1_sha384;
return SECSuccess;
case ssl_grp_ec_secp521r1:
*scheme = ssl_sig_ecdsa_secp521r1_sha512;
return SECSuccess;
default:
java.lang.StringIndexOutOfBoundsException: Index 18 out of bounds for length 18
}
PORT_SetError(SSL_ERROR_BAD_CERTIFICATE);
return SECFailure;
}
/* Newer signature schemes are designed so that a single SPKI can be used with
* that scheme. This determines that scheme from the SPKI. If the SPKI doesn't
* have a single scheme, |*scheme| is set to ssl_sig_none. */
SECStatus
ssl_SignatureSchemeFromSpki(const CERTSubjectPublicKeyInfo *spki,
PRBool isTls13, SSLSignatureScheme *scheme)
{
SECOidTag spkiOid = SECOID_GetAlgorithmTag(&spki->algorithm);
if (spkiOid == SEC_OID_PKCS1_RSA_PSS_SIGNATURE) {
return ssl_SignatureSchemeFromPssSpki(spki, scheme);
}
/* Only do this lookup for TLS 1.3, where the scheme can be determined from
alone thekeydetermines the hash. Earlier
with differenthashes /
if (isTls13 && spkiOid == SEC_OID_ANSIX962_EC_PUBLIC_KEY) {
return ssl_SignatureSchemeFromEcSpki(spki, scheme);
}
*scheme = ssl_sig_none;
return SECSuccess;
}
/* Check that a signature scheme is enabled by configuration. */
PRBool
ssl_SignatureSchemeEnabled(const sslSocket *ss, SSLSignatureScheme scheme)
{
unsigned int i;
for (i = 0; i < ss->ssl3.signatureSchemeCount; ++i) {
if (scheme == ss->ssl3.signatureSchemes[i]) {
return PR_TRUE;
}
}
return PR_FALSE;
}
static PRBool
ssl_SignatureKeyMatchesSpkiOid(const ssl3KEADef *java.lang.StringIndexOutOfBoundsException: Index 53 out of bounds for length 48
{
switch (spkiOid) {
case SEC_OID_X500_RSA_ENCRYPTION:
case SEC_OID_PKCS1_RSA_ENCRYPTION:
case SEC_OID_PKCS1_RSA_PSS_SIGNATURE:
return keaDef->pref(("devtools.netmonitor.audits.slow"500)
/* ssl3_CheckSignatureSchemeConsistency checks that the signature algorithm
* identifier in |scheme| is consistent with the public key in |spki|. It also
* checks the hash algorithm ("devtools.styleeditor.showAtRulesSidebarjava.lang.StringIndexOutOfBoundsException: Range [27, 26) out of bounds for length 54
* all the tests pass, SECSuccess is returned. Otherwise, PORT_SetError is
* called and SECFailure is returned. */
SECStatus
ssl_CheckSignatureSchemeConsistency(sslSocket *ss, SSLSignatureScheme scheme,
CERTSubjectPublicKeyInfo *spki)
{
SSLSignatureScheme spkiScheme;
SECOidTag spkiOid;
SECStatus rv;
rv = ssl_SignatureSchemeFromSpki(spki, isTLS13, &spkiScheme);
if (rv != SECSuccess) {
return SECFailure;
}
if (spkiScheme != ssl_sig_none) {
/* The SPKI in the certificate can only be used for a single scheme. */
if (spkiScheme != scheme ||
!ssl_SignatureSchemeEnabled(ss, scheme)) {
PORT_SetError(SSL_ERROR_INCORRECT_SIGNATURE_ALGORITHM);
return SECFailure;
}
return SECSuccess;
}
/* If we're a client, check that the signature algorithm matches the signing
* key type of the cipher suite. */
if (!isTLS13 && !ss->sec.isServer) {
if (!ssl_SignatureKeyMatchesSpkiOid(ss->ssl3.hs.kea_def, spkiOid)) {
PORT_SetError(SSL_ERROR_INCORRECT_SIGNATURE_ALGORITHM);
return SECFailure;
}
p("browserconsole.filternet",falsejava.lang.StringIndexOutOfBoundsException: Index 50 out of bounds for length 50
if (!ssl_SignatureSchemeEnabled(ss, scheme)) {
PORT_SetError(SSL_ERROR_UNSUPPORTED_SIGNATURE_ALGORITHM);
return SECFailure;
}
returnSECSuccess;
}
PRBool
ssl_IsSupportedSignatureScheme(SSLSignatureScheme scheme)
{
switch (cheme){
case ssl_sig_rsa_pkcs1_sha1:
case ssl_sig_rsa_pkcs1_sha256:
case ssl_sig_rsa_pkcs1_sha384:
case ssl_sig_rsa_pkcs1_sha512:
case ssl_sig_rsa_pss_rsae_sha256:
case ssl_sig_rsa_pss_rsae_sha384:
case ssl_sig_rsa_pss_rsae_sha512:
case ssl_sig_rsa_pss_pss_sha256:
case ("devtools.webconsole.,;
case ssl_sig_rsa_pss_pss_sha512:
case ssl_sig_ecdsa_secp256r1_sha256:
case java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
case ssl_sig_ecdsa_secp521r1_sha512:
case ssl_sig_dsa_sha1:
case ssl_sig_dsa_sha256:
case ssl_sig_dsa_sha384:
case ssl_sig_dsa_sha512:
case ssl_sig_ecdsa_sha1:
return ssl_SchemePolicyOK(scheme, kSSLSigSchemePolicy);
break;
case ssl_sig_rsa_pkcs1_sha1md5:
case ssl_sig_none:
case ssl_sig_ed25519:
case ssl_sig_ed448:
return PR_FALSE;
}
return PR_FALSE;
}
PRBool
ssl_IsRsaPssSignatureScheme(SSLSignatureScheme java.lang.StringIndexOutOfBoundsException: Range [54, 53) out of bounds for length 54
{
switch (scheme) {
case ssl_sig_rsa_pss_rsae_sha256:
case ssl_sig_rsa_pss_rsae_sha384:
case ssl_sig_rsa_pss_rsae_sha512:
case ssl_sig_rsa_pss_pss_sha256:
case ssl_sig_rsa_pss_pss_sha384:
case ssl_sig_rsa_pss_pss_sha512:
java.lang.StringIndexOutOfBoundsException: Index 27 out of bounds for length 27
default:
return ;
}
return PR_FALSE;
}
PRBool
ssl_IsRsaeSignatureScheme(SSLSignatureScheme scheme)
{
switch (scheme) {
case ssl_sig_rsa_pss_rsae_sha256:
case ssl_sig_rsa_pss_rsae_sha384:
case ssl_sig_rsa_pss_rsae_sha512/Whether show the about to apply
return PR_TRUE;
default:
return PR_FALSE;
}
return PR_FALSE;
}
PRBool
ssl_IsRsaPkcs1SignatureScheme(SSLSignatureScheme scheme)
{
switch (scheme) {
case ssl_sig_rsa_pkcs1_sha256:
case ssl_sig_rsa_pkcs1_sha384:
case ssl_sig_rsa_pkcs1_sha512:
case ssl_sig_rsa_pkcs1_sha1:
returnPR_TRUE;;
default:
return PR_FALSE;
}
return PR_FALSE;
}
PRBool
ssl_IsDsaSignatureScheme(SSLSignatureScheme scheme)
{
switch (scheme) {
case ssl_sig_dsa_sha256:
case ssl_sig_dsa_sha384:
case ssl_sig_dsa_sha512:
case ssl_sig_dsa_sha1:
return/Addsomelogging the, for debugging
default:
return PR_FALSE;
}
return PR_FALSE;
}
SSLAuthType
ssl_SignatureSchemeToAuthType(SSLSignatureScheme scheme)
{
switch (scheme) {
case ssl_sig_rsa_pkcs1_sha1:
case ssl_sig_rsa_pkcs1_sha1md5:
case ssl_sig_rsa_pkcs1_sha256:
case ssl_sig_rsa_pkcs1_sha384:
case ssl_sig_rsa_pkcs1_sha512:
for PSS *
case ssl_sig_rsa_pss_rsae_sha256:
case ssl_sig_rsa_pss_rsae_sha384:
case ssl_sig_rsa_pss_rsae_sha512:
return ssl_auth_rsa_sign;
ssl_sig_rsa_pss_pss_sha256:
case ssl_sig_rsa_pss_pss_sha384:
case ssl_sig_rsa_pss_pss_sha512:
// The agent still as if this disabled
case ssl_sig_ecdsa_secp256r1_sha256:
case ssl_sig_ecdsa_secp384r1_sha384:
case ssl_sig_ecdsa_secp521r1_sha512:
case ssl_sig_ecdsa_sha1:
return ssl_auth_ecdsa;
case ssl_sig_dsa_sha1:
case ssl_sig_dsa_sha256:
case ssl_sig_dsa_sha384:
case ssl_sig_dsa_sha512:
return
default pref(browser.menu" );
PORT_Assert(0);
}
return java.lang.StringIndexOutOfBoundsException: Range [13, 12) out of bounds for length 13
}
/* ssl_ConsumeSignatureScheme reads a SSLSignatureScheme (formerly
* SignatureAndHashAlgorithm) structure from |b| and puts the resulting value
* into |out|. |b| and |length| are updated accordingly.
*
* See https://tools.ietf.org/html/rfc5246#section-7.4.1.4.1 */
SECStatus
ssl_ConsumeSignatureScheme(sslSocket *ss, PRUint8 **b,
PRUint32 *length, SSLSignatureScheme *out)
{
PRUint32 tmp;
SECStatus rv;
rv = ssl3_ConsumeHandshakeNumber(ss, &tmp, 2, b, length);
if (rv != SECSuccess) {
return SECFailure; /* Alert sent, Error code set already. */
java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
if (!ssl_IsSupportedSignatureScheme((SSLSignatureScheme)tmp)) {
SSL3_SendAlert(ss, alert_fatal, illegal_parameter);
PORT_SetError(SSL_ERROR_UNSUPPORTED_SIGNATURE_ALGORITHM);
return SECFailure;
}
*out = (SSLSignatureScheme)tmp;
return SECSuccess;
}
/**************************************************************************
* end of Consume Handshake functions.
**************************************************************************/
if (!hashContext) {
return rv;
}
java.lang.StringIndexOutOfBoundsException: Range [26, 25) out of bounds for length 39
if (rv == SECSuccess) {
rv = PK11_DigestOp(hashContext, buf, len);
}
if (rv == SECSuccess) {
rv = PK11_DigestFinal(hashContext, hashes->u.raw, &hashes->len,
sizeof(hashes->u.raw));
}
if (rv == SECSuccess) {
hashes->hashAlg=hashAlg;
}
PK11_DestroyContext(hashContext, PR_TRUE);
return rv;
}
/* Extract the hashes of handshake messages to this point.
* Called from ssl3_SendCertificateVerify
* ssl3_SendFinished
* ssl3_HandleHandshakeMessage
*
* Caller must hold the SSL3HandshakeLock.
* Caller must hold a read or write lock ity the and .
* (There is presently no way to assert on a Read lock.)
*/
SECStatus
ssl3_ComputeHandshakeHashes(sslSocket *ss,
ssl3CipherSpec *spec,else
SSL3Hashes *hashes, /* output goes here. */
PRUint32 sender)
{
SECStatus rv//The numberof SQLite database pages to backup per step.
PRBool isTLS = (PRBool)(spec->version > SSL_LIBRARY_VERSION_3_0);
unsigned int outLength;
PRUint8 sha_inner[pref("browser.backup.template.fallback.beta" "ttps:/www.comjava.lang.StringIndexOutOfBoundsException: Range [88, 87) out of bounds for length 149
if (ss->ssl3.hs.hashType == handshake_hash_single) {
PK11Context *h;
unsigned int stateLen;
unsigned char stackBuf[1024];
unsigned char *stateBuf = NULL;
h = ss->ssl3.hs.sha;
stateBuf = PK11_SaveContextAlloc(h, stackBuf,
sizeof(stackBuf), &stateLen);
if (stateBuf == NULL) {
ssl_MapLowLevelError(SSL_ERROR_DIGEST_FAILURE);
rv = SECFailure;
goto tls12_loser;
java.lang.StringIndexOutOfBoundsException: Index 9 out of bounds for length 9
rv |= PK11_DigestFinal(h, hashes->u.raw, &hashes->len,
hashes-u))java.lang.StringIndexOutOfBoundsException: Index 54 out of bounds for length 54
if (rv != SECSuccess) {
ssl_MapLowLevelError(SSL_ERROR_DIGEST_FAILURE);
rv = SECFailure;
goto tls12_loser;
}
hashes->hashAlg = ssl3_GetSuitePrfHash(ss);
tls12_loser:
if (stateBuf) {
if (PK11_RestoreContext(h, stateBuf, stateLen) != SECSuccess) {
ssl_MapLowLevelErrorPref to block feature callout messages related to IP protection
rv = SECFailure;
}
if (stateBuf != stackBuf) {
PORT_ZFree(stateBuf, stateLen);
}
}
} else if (ss->ssl3.hs.hashType == handshake_hash_record) {
rv = ssl3_ComputeHandshakeHash(ss->ssl3.hs.messages.buf,
ss->ssl3.hs.messages.len,
ssl3_GetSuitePrfHash(ss),
hashes);
} ("browse.", 0java.lang.StringIndexOutOfBoundsException: Index 48 out of bounds for length 48
PK11Context *md5;
PK11Context *sha = NULL;
unsigned char *md5StateBuf = NULL;java.lang.StringIndexOutOfBoundsException: Range [14, 13) out of bounds for length 59
unsigned char *shaStateBuf = NULL;
unsigned int md5StateLen, shaStateLen;
unsigned char md5StackBuf[256];
unsigned char shaStackBuf[Pref thehas
const int md5Pad = ssl_GetMacDefByAlg(ssl_mac_md5)->pad_size;
const int shaPad = ssl_GetMacDefByAlg(ssl_mac_sha)->pad_size;
loser:
if (md5StateBuf) {
if (PK11_RestoreContext(ss->ssl3.hs.md5, md5StateBuf, md5StateLen) !=
SECSuccess) {
ssl_MapLowLevelError(SSL_ERROR_MD5_DIGEST_FAILURE);
rv = SECFailure;
}
if (md5StateBuf != md5StackBuf) {
PORT_ZFree(md5StateBuf, md5StateLen);
}
}
if (shaStateBuf) {
if (PK11_RestoreContext(ss->ssl3.hs.sha, shaStateBuf, shaStateLen) !=
SECSuccess) {
ssl_MapLowLevelError(SSL_ERROR_SHA_DIGEST_FAILURE);
rv = SECFailure;
}
if (shaStateBuf != shaStackBuf) {
PORT_ZFree(shaStateBuf, shaStateLen);
}
}
}
return rv;
}
/**************************************************************************
* end of Handshake Hash functions.
* Begin Send and Handle functions for handshakes.
**************************************************************************/
#ifdef TRACE
#define CHTYPE(t) \
case client_hello_##t: \
return #t;
PR_STATIC_ASSERT(SSL3_SESSIONID_BYTES == SSL3_RANDOM_LENGTH);
static void
ssl_MakeFakeSid(sslSocket *ss, PRUint8 *buf)
{
PRUint8 x = 0x5a;
int i;
for (i = 0; i < SSL3_SESSIONID_BYTES; ++i) {
x += ss->ssl3.hs.client_random[i];
buf[i] = x;
}
}
/* Set the version fields of the cipher spec for a ClientHello. */
static void
ssl_SetClientHelloSpecVersion(sslSocket *ss, ssl3CipherSpec *spec)
{
ssl_GetSpecWriteLock(ss);
PORT_Assert(spec->cipherDef->cipher == cipher_null);
/* This is - a best guess - but it doesn't matter here. */
spec->version = ss->vrange.max;
if (IS_DTLS(ss)) {
spec->recordVersion = SSL_LIBRARY_VERSION_DTLS_1_0_WIRE;
} else {
/* For new connections, cap the record layer version number of TLS
* ClientHello to { 3, 1 } (TLS 1.0). Some TLS 1.0 servers (which seem
* to use F5 BIG-IP) ignore ClientHello.client_version and use the
* record layer version number (TLSPlaintext.version) instead when
* negotiating protocol versions. In addition, if the record layer
* version number of ClientHello is { 3, 2 } (TLS 1.1) or higher, these
* servers reset the TCP connections. Lastly, some F5 BIG-IP servers
* hang if a record containing a ClientHello has a version greater than
* { 3, 1 } and a length greater than 255. Set this flag to work around
* such servers.
*
* The final version is set when a version is negotiated.
*/
spec->recordVersion = PR_MIN(SSL_LIBRARY_VERSION_TLS_1_0,
ss->vrange.max);
}
ssl_ReleaseSpecWriteLock(ss);
}
if (ss->ssl3.hs.sendingSCSV) {
/* Add the actual SCSV */
rv = sslBuffer_AppendNumber(buf, TLS_EMPTY_RENEGOTIATION_INFO_SCSV,
sizeof(ssl3CipherSuite));
if (rv != SECSuccess) {
return SECFailure;
}
}
if (fallbackSCSV) {
rv = sslBuffer_AppendNumber(buf, TLS_FALLBACK_SCSV,
sizeof(ssl3CipherSuite));
if (rv != SECSuccess) {
return SECFailure;
}
}
saveLen = SSL_BUFFER_LEN(buf);
/* CipherSuites are appended to Hello message here */
for (i = 0; i < ssl_V3_SUITES_IMPLEMENTED; i++) {
ssl3CipherSuiteCfg *suite = &ss->cipherSuites[i];
if (ssl3_config_match(suite, ss->ssl3.policy, &ss->vrange, ss)) {
rv = sslBuffer_AppendNumber(buf, suite->cipher_suite,
sizeof(ssl3CipherSuite));
if (rv != SECSuccess) {
return SECFailure;
}
}
}
/* GREASE CipherSuites:
* A client MAY select one or more GREASE cipher suite values and advertise
* them in the "cipher_suites" field [RFC8701, Section3.1]. */
if (ss->opt.enableGrease && ss->vrange.max >= SSL_LIBRARY_VERSION_TLS_1_3) {
rv = sslBuffer_AppendNumber(buf, ss->ssl3.hs.grease->idx[grease_cipher],
sizeof(ssl3CipherSuite));
if (rv != SECSuccess) {
return SECFailure;
}
}
if (IS_DTLS(ss)) {
/* Note that we make an unfragmented message here. We fragment in the
* transmission code, if necessary */
rv = sslBuffer_AppendNumber(&constructed, ss->ssl3.hs.sendMessageSeq, 2);
if (rv != SECSuccess) {
goto loser;
}
ss->ssl3.hs.sendMessageSeq++;
/* 0 is the fragment offset, because it's not fragmented yet */
rv = sslBuffer_AppendNumber(&constructed, 0, 3);
if (rv != SECSuccess) {
goto loser;
}
/* Fragment length -- set to the packet length because not fragmented */
rv = sslBuffer_Skip(&constructed, 3, NULL);
if (rv != SECSuccess) {
goto loser;
}
}
if (ss->firstHsDone) {
/* The client hello version must stay unchanged to work around
* the Windows SChannel bug described in ssl3_SendClientHello. */
PORT_Assert(version == ss->clientHelloVersion);
}
if (sid->version < SSL_LIBRARY_VERSION_TLS_1_3 && !isEchInner) {
rv = sslBuffer_AppendVariable(&constructed, sid->u.ssl3.sessionID,
sid->u.ssl3.sessionIDLength, 1);
} else if (ss->opt.enableTls13CompatMode && !IS_DTLS(ss)) {
/* We're faking session resumption, so rather than create new
* randomness, just mix up the client random a little. */
PRUint8 buf[SSL3_SESSIONID_BYTES];
ssl_MakeFakeSid(ss, buf);
rv = sslBuffer_AppendVariable(&constructed, buf, SSL3_SESSIONID_BYTES, 1);
} else {
rv = sslBuffer_AppendNumber(&constructed, 0, 1);
}
if (rv != SECSuccess) {
goto loser;
}
if (IS_DTLS(ss)) {
/* This cookieLen applies to the cookie that appears in the DTLS
* ClientHello, which isn't used in DTLS 1.3. */
rv = sslBuffer_AppendVariable(&constructed, ss->ssl3.hs.cookie.data,
ss->ssl3.hs.helloRetry ? 0 : ss->ssl3.hs.cookie.len, 1);
if (rv != SECSuccess) {
goto loser;
}
}
/* Called from ssl3_HandleHelloRequest(),
* ssl3_RedoHandshake()
* ssl_BeginClientHandshake (when resuming ssl3 session)
* dtls_HandleHelloVerifyRequest(with resending=PR_TRUE)
*
* The |type| argument indicates what is going on here:
* - client_hello_initial is set for the very first ClientHello
* - client_hello_retry indicates that this is a second attempt after receiving
* a HelloRetryRequest (in TLS 1.3)
* - client_hello_retransmit is used in DTLS when resending
* - client_hello_renegotiation is used to renegotiate (in TLS <1.3)
*/
SECStatus
ssl3_SendClientHello(sslSocket *ss, sslClientHelloType type)
{
sslSessionID *sid;
SECStatus rv;
PRBool isTLS = PR_FALSE;
PRBool requestingResume = PR_FALSE;
PRBool unlockNeeded = PR_FALSE;
sslBuffer extensionBuf = SSL_BUFFER_EMPTY;
PRUint16 version = ss->vrange.max;
PRInt32 flags;
sslBuffer chBuf = SSL_BUFFER_EMPTY;
/* shouldn't get here if SSL3 is disabled, but ... */
if (SSL_ALL_VERSIONS_DISABLED(&ss->vrange)) {
PR_NOT_REACHED("No versions of SSL 3.0 or later are enabled");
PORT_SetError(SSL_ERROR_SSL_DISABLED);
return SECFailure;
}
/* If we are responding to a HelloRetryRequest, don't reinitialize. We need
* to maintain the handshake hashes. */
if (!ss->ssl3.hs.helloRetry) {
ssl3_RestartHandshakeHashes(ss);
}
PORT_Assert(!ss->ssl3.hs.helloRetry || type == client_hello_retry);
if (type == client_hello_initial) {
ssl_SetClientHelloSpecVersion(ss, ss->ssl3.cwSpec);
}
/* These must be reset every handshake. */
ssl3_ResetExtensionData(&ss->xtnData, ss);
ss->ssl3.hs.sendingSCSV = PR_FALSE;
ss->ssl3.hs.preliminaryInfo = 0;
PORT_Assert(IS_DTLS(ss) || type != client_hello_retransmit);
SECITEM_FreeItem(&ss->ssl3.hs.newSessionTicket.ticket, PR_FALSE);
ss->ssl3.hs.receivedNewSessionTicket = PR_FALSE;
/* How many suites does our PKCS11 support (regardless of policy)? */
if (ssl3_config_match_init(ss) == 0) {
return SECFailure; /* ssl3_config_match_init has set error code. */
}
/*
* During a renegotiation, ss->clientHelloVersion will be used again to
* work around a Windows SChannel bug. Ensure that it is still enabled.
*/
if (ss->firstHsDone) {
PORT_Assert(type != client_hello_initial);
if (SSL_ALL_VERSIONS_DISABLED(&ss->vrange)) {
PORT_SetError(SSL_ERROR_SSL_DISABLED);
return SECFailure;
}
/* Check if we have a ss->sec.ci.sid.
* Check that it's not expired.
* If we have an sid and it comes from an external cache, we use it. */
if (ss->sec.ci.sid && ss->sec.ci.sid->cached == in_external_cache) {
PORT_Assert(!ss->sec.isServer);
sid = ssl_ReferenceSID(ss->sec.ci.sid);
SSL_TRC(3, ("%d: SSL3[%d]: using external resumption token in ClientHello",
SSL_GETPID(), ss->fd));
} else if (ss->sec.ci.sid && ss->statelessResume && type == client_hello_retry) {
/* If we are sending a second ClientHello, reuse the same SID
* as the original one. */
sid = ssl_ReferenceSID(ss->sec.ci.sid);
} else if (!ss->opt.noCache) {
/* We ignore ss->sec.ci.sid here, and use ssl_Lookup because Lookup
* handles expired entries and other details.
* XXX If we've been called from ssl_BeginClientHandshake, then
* this lookup is duplicative and wasteful.
*/
sid = ssl_LookupSID(ssl_Time(ss), &ss->sec.ci.peer,
ss->sec.ci.port, ss->peerID, ss->url);
} else {
sid = NULL;
}
/* We can't resume based on a different token. If the sid exists,
* make sure the token that holds the master secret still exists ...
* If we previously did client-auth, make sure that the token that holds
* the private key still exists, is logged in, hasn't been removed, etc.
*/
if (sid) {
PRBool sidOK = PR_TRUE;
if (sid->version >= SSL_LIBRARY_VERSION_TLS_1_3) {
if (!tls13_ResumptionCompatible(ss, sid->u.ssl3.cipherSuite)) {
sidOK = PR_FALSE;
}
} else {
/* Check that the cipher suite we need is enabled. */
const ssl3CipherSuiteCfg *suite =
ssl_LookupCipherSuiteCfg(sid->u.ssl3.cipherSuite,
ss->cipherSuites);
SSLVersionRange vrange = { sid->version, sid->version };
if (!suite || !ssl3_config_match(suite, ss->ssl3.policy, &vrange, ss)) {
sidOK = PR_FALSE;
}
/* Check that no (valid) ECHConfigs are setup in combination with a
* (resumable) TLS < 1.3 session id. */
if (!PR_CLIST_IS_EMPTY(&ss->echConfigs)) {
/* If there are ECH configs, the client must not resume but
* offer ECH. */
sidOK = PR_FALSE;
}
}
/* Check that we can recover the master secret. */
if (sidOK) {
PK11SlotInfo *slot = NULL;
if (sid->u.ssl3.masterValid) {
slot = SECMOD_LookupSlot(sid->u.ssl3.masterModuleID,
sid->u.ssl3.masterSlotID);
}
if (slot == NULL) {
sidOK = PR_FALSE;
} else {
PK11SymKey *wrapKey = NULL;
if (!PK11_IsPresent(slot) ||
((wrapKey = PK11_GetWrapKey(slot,
sid->u.ssl3.masterWrapIndex,
sid->u.ssl3.masterWrapMech,
sid->u.ssl3.masterWrapSeries,
ss->pkcs11PinArg)) == NULL)) {
sidOK = PR_FALSE;
}
if (wrapKey)
PK11_FreeSymKey(wrapKey);
PK11_FreeSlot(slot);
slot = NULL;
}
}
/* If we previously did client-auth, make sure that the token that
** holds the private key still exists, is logged in, hasn't been
** removed, etc.
*/
if (sidOK && !ssl3_ClientAuthTokenPresent(sid)) {
sidOK = PR_FALSE;
}
if (sidOK) {
/* Set version based on the sid. */
if (ss->firstHsDone) {
/*
* Windows SChannel compares the client_version inside the RSA
* EncryptedPreMasterSecret of a renegotiation with the
* client_version of the initial ClientHello rather than the
* ClientHello in the renegotiation. To work around this bug, we
* continue to use the client_version used in the initial
* ClientHello when renegotiating.
*
* The client_version of the initial ClientHello is still
* available in ss->clientHelloVersion. Ensure that
* sid->version is bounded within
* [ss->vrange.min, ss->clientHelloVersion], otherwise we
* can't use sid.
*/
if (sid->version >= ss->vrange.min &&
sid->version <= ss->clientHelloVersion) {
version = ss->clientHelloVersion;
} else {
sidOK = PR_FALSE;
}
} else {
/*
* Check sid->version is OK first.
* Previously, we would cap the version based on sid->version,
* but that prevents negotiation of a higher version if the
* previous session was reduced (e.g., with version fallback)
*/
if (sid->version < ss->vrange.min ||
sid->version > ss->vrange.max) {
sidOK = PR_FALSE;
}
}
}
/*
* Windows SChannel compares the client_version inside the RSA
* EncryptedPreMasterSecret of a renegotiation with the
* client_version of the initial ClientHello rather than the
* ClientHello in the renegotiation. To work around this bug, we
* continue to use the client_version used in the initial
* ClientHello when renegotiating.
*/
if (ss->firstHsDone) {
version = ss->clientHelloVersion;
}
sid = ssl3_NewSessionID(ss, PR_FALSE);
if (!sid) {
return SECFailure; /* memory error is set */
}
/* ss->version isn't set yet, but the sid needs a sane value. */
sid->version = version;
}
isTLS = (version > SSL_LIBRARY_VERSION_3_0);
ssl_GetSpecWriteLock(ss);
if (ss->ssl3.cwSpec->macDef->mac == ssl_mac_null) {
/* SSL records are not being MACed. */
ss->ssl3.cwSpec->version = version;
}
ssl_ReleaseSpecWriteLock(ss);
ssl_FreeSID(ss->sec.ci.sid); /* release the old sid */
ss->sec.ci.sid = sid;
/* HACK for SCSV in SSL 3.0. On initial handshake, prepend SCSV,
* only if TLS is disabled.
*/
if (!ss->firstHsDone && !isTLS) {
/* Must set this before calling Hello Extension Senders,
* to suppress sending of empty RI extension.
*/
ss->ssl3.hs.sendingSCSV = PR_TRUE;
}
/* When we attempt session resumption (only), we must lock the sid to
* prevent races with other resumption connections that receive a
* NewSessionTicket that will cause the ticket in the sid to be replaced.
* Once we've copied the session ticket into our ClientHello message, it
* is OK for the ticket to change, so we just need to make sure we hold
* the lock across the calls to ssl_ConstructExtensions.
*/
if (sid->u.ssl3.lock) {
unlockNeeded = PR_TRUE;
PR_RWLock_Rlock(sid->u.ssl3.lock);
}
/* Generate a new random if this is the first attempt or renegotiation. */
if (type == client_hello_initial ||
type == client_hello_renegotiation) {
rv = ssl3_GetNewRandom(ss->ssl3.hs.client_random);
if (rv != SECSuccess) {
goto loser; /* err set by GetNewRandom. */
}
}
if (ss->vrange.max >= SSL_LIBRARY_VERSION_TLS_1_3) {
rv = tls13_SetupClientHello(ss, type);
if (rv != SECSuccess) {
goto loser;
}
}
if (IS_DTLS(ss)) {
ssl3_DisableNonDTLSSuites(ss);
}
rv = ssl3_CreateClientHelloPreamble(ss, sid, requestingResume, version,
PR_FALSE, &extensionBuf, &chBuf);
if (rv != SECSuccess) {
goto loser; /* err set by ssl3_CreateClientHelloPreamble. */
}
if (!ss->ssl3.hs.echHpkeCtx) {
if (extensionBuf.len) {
rv = tls13_MaybeGreaseEch(ss, &chBuf, &extensionBuf);
if (rv != SECSuccess) {
goto loser; /* err set by tls13_MaybeGreaseEch. */
}
rv = ssl_InsertPaddingExtension(ss, chBuf.len, &extensionBuf);
if (rv != SECSuccess) {
goto loser; /* err set by ssl_InsertPaddingExtension. */
}
rv = ssl3_InsertChHeaderSize(ss, &chBuf, &extensionBuf);
if (rv != SECSuccess) {
goto loser; /* err set by ssl3_InsertChHeaderSize. */
}
/* If we are sending a PSK binder, replace the dummy value. */
if (ssl3_ExtensionAdvertised(ss, ssl_tls13_pre_shared_key_xtn)) {
rv = tls13_WriteExtensionsWithBinder(ss, &extensionBuf, &chBuf);
} else {
rv = sslBuffer_AppendNumber(&chBuf, extensionBuf.len, 2);
if (rv != SECSuccess) {
goto loser;
}
rv = sslBuffer_AppendBuffer(&chBuf, &extensionBuf);
}
if (rv != SECSuccess) {
goto loser; /* err set by sslBuffer_Append*. */
}
}
/* If we already have a message in place, we need to enqueue it.
* This empties the buffer. This is a convenient place to call
* dtls_StageHandshakeMessage to mark the message boundary. */
if (IS_DTLS(ss)) {
rv = dtls_StageHandshakeMessage(ss);
if (rv != SECSuccess) {
goto loser;
}
}
/* As here the function takes the full message and hashes it in one go,
* For DTLS1.3, we skip hashing the unnecessary header fields.
* See ssl3_AppendHandshakeHeader. */
if (IS_DTLS(ss) && ss->vrange.max >= SSL_LIBRARY_VERSION_TLS_1_3) {
rv = ssl3_AppendHandshakeSuppressHash(ss, chBuf.buf, chBuf.len);
if (rv != SECSuccess) {
goto loser; /* code set */
}
if (!ss->firstHsDone) {
PORT_Assert(type == client_hello_retransmit ||
ss->ssl3.hs.dtls13ClientMessageBuffer.len == 0);
sslBuffer_Clear(&ss->ssl3.hs.dtls13ClientMessageBuffer);
/* Here instead of computing the hash, we copy the data to a buffer.*/
rv = sslBuffer_Append(&ss->ssl3.hs.dtls13ClientMessageBuffer, chBuf.buf, chBuf.len);
}
} else {
rv = ssl3_AppendHandshake(ss, chBuf.buf, chBuf.len);
}
} else {
PORT_Assert(!IS_DTLS(ss));
rv = tls13_ConstructClientHelloWithEch(ss, sid, !requestingResume, &chBuf, &extensionBuf);
if (rv != SECSuccess) {
goto loser; /* code set */
}
rv = ssl3_UpdateDefaultHandshakeHashes(ss, chBuf.buf, chBuf.len);
if (rv != SECSuccess) {
goto loser; /* code set */
}
if (IS_DTLS(ss)) {
rv = dtls_StageHandshakeMessage(ss);
if (rv != SECSuccess) {
goto loser;
}
}
/* By default, all messagess are added to both the inner and
* outer transcripts. For CH (or CH2 if HRR), that's problematic. */
rv = ssl3_AppendHandshakeSuppressHash(ss, chBuf.buf, chBuf.len);
}
if (rv != SECSuccess) {
goto loser;
}
if (unlockNeeded) {
/* Note: goto loser can't be used past this point. */
PR_RWLock_Unlock(sid->u.ssl3.lock);
}
if (ss->xtnData.sentSessionTicketInClientHello) {
SSL_AtomicIncrementLong(&ssl3stats.sch_sid_stateless_resumes);
}
if (ss->ssl3.hs.sendingSCSV) {
/* Since we sent the SCSV, pretend we sent empty RI extension. */
TLSExtensionData *xtnData = &ss->xtnData;
xtnData->advertised[xtnData->numAdvertised++] =
ssl_renegotiation_info_xtn;
}
flags = 0;
rv = ssl3_FlushHandshake(ss, flags);
if (rv != SECSuccess) {
return rv; /* error code set by ssl3_FlushHandshake */
}
if (version >= SSL_LIBRARY_VERSION_TLS_1_3) {
rv = tls13_MaybeDo0RTTHandshake(ss);
if (rv != SECSuccess) {
return SECFailure; /* error code set already. */
}
}
/* Called from ssl3_HandlePostHelloHandshakeMessage() when it has deciphered a
* complete ssl3 Hello Request.
* Caller must hold Handshake and RecvBuf locks.
*/
static SECStatus
ssl3_HandleHelloRequest(sslSocket *ss)
{
sslSessionID *sid = ss->sec.ci.sid;
SECStatus rv;
static SECStatus
ssl_FindIndexByWrapMechanism(CK_MECHANISM_TYPE mech, unsigned int *wrapMechIndex)
{
unsigned int i;
for (i = 0; i < SSL_NUM_WRAP_MECHS; ++i) {
if (wrapMechanismList[i] == mech) {
*wrapMechIndex = i;
return SECSuccess;
}
}
PORT_Assert(0);
PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
return SECFailure;
}
/* Each process sharing the server session ID cache has its own array of SymKey
* pointers for the symmetric wrapping keys that are used to wrap the master
* secrets. There is one key for each authentication type. These Symkeys
* correspond to the wrapped SymKeys kept in the server session cache.
*/
const SSLAuthType ssl_wrap_key_auth_type[SSL_NUM_WRAP_KEYS] = {
ssl_auth_rsa_decrypt,
ssl_auth_rsa_sign,
ssl_auth_rsa_pss,
ssl_auth_ecdsa,
ssl_auth_ecdh_rsa,
ssl_auth_ecdh_ecdsa
};
static SECStatus
ssl_FindIndexByWrapKey(const sslServerCert *serverCert, unsigned int *wrapKeyIndex)
{
unsigned int i;
for (i = 0; i < SSL_NUM_WRAP_KEYS; ++i) {
if (SSL_CERT_IS(serverCert, ssl_wrap_key_auth_type[i])) {
*wrapKeyIndex = i;
return SECSuccess;
}
}
/* Can't assert here because we still get people using DSA certificates. */
PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
return SECFailure;
}
/* found the wrapping key on disk. */
PORT_Assert(pWswk->symWrapMechanism == masterWrapMech);
PORT_Assert(pWswk->wrapKeyIndex == wrapKeyIndex);
if (pWswk->symWrapMechanism != masterWrapMech ||
pWswk->wrapKeyIndex != wrapKeyIndex) {
goto loser;
}
wrappedKey.type = siBuffer;
wrappedKey.data = pWswk->wrappedSymmetricWrappingkey;
wrappedKey.len = pWswk->wrappedSymKeyLen;
PORT_Assert(wrappedKey.len <= sizeof pWswk->wrappedSymmetricWrappingkey);
switch (ssl_wrap_key_auth_type[wrapKeyIndex]) {
case ssl_auth_rsa_decrypt:
case ssl_auth_rsa_sign: /* bad: see Bug 1248320 */
unwrappedWrappingKey =
PK11_PubUnwrapSymKey(svrPrivKey, &wrappedKey,
masterWrapMech, CKA_UNWRAP, 0);
break;
case ssl_auth_ecdsa:
case ssl_auth_ecdh_rsa:
case ssl_auth_ecdh_ecdsa:
/*
* For ssl_auth_ecd*, we first create an EC public key based on
* data stored with the wrappedSymmetricWrappingkey. Next,
* we do an ECDH computation involving this public key and
* the SSL server's (long-term) EC private key. The resulting
* shared secret is treated the same way as Fortezza's Ks, i.e.,
* it is used to recover the symmetric wrapping key.
*
* The data in wrappedSymmetricWrappingkey is laid out as defined
* in the ECCWrappedKeyInfo structure.
*/
ecWrapped = (ECCWrappedKeyInfo *)pWswk->wrappedSymmetricWrappingkey;
SECStatus
SSL3_ShutdownServerCache(void)
{
int i, j;
if (!symWrapKeysLock)
return SECSuccess; /* lock was never initialized */
PR_Lock(symWrapKeysLock);
/* get rid of all symWrapKeys */
for (i = 0; i < SSL_NUM_WRAP_MECHS; ++i) {
for (j = 0; j < SSL_NUM_WRAP_KEYS; ++j) {
PK11SymKey **pSymWrapKey;
pSymWrapKey = &symWrapKeys[i].symWrapKey[j];
if (*pSymWrapKey) {
PK11_FreeSymKey(*pSymWrapKey);
*pSymWrapKey = NULL;
}
}
}
/* Try to get wrapping key for mechanism from in-memory array.
* If that fails, look for one on disk.
* If that fails, generate a new one, put the new one on disk,
* Put the new key in the in-memory array.
*
* Note that this function performs some fairly inadvisable functions with
* certificate private keys. ECDSA keys are used with ECDH; similarly, RSA
* signing keys are used to encrypt. Bug 1248320.
*/
PK11SymKey *
ssl3_GetWrappingKey(sslSocket *ss,
PK11SlotInfo *masterSecretSlot,
CK_MECHANISM_TYPE masterWrapMech,
void *pwArg)
{
SSLAuthType authType;
SECKEYPrivateKey *svrPrivKey;
SECKEYPublicKey *svrPubKey = NULL;
PK11SymKey *unwrappedWrappingKey = NULL;
PK11SymKey **pSymWrapKey;
CK_MECHANISM_TYPE asymWrapMechanism = CKM_INVALID_MECHANISM;
int length;
unsigned int wrapMechIndex;
unsigned int wrapKeyIndex;
SECStatus rv;
SECItem wrappedKey;
SSLWrappedSymWrappingKey wswk;
PK11SymKey *Ks = NULL;
SECKEYPublicKey *pubWrapKey = NULL;
SECKEYPrivateKey *privWrapKey = NULL;
ECCWrappedKeyInfo *ecWrapped;
const sslServerCert *serverCert = ss->sec.serverCert;
unwrappedWrappingKey = *pSymWrapKey;
if (unwrappedWrappingKey != NULL) {
if (PK11_VerifyKeyOK(unwrappedWrappingKey)) {
unwrappedWrappingKey = PK11_ReferenceSymKey(unwrappedWrappingKey);
goto done;
}
/* slot series has changed, so this key is no good any more. */
PK11_FreeSymKey(unwrappedWrappingKey);
*pSymWrapKey = unwrappedWrappingKey = NULL;
}
/* Try to get wrapped SymWrapping key out of the (disk) cache. */
/* Following call fills in wswk on success. */
rv = ssl_GetWrappingKey(wrapMechIndex, wrapKeyIndex, &wswk);
if (rv == SECSuccess) {
/* found the wrapped sym wrapping key on disk. */
unwrappedWrappingKey =
ssl_UnwrapSymWrappingKey(&wswk, svrPrivKey, wrapKeyIndex,
masterWrapMech, pwArg);
if (unwrappedWrappingKey) {
goto install;
}
}
if (!masterSecretSlot) /* caller doesn't want to create a new one. */
goto loser;
length = PK11_GetBestKeyLength(masterSecretSlot, masterWrapMech);
/* Zero length means fixed key length algorithm, or error.
* It's ambiguous.
*/
unwrappedWrappingKey = PK11_KeyGen(masterSecretSlot, masterWrapMech, NULL,
length, pwArg);
if (!unwrappedWrappingKey) {
goto loser;
}
/* Prepare the buffer to receive the wrappedWrappingKey,
* the symmetric wrapping key wrapped using the server's pub key.
*/
PORT_Memset(&wswk, 0, sizeof wswk); /* eliminate UMRs. */
/* wrap symmetric wrapping key in server's public key. */
switch (authType) {
case ssl_auth_rsa_decrypt:
case ssl_auth_rsa_sign: /* bad: see Bug 1248320 */
case ssl_auth_rsa_pss:
asymWrapMechanism = CKM_RSA_PKCS;
rv = PK11_PubWrapSymKey(asymWrapMechanism, svrPubKey,
unwrappedWrappingKey, &wrappedKey);
break;
case ssl_auth_ecdsa:
case ssl_auth_ecdh_rsa:
case ssl_auth_ecdh_ecdsa:
/*
* We generate an ephemeral EC key pair. Perform an ECDH
* computation involving this ephemeral EC public key and
* the SSL server's (long-term) EC private key. The resulting
* shared secret is treated in the same way as Fortezza's Ks,
* i.e., it is used to wrap the wrapping key. To facilitate
* unwrapping in ssl_UnwrapWrappingKey, we also store all
* relevant info about the ephemeral EC public key in
* wswk.wrappedSymmetricWrappingkey and lay it out as
* described in the ECCWrappedKeyInfo structure.
*/
PORT_Assert(SECKEY_GetPublicKeyType(svrPubKey) == ecKey);
if (SECKEY_GetPublicKeyType(svrPubKey) != ecKey) {
/* something is wrong in sslsecur.c if this isn't an ecKey */
PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
rv = SECFailure;
goto ec_cleanup;
}
/* wrap symmetricWrapping key with the local Ks */
rv = PK11_WrapSymKey(masterWrapMech, NULL, Ks,
unwrappedWrappingKey, &wrappedKey);
if (rv != SECSuccess) {
goto ec_cleanup;
}
/* Write down the length of wrapped key in the buffer
* wswk.wrappedSymmetricWrappingkey at the appropriate offset
*/
ecWrapped->wrappedKeyLen = wrappedKey.len;
ec_cleanup: if (privWrapKey)
SECKEY_DestroyPrivateKey(privWrapKey); if (pubWrapKey)
SECKEY_DestroyPublicKey(pubWrapKey); if (Ks)
PK11_FreeSymKey(Ks);
asymWrapMechanism = masterWrapMech; break;
default:
rv = SECFailure; break;
}
if (rv != SECSuccess) {
ssl_MapLowLevelError(SSL_ERROR_CLIENT_KEY_EXCHANGE_FAILURE); goto loser;
}
/* put it on disk. */ /* If the wrapping key for this KEA type has already been set, *thenabandonthevaluewejustcomputedand *usetheonewegotfromthedisk.
*/
rv = ssl_SetWrappingKey(&wswk); if (rv == SECSuccess) { /* somebody beat us to it. The original contents of our wswk *hasbeenreplacedwiththecontentondisk.Now,discard *thekeywejustcreatedandunwrapthisnewone.
*/
PK11_FreeSymKey(unwrappedWrappingKey);
if (rv != SECSuccess) {
ssl_MapLowLevelError(SSL_ERROR_CLIENT_KEY_EXCHANGE_FAILURE); goto loser;
}
rv = SECSuccess;
loser: if (enc_pms.data != NULL) {
PORT_Free(enc_pms.data);
} if (pms != NULL) {
PK11_FreeSymKey(pms);
} return rv;
}
/* DH shares need to be padded to the size of their prime. Some implementations
* require this. TLS 1.3 also requires this. */
SECStatus
ssl_AppendPaddedDHKeyShare(sslBuffer *buf, const SECKEYPublicKey *pubKey,
PRBool appendLength)
{
SECStatus rv; unsignedint pad = pubKey->u.dh.prime.len - pubKey->u.dh.publicValue.len;
if (SECKEY_GetPublicKeyType(svrPubKey) != dhKey) {
PORT_SetError(SEC_ERROR_BAD_KEY); return SECFailure;
}
/* Work out the parameters. */
rv = ssl_ValidateDHENamedGroup(ss, &svrPubKey->u.dh.prime,
&svrPubKey->u.dh.base,
&groupDef, ¶ms); if (rv != SECSuccess) { /* If we require named groups, we will have already validated the group
* in ssl_HandleDHServerKeyExchange() */
PORT_Assert(!ss->opt.requireDHENamedGroups &&
!ss->xtnData.peerSupportsFfdheGroups);
/* Skip RSA-PSS schemes when the certificate's private key slot does
* not support this signature mechanism. */ if (ssl_IsRsaPssSignatureScheme(scheme) && !slotDoesPss) { return PR_FALSE;
}
/* Now we have to search based on the key type. Go through our preferred
* schemes in order and find the first that can be used. */ for (i = 0; i < ss->ssl3.signatureSchemeCount; ++i) {
scheme = ss->ssl3.signatureSchemes[i];
switch (SECKEY_GetPublicKeyType(pubKey)) {
case rsaKey:
if (isTLS12) {
ss->ssl3.hs.signatureScheme = ssl_sig_rsa_pkcs1_sha1;
} else {
ss->ssl3.hs.signatureScheme = ssl_sig_rsa_pkcs1_sha1md5;
}
break;
case ecKey:
ss->ssl3.hs.signatureScheme = ssl_sig_ecdsa_sha1;
break;
case dsaKey:
ss->ssl3.hs.signatureScheme = ssl_sig_dsa_sha1;
break;
default:
PORT_Assert(0);
PORT_SetError(SEC_ERROR_INVALID_KEY);
return SECFailure;
}
return SECSuccess;
}
/* ssl3_PickServerSignatureScheme selects a signature scheme for signing the
* handshake. Most of this is determined by the key pair we are using.
* Prior to TLS 1.2, the MD5/SHA1 combination is always used. With TLS 1.2, a
* client may advertise its support for signature and hash combinations. */
static SECStatus
ssl3_PickServerSignatureScheme(sslSocket *ss)
{
const sslServerCert *cert = ss->sec.serverCert;
PRBool isTLS12 = ss->version >= SSL_LIBRARY_VERSION_TLS_1_2;
if (!isTLS12 || !ssl3_ExtensionNegotiated(ss, ssl_signature_algorithms_xtn)) {
/* If the client didn't provide any signature_algorithms extension then
* we can assume that they support SHA-1: RFC5246, Section 7.4.1.4.1. */
return ssl_PickFallbackSignatureScheme(ss, cert->serverKeyPair->pubKey);
}
if (ss->version >= SSL_LIBRARY_VERSION_TLS_1_2) {
/* We should have already checked that a signature scheme was
* listed in the request. */
PORT_Assert(schemes && numSchemes > 0);
}
if (!isTLS13 &&
(SECKEY_GetPublicKeyType(pubKey) == rsaKey ||
SECKEY_GetPublicKeyType(pubKey) == dsaKey) &&
SECKEY_PublicKeyStrengthInBits(pubKey) <= 1024) {
/* If the key is a 1024-bit RSA or DSA key, assume conservatively that
* it may be unable to sign SHA-256 hashes. This is the case for older
* Estonian ID cards that have 1024-bit RSA keys. In FIPS 186-2 and
* older, DSA key size is at most 1024 bits and the hash function must
* be SHA-1.
*/
rv = ssl_PickSignatureScheme(ss, clientCertificate,
pubKey, privKey, schemes, numSchemes,
PR_TRUE /* requireSha1 */, schemePtr);
if (rv == SECSuccess) {
SECKEY_DestroyPublicKey(pubKey);
return SECSuccess;
}
/* If this fails, that's because the peer doesn't advertise SHA-1,
* so fall back to the full negotiation. */
}
rv = ssl_PickSignatureScheme(ss, clientCertificate,
pubKey, privKey, schemes, numSchemes,
PR_FALSE /* requireSha1 */, schemePtr);
SECKEY_DestroyPublicKey(pubKey);
return rv;
}
rv = ssl3_SignHashes(ss, &hashes, privKey, &buf);
if (rv == SECSuccess && !ss->sec.isServer) {
/* Remember the info about the slot that did the signing.
** Later, when doing an SSL restart handshake, verify this.
** These calls are mere accessors, and can't fail.
*/
PK11SlotInfo *slot;
sslSessionID *sid = ss->sec.ci.sid;
slot = PK11_GetSlotFromPrivateKey(privKey);
sid->u.ssl3.clAuthSeries = PK11_GetSlotSeries(slot);
sid->u.ssl3.clAuthSlotID = PK11_GetSlotID(slot);
sid->u.ssl3.clAuthModuleID = PK11_GetModuleID(slot);
sid->u.ssl3.clAuthValid = PR_TRUE;
PK11_FreeSlot(slot);
}
if (rv != SECSuccess) {
goto done; /* err code was set by ssl3_SignHashes */
}
len = buf.len + 2 + (isTLS12 ? 2 : 0);
rv = ssl3_AppendHandshakeHeader(ss, ssl_hs_certificate_verify, len);
if (rv != SECSuccess) {
goto done; /* error code set by AppendHandshake */
}
if (isTLS12) {
rv = ssl3_AppendHandshakeNumber(ss, ss->ssl3.hs.signatureScheme, 2);
if (rv != SECSuccess) {
goto done; /* err set by AppendHandshake. */
}
}
rv = ssl3_AppendHandshakeVariable(ss, buf.data, buf.len, 2);
if (rv != SECSuccess) {
goto done; /* error code set by AppendHandshake */
}
done:
if (buf.data)
PORT_Free(buf.data);
return rv;
}
/* Once a cipher suite has been selected, make sure that the necessary secondary
* information is properly set. */
SECStatus
ssl3_SetupCipherSuite(sslSocket *ss, PRBool initHashes)
{
ss->ssl3.hs.suite_def = ssl_LookupCipherSuiteDef(ss->ssl3.hs.cipher_suite);
if (!ss->ssl3.hs.suite_def) {
PORT_Assert(0);
PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
return SECFailure;
}
if (!initHashes) {
return SECSuccess;
}
/* Now we have a cipher suite, initialize the handshake hashes. */
return ssl3_InitHandshakeHashes(ss);
}
SECStatus
ssl_ClientSetCipherSuite(sslSocket *ss, SSL3ProtocolVersion version,
ssl3CipherSuite suite, PRBool initHashes)
{
unsigned int i;
if (ssl3_config_match_init(ss) == 0) {
PORT_Assert(PR_FALSE);
return SECFailure;
}
for (i = 0; i < ssl_V3_SUITES_IMPLEMENTED; i++) {
ssl3CipherSuiteCfg *suiteCfg = &ss->cipherSuites[i];
if (suite == suiteCfg->cipher_suite) {
SSLVersionRange vrange = { version, version };
if (!ssl3_config_match(suiteCfg, ss->ssl3.policy, &vrange, ss)) {
/* config_match already checks whether the cipher suite is
* acceptable for the version, but the check is repeated here
* in order to give a more precise error code. */
if (!ssl3_CipherSuiteAllowedForVersionRange(suite, &vrange)) {
PORT_SetError(SSL_ERROR_CIPHER_DISALLOWED_FOR_VERSION);
} else {
PORT_SetError(SSL_ERROR_NO_CYPHER_OVERLAP);
}
return SECFailure;
}
break;
}
}
if (i >= ssl_V3_SUITES_IMPLEMENTED) {
PORT_SetError(SSL_ERROR_NO_CYPHER_OVERLAP);
return SECFailure;
}
/* Don't let the server change its mind. */
if (ss->ssl3.hs.helloRetry && suite != ss->ssl3.hs.cipher_suite) {
(void)SSL3_SendAlert(ss, alert_fatal, illegal_parameter);
PORT_SetError(SSL_ERROR_RX_MALFORMED_SERVER_HELLO);
return SECFailure;
}
/* Check that session ID we received from the server, if any, matches our
* expectations, depending on whether we're in compat mode and whether we
* negotiated TLS 1.3+ or TLS 1.2-.
*/
static PRBool
ssl_CheckServerSessionIdCorrectness(sslSocket *ss, SECItem *sidBytes)
{
sslSessionID *sid = ss->sec.ci.sid;
PRBool sidMatch = PR_FALSE;
PRBool sentFakeSid = PR_FALSE;
PRBool sentRealSid = sid && sid->version < SSL_LIBRARY_VERSION_TLS_1_3;
/* If attempting to resume a TLS 1.2 connection, the session ID won't be a
* fake. Check for the real value. */
if (sentRealSid) {
sidMatch = (sidBytes->len == sid->u.ssl3.sessionIDLength) &&
(!sidBytes->len || PORT_Memcmp(sid->u.ssl3.sessionID, sidBytes->data, sidBytes->len) == 0);
} else {
/* Otherwise, the session ID was a fake if TLS 1.3 compat mode is
* enabled. If so, check for the fake value. */
sentFakeSid = ss->opt.enableTls13CompatMode && !IS_DTLS(ss);
if (sentFakeSid && sidBytes->len == SSL3_SESSIONID_BYTES) {
PRUint8 buf[SSL3_SESSIONID_BYTES];
ssl_MakeFakeSid(ss, buf);
sidMatch = PORT_Memcmp(buf, sidBytes->data, sidBytes->len) == 0;
}
}
/* TLS 1.2: Session ID shouldn't match if we sent a fake. */
if (ss->version < SSL_LIBRARY_VERSION_TLS_1_3) {
if (sentFakeSid) {
return !sidMatch;
}
return PR_TRUE;
}
/* TLS 1.3: We sent a session ID. The server's should match. */
if (!IS_DTLS(ss) && (sentRealSid || sentFakeSid)) {
return sidMatch;
}
/* TLS 1.3 (no SID)/DTLS 1.3: The server shouldn't send a session ID. */
return sidBytes->len == 0;
}
static SECStatus
ssl_CheckServerRandom(sslSocket *ss)
{
/* Check the ServerHello.random per [RFC 8446 Section 4.1.3].
*
* TLS 1.3 clients receiving a ServerHello indicating TLS 1.2 or below
* MUST check that the last 8 bytes are not equal to either of these
* values. TLS 1.2 clients SHOULD also check that the last 8 bytes are
* not equal to the second value if the ServerHello indicates TLS 1.1 or
* below. If a match is found, the client MUST abort the handshake with
* an "illegal_parameter" alert.
*/
SSL3ProtocolVersion checkVersion =
ss->ssl3.downgradeCheckVersion ? ss->ssl3.downgradeCheckVersion
: ss->vrange.max;
if (checkVersion >= SSL_LIBRARY_VERSION_TLS_1_2 &&
checkVersion > ss->version) {
/* Both sections use the same sentinel region. */
PRUint8 *downgrade_sentinel =
ss->ssl3.hs.server_random +
SSL3_RANDOM_LENGTH - sizeof(tls12_downgrade_random);
/* clean up anything left from previous handshake. */
if (ss->ssl3.clientCertChain != NULL) {
CERT_DestroyCertificateList(ss->ssl3.clientCertChain);
ss->ssl3.clientCertChain = NULL;
}
if (ss->ssl3.clientCertificate != NULL) {
CERT_DestroyCertificate(ss->ssl3.clientCertificate);
ss->ssl3.clientCertificate = NULL;
}
if (ss->ssl3.clientPrivateKey != NULL) {
SECKEY_DestroyPrivateKey(ss->ssl3.clientPrivateKey);
ss->ssl3.clientPrivateKey = NULL;
}
// TODO(djackson) - Bob removed this. Why?
if (ss->ssl3.hs.clientAuthSignatureSchemes != NULL) {
PR_Free(ss->ssl3.hs.clientAuthSignatureSchemes);
ss->ssl3.hs.clientAuthSignatureSchemes = NULL;
ss->ssl3.hs.clientAuthSignatureSchemesLen = 0;
}
/* Note that if the server selects TLS 1.3, this will set the version to TLS
* 1.2. We will amend that once all other fields have been read. */
rv = ssl_ClientReadVersion(ss, &b, &length, &ss->version);
if (rv != SECSuccess) {
goto loser; /* alert has been sent */
}
rv = ssl3_ConsumeHandshake(
ss, ss->ssl3.hs.server_random, SSL3_RANDOM_LENGTH, &b, &length);
if (rv != SECSuccess) {
goto loser; /* alert has been sent */
}
isHelloRetry = !PORT_Memcmp(ss->ssl3.hs.server_random,
ssl_hello_retry_random, SSL3_RANDOM_LENGTH);
rv = ssl3_ConsumeHandshakeVariable(ss, &sidBytes, 1, &b, &length);
if (rv != SECSuccess) {
goto loser; /* alert has been sent */
}
if (sidBytes.len > SSL3_SESSIONID_BYTES) {
if (ss->version >= SSL_LIBRARY_VERSION_TLS_1_0)
desc = decode_error;
goto alert_loser; /* malformed. */
}
/* Read the cipher suite. */
rv = ssl3_ConsumeHandshakeNumber(ss, &cipher, 2, &b, &length);
if (rv != SECSuccess) {
goto loser; /* alert has been sent */
}
/* Compression method. */
rv = ssl3_ConsumeHandshakeNumber(ss, &compression, 1, &b, &length);
if (rv != SECSuccess) {
goto loser; /* alert has been sent */
}
if (compression != ssl_compression_null) {
desc = illegal_parameter;
errCode = SSL_ERROR_RX_MALFORMED_SERVER_HELLO;
goto alert_loser;
}
/* Read supported_versions if present. */
rv = tls13_ClientReadSupportedVersion(ss);
if (rv != SECSuccess) {
goto loser;
}
/* RFC 9147. 5.2.
* DTLS Handshake Message Format states the difference between the computation
* of the transcript if the version is DTLS1.2 or DTLS1.3.
*
* At this moment we are sure which version
* we are planning to use during the connection, so we can compute the hash. */
rv = ssl3_MaybeUpdateHashWithSavedRecord(ss);
if (rv != SECSuccess) {
goto loser;
}
PORT_Assert(!SSL_ALL_VERSIONS_DISABLED(&ss->vrange));
/* Check that the version is within the configured range. */
if (ss->vrange.min > ss->version || ss->vrange.max < ss->version) {
desc = (ss->version > SSL_LIBRARY_VERSION_3_0)
? protocol_version
: handshake_failure;
errCode = SSL_ERROR_UNSUPPORTED_VERSION;
goto alert_loser;
}
if (isHelloRetry && ss->ssl3.hs.helloRetry) {
SSL_TRC(3, ("%d: SSL3[%d]: received a second hello_retry_request",
SSL_GETPID(), ss->fd));
desc = unexpected_message;
errCode = SSL_ERROR_RX_UNEXPECTED_HELLO_RETRY_REQUEST;
goto alert_loser;
}
/* A server that sent HelloVerifyRequest is DTLS 1.2 or earlier;
* reject a subsequent TLS 1.3 ServerHello as illegal. */
if (ss->ssl3.hs.dtlsReceivedHVR &&
ss->version >= SSL_LIBRARY_VERSION_TLS_1_3) {
desc = illegal_parameter;
errCode = SSL_ERROR_RX_MALFORMED_SERVER_HELLO;
goto alert_loser;
}
/* There are three situations in which the server must pick
* TLS 1.3.
*
* 1. We received HRR
* 2. We sent early app data
* 3. ECH was accepted (checked in MaybeHandleEchSignal)
*
* If we offered ECH and the server negotiated a lower version,
* authenticate to the public name for secure disablement.
*
*/
if (ss->version < SSL_LIBRARY_VERSION_TLS_1_3) {
if (isHelloRetry || ss->ssl3.hs.helloRetry) {
/* SSL3_SendAlert() will uncache the SID. */
desc = illegal_parameter;
errCode = SSL_ERROR_RX_MALFORMED_SERVER_HELLO;
goto alert_loser;
}
if (ss->ssl3.hs.zeroRttState == ssl_0rtt_sent) {
/* SSL3_SendAlert() will uncache the SID. */
desc = illegal_parameter;
errCode = SSL_ERROR_DOWNGRADE_WITH_EARLY_DATA;
goto alert_loser;
}
}
/* Check that the server negotiated the same version as it did
* in the first handshake. This isn't really the best place for
* us to be getting this version number, but it's what we have.
* (1294697). */
if (ss->firstHsDone && (ss->version != ss->ssl3.crSpec->version)) {
desc = protocol_version;
errCode = SSL_ERROR_UNSUPPORTED_VERSION;
goto alert_loser;
}
/* Finally, now all the version-related checks have passed. */
ss->ssl3.hs.preliminaryInfo |= ssl_preinfo_version;
/* Update the write cipher spec to match the version. But not after
* HelloRetryRequest, because cwSpec might be a 0-RTT cipher spec,
* in which case this is a no-op. */
if (!ss->firstHsDone && !isHelloRetry) {
ssl_GetSpecWriteLock(ss);
ssl_SetSpecVersions(ss, ss->ssl3.cwSpec);
ssl_ReleaseSpecWriteLock(ss);
}
/* Check that the session ID is as expected. */
if (!ssl_CheckServerSessionIdCorrectness(ss, &sidBytes)) {
desc = illegal_parameter;
errCode = SSL_ERROR_RX_MALFORMED_SERVER_HELLO;
goto alert_loser;
}
/* Only initialize hashes if this isn't a Hello Retry. */
rv = ssl_ClientSetCipherSuite(ss, ss->version, cipher,
!isHelloRetry);
if (rv != SECSuccess) {
desc = illegal_parameter;
errCode = PORT_GetError();
goto alert_loser;
}
dtls_ReceivedFirstMessageInFlight(ss);
if (isHelloRetry) {
rv = tls13_HandleHelloRetryRequest(ss, savedMsg, savedLength);
if (rv != SECSuccess) {
goto loser;
}
return SECSuccess;
}
loser:
/* Clean up the temporary pointer to the handshake buffer. */
ss->xtnData.signedCertTimestamps.len = 0;
ssl_MapLowLevelError(errCode);
return SECFailure;
}
/* Any errors after this point are not "malformed" errors. */
desc = handshake_failure;
/* we need to call ssl3_SetupPendingCipherSpec here so we can check the
* key exchange algorithm. */
rv = ssl3_SetupBothPendingCipherSpecs(ss);
if (rv != SECSuccess) {
goto alert_loser; /* error code is set. */
}
/* We may or may not have sent a session id, we may get one back or
* not and if so it may match the one we sent.
* Attempt to restore the master secret to see if this is so...
* Don't consider failure to find a matching SID an error.
*/
sid_match = (PRBool)(sidBytes->len > 0 &&
sidBytes->len ==
sid->u.ssl3.sessionIDLength &&
!PORT_Memcmp(sid->u.ssl3.sessionID,
sidBytes->data, sidBytes->len));
if (sid_match) {
if (sid->version != ss->version ||
sid->u.ssl3.cipherSuite != ss->ssl3.hs.cipher_suite) {
errCode = SSL_ERROR_RX_MALFORMED_SERVER_HELLO;
goto alert_loser;
}
do {
PK11SymKey *masterSecret;
/* [draft-ietf-tls-session-hash-06; Section 5.3]
*
* o If the original session did not use the "extended_master_secret"
* extension but the new ServerHello contains the extension, the
* client MUST abort the handshake.
*/
if (!sid->u.ssl3.keys.extendedMasterSecretUsed &&
ssl3_ExtensionNegotiated(ss, ssl_extended_master_secret_xtn)) {
errCode = SSL_ERROR_UNEXPECTED_EXTENDED_MASTER_SECRET;
goto alert_loser;
}
/*
* o If the original session used an extended master secret but the new
* ServerHello does not contain the "extended_master_secret"
* extension, the client SHOULD abort the handshake.
*
* TODO(ekr@rtfm.com): Add option to refuse to resume when EMS is not
* used at all (bug 1176526).
*/
if (sid->u.ssl3.keys.extendedMasterSecretUsed &&
!ssl3_ExtensionNegotiated(ss, ssl_extended_master_secret_xtn)) {
errCode = SSL_ERROR_MISSING_EXTENDED_MASTER_SECRET;
goto alert_loser;
}
rv = ssl3_UnwrapMasterSecretClient(ss, sid, &masterSecret);
if (rv != SECSuccess) {
break; /* not considered an error */
}
/* Got a Match */
SSL_AtomicIncrementLong(&ssl3stats.hsh_sid_cache_hits);
/* If we sent a session ticket, then this is a stateless resume. */
if (ss->xtnData.sentSessionTicketInClientHello)
SSL_AtomicIncrementLong(&ssl3stats.hsh_sid_stateless_resumes);
if (ssl3_ExtensionNegotiated(ss, ssl_session_ticket_xtn))
ss->ssl3.hs.ws = wait_new_session_ticket;
else
ss->ssl3.hs.ws = wait_change_cipher;
ss->ssl3.hs.isResuming = PR_TRUE;
/* copy the peer cert from the SID */
if (sid->peerCert != NULL) {
ss->sec.peerCert = CERT_DupCertificate(sid->peerCert);
}
/* We are re-using the old MS, so no need to derive again. */
rv = ssl3_InitPendingCipherSpecs(ss, masterSecret, PR_FALSE);
if (rv != SECSuccess) {
goto alert_loser; /* err code was set */
}
return SECSuccess;
} while (0);
}
if (sid_match)
SSL_AtomicIncrementLong(&ssl3stats.hsh_sid_cache_not_ok);
else
SSL_AtomicIncrementLong(&ssl3stats.hsh_sid_cache_misses);
/* We tried to resume a 1.3 session but the server negotiated 1.2. */
if (ss->statelessResume) {
PORT_Assert(sid->version == SSL_LIBRARY_VERSION_TLS_1_3);
PORT_Assert(ss->ssl3.hs.currentSecret);
/* Reset resumption state, only used by 1.3 code. */
ss->statelessResume = PR_FALSE;
/* Clear TLS 1.3 early data traffic key. */
PK11_FreeSymKey(ss->ssl3.hs.currentSecret);
ss->ssl3.hs.currentSecret = NULL;
}
/* throw the old one away */
sid->u.ssl3.keys.resumable = PR_FALSE;
ssl_UncacheSessionID(ss);
ssl_FreeSID(sid);
/* get a new sid */
ss->sec.ci.sid = sid = ssl3_NewSessionID(ss, PR_FALSE);
if (sid == NULL) {
goto alert_loser; /* memory error is set. */
}
/* Copy Signed Certificate Timestamps, if any. */
if (ss->xtnData.signedCertTimestamps.len) {
rv = SECITEM_CopyItem(NULL, &sid->u.ssl3.signedCertTimestamps,
&ss->xtnData.signedCertTimestamps);
ss->xtnData.signedCertTimestamps.len = 0;
if (rv != SECSuccess)
goto loser;
}
ss->ssl3.hs.isResuming = PR_FALSE;
if (ss->ssl3.hs.kea_def->authKeyType != ssl_auth_null) {
/* All current cipher suites other than those with ssl_auth_null (i.e.,
* (EC)DH_anon_* suites) require a certificate, so use that signal. */
ss->ssl3.hs.ws = wait_server_cert;
} else {
/* All the remaining cipher suites must be (EC)DH_anon_* and so
* must be ephemeral. Note, if we ever add PSK this might
* change. */
PORT_Assert(ss->ssl3.hs.kea_def->ephemeral);
ss->ssl3.hs.ws = wait_server_key;
}
return SECSuccess;
/* failures after this point are not malformed handshakes. */
/* TLS: send decrypt_error if signature failed. */
desc = isTLS ? decrypt_error : handshake_failure;
/*
* Check to make sure the hash is signed by right guy.
*/
rv = ssl3_ComputeDHKeyHash(ss, hashAlg, &hashes,
dh_p, dh_g, dh_Ys, PR_FALSE /* padY */);
if (rv != SECSuccess) {
errCode =
ssl_MapLowLevelError(SSL_ERROR_SERVER_KEY_EXCHANGE_FAILURE);
goto alert_loser;
}
rv = ssl3_VerifySignedHashes(ss, sigScheme, &hashes, &signature);
if (rv != SECSuccess) {
errCode =
ssl_MapLowLevelError(SSL_ERROR_SERVER_KEY_EXCHANGE_FAILURE);
goto alert_loser;
}
/*
* we really need to build a new key here because we can no longer
* ignore calling SECKEY_DestroyPublicKey. Using the key may allocate
* pkcs11 slots and ID's.
*/
arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
if (arena == NULL) {
errCode = SEC_ERROR_NO_MEMORY;
goto loser;
}
/* Called from ssl3_HandlePostHelloHandshakeMessage() when it has deciphered a
* complete ssl3 ServerKeyExchange message.
* Caller must hold Handshake and RecvBuf locks.
*/
static SECStatus
ssl3_HandleServerKeyExchange(sslSocket *ss, PRUint8 *b, PRUint32 length)
{
SECStatus rv;
static void
ssl3_ClientAuthCallbackOutcome(sslSocket *ss, SECStatus outcome)
{
SECStatus rv;
switch (outcome) {
case SECSuccess:
/* check what the callback function returned */
if ((!ss->ssl3.clientCertificate) || (!ss->ssl3.clientPrivateKey)) {
/* we are missing either the key or cert */
goto send_no_certificate;
}
/* Setting ssl3.clientCertChain non-NULL will cause
* ssl3_HandleServerHelloDone to call SendCertificate.
*/
ss->ssl3.clientCertChain = CERT_CertChainFromCert(
ss->ssl3.clientCertificate,
certUsageSSLClient, PR_FALSE);
if (ss->ssl3.clientCertChain == NULL) {
goto send_no_certificate;
}
if (ss->ssl3.hs.hashType == handshake_hash_record ||
ss->ssl3.hs.hashType == handshake_hash_single) {
rv = ssl_PickClientSignatureScheme(ss,
ss->ssl3.clientCertificate,
ss->ssl3.clientPrivateKey,
ss->ssl3.hs.clientAuthSignatureSchemes,
ss->ssl3.hs.clientAuthSignatureSchemesLen,
&ss->ssl3.hs.signatureScheme);
if (rv != SECSuccess) {
/* This should only happen if our schemes changed or
* if an RSA-PSS cert was selected, but the token
* does not support PSS schemes.
*/
goto send_no_certificate;
}
}
break;
case SECFailure:
default:
send_no_certificate:
CERT_DestroyCertificate(ss->ssl3.clientCertificate);
SECKEY_DestroyPrivateKey(ss->ssl3.clientPrivateKey);
ss->ssl3.clientCertificate = NULL;
ss->ssl3.clientPrivateKey = NULL;
if (ss->ssl3.clientCertChain) {
CERT_DestroyCertificateList(ss->ssl3.clientCertChain);
ss->ssl3.clientCertChain = NULL;
}
/* Should not send a client cert when (non-GREASE) ECH is rejected. */
if (ss->ssl3.hs.echHpkeCtx && !ss->ssl3.hs.echAccepted) {
PORT_Assert(ssl3_ExtensionAdvertised(ss, ssl_tls13_encrypted_client_hello_xtn));
rv = SECFailure;
} else if (ss->getClientAuthData != NULL) {
PORT_Assert(signatureSchemes || !signatureSchemeCount);
PORT_Assert((ss->ssl3.hs.preliminaryInfo & ssl_preinfo_all) ==
ssl_preinfo_all);
PORT_Assert(ss->ssl3.clientPrivateKey == NULL);
PORT_Assert(ss->ssl3.clientCertificate == NULL);
PORT_Assert(ss->ssl3.clientCertChain == NULL);
/* Previously cached parameters should be empty */
PORT_Assert(ss->ssl3.hs.clientAuthSignatureSchemes == NULL);
PORT_Assert(ss->ssl3.hs.clientAuthSignatureSchemesLen == 0);
/*
* Peer signatures are only available while in the context of
* of a getClientAuthData callback. It is required for proper
* functioning of SSL_CertIsUsable and SSL_FilterClientCertListBySocket
* Calling these functions outside the context of a getClientAuthData
* callback will result in no filtering.*/
/* Continue the handshake */
if (!ss->ssl3.hs.restartTarget) {
/* The client cert callback completed before the server Finished
* message was fully received. This can happen on a non-blocking
* socket when EAGAIN interrupts the record-header read partway
* through (e.g. when the Finished record header straddles a TCP
* segment boundary). The partial gather state is preserved in
* ss->gs and will be resumed by the next SSL_ForceHandshake /
* PR_Read call. tls13_SendClientSecondRound will run after the
* Finished is processed and will find clientCertificatePending
* already cleared, so it will proceed without blocking. */
SSL_TRC(3, ("%d: SSL3[%p]: client certificate selection won the race"
" with server Finished; will resume on next I/O",
SSL_GETPID(), ss->fd));
PORT_Assert(ss->ssl3.hs.ws != idle_handshake);
return SECSuccess;
}
sslRestartTarget target = ss->ssl3.hs.restartTarget;
ss->ssl3.hs.restartTarget = NULL;
return target(ss);
}
if (!ss->canFalseStartCallback) {
SSL_TRC(3, ("%d: SSL[%d]: no false start callback so no false start",
SSL_GETPID(), ss->fd));
} else {
SECStatus rv;
rv = ssl_CheckServerRandom(ss);
if (rv != SECSuccess) {
SSL_TRC(3, ("%d: SSL[%d]: no false start due to possible downgrade",
SSL_GETPID(), ss->fd));
goto no_false_start;
}
/* An attacker can control the selected ciphersuite so we only wish to
* do False Start in the case that the selected ciphersuite is
* sufficiently strong that the attack can gain no advantage.
* Therefore we always require an 80-bit cipher. */
ssl_GetSpecReadLock(ss);
PRBool weakCipher = ss->ssl3.cwSpec->cipherDef->secret_key_size < 10;
ssl_ReleaseSpecReadLock(ss);
if (weakCipher) {
SSL_TRC(3, ("%d: SSL[%d]: no false start due to weak cipher",
SSL_GETPID(), ss->fd));
goto no_false_start;
}
if (ssl3_ExtensionAdvertised(ss, ssl_tls13_encrypted_client_hello_xtn)) {
SSL_TRC(3, ("%d: SSL[%d]: no false start due to lower version after ECH",
SSL_GETPID(), ss->fd));
goto no_false_start;
}
switch (ss->ssl3.hs.ws) {
case wait_new_session_ticket:
case wait_change_cipher:
case wait_finished:
result = PR_TRUE;
break;
default:
result = PR_FALSE;
break;
}
/* Called from ssl3_HandlePostHelloHandshakeMessage() when it has deciphered
* a complete ssl3 Server Hello Done message.
* Caller must hold Handshake and RecvBuf locks.
*/
static SECStatus
ssl3_HandleServerHelloDone(sslSocket *ss)
{
SECStatus rv;
SSL3WaitState ws = ss->ssl3.hs.ws;
/* Called from ssl3_HandleServerHelloDone and ssl3_AuthCertificateComplete.
*
* Caller must hold Handshake and RecvBuf locks.
*/
static SECStatus
ssl3_SendClientSecondRound(sslSocket *ss)
{
SECStatus rv;
PRBool sendClientCert;
/* We must wait for the server's certificate to be authenticated before
* sending the client certificate in order to disclosing the client
* certificate to an attacker that does not have a valid cert for the
* domain we are connecting to.
*
* During the initial handshake on a connection, we never send/receive
* application data until we have authenticated the server's certificate;
* i.e. we have fully authenticated the handshake before using the cipher
* specs agreed upon for that handshake. During a renegotiation, we may
* continue sending and receiving application data during the handshake
* interleaved with the handshake records. If we were to send the client's
* second round for a renegotiation before the server's certificate was
* authenticated, then the application data sent/received after this point
* would be using cipher spec that hadn't been authenticated. By waiting
* until the server's certificate has been authenticated during
* renegotiations, we ensure that renegotiations have the same property
* as initial handshakes; i.e. we have fully authenticated the handshake
* before using the cipher specs agreed upon for that handshake for
* application data.
*/
if (ss->ssl3.hs.restartTarget) {
PR_NOT_REACHED("unexpected ss->ssl3.hs.restartTarget");
PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
return SECFailure;
}
/* Check whether waiting for client certificate selection OR
waiting on server certificate verification AND
going to send client cert */
if ((ss->ssl3.hs.clientCertificatePending) ||
(ss->ssl3.hs.authCertificatePending && (sendClientCert || ss->ssl3.sendEmptyCert || ss->firstHsDone))) {
SSL_TRC(3, ("%d: SSL3[%p]: deferring ssl3_SendClientSecondRound because"
" certificate authentication is still pending.",
SSL_GETPID(), ss->fd));
ss->ssl3.hs.restartTarget = ssl3_SendClientSecondRound;
PORT_SetError(PR_WOULD_BLOCK_ERROR);
return SECFailure;
}
if (ss->ssl3.sendEmptyCert) {
ss->ssl3.sendEmptyCert = PR_FALSE;
rv = ssl3_SendEmptyCertificate(ss);
/* Don't send verify */
if (rv != SECSuccess) {
goto loser; /* error code is set. */
}
} else if (sendClientCert) {
rv = ssl3_SendCertificate(ss);
if (rv != SECSuccess) {
goto loser; /* error code is set. */
}
}
rv = ssl3_SendClientKeyExchange(ss);
if (rv != SECSuccess) {
goto loser; /* err is set. */
}
if (sendClientCert) {
rv = ssl3_SendCertificateVerify(ss, ss->ssl3.clientPrivateKey);
SECKEY_DestroyPrivateKey(ss->ssl3.clientPrivateKey);
ss->ssl3.clientPrivateKey = NULL;
if (rv != SECSuccess) {
goto loser; /* err is set. */
}
}
rv = ssl3_SendChangeCipherSpecs(ss);
if (rv != SECSuccess) {
goto loser; /* err code was set. */
}
/* This must be done after we've set ss->ssl3.cwSpec in
* ssl3_SendChangeCipherSpecs because SSL_GetChannelInfo uses information
* from cwSpec. This must be done before we call ssl3_CheckFalseStart
* because the false start callback (if any) may need the information from
* the functions that depend on this being set.
*/
ss->enoughFirstHsDone = PR_TRUE;
if (!ss->firstHsDone) {
if (ss->opt.enableFalseStart) {
if (!ss->ssl3.hs.authCertificatePending) {
/* When we fix bug 589047, we will need to know whether we are
* false starting before we try to flush the client second
* round to the network. With that in mind, we purposefully
* call ssl3_CheckFalseStart before calling ssl3_SendFinished,
* which includes a call to ssl3_FlushHandshake, so that
* no application develops a reliance on such flushing being
* done before its false start callback is called.
*/
ssl_ReleaseXmitBufLock(ss);
rv = ssl3_CheckFalseStart(ss);
ssl_GetXmitBufLock(ss); if (rv != SECSuccess) { goto loser;
}
} else { /* The certificate authentication and the server's Finished *messageareracingeachother.Ifthecertificate *authenticationwins,thenwewilltrytofalsestartin *ssl3_AuthCertificateComplete.
*/
SSL_TRC(3, ("%d: SSL3[%p]: deferring false start check because" " certificate authentication is still pending.",
SSL_GETPID(), ss->fd));
}
}
}
rv = ssl3_SendFinished(ss, 0); if (rv != SECSuccess) { goto loser; /* err code was set. */
}
rv = ssl3_SendServerHello(ss); if (rv != SECSuccess) { return rv; /* err code is set. */
}
rv = ssl3_SendCertificate(ss); if (rv != SECSuccess) { return rv; /* error code is set. */
}
rv = ssl3_SendCertificateStatus(ss); if (rv != SECSuccess) { return rv; /* error code is set. */
} /* We have to do this after the call to ssl3_SendServerHello, *becausekea_defissetupbyssl3_SendServerHello().
*/
kea_def = ss->ssl3.hs.kea_def;
if (kea_def->ephemeral) {
rv = ssl3_SendServerKeyExchange(ss); if (rv != SECSuccess) { return rv; /* err code was set. */
}
}
if (ss->opt.requestCertificate) {
rv = ssl3_SendCertificateRequest(ss); if (rv != SECSuccess) { return rv; /* err code is set. */
}
}
rv = ssl3_SendServerHelloDone(ss); if (rv != SECSuccess) { return rv; /* err code is set. */
}
/* An empty TLS Renegotiation Info (RI) extension */ staticconst PRUint8 emptyRIext[5] = { 0xff, 0x01, 0x00, 0x01, 0x00 };
static PRBool
ssl3_KEASupportsTickets(const ssl3KEADef *kea_def)
{ if (kea_def->signKeyType == dsaKey) { /* TODO: Fix session tickets for DSS. The server code rejects the
* session ticket received from the client. Bug 1174677 */ return PR_FALSE;
} return PR_TRUE;
}
static PRBool
ssl3_PeerSupportsCipherSuite(const SECItem *peerSuites, uint16_t suite)
{ for (unsignedint i = 0; i + 1 < peerSuites->len; i += 2) {
PRUint16 suite_i = (peerSuites->data[i] << 8) | peerSuites->data[i + 1]; if (suite_i == suite) { return PR_TRUE;
}
} return PR_FALSE;
}
/* Ensure that only valid cipher suites are enabled. */ if (ssl3_config_match_init(ss) == 0) { /* No configured cipher is both supported by PK11 and allowed.
* This is a configuration error, so report handshake failure.*/
FATAL_ERROR(ss, PORT_GetError(), handshake_failure); return SECFailure;
}
/* *CalltheSNIconfighook. * *Calledfrom: *ssl3_HandleClientHello *tls13_HandleClientHelloPart2
*/
SECStatus
ssl3_ServerCallSNICallback(sslSocket *ss)
{ int errCode = SSL_ERROR_RX_MALFORMED_CLIENT_HELLO;
SSL3AlertDescription desc = illegal_parameter; int ret = 0;
#ifdef SSL_SNI_ALLOW_NAME_CHANGE_2HS #error("No longer allowed to set SSL_SNI_ALLOW_NAME_CHANGE_2HS") #endif if (!ssl3_ExtensionNegotiated(ss, ssl_server_name_xtn)) { if (ss->firstHsDone) { /* Check that we don't have the name is current spec
* if this extension was not negotiated on the 2d hs. */
PRBool passed = PR_TRUE;
ssl_GetSpecReadLock(ss); /*******************************/ if (ss->ssl3.hs.srvVirtName.data) {
passed = PR_FALSE;
}
ssl_ReleaseSpecReadLock(ss); /***************************/ if (!passed) {
errCode = SSL_ERROR_UNRECOGNIZED_NAME_ALERT;
desc = handshake_failure; goto alert_loser;
}
} return SECSuccess;
}
if (ss->sniSocketConfig) do { /* not a loop */
PORT_Assert((ss->ssl3.hs.preliminaryInfo & ssl_preinfo_all) ==
ssl_preinfo_all);
ret = SSL_SNI_SEND_ALERT; /* If extension is negotiated, the len of names should > 0. */ if (ss->xtnData.sniNameArrSize) { /* Calling client callback to reconfigure the socket. */
ret = (SECStatus)(*ss->sniSocketConfig)(ss->fd,
ss->xtnData.sniNameArr,
ss->xtnData.sniNameArrSize,
ss->sniSocketConfigArg);
} if (ret <= SSL_SNI_SEND_ALERT) { /* Application does not know the name or was not able to
* properly reconfigure the socket. */
errCode = SSL_ERROR_UNRECOGNIZED_NAME_ALERT;
desc = unrecognized_name; break;
} elseif (ret == SSL_SNI_CURRENT_CONFIG_IS_USED) {
SECStatus rv = SECSuccess;
SECItem pwsNameBuf = { 0, NULL, 0 };
SECItem *pwsName = &pwsNameBuf;
SECItem *cwsName;
ssl_GetSpecWriteLock(ss); /*******************************/
cwsName = &ss->ssl3.hs.srvVirtName; /* not allow name change on the 2d HS */ if (ss->firstHsDone) { if (ssl3_ServerNameCompare(pwsName, cwsName)) {
ssl_ReleaseSpecWriteLock(ss); /******************/
errCode = SSL_ERROR_UNRECOGNIZED_NAME_ALERT;
desc = handshake_failure;
ret = SSL_SNI_SEND_ALERT; break;
}
} if (pwsName->data) {
SECITEM_FreeItem(pwsName, PR_FALSE);
} if (cwsName->data) {
rv = SECITEM_CopyItem(NULL, pwsName, cwsName);
}
ssl_ReleaseSpecWriteLock(ss); /**************************/ if (rv != SECSuccess) {
errCode = SSL_ERROR_INTERNAL_ERROR_ALERT;
desc = internal_error;
ret = SSL_SNI_SEND_ALERT; break;
}
} elseif ((unsigned int)ret < ss->xtnData.sniNameArrSize) { /* Application has configured new socket info. Lets check it
* and save the name. */
SECStatus rv;
SECItem *name = &ss->xtnData.sniNameArr[ret];
SECItem *pwsName;
/* get rid of the old name and save the newly picked. */ /* This code is protected by ssl3HandshakeLock. */
ssl_GetSpecWriteLock(ss); /*******************************/ /* not allow name change on the 2d HS */ if (ss->firstHsDone) {
SECItem *cwsName = &ss->ssl3.hs.srvVirtName; if (ssl3_ServerNameCompare(name, cwsName)) {
ssl_ReleaseSpecWriteLock(ss); /******************/
errCode = SSL_ERROR_UNRECOGNIZED_NAME_ALERT;
desc = handshake_failure;
ret = SSL_SNI_SEND_ALERT; break;
}
}
pwsName = &ss->ssl3.hs.srvVirtName; if (pwsName->data) {
SECITEM_FreeItem(pwsName, PR_FALSE);
}
rv = SECITEM_CopyItem(NULL, pwsName, name);
ssl_ReleaseSpecWriteLock(ss); /***************************/ if (rv != SECSuccess) {
errCode = SSL_ERROR_INTERNAL_ERROR_ALERT;
desc = internal_error;
ret = SSL_SNI_SEND_ALERT; break;
} /* Need to tell the client that application has picked *thenamefromtheofferedlistandreconfiguredthesocket.
*/
ssl3_RegisterExtensionSender(ss, &ss->xtnData, ssl_server_name_xtn,
ssl_SendEmptyExtension);
} else { /* Callback returned index outside of the boundary. */
PORT_Assert((unsigned int)ret < ss->xtnData.sniNameArrSize);
errCode = SSL_ERROR_INTERNAL_ERROR_ALERT;
desc = internal_error;
ret = SSL_SNI_SEND_ALERT; break;
}
} while (0);
ssl3_FreeSniNameArray(&ss->xtnData); if (ret <= SSL_SNI_SEND_ALERT) { /* desc and errCode should be set. */ goto alert_loser;
}
/* If the client didn't include the supported groups extension, assume just *P-256supportanddisablealltheotherECDHEgroups.Thisalsoaffects
* ECDHE group selection, but this function is called first. */ if (!ssl3_ExtensionNegotiated(ss, ssl_supported_groups_xtn)) {
unsigned int i; for (i = 0; i < SSL_NAMED_GROUP_COUNT; ++i) { if (ss->namedGroupPreferences[i] &&
ss->namedGroupPreferences[i]->keaType == ssl_kea_ecdh &&
ss->namedGroupPreferences[i]->name != ssl_grp_ec_secp256r1) {
ss->namedGroupPreferences[i] = NULL;
}
}
}
/* This picks the first certificate that has: *a)therightauthenticationmethod,and *b)therightnamedcurve(EConly) * *Wemightwanttodosomesortofrankingherelater.Fornow,it'sall
* based on what order they are configured in. */ for (cursor = PR_NEXT_LINK(&ss->serverCerts);
cursor != &ss->serverCerts;
cursor = PR_NEXT_LINK(cursor)) {
sslServerCert *cert = (sslServerCert *)cursor; if (kea_def->authKeyType == ssl_auth_rsa_sign) { /* We consider PSS certificates here as well for TLS 1.2. */ if (!SSL_CERT_IS(cert, ssl_auth_rsa_sign) &&
(!SSL_CERT_IS(cert, ssl_auth_rsa_pss) ||
ss->version < SSL_LIBRARY_VERSION_TLS_1_2)) { continue;
}
} else { if (!SSL_CERT_IS(cert, kea_def->authKeyType)) { continue;
} if (SSL_CERT_IS_EC(cert) &&
!ssl_NamedGroupEnabled(ss, cert->namedCurve)) { continue;
}
}
/* Found one. */
ss->sec.serverCert = cert;
ss->sec.authKeyBits = cert->serverKeyBits;
/* Don't pick a signature scheme if we aren't going to use it. */ if (kea_def->signKeyType == nullKey) {
ss->sec.authType = kea_def->authKeyType; return SECSuccess;
}
/* Translate the version. */ if (IS_DTLS(ss)) {
ss->clientHelloVersion = dtls_DTLSVersionToTLSVersion((SSL3ProtocolVersion)tmp);
} else {
ss->clientHelloVersion = (SSL3ProtocolVersion)tmp;
}
/* Grab the client random data. */
rv = ssl3_ConsumeHandshake(
ss, ss->ssl3.hs.client_random, SSL3_RANDOM_LENGTH, b, length); if (rv != SECSuccess) { return SECFailure; /* malformed */
}
/* Grab the client's SID, if present. */
rv = ssl3_ConsumeHandshakeVariable(ss, sidBytes, 1, b, length); /* Check that the SID has the format: opaque legacy_session_id<0..32>, as
* specified in RFC8446, Section 4.1.2. */ if (rv != SECSuccess || sidBytes->len > SSL3_SESSIONID_BYTES) { return SECFailure; /* malformed */
}
/* Grab the client's cookie, if present. It is checked after version negotiation. */ if (IS_DTLS(ss)) {
rv = ssl3_ConsumeHandshakeVariable(ss, cookieBytes, 1, b, length); if (rv != SECSuccess) { return SECFailure; /* malformed */
}
}
/* Grab the list of cipher suites. */
rv = ssl3_ConsumeHandshakeVariable(ss, suites, 2, b, length); if (rv != SECSuccess) { return SECFailure; /* malformed */
}
/* Grab the list of compression methods. */
rv = ssl3_ConsumeHandshakeVariable(ss, comps, 1, b, length); if (rv != SECSuccess) { return SECFailure; /* malformed */
} return SECSuccess;
}
/* TLS 1.3 requires that compression include only null. */ if (comps->len != 1 || comps->data[0] != ssl_compression_null) {
FATAL_ERROR(ss, SSL_ERROR_RX_MALFORMED_CLIENT_HELLO, illegal_parameter); return SECFailure;
}
/* receivedCcs is only valid if we sent an HRR. */ if (ss->ssl3.hs.receivedCcs && !ss->ssl3.hs.helloRetry) {
FATAL_ERROR(ss, SSL_ERROR_RX_UNEXPECTED_CHANGE_CIPHER, unexpected_message); return SECFailure;
}
/* A DTLS 1.3-only client MUST set the legacy_cookie field to zero length. *IfaDTLS1.3ClientHelloisreceivedwithanyothervalueinthisfield,
* the server MUST abort the handshake with an "illegal_parameter" alert. */ if (IS_DTLS(ss) && cookieBytes->len != 0) {
FATAL_ERROR(ss, SSL_ERROR_RX_MALFORMED_CLIENT_HELLO, illegal_parameter); return SECFailure;
}
} else { /* ECH not possible here. */
ss->ssl3.hs.preliminaryInfo |= ssl_preinfo_ech;
/* HRR and ECH are TLS1.3-only. We ignore the Cookie extension here. */ if (ss->ssl3.hs.helloRetry) {
FATAL_ERROR(ss, SSL_ERROR_UNSUPPORTED_VERSION, protocol_version); return SECFailure;
}
/* receivedCcs is only valid if we sent an HRR. */ if (ss->ssl3.hs.receivedCcs) {
FATAL_ERROR(ss, SSL_ERROR_RX_UNEXPECTED_CHANGE_CIPHER, unexpected_message); return SECFailure;
}
/* TLS versions prior to 1.3 must include null somewhere. */ if (comps->len < 1 ||
!memchr(comps->data, ssl_compression_null, comps->len)) {
FATAL_ERROR(ss, SSL_ERROR_RX_MALFORMED_CLIENT_HELLO, illegal_parameter); return SECFailure;
}
/* We never send cookies in DTLS 1.2. */ if (IS_DTLS(ss) && cookieBytes->len != 0) {
FATAL_ERROR(ss, SSL_ERROR_RX_MALFORMED_CLIENT_HELLO, illegal_parameter); return SECFailure;
}
}
if (!ss->sec.isServer ||
(ss->ssl3.hs.ws != wait_client_hello &&
ss->ssl3.hs.ws != idle_handshake)) {
desc = unexpected_message;
errCode = SSL_ERROR_RX_UNEXPECTED_CLIENT_HELLO; goto alert_loser;
} if (ss->ssl3.hs.ws == idle_handshake) { /* Refuse re-handshake when we have already negotiated TLS 1.3. */ if (ss->version >= SSL_LIBRARY_VERSION_TLS_1_3) {
desc = unexpected_message;
errCode = SSL_ERROR_RENEGOTIATION_NOT_ALLOWED; goto alert_loser;
} if (ss->opt.enableRenegotiation == SSL_RENEGOTIATE_NEVER) {
desc = no_renegotiation;
level = alert_warning;
errCode = SSL_ERROR_RENEGOTIATION_NOT_ALLOWED; goto alert_loser;
}
}
/* We should always be in a fresh state. */
SSL_ASSERT_HASHES_EMPTY(ss);
/* Get peer name of client */
rv = ssl_GetPeerInfo(ss); if (rv != SECSuccess) { return rv; /* error code is set. */
}
/* We might be starting session renegotiation in which case we should *clearpreviousstate.
*/
ssl3_ResetExtensionData(&ss->xtnData, ss);
ss->statelessResume = PR_FALSE;
versionExtension = ssl3_FindExtension(ss, ssl_tls13_supported_versions_xtn); if (versionExtension) {
rv = tls13_NegotiateVersion(ss, versionExtension); if (rv != SECSuccess) {
errCode = PORT_GetError();
desc = (errCode == SSL_ERROR_UNSUPPORTED_VERSION) ? protocol_version : illegal_parameter; goto alert_loser;
}
} else { /* The PR_MIN here ensures that we never negotiate 1.3 if the
* peer didn't offer "supported_versions". */
rv = ssl3_NegotiateVersion(ss,
PR_MIN(ss->clientHelloVersion,
SSL_LIBRARY_VERSION_TLS_1_2),
PR_TRUE); /* Send protocol version alert if the ClientHello.legacy_version is not *supportedbytheserver. * *Ifthe"supported_versions"extensionisabsentandtheserveronly *supportsversionsgreaterthanClientHello.legacy_version,the *serverMUSTabortthehandshakewitha"protocol_version"alert
* [RFC8446, Appendix D.2]. */ if (rv != SECSuccess) {
desc = protocol_version;
errCode = SSL_ERROR_UNSUPPORTED_VERSION; goto alert_loser;
}
}
ss->ssl3.hs.preliminaryInfo |= ssl_preinfo_version;
/* Update the write spec to match the selected version. */ if (!ss->firstHsDone) {
ssl_GetSpecWriteLock(ss);
ssl_SetSpecVersions(ss, ss->ssl3.cwSpec);
ssl_ReleaseSpecWriteLock(ss);
}
isTLS13 = ss->version >= SSL_LIBRARY_VERSION_TLS_1_3; if (isTLS13) { if (ss->firstHsDone) {
desc = unexpected_message;
errCode = SSL_ERROR_RENEGOTIATION_NOT_ALLOWED; goto alert_loser;
}
/* If there is a cookie, then this is a second ClientHello (TLS 1.3). */ if (ssl3_FindExtension(ss, ssl_tls13_cookie_xtn)) {
ss->ssl3.hs.helloRetry = PR_TRUE;
}
/* Now parse the rest of the extensions. */
rv = ssl3_HandleParsedExtensions(ss, ssl_hs_client_hello);
ssl3_DestroyRemoteExtensions(&ss->ssl3.hs.remoteExtensions); if (rv != SECSuccess) { if (PORT_GetError() == SSL_ERROR_UNSUPPORTED_SIGNATURE_ALGORITHM) {
errCode = SSL_ERROR_UNSUPPORTED_SIGNATURE_ALGORITHM;
} goto loser; /* malformed */
}
/* If the ClientHello version is less than our maximum version, check for a
* TLS_FALLBACK_SCSV and reject the connection if found. */ if (ss->vrange.max > ss->version) { for (i = 0; i + 1 < suites.len; i += 2) {
PRUint16 suite_i = (suites.data[i] << 8) | suites.data[i + 1]; if (suite_i != TLS_FALLBACK_SCSV) continue;
desc = inappropriate_fallback;
errCode = SSL_ERROR_INAPPROPRIATE_FALLBACK_ALERT; goto alert_loser;
}
}
if (!ssl3_ExtensionNegotiated(ss, ssl_renegotiation_info_xtn)) { /* If we didn't receive an RI extension, look for the SCSV, *andiffound,treatitjustlikeanemptyRIextension *byprocessingalocalcopyofanemptyRIextension.
*/ for (i = 0; i + 1 < suites.len; i += 2) {
PRUint16 suite_i = (suites.data[i] << 8) | suites.data[i + 1]; if (suite_i == TLS_EMPTY_RENEGOTIATION_INFO_SCSV) {
PRUint8 *b2 = (PRUint8 *)emptyRIext;
PRUint32 L2 = sizeof emptyRIext;
(void)ssl3_HandleExtensions(ss, &b2, &L2, ssl_hs_client_hello); break;
}
}
}
/* The check for renegotiation in TLS 1.3 is earlier. */ if (!isTLS13) { if (ss->firstHsDone &&
(ss->opt.enableRenegotiation == SSL_RENEGOTIATE_REQUIRES_XTN ||
ss->opt.enableRenegotiation == SSL_RENEGOTIATE_TRANSITIONAL) &&
!ssl3_ExtensionNegotiated(ss, ssl_renegotiation_info_xtn)) {
desc = no_renegotiation;
level = alert_warning;
errCode = SSL_ERROR_RENEGOTIATION_NOT_ALLOWED; goto alert_loser;
} if ((ss->opt.requireSafeNegotiation ||
(ss->firstHsDone && ss->peerRequestedProtection)) &&
!ssl3_ExtensionNegotiated(ss, ssl_renegotiation_info_xtn)) {
desc = handshake_failure;
errCode = SSL_ERROR_UNSAFE_NEGOTIATION; goto alert_loser;
}
}
/* We do stateful resumes only if we are in TLS < 1.3 and *eitherofthefollowingconditionsaresatisfied: *(1)theclientdoesnotsupportthesessionticketextension,or *(2)theclientsupportthesessionticketextension,butsentan *emptyticket.
*/ if (!isTLS13 &&
(!ssl3_ExtensionNegotiated(ss, ssl_session_ticket_xtn) ||
ss->xtnData.emptySessionTicket)) { if (sidBytes.len > 0 && !ss->opt.noCache) {
SSL_TRC(7, ("%d: SSL3[%d]: server, lookup client session-id for 0x%08x%08x%08x%08x",
SSL_GETPID(), ss->fd, ss->sec.ci.peer.pr_s6_addr32[0],
ss->sec.ci.peer.pr_s6_addr32[1],
ss->sec.ci.peer.pr_s6_addr32[2],
ss->sec.ci.peer.pr_s6_addr32[3])); if (ssl_sid_lookup) {
sid = (*ssl_sid_lookup)(ssl_Time(ss), &ss->sec.ci.peer,
sidBytes.data, sidBytes.len, ss->dbHandle);
} else {
errCode = SSL_ERROR_SERVER_CACHE_NOT_CONFIGURED; goto loser;
}
}
} elseif (ss->statelessResume) { /* Fill in the client's session ID if doing a stateless resume. *(Whendoingstatelessresumes,serverechosclient'sSessionID.) *ThisbranchalsohandlesTLS1.3resumption-PSK.
*/
sid = ss->sec.ci.sid;
PORT_Assert(sid != NULL); /* Should have already been filled in.*/
/* unwrap helper function to handle the case where the wrapKey doesn't wind
* up in the correct token for the master secret */
PK11SymKey *
ssl_unwrapSymKey(PK11SymKey *wrapKey,
CK_MECHANISM_TYPE wrapType, SECItem *param,
SECItem *wrappedKey,
CK_MECHANISM_TYPE target, CK_ATTRIBUTE_TYPE operation, int keySize, CK_FLAGS keyFlags, void *pinArg)
{
PK11SymKey *unwrappedKey;
/* it's possible that we failed to unwrap because the wrapKey is in *aslotthatcan'thandletarget.MovethewrapKeytoaslotthat
* can handle this mechanism and retry the operation */ if (targetSlot == NULL) { return NULL;
}
newWrapKey = PK11_MoveSymKey(targetSlot, CKA_UNWRAP, 0,
PR_FALSE, wrapKey);
PK11_FreeSlot(targetSlot); if (newWrapKey == NULL) { return NULL;
}
unwrappedKey = PK11_UnwrapSymKeyWithFlags(newWrapKey, wrapType, param,
wrappedKey, target, operation, keySize,
keyFlags);
PK11_FreeSymKey(newWrapKey);
} return unwrappedKey;
}
/* If we already have a session for this client, be sure to pick the same **ciphersuitewepickedbefore.Thisisnotaloop,despiteappearances.
*/ if (sid) do {
ssl3CipherSuiteCfg *suite;
SSLVersionRange vrange = { ss->version, ss->version };
suite = ss->cipherSuites; /* Find the entry for the cipher suite used in the cached session. */ for (j = ssl_V3_SUITES_IMPLEMENTED; j > 0; --j, ++suite) { if (suite->cipher_suite == sid->u.ssl3.cipherSuite) break;
}
if (j == 0) break;
/* Double check that the cached cipher suite is still enabled, *implemented,andallowedbypolicy.Mighthavebeendisabled.
*/ if (ssl3_config_match_init(ss) == 0) {
desc = handshake_failure;
errCode = PORT_GetError(); goto alert_loser;
} if (!ssl3_config_match(suite, ss->ssl3.policy, &vrange, ss)) break;
/* Double check that the cached cipher suite is in the client's
* list. If it isn't, fall through and start a new session. */ for (i = 0; i + 1 < suites->len; i += 2) {
PRUint16 suite_i = (suites->data[i] << 8) | suites->data[i + 1]; if (suite_i == suite->cipher_suite) {
ss->ssl3.hs.cipher_suite = suite_i;
rv = ssl3_SetupCipherSuite(ss, PR_TRUE); if (rv != SECSuccess) {
desc = internal_error;
errCode = PORT_GetError(); goto alert_loser;
}
goto cipher_found;
}
}
} while (0); /* START A NEW SESSION */
/* If there are any failures while processing the old sid, *wedon'tconsiderthemtobeerrors.Instead,Wejustbehave *asiftheclienthadsentusnosidtobeginwith,andmakeanewone. *Theexceptionhereisattemptstoresumeextended_master_secret *sessionswithouttheextension,whichcausesanalert.
*/ if (sid != NULL) do {
PK11SymKey *masterSecret;
if (sid->version != ss->version ||
sid->u.ssl3.cipherSuite != ss->ssl3.hs.cipher_suite) { break; /* not an error */
}
/* server sids don't remember the server cert we previously sent,
** but they do remember the slot we originally used, so we
** can locate it again, provided that the current ssl socket
** has had its server certs configured the same as the previous one.
*/
ss->sec.serverCert = ssl_FindServerCert(ss, sid->authType, sid->namedCurve); if (!ss->sec.serverCert || !ss->sec.serverCert->serverCert) {
/* A compatible certificate must not have been configured. It
* might not be the same certificate, but we only find that out
* when the ticket fails to decrypt. */
break;
}
/* [draft-ietf-tls-session-hash-06; Section5.3]
* o If the original session did not use the "extended_master_secret"
* extension but the new ClientHello contains the extension, then the
* server MUST NOT perform the abbreviated handshake. Instead, it
* SHOULD continue with a full handshake (as described in
* Section5.2) to negotiate a new session.
*
* o If the original session used the "extended_master_secret"
* extension but the new ClientHello does not contain the extension,
* the server MUST abort the abbreviated handshake.
*/ if (ssl3_ExtensionNegotiated(ss, ssl_extended_master_secret_xtn)) { if (!sid->u.ssl3.keys.extendedMasterSecretUsed) {
break; /* not an error */
}
} else { if (sid->u.ssl3.keys.extendedMasterSecretUsed) {
/* Note: we do not destroy the session */
desc = handshake_failure;
errCode = SSL_ERROR_MISSING_EXTENDED_MASTER_SECRET;
goto alert_loser;
}
}
if (ss->sec.ci.sid) {
ssl_UncacheSessionID(ss);
PORT_Assert(ss->sec.ci.sid != sid); /* should be impossible, but ... */ if (ss->sec.ci.sid != sid) {
ssl_FreeSID(ss->sec.ci.sid);
}
ss->sec.ci.sid = NULL;
}
/* we need to resurrect the master secret.... */
rv = ssl3_UnwrapMasterSecretServer(ss, sid, &masterSecret); if (rv != SECSuccess) {
break; /* not an error */
}
/*
* Old SID passed all tests, so resume this old session.
*/
SSL_AtomicIncrementLong(&ssl3stats.hch_sid_cache_hits); if (ss->statelessResume)
SSL_AtomicIncrementLong(&ssl3stats.hch_sid_stateless_resumes);
ss->ssl3.hs.isResuming = PR_TRUE;
/* We are re-using the old MS, so no need to derive again. */
rv = ssl3_InitPendingCipherSpecs(ss, masterSecret, PR_FALSE); if (rv != SECSuccess) {
errCode = PORT_GetError();
goto loser;
}
if (sid) { /* we had a sid, but it's no longer valid, free it */
ss->statelessResume = PR_FALSE;
SSL_AtomicIncrementLong(&ssl3stats.hch_sid_cache_not_ok);
ssl_UncacheSessionID(ss);
ssl_FreeSID(sid);
sid = NULL;
}
SSL_AtomicIncrementLong(&ssl3stats.hch_sid_cache_misses);
/* We only send a session ticket extension if the client supports
* the extension and we are unable to resume.
*
* TODO: send a session ticket if performing a stateful
* resumption. (Asper RFC4507, a server may issue a session
* ticket while doing a (stateless or stateful) session resume,
* but OpenSSL-0.9.8g does not accept session tickets while
* resuming.)
*/ if (ssl3_ExtensionNegotiated(ss, ssl_session_ticket_xtn) &&
ssl3_KEASupportsTickets(ss->ssl3.hs.kea_def)) {
ssl3_RegisterExtensionSender(ss, &ss->xtnData, ssl_session_ticket_xtn,
ssl_SendEmptyExtension);
}
rv = ssl3_ServerCallSNICallback(ss); if (rv != SECSuccess) {
/* The alert has already been sent. */
errCode = PORT_GetError();
goto loser;
}
if (haveXmitBufLock) {
ssl_ReleaseXmitBufLock(ss);
}
PORT_SetError(errCode); return SECFailure;
}
/*
* ssl3_HandleV2ClientHello is used when a V2 formatted hello comes
* in asking to use the V3 handshake.
*/
SECStatus
ssl3_HandleV2ClientHello(sslSocket *ss, unsigned char *buffer, unsigned int length,
PRUint8 padding)
{
sslSessionID *sid = NULL;
unsigned char *suites;
unsigned char *random;
SSL3ProtocolVersion version;
SECStatus rv;
unsigned int i;
unsigned int j;
unsigned int sid_length;
unsigned int suite_length;
unsigned int rand_length;
int errCode = SSL_ERROR_RX_MALFORMED_CLIENT_HELLO;
SSL3AlertDescription desc = handshake_failure;
unsigned int total = SSL_HL_CLIENT_HELLO_HBYTES;
total += suite_length = (buffer[3] << 8) | buffer[4];
total += sid_length = (buffer[5] << 8) | buffer[6];
total += rand_length = (buffer[7] << 8) | buffer[8];
total += padding;
ss->clientHelloVersion = version;
if (version >= SSL_LIBRARY_VERSION_TLS_1_3) {
/* [draft-ietf-tls-tls-11; C.3] forbids sending a TLS 1.3
* ClientHello using the backwards-compatible format. */
desc = illegal_parameter;
errCode = SSL_ERROR_RX_MALFORMED_CLIENT_HELLO;
goto alert_loser;
}
rv = ssl3_NegotiateVersion(ss, version, PR_TRUE); if (rv != SECSuccess) {
/* send back which ever alert client will understand. */
desc = (version > SSL_LIBRARY_VERSION_3_0) ? protocol_version
: handshake_failure;
errCode = SSL_ERROR_UNSUPPORTED_VERSION;
goto alert_loser;
}
/* ECH not possible here. */
ss->ssl3.hs.preliminaryInfo |= ssl_preinfo_ech;
ss->ssl3.hs.preliminaryInfo |= ssl_preinfo_version; if (!ss->firstHsDone) {
ssl_GetSpecWriteLock(ss);
ssl_SetSpecVersions(ss, ss->ssl3.cwSpec);
ssl_ReleaseSpecWriteLock(ss);
}
/* if we get a non-zero SID, just ignore it. */ if (length != total) {
SSL_DBG(("%d: SSL3[%d]: bad v2 client hello message, len=%d should=%d",
SSL_GETPID(), ss->fd, length, total));
desc = illegal_parameter;
errCode = SSL_ERROR_RX_MALFORMED_CLIENT_HELLO;
goto alert_loser;
}
if (ssl3_config_match_init(ss) == 0) {
errCode = PORT_GetError(); /* error code is already set. */
goto alert_loser;
}
/* Select a cipher suite.
**
** NOTE: This suite selection algorithm should be the same as the one in
** ssl3_HandleClientHello().
*/
for (j = 0; j < ssl_V3_SUITES_IMPLEMENTED; j++) {
ssl3CipherSuiteCfg *suite = &ss->cipherSuites[j];
SSLVersionRange vrange = { ss->version, ss->version }; if (!ssl3_config_match(suite, ss->ssl3.policy, &vrange, ss)) {
continue;
}
for (i = 0; i + 2 < suite_length; i += 3) {
PRUint32 suite_i = (suites[i] << 16) | (suites[i + 1] << 8) | suites[i + 2]; if (suite_i == suite->cipher_suite) {
ss->ssl3.hs.cipher_suite = suite_i;
rv = ssl3_SetupCipherSuite(ss, PR_TRUE); if (rv != SECSuccess) {
desc = internal_error;
errCode = PORT_GetError();
goto alert_loser;
}
goto suite_found;
}
}
}
errCode = SSL_ERROR_NO_CYPHER_OVERLAP;
goto alert_loser;
suite_found:
/* If the ClientHello version is less than our maximum version, check for a
* TLS_FALLBACK_SCSV and reject the connection if found. */ if (ss->vrange.max > ss->clientHelloVersion) {
for (i = 0; i + 2 < suite_length; i += 3) {
PRUint16 suite_i = (suites[i] << 16) | (suites[i + 1] << 8) | suites[i + 2]; if (suite_i == TLS_FALLBACK_SCSV) {
desc = inappropriate_fallback;
errCode = SSL_ERROR_INAPPROPRIATE_FALLBACK_ALERT;
goto alert_loser;
}
}
}
/* Look for the SCSV, and if found, treat it just like an empty RI
* extension by processing a local copy of an empty RI extension.
*/
for (i = 0; i + 2 < suite_length; i += 3) {
PRUint32 suite_i = (suites[i] << 16) | (suites[i + 1] << 8) | suites[i + 2]; if (suite_i == TLS_EMPTY_RENEGOTIATION_INFO_SCSV) {
PRUint8 *b2 = (PRUint8 *)emptyRIext;
PRUint32 L2 = sizeof emptyRIext;
(void)ssl3_HandleExtensions(ss, &b2, &L2, ssl_hs_client_hello);
break;
}
}
/* we don't even search for a cache hit here. It's just a miss. */
SSL_AtomicIncrementLong(&ssl3stats.hch_sid_cache_misses);
sid = ssl3_NewSessionID(ss, PR_TRUE); if (sid == NULL) {
errCode = PORT_GetError();
goto loser; /* memory error is set. */
}
ss->sec.ci.sid = sid;
/* do not worry about memory leak of sid since it now belongs to ci */
/* We have to update the handshake hashes before we can send stuff */
rv = ssl3_UpdateHandshakeHashes(ss, buffer, length); if (rv != SECSuccess) {
errCode = PORT_GetError();
goto loser;
}
rv = sslBuffer_AppendNumber(messageBuf, ss->ssl3.hs.cipher_suite, 2); if (rv != SECSuccess) { return SECFailure;
}
rv = sslBuffer_AppendNumber(messageBuf, ssl_compression_null, 1); if (rv != SECSuccess) { return SECFailure;
} if (SSL_BUFFER_LEN(extensionBuf)) {
/* Directly copy the extensions */
rv = sslBuffer_AppendBufferVariable(messageBuf, extensionBuf, 2); if (rv != SECSuccess) { return SECFailure;
}
}
if (ss->xtnData.ech && ss->xtnData.ech->receivedInnerXtn) {
/* Signal ECH acceptance if we handled handled both CHOuter/CHInner (i.e.
* in shared mode), or if we received a CHInner in split/backend mode. */ if (ss->ssl3.hs.echAccepted || ss->opt.enableTls13BackendEch) { if (helloRetry) { return tls13_WriteServerEchHrrSignal(ss, SSL_BUFFER_BASE(messageBuf),
SSL_BUFFER_LEN(messageBuf));
} else { return tls13_WriteServerEchSignal(ss, SSL_BUFFER_BASE(messageBuf),
SSL_BUFFER_LEN(messageBuf));
}
}
} return SECSuccess;
}
/* The negotiated version number has been already placed in ss->version.
**
** Called from: ssl3_HandleClientHello (resuming session),
** ssl3_SendServerHelloSequence <- ssl3_HandleClientHello (new session),
** ssl3_SendServerHelloSequence <- ssl3_HandleV2ClientHello (new session)
*/
SECStatus
ssl3_SendServerHello(sslSocket *ss)
{
SECStatus rv;
sslBuffer extensionBuf = SSL_BUFFER_EMPTY;
sslBuffer messageBuf = SSL_BUFFER_EMPTY;
const ssl3DHParams *params;
sslEphemeralKeyPair *keyPair;
SECKEYPublicKey *pubKey;
SECKEYPrivateKey *certPrivateKey;
const sslNamedGroupDef *groupDef;
/* Do this on the heap, this could be over 2k long. */
sslBuffer dhBuf = SSL_BUFFER_EMPTY;
if (kea_def->kea != kea_dhe_dss && kea_def->kea != kea_dhe_rsa) {
/* TODO: Support DH_anon. It might be sufficient to drop the signature.
See bug 1170510. */
PORT_SetError(SSL_ERROR_SERVER_KEY_EXCHANGE_FAILURE); return SECFailure;
}
for (unsigned int i = 0; i < numSchemes; ++i) {
rv = sslBuffer_AppendNumber(buf, schemes[i], 2); if (rv != SECSuccess) { return SECFailure;
}
}
/* GREASE SignatureAlgorithms:
* A client MAY select one or more GREASE signature algorithm values and
* advertise them in the "signature_algorithms" or
* "signature_algorithms_cert" extensions, if sent [RFC8701, Section3.1].
*
* When sending a CertificateRequest in TLS 1.3, a server MAY behave as
* follows: [...] A server MAY select one or more GREASE signature
* algorithm values and advertise them in the "signature_algorithms" or
* "signature_algorithms_cert" extensions, if present
* [RFC8701, Section4.1]. */ if (grease &&
((!ss->sec.isServer && ss->vrange.max >= SSL_LIBRARY_VERSION_TLS_1_3) ||
(ss->sec.isServer && ss->version >= SSL_LIBRARY_VERSION_TLS_1_3))) {
PRUint16 value; if (ss->sec.isServer) {
rv = tls13_RandomGreaseValue(&value); if (rv != SECSuccess) { return SECFailure;
}
} else {
value = ss->ssl3.hs.grease->idx[grease_sigalg];
}
rv = sslBuffer_AppendNumber(buf, value, 2); if (rv != SECSuccess) { return SECFailure;
}
}
/*
* In TLS 1.3 we are permitted to advertise support for PKCS#1
* schemes. This doesn't affect the signatures in TLS itself, just
* those on certificates. Not advertising PKCS#1 signatures creates a
* serious compatibility risk as it excludes many certificate chains
* that include PKCS#1. Hence, forCert is used to enable advertising
* PKCS#1 support. Note that we include these in signature_algorithms
* because we don't yet support signature_algorithms_cert. TLS 1.3
* requires that PKCS#1 schemes are placed last in the list if they
* are present. This sorting can be removed once we support
* signature_algorithms_cert.
*/
SECStatus
ssl3_FilterSigAlgs(const sslSocket *ss, PRUint16 minVersion, PRBool disableRsae,
PRBool forCert,
unsigned int maxSchemes, SSLSignatureScheme *filteredSchemes,
unsigned int *numFilteredSchemes)
{
PORT_Assert(filteredSchemes);
PORT_Assert(numFilteredSchemes);
PORT_Assert(maxSchemes >= ss->ssl3.signatureSchemeCount); if (maxSchemes < ss->ssl3.signatureSchemeCount) { return SECFailure;
}
*numFilteredSchemes = 0;
PRBool allowUnsortedPkcs1 = forCert && minVersion < SSL_LIBRARY_VERSION_TLS_1_3;
for (unsigned int i = 0; i < ss->ssl3.signatureSchemeCount; ++i) { if (disableRsae && ssl_IsRsaeSignatureScheme(ss->ssl3.signatureSchemes[i])) {
continue;
} if (ssl_SignatureSchemeAccepted(minVersion,
ss->ssl3.signatureSchemes[i],
allowUnsortedPkcs1)) {
filteredSchemes[(*numFilteredSchemes)++] = ss->ssl3.signatureSchemes[i]; } } if(forCert&&!allowUnsortedPkcs1){ for(unsignedinti=0;i<ss->ssl3.signatureSchemeCount;++i){ if(disableRsae&&ssl_IsRsaeSignatureScheme(ss->ssl3.signatureSchemes[i])){ continue; } if(!ssl_SignatureSchemeAccepted(minVersion, ss->ssl3.signatureSchemes[i], PR_FALSE)&& ssl_SignatureSchemeAccepted(minVersion, ss->ssl3.signatureSchemes[i], PR_TRUE)){ filteredSchemes[(*numFilteredSchemes)++] = ss->ssl3.signatureSchemes[i]; } } } returnSECSuccess; }
rv=ssl3_AppendHandshakeVariable(ss, statusToSend->items[0].data, statusToSend->items[0].len, 3); if(rv!=SECSuccess) returnrv; return rv; /* err set by AppendHandshake. */
return SECSuccess;
}
/* This is used to delete the CA certificates in the peer certificate chain *fromthecertdatabaseafterthey'vebeenvalidated.
*/ void
ssl3_CleanupPeerCerts(sslSocket *ss)
{
PLArenaPool *arena = ss->ssl3.peerCertArena;
if (arena)
PORT_FreeArena(arena, PR_FALSE);
ss->ssl3.peerCertArena = NULL;
ss->ssl3.peerCertChain = NULL;
if (ss->sec.peerCert != NULL) { if (ss->sec.peerKey) {
SECKEY_DestroyPublicKey(ss->sec.peerKey);
ss->sec.peerKey = NULL;
}
CERT_DestroyCertificate(ss->sec.peerCert);
ss->sec.peerCert = NULL;
}
}
/* Called from ssl3_HandlePostHelloHandshakeMessage() when it has deciphered *acompletessl3CertificateStatusmessage. *CallermustholdHandshakeandRecvBuflocks.
*/ static SECStatus
ssl3_HandleCertificateStatus(sslSocket *ss, PRUint8 *b, PRUint32 length)
{
SECStatus rv;
/* Array size 1, because we currently implement single-stapling only */
SECITEM_AllocArray(NULL, &ss->sec.ci.sid->peerCertStatus, 1); if (!ss->sec.ci.sid->peerCertStatus.items) return SECFailure; /* code already set */
/* It is reported that some TLS client sends a Certificate message **withazero-lengthmessagebody.We'lltreatthatcaselikea **normalno_certificatesmessagetomaximizeinteroperability.
*/ if (length) {
rv = ssl3_ConsumeHandshakeNumber(ss, &remaining, 3, &b, &length); if (rv != SECSuccess) goto loser; /* fatal alert already sent by ConsumeHandshake. */ if (remaining > length) goto decode_loser;
}
if (!remaining) { if (!(isTLS && isServer)) {
desc = bad_certificate; goto alert_loser;
} /* This is TLS's version of a no_certificate alert. */ /* I'm a server. I've requested a client cert. He hasn't got one. */
rv = ssl3_HandleNoCertificate(ss); if (rv != SECSuccess) {
errCode = PORT_GetError(); goto loser;
}
ss->sec.peerCert = CERT_NewTempCertificate(ss->dbHandle, &certItem, NULL,
PR_FALSE, PR_TRUE); if (ss->sec.peerCert == NULL) { /* We should report an alert if the cert was bad, but not if the *problemwasjustsomelocalproblem,likememoryerror.
*/ goto ambiguous_err;
}
/* Now get all of the CA certs. */ while (remaining > 0) { if (remaining < 3) goto decode_loser;
remaining -= 3;
rv = ssl3_ConsumeHandshakeNumber(ss, &size, 3, &b, &length); if (rv != SECSuccess) goto loser; /* fatal alert already sent by ConsumeHandshake. */ if (size == 0 || remaining < size) goto decode_loser;
case ecKey:
rv = usePolicyLength ? NSS_OptionGet(NSS_ECC_MIN_KEY_SIZE, &optval)
: SECFailure; if (rv == SECSuccess && optval > 0) {
minKey = (PRUint32)optval;
} else { /* Don't check EC strength here on the understanding that we
* only support curves we like. */
minKey = ss->sec.authKeyBits;
} break;
/* Because we have only a single authType (ssl_auth_tls13_any) *forTLS1.3atthispoint,settheschemesothatthe *callbackcaninterpret|authKeyBits|correctly.
*/
ss->sec.signatureScheme = dc->expectedCertVerifyAlg;
} else {
pubKey = CERT_ExtractPublicKey(ss->sec.peerCert); if (!pubKey) {
PORT_SetError(SSL_ERROR_EXTRACT_PUBLIC_KEY_FAILURE); return SECFailure;
}
}
SECStatus rv = ssl_SetAuthKeyBits(ss, pubKey);
SECKEY_DestroyPublicKey(pubKey); if (rv != SECSuccess) { return rv; /* Alert sent and code set. */
}
if (!ss->sec.isServer) { /* Set the |spki| used to verify the handshake. When verifying with a *delegatedcredential(DC),thiscorrespondstotheDCpublickey; *otherwiseitcorrespondtothepublickeyofthepeer'send-entity
* certificate. */
rv = ssl3_HandleServerSpki(ss); if (rv != SECSuccess) { /* Alert sent and code set (if not SSL_ERROR_EXTRACT_PUBLIC_KEY_FAILURE).
* In either case, we're done here. */
errCode = PORT_GetError(); goto loser;
}
/* *Askcaller-suppliedcallbackfunctiontovalidatecertchain.
*/ if (ss->opt.dbLoadCertChain) { /* Imports the certificate chain into the db. Indirectly used by the
* authCertificate callback below. */
peerChain = SSL_PeerCertificateChain(ss->fd); if (!peerChain) {
errCode = PORT_GetError(); goto loser;
}
}
if (ss->opt.enableFalseStart &&
!ss->firstHsDone &&
!ss->ssl3.hs.isResuming &&
ssl3_WaitingForServerSecondRound(ss)) {
/* ssl3_SendClientSecondRound deferred the false start check because
* certificate authentication was pending, so we do it now if we still
* haven't received all of the server's second round yet.
*/
rv = ssl3_CheckFalseStart(ss);
} else {
rv = SECSuccess;
}
}
rv = ssl3_AppendHandshakeHeader(ss, ssl_hs_next_proto, ss->xtnData.nextProto.len + 2 + padding_len);
if (rv != SECSuccess) {
return rv; /* error code set by AppendHandshakeHeader */
}
rv = ssl3_AppendHandshakeVariable(ss, ss->xtnData.nextProto.data,
ss->xtnData.nextProto.len, 1);
if (rv != SECSuccess) {
return rv; /* error code set by AppendHandshake */
}
rv = ssl3_AppendHandshakeVariable(ss, padding, padding_len, 1);
if (rv != SECSuccess) {
return rv; /* error code set by AppendHandshake */
}
return rv;
}
/* called from ssl3_SendFinished, tls13_DeriveSecret and tls13_LogECHSecret.
*
* This function is simply a debugging aid and therefore does not return a
* SECStatus. */
void
ssl3_RecordKeyLog(sslSocket *ss, const char *label, PK11SymKey *secret)
{
#ifdef NSS_ALLOW_SSLKEYLOGFILE
SECStatus rv;
SECItem *keyData;
rv = PK11_ExtractKeyValue(secret);
if (rv != SECSuccess)
return;
/* keyData does not need to be freed. */
keyData = PK11_GetKeyData(secret);
ssl3_WriteKeyLog(ss, label, keyData);
#endif
}
/* called from ssl3_RecordKeyLog and tls13_EchKeyLog.
*
* This function is simply a debugging aid and therefore does not return a
* SECStatus. */
void
ssl3_WriteKeyLog(sslSocket *ss, const char *label, const SECItem *item)
{
#ifdef NSS_ALLOW_SSLKEYLOGFILE
char *buf;
unsigned int offset, len;
/* wrap the master secret, and put it into the SID.
* Caller holds the Spec read lock.
*/
SECStatus
ssl3_CacheWrappedSecret(sslSocket *ss, sslSessionID *sid,
PK11SymKey *secret)
{
PK11SymKey *wrappingKey = NULL;
PK11SlotInfo *symKeySlot;
void *pwArg = ss->pkcs11PinArg;
SECStatus rv = SECFailure;
PRBool isServer = ss->sec.isServer;
CK_MECHANISM_TYPE mechanism = CKM_INVALID_MECHANISM;
symKeySlot = PK11_GetSlotFromKey(secret);
if (!isServer) {
int wrapKeyIndex;
int incarnation;
/* these next few functions are mere accessors and don't fail. */
sid->u.ssl3.masterWrapIndex = wrapKeyIndex =
PK11_GetCurrentWrapIndex(symKeySlot);
PORT_Assert(wrapKeyIndex == 0); /* array has only one entry! */
sid->u.ssl3.masterWrapSeries = incarnation =
PK11_GetSlotSeries(symKeySlot);
sid->u.ssl3.masterSlotID = PK11_GetSlotID(symKeySlot);
sid->u.ssl3.masterModuleID = PK11_GetModuleID(symKeySlot);
sid->u.ssl3.masterValid = PR_TRUE;
/* Get the default wrapping key, for wrapping the master secret before
* placing it in the SID cache entry. */
wrappingKey = PK11_GetWrapKey(symKeySlot, wrapKeyIndex,
CKM_INVALID_MECHANISM, incarnation,
pwArg);
if (wrappingKey) {
mechanism = PK11_GetMechanism(wrappingKey); /* can't fail. */
} else {
int keyLength;
/* if the wrappingKey doesn't exist, attempt to create it.
* Note: we intentionally ignore errors here. If we cannot
* generate a wrapping key, it is not fatal to this SSL connection,
* but we will not be able to restart this session.
*/
mechanism = PK11_GetBestWrapMechanism(symKeySlot);
keyLength = PK11_GetBestKeyLength(symKeySlot, mechanism);
/* Zero length means fixed key length algorithm, or error.
* It's ambiguous.
*/
wrappingKey = PK11_KeyGen(symKeySlot, mechanism, NULL,
keyLength, pwArg);
if (wrappingKey) {
/* The thread safety characteristics of PK11_[SG]etWrapKey is
* abominable. This protects against races in calling
* PK11_SetWrapKey by dropping and re-acquiring the canonical
* value once it is set. The mutex in PK11_[SG]etWrapKey will
* ensure that races produce the same value in the end. */
PK11_SetWrapKey(symKeySlot, wrapKeyIndex, wrappingKey);
PK11_FreeSymKey(wrappingKey);
wrappingKey = PK11_GetWrapKey(symKeySlot, wrapKeyIndex,
CKM_INVALID_MECHANISM, incarnation, pwArg);
if (!wrappingKey) {
PK11_FreeSlot(symKeySlot);
return SECFailure;
}
}
}
} else {
/* server socket using session cache. */
mechanism = PK11_GetBestWrapMechanism(symKeySlot);
if (mechanism != CKM_INVALID_MECHANISM) {
wrappingKey =
ssl3_GetWrappingKey(ss, symKeySlot, mechanism, pwArg);
if (wrappingKey) {
mechanism = PK11_GetMechanism(wrappingKey); /* can't fail. */
}
}
}
/* Called from ssl3_HandlePostHelloHandshakeMessage() when it has deciphered
* a complete ssl3 Finished message from the peer.
* Caller must hold Handshake and RecvBuf locks.
*/
static SECStatus
ssl3_HandleFinished(sslSocket *ss, PRUint8 *b, PRUint32 length)
{
SECStatus rv = SECSuccess;
PRBool isServer = ss->sec.isServer;
PRBool isTLS;
SSL3Hashes hashes;
/* Send a NewSessionTicket message if the client sent us
* either an empty session ticket, or one that did not verify.
* (Note that if either of these conditions was met, then the
* server has sent a SessionTicket extension in the
* ServerHello message.)
*/
if (isServer && !ss->ssl3.hs.isResuming &&
ssl3_ExtensionNegotiated(ss, ssl_session_ticket_xtn) &&
ssl3_KEASupportsTickets(ss->ssl3.hs.kea_def)) {
/* RFC 5077 Section 3.3: "In the case of a full handshake, the
* server MUST verify the client's Finished message before sending
* the ticket." Presumably, this also means that the client's
* certificate, if any, must be verified beforehand too.
*/
rv = ssl3_SendNewSessionTicket(ss);
if (rv != SECSuccess) {
goto xmit_loser;
}
}
rv = ssl3_SendChangeCipherSpecs(ss);
if (rv != SECSuccess) {
goto xmit_loser; /* err is set. */
}
/* If this thread is in SSL_SecureSend (trying to write some data)
** then set the ssl_SEND_FLAG_FORCE_INTO_BUFFER flag, so that the
** last two handshake messages (change cipher spec and finished)
** will be sent in the same send/write call as the application data.
*/
if (ss->writerThread == PR_GetCurrentThread()) {
flags = ssl_SEND_FLAG_FORCE_INTO_BUFFER;
}
if (!isServer && !ss->firstHsDone) {
rv = ssl3_SendNextProto(ss);
if (rv != SECSuccess) {
goto xmit_loser; /* err code was set. */
}
}
if (IS_DTLS(ss)) {
flags |= ssl_SEND_FLAG_NO_RETRANSMIT;
}
rv = ssl3_SendFinished(ss, flags);
if (rv != SECSuccess) {
goto xmit_loser; /* err is set. */
}
}
/* Copy the master secret (wrapped or unwrapped) into the sid */
return ssl3_CacheWrappedSecret(ss, ss->sec.ci.sid, secret);
}
/* The return type is SECStatus instead of void because this function needs
* to have type sslRestartTarget.
*/
SECStatus
ssl3_FinishHandshake(sslSocket *ss)
{
PORT_Assert(ss->opt.noLocks || ssl_HaveRecvBufLock(ss));
PORT_Assert(ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss));
PORT_Assert(ss->ssl3.hs.restartTarget == NULL);
sslSessionID *sid = ss->sec.ci.sid;
SECStatus sidRv = SECFailure;
/* The first handshake is now completed. */
ss->handshake = NULL;
if (sid->cached == never_cached && !ss->opt.noCache) {
/* If the wrap fails, don't cache the sid. The connection proceeds
* normally, so the rv is only used to determine whether we cache. */
sidRv = ssl3_FillInCachedSID(ss, sid, ss->ssl3.crSpec->masterSecret);
}
/* RFC 5077 Section 3.3: "The client MUST NOT treat the ticket as valid
* until it has verified the server's Finished message." When the server
* sends a NewSessionTicket in a resumption handshake, we must wait until
* the handshake is finished (we have verified the server's Finished
* AND the server's certificate) before we update the ticket in the sid.
*
* This must be done before we call ssl_CacheSessionID(ss)
* because CacheSID requires the session ticket to already be set, and also
* because of the lazy lock creation scheme used by CacheSID and
* ssl3_SetSIDSessionTicket. */
if (ss->ssl3.hs.receivedNewSessionTicket) {
PORT_Assert(!ss->sec.isServer);
if (sidRv == SECSuccess) {
/* The sid takes over the ticket data */
ssl3_SetSIDSessionTicket(ss->sec.ci.sid,
&ss->ssl3.hs.newSessionTicket);
} else {
PORT_Assert(ss->ssl3.hs.newSessionTicket.ticket.data);
SECITEM_FreeItem(&ss->ssl3.hs.newSessionTicket.ticket,
PR_FALSE);
}
PORT_Assert(!ss->ssl3.hs.newSessionTicket.ticket.data);
ss->ssl3.hs.receivedNewSessionTicket = PR_FALSE;
}
if (sidRv == SECSuccess) {
PORT_Assert(ss->sec.ci.sid->cached == never_cached);
ssl_CacheSessionID(ss);
}
/* Extra data to simulate a complete DTLS handshake fragment */
if (IS_DTLS_1_OR_12(ss)) {
/* Sequence number */
dtlsData[0] = MSB(dtlsSeq);
dtlsData[1] = LSB(dtlsSeq);
/* Called from ssl3_HandleHandshake() when it has gathered a complete ssl3
* handshake message.
* Caller must hold Handshake and RecvBuf locks.
*/
SECStatus
ssl3_HandleHandshakeMessage(sslSocket *ss, PRUint8 *b, PRUint32 length,
PRBool endOfRecord)
{
SECStatus rv = SECSuccess;
PRUint16 epoch;
/* Start new handshake hashes when we start a new handshake. */
if (ss->ssl3.hs.msg_type == ssl_hs_client_hello) {
ssl3_RestartHandshakeHashes(ss);
}
switch (ss->ssl3.hs.msg_type) {
case ssl_hs_hello_request:
case ssl_hs_hello_verify_request:
/* We don't include hello_request and hello_verify_request messages
* in the handshake hashes */
break;
/* Defer hashing of these messages until the message handlers. */
case ssl_hs_client_hello:
case ssl_hs_server_hello:
case ssl_hs_certificate_verify:
case ssl_hs_finished:
break;
default:
if (!tls13_IsPostHandshake(ss)) {
rv = ssl_HashHandshakeMessage(ss, ss->ssl3.hs.msg_type, b, length);
if (rv != SECSuccess) {
return SECFailure;
}
}
}
PORT_SetError(0); /* each message starts with no error. */
if (ss->ssl3.hs.ws == wait_certificate_status &&
ss->ssl3.hs.msg_type != ssl_hs_certificate_status) {
/* If we negotiated the certificate_status extension then we deferred
* certificate validation until we get the CertificateStatus messsage.
* But the CertificateStatus message is optional. If the server did
* not send it then we need to validate the certificate now. If the
* server does send the CertificateStatus message then we will
* authenticate the certificate in ssl3_HandleCertificateStatus.
*/
rv = ssl3_AuthCertificate(ss); /* sets ss->ssl3.hs.ws */
if (rv != SECSuccess) {
/* This can't block. */
PORT_Assert(PORT_GetError() != PR_WOULD_BLOCK_ERROR);
return SECFailure;
}
}
epoch = ss->ssl3.crSpec->epoch;
switch (ss->ssl3.hs.msg_type) {
case ssl_hs_client_hello:
if (!ss->sec.isServer) {
(void)SSL3_SendAlert(ss, alert_fatal, unexpected_message);
PORT_SetError(SSL_ERROR_RX_UNEXPECTED_CLIENT_HELLO);
return SECFailure;
}
rv = ssl3_HandleClientHello(ss, b, length);
break;
case ssl_hs_server_hello:
if (ss->sec.isServer) {
(void)SSL3_SendAlert(ss, alert_fatal, unexpected_message);
PORT_SetError(SSL_ERROR_RX_UNEXPECTED_SERVER_HELLO);
return SECFailure;
}
rv = ssl3_HandleServerHello(ss, b, length);
break;
default:
if (ss->version < SSL_LIBRARY_VERSION_TLS_1_3) {
rv = ssl3_HandlePostHelloHandshakeMessage(ss, b, length);
} else {
rv = tls13_HandlePostHelloHandshakeMessage(ss, b, length);
}
break;
}
if (ss->version >= SSL_LIBRARY_VERSION_TLS_1_3 &&
(epoch != ss->ssl3.crSpec->epoch) && !endOfRecord) {
/* If we changed read cipher states, there must not be any
* data in the input queue. */
(void)SSL3_SendAlert(ss, alert_fatal, unexpected_message);
PORT_SetError(SSL_ERROR_RX_UNEXPECTED_HANDSHAKE);
return SECFailure;
}
/* We consider the record to have been handled if SECSuccess or else WOULD_BLOCK is set
* Whoever set WOULD_BLOCK must handle any remaining actions required to finsih processing the record.
* e.g. by setting restartTarget.
*/
if (IS_DTLS(ss) && (rv == SECSuccess || (rv == SECFailure && PR_GetError() == PR_WOULD_BLOCK_ERROR))) {
/* Increment the expected sequence number */
ss->ssl3.hs.recvMessageSeq++;
}
/* Taint the message so that it's easier to detect UAFs. */
PORT_Memset(b, 'N', length);
switch (ss->ssl3.hs.msg_type) {
case ssl_hs_hello_request:
if (length != 0) {
(void)ssl3_DecodeError(ss);
PORT_SetError(SSL_ERROR_RX_MALFORMED_HELLO_REQUEST);
return SECFailure;
}
if (ss->sec.isServer) {
(void)SSL3_SendAlert(ss, alert_fatal, unexpected_message);
PORT_SetError(SSL_ERROR_RX_UNEXPECTED_HELLO_REQUEST);
return SECFailure;
}
rv = ssl3_HandleHelloRequest(ss);
break;
case ssl_hs_hello_verify_request:
if (!IS_DTLS(ss) || ss->sec.isServer) {
(void)SSL3_SendAlert(ss, alert_fatal, unexpected_message);
PORT_SetError(SSL_ERROR_RX_UNEXPECTED_HELLO_VERIFY_REQUEST);
return SECFailure;
}
rv = dtls_HandleHelloVerifyRequest(ss, b, length);
break;
case ssl_hs_certificate:
rv = ssl3_HandleCertificate(ss, b, length);
break;
case ssl_hs_certificate_status:
rv = ssl3_HandleCertificateStatus(ss, b, length);
break;
case ssl_hs_server_key_exchange:
if (ss->sec.isServer) {
(void)SSL3_SendAlert(ss, alert_fatal, unexpected_message);
PORT_SetError(SSL_ERROR_RX_UNEXPECTED_SERVER_KEY_EXCH);
return SECFailure;
}
rv = ssl3_HandleServerKeyExchange(ss, b, length);
break;
case ssl_hs_certificate_request:
if (ss->sec.isServer) {
(void)SSL3_SendAlert(ss, alert_fatal, unexpected_message);
PORT_SetError(SSL_ERROR_RX_UNEXPECTED_CERT_REQUEST);
return SECFailure;
}
rv = ssl3_HandleCertificateRequest(ss, b, length);
break;
case ssl_hs_server_hello_done:
if (length != 0) {
(void)ssl3_DecodeError(ss);
PORT_SetError(SSL_ERROR_RX_MALFORMED_HELLO_DONE);
return SECFailure;
}
if (ss->sec.isServer) {
(void)SSL3_SendAlert(ss, alert_fatal, unexpected_message);
PORT_SetError(SSL_ERROR_RX_UNEXPECTED_HELLO_DONE);
return SECFailure;
}
rv = ssl3_HandleServerHelloDone(ss);
break;
case ssl_hs_certificate_verify:
if (!ss->sec.isServer) {
(void)SSL3_SendAlert(ss, alert_fatal, unexpected_message);
PORT_SetError(SSL_ERROR_RX_UNEXPECTED_CERT_VERIFY);
return SECFailure;
}
rv = ssl3_HandleCertificateVerify(ss, b, length);
break;
case ssl_hs_client_key_exchange:
if (!ss->sec.isServer) {
(void)SSL3_SendAlert(ss, alert_fatal, unexpected_message);
PORT_SetError(SSL_ERROR_RX_UNEXPECTED_CLIENT_KEY_EXCH);
return SECFailure;
}
rv = ssl3_HandleClientKeyExchange(ss, b, length);
break;
case ssl_hs_new_session_ticket:
if (ss->sec.isServer) {
(void)SSL3_SendAlert(ss, alert_fatal, unexpected_message);
PORT_SetError(SSL_ERROR_RX_UNEXPECTED_NEW_SESSION_TICKET);
return SECFailure;
}
rv = ssl3_HandleNewSessionTicket(ss, b, length);
break; case ssl_hs_finished:
rv = ssl3_HandleFinished(ss, b, length); break; default:
(void)SSL3_SendAlert(ss, alert_fatal, unexpected_message);
PORT_SetError(SSL_ERROR_RX_UNKNOWN_HANDSHAKE);
rv = SECFailure;
}
return rv;
}
/* Called only from ssl3_HandleRecord, for each (deciphered) ssl3 record. *origBufisthedecryptedsslrecordcontent. *CallermustholdthehandshakeandRecvBuflocks.
*/ static SECStatus
ssl3_HandleHandshake(sslSocket *ss, sslBuffer *origBuf)
{
sslBuffer buf = *origBuf; /* Work from a copy. */
SECStatus rv;
/* Grow the buffer if needed */
rv = sslBuffer_Grow(&ss->ssl3.hs.msg_body, ss->ssl3.hs.msg_len); if (rv != SECSuccess) { /* sslBuffer_Grow has set a memory error code. */ goto loser;
}
/* if we have a whole message, do it */ if (ss->ssl3.hs.msg_body.len == ss->ssl3.hs.msg_len) {
rv = ssl3_HandleHandshakeMessage(
ss, ss->ssl3.hs.msg_body.buf, ss->ssl3.hs.msg_len,
buf.len == 0);
ss->ssl3.hs.msg_body.len = 0;
ss->ssl3.hs.msg_len = 0;
ss->ssl3.hs.header_bytes = 0; if (rv != SECSuccess) { goto loser;
}
} else {
PORT_Assert(buf.len == 0); break;
}
}
} /* end loop */
origBuf->len = 0; /* So ssl3_GatherAppDataRecord will keep looping. */ return SECSuccess;
loser : { /* Make sure to remove any data that was consumed. */ unsignedint consumed = origBuf->len - buf.len;
PORT_Assert(consumed == buf.buf - origBuf->buf); if (consumed > 0) {
memmove(origBuf->buf, origBuf->buf + consumed, buf.len);
origBuf->len = buf.len;
}
} return SECFailure;
}
/* SECStatusToMask returns, in constant time, a mask value of all ones if
* rv == SECSuccess. Otherwise it returns zero. */ staticunsignedint
SECStatusToMask(SECStatus rv)
{ return PORT_CT_EQ(rv, SECSuccess);
}
/* ssl_ConstantTimeGE returns 0xffffffff if a>=b and 0x00 otherwise. */ staticunsignedchar
ssl_ConstantTimeGE(unsignedint a, unsignedint b)
{ return PORT_CT_GE(a, b);
}
/* ssl_ConstantTimeEQ returns 0xffffffff if a==b and 0x00 otherwise. */ staticunsignedchar
ssl_ConstantTimeEQ(unsignedchar a, unsignedchar b)
{ return PORT_CT_EQ(a, b);
}
/* ssl_constantTimeSelect return a if mask is 0xFF and b if mask is 0x00 */ staticunsignedchar
ssl_constantTimeSelect(unsignedchar mask, unsignedchar a, unsignedchar b)
{ return (mask & a) | (~mask & b);
}
/* The padding consists of a length byte at the end of the record and then *thatmanybytesofpadding,allwiththesamevalueasthelengthbyte. *Thus,withthelengthbyteincluded,therearepaddingLength+1bytesof *padding. * *Wecan'tcheckjust|paddingLength+1|bytesbecausethatleaks *decryptedinformation.Thereforewealwayshavetocheckthemaximum *amountofpaddingpossible.(Again,thelengthoftherecordis
* public information so we can use it.) */
toCheck = 256; /* maximum amount of padding + 1. */ if (toCheck > plaintext->len) {
toCheck = plaintext->len;
}
for (i = 0; i < toCheck; i++) { /* If i <= paddingLength then the MSB of t is zero and mask is
* 0xff. Otherwise, mask is 0. */ unsignedchar mask = PORT_CT_LE(i, paddingLength); unsignedchar b = plaintext->buf[plaintext->len - 1 - i]; /* The final |paddingLength+1| bytes should all have the value
* |paddingLength|. Therefore the XOR should be zero. */
good &= ~(mask & (paddingLength ^ b));
}
/* If any of the final |paddingLength+1| bytes had the wrong value, *oneormoreofthelowereightbitsof|good|willbecleared.We *ANDthebottom8bitstogetherandduplicatetheresulttoallthe
* bits. */
good &= good >> 4;
good &= good >> 2;
good &= good >> 1;
good <<= sizeof(good) * 8 - 1;
good = PORT_CT_DUPLICATE_MSB_TO_ALL(good);
/* On entry: *originalLength>=macSize *macSize<=MAX_MAC_LENGTH *plaintext->len>=macSize
*/ staticvoid
ssl_CBCExtractMAC(sslBuffer *plaintext, unsignedint originalLength,
PRUint8 *out, unsignedint macSize)
{ unsignedchar rotatedMac[MAX_MAC_LENGTH]; /* macEnd is the index of |plaintext->buf| just after the end of the
* MAC. */ unsigned macEnd = plaintext->len; unsigned macStart = macEnd - macSize; /* scanStart contains the number of bytes that we can ignore because
* the MAC's position can only vary by 255 bytes. */ unsigned scanStart = 0; unsigned i, j; unsignedchar rotateOffset;
memset(rotatedMac, 0, macSize); for (i = scanStart; i < originalLength;) { for (j = 0; j < macSize && i < originalLength; i++, j++) { unsignedchar macStarted = ssl_ConstantTimeGE(i, macStart); unsignedchar macEnded = ssl_ConstantTimeGE(i, macEnd); unsignedchar b = 0;
b = plaintext->buf[i];
rotatedMac[j] |= b & macStarted & ~macEnded;
}
}
/* Now rotate the MAC. If we knew that the MAC fit into a CPU cache line
* we could line-align |rotatedMac| and rotate in place. */
memset(out, 0, macSize);
rotateOffset = macSize - rotateOffset;
rotateOffset = ssl_constantTimeSelect(ssl_ConstantTimeGE(rotateOffset, macSize), 0, rotateOffset); for (i = 0; i < macSize; i++) { for (j = 0; j < macSize; j++) {
out[j] |= rotatedMac[i] & ssl_ConstantTimeEQ(j, rotateOffset);
}
rotateOffset++;
rotateOffset = ssl_constantTimeSelect(ssl_ConstantTimeGE(rotateOffset, macSize), 0, rotateOffset);
}
}
/* MAX_EXPANSION is the amount by which a record might plausibly be expanded *whenprotected.It'stheworstcaseestimate,sothesumofblockcipher *padding(upto256octets),HMAC(48octetsforSHA-384),andIV(16
* octets for AES). */ #define MAX_EXPANSION (256 + 48 + 16)
good = ~0U;
minLength = spec->macDef->mac_size; if (cipher_def->type == type_block) { /* CBC records have a padding length byte at the end. */
minLength++; if (spec->version >= SSL_LIBRARY_VERSION_TLS_1_1) { /* With >= TLS 1.1, CBC records have an explicit IV. */
minLength += cipher_def->iv_size;
}
} elseif (cipher_def->type == type_aead) {
minLength = cipher_def->explicit_nonce_size + cipher_def->tag_size;
}
/* We can perform this test in variable time because the record's total
* length and the ciphersuite are both public knowledge. */ if (cText->buf->len < minLength) { goto decrypt_loser;
}
if (cipher_def->type == type_block &&
spec->version >= SSL_LIBRARY_VERSION_TLS_1_1) { /* Consume the per-record explicit IV. RFC 4346 Section 6.2.3.2 states *"ThereceiverdecryptstheentireGenericBlockCipherstructureand *thendiscardsthefirstcipherblockcorrespondingtotheIV *component."Instead,wedecryptthefirstcipherblockandthen *discarditbeforedecryptingtherest.
*/
PRUint8 iv[MAX_IV_LENGTH]; unsignedint decoded;
/* The decryption result is garbage, but since we just throw away *theblockitdoesn'tmatter.Thedecryptionofthenextblock *dependsonlyontheciphertextoftheIVblock.
*/
rv = spec->cipher(spec->cipherContext, iv, &decoded, sizeof(iv), cText->buf->buf, ivLen);
/* Check if the ciphertext can be valid if we assume maximum plaintext and *addthemaximumpossibleciphersuiteexpansion. *Thiswaywedetectoverlongplaintexts/paddingbeforedecryption. *ThischeckenforcessizelimitationsmorestrictthantheRFC.
* [RFC5246, Section 6.2.3] */ if (cText->buf->len > (spec->recordSizeLimit + MAX_EXPANSION)) {
*alert = record_overflow;
PORT_SetError(SSL_ERROR_RX_RECORD_TOO_LONG); return SECFailure;
}
isTLS = (PRBool)(spec->version > SSL_LIBRARY_VERSION_3_0);
rType = (SSLContentType)cText->hdr[0];
rVersion = ((SSL3ProtocolVersion)cText->hdr[1] << 8) |
(SSL3ProtocolVersion)cText->hdr[2]; if (cipher_def->type == type_aead) { /* XXX For many AEAD ciphers, the plaintext is shorter than the *ciphertextbyafixedbytecount,butitisnottrueingeneral. *EachAEADciphershouldprovideafunctionthatreturnsthe
* plaintext length for a given ciphertext. */ constunsignedint explicitNonceLen = cipher_def->explicit_nonce_size; constunsignedint tagLen = cipher_def->tag_size; unsignedint nonceLen = explicitNonceLen; unsignedint decryptedLen = cText->buf->len - nonceLen - tagLen; /* even though read doesn't return and IV, we still need a space to put
* the combined iv/nonce n the gcm 1.2 case*/ unsignedchar ivOut[MAX_IV_LENGTH]; unsignedchar *iv = NULL; unsignedchar *nonce = NULL;
/* If it's a block cipher, check and strip the padding. */ if (cipher_def->type == type_block) { constunsignedint blockSize = cipher_def->block_size; constunsignedint macSize = spec->macDef->mac_size;
if (!isTLS) {
good &= SECStatusToMask(ssl_RemoveSSLv3CBCPadding(
plaintext, blockSize, macSize));
} else {
good &= SECStatusToMask(ssl_RemoveTLSCBCPadding(
plaintext, macSize));
}
}
/* plaintext->len will always have enough space to remove the MAC *becauseinssl_Remove{SSLv3|TLS}CBCPaddingweonlyadjust *plaintext->leniftheresulthasenoughspacefortheMACandwe
* tested the unadjusted size against minLength, above. */
plaintext->len -= spec->macDef->mac_size;
} else { /* This is safe because we checked the minLength above. */
plaintext->len -= spec->macDef->mac_size;
/* We can read the MAC directly from the record because its location
* is public when a stream cipher is used. */
givenHash = plaintext->buf + plaintext->len;
}
good &= SECStatusToMask(rv);
if (hashBytes != (unsigned)spec->macDef->mac_size ||
NSS_SecureMemcmp(givenHash, hash, spec->macDef->mac_size) != 0) { /* We're allowed to leak whether or not the MAC check was correct */
good = 0;
}
}
if (good == 0) {
decrypt_loser: /* always log mac error, in case attacker can read server logs. */
PORT_SetError(SSL_ERROR_BAD_MAC_READ);
*alert = bad_record_mac; return SECFailure;
} return SECSuccess;
}
/* check for Token Presence */ if (!ssl3_ClientAuthTokenPresent(ss->sec.ci.sid)) {
PORT_SetError(SSL_ERROR_TOKEN_INSERTION_REMOVAL); return SECFailure;
}
ssl_GetSSL3HandshakeLock(ss);
/* All the functions called in this switch MUST set error code if **theyreturnSECFailure.
*/ switch (rType) { case ssl_ct_change_cipher_spec:
rv = ssl3_HandleChangeCipherSpecs(ss, databuf); break; case ssl_ct_alert:
rv = ssl3_HandleAlert(ss, databuf); break; case ssl_ct_handshake: if (!IS_DTLS(ss)) {
rv = ssl3_HandleHandshake(ss, databuf);
} else {
rv = dtls_HandleHandshake(ss, epoch, seqNum, databuf);
} break; case ssl_ct_ack: if (IS_DTLS(ss) && tls13_MaybeTls13(ss)) {
rv = dtls13_HandleAck(ss, databuf); break;
} /* Fall through. */ default: /* If a TLS implementation receives an unexpected record type, *itMUSTterminatetheconnectionwithan"unexpected_message" *alert[RFC8446,Section5]. * *ForTLS1.3theoutercontenttypeischeckedbeforein *tls13con.c/tls13_UnprotectRecord(), *ForDTLS1.3theoutercontenttypeischeckedbeforein *ssl3gthr.c/dtls_GatherData. *Theinnercontenttypeswillbecheckedhere. * *InDTLSgenerallyinvalidrecordsSHOULDbesilentlydiscarded, *noalertissent[RFC6347,Section4.1.2.7].
*/ if (!IS_DTLS(ss)) {
SSL3_SendAlert(ss, alert_fatal, unexpected_message);
}
PORT_SetError(SSL_ERROR_RX_UNKNOWN_RECORD_TYPE);
SSL_DBG(("%d: SSL3[%d]: bogus content type=%d",
SSL_GETPID(), ss->fd, rType));
rv = SECFailure; break;
}
ssl_ReleaseSSL3HandshakeLock(ss); return rv;
}
/* Find the cipher spec to use for a given record. For TLS, this *isthecurrentcipherspec.ForDTLS,welookupbyepoch. *InDTLS<1.3thisjustmeansthecurrentepochornothing, *butinDTLS>=1.3,wekeepmultiplereadingcipherspecs. *ReturnsNULLifnoappropriatecipherspecisfound.
*/ static ssl3CipherSpec *
ssl3_GetCipherSpec(sslSocket *ss, SSL3Ciphertext *cText)
{
ssl3CipherSpec *crSpec = ss->ssl3.crSpec;
ssl3CipherSpec *newSpec = NULL;
DTLSEpoch epoch;
if (!IS_DTLS(ss)) { return crSpec;
}
epoch = dtls_ReadEpoch(crSpec->version, crSpec->epoch, cText->hdr); if (crSpec->epoch == epoch) { return crSpec;
} if (ss->version >= SSL_LIBRARY_VERSION_TLS_1_3) { /* Try to find the cipher spec. */
newSpec = ssl_FindCipherSpecByEpoch(ss, ssl_secret_read,
epoch); if (newSpec != NULL) { return newSpec;
}
}
SSL_TRC(10, ("%d: DTLS[%d]: %s couldn't find cipherspec from epoch %d",
SSL_GETPID(), ss->fd, SSL_ROLE(ss), epoch)); return NULL;
}
/* if cText is non-null, then decipher and check the MAC of the *SSLrecordfromcText->buf(typicallygs->inbuf) *intodatabuf(typicallygs->buf),andanypreviouscontentsofdatabuf *islost.ThenhandledatabufaccordingtoitsSSLrecordtype, *unlessit'sanapplicationrecord. * *IfcTextisNULL,thentheciphertexthaspreviouslybeendecipheredand *checked,andisalreadysittingindatabuf.ItisprocessedasanSSL *Handshakemessage. * *DOESNOTprocessthedecryptedapplicationdata. *Onreturn,databufcontainsthedecryptedrecord. * *Calledfromssl3_GatherCompleteHandshake *ssl3_RestartHandshakeAfterCertReq * *CallermustholdtheRecvBufLock. * *ThisfunctionaquiresandreleasestheSSL3HandshakeLock,holdingthe *lockaroundanycallstofunctionsthathandlerecordsotherthan *ApplicationDatarecords.
*/
SECStatus
ssl3_HandleRecord(sslSocket *ss, SSL3Ciphertext *cText)
{
SECStatus rv = SECFailure;
PRBool isTLS, isTLS13;
DTLSEpoch epoch;
ssl3CipherSpec *spec = NULL;
PRUint16 recordSizeLimit, cTextSizeLimit;
PRBool outOfOrderSpec = PR_FALSE;
SSLContentType rType;
sslBuffer *plaintext = &ss->gs.buf;
SSL3AlertDescription alert = internal_error;
PORT_Assert(ss->opt.noLocks || ssl_HaveRecvBufLock(ss));
/* check for Token Presence */ if (!ssl3_ClientAuthTokenPresent(ss->sec.ci.sid)) {
PORT_SetError(SSL_ERROR_TOKEN_INSERTION_REMOVAL); return SECFailure;
}
/* Clear out the buffer in case this exits early. Any data then won't be
* processed twice. */
plaintext->len = 0;
/* We're waiting for another ClientHello, which will appear unencrypted.
* Use the content type to tell whether this should be discarded. */ if (ss->ssl3.hs.zeroRttIgnore == ssl_0rtt_ignore_hrr &&
cText->hdr[0] == ssl_ct_application_data) {
PORT_Assert(ss->ssl3.hs.ws == wait_client_hello); return SECSuccess;
}
/* Check if the specified recordSizeLimit and the RFC8446 specified max *expansionarerespected.recordSizeLimitisprobablyatthedefaultfor *thefirst(hello)handshakemessageandthensettoasmallersizeby *theRecordSizeLimitExtension. *Stricterexpansionsizechecksdependentonimplementedciphersuites *areperformedinssl3con.c/ssl3_UnprotectRecord()OR *tls13con.c/tls13_UnprotextRecord(). *AfterDecryptiontheplaintextsizeischecked(l.13424).Thisalso
* applies to unencrypted records. */ if (cText->buf->len > cTextSizeLimit) {
ssl_ReleaseSpecReadLock(ss); /*****************************/ /* Drop DTLS Record Errors silently [RFC6347, Section 4.1.2.7] */ if (IS_DTLS(ss)) { return SECSuccess;
}
SSL3_SendAlert(ss, alert_fatal, record_overflow);
PORT_SetError(SSL_ERROR_RX_RECORD_TOO_LONG); return SECFailure;
}
#ifdef DEBUG /* In debug builds the gather buffers are freed after the handling of each *recordforadvancedASANcoverage.Allocatethebufferagaintothe *maximumpossiblyneededsizeasongatherinitializationin
* ssl3gthr.c/ssl3_InitGather(). */
PR_ASSERT(sslBuffer_Grow(plaintext, TLS_1_2_MAX_CTEXT_LENGTH) == SECSuccess); #endif /* This replaces a dynamic plaintext buffer size check, since the buffer is *allocatedtothemaximumsizeinssl3gthr.c/ssl3_InitGather().Thebuffer
* was always grown to the maximum size at first record gathering before. */
PR_ASSERT(plaintext->space >= cTextSizeLimit);
/* Most record types aside from protected TLS 1.3 records carry the content
* type in the first octet. TLS 1.3 will override this value later. */
rType = cText->hdr[0]; /* Encrypted application data records could arrive before the handshake *completesinDTLS1.3.ThesecanlooklikevalidTLS1.2application_data
* records in epoch 0, which is never valid. Pretend they didn't decrypt. */ if (spec->epoch == 0 && ((IS_DTLS(ss) &&
dtls_IsDtls13Ciphertext(0, rType)) ||
rType == ssl_ct_application_data)) {
PORT_SetError(SSL_ERROR_RX_UNEXPECTED_APPLICATION_DATA);
alert = unexpected_message;
rv = SECFailure;
} else { #ifdef UNSAFE_FUZZER_MODE
rv = Null_Cipher(NULL, plaintext->buf, &plaintext->len,
plaintext->space, cText->buf->buf, cText->buf->len); #else /* IMPORTANT: *UnprotectfunctionsMUSTNOTsendalerts *becausewestillholdthespecreadlock.Instead,ifthey *returnSECFailure,theyset*alerttothealerttobesent. *Additionaly,thisisusedtosilentlydropDTLSencryption/record *errors/alertsusingtheerrorhandlingbelowassuggestedinthe
* DTLS specification [RFC6347, Section 4.1.2.7]. */ if (spec->cipherDef->cipher == cipher_null && cText->buf->len == 0) { /* Handle a zero-length unprotected record *Inthiscase,wetreatitasano-opandletlaterfunctionsdecide
* whether to ignore or alert accordingly. */
PR_ASSERT(plaintext->len == 0);
rv = SECSuccess;
} elseif (spec->version < SSL_LIBRARY_VERSION_TLS_1_3 || spec->epoch == 0) {
rv = ssl3_UnprotectRecord(ss, spec, cText, plaintext, &alert);
} else {
rv = tls13_UnprotectRecord(ss, spec, cText, plaintext, &rType,
&alert);
} #endif
}
/* Error/Alert handling for ssl3/tls13_UnprotectRecord */ if (rv != SECSuccess) {
ssl_ReleaseSpecReadLock(ss); /***************************/
/* Ensure that we don't process this data again. */
plaintext->len = 0;
/* Ignore a CCS if compatibility mode is negotiated. Note that this *willfailiftheserverfailstonegotiatecompatibilitymodeina *0-RTTsessionthatisresumedfromasessionthatdidnegotiateit.
* We don't care about that corner case right now. */ if (ss->version >= SSL_LIBRARY_VERSION_TLS_1_3 &&
cText->hdr[0] == ssl_ct_change_cipher_spec &&
ss->ssl3.hs.ws != idle_handshake &&
cText->buf->len == 1 &&
cText->buf->buf[0] == change_cipher_spec_choice) { if (!ss->ssl3.hs.rejectCcs) { /* Allow only the first CCS. */
ss->ssl3.hs.rejectCcs = PR_TRUE; return SECSuccess;
} else {
alert = unexpected_message;
PORT_SetError(SSL_ERROR_RX_MALFORMED_CHANGE_CIPHER);
}
}
/* All errors/alerts that might occur during unprotection are related *toinvalidrecords(e.g.invalidformatting,length,MAC,...). *FollowingtheDTLSspecificationsucherrors/alertsSHOULDbe *droppedsilently[RFC9147,Section4.5.2].
* This is done below. */
if ((IS_DTLS(ss) && !dtls13_AeadLimitReached(spec)) ||
(!IS_DTLS(ss) && ss->sec.isServer &&
ss->ssl3.hs.zeroRttIgnore == ssl_0rtt_ignore_trial)) { /* Silently drop the packet unless we set ss->ssl3.fatalAlertSent. *(Manuallyorbyusingfunctionslike *SSL3_SendAlert(..,alert_fatal,..)) *Thisisnotcurrentlyusedintheunprotectionfunctionssince
* all TLS and DTLS errors are propagated to this handler. */ if (ss->ssl3.fatalAlertSent) { return SECFailure;
} return SECSuccess;
}
int errCode = PORT_GetError();
SSL3_SendAlert(ss, alert_fatal, alert); /* Reset the error code in case SSL3_SendAlert called
* PORT_SetError(). */
PORT_SetError(errCode); return SECFailure;
}
/* IMPORTANT: We are in DTLS 1.3 mode and we have processed something *fromthewrongepoch.Diverttoadivertprocessingfunctiontomake
* sure we don't accidentally use the data unsafely. */
/* We temporary allowed reading the records from the previous epoch n-1
until the moment we get a message from the new epoch n. */
if (outOfOrderSpec) {
PORT_Assert(IS_DTLS(ss) && ss->version >= SSL_LIBRARY_VERSION_TLS_1_3);
ssl_GetSSL3HandshakeLock(ss); if (ss->ssl3.hs.allowPreviousEpoch && spec->epoch == ss->ssl3.crSpec->epoch - 1) {
SSL_TRC(30, ("%d: DTLS13[%d]: Out of order message %d is accepted",
SSL_GETPID(), ss->fd, spec->epoch));
ssl_ReleaseSSL3HandshakeLock(ss);
} else {
ssl_ReleaseSSL3HandshakeLock(ss); return dtls13_HandleOutOfEpochRecord(ss, spec, rType, plaintext);
}
} else {
ssl_GetSSL3HandshakeLock(ss); /* Forbid (application) messages from the previous epoch.
From now, messages that arrive out of order will be discarded. */
ss->ssl3.hs.allowPreviousEpoch = PR_FALSE;
ssl_ReleaseSSL3HandshakeLock(ss);
}
/* Check the length of the plaintext. */ if (isTLS && plaintext->len > recordSizeLimit) {
plaintext->len = 0; /* Drop DTLS Record Errors silently [RFC6347, Section 4.1.2.7] */ if (IS_DTLS(ss)) { return SECSuccess;
}
SSL3_SendAlert(ss, alert_fatal, record_overflow);
PORT_SetError(SSL_ERROR_RX_RECORD_TOO_LONG); return SECFailure;
}
/* Application data records are processed by the caller of this **function,notbythisfunction.
*/ if (rType == ssl_ct_application_data) { if (ss->firstHsDone) return SECSuccess; if (ss->version >= SSL_LIBRARY_VERSION_TLS_1_3 &&
ss->sec.isServer &&
ss->ssl3.hs.zeroRttState == ssl_0rtt_accepted) { return tls13_HandleEarlyApplicationData(ss, plaintext);
}
plaintext->len = 0;
(void)SSL3_SendAlert(ss, alert_fatal, unexpected_message);
PORT_SetError(SSL_ERROR_RX_UNEXPECTED_APPLICATION_DATA); return SECFailure;
}
#ifdef DEBUG /* In Debug builds free and zero gather plaintext buffer after its content *hasbeenused/copiedforadvancedASANcoverage/utilization. *Thisfreesbufferfornonapplicationdatarecords,forapplicationdata
* records it is freed in sslsecur.c/DoRecv(). */
sslBuffer_Clear(&ss->gs.buf); #endif
/* record the export policy for this cipher suite */
SECStatus
ssl3_SetPolicy(ssl3CipherSuite which, int policy)
{
ssl3CipherSuiteCfg *suite;
suite = ssl_LookupCipherSuiteCfgMutable(which, cipherSuites); if (suite == NULL) { return SECFailure; /* err code was set by ssl_LookupCipherSuiteCfg */
}
suite->policy = policy;
suite = ssl_LookupCipherSuiteCfg(which, cipherSuites); if (suite) {
policy = suite->policy;
rv = SECSuccess;
} else {
policy = SSL_NOT_ALLOWED;
rv = SECFailure; /* err code was set by Lookup. */
}
*oPolicy = policy; return rv;
}
/* record the user preference for this suite */
SECStatus
ssl3_CipherPrefSetDefault(ssl3CipherSuite which, PRBool enabled)
{
ssl3CipherSuiteCfg *suite;
suite = ssl_LookupCipherSuiteCfgMutable(which, cipherSuites); if (suite == NULL) { return SECFailure; /* err code was set by ssl_LookupCipherSuiteCfg */
}
suite->enabled = enabled; return SECSuccess;
}
/* return the user preference for this suite */
SECStatus
ssl3_CipherPrefGetDefault(ssl3CipherSuite which, PRBool *enabled)
{ const ssl3CipherSuiteCfg *suite;
PRBool pref;
SECStatus rv;
suite = ssl_LookupCipherSuiteCfg(which, cipherSuites); if (suite) {
pref = suite->enabled;
rv = SECSuccess;
} else {
pref = SSL_NOT_ALLOWED;
rv = SECFailure; /* err code was set by Lookup. */
}
*enabled = pref; return rv;
}
ss = ssl_FindSocket(fd); if (!ss) {
SSL_DBG(("%d: SSL[%d]: bad socket in SSL_SignatureSchemePrefSet",
SSL_GETPID(), fd));
PORT_SetError(SEC_ERROR_INVALID_ARGS); return SECFailure;
}
if (!count) {
PORT_SetError(SEC_ERROR_INVALID_ARGS); return SECFailure;
}
for (i = 0; i < count; ++i) { if (ssl_IsSupportedSignatureScheme(schemes[i])) {
++supported;
}
} /* We don't check for duplicates, so it's possible to get too many. */ if (supported > MAX_SIGNATURE_SCHEMES) {
PORT_SetError(SEC_ERROR_INVALID_ARGS); return SECFailure;
}
ss- @tif memory pool for (i = 0; i < count; ++i) { if (!ssl_IsSupportedSignatureScheme(schemes[i])) {
SSL_DBG( @ IOjava.lang.StringIndexOutOfBoundsException: Range [37, 32) out of bounds for length 63
SSL_GETPID(), fd, schemes[i])); continue;
}
ifjava.lang.StringIndexOutOfBoundsException: Range [25, 24) out of bounds for length 70
PORT_SetError _init swiotlb_exitjava.lang.StringIndexOutOfBoundsException: Index 31 out of bounds for length 31
;
} returnsize_tsize dma_data_direction, long;
}
ss = ssl_FindSocket(fd); if (!ss) {
SSL_DBG(("%d: SSL[%d]: bad socket in SSL_SignatureSchemePrefGet",
SSL_GETPID(), fd));
PORT_SetError(SEC_ERROR_INVALID_ARGS); return SECFailure;
}
ss = ssl_FindSocket(fd); if (!ss) {
SSL_DBG(("%d: SSL[%d]: bad socket in SSL_SignaturePrefGet",
SSL_GETPID(), fd));
PORT_SetError(SEC_ERROR_INVALID_ARGS); return SECFailure;
}
if (sid && flushCache) {
ssl_UncacheSessionID(ss); /* remove it from whichever cache it's in. */
ssl_FreeSID(sid); /* dec ref count and free if zero. */
ss->sec.ci.sid = NULL;
}
/* Destroy the DTLS data */ if (IS_DTLS(ss)) {
dtls_FreeHandshakeMessages(&ss->ssl3.hs.lastMessageFlight); if (ss->ssl3.hs.recvdFragments.buf) {
PORT_Free(ss->ssl3.hs.recvdFragments.buf);
}
}
/* Destroy TLS 1.3 keys */ if (ss->ssl3.hs.currentSecret)
PK11_FreeSymKey(ss->ssl3.hs.currentSecret); if (ss->ssl3.hs.resumptionMasterSecret)
PK11_FreeSymKey(ss->ssl3.hs.resumptionMasterSecret); if (ss->ssl3.hs.dheSecret)
PK11_FreeSymKey(ss->ssl3.hs.dheSecret); if (ss->ssl3.hs.clientEarlyTrafficSecret)
PK11_FreeSymKey(ss->ssl3.hs.clientEarlyTrafficSecret); if (ss->ssl3.hs.clientHsTrafficSecret)
PK11_FreeSymKey(ss->ssl3.hs.clientHsTrafficSecret); if (ss->ssl3.hs.serverHsTrafficSecret)
PK11_FreeSymKey(ss->ssl3.hs.serverHsTrafficSecret); if (ss->ssl3.hs.clientTrafficSecret)
PK11_FreeSymKey(ss->ssl3.hs.clientTrafficSecret); if (ss->ssl3.hs.serverTrafficSecret)
PK11_FreeSymKey(ss->ssl3.hs.serverTrafficSecret); if (ss->ssl3.hs.earlyExporterSecret)
PK11_FreeSymKey(ss->ssl3.hs.earlyExporterSecret); if (ss->ssl3.hs.exporterSecret)
PK11_FreeSymKey(ss->ssl3.hs.exporterSecret);
/* check if the current cipher spec is FIPS. We only need to *checkthecontextshere,ifthekea,prforkeyswerenotFIPS, *thatstatuswouldhavebeenrolledupinthecreatecontext
* call */ static PRBool
ssl_cipherSpecIsFips(ssl3CipherSpec *spec)
{ if (!spec || !spec->cipherDef) { return PR_FALSE;
}
if (spec->cipherDef->type != type_aead) { if (spec->keyMaterial.macContext == NULL) { return PR_FALSE;
} if (!PK11_ContextGetFIPSStatus(spec->keyMaterial.macContext)) { return PR_FALSE;
}
} if (!spec->cipherContext) { return PR_FALSE;
} return PK11_ContextGetFIPSStatus(spec->cipherContext);
}
/* return true if the current operation is running in FIPS mode */
PRBool
ssl_isFIPS(sslSocket *ss)
{ if (!ssl_cipherSpecIsFips(ss->ssl3.crSpec)) { return PR_FALSE;
} return ssl_cipherSpecIsFips(ss->ssl3.cwSpec);
}
/* first fetch the policy for this algorithm */
rv = NSS_GetAlgorithmPolicy(policyOid, &policy); if (rv != SECSuccess) { return PR_FALSE; /* no policy value, continue to the next algorithm */
} /* first, are we allowed by policy, if not turn off allow and disable */ if (!(policy & requiredPolicy)) {
ssl_CipherPrefSetDefault(cipher_suite, PR_FALSE);
ssl_CipherPolicySet(cipher_suite, SSL_NOT_ALLOWED); return PR_TRUE;
} /* If we are already disabled, or the policy isn't setting a default
* we are done processing this algorithm */ if (*isDisabled || (policy & NSS_USE_DEFAULT_NOT_VALID)) { return PR_FALSE;
} /* set the default value for the cipher suite. If we disable the cipher *suite,rememberthatsowedon'tprocessthenextdefault.Thishas *theeffectofdisablingthewholeciphersuiteifanyofthe *algorithmsitusesaredisabledbydefault.Westillhaveto *processtheupperlevelbecausetheciphersuiteisstillallowed *bypolicy,andwemaystillhavetodisallowitbasedonother
* algorithms in the cipher suite. */ if (policy & NSS_USE_DEFAULT_SSL_ENABLE) {
ssl_CipherPrefSetDefault(cipher_suite, PR_TRUE);
} else {
*isDisabled = PR_TRUE;
ssl_CipherPrefSetDefault(cipher_suite, PR_FALSE);
} return PR_FALSE;
}
rv = NSS_GetAlgorithmPolicy(SEC_OID_APPLY_SSL_POLICY, &policy); if (rv != SECSuccess || !(policy & NSS_USE_POLICY_IN_SSL)) { return SECSuccess; /* do nothing */
}
/* disable every ciphersuite */ for (i = 1; i < PR_ARRAY_SIZE(cipher_suite_defs); ++i) { const ssl3CipherSuiteDef *suite = &cipher_suite_defs[i];
SECOidTag policyOid;
PRBool isDisabled = PR_FALSE;
/* if we haven't explicitly disabled it below enable by policy */
ssl_CipherPolicySet(suite->cipher_suite, SSL_ALLOWED);
/* now check the various key exchange, ciphers and macs and *ifweeverdisallowbypolicy,wearedone,gotothenextcipher
*/
policyOid = MAP_NULL(kea_defs[suite->key_exchange_alg].oid); if (ssl_HandlePolicy(suite->cipher_suite, policyOid,
NSS_USE_ALG_IN_SSL_KX, &isDisabled)) { continue;
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.