/* 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 (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) { unsignedint written = 0;
PRInt32 sent;
PORT_Assert(written > 0); /* DTLS should not fragment non-application data here. */ if (IS_DTLS(ss) && ct != ssl_ct_application_data) {
PORT_Assert(written == nIn);
}
pIn += written;
nIn -= written;
PORT_Assert(nIn >= 0);
/* If there's still some previously saved ciphertext, *orthecallerdoesn'twantustosendthedatayet, *thenaddallournewciphertexttotheamountpreviouslysaved.
*/ if ((ss->pendingBuf.len > 0) ||
(flags & ssl_SEND_FLAG_FORCE_INTO_BUFFER)) {
rv = ssl_SaveWriteData(ss, SSL_BUFFER_BASE(wrBuf),
SSL_BUFFER_LEN(wrBuf)); if (rv != SECSuccess) { /* presumably a memory error, SEC_ERROR_NO_MEMORY */ goto loser;
}
if (!(flags & ssl_SEND_FLAG_FORCE_INTO_BUFFER)) {
ss->handshakeBegun = 1;
sent = ssl_SendSavedWriteData(ss); if (sent < 0 && PR_GetError() != PR_WOULD_BLOCK_ERROR) {
ssl_MapLowLevelError(SSL_ERROR_SOCKET_WRITE_FAILURE); goto loser;
} if (ss->pendingBuf.len) {
flags |= ssl_SEND_FLAG_FORCE_INTO_BUFFER;
}
}
} else {
PORT_Assert(SSL_BUFFER_LEN(wrBuf) > 0);
ss->handshakeBegun = 1;
sent = ssl_DefSend(ss, SSL_BUFFER_BASE(wrBuf),
SSL_BUFFER_LEN(wrBuf),
flags & ~ssl_SEND_FLAG_MASK); if (sent < 0) { if (PORT_GetError() != PR_WOULD_BLOCK_ERROR) {
ssl_MapLowLevelError(SSL_ERROR_SOCKET_WRITE_FAILURE); goto loser;
} /* we got PR_WOULD_BLOCK_ERROR, which means none was sent. */
sent = 0;
} if (SSL_BUFFER_LEN(wrBuf) > (unsignedint)sent) { 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.
*/
rv = ssl_SaveWriteData(ss, SSL_BUFFER_BASE(wrBuf) + sent,
SSL_BUFFER_LEN(wrBuf) - sent); if (rv != SECSuccess) { /* presumably a memory error, SEC_ERROR_NO_MEMORY */ goto loser;
}
}
}
wrBuf->len = 0;
totalSent += written;
} return totalSent;
/* Attempt to send the content of "in" in an SSL application_data record. *Returns"len"or-1onfailure.
*/ int
ssl3_SendApplicationData(sslSocket *ss, constunsignedchar *in,
PRInt32 len, PRInt32 flags)
{
PRInt32 totalSent = 0;
PRInt32 discarded = 0;
PRBool splitNeeded = PR_FALSE;
PORT_Assert(ss->opt.noLocks || ssl_HaveXmitBufLock(ss)); /* These flags for internal use only */
PORT_Assert(!(flags & ssl_SEND_FLAG_NO_RETRANSMIT)); if (len < 0 || !in) {
PORT_SetError(PR_INVALID_ARGUMENT_ERROR); return -1;
}
/* We will split the first byte of the record into its own record, as *explainedinthedocumentationforSSL_CBC_RANDOM_IVinssl.h.
*/ if (len > 1 && ss->opt.cbcRandomIV &&
ss->version < SSL_LIBRARY_VERSION_TLS_1_1 &&
ss->ssl3.cwSpec->cipherDef->type == type_block /* CBC */) {
splitNeeded = PR_TRUE;
}
/* If the server has required client-auth blindly but doesn't *actuallylookatthecertificateitwon'tknowthatno *certificatewaspresentedsoweshutdownthesockettoensure *anerror.Weonlydothisifwehaven'talreadycompletedthe *firsthandshakebecauseifwe'reredoingthehandshakewe *knowtheserverispayingattentiontothecertificate.
*/ if ((ss->opt.requireCertificate == SSL_REQUIRE_ALWAYS) ||
(!ss->firstHsDone &&
(ss->opt.requireCertificate == SSL_REQUIRE_FIRST_HANDSHAKE))) {
PRFileDesc *lower;
switch (errCode) { case SEC_ERROR_LIBRARY_FAILURE:
desc = unsupported_certificate; break; case SEC_ERROR_EXPIRED_CERTIFICATE:
desc = certificate_expired; break; case SEC_ERROR_REVOKED_CERTIFICATE:
desc = certificate_revoked; break; case SEC_ERROR_INADEQUATE_KEY_USAGE: case SEC_ERROR_INADEQUATE_CERT_TYPE:
desc = certificate_unknown; break; case SEC_ERROR_UNTRUSTED_CERT:
desc = isTLS ? access_denied : certificate_unknown; 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; break;
case SEC_ERROR_CERT_NOT_IN_NAME_SPACE: case SEC_ERROR_PATH_LEN_CONSTRAINT_INVALID: case 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(), ss->fd, errCode));
SSL_TRC(3, ("%d: SSL3[%d] Set Current Write Cipher Suite to Pending",
SSL_GETPID(), ss->fd));
/* 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);
}
ssl_ReleaseSpecWriteLock(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 && IS_DTLS(ss)) { /* 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->fd));
buf->len = 0; return SECSuccess;
}
/* Handshake messages should not span ChangeCipherSpec. */ if (ss->ssl3.hs.header_bytes) {
(void)SSL3_SendAlert(ss, alert_fatal, unexpected_message);
PORT_SetError(SSL_ERROR_RX_UNEXPECTED_CHANGE_CIPHER); return SECFailure;
} if (buf->len != 1) {
(void)ssl3_DecodeError(ss);
PORT_SetError(SSL_ERROR_RX_MALFORMED_CHANGE_CIPHER); 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(). */ if (ws == wait_server_hello &&
ss->version >= SSL_LIBRARY_VERSION_TLS_1_3 &&
ss->ssl3.hs.helloRetry) {
PORT_Assert(!ss->sec.isServer); return SECSuccess;
} /* Note: For a server, we can't test ss->ssl3.hs.helloRetry or *ss->versionbecausetheservermightbestateless(andsoitwon't *haveseteithervalueyet).Setaflagsothatatleastwewill
* 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; return SECSuccess;
}
(void)SSL3_SendAlert(ss, alert_fatal, unexpected_message);
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(ss->ssl3.crSpec);
ss->ssl3.crSpec = ss->ssl3.prSpec;
ss->ssl3.prSpec = NULL;
ssl_ReleaseSpecWriteLock(ss); /*************************************/
static CK_MECHANISM_TYPE
ssl3_GetMgfMechanismByHashType(SSLHashType hash)
{ switch (hash) { case ssl_hash_sha256: return CKG_MGF1_SHA256; 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_1; default:
PORT_Assert(0);
} return CKM_SHA256;
}
/* 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,elsereturnanerror. ** **2.Checktheversionif|pms_version|isnon-zeroandifwrong, **returnanerror. ** **3.If|msp|isnonzero,returnMSin|*msp|.
/* if we are using TLS and we aren't using the extended master secret, *andSEC_OID_TLS_REQUIRE_EMSpolicyistrue,fail.Thecallerwill *sendanalert(eventually).IntheRSAServercase,thealert *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); return SECFailure;
}
}
/* 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(SSL_ERROR_SESSION_KEY_GEN_FAILURE); return SECFailure;
} /* we really should use the actual mac'ing mechanism here, but we *don'tbecausethesetypesareusedtomapkeytypeanywayandboth *mac'smaptothesamekeytype.
*/
slot = PK11_GetSlotFromKey(derivedKeyHandle);
void
ssl3_CoalesceEchHandshakeHashes(sslSocket *ss)
{ /* |sha| contains the CHOuter transcript, which is the singular *transcriptifnotdoingECH.Iftheserverrespondedwith1.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_InitHandshakeHashes(sslSocket *ss)
{
SSL_TRC(30, ("%d: SSL3[%d]: start handshake hashes", SSL_GETPID(), ss->fd));
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 *handshakehashesinhopesthatwewindupwiththesameslots *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); return SECFailure;
}
/* 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, constunsignedchar *b, unsignedint l, sslBuffer *target)
{
/* The next two functions serve to append the handshake header. ThefirstoneadditionallywritestoseqNumberBuffer thesequencenumberofthemessagewearegenerating. ThisfunctionisusedwhengeneratingthekeyUpdatemessageindtls13_enqueueKeyUpdateMessage.
*/
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. *Thisemptiesthebuffer.Thisisaconvenientplacetocall *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 = ssl3_AppendHandshakeNumber(ss, length, 3); 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, 3, suppressHash); 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);
}
/* 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
ssl3_HashTypeToOID(SSLHashType hashType)
{ switch (hashType) { 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: case ssl_sig_dsa_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 ssl_hash_sha384; 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 1.0/1.1. */ case ssl_sig_none: case ssl_sig_ed25519: case ssl_sig_ed448: break;
}
PORT_Assert(0); return ssl_hash_none;
}
/* Validate that the signature scheme works for the given key type. */
PRBool
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 *wenotcheckingtheschemeagainstapotentialkey,soskip
* the call */ if ((spkiOid != SEC_OID_UNKNOWN) &&
!ssl_SignatureSchemeMatchesSpkiOid(scheme, spkiOid)) { return PR_FALSE;
} if (isTls13) { if (ssl_SignatureSchemeToHashType(scheme) == ssl_hash_sha1) { return PR_FALSE;
} 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;
} return PR_TRUE;
}
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); 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: break;
}
PORT_SetError(SSL_ERROR_BAD_CERTIFICATE); return SECFailure;
}
/* Newer signature schemes are designed so that a single SPKI can be used with *thatscheme.ThisdeterminesthatschemefromtheSPKI.IftheSPKIdoesn'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 *theSPKIalonebecausetheECDSAkeysizedeterminesthehash.Earlier
* TLS versions allow the same EC key to be used with different hashes. */ 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)
{ unsignedint 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 *keaDef, SECOidTag spkiOid)
{ switch (spkiOid) { case SEC_OID_X500_RSA_ENCRYPTION: case SEC_OID_PKCS1_RSA_ENCRYPTION: case SEC_OID_PKCS1_RSA_PSS_SIGNATURE: return keaDef->signKeyType == rsaKey; case SEC_OID_ANSIX9_DSA_SIGNATURE: return keaDef->signKeyType == dsaKey; case SEC_OID_ANSIX962_EC_PUBLIC_KEY: return keaDef->signKeyType == ecKey; default: break;
} return PR_FALSE;
}
/* ssl3_CheckSignatureSchemeConsistency checks that the signature algorithm *identifierin|scheme|isconsistentwiththepublickeyin|spki|.Italso *checksthehashalgorithmagainsttheconfiguredsignaturealgorithms.If *allthetestspass,SECSuccessisreturned.Otherwise,PORT_SetErroris
* called and SECFailure is returned. */
SECStatus
ssl_CheckSignatureSchemeConsistency(sslSocket *ss, SSLSignatureScheme scheme,
CERTSubjectPublicKeyInfo *spki)
{
SSLSignatureScheme spkiScheme;
PRBool isTLS13 = ss->version == SSL_LIBRARY_VERSION_TLS_1_3;
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;
}
}
/* Verify that the signature scheme matches the signing key. */ if ((spkiOid == SEC_OID_UNKNOWN) ||
!ssl_SignatureSchemeValid(scheme, spkiOid, isTLS13)) {
PORT_SetError(SSL_ERROR_INCORRECT_SIGNATURE_ALGORITHM); return SECFailure;
}
if (!ssl_SignatureSchemeEnabled(ss, scheme)) {
PORT_SetError(SSL_ERROR_UNSUPPORTED_SIGNATURE_ALGORITHM); return SECFailure;
}
return SECSuccess;
}
PRBool
ssl_IsSupportedSignatureScheme(SSLSignatureScheme scheme)
{ switch (scheme) { 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 ssl_sig_rsa_pss_pss_sha384: case ssl_sig_rsa_pss_pss_sha512: case ssl_sig_ecdsa_secp256r1_sha256: case ssl_sig_ecdsa_secp384r1_sha384: 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 scheme)
{ 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: return PR_TRUE;
default: return PR_FALSE;
} 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: 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: return PR_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 PR_TRUE;
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: /* We report based on the key type for PSS signatures. */ 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; case ssl_sig_rsa_pss_pss_sha256: case ssl_sig_rsa_pss_pss_sha384: case ssl_sig_rsa_pss_pss_sha512: return ssl_auth_rsa_pss; 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 ssl_auth_dsa;
PR_STATIC_ASSERT(SSL3_SESSIONID_BYTES == SSL3_RANDOM_LENGTH); staticvoid
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. */ staticvoid
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 *ClientHelloto{3,1}(TLS1.0).SomeTLS1.0servers(whichseem *touseF5BIG-IP)ignoreClientHello.client_versionandusethe *recordlayerversionnumber(TLSPlaintext.version)insteadwhen *negotiatingprotocolversions.Inaddition,iftherecordlayer *versionnumberofClientHellois{3,2}(TLS1.1)orhigher,these *serversresettheTCPconnections.Lastly,someF5BIG-IPservers *hangifarecordcontainingaClientHellohasaversiongreaterthan *{3,1}andalengthgreaterthan255.Setthisflagtoworkaround *suchservers. * *Thefinalversionissetwhenaversionisnegotiated.
*/
spec->recordVersion = PR_MIN(SSL_LIBRARY_VERSION_TLS_1_0,
ss->vrange.max);
}
ssl_ReleaseSpecWriteLock(ss);
}
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);
} elseif (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;
}
}
/* 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. */
}
/* *Duringarenegotiation,ss->clientHelloVersionwillbeusedagainto *workaroundaWindowsSChannelbug.Ensurethatitisstillenabled.
*/ 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. *Checkthatit'snotexpired.
* 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));
} elseif (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);
} elseif (!ss->opt.noCache) { /* We ignore ss->sec.ci.sid here, and use ssl_Lookup because Lookup *handlesexpiredentriesandotherdetails. *XXXIfwe'vebeencalledfromssl_BeginClientHandshake,then *thislookupisduplicativeandwasteful.
*/
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, *makesurethetokenthatholdsthemastersecretstillexists... *Ifwepreviouslydidclient-auth,makesurethatthetokenthatholds *theprivatekeystillexists,isloggedin,hasn'tbeenremoved,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 **holdstheprivatekeystillexists,isloggedin,hasn'tbeen **removed,etc.
*/ if (sidOK && !ssl3_ClientAuthTokenPresent(sid)) {
sidOK = PR_FALSE;
}
if (sidOK) { /* Set version based on the sid. */ if (ss->firstHsDone) { /* *WindowsSChannelcomparestheclient_versioninsidetheRSA *EncryptedPreMasterSecretofarenegotiationwiththe *client_versionoftheinitialClientHelloratherthanthe *ClientHellointherenegotiation.Toworkaroundthisbug,we *continuetousetheclient_versionusedintheinitial *ClientHellowhenrenegotiating. * *Theclient_versionoftheinitialClientHelloisstill *availableinss->clientHelloVersion.Ensurethat *sid->versionisboundedwithin *[ss->vrange.min,ss->clientHelloVersion],otherwisewe *can'tusesid.
*/ if (sid->version >= ss->vrange.min &&
sid->version <= ss->clientHelloVersion) {
version = ss->clientHelloVersion;
} else {
sidOK = PR_FALSE;
}
} else { /* *Checksid->versionisOKfirst. *Previously,wewouldcaptheversionbasedonsid->version, *butthatpreventsnegotiationofahigherversionifthe *previoussessionwasreduced(e.g.,withversionfallback)
*/ if (sid->version < ss->vrange.min ||
sid->version > ss->vrange.max) {
sidOK = PR_FALSE;
}
}
}
/* *WindowsSChannelcomparestheclient_versioninsidetheRSA *EncryptedPreMasterSecretofarenegotiationwiththe *client_versionoftheinitialClientHelloratherthanthe *ClientHellointherenegotiation.Toworkaroundthisbug,we *continuetousetheclient_versionusedintheinitial *ClientHellowhenrenegotiating.
*/ 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, *onlyifTLSisdisabled.
*/ if (!ss->firstHsDone && !isTLS) { /* Must set this before calling Hello Extension Senders, *tosuppresssendingofemptyRIextension.
*/
ss->ssl3.hs.sendingSCSV = PR_TRUE;
}
/* When we attempt session resumption (only), we must lock the sid to *preventraceswithotherresumptionconnectionsthatreceivea *NewSessionTicketthatwillcausetheticketinthesidtobereplaced. *Oncewe'vecopiedthesessionticketintoourClientHellomessage,it *isOKforthetickettochange,sowejustneedtomakesurewehold *thelockacrossthecallstossl_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. *Thisemptiesthebuffer.Thisisaconvenientplacetocall
* 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, *ForDTLS1.3,weskiphashingtheunnecessaryheaderfields.
* 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 *completessl3HelloRequest. *CallermustholdHandshakeandRecvBuflocks.
*/ static SECStatus
ssl3_HandleHelloRequest(sslSocket *ss)
{
sslSessionID *sid = ss->sec.ci.sid;
SECStatus rv;
static SECStatus
ssl_FindIndexByWrapMechanism(CK_MECHANISM_TYPE mech, unsignedint *wrapMechIndex)
{ unsignedint 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 *pointersforthesymmetricwrappingkeysthatareusedtowrapthemaster *secrets.Thereisonekeyforeachauthenticationtype.TheseSymkeys *correspondtothewrappedSymKeyskeptintheserversessioncache.
*/ 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, unsignedint *wrapKeyIndex)
{ unsignedint 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;
}
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;
}
}
}
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'sambiguous.
*/
unwrappedWrappingKey = PK11_KeyGen(masterSecretSlot, masterWrapMech, NULL,
length, pwArg); if (!unwrappedWrappingKey) { goto loser;
}
/* Prepare the buffer to receive the wrappedWrappingKey, *thesymmetricwrappingkeywrappedusingtheserver'spubkey.
*/
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: /* *WegenerateanephemeralECkeypair.PerformanECDH *computationinvolvingthisephemeralECpublickeyand *theSSLserver's(long-term)ECprivatekey.Theresulting *sharedsecretistreatedinthesamewayasFortezza'sKs, *i.e.,itisusedtowrapthewrappingkey.Tofacilitate *unwrappinginssl_UnwrapWrappingKey,wealsostoreall *relevantinfoabouttheephemeralECpublickeyin *wswk.wrappedSymmetricWrappingkeyandlayitoutas *describedintheECCWrappedKeyInfostructure.
*/
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.wrappedSymmetricWrappingkeyattheappropriateoffset
*/
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.Mostofthisisdeterminedbythekeypairweareusing. *PriortoTLS1.2,theMD5/SHA1combinationisalwaysused.WithTLS1.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 *itmaybeunabletosignSHA-256hashes.Thisisthecaseforolder *EstonianIDcardsthathave1024-bitRSAkeys.InFIPS186-2and *older,DSAkeysizeisatmost1024bitsandthehashfunctionmust *beSHA-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,whendoinganSSLrestarthandshake,verifythis. **Thesecallsaremereaccessors,andcan'tfail.
*/
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)
{ unsignedint 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 *acceptablefortheversion,butthecheckisrepeatedhere
* 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,dependingonwhetherwe'reincompatmodeandwhetherwe *negotiatedTLS1.3+orTLS1.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;
}
/* 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. *DTLSHandshakeMessageFormatstatesthedifferencebetweenthecomputation *ofthetranscriptiftheversionisDTLS1.2orDTLS1.3. * *Atthismomentwearesurewhichversion
* 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 *TLS1.3. * *1.WereceivedHRR *2.Wesentearlyappdata *3.ECHwasaccepted(checkedinMaybeHandleEchSignal) * *IfweofferedECHandtheservernegotiatedalowerversion, *authenticatetothepublicnameforsecuredisablement. *
*/ 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 *inthefirsthandshake.Thisisn'treallythebestplacefor *ustobegettingthisversionnumber,butit'swhatwehave.
* (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,becausecwSpecmightbea0-RTTcipherspec,
* 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 *notandifsoitmaymatchtheonewesent. *Attempttorestorethemastersecrettoseeifthisisso... *Don'tconsiderfailuretofindamatchingSIDanerror.
*/
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;
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 *mustbeephemeral.Note,ifweeveraddPSKthismight
* 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;
/* Called from ssl3_HandlePostHelloHandshakeMessage() when it has deciphered a *completessl3ServerKeyExchangemessage. *CallermustholdHandshakeandRecvBuflocks.
*/ static SECStatus
ssl3_HandleServerKeyExchange(sslSocket *ss, PRUint8 *b, PRUint32 length)
{
SECStatus rv;
staticvoid
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_HandleServerHelloDonetocallSendCertificate.
*/
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 *ifanRSA-PSScertwasselected,butthetoken *doesnotsupportPSSschemes.
*/ 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;
} elseif (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); /* *Peersignaturesareonlyavailablewhileinthecontextof *ofagetClientAuthDatacallback.Itisrequiredforproper *functioningofSSL_CertIsUsableandSSL_FilterClientCertListBySocket *CallingthesefunctionsoutsidethecontextofagetClientAuthData
* callback will result in no filtering.*/
/* Continue the handshake */ if (!ss->ssl3.hs.restartTarget) { /* The client cert callback completed before the server Finished *messagewasfullyreceived.Thiscanhappenonanon-blocking *socketwhenEAGAINinterruptstherecord-headerreadpartway *through(e.g.whentheFinishedrecordheaderstraddlesaTCP *segmentboundary).Thepartialgatherstateispreservedin *ss->gsandwillberesumedbythenextSSL_ForceHandshake/ *PR_Readcall.tls13_SendClientSecondRoundwillrunafterthe *FinishedisprocessedandwillfindclientCertificatePending
* 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 *doFalseStartinthecasethattheselectedciphersuiteis *sufficientlystrongthattheattackcangainnoadvantage.
* 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 *acompletessl3ServerHelloDonemessage. *CallermustholdHandshakeandRecvBuflocks.
*/ static SECStatus
ssl3_HandleServerHelloDone(sslSocket *ss)
{
SECStatus rv;
SSL3WaitState ws = ss->ssl3.hs.ws;
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. */
}
} elseif (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_SendChangeCipherSpecsbecauseSSL_GetChannelInfousesinformation *fromcwSpec.Thismustbedonebeforewecallssl3_CheckFalseStart *becausethefalsestartcallback(ifany)mayneedtheinformationfrom *thefunctionsthatdependonthisbeingset.
*/
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 *falsestartingbeforewetrytoflushtheclientsecond *roundtothenetwork.Withthatinmind,wepurposefully *callssl3_CheckFalseStartbeforecallingssl3_SendFinished, *whichincludesacalltossl3_FlushHandshake,sothat *noapplicationdevelopsarelianceonsuchflushingbeing *donebeforeitsfalsestartcallbackiscalled.
*/
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 ((unsignedint)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((unsignedint)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)) { unsignedint 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, **buttheydoremembertheslotweoriginallyused,sowe **canlocateitagain,providedthatthecurrentsslsocket **hashaditsservercertsconfiguredthesameasthepreviousone.
*/
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 *mightnotbethesamecertificate,butweonlyfindthatout
* when the ticket fails to decrypt. */ break;
}
/* [draft-ietf-tls-session-hash-06; Section 5.3] *oIftheoriginalsessiondidnotusethe"extended_master_secret" *extensionbutthenewClientHellocontainstheextension,thenthe *serverMUSTNOTperformtheabbreviatedhandshake.Instead,it *SHOULDcontinuewithafullhandshake(asdescribedin *Section5.2)tonegotiateanewsession. * *oIftheoriginalsessionusedthe"extended_master_secret" *extensionbutthenewClientHellodoesnotcontaintheextension, *theserverMUSTaborttheabbreviatedhandshake.
*/ 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 */
}
/* 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 *theextensionandweareunabletoresume. * *TODO:sendasessionticketifperformingastateful *resumption.(AsperRFC4507,aservermayissueasession *ticketwhiledoinga(statelessorstateful)sessionresume, *butOpenSSL-0.9.8gdoesnotacceptsessionticketswhile *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;
}
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 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 *extensionbyprocessingalocalcopyofanemptyRIextension.
*/ 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. ** **Calledfrom:ssl3_HandleClientHello(resumingsession), **ssl3_SendServerHelloSequence<-ssl3_HandleClientHello(newsession), **ssl3_SendServerHelloSequence<-ssl3_HandleV2ClientHello(newsession)
*/
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;
}
if (slot == NULL) {
SSLCipherAlgorithm calg; /* The specReadLock would suffice here, but we cannot assert on **readlocks.Also,allthecallerswhocallwithanon-null **slotalreadyholdtheSpecWriteLock.
*/
PORT_Assert(ss->opt.noLocks || ssl_HaveSpecWriteLock(ss));
PORT_Assert(ss->ssl3.prSpec->epoch == ss->ssl3.pwSpec->epoch);
calg = spec->cipherDef->calg;
/* First get an appropriate slot. */
mechanism_array[0] = CKM_SSL3_PRE_MASTER_KEY_GEN;
mechanism_array[1] = CKM_RSA_PKCS;
mechanism_array[2] = ssl3_Alg2Mech(calg);
slot = PK11_GetBestSlotMultiple(mechanism_array, 3, pwArg); if (slot == NULL) { /* can't find a slot with all three, find a slot with the minimum */
slot = PK11_GetBestSlotMultiple(mechanism_array, 2, pwArg); if (slot == NULL) {
PORT_SetError(SSL_ERROR_TOKEN_SLOT_NOT_FOUND); return pms; /* which is NULL */
}
}
}
/* Generate the pre-master secret ... */ if (IS_DTLS(ss)) {
SSL3ProtocolVersion temp;
if (fauxPms == NULL) {
ssl_MapLowLevelError(SSL_ERROR_CLIENT_KEY_EXCHANGE_FAILURE); return SECFailure;
}
/* *unwrappmsoutoftheincomingbuffer *Note:CKM_SSL3_MASTER_KEY_DERIVEisNOTthemechanismusedtodo *theunwrap.Rather,itisthemechanismwithwhichthe *unwrappedpmswillbeused.
*/
pms = PK11_PubUnwrapSymKey(serverKeyPair->privKey, &enc_pms,
CKM_SSL3_MASTER_KEY_DERIVE, CKA_DERIVE, 0); /* Temporarily use the PMS if unwrapping the real PMS fails. */
ssl3_CSwapPK11SymKey(&pms, &fauxPms, pms == NULL);
/* Attempt to derive the MS from the PMS. This is the only way to *checktheversionfieldintheRSAPMS.Ifthisfails,we *thenusethefauxPMSinplaceofthePMS.Notethatthis *operationshouldneverfailifweareusingthefauxPMS
* since it is correctly formatted. */
rv = ssl3_ComputeMasterSecret(ss, pms, NULL);
/* If we succeeded, then select the true PMS, else select the FPMS. */
ssl3_CSwapPK11SymKey(&pms, &fauxPms, (rv != SECSuccess) & (fauxPms != NULL));
/* This step will derive the MS from the PMS, among other things. */
rv = ssl3_InitPendingCipherSpecs(ss, pms, PR_TRUE);
/* Clear both PMS. */
PK11_FreeSymKey(pms);
PK11_FreeSymKey(fauxPms);
if (rv != SECSuccess) {
(void)SSL3_SendAlert(ss, alert_fatal, handshake_failure); return SECFailure; /* error code set by ssl3_InitPendingCipherSpec */
}
if (ss->sec.localCert)
CERT_DestroyCertificate(ss->sec.localCert); if (ss->sec.isServer) { /* A server certificate is selected in ssl3_HandleClientHello. */
PORT_Assert(ss->sec.serverCert);
if (!ssl3_ExtensionNegotiated(ss, ssl_cert_status_xtn)) return SECSuccess;
/* Use certStatus based on the cert being used. */
serverCert = ss->sec.serverCert; if (serverCert->certStatusArray && serverCert->certStatusArray->len) {
statusToSend = serverCert->certStatusArray;
} if (!statusToSend) return SECSuccess;
/* Use the array's first item only (single stapling) */
len = 1 + statusToSend->items[0].len + 3;
rv = ssl3_AppendHandshakeHeader(ss, ssl_hs_certificate_status, len); if (rv != SECSuccess) { return rv; /* err set by AppendHandshake. */
}
rv = ssl3_AppendHandshakeNumber(ss, 1/*ocsp*/, 1); if (rv != SECSuccess) return rv; /* err set by AppendHandshake. */
rv = ssl3_AppendHandshakeVariable(ss,
statusToSend->items[0].data,
statusToSend->items[0].len, 3); if (rv != SECSuccess) 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;
}
}
/* wrap the master secret, and put it into the SID. *CallerholdstheSpecreadlock.
*/
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:weintentionallyignoreerrorshere.Ifwecannot *generateawrappingkey,itisnotfataltothisSSLconnection, *butwewillnotbeabletorestartthissession.
*/
mechanism = PK11_GetBestWrapMechanism(symKeySlot);
keyLength = PK11_GetBestKeyLength(symKeySlot, mechanism); /* Zero length means fixed key length algorithm, or error. *It'sambiguous.
*/
wrappingKey = PK11_KeyGen(symKeySlot, mechanism, NULL,
keyLength, pwArg); if (wrappingKey) { /* The thread safety characteristics of PK11_[SG]etWrapKey is *abominable.Thisprotectsagainstracesincalling *PK11_SetWrapKeybydroppingandre-acquiringthecanonical *valueonceitisset.ThemutexinPK11_[SG]etWrapKeywill
* 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. */
}
}
}
/* Send a NewSessionTicket message if the client sent us *eitheranemptysessionticket,oronethatdidnotverify. *(Notethatifeitheroftheseconditionswasmet,thenthe *serverhassentaSessionTicketextensioninthe *ServerHellomessage.)
*/ 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 *serverMUSTverifytheclient'sFinishedmessagebeforesending *theticket."Presumably,thisalsomeansthattheclient's *certificate,ifany,mustbeverifiedbeforehandtoo.
*/
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) **thensetthessl_SEND_FLAG_FORCE_INTO_BUFFERflag,sothatthe **lasttwohandshakemessages(changecipherspecandfinished) **willbesentinthesamesend/writecallastheapplicationdata.
*/ 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 *tohavetypesslRestartTarget.
*/
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 *untilithasverifiedtheserver'sFinishedmessage."Whentheserver *sendsaNewSessionTicketinaresumptionhandshake,wemustwaituntil *thehandshakeisfinished(wehaveverifiedtheserver'sFinished *ANDtheserver'scertificate)beforeweupdatetheticketinthesid. * *Thismustbedonebeforewecallssl_CacheSessionID(ss) *becauseCacheSIDrequiresthesessiontickettoalreadybeset,andalso *becauseofthelazylockcreationschemeusedbyCacheSIDand
* 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 *handshakemessage. *CallermustholdHandshakeandRecvBuflocks.
*/
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 *certificatevalidationuntilwegettheCertificateStatusmesssage. *ButtheCertificateStatusmessageisoptional.Iftheserverdid *notsenditthenweneedtovalidatethecertificatenow.Ifthe *serverdoessendtheCertificateStatusmessagethenwewill *authenticatethecertificateinssl3_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 *WhoeversetWOULD_BLOCKmusthandleanyremainingactionsrequiredtofinsihprocessingtherecord. *e.g.bysettingrestartTarget.
*/ 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->ssl3.signatureSchemeCount = 0; for (i = 0; i < count; ++i) { if (!ssl_IsSupportedSignatureScheme(schemes[i])) {
SSL_DBG(("%d: SSL[%d]: invalid signature scheme %d ignored",
SSL_GETPID(), fd, schemes[i])); continue;
}
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.