summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authoreranm@google.com <eranm@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2013-11-13 00:18:11 +0000
committereranm@google.com <eranm@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2013-11-13 00:18:11 +0000
commitab6eb567415d4c0bd4b6ab14351c2fe0a0f0dcc8 (patch)
tree8a851053599d1643fb19f8b0f048b9490165aed9
parentd85fb73104a08ef2bf9868aa1c6fdce51bb865b3 (diff)
downloadchromium_src-ab6eb567415d4c0bd4b6ab14351c2fe0a0f0dcc8.zip
chromium_src-ab6eb567415d4c0bd4b6ab14351c2fe0a0f0dcc8.tar.gz
chromium_src-ab6eb567415d4c0bd4b6ab14351c2fe0a0f0dcc8.tar.bz2
CT: Adding SCT verification functionality: A CTLogVerifier instance can verify SCTs signed by a single log.
BUG=309578 Review URL: https://codereview.chromium.org/55953002 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@234672 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--net/cert/ct_log_verifier.cc56
-rw-r--r--net/cert/ct_log_verifier.h78
-rw-r--r--net/cert/ct_log_verifier_nss.cc142
-rw-r--r--net/cert/ct_log_verifier_openssl.cc120
-rw-r--r--net/cert/ct_log_verifier_unittest.cc78
-rw-r--r--net/net.gyp7
-rw-r--r--net/test/ct_test_util.cc64
-rw-r--r--net/test/ct_test_util.h15
8 files changed, 551 insertions, 9 deletions
diff --git a/net/cert/ct_log_verifier.cc b/net/cert/ct_log_verifier.cc
new file mode 100644
index 0000000..1c9374d
--- /dev/null
+++ b/net/cert/ct_log_verifier.cc
@@ -0,0 +1,56 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "net/cert/ct_log_verifier.h"
+
+#include "base/logging.h"
+#include "net/cert/ct_serialization.h"
+
+namespace net {
+
+// static
+scoped_ptr<CTLogVerifier> CTLogVerifier::Create(
+ const base::StringPiece& public_key,
+ const base::StringPiece& description) {
+ scoped_ptr<CTLogVerifier> result(new CTLogVerifier());
+ if (!result->Init(public_key, description))
+ result.reset();
+ return result.Pass();
+}
+
+bool CTLogVerifier::Verify(const ct::LogEntry& entry,
+ const ct::SignedCertificateTimestamp& sct) {
+ if (sct.log_id != key_id()) {
+ DVLOG(1) << "SCT is not signed by this log.";
+ return false;
+ }
+
+ if (sct.signature.hash_algorithm != hash_algorithm_) {
+ DVLOG(1) << "Mismatched hash algorithm. Expected " << hash_algorithm_
+ << ", got " << sct.signature.hash_algorithm << ".";
+ return false;
+ }
+
+ if (sct.signature.signature_algorithm != signature_algorithm_) {
+ DVLOG(1) << "Mismatched sig algorithm. Expected " << signature_algorithm_
+ << ", got " << sct.signature.signature_algorithm << ".";
+ return false;
+ }
+
+ std::string serialized_log_entry;
+ if (!ct::EncodeLogEntry(entry, &serialized_log_entry)) {
+ DVLOG(1) << "Unable to serialize entry.";
+ return false;
+ }
+ std::string serialized_data;
+ if (!ct::EncodeV1SCTSignedData(sct.timestamp, serialized_log_entry,
+ sct.extensions, &serialized_data)) {
+ DVLOG(1) << "Unable to create SCT to verify.";
+ return false;
+ }
+
+ return VerifySignature(serialized_data, sct.signature.signature_data);
+}
+
+} // namespace net
diff --git a/net/cert/ct_log_verifier.h b/net/cert/ct_log_verifier.h
new file mode 100644
index 0000000..b4ee520
--- /dev/null
+++ b/net/cert/ct_log_verifier.h
@@ -0,0 +1,78 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef NET_CERT_CT_LOG_VERIFIER_H_
+#define NET_CERT_CT_LOG_VERIFIER_H_
+
+#include <string>
+
+#include "base/gtest_prod_util.h"
+#include "base/memory/scoped_ptr.h"
+#include "base/strings/string_piece.h"
+#include "net/base/net_export.h"
+#include "net/cert/signed_certificate_timestamp.h"
+
+// Forward declare the crypto types to avoid having to include the full
+// headers.
+#if defined(USE_OPENSSL)
+typedef struct evp_pkey_st EVP_PKEY;
+#else
+typedef struct SECKEYPublicKeyStr SECKEYPublicKey;
+#endif
+
+namespace net {
+
+// Class for verifying Signed Certificate Timestamps (SCTs) provided by a
+// specific log (whose identity is provided during construction).
+class NET_EXPORT CTLogVerifier {
+ public:
+ // Creates a new CTLogVerifier that will verify SignedCertificateTimestamps
+ // using |public_key|, which is a DER-encoded SubjectPublicKeyInfo.
+ // If |public_key| refers to an unsupported public key, returns NULL.
+ // |description| is a textual description of the log.
+ static scoped_ptr<CTLogVerifier> Create(
+ const base::StringPiece& public_key,
+ const base::StringPiece& description);
+
+ ~CTLogVerifier();
+
+ // Returns the log's key ID (RFC6962, Section 3.2)
+ const std::string& key_id() const { return key_id_; }
+ // Returns the log's human-readable description.
+ const std::string& description() const { return description_; }
+
+ // Verifies that |sct| contains a valid signature for |entry|.
+ bool Verify(const ct::LogEntry& entry,
+ const ct::SignedCertificateTimestamp& sct);
+
+ private:
+ FRIEND_TEST_ALL_PREFIXES(CTLogVerifierTest, VerifySignature);
+
+ CTLogVerifier();
+
+ // Performs crypto-library specific initialization.
+ bool Init(const base::StringPiece& public_key,
+ const base::StringPiece& description);
+
+ // Performs the underlying verification using the selected public key. Note
+ // that |signature| contains the raw signature data (eg: without any
+ // DigitallySigned struct encoding).
+ bool VerifySignature(const base::StringPiece& data_to_sign,
+ const base::StringPiece& signature);
+
+ std::string key_id_;
+ std::string description_;
+ ct::DigitallySigned::HashAlgorithm hash_algorithm_;
+ ct::DigitallySigned::SignatureAlgorithm signature_algorithm_;
+
+#if defined(USE_OPENSSL)
+ EVP_PKEY* public_key_;
+#else
+ SECKEYPublicKey* public_key_;
+#endif
+};
+
+} // namespace net
+
+#endif // NET_CERT_CT_LOG_VERIFIER_H_
diff --git a/net/cert/ct_log_verifier_nss.cc b/net/cert/ct_log_verifier_nss.cc
new file mode 100644
index 0000000..a8422301
--- /dev/null
+++ b/net/cert/ct_log_verifier_nss.cc
@@ -0,0 +1,142 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "net/cert/ct_log_verifier.h"
+
+#include <cryptohi.h>
+#include <keyhi.h>
+#include <nss.h>
+#include <pk11pub.h>
+#include <secitem.h>
+#include <secoid.h>
+
+#include "base/logging.h"
+#include "crypto/nss_util.h"
+#include "crypto/sha2.h"
+#include "net/cert/signed_certificate_timestamp.h"
+
+namespace net {
+
+namespace {
+
+SECOidTag GetNSSSigAlg(ct::DigitallySigned::SignatureAlgorithm alg) {
+ switch (alg) {
+ case ct::DigitallySigned::SIG_ALGO_RSA:
+ return SEC_OID_PKCS1_RSA_ENCRYPTION;
+ case ct::DigitallySigned::SIG_ALGO_DSA:
+ return SEC_OID_ANSIX9_DSA_SIGNATURE;
+ case ct::DigitallySigned::SIG_ALGO_ECDSA:
+ return SEC_OID_ANSIX962_EC_PUBLIC_KEY;
+ case ct::DigitallySigned::SIG_ALGO_ANONYMOUS:
+ default:
+ NOTREACHED();
+ return SEC_OID_UNKNOWN;
+ }
+}
+
+SECOidTag GetNSSHashAlg(ct::DigitallySigned::HashAlgorithm alg) {
+ switch (alg) {
+ case ct::DigitallySigned::HASH_ALGO_MD5:
+ return SEC_OID_MD5;
+ case ct::DigitallySigned::HASH_ALGO_SHA1:
+ return SEC_OID_SHA1;
+ case ct::DigitallySigned::HASH_ALGO_SHA224:
+ return SEC_OID_SHA224;
+ case ct::DigitallySigned::HASH_ALGO_SHA256:
+ return SEC_OID_SHA256;
+ case ct::DigitallySigned::HASH_ALGO_SHA384:
+ return SEC_OID_SHA384;
+ case ct::DigitallySigned::HASH_ALGO_SHA512:
+ return SEC_OID_SHA512;
+ case ct::DigitallySigned::HASH_ALGO_NONE:
+ default:
+ NOTREACHED();
+ return SEC_OID_UNKNOWN;
+ }
+}
+
+} // namespace
+
+CTLogVerifier::~CTLogVerifier() {
+ if (public_key_)
+ SECKEY_DestroyPublicKey(public_key_);
+}
+
+CTLogVerifier::CTLogVerifier() :
+ hash_algorithm_(ct::DigitallySigned::HASH_ALGO_NONE),
+ signature_algorithm_(ct::DigitallySigned::SIG_ALGO_ANONYMOUS),
+ public_key_(NULL) {}
+
+bool CTLogVerifier::Init(const base::StringPiece& public_key,
+ const base::StringPiece& description) {
+ SECItem key_data;
+
+ crypto::EnsureNSSInit();
+
+ key_data.data = reinterpret_cast<unsigned char*>(
+ const_cast<char*>(public_key.data()));
+ key_data.len = public_key.size();
+
+ CERTSubjectPublicKeyInfo* public_key_info =
+ SECKEY_DecodeDERSubjectPublicKeyInfo(&key_data);
+ if (!public_key_info) {
+ DVLOG(1) << "Failed decoding public key.";
+ return false;
+ }
+
+ public_key_ = SECKEY_ExtractPublicKey(public_key_info);
+ SECKEY_DestroySubjectPublicKeyInfo(public_key_info);
+
+ if (!public_key_) {
+ DVLOG(1) << "Failed extracting public key.";
+ return false;
+ }
+
+ key_id_ = crypto::SHA256HashString(public_key);
+ description_ = description.as_string();
+
+ // Right now, only RSASSA-PKCS1v15 with SHA-256 and ECDSA with SHA-256 are
+ // supported.
+ switch (SECKEY_GetPublicKeyType(public_key_)) {
+ case rsaKey:
+ hash_algorithm_ = ct::DigitallySigned::HASH_ALGO_SHA256;
+ signature_algorithm_ = ct::DigitallySigned::SIG_ALGO_RSA;
+ break;
+ case ecKey:
+ hash_algorithm_ = ct::DigitallySigned::HASH_ALGO_SHA256;
+ signature_algorithm_ = ct::DigitallySigned::SIG_ALGO_ECDSA;
+ break;
+ default:
+ DVLOG(1) << "Unsupported key type: " <<
+ SECKEY_GetPublicKeyType(public_key_);
+ return false;
+ }
+
+ // Extra sanity check: Require RSA keys of at least 2048 bits.
+ if (signature_algorithm_ == ct::DigitallySigned::SIG_ALGO_RSA &&
+ SECKEY_PublicKeyStrengthInBits(public_key_) < 2048) {
+ DVLOG(1) << "Too small a public key.";
+ return false;
+ }
+
+ return true;
+}
+
+bool CTLogVerifier::VerifySignature(const base::StringPiece& data_to_sign,
+ const base::StringPiece& signature) {
+ SECItem sig_data;
+ sig_data.data = reinterpret_cast<unsigned char*>(const_cast<char*>(
+ signature.data()));
+ sig_data.len = signature.size();
+
+ SECStatus rv = VFY_VerifyDataDirect(
+ reinterpret_cast<const unsigned char*>(data_to_sign.data()),
+ data_to_sign.size(), public_key_, &sig_data,
+ GetNSSSigAlg(signature_algorithm_), GetNSSHashAlg(hash_algorithm_),
+ NULL, NULL);
+ DVLOG(1) << "Signature verification result: " << (rv == SECSuccess);
+ return rv == SECSuccess;
+}
+
+} // namespace net
diff --git a/net/cert/ct_log_verifier_openssl.cc b/net/cert/ct_log_verifier_openssl.cc
new file mode 100644
index 0000000..a4bc3dd
--- /dev/null
+++ b/net/cert/ct_log_verifier_openssl.cc
@@ -0,0 +1,120 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "net/cert/ct_log_verifier.h"
+
+#include <openssl/evp.h>
+#include <openssl/x509.h>
+
+#include "base/logging.h"
+#include "crypto/openssl_util.h"
+#include "crypto/sha2.h"
+
+namespace net {
+
+namespace {
+
+const EVP_MD* GetEvpAlg(ct::DigitallySigned::HashAlgorithm alg) {
+ switch (alg) {
+ case ct::DigitallySigned::HASH_ALGO_MD5:
+ return EVP_md5();
+ case ct::DigitallySigned::HASH_ALGO_SHA1:
+ return EVP_sha1();
+ case ct::DigitallySigned::HASH_ALGO_SHA224:
+ return EVP_sha224();
+ case ct::DigitallySigned::HASH_ALGO_SHA256:
+ return EVP_sha256();
+ case ct::DigitallySigned::HASH_ALGO_SHA384:
+ return EVP_sha384();
+ case ct::DigitallySigned::HASH_ALGO_SHA512:
+ return EVP_sha512();
+ case ct::DigitallySigned::HASH_ALGO_NONE:
+ default:
+ NOTREACHED();
+ return NULL;
+ }
+}
+
+} // namespace
+
+CTLogVerifier::~CTLogVerifier() {
+ crypto::OpenSSLErrStackTracer err_tracer(FROM_HERE);
+
+ if (public_key_)
+ EVP_PKEY_free(public_key_);
+}
+
+CTLogVerifier::CTLogVerifier() :
+ hash_algorithm_(ct::DigitallySigned::HASH_ALGO_NONE),
+ signature_algorithm_(ct::DigitallySigned::SIG_ALGO_ANONYMOUS),
+ public_key_(NULL) {}
+
+bool CTLogVerifier::Init(const base::StringPiece& public_key,
+ const base::StringPiece& description) {
+ crypto::OpenSSLErrStackTracer err_tracer(FROM_HERE);
+
+ crypto::ScopedOpenSSL<BIO, BIO_free_all> bio(
+ BIO_new_mem_buf(const_cast<char*>(public_key.data()), public_key.size()));
+ if (!bio.get())
+ return false;
+
+ public_key_ = d2i_PUBKEY_bio(bio.get(), NULL);
+ if (!public_key_)
+ return false;
+
+ key_id_ = crypto::SHA256HashString(public_key);
+ description_ = description.as_string();
+
+ // Right now, only RSASSA-PKCS1v15 with SHA-256 and ECDSA with SHA-256 are
+ // supported.
+ switch (EVP_PKEY_type(public_key_->type)) {
+ case EVP_PKEY_RSA:
+ hash_algorithm_ = ct::DigitallySigned::HASH_ALGO_SHA256;
+ signature_algorithm_ = ct::DigitallySigned::SIG_ALGO_RSA;
+ break;
+ case EVP_PKEY_EC:
+ hash_algorithm_ = ct::DigitallySigned::HASH_ALGO_SHA256;
+ signature_algorithm_ = ct::DigitallySigned::SIG_ALGO_ECDSA;
+ break;
+ default:
+ DVLOG(1) << "Unsupported key type: " << EVP_PKEY_type(public_key_->type);
+ return false;
+ }
+
+ // Extra sanity check: Require RSA keys of at least 2048 bits.
+ // EVP_PKEY_size returns the size in bytes. 256 = 2048-bit RSA key.
+ if (signature_algorithm_ == ct::DigitallySigned::SIG_ALGO_RSA &&
+ EVP_PKEY_size(public_key_) < 256) {
+ DVLOG(1) << "Too small a public key.";
+ return false;
+ }
+
+ return true;
+}
+
+bool CTLogVerifier::VerifySignature(const base::StringPiece& data_to_sign,
+ const base::StringPiece& signature) {
+ crypto::OpenSSLErrStackTracer err_tracer(FROM_HERE);
+
+ const EVP_MD* hash_alg = GetEvpAlg(hash_algorithm_);
+ if (hash_alg == NULL)
+ return false;
+
+ EVP_MD_CTX ctx;
+ EVP_MD_CTX_init(&ctx);
+
+ bool ok = (
+ 1 == EVP_DigestVerifyInit(&ctx, NULL, hash_alg, NULL, public_key_) &&
+ 1 == EVP_DigestVerifyUpdate(
+ &ctx, data_to_sign.data(), data_to_sign.size()) &&
+ 1 == EVP_DigestVerifyFinal(
+ &ctx,
+ reinterpret_cast<unsigned char*>(const_cast<char*>(signature.data())),
+ signature.size()));
+
+ EVP_MD_CTX_cleanup(&ctx);
+ return ok;
+}
+
+} // namespace net
diff --git a/net/cert/ct_log_verifier_unittest.cc b/net/cert/ct_log_verifier_unittest.cc
new file mode 100644
index 0000000..4412258
--- /dev/null
+++ b/net/cert/ct_log_verifier_unittest.cc
@@ -0,0 +1,78 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "net/cert/ct_log_verifier.h"
+
+#include <string>
+
+#include "base/time/time.h"
+#include "net/cert/signed_certificate_timestamp.h"
+#include "net/test/ct_test_util.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace net {
+
+class CTLogVerifierTest : public ::testing::Test {
+ public:
+ CTLogVerifierTest() {}
+
+ virtual void SetUp() OVERRIDE {
+ log_ = CTLogVerifier::Create(ct::GetTestPublicKey(), "testlog").Pass();
+
+ ASSERT_TRUE(log_);
+ ASSERT_EQ(log_->key_id(), ct::GetTestPublicKeyId());
+ }
+
+ protected:
+ scoped_ptr<CTLogVerifier> log_;
+};
+
+TEST_F(CTLogVerifierTest, VerifiesCertSCT) {
+ ct::LogEntry cert_entry;
+ ct::GetX509CertLogEntry(&cert_entry);
+
+ ct::SignedCertificateTimestamp cert_sct;
+ ct::GetX509CertSCT(&cert_sct);
+
+ EXPECT_TRUE(log_->Verify(cert_entry, cert_sct));
+}
+
+TEST_F(CTLogVerifierTest, VerifiesPrecertSCT) {
+ ct::LogEntry precert_entry;
+ ct::GetPrecertLogEntry(&precert_entry);
+
+ ct::SignedCertificateTimestamp precert_sct;
+ ct::GetPrecertSCT(&precert_sct);
+
+ EXPECT_TRUE(log_->Verify(precert_entry, precert_sct));
+}
+
+TEST_F(CTLogVerifierTest, FailsInvalidTimestamp) {
+ ct::LogEntry cert_entry;
+ ct::GetX509CertLogEntry(&cert_entry);
+
+ ct::SignedCertificateTimestamp cert_sct;
+ ct::GetX509CertSCT(&cert_sct);
+
+ // Mangle the timestamp, so that it should fail signature validation.
+ cert_sct.timestamp = base::Time::Now();
+
+ EXPECT_FALSE(log_->Verify(cert_entry, cert_sct));
+}
+
+TEST_F(CTLogVerifierTest, FailsInvalidLogID) {
+ ct::LogEntry cert_entry;
+ ct::GetX509CertLogEntry(&cert_entry);
+
+ ct::SignedCertificateTimestamp cert_sct;
+ ct::GetX509CertSCT(&cert_sct);
+
+ // Mangle the log ID, which should cause it to match a different log before
+ // attempting signature validation.
+ cert_sct.log_id.assign(cert_sct.log_id.size(), '\0');
+
+ EXPECT_FALSE(log_->Verify(cert_entry, cert_sct));
+}
+
+} // namespace net
diff --git a/net/net.gyp b/net/net.gyp
index f0b8ce4..338073c 100644
--- a/net/net.gyp
+++ b/net/net.gyp
@@ -270,6 +270,10 @@
'cert/cert_verify_result.h',
'cert/crl_set.cc',
'cert/crl_set.h',
+ 'cert/ct_log_verifier.cc',
+ 'cert/ct_log_verifier.h',
+ 'cert/ct_log_verifier_nss.cc',
+ 'cert/ct_log_verifier_openssl.cc',
'cert/ct_serialization.cc',
'cert/ct_serialization.h',
'cert/ev_root_ca_metadata.cc',
@@ -1257,6 +1261,7 @@
'cert/cert_database_nss.cc',
'cert/cert_verify_proc_nss.cc',
'cert/cert_verify_proc_nss.h',
+ 'cert/ct_log_verifier_nss.cc',
'cert/jwk_serializer_nss.cc',
'cert/nss_cert_database.cc',
'cert/nss_cert_database.h',
@@ -1295,6 +1300,7 @@
'cert/cert_database_openssl.cc',
'cert/cert_verify_proc_openssl.cc',
'cert/cert_verify_proc_openssl.h',
+ 'cert/ct_log_verifier_openssl.cc',
'cert/jwk_serializer_openssl.cc',
'cert/test_root_certs_openssl.cc',
'cert/x509_certificate_openssl.cc',
@@ -1583,6 +1589,7 @@
'base/url_util_unittest.cc',
'cert/cert_verify_proc_unittest.cc',
'cert/crl_set_unittest.cc',
+ 'cert/ct_log_verifier_unittest.cc',
'cert/ct_serialization_unittest.cc',
'cert/ev_root_ca_metadata_unittest.cc',
'cert/jwk_serializer_unittest.cc',
diff --git a/net/test/ct_test_util.cc b/net/test/ct_test_util.cc
index cd014e4..b588b13 100644
--- a/net/test/ct_test_util.cc
+++ b/net/test/ct_test_util.cc
@@ -53,8 +53,8 @@ const char kDefaultDerCert[] =
"f667256cd6a1647b5e13203bb8582de7d6696f656d1c60b95f456b7fcf338571908f1c6972"
"7d24c4fccd249295795814d1dac0e6";
-const char kDefaultKeyHash[] =
- "2518ce9dcf869f18562d21cf7d040cbacc75371f019f8bea8cbe2f5f6619472d";
+const char kDefaultIssuerKeyHash[] =
+ "02adddca08b8bf9861f035940c940156d8350fdff899a6239c6bd77255b8f8fc";
const char kDefaultDerTbsCert[] =
"30820233a003020102020107300d06092a864886f70d01010505003055310b300906035504"
@@ -64,12 +64,12 @@ const char kDefaultDerTbsCert[] =
"310b30090603550406130247423121301f060355040a131843657274696669636174652054"
"72616e73706172656e6379310e300c0603550408130557616c65733110300e060355040713"
"074572772057656e30819f300d06092a864886f70d010101050003818d0030818902818100"
- "bed8893cc8f177efc548df4961443f999aeda90471992f818bf8b61d0df19d6eec3d596c9b"
- "43e60033a501c8cffcc438f49f5edb3662aaaecf180e7c9b59fc4bd465c18c406b3b70cdde"
- "52d5dec42aaef913c2173592c76130f2399de6ccd6e75e04ccea7d7e4bdf4bacb16b5fe697"
- "2974bca8bcb3e8468dec941e945fdf98310203010001a381ac3081a9301d0603551d0e0416"
- "0414a4998f6b0abefd0e549bd56f221da976d0ce57d6307d0603551d230476307480143633"
- "1299dbdc389d1cccfe31c08b8932501a8f7ca159a4573055310b3009060355040613024742"
+ "beef98e7c26877ae385f75325a0c1d329bedf18faaf4d796bf047eb7e1ce15c95ba2f80ee4"
+ "58bd7db86f8a4b252191a79bd700c38e9c0389b45cd4dc9a120ab21e0cb41cd0e72805a410"
+ "cd9c5bdb5d4927726daf1710f60187377ea25b1a1e39eed0b88119dc154dc68f7da8e30caf"
+ "158a33e6c9509f4a05b01409ff5dd87eb50203010001a381ac3081a9301d0603551d0e0416"
+ "04142031541af25c05ffd8658b6843794f5e9036f7b4307d0603551d230476307480145f9d"
+ "880dc873e654d4f80dd8e6b0c124b447c355a159a4573055310b3009060355040613024742"
"31243022060355040a131b4365727469666963617465205472616e73706172656e63792043"
"41310e300c0603550408130557616c65733110300e060355040713074572772057656e8201"
"0030090603551d1304023000";
@@ -85,6 +85,22 @@ const char kTestSignedCertificateTimestamp[] =
"08dfbfe9ef536cf7f2022100beb29c72d7d06d61d06bdb38a069469aa86fe12e18bb7cc456"
"89a2c0187ef5a5";
+const char kEcP256PublicKey[] =
+ "3059301306072a8648ce3d020106082a8648ce3d0301070342000499783cb14533c0161a5a"
+ "b45bf95d08a29cd0ea8dd4c84274e2be59ad15c676960cf0afa1074a57ac644b23479e5b3f"
+ "b7b245eb4b420ef370210371a944beaceb";
+
+const char kTestKeyId[] =
+ "df1c2ec11500945247a96168325ddc5c7959e8f7c6d388fc002e0bbd3f74d764";
+
+const char kTestSCTSignatureData[] =
+ "30450220606e10ae5c2d5a1b0aed49dc4937f48de71a4e9784e9c208dfbfe9ef536cf7f202"
+ "2100beb29c72d7d06d61d06bdb38a069469aa86fe12e18bb7cc45689a2c0187ef5a5";
+
+const char kTestSCTPrecertSignatureData[] =
+ "30450220482f6751af35dba65436be1fd6640f3dbf9a41429495924530288fa3e5e23e0602"
+ "2100e4edc0db3ac572b1e2f5e8ab6a680653987dcf41027dfeffa105519d89edbf08";
+
} // namespace
void GetX509CertLogEntry(LogEntry* entry) {
@@ -94,7 +110,7 @@ void GetX509CertLogEntry(LogEntry* entry) {
void GetPrecertLogEntry(LogEntry* entry) {
entry->type = ct::LogEntry::LOG_ENTRY_TYPE_PRECERT;
- std::string issuer_hash(HexToBytes(kDefaultKeyHash));
+ std::string issuer_hash(HexToBytes(kDefaultIssuerKeyHash));
memcpy(entry->issuer_key_hash.data, issuer_hash.data(), issuer_hash.size());
entry->tbs_certificate = HexToBytes(kDefaultDerTbsCert);
}
@@ -107,6 +123,36 @@ std::string GetTestSignedCertificateTimestamp() {
return HexToBytes(kTestSignedCertificateTimestamp);
}
+std::string GetTestPublicKey() {
+ return HexToBytes(kEcP256PublicKey);
+}
+
+std::string GetTestPublicKeyId() {
+ return HexToBytes(kTestKeyId);
+}
+
+void GetX509CertSCT(SignedCertificateTimestamp* sct) {
+ sct->log_id = HexToBytes(kTestKeyId);
+ sct->timestamp = base::Time::UnixEpoch() +
+ base::TimeDelta::FromMilliseconds(GG_UINT64_C(1365181456089));
+ sct->extensions.clear();
+
+ sct->signature.hash_algorithm = ct::DigitallySigned::HASH_ALGO_SHA256;
+ sct->signature.signature_algorithm = ct::DigitallySigned::SIG_ALGO_ECDSA;
+ sct->signature.signature_data = HexToBytes(kTestSCTSignatureData);
+}
+
+void GetPrecertSCT(SignedCertificateTimestamp* sct) {
+ sct->log_id = HexToBytes(kTestKeyId);
+ sct->timestamp = base::Time::UnixEpoch() +
+ base::TimeDelta::FromMilliseconds(GG_UINT64_C(1365181456275));
+ sct->extensions.clear();
+
+ sct->signature.hash_algorithm = ct::DigitallySigned::HASH_ALGO_SHA256;
+ sct->signature.signature_algorithm = ct::DigitallySigned::SIG_ALGO_ECDSA;
+ sct->signature.signature_data = HexToBytes(kTestSCTPrecertSignatureData);
+}
+
} // namespace ct
} // namespace net
diff --git a/net/test/ct_test_util.h b/net/test/ct_test_util.h
index 79881ce..f12e144 100644
--- a/net/test/ct_test_util.h
+++ b/net/test/ct_test_util.h
@@ -16,6 +16,9 @@ namespace ct {
struct LogEntry;
struct SignedCertificateTimestamp;
+// Note: unless specified otherwise, all test data is taken from Certificate
+// Transparency test data repository.
+
// Fills |entry| with test data for an X.509 entry.
void GetX509CertLogEntry(LogEntry* entry);
@@ -28,6 +31,18 @@ std::string GetTestDigitallySigned();
// Returns the binary representation of a test serialized SCT.
std::string GetTestSignedCertificateTimestamp();
+// Test log key
+std::string GetTestPublicKey();
+
+// ID of test log key
+std::string GetTestPublicKeyId();
+
+// SCT for the X509Certificate provided above.
+void GetX509CertSCT(SignedCertificateTimestamp* sct);
+
+// SCT for the Precertificate log entry provided above.
+void GetPrecertSCT(SignedCertificateTimestamp* sct);
+
} // namespace ct
} // namespace net