CFDataRef SecFDERecoveryUnwrapCRSKWithPrivKey(SecKeychainRef keychain, const FVPrivateKeyHeader *inHeader)
{
	CFDataRef result = NULL;
	OSStatus __secapiresult = 0;

	try
	{
		result = decodePrivateKeyHeader(keychain, Required(inHeader));
	}
	catch (const MacOSError &err) { __secapiresult=err.osStatus(); }
	catch (const CommonError &err) { __secapiresult=SecKeychainErrFromOSStatus(err.osStatus()); }
	catch (const std::bad_alloc &) { __secapiresult=errSecAllocate; }
	catch (...) { __secapiresult=errSecInternalComponent; }
	secinfo("FDERecovery", "SecFDERecoveryUnwrapCRSKWithPrivKey: %d", (int)__secapiresult);
	return result;
}
/* new in 10.6 */
size_t
SecKeyGetBlockSize(SecKeyRef key)
{
	size_t blockSize = 0;
    OSStatus __secapiresult;
	try {
		CSSM_KEY cssmKey = KeyItem::required(key)->key();
		blockSize = cssmKey.KeyHeader.LogicalKeySizeInBits;

		__secapiresult=noErr;
	}
	catch (const MacOSError &err) { __secapiresult=err.osStatus(); }
	catch (const CommonError &err) { __secapiresult=SecKeychainErrFromOSStatus(err.osStatus()); }
	catch (const std::bad_alloc &) { __secapiresult=memFullErr; }
	catch (...) { __secapiresult=internalComponentErr; }
	return blockSize;
}
/* Create a key from supplied data and parameters */
SecKeyRef
SecKeyCreate(CFAllocatorRef allocator,
    const SecKeyDescriptor *keyClass,
	const uint8_t *keyData,
	CFIndex keyDataLength,
	SecKeyEncoding encoding)
{
	SecKeyRef keyRef = NULL;
    OSStatus __secapiresult;
	try {
		//FIXME: needs implementation

		__secapiresult=noErr;
	}
	catch (const MacOSError &err) { __secapiresult=err.osStatus(); }
	catch (const CommonError &err) { __secapiresult=SecKeychainErrFromOSStatus(err.osStatus()); }
	catch (const std::bad_alloc &) { __secapiresult=memFullErr; }
	catch (...) { __secapiresult=internalComponentErr; }
	return keyRef;
}
SecIdentityRef
SecIdentityCreate(
	CFAllocatorRef allocator,
	SecCertificateRef certificate,
	SecKeyRef privateKey)
{
	SecIdentityRef identityRef = NULL;
    OSStatus __secapiresult;
	try {
		SecPointer<Certificate> certificatePtr(Certificate::required(certificate));
		SecPointer<KeyItem> keyItemPtr(KeyItem::required(privateKey));
		SecPointer<Identity> identityPtr(new Identity(keyItemPtr, certificatePtr));
		identityRef = identityPtr->handle();

		__secapiresult=errSecSuccess;
	}
	catch (const MacOSError &err) { __secapiresult=err.osStatus(); }
	catch (const CommonError &err) { __secapiresult=SecKeychainErrFromOSStatus(err.osStatus()); }
	catch (const std::bad_alloc &) { __secapiresult=errSecAllocate; }
	catch (...) { __secapiresult=errSecInternalComponent; }
	return identityRef;
}
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
}