X-Git-Url: https://git.saurik.com/apple/security.git/blobdiff_plain/5dd5f9ec28f304ca377c42fd7f711d6cf12b90e1..5c19dc3ae3bd8e40a9c028b0deddd50ff337692c:/Security/libsecurity_pkcs12/lib/pkcs12Utils.cpp diff --git a/Security/libsecurity_pkcs12/lib/pkcs12Utils.cpp b/Security/libsecurity_pkcs12/lib/pkcs12Utils.cpp deleted file mode 100644 index 7ad4593c..00000000 --- a/Security/libsecurity_pkcs12/lib/pkcs12Utils.cpp +++ /dev/null @@ -1,832 +0,0 @@ -/* - * Copyright (c) 2003-2004,2011-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@ - */ - -/* - * pkcs12Utils.cpp - */ - -#include "pkcs12Utils.h" -#include -#include "pkcs7Templates.h" -#include "pkcs12Templates.h" -#include "pkcs12Crypto.h" -#include "pkcs12Debug.h" -#include -#include -#include -#include -#include -#include -#include -#include - -/* 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 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>= 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(); - 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; dexoid)) { - 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(&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); -}