]> git.saurik.com Git - apple/security.git/blobdiff - Security/libsecurity_keychain/lib/SecKey.cpp
Security-57336.1.9.tar.gz
[apple/security.git] / Security / libsecurity_keychain / lib / SecKey.cpp
diff --git a/Security/libsecurity_keychain/lib/SecKey.cpp b/Security/libsecurity_keychain/lib/SecKey.cpp
deleted file mode 100644 (file)
index d11deeb..0000000
+++ /dev/null
@@ -1,2266 +0,0 @@
-/*
- * Copyright (c) 2002-2014 Apple Inc. All Rights Reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- * 
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this
- * file.
- * 
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- * 
- * @APPLE_LICENSE_HEADER_END@
- */
-
-#include "SecKey.h"
-#include "SecKeyPriv.h"
-#include "SecItem.h"
-#include "SecItemPriv.h"
-#include <libDER/asn1Types.h>
-#include <libDER/DER_Encode.h>
-#include <libDER/DER_Decode.h>
-#include <libDER/DER_Keys.h>
-#include <Security/SecAsn1Types.h>
-#include <Security/SecAsn1Coder.h>
-#include <security_keychain/KeyItem.h>
-#include <CommonCrypto/CommonKeyDerivation.h>
-
-#include "SecBridge.h"
-
-#include <security_keychain/Access.h>
-#include <security_keychain/Keychains.h>
-#include <security_keychain/KeyItem.h>
-#include <string.h>
-#include <syslog.h>
-
-#include <security_cdsa_utils/cuCdsaUtils.h>
-#include <security_cdsa_client/wrapkey.h>
-
-#include "SecImportExportCrypto.h"
-
-CFTypeID
-SecKeyGetTypeID(void)
-{
-       BEGIN_SECAPI
-
-       return gTypes().KeyItem.typeID;
-
-       END_SECAPI1(_kCFRuntimeNotATypeID)
-}
-
-static OSStatus SecKeyCreatePairInternal(
-       SecKeychainRef keychainRef,
-       CSSM_ALGORITHMS algorithm,
-       uint32 keySizeInBits,
-       CSSM_CC_HANDLE contextHandle,
-       CSSM_KEYUSE publicKeyUsage,
-       uint32 publicKeyAttr,
-       CSSM_KEYUSE privateKeyUsage,
-       uint32 privateKeyAttr,
-       SecAccessRef initialAccess,
-       SecKeyRef* publicKeyRef,
-       SecKeyRef* privateKeyRef)
-{
-       BEGIN_SECAPI
-
-       Keychain keychain = Keychain::optional(keychainRef);
-       SecPointer<Access> theAccess(initialAccess ? Access::required(initialAccess) : new Access("<key>"));
-       SecPointer<KeyItem> pubItem, privItem;
-
-    Mutex *keychainMutex = keychain->getKeychainMutex();
-    StLock<Mutex> _(*keychainMutex);
-    
-       KeyItem::createPair(keychain,
-        algorithm,
-        keySizeInBits,
-        contextHandle,
-        publicKeyUsage,
-        publicKeyAttr,
-        privateKeyUsage,
-        privateKeyAttr,
-        theAccess,
-        pubItem,
-        privItem);
-
-       // Return the generated keys.
-       if (publicKeyRef)
-               *publicKeyRef = pubItem->handle();
-       if (privateKeyRef)
-               *privateKeyRef = privItem->handle();
-
-       END_SECAPI
-}
-
-OSStatus
-SecKeyCreatePair(
-       SecKeychainRef keychainRef,
-       CSSM_ALGORITHMS algorithm,
-       uint32 keySizeInBits,
-       CSSM_CC_HANDLE contextHandle,
-       CSSM_KEYUSE publicKeyUsage,
-       uint32 publicKeyAttr,
-       CSSM_KEYUSE privateKeyUsage,
-       uint32 privateKeyAttr,
-       SecAccessRef initialAccess,
-       SecKeyRef* publicKeyRef,
-       SecKeyRef* privateKeyRef)
-{
-    OSStatus result = SecKeyCreatePairInternal(keychainRef, algorithm, keySizeInBits, contextHandle, publicKeyUsage,
-                                               publicKeyAttr, privateKeyUsage, privateKeyAttr, initialAccess, publicKeyRef, privateKeyRef);
-    
-    return result;
-}
-
-
-
-OSStatus
-SecKeyGetCSSMKey(SecKeyRef key, const CSSM_KEY **cssmKey)
-{
-       BEGIN_SECAPI
-
-       Required(cssmKey) = KeyItem::required(key)->key();
-
-       END_SECAPI
-}
-
-
-//
-// Private APIs
-//
-
-OSStatus
-SecKeyGetCSPHandle(SecKeyRef keyRef, CSSM_CSP_HANDLE *cspHandle)
-{
-    BEGIN_SECAPI
-
-       SecPointer<KeyItem> keyItem(KeyItem::required(keyRef));
-       Required(cspHandle) = keyItem->csp()->handle();
-
-       END_SECAPI
-}
-
-/* deprecated as of 10.8 */
-OSStatus
-SecKeyGetAlgorithmID(SecKeyRef keyRef, const CSSM_X509_ALGORITHM_IDENTIFIER **algid)
-{
-    BEGIN_SECAPI
-
-       SecPointer<KeyItem> keyItem(KeyItem::required(keyRef));
-       Required(algid) = &keyItem->algorithmIdentifier();
-
-       END_SECAPI
-}
-
-/* new for 10.8 */
-CFIndex
-SecKeyGetAlgorithmId(SecKeyRef key)
-{
-       const CSSM_KEY *cssmKey;
-
-       if (SecKeyGetCSSMKey(key, &cssmKey) != errSecSuccess)
-               return kSecNullAlgorithmID;
-
-       switch (cssmKey->KeyHeader.AlgorithmId) {
-               case CSSM_ALGID_RSA:
-                       return kSecRSAAlgorithmID;
-               case CSSM_ALGID_DSA:
-                       return kSecDSAAlgorithmID;
-               case CSSM_ALGID_ECDSA:
-                       return kSecECDSAAlgorithmID;
-               default:
-                       assert(0); /* other algorithms TBA */
-                       return kSecNullAlgorithmID;
-       }
-}
-
-OSStatus
-SecKeyGetStrengthInBits(SecKeyRef keyRef, const CSSM_X509_ALGORITHM_IDENTIFIER *algid, unsigned int *strength)
-{
-    BEGIN_SECAPI
-
-       SecPointer<KeyItem> keyItem(KeyItem::required(keyRef));
-       Required(strength) = keyItem->strengthInBits(algid);
-
-       END_SECAPI
-}
-
-OSStatus
-SecKeyGetCredentials(
-       SecKeyRef keyRef,
-       CSSM_ACL_AUTHORIZATION_TAG operation,
-       SecCredentialType credentialType,
-       const CSSM_ACCESS_CREDENTIALS **outCredentials)
-{
-       BEGIN_SECAPI
-
-       SecPointer<KeyItem> keyItem(KeyItem::required(keyRef));
-       Required(outCredentials) = keyItem->getCredentials(operation, credentialType);
-
-       END_SECAPI
-}
-
-OSStatus
-SecKeyImportPair(
-       SecKeychainRef keychainRef,
-       const CSSM_KEY *publicCssmKey,
-       const CSSM_KEY *privateCssmKey,
-       SecAccessRef initialAccess,
-       SecKeyRef* publicKey,
-       SecKeyRef* privateKey)
-{
-       BEGIN_SECAPI
-
-       Keychain keychain = Keychain::optional(keychainRef);
-       SecPointer<Access> theAccess(initialAccess ? Access::required(initialAccess) : new Access("<key>"));
-       SecPointer<KeyItem> pubItem, privItem;
-
-       KeyItem::importPair(keychain,
-               Required(publicCssmKey),
-               Required(privateCssmKey),
-        theAccess,
-        pubItem,
-        privItem);
-
-       // Return the generated keys.
-       if (publicKey)
-               *publicKey = pubItem->handle();
-       if (privateKey)
-               *privateKey = privItem->handle();
-
-       END_SECAPI
-}
-
-static OSStatus
-SecKeyGenerateWithAttributes(
-       SecKeychainAttributeList* attrList,
-       SecKeychainRef keychainRef,
-       CSSM_ALGORITHMS algorithm,
-       uint32 keySizeInBits,
-       CSSM_CC_HANDLE contextHandle,
-       CSSM_KEYUSE keyUsage,
-       uint32 keyAttr,
-       SecAccessRef initialAccess,
-       SecKeyRef* keyRef)
-{
-       BEGIN_SECAPI
-
-       Keychain keychain;
-       SecPointer<Access> theAccess;
-
-       if (keychainRef)
-               keychain = KeychainImpl::required(keychainRef);
-       if (initialAccess)
-               theAccess = Access::required(initialAccess);
-
-       SecPointer<KeyItem> item = KeyItem::generateWithAttributes(attrList,
-        keychain,
-        algorithm,
-        keySizeInBits,
-        contextHandle,
-        keyUsage,
-        keyAttr,
-        theAccess);
-
-       // Return the generated key.
-       if (keyRef)
-               *keyRef = item->handle();
-
-       END_SECAPI
-}
-
-OSStatus
-SecKeyGenerate(
-       SecKeychainRef keychainRef,
-       CSSM_ALGORITHMS algorithm,
-       uint32 keySizeInBits,
-       CSSM_CC_HANDLE contextHandle,
-       CSSM_KEYUSE keyUsage,
-       uint32 keyAttr,
-       SecAccessRef initialAccess,
-       SecKeyRef* keyRef)
-{
-       return SecKeyGenerateWithAttributes(NULL,
-               keychainRef, algorithm, keySizeInBits,
-               contextHandle, keyUsage, keyAttr,
-               initialAccess, keyRef);
-}
-
-
-/* new in 10.6 */
-/* 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=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 keyRef;
-}
-
-/* new in 10.6 */
-/* Generate a floating key reference from a CSSM_KEY */
-OSStatus
-SecKeyCreateWithCSSMKey(const CSSM_KEY *cssmKey,
-    SecKeyRef *keyRef)
-{
-       BEGIN_SECAPI
-
-       Required(cssmKey);
-    if(cssmKey->KeyData.Length == 0){
-        MacOSError::throwMe(errSecInvalidAttributeKeyLength);
-    }
-    if(cssmKey->KeyData.Data == NULL){
-        MacOSError::throwMe(errSecInvalidPointer);
-    }
-       CssmClient::CSP csp(cssmKey->KeyHeader.CspId);
-       CssmClient::Key key(csp, *cssmKey);
-       KeyItem *item = new KeyItem(key);
-
-       // Return the generated key.
-       if (keyRef)
-               *keyRef = item->handle();
-
-       END_SECAPI
-}
-
-
-
-static u_int32_t ConvertCFStringToInteger(CFStringRef ref)
-{
-       if (ref == NULL)
-       {
-               return 0;
-       }
-
-       // figure out the size of the string
-       CFIndex numChars = CFStringGetMaximumSizeForEncoding(CFStringGetLength(ref), kCFStringEncodingUTF8);
-       char buffer[numChars];
-       if (!CFStringGetCString(ref, buffer, numChars, kCFStringEncodingUTF8))
-       {
-               MacOSError::throwMe(errSecParam);
-       }
-
-       return atoi(buffer);
-}
-
-
-
-static OSStatus CheckAlgorithmType(CFDictionaryRef parameters, CSSM_ALGORITHMS &algorithms)
-{
-       // figure out the algorithm to use
-       CFStringRef ktype = (CFStringRef) CFDictionaryGetValue(parameters, kSecAttrKeyType);
-       if (ktype == NULL)
-       {
-               return errSecParam;
-       }
-
-       if (CFEqual(ktype, kSecAttrKeyTypeRSA)) {
-               algorithms = CSSM_ALGID_RSA;
-               return errSecSuccess;
-       } else if(CFEqual(ktype, kSecAttrKeyTypeECDSA) ||
-                       CFEqual(ktype, kSecAttrKeyTypeEC)) {
-               algorithms = CSSM_ALGID_ECDSA;
-               return errSecSuccess;
-       } else if(CFEqual(ktype, kSecAttrKeyTypeAES)) {
-               algorithms = CSSM_ALGID_AES;
-               return errSecSuccess;
-       } else if(CFEqual(ktype, kSecAttrKeyType3DES)) {
-               algorithms = CSSM_ALGID_3DES;
-               return errSecSuccess;
-       } else {
-               return errSecUnsupportedAlgorithm;
-       }
-}
-
-
-
-static OSStatus GetKeySize(CFDictionaryRef parameters, CSSM_ALGORITHMS algorithms, uint32 &keySizeInBits)
-{
-
-    // get the key size and check it for validity
-    CFTypeRef ref = CFDictionaryGetValue(parameters, kSecAttrKeySizeInBits);
-
-    keySizeInBits = kSecDefaultKeySize;
-
-    CFTypeID bitSizeType = CFGetTypeID(ref);
-    if (bitSizeType == CFStringGetTypeID())
-        keySizeInBits = ConvertCFStringToInteger((CFStringRef) ref);
-    else if (bitSizeType == CFNumberGetTypeID())
-        CFNumberGetValue((CFNumberRef) ref, kCFNumberSInt32Type, &keySizeInBits);
-    else return errSecParam;
-
-
-    switch (algorithms) {
-    case CSSM_ALGID_ECDSA:
-        if(keySizeInBits == kSecDefaultKeySize) keySizeInBits = kSecp256r1;
-        if(keySizeInBits == kSecp192r1 || keySizeInBits == kSecp256r1 || keySizeInBits == kSecp384r1 || keySizeInBits == kSecp521r1 ) return errSecSuccess;
-        break;
-    case CSSM_ALGID_RSA:
-                         if(keySizeInBits % 8) return errSecParam;
-        if(keySizeInBits == kSecDefaultKeySize) keySizeInBits = 2048;
-        if(keySizeInBits >= kSecRSAMin && keySizeInBits <= kSecRSAMax) return errSecSuccess;
-        break;
-    case CSSM_ALGID_AES:
-        if(keySizeInBits == kSecDefaultKeySize) keySizeInBits = kSecAES128;
-        if(keySizeInBits == kSecAES128 || keySizeInBits == kSecAES192 || keySizeInBits == kSecAES256) return errSecSuccess;
-        break;
-    case CSSM_ALGID_3DES:
-        if(keySizeInBits == kSecDefaultKeySize) keySizeInBits = kSec3DES192;
-        if(keySizeInBits == kSec3DES192) return errSecSuccess;
-        break;
-    default:
-        break;
-    }
-    return errSecParam;
-}
-
-
-
-enum AttributeType
-{
-       kStringType,
-       kBooleanType,
-       kIntegerType
-};
-
-
-
-struct ParameterAttribute
-{
-       const CFTypeRef *name;
-       AttributeType type;
-};
-
-
-
-static ParameterAttribute gAttributes[] =
-{
-       {
-               &kSecAttrLabel,
-               kStringType
-       },
-       {
-               &kSecAttrIsPermanent,
-               kBooleanType
-       },
-       {
-               &kSecAttrApplicationTag,
-               kStringType
-       },
-       {
-               &kSecAttrEffectiveKeySize,
-               kBooleanType
-       },
-       {
-               &kSecAttrCanEncrypt,
-               kBooleanType
-       },
-       {
-               &kSecAttrCanDecrypt,
-               kBooleanType
-       },
-       {
-               &kSecAttrCanDerive,
-               kBooleanType
-       },
-       {
-               &kSecAttrCanSign,
-               kBooleanType
-       },
-       {
-               &kSecAttrCanVerify,
-               kBooleanType
-       },
-       {
-               &kSecAttrCanUnwrap,
-               kBooleanType
-       }
-};
-
-const int kNumberOfAttributes = sizeof(gAttributes) / sizeof(ParameterAttribute);
-
-static OSStatus ScanDictionaryForParameters(CFDictionaryRef parameters, void* attributePointers[])
-{
-       int i;
-       for (i = 0; i < kNumberOfAttributes; ++i)
-       {
-               // see if the corresponding tag exists in the dictionary
-               CFTypeRef value = CFDictionaryGetValue(parameters, *(gAttributes[i].name));
-               if (value != NULL)
-               {
-                       switch (gAttributes[i].type)
-                       {
-                               case kStringType:
-                                       // just return the value
-                                       *(CFTypeRef*) attributePointers[i] = value;
-                               break;
-
-                               case kBooleanType:
-                               {
-                                       CFBooleanRef bRef = (CFBooleanRef) value;
-                                       *(bool*) attributePointers[i] = CFBooleanGetValue(bRef);
-                               }
-                               break;
-
-                               case kIntegerType:
-                               {
-                                       CFNumberRef nRef = (CFNumberRef) value;
-                                       CFNumberGetValue(nRef, kCFNumberSInt32Type, attributePointers[i]);
-                               }
-                               break;
-                       }
-               }
-       }
-
-       return errSecSuccess;
-}
-
-
-
-static OSStatus GetKeyParameters(CFDictionaryRef parameters, int keySize, bool isPublic, CSSM_KEYUSE &keyUse, uint32 &attrs, CFTypeRef &labelRef, CFDataRef &applicationTagRef)
-{
-       // establish default values
-       labelRef = NULL;
-       bool isPermanent = false;
-       applicationTagRef = NULL;
-       CFTypeRef effectiveKeySize = NULL;
-       bool canDecrypt = isPublic ? false : true;
-       bool canEncrypt = !canDecrypt;
-       bool canDerive = true;
-       bool canSign = isPublic ? false : true;
-       bool canVerify = !canSign;
-       bool canUnwrap = isPublic ? false : true;
-       attrs = CSSM_KEYATTR_EXTRACTABLE;
-       keyUse = 0;
-
-       void* attributePointers[] = {&labelRef, &isPermanent, &applicationTagRef, &effectiveKeySize, &canEncrypt, &canDecrypt,
-                                                                &canDerive, &canSign, &canVerify, &canUnwrap};
-
-       // look for modifiers in the general dictionary
-       OSStatus result = ScanDictionaryForParameters(parameters, attributePointers);
-       if (result != errSecSuccess)
-       {
-               return result;
-       }
-
-       // see if we have anything which modifies the defaults
-       CFTypeRef key;
-       if (isPublic)
-       {
-               key = kSecPublicKeyAttrs;
-       }
-       else
-       {
-               key = kSecPrivateKeyAttrs;
-       }
-
-       CFTypeRef dType = CFDictionaryGetValue(parameters, key);
-       if (dType != NULL)
-       {
-               // this had better be a dictionary
-               if (CFGetTypeID(dType) != CFDictionaryGetTypeID())
-               {
-                       return errSecParam;
-               }
-
-               // pull any additional parameters out of this dictionary
-               result = ScanDictionaryForParameters((CFDictionaryRef)dType, attributePointers);
-               if (result != errSecSuccess)
-               {
-                       return result;
-               }
-       }
-
-       // figure out the key usage
-       keyUse = 0;
-       if (canDecrypt)
-       {
-               keyUse |= CSSM_KEYUSE_DECRYPT;
-       }
-
-       if (canEncrypt)
-       {
-               keyUse |= CSSM_KEYUSE_ENCRYPT;
-       }
-
-       if (canDerive)
-       {
-               keyUse |= CSSM_KEYUSE_DERIVE;
-       }
-
-       if (canSign)
-       {
-               keyUse |= CSSM_KEYUSE_SIGN;
-       }
-
-       if (canVerify)
-       {
-               keyUse |= CSSM_KEYUSE_VERIFY;
-       }
-
-       if (canUnwrap)
-       {
-               keyUse |= CSSM_KEYUSE_UNWRAP;
-       }
-
-       // public key is always extractable;
-       // private key is extractable by default unless explicitly set to false
-       CFTypeRef value = NULL;
-       if (!isPublic && CFDictionaryGetValueIfPresent(parameters, kSecAttrIsExtractable, (const void **)&value) && value)
-       {
-               Boolean keyIsExtractable = CFEqual(kCFBooleanTrue, value);
-               if (!keyIsExtractable)
-                       attrs = 0;
-       }
-
-       attrs |= CSSM_KEYATTR_PERMANENT;
-
-       return errSecSuccess;
-}
-
-
-
-static OSStatus MakeKeyGenParametersFromDictionary(CFDictionaryRef parameters,
-                                                                                                  CSSM_ALGORITHMS &algorithms,
-                                                                                                  uint32 &keySizeInBits,
-                                                                                                  CSSM_KEYUSE &publicKeyUse,
-                                                                                                  uint32 &publicKeyAttr,
-                                                                                                  CFTypeRef &publicKeyLabelRef,
-                                                                                                  CFDataRef &publicKeyAttributeTagRef,
-                                                                                                  CSSM_KEYUSE &privateKeyUse,
-                                                                                                  uint32 &privateKeyAttr,
-                                                                                                  CFTypeRef &privateKeyLabelRef,
-                                                                                                  CFDataRef &privateKeyAttributeTagRef,
-                                                                                                  SecAccessRef &initialAccess)
-{
-       OSStatus result;
-
-       result = CheckAlgorithmType(parameters, algorithms);
-       if (result != errSecSuccess)
-       {
-               return result;
-       }
-
-       result = GetKeySize(parameters, algorithms, keySizeInBits);
-       if (result != errSecSuccess)
-       {
-               return result;
-       }
-
-       result = GetKeyParameters(parameters, keySizeInBits, false, privateKeyUse, privateKeyAttr, privateKeyLabelRef, privateKeyAttributeTagRef);
-       if (result != errSecSuccess)
-       {
-               return result;
-       }
-
-       result = GetKeyParameters(parameters, keySizeInBits, true, publicKeyUse, publicKeyAttr, publicKeyLabelRef, publicKeyAttributeTagRef);
-       if (result != errSecSuccess)
-       {
-               return result;
-       }
-
-       if (!CFDictionaryGetValueIfPresent(parameters, kSecAttrAccess, (const void **)&initialAccess))
-       {
-               initialAccess = NULL;
-       }
-       else if (SecAccessGetTypeID() != CFGetTypeID(initialAccess))
-       {
-               return errSecParam;
-       }
-
-       return errSecSuccess;
-}
-
-
-
-static OSStatus SetKeyLabelAndTag(SecKeyRef keyRef, CFTypeRef label, CFDataRef tag)
-{
-       int numToModify = 0;
-       if (label != NULL)
-       {
-               numToModify += 1;
-       }
-
-       if (tag != NULL)
-       {
-               numToModify += 1;
-       }
-
-       if (numToModify == 0)
-       {
-               return errSecSuccess;
-       }
-
-       SecKeychainAttributeList attrList;
-       SecKeychainAttribute attributes[numToModify];
-
-       int i = 0;
-
-       if (label != NULL)
-       {
-               if (CFStringGetTypeID() == CFGetTypeID(label)) {
-                       CFStringRef label_string = static_cast<CFStringRef>(label);
-                       attributes[i].tag = kSecKeyPrintName;
-                       attributes[i].data = (void*) CFStringGetCStringPtr(label_string, kCFStringEncodingUTF8);
-                       if (NULL == attributes[i].data) {
-                               CFIndex buffer_length = CFStringGetMaximumSizeForEncoding(CFStringGetLength(label_string), kCFStringEncodingUTF8);
-                               attributes[i].data = alloca((size_t)buffer_length);
-                               if (NULL == attributes[i].data) {
-                                       UnixError::throwMe(ENOMEM);
-                               }
-                               if (!CFStringGetCString(label_string, static_cast<char *>(attributes[i].data), buffer_length, kCFStringEncodingUTF8)) {
-                                       MacOSError::throwMe(errSecParam);
-                               }
-                       }
-                       attributes[i].length = (UInt32)strlen(static_cast<char *>(attributes[i].data));
-               } else if (CFDataGetTypeID() == CFGetTypeID(label)) {
-                       // 10.6 bug compatibility
-                       CFDataRef label_data = static_cast<CFDataRef>(label);
-                       attributes[i].tag = kSecKeyLabel;
-                       attributes[i].data = (void*) CFDataGetBytePtr(label_data);
-                       attributes[i].length = (UInt32)CFDataGetLength(label_data);
-               } else {
-                       MacOSError::throwMe(errSecParam);
-               }
-               i++;
-       }
-
-       if (tag != NULL)
-       {
-               attributes[i].tag = kSecKeyApplicationTag;
-               attributes[i].data = (void*) CFDataGetBytePtr(tag);
-               attributes[i].length = (UInt32)CFDataGetLength(tag);
-               i++;
-       }
-
-       attrList.count = numToModify;
-       attrList.attr = attributes;
-
-       return SecKeychainItemModifyAttributesAndData((SecKeychainItemRef) keyRef, &attrList, 0, NULL);
-}
-
-
-
-/* new in 10.6 */
-/* Generate a private/public keypair. */
-OSStatus
-SecKeyGeneratePair(
-       CFDictionaryRef parameters,
-       SecKeyRef *publicKey,
-       SecKeyRef *privateKey)
-{
-       BEGIN_SECAPI
-
-       Required(parameters);
-       Required(publicKey);
-       Required(privateKey);
-
-       CSSM_ALGORITHMS algorithms;
-       uint32 keySizeInBits;
-       CSSM_KEYUSE publicKeyUse;
-       uint32 publicKeyAttr;
-       CFTypeRef publicKeyLabelRef;
-       CFDataRef publicKeyAttributeTagRef;
-       CSSM_KEYUSE privateKeyUse;
-       uint32 privateKeyAttr;
-       CFTypeRef privateKeyLabelRef;
-       CFDataRef privateKeyAttributeTagRef;
-       SecAccessRef initialAccess;
-       SecKeychainRef keychain;
-
-       OSStatus result = MakeKeyGenParametersFromDictionary(parameters, algorithms, keySizeInBits, publicKeyUse, publicKeyAttr, publicKeyLabelRef,
-                                                                                                                publicKeyAttributeTagRef, privateKeyUse, privateKeyAttr, privateKeyLabelRef, privateKeyAttributeTagRef,
-                                                                                                                initialAccess);
-
-       if (result != errSecSuccess)
-       {
-               return result;
-       }
-
-       // verify keychain parameter
-       keychain = NULL;
-       if (!CFDictionaryGetValueIfPresent(parameters, kSecUseKeychain, (const void **)&keychain))
-               keychain = NULL;
-       else if (SecKeychainGetTypeID() != CFGetTypeID(keychain))
-               keychain = NULL;
-
-       // do the key generation
-       result = SecKeyCreatePair(keychain, algorithms, keySizeInBits, 0, publicKeyUse, publicKeyAttr, privateKeyUse, privateKeyAttr, initialAccess, publicKey, privateKey);
-       if (result != errSecSuccess)
-       {
-               return result;
-       }
-
-       // set the label and print attributes on the keys
-       SetKeyLabelAndTag(*publicKey, publicKeyLabelRef, publicKeyAttributeTagRef);
-       SetKeyLabelAndTag(*privateKey, privateKeyLabelRef, privateKeyAttributeTagRef);
-       return result;
-
-       END_SECAPI
-}
-
-/* new in 10.6 */
-OSStatus
-SecKeyRawSign(
-    SecKeyRef           key,
-       SecPadding          padding,
-       const uint8_t       *dataToSign,
-       size_t              dataToSignLen,
-       uint8_t             *sig,
-       size_t              *sigLen)
-{
-       BEGIN_SECAPI
-
-       Required(key);
-       SecPointer<KeyItem> keyItem(KeyItem::required(key));
-       CSSM_DATA dataInput;
-
-       dataInput.Data = (uint8_t*) dataToSign;
-       dataInput.Length = dataToSignLen;
-
-       CSSM_DATA output;
-       output.Data = sig;
-       output.Length = *sigLen;
-
-       const AccessCredentials* credentials = keyItem->getCredentials(CSSM_ACL_AUTHORIZATION_SIGN, kSecCredentialTypeDefault);
-
-       keyItem->RawSign(padding, dataInput, credentials, output);
-       *sigLen = output.Length;
-
-       END_SECAPI
-}
-
-OSStatus SecKeyRawVerifyOSX(
-    SecKeyRef           key,            /* Public key */
-       SecPadding          padding,            /* kSecPaddingNone or kSecPaddingPKCS1 */
-       const uint8_t       *signedData,        /* signature over this data */
-       size_t              signedDataLen,      /* length of dataToSign */
-       const uint8_t       *sig,                       /* signature */
-       size_t              sigLen)
-{
-    return SecKeyRawVerify(key,padding,signedData,signedDataLen,sig,sigLen);
-}
-
-/* new in 10.6 */
-OSStatus
-SecKeyRawVerify(
-    SecKeyRef           key,
-       SecPadding          padding,
-       const uint8_t       *signedData,
-       size_t              signedDataLen,
-       const uint8_t       *sig,
-       size_t              sigLen)
-{
-       BEGIN_SECAPI
-
-       Required(key);
-
-       SecPointer<KeyItem> keyItem(KeyItem::required(key));
-       CSSM_DATA dataInput;
-
-       dataInput.Data = (uint8_t*) signedData;
-       dataInput.Length = signedDataLen;
-
-       CSSM_DATA signature;
-       signature.Data = (uint8_t*) sig;
-       signature.Length = sigLen;
-
-       const AccessCredentials* credentials = keyItem->getCredentials(CSSM_ACL_AUTHORIZATION_ANY, kSecCredentialTypeDefault);
-
-       keyItem->RawVerify(padding, dataInput, credentials, signature);
-
-       END_SECAPI
-}
-
-/* new in 10.6 */
-OSStatus
-SecKeyEncrypt(
-    SecKeyRef           key,
-       SecPadding          padding,
-       const uint8_t           *plainText,
-       size_t              plainTextLen,
-       uint8_t             *cipherText,
-       size_t              *cipherTextLen)
-{
-       BEGIN_SECAPI
-
-       SecPointer<KeyItem> keyItem(KeyItem::required(key));
-       CSSM_DATA inData, outData;
-       inData.Data = (uint8*) plainText;
-       inData.Length = plainTextLen;
-       outData.Data = cipherText;
-       outData.Length = *cipherTextLen;
-
-       const AccessCredentials* credentials = keyItem->getCredentials(CSSM_ACL_AUTHORIZATION_ENCRYPT, kSecCredentialTypeDefault);
-
-       keyItem->Encrypt(padding, inData, credentials, outData);
-       *cipherTextLen = outData.Length;
-
-       END_SECAPI
-}
-
-/* new in 10.6 */
-OSStatus
-SecKeyDecrypt(
-    SecKeyRef           key,                /* Private key */
-       SecPadding          padding,                    /* kSecPaddingNone, kSecPaddingPKCS1, kSecPaddingOAEP */
-       const uint8_t       *cipherText,
-       size_t              cipherTextLen,              /* length of cipherText */
-       uint8_t             *plainText,
-       size_t              *plainTextLen)              /* IN/OUT */
-{
-       BEGIN_SECAPI
-
-       SecPointer<KeyItem> keyItem(KeyItem::required(key));
-       CSSM_DATA inData, outData;
-       inData.Data = (uint8*) cipherText;
-       inData.Length = cipherTextLen;
-       outData.Data = plainText;
-       outData.Length = *plainTextLen;
-
-       const AccessCredentials* credentials = keyItem->getCredentials(CSSM_ACL_AUTHORIZATION_DECRYPT, kSecCredentialTypeDefault);
-
-       keyItem->Decrypt(padding, inData, credentials, outData);
-       *plainTextLen = outData.Length;
-
-       END_SECAPI
-}
-
-/* new in 10.6 */
-size_t
-SecKeyGetBlockSize(SecKeyRef key)
-{
-       size_t blockSize = 0;
-    OSStatus __secapiresult;
-       try {
-               CSSM_KEY cssmKey = KeyItem::required(key)->key();
-               switch(cssmKey.KeyHeader.AlgorithmId)
-               {
-                       case CSSM_ALGID_RSA:
-                       case CSSM_ALGID_DSA:
-                               blockSize = cssmKey.KeyHeader.LogicalKeySizeInBits / 8;
-                               break;
-                       case CSSM_ALGID_ECDSA:
-                       {
-                               /* Block size is up to 9 bytes of DER encoding for sequence of 2 integers,
-                                * plus both coordinates for the point used */
-                               #define ECDSA_KEY_SIZE_IN_BYTES(bits) (((bits) + 7) / 8)
-                               #define ECDSA_MAX_COORD_SIZE_IN_BYTES(n) (ECDSA_KEY_SIZE_IN_BYTES(n) + 1)
-                               size_t coordSize = ECDSA_MAX_COORD_SIZE_IN_BYTES(cssmKey.KeyHeader.LogicalKeySizeInBits);
-                               assert(coordSize < 256); /* size must fit in a byte for DER */
-                               size_t coordDERLen = (coordSize > 127) ? 2 : 1;
-                               size_t coordLen = 1 + coordDERLen + coordSize;
-
-                               size_t pointSize = 2 * coordLen;
-                               assert(pointSize < 256); /* size must fit in a byte for DER */
-                               size_t pointDERLen = (pointSize > 127) ? 2 : 1;
-                               size_t pointLen = 1 + pointDERLen + pointSize;
-
-                               blockSize = pointLen;
-                       }
-                       break;
-                       case CSSM_ALGID_AES:
-                               blockSize = 16; /* all AES keys use 128-bit blocks */
-                               break;
-                       case CSSM_ALGID_DES:
-                       case CSSM_ALGID_3DES_3KEY:
-                               blockSize = 8; /* all DES keys use 64-bit blocks */
-                               break;
-                       default:
-                               assert(0); /* some other key algorithm */
-                               blockSize = 16; /* FIXME: revisit this */
-                               break;
-               }
-               __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 blockSize;
-}
-
-
-/*
-    M4 Additions
-*/
-
-static CFTypeRef
-utilGetStringFromCFDict(CFDictionaryRef parameters, CFTypeRef key, CFTypeRef defaultValue)
-{
-               CFTypeRef value = CFDictionaryGetValue(parameters, key);
-        if (value != NULL) return value;
-        return defaultValue;
-}
-
-static uint32_t
-utilGetNumberFromCFDict(CFDictionaryRef parameters, CFTypeRef key, uint32_t defaultValue)
-{
-        uint32_t integerValue;
-               CFTypeRef value = CFDictionaryGetValue(parameters, key);
-        if (value != NULL) {
-            CFNumberRef nRef = (CFNumberRef) value;
-            CFNumberGetValue(nRef, kCFNumberSInt32Type, &integerValue);
-            return integerValue;
-        }
-        return defaultValue;
- }
-
-static uint32_t
-utilGetMaskValFromCFDict(CFDictionaryRef parameters, CFTypeRef key, uint32_t maskValue)
-{
-               CFTypeRef value = CFDictionaryGetValue(parameters, key);
-        if (value != NULL) {
-            CFBooleanRef bRef = (CFBooleanRef) value;
-            if(CFBooleanGetValue(bRef)) return maskValue;
-        }
-        return 0;
-}
-
-static void
-utilGetKeyParametersFromCFDict(CFDictionaryRef parameters, CSSM_ALGORITHMS *algorithm, uint32 *keySizeInBits, CSSM_KEYUSE *keyUsage, CSSM_KEYCLASS *keyClass)
-{
-    CFTypeRef algorithmDictValue = utilGetStringFromCFDict(parameters, kSecAttrKeyType, kSecAttrKeyTypeAES);
-    CFTypeRef keyClassDictValue = utilGetStringFromCFDict(parameters, kSecAttrKeyClass, kSecAttrKeyClassSymmetric);
-
-    if(CFEqual(algorithmDictValue, kSecAttrKeyTypeAES)) {
-        *algorithm = CSSM_ALGID_AES;
-        *keySizeInBits = 128;
-        *keyClass = CSSM_KEYCLASS_SESSION_KEY;
-    } else if(CFEqual(algorithmDictValue, kSecAttrKeyTypeDES)) {
-        *algorithm = CSSM_ALGID_DES;
-        *keySizeInBits = 128;
-         *keyClass = CSSM_KEYCLASS_SESSION_KEY;
-    } else if(CFEqual(algorithmDictValue, kSecAttrKeyType3DES)) {
-        *algorithm = CSSM_ALGID_3DES_3KEY_EDE;
-        *keySizeInBits = 128;
-        *keyClass = CSSM_KEYCLASS_SESSION_KEY;
-    } else if(CFEqual(algorithmDictValue, kSecAttrKeyTypeRC4)) {
-        *algorithm = CSSM_ALGID_RC4;
-        *keySizeInBits = 128;
-        *keyClass = CSSM_KEYCLASS_SESSION_KEY;
-    } else if(CFEqual(algorithmDictValue, kSecAttrKeyTypeRC2)) {
-        *algorithm = CSSM_ALGID_RC2;
-        *keySizeInBits = 128;
-         *keyClass = CSSM_KEYCLASS_SESSION_KEY;
-    } else if(CFEqual(algorithmDictValue, kSecAttrKeyTypeCAST)) {
-        *algorithm = CSSM_ALGID_CAST;
-        *keySizeInBits = 128;
-         *keyClass = CSSM_KEYCLASS_SESSION_KEY;
-    } else if(CFEqual(algorithmDictValue, kSecAttrKeyTypeRSA)) {
-        *algorithm = CSSM_ALGID_RSA;
-        *keySizeInBits = 128;
-         *keyClass = CSSM_KEYCLASS_PRIVATE_KEY;
-    } else if(CFEqual(algorithmDictValue, kSecAttrKeyTypeDSA)) {
-        *algorithm = CSSM_ALGID_DSA;
-        *keySizeInBits = 128;
-         *keyClass = CSSM_KEYCLASS_PRIVATE_KEY;
-    } else if(CFEqual(algorithmDictValue, kSecAttrKeyTypeECDSA) ||
-            CFEqual(algorithmDictValue, kSecAttrKeyTypeEC)) {
-        *algorithm = CSSM_ALGID_ECDSA;
-        *keySizeInBits = 128;
-        *keyClass = CSSM_KEYCLASS_PRIVATE_KEY;
-    } else {
-        *algorithm = CSSM_ALGID_AES;
-        *keySizeInBits = 128;
-        *keyClass = CSSM_KEYCLASS_SESSION_KEY;
-    }
-
-    if(CFEqual(keyClassDictValue, kSecAttrKeyClassPublic)) {
-        *keyClass = CSSM_KEYCLASS_PUBLIC_KEY;
-    } else if(CFEqual(keyClassDictValue, kSecAttrKeyClassPrivate)) {
-        *keyClass = CSSM_KEYCLASS_PRIVATE_KEY;
-    } else if(CFEqual(keyClassDictValue, kSecAttrKeyClassSymmetric)) {
-         *keyClass = CSSM_KEYCLASS_SESSION_KEY;
-    }
-
-    *keySizeInBits = utilGetNumberFromCFDict(parameters, kSecAttrKeySizeInBits, *keySizeInBits);
-    *keyUsage =  utilGetMaskValFromCFDict(parameters, kSecAttrCanEncrypt, CSSM_KEYUSE_ENCRYPT) |
-                utilGetMaskValFromCFDict(parameters, kSecAttrCanDecrypt, CSSM_KEYUSE_DECRYPT) |
-                utilGetMaskValFromCFDict(parameters, kSecAttrCanWrap, CSSM_KEYUSE_WRAP) |
-                utilGetMaskValFromCFDict(parameters, kSecAttrCanUnwrap, CSSM_KEYUSE_UNWRAP);
-
-
-    if(*keyClass == CSSM_KEYCLASS_PRIVATE_KEY || *keyClass == CSSM_KEYCLASS_PUBLIC_KEY) {
-               *keyUsage |=  utilGetMaskValFromCFDict(parameters, kSecAttrCanSign, CSSM_KEYUSE_SIGN) |
-                                       utilGetMaskValFromCFDict(parameters, kSecAttrCanVerify, CSSM_KEYUSE_VERIFY);
-    }
-
-    if(*keyUsage == 0) {
-               switch (*keyClass) {
-                       case CSSM_KEYCLASS_PRIVATE_KEY:
-                               *keyUsage = CSSM_KEYUSE_DECRYPT | CSSM_KEYUSE_UNWRAP | CSSM_KEYUSE_SIGN;
-                               break;
-                       case CSSM_KEYCLASS_PUBLIC_KEY:
-                               *keyUsage = CSSM_KEYUSE_ENCRYPT | CSSM_KEYUSE_VERIFY | CSSM_KEYUSE_WRAP;
-                               break;
-                       default:
-                               *keyUsage = CSSM_KEYUSE_ENCRYPT | CSSM_KEYUSE_DECRYPT | CSSM_KEYUSE_WRAP | CSSM_KEYUSE_UNWRAP | CSSM_KEYUSE_SIGN | CSSM_KEYUSE_VERIFY;
-                               break;
-               }
-       }
-}
-
-static CFStringRef
-utilCopyDefaultKeyLabel(void)
-{
-       // generate a default label from the current date
-       CFDateRef dateNow = CFDateCreate(kCFAllocatorDefault, CFAbsoluteTimeGetCurrent());
-       CFStringRef defaultLabel = CFCopyDescription(dateNow);
-       CFRelease(dateNow);
-
-       return defaultLabel;
-}
-
-SecKeyRef
-SecKeyGenerateSymmetric(CFDictionaryRef parameters, CFErrorRef *error)
-{
-       OSStatus result = errSecParam; // default result for an early exit
-       SecKeyRef key = NULL;
-       SecKeychainRef keychain = NULL;
-       SecAccessRef access;
-       CFStringRef label;
-       CFStringRef appLabel;
-       CFStringRef appTag;
-       CFStringRef dateLabel = NULL;
-
-       CSSM_ALGORITHMS algorithm;
-       uint32 keySizeInBits;
-       CSSM_KEYUSE keyUsage;
-       uint32 keyAttr = CSSM_KEYATTR_RETURN_DEFAULT;
-       CSSM_KEYCLASS keyClass;
-       CFTypeRef value;
-       Boolean isPermanent;
-       Boolean isExtractable;
-
-       // verify keychain parameter
-       if (!CFDictionaryGetValueIfPresent(parameters, kSecUseKeychain, (const void **)&keychain))
-               keychain = NULL;
-       else if (SecKeychainGetTypeID() != CFGetTypeID(keychain)) {
-               keychain = NULL;
-               goto errorExit;
-       }
-       else
-               CFRetain(keychain);
-
-       // verify permanent parameter
-       if (!CFDictionaryGetValueIfPresent(parameters, kSecAttrIsPermanent, (const void **)&value))
-               isPermanent = false;
-       else if (!value || (CFBooleanGetTypeID() != CFGetTypeID(value)))
-               goto errorExit;
-       else
-               isPermanent = CFEqual(kCFBooleanTrue, value);
-       if (isPermanent) {
-               if (keychain == NULL) {
-                       // no keychain was specified, so use the default keychain
-                       result = SecKeychainCopyDefault(&keychain);
-               }
-               keyAttr |= CSSM_KEYATTR_PERMANENT;
-       }
-
-       // verify extractable parameter
-       if (!CFDictionaryGetValueIfPresent(parameters, kSecAttrIsExtractable, (const void **)&value))
-               isExtractable = true; // default to extractable if value not specified
-       else if (!value || (CFBooleanGetTypeID() != CFGetTypeID(value)))
-               goto errorExit;
-       else
-               isExtractable = CFEqual(kCFBooleanTrue, value);
-       if (isExtractable)
-               keyAttr |= CSSM_KEYATTR_EXTRACTABLE;
-
-       // verify access parameter
-       if (!CFDictionaryGetValueIfPresent(parameters, kSecAttrAccess, (const void **)&access))
-               access = NULL;
-       else if (SecAccessGetTypeID() != CFGetTypeID(access))
-               goto errorExit;
-
-       // verify label parameter
-       if (!CFDictionaryGetValueIfPresent(parameters, kSecAttrLabel, (const void **)&label))
-               label = (dateLabel = utilCopyDefaultKeyLabel()); // no label provided, so use default
-       else if (CFStringGetTypeID() != CFGetTypeID(label))
-               goto errorExit;
-
-       // verify application label parameter
-       if (!CFDictionaryGetValueIfPresent(parameters, kSecAttrApplicationLabel, (const void **)&appLabel))
-               appLabel = (dateLabel) ? dateLabel : (dateLabel = utilCopyDefaultKeyLabel());
-       else if (CFStringGetTypeID() != CFGetTypeID(appLabel))
-               goto errorExit;
-
-       // verify application tag parameter
-       if (!CFDictionaryGetValueIfPresent(parameters, kSecAttrApplicationTag, (const void **)&appTag))
-               appTag = NULL;
-       else if (CFStringGetTypeID() != CFGetTypeID(appTag))
-               goto errorExit;
-
-    utilGetKeyParametersFromCFDict(parameters, &algorithm, &keySizeInBits, &keyUsage, &keyClass);
-
-       if (!keychain) {
-               // the generated key will not be stored in any keychain
-               result = SecKeyGenerate(keychain, algorithm, keySizeInBits, 0, keyUsage, keyAttr, access, &key);
-       }
-       else {
-               // we can set the label attributes on the generated key if it's a keychain item
-               size_t labelBufLen = (label) ? (size_t)CFStringGetMaximumSizeForEncoding(CFStringGetLength(label), kCFStringEncodingUTF8) + 1 : 0;
-               char *labelBuf = (char *)malloc(labelBufLen);
-               size_t appLabelBufLen = (appLabel) ? (size_t)CFStringGetMaximumSizeForEncoding(CFStringGetLength(appLabel), kCFStringEncodingUTF8) + 1 : 0;
-               char *appLabelBuf = (char *)malloc(appLabelBufLen);
-               size_t appTagBufLen = (appTag) ? (size_t)CFStringGetMaximumSizeForEncoding(CFStringGetLength(appTag), kCFStringEncodingUTF8) + 1 : 0;
-               char *appTagBuf = (char *)malloc(appTagBufLen);
-
-               if (label && !CFStringGetCString(label, labelBuf, labelBufLen-1, kCFStringEncodingUTF8))
-                       labelBuf[0]=0;
-               if (appLabel && !CFStringGetCString(appLabel, appLabelBuf, appLabelBufLen-1, kCFStringEncodingUTF8))
-                       appLabelBuf[0]=0;
-               if (appTag && !CFStringGetCString(appTag, appTagBuf, appTagBufLen-1, kCFStringEncodingUTF8))
-                       appTagBuf[0]=0;
-
-               SecKeychainAttribute attrs[] = {
-                       { kSecKeyPrintName, (UInt32)strlen(labelBuf), (char *)labelBuf },
-                       { kSecKeyLabel, (UInt32)strlen(appLabelBuf), (char *)appLabelBuf },
-                       { kSecKeyApplicationTag, (UInt32)strlen(appTagBuf), (char *)appTagBuf } };
-               SecKeychainAttributeList attributes = { sizeof(attrs) / sizeof(attrs[0]), attrs };
-               if (!appTag) --attributes.count;
-
-               result = SecKeyGenerateWithAttributes(&attributes,
-                       keychain, algorithm, keySizeInBits, 0,
-                       keyUsage, keyAttr, access, &key);
-
-               free(labelBuf);
-               free(appLabelBuf);
-               free(appTagBuf);
-       }
-
-errorExit:
-       if (result && error) {
-               *error = CFErrorCreate(kCFAllocatorDefault, kCFErrorDomainOSStatus, result, NULL);
-       }
-       if (dateLabel)
-               CFRelease(dateLabel);
-       if (keychain)
-               CFRelease(keychain);
-
-    return key;
-}
-
-
-
-SecKeyRef
-SecKeyCreateFromData(CFDictionaryRef parameters, CFDataRef keyData, CFErrorRef *error)
-{
-       CSSM_ALGORITHMS         algorithm;
-    uint32                             keySizeInBits;
-    CSSM_KEYUSE                        keyUsage;
-    CSSM_KEYCLASS              keyClass;
-    CSSM_RETURN                        crtn;
-    
-    if(keyData == NULL || CFDataGetLength(keyData) == 0){
-        MacOSError::throwMe(errSecUnsupportedKeySize);
-    }
-    
-    utilGetKeyParametersFromCFDict(parameters, &algorithm, &keySizeInBits, &keyUsage, &keyClass);
-
-       CSSM_CSP_HANDLE cspHandle = cuCspStartup(CSSM_FALSE); // TRUE => CSP, FALSE => CSPDL
-
-       SecKeyImportExportParameters iparam;
-       memset(&iparam, 0, sizeof(iparam));
-       iparam.keyUsage = keyUsage;
-
-       SecExternalItemType itype;
-       switch (keyClass) {
-               case CSSM_KEYCLASS_PRIVATE_KEY:
-                       itype = kSecItemTypePrivateKey;
-                       break;
-               case CSSM_KEYCLASS_PUBLIC_KEY:
-                       itype = kSecItemTypePublicKey;
-                       break;
-               case CSSM_KEYCLASS_SESSION_KEY:
-                       itype = kSecItemTypeSessionKey;
-                       break;
-               default:
-                       itype = kSecItemTypeUnknown;
-                       break;
-       }
-
-       CFMutableArrayRef ka = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
-       // NOTE: if we had a way to specify values other then kSecFormatUnknown we might be more useful.
-       crtn = impExpImportRawKey(keyData, kSecFormatUnknown, itype, algorithm, NULL, cspHandle, 0, NULL, NULL, ka);
-       if (crtn == CSSM_OK && CFArrayGetCount((CFArrayRef)ka)) {
-               SecKeyRef sk = (SecKeyRef)CFArrayGetValueAtIndex((CFArrayRef)ka, 0);
-               CFRetain(sk);
-               CFRelease(ka);
-               return sk;
-       } else {
-               if (error) {
-                       *error = CFErrorCreate(NULL, kCFErrorDomainOSStatus, crtn ? crtn : CSSM_ERRCODE_INTERNAL_ERROR, NULL);
-               }
-               return NULL;
-       }
-}
-
-
-void
-SecKeyGeneratePairAsync(CFDictionaryRef parametersWhichMightBeMutiable, dispatch_queue_t deliveryQueue,
-                                               SecKeyGeneratePairBlock result)
-{
-       CFDictionaryRef parameters = CFDictionaryCreateCopy(NULL, parametersWhichMightBeMutiable);
-       dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
-               SecKeyRef publicKey = NULL;
-               SecKeyRef privateKey = NULL;
-               OSStatus status = SecKeyGeneratePair(parameters, &publicKey, &privateKey);
-               dispatch_async(deliveryQueue, ^{
-                       CFErrorRef error = NULL;
-                       if (errSecSuccess != status) {
-                               error = CFErrorCreate(NULL, kCFErrorDomainOSStatus, status, NULL);
-                       }
-                       result(publicKey, privateKey, error);
-                       if (error) {
-                               CFRelease(error);
-                       }
-                       if (publicKey) {
-                               CFRelease(publicKey);
-                       }
-                       if (privateKey) {
-                               CFRelease(privateKey);
-                       }
-                       CFRelease(parameters);
-               });
-       });
-}
-
-static inline void utilClearAndFree(void *p, size_t len) {
-    if(p) {
-        if(len) bzero(p, len);
-        free(p);
-    }
-}
-
-SecKeyRef
-SecKeyDeriveFromPassword(CFStringRef password, CFDictionaryRef parameters, CFErrorRef *error)
-{
-    CCPBKDFAlgorithm algorithm;
-    CFIndex passwordLen = 0;
-    CFDataRef keyData = NULL;
-    char *thePassword = NULL;
-    uint8_t *salt = NULL;
-    uint8_t *derivedKey = NULL;
-    size_t  saltLen = 0, derivedKeyLen = 0;
-    uint rounds;
-    CFDataRef saltDictValue, algorithmDictValue;
-    SecKeyRef retval = NULL;
-    
-    /* Pick Values from parameters */
-
-    if((saltDictValue = (CFDataRef) CFDictionaryGetValue(parameters, kSecAttrSalt)) == NULL) {
-        *error = CFErrorCreate(NULL, kCFErrorDomainOSStatus, errSecMissingAlgorithmParms, NULL);
-        goto errOut;
-    }
-
-    derivedKeyLen = utilGetNumberFromCFDict(parameters, kSecAttrKeySizeInBits, 128);
-       // This value come in bits but the rest of the code treats it as bytes
-       derivedKeyLen /= 8;
-
-    algorithmDictValue = (CFDataRef) utilGetStringFromCFDict(parameters, kSecAttrPRF, kSecAttrPRFHmacAlgSHA256);
-
-    rounds = utilGetNumberFromCFDict(parameters, kSecAttrRounds, 0);
-
-    /* Convert any remaining parameters and get the password bytes */
-
-    saltLen = CFDataGetLength(saltDictValue);
-    if((salt = (uint8_t *) malloc(saltLen)) == NULL) {
-        *error = CFErrorCreate(NULL, kCFErrorDomainOSStatus, errSecAllocate, NULL);
-        goto errOut;
-    }
-
-    CFDataGetBytes(saltDictValue, CFRangeMake(0, saltLen), (UInt8 *) salt);
-
-    passwordLen = CFStringGetMaximumSizeForEncoding(CFStringGetLength(password), kCFStringEncodingUTF8) + 1;
-    if((thePassword = (char *) malloc(passwordLen)) == NULL) {
-        *error = CFErrorCreate(NULL, kCFErrorDomainOSStatus, errSecAllocate, NULL);
-        goto errOut;
-    }
-    CFStringGetBytes(password, CFRangeMake(0, CFStringGetLength(password)), kCFStringEncodingUTF8, '?', FALSE, (UInt8*)thePassword, passwordLen, &passwordLen);
-
-    if((derivedKey = (uint8_t *) malloc(derivedKeyLen)) == NULL) {
-        *error = CFErrorCreate(NULL, kCFErrorDomainOSStatus, errSecAllocate, NULL);
-        goto errOut;
-    }
-
-    if(algorithmDictValue == NULL) {
-        algorithm = kCCPRFHmacAlgSHA1; /* default */
-    } else if(CFEqual(algorithmDictValue, kSecAttrPRFHmacAlgSHA1)) {
-        algorithm = kCCPRFHmacAlgSHA1;
-    } else if(CFEqual(algorithmDictValue, kSecAttrPRFHmacAlgSHA224)) {
-        algorithm = kCCPRFHmacAlgSHA224;
-    } else if(CFEqual(algorithmDictValue, kSecAttrPRFHmacAlgSHA256)) {
-        algorithm = kCCPRFHmacAlgSHA256;
-    } else if(CFEqual(algorithmDictValue, kSecAttrPRFHmacAlgSHA384)) {
-        algorithm = kCCPRFHmacAlgSHA384;
-    } else if(CFEqual(algorithmDictValue, kSecAttrPRFHmacAlgSHA512)) {
-        algorithm = kCCPRFHmacAlgSHA512;
-    } else {
-        *error = CFErrorCreate(NULL, kCFErrorDomainOSStatus, errSecInvalidAlgorithmParms, NULL);
-        goto errOut;
-    }
-
-    if(rounds == 0) {
-        rounds = 33333; // we need to pass back a consistent value since there's no way to record the round count.
-    }
-
-    if(CCKeyDerivationPBKDF(kCCPBKDF2, thePassword, passwordLen, salt, saltLen, algorithm, rounds, derivedKey, derivedKeyLen)) {
-        *error = CFErrorCreate(NULL, kCFErrorDomainOSStatus, errSecInternalError, NULL);
-        goto errOut;
-    }
-    
-    if((keyData = CFDataCreate(NULL, derivedKey, derivedKeyLen)) != NULL) {
-        retval =  SecKeyCreateFromData(parameters, keyData, error);
-        CFRelease(keyData);
-    } else {
-        *error = CFErrorCreate(NULL, kCFErrorDomainOSStatus, errSecInternalError, NULL);
-    }
-    
-errOut:
-    utilClearAndFree(salt, saltLen);
-    utilClearAndFree(thePassword, passwordLen);
-    utilClearAndFree(derivedKey, derivedKeyLen);
-    return retval;
-}
-
-CFDataRef
-SecKeyWrapSymmetric(SecKeyRef keyToWrap, SecKeyRef wrappingKey, CFDictionaryRef parameters, CFErrorRef *error)
-{
-    *error = CFErrorCreate(NULL, kCFErrorDomainOSStatus, errSecUnimplemented, NULL);
-    return NULL;
-}
-
-SecKeyRef
-SecKeyUnwrapSymmetric(CFDataRef *keyToUnwrap, SecKeyRef unwrappingKey, CFDictionaryRef parameters, CFErrorRef *error)
-{
-    *error = CFErrorCreate(NULL, kCFErrorDomainOSStatus, errSecUnimplemented, NULL);
-    return NULL;
-}
-
-
-/* iOS SecKey shim functions */
-
-#define MAX_DIGEST_LEN (CC_SHA512_DIGEST_LENGTH)
-
-/* Currently length of SHA512 oid + 1 */
-#define MAX_OID_LEN (10)
-
-#define DER_MAX_DIGEST_INFO_LEN  (10 + MAX_DIGEST_LEN + MAX_OID_LEN)
-
-/* Encode the digestInfo header into digestInfo and return the offset from
- digestInfo at which to put the actual digest.  Returns 0 if digestInfo
- won't fit within digestInfoLength bytes.
-
- 0x30, topLen,
- 0x30, algIdLen,
- 0x06, oid.Len, oid.Data,
- 0x05, 0x00
- 0x04, digestLen
- digestData
- */
-static size_t DEREncodeDigestInfoPrefix(const SecAsn1Oid *oid,
-                                        size_t digestLength,
-                                        uint8_t *digestInfo,
-                                        size_t digestInfoLength)
-{
-    size_t algIdLen = oid->Length + 4;
-    size_t topLen = algIdLen + digestLength + 4;
-       size_t totalLen = topLen + 2;
-
-    if (totalLen > digestInfoLength) {
-        return 0;
-    }
-
-    size_t ix = 0;
-    digestInfo[ix++] = (SEC_ASN1_SEQUENCE | SEC_ASN1_CONSTRUCTED);
-    digestInfo[ix++] = topLen;
-    digestInfo[ix++] = (SEC_ASN1_SEQUENCE | SEC_ASN1_CONSTRUCTED);
-    digestInfo[ix++] = algIdLen;
-    digestInfo[ix++] = SEC_ASN1_OBJECT_ID;
-    digestInfo[ix++] = oid->Length;
-    memcpy(&digestInfo[ix], oid->Data, oid->Length);
-    ix += oid->Length;
-    digestInfo[ix++] = SEC_ASN1_NULL;
-    digestInfo[ix++] = 0;
-    digestInfo[ix++] = SEC_ASN1_OCTET_STRING;
-    digestInfo[ix++] = digestLength;
-
-    return ix;
-}
-
-static OSStatus SecKeyGetDigestInfo(SecKeyRef key, const SecAsn1AlgId *algId,
-                                    const uint8_t *data, size_t dataLen, bool digestData,
-                                    uint8_t *digestInfo, size_t *digestInfoLen /* IN/OUT */)
-{
-    unsigned char *(*digestFcn)(const void *, CC_LONG, unsigned char *);
-    CFIndex keyAlgID = kSecNullAlgorithmID;
-    const SecAsn1Oid *digestOid;
-    size_t digestLen;
-    size_t offset = 0;
-
-    /* Since these oids all have the same prefix, use switch. */
-    if ((algId->algorithm.Length == CSSMOID_RSA.Length) &&
-        !memcmp(algId->algorithm.Data, CSSMOID_RSA.Data,
-                algId->algorithm.Length - 1)) {
-            keyAlgID = kSecRSAAlgorithmID;
-            switch (algId->algorithm.Data[algId->algorithm.Length - 1]) {
-#if 0
-                case 2: /* oidMD2WithRSA */
-                    digestFcn = CC_MD2;
-                    digestLen = CC_MD2_DIGEST_LENGTH;
-                    digestOid = &CSSMOID_MD2;
-                    break;
-                case 3: /* oidMD4WithRSA */
-                    digestFcn = CC_MD4;
-                    digestLen = CC_MD4_DIGEST_LENGTH;
-                    digestOid = &CSSMOID_MD4;
-                    break;
-                case 4: /* oidMD5WithRSA */
-                    digestFcn = CC_MD5;
-                    digestLen = CC_MD5_DIGEST_LENGTH;
-                    digestOid = &CSSMOID_MD5;
-                    break;
-#endif /* 0 */
-                case 5: /* oidSHA1WithRSA */
-                    digestFcn = CC_SHA1;
-                    digestLen = CC_SHA1_DIGEST_LENGTH;
-                    digestOid = &CSSMOID_SHA1;
-                    break;
-                case 11: /* oidSHA256WithRSA */
-                    digestFcn = CC_SHA256;
-                    digestLen = CC_SHA256_DIGEST_LENGTH;
-                    digestOid = &CSSMOID_SHA256;
-                    break;
-                case 12: /* oidSHA384WithRSA */
-                    /* pkcs1 12 */
-                    digestFcn = CC_SHA384;
-                    digestLen = CC_SHA384_DIGEST_LENGTH;
-                    digestOid = &CSSMOID_SHA384;
-                    break;
-                case 13: /* oidSHA512WithRSA */
-                    digestFcn = CC_SHA512;
-                    digestLen = CC_SHA512_DIGEST_LENGTH;
-                    digestOid = &CSSMOID_SHA512;
-                    break;
-                case 14: /* oidSHA224WithRSA */
-                    digestFcn = CC_SHA224;
-                    digestLen = CC_SHA224_DIGEST_LENGTH;
-                    digestOid = &CSSMOID_SHA224;
-                    break;
-                default:
-                    secdebug("key", "unsupported rsa signature algorithm");
-                    return errSecUnsupportedAlgorithm;
-            }
-        } else if ((algId->algorithm.Length == CSSMOID_ECDSA_WithSHA224.Length) &&
-                   !memcmp(algId->algorithm.Data, CSSMOID_ECDSA_WithSHA224.Data,
-                           algId->algorithm.Length - 1)) {
-                       keyAlgID = kSecECDSAAlgorithmID;
-                       switch (algId->algorithm.Data[algId->algorithm.Length - 1]) {
-                           case 1: /* oidSHA224WithECDSA */
-                               digestFcn = CC_SHA224;
-                               digestLen = CC_SHA224_DIGEST_LENGTH;
-                               break;
-                           case 2: /* oidSHA256WithECDSA */
-                               digestFcn = CC_SHA256;
-                               digestLen = CC_SHA256_DIGEST_LENGTH;
-                               break;
-                           case 3: /* oidSHA384WithECDSA */
-                               /* pkcs1 12 */
-                               digestFcn = CC_SHA384;
-                               digestLen = CC_SHA384_DIGEST_LENGTH;
-                               break;
-                           case 4: /* oidSHA512WithECDSA */
-                               digestFcn = CC_SHA512;
-                               digestLen = CC_SHA512_DIGEST_LENGTH;
-                               break;
-                           default:
-                               secdebug("key", "unsupported ecdsa signature algorithm");
-                               return errSecUnsupportedAlgorithm;
-                       }
-                   } else if (SecAsn1OidCompare(&algId->algorithm, &CSSMOID_ECDSA_WithSHA1)) {
-                       keyAlgID = kSecECDSAAlgorithmID;
-                       digestFcn = CC_SHA1;
-                       digestLen = CC_SHA1_DIGEST_LENGTH;
-                   } else if (SecAsn1OidCompare(&algId->algorithm, &CSSMOID_SHA1)) {
-                       digestFcn = CC_SHA1;
-                       digestLen = CC_SHA1_DIGEST_LENGTH;
-                       digestOid = &CSSMOID_SHA1;
-                   } else if ((algId->algorithm.Length == CSSMOID_SHA224.Length) &&
-                              !memcmp(algId->algorithm.Data, CSSMOID_SHA224.Data, algId->algorithm.Length - 1))
-                   {
-                       switch (algId->algorithm.Data[algId->algorithm.Length - 1]) {
-                           case 4: /* OID_SHA224 */
-                               digestFcn = CC_SHA224;
-                               digestLen = CC_SHA224_DIGEST_LENGTH;
-                               digestOid = &CSSMOID_SHA224;
-                               break;
-                           case 1: /* OID_SHA256 */
-                               digestFcn = CC_SHA256;
-                               digestLen = CC_SHA256_DIGEST_LENGTH;
-                               digestOid = &CSSMOID_SHA256;
-                               break;
-                           case 2: /* OID_SHA384 */
-                               /* pkcs1 12 */
-                               digestFcn = CC_SHA384;
-                               digestLen = CC_SHA384_DIGEST_LENGTH;
-                               digestOid = &CSSMOID_SHA384;
-                               break;
-                           case 3: /* OID_SHA512 */
-                               digestFcn = CC_SHA512;
-                               digestLen = CC_SHA512_DIGEST_LENGTH;
-                               digestOid = &CSSMOID_SHA512;
-                               break;
-                           default:
-                               secdebug("key", "unsupported sha-2 signature algorithm");
-                               return errSecUnsupportedAlgorithm;
-                       }
-                   } else if (SecAsn1OidCompare(&algId->algorithm, &CSSMOID_MD5)) {
-                       digestFcn = CC_MD5;
-                       digestLen = CC_MD5_DIGEST_LENGTH;
-                       digestOid = &CSSMOID_MD5;
-                   } else {
-                       secdebug("key", "unsupported digesting algorithm");
-                       return errSecUnsupportedAlgorithm;
-                   }
-
-    /* check key is appropriate for signature (superfluous for digest only oid) */
-    {
-        CFIndex supportedKeyAlgID = kSecNullAlgorithmID;
-    #if TARGET_OS_EMBEDDED
-        supportedKeyAlgID = SecKeyGetAlgorithmID(key);
-    #else
-        const CSSM_KEY* temporaryKey;
-        SecKeyGetCSSMKey(key, &temporaryKey);
-        CSSM_ALGORITHMS tempAlgorithm = temporaryKey->KeyHeader.AlgorithmId;
-        if (CSSM_ALGID_RSA == tempAlgorithm) {
-            supportedKeyAlgID = kSecRSAAlgorithmID;
-        } else if (CSSM_ALGID_ECDSA == tempAlgorithm) {
-            supportedKeyAlgID = kSecECDSAAlgorithmID;
-        }
-    #endif
-
-        if (keyAlgID == kSecNullAlgorithmID) {
-            keyAlgID = supportedKeyAlgID;
-        }
-        else if (keyAlgID != supportedKeyAlgID) {
-            return errSecUnsupportedAlgorithm;
-        }
-    }
-
-    switch(keyAlgID) {
-        case kSecRSAAlgorithmID:
-            offset = DEREncodeDigestInfoPrefix(digestOid, digestLen,
-                                               digestInfo, *digestInfoLen);
-            if (!offset)
-                return errSecBufferTooSmall;
-            break;
-        case kSecDSAAlgorithmID:
-            if (digestOid != &CSSMOID_SHA1)
-                return errSecUnsupportedAlgorithm;
-            break;
-        case kSecECDSAAlgorithmID:
-            break;
-        default:
-            secdebug("key", "unsupported signature algorithm");
-            return errSecUnsupportedAlgorithm;
-    }
-
-    if (digestData) {
-        if(dataLen>UINT32_MAX) /* Check for overflow with CC_LONG cast */
-            return errSecParam;
-        digestFcn(data, (CC_LONG)dataLen, &digestInfo[offset]);
-        *digestInfoLen = offset + digestLen;
-    } else {
-        if (dataLen != digestLen)
-            return errSecParam;
-        memcpy(&digestInfo[offset], data, dataLen);
-        *digestInfoLen = offset + dataLen;
-    }
-
-    return errSecSuccess;
-}
-
-OSStatus SecKeyVerifyDigest(
-    SecKeyRef           key,            /* Private key */
-    const SecAsn1AlgId  *algId,         /* algorithm oid/params */
-    const uint8_t       *digestData,    /* signature over this digest */
-    size_t              digestDataLen,  /* length of dataToDigest */
-    const uint8_t       *sig,           /* signature to verify */
-    size_t              sigLen)         /* length of sig */
-{
-    size_t digestInfoLength = DER_MAX_DIGEST_INFO_LEN;
-    uint8_t digestInfo[digestInfoLength];
-    OSStatus status;
-
-    status = SecKeyGetDigestInfo(key, algId, digestData, digestDataLen, false /* data is digest */,
-                                 digestInfo, &digestInfoLength);
-    if (status)
-        return status;
-    return SecKeyRawVerify(key, kSecPaddingPKCS1,
-                           digestInfo, digestInfoLength, sig, sigLen);
-}
-
-OSStatus SecKeySignDigest(
-    SecKeyRef           key,            /* Private key */
-    const SecAsn1AlgId  *algId,         /* algorithm oid/params */
-    const uint8_t       *digestData,   /* signature over this digest */
-    size_t              digestDataLen,  /* length of digestData */
-    uint8_t             *sig,                  /* signature, RETURNED */
-    size_t              *sigLen)               /* IN/OUT */
-{
-    size_t digestInfoLength = DER_MAX_DIGEST_INFO_LEN;
-    uint8_t digestInfo[digestInfoLength];
-    OSStatus status;
-
-    status = SecKeyGetDigestInfo(key, algId, digestData, digestDataLen, false,
-                                 digestInfo, &digestInfoLength);
-    if (status)
-        return status;
-    return SecKeyRawSign(key, kSecPaddingPKCS1,
-                         digestInfo, digestInfoLength, sig, sigLen);
-}
-
-/* It's debatable whether this belongs here or in the ssl code since the
- curve values come from a tls related rfc4492. */
-SecECNamedCurve SecECKeyGetNamedCurve(SecKeyRef key)
-{
-    try {
-        SecPointer<KeyItem> keyItem(KeyItem::required(key));
-        switch (keyItem->key().header().LogicalKeySizeInBits) {
-#if 0
-            case 192:
-                return kSecECCurveSecp192r1;
-            case 224:
-                return kSecECCurveSecp224r1;
-#endif
-            case 256:
-                return kSecECCurveSecp256r1;
-            case 384:
-                return kSecECCurveSecp384r1;
-            case 521:
-                return kSecECCurveSecp521r1;
-        }
-    }
-    catch (...) {}
-    return kSecECCurveNone;
-}
-
-static inline CFDataRef _CFDataCreateReferenceFromRange(CFAllocatorRef allocator, CFDataRef sourceData, CFRange range)
-{
-    return CFDataCreateWithBytesNoCopy(allocator,
-                                       CFDataGetBytePtr(sourceData) + range.location, range.length,
-                                       kCFAllocatorNull);
-}
-
-static inline CFDataRef _CFDataCreateCopyFromRange(CFAllocatorRef allocator, CFDataRef sourceData, CFRange range)
-{
-    return CFDataCreate(allocator, CFDataGetBytePtr(sourceData) + range.location, range.length);
-}
-
-#pragma clang diagnostic push
-#pragma clang diagnostic ignored "-Wunused-function"
-static inline bool _CFDataEquals(CFDataRef left, CFDataRef right)
-{
-    return (left != NULL) &&
-    (right != NULL) &&
-    (CFDataGetLength(left) == CFDataGetLength(right)) &&
-    (0 == memcmp(CFDataGetBytePtr(left), CFDataGetBytePtr(right), (size_t)CFDataGetLength(left)));
-}
-#pragma clang diagnostic pop
-
-#if ECDSA_DEBUG
-void secdump(const unsigned char *data, unsigned long len)
-{
-       unsigned long i;
-       char s[128];
-       char t[32];
-       s[0]=0;
-       for(i=0;i<len;i++)
-       {
-               if((i&0xf)==0) {
-                       sprintf(t, "%04lx :", i);
-                       strcat(s, t);
-               }
-               sprintf(t, " %02x", data[i]);
-               strcat(s, t);
-               if((i&0xf)==0xf) {
-                       strcat(s, "\n");
-                       syslog(LOG_NOTICE, s);
-                       s[0]=0;
-               }
-       }
-       strcat(s, "\n");
-       syslog(LOG_NOTICE, s);
-}
-#endif
-
-OSStatus SecKeyCopyPublicBytes(SecKeyRef key, CFDataRef* publicBytes)
-{
-       CFIndex keyAlgId;
-#if TARGET_OS_EMBEDDED
-       keyAlgId = SecKeyGetAlgorithmID(key);
-#else
-       keyAlgId = SecKeyGetAlgorithmId(key);
-#endif
-
-       OSStatus ecStatus = errSecParam;
-       CFDataRef tempPublicData = NULL;
-       CFDataRef headerlessPublicData = NULL;
-       CFIndex headerLength = 0;
-    const UInt8* pData_Ptr = NULL;
-
-       if (kSecRSAAlgorithmID == keyAlgId) 
-       {
-               return SecItemExport(key, kSecFormatBSAFE, 0, NULL, publicBytes);
-       }
-
-       if (kSecECDSAAlgorithmID == keyAlgId) 
-       {       
-               // First export the key so there is access to the underlying key material
-               ecStatus = SecItemExport(key, kSecFormatOpenSSL, 0, NULL, &tempPublicData);
-               if(ecStatus != errSecSuccess)
-               {
-                       secdebug("key", "SecKeyCopyPublicBytes: SecItemExport error (%d) for ECDSA public key %p",
-                                       ecStatus, (uintptr_t)key);
-                                       
-               return ecStatus;
-        }
-
-               
-        // Get a pointer to the first byte of the exported data
-        pData_Ptr = CFDataGetBytePtr(tempPublicData);
-
-        // the first byte should be a sequence 0x30
-        if (*pData_Ptr != 0x30)
-        {
-            secdebug("key", "SecKeyCopyPublicBytes: exported data is invalid");
-             if (NULL != tempPublicData)
-                   CFRelease(tempPublicData);
-
-                       ecStatus = errSecParam;
-               return ecStatus;
-        }
-
-        // move past the sequence byte
-        pData_Ptr++;
-
-        // Check to see if the high bit is set which
-        // indicates that the length will be at least 
-        // two bytes.  If the high bit is set then
-        // The lower seven bits specifies the number of
-       // bytes used for the length.  The additonal 1
-       // is for the current byte. Otherwise just move past the 
-       // single length byte
-        pData_Ptr += (*pData_Ptr & 0x80) ? ((*pData_Ptr & 0x7F) + 1) : 1;
-
-        // The current byte should be a sequence 0x30
-        if (*pData_Ptr != 0x30)
-        {
-               secdebug("key", "SecKeyCopyPublicBytes: Could not find the key sequence");
-             if (NULL != tempPublicData)
-                   CFRelease(tempPublicData);
-       
-                       ecStatus = errSecParam;
-
-               return ecStatus;
-        }
-
-        // The next bytes will always be the same
-        // 0x30 = SEQUENCE
-        // XX Length Byte
-        // 0x06 OBJECT ID
-        // 0x07 Length Byte
-        // ECDSA public KEY OID value 0x2a,0x86,0x48,0xce,0x3d,0x02,0x01
-        // 0x06 OBJECT ID
-        // This is a total of 12 bytes
-        pData_Ptr += 12;
-
-        // Next byte is the length of the ECDSA curve OID
-        // Move past the length byte and the curve OID
-        pData_Ptr += (((int)*pData_Ptr) + 1);
-
-        // Should be at a BINARY String which is specifed by a 0x3
-        if (*pData_Ptr != 0x03)
-        {
-               secdebug("key", "SecKeyCopyPublicBytes: Invalid key structure");
-             if (NULL != tempPublicData)
-                   CFRelease(tempPublicData);
-       
-                       ecStatus = errSecParam;
-
-               return ecStatus;
-        }
-
-        // Move past the BINARY String specifier 0x03
-        pData_Ptr++;
-
-
-        // Check to see if the high bit is set which
-        // indicates that the length will be at least 
-        // two bytes.  If the high bit is set then
-        // The lower seven bits specifies the number of
-       // bytes used for the length.  The additonal 1
-       // is for the current byte. Otherwise just move past the 
-       // single length byte
-        pData_Ptr += (*pData_Ptr & 0x80) ? ((*pData_Ptr & 0x7F) + 1) : 1;
-
-        // Move past the beginning marker for the BINARY String 0x00
-        pData_Ptr++;
-
-        // pData_Ptr now points to the first bytes of the key material
-        headerLength = (CFIndex)(((intptr_t)pData_Ptr) -  ((intptr_t)CFDataGetBytePtr(tempPublicData)));       
-        
-        headerlessPublicData = _CFDataCreateCopyFromRange(kCFAllocatorDefault,
-            tempPublicData, CFRangeMake(headerLength, CFDataGetLength(tempPublicData) - headerLength));
-        
-        if (!headerlessPublicData)
-        {
-                       printf("SecKeyCopyPublicBytes: headerlessPublicData is nil (1)\n");
-                if (NULL != tempPublicData)
-                   CFRelease(tempPublicData);
-       
-                       ecStatus = errSecParam;
-
-               return ecStatus;
-               }
-        
-        if (publicBytes)
-        {
-               *publicBytes = headerlessPublicData;
-        }
-
-        ecStatus = errSecSuccess;
-        
-        if (NULL != tempPublicData)
-            CFRelease(tempPublicData);
-            
-        return ecStatus;
-      }
-
-  return errSecParam;
-}
-
-
-CFDataRef SecECKeyCopyPublicBits(SecKeyRef key)
-{
-    CFDataRef exportedKey;
-    if(SecKeyCopyPublicBytes(key, &exportedKey) != errSecSuccess) {
-        exportedKey = NULL;
-    }
-    return exportedKey;
-}
-
-SecKeyRef SecKeyCreateFromPublicData(CFAllocatorRef allocator, CFIndex algorithmID, CFDataRef publicBytes)
-{
-    SecExternalFormat externalFormat = kSecFormatOpenSSL;
-    SecExternalItemType externalItemType = kSecItemTypePublicKey;
-    CFDataRef workingData = NULL;
-    CFArrayRef outArray = NULL;
-    SecKeyRef retVal = NULL;
-    
-    if (kSecRSAAlgorithmID == algorithmID) {
-               /*
-                * kSecFormatBSAFE uses the original PKCS#1 definition:
-                *     RSAPublicKey ::= SEQUENCE {
-                *        modulus           INTEGER,  -- n
-                *        publicExponent    INTEGER   -- e
-                *     }
-                * kSecFormatOpenSSL uses different ASN.1 encoding.
-                */
-               externalFormat = kSecFormatBSAFE;
-        workingData = _CFDataCreateReferenceFromRange(kCFAllocatorDefault, publicBytes, CFRangeMake(0, CFDataGetLength(publicBytes)));
-    } else if (kSecECDSAAlgorithmID == algorithmID) {
-        CFMutableDataRef tempData;
-        uint8 requiredFirstDERByte [] = {0x04};
-        uint8 placeholder[1];
-        uint8 headerBytes[] = { 0x30,0x59,0x30,0x13,0x06,0x07,0x2a,0x86,
-                                0x48,0xce,0x3d,0x02,0x01,0x06,0x08,0x2a,
-                                0x86,0x48,0xce,0x3d,0x03,0x01,0x07,0x03,
-                                0x42,0x00 };
-
-        /* FIXME: this code only handles one specific curve type; need to expand this */        
-        if(CFDataGetLength(publicBytes) != 65)
-            goto cleanup;
-
-        CFDataGetBytes(publicBytes, CFRangeMake(0, 1), placeholder);
-        
-        if(requiredFirstDERByte[0] != placeholder[0])
-            goto cleanup;
-        
-        
-        tempData = CFDataCreateMutable(kCFAllocatorDefault, 0);
-        CFDataAppendBytes(tempData, headerBytes, sizeof(headerBytes));
-        CFDataAppendBytes(tempData, CFDataGetBytePtr(publicBytes), CFDataGetLength(publicBytes));
-        
-        workingData = tempData;
-    }
-    if(SecItemImport(workingData, NULL, &externalFormat, &externalItemType, 0, NULL, NULL, &outArray) != errSecSuccess) {
-               goto cleanup;
-    }
-       if(!outArray || CFArrayGetCount(outArray) == 0) {
-               goto cleanup;
-       }
-    retVal = (SecKeyRef)CFArrayGetValueAtIndex(outArray, 0);
-    CFRetain(retVal);
-
-cleanup:
-    if(workingData) CFRelease(workingData);
-    if(outArray) CFRelease(outArray);
-    return retVal;
-}
-
-SecKeyRef SecKeyCreateRSAPublicKey(CFAllocatorRef allocator,
-    const uint8_t *keyData, CFIndex keyDataLength,
-    SecKeyEncoding encoding)
-{
-       CFDataRef pubKeyData = NULL;
-    if(kSecKeyEncodingPkcs1 == encoding) {
-        /* DER-encoded according to PKCS1. */
-               pubKeyData = CFDataCreate(allocator, keyData, keyDataLength);
-
-    } else if(kSecKeyEncodingApplePkcs1 == encoding) {
-        /* DER-encoded according to PKCS1 with Apple Extensions. */
-               /* FIXME: need to actually handle extensions */
-               return NULL;
-
-    } else if(kSecKeyEncodingRSAPublicParams == encoding) {
-        /* SecRSAPublicKeyParams format; we must encode as PKCS1. */
-               SecRSAPublicKeyParams *params = (SecRSAPublicKeyParams *)keyData;
-               DERSize m_size = params->modulusLength;
-               DERSize e_size = params->exponentLength;
-               const DERSize seq_size = DERLengthOfItem(ASN1_INTEGER, m_size) +
-                       DERLengthOfItem(ASN1_INTEGER, e_size);
-               const DERSize result_size = DERLengthOfItem(ASN1_SEQUENCE, seq_size);
-               DERSize r_size, remaining_size = result_size;
-               DERReturn drtn;
-
-               CFMutableDataRef pkcs1 = CFDataCreateMutable(allocator, result_size);
-               if (pkcs1 == NULL) {
-                       return NULL;
-               }
-               CFDataSetLength(pkcs1, result_size);
-               uint8_t *bytes = CFDataGetMutableBytePtr(pkcs1);
-
-               *bytes++ = ASN1_CONSTR_SEQUENCE;
-               remaining_size--;
-               r_size = 4;
-               drtn = DEREncodeLength(seq_size, bytes, &r_size);
-               if (r_size <= remaining_size) {
-                       bytes += r_size;
-                       remaining_size -= r_size;
-               }
-               r_size = remaining_size;
-               drtn = DEREncodeItem(ASN1_INTEGER, m_size, (const DERByte *)params->modulus, (DERByte *)bytes, &r_size);
-               if (r_size <= remaining_size) {
-                       bytes += r_size;
-                       remaining_size -= r_size;
-               }
-               r_size = remaining_size;
-               drtn = DEREncodeItem(ASN1_INTEGER, e_size, (const DERByte *)params->exponent, (DERByte *)bytes, &r_size);
-
-               pubKeyData = pkcs1;
-
-    } else {
-        /* unsupported encoding */
-        return NULL;
-    }
-    SecKeyRef publicKey = SecKeyCreateFromPublicData(allocator, kSecRSAAlgorithmID, pubKeyData);
-    CFRelease(pubKeyData);
-    return publicKey;
-}
-
-#if !TARGET_OS_EMBEDDED
-//
-// Given a CSSM public key, copy its modulus and/or exponent data.
-// Caller is responsible for releasing the returned CFDataRefs.
-//
-static
-OSStatus _SecKeyCopyRSAPublicModulusAndExponent(SecKeyRef key, CFDataRef *modulus, CFDataRef *exponent)
-{
-       const CSSM_KEY          *pubKey;
-       const CSSM_KEYHEADER    *hdr;
-       CSSM_DATA               pubKeyBlob;
-       OSStatus                result;
-
-    result = SecKeyGetCSSMKey(key, &pubKey);
-       if(result != errSecSuccess) {
-               return result;
-       }
-       hdr = &pubKey->KeyHeader;
-       if(hdr->KeyClass != CSSM_KEYCLASS_PUBLIC_KEY) {
-               return errSSLInternal;
-       }
-       if(hdr->AlgorithmId != CSSM_ALGID_RSA) {
-               return errSSLInternal;
-       }
-       switch(hdr->BlobType) {
-               case CSSM_KEYBLOB_RAW:
-                       pubKeyBlob.Length = pubKey->KeyData.Length;
-                       pubKeyBlob.Data = pubKey->KeyData.Data;
-                       break;
-               case CSSM_KEYBLOB_REFERENCE:
-                       // FIXME: currently SSL only uses raw public keys, obtained from the CL
-               default:
-                       return errSSLInternal;
-       }
-       assert(hdr->BlobType == CSSM_KEYBLOB_RAW);
-       // at this point we should have a PKCS1-encoded blob
-
-    DERItem keyItem = {(DERByte *)pubKeyBlob.Data, pubKeyBlob.Length};
-    DERRSAPubKeyPKCS1 decodedKey;
-    if(DERParseSequence(&keyItem, DERNumRSAPubKeyPKCS1ItemSpecs,
-                        DERRSAPubKeyPKCS1ItemSpecs,
-                        &decodedKey, sizeof(decodedKey)) != DR_Success) {
-        return errSecDecode;
-    }
-    if(modulus) {
-        *modulus = CFDataCreate(kCFAllocatorDefault, decodedKey.modulus.data, decodedKey.modulus.length);
-        if(*modulus == NULL) {
-            return errSecDecode;
-        }
-    }
-    if(exponent) {
-        *exponent = CFDataCreate(kCFAllocatorDefault, decodedKey.pubExponent.data, decodedKey.pubExponent.length);
-        if(*exponent == NULL) {
-            return errSecDecode;
-        }
-    }
-
-    return errSecSuccess;
-}
-#endif /* !TARGET_OS_EMBEDDED */
-
-CFDataRef SecKeyCopyModulus(SecKeyRef key)
-{
-#if TARGET_OS_EMBEDDED
-    ccrsa_pub_ctx_t pubkey;
-    pubkey.pub = key->key;
-
-    size_t m_size = ccn_write_uint_size(ccrsa_ctx_n(pubkey), ccrsa_ctx_m(pubkey));
-
-       CFAllocatorRef allocator = CFGetAllocator(key);
-       CFMutableDataRef modulusData = CFDataCreateMutable(allocator, m_size);
-
-    if (modulusData == NULL)
-        return NULL;
-
-       CFDataSetLength(modulusData, m_size);
-
-    ccn_write_uint(ccrsa_ctx_n(pubkey), ccrsa_ctx_m(pubkey), m_size, CFDataGetMutableBytePtr(modulusData));
-#else
-    CFDataRef modulusData;
-    OSStatus status = _SecKeyCopyRSAPublicModulusAndExponent(key, &modulusData, NULL);
-    if(status != errSecSuccess) {
-        modulusData = NULL;
-    }
-#endif
-
-    return modulusData;
-}
-
-CFDataRef SecKeyCopyExponent(SecKeyRef key)
-{
-#if TARGET_OS_EMBEDDED
-    ccrsa_pub_ctx_t pubkey;
-    pubkey.pub = key->key;
-
-    size_t e_size = ccn_write_uint_size(ccrsa_ctx_n(pubkey), ccrsa_ctx_e(pubkey));
-
-       CFAllocatorRef allocator = CFGetAllocator(key);
-       CFMutableDataRef exponentData = CFDataCreateMutable(allocator, e_size);
-
-    if (exponentData == NULL)
-        return NULL;
-
-       CFDataSetLength(exponentData, e_size);
-
-    ccn_write_uint(ccrsa_ctx_n(pubkey), ccrsa_ctx_m(pubkey), e_size, CFDataGetMutableBytePtr(exponentData));
-#else
-    CFDataRef exponentData;
-    OSStatus status = _SecKeyCopyRSAPublicModulusAndExponent(key, NULL, &exponentData);
-    if(status != errSecSuccess) {
-        exponentData = NULL;
-    }
-#endif
-
-    return exponentData;
-}
-
-SecKeyRef SecKeyCreatePublicFromPrivate(SecKeyRef privateKey) {
-    OSStatus status = errSecParam;
-    
-    CFDataRef serializedPublic = NULL;
-
-    status = SecKeyCopyPublicBytes(privateKey, &serializedPublic);
-    if ((status == errSecSuccess) && (serializedPublic != NULL)) {
-        SecKeyRef publicKeyRef = SecKeyCreateFromPublicData(kCFAllocatorDefault, SecKeyGetAlgorithmId(privateKey), serializedPublic);
-        CFRelease(serializedPublic);
-        if (publicKeyRef != NULL) {
-            return publicKeyRef;
-        }
-    }
-
-    const void *keys[]      = { kSecClass, kSecValueRef, kSecReturnAttributes };
-    const void *values[]    = { kSecClassKey, privateKey,  kCFBooleanTrue };
-    CFDictionaryRef query= CFDictionaryCreate(NULL, keys, values,
-                                              (sizeof(values) / sizeof(*values)),
-                                              &kCFTypeDictionaryKeyCallBacks,
-                                              &kCFTypeDictionaryValueCallBacks);
-    CFTypeRef foundItem = NULL;
-    status = SecItemCopyMatching(query, &foundItem);
-    
-    if (status == errSecSuccess) {
-        if (CFGetTypeID(foundItem) == CFDictionaryGetTypeID()) {
-            CFMutableDictionaryRef query2 = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
-            CFDictionaryAddValue(query2, kSecClass, kSecClassKey);
-            CFDictionaryAddValue(query2, kSecAttrKeyClass, kSecAttrKeyClassPublic);
-            CFDictionaryAddValue(query2, kSecAttrApplicationLabel, CFDictionaryGetValue((CFDictionaryRef)foundItem, kSecAttrApplicationLabel));
-            CFDictionaryAddValue(query2, kSecReturnRef, kCFBooleanTrue);
-
-            CFTypeRef foundKey = NULL;
-            status = SecItemCopyMatching(query2, &foundKey);
-            if (status == errSecSuccess) {
-                if (CFGetTypeID(foundKey) == SecKeyGetTypeID()) {
-                    CFRelease(query);
-                    CFRelease(query2);
-                    CFRelease(foundItem);
-                    return (SecKeyRef)foundKey;
-                } else {
-                    status = errSecItemNotFound;
-                }
-            }
-            CFRelease(query2);
-            
-        } else {
-            status = errSecItemNotFound;
-        }
-        CFRelease(foundItem);
-    }
-   
-    CFRelease(query);
-    return NULL;
-}
-