MCSMKeychainItem 1.1

MCSMKeychainItem 1.1

TestsTested
LangLanguage Obj-CObjective C
License BSD
ReleasedLast Release Dec 2014

Maintained by Spencer MacDonald.



  • By
  • Spencer MacDonald

MCSMGenericKeychainItem

MCSMKeychainItem (or more specifically MCSMGenericKeychainItem) allows you to create, fetch and remove Keychain Items from the Keychain on iOS and OS X using the same simple Objective-C API.

Generic Keychain Item allows you to store an Account (typically a username) and Password for a given Service. Doing this with MCSMGenericKeychainItem is easy:

// First Check to see if a Generic Keychain Item for the Service and Username already exists

MCSMGenericKeychainItem *genericKeychainItem = nil;

genericKeychainItem = [MCSMGenericKeychainItem genericKeychainItemForService:service
                                                                     account:account 
                                                                  attributes:attributes
                                                                       error:NULL];

// If a Generic Keychain Item already exists remove it to prevent duplicates
if(genericKeychainItem)
{
  [genericKeychainItem removeFromKeychainWithError:NULL];
}

//Add the new Generic Keychain Item                             
[MCSMGenericKeychainItem genericKeychainItemWithService:service 
                                                account:account 
                                             attributes:attributes 
                                               password:password
                                                  error:NULL];

When you want to fetch the Generic Keychain Item for a Service and Account you need to do:

MCSMGenericKeychainItem *genericKeychainItem = [MCSMGenericKeychainItem genericKeychainItemForService:service 
                                                                                              account:account 
                                                                                           attributes:attributes
                                                                                                error:NULL];

You can then get the password using the password property:

NSString *password = genericKeychainItem.password;

And to remove it from the Keychain just call removeFromKeychainWithError:

[genericKeychainItem removeFromKeychainWithError:NULL];

MCSMInternetKeychainItem

MCSMInternetKeychainItem allows you to create, fetch and remove Internet Keychain Items from the Keychain on iOS and OS X using the same simple Objective-C API.

Internet Keychain Item allows you to store a Server, Security Domain, Account (typically a username), Path, Port, Protocol, Authentication Type and Password.

The Protocols and Authentication Types are defined in Security/SecItem.h, the current list is:

Protocols

kSecAttrProtocolFTP
kSecAttrProtocolFTPAccount
kSecAttrProtocolHTTP
kSecAttrProtocolIRC
kSecAttrProtocolNNTP
kSecAttrProtocolPOP3
kSecAttrProtocolSMTP
kSecAttrProtocolSOCKS
kSecAttrProtocolIMAP
kSecAttrProtocolLDAP
kSecAttrProtocolAppleTalk
kSecAttrProtocolAFP
kSecAttrProtocolTelnet
kSecAttrProtocolSSH
kSecAttrProtocolFTPS
kSecAttrProtocolHTTPS
kSecAttrProtocolHTTPProxy
kSecAttrProtocolHTTPSProxy
kSecAttrProtocolFTPProxy
kSecAttrProtocolSMB
kSecAttrProtocolRTSP
kSecAttrProtocolRTSPProxy
kSecAttrProtocolDAAP
kSecAttrProtocolEPPC
kSecAttrProtocolIPP
kSecAttrProtocolNNTPS
kSecAttrProtocolLDAPS
kSecAttrProtocolTelnetS
kSecAttrProtocolIMAPS
kSecAttrProtocolIRCS
kSecAttrProtocolPOP3S

Authentication Types

kSecAttrAuthenticationTypeNTLM
kSecAttrAuthenticationTypeMSN
kSecAttrAuthenticationTypeDPA
kSecAttrAuthenticationTypeRPA
kSecAttrAuthenticationTypeHTTPBasic
kSecAttrAuthenticationTypeHTTPDigest
kSecAttrAuthenticationTypeHTMLForm
kSecAttrAuthenticationTypeDefault

The recommended way to create a MCSMInternetKeychainItem is:

// Fetch existing Keychain Item
MCSMInternetKeychainItem *internetKeychainItem = nil;

internetKeychainItem = [MCSMInternetKeychainItem internetKeychainItemForServer:server
                                                                securityDomain:securityDomain
                                                                       account:account
                                                                          path:path
                                                                          port:port
                                                                      protocol:protocol
                                                            authenticationType:authenticationType
                                                                    attributes:attributes
                                                                         error:NULL];

// If a Internet Keychain Item already exists remove it to prevent duplicates
if(internetKeychainItem)
{
  [internetKeychainItem removeFromKeychainWithError:NULL];
}

//Add the new Internet Keychain Item                             
[MCSMInternetKeychainItem internetKeychainItemForServer:server
                                         securityDomain:securityDomain
                                                account:account
                                                   path:path
                                                   port:port
                                               protocol:protocol
                                     authenticationType:authenticationType
                                             attributes:attributes
                                               password:password
                                                  error:NULL];

When you want to fetch the Internet Keychain Item you need to do:

MCSMInternetKeychainItem *internetKeychainItem = nil;

internetKeychainItem = [MCSMInternetKeychainItem internetKeychainItemForServer:server
                                                                securityDomain:securityDomain
                                                                       account:account
                                                                          path:path
                                                                          port:port
                                                                      protocol:protocol
                                                            authenticationType:authenticationType
                                                                    attributes:attributes
                                                                         error:NULL];

You can then get the password using the password property:

NSString *password = internetKeychainItem.password;

And to remove it from the Keychain just call removeFromKeychainWithError:

[internetKeychainItem removeFromKeychainWithError:NULL];

MCSMApplicationUUIDKeychainItem

Apple have deprecated the unique identifier API that returns the UDID for a device in iOS 5.0.

You can however generate a UUID using the CoreFoundation's CFUUIDCreateString API

The important thing to realize about CFUUIDCreateString is that (by design) it generates a different UUID everytime you call it. This means that you cannot uniquely identify a device by simply replacing [UIDevice uniqueIdentifier] with CFUUIDCreateString.

MCSMApplicationUUIDKeychainItem's approach is to generate a UUID on first call of the API and then store the UUID into the device's keychain. This means that the UUID will not change between launches of the application and storing it in the keychain means it persists between reinstalls of the application. However the UUID will be deleted if the user restores their device, along with every other keychain item.

If all you need is a replacement for UIDevice's uniqueIdentifier API, then all you need to do replace it with MCSMApplicationUUIDKeychainItem's applicationUUID API.

NSString *UUID = [MCSMApplicationUUIDKeychainItem applicationUUID];

The first time applicationUUID is called it with generate a UUID and store it in the keychain. Subsequent calls will return the previously generated UUID.

If you need more control you can retrieve the Application UUID Keychain Item using:

MCSMApplicationUUIDKeychainItem *applicationUUIDKeychainItem = [MCSMApplicationUUIDKeychainItem applicationUUIDKeychainItem];

Then you can get the UUID using the UUID property:

NSString *UUID = applicationUUIDKeychainItem.UUID

If one doesn't exist you can generate one:

MCSMApplicationUUIDKeychainItem *applicationUUIDKeychainItem = [MCSMApplicationUUIDKeychainItem generateApplicationUUIDKeychainItem];

And you can remove it using removeFromKeychainWithError:

[applicationUUIDKeychainItem removeFromKeychainWithError:NULL];