Commit 1aed13d7 authored by Kunihiko Sakamoto's avatar Kunihiko Sakamoto Committed by Commit Bot

Add asn1::HasTestCanSignHttpExchangesExtension()

This will be used by SignedExchangeHandler to verify that certificates
for signed exchanges have the testCanSignHttpExchanges extension.

Bug: 851778
Change-Id: Ib32a00246da5176b3077e7fcf70ad283a8511b98
Reviewed-on: https://chromium-review.googlesource.com/1103430
Commit-Queue: Kunihiko Sakamoto <ksakamoto@chromium.org>
Reviewed-by: default avatarRyan Sleevi <rsleevi@chromium.org>
Cr-Commit-Position: refs/heads/master@{#569514}
parent 8af34d70
...@@ -2481,6 +2481,7 @@ bundle_data("test_support_bundle_data") { ...@@ -2481,6 +2481,7 @@ bundle_data("test_support_bundle_data") {
"data/ssl/certificates/start_after_expiry.pem", "data/ssl/certificates/start_after_expiry.pem",
"data/ssl/certificates/subjectAltName_sanity_check.pem", "data/ssl/certificates/subjectAltName_sanity_check.pem",
"data/ssl/certificates/subjectAltName_www_example_com.pem", "data/ssl/certificates/subjectAltName_www_example_com.pem",
"data/ssl/certificates/test_can_sign_http_exchanges_extension.pem",
"data/ssl/certificates/thawte.single.pem", "data/ssl/certificates/thawte.single.pem",
"data/ssl/certificates/tls_feature_extension.pem", "data/ssl/certificates/tls_feature_extension.pem",
"data/ssl/certificates/trustcenter.websecurity.symantec.com.pem", "data/ssl/certificates/trustcenter.websecurity.symantec.com.pem",
......
...@@ -147,6 +147,30 @@ bool SeekToExtensions(der::Input in, ...@@ -147,6 +147,30 @@ bool SeekToExtensions(der::Input in,
return true; return true;
} }
bool HasExtensionWithOID(base::StringPiece cert, der::Input extension_oid) {
bool present;
der::Parser extensions_parser;
if (!SeekToExtensions(der::Input(cert), &present, &extensions_parser))
return false;
if (!present)
return false;
while (extensions_parser.HasMore()) {
der::Parser extension_parser;
if (!extensions_parser.ReadSequence(&extension_parser))
return false;
der::Input oid;
if (!extension_parser.ReadTag(der::kOid, &oid))
return false;
if (oid == extension_oid)
return true;
}
return false;
}
} // namespace } // namespace
bool ExtractSubjectFromDERCert(base::StringPiece cert, bool ExtractSubjectFromDERCert(base::StringPiece cert,
...@@ -203,31 +227,22 @@ bool ExtractSubjectPublicKeyFromSPKI(base::StringPiece spki, ...@@ -203,31 +227,22 @@ bool ExtractSubjectPublicKeyFromSPKI(base::StringPiece spki,
} }
bool HasTLSFeatureExtension(base::StringPiece cert) { bool HasTLSFeatureExtension(base::StringPiece cert) {
bool present; // kTLSFeatureExtensionOID is the DER encoding of the OID for the
der::Parser extensions_parser; // X.509 TLS Feature Extension.
if (!SeekToExtensions(der::Input(cert), &present, &extensions_parser)) static const uint8_t kTLSFeatureExtensionOID[] = {0x2B, 0x06, 0x01, 0x05,
return false; 0x05, 0x07, 0x01, 0x18};
if (!present)
return false;
while (extensions_parser.HasMore()) {
der::Parser extension_parser;
if (!extensions_parser.ReadSequence(&extension_parser))
return false;
der::Input oid; return HasExtensionWithOID(cert, der::Input(kTLSFeatureExtensionOID));
if (!extension_parser.ReadTag(der::kOid, &oid)) }
return false;
// kTLSFeatureExtensionOID is the DER encoding of the OID for the bool HasTestCanSignHttpExchangesExtension(base::StringPiece cert) {
// X.509 TLS Feature Extension. // kTestCanSignHttpExchangesOid is the DER encoding of the OID for
static const uint8_t kTLSFeatureExtensionOID[] = {0x2B, 0x06, 0x01, 0x05, // testCanSignHttpExchanges defined in:
0x05, 0x07, 0x01, 0x18}; // https://wicg.github.io/webpackage/draft-yasskin-http-origin-signed-responses.html
if (oid == der::Input(kTLSFeatureExtensionOID)) static const uint8_t kTestCanSignHttpExchangesOid[] = {
return true; 0x2B, 0x06, 0x01, 0x04, 0x01, 0xd6, 0x79, 0x02, 0x01, 0x16};
}
return false; return HasExtensionWithOID(cert, der::Input(kTestCanSignHttpExchangesOid));
} }
bool ExtractSignatureAlgorithmsFromDERCert( bool ExtractSignatureAlgorithmsFromDERCert(
......
...@@ -41,6 +41,13 @@ NET_EXPORT_PRIVATE bool ExtractSubjectPublicKeyFromSPKI( ...@@ -41,6 +41,13 @@ NET_EXPORT_PRIVATE bool ExtractSubjectPublicKeyFromSPKI(
// present or if there was a parsing failure. // present or if there was a parsing failure.
NET_EXPORT_PRIVATE bool HasTLSFeatureExtension(base::StringPiece cert); NET_EXPORT_PRIVATE bool HasTLSFeatureExtension(base::StringPiece cert);
// HasTestCanSignHttpExchangesExtension parses the DER encoded certificate
// in |cert| and extracts the testCanSignHttpExchangesExtension extension
// (https://wicg.github.io/webpackage/draft-yasskin-http-origin-signed-responses.html)
// if present. Returns true if the extension was present, and false if
// the extension was not present or if there was a parsing failure.
NET_EXPORT bool HasTestCanSignHttpExchangesExtension(base::StringPiece cert);
// Extracts the two (SEQUENCE) tag-length-values for the signature // Extracts the two (SEQUENCE) tag-length-values for the signature
// AlgorithmIdentifiers in a DER encoded certificate. Does not use strict // AlgorithmIdentifiers in a DER encoded certificate. Does not use strict
// parsing or validate the resulting AlgorithmIdentifiers. // parsing or validate the resulting AlgorithmIdentifiers.
......
...@@ -605,6 +605,26 @@ TEST(X509CertificateTest, DoesNotHaveTLSFeatureExtension) { ...@@ -605,6 +605,26 @@ TEST(X509CertificateTest, DoesNotHaveTLSFeatureExtension) {
x509_util::CryptoBufferAsStringPiece(cert->cert_buffer()))); x509_util::CryptoBufferAsStringPiece(cert->cert_buffer())));
} }
TEST(X509CertificateTest, HasTestCanSignHttpExchangesExtension) {
base::FilePath certs_dir = GetTestCertsDirectory();
scoped_refptr<X509Certificate> cert = ImportCertFromFile(
certs_dir, "test_can_sign_http_exchanges_extension.pem");
ASSERT_NE(static_cast<X509Certificate*>(NULL), cert.get());
EXPECT_TRUE(asn1::HasTestCanSignHttpExchangesExtension(
x509_util::CryptoBufferAsStringPiece(cert->cert_buffer())));
}
TEST(X509CertificateTest, DoesNotHaveTestCanSignHttpExchangesExtension) {
base::FilePath certs_dir = GetTestCertsDirectory();
scoped_refptr<X509Certificate> cert =
ImportCertFromFile(certs_dir, "ok_cert.pem");
ASSERT_NE(static_cast<X509Certificate*>(NULL), cert.get());
EXPECT_FALSE(asn1::HasTestCanSignHttpExchangesExtension(
x509_util::CryptoBufferAsStringPiece(cert->cert_buffer())));
}
// Tests CRYPTO_BUFFER deduping via X509Certificate::CreateFromBuffer. We // Tests CRYPTO_BUFFER deduping via X509Certificate::CreateFromBuffer. We
// call X509Certificate::CreateFromBuffer several times and observe whether // call X509Certificate::CreateFromBuffer several times and observe whether
// it returns a cached or new CRYPTO_BUFFER. // it returns a cached or new CRYPTO_BUFFER.
......
-----BEGIN CERTIFICATE-----
MIIDazCCAlOgAwIBAgIJAIymUztkzWQvMA0GCSqGSIb3DQEBCwUAMGAxCzAJBgNV
BAYTAlVTMRMwEQYDVQQIDApDYWxpZm9ybmlhMRYwFAYDVQQHDA1Nb3VudGFpbiBW
aWV3MRAwDgYDVQQKDAdUZXN0IENBMRIwEAYDVQQDDAkxMjcuMC4wLjEwHhcNMTgw
NjE4MDM1NjMxWhcNMTkwNjE4MDM1NjMxWjBgMQswCQYDVQQGEwJVUzETMBEGA1UE
CAwKQ2FsaWZvcm5pYTEWMBQGA1UEBwwNTW91bnRhaW4gVmlldzEQMA4GA1UECgwH
VGVzdCBDQTESMBAGA1UEAwwJMTI3LjAuMC4xMIIBIjANBgkqhkiG9w0BAQEFAAOC
AQ8AMIIBCgKCAQEAq3WemlGl/h0AYRAiQeLWG51rXk2ayySal/Dp9ovOsKqLarcZ
JJiNFWhq71Aw3Mqu5pzdN10BMBIxSoBQXWU28XcjiZtIhqhQYyKUmEHJtkas3p4a
V16MeG2SciwF9XpqBR8BGOTxsGclH1+qK0UgnCeLfwYjqxyATSl2UJF+ZeHvLaYl
Z1MfuMUzt2mTILxg/7dblHuFcFiPvjcfNiQ6RdxC7y2SBnPL2us0AgJKm3n1/w5S
zlf5PYccat7qdYe9BgQGWDa9pMQKGO6+9rm7SI8bt2cdUgnqS3ODHV5y5SnS3IjF
KGBNujSyhIsJqNExjTKRw3nfI4E7b8NPO1mJCwIDAQABoygwJjAPBgNVHREECDAG
hwR/AAABMBMGCisGAQQB1nkCARYBAf8EAgUAMA0GCSqGSIb3DQEBCwUAA4IBAQAM
QDGGqhPiwz1OpJjzYBX5ruUu42mlxkkqdVKnEceLi9c4L1lFSpSSoowxWcpeBelG
mqXxwVTYkrpN5+4sUexMBcIt8Lsd+po0XPN/JY9Tr2xC10jzQ+7fYaXH9l+38OaP
Ne4lWjpgF2eUizJweFTugivnU1+7oRYoP9FibN7Oa/CX50eZL5onLkHka8LeOToF
BlRIrk75U3JNyS+X5jN194tEJ+W0ZYGr955CTOpAmRH90pWcbUO991Zbuj2Sjidb
WE7SHqatZ1wf7YNDN+hXYHOMl2YuiZ8Y7jQXJnXv5SW3EKKaPIv1kuOEOSXQcZ1Y
jHLdGk8wx0wnZclbn5LK
-----END CERTIFICATE-----
...@@ -65,6 +65,10 @@ subjectAltName = DNS:webmail ...@@ -65,6 +65,10 @@ subjectAltName = DNS:webmail
subjectAltName = IP:127.0.0.1 subjectAltName = IP:127.0.0.1
1.3.6.1.5.5.7.1.24=DER:30:03:02:01:05 1.3.6.1.5.5.7.1.24=DER:30:03:02:01:05
[req_extensions_with_test_can_sign_http_exchanges]
subjectAltName = IP:127.0.0.1
1.3.6.1.4.1.11129.2.1.22 = critical,ASN1:NULL
[req_localhost_san] [req_localhost_san]
subjectAltName = DNS:localhost subjectAltName = DNS:localhost
......
...@@ -472,6 +472,14 @@ openssl req -x509 -newkey rsa:2048 \ ...@@ -472,6 +472,14 @@ openssl req -x509 -newkey rsa:2048 \
-extensions req_extensions_with_tls_feature \ -extensions req_extensions_with_tls_feature \
-nodes -config ee.cnf -nodes -config ee.cnf
# Includes the testCanSignHttpExchanges extension
openssl req -x509 -newkey rsa:2048 \
-keyout out/test_can_sign_http_exchanges_extension.key \
-out ../certificates/test_can_sign_http_exchanges_extension.pem \
-days 365 \
-extensions req_extensions_with_test_can_sign_http_exchanges \
-nodes -config ee.cnf
# SHA-1 certificate issued by locally trusted CA # SHA-1 certificate issued by locally trusted CA
openssl req \ openssl req \
-config ../scripts/ee.cnf \ -config ../scripts/ee.cnf \
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment