#include <security_keychain/KCCursor.h>
#include <security_cdsa_utilities/Schema.h>
#include <security_utilities/simpleprefs.h>
+#include <utilities/SecCFRelease.h>
#include <sys/param.h>
#include <syslog.h>
+#include <os/activity.h>
/* private function declarations */
OSStatus
SecCertificateRef *certificateRef)
{
BEGIN_SECAPI
+ os_activity_t activity = os_activity_create("SecIdentityCopyCertificate", OS_ACTIVITY_CURRENT, OS_ACTIVITY_FLAG_IF_NONE_PRESENT);
+ os_activity_scope(activity);
+ os_release(activity);
- SecPointer<Certificate> certificatePtr(Identity::required(identityRef)->certificate());
- Required(certificateRef) = certificatePtr->handle();
-
-#if SECTRUST_OSX
- /* convert outgoing item to a unified SecCertificateRef */
- CssmData certData = certificatePtr->data();
- CFDataRef data = NULL;
- if (certData.Data && certData.Length) {
- data = CFDataCreate(NULL, certData.Data, certData.Length);
+ if (!identityRef || !certificateRef) {
+ return errSecParam;
+ }
+ CFTypeID itemType = CFGetTypeID(identityRef);
+ if (itemType == SecIdentityGetTypeID()) {
+ SecPointer<Certificate> certificatePtr(Identity::required(identityRef)->certificate());
+ Required(certificateRef) = certificatePtr->handle();
+
+ /* convert outgoing certificate item to a unified SecCertificateRef */
+ CssmData certData = certificatePtr->data();
+ CFDataRef data = NULL;
+ if (certData.Data && certData.Length) {
+ data = CFDataCreate(NULL, certData.Data, certData.Length);
+ }
+ if (!data) {
+ *certificateRef = NULL;
+ syslog(LOG_ERR, "ERROR: SecIdentityCopyCertificate failed to retrieve certificate data (length=%ld, data=0x%lX)",
+ (long)certData.Length, (uintptr_t)certData.Data);
+ return errSecInternal;
+ }
+ SecCertificateRef tmpRef = *certificateRef;
+ *certificateRef = SecCertificateCreateWithKeychainItem(NULL, data, tmpRef);
+ if (data) {
+ CFRelease(data);
+ }
+ if (tmpRef) {
+ CFRelease(tmpRef);
+ }
+ }
+ else if (itemType == SecCertificateGetTypeID()) {
+ // rdar://24483382
+ // reconstituting a persistent identity reference could return the certificate
+ SecCertificateRef certificate = (SecCertificateRef)identityRef;
+
+ /* convert outgoing certificate item to a unified SecCertificateRef, if needed */
+ if (SecCertificateIsItemImplInstance(certificate)) {
+ *certificateRef = SecCertificateCreateFromItemImplInstance(certificate);
+ }
+ else {
+ *certificateRef = (SecCertificateRef) CFRetain(certificate);
+ }
+ return errSecSuccess;
}
- if (!data) {
- *certificateRef = NULL;
- syslog(LOG_ERR, "ERROR: SecIdentityCopyCertificate failed to retrieve certificate data (length=%ld, data=0x%lX)",
- (long)certData.Length, (uintptr_t)certData.Data);
- return errSecInternal;
+ else {
+ return errSecParam;
}
- SecCertificateRef tmpRef = *certificateRef;
- *certificateRef = SecCertificateCreateWithKeychainItem(NULL, data, tmpRef);
- if (data)
- CFRelease(data);
- if (tmpRef)
- CFRelease(tmpRef);
-#endif
END_SECAPI
}
SecKeyRef *privateKeyRef)
{
BEGIN_SECAPI
+ os_activity_t activity = os_activity_create("SecIdentityCopyPrivateKey", OS_ACTIVITY_CURRENT, OS_ACTIVITY_FLAG_IF_NONE_PRESENT);
+ os_activity_scope(activity);
+ os_release(activity);
- SecPointer<KeyItem> keyItemPtr(Identity::required(identityRef)->privateKey());
- Required(privateKeyRef) = keyItemPtr->handle();
+ Required(privateKeyRef) = (SecKeyRef)CFRetain(Identity::required(identityRef)->privateKeyRef());
END_SECAPI
}
{
SecIdentityRef identityRef = NULL;
OSStatus __secapiresult;
- SecCertificateRef __itemImplRef=SecCertificateCreateItemImplInstance(certificate);
+ SecCertificateRef __itemImplRef = NULL;
+ if (SecCertificateIsItemImplInstance(certificate)) {
+ __itemImplRef=(SecCertificateRef)CFRetain(certificate);
+ }
+ if (!__itemImplRef && certificate) {
+ __itemImplRef=(SecCertificateRef)SecCertificateCopyKeychainItem(certificate);
+ }
+ if (!__itemImplRef && certificate) {
+ __itemImplRef=SecCertificateCreateItemImplInstance(certificate);
+ (void)SecCertificateSetKeychainItem(certificate,__itemImplRef);
+ }
try {
SecPointer<Certificate> certificatePtr(Certificate::required(__itemImplRef));
- SecPointer<KeyItem> keyItemPtr(KeyItem::required(privateKey));
- SecPointer<Identity> identityPtr(new Identity(keyItemPtr, certificatePtr));
+ SecPointer<Identity> identityPtr(new Identity(privateKey, certificatePtr));
identityRef = identityPtr->handle();
__secapiresult=errSecSuccess;
catch (const CommonError &err) { __secapiresult=SecKeychainErrFromOSStatus(err.osStatus()); }
catch (const std::bad_alloc &) { __secapiresult=errSecAllocate; }
catch (...) { __secapiresult=errSecInternalComponent; }
+ if (__itemImplRef) { CFRelease(__itemImplRef); }
return identityRef;
}
return kCFCompareGreaterThan;
}
- BEGIN_SECAPI
-
- SecPointer<Identity> id1(Identity::required(identity1));
- SecPointer<Identity> id2(Identity::required(identity2));
-
- if (id1 == id2)
- return kCFCompareEqualTo;
- else if (id1 < id2)
- return kCFCompareLessThan;
- else
- return kCFCompareGreaterThan;
-
- END_SECAPI1(kCFCompareGreaterThan);
+ try {
+ SecPointer<Identity> id1(Identity::required(identity1));
+ SecPointer<Identity> id2(Identity::required(identity2));
+
+ if (id1 == id2)
+ return kCFCompareEqualTo;
+ else if (id1 < id2)
+ return kCFCompareLessThan;
+ else
+ return kCFCompareGreaterThan;
+ } catch(...)
+ {}
+
+ return kCFCompareGreaterThan;
}
static
}
// create identity reference, given certificate
-#if SECTRUST_OSX
- status = SecIdentityCreateWithCertificate(NULL, (SecCertificateRef)certItemRef, identity);
-#else
- try {
- Item certItem = ItemImpl::required(SecKeychainItemRef(certItemRef));
- SecPointer<Certificate> certificate(static_cast<Certificate *>(certItem.get()));
- SecPointer<Identity> identity_ptr(new Identity(keychains, certificate));
- if (certItemRef) {
- CFRelease(certItemRef); // retained by identity
- }
- Required(identity) = identity_ptr->handle();
- }
- catch (const MacOSError &err) { status=err.osStatus(); }
- catch (const CommonError &err) { status=SecKeychainErrFromOSStatus(err.osStatus()); }
- catch (const std::bad_alloc &) { status=errSecAllocate; }
- catch (...) { status=errSecInvalidItemRef; }
-#endif
+ status = SecIdentityCreateWithCertificate(NULL, (SecCertificateRef)certItemRef, identity);
+ if (certItemRef) {
+ CFRelease(certItemRef);
+ }
- return status;
+ return status;
}
SecIdentityRef SecIdentityCopyPreferred(CFStringRef name, CFArrayRef keyUsage, CFArrayRef validIssuers)
// (Note that behavior is unchanged if the specified name is not a URL.)
BEGIN_SECAPI
+ os_activity_t activity = os_activity_create("SecIdentityCopyPreference", OS_ACTIVITY_CURRENT, OS_ACTIVITY_FLAG_IF_NONE_PRESENT);
+ os_activity_scope(activity);
+ os_release(activity);
CFTypeRef val = (CFTypeRef)CFPreferencesCopyValue(CFSTR("LogIdentityPreferenceLookup"),
CFSTR("com.apple.security"),
kCFPreferencesCurrentUser,
kCFPreferencesAnyHost);
Boolean logging = false;
- if (val && CFGetTypeID(val) == CFBooleanGetTypeID()) {
- logging = CFBooleanGetValue((CFBooleanRef)val);
- CFRelease(val);
+ if (val) {
+ if (CFGetTypeID(val) == CFBooleanGetTypeID()) {
+ logging = CFBooleanGetValue((CFBooleanRef)val);
+ }
}
+ CFReleaseNull(val);
OSStatus status = errSecItemNotFound;
CFArrayRef names = _SecIdentityCopyPossiblePaths(name);
}
BEGIN_SECAPI
-
- SecPointer<Certificate> certificate(Identity::required(identity)->certificate());
+ os_activity_t activity = os_activity_create("SecIdentitySetPreference", OS_ACTIVITY_CURRENT, OS_ACTIVITY_FLAG_IF_NONE_PRESENT);
+ os_activity_scope(activity);
+ os_release(activity);
+
+ CFRef<SecCertificateRef> certRef;
+ OSStatus status = SecIdentityCopyCertificate(identity, certRef.take());
+ if(status != errSecSuccess) {
+ MacOSError::throwMe(status);
+ }
// determine the account attribute
//
// If the key usage is 0 (i.e. the normal case), we omit the appended key usage string.
//
CFStringRef labelStr = nil;
- certificate->inferLabel(false, &labelStr);
+ SecCertificateInferLabel(certRef.get(), &labelStr);
if (!labelStr) {
MacOSError::throwMe(errSecDataTooLarge); // data is "in a format which cannot be displayed"
}
const char *templateStr = "%s [key usage 0x%X]";
const int keyUsageMaxStrLen = 8;
accountUTF8Len += strlen(templateStr) + keyUsageMaxStrLen;
- char accountUTF8[accountUTF8Len];
+ char *accountUTF8 = (char *)malloc(accountUTF8Len);
+ if (!accountUTF8) {
+ MacOSError::throwMe(errSecMemoryError);
+ }
if (!CFStringGetCString(labelStr, accountUTF8, accountUTF8Len-1, kCFStringEncodingUTF8))
accountUTF8[0] = (char)'\0';
if (keyUsage)
snprintf(accountUTF8, accountUTF8Len-1, templateStr, accountUTF8, keyUsage);
snprintf(accountUTF8, accountUTF8Len-1, "%s ", accountUTF8);
- CssmData account(const_cast<char *>(accountUTF8), strlen(accountUTF8));
+ CssmDataContainer account(const_cast<char *>(accountUTF8), strlen(accountUTF8));
+ free(accountUTF8);
CFRelease(labelStr);
// service attribute (name provided by the caller)
CFIndex serviceUTF8Len = CFStringGetMaximumSizeForEncoding(CFStringGetLength(name), kCFStringEncodingUTF8) + 1;;
- char serviceUTF8[serviceUTF8Len];
+ char *serviceUTF8 = (char *)malloc(serviceUTF8Len);
+ if (!serviceUTF8) {
+ MacOSError::throwMe(errSecMemoryError);
+ }
if (!CFStringGetCString(name, serviceUTF8, serviceUTF8Len-1, kCFStringEncodingUTF8))
serviceUTF8[0] = (char)'\0';
- CssmData service(const_cast<char *>(serviceUTF8), strlen(serviceUTF8));
+ CssmDataContainer service(const_cast<char *>(serviceUTF8), strlen(serviceUTF8));
+ free(serviceUTF8);
// look for existing identity preference item, in case this is an update
StorageManager::KeychainList keychains;
// generic attribute (store persistent certificate reference)
CFDataRef pItemRef = nil;
- certificate->copyPersistentReference(pItemRef);
+ SecKeychainItemCreatePersistentReference((SecKeychainItemRef)certRef.get(), &pItemRef);
if (!pItemRef) {
MacOSError::throwMe(errSecInvalidItemRef);
}
SecKeychainItemRef *itemRef)
{
BEGIN_SECAPI
+ os_activity_t activity = os_activity_create("SecIdentityFindPreferenceItem", OS_ACTIVITY_CURRENT, OS_ACTIVITY_FLAG_IF_NONE_PRESENT);
+ os_activity_scope(activity);
+ os_release(activity);
StorageManager::KeychainList keychains;
globals().storageManager.optionalSearchList(keychainOrArray, keychains);
SecKeychainItemRef *itemRef)
{
BEGIN_SECAPI
+ os_activity_t activity = os_activity_create("SecIdentityFindPreferenceItemWithNameAndKeyUsage", OS_ACTIVITY_CURRENT, OS_ACTIVITY_FLAG_IF_NONE_PRESENT);
+ os_activity_scope(activity);
+ os_release(activity);
StorageManager::KeychainList keychains;
globals().storageManager.optionalSearchList(keychainOrArray, keychains);
// cut things off at that point if we're still finding items (if they can't
// be deleted for some reason, we'd never break out of the loop.)
- OSStatus status;
+ OSStatus status = errSecInternalError;
SecKeychainItemRef item = NULL;
int count = 0, maxUsages = 12;
while (++count <= maxUsages &&
const char *templateStr = "%s [key usage 0x%X]";
const int keyUsageMaxStrLen = 8;
accountUTF8Len += strlen(templateStr) + keyUsageMaxStrLen;
- char accountUTF8[accountUTF8Len];
+ char *accountUTF8 = (char *)malloc(accountUTF8Len);
+ if (!accountUTF8) {
+ MacOSError::throwMe(errSecMemoryError);
+ }
if (!CFStringGetCString(labelStr, accountUTF8, accountUTF8Len-1, kCFStringEncodingUTF8))
accountUTF8[0] = (char)'\0';
if (keyUsage)
snprintf(accountUTF8, accountUTF8Len-1, templateStr, accountUTF8, keyUsage);
snprintf(accountUTF8, accountUTF8Len-1, "%s ", accountUTF8);
- CssmData account(const_cast<char *>(accountUTF8), strlen(accountUTF8));
+ CssmDataContainer account(const_cast<char *>(accountUTF8), strlen(accountUTF8));
+ free(accountUTF8);
CFRelease(labelStr);
// service attribute (name provided by the caller)
CFIndex serviceUTF8Len = CFStringGetMaximumSizeForEncoding(CFStringGetLength(idString), kCFStringEncodingUTF8) + 1;;
- char serviceUTF8[serviceUTF8Len];
+ char *serviceUTF8 = (char *)malloc(serviceUTF8Len);
+ if (!serviceUTF8) {
+ MacOSError::throwMe(errSecMemoryError);
+ }
if (!CFStringGetCString(idString, serviceUTF8, serviceUTF8Len-1, kCFStringEncodingUTF8))
serviceUTF8[0] = (char)'\0';
- CssmData service(const_cast<char *>(serviceUTF8), strlen(serviceUTF8));
+ CssmDataContainer service(const_cast<char *>(serviceUTF8), strlen(serviceUTF8));
+ free(serviceUTF8);
// set item attribute values
item->setAttribute(Schema::attributeInfo(kSecServiceItemAttr), service);
// (Note that behavior is unchanged if the specified idString is not a URL.)
BEGIN_SECAPI
+ os_activity_t activity = os_activity_create("SecIdentityAddPreferenceItem", OS_ACTIVITY_CURRENT, OS_ACTIVITY_FLAG_IF_NONE_PRESENT);
+ os_activity_scope(activity);
+ os_release(activity);
OSStatus status = errSecInternalComponent;
CFArrayRef names = _SecIdentityCopyPossiblePaths(idString);
SecIdentityRef identityRef)
{
BEGIN_SECAPI
+ os_activity_t activity = os_activity_create("SecIdentityUpdatePreferenceItem", OS_ACTIVITY_CURRENT, OS_ACTIVITY_FLAG_IF_NONE_PRESENT);
+ os_activity_scope(activity);
+ os_release(activity);
if (!itemRef || !identityRef)
MacOSError::throwMe(errSecParam);
const char *templateStr = "%s [key usage 0x%X]";
const int keyUsageMaxStrLen = 8;
accountUTF8Len += strlen(templateStr) + keyUsageMaxStrLen;
- char accountUTF8[accountUTF8Len];
- if (!CFStringGetCString(labelStr, accountUTF8, accountUTF8Len-1, kCFStringEncodingUTF8))
+ char *accountUTF8 = (char *)malloc(accountUTF8Len);
+ if (!accountUTF8) {
+ MacOSError::throwMe(errSecMemoryError);
+ }
+ if (!CFStringGetCString(labelStr, accountUTF8, accountUTF8Len-1, kCFStringEncodingUTF8))
accountUTF8[0] = (char)'\0';
if (keyUsage)
snprintf(accountUTF8, accountUTF8Len-1, templateStr, accountUTF8, keyUsage);
snprintf(accountUTF8, accountUTF8Len-1, "%s ", accountUTF8);
- CssmData account(const_cast<char *>(accountUTF8), strlen(accountUTF8));
+ CssmDataContainer account(const_cast<char *>(accountUTF8), strlen(accountUTF8));
prefItem->setAttribute(Schema::attributeInfo(kSecAccountItemAttr), account);
- CFRelease(labelStr);
+ free(accountUTF8);
+ CFRelease(labelStr);
// generic attribute (store persistent certificate reference)
CFDataRef pItemRef = nil;
SecIdentityRef *identityRef)
{
BEGIN_SECAPI
+ os_activity_t activity = os_activity_create("SecIdentityCopyFromPreferenceItem", OS_ACTIVITY_CURRENT, OS_ACTIVITY_FLAG_IF_NONE_PRESENT);
+ os_activity_scope(activity);
+ os_release(activity);
if (!itemRef || !identityRef)
MacOSError::throwMe(errSecParam);
CFStringRef *actualDomain) /* optional */
{
BEGIN_SECAPI
+ os_activity_t activity = os_activity_create("SecIdentityCopySystemIdentity", OS_ACTIVITY_CURRENT, OS_ACTIVITY_FLAG_IF_NONE_PRESENT);
+ os_activity_scope(activity);
+ os_release(activity);
StLock<Mutex> _(systemIdentityLock());
auto_ptr<Dictionary> identDict;
SecIdentityRef idRef)
{
BEGIN_SECAPI
+ os_activity_t activity = os_activity_create("SecIdentitySetSystemIdentity", OS_ACTIVITY_CURRENT, OS_ACTIVITY_FLAG_IF_NONE_PRESENT);
+ os_activity_scope(activity);
+ os_release(activity);
StLock<Mutex> _(systemIdentityLock());
if(geteuid() != 0) {