summaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
Diffstat (limited to 'net')
-rw-r--r--net/base/x509_certificate.h11
-rw-r--r--net/base/x509_certificate_mac.cc79
-rw-r--r--net/base/x509_certificate_unittest.cc7
-rw-r--r--net/net.xcodeproj/project.pbxproj12
4 files changed, 84 insertions, 25 deletions
diff --git a/net/base/x509_certificate.h b/net/base/x509_certificate.h
index 763084b..c9f872a 100644
--- a/net/base/x509_certificate.h
+++ b/net/base/x509_certificate.h
@@ -137,7 +137,6 @@ class X509Certificate : public base::RefCountedThreadSafe<X509Certificate> {
// The issuer of the certificate.
const Principal& issuer() const { return issuer_; }
-#if defined(OS_WIN)
// Time period during which the certificate is valid. More precisely, this
// certificate is invalid before the |valid_start| date and invalid after
// the |valid_expiry| date.
@@ -145,12 +144,6 @@ class X509Certificate : public base::RefCountedThreadSafe<X509Certificate> {
// lacks either date), the date will be null (i.e., is_null() will be true).
const Time& valid_start() const { return valid_start_; }
const Time& valid_expiry() const { return valid_expiry_; }
-#elif defined(OS_MACOSX)
- // These are used only for some UI, where HasExpired is used to disambiguate a
- // time error on the certificate as a "too old" or "too young" error. On the
- // Mac you get different codes for those. There's no easy way of pulling dates
- // out of the cert short of CSSM, so these remain unimplemented for now.
-#endif
// The fingerprint of this certificate.
const Fingerprint& fingerprint() const { return fingerprint_; }
@@ -161,11 +154,9 @@ class X509Certificate : public base::RefCountedThreadSafe<X509Certificate> {
// Otherwise, it gets the common name in the subject field.
void GetDNSNames(std::vector<std::string>* dns_names) const;
-#if defined(OS_WIN)
// Convenience method that returns whether this certificate has expired as of
// now.
bool HasExpired() const;
-#endif
// Returns true if the certificate is an extended-validation (EV)
// certificate.
@@ -200,13 +191,11 @@ class X509Certificate : public base::RefCountedThreadSafe<X509Certificate> {
// The issuer of the certificate.
Principal issuer_;
-#if defined(OS_WIN)
// This certificate is not valid before |valid_start_|
Time valid_start_;
// This certificate is not valid after |valid_expiry_|
Time valid_expiry_;
-#endif
// The fingerprint of this certificate.
Fingerprint fingerprint_;
diff --git a/net/base/x509_certificate_mac.cc b/net/base/x509_certificate_mac.cc
index 66e491a..d8915a4 100644
--- a/net/base/x509_certificate_mac.cc
+++ b/net/base/x509_certificate_mac.cc
@@ -6,6 +6,7 @@
#include <CommonCrypto/CommonDigest.h>
#include <map>
+#include <time.h>
#include "base/histogram.h"
#include "base/lock.h"
@@ -119,23 +120,33 @@ void ParsePrincipal(const CSSM_X509_NAME* name,
}
}
-void GetCertFieldsForOID(X509Certificate::OSCertHandle cert_handle,
- CSSM_OID oid,
- std::vector<std::string>* result) {
+OSStatus GetCertFieldsForOID(X509Certificate::OSCertHandle cert_handle,
+ CSSM_OID oid, uint32* num_of_fields,
+ CSSM_FIELD_PTR* fields) {
+ *num_of_fields = 0;
+ *fields = NULL;
+
CSSM_DATA cert_data;
OSStatus status = SecCertificateGetData(cert_handle, &cert_data);
if (status)
- return;
+ return status;
CSSM_CL_HANDLE cl_handle;
status = SecCertificateGetCLHandle(cert_handle, &cl_handle);
if (status)
- return;
+ return status;
+ status = CSSM_CL_CertGetAllFields(cl_handle, &cert_data, num_of_fields,
+ fields);
+ return status;
+}
+
+void GetCertStringsForOID(X509Certificate::OSCertHandle cert_handle,
+ CSSM_OID oid, std::vector<std::string>* result) {
uint32 num_of_fields;
CSSM_FIELD_PTR fields;
- status = CSSM_CL_CertGetAllFields(cl_handle, &cert_data, &num_of_fields,
- &fields);
+ OSStatus status = GetCertFieldsForOID(cert_handle, oid, &num_of_fields,
+ &fields);
if (status)
return;
@@ -150,6 +161,49 @@ void GetCertFieldsForOID(X509Certificate::OSCertHandle cert_handle,
}
}
+void GetCertDateForOID(X509Certificate::OSCertHandle cert_handle,
+ CSSM_OID oid, Time* result) {
+ uint32 num_of_fields;
+ CSSM_FIELD_PTR fields;
+ OSStatus status = GetCertFieldsForOID(cert_handle, oid, &num_of_fields,
+ &fields);
+ if (status)
+ return;
+
+ for (size_t field = 0; field < num_of_fields; ++field) {
+ if (CSSMOIDEqual(&fields[field].FieldOid, &oid)) {
+ CSSM_X509_TIME *x509_time =
+ reinterpret_cast<CSSM_X509_TIME *>(fields[field].FieldValue.Data);
+ std::string time_string =
+ std::string(reinterpret_cast<std::string::value_type*>
+ (x509_time->time.Data),
+ x509_time->time.Length);
+
+ struct tm time;
+ const char *parse_string;
+ if (x509_time->timeType == BER_TAG_UTC_TIME)
+ parse_string = "%y%m%d%H%M%SZ";
+ else if (x509_time->timeType == BER_TAG_GENERALIZED_TIME)
+ parse_string = "%y%m%d%H%M%SZ";
+ // else log?
+
+ strptime(time_string.c_str(), parse_string, &time);
+
+ Time::Exploded exploded;
+ exploded.year = time.tm_year + 1900;
+ exploded.month = time.tm_mon + 1;
+ exploded.day_of_week = time.tm_wday;
+ exploded.day_of_month = time.tm_mday;
+ exploded.hour = time.tm_hour;
+ exploded.minute = time.tm_min;
+ exploded.second = time.tm_sec;
+ exploded.millisecond = 0;
+
+ *result = Time::FromUTCExploded(exploded);
+ }
+ }
+}
+
} // namespace
bool X509Certificate::FingerprintLessThan::operator()(
@@ -247,6 +301,11 @@ void X509Certificate::Initialize() {
ParsePrincipal(name, &issuer_);
}
+ GetCertDateForOID(cert_handle_, CSSMOID_X509V1ValidityNotBefore,
+ &valid_start_);
+ GetCertDateForOID(cert_handle_, CSSMOID_X509V1ValidityNotAfter,
+ &valid_expiry_);
+
fingerprint_ = CalculateFingerprint(cert_handle_);
// Store the certificate in the cache in case we need it later.
@@ -306,9 +365,11 @@ X509Certificate::X509Certificate(OSCertHandle cert_handle)
}
X509Certificate::X509Certificate(std::string subject, std::string issuer,
- Time, Time)
+ Time start_date, Time expiration_date)
: subject_(subject),
issuer_(issuer),
+ valid_start_(start_date),
+ valid_expiry_(expiration_date),
cert_handle_(NULL) {
memset(fingerprint_.data, 0, sizeof(fingerprint_.data));
}
@@ -334,7 +395,7 @@ X509Certificate::~X509Certificate() {
void X509Certificate::GetDNSNames(std::vector<std::string>* dns_names) const {
dns_names->clear();
- GetCertFieldsForOID(cert_handle_, CSSMOID_SubjectAltName, dns_names);
+ GetCertStringsForOID(cert_handle_, CSSMOID_SubjectAltName, dns_names);
// TODO(avi): wtc says we need more parsing here. Return and fix when the
// unit tests are complete and we can verify we're doing this right.
diff --git a/net/base/x509_certificate_unittest.cc b/net/base/x509_certificate_unittest.cc
index d9f31b7..4a61562 100644
--- a/net/base/x509_certificate_unittest.cc
+++ b/net/base/x509_certificate_unittest.cc
@@ -97,7 +97,7 @@ unsigned char google_fingerprint[] = {
using net::X509Certificate;
-TEST(X509CertificateTest, BasicParsing) {
+TEST(X509CertificateTest, GoogleCertParsing) {
X509Certificate *google_cert = X509Certificate::CreateFromBytes(
reinterpret_cast<const char*>(google_der), sizeof(google_der));
@@ -125,11 +125,12 @@ TEST(X509CertificateTest, BasicParsing) {
EXPECT_EQ(0U, issuer.organization_unit_names.size());
EXPECT_EQ(0U, issuer.domain_components.size());
+ // Use DoubleT because its epoch is the same on all platforms
const Time& valid_start = google_cert->valid_start();
- EXPECT_EQ(GG_LONGLONG(12854221375000000), valid_start.ToInternalValue());
+ EXPECT_EQ(1209747775, valid_start.ToDoubleT());
const Time& valid_expiry = google_cert->valid_expiry();
- EXPECT_EQ(GG_LONGLONG(12885757375000000), valid_expiry.ToInternalValue());
+ EXPECT_EQ(1241283775, valid_expiry.ToDoubleT());
const X509Certificate::Fingerprint& fingerprint = google_cert->fingerprint();
for (size_t i = 0; i < 20; ++i)
diff --git a/net/net.xcodeproj/project.pbxproj b/net/net.xcodeproj/project.pbxproj
index ca6a360..0eae425 100644
--- a/net/net.xcodeproj/project.pbxproj
+++ b/net/net.xcodeproj/project.pbxproj
@@ -110,6 +110,8 @@
7BED34450E5A1A9600A747DB /* libbase.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 7BED324A0E5A17C000A747DB /* libbase.a */; };
7BED34520E5A1ABC00A747DB /* libgtest.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 7BED32530E5A17C300A747DB /* libgtest.a */; };
8200F2030E5F741E005A3C44 /* CoreServices.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8200F2020E5F741E005A3C44 /* CoreServices.framework */; };
+ 82113A1D0E8434EE00E3848F /* x509_certificate_unittest.cc in Sources */ = {isa = PBXBuildFile; fileRef = 82113A1C0E8434EE00E3848F /* x509_certificate_unittest.cc */; };
+ 82113A280E84360200E3848F /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 82113A270E84360200E3848F /* Security.framework */; };
821F207B0E5CD342003C7E38 /* cert_status_cache.cc in Sources */ = {isa = PBXBuildFile; fileRef = 7BED33610E5A194700A747DB /* cert_status_cache.cc */; };
821F207F0E5CD3C6003C7E38 /* http_vary_data.cc in Sources */ = {isa = PBXBuildFile; fileRef = 7BED33520E5A194700A747DB /* http_vary_data.cc */; };
821F20A30E5CD407003C7E38 /* mime_sniffer_proxy.cc in Sources */ = {isa = PBXBuildFile; fileRef = 7BED33A60E5A198600A747DB /* mime_sniffer_proxy.cc */; };
@@ -136,14 +138,14 @@
isa = PBXContainerItemProxy;
containerPortal = 7B2630600E82F282001CE27F /* libevent.xcodeproj */;
proxyType = 2;
- remoteGlobalIDString = 7B262E840E82E5D7001CE27F /* libevent.a */;
+ remoteGlobalIDString = 7B262E840E82E5D7001CE27F;
remoteInfo = libevent;
};
7B2630660E82F291001CE27F /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 7B2630600E82F282001CE27F /* libevent.xcodeproj */;
proxyType = 1;
- remoteGlobalIDString = 7B262E830E82E5D7001CE27F /* libevent */;
+ remoteGlobalIDString = 7B262E830E82E5D7001CE27F;
remoteInfo = libevent;
};
7B8501FD0E5A372500730B43 /* PBXContainerItemProxy */ = {
@@ -584,6 +586,8 @@
7BED33BB0E5A198600A747DB /* url_request_inet_job.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = url_request_inet_job.cc; sourceTree = "<group>"; };
7BED33BC0E5A198600A747DB /* url_request_http_job.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = url_request_http_job.h; sourceTree = "<group>"; };
8200F2020E5F741E005A3C44 /* CoreServices.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreServices.framework; path = /System/Library/Frameworks/CoreServices.framework; sourceTree = "<absolute>"; };
+ 82113A1C0E8434EE00E3848F /* x509_certificate_unittest.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = x509_certificate_unittest.cc; sourceTree = "<group>"; };
+ 82113A270E84360200E3848F /* Security.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Security.framework; path = /System/Library/Frameworks/Security.framework; sourceTree = "<absolute>"; };
E4AFA6230E523E2900201347 /* net_unittests */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = net_unittests; sourceTree = BUILT_PRODUCTS_DIR; };
E4AFA62E0E5240A300201347 /* gtest.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = gtest.xcodeproj; path = testing/gtest.xcodeproj; sourceTree = "<group>"; };
E4AFA6420E5241B400201347 /* run_all_unittests.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = run_all_unittests.cc; sourceTree = "<group>"; };
@@ -616,6 +620,7 @@
7B85026D0E5A38D400730B43 /* libmodp_b64.a in Frameworks */,
7BED34190E5A1A8600A747DB /* libnet.a in Frameworks */,
7BA0169E0E5A1EAE00044150 /* libzlib.a in Frameworks */,
+ 82113A280E84360200E3848F /* Security.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -715,6 +720,7 @@
7BED31A20E5A15DD00A747DB /* Frameworks */ = {
isa = PBXGroup;
children = (
+ 82113A270E84360200E3848F /* Security.framework */,
8200F2020E5F741E005A3C44 /* CoreServices.framework */,
7BA0157A0E5A1C9100044150 /* Foundation.framework */,
);
@@ -863,6 +869,7 @@
7BED32860E5A181C00A747DB /* upload_data_stream.h */,
7BED32800E5A181C00A747DB /* x509_certificate_mac.cc */,
7BED327F0E5A181C00A747DB /* x509_certificate.h */,
+ 82113A1C0E8434EE00E3848F /* x509_certificate_unittest.cc */,
);
path = base;
sourceTree = "<group>";
@@ -1354,6 +1361,7 @@
7B8B5B9E0E5D188E002F9A97 /* registry_controlled_domain_unittest.cc in Sources */,
E4AFA6430E5241B400201347 /* run_all_unittests.cc in Sources */,
7BD8F7110E65DCF500034DE9 /* storage_block_unittest.cc in Sources */,
+ 82113A1D0E8434EE00E3848F /* x509_certificate_unittest.cc in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};