/* * Copyright 2014 Robert Bachmann * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.licel.jcardsim.utils; import javacard.framework.AID; import javacard.framework.ISO7816; import org.bouncycastle.util.encoders.Hex; import java.util.Comparator; /** * Utility methods for dealing with AIDs. */ public final class AIDUtil { private static final Comparator<AID> aidComparator = new Comparator<AID>() { public int compare(AID aid1, AID aid2) { String s1 = (aid1 != null) ? AIDUtil.toString(aid1) : ""; String s2 = (aid1 != null) ? AIDUtil.toString(aid2) : ""; return s1.compareTo(s2); } }; /** * Generate a SELECT APDU for <code>aid</code> * @param aid AID to be selected * @return SELECT APDU (CLA=0x00, INS=0xA4, P1=0x04, P2=0x00, Lc, AID, Le=0x00) * @throws java.lang.NullPointerException if <code>aid</code> is null */ public static byte[] select(AID aid) { if (aid == null) { throw new NullPointerException("aid"); } byte[] aidBuffer = new byte[16]; byte length = aid.getBytes(aidBuffer, (short) 0); byte[] selectCmd = new byte[length + ISO7816.OFFSET_CDATA + 1]; selectCmd[ISO7816.OFFSET_CLA] = ISO7816.CLA_ISO7816; selectCmd[ISO7816.OFFSET_INS] = ISO7816.INS_SELECT; selectCmd[ISO7816.OFFSET_P1] = 0x04; selectCmd[ISO7816.OFFSET_P2] = 0x00; selectCmd[ISO7816.OFFSET_LC] = length; System.arraycopy(aidBuffer, 0, selectCmd, ISO7816.OFFSET_CDATA, length); selectCmd[selectCmd.length - 1] = 0; return selectCmd; } /** * Generate a SELECT APDU for <code>aid</code> * @param aid AID to be selected * @return SELECT APDU (CLA=0x00, INS=0xA4, P1=0x04, P2=0x00, Lc, AID, Le=0x00) * @throws java.lang.IllegalArgumentException if <code>aid</code> is invalid * @throws java.lang.NullPointerException if <code>aid</code> is null */ public static byte[] select(String aid) { if (aid == null) { throw new NullPointerException("aid"); } byte[] aidBuffer = ByteUtil.byteArray(aid); if (aidBuffer.length > 16) { throw new IllegalArgumentException("AID must not be larger than 16 bytes: " + ByteUtil.hexString(aidBuffer)); } byte[] selectCmd = new byte[aidBuffer.length + ISO7816.OFFSET_CDATA + 1]; selectCmd[ISO7816.OFFSET_CLA] = ISO7816.CLA_ISO7816; selectCmd[ISO7816.OFFSET_INS] = ISO7816.INS_SELECT; selectCmd[ISO7816.OFFSET_P1] = 0x04; selectCmd[ISO7816.OFFSET_P2] = 0x00; selectCmd[ISO7816.OFFSET_LC] = (byte) aidBuffer.length; System.arraycopy(aidBuffer, 0, selectCmd, ISO7816.OFFSET_CDATA, aidBuffer.length); selectCmd[selectCmd.length - 1] = 0; return selectCmd; } /** * Create an AID from a byte array * @param aidBytes AID bytes * @return aid * @throws java.lang.NullPointerException if <code>aidBytes</code> is null * @throws java.lang.IllegalArgumentException if <code>aidBytes.length</code> is incorrect */ public static AID create(byte[] aidBytes) { if (aidBytes == null) { throw new NullPointerException("aidString"); } if (aidBytes.length < 5 || aidBytes.length > 16) { throw new IllegalArgumentException("AID size must be between 5 and 16 but was " + aidBytes.length); } return new AID(aidBytes, (short) 0, (byte) aidBytes.length); } /** * Create an AID from a byte array * @param aidString AID bytes as hex string * @return aid * @throws java.lang.NullPointerException if <code>aidString</code> is null * @throws java.lang.IllegalArgumentException if length is incorrect */ public static AID create(String aidString) { if (aidString == null) { throw new NullPointerException("aidString"); } return create(Hex.decode(aidString)); } /** * Convert AID to hex-string * @param aid AID to convert * @return hex string * @throws java.lang.NullPointerException if <code>aid</code> is null */ public static String toString(AID aid) { if (aid == null) { throw new NullPointerException("aid"); } byte[] buffer = new byte[16]; short len = aid.getBytes(buffer, (short) 0); return ByteUtil.hexString(buffer, 0, len); } /** * @return a Comparator for AIDs */ public static Comparator<AID> comparator() { return aidComparator; } private AIDUtil() {} }