2 * Copyright (c) 2002-2010 Apple Inc. All Rights Reserved.
4 * @APPLE_LICENSE_HEADER_START@
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. Please obtain a copy of the License at
10 * http://www.opensource.apple.com/apsl/ and read it before using this
13 * The Original Code and all software distributed under the License are
14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
18 * Please see the License for the specific language governing rights and
19 * limitations under the License.
21 * @APPLE_LICENSE_HEADER_END@
24 #include <Security/SecCertificate.h>
25 #include <Security/SecCertificatePriv.h>
26 #include <security_keychain/Certificate.h>
27 #include <security_keychain/Item.h>
28 #include <security_keychain/KCCursor.h>
29 #include <Security/cssmapi.h>
30 #include <Security/cssmapple.h>
31 #include <security_cdsa_client/cspclient.h>
32 #include <security_cdsa_client/clclient.h>
33 #include <security_cdsa_client/tpclient.h>
34 #include <Security/cssmtype.h>
36 #include "SecBridge.h"
38 // %%% used by SecCertificate{Copy,Set}Preference
39 #include <Security/SecKeychainItemPriv.h>
40 #include <Security/SecIdentityPriv.h>
41 #include <security_keychain/KCCursor.h>
42 #include <security_cdsa_utilities/Schema.h>
43 #include <sys/param.h>
44 #include "CertificateValues.h"
45 #include "SecCertificateP.h"
47 extern CSSM_KEYUSE
ConvertArrayToKeyUsage(CFArrayRef usage
);
50 using namespace CssmClient
;
53 SecCertificateGetTypeID(void)
57 return gTypes().Certificate
.typeID
;
59 END_SECAPI1(_kCFRuntimeNotATypeID
)
64 SecCertificateCreateFromData(const CSSM_DATA
*data
, CSSM_CERT_TYPE type
, CSSM_CERT_ENCODING encoding
, SecCertificateRef
*certificate
)
68 SecPointer
<Certificate
> certificatePtr(new Certificate(Required(data
), type
, encoding
));
69 Required(certificate
) = certificatePtr
->handle();
76 SecCertificateCreateWithData(CFAllocatorRef allocator
, CFDataRef data
)
78 SecCertificateRef certificate
= NULL
;
79 OSStatus __secapiresult
;
81 CSSM_DATA cssmCertData
;
82 cssmCertData
.Length
= (data
) ? (CSSM_SIZE
)CFDataGetLength(data
) : 0;
83 cssmCertData
.Data
= (data
) ? (uint8
*)CFDataGetBytePtr(data
) : NULL
;
85 //NOTE: there isn't yet a Certificate constructor which accepts a CFAllocatorRef
86 SecPointer
<Certificate
> certificatePtr(new Certificate(cssmCertData
, CSSM_CERT_X_509v3
, CSSM_CERT_ENCODING_DER
));
87 certificate
= certificatePtr
->handle();
91 catch (const MacOSError
&err
) { __secapiresult
=err
.osStatus(); }
92 catch (const CommonError
&err
) { __secapiresult
=SecKeychainErrFromOSStatus(err
.osStatus()); }
93 catch (const std::bad_alloc
&) { __secapiresult
=memFullErr
; }
94 catch (...) { __secapiresult
=internalComponentErr
; }
99 SecCertificateAddToKeychain(SecCertificateRef certificate
, SecKeychainRef keychain
)
103 Item
item(Certificate::required(certificate
));
104 Keychain::optional(keychain
)->add(item
);
110 SecCertificateGetData(SecCertificateRef certificate
, CSSM_DATA_PTR data
)
114 Required(data
) = Certificate::required(certificate
)->data();
121 SecCertificateCopyData(SecCertificateRef certificate
)
123 CFDataRef data
= NULL
;
124 OSStatus __secapiresult
;
126 CssmData output
= Certificate::required(certificate
)->data();
127 CFIndex length
= (CFIndex
)output
.length();
128 const UInt8
*bytes
= (const UInt8
*)output
.data();
129 if (length
&& bytes
) {
130 data
= CFDataCreate(NULL
, bytes
, length
);
132 __secapiresult
=noErr
;
134 catch (const MacOSError
&err
) { __secapiresult
=err
.osStatus(); }
135 catch (const CommonError
&err
) { __secapiresult
=SecKeychainErrFromOSStatus(err
.osStatus()); }
136 catch (const std::bad_alloc
&) { __secapiresult
=memFullErr
; }
137 catch (...) { __secapiresult
=internalComponentErr
; }
142 SecCertificateGetType(SecCertificateRef certificate
, CSSM_CERT_TYPE
*certificateType
)
146 Required(certificateType
) = Certificate::required(certificate
)->type();
153 SecCertificateGetSubject(SecCertificateRef certificate
, const CSSM_X509_NAME
**subject
)
157 Required(subject
) = Certificate::required(certificate
)->subjectName();
164 SecCertificateGetIssuer(SecCertificateRef certificate
, const CSSM_X509_NAME
**issuer
)
168 Required(issuer
) = Certificate::required(certificate
)->issuerName();
175 SecCertificateGetCLHandle(SecCertificateRef certificate
, CSSM_CL_HANDLE
*clHandle
)
179 Required(clHandle
) = Certificate::required(certificate
)->clHandle();
185 * Private API to infer a display name for a SecCertificateRef which
186 * may or may not be in a keychain.
189 SecCertificateInferLabel(SecCertificateRef certificate
, CFStringRef
*label
)
193 Certificate::required(certificate
)->inferLabel(false,
200 SecCertificateCopyPublicKey(SecCertificateRef certificate
, SecKeyRef
*key
)
204 Required(key
) = Certificate::required(certificate
)->publicKey()->handle();
210 SecCertificateGetAlgorithmID(SecCertificateRef certificate
, const CSSM_X509_ALGORITHM_IDENTIFIER
**algid
)
214 Required(algid
) = Certificate::required(certificate
)->algorithmID();
220 SecCertificateCopyCommonName(SecCertificateRef certificate
, CFStringRef
*commonName
)
224 Required(commonName
) = Certificate::required(certificate
)->commonName();
231 SecCertificateCopySubjectSummary(SecCertificateRef certificate
)
233 CFStringRef summary
= NULL
;
234 OSStatus __secapiresult
;
236 Certificate::required(certificate
)->inferLabel(false, &summary
);
238 __secapiresult
=noErr
;
240 catch (const MacOSError
&err
) { __secapiresult
=err
.osStatus(); }
241 catch (const CommonError
&err
) { __secapiresult
=SecKeychainErrFromOSStatus(err
.osStatus()); }
242 catch (const std::bad_alloc
&) { __secapiresult
=memFullErr
; }
243 catch (...) { __secapiresult
=internalComponentErr
; }
248 SecCertificateCopySubjectComponent(SecCertificateRef certificate
, const CSSM_OID
*component
, CFStringRef
*result
)
252 Required(result
) = Certificate::required(certificate
)->distinguishedName(&CSSMOID_X509V1SubjectNameCStruct
, component
);
258 SecCertificateGetCommonName(SecCertificateRef certificate
, CFStringRef
*commonName
)
260 // deprecated SPI signature; replaced by SecCertificateCopyCommonName
261 return SecCertificateCopyCommonName(certificate
, commonName
);
265 SecCertificateGetEmailAddress(SecCertificateRef certificate
, CFStringRef
*emailAddress
)
269 Required(emailAddress
) = Certificate::required(certificate
)->copyFirstEmailAddress();
275 SecCertificateCopyEmailAddresses(SecCertificateRef certificate
, CFArrayRef
*emailAddresses
)
279 Required(emailAddresses
) = Certificate::required(certificate
)->copyEmailAddresses();
285 SecCertificateCopyFieldValues(SecCertificateRef certificate
, const CSSM_OID
*field
, CSSM_DATA_PTR
**fieldValues
)
287 /* Return a zero terminated list of CSSM_DATA_PTR's with the values of the field specified by field. Caller must call releaseFieldValues to free the storage allocated by this call. */
290 Required(fieldValues
) = Certificate::required(certificate
)->copyFieldValues(Required(field
));
296 SecCertificateReleaseFieldValues(SecCertificateRef certificate
, const CSSM_OID
*field
, CSSM_DATA_PTR
*fieldValues
)
300 Certificate::required(certificate
)->releaseFieldValues(Required(field
), fieldValues
);
306 SecCertificateCopyFirstFieldValue(SecCertificateRef certificate
, const CSSM_OID
*field
, CSSM_DATA_PTR
*fieldValue
)
310 Required(fieldValue
) = Certificate::required(certificate
)->copyFirstFieldValue(Required(field
));
316 SecCertificateReleaseFirstFieldValue(SecCertificateRef certificate
, const CSSM_OID
*field
, CSSM_DATA_PTR fieldValue
)
320 Certificate::required(certificate
)->releaseFieldValue(Required(field
), fieldValue
);
326 SecCertificateFindByIssuerAndSN(CFTypeRef keychainOrArray
,const CSSM_DATA
*issuer
,
327 const CSSM_DATA
*serialNumber
, SecCertificateRef
*certificate
)
331 StorageManager::KeychainList keychains
;
332 globals().storageManager
.optionalSearchList(keychainOrArray
, keychains
);
333 Required(certificate
) = Certificate::findByIssuerAndSN(keychains
, CssmData::required(issuer
), CssmData::required(serialNumber
))->handle();
339 SecCertificateFindBySubjectKeyID(CFTypeRef keychainOrArray
, const CSSM_DATA
*subjectKeyID
,
340 SecCertificateRef
*certificate
)
344 StorageManager::KeychainList keychains
;
345 globals().storageManager
.optionalSearchList(keychainOrArray
, keychains
);
346 Required(certificate
) = Certificate::findBySubjectKeyID(keychains
, CssmData::required(subjectKeyID
))->handle();
352 SecCertificateFindByEmail(CFTypeRef keychainOrArray
, const char *emailAddress
, SecCertificateRef
*certificate
)
356 StorageManager::KeychainList keychains
;
357 globals().storageManager
.optionalSearchList(keychainOrArray
, keychains
);
358 Required(certificate
) = Certificate::findByEmail(keychains
, emailAddress
)->handle();
364 SecKeychainSearchCreateForCertificateByIssuerAndSN(CFTypeRef keychainOrArray
, const CSSM_DATA
*issuer
,
365 const CSSM_DATA
*serialNumber
, SecKeychainSearchRef
*searchRef
)
371 StorageManager::KeychainList keychains
;
372 globals().storageManager
.optionalSearchList(keychainOrArray
, keychains
);
373 KCCursor
cursor(Certificate::cursorForIssuerAndSN(keychains
, CssmData::required(issuer
), CssmData::required(serialNumber
)));
374 *searchRef
= cursor
->handle();
380 SecKeychainSearchCreateForCertificateByIssuerAndSN_CF(CFTypeRef keychainOrArray
, CFDataRef issuer
,
381 CFDataRef serialNumber
, SecKeychainSearchRef
*searchRef
)
387 StorageManager::KeychainList keychains
;
388 globals().storageManager
.optionalSearchList(keychainOrArray
, keychains
);
390 Required(serialNumber
);
391 KCCursor
cursor(Certificate::cursorForIssuerAndSN_CF(keychains
, issuer
, serialNumber
));
392 *searchRef
= cursor
->handle();
398 SecKeychainSearchCreateForCertificateBySubjectKeyID(CFTypeRef keychainOrArray
, const CSSM_DATA
*subjectKeyID
,
399 SecKeychainSearchRef
*searchRef
)
405 StorageManager::KeychainList keychains
;
406 globals().storageManager
.optionalSearchList(keychainOrArray
, keychains
);
407 KCCursor
cursor(Certificate::cursorForSubjectKeyID(keychains
, CssmData::required(subjectKeyID
)));
408 *searchRef
= cursor
->handle();
414 SecKeychainSearchCreateForCertificateByEmail(CFTypeRef keychainOrArray
, const char *emailAddress
,
415 SecKeychainSearchRef
*searchRef
)
421 StorageManager::KeychainList keychains
;
422 globals().storageManager
.optionalSearchList(keychainOrArray
, keychains
);
423 KCCursor
cursor(Certificate::cursorForEmail(keychains
, emailAddress
));
424 *searchRef
= cursor
->handle();
429 /* NOT EXPORTED YET; copied from SecurityInterface but could be useful in the future.
431 SecGetAppleCSPHandle()
434 return CSP(gGuidAppleCSP)->handle();
439 SecGetAppleCLHandle()
442 return CL(gGuidAppleX509CL)->handle();
448 SecDigestGetData (CSSM_ALGORITHMS alg
, CSSM_DATA
* digest
, const CSSM_DATA
* data
)
452 if (!digest
|| !digest
->Data
|| !digest
->Length
|| !data
|| !data
->Data
|| !data
->Length
)
455 CSP
csp(gGuidAppleCSP
);
456 Digest
context(csp
, alg
);
457 CssmData
input(data
->Data
, data
->Length
);
458 CssmData
output(digest
->Data
, digest
->Length
);
460 context
.digest(input
, output
);
461 digest
->Length
= output
.length();
467 /* determine whether a cert is self-signed */
468 OSStatus
SecCertificateIsSelfSigned(
469 SecCertificateRef certificate
,
470 Boolean
*isSelfSigned
) /* RETURNED */
474 *isSelfSigned
= Certificate::required(certificate
)->isSelfSigned();
480 SecCertificateCopyPreference(
482 CSSM_KEYUSE keyUsage
,
483 SecCertificateRef
*certificate
)
488 Required(certificate
);
489 StorageManager::KeychainList keychains
;
490 globals().storageManager
.getSearchList(keychains
);
491 KCCursor
cursor(keychains
, kSecGenericPasswordItemClass
, NULL
);
493 char idUTF8
[MAXPATHLEN
];
494 if (!CFStringGetCString(name
, idUTF8
, sizeof(idUTF8
)-1, kCFStringEncodingUTF8
))
495 idUTF8
[0] = (char)'\0';
496 CssmData
service(const_cast<char *>(idUTF8
), strlen(idUTF8
));
497 FourCharCode itemType
= 'cprf';
498 cursor
->add(CSSM_DB_EQUAL
, Schema::attributeInfo(kSecServiceItemAttr
), service
);
499 cursor
->add(CSSM_DB_EQUAL
, Schema::attributeInfo(kSecTypeItemAttr
), itemType
);
501 cursor
->add(CSSM_DB_EQUAL
, Schema::attributeInfo(kSecScriptCodeItemAttr
), (sint32
)keyUsage
);
504 if (!cursor
->next(prefItem
))
505 MacOSError::throwMe(errSecItemNotFound
);
507 // get persistent certificate reference
508 SecKeychainAttribute itemAttrs
[] = { { kSecGenericItemAttr
, 0, NULL
} };
509 SecKeychainAttributeList itemAttrList
= { sizeof(itemAttrs
) / sizeof(itemAttrs
[0]), itemAttrs
};
510 prefItem
->getContent(NULL
, &itemAttrList
, NULL
, NULL
);
512 // find certificate, given persistent reference data
513 CFDataRef pItemRef
= CFDataCreateWithBytesNoCopy(NULL
, (const UInt8
*)itemAttrs
[0].data
, itemAttrs
[0].length
, kCFAllocatorNull
);
514 SecKeychainItemRef certItemRef
= nil
;
515 OSStatus status
= SecKeychainItemCopyFromPersistentReference(pItemRef
, &certItemRef
); //%%% need to make this a method of ItemImpl
516 prefItem
->freeContent(&itemAttrList
, NULL
);
522 *certificate
= (SecCertificateRef
)certItemRef
;
528 SecCertificateCopyPreferred(
532 // This function will look for a matching preference in the following order:
533 // - matches the name and the supplied key use
534 // - matches the name and the special 'ANY' key use
535 // - matches the name with no key usage constraint
537 SecCertificateRef certRef
= NULL
;
538 CSSM_KEYUSE keyUse
= ConvertArrayToKeyUsage(keyUsage
);
539 OSStatus status
= SecCertificateCopyPreference(name
, keyUse
, &certRef
);
540 if (status
!= noErr
&& keyUse
!= CSSM_KEYUSE_ANY
)
541 status
= SecCertificateCopyPreference(name
, CSSM_KEYUSE_ANY
, &certRef
);
542 if (status
!= noErr
&& keyUse
!= 0)
543 status
= SecCertificateCopyPreference(name
, 0, &certRef
);
549 SecCertificateFindPreferenceItemWithNameAndKeyUsage(
550 CFTypeRef keychainOrArray
,
553 SecKeychainItemRef
*itemRef
)
557 StorageManager::KeychainList keychains
;
558 globals().storageManager
.optionalSearchList(keychainOrArray
, keychains
);
559 KCCursor
cursor(keychains
, kSecGenericPasswordItemClass
, NULL
);
561 char idUTF8
[MAXPATHLEN
];
562 idUTF8
[0] = (char)'\0';
565 if (!CFStringGetCString(name
, idUTF8
, sizeof(idUTF8
)-1, kCFStringEncodingUTF8
))
566 idUTF8
[0] = (char)'\0';
568 size_t idUTF8Len
= strlen(idUTF8
);
570 MacOSError::throwMe(paramErr
);
572 CssmData
service(const_cast<char *>(idUTF8
), idUTF8Len
);
573 cursor
->add(CSSM_DB_EQUAL
, Schema::attributeInfo(kSecServiceItemAttr
), service
);
574 cursor
->add(CSSM_DB_EQUAL
, Schema::attributeInfo(kSecTypeItemAttr
), (FourCharCode
)'cprf');
576 cursor
->add(CSSM_DB_EQUAL
, Schema::attributeInfo(kSecScriptCodeItemAttr
), (sint32
)keyUsage
);
579 if (!cursor
->next(item
))
580 MacOSError::throwMe(errSecItemNotFound
);
583 *itemRef
=item
->handle();
588 OSStatus
SecCertificateDeletePreferenceItemWithNameAndKeyUsage(
589 CFTypeRef keychainOrArray
,
593 // when a specific key usage is passed, we'll only match & delete that pref;
594 // when a key usage of 0 is passed, all matching prefs should be deleted.
595 // maxUsages represents the most matches there could theoretically be, so
596 // cut things off at that point if we're still finding items (if they can't
597 // be deleted for some reason, we'd never break out of the loop.)
600 SecKeychainItemRef item
= NULL
;
601 int count
= 0, maxUsages
= 12;
602 while (++count
<= maxUsages
&&
603 (status
= SecCertificateFindPreferenceItemWithNameAndKeyUsage(keychainOrArray
, name
, keyUsage
, &item
)) == noErr
) {
604 status
= SecKeychainItemDelete(item
);
609 // it's not an error if the item isn't found
610 return (status
== errSecItemNotFound
) ? noErr
: status
;
613 OSStatus
SecCertificateSetPreference(
614 SecCertificateRef certificate
,
616 CSSM_KEYUSE keyUsage
,
623 // treat NULL certificate as a request to clear the preference
624 // (note: if keyUsage is 0, this clears all key usage prefs for name)
625 return SecCertificateDeletePreferenceItemWithNameAndKeyUsage(NULL
, name
, keyUsage
);
630 // determine the account attribute
632 // This attribute must be synthesized from certificate label + pref item type + key usage,
633 // as only the account and service attributes can make a generic keychain item unique.
634 // For 'iprf' type items (but not 'cprf'), we append a trailing space. This insures that
635 // we can save a certificate preference if an identity preference already exists for the
636 // given service name, and vice-versa.
637 // If the key usage is 0 (i.e. the normal case), we omit the appended key usage string.
639 CFStringRef labelStr
= nil
;
640 Certificate::required(certificate
)->inferLabel(false, &labelStr
);
642 MacOSError::throwMe(errSecDataTooLarge
); // data is "in a format which cannot be displayed"
644 CFIndex accountUTF8Len
= CFStringGetMaximumSizeForEncoding(CFStringGetLength(labelStr
), kCFStringEncodingUTF8
) + 1;
645 const char *templateStr
= "%s [key usage 0x%X]";
646 const int keyUsageMaxStrLen
= 8;
647 accountUTF8Len
+= strlen(templateStr
) + keyUsageMaxStrLen
;
648 char accountUTF8
[accountUTF8Len
];
649 if (!CFStringGetCString(labelStr
, accountUTF8
, accountUTF8Len
-1, kCFStringEncodingUTF8
))
650 accountUTF8
[0] = (char)'\0';
652 snprintf(accountUTF8
, accountUTF8Len
-1, templateStr
, accountUTF8
, keyUsage
);
653 CssmData
account(const_cast<char *>(accountUTF8
), strlen(accountUTF8
));
656 // service attribute (name provided by the caller)
657 CFIndex serviceUTF8Len
= CFStringGetMaximumSizeForEncoding(CFStringGetLength(name
), kCFStringEncodingUTF8
) + 1;;
658 char serviceUTF8
[serviceUTF8Len
];
659 if (!CFStringGetCString(name
, serviceUTF8
, serviceUTF8Len
-1, kCFStringEncodingUTF8
))
660 serviceUTF8
[0] = (char)'\0';
661 CssmData
service(const_cast<char *>(serviceUTF8
), strlen(serviceUTF8
));
663 // look for existing preference item, in case this is an update
664 StorageManager::KeychainList keychains
;
665 globals().storageManager
.getSearchList(keychains
);
666 KCCursor
cursor(keychains
, kSecGenericPasswordItemClass
, NULL
);
667 FourCharCode itemType
= 'cprf';
668 cursor
->add(CSSM_DB_EQUAL
, Schema::attributeInfo(kSecServiceItemAttr
), service
);
669 cursor
->add(CSSM_DB_EQUAL
, Schema::attributeInfo(kSecTypeItemAttr
), itemType
);
671 cursor
->add(CSSM_DB_EQUAL
, Schema::attributeInfo(kSecScriptCodeItemAttr
), (sint32
)keyUsage
);
675 Item
item(kSecGenericPasswordItemClass
, 'aapl', 0, NULL
, false);
676 bool add
= (!cursor
->next(item
));
677 // at this point, we either have a new item to add or an existing item to update
679 // set item attribute values
680 item
->setAttribute(Schema::attributeInfo(kSecServiceItemAttr
), service
);
681 item
->setAttribute(Schema::attributeInfo(kSecTypeItemAttr
), itemType
);
682 item
->setAttribute(Schema::attributeInfo(kSecAccountItemAttr
), account
);
683 item
->setAttribute(Schema::attributeInfo(kSecScriptCodeItemAttr
), (sint32
)keyUsage
);
684 item
->setAttribute(Schema::attributeInfo(kSecLabelItemAttr
), service
);
690 // generic attribute (store persistent certificate reference)
691 CFDataRef pItemRef
= nil
;
692 Certificate::required(certificate
)->copyPersistentReference(pItemRef
);
694 MacOSError::throwMe(errSecInvalidItemRef
);
696 const UInt8
*dataPtr
= CFDataGetBytePtr(pItemRef
);
697 CFIndex dataLen
= CFDataGetLength(pItemRef
);
698 CssmData
pref(const_cast<void *>(reinterpret_cast<const void *>(dataPtr
)), dataLen
);
699 item
->setAttribute(Schema::attributeInfo(kSecGenericItemAttr
), pref
);
703 Keychain keychain
= nil
;
705 keychain
= globals().storageManager
.defaultKeychain();
706 if (!keychain
->exists())
707 MacOSError::throwMe(errSecNoSuchKeychain
); // Might be deleted or not available at this time.
710 keychain
= globals().storageManager
.defaultKeychainUI(item
);
716 catch (const MacOSError
&err
) {
717 if (err
.osStatus() != errSecDuplicateItem
)
718 throw; // if item already exists, fall through to update
726 OSStatus
SecCertificateSetPreferred(
727 SecCertificateRef certificate
,
731 CSSM_KEYUSE keyUse
= ConvertArrayToKeyUsage(keyUsage
);
732 return SecCertificateSetPreference(certificate
, name
, keyUse
, NULL
);
735 CFDictionaryRef
SecCertificateCopyValues(SecCertificateRef certificate
, CFArrayRef keys
, CFErrorRef
*error
)
737 CFDictionaryRef result
= NULL
;
738 OSStatus __secapiresult
;
741 CertificateValues
cv(certificate
);
742 result
= cv
.copyFieldValues(keys
,error
);
745 catch (const MacOSError
&err
) { __secapiresult
=err
.osStatus(); }
746 catch (const CommonError
&err
) { __secapiresult
=SecKeychainErrFromOSStatus(err
.osStatus()); }
747 catch (const std::bad_alloc
&) { __secapiresult
=memFullErr
; }
748 catch (...) { __secapiresult
=internalComponentErr
; }
752 CFStringRef
SecCertificateCopyLongDescription(CFAllocatorRef alloc
, SecCertificateRef certificate
, CFErrorRef
*error
)
754 return SecCertificateCopyShortDescription(alloc
, certificate
, error
);
757 CFStringRef
SecCertificateCopyShortDescription(CFAllocatorRef alloc
, SecCertificateRef certificate
, CFErrorRef
*error
)
759 CFStringRef result
= NULL
;
760 OSStatus __secapiresult
;
763 __secapiresult
= SecCertificateInferLabel(certificate
, &result
);
765 catch (const MacOSError
&err
) { __secapiresult
=err
.osStatus(); }
766 catch (const CommonError
&err
) { __secapiresult
=SecKeychainErrFromOSStatus(err
.osStatus()); }
767 catch (const std::bad_alloc
&) { __secapiresult
=memFullErr
; }
768 catch (...) { __secapiresult
=internalComponentErr
; }
769 if (error
!=NULL
&& __secapiresult
!=noErr
)
771 *error
= CFErrorCreate(kCFAllocatorDefault
, kCFErrorDomainOSStatus
,
772 __secapiresult
? __secapiresult
: CSSM_ERRCODE_INTERNAL_ERROR
, NULL
);
777 CFDataRef
SecCertificateCopySerialNumber(SecCertificateRef certificate
, CFErrorRef
*error
)
779 CFDataRef result
= NULL
;
780 OSStatus __secapiresult
;
783 CertificateValues
cv(certificate
);
784 result
= cv
.copySerialNumber(error
);
787 catch (const MacOSError
&err
) { __secapiresult
=err
.osStatus(); }
788 catch (const CommonError
&err
) { __secapiresult
=SecKeychainErrFromOSStatus(err
.osStatus()); }
789 catch (const std::bad_alloc
&) { __secapiresult
=memFullErr
; }
790 catch (...) { __secapiresult
=internalComponentErr
; }
794 CFDataRef
SecCertificateCopyNormalizedIssuerContent(SecCertificateRef certificate
, CFErrorRef
*error
)
796 CFDataRef result
= NULL
;
797 OSStatus __secapiresult
;
800 CertificateValues
cv(certificate
);
801 result
= cv
.getNormalizedIssuerContent(error
);
804 catch (const MacOSError
&err
) { __secapiresult
=err
.osStatus(); }
805 catch (const CommonError
&err
) { __secapiresult
=SecKeychainErrFromOSStatus(err
.osStatus()); }
806 catch (const std::bad_alloc
&) { __secapiresult
=memFullErr
; }
807 catch (...) { __secapiresult
=internalComponentErr
; }
811 CFDataRef
SecCertificateCopyNormalizedSubjectContent(SecCertificateRef certificate
, CFErrorRef
*error
)
813 CFDataRef result
= NULL
;
814 OSStatus __secapiresult
;
817 CertificateValues
cv(certificate
);
818 result
= cv
.getNormalizedSubjectContent(error
);
821 catch (const MacOSError
&err
) { __secapiresult
=err
.osStatus(); }
822 catch (const CommonError
&err
) { __secapiresult
=SecKeychainErrFromOSStatus(err
.osStatus()); }
823 catch (const std::bad_alloc
&) { __secapiresult
=memFullErr
; }
824 catch (...) { __secapiresult
=internalComponentErr
; }
828 bool SecCertificateIsValidX(SecCertificateRef certificate
, CFAbsoluteTime verifyTime
)
831 OSStatus __secapiresult
;
834 CFErrorRef error
= NULL
;
835 CertificateValues
cv(certificate
);
836 result
= cv
.SecCertificateIsValidX(verifyTime
, &error
);
839 catch (const MacOSError
&err
) { __secapiresult
=err
.osStatus(); }
840 catch (const CommonError
&err
) { __secapiresult
=SecKeychainErrFromOSStatus(err
.osStatus()); }
841 catch (const std::bad_alloc
&) { __secapiresult
=memFullErr
; }
842 catch (...) { __secapiresult
=internalComponentErr
; }
847 SecCertificateRef
SecCertificateCreateWithBytes(CFAllocatorRef allocator
,
848 const UInt8
*bytes
, CFIndex length
)
850 SecCertificateRef certificate
= NULL
;
851 OSStatus __secapiresult
;
853 CSSM_DATA cssmCertData
= { (CSSM_SIZE
)length
, (uint8
*)bytes
};
855 //NOTE: there isn't yet a Certificate constructor which accepts a CFAllocatorRef
856 SecPointer
<Certificate
> certificatePtr(new Certificate(cssmCertData
, CSSM_CERT_X_509v3
, CSSM_CERT_ENCODING_DER
));
857 certificate
= certificatePtr
->handle();
859 __secapiresult
=noErr
;
861 catch (const MacOSError
&err
) { __secapiresult
=err
.osStatus(); }
862 catch (const CommonError
&err
) { __secapiresult
=SecKeychainErrFromOSStatus(err
.osStatus()); }
863 catch (const std::bad_alloc
&) { __secapiresult
=memFullErr
; }
864 catch (...) { __secapiresult
=internalComponentErr
; }
869 CFIndex
SecCertificateGetLength(SecCertificateRef certificate
)
872 OSStatus __secapiresult
;
874 CssmData output
= Certificate::required(certificate
)->data();
875 length
= (CFIndex
)output
.length();
876 __secapiresult
=noErr
;
878 catch (const MacOSError
&err
) { __secapiresult
=err
.osStatus(); }
879 catch (const CommonError
&err
) { __secapiresult
=SecKeychainErrFromOSStatus(err
.osStatus()); }
880 catch (const std::bad_alloc
&) { __secapiresult
=memFullErr
; }
881 catch (...) { __secapiresult
=internalComponentErr
; }
886 const UInt8
*SecCertificateGetBytePtr(SecCertificateRef certificate
)
888 const UInt8
*bytes
= NULL
;
889 OSStatus __secapiresult
;
891 CssmData output
= Certificate::required(certificate
)->data();
892 bytes
= (const UInt8
*)output
.data();
893 __secapiresult
=noErr
;
895 catch (const MacOSError
&err
) { __secapiresult
=err
.osStatus(); }
896 catch (const CommonError
&err
) { __secapiresult
=SecKeychainErrFromOSStatus(err
.osStatus()); }
897 catch (const std::bad_alloc
&) { __secapiresult
=memFullErr
; }
898 catch (...) { __secapiresult
=internalComponentErr
; }