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