/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* * SSL3 Protocol * * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
/* TODO(ekr): Implement HelloVerifyRequest on server side. OK for now. */
/* This list of SSL3 cipher suites is sorted in descending order of * precedence (desirability). It only includes cipher suites we implement. * This table is modified by SSL3_SetPolicy(). The ordering of cipher suites * in this table must match the ordering in SSL_ImplementedCiphers (sslenum.c) * * Important: See bug 946147 before enabling, reordering, or adding any cipher * suites to this list.
*/ /* clang-format off */ static ssl3CipherSuiteCfg cipherSuites[ssl_V3_SUITES_IMPLEMENTED] = { /* cipher_suite policy enabled isPresent */ /* Special TLS 1.3 suites. */
{ TLS_AES_128_GCM_SHA256, SSL_ALLOWED, PR_TRUE, PR_FALSE },
{ TLS_CHACHA20_POLY1305_SHA256, SSL_ALLOWED, PR_TRUE, PR_FALSE },
{ TLS_AES_256_GCM_SHA384, SSL_ALLOWED, PR_TRUE, PR_FALSE },
/* This is the default supported set of signature schemes. The order of the * hashes here is all that is important, since that will (sometimes) determine * which hash we use. The key pair (i.e., cert) is the primary thing that * determines what we use and this doesn't affect how we select key pairs. The * order of signature types is based on the same rules for ordering we use for * cipher suites just for consistency.
*/ 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 * information are laid out within wrappedSymmetricWrappingkey * for ECDH key exchange. Since wrappedSymmetricWrappingkey is * a 512-byte buffer (see sslimpl.h), the variable length field * in ECCWrappedKeyInfo can be at most (512 - 8) = 504 bytes. * * XXX For now, NSS only supports named elliptic curves of size 571 bits * or smaller. The public value will fit within 145 bytes and EC params * will fit within 12 bytes. We'll need to revisit this when NSS * supports arbitrary curves.
*/ #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;
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 * must have included an FFDHE group. 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. We don't require named groups. * 2. The peer doesn't support named groups. * 3. This isn't TLS 1.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 * are enabled. Only if this isn't TLS 1.3 and named groups
* 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, so this will essentially do nothing (unless we implement * curve configuration). However, once we have seen the * supported_groups extension and this is called from config_match(), * this will filter out certificates with an unsupported curve. * * If we might negotiate TLS 1.3, skip this test as group configuration * doesn't affect choices in TLS 1.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 * failures later when our actual signatures are rejected by
* 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 * actually implement pss signatures when we sign, so just use RSA_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. * We still need to advertise PKCS#1 signatures in CH and CR * for certificate signatures.
*/ 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 * scheme for which we have a usable certificate. * * Note: Certificates for earlier TLS versions are checked along with the
* 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;
}
/* Initialize the suite->isPresent value for config_match * Returns count of enabled ciphers supported by extant tokens, * regardless of policy or user preference. * If this returns zero, the user cannot do SSL v3.
*/ unsignedint
ssl3_config_match_init(sslSocket *ss)
{
ssl3CipherSuiteCfg *suite; const ssl3CipherSuiteDef *cipher_def;
SSLCipherAlgorithm cipher_alg;
CK_MECHANISM_TYPE cipher_mech;
SSLAuthType authType;
SSLKEAType keaType; unsignedint i; unsignedint numPresent = 0; unsignedint numEnabled = 0;
PORT_Assert(ss); if (!ss) {
PORT_SetError(SEC_ERROR_INVALID_ARGS); return 0;
} if (SSL_ALL_VERSIONS_DISABLED(&ss->vrange)) { return 0;
} 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); return 0;
} if (ssl_CheckSignatureSchemes(ss) != SECSuccess) { return 0; /* 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 * this cipher. It isn't part of the static definition.
*/
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, has a certificate (as needed), has a viable key agreement method, 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 * the PSK. We advertise non-PSK-compatible suites in the CH, as we could * fallback to certificate auth. The client handler will check hash
* 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 * highest enabled SSL version or fail when peerVersion is greater than the * highest enabled version. * * If allowLargerPeerVersion is true, peerVersion is the peer's highest * enabled version rather than the peer's selected version.
*/
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);
PRINT_BUF(60, (NULL, "check signed hashes", buf->data, buf->len));
hashAlg = ssl3_HashTypeToOID(hash->hashAlg); switch (SECKEY_GetPublicKeyType(key)) { case rsaKey:
encAlg = SEC_OID_PKCS1_RSA_ENCRYPTION;
hashItem.data = hash->u.raw;
hashItem.len = hash->len; if (scheme == ssl_sig_none) {
scheme = ssl_sig_rsa_pkcs1_sha1md5;
} break; case dsaKey:
encAlg = SEC_OID_ANSIX9_DSA_SIGNATURE; /* 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;
} /* Allow DER encoded DSA signatures in SSL 3.0 */ if (ss->ssl3.prSpec->version > SSL_LIBRARY_VERSION_3_0 ||
buf->len != SECKEY_SignatureLen(key)) {
signature = DSAU_DecodeDerSigToLen(buf, SECKEY_SignatureLen(key)); if (!signature) {
PORT_SetError(SSL_ERROR_BAD_HANDSHAKE_HASH_VALUE); goto loser;
}
buf = signature;
} if (scheme == ssl_sig_none) {
scheme = ssl_sig_dsa_sha1;
} break;
case ecKey:
encAlg = SEC_OID_ANSIX962_EC_PUBLIC_KEY; /* ssl_hash_none is used to specify the MD5/SHA1 concatenated hash. * In that case, we use just the SHA1 part. * ECDSA signatures always encode the integers r and s using ASN.1 * (unlike DSA where ASN.1 encoding is used with TLS but not with * SSL3). So we can use VFY_VerifyDigestDirect for ECDSA.
*/ if (hash->hashAlg == ssl_hash_none) {
hashAlg = SEC_OID_SHA1;
hashItem.data = hash->u.s.sha;
hashItem.len = sizeof(hash->u.s.sha);
} else {
hashItem.data = hash->u.raw;
hashItem.len = hash->len;
} if (scheme == ssl_sig_none) {
scheme = ssl_sig_ecdsa_sha1;
} break;
PRINT_BUF(60, (NULL, "hash(es) to be verified",
hashItem.data, hashItem.len));
if (isRsaPssScheme ||
hashAlg == SEC_OID_UNKNOWN ||
SECKEY_GetPublicKeyType(key) == dsaKey) { /* VFY_VerifyDigestDirect requires DSA signatures to be DER-encoded. * DSA signatures are DER-encoded in TLS but not in SSL3 and the code * above always removes the DER encoding of DSA signatures when * present. Thus DSA signatures are always verified with PK11_Verify.
*/
CK_MECHANISM_TYPE mech = PK11_MapSignKeyType(key->keyType);
/* Caller must set hiLevel error code. */ /* Called from ssl3_ComputeDHKeyHash * which are called from ssl3_HandleServerKeyExchange. * * hashAlg: ssl_hash_none indicates the pre-1.2, MD5/SHA1 combination hash.
*/
SECStatus
ssl3_ComputeCommonKeyHash(SSLHashType hashAlg,
PRUint8 *hashBuf, unsignedint bufLen,
SSL3Hashes *hashes)
{
SECStatus rv;
SECOidTag hashOID;
PRUint32 policy;
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.