Bug 1334127 - land NSS 650e5f6cb617, r=me

This commit is contained in:
Franziskus Kiefer 2017-02-01 06:01:01 +01:00
Родитель 2000e89fcc
Коммит 9d099e6afc
11 изменённых файлов: 166 добавлений и 41 удалений

Просмотреть файл

@ -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;