diff options
author | avi@google.com <avi@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2008-09-22 14:48:39 +0000 |
---|---|---|
committer | avi@google.com <avi@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2008-09-22 14:48:39 +0000 |
commit | 9bbb0b88f274f767358644dd97b1ee0c9604010b (patch) | |
tree | 7fc08817df3ebcfbbb1426a48cee714ed43cd747 | |
parent | 5da98afcd7ce538f44d4123b63d14eb6110f57d8 (diff) | |
download | chromium_src-9bbb0b88f274f767358644dd97b1ee0c9604010b.zip chromium_src-9bbb0b88f274f767358644dd97b1ee0c9604010b.tar.gz chromium_src-9bbb0b88f274f767358644dd97b1ee0c9604010b.tar.bz2 |
Unit test now runs on the Mac.
Review URL: http://codereview.chromium.org/3000
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@2440 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r-- | net/base/x509_certificate.h | 11 | ||||
-rw-r--r-- | net/base/x509_certificate_mac.cc | 79 | ||||
-rw-r--r-- | net/base/x509_certificate_unittest.cc | 7 | ||||
-rw-r--r-- | net/net.xcodeproj/project.pbxproj | 12 |
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; }; |