/* * Free memory via specified plugin's app-level allocator */ void impExpFreeCssmMemory( CSSM_HANDLE hand, void *p) { CSSM_API_MEMORY_FUNCS memFuncs; CSSM_RETURN crtn = CSSM_GetAPIMemoryFunctions(hand, &memFuncs); if(crtn) { return; } memFuncs.free_func(p, memFuncs.AllocRef); }
/* * 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); }
/* * Free memory via specified plugin's app-level allocator */ void tpFreePluginMemory( CSSM_HANDLE hand, void *p) { CSSM_API_MEMORY_FUNCS memFuncs; CSSM_RETURN crtn = CSSM_GetAPIMemoryFunctions(hand, &memFuncs); if(crtn) { tpErrorLog("CSSM_GetAPIMemoryFunctions failure\n"); /* oh well, leak and continue */ return; } memFuncs.free_func(p, memFuncs.AllocRef); }
CFDataRef decodePrivateKeyHeader(SecKeychainRef keychain, const FVPrivateKeyHeader &inHeader) { // kSecKeyLabel is defined in libsecurity_keychain/lib/SecKey.h SecKeychainAttribute attrs[] = { { 6 /* kSecKeyLabel */, inHeader.publicKeyHashSize, const_cast<uint8 *>(inHeader.publicKeyHash) } }; SecKeychainAttributeList attrList = { sizeof(attrs) / sizeof(SecKeychainAttribute), attrs }; CSSM_CSP_HANDLE cspHandle = 0; const CSSM_KEY *cssmKey = NULL; const CSSM_ACCESS_CREDENTIALS *accessCred = NULL; CSSM_CC_HANDLE cc = 0; SecKeychainSearchRef _searchRef; throwIfError(SecKeychainSearchCreateFromAttributes(keychain, (SecItemClass) CSSM_DL_DB_RECORD_PRIVATE_KEY, &attrList, &_searchRef)); CFRef<SecKeychainSearchRef> searchRef(_searchRef); SecKeychainItemRef _item; if (SecKeychainSearchCopyNext(searchRef, &_item) != 0) { return NULL; // XXX possibly should throw here? } CFRef<SecKeyRef> keyItem(reinterpret_cast<SecKeyRef>(_item)); throwIfError(SecKeyGetCSPHandle(keyItem, &cspHandle)); throwIfError(SecKeyGetCSSMKey(keyItem, &cssmKey)); throwIfError(SecKeyGetCredentials(keyItem, CSSM_ACL_AUTHORIZATION_DECRYPT, kSecCredentialTypeDefault, &accessCred)); throwIfError(CSSM_CSP_CreateAsymmetricContext(cspHandle, cssmKey->KeyHeader.AlgorithmId, accessCred, cssmKey, CSSM_PADDING_PKCS1, &cc)); CFDataRef result; try { CssmMemoryFunctions memFuncs; throwIfError(CSSM_GetAPIMemoryFunctions(cspHandle, &memFuncs)); CssmMemoryFunctionsAllocator allocator(memFuncs); const CssmData cipherBuf(const_cast<uint8 *>(inHeader.encryptedBlob), inHeader.encryptedBlobSize); CssmAutoData clearBuf(allocator); CssmAutoData remData(allocator); size_t bytesDecrypted; CSSM_RETURN crx = CSSM_DecryptData(cc, &cipherBuf, 1, &clearBuf.get(), 1, &bytesDecrypted, &remData.get()); secinfo("FDERecovery", "decodePrivateKeyHeader: CSSM_DecryptData result: %d", crx); throwIfError(crx); // throwIfError(CSSM_DecryptData(cc, &cipherBuf, 1, &clearBuf.get(), 1, &bytesDecrypted, &remData.get())); clearBuf.length(bytesDecrypted); // rawKey.copy(clearBuf.get()); result = CFDataCreate(kCFAllocatorDefault, (const UInt8 *)clearBuf.get().data(), clearBuf.get().length()); // result = parseKeyBlob(clearBuf.get()); } catch(...) { CSSM_DeleteContext(cc); throw; } throwIfError(CSSM_DeleteContext(cc)); return result; }
/* * Find private key by label, modify its Label attr to be the * hash of the associated public key. */ static CSSM_RETURN setPubKeyHash( CSSM_CSP_HANDLE cspHand, CSSM_DL_DB_HANDLE dlDbHand, const CSSM_KEY *pubOrPrivKey, // to get hash; raw or ref/CSPDL const char *keyLabel) // look up by this { CSSM_QUERY query; CSSM_SELECTION_PREDICATE predicate; CSSM_DB_UNIQUE_RECORD_PTR record = NULL; CSSM_RETURN crtn; CSSM_DATA labelData; CSSM_HANDLE resultHand; labelData.Data = (uint8 *)keyLabel; labelData.Length = strlen(keyLabel) + 1; // incl. NULL 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 = "Label"; predicate.Attribute.Info.AttributeFormat = CSSM_DB_ATTRIBUTE_FORMAT_BLOB; predicate.Attribute.Value = &labelData; query.SelectionPredicate = &predicate; query.QueryLimits.TimeLimit = 0; query.QueryLimits.SizeLimit = 1; query.QueryFlags = 0; /* build Record attribute with one attr */ CSSM_DB_RECORD_ATTRIBUTE_DATA recordAttrs; CSSM_DB_ATTRIBUTE_DATA attr; attr.Info.AttributeNameFormat = CSSM_DB_ATTRIBUTE_NAME_AS_STRING; attr.Info.Label.AttributeName = "Label"; attr.Info.AttributeFormat = CSSM_DB_ATTRIBUTE_FORMAT_BLOB; recordAttrs.DataRecordType = CSSM_DL_DB_RECORD_PRIVATE_KEY; recordAttrs.NumberOfAttributes = 1; recordAttrs.AttributeData = &attr; crtn = CSSM_DL_DataGetFirst(dlDbHand, &query, &resultHand, &recordAttrs, NULL, // hopefully optional ...theData, &record); /* abort only on success */ if(crtn != CSSM_OK) { sec_error("CSSM_DL_DataGetFirst: setPubKeyHash: can't find private key: %s", sec_errstr(crtn)); return crtn; } /* * If specified key is a ref key, do NULL unwrap for use with raw CSP. * If the CSPDL and SecurityServer support the key digest passthrough * this is unnecessary. */ CSSM_KEY rawKeyToDigest; if(pubOrPrivKey->KeyHeader.BlobType == CSSM_KEYBLOB_REFERENCE) { crtn = refKeyToRaw(cspHand, pubOrPrivKey, &rawKeyToDigest); if(crtn) { sec_error("setPubKeyHash: Error converting public key to raw format: %s", sec_errstr(crtn)); return crtn; } } else { /* use as is */ rawKeyToDigest = *pubOrPrivKey; } /* connect to raw CSP */ CSSM_CSP_HANDLE rawCspHand = srCspStartup(CSSM_TRUE); if(rawCspHand == 0) { printf("***Error connecting to raw CSP; aborting.\n"); return -1; } /* calculate hash of pub key from private or public part */ CSSM_DATA_PTR keyDigest = NULL; CSSM_CC_HANDLE ccHand; crtn = CSSM_CSP_CreatePassThroughContext(rawCspHand, &rawKeyToDigest, &ccHand); if(ccHand == 0) { sec_error("CSSM_CSP_CreatePassThroughContext: Error calculating public key hash. Aborting: %s", sec_errstr(crtn)); return -1; } crtn = CSSM_CSP_PassThrough(ccHand, CSSM_APPLECSP_KEYDIGEST, NULL, (void **)&keyDigest); if(crtn) { sec_error("CSSM_CSP_PassThrough(PUBKEYHASH): Error calculating public key hash. Aborting: %s", sec_errstr(crtn)); return crtn; } if(pubOrPrivKey->KeyHeader.BlobType == CSSM_KEYBLOB_REFERENCE) { /* created in refKeyToRaw().... */ CSSM_FreeKey(cspHand, NULL, &rawKeyToDigest, CSSM_FALSE); } CSSM_DeleteContext(ccHand); CSSM_ModuleDetach(rawCspHand); /* * Replace Label attr data with hash. * NOTE: the module which allocated this attribute data - a DL - * was loaded and attached by the Sec layer, not by us. Thus * we can't use the memory allocator functions *we* used when * attaching to the CSPDL - we have to use the ones * which the Sec layer registered with the DL. */ CSSM_API_MEMORY_FUNCS memFuncs; crtn = CSSM_GetAPIMemoryFunctions(dlDbHand.DLHandle, &memFuncs); if(crtn) { sec_error("CSSM_GetAPIMemoryFunctions(DLHandle): Error: %s", sec_errstr(crtn)); /* oh well, leak and continue */ } else { memFuncs.free_func(attr.Value->Data, memFuncs.AllocRef); memFuncs.free_func(attr.Value, memFuncs.AllocRef); } attr.Value = keyDigest; /* modify key attributes */ crtn = CSSM_DL_DataModify(dlDbHand, CSSM_DL_DB_RECORD_PRIVATE_KEY, record, &recordAttrs, NULL, // DataToBeModified CSSM_DB_MODIFY_ATTRIBUTE_REPLACE); if(crtn) { sec_error("CSSM_DL_DataModify(PUBKEYHASH): Error setting public key hash. Aborting: %s", sec_errstr(crtn)); return crtn; } crtn = CSSM_DL_DataAbortQuery(dlDbHand, resultHand); if(crtn) { sec_error("CSSM_DL_DataAbortQuery: Error while stopping query: %s", sec_errstr(crtn)); /* let's keep going in this case */ } crtn = CSSM_DL_FreeUniqueRecord(dlDbHand, record); if(crtn) { sec_error("CSSM_DL_FreeUniqueRecord: Error while freeing record: %s", sec_errstr(crtn)); /* let's keep going in this case */ crtn = CSSM_OK; } /* free resources */ if (keyDigest) { srAppFree(keyDigest->Data, NULL); srAppFree(keyDigest, NULL); } return CSSM_OK; }