Yuriy Ackermann, Sr. Certification Engineer, FIDO Alliance
The FIDO Alliance is pleased to announce the release of the FIDO U2F version 1.2 specification.
Since the last two versions, there’s been structural changes, improvements, updates and new security features. Below, we take a detailed look at these changes. For a summary version of the changes, go to “FIDO U2F v1.2: Changes Overview.”
JS API
interface u2f {
void register (
DOMString appId,
sequence<RegisterRequest> registerRequests,
sequence<RegisteredKey> registeredKeys,
function(RegisterResponse or Error) callback,
optional unsigned long? opt_timeoutSeconds
);
void sign (
DOMString appId,
DOMString challenge,
sequence<RegisteredKey> registeredKeys,
function(SignResponse or Error) callback,
optional unsigned long? opt_timeoutSeconds
);
};
High level JS API has been updated. Previously, you had to individually set,every “RegisterRequest” and “SignRequest” appId and challenge. In JS API v1.2 appld is passed as a first argument for u2f.register.
/* —– U2Fv1.0 —– */
let appId = “https://example.com“;
let registerRequests = […];
let signRequests = […];
for (let regReq of registerRequests) {
regReq.appId = appId;
}
for (let signReq of signRequests) {
signReq.appId = appId;
}
u2f.register(registerRequests, signRequests, () => {
…
})
/* —– U2Fv1.2—– */
let appId = “https://example.com“;
let registerRequests = […];
let signRequests = […];
u2f.register(appId, registerRequests, signRequests, () => {
…
})
Another way that v1.2 has been redefined is authentication request dictionaries. Previous dictionaries of type “SignRequest” have been replaced by “RegisteredKey” dictionary.
/* —– U2Fv1.0 —– */
dictionary SignRequest { // OLD
DOMString version;
DOMString challenge;
DOMString keyHandle;
DOMString appId;
};
/* —– U2Fv1.2 —– */
dictionary RegisteredKey { // New
DOMString version;
DOMString keyHandle;
Transports? transports;
DOMString? appId;
};
With this change, the challenge has been removed from the dictionary and is now the second argument of the u2f.sign command The first is appId, same as for the u2f.register command.
/* —– U2Fv1.0 —– */
let appId = “https://example.com“;
let signRequests = […];
for (let regReq of registerRequests) {
regReq.appId = appId;
}
u2f.sign(signRequests, () => {
…
})
/* —– U2Fv1.2 —– */
let appId = “https://example.com“;
let challenge = “YJjw3jBh6RiMPKY0lMWq8GXm0Qap”;
let registeredKeys = […];
u2f.sign(appId, challenge, registeredKeys, () => {
…
})
For backward compatibility, the client may still process SignRequest. The same applies for an RP, who may continue processing SignResponse.
Another added feature is “transports” array. The RP may indicate to the client which transports a particular key handle uses. It does so through the use of the Transport enumeration:
enum Transport {
“bt”, // Bluetooth Classic (Bluetooth BR/EDR)
“ble”, // Bluetooth Low Energy (Bluetooth Smart)
“nfc”, // Near-Field Communications
“usb”, // USB HID
“usb-internal” // Non-removable USB HID (built in)
};
This is particularly useful for UI/UX, where the client can refer to the prompt that is specified by the indicated transport.
We will discuss transport detection in the “Authenticator Transport Extension” section.
The MessagePort API gained it’s own request definition dictionary IDL.
dictionary U2fRequest {
DOMString type;
DOMString? appId;
unsigned long? timeoutSeconds;
unsigned long? requestId;
};
That extends to “U2fRegisterRequest” and “U2fSignRequest”
dictionary U2fRegisterRequest : U2fRequest {
DOMString type = ‘u2f_register_request’;
sequence<RegisterRequest> registerRequests;
sequence<RegisteredKey> registeredKeys;
};
dictionary U2fSignRequest : U2fRequest {
DOMString type = ‘u2f_sign_request’;
DOMString challenge;
sequence<RegisteredKey> registeredKeys;
};
As you can see, the changes that happen to the U2F JS API, happen correspondingly to the MessagePort API as well.
/* —– U2Fv1.0 —– */
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
});
/* —– U2Fv1.2 —– */
var port = <obtain U2F MessagePort in a browser specific manner>;
port.addEventListener(‘message’, responseHandler);
port.postMessage({
‘type’: ‘u2f_register_request’,
‘appId’: <Application id>,
‘registerRequests’: [<RegisterRequest instance>, …],
‘registeredKeys’: [<RegisteredKey for known token 1>, …],
‘timeoutSeconds’: 30,
‘requestId’: <unique integer> // optional
});]
Authenticator Transport Extension
During registration, the authenticator signs the challenge with a batch key, and provides its public key with an X.509 certificate. The vendor now can add X.509 FIDO OID’s and U2F certificate extension that will identify that this is a U2F authenticator certificate:
— FIDO Alliance’s OID
id-fido OBJECT IDENTIFIER ::= 1.3.6.1.4.1.45724
— FIDO U2F protocol OID
id-fido-u2f OBJECT IDENTIFIER ::= { id-fido 2 }
— FIDO U2F certificate extensions arc
id-fido-u2f-ce OBJECT IDENTIFIER ::= { id-fido-u2f 1 }
To identify the type of the authenticator, the specification defines U2F Transport Extension
— FIDO U2F certificate extensions
id-fido-u2f-ce-transports OBJECT IDENTIFIER ::= { id-fido-u2f-ce 1 }
fidoU2FTransports EXTENSION ::= {
WITH SYNTAX FIDOU2FTransports ID id-fido-u2f-ce-transports
}
FIDOU2FTransports ::= BIT STRING {
bluetoothRadio(0),– Bluetooth Classic
bluetoothLowEnergyRadio(1),
uSB(2),
nFC(3),
uSBInternal(4)
}
Raw Message Format
One of the most important features of this update is added silent authenticator support. With this feature, Application Protocol Data Units (APDUs) received new sign parameters dont-enforce-user-presence-and-sign(0x08). Now clients can request signature without user presence enforcement. This is particularly useful to FIDO-based federated solutions that use silent mode for “bearer token” like authentication modes. The major advantage of FIDO-based solutions is leakage resilience. Since FIDO protocols are based on digital signatures, and the private key is stored generally in secure enclaves, federated identity can use the authenticator as an unrecoverable bearer token, and therefore not have to worry about XSS and malware on the client side.
U2FHID
U2FHID was updated with a U2FHID_LOCK command. Now the client can request the authenticator to lock communication only to one channel for up to 10 seconds. The client can continuously send LOCK command to extend authenticator lock time.
Metadata Statement
U2F has received support for metadata statements.
{
“description”: “FIDO Alliance Sample U2F Authenticator”,
“attestationCertificateKeyIdentifiers”: [“7c0903708b87115b0b422def3138c3c864e44573”],
“protocolFamily”: “u2f”,
“authenticatorVersion”: 2,
“upv”: [
{ “major”: 1, “minor”: 2 }
],
“assertionScheme”: “U2FV1BIN”,
“authenticationAlgorithm”: 1,
“publicKeyAlgAndEncoding”: 256,
“attestationTypes”: [15879],
“userVerificationDetails”: [
[{ “userVerification”: 1 }]
],
“keyProtection”: 10,
“matcherProtection”: 4,
“attachmentHint”: 2,
“isSecondFactorOnly”: “true”,
“tcDisplay”: 0,
“attestationRootCertificates”: [
“MIICPTCCAeOgAwIBAgIJAOuexvU3Oy2wMAoGCCqGS
VdLIgtfsbDSu7ErJfzr4AiBqoYCZf0+zI55aQeAHjI…
lQ==”
],
“icon”: “data:image/png;base64,iVBORw0KGgoAAAAUgAAAE8AAAAv…”
}
To accommodate these changes, new fields have been added, such as
- attestationCertificateKeyIdentifiers — SHA-1 Certificate SKID from RFC5280
- assertionScheme —new U2FV1BIN scheme definition
With these changes, U2F can now be added to the list of supported by Metadata Service protocols.
— — — — — — — — — — — — — — — — — — — — — — — — — — — — —
If you wish to learn more about U2Fv1.2, visit the FIDO Alliance specs repository.
References
- https://fidoalliance.org/specs/fido-u2f-v1.2-ps-20170411/fido-u2f-javascript-api-v1.2-ps-20170411.html
- https://fidoalliance.org/specs/fido-u2f-v1.2-ps-20170411/fido-u2f-authenticator-transports-extension-v1.2-ps-20170411.html
- https://fidoalliance.org/specs/fido-u2f-v1.2-ps-20170411/fido-u2f-raw-message-formats-v1.2-ps-20170411.html
- https://fidoalliance.org/specs/fido-u2f-v1.2-ps-20170411/fido-u2f-hid-protocol-v1.2-ps-20170411.pdf
- https://fidoalliance.org/specs/fido-u2f-v1.2-ps-20170411/fido-metadata-statement-v1.2-ps-20170411.html
- https://www.ietf.org/rfc/rfc5280.txt
- https://fidoalliance.org/specs/fido-u2f-v1.2-ps-20170411/