-
Notifications
You must be signed in to change notification settings - Fork 10
During the U2F kick-off meeting, a number of challenges were anticipated. They are outlined below.
Unlike the SMS and Yubikey second factors, and very much like Tiqr, U2F needs a common origin (protocol, hostname and port) between registration (Self-Service, Registration Authority) and authentication (Gateway). In simple words: the U2F interaction must take place from one domain. One solution was thought to be to implement a second generic SAML second factor IdP on the Gateway or as a separate application.
As of August 2015, Linux (Ubuntu 14.04) does not support U2F out of the box and requires changes to udev rules. This issue has been noted, but won't be addressed, since U2F is not yet widely used, not yet used in production and may be addressed by Linux or Google Chrome in the future.
Like all other current second factors (SMS, Yubikey, Tiqr), U2F requires registration through the Self-Service and Registration Authority applications, after which it can be used on the Gateway to increase authentication security. Regarding user interaction, U2F's is the same as Yubikey's, but without an OTP entry field and more browser instructions.
In the Self-Service application, after the user has selected U2F as the second factor to register, the user is shown a page that will instruct him or her about the steps to take to register the U2F device with the Sterke Authenticatie infrastructure. These steps may include one or more of the following:
- Make sure the U2F device is inserted in the computer
- If the browser prompts the user to allow Sterke Authenticatie to register the U2F device, confirm
- Press the button on the U2F device, which will blink
Error conditions:
- The user aborts the registration of the device. This is our UI or the browser back button.
- The user denies registration of the device through the browser UI.
- Chrome Runtime response message error codes returned through U2F JS API wrapper library, see 3.1.2 and 4.3 of the FIDO U2F Javascript API document.
For the time being, we assume all U2F devices to be USB devices with a blinking button.
Usage of a U2F second factor happens through an assertion signing process. During vetting in the Registration Authority application, or during authentication in the Gateway, the user is shown a page that will instruct him or her about the steps to take to sign the assertion.
- Make sure the U2F device is inserted in the computer
- Press the button on the U2F device
Error conditions:
- The user aborts the signing. This is our UI or the browser back button.
- Chrome Runtime response message error codes returned through U2F JS API wrapper library, see 3.1.2 and 4.3 of the FIDO U2F Javascript API document.
U2F knows a concept called Application Facets. This concept allows for multiple web origins and native applications (facets) to make up a single logical application. The Gateway will serve a resource from its AppID URL (eg. https://sa-gw.surfconext.nl/u2f/app-id), which will state which AppIDs are facets of the logical application that is Sterke Authenticatie. When registering at the Self-Service, it will state that the https://sa-gw.surfconext.nl/u2f/app-id is its AppID, which will allow the Self-Service to register the connected U2F device in the logical application that is Sterke Authenticatie. Subsequently, in the Registration Authority and Gateway applications, a signing request can be performed using that same U2F device.
The Sterke Authenticatie AppID must be determined very carefully. If this ID is ever changed, identities can no longer authenticate using their U2F devices and must reregister their U2F devices.
SURFnet must make sure a file is served from the AppID URL. This can be performed during deploy and be served by nginx.
An example AppID resource:
{
"trustedFacets": [{
"version": {"major": 1, "minor": 0},
"ids": [
"https://ss.surfconext.nl",
"https://ra.surfconext.nl",
"https://gw.surfconext.nl"
]
}]
}
The interaction with the device will be performed using a form and Yubikey's high-level wrapper around the low-level U2F JavaScript API.
The U2F key handle will be the second factor's identifier, its public key will be stored in its attributes. These attributes will be stored in a JSON column in the second factor table. Server validation will be performed using Yubico's PHP U2F server library, which contains a validation class, unless it will prove unwieldy or exceptions cannot be handled properly, in which case we will refactor it to our needs.
To enable proper verification of U2F registrations and authentications, a counter state must be kept across the Self-Service, Registration Authority and Gateway applications. The Gateway is an application that may not have dependencies on other applications. Therefore it must implement the U2F verification server functionality. This functionality is exposed internally through a Symfony2 service. To prevent duplication, enable statistics about U2F usage across all user-facing applications and allow storage in a single location, that same service is exposed over an HTTP API.
The following API will be available:
register(RegistrationRequest, RegistrationResponse): RegistrationVerification[status: int]
verifyAuthentication(SignRequest, SignResponse): AuthenticationVerification[status: int]
revokeRegistration($keyHandle): RegistrationRevocation[status: int]
Which translates to an HTTP API as described API Design.
Request generation and invalidation (eg. after a given time) are client concerns and must still be performed on the client.
Because this is a concern that is separate from the Gateway's main functionality, namely operating as a step-up SAML proxy, the U2F state should be stored in a separate database, called u2f. This separate database stores key handles, public keys and signing counters from U2F devices. The additional database affects the deployment Ansible scripts and our development VM, however the impact is minimal.
Sign counter wrapping is not supported (eg. MAX_INT to 1). Should a counter wrap, a registrant must revoke, and register and vet his or her device again.
The sign counter does not necessarily increment monotonically; the U2F device may use a global counter, or authentications may get lost between client and server. Thus, sign counter verification succeeds if the authentication's sign counter is merely higher than the stored sign counter.
All in all, the centralised verification server reduces duplication and isolates complexity. This in turn eases development and maintenance, and simplifies implementation in the Self-Service and Registration Authority applications.
The U2F second factor should not be rolled out to production. An enabled-by-default feature toggle will be available in the configuration of the Self-Service application that disables U2F in views and controllers.
To allow reuse of U2F forms, resources and device verification, a Symfony2 Bundle will be created that encapsulates the logic and resources.
If there is time, a directory containing trusted attestation certificate roots may be configured and used to verify a device has been manufactured by an owner of one of these certificates. This is a nice-to-have.
The certificates are provisioned during deploy.
Reading material: