Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(313)

Side by Side Diff: net/base/x509_certificate_mac.cc

Issue 18836: Work around our not caching the intermediate CA... (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: '' Created 11 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « net/base/x509_certificate.cc ('k') | net/base/x509_certificate_nss.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "net/base/x509_certificate.h" 5 #include "net/base/x509_certificate.h"
6 6
7 #include <CommonCrypto/CommonDigest.h> 7 #include <CommonCrypto/CommonDigest.h>
8 #include <time.h> 8 #include <time.h>
9 9
10 #include "base/histogram.h"
11 #include "base/logging.h" 10 #include "base/logging.h"
12 #include "base/pickle.h" 11 #include "base/pickle.h"
13 #include "net/base/cert_status_flags.h" 12 #include "net/base/cert_status_flags.h"
14 #include "net/base/ev_root_ca_metadata.h" 13 #include "net/base/ev_root_ca_metadata.h"
15 14
16 using base::Time; 15 using base::Time;
17 16
18 namespace net { 17 namespace net {
19 18
20 namespace { 19 namespace {
21 20
22 // Calculates the SHA-1 fingerprint of the certificate. Returns an empty
23 // (all zero) fingerprint on failure.
24 X509Certificate::Fingerprint CalculateFingerprint(
25 X509Certificate::OSCertHandle cert) {
26 X509Certificate::Fingerprint sha1;
27 memset(sha1.data, 0, sizeof(sha1.data));
28
29 CSSM_DATA cert_data;
30 OSStatus status = SecCertificateGetData(cert, &cert_data);
31 if (status)
32 return sha1;
33
34 DCHECK(NULL != cert_data.Data);
35 DCHECK(0 != cert_data.Length);
36
37 CC_SHA1(cert_data.Data, cert_data.Length, sha1.data);
38
39 return sha1;
40 }
41
42 inline bool CSSMOIDEqual(const CSSM_OID* oid1, const CSSM_OID* oid2) { 21 inline bool CSSMOIDEqual(const CSSM_OID* oid1, const CSSM_OID* oid2) {
43 return oid1->Length == oid2->Length && 22 return oid1->Length == oid2->Length &&
44 (memcmp(oid1->Data, oid2->Data, oid1->Length) == 0); 23 (memcmp(oid1->Data, oid2->Data, oid1->Length) == 0);
45 } 24 }
46 25
47 void ParsePrincipal(const CSSM_X509_NAME* name, 26 void ParsePrincipal(const CSSM_X509_NAME* name,
48 X509Certificate::Principal* principal) { 27 X509Certificate::Principal* principal) {
49 std::vector<std::string> common_names, locality_names, state_names, 28 std::vector<std::string> common_names, locality_names, state_names,
50 country_names; 29 country_names;
51 30
(...skipping 183 matching lines...) Expand 10 before | Expand all | Expand 10 after
235 GetCertDateForOID(cert_handle_, CSSMOID_X509V1ValidityNotAfter, 214 GetCertDateForOID(cert_handle_, CSSMOID_X509V1ValidityNotAfter,
236 &valid_expiry_); 215 &valid_expiry_);
237 216
238 fingerprint_ = CalculateFingerprint(cert_handle_); 217 fingerprint_ = CalculateFingerprint(cert_handle_);
239 218
240 // Store the certificate in the cache in case we need it later. 219 // Store the certificate in the cache in case we need it later.
241 X509Certificate::Cache::GetInstance()->Insert(this); 220 X509Certificate::Cache::GetInstance()->Insert(this);
242 } 221 }
243 222
244 // static 223 // static
245 X509Certificate* X509Certificate::CreateFromHandle(OSCertHandle cert_handle) {
246 DCHECK(cert_handle);
247
248 // Check if we already have this certificate in memory.
249 X509Certificate::Cache* cache = X509Certificate::Cache::GetInstance();
250 X509Certificate* cert = cache->Find(CalculateFingerprint(cert_handle));
251 if (cert) {
252 // We've found a certificate with the same fingerprint in our cache. We own
253 // the |cert_handle|, which makes it our job to free it.
254 CFRelease(cert_handle);
255 DHISTOGRAM_COUNTS(L"X509CertificateReuseCount", 1);
256 return cert;
257 }
258 // Otherwise, allocate a new object.
259 return new X509Certificate(cert_handle);
260 }
261
262 // static
263 X509Certificate* X509Certificate::CreateFromBytes(const char* data,
264 int length) {
265 CSSM_DATA cert_data;
266 cert_data.Data = const_cast<uint8*>(reinterpret_cast<const uint8*>(data));
267 cert_data.Length = length;
268
269 OSCertHandle cert_handle = NULL;
270 OSStatus status = SecCertificateCreateFromData(&cert_data,
271 CSSM_CERT_X_509v3,
272 CSSM_CERT_ENCODING_BER,
273 &cert_handle);
274 if (status)
275 return NULL;
276
277 return CreateFromHandle(cert_handle);
278 }
279
280 // static
281 X509Certificate* X509Certificate::CreateFromPickle(const Pickle& pickle, 224 X509Certificate* X509Certificate::CreateFromPickle(const Pickle& pickle,
282 void** pickle_iter) { 225 void** pickle_iter) {
283 const char* data; 226 const char* data;
284 int length; 227 int length;
285 if (!pickle.ReadData(pickle_iter, &data, &length)) 228 if (!pickle.ReadData(pickle_iter, &data, &length))
286 return NULL; 229 return NULL;
287 230
288 return CreateFromBytes(data, length); 231 return CreateFromBytes(data, length);
289 } 232 }
290 233
291 X509Certificate::X509Certificate(OSCertHandle cert_handle)
292 : cert_handle_(cert_handle) {
293 Initialize();
294 }
295
296 X509Certificate::X509Certificate(std::string subject, std::string issuer,
297 Time start_date, Time expiration_date)
298 : subject_(subject),
299 issuer_(issuer),
300 valid_start_(start_date),
301 valid_expiry_(expiration_date),
302 cert_handle_(NULL) {
303 memset(fingerprint_.data, 0, sizeof(fingerprint_.data));
304 }
305
306 void X509Certificate::Persist(Pickle* pickle) { 234 void X509Certificate::Persist(Pickle* pickle) {
307 CSSM_DATA cert_data; 235 CSSM_DATA cert_data;
308 OSStatus status = SecCertificateGetData(cert_handle_, &cert_data); 236 OSStatus status = SecCertificateGetData(cert_handle_, &cert_data);
309 if (status) { 237 if (status) {
310 NOTREACHED(); 238 NOTREACHED();
311 return; 239 return;
312 } 240 }
313 241
314 pickle->WriteData(reinterpret_cast<char*>(cert_data.Data), cert_data.Length); 242 pickle->WriteData(reinterpret_cast<char*>(cert_data.Data), cert_data.Length);
315 } 243 }
316 244
317 X509Certificate::~X509Certificate() {
318 // We might not be in the cache, but it is safe to remove ourselves anyway.
319 X509Certificate::Cache::GetInstance()->Remove(this);
320 if (cert_handle_)
321 CFRelease(cert_handle_);
322 }
323
324 void X509Certificate::GetDNSNames(std::vector<std::string>* dns_names) const { 245 void X509Certificate::GetDNSNames(std::vector<std::string>* dns_names) const {
325 dns_names->clear(); 246 dns_names->clear();
326 247
327 GetCertGeneralNamesForOID(cert_handle_, CSSMOID_SubjectAltName, GNT_DNSName, 248 GetCertGeneralNamesForOID(cert_handle_, CSSMOID_SubjectAltName, GNT_DNSName,
328 dns_names); 249 dns_names);
329 250
330 if (dns_names->empty()) 251 if (dns_names->empty())
331 dns_names->push_back(subject_.common_name); 252 dns_names->push_back(subject_.common_name);
332 } 253 }
333 254
334 // Returns true if the certificate is an extended-validation certificate. 255 // Returns true if the certificate is an extended-validation certificate.
335 // 256 //
336 // The certificate has already been verified by the HTTP library. cert_status 257 // The certificate has already been verified by the HTTP library. cert_status
337 // represents the result of that verification. This function performs 258 // represents the result of that verification. This function performs
338 // additional checks of the certificatePolicies extensions of the certificates 259 // additional checks of the certificatePolicies extensions of the certificates
339 // in the certificate chain according to Section 7 (pp. 11-12) of the EV 260 // in the certificate chain according to Section 7 (pp. 11-12) of the EV
340 // Certificate Guidelines Version 1.0 at 261 // Certificate Guidelines Version 1.0 at
341 // http://cabforum.org/EV_Certificate_Guidelines.pdf. 262 // http://cabforum.org/EV_Certificate_Guidelines.pdf.
342 bool X509Certificate::IsEV(int cert_status) const { 263 bool X509Certificate::IsEV(int cert_status) const {
343 // TODO(avi): implement this 264 // TODO(avi): implement this
344 NOTIMPLEMENTED(); 265 NOTIMPLEMENTED();
345 return false; 266 return false;
346 } 267 }
347 268
269 // static
270 X509Certificate::OSCertHandle X509Certificate::CreateOSCertHandleFromBytes(
271 const char* data, int length) {
272 CSSM_DATA cert_data;
273 cert_data.Data = const_cast<uint8*>(reinterpret_cast<const uint8*>(data));
274 cert_data.Length = length;
275
276 OSCertHandle cert_handle = NULL;
277 OSStatus status = SecCertificateCreateFromData(&cert_data,
278 CSSM_CERT_X_509v3,
279 CSSM_CERT_ENCODING_BER,
280 &cert_handle);
281 if (status)
282 return NULL;
283
284 return cert_handle;
285 }
286
287 // static
288 void X509Certificate::FreeOSCertHandle(OSCertHandle cert_handle) {
289 CFRelease(cert_handle);
290 }
291
292 // static
293 X509Certificate::Fingerprint X509Certificate::CalculateFingerprint(
294 OSCertHandle cert) {
295 Fingerprint sha1;
296 memset(sha1.data, 0, sizeof(sha1.data));
297
298 CSSM_DATA cert_data;
299 OSStatus status = SecCertificateGetData(cert, &cert_data);
300 if (status)
301 return sha1;
302
303 DCHECK(NULL != cert_data.Data);
304 DCHECK(0 != cert_data.Length);
305
306 CC_SHA1(cert_data.Data, cert_data.Length, sha1.data);
307
308 return sha1;
309 }
310
348 } // namespace net 311 } // namespace net
OLDNEW
« no previous file with comments | « net/base/x509_certificate.cc ('k') | net/base/x509_certificate_nss.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698