]> git.saurik.com Git - apple/security.git/blobdiff - libsecurity_pkcs12/lib/pkcs12Utils.cpp
Security-57031.1.35.tar.gz
[apple/security.git] / libsecurity_pkcs12 / lib / pkcs12Utils.cpp
diff --git a/libsecurity_pkcs12/lib/pkcs12Utils.cpp b/libsecurity_pkcs12/lib/pkcs12Utils.cpp
deleted file mode 100644 (file)
index e2040dc..0000000
+++ /dev/null
@@ -1,832 +0,0 @@
-/*
- * Copyright (c) 2003-2004 Apple Computer, 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@
- */
-
-/*
- * pkcs12Utils.cpp
- */
-
-#include "pkcs12Utils.h"
-#include <string.h>
-#include "pkcs7Templates.h"
-#include "pkcs12Templates.h"
-#include "pkcs12Crypto.h"
-#include "pkcs12Debug.h"
-#include <security_asn1/nssUtils.h>
-#include <Security/secasn1t.h>
-#include <security_utilities/devrandom.h>
-#include <security_utilities/errors.h>
-#include <security_cdsa_utils/cuCdsaUtils.h>
-#include <Security/oidsattr.h>
-#include <Security/oidsalg.h>
-#include <Security/cssmapple.h>
-
-/* malloc a NULL-ed array of pointers of size num+1 */
-void **p12NssNullArray(
-       uint32 num,
-       SecNssCoder &coder)
-{
-       unsigned len = (num + 1) * sizeof(void *);
-       void **p = (void **)coder.malloc(len);
-       memset(p, 0, len);
-       return p;
-}
-
-/* CSSM_DATA --> uint32. Returns true if OK. */
-bool p12DataToInt(
-       const CSSM_DATA &cdata,
-       uint32 &u)
-{
-       if((cdata.Length == 0) || (cdata.Data == NULL)) {
-               /* default/not present */
-               u = 0;
-               return true;
-       }
-       CSSM_SIZE len = cdata.Length;
-       if(len > sizeof(uint32)) {
-               return false;
-       }
-       
-       uint32 rtn = 0;
-       uint8 *cp = cdata.Data;
-       for(uint32 i=0; i<len; i++) {
-               rtn = (rtn << 8) | *cp++;
-       }
-       u = rtn;
-       return true;
-}
-
-/* uint32 --> CSSM_DATA */
-void p12IntToData(
-       uint32 num,
-       CSSM_DATA &cdata,
-       SecNssCoder &coder)
-{
-       uint32 len = 0;
-       
-       if(num < 0x100) {
-               len = 1;
-       }
-       else if(num < 0x10000) {
-               len = 2;
-       }
-       else if(num < 0x1000000) {
-               len = 3;
-       }
-       else {
-               len = 4;
-       }
-       coder.allocItem(cdata, len);
-       uint8 *cp = &cdata.Data[len - 1];
-       for(unsigned i=0; i<len; i++) {
-               *cp-- = num & 0xff;
-               num >>= 8;
-       }
-}
-
-/* CFDataRef <--> CSSM_DATA */
-CFDataRef p12CssmDataToCf(
-       const CSSM_DATA &c)
-{
-       return CFDataCreate(NULL, c.Data, c.Length);
-}
-
-void p12CfDataToCssm(
-       CFDataRef cf,
-       CSSM_DATA &c,
-       SecNssCoder &coder)
-{
-       coder.allocCopyItem(CFDataGetBytePtr(cf),
-               CFDataGetLength(cf), c);
-}
-
-/*
- * Attempt to convert a CFStringRef, which represents a SafeBag's
- * FriendlyName, to a UTF8-encoded CSSM_DATA. The CSSM_DATA and its
- * referent are allocated in the specified SecNssCoder's memory.
- * No guarantee that this conversion works. If it doesn't we return 
- * NULL and caller must be prepared to deal with that. 
- */
-CSSM_DATA_PTR p12StringToUtf8(
-       CFStringRef cfStr,
-       SecNssCoder &coder)
-{
-       if(cfStr == NULL) {
-               return NULL;
-       }
-       CFIndex strLen = CFStringGetLength(cfStr);
-       if(strLen == 0) {
-               return NULL;
-       }
-       CSSM_DATA_PTR rtn = coder.mallocn<CSSM_DATA>();
-       coder.allocItem(*rtn, strLen + 1);
-       if(!CFStringGetCString(cfStr, (char *)rtn->Data,strLen + 1,
-                       kCFStringEncodingUTF8)) {
-               /* not convertible from native Unicode to UTF8 */
-               return NULL;
-       }
-       return rtn;
-}
-
-/*
- * Enum to string mappper.
- * Maybe DEBUG only.
- */
-/*
- * Each type of attribute has a name/value pair in a table of these:
- */
-typedef struct {
-       unsigned                value;
-       const char              *name;
-} p12NameValuePair;
-
-/* declare one entry in a table of p12NameValuePair */
-#define NVP(attr)              {attr, #attr}
-
-/* the NULL entry which terminates all p12NameValuePair tables */
-#define NVP_END                {0, NULL}
-
-static const p12NameValuePair p7CITypeNames[] = 
-{
-       NVP(CT_None),
-       NVP(CT_Data),
-       NVP(CT_SignedData),
-       NVP(CT_EnvData),
-       NVP(CT_SignedEnvData),
-       NVP(CT_DigestData),
-       NVP(CT_EncryptedData),
-       NVP_END
-};
-
-static const p12NameValuePair p12BagTypeNames[] = 
-{
-       NVP(BT_None),
-       NVP(BT_KeyBag),
-       NVP(BT_ShroudedKeyBag),
-       NVP(BT_CertBag),
-       NVP(BT_CrlBag),
-       NVP(BT_SecretBag),
-       NVP(BT_SafeContentsBag),
-       NVP_END
-};
-
-static const char *typeToStr(
-       unsigned type,
-       const p12NameValuePair *table)
-{
-       while(table->name) {
-               if(table->value == type) {
-                       return table->name;
-               }
-               table++;
-       }
-       return "Unknown";
-}
-
-const char *p12BagTypeStr(
-       NSS_P12_SB_Type type)
-{
-       return typeToStr(type, p12BagTypeNames);
-}
-
-const char *p7ContentInfoTypeStr(
-       NSS_P7_CI_Type type)
-{
-       return typeToStr(type, p7CITypeNames);
-}
-
-/*
- * OIDS for P12 and PKCS5 v1.5 (PBES1) encrypt and decrypt map to the following
- * attributes.
- */
-typedef struct {
-       const CSSM_OID          *oid;
-       CSSM_ALGORITHMS         keyAlg;         // e.g., CSSM_ALGID_DES
-       CSSM_ALGORITHMS         encrAlg;        // e.g., CSSM_ALGID_3DES_3KEY_EDE
-       CSSM_ALGORITHMS         pbeHashAlg;     // SHA1 or MD5
-       uint32                          keySizeInBits;
-       uint32                          blockSizeInBytes;       // for IV, optional
-       CSSM_PADDING            padding;        // CSSM_PADDING_PKCS7, etc.
-       CSSM_ENCRYPT_MODE       mode;           // CSSM_ALGMODE_CBCPadIV8, etc.
-       PKCS_Which                      pkcs;           // PW_PKCS12 (for this module) or PW_PKCS5_v1_5
-} PKCSOidInfo;
-
-static const PKCSOidInfo pkcsOidInfos[] = {
-       /* PKCS12 first, the ones this module uses */
-       { 
-               &CSSMOID_PKCS12_pbeWithSHAAnd128BitRC4,
-               CSSM_ALGID_RC4,
-               CSSM_ALGID_RC4,
-               CSSM_ALGID_SHA1,
-               128,
-               0,                                      // RC4 is a stream cipher
-               CSSM_PADDING_NONE,
-               CSSM_ALGMODE_NONE,
-               PW_PKCS12
-       },
-       { 
-               &CSSMOID_PKCS12_pbeWithSHAAnd40BitRC4,
-               CSSM_ALGID_RC4,
-               CSSM_ALGID_RC4,
-               CSSM_ALGID_SHA1,
-               40,
-               0,                                      // RC4 is a stream cipher
-               CSSM_PADDING_NONE,
-               CSSM_ALGMODE_NONE,
-               PW_PKCS12
-       },
-       { 
-               &CSSMOID_PKCS12_pbeWithSHAAnd3Key3DESCBC,
-               CSSM_ALGID_3DES_3KEY,
-               CSSM_ALGID_3DES_3KEY_EDE,
-               CSSM_ALGID_SHA1,
-               64 * 3,
-               8,      
-               CSSM_PADDING_PKCS7,
-               CSSM_ALGMODE_CBCPadIV8,
-               PW_PKCS12
-       },
-       { 
-               &CSSMOID_PKCS12_pbeWithSHAAnd2Key3DESCBC,
-               CSSM_ALGID_3DES_2KEY,
-               CSSM_ALGID_3DES_2KEY_EDE,
-               CSSM_ALGID_SHA1,
-               64 * 2,
-               8,      
-               CSSM_PADDING_PKCS7,
-               CSSM_ALGMODE_CBCPadIV8,
-               PW_PKCS12
-       },
-       { 
-               &CSSMOID_PKCS12_pbeWithSHAAnd128BitRC2CBC,
-               CSSM_ALGID_RC2,
-               CSSM_ALGID_RC2,
-               CSSM_ALGID_SHA1,
-               128,
-               8,      
-               CSSM_PADDING_PKCS7,
-               CSSM_ALGMODE_CBCPadIV8,
-               PW_PKCS12
-       },
-       { 
-               &CSSMOID_PKCS12_pbewithSHAAnd40BitRC2CBC,
-               CSSM_ALGID_RC2,
-               CSSM_ALGID_RC2,
-               CSSM_ALGID_SHA1,
-               40,
-               8,      
-               CSSM_PADDING_PKCS7,
-               CSSM_ALGMODE_CBCPadIV8,
-               PW_PKCS12
-       },
-       
-       /* PKCS5 v1.5, used for SecImportExport module */
-       {
-               &CSSMOID_PKCS5_pbeWithMD2AndDES,
-               CSSM_ALGID_DES,
-               CSSM_ALGID_DES,
-               CSSM_ALGID_MD2,
-               64,
-               8,
-               CSSM_PADDING_PKCS7,
-               CSSM_ALGMODE_CBCPadIV8,
-               PW_PKCS5_v1_5
-       },
-       {
-               &CSSMOID_PKCS5_pbeWithMD2AndRC2,
-               CSSM_ALGID_RC2,
-               CSSM_ALGID_RC2,
-               CSSM_ALGID_MD2,
-               64,
-               8,
-               CSSM_PADDING_PKCS7,
-               CSSM_ALGMODE_CBCPadIV8,
-               PW_PKCS5_v1_5
-       },
-       {
-               &CSSMOID_PKCS5_pbeWithMD5AndDES,
-               CSSM_ALGID_DES,
-               CSSM_ALGID_DES,
-               CSSM_ALGID_MD5,
-               64,
-               8,
-               CSSM_PADDING_PKCS7,
-               CSSM_ALGMODE_CBCPadIV8,
-               PW_PKCS5_v1_5
-       },
-       {
-               &CSSMOID_PKCS5_pbeWithMD5AndRC2,
-               CSSM_ALGID_RC2,
-               CSSM_ALGID_RC2,
-               CSSM_ALGID_MD5,
-               64,
-               8,
-               CSSM_PADDING_PKCS7,
-               CSSM_ALGMODE_CBCPadIV8,
-               PW_PKCS5_v1_5
-       },
-       {
-               &CSSMOID_PKCS5_pbeWithSHA1AndDES,
-               CSSM_ALGID_DES,
-               CSSM_ALGID_DES,
-               CSSM_ALGID_SHA1,
-               64,
-               8,
-               CSSM_PADDING_PKCS7,
-               CSSM_ALGMODE_CBCPadIV8,
-               PW_PKCS5_v1_5
-       },
-       {
-               &CSSMOID_PKCS5_pbeWithSHA1AndRC2,
-               CSSM_ALGID_RC2,
-               CSSM_ALGID_RC2,
-               CSSM_ALGID_SHA1,
-               64,
-               8,
-               CSSM_PADDING_PKCS7,
-               CSSM_ALGMODE_CBCPadIV8,
-               PW_PKCS5_v1_5
-       },
-       
-       /* finally one for PKCS5 v2.0, which has its own means of 
-        * cooking up all the parameters */
-       {
-               &CSSMOID_PKCS5_PBES2,
-               CSSM_ALGID_NONE,
-               CSSM_ALGID_NONE,
-               CSSM_ALGID_NONE,
-               0, 0, 0, 0, 
-               PW_PKCS5_v2
-       }
-};
-
-#define NUM_PKCS_OID_INFOS (sizeof(pkcsOidInfos) / sizeof(pkcsOidInfos[1]))
-
-/* map an OID to the components */
-/* returns false if OID not found */
-
-/* 
- * NOTE: as of March 8 2004 this is also used by the SecImportExport
- * module...not just PKCS12!
- */
-bool pkcsOidToParams(
-       const CSSM_OID          *oid,
-       CSSM_ALGORITHMS         &keyAlg,                // e.g., CSSM_ALGID_DES
-       CSSM_ALGORITHMS         &encrAlg,               // e.g., CSSM_ALGID_3DES_3KEY_EDE
-       CSSM_ALGORITHMS         &pbeHashAlg,    // SHA1 or MD5
-       uint32                          &keySizeInBits,
-       uint32                          &blockSizeInBytes,      // for IV, optional
-       CSSM_PADDING            &padding,               // CSSM_PADDING_PKCS7, etc.
-       CSSM_ENCRYPT_MODE       &mode,                  // CSSM_ALGMODE_CBCPadIV8, etc.
-       PKCS_Which                      &pkcs)                  // PW_PKCS5_v1_5 or PW_PKCS12
-{
-       const PKCSOidInfo *info = pkcsOidInfos;
-       pkcs = PW_None;
-       
-       for(unsigned dex=0; dex<NUM_PKCS_OID_INFOS; dex++) {
-               if(nssCompareCssmData(oid, info->oid)) {
-                       keyAlg                   = info->keyAlg;
-                       encrAlg                  = info->encrAlg;
-                       pbeHashAlg               = info->pbeHashAlg;
-                       keySizeInBits    = info->keySizeInBits;
-                       blockSizeInBytes = info->blockSizeInBytes;
-                       padding                  = info->padding;
-                       mode                     = info->mode;
-                       pkcs                     = info->pkcs;
-                       return true;
-               }
-               info++;
-       }
-       return false;
-}
-
-/*
- * Verify MAC on an existing PFX.  
- */
-CSSM_RETURN p12VerifyMac(
-       const NSS_P12_DecodedPFX        &pfx,
-       CSSM_CSP_HANDLE                         cspHand,
-       const CSSM_DATA                         *pwd,   // unicode, double null terminated
-       const CSSM_KEY                          *passKey,
-       SecNssCoder                                     &coder) // for temp mallocs
-{
-       if(pfx.macData == NULL) {
-               return CSSMERR_CSP_INVALID_SIGNATURE;
-       }
-       NSS_P12_MacData &macData = *pfx.macData;
-       NSS_P7_DigestInfo &digestInfo  = macData.mac;
-       CSSM_OID &algOid = digestInfo.digestAlgorithm.algorithm;
-       CSSM_ALGORITHMS macAlg;
-       if(!cssmOidToAlg(&algOid, &macAlg)) {
-               return CSSMERR_CSP_INVALID_ALGORITHM;
-       }
-       uint32 iterCount = 0;
-       CSSM_DATA &citer = macData.iterations;
-       if(!p12DataToInt(citer, iterCount)) {
-               return CSSMERR_CSP_INVALID_ATTR_ROUNDS;
-       }
-       if(iterCount == 0) {
-               /* optional, default 1 */
-               iterCount = 1;
-       }
-
-       /*
-        * In classic fashion, the PKCS12 spec now says:
-        *
-        *      When password integrity mode is used to secure a PFX PDU, 
-        *      an SHA-1 HMAC is computed on the BER-encoding of the contents 
-        *      of the content field of the authSafe field in the PFX PDU.
-        *
-        * So here we go.
-        */
-       CSSM_DATA genMac;
-       CSSM_RETURN crtn = p12GenMac(cspHand, *pfx.authSafe.content.data, 
-               macAlg, iterCount, macData.macSalt, pwd, passKey, coder, genMac);
-       if(crtn) {
-               return crtn;
-       }
-       if(nssCompareCssmData(&genMac, &digestInfo.digest)) {
-               return CSSM_OK;
-       }
-       else {
-               return CSSMERR_CSP_VERIFY_FAILED;
-       }
-}
-
-/* we generate 8 random bytes of salt */
-#define P12_SALT_LEN           8
-
-void p12GenSalt(
-       CSSM_DATA &salt,
-       SecNssCoder &coder)
-{
-       DevRandomGenerator rng;
-       coder.allocItem(salt, P12_SALT_LEN);
-       rng.random(salt.Data, P12_SALT_LEN);
-}
-
-/* 
- * Generate random label string to allow associating an imported private
- * key with a cert.
- */
-void p12GenLabel(
-       CSSM_DATA &label,
-       SecNssCoder &coder)
-{
-       /* first a random uint32 */
-       uint8 d[4];
-       DevRandomGenerator rng;
-       rng.random(d, 4);
-       CSSM_DATA cd = {4, d};
-       uint32 i;
-       p12DataToInt(cd, i);
-       
-       /* sprintf that into a real string */
-       coder.allocItem(label, 9);
-       memset(label.Data, 0, 9);
-       sprintf((char *)label.Data, "%08X", (unsigned)i);
-}
-
-/* NULL algorithm parameters */
-
-static const uint8 nullAlg[2] = {SEC_ASN1_NULL, 0};
-
-void p12NullAlgParams(
-       CSSM_X509_ALGORITHM_IDENTIFIER &algId)
-{
-       CSSM_DATA &p = algId.parameters;
-       p.Data = (uint8 *)nullAlg;
-       p.Length = 2;
-}
-
-/*
- * Free memory via specified plugin's app-level allocator
- */
-void freeCssmMemory(
-       CSSM_HANDLE     hand,
-       void                    *p)
-{
-       CSSM_API_MEMORY_FUNCS memFuncs;
-       CSSM_RETURN crtn = CSSM_GetAPIMemoryFunctions(hand, &memFuncs);
-       if(crtn) {
-               p12LogCssmError("CSSM_GetAPIMemoryFunctions", crtn);
-               /* oh well, leak and continue */
-               return;
-       }
-       memFuncs.free_func(p, memFuncs.AllocRef);
-}
-
-/*
- * Find private key by label, modify its Label attr to be the
- * hash of the associated public key. 
- * Also optionally re-sets the key's PrintName attribute; used to reset
- * this attr from the random label we create when first unwrap it 
- * to the friendly name we find later after parsing attributes.
- * Detection of a duplicate key when updating the key's attributes
- * results in a lookup of the original key and returning it in
- * foundKey.
- */
-CSSM_RETURN p12SetPubKeyHash(
-       CSSM_CSP_HANDLE         cspHand,                // where the key lives
-       CSSM_DL_DB_HANDLE       dlDbHand,               // ditto
-       CSSM_DATA                       &keyLabel,              // for DB lookup
-       CSSM_DATA_PTR           newPrintName,   // optional
-       SecNssCoder                     &coder,                 // for mallocing newLabel
-       CSSM_DATA                       &newLabel,              // RETURNED with label as hash
-       CSSM_KEY_PTR            &foundKey)              // RETURNED
-{
-       CSSM_QUERY                                              query;
-       CSSM_SELECTION_PREDICATE                predicate;
-       CSSM_DB_UNIQUE_RECORD_PTR               record = NULL;
-       CSSM_RETURN                                             crtn;
-       CSSM_HANDLE                                             resultHand = 0;
-       CSSM_DATA                                               keyData = {0, NULL};
-       CSSM_CC_HANDLE                                  ccHand = 0;
-       CSSM_KEY_PTR                                    privKey = NULL;
-       CSSM_DATA_PTR                                   keyDigest = NULL;
-       
-       assert(cspHand != 0);
-       query.RecordType = CSSM_DL_DB_RECORD_PRIVATE_KEY;
-       query.Conjunctive = CSSM_DB_NONE;
-       query.NumSelectionPredicates = 1;
-       predicate.DbOperator = CSSM_DB_EQUAL;
-       
-       predicate.Attribute.Info.AttributeNameFormat = 
-               CSSM_DB_ATTRIBUTE_NAME_AS_STRING;
-       predicate.Attribute.Info.Label.AttributeName = 
-               (char*) P12_KEY_ATTR_LABEL_AND_HASH;
-       predicate.Attribute.Info.AttributeFormat = 
-               CSSM_DB_ATTRIBUTE_FORMAT_BLOB;
-       /* hope this cast is OK */
-       predicate.Attribute.Value = &keyLabel;
-       query.SelectionPredicate = &predicate;
-       
-       query.QueryLimits.TimeLimit = 0;        // FIXME - meaningful?
-       query.QueryLimits.SizeLimit = 1;        // FIXME - meaningful?
-       query.QueryFlags = CSSM_QUERY_RETURN_DATA;      
-
-       /* build Record attribute with one or two attrs */
-       CSSM_DB_RECORD_ATTRIBUTE_DATA recordAttrs;
-       CSSM_DB_ATTRIBUTE_DATA attr[2];
-       attr[0].Info.AttributeNameFormat = CSSM_DB_ATTRIBUTE_NAME_AS_STRING;
-       attr[0].Info.Label.AttributeName = (char*) P12_KEY_ATTR_LABEL_AND_HASH;
-       attr[0].Info.AttributeFormat = CSSM_DB_ATTRIBUTE_FORMAT_BLOB;
-       if(newPrintName) {
-               attr[1].Info.AttributeNameFormat = CSSM_DB_ATTRIBUTE_NAME_AS_STRING;
-               attr[1].Info.Label.AttributeName = (char*) P12_KEY_ATTR_PRINT_NAME;
-               attr[1].Info.AttributeFormat = CSSM_DB_ATTRIBUTE_FORMAT_BLOB;
-       }
-       recordAttrs.DataRecordType = CSSM_DL_DB_RECORD_PRIVATE_KEY;
-       recordAttrs.NumberOfAttributes = newPrintName ? 2 : 1;
-       recordAttrs.AttributeData = attr;
-       
-       crtn = CSSM_DL_DataGetFirst(dlDbHand,
-               &query,
-               &resultHand,
-               &recordAttrs,
-               &keyData,                       // theData
-               &record);
-       /* abort only on success */
-       if(crtn != CSSM_OK) {
-               p12LogCssmError("CSSM_DL_DataGetFirst", crtn);
-               p12ErrorLog("***p12SetPubKeyHash: can't find private key\n");
-               return crtn;
-       }
-       /* subsequent errors to errOut: */
-       if(keyData.Data == NULL) {
-               p12ErrorLog("***p12SetPubKeyHash: private key lookup failure\n");
-               crtn = CSSMERR_CSSM_INTERNAL_ERROR;
-               goto errOut;
-       }
-       privKey = (CSSM_KEY_PTR)keyData.Data;
-       
-       /* public key hash via passthrough - works on any key, any CSP/CSPDL.... */
-       /*
-        * Warning! This relies on the current default ACL meaning "allow this
-        * current app to access this private key" since we created the key. 
-        */
-       crtn = CSSM_CSP_CreatePassThroughContext(cspHand, privKey, &ccHand);
-       if(crtn) {
-               p12LogCssmError("CSSM_CSP_CreatePassThroughContext", crtn);
-               goto errOut;
-       }
-       crtn = CSSM_CSP_PassThrough(ccHand,
-               CSSM_APPLECSP_KEYDIGEST,
-               NULL,
-               (void **)&keyDigest);
-       if(crtn) {
-               p12LogCssmError("CSSM_CSP_PassThrough", crtn);
-               goto errOut;
-       }
-
-       /* 
-        * Replace Label attr data with hash.
-        * NOTE: the module which allocated this attribute data - a DL -
-        * was loaded and attached by out client layer, not by us. Thus 
-        * we can't use the memory allocator functions *we* used when 
-        * attaching to the CSP - we have to use the ones
-        * which the client registered with the DL.
-        */
-       freeCssmMemory(dlDbHand.DLHandle, attr[0].Value->Data);
-       freeCssmMemory(dlDbHand.DLHandle, attr[0].Value);
-       if(newPrintName) {
-               freeCssmMemory(dlDbHand.DLHandle, attr[1].Value->Data);
-               freeCssmMemory(dlDbHand.DLHandle, attr[1].Value);
-       }
-       /* modify key attributes */
-       attr[0].Value = keyDigest;
-       if(newPrintName) {
-               attr[1].Value = newPrintName;
-       }
-       crtn = CSSM_DL_DataModify(dlDbHand,
-                       CSSM_DL_DB_RECORD_PRIVATE_KEY,
-                       record,
-                       &recordAttrs,
-            NULL,                              // DataToBeModified
-                       CSSM_DB_MODIFY_ATTRIBUTE_REPLACE);
-       switch(crtn) {
-               case CSSM_OK:
-                       /* give caller the key's new label */
-                       coder.allocCopyItem(*keyDigest, newLabel);
-                       break;
-               default:
-                       p12LogCssmError("CSSM_DL_DataModify", crtn);
-                       break;
-               case CSSMERR_DL_INVALID_UNIQUE_INDEX_DATA:
-               {
-                       /* 
-                        * Special case: dup private key. The label we just tried to modify is 
-                        * the public key hash so we can be confident that this really is a dup. 
-                        * Delete it, look up the original, and return the original to caller. 
-                        */ 
-                       CSSM_RETURN drtn = CSSM_DL_DataDelete(dlDbHand, record);
-                       if(drtn) {
-                               p12LogCssmError("CSSM_DL_DataDelete on dup key", drtn);
-                               crtn = drtn;
-                               break;
-                       }
-
-                       /* Free items created in last search */
-                       CSSM_DL_DataAbortQuery(dlDbHand, resultHand);
-                       resultHand = 0;
-                       CSSM_DL_FreeUniqueRecord(dlDbHand, record);
-                       record = NULL;
-                       
-                       /* lookup by label as public key hash this time */
-                       predicate.Attribute.Value = keyDigest;
-                       drtn = CSSM_DL_DataGetFirst(dlDbHand,
-                               &query,
-                               &resultHand,
-                               NULL,                           // no attrs this time
-                               &keyData,               
-                               &record);
-                       if(drtn) {
-                               p12LogCssmError("CSSM_DL_DataGetFirst on original key", crtn);
-                               crtn = drtn;
-                               break;
-                       }
-                       foundKey = (CSSM_KEY_PTR)keyData.Data;
-                       /* give caller the key's actual label */
-                       coder.allocCopyItem(*keyDigest, newLabel);
-                       break;
-               }
-       }
-       
-errOut:
-       /* free resources */
-       if(resultHand) {
-               CSSM_DL_DataAbortQuery(dlDbHand, resultHand);
-       }
-       if(record) {
-               CSSM_DL_FreeUniqueRecord(dlDbHand, record);
-       }
-       if(ccHand) {
-               CSSM_DeleteContext(ccHand);
-       }
-       if(privKey) {
-               /* key created by the CSPDL */
-               CSSM_FreeKey(cspHand, NULL, privKey, CSSM_FALSE);
-               freeCssmMemory(dlDbHand.DLHandle, privKey);
-       }
-       if(keyDigest)  {
-               /* mallocd by someone else's CSP */
-               freeCssmMemory(cspHand, keyDigest->Data);
-               freeCssmMemory(cspHand, keyDigest);
-       }
-       return crtn;
-}
-
-/*
- * Given a context specified via a CSSM_CC_HANDLE, add a new
- * CSSM_CONTEXT_ATTRIBUTE to the context as specified by AttributeType,
- * AttributeLength, and an untyped pointer.
- */
-CSSM_RETURN p12AddContextAttribute(CSSM_CC_HANDLE CCHandle,
-       uint32 AttributeType,
-       uint32 AttributeLength,
-       const void *AttributePtr)
-{
-       CSSM_CONTEXT_ATTRIBUTE          newAttr;        
-       CSSM_RETURN                                     crtn;
-       
-       newAttr.AttributeType     = AttributeType;
-       newAttr.AttributeLength   = AttributeLength;
-       newAttr.Attribute.Data    = (CSSM_DATA_PTR)AttributePtr;
-       crtn = CSSM_UpdateContextAttributes(CCHandle, 1, &newAttr);
-       if(crtn) {
-               p12LogCssmError("CSSM_UpdateContextAttributes", crtn);
-       }
-       return crtn;
-}
-
-/*
- * Find private key by specified label, delete it.
- */
-CSSM_RETURN p12DeleteKey(
-       CSSM_DL_DB_HANDLE dlDbHand, 
-       const CSSM_DATA &keyLabel)
-{
-       CSSM_QUERY                                              query;
-       CSSM_SELECTION_PREDICATE                predicate;
-       CSSM_DB_UNIQUE_RECORD_PTR               record = NULL;
-       CSSM_RETURN                                             crtn;
-       CSSM_HANDLE                                             resultHand = 0;
-       
-       query.RecordType = CSSM_DL_DB_RECORD_PRIVATE_KEY;
-       query.Conjunctive = CSSM_DB_NONE;
-       query.NumSelectionPredicates = 1;
-       predicate.DbOperator = CSSM_DB_EQUAL;
-       
-       predicate.Attribute.Info.AttributeNameFormat = 
-               CSSM_DB_ATTRIBUTE_NAME_AS_STRING;
-       predicate.Attribute.Info.Label.AttributeName = 
-               (char*) P12_KEY_ATTR_LABEL_AND_HASH;
-       predicate.Attribute.Info.AttributeFormat = 
-               CSSM_DB_ATTRIBUTE_FORMAT_BLOB;
-       predicate.Attribute.Value = const_cast<CSSM_DATA_PTR>(&keyLabel);
-       
-       query.SelectionPredicate = &predicate;
-       query.QueryLimits.TimeLimit = 0;
-       query.QueryLimits.SizeLimit = 1;
-       query.QueryFlags = 0;
-
-       crtn = CSSM_DL_DataGetFirst(dlDbHand,
-               &query,
-               &resultHand,
-               NULL,                   // attrs - don't need 'em
-               NULL,                   // theData - don't need it
-               &record);
-       /* abort only on success */
-       if(crtn) {
-               p12LogCssmError("CSSM_DL_DataGetFirst", crtn);
-               p12ErrorLog("***p12DeleteKey: can't find private key\n");
-               return crtn;
-       }
-
-       crtn = CSSM_DL_DataDelete(dlDbHand, record);
-       if(crtn) {
-               p12LogCssmError("CSSM_DL_DataDelete", crtn);
-               p12ErrorLog("***p12DeleteKey: can't delete private key\n");
-       }
-       
-       CSSM_DL_DataAbortQuery(dlDbHand, resultHand);
-       CSSM_DL_FreeUniqueRecord(dlDbHand, record);
-       return crtn;
-}
-
-/* convert App passphrase to array of chars used in P12 PBE */
-void p12ImportPassPhrase(
-       CFStringRef             inPhrase,
-       SecNssCoder             &coder,
-       CSSM_DATA               &outPhrase)
-{
-       CFDataRef cfData = CFStringCreateExternalRepresentation(NULL,
-               inPhrase, kCFStringEncodingUTF8, 0);
-       if(cfData == NULL) {
-               p12ErrorLog("***p12ImportPassPhrase: can't convert passphrase to UTF8\n");
-               MacOSError::throwMe(errSecParam);
-       }
-       CFIndex keyLen = CFDataGetLength(cfData);
-       coder.allocItem(outPhrase, keyLen);
-       memmove(outPhrase.Data, CFDataGetBytePtr(cfData), keyLen);
-       CFRelease(cfData);
-}