X-Git-Url: https://git.saurik.com/apple/security.git/blobdiff_plain/6b200bc335dc93c5516ccb52f14bd896d8c7fad7..07691282a056c4efea71e1e505527601e8cc166b:/OSX/libsecurity_keychain/lib/KeyItem.cpp?ds=inline diff --git a/OSX/libsecurity_keychain/lib/KeyItem.cpp b/OSX/libsecurity_keychain/lib/KeyItem.cpp index c8aa467c..fed9dae0 100644 --- a/OSX/libsecurity_keychain/lib/KeyItem.cpp +++ b/OSX/libsecurity_keychain/lib/KeyItem.cpp @@ -81,6 +81,7 @@ KeyItem::operator CFTypeRef() const throw() if (mWeakSecKeyRef != NULL) { if (_CFTryRetain(mWeakSecKeyRef) == NULL) { + StMaybeLock secKeyCDSAMutex(mWeakSecKeyRef->cdsaKeyMutex); // mWeakSecKeyRef is not really valid, pointing to SecKeyRef which going to die - it is somewhere between last CFRelease and entering into mutex-protected section of SecCDSAKeyDestroy. Avoid using it, pretend that no enveloping SecKeyRef exists. But make sure that this KeyImpl is disconnected from this about-to-die SecKeyRef, because we do not want KeyImpl connected to it to be really destroyed, it will be connected to newly created SecKeyRef (see below). mWeakSecKeyRef->key = NULL; mWeakSecKeyRef = NULL; @@ -351,7 +352,17 @@ KeyItem::importTo(const Keychain &keychain, Access *newAccess, SecKeychainAttrib /* Unwrap the new key into the new Keychain. */ CssmClient::UnwrapKey unwrap(keychain->csp(), CSSM_ALGID_3DES_3KEY_EDE); - unwrap.key(wrappingKey); + if (csp()->guid() != keychain->csp()->guid()) { + // Prepare wrapping key to be usable in target keychain's CSP. + CssmClient::WrapKey exportWrapKey(csp(), CSSM_ALGID_NONE); + CssmClient::Key exportedWrappingKey(exportWrapKey(wrappingKey)); + CssmClient::UnwrapKey importUnwrapKey(keychain->csp(), CSSM_ALGID_NONE); + CssmClient::Key importedWrappingKey(importUnwrapKey(exportedWrappingKey, KeySpec(CSSM_KEYUSE_UNWRAP, 0))); + unwrap.key(importedWrappingKey); + } else { + // Wrapping key can be used directly, because source and target CSPs are the same. + unwrap.key(wrappingKey); + } unwrap.mode(CSSM_ALGMODE_ECBPad); unwrap.padding(CSSM_PADDING_PKCS7); unwrap.initVector(iv); @@ -478,7 +489,7 @@ KeyItem::key() } catch(CssmError cssme) { mKey.release(); secnotice("integrity", "error while checking integrity, denying access: %s", cssme.what()); - throw cssme; + throw; } } @@ -634,7 +645,7 @@ KeyItem::createPair( CssmError::throwMe(CSSMERR_CSSM_INVALID_POINTER); ssDb = SSDb(impl); - csp = CssmClient::CSP(keychain->csp()); + csp = keychain->csp(); // Generate a random label to use initially CssmClient::Random random(appleCsp, CSSM_ALGID_APPLE_YARROW); @@ -698,14 +709,14 @@ KeyItem::createPair( CssmClient::Key publicKey; DbAttributes pubDbAttributes; DbUniqueRecord pubUniqueId; - if (permanentPubKey) { + if (permanentPubKey && ssDb) { SSDbCursor dbPubCursor(ssDb, 1); dbPubCursor->recordType(CSSM_DL_DB_RECORD_PUBLIC_KEY); dbPubCursor->add(CSSM_DB_EQUAL, kInfoKeyLabel, label); if (!dbPubCursor->nextKey(&pubDbAttributes, publicKey, pubUniqueId)) MacOSError::throwMe(errSecItemNotFound); } else { - publicKey = CssmClient::Key(appleCsp, publicCssmKey); + publicKey = CssmClient::Key(csp, publicCssmKey); outPublicKey = new KeyItem(publicKey); freePublicKey = false; } @@ -714,14 +725,14 @@ KeyItem::createPair( CssmClient::Key privateKey; DbAttributes privDbAttributes; DbUniqueRecord privUniqueId; - if (permanentPrivKey) { + if (permanentPrivKey && ssDb) { SSDbCursor dbPrivCursor(ssDb, 1); dbPrivCursor->recordType(CSSM_DL_DB_RECORD_PRIVATE_KEY); dbPrivCursor->add(CSSM_DB_EQUAL, kInfoKeyLabel, label); if (!dbPrivCursor->nextKey(&privDbAttributes, privateKey, privUniqueId)) MacOSError::throwMe(errSecItemNotFound); } else { - privateKey = CssmClient::Key(appleCsp, privateCssmKey); + privateKey = CssmClient::Key(csp, privateCssmKey); outPrivateKey = new KeyItem(privateKey); freePrivateKey = false; } @@ -747,8 +758,8 @@ KeyItem::createPair( pubKeyHash.set(*pubKeyHashData); passThrough.allocator().free(pubKeyHashData); - auto_ptrprivDescription; - auto_ptrpubDescription; + auto_ptr privDescription; + auto_ptr pubDescription; try { privDescription.reset(new string(initialAccess->promptDescription())); pubDescription.reset(new string(initialAccess->promptDescription())); @@ -1121,7 +1132,7 @@ KeyItem::generateWithAttributes(const SecKeychainAttributeList *attrList, if (!initialAccess) { // We don't have an access, but we need to set integrity. Make an Access. - initialAccess = new Access(string(label)); + initialAccess = new Access(label.toString()); } } @@ -1398,9 +1409,9 @@ void KeyItem::modifyUniqueId(Keychain keychain, SSDb ssDb, DbUniqueRecord& uniqu } try { - secnotice("integrity", "modifying unique id"); + secinfo("integrity", "modifying unique id"); uniqueId->modify(recordType, &newDbAttributes, NULL, CSSM_DB_MODIFY_ATTRIBUTE_REPLACE); - secnotice("integrity", "done modifying unique id"); + secinfo("integrity", "done modifying unique id"); } catch(CssmError e) { // Just in case something went wrong, clean up after this add uniqueId->deleteRecord();