Creating a Custom Certificate Provider
The certificate provider interface source files are distributed with the Hybrid SDK (Kapsel) Logon plugin. For iOS, the interface files are available at the Kapsel SDK installation folder at plugins/logon/ios/headers. For Android, the interfaces are available in the plugins/logon/android/libs/CommonCertificateProvider.jar file.
Create a CustomCertificateProvider that implements methods in the CertificateProvider interface.
For iOS:
- (void) initialize:(NSDictionary*)option withCompletion:(void(^)(SecIdentityRef identityRef, NSError* error))completion - (NSString*) getProviderID - (BOOL) getStoredCertificate:(SecIdentityRef *)identityRef error:(NSError**)anError; - (BOOL) deleteStoredCertificateWithError:(NSError**)anError; - (BOOL) setParameters:(NSDictionary*)params failedWithError:(NSError **)error;
For Android:
initialize(CertificateProviderListener callback) throws CertificateProviderException; void getCertificate(CertificateProviderListener callbackObject) X509KeyManager getStoredCertificate() void deleteStoredCertificate() void setParameters(Map params)
For Windows:
#if NETFX_CORE Windows.Security.Cryptography.Certificates.Certificate #else System.Security.Cryptography.X509Certificates.X509Certificate2 #endif GetCertificate(); #if NETFX_CORE IAsyncAction #else Task #endif DeleteStoredCertificateAsync(); #if NETFX_CORE IAsyncAction #else Task #endif InitializeAsync();
The setParameters method is optional, and necessary only if the application needs to pass extra information to the certificate provider for retrieving the certificate. For example, if the iOS certificate provider needs to receive the URL information from the AppDelegate's openURL method, the application delegate can call the certificate provider's setParameter method to pass the URL information to the certificate provider.
initialize Method
The initialize method is an asynchronous call made by Kapsel Logon plugin to provision a certificate from the certificate provider. If required, the Certificate Provider can present a native UI screen.
The Logon plugin calls the initialize method to retrieve the client certificate before logon registration or OData requests. The initialize method contains logic to retrieve the client certificate from the server or local file system and store the client certificate as a SecRefIdentity (for iOS), or X509KeyManager (for Android). If the certificate already exists on the device when the initialize method is called, it should only return the existing certificate to the caller without retrieving a new certificate from the server (on iOS) or only call CertificateProviderListener.initializationComplete (on Android).
For Android:
To get an activity context, the Kapsel plugin passes an android context reference through setParameters call. The constant to get the context is available on the CerticateProvider interface as ANDROID_CONTEXT_KEY. Once the provider has done all its initialization, and is prepared to return a certificate synchronously, it should call CertificateProviderListener.initializationComplete. It does not provide the certificate at this point. When the certificate is needed, the getStoredCertificate function will be called on the certificate provider.
For iOS:
The Logon plugin calls the initialize method to retrieve the client certificate. Once the certificate is retrieved, it uses the completion block to return the results to the caller, so the Logon plugin can use the identity to authenticate the end user for registration.
In case an error occurs while retrieving the certificate from the server, or the user cancels the operation before completion, the certificate provider should create an NSError object with the related information, and return the object in the completion block's error parameter. Note that teh certificate provider should only call the completion block with error information for non-recoverable errors. For recoverable errors, the certificate provider should automatically let the user retry. For example, if the user enters a wrong username or password, the certificate provider should allow the user to retry the username and password instead of calling the completion block to report the error to the caller.
-
Inform the user to retry and continue the initialization (if the error is recoverable)
-
Abort the current operation and call the completion block to report the error (if the error is not recoverable, or if a user cancels the retry operation)
getProviderID Method (iOS)
The certificate provider should implement the getProviderID method to provide the unique string that identifies the certificate provider type. The unique string must be distinct from the SAP provided certificate provider IDs of "afaria" or "com.sap.afaria". For the iOS client, it is recommended to return only the certificate provider's class name as the certificate provider's ID as follows:
-(NSString*) getProviderID{ return NSStringFromClass (self.class); }
GetCertificate (Windows)
The GetCertificate is a synchronous method to receive certificate from a provider. This method provides certificates stored by the provider and does not access any external servers or display any UI to enter parameters.
getStoredCertificate Method
The getStoredCertificate method is different from initialize in one critical way: it is synchronous, and is designed to be called by the application many times, for HTTP requests, instead of only once, for application registration. Therefore, the implementation should return either a certificate (identity on iOS, X509KeyManager on Android) already in memory, or return a certificate from the keychain or a similar 3rd-party API. You should not show any UI or execute long-running processes within this method.
If an identity cannot be returned from the keychain, return only null as the client certificate to the caller, but set the error parameter to null.
If an error occurs when executing the method, you should return an error to the caller to report the error.
deleteStoredCertificate Method
The deleteStoredCertificate method is necessary for handling cases of "invalid certificate" HTTP responses, which might result from an expired or revoked certificate. If a certificate is invalid, the application can call this method to delete it and then call the initialize method to get a new certificate from the server.
setParameters Method
The setParameters method is optional, and necessary only if the certificate provider wants to receive information from the application while retrieving the certificate. You can also use the setParameters method to provide optional information for the certificate provider implementation. For example, the Logon Plugin can provide information to present native UI (like the Activity object for Android), or the application can call this method to pass the launch URL information to certificate provider (if the application receives the AppDelegate.openURL message on iOS).