Add rule for 'All devices apps' when access rule is empty.
[platform/core/connectivity/smartcard-service.git] / common / ISO7816BERTLV.cpp
1 /*
2  * Copyright (c) 2012, 2013 Samsung Electronics Co., Ltd.
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 #include <stdio.h>
18 #include <string.h>
19
20 #include "ISO7816BERTLV.h"
21
22 namespace smartcard_service_api
23 {
24         ISO7816BERTLV::ISO7816BERTLV() : TLVHelper(), firstByte(0), tagClass(0),
25                 encoding(0)
26         {
27         }
28
29         ISO7816BERTLV::ISO7816BERTLV(TLVHelper *parent) : TLVHelper(parent),
30                 firstByte(0), tagClass(0), encoding(0)
31         {
32         }
33
34         ISO7816BERTLV::ISO7816BERTLV(const ByteArray &array) : TLVHelper(array),
35                         firstByte(0), tagClass(0), encoding(0)
36         {
37         }
38
39         ISO7816BERTLV::ISO7816BERTLV(const ByteArray &array, TLVHelper *parent) :
40                 TLVHelper(array, parent), firstByte(0), tagClass(0), encoding(0)
41         {
42         }
43
44         ISO7816BERTLV::~ISO7816BERTLV()
45         {
46                 if (childTLV != NULL)
47                 {
48                         delete childTLV;
49                         childTLV = NULL;
50                 }
51         }
52
53         int ISO7816BERTLV::decodeTag(const unsigned char *buffer)
54         {
55                 /* 0x00 is invalid tag value */
56                 if (buffer[0] == 0x00)
57                 {
58                         return -1;
59                 }
60
61                 /* first byte */
62                 tagClass = (buffer[0] & 0xC0) >> 6;
63                 encoding = (buffer[0] & 0x20) >> 5;
64
65                 currentT = buffer[0];
66
67                 if ((buffer[0] & 0x1F) < 0x1F)
68                 {
69                         return 1;
70                 }
71
72                 /* second byte */
73                 currentT = (currentT << 8) | buffer[1];
74                 if (buffer[1] & 0x80)
75                 {
76                         /* third byte */
77                         if (buffer[2] & 0x80)
78                         {
79                                 return -1;
80                         }
81
82                         currentT = (currentT << 8) | buffer[2];
83
84                         return 3;
85                 }
86
87                 return 2;
88         }
89
90         int ISO7816BERTLV::decodeLength(const unsigned char *buffer)
91         {
92                 if (buffer[0] & 0x80)
93                 {
94                         uint8_t count = (buffer[0] & 0x7F);
95                         uint8_t i;
96
97                         /* count will be less than 5 */
98                         if (count > 4)
99                                 return -1;
100
101                         count++;
102
103                         for (i = 1; i < count; i++)
104                         {
105                                 /* if big endian */
106                                 currentL = (currentL << 8) | buffer[i];
107
108                                 /* if little endian */
109                                 /* currentL = currentL | (buffer[i] << (8 * (i - 1))); */
110                         }
111
112                         return count;
113                 }
114                 else
115                 {
116                         currentL = buffer[0];
117
118                         return 1;
119                 }
120         }
121
122         int ISO7816BERTLV::decodeValue(const unsigned char *buffer)
123         {
124                 if (currentL == 0)
125                         return 0;
126
127                 currentV.assign(buffer, currentL);
128
129                 return currentL;
130         }
131
132         unsigned int ISO7816BERTLV::getClass() const
133         {
134                 return tagClass;
135         }
136
137         unsigned int ISO7816BERTLV::getEncoding() const
138         {
139                 return encoding;
140         }
141
142         const ByteArray ISO7816BERTLV::encode(unsigned int tagClass, unsigned int encoding, unsigned int tag, const ByteArray &buffer)
143         {
144                 unsigned char temp_tag[3] = { 0, };
145                 unsigned char temp_tag_len = 0;
146                 unsigned char temp_len[5] = { 0, };
147                 unsigned char temp_len_len = 0;
148                 ByteArray result;
149                 unsigned int total_len = 0;
150                 unsigned int current = 0;
151                 unsigned char *temp_buffer = NULL;
152
153                 /* add tag's length */
154                 if (tag > 0x7FFF)
155                         return result;
156
157                 temp_tag[0] = (tagClass << 6) | (encoding << 5);
158
159                 if (tag < 0x1F)
160                 {
161                         temp_tag[0] |= tag;
162                         temp_tag_len = 1;
163                 }
164                 else
165                 {
166                         temp_tag[0] |= 0x1F;
167
168                         if (tag < 0x80)
169                         {
170                                 temp_tag[1] = tag;
171
172                                 temp_tag_len = 2;
173                         }
174                         else
175                         {
176                                 temp_tag[1] = (tag & 0x000000FF);
177                                 temp_tag[2] = (tag & 0x0000FF00);
178
179                                 temp_tag_len = 3;
180                         }
181                 }
182
183                 total_len += temp_tag_len;
184
185                 /* add length's length */
186                 if (buffer.size() < 128)
187                 {
188                         temp_len[0] = buffer.size();
189
190                         temp_len_len = 1;
191                 }
192                 else
193                 {
194                         temp_len[0] = 0x80;
195                         temp_len_len = 1;
196
197                         if (buffer.size() > 0x00FFFFFF)
198                         {
199                                 temp_len[4] = (buffer.size() & 0xFF000000) >> 24;
200                                 temp_len_len++;
201                         }
202
203                         if (buffer.size() > 0x0000FFFF)
204                         {
205                                 temp_len[3] = (buffer.size() & 0x00FF0000) >> 16;
206                                 temp_len_len++;
207                         }
208
209                         if (buffer.size() > 0x000000FF)
210                         {
211                                 temp_len[2] = (buffer.size() & 0x0000FF00) >> 8;
212                                 temp_len_len++;
213                         }
214
215                         temp_len[1] = buffer.size() & 0x000000FF;
216                         temp_len_len++;
217
218                         temp_len[0] |= temp_len_len;
219                 }
220
221                 /* add buffer's length */
222                 total_len += buffer.size();
223
224                 /* alloc new buffer */
225                 temp_buffer = new unsigned char[total_len];
226                 if (temp_buffer == NULL)
227                 {
228                         return result;
229                 }
230                 memset(temp_buffer, 0, total_len);
231
232                 /* fill tag */
233                 memcpy(temp_buffer + current, temp_tag, temp_tag_len);
234                 current += temp_tag_len;
235
236                 /* fill length */
237                 memcpy(temp_buffer + current, temp_len, temp_len_len);
238                 current += temp_len_len;
239
240                 /* fill value */
241                 if (buffer.size() > 0)
242                         memcpy(temp_buffer + current, buffer.getBuffer(), buffer.size());
243
244                 result.assign(temp_buffer, total_len);
245
246                 delete []temp_buffer;
247
248                 return result;
249         }
250
251         const ByteArray ISO7816BERTLV::encode(unsigned int tagClass, unsigned int encoding, unsigned int tag, unsigned char *buffer, unsigned int length)
252         {
253                 return encode(tagClass, encoding, tag, ByteArray(buffer, length));
254         }
255
256         TLVHelper *ISO7816BERTLV::getChildTLV(const ByteArray &data)
257         {
258                 if (childTLV != NULL)
259                 {
260                         delete childTLV;
261                         childTLV = NULL;
262                 }
263                 childTLV = new ISO7816BERTLV(data, this);
264
265                 return (TLVHelper *)childTLV;
266         }
267
268 } /* namespace smartcard_service_api */