Developer Guide for iOS

The following issues or updates were identified in this document.

TitleSummary
675835
The Encryptionkey API is located within the database class:
(void)setEncryptionKey:(SUPString)value
Sets the  encryption key for the database in SUPConnectionProfile. 
It should be called before any database operations.

[cp setEncryptionKey:@”test”];

(void)changeEncryptionKey:(SUPString)
Changes the encryption key to the newKey value and saves the newKey value to the connection profile. 
This should be called after the call to createDatabase.

[SampleApp_SampleAppDB changeEncryptionKey:@"newkey" ];

(SUPString)encryptionKey
retrieve the current encryption key from SUPConnection Profile object.

	[cp encryptionKey];
667144
Understand how to secure iOS applications at the messaging layer with SUPDataVault

In Unwired Platform version 2.0 and earlier, you used the SUPKeyVault interface to secure iOS (iPhone) client applications, including security for the messaging layer. (See "Configuring Application Security Using Keychain" in the 2.0 Developer Reference for iOS.)

For Unwired Platform version 2.0 ESD#1 and later, the SUPKeyVault class has been deprecated.

Use the new SUPDataVault class (introduced in Unwired Platform version 2.0 for all client platforms) for on-device persistent storage of certificates, DB encryption keys, passwords, and other sensitive items.

This section explains how to secure the messaging layer using the SUPDataVault class. The class provides some defined strings for this purpose:

// ID of the standard messaging data vault
// Messaging vault must be unlocked before calling startEngine which will use the key from this vault to decrypt the messaging queue database
extern NSString * const kMessagingDataVaultID;

// Standard password and salt used in "No" security mode
extern NSString * const kDVStandardPassword;
extern NSString * const kDVStandardSalt;

The encryption key used by the messaging layer is stored in a DataVault named "kMessagingDataVaultID". The application simply unlocks the DataVault "kMessagingDataVaultID" before starting the engine. If the vault stays locked, the messaging layer cannot retrieve the key it needs to decrypt the persistent storage it uses, and the engine does not start.

If the application does not create this vault, or does not modify it, it will be locked with constant known values for password and salt (kDVStandardPassword and kDVStandardSalt). If the messaging layer startup code detects that the vault is locked, it attempts to unlock the vault with those values, and if successful, proceeds to start the messaging engine. This is the default "no security" mode of operation.

To secure the vault, the application can create it (if it does not already exist), unlock it with the standard password and salt values above, then change the password and salt to values provided by the application or by the user, then lock the vault. The messaging layer is then secure from any access until the application unlocks the vault with the new password and salt values.

Typical usage in an application is:
  1. The application first creates kMessagingDataVaultID DataVault with StandardPassword and StandardSalt:
    SUPDataVault *messagingVault = nil;
        if([SUPDataVault vaultExists:kMessagingDataVaultID])
            messagingVault = [SUPDataVault getVault:kMessagingDataVaultID];
        else
            messagingVault = [SUPDataVault createVault:kMessagingDataVaultID
                                  withPassword:kDVStandardPassword 
                                      withSalt:kDVStandardSalt];
  2. If the application can unlock kMessagingDataVaultID DataVault with StandardPassword & StandardSalt and if it requires a security PIN (for example, a Mobile Workflow application), then it asks you to create a PIN and changes the password in the DataVault to the newly created PIN.
  3. If the application cannot unlock kMessagingDataVaultID DataVault with StandardPassword and StandardSalt then it asks the user to enter PIN:
    @try
        {
            [messagingVault unlock:kDVStandardPassword withSalt:kDVStandardSalt];
        // If we reach this line, user has not changed the password
        // Put code here to request password from the user
            [messagingVault changePassword:myMessageVaultPassword withSalt:myMessageVaultSalt];
        }
        @catch (NSException *e)
        {
            if([[e reason] isEqualToString:kDataVaultExceptionReasonInvalidPassword])
            {
        // The vault was already secured, ask the user for their password and try to unlock the vault again
                
            } else {
        // Some other problem occurred, handle it here
            }
        }
        @finally 
        {
        // Ensure that the vault ends up locked regardless of exceptions
            [messagingVault lock];
        }
    
  4. If the application is uninstalled by the user, the keychain item used by the underlying DataVault implementation may not be removed. To workaround this problem, a check is made to see if the messaging database does not exist; if so, the application is being run for the first time, and we delete the old messaging vault if it exists (do this before running any of the code above):
    if ( ![SUPEngine isMessagingDBExist] )
        {
            @try 
            {
                [SUPDataVault deleteVault:kMessagingDataVaultID];
            }
            @catch(NSException *e)
            {
            // Ignore any exception
            }
        }