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