summaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authormattm@chromium.org <mattm@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-12-22 01:46:19 +0000
committermattm@chromium.org <mattm@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-12-22 01:46:19 +0000
commit4082fa2a9b307fc78675602bbcc0acade2029059 (patch)
treeaf99bc0b6de4414edea1b97af87316d203648095 /net
parent25142ecaf7ff6a2ade87625b34d715700cb7e68f (diff)
downloadchromium_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.cc6
-rw-r--r--net/base/default_origin_bound_cert_store.h2
-rw-r--r--net/base/default_origin_bound_cert_store_unittest.cc91
-rw-r--r--net/base/origin_bound_cert_service.cc45
-rw-r--r--net/base/origin_bound_cert_service.h6
-rw-r--r--net/base/origin_bound_cert_service_unittest.cc50
-rw-r--r--net/base/origin_bound_cert_store.cc2
-rw-r--r--net/base/origin_bound_cert_store.h14
-rw-r--r--net/base/x509_certificate_nss.cc5
-rw-r--r--net/base/x509_util.h6
-rw-r--r--net/base/x509_util_nss.cc35
-rw-r--r--net/base/x509_util_nss.h3
-rw-r--r--net/base/x509_util_nss_unittest.cc22
-rw-r--r--net/base/x509_util_openssl.cc6
-rw-r--r--net/base/x509_util_openssl_unittest.cc11
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());
}