com.google.u2f.key.impl.U2FKeyReferenceImpl.java Source code

Java tutorial

Introduction

Here is the source code for com.google.u2f.key.impl.U2FKeyReferenceImpl.java

Source

// Copyright 2014 Google Inc. All rights reserved.
//
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file or at
// https://developers.google.com/open-source/licenses/bsd

package com.google.u2f.key.impl;

import java.security.KeyPair;
import java.security.PrivateKey;
import java.security.cert.X509Certificate;
import java.util.logging.Logger;

import org.apache.commons.codec.binary.Hex;

import com.google.u2f.U2FException;
import com.google.u2f.codec.RawMessageCodec;
import com.google.u2f.key.Crypto;
import com.google.u2f.key.DataStore;
import com.google.u2f.key.KeyHandleGenerator;
import com.google.u2f.key.KeyPairGenerator;
import com.google.u2f.key.U2FKey;
import com.google.u2f.key.UserPresenceVerifier;
import com.google.u2f.key.messages.AuthenticateRequest;
import com.google.u2f.key.messages.AuthenticateResponse;
import com.google.u2f.key.messages.RegisterRequest;
import com.google.u2f.key.messages.RegisterResponse;

public class U2FKeyReferenceImpl implements U2FKey {
    private static final Logger Log = Logger.getLogger(U2FKeyReferenceImpl.class.getName());

    private final X509Certificate vendorCertificate;
    private final PrivateKey certificatePrivateKey;
    private final KeyPairGenerator keyPairGenerator;
    private final KeyHandleGenerator keyHandleGenerator;
    private final DataStore dataStore;
    private final UserPresenceVerifier userPresenceVerifier;
    private final Crypto crypto;

    public U2FKeyReferenceImpl(X509Certificate vendorCertificate, PrivateKey certificatePrivateKey,
            KeyPairGenerator keyPairGenerator, KeyHandleGenerator keyHandleGenerator, DataStore dataStore,
            UserPresenceVerifier userPresenceVerifier, Crypto crypto) {
        this.vendorCertificate = vendorCertificate;
        this.certificatePrivateKey = certificatePrivateKey;
        this.keyPairGenerator = keyPairGenerator;
        this.keyHandleGenerator = keyHandleGenerator;
        this.dataStore = dataStore;
        this.userPresenceVerifier = userPresenceVerifier;
        this.crypto = crypto;
    }

    @Override
    public RegisterResponse register(RegisterRequest registerRequest) throws U2FException {
        Log.info(">> register");

        byte[] applicationSha256 = registerRequest.getApplicationSha256();
        byte[] challengeSha256 = registerRequest.getChallengeSha256();

        Log.info(" -- Inputs --");
        Log.info("  applicationSha256: " + Hex.encodeHexString(applicationSha256));
        Log.info("  challengeSha256: " + Hex.encodeHexString(challengeSha256));

        byte userPresent = userPresenceVerifier.verifyUserPresence();
        if ((userPresent & UserPresenceVerifier.USER_PRESENT_FLAG) == 0) {
            throw new U2FException("Cannot verify user presence");
        }

        KeyPair keyPair = keyPairGenerator.generateKeyPair(applicationSha256, challengeSha256);
        byte[] keyHandle = keyHandleGenerator.generateKeyHandle(applicationSha256, keyPair);

        dataStore.storeKeyPair(keyHandle, keyPair);

        byte[] userPublicKey = keyPairGenerator.encodePublicKey(keyPair.getPublic());

        byte[] signedData = RawMessageCodec.encodeRegistrationSignedBytes(applicationSha256, challengeSha256,
                keyHandle, userPublicKey);
        Log.info("Signing bytes " + Hex.encodeHexString(signedData));

        byte[] signature = crypto.sign(signedData, certificatePrivateKey);

        Log.info(" -- Outputs --");
        Log.info("  userPublicKey: " + Hex.encodeHexString(userPublicKey));
        Log.info("  keyHandle: " + Hex.encodeHexString(keyHandle));
        Log.info("  vendorCertificate: " + vendorCertificate);
        Log.info("  signature: " + Hex.encodeHexString(signature));

        Log.info("<< register");

        return new RegisterResponse(userPublicKey, keyHandle, vendorCertificate, signature);
    }

    @Override
    public AuthenticateResponse authenticate(AuthenticateRequest authenticateRequest) throws U2FException {
        Log.info(">> authenticate");

        byte control = authenticateRequest.getControl();
        byte[] applicationSha256 = authenticateRequest.getApplicationSha256();
        byte[] challengeSha256 = authenticateRequest.getChallengeSha256();
        byte[] keyHandle = authenticateRequest.getKeyHandle();

        Log.info(" -- Inputs --");
        Log.info("  control: " + control);
        Log.info("  applicationSha256: " + Hex.encodeHexString(applicationSha256));
        Log.info("  challengeSha256: " + Hex.encodeHexString(challengeSha256));
        Log.info("  keyHandle: " + Hex.encodeHexString(keyHandle));

        KeyPair keyPair = dataStore.getKeyPair(keyHandle);
        int counter = dataStore.incrementCounter();
        byte userPresence = userPresenceVerifier.verifyUserPresence();
        byte[] signedData = RawMessageCodec.encodeAuthenticateSignedBytes(applicationSha256, userPresence, counter,
                challengeSha256);

        Log.info("Signing bytes " + Hex.encodeHexString(signedData));

        byte[] signature = crypto.sign(signedData, keyPair.getPrivate());

        Log.info(" -- Outputs --");
        Log.info("  userPresence: " + userPresence);
        Log.info("  counter: " + counter);
        Log.info("  signature: " + Hex.encodeHexString(signature));

        Log.info("<< authenticate");

        return new AuthenticateResponse(userPresence, counter, signature);
    }
}