Sending derived credentials to the MobileIron client
Sending a derived credential to the MobileIron client requires the following tasks in your app:
• | Handling the custom URL scheme in your app delegate |
• | Checking if the MobileIron client supports derived credentials |
• | Checking if sending credentials to MobileIron client is currently allowed |
• | Getting a derived credential |
• | Preparing a certificates array |
• | Preparing an ACDerivedCredential object |
• | Creating an ACDervicedCredentialService object |
• | Sending the certificates to the MobileIron client |
• | Handling secure services becoming available |
Handling the custom URL scheme in your app delegate
You registered as a handler of a custom URL scheme that the MobileIron client uses to send your app derived credential requests. How to register as a handler is described in Registering as a handler of a URL scheme you define.
Add code to handle the custom URL scheme in your application delegate.
Objective-C example
-(BOOL)application:(UIApplication *)app openURL:(NSURL *) url options:(NSDictionary<NSString*,id> *) options { // If the URL is your app’s custom URL scheme for receiving derived credential // communications from the MobileIron client (in this example “myappderivedcredential”), // and the command is “new”... if ( [url.scheme isEqualToString:@"myappderivedcredential"] && [url.host isEqualToString:@"new"] ) { // begin the logic for creating a new derived credential. } }
Swift example
func application(_ app: UIApplication, open url: URL, options: [UIApplicationOpenURLOptionsKey : Any] = [:]) -> Bool { // If the URL is your app’s custom URL scheme for receiving derived credential // communications from the MobileIron client (in this example “myappderivedcredential”), // and the command is “new”... if (url.scheme == "myappderivedcredential" && url.host == "new") { // begin the logic for creating a new derived credential. } return true }
Checking if the MobileIron client supports derived credentials
Before beginning the logic to create a derived credential and send it to the MobileIron client, check whether a MobileIron client is installed that supports derived credentials.
Header file: ACDerivedCredentialService.h
Method:
+(ACDerivedCredentialServiceSupport)derivedCredentialSupport;
In a typical call flow, the app does not call this method until:
• | after the app is authorized (the authState property on the AppConnect object is ACAUTHSTATE_AUTHORIZED) |
• | after the app is in AppConnect Mode (the managedPolicy property on the AppConnect object is ACMANAGEDPOLICY_MANAGED) |
Return values:
The method returns a value from the enumeration ACDerivedCredentialServiceSupport:
typedef NS_ENUM (NSInteger, ACDerivedCredentialServiceSupport) { ACDerivedCredentialServiceSupportPresent = 0, ACDerivedCredentialServiceSupportOldClient, ACDerivedCredentialServiceSupportMissingClient }
Example:
ACDerivedCredentialServiceSupport supportStatus = [ACDerivedCredentialService derivedCredentialSupport]; if (ACDerivedCredentialServiceSupportOldClient == supportStatus) { // Notify user to upgrade MobileIron client app to latest version. // The version running does not support derived credentials. } else if (ACDerivedCredentialServiceSupportMissingClient == supportStatus) { // Typically, this case won’t happen if the app does not call +derivedCredentialSupport // until after the app is in AppConnect mode. } else { // Continue with code to check if sending credentials to the MobileIron client // is currently allowed. }
Checking if sending credentials to MobileIron client is currently allowed
Before your app obtains derived credentials and prepares them for delivery to the MobileIron client, make sure sending credentials is currently allowed. It is allowed only if secure services are available and the MobileIron client supports receiving derived credentials. At this point, you have already verified that the MobileIron client supports derived credentials, but secure services are not necessarily available.
Header file: ACDerivedCredentialService.h
Method:
+(BOOL) canSendCredential;
Return values:
Returns YES if a MobileIron client that supports derived credentials is installed and secure services are available. Otherwise, returns NO.
Example:
if (![ACDerivedCredentialService canSendCredential]) { // Notify user that derived credentials cannot be obtained at this time. // When secure services become available, the AppConnect library calls // the notification method -appConnect:secureServicesAvailabilityChangedTo:. // At that time, the app can continue with the logic to get derived credentials // and deliver them to the MobileIron client. } else { // Continue with code to get derived credential. }
Getting a derived credential
Your app gets a derived credential only after both of the following are true:
• | Your app has determined that derived credentials are supported (+derivedCredentialSupport) |
• | Your app has determined that it is allowed to send derived credentials to the MobileIron client at this time (+canSendCredential) |
Your app gets the certificates that comprise the derived credential according to its own requirements.
Preparing a certificates array
After your app has obtained the certificates that comprise the derived credential, prepare an NSArray of the certificates. Each array entry is an NSDictionary object. The following table describes each entry in the NSDictionary object.
Entry |
Key |
Value |
||||||||||||
The certificate tag
|
ACDerivedCredentialPayloadKeyTag
|
An NSString object The value describes the expected use of the certificate. The MobileIron client uses the value to determine which certificates to deliver to an AppConnect app. The value is one of the certificate tags defined in ACDerivedCredential.h:
You can use each value in only one NSDictionary object in the NSArray. That is, you can associate each value with only one certificate in the derived credential. |
||||||||||||
The certificate contents |
ACDerivedCredentialPayloadKeyCert
|
An NSData object The object contains the DER-encoded certificate data. |
||||||||||||
The certificate’s private key |
ACDerivedCredentialPayloadKeyPrivateKey
|
An NSData object The object contains the DER-encoded private key of the certificate. The private key must be in PKCS #8 format. |
Header file: ACDerivedCredential.h -- contains definitions of constants
Example:
#import <AppConnect/ACDerivedCredential.h> NSData *certificateData; // contains DER-encoded certificate data NSData *privateKeyData; // contains DER-encoded private key, in PKCS #8 format. // Insert code that gets the certificate used for authentication and its private key. NSDictionary *authCertificatePackage = @{ ACDerivedCredentialPayloadKeyTag : ACDerivedCredentialTagAuthentication, ACDerivedCredentialPayloadKeyCert : certificateData, ACDerivedCredentialPayloadKeyPrivateKey : privateKeyData }; // Insert similar code for populating NSDictionary objects with certificates to be used for // encryption or signing. The number of NSDictionary objects you populate depends on the // number of different uses for certificates your app supports. // Place the NSDictionary entries into an array NSArray *certificatesArray = @[authCertificatePackage, encryptCertificatePackage, signingCertificatePackage];
Preparing an ACDerivedCredential object
After you have prepared the certificates array, create and initialize an ACDerivedCredential object.
Header file: ACDerivedCredential.h
Method:
-(instancetype)initWithName:(NSString *)name serialNumber:(NSString *)serialNumber expirationDate:(NSDate *)expirationDate certificates:(NSArray *)certificates NS_DESIGNATED_INITIALIZER;
Parameter |
Description |
name |
A human readable name for this derived credential payload. The MobileIron client displays this name with the derived credential information. |
serialNumber |
A unique identifier for the derived credential. Typically, this serial number is provided to your app by your derived credential provider. |
expirationDate |
The expiration date of the derived credential. This date is not necessarily the same as the expiration date of each certificate in the derived credential. It is the responsibility of the derived credential provider to enforce this expiration date according to the provider’s requirements. |
certificates |
The array of certificates that comprise the derived credential. |
Return values:
• | Returns an ACDerivedCredential object if no errors occur. |
• | Returns nil if: |
- | the name or serialNumber parameter is nil or an empty string |
- | the expirationDate parameter is nil. |
- | the certificates parameter is nil or an empty array |
NOTE: | The AppConnect library within the app logs an error to the device’s console when this method returns nil. |
Example:
ACDerivedCredential *derivedCredential = [[ACDerivedCredential alloc] initWithName:@"Derived Credential Name" serialNumber:@"123-4567-8910" expirationDate:expirationDate certificates:certificatesArray];
Creating an ACDervicedCredentialService object
Create an ACDerivedCredentialService object for communicating with the MobileIron client.
Header file: ACDerivedCredentialService.h
Method:
-(instancetype)initWithBrand:(NSString *)brand callbackScheme:(NSString *)callbackScheme NS_DESIGNATED_INITIALIZER;
Parameter |
Description |
brand |
The name of the derived credentials provider. |
callbackScheme |
The custom URL scheme that your app defines for the MobileIron client to communicate with your app about derived credentials. |
Return values:
• | Returns an ACDerivedCredentialService object if no errors occur |
• | Returns nil if either of the following are true: |
- | any parameter is nil or an empty string |
- | the MobileIron client does not support derived credentials |
NOTE: | The AppConnect library within the app logs an error to the device’s console when this method returns nil. |
Example:
ACDerivedCredentialService *derivedCredentialService = [[ACDerivedCredentialService alloc] initWithBrand:@"Derived Credential Provider Name" callbackScheme:@"MyCustomDcScheme"];
Sending the certificates to the MobileIron client
After creating the ACDerivedCredential and ACDerivedCredentialService objects, send the derived credential to the MobileIron client.
Header file: ACDerivedCredentialService.h
Method:
-(BOOL)sendDerivedCredential:(ACDerivedCredential*)derivedCredential withError:(NSError **)error;
Parameter |
Description |
derivedCredential |
The ACDerivedCredential object you created and initialized. |
error |
A reference to an NSError pointer. If an error occurs, the method returns NO and updates the pointer to point to an NSError object describing the problem. Possible values of the NSError object’s code property are defined in the enumeration ACDerivedCredentialServiceErrorCode. Although allowed, passing NULL for this parameter is not recommended, since the app’s error handling would be limited. |
Return values:
Returns YES if the certificates have been sent to the MobileIron client. Otherwise, returns NO.
NOTE: | When the return value is YES, the MobileIron client is launched. Control does not automatically return to the app. Therefore, a typical behavior in this case is to change to a “home” screen that offers options for what the device user can do next. |
Example:
NSError *error = nil; BOOL credentialSent = [derivedCredentialService sendDerivedCredential:derivedCredential withError:&error]; if (!credentialSent) { // Sending the derived credential to the MobileIron client failed. // Examine the error and handle appropriately, notifying the user as necessary. // If the error is ACDerivedCredentialErrorServiceUnavailable, notify the user // and wait for the callback method -appConnect:secureServicesAvailabilityChangedTo: // to indicate that secure services are available before trying again. } else { // The derived credential was successfully sent to the MobileIron client. }
Handling secure services becoming available
Sending derived credentials to the MobileIron client requires AppConnect’s secure services to be available. Your app calls the method +canSendCredential, which checks if secure services are available and the MobileIron client supports receiving them.
If +canSendCredential returns YES, your app proceeds with getting and delivering derived credentials. However, secure services could become unavailable before you deliver the derived credentials to the MobileIron client. In that case, your app must take the appropriate actions. If +canSendCredential returns NO, your app notifies the user and must wait for secure services to become available.
Therefore, implement the notification method -appConnect:secureServicesAvailabilityChangedTo: in the AppConnectDelegate protocol, defined in AppConnect.h:
-(void) appConnect:(AppConnect *)appConnect secureServicesAvailabilityChangedTo: (ACSecureServicesAvailability)secureServicesAvailability;
Example:
-(void)appConnect:(AppConnect *)appConnect secureServicesAvailabilityChangedTo: (ACSecureServicesAvailability)secureServicesAvailability { if (ACSECURESERVICESAVAILABILITY_AVAILABLE == secureServicesAvailability) { // Notify the user as necessary, according to your app state. // The app can now proceed to logic for getting and delivering derived credentials. } else { // Secure services are not available. // The app cannot deliver derived credentials to the MobileIron client. // Notify the user as necessary, and change your app state appropriately. } }