2  * Copyright (c) 2002-2015 Apple Inc. All Rights Reserved. 
   4  * @APPLE_LICENSE_HEADER_START@ 
   6  * This file contains Original Code and/or Modifications of Original Code 
   7  * as defined in and that are subject to the Apple Public Source License 
   8  * Version 2.0 (the 'License'). You may not use this file except in 
   9  * compliance with the License. Please obtain a copy of the License at 
  10  * http://www.opensource.apple.com/apsl/ and read it before using this 
  13  * The Original Code and all software distributed under the License are 
  14  * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 
  15  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 
  16  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 
  17  * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 
  18  * Please see the License for the specific language governing rights and 
  19  * limitations under the License. 
  21  * @APPLE_LICENSE_HEADER_END@ 
  24 #include <Security/SecCertificate.h> 
  25 #include <Security/SecCertificatePriv.h> 
  26 #include <security_keychain/Certificate.h> 
  27 #include <security_keychain/Item.h> 
  28 #include <security_keychain/KCCursor.h> 
  29 #include <Security/cssmapi.h> 
  30 #include <Security/cssmapple.h> 
  31 #include <security_cdsa_client/cspclient.h> 
  32 #include <security_cdsa_client/clclient.h> 
  33 #include <security_cdsa_client/tpclient.h> 
  34 #include <Security/cssmtype.h> 
  36 #include "SecBridge.h" 
  38 // %%% used by SecCertificate{Copy,Set}Preference 
  39 #include <Security/SecKeychainItemPriv.h> 
  40 #include <Security/SecIdentityPriv.h> 
  41 #include <security_keychain/KCCursor.h> 
  42 #include <security_cdsa_utilities/Schema.h> 
  43 #include <security_cdsa_utils/cuCdsaUtils.h> 
  44 #include <sys/param.h> 
  46 #include "CertificateValues.h" 
  47 #include "SecCertificateP.h" 
  48 #include "SecCertificatePrivP.h" 
  50 #include "AppleBaselineEscrowCertificates.h" 
  53 SecCertificateRef 
SecCertificateCreateItemImplInstance(SecCertificateRef certificate
); 
  54 OSStatus 
SecCertificateGetCLHandle_legacy(SecCertificateRef certificate
, CSSM_CL_HANDLE 
*clHandle
); 
  55 extern CSSM_KEYUSE 
ConvertArrayToKeyUsage(CFArrayRef usage
); 
  57 #define SEC_CONST_DECL(k,v) const CFStringRef k = CFSTR(v); 
  59 SEC_CONST_DECL (kSecCertificateProductionEscrowKey
, "ProductionEscrowKey"); 
  60 SEC_CONST_DECL (kSecCertificateProductionPCSEscrowKey
, "ProductionPCSEscrowKey"); 
  61 SEC_CONST_DECL (kSecCertificateEscrowFileName
, "AppleESCertificates"); 
  64 using namespace CssmClient
; 
  68 SecCertificateGetTypeID(void) 
  72         return gTypes().Certificate
.typeID
; 
  74         END_SECAPI1(_kCFRuntimeNotATypeID
) 
  78 /* convert a new-world SecCertificateRef to an old-world ItemImpl instance */ 
  80 SecCertificateCreateItemImplInstance(SecCertificateRef certificate
) 
  83     return (SecCertificateRef
)(certificate 
? CFRetain(certificate
) : NULL
); 
  88         SecCertificateRef implCertRef 
= (SecCertificateRef
) SecCertificateCopyKeychainItem(certificate
); 
  92         CFDataRef data 
= SecCertificateCopyData(certificate
); 
  97                 CSSM_DATA cssmCertData
; 
  98                 cssmCertData
.Length 
= (data
) ? (CSSM_SIZE
)CFDataGetLength(data
) : 0; 
  99                 cssmCertData
.Data 
= (data
) ? (uint8 
*)CFDataGetBytePtr(data
) : NULL
; 
 101                 SecPointer
<Certificate
> certificatePtr(new Certificate(cssmCertData
, CSSM_CERT_X_509v3
, CSSM_CERT_ENCODING_DER
)); 
 102                 implCertRef 
= certificatePtr
->handle(); 
 110 /* convert an old-world ItemImpl instance to a new-world SecCertificateRef */ 
 112 SecCertificateCreateFromItemImplInstance(SecCertificateRef certificate
) 
 115     return (SecCertificateRef
)(certificate 
? CFRetain(certificate
) : NULL
); 
 120         SecCertificateRef result 
= NULL
; 
 121         CFDataRef data 
= NULL
; 
 123                 CssmData certData 
= Certificate::required(certificate
)->data(); 
 124                 if (certData
.Data 
&& certData
.Length
) { 
 125                         data 
= CFDataCreate(NULL
, certData
.Data
, certData
.Length
); 
 128                         if (certData
.Data 
&& !certData
.Length
) { 
 129                                 /* zero-length certs can exist, so don't bother logging this */ 
 132                                 syslog(LOG_ERR
, "WARNING: SecKeychainSearchCopyNext failed to retrieve certificate data (length=%ld, data=0x%lX)", 
 133                                                 (long)certData
.Length
, (uintptr_t)certData
.Data
); 
 140         result 
= SecCertificateCreateWithKeychainItem(NULL
, data
, certificate
); 
 147 /* OS X only: DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER */ 
 149 SecCertificateCreateFromData(const CSSM_DATA 
*data
, CSSM_CERT_TYPE type
, CSSM_CERT_ENCODING encoding
, SecCertificateRef 
*certificate
) 
 154         SecPointer
<Certificate
> certificatePtr(new Certificate(Required(data
), type
, encoding
)); 
 155         Required(certificate
) = certificatePtr
->handle(); 
 159         /* bridge to support old functionality */ 
 160         if (!data 
|| !data
->Data 
|| !data
->Length 
|| !certificate
) { 
 163         SecCertificateRef certRef 
= NULL
; 
 164         CFDataRef dataRef 
= CFDataCreate(NULL
, data
->Data
, data
->Length
); 
 166                 certRef 
= SecCertificateCreateWithData(NULL
, dataRef
); 
 169         *certificate 
= certRef
; 
 170         return (certRef
) ? errSecSuccess 
: errSecUnknownFormat
; 
 177 SecCertificateCreateWithData(CFAllocatorRef allocator
, CFDataRef data
) 
 179         SecCertificateRef certificate 
= NULL
; 
 180     OSStatus __secapiresult
; 
 182                 CSSM_DATA cssmCertData
; 
 183                 cssmCertData
.Length 
= (data
) ? (CSSM_SIZE
)CFDataGetLength(data
) : 0; 
 184                 cssmCertData
.Data 
= (data
) ? (uint8 
*)CFDataGetBytePtr(data
) : NULL
; 
 186                 //NOTE: there isn't yet a Certificate constructor which accepts a CFAllocatorRef 
 187                 SecPointer
<Certificate
> certificatePtr(new Certificate(cssmCertData
, CSSM_CERT_X_509v3
, CSSM_CERT_ENCODING_DER
)); 
 188                 certificate 
= certificatePtr
->handle(); 
 190                 __secapiresult
=errSecSuccess
; 
 192         catch (const MacOSError 
&err
) { __secapiresult
=err
.osStatus(); } 
 193         catch (const CommonError 
&err
) { __secapiresult
=SecKeychainErrFromOSStatus(err
.osStatus()); } 
 194         catch (const std::bad_alloc 
&) { __secapiresult
=errSecAllocate
; } 
 195         catch (...) { __secapiresult
=errSecInternalComponent
; } 
 200 /* OS X only: __OSX_AVAILABLE_STARTING(__MAC_10_3, __IPHONE_NA) */ 
 202 SecCertificateAddToKeychain(SecCertificateRef certificate
, SecKeychainRef keychain
) 
 204         // This macro converts a new-style SecCertificateRef to an old-style ItemImpl 
 207         Item 
item(Certificate::required(__itemImplRef
)); 
 208         Keychain::optional(keychain
)->add(item
); 
 213 /* OS X only: DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER */ 
 215 SecCertificateGetData(SecCertificateRef certificate
, CSSM_DATA_PTR data
) 
 217         // This macro converts a new-style SecCertificateRef to an old-style ItemImpl 
 220         Required(data
) = Certificate::required(__itemImplRef
)->data(); 
 228 SecCertificateCopyData(SecCertificateRef certificate
) 
 230         CFDataRef data 
= NULL
; 
 231     OSStatus __secapiresult 
= errSecSuccess
; 
 233                 CssmData output 
= Certificate::required(certificate
)->data(); 
 234                 CFIndex length 
= (CFIndex
)output
.length(); 
 235                 const UInt8 
*bytes 
= (const UInt8 
*)output
.data(); 
 236                 if (length 
&& bytes
) { 
 237                         data 
= CFDataCreate(NULL
, bytes
, length
); 
 240         catch (const MacOSError 
&err
) { __secapiresult
=err
.osStatus(); } 
 241         catch (const CommonError 
&err
) { __secapiresult
=SecKeychainErrFromOSStatus(err
.osStatus()); } 
 242         catch (const std::bad_alloc 
&) { __secapiresult
=errSecAllocate
; } 
 243         catch (...) { __secapiresult
=errSecInternalComponent
; } 
 250 SecCertificateGetSHA1Digest(SecCertificateRef certificate
) 
 252         CFDataRef data 
= NULL
; 
 253     OSStatus __secapiresult 
= errSecSuccess
; 
 255                 data 
= Certificate::required(certificate
)->sha1Hash(); 
 257         catch (const MacOSError 
&err
) { __secapiresult
=err
.osStatus(); } 
 258         catch (const CommonError 
&err
) { __secapiresult
=SecKeychainErrFromOSStatus(err
.osStatus()); } 
 259         catch (const std::bad_alloc 
&) { __secapiresult
=errSecAllocate
; } 
 260         catch (...) { __secapiresult
=errSecInternalComponent
; } 
 267 SecCertificateCopyPublicKeySHA1Digest(SecCertificateRef certificate
) 
 269     CFDataRef data 
= NULL
; 
 270     OSStatus __secapiresult 
= errSecSuccess
; 
 272         CssmData output 
= Certificate::required(certificate
)->publicKeyHash(); 
 273         CFIndex length 
= (CFIndex
)output
.length(); 
 274         const UInt8 
*bytes 
= (const UInt8 
*)output
.data(); 
 275         if (length 
&& bytes
) { 
 276             data 
= CFDataCreate(NULL
, bytes
, length
); 
 279     catch (const MacOSError 
&err
) { __secapiresult
=err
.osStatus(); } 
 280     catch (const CommonError 
&err
) { __secapiresult
=SecKeychainErrFromOSStatus(err
.osStatus()); } 
 281     catch (const std::bad_alloc 
&) { __secapiresult
=errSecAllocate
; } 
 282     catch (...) { __secapiresult
=errSecInternalComponent
; } 
 289 SecCertificateCopyDNSNames(SecCertificateRef certificate
) 
 291         CFArrayRef names 
= NULL
; 
 292         OSStatus __secapiresult 
= errSecSuccess
; 
 294                 names 
= Certificate::required(certificate
)->copyDNSNames(); 
 296         catch (const MacOSError 
&err
) { __secapiresult
=err
.osStatus(); } 
 297         catch (const CommonError 
&err
) { __secapiresult
=SecKeychainErrFromOSStatus(err
.osStatus()); } 
 298         catch (const std::bad_alloc 
&) { __secapiresult
=errSecAllocate
; } 
 299         catch (...) { __secapiresult
=errSecInternalComponent
; } 
 304 /* OS X only: DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER */ 
 306 SecCertificateGetType(SecCertificateRef certificate
, CSSM_CERT_TYPE 
*certificateType
) 
 308     // This macro converts a new-style SecCertificateRef to an old-style ItemImpl 
 311     Required(certificateType
) = Certificate::required(__itemImplRef
)->type(); 
 316 /* OS X only: DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER */ 
 318 SecCertificateGetSubject(SecCertificateRef certificate
, const CSSM_X509_NAME 
**subject
) 
 320     // This macro converts a new-style SecCertificateRef to an old-style ItemImpl 
 323     Required(subject
) = Certificate::required(__itemImplRef
)->subjectName(); 
 328 /* OS X only: DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER */ 
 330 SecCertificateGetIssuer(SecCertificateRef certificate
, const CSSM_X509_NAME 
**issuer
) 
 332     // This macro converts a new-style SecCertificateRef to an old-style ItemImpl 
 335     Required(issuer
) = Certificate::required(__itemImplRef
)->issuerName(); 
 340 /* OS X only: DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER */ 
 342 SecCertificateGetCLHandle(SecCertificateRef certificate
, CSSM_CL_HANDLE 
*clHandle
) 
 347     Required(clHandle
) = Certificate::required(certificate
)->clHandle(); 
 352     // This macro converts a new-style SecCertificateRef to an old-style ItemImpl 
 355     Required(clHandle
) = Certificate::required(__itemImplRef
)->clHandle(); 
 359         /* bridge code to support deprecated functionality */ 
 360         OSStatus __secapiresult
=errSecSuccess
; 
 362         SecCertificateRef __itemImplRef
=(SecCertificateRef
)SecCertificateCopyKeychainItem(certificate
); 
 363         if (!__itemImplRef
) { __itemImplRef
=SecCertificateCreateItemImplInstance(certificate
); kcItem
=false; } 
 365                 Required(clHandle
) = Certificate::required(__itemImplRef
)->clHandle(); 
 367         catch (const MacOSError 
&err
) { __secapiresult
=err
.osStatus(); } 
 368         catch (const CommonError 
&err
) { __secapiresult
=SecKeychainErrFromOSStatus(err
.osStatus()); } 
 369         catch (const std::bad_alloc 
&) { __secapiresult
=errSecAllocate
; } 
 370         catch (...) { __secapiresult
=errSecInternalComponent
; } 
 373                         /* we can't release the temporary certificate, or the CL handle becomes invalid. 
 374                          * for now, just stick the temporary certificate into an array. 
 375                          * TBD: use a dictionary, indexed by hash of certificate. */ 
 376                         static CFMutableArrayRef sLegacyCertArray 
= NULL
; 
 377                         if (!sLegacyCertArray
) { 
 378                                 sLegacyCertArray 
= CFArrayCreateMutable(NULL
, 0, &kCFTypeArrayCallBacks
); 
 379                                 if (!sLegacyCertArray
) { 
 380                                         return errSecAllocate
; 
 383                         CFArrayAppendValue(sLegacyCertArray
, __itemImplRef
); 
 385                         syslog(LOG_ERR
, "WARNING: SecCertificateGetCLHandle called on certificate which is not in a keychain."); 
 388                 CFRelease(__itemImplRef
); 
 390         return __secapiresult
; 
 395 /* private function; assumes input is old-style ItemImpl certificate reference, 
 396    and does not release that certificate reference! 
 399 SecCertificateGetCLHandle_legacy(SecCertificateRef certificate
, CSSM_CL_HANDLE 
*clHandle
) 
 403     Required(clHandle
) = Certificate::required(certificate
)->clHandle(); 
 410  * Private API to infer a display name for a SecCertificateRef which 
 411  * may or may not be in a keychain. 
 416 SecCertificateInferLabel(SecCertificateRef certificate
, CFStringRef 
*label
) 
 418     // This macro converts a new-style SecCertificateRef to an old-style ItemImpl 
 421     Certificate::required(__itemImplRef
)->inferLabel(false, &Required(label
)); 
 426 /* OS X only (note: iOS version has different arguments and return value) */ 
 428 SecCertificateCopyPublicKey(SecCertificateRef certificate
, SecKeyRef 
*key
) 
 430     // This macro converts a new-style SecCertificateRef to an old-style ItemImpl 
 433     Required(key
) = Certificate::required(__itemImplRef
)->publicKey()->handle(); 
 438 /* OS X only: DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER */ 
 440 SecCertificateGetAlgorithmID(SecCertificateRef certificate
, const CSSM_X509_ALGORITHM_IDENTIFIER 
**algid
) 
 442     // This macro converts a new-style SecCertificateRef to an old-style ItemImpl 
 445     Required(algid
) = Certificate::required(__itemImplRef
)->algorithmID(); 
 450 /* OS X only: __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_NA) */ 
 452 SecCertificateCopyCommonName(SecCertificateRef certificate
, CFStringRef 
*commonName
) 
 454     // This macro converts a new-style SecCertificateRef to an old-style ItemImpl 
 457     Required(commonName
) = Certificate::required(__itemImplRef
)->commonName(); 
 465 SecCertificateCopySubjectSummary(SecCertificateRef certificate
) 
 467         CFStringRef summary 
= NULL
; 
 468     OSStatus __secapiresult
; 
 470                 Certificate::required(certificate
)->inferLabel(false, &summary
); 
 472                 __secapiresult
=errSecSuccess
; 
 474         catch (const MacOSError 
&err
) { __secapiresult
=err
.osStatus(); } 
 475         catch (const CommonError 
&err
) { __secapiresult
=SecKeychainErrFromOSStatus(err
.osStatus()); } 
 476         catch (const std::bad_alloc 
&) { __secapiresult
=errSecAllocate
; } 
 477         catch (...) { __secapiresult
=errSecInternalComponent
; } 
 484 SecCertificateCopyIssuerSummary(SecCertificateRef certificate
) 
 486         CFStringRef issuerStr 
= NULL
; 
 487         SecCertificateRefP certP 
= NULL
; 
 488         CFDataRef certData 
= SecCertificateCopyData(certificate
); 
 490                 certP 
= SecCertificateCreateWithDataP(NULL
, certData
); 
 494                 issuerStr 
= SecCertificateCopyIssuerSummaryP(certP
); 
 503 SecCertificateCopySubjectComponent(SecCertificateRef certificate
, const CSSM_OID 
*component
, CFStringRef 
*result
) 
 505     // This macro converts a new-style SecCertificateRef to an old-style ItemImpl 
 508     Required(result
) = Certificate::required(__itemImplRef
)->distinguishedName(&CSSMOID_X509V1SubjectNameCStruct
, component
); 
 513 /* OS X only; deprecated SPI */ 
 515 SecCertificateGetCommonName(SecCertificateRef certificate
, CFStringRef 
*commonName
) 
 517     // deprecated SPI signature; replaced by SecCertificateCopyCommonName 
 518     return SecCertificateCopyCommonName(certificate
, commonName
); 
 521 /* OS X only; deprecated SPI */ 
 523 SecCertificateGetEmailAddress(SecCertificateRef certificate
, CFStringRef 
*emailAddress
) 
 525     // This macro converts a new-style SecCertificateRef to an old-style ItemImpl 
 528     Required(emailAddress
) = Certificate::required(__itemImplRef
)->copyFirstEmailAddress(); 
 535 SecCertificateCopyEmailAddresses(SecCertificateRef certificate
, CFArrayRef 
*emailAddresses
) 
 537     // This macro converts a new-style SecCertificateRef to an old-style ItemImpl 
 540     Required(emailAddresses
) = Certificate::required(__itemImplRef
)->copyEmailAddresses(); 
 545 /* Return a zero terminated list of CSSM_DATA_PTR's with the values of the field specified by field. 
 546  * Caller must call releaseFieldValues to free the storage allocated by this call. 
 551 SecCertificateCopyFieldValues(SecCertificateRef certificate
, const CSSM_OID 
*field
, CSSM_DATA_PTR 
**fieldValues
) 
 553     // This macro converts a new-style SecCertificateRef to an old-style ItemImpl 
 556     Required(fieldValues
) = Certificate::required(__itemImplRef
)->copyFieldValues(Required(field
)); 
 563 SecCertificateReleaseFieldValues(SecCertificateRef certificate
, const CSSM_OID 
*field
, CSSM_DATA_PTR 
*fieldValues
) 
 565     // This macro converts a new-style SecCertificateRef to an old-style ItemImpl 
 568     Certificate::required(__itemImplRef
)->releaseFieldValues(Required(field
), fieldValues
); 
 575 SecCertificateCopyFirstFieldValue(SecCertificateRef certificate
, const CSSM_OID 
*field
, CSSM_DATA_PTR 
*fieldValue
) 
 577     // This macro converts a new-style SecCertificateRef to an old-style ItemImpl 
 580     Required(fieldValue
) = Certificate::required(__itemImplRef
)->copyFirstFieldValue(Required(field
)); 
 587 SecCertificateReleaseFirstFieldValue(SecCertificateRef certificate
, const CSSM_OID 
*field
, CSSM_DATA_PTR fieldValue
) 
 589     // This macro converts a new-style SecCertificateRef to an old-style ItemImpl 
 592     Certificate::required(__itemImplRef
)->releaseFieldValue(Required(field
), fieldValue
); 
 599 SecCertificateFindByIssuerAndSN(CFTypeRef keychainOrArray
,const CSSM_DATA 
*issuer
, 
 600         const CSSM_DATA 
*serialNumber
, SecCertificateRef 
*certificate
) 
 604         StorageManager::KeychainList keychains
; 
 605         globals().storageManager
.optionalSearchList(keychainOrArray
, keychains
); 
 606         Required(certificate
) = Certificate::findByIssuerAndSN(keychains
, CssmData::required(issuer
), CssmData::required(serialNumber
))->handle(); 
 609     // convert ItemImpl-based SecCertificateRef to new-world version before returning 
 610         CssmData certData 
= Certificate::required(*certificate
)->data(); 
 611         CFRef
<CFDataRef
> cfData(CFDataCreate(NULL
, certData
.Data
, certData
.Length
)); 
 612         SecCertificateRef tmpRef 
= *certificate
; 
 613         *certificate 
= SecCertificateCreateWithData(NULL
, cfData
); 
 622 SecCertificateFindBySubjectKeyID(CFTypeRef keychainOrArray
, const CSSM_DATA 
*subjectKeyID
, 
 623         SecCertificateRef 
*certificate
) 
 627         StorageManager::KeychainList keychains
; 
 628         globals().storageManager
.optionalSearchList(keychainOrArray
, keychains
); 
 629         Required(certificate
) = Certificate::findBySubjectKeyID(keychains
, CssmData::required(subjectKeyID
))->handle(); 
 632     // convert ItemImpl-based SecCertificateRef to new-world version before returning 
 633         CssmData certData 
= Certificate::required(*certificate
)->data(); 
 634         CFRef
<CFDataRef
> cfData(CFDataCreate(NULL
, certData
.Data
, certData
.Length
)); 
 635         SecCertificateRef tmpRef 
= *certificate
; 
 636         *certificate 
= SecCertificateCreateWithData(NULL
, cfData
); 
 645 SecCertificateFindByEmail(CFTypeRef keychainOrArray
, const char *emailAddress
, SecCertificateRef 
*certificate
) 
 649         StorageManager::KeychainList keychains
; 
 650         globals().storageManager
.optionalSearchList(keychainOrArray
, keychains
); 
 651         Required(certificate
) = Certificate::findByEmail(keychains
, emailAddress
)->handle(); 
 654     // convert ItemImpl-based SecCertificateRef to new-world version before returning 
 655         CssmData certData 
= Certificate::required(*certificate
)->data(); 
 656         CFRef
<CFDataRef
> cfData(CFDataCreate(NULL
, certData
.Data
, certData
.Length
)); 
 657         SecCertificateRef tmpRef 
= *certificate
; 
 658         *certificate 
= SecCertificateCreateWithData(NULL
, cfData
); 
 667 SecKeychainSearchCreateForCertificateByIssuerAndSN(CFTypeRef keychainOrArray
, const CSSM_DATA 
*issuer
, 
 668         const CSSM_DATA 
*serialNumber
, SecKeychainSearchRef 
*searchRef
) 
 674         StorageManager::KeychainList keychains
; 
 675         globals().storageManager
.optionalSearchList(keychainOrArray
, keychains
); 
 676         KCCursor 
cursor(Certificate::cursorForIssuerAndSN(keychains
, CssmData::required(issuer
), CssmData::required(serialNumber
))); 
 677         *searchRef 
= cursor
->handle(); 
 684 SecKeychainSearchCreateForCertificateByIssuerAndSN_CF(CFTypeRef keychainOrArray
, CFDataRef issuer
, 
 685         CFDataRef serialNumber
, SecKeychainSearchRef 
*searchRef
) 
 691         StorageManager::KeychainList keychains
; 
 692         globals().storageManager
.optionalSearchList(keychainOrArray
, keychains
); 
 694         Required(serialNumber
); 
 695         KCCursor 
cursor(Certificate::cursorForIssuerAndSN_CF(keychains
, issuer
, serialNumber
)); 
 696         *searchRef 
= cursor
->handle(); 
 703 SecKeychainSearchCreateForCertificateBySubjectKeyID(CFTypeRef keychainOrArray
, const CSSM_DATA 
*subjectKeyID
, 
 704         SecKeychainSearchRef 
*searchRef
) 
 710         StorageManager::KeychainList keychains
; 
 711         globals().storageManager
.optionalSearchList(keychainOrArray
, keychains
); 
 712         KCCursor 
cursor(Certificate::cursorForSubjectKeyID(keychains
, CssmData::required(subjectKeyID
))); 
 713         *searchRef 
= cursor
->handle(); 
 720 SecKeychainSearchCreateForCertificateByEmail(CFTypeRef keychainOrArray
, const char *emailAddress
, 
 721         SecKeychainSearchRef 
*searchRef
) 
 727         StorageManager::KeychainList keychains
; 
 728         globals().storageManager
.optionalSearchList(keychainOrArray
, keychains
); 
 729         KCCursor 
cursor(Certificate::cursorForEmail(keychains
, emailAddress
)); 
 730         *searchRef 
= cursor
->handle(); 
 737 SecDigestGetData (CSSM_ALGORITHMS alg
, CSSM_DATA
* digest
, const CSSM_DATA
* data
) 
 741         if (!digest 
|| !digest
->Data 
|| !digest
->Length 
|| !data 
|| !data
->Data 
|| !data
->Length
) 
 744         CSP 
csp(gGuidAppleCSP
); 
 745         Digest 
context(csp
, alg
); 
 746         CssmData 
input(data
->Data
, data
->Length
); 
 747         CssmData 
output(digest
->Data
, digest
->Length
); 
 749         context
.digest(input
, output
); 
 750         digest
->Length 
= output
.length(); 
 757 /* determine whether a cert is self-signed */ 
 758 OSStatus 
SecCertificateIsSelfSigned( 
 759         SecCertificateRef certificate
, 
 760         Boolean 
*isSelfSigned
)          /* RETURNED */ 
 764         *isSelfSigned 
= Certificate::required(certificate
)->isSelfSigned(); 
 770 /* OS X only: DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER */ 
 772 SecCertificateCopyPreference( 
 774     CSSM_KEYUSE keyUsage
, 
 775     SecCertificateRef 
*certificate
) 
 780         Required(certificate
); 
 781         StorageManager::KeychainList keychains
; 
 782         globals().storageManager
.getSearchList(keychains
); 
 783         KCCursor 
cursor(keychains
, kSecGenericPasswordItemClass
, NULL
); 
 785         char idUTF8
[MAXPATHLEN
]; 
 786     if (!CFStringGetCString(name
, idUTF8
, sizeof(idUTF8
)-1, kCFStringEncodingUTF8
)) 
 787         idUTF8
[0] = (char)'\0'; 
 788     CssmData 
service(const_cast<char *>(idUTF8
), strlen(idUTF8
)); 
 789     FourCharCode itemType 
= 'cprf'; 
 790     cursor
->add(CSSM_DB_EQUAL
, Schema::attributeInfo(kSecServiceItemAttr
), service
); 
 791         cursor
->add(CSSM_DB_EQUAL
, Schema::attributeInfo(kSecTypeItemAttr
), itemType
); 
 793         cursor
->add(CSSM_DB_EQUAL
, Schema::attributeInfo(kSecScriptCodeItemAttr
), (sint32
)keyUsage
); 
 796         if (!cursor
->next(prefItem
)) 
 797                 MacOSError::throwMe(errSecItemNotFound
); 
 799         // get persistent certificate reference 
 800         SecKeychainAttribute itemAttrs
[] = { { kSecGenericItemAttr
, 0, NULL 
} }; 
 801         SecKeychainAttributeList itemAttrList 
= { sizeof(itemAttrs
) / sizeof(itemAttrs
[0]), itemAttrs 
}; 
 802         prefItem
->getContent(NULL
, &itemAttrList
, NULL
, NULL
); 
 804         // find certificate, given persistent reference data 
 805         CFDataRef pItemRef 
= CFDataCreateWithBytesNoCopy(NULL
, (const UInt8 
*)itemAttrs
[0].data
, itemAttrs
[0].length
, kCFAllocatorNull
); 
 806         SecKeychainItemRef certItemRef 
= nil
; 
 807         OSStatus status 
= SecKeychainItemCopyFromPersistentReference(pItemRef
, &certItemRef
); //%%% need to make this a method of ItemImpl 
 808         prefItem
->freeContent(&itemAttrList
, NULL
); 
 814         *certificate 
= (SecCertificateRef
)certItemRef
; 
 817         // convert ItemImpl-based SecCertificateRef to new-world version before returning 
 818         CssmData certData 
= Certificate::required(*certificate
)->data(); 
 819         CFRef
<CFDataRef
> cfData(CFDataCreate(NULL
, certData
.Data
, certData
.Length
)); 
 820         SecCertificateRef tmpRef 
= *certificate
; 
 821         *certificate 
= SecCertificateCreateWithData(NULL
, cfData
); 
 830 SecCertificateCopyPreferred( 
 834         // This function will look for a matching preference in the following order: 
 835         // - matches the name and the supplied key use 
 836         // - matches the name and the special 'ANY' key use 
 837         // - matches the name with no key usage constraint 
 839         SecCertificateRef certRef 
= NULL
; 
 840         CSSM_KEYUSE keyUse 
= ConvertArrayToKeyUsage(keyUsage
); 
 841         OSStatus status 
= SecCertificateCopyPreference(name
, keyUse
, &certRef
); 
 842         if (status 
!= errSecSuccess 
&& keyUse 
!= CSSM_KEYUSE_ANY
) 
 843                 status 
= SecCertificateCopyPreference(name
, CSSM_KEYUSE_ANY
, &certRef
); 
 844         if (status 
!= errSecSuccess 
&& keyUse 
!= 0) 
 845                 status 
= SecCertificateCopyPreference(name
, 0, &certRef
); 
 850 /* OS X only; not exported */ 
 852 SecCertificateFindPreferenceItemWithNameAndKeyUsage( 
 853         CFTypeRef keychainOrArray
, 
 856         SecKeychainItemRef 
*itemRef
) 
 860         StorageManager::KeychainList keychains
; 
 861         globals().storageManager
.optionalSearchList(keychainOrArray
, keychains
); 
 862         KCCursor 
cursor(keychains
, kSecGenericPasswordItemClass
, NULL
); 
 864         char idUTF8
[MAXPATHLEN
]; 
 865     idUTF8
[0] = (char)'\0'; 
 868                 if (!CFStringGetCString(name
, idUTF8
, sizeof(idUTF8
)-1, kCFStringEncodingUTF8
)) 
 869                         idUTF8
[0] = (char)'\0'; 
 871     size_t idUTF8Len 
= strlen(idUTF8
); 
 873         MacOSError::throwMe(errSecParam
); 
 875     CssmData 
service(const_cast<char *>(idUTF8
), idUTF8Len
); 
 876     cursor
->add(CSSM_DB_EQUAL
, Schema::attributeInfo(kSecServiceItemAttr
), service
); 
 877         cursor
->add(CSSM_DB_EQUAL
, Schema::attributeInfo(kSecTypeItemAttr
), (FourCharCode
)'cprf'); 
 879         cursor
->add(CSSM_DB_EQUAL
, Schema::attributeInfo(kSecScriptCodeItemAttr
), (sint32
)keyUsage
); 
 882         if (!cursor
->next(item
)) 
 883                 MacOSError::throwMe(errSecItemNotFound
); 
 886                 *itemRef
=item
->handle(); 
 891 /* OS X only; not exported */ 
 893 OSStatus 
SecCertificateDeletePreferenceItemWithNameAndKeyUsage( 
 894         CFTypeRef keychainOrArray
, 
 898         // when a specific key usage is passed, we'll only match & delete that pref; 
 899         // when a key usage of 0 is passed, all matching prefs should be deleted. 
 900         // maxUsages represents the most matches there could theoretically be, so 
 901         // cut things off at that point if we're still finding items (if they can't 
 902         // be deleted for some reason, we'd never break out of the loop.) 
 905         SecKeychainItemRef item 
= NULL
; 
 906         int count 
= 0, maxUsages 
= 12; 
 907         while (++count 
<= maxUsages 
&& 
 908                         (status 
= SecCertificateFindPreferenceItemWithNameAndKeyUsage(keychainOrArray
, name
, keyUsage
, &item
)) == errSecSuccess
) { 
 909                 status 
= SecKeychainItemDelete(item
); 
 914         // it's not an error if the item isn't found 
 915         return (status 
== errSecItemNotFound
) ? errSecSuccess 
: status
; 
 918 /* OS X only: __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_NA) */ 
 919 OSStatus 
SecCertificateSetPreference( 
 920     SecCertificateRef certificate
, 
 922     CSSM_KEYUSE keyUsage
, 
 929                 // treat NULL certificate as a request to clear the preference 
 930                 // (note: if keyUsage is 0, this clears all key usage prefs for name) 
 931                 return SecCertificateDeletePreferenceItemWithNameAndKeyUsage(NULL
, name
, keyUsage
); 
 934     // This macro converts a new-style SecCertificateRef to an old-style ItemImpl 
 937         // determine the account attribute 
 939         // This attribute must be synthesized from certificate label + pref item type + key usage, 
 940         // as only the account and service attributes can make a generic keychain item unique. 
 941         // For 'iprf' type items (but not 'cprf'), we append a trailing space. This insures that 
 942         // we can save a certificate preference if an identity preference already exists for the 
 943         // given service name, and vice-versa. 
 944         // If the key usage is 0 (i.e. the normal case), we omit the appended key usage string. 
 946     CFStringRef labelStr 
= nil
; 
 947         Certificate::required(__itemImplRef
)->inferLabel(false, &labelStr
); 
 949         MacOSError::throwMe(errSecDataTooLarge
); // data is "in a format which cannot be displayed" 
 951         CFIndex accountUTF8Len 
= CFStringGetMaximumSizeForEncoding(CFStringGetLength(labelStr
), kCFStringEncodingUTF8
) + 1; 
 952         const char *templateStr 
= "%s [key usage 0x%X]"; 
 953         const int keyUsageMaxStrLen 
= 8; 
 954         accountUTF8Len 
+= strlen(templateStr
) + keyUsageMaxStrLen
; 
 955         char accountUTF8
[accountUTF8Len
]; 
 956     if (!CFStringGetCString(labelStr
, accountUTF8
, accountUTF8Len
-1, kCFStringEncodingUTF8
)) 
 957                 accountUTF8
[0] = (char)'\0'; 
 959                 snprintf(accountUTF8
, accountUTF8Len
-1, templateStr
, accountUTF8
, keyUsage
); 
 960     CssmData 
account(const_cast<char *>(accountUTF8
), strlen(accountUTF8
)); 
 963         // service attribute (name provided by the caller) 
 964         CFIndex serviceUTF8Len 
= CFStringGetMaximumSizeForEncoding(CFStringGetLength(name
), kCFStringEncodingUTF8
) + 1;; 
 965         char serviceUTF8
[serviceUTF8Len
]; 
 966     if (!CFStringGetCString(name
, serviceUTF8
, serviceUTF8Len
-1, kCFStringEncodingUTF8
)) 
 967         serviceUTF8
[0] = (char)'\0'; 
 968     CssmData 
service(const_cast<char *>(serviceUTF8
), strlen(serviceUTF8
)); 
 970     // look for existing preference item, in case this is an update 
 971         StorageManager::KeychainList keychains
; 
 972         globals().storageManager
.getSearchList(keychains
); 
 973         KCCursor 
cursor(keychains
, kSecGenericPasswordItemClass
, NULL
); 
 974     FourCharCode itemType 
= 'cprf'; 
 975     cursor
->add(CSSM_DB_EQUAL
, Schema::attributeInfo(kSecServiceItemAttr
), service
); 
 976         cursor
->add(CSSM_DB_EQUAL
, Schema::attributeInfo(kSecTypeItemAttr
), itemType
); 
 978         cursor
->add(CSSM_DB_EQUAL
, Schema::attributeInfo(kSecScriptCodeItemAttr
), (sint32
)keyUsage
); 
 982         Item 
item(kSecGenericPasswordItemClass
, 'aapl', 0, NULL
, false); 
 983     bool add 
= (!cursor
->next(item
)); 
 984         // at this point, we either have a new item to add or an existing item to update 
 986     // set item attribute values 
 987     item
->setAttribute(Schema::attributeInfo(kSecServiceItemAttr
), service
); 
 988     item
->setAttribute(Schema::attributeInfo(kSecTypeItemAttr
), itemType
); 
 989     item
->setAttribute(Schema::attributeInfo(kSecAccountItemAttr
), account
); 
 990     item
->setAttribute(Schema::attributeInfo(kSecScriptCodeItemAttr
), (sint32
)keyUsage
); 
 991     item
->setAttribute(Schema::attributeInfo(kSecLabelItemAttr
), service
); 
 997         // generic attribute (store persistent certificate reference) 
 998         CFDataRef pItemRef 
= nil
; 
 999         Certificate::required(__itemImplRef
)->copyPersistentReference(pItemRef
); 
1001                 MacOSError::throwMe(errSecInvalidItemRef
); 
1003         const UInt8 
*dataPtr 
= CFDataGetBytePtr(pItemRef
); 
1004         CFIndex dataLen 
= CFDataGetLength(pItemRef
); 
1005         CssmData 
pref(const_cast<void *>(reinterpret_cast<const void *>(dataPtr
)), dataLen
); 
1006         item
->setAttribute(Schema::attributeInfo(kSecGenericItemAttr
), pref
); 
1007         CFRelease(pItemRef
); 
1010         Keychain keychain 
= nil
; 
1012             keychain 
= globals().storageManager
.defaultKeychain(); 
1013             if (!keychain
->exists()) 
1014                 MacOSError::throwMe(errSecNoSuchKeychain
);      // Might be deleted or not available at this time. 
1017             keychain 
= globals().storageManager
.defaultKeychainUI(item
); 
1021                         keychain
->add(item
); 
1023                 catch (const MacOSError 
&err
) { 
1024                         if (err
.osStatus() != errSecDuplicateItem
) 
1025                                 throw; // if item already exists, fall through to update 
1033 /* OS X only: __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_NA) */ 
1034 OSStatus 
SecCertificateSetPreferred( 
1035         SecCertificateRef certificate
, 
1037         CFArrayRef keyUsage
) 
1039         CSSM_KEYUSE keyUse 
= ConvertArrayToKeyUsage(keyUsage
); 
1040         return SecCertificateSetPreference(certificate
, name
, keyUse
, NULL
); 
1043 /* OS X only: __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_NA) */ 
1044 CFDictionaryRef 
SecCertificateCopyValues(SecCertificateRef certificate
, CFArrayRef keys
, CFErrorRef 
*error
) 
1046         CFDictionaryRef result 
= NULL
; 
1047         OSStatus __secapiresult
; 
1050                 CertificateValues 
cv(certificate
); 
1051                 result 
= cv
.copyFieldValues(keys
,error
); 
1054         catch (const MacOSError 
&err
) { __secapiresult
=err
.osStatus(); } 
1055         catch (const CommonError 
&err
) { __secapiresult
=SecKeychainErrFromOSStatus(err
.osStatus()); } 
1056         catch (const std::bad_alloc 
&) { __secapiresult
=errSecAllocate
; } 
1057         catch (...) { __secapiresult
=errSecInternalComponent
; } 
1061 /* OS X only: __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_NA) */ 
1062 CFStringRef 
SecCertificateCopyLongDescription(CFAllocatorRef alloc
, SecCertificateRef certificate
, CFErrorRef 
*error
) 
1064         return SecCertificateCopyShortDescription(alloc
, certificate
, error
); 
1067 /* OS X only: __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_NA) */ 
1068 CFStringRef 
SecCertificateCopyShortDescription(CFAllocatorRef alloc
, SecCertificateRef certificate
, CFErrorRef 
*error
) 
1070         CFStringRef result 
= NULL
; 
1071         OSStatus __secapiresult 
= SecCertificateInferLabel(certificate
, &result
); 
1072         if (error
!=NULL 
&& __secapiresult
!=errSecSuccess
) 
1074                 *error 
= CFErrorCreate(kCFAllocatorDefault
, kCFErrorDomainOSStatus
, 
1075                         __secapiresult 
? __secapiresult 
: CSSM_ERRCODE_INTERNAL_ERROR
, NULL
); 
1080 /* OS X only: __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_NA) */ 
1081 CFDataRef 
SecCertificateCopySerialNumber(SecCertificateRef certificate
, CFErrorRef 
*error
) 
1083         CFDataRef result 
= NULL
; 
1084         OSStatus __secapiresult
; 
1087                 CertificateValues 
cv(certificate
); 
1088                 result 
= cv
.copySerialNumber(error
); 
1091         catch (const MacOSError 
&err
) { __secapiresult
=err
.osStatus(); } 
1092         catch (const CommonError 
&err
) { __secapiresult
=SecKeychainErrFromOSStatus(err
.osStatus()); } 
1093         catch (const std::bad_alloc 
&) { __secapiresult
=errSecAllocate
; } 
1094         catch (...) { __secapiresult
=errSecInternalComponent
; } 
1098 /* OS X only: __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_NA) */ 
1099 CFDataRef 
SecCertificateCopyNormalizedIssuerContent(SecCertificateRef certificate
, CFErrorRef 
*error
) 
1101         CFDataRef result 
= NULL
; 
1102         OSStatus __secapiresult
; 
1105                 CertificateValues 
cv(certificate
); 
1106                 result 
= cv
.copyNormalizedIssuerContent(error
); 
1109         catch (const MacOSError 
&err
) { __secapiresult
=err
.osStatus(); } 
1110         catch (const CommonError 
&err
) { __secapiresult
=SecKeychainErrFromOSStatus(err
.osStatus()); } 
1111         catch (const std::bad_alloc 
&) { __secapiresult
=errSecAllocate
; } 
1112         catch (...) { __secapiresult
=errSecInternalComponent
; } 
1116 /* OS X only: __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_NA) */ 
1117 CFDataRef 
SecCertificateCopyNormalizedSubjectContent(SecCertificateRef certificate
, CFErrorRef 
*error
) 
1119         CFDataRef result 
= NULL
; 
1120         OSStatus __secapiresult
; 
1123                 CertificateValues 
cv(certificate
); 
1124                 result 
= cv
.copyNormalizedSubjectContent(error
); 
1127         catch (const MacOSError 
&err
) { __secapiresult
=err
.osStatus(); } 
1128         catch (const CommonError 
&err
) { __secapiresult
=SecKeychainErrFromOSStatus(err
.osStatus()); } 
1129         catch (const std::bad_alloc 
&) { __secapiresult
=errSecAllocate
; } 
1130         catch (...) { __secapiresult
=errSecInternalComponent
; } 
1135 CFDataRef 
SecCertificateCopyIssuerSequence(SecCertificateRef certificate
) 
1137         CFDataRef result 
= NULL
; 
1138         OSStatus __secapiresult
; 
1141                 CertificateValues 
cv(certificate
); 
1142                 result 
= cv
.copyIssuerSequence(NULL
); 
1145         catch (const MacOSError 
&err
) { __secapiresult
=err
.osStatus(); } 
1146         catch (const CommonError 
&err
) { __secapiresult
=SecKeychainErrFromOSStatus(err
.osStatus()); } 
1147         catch (const std::bad_alloc 
&) { __secapiresult
=errSecAllocate
; } 
1148         catch (...) { __secapiresult
=errSecInternalComponent
; } 
1154 CFDataRef 
SecCertificateCopySubjectSequence(SecCertificateRef certificate
) 
1156         CFDataRef result 
= NULL
; 
1157         OSStatus __secapiresult
; 
1160                 CertificateValues 
cv(certificate
); 
1161                 result 
= cv
.copySubjectSequence(NULL
); 
1164         catch (const MacOSError 
&err
) { __secapiresult
=err
.osStatus(); } 
1165         catch (const CommonError 
&err
) { __secapiresult
=SecKeychainErrFromOSStatus(err
.osStatus()); } 
1166         catch (const std::bad_alloc 
&) { __secapiresult
=errSecAllocate
; } 
1167         catch (...) { __secapiresult
=errSecInternalComponent
; } 
1173 bool SecCertificateIsValid(SecCertificateRef certificate
, CFAbsoluteTime verifyTime
) 
1176         OSStatus __secapiresult
; 
1179                 CFErrorRef error 
= NULL
; 
1180                 CertificateValues 
cv(certificate
); 
1181                 result 
= cv
.isValid(verifyTime
, &error
); 
1182                 if (error
) CFRelease(error
); 
1185         catch (const MacOSError 
&err
) { __secapiresult
=err
.osStatus(); } 
1186         catch (const CommonError 
&err
) { __secapiresult
=SecKeychainErrFromOSStatus(err
.osStatus()); } 
1187         catch (const std::bad_alloc 
&) { __secapiresult
=errSecAllocate
; } 
1188         catch (...) { __secapiresult
=errSecInternalComponent
; } 
1193 /* OS X only: __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_7, __MAC_10_9, __IPHONE_NA, __IPHONE_NA) */ 
1194 bool SecCertificateIsValidX(SecCertificateRef certificate
, CFAbsoluteTime verifyTime
) 
1197      * deprecated function name 
1199         return SecCertificateIsValid(certificate
, verifyTime
); 
1203 CFAbsoluteTime 
SecCertificateNotValidBefore(SecCertificateRef certificate
) 
1205         CFAbsoluteTime result 
= 0; 
1206         OSStatus __secapiresult
; 
1209                 CFErrorRef error 
= NULL
; 
1210                 CertificateValues 
cv(certificate
); 
1211                 result 
= cv
.notValidBefore(&error
); 
1212                 if (error
) CFRelease(error
); 
1215         catch (const MacOSError 
&err
) { __secapiresult
=err
.osStatus(); } 
1216         catch (const CommonError 
&err
) { __secapiresult
=SecKeychainErrFromOSStatus(err
.osStatus()); } 
1217         catch (const std::bad_alloc 
&) { __secapiresult
=errSecAllocate
; } 
1218         catch (...) { __secapiresult
=errSecInternalComponent
; } 
1224 CFAbsoluteTime 
SecCertificateNotValidAfter(SecCertificateRef certificate
) 
1226         CFAbsoluteTime result 
= 0; 
1227         OSStatus __secapiresult
; 
1230                 CFErrorRef error 
= NULL
; 
1231                 CertificateValues 
cv(certificate
); 
1232                 result 
= cv
.notValidAfter(&error
); 
1233                 if (error
) CFRelease(error
); 
1236         catch (const MacOSError 
&err
) { __secapiresult
=err
.osStatus(); } 
1237         catch (const CommonError 
&err
) { __secapiresult
=SecKeychainErrFromOSStatus(err
.osStatus()); } 
1238         catch (const std::bad_alloc 
&) { __secapiresult
=errSecAllocate
; } 
1239         catch (...) { __secapiresult
=errSecInternalComponent
; } 
1246 SecCertificateRef 
SecCertificateCreateWithBytes(CFAllocatorRef allocator
, 
1247     const UInt8 
*bytes
, CFIndex length
) 
1249         SecCertificateRef certificate 
= NULL
; 
1250         OSStatus __secapiresult
; 
1252                 CSSM_DATA cssmCertData 
= { (CSSM_SIZE
)length
, (uint8 
*)bytes 
}; 
1254                 //NOTE: there isn't yet a Certificate constructor which accepts a CFAllocatorRef 
1255                 SecPointer
<Certificate
> certificatePtr(new Certificate(cssmCertData
, CSSM_CERT_X_509v3
, CSSM_CERT_ENCODING_DER
)); 
1256                 certificate 
= certificatePtr
->handle(); 
1258                 __secapiresult
=errSecSuccess
; 
1260         catch (const MacOSError 
&err
) { __secapiresult
=err
.osStatus(); } 
1261         catch (const CommonError 
&err
) { __secapiresult
=SecKeychainErrFromOSStatus(err
.osStatus()); } 
1262         catch (const std::bad_alloc 
&) { __secapiresult
=errSecAllocate
; } 
1263         catch (...) { __secapiresult
=errSecInternalComponent
; } 
1270 CFIndex 
SecCertificateGetLength(SecCertificateRef certificate
) 
1273         OSStatus __secapiresult
; 
1275                 CssmData output 
= Certificate::required(certificate
)->data(); 
1276                 length 
= (CFIndex
)output
.length(); 
1277                 __secapiresult
=errSecSuccess
; 
1279         catch (const MacOSError 
&err
) { __secapiresult
=err
.osStatus(); } 
1280         catch (const CommonError 
&err
) { __secapiresult
=SecKeychainErrFromOSStatus(err
.osStatus()); } 
1281         catch (const std::bad_alloc 
&) { __secapiresult
=errSecAllocate
; } 
1282         catch (...) { __secapiresult
=errSecInternalComponent
; } 
1289 const UInt8 
*SecCertificateGetBytePtr(SecCertificateRef certificate
) 
1291         const UInt8 
*bytes 
= NULL
; 
1292         OSStatus __secapiresult
; 
1294                 CssmData output 
= Certificate::required(certificate
)->data(); 
1295                 bytes 
= (const UInt8 
*)output
.data(); 
1296                 __secapiresult
=errSecSuccess
; 
1298         catch (const MacOSError 
&err
) { __secapiresult
=err
.osStatus(); } 
1299         catch (const CommonError 
&err
) { __secapiresult
=SecKeychainErrFromOSStatus(err
.osStatus()); } 
1300         catch (const std::bad_alloc 
&) { __secapiresult
=errSecAllocate
; } 
1301         catch (...) { __secapiresult
=errSecInternalComponent
; } 
1308 static CFArrayRef 
CopyEscrowCertificates(SecCertificateEscrowRootType escrowRootType
, CFErrorRef 
*error
) 
1310         // Return array of CFDataRef certificates. 
1311     CFArrayRef result 
= NULL
; 
1315         // Get the hard coded set of production roots 
1316         // static struct RootRecord* kProductionEscrowRoots[] = {&kOldEscrowRootRecord, &kProductionEscrowRootRecord}; 
1318         struct RootRecord
** pEscrowRoots 
= NULL
; 
1319         switch (escrowRootType
) { 
1320                 case kSecCertificateBaselineEscrowRoot
: 
1321                         numRoots 
= kNumberOfBaseLineEscrowRoots
; 
1322                         pEscrowRoots 
= kBaseLineEscrowRoots
; 
1324                 case kSecCertificateProductionEscrowRoot
: 
1325                         numRoots 
= kNumberOfBaseLineEscrowRoots
; //%%% currently, production == baseline on OS X 
1326                         pEscrowRoots 
= kBaseLineEscrowRoots
; 
1328                 case kSecCertificateBaselinePCSEscrowRoot
: 
1329                         numRoots 
= kNumberOfBaseLinePCSEscrowRoots
; 
1330                         pEscrowRoots 
= kBaseLinePCSEscrowRoots
; 
1332                 case kSecCertificateProductionPCSEscrowRoot
: 
1333                         numRoots 
= kNumberOfBaseLinePCSEscrowRoots
; //%%% currently, production == baseline on OS X 
1334                         pEscrowRoots 
= kBaseLinePCSEscrowRoots
; 
1340         CFDataRef productionCerts
[numRoots
]; 
1341         struct RootRecord
* pRootRecord 
= NULL
; 
1343         for (iCnt 
= 0; pEscrowRoots 
!= NULL 
&& iCnt 
< numRoots
; iCnt
++) 
1345                 pRootRecord 
= pEscrowRoots
[iCnt
]; 
1346                 if (NULL 
!= pRootRecord 
&& pRootRecord
->_length 
> 0 && NULL 
!= pRootRecord
->_bytes
) 
1348                         productionCerts
[iCnt
] = CFDataCreate(kCFAllocatorDefault
, pRootRecord
->_bytes
, pRootRecord
->_length
); 
1351         result 
= CFArrayCreate(kCFAllocatorDefault
, (const void **)productionCerts
, numRoots
, &kCFTypeArrayCallBacks
); 
1352         for (iCnt 
= 0; iCnt 
< numRoots
; iCnt
++) 
1354                 if (NULL 
!= productionCerts
[iCnt
]) 
1356                         CFRelease(productionCerts
[iCnt
]); 
1366 CFArrayRef 
SecCertificateCopyEscrowRoots(SecCertificateEscrowRootType escrowRootType
) 
1368         CFArrayRef result 
= NULL
; 
1371         CFDataRef certData 
= NULL
; 
1373         // The request is for the base line certificates. 
1374         // Use the hard coded data to generate the return array 
1375         if (kSecCertificateBaselineEscrowRoot 
== escrowRootType
) 
1377                 // Get the hard coded set of roots 
1378                 numRoots 
= kNumberOfBaseLineEscrowRoots
; 
1379             SecCertificateRef baseLineCerts
[numRoots
]; 
1380             struct RootRecord
* pRootRecord 
= NULL
; 
1382             for (iCnt 
= 0; iCnt 
< numRoots
; iCnt
++) 
1384                 pRootRecord 
= kBaseLineEscrowRoots
[iCnt
]; 
1385                 if (NULL 
!= pRootRecord 
&& pRootRecord
->_length 
> 0 && NULL 
!= pRootRecord
->_bytes
) 
1387                                 certData 
= CFDataCreate(kCFAllocatorDefault
, pRootRecord
->_bytes
, pRootRecord
->_length
); 
1388                                 if (NULL 
!= certData
) 
1390                                         baseLineCerts
[iCnt
] = SecCertificateCreateWithData(kCFAllocatorDefault
, certData
); 
1391                                         CFRelease(certData
); 
1395                 result 
= CFArrayCreate(kCFAllocatorDefault
, (const void **)baseLineCerts
, numRoots
, &kCFTypeArrayCallBacks
); 
1396                 for (iCnt 
= 0; iCnt 
< numRoots
; iCnt
++) 
1398                         if (NULL 
!= baseLineCerts
[iCnt
]) 
1400                                 CFRelease(baseLineCerts
[iCnt
]); 
1404         // The request is for the current certificates. 
1407                 CFErrorRef error 
= NULL
; 
1408                 CFArrayRef cert_datas 
= CopyEscrowCertificates(escrowRootType
, &error
); 
1409                 if (NULL 
!= error 
|| NULL 
== cert_datas 
|| 0 == (numRoots 
= (int)CFArrayGetCount(cert_datas
))) 
1416                         if (NULL 
!= cert_datas
) 
1418                                 CFRelease(cert_datas
); 
1423                 SecCertificateRef assetCerts
[numRoots
]; 
1424                 for (iCnt 
= 0; iCnt 
< numRoots
; iCnt
++) 
1426                         certData 
= (CFDataRef
)CFArrayGetValueAtIndex(cert_datas
, iCnt
); 
1427                         if (NULL 
!= certData
) 
1429                                 SecCertificateRef aCertRef 
= SecCertificateCreateWithData(kCFAllocatorDefault
, certData
); 
1430                                 assetCerts
[iCnt
] = aCertRef
; 
1434                                 assetCerts
[iCnt
] = NULL
; 
1440                         result 
= CFArrayCreate(kCFAllocatorDefault
, (const void **)assetCerts
, numRoots
, &kCFTypeArrayCallBacks
); 
1441                         for (iCnt 
= 0; iCnt 
< numRoots
; iCnt
++) 
1443                                 if (NULL 
!= assetCerts
[iCnt
]) 
1445                                         CFRelease(assetCerts
[iCnt
]); 
1449                 CFRelease(cert_datas
); 
1458 SecSignatureHashAlgorithm 
SecCertificateGetSignatureHashAlgorithm(SecCertificateRef certificate
) 
1460         SecSignatureHashAlgorithm result 
= kSecSignatureHashAlgorithmUnknown
; 
1461         CSSM_X509_ALGORITHM_IDENTIFIER_PTR algId 
= NULL
; 
1462         CSSM_DATA_PTR fieldValue 
= NULL
; 
1463         CSSM_OID_PTR algOID 
= NULL
; 
1464     const CSSM_OID 
*sigAlgOID 
= &CSSMOID_X509V1SignatureAlgorithm
; 
1467         status 
= SecCertificateCopyFirstFieldValue(certificate
, sigAlgOID
, &fieldValue
); 
1468         if (status 
|| !fieldValue
)  { 
1471         algId 
= (CSSM_X509_ALGORITHM_IDENTIFIER_PTR
)fieldValue
->Data
; 
1472         algOID 
= (algId
) ? &algId
->algorithm 
: NULL
; 
1475                 if (!algOID
->Data 
|| !algOID
->Length
) { 
1478                 /* classify the signature algorithm OID into one of our known types */ 
1479                 if (cuCompareCssmData(algOID
, &CSSMOID_ECDSA_WithSHA512
) || 
1480                         cuCompareCssmData(algOID
, &CSSMOID_SHA512WithRSA
) || 
1481                         cuCompareCssmData(algOID
, &CSSMOID_SHA512
)) { 
1482                         result 
= kSecSignatureHashAlgorithmSHA512
; 
1485                 if (cuCompareCssmData(algOID
, &CSSMOID_ECDSA_WithSHA384
) || 
1486                         cuCompareCssmData(algOID
, &CSSMOID_SHA384WithRSA
) || 
1487                         cuCompareCssmData(algOID
, &CSSMOID_SHA384
)) { 
1488                         result 
= kSecSignatureHashAlgorithmSHA384
; 
1491                 if (cuCompareCssmData(algOID
, &CSSMOID_ECDSA_WithSHA256
) || 
1492                         cuCompareCssmData(algOID
, &CSSMOID_SHA256WithRSA
) || 
1493                         cuCompareCssmData(algOID
, &CSSMOID_SHA256
)) { 
1494                         result 
= kSecSignatureHashAlgorithmSHA256
; 
1497                 if (cuCompareCssmData(algOID
, &CSSMOID_ECDSA_WithSHA224
) || 
1498                         cuCompareCssmData(algOID
, &CSSMOID_SHA224WithRSA
) || 
1499                         cuCompareCssmData(algOID
, &CSSMOID_SHA224
)) { 
1500                         result 
= kSecSignatureHashAlgorithmSHA224
; 
1503                 if (cuCompareCssmData(algOID
, &CSSMOID_ECDSA_WithSHA1
) || 
1504                         cuCompareCssmData(algOID
, &CSSMOID_SHA1WithRSA
) || 
1505                         cuCompareCssmData(algOID
, &CSSMOID_SHA1WithDSA
) || 
1506                         cuCompareCssmData(algOID
, &CSSMOID_SHA1WithDSA_CMS
) || 
1507                         cuCompareCssmData(algOID
, &CSSMOID_SHA1WithDSA_JDK
) || 
1508                         cuCompareCssmData(algOID
, &CSSMOID_SHA1WithRSA_OIW
) || 
1509                         cuCompareCssmData(algOID
, &CSSMOID_APPLE_FEE_SHA1
) || 
1510                         cuCompareCssmData(algOID
, &CSSMOID_SHA1
)) { 
1511                         result 
= kSecSignatureHashAlgorithmSHA1
; 
1514                 if (cuCompareCssmData(algOID
, &CSSMOID_MD5WithRSA
) || 
1515                         cuCompareCssmData(algOID
, &CSSMOID_APPLE_FEE_MD5
) || 
1516                         cuCompareCssmData(algOID
, &CSSMOID_MD5
)) { 
1517                         result 
= kSecSignatureHashAlgorithmMD5
; 
1520                 if (cuCompareCssmData(algOID
, &CSSMOID_MD4WithRSA
) || 
1521                         cuCompareCssmData(algOID
, &CSSMOID_MD4
)) { 
1522                         result 
= kSecSignatureHashAlgorithmMD4
; 
1525                 if (cuCompareCssmData(algOID
, &CSSMOID_MD2WithRSA
) || 
1526                         cuCompareCssmData(algOID
, &CSSMOID_MD2
)) { 
1527                         result 
= kSecSignatureHashAlgorithmMD2
; 
1533         (void)SecCertificateReleaseFirstFieldValue(certificate
, sigAlgOID
, fieldValue
);