From f730b121e6cce058f0ba2c530326c46807a586b4 Mon Sep 17 00:00:00 2001 From: Christopher Lloyd Date: Thu, 1 Apr 2010 12:05:15 -0400 Subject: [PATCH] (fixes issue #549) Security additions by Matt Gallagher --- Security/SecBase.h | 5 ++++ Security/SecBase.m | 63 ++++++++++++++++++++++++++++++++++++++++++ Security/SecKeychain.m | 2 ++ 3 files changed, 70 insertions(+) diff --git a/Security/SecBase.h b/Security/SecBase.h index da5eb0a3..a93acef0 100644 --- a/Security/SecBase.h +++ b/Security/SecBase.h @@ -66,6 +66,8 @@ enum { kSecAccountItemAttr='acct', kSecServerItemAttr='srvr', kSecProtocolItemAttr='ptcl', + kSecServiceItemAttr='svce', + kSecGenericPasswordItemClass='genp' }; // Keychain Item Class @@ -77,6 +79,8 @@ enum { errSecItemNotFound=-25300 }; +SECURITY_EXPORT OSStatus SecKeychainFindGenericPassword (CFTypeRef keychainOrArray, UInt32 serviceNameLength, const char *serviceName, UInt32 accountNameLength, const char *accountName, UInt32 *passwordLength, void **passwordData, SecKeychainItemRef *itemRef); +SECURITY_EXPORT OSStatus SecKeychainAddGenericPassword (SecKeychainRef keychain, UInt32 serviceNameLength, const char *serviceName, UInt32 accountNameLength, const char *accountName, UInt32 passwordLength, void *passwordData, SecKeychainItemRef *itemRef); SECURITY_EXPORT OSStatus SecKeychainSearchCreateFromAttributes(CFTypeRef keychainOrArray,SecItemClass itemClass,const SecKeychainAttributeList *attributeList,SecKeychainSearchRef *resultSearch); SECURITY_EXPORT OSStatus SecKeychainSearchCopyNext(SecKeychainSearchRef search,SecKeychainItemRef *resultItem); @@ -84,6 +88,7 @@ SECURITY_EXPORT OSStatus SecKeychainSearchCopyNext(SecKeychainSearchRef search,S SECURITY_EXPORT OSStatus SecKeychainItemCopyAttributesAndData(SecKeychainItemRef item,SecKeychainAttributeInfo *info,SecItemClass *itemClass,SecKeychainAttributeList **attributeList,UInt32 *length,void **resultBytes); SECURITY_EXPORT OSStatus SecKeychainItemModifyAttributesAndData(SecKeychainItemRef item,const SecKeychainAttributeList *attributeList,UInt32 length,const void *bytes); SECURITY_EXPORT OSStatus SecKeychainItemFreeAttributesAndData(SecKeychainAttributeList *attributeList,void *data); +SECURITY_EXPORT OSStatus SecKeychainItemFreeContent(SecKeychainAttributeList *attributeList,void *data); SECURITY_EXPORT OSStatus SecTrustedApplicationCreateFromPath(const char *path,SecTrustedApplicationRef *resultApplication); SECURITY_EXPORT OSStatus SecAccessCreate(CFStringRef descriptor,CFArrayRef trustedlist,SecAccessRef *resultAccess); diff --git a/Security/SecBase.m b/Security/SecBase.m index 18eef816..7f809a8f 100644 --- a/Security/SecBase.m +++ b/Security/SecBase.m @@ -5,6 +5,60 @@ #import "SecKeychainSearch.h" #import "SecTrustedApplication.h" +OSStatus SecKeychainFindGenericPassword(CFTypeRef keychainOrArray, UInt32 serviceNameLength, const char *serviceName, UInt32 accountNameLength, const char *accountName, UInt32 *passwordLength, void **passwordData, SecKeychainItemRef *itemRef) +{ + SecKeychainAttributeList attributeList; + attributeList.count = 2; + attributeList.attr = malloc(sizeof(SecKeychainAttribute) * attributeList.count); + attributeList.attr[0].tag = kSecAccountItemAttr; + attributeList.attr[0].length = accountNameLength; + attributeList.attr[0].data = (void *)accountName; + attributeList.attr[1].tag = kSecServiceItemAttr; + attributeList.attr[1].length = serviceNameLength; + attributeList.attr[1].data = (void *)serviceName; + + SecKeychainSearchRef search; + OSStatus status = SecKeychainSearchCreateFromAttributes(NULL, kSecGenericPasswordItemClass, &attributeList, &search); + if (status != noErr) + { + free(attributeList.attr); + return status; + } + + status = SecKeychainSearchCopyNext(search, itemRef); + if (status == noErr && *itemRef) + { + status = SecKeychainItemCopyAttributesAndData(*itemRef, NULL, NULL, NULL, passwordLength, passwordData); + } + else + { + status = errSecItemNotFound; + *itemRef = NULL; + *passwordData = NULL; + *passwordLength = 0; + } + + free(attributeList.attr); + return status; +} + +OSStatus SecKeychainAddGenericPassword (SecKeychainRef keychain, UInt32 serviceNameLength, const char *serviceName, UInt32 accountNameLength, const char *accountName, UInt32 passwordLength, void *passwordData, SecKeychainItemRef *itemRef) +{ + SecKeychainAttributeList attributeList; + attributeList.count = 2; + attributeList.attr = malloc(sizeof(SecKeychainAttribute) * attributeList.count); + attributeList.attr[0].tag = kSecAccountItemAttr; + attributeList.attr[0].length = accountNameLength; + attributeList.attr[0].data = (void *)accountName; + attributeList.attr[1].tag = kSecServiceItemAttr; + attributeList.attr[1].length = serviceNameLength; + attributeList.attr[1].data = (void *)serviceName; + + OSStatus status = SecKeychainItemCreateFromContent(kSecGenericPasswordItemClass, &attributeList, passwordLength, passwordData, keychain, NULL, itemRef); + free(attributeList.attr); + return status; +} + OSStatus SecKeychainSearchCreateFromAttributes(CFTypeRef keychainOrArray,SecItemClass itemClass,const SecKeychainAttributeList *attributeList,SecKeychainSearchRef *resultSearch) { *resultSearch=[[SecKeychainSearch alloc] initWithKeychainOrArray:keychainOrArray itemClass:itemClass attributeList:attributeList]; return 0; @@ -35,6 +89,15 @@ OSStatus SecKeychainItemFreeAttributesAndData(SecKeychainAttributeList *attribut return 0; } +OSStatus SecKeychainItemFreeContent(SecKeychainAttributeList *attributeList,void *data) { + SecFreeAttributeList(attributeList); + + if(data!=NULL) + NSZoneFree(NULL,data); + + return 0; +} + OSStatus SecTrustedApplicationCreateFromPath(const char *path,SecTrustedApplicationRef *resultApplication) { *resultApplication=[[SecTrustedApplication alloc] init]; return 0; diff --git a/Security/SecKeychain.m b/Security/SecKeychain.m index febd422c..bb245c2c 100644 --- a/Security/SecKeychain.m +++ b/Security/SecKeychain.m @@ -279,6 +279,7 @@ static void *decryptData(void *bytes,unsigned length,unsigned *resultLength){ case kSecLabelItemAttr: // utf8 case kSecAccountItemAttr: // utf8 case kSecServerItemAttr: // utf8 + case kSecServiceItemAttr: // utf8 ; const char *utf8=[string UTF8String]; @@ -380,6 +381,7 @@ static void *decryptData(void *bytes,unsigned length,unsigned *resultLength){ case kSecLabelItemAttr: // utf8 case kSecAccountItemAttr: // utf8 case kSecServerItemAttr: // utf8 + case kSecServiceItemAttr: // utf8 ; NSString *string=[[NSString alloc] initWithBytes:data length:length encoding:NSUTF8StringEncoding]; const unichar *unicode=ZeroTerminatedString(string);