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