Digipass S3 is now DigipassONE. This section is currently being updated to reflect our new name.

Using the Authenticator SDK

Prev Next

This section describes the steps needed to create a custom ASM using the Digipass S3 Authenticator SDK. You should refer to the sample project called SampleASM that defines an ASM authenticator.

Importing the Authenticator SDK into Your Project

Add <ASM_SDK_HOME>/Framework/uaf_asm.xcframework into the Linked Frameworks and Libraries section of your project’s properties General tab.

For example, the SampleASM project is shown here with uaf_asm.xcframework added as a linked framework:

Implementing the Matching Algorithm

The matcher handles all user interaction for user verification. The matcher is responsible for returning UVT upon successful verification of the user. The UVTHelper and JsonUIOut classes from the ASM SDK can be used to create and serialize UVT. The resulting JSON string should be passed to the ASM SDK via IMatcherResultHandler::onFinalize() to be used for Register and Sign operations in the Authenticator Kernel.

See the IMatcher doxygen documentation and the NNL::SampleMatcher sample class for more information.

Implementing a Custom Transaction Screen

Imagine a situation in which a Relying Party wants the end-user to confirm a transaction (e.g. financial operation, privileged operation, etc.) so that any tampering of a transaction message during its route to the end device display and back can be detected. The FIDO architecture uses the concept of a "secure transaction" to provide this capability. Basically, if a FIDO UAF Authenticator has a transaction confirmation display capability, the FIDO™ UAF architecture makes sure that the system supports What You See is What You Sign mode (WYSIWYS).

There is a special IAuthenticatorDescriptor::getTransactionUIType method for controlling Transaction Screen. The getTransactionUIType method must return the value from enum class TransactionUI { None, Default, Custom };

If your ASM wants to implement a transaction confirmation screen in the matcher, then return the TransactionUI::Custom from the getTransactionUIType method.

If the transaction confirmation screen is not implemented, then return TransactionUI::Default from the getTransactionUIType function. In this case, the default transaction confirmation screen is used.

If the transaction confirmation screen should not be displayed for your ASM, then return TransactionUI::None.

Descriptor

The descriptor is a configuration file that specifies properties of the authenticator. Refer to the IAuthenticatorDescriptor doxygen docs and the SampleAuthenticatorDescriptor sample for more information.

Descriptor List

An ASM Framework implements one or more authenticators. The application is responsible for adding supported descriptors to the ASM. Refer to didFinishLaunchingWithOptions function in TutorialAppPlus/TutorialAppPlus/AppDelegate.swift file as an example.

Alternate FIDO Crypto Modules

Typically, you’ll use the Authenticator SDK’s built-in Digipass S3 FIDO Crypto Module. You can use an alternate FIDO Crypto Module by specifying the Authenticator Kernel Selector class in the descriptor. The Authenticator Kernel Selector is responsible for creating instances of the Authenticator Kernel. The Authenticator Kernel provides an interface for the FIDO Crypto Module which performs the FIDO crypto operations. The FIDO Crypto Module accepts commands encoded as tag-length-value as defined in the FIDO UAF Authenticator Commands v1.2 specification. Refer to the IAuthenticatorKernel and IAKSelector in the Authenticator SDK API docs for details.

To use your own FIDO Crypto Module, you need to implement the Authenticator Kernel and Authenticator Selector classes.

Returning Additional Information on Error

Errors are returned from Matcher. In some cases, you want to provide additional information to the calling application so it can take the correct action.

You can do this by defining a custom extension and returning it. Then the SDK provides this extension to the calling application. The sample code below shows how to create an extension:

NSMutableDictionary* extension = [[NSMutableDictionary alloc] init];
extension[@"id"] = @"noknok.pin.result";
extension[@"data"] = @"FORGOT_PIN";
extension[@"fail_if_unknown"] = @NO;

PIN Management Library Usage

The PIN management library simplifies PIN-based authenticator development. It encapsulates PIN-specific functionality such as:

  • Storing a PIN

  • Verifying a PIN

  • Deleting a PIN

  • Changing a PIN

  • Anti-hammering support

The Authenticator SDK contains the SampleASM project which includes sample code that demonstrates usage of all PIN functionality.

PIN Manager Class Usage

PinManager is the main entry point class for the PIN management library. To use the library features, you must first instantiate PinManager using the following statement:

let pinManager = PinManager(aaid: self.mAAID, andAntiHammeringCallback: antiHammering)

You can use the PinManager class in your UI implementation. The matcher should open the UI, get the PIN from it, and call the appropriate PinManager methods. After that, close the UI and pass the results of the operation to the matcher.

For more details, see the SampleASM project.

Enrollment

To enroll a new PIN, use the following call:

pinManager.enroll(pinToEnroll)

pinToEnroll is the PIN entered by the user in String format. The method returns a boolean result of true if enrollment completed successfully and false otherwise.

Verification

To verify the PIN, use the following call:

let status:VerifyStatus = pinManager.verify(pinToEnroll, withfalseAttemptLimit: falseAttemptTimesLimit)

pinToVerify is the PIN entered by the user in String format. falseAttemptTimesLimit is the maximum number of allowed false attempts. By default, this value is 10. The method returns a result of type VerifyStatus, which is an enumeration containing the following verification results:

  • SUCCESS - Operation completed successfully

  • FAILED - Operation failed for some reason not related with PIN verification

  • PIN_INVALID - Verification failed, invalid PIN provided

  • PIN_ERASED - PIN data erased due to too many failed attempts

After verification completes, you should analyze the return value and take the appropriate action.

Change PIN

To change the existing PIN, use the following call:

let status:VerifyStatus = pinManager.changePin(oldPin, newPin)

oldPin and newPin are strings. The method verifies the old PIN and, if valid, replaces it with the new PIN. It returns a result of type VerifyStatus as described above.

Remove PIN

To permanently remove the previously enrolled PIN, use the following call:

pinManager.removePin()

This method has no parameters and is void. It just removes all PIN-related data from the database.

Is Enrolled

To check if there are any PIN enrollments, use the following call:

pinManager.isEnrolled()

This method returns boolean true if there are any enrollments and false otherwise.

Get PIN Configuration

To get the supported PIN configuration parameters, use the following call:

let pinConfig: PinCfg = pinManager.getPinConfig()

This method returns the PinConfig object which contains the PIN creation rules and constraints that are encapsulated in the minLength, maxLength, maxRepeatDigits, maxSequentialDigits, confirmationButton, and nonReusableOldPINs parameters. In addition, PinConfig contains 3 parameters for anti-hammering configuration: maxFalseAttempts, probationPeriod, and lockoutPeriod.

Alternatively, you can configure these values by adding the following to the mfac_cfg.json file:

"pinConfig":{
    "minLength": 4,
    "maxLength": 4,
    "maxRepeatDigits": 0,
    "maxSequentialDigits": 0,
    "confirmationButton": true,
    "maxFalseAttempts": 10,
    "probationPeriod": 0,
    "lockoutPeriod": 0,
    "nonReusableOldPINs": 0
}

The above example shows the default values.

Get Current PIN Length

To get the actual length of an already enrolled PIN, use the following call:

int pinLength = pinManager.getPinLength()

This method returns the length of the enrolled PIN or 0 if there is no enrollment.

Handling Anti-Hammering

For handling anti-hammering functionality, use the antiHammeringCallback object. Note that there is no need to instantiate this object. For anti-hammering functionality to work properly, pass the antiHammeringCallback object received in matcherInParams to the PinManager constructor. The same object can be used to get the current failed attempts count.

In the current PIN Management Library implementation, a user is allowed a maximum of 10 attempts to enter a correct PIN. After 10 failures, PIN data is automatically erased and the PIN_ERASED PIN verification status is returned.

No action is required to increase or reset the failed attempts count. These actions are automatically performed on each verify or changePin call, depending on the PIN verification result. If there is a requirement to show different warning messages on different failed attempt counts, the current count could be taken using the following call:

int failedCount = antiHammeringCallback.getFailedCount();

Each time PIN verification fails, you could retrieve this count and display an appropriate message depending on the returned count.

Importing the PIN Management Library into Your ASM

Add the libPinManagement.xcframework static library from the Frameworks folder into the Linked Frameworks and Libraries section of the application properties General tab.

Add the Frameworks folder path into the Header Search Paths and Framework Search Paths sections of the application properties Build Settings tab.

Support for Swift Language

The Authenticator UI can be created in Swift. This is supported by the following Objective C interfaces on top of the ASM SDK APIs:

  • IMatcher

  • IMatcherResultHandler

  • IAntiHammeringCallback

  • PinManager

The matcher should be written in Swift and implement the MatcherDelegate protocol so that it can be used by the ASM SDK. For more details and examples, see the SwiftSampleASM target in the SampleASM project.