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

Customizing the Sample ASM

Prev Next

The easiest way to create your own ASM entails:

  • Modifying the Sample ASM included with the Authenticator SDK

  • Integrating a custom user verification method into the Sample ASM

  • (Advanced) Integrating a custom FIDO Crypto Module to perform cryptographic operations in custom security hardware, such as a Trusted Execution Environment

This section covers the following individual steps of building an ASM by customizing the Sample ASM:

Refer to the sample project asm_sample_service that defines the Sample ASM service.

Modify the Manifest

In the manifest, you need to define entry points to handle incoming requests. Refer to the sample manifest file and look for an activity that references com.noknok.android.client.asm.core.uaf.AsmActivity and look for a service entry point that references com.noknok.android.client.asm.core.uaf.AsmService. These implement the UAF v1.0 and UAF v1.1 entry points respectively. By default, the Sample ASM provides no user interface and performs no user verification process; you will modify com.MyASM.MyActivity in Sample ASM to handle your UI interaction.

The sample manifest file is located at:

<ASM_SDK_HOME>/android-studio/asm_sample_service/app/src/main/AndroidManifest.xml

Implement the Matcher

The IMatcher implementation handles all user interaction for performing user verification. IMatcher is designed to be protocol independent. For this reason, it defines a synchronous interface, which is always called from a background thread. This allows it to support multiple environments; for example, IMatcher may be used in a service.

ASM developers can use semaphores, wait/notify, or other suitable synchronization mechanisms to block the activity call before returning responses back to the caller.

The ASM SDK supports a UVT-based IMatcher implementation.

Using the UVT-based Matcher

Some FIDO Crypto Modules require a User Verification Token to perform FIDO operations. Upon successful verification of the user, the UVT-based IMatcher implementation is responsible for creating a UVT and returning it to the Authenticator Core. Refer to the IAuthenticatorKernel section, the IMatcher javadocs and the MyMatcher sample for more information.

Authenticator Core passes parameters to UVT-based IMatcher implementation via the UVTMatcherInParams class and the matcher returns the user verification result to Authenticator Core via UVTMatcherOutParams.

For a UVT-based IMatcher, the Matcher.getMatcherDefinedParamsClassList method should return the following:

Field in MatcherDefinedParamsClassList

Class type

matcherInParamsClass

UVTMatcherInParams.class

matcherOutParamsClass

UVTMatcherOutParams.class

User ID

Some FIDO Crypto Modules invalidate user keys when all user verification reference data is deleted from the device. For example, if the user erases all fingerprints from the device, then the associated user keys should no longer be usable. To support this, the concept of a User ID is supported. When the FIDO Crypto Module generates a key, it extracts the User ID from the UVT and stores it with the key. Before an authentication is performed, the Crypto Module compares the User ID in the UVT with the User ID stored with the key. If they do not match, the Crypto Module does not perform the authentication. Normally, the matcher should use the same User ID in the UVT. However, when the user erases all verification reference data, the matcher should generate a new User ID to use in subsequent UVTs. This effectively disables all existing user keys.

A User ID is not the same as a username but is a globally unique value generated when a user registers his or her biometric to the device for the first time. The User ID remains the same until the user removes all biometrics from the device. Then, on the next enrollment, a new user ID is generated, and that User ID is used for all subsequent enrollments until all biometrics are removed from the device. The User ID value can be implemented as a counter or as a random value. Digipass S3 recommends using a counter.

isUserIDValid is used for checking the value of User ID, and it should return TRUE only if the User ID passed in is the same as the current User ID. Using an example of a fingerprint sensor, the fingerprint sensor trustlet should manage a User ID from when the first fingerprint is added, continuing until all fingerprints have been removed from the device. isUserIDValid should only return true if the User ID managed by the fingerprint sensor trustlet is the same as the one passed in.

The hazard that User ID and isUserIDValid() are designed to guard against is illustrated in the following sequence:

  1. User 1 enrolls his finger on the device

  2. User 1 performs a FIDO registration on a FIDO-enabled website (e.g. PayPal) using a native FIDO app installed on the device

  3. User 1 decides to sell the device. He removes all his fingerprint enrollments using the Android settings, and also uninstalls the PayPal FIDO app. However, the FIDO keys still remain stored on the device.

  4. User 1 sells the device to User 2

  5. User 2 enrolls her fingers on the device

  6. User 2 installs the PayPal FIDO app on the device

  7. User 2 can now authenticate using her finger to the PayPal account belonging to User 1

When properly implemented, User ID and isUserIDValid() prevent the hazard from occurring; when User 2 attempts to perform a FIDO operation, isUserIDValid is used to detect that the User ID managed by the fingerprint sensor has changed, and therefore the user must have removed all fingerprint enrollments; this triggers the trustlet managing the FIDO keys to delete those keys and prevent their use.

Biometric Matching Models

Most biometric authenticators support multiple biometric reference data sets, e.g., finger enrollments. The same reference data set is typically used for the authenticators and for the device unlock. In practice, the capability of supporting multiple biometric reference data sets is sometimes used to allow multiple people to use the device. Unfortunately, using the device and using the authenticator cannot be distinguished. This is also known as “friendly fraud”. Especially in the case of financial transactions, relying parties typically want a way to prevent friendly fraud.

Within FIDO, an extension called User Verification Index (UVI), is used to allow the UAF server to determine which biometric template (e.g. finger) was matched during registration and authentication. For example, with this information the server can limit high value transactions to the biometric that was used for the original UAF registration. By using UVI, a UAF server can limit authentication to a specific biometric template, sets of biometric templates, or any biometric template enrolled on the device; it also permits the UAF server to dynamically switch between those models of biometric matching when performing authentication.

This section describes the technical requirements for supporting multiple matching models.

Enabling Different Matching Models in Matcher

To enable different matching models, the matcher should prepare proprietary extensions in Tag Length Value (TLV) format defined as follows:

Field

Length (bytes)

Description

Tag

2

AFI_RAW_USER_VERIFICATION_INDEX (0x0103)

Length

2

Length (n <= 32)

Data

n

Raw user verification index

Tag

2

AFI_RAW_USER_VERIFICATION_STATE (0x0105)

Length

2

Length (n <= 32)

Data

n

Raw user verification state

The matcher should include the above extensions in the UVT. The Authenticator Core gets the UVT from the IMatcher implementation and sends it to the FIDO Crypto Module.

Enabling Different Matching Models in FIDO Crypto Module

To enable different matching models, the FIDO Crypto Module receives the UVT containing the UVI and UVS extensions. The raw UVI and UVS are not sent to the server, since it would allow tracking a user across RPs. This would especially be true if the raw UVI and UVS values are random. Instead, the FIDO Crypto Module creates a new TLV as follows:

Field

Length (bytes)

Description

Tag

2

AFI_USER_VERIFICATION_INDEX (0x0104)

Length

2

Length (32)

Data

32

SHA256 (keyID | Raw User Verification Index)

Tag

2

AFI_USER_VERIFICATION_STATE (0x0106)

Length

2

Length (32)

Data

32

SHA256 (keyID | Raw User Verification State)

Since the keyID is specific to one RP, the UVI and UVS are also specific to an RP. The FIDO Crypto Module appends the extensions to the “to be signed” part of the register or sign assertions. The authenticator receives the assertions, sends these via the ASM interface to the UAF Client, which sends it to the Server as a UAF response.

Modify the Descriptor

The descriptor specifies properties of the authenticator. Refer to IAuthenticatorDescriptor in the javadocs and the MyAuthenticatorDescriptor sample for more information.

Setting Up Your AAIDs

Each authenticator has an AAID to globally identify UAF authenticator models. The AAID uniquely identifies a specific authenticator model within the range of all UAF authenticator models made by all authenticator vendors. Each AAID must relate to a distinct Authentication Metadata file.

Vendor and Model Codes

The AAID is a string in the format V#M, where

# is a separator, V indicates the authenticator Vendor Code, and M indicates the authenticator Model Code.

The Vendor Code and Model Code consists of 4 hexadecimal digits each, e.g.

AAID = 4(HEXDIG) "#" 4(HEXDIG)

The Vendor Code is assigned by the FIDO Alliance. See the Conformance Self‐Validation Testing page on the FIDO Alliance website for more details.

The Model Code is chosen by the authenticator vendor and may be an arbitrary value.

Authentication Metadata File

If you are developing your own authenticator, you need to generate metadata describing your authenticator. For more information on what goes into the metadata, see the FIDO Metadata Statement.

Once you generate your custom metadata, you must test it for conformance using the UAF Conformance Tool. For more information contact the FIDO Alliance .

For generating, protecting, and using cryptographic keys, the Sample ASM can use either a FIDO Crypto Module that is a pure software implementation or a hardware-backed implementation. The Sample ASM will automatically choose the FIDO Crypto Module, depending on whether the user’s device supports a hardware-backed Android Keystore. The ASM will surface a different AAID, depending on which FIDO Crypto Module implementation is chosen. Digipass S3 recommends that you only use the hardware-backed FIDO Crypto Module version in a production environment.

An Authenticator can support multiple AAIDs, each AAID represents different security characteristics and at a given time only one AAID is surfaced by the authenticator. The list of supported AAIDs are specified in AuthenticatorDescriptor. For each AAID an instance of AAIDInfo structure is created and AKSelector is responsible to choose an AAIDInfo. AKSelector determines various security parameters of the device and selects an authenticator label and then for the selected label, queries AuthenticatorDescriptor for AAIDInfo data.

By convention, authenticator label should be in the format <vendor>_<type>_<protocol>. Labels currently supported by GenericAKSelector are NNL_KS_UAF (hardware-backed keys) and NNL_SFT_UAF (software backed keys).

Refer to IAuthenticatorDescriptor.AAIDInfo in javadocs for more information.

Setting Up Auto Configuration

The authenticator should be configured in the FIDO Crypto Module, and in some cases the authenticator is preconfigured. The autoconfigure field is set to true if the authenticator has to be configured with the details from AuthenticatorDescriptor, and is set to false if the authenticator is already preconfigured.

Setting Up Your Attestation Type

The NNL Crypto Module currently supports surrogate and full attestation. For surrogate attestation the certificateChain should be set to null. For more details on surrogate basic attestation, see the FIDO UAF Authenticator Commands v1.2 specification.

Create the Descriptor List

A FIDO UAF ASM implements one or more authenticators. You need to create a JSON file, asmdescriptors.json that lists the IAuthenticatorDescriptor implementation class names in the descriptorclass key. When building the ASM, files in raw folders are aggregated across all projects, so the JSON file can go in the raw folder of any included project. Reference res/raw/asmdescriptors.json in the Sample ASM for an example.

Implementing a Custom Transaction Confirmation 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 has the concept of a "secure transaction" to provide this capability. If a FIDO UAF Authenticator has a transaction confirmation display capability, the FIDO UAF architecture ensures that the system supports What You See is What You Sign mode (WYSIWYS).

A default transaction confirmation screen will be shown by the ASM SDK. The IAuthenticatorDescriptor class provides a method, getTransactionUIType, which indicates the type of transaction confirmation screen. If getTransactionUIType returns TransactionUI.Default, the default transaction confirmation screen will be displayed by the ASM SDK. If this flag is None, no transaction display is supported. if set to custom,

the matcher will show its own custom transaction screen.

Using an Alternate FIDO Crypto Module

In UAF, a FIDO Crypto Module implements cryptographic functions for the FIDO Authenticator, e.g., key generation and signing. The Authenticator SDK ships with a default Crypto Module, and typically you’ll use this during development. The Crypto Module will store keys and perform cryptographic operations in the hardware-backed Android Keystore if the device supports it. Otherwise, the keys are stored in software. The Authenticator will surface a different AAID, depending on how keys are stored and generated (see Setting up Your AAIDs). Digipass S3 recommends that Relying Parties only allow authenticators with hardware-backed keys in their production environment.

Implementing AKSelector

You can use an alternate FIDO Crypto Module by specifying the IAKSelector implementation class in the IAuthenticatorDescriptor.getAuthenticatorSelectorClass method. The IAKSelector implementation is responsible for setting up the AAID and creating the corresponding instance of IAuthenticatorKernel implementations. Refer to the javadocs IAuthenticatorKernel and IAKSelector for details.

To create your own FIDO Crypto Module, you will need to implement IAuthenticatorKernel and IAKSelector. See the MyAuthenticatorKernel and MyAKSelector samples for details. Your IAuthenticatorKernel implementation will need to accept commands and generate responses as defined in the FIDO UAF Authenticator Commands v1.2 specification.

Implementing a Custom Crypto Module

It is possible to create a custom Crypto Module, for example, to run inside a Trusted Execution Environment (TEE). By implementing the UAF operations in a Trustlet, sensitive key material can be protected from access by the rich OS.

IAuthenticatorKernel - This class provides an interface to a FIDO Crypto Module and is used by the ASM as the exclusive interface to communicate with such modules.

processRequest - This method is called by the ASM whenever a request is to be sent to the FIDO Crypto Module. It is expected that this method transmits the request to the FIDO Crypto Module (e.g. using some secure transport protocol or API).

getDigestMethod - This method returns a IAKDigestMethod instance that implements the same digest algorithm used in the FIDO Crypto Module.

postProcess - This method is called by ASM Core when the FIDO Crypto Module operation is completed, enabling AuthenticatorKernel to perform a cleanup of state information.

Authenticators should leverage hardware protection to the extent possible. For example, a face recognition based authenticator should maintain the authentication keys in a TPM if available, even though the face recognition algorithm might have to be implemented as software running on the User Device.

Returning Additional Information on Error

Errors are returned in MatcherOutParams. 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 in MatcherOutParams’s m_Exts field. The SDK provides both the error code and this extension to the calling application. The sample code below shows how to create an extension.

resultExtensions = new ArrayList<>();
IMatcher.Extension resultExtension = new IMatcher.Extension();
resultExtension.id = EXTENSION_ID;
resultExtension.data = data.getBytes();
resultExtension.fail_if_unknown = false;
resultExtensions.add(resultExtension);
// Set the list to MatcherOutParams
// e.g. new MatcherOutParams(result, null, resultExtensions);

Configuring Metadata

Relying Parties must have some means of discovering and verifying various characteristics of authenticators. Relying Parties can learn a subset of verifiable information for authenticators certified by the FIDO Alliance with an authenticator metadata statement.

Authenticator metadata statements are used directly by the UAF server at a relying party, but the information contained in the authoritative statement is used in several other places.

This section details the appropriate values for the metadata that the authenticator provides in getInfo.

  • authenticatorType - Whether the authenticator is bound or roaming, and whether it is first or second factor only.

  • maxKeyHandle - Maximum number of key handles this authenticator can receive and process in a single command.

  • userVerification - Represents a single USER_VERIFY constant.

  • keyProtection - Bit fields defined by the KEY_PROTECTION constants

  • matcherProtection - Bit fields defined by the MATCHER_PROTECTION constants.

  • tcDisplay - Bit fields defined by the TRANSACTION_CONFIRMATIOM_DISPLAY constants.

  • authenticationAlg - Authentication algorithm supported by the authenticator.

For the complete authenticator metadata specification, see the FIDO Alliance documentation.

Packaging Your ASM

Ensure that any legal notices included with your application contain the proper attributions to third party source licenses. Refer to the <ASMSDK_HOME>/licenses/ folder for the list of third party source licenses used in the ASM SDK.

Stripping the Logging from Your ASM

To assure that no sensitive information is sent to the Android logging system, all logging statements need to be stripped as part of preparing your ASM for production release. R8 is the recommended tool to do this, and it comes with the Android SDK. R8 uses a configuration file usually called proguard.cfg. You should add the following statements to this file to remove logs:

-assumenosideeffects class android.util.Log {
public static *** d(...);
public static *** v(...);
public static *** w(...);
public static *** e(...);
public static *** i(...);
}

For more information on using R8, see the Android documentation.

Packaging an ASM for Embedding into a Mobile App

It is possible to embed a FIDO UAF ASM directly in an application. The Sample ASM is built as a standalone ASM app. To make it embeddable, you need to convert it into a library project using the following steps.

Converting an ASM into a Library Project

  1. Navigate to <ASM_SDK_HOME>\android-studio\asm_sample_service project in the asmsdk package and click on the build.gradle file.

  1. Android Studio will be opened with the asm_sample_service project files.

  2. In the asm_sample_service gradle file change the apply plugin declaration to apply plugin: 'com.android.library'. In the android section of the gradle file, set the publishNonDefault flag to true.In the buildTypes section, set the minifyEnabled flag to true for the release build type.

  3. Next, modify the asm_sample_service project manifest file and remove everything except for the following:

<manifest
    xmlns:android="http://schemas.android.com/apk/res/android" 
    xmlns:tools="http://schemas.android.com/tools"
    package="com.MyASM"
    android:versionCode="1"
    android:versionName="3.0.1.0">
    <application>
        <activity
             android:name="com.MyASM.MyActivity"
             android:excludeFromRecents="true"
             android:configChanges="orientation|screenSize"
             android:theme="@style/nnlThemeTransparent">
        </activity>
    </application>
</manifest>
  1. In Android Studio, click Build -> Make Module <module_name> to generate a library ready for embedding into an RP application. The generated library can be found in the following location:

    ASMSDK/android-studio/asm_sample_service/asm_sample/build/outputs/aar

  2. Copy the generated New_sample_asm_aar file to the aar folder in the relying party application.

  3. Update the asmdescriptors.json file as noted in section Create the Descriptor List. The descriptor class name for the asm_sample library is shown here:

{
    "descriptorclass":[
        "com.MyASM.MyAuthenticatorDescriptor"
    ]
}

Now that asm_sample_service is a library project, it is ready to be embedded into an RP App. For details on how to embed the authenticator into your own application, refer to the Android Developer Guide.

Updating the Package Names

You can change your authenticator's package names in Android studio. For example, to rename the com.MyASM package, perform the following steps:

  1. In your Project pane, click on the gear icon.

  2. Deselect the Compact Empty Middle Packages option. Your package directory will now be broken up into individual directories.

  3. Individually select each directory you want to rename, then:

    1. Right-click it

    2. Select Refactor

    3. Click on Rename

    4. In the Pop-up dialog, click on Rename Package instead of Rename Directory

    5. Enter the new name and hit Refactor

    6. Wait while Android Studio updates all changes.

      When renaming com in Android Studio, it might give a warning. If this happens, select Rename All

  4. Now open your Gradle Build File build.gradle, usually app or mobile. Update the application Id to your new Package Name and Sync Gradle if it hasn't already been updated automatically.