org.xdi.oxauth.service.fido.u2f.RawAuthenticationService.java Source code

Java tutorial

Introduction

Here is the source code for org.xdi.oxauth.service.fido.u2f.RawAuthenticationService.java

Source

/*
 * oxAuth is available under the MIT License (2008). See http://opensource.org/licenses/MIT for full text.
 *
 * Copyright (c) 2014, Gluu
 */

package org.xdi.oxauth.service.fido.u2f;

import java.io.IOException;

import org.apache.commons.io.IOUtils;
import org.jboss.seam.ScopeType;
import org.jboss.seam.annotations.AutoCreate;
import org.jboss.seam.annotations.In;
import org.jboss.seam.annotations.Logger;
import org.jboss.seam.annotations.Name;
import org.jboss.seam.annotations.Scope;
import org.jboss.seam.log.Log;
import org.xdi.oxauth.crypto.signature.BouncyCastleSignatureVerification;
import org.xdi.oxauth.model.exception.SignatureException;
import org.xdi.oxauth.model.fido.u2f.exception.BadInputException;
import org.xdi.oxauth.model.fido.u2f.message.RawAuthenticateResponse;
import org.xdi.oxauth.model.fido.u2f.protocol.ClientData;
import org.xdi.oxauth.model.util.Base64Util;
import org.xdi.util.io.ByteDataInputStream;

import com.google.common.io.ByteArrayDataOutput;
import com.google.common.io.ByteStreams;

/**
 * Provides operations with U2F RAW authentication response
 *
 * @author Yuriy Movchan Date: 05/20/2015
 */
@Scope(ScopeType.STATELESS)
@Name("rawAuthenticationService")
@AutoCreate
public class RawAuthenticationService {

    public static final String AUTHENTICATE_TYPE = "navigator.id.getAssertion";

    @Logger
    private Log log;

    @In(value = "bouncyCastleSignatureVerification")
    private BouncyCastleSignatureVerification signatureVerification;

    public RawAuthenticateResponse parseRawAuthenticateResponse(String rawDataBase64) {
        ByteDataInputStream bis = new ByteDataInputStream(Base64Util.base64urldecode(rawDataBase64));
        try {
            return new RawAuthenticateResponse(bis.readSigned(), bis.readInt(), bis.readAll());
        } catch (IOException ex) {
            throw new BadInputException("Failed to parse RAW authenticate response", ex);
        } finally {
            IOUtils.closeQuietly(bis);
        }
    }

    public void checkSignature(String appId, ClientData clientData, RawAuthenticateResponse rawAuthenticateResponse,
            byte[] publicKey) throws BadInputException {
        String rawClientData = clientData.getRawClientData();

        byte[] signedBytes = packBytesToSign(signatureVerification.hash(appId),
                rawAuthenticateResponse.getUserPresence(), rawAuthenticateResponse.getCounter(),
                signatureVerification.hash(rawClientData));
        try {
            signatureVerification.checkSignature(signatureVerification.decodePublicKey(publicKey), signedBytes,
                    rawAuthenticateResponse.getSignature());
        } catch (SignatureException ex) {
            throw new BadInputException("Failed to checkSignature", ex);
        }
    }

    private byte[] packBytesToSign(byte[] appIdHash, byte userPresence, long counter, byte[] challengeHash) {
        ByteArrayDataOutput encoded = ByteStreams.newDataOutput();
        encoded.write(appIdHash);
        encoded.write(userPresence);
        encoded.writeInt((int) counter);
        encoded.write(challengeHash);

        return encoded.toByteArray();
    }

}