|
|
a809bb |
# HG changeset patch
|
|
|
a809bb |
# User Daiki Ueno <dueno@redhat.com>
|
|
|
a809bb |
# Date 1594360877 -7200
|
|
|
a809bb |
# Fri Jul 10 08:01:17 2020 +0200
|
|
|
a809bb |
# Node ID df1d2695e115ed9e6f7e8df6ad4d7be2c9bc77d8
|
|
|
a809bb |
# Parent de661583d46713c9b4873a904dda3a8ba4a61976
|
|
|
a809bb |
Bug 1646324, advertise rsa_pkcs1_* schemes in CH and CR for certs, r=mt
|
|
|
a809bb |
|
|
|
a809bb |
Summary:
|
|
|
a809bb |
In TLS 1.3, unless "signature_algorithms_cert" is advertised, the
|
|
|
a809bb |
"signature_algorithms" extension is used as an indication of supported
|
|
|
a809bb |
algorithms for signatures on certificates. While rsa_pkcs1_*
|
|
|
a809bb |
signatures schemes cannot be used for signing handshake messages, they
|
|
|
a809bb |
should be advertised if the peer wants to to support certificates
|
|
|
a809bb |
signed with RSA PKCS#1.
|
|
|
a809bb |
|
|
|
a809bb |
This adds a flag to ssl3_EncodeSigAlgs() and ssl3_FilterSigAlgs() to
|
|
|
a809bb |
preserve rsa_pkcs1_* schemes in the output.
|
|
|
a809bb |
|
|
|
a809bb |
Reviewers: mt
|
|
|
a809bb |
|
|
|
a809bb |
Reviewed By: mt
|
|
|
a809bb |
|
|
|
a809bb |
Bug #: 1646324
|
|
|
a809bb |
|
|
|
a809bb |
Differential Revision: https://phabricator.services.mozilla.com/D80881
|
|
|
a809bb |
|
|
|
a809bb |
diff -r de661583d467 -r df1d2695e115 gtests/ssl_gtest/ssl_auth_unittest.cc
|
|
|
a809bb |
--- a/gtests/ssl_gtest/ssl_auth_unittest.cc Thu Jul 09 22:45:27 2020 +0000
|
|
|
a809bb |
+++ b/gtests/ssl_gtest/ssl_auth_unittest.cc Fri Jul 10 08:01:17 2020 +0200
|
|
|
a809bb |
@@ -1591,6 +1591,47 @@
|
|
|
a809bb |
capture->extension());
|
|
|
a809bb |
}
|
|
|
a809bb |
|
|
|
a809bb |
+TEST_P(TlsConnectTls13, Tls13RsaPkcs1IsAdvertisedClient) {
|
|
|
a809bb |
+ EnsureTlsSetup();
|
|
|
a809bb |
+ static const SSLSignatureScheme kSchemes[] = {ssl_sig_rsa_pkcs1_sha256,
|
|
|
a809bb |
+ ssl_sig_rsa_pss_rsae_sha256};
|
|
|
a809bb |
+ client_->SetSignatureSchemes(kSchemes, PR_ARRAY_SIZE(kSchemes));
|
|
|
a809bb |
+ auto capture =
|
|
|
a809bb |
+ MakeTlsFilter<TlsExtensionCapture>(client_, ssl_signature_algorithms_xtn);
|
|
|
a809bb |
+ Connect();
|
|
|
a809bb |
+ // We should only have the one signature algorithm advertised.
|
|
|
a809bb |
+ static const uint8_t kExpectedExt[] = {0,
|
|
|
a809bb |
+ 4,
|
|
|
a809bb |
+ ssl_sig_rsa_pss_rsae_sha256 >> 8,
|
|
|
a809bb |
+ ssl_sig_rsa_pss_rsae_sha256 & 0xff,
|
|
|
a809bb |
+ ssl_sig_rsa_pkcs1_sha256 >> 8,
|
|
|
a809bb |
+ ssl_sig_rsa_pkcs1_sha256 & 0xff};
|
|
|
a809bb |
+ ASSERT_EQ(DataBuffer(kExpectedExt, sizeof(kExpectedExt)),
|
|
|
a809bb |
+ capture->extension());
|
|
|
a809bb |
+}
|
|
|
a809bb |
+
|
|
|
a809bb |
+TEST_P(TlsConnectTls13, Tls13RsaPkcs1IsAdvertisedServer) {
|
|
|
a809bb |
+ EnsureTlsSetup();
|
|
|
a809bb |
+ static const SSLSignatureScheme kSchemes[] = {ssl_sig_rsa_pkcs1_sha256,
|
|
|
a809bb |
+ ssl_sig_rsa_pss_rsae_sha256};
|
|
|
a809bb |
+ server_->SetSignatureSchemes(kSchemes, PR_ARRAY_SIZE(kSchemes));
|
|
|
a809bb |
+ auto capture = MakeTlsFilter<TlsExtensionCapture>(
|
|
|
a809bb |
+ server_, ssl_signature_algorithms_xtn, true);
|
|
|
a809bb |
+ capture->SetHandshakeTypes({kTlsHandshakeCertificateRequest});
|
|
|
a809bb |
+ capture->EnableDecryption();
|
|
|
a809bb |
+ server_->RequestClientAuth(false); // So we get a CertificateRequest.
|
|
|
a809bb |
+ Connect();
|
|
|
a809bb |
+ // We should only have the one signature algorithm advertised.
|
|
|
a809bb |
+ static const uint8_t kExpectedExt[] = {0,
|
|
|
a809bb |
+ 4,
|
|
|
a809bb |
+ ssl_sig_rsa_pss_rsae_sha256 >> 8,
|
|
|
a809bb |
+ ssl_sig_rsa_pss_rsae_sha256 & 0xff,
|
|
|
a809bb |
+ ssl_sig_rsa_pkcs1_sha256 >> 8,
|
|
|
a809bb |
+ ssl_sig_rsa_pkcs1_sha256 & 0xff};
|
|
|
a809bb |
+ ASSERT_EQ(DataBuffer(kExpectedExt, sizeof(kExpectedExt)),
|
|
|
a809bb |
+ capture->extension());
|
|
|
a809bb |
+}
|
|
|
a809bb |
+
|
|
|
a809bb |
// variant, version, certificate, auth type, signature scheme
|
|
|
a809bb |
typedef std::tuple
|
|
|
a809bb |
SSLSignatureScheme>
|
|
|
a809bb |
diff -r de661583d467 -r df1d2695e115 lib/ssl/ssl3con.c
|
|
|
a809bb |
--- a/lib/ssl/ssl3con.c Thu Jul 09 22:45:27 2020 +0000
|
|
|
a809bb |
+++ b/lib/ssl/ssl3con.c Fri Jul 10 08:01:17 2020 +0200
|
|
|
a809bb |
@@ -784,15 +784,19 @@
|
|
|
a809bb |
* Both by policy and by having a token that supports it. */
|
|
|
a809bb |
static PRBool
|
|
|
a809bb |
ssl_SignatureSchemeAccepted(PRUint16 minVersion,
|
|
|
a809bb |
- SSLSignatureScheme scheme)
|
|
|
a809bb |
+ SSLSignatureScheme scheme,
|
|
|
a809bb |
+ PRBool forCert)
|
|
|
a809bb |
{
|
|
|
a809bb |
/* Disable RSA-PSS schemes if there are no tokens to verify them. */
|
|
|
a809bb |
if (ssl_IsRsaPssSignatureScheme(scheme)) {
|
|
|
a809bb |
if (!PK11_TokenExists(auth_alg_defs[ssl_auth_rsa_pss])) {
|
|
|
a809bb |
return PR_FALSE;
|
|
|
a809bb |
}
|
|
|
a809bb |
- } else if (ssl_IsRsaPkcs1SignatureScheme(scheme)) {
|
|
|
a809bb |
- /* Disable PKCS#1 signatures if we are limited to TLS 1.3. */
|
|
|
a809bb |
+ } else if (!forCert && ssl_IsRsaPkcs1SignatureScheme(scheme)) {
|
|
|
a809bb |
+ /* Disable PKCS#1 signatures if we are limited to TLS 1.3.
|
|
|
a809bb |
+ * We still need to advertise PKCS#1 signatures in CH and CR
|
|
|
a809bb |
+ * for certificate signatures.
|
|
|
a809bb |
+ */
|
|
|
a809bb |
if (minVersion >= SSL_LIBRARY_VERSION_TLS_1_3) {
|
|
|
a809bb |
return PR_FALSE;
|
|
|
a809bb |
}
|
|
|
a809bb |
@@ -851,7 +855,8 @@
|
|
|
a809bb |
/* Ensure that there is a signature scheme that can be accepted.*/
|
|
|
a809bb |
for (unsigned int i = 0; i < ss->ssl3.signatureSchemeCount; ++i) {
|
|
|
a809bb |
if (ssl_SignatureSchemeAccepted(ss->vrange.min,
|
|
|
a809bb |
- ss->ssl3.signatureSchemes[i])) {
|
|
|
a809bb |
+ ss->ssl3.signatureSchemes[i],
|
|
|
a809bb |
+ PR_FALSE /* forCert */)) {
|
|
|
a809bb |
return SECSuccess;
|
|
|
a809bb |
}
|
|
|
a809bb |
}
|
|
|
a809bb |
@@ -880,7 +885,7 @@
|
|
|
a809bb |
PRBool acceptable = authType == schemeAuthType ||
|
|
|
a809bb |
(schemeAuthType == ssl_auth_rsa_pss &&
|
|
|
a809bb |
authType == ssl_auth_rsa_sign);
|
|
|
a809bb |
- if (acceptable && ssl_SignatureSchemeAccepted(ss->version, scheme)) {
|
|
|
a809bb |
+ if (acceptable && ssl_SignatureSchemeAccepted(ss->version, scheme, PR_FALSE /* forCert */)) {
|
|
|
a809bb |
return PR_TRUE;
|
|
|
a809bb |
}
|
|
|
a809bb |
}
|
|
|
a809bb |
@@ -9803,12 +9808,13 @@
|
|
|
a809bb |
}
|
|
|
a809bb |
|
|
|
a809bb |
SECStatus
|
|
|
a809bb |
-ssl3_EncodeSigAlgs(const sslSocket *ss, PRUint16 minVersion, sslBuffer *buf)
|
|
|
a809bb |
+ssl3_EncodeSigAlgs(const sslSocket *ss, PRUint16 minVersion, PRBool forCert,
|
|
|
a809bb |
+ sslBuffer *buf)
|
|
|
a809bb |
{
|
|
|
a809bb |
SSLSignatureScheme filtered[MAX_SIGNATURE_SCHEMES] = { 0 };
|
|
|
a809bb |
unsigned int filteredCount = 0;
|
|
|
a809bb |
|
|
|
a809bb |
- SECStatus rv = ssl3_FilterSigAlgs(ss, minVersion, PR_FALSE,
|
|
|
a809bb |
+ SECStatus rv = ssl3_FilterSigAlgs(ss, minVersion, PR_FALSE, forCert,
|
|
|
a809bb |
PR_ARRAY_SIZE(filtered),
|
|
|
a809bb |
filtered, &filteredCount);
|
|
|
a809bb |
if (rv != SECSuccess) {
|
|
|
a809bb |
@@ -9843,8 +9849,21 @@
|
|
|
a809bb |
return sslBuffer_InsertLength(buf, lengthOffset, 2);
|
|
|
a809bb |
}
|
|
|
a809bb |
|
|
|
a809bb |
+/*
|
|
|
a809bb |
+ * In TLS 1.3 we are permitted to advertise support for PKCS#1
|
|
|
a809bb |
+ * schemes. This doesn't affect the signatures in TLS itself, just
|
|
|
a809bb |
+ * those on certificates. Not advertising PKCS#1 signatures creates a
|
|
|
a809bb |
+ * serious compatibility risk as it excludes many certificate chains
|
|
|
a809bb |
+ * that include PKCS#1. Hence, forCert is used to enable advertising
|
|
|
a809bb |
+ * PKCS#1 support. Note that we include these in signature_algorithms
|
|
|
a809bb |
+ * because we don't yet support signature_algorithms_cert. TLS 1.3
|
|
|
a809bb |
+ * requires that PKCS#1 schemes are placed last in the list if they
|
|
|
a809bb |
+ * are present. This sorting can be removed once we support
|
|
|
a809bb |
+ * signature_algorithms_cert.
|
|
|
a809bb |
+ */
|
|
|
a809bb |
SECStatus
|
|
|
a809bb |
ssl3_FilterSigAlgs(const sslSocket *ss, PRUint16 minVersion, PRBool disableRsae,
|
|
|
a809bb |
+ PRBool forCert,
|
|
|
a809bb |
unsigned int maxSchemes, SSLSignatureScheme *filteredSchemes,
|
|
|
a809bb |
unsigned int *numFilteredSchemes)
|
|
|
a809bb |
{
|
|
|
a809bb |
@@ -9856,15 +9875,32 @@
|
|
|
a809bb |
}
|
|
|
a809bb |
|
|
|
a809bb |
*numFilteredSchemes = 0;
|
|
|
a809bb |
+ PRBool allowUnsortedPkcs1 = forCert && minVersion < SSL_LIBRARY_VERSION_TLS_1_3;
|
|
|
a809bb |
for (unsigned int i = 0; i < ss->ssl3.signatureSchemeCount; ++i) {
|
|
|
a809bb |
if (disableRsae && ssl_IsRsaeSignatureScheme(ss->ssl3.signatureSchemes[i])) {
|
|
|
a809bb |
continue;
|
|
|
a809bb |
}
|
|
|
a809bb |
if (ssl_SignatureSchemeAccepted(minVersion,
|
|
|
a809bb |
- ss->ssl3.signatureSchemes[i])) {
|
|
|
a809bb |
+ ss->ssl3.signatureSchemes[i],
|
|
|
a809bb |
+ allowUnsortedPkcs1)) {
|
|
|
a809bb |
filteredSchemes[(*numFilteredSchemes)++] = ss->ssl3.signatureSchemes[i];
|
|
|
a809bb |
}
|
|
|
a809bb |
}
|
|
|
a809bb |
+ if (forCert && !allowUnsortedPkcs1) {
|
|
|
a809bb |
+ for (unsigned int i = 0; i < ss->ssl3.signatureSchemeCount; ++i) {
|
|
|
a809bb |
+ if (disableRsae && ssl_IsRsaeSignatureScheme(ss->ssl3.signatureSchemes[i])) {
|
|
|
a809bb |
+ continue;
|
|
|
a809bb |
+ }
|
|
|
a809bb |
+ if (!ssl_SignatureSchemeAccepted(minVersion,
|
|
|
a809bb |
+ ss->ssl3.signatureSchemes[i],
|
|
|
a809bb |
+ PR_FALSE) &&
|
|
|
a809bb |
+ ssl_SignatureSchemeAccepted(minVersion,
|
|
|
a809bb |
+ ss->ssl3.signatureSchemes[i],
|
|
|
a809bb |
+ PR_TRUE)) {
|
|
|
a809bb |
+ filteredSchemes[(*numFilteredSchemes)++] = ss->ssl3.signatureSchemes[i];
|
|
|
a809bb |
+ }
|
|
|
a809bb |
+ }
|
|
|
a809bb |
+ }
|
|
|
a809bb |
return SECSuccess;
|
|
|
a809bb |
}
|
|
|
a809bb |
|
|
|
a809bb |
@@ -9901,7 +9937,7 @@
|
|
|
a809bb |
|
|
|
a809bb |
length = 1 + certTypesLength + 2 + calen;
|
|
|
a809bb |
if (isTLS12) {
|
|
|
a809bb |
- rv = ssl3_EncodeSigAlgs(ss, ss->version, &sigAlgsBuf);
|
|
|
a809bb |
+ rv = ssl3_EncodeSigAlgs(ss, ss->version, PR_TRUE /* forCert */, &sigAlgsBuf);
|
|
|
a809bb |
if (rv != SECSuccess) {
|
|
|
a809bb |
return rv;
|
|
|
a809bb |
}
|
|
|
a809bb |
diff -r de661583d467 -r df1d2695e115 lib/ssl/ssl3exthandle.c
|
|
|
a809bb |
--- a/lib/ssl/ssl3exthandle.c Thu Jul 09 22:45:27 2020 +0000
|
|
|
a809bb |
+++ b/lib/ssl/ssl3exthandle.c Fri Jul 10 08:01:17 2020 +0200
|
|
|
a809bb |
@@ -1652,7 +1652,7 @@
|
|
|
a809bb |
minVersion = ss->vrange.min; /* ClientHello */
|
|
|
a809bb |
}
|
|
|
a809bb |
|
|
|
a809bb |
- SECStatus rv = ssl3_EncodeSigAlgs(ss, minVersion, buf);
|
|
|
a809bb |
+ SECStatus rv = ssl3_EncodeSigAlgs(ss, minVersion, PR_TRUE /* forCert */, buf);
|
|
|
a809bb |
if (rv != SECSuccess) {
|
|
|
a809bb |
return SECFailure;
|
|
|
a809bb |
}
|
|
|
a809bb |
diff -r de661583d467 -r df1d2695e115 lib/ssl/sslimpl.h
|
|
|
a809bb |
--- a/lib/ssl/sslimpl.h Thu Jul 09 22:45:27 2020 +0000
|
|
|
a809bb |
+++ b/lib/ssl/sslimpl.h Fri Jul 10 08:01:17 2020 +0200
|
|
|
a809bb |
@@ -1688,12 +1688,12 @@
|
|
|
a809bb |
SECStatus ssl3_AuthCertificate(sslSocket *ss);
|
|
|
a809bb |
SECStatus ssl_ReadCertificateStatus(sslSocket *ss, PRUint8 *b,
|
|
|
a809bb |
PRUint32 length);
|
|
|
a809bb |
-SECStatus ssl3_EncodeSigAlgs(const sslSocket *ss, PRUint16 minVersion,
|
|
|
a809bb |
+SECStatus ssl3_EncodeSigAlgs(const sslSocket *ss, PRUint16 minVersion, PRBool forCert,
|
|
|
a809bb |
sslBuffer *buf);
|
|
|
a809bb |
SECStatus ssl3_EncodeFilteredSigAlgs(const sslSocket *ss,
|
|
|
a809bb |
const SSLSignatureScheme *schemes,
|
|
|
a809bb |
PRUint32 numSchemes, sslBuffer *buf);
|
|
|
a809bb |
-SECStatus ssl3_FilterSigAlgs(const sslSocket *ss, PRUint16 minVersion, PRBool disableRsae,
|
|
|
a809bb |
+SECStatus ssl3_FilterSigAlgs(const sslSocket *ss, PRUint16 minVersion, PRBool disableRsae, PRBool forCert,
|
|
|
a809bb |
unsigned int maxSchemes, SSLSignatureScheme *filteredSchemes,
|
|
|
a809bb |
unsigned int *numFilteredSchemes);
|
|
|
a809bb |
SECStatus ssl_GetCertificateRequestCAs(const sslSocket *ss,
|
|
|
a809bb |
diff -r de661583d467 -r df1d2695e115 lib/ssl/tls13exthandle.c
|
|
|
a809bb |
--- a/lib/ssl/tls13exthandle.c Thu Jul 09 22:45:27 2020 +0000
|
|
|
a809bb |
+++ b/lib/ssl/tls13exthandle.c Fri Jul 10 08:01:17 2020 +0200
|
|
|
a809bb |
@@ -1519,7 +1519,8 @@
|
|
|
a809bb |
SSLSignatureScheme filtered[MAX_SIGNATURE_SCHEMES] = { 0 };
|
|
|
a809bb |
unsigned int filteredCount = 0;
|
|
|
a809bb |
SECStatus rv = ssl3_FilterSigAlgs(ss, ss->vrange.max,
|
|
|
a809bb |
- PR_TRUE,
|
|
|
a809bb |
+ PR_TRUE /* disableRsae */,
|
|
|
a809bb |
+ PR_FALSE /* forCert */,
|
|
|
a809bb |
MAX_SIGNATURE_SCHEMES,
|
|
|
a809bb |
filtered,
|
|
|
a809bb |
&filteredCount);
|