diff options
author | mattm@chromium.org <mattm@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-12-22 01:46:19 +0000 |
---|---|---|
committer | mattm@chromium.org <mattm@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-12-22 01:46:19 +0000 |
commit | 4082fa2a9b307fc78675602bbcc0acade2029059 (patch) | |
tree | af99bc0b6de4414edea1b97af87316d203648095 /net | |
parent | 25142ecaf7ff6a2ade87625b34d715700cb7e68f (diff) | |
download | chromium_src-4082fa2a9b307fc78675602bbcc0acade2029059.zip chromium_src-4082fa2a9b307fc78675602bbcc0acade2029059.tar.gz chromium_src-4082fa2a9b307fc78675602bbcc0acade2029059.tar.bz2 |
Try#2: Handle Origin Bound Certificate expiration.
(Initialize test from raw time value to work around inability to parse dates past 2038 on 32-bit linux.)
BUG=107047
TEST=net_unittests, unit_tests
Review URL: http://codereview.chromium.org/9016002
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@115463 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'net')
-rw-r--r-- | net/base/default_origin_bound_cert_store.cc | 6 | ||||
-rw-r--r-- | net/base/default_origin_bound_cert_store.h | 2 | ||||
-rw-r--r-- | net/base/default_origin_bound_cert_store_unittest.cc | 91 | ||||
-rw-r--r-- | net/base/origin_bound_cert_service.cc | 45 | ||||
-rw-r--r-- | net/base/origin_bound_cert_service.h | 6 | ||||
-rw-r--r-- | net/base/origin_bound_cert_service_unittest.cc | 50 | ||||
-rw-r--r-- | net/base/origin_bound_cert_store.cc | 2 | ||||
-rw-r--r-- | net/base/origin_bound_cert_store.h | 14 | ||||
-rw-r--r-- | net/base/x509_certificate_nss.cc | 5 | ||||
-rw-r--r-- | net/base/x509_util.h | 6 | ||||
-rw-r--r-- | net/base/x509_util_nss.cc | 35 | ||||
-rw-r--r-- | net/base/x509_util_nss.h | 3 | ||||
-rw-r--r-- | net/base/x509_util_nss_unittest.cc | 22 | ||||
-rw-r--r-- | net/base/x509_util_openssl.cc | 6 | ||||
-rw-r--r-- | net/base/x509_util_openssl_unittest.cc | 11 |
15 files changed, 238 insertions, 66 deletions
diff --git a/net/base/default_origin_bound_cert_store.cc b/net/base/default_origin_bound_cert_store.cc index 8104658..3c311ca 100644 --- a/net/base/default_origin_bound_cert_store.cc +++ b/net/base/default_origin_bound_cert_store.cc @@ -30,6 +30,7 @@ void DefaultOriginBoundCertStore::FlushStore( bool DefaultOriginBoundCertStore::GetOriginBoundCert( const std::string& origin, SSLClientCertType* type, + base::Time* expiration_time, std::string* private_key_result, std::string* cert_result) { base::AutoLock autolock(lock_); @@ -42,6 +43,7 @@ bool DefaultOriginBoundCertStore::GetOriginBoundCert( OriginBoundCert* cert = it->second; *type = cert->type(); + *expiration_time = cert->expiration_time(); *private_key_result = cert->private_key(); *cert_result = cert->cert(); @@ -51,6 +53,7 @@ bool DefaultOriginBoundCertStore::GetOriginBoundCert( void DefaultOriginBoundCertStore::SetOriginBoundCert( const std::string& origin, SSLClientCertType type, + base::Time expiration_time, const std::string& private_key, const std::string& cert) { base::AutoLock autolock(lock_); @@ -58,7 +61,8 @@ void DefaultOriginBoundCertStore::SetOriginBoundCert( InternalDeleteOriginBoundCert(origin); InternalInsertOriginBoundCert( - origin, new OriginBoundCert(origin, type, private_key, cert)); + origin, + new OriginBoundCert(origin, type, expiration_time, private_key, cert)); } void DefaultOriginBoundCertStore::DeleteOriginBoundCert( diff --git a/net/base/default_origin_bound_cert_store.h b/net/base/default_origin_bound_cert_store.h index 8f9a3e3..1714248 100644 --- a/net/base/default_origin_bound_cert_store.h +++ b/net/base/default_origin_bound_cert_store.h @@ -57,11 +57,13 @@ class NET_EXPORT DefaultOriginBoundCertStore : public OriginBoundCertStore { virtual bool GetOriginBoundCert( const std::string& origin, SSLClientCertType* type, + base::Time* expiration_time, std::string* private_key_result, std::string* cert_result) OVERRIDE; virtual void SetOriginBoundCert( const std::string& origin, SSLClientCertType type, + base::Time expiration_time, const std::string& private_key, const std::string& cert) OVERRIDE; virtual void DeleteOriginBoundCert(const std::string& origin) OVERRIDE; diff --git a/net/base/default_origin_bound_cert_store_unittest.cc b/net/base/default_origin_bound_cert_store_unittest.cc index 6b888e0..a62191a 100644 --- a/net/base/default_origin_bound_cert_store_unittest.cc +++ b/net/base/default_origin_bound_cert_store_unittest.cc @@ -77,40 +77,59 @@ TEST(DefaultOriginBoundCertStoreTest, TestLoading) { persistent_store->AddOriginBoundCert( DefaultOriginBoundCertStore::OriginBoundCert( - "https://encrypted.google.com/", CLIENT_CERT_RSA_SIGN, "a", "b")); + "https://encrypted.google.com/", + CLIENT_CERT_RSA_SIGN, + base::Time(), + "a", "b")); persistent_store->AddOriginBoundCert( DefaultOriginBoundCertStore::OriginBoundCert( - "https://www.verisign.com/", CLIENT_CERT_ECDSA_SIGN, "c", "d")); + "https://www.verisign.com/", + CLIENT_CERT_ECDSA_SIGN, + base::Time(), + "c", "d")); // Make sure certs load properly. DefaultOriginBoundCertStore store(persistent_store.get()); EXPECT_EQ(2, store.GetCertCount()); store.SetOriginBoundCert( - "https://www.verisign.com/", CLIENT_CERT_RSA_SIGN, "e", "f"); + "https://www.verisign.com/", + CLIENT_CERT_RSA_SIGN, + base::Time(), + "e", "f"); EXPECT_EQ(2, store.GetCertCount()); store.SetOriginBoundCert( - "https://www.twitter.com/", CLIENT_CERT_RSA_SIGN, "g", "h"); + "https://www.twitter.com/", + CLIENT_CERT_RSA_SIGN, + base::Time(), + "g", "h"); EXPECT_EQ(3, store.GetCertCount()); } TEST(DefaultOriginBoundCertStoreTest, TestSettingAndGetting) { DefaultOriginBoundCertStore store(NULL); SSLClientCertType type; + base::Time expiration_time; std::string private_key, cert; EXPECT_EQ(0, store.GetCertCount()); EXPECT_FALSE(store.GetOriginBoundCert("https://www.verisign.com/", &type, + &expiration_time, &private_key, &cert)); EXPECT_TRUE(private_key.empty()); EXPECT_TRUE(cert.empty()); store.SetOriginBoundCert( - "https://www.verisign.com/", CLIENT_CERT_RSA_SIGN, "i", "j"); + "https://www.verisign.com/", + CLIENT_CERT_RSA_SIGN, + base::Time::FromInternalValue(123), + "i", "j"); EXPECT_TRUE(store.GetOriginBoundCert("https://www.verisign.com/", &type, + &expiration_time, &private_key, &cert)); EXPECT_EQ(CLIENT_CERT_RSA_SIGN, type); + EXPECT_EQ(123, expiration_time.ToInternalValue()); EXPECT_EQ("i", private_key); EXPECT_EQ("j", cert); } @@ -120,19 +139,28 @@ TEST(DefaultOriginBoundCertStoreTest, TestDuplicateCerts) { DefaultOriginBoundCertStore store(persistent_store.get()); SSLClientCertType type; + base::Time expiration_time; std::string private_key, cert; EXPECT_EQ(0, store.GetCertCount()); store.SetOriginBoundCert( - "https://www.verisign.com/", CLIENT_CERT_RSA_SIGN, "a", "b"); + "https://www.verisign.com/", + CLIENT_CERT_RSA_SIGN, + base::Time::FromInternalValue(123), + "a", "b"); store.SetOriginBoundCert( - "https://www.verisign.com/", CLIENT_CERT_ECDSA_SIGN, "c", "d"); + "https://www.verisign.com/", + CLIENT_CERT_ECDSA_SIGN, + base::Time::FromInternalValue(456), + "c", "d"); EXPECT_EQ(1, store.GetCertCount()); EXPECT_TRUE(store.GetOriginBoundCert("https://www.verisign.com/", &type, + &expiration_time, &private_key, &cert)); EXPECT_EQ(CLIENT_CERT_ECDSA_SIGN, type); + EXPECT_EQ(456, expiration_time.ToInternalValue()); EXPECT_EQ("c", private_key); EXPECT_EQ("d", cert); } @@ -143,11 +171,20 @@ TEST(DefaultOriginBoundCertStoreTest, TestDeleteAll) { EXPECT_EQ(0, store.GetCertCount()); store.SetOriginBoundCert( - "https://www.verisign.com/", CLIENT_CERT_RSA_SIGN, "a", "b"); + "https://www.verisign.com/", + CLIENT_CERT_RSA_SIGN, + base::Time(), + "a", "b"); store.SetOriginBoundCert( - "https://www.google.com/", CLIENT_CERT_RSA_SIGN, "c", "d"); + "https://www.google.com/", + CLIENT_CERT_RSA_SIGN, + base::Time(), + "c", "d"); store.SetOriginBoundCert( - "https://www.harvard.com/", CLIENT_CERT_RSA_SIGN, "e", "f"); + "https://www.harvard.com/", + CLIENT_CERT_RSA_SIGN, + base::Time(), + "e", "f"); EXPECT_EQ(3, store.GetCertCount()); store.DeleteAll(); @@ -159,28 +196,38 @@ TEST(DefaultOriginBoundCertStoreTest, TestDelete) { DefaultOriginBoundCertStore store(persistent_store.get()); SSLClientCertType type; + base::Time expiration_time; std::string private_key, cert; EXPECT_EQ(0, store.GetCertCount()); store.SetOriginBoundCert( - "https://www.verisign.com/", CLIENT_CERT_RSA_SIGN, "a", "b"); + "https://www.verisign.com/", + CLIENT_CERT_RSA_SIGN, + base::Time(), + "a", "b"); store.SetOriginBoundCert( - "https://www.google.com/", CLIENT_CERT_ECDSA_SIGN, "c", "d"); + "https://www.google.com/", + CLIENT_CERT_ECDSA_SIGN, + base::Time(), + "c", "d"); EXPECT_EQ(2, store.GetCertCount()); store.DeleteOriginBoundCert("https://www.verisign.com/"); EXPECT_EQ(1, store.GetCertCount()); EXPECT_FALSE(store.GetOriginBoundCert("https://www.verisign.com/", &type, + &expiration_time, &private_key, &cert)); EXPECT_TRUE(store.GetOriginBoundCert("https://www.google.com/", &type, + &expiration_time, &private_key, &cert)); store.DeleteOriginBoundCert("https://www.google.com/"); EXPECT_EQ(0, store.GetCertCount()); EXPECT_FALSE(store.GetOriginBoundCert("https://www.google.com/", &type, + &expiration_time, &private_key, &cert)); } @@ -191,13 +238,25 @@ TEST(DefaultOriginBoundCertStoreTest, TestGetAll) { EXPECT_EQ(0, store.GetCertCount()); store.SetOriginBoundCert( - "https://www.verisign.com/", CLIENT_CERT_RSA_SIGN, "a", "b"); + "https://www.verisign.com/", + CLIENT_CERT_RSA_SIGN, + base::Time(), + "a", "b"); store.SetOriginBoundCert( - "https://www.google.com/", CLIENT_CERT_ECDSA_SIGN, "c", "d"); + "https://www.google.com/", + CLIENT_CERT_ECDSA_SIGN, + base::Time(), + "c", "d"); store.SetOriginBoundCert( - "https://www.harvard.com/", CLIENT_CERT_RSA_SIGN, "e", "f"); + "https://www.harvard.com/", + CLIENT_CERT_RSA_SIGN, + base::Time(), + "e", "f"); store.SetOriginBoundCert( - "https://www.mit.com/", CLIENT_CERT_RSA_SIGN, "g", "h"); + "https://www.mit.com/", + CLIENT_CERT_RSA_SIGN, + base::Time(), + "g", "h"); EXPECT_EQ(4, store.GetCertCount()); std::vector<OriginBoundCertStore::OriginBoundCert> certs; diff --git a/net/base/origin_bound_cert_service.cc b/net/base/origin_bound_cert_service.cc index 762255f..246383e 100644 --- a/net/base/origin_bound_cert_service.cc +++ b/net/base/origin_bound_cert_service.cc @@ -134,6 +134,7 @@ class OriginBoundCertServiceWorker { error_ = OriginBoundCertService::GenerateCert(origin_, type_, serial_number_, + &expiration_time_, &private_key_, &cert_); #if defined(USE_NSS) @@ -159,8 +160,8 @@ class OriginBoundCertServiceWorker { // memory leaks or worse errors. base::AutoLock locked(lock_); if (!canceled_) { - origin_bound_cert_service_->HandleResult(origin_, error_, type_, - private_key_, cert_); + origin_bound_cert_service_->HandleResult( + origin_, error_, type_, expiration_time_, private_key_, cert_); } } delete this; @@ -208,6 +209,7 @@ class OriginBoundCertServiceWorker { bool canceled_; int error_; + base::Time expiration_time_; std::string private_key_; std::string cert_; @@ -322,20 +324,26 @@ int OriginBoundCertService::GetOriginBoundCert( requests_++; // Check if an origin bound cert of an acceptable type already exists for this - // origin. + // origin, and that it has not expired. + base::Time now = base::Time::Now(); + base::Time expiration_time; if (origin_bound_cert_store_->GetOriginBoundCert(origin, type, + &expiration_time, private_key, cert)) { - if (IsSupportedCertType(*type) && - std::find(requested_types.begin(), requested_types.end(), *type) != - requested_types.end()) { + if (expiration_time < now) { + DVLOG(1) << "Cert store had expired cert for " << origin; + } else if (!IsSupportedCertType(*type) || + std::find(requested_types.begin(), requested_types.end(), + *type) == requested_types.end()) { + DVLOG(1) << "Cert store had cert of wrong type " << *type << " for " + << origin; + } else { cert_store_hits_++; *out_req = NULL; return OK; } - DVLOG(1) << "Cert store had cert of wrong type " << *type << " for " - << origin; } // |origin_bound_cert_store_| has no cert for this origin. See if an @@ -363,8 +371,10 @@ int OriginBoundCertService::GetOriginBoundCert( inflight_joins_++; } else { // Need to make a new request. - OriginBoundCertServiceWorker* worker = - new OriginBoundCertServiceWorker(origin, preferred_type, this); + OriginBoundCertServiceWorker* worker = new OriginBoundCertServiceWorker( + origin, + preferred_type, + this); job = new OriginBoundCertServiceJob(worker, preferred_type); if (!worker->Start()) { delete job; @@ -388,8 +398,12 @@ int OriginBoundCertService::GetOriginBoundCert( int OriginBoundCertService::GenerateCert(const std::string& origin, SSLClientCertType type, uint32 serial_number, + base::Time* expiration_time, std::string* private_key, std::string* cert) { + base::Time now = base::Time::Now(); + base::Time not_valid_after = + now + base::TimeDelta::FromDays(kValidityPeriodInDays); std::string der_cert; std::vector<uint8> private_key_info; switch (type) { @@ -404,7 +418,8 @@ int OriginBoundCertService::GenerateCert(const std::string& origin, key.get(), origin, serial_number, - base::TimeDelta::FromDays(kValidityPeriodInDays), + now, + not_valid_after, &der_cert)) { DLOG(ERROR) << "Unable to create x509 cert for client"; return ERR_ORIGIN_BOUND_CERT_GENERATION_FAILED; @@ -426,7 +441,8 @@ int OriginBoundCertService::GenerateCert(const std::string& origin, key.get(), origin, serial_number, - base::TimeDelta::FromDays(kValidityPeriodInDays), + now, + not_valid_after, &der_cert)) { DLOG(ERROR) << "Unable to create x509 cert for client"; return ERR_ORIGIN_BOUND_CERT_GENERATION_FAILED; @@ -450,6 +466,7 @@ int OriginBoundCertService::GenerateCert(const std::string& origin, private_key->swap(key_out); cert->swap(der_cert); + *expiration_time = not_valid_after; return OK; } @@ -465,11 +482,13 @@ void OriginBoundCertService::CancelRequest(RequestHandle req) { void OriginBoundCertService::HandleResult(const std::string& origin, int error, SSLClientCertType type, + base::Time expiration_time, const std::string& private_key, const std::string& cert) { DCHECK(CalledOnValidThread()); - origin_bound_cert_store_->SetOriginBoundCert(origin, type, private_key, cert); + origin_bound_cert_store_->SetOriginBoundCert( + origin, type, expiration_time, private_key, cert); std::map<std::string, OriginBoundCertServiceJob*>::iterator j; j = inflight_.find(origin); diff --git a/net/base/origin_bound_cert_service.h b/net/base/origin_bound_cert_service.h index c3861e6..0f78260 100644 --- a/net/base/origin_bound_cert_service.h +++ b/net/base/origin_bound_cert_service.h @@ -12,6 +12,7 @@ #include "base/basictypes.h" #include "base/memory/scoped_ptr.h" +#include "base/time.h" #include "base/threading/non_thread_safe.h" #include "net/base/completion_callback.h" #include "net/base/net_export.h" @@ -86,7 +87,8 @@ class NET_EXPORT OriginBoundCertService friend class OriginBoundCertServiceWorker; // Calls HandleResult. // On success, |private_key| stores a DER-encoded PrivateKeyInfo - // struct, and |cert| stores a DER-encoded certificate. Returns + // struct, |cert| stores a DER-encoded certificate, and |expiration_time| + // stores the expiration time of the certificate. Returns // OK if successful and an error code otherwise. // |serial_number| is passed in because it is created with the function // base::RandInt, which opens the file /dev/urandom. /dev/urandom is opened @@ -94,12 +96,14 @@ class NET_EXPORT OriginBoundCertService static int GenerateCert(const std::string& origin, SSLClientCertType type, uint32 serial_number, + base::Time* expiration_time, std::string* private_key, std::string* cert); void HandleResult(const std::string& origin, int error, SSLClientCertType type, + base::Time expiration_time, const std::string& private_key, const std::string& cert); diff --git a/net/base/origin_bound_cert_service_unittest.cc b/net/base/origin_bound_cert_service_unittest.cc index 1adedfa..65f40a5 100644 --- a/net/base/origin_bound_cert_service_unittest.cc +++ b/net/base/origin_bound_cert_service_unittest.cc @@ -457,6 +457,56 @@ TEST(OriginBoundCertServiceTest, CancelRequest) { EXPECT_EQ(6, service->cert_count()); } +TEST(OriginBoundCertServiceTest, Expiration) { + OriginBoundCertStore* store = new DefaultOriginBoundCertStore(NULL); + store->SetOriginBoundCert("https://good", + CLIENT_CERT_RSA_SIGN, + base::Time::Now() + base::TimeDelta::FromDays(1), + "a", + "b"); + store->SetOriginBoundCert("https://expired", + CLIENT_CERT_RSA_SIGN, + base::Time::Now() - base::TimeDelta::FromDays(1), + "c", + "d"); + OriginBoundCertService service(store); + EXPECT_EQ(2, service.cert_count()); + + int error; + std::vector<uint8> types; + types.push_back(CLIENT_CERT_RSA_SIGN); + TestCompletionCallback callback; + OriginBoundCertService::RequestHandle request_handle; + + // Cert still valid - synchronous completion. + SSLClientCertType type1; + std::string private_key_info1, der_cert1; + error = service.GetOriginBoundCert( + "https://good", types, &type1, &private_key_info1, &der_cert1, + callback.callback(), &request_handle); + EXPECT_EQ(OK, error); + EXPECT_TRUE(request_handle == NULL); + EXPECT_EQ(2, service.cert_count()); + EXPECT_EQ(CLIENT_CERT_RSA_SIGN, type1); + EXPECT_STREQ("a", private_key_info1.c_str()); + EXPECT_STREQ("b", der_cert1.c_str()); + + // Cert expired - New cert will be generated, asynchronous completion. + SSLClientCertType type2; + std::string private_key_info2, der_cert2; + error = service.GetOriginBoundCert( + "https://expired", types, &type2, &private_key_info2, &der_cert2, + callback.callback(), &request_handle); + EXPECT_EQ(ERR_IO_PENDING, error); + EXPECT_TRUE(request_handle != NULL); + error = callback.WaitForResult(); + EXPECT_EQ(OK, error); + EXPECT_EQ(2, service.cert_count()); + EXPECT_EQ(CLIENT_CERT_RSA_SIGN, type2); + EXPECT_LT(1U, private_key_info2.size()); + EXPECT_LT(1U, der_cert2.size()); +} + #endif // !defined(USE_OPENSSL) } // namespace diff --git a/net/base/origin_bound_cert_store.cc b/net/base/origin_bound_cert_store.cc index fe2b45f..6a31a7e 100644 --- a/net/base/origin_bound_cert_store.cc +++ b/net/base/origin_bound_cert_store.cc @@ -13,10 +13,12 @@ OriginBoundCertStore::OriginBoundCert::OriginBoundCert() OriginBoundCertStore::OriginBoundCert::OriginBoundCert( const std::string& origin, SSLClientCertType type, + base::Time expiration_time, const std::string& private_key, const std::string& cert) : origin_(origin), type_(type), + expiration_time_(expiration_time), private_key_(private_key), cert_(cert) {} diff --git a/net/base/origin_bound_cert_store.h b/net/base/origin_bound_cert_store.h index 094839b..1eb8382 100644 --- a/net/base/origin_bound_cert_store.h +++ b/net/base/origin_bound_cert_store.h @@ -9,6 +9,7 @@ #include <string> #include <vector> +#include "base/time.h" #include "net/base/net_export.h" #include "net/base/ssl_client_cert_type.h" @@ -30,6 +31,7 @@ class NET_EXPORT OriginBoundCertStore { OriginBoundCert(); OriginBoundCert(const std::string& origin, SSLClientCertType type, + base::Time expiration_time, const std::string& private_key, const std::string& cert); ~OriginBoundCert(); @@ -38,6 +40,8 @@ class NET_EXPORT OriginBoundCertStore { const std::string& origin() const { return origin_; } // TLS ClientCertificateType. SSLClientCertType type() const { return type_; } + // The time after which this certificate is no longer valid. + base::Time expiration_time() const { return expiration_time_; } // The encoding of the private key depends on the type. // rsa_sign: DER-encoded PrivateKeyInfo struct. // ecdsa_sign: DER-encoded EncryptedPrivateKeyInfo struct. @@ -48,6 +52,7 @@ class NET_EXPORT OriginBoundCertStore { private: std::string origin_; SSLClientCertType type_; + base::Time expiration_time_; std::string private_key_; std::string cert_; }; @@ -57,12 +62,14 @@ class NET_EXPORT OriginBoundCertStore { // TODO(rkn): File I/O may be required, so this should have an asynchronous // interface. // Returns true on success. |private_key_result| stores a DER-encoded - // PrivateKeyInfo struct and |cert_result| stores a DER-encoded - // certificate. Returns false if no origin bound cert exists for the - // specified origin. + // PrivateKeyInfo struct, |cert_result| stores a DER-encoded certificate, + // |type| is the ClientCertificateType of the returned certificate, and + // |expiration_time| is the expiration time of the certificate. + // Returns false if no origin bound cert exists for the specified origin. virtual bool GetOriginBoundCert( const std::string& origin, SSLClientCertType* type, + base::Time* expiration_time, std::string* private_key_result, std::string* cert_result) = 0; @@ -70,6 +77,7 @@ class NET_EXPORT OriginBoundCertStore { virtual void SetOriginBoundCert( const std::string& origin, SSLClientCertType type, + base::Time expiration_time, const std::string& private_key, const std::string& cert) = 0; diff --git a/net/base/x509_certificate_nss.cc b/net/base/x509_certificate_nss.cc index 39f2a94..b4bf88d 100644 --- a/net/base/x509_certificate_nss.cc +++ b/net/base/x509_certificate_nss.cc @@ -778,11 +778,14 @@ X509Certificate* X509Certificate::CreateSelfSigned( base::TimeDelta valid_duration) { DCHECK(key); + base::Time not_valid_before = base::Time::Now(); + base::Time not_valid_after = not_valid_before + valid_duration; CERTCertificate* cert = x509_util::CreateSelfSignedCert(key->public_key(), key->key(), subject, serial_number, - valid_duration); + not_valid_before, + not_valid_after); if (!cert) return NULL; diff --git a/net/base/x509_util.h b/net/base/x509_util.h index 1d8c933..b35d274 100644 --- a/net/base/x509_util.h +++ b/net/base/x509_util.h @@ -30,12 +30,14 @@ namespace x509_util { bool NET_EXPORT_PRIVATE CreateOriginBoundCertRSA(crypto::RSAPrivateKey* key, const std::string& origin, uint32 serial_number, - base::TimeDelta valid_duration, + base::Time not_valid_before, + base::Time not_valid_after, std::string* der_cert); bool NET_EXPORT_PRIVATE CreateOriginBoundCertEC(crypto::ECPrivateKey* key, const std::string& origin, uint32 serial_number, - base::TimeDelta valid_duration, + base::Time not_valid_before, + base::Time not_valid_after, std::string* der_cert); } // namespace x509_util diff --git a/net/base/x509_util_nss.cc b/net/base/x509_util_nss.cc index 61126af..3f630e2 100644 --- a/net/base/x509_util_nss.cc +++ b/net/base/x509_util_nss.cc @@ -78,7 +78,8 @@ CERTCertificate* CreateCertificate( SECKEYPublicKey* public_key, const std::string& subject, uint32 serial_number, - base::TimeDelta valid_duration) { + base::Time not_valid_before, + base::Time not_valid_after) { // Create info about public key. CERTSubjectPublicKeyInfo* spki = SECKEY_CreateSubjectPublicKeyInfo(public_key); @@ -99,11 +100,9 @@ CERTCertificate* CreateCertificate( return NULL; } - PRTime now = PR_Now(); - PRTime not_after = now + valid_duration.InMicroseconds(); - - // Note that the time is now in micro-second unit. - CERTValidity* validity = CERT_CreateValidity(now, not_after); + CERTValidity* validity = CERT_CreateValidity( + crypto::BaseTimeToPRTime(not_valid_before), + crypto::BaseTimeToPRTime(not_valid_after)); CERTCertificate* cert = CERT_CreateCertificate(serial_number, subject_name, validity, cert_request); if (!cert) { @@ -176,13 +175,15 @@ bool CreateOriginBoundCertInternal( SECKEYPrivateKey* private_key, const std::string& origin, uint32 serial_number, - base::TimeDelta valid_duration, + base::Time not_valid_before, + base::Time not_valid_after, std::string* der_cert) { CERTCertificate* cert = CreateCertificate(public_key, "CN=anonymous.invalid", serial_number, - valid_duration); + not_valid_before, + not_valid_after); if (!cert) return false; @@ -254,11 +255,13 @@ CERTCertificate* CreateSelfSignedCert( SECKEYPrivateKey* private_key, const std::string& subject, uint32 serial_number, - base::TimeDelta valid_duration) { + base::Time not_valid_before, + base::Time not_valid_after) { CERTCertificate* cert = CreateCertificate(public_key, subject, serial_number, - valid_duration); + not_valid_before, + not_valid_after); if (!cert) return NULL; @@ -274,7 +277,8 @@ bool CreateOriginBoundCertRSA( crypto::RSAPrivateKey* key, const std::string& origin, uint32 serial_number, - base::TimeDelta valid_duration, + base::Time not_valid_before, + base::Time not_valid_after, std::string* der_cert) { DCHECK(key); @@ -329,7 +333,8 @@ bool CreateOriginBoundCertRSA( private_key, origin, serial_number, - valid_duration, + not_valid_before, + not_valid_after, der_cert); } @@ -337,14 +342,16 @@ bool CreateOriginBoundCertEC( crypto::ECPrivateKey* key, const std::string& origin, uint32 serial_number, - base::TimeDelta valid_duration, + base::Time not_valid_before, + base::Time not_valid_after, std::string* der_cert) { DCHECK(key); return CreateOriginBoundCertInternal(key->public_key(), key->key(), origin, serial_number, - valid_duration, + not_valid_before, + not_valid_after, der_cert); } diff --git a/net/base/x509_util_nss.h b/net/base/x509_util_nss.h index 82dd4f9..b5cc503 100644 --- a/net/base/x509_util_nss.h +++ b/net/base/x509_util_nss.h @@ -28,7 +28,8 @@ CERTCertificate* CreateSelfSignedCert( SECKEYPrivateKey* private_key, const std::string& subject, uint32 serial_number, - base::TimeDelta valid_duration); + base::Time not_valid_before, + base::Time not_valid_after); } // namespace x509_util diff --git a/net/base/x509_util_nss_unittest.cc b/net/base/x509_util_nss_unittest.cc index 7490874..1dc2cd2 100644 --- a/net/base/x509_util_nss_unittest.cc +++ b/net/base/x509_util_nss_unittest.cc @@ -145,14 +145,17 @@ void VerifyOriginBoundCert(const std::string& origin, TEST(X509UtilNSSTest, CreateOriginBoundCertRSA) { // Create a sample ASCII weborigin. std::string origin = "http://weborigin.com:443"; + base::Time now = base::Time::Now(); scoped_ptr<crypto::RSAPrivateKey> private_key( crypto::RSAPrivateKey::Create(1024)); std::string der_cert; - ASSERT_TRUE(x509_util::CreateOriginBoundCertRSA(private_key.get(), - origin, 1, - base::TimeDelta::FromDays(1), - &der_cert)); + ASSERT_TRUE(x509_util::CreateOriginBoundCertRSA( + private_key.get(), + origin, 1, + now, + now + base::TimeDelta::FromDays(1), + &der_cert)); VerifyOriginBoundCert(origin, der_cert); @@ -166,14 +169,17 @@ TEST(X509UtilNSSTest, CreateOriginBoundCertRSA) { TEST(X509UtilNSSTest, CreateOriginBoundCertEC) { // Create a sample ASCII weborigin. std::string origin = "http://weborigin.com:443"; + base::Time now = base::Time::Now(); scoped_ptr<crypto::ECPrivateKey> private_key( crypto::ECPrivateKey::Create()); std::string der_cert; - ASSERT_TRUE(x509_util::CreateOriginBoundCertEC(private_key.get(), - origin, 1, - base::TimeDelta::FromDays(1), - &der_cert)); + ASSERT_TRUE(x509_util::CreateOriginBoundCertEC( + private_key.get(), + origin, 1, + now, + now + base::TimeDelta::FromDays(1), + &der_cert)); VerifyOriginBoundCert(origin, der_cert); diff --git a/net/base/x509_util_openssl.cc b/net/base/x509_util_openssl.cc index e663b95..786dd86 100644 --- a/net/base/x509_util_openssl.cc +++ b/net/base/x509_util_openssl.cc @@ -19,7 +19,8 @@ bool CreateOriginBoundCertRSA( crypto::RSAPrivateKey* key, const std::string& origin, uint32 serial_number, - base::TimeDelta valid_duration, + base::Time not_valid_before, + base::Time not_valid_after, std::string* der_cert) { NOTIMPLEMENTED(); return false; @@ -29,7 +30,8 @@ bool CreateOriginBoundCertEC( crypto::ECPrivateKey* key, const std::string& origin, uint32 serial_number, - base::TimeDelta valid_duration, + base::Time not_valid_before, + base::Time not_valid_after, std::string* der_cert) { NOTIMPLEMENTED(); return false; diff --git a/net/base/x509_util_openssl_unittest.cc b/net/base/x509_util_openssl_unittest.cc index 23c33a3..5d96dfa 100644 --- a/net/base/x509_util_openssl_unittest.cc +++ b/net/base/x509_util_openssl_unittest.cc @@ -15,13 +15,16 @@ namespace net { // is present. TEST(X509UtilOpenSSLTest, CreateOriginBoundCertNotImplemented) { std::string origin = "http://weborigin.com:443"; + base::Time now = base::Time::Now(); scoped_ptr<crypto::RSAPrivateKey> private_key( crypto::RSAPrivateKey::Create(1024)); std::string der_cert; - EXPECT_FALSE(x509_util::CreateOriginBoundCertRSA(private_key.get(), - origin, 1, - base::TimeDelta::FromDays(1), - &der_cert)); + EXPECT_FALSE(x509_util::CreateOriginBoundCertRSA( + private_key.get(), + origin, 1, + now, + now + base::TimeDelta::FromDays(1), + &der_cert)); EXPECT_TRUE(der_cert.empty()); } |