Sending derived credentials to the Ivanti client

Sending a derived credential to the Ivanti client requires the following tasks in your app:

Handling the custom URL scheme in your app delegate

Checking if the Ivanti client supports derived credentials

Checking if sending credentials to Ivanti 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 Ivanti 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 Ivanti 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 Ivanti 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 Ivanti 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 Ivanti client supports derived credentials

Before beginning the logic to create a derived credential and send it to the Ivanti client, check whether an Ivanti 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 Ivanti 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 Ivanti client
	// is currently allowed.
}

Checking if sending credentials to Ivanti client is currently allowed

Before your app obtains derived credentials and prepares them for delivery to the Ivanti client, make sure sending credentials is currently allowed. It is allowed only if secure services are available and the Ivanti client supports receiving derived credentials. At this point, you have already verified that the Ivanti client supports derived credentials, but secure services are not necessarily available.

Header file: ACDerivedCredentialService.h

Method:

+(BOOL) canSendCredential;

Return values:

Returns YES if an Ivanti 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 Ivanti 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 Ivanti 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.

Table 55.   Entries in the NSDictionary object of a certificate array entry

Entry

Key

Value

The certificate tag

 

ACDerivedCredentialPayloadKeyTag

 

An NSString object

The value describes the expected use of the certificate. The Ivanti 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:

ACDerivedCredentialTagAuthentication

ACDerivedCredentialTagSigning

ACDerivedCredentialTagEncryption

ACDerivedCredentialTagEscrow

 

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;
Table 56.   parameters for -initWithName:serialNumber:expirationDate:certificates:

Parameter

Description

name

A human readable name for this derived credential payload. The Ivanti 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

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 Ivanti client.

Header file: ACDerivedCredentialService.h

Method:

-(instancetype)initWithBrand:(NSString *)brand
	callbackScheme:(NSString *)callbackScheme NS_DESIGNATED_INITIALIZER;
Table 57.   parameters for -initWithBrand:callbackScheme:

Parameter

Description

brand

The name of the derived credentials provider.

callbackScheme

The custom URL scheme that your app defines for the Ivanti 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 Ivanti client does not support derived credentials

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 Ivanti client

After creating the ACDerivedCredential and ACDerivedCredentialService objects, send the derived credential to the Ivanti client.

Header file: ACDerivedCredentialService.h

Method:

-(BOOL)sendDerivedCredential:(ACDerivedCredential*)derivedCredential withError:(NSError **)error;
Table 58.   Parameters for -sendDerivedCredential:withError:

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 Ivanti client. Otherwise, returns NO.

When the return value is YES, the Ivanti 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 Ivanti 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 Ivanti client.
}

Handling secure services becoming available

Sending derived credentials to the Ivanti client requires AppConnect’s secure services to be available. Your app calls the method +canSendCredential, which checks if secure services are available and the Ivanti 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 Ivanti 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 Ivanti client.
		// Notify the user as necessary, and change your app state appropriately.
	}
}