FIDO Client Adapter
HYPR SDK for iOS
Describes the steps for integrating the HYPR FIDO Client Adapter (FCA) into an iOS Application to facilitate decentralized registration, authentication, and deregistration.
HyprFidoClientAdapter
class can be used separately from the HyprUserAgent
for FIDO Client registration, authentication and deregistration operations.
Requirements
HyprFidoClientAdapter
is a part of the HYPR SDK for iOS and can be used separately fromHyprUserAgent
- HYPR SDK for iOS supports the iOS 11+, iPhone 5S, and all latest models
- Minimum deployment target: iOS 10.0
- Valid architectures: arm64
- Minimum Xcode version: 9.2
- Objective-C or Swift
Project Setup Instructions
- Copy all frameworks from the
HyprFidoClientAdapterSampleApp
folder to your project folder.

- Add all frameworks files to your Xcode project with Add Files to ....

- On the General tab of your project file, add all frameworks to the Embedded Binaries section.

- Set Enable Bitcode to No.

- Set Valid Architectures to arm64.
HYPR SDK for iOS frameworks are ready to use in your Xcode project.
Running Instructions
Before running the HYPR SDK for iOS version with HYPR ADP included on the device, the developer should perform the following steps:
- Go to the Edit Scheme... menu.
- Uncheck the Debug executable checkmark for the appropriate target.
The simulator works without this workaround.
HYPR SDK Setup
Initialize and set the parentViewController
. parentViewController
will be used for presenting authenticators.
You must register the authenticators to be used in your app before the initialization. By default, interstitial view is enabled and if 'interstitialViewDelegate' is not set, a default interstitial view will be provided. If interstitial view is not desired, disable it by calling the 'enableInterstitialView' function.
//register authenticators
[HYPRUAFClient registerAuthenticatorModule:[HYPRFaceAsm class]];
[HYPRUAFClient registerAuthenticatorModule:[HYPRFingerprintAsm class]];
//add another ones if needed
//set custom timeout in miliseconds. 30000 is default value
[HYPRFaceAsm setTimeout:10000];
//initialize
HYPRFidoClientAdapter* adapter = [HYPRFidoClientAdapter new];
//set parent view controller
[adapter setParentViewController:self];
// disable interstitial view
[adapter enableInterstitialView:NO];
//register authenticators
HYPRUAFClient.registerAuthenticatorModule(HYPRFaceIDAsm.self)
HYPRUAFClient.registerAuthenticatorModule(HYPRFingerprintAsm.self)
//add another ones if needed
//initialize
let fidoAdapter = HYPRFidoClientAdapter()
//set parent view controller
fidoAdapter.setParentViewController(self)
// disable interstitial view
fidoAdapter.enableInterstitialView(false)
FIDO Operations
Registration
[adapter registerRequest:fidoPayload
completion:^(NSString * _Nullable resultString, NSError * _Nullable error) {
//create a call to server with successPayload or handle the error
}];
//after receiving server response notify the adapter was it successful or not
NSError* error = nil;
BOOL isSuccessful = [adapter registerDidComplete:YES error:&error];
fidoAdapter.registerRequest(requestString!) { (resultString, error) in
self.textView.text = resultString != nil ?
resultString : "\(String(describing: error))"
//create a call to server with successPayload or handle the error
}
//after receiving server response notify the adapter was it successful or not
let isSuccess = fidoAdapter.registerDidComplete(true)
Authentication
fidoPayload
UserUse the same username for authenticate requests as used in
fidoPayload
.
[adapter authenticateRequest:fidoPayload username:username
completion:^(NSString * _Nullable resultString, NSError * _Nullable error) {
//create a call to server with successPayload or handle the error
}];
//after receiving server response notify the adapter was it successful or not
NSError* error = nil;
BOOL isSuccessful = [adapter authenticateDidComplete:YES error:&error];
fidoAdapter.authenticateRequest(requestString!, username: username!) { (resultString, error) in
self.textView.text = resultString != nil ?
resultString : "\(String(describing: error))"
//create a call to server with successPayload or handle the error
}
//after receiving server response notify the adapter was it successful or not
let isSuccess = fidoAdapter.authenticateDidComplete(true)
Deregistration
fidoPayload
UserUse the same username for deregister requests as used in
fidoPayload
.
[adapter deregisterRequest:fidoPayload username:username
completion:^(NSString * _Nullable resultString, NSError * _Nullable error) {
//nothing to send to server here
}];
fidoAdapter.deregisterRequest(requestString!, username: username!) { (resultString, error) in
self.textView.text = resultString != nil ?
resultString : "\(String(describing: error))"
//nothing to send to server here
}
Error Handling
Errors may occur during registration, authentication, and deregistration.
HYPR SDK for iOS returns NSError
in the case of an error. You can check the error code and its localized description as with the standard NSError
. In the HyprError.h
interface you can find the method in the NSError
category which also could be checked for an error code and localized description.
-(NSError*)rootError;
Please see Error Reporting for more information on possible errors.
Offline Mode
The HYPRFidoClientAdapter
can perform any FIDO operations, such as registration, authentication and deregistration in offline mode.
If the payload includes the facets check and the facets URL is not reachable and no cached facets values exist, the operation will fail.
All other cases will succeed, including:
- No facets URL is specified in the payload
- Facets are cached because of previous successful facets URL checks
Policy Handling
If the HYPR SDK for iOS matches more than one set of authenticators upon a registration or authentication request, the HYPR FCA presents the ViewController
with UITableView
, which includes one set per cell. Each set may include one or many authenticators. The SDK will precede the registration or authentication process, with the chosen set following.
This feature can be turned off by passing NO to the -(void)setAAIDPickerViewEnabled:(BOOL)enabled
method of HyprFidoClientAdapter
. Also if the picker view is enabled you can enable/disable it separately for authentication with the -(void)setAAIDPickerViewEnabledForAuthentication:(BOOL)enabled
method.
// Enables/disables the AAID Picker for the Fido Client Adapter
-(void)setAAIDPickerViewEnabled:(BOOL)enabled;
// Enables/disables the AAID picker for authentication only if it is enabled with previous method
-(void)setAAIDPickerViewEnabledForAuthentication:(BOOL)enabled;
Implementing HYPRInterstitialDelegateProtocol
HYPRInterstitialDelegateProtocol
HYPRFidoClientAdapter
provides the ability to specify the custom interstitialViewDelegate
:
@property (nonatomic, weak) _Nullable id<HYPRInterstitialDelegateProtocol> interstitialViewDelegate;
Currently only UIAlertController
is supported, and the user can specify a text string only.
-(HYPRInterstitialViewModel* _Nullable)interstitialViewModelForUserInfo:(NSDictionary *)userInfo {
HYPRInterstitialViewModel *customModel = [[HYPRInterstitialViewModel alloc] init];
customModel.viewMode = HYPRInterstitialViewModeAlert;
NSString *previousDescription = userInfo[kHYPRInterstitialDelegateProtocolPreviousDescription];
NSString *nextDescription = userInfo[kHYPRInterstitialDelegateProtocolNextDescription];
NSNumber *currentStep = userInfo[kHYPRInterstitialDelegateProtocolAuthenticatorIndex];
NSNumber *totalSteps = userInfo[kHYPRInterstitialDelegateProtocolTotalAuthenticators];
NSString *title = [NSString stringWithFormat:@"Step %@ of %@ Complete",
currentStep, totalSteps];
NSString *operationString;
if ([userInfo[kHYPRInterstitialDelegateProtocolOperation] isEqualToString:kHYPRInterstitialDelegateProtocolOperationRegistration]) {
operationString = @"registration";
} else if ([userInfo[kHYPRInterstitialDelegateProtocolOperation] isEqualToString:kHYPRInterstitialDelegateProtocolOperationAuthentication]) {
operationString = @"authentication";
} else {
operationString = @"operation"; // fallback, but should not be used
}
NSString *message = [NSString stringWithFormat:@"Completed %@ for %@. Next is %@.",
operationString, previousDescription, nextDescription];
customModel.message = message;
customModel.title = title;
return customModel;
}
Authentication Failing Due to Private Key Signing
Authentication can fail if the user has deleted their passcode and created a new one. To detect this, call the following method:
let authSigningWillSucceed = HYPRFidoClientAdapter().authenticationSignatureWillSucceedDuringAuth(forUser: "User4e442oqsbi99g31u98rprrvbc3", withFacetId: HYPRUAFClient.facetId())
If you are updating from any version below 6.4.1, then you must update your existing users with this method:
HYPRFidoClientAdapter.createPrivateKeysToCheckIfPasscodeSet(forUser: "User4e442oqsbi99g31u98rprrvbc3", withFacetId: HYPRUAFClient.facetId())
Code Blind
If the passcode was changed prior to upgrading 6.4.1,
HYPRFidoClientAdapter().authenticationSignatureWillSucceedDuringAuth
will not be able to detect that the passcode has changed.
Updated 10 months ago