зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1334127 - land NSS 650e5f6cb617, r=me
This commit is contained in:
Родитель
2000e89fcc
Коммит
9d099e6afc
|
@ -1 +1 @@
|
|||
87188da8b352
|
||||
650e5f6cb617
|
||||
|
|
|
@ -10,4 +10,3 @@
|
|||
*/
|
||||
|
||||
#error "Do not include this header file."
|
||||
|
||||
|
|
|
@ -2,14 +2,18 @@
|
|||
# This file is used by build.sh to setup sanitizers.
|
||||
|
||||
sanitizer_flags=""
|
||||
sanitizers=()
|
||||
|
||||
# This tracks what sanitizers are enabled, and their options.
|
||||
declare -A sanitizers
|
||||
# This tracks what sanitizers are enabled so they don't get enabled twice. This
|
||||
# means that doing things that enable the same sanitizer twice (such as enabling
|
||||
# both --asan and --fuzz) is order-dependent: only the first is used.
|
||||
enable_sanitizer()
|
||||
{
|
||||
local san="$1"
|
||||
[ -n "${sanitizers[$san]}" ] && return
|
||||
sanitizers[$san]="${2:-1}"
|
||||
for i in "${sanitizers[@]}"; do
|
||||
[ "$san" = "$i" ] && return
|
||||
done
|
||||
sanitizers+=("$san")
|
||||
|
||||
if [ -z "$sanitizer_flags" ]; then
|
||||
gyp_params+=(-Dno_zdefs=1)
|
||||
|
|
|
@ -161,10 +161,16 @@
|
|||
'dependencies': [
|
||||
'nssfuzz-certDN',
|
||||
'nssfuzz-hash',
|
||||
'nssfuzz-mpi',
|
||||
'nssfuzz-pkcs8',
|
||||
'nssfuzz-quickder',
|
||||
],
|
||||
'conditions': [
|
||||
['OS=="linux"', {
|
||||
'dependencies': [
|
||||
'nssfuzz-mpi',
|
||||
],
|
||||
}],
|
||||
],
|
||||
}
|
||||
],
|
||||
}
|
||||
|
|
|
@ -136,6 +136,75 @@ TEST_P(TlsConnectTls12, ClientAuthBigRsaCheckSigAlg) {
|
|||
CheckSigScheme(capture_cert_verify, 0, server_, ssl_sig_rsa_pss_sha256, 2048);
|
||||
}
|
||||
|
||||
class TlsZeroCertificateRequestSigAlgsFilter : public TlsHandshakeFilter {
|
||||
public:
|
||||
virtual PacketFilter::Action FilterHandshake(
|
||||
const TlsHandshakeFilter::HandshakeHeader& header,
|
||||
const DataBuffer& input, DataBuffer* output) {
|
||||
if (header.handshake_type() != kTlsHandshakeCertificateRequest) {
|
||||
return KEEP;
|
||||
}
|
||||
|
||||
TlsParser parser(input);
|
||||
std::cerr << "Zeroing CertReq.supported_signature_algorithms" << std::endl;
|
||||
|
||||
DataBuffer cert_types;
|
||||
if (!parser.ReadVariable(&cert_types, 1)) {
|
||||
ADD_FAILURE();
|
||||
return KEEP;
|
||||
}
|
||||
|
||||
if (!parser.SkipVariable(2)) {
|
||||
ADD_FAILURE();
|
||||
return KEEP;
|
||||
}
|
||||
|
||||
DataBuffer cas;
|
||||
if (!parser.ReadVariable(&cas, 2)) {
|
||||
ADD_FAILURE();
|
||||
return KEEP;
|
||||
}
|
||||
|
||||
size_t idx = 0;
|
||||
|
||||
// Write certificate types.
|
||||
idx = output->Write(idx, cert_types.len(), 1);
|
||||
idx = output->Write(idx, cert_types);
|
||||
|
||||
// Write zero signature algorithms.
|
||||
idx = output->Write(idx, 0U, 2);
|
||||
|
||||
// Write certificate authorities.
|
||||
idx = output->Write(idx, cas.len(), 2);
|
||||
idx = output->Write(idx, cas);
|
||||
|
||||
return CHANGE;
|
||||
}
|
||||
};
|
||||
|
||||
// Check that we fall back to SHA-1 when the server doesn't provide any
|
||||
// supported_signature_algorithms in the CertificateRequest message.
|
||||
TEST_P(TlsConnectTls12, ClientAuthNoSigAlgsFallback) {
|
||||
EnsureTlsSetup();
|
||||
auto filter = new TlsZeroCertificateRequestSigAlgsFilter();
|
||||
server_->SetPacketFilter(filter);
|
||||
auto capture_cert_verify =
|
||||
new TlsInspectorRecordHandshakeMessage(kTlsHandshakeCertificateVerify);
|
||||
client_->SetPacketFilter(capture_cert_verify);
|
||||
client_->SetupClientAuth();
|
||||
server_->RequestClientAuth(true);
|
||||
|
||||
ConnectExpectFail();
|
||||
|
||||
// We're expecting a bad signature here because we tampered with a handshake
|
||||
// message (CertReq). Previously, without the SHA-1 fallback, we would've
|
||||
// seen a malformed record alert.
|
||||
server_->CheckErrorCode(SEC_ERROR_BAD_SIGNATURE);
|
||||
client_->CheckErrorCode(SSL_ERROR_DECRYPT_ERROR_ALERT);
|
||||
|
||||
CheckSigScheme(capture_cert_verify, 0, server_, ssl_sig_rsa_pkcs1_sha1, 1024);
|
||||
}
|
||||
|
||||
static const SSLSignatureScheme SignatureSchemeEcdsaSha384[] = {
|
||||
ssl_sig_ecdsa_secp384r1_sha384};
|
||||
static const SSLSignatureScheme SignatureSchemeEcdsaSha256[] = {
|
||||
|
@ -198,7 +267,16 @@ TEST_P(TlsConnectGeneric, SignatureAlgorithmServerOnly) {
|
|||
ssl_sig_ecdsa_secp384r1_sha384);
|
||||
}
|
||||
|
||||
TEST_P(TlsConnectTls12Plus, SignatureSchemeCurveMismatch) {
|
||||
// In TLS 1.2, curve and hash aren't bound together.
|
||||
TEST_P(TlsConnectTls12, SignatureSchemeCurveMismatch) {
|
||||
Reset(TlsAgent::kServerEcdsa256);
|
||||
client_->SetSignatureSchemes(SignatureSchemeEcdsaSha384,
|
||||
PR_ARRAY_SIZE(SignatureSchemeEcdsaSha384));
|
||||
Connect();
|
||||
}
|
||||
|
||||
// In TLS 1.3, curve and hash are coupled.
|
||||
TEST_P(TlsConnectTls13, SignatureSchemeCurveMismatch) {
|
||||
Reset(TlsAgent::kServerEcdsa256);
|
||||
client_->SetSignatureSchemes(SignatureSchemeEcdsaSha384,
|
||||
PR_ARRAY_SIZE(SignatureSchemeEcdsaSha384));
|
||||
|
@ -207,7 +285,16 @@ TEST_P(TlsConnectTls12Plus, SignatureSchemeCurveMismatch) {
|
|||
client_->CheckErrorCode(SSL_ERROR_NO_CYPHER_OVERLAP);
|
||||
}
|
||||
|
||||
TEST_P(TlsConnectTls12Plus, SignatureSchemeBadConfig) {
|
||||
// Configuring a P-256 cert with only SHA-384 signatures is OK in TLS 1.2.
|
||||
TEST_P(TlsConnectTls12, SignatureSchemeBadConfig) {
|
||||
Reset(TlsAgent::kServerEcdsa256); // P-256 cert can't be used.
|
||||
server_->SetSignatureSchemes(SignatureSchemeEcdsaSha384,
|
||||
PR_ARRAY_SIZE(SignatureSchemeEcdsaSha384));
|
||||
Connect();
|
||||
}
|
||||
|
||||
// A P-256 certificate in TLS 1.3 needs a SHA-256 signature scheme.
|
||||
TEST_P(TlsConnectTls13, SignatureSchemeBadConfig) {
|
||||
Reset(TlsAgent::kServerEcdsa256); // P-256 cert can't be used.
|
||||
server_->SetSignatureSchemes(SignatureSchemeEcdsaSha384,
|
||||
PR_ARRAY_SIZE(SignatureSchemeEcdsaSha384));
|
||||
|
|
|
@ -58,7 +58,7 @@ TEST_P(TlsConnectTls12, ConnectEcdheP384) {
|
|||
Reset(TlsAgent::kServerEcdsa384);
|
||||
ConnectWithCipherSuite(TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256);
|
||||
CheckKeys(ssl_kea_ecdh, ssl_grp_ec_secp384r1, ssl_auth_ecdsa,
|
||||
ssl_sig_ecdsa_secp384r1_sha384);
|
||||
ssl_sig_ecdsa_secp256r1_sha256);
|
||||
}
|
||||
|
||||
TEST_P(TlsConnectGeneric, ConnectEcdheP384Client) {
|
||||
|
|
|
@ -30,6 +30,7 @@ const uint8_t kTlsHandshakeHelloRetryRequest = 6;
|
|||
const uint8_t kTlsHandshakeEncryptedExtensions = 8;
|
||||
const uint8_t kTlsHandshakeCertificate = 11;
|
||||
const uint8_t kTlsHandshakeServerKeyExchange = 12;
|
||||
const uint8_t kTlsHandshakeCertificateRequest = 13;
|
||||
const uint8_t kTlsHandshakeCertificateVerify = 15;
|
||||
const uint8_t kTlsHandshakeClientKeyExchange = 16;
|
||||
const uint8_t kTlsHandshakeFinished = 20;
|
||||
|
|
|
@ -356,10 +356,11 @@ SSL_IMPORT SECStatus SSL_CipherPolicyGet(PRInt32 cipher, PRInt32 *policy);
|
|||
** that is compatible with both its certificate and its peer's supported
|
||||
** values.
|
||||
**
|
||||
** NSS uses the strict signature schemes from TLS 1.3 in TLS 1.2. That means
|
||||
** that if a peer indicates support for SHA-384 and ECDSA, NSS will not
|
||||
** generate a signature if it has a P-256 key, even though that is permitted in
|
||||
** TLS 1.2.
|
||||
** This configuration affects TLS 1.2, but the combination of EC group and hash
|
||||
** algorithm is interpreted loosely to be compatible with other implementations.
|
||||
** For TLS 1.2, NSS will ignore the curve group when generating or verifying
|
||||
** ECDSA signatures. For example, a P-384 ECDSA certificate is used with
|
||||
** SHA-256 if ssl_sig_ecdsa_secp256r1_sha256 is enabled.
|
||||
**
|
||||
** Omitting SHA-256 schemes from this list might be foolish. Support is
|
||||
** mandatory in TLS 1.2 and 1.3 and there might be interoperability issues.
|
||||
|
|
|
@ -6404,7 +6404,7 @@ ssl_PickSignatureScheme(sslSocket *ss,
|
|||
PRUint32 policy;
|
||||
|
||||
if (!ssl_SignatureSchemeValidForKey(!isTLS13 /* allowSha1 */,
|
||||
PR_TRUE /* matchGroup */,
|
||||
isTLS13 /* matchGroup */,
|
||||
keyType, group, preferred)) {
|
||||
continue;
|
||||
}
|
||||
|
@ -6438,6 +6438,33 @@ ssl_PickSignatureScheme(sslSocket *ss,
|
|||
return SECFailure;
|
||||
}
|
||||
|
||||
static SECStatus
|
||||
ssl_PickFallbackSignatureScheme(sslSocket *ss, SECKEYPublicKey *pubKey)
|
||||
{
|
||||
PRBool isTLS12 = ss->version >= SSL_LIBRARY_VERSION_TLS_1_2;
|
||||
|
||||
switch (SECKEY_GetPublicKeyType(pubKey)) {
|
||||
case rsaKey:
|
||||
if (isTLS12) {
|
||||
ss->ssl3.hs.signatureScheme = ssl_sig_rsa_pkcs1_sha1;
|
||||
} else {
|
||||
ss->ssl3.hs.signatureScheme = ssl_sig_rsa_pkcs1_sha1md5;
|
||||
}
|
||||
break;
|
||||
case ecKey:
|
||||
ss->ssl3.hs.signatureScheme = ssl_sig_ecdsa_sha1;
|
||||
break;
|
||||
case dsaKey:
|
||||
ss->ssl3.hs.signatureScheme = ssl_sig_dsa_sha1;
|
||||
break;
|
||||
default:
|
||||
PORT_Assert(0);
|
||||
PORT_SetError(SEC_ERROR_INVALID_KEY);
|
||||
return SECFailure;
|
||||
}
|
||||
return SECSuccess;
|
||||
}
|
||||
|
||||
/* ssl3_PickServerSignatureScheme selects a signature scheme for signing the
|
||||
* handshake. Most of this is determined by the key pair we are using.
|
||||
* Prior to TLS 1.2, the MD5/SHA1 combination is always used. With TLS 1.2, a
|
||||
|
@ -6451,26 +6478,7 @@ ssl3_PickServerSignatureScheme(sslSocket *ss)
|
|||
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. */
|
||||
switch (SECKEY_GetPublicKeyType(keyPair->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;
|
||||
return ssl_PickFallbackSignatureScheme(ss, keyPair->pubKey);
|
||||
}
|
||||
|
||||
/* Sets error code, if needed. */
|
||||
|
@ -6488,9 +6496,21 @@ ssl_PickClientSignatureScheme(sslSocket *ss, const SSLSignatureScheme *schemes,
|
|||
SECKEYPublicKey *pubKey;
|
||||
SECStatus rv;
|
||||
|
||||
PRBool isTLS13 = (PRBool)ss->version >= SSL_LIBRARY_VERSION_TLS_1_3;
|
||||
pubKey = CERT_ExtractPublicKey(ss->ssl3.clientCertificate);
|
||||
PORT_Assert(pubKey);
|
||||
if (ss->version < SSL_LIBRARY_VERSION_TLS_1_3 &&
|
||||
|
||||
if (!isTLS13 && numSchemes == 0) {
|
||||
/* If the server didn't provide any signature algorithms
|
||||
* then let's assume they support SHA-1. */
|
||||
rv = ssl_PickFallbackSignatureScheme(ss, pubKey);
|
||||
SECKEY_DestroyPublicKey(pubKey);
|
||||
return rv;
|
||||
}
|
||||
|
||||
PORT_Assert(schemes && numSchemes > 0);
|
||||
|
||||
if (!isTLS13 &&
|
||||
(SECKEY_GetPublicKeyType(pubKey) == rsaKey ||
|
||||
SECKEY_GetPublicKeyType(pubKey) == dsaKey) &&
|
||||
SECKEY_PublicKeyStrengthInBits(pubKey) <= 1024) {
|
||||
|
@ -7404,7 +7424,7 @@ ssl_ParseSignatureSchemes(const sslSocket *ss, PLArenaPool *arena,
|
|||
{
|
||||
SECStatus rv;
|
||||
SECItem buf;
|
||||
SSLSignatureScheme *schemes;
|
||||
SSLSignatureScheme *schemes = NULL;
|
||||
unsigned int numSchemes = 0;
|
||||
unsigned int max;
|
||||
|
||||
|
@ -7412,12 +7432,17 @@ ssl_ParseSignatureSchemes(const sslSocket *ss, PLArenaPool *arena,
|
|||
if (rv != SECSuccess) {
|
||||
return SECFailure;
|
||||
}
|
||||
/* An empty or odd-length value is invalid. */
|
||||
if (buf.len == 0 || (buf.len & 1) != 0) {
|
||||
/* An odd-length value is invalid. */
|
||||
if ((buf.len & 1) != 0) {
|
||||
ssl3_ExtSendAlert(ss, alert_fatal, decode_error);
|
||||
return SECFailure;
|
||||
}
|
||||
|
||||
/* Let the caller decide whether to alert here. */
|
||||
if (buf.len == 0) {
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* Limit the number of schemes we read. */
|
||||
max = PR_MIN(buf.len / 2, MAX_SIGNATURE_SCHEMES);
|
||||
|
||||
|
@ -7451,6 +7476,7 @@ ssl_ParseSignatureSchemes(const sslSocket *ss, PLArenaPool *arena,
|
|||
schemes = NULL;
|
||||
}
|
||||
|
||||
done:
|
||||
*schemesOut = schemes;
|
||||
*numSchemesOut = numSchemes;
|
||||
return SECSuccess;
|
||||
|
|
|
@ -2045,7 +2045,8 @@ ssl3_ServerHandleSigAlgsXtn(const sslSocket *ss, TLSExtensionData *xtnData, PRUi
|
|||
&xtnData->clientSigSchemes,
|
||||
&xtnData->numClientSigScheme,
|
||||
&data->data, &data->len);
|
||||
if (rv != SECSuccess) {
|
||||
if (rv != SECSuccess || xtnData->numClientSigScheme == 0) {
|
||||
ssl3_ExtSendAlert(ss, alert_fatal, decode_error);
|
||||
PORT_SetError(SSL_ERROR_RX_MALFORMED_CLIENT_HELLO);
|
||||
return SECFailure;
|
||||
}
|
||||
|
|
|
@ -1831,7 +1831,7 @@ tls13_HandleCertificateRequest(sslSocket *ss, SSL3Opaque *b, PRUint32 length)
|
|||
&certRequest->signatureSchemes,
|
||||
&certRequest->signatureSchemeCount,
|
||||
&b, &length);
|
||||
if (rv != SECSuccess) {
|
||||
if (rv != SECSuccess || certRequest->signatureSchemeCount == 0) {
|
||||
FATAL_ERROR(ss, SSL_ERROR_RX_MALFORMED_CERT_REQUEST,
|
||||
decode_error);
|
||||
goto loser;
|
||||
|
|
Загрузка…
Ссылка в новой задаче