void ItemImpl::copyPersistentReference(CFDataRef &outDataRef, bool isSecIdentityRef) { if (secd_PersistentRef) { outDataRef = secd_PersistentRef; return; } StLock<Mutex>_(mMutex); // item must be in a keychain and have a primary key to be persistent if (!mKeychain || !mPrimaryKey) { MacOSError::throwMe(errSecItemNotFound); } DLDbIdentifier dlDbIdentifier = mKeychain->dlDbIdentifier(); DLDbIdentifier newDlDbIdentifier(dlDbIdentifier.ssuid(), DLDbListCFPref::AbbreviatedPath(mKeychain->name()).c_str(), dlDbIdentifier.dbLocation()); NameValueDictionary dict; NameValueDictionary::MakeNameValueDictionaryFromDLDbIdentifier(newDlDbIdentifier, dict); CssmData* pKey = mPrimaryKey; dict.Insert (new NameValuePair(ITEM_KEY, *pKey)); if (isSecIdentityRef) { uint32_t value = -1; CssmData valueData((void*)&value, sizeof(value)); dict.Insert (new NameValuePair(IDENTITY_KEY, valueData)); } // flatten the NameValueDictionary CssmData dictData; dict.Export(dictData); outDataRef = ::CFDataCreate(kCFAllocatorDefault, dictData.Data, dictData.Length); free (dictData.Data); }
Item ItemImpl::makeFromPersistentReference(const CFDataRef persistentRef, bool *isIdentityRef) { CssmData dictData((void*)::CFDataGetBytePtr(persistentRef), ::CFDataGetLength(persistentRef)); NameValueDictionary dict(dictData); Keychain keychain; Item item = (ItemImpl *) NULL; if (isIdentityRef) { *isIdentityRef = (dict.FindByName(IDENTITY_KEY) != 0) ? true : false; } // make sure we have a database identifier if (dict.FindByName(SSUID_KEY) != 0) { DLDbIdentifier dlDbIdentifier = NameValueDictionary::MakeDLDbIdentifierFromNameValueDictionary(dict); DLDbIdentifier newDlDbIdentifier(dlDbIdentifier.ssuid(), DLDbListCFPref::ExpandTildesInPath(dlDbIdentifier.dbName()).c_str(), dlDbIdentifier.dbLocation()); keychain = globals().storageManager.keychain(newDlDbIdentifier); const NameValuePair* aDictItem = dict.FindByName(ITEM_KEY); if (aDictItem && keychain) { PrimaryKey primaryKey(aDictItem->Value()); item = keychain->item(primaryKey); } } KCThrowIf_( !item, errSecItemNotFound ); return item; }