1 /* 2 * Copyright (C) 2017 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 /* 17 * Copyright (c) 2017, The Linux Foundation. 18 */ 19 20 /* 21 * Copyright 2010 Giesecke & Devrient GmbH. 22 * 23 * Licensed under the Apache License, Version 2.0 (the "License"); 24 * you may not use this file except in compliance with the License. 25 * You may obtain a copy of the License at 26 * 27 * http://www.apache.org/licenses/LICENSE-2.0 28 * 29 * Unless required by applicable law or agreed to in writing, software 30 * distributed under the License is distributed on an "AS IS" BASIS, 31 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 32 * See the License for the specific language governing permissions and 33 * limitations under the License. 34 */ 35 36 package com.android.se.security; 37 38 /** Represents the APDU command splitting all the individual fields */ 39 public class CommandApdu { 40 protected int mCla = 0x00; 41 protected int mIns = 0x00; 42 protected int mP1 = 0x00; 43 protected int mP2 = 0x00; 44 protected int mLc = 0x00; 45 protected byte[] mData = new byte[0]; 46 protected int mLe = 0x00; 47 protected boolean mLeUsed = false; 48 CommandApdu(int cla, int ins, int p1, int p2)49 public CommandApdu(int cla, int ins, int p1, int p2) { 50 mCla = cla; 51 mIns = ins; 52 mP1 = p1; 53 mP2 = p2; 54 } 55 CommandApdu()56 public CommandApdu() { 57 } 58 CommandApdu(int cla, int ins, int p1, int p2, byte[] data)59 public CommandApdu(int cla, int ins, int p1, int p2, byte[] data) { 60 mCla = cla; 61 mIns = ins; 62 mLc = data.length; 63 mP1 = p1; 64 mP2 = p2; 65 mData = data; 66 } 67 CommandApdu(int cla, int ins, int p1, int p2, byte[] data, int le)68 public CommandApdu(int cla, int ins, int p1, int p2, byte[] data, int le) { 69 mCla = cla; 70 mIns = ins; 71 mLc = data.length; 72 mP1 = p1; 73 mP2 = p2; 74 mData = data; 75 mLe = le; 76 mLeUsed = true; 77 } 78 CommandApdu(int cla, int ins, int p1, int p2, int le)79 public CommandApdu(int cla, int ins, int p1, int p2, int le) { 80 mCla = cla; 81 mIns = ins; 82 mP1 = p1; 83 mP2 = p2; 84 mLe = le; 85 mLeUsed = true; 86 } 87 88 /** Returns true if both the headers are same */ compareHeaders(byte[] header1, byte[] mask, byte[] header2)89 public static boolean compareHeaders(byte[] header1, byte[] mask, byte[] header2) { 90 if (header1.length < 4 || header2.length < 4) { 91 return false; 92 } 93 byte[] compHeader = new byte[4]; 94 compHeader[0] = (byte) (header1[0] & mask[0]); 95 compHeader[1] = (byte) (header1[1] & mask[1]); 96 compHeader[2] = (byte) (header1[2] & mask[2]); 97 compHeader[3] = (byte) (header1[3] & mask[3]); 98 99 if (((byte) compHeader[0] == (byte) header2[0]) 100 && ((byte) compHeader[1] == (byte) header2[1]) 101 && ((byte) compHeader[2] == (byte) header2[2]) 102 && ((byte) compHeader[3] == (byte) header2[3])) { 103 return true; 104 } 105 return false; 106 } 107 getP1()108 public int getP1() { 109 return mP1; 110 } 111 setP1(int p1)112 public void setP1(int p1) { 113 mP1 = p1; 114 } 115 getP2()116 public int getP2() { 117 return mP2; 118 } 119 setP2(int p2)120 public void setP2(int p2) { 121 mP2 = p2; 122 } 123 getLc()124 public int getLc() { 125 return mLc; 126 } 127 getData()128 public byte[] getData() { 129 return mData; 130 } 131 132 /** Sets Data field of the APDU */ setData(byte[] data)133 public void setData(byte[] data) { 134 mLc = data.length; 135 mData = data; 136 } 137 getLe()138 public int getLe() { 139 return mLe; 140 } 141 142 /** Sets the Le field of the command */ setLe(int le)143 public void setLe(int le) { 144 mLe = le; 145 mLeUsed = true; 146 } 147 148 /** Returns the APDU in byte[] format */ toBytes()149 public byte[] toBytes() { 150 int length = 4; // CLA, INS, P1, P2 151 if (mData.length != 0) { 152 length += 1; // LC 153 length += mData.length; // DATA 154 } 155 if (mLeUsed) { 156 length += 1; // LE 157 } 158 159 byte[] apdu = new byte[length]; 160 161 int index = 0; 162 apdu[index] = (byte) mCla; 163 index++; 164 apdu[index] = (byte) mIns; 165 index++; 166 apdu[index] = (byte) mP1; 167 index++; 168 apdu[index] = (byte) mP2; 169 index++; 170 if (mData.length != 0) { 171 apdu[index] = (byte) mLc; 172 index++; 173 System.arraycopy(mData, 0, apdu, index, mData.length); 174 index += mData.length; 175 } 176 if (mLeUsed) { 177 apdu[index] += (byte) mLe; // LE 178 } 179 180 return apdu; 181 } 182 183 /** Clones the APDU */ clone()184 public CommandApdu clone() { 185 CommandApdu apdu = new CommandApdu(); 186 apdu.mCla = mCla; 187 apdu.mIns = mIns; 188 apdu.mP1 = mP1; 189 apdu.mP2 = mP2; 190 apdu.mLc = mLc; 191 apdu.mData = new byte[mData.length]; 192 System.arraycopy(mData, 0, apdu.mData, 0, mData.length); 193 apdu.mLe = mLe; 194 apdu.mLeUsed = mLeUsed; 195 return apdu; 196 } 197 } 198