The English version of this specification is the only normative version. Non-normative translations may also be available.
Copyright © 2013-2014 FIDO Alliance All Rights Reserved.
The U2F Javascript API consists of two calls - one to register a U2F token with a relying party (i.e., cause the U2F token to generate a new key pair, and to introduce the new public key to the relying party), and one to sign an identity assertion (i.e., exercise a previously-registered key pair).
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://www.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.
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].
U2F specific terminology used in this document is defined in [FIDOGlossary].
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].
Below we explain some of the terms used in this document:
Term | Definition |
---|---|
websafe-base64 encoding |
This is the "Base 64 Encoding with URL and Filename Safe Alphabet" from Section 5 in [RFC4648] without padding. |
stringified javascript object |
This is the JSON object (i.e., a string starting with "{" and ending with "}") whose keys are the property names of the javascript object, and whose values are the corresponding property values. Only "data objects" can be stringified, i.e., only objects whose property names and values are supported in JSON. |
Note: Reading the 'FIDO U2F Overview' (see [U2FOverview] in bibliography) is recommended as a background for this document.
A Relying Party (RP) consumes identity assertions from U2F tokens. The RP's web pages communicate with the U2F tokens on the client through a Javascript API. The RP also needs to perform some verification steps on the server side (see below). How the data obtained by the RP's Javascript is transferred to the RP's server is out of scope of this document. We instead describe the Javascript API used by the RP.
The U2F API MAY be exposed to web pages on two levels. On the required lower level, RPs interact with the FIDO client through a MessagePort [WEBMESSAGING] object. The low-level MessagePort API defines the message formats for messages sent and received on the port, for the two operations supported by the API. This specification does not describe how such a port is made available to RP web pages, as this is (for now) implementation and browser dependent.
For convenience, the FIDO client MAY also expose a high-level Javascript API built on top of the MessagePort API. This API consists of functions corresponding to the different requests that can be made to the FIDO client. These functions respond to the RP asynchronously by invoking a callback.
Why two API levels? The messaging API requires only that pages obtain a MessagePort instance to the FIDO client, i.e. no code needs to be injected to JavaScript context of the RP's pages. This allows RPs to keep full control over the JS running in their pages. The JS API is offered as a convenient abstraction of the messaging API, and is useful for RP developers to quickly integrate U2F into their websites.
RP web pages communicate with the FIDO client over an instance of the HTML5 MessagePort interface. Client implementations may choose how this instance is made available to web pages.
Messages sent to the FIDO client SHOULD be Request
dictionaries:
dictionary Request {
DOMString type;
SignRequest
[] signRequests;
RegisterRequest
[]? registerRequests;
int? timeoutSeconds;
optional int? requestId;
};
Request
Memberstype
of type DOMStringsignRequests
of type array of SignRequest
SignRequest
dictionaries, one for each
token already registered with this RP.registerRequests
of type array of RegisterRequest
, nullableRegisterRequest
dictionaries, one for each
protocol version that the RP is willing to register.timeoutSeconds
of type int, nullablerequestId
of type optional int, nullable
SignRequest
and RegisterRequest
are defined
below. If timeoutSeconds
is omitted, timeout behavior is
unspecified. If requestId
is present, the FIDO client MUST
include its value the corresponding Response
dictionary
under the same key.
Responses from the FIDO client to the RP webpage SHOULD be
Response
dictionaries:
dictionary Response {
DOMString type;
(Error
or RegisterResponse
or SignResponse
) responseData;
int? requestId;
};
Response
Memberstype
of type DOMStringresponseData
of type (Error or RegisterResponse or SignResponse)requestId
of type int, nullablerequestId
value of the corresponding request,
if present. Otherwise omitted.
Errors are indicated by an Error
dictionary sent as the response data.
An error dictionary can be identified by checking for its non-zero integer errorCode
key. RegisterResponse
and SignResponse
do not define this
key. An error object may optionally contain a string errorMessage
with further description of the error.
dictionary Error {
ErrorCode
errorCode;
DOMString? errorMessage;
};
Error
MemberserrorCode
of type ErrorCode
ErrorCode
enumeration.errorMessage
of type DOMString, nullable
A FIDO client MAY provide a JavaScript convenience API that abstracts the
lower-level MessagePort API. Implementations may choose how to make such
an API available to RP web pages. If such an API is provided, it SHOULD
provide a namespace object u2f
of the following interface.
interface u2f {
void register (RegisterRequest
[] registerRequests, SignRequest
[] signRequests, function(RegisterResponse or Error) callback, optional int? opt_timeoutSeconds);
void sign (SignRequest
[] signRequests, function(SignResponse or Error) callback, optional int? opt_timeoutSeconds);
};
register
Parameter | Type | Nullable | Optional | Description |
---|---|---|---|---|
registerRequests |
| ✘ | ✘ | Register requests, one for each U2F protocol version accepted by RP |
signRequests |
| ✘ | ✘ | Sign requests for already registered tokens |
callback | function(RegisterResponse or Error) | ✘ | ✘ | Response handler |
opt_timeoutSeconds | int | ✔ | ✔ | Timeout in seconds, for the FIDO client's handling of the request. |
void
sign
Parameter | Type | Nullable | Optional | Description |
---|---|---|---|---|
signRequests |
| ✘ | ✘ | Sign requests, one for each registered token |
callback | function(SignResponse or Error) | ✘ | ✘ | Response handler |
opt_timeoutSeconds | int | ✔ | ✔ | Timeout in seconds, for the FIDO client's handling of the request. |
void
The JavaScript API MUST invoke the provided callbacks with either
response objects, or an error object. An error can be detected by testing
for a non-zero errorCode
key.
u2f.sign(reqs, function(response) { if (response.errorCode) { // response is an Error ... } else { // response is a SignResponse ... } });
Regardless of the API level used, the U2F client MUST support the two operations of registering a token, and generating a signed assertion. This section describes the interface to each operation, their corresponding request and response dictionaries and possible error codes.
To register a U2F token for a user account at the RP, the RP MUST:
For each version it is willing to register, it then prepares a
RegisterRequest
dictionary as follows:
dictionary RegisterRequest {
DOMString version;
DOMString challenge;
DOMString appId;
};
RegisterRequest
Membersversion
of type DOMStringchallenge
of type DOMStringappId
of type DOMStringThe RP delivers a registration request to the FIDO client either via the low-level MessagePort API, or by invoking the high-level JavaScript API.
// Low-level API var port = <obtain U2F MessagePort in a browser specific manner>; port.addEventListener(‘message’, responseHandler); port.postMessage({ ‘type’: ‘u2f_register_request’, ‘registerRequests’: [<RegisterRequest instance>, ...], ‘signRequests’: [<SignRequest for known token 1>, ...], ‘timeoutSeconds’: 30, ‘requestId’: <unique integer> // optional });
// High-level API u2f.register([<RegisterRequest instance>, ...], [<SignRequest for known token 1>, ...], registerResponseHandler);
The FIDO client SHOULD treat the order of RegisterRequest dictionaries in the first parameter as a prioritized list. That is, if multiple tokens are present that support more than one version provided by the RP, the version that appears first should be selected. Note that this means multiple RegisterRequests with the same version are redundant, since the first one will always be selected.
Note also that the responseHandler in the low-level API receives a
Response
object, while the
registerResponseHandler
in the high-level API receives
the Error
or RegisterResponse
objects
directly.
The FIDO client will create the raw registration and sign request
messages from this data (see [U2FRawMsgs] in bibliography),
and attempt to perform a registration operation with a U2F token. The
sign request messages will have the (internal) checkOnly
boolean of the control state set to true, and are used to identity
such U2F tokens that are already registered with the relying party.
The registration request message is then used to register a U2F token
that is not already registered (if such a token is present).
Note that as part of creating the registration request message, the FIDO client will create a Client Data object (see [U2FRawMsgs]). This Client Data object will be returned to the caller as part of the registration response (see below).
If the registration is successful, the FIDO client returns (via the
message port, or the JS API callback) a RegisterResponse
dictionary as follows.
dictionary RegisterResponse {
DOMString registrationData;
DOMString clientData;
};
RegisterResponse
MembersregistrationData
of type DOMStringclientData
of type DOMStringTo obtain an identity assertion from a locally-attached U2F token, the RP must
SignRequest
object for each U2F token that the user has
currently registered with the RP.
dictionary SignRequest {
DOMString version;
DOMString challenge;
DOMString keyHandle;
DOMString appId;
};
SignRequest
Membersversion
of type DOMStringchallenge
of type DOMStringkeyHandle
of type DOMStringappId
of type DOMStringIn response to a sign request, the FIDO client should perform the following steps:
Eventually the FIDO client must respond (via the MessageChannel or
the provided callback). In the case of an error, an
Error
dictionary is returned. In case of success, a
SignResponse
is returned.
dictionary SignResponse {
DOMString keyHandle;
DOMString signatureData;
DOMString clientData;
};
SignResponse
MemberskeyHandle
of type DOMStringsignatureData
of type DOMStringclientData
of type DOMStringIf there are multiple U2F tokens that responded to the authentication request, the FIDO client will pick one of the responses and pass it to the caller.
When an Error
object is returned, its errorCode
field is set to a non-negative integer indicating the general error
that occurred, from the following enumeration.
interface ErrorCode {
const int OK = 0;
const int OTHER_ERROR = 1;
const int BAD_REQUEST = 2;
const int CONFIGURATION_UNSUPPORTED = 3;
const int DEVICE_INELIGIBLE = 4;
const int TIMEOUT = 5;
};
OK
of type intOTHER_ERROR
of type intBAD_REQUEST
of type intCONFIGURATION_UNSUPPORTED
of type intDEVICE_INELIGIBLE
of type intTIMEOUT
of type int