X-Git-Url: https://git.saurik.com/apple/security.git/blobdiff_plain/80e2389990082500d76eb566d4946be3e786c3ef..d8f41ccd20de16f8ebe2ccc84d47bf1cb2b26bbb:/libsecurity_apple_cspdl/lib/SSDLSession.cpp diff --git a/libsecurity_apple_cspdl/lib/SSDLSession.cpp b/libsecurity_apple_cspdl/lib/SSDLSession.cpp deleted file mode 100644 index cde4301a..00000000 --- a/libsecurity_apple_cspdl/lib/SSDLSession.cpp +++ /dev/null @@ -1,1448 +0,0 @@ -/* - * Copyright (c) 2000-2001 Apple Computer, Inc. All Rights Reserved. - * - * The contents of this file constitute Original Code as defined in and are - * subject to the Apple Public Source License Version 1.2 (the 'License'). - * You may not use this file except in compliance with the License. Please obtain - * a copy of the License at http://www.apple.com/publicsource and read it before - * using this file. - * - * This 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. - */ - - -// -// SSDLSession.h - DL session for security server CSP/DL. -// -#include "SSDLSession.h" - -#include "CSPDLPlugin.h" -#include "SSKey.h" -#include -#include - -using namespace CssmClient; -using namespace SecurityServer; -using namespace std; - -// -// SSDLSession -- Security Server DL session -// -SSDLSession::SSDLSession(CSSM_MODULE_HANDLE handle, - CSPDLPlugin &plug, - const CSSM_VERSION &version, - uint32 subserviceId, - CSSM_SERVICE_TYPE subserviceType, - CSSM_ATTACH_FLAGS attachFlags, - const CSSM_UPCALLS &upcalls, - DatabaseManager &databaseManager, - SSCSPDLSession &ssCSPDLSession) -: DLPluginSession(handle, plug, version, subserviceId, subserviceType, - attachFlags, upcalls, databaseManager), - mSSCSPDLSession(ssCSPDLSession), - mDL(Module(gGuidAppleFileDL, Cssm::standard())), - mClientSession(Allocator::standard(), static_cast(*this)) -{ - mClientSession.registerForAclEdits(SSCSPDLSession::didChangeKeyAclCallback, &mSSCSPDLSession); - // @@@ mDL.allocator(*static_cast(this)); - mDL->allocator(allocator()); - mDL->version(version); - mDL->subserviceId(subserviceId); - mDL->flags(attachFlags); - // fprintf(stderr, "%p: Created %p\n", pthread_self(), this); -} - -SSDLSession::~SSDLSession() -try -{ - StLock _1(mSSUniqueRecordLock); - mSSUniqueRecordMap.clear(); - - StLock _2(mDbHandleLock); - DbHandleMap::iterator end = mDbHandleMap.end(); - for (DbHandleMap::iterator it = mDbHandleMap.begin(); it != end; ++it) - it->second->close(); - - mDbHandleMap.clear(); - mDL->detach(); -} -catch (...) -{ -} - -// Utility functions -void -SSDLSession::GetDbNames(CSSM_NAME_LIST_PTR &outNameList) -{ - // @@@ Fix client lib - CSSM_DL_GetDbNames(mDL->handle(), &outNameList); -} - - -void -SSDLSession::FreeNameList(CSSM_NAME_LIST &inNameList) -{ - // @@@ Fix client lib - CSSM_DL_FreeNameList(mDL->handle(), &inNameList); -} - - -void -SSDLSession::DbDelete(const char *inDbName, - const CSSM_NET_ADDRESS *inDbLocation, - const AccessCredentials *inAccessCred) -{ - SSDatabase db(mClientSession, mDL, inDbName, inDbLocation); - db->accessCredentials(inAccessCred); - db->deleteDb(); -} - -// DbContext creation and destruction. -void -SSDLSession::DbCreate(const char *inDbName, - const CSSM_NET_ADDRESS *inDbLocation, - const CSSM_DBINFO &inDBInfo, - CSSM_DB_ACCESS_TYPE inAccessRequest, - const CSSM_RESOURCE_CONTROL_CONTEXT *inCredAndAclEntry, - const void *inOpenParameters, - CSSM_DB_HANDLE &outDbHandle) -{ - SSDatabase db(mClientSession, mDL, inDbName, inDbLocation); - db->dbInfo(&inDBInfo); - db->accessRequest(inAccessRequest); - db->resourceControlContext(inCredAndAclEntry); - db->openParameters(inOpenParameters); - db->create(DLDbIdentifier(CssmSubserviceUid(plugin.myGuid(), &version(), subserviceId(), - CSSM_SERVICE_DL | CSSM_SERVICE_CSP), - inDbName, inDbLocation)); - db->dbInfo(NULL); - outDbHandle = makeDbHandle(db); - // fprintf(stderr, "%p %p was created for %s in session %p\n", pthread_self(), (void*) outDbHandle, inDbName, this); -} - -void -SSDLSession::CreateWithBlob(const char *DbName, - const CSSM_NET_ADDRESS *DbLocation, - const CSSM_DBINFO &DBInfo, - CSSM_DB_ACCESS_TYPE AccessRequest, - const void *OpenParameters, - const CSSM_DATA &blob, - CSSM_DB_HANDLE &DbHandle) -{ - SSDatabase db(mClientSession, mDL, DbName, DbLocation); - db->dbInfo(&DBInfo); - db->accessRequest(AccessRequest); - db->resourceControlContext(NULL); - db->openParameters(OpenParameters); - db->createWithBlob(DLDbIdentifier(CssmSubserviceUid(plugin.myGuid(), &version(), subserviceId(), - CSSM_SERVICE_DL | CSSM_SERVICE_CSP), - DbName, DbLocation), - blob); - db->dbInfo(NULL); - DbHandle = makeDbHandle(db); - // fprintf(stderr, "%p %p was created with a blob in session %p\n", pthread_self(), (void*) DbHandle, this); -} - -void -SSDLSession::DbOpen(const char *inDbName, - const CSSM_NET_ADDRESS *inDbLocation, - CSSM_DB_ACCESS_TYPE inAccessRequest, - const AccessCredentials *inAccessCred, - const void *inOpenParameters, - CSSM_DB_HANDLE &outDbHandle) -{ - SSDatabase db(mClientSession, mDL, inDbName, inDbLocation); - db->accessRequest(inAccessRequest); - db->accessCredentials(inAccessCred); - db->openParameters(inOpenParameters); - db->open(DLDbIdentifier(CssmSubserviceUid(plugin.myGuid(), &version(), subserviceId(), - CSSM_SERVICE_DL | CSSM_SERVICE_CSP), - inDbName, inDbLocation)); - outDbHandle = makeDbHandle(db); - // fprintf(stderr, "%p %p was opened for %s in session %p\n", pthread_self(), (void*) outDbHandle, inDbName, this); -} - -// Operations using DbContext instances. -void -SSDLSession::DbClose(CSSM_DB_HANDLE inDbHandle) -{ - killDbHandle(inDbHandle)->close(); -} - -void -SSDLSession::CreateRelation(CSSM_DB_HANDLE inDbHandle, - CSSM_DB_RECORDTYPE inRelationID, - const char *inRelationName, - uint32 inNumberOfAttributes, - const CSSM_DB_SCHEMA_ATTRIBUTE_INFO *inAttributeInfo, - uint32 inNumberOfIndexes, - const CSSM_DB_SCHEMA_INDEX_INFO &inIndexInfo) -{ - SSDatabase db = findDbHandle(inDbHandle); - // @@@ Fix inAttributeInfo and inIndexInfo arguments (might be NULL if NumberOf = 0) - db->createRelation(inRelationID, inRelationName, - inNumberOfAttributes, inAttributeInfo, - inNumberOfIndexes, &inIndexInfo); -} - -void -SSDLSession::DestroyRelation(CSSM_DB_HANDLE inDbHandle, - CSSM_DB_RECORDTYPE inRelationID) -{ - // @@@ Check credentials. - SSDatabase db = findDbHandle(inDbHandle); - db->destroyRelation(inRelationID); -} - -void -SSDLSession::Authenticate(CSSM_DB_HANDLE inDbHandle, - CSSM_DB_ACCESS_TYPE inAccessRequest, - const AccessCredentials &inAccessCred) -{ - SSDatabase db = findDbHandle(inDbHandle); - db->authenticate(inAccessRequest, &inAccessCred); -} - - -void -SSDLSession::GetDbAcl(CSSM_DB_HANDLE inDbHandle, - const CSSM_STRING *inSelectionTag, - uint32 &outNumberOfAclInfos, - CSSM_ACL_ENTRY_INFO_PTR &outAclInfos) -{ - SSDatabase db = findDbHandle(inDbHandle); - mClientSession.getDbAcl(db->dbHandle(), - inSelectionTag ? *inSelectionTag : NULL, - outNumberOfAclInfos, AclEntryInfo::overlayVar(outAclInfos), allocator()); -} - -void -SSDLSession::ChangeDbAcl(CSSM_DB_HANDLE inDbHandle, - const AccessCredentials &inAccessCred, - const CSSM_ACL_EDIT &inAclEdit) -{ - SSDatabase db = findDbHandle(inDbHandle); - mClientSession.changeDbAcl(db->dbHandle(), inAccessCred, AclEdit::overlay(inAclEdit)); -} - -void -SSDLSession::GetDbOwner(CSSM_DB_HANDLE inDbHandle, - CSSM_ACL_OWNER_PROTOTYPE &outOwner) -{ - SSDatabase db = findDbHandle(inDbHandle); - mClientSession.getDbOwner(db->dbHandle(), - AclOwnerPrototype::overlay(outOwner), allocator()); -} - -void -SSDLSession::ChangeDbOwner(CSSM_DB_HANDLE inDbHandle, - const AccessCredentials &inAccessCred, - const CSSM_ACL_OWNER_PROTOTYPE &inNewOwner) -{ - SSDatabase db = findDbHandle(inDbHandle); - mClientSession.changeDbOwner(db->dbHandle(), inAccessCred, - AclOwnerPrototype::overlay(inNewOwner)); -} - -void -SSDLSession::GetDbNameFromHandle(CSSM_DB_HANDLE inDbHandle, - char **outDbName) -{ - SSDatabase db = findDbHandle(inDbHandle); - // @@@ Fix this functions signature. - db->name(*outDbName); -} - -void -SSDLSession::DataInsert(CSSM_DB_HANDLE inDbHandle, - CSSM_DB_RECORDTYPE inRecordType, - const CSSM_DB_RECORD_ATTRIBUTE_DATA *inAttributes, - const CssmData *inData, - CSSM_DB_UNIQUE_RECORD_PTR &outUniqueId) -{ - SSDatabase db = findDbHandle(inDbHandle); - // @@@ Fix client lib. - SSUniqueRecord uniqueId = db->insert(inRecordType, inAttributes, inData, true); // @@@ Fix me - outUniqueId = makeSSUniqueRecord(uniqueId); - // @@@ If this is a key do the right thing. -} - -void -SSDLSession::DataDelete(CSSM_DB_HANDLE inDbHandle, - const CSSM_DB_UNIQUE_RECORD &inUniqueRecordIdentifier) -{ - SSDatabase db = findDbHandle(inDbHandle); - SSUniqueRecord uniqueId = findSSUniqueRecord(inUniqueRecordIdentifier); - uniqueId->deleteRecord(); - // @@@ If this is a key do the right thing. -} - - -void -SSDLSession::DataModify(CSSM_DB_HANDLE inDbHandle, - CSSM_DB_RECORDTYPE inRecordType, - CSSM_DB_UNIQUE_RECORD &inoutUniqueRecordIdentifier, - const CSSM_DB_RECORD_ATTRIBUTE_DATA *inAttributesToBeModified, - const CssmData *inDataToBeModified, - CSSM_DB_MODIFY_MODE inModifyMode) -{ - SSDatabase db = findDbHandle(inDbHandle); - SSUniqueRecord uniqueId = findSSUniqueRecord(inoutUniqueRecordIdentifier); - uniqueId->modify(inRecordType, inAttributesToBeModified, inDataToBeModified, inModifyMode); - // @@@ If this is a key do the right thing. -} - -CSSM_HANDLE -SSDLSession::DataGetFirst(CSSM_DB_HANDLE inDbHandle, - const CssmQuery *inQuery, - CSSM_DB_RECORD_ATTRIBUTE_DATA_PTR inoutAttributes, - CssmData *inoutData, - CSSM_DB_UNIQUE_RECORD_PTR &outUniqueRecord) -{ - SSDatabase db = findDbHandle(inDbHandle); - CSSM_HANDLE resultsHandle = CSSM_INVALID_HANDLE; - SSUniqueRecord uniqueId(db); - - // Setup so we always retrive the attributes even if the client - // doesn't want them so we can figure out if we just retrived a key. - CSSM_DB_RECORD_ATTRIBUTE_DATA attributes; - CSSM_DB_RECORD_ATTRIBUTE_DATA_PTR pAttributes; - if (inoutAttributes) - pAttributes = inoutAttributes; - else - { - pAttributes = &attributes; - memset(pAttributes, 0, sizeof(attributes)); - } - - // Retrive the record. - CSSM_RETURN result = CSSM_DL_DataGetFirst(db->handle(), inQuery, &resultsHandle, - pAttributes, inoutData, uniqueId); - if (result) - { - if (result == CSSMERR_DL_ENDOFDATA) - return CSSM_INVALID_HANDLE; - - CssmError::throwMe(result); - } - - uniqueId->activate(); - - // If we the client didn't ask for data then it doesn't matter - // if this record is a key or not, just return it. - if (inoutData) - { - if (pAttributes->DataRecordType == CSSM_DL_DB_RECORD_PUBLIC_KEY - || pAttributes->DataRecordType == CSSM_DL_DB_RECORD_PRIVATE_KEY - || pAttributes->DataRecordType == CSSM_DL_DB_RECORD_SYMMETRIC_KEY) - { - // This record is a key, do the right thing (tm). - // Allocate storage for the key. - CssmKey *outKey = DatabaseSession::alloc(); - new SSKey(*this, *outKey, db, uniqueId, pAttributes->DataRecordType, *inoutData); - - // Free the data we retrived (keyblob) - allocator().free(inoutData->Data); - - // Set the length and data on the data we return to the client - inoutData->Length = sizeof(*outKey); - inoutData->Data = reinterpret_cast(outKey); - } - } - - outUniqueRecord = makeSSUniqueRecord(uniqueId); - return resultsHandle; -} - -bool -SSDLSession::DataGetNext(CSSM_DB_HANDLE inDbHandle, - CSSM_HANDLE inResultsHandle, - CSSM_DB_RECORD_ATTRIBUTE_DATA_PTR inoutAttributes, - CssmData *inoutData, - CSSM_DB_UNIQUE_RECORD_PTR &outUniqueRecord) -{ - // @@@ If this is a key do the right thing. - SSDatabase db = findDbHandle(inDbHandle); - SSUniqueRecord uniqueId(db); - - // Setup so we always retrive the attributes even if the client - // doesn't want them so we can figure out if we just retrived a key. - CSSM_DB_RECORD_ATTRIBUTE_DATA attributes; - CSSM_DB_RECORD_ATTRIBUTE_DATA_PTR pAttributes; - if (inoutAttributes) - pAttributes = inoutAttributes; - else - { - pAttributes = &attributes; - memset(pAttributes, 0, sizeof(attributes)); - } - - CSSM_RETURN result = CSSM_DL_DataGetNext(db->handle(), inResultsHandle, - inoutAttributes, inoutData, uniqueId); - if (result) - { - if (result == CSSMERR_DL_ENDOFDATA) - return false; - - CssmError::throwMe(result); - } - - uniqueId->activate(); - - // If we the client didn't ask for data then it doesn't matter - // if this record is a key or not, just return it. - if (inoutData) - { - if (pAttributes->DataRecordType == CSSM_DL_DB_RECORD_PUBLIC_KEY - || pAttributes->DataRecordType == CSSM_DL_DB_RECORD_PRIVATE_KEY - || pAttributes->DataRecordType == CSSM_DL_DB_RECORD_SYMMETRIC_KEY) - { - // This record is a key, do the right thing (tm). - // Allocate storage for the key. - CssmKey *outKey = DatabaseSession::alloc(); - new SSKey(*this, *outKey, db, uniqueId, pAttributes->DataRecordType, *inoutData); - - // Free the data we retrived (keyblob) - allocator().free(inoutData->Data); - - // Set the length and data on the data we return to the client - inoutData->Length = sizeof(*outKey); - inoutData->Data = reinterpret_cast(outKey); - } - } - - outUniqueRecord = makeSSUniqueRecord(uniqueId); - - return true; -} - -void -SSDLSession::DataAbortQuery(CSSM_DB_HANDLE inDbHandle, - CSSM_HANDLE inResultsHandle) -{ - // @@@ If this is a key do the right thing. - SSDatabase db = findDbHandle(inDbHandle); - CSSM_RETURN result = CSSM_DL_DataAbortQuery(db->handle(), inResultsHandle); - if (result) - CssmError::throwMe(result); -} - -void -SSDLSession::DataGetFromUniqueRecordId(CSSM_DB_HANDLE inDbHandle, - const CSSM_DB_UNIQUE_RECORD &inUniqueRecord, - CSSM_DB_RECORD_ATTRIBUTE_DATA_PTR inoutAttributes, - CssmData *inoutData) -{ - SSDatabase db = findDbHandle(inDbHandle); - const SSUniqueRecord uniqueId = findSSUniqueRecord(inUniqueRecord); - - // Setup so we always retrive the attributes even if the client - // doesn't want them so we can figure out if we just retrived a key. - CSSM_DB_RECORD_ATTRIBUTE_DATA attributes; - CSSM_DB_RECORD_ATTRIBUTE_DATA_PTR pAttributes; - if (inoutAttributes) - pAttributes = inoutAttributes; - else - { - pAttributes = &attributes; - memset(pAttributes, 0, sizeof(attributes)); - } - - CSSM_RETURN result = CSSM_DL_DataGetFromUniqueRecordId(db->handle(), - uniqueId, pAttributes, inoutData); - if (result) - CssmError::throwMe(result); - - if (inoutData) - { - if (pAttributes->DataRecordType == CSSM_DL_DB_RECORD_PUBLIC_KEY - || pAttributes->DataRecordType == CSSM_DL_DB_RECORD_PRIVATE_KEY - || pAttributes->DataRecordType == CSSM_DL_DB_RECORD_SYMMETRIC_KEY) - { - // This record is a key, do the right thing (tm). - // Allocate storage for the key. - CssmKey *outKey = DatabaseSession::alloc(); - new SSKey(*this, *outKey, db, uniqueId, pAttributes->DataRecordType, *inoutData); - - // Free the data we retrived (keyblob) - allocator().free(inoutData->Data); - - // Set the length and data on the data we return to the client - inoutData->Length = sizeof(*outKey); - inoutData->Data = reinterpret_cast(outKey); - } - } -} - -void -SSDLSession::FreeUniqueRecord(CSSM_DB_HANDLE inDbHandle, - CSSM_DB_UNIQUE_RECORD &inUniqueRecordIdentifier) -{ - killSSUniqueRecord(inUniqueRecordIdentifier); -} - -static const uint32 kGenericAttributeNames[] = -{ - 'cdat', 'mdat', 'desc', 'icmt', 'crtr', 'type', 'scrp', 7, 8, 'invi', 'nega', 'cusi', 'prot', 'acct', 'svce', - 'gena' -}; - -const uint32 kNumGenericAttributes = sizeof (kGenericAttributeNames) / sizeof (uint32); - -static const uint32 kApplesharePasswordNames[] = -{ - 'cdat', 'mdat', 'desc', 'icmt', 'crtr', 'type', 'scrp', 7, 8, 'invi', 'nega', 'cusi', 'prot', 'acct', 'vlme', - 'srvr', 'ptcl', 'addr', 'ssig' -}; - -const uint32 kNumApplesharePasswordAttributes = sizeof (kApplesharePasswordNames) / sizeof (uint32); - -static const uint32 kInternetPasswordNames[] = -{ - 'cdat', 'mdat', 'desc', 'icmt', 'crtr', 'type', 'scrp', 7, 8, 'invi', 'nega', 'cusi', 'prot', 'acct', 'sdmn', - 'srvr', 'ptcl', 'atyp', 'port', 'path' -}; - -const uint32 kNumInternetPasswordAttributes = sizeof (kInternetPasswordNames) / sizeof (uint32); - -const uint32 kKeyAttributeNames[] = -{ - 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26 -}; - -const uint32 kNumKeyAttributes = sizeof (kKeyAttributeNames) / sizeof (uint32); - -const uint32 kCertificateAttributeNames[] = -{ - 'ctyp', 'cenc', 'labl', 'alis', 'subj', 'issu', 'snbr', 'skid', 'hpky' -}; - -const uint32 kNumCertificateAttributes = sizeof (kCertificateAttributeNames) / sizeof (uint32); - -const unsigned kSymmetricKeyLabel = 6; // record id for the symmetric key -const unsigned kLabelSize = 20; -const unsigned kNumSymmetricAttributes = 27; // number of attributes to request - -static void appendUInt32ToData (const uint32 value, CssmDataContainer &data) -{ - data.append (CssmPolyData (uint32 (htonl (value)))); -} - -static inline uint32 GetUInt32AtFinger (uint8 *&finger) -{ - uint32 a = ((finger[0] << 24) | (finger[1] << 16) | (finger[2] << 8) | finger[3]); - finger += sizeof (uint32); - return a; -} - -void -SSDLSession::unwrapAttributesAndData (uint32 &numAttributes, - CSSM_DB_ATTRIBUTE_DATA_PTR &attributes, - CSSM_DATA &data, - CSSM_DATA &input) -{ - // get the number of attributes - uint8* finger = input.Data; - numAttributes = GetUInt32AtFinger (finger); - - // compute the end of the data for sanity checking later - uint8* maximum = input.Data + input.Length; - - // make the attribute array - attributes = (CSSM_DB_ATTRIBUTE_DATA*) allocator ().malloc (numAttributes * sizeof (CSSM_DB_ATTRIBUTE_DATA)); - - // for each attribute, retrieve the name format, name, type, and number of values - unsigned i; - for (i = 0; i < numAttributes; ++i) - { - attributes[i].Info.AttributeNameFormat = GetUInt32AtFinger (finger); - attributes[i].Info.Label.AttributeID = GetUInt32AtFinger (finger); - attributes[i].Info.AttributeFormat = GetUInt32AtFinger (finger); - attributes[i].NumberOfValues = GetUInt32AtFinger (finger); - - // for each value, get the length and data - attributes[i].Value = (CSSM_DATA*) allocator ().malloc (sizeof (CSSM_DATA) * attributes[i].NumberOfValues); - unsigned j; - for (j = 0; j < attributes[i].NumberOfValues; ++j) - { - attributes[i].Value[j].Length = GetUInt32AtFinger (finger); - if (attributes[i].Value[j].Length != 0) - { - // sanity check what we are about to do - if (finger > maximum || finger + attributes[i].Value[j].Length > maximum) - { - CssmError::throwMe (CSSM_ERRCODE_INVALID_POINTER); - } - - attributes[i].Value[j].Data = (uint8*) allocator ().malloc (attributes[i].Value[j].Length); - - switch (attributes[i].Info.AttributeFormat) - { - default: - { - memmove (attributes[i].Value[j].Data, finger, attributes[i].Value[j].Length); - finger += attributes[i].Value[j].Length; - break; - } - - case CSSM_DB_ATTRIBUTE_FORMAT_SINT32: - case CSSM_DB_ATTRIBUTE_FORMAT_UINT32: - { - *(uint32*) attributes[i].Value[j].Data = GetUInt32AtFinger (finger); - break; - } - - case CSSM_DB_ATTRIBUTE_FORMAT_MULTI_UINT32: - { - uint32* d = (uint32*) attributes[i].Value[j].Data; - unsigned long numValues = attributes[i].Value[j].Length / sizeof (UInt32); - while (numValues--) - { - *d++ = GetUInt32AtFinger (finger); - } - break; - } - } - } - else - { - attributes[i].Value[j].Data = NULL; - } - } - } - - // get the data - data.Length = GetUInt32AtFinger (finger); - if (data.Length != 0) - { - // sanity check the pointer - if (finger + data.Length > maximum) - { - CssmError::throwMe (CSSM_ERRCODE_INVALID_POINTER); - } - - data.Data = (uint8*) allocator ().malloc (data.Length); - memmove (data.Data, finger, data.Length); - finger += data.Length; - } - else - { - data.Data = NULL; - } -} - -void -SSDLSession::getWrappedAttributesAndData (SSDatabase &db, - CSSM_DB_RECORDTYPE recordType, - CSSM_DB_UNIQUE_RECORD_PTR recordPtr, - CssmDataContainer &output, - CSSM_DATA *dataBlob) -{ - // figure out which attributes to use - const uint32* attributeNameArray; - uint32 numAttributeNames; - - switch (recordType) - { - case CSSM_DL_DB_RECORD_GENERIC_PASSWORD: - { - attributeNameArray = kGenericAttributeNames; - numAttributeNames = kNumGenericAttributes; - break; - } - - case CSSM_DL_DB_RECORD_INTERNET_PASSWORD: - { - attributeNameArray = kInternetPasswordNames; - numAttributeNames = kNumInternetPasswordAttributes; - break; - } - - case CSSM_DL_DB_RECORD_APPLESHARE_PASSWORD: - { - attributeNameArray = kApplesharePasswordNames; - numAttributeNames = kNumApplesharePasswordAttributes; - break; - } - - case CSSM_DL_DB_RECORD_X509_CERTIFICATE: - { - attributeNameArray = kCertificateAttributeNames; - numAttributeNames = kNumCertificateAttributes; - break; - } - - case CSSM_DL_DB_RECORD_PUBLIC_KEY: - case CSSM_DL_DB_RECORD_PRIVATE_KEY: - case CSSM_DL_DB_RECORD_SYMMETRIC_KEY: - { - attributeNameArray = kKeyAttributeNames; - numAttributeNames = kNumKeyAttributes; - break; - } - - default: - { - CssmError::throwMe (CSSMERR_DL_FUNCTION_NOT_IMPLEMENTED); - } - } - - // make the attribute array - size_t arraySize = numAttributeNames * sizeof (CSSM_DB_ATTRIBUTE_DATA); - - CSSM_DB_ATTRIBUTE_DATA_PTR attributes = - (CSSM_DB_ATTRIBUTE_DATA_PTR) allocator ().malloc (arraySize); - - // initialize the array - memset (attributes, 0, arraySize); - unsigned i; - for (i = 0; i < numAttributeNames; ++i) - { - attributes[i].Info.AttributeNameFormat = CSSM_DB_ATTRIBUTE_NAME_AS_INTEGER; - attributes[i].Info.Label.AttributeID = attributeNameArray[i]; - } - - // make the attribute record - CSSM_DB_RECORD_ATTRIBUTE_DATA attrData; - attrData.DataRecordType = recordType; - attrData.SemanticInformation = 0; - attrData.NumberOfAttributes = numAttributeNames; - attrData.AttributeData = attributes; - - // get the data - CssmDataContainer data; - CSSM_RETURN result = CSSM_DL_DataGetFromUniqueRecordId (db->handle (), - recordPtr, - &attrData, - &data); - if (result != 0) - { - CssmError::throwMe (result); - } - - // wrap the data -- write the number of attributes - appendUInt32ToData (numAttributeNames, output); - - // for each attribute, write the type and number of values - for (i = 0; i < numAttributeNames; ++i) - { - appendUInt32ToData (attributes[i].Info.AttributeNameFormat, output); - appendUInt32ToData (attributes[i].Info.Label.AttributeID, output); - appendUInt32ToData (attributes[i].Info.AttributeFormat, output); - appendUInt32ToData (attributes[i].NumberOfValues, output); - - // for each value, write the name format, name, length and the data - unsigned j; - for (j = 0; j < attributes[i].NumberOfValues; ++j) - { - appendUInt32ToData ((uint32)attributes[i].Value[j].Length, output); - if (attributes[i].Value[j].Length != 0) - { - switch (attributes[i].Info.AttributeFormat) - { - default: - { - output.append (CssmPolyData (attributes[i].Value[j])); - break; - } - - case CSSM_DB_ATTRIBUTE_FORMAT_SINT32: - case CSSM_DB_ATTRIBUTE_FORMAT_UINT32: - { - uint32 n = htonl (*(uint32*) attributes[i].Value[j].Data); - CSSM_DATA d; - d.Length = sizeof (uint32); - d.Data = (uint8*) &n; - output.append (CssmPolyData (d)); - break; - } - } - } - } - } - - // write the length of the data - appendUInt32ToData ((uint32)data.Length, output); - - // write the data itself - if (data.Length != 0) - { - output.append (CssmPolyData (data)); - } - - // clean up - for (i = 0; i < numAttributeNames; ++i) - { - unsigned j; - for (j = 0; j < attributes[i].NumberOfValues; ++j) - { - allocator ().free (attributes[i].Value[j].Data); - } - - allocator ().free (attributes[i].Value); - } - - allocator ().free (attributes); - - // copy out the data if the caller needs it - if (dataBlob) - { - dataBlob->Data = data.Data; - dataBlob->Length = data.Length; - data.Data = NULL; - data.Length = 0; - } -} - -void -SSDLSession::getUniqueIdForSymmetricKey (SSDatabase &db, CSSM_DATA &label, - CSSM_DB_UNIQUE_RECORD_PTR &uniqueRecord) -{ - // set up a query to get the key - CSSM_SELECTION_PREDICATE predicate; - predicate.DbOperator = CSSM_DB_EQUAL; - predicate.Attribute.Info.AttributeNameFormat = CSSM_DB_ATTRIBUTE_NAME_AS_INTEGER; - predicate.Attribute.Info.Label.AttributeID = kSymmetricKeyLabel; - predicate.Attribute.Info.AttributeFormat = CSSM_DB_ATTRIBUTE_FORMAT_BLOB; - predicate.Attribute.NumberOfValues = 1; - // the label of the corresponding key is the first 20 bytes of the blob we returned - predicate.Attribute.Value = &label; - - CSSM_QUERY query; - query.RecordType = CSSM_DL_DB_RECORD_SYMMETRIC_KEY; - query.Conjunctive = CSSM_DB_NONE; - query.NumSelectionPredicates = 1; - query.SelectionPredicate = &predicate; - - // fill out the record data - CSSM_DB_RECORD_ATTRIBUTE_DATA recordAttributeData; - recordAttributeData.DataRecordType = CSSM_DL_DB_RECORD_SYMMETRIC_KEY; - recordAttributeData.SemanticInformation = 0; - recordAttributeData.NumberOfAttributes = 0; - recordAttributeData.AttributeData = NULL; - - // get the data - CSSM_HANDLE handle; - CSSM_RETURN result = CSSM_DL_DataGetFirst (db->handle (), &query, &handle, &recordAttributeData, NULL, - &uniqueRecord); - if (result) - { - CssmError::throwMe (result); - } - - // clean up - CSSM_DL_DataAbortQuery (db->handle (), handle); -} - -void -SSDLSession::getCorrespondingSymmetricKey (SSDatabase &db, CSSM_DATA &labelData, CssmDataContainer &data) -{ - // get the unique ID - CSSM_DB_UNIQUE_RECORD_PTR uniqueRecord; - getUniqueIdForSymmetricKey (db, labelData, uniqueRecord); - - // from this. get the wrapped attributes and data - getWrappedAttributesAndData (db, CSSM_DL_DB_RECORD_SYMMETRIC_KEY, uniqueRecord, data, NULL); - - // clean up after the query - CSSM_DL_FreeUniqueRecord (db->handle (), uniqueRecord); -} - -void SSDLSession::doGetWithoutEncryption (SSDatabase &db, const void *inInputParams, void **outOutputParams) -{ - CSSM_APPLECSPDL_DB_GET_WITHOUT_ENCRYPTION_PARAMETERS* params = - (CSSM_APPLECSPDL_DB_GET_WITHOUT_ENCRYPTION_PARAMETERS*) inInputParams; - - SSUniqueRecord uniqueID = findSSUniqueRecord(*(params->uniqueID)); - - CSSM_DATA *outputData = (CSSM_DATA*) outOutputParams; - CssmDataContainer output; - - // get the record type and requested attributes from the DL - CssmDataContainer data; - CSSM_RETURN result = CSSM_DL_DataGetFromUniqueRecordId(db->handle(), - uniqueID, - params->attributes, - NULL); - - if (result) - { - CssmError::throwMe(result); - } - - // get the real data and all of the attributes from the DL - CssmDataContainer blobData; - getWrappedAttributesAndData (db, params->attributes->DataRecordType, uniqueID, data, &blobData); - - // write out the data blob - appendUInt32ToData ((uint32)data.Length, output); - output.append (CssmPolyData (data)); - - // figure out what we need to do with the key blob - CssmDataContainer key; - switch (params->attributes->DataRecordType) - { - case CSSM_DL_DB_RECORD_GENERIC_PASSWORD: - case CSSM_DL_DB_RECORD_INTERNET_PASSWORD: - case CSSM_DL_DB_RECORD_APPLESHARE_PASSWORD: - { - // the label is the first kLabelSize bytes of the resultant data blob - CSSM_DATA label = {kLabelSize, blobData.Data}; - - // get the key - getCorrespondingSymmetricKey (db, label, key); - } - break; - - default: - { - break; - } - } - - - // write out the length of the key blob - appendUInt32ToData ((uint32)key.Length, output); - - if (key.Length != 0) - { - // write the key - output.append (CssmPolyData (key)); - } - - // copy out the results - outputData->Data = output.Data; - output.Data = NULL; - outputData->Length = output.Length; - output.Length = 0; -} - -void -SSDLSession::cleanupAttributes (uint32 numAttributes, CSSM_DB_ATTRIBUTE_DATA_PTR attributes) -{ - unsigned i; - for (i = 0; i < numAttributes; ++i) - { - unsigned j; - for (j = 0; j < attributes[i].NumberOfValues; ++j) - { - free (attributes[i].Value[j].Data); - } - - free (attributes[i].Value); - } - - free (attributes); -} - -void -SSDLSession::doModifyWithoutEncryption (SSDatabase &db, const void* inInputParams, void** outOutputParams) -{ - CSSM_RETURN result; - CSSM_APPLECSPDL_DB_MODIFY_WITHOUT_ENCRYPTION_PARAMETERS* params = - (CSSM_APPLECSPDL_DB_MODIFY_WITHOUT_ENCRYPTION_PARAMETERS*) inInputParams; - - // extract the data for this modify. - uint8* finger = params->data->Data; - CSSM_DATA data; - data.Length = GetUInt32AtFinger (finger); - data.Data = finger; - if (data.Length + sizeof (UInt32) > params->data->Length) - { - CssmError::throwMe (CSSM_ERRCODE_INVALID_POINTER); - } - - // point to the key - finger += data.Length; - - // reconstruct the attributes and data - uint32 numAttributes; - CSSM_DB_ATTRIBUTE_DATA_PTR attributes; - CssmDataContainer dataBlob; - - unwrapAttributesAndData (numAttributes, attributes, dataBlob, data); - - CSSM_DB_RECORD_ATTRIBUTE_DATA attrData; - attrData.DataRecordType = params->attributes->DataRecordType; - attrData.SemanticInformation = 0; - attrData.NumberOfAttributes = numAttributes; - attrData.AttributeData = attributes; - - // get the unique ID for this record (from the db's perspective) - SSUniqueRecord uniqueID = findSSUniqueRecord(*(params->uniqueID)); - CSSM_DB_UNIQUE_RECORD *uniqueIDPtr = uniqueID; // for readability. There's cast overloading - // going on here. - - switch (attrData.DataRecordType) - { - case CSSM_DL_DB_RECORD_GENERIC_PASSWORD: - case CSSM_DL_DB_RECORD_INTERNET_PASSWORD: - case CSSM_DL_DB_RECORD_APPLESHARE_PASSWORD: - { - // read off the data so that we can update the key - CssmDataContainer oldData; - result = CSSM_DL_DataGetFromUniqueRecordId (db->handle(), - uniqueIDPtr, - NULL, - &oldData); - if (result) - { - CssmError::throwMe (result); - } - - CSSM_DB_MODIFY_MODE modifyMode = params->modifyMode; - - // parse the key data blob - CssmDataContainer keyBlob; - data.Length = GetUInt32AtFinger (finger); - data.Data = finger; - - CSSM_DB_RECORD_ATTRIBUTE_DATA* attrDataPtr = NULL; - CSSM_DB_RECORD_ATTRIBUTE_DATA attrData; - - CSSM_DATA labelData = {kLabelSize, oldData.Data}; - CSSM_DB_UNIQUE_RECORD_PTR recordID; - getUniqueIdForSymmetricKey (db, labelData, recordID); - - CSSM_DB_ATTRIBUTE_DATA_PTR keyAttributes; - uint32 numKeyAttributes; - unwrapAttributesAndData (numKeyAttributes, keyAttributes, keyBlob, data); - - // make the attribute data - attrData.DataRecordType = params->recordType; - attrData.SemanticInformation = 0; - attrData.NumberOfAttributes = numKeyAttributes; - attrData.AttributeData = keyAttributes; - - attrDataPtr = &attrData; - - result = CSSM_DL_DataModify (db->handle(), - CSSM_DL_DB_RECORD_SYMMETRIC_KEY, - recordID, - attrDataPtr, - &keyBlob, - modifyMode); - - // clean up - CSSM_DL_FreeUniqueRecord (db->handle (), recordID); - - cleanupAttributes (numKeyAttributes, keyAttributes); - break; - } - - default: - { - break; - } - } - - // save off the new data - result = CSSM_DL_DataModify(db->handle(), - params->recordType, - uniqueIDPtr, - &attrData, - &dataBlob, - params->modifyMode); - - // clean up - cleanupAttributes (numAttributes, attributes); - - if (result) - { - CssmError::throwMe(result); - } - -} - -void -SSDLSession::doInsertWithoutEncryption (SSDatabase &db, const void* inInputParams, void** outOutputParams) -{ - CSSM_RETURN result; - - CSSM_APPLECSPDL_DB_INSERT_WITHOUT_ENCRYPTION_PARAMETERS* params = - (CSSM_APPLECSPDL_DB_INSERT_WITHOUT_ENCRYPTION_PARAMETERS*) inInputParams; - - // extract the data for this insert. - uint8* finger = params->data.Data; - CSSM_DATA data; - data.Length = GetUInt32AtFinger (finger); - data.Data = finger; - finger += data.Length; - - // reconstruct the attributes and data - uint32 numAttributes; - CSSM_DB_ATTRIBUTE_DATA_PTR attributes; - CSSM_DATA dataBlob; - - unwrapAttributesAndData (numAttributes, attributes, dataBlob, data); - - // make the attribute data - CSSM_DB_RECORD_ATTRIBUTE_DATA attrData; - attrData.DataRecordType = params->recordType; - attrData.SemanticInformation = 0; - attrData.NumberOfAttributes = numAttributes; - attrData.AttributeData = attributes; - - // insert into the database - SSUniqueRecord uniqueID (db); - result = CSSM_DL_DataInsert (db->handle(), params->recordType, - &attrData, - &dataBlob, - uniqueID); - - // cleanup - allocator ().free (dataBlob.Data); - cleanupAttributes (numAttributes, attributes); - - // attach into the CSP/DL mechanism - CSSM_DB_UNIQUE_RECORD_PTR newRecord = makeSSUniqueRecord(uniqueID); - *(CSSM_DB_UNIQUE_RECORD_PTR*) outOutputParams = newRecord; - - if (result) - { - CssmError::throwMe(result); - } - - // Get the key data for this insert - data.Length = GetUInt32AtFinger (finger); - if (data.Length != 0) - { - data.Data = finger; - - // parse the key data blob - unwrapAttributesAndData (numAttributes, attributes, dataBlob, data); - - // make the attribute data - CSSM_DB_RECORD_ATTRIBUTE_DATA attrData; - attrData.DataRecordType = params->recordType; - attrData.SemanticInformation = 0; - attrData.NumberOfAttributes = numAttributes; - attrData.AttributeData = attributes; - - // insert the key data into the symmetric key table - CSSM_DB_UNIQUE_RECORD_PTR uniqueRecord; - result = CSSM_DL_DataInsert (db->handle(), CSSM_DL_DB_RECORD_SYMMETRIC_KEY, &attrData, &dataBlob, - &uniqueRecord); - if (result) - { - CssmError::throwMe (result); - } - - // clean up after inserting the key - CSSM_DL_FreeUniqueRecord (db->handle (), uniqueRecord); - allocator ().free (dataBlob.Data); - cleanupAttributes (numAttributes, attributes); - } -} - -void -SSDLSession::doConvertRecordIdentifier (SSDatabase &db, const void *inInputParams, void **outOutputParams) -{ - SSUniqueRecord uniqueId (db); - - // clone the unique record - CSSM_DB_UNIQUE_RECORD_PTR clone = (CSSM_DB_UNIQUE_RECORD_PTR) allocator ().malloc (sizeof (CSSM_DB_UNIQUE_RECORD)); - *clone = *(CSSM_DB_UNIQUE_RECORD_PTR) inInputParams; - - // set the value of the unique record - uniqueId->setUniqueRecordPtr (clone); - - // byte swap the retrieved record pointer to host order - uint32* idArray = (uint32*) clone->RecordIdentifier.Data; - idArray[0] = ntohl (idArray[0]); - idArray[1] = ntohl (idArray[1]); - idArray[2] = ntohl (idArray[2]); - - CSSM_DB_UNIQUE_RECORD_PTR newRecord = makeSSUniqueRecord(uniqueId); - *(CSSM_DB_UNIQUE_RECORD_PTR*) outOutputParams = newRecord; -} - -void -SSDLSession::PassThrough(CSSM_DB_HANDLE inDbHandle, - uint32 inPassThroughId, - const void *inInputParams, - void **outOutputParams) -{ - if (inPassThroughId == CSSM_APPLECSPDL_DB_CREATE_WITH_BLOB) - { - CSSM_APPLE_CSPDL_DB_CREATE_WITH_BLOB_PARAMETERS* params = (CSSM_APPLE_CSPDL_DB_CREATE_WITH_BLOB_PARAMETERS*) inInputParams; - CreateWithBlob(params->dbName, params->dbLocation, *params->dbInfo, params->accessRequest, params->openParameters, *params->blob, - * (CSSM_DB_HANDLE*) outOutputParams); - return; - } - - SSDatabase db = findDbHandle(inDbHandle); - switch (inPassThroughId) - { - case CSSM_APPLECSPDL_DB_LOCK: - db->lock(); - break; - case CSSM_APPLECSPDL_DB_UNLOCK: - if (inInputParams) - db->unlock(*reinterpret_cast(inInputParams)); - else - db->unlock(); - break; - case CSSM_APPLECSPDL_DB_STASH: - db->stash(); - break; - case CSSM_APPLECSPDL_DB_STASH_CHECK: - db->stashCheck(); - break; - case CSSM_APPLECSPDL_DB_GET_SETTINGS: - { - if (!outOutputParams) - CssmError::throwMe(CSSM_ERRCODE_INVALID_OUTPUT_POINTER); - - CSSM_APPLECSPDL_DB_SETTINGS_PARAMETERS_PTR params = - DatabaseSession::alloc(); - try - { - uint32 idleTimeout; - bool lockOnSleep; - db->getSettings(idleTimeout, lockOnSleep); - params->idleTimeout = idleTimeout; - params->lockOnSleep = lockOnSleep; - } - catch(...) - { - allocator().free(params); - throw; - } - *reinterpret_cast(outOutputParams) = params; - break; - } - case CSSM_APPLECSPDL_DB_SET_SETTINGS: - { - if (!inInputParams) - CssmError::throwMe(CSSM_ERRCODE_INVALID_INPUT_POINTER); - - const CSSM_APPLECSPDL_DB_SETTINGS_PARAMETERS *params = - reinterpret_cast(inInputParams); - db->setSettings(params->idleTimeout, params->lockOnSleep); - break; - } - case CSSM_APPLECSPDL_DB_IS_LOCKED: - { - if (!outOutputParams) - CssmError::throwMe(CSSM_ERRCODE_INVALID_OUTPUT_POINTER); - - CSSM_APPLECSPDL_DB_IS_LOCKED_PARAMETERS_PTR params = - DatabaseSession::alloc(); - try - { - params->isLocked = db->isLocked(); - } - catch(...) - { - allocator().free(params); - throw; - } - *reinterpret_cast(outOutputParams) = params; - break; - } - case CSSM_APPLECSPDL_DB_CHANGE_PASSWORD: - { - if (!inInputParams) - CssmError::throwMe(CSSM_ERRCODE_INVALID_INPUT_POINTER); - - const CSSM_APPLECSPDL_DB_CHANGE_PASSWORD_PARAMETERS *params = - reinterpret_cast(inInputParams); - db->changePassphrase(params->accessCredentials); - break; - } - case CSSM_APPLECSPDL_DB_GET_HANDLE: - { - using SecurityServer::DbHandle; - Required(outOutputParams, CSSM_ERRCODE_INVALID_OUTPUT_POINTER); - *reinterpret_cast(outOutputParams) = db->handle(); - break; - } - case CSSM_APPLECSPDL_CSP_RECODE: - { - if (!inInputParams) - CssmError::throwMe(CSSM_ERRCODE_INVALID_INPUT_POINTER); - - const CSSM_APPLECSPDL_RECODE_PARAMETERS *params = - reinterpret_cast(inInputParams); - - db->recode(CssmData::overlay(params->dbBlob), - CssmData::overlay(params->extraData)); - break; - } - case CSSM_APPLECSPDL_DB_GET_RECORD_IDENTIFIER: - { - SSUniqueRecord uniqueID = findSSUniqueRecord(*(CSSM_DB_UNIQUE_RECORD_PTR) inInputParams); - db->getRecordIdentifier(uniqueID, *reinterpret_cast(outOutputParams)); - break; - } - case CSSM_APPLECSPDL_DB_COPY_BLOB: - { - // make the output parameters - db->copyBlob(*reinterpret_cast(outOutputParams)); - break; - } - case CSSM_APPLECSPDL_DB_INSERT_WITHOUT_ENCRYPTION: - { - doInsertWithoutEncryption (db, inInputParams, outOutputParams); - break; - } - case CSSM_APPLECSPDL_DB_MODIFY_WITHOUT_ENCRYPTION: - { - doModifyWithoutEncryption (db, inInputParams, outOutputParams); - break; - } - case CSSM_APPLECSPDL_DB_GET_WITHOUT_ENCRYPTION: - { - doGetWithoutEncryption (db, inInputParams, outOutputParams); - break; - } - case CSSM_APPLECSPDL_DB_CONVERT_RECORD_IDENTIFIER: - { - doConvertRecordIdentifier (db, inInputParams, outOutputParams); - break; - } - default: - { - CSSM_RETURN result = CSSM_DL_PassThrough(db->handle(), inPassThroughId, inInputParams, outOutputParams); - if (result) - CssmError::throwMe(result); - break; - } - } -} - -CSSM_DB_HANDLE -SSDLSession::makeDbHandle(SSDatabase &inDb) -{ - StLock _(mDbHandleLock); - CSSM_DB_HANDLE aDbHandle = inDb->handle().DBHandle; - bool inserted; - inserted = mDbHandleMap.insert(DbHandleMap::value_type(aDbHandle, inDb)).second; - assert(inserted); - // fprintf(stderr, "%p Added %p to %p\n", pthread_self(), (void*) aDbHandle, (void*) this); - return aDbHandle; -} - -SSDatabase -SSDLSession::killDbHandle(CSSM_DB_HANDLE inDbHandle) -{ - StLock _(mDbHandleLock); - DbHandleMap::iterator it = mDbHandleMap.find(inDbHandle); - if (it == mDbHandleMap.end()) - { - // fprintf(stderr, "Can't find %p in %p\n", (void*) inDbHandle, this); - CssmError::throwMe(CSSMERR_DL_INVALID_DB_HANDLE); - } - - SSDatabase db = it->second; - // fprintf(stderr, "%p Removed %p from %p\n", pthread_self(), (void*) it->first, (void*) this); - mDbHandleMap.erase(it); - return db; -} - -SSDatabase -SSDLSession::findDbHandle(CSSM_DB_HANDLE inDbHandle) -{ - StLock _(mDbHandleLock); - // fprintf(stderr, "%p Looking for %p in %p\n", pthread_self(), (void*) inDbHandle, (void*) this); - DbHandleMap::iterator it = mDbHandleMap.find(inDbHandle); - if (it == mDbHandleMap.end()) - { - // fprintf(stderr, "%p Can't find %p in %p\n", pthread_self(), (void*) inDbHandle, this); - DbHandleMap::iterator it = mDbHandleMap.begin(); - while (it != mDbHandleMap.end()) - { - // fprintf(stderr, "\t%p\n", (void*) it->first); - it++; - } - - CssmError::throwMe(CSSMERR_DL_INVALID_DB_HANDLE); - } - - return it->second; -} - -CSSM_DB_UNIQUE_RECORD_PTR -SSDLSession::makeSSUniqueRecord(SSUniqueRecord &uniqueId) -{ - StLock _(mSSUniqueRecordLock); - CSSM_HANDLE ref = CSSM_HANDLE(static_cast(uniqueId)); - bool inserted; - inserted = mSSUniqueRecordMap.insert(SSUniqueRecordMap::value_type(ref, uniqueId)).second; - assert(inserted); - return createUniqueRecord(ref); -} - -SSUniqueRecord -SSDLSession::killSSUniqueRecord(CSSM_DB_UNIQUE_RECORD &inUniqueRecord) -{ - CSSM_HANDLE ref = parseUniqueRecord(inUniqueRecord); - StLock _(mSSUniqueRecordLock); - SSUniqueRecordMap::iterator it = mSSUniqueRecordMap.find(ref); - if (it == mSSUniqueRecordMap.end()) - CssmError::throwMe(CSSMERR_DL_INVALID_RECORD_UID); - - SSUniqueRecord uniqueRecord = it->second; - mSSUniqueRecordMap.erase(it); - freeUniqueRecord(inUniqueRecord); - return uniqueRecord; -} - -SSUniqueRecord -SSDLSession::findSSUniqueRecord(const CSSM_DB_UNIQUE_RECORD &inUniqueRecord) -{ - CSSM_HANDLE ref = parseUniqueRecord(inUniqueRecord); - StLock _(mSSUniqueRecordLock); - SSUniqueRecordMap::iterator it = mSSUniqueRecordMap.find(ref); - if (it == mSSUniqueRecordMap.end()) - CssmError::throwMe(CSSMERR_DL_INVALID_RECORD_UID); - - return it->second; -} - -CSSM_DB_UNIQUE_RECORD_PTR -SSDLSession::createUniqueRecord(CSSM_HANDLE ref) -{ - CSSM_DB_UNIQUE_RECORD *aUniqueRecord = DatabaseSession::alloc(); - memset(aUniqueRecord, 0, sizeof(CSSM_DB_UNIQUE_RECORD)); - aUniqueRecord->RecordIdentifier.Length = sizeof(CSSM_HANDLE); - try - { - aUniqueRecord->RecordIdentifier.Data = DatabaseSession::alloc(sizeof(CSSM_HANDLE)); - *reinterpret_cast(aUniqueRecord->RecordIdentifier.Data) = ref; - } - catch(...) - { - free(aUniqueRecord); - throw; - } - - return aUniqueRecord; -} - -CSSM_HANDLE -SSDLSession::parseUniqueRecord(const CSSM_DB_UNIQUE_RECORD &inUniqueRecord) -{ - if (inUniqueRecord.RecordIdentifier.Length != sizeof(CSSM_HANDLE)) - CssmError::throwMe(CSSMERR_DL_INVALID_RECORD_UID); - - return *reinterpret_cast(inUniqueRecord.RecordIdentifier.Data); -} - -void -SSDLSession::freeUniqueRecord(CSSM_DB_UNIQUE_RECORD &inUniqueRecord) -{ - if (inUniqueRecord.RecordIdentifier.Length != 0 - && inUniqueRecord.RecordIdentifier.Data != NULL) - { - inUniqueRecord.RecordIdentifier.Length = 0; - allocator().free(inUniqueRecord.RecordIdentifier.Data); - } - allocator().free(&inUniqueRecord); -}