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((UInt32
)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 SecurityServer::ClientSession().resetKeyStorePassphrase(password
? CssmData(const_cast<void *>(password
), passwordLength
) : CssmData());
247 // Post a "list changed" event after a reset, so apps can refresh their list.
248 // Make sure we are not holding mLock when we post this event.
249 KCEventNotifier::PostKeychainEvent(kSecKeychainListChangedEvent
);
255 SecKeychainCopyDefault(SecKeychainRef
*keychainRef
)
259 RequiredParam(keychainRef
)=globals().storageManager
.defaultKeychain()->handle();
266 SecKeychainSetDefault(SecKeychainRef keychainRef
)
270 globals().storageManager
.defaultKeychain(Keychain::optional(keychainRef
));
275 OSStatus
SecKeychainCopySearchList(CFArrayRef
*searchList
)
279 RequiredParam(searchList
);
280 StorageManager
&smr
= globals().storageManager
;
281 StorageManager::KeychainList keychainList
;
282 smr
.getSearchList(keychainList
);
283 *searchList
= smr
.convertFromKeychainList(keychainList
);
288 OSStatus
SecKeychainSetSearchList(CFArrayRef searchList
)
292 RequiredParam(searchList
);
293 StorageManager
&smr
= globals().storageManager
;
294 StorageManager::KeychainList keychainList
;
295 smr
.convertToKeychainList(searchList
, keychainList
);
296 smr
.setSearchList(keychainList
);
301 OSStatus
SecKeychainCopyDomainDefault(SecPreferencesDomain domain
, SecKeychainRef
*keychainRef
)
305 RequiredParam(keychainRef
)=globals().storageManager
.defaultKeychain(domain
)->handle();
310 OSStatus
SecKeychainSetDomainDefault(SecPreferencesDomain domain
, SecKeychainRef keychainRef
)
314 globals().storageManager
.defaultKeychain(domain
, Keychain::optional(keychainRef
));
319 OSStatus
SecKeychainCopyDomainSearchList(SecPreferencesDomain domain
, CFArrayRef
*searchList
)
323 RequiredParam(searchList
);
324 StorageManager
&smr
= globals().storageManager
;
325 StorageManager::KeychainList keychainList
;
326 smr
.getSearchList(domain
, keychainList
);
327 *searchList
= smr
.convertFromKeychainList(keychainList
);
332 OSStatus
SecKeychainSetDomainSearchList(SecPreferencesDomain domain
, CFArrayRef searchList
)
336 RequiredParam(searchList
);
337 StorageManager
&smr
= globals().storageManager
;
338 StorageManager::KeychainList keychainList
;
339 smr
.convertToKeychainList(searchList
, keychainList
);
340 smr
.setSearchList(domain
, keychainList
);
345 OSStatus
SecKeychainSetPreferenceDomain(SecPreferencesDomain domain
)
349 globals().storageManager
.domain(domain
);
354 OSStatus
SecKeychainGetPreferenceDomain(SecPreferencesDomain
*domain
)
358 *domain
= globals().storageManager
.domain();
365 SecKeychainGetStatus(SecKeychainRef keychainRef
, SecKeychainStatus
*keychainStatus
)
369 RequiredParam(keychainStatus
) = (SecKeychainStatus
)Keychain::optional(keychainRef
)->status();
376 SecKeychainGetPath(SecKeychainRef keychainRef
, UInt32
*ioPathLength
, char *pathName
)
380 RequiredParam(pathName
);
381 RequiredParam(ioPathLength
);
383 const char *name
= Keychain::optional(keychainRef
)->name();
384 UInt32 nameLen
= (UInt32
)strlen(name
);
385 UInt32 callersLen
= *ioPathLength
;
386 *ioPathLength
= nameLen
;
387 if (nameLen
+1 > callersLen
) // if the client's buffer is too small (including null-termination), throw
388 return errSecBufferTooSmall
;
389 strncpy(pathName
, name
, nameLen
);
390 pathName
[nameLen
] = 0;
391 *ioPathLength
= nameLen
; // set the length.
399 SecKeychainListGetCount(void)
403 return globals().storageManager
.size();
411 SecKeychainListCopyKeychainAtIndex(UInt16 index
, SecKeychainRef
*keychainRef
)
415 KeychainCore::StorageManager
&smgr
=KeychainCore::globals().storageManager
;
416 RequiredParam(keychainRef
)=smgr
[index
]->handle();
424 SecKeychainListRemoveKeychain(SecKeychainRef
*keychainRef
)
428 Required(keychainRef
);
429 Keychain keychain
= Keychain::optional(*keychainRef
);
430 StorageManager::KeychainList keychainList
;
431 keychainList
.push_back(keychain
);
432 globals().storageManager
.remove(keychainList
);
440 SecKeychainAttributeInfoForItemID(SecKeychainRef keychainRef
, UInt32 itemID
, SecKeychainAttributeInfo
**info
)
444 Keychain keychain
= Keychain::optional(keychainRef
);
445 keychain
->getAttributeInfoForItemID(itemID
, info
);
452 SecKeychainFreeAttributeInfo(SecKeychainAttributeInfo
*info
)
456 KeychainImpl::freeAttributeInfo(info
);
463 SecKeychainAddCallback(SecKeychainCallback callbackFunction
, SecKeychainEventMask eventMask
, void* userContext
)
467 RequiredParam(callbackFunction
);
468 CCallbackMgr::AddCallback(callbackFunction
,eventMask
,userContext
);
475 SecKeychainRemoveCallback(SecKeychainCallback callbackFunction
)
479 RequiredParam(callbackFunction
);
480 CCallbackMgr::RemoveCallback(callbackFunction
);
486 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
)
490 KCThrowParamErrIf_(passwordLength
!=0 && passwordData
==NULL
);
491 // @@@ Get real itemClass
492 Item
item(kSecInternetPasswordItemClass
, 'aapl', passwordLength
, passwordData
, false);
494 if (serverName
&& serverNameLength
)
496 CssmData
server(const_cast<void *>(reinterpret_cast<const void *>(serverName
)), serverNameLength
);
497 item
->setAttribute(Schema::attributeInfo(kSecServerItemAttr
), server
);
498 // use server name as default label
499 item
->setAttribute(Schema::attributeInfo(kSecLabelItemAttr
), server
);
502 if (accountName
&& accountNameLength
)
504 CssmData
account(const_cast<void *>(reinterpret_cast<const void *>(accountName
)), accountNameLength
);
505 item
->setAttribute(Schema::attributeInfo(kSecAccountItemAttr
), account
);
508 if (securityDomain
&& securityDomainLength
)
509 item
->setAttribute(Schema::attributeInfo(kSecSecurityDomainItemAttr
),
510 CssmData(const_cast<void *>(reinterpret_cast<const void *>(securityDomain
)), securityDomainLength
));
512 item
->setAttribute(Schema::attributeInfo(kSecPortItemAttr
), UInt32(port
));
513 item
->setAttribute(Schema::attributeInfo(kSecProtocolItemAttr
), protocol
);
514 item
->setAttribute(Schema::attributeInfo(kSecAuthenticationTypeItemAttr
), authenticationType
);
516 if (path
&& pathLength
)
517 item
->setAttribute(Schema::attributeInfo(kSecPathItemAttr
),
518 CssmData(const_cast<void *>(reinterpret_cast<const void *>(path
)), pathLength
));
520 Keychain keychain
= nil
;
523 keychain
= Keychain::optional(keychainRef
);
524 if ( !keychain
->exists() )
526 MacOSError::throwMe(errSecNoSuchKeychain
); // Might be deleted or not available at this time.
531 keychain
= globals().storageManager
.defaultKeychainUI(item
);
537 *itemRef
= item
->handle();
544 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
)
549 StorageManager::KeychainList keychains
;
550 globals().storageManager
.optionalSearchList(keychainOrArray
, keychains
);
551 KCCursor
cursor(keychains
, kSecInternetPasswordItemClass
, NULL
);
553 if (serverName
&& serverNameLength
)
555 cursor
->add(CSSM_DB_EQUAL
, Schema::attributeInfo(kSecServerItemAttr
),
556 CssmData(const_cast<char *>(serverName
), serverNameLength
));
559 if (securityDomain
&& securityDomainLength
)
561 cursor
->add(CSSM_DB_EQUAL
, Schema::attributeInfo(kSecSecurityDomainItemAttr
),
562 CssmData (const_cast<char*>(securityDomain
), securityDomainLength
));
565 if (accountName
&& accountNameLength
)
567 cursor
->add(CSSM_DB_EQUAL
, Schema::attributeInfo(kSecAccountItemAttr
),
568 CssmData (const_cast<char*>(accountName
), accountNameLength
));
573 cursor
->add(CSSM_DB_EQUAL
, Schema::attributeInfo(kSecPortItemAttr
),
579 cursor
->add(CSSM_DB_EQUAL
, Schema::attributeInfo(kSecProtocolItemAttr
),
583 if (authenticationType
)
585 cursor
->add(CSSM_DB_EQUAL
, Schema::attributeInfo(kSecAuthenticationTypeItemAttr
),
589 if (path
&& pathLength
)
591 cursor
->add(CSSM_DB_EQUAL
, Schema::attributeInfo(kSecPathItemAttr
), path
);
595 if (!cursor
->next(item
))
596 return errSecItemNotFound
;
598 // Get its data (only if necessary)
599 if (passwordData
|| passwordLength
)
601 CssmDataContainer outData
;
602 item
->getData(outData
);
603 *passwordLength
=(UInt32
)outData
.length();
605 *passwordData
=outData
.data();
610 *itemRef
=item
->handle();
617 SecKeychainAddGenericPassword(SecKeychainRef keychainRef
, UInt32 serviceNameLength
, const char *serviceName
, UInt32 accountNameLength
, const char *accountName
, UInt32 passwordLength
, const void *passwordData
, SecKeychainItemRef
*itemRef
)
621 KCThrowParamErrIf_(passwordLength
!=0 && passwordData
==NULL
);
622 // @@@ Get real itemClass
624 Item
item(kSecGenericPasswordItemClass
, 'aapl', passwordLength
, passwordData
, false);
626 if (serviceName
&& serviceNameLength
)
628 CssmData
service(const_cast<void *>(reinterpret_cast<const void *>(serviceName
)), serviceNameLength
);
629 item
->setAttribute(Schema::attributeInfo(kSecServiceItemAttr
), service
);
630 // use service name as default label (UNLESS the service is iTools and we have an account name [3787371])
631 const char *iTools
= "iTools";
632 if (accountNameLength
&& serviceNameLength
==strlen(iTools
) && !memcmp(serviceName
, iTools
, serviceNameLength
))
634 CssmData
account(const_cast<void *>(reinterpret_cast<const void *>(accountName
)), accountNameLength
);
635 item
->setAttribute(Schema::attributeInfo(kSecLabelItemAttr
), account
);
639 item
->setAttribute(Schema::attributeInfo(kSecLabelItemAttr
), service
);
643 if (accountName
&& accountNameLength
)
645 CssmData
account(const_cast<void *>(reinterpret_cast<const void *>(accountName
)), accountNameLength
);
646 item
->setAttribute(Schema::attributeInfo(kSecAccountItemAttr
), account
);
649 Keychain keychain
= nil
;
652 keychain
= Keychain::optional(keychainRef
);
653 if ( !keychain
->exists() )
655 MacOSError::throwMe(errSecNoSuchKeychain
); // Might be deleted or not available at this time.
660 keychain
= globals().storageManager
.defaultKeychainUI(item
);
665 *itemRef
= item
->handle();
672 SecKeychainFindGenericPassword(CFTypeRef keychainOrArray
, UInt32 serviceNameLength
, const char *serviceName
, UInt32 accountNameLength
, const char *accountName
, UInt32
*passwordLength
, void **passwordData
, SecKeychainItemRef
*itemRef
)
677 StorageManager::KeychainList keychains
;
678 globals().storageManager
.optionalSearchList(keychainOrArray
, keychains
);
679 KCCursor
cursor(keychains
, kSecGenericPasswordItemClass
, NULL
);
681 if (serviceName
&& serviceNameLength
)
683 cursor
->add(CSSM_DB_EQUAL
, Schema::attributeInfo(kSecServiceItemAttr
),
684 CssmData(const_cast<char *>(serviceName
), serviceNameLength
));
687 if (accountName
&& accountNameLength
)
689 cursor
->add(CSSM_DB_EQUAL
, Schema::attributeInfo(kSecAccountItemAttr
),
690 CssmData(const_cast<char *>(accountName
), accountNameLength
));
694 if (!cursor
->next(item
))
695 return errSecItemNotFound
;
697 // Get its data (only if necessary)
698 if (passwordData
|| passwordLength
)
700 CssmDataContainer outData
;
701 item
->getData(outData
);
702 *passwordLength
=(UInt32
)outData
.length();
704 *passwordData
=outData
.data();
709 *itemRef
=item
->handle();
716 SecKeychainSetUserInteractionAllowed(Boolean state
)
720 globals().setUserInteractionAllowed(state
);
727 SecKeychainGetUserInteractionAllowed(Boolean
*state
)
731 Required(state
)=globals().getUserInteractionAllowed();
738 SecKeychainGetDLDBHandle(SecKeychainRef keychainRef
, CSSM_DL_DB_HANDLE
*dldbHandle
)
742 RequiredParam(dldbHandle
);
744 Keychain keychain
= Keychain::optional(keychainRef
);
745 *dldbHandle
= keychain
->database()->handle();
752 SecKeychainGetCSPHandle(SecKeychainRef keychainRef
, CSSM_CSP_HANDLE
*cspHandle
)
756 RequiredParam(cspHandle
);
758 Keychain keychain
= Keychain::optional(keychainRef
);
759 *cspHandle
= keychain
->csp()->handle();
766 SecKeychainCopyAccess(SecKeychainRef keychainRef
, SecAccessRef
*accessRef
)
770 MacOSError::throwMe(errSecUnimplemented
);//%%%for now
777 SecKeychainSetAccess(SecKeychainRef keychainRef
, SecAccessRef accessRef
)
781 MacOSError::throwMe(errSecUnimplemented
);//%%%for now
787 #pragma mark ---- Private API ----
791 SecKeychainChangePassword(SecKeychainRef keychainRef
, UInt32 oldPasswordLength
, const void *oldPassword
, UInt32 newPasswordLength
, const void *newPassword
)
795 Keychain keychain
= Keychain::optional(keychainRef
);
796 keychain
->changePassphrase (oldPasswordLength
, oldPassword
, newPasswordLength
, newPassword
);
803 SecKeychainCopyLogin(SecKeychainRef
*keychainRef
)
807 RequiredParam(keychainRef
)=globals().storageManager
.loginKeychain()->handle();
814 SecKeychainLogin(UInt32 nameLength
, const void* name
, UInt32 passwordLength
, const void* password
)
821 globals().storageManager
.login(nameLength
, name
, passwordLength
, password
);
823 globals().storageManager
.stashLogin();
826 catch (CommonError
&e
)
828 if (e
.osStatus() == CSSMERR_DL_OPERATION_AUTH_DENIED
)
830 return errSecAuthFailed
;
841 OSStatus
SecKeychainStash()
847 globals().storageManager
.stashKeychain();
849 catch (CommonError
&e
)
851 if (e
.osStatus() == CSSMERR_DL_OPERATION_AUTH_DENIED
)
853 return errSecAuthFailed
;
869 globals().storageManager
.logout();
874 /* (non-exported C utility routine) 'Makes' a keychain based on a full path
876 static Keychain
make(const char *name
)
878 return globals().storageManager
.make(name
);
881 /* 'Makes' a keychain based on a full path for legacy "KC" CoreServices APIs.
882 Note this version doesn't take an accessRef or password.
883 The "KC" create API takes a keychainRef...
885 OSStatus
SecKeychainMakeFromFullPath(const char *fullPathName
, SecKeychainRef
*keychainRef
)
888 RequiredParam(fullPathName
);
889 RequiredParam(keychainRef
)=make(fullPathName
)->handle();
894 /* Determines if the keychainRef is a valid keychain.
896 OSStatus
SecKeychainIsValid(SecKeychainRef keychainRef
, Boolean
* isValid
)
900 if (KeychainImpl::optional(keychainRef
)->dlDbIdentifier().ssuid().guid() == gGuidAppleCSPDL
)
905 /* Removes a keychain from the keychain search list for legacy "KC" CoreServices APIs.
907 OSStatus
SecKeychainRemoveFromSearchList(SecKeychainRef keychainRef
)
910 StorageManager::KeychainList singleton
;
911 singleton
.push_back(KeychainImpl::required(keychainRef
));
912 globals().storageManager
.remove(singleton
);
916 /* Create a keychain based on a keychain Ref for legacy "KC" CoreServices APIs.
918 OSStatus
SecKeychainCreateNew(SecKeychainRef keychainRef
, UInt32 passwordLength
, const char* inPassword
)
921 RequiredParam(inPassword
);
922 KeychainImpl::required(keychainRef
)->create(passwordLength
, inPassword
);
926 /* Modify a keychain so that it can be synchronized.
928 OSStatus
SecKeychainRecodeKeychain(SecKeychainRef keychainRef
, CFArrayRef dbBlobArray
, CFDataRef extraData
)
932 // do error checking for required parameters
933 RequiredParam(dbBlobArray
);
934 RequiredParam(extraData
);
936 const CssmData
extraCssmData(const_cast<UInt8
*>(CFDataGetBytePtr(extraData
)),
937 CFDataGetLength(extraData
));
939 CFIndex dbBlobArrayCount
= CFArrayGetCount(dbBlobArray
);
940 size_t space
= sizeof(uint8
) + (dbBlobArrayCount
* sizeof(SecurityServer::DbHandle
));
941 void *dataPtr
= (void*)malloc(space
);
943 return errSecAllocate
;
945 // Get a DbHandle(IPCDbHandle) from securityd for each blob in the array that we'll authenticate with.
947 uint8
* sizePtr
= (uint8
*)dataPtr
;
948 *sizePtr
= dbBlobArrayCount
;
949 SecurityServer::DbHandle
*currDbHandle
= (SecurityServer::DbHandle
*)(sizePtr
+1);
951 SecurityServer::ClientSession
ss(Allocator::standard(), Allocator::standard());
952 for (index
=0; index
< dbBlobArrayCount
; index
++)
954 CFDataRef cfBlobData
= (CFDataRef
)CFArrayGetValueAtIndex(dbBlobArray
, index
);
955 const CssmData
thisKCData(const_cast<UInt8
*>(CFDataGetBytePtr(cfBlobData
)), CFDataGetLength(cfBlobData
));
957 // Since it's to a DbHandle that's not on our disk (it came from user's iDisk),
958 // it's OK to use the mIdentifier and access credentials of the keychain we're recoding.
960 Keychain kc
= KeychainImpl::required(keychainRef
);
961 *currDbHandle
= ss
.decodeDb(kc
->dlDbIdentifier(), kc
->defaultCredentials(), thisKCData
); /* returns a DbHandle (IPCDbHandle) */
966 Keychain keychain
= Keychain::optional(keychainRef
);
967 const CssmData
data(const_cast<UInt8
*>((uint8
*)dataPtr
), space
);
968 Boolean recodeFailed
= false;
970 int errCode
=errSecSuccess
;
974 keychain
->recode(data
, extraCssmData
);
978 errCode
= e
.osStatus();
983 errCode
= ue
.unixError();
986 currDbHandle
= (SecurityServer::DbHandle
*)(sizePtr
+1);
987 for (index
=0; index
< dbBlobArrayCount
; index
++)
989 ss
.releaseDb(*currDbHandle
);
1003 OSStatus
SecKeychainCopySignature(SecKeychainRef keychainRef
, CFDataRef
*keychainSignature
)
1007 // do error checking for required parameters
1008 RequiredParam(keychainSignature
);
1010 // make a keychain object "wrapper" for this keychain ref
1011 Keychain keychain
= Keychain::optional(keychainRef
);
1012 CssmAutoData
data(keychain
->database()->allocator());
1013 keychain
->copyBlob(data
.get());
1015 // get the cssmDBBlob
1016 const SecurityServer::DbBlob
*cssmDBBlob
=
1017 data
.get().interpretedAs
<const SecurityServer::DbBlob
>();
1019 // convert from CDSA standards to CF standards
1020 *keychainSignature
= CFDataCreate(kCFAllocatorDefault
,
1021 cssmDBBlob
->randomSignature
.bytes
,
1022 sizeof(SecurityServer::DbBlob::Signature
));
1027 OSStatus
SecKeychainCopyBlob(SecKeychainRef keychainRef
, CFDataRef
*dbBlob
)
1031 // do error checking for required parameters
1032 RequiredParam(dbBlob
);
1034 // make a keychain object "wrapper" for this keychain ref
1035 Keychain keychain
= Keychain::optional(keychainRef
);
1036 CssmAutoData
data(keychain
->database()->allocator());
1037 keychain
->copyBlob(data
.get());
1039 // convert from CDSA standards to CF standards
1040 *dbBlob
= CFDataCreate(kCFAllocatorDefault
, data
, data
.length());
1045 // make a new keychain with pre-existing secrets
1046 OSStatus
SecKeychainCreateWithBlob(const char* fullPathName
, CFDataRef dbBlob
, SecKeychainRef
*kcRef
)
1050 KCThrowParamErrIf_(!fullPathName
);
1051 KCThrowParamErrIf_(!dbBlob
);
1053 Keychain keychain
= globals().storageManager
.make(fullPathName
);
1055 CssmData
blob(const_cast<unsigned char *>(CFDataGetBytePtr(dbBlob
)), CFDataGetLength(dbBlob
));
1057 // @@@ the call to StorageManager::make above leaves keychain the the cache.
1058 // If the create below fails we should probably remove it.
1059 keychain
->createWithBlob(blob
);
1061 RequiredParam(kcRef
)=keychain
->handle();
1068 // add a non-file based DB to the keychain list
1069 OSStatus
SecKeychainAddDBToKeychainList (SecPreferencesDomain domain
, const char* dbName
,
1070 const CSSM_GUID
*guid
, uint32 subServiceType
)
1074 RequiredParam(dbName
);
1075 StorageManager
&smr
= globals().storageManager
;
1076 smr
.addToDomainList(domain
, dbName
, *guid
, subServiceType
);
1081 // determine if a non-file based DB is in the keychain list
1082 OSStatus
SecKeychainDBIsInKeychainList (SecPreferencesDomain domain
, const char* dbName
,
1083 const CSSM_GUID
*guid
, uint32 subServiceType
)
1086 RequiredParam(dbName
);
1087 StorageManager
&smr
= globals().storageManager
;
1088 smr
.isInDomainList(domain
, dbName
, *guid
, subServiceType
);
1092 // remove a non-file based DB from the keychain list
1093 OSStatus
SecKeychainRemoveDBFromKeychainList (SecPreferencesDomain domain
, const char* dbName
,
1094 const CSSM_GUID
*guid
, uint32 subServiceType
)
1097 RequiredParam(dbName
);
1098 StorageManager
&smr
= globals().storageManager
;
1099 smr
.removeFromDomainList(domain
, dbName
, *guid
, subServiceType
);
1104 // set server mode -- must be called before any other Sec* etc. call
1105 void SecKeychainSetServerMode()
1112 OSStatus
SecKeychainSetBatchMode (SecKeychainRef kcRef
, Boolean mode
, Boolean rollback
)
1115 RequiredParam(kcRef
);
1116 Keychain keychain
= Keychain::optional(kcRef
);
1117 keychain
->setBatchMode(mode
, rollback
);
1123 OSStatus
SecKeychainCleanupHandles()
1126 END_SECAPI
// which causes the handle cache cleanup routine to run
1129 OSStatus
SecKeychainVerifyKeyStorePassphrase(uint32_t retries
)
1132 SecurityServer::ClientSession().verifyKeyStorePassphrase(retries
);
1136 OSStatus
SecKeychainChangeKeyStorePassphrase()
1139 SecurityServer::ClientSession().changeKeyStorePassphrase();