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

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

Issue 4653002: Cleanup X509CertificateMac style nits (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: bulach feedback Created 10 years, 1 month 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 <Security/Security.h> 8 #include <Security/Security.h>
9 #include <time.h> 9 #include <time.h>
10 10
(...skipping 202 matching lines...) Expand 10 before | Expand all | Expand 10 after
213 name_type == GNT_URI); 213 name_type == GNT_URI);
214 214
215 CSSMFields fields; 215 CSSMFields fields;
216 OSStatus status = GetCertFields(cert_handle, &fields); 216 OSStatus status = GetCertFields(cert_handle, &fields);
217 if (status) 217 if (status)
218 return; 218 return;
219 219
220 for (size_t field = 0; field < fields.num_of_fields; ++field) { 220 for (size_t field = 0; field < fields.num_of_fields; ++field) {
221 if (CSSMOIDEqual(&fields.fields[field].FieldOid, &oid)) { 221 if (CSSMOIDEqual(&fields.fields[field].FieldOid, &oid)) {
222 CSSM_X509_EXTENSION_PTR cssm_ext = 222 CSSM_X509_EXTENSION_PTR cssm_ext =
223 (CSSM_X509_EXTENSION_PTR)fields.fields[field].FieldValue.Data; 223 reinterpret_cast<CSSM_X509_EXTENSION_PTR>(
224 fields.fields[field].FieldValue.Data);
224 CE_GeneralNames* alt_name = 225 CE_GeneralNames* alt_name =
225 (CE_GeneralNames*) cssm_ext->value.parsedValue; 226 reinterpret_cast<CE_GeneralNames*>(cssm_ext->value.parsedValue);
226 227
227 for (size_t name = 0; name < alt_name->numNames; ++name) { 228 for (size_t name = 0; name < alt_name->numNames; ++name) {
228 const CE_GeneralName& name_struct = alt_name->generalName[name]; 229 const CE_GeneralName& name_struct = alt_name->generalName[name];
229 // All of the general name types we support are encoded as 230 // All of the general name types we support are encoded as
230 // IA5String. In general, we should be switching off 231 // IA5String. In general, we should be switching off
231 // |name_struct.nameType| and doing type-appropriate conversions. See 232 // |name_struct.nameType| and doing type-appropriate conversions. See
232 // certextensions.h and the comment immediately preceding 233 // certextensions.h and the comment immediately preceding
233 // CE_GeneralNameType for more information. 234 // CE_GeneralNameType for more information.
234 if (name_struct.nameType == name_type) { 235 if (name_struct.nameType == name_type) {
235 const CSSM_DATA& name_data = name_struct.name; 236 const CSSM_DATA& name_data = name_struct.name;
236 std::string value = 237 std::string value = std::string(
237 std::string(reinterpret_cast<std::string::value_type*> 238 reinterpret_cast<const char*>(name_data.Data),
238 (name_data.Data), 239 name_data.Length);
239 name_data.Length);
240 result->push_back(value); 240 result->push_back(value);
241 } 241 }
242 } 242 }
243 } 243 }
244 } 244 }
245 } 245 }
246 246
247 void GetCertDateForOID(X509Certificate::OSCertHandle cert_handle, 247 void GetCertDateForOID(X509Certificate::OSCertHandle cert_handle,
248 CSSM_OID oid, Time* result) { 248 CSSM_OID oid, Time* result) {
249 *result = Time::Time(); 249 *result = Time::Time();
250 250
251 CSSMFields fields; 251 CSSMFields fields;
252 OSStatus status = GetCertFields(cert_handle, &fields); 252 OSStatus status = GetCertFields(cert_handle, &fields);
253 if (status) 253 if (status)
254 return; 254 return;
255 255
256 for (size_t field = 0; field < fields.num_of_fields; ++field) { 256 for (size_t field = 0; field < fields.num_of_fields; ++field) {
257 if (CSSMOIDEqual(&fields.fields[field].FieldOid, &oid)) { 257 if (CSSMOIDEqual(&fields.fields[field].FieldOid, &oid)) {
258 CSSM_X509_TIME* x509_time = 258 CSSM_X509_TIME* x509_time = reinterpret_cast<CSSM_X509_TIME*>(
259 reinterpret_cast<CSSM_X509_TIME *> 259 fields.fields[field].FieldValue.Data);
260 (fields.fields[field].FieldValue.Data); 260 if (x509_time->timeType != BER_TAG_UTC_TIME &&
261 std::string time_string = 261 x509_time->timeType != BER_TAG_GENERALIZED_TIME) {
262 std::string(reinterpret_cast<std::string::value_type*> 262 LOG(ERROR) << "Unsupported date/time format "
263 (x509_time->time.Data), 263 << x509_time->timeType;
264 x509_time->time.Length);
265
266 DCHECK(x509_time->timeType == BER_TAG_UTC_TIME ||
267 x509_time->timeType == BER_TAG_GENERALIZED_TIME);
268
269 struct tm time;
270 const char* parse_string;
271 if (x509_time->timeType == BER_TAG_UTC_TIME)
272 parse_string = "%y%m%d%H%M%SZ";
273 else if (x509_time->timeType == BER_TAG_GENERALIZED_TIME)
274 parse_string = "%y%m%d%H%M%SZ";
275 else {
276 // Those are the only two BER tags for time; if neither are used then
277 // this is a rather broken cert.
278 return; 264 return;
279 } 265 }
280 266
281 strptime(time_string.c_str(), parse_string, &time); 267 base::StringPiece time_string(
282 268 reinterpret_cast<const char*>(x509_time->time.Data),
283 Time::Exploded exploded; 269 x509_time->time.Length);
284 exploded.year = time.tm_year + 1900; 270 CertificateDateFormat format = x509_time->timeType == BER_TAG_UTC_TIME ?
285 exploded.month = time.tm_mon + 1; 271 CERT_DATE_FORMAT_UTC_TIME : CERT_DATE_FORMAT_GENERALIZED_TIME;
286 exploded.day_of_week = time.tm_wday; 272 if (!ParseCertificateDate(time_string, format, result))
287 exploded.day_of_month = time.tm_mday; 273 LOG(ERROR) << "Invalid certificate date/time " << time_string;
288 exploded.hour = time.tm_hour; 274 return;
289 exploded.minute = time.tm_min;
290 exploded.second = time.tm_sec;
291 exploded.millisecond = 0;
292
293 *result = Time::FromUTCExploded(exploded);
294 break;
295 } 275 }
296 } 276 }
297 } 277 }
298 278
299 // Creates a SecPolicyRef for the given OID, with optional value. 279 // Creates a SecPolicyRef for the given OID, with optional value.
300 OSStatus CreatePolicy(const CSSM_OID* policy_OID, 280 OSStatus CreatePolicy(const CSSM_OID* policy_OID,
301 void* option_data, 281 void* option_data,
302 size_t option_length, 282 size_t option_length,
303 SecPolicyRef* policy) { 283 SecPolicyRef* policy) {
304 SecPolicySearchRef search; 284 SecPolicySearchRef search;
(...skipping 20 matching lines...) Expand all
325 return noErr; 305 return noErr;
326 } 306 }
327 307
328 // Gets the issuer for a given cert, starting with the cert itself and 308 // Gets the issuer for a given cert, starting with the cert itself and
329 // including the intermediate and finally root certificates (if any). 309 // including the intermediate and finally root certificates (if any).
330 // This function calls SecTrust but doesn't actually pay attention to the trust 310 // This function calls SecTrust but doesn't actually pay attention to the trust
331 // result: it shouldn't be used to determine trust, just to traverse the chain. 311 // result: it shouldn't be used to determine trust, just to traverse the chain.
332 // Caller is responsible for releasing the value stored into *out_cert_chain. 312 // Caller is responsible for releasing the value stored into *out_cert_chain.
333 OSStatus CopyCertChain(SecCertificateRef cert_handle, 313 OSStatus CopyCertChain(SecCertificateRef cert_handle,
334 CFArrayRef* out_cert_chain) { 314 CFArrayRef* out_cert_chain) {
335 DCHECK(cert_handle && out_cert_chain); 315 DCHECK(cert_handle);
316 DCHECK(out_cert_chain);
336 // Create an SSL policy ref configured for client cert evaluation. 317 // Create an SSL policy ref configured for client cert evaluation.
337 SecPolicyRef ssl_policy; 318 SecPolicyRef ssl_policy;
338 OSStatus result = X509Certificate::CreateSSLClientPolicy(&ssl_policy); 319 OSStatus result = X509Certificate::CreateSSLClientPolicy(&ssl_policy);
339 if (result) 320 if (result)
340 return result; 321 return result;
341 ScopedCFTypeRef<SecPolicyRef> scoped_ssl_policy(ssl_policy); 322 ScopedCFTypeRef<SecPolicyRef> scoped_ssl_policy(ssl_policy);
342 323
343 // Create a SecTrustRef. 324 // Create a SecTrustRef.
344 ScopedCFTypeRef<CFArrayRef> input_certs( 325 ScopedCFTypeRef<CFArrayRef> input_certs(CFArrayCreate(
345 CFArrayCreate(NULL, (const void**)&cert_handle, 1, 326 NULL, const_cast<const void**>(reinterpret_cast<void**>(&cert_handle)),
346 &kCFTypeArrayCallBacks)); 327 1, &kCFTypeArrayCallBacks));
347 SecTrustRef trust_ref = NULL; 328 SecTrustRef trust_ref = NULL;
348 result = SecTrustCreateWithCertificates(input_certs, ssl_policy, &trust_ref); 329 result = SecTrustCreateWithCertificates(input_certs, ssl_policy, &trust_ref);
349 if (result) 330 if (result)
350 return result; 331 return result;
351 ScopedCFTypeRef<SecTrustRef> trust(trust_ref); 332 ScopedCFTypeRef<SecTrustRef> trust(trust_ref);
352 333
353 // Evaluate trust, which creates the cert chain. 334 // Evaluate trust, which creates the cert chain.
354 SecTrustResultType status; 335 SecTrustResultType status;
355 CSSM_TP_APPLE_EVIDENCE_INFO* status_chain; 336 CSSM_TP_APPLE_EVIDENCE_INFO* status_chain;
356 result = SecTrustEvaluate(trust, &status); 337 result = SecTrustEvaluate(trust, &status);
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
391 } 372 }
392 373
393 // Parses |data| of length |length|, attempting to decode it as the specified 374 // Parses |data| of length |length|, attempting to decode it as the specified
394 // |format|. If |data| is in the specified format, any certificates contained 375 // |format|. If |data| is in the specified format, any certificates contained
395 // within are stored into |output|. 376 // within are stored into |output|.
396 void AddCertificatesFromBytes(const char* data, size_t length, 377 void AddCertificatesFromBytes(const char* data, size_t length,
397 SecExternalFormat format, 378 SecExternalFormat format,
398 X509Certificate::OSCertHandles* output) { 379 X509Certificate::OSCertHandles* output) {
399 SecExternalFormat input_format = format; 380 SecExternalFormat input_format = format;
400 ScopedCFTypeRef<CFDataRef> local_data(CFDataCreateWithBytesNoCopy( 381 ScopedCFTypeRef<CFDataRef> local_data(CFDataCreateWithBytesNoCopy(
401 kCFAllocatorDefault, reinterpret_cast<const UInt8*>(data), 382 kCFAllocatorDefault, reinterpret_cast<const UInt8*>(data), length,
402 length, kCFAllocatorNull)); 383 kCFAllocatorNull));
403 384
404 CFArrayRef items = NULL; 385 CFArrayRef items = NULL;
405 OSStatus status = SecKeychainItemImport(local_data, NULL, &input_format, 386 OSStatus status = SecKeychainItemImport(local_data, NULL, &input_format,
406 NULL, 0, NULL, NULL, &items); 387 NULL, 0, NULL, NULL, &items);
407 if (status) { 388 if (status) {
408 DLOG(WARNING) << status << " Unable to import items from data of length " 389 DLOG(WARNING) << status << " Unable to import items from data of length "
409 << length; 390 << length;
410 return; 391 return;
411 } 392 }
412 393
(...skipping 26 matching lines...) Expand all
439 } 420 }
440 } 421 }
441 } 422 }
442 } 423 }
443 424
444 } // namespace 425 } // namespace
445 426
446 void X509Certificate::Initialize() { 427 void X509Certificate::Initialize() {
447 const CSSM_X509_NAME* name; 428 const CSSM_X509_NAME* name;
448 OSStatus status = SecCertificateGetSubject(cert_handle_, &name); 429 OSStatus status = SecCertificateGetSubject(cert_handle_, &name);
449 if (!status) { 430 if (!status)
450 subject_.Parse(name); 431 subject_.Parse(name);
451 } 432
452 status = SecCertificateGetIssuer(cert_handle_, &name); 433 status = SecCertificateGetIssuer(cert_handle_, &name);
453 if (!status) { 434 if (!status)
454 issuer_.Parse(name); 435 issuer_.Parse(name);
455 }
456 436
457 GetCertDateForOID(cert_handle_, CSSMOID_X509V1ValidityNotBefore, 437 GetCertDateForOID(cert_handle_, CSSMOID_X509V1ValidityNotBefore,
458 &valid_start_); 438 &valid_start_);
459 GetCertDateForOID(cert_handle_, CSSMOID_X509V1ValidityNotAfter, 439 GetCertDateForOID(cert_handle_, CSSMOID_X509V1ValidityNotAfter,
460 &valid_expiry_); 440 &valid_expiry_);
461 441
462 fingerprint_ = CalculateFingerprint(cert_handle_); 442 fingerprint_ = CalculateFingerprint(cert_handle_);
463 } 443 }
464 444
465 // static 445 // static
(...skipping 180 matching lines...) Expand 10 before | Expand all | Expand 10 after
646 verify_result->cert_status |= CERT_STATUS_DATE_INVALID; 626 verify_result->cert_status |= CERT_STATUS_DATE_INVALID;
647 for (uint32 status_code_index = 0; 627 for (uint32 status_code_index = 0;
648 status_code_index < chain_info[index].NumStatusCodes; 628 status_code_index < chain_info[index].NumStatusCodes;
649 ++status_code_index) { 629 ++status_code_index) {
650 got_certificate_error = true; 630 got_certificate_error = true;
651 int cert_status = CertStatusFromOSStatus( 631 int cert_status = CertStatusFromOSStatus(
652 chain_info[index].StatusCodes[status_code_index]); 632 chain_info[index].StatusCodes[status_code_index]);
653 if (cert_status == CERT_STATUS_COMMON_NAME_INVALID) { 633 if (cert_status == CERT_STATUS_COMMON_NAME_INVALID) {
654 std::vector<std::string> names; 634 std::vector<std::string> names;
655 GetDNSNames(&names); 635 GetDNSNames(&names);
656 if (OverrideHostnameMismatch(hostname, &names)) { 636 if (OverrideHostnameMismatch(hostname, &names))
657 cert_status = 0; 637 cert_status = 0;
658 }
659 } 638 }
660 verify_result->cert_status |= cert_status; 639 verify_result->cert_status |= cert_status;
661 } 640 }
662 } 641 }
663 // Be paranoid and ensure that we recorded at least one certificate 642 // Be paranoid and ensure that we recorded at least one certificate
664 // status on receiving kSecTrustResultRecoverableTrustFailure. The 643 // status on receiving kSecTrustResultRecoverableTrustFailure. The
665 // call to SecTrustGetCssmResultCode() should pick up when the chain 644 // call to SecTrustGetCssmResultCode() should pick up when the chain
666 // is not trusted and the loop through CSSM_TP_APPLE_EVIDENCE_INFO 645 // is not trusted and the loop through CSSM_TP_APPLE_EVIDENCE_INFO
667 // should pick up everything else, but let's be safe. 646 // should pick up everything else, but let's be safe.
668 if (!verify_result->cert_status && !got_certificate_error) { 647 if (!verify_result->cert_status && !got_certificate_error) {
669 verify_result->cert_status |= CERT_STATUS_INVALID; 648 verify_result->cert_status |= CERT_STATUS_INVALID;
670 NOTREACHED(); 649 NOTREACHED();
671 } 650 }
672 break; 651 break;
673 652
674 default: 653 default:
675 status = SecTrustGetCssmResultCode(trust_ref, &cssm_result); 654 status = SecTrustGetCssmResultCode(trust_ref, &cssm_result);
676 if (status) 655 if (status)
677 return NetErrorFromOSStatus(status); 656 return NetErrorFromOSStatus(status);
678 verify_result->cert_status |= CertStatusFromOSStatus(cssm_result); 657 verify_result->cert_status |= CertStatusFromOSStatus(cssm_result);
679 if (!verify_result->cert_status) { 658 if (!verify_result->cert_status)
680 verify_result->cert_status |= CERT_STATUS_INVALID; 659 verify_result->cert_status |= CERT_STATUS_INVALID;
681 }
682 break; 660 break;
683 } 661 }
684 662
685 // TODO(wtc): Suppress CERT_STATUS_NO_REVOCATION_MECHANISM for now to be 663 // TODO(wtc): Suppress CERT_STATUS_NO_REVOCATION_MECHANISM for now to be
686 // compatible with Windows, which in turn implements this behavior to be 664 // compatible with Windows, which in turn implements this behavior to be
687 // compatible with WinHTTP, which doesn't report this error (bug 3004). 665 // compatible with WinHTTP, which doesn't report this error (bug 3004).
688 verify_result->cert_status &= ~CERT_STATUS_NO_REVOCATION_MECHANISM; 666 verify_result->cert_status &= ~CERT_STATUS_NO_REVOCATION_MECHANISM;
689 667
690 if (IsCertStatusError(verify_result->cert_status)) 668 if (IsCertStatusError(verify_result->cert_status))
691 return MapCertStatusToNetError(verify_result->cert_status); 669 return MapCertStatusToNetError(verify_result->cert_status);
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after
805 SHA1Fingerprint X509Certificate::CalculateFingerprint( 783 SHA1Fingerprint X509Certificate::CalculateFingerprint(
806 OSCertHandle cert) { 784 OSCertHandle cert) {
807 SHA1Fingerprint sha1; 785 SHA1Fingerprint sha1;
808 memset(sha1.data, 0, sizeof(sha1.data)); 786 memset(sha1.data, 0, sizeof(sha1.data));
809 787
810 CSSM_DATA cert_data; 788 CSSM_DATA cert_data;
811 OSStatus status = SecCertificateGetData(cert, &cert_data); 789 OSStatus status = SecCertificateGetData(cert, &cert_data);
812 if (status) 790 if (status)
813 return sha1; 791 return sha1;
814 792
815 DCHECK(NULL != cert_data.Data); 793 DCHECK(cert_data.Data);
816 DCHECK(0 != cert_data.Length); 794 DCHECK_NE(cert_data.Length, 0U);
817 795
818 CC_SHA1(cert_data.Data, cert_data.Length, sha1.data); 796 CC_SHA1(cert_data.Data, cert_data.Length, sha1.data);
819 797
820 return sha1; 798 return sha1;
821 } 799 }
822 800
823 bool X509Certificate::SupportsSSLClientAuth() const { 801 bool X509Certificate::SupportsSSLClientAuth() const {
824 CSSMFields fields; 802 CSSMFields fields;
825 if (GetCertFields(cert_handle_, &fields) != noErr) 803 if (GetCertFields(cert_handle_, &fields) != noErr)
826 return false; 804 return false;
(...skipping 30 matching lines...) Expand all
857 return false; 835 return false;
858 return true; 836 return true;
859 } 837 }
860 838
861 bool X509Certificate::IsIssuedBy( 839 bool X509Certificate::IsIssuedBy(
862 const std::vector<CertPrincipal>& valid_issuers) { 840 const std::vector<CertPrincipal>& valid_issuers) {
863 // Get the cert's issuer chain. 841 // Get the cert's issuer chain.
864 CFArrayRef cert_chain = NULL; 842 CFArrayRef cert_chain = NULL;
865 OSStatus result; 843 OSStatus result;
866 result = CopyCertChain(os_cert_handle(), &cert_chain); 844 result = CopyCertChain(os_cert_handle(), &cert_chain);
867 if (result != noErr) 845 if (result)
868 return false; 846 return false;
869 ScopedCFTypeRef<CFArrayRef> scoped_cert_chain(cert_chain); 847 ScopedCFTypeRef<CFArrayRef> scoped_cert_chain(cert_chain);
870 848
871 // Check all the certs in the chain for a match. 849 // Check all the certs in the chain for a match.
872 int n = CFArrayGetCount(cert_chain); 850 int n = CFArrayGetCount(cert_chain);
873 for (int i = 0; i < n; ++i) { 851 for (int i = 0; i < n; ++i) {
874 SecCertificateRef cert_handle = reinterpret_cast<SecCertificateRef>( 852 SecCertificateRef cert_handle = reinterpret_cast<SecCertificateRef>(
875 const_cast<void*>(CFArrayGetValueAtIndex(cert_chain, i))); 853 const_cast<void*>(CFArrayGetValueAtIndex(cert_chain, i)));
876 scoped_refptr<X509Certificate> cert(X509Certificate::CreateFromHandle( 854 scoped_refptr<X509Certificate> cert(X509Certificate::CreateFromHandle(
877 cert_handle, 855 cert_handle,
(...skipping 15 matching lines...) Expand all
893 NULL, 871 NULL,
894 CSSM_APPLE_TP_SSL_CLIENT 872 CSSM_APPLE_TP_SSL_CLIENT
895 }; 873 };
896 return CreatePolicy(&CSSMOID_APPLE_TP_SSL, 874 return CreatePolicy(&CSSMOID_APPLE_TP_SSL,
897 &tp_ssl_options, 875 &tp_ssl_options,
898 sizeof(tp_ssl_options), 876 sizeof(tp_ssl_options),
899 out_policy); 877 out_policy);
900 } 878 }
901 879
902 // static 880 // static
903 bool X509Certificate::GetSSLClientCertificates ( 881 bool X509Certificate::GetSSLClientCertificates(
904 const std::string& server_domain, 882 const std::string& server_domain,
905 const std::vector<CertPrincipal>& valid_issuers, 883 const std::vector<CertPrincipal>& valid_issuers,
906 std::vector<scoped_refptr<X509Certificate> >* certs) { 884 CertificateList* certs) {
907 ScopedCFTypeRef<SecIdentityRef> preferred_identity; 885 ScopedCFTypeRef<SecIdentityRef> preferred_identity;
908 if (!server_domain.empty()) { 886 if (!server_domain.empty()) {
909 // See if there's an identity preference for this domain: 887 // See if there's an identity preference for this domain:
910 ScopedCFTypeRef<CFStringRef> domain_str( 888 ScopedCFTypeRef<CFStringRef> domain_str(
911 base::SysUTF8ToCFStringRef("https://" + server_domain)); 889 base::SysUTF8ToCFStringRef("https://" + server_domain));
912 SecIdentityRef identity = NULL; 890 SecIdentityRef identity = NULL;
913 if (SecIdentityCopyPreference(domain_str, 891 // While SecIdentityCopyPreferences appears to take a list of CA issuers
914 0, 892 // to restrict the identity search to, within Security.framework the
915 NULL, // validIssuers argument is ignored :( 893 // argument is ignored and filtering unimplemented. See
916 &identity) == noErr) 894 // SecIdentity.cpp in libsecurity_keychain, specifically
895 // _SecIdentityCopyPreferenceMatchingName().
896 if (SecIdentityCopyPreference(domain_str, 0, NULL, &identity) == noErr)
917 preferred_identity.reset(identity); 897 preferred_identity.reset(identity);
918 } 898 }
919 899
920 // Now enumerate the identities in the available keychains. 900 // Now enumerate the identities in the available keychains.
921 SecIdentitySearchRef search = nil; 901 SecIdentitySearchRef search = nil;
922 OSStatus err = SecIdentitySearchCreate(NULL, CSSM_KEYUSE_SIGN, &search); 902 OSStatus err = SecIdentitySearchCreate(NULL, CSSM_KEYUSE_SIGN, &search);
923 ScopedCFTypeRef<SecIdentitySearchRef> scoped_search(search); 903 ScopedCFTypeRef<SecIdentitySearchRef> scoped_search(search);
924 while (!err) { 904 while (!err) {
925 SecIdentityRef identity = NULL; 905 SecIdentityRef identity = NULL;
926 err = SecIdentitySearchCopyNext(search, &identity); 906 err = SecIdentitySearchCopyNext(search, &identity);
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
984 if (result) { 964 if (result) {
985 LOG(ERROR) << "SecIdentityCreateWithCertificate error " << result; 965 LOG(ERROR) << "SecIdentityCreateWithCertificate error " << result;
986 return NULL; 966 return NULL;
987 } 967 }
988 ScopedCFTypeRef<CFMutableArrayRef> chain( 968 ScopedCFTypeRef<CFMutableArrayRef> chain(
989 CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks)); 969 CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks));
990 CFArrayAppendValue(chain, identity); 970 CFArrayAppendValue(chain, identity);
991 971
992 CFArrayRef cert_chain = NULL; 972 CFArrayRef cert_chain = NULL;
993 result = CopyCertChain(cert_handle_, &cert_chain); 973 result = CopyCertChain(cert_handle_, &cert_chain);
994 if (result) 974 if (result) {
995 goto exit; 975 LOG(ERROR) << "CreateIdentityCertificateChain error " << result;
976 return chain.release();
977 }
996 978
997 // Append the intermediate certs from SecTrust to the result array: 979 // Append the intermediate certs from SecTrust to the result array:
998 if (cert_chain) { 980 if (cert_chain) {
999 int chain_count = CFArrayGetCount(cert_chain); 981 int chain_count = CFArrayGetCount(cert_chain);
1000 if (chain_count > 1) { 982 if (chain_count > 1) {
1001 CFArrayAppendArray(chain, 983 CFArrayAppendArray(chain,
1002 cert_chain, 984 cert_chain,
1003 CFRangeMake(1, chain_count - 1)); 985 CFRangeMake(1, chain_count - 1));
1004 } 986 }
1005 CFRelease(cert_chain); 987 CFRelease(cert_chain);
1006 } 988 }
1007 exit: 989
1008 if (result)
1009 LOG(ERROR) << "CreateIdentityCertificateChain error " << result;
1010 return chain.release(); 990 return chain.release();
1011 } 991 }
1012 992
1013 } // namespace net 993 } // namespace net
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698