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
)
76 // Prevent re-throw of exception.
82 SSDLSession::GetDbNames(CSSM_NAME_LIST_PTR
&outNameList
)
85 CSSM_DL_GetDbNames(mDL
->handle(), &outNameList
);
90 SSDLSession::FreeNameList(CSSM_NAME_LIST
&inNameList
)
93 CSSM_DL_FreeNameList(mDL
->handle(), &inNameList
);
98 SSDLSession::DbDelete(const char *inDbName
,
99 const CSSM_NET_ADDRESS
*inDbLocation
,
100 const AccessCredentials
*inAccessCred
)
102 SSDatabase
db(mClientSession
, mDL
, inDbName
, inDbLocation
);
103 db
->accessCredentials(inAccessCred
);
107 // DbContext creation and destruction.
109 SSDLSession::DbCreate(const char *inDbName
,
110 const CSSM_NET_ADDRESS
*inDbLocation
,
111 const CSSM_DBINFO
&inDBInfo
,
112 CSSM_DB_ACCESS_TYPE inAccessRequest
,
113 const CSSM_RESOURCE_CONTROL_CONTEXT
*inCredAndAclEntry
,
114 const void *inOpenParameters
,
115 CSSM_DB_HANDLE
&outDbHandle
)
117 SSDatabase
db(mClientSession
, mDL
, inDbName
, inDbLocation
);
118 db
->dbInfo(&inDBInfo
);
119 db
->accessRequest(inAccessRequest
);
120 db
->resourceControlContext(inCredAndAclEntry
);
121 db
->openParameters(inOpenParameters
);
122 db
->ssCreate(DLDbIdentifier(CssmSubserviceUid(plugin
.myGuid(), &version(), subserviceId(),
123 CSSM_SERVICE_DL
| CSSM_SERVICE_CSP
),
124 inDbName
, inDbLocation
));
126 outDbHandle
= makeDbHandle(db
);
127 // fprintf(stderr, "%p %p was created for %s in session %p\n", pthread_self(), (void*) outDbHandle, inDbName, this);
131 SSDLSession::CreateWithBlob(const char *DbName
,
132 const CSSM_NET_ADDRESS
*DbLocation
,
133 const CSSM_DBINFO
&DBInfo
,
134 CSSM_DB_ACCESS_TYPE AccessRequest
,
135 const void *OpenParameters
,
136 const CSSM_DATA
&blob
,
137 CSSM_DB_HANDLE
&DbHandle
)
139 SSDatabase
db(mClientSession
, mDL
, DbName
, DbLocation
);
141 db
->accessRequest(AccessRequest
);
142 db
->resourceControlContext(NULL
);
143 db
->openParameters(OpenParameters
);
144 db
->ssCreateWithBlob(DLDbIdentifier(CssmSubserviceUid(plugin
.myGuid(), &version(), subserviceId(),
145 CSSM_SERVICE_DL
| CSSM_SERVICE_CSP
),
149 DbHandle
= makeDbHandle(db
);
150 // fprintf(stderr, "%p %p was created with a blob in session %p\n", pthread_self(), (void*) DbHandle, this);
154 SSDLSession::DbOpen(const char *inDbName
,
155 const CSSM_NET_ADDRESS
*inDbLocation
,
156 CSSM_DB_ACCESS_TYPE inAccessRequest
,
157 const AccessCredentials
*inAccessCred
,
158 const void *inOpenParameters
,
159 CSSM_DB_HANDLE
&outDbHandle
)
161 SSDatabase
db(mClientSession
, mDL
, inDbName
, inDbLocation
);
162 db
->accessRequest(inAccessRequest
);
163 db
->accessCredentials(inAccessCred
);
164 db
->openParameters(inOpenParameters
);
165 db
->ssOpen(DLDbIdentifier(CssmSubserviceUid(plugin
.myGuid(), &version(), subserviceId(),
166 CSSM_SERVICE_DL
| CSSM_SERVICE_CSP
),
167 inDbName
, inDbLocation
));
168 outDbHandle
= makeDbHandle(db
);
169 // fprintf(stderr, "%p %p was opened for %s in session %p\n", pthread_self(), (void*) outDbHandle, inDbName, this);
172 // Operations using DbContext instances.
174 SSDLSession::DbClose(CSSM_DB_HANDLE inDbHandle
)
176 killDbHandle(inDbHandle
)->close();
180 SSDLSession::CreateRelation(CSSM_DB_HANDLE inDbHandle
,
181 CSSM_DB_RECORDTYPE inRelationID
,
182 const char *inRelationName
,
183 uint32 inNumberOfAttributes
,
184 const CSSM_DB_SCHEMA_ATTRIBUTE_INFO
*inAttributeInfo
,
185 uint32 inNumberOfIndexes
,
186 const CSSM_DB_SCHEMA_INDEX_INFO
&inIndexInfo
)
188 SSDatabase db
= findDbHandle(inDbHandle
);
189 // @@@ Fix inAttributeInfo and inIndexInfo arguments (might be NULL if NumberOf = 0)
190 db
->createRelation(inRelationID
, inRelationName
,
191 inNumberOfAttributes
, inAttributeInfo
,
192 inNumberOfIndexes
, &inIndexInfo
);
196 SSDLSession::DestroyRelation(CSSM_DB_HANDLE inDbHandle
,
197 CSSM_DB_RECORDTYPE inRelationID
)
199 // @@@ Check credentials.
200 SSDatabase db
= findDbHandle(inDbHandle
);
201 db
->destroyRelation(inRelationID
);
205 SSDLSession::Authenticate(CSSM_DB_HANDLE inDbHandle
,
206 CSSM_DB_ACCESS_TYPE inAccessRequest
,
207 const AccessCredentials
&inAccessCred
)
209 SSDatabase db
= findDbHandle(inDbHandle
);
210 db
->authenticate(inAccessRequest
, &inAccessCred
);
215 SSDLSession::GetDbAcl(CSSM_DB_HANDLE inDbHandle
,
216 const CSSM_STRING
*inSelectionTag
,
217 uint32
&outNumberOfAclInfos
,
218 CSSM_ACL_ENTRY_INFO_PTR
&outAclInfos
)
220 SSDatabase db
= findDbHandle(inDbHandle
);
221 mClientSession
.getDbAcl(db
->dbHandle(),
222 inSelectionTag
? *inSelectionTag
: NULL
,
223 outNumberOfAclInfos
, AclEntryInfo::overlayVar(outAclInfos
), allocator());
227 SSDLSession::ChangeDbAcl(CSSM_DB_HANDLE inDbHandle
,
228 const AccessCredentials
&inAccessCred
,
229 const CSSM_ACL_EDIT
&inAclEdit
)
231 SSDatabase db
= findDbHandle(inDbHandle
);
232 mClientSession
.changeDbAcl(db
->dbHandle(), inAccessCred
, AclEdit::overlay(inAclEdit
));
236 SSDLSession::GetDbOwner(CSSM_DB_HANDLE inDbHandle
,
237 CSSM_ACL_OWNER_PROTOTYPE
&outOwner
)
239 SSDatabase db
= findDbHandle(inDbHandle
);
240 mClientSession
.getDbOwner(db
->dbHandle(),
241 AclOwnerPrototype::overlay(outOwner
), allocator());
245 SSDLSession::ChangeDbOwner(CSSM_DB_HANDLE inDbHandle
,
246 const AccessCredentials
&inAccessCred
,
247 const CSSM_ACL_OWNER_PROTOTYPE
&inNewOwner
)
249 SSDatabase db
= findDbHandle(inDbHandle
);
250 mClientSession
.changeDbOwner(db
->dbHandle(), inAccessCred
,
251 AclOwnerPrototype::overlay(inNewOwner
));
255 SSDLSession::GetDbNameFromHandle(CSSM_DB_HANDLE inDbHandle
,
258 SSDatabase db
= findDbHandle(inDbHandle
);
259 // @@@ Fix this functions signature.
260 db
->name(*outDbName
);
264 SSDLSession::DataInsert(CSSM_DB_HANDLE inDbHandle
,
265 CSSM_DB_RECORDTYPE inRecordType
,
266 const CSSM_DB_RECORD_ATTRIBUTE_DATA
*inAttributes
,
267 const CssmData
*inData
,
268 CSSM_DB_UNIQUE_RECORD_PTR
&outUniqueId
)
270 SSDatabase db
= findDbHandle(inDbHandle
);
271 // @@@ Fix client lib.
272 SSUniqueRecord uniqueId
= db
->ssInsert(inRecordType
, inAttributes
, inData
);
273 outUniqueId
= makeSSUniqueRecord(uniqueId
);
274 // @@@ If this is a key do the right thing.
278 SSDLSession::DataDelete(CSSM_DB_HANDLE inDbHandle
,
279 const CSSM_DB_UNIQUE_RECORD
&inUniqueRecordIdentifier
)
281 SSDatabase db
= findDbHandle(inDbHandle
);
282 SSUniqueRecord uniqueId
= findSSUniqueRecord(inUniqueRecordIdentifier
);
283 uniqueId
->deleteRecord();
284 // @@@ If this is a key do the right thing.
289 SSDLSession::DataModify(CSSM_DB_HANDLE inDbHandle
,
290 CSSM_DB_RECORDTYPE inRecordType
,
291 CSSM_DB_UNIQUE_RECORD
&inoutUniqueRecordIdentifier
,
292 const CSSM_DB_RECORD_ATTRIBUTE_DATA
*inAttributesToBeModified
,
293 const CssmData
*inDataToBeModified
,
294 CSSM_DB_MODIFY_MODE inModifyMode
)
296 SSDatabase db
= findDbHandle(inDbHandle
);
297 SSUniqueRecord uniqueId
= findSSUniqueRecord(inoutUniqueRecordIdentifier
);
298 uniqueId
->modify(inRecordType
, inAttributesToBeModified
, inDataToBeModified
, inModifyMode
);
299 // @@@ If this is a key do the right thing.
303 SSDLSession::DataGetFirst(CSSM_DB_HANDLE inDbHandle
,
304 const CssmQuery
*inQuery
,
305 CSSM_DB_RECORD_ATTRIBUTE_DATA_PTR inoutAttributes
,
307 CSSM_DB_UNIQUE_RECORD_PTR
&outUniqueRecord
)
309 SSDatabase db
= findDbHandle(inDbHandle
);
310 CSSM_HANDLE resultsHandle
= CSSM_INVALID_HANDLE
;
311 SSUniqueRecord
uniqueId(db
);
313 // Setup so we always retrive the attributes even if the client
314 // doesn't want them so we can figure out if we just retrived a key.
315 CSSM_DB_RECORD_ATTRIBUTE_DATA attributes
;
316 CSSM_DB_RECORD_ATTRIBUTE_DATA_PTR pAttributes
;
318 pAttributes
= inoutAttributes
;
321 pAttributes
= &attributes
;
322 memset(pAttributes
, 0, sizeof(attributes
));
325 // Retrive the record.
326 CSSM_RETURN result
= CSSM_DL_DataGetFirst(db
->handle(), inQuery
, &resultsHandle
,
327 pAttributes
, inoutData
, uniqueId
);
330 if (result
== CSSMERR_DL_ENDOFDATA
)
331 return CSSM_INVALID_HANDLE
;
333 CssmError::throwMe(result
);
336 uniqueId
->activate();
338 // If we the client didn't ask for data then it doesn't matter
339 // if this record is a key or not, just return it.
342 if (pAttributes
->DataRecordType
== CSSM_DL_DB_RECORD_PUBLIC_KEY
343 || pAttributes
->DataRecordType
== CSSM_DL_DB_RECORD_PRIVATE_KEY
344 || pAttributes
->DataRecordType
== CSSM_DL_DB_RECORD_SYMMETRIC_KEY
)
346 // This record is a key, do the right thing (tm).
347 // Allocate storage for the key.
348 CssmKey
*outKey
= DatabaseSession::alloc
<CssmKey
>();
349 new SSKey(*this, *outKey
, db
, uniqueId
, pAttributes
->DataRecordType
, *inoutData
);
351 // Free the data we retrived (keyblob)
352 allocator().free(inoutData
->Data
);
354 // Set the length and data on the data we return to the client
355 inoutData
->Length
= sizeof(*outKey
);
356 inoutData
->Data
= reinterpret_cast<uint8
*>(outKey
);
360 outUniqueRecord
= makeSSUniqueRecord(uniqueId
);
361 return resultsHandle
;
365 SSDLSession::DataGetNext(CSSM_DB_HANDLE inDbHandle
,
366 CSSM_HANDLE inResultsHandle
,
367 CSSM_DB_RECORD_ATTRIBUTE_DATA_PTR inoutAttributes
,
369 CSSM_DB_UNIQUE_RECORD_PTR
&outUniqueRecord
)
371 // @@@ If this is a key do the right thing.
372 SSDatabase db
= findDbHandle(inDbHandle
);
373 SSUniqueRecord
uniqueId(db
);
375 // Setup so we always retrive the attributes even if the client
376 // doesn't want them so we can figure out if we just retrived a key.
377 CSSM_DB_RECORD_ATTRIBUTE_DATA attributes
;
378 CSSM_DB_RECORD_ATTRIBUTE_DATA_PTR pAttributes
;
380 pAttributes
= inoutAttributes
;
383 pAttributes
= &attributes
;
384 memset(pAttributes
, 0, sizeof(attributes
));
387 CSSM_RETURN result
= CSSM_DL_DataGetNext(db
->handle(), inResultsHandle
,
388 inoutAttributes
, inoutData
, uniqueId
);
391 if (result
== CSSMERR_DL_ENDOFDATA
)
394 CssmError::throwMe(result
);
397 uniqueId
->activate();
399 // If we the client didn't ask for data then it doesn't matter
400 // if this record is a key or not, just return it.
403 if (pAttributes
->DataRecordType
== CSSM_DL_DB_RECORD_PUBLIC_KEY
404 || pAttributes
->DataRecordType
== CSSM_DL_DB_RECORD_PRIVATE_KEY
405 || pAttributes
->DataRecordType
== CSSM_DL_DB_RECORD_SYMMETRIC_KEY
)
407 // This record is a key, do the right thing (tm).
408 // Allocate storage for the key.
409 CssmKey
*outKey
= DatabaseSession::alloc
<CssmKey
>();
410 new SSKey(*this, *outKey
, db
, uniqueId
, pAttributes
->DataRecordType
, *inoutData
);
412 // Free the data we retrived (keyblob)
413 allocator().free(inoutData
->Data
);
415 // Set the length and data on the data we return to the client
416 inoutData
->Length
= sizeof(*outKey
);
417 inoutData
->Data
= reinterpret_cast<uint8
*>(outKey
);
421 outUniqueRecord
= makeSSUniqueRecord(uniqueId
);
427 SSDLSession::DataAbortQuery(CSSM_DB_HANDLE inDbHandle
,
428 CSSM_HANDLE inResultsHandle
)
430 // @@@ If this is a key do the right thing.
431 SSDatabase db
= findDbHandle(inDbHandle
);
432 CSSM_RETURN result
= CSSM_DL_DataAbortQuery(db
->handle(), inResultsHandle
);
434 CssmError::throwMe(result
);
438 SSDLSession::DataGetFromUniqueRecordId(CSSM_DB_HANDLE inDbHandle
,
439 const CSSM_DB_UNIQUE_RECORD
&inUniqueRecord
,
440 CSSM_DB_RECORD_ATTRIBUTE_DATA_PTR inoutAttributes
,
443 SSDatabase db
= findDbHandle(inDbHandle
);
444 const SSUniqueRecord uniqueId
= findSSUniqueRecord(inUniqueRecord
);
446 // Setup so we always retrive the attributes even if the client
447 // doesn't want them so we can figure out if we just retrived a key.
448 CSSM_DB_RECORD_ATTRIBUTE_DATA attributes
;
449 CSSM_DB_RECORD_ATTRIBUTE_DATA_PTR pAttributes
;
451 pAttributes
= inoutAttributes
;
454 pAttributes
= &attributes
;
455 memset(pAttributes
, 0, sizeof(attributes
));
458 CSSM_RETURN result
= CSSM_DL_DataGetFromUniqueRecordId(db
->handle(),
459 uniqueId
, pAttributes
, inoutData
);
461 CssmError::throwMe(result
);
465 if (pAttributes
->DataRecordType
== CSSM_DL_DB_RECORD_PUBLIC_KEY
466 || pAttributes
->DataRecordType
== CSSM_DL_DB_RECORD_PRIVATE_KEY
467 || pAttributes
->DataRecordType
== CSSM_DL_DB_RECORD_SYMMETRIC_KEY
)
469 // This record is a key, do the right thing (tm).
470 // Allocate storage for the key.
471 CssmKey
*outKey
= DatabaseSession::alloc
<CssmKey
>();
472 new SSKey(*this, *outKey
, db
, uniqueId
, pAttributes
->DataRecordType
, *inoutData
);
474 // Free the data we retrived (keyblob)
475 allocator().free(inoutData
->Data
);
477 // Set the length and data on the data we return to the client
478 inoutData
->Length
= sizeof(*outKey
);
479 inoutData
->Data
= reinterpret_cast<uint8
*>(outKey
);
485 SSDLSession::FreeUniqueRecord(CSSM_DB_HANDLE inDbHandle
,
486 CSSM_DB_UNIQUE_RECORD
&inUniqueRecordIdentifier
)
488 killSSUniqueRecord(inUniqueRecordIdentifier
);
491 #pragma clang diagnostic push
492 #pragma clang diagnostic ignored "-Wunused-const-variable"
494 static const uint32 kGenericAttributeNames
[] =
496 'cdat', 'mdat', 'desc', 'icmt', 'crtr', 'type', 'scrp', 7, 8, 'invi', 'nega', 'cusi', 'prot', 'acct', 'svce',
500 const uint32 kNumGenericAttributes
= sizeof (kGenericAttributeNames
) / sizeof (uint32
);
502 static const uint32 kApplesharePasswordNames
[] =
504 'cdat', 'mdat', 'desc', 'icmt', 'crtr', 'type', 'scrp', 7, 8, 'invi', 'nega', 'cusi', 'prot', 'acct', 'vlme',
505 'srvr', 'ptcl', 'addr', 'ssig'
508 const uint32 kNumApplesharePasswordAttributes
= sizeof (kApplesharePasswordNames
) / sizeof (uint32
);
510 static const uint32 kInternetPasswordNames
[] =
512 'cdat', 'mdat', 'desc', 'icmt', 'crtr', 'type', 'scrp', 7, 8, 'invi', 'nega', 'cusi', 'prot', 'acct', 'sdmn',
513 'srvr', 'ptcl', 'atyp', 'port', 'path'
516 const uint32 kNumInternetPasswordAttributes
= sizeof (kInternetPasswordNames
) / sizeof (uint32
);
518 const uint32 kKeyAttributeNames
[] =
520 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
523 const uint32 kNumKeyAttributes
= sizeof (kKeyAttributeNames
) / sizeof (uint32
);
525 const uint32 kCertificateAttributeNames
[] =
527 'ctyp', 'cenc', 'labl', 'alis', 'subj', 'issu', 'snbr', 'skid', 'hpky'
530 const uint32 kNumCertificateAttributes
= sizeof (kCertificateAttributeNames
) / sizeof (uint32
);
532 const unsigned kSymmetricKeyLabel
= 6; // record id for the symmetric key
533 const unsigned kLabelSize
= 20;
534 const unsigned kNumSymmetricAttributes
= 27; // number of attributes to request
536 #pragma clang diagnostic pop
538 static void appendUInt32ToData (const uint32 value
, CssmDataContainer
&data
)
540 data
.append (CssmPolyData (uint32 (htonl (value
))));
543 static inline uint32
GetUInt32AtFinger (uint8
*&finger
)
545 uint32 a
= ((finger
[0] << 24) | (finger
[1] << 16) | (finger
[2] << 8) | finger
[3]);
546 finger
+= sizeof (uint32
);
551 SSDLSession::unwrapAttributesAndData (uint32
&numAttributes
,
552 CSSM_DB_ATTRIBUTE_DATA_PTR
&attributes
,
556 // get the number of attributes
557 uint8
* finger
= input
.Data
;
558 numAttributes
= GetUInt32AtFinger (finger
);
560 // compute the end of the data for sanity checking later
561 uint8
* maximum
= input
.Data
+ input
.Length
;
563 // make the attribute array
564 attributes
= (CSSM_DB_ATTRIBUTE_DATA
*) allocator ().malloc (numAttributes
* sizeof (CSSM_DB_ATTRIBUTE_DATA
));
566 // for each attribute, retrieve the name format, name, type, and number of values
568 for (i
= 0; i
< numAttributes
; ++i
)
570 attributes
[i
].Info
.AttributeNameFormat
= GetUInt32AtFinger (finger
);
571 attributes
[i
].Info
.Label
.AttributeID
= GetUInt32AtFinger (finger
);
572 attributes
[i
].Info
.AttributeFormat
= GetUInt32AtFinger (finger
);
573 attributes
[i
].NumberOfValues
= GetUInt32AtFinger (finger
);
575 // for each value, get the length and data
576 attributes
[i
].Value
= (CSSM_DATA
*) allocator ().malloc (sizeof (CSSM_DATA
) * attributes
[i
].NumberOfValues
);
578 for (j
= 0; j
< attributes
[i
].NumberOfValues
; ++j
)
580 attributes
[i
].Value
[j
].Length
= GetUInt32AtFinger (finger
);
581 if (attributes
[i
].Value
[j
].Length
!= 0)
583 // sanity check what we are about to do
584 if (finger
> maximum
|| finger
+ attributes
[i
].Value
[j
].Length
> maximum
)
586 CssmError::throwMe (CSSM_ERRCODE_INVALID_POINTER
);
589 attributes
[i
].Value
[j
].Data
= (uint8
*) allocator ().malloc (attributes
[i
].Value
[j
].Length
);
591 switch (attributes
[i
].Info
.AttributeFormat
)
595 memmove (attributes
[i
].Value
[j
].Data
, finger
, attributes
[i
].Value
[j
].Length
);
596 finger
+= attributes
[i
].Value
[j
].Length
;
600 case CSSM_DB_ATTRIBUTE_FORMAT_SINT32
:
601 case CSSM_DB_ATTRIBUTE_FORMAT_UINT32
:
603 *(uint32
*) attributes
[i
].Value
[j
].Data
= GetUInt32AtFinger (finger
);
607 case CSSM_DB_ATTRIBUTE_FORMAT_MULTI_UINT32
:
609 uint32
* d
= (uint32
*) attributes
[i
].Value
[j
].Data
;
610 unsigned long numValues
= attributes
[i
].Value
[j
].Length
/ sizeof (UInt32
);
613 *d
++ = GetUInt32AtFinger (finger
);
621 attributes
[i
].Value
[j
].Data
= NULL
;
627 data
.Length
= GetUInt32AtFinger (finger
);
628 if (data
.Length
!= 0)
630 // sanity check the pointer
631 if (finger
+ data
.Length
> maximum
)
633 CssmError::throwMe (CSSM_ERRCODE_INVALID_POINTER
);
636 data
.Data
= (uint8
*) allocator ().malloc (data
.Length
);
637 memmove (data
.Data
, finger
, data
.Length
);
638 finger
+= data
.Length
;
647 SSDLSession::getWrappedAttributesAndData (SSDatabase
&db
,
648 CSSM_DB_RECORDTYPE recordType
,
649 CSSM_DB_UNIQUE_RECORD_PTR recordPtr
,
650 CssmDataContainer
&output
,
653 // figure out which attributes to use
654 const uint32
* attributeNameArray
;
655 uint32 numAttributeNames
;
659 case CSSM_DL_DB_RECORD_GENERIC_PASSWORD
:
661 attributeNameArray
= kGenericAttributeNames
;
662 numAttributeNames
= kNumGenericAttributes
;
666 case CSSM_DL_DB_RECORD_INTERNET_PASSWORD
:
668 attributeNameArray
= kInternetPasswordNames
;
669 numAttributeNames
= kNumInternetPasswordAttributes
;
673 case CSSM_DL_DB_RECORD_APPLESHARE_PASSWORD
:
675 attributeNameArray
= kApplesharePasswordNames
;
676 numAttributeNames
= kNumApplesharePasswordAttributes
;
680 case CSSM_DL_DB_RECORD_X509_CERTIFICATE
:
682 attributeNameArray
= kCertificateAttributeNames
;
683 numAttributeNames
= kNumCertificateAttributes
;
687 case CSSM_DL_DB_RECORD_PUBLIC_KEY
:
688 case CSSM_DL_DB_RECORD_PRIVATE_KEY
:
689 case CSSM_DL_DB_RECORD_SYMMETRIC_KEY
:
691 attributeNameArray
= kKeyAttributeNames
;
692 numAttributeNames
= kNumKeyAttributes
;
698 CssmError::throwMe (CSSMERR_DL_FUNCTION_NOT_IMPLEMENTED
);
702 // make the attribute array
703 size_t arraySize
= numAttributeNames
* sizeof (CSSM_DB_ATTRIBUTE_DATA
);
705 CSSM_DB_ATTRIBUTE_DATA_PTR attributes
=
706 (CSSM_DB_ATTRIBUTE_DATA_PTR
) allocator ().malloc (arraySize
);
708 // initialize the array
709 memset (attributes
, 0, arraySize
);
711 for (i
= 0; i
< numAttributeNames
; ++i
)
713 attributes
[i
].Info
.AttributeNameFormat
= CSSM_DB_ATTRIBUTE_NAME_AS_INTEGER
;
714 attributes
[i
].Info
.Label
.AttributeID
= attributeNameArray
[i
];
717 // make the attribute record
718 CSSM_DB_RECORD_ATTRIBUTE_DATA attrData
;
719 attrData
.DataRecordType
= recordType
;
720 attrData
.SemanticInformation
= 0;
721 attrData
.NumberOfAttributes
= numAttributeNames
;
722 attrData
.AttributeData
= attributes
;
725 CssmDataContainer data
;
726 CSSM_RETURN result
= CSSM_DL_DataGetFromUniqueRecordId (db
->handle (),
732 CssmError::throwMe (result
);
735 // wrap the data -- write the number of attributes
736 appendUInt32ToData (numAttributeNames
, output
);
738 // for each attribute, write the type and number of values
739 for (i
= 0; i
< numAttributeNames
; ++i
)
741 appendUInt32ToData (attributes
[i
].Info
.AttributeNameFormat
, output
);
742 appendUInt32ToData (attributes
[i
].Info
.Label
.AttributeID
, output
);
743 appendUInt32ToData (attributes
[i
].Info
.AttributeFormat
, output
);
744 appendUInt32ToData (attributes
[i
].NumberOfValues
, output
);
746 // for each value, write the name format, name, length and the data
748 for (j
= 0; j
< attributes
[i
].NumberOfValues
; ++j
)
750 appendUInt32ToData ((uint32
)attributes
[i
].Value
[j
].Length
, output
);
751 if (attributes
[i
].Value
[j
].Length
!= 0)
753 switch (attributes
[i
].Info
.AttributeFormat
)
757 output
.append (CssmPolyData (attributes
[i
].Value
[j
]));
761 case CSSM_DB_ATTRIBUTE_FORMAT_SINT32
:
762 case CSSM_DB_ATTRIBUTE_FORMAT_UINT32
:
764 uint32 n
= htonl (*(uint32
*) attributes
[i
].Value
[j
].Data
);
766 d
.Length
= sizeof (uint32
);
767 d
.Data
= (uint8
*) &n
;
768 output
.append (CssmPolyData (d
));
776 // write the length of the data
777 appendUInt32ToData ((uint32
)data
.Length
, output
);
779 // write the data itself
780 if (data
.Length
!= 0)
782 output
.append (CssmPolyData (data
));
786 for (i
= 0; i
< numAttributeNames
; ++i
)
789 for (j
= 0; j
< attributes
[i
].NumberOfValues
; ++j
)
791 allocator ().free (attributes
[i
].Value
[j
].Data
);
794 allocator ().free (attributes
[i
].Value
);
797 allocator ().free (attributes
);
799 // copy out the data if the caller needs it
802 dataBlob
->Data
= data
.Data
;
803 dataBlob
->Length
= data
.Length
;
810 SSDLSession::getUniqueIdForSymmetricKey (SSDatabase
&db
, CSSM_DATA
&label
,
811 CSSM_DB_UNIQUE_RECORD_PTR
&uniqueRecord
)
813 // set up a query to get the key
814 CSSM_SELECTION_PREDICATE predicate
;
815 predicate
.DbOperator
= CSSM_DB_EQUAL
;
816 predicate
.Attribute
.Info
.AttributeNameFormat
= CSSM_DB_ATTRIBUTE_NAME_AS_INTEGER
;
817 predicate
.Attribute
.Info
.Label
.AttributeID
= kSymmetricKeyLabel
;
818 predicate
.Attribute
.Info
.AttributeFormat
= CSSM_DB_ATTRIBUTE_FORMAT_BLOB
;
819 predicate
.Attribute
.NumberOfValues
= 1;
820 // the label of the corresponding key is the first 20 bytes of the blob we returned
821 predicate
.Attribute
.Value
= &label
;
824 query
.RecordType
= CSSM_DL_DB_RECORD_SYMMETRIC_KEY
;
825 query
.Conjunctive
= CSSM_DB_NONE
;
826 query
.NumSelectionPredicates
= 1;
827 query
.SelectionPredicate
= &predicate
;
829 // fill out the record data
830 CSSM_DB_RECORD_ATTRIBUTE_DATA recordAttributeData
;
831 recordAttributeData
.DataRecordType
= CSSM_DL_DB_RECORD_SYMMETRIC_KEY
;
832 recordAttributeData
.SemanticInformation
= 0;
833 recordAttributeData
.NumberOfAttributes
= 0;
834 recordAttributeData
.AttributeData
= NULL
;
838 CSSM_RETURN result
= CSSM_DL_DataGetFirst (db
->handle (), &query
, &handle
, &recordAttributeData
, NULL
,
842 CssmError::throwMe (result
);
846 CSSM_DL_DataAbortQuery (db
->handle (), handle
);
850 SSDLSession::getCorrespondingSymmetricKey (SSDatabase
&db
, CSSM_DATA
&labelData
, CssmDataContainer
&data
)
853 CSSM_DB_UNIQUE_RECORD_PTR uniqueRecord
;
854 getUniqueIdForSymmetricKey (db
, labelData
, uniqueRecord
);
856 // from this. get the wrapped attributes and data
857 getWrappedAttributesAndData (db
, CSSM_DL_DB_RECORD_SYMMETRIC_KEY
, uniqueRecord
, data
, NULL
);
859 // clean up after the query
860 CSSM_DL_FreeUniqueRecord (db
->handle (), uniqueRecord
);
863 void SSDLSession::doGetWithoutEncryption (SSDatabase
&db
, const void *inInputParams
, void **outOutputParams
)
865 CSSM_APPLECSPDL_DB_GET_WITHOUT_ENCRYPTION_PARAMETERS
* params
=
866 (CSSM_APPLECSPDL_DB_GET_WITHOUT_ENCRYPTION_PARAMETERS
*) inInputParams
;
868 SSUniqueRecord uniqueID
= findSSUniqueRecord(*(params
->uniqueID
));
870 CSSM_DATA
*outputData
= (CSSM_DATA
*) outOutputParams
;
871 CssmDataContainer output
;
873 // get the record type and requested attributes from the DL
874 CssmDataContainer data
;
875 CSSM_RETURN result
= CSSM_DL_DataGetFromUniqueRecordId(db
->handle(),
882 CssmError::throwMe(result
);
885 // get the real data and all of the attributes from the DL
886 CssmDataContainer blobData
;
887 getWrappedAttributesAndData (db
, params
->attributes
->DataRecordType
, uniqueID
, data
, &blobData
);
889 // write out the data blob
890 appendUInt32ToData ((uint32
)data
.Length
, output
);
891 output
.append (CssmPolyData (data
));
893 // figure out what we need to do with the key blob
894 CssmDataContainer key
;
895 switch (params
->attributes
->DataRecordType
)
897 case CSSM_DL_DB_RECORD_GENERIC_PASSWORD
:
898 case CSSM_DL_DB_RECORD_INTERNET_PASSWORD
:
899 case CSSM_DL_DB_RECORD_APPLESHARE_PASSWORD
:
901 // the label is the first kLabelSize bytes of the resultant data blob
902 CSSM_DATA label
= {kLabelSize
, blobData
.Data
};
905 getCorrespondingSymmetricKey (db
, label
, key
);
916 // write out the length of the key blob
917 appendUInt32ToData ((uint32
)key
.Length
, output
);
922 output
.append (CssmPolyData (key
));
925 // copy out the results
926 outputData
->Data
= output
.Data
;
928 outputData
->Length
= output
.Length
;
933 SSDLSession::cleanupAttributes (uint32 numAttributes
, CSSM_DB_ATTRIBUTE_DATA_PTR attributes
)
936 for (i
= 0; i
< numAttributes
; ++i
)
939 for (j
= 0; j
< attributes
[i
].NumberOfValues
; ++j
)
941 free (attributes
[i
].Value
[j
].Data
);
944 free (attributes
[i
].Value
);
951 SSDLSession::doModifyWithoutEncryption (SSDatabase
&db
, const void* inInputParams
, void** outOutputParams
)
954 CSSM_APPLECSPDL_DB_MODIFY_WITHOUT_ENCRYPTION_PARAMETERS
* params
=
955 (CSSM_APPLECSPDL_DB_MODIFY_WITHOUT_ENCRYPTION_PARAMETERS
*) inInputParams
;
957 // extract the data for this modify.
958 uint8
* finger
= params
->data
->Data
;
960 data
.Length
= GetUInt32AtFinger (finger
);
962 if (data
.Length
+ sizeof (UInt32
) > params
->data
->Length
)
964 CssmError::throwMe (CSSM_ERRCODE_INVALID_POINTER
);
968 finger
+= data
.Length
;
970 // reconstruct the attributes and data
971 uint32 numAttributes
;
972 CSSM_DB_ATTRIBUTE_DATA_PTR attributes
;
973 CssmDataContainer dataBlob
;
975 unwrapAttributesAndData (numAttributes
, attributes
, dataBlob
, data
);
977 CSSM_DB_RECORD_ATTRIBUTE_DATA attrData
;
978 attrData
.DataRecordType
= params
->attributes
->DataRecordType
;
979 attrData
.SemanticInformation
= 0;
980 attrData
.NumberOfAttributes
= numAttributes
;
981 attrData
.AttributeData
= attributes
;
983 // get the unique ID for this record (from the db's perspective)
984 SSUniqueRecord uniqueID
= findSSUniqueRecord(*(params
->uniqueID
));
985 CSSM_DB_UNIQUE_RECORD
*uniqueIDPtr
= uniqueID
; // for readability. There's cast overloading
988 switch (attrData
.DataRecordType
)
990 case CSSM_DL_DB_RECORD_GENERIC_PASSWORD
:
991 case CSSM_DL_DB_RECORD_INTERNET_PASSWORD
:
992 case CSSM_DL_DB_RECORD_APPLESHARE_PASSWORD
:
994 // read off the data so that we can update the key
995 CssmDataContainer oldData
;
996 result
= CSSM_DL_DataGetFromUniqueRecordId (db
->handle(),
1002 CssmError::throwMe (result
);
1005 CSSM_DB_MODIFY_MODE modifyMode
= params
->modifyMode
;
1007 // parse the key data blob
1008 CssmDataContainer keyBlob
;
1009 data
.Length
= GetUInt32AtFinger (finger
);
1012 CSSM_DB_RECORD_ATTRIBUTE_DATA
* attrDataPtr
= NULL
;
1013 CSSM_DB_RECORD_ATTRIBUTE_DATA attrData
;
1015 CSSM_DATA labelData
= {kLabelSize
, oldData
.Data
};
1016 CSSM_DB_UNIQUE_RECORD_PTR recordID
;
1017 getUniqueIdForSymmetricKey (db
, labelData
, recordID
);
1019 CSSM_DB_ATTRIBUTE_DATA_PTR keyAttributes
;
1020 uint32 numKeyAttributes
;
1021 unwrapAttributesAndData (numKeyAttributes
, keyAttributes
, keyBlob
, data
);
1023 // make the attribute data
1024 attrData
.DataRecordType
= params
->recordType
;
1025 attrData
.SemanticInformation
= 0;
1026 attrData
.NumberOfAttributes
= numKeyAttributes
;
1027 attrData
.AttributeData
= keyAttributes
;
1029 attrDataPtr
= &attrData
;
1031 result
= CSSM_DL_DataModify (db
->handle(),
1032 CSSM_DL_DB_RECORD_SYMMETRIC_KEY
,
1039 CSSM_DL_FreeUniqueRecord (db
->handle (), recordID
);
1041 cleanupAttributes (numKeyAttributes
, keyAttributes
);
1051 // save off the new data
1052 result
= CSSM_DL_DataModify(db
->handle(),
1057 params
->modifyMode
);
1060 cleanupAttributes (numAttributes
, attributes
);
1064 CssmError::throwMe(result
);
1070 SSDLSession::doInsertWithoutEncryption (SSDatabase
&db
, const void* inInputParams
, void** outOutputParams
)
1074 CSSM_APPLECSPDL_DB_INSERT_WITHOUT_ENCRYPTION_PARAMETERS
* params
=
1075 (CSSM_APPLECSPDL_DB_INSERT_WITHOUT_ENCRYPTION_PARAMETERS
*) inInputParams
;
1077 // extract the data for this insert.
1078 uint8
* finger
= params
->data
.Data
;
1080 data
.Length
= GetUInt32AtFinger (finger
);
1082 finger
+= data
.Length
;
1084 // reconstruct the attributes and data
1085 uint32 numAttributes
;
1086 CSSM_DB_ATTRIBUTE_DATA_PTR attributes
;
1089 unwrapAttributesAndData (numAttributes
, attributes
, dataBlob
, data
);
1091 // make the attribute data
1092 CSSM_DB_RECORD_ATTRIBUTE_DATA attrData
;
1093 attrData
.DataRecordType
= params
->recordType
;
1094 attrData
.SemanticInformation
= 0;
1095 attrData
.NumberOfAttributes
= numAttributes
;
1096 attrData
.AttributeData
= attributes
;
1098 // insert into the database
1099 SSUniqueRecord
uniqueID (db
);
1100 result
= CSSM_DL_DataInsert (db
->handle(), params
->recordType
,
1106 allocator ().free (dataBlob
.Data
);
1107 cleanupAttributes (numAttributes
, attributes
);
1109 // attach into the CSP/DL mechanism
1110 CSSM_DB_UNIQUE_RECORD_PTR newRecord
= makeSSUniqueRecord(uniqueID
);
1111 *(CSSM_DB_UNIQUE_RECORD_PTR
*) outOutputParams
= newRecord
;
1115 CssmError::throwMe(result
);
1118 // Get the key data for this insert
1119 data
.Length
= GetUInt32AtFinger (finger
);
1120 if (data
.Length
!= 0)
1124 // parse the key data blob
1125 unwrapAttributesAndData (numAttributes
, attributes
, dataBlob
, data
);
1127 // make the attribute data
1128 CSSM_DB_RECORD_ATTRIBUTE_DATA attrData
;
1129 attrData
.DataRecordType
= params
->recordType
;
1130 attrData
.SemanticInformation
= 0;
1131 attrData
.NumberOfAttributes
= numAttributes
;
1132 attrData
.AttributeData
= attributes
;
1134 // insert the key data into the symmetric key table
1135 CSSM_DB_UNIQUE_RECORD_PTR uniqueRecord
;
1136 result
= CSSM_DL_DataInsert (db
->handle(), CSSM_DL_DB_RECORD_SYMMETRIC_KEY
, &attrData
, &dataBlob
,
1140 CssmError::throwMe (result
);
1143 // clean up after inserting the key
1144 CSSM_DL_FreeUniqueRecord (db
->handle (), uniqueRecord
);
1145 allocator ().free (dataBlob
.Data
);
1146 cleanupAttributes (numAttributes
, attributes
);
1151 SSDLSession::doConvertRecordIdentifier (SSDatabase
&db
, const void *inInputParams
, void **outOutputParams
)
1153 SSUniqueRecord
uniqueId (db
);
1155 // clone the unique record
1156 CSSM_DB_UNIQUE_RECORD_PTR clone
= (CSSM_DB_UNIQUE_RECORD_PTR
) allocator ().malloc (sizeof (CSSM_DB_UNIQUE_RECORD
));
1157 *clone
= *(CSSM_DB_UNIQUE_RECORD_PTR
) inInputParams
;
1159 // set the value of the unique record
1160 uniqueId
->setUniqueRecordPtr (clone
);
1162 // byte swap the retrieved record pointer to host order
1163 uint32
* idArray
= (uint32
*) clone
->RecordIdentifier
.Data
;
1164 idArray
[0] = ntohl (idArray
[0]);
1165 idArray
[1] = ntohl (idArray
[1]);
1166 idArray
[2] = ntohl (idArray
[2]);
1168 CSSM_DB_UNIQUE_RECORD_PTR newRecord
= makeSSUniqueRecord(uniqueId
);
1169 *(CSSM_DB_UNIQUE_RECORD_PTR
*) outOutputParams
= newRecord
;
1173 SSDLSession::PassThrough(CSSM_DB_HANDLE inDbHandle
,
1174 uint32 inPassThroughId
,
1175 const void *inInputParams
,
1176 void **outOutputParams
)
1178 if (inPassThroughId
== CSSM_APPLECSPDL_DB_CREATE_WITH_BLOB
)
1180 CSSM_APPLE_CSPDL_DB_CREATE_WITH_BLOB_PARAMETERS
* params
= (CSSM_APPLE_CSPDL_DB_CREATE_WITH_BLOB_PARAMETERS
*) inInputParams
;
1181 CreateWithBlob(params
->dbName
, params
->dbLocation
, *params
->dbInfo
, params
->accessRequest
, params
->openParameters
, *params
->blob
,
1182 * (CSSM_DB_HANDLE
*) outOutputParams
);
1186 SSDatabase db
= findDbHandle(inDbHandle
);
1187 switch (inPassThroughId
)
1189 case CSSM_APPLECSPDL_DB_LOCK
:
1192 case CSSM_APPLECSPDL_DB_UNLOCK
:
1194 db
->unlock(*reinterpret_cast<const CSSM_DATA
*>(inInputParams
));
1198 case CSSM_APPLECSPDL_DB_STASH
:
1201 case CSSM_APPLECSPDL_DB_STASH_CHECK
:
1204 case CSSM_APPLECSPDL_DB_GET_SETTINGS
:
1206 if (!outOutputParams
)
1207 CssmError::throwMe(CSSM_ERRCODE_INVALID_OUTPUT_POINTER
);
1209 CSSM_APPLECSPDL_DB_SETTINGS_PARAMETERS_PTR params
=
1210 DatabaseSession::alloc
<CSSM_APPLECSPDL_DB_SETTINGS_PARAMETERS
>();
1215 db
->getSettings(idleTimeout
, lockOnSleep
);
1216 params
->idleTimeout
= idleTimeout
;
1217 params
->lockOnSleep
= lockOnSleep
;
1221 allocator().free(params
);
1224 *reinterpret_cast<CSSM_APPLECSPDL_DB_SETTINGS_PARAMETERS_PTR
*>(outOutputParams
) = params
;
1227 case CSSM_APPLECSPDL_DB_SET_SETTINGS
:
1230 CssmError::throwMe(CSSM_ERRCODE_INVALID_INPUT_POINTER
);
1232 const CSSM_APPLECSPDL_DB_SETTINGS_PARAMETERS
*params
=
1233 reinterpret_cast<const CSSM_APPLECSPDL_DB_SETTINGS_PARAMETERS
*>(inInputParams
);
1234 db
->setSettings(params
->idleTimeout
, params
->lockOnSleep
);
1237 case CSSM_APPLECSPDL_DB_IS_LOCKED
:
1239 if (!outOutputParams
)
1240 CssmError::throwMe(CSSM_ERRCODE_INVALID_OUTPUT_POINTER
);
1242 CSSM_APPLECSPDL_DB_IS_LOCKED_PARAMETERS_PTR params
=
1243 DatabaseSession::alloc
<CSSM_APPLECSPDL_DB_IS_LOCKED_PARAMETERS
>();
1246 params
->isLocked
= db
->isLocked();
1250 allocator().free(params
);
1253 *reinterpret_cast<CSSM_APPLECSPDL_DB_IS_LOCKED_PARAMETERS_PTR
*>(outOutputParams
) = params
;
1256 case CSSM_APPLECSPDL_DB_CHANGE_PASSWORD
:
1259 CssmError::throwMe(CSSM_ERRCODE_INVALID_INPUT_POINTER
);
1261 const CSSM_APPLECSPDL_DB_CHANGE_PASSWORD_PARAMETERS
*params
=
1262 reinterpret_cast<const CSSM_APPLECSPDL_DB_CHANGE_PASSWORD_PARAMETERS
*>(inInputParams
);
1263 db
->changePassphrase(params
->accessCredentials
);
1266 case CSSM_APPLECSPDL_DB_GET_HANDLE
:
1268 using SecurityServer::DbHandle
;
1269 Required(outOutputParams
, CSSM_ERRCODE_INVALID_OUTPUT_POINTER
);
1270 *reinterpret_cast<CSSM_DL_DB_HANDLE
*>(outOutputParams
) = db
->handle();
1273 case CSSM_APPLECSPDL_CSP_RECODE
:
1276 CssmError::throwMe(CSSM_ERRCODE_INVALID_INPUT_POINTER
);
1278 const CSSM_APPLECSPDL_RECODE_PARAMETERS
*params
=
1279 reinterpret_cast<const CSSM_APPLECSPDL_RECODE_PARAMETERS
*>(inInputParams
);
1281 db
->recode(CssmData::overlay(params
->dbBlob
),
1282 CssmData::overlay(params
->extraData
));
1285 case CSSM_APPLECSPDL_DB_GET_RECORD_IDENTIFIER
:
1287 SSUniqueRecord uniqueID
= findSSUniqueRecord(*(CSSM_DB_UNIQUE_RECORD_PTR
) inInputParams
);
1288 db
->getRecordIdentifier(uniqueID
, *reinterpret_cast<CSSM_DATA
*>(outOutputParams
));
1291 case CSSM_APPLECSPDL_DB_COPY_BLOB
:
1293 // make the output parameters
1294 db
->ssCopyBlob(*reinterpret_cast<CSSM_DATA
*>(outOutputParams
));
1297 case CSSM_APPLECSPDL_DB_INSERT_WITHOUT_ENCRYPTION
:
1299 doInsertWithoutEncryption (db
, inInputParams
, outOutputParams
);
1302 case CSSM_APPLECSPDL_DB_MODIFY_WITHOUT_ENCRYPTION
:
1304 doModifyWithoutEncryption (db
, inInputParams
, outOutputParams
);
1307 case CSSM_APPLECSPDL_DB_GET_WITHOUT_ENCRYPTION
:
1309 doGetWithoutEncryption (db
, inInputParams
, outOutputParams
);
1312 case CSSM_APPLECSPDL_DB_CONVERT_RECORD_IDENTIFIER
:
1314 doConvertRecordIdentifier (db
, inInputParams
, outOutputParams
);
1317 case CSSM_APPLECSPDL_DB_GET_BLOB_VERSION
:
1319 *((uint32
*) *outOutputParams
) = db
->dbBlobVersion();
1322 case CSSM_APPLECSPDL_DB_RECODE_TO_BLOB_VERSION
:
1324 *((uint32
*) *outOutputParams
) = db
->recodeDbToVersion(*((uint32
*) inInputParams
));
1327 case CSSM_APPLECSPDL_DB_RECODE_FINISHED
:
1329 db
->recodeFinished();
1332 case CSSM_APPLECSPDL_DB_TAKE_FILE_LOCK
:
1337 case CSSM_APPLECSPDL_DB_RELEASE_FILE_LOCK
:
1339 db
->releaseFileLock(*((bool*) inInputParams
));
1342 case CSSM_APPLECSPDL_DB_MAKE_BACKUP
:
1347 case CSSM_APPLECSPDL_DB_MAKE_COPY
:
1349 db
->makeCopy((const char*) inInputParams
);
1352 case CSSM_APPLECSPDL_DB_DELETE_FILE
:
1357 case CSSM_APPLECSPDL_DB_CLONE
:
1359 SSDatabase ssdb
= db
->ssCloneTo(*((DLDbIdentifier
*) inInputParams
));
1360 *((CSSM_DB_HANDLE
*) outOutputParams
) = makeDbHandle(ssdb
);
1365 CSSM_RETURN result
= CSSM_DL_PassThrough(db
->handle(), inPassThroughId
, inInputParams
, outOutputParams
);
1367 CssmError::throwMe(result
);
1374 SSDLSession::makeDbHandle(SSDatabase
&inDb
)
1376 StLock
<Mutex
> _(mDbHandleLock
);
1377 CSSM_DB_HANDLE aDbHandle
= inDb
->handle().DBHandle
;
1379 inserted
= mDbHandleMap
.insert(DbHandleMap::value_type(aDbHandle
, inDb
)).second
;
1381 // fprintf(stderr, "%p Added %p to %p\n", pthread_self(), (void*) aDbHandle, (void*) this);
1386 SSDLSession::killDbHandle(CSSM_DB_HANDLE inDbHandle
)
1388 StLock
<Mutex
> _(mDbHandleLock
);
1389 DbHandleMap::iterator it
= mDbHandleMap
.find(inDbHandle
);
1390 if (it
== mDbHandleMap
.end())
1392 // fprintf(stderr, "Can't find %p in %p\n", (void*) inDbHandle, this);
1393 CssmError::throwMe(CSSMERR_DL_INVALID_DB_HANDLE
);
1396 SSDatabase db
= it
->second
;
1397 // fprintf(stderr, "%p Removed %p from %p\n", pthread_self(), (void*) it->first, (void*) this);
1398 mDbHandleMap
.erase(it
);
1403 SSDLSession::findDbHandle(CSSM_DB_HANDLE inDbHandle
)
1405 StLock
<Mutex
> _(mDbHandleLock
);
1406 // fprintf(stderr, "%p Looking for %p in %p\n", pthread_self(), (void*) inDbHandle, (void*) this);
1407 DbHandleMap::iterator it
= mDbHandleMap
.find(inDbHandle
);
1408 if (it
== mDbHandleMap
.end())
1410 // fprintf(stderr, "%p Can't find %p in %p\n", pthread_self(), (void*) inDbHandle, this);
1411 DbHandleMap::iterator it
= mDbHandleMap
.begin();
1412 while (it
!= mDbHandleMap
.end())
1414 // fprintf(stderr, "\t%p\n", (void*) it->first);
1418 CssmError::throwMe(CSSMERR_DL_INVALID_DB_HANDLE
);
1424 CSSM_DB_UNIQUE_RECORD_PTR
1425 SSDLSession::makeSSUniqueRecord(SSUniqueRecord
&uniqueId
)
1427 StLock
<Mutex
> _(mSSUniqueRecordLock
);
1428 CSSM_HANDLE ref
= CSSM_HANDLE(static_cast<CSSM_DB_UNIQUE_RECORD
*>(uniqueId
));
1430 inserted
= mSSUniqueRecordMap
.insert(SSUniqueRecordMap::value_type(ref
, uniqueId
)).second
;
1432 return createUniqueRecord(ref
);
1436 SSDLSession::killSSUniqueRecord(CSSM_DB_UNIQUE_RECORD
&inUniqueRecord
)
1438 CSSM_HANDLE ref
= parseUniqueRecord(inUniqueRecord
);
1439 StLock
<Mutex
> _(mSSUniqueRecordLock
);
1440 SSUniqueRecordMap::iterator it
= mSSUniqueRecordMap
.find(ref
);
1441 if (it
== mSSUniqueRecordMap
.end())
1442 CssmError::throwMe(CSSMERR_DL_INVALID_RECORD_UID
);
1444 SSUniqueRecord uniqueRecord
= it
->second
;
1445 mSSUniqueRecordMap
.erase(it
);
1446 freeUniqueRecord(inUniqueRecord
);
1447 return uniqueRecord
;
1451 SSDLSession::findSSUniqueRecord(const CSSM_DB_UNIQUE_RECORD
&inUniqueRecord
)
1453 CSSM_HANDLE ref
= parseUniqueRecord(inUniqueRecord
);
1454 StLock
<Mutex
> _(mSSUniqueRecordLock
);
1455 SSUniqueRecordMap::iterator it
= mSSUniqueRecordMap
.find(ref
);
1456 if (it
== mSSUniqueRecordMap
.end())
1457 CssmError::throwMe(CSSMERR_DL_INVALID_RECORD_UID
);
1462 CSSM_DB_UNIQUE_RECORD_PTR
1463 SSDLSession::createUniqueRecord(CSSM_HANDLE ref
)
1465 CSSM_DB_UNIQUE_RECORD
*aUniqueRecord
= DatabaseSession::alloc
<CSSM_DB_UNIQUE_RECORD
>();
1466 memset(aUniqueRecord
, 0, sizeof(CSSM_DB_UNIQUE_RECORD
));
1467 aUniqueRecord
->RecordIdentifier
.Length
= sizeof(CSSM_HANDLE
);
1470 aUniqueRecord
->RecordIdentifier
.Data
= DatabaseSession::alloc
<uint8
>(sizeof(CSSM_HANDLE
));
1471 *reinterpret_cast<CSSM_HANDLE
*>(aUniqueRecord
->RecordIdentifier
.Data
) = ref
;
1475 free(aUniqueRecord
);
1479 return aUniqueRecord
;
1483 SSDLSession::parseUniqueRecord(const CSSM_DB_UNIQUE_RECORD
&inUniqueRecord
)
1485 if (inUniqueRecord
.RecordIdentifier
.Length
!= sizeof(CSSM_HANDLE
))
1486 CssmError::throwMe(CSSMERR_DL_INVALID_RECORD_UID
);
1488 return *reinterpret_cast<CSSM_HANDLE
*>(inUniqueRecord
.RecordIdentifier
.Data
);
1492 SSDLSession::freeUniqueRecord(CSSM_DB_UNIQUE_RECORD
&inUniqueRecord
)
1494 if (inUniqueRecord
.RecordIdentifier
.Length
!= 0
1495 && inUniqueRecord
.RecordIdentifier
.Data
!= NULL
)
1497 inUniqueRecord
.RecordIdentifier
.Length
= 0;
1498 allocator().free(inUniqueRecord
.RecordIdentifier
.Data
);
1500 allocator().free(&inUniqueRecord
);