248 lines
12 KiB
Diff
248 lines
12 KiB
Diff
diff --git a/netwerk/protocol/http/WebTransportCertificateVerifier.cpp b/netwerk/protocol/http/WebTransportCertificateVerifier.cpp
|
|
index cc778640a1..298d6a61e8 100644
|
|
--- a/netwerk/protocol/http/WebTransportCertificateVerifier.cpp
|
|
+++ b/netwerk/protocol/http/WebTransportCertificateVerifier.cpp
|
|
@@ -53,6 +53,10 @@ class ServerCertHashesTrustDomain : public mozilla::pkix::TrustDomain {
|
|
mozilla::pkix::Input signature,
|
|
mozilla::pkix::Input subjectPublicKeyInfo) override;
|
|
|
|
+ virtual mozilla::pkix::Result VerifyMLDSASignedData(
|
|
+ mozilla::pkix::Input data, mozilla::pkix::Input signature,
|
|
+ mozilla::pkix::Input subjectPublicKeyInfo) override;
|
|
+
|
|
virtual mozilla::pkix::Result DigestBuf(
|
|
mozilla::pkix::Input item, mozilla::pkix::DigestAlgorithm digestAlg,
|
|
/*out*/ uint8_t* digestBuf, size_t digestBufLen) override;
|
|
@@ -151,6 +155,14 @@ mozilla::pkix::Result ServerCertHashesTrustDomain::VerifyECDSASignedData(
|
|
return mozilla::pkix::Result::FATAL_ERROR_LIBRARY_FAILURE;
|
|
}
|
|
|
|
+mozilla::pkix::Result ServerCertHashesTrustDomain::VerifyMLDSASignedData(
|
|
+ mozilla::pkix::Input data, mozilla::pkix::Input signature,
|
|
+ mozilla::pkix::Input subjectPublicKeyInfo) {
|
|
+ MOZ_ASSERT_UNREACHABLE("not expecting this to be called");
|
|
+
|
|
+ return mozilla::pkix::Result::FATAL_ERROR_LIBRARY_FAILURE;
|
|
+}
|
|
+
|
|
mozilla::pkix::Result ServerCertHashesTrustDomain::DigestBuf(
|
|
mozilla::pkix::Input item, mozilla::pkix::DigestAlgorithm digestAlg,
|
|
/*out*/ uint8_t* digestBuf, size_t digestBufLen) {
|
|
diff --git a/security/certverifier/CertVerifier.cpp b/security/certverifier/CertVerifier.cpp
|
|
index ca330770fb..1e8f1d4996 100644
|
|
--- a/security/certverifier/CertVerifier.cpp
|
|
+++ b/security/certverifier/CertVerifier.cpp
|
|
@@ -7,6 +7,7 @@
|
|
#include "CertVerifier.h"
|
|
|
|
#include <stdint.h>
|
|
+#include <optional>
|
|
|
|
#include "AppTrustDomain.h"
|
|
#include "CTKnownLogs.h"
|
|
@@ -1010,7 +1011,7 @@ Result CertVerifier::VerifySSLServerCert(
|
|
void HashSignatureParams(pkix::Input data, pkix::Input signature,
|
|
pkix::Input subjectPublicKeyInfo,
|
|
pkix::der::PublicKeyAlgorithm publicKeyAlgorithm,
|
|
- pkix::DigestAlgorithm digestAlgorithm,
|
|
+ std::optional<pkix::DigestAlgorithm> digestAlgorithm,
|
|
/*out*/ Maybe<nsTArray<uint8_t>>& sha512Hash) {
|
|
sha512Hash.reset();
|
|
Digest digest;
|
|
@@ -1048,10 +1049,14 @@ void HashSignatureParams(pkix::Input data, pkix::Input signature,
|
|
sizeof(publicKeyAlgorithm)))) {
|
|
return;
|
|
}
|
|
- if (NS_FAILED(
|
|
- digest.Update(reinterpret_cast<const uint8_t*>(&digestAlgorithm),
|
|
- sizeof(digestAlgorithm)))) {
|
|
- return;
|
|
+ // There is no fallback digest algorithm when it's empty.
|
|
+ // Check that digestAlgorithm actually contains a value.
|
|
+ if (digestAlgorithm) {
|
|
+ pkix::DigestAlgorithm value = digestAlgorithm.value();
|
|
+ if (NS_FAILED(digest.Update(reinterpret_cast<const uint8_t*>(&value),
|
|
+ sizeof(value)))) {
|
|
+ return;
|
|
+ }
|
|
}
|
|
nsTArray<uint8_t> result;
|
|
if (NS_FAILED(digest.End(result))) {
|
|
@@ -1064,10 +1069,17 @@ Result VerifySignedDataWithCache(
|
|
der::PublicKeyAlgorithm publicKeyAlg,
|
|
mozilla::glean::impl::DenominatorMetric telemetryDenominator,
|
|
mozilla::glean::impl::NumeratorMetric telemetryNumerator, Input data,
|
|
- DigestAlgorithm digestAlgorithm, Input signature,
|
|
+ std::optional<DigestAlgorithm> digestAlgorithm, Input signature,
|
|
Input subjectPublicKeyInfo, SignatureCache* signatureCache, void* pinArg) {
|
|
telemetryDenominator.Add(1);
|
|
Maybe<nsTArray<uint8_t>> sha512Hash;
|
|
+
|
|
+ // Currently, it is only acceptable for `digestAlgorithm` to be null when the
|
|
+ // public key algorithm is pure ML-DSA. Fail immediately otherwise.
|
|
+ if ((publicKeyAlg != der::PublicKeyAlgorithm::MLDSA) && !digestAlgorithm) {
|
|
+ return Result::ERROR_INVALID_ALGORITHM;
|
|
+ }
|
|
+
|
|
HashSignatureParams(data, signature, subjectPublicKeyInfo, publicKeyAlg,
|
|
digestAlgorithm, sha512Hash);
|
|
// If hashing the signature parameters succeeded, see if this signature is in
|
|
@@ -1080,16 +1092,23 @@ Result VerifySignedDataWithCache(
|
|
Result result;
|
|
switch (publicKeyAlg) {
|
|
case der::PublicKeyAlgorithm::ECDSA:
|
|
- result = VerifyECDSASignedDataNSS(data, digestAlgorithm, signature,
|
|
- subjectPublicKeyInfo, pinArg);
|
|
+ result =
|
|
+ VerifyECDSASignedDataNSS(data, digestAlgorithm.value(), signature,
|
|
+ subjectPublicKeyInfo, pinArg);
|
|
break;
|
|
case der::PublicKeyAlgorithm::RSA_PKCS1:
|
|
- result = VerifyRSAPKCS1SignedDataNSS(data, digestAlgorithm, signature,
|
|
- subjectPublicKeyInfo, pinArg);
|
|
+ result =
|
|
+ VerifyRSAPKCS1SignedDataNSS(data, digestAlgorithm.value(), signature,
|
|
+ subjectPublicKeyInfo, pinArg);
|
|
break;
|
|
case der::PublicKeyAlgorithm::RSA_PSS:
|
|
- result = VerifyRSAPSSSignedDataNSS(data, digestAlgorithm, signature,
|
|
- subjectPublicKeyInfo, pinArg);
|
|
+ result =
|
|
+ VerifyRSAPSSSignedDataNSS(data, digestAlgorithm.value(), signature,
|
|
+ subjectPublicKeyInfo, pinArg);
|
|
+ break;
|
|
+ case der::PublicKeyAlgorithm::MLDSA:
|
|
+ result = VerifyMLDSASignedDataNSS(data, signature, subjectPublicKeyInfo,
|
|
+ pinArg);
|
|
break;
|
|
default:
|
|
MOZ_ASSERT_UNREACHABLE("unhandled public key algorithm");
|
|
diff --git a/security/certverifier/CertVerifier.h b/security/certverifier/CertVerifier.h
|
|
index 6432547c8a..6e09e6fcdd 100644
|
|
--- a/security/certverifier/CertVerifier.h
|
|
+++ b/security/certverifier/CertVerifier.h
|
|
@@ -331,7 +331,8 @@ mozilla::pkix::Result VerifySignedDataWithCache(
|
|
mozilla::pkix::der::PublicKeyAlgorithm publicKeyAlg,
|
|
mozilla::glean::impl::DenominatorMetric telemetryDenominator,
|
|
mozilla::glean::impl::NumeratorMetric telemetryNumerator,
|
|
- mozilla::pkix::Input data, mozilla::pkix::DigestAlgorithm digestAlgorithm,
|
|
+ mozilla::pkix::Input data,
|
|
+ std::optional<mozilla::pkix::DigestAlgorithm> digestAlgorithm,
|
|
mozilla::pkix::Input signature, mozilla::pkix::Input subjectPublicKeyInfo,
|
|
SignatureCache* signatureCache, void* pinArg);
|
|
|
|
diff --git a/security/certverifier/NSSCertDBTrustDomain.cpp b/security/certverifier/NSSCertDBTrustDomain.cpp
|
|
index 70ba17d70f..a3ace3cee7 100644
|
|
--- a/security/certverifier/NSSCertDBTrustDomain.cpp
|
|
+++ b/security/certverifier/NSSCertDBTrustDomain.cpp
|
|
@@ -1541,6 +1541,15 @@ Result NSSCertDBTrustDomain::VerifyECDSASignedData(
|
|
signature, subjectPublicKeyInfo, mSignatureCache, mPinArg);
|
|
}
|
|
|
|
+Result NSSCertDBTrustDomain::VerifyMLDSASignedData(Input data, Input signature,
|
|
+ Input subjectPublicKeyInfo) {
|
|
+ return VerifySignedDataWithCache(
|
|
+ der::PublicKeyAlgorithm::MLDSA,
|
|
+ mozilla::glean::cert_signature_cache::total,
|
|
+ mozilla::glean::cert_signature_cache::hits, data, std::nullopt, signature,
|
|
+ subjectPublicKeyInfo, mSignatureCache, mPinArg);
|
|
+}
|
|
+
|
|
Result NSSCertDBTrustDomain::CheckValidityIsAcceptable(
|
|
Time notBefore, Time notAfter, EndEntityOrCA endEntityOrCA,
|
|
KeyPurposeId keyPurpose) {
|
|
diff --git a/security/certverifier/NSSCertDBTrustDomain.h b/security/certverifier/NSSCertDBTrustDomain.h
|
|
index fc210f3254..6178201758 100644
|
|
--- a/security/certverifier/NSSCertDBTrustDomain.h
|
|
+++ b/security/certverifier/NSSCertDBTrustDomain.h
|
|
@@ -197,6 +197,10 @@ class NSSCertDBTrustDomain : public mozilla::pkix::TrustDomain {
|
|
mozilla::pkix::Input signature,
|
|
mozilla::pkix::Input subjectPublicKeyInfo) override;
|
|
|
|
+ virtual Result VerifyMLDSASignedData(
|
|
+ mozilla::pkix::Input data, mozilla::pkix::Input signature,
|
|
+ mozilla::pkix::Input subjectPublicKeyInfo) override;
|
|
+
|
|
virtual Result DigestBuf(mozilla::pkix::Input item,
|
|
mozilla::pkix::DigestAlgorithm digestAlg,
|
|
/*out*/ uint8_t* digestBuf,
|
|
diff --git a/security/ct/CTLogVerifier.cpp b/security/ct/CTLogVerifier.cpp
|
|
index d5e665aaca..471213745d 100644
|
|
--- a/security/ct/CTLogVerifier.cpp
|
|
+++ b/security/ct/CTLogVerifier.cpp
|
|
@@ -99,6 +99,10 @@ class SignatureParamsTrustDomain final : public TrustDomain {
|
|
return pkix::Result::FATAL_ERROR_LIBRARY_FAILURE;
|
|
}
|
|
|
|
+ pkix::Result VerifyMLDSASignedData(Input, Input, Input) override {
|
|
+ return pkix::Result::FATAL_ERROR_LIBRARY_FAILURE;
|
|
+ }
|
|
+
|
|
pkix::Result CheckValidityIsAcceptable(Time, Time, EndEntityOrCA,
|
|
KeyPurposeId) override {
|
|
return pkix::Result::FATAL_ERROR_LIBRARY_FAILURE;
|
|
diff --git a/security/ct/tests/gtest/CTTestUtils.cpp b/security/ct/tests/gtest/CTTestUtils.cpp
|
|
index 6a25307ec3..dbec7adc91 100644
|
|
--- a/security/ct/tests/gtest/CTTestUtils.cpp
|
|
+++ b/security/ct/tests/gtest/CTTestUtils.cpp
|
|
@@ -807,6 +807,12 @@ class OCSPExtensionTrustDomain : public TrustDomain {
|
|
subjectPublicKeyInfo, nullptr);
|
|
}
|
|
|
|
+ pkix::Result VerifyMLDSASignedData(Input data, Input signature,
|
|
+ Input subjectPublicKeyInfo) override {
|
|
+ return VerifyMLDSASignedDataNSS(data, signature, subjectPublicKeyInfo,
|
|
+ nullptr);
|
|
+ }
|
|
+
|
|
pkix::Result CheckValidityIsAcceptable(Time, Time, EndEntityOrCA,
|
|
KeyPurposeId) override {
|
|
ADD_FAILURE();
|
|
diff --git a/security/manager/ssl/AppTrustDomain.cpp b/security/manager/ssl/AppTrustDomain.cpp
|
|
index ab49d7eb1f..3963f90eb1 100644
|
|
--- a/security/manager/ssl/AppTrustDomain.cpp
|
|
+++ b/security/manager/ssl/AppTrustDomain.cpp
|
|
@@ -322,6 +322,12 @@ pkix::Result AppTrustDomain::VerifyECDSASignedData(
|
|
subjectPublicKeyInfo, nullptr);
|
|
}
|
|
|
|
+pkix::Result AppTrustDomain::VerifyMLDSASignedData(Input data, Input signature,
|
|
+ Input subjectPublicKeyInfo) {
|
|
+ return VerifyMLDSASignedDataNSS(data, signature, subjectPublicKeyInfo,
|
|
+ nullptr);
|
|
+}
|
|
+
|
|
pkix::Result AppTrustDomain::CheckValidityIsAcceptable(
|
|
Time /*notBefore*/, Time /*notAfter*/, EndEntityOrCA /*endEntityOrCA*/,
|
|
KeyPurposeId /*keyPurpose*/) {
|
|
diff --git a/security/manager/ssl/AppTrustDomain.h b/security/manager/ssl/AppTrustDomain.h
|
|
index 4b0212ede0..85fdff5f13 100644
|
|
--- a/security/manager/ssl/AppTrustDomain.h
|
|
+++ b/security/manager/ssl/AppTrustDomain.h
|
|
@@ -80,6 +80,9 @@ class AppTrustDomain final : public mozilla::pkix::TrustDomain {
|
|
mozilla::pkix::DigestAlgorithm digestAlg,
|
|
/*out*/ uint8_t* digestBuf,
|
|
size_t digestBufLen) override;
|
|
+ virtual Result VerifyMLDSASignedData(
|
|
+ mozilla::pkix::Input data, mozilla::pkix::Input signature,
|
|
+ mozilla::pkix::Input subjectPublicKeyInfo) override;
|
|
|
|
private:
|
|
nsTArray<Span<const uint8_t>> mTrustedRoots;
|
|
diff --git a/security/manager/ssl/TLSClientAuthCertSelection.cpp b/security/manager/ssl/TLSClientAuthCertSelection.cpp
|
|
index 3a84b15ee6..a3dc5a1af1 100644
|
|
--- a/security/manager/ssl/TLSClientAuthCertSelection.cpp
|
|
+++ b/security/manager/ssl/TLSClientAuthCertSelection.cpp
|
|
@@ -217,6 +217,11 @@ class ClientAuthCertNonverifyingTrustDomain final : public TrustDomain {
|
|
pkix::Input subjectPublicKeyInfo) override {
|
|
return pkix::Success;
|
|
}
|
|
+ virtual mozilla::pkix::Result VerifyMLDSASignedData(
|
|
+ pkix::Input data, pkix::Input signature,
|
|
+ pkix::Input subjectPublicKeyInfo) override {
|
|
+ return pkix::Success;
|
|
+ }
|
|
virtual mozilla::pkix::Result CheckValidityIsAcceptable(
|
|
pkix::Time notBefore, pkix::Time notAfter,
|
|
pkix::EndEntityOrCA endEntityOrCA,
|