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