X-Git-Url: https://git.saurik.com/apple/security.git/blobdiff_plain/bac41a7b9a0a9254fa30f8bb6e6038ab71a483e2..67c7378dcb8de24c86b7fedff90b4b496f2e474c:/Keychain/SecKeychainAPI.cpp?ds=inline diff --git a/Keychain/SecKeychainAPI.cpp b/Keychain/SecKeychainAPI.cpp index 1c9c123c..50378ea2 100644 --- a/Keychain/SecKeychainAPI.cpp +++ b/Keychain/SecKeychainAPI.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000-2001 Apple Computer, Inc. All Rights Reserved. + * Copyright (c) 2000-2002 Apple Computer, Inc. All Rights Reserved. * * The contents of this file constitute Original Code as defined in and are * subject to the Apple Public Source License Version 1.2 (the 'License'). @@ -15,722 +15,59 @@ * specific language governing rights and limitations under the License. */ - /* - * SecKeychainAPI.cpp + * SecKeychainAPI.h * SecurityCore * - * Copyright: (c) 2000 by Apple Computer, Inc., all rights reserved + * Copyright: (c) 2000-2002 by Apple Computer, Inc., all rights reserved * */ +/*! + @header SecKeychainAPI The Security Keychain API contains all the APIs need to create a client and Keychain management application. It also contains a certificate, policy, identity and trust management API. + + NOTE: Any function with Create or Copy in the name returns an object that must be released. +*/ #include -#include "SecKeychainAPIPriv.h" -#include "Keychains.h" -#include "Globals.h" -#include "KCUtilities.h" -#include "KCEventNotifier.h" -#include "KCCursor.h" -#include "CCallbackMgr.h" -#include "KCExceptions.h" -#include "Schema.h" -#include - -using namespace Security; - -using namespace KeychainCore; - -// -// API boilerplate macros. These provide a frame for C++ code that is impermeable to exceptions. -// Usage: -// BEGIN_API -// ... your C++ code here ... -// END_API // returns CSSM_RETURN on exception -// END_API0 // returns nothing (void) on exception -// END_API1(bad) // return (bad) on exception -// -#define BEGIN_SECAPI \ - try { \ - StLock _(globals().apiLock); -#define END_SECAPI \ - } \ - catch (const MacOSError &err) { return err.osStatus(); } \ - catch (const CssmCommonError &err) { return GetKeychainErrFromCSSMErr(err.cssmError())/*err.cssmError(CSSM_CSSM_BASE_ERROR)*/; } \ - catch (::std::bad_alloc) { return memFullErr; } \ - catch (...) { return internalComponentErr; } \ - return noErr; -#define END_SECAPI0 } catch (...) { return; } -#define END_SECAPI1(bad) } catch (...) { return bad; } - - -OSStatus SecKeychainGetVersion(UInt32 *returnVers) -{ - if (!returnVers) return noErr; - - *returnVers=0x02028000; - return noErr; -} - - -OSStatus SecKeychainOpen(const char *pathName, SecKeychainRef *keychainRef) -{ - BEGIN_SECAPI - RequiredParam(keychainRef)=KeychainRef::handle(globals().storageManager.make(pathName)); - END_SECAPI -} - -OSStatus SecKeychainCreateNew(const char *pathName, SecKeychainRef *keychainRef, UInt32 passwordLength, const void *password, Boolean promptUser) -{ - BEGIN_SECAPI - - KCThrowParamErrIf_(!pathName); - - Keychain keychain = globals().storageManager.make(pathName); - - if(promptUser) - { - keychain->create(); - } - else - { - KCThrowParamErrIf_(!password); - - keychain->create(passwordLength, password); - } - RequiredParam(keychainRef)=KeychainRef::handle(keychain); - - END_SECAPI -} - -OSStatus SecKeychainDelete(SecKeychainRef keychainRef) -{ - BEGIN_SECAPI - - Keychain keychain = Keychain::optional(keychainRef); - keychain->database()->deleteDb(); - - list SecKeychainRefToRemove; - SecKeychainRefToRemove.push_back(keychainRef); - KeychainCore::StorageManager &smgr=KeychainCore::globals().storageManager; - smgr.remove(SecKeychainRefToRemove); - return noErr; - - END_SECAPI - - -} -OSStatus SecKeychainSetSettings(SecKeychainRef keychainRef, const SecKeychainSettings *newSettings) -{ - BEGIN_SECAPI - Keychain keychain = Keychain::optional(keychainRef); - if(newSettings->version==SEC_KEYCHAIN_SETTINGS_VERS1) - { - UInt32 lockInterval=newSettings->lockInterval; - bool lockOnSleep=newSettings->lockOnSleep; - - keychain->setSettings(lockInterval, lockOnSleep); - } - END_SECAPI -} - - -OSStatus SecKeychainCopySettings(SecKeychainRef keychainRef, SecKeychainSettings *outSettings) -{ - BEGIN_SECAPI - Keychain keychain = Keychain::optional(keychainRef); - if(outSettings->version==SEC_KEYCHAIN_SETTINGS_VERS1) - { - UInt32 lockInterval; - bool lockOnSleep; - - keychain->getSettings(lockInterval, lockOnSleep); - outSettings->lockInterval=lockInterval; - outSettings->lockOnSleep=lockOnSleep; - } - END_SECAPI -} - - -OSStatus SecKeychainUnlock(SecKeychainRef keychainRef, UInt32 passwordLength, void *password, Boolean usePassword) -{ - BEGIN_SECAPI - Keychain keychain = Keychain::optional(keychainRef); - - if(usePassword) - keychain->unlock(CssmData(password,passwordLength)); - else - keychain->unlock(); - END_SECAPI -} - - -OSStatus SecKeychainLock(SecKeychainRef keychainRef) -{ - BEGIN_SECAPI - Keychain keychain = Keychain::optional(keychainRef); - keychain->lock(); - END_SECAPI -} - - -OSStatus SecKeychainLockAll() -{ - BEGIN_SECAPI - globals().storageManager.lockAll(); - END_SECAPI -} - +#include +#include OSStatus SecKeychainRelease(SecKeychainRef keychainRef) { - BEGIN_SECAPI - KeychainRef::release(keychainRef); - END_SECAPI -} - - -OSStatus SecKeychainCopyDefault(SecKeychainRef *keychainRef) -{ - BEGIN_SECAPI - RequiredParam(keychainRef)=KeychainRef::handle(globals().defaultKeychain.keychain()); - END_SECAPI -} - - -OSStatus SecKeychainSetDefault(SecKeychainRef keychainRef) -{ - BEGIN_SECAPI - globals().defaultKeychain.keychain(Keychain::optional(keychainRef)); - END_SECAPI -} - - -OSStatus SecKeychainGetStatus(SecKeychainRef keychainRef, SecKeychainStatus *keychainStatus) -{ - BEGIN_SECAPI - RequiredParam(keychainStatus) = (SecKeychainStatus)Keychain::optional(keychainRef)->status(); - END_SECAPI -} - - -OSStatus SecKeychainGetPath(SecKeychainRef keychainRef, UInt32 * ioPathLength, char *pathName) -{ - BEGIN_SECAPI - RequiredParam(pathName); - const char *name = Keychain::optional(keychainRef)->name(); - UInt32 nameLen = strlen(name); - memcpy(pathName, name, *ioPathLength); - if(nameLen < *ioPathLength) // if the size is smaller then the buffer - *ioPathLength=nameLen; // set the length. otherwise the size is clipped because - // the buffer is too small. - - END_SECAPI -} - - -UInt16 SecKeychainListGetCount(void) -{ - BEGIN_SECAPI - return globals().storageManager.size(); - END_SECAPI -} - - -OSStatus SecKeychainListCopyKeychainAtIndex(UInt16 index, SecKeychainRef *keychainRef) -{ - BEGIN_SECAPI - KeychainCore::StorageManager &smgr=KeychainCore::globals().storageManager; - RequiredParam(keychainRef)=KeychainRef::handle(smgr[index]); - END_SECAPI -} - -OSStatus SecKeychainItemCreateFromContent(SecItemClass itemClass, SecKeychainAttributeList *attrList, UInt32 length, const void *data, SecKeychainRef keychainRef, SecKeychainItemRef *itemRef) -{ - BEGIN_SECAPI - KCThrowParamErrIf_(length!=0 && data==NULL); - Item item(itemClass, attrList, length, data); - Keychain::optional(keychainRef)->add(item); - if (itemRef) - *itemRef = ItemRef::handle(item); - END_SECAPI -} - -OSStatus SecKeychainItemModifyContent(SecKeychainItemRef itemRef, const SecKeychainAttributeList *attrList, UInt32 length, const void *data) -{ - BEGIN_SECAPI - Item item = ItemRef::required(itemRef); - item->modifyContent(attrList, length, data); - END_SECAPI -} - - -OSStatus SecKeychainItemCopyContent(SecKeychainItemRef itemRef, SecItemClass *itemClass, SecKeychainAttributeList *attrList, UInt32 *length, void **outData) -{ - BEGIN_SECAPI - Item item = ItemRef::required(itemRef); - item->getContent(itemClass, attrList, length, outData); - END_SECAPI -} - -OSStatus SecKeychainItemFreeContent(SecKeychainAttributeList *attrList, void *data) -{ - BEGIN_SECAPI - ItemImpl::freeContent(attrList, data); - END_SECAPI -} - - -OSStatus SecKeychainAttributeInfoForItemID(SecKeychainRef keychainRef, UInt32 itemID, SecKeychainAttributeInfo **info) -{ - BEGIN_SECAPI - Keychain keychain = Keychain::optional(keychainRef); - keychain->getAttributeInfoForItemID(itemID, info); - END_SECAPI -} - -OSStatus SecKeychainFreeAttributeInfo(SecKeychainAttributeInfo *info) -{ - BEGIN_SECAPI - KeychainImpl::freeAttributeInfo(info); - END_SECAPI -} - -OSStatus SecKeychainItemModifyAttributesAndData(SecKeychainItemRef itemRef, const SecKeychainAttributeList *attrList, UInt32 length, const void *data) -{ - BEGIN_SECAPI - Item item = ItemRef::required(itemRef); - item->modifyAttributesAndData(attrList, length, data); - END_SECAPI -} + if (!keychainRef) + return errSecInvalidKeychain; -OSStatus SecKeychainItemCopyAttributesAndData(SecKeychainItemRef itemRef, SecKeychainAttributeInfo *info, SecItemClass *itemClass, SecKeychainAttributeList **attrList, UInt32 *length, void **outData) -{ - BEGIN_SECAPI - Item item = ItemRef::required(itemRef); - item->getAttributesAndData(info, itemClass, attrList, length, outData); - END_SECAPI -} - -OSStatus SecKeychainItemFreeAttributesAndData(SecKeychainAttributeList *attrList, void *data) -{ - BEGIN_SECAPI - ItemImpl::freeAttributesAndData(attrList, data); - END_SECAPI -} - -OSStatus SecKeychainItemDelete(SecKeychainItemRef itemRef) -{ - BEGIN_SECAPI - Item item = ItemRef::required( itemRef ); - Keychain keychain = item->keychain(); - KCThrowIf_( !keychain, errSecInvalidItemRef ); - - keychain->deleteItem( item ); // item must be persistant. - END_SECAPI -} - - -OSStatus SecKeychainItemCopyKeychain(SecKeychainItemRef itemRef, SecKeychainRef* keychainRef) -{ - BEGIN_SECAPI - Required(keychainRef) = KeychainRef::handle(ItemRef::required(itemRef)->keychain()); - END_SECAPI -} - - -OSStatus SecKeychainItemCreateCopy(SecKeychainItemRef itemRef, SecKeychainItemRef *itemCopy, SecKeychainRef destKeychainRef) -{ - BEGIN_SECAPI - Item copy = ItemRef::required(itemRef)->copyTo(Keychain::optional(destKeychainRef)); - if (itemCopy) - *itemCopy = ItemRef::handle(copy); - END_SECAPI + CFRelease(keychainRef); + return noErr; } - OSStatus SecKeychainItemRelease(SecKeychainItemRef itemRef) { - BEGIN_SECAPI - ItemRef::release(itemRef); - END_SECAPI -} - -OSStatus SecKeychainSearchCreateFromAttributes(SecKeychainRef keychainRef, SecItemClass itemClass, const SecKeychainAttributeList *attrList, SecKeychainSearchRef *searchRef) -{ - BEGIN_SECAPI - - Required(searchRef); // Make sure that searchRef is an invalid SearchRef - - KCCursor cursor; - if (keychainRef) - cursor = Keychain::optional(keychainRef)->createCursor(itemClass, attrList); - else - cursor = globals().storageManager.createCursor(itemClass, attrList); - - *searchRef = KCCursorRef::handle(cursor); + if (!itemRef) + return errSecInvalidItemRef; - END_SECAPI + CFRelease(itemRef); + return noErr; } - - -OSStatus SecKeychainCopySearchNextItem(SecKeychainSearchRef searchRef, SecKeychainItemRef *itemRef) -{ - BEGIN_SECAPI - RequiredParam(itemRef); - Item item; - if (!KCCursorRef::required(searchRef)->next(item)) - return errSecItemNotFound; - *itemRef=ItemRef::handle(item); - END_SECAPI -} - OSStatus SecKeychainSearchRelease(SecKeychainSearchRef searchRef) { - BEGIN_SECAPI - KCCursorRef::release(searchRef); - END_SECAPI -} + if (!searchRef) + return errSecInvalidSearchRef; - -OSStatus SecKeychainListRemoveKeychain(SecKeychainRef *keychainRef) -{ - BEGIN_SECAPI - list SecKeychainRefToRemove; - SecKeychainRefToRemove.push_back(RequiredParam(keychainRef)); - StorageManager &smgr = globals().storageManager; - smgr.remove(SecKeychainRefToRemove); - return noErr; - END_SECAPI -} - - -pascal OSStatus SecKeychainAddCallback(SecKeychainCallbackProcPtr callbackFunction, SecKeychainEventMask eventMask, void* userContext) -{ - BEGIN_SECAPI - RequiredParam(callbackFunction); - CCallbackMgr::AddCallback(callbackFunction,eventMask,userContext); - END_SECAPI -} - -OSStatus SecKeychainRemoveCallback(SecKeychainCallbackProcPtr callbackFunction) -{ - BEGIN_SECAPI - RequiredParam(callbackFunction); - CCallbackMgr::RemoveCallback(callbackFunction); - END_SECAPI -} - - -// --- Private API - -OSStatus SecKeychainChangePassword(SecKeychainRef keychainRef, UInt32 oldPasswordLength, const void *oldPassword, UInt32 newPasswordLength, const void *newPassword) -{ - BEGIN_SECAPI - globals().storageManager.changeLoginPassword(oldPasswordLength, oldPassword, newPasswordLength, newPassword); - END_SECAPI -} - -OSStatus SecKeychainCopyLogin(SecKeychainRef *keychainRef) -{ - BEGIN_SECAPI - // NOTE: operates on default Keychain! It shouldn't... we want to - // have code that operates of a login keychain. - RequiredParam(keychainRef)=KeychainRef::handle(globals().defaultKeychain.keychain()); - END_SECAPI -} - - -OSStatus SecKeychainAddInternetPassword(SecKeychainRef keychainRef, UInt32 serverNameLength, char *serverName, - UInt32 securityDomainLength, char *securityDomain, UInt32 accountNameLength, char *accountName, - UInt32 pathLength, char *path, UInt16 port, OSType protocol, OSType authType, - UInt32 passwordLength, const void *passwordData, SecKeychainItemRef *itemRef) -{ - BEGIN_SECAPI - KCThrowParamErrIf_(passwordLength!=0 && passwordData==NULL); - // @@@ Get real itemClass - Item item(kSecInternetPasswordItemClass, 'aapl', passwordLength, passwordData); - - if (serverName && serverNameLength) - item->setAttribute(Schema::attributeInfo(kSecServerItemAttr), - CssmData(serverName, serverNameLength)); - - if (accountName && accountNameLength) - { - CssmData account(accountName, accountNameLength); - item->setAttribute(Schema::attributeInfo(kSecAccountItemAttr), account); - // @@@ We should probably leave setting of label up to lower level code. - item->setAttribute(Schema::attributeInfo(kSecLabelItemAttr), account); - } - - if (securityDomain && securityDomainLength) - item->setAttribute(Schema::attributeInfo(kSecSecurityDomainItemAttr), - CssmData(securityDomain, securityDomainLength)); - - item->setAttribute(Schema::attributeInfo(kSecPortItemAttr), UInt32(port)); - item->setAttribute(Schema::attributeInfo(kSecProtocolItemAttr), protocol); - item->setAttribute(Schema::attributeInfo(kSecAuthTypeItemAttr), authType); - - if (path && pathLength) - item->setAttribute(Schema::attributeInfo(kSecPathItemAttr), - CssmData(path, pathLength)); - - Keychain::optional(keychainRef)->add(item); - if (itemRef) - *itemRef = ItemRef::handle(item); - - END_SECAPI -} - -OSStatus SecKeychainFindInternetPassword(SecKeychainRef keychainRef, UInt32 serverNameLength, char *serverName, - UInt32 securityDomainLength, char *securityDomain, UInt32 accountNameLength, char *accountName, - UInt32 pathLength, char *path, UInt16 port, OSType protocol, OSType authType, - UInt32 *passwordLength, void **passwordData, SecKeychainItemRef *itemRef) - -{ - BEGIN_SECAPI - - - UInt32 attrCount = 0; - - // The number of attributes to search on depends on what was passed in - if ( serverName && serverNameLength) - attrCount++; - - if ( securityDomain && securityDomainLength ) - attrCount++; - - if ( accountName && accountNameLength) - attrCount++; - - if ( port ) - attrCount++; - - if ( protocol ) - attrCount++; - - if ( authType ) - attrCount++; - - if ( path && pathLength ) - attrCount++; - - auto_array attrs(attrCount); - attrCount = 0; - - if ( serverName && serverNameLength ) - { - attrs[attrCount].tag = kSecServerItemAttr; - attrs[attrCount].length = serverNameLength; - attrs[attrCount].data = serverName; - attrCount++; - } - if ( securityDomain && securityDomainLength ) - { - attrs[attrCount].tag = kSecSecurityDomainItemAttr; - attrs[attrCount].length = securityDomainLength; - attrs[attrCount].data = securityDomain; - attrCount++; - } - if ( accountName && accountNameLength ) - { - attrs[attrCount].tag = kSecAccountItemAttr; - attrs[attrCount].length = accountNameLength; - attrs[attrCount].data = accountName; - attrCount++; - } - - if ( port ) - { - attrs[attrCount].tag = kSecPortItemAttr; - attrs[attrCount].length = sizeof( port ); - attrs[attrCount].data = &port; - attrCount++; - } - if ( protocol ) - { - attrs[attrCount].tag = kSecProtocolItemAttr; - attrs[attrCount].length = sizeof( protocol ); - attrs[attrCount].data = &protocol; - attrCount++; - } - if ( authType ) - { - attrs[attrCount].tag = kSecAuthTypeItemAttr; - attrs[attrCount].length = sizeof( authType ); - attrs[attrCount].data = &authType; - attrCount++; - } - - if ( path && pathLength ) - { - attrs[attrCount].tag = kSecPathItemAttr; - attrs[attrCount].length = pathLength; - attrs[attrCount].data = path; - attrCount++; - } - - SecKeychainAttributeList attrList; - attrList.count = attrCount; - attrList.attr = attrs.get(); - - Item item; - - KCCursor cursor; - if (keychainRef) - cursor = Keychain::optional(keychainRef)->createCursor(kSecInternetPasswordItemClass, &attrList); - else - cursor = globals().storageManager.createCursor(kSecInternetPasswordItemClass, &attrList); - - if (!cursor->next(item)) - return errSecItemNotFound; - - - // Get its data (only if necessary) - if ( passwordData || passwordLength ) - { - CssmDataContainer outData; - item->getData(outData); - *passwordLength=outData.length(); - outData.Length=NULL; - *passwordData=outData.data(); - outData.Data=NULL; - } - - if (itemRef) - *itemRef=ItemRef::handle(item); - - - END_SECAPI - - - -} - -OSStatus SecKeychainAddGenericPassword(SecKeychainRef keychainRef, UInt32 serviceNameLength, char *serviceName, - UInt32 accountNameLength, char *accountName, - UInt32 passwordLength, const void *passwordData, SecKeychainItemRef *itemRef) - -{ - BEGIN_SECAPI - - KCThrowParamErrIf_(passwordLength!=0 && passwordData==NULL); - // @@@ Get real itemClass - Item item(kSecGenericPasswordItemClass, 'aapl', passwordLength, passwordData); - - if (serviceName && serviceNameLength) - item->setAttribute(Schema::attributeInfo(kSecServiceItemAttr), CssmData(serviceName, serviceNameLength)); - - if (accountName && accountNameLength) - { - CssmData account(accountName, accountNameLength); - item->setAttribute(Schema::attributeInfo(kSecAccountItemAttr), account); - // @@@ We should probably leave setting of label up to lower level code. - item->setAttribute(Schema::attributeInfo(kSecLabelItemAttr), account); - } - - Keychain::optional(keychainRef)->add(item); - if (itemRef) - *itemRef = ItemRef::handle(item); - - END_SECAPI -} - -OSStatus SecKeychainFindGenericPassword(SecKeychainRef keychainRef, UInt32 serviceNameLength, char *serviceName, - UInt32 accountNameLength, char *accountName, - UInt32 *passwordLength, void **passwordData, SecKeychainItemRef *itemRef) - -{ - BEGIN_SECAPI - UInt32 attrCount = 0; - - // The number of attributes to search on depends on what was passed in - if (serviceName && serviceNameLength) - attrCount++; - - if (accountName && accountNameLength) - attrCount++; - - auto_array attrs(attrCount); - attrCount = 0; - - if (serviceName && serviceNameLength) - { - attrs[attrCount].tag = kSecServiceItemAttr; - attrs[attrCount].length = serviceNameLength; - attrs[attrCount].data = serviceName; - attrCount++; - } - if (accountName && accountNameLength) - { - attrs[attrCount].tag = kSecAccountItemAttr; - attrs[attrCount].length = accountNameLength; - attrs[attrCount].data = accountName; - attrCount++; - } - - SecKeychainAttributeList attrList; - attrList.count = attrCount; - attrList.attr = attrs.get(); - - Item item; - - KCCursor cursor; - if (keychainRef) - cursor = Keychain::optional(keychainRef)->createCursor(kSecGenericPasswordItemClass, &attrList); - else - cursor = globals().storageManager.createCursor(kSecGenericPasswordItemClass, &attrList); - - if (!cursor->next(item)) - return errSecItemNotFound; - - - // Get its data (only if necessary) - if ( passwordData || passwordLength ) - { - CssmDataContainer outData; - item->getData(outData); - *passwordLength=outData.length(); - outData.Length=NULL; - *passwordData=outData.data(); - outData.Data=NULL; - } - - if (itemRef) - *itemRef=ItemRef::handle(item); - - - END_SECAPI -} - -OSStatus SecKeychainLogin(UInt32 nameLength, void* name, UInt32 passwordLength, void* password) -{ - BEGIN_SECAPI - globals().storageManager.login(nameLength, name, passwordLength, password); - END_SECAPI -} - -OSStatus SecKeychainLogout() -{ - BEGIN_SECAPI - globals().storageManager.logout(); - END_SECAPI + CFRelease(searchRef); + return noErr; } -OSStatus SecKeychainSetUserInteractionAllowed(Boolean state) +OSStatus SecKeychainCopySearchNextItem(SecKeychainSearchRef searchRef, SecKeychainItemRef *itemRef) { - BEGIN_SECAPI - globals().setUserInteractionAllowed(state); - END_SECAPI - -} + static bool warnonce; + if (!warnonce) + { + warnonce = true; + Syslog::warning("Calling OBSOLETE SecKeychainCopySearchNextItem please use SecKeychainSearchCopyNext instead"); + } -OSStatus SecKeychainGetUserInteractionAllowed(Boolean *state) -{ - BEGIN_SECAPI - Required(state)=globals().getUserInteractionAllowed(); - END_SECAPI - + return SecKeychainSearchCopyNext(searchRef, itemRef); } -