]> git.saurik.com Git - apple/security.git/blame - OSX/libsecurity_keychain/lib/SecCertificate.cpp
Security-59306.140.5.tar.gz
[apple/security.git] / OSX / libsecurity_keychain / lib / SecCertificate.cpp
CommitLineData
b1ab9ed8 1/*
fa7225c8 2 * Copyright (c) 2002-2016 Apple Inc. All Rights Reserved.
b1ab9ed8
A
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
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
11 * file.
12 *
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.
20 *
21 * @APPLE_LICENSE_HEADER_END@
22 */
23
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>
35
36#include "SecBridge.h"
37
38// %%% used by SecCertificate{Copy,Set}Preference
39#include <Security/SecKeychainItemPriv.h>
40#include <Security/SecIdentityPriv.h>
b04fe171 41#include <Security/SecItemPriv.h>
b1ab9ed8
A
42#include <security_keychain/KCCursor.h>
43#include <security_cdsa_utilities/Schema.h>
5c19dc3a 44#include <security_cdsa_utils/cuCdsaUtils.h>
b1ab9ed8 45#include <sys/param.h>
5c19dc3a 46#include <syslog.h>
b1ab9ed8 47#include "CertificateValues.h"
427c49bc 48
5c19dc3a 49OSStatus SecCertificateGetCLHandle_legacy(SecCertificateRef certificate, CSSM_CL_HANDLE *clHandle);
b1ab9ed8
A
50extern CSSM_KEYUSE ConvertArrayToKeyUsage(CFArrayRef usage);
51
427c49bc 52
427c49bc 53
b1ab9ed8
A
54
55using namespace CssmClient;
56
6b200bc3 57CFTypeID static SecCertificateGetTypeID_osx(void)
b1ab9ed8
A
58{
59 BEGIN_SECAPI
60
61 return gTypes().Certificate.typeID;
62
63 END_SECAPI1(_kCFRuntimeNotATypeID)
64}
fa7225c8
A
65
66Boolean
67SecCertificateIsItemImplInstance(SecCertificateRef certificate)
68{
69 if (certificate == NULL) {
70 return false;
71 }
6b200bc3 72
fa7225c8
A
73 CFTypeID typeID = CFGetTypeID(certificate);
74
75#if 0 /* debug code to verify type IDs */
76 syslog(LOG_ERR, "SecCertificate typeID=%d [STU=%d, OSX=%d, SKI=%d]",
77 (int)typeID,
78 (int)SecCertificateGetTypeID(),
79 (int)SecCertificateGetTypeID_osx(),
80 (int)SecKeychainItemGetTypeID());
5c19dc3a 81#endif
fa7225c8
A
82 if (typeID == _kCFRuntimeNotATypeID) {
83 return false;
84 }
85
86 return (typeID == SecCertificateGetTypeID_osx() ||
87 typeID == SecKeychainItemGetTypeID()) ? true : false;
fa7225c8 88}
b1ab9ed8 89
5c19dc3a
A
90/* convert a new-world SecCertificateRef to an old-world ItemImpl instance */
91SecCertificateRef
92SecCertificateCreateItemImplInstance(SecCertificateRef certificate)
93{
5c19dc3a
A
94 if (!certificate) {
95 return NULL;
96 }
97 SecCertificateRef implCertRef = (SecCertificateRef) SecCertificateCopyKeychainItem(certificate);
98 if (implCertRef) {
99 return implCertRef;
100 }
101 CFDataRef data = SecCertificateCopyData(certificate);
102 if (!data) {
103 return NULL;
104 }
105 try {
106 CSSM_DATA cssmCertData;
107 cssmCertData.Length = (data) ? (CSSM_SIZE)CFDataGetLength(data) : 0;
108 cssmCertData.Data = (data) ? (uint8 *)CFDataGetBytePtr(data) : NULL;
b1ab9ed8 109
5c19dc3a
A
110 SecPointer<Certificate> certificatePtr(new Certificate(cssmCertData, CSSM_CERT_X_509v3, CSSM_CERT_ENCODING_DER));
111 implCertRef = certificatePtr->handle();
112 }
113 catch (...) {}
114 CFRelease(data);
115 return implCertRef;
5c19dc3a
A
116}
117
118/* convert an old-world ItemImpl instance to a new-world SecCertificateRef */
119SecCertificateRef
120SecCertificateCreateFromItemImplInstance(SecCertificateRef certificate)
121{
5c19dc3a
A
122 if (!certificate) {
123 return NULL;
124 }
125 SecCertificateRef result = NULL;
126 CFDataRef data = NULL;
127 try {
128 CssmData certData = Certificate::required(certificate)->data();
129 if (certData.Data && certData.Length) {
130 data = CFDataCreate(NULL, certData.Data, certData.Length);
131 }
132 if (!data) {
133 if (certData.Data && !certData.Length) {
134 /* zero-length certs can exist, so don't bother logging this */
135 }
136 else {
137 syslog(LOG_ERR, "WARNING: SecKeychainSearchCopyNext failed to retrieve certificate data (length=%ld, data=0x%lX)",
138 (long)certData.Length, (uintptr_t)certData.Data);
139 }
140 return NULL;
141 }
142 }
143 catch (...) {}
144
145 result = SecCertificateCreateWithKeychainItem(NULL, data, certificate);
146 if (data)
147 CFRelease(data);
148 return result;
5c19dc3a
A
149}
150
fa7225c8 151
5c19dc3a 152/* OS X only: DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER */
b1ab9ed8
A
153OSStatus
154SecCertificateCreateFromData(const CSSM_DATA *data, CSSM_CERT_TYPE type, CSSM_CERT_ENCODING encoding, SecCertificateRef *certificate)
155{
5c19dc3a
A
156 /* bridge to support old functionality */
157 if (!data || !data->Data || !data->Length || !certificate) {
158 return errSecParam;
159 }
160 SecCertificateRef certRef = NULL;
fa7225c8
A
161
162 // <rdar://problem/24403998> REG: Adobe {Photoshop, InDesign} CC(2015) crashes on launch
163 // If you take the length that SecKeychainItemCopyContent gives you (a Uint32) and assign it incorrectly
164 // to a CSSM_DATA Length field (a CSSM_SIZE, i.e., a size_t), the upper 32 bits aren't set. If those bits
165 // are non-zero, the length is incredibly wrong.
166 //
167 // Assume that there will not exist a certificate > 4GiB, and fake this length field.
168 CSSM_SIZE length = data->Length & 0xfffffffful;
169
170 CFDataRef dataRef = CFDataCreate(NULL, data->Data, length);
5c19dc3a
A
171 if (dataRef) {
172 certRef = SecCertificateCreateWithData(NULL, dataRef);
173 CFRelease(dataRef);
174 }
175 *certificate = certRef;
176 return (certRef) ? errSecSuccess : errSecUnknownFormat;
b1ab9ed8
A
177}
178
5c19dc3a 179/* OS X only: __OSX_AVAILABLE_STARTING(__MAC_10_3, __IPHONE_NA) */
b1ab9ed8
A
180OSStatus
181SecCertificateAddToKeychain(SecCertificateRef certificate, SecKeychainRef keychain)
182{
fa7225c8 183 // This macro creates an ItemImpl certificate if it does not exist
5c19dc3a 184 BEGIN_SECCERTAPI
b1ab9ed8 185
5c19dc3a 186 Item item(Certificate::required(__itemImplRef));
b1ab9ed8
A
187 Keychain::optional(keychain)->add(item);
188
5c19dc3a 189 END_SECCERTAPI
b1ab9ed8
A
190}
191
5c19dc3a 192/* OS X only: DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER */
b1ab9ed8
A
193OSStatus
194SecCertificateGetData(SecCertificateRef certificate, CSSM_DATA_PTR data)
195{
5c19dc3a 196 BEGIN_SECCERTAPI
b1ab9ed8 197
fa7225c8
A
198 if (!certificate || !data) {
199 __secapiresult=errSecParam;
200 }
201 else if (SecCertificateIsItemImplInstance(certificate)) {
202 Required(data) = Certificate::required(certificate)->data();
203 }
204 else {
205 data->Length = (CSSM_SIZE)SecCertificateGetLength(certificate);
206 data->Data = (uint8*)SecCertificateGetBytePtr(certificate);
207 }
b1ab9ed8 208
5c19dc3a 209 END_SECCERTAPI
e3d460c9 210}
427c49bc 211
5c19dc3a 212/* OS X only: DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER */
b1ab9ed8
A
213OSStatus
214SecCertificateGetType(SecCertificateRef certificate, CSSM_CERT_TYPE *certificateType)
215{
fa7225c8 216 // This macro creates an ItemImpl certificate if it does not exist
5c19dc3a 217 BEGIN_SECCERTAPI
b1ab9ed8 218
5c19dc3a 219 Required(certificateType) = Certificate::required(__itemImplRef)->type();
b1ab9ed8 220
5c19dc3a 221 END_SECCERTAPI
b1ab9ed8
A
222}
223
5c19dc3a 224/* OS X only: DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER */
b1ab9ed8
A
225OSStatus
226SecCertificateGetSubject(SecCertificateRef certificate, const CSSM_X509_NAME **subject)
227{
fa7225c8 228 // This macro creates an ItemImpl certificate if it does not exist
5c19dc3a 229 BEGIN_SECCERTAPI
b1ab9ed8 230
5c19dc3a 231 Required(subject) = Certificate::required(__itemImplRef)->subjectName();
b1ab9ed8 232
5c19dc3a 233 END_SECCERTAPI
b1ab9ed8
A
234}
235
5c19dc3a 236/* OS X only: DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER */
b1ab9ed8
A
237OSStatus
238SecCertificateGetIssuer(SecCertificateRef certificate, const CSSM_X509_NAME **issuer)
239{
fa7225c8 240 // This macro creates an ItemImpl certificate if it does not exist
5c19dc3a
A
241 BEGIN_SECCERTAPI
242
243 Required(issuer) = Certificate::required(__itemImplRef)->issuerName();
244
245 END_SECCERTAPI
246}
247
248/* OS X only: DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER */
249OSStatus
250SecCertificateGetCLHandle(SecCertificateRef certificate, CSSM_CL_HANDLE *clHandle)
251{
fa7225c8 252 // This macro creates an ItemImpl certificate if it does not exist
5c19dc3a
A
253 BEGIN_SECCERTAPI
254
255 Required(clHandle) = Certificate::required(__itemImplRef)->clHandle();
256
257 END_SECCERTAPI
5c19dc3a 258}
b1ab9ed8 259
5c19dc3a
A
260/* private function; assumes input is old-style ItemImpl certificate reference,
261 and does not release that certificate reference!
262 */
b1ab9ed8 263OSStatus
5c19dc3a 264SecCertificateGetCLHandle_legacy(SecCertificateRef certificate, CSSM_CL_HANDLE *clHandle)
b1ab9ed8
A
265{
266 BEGIN_SECAPI
267
5c19dc3a 268 Required(clHandle) = Certificate::required(certificate)->clHandle();
b1ab9ed8
A
269
270 END_SECAPI
271}
272
273/*
274 * Private API to infer a display name for a SecCertificateRef which
275 * may or may not be in a keychain.
5c19dc3a
A
276 *
277 * OS X only
b1ab9ed8
A
278 */
279OSStatus
280SecCertificateInferLabel(SecCertificateRef certificate, CFStringRef *label)
281{
fa7225c8 282 // This macro creates an ItemImpl certificate if it does not exist
5c19dc3a 283 BEGIN_SECCERTAPI
b1ab9ed8 284
5c19dc3a 285 Certificate::required(__itemImplRef)->inferLabel(false, &Required(label));
b1ab9ed8 286
5c19dc3a 287 END_SECCERTAPI
b1ab9ed8
A
288}
289
5c19dc3a 290/* OS X only (note: iOS version has different arguments and return value) */
b1ab9ed8
A
291OSStatus
292SecCertificateCopyPublicKey(SecCertificateRef certificate, SecKeyRef *key)
293{
fa7225c8 294 // This macro creates an ItemImpl certificate if it does not exist
5c19dc3a 295 BEGIN_SECCERTAPI
b1ab9ed8 296
5c19dc3a 297 Required(key) = Certificate::required(__itemImplRef)->publicKey()->handle();
b1ab9ed8 298
5c19dc3a 299 END_SECCERTAPI
b1ab9ed8
A
300}
301
5c19dc3a 302/* OS X only: DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER */
b1ab9ed8
A
303OSStatus
304SecCertificateGetAlgorithmID(SecCertificateRef certificate, const CSSM_X509_ALGORITHM_IDENTIFIER **algid)
305{
fa7225c8 306 // This macro creates an ItemImpl certificate if it does not exist
5c19dc3a 307 BEGIN_SECCERTAPI
b1ab9ed8 308
5c19dc3a 309 Required(algid) = Certificate::required(__itemImplRef)->algorithmID();
b1ab9ed8 310
5c19dc3a 311 END_SECCERTAPI
b1ab9ed8
A
312}
313
5c19dc3a 314/* OS X only */
b1ab9ed8
A
315OSStatus
316SecCertificateCopySubjectComponent(SecCertificateRef certificate, const CSSM_OID *component, CFStringRef *result)
317{
fa7225c8 318 // This macro creates an ItemImpl certificate if it does not exist
5c19dc3a 319 BEGIN_SECCERTAPI
b1ab9ed8 320
5c19dc3a 321 Required(result) = Certificate::required(__itemImplRef)->distinguishedName(&CSSMOID_X509V1SubjectNameCStruct, component);
b1ab9ed8 322
5c19dc3a 323 END_SECCERTAPI
b1ab9ed8
A
324}
325
5c19dc3a 326/* OS X only; deprecated SPI */
b1ab9ed8
A
327OSStatus
328SecCertificateGetCommonName(SecCertificateRef certificate, CFStringRef *commonName)
329{
330 // deprecated SPI signature; replaced by SecCertificateCopyCommonName
331 return SecCertificateCopyCommonName(certificate, commonName);
332}
333
5c19dc3a 334/* OS X only; deprecated SPI */
b1ab9ed8
A
335OSStatus
336SecCertificateGetEmailAddress(SecCertificateRef certificate, CFStringRef *emailAddress)
337{
fa7225c8 338 // This macro creates an ItemImpl certificate if it does not exist
5c19dc3a 339 BEGIN_SECCERTAPI
b1ab9ed8 340
5c19dc3a 341 Required(emailAddress) = Certificate::required(__itemImplRef)->copyFirstEmailAddress();
b1ab9ed8 342
5c19dc3a 343 END_SECCERTAPI
b1ab9ed8
A
344}
345
5c19dc3a
A
346/* Return a zero terminated list of CSSM_DATA_PTR's with the values of the field specified by field.
347 * Caller must call releaseFieldValues to free the storage allocated by this call.
348 *
349 * OS X only
350 */
b1ab9ed8
A
351OSStatus
352SecCertificateCopyFieldValues(SecCertificateRef certificate, const CSSM_OID *field, CSSM_DATA_PTR **fieldValues)
353{
fa7225c8 354 // This macro creates an ItemImpl certificate if it does not exist
5c19dc3a 355 BEGIN_SECCERTAPI
b1ab9ed8 356
5c19dc3a 357 Required(fieldValues) = Certificate::required(__itemImplRef)->copyFieldValues(Required(field));
b1ab9ed8 358
5c19dc3a 359 END_SECCERTAPI
b1ab9ed8
A
360}
361
5c19dc3a 362/* OS X only */
b1ab9ed8
A
363OSStatus
364SecCertificateReleaseFieldValues(SecCertificateRef certificate, const CSSM_OID *field, CSSM_DATA_PTR *fieldValues)
365{
fa7225c8 366 // This macro creates an ItemImpl certificate if it does not exist
5c19dc3a 367 BEGIN_SECCERTAPI
b1ab9ed8 368
5c19dc3a 369 Certificate::required(__itemImplRef)->releaseFieldValues(Required(field), fieldValues);
b1ab9ed8 370
5c19dc3a 371 END_SECCERTAPI
b1ab9ed8
A
372}
373
5c19dc3a 374/* OS X only */
b1ab9ed8
A
375OSStatus
376SecCertificateCopyFirstFieldValue(SecCertificateRef certificate, const CSSM_OID *field, CSSM_DATA_PTR *fieldValue)
377{
fa7225c8 378 // This macro creates an ItemImpl certificate if it does not exist
5c19dc3a 379 BEGIN_SECCERTAPI
b1ab9ed8 380
5c19dc3a 381 Required(fieldValue) = Certificate::required(__itemImplRef)->copyFirstFieldValue(Required(field));
b1ab9ed8 382
5c19dc3a 383 END_SECCERTAPI
b1ab9ed8
A
384}
385
5c19dc3a 386/* OS X only */
b1ab9ed8
A
387OSStatus
388SecCertificateReleaseFirstFieldValue(SecCertificateRef certificate, const CSSM_OID *field, CSSM_DATA_PTR fieldValue)
389{
fa7225c8 390 // This macro creates an ItemImpl certificate if it does not exist
5c19dc3a 391 BEGIN_SECCERTAPI
b1ab9ed8 392
5c19dc3a 393 Certificate::required(__itemImplRef)->releaseFieldValue(Required(field), fieldValue);
b1ab9ed8 394
5c19dc3a 395 END_SECCERTAPI
b1ab9ed8
A
396}
397
5c19dc3a 398/* OS X only */
b1ab9ed8
A
399OSStatus
400SecCertificateFindByIssuerAndSN(CFTypeRef keychainOrArray,const CSSM_DATA *issuer,
401 const CSSM_DATA *serialNumber, SecCertificateRef *certificate)
402{
b04fe171
A
403 if (issuer && serialNumber) {
404 CFRef<CFMutableDictionaryRef> query = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
405 CFDictionarySetValue(query, kSecClass, kSecClassCertificate);
406 CFDictionarySetValue(query, kSecReturnRef, kCFBooleanTrue);
b54c578e 407 CFDictionarySetValue(query, kSecUseDataProtectionKeychain, kCFBooleanTrue);
b04fe171
A
408
409 CFRef<CFDataRef> issuerData = CFDataCreateWithBytesNoCopy(kCFAllocatorDefault, (const UInt8 *)issuer->Data, issuer->Length, kCFAllocatorNull);
410 CFDictionarySetValue(query, kSecAttrIssuer, issuerData);
411
412 CFRef<CFDataRef> serialNumberData = CFDataCreateWithBytesNoCopy(kCFAllocatorDefault, (const UInt8 *)serialNumber->Data, serialNumber->Length, kCFAllocatorNull);
413 CFDictionarySetValue(query, kSecAttrSerialNumber, serialNumberData);
414
415 OSStatus status = SecItemCopyMatching(query, (CFTypeRef*)certificate);
416 if (status == errSecSuccess) {
417 return status;
418 }
419 }
420
b1ab9ed8
A
421 BEGIN_SECAPI
422
423 StorageManager::KeychainList keychains;
424 globals().storageManager.optionalSearchList(keychainOrArray, keychains);
425 Required(certificate) = Certificate::findByIssuerAndSN(keychains, CssmData::required(issuer), CssmData::required(serialNumber))->handle();
426
5c19dc3a
A
427 // convert ItemImpl-based SecCertificateRef to new-world version before returning
428 CssmData certData = Certificate::required(*certificate)->data();
429 CFRef<CFDataRef> cfData(CFDataCreate(NULL, certData.Data, certData.Length));
430 SecCertificateRef tmpRef = *certificate;
431 *certificate = SecCertificateCreateWithData(NULL, cfData);
432 CFRelease(tmpRef);
5c19dc3a 433
b1ab9ed8
A
434 END_SECAPI
435}
436
5c19dc3a 437/* OS X only */
b1ab9ed8
A
438OSStatus
439SecCertificateFindBySubjectKeyID(CFTypeRef keychainOrArray, const CSSM_DATA *subjectKeyID,
440 SecCertificateRef *certificate)
441{
b04fe171
A
442 if (subjectKeyID) {
443 CFRef<CFMutableDictionaryRef> query = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
444 CFDictionarySetValue(query, kSecClass, kSecClassCertificate);
445 CFDictionarySetValue(query, kSecReturnRef, kCFBooleanTrue);
b54c578e 446 CFDictionarySetValue(query, kSecUseDataProtectionKeychain, kCFBooleanTrue);
b04fe171
A
447
448 CFRef<CFDataRef> subjectKeyIDData = CFDataCreateWithBytesNoCopy(kCFAllocatorDefault, (const UInt8 *)subjectKeyID->Data, subjectKeyID->Length, kCFAllocatorNull);
449 CFDictionarySetValue(query, kSecAttrSubjectKeyID, subjectKeyIDData);
450
451 OSStatus status = SecItemCopyMatching(query, (CFTypeRef*)certificate);
452 if (status == errSecSuccess) {
453 return status;
454 }
455 }
456
457 BEGIN_SECAPI
b1ab9ed8
A
458
459 StorageManager::KeychainList keychains;
460 globals().storageManager.optionalSearchList(keychainOrArray, keychains);
461 Required(certificate) = Certificate::findBySubjectKeyID(keychains, CssmData::required(subjectKeyID))->handle();
462
5c19dc3a
A
463 // convert ItemImpl-based SecCertificateRef to new-world version before returning
464 CssmData certData = Certificate::required(*certificate)->data();
465 CFRef<CFDataRef> cfData(CFDataCreate(NULL, certData.Data, certData.Length));
466 SecCertificateRef tmpRef = *certificate;
467 *certificate = SecCertificateCreateWithData(NULL, cfData);
468 CFRelease(tmpRef);
5c19dc3a 469
b1ab9ed8
A
470 END_SECAPI
471}
472
5c19dc3a 473/* OS X only */
b1ab9ed8
A
474OSStatus
475SecCertificateFindByEmail(CFTypeRef keychainOrArray, const char *emailAddress, SecCertificateRef *certificate)
476{
b04fe171
A
477 if (emailAddress) {
478 CFRef<CFMutableDictionaryRef> query = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
479 CFDictionarySetValue(query, kSecClass, kSecClassCertificate);
480 CFDictionarySetValue(query, kSecReturnRef, kCFBooleanTrue);
b54c578e 481 CFDictionarySetValue(query, kSecUseDataProtectionKeychain, kCFBooleanTrue);
b04fe171
A
482
483 CFRef<CFStringRef> emailAddressString = CFStringCreateWithCString(kCFAllocatorDefault, emailAddress, kCFStringEncodingUTF8);
484 CFTypeRef keys[] = { kSecPolicyName };
485 CFTypeRef values[] = { emailAddressString };
486 CFRef<CFDictionaryRef> properties = CFDictionaryCreate(kCFAllocatorDefault, keys, values, 1, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
487 CFRef<SecPolicyRef> policy = SecPolicyCreateWithProperties(kSecPolicyAppleSMIME, properties);
488 CFDictionarySetValue(query, kSecMatchPolicy, policy);
489
490 OSStatus status = SecItemCopyMatching(query, (CFTypeRef*)certificate);
491 if (status == errSecSuccess) {
492 return status;
493 }
494 }
495
496 BEGIN_SECAPI
b1ab9ed8
A
497
498 StorageManager::KeychainList keychains;
499 globals().storageManager.optionalSearchList(keychainOrArray, keychains);
500 Required(certificate) = Certificate::findByEmail(keychains, emailAddress)->handle();
501
5c19dc3a
A
502 // convert ItemImpl-based SecCertificateRef to new-world version before returning
503 CssmData certData = Certificate::required(*certificate)->data();
504 CFRef<CFDataRef> cfData(CFDataCreate(NULL, certData.Data, certData.Length));
505 SecCertificateRef tmpRef = *certificate;
506 *certificate = SecCertificateCreateWithData(NULL, cfData);
507 CFRelease(tmpRef);
5c19dc3a 508
b1ab9ed8
A
509 END_SECAPI
510}
511
5c19dc3a 512/* OS X only */
b1ab9ed8
A
513OSStatus
514SecKeychainSearchCreateForCertificateByIssuerAndSN(CFTypeRef keychainOrArray, const CSSM_DATA *issuer,
515 const CSSM_DATA *serialNumber, SecKeychainSearchRef *searchRef)
516{
517 BEGIN_SECAPI
518
519 Required(searchRef);
520
521 StorageManager::KeychainList keychains;
522 globals().storageManager.optionalSearchList(keychainOrArray, keychains);
523 KCCursor cursor(Certificate::cursorForIssuerAndSN(keychains, CssmData::required(issuer), CssmData::required(serialNumber)));
524 *searchRef = cursor->handle();
525
526 END_SECAPI
527}
528
5c19dc3a 529/* OS X only */
b1ab9ed8
A
530OSStatus
531SecKeychainSearchCreateForCertificateByIssuerAndSN_CF(CFTypeRef keychainOrArray, CFDataRef issuer,
532 CFDataRef serialNumber, SecKeychainSearchRef *searchRef)
533{
534 BEGIN_SECAPI
535
536 Required(searchRef);
537
538 StorageManager::KeychainList keychains;
539 globals().storageManager.optionalSearchList(keychainOrArray, keychains);
540 Required(issuer);
541 Required(serialNumber);
542 KCCursor cursor(Certificate::cursorForIssuerAndSN_CF(keychains, issuer, serialNumber));
543 *searchRef = cursor->handle();
544
545 END_SECAPI
546}
547
5c19dc3a 548/* OS X only */
b1ab9ed8
A
549OSStatus
550SecKeychainSearchCreateForCertificateBySubjectKeyID(CFTypeRef keychainOrArray, const CSSM_DATA *subjectKeyID,
551 SecKeychainSearchRef *searchRef)
552{
553 BEGIN_SECAPI
554
555 Required(searchRef);
556
557 StorageManager::KeychainList keychains;
558 globals().storageManager.optionalSearchList(keychainOrArray, keychains);
559 KCCursor cursor(Certificate::cursorForSubjectKeyID(keychains, CssmData::required(subjectKeyID)));
560 *searchRef = cursor->handle();
561
562 END_SECAPI
563}
564
5c19dc3a 565/* OS X only */
b1ab9ed8
A
566OSStatus
567SecKeychainSearchCreateForCertificateByEmail(CFTypeRef keychainOrArray, const char *emailAddress,
568 SecKeychainSearchRef *searchRef)
569{
570 BEGIN_SECAPI
571
572 Required(searchRef);
573
574 StorageManager::KeychainList keychains;
575 globals().storageManager.optionalSearchList(keychainOrArray, keychains);
576 KCCursor cursor(Certificate::cursorForEmail(keychains, emailAddress));
577 *searchRef = cursor->handle();
578
579 END_SECAPI
580}
581
5c19dc3a 582/* OS X only */
b1ab9ed8
A
583CSSM_RETURN
584SecDigestGetData (CSSM_ALGORITHMS alg, CSSM_DATA* digest, const CSSM_DATA* data)
585{
586 BEGIN_SECAPI
587 // sanity checking
588 if (!digest || !digest->Data || !digest->Length || !data || !data->Data || !data->Length)
427c49bc 589 return errSecParam;
b1ab9ed8
A
590
591 CSP csp(gGuidAppleCSP);
592 Digest context(csp, alg);
593 CssmData input(data->Data, data->Length);
594 CssmData output(digest->Data, digest->Length);
595
596 context.digest(input, output);
597 digest->Length = output.length();
598
599 return CSSM_OK;
600 END_SECAPI1(1);
601}
602
5c19dc3a 603/* OS X only: DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER */
b1ab9ed8
A
604OSStatus
605SecCertificateCopyPreference(
606 CFStringRef name,
607 CSSM_KEYUSE keyUsage,
608 SecCertificateRef *certificate)
609{
610 BEGIN_SECAPI
611
612 Required(name);
613 Required(certificate);
614 StorageManager::KeychainList keychains;
615 globals().storageManager.getSearchList(keychains);
616 KCCursor cursor(keychains, kSecGenericPasswordItemClass, NULL);
617
618 char idUTF8[MAXPATHLEN];
619 if (!CFStringGetCString(name, idUTF8, sizeof(idUTF8)-1, kCFStringEncodingUTF8))
620 idUTF8[0] = (char)'\0';
621 CssmData service(const_cast<char *>(idUTF8), strlen(idUTF8));
622 FourCharCode itemType = 'cprf';
623 cursor->add(CSSM_DB_EQUAL, Schema::attributeInfo(kSecServiceItemAttr), service);
624 cursor->add(CSSM_DB_EQUAL, Schema::attributeInfo(kSecTypeItemAttr), itemType);
625 if (keyUsage)
626 cursor->add(CSSM_DB_EQUAL, Schema::attributeInfo(kSecScriptCodeItemAttr), (sint32)keyUsage);
627
628 Item prefItem;
629 if (!cursor->next(prefItem))
630 MacOSError::throwMe(errSecItemNotFound);
631
632 // get persistent certificate reference
633 SecKeychainAttribute itemAttrs[] = { { kSecGenericItemAttr, 0, NULL } };
634 SecKeychainAttributeList itemAttrList = { sizeof(itemAttrs) / sizeof(itemAttrs[0]), itemAttrs };
635 prefItem->getContent(NULL, &itemAttrList, NULL, NULL);
636
637 // find certificate, given persistent reference data
638 CFDataRef pItemRef = CFDataCreateWithBytesNoCopy(NULL, (const UInt8 *)itemAttrs[0].data, itemAttrs[0].length, kCFAllocatorNull);
639 SecKeychainItemRef certItemRef = nil;
640 OSStatus status = SecKeychainItemCopyFromPersistentReference(pItemRef, &certItemRef); //%%% need to make this a method of ItemImpl
641 prefItem->freeContent(&itemAttrList, NULL);
642 if (pItemRef)
643 CFRelease(pItemRef);
644 if (status)
645 return status;
646
647 *certificate = (SecCertificateRef)certItemRef;
648
fa7225c8
A
649 if (certItemRef && (CFGetTypeID(certItemRef) == SecIdentityGetTypeID())) {
650 // SecKeychainItemCopyFromPersistentReference handed out an identity reference
651 *certificate = NULL;
652 status = SecIdentityCopyCertificate((SecIdentityRef)certItemRef, certificate);
653 CFRelease(certItemRef);
654 return status;
655 }
5c19dc3a 656
b1ab9ed8
A
657 END_SECAPI
658}
659
5c19dc3a 660/* OS X only */
b1ab9ed8
A
661SecCertificateRef
662SecCertificateCopyPreferred(
663 CFStringRef name,
664 CFArrayRef keyUsage)
665{
666 // This function will look for a matching preference in the following order:
667 // - matches the name and the supplied key use
668 // - matches the name and the special 'ANY' key use
669 // - matches the name with no key usage constraint
670
671 SecCertificateRef certRef = NULL;
672 CSSM_KEYUSE keyUse = ConvertArrayToKeyUsage(keyUsage);
673 OSStatus status = SecCertificateCopyPreference(name, keyUse, &certRef);
427c49bc 674 if (status != errSecSuccess && keyUse != CSSM_KEYUSE_ANY)
b1ab9ed8 675 status = SecCertificateCopyPreference(name, CSSM_KEYUSE_ANY, &certRef);
427c49bc 676 if (status != errSecSuccess && keyUse != 0)
b1ab9ed8
A
677 status = SecCertificateCopyPreference(name, 0, &certRef);
678
679 return certRef;
680}
681
5c19dc3a 682/* OS X only; not exported */
427c49bc 683static OSStatus
b1ab9ed8
A
684SecCertificateFindPreferenceItemWithNameAndKeyUsage(
685 CFTypeRef keychainOrArray,
686 CFStringRef name,
687 int32_t keyUsage,
688 SecKeychainItemRef *itemRef)
689{
690 BEGIN_SECAPI
691
692 StorageManager::KeychainList keychains;
693 globals().storageManager.optionalSearchList(keychainOrArray, keychains);
694 KCCursor cursor(keychains, kSecGenericPasswordItemClass, NULL);
695
696 char idUTF8[MAXPATHLEN];
697 idUTF8[0] = (char)'\0';
698 if (name)
699 {
700 if (!CFStringGetCString(name, idUTF8, sizeof(idUTF8)-1, kCFStringEncodingUTF8))
701 idUTF8[0] = (char)'\0';
702 }
703 size_t idUTF8Len = strlen(idUTF8);
704 if (!idUTF8Len)
427c49bc 705 MacOSError::throwMe(errSecParam);
b1ab9ed8
A
706
707 CssmData service(const_cast<char *>(idUTF8), idUTF8Len);
708 cursor->add(CSSM_DB_EQUAL, Schema::attributeInfo(kSecServiceItemAttr), service);
709 cursor->add(CSSM_DB_EQUAL, Schema::attributeInfo(kSecTypeItemAttr), (FourCharCode)'cprf');
710 if (keyUsage)
711 cursor->add(CSSM_DB_EQUAL, Schema::attributeInfo(kSecScriptCodeItemAttr), (sint32)keyUsage);
712
713 Item item;
714 if (!cursor->next(item))
715 MacOSError::throwMe(errSecItemNotFound);
716
717 if (itemRef)
718 *itemRef=item->handle();
719
720 END_SECAPI
721}
722
5c19dc3a 723/* OS X only; not exported */
427c49bc 724static
b1ab9ed8
A
725OSStatus SecCertificateDeletePreferenceItemWithNameAndKeyUsage(
726 CFTypeRef keychainOrArray,
727 CFStringRef name,
728 int32_t keyUsage)
729{
730 // when a specific key usage is passed, we'll only match & delete that pref;
731 // when a key usage of 0 is passed, all matching prefs should be deleted.
732 // maxUsages represents the most matches there could theoretically be, so
733 // cut things off at that point if we're still finding items (if they can't
734 // be deleted for some reason, we'd never break out of the loop.)
735
6b200bc3 736 OSStatus status = errSecSuccess;
b1ab9ed8
A
737 SecKeychainItemRef item = NULL;
738 int count = 0, maxUsages = 12;
739 while (++count <= maxUsages &&
427c49bc 740 (status = SecCertificateFindPreferenceItemWithNameAndKeyUsage(keychainOrArray, name, keyUsage, &item)) == errSecSuccess) {
b1ab9ed8
A
741 status = SecKeychainItemDelete(item);
742 CFRelease(item);
743 item = NULL;
744 }
745
746 // it's not an error if the item isn't found
427c49bc 747 return (status == errSecItemNotFound) ? errSecSuccess : status;
b1ab9ed8
A
748}
749
5c19dc3a 750/* OS X only: __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_NA) */
b1ab9ed8
A
751OSStatus SecCertificateSetPreference(
752 SecCertificateRef certificate,
753 CFStringRef name,
754 CSSM_KEYUSE keyUsage,
755 CFDateRef date)
756{
757 if (!name) {
427c49bc 758 return errSecParam;
b1ab9ed8
A
759 }
760 if (!certificate) {
761 // treat NULL certificate as a request to clear the preference
762 // (note: if keyUsage is 0, this clears all key usage prefs for name)
763 return SecCertificateDeletePreferenceItemWithNameAndKeyUsage(NULL, name, keyUsage);
764 }
765
fa7225c8 766 // This macro creates an ItemImpl certificate if it does not exist
5c19dc3a 767 BEGIN_SECCERTAPI
b1ab9ed8
A
768
769 // determine the account attribute
770 //
771 // This attribute must be synthesized from certificate label + pref item type + key usage,
772 // as only the account and service attributes can make a generic keychain item unique.
773 // For 'iprf' type items (but not 'cprf'), we append a trailing space. This insures that
774 // we can save a certificate preference if an identity preference already exists for the
775 // given service name, and vice-versa.
776 // If the key usage is 0 (i.e. the normal case), we omit the appended key usage string.
777 //
778 CFStringRef labelStr = nil;
5c19dc3a 779 Certificate::required(__itemImplRef)->inferLabel(false, &labelStr);
b1ab9ed8
A
780 if (!labelStr) {
781 MacOSError::throwMe(errSecDataTooLarge); // data is "in a format which cannot be displayed"
782 }
783 CFIndex accountUTF8Len = CFStringGetMaximumSizeForEncoding(CFStringGetLength(labelStr), kCFStringEncodingUTF8) + 1;
784 const char *templateStr = "%s [key usage 0x%X]";
785 const int keyUsageMaxStrLen = 8;
786 accountUTF8Len += strlen(templateStr) + keyUsageMaxStrLen;
79b9da22
A
787 char *accountUTF8 = (char *)malloc(accountUTF8Len);
788 if (!accountUTF8) {
789 MacOSError::throwMe(errSecMemoryError);
790 }
b1ab9ed8
A
791 if (!CFStringGetCString(labelStr, accountUTF8, accountUTF8Len-1, kCFStringEncodingUTF8))
792 accountUTF8[0] = (char)'\0';
793 if (keyUsage)
794 snprintf(accountUTF8, accountUTF8Len-1, templateStr, accountUTF8, keyUsage);
79b9da22
A
795 CssmDataContainer account(const_cast<char *>(accountUTF8), strlen(accountUTF8));
796 free(accountUTF8);
b1ab9ed8
A
797 CFRelease(labelStr);
798
799 // service attribute (name provided by the caller)
800 CFIndex serviceUTF8Len = CFStringGetMaximumSizeForEncoding(CFStringGetLength(name), kCFStringEncodingUTF8) + 1;;
79b9da22
A
801 char *serviceUTF8 = (char *)malloc(serviceUTF8Len);
802 if (!serviceUTF8) {
803 MacOSError::throwMe(errSecMemoryError);
804 }
b1ab9ed8
A
805 if (!CFStringGetCString(name, serviceUTF8, serviceUTF8Len-1, kCFStringEncodingUTF8))
806 serviceUTF8[0] = (char)'\0';
79b9da22
A
807 CssmDataContainer service(const_cast<char *>(serviceUTF8), strlen(serviceUTF8));
808 free(serviceUTF8);
b1ab9ed8
A
809
810 // look for existing preference item, in case this is an update
811 StorageManager::KeychainList keychains;
812 globals().storageManager.getSearchList(keychains);
813 KCCursor cursor(keychains, kSecGenericPasswordItemClass, NULL);
814 FourCharCode itemType = 'cprf';
815 cursor->add(CSSM_DB_EQUAL, Schema::attributeInfo(kSecServiceItemAttr), service);
816 cursor->add(CSSM_DB_EQUAL, Schema::attributeInfo(kSecTypeItemAttr), itemType);
817 if (keyUsage)
818 cursor->add(CSSM_DB_EQUAL, Schema::attributeInfo(kSecScriptCodeItemAttr), (sint32)keyUsage);
819 if (date)
820 ; // %%%TBI
821
822 Item item(kSecGenericPasswordItemClass, 'aapl', 0, NULL, false);
823 bool add = (!cursor->next(item));
824 // at this point, we either have a new item to add or an existing item to update
825
826 // set item attribute values
827 item->setAttribute(Schema::attributeInfo(kSecServiceItemAttr), service);
828 item->setAttribute(Schema::attributeInfo(kSecTypeItemAttr), itemType);
829 item->setAttribute(Schema::attributeInfo(kSecAccountItemAttr), account);
830 item->setAttribute(Schema::attributeInfo(kSecScriptCodeItemAttr), (sint32)keyUsage);
831 item->setAttribute(Schema::attributeInfo(kSecLabelItemAttr), service);
832
833 // date
834 if (date)
835 ; // %%%TBI
836
837 // generic attribute (store persistent certificate reference)
838 CFDataRef pItemRef = nil;
5c19dc3a 839 Certificate::required(__itemImplRef)->copyPersistentReference(pItemRef);
b1ab9ed8
A
840 if (!pItemRef) {
841 MacOSError::throwMe(errSecInvalidItemRef);
842 }
843 const UInt8 *dataPtr = CFDataGetBytePtr(pItemRef);
844 CFIndex dataLen = CFDataGetLength(pItemRef);
845 CssmData pref(const_cast<void *>(reinterpret_cast<const void *>(dataPtr)), dataLen);
846 item->setAttribute(Schema::attributeInfo(kSecGenericItemAttr), pref);
847 CFRelease(pItemRef);
848
849 if (add) {
850 Keychain keychain = nil;
851 try {
852 keychain = globals().storageManager.defaultKeychain();
853 if (!keychain->exists())
854 MacOSError::throwMe(errSecNoSuchKeychain); // Might be deleted or not available at this time.
855 }
856 catch(...) {
857 keychain = globals().storageManager.defaultKeychainUI(item);
858 }
859
860 try {
861 keychain->add(item);
862 }
863 catch (const MacOSError &err) {
864 if (err.osStatus() != errSecDuplicateItem)
865 throw; // if item already exists, fall through to update
866 }
867 }
868 item->update();
869
5c19dc3a 870 END_SECCERTAPI
b1ab9ed8
A
871}
872
5c19dc3a 873/* OS X only: __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_NA) */
b1ab9ed8
A
874OSStatus SecCertificateSetPreferred(
875 SecCertificateRef certificate,
876 CFStringRef name,
877 CFArrayRef keyUsage)
878{
879 CSSM_KEYUSE keyUse = ConvertArrayToKeyUsage(keyUsage);
880 return SecCertificateSetPreference(certificate, name, keyUse, NULL);
881}
882
5c19dc3a 883/* OS X only: __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_NA) */
b1ab9ed8
A
884CFDictionaryRef SecCertificateCopyValues(SecCertificateRef certificate, CFArrayRef keys, CFErrorRef *error)
885{
886 CFDictionaryRef result = NULL;
427c49bc 887 OSStatus __secapiresult;
fa7225c8 888 SecCertificateRef tmpcert = NULL;
6b200bc3 889
fa7225c8
A
890 // convert input to a new-style certificate reference if necessary,
891 // since the implementation of CertificateValues calls SecCertificate API functions
892 // which now assume a unified certificate reference.
893 if (SecCertificateIsItemImplInstance(certificate)) {
894 tmpcert = SecCertificateCreateFromItemImplInstance(certificate);
895 }
fa7225c8
A
896 if (certificate && !tmpcert) {
897 tmpcert = (SecCertificateRef) CFRetain(certificate);
898 }
b1ab9ed8
A
899 try
900 {
fa7225c8 901 CertificateValues cv(tmpcert);
b1ab9ed8
A
902 result = cv.copyFieldValues(keys,error);
903 __secapiresult=0;
904 }
905 catch (const MacOSError &err) { __secapiresult=err.osStatus(); }
906 catch (const CommonError &err) { __secapiresult=SecKeychainErrFromOSStatus(err.osStatus()); }
427c49bc
A
907 catch (const std::bad_alloc &) { __secapiresult=errSecAllocate; }
908 catch (...) { __secapiresult=errSecInternalComponent; }
fa7225c8 909 if (tmpcert) { CFRelease(tmpcert); }
427c49bc 910 return result;
b1ab9ed8
A
911}
912
5c19dc3a 913/* OS X only: __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_NA) */
b1ab9ed8
A
914CFStringRef SecCertificateCopyLongDescription(CFAllocatorRef alloc, SecCertificateRef certificate, CFErrorRef *error)
915{
916 return SecCertificateCopyShortDescription(alloc, certificate, error);
917}
918
5c19dc3a 919/* OS X only: __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_NA) */
b1ab9ed8
A
920CFStringRef SecCertificateCopyShortDescription(CFAllocatorRef alloc, SecCertificateRef certificate, CFErrorRef *error)
921{
922 CFStringRef result = NULL;
5c19dc3a 923 OSStatus __secapiresult = SecCertificateInferLabel(certificate, &result);
427c49bc 924 if (error!=NULL && __secapiresult!=errSecSuccess)
b1ab9ed8
A
925 {
926 *error = CFErrorCreate(kCFAllocatorDefault, kCFErrorDomainOSStatus,
927 __secapiresult ? __secapiresult : CSSM_ERRCODE_INTERNAL_ERROR, NULL);
928 }
427c49bc 929 return result;
b1ab9ed8
A
930}
931
5c19dc3a 932/* OS X only: __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_NA) */
b1ab9ed8
A
933CFDataRef SecCertificateCopySerialNumber(SecCertificateRef certificate, CFErrorRef *error)
934{
935 CFDataRef result = NULL;
427c49bc 936 OSStatus __secapiresult;
b1ab9ed8
A
937 try
938 {
939 CertificateValues cv(certificate);
940 result = cv.copySerialNumber(error);
941 __secapiresult=0;
942 }
943 catch (const MacOSError &err) { __secapiresult=err.osStatus(); }
944 catch (const CommonError &err) { __secapiresult=SecKeychainErrFromOSStatus(err.osStatus()); }
427c49bc
A
945 catch (const std::bad_alloc &) { __secapiresult=errSecAllocate; }
946 catch (...) { __secapiresult=errSecInternalComponent; }
947 return result;
b1ab9ed8
A
948}
949
6b200bc3 950/* OS X only: __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_7, __MAC_10_12_4, __IPHONE_NA, __IPHONE_NA) */
b1ab9ed8
A
951CFDataRef SecCertificateCopyNormalizedIssuerContent(SecCertificateRef certificate, CFErrorRef *error)
952{
953 CFDataRef result = NULL;
427c49bc 954 OSStatus __secapiresult;
b1ab9ed8
A
955 try
956 {
957 CertificateValues cv(certificate);
427c49bc 958 result = cv.copyNormalizedIssuerContent(error);
b1ab9ed8
A
959 __secapiresult=0;
960 }
961 catch (const MacOSError &err) { __secapiresult=err.osStatus(); }
962 catch (const CommonError &err) { __secapiresult=SecKeychainErrFromOSStatus(err.osStatus()); }
427c49bc
A
963 catch (const std::bad_alloc &) { __secapiresult=errSecAllocate; }
964 catch (...) { __secapiresult=errSecInternalComponent; }
965 return result;
b1ab9ed8
A
966}
967
6b200bc3 968/* OS X only: __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_7, __MAC_10_12_4, __IPHONE_NA, __IPHONE_NA) */
b1ab9ed8
A
969CFDataRef SecCertificateCopyNormalizedSubjectContent(SecCertificateRef certificate, CFErrorRef *error)
970{
971 CFDataRef result = NULL;
427c49bc 972 OSStatus __secapiresult;
b1ab9ed8
A
973 try
974 {
975 CertificateValues cv(certificate);
427c49bc 976 result = cv.copyNormalizedSubjectContent(error);
b1ab9ed8
A
977 __secapiresult=0;
978 }
979 catch (const MacOSError &err) { __secapiresult=err.osStatus(); }
980 catch (const CommonError &err) { __secapiresult=SecKeychainErrFromOSStatus(err.osStatus()); }
427c49bc
A
981 catch (const std::bad_alloc &) { __secapiresult=errSecAllocate; }
982 catch (...) { __secapiresult=errSecInternalComponent; }
983 return result;
b1ab9ed8
A
984}
985
5c19dc3a 986/* OS X only: __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_7, __MAC_10_9, __IPHONE_NA, __IPHONE_NA) */
427c49bc
A
987bool SecCertificateIsValidX(SecCertificateRef certificate, CFAbsoluteTime verifyTime)
988{
5c19dc3a
A
989 /*
990 * deprecated function name
991 */
427c49bc
A
992 return SecCertificateIsValid(certificate, verifyTime);
993}
8a50f688
A
994
995/* OS X only */
996CFDataRef SecCertificateCopyPublicKeySHA1DigestFromCertificateData(CFAllocatorRef allocator,
997 CFDataRef der_certificate)
998{
999 CFDataRef result = NULL;
1000 SecCertificateRef iosCertRef = SecCertificateCreateWithData(allocator, der_certificate);
1001 if (NULL == iosCertRef)
1002 {
1003 return result;
1004 }
1005
1006 result = SecCertificateCopyPublicKeySHA1Digest(iosCertRef);
1007 CFRelease(iosCertRef);
1008 return result;
1009}
1010