2 * Copyright (c) 2000-2004 Apple Computer, Inc. All Rights Reserved.
4 * @APPLE_LICENSE_HEADER_START@
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. Please obtain a copy of the License at
10 * http://www.opensource.apple.com/apsl/ and read it before using this
13 * The Original Code and all software distributed under the License are
14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
18 * Please see the License for the specific language governing rights and
19 * limitations under the License.
21 * @APPLE_LICENSE_HEADER_END@
24 #include <Security/SecKeychain.h>
25 #include <Security/SecKeychainPriv.h>
26 #include <security_keychain/KCCursor.h>
27 #include <security_cdsa_utilities/cssmdata.h>
28 #include <security_keychain/KCExceptions.h>
29 #include <securityd_client/ssblob.h>
30 #include "SecBridge.h"
31 #include "CCallbackMgr.h"
32 #include <security_cdsa_utilities/Schema.h>
36 SecKeychainGetTypeID(void)
40 return gTypes().KeychainImpl
.typeID
;
42 END_SECAPI1(_kCFRuntimeNotATypeID
)
47 SecKeychainGetVersion(UInt32
*returnVers
)
52 *returnVers
= 0x02028000;
58 SecKeychainOpen(const char *pathName
, SecKeychainRef
*keychainRef
)
62 RequiredParam(keychainRef
)=globals().storageManager
.make(pathName
, false)->handle();
69 SecKeychainOpenWithGuid(const CSSM_GUID
*guid
, uint32 subserviceId
, uint32 subserviceType
, const char* dbName
,
70 const CSSM_NET_ADDRESS
*dbLocation
, SecKeychainRef
*keychain
)
74 // range check parameters
76 RequiredParam (dbName
);
78 // create a DLDbIdentifier that describes what should be opened
79 const CSSM_VERSION
*version
= NULL
;
80 const CssmSubserviceUid
ssuid(*guid
, version
, subserviceId
, subserviceType
);
81 DLDbIdentifier
dLDbIdentifier(ssuid
, dbName
, dbLocation
);
83 // make a keychain from the supplied info
84 RequiredParam(keychain
) = globals().storageManager
.makeKeychain(dLDbIdentifier
, false)->handle ();
91 SecKeychainCreate(const char *pathName
, UInt32 passwordLength
, const void *password
,
92 Boolean promptUser
, SecAccessRef initialAccess
, SecKeychainRef
*keychainRef
)
96 KCThrowParamErrIf_(!pathName
);
97 Keychain keychain
= globals().storageManager
.make(pathName
);
99 // @@@ the call to StorageManager::make above leaves keychain the the cache.
100 // If the create below fails we should probably remove it.
105 KCThrowParamErrIf_(!password
);
106 keychain
->create(passwordLength
, password
);
109 RequiredParam(keychainRef
)=keychain
->handle();
116 SecKeychainDelete(SecKeychainRef keychainOrArray
)
120 KCThrowIf_(!keychainOrArray
, errSecInvalidKeychain
);
121 StorageManager::KeychainList keychains
;
122 globals().storageManager
.optionalSearchList(keychainOrArray
, keychains
);
124 globals().storageManager
.remove(keychains
, true);
131 SecKeychainSetSettings(SecKeychainRef keychainRef
, const SecKeychainSettings
*newSettings
)
135 Keychain keychain
= Keychain::optional(keychainRef
);
136 if (newSettings
->version
==SEC_KEYCHAIN_SETTINGS_VERS1
)
138 UInt32 lockInterval
=newSettings
->lockInterval
;
139 bool lockOnSleep
=newSettings
->lockOnSleep
;
140 keychain
->setSettings(lockInterval
, lockOnSleep
);
148 SecKeychainCopySettings(SecKeychainRef keychainRef
, SecKeychainSettings
*outSettings
)
152 Keychain keychain
= Keychain::optional(keychainRef
);
153 if (outSettings
->version
==SEC_KEYCHAIN_SETTINGS_VERS1
)
158 keychain
->getSettings(lockInterval
, lockOnSleep
);
159 outSettings
->lockInterval
=lockInterval
;
160 outSettings
->lockOnSleep
=lockOnSleep
;
168 SecKeychainUnlock(SecKeychainRef keychainRef
, UInt32 passwordLength
, const void *password
, Boolean usePassword
)
172 Keychain keychain
= Keychain::optional(keychainRef
);
175 keychain
->unlock(CssmData(const_cast<void *>(password
), passwordLength
));
184 SecKeychainLock(SecKeychainRef keychainRef
)
188 Keychain keychain
= Keychain::optional(keychainRef
);
196 SecKeychainLockAll(void)
200 globals().storageManager
.lockAll();
206 OSStatus
SecKeychainResetLogin(UInt32 passwordLength
, const void* password
, Boolean resetSearchList
)
210 // Get the current user (using fallback method if necessary)
212 char* uName
= getenv("USER");
213 string userName
= uName
? uName
: "";
214 if ( userName
.length() == 0 )
216 uid_t uid
= geteuid();
217 if (!uid
) uid
= getuid();
218 struct passwd
*pw
= getpwuid(uid
); // fallback case...
220 userName
= pw
->pw_name
;
223 if ( userName
.length() == 0 ) // did we ultimately get one?
224 MacOSError::throwMe(errAuthorizationInternal
);
228 // Clear the plist and move aside (rename) the existing login.keychain
229 globals().storageManager
.resetKeychain(resetSearchList
);
231 // Create the login keychain without UI
232 globals().storageManager
.login(userName
.length(), userName
.c_str(), passwordLength
, password
);
234 // Set it as the default
235 Keychain keychain
= globals().storageManager
.loginKeychain();
236 globals().storageManager
.defaultKeychain(keychain
);
240 // Create the login keychain, prompting for password
241 // (implicitly calls resetKeychain, login, and defaultKeychain)
242 globals().storageManager
.makeLoginAuthUI(NULL
);
245 // Post a "list changed" event after a reset, so apps can refresh their list.
246 // Make sure we are not holding mLock when we post this event.
247 KCEventNotifier::PostKeychainEvent(kSecKeychainListChangedEvent
);
253 SecKeychainCopyDefault(SecKeychainRef
*keychainRef
)
257 RequiredParam(keychainRef
)=globals().storageManager
.defaultKeychain()->handle();
264 SecKeychainSetDefault(SecKeychainRef keychainRef
)
268 globals().storageManager
.defaultKeychain(Keychain::optional(keychainRef
));
273 OSStatus
SecKeychainCopySearchList(CFArrayRef
*searchList
)
277 RequiredParam(searchList
);
278 StorageManager
&smr
= globals().storageManager
;
279 StorageManager::KeychainList keychainList
;
280 smr
.getSearchList(keychainList
);
281 *searchList
= smr
.convertFromKeychainList(keychainList
);
286 OSStatus
SecKeychainSetSearchList(CFArrayRef searchList
)
290 RequiredParam(searchList
);
291 StorageManager
&smr
= globals().storageManager
;
292 StorageManager::KeychainList keychainList
;
293 smr
.convertToKeychainList(searchList
, keychainList
);
294 smr
.setSearchList(keychainList
);
299 OSStatus
SecKeychainCopyDomainDefault(SecPreferencesDomain domain
, SecKeychainRef
*keychainRef
)
303 RequiredParam(keychainRef
)=globals().storageManager
.defaultKeychain(domain
)->handle();
308 OSStatus
SecKeychainSetDomainDefault(SecPreferencesDomain domain
, SecKeychainRef keychainRef
)
312 globals().storageManager
.defaultKeychain(domain
, Keychain::optional(keychainRef
));
317 OSStatus
SecKeychainCopyDomainSearchList(SecPreferencesDomain domain
, CFArrayRef
*searchList
)
321 RequiredParam(searchList
);
322 StorageManager
&smr
= globals().storageManager
;
323 StorageManager::KeychainList keychainList
;
324 smr
.getSearchList(domain
, keychainList
);
325 *searchList
= smr
.convertFromKeychainList(keychainList
);
330 OSStatus
SecKeychainSetDomainSearchList(SecPreferencesDomain domain
, CFArrayRef searchList
)
334 RequiredParam(searchList
);
335 StorageManager
&smr
= globals().storageManager
;
336 StorageManager::KeychainList keychainList
;
337 smr
.convertToKeychainList(searchList
, keychainList
);
338 smr
.setSearchList(domain
, keychainList
);
343 OSStatus
SecKeychainSetPreferenceDomain(SecPreferencesDomain domain
)
347 globals().storageManager
.domain(domain
);
352 OSStatus
SecKeychainGetPreferenceDomain(SecPreferencesDomain
*domain
)
356 *domain
= globals().storageManager
.domain();
363 SecKeychainGetStatus(SecKeychainRef keychainRef
, SecKeychainStatus
*keychainStatus
)
367 RequiredParam(keychainStatus
) = (SecKeychainStatus
)Keychain::optional(keychainRef
)->status();
374 SecKeychainGetPath(SecKeychainRef keychainRef
, UInt32
*ioPathLength
, char *pathName
)
378 RequiredParam(pathName
);
379 RequiredParam(ioPathLength
);
381 const char *name
= Keychain::optional(keychainRef
)->name();
382 UInt32 nameLen
= strlen(name
);
383 UInt32 callersLen
= *ioPathLength
;
384 *ioPathLength
= nameLen
;
385 if (nameLen
+1 > callersLen
) // if the client's buffer is too small (including null-termination), throw
386 return errSecBufferTooSmall
;
387 strncpy(pathName
, name
, nameLen
);
388 pathName
[nameLen
] = 0;
389 *ioPathLength
= nameLen
; // set the length.
397 SecKeychainListGetCount(void)
401 return globals().storageManager
.size();
409 SecKeychainListCopyKeychainAtIndex(UInt16 index
, SecKeychainRef
*keychainRef
)
413 KeychainCore::StorageManager
&smgr
=KeychainCore::globals().storageManager
;
414 RequiredParam(keychainRef
)=smgr
[index
]->handle();
422 SecKeychainListRemoveKeychain(SecKeychainRef
*keychainRef
)
426 Required(keychainRef
);
427 Keychain keychain
= Keychain::optional(*keychainRef
);
428 StorageManager::KeychainList keychainList
;
429 keychainList
.push_back(keychain
);
430 globals().storageManager
.remove(keychainList
);
438 SecKeychainAttributeInfoForItemID(SecKeychainRef keychainRef
, UInt32 itemID
, SecKeychainAttributeInfo
**info
)
442 Keychain keychain
= Keychain::optional(keychainRef
);
443 keychain
->getAttributeInfoForItemID(itemID
, info
);
450 SecKeychainFreeAttributeInfo(SecKeychainAttributeInfo
*info
)
454 KeychainImpl::freeAttributeInfo(info
);
461 SecKeychainAddCallback(SecKeychainCallback callbackFunction
, SecKeychainEventMask eventMask
, void* userContext
)
465 RequiredParam(callbackFunction
);
466 CCallbackMgr::AddCallback(callbackFunction
,eventMask
,userContext
);
473 SecKeychainRemoveCallback(SecKeychainCallback callbackFunction
)
477 RequiredParam(callbackFunction
);
478 CCallbackMgr::RemoveCallback(callbackFunction
);
484 SecKeychainAddInternetPassword(SecKeychainRef keychainRef
, UInt32 serverNameLength
, const char *serverName
, UInt32 securityDomainLength
, const char *securityDomain
, UInt32 accountNameLength
, const char *accountName
, UInt32 pathLength
, const char *path
, UInt16 port
, SecProtocolType protocol
, SecAuthenticationType authenticationType
, UInt32 passwordLength
, const void *passwordData
, SecKeychainItemRef
*itemRef
)
488 KCThrowParamErrIf_(passwordLength
!=0 && passwordData
==NULL
);
489 // @@@ Get real itemClass
490 Item
item(kSecInternetPasswordItemClass
, 'aapl', passwordLength
, passwordData
, false);
492 if (serverName
&& serverNameLength
)
494 CssmData
server(const_cast<void *>(reinterpret_cast<const void *>(serverName
)), serverNameLength
);
495 item
->setAttribute(Schema::attributeInfo(kSecServerItemAttr
), server
);
496 // use server name as default label
497 item
->setAttribute(Schema::attributeInfo(kSecLabelItemAttr
), server
);
500 if (accountName
&& accountNameLength
)
502 CssmData
account(const_cast<void *>(reinterpret_cast<const void *>(accountName
)), accountNameLength
);
503 item
->setAttribute(Schema::attributeInfo(kSecAccountItemAttr
), account
);
506 if (securityDomain
&& securityDomainLength
)
507 item
->setAttribute(Schema::attributeInfo(kSecSecurityDomainItemAttr
),
508 CssmData(const_cast<void *>(reinterpret_cast<const void *>(securityDomain
)), securityDomainLength
));
510 item
->setAttribute(Schema::attributeInfo(kSecPortItemAttr
), UInt32(port
));
511 item
->setAttribute(Schema::attributeInfo(kSecProtocolItemAttr
), protocol
);
512 item
->setAttribute(Schema::attributeInfo(kSecAuthenticationTypeItemAttr
), authenticationType
);
514 if (path
&& pathLength
)
515 item
->setAttribute(Schema::attributeInfo(kSecPathItemAttr
),
516 CssmData(const_cast<void *>(reinterpret_cast<const void *>(path
)), pathLength
));
518 Keychain keychain
= nil
;
521 keychain
= Keychain::optional(keychainRef
);
522 if ( !keychain
->exists() )
524 MacOSError::throwMe(errSecNoSuchKeychain
); // Might be deleted or not available at this time.
529 keychain
= globals().storageManager
.defaultKeychainUI(item
);
535 *itemRef
= item
->handle();
542 SecKeychainFindInternetPassword(CFTypeRef keychainOrArray
, UInt32 serverNameLength
, const char *serverName
, UInt32 securityDomainLength
, const char *securityDomain
, UInt32 accountNameLength
, const char *accountName
, UInt32 pathLength
, const char *path
, UInt16 port
, SecProtocolType protocol
, SecAuthenticationType authenticationType
, UInt32
*passwordLength
, void **passwordData
, SecKeychainItemRef
*itemRef
)
547 StorageManager::KeychainList keychains
;
548 globals().storageManager
.optionalSearchList(keychainOrArray
, keychains
);
549 KCCursor
cursor(keychains
, kSecInternetPasswordItemClass
, NULL
);
551 if (serverName
&& serverNameLength
)
553 cursor
->add(CSSM_DB_EQUAL
, Schema::attributeInfo(kSecServerItemAttr
),
554 CssmData(const_cast<char *>(serverName
), serverNameLength
));
557 if (securityDomain
&& securityDomainLength
)
559 cursor
->add(CSSM_DB_EQUAL
, Schema::attributeInfo(kSecSecurityDomainItemAttr
),
560 CssmData (const_cast<char*>(securityDomain
), securityDomainLength
));
563 if (accountName
&& accountNameLength
)
565 cursor
->add(CSSM_DB_EQUAL
, Schema::attributeInfo(kSecAccountItemAttr
),
566 CssmData (const_cast<char*>(accountName
), accountNameLength
));
571 cursor
->add(CSSM_DB_EQUAL
, Schema::attributeInfo(kSecPortItemAttr
),
577 cursor
->add(CSSM_DB_EQUAL
, Schema::attributeInfo(kSecProtocolItemAttr
),
581 if (authenticationType
)
583 cursor
->add(CSSM_DB_EQUAL
, Schema::attributeInfo(kSecAuthenticationTypeItemAttr
),
587 if (path
&& pathLength
)
589 cursor
->add(CSSM_DB_EQUAL
, Schema::attributeInfo(kSecPathItemAttr
), path
);
593 if (!cursor
->next(item
))
594 return errSecItemNotFound
;
596 // Get its data (only if necessary)
597 if (passwordData
|| passwordLength
)
599 CssmDataContainer outData
;
600 item
->getData(outData
);
601 *passwordLength
=outData
.length();
603 *passwordData
=outData
.data();
608 *itemRef
=item
->handle();
615 SecKeychainAddGenericPassword(SecKeychainRef keychainRef
, UInt32 serviceNameLength
, const char *serviceName
, UInt32 accountNameLength
, const char *accountName
, UInt32 passwordLength
, const void *passwordData
, SecKeychainItemRef
*itemRef
)
619 KCThrowParamErrIf_(passwordLength
!=0 && passwordData
==NULL
);
620 // @@@ Get real itemClass
622 Item
item(kSecGenericPasswordItemClass
, 'aapl', passwordLength
, passwordData
, false);
624 if (serviceName
&& serviceNameLength
)
626 CssmData
service(const_cast<void *>(reinterpret_cast<const void *>(serviceName
)), serviceNameLength
);
627 item
->setAttribute(Schema::attributeInfo(kSecServiceItemAttr
), service
);
628 // use service name as default label (UNLESS the service is iTools and we have an account name [3787371])
629 const char *iTools
= "iTools";
630 if (accountNameLength
&& serviceNameLength
==strlen(iTools
) && !memcmp(serviceName
, iTools
, serviceNameLength
))
632 CssmData
account(const_cast<void *>(reinterpret_cast<const void *>(accountName
)), accountNameLength
);
633 item
->setAttribute(Schema::attributeInfo(kSecLabelItemAttr
), account
);
637 item
->setAttribute(Schema::attributeInfo(kSecLabelItemAttr
), service
);
641 if (accountName
&& accountNameLength
)
643 CssmData
account(const_cast<void *>(reinterpret_cast<const void *>(accountName
)), accountNameLength
);
644 item
->setAttribute(Schema::attributeInfo(kSecAccountItemAttr
), account
);
647 Keychain keychain
= nil
;
650 keychain
= Keychain::optional(keychainRef
);
651 if ( !keychain
->exists() )
653 MacOSError::throwMe(errSecNoSuchKeychain
); // Might be deleted or not available at this time.
658 keychain
= globals().storageManager
.defaultKeychainUI(item
);
663 *itemRef
= item
->handle();
670 SecKeychainFindGenericPassword(CFTypeRef keychainOrArray
, UInt32 serviceNameLength
, const char *serviceName
, UInt32 accountNameLength
, const char *accountName
, UInt32
*passwordLength
, void **passwordData
, SecKeychainItemRef
*itemRef
)
675 StorageManager::KeychainList keychains
;
676 globals().storageManager
.optionalSearchList(keychainOrArray
, keychains
);
677 KCCursor
cursor(keychains
, kSecGenericPasswordItemClass
, NULL
);
679 if (serviceName
&& serviceNameLength
)
681 cursor
->add(CSSM_DB_EQUAL
, Schema::attributeInfo(kSecServiceItemAttr
),
682 CssmData(const_cast<char *>(serviceName
), serviceNameLength
));
685 if (accountName
&& accountNameLength
)
687 cursor
->add(CSSM_DB_EQUAL
, Schema::attributeInfo(kSecAccountItemAttr
),
688 CssmData(const_cast<char *>(accountName
), accountNameLength
));
692 if (!cursor
->next(item
))
693 return errSecItemNotFound
;
695 // Get its data (only if necessary)
696 if (passwordData
|| passwordLength
)
698 CssmDataContainer outData
;
699 item
->getData(outData
);
700 *passwordLength
=outData
.length();
702 *passwordData
=outData
.data();
707 *itemRef
=item
->handle();
714 SecKeychainSetUserInteractionAllowed(Boolean state
)
718 globals().setUserInteractionAllowed(state
);
725 SecKeychainGetUserInteractionAllowed(Boolean
*state
)
729 Required(state
)=globals().getUserInteractionAllowed();
736 SecKeychainGetDLDBHandle(SecKeychainRef keychainRef
, CSSM_DL_DB_HANDLE
*dldbHandle
)
740 RequiredParam(dldbHandle
);
742 Keychain keychain
= Keychain::optional(keychainRef
);
743 *dldbHandle
= keychain
->database()->handle();
750 SecKeychainGetCSPHandle(SecKeychainRef keychainRef
, CSSM_CSP_HANDLE
*cspHandle
)
754 RequiredParam(cspHandle
);
756 Keychain keychain
= Keychain::optional(keychainRef
);
757 *cspHandle
= keychain
->csp()->handle();
764 SecKeychainCopyAccess(SecKeychainRef keychainRef
, SecAccessRef
*accessRef
)
768 MacOSError::throwMe(unimpErr
);//%%%for now
775 SecKeychainSetAccess(SecKeychainRef keychainRef
, SecAccessRef accessRef
)
779 MacOSError::throwMe(unimpErr
);//%%%for now
785 #pragma mark ---- Private API ----
789 SecKeychainChangePassword(SecKeychainRef keychainRef
, UInt32 oldPasswordLength
, const void *oldPassword
, UInt32 newPasswordLength
, const void *newPassword
)
793 Keychain keychain
= Keychain::optional(keychainRef
);
794 keychain
->changePassphrase (oldPasswordLength
, oldPassword
, newPasswordLength
, newPassword
);
801 SecKeychainCopyLogin(SecKeychainRef
*keychainRef
)
805 RequiredParam(keychainRef
)=globals().storageManager
.loginKeychain()->handle();
812 SecKeychainLogin(UInt32 nameLength
, const void* name
, UInt32 passwordLength
, const void* password
)
818 globals().storageManager
.login(nameLength
, name
, passwordLength
, password
);
820 catch (CommonError
&e
)
822 if (e
.osStatus() == CSSMERR_DL_OPERATION_AUTH_DENIED
)
824 return errSecAuthFailed
;
841 globals().storageManager
.logout();
846 /* (non-exported C utility routine) 'Makes' a keychain based on a full path
848 static Keychain
make(const char *name
)
850 return globals().storageManager
.make(name
);
853 /* 'Makes' a keychain based on a full path for legacy "KC" CoreServices APIs.
854 Note this version doesn't take an accessRef or password.
855 The "KC" create API takes a keychainRef...
857 OSStatus
SecKeychainMakeFromFullPath(const char *fullPathName
, SecKeychainRef
*keychainRef
)
860 RequiredParam(fullPathName
);
861 RequiredParam(keychainRef
)=make(fullPathName
)->handle();
866 /* Determines if the keychainRef is a valid keychain.
868 OSStatus
SecKeychainIsValid(SecKeychainRef keychainRef
, Boolean
* isValid
)
872 if (KeychainImpl::optional(keychainRef
)->dlDbIdentifier().ssuid().guid() == gGuidAppleCSPDL
)
877 /* Removes a keychain from the keychain search list for legacy "KC" CoreServices APIs.
879 OSStatus
SecKeychainRemoveFromSearchList(SecKeychainRef keychainRef
)
882 StorageManager::KeychainList singleton
;
883 singleton
.push_back(KeychainImpl::required(keychainRef
));
884 globals().storageManager
.remove(singleton
);
888 /* Create a keychain based on a keychain Ref for legacy "KC" CoreServices APIs.
890 OSStatus
SecKeychainCreateNew(SecKeychainRef keychainRef
, UInt32 passwordLength
, const char* inPassword
)
893 RequiredParam(inPassword
);
894 KeychainImpl::required(keychainRef
)->create(passwordLength
, inPassword
);
898 /* Modify a keychain so that it can be synchronized.
900 OSStatus
SecKeychainRecodeKeychain(SecKeychainRef keychainRef
, CFArrayRef dbBlobArray
, CFDataRef extraData
)
904 // do error checking for required parameters
905 RequiredParam(dbBlobArray
);
906 RequiredParam(extraData
);
908 const CssmData
extraCssmData(const_cast<UInt8
*>(CFDataGetBytePtr(extraData
)),
909 CFDataGetLength(extraData
));
911 CFIndex dbBlobArrayCount
= CFArrayGetCount(dbBlobArray
);
912 size_t space
= sizeof(uint8
) + (dbBlobArrayCount
* sizeof(SecurityServer::DbHandle
));
913 void *dataPtr
= (void*)malloc(space
);
917 // Get a DbHandle(IPCDbHandle) from securityd for each blob in the array that we'll authenticate with.
919 uint8
* sizePtr
= (uint8
*)dataPtr
;
920 *sizePtr
= dbBlobArrayCount
;
921 SecurityServer::DbHandle
*currDbHandle
= (SecurityServer::DbHandle
*)(sizePtr
+1);
923 SecurityServer::ClientSession
ss(Allocator::standard(), Allocator::standard());
924 for (index
=0; index
< dbBlobArrayCount
; index
++)
926 CFDataRef cfBlobData
= (CFDataRef
)CFArrayGetValueAtIndex(dbBlobArray
, index
);
927 const CssmData
thisKCData(const_cast<UInt8
*>(CFDataGetBytePtr(cfBlobData
)), CFDataGetLength(cfBlobData
));
929 // Since it's to a DbHandle that's not on our disk (it came from user's iDisk),
930 // it's OK to use the mIdentifier and access credentials of the keychain we're recoding.
932 Keychain kc
= KeychainImpl::required(keychainRef
);
933 *currDbHandle
= ss
.decodeDb(kc
->dlDbIdentifier(), kc
->defaultCredentials(), thisKCData
); /* returns a DbHandle (IPCDbHandle) */
938 Keychain keychain
= Keychain::optional(keychainRef
);
939 const CssmData
data(const_cast<UInt8
*>((uint8
*)dataPtr
), space
);
940 Boolean recodeFailed
= false;
946 keychain
->recode(data
, extraCssmData
);
950 errCode
= e
.osStatus();
955 errCode
= ue
.unixError();
958 currDbHandle
= (SecurityServer::DbHandle
*)(sizePtr
+1);
959 for (index
=0; index
< dbBlobArrayCount
; index
++)
961 ss
.releaseDb(*currDbHandle
);
975 OSStatus
SecKeychainCopySignature(SecKeychainRef keychainRef
, CFDataRef
*keychainSignature
)
979 // do error checking for required parameters
980 RequiredParam(keychainSignature
);
982 // make a keychain object "wrapper" for this keychain ref
983 Keychain keychain
= Keychain::optional(keychainRef
);
984 CssmAutoData
data(keychain
->database()->allocator());
985 keychain
->copyBlob(data
.get());
987 // get the cssmDBBlob
988 const SecurityServer::DbBlob
*cssmDBBlob
=
989 data
.get().interpretedAs
<const SecurityServer::DbBlob
>();
991 // convert from CDSA standards to CF standards
992 *keychainSignature
= CFDataCreate(kCFAllocatorDefault
,
993 cssmDBBlob
->randomSignature
.bytes
,
994 sizeof(SecurityServer::DbBlob::Signature
));
999 OSStatus
SecKeychainCopyBlob(SecKeychainRef keychainRef
, CFDataRef
*dbBlob
)
1003 // do error checking for required parameters
1004 RequiredParam(dbBlob
);
1006 // make a keychain object "wrapper" for this keychain ref
1007 Keychain keychain
= Keychain::optional(keychainRef
);
1008 CssmAutoData
data(keychain
->database()->allocator());
1009 keychain
->copyBlob(data
.get());
1011 // convert from CDSA standards to CF standards
1012 *dbBlob
= CFDataCreate(kCFAllocatorDefault
, data
, data
.length());
1017 // make a new keychain with pre-existing secrets
1018 OSStatus
SecKeychainCreateWithBlob(const char* fullPathName
, CFDataRef dbBlob
, SecKeychainRef
*kcRef
)
1022 KCThrowParamErrIf_(!fullPathName
);
1023 KCThrowParamErrIf_(!dbBlob
);
1025 Keychain keychain
= globals().storageManager
.make(fullPathName
);
1027 CssmData
blob(const_cast<unsigned char *>(CFDataGetBytePtr(dbBlob
)), CFDataGetLength(dbBlob
));
1029 // @@@ the call to StorageManager::make above leaves keychain the the cache.
1030 // If the create below fails we should probably remove it.
1031 keychain
->createWithBlob(blob
);
1033 RequiredParam(kcRef
)=keychain
->handle();
1040 // add a non-file based DB to the keychain list
1041 OSStatus
SecKeychainAddDBToKeychainList (SecPreferencesDomain domain
, const char* dbName
,
1042 const CSSM_GUID
*guid
, uint32 subServiceType
)
1046 RequiredParam(dbName
);
1047 StorageManager
&smr
= globals().storageManager
;
1048 smr
.addToDomainList(domain
, dbName
, *guid
, subServiceType
);
1053 // determine if a non-file based DB is in the keychain list
1054 OSStatus
SecKeychainDBIsInKeychainList (SecPreferencesDomain domain
, const char* dbName
,
1055 const CSSM_GUID
*guid
, uint32 subServiceType
)
1058 RequiredParam(dbName
);
1059 StorageManager
&smr
= globals().storageManager
;
1060 smr
.isInDomainList(domain
, dbName
, *guid
, subServiceType
);
1064 // remove a non-file based DB from the keychain list
1065 OSStatus
SecKeychainRemoveDBFromKeychainList (SecPreferencesDomain domain
, const char* dbName
,
1066 const CSSM_GUID
*guid
, uint32 subServiceType
)
1069 RequiredParam(dbName
);
1070 StorageManager
&smr
= globals().storageManager
;
1071 smr
.removeFromDomainList(domain
, dbName
, *guid
, subServiceType
);
1076 // set server mode -- must be called before any other Sec* etc. call
1077 void SecKeychainSetServerMode()
1084 OSStatus
SecKeychainSetBatchMode (SecKeychainRef kcRef
, Boolean mode
, Boolean rollback
)
1087 RequiredParam(kcRef
);
1088 Keychain keychain
= Keychain::optional(kcRef
);
1089 keychain
->setBatchMode(mode
, rollback
);
1095 OSStatus
SecKeychainCleanupHandles()
1098 END_SECAPI
// which causes the handle cache cleanup routine to run