#include <utilities/SecCFRelease.h>
#include <sys/param.h>
#include <syslog.h>
+#include <os/activity.h>
+#include "LegacyAPICounts.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);
if (!identityRef || !certificateRef) {
return errSecParam;
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);
Required(privateKeyRef) = (SecKeyRef)CFRetain(Identity::required(identityRef)->privateKeyRef());
SecCertificateRef certificate,
SecKeyRef privateKey)
{
+ COUNTLEGACYAPI
SecIdentityRef identityRef = NULL;
OSStatus __secapiresult;
SecCertificateRef __itemImplRef = NULL;
return identityRef;
}
-CFComparisonResult
-SecIdentityCompare(
- SecIdentityRef identity1,
- SecIdentityRef identity2,
- CFOptionFlags compareOptions)
-{
- if (!identity1 || !identity2)
- {
- if (identity1 == identity2)
- return kCFCompareEqualTo;
- else if (identity1 < identity2)
- return kCFCompareLessThan;
- else
- return 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
CFArrayRef _SecIdentityCopyPossiblePaths(
CFStringRef name)
FourCharCode itemType = 'iprf';
cursor->add(CSSM_DB_EQUAL, Schema::attributeInfo(kSecServiceItemAttr), service);
cursor->add(CSSM_DB_EQUAL, Schema::attributeInfo(kSecTypeItemAttr), itemType);
- if (keyUsage)
+ if (keyUsage) {
cursor->add(CSSM_DB_EQUAL, Schema::attributeInfo(kSecScriptCodeItemAttr), (sint32)keyUsage);
+ }
Item prefItem;
if (!cursor->next(prefItem))
// (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);
+ if (val) {
+ if (CFGetTypeID(val) == CFBooleanGetTypeID()) {
+ logging = CFBooleanGetValue((CFBooleanRef)val);
+ }
}
CFReleaseNull(val);
}
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);
}
OSStatus
SecIdentitySetPreferred(SecIdentityRef identity, CFStringRef name, CFArrayRef keyUsage)
{
+ COUNTLEGACYAPI
CSSM_KEYUSE keyUse = ConvertArrayToKeyUsage(keyUsage);
return SecIdentitySetPreference(identity, name, keyUse);
}
-OSStatus
-SecIdentityFindPreferenceItem(
- CFTypeRef keychainOrArray,
- CFStringRef idString,
- SecKeychainItemRef *itemRef)
-{
- BEGIN_SECAPI
-
- StorageManager::KeychainList keychains;
- globals().storageManager.optionalSearchList(keychainOrArray, keychains);
- KCCursor cursor(keychains, kSecGenericPasswordItemClass, NULL);
-
- char idUTF8[MAXPATHLEN];
- idUTF8[0] = (char)'\0';
- if (idString)
- {
- if (!CFStringGetCString(idString, idUTF8, sizeof(idUTF8)-1, kCFStringEncodingUTF8))
- idUTF8[0] = (char)'\0';
- }
- size_t idUTF8Len = strlen(idUTF8);
- if (!idUTF8Len)
- MacOSError::throwMe(errSecParam);
-
- CssmData service(const_cast<char *>(idUTF8), idUTF8Len);
- cursor->add(CSSM_DB_EQUAL, Schema::attributeInfo(kSecServiceItemAttr), service);
- cursor->add(CSSM_DB_EQUAL, Schema::attributeInfo(kSecTypeItemAttr), (FourCharCode)'iprf');
-
- Item item;
- if (!cursor->next(item))
- MacOSError::throwMe(errSecItemNotFound);
-
- if (itemRef)
- *itemRef=item->handle();
-
- END_SECAPI
-}
-
OSStatus
SecIdentityFindPreferenceItemWithNameAndKeyUsage(
CFTypeRef keychainOrArray,
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);
CssmData service(const_cast<char *>(idUTF8), idUTF8Len);
cursor->add(CSSM_DB_EQUAL, Schema::attributeInfo(kSecServiceItemAttr), service);
cursor->add(CSSM_DB_EQUAL, Schema::attributeInfo(kSecTypeItemAttr), (FourCharCode)'iprf');
- if (keyUsage)
+ if (keyUsage) {
cursor->add(CSSM_DB_EQUAL, Schema::attributeInfo(kSecScriptCodeItemAttr), (sint32)keyUsage);
+ }
Item item;
if (!cursor->next(item))
CFStringRef name,
int32_t keyUsage)
{
+ COUNTLEGACYAPI
// when a specific key usage is passed, we'll only match & delete that pref;
// when a key usage of 0 is passed, all matching prefs should be deleted.
// maxUsages represents the most matches there could theoretically be, so
return (status == errSecItemNotFound) ? errSecSuccess : status;
}
-
-static
-OSStatus _SecIdentityAddPreferenceItemWithName(
- SecKeychainRef keychainRef,
- SecIdentityRef identityRef,
- CFStringRef idString,
- SecKeychainItemRef *itemRef)
-{
- // this is NOT exported, and called only from SecIdentityAddPreferenceItem (below), so no BEGIN/END macros here;
- // caller must handle exceptions
-
- if (!identityRef || !idString)
- return errSecParam;
- SecPointer<Certificate> cert(Identity::required(identityRef)->certificate());
- Item item(kSecGenericPasswordItemClass, 'aapl', 0, NULL, false);
- sint32 keyUsage = 0;
-
- // determine the account attribute
- //
- // This attribute must be synthesized from certificate label + pref item type + key usage,
- // as only the account and service attributes can make a generic keychain item unique.
- // For 'iprf' type items (but not 'cprf'), we append a trailing space. This insures that
- // we can save a certificate preference if an identity preference already exists for the
- // given service name, and vice-versa.
- // If the key usage is 0 (i.e. the normal case), we omit the appended key usage string.
- //
- CFStringRef labelStr = nil;
- cert->inferLabel(false, &labelStr);
- if (!labelStr) {
- return errSecDataTooLarge; // data is "in a format which cannot be displayed"
- }
- CFIndex accountUTF8Len = CFStringGetMaximumSizeForEncoding(CFStringGetLength(labelStr), kCFStringEncodingUTF8) + 1;
- 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))
- 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));
- CFRelease(labelStr);
-
- // service attribute (name provided by the caller)
- CFIndex serviceUTF8Len = CFStringGetMaximumSizeForEncoding(CFStringGetLength(idString), kCFStringEncodingUTF8) + 1;;
- char serviceUTF8[serviceUTF8Len];
- if (!CFStringGetCString(idString, serviceUTF8, serviceUTF8Len-1, kCFStringEncodingUTF8))
- serviceUTF8[0] = (char)'\0';
- CssmData service(const_cast<char *>(serviceUTF8), strlen(serviceUTF8));
-
- // set item attribute values
- item->setAttribute(Schema::attributeInfo(kSecServiceItemAttr), service);
- item->setAttribute(Schema::attributeInfo(kSecLabelItemAttr), service);
- item->setAttribute(Schema::attributeInfo(kSecTypeItemAttr), (FourCharCode)'iprf');
- item->setAttribute(Schema::attributeInfo(kSecAccountItemAttr), account);
- item->setAttribute(Schema::attributeInfo(kSecScriptCodeItemAttr), keyUsage);
-
- // generic attribute (store persistent certificate reference)
- CFDataRef pItemRef = nil;
- OSStatus status = SecKeychainItemCreatePersistentReference((SecKeychainItemRef)cert->handle(), &pItemRef);
- if (!pItemRef)
- status = errSecInvalidItemRef;
- if (status)
- return status;
- const UInt8 *dataPtr = CFDataGetBytePtr(pItemRef);
- CFIndex dataLen = CFDataGetLength(pItemRef);
- CssmData pref(const_cast<void *>(reinterpret_cast<const void *>(dataPtr)), dataLen);
- item->setAttribute(Schema::attributeInfo(kSecGenericItemAttr), pref);
- CFRelease(pItemRef);
-
- Keychain keychain = nil;
- try {
- keychain = Keychain::optional(keychainRef);
- if (!keychain->exists())
- MacOSError::throwMe(errSecNoSuchKeychain); // Might be deleted or not available at this time.
- }
- catch(...) {
- keychain = globals().storageManager.defaultKeychainUI(item);
- }
-
- try {
- keychain->add(item);
- }
- catch (const MacOSError &err) {
- if (err.osStatus() != errSecDuplicateItem)
- throw; // if item already exists, fall through to update
- }
-
- item->update();
-
- if (itemRef)
- *itemRef = item->handle();
-
- return status;
-}
-
-OSStatus SecIdentityAddPreferenceItem(
- SecKeychainRef keychainRef,
- SecIdentityRef identityRef,
- CFStringRef idString,
- SecKeychainItemRef *itemRef)
-{
- // The original implementation of SecIdentityAddPreferenceItem adds the exact string only.
- // That implementation has been moved to _SecIdentityAddPreferenceItemWithName (above),
- // and this function is a wrapper which calls it, so that existing clients will get the
- // extended behavior of server domain matching for items that specify URLs.
- // (Note that behavior is unchanged if the specified idString is not a URL.)
-
- BEGIN_SECAPI
-
- OSStatus status = errSecInternalComponent;
- CFArrayRef names = _SecIdentityCopyPossiblePaths(idString);
- if (!names) {
- return status;
- }
-
- CFIndex total = CFArrayGetCount(names);
- if (total > 0) {
- // add item for name (first element in array)
- CFStringRef aName = (CFStringRef)CFArrayGetValueAtIndex(names, 0);
- try {
- status = _SecIdentityAddPreferenceItemWithName(keychainRef, identityRef, aName, itemRef);
- }
- catch (const MacOSError &err) { status=err.osStatus(); }
- catch (const CommonError &err) { status=SecKeychainErrFromOSStatus(err.osStatus()); }
- catch (const std::bad_alloc &) { status=errSecAllocate; }
- catch (...) { status=errSecInternalComponent; }
- }
- if (total > 2) {
- Boolean setDomainDefaultIdentity = FALSE;
- CFTypeRef val = (CFTypeRef)CFPreferencesCopyValue(CFSTR("SetDomainDefaultIdentity"),
- CFSTR("com.apple.security.identities"),
- kCFPreferencesCurrentUser,
- kCFPreferencesAnyHost);
- if (val) {
- if (CFGetTypeID(val) == CFBooleanGetTypeID())
- setDomainDefaultIdentity = CFBooleanGetValue((CFBooleanRef)val) ? TRUE : FALSE;
- CFRelease(val);
- }
- if (setDomainDefaultIdentity) {
- // add item for domain (second-to-last element in array, e.g. "*.apple.com")
- OSStatus tmpStatus = errSecSuccess;
- CFStringRef aName = (CFStringRef)CFArrayGetValueAtIndex(names, total-2);
- try {
- tmpStatus = _SecIdentityAddPreferenceItemWithName(keychainRef, identityRef, aName, itemRef);
- }
- catch (const MacOSError &err) { tmpStatus=err.osStatus(); }
- catch (const CommonError &err) { tmpStatus=SecKeychainErrFromOSStatus(err.osStatus()); }
- catch (const std::bad_alloc &) { tmpStatus=errSecAllocate; }
- catch (...) { tmpStatus=errSecInternalComponent; }
- }
- }
-
- CFRelease(names);
- return status;
-
- END_SECAPI
-}
-
-/* deprecated in 10.5 */
-OSStatus SecIdentityUpdatePreferenceItem(
- SecKeychainItemRef itemRef,
- SecIdentityRef identityRef)
-{
- BEGIN_SECAPI
-
- if (!itemRef || !identityRef)
- MacOSError::throwMe(errSecParam);
- SecPointer<Certificate> certificate(Identity::required(identityRef)->certificate());
- Item prefItem = ItemImpl::required(itemRef);
-
- // get the current key usage value for this item
- sint32 keyUsage = 0;
- UInt32 actLen = 0;
- SecKeychainAttribute attr = { kSecScriptCodeItemAttr, sizeof(sint32), &keyUsage };
- try {
- prefItem->getAttribute(attr, &actLen);
- }
- catch(...) {
- keyUsage = 0;
- };
-
- // set the account attribute
- //
- // This attribute must be synthesized from certificate label + pref item type + key usage,
- // as only the account and service attributes can make a generic keychain item unique.
- // For 'iprf' type items (but not 'cprf'), we append a trailing space. This insures that
- // we can save a certificate preference if an identity preference already exists for the
- // given service name, and vice-versa.
- // 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);
- if (!labelStr) {
- MacOSError::throwMe(errSecDataTooLarge); // data is "in a format which cannot be displayed"
- }
- CFIndex accountUTF8Len = CFStringGetMaximumSizeForEncoding(CFStringGetLength(labelStr), kCFStringEncodingUTF8) + 1;
- 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))
- 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));
- prefItem->setAttribute(Schema::attributeInfo(kSecAccountItemAttr), account);
- CFRelease(labelStr);
-
- // generic attribute (store persistent certificate reference)
- CFDataRef pItemRef = nil;
- OSStatus status = SecKeychainItemCreatePersistentReference((SecKeychainItemRef)certificate->handle(), &pItemRef);
- if (!pItemRef)
- status = errSecInvalidItemRef;
- if (status)
- MacOSError::throwMe(status);
- const UInt8 *dataPtr = CFDataGetBytePtr(pItemRef);
- CFIndex dataLen = CFDataGetLength(pItemRef);
- CssmData pref(const_cast<void *>(reinterpret_cast<const void *>(dataPtr)), dataLen);
- prefItem->setAttribute(Schema::attributeInfo(kSecGenericItemAttr), pref);
- CFRelease(pItemRef);
-
- prefItem->update();
-
- END_SECAPI
-}
-
-OSStatus SecIdentityCopyFromPreferenceItem(
- SecKeychainItemRef itemRef,
- SecIdentityRef *identityRef)
-{
- BEGIN_SECAPI
-
- if (!itemRef || !identityRef)
- MacOSError::throwMe(errSecParam);
- Item prefItem = ItemImpl::required(itemRef);
-
- // get persistent certificate reference
- SecKeychainAttribute itemAttrs[] = { { kSecGenericItemAttr, 0, NULL } };
- SecKeychainAttributeList itemAttrList = { sizeof(itemAttrs) / sizeof(itemAttrs[0]), itemAttrs };
- prefItem->getContent(NULL, &itemAttrList, NULL, NULL);
-
- // find certificate, given persistent reference data
- CFDataRef pItemRef = CFDataCreateWithBytesNoCopy(NULL, (const UInt8 *)itemAttrs[0].data, itemAttrs[0].length, kCFAllocatorNull);
- SecKeychainItemRef certItemRef = nil;
- OSStatus status = SecKeychainItemCopyFromPersistentReference(pItemRef, &certItemRef); //%%% need to make this a method of ItemImpl
- prefItem->freeContent(&itemAttrList, NULL);
- if (pItemRef)
- CFRelease(pItemRef);
- if (status)
- return status;
-
- // create identity reference, given certificate
- StorageManager::KeychainList keychains;
- globals().storageManager.optionalSearchList((CFTypeRef)NULL, keychains);
- Item certItem = ItemImpl::required(SecKeychainItemRef(certItemRef));
- SecPointer<Certificate> certificate(static_cast<Certificate *>(certItem.get()));
- SecPointer<Identity> identity(new Identity(keychains, certificate));
- if (certItemRef)
- CFRelease(certItemRef);
-
- Required(identityRef) = identity->handle();
-
- END_SECAPI
-}
-
/*
* System Identity Support.
*/
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;
+ unique_ptr<Dictionary> identDict;
/* get top-level dictionary - if not present, we're done */
Dictionary* d = Dictionary::CreateDictionary(IDENTITY_DOMAIN, Dictionary::US_System);
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) {
MacOSError::throwMe(errSecAuthFailed);
}
- auto_ptr<MutableDictionary> identDict;
+ unique_ptr<MutableDictionary> identDict;
MutableDictionary *d = MutableDictionary::CreateMutableDictionary(IDENTITY_DOMAIN, Dictionary::US_System);
if (d)
{