Add a way to make WebTransportFingerprintProofVerifier reject RSA keys. This is necessary as <https://github.com/w3c/webtransport/pull/375> will require us rejecting RSA keys for self-signed certificates. PiperOrigin-RevId: 420822901
diff --git a/quic/core/crypto/certificate_view.cc b/quic/core/crypto/certificate_view.cc index e920cdb..1286667 100644 --- a/quic/core/crypto/certificate_view.cc +++ b/quic/core/crypto/certificate_view.cc
@@ -168,6 +168,22 @@ } // namespace +std::string PublicKeyTypeToString(PublicKeyType type) { + switch (type) { + case PublicKeyType::kRsa: + return "RSA"; + case PublicKeyType::kP256: + return "ECDSA P-256"; + case PublicKeyType::kP384: + return "ECDSA P-384"; + case PublicKeyType::kEd25519: + return "Ed25519"; + case PublicKeyType::kUnknown: + return "unknown"; + } + return ""; +} + absl::optional<quic::QuicWallTime> ParseDerTime(unsigned tag, absl::string_view payload) { if (tag != CBS_ASN1_GENERALIZEDTIME && tag != CBS_ASN1_UTCTIME) { @@ -461,7 +477,7 @@ } } -PublicKeyType CertificateView::public_key_type() { +PublicKeyType CertificateView::public_key_type() const { return PublicKeyTypeFromKey(public_key_.get()); }
diff --git a/quic/core/crypto/certificate_view.h b/quic/core/crypto/certificate_view.h index 4249258..e546bf6 100644 --- a/quic/core/crypto/certificate_view.h +++ b/quic/core/crypto/certificate_view.h
@@ -42,6 +42,7 @@ kEd25519, kUnknown, }; +std::string PublicKeyTypeToString(PublicKeyType type); // CertificateView represents a parsed version of a single X.509 certificate. As // the word "view" implies, it does not take ownership of the underlying strings @@ -79,7 +80,7 @@ uint16_t signature_algorithm) const; // Returns the type of the key used in the certificate's SPKI. - PublicKeyType public_key_type(); + PublicKeyType public_key_type() const; private: CertificateView() = default;
diff --git a/quic/core/crypto/certificate_view_test.cc b/quic/core/crypto/certificate_view_test.cc index 33514f2..fbca915 100644 --- a/quic/core/crypto/certificate_view_test.cc +++ b/quic/core/crypto/certificate_view_test.cc
@@ -59,6 +59,7 @@ *quiche::QuicheUtcDateTimeToUnixSeconds(2020, 2, 2, 18, 13, 59)); EXPECT_EQ(view->validity_end(), validity_end); EXPECT_EQ(view->public_key_type(), PublicKeyType::kRsa); + EXPECT_EQ(PublicKeyTypeToString(view->public_key_type()), "RSA"); EXPECT_EQ("C=US,ST=California,L=Mountain View,O=QUIC Server,CN=127.0.0.1", view->GetHumanReadableSubject());
diff --git a/quic/quic_transport/web_transport_fingerprint_proof_verifier.cc b/quic/quic_transport/web_transport_fingerprint_proof_verifier.cc index ec58386..649406a 100644 --- a/quic/quic_transport/web_transport_fingerprint_proof_verifier.cc +++ b/quic/quic_transport/web_transport_fingerprint_proof_verifier.cc
@@ -158,6 +158,14 @@ return QUIC_FAILURE; } + if (!IsKeyTypeAllowedByPolicy(*view)) { + *details = std::make_unique<Details>(Status::kDisallowedKeyAlgorithm); + *error_details = + absl::StrCat("Certificate uses a disallowed public key type (", + PublicKeyTypeToString(view->public_key_type()), ")"); + return QUIC_FAILURE; + } + *details = std::make_unique<Details>(Status::kValidCertificate); return QUIC_SUCCESS; } @@ -201,4 +209,21 @@ now.IsBefore(certificate.validity_end()); } +bool WebTransportFingerprintProofVerifier::IsKeyTypeAllowedByPolicy( + const CertificateView& certificate) { + switch (certificate.public_key_type()) { + // https://github.com/w3c/webtransport/pull/375 defines P-256 as an MTI + // algorithm, and prohibits RSA. We also allow P-384 and Ed25519. + case PublicKeyType::kP256: + case PublicKeyType::kP384: + case PublicKeyType::kEd25519: + return true; + case PublicKeyType::kRsa: + // TODO(b/213614428): this should be false by default. + return true; + default: + return false; + } +} + } // namespace quic
diff --git a/quic/quic_transport/web_transport_fingerprint_proof_verifier.h b/quic/quic_transport/web_transport_fingerprint_proof_verifier.h index 76323d5..9a03c66 100644 --- a/quic/quic_transport/web_transport_fingerprint_proof_verifier.h +++ b/quic/quic_transport/web_transport_fingerprint_proof_verifier.h
@@ -61,8 +61,9 @@ kExpiryTooLong = 3, kExpired = 4, kInternalError = 5, + kDisallowedKeyAlgorithm = 6, - kMaxValue = kInternalError, + kMaxValue = kDisallowedKeyAlgorithm, }; class QUIC_EXPORT_PRIVATE Details : public ProofVerifyDetails { @@ -115,6 +116,9 @@ std::unique_ptr<ProofVerifierCallback> callback) override; std::unique_ptr<ProofVerifyContext> CreateDefaultContext() override; + protected: + virtual bool IsKeyTypeAllowedByPolicy(const CertificateView& certificate); + private: bool HasKnownFingerprint(absl::string_view der_certificate); bool HasValidExpiry(const CertificateView& certificate);