Abstract

UAF authenticators may be connected to a user device via various physical interfaces (SPI, USB, Bluetooth, etc). The UAF Authenticator-Specific Module (ASM) is a software interface on top of UAF authenticators which gives a standardized way for FIDO UAF Clients to detect and access the functionality of UAF authenticators and hides internal communication complexity from FIDO UAF Client.

This document describes the internal functionality of ASMs, defines the UAF ASM API and explains how FIDO UAF Clients should use the API.

This document's intended audience is FIDO authenticator and FIDO FIDO UAF Client vendors.

Status of This Document

This section describes the status of this document at the time of its publication. Other documents may supersede this document. A list of current FIDO Alliance publications and the latest revision of this technical report can be found in the FIDO Alliance specifications index at https://fidoalliance.org/specifications/.

This document was published by the FIDO Alliance as a Proposed Standard. If you wish to make comments regarding this document, please Contact Us. All comments are welcome.

Implementation of certain elements of this Specification may require licenses under third party intellectual property rights, including without limitation, patent rights. The FIDO Alliance, Inc. and its Members and any other contributors to the Specification are not, and shall not be held, responsible in any manner for identifying or failing to identify any or all such third party intellectual property rights.

THIS FIDO ALLIANCE SPECIFICATION IS PROVIDED “AS IS” AND WITHOUT ANY WARRANTY OF ANY KIND, INCLUDING, WITHOUT LIMITATION, ANY EXPRESS OR IMPLIED WARRANTY OF NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.

This document has been reviewed by FIDO Aliance Members and is endorsed as a Proposed Standard. It is a stable document and may be used as reference material or cited from another document. FIDO Alliance's role in making the Recommendation is to draw attention to the specification and to promote its widespread deployment.

Table of Contents

1. Notation

Type names, attribute names and element names are written as code.

String literals are enclosed in “”, e.g. “UAF-TLV”.

In formulas we use “|” to denote byte wise concatenation operations.

DOM APIs are described using the ECMAScript [ECMA-262] bindings for WebIDL [WebIDL-ED].

The notation base64url refers to "Base 64 Encoding with URL and Filename Safe Alphabet" [RFC4648] without padding.

Following [WebIDL-ED], dictionary members are optional unless they are explicitly marked as required.

WebIDL dictionary members MUST NOT have a value of null.

Unless otherwise specified, if a WebIDL dictionary member is DOMString, it MUST NOT be empty.

Unless otherwise specified, if a WebIDL dictionary member is a List, it MUST NOT be an empty list.

UAF specific terminology used in this document is defined in [FIDOGlossary].

All diagrams, examples, notes in this specification are non-normative.

Note

Note: Certain dictionary members need to be present in order to comply with FIDO requirements. Such members are marked in the WebIDL definitions found in this document, as required. The keyword required has been introduced by [WebIDL-ED], which is a work-in-progress. If you are using a WebIDL parser which implements [WebIDL], then you may remove the keyword required from your WebIDL and use other means to ensure those fields are present.

1.1 Key Words

The key words “MUST”, “MUST NOT”, “REQUIRED”, “SHALL”, “SHALL NOT”, “SHOULD”, “SHOULD NOT”, “RECOMMENDED”, “MAY”, and “OPTIONAL” in this document are to be interpreted as described in [RFC2119].

2. Overview

This section is non-normative.

UAF authenticators may be connected to a user device via various physical interfaces (SPI, USB, Bluetooth, etc.). The UAF Authenticator-Specific module (ASM) is a software interface on top of UAF authenticators which gives a standardized way for FIDO UAF Clients to detect and access the functionality of UAF authenticators, and hides internal communication complexity from clients.

The ASM is a platform-specific software component offering an API to FIDO UAF Clients, enabling them to discover and communicate with one or more available authenticators.

A single ASM may report on behalf of multiple authenticators.

The intended audience for this document is FIDO UAF authenticator and FIDO UAF Client vendors.

Note

Platform vendors might choose to not expose the ASM API defined in this document to applications. They might instead choose to expose ASM functionality through some other API (such as, for example, the Android KeyStore API, or iOS KeyChain API). In these cases it's important to make sure that the underlying ASM communicates with the FIDO UAF authenticator in a manner defined in this document.

The FIDO UAF protocol and its various operations is described in the FIDO UAF Protocol Specification [UAFProtocol]. The following simplified architecture diagram illustrates the interactions and actors this document is concerned with:

UAF ASM API Architecture
Fig. 1 UAF ASM API Architecture

2.1 Code Example format

ASM requests and responses are presented in WebIDL format.

3. ASM Requests and Responses

This section is normative.

The ASM API is defined in terms of JSON-formatted [ECMA-404] request and reply messages. In order to send a request to an ASM, a FIDO UAF Client creates an appropriate object (e.g., in ECMAscript), "stringifies" it (also known as serialization) into a JSON-formated string, and sends it to the ASM. The ASM de-serializes the JSON-formatted string, processes the request, constructs a response, stringifies it, returning it as a JSON-formatted string.

Note

The ASM request processing rules in this document explicitly assume that the underlying authenticator implements the "UAFV1TLV" assertion scheme (e.g. references to TLVs and tags) as described in [UAFProtocol]. If an authenticator supports a different assertion scheme then the corresponding processing rules must be replaced with appropriate assertion scheme-specific rules.

Authenticator implementers MAY create custom authenticator command interfaces other than the one defined in [UAFAuthnrCommands]. Such implementations are not required to implement the exact message-specific processing steps described in this section. However,

  1. the command interfaces MUST present the ASM with external behavior equivalent to that described below in order for the ASM to properly respond to the client request messages (e.g. returning appropriate UAF status codes for specific conditions).
  2. all authenticator implementations MUST support an assertion scheme as defined [UAFRegistry] and MUST return the related objects, i.e. TAG_UAFV1_REG_ASSERTION and TAG_UAFV1_AUTH_ASSERTION as defined in [UAFAuthnrCommands].

3.1 Request enum

enum Request {
    "GetInfo",
    "Register",
    "Authenticate",
    "Deregister",
    "GetRegistrations",
    "OpenSettings"
};
Enumeration description
GetInfoGetInfo
RegisterRegister
AuthenticateAuthenticate
DeregisterDeregister
GetRegistrationsGetRegistrations
OpenSettingsOpenSettings

3.2 StatusCode Interface

If the ASM needs to return an error received from the authenticator, it SHALL map the status code received from the authenticator to the appropriate ASM status code as specified here.

If the ASM doesn't understand the authenticator's status code, it SHALL treat it as UAF_CMD_STATUS_ERR_UNKNOWN and map it to UAF_ASM_STATUS_ERROR if it cannot be handled otherwise.

If the caller of the ASM interface (i.e. the FIDO Client) doesn't understand a status code returned by the ASM, it SHALL treat it as UAF_ASM_STATUS_ERROR. This might occur when new error codes are introduced.

interface StatusCode {
    const short UAF_ASM_STATUS_OK = 0x00;
    const short UAF_ASM_STATUS_ERROR = 0x01;
    const short UAF_ASM_STATUS_ACCESS_DENIED = 0x02;
    const short UAF_ASM_STATUS_USER_CANCELLED = 0x03;
    const short UAF_ASM_STATUS_CANNOT_RENDER_TRANSACTION_CONTENT = 0x04;
    const short UAF_ASM_STATUS_KEY_DISAPPEARED_PERMANENTLY = 0x09;
    const short UAF_ASM_STATUS_AUTHENTICATOR_DISCONNECTED = 0x0b;
    const short UAF_ASM_STATUS_USER_NOT_RESPONSIVE = 0x0e;
    const short UAF_ASM_STATUS_INSUFFICIENT_AUTHENTICATOR_RESOURCES = 0x0f;
    const short UAF_ASM_STATUS_USER_LOCKOUT = 0x10;
    const short UAF_ASM_STATUS_USER_NOT_ENROLLED = 0x11;
    const short UAF_ASM_STATUS_SYSTEM_INTERRUPTED = 0x12;
};

3.2.1 Constants

UAF_ASM_STATUS_OK of type short
No error condition encountered.
UAF_ASM_STATUS_ERROR of type short
An unknown error has been encountered during the processing.
UAF_ASM_STATUS_ACCESS_DENIED of type short
Access to this request is denied.
UAF_ASM_STATUS_USER_CANCELLED of type short
Indicates that user explicitly canceled the request.
UAF_ASM_STATUS_CANNOT_RENDER_TRANSACTION_CONTENT of type short
Transaction content cannot be rendered, e.g. format doesn't fit authenticator's need.
UAF_ASM_STATUS_KEY_DISAPPEARED_PERMANENTLY of type short
Indicates that the UAuth key disappeared from the authenticator and canot be restored.
UAF_ASM_STATUS_AUTHENTICATOR_DISCONNECTED of type short
Indicates that the authenticator is no longer connected to the ASM.
UAF_ASM_STATUS_USER_NOT_RESPONSIVE of type short
The user took too long to follow an instruction, e.g. didn't swipe the finger within the accepted time.
UAF_ASM_STATUS_INSUFFICIENT_AUTHENTICATOR_RESOURCES of type short
Insufficient resources in the authenticator to perform the requested task.
UAF_ASM_STATUS_USER_LOCKOUT of type short
The operation failed because the user is locked out and the authenticator cannot automatically trigger an action to change that. Typically the user would have to enter an alternative password (formally: undergo some other alternative user verification method) to re-enable the use of the main user verification method.
Note

Any method the user can use to (re-) enable the main user verification method is considered an alternative user verification method and must be properly declared as such. For example, if the user can enter an alternative password to re-enable the use of fingerprints or to add additional fingers, the authenticator obviously supports fingerprint or password based user verification.

UAF_ASM_STATUS_USER_NOT_ENROLLED of type short
The operation failed because the user is not enrolled to the authenticator and the authenticator cannot automatically trigger user enrollment.
UAF_ASM_STATUS_SYSTEM_INTERRUPTED of type short
Indicates that the system interrupted the operation. Retry might make sense.

3.2.2 Mapping Authenticator Status Codes to ASM Status Codes

Authenticators are returning a status code in their responses to the ASM. The ASM needs to act on those responses and also map the status code returned by the authenticator to an ASM status code.

The mapping of authenticator status codes to ASM status codes is specified here:

Authenticator Status Code ASM Status Code Comment
UAF_CMD_STATUS_OK UAF_ASM_STATUS_OK Pass-through success status.
UAF_CMD_STATUS_ERR_UNKNOWN UAF_ASM_STATUS_ERROR Pass-through unspecific error status.
UAF_CMD_STATUS_ACCESS_DENIED UAF_ASM_STATUS_ACCESS_DENIED Pass-through status code.
UAF_CMD_STATUS_USER
_NOT_ENROLLED
UAF_ASM_STATUS_USER
_NOT_ENROLLED (or UAF_ASM_STATUS_ACCESS_DENIED in some situations)
According to [UAFAuthnrCommands], this might occur at the Sign command or at the Register command if the authenticator cannot automatically trigger user enrollment. The mapping depends on the command as follows.

In the case of "Register" command, the error is mapped to UAF_ASM_STATUS_USER_NOT_ENROLLED in order to tell the calling FIDO Client the there is an authenticator present but the user enrollment needs to be triggered outside the authenticator.

In the case of the "Sign" command, the Uauth key needs to be protected by one of the authenticator's user verification methods at all times. So if this error occurs it is considered an internal error and hence mapped to UAF_ASM_STATUS_ACCESS_DENIED.

UAF_CMD_STATUS_CANNOT_RENDER
_TRANSACTION_CONTENT
UAF_ASM_STATUS_CANNOT_RENDER
_TRANSACTION_CONTENT
Pass-through status code as it indicates a problem to be resolved by the entity providing the transaction text.
UAF_CMD_STATUS_USER_CANCELLED UAF_ASM_STATUS_USER_CANCELLED Map to UAF_ASM_STATUS_USER_CANCELLED.
UAF_CMD_STATUS_CMD
_NOT_SUPPORTED
UAF_ASM_STATUS_OK or UAF_ASM_STATUS_ERROR If the ASM is able to handle that command on behalf of the authenticator (e.g. removing the key handle in the case of Dereg command for a bound authenticator), the UAF_ASM_STATUS_OK must be returned. Map the status code to UAF_ASM_STATUS_ERROR otherwise.
UAF_CMD_STATUS_ATTESTATION
_NOT_SUPPORTED
UAF_ASM_STATUS_ERROR Indicates an ASM issue as the ASM has obviously not requested one of the supported attestation types indicated in the authenticator's response to the GetInfo command.
UAF_CMD_STATUS_PARAMS_INVALID UAF_ASM_STATUS_ERROR Indicates an ASM issue as the ASM has obviously not provided the correct parameters to the authenticator when sending the command.
UAF_CMD_STATUS_KEY_
DISAPPEARED_PERMANENTLY
UAF_ASM_STATUS_KEY_
DISAPPEARED_PERMANENTLY
Pass-through status code. It indicates that the Uauth key disappeared permanently and the RP App might want to trigger re-registration of the authenticator.
UAF_STATUS_CMD_TIMEOUT UAF_ASM_STATUS_ERROR Retry operation and map to UAF_ASM_STATUS_ERROR if the problem persists.
UAF_CMD_STATUS_USER
_NOT_RESPONSIVE
UAF_ASM_STATUS_USER
_NOT_RESPONSIVE
Pass-through status code. The RP App might want to retry the operation once the user pays attention to the application again.
UAF_CMD_STATUS_
INSUFFICIENT_RESOURCES
UAF_ASM_STATUS_INSUFFICIENT
_AUTHENTICATOR_RESOURCES
Pass-through status code.
UAF_CMD_STATUS_USER_LOCKOUT UAF_ASM_STATUS_USER_LOCKOUT Pass-through status code.
Any other status code UAF_ASM_STATUS_ERROR Map any unknown error code to UAF_ASM_STATUS_ERROR. This might happen when an ASM communicates with an authenticator implementing a newer UAF specification than the ASM.

3.3 ASMRequest Dictionary

All ASM requests are represented as ASMRequest objects.

dictionary ASMRequest {
    required Request requestType;
    Version          asmVersion;
    unsigned short   authenticatorIndex;
    object           args;
    Extension[]      exts;
};

3.3.1 Dictionary ASMRequest Members

requestType of type required Request
Request type
asmVersion of type Version
ASM message version to be used with this request. For the definition of the Version dictionary see [UAFProtocol]. The asmVersion MUST be 1.2 (i.e. major version is 1 and minor version is 2) for this version of the specification.
authenticatorIndex of type unsigned short
Refer to the GetInfo request for more details. Field authenticatorIndex MUST NOT be set for GetInfo request.
args of type object
Request-specific arguments. If set, this attribute MAY take one of the following types:
  • RegisterIn
  • AuthenticateIn
  • DeregisterIn
exts of type array of Extension
List of UAF extensions. For the definition of the Extension dictionary see [UAFProtocol].

3.4 ASMResponse Dictionary

All ASM responses are represented as ASMResponse objects.

dictionary ASMResponse {
    required short statusCode;
    object         responseData;
    Extension[]    exts;
};

3.4.1 Dictionary ASMResponse Members

statusCode of type required short
MUST contain one of the values defined in the StatusCode interface
responseData of type object
Request-specific response data. This attribute MUST have one of the following types:
  • GetInfoOut
  • RegisterOut
  • AuthenticateOut
  • GetRegistrationOut
exts of type array of Extension
List of UAF extensions. For the definition of the Extension dictionary see [UAFProtocol].

3.5 GetInfo Request

Return information about available authenticators.

  1. Enumerate all of the authenticators this ASM supports
  2. Collect information about all of them
  3. Assign indices to them (authenticatorIndex)
  4. Return the information to the caller
Note

Where possible, an authenticatorIndex should be a persistent identifier that uniquely identifies an authenticator over time, even if it is repeatedly disconnected and reconnected. This avoids possible confusion if the set of available authenticators changes between a GetInfo request and subsequent ASM requests, and allows a FIDO client to perform caching of information about removable authenticators for a better user experience.

Note

It is up to the ASM to decide whether authenticators which are disconnected temporarily will be reported or not. However, if disconnected authenticators are reported, the FIDO Client might trigger an operation via the ASM on those. The ASM will have to notify the user to connect the authenticator and report an appropriate error if the authenticator isn't connected in time.

For a GetInfo request, the following ASMRequest member(s) MUST have the following value(s). The remaining ASMRequest members SHOULD be omitted:

For a GetInfo response, the following ASMResponse member(s) MUST have the following value(s). The remaining ASMResponse members SHOULD be omitted:

See section 3.2.2 Mapping Authenticator Status Codes to ASM Status Codes for details on the mapping of authenticator status codes to ASM status codes.

3.5.1 GetInfoOut Dictionary

dictionary GetInfoOut {
    required AuthenticatorInfo[] Authenticators;
};
3.5.1.1 Dictionary GetInfoOut Members
Authenticators of type array of required AuthenticatorInfo
List of authenticators reported by the current ASM. MAY be empty an empty list.

3.5.2 AuthenticatorInfo Dictionary

dictionary AuthenticatorInfo {
    required unsigned short               authenticatorIndex;
    required Version[]                    asmVersions;
    required boolean                      isUserEnrolled;
    required boolean                      hasSettings;
    required AAID                         aaid;
    required DOMString                    assertionScheme;
    required unsigned short               authenticationAlgorithm;
    required unsigned short[]             attestationTypes;
    required unsigned long                userVerification;
    required unsigned short               keyProtection;
    required unsigned short               matcherProtection;
    required unsigned long                attachmentHint;
    required boolean                      isSecondFactorOnly;
    required boolean                      isRoamingAuthenticator;
    required DOMString[]                  supportedExtensionIDs;
    required unsigned short               tcDisplay;
    DOMString                             tcDisplayContentType;
    DisplayPNGCharacteristicsDescriptor[] tcDisplayPNGCharacteristics;
    DOMString                             title;
    DOMString                             description;
    DOMString                             icon;
};
3.5.2.1 Dictionary AuthenticatorInfo Members
authenticatorIndex of type required unsigned short
Authenticator index. Unique, within the scope of all authenticators reported by the ASM, index referring to an authenticator. This index is used by the UAF Client to refer to the appropriate authenticator in further requests.
asmVersions of type array of required Version
A list of ASM Versions that this authenticator can be used with. For the definition of the Version dictionary see [UAFProtocol].
isUserEnrolled of type required boolean
Indicates whether a user is enrolled with this authenticator. Authenticators which don't have user verification technology MUST always return true. Bound authenticators which support different profiles per operating system (OS) user MUST report enrollment status for the current OS user.
hasSettings of type required boolean
A boolean value indicating whether the authenticator has its own settings. If so, then a FIDO UAF Client can launch these settings by sending a OpenSettings request.
aaid of type required AAID
The "Authenticator Attestation ID" (AAID), which identifies the type and batch of the authenticator. See [UAFProtocol] for the definition of the AAID structure.
assertionScheme of type required DOMString
The assertion scheme the authenticator uses for attested data and signatures.

AssertionScheme identifiers are defined in the UAF Protocol specification [UAFProtocol].

authenticationAlgorithm of type required unsigned short
Indicates the authentication algorithm that the authenticator uses. Authentication algorithm identifiers are defined in are defined in [FIDORegistry] with ALG_ prefix.
attestationTypes of type array of required unsigned short
Indicates attestation types supported by the authenticator. Attestation type TAGs are defined in [UAFRegistry] with TAG_ATTESTATION prefix
userVerification of type required unsigned long
A set of bit flags indicating the user verification method(s) supported by the authenticator. The algorithm for combining the flags is defined in [UAFProtocol], section 3.1.12.1. The values are defined by the USER_VERIFY constants in [FIDORegistry].
keyProtection of type required unsigned short
A set of bit flags indicating the key protections used by the authenticator. The values are defined by the KEY_PROTECTION constants in [FIDORegistry].
matcherProtection of type required unsigned short
A set of bit flags indicating the matcher protections used by the authenticator. The values are defined by the MATCHER_PROTECTION constants in [FIDORegistry].
attachmentHint of type required unsigned long
A set of bit flags indicating how the authenticator is currently connected to the system hosting the FIDO UAF Client software. The values are defined by the ATTACHMENT_HINT constants defined in [FIDORegistry].
Note

Because the connection state and topology of an authenticator may be transient, these values are only hints that can be used by server-supplied policy to guide the user experience, e.g. to prefer a device that is connected and ready for authenticating or confirming a low-value transaction, rather than one that is more secure but requires more user effort. These values are not reflected in authenticator metadata and cannot be relied on by the relying party, although some models of authenticator may provide attested measurements with similar semantics as part of UAF protocol messages.

isSecondFactorOnly of type required boolean
Indicates whether the authenticator can be used only as a second factor.
isRoamingAuthenticator of type required boolean
Indicates whether this is a roaming authenticator or not.
supportedExtensionIDs of type array of required DOMString
List of supported UAF extension IDs. MAY be an empty list.
tcDisplay of type required unsigned short
A set of bit flags indicating the availability and type of the authenticator's transaction confirmation display. The values are defined by the TRANSACTION_CONFIRMATION_DISPLAY constants in [FIDORegistry].

This value MUST be 0 if transaction confirmation is not supported by the authenticator.

tcDisplayContentType of type DOMString
Supported transaction content type [FIDOMetadataStatement].

This value MUST be present if transaction confirmation is supported, i.e. tcDisplay is non-zero.

tcDisplayPNGCharacteristics of type array of DisplayPNGCharacteristicsDescriptor
Supported transaction Portable Network Graphic (PNG) type [FIDOMetadataStatement]. For the definition of the DisplayPNGCharacteristicsDescriptor structure see [FIDOMetadataStatement].

This list MUST be present if PNG-image based transaction confirmation is supported, i.e. tcDisplay is non-zero and tcDisplayContentType is image/png.

title of type DOMString
A human-readable short title for the authenticator. It should be localized for the current locale.
Note

If the ASM doesn't return a title, the FIDO UAF Client must provide a title to the calling App. See section "Authenticator interface" in [UAFAppAPIAndTransport].

description of type DOMString
Human-readable longer description of what the authenticator represents.
Note

This text should be localized for current locale.

The text is intended to be displayed to the user. It might deviate from the description specified in the metadata statement for the authenticator [FIDOMetadataStatement].

If the ASM doesn't return a description, the FIDO UAF Client will provide a description to the calling application. See section "Authenticator interface" in [UAFAppAPIAndTransport].

icon of type DOMString
Portable Network Graphic (PNG) format image file representing the icon encoded as a data: url [RFC2397].
Note

If the ASM doesn't return an icon, the FIDO UAF Client will provide a default icon to the calling application. See section "Authenticator interface" in [UAFAppAPIAndTransport].

3.6 Register Request

Verify the user and return an authenticator-generated UAF registration assertion.

For a Register request, the following ASMRequest member(s) MUST have the following value(s). The remaining ASMRequest members SHOULD be omitted:

For a Register response, the following ASMResponse member(s) MUST have the following value(s). The remaining ASMResponse members SHOULD be omitted:

3.6.1 RegisterIn Object

dictionary RegisterIn {
    required DOMString      appID;
    required DOMString      username;
    required DOMString      finalChallenge;
    required unsigned short attestationType;
};
3.6.1.1 Dictionary RegisterIn Members
appID of type required DOMString
The FIDO server Application Identity.
username of type required DOMString
Human-readable user account name
finalChallenge of type required DOMString
base64url-encoded challenge data [RFC4648]
attestationType of type required unsigned short
Single requested attestation type

3.6.2 RegisterOut Object

dictionary RegisterOut {
    required DOMString assertion;
    required DOMString assertionScheme;
};
3.6.2.1 Dictionary RegisterOut Members
assertion of type required DOMString
FIDO UAF authenticator registration assertion, base64url-encoded
assertionScheme of type required DOMString
Assertion scheme.

AssertionScheme identifiers are defined in the UAF Protocol specification [UAFProtocol].

3.6.3 Detailed Description for Processing the Register Request

Refer to [UAFAuthnrCommands] document for more information about the TAGs and structure mentioned in this paragraph.

  1. Locate authenticator using authenticatorIndex. If the authenticator cannot be located, then fail with UAF_ASM_STATUS_AUTHENTICATOR_DISCONNECTED.
  2. If a user is already enrolled with this authenticator (such as biometric enrollment, PIN setup, etc. for example) then the ASM MUST request that the authenticator verifies the user.
    Note

    If the authenticator supports UserVerificationToken (see [UAFAuthnrCommands]), then the ASM must obtain this token in order to later include it with the Register command.

    If the user is locked out (e.g. too many failed attempts to get verified) and the authenticator cannot automatically trigger unblocking, return UAF_ASM_STATUS_USER_LOCKOUT.

    • If verification fails, return UAF_ASM_STATUS_ACCESS_DENIED
  3. If the user is not enrolled with the authenticator then take the user through the enrollment process.
    • If neither the ASM nor the Authenticator can trigger the enrollment process, return UAF_ASM_STATUS_USER_NOT_ENROLLED.
    • If enrollment fails, return UAF_ASM_STATUS_ACCESS_DENIED
  4. Verify whether registerIn.appID and the appID included in the finalChallenge parameter are identical. The registerIn.finalChallenge value needs to be (1) base64url decoded and (2) parsed into a JSON object first.
    • If verification fails, return UAF_ASM_STATUS_ACCESS_DENIED
  5. Construct KHAccessToken (see section KHAccessToken for more details)
  6. Hash the provided RegisterIn.finalChallenge using the authenticator-specific hash function (FinalChallengeHash)

    An authenticator's preferred hash function information MUST meet the algorithm defined in the AuthenticatorInfo.authenticationAlgorithm field.

  7. Create a TAG_UAFV1_REGISTER_CMD structure and pass it to the authenticator
    1. Copy FinalChallengeHash, KHAccessToken, RegisterIn.Username, UserVerificationToken, RegisterIn.AppID, RegisterIn.AttestationType
      1. Depending on AuthenticatorType some arguments may be optional. Refer to [UAFAuthnrCommands] for more information on authenticator types and their required arguments.
    2. Add the extensions from the ASMRequest.exts dictionary appropriately to the TAG_UAFV1_REGISTER_CMD as TAG_EXTENSION object.
  8. Invoke the command and receive the response. If the authenticator returns an error, handle that error appropriately. If the connection to the authenticator gets lost and cannot be restored, return UAF_ASM_STATUS_AUTHENTICATOR_DISCONNECTED. If the operation finally fails, map the authenticator error code to the the appropriate ASM error code (see section 3.2.2 Mapping Authenticator Status Codes to ASM Status Codes for details).
  9. Parse TAG_UAFV1_REGISTER_CMD_RESP
    1. Parse the content of TAG_AUTHENTICATOR_ASSERTION (e.g. TAG_UAFV1_REG_ASSERTION) and extract TAG_KEYID
  10. If the authenticator is a bound authenticator
    1. Store CallerID, AppID, TAG_KEYHANDLE, TAG_KEYID and CurrentTimestamp in the ASM's database.
      Note

      What data an ASM will store at this stage depends on underlying authenticator's architecture. For example some authenticators might store AppID, KeyHandle, KeyID inside their own secure storage. In this case ASM doesn't have to store these data in its database.

  11. Create a RegisterOut object
    1. Set RegisterOut.assertionScheme according to AuthenticatorInfo.assertionScheme
    2. Encode the content of TAG_AUTHENTICATOR_ASSERTION (e.g. TAG_UAFV1_REG_ASSERTION) in base64url format and set as RegisterOut.assertion.
    3. Return RegisterOut object

3.7 Authenticate Request

Verify the user and return authenticator-generated UAF authentication assertion.

For an Authenticate request, the following ASMRequest member(s) MUST have the following value(s). The remaining ASMRequest members SHOULD be omitted:

For an Authenticate response, the following ASMResponse member(s) MUST have the following value(s). The remaining ASMResponse members SHOULD be omitted:

3.7.1 AuthenticateIn Object

dictionary AuthenticateIn {
    required DOMString appID;
    DOMString[]        keyIDs;
    required DOMString finalChallenge;
    Transaction[]      transaction;
};
3.7.1.1 Dictionary AuthenticateIn Members
appID of type required DOMString
appID string
keyIDs of type array of DOMString
base64url [RFC4648] encoded keyIDs
finalChallenge of type required DOMString
base64url [RFC4648] encoded final challenge
transaction of type array of Transaction
An array of transaction data to be confirmed by user. If multiple transactions are provided, then the ASM MUST select the one that best matches the current display characteristics.
Note

This may, for example, depend on whether user's device is positioned horizontally or vertically at the moment of transaction.

3.7.2 Transaction Object

dictionary Transaction {
    required DOMString                  contentType;
    required DOMString                  content;
    DisplayPNGCharacteristicsDescriptor tcDisplayPNGCharacteristics;
};
3.7.2.1 Dictionary Transaction Members
contentType of type required DOMString
Contains the MIME Content-Type supported by the authenticator according to its metadata statement (see [FIDOMetadataStatement])
content of type required DOMString
Contains the base64url-encoded [RFC4648] transaction content according to the contentType to be shown to the user.
tcDisplayPNGCharacteristics of type DisplayPNGCharacteristicsDescriptor
Transaction content PNG characteristics. For the definition of the DisplayPNGCharacteristicsDescriptor structure See [FIDOMetadataStatement].

3.7.3 AuthenticateOut Object

dictionary AuthenticateOut {
    required DOMString assertion;
    required DOMString assertionScheme;
};
3.7.3.1 Dictionary AuthenticateOut Members
assertion of type required DOMString
Authenticator UAF authentication assertion.
assertionScheme of type required DOMString
Assertion scheme

3.7.4 Detailed Description for Processing the Authenticate Request

Refer to the [UAFAuthnrCommands] document for more information about the TAGs and structure mentioned in this paragraph.

  1. Locate the authenticator using authenticatorIndex. If the authenticator cannot be located, then fail with UAF_ASM_STATUS_AUTHENTICATOR_DISCONNECTED.
  2. If no user is enrolled with this authenticator (such as biometric enrollment, PIN setup, etc.), return UAF_ASM_STATUS_ACCESS_DENIED
  3. The ASM MUST request the authenticator to verify the user.
    • If the user is locked out (e.g. too many failed attempts to get verified) and the authenticator cannot automatically trigger unblocking, return UAF_ASM_STATUS_USER_LOCKOUT.
    • If verification fails, return UAF_ASM_STATUS_ACCESS_DENIED
    • Note

      If the authenticator supports UserVerificationToken (see [UAFAuthnrCommands]), the ASM must obtain this token in order to later pass to Sign command.

  4. Construct KHAccessToken (see section KHAccessToken for more details)
  5. Hash the provided AuthenticateIn.finalChallenge using an authenticator-specific hash function (FinalChallengeHash).

    The authenticator's preferred hash function information MUST meet the algorithm defined in the AuthenticatorInfo.authenticationAlgorithm field.

  6. If this is a Second Factor authenticator and AuthenticateIn.keyIDs is empty, then return UAF_ASM_STATUS_ACCESS_DENIED
  7. If AuthenticateIn.keyIDs is not empty,
    1. If this is a bound authenticator, then look up ASM's database with AuthenticateIn.appID and AuthenticateIn.keyIDs and obtain the KeyHandles associated with it.
      • Return UAF_ASM_STATUS_KEY_DISAPPEARED_PERMANENTLY if the related key disappeared permanently from the authenticator.
      • Return UAF_ASM_STATUS_ACCESS_DENIED if no entry has been found.
    2. If this is a roaming authenticator, then treat AuthenticateIn.keyIDs as KeyHandles
  8. Create TAG_UAFV1_SIGN_CMD structure and pass it to the authenticator.
    1. Copy AuthenticateIn.AppID, AuthenticateIn.Transaction.content (if not empty), FinalChallengeHash, KHAccessToken, UserVerificationToken, KeyHandles
      • Depending on AuthenticatorType some arguments may be optional. Refer to [UAFAuthnrCommands] for more information on authenticator types and their required arguments.
      • If multiple transactions are provided, select the one that best matches the current display characteristics.
        Note

        This may, for example, depend on whether user's device is positioned horizontally or vertically at the moment of transaction.

      • Decode the base64url encoded AuthenticateIn.Transaction.content before passing it to the authenticator
    2. Add the extensions from the ASMRequest.exts dictionary appropriately to the TAG_UAFV1_REGISTER_CMD as TAG_EXTENSION object.
  9. Invoke the command and receive the response. If the authenticator returns an error, handle that error appropriately. If the connection to the authenticator gets lost and cannot be restored, return UAF_ASM_STATUS_AUTHENTICATOR_DISCONNECTED. If the operation finally fails, map the authenticator error code to the appropriate ASM error code (see section 3.2.2 Mapping Authenticator Status Codes to ASM Status Codes for details).
  10. Parse TAG_UAFV1_SIGN_CMD_RESP
    • If it's a first-factor authenticator and the response includes TAG_USERNAME_AND_KEYHANDLE, then
      1. Extract usernames from TAG_USERNAME_AND_KEYHANDLE fields
      2. If two or more equal usernames are found, then choose the one which has registered most recently
        Note

        After this step, a first-factor bound authenticator which stores KeyHandles inside the ASM's database may delete the redundant KeyHandles from the ASM's database. This avoids having unusable (old) private key in the authenticator which (surprisingly) might become active after deregistering the newly generated one.

      3. Show remaining distinct usernames and ask the user to choose a single username
      4. Set TAG_UAFV1_SIGN_CMD.KeyHandles to the single KeyHandle associated with the selected username.
      5. Go to step #8 and send a new TAG_UAFV1_SIGN_CMD command
  11. Create the AuthenticateOut object
    1. Set AuthenticateOut.assertionScheme as AuthenticatorInfo.assertionScheme
    2. Encode the content of TAG_AUTHENTICATOR_ASSERTION (e.g. TAG_UAFV1_AUTH_ASSERTION) in base64url format and set as AuthenticateOut.assertion
    3. Return the AuthenticateOut object
Note

Some authenticators might support "Transaction Confirmation Display" functionality not inside the authenticator but within the boundaries of the ASM. Typically these are software based Transaction Confirmation Displays. When processing the Sign command with a given transaction such ASM should show transaction content in its own UI and after user confirms it -- pass the content to authenticator so that the authenticator includes it in the final assertion.

See [FIDORegistry] for flags describing Transaction Confirmation Display type.

The authenticator metadata statement MUST truly indicate the type of transaction confirmation display implementation. Typically the "Transaction Confirmation Display" flag will be set to TRANSACTION_CONFIRMATION_DISPLAY_ANY (bitwise) or TRANSACTION_CONFIRMATION_DISPLAY_PRIVILEGED_SOFTWARE.

3.8 Deregister Request

Delete registered UAF record from the authenticator.

For a Deregister request, the following ASMRequest member(s) MUST have the following value(s). The remaining ASMRequest members SHOULD be omitted:

For a Deregister response, the following ASMResponse member(s) MUST have the following value(s). The remaining ASMResponse members SHOULD be omitted:

3.8.1 DeregisterIn Object

dictionary DeregisterIn {
    required DOMString appID;
    required DOMString keyID;
};
3.8.1.1 Dictionary DeregisterIn Members
appID of type required DOMString
FIDO Server Application Identity
keyID of type required DOMString
Base64url-encoded [RFC4648] key identifier of the authenticator to be de-registered. The keyID can be an empty string. In this case all keyIDs related to this appID MUST be deregistered.

3.8.2 Detailed Description for Processing the Deregister Request

Refer to [UAFAuthnrCommands] for more information about the TAGs and structures mentioned in this paragraph.

  1. Locate the authenticator using authenticatorIndex
  2. Construct KHAccessToken (see section KHAccessToken for more details).
  3. If this is a bound authenticator, then
    • If the value of DeregisterIn.keyID is an empty string, then lookup all pairs of this appID and any keyID mapped to this authenticatorIndex and delete them. Go to step 4.
    • Otherwise, lookup the authenticator related data in the ASM database and delete the record associated with DeregisterIn.appID and DeregisterIn.keyID. Go to step 4.
  4. Create the TAG_UAFV1_DEREGISTER_CMD structure, copy KHAccessToken and DeregisterIn.keyID and pass it to the authenticator.
    Note

    In the case of roaming authenticators, the keyID passed to the authenticator might be an empty string. The authenticator is supposed to deregister all keys related to this appID in this case.

  5. Invoke the command and receive the response. If the authenticator returns an error, handle that error appropriately. If the connection to the authenticator gets lost and cannot be restored, return UAF_ASM_STATUS_AUTHENTICATOR_DISCONNECTED. If the operation finally fails, map the authenticator error code to the appropriate ASM error code (see section 3.2.2 Mapping Authenticator Status Codes to ASM Status Codes for details). Return proper ASMResponse.

3.9 GetRegistrations Request

Return all registrations made for the calling FIDO UAF Client.

For a GetRegistrations request, the following ASMRequest member(s) MUST have the following value(s). The remaining ASMRequest members SHOULD be omitted:

For a GetRegistrations response, the following ASMResponse member(s) MUST have the following value(s). The remaining ASMResponse members SHOULD be omitted:

3.9.1 GetRegistrationsOut Object

dictionary GetRegistrationsOut {
    required AppRegistration[] appRegs;
};
3.9.1.1 Dictionary GetRegistrationsOut Members
appRegs of type array of required AppRegistration
List of registrations associated with an appID (see AppRegistration below). MAY be an empty list.

3.9.2 AppRegistration Object

dictionary AppRegistration {
    required DOMString   appID;
    required DOMString[] keyIDs;
};
3.9.2.1 Dictionary AppRegistration Members
appID of type required DOMString
FIDO Server Application Identity.
keyIDs of type array of required DOMString
List of key identifiers associated with the appID

3.9.3 Detailed Description for Processing the GetRegistrations Request

  1. Locate the authenticator using authenticatorIndex
  2. If this is bound authenticator, then
    • Lookup the registrations associated with CallerID and AppID in the ASM database and construct a list of AppRegistration objects
    • Note

      Some ASMs might not store this information inside their own database. Instead it might have been stored inside the authenticator's secure storage area. In this case the ASM must send a proprietary command to obtain the necessary data.

  3. If this is not a bound authenticator, then set the list to empty.
  4. Create GetRegistrationsOut object and return

3.10 OpenSettings Request

Display the authenticator-specific settings interface. If the authenticator has its own built-in user interface, then the ASM MUST invoke TAG_UAFV1_OPEN_SETTINGS_CMD to display it.

For an OpenSettings request, the following ASMRequest member(s) MUST have the following value(s). The remaining ASMRequest members SHOULD be omitted:

For an OpenSettings response, the following ASMResponse member(s) MUST have the following value(s). The remaining ASMResponse members SHOULD be omitted:

4. Using ASM API

This section is non-normative.

In a typical implementation, the FIDO UAF Client will call GetInfo during initialization and obtain information about the authenticators. Once the information is obtained it will typically be used during FIDO UAF message processing to find a match for given FIDO UAF policy. Once a match is found the FIDO UAF Client will send the appropriate request (Register/Authenticate/Deregister...) to this ASM.

The FIDO UAF Client may use the information obtained from a GetInfo response to display relevant information about an authenticator to the user.

5. ASM APIs for various platforms

This section is normative.

5.1 Android ASM Intent API

On Android systems FIDO UAF ASMs MAY be implemented as a separate APK-packaged application.

The FIDO UAF Client invokes ASM operations via Android Intents. All interactions between the FIDO UAF Client and an ASM on Android takes place through the following intent identifier:

org.fidoalliance.intent.FIDO_OPERATION

To carry messages described in this document, an intent MUST also have its type attribute set to application/fido.uaf_asm+json.

ASMs MUST register that intent in their manifest file and implement a handler for it.

FIDO UAF Clients MUST append an extra, message, containing a String representation of a ASMRequest, before invoking the intent.

FIDO UAF Clients MUST invoke ASMs by calling startActivityForResult()

FIDO UAF Clients SHOULD assume that ASMs will display an interface to the user in order to handle this intent, e.g. prompting the user to complete the verification ceremony. However, the ASM SHOULD NOT display any user interface when processing a GetInfo request.

After processing is complete the ASM will return the response intent as an argument to onActivityResult(). The response intent will have an extra, message, containing a String representation of a ASMResponse.

5.1.1 Discovering ASMs

FIDO UAF Clients can discover the ASMs available on the system by using PackageManager.queryIntentActivities(Intent intent, int flags) with the FIDO Intent described above to see if any activities are available.

A typical FIDO UAF Client will enumerate all ASM applications using this function and will invoke the GetInfo operation for each one discovered.

5.1.2 Alternate Android AIDL Service ASM Implementation

The Android Intent API can also be implemented using Android AIDL services as an alternative transport mechanism to Android Intents. Please see Android Intent API section [UAFAppAPIAndTransport] for differences between the Android AIDL service and Android Intent implementation.

This API should be used if the ASM itself doesn't implement any user interface.
Note

The advantage of this AIDL Server based API is that it doesn't cause a focus lose on the caller App.

5.2 Java ASM API for Android

Note

The Java ASM API is useful for ASMs for KeyStore based authenticators. In this case the platform limits key use-access to the application generating the key. The ASM runs in the process scope of the RP App.

public interface IASM {
  enum Event {
    PLUGGED,  /** Indicates that the authenticator was Plugged to system */
    UNPLUGGED /** Indicates that the authenticator was Unplugged from system */
  }

  public interface IEnumeratorListener {
    /**
        This function is called when an authenticator is plugged or
	unplugged.
       @param eventType event type (plugged/unplugged)
       @param serialized AuthenticatorInfo JSON based GetInfoResponse object
    */
    void onNotify(Event eventType, String authenticatorInfo);
  }

  public interface IResponseReceiver {
    /**
	This function is called when ASM's response is ready.
	    
       @param response serialized response JSON based event data
       @param exchangeData for ASM if it needs some
              data back right after calling the callback function.
              onResponse will set the exchangeData to the data to 
              be returned to the ASM.
    */
    void onResponse(String response, StringBuilder exchangeData);
  }

  /**
      Initializes the ASM. This is the first function to
      be called.	
     @param ctx the Android Application context of the calling application (or null)
     @param enumeratorListener caller provided Enumerator
     @return ASM StatusCode value
  */
  short init(Context ctx, IEnumeratorListener enumeratorListener);

  /**
      Process given JSON request and returns JSON response.
      If the caller wants to execute a function defined in ASM JSON
      schema then this is the function that must be called.
     @param act the calling Android Activity or null
     @param inData input JSON data
     @param ProcessListener event listener for receiving events from ASM
     @return ASM StatusCode value
  */
  short process(Activity act, String inData, IResponseReceiver responseReceiver);

  /**
      Uninitializes (shut's down) the ASM.
     @return ASM StatusCode value
  */
  short uninit();	
}

5.3 C++ ASM API for iOS

Note

The C++ ASM API is useful for ASMs for KeyChain based authenticators. In this case the platform limits key use-access to the application generating the key. The ASM runs in the process scope of the RP App.

#include 
namespace FIDO_UAF {

class IASM {
 public:

  typedef enum  {
    PLUGGED,  /** Indicates that the authenticator was Plugged to system */
    UNPLUGGED /** Indicates that the authenticator was Unplugged from system */
  } Event;


  class IEnumeratorListener {
    virtual ~IEnumeratorListener() {}
    /**
        This function is called when an authenticator is plugged or
	unplugged.
       @param eventType event type (plugged/unplugged)
       @param serialized AuthenticatorInfo JSON based GetInfoResponse object
    */
    virtual void onNotify(Event eventType, const std::string& authenticatorInfo) {};
  };

  class IResponseReceiver {
    virtual ~IResponseReceiver() {}
    /**
	This function is called when ASM's response is ready.
	    
       @param response serialized JSON based event data
       @param exchangeData for ASM if it needs some
              data back right after calling the callback function.
    */
    virtual void onResponse(const std::string& response, std::string &exchangeData) {};
  };

  /**
      Initializes the ASM. This is the first function to
      be called.	
     @param unc the platform UINavigationController or one of the derived classes 
       (e.g. UINavigationController) in order to allow smooth UI integration of the ASM.
     @param EnumerationListener caller provided Enumerator
     @return ASM StatusCode value
  */
  virtual short int init(UINavigationController unc, IEnumerator EnumerationListener)=0;

  /**
      Process given JSON request and returns JSON response.
      If the caller wants to execute a function defined in ASM JSON
      schema then this is the function that must be called.
     @param unc the platform UINavigationController or one of the derived classes 
       (e.g. UINavigationController) in order to allow smooth UI integration of the ASM
     @param InData input JSON data
     @param ProcessListener event listener for receiving events from ASM
     @return ASM StatusCode value
  */
  virtual short int process(UINavigationController unc, const std::string& InData, ICallback ProcessListener)=0;

  /**
      Uninitializes (shut's down) the ASM.
     @return ASM StatusCode value
  */
  virtual short int uninit()=0;	
};

}

5.4 Windows ASM API

On Windows, an ASM is implemented in the form of a Dynamic Link Library (DLL). The following is an example asmplugin.h header file defining a Windows ASM API:

Example 1
/*! @file asm.h
*/

#ifndef __ASMH_
#define __ASMH_
#ifdef _WIN32
#define ASM_API __declspec(dllexport)
#endif

#ifdef _WIN32
#pragma warning ( disable : 4251 )
#endif

#define ASM_FUNC extern "C" ASM_API
#define ASM_NULL 0

/*! \brief Error codes returned by ASM Plugin API.
*  Authenticator specific error codes are returned in JSON form.
*  See JSON schemas for more details.
*/

enum asmResult_t
{
  Success = 0, /**< Success */
  Failure /**< Generic failure */
};

/*! \brief Generic structure containing JSON string in UTF-8
*  format.
*  This structure is used throughout functions to pass and receives
*  JSON data.
*/

struct asmJSONData_t
{
  int length; /**< JSON data length */
  char *pData; /**< JSON data */
};

/*! \brief Enumeration event types for authenticators.
These events will be fired when an authenticator becomes
  available (plugged) or unavailable (unplugged).
*/

enum asmEnumerationType_t
{
  Plugged = 0, /**< Indicates that authenticator Plugged to system */
  Unplugged /**< Indicates that authenticator Unplugged from system */
};

namespace ASM
{
  /*! \brief Callback listener.
  FIDO UAF Client must pass an object implementating this interface to
  Authenticator::Process function. This interface is used to provide
  ASM JSON based response data.*/
  class ICallback
  {
    public
      virtual ~ICallback() {}
      /**
      This function is called when ASM's response is ready.
      *
      @param response JSON based event data
      @param exchangeData must be provided by ASM if it needs some
      data back right after calling the callback function.
      The lifecycle of this parameter must be managed by ASM. ASM must
      allocate enough memory for getting the data back.
      */

      virtual void Callback(const asmJSONData_t &response,
      asmJSONData_t &exchangeData) = 0;
  };

  /*! \brief Authenticator Enumerator.
  FIDO UAF Client must provide an object implementing this
  interface. It will be invoked when a new authenticator is plugged or
  when an authenticator has been unplugged. */

  class IEnumerator
  {
    public
      virtual ~IEnumerator() {}
      /**
        This function is called when an authenticator is plugged or
	    unplugged.
      * @param eventType event type (plugged/unplugged)
        @param AuthenticatorInfo JSON based GetInfoResponse object
      */

      virtual void Notify(const asmEnumerationType_t eventType, const
      asmJSONData_t &AuthenticatorInfo) = 0;
  };
}

/**
Initializes ASM plugin. This is the first function to be
	    called.
*
@param pEnumerationListener caller provided Enumerator
*/

ASM_FUNC asmResult_t asmInit(ASM::IEnumerator
	  *pEnumerationListener);
/**
Process given JSON request and returns JSON response.
*
If the caller wants to execute a function defined in ASM JSON
	    schema then this is the function that must be called.
*
@param pInData input JSON data
@param pListener event listener for receiving events from ASM
*/
ASM_FUNC asmResult_t asmProcess(const asmJSONData_t *pInData,
	  ASM::ICallback *pListener);
/**
Uninitializes ASM plugin.
*
*/
ASM_FUNC asmResult_t asmUninit();
#endif // __ASMPLUGINH_

A Windows-based FIDO UAF Client MUST look for ASM DLLs in the following registry paths:

HKCU\Software\FIDO\UAF\ASM

HKLM\Software\FIDO\UAF\ASM

The FIDO UAF Client iterates over all keys under this path and looks for "path" field:

[HK**\Software\FIDO\UAF\ASM\<exampleASMName>]

"path"="<ABSOLUTE_PATH_TO_ASM>.dll"

path MUST point to the absolute location of the ASM DLL.

6. CTAP2 Interface

This section is normative.

ASMs can (optionally) provide a FIDO CTAP 2 interface in order to allow the authenticator being used as external authenticator from a FIDO2 or Web Authentication enabled platform supporting the CTAP 2 protocol [FIDOCTAP].

In this case the CTAP2 enabled ASM provides the CTAP2 interface upstream through one or more of the transport protocols defined in [FIDOCTAP] (e.g. USB, NFC, BLE). Note that the CTAP2 interface is the connection to the FIDO Client / FIDO enabled platform.

In the following section we specify how the ASM needs to map the parameters received via the FIDO CTAP2 interface to FIDO UAF Authenticator Commands [UAFAuthnrCommands].

6.1 authenticatorMakeCredential

This section is normative.

Note

This interface has the following input parameters (see [FIDOCTAP]):

  1. clientDataHash (required, byte array).
  2. rp (required, PublicKeyCredentialEntity). Identity of the relying party.
  3. user (required, PublicKeyCredentialUserEntity).
  4. pubKeyCredParams (required, CBOR array).
  5. excludeList (optional, sequence of PublicKeyCredentialDescriptors).
  6. extensions (optional, CBOR map). Parameters to influence authenticator operation.
  7. options (optional, sequence of authenticator options, i.e. "rk" and "uv"). Parameters to influence authenticator operation.
  8. pinAuth (optional, byte array).
  9. pinProtocol (optional, unsigned integer).

The output parameters are (see [FIDOCTAP]):

  1. authData (required, sequence of bytes). The authenticator data object.
  2. fmt (required, String). The attestation statement format identifier.
  3. attStmt (required, sequence of bytes). The attestation statement.

6.1.1 Processing rules for authenticatorMakeCredential

This section is normative.

  1. invoke Register command for UAF authenticator as described in [UAFAuthnrCommands] section 6.2.4 using the following field mapping instructions:
    • authenticatorIndex set appropriately, e.g. 1.
    • If webauthn_appid is present, then
      1. Verify that the effective domain of AppID is identical to the effective domain of rp.id.
      2. Set AppID to the value of extension webauthn_appid (see [WebAuthn]).
    • If webauthn_appid is not present, then set AppID to rp.id (see [WebAuthn]).
    • FinalChallengeHash set to clientDataHash.
    • Username set to user.displayName (see [WebAuthn]). This string will be displayed to the user in order to select a specific account if the user has multiple accounts at that relying party.
    • attestationType set to the attestation supported by that authenticator, e.g. ATTESTATION_BASIC_FULL or ATTESTATION_ECDAA.
    • KHAccessToken set to some persistent identifier used for this authenticator. If the authenticator is bound to the platform this ASM is running on, it needs to be a secret identifier only known to this ASM instance. If the authenticator is a "roaming authenticator", i.e. external to the platform this ASM is running on, the identifier can have value 0.
    • Add the fido.uaf.userid extension with value user.id to the Register command.
    • Use the pinAuth and pinProtocol parameters appropriately when communicating with the authenticator (if supported).
  2. If this is a bound authenticator and the Authenticator doesn't support the fido.uaf.userid, let the ASM remember the user.id value related to the generated UAuth key pair.
  3. If the command was successful, create the result object as follows
    • set authData to a freshly generated authenticator data object, containing the corresponding values taken from the assertion geenrated by the authenticator. That means:
      • set authData.rpID to the SHA256 hash of AppID.
      • initialize authData with 0 and then set set flag authData.AT to 1 and set authData.UP to 1 if the authenticator is not a silent authenticator. Set flag authData.uv to 1 if the authenticator is not a silent authenticator. The flags authData.UP and authData.UV need to be 0 if it is a silent authenticator. Set authData.ED to 1 if the authenticator added extensions to the assertion. In this case add the individual extensions to the CBOR map appropriately.
      • set authData.signCount to the uafAssertion.signCounter.
      • set authData.attestationData.AAGUID to the AAID of this authenticator. Setting the remaining bytes to 0.
      • set authData.attestationData.CredentialID to uafAssertion.keyHandle and set the length L of the Credential ID to the size of the keyHandle.
      • set authData.attestationData.pubKey to uafAssertion.publicKey with appropriate encoding conversion
    • set fmt to the "fido-uaf".
    • set attStmt to the AUTHENTICATOR_ASSERTION element of the TAG_UAFV1_REGISTER_CMD_RESPONSE returned by the authenticator.
  4. Return authData, fmt and attStmt.

6.2 authenticatorGetAssertion

This section is normative.

Note

This interface has the following input parameters (see [FIDOCTAP]):

  1. rpId (required, String). Identity of the relying party.
  2. clientDataHash (required, byte array).
  3. allowList (optional, sequence of PublicKeyCredentialDescriptors).
  4. extensions (optional, CBOR map).
  5. options (optional, sequence of authenticator options, i.e. "up" and "uv").

The output parameters are (see [FIDOCTAP]):

  1. credential (optional, PublicKeyCredentialDescriptor).
  2. authData (required, byte array).
  3. signature (required, byte array).
  4. user (required, PublicKeyCredentialUserEntity).
  5. numberOfCredentials (optional, integer).

6.2.1 Processing rules for authenticatorGetAssertion

This section is normative.

  1. invoke Sign command for UAF authenticator as described in [UAFAuthnrCommands] section 6.3.4 using the following field mapping instructions
    • authenticatorIndex set appropriately, e.g. 1.
    • If webauthn_appid is present, then
      1. Verify that the effective domain of AppID is identical to the effective domain of rpId.
      2. Set AppID to the value of extension webauthn_appid (see [WebAuthn]).
    • If webauthn_appid is not present, then set AppID to rpId (see [WebAuthn]).
    • FinalChallengeHash set to clientDataHash.
    • TransactionContent set to value of extension webauthn_txAuthGeneric or webauthn_txAuthsimple (see [WebAuthn]) depending on which extension is present and supported by this authenticator. If the authenticator doesn't natively support transactionConfirmation, the hash of the value included in either of the webauthn_tx* extensions can be computed by the ASM and passed to the authenticator in TransactionContentHash. See [UAFAuthnrCommands] section 6.3.1 for details.
    • KHAccessToken set to the persistent identifier used for this authenticator (at authenticatorMakeCredential).
    • If allowList is present then add the .id field of each element as KeyHandle element to the command.
    • Use the pinAuth and pinProtocol parameters appropriately when communicating with the authenticator (if supported).
  2. If the command was successful (with potential ambiguities of RawKeyHandles resolved), create the result object as follows
    • set credential.id to the keyHandle returned by the authenticator command. Set credential.type to "public-key-uaf" and set credential.transports to the transport currently being used by this authenticator (e.g. "usb").
    • set authData to the UAFV1_SIGNED_DATA element included in the AUTHENTICATOR_ASSERTION element.
    • set signature to the SIGNATURE element included in the AUTHENTICATOR_ASSERTION element.
    • If the authenticator returned the fido.uaf.userid extension, then set user.id to the value of the fido.uaf.userid extension as returned by the authenticator.
    • If the authenticator did not return the fido.uaf.userid extension but the ASM remembered the user ID, then set user.id to the value of the user ID remembered by the ASM.
  3. Return credential, authData, signature, user.

6.3 authenticatorGetNextAssertion

This section is normative.

Not supported. This interface will always return a single assertion.

6.4 authenticatorCancel

This section is normative.

Cancel the existing authenticator command if it is still pending.

6.5 authenticatorReset

This section is normative.

Reset the authenticator back to factory default state. In order to prevent accidental trigger of this mechanism, some form of user approval MAY be performed by the authenticator itself.

6.6 authenticatorGetInfo

This section is normative.

This interface has no input parameters.

Note

Output parameters are (see [FIDOCTAP]):

  1. versions (required, sequence of strings). List of FIDO protocol versions supported by the authenticator.
  2. extensions (optional, sequence of strings). List of extensions supported by the authenticator.
  3. aaguid (optional, string). The AAGUID claimed by the authenticator.
  4. options (optional, map). Map of "plat", "rk", "clientPin", "up", "uv"
  5. maxMsgSize (optional, unsignd integer). The maximum message size accepted by the authenticator.
  6. pinProtocols (optional, array of unsigned integers).

6.6.1 Processing rules for authenticatorGetInfo

This section is normative.

This interface is expected to report a single authenticator only.
  1. Invoke the GetInfo command [UAFAuthnrCommands] for the connected authenticator.
    • authenticatorIndex set appropriately, e.g. 1.
  2. If the command was successful, create the result object as follows
    • set versions to "FIDO_2_0" as this is the only version supported by CTAP2 at this time.
    • set extensions to the list of extensions returned by the authenticator (one entry per field SupportedExtensionID).
    • set aaguid to the AAID returned by the authenticator, setting all remaining bytes to 0.
    • set options appropriately.
    • set maxMsgSize to the maximum message size supported by the authenticator - if known
    • set pinProtocols to the list of supported pin protocols (if any).
  3. Return versions, extensions, aaguid, options, mxMsgSize (if known) and pinProtocols (if any).

7. Security and Privacy Guidelines

This section is normative.

ASM developers must carefully protect the FIDO UAF data they are working with. ASMs must follow these security guidelines:

7.1 KHAccessToken

KHAccessToken is an access control mechanism for protecting an authenticator's FIDO UAF credentials from unauthorized use. It is created by the ASM by mixing various sources of information together. Typically, a KHAccessToken contains the following four data items in it: AppID, PersonaID, ASMToken and CallerID.

AppID is provided by the FIDO Server and is contained in every FIDO UAF message.

PersonaID is obtained by the ASM from the operational environment. Typically a different PersonaID is assigned to every operating system user account.

ASMToken is a randomly generated secret which is maintained and protected by the ASM.

Note

In a typical implementation an ASM will randomly generate an ASMToken when it is launched the first time and will maintain this secret until the ASM is uninstalled.

CallerID is the ID the platform has assigned to the calling FIDO UAF Client (e.g. "bundle ID" for iOS). On different platforms the CallerID can be obtained differently.

Note

For example on Android platform ASM can use the hash of the caller's apk-signing-cert.

The ASM uses the KHAccessToken to establish a link between the ASM and the key handle that is created by authenticator on behalf of this ASM.

The ASM provides the KHAccessToken to the authenticator with every command which works with key handles.

Note

The following example describes how the ASM constructs and uses KHAccessToken.

  • During a Register request
    • Set KHAccessToken to a secret value only known to the ASM. This value will always be the same for this ASM.
    • Append AppID
      • KHAccessToken = AppID
    • If a bound authenticator, append ASMToken, PersonaID and CallerID
      • KHAccessToken |= ASMToken | PersonaID | CallerID
    • Hash KHAccessToken
      • Hash KHAccessToken using the authenticator's hashing algorithm. The reason of using authenticator specific hash function is to make sure of interoperability between ASMs. If interoperability is not required, an ASM can use any other secure hash function it wants.
      • KHAccessToken=hash(KHAccessToken)
    • Provide KHAccessToken to the authenticator
    • The authenticator puts the KHAccessToken into RawKeyHandle (see [UAFAuthnrCommands] for more details)
  • During other commands which require KHAccessToken as input argument
    • The ASM computes KHAccessToken the same way as during the Register request and provides it to the authenticator along with other arguments.
    • The authenticator unwraps the provided key handle(s) and proceeds with the command only if RawKeyHandle.KHAccessToken is equal to the provided KHAccessToken.

Bound authenticators MUST support a mechanism for binding generated key handles to ASMs. The binding mechanism MUST have at least the same security characteristics as mechanism for protcting KHAccessToken described above. As a consequence it is RECOMMENDED to securely derive KHAccessToken from AppID, ASMToken, PersonaID and the CallerID.

Alternative methods for binding key handles to ASMs can be used if their security level is equal or better.

From a security perspective, the KHAccessToken method relies on the OS/platform to:
  1. allow the ASM keeping the ASMToken secret
  2. and let the ASM determine the CalledID correctly
  3. and let the FIDO Client verify the AppID/FacetID correctly
Note

It is recommended for roaming authenticators that the KHAccessToken contains only the AppID since otherwise users won't be able to use them on different machines (PersonaID, ASMToken and CallerID are platform specific). If the authenticator vendor decides to do that in order to address a specific use case, however, it is allowed.

Including PersonaID in the KHAccessToken is optional for all types of authenticators. However an authenticator designed for multi-user systems will likely have to support it.

If an ASM for roaming authenticators doesn't use a KHAccessToken which is different for each AppID, the ASM MUST include the AppID in the command for a deregister request containing an empty KeyID.

7.2 Access Control for ASM APIs

The following table summarizes the access control requirements for each API call.

ASMs MUST implement the access control requirements defined below. ASM vendors MAY implement additional security mechanisms.

Terms used in the table:

Commands First-factor bound authenticator Second-factor bound authenticator First-factor roaming authenticator Second-factor roaming authenticator
GetInfo NoAuth NoAuth NoAuth NoAuth
OpenSettings NoAuth NoAuth NoAuth NoAuth
Register UserVerify UserVerify UserVerify UserVerify
Authenticate UserVerify
AppID
CallerID
PersonaID
UserVerify
AppID
KeyIDList
CallerID
PersonaID
UserVerify
AppID
UserVerify
AppiD
KeyIDList
GetRegistrations* CallerID
PersonaID
CallerID
PersonaID
X X
Deregister AppID
KeyID
PersonaID
CallerID
AppID
KeyID
PersonaID
CallerID
AppID
KeyID
AppID
KeyID

A. References

A.1 Normative references

[ECMA-262]
ECMAScript Language Specification. URL: https://tc39.es/ecma262/
[FIDOCTAP]
C. Brand; A. Czeskis; J. Ehrensvärd; M. Jones; A. Kumar; R. Lindemann; A. Powers; J. Verrept. FIDO 2.0: Client To Authenticator Protocol. 30 January 2019. URL: https://fidoalliance.org/specs/fido-v2.0-ps-20190130/fido-client-to-authenticator-protocol-v2.0-ps-20190130.html
[FIDOGlossary]
R. Lindemann; D. Baghdasaryan; B. Hill; J. Hodges. FIDO Technical Glossary. Review Draft. URL: https://fidoalliance.org/specs/fido-v2.0-id-20180227/fido-glossary-v2.0-id-20180227.html
[FIDOMetadataStatement]
B. Hill; D. Baghdasaryan; J. Kemp. FIDO Metadata Statements. Review Draft. URL: https://fidoalliance.org/specs/fido-v2.0-id-20180227/fido-metadata-statement-v2.0-id-20180227.html
[FIDORegistry]
R. Lindemann; D. Baghdasaryan; B. Hill. FIDO Registry of Predefined Values. Proposed Standard. URL: https://fidoalliance.org/specs/common-specs/fido-registry-v2.1-ps-20191217.html
[RFC2119]
S. Bradner. Key words for use in RFCs to Indicate Requirement Levels. March 1997. Best Current Practice. URL: https://tools.ietf.org/html/rfc2119
[RFC4648]
S. Josefsson. The Base16, Base32, and Base64 Data Encodings (RFC 4648). October 2006. URL: http://www.ietf.org/rfc/rfc4648.txt
[UAFAuthnrCommands]
D. Baghdasaryan; J. Kemp; R. Lindemann; R. Sasson; B. Hill; J. Hodges; K. Yang. FIDO UAF Authenticator Commands. Review Draft. URL: https://fidoalliance.org/specs/fido-uaf-v1.2-ps-20201020/fido-uaf-authnr-cmds-v1.2-ps-20201020.html
[UAFProtocol]
R. Lindemann; D. Baghdasaryan; E. Tiffany; D. Balfanz; B. Hill; J. Hodges; K. Yang. FIDO UAF Protocol Specification v1.2. Review Draft. URL: https://fidoalliance.org/specs/fido-uaf-v1.2-ps-20201020/fido-uaf-protocol-v1.2-ps-20201020.html
[UAFRegistry]
R. Lindemann; D. Baghdasaryan; B. Hill. FIDO UAF Registry of Predefined Values. Review Draft. URL: https://fidoalliance.org/specs/fido-v2.0-id-20180227/fido-registry-v2.0-id-20180227.html
[WebIDL-ED]
Cameron McCormack. Web IDL. 13 November 2014. Editor's Draft. URL: http://heycam.github.io/webidl/

A.2 Informative references

[ECMA-404]
The JSON Data Interchange Format. 1 October 2013. Standard. URL: https://www.ecma-international.org/publications/files/ECMA-ST/ECMA-404.pdf
[FIDOSecRef]
R. Lindemann; D. Baghdasaryan; B. Hill; J. Hill; D. Biggs. FIDO Security Reference. 27 February 2018. Implementation Draft. URL: https://fidoalliance.org/specs/fido-v2.0-id-20180227/fido-security-ref-v2.0-id-20180227.html
[RFC2397]
L. Masinter. The "data" URL scheme. August 1998. Proposed Standard. URL: https://tools.ietf.org/html/rfc2397
[UAFAppAPIAndTransport]
B. Hill; D. Baghdasaryan; B. Blanke. FIDO UAF Application API and Transport Binding Specification. Review Draft. URL: https://fidoalliance.org/specs/fido-uaf-v1.2-ps-20201020/fido-uaf-client-api-transport-v1.2-ps-20201020.html
[WebAuthn]
Dirk Balfanz; Alexei Czeskis; Jeff Hodges; J.C. Jones; Michael B. Jones; Akshay Kumar; Angelo Liao; Rolf Lindemann; Emil Lundberg. Web Authentication: An API for accessing Public Key Credentials Level 1. March 2019. TR. URL: https://www.w3.org/TR/webauthn/
[WebIDL]
Boris Zbarsky. Web IDL. 15 December 2016. W3C Editor's Draft. URL: https://heycam.github.io/webidl/