GSoc-Mozilla-2020
GSoc-Mozilla-2020

I implemented FIDO2 webauthn (Javascript & Node.js Version) for Mozilla Firefox Accounts as a part of Google Summer Of Code Intern 2020

The FIDO U2F protocol enables relying parties to offer a strong cryptographic 2nd factor option for end user security. The relying party’s dependence on passwords is reduced. The password can even be simplified to a 4-digit PIN or fingerprint sensor. End users carry a single U2F device which works with any relying party supporting the protocol. The user gets the convenience of a single ‘keychain’ device and convenient security

Done (During GSoC):

  • Server - PR #5773 & commit #da8366e
    • Added utility lib and fido2 helpers.
    • Added Authenticator Keys (u2f, packed).
    • Added Challenge generation for Registration & Login.
    • Added Functions for parsing and authenticating keys.
    • Added raw database to store in memory.
    • Added server side routes.
    • Added supporting unit tests in mocha and sinon.
    • Added Missing “none” fmt keys support for BLE and NFC authentication.

  • Client - PR #6033 & commit #9e81f9e
    • Added client side utility file to parse and generate registration and login.
    • Added client side model in backbone.js.
    • Added view and templates in mustache.
    • Added Client side routes.

To Do (Plan post GSoC):

  • Add more tests for code coverage.
  • Add TypeScript support.
  • Redesign UI.
  • Add future docs.

Let’s build…

The Utility Helpers

Let’s store our utility helpers.

  • Create a file util.js

  • Libraries Required

  1. Install cbor and import those libraries in util.js

    const crypto = require('crypto');
    const cbor = require('cbor');
    
  2. The U2F device has a physical ‘test of user presence’. The user touches a button (sensor of some kind) to ‘activate’ the U2F device. It ensures that the relying party can trust in that the authentication process is actively triggered by the user himself.

  • Let’s name this U2F_REGISTER and export it.
/**
* U2F PRESENCE CONSTANT
*/
exports.U2F_REGISTER = 0x01;

Note: 0x01 is the hexadecimal code which means 1 (i.e successful).

  1. Let’s define our hashing function. A hash is a way to encrypt data into a fixed-length digest. This digest serves as a signature representing the original data that hashed. The various types of hashing algorithms are available in Node.js through the crypto module. This core module provides the wrappers on OpenSSL functions.
$ openssl list -digest-algorithms
  • Each algorithms has pros and cons and can be used according to need of application.

  • We will use sha256 for this application.

  • Following steps for creating hash:

    • Load crypto module (which we already did!)

    • Create Hash object from crypto. For creating the hash object, you need to provide the algorithm to be used, mostly following three are used md5, sha1, sha256.

      // const hash = crypto.createHash([algorithm-to-be-used])
      const hash = crypto.createHash('sha256');
      
    • Set data to be hashed. We need to set data to be hashed to which we have to generate hash. This can be string, file object, along with data we need to specify the encoding type for data, this usually utf-8 or can be binary, ascii. If data is a Buffer then encoding-type is ignored.

      // hash.update([data to be hashed], [encoding-type] )
      hash_update = hash.update('Mozilla', 'utf-8'); 
      
    • Create the hash digest in required format. This digest takes parameter which asks for in which format the hash to be generated, this can be hex. If no encoding is provided, then a buffer is returned.

      // generated_hash= hash_update.digest([format])
      generated_hash = hash_update.digest('hex');
      
  • Let’s combine everything, more utility helpers are located in the fxa repository

Attestation

FIDO2 U2F
FIDO2 U2F
Packed fmt
Packed fmt

Demo Video

Acknowledgement

  • I would like to thank my mentor Vijay Budhram and Firefox Accounts Team for helping and guiding me in the project throughout the gsoc journey!

  • I am thankful to Google Summer Of Code for providing me an opportunity to work with Mozilla.

References