X-Git-Url: https://git.saurik.com/apple/security.git/blobdiff_plain/bac41a7b9a0a9254fa30f8bb6e6038ab71a483e2..67c7378dcb8de24c86b7fedff90b4b496f2e474c:/Keychain/Keychains.cpp diff --git a/Keychain/Keychains.cpp b/Keychain/Keychains.cpp index 085b62f9..a5254468 100644 --- a/Keychain/Keychains.cpp +++ b/Keychain/Keychains.cpp @@ -31,7 +31,8 @@ #include #include #include - +#include +#include using namespace KeychainCore; using namespace CssmClient; @@ -71,7 +72,8 @@ KeychainSchemaImpl::KeychainSchemaImpl(const Db &db) RelationInfoMap &rim = mDatabaseInfoMap[relationID]; while (attributes->next(&attributeRecord, NULL, uniqueId)) { - if(CSSM_DB_ATTRIBUTE_FORMAT(attributeRecord.at(2))==CSSM_DB_ATTRIBUTE_NAME_AS_INTEGER) + // @@@ this if statement was blocking tags of different naming conventions + //if(CSSM_DB_ATTRIBUTE_FORMAT(attributeRecord.at(2))==CSSM_DB_ATTRIBUTE_NAME_AS_INTEGER) rim[attributeRecord.at(1)] = attributeRecord.at(0); } @@ -104,60 +106,64 @@ KeychainSchemaImpl::~KeychainSchemaImpl() for_each_map_delete(mPrimaryKeyInfoMap.begin(), mPrimaryKeyInfoMap.end()); } -CSSM_DB_ATTRIBUTE_FORMAT -KeychainSchemaImpl::attributeFormatFor(CSSM_DB_RECORDTYPE recordType, uint32 attributeId) const +const KeychainSchemaImpl::RelationInfoMap & +KeychainSchemaImpl::relationInfoMapFor(CSSM_DB_RECORDTYPE recordType) const { - DatabaseInfoMap::const_iterator dit = mDatabaseInfoMap.find(recordType); if (dit == mDatabaseInfoMap.end()) MacOSError::throwMe(errSecNoSuchClass); - RelationInfoMap::const_iterator rit = dit->second.find(attributeId); - if (dit == dit->second.end()) + return dit->second; +} + +bool +KeychainSchemaImpl::hasAttribute(CSSM_DB_RECORDTYPE recordType, uint32 attributeId) const +{ + const RelationInfoMap &rmap = relationInfoMapFor(recordType); + RelationInfoMap::const_iterator rit = rmap.find(attributeId); + return rit != rmap.end(); +} + +CSSM_DB_ATTRIBUTE_FORMAT +KeychainSchemaImpl::attributeFormatFor(CSSM_DB_RECORDTYPE recordType, uint32 attributeId) const +{ + const RelationInfoMap &rmap = relationInfoMapFor(recordType); + RelationInfoMap::const_iterator rit = rmap.find(attributeId); + if (rit == rmap.end()) MacOSError::throwMe(errSecNoSuchAttr); return rit->second; } CssmDbAttributeInfo -KeychainSchemaImpl::attributeInfoForTag(UInt32 tag) +KeychainSchemaImpl::attributeInfoFor(CSSM_DB_RECORDTYPE recordType, uint32 attributeId) const { CSSM_DB_ATTRIBUTE_INFO info; + info.AttributeFormat = attributeFormatFor(recordType, attributeId); + info.AttributeNameFormat = CSSM_DB_ATTRIBUTE_NAME_AS_INTEGER; + info.Label.AttributeID = attributeId; - for(DatabaseInfoMap::const_iterator dit = mDatabaseInfoMap.begin(); dit != mDatabaseInfoMap.end(); ++dit) - { - for(RelationInfoMap::const_iterator rit = dit->second.begin(); rit != dit->second.end(); ++rit) - { - if(rit->first==tag) - { - info.AttributeNameFormat = CSSM_DB_ATTRIBUTE_NAME_AS_INTEGER; - info.Label.AttributeID = rit->first; - info.AttributeFormat = rit->second; - return info; - } - } - } return info; } void -KeychainSchemaImpl::getAttributeInfoForRecordType(CSSM_DB_RECORDTYPE recordType, SecKeychainAttributeInfo **Info) +KeychainSchemaImpl::getAttributeInfoForRecordType(CSSM_DB_RECORDTYPE recordType, SecKeychainAttributeInfo **Info) const { - DatabaseInfoMap::const_iterator dit = mDatabaseInfoMap.find(recordType); - if (dit == mDatabaseInfoMap.end()) - MacOSError::throwMe(errSecNoSuchClass); + const RelationInfoMap &rmap = relationInfoMapFor(recordType); SecKeychainAttributeInfo *theList=reinterpret_cast(malloc(sizeof(SecKeychainAttributeInfo))); - UInt32 capacity=32; + UInt32 capacity=rmap.size(); UInt32 *tagBuf=reinterpret_cast(malloc(capacity*sizeof(UInt32))); UInt32 *formatBuf=reinterpret_cast(malloc(capacity*sizeof(UInt32))); UInt32 i=0; - for(RelationInfoMap::const_iterator rit = dit->second.begin(); rit != dit->second.end(); ++rit) + + for (RelationInfoMap::const_iterator rit = rmap.begin(); rit != rmap.end(); ++rit) { - if(i>=capacity) + if (i>=capacity) { - capacity*=2; + capacity *= 2; + if (capacity <= i) capacity = i + 1; tagBuf=reinterpret_cast(realloc(tagBuf, (capacity*sizeof(UInt32)))); formatBuf=reinterpret_cast(realloc(tagBuf, (capacity*sizeof(UInt32)))); } @@ -173,14 +179,11 @@ KeychainSchemaImpl::getAttributeInfoForRecordType(CSSM_DB_RECORDTYPE recordType, const CssmAutoDbRecordAttributeInfo & -KeychainSchemaImpl::primaryKeyInfosFor(CSSM_DB_RECORDTYPE recordType) +KeychainSchemaImpl::primaryKeyInfosFor(CSSM_DB_RECORDTYPE recordType) const { - PrimaryKeyInfoMap::iterator it; + PrimaryKeyInfoMap::const_iterator it; it = mPrimaryKeyInfoMap.find(recordType); - // if the primary key attributes have already been determined, - // return the cached results - if (it == mPrimaryKeyInfoMap.end()) MacOSError::throwMe(errSecNoSuchClass); // @@@ Not really but whatever. @@ -212,16 +215,26 @@ KeychainImpl::~KeychainImpl() { } +bool +KeychainImpl::operator ==(const KeychainImpl &keychain) const +{ + return dLDbIdentifier() == keychain.dLDbIdentifier(); +} + KCCursor KeychainImpl::createCursor(SecItemClass itemClass, const SecKeychainAttributeList *attrList) { - return KCCursor(DbCursor(mDb), itemClass, attrList); + StorageManager::KeychainList keychains; + keychains.push_back(Keychain(this)); + return KCCursor(keychains, itemClass, attrList); } KCCursor KeychainImpl::createCursor(const SecKeychainAttributeList *attrList) { - return KCCursor(DbCursor(mDb), attrList); + StorageManager::KeychainList keychains; + keychains.push_back(Keychain(this)); + return KCCursor(keychains, attrList); } void @@ -234,13 +247,13 @@ KeychainImpl::create(UInt32 passwordLength, const void *inPassword) } CssmAllocator &alloc = CssmAllocator::standard(); + // @@@ Share this instance - KeychainAclFactory aclFactory(alloc); - // @@@ This leaks the returned credentials const CssmData password(const_cast(inPassword), passwordLength); - const AccessCredentials *cred = aclFactory.passwordChangeCredentials(password); - + AclFactory::PasswordChangeCredentials pCreds (password, alloc); + const AccessCredentials* aa = pCreds; + // @@@ Create a nice wrapper for building the default AclEntryPrototype. TypedList subject(alloc, CSSM_ACL_SUBJECT_TYPE_ANY); AclEntryPrototype protoType(subject); @@ -249,7 +262,7 @@ KeychainImpl::create(UInt32 passwordLength, const void *inPassword) authGroup.NumberOfAuthTags = 1; authGroup.AuthTags = &tag; - const ResourceControlContext rcc(protoType, const_cast(cred)); + const ResourceControlContext rcc(protoType, const_cast(aa)); create(&rcc); } @@ -266,10 +279,14 @@ KeychainImpl::create() { CssmAllocator &alloc = CssmAllocator::standard(); // @@@ Share this instance +#ifdef OBSOLETE KeychainAclFactory aclFactory(alloc); const AccessCredentials *cred = aclFactory.keychainPromptUnlockCredentials(); - +#endif + AclFactory aclFactor; + const AccessCredentials *cred = aclFactor.unlockCred (); + // @@@ Create a nice wrapper for building the default AclEntryPrototype. TypedList subject(alloc, CSSM_ACL_SUBJECT_TYPE_ANY); AclEntryPrototype protoType(subject); @@ -422,7 +439,7 @@ KeychainImpl::status() const { // @@@ We should figure out the read/write status though a DL passthrough or some other way. // @@@ Also should locked be unlocked read only or just read-only? - return (mDb->isLocked() ? 0 : kSecUnlockStateStatus | kSecWrPermStatus) | kSecRdPermStatus; + return (mDb->isLocked() ? 0 : kSecUnlockStateStatus | kSecWritePermStatus) | kSecReadPermStatus; } bool @@ -453,11 +470,11 @@ KeychainImpl::isActive() const void KeychainImpl::add(Item &inItem) { - PrimaryKey primaryKey = inItem->add(this); + Keychain keychain(this); + PrimaryKey primaryKey = inItem->add(keychain); { StLock _(mDbItemMapLock); - // Use &* to get the item's Impl. - mDbItemMap[primaryKey] = &*inItem; + mDbItemMap[primaryKey] = inItem.get(); } KCEventNotifier::PostKeychainEvent(kSecAddEvent, this, inItem); @@ -500,6 +517,17 @@ KeychainImpl::deleteItem(Item &inoutItem) KCEventNotifier::PostKeychainEvent(kSecDeleteEvent, dLDbIdentifier(), primaryKey); } + +CssmClient::CSP +KeychainImpl::csp() +{ + if (!mDb->dl()->subserviceMask() & CSSM_SERVICE_CSP) + MacOSError::throwMe(errSecInvalidKeychain); + + SSDb ssDb(safe_cast(&(*mDb))); + return ssDb->csp(); +} + PrimaryKey KeychainImpl::makePrimaryKey(CSSM_DB_RECORDTYPE recordType, DbUniqueRecord &uniqueId) { @@ -615,9 +643,9 @@ KeychainImpl::freeAttributeInfo(SecKeychainAttributeInfo *Info) } CssmDbAttributeInfo -KeychainImpl::attributeInfoForTag(UInt32 tag) +KeychainImpl::attributeInfoFor(CSSM_DB_RECORDTYPE recordType, UInt32 tag) { - return keychainSchema()->attributeInfoForTag(tag); + return keychainSchema()->attributeInfoFor(recordType, tag); } @@ -625,7 +653,7 @@ Keychain Keychain::optional(SecKeychainRef handle) { if (handle) - return KeychainRef::required(handle); + return gTypes().keychain.required(handle); else return globals().defaultKeychain; }