All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.jmrtd.lds.ChipAuthenticationInfo Maven / Gradle / Ivy

/*
 * JMRTD - A Java API for accessing machine readable travel documents.
 *
 * Copyright (C) 2006 - 2018  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: ChipAuthenticationInfo.java 1799 2018-10-30 16:25:48Z martijno $
 */

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.
 * 
    *
  • The object identifier protocol SHALL identify the * algorithms to be used (i.e. key agreement, symmetric cipher and MAC).
  • *
  • The integer version SHALL identify the version of the protocol. * Currently, versions 1 and 2 are supported.
  • *
  • The integer keyId MAY be used to indicate the local key identifier. * It MUST be used if the MRTD chip provides multiple public keys for Chip * Authentication.
  • *
* * @author The JMRTD team ([email protected]) * * @version $Revision: 1799 $ */ public class ChipAuthenticationInfo extends SecurityInfo { private static final long serialVersionUID = 5591988305059068535L; private static final Logger LOGGER = Logger.getLogger("org.jmrtd"); /** Chip Authentication version 1. */ public static final int VERSION_1 = 1; /** Chip Authentication version 2. */ public static final int 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 */ public ChipAuthenticationInfo(String oid, int version) { this(oid, version, null); } /** * 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(); } /** * Returns a DER object with this SecurityInfo data (DER sequence). * * @return a DER object with this SecurityInfo data * * @deprecated Remove this method from visible interface (because of dependency on BC API) */ @Override @Deprecated public ASN1Primitive getDERObject() { ASN1EncodableVector v = new ASN1EncodableVector(); v.add(new ASN1ObjectIdentifier(oid)); v.add(new ASN1Integer(version)); if (keyId != null) { v.add(new ASN1Integer(keyId)); } return new DLSequence(v); } /** * Gets the protocol object identifier. * * @return the {@code ID_CA_} object identifier indicating the Chip Authentication protocol */ @Override public String getObjectIdentifier() { return oid; } /** * Returns the Chip Authentication version (either 1 or 2). * * @return the Chip Authentication version */ public int getVersion() { return version; } /** * Gets the protocol object identifier as a human readable string. * * @return a string */ @Override public String getProtocolOIDString() { return toProtocolOIDString(oid); } /** * Returns a key identifier stored in this ChipAuthenticationInfo structure, * {@code 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. * Throws an {@code IllegalArgumentException} when not correct. */ 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.WARNING, "Unexpected 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.equals(oid) || ID_CA_ECDH_3DES_CBC_CBC.equals(oid) || ID_CA_DH_AES_CBC_CMAC_128.equals(oid) || ID_CA_DH_AES_CBC_CMAC_192.equals(oid) || ID_CA_DH_AES_CBC_CMAC_256.equals(oid) || ID_CA_ECDH_AES_CBC_CMAC_128.equals(oid) || ID_CA_ECDH_AES_CBC_CMAC_192.equals(oid) || ID_CA_ECDH_AES_CBC_CMAC_256.equals(oid); } @Override public String toString() { return "ChipAuthenticationInfo [" + "protocol: " + toProtocolOIDString(oid) + ", version: " + version + ", keyId: " + (keyId == null ? "-" : keyId) + "]"; } @Override public int hashCode() { return 3 + 11 * (oid == null ? 0 : oid.hashCode()) + 61 * version + 1991 * (keyId == null ? 111 : keyId.hashCode()); } @Override 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 == null && otherChipAuthenticationInfo.keyId == null || keyId != null && keyId.equals(otherChipAuthenticationInfo.keyId)); } /** * Returns the key agreement algorithm ({@code "DH"} or {@code "ECDH"} * for the given Chip Authentication info object identifier. * * @param oid a EAC-CA protocol object identifier * * @return the key agreement algorithm */ public static String toKeyAgreementAlgorithm(String oid) { if (oid == null) { throw new NumberFormatException("Unknown OID: null"); } if (ID_CA_DH_3DES_CBC_CBC.equals(oid) || ID_CA_DH_AES_CBC_CMAC_128.equals(oid) || ID_CA_DH_AES_CBC_CMAC_192.equals(oid) || ID_CA_DH_AES_CBC_CMAC_256.equals(oid)) { return "DH"; } else if (ID_CA_ECDH_3DES_CBC_CBC.equals(oid) || ID_CA_ECDH_AES_CBC_CMAC_128.equals(oid) || ID_CA_ECDH_AES_CBC_CMAC_192.equals(oid) || ID_CA_ECDH_AES_CBC_CMAC_256.equals(oid)) { return "ECDH"; } throw new NumberFormatException("Unknown OID: \"" + oid + "\""); } /** * Returns the encryption algorithm ({@code "DESede"} or {@code "AES"}) * for the given EAC-CA info object identifier. * * @param oid a EAC-CA protocol object identifier * * @return a JCE mnemonic cipher algorithm string */ public static String toCipherAlgorithm(String oid) { if (ID_CA_DH_3DES_CBC_CBC.equals(oid) || ID_CA_ECDH_3DES_CBC_CBC.equals(oid)) { return "DESede"; } else if (ID_CA_DH_AES_CBC_CMAC_128.equals(oid) || ID_CA_DH_AES_CBC_CMAC_192.equals(oid) || ID_CA_DH_AES_CBC_CMAC_256.equals(oid) || ID_CA_ECDH_AES_CBC_CMAC_128.equals(oid) || ID_CA_ECDH_AES_CBC_CMAC_192.equals(oid) || ID_CA_ECDH_AES_CBC_CMAC_256.equals(oid)) { return "AES"; } throw new NumberFormatException("Unknown OID: \"" + oid + "\""); } /** * Returns the digest algorithm ({@code "SHA-1"} or {@code "SHA-256"}) * for the given EAC-CA protocol object identifier. * * @param oid a EAC-CA protocol object identifier * * @return a JCE mnemonic digest algorithm string */ public static String toDigestAlgorithm(String oid) { if (ID_CA_DH_3DES_CBC_CBC.equals(oid) || ID_CA_ECDH_3DES_CBC_CBC.equals(oid) || ID_CA_DH_AES_CBC_CMAC_128.equals(oid) || ID_CA_ECDH_AES_CBC_CMAC_128.equals(oid)) { return "SHA-1"; } else if (ID_CA_DH_AES_CBC_CMAC_192.equals(oid) || ID_CA_ECDH_AES_CBC_CMAC_192.equals(oid) || ID_CA_DH_AES_CBC_CMAC_256.equals(oid) || ID_CA_ECDH_AES_CBC_CMAC_256.equals(oid)) { return "SHA-256"; } throw new NumberFormatException("Unknown OID: \"" + oid + "\""); } /** * Returns the key length in bits (128, 192, or 256) * for the given EAC-CA protocol object identifier. * * @param oid a EAC-CA protocol object identifier * * @return a key length in bits */ public static int toKeyLength(String oid) { if (ID_CA_DH_3DES_CBC_CBC.equals(oid) || ID_CA_ECDH_3DES_CBC_CBC.equals(oid) || ID_CA_DH_AES_CBC_CMAC_128.equals(oid) || ID_CA_ECDH_AES_CBC_CMAC_128.equals(oid)) { return 128; } else if (ID_CA_DH_AES_CBC_CMAC_192.equals(oid) || ID_CA_ECDH_AES_CBC_CMAC_192.equals(oid)) { return 192; } else if (ID_CA_DH_AES_CBC_CMAC_256.equals(oid) || ID_CA_ECDH_AES_CBC_CMAC_256.equals(oid)) { return 256; } throw new NumberFormatException("Unknown OID: \"" + oid + "\""); } /** * Returns an ASN1 name for the given EAC-CA protocol identifier. * * @param oid a EAC-CA protocol identifier * * @return an ASN1 name */ private static String toProtocolOIDString(String oid) { if (ID_CA_DH_3DES_CBC_CBC.equals(oid)) { return "id-CA-DH-3DES-CBC-CBC"; } if (ID_CA_DH_AES_CBC_CMAC_128.equals(oid)) { return "id-CA-DH-AES-CBC-CMAC-128"; } if (ID_CA_DH_AES_CBC_CMAC_192.equals(oid)) { return "id-CA-DH-AES-CBC-CMAC-192"; } if (ID_CA_DH_AES_CBC_CMAC_256.equals(oid)) { return "id-CA-DH-AES-CBC-CMAC-256"; } if (ID_CA_ECDH_3DES_CBC_CBC.equals(oid)) { return "id-CA-ECDH-3DES-CBC-CBC"; } if (ID_CA_ECDH_AES_CBC_CMAC_128.equals(oid)) { return "id-CA-ECDH-AES-CBC-CMAC-128"; } if (ID_CA_ECDH_AES_CBC_CMAC_192.equals(oid)) { return "id-CA-ECDH-AES-CBC-CMAC-192"; } if (ID_CA_ECDH_AES_CBC_CMAC_256.equals(oid)) { return "id-CA-ECDH-AES-CBC-CMAC-256"; } return oid; } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy