2 * Copyright (c) 2002-2013 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 <sys/param.h>
44 #include "CertificateValues.h"
45 #include "SecCertificateP.h"
46 #include "SecCertificatePrivP.h"
48 //#include "AppleBaselineEscrowCertificates.h"
50 //######################################################################
51 //%%% start workaround: rdar://14292830
52 //######################################################################
54 #ifndef sec_AppleBaselineEscrowCertificates_h
55 #define sec_AppleBaselineEscrowCertificates_h
63 /* ==========================================================================
64 Production Escrow Certificates
65 ========================================================================== */
67 static const UInt8 kProductionEscrowRootGM
[] = {
68 0x30,0x82,0x03,0xD0,0x30,0x82,0x02,0xB8,0xA0,0x03,0x02,0x01,0x02,0x02,0x01,0x64,
69 0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x0B,0x05,0x00,0x30,
70 0x79,0x31,0x0C,0x30,0x0A,0x06,0x03,0x55,0x04,0x05,0x13,0x03,0x31,0x30,0x30,0x31,
71 0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,0x53,0x31,0x13,0x30,0x11,
72 0x06,0x03,0x55,0x04,0x0A,0x13,0x0A,0x41,0x70,0x70,0x6C,0x65,0x20,0x49,0x6E,0x63,
73 0x2E,0x31,0x26,0x30,0x24,0x06,0x03,0x55,0x04,0x0B,0x13,0x1D,0x41,0x70,0x70,0x6C,
74 0x65,0x20,0x43,0x65,0x72,0x74,0x69,0x66,0x69,0x63,0x61,0x74,0x69,0x6F,0x6E,0x20,
75 0x41,0x75,0x74,0x68,0x6F,0x72,0x69,0x74,0x79,0x31,0x1F,0x30,0x1D,0x06,0x03,0x55,
76 0x04,0x03,0x13,0x16,0x45,0x73,0x63,0x72,0x6F,0x77,0x20,0x53,0x65,0x72,0x76,0x69,
77 0x63,0x65,0x20,0x52,0x6F,0x6F,0x74,0x20,0x43,0x41,0x30,0x1E,0x17,0x0D,0x31,0x33,
78 0x30,0x38,0x30,0x32,0x32,0x33,0x32,0x34,0x34,0x34,0x5A,0x17,0x0D,0x32,0x33,0x30,
79 0x38,0x30,0x32,0x32,0x33,0x32,0x34,0x34,0x34,0x5A,0x30,0x79,0x31,0x0C,0x30,0x0A,
80 0x06,0x03,0x55,0x04,0x05,0x13,0x03,0x31,0x30,0x30,0x31,0x0B,0x30,0x09,0x06,0x03,
81 0x55,0x04,0x06,0x13,0x02,0x55,0x53,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x0A,
82 0x13,0x0A,0x41,0x70,0x70,0x6C,0x65,0x20,0x49,0x6E,0x63,0x2E,0x31,0x26,0x30,0x24,
83 0x06,0x03,0x55,0x04,0x0B,0x13,0x1D,0x41,0x70,0x70,0x6C,0x65,0x20,0x43,0x65,0x72,
84 0x74,0x69,0x66,0x69,0x63,0x61,0x74,0x69,0x6F,0x6E,0x20,0x41,0x75,0x74,0x68,0x6F,
85 0x72,0x69,0x74,0x79,0x31,0x1F,0x30,0x1D,0x06,0x03,0x55,0x04,0x03,0x13,0x16,0x45,
86 0x73,0x63,0x72,0x6F,0x77,0x20,0x53,0x65,0x72,0x76,0x69,0x63,0x65,0x20,0x52,0x6F,
87 0x6F,0x74,0x20,0x43,0x41,0x30,0x82,0x01,0x22,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,
88 0x86,0xF7,0x0D,0x01,0x01,0x01,0x05,0x00,0x03,0x82,0x01,0x0F,0x00,0x30,0x82,0x01,
89 0x0A,0x02,0x82,0x01,0x01,0x00,0xD0,0xA3,0xF4,0x56,0x7D,0x3F,0x46,0x31,0xD2,0x56,
90 0xA0,0xDF,0x42,0xA0,0x29,0x83,0x1E,0xB9,0x82,0xB5,0xA5,0xFF,0x3E,0xDE,0xB5,0x0F,
91 0x4A,0x8A,0x28,0x60,0xCF,0x75,0xB4,0xA0,0x70,0x7C,0xF5,0xE2,0x94,0xF3,0x22,0x02,
92 0xC8,0x81,0xCE,0x34,0xC7,0x66,0x6A,0x18,0xAA,0xB4,0xFD,0x6D,0xB0,0x0B,0xDD,0x4A,
93 0xDD,0xCF,0xE0,0x08,0x1B,0x1C,0xA6,0xDB,0xBA,0xB2,0xC1,0xA4,0x10,0x5F,0x35,0x4F,
94 0x8B,0x8B,0x7A,0xA3,0xDB,0x3C,0xF6,0x54,0x95,0x42,0xAD,0x2A,0x3B,0xFE,0x06,0x8C,
95 0xE1,0x92,0xF1,0x60,0x97,0x58,0x1B,0xD9,0x8F,0xBE,0xFB,0x46,0x4C,0x29,0x5C,0x1C,
96 0xF0,0x20,0xB6,0x2B,0xA5,0x12,0x09,0x9B,0x28,0x41,0x34,0x97,0x9F,0xF3,0x88,0x4B,
97 0x69,0x72,0xEA,0x3A,0x27,0xB0,0x50,0x1D,0x88,0x29,0x0D,0xBB,0xED,0x04,0xA2,0x11,
98 0xCF,0x0C,0x5B,0x65,0x61,0x35,0xBD,0xF2,0x0D,0xFC,0xE2,0xB9,0x20,0xD3,0xB7,0x03,
99 0x70,0x39,0xD5,0xE0,0x86,0x7C,0x04,0xCC,0xC9,0xA1,0x85,0xB4,0x9B,0xBC,0x88,0x4E,
100 0xD7,0xAD,0x5C,0xFF,0x2C,0x0D,0x80,0x8E,0x51,0x39,0x20,0x8B,0xAF,0x1E,0x46,0x95,
101 0xFA,0x0D,0x1B,0xD2,0xBF,0x80,0xE0,0x9F,0x6D,0x4A,0xF5,0x31,0x67,0x18,0x11,0xA5,
102 0x63,0x27,0x08,0xEE,0xD9,0x07,0x29,0xD0,0xD4,0x36,0x91,0x5B,0xFB,0x4A,0x0B,0x07,
103 0xD1,0x0D,0x79,0x16,0x6E,0x16,0x02,0x23,0x80,0xC6,0x15,0x07,0x6D,0xA0,0x06,0xB6,
104 0x45,0x90,0xB0,0xAE,0xA4,0xAD,0x0E,0x75,0x04,0x2B,0x2B,0x78,0xF1,0x57,0x84,0x23,
105 0x87,0x24,0xEC,0x58,0xC4,0xF1,0x02,0x03,0x01,0x00,0x01,0xA3,0x63,0x30,0x61,0x30,
106 0x0F,0x06,0x03,0x55,0x1D,0x13,0x01,0x01,0xFF,0x04,0x05,0x30,0x03,0x01,0x01,0xFF,
107 0x30,0x0E,0x06,0x03,0x55,0x1D,0x0F,0x01,0x01,0xFF,0x04,0x04,0x03,0x02,0x01,0x06,
108 0x30,0x1D,0x06,0x03,0x55,0x1D,0x0E,0x04,0x16,0x04,0x14,0xFD,0x78,0x96,0x53,0x80,
109 0xD6,0xF6,0xDC,0xA6,0xC3,0x59,0x06,0x38,0xED,0x79,0x3E,0x8F,0x50,0x1B,0x50,0x30,
110 0x1F,0x06,0x03,0x55,0x1D,0x23,0x04,0x18,0x30,0x16,0x80,0x14,0xFD,0x78,0x96,0x53,
111 0x80,0xD6,0xF6,0xDC,0xA6,0xC3,0x59,0x06,0x38,0xED,0x79,0x3E,0x8F,0x50,0x1B,0x50,
112 0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x0B,0x05,0x00,0x03,
113 0x82,0x01,0x01,0x00,0x71,0x15,0xCA,0x87,0xD0,0x2D,0xB5,0x18,0xD5,0x35,0x7A,0xCD,
114 0xDF,0x62,0x28,0xF0,0x0B,0x63,0x4D,0x4E,0x02,0xBA,0x3D,0xB8,0xB4,0x37,0xEA,0xB0,
115 0x93,0x93,0xAB,0x1C,0xFD,0x9F,0xE8,0x72,0xBF,0xF3,0xDB,0xE6,0xAD,0x16,0xFE,0x71,
116 0x61,0xA8,0x5A,0xD0,0x58,0x0F,0x65,0x7A,0x57,0x7A,0xE0,0x34,0x80,0x8E,0xBB,0x41,
117 0x01,0xE7,0xB0,0x3B,0xF7,0x2B,0x3A,0x6D,0x44,0x2A,0x3A,0x04,0x52,0xFA,0x2B,0x7B,
118 0x3B,0x21,0xDD,0x0C,0x70,0x3D,0xFB,0x45,0xC6,0x79,0x68,0x62,0xE2,0x89,0xB8,0x25,
119 0xEE,0x63,0x76,0x02,0xB2,0x22,0xE9,0x53,0x85,0x68,0x3E,0x75,0xB6,0x0B,0x65,0xE9,
120 0x1C,0xBA,0x84,0x93,0xB0,0x8A,0xEF,0xB5,0x1A,0x12,0xE4,0x8F,0xAE,0xD5,0x5C,0xA1,
121 0x05,0x4A,0x01,0xBC,0x6F,0xF9,0x58,0x5E,0xF7,0x04,0x61,0xEE,0xF5,0xC6,0xA0,0x1B,
122 0x44,0x2E,0x5A,0x3A,0x59,0xA1,0xB3,0xB0,0xF4,0xB6,0xCB,0xE0,0x6C,0x2B,0x59,0x8A,
123 0xFB,0x6A,0xE0,0xA2,0x57,0x09,0x79,0xC1,0xDD,0xFB,0x84,0x86,0xEB,0x66,0x29,0x73,
124 0xAE,0xBF,0x58,0xAE,0x47,0x4D,0x48,0x37,0xD6,0xB1,0x8C,0x5F,0x26,0x5F,0xB5,0x26,
125 0x07,0x0B,0x85,0xB7,0x36,0x37,0x14,0xCF,0x5E,0x55,0xA5,0x3C,0xF3,0x1E,0x79,0x50,
126 0xBB,0x85,0x3B,0xB2,0x94,0x68,0xB0,0x25,0x4F,0x75,0xEC,0xF0,0xF9,0xC0,0x5A,0x2D,
127 0xE5,0xED,0x67,0xCD,0x88,0x55,0xA0,0x42,0xDE,0x78,0xBC,0xFE,0x30,0xB1,0x62,0x2D,
128 0xE1,0xFD,0xEC,0x75,0x03,0xA6,0x1F,0x7C,0xC4,0x3A,0x4A,0x59,0xFE,0x77,0xC3,0x99,
132 static struct RootRecord kProductionEscrowRootRecord
= {sizeof(kProductionEscrowRootGM
), (UInt8
*)kProductionEscrowRootGM
};
133 static struct RootRecord
* kProductionEscrowRoots
[] = {&kProductionEscrowRootRecord
};
134 static const int kNumberOfProductionEscrowRoots
= (int)(sizeof(kProductionEscrowRoots
)/sizeof(kProductionEscrowRoots
[0]));
136 static struct RootRecord kBaseLineEscrowRootRecord
= {sizeof(kProductionEscrowRootGM
), (UInt8
*)kProductionEscrowRootGM
};
137 static struct RootRecord
* kBaseLineEscrowRoots
[] = {&kBaseLineEscrowRootRecord
};
138 static const int kNumberOfBaseLineEscrowRoots
= (int)(sizeof(kBaseLineEscrowRoots
)/sizeof(kBaseLineEscrowRoots
[0]));
142 //######################################################################
143 //%%% end workaround: rdar://14292830
144 ////######################################################################
147 extern CSSM_KEYUSE
ConvertArrayToKeyUsage(CFArrayRef usage
);
149 #define SEC_CONST_DECL(k,v) CFTypeRef k = (CFTypeRef)(CFSTR(v));
151 SEC_CONST_DECL (kSecCertificateProductionEscrowKey
, "ProductionEscrowKey");
152 SEC_CONST_DECL (kSecCertificateEscrowFileName
, "AppleESCertificates");
155 using namespace CssmClient
;
158 SecCertificateGetTypeID(void)
162 return gTypes().Certificate
.typeID
;
164 END_SECAPI1(_kCFRuntimeNotATypeID
)
169 SecCertificateCreateFromData(const CSSM_DATA
*data
, CSSM_CERT_TYPE type
, CSSM_CERT_ENCODING encoding
, SecCertificateRef
*certificate
)
173 SecPointer
<Certificate
> certificatePtr(new Certificate(Required(data
), type
, encoding
));
174 Required(certificate
) = certificatePtr
->handle();
181 SecCertificateCreateWithData(CFAllocatorRef allocator
, CFDataRef data
)
183 SecCertificateRef certificate
= NULL
;
184 OSStatus __secapiresult
;
186 CSSM_DATA cssmCertData
;
187 cssmCertData
.Length
= (data
) ? (CSSM_SIZE
)CFDataGetLength(data
) : 0;
188 cssmCertData
.Data
= (data
) ? (uint8
*)CFDataGetBytePtr(data
) : NULL
;
190 //NOTE: there isn't yet a Certificate constructor which accepts a CFAllocatorRef
191 SecPointer
<Certificate
> certificatePtr(new Certificate(cssmCertData
, CSSM_CERT_X_509v3
, CSSM_CERT_ENCODING_DER
));
192 certificate
= certificatePtr
->handle();
194 __secapiresult
=errSecSuccess
;
196 catch (const MacOSError
&err
) { __secapiresult
=err
.osStatus(); }
197 catch (const CommonError
&err
) { __secapiresult
=SecKeychainErrFromOSStatus(err
.osStatus()); }
198 catch (const std::bad_alloc
&) { __secapiresult
=errSecAllocate
; }
199 catch (...) { __secapiresult
=errSecInternalComponent
; }
204 SecCertificateAddToKeychain(SecCertificateRef certificate
, SecKeychainRef keychain
)
208 Item
item(Certificate::required(certificate
));
209 Keychain::optional(keychain
)->add(item
);
215 SecCertificateGetData(SecCertificateRef certificate
, CSSM_DATA_PTR data
)
219 Required(data
) = Certificate::required(certificate
)->data();
226 SecCertificateCopyData(SecCertificateRef certificate
)
228 CFDataRef data
= NULL
;
229 OSStatus __secapiresult
= errSecSuccess
;
231 CssmData output
= Certificate::required(certificate
)->data();
232 CFIndex length
= (CFIndex
)output
.length();
233 const UInt8
*bytes
= (const UInt8
*)output
.data();
234 if (length
&& bytes
) {
235 data
= CFDataCreate(NULL
, bytes
, length
);
238 catch (const MacOSError
&err
) { __secapiresult
=err
.osStatus(); }
239 catch (const CommonError
&err
) { __secapiresult
=SecKeychainErrFromOSStatus(err
.osStatus()); }
240 catch (const std::bad_alloc
&) { __secapiresult
=errSecAllocate
; }
241 catch (...) { __secapiresult
=errSecInternalComponent
; }
246 SecCertificateGetSHA1Digest(SecCertificateRef certificate
)
248 CFDataRef data
= NULL
;
249 OSStatus __secapiresult
= errSecSuccess
;
251 data
= Certificate::required(certificate
)->sha1Hash();
253 catch (const MacOSError
&err
) { __secapiresult
=err
.osStatus(); }
254 catch (const CommonError
&err
) { __secapiresult
=SecKeychainErrFromOSStatus(err
.osStatus()); }
255 catch (const std::bad_alloc
&) { __secapiresult
=errSecAllocate
; }
256 catch (...) { __secapiresult
=errSecInternalComponent
; }
261 SecCertificateCopyDNSNames(SecCertificateRef certificate
)
263 CFArrayRef names
= NULL
;
264 OSStatus __secapiresult
= errSecSuccess
;
266 names
= Certificate::required(certificate
)->copyDNSNames();
268 catch (const MacOSError
&err
) { __secapiresult
=err
.osStatus(); }
269 catch (const CommonError
&err
) { __secapiresult
=SecKeychainErrFromOSStatus(err
.osStatus()); }
270 catch (const std::bad_alloc
&) { __secapiresult
=errSecAllocate
; }
271 catch (...) { __secapiresult
=errSecInternalComponent
; }
276 SecCertificateGetType(SecCertificateRef certificate
, CSSM_CERT_TYPE
*certificateType
)
280 Required(certificateType
) = Certificate::required(certificate
)->type();
287 SecCertificateGetSubject(SecCertificateRef certificate
, const CSSM_X509_NAME
**subject
)
291 Required(subject
) = Certificate::required(certificate
)->subjectName();
298 SecCertificateGetIssuer(SecCertificateRef certificate
, const CSSM_X509_NAME
**issuer
)
302 Required(issuer
) = Certificate::required(certificate
)->issuerName();
309 SecCertificateGetCLHandle(SecCertificateRef certificate
, CSSM_CL_HANDLE
*clHandle
)
313 Required(clHandle
) = Certificate::required(certificate
)->clHandle();
319 * Private API to infer a display name for a SecCertificateRef which
320 * may or may not be in a keychain.
323 SecCertificateInferLabel(SecCertificateRef certificate
, CFStringRef
*label
)
327 Certificate::required(certificate
)->inferLabel(false,
334 SecCertificateCopyPublicKey(SecCertificateRef certificate
, SecKeyRef
*key
)
338 Required(key
) = Certificate::required(certificate
)->publicKey()->handle();
344 SecCertificateGetAlgorithmID(SecCertificateRef certificate
, const CSSM_X509_ALGORITHM_IDENTIFIER
**algid
)
348 Required(algid
) = Certificate::required(certificate
)->algorithmID();
354 SecCertificateCopyCommonName(SecCertificateRef certificate
, CFStringRef
*commonName
)
358 Required(commonName
) = Certificate::required(certificate
)->commonName();
365 SecCertificateCopySubjectSummary(SecCertificateRef certificate
)
367 CFStringRef summary
= NULL
;
368 OSStatus __secapiresult
;
370 Certificate::required(certificate
)->inferLabel(false, &summary
);
372 __secapiresult
=errSecSuccess
;
374 catch (const MacOSError
&err
) { __secapiresult
=err
.osStatus(); }
375 catch (const CommonError
&err
) { __secapiresult
=SecKeychainErrFromOSStatus(err
.osStatus()); }
376 catch (const std::bad_alloc
&) { __secapiresult
=errSecAllocate
; }
377 catch (...) { __secapiresult
=errSecInternalComponent
; }
382 SecCertificateCopyIssuerSummary(SecCertificateRef certificate
)
384 CFStringRef issuerStr
= NULL
;
385 SecCertificateRefP certP
= NULL
;
386 CFDataRef certData
= SecCertificateCopyData(certificate
);
388 certP
= SecCertificateCreateWithDataP(NULL
, certData
);
392 issuerStr
= SecCertificateCopyIssuerSummaryP(certP
);
399 SecCertificateCopySubjectComponent(SecCertificateRef certificate
, const CSSM_OID
*component
, CFStringRef
*result
)
403 Required(result
) = Certificate::required(certificate
)->distinguishedName(&CSSMOID_X509V1SubjectNameCStruct
, component
);
409 SecCertificateGetCommonName(SecCertificateRef certificate
, CFStringRef
*commonName
)
411 // deprecated SPI signature; replaced by SecCertificateCopyCommonName
412 return SecCertificateCopyCommonName(certificate
, commonName
);
416 SecCertificateGetEmailAddress(SecCertificateRef certificate
, CFStringRef
*emailAddress
)
420 Required(emailAddress
) = Certificate::required(certificate
)->copyFirstEmailAddress();
426 SecCertificateCopyEmailAddresses(SecCertificateRef certificate
, CFArrayRef
*emailAddresses
)
430 Required(emailAddresses
) = Certificate::required(certificate
)->copyEmailAddresses();
436 SecCertificateCopyFieldValues(SecCertificateRef certificate
, const CSSM_OID
*field
, CSSM_DATA_PTR
**fieldValues
)
438 /* Return a zero terminated list of CSSM_DATA_PTR's with the values of the field specified by field. Caller must call releaseFieldValues to free the storage allocated by this call. */
441 Required(fieldValues
) = Certificate::required(certificate
)->copyFieldValues(Required(field
));
447 SecCertificateReleaseFieldValues(SecCertificateRef certificate
, const CSSM_OID
*field
, CSSM_DATA_PTR
*fieldValues
)
451 Certificate::required(certificate
)->releaseFieldValues(Required(field
), fieldValues
);
457 SecCertificateCopyFirstFieldValue(SecCertificateRef certificate
, const CSSM_OID
*field
, CSSM_DATA_PTR
*fieldValue
)
461 Required(fieldValue
) = Certificate::required(certificate
)->copyFirstFieldValue(Required(field
));
467 SecCertificateReleaseFirstFieldValue(SecCertificateRef certificate
, const CSSM_OID
*field
, CSSM_DATA_PTR fieldValue
)
471 Certificate::required(certificate
)->releaseFieldValue(Required(field
), fieldValue
);
477 SecCertificateFindByIssuerAndSN(CFTypeRef keychainOrArray
,const CSSM_DATA
*issuer
,
478 const CSSM_DATA
*serialNumber
, SecCertificateRef
*certificate
)
482 StorageManager::KeychainList keychains
;
483 globals().storageManager
.optionalSearchList(keychainOrArray
, keychains
);
484 Required(certificate
) = Certificate::findByIssuerAndSN(keychains
, CssmData::required(issuer
), CssmData::required(serialNumber
))->handle();
490 SecCertificateFindBySubjectKeyID(CFTypeRef keychainOrArray
, const CSSM_DATA
*subjectKeyID
,
491 SecCertificateRef
*certificate
)
495 StorageManager::KeychainList keychains
;
496 globals().storageManager
.optionalSearchList(keychainOrArray
, keychains
);
497 Required(certificate
) = Certificate::findBySubjectKeyID(keychains
, CssmData::required(subjectKeyID
))->handle();
503 SecCertificateFindByEmail(CFTypeRef keychainOrArray
, const char *emailAddress
, SecCertificateRef
*certificate
)
507 StorageManager::KeychainList keychains
;
508 globals().storageManager
.optionalSearchList(keychainOrArray
, keychains
);
509 Required(certificate
) = Certificate::findByEmail(keychains
, emailAddress
)->handle();
515 SecKeychainSearchCreateForCertificateByIssuerAndSN(CFTypeRef keychainOrArray
, const CSSM_DATA
*issuer
,
516 const CSSM_DATA
*serialNumber
, SecKeychainSearchRef
*searchRef
)
522 StorageManager::KeychainList keychains
;
523 globals().storageManager
.optionalSearchList(keychainOrArray
, keychains
);
524 KCCursor
cursor(Certificate::cursorForIssuerAndSN(keychains
, CssmData::required(issuer
), CssmData::required(serialNumber
)));
525 *searchRef
= cursor
->handle();
531 SecKeychainSearchCreateForCertificateByIssuerAndSN_CF(CFTypeRef keychainOrArray
, CFDataRef issuer
,
532 CFDataRef serialNumber
, SecKeychainSearchRef
*searchRef
)
538 StorageManager::KeychainList keychains
;
539 globals().storageManager
.optionalSearchList(keychainOrArray
, keychains
);
541 Required(serialNumber
);
542 KCCursor
cursor(Certificate::cursorForIssuerAndSN_CF(keychains
, issuer
, serialNumber
));
543 *searchRef
= cursor
->handle();
549 SecKeychainSearchCreateForCertificateBySubjectKeyID(CFTypeRef keychainOrArray
, const CSSM_DATA
*subjectKeyID
,
550 SecKeychainSearchRef
*searchRef
)
556 StorageManager::KeychainList keychains
;
557 globals().storageManager
.optionalSearchList(keychainOrArray
, keychains
);
558 KCCursor
cursor(Certificate::cursorForSubjectKeyID(keychains
, CssmData::required(subjectKeyID
)));
559 *searchRef
= cursor
->handle();
565 SecKeychainSearchCreateForCertificateByEmail(CFTypeRef keychainOrArray
, const char *emailAddress
,
566 SecKeychainSearchRef
*searchRef
)
572 StorageManager::KeychainList keychains
;
573 globals().storageManager
.optionalSearchList(keychainOrArray
, keychains
);
574 KCCursor
cursor(Certificate::cursorForEmail(keychains
, emailAddress
));
575 *searchRef
= cursor
->handle();
580 /* NOT EXPORTED YET; copied from SecurityInterface but could be useful in the future.
582 SecGetAppleCSPHandle()
585 return CSP(gGuidAppleCSP)->handle();
590 SecGetAppleCLHandle()
593 return CL(gGuidAppleX509CL)->handle();
599 SecDigestGetData (CSSM_ALGORITHMS alg
, CSSM_DATA
* digest
, const CSSM_DATA
* data
)
603 if (!digest
|| !digest
->Data
|| !digest
->Length
|| !data
|| !data
->Data
|| !data
->Length
)
606 CSP
csp(gGuidAppleCSP
);
607 Digest
context(csp
, alg
);
608 CssmData
input(data
->Data
, data
->Length
);
609 CssmData
output(digest
->Data
, digest
->Length
);
611 context
.digest(input
, output
);
612 digest
->Length
= output
.length();
618 /* determine whether a cert is self-signed */
619 OSStatus
SecCertificateIsSelfSigned(
620 SecCertificateRef certificate
,
621 Boolean
*isSelfSigned
) /* RETURNED */
625 *isSelfSigned
= Certificate::required(certificate
)->isSelfSigned();
631 SecCertificateCopyPreference(
633 CSSM_KEYUSE keyUsage
,
634 SecCertificateRef
*certificate
)
639 Required(certificate
);
640 StorageManager::KeychainList keychains
;
641 globals().storageManager
.getSearchList(keychains
);
642 KCCursor
cursor(keychains
, kSecGenericPasswordItemClass
, NULL
);
644 char idUTF8
[MAXPATHLEN
];
645 if (!CFStringGetCString(name
, idUTF8
, sizeof(idUTF8
)-1, kCFStringEncodingUTF8
))
646 idUTF8
[0] = (char)'\0';
647 CssmData
service(const_cast<char *>(idUTF8
), strlen(idUTF8
));
648 FourCharCode itemType
= 'cprf';
649 cursor
->add(CSSM_DB_EQUAL
, Schema::attributeInfo(kSecServiceItemAttr
), service
);
650 cursor
->add(CSSM_DB_EQUAL
, Schema::attributeInfo(kSecTypeItemAttr
), itemType
);
652 cursor
->add(CSSM_DB_EQUAL
, Schema::attributeInfo(kSecScriptCodeItemAttr
), (sint32
)keyUsage
);
655 if (!cursor
->next(prefItem
))
656 MacOSError::throwMe(errSecItemNotFound
);
658 // get persistent certificate reference
659 SecKeychainAttribute itemAttrs
[] = { { kSecGenericItemAttr
, 0, NULL
} };
660 SecKeychainAttributeList itemAttrList
= { sizeof(itemAttrs
) / sizeof(itemAttrs
[0]), itemAttrs
};
661 prefItem
->getContent(NULL
, &itemAttrList
, NULL
, NULL
);
663 // find certificate, given persistent reference data
664 CFDataRef pItemRef
= CFDataCreateWithBytesNoCopy(NULL
, (const UInt8
*)itemAttrs
[0].data
, itemAttrs
[0].length
, kCFAllocatorNull
);
665 SecKeychainItemRef certItemRef
= nil
;
666 OSStatus status
= SecKeychainItemCopyFromPersistentReference(pItemRef
, &certItemRef
); //%%% need to make this a method of ItemImpl
667 prefItem
->freeContent(&itemAttrList
, NULL
);
673 *certificate
= (SecCertificateRef
)certItemRef
;
679 SecCertificateCopyPreferred(
683 // This function will look for a matching preference in the following order:
684 // - matches the name and the supplied key use
685 // - matches the name and the special 'ANY' key use
686 // - matches the name with no key usage constraint
688 SecCertificateRef certRef
= NULL
;
689 CSSM_KEYUSE keyUse
= ConvertArrayToKeyUsage(keyUsage
);
690 OSStatus status
= SecCertificateCopyPreference(name
, keyUse
, &certRef
);
691 if (status
!= errSecSuccess
&& keyUse
!= CSSM_KEYUSE_ANY
)
692 status
= SecCertificateCopyPreference(name
, CSSM_KEYUSE_ANY
, &certRef
);
693 if (status
!= errSecSuccess
&& keyUse
!= 0)
694 status
= SecCertificateCopyPreference(name
, 0, &certRef
);
700 SecCertificateFindPreferenceItemWithNameAndKeyUsage(
701 CFTypeRef keychainOrArray
,
704 SecKeychainItemRef
*itemRef
)
708 StorageManager::KeychainList keychains
;
709 globals().storageManager
.optionalSearchList(keychainOrArray
, keychains
);
710 KCCursor
cursor(keychains
, kSecGenericPasswordItemClass
, NULL
);
712 char idUTF8
[MAXPATHLEN
];
713 idUTF8
[0] = (char)'\0';
716 if (!CFStringGetCString(name
, idUTF8
, sizeof(idUTF8
)-1, kCFStringEncodingUTF8
))
717 idUTF8
[0] = (char)'\0';
719 size_t idUTF8Len
= strlen(idUTF8
);
721 MacOSError::throwMe(errSecParam
);
723 CssmData
service(const_cast<char *>(idUTF8
), idUTF8Len
);
724 cursor
->add(CSSM_DB_EQUAL
, Schema::attributeInfo(kSecServiceItemAttr
), service
);
725 cursor
->add(CSSM_DB_EQUAL
, Schema::attributeInfo(kSecTypeItemAttr
), (FourCharCode
)'cprf');
727 cursor
->add(CSSM_DB_EQUAL
, Schema::attributeInfo(kSecScriptCodeItemAttr
), (sint32
)keyUsage
);
730 if (!cursor
->next(item
))
731 MacOSError::throwMe(errSecItemNotFound
);
734 *itemRef
=item
->handle();
740 OSStatus
SecCertificateDeletePreferenceItemWithNameAndKeyUsage(
741 CFTypeRef keychainOrArray
,
745 // when a specific key usage is passed, we'll only match & delete that pref;
746 // when a key usage of 0 is passed, all matching prefs should be deleted.
747 // maxUsages represents the most matches there could theoretically be, so
748 // cut things off at that point if we're still finding items (if they can't
749 // be deleted for some reason, we'd never break out of the loop.)
752 SecKeychainItemRef item
= NULL
;
753 int count
= 0, maxUsages
= 12;
754 while (++count
<= maxUsages
&&
755 (status
= SecCertificateFindPreferenceItemWithNameAndKeyUsage(keychainOrArray
, name
, keyUsage
, &item
)) == errSecSuccess
) {
756 status
= SecKeychainItemDelete(item
);
761 // it's not an error if the item isn't found
762 return (status
== errSecItemNotFound
) ? errSecSuccess
: status
;
765 OSStatus
SecCertificateSetPreference(
766 SecCertificateRef certificate
,
768 CSSM_KEYUSE keyUsage
,
775 // treat NULL certificate as a request to clear the preference
776 // (note: if keyUsage is 0, this clears all key usage prefs for name)
777 return SecCertificateDeletePreferenceItemWithNameAndKeyUsage(NULL
, name
, keyUsage
);
782 // determine the account attribute
784 // This attribute must be synthesized from certificate label + pref item type + key usage,
785 // as only the account and service attributes can make a generic keychain item unique.
786 // For 'iprf' type items (but not 'cprf'), we append a trailing space. This insures that
787 // we can save a certificate preference if an identity preference already exists for the
788 // given service name, and vice-versa.
789 // If the key usage is 0 (i.e. the normal case), we omit the appended key usage string.
791 CFStringRef labelStr
= nil
;
792 Certificate::required(certificate
)->inferLabel(false, &labelStr
);
794 MacOSError::throwMe(errSecDataTooLarge
); // data is "in a format which cannot be displayed"
796 CFIndex accountUTF8Len
= CFStringGetMaximumSizeForEncoding(CFStringGetLength(labelStr
), kCFStringEncodingUTF8
) + 1;
797 const char *templateStr
= "%s [key usage 0x%X]";
798 const int keyUsageMaxStrLen
= 8;
799 accountUTF8Len
+= strlen(templateStr
) + keyUsageMaxStrLen
;
800 char accountUTF8
[accountUTF8Len
];
801 if (!CFStringGetCString(labelStr
, accountUTF8
, accountUTF8Len
-1, kCFStringEncodingUTF8
))
802 accountUTF8
[0] = (char)'\0';
804 snprintf(accountUTF8
, accountUTF8Len
-1, templateStr
, accountUTF8
, keyUsage
);
805 CssmData
account(const_cast<char *>(accountUTF8
), strlen(accountUTF8
));
808 // service attribute (name provided by the caller)
809 CFIndex serviceUTF8Len
= CFStringGetMaximumSizeForEncoding(CFStringGetLength(name
), kCFStringEncodingUTF8
) + 1;;
810 char serviceUTF8
[serviceUTF8Len
];
811 if (!CFStringGetCString(name
, serviceUTF8
, serviceUTF8Len
-1, kCFStringEncodingUTF8
))
812 serviceUTF8
[0] = (char)'\0';
813 CssmData
service(const_cast<char *>(serviceUTF8
), strlen(serviceUTF8
));
815 // look for existing preference item, in case this is an update
816 StorageManager::KeychainList keychains
;
817 globals().storageManager
.getSearchList(keychains
);
818 KCCursor
cursor(keychains
, kSecGenericPasswordItemClass
, NULL
);
819 FourCharCode itemType
= 'cprf';
820 cursor
->add(CSSM_DB_EQUAL
, Schema::attributeInfo(kSecServiceItemAttr
), service
);
821 cursor
->add(CSSM_DB_EQUAL
, Schema::attributeInfo(kSecTypeItemAttr
), itemType
);
823 cursor
->add(CSSM_DB_EQUAL
, Schema::attributeInfo(kSecScriptCodeItemAttr
), (sint32
)keyUsage
);
827 Item
item(kSecGenericPasswordItemClass
, 'aapl', 0, NULL
, false);
828 bool add
= (!cursor
->next(item
));
829 // at this point, we either have a new item to add or an existing item to update
831 // set item attribute values
832 item
->setAttribute(Schema::attributeInfo(kSecServiceItemAttr
), service
);
833 item
->setAttribute(Schema::attributeInfo(kSecTypeItemAttr
), itemType
);
834 item
->setAttribute(Schema::attributeInfo(kSecAccountItemAttr
), account
);
835 item
->setAttribute(Schema::attributeInfo(kSecScriptCodeItemAttr
), (sint32
)keyUsage
);
836 item
->setAttribute(Schema::attributeInfo(kSecLabelItemAttr
), service
);
842 // generic attribute (store persistent certificate reference)
843 CFDataRef pItemRef
= nil
;
844 Certificate::required(certificate
)->copyPersistentReference(pItemRef
);
846 MacOSError::throwMe(errSecInvalidItemRef
);
848 const UInt8
*dataPtr
= CFDataGetBytePtr(pItemRef
);
849 CFIndex dataLen
= CFDataGetLength(pItemRef
);
850 CssmData
pref(const_cast<void *>(reinterpret_cast<const void *>(dataPtr
)), dataLen
);
851 item
->setAttribute(Schema::attributeInfo(kSecGenericItemAttr
), pref
);
855 Keychain keychain
= nil
;
857 keychain
= globals().storageManager
.defaultKeychain();
858 if (!keychain
->exists())
859 MacOSError::throwMe(errSecNoSuchKeychain
); // Might be deleted or not available at this time.
862 keychain
= globals().storageManager
.defaultKeychainUI(item
);
868 catch (const MacOSError
&err
) {
869 if (err
.osStatus() != errSecDuplicateItem
)
870 throw; // if item already exists, fall through to update
878 OSStatus
SecCertificateSetPreferred(
879 SecCertificateRef certificate
,
883 CSSM_KEYUSE keyUse
= ConvertArrayToKeyUsage(keyUsage
);
884 return SecCertificateSetPreference(certificate
, name
, keyUse
, NULL
);
887 CFDictionaryRef
SecCertificateCopyValues(SecCertificateRef certificate
, CFArrayRef keys
, CFErrorRef
*error
)
889 CFDictionaryRef result
= NULL
;
890 OSStatus __secapiresult
;
893 CertificateValues
cv(certificate
);
894 result
= cv
.copyFieldValues(keys
,error
);
897 catch (const MacOSError
&err
) { __secapiresult
=err
.osStatus(); }
898 catch (const CommonError
&err
) { __secapiresult
=SecKeychainErrFromOSStatus(err
.osStatus()); }
899 catch (const std::bad_alloc
&) { __secapiresult
=errSecAllocate
; }
900 catch (...) { __secapiresult
=errSecInternalComponent
; }
904 CFStringRef
SecCertificateCopyLongDescription(CFAllocatorRef alloc
, SecCertificateRef certificate
, CFErrorRef
*error
)
906 return SecCertificateCopyShortDescription(alloc
, certificate
, error
);
909 CFStringRef
SecCertificateCopyShortDescription(CFAllocatorRef alloc
, SecCertificateRef certificate
, CFErrorRef
*error
)
911 CFStringRef result
= NULL
;
912 OSStatus __secapiresult
;
915 __secapiresult
= SecCertificateInferLabel(certificate
, &result
);
917 catch (const MacOSError
&err
) { __secapiresult
=err
.osStatus(); }
918 catch (const CommonError
&err
) { __secapiresult
=SecKeychainErrFromOSStatus(err
.osStatus()); }
919 catch (const std::bad_alloc
&) { __secapiresult
=errSecAllocate
; }
920 catch (...) { __secapiresult
=errSecInternalComponent
; }
921 if (error
!=NULL
&& __secapiresult
!=errSecSuccess
)
923 *error
= CFErrorCreate(kCFAllocatorDefault
, kCFErrorDomainOSStatus
,
924 __secapiresult
? __secapiresult
: CSSM_ERRCODE_INTERNAL_ERROR
, NULL
);
929 CFDataRef
SecCertificateCopySerialNumber(SecCertificateRef certificate
, CFErrorRef
*error
)
931 CFDataRef result
= NULL
;
932 OSStatus __secapiresult
;
935 CertificateValues
cv(certificate
);
936 result
= cv
.copySerialNumber(error
);
939 catch (const MacOSError
&err
) { __secapiresult
=err
.osStatus(); }
940 catch (const CommonError
&err
) { __secapiresult
=SecKeychainErrFromOSStatus(err
.osStatus()); }
941 catch (const std::bad_alloc
&) { __secapiresult
=errSecAllocate
; }
942 catch (...) { __secapiresult
=errSecInternalComponent
; }
946 CFDataRef
SecCertificateCopyNormalizedIssuerContent(SecCertificateRef certificate
, CFErrorRef
*error
)
948 CFDataRef result
= NULL
;
949 OSStatus __secapiresult
;
952 CertificateValues
cv(certificate
);
953 result
= cv
.copyNormalizedIssuerContent(error
);
956 catch (const MacOSError
&err
) { __secapiresult
=err
.osStatus(); }
957 catch (const CommonError
&err
) { __secapiresult
=SecKeychainErrFromOSStatus(err
.osStatus()); }
958 catch (const std::bad_alloc
&) { __secapiresult
=errSecAllocate
; }
959 catch (...) { __secapiresult
=errSecInternalComponent
; }
963 CFDataRef
SecCertificateCopyNormalizedSubjectContent(SecCertificateRef certificate
, CFErrorRef
*error
)
965 CFDataRef result
= NULL
;
966 OSStatus __secapiresult
;
969 CertificateValues
cv(certificate
);
970 result
= cv
.copyNormalizedSubjectContent(error
);
973 catch (const MacOSError
&err
) { __secapiresult
=err
.osStatus(); }
974 catch (const CommonError
&err
) { __secapiresult
=SecKeychainErrFromOSStatus(err
.osStatus()); }
975 catch (const std::bad_alloc
&) { __secapiresult
=errSecAllocate
; }
976 catch (...) { __secapiresult
=errSecInternalComponent
; }
980 CFDataRef
SecCertificateCopyIssuerSequence(SecCertificateRef certificate
)
982 CFDataRef result
= NULL
;
983 OSStatus __secapiresult
;
986 CertificateValues
cv(certificate
);
987 result
= cv
.copyIssuerSequence(NULL
);
990 catch (const MacOSError
&err
) { __secapiresult
=err
.osStatus(); }
991 catch (const CommonError
&err
) { __secapiresult
=SecKeychainErrFromOSStatus(err
.osStatus()); }
992 catch (const std::bad_alloc
&) { __secapiresult
=errSecAllocate
; }
993 catch (...) { __secapiresult
=errSecInternalComponent
; }
997 CFDataRef
SecCertificateCopySubjectSequence(SecCertificateRef certificate
)
999 CFDataRef result
= NULL
;
1000 OSStatus __secapiresult
;
1003 CertificateValues
cv(certificate
);
1004 result
= cv
.copySubjectSequence(NULL
);
1007 catch (const MacOSError
&err
) { __secapiresult
=err
.osStatus(); }
1008 catch (const CommonError
&err
) { __secapiresult
=SecKeychainErrFromOSStatus(err
.osStatus()); }
1009 catch (const std::bad_alloc
&) { __secapiresult
=errSecAllocate
; }
1010 catch (...) { __secapiresult
=errSecInternalComponent
; }
1014 bool SecCertificateIsValid(SecCertificateRef certificate
, CFAbsoluteTime verifyTime
)
1017 OSStatus __secapiresult
;
1020 CFErrorRef error
= NULL
;
1021 CertificateValues
cv(certificate
);
1022 result
= cv
.isValid(verifyTime
, &error
);
1023 if (error
) CFRelease(error
);
1026 catch (const MacOSError
&err
) { __secapiresult
=err
.osStatus(); }
1027 catch (const CommonError
&err
) { __secapiresult
=SecKeychainErrFromOSStatus(err
.osStatus()); }
1028 catch (const std::bad_alloc
&) { __secapiresult
=errSecAllocate
; }
1029 catch (...) { __secapiresult
=errSecInternalComponent
; }
1034 * deprecated function name
1036 bool SecCertificateIsValidX(SecCertificateRef certificate
, CFAbsoluteTime verifyTime
)
1038 return SecCertificateIsValid(certificate
, verifyTime
);
1042 CFAbsoluteTime
SecCertificateNotValidBefore(SecCertificateRef certificate
)
1044 CFAbsoluteTime result
= 0;
1045 OSStatus __secapiresult
;
1048 CFErrorRef error
= NULL
;
1049 CertificateValues
cv(certificate
);
1050 result
= cv
.notValidBefore(&error
);
1051 if (error
) CFRelease(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 CFAbsoluteTime
SecCertificateNotValidAfter(SecCertificateRef certificate
)
1063 CFAbsoluteTime result
= 0;
1064 OSStatus __secapiresult
;
1067 CFErrorRef error
= NULL
;
1068 CertificateValues
cv(certificate
);
1069 result
= cv
.notValidAfter(&error
);
1070 if (error
) CFRelease(error
);
1073 catch (const MacOSError
&err
) { __secapiresult
=err
.osStatus(); }
1074 catch (const CommonError
&err
) { __secapiresult
=SecKeychainErrFromOSStatus(err
.osStatus()); }
1075 catch (const std::bad_alloc
&) { __secapiresult
=errSecAllocate
; }
1076 catch (...) { __secapiresult
=errSecInternalComponent
; }
1081 SecCertificateRef
SecCertificateCreateWithBytes(CFAllocatorRef allocator
,
1082 const UInt8
*bytes
, CFIndex length
)
1084 SecCertificateRef certificate
= NULL
;
1085 OSStatus __secapiresult
;
1087 CSSM_DATA cssmCertData
= { (CSSM_SIZE
)length
, (uint8
*)bytes
};
1089 //NOTE: there isn't yet a Certificate constructor which accepts a CFAllocatorRef
1090 SecPointer
<Certificate
> certificatePtr(new Certificate(cssmCertData
, CSSM_CERT_X_509v3
, CSSM_CERT_ENCODING_DER
));
1091 certificate
= certificatePtr
->handle();
1093 __secapiresult
=errSecSuccess
;
1095 catch (const MacOSError
&err
) { __secapiresult
=err
.osStatus(); }
1096 catch (const CommonError
&err
) { __secapiresult
=SecKeychainErrFromOSStatus(err
.osStatus()); }
1097 catch (const std::bad_alloc
&) { __secapiresult
=errSecAllocate
; }
1098 catch (...) { __secapiresult
=errSecInternalComponent
; }
1103 CFIndex
SecCertificateGetLength(SecCertificateRef certificate
)
1106 OSStatus __secapiresult
;
1108 CssmData output
= Certificate::required(certificate
)->data();
1109 length
= (CFIndex
)output
.length();
1110 __secapiresult
=errSecSuccess
;
1112 catch (const MacOSError
&err
) { __secapiresult
=err
.osStatus(); }
1113 catch (const CommonError
&err
) { __secapiresult
=SecKeychainErrFromOSStatus(err
.osStatus()); }
1114 catch (const std::bad_alloc
&) { __secapiresult
=errSecAllocate
; }
1115 catch (...) { __secapiresult
=errSecInternalComponent
; }
1120 const UInt8
*SecCertificateGetBytePtr(SecCertificateRef certificate
)
1122 const UInt8
*bytes
= NULL
;
1123 OSStatus __secapiresult
;
1125 CssmData output
= Certificate::required(certificate
)->data();
1126 bytes
= (const UInt8
*)output
.data();
1127 __secapiresult
=errSecSuccess
;
1129 catch (const MacOSError
&err
) { __secapiresult
=err
.osStatus(); }
1130 catch (const CommonError
&err
) { __secapiresult
=SecKeychainErrFromOSStatus(err
.osStatus()); }
1131 catch (const std::bad_alloc
&) { __secapiresult
=errSecAllocate
; }
1132 catch (...) { __secapiresult
=errSecInternalComponent
; }
1136 static CFArrayRef
CopyEscrowCertificates(CFErrorRef
*error
)
1138 // Return array of CFDataRef certificates.
1139 CFArrayRef result
= NULL
;
1143 // Get the hard coded set of production roots
1144 // static struct RootRecord* kProductionEscrowRoots[] = {&kOldEscrowRootRecord, &kProductionEscrowRootRecord};
1146 numRoots
= kNumberOfProductionEscrowRoots
;
1147 CFDataRef productionCerts
[numRoots
];
1148 struct RootRecord
* pRootRecord
= NULL
;
1150 for (iCnt
= 0; iCnt
< numRoots
; iCnt
++)
1152 pRootRecord
= kProductionEscrowRoots
[iCnt
];
1153 if (NULL
!= pRootRecord
&& pRootRecord
->_length
> 0 && NULL
!= pRootRecord
->_bytes
)
1155 productionCerts
[iCnt
] = CFDataCreate(kCFAllocatorDefault
, pRootRecord
->_bytes
, pRootRecord
->_length
);
1158 result
= CFArrayCreate(kCFAllocatorDefault
, (const void **)productionCerts
, numRoots
, &kCFTypeArrayCallBacks
);
1159 for (iCnt
= 0; iCnt
< numRoots
; iCnt
++)
1161 if (NULL
!= productionCerts
[iCnt
])
1163 CFRelease(productionCerts
[iCnt
]);
1171 CFArrayRef
SecCertificateCopyEscrowRoots(SecCertificateEscrowRootType escrowRootType
)
1173 CFArrayRef result
= NULL
;
1176 CFDataRef certData
= NULL
;
1178 // The request is for the base line certificates.
1179 // Use the hard coded data to generate the return array
1180 if (kSecCertificateBaselineEscrowRoot
== escrowRootType
)
1182 // Get the hard coded set of roots
1183 numRoots
= kNumberOfBaseLineEscrowRoots
;
1184 SecCertificateRef baseLineCerts
[numRoots
];
1185 struct RootRecord
* pRootRecord
= NULL
;
1187 for (iCnt
= 0; iCnt
< numRoots
; iCnt
++)
1189 pRootRecord
= kBaseLineEscrowRoots
[iCnt
];
1190 if (NULL
!= pRootRecord
&& pRootRecord
->_length
> 0 && NULL
!= pRootRecord
->_bytes
)
1192 certData
= CFDataCreate(kCFAllocatorDefault
, pRootRecord
->_bytes
, pRootRecord
->_length
);
1193 if (NULL
!= certData
)
1195 baseLineCerts
[iCnt
] = SecCertificateCreateWithData(kCFAllocatorDefault
, certData
);
1196 CFRelease(certData
);
1200 result
= CFArrayCreate(kCFAllocatorDefault
, (const void **)baseLineCerts
, numRoots
, &kCFTypeArrayCallBacks
);
1201 for (iCnt
= 0; iCnt
< numRoots
; iCnt
++)
1203 if (NULL
!= baseLineCerts
[iCnt
])
1205 CFRelease(baseLineCerts
[iCnt
]);
1209 // The request is for the current certificates.
1210 else if (kSecCertificateProductionEscrowRoot
== escrowRootType
)
1212 CFErrorRef error
= NULL
;
1213 CFArrayRef cert_datas
= CopyEscrowCertificates(&error
);
1214 if (NULL
!= error
|| NULL
== cert_datas
|| 0 == (numRoots
= (int)CFArrayGetCount(cert_datas
)))
1221 if (NULL
!= cert_datas
)
1223 CFRelease(cert_datas
);
1228 SecCertificateRef assetCerts
[numRoots
];
1229 for (iCnt
= 0; iCnt
< numRoots
; iCnt
++)
1231 certData
= (CFDataRef
)CFArrayGetValueAtIndex(cert_datas
, iCnt
);
1232 if (NULL
!= certData
)
1234 SecCertificateRef aCertRef
= SecCertificateCreateWithData(kCFAllocatorDefault
, certData
);
1235 assetCerts
[iCnt
] = aCertRef
;
1239 assetCerts
[iCnt
] = NULL
;
1245 result
= CFArrayCreate(kCFAllocatorDefault
, (const void **)assetCerts
, numRoots
, &kCFTypeArrayCallBacks
);
1246 for (iCnt
= 0; iCnt
< numRoots
; iCnt
++)
1248 if (NULL
!= assetCerts
[iCnt
])
1250 CFRelease(assetCerts
[iCnt
]);
1254 CFRelease(cert_datas
);