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

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

Issue 174102: Enable SSLClientSocketTest unit tests on Mac OS X by implementing our own cer... (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: '' Created 11 years, 3 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
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/scoped_cftyperef.h"
10 #include "base/logging.h" 11 #include "base/logging.h"
11 #include "base/pickle.h" 12 #include "base/pickle.h"
12 #include "net/base/cert_status_flags.h" 13 #include "net/base/cert_status_flags.h"
13 #include "net/base/ev_root_ca_metadata.h" 14 #include "net/base/cert_verify_result.h"
14 #include "net/base/net_errors.h" 15 #include "net/base/net_errors.h"
15 16
16 using base::Time; 17 using base::Time;
17 18
18 namespace net { 19 namespace net {
19 20
21 class MacTrustedCertificates {
wtc 2009/08/27 00:14:18 See if you can put this class inside #ifdef UNIT_T
22 public:
23 // Sets the trusted root certificate used by tests. Call with |cert| set
24 // to NULL to clear the test certificate.
25 void SetTestCertificate(X509Certificate* cert) {
26 AutoLock lock(lock_);
27 test_certificate_ = cert;
28 }
29
30 // Returns an array containing the trusted certificates for use with
31 // SecTrustSetAnchorCertificates(). Returns NULL if the system-supplied
32 // list of trust anchors is acceptable (that is, there is not test
33 // certificate available). Ownership follows the Create Rule (caller
34 // is responsible for calling CFRelease on the non-NULL result).
35 CFArrayRef CopyTrustedCertificateArray() {
36 AutoLock lock(lock_);
37
38 if (!test_certificate_)
39 return NULL;
40
41 // Failure to copy the anchor certificates or add the test certificate
42 // is non-fatal; SecTrustEvaluate() will use the system anchors instead.
43 CFArrayRef anchor_array;
44 OSStatus status = SecTrustCopyAnchorCertificates(&anchor_array);
45 if (status)
46 return NULL;
47 scoped_cftyperef<CFArrayRef> scoped_anchor_array(anchor_array);
48 CFMutableArrayRef merged_array = CFArrayCreateMutableCopy(
49 kCFAllocatorDefault, 0, anchor_array);
50 if (!merged_array)
51 return NULL;
52 CFArrayAppendValue(merged_array, test_certificate_->os_cert_handle());
53
54 return merged_array;
55 }
56 private:
57 friend struct DefaultSingletonTraits<MacTrustedCertificates>;
58
59 // Obtain an instance of MacTrustedCertificates via the singleton
60 // interface.
61 MacTrustedCertificates() : test_certificate_(NULL) { }
62
63 // An X509Certificate object that may be appended to the list of
64 // system trusted anchors.
65 scoped_refptr<X509Certificate> test_certificate_;
66
67 // The trusted cache may be accessed from multiple threads.
68 mutable Lock lock_;
69
70 DISALLOW_COPY_AND_ASSIGN(MacTrustedCertificates);
71 };
72
73 void SetMacTestCertificate(X509Certificate* cert) {
wtc 2009/08/27 00:14:18 We should declare this function in x509_certificat
74 Singleton<MacTrustedCertificates>::get()->SetTestCertificate(cert);
75 }
76
20 namespace { 77 namespace {
21 78
79 typedef OSStatus (*SecTrustCopyExtendedResultFuncPtr)(SecTrustRef,
80 CFDictionaryRef*);
81
22 inline bool CSSMOIDEqual(const CSSM_OID* oid1, const CSSM_OID* oid2) { 82 inline bool CSSMOIDEqual(const CSSM_OID* oid1, const CSSM_OID* oid2) {
23 return oid1->Length == oid2->Length && 83 return oid1->Length == oid2->Length &&
24 (memcmp(oid1->Data, oid2->Data, oid1->Length) == 0); 84 (memcmp(oid1->Data, oid2->Data, oid1->Length) == 0);
25 } 85 }
26 86
87 int NetErrorFromOSStatus(OSStatus status) {
88 switch (status) {
89 case noErr:
90 return OK;
91 case errSecNotAvailable:
92 case errSecNoCertificateModule:
93 case errSecNoPolicyModule:
94 return ERR_NOT_IMPLEMENTED;
95 case errSecAuthFailed:
96 return ERR_ACCESS_DENIED;
97 default:
98 LOG(ERROR) << "Unknown error " << status << " mapped to net::ERR_FAILED";
99 return ERR_FAILED;
100 }
101 }
102
103 int CertStatusFromOSStatus(OSStatus status) {
104 switch (status) {
105 case noErr:
106 return 0;
107
108 case CSSMERR_TP_INVALID_ANCHOR_CERT:
109 case CSSMERR_TP_NOT_TRUSTED:
110 case CSSMERR_TP_INVALID_CERT_AUTHORITY:
111 return CERT_STATUS_AUTHORITY_INVALID;
112
113 case CSSMERR_TP_CERT_EXPIRED:
114 case CSSMERR_TP_CERT_NOT_VALID_YET:
115 // "Expired" and "not yet valid" collapse into a single status.
116 return CERT_STATUS_DATE_INVALID;
117
118 case CSSMERR_TP_CERT_REVOKED:
119 case CSSMERR_TP_CERT_SUSPENDED:
120 return CERT_STATUS_REVOKED;
121
122 case CSSMERR_APPLETP_HOSTNAME_MISMATCH:
123 return CERT_STATUS_COMMON_NAME_INVALID;
124
125 case CSSMERR_APPLETP_CRL_NOT_FOUND:
126 case CSSMERR_APPLETP_INCOMPLETE_REVOCATION_CHECK:
127 return CERT_STATUS_NO_REVOCATION_MECHANISM;
128
129 case CSSMERR_APPLETP_CRL_NOT_TRUSTED:
130 case CSSMERR_APPLETP_CRL_SERVER_DOWN:
131 case CSSMERR_APPLETP_CRL_NOT_VALID_YET:
132 case CSSMERR_APPLETP_NETWORK_FAILURE:
133 case CSSMERR_APPLETP_OCSP_UNAVAILABLE:
134 case CSSMERR_APPLETP_OCSP_BAD_RESPONSE:
135 case CSSMERR_APPLETP_OCSP_RESP_UNAUTHORIZED:
136 case CSSMERR_APPLETP_OCSP_RESP_SIG_REQUIRED:
137 case CSSMERR_APPLETP_OCSP_RESP_MALFORMED_REQ:
138 case CSSMERR_APPLETP_OCSP_RESP_INTERNAL_ERR:
139 case CSSMERR_APPLETP_OCSP_RESP_TRY_LATER:
140 // We asked for a revocation check, but didn't get it.
141 return CERT_STATUS_UNABLE_TO_CHECK_REVOCATION;
142
143 default:
144 // Failure was due to something Chromium doesn't define a
145 // specific status for (such as basic constraints violation, or
146 // unknown critical extension)
147 return CERT_STATUS_INVALID;
148 }
149 }
150
151 bool OverrideHostnameMismatch(const std::string& hostname,
152 std::vector<std::string>* dns_names) {
153 // SecTrustEvaluate() does not check dotted IP addresses. If
154 // hostname is provided as, say, 127.0.0.1, then the error
155 // CSSMERR_APPLETP_HOSTNAME_MISMATCH will always be returned,
156 // even if the certificate contains 127.0.0.1 as one of its names.
wtc 2009/08/27 02:12:06 Change "one of its names" to "the commonName in th
157 // We, however, want to allow that behavior. SecTrustEvaluate()
wtc 2009/08/27 02:12:06 Add something like "to be compatible with Windows
158 // only checks for digits and dots when considering whether a
159 // hostname is an IP address, so IPv6 and hex addresses go through
160 // its normal comparison.
161 bool is_dotted_ip = true;
162 bool override_hostname_mismatch = false;
163 for (std::string::const_iterator c = hostname.begin();
164 c != hostname.end() && is_dotted_ip; ++c)
165 is_dotted_ip = (*c >= '0' && *c <= '9') || *c == '.';
166 if (is_dotted_ip) {
167 for (std::vector<std::string>::const_iterator name = dns_names->begin();
168 name != dns_names->end() && !override_hostname_mismatch; ++name)
169 override_hostname_mismatch = (*name == hostname);
170 }
171 return override_hostname_mismatch;
172 }
173
27 void ParsePrincipal(const CSSM_X509_NAME* name, 174 void ParsePrincipal(const CSSM_X509_NAME* name,
28 X509Certificate::Principal* principal) { 175 X509Certificate::Principal* principal) {
29 std::vector<std::string> common_names, locality_names, state_names, 176 std::vector<std::string> common_names, locality_names, state_names,
30 country_names; 177 country_names;
31 178
32 // TODO(jcampan): add business_category and serial_number. 179 // TODO(jcampan): add business_category and serial_number.
33 const CSSM_OID* kOIDs[] = { &CSSMOID_CommonName, 180 const CSSM_OID* kOIDs[] = { &CSSMOID_CommonName,
34 &CSSMOID_LocalityName, 181 &CSSMOID_LocalityName,
35 &CSSMOID_StateProvinceName, 182 &CSSMOID_StateProvinceName,
36 &CSSMOID_CountryName, 183 &CSSMOID_CountryName,
(...skipping 218 matching lines...) Expand 10 before | Expand all | Expand 10 after
255 void X509Certificate::GetDNSNames(std::vector<std::string>* dns_names) const { 402 void X509Certificate::GetDNSNames(std::vector<std::string>* dns_names) const {
256 dns_names->clear(); 403 dns_names->clear();
257 404
258 GetCertGeneralNamesForOID(cert_handle_, CSSMOID_SubjectAltName, GNT_DNSName, 405 GetCertGeneralNamesForOID(cert_handle_, CSSMOID_SubjectAltName, GNT_DNSName,
259 dns_names); 406 dns_names);
260 407
261 if (dns_names->empty()) 408 if (dns_names->empty())
262 dns_names->push_back(subject_.common_name); 409 dns_names->push_back(subject_.common_name);
263 } 410 }
264 411
265 int X509Certificate::Verify(const std::string& hostname, 412 int X509Certificate::Verify(const std::string& hostname, int flags,
266 int flags, CertVerifyResult* verify_result) const { 413 CertVerifyResult* verify_result) const {
267 NOTIMPLEMENTED(); 414 verify_result->Reset();
268 return ERR_NOT_IMPLEMENTED; 415
269 } 416 // Create an SSL SecPolicyRef, and configure it to perform hostname
270 417 // validation. The hostname check does 99% of what we want, with the
271 // Returns true if the certificate is an extended-validation certificate. 418 // exception of dotted IPv4 addreses, which we handle ourselves below.
272 // 419 SecPolicySearchRef ssl_policy_search_ref = NULL;
273 // The certificate has already been verified by the HTTP library. cert_status 420 OSStatus status = SecPolicySearchCreate(CSSM_CERT_X_509v3,
274 // represents the result of that verification. This function performs 421 &CSSMOID_APPLE_TP_SSL,
275 // additional checks of the certificatePolicies extensions of the certificates 422 NULL,
276 // in the certificate chain according to Section 7 (pp. 11-12) of the EV 423 &ssl_policy_search_ref);
277 // Certificate Guidelines Version 1.0 at 424 if (status)
278 // http://cabforum.org/EV_Certificate_Guidelines.pdf. 425 return NetErrorFromOSStatus(status);
426 scoped_cftyperef<SecPolicySearchRef>
427 scoped_ssl_policy_search_ref(ssl_policy_search_ref);
428 SecPolicyRef ssl_policy = NULL;
429 status = SecPolicySearchCopyNext(ssl_policy_search_ref, &ssl_policy);
430 if (status)
431 return NetErrorFromOSStatus(status);
432 scoped_cftyperef<SecPolicyRef> scoped_ssl_policy(ssl_policy);
433 CSSM_APPLE_TP_SSL_OPTIONS tp_ssl_options = { CSSM_APPLE_TP_SSL_OPTS_VERSION };
434 tp_ssl_options.ServerName = hostname.data();
435 tp_ssl_options.ServerNameLen = hostname.size();
436 CSSM_DATA tp_ssl_options_data_value;
437 tp_ssl_options_data_value.Data = reinterpret_cast<uint8*>(&tp_ssl_options);
438 tp_ssl_options_data_value.Length = sizeof(tp_ssl_options);
439 status = SecPolicySetValue(ssl_policy, &tp_ssl_options_data_value);
440 if (status)
441 return NetErrorFromOSStatus(status);
442
443 // Create and configure a SecTrustRef, which takes our certificate(s)
444 // and our SSL SecPolicyRef. SecTrustCreateWithCertificates() takes an
445 // array of certificates, the first of which is the certificate we're
446 // verifying, and the subsequent (optional) certificates are used for
447 // chain building.
448 CFMutableArrayRef cert_array = CFArrayCreateMutable(kCFAllocatorDefault, 0,
449 &kCFTypeArrayCallBacks);
450 if (!cert_array)
451 return ERR_OUT_OF_MEMORY;
452 scoped_cftyperef<CFArrayRef> scoped_cert_array(cert_array);
453 CFArrayAppendValue(cert_array, cert_handle_);
454 if (intermediate_ca_certs_) {
455 CFIndex intermediate_count = CFArrayGetCount(intermediate_ca_certs_);
456 for (CFIndex i = 0; i < intermediate_count; ++i) {
457 SecCertificateRef intermediate_cert = static_cast<SecCertificateRef>(
458 const_cast<void*>(CFArrayGetValueAtIndex(intermediate_ca_certs_, i)));
459 CFArrayAppendValue(cert_array, intermediate_cert);
460 }
461 }
462
463 SecTrustRef trust_ref = NULL;
464 status = SecTrustCreateWithCertificates(cert_array, ssl_policy, &trust_ref);
465 if (status)
466 return NetErrorFromOSStatus(status);
467 scoped_cftyperef<SecTrustRef> scoped_trust_ref(trust_ref);
468
469 // Set the trusted anchor certificates for the SecTrustRef by merging the
wtc 2009/08/27 00:14:18 See if you can put this block of code (lines 469 -
470 // system trust anchors and the test root certificate.
471 CFArrayRef anchor_array =
472 Singleton<MacTrustedCertificates>::get()->CopyTrustedCertificateArray();
473 scoped_cftyperef<CFArrayRef> scoped_anchor_array(anchor_array);
474 if (anchor_array) {
475 status = SecTrustSetAnchorCertificates(trust_ref, anchor_array);
476 if (status)
477 return NetErrorFromOSStatus(status);
478 }
479
480 if (flags & VERIFY_REV_CHECKING_ENABLED) {
481 // When called with VERIFY_REV_CHECKING_ENABLED, we ask SecTrustEvaluate()
482 // to apply OCSP and CRL checking, but we're still subject to the global
483 // settings, which are configured in the Keychain Access application (in
484 // the Certificates tab of the Preferences dialog). If the user has
485 // revocation disabled (which is the default), then we will get
486 // kSecTrustResultRecoverableTrustFailure back from SecTrustEvaluate()
487 // with one of a number of sub error codes indicating that revocation
488 // checking did not occur. In that case, we'll set our own result to include
489 // CERT_STATUS_UNABLE_TO_CHECK_REVOCATION (note that this does not apply
490 // to EV certificates, which always get revocation checks regardless of the
491 // global settings).
492 verify_result->cert_status |= CERT_STATUS_REV_CHECKING_ENABLED;
493 CSSM_APPLE_TP_ACTION_DATA tp_action_data = { CSSM_APPLE_TP_ACTION_VERSION };
494 tp_action_data.ActionFlags = CSSM_TP_ACTION_REQUIRE_REV_PER_CERT;
495 CFDataRef action_data_ref =
496 CFDataCreate(NULL, reinterpret_cast<UInt8*>(&tp_action_data),
497 sizeof(tp_action_data));
498 if (!action_data_ref)
499 return ERR_OUT_OF_MEMORY;
500 scoped_cftyperef<CFDataRef> scoped_action_data_ref(action_data_ref);
501 status = SecTrustSetParameters(trust_ref, CSSM_TP_ACTION_DEFAULT,
502 action_data_ref);
503 if (status)
504 return NetErrorFromOSStatus(status);
505 } else {
506 // EV requires revocation checking.
507 flags &= ~VERIFY_EV_CERT;
508 }
509
510 // Verify the certificate. A non-zero result from SecTrustGetResult()
511 // indicates that some fatal error occurred and the chain couldn't be
512 // processed, not that the chain contains no errors. We need to examine the
513 // output of SecTrustGetResult() to determine that.
514 SecTrustResultType trust_result;
515 status = SecTrustEvaluate(trust_ref, &trust_result);
516 if (status)
517 return NetErrorFromOSStatus(status);
518 CFArrayRef completed_chain = NULL;
519 CSSM_TP_APPLE_EVIDENCE_INFO* chain_info;
520 status = SecTrustGetResult(trust_ref, &trust_result, &completed_chain,
521 &chain_info);
522 if (status)
523 return NetErrorFromOSStatus(status);
524 scoped_cftyperef<CFArrayRef> scoped_completed_chain(completed_chain);
525
526 // Evaluate the results
527 OSStatus cssm_result;
528 bool got_certificate_error = false;
529 switch (trust_result) {
530 case kSecTrustResultUnspecified:
531 case kSecTrustResultProceed:
532 // Certificate chain is valid and trusted ("unspecified" indicates that
533 // the user has not explicitly set a trust setting)
534 break;
535
536 case kSecTrustResultDeny:
537 case kSecTrustResultConfirm:
538 // Certificate chain is explicitly untrusted. For kSecTrustResultConfirm,
539 // we're following what Secure Transport does and treating it as
540 // "deny".
541 verify_result->cert_status |= CERT_STATUS_AUTHORITY_INVALID;
542 break;
543
544 case kSecTrustResultRecoverableTrustFailure:
545 // Certificate chain has a failure that can be overridden by the user.
546 status = SecTrustGetCssmResultCode(trust_ref, &cssm_result);
547 if (status)
548 return NetErrorFromOSStatus(status);
549 switch (cssm_result) {
550 case CSSMERR_TP_NOT_TRUSTED:
551 case CSSMERR_TP_INVALID_ANCHOR_CERT:
552 verify_result->cert_status |= CERT_STATUS_AUTHORITY_INVALID;
553 break;
554 case CSSMERR_TP_CERT_EXPIRED:
555 case CSSMERR_TP_CERT_NOT_VALID_YET:
556 verify_result->cert_status |= CERT_STATUS_DATE_INVALID;
557 break;
558 case CSSMERR_TP_CERT_REVOKED:
559 case CSSMERR_TP_CERT_SUSPENDED:
560 verify_result->cert_status |= CERT_STATUS_REVOKED;
561 break;
562 default:
563 // Look for specific per-certificate errors below.
564 break;
565 }
566 // Walk the chain of error codes in the CSSM_TP_APPLE_EVIDENCE_INFO
567 // structure which can catch multiple errors from each certificate.
568 for (CFIndex index = 0, chain_count = CFArrayGetCount(completed_chain);
569 index < chain_count; ++index) {
570 if (chain_info[index].StatusBits & CSSM_CERT_STATUS_EXPIRED ||
571 chain_info[index].StatusBits & CSSM_CERT_STATUS_NOT_VALID_YET)
572 verify_result->cert_status |= CERT_STATUS_DATE_INVALID;
573 for (uint32 status_code_index = 0;
574 status_code_index < chain_info[index].NumStatusCodes;
575 ++status_code_index) {
576 got_certificate_error = true;
577 int cert_status = CertStatusFromOSStatus(cssm_result);
578 if (cert_status == CERT_STATUS_COMMON_NAME_INVALID) {
579 std::vector<std::string> names;
580 GetDNSNames(&names);
wtc 2009/08/27 02:12:06 We should use only the common name in the subject
581 if (OverrideHostnameMismatch(hostname, &names)) {
582 cert_status = 0;
583 }
584 }
585 verify_result->cert_status |= cert_status;
586 }
587 }
588 // Be paranoid and ensure that we recorded at least one certificate
589 // status on receiving kSecTrustResultRecoverableTrustFailure. The
590 // call to SecTrustGetCssmResultCode() should pick up when the chain
591 // is not trusted and the loop through CSSM_TP_APPLE_EVIDENCE_INFO
592 // should pick up everything else, but let's be safe.
593 if (!verify_result->cert_status && !got_certificate_error) {
594 verify_result->cert_status |= CERT_STATUS_INVALID;
595 NOTREACHED();
596 }
597 break;
598
599 default:
600 status = SecTrustGetCssmResultCode(trust_ref, &cssm_result);
601 if (status)
602 return NetErrorFromOSStatus(status);
603 verify_result->cert_status |= CertStatusFromOSStatus(cssm_result);
604 if (!verify_result->cert_status) {
605 verify_result->cert_status |= CERT_STATUS_INVALID;
606 }
607 break;
608 }
609
610 if (IsCertStatusError(verify_result->cert_status))
611 return MapCertStatusToNetError(verify_result->cert_status);
612
613 if (flags & VERIFY_EV_CERT) {
614 // Determine the certificate's EV status using SecTrustCopyExtendedResult(),
615 // which we need to look up because the function wasn't added until
616 // Mac OS X 10.5.7.
617 CFBundleRef bundle =
618 CFBundleGetBundleWithIdentifier(CFSTR("com.apple.security"));
619 if (bundle) {
620 SecTrustCopyExtendedResultFuncPtr copy_extended_result =
621 reinterpret_cast<SecTrustCopyExtendedResultFuncPtr>(
622 CFBundleGetFunctionPointerForName(bundle,
623 CFSTR("SecTrustCopyExtendedResult")));
624 if (copy_extended_result) {
625 CFDictionaryRef ev_dict = NULL;
626 status = copy_extended_result(trust_ref, &ev_dict);
627 if (!status && ev_dict) {
628 // The returned dictionary contains the EV organization name from the
629 // server certificate, which we don't need at this point (and we
630 // have other ways to access, anyway). All we care is that
631 // SecTrustCopyExtendedResult() returned noErr and a non-NULL
632 // dictionary.
633 CFRelease(ev_dict);
634 verify_result->cert_status |= CERT_STATUS_IS_EV;
635 }
636 }
637 }
638 }
639
640 return OK;
641 }
642
279 bool X509Certificate::VerifyEV() const { 643 bool X509Certificate::VerifyEV() const {
280 // TODO(avi): implement this 644 // We don't call this private method, but we do need to implement it because
281 NOTIMPLEMENTED(); 645 // it's defined in x509_certificate.h. We perform EV checking in the
646 // Verify() above.
647 NOTREACHED();
282 return false; 648 return false;
283 } 649 }
284 650
651 void X509Certificate::AddIntermediateCertificate(SecCertificateRef cert) {
652 if (cert) {
653 if (!intermediate_ca_certs_) {
654 intermediate_ca_certs_ = CFArrayCreateMutable(kCFAllocatorDefault, 0,
655 &kCFTypeArrayCallBacks);
656 }
657 if (intermediate_ca_certs_) {
658 CFArrayAppendValue(intermediate_ca_certs_, cert);
659 }
660 }
661 }
662
285 // static 663 // static
286 X509Certificate::OSCertHandle X509Certificate::CreateOSCertHandleFromBytes( 664 X509Certificate::OSCertHandle X509Certificate::CreateOSCertHandleFromBytes(
287 const char* data, int length) { 665 const char* data, int length) {
288 CSSM_DATA cert_data; 666 CSSM_DATA cert_data;
289 cert_data.Data = const_cast<uint8*>(reinterpret_cast<const uint8*>(data)); 667 cert_data.Data = const_cast<uint8*>(reinterpret_cast<const uint8*>(data));
290 cert_data.Length = length; 668 cert_data.Length = length;
291 669
292 OSCertHandle cert_handle = NULL; 670 OSCertHandle cert_handle = NULL;
293 OSStatus status = SecCertificateCreateFromData(&cert_data, 671 OSStatus status = SecCertificateCreateFromData(&cert_data,
294 CSSM_CERT_X_509v3, 672 CSSM_CERT_X_509v3,
(...skipping 23 matching lines...) Expand all
318 696
319 DCHECK(NULL != cert_data.Data); 697 DCHECK(NULL != cert_data.Data);
320 DCHECK(0 != cert_data.Length); 698 DCHECK(0 != cert_data.Length);
321 699
322 CC_SHA1(cert_data.Data, cert_data.Length, sha1.data); 700 CC_SHA1(cert_data.Data, cert_data.Length, sha1.data);
323 701
324 return sha1; 702 return sha1;
325 } 703 }
326 704
327 } // namespace net 705 } // namespace net
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698