2 * Copyright (c) 2000-2001,2011-2014 Apple Inc. All Rights Reserved.
4 * The contents of this file constitute Original Code as defined in and are
5 * subject to the Apple Public Source License Version 1.2 (the 'License').
6 * You may not use this file except in compliance with the License. Please obtain
7 * a copy of the License at http://www.apple.com/publicsource and read it before
10 * This Original Code and all software distributed under the License are
11 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS
12 * OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, INCLUDING WITHOUT
13 * LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
14 * PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. Please see the License for the
15 * specific language governing rights and limitations under the License.
20 // SSDLSession.h - DL session for security server CSP/DL.
22 #include "SSDLSession.h"
24 #include "CSPDLPlugin.h"
26 #include <security_cdsa_utilities/cssmbridge.h>
27 #include <Security/cssmapplePriv.h>
29 using namespace CssmClient
;
30 using namespace SecurityServer
;
34 // SSDLSession -- Security Server DL session
36 SSDLSession::SSDLSession(CSSM_MODULE_HANDLE handle
,
38 const CSSM_VERSION
&version
,
40 CSSM_SERVICE_TYPE subserviceType
,
41 CSSM_ATTACH_FLAGS attachFlags
,
42 const CSSM_UPCALLS
&upcalls
,
43 DatabaseManager
&databaseManager
,
44 SSCSPDLSession
&ssCSPDLSession
)
45 : DLPluginSession(handle
, plug
, version
, subserviceId
, subserviceType
,
46 attachFlags
, upcalls
, databaseManager
),
47 mSSCSPDLSession(ssCSPDLSession
),
48 mDL(Module(gGuidAppleFileDL
, Cssm::standard())),
49 mClientSession(Allocator::standard(), static_cast<PluginSession
&>(*this))
51 mClientSession
.registerForAclEdits(SSCSPDLSession::didChangeKeyAclCallback
, &mSSCSPDLSession
);
52 // @@@ mDL.allocator(*static_cast<DatabaseSession *>(this));
53 mDL
->allocator(allocator());
54 mDL
->version(version
);
55 mDL
->subserviceId(subserviceId
);
56 mDL
->flags(attachFlags
);
57 // fprintf(stderr, "%p: Created %p\n", pthread_self(), this);
60 SSDLSession::~SSDLSession()
63 StLock
<Mutex
> _1(mSSUniqueRecordLock
);
64 mSSUniqueRecordMap
.clear();
66 StLock
<Mutex
> _2(mDbHandleLock
);
67 DbHandleMap::iterator end
= mDbHandleMap
.end();
68 for (DbHandleMap::iterator it
= mDbHandleMap
.begin(); it
!= end
; ++it
)
80 SSDLSession::GetDbNames(CSSM_NAME_LIST_PTR
&outNameList
)
83 CSSM_DL_GetDbNames(mDL
->handle(), &outNameList
);
88 SSDLSession::FreeNameList(CSSM_NAME_LIST
&inNameList
)
91 CSSM_DL_FreeNameList(mDL
->handle(), &inNameList
);
96 SSDLSession::DbDelete(const char *inDbName
,
97 const CSSM_NET_ADDRESS
*inDbLocation
,
98 const AccessCredentials
*inAccessCred
)
100 SSDatabase
db(mClientSession
, mDL
, inDbName
, inDbLocation
);
101 db
->accessCredentials(inAccessCred
);
105 // DbContext creation and destruction.
107 SSDLSession::DbCreate(const char *inDbName
,
108 const CSSM_NET_ADDRESS
*inDbLocation
,
109 const CSSM_DBINFO
&inDBInfo
,
110 CSSM_DB_ACCESS_TYPE inAccessRequest
,
111 const CSSM_RESOURCE_CONTROL_CONTEXT
*inCredAndAclEntry
,
112 const void *inOpenParameters
,
113 CSSM_DB_HANDLE
&outDbHandle
)
115 SSDatabase
db(mClientSession
, mDL
, inDbName
, inDbLocation
);
116 db
->dbInfo(&inDBInfo
);
117 db
->accessRequest(inAccessRequest
);
118 db
->resourceControlContext(inCredAndAclEntry
);
119 db
->openParameters(inOpenParameters
);
120 db
->create(DLDbIdentifier(CssmSubserviceUid(plugin
.myGuid(), &version(), subserviceId(),
121 CSSM_SERVICE_DL
| CSSM_SERVICE_CSP
),
122 inDbName
, inDbLocation
));
124 outDbHandle
= makeDbHandle(db
);
125 // fprintf(stderr, "%p %p was created for %s in session %p\n", pthread_self(), (void*) outDbHandle, inDbName, this);
129 SSDLSession::CreateWithBlob(const char *DbName
,
130 const CSSM_NET_ADDRESS
*DbLocation
,
131 const CSSM_DBINFO
&DBInfo
,
132 CSSM_DB_ACCESS_TYPE AccessRequest
,
133 const void *OpenParameters
,
134 const CSSM_DATA
&blob
,
135 CSSM_DB_HANDLE
&DbHandle
)
137 SSDatabase
db(mClientSession
, mDL
, DbName
, DbLocation
);
139 db
->accessRequest(AccessRequest
);
140 db
->resourceControlContext(NULL
);
141 db
->openParameters(OpenParameters
);
142 db
->createWithBlob(DLDbIdentifier(CssmSubserviceUid(plugin
.myGuid(), &version(), subserviceId(),
143 CSSM_SERVICE_DL
| CSSM_SERVICE_CSP
),
147 DbHandle
= makeDbHandle(db
);
148 // fprintf(stderr, "%p %p was created with a blob in session %p\n", pthread_self(), (void*) DbHandle, this);
152 SSDLSession::DbOpen(const char *inDbName
,
153 const CSSM_NET_ADDRESS
*inDbLocation
,
154 CSSM_DB_ACCESS_TYPE inAccessRequest
,
155 const AccessCredentials
*inAccessCred
,
156 const void *inOpenParameters
,
157 CSSM_DB_HANDLE
&outDbHandle
)
159 SSDatabase
db(mClientSession
, mDL
, inDbName
, inDbLocation
);
160 db
->accessRequest(inAccessRequest
);
161 db
->accessCredentials(inAccessCred
);
162 db
->openParameters(inOpenParameters
);
163 db
->open(DLDbIdentifier(CssmSubserviceUid(plugin
.myGuid(), &version(), subserviceId(),
164 CSSM_SERVICE_DL
| CSSM_SERVICE_CSP
),
165 inDbName
, inDbLocation
));
166 outDbHandle
= makeDbHandle(db
);
167 // fprintf(stderr, "%p %p was opened for %s in session %p\n", pthread_self(), (void*) outDbHandle, inDbName, this);
170 // Operations using DbContext instances.
172 SSDLSession::DbClose(CSSM_DB_HANDLE inDbHandle
)
174 killDbHandle(inDbHandle
)->close();
178 SSDLSession::CreateRelation(CSSM_DB_HANDLE inDbHandle
,
179 CSSM_DB_RECORDTYPE inRelationID
,
180 const char *inRelationName
,
181 uint32 inNumberOfAttributes
,
182 const CSSM_DB_SCHEMA_ATTRIBUTE_INFO
*inAttributeInfo
,
183 uint32 inNumberOfIndexes
,
184 const CSSM_DB_SCHEMA_INDEX_INFO
&inIndexInfo
)
186 SSDatabase db
= findDbHandle(inDbHandle
);
187 // @@@ Fix inAttributeInfo and inIndexInfo arguments (might be NULL if NumberOf = 0)
188 db
->createRelation(inRelationID
, inRelationName
,
189 inNumberOfAttributes
, inAttributeInfo
,
190 inNumberOfIndexes
, &inIndexInfo
);
194 SSDLSession::DestroyRelation(CSSM_DB_HANDLE inDbHandle
,
195 CSSM_DB_RECORDTYPE inRelationID
)
197 // @@@ Check credentials.
198 SSDatabase db
= findDbHandle(inDbHandle
);
199 db
->destroyRelation(inRelationID
);
203 SSDLSession::Authenticate(CSSM_DB_HANDLE inDbHandle
,
204 CSSM_DB_ACCESS_TYPE inAccessRequest
,
205 const AccessCredentials
&inAccessCred
)
207 SSDatabase db
= findDbHandle(inDbHandle
);
208 db
->authenticate(inAccessRequest
, &inAccessCred
);
213 SSDLSession::GetDbAcl(CSSM_DB_HANDLE inDbHandle
,
214 const CSSM_STRING
*inSelectionTag
,
215 uint32
&outNumberOfAclInfos
,
216 CSSM_ACL_ENTRY_INFO_PTR
&outAclInfos
)
218 SSDatabase db
= findDbHandle(inDbHandle
);
219 mClientSession
.getDbAcl(db
->dbHandle(),
220 inSelectionTag
? *inSelectionTag
: NULL
,
221 outNumberOfAclInfos
, AclEntryInfo::overlayVar(outAclInfos
), allocator());
225 SSDLSession::ChangeDbAcl(CSSM_DB_HANDLE inDbHandle
,
226 const AccessCredentials
&inAccessCred
,
227 const CSSM_ACL_EDIT
&inAclEdit
)
229 SSDatabase db
= findDbHandle(inDbHandle
);
230 mClientSession
.changeDbAcl(db
->dbHandle(), inAccessCred
, AclEdit::overlay(inAclEdit
));
234 SSDLSession::GetDbOwner(CSSM_DB_HANDLE inDbHandle
,
235 CSSM_ACL_OWNER_PROTOTYPE
&outOwner
)
237 SSDatabase db
= findDbHandle(inDbHandle
);
238 mClientSession
.getDbOwner(db
->dbHandle(),
239 AclOwnerPrototype::overlay(outOwner
), allocator());
243 SSDLSession::ChangeDbOwner(CSSM_DB_HANDLE inDbHandle
,
244 const AccessCredentials
&inAccessCred
,
245 const CSSM_ACL_OWNER_PROTOTYPE
&inNewOwner
)
247 SSDatabase db
= findDbHandle(inDbHandle
);
248 mClientSession
.changeDbOwner(db
->dbHandle(), inAccessCred
,
249 AclOwnerPrototype::overlay(inNewOwner
));
253 SSDLSession::GetDbNameFromHandle(CSSM_DB_HANDLE inDbHandle
,
256 SSDatabase db
= findDbHandle(inDbHandle
);
257 // @@@ Fix this functions signature.
258 db
->name(*outDbName
);
262 SSDLSession::DataInsert(CSSM_DB_HANDLE inDbHandle
,
263 CSSM_DB_RECORDTYPE inRecordType
,
264 const CSSM_DB_RECORD_ATTRIBUTE_DATA
*inAttributes
,
265 const CssmData
*inData
,
266 CSSM_DB_UNIQUE_RECORD_PTR
&outUniqueId
)
268 SSDatabase db
= findDbHandle(inDbHandle
);
269 // @@@ Fix client lib.
270 SSUniqueRecord uniqueId
= db
->insert(inRecordType
, inAttributes
, inData
, true); // @@@ Fix me
271 outUniqueId
= makeSSUniqueRecord(uniqueId
);
272 // @@@ If this is a key do the right thing.
276 SSDLSession::DataDelete(CSSM_DB_HANDLE inDbHandle
,
277 const CSSM_DB_UNIQUE_RECORD
&inUniqueRecordIdentifier
)
279 SSDatabase db
= findDbHandle(inDbHandle
);
280 SSUniqueRecord uniqueId
= findSSUniqueRecord(inUniqueRecordIdentifier
);
281 uniqueId
->deleteRecord();
282 // @@@ If this is a key do the right thing.
287 SSDLSession::DataModify(CSSM_DB_HANDLE inDbHandle
,
288 CSSM_DB_RECORDTYPE inRecordType
,
289 CSSM_DB_UNIQUE_RECORD
&inoutUniqueRecordIdentifier
,
290 const CSSM_DB_RECORD_ATTRIBUTE_DATA
*inAttributesToBeModified
,
291 const CssmData
*inDataToBeModified
,
292 CSSM_DB_MODIFY_MODE inModifyMode
)
294 SSDatabase db
= findDbHandle(inDbHandle
);
295 SSUniqueRecord uniqueId
= findSSUniqueRecord(inoutUniqueRecordIdentifier
);
296 uniqueId
->modify(inRecordType
, inAttributesToBeModified
, inDataToBeModified
, inModifyMode
);
297 // @@@ If this is a key do the right thing.
301 SSDLSession::DataGetFirst(CSSM_DB_HANDLE inDbHandle
,
302 const CssmQuery
*inQuery
,
303 CSSM_DB_RECORD_ATTRIBUTE_DATA_PTR inoutAttributes
,
305 CSSM_DB_UNIQUE_RECORD_PTR
&outUniqueRecord
)
307 SSDatabase db
= findDbHandle(inDbHandle
);
308 CSSM_HANDLE resultsHandle
= CSSM_INVALID_HANDLE
;
309 SSUniqueRecord
uniqueId(db
);
311 // Setup so we always retrive the attributes even if the client
312 // doesn't want them so we can figure out if we just retrived a key.
313 CSSM_DB_RECORD_ATTRIBUTE_DATA attributes
;
314 CSSM_DB_RECORD_ATTRIBUTE_DATA_PTR pAttributes
;
316 pAttributes
= inoutAttributes
;
319 pAttributes
= &attributes
;
320 memset(pAttributes
, 0, sizeof(attributes
));
323 // Retrive the record.
324 CSSM_RETURN result
= CSSM_DL_DataGetFirst(db
->handle(), inQuery
, &resultsHandle
,
325 pAttributes
, inoutData
, uniqueId
);
328 if (result
== CSSMERR_DL_ENDOFDATA
)
329 return CSSM_INVALID_HANDLE
;
331 CssmError::throwMe(result
);
334 uniqueId
->activate();
336 // If we the client didn't ask for data then it doesn't matter
337 // if this record is a key or not, just return it.
340 if (pAttributes
->DataRecordType
== CSSM_DL_DB_RECORD_PUBLIC_KEY
341 || pAttributes
->DataRecordType
== CSSM_DL_DB_RECORD_PRIVATE_KEY
342 || pAttributes
->DataRecordType
== CSSM_DL_DB_RECORD_SYMMETRIC_KEY
)
344 // This record is a key, do the right thing (tm).
345 // Allocate storage for the key.
346 CssmKey
*outKey
= DatabaseSession::alloc
<CssmKey
>();
347 new SSKey(*this, *outKey
, db
, uniqueId
, pAttributes
->DataRecordType
, *inoutData
);
349 // Free the data we retrived (keyblob)
350 allocator().free(inoutData
->Data
);
352 // Set the length and data on the data we return to the client
353 inoutData
->Length
= sizeof(*outKey
);
354 inoutData
->Data
= reinterpret_cast<uint8
*>(outKey
);
358 outUniqueRecord
= makeSSUniqueRecord(uniqueId
);
359 return resultsHandle
;
363 SSDLSession::DataGetNext(CSSM_DB_HANDLE inDbHandle
,
364 CSSM_HANDLE inResultsHandle
,
365 CSSM_DB_RECORD_ATTRIBUTE_DATA_PTR inoutAttributes
,
367 CSSM_DB_UNIQUE_RECORD_PTR
&outUniqueRecord
)
369 // @@@ If this is a key do the right thing.
370 SSDatabase db
= findDbHandle(inDbHandle
);
371 SSUniqueRecord
uniqueId(db
);
373 // Setup so we always retrive the attributes even if the client
374 // doesn't want them so we can figure out if we just retrived a key.
375 CSSM_DB_RECORD_ATTRIBUTE_DATA attributes
;
376 CSSM_DB_RECORD_ATTRIBUTE_DATA_PTR pAttributes
;
378 pAttributes
= inoutAttributes
;
381 pAttributes
= &attributes
;
382 memset(pAttributes
, 0, sizeof(attributes
));
385 CSSM_RETURN result
= CSSM_DL_DataGetNext(db
->handle(), inResultsHandle
,
386 inoutAttributes
, inoutData
, uniqueId
);
389 if (result
== CSSMERR_DL_ENDOFDATA
)
392 CssmError::throwMe(result
);
395 uniqueId
->activate();
397 // If we the client didn't ask for data then it doesn't matter
398 // if this record is a key or not, just return it.
401 if (pAttributes
->DataRecordType
== CSSM_DL_DB_RECORD_PUBLIC_KEY
402 || pAttributes
->DataRecordType
== CSSM_DL_DB_RECORD_PRIVATE_KEY
403 || pAttributes
->DataRecordType
== CSSM_DL_DB_RECORD_SYMMETRIC_KEY
)
405 // This record is a key, do the right thing (tm).
406 // Allocate storage for the key.
407 CssmKey
*outKey
= DatabaseSession::alloc
<CssmKey
>();
408 new SSKey(*this, *outKey
, db
, uniqueId
, pAttributes
->DataRecordType
, *inoutData
);
410 // Free the data we retrived (keyblob)
411 allocator().free(inoutData
->Data
);
413 // Set the length and data on the data we return to the client
414 inoutData
->Length
= sizeof(*outKey
);
415 inoutData
->Data
= reinterpret_cast<uint8
*>(outKey
);
419 outUniqueRecord
= makeSSUniqueRecord(uniqueId
);
425 SSDLSession::DataAbortQuery(CSSM_DB_HANDLE inDbHandle
,
426 CSSM_HANDLE inResultsHandle
)
428 // @@@ If this is a key do the right thing.
429 SSDatabase db
= findDbHandle(inDbHandle
);
430 CSSM_RETURN result
= CSSM_DL_DataAbortQuery(db
->handle(), inResultsHandle
);
432 CssmError::throwMe(result
);
436 SSDLSession::DataGetFromUniqueRecordId(CSSM_DB_HANDLE inDbHandle
,
437 const CSSM_DB_UNIQUE_RECORD
&inUniqueRecord
,
438 CSSM_DB_RECORD_ATTRIBUTE_DATA_PTR inoutAttributes
,
441 SSDatabase db
= findDbHandle(inDbHandle
);
442 const SSUniqueRecord uniqueId
= findSSUniqueRecord(inUniqueRecord
);
444 // Setup so we always retrive the attributes even if the client
445 // doesn't want them so we can figure out if we just retrived a key.
446 CSSM_DB_RECORD_ATTRIBUTE_DATA attributes
;
447 CSSM_DB_RECORD_ATTRIBUTE_DATA_PTR pAttributes
;
449 pAttributes
= inoutAttributes
;
452 pAttributes
= &attributes
;
453 memset(pAttributes
, 0, sizeof(attributes
));
456 CSSM_RETURN result
= CSSM_DL_DataGetFromUniqueRecordId(db
->handle(),
457 uniqueId
, pAttributes
, inoutData
);
459 CssmError::throwMe(result
);
463 if (pAttributes
->DataRecordType
== CSSM_DL_DB_RECORD_PUBLIC_KEY
464 || pAttributes
->DataRecordType
== CSSM_DL_DB_RECORD_PRIVATE_KEY
465 || pAttributes
->DataRecordType
== CSSM_DL_DB_RECORD_SYMMETRIC_KEY
)
467 // This record is a key, do the right thing (tm).
468 // Allocate storage for the key.
469 CssmKey
*outKey
= DatabaseSession::alloc
<CssmKey
>();
470 new SSKey(*this, *outKey
, db
, uniqueId
, pAttributes
->DataRecordType
, *inoutData
);
472 // Free the data we retrived (keyblob)
473 allocator().free(inoutData
->Data
);
475 // Set the length and data on the data we return to the client
476 inoutData
->Length
= sizeof(*outKey
);
477 inoutData
->Data
= reinterpret_cast<uint8
*>(outKey
);
483 SSDLSession::FreeUniqueRecord(CSSM_DB_HANDLE inDbHandle
,
484 CSSM_DB_UNIQUE_RECORD
&inUniqueRecordIdentifier
)
486 killSSUniqueRecord(inUniqueRecordIdentifier
);
489 #pragma clang diagnostic push
490 #pragma clang diagnostic ignored "-Wunused-const-variable"
492 static const uint32 kGenericAttributeNames
[] =
494 'cdat', 'mdat', 'desc', 'icmt', 'crtr', 'type', 'scrp', 7, 8, 'invi', 'nega', 'cusi', 'prot', 'acct', 'svce',
498 const uint32 kNumGenericAttributes
= sizeof (kGenericAttributeNames
) / sizeof (uint32
);
500 static const uint32 kApplesharePasswordNames
[] =
502 'cdat', 'mdat', 'desc', 'icmt', 'crtr', 'type', 'scrp', 7, 8, 'invi', 'nega', 'cusi', 'prot', 'acct', 'vlme',
503 'srvr', 'ptcl', 'addr', 'ssig'
506 const uint32 kNumApplesharePasswordAttributes
= sizeof (kApplesharePasswordNames
) / sizeof (uint32
);
508 static const uint32 kInternetPasswordNames
[] =
510 'cdat', 'mdat', 'desc', 'icmt', 'crtr', 'type', 'scrp', 7, 8, 'invi', 'nega', 'cusi', 'prot', 'acct', 'sdmn',
511 'srvr', 'ptcl', 'atyp', 'port', 'path'
514 const uint32 kNumInternetPasswordAttributes
= sizeof (kInternetPasswordNames
) / sizeof (uint32
);
516 const uint32 kKeyAttributeNames
[] =
518 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
521 const uint32 kNumKeyAttributes
= sizeof (kKeyAttributeNames
) / sizeof (uint32
);
523 const uint32 kCertificateAttributeNames
[] =
525 'ctyp', 'cenc', 'labl', 'alis', 'subj', 'issu', 'snbr', 'skid', 'hpky'
528 const uint32 kNumCertificateAttributes
= sizeof (kCertificateAttributeNames
) / sizeof (uint32
);
530 const unsigned kSymmetricKeyLabel
= 6; // record id for the symmetric key
531 const unsigned kLabelSize
= 20;
532 const unsigned kNumSymmetricAttributes
= 27; // number of attributes to request
534 #pragma clang diagnostic pop
536 static void appendUInt32ToData (const uint32 value
, CssmDataContainer
&data
)
538 data
.append (CssmPolyData (uint32 (htonl (value
))));
541 static inline uint32
GetUInt32AtFinger (uint8
*&finger
)
543 uint32 a
= ((finger
[0] << 24) | (finger
[1] << 16) | (finger
[2] << 8) | finger
[3]);
544 finger
+= sizeof (uint32
);
549 SSDLSession::unwrapAttributesAndData (uint32
&numAttributes
,
550 CSSM_DB_ATTRIBUTE_DATA_PTR
&attributes
,
554 // get the number of attributes
555 uint8
* finger
= input
.Data
;
556 numAttributes
= GetUInt32AtFinger (finger
);
558 // compute the end of the data for sanity checking later
559 uint8
* maximum
= input
.Data
+ input
.Length
;
561 // make the attribute array
562 attributes
= (CSSM_DB_ATTRIBUTE_DATA
*) allocator ().malloc (numAttributes
* sizeof (CSSM_DB_ATTRIBUTE_DATA
));
564 // for each attribute, retrieve the name format, name, type, and number of values
566 for (i
= 0; i
< numAttributes
; ++i
)
568 attributes
[i
].Info
.AttributeNameFormat
= GetUInt32AtFinger (finger
);
569 attributes
[i
].Info
.Label
.AttributeID
= GetUInt32AtFinger (finger
);
570 attributes
[i
].Info
.AttributeFormat
= GetUInt32AtFinger (finger
);
571 attributes
[i
].NumberOfValues
= GetUInt32AtFinger (finger
);
573 // for each value, get the length and data
574 attributes
[i
].Value
= (CSSM_DATA
*) allocator ().malloc (sizeof (CSSM_DATA
) * attributes
[i
].NumberOfValues
);
576 for (j
= 0; j
< attributes
[i
].NumberOfValues
; ++j
)
578 attributes
[i
].Value
[j
].Length
= GetUInt32AtFinger (finger
);
579 if (attributes
[i
].Value
[j
].Length
!= 0)
581 // sanity check what we are about to do
582 if (finger
> maximum
|| finger
+ attributes
[i
].Value
[j
].Length
> maximum
)
584 CssmError::throwMe (CSSM_ERRCODE_INVALID_POINTER
);
587 attributes
[i
].Value
[j
].Data
= (uint8
*) allocator ().malloc (attributes
[i
].Value
[j
].Length
);
589 switch (attributes
[i
].Info
.AttributeFormat
)
593 memmove (attributes
[i
].Value
[j
].Data
, finger
, attributes
[i
].Value
[j
].Length
);
594 finger
+= attributes
[i
].Value
[j
].Length
;
598 case CSSM_DB_ATTRIBUTE_FORMAT_SINT32
:
599 case CSSM_DB_ATTRIBUTE_FORMAT_UINT32
:
601 *(uint32
*) attributes
[i
].Value
[j
].Data
= GetUInt32AtFinger (finger
);
605 case CSSM_DB_ATTRIBUTE_FORMAT_MULTI_UINT32
:
607 uint32
* d
= (uint32
*) attributes
[i
].Value
[j
].Data
;
608 unsigned long numValues
= attributes
[i
].Value
[j
].Length
/ sizeof (UInt32
);
611 *d
++ = GetUInt32AtFinger (finger
);
619 attributes
[i
].Value
[j
].Data
= NULL
;
625 data
.Length
= GetUInt32AtFinger (finger
);
626 if (data
.Length
!= 0)
628 // sanity check the pointer
629 if (finger
+ data
.Length
> maximum
)
631 CssmError::throwMe (CSSM_ERRCODE_INVALID_POINTER
);
634 data
.Data
= (uint8
*) allocator ().malloc (data
.Length
);
635 memmove (data
.Data
, finger
, data
.Length
);
636 finger
+= data
.Length
;
645 SSDLSession::getWrappedAttributesAndData (SSDatabase
&db
,
646 CSSM_DB_RECORDTYPE recordType
,
647 CSSM_DB_UNIQUE_RECORD_PTR recordPtr
,
648 CssmDataContainer
&output
,
651 // figure out which attributes to use
652 const uint32
* attributeNameArray
;
653 uint32 numAttributeNames
;
657 case CSSM_DL_DB_RECORD_GENERIC_PASSWORD
:
659 attributeNameArray
= kGenericAttributeNames
;
660 numAttributeNames
= kNumGenericAttributes
;
664 case CSSM_DL_DB_RECORD_INTERNET_PASSWORD
:
666 attributeNameArray
= kInternetPasswordNames
;
667 numAttributeNames
= kNumInternetPasswordAttributes
;
671 case CSSM_DL_DB_RECORD_APPLESHARE_PASSWORD
:
673 attributeNameArray
= kApplesharePasswordNames
;
674 numAttributeNames
= kNumApplesharePasswordAttributes
;
678 case CSSM_DL_DB_RECORD_X509_CERTIFICATE
:
680 attributeNameArray
= kCertificateAttributeNames
;
681 numAttributeNames
= kNumCertificateAttributes
;
685 case CSSM_DL_DB_RECORD_PUBLIC_KEY
:
686 case CSSM_DL_DB_RECORD_PRIVATE_KEY
:
687 case CSSM_DL_DB_RECORD_SYMMETRIC_KEY
:
689 attributeNameArray
= kKeyAttributeNames
;
690 numAttributeNames
= kNumKeyAttributes
;
696 CssmError::throwMe (CSSMERR_DL_FUNCTION_NOT_IMPLEMENTED
);
700 // make the attribute array
701 size_t arraySize
= numAttributeNames
* sizeof (CSSM_DB_ATTRIBUTE_DATA
);
703 CSSM_DB_ATTRIBUTE_DATA_PTR attributes
=
704 (CSSM_DB_ATTRIBUTE_DATA_PTR
) allocator ().malloc (arraySize
);
706 // initialize the array
707 memset (attributes
, 0, arraySize
);
709 for (i
= 0; i
< numAttributeNames
; ++i
)
711 attributes
[i
].Info
.AttributeNameFormat
= CSSM_DB_ATTRIBUTE_NAME_AS_INTEGER
;
712 attributes
[i
].Info
.Label
.AttributeID
= attributeNameArray
[i
];
715 // make the attribute record
716 CSSM_DB_RECORD_ATTRIBUTE_DATA attrData
;
717 attrData
.DataRecordType
= recordType
;
718 attrData
.SemanticInformation
= 0;
719 attrData
.NumberOfAttributes
= numAttributeNames
;
720 attrData
.AttributeData
= attributes
;
723 CssmDataContainer data
;
724 CSSM_RETURN result
= CSSM_DL_DataGetFromUniqueRecordId (db
->handle (),
730 CssmError::throwMe (result
);
733 // wrap the data -- write the number of attributes
734 appendUInt32ToData (numAttributeNames
, output
);
736 // for each attribute, write the type and number of values
737 for (i
= 0; i
< numAttributeNames
; ++i
)
739 appendUInt32ToData (attributes
[i
].Info
.AttributeNameFormat
, output
);
740 appendUInt32ToData (attributes
[i
].Info
.Label
.AttributeID
, output
);
741 appendUInt32ToData (attributes
[i
].Info
.AttributeFormat
, output
);
742 appendUInt32ToData (attributes
[i
].NumberOfValues
, output
);
744 // for each value, write the name format, name, length and the data
746 for (j
= 0; j
< attributes
[i
].NumberOfValues
; ++j
)
748 appendUInt32ToData ((uint32
)attributes
[i
].Value
[j
].Length
, output
);
749 if (attributes
[i
].Value
[j
].Length
!= 0)
751 switch (attributes
[i
].Info
.AttributeFormat
)
755 output
.append (CssmPolyData (attributes
[i
].Value
[j
]));
759 case CSSM_DB_ATTRIBUTE_FORMAT_SINT32
:
760 case CSSM_DB_ATTRIBUTE_FORMAT_UINT32
:
762 uint32 n
= htonl (*(uint32
*) attributes
[i
].Value
[j
].Data
);
764 d
.Length
= sizeof (uint32
);
765 d
.Data
= (uint8
*) &n
;
766 output
.append (CssmPolyData (d
));
774 // write the length of the data
775 appendUInt32ToData ((uint32
)data
.Length
, output
);
777 // write the data itself
778 if (data
.Length
!= 0)
780 output
.append (CssmPolyData (data
));
784 for (i
= 0; i
< numAttributeNames
; ++i
)
787 for (j
= 0; j
< attributes
[i
].NumberOfValues
; ++j
)
789 allocator ().free (attributes
[i
].Value
[j
].Data
);
792 allocator ().free (attributes
[i
].Value
);
795 allocator ().free (attributes
);
797 // copy out the data if the caller needs it
800 dataBlob
->Data
= data
.Data
;
801 dataBlob
->Length
= data
.Length
;
808 SSDLSession::getUniqueIdForSymmetricKey (SSDatabase
&db
, CSSM_DATA
&label
,
809 CSSM_DB_UNIQUE_RECORD_PTR
&uniqueRecord
)
811 // set up a query to get the key
812 CSSM_SELECTION_PREDICATE predicate
;
813 predicate
.DbOperator
= CSSM_DB_EQUAL
;
814 predicate
.Attribute
.Info
.AttributeNameFormat
= CSSM_DB_ATTRIBUTE_NAME_AS_INTEGER
;
815 predicate
.Attribute
.Info
.Label
.AttributeID
= kSymmetricKeyLabel
;
816 predicate
.Attribute
.Info
.AttributeFormat
= CSSM_DB_ATTRIBUTE_FORMAT_BLOB
;
817 predicate
.Attribute
.NumberOfValues
= 1;
818 // the label of the corresponding key is the first 20 bytes of the blob we returned
819 predicate
.Attribute
.Value
= &label
;
822 query
.RecordType
= CSSM_DL_DB_RECORD_SYMMETRIC_KEY
;
823 query
.Conjunctive
= CSSM_DB_NONE
;
824 query
.NumSelectionPredicates
= 1;
825 query
.SelectionPredicate
= &predicate
;
827 // fill out the record data
828 CSSM_DB_RECORD_ATTRIBUTE_DATA recordAttributeData
;
829 recordAttributeData
.DataRecordType
= CSSM_DL_DB_RECORD_SYMMETRIC_KEY
;
830 recordAttributeData
.SemanticInformation
= 0;
831 recordAttributeData
.NumberOfAttributes
= 0;
832 recordAttributeData
.AttributeData
= NULL
;
836 CSSM_RETURN result
= CSSM_DL_DataGetFirst (db
->handle (), &query
, &handle
, &recordAttributeData
, NULL
,
840 CssmError::throwMe (result
);
844 CSSM_DL_DataAbortQuery (db
->handle (), handle
);
848 SSDLSession::getCorrespondingSymmetricKey (SSDatabase
&db
, CSSM_DATA
&labelData
, CssmDataContainer
&data
)
851 CSSM_DB_UNIQUE_RECORD_PTR uniqueRecord
;
852 getUniqueIdForSymmetricKey (db
, labelData
, uniqueRecord
);
854 // from this. get the wrapped attributes and data
855 getWrappedAttributesAndData (db
, CSSM_DL_DB_RECORD_SYMMETRIC_KEY
, uniqueRecord
, data
, NULL
);
857 // clean up after the query
858 CSSM_DL_FreeUniqueRecord (db
->handle (), uniqueRecord
);
861 void SSDLSession::doGetWithoutEncryption (SSDatabase
&db
, const void *inInputParams
, void **outOutputParams
)
863 CSSM_APPLECSPDL_DB_GET_WITHOUT_ENCRYPTION_PARAMETERS
* params
=
864 (CSSM_APPLECSPDL_DB_GET_WITHOUT_ENCRYPTION_PARAMETERS
*) inInputParams
;
866 SSUniqueRecord uniqueID
= findSSUniqueRecord(*(params
->uniqueID
));
868 CSSM_DATA
*outputData
= (CSSM_DATA
*) outOutputParams
;
869 CssmDataContainer output
;
871 // get the record type and requested attributes from the DL
872 CssmDataContainer data
;
873 CSSM_RETURN result
= CSSM_DL_DataGetFromUniqueRecordId(db
->handle(),
880 CssmError::throwMe(result
);
883 // get the real data and all of the attributes from the DL
884 CssmDataContainer blobData
;
885 getWrappedAttributesAndData (db
, params
->attributes
->DataRecordType
, uniqueID
, data
, &blobData
);
887 // write out the data blob
888 appendUInt32ToData ((uint32
)data
.Length
, output
);
889 output
.append (CssmPolyData (data
));
891 // figure out what we need to do with the key blob
892 CssmDataContainer key
;
893 switch (params
->attributes
->DataRecordType
)
895 case CSSM_DL_DB_RECORD_GENERIC_PASSWORD
:
896 case CSSM_DL_DB_RECORD_INTERNET_PASSWORD
:
897 case CSSM_DL_DB_RECORD_APPLESHARE_PASSWORD
:
899 // the label is the first kLabelSize bytes of the resultant data blob
900 CSSM_DATA label
= {kLabelSize
, blobData
.Data
};
903 getCorrespondingSymmetricKey (db
, label
, key
);
914 // write out the length of the key blob
915 appendUInt32ToData ((uint32
)key
.Length
, output
);
920 output
.append (CssmPolyData (key
));
923 // copy out the results
924 outputData
->Data
= output
.Data
;
926 outputData
->Length
= output
.Length
;
931 SSDLSession::cleanupAttributes (uint32 numAttributes
, CSSM_DB_ATTRIBUTE_DATA_PTR attributes
)
934 for (i
= 0; i
< numAttributes
; ++i
)
937 for (j
= 0; j
< attributes
[i
].NumberOfValues
; ++j
)
939 free (attributes
[i
].Value
[j
].Data
);
942 free (attributes
[i
].Value
);
949 SSDLSession::doModifyWithoutEncryption (SSDatabase
&db
, const void* inInputParams
, void** outOutputParams
)
952 CSSM_APPLECSPDL_DB_MODIFY_WITHOUT_ENCRYPTION_PARAMETERS
* params
=
953 (CSSM_APPLECSPDL_DB_MODIFY_WITHOUT_ENCRYPTION_PARAMETERS
*) inInputParams
;
955 // extract the data for this modify.
956 uint8
* finger
= params
->data
->Data
;
958 data
.Length
= GetUInt32AtFinger (finger
);
960 if (data
.Length
+ sizeof (UInt32
) > params
->data
->Length
)
962 CssmError::throwMe (CSSM_ERRCODE_INVALID_POINTER
);
966 finger
+= data
.Length
;
968 // reconstruct the attributes and data
969 uint32 numAttributes
;
970 CSSM_DB_ATTRIBUTE_DATA_PTR attributes
;
971 CssmDataContainer dataBlob
;
973 unwrapAttributesAndData (numAttributes
, attributes
, dataBlob
, data
);
975 CSSM_DB_RECORD_ATTRIBUTE_DATA attrData
;
976 attrData
.DataRecordType
= params
->attributes
->DataRecordType
;
977 attrData
.SemanticInformation
= 0;
978 attrData
.NumberOfAttributes
= numAttributes
;
979 attrData
.AttributeData
= attributes
;
981 // get the unique ID for this record (from the db's perspective)
982 SSUniqueRecord uniqueID
= findSSUniqueRecord(*(params
->uniqueID
));
983 CSSM_DB_UNIQUE_RECORD
*uniqueIDPtr
= uniqueID
; // for readability. There's cast overloading
986 switch (attrData
.DataRecordType
)
988 case CSSM_DL_DB_RECORD_GENERIC_PASSWORD
:
989 case CSSM_DL_DB_RECORD_INTERNET_PASSWORD
:
990 case CSSM_DL_DB_RECORD_APPLESHARE_PASSWORD
:
992 // read off the data so that we can update the key
993 CssmDataContainer oldData
;
994 result
= CSSM_DL_DataGetFromUniqueRecordId (db
->handle(),
1000 CssmError::throwMe (result
);
1003 CSSM_DB_MODIFY_MODE modifyMode
= params
->modifyMode
;
1005 // parse the key data blob
1006 CssmDataContainer keyBlob
;
1007 data
.Length
= GetUInt32AtFinger (finger
);
1010 CSSM_DB_RECORD_ATTRIBUTE_DATA
* attrDataPtr
= NULL
;
1011 CSSM_DB_RECORD_ATTRIBUTE_DATA attrData
;
1013 CSSM_DATA labelData
= {kLabelSize
, oldData
.Data
};
1014 CSSM_DB_UNIQUE_RECORD_PTR recordID
;
1015 getUniqueIdForSymmetricKey (db
, labelData
, recordID
);
1017 CSSM_DB_ATTRIBUTE_DATA_PTR keyAttributes
;
1018 uint32 numKeyAttributes
;
1019 unwrapAttributesAndData (numKeyAttributes
, keyAttributes
, keyBlob
, data
);
1021 // make the attribute data
1022 attrData
.DataRecordType
= params
->recordType
;
1023 attrData
.SemanticInformation
= 0;
1024 attrData
.NumberOfAttributes
= numKeyAttributes
;
1025 attrData
.AttributeData
= keyAttributes
;
1027 attrDataPtr
= &attrData
;
1029 result
= CSSM_DL_DataModify (db
->handle(),
1030 CSSM_DL_DB_RECORD_SYMMETRIC_KEY
,
1037 CSSM_DL_FreeUniqueRecord (db
->handle (), recordID
);
1039 cleanupAttributes (numKeyAttributes
, keyAttributes
);
1049 // save off the new data
1050 result
= CSSM_DL_DataModify(db
->handle(),
1055 params
->modifyMode
);
1058 cleanupAttributes (numAttributes
, attributes
);
1062 CssmError::throwMe(result
);
1068 SSDLSession::doInsertWithoutEncryption (SSDatabase
&db
, const void* inInputParams
, void** outOutputParams
)
1072 CSSM_APPLECSPDL_DB_INSERT_WITHOUT_ENCRYPTION_PARAMETERS
* params
=
1073 (CSSM_APPLECSPDL_DB_INSERT_WITHOUT_ENCRYPTION_PARAMETERS
*) inInputParams
;
1075 // extract the data for this insert.
1076 uint8
* finger
= params
->data
.Data
;
1078 data
.Length
= GetUInt32AtFinger (finger
);
1080 finger
+= data
.Length
;
1082 // reconstruct the attributes and data
1083 uint32 numAttributes
;
1084 CSSM_DB_ATTRIBUTE_DATA_PTR attributes
;
1087 unwrapAttributesAndData (numAttributes
, attributes
, dataBlob
, data
);
1089 // make the attribute data
1090 CSSM_DB_RECORD_ATTRIBUTE_DATA attrData
;
1091 attrData
.DataRecordType
= params
->recordType
;
1092 attrData
.SemanticInformation
= 0;
1093 attrData
.NumberOfAttributes
= numAttributes
;
1094 attrData
.AttributeData
= attributes
;
1096 // insert into the database
1097 SSUniqueRecord
uniqueID (db
);
1098 result
= CSSM_DL_DataInsert (db
->handle(), params
->recordType
,
1104 allocator ().free (dataBlob
.Data
);
1105 cleanupAttributes (numAttributes
, attributes
);
1107 // attach into the CSP/DL mechanism
1108 CSSM_DB_UNIQUE_RECORD_PTR newRecord
= makeSSUniqueRecord(uniqueID
);
1109 *(CSSM_DB_UNIQUE_RECORD_PTR
*) outOutputParams
= newRecord
;
1113 CssmError::throwMe(result
);
1116 // Get the key data for this insert
1117 data
.Length
= GetUInt32AtFinger (finger
);
1118 if (data
.Length
!= 0)
1122 // parse the key data blob
1123 unwrapAttributesAndData (numAttributes
, attributes
, dataBlob
, data
);
1125 // make the attribute data
1126 CSSM_DB_RECORD_ATTRIBUTE_DATA attrData
;
1127 attrData
.DataRecordType
= params
->recordType
;
1128 attrData
.SemanticInformation
= 0;
1129 attrData
.NumberOfAttributes
= numAttributes
;
1130 attrData
.AttributeData
= attributes
;
1132 // insert the key data into the symmetric key table
1133 CSSM_DB_UNIQUE_RECORD_PTR uniqueRecord
;
1134 result
= CSSM_DL_DataInsert (db
->handle(), CSSM_DL_DB_RECORD_SYMMETRIC_KEY
, &attrData
, &dataBlob
,
1138 CssmError::throwMe (result
);
1141 // clean up after inserting the key
1142 CSSM_DL_FreeUniqueRecord (db
->handle (), uniqueRecord
);
1143 allocator ().free (dataBlob
.Data
);
1144 cleanupAttributes (numAttributes
, attributes
);
1149 SSDLSession::doConvertRecordIdentifier (SSDatabase
&db
, const void *inInputParams
, void **outOutputParams
)
1151 SSUniqueRecord
uniqueId (db
);
1153 // clone the unique record
1154 CSSM_DB_UNIQUE_RECORD_PTR clone
= (CSSM_DB_UNIQUE_RECORD_PTR
) allocator ().malloc (sizeof (CSSM_DB_UNIQUE_RECORD
));
1155 *clone
= *(CSSM_DB_UNIQUE_RECORD_PTR
) inInputParams
;
1157 // set the value of the unique record
1158 uniqueId
->setUniqueRecordPtr (clone
);
1160 // byte swap the retrieved record pointer to host order
1161 uint32
* idArray
= (uint32
*) clone
->RecordIdentifier
.Data
;
1162 idArray
[0] = ntohl (idArray
[0]);
1163 idArray
[1] = ntohl (idArray
[1]);
1164 idArray
[2] = ntohl (idArray
[2]);
1166 CSSM_DB_UNIQUE_RECORD_PTR newRecord
= makeSSUniqueRecord(uniqueId
);
1167 *(CSSM_DB_UNIQUE_RECORD_PTR
*) outOutputParams
= newRecord
;
1171 SSDLSession::PassThrough(CSSM_DB_HANDLE inDbHandle
,
1172 uint32 inPassThroughId
,
1173 const void *inInputParams
,
1174 void **outOutputParams
)
1176 if (inPassThroughId
== CSSM_APPLECSPDL_DB_CREATE_WITH_BLOB
)
1178 CSSM_APPLE_CSPDL_DB_CREATE_WITH_BLOB_PARAMETERS
* params
= (CSSM_APPLE_CSPDL_DB_CREATE_WITH_BLOB_PARAMETERS
*) inInputParams
;
1179 CreateWithBlob(params
->dbName
, params
->dbLocation
, *params
->dbInfo
, params
->accessRequest
, params
->openParameters
, *params
->blob
,
1180 * (CSSM_DB_HANDLE
*) outOutputParams
);
1184 SSDatabase db
= findDbHandle(inDbHandle
);
1185 switch (inPassThroughId
)
1187 case CSSM_APPLECSPDL_DB_LOCK
:
1190 case CSSM_APPLECSPDL_DB_UNLOCK
:
1192 db
->unlock(*reinterpret_cast<const CSSM_DATA
*>(inInputParams
));
1196 case CSSM_APPLECSPDL_DB_STASH
:
1199 case CSSM_APPLECSPDL_DB_STASH_CHECK
:
1202 case CSSM_APPLECSPDL_DB_GET_SETTINGS
:
1204 if (!outOutputParams
)
1205 CssmError::throwMe(CSSM_ERRCODE_INVALID_OUTPUT_POINTER
);
1207 CSSM_APPLECSPDL_DB_SETTINGS_PARAMETERS_PTR params
=
1208 DatabaseSession::alloc
<CSSM_APPLECSPDL_DB_SETTINGS_PARAMETERS
>();
1213 db
->getSettings(idleTimeout
, lockOnSleep
);
1214 params
->idleTimeout
= idleTimeout
;
1215 params
->lockOnSleep
= lockOnSleep
;
1219 allocator().free(params
);
1222 *reinterpret_cast<CSSM_APPLECSPDL_DB_SETTINGS_PARAMETERS_PTR
*>(outOutputParams
) = params
;
1225 case CSSM_APPLECSPDL_DB_SET_SETTINGS
:
1228 CssmError::throwMe(CSSM_ERRCODE_INVALID_INPUT_POINTER
);
1230 const CSSM_APPLECSPDL_DB_SETTINGS_PARAMETERS
*params
=
1231 reinterpret_cast<const CSSM_APPLECSPDL_DB_SETTINGS_PARAMETERS
*>(inInputParams
);
1232 db
->setSettings(params
->idleTimeout
, params
->lockOnSleep
);
1235 case CSSM_APPLECSPDL_DB_IS_LOCKED
:
1237 if (!outOutputParams
)
1238 CssmError::throwMe(CSSM_ERRCODE_INVALID_OUTPUT_POINTER
);
1240 CSSM_APPLECSPDL_DB_IS_LOCKED_PARAMETERS_PTR params
=
1241 DatabaseSession::alloc
<CSSM_APPLECSPDL_DB_IS_LOCKED_PARAMETERS
>();
1244 params
->isLocked
= db
->isLocked();
1248 allocator().free(params
);
1251 *reinterpret_cast<CSSM_APPLECSPDL_DB_IS_LOCKED_PARAMETERS_PTR
*>(outOutputParams
) = params
;
1254 case CSSM_APPLECSPDL_DB_CHANGE_PASSWORD
:
1257 CssmError::throwMe(CSSM_ERRCODE_INVALID_INPUT_POINTER
);
1259 const CSSM_APPLECSPDL_DB_CHANGE_PASSWORD_PARAMETERS
*params
=
1260 reinterpret_cast<const CSSM_APPLECSPDL_DB_CHANGE_PASSWORD_PARAMETERS
*>(inInputParams
);
1261 db
->changePassphrase(params
->accessCredentials
);
1264 case CSSM_APPLECSPDL_DB_GET_HANDLE
:
1266 using SecurityServer::DbHandle
;
1267 Required(outOutputParams
, CSSM_ERRCODE_INVALID_OUTPUT_POINTER
);
1268 *reinterpret_cast<CSSM_DL_DB_HANDLE
*>(outOutputParams
) = db
->handle();
1271 case CSSM_APPLECSPDL_CSP_RECODE
:
1274 CssmError::throwMe(CSSM_ERRCODE_INVALID_INPUT_POINTER
);
1276 const CSSM_APPLECSPDL_RECODE_PARAMETERS
*params
=
1277 reinterpret_cast<const CSSM_APPLECSPDL_RECODE_PARAMETERS
*>(inInputParams
);
1279 db
->recode(CssmData::overlay(params
->dbBlob
),
1280 CssmData::overlay(params
->extraData
));
1283 case CSSM_APPLECSPDL_DB_GET_RECORD_IDENTIFIER
:
1285 SSUniqueRecord uniqueID
= findSSUniqueRecord(*(CSSM_DB_UNIQUE_RECORD_PTR
) inInputParams
);
1286 db
->getRecordIdentifier(uniqueID
, *reinterpret_cast<CSSM_DATA
*>(outOutputParams
));
1289 case CSSM_APPLECSPDL_DB_COPY_BLOB
:
1291 // make the output parameters
1292 db
->copyBlob(*reinterpret_cast<CSSM_DATA
*>(outOutputParams
));
1295 case CSSM_APPLECSPDL_DB_INSERT_WITHOUT_ENCRYPTION
:
1297 doInsertWithoutEncryption (db
, inInputParams
, outOutputParams
);
1300 case CSSM_APPLECSPDL_DB_MODIFY_WITHOUT_ENCRYPTION
:
1302 doModifyWithoutEncryption (db
, inInputParams
, outOutputParams
);
1305 case CSSM_APPLECSPDL_DB_GET_WITHOUT_ENCRYPTION
:
1307 doGetWithoutEncryption (db
, inInputParams
, outOutputParams
);
1310 case CSSM_APPLECSPDL_DB_CONVERT_RECORD_IDENTIFIER
:
1312 doConvertRecordIdentifier (db
, inInputParams
, outOutputParams
);
1317 CSSM_RETURN result
= CSSM_DL_PassThrough(db
->handle(), inPassThroughId
, inInputParams
, outOutputParams
);
1319 CssmError::throwMe(result
);
1326 SSDLSession::makeDbHandle(SSDatabase
&inDb
)
1328 StLock
<Mutex
> _(mDbHandleLock
);
1329 CSSM_DB_HANDLE aDbHandle
= inDb
->handle().DBHandle
;
1331 inserted
= mDbHandleMap
.insert(DbHandleMap::value_type(aDbHandle
, inDb
)).second
;
1333 // fprintf(stderr, "%p Added %p to %p\n", pthread_self(), (void*) aDbHandle, (void*) this);
1338 SSDLSession::killDbHandle(CSSM_DB_HANDLE inDbHandle
)
1340 StLock
<Mutex
> _(mDbHandleLock
);
1341 DbHandleMap::iterator it
= mDbHandleMap
.find(inDbHandle
);
1342 if (it
== mDbHandleMap
.end())
1344 // fprintf(stderr, "Can't find %p in %p\n", (void*) inDbHandle, this);
1345 CssmError::throwMe(CSSMERR_DL_INVALID_DB_HANDLE
);
1348 SSDatabase db
= it
->second
;
1349 // fprintf(stderr, "%p Removed %p from %p\n", pthread_self(), (void*) it->first, (void*) this);
1350 mDbHandleMap
.erase(it
);
1355 SSDLSession::findDbHandle(CSSM_DB_HANDLE inDbHandle
)
1357 StLock
<Mutex
> _(mDbHandleLock
);
1358 // fprintf(stderr, "%p Looking for %p in %p\n", pthread_self(), (void*) inDbHandle, (void*) this);
1359 DbHandleMap::iterator it
= mDbHandleMap
.find(inDbHandle
);
1360 if (it
== mDbHandleMap
.end())
1362 // fprintf(stderr, "%p Can't find %p in %p\n", pthread_self(), (void*) inDbHandle, this);
1363 DbHandleMap::iterator it
= mDbHandleMap
.begin();
1364 while (it
!= mDbHandleMap
.end())
1366 // fprintf(stderr, "\t%p\n", (void*) it->first);
1370 CssmError::throwMe(CSSMERR_DL_INVALID_DB_HANDLE
);
1376 CSSM_DB_UNIQUE_RECORD_PTR
1377 SSDLSession::makeSSUniqueRecord(SSUniqueRecord
&uniqueId
)
1379 StLock
<Mutex
> _(mSSUniqueRecordLock
);
1380 CSSM_HANDLE ref
= CSSM_HANDLE(static_cast<CSSM_DB_UNIQUE_RECORD
*>(uniqueId
));
1382 inserted
= mSSUniqueRecordMap
.insert(SSUniqueRecordMap::value_type(ref
, uniqueId
)).second
;
1384 return createUniqueRecord(ref
);
1388 SSDLSession::killSSUniqueRecord(CSSM_DB_UNIQUE_RECORD
&inUniqueRecord
)
1390 CSSM_HANDLE ref
= parseUniqueRecord(inUniqueRecord
);
1391 StLock
<Mutex
> _(mSSUniqueRecordLock
);
1392 SSUniqueRecordMap::iterator it
= mSSUniqueRecordMap
.find(ref
);
1393 if (it
== mSSUniqueRecordMap
.end())
1394 CssmError::throwMe(CSSMERR_DL_INVALID_RECORD_UID
);
1396 SSUniqueRecord uniqueRecord
= it
->second
;
1397 mSSUniqueRecordMap
.erase(it
);
1398 freeUniqueRecord(inUniqueRecord
);
1399 return uniqueRecord
;
1403 SSDLSession::findSSUniqueRecord(const CSSM_DB_UNIQUE_RECORD
&inUniqueRecord
)
1405 CSSM_HANDLE ref
= parseUniqueRecord(inUniqueRecord
);
1406 StLock
<Mutex
> _(mSSUniqueRecordLock
);
1407 SSUniqueRecordMap::iterator it
= mSSUniqueRecordMap
.find(ref
);
1408 if (it
== mSSUniqueRecordMap
.end())
1409 CssmError::throwMe(CSSMERR_DL_INVALID_RECORD_UID
);
1414 CSSM_DB_UNIQUE_RECORD_PTR
1415 SSDLSession::createUniqueRecord(CSSM_HANDLE ref
)
1417 CSSM_DB_UNIQUE_RECORD
*aUniqueRecord
= DatabaseSession::alloc
<CSSM_DB_UNIQUE_RECORD
>();
1418 memset(aUniqueRecord
, 0, sizeof(CSSM_DB_UNIQUE_RECORD
));
1419 aUniqueRecord
->RecordIdentifier
.Length
= sizeof(CSSM_HANDLE
);
1422 aUniqueRecord
->RecordIdentifier
.Data
= DatabaseSession::alloc
<uint8
>(sizeof(CSSM_HANDLE
));
1423 *reinterpret_cast<CSSM_HANDLE
*>(aUniqueRecord
->RecordIdentifier
.Data
) = ref
;
1427 free(aUniqueRecord
);
1431 return aUniqueRecord
;
1435 SSDLSession::parseUniqueRecord(const CSSM_DB_UNIQUE_RECORD
&inUniqueRecord
)
1437 if (inUniqueRecord
.RecordIdentifier
.Length
!= sizeof(CSSM_HANDLE
))
1438 CssmError::throwMe(CSSMERR_DL_INVALID_RECORD_UID
);
1440 return *reinterpret_cast<CSSM_HANDLE
*>(inUniqueRecord
.RecordIdentifier
.Data
);
1444 SSDLSession::freeUniqueRecord(CSSM_DB_UNIQUE_RECORD
&inUniqueRecord
)
1446 if (inUniqueRecord
.RecordIdentifier
.Length
!= 0
1447 && inUniqueRecord
.RecordIdentifier
.Data
!= NULL
)
1449 inUniqueRecord
.RecordIdentifier
.Length
= 0;
1450 allocator().free(inUniqueRecord
.RecordIdentifier
.Data
);
1452 allocator().free(&inUniqueRecord
);