org.jmrtd.lds.ChipAuthenticationInfo.java Source code

Java tutorial

Introduction

Here is the source code for org.jmrtd.lds.ChipAuthenticationInfo.java

Source

/*
 * JMRTD - A Java API for accessing machine readable travel documents.
 *
 * Copyright (C) 2006 - 2015  The JMRTD team
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 *
 * $Id$
 */

package org.jmrtd.lds;

import java.math.BigInteger;
import java.util.logging.Level;
import java.util.logging.Logger;

import org.bouncycastle.asn1.ASN1EncodableVector;
import org.bouncycastle.asn1.ASN1Integer;
import org.bouncycastle.asn1.ASN1ObjectIdentifier;
import org.bouncycastle.asn1.ASN1Primitive;
import org.bouncycastle.asn1.DLSequence;

/**
 * A concrete SecurityInfo structure that stores chip authentication info,
 * see EAC 1.11 specification.
 *
 * This data structure provides detailed information on an implementation of
 * Chip Authentication.
 * <ul>
 * <li>The object identifier <code>protocol</code> SHALL identify the
 *     algorithms to be used (i.e. key agreement, symmetric cipher and MAC).</li>
 * <li>The integer <code>version</code> SHALL identify the version of the protocol.
 *     Currently, versions 1 and 2 are supported.</li>
 * <li>The integer <code>keyId</code> MAY be used to indicate the local key identifier.
 *     It MUST be used if the MRTD chip provides multiple public keys for Chip
 *     Authentication.</li>
 * </ul>
 *
 * @author Wojciech Mostowski (woj@cs.ru.nl)
 * 
 * @version $Revision$
 *
 * FIXME: dependency on BC?
 */
public class ChipAuthenticationInfo extends SecurityInfo {

    private static final long serialVersionUID = 5591988305059068535L;

    private static final Logger LOGGER = Logger.getLogger("org.jmrtd");

    /** Chip Authenticaiton version. */
    public static final int VERSION_1 = 1, VERSION_2 = 2;

    private String oid;
    private int version;
    private BigInteger keyId;

    /**
     * Constructs a new object.
     *
     * @param oid a proper EAC identifier
     * @param version has to be 1 or 2
     * @param keyId the key identifier
     */
    public ChipAuthenticationInfo(String oid, int version, BigInteger keyId) {
        this.oid = oid;
        this.version = version;
        this.keyId = keyId;
        checkFields();
    }

    /**
     * Constructs a new object.
     *
     * @param oid a proper EAC identifier
     * @param version has to be 1 or 2
     */
    public ChipAuthenticationInfo(String oid, int version) {
        this(oid, version, BigInteger.valueOf(-1));
    }

    @Deprecated
    public ASN1Primitive getDERObject() {
        ASN1EncodableVector v = new ASN1EncodableVector();
        v.add(new ASN1ObjectIdentifier(oid));
        v.add(new ASN1Integer(version));
        if (keyId.compareTo(BigInteger.ZERO) >= 0) {
            v.add(new ASN1Integer(keyId));
        }
        return new DLSequence(v);
    }

    public String getObjectIdentifier() {
        return oid;
    }

    /**
     * Returns a key identifier stored in this ChipAuthenticationInfo structure, null
     * if not present
     *
     * @return key identifier stored in this ChipAuthenticationInfo structure
     */
    public BigInteger getKeyId() {
        return keyId;
    }

    /**
     * Checks the correctness of the data for this instance of SecurityInfo
     */
    protected void checkFields() {
        try {
            if (!checkRequiredIdentifier(oid)) {
                throw new IllegalArgumentException("Wrong identifier: " + oid);
            }
            if (version != VERSION_1 && version != VERSION_2) {
                throw new IllegalArgumentException(
                        "Wrong version. Was expecting " + VERSION_1 + " or " + VERSION_2 + ", found " + version);
            }
        } catch (Exception e) {
            LOGGER.log(Level.SEVERE, "Exception", e);
            throw new IllegalArgumentException("Malformed ChipAuthenticationInfo.");
        }
    }

    /**
     * Checks whether the given object identifier identifies a
     * ChipAuthenticationInfo structure.
     *
     * FIXME: for EAC 1.11 only the 3DES OIDs are allowed.
     *
     * @param oid
     *            object identifier
     * @return true if the match is positive
     */
    static boolean checkRequiredIdentifier(String oid) {
        return ID_CA_DH_3DES_CBC_CBC_OID.equals(oid) || ID_CA_ECDH_3DES_CBC_CBC_OID.equals(oid)
                || ID_CA_DH_AES_CBC_CMAC_128_OID.equals(oid) || ID_CA_DH_AES_CBC_CMAC_192_OID.equals(oid)
                || ID_CA_DH_AES_CBC_CMAC_256_OID.equals(oid) || ID_CA_ECDH_AES_CBC_CMAC_128_OID.equals(oid)
                || ID_CA_ECDH_AES_CBC_CMAC_192_OID.equals(oid) || ID_CA_ECDH_AES_CBC_CMAC_256_OID.equals(oid);
    }

    public String toString() {
        return "ChipAuthenticationInfo [oid = " + oid + ", version = " + version + ", keyId = " + keyId + "]";
    }

    public int hashCode() {
        return 3 + 11 * (oid == null ? 0 : oid.hashCode()) + 61 * version + 1991 * keyId.hashCode();
    }

    public boolean equals(Object other) {
        if (other == null) {
            return false;
        }
        if (other == this) {
            return true;
        }
        if (!ChipAuthenticationInfo.class.equals(other.getClass())) {
            return false;
        }
        ChipAuthenticationInfo otherChipAuthenticationInfo = (ChipAuthenticationInfo) other;
        return oid.equals(otherChipAuthenticationInfo.oid) && version == otherChipAuthenticationInfo.version
                && keyId.equals(otherChipAuthenticationInfo.keyId);
    }
}