|
1 Upstream fixes already included in the latest community updates to coolkey v1.1.0 |
|
2 |
|
3 Addresses APDU applet issues with card management. |
|
4 |
|
5 --- ORIGINAL/./src/libckyapplet/cky_factory.c 2016-06-24 16:08:04.366910071 -0400 |
|
6 +++ ././src/libckyapplet/cky_factory.c 2016-06-24 12:38:22.645520956 -0400 |
|
7 @@ -25,12 +25,13 @@ |
|
8 * special commands can be issued at any time |
|
9 */ |
|
10 CKYStatus |
|
11 -CKYAPDUFactory_SelectFile(CKYAPDU *apdu, const CKYBuffer *AID) |
|
12 +CKYAPDUFactory_SelectFile(CKYAPDU *apdu, CKYByte p1, CKYByte p2, |
|
13 + const CKYBuffer *AID) |
|
14 { |
|
15 CKYAPDU_SetCLA(apdu, CKY_CLASS_ISO7816); |
|
16 CKYAPDU_SetINS(apdu, CKY_INS_SELECT_FILE); |
|
17 - CKYAPDU_SetP1(apdu, 0x04); |
|
18 - CKYAPDU_SetP2(apdu, 0x00); |
|
19 + CKYAPDU_SetP1(apdu, p1); |
|
20 + CKYAPDU_SetP2(apdu, p2); |
|
21 return CKYAPDU_SetSendDataBuffer(apdu, AID); |
|
22 } |
|
23 |
|
24 @@ -61,7 +62,6 @@ |
|
25 CKYAPDU_SetP2(apdu, 0x7f); |
|
26 return CKYAPDU_SetReceiveLen(apdu, CKY_SIZE_GET_CPLCDATA); |
|
27 } |
|
28 - |
|
29 /* |
|
30 * applet commands must be issued with the appplet selected. |
|
31 */ |
|
32 @@ -131,6 +131,7 @@ |
|
33 return ret; |
|
34 } |
|
35 |
|
36 + |
|
37 CKYStatus |
|
38 CKYAPDUFactory_ComputeCryptFinal(CKYAPDU *apdu, CKYByte keyNumber, |
|
39 CKYByte location, const CKYBuffer *data, const CKYBuffer *sig) |
|
40 @@ -182,6 +183,49 @@ |
|
41 } |
|
42 |
|
43 CKYStatus |
|
44 +CKYAPDUFactory_ComputeECCKeyAgreementOneStep(CKYAPDU *apdu, CKYByte keyNumber, |
|
45 + CKYByte location, |
|
46 + const CKYBuffer *publicData, const CKYBuffer *secretKey) |
|
47 +{ |
|
48 + CKYStatus ret = CKYINVALIDARGS; |
|
49 + CKYSize len; |
|
50 + CKYBuffer buf; |
|
51 + |
|
52 + if (!publicData) |
|
53 + return ret; |
|
54 + |
|
55 + if (!(len = CKYBuffer_Size(publicData))) |
|
56 + return ret; |
|
57 + |
|
58 + CKYAPDU_SetCLA(apdu, CKY_CLASS_COOLKEY); |
|
59 + CKYAPDU_SetINS(apdu, CKY_INS_COMPUTE_ECC_KEY_AGREEMENT); |
|
60 + CKYAPDU_SetP1(apdu, keyNumber); |
|
61 + CKYAPDU_SetP2(apdu, CKY_CIPHER_ONE_STEP); |
|
62 + |
|
63 + CKYBuffer_InitEmpty(&buf); |
|
64 + |
|
65 + ret = CKYBuffer_Reserve(&buf, 3); |
|
66 + |
|
67 + if (ret == CKYSUCCESS) |
|
68 + ret = CKYBuffer_AppendChar(&buf, location); |
|
69 + if (ret == CKYSUCCESS) |
|
70 + ret = CKYBuffer_AppendShort(&buf, (unsigned short)len); |
|
71 + if (ret == CKYSUCCESS) |
|
72 + ret = CKYAPDU_SetSendDataBuffer(apdu, &buf); |
|
73 + if (ret == CKYSUCCESS) |
|
74 + ret = CKYAPDU_AppendSendDataBuffer(apdu, publicData); |
|
75 + if (ret == CKYSUCCESS && secretKey && 0 < (len = CKYBuffer_Size(secretKey))) { |
|
76 + CKYBuffer_Resize(&buf,2); |
|
77 + CKYBuffer_SetShort(&buf, 0, (unsigned short)len); |
|
78 + ret = CKYAPDU_AppendSendDataBuffer(apdu, &buf); |
|
79 + if (ret == CKYSUCCESS) |
|
80 + ret = CKYAPDU_AppendSendDataBuffer(apdu, secretKey); |
|
81 + } |
|
82 + CKYBuffer_FreeData(&buf); |
|
83 + return ret; |
|
84 +} |
|
85 + |
|
86 +CKYStatus |
|
87 CKYAPDUFactory_ComputeCryptOneStep(CKYAPDU *apdu, CKYByte keyNumber, CKYByte mode, |
|
88 CKYByte direction, CKYByte location, |
|
89 const CKYBuffer *idata, const CKYBuffer *sig) |
|
90 @@ -190,8 +234,11 @@ |
|
91 CKYSize len; |
|
92 CKYBuffer buf; |
|
93 |
|
94 - if (!idata || !(len = CKYBuffer_Size(idata)) || location != CKY_DL_APDU) |
|
95 - return ret; |
|
96 + if (!idata) |
|
97 + return ret; |
|
98 + |
|
99 + if (!(len = CKYBuffer_Size(idata)) && location != CKY_DL_OBJECT) |
|
100 + return ret; |
|
101 |
|
102 CKYAPDU_SetCLA(apdu, CKY_CLASS_COOLKEY); |
|
103 CKYAPDU_SetINS(apdu, CKY_INS_COMPUTE_CRYPT); |
|
104 @@ -314,8 +361,6 @@ |
|
105 return CKYSUCCESS; |
|
106 } |
|
107 |
|
108 -/* Future add WriteObject */ |
|
109 - |
|
110 CKYStatus |
|
111 CKYAPDUFactory_CreateObject(CKYAPDU *apdu, unsigned long objectID, CKYSize size, |
|
112 unsigned short readACL, unsigned short writeACL, unsigned short deleteACL) |
|
113 @@ -383,6 +428,49 @@ |
|
114 } |
|
115 |
|
116 CKYStatus |
|
117 +CKYAPDUFactory_ComputeECCSignatureOneStep(CKYAPDU *apdu, CKYByte keyNumber, |
|
118 + CKYByte location, |
|
119 + const CKYBuffer *idata, const CKYBuffer *sig) |
|
120 +{ |
|
121 + CKYStatus ret = CKYINVALIDARGS; |
|
122 + CKYSize len; |
|
123 + CKYBuffer buf; |
|
124 + |
|
125 + if (!idata) |
|
126 + return ret; |
|
127 + |
|
128 + if (!(len = CKYBuffer_Size(idata)) && location != CKY_DL_OBJECT) |
|
129 + return ret; |
|
130 + |
|
131 + CKYAPDU_SetCLA(apdu, CKY_CLASS_COOLKEY); |
|
132 + CKYAPDU_SetINS(apdu, CKY_INS_COMPUTE_ECC_SIGNATURE); |
|
133 + CKYAPDU_SetP1(apdu, keyNumber); |
|
134 + CKYAPDU_SetP2(apdu, CKY_CIPHER_ONE_STEP); |
|
135 + |
|
136 + CKYBuffer_InitEmpty(&buf); |
|
137 + |
|
138 + ret = CKYBuffer_Reserve(&buf, 3); |
|
139 + |
|
140 + if (ret == CKYSUCCESS) |
|
141 + ret = CKYBuffer_AppendChar(&buf, location); |
|
142 + if (ret == CKYSUCCESS) |
|
143 + ret = CKYBuffer_AppendShort(&buf, (unsigned short)len); |
|
144 + if (ret == CKYSUCCESS) |
|
145 + ret = CKYAPDU_SetSendDataBuffer(apdu, &buf); |
|
146 + if (ret == CKYSUCCESS) |
|
147 + ret = CKYAPDU_AppendSendDataBuffer(apdu, idata); |
|
148 + if (ret == CKYSUCCESS && sig && 0 < (len = CKYBuffer_Size(sig))) { |
|
149 + CKYBuffer_Resize(&buf,2); |
|
150 + CKYBuffer_SetShort(&buf, 0, (unsigned short)len); |
|
151 + ret = CKYAPDU_AppendSendDataBuffer(apdu, &buf); |
|
152 + if (ret == CKYSUCCESS) |
|
153 + ret = CKYAPDU_AppendSendDataBuffer(apdu, sig); |
|
154 + } |
|
155 + CKYBuffer_FreeData(&buf); |
|
156 + return ret; |
|
157 +} |
|
158 + |
|
159 +CKYStatus |
|
160 CKYAPDUFactory_ReadObject(CKYAPDU *apdu, unsigned long objectID, |
|
161 CKYOffset offset, CKYByte size) |
|
162 { |
|
163 @@ -419,6 +507,58 @@ |
|
164 } |
|
165 |
|
166 CKYStatus |
|
167 +CKYAPDUFactory_WriteObject(CKYAPDU *apdu, unsigned long objectID, |
|
168 + CKYOffset offset,CKYSize size,CKYBuffer *data) |
|
169 +{ |
|
170 + CKYBuffer buf; |
|
171 + CKYStatus ret = CKYSUCCESS; |
|
172 + unsigned short dataSize = 0; |
|
173 + |
|
174 + CKYAPDU_SetCLA(apdu, CKY_CLASS_COOLKEY); |
|
175 + CKYAPDU_SetINS(apdu, CKY_INS_WRITE_OBJ); |
|
176 + CKYAPDU_SetP1(apdu, 0x00); |
|
177 + CKYAPDU_SetP2(apdu, 0x00); |
|
178 + CKYBuffer_InitEmpty(&buf); |
|
179 + |
|
180 + dataSize = (unsigned short) CKYBuffer_Size(data); |
|
181 + |
|
182 + if(!dataSize) { |
|
183 + ret = CKYINVALIDARGS; |
|
184 + goto fail; |
|
185 + } |
|
186 + |
|
187 + ret = CKYBuffer_AppendLong(&buf,objectID); |
|
188 + if (ret != CKYSUCCESS) { |
|
189 + goto fail; |
|
190 + } |
|
191 + ret = CKYBuffer_AppendLong(&buf,offset); |
|
192 + if (ret != CKYSUCCESS) { |
|
193 + goto fail; |
|
194 + } |
|
195 + ret = CKYBuffer_AppendChar(&buf, size); |
|
196 + if (ret != CKYSUCCESS) { |
|
197 + goto fail; |
|
198 + } |
|
199 + |
|
200 + ret = CKYAPDU_SetSendDataBuffer(apdu,&buf); |
|
201 + |
|
202 + if (ret != CKYSUCCESS) { |
|
203 + goto fail; |
|
204 + } |
|
205 + |
|
206 + ret = CKYAPDU_AppendSendDataBuffer(apdu, data); |
|
207 + |
|
208 + if (ret != CKYSUCCESS) { |
|
209 + goto fail; |
|
210 + } |
|
211 + |
|
212 +fail: |
|
213 + CKYBuffer_FreeData(&buf); |
|
214 + return ret; |
|
215 + |
|
216 +} |
|
217 + |
|
218 +CKYStatus |
|
219 CKYAPDUFactory_ListObjects(CKYAPDU *apdu, CKYByte sequence) |
|
220 { |
|
221 CKYAPDU_SetCLA(apdu, CKY_CLASS_COOLKEY); |
|
222 @@ -519,11 +659,11 @@ |
|
223 } |
|
224 |
|
225 CKYStatus |
|
226 -CACAPDUFactory_SignDecrypt(CKYAPDU *apdu, const CKYBuffer *data) |
|
227 +CACAPDUFactory_SignDecrypt(CKYAPDU *apdu, CKYByte type, const CKYBuffer *data) |
|
228 { |
|
229 CKYAPDU_SetCLA(apdu, CKY_CLASS_ISO7816); |
|
230 CKYAPDU_SetINS(apdu, CAC_INS_SIGN_DECRYPT); |
|
231 - CKYAPDU_SetP1(apdu, 0x00); |
|
232 + CKYAPDU_SetP1(apdu, type); |
|
233 CKYAPDU_SetP2(apdu, 0x00); |
|
234 return CKYAPDU_SetSendDataBuffer(apdu, data); |
|
235 } |
|
236 @@ -539,6 +679,35 @@ |
|
237 } |
|
238 |
|
239 CKYStatus |
|
240 +CACAPDUFactory_ReadFile(CKYAPDU *apdu, unsigned short offset, |
|
241 + CKYByte type, CKYByte count) |
|
242 +{ |
|
243 + CKYStatus ret; |
|
244 + CKYBuffer buf; |
|
245 + |
|
246 + CKYBuffer_InitEmpty(&buf); |
|
247 + CKYAPDU_SetCLA(apdu, CKY_CLASS_GLOBAL_PLATFORM); |
|
248 + CKYAPDU_SetINS(apdu, CAC_INS_READ_FILE); |
|
249 + CKYAPDU_SetP1(apdu, (offset >> 8) & 0xff); |
|
250 + CKYAPDU_SetP2(apdu, offset & 0xff); |
|
251 + ret = CKYBuffer_Reserve(&buf, 2); |
|
252 + if (ret != CKYSUCCESS) { |
|
253 + goto fail; |
|
254 + } |
|
255 + ret = CKYBuffer_AppendChar(&buf, type); |
|
256 + if (ret != CKYSUCCESS) { |
|
257 + goto fail; |
|
258 + } |
|
259 + ret = CKYBuffer_AppendChar(&buf, count); |
|
260 + if (ret != CKYSUCCESS) { |
|
261 + goto fail; |
|
262 + } |
|
263 + ret = CKYAPDU_SetSendDataBuffer(apdu, &buf); |
|
264 +fail: |
|
265 + CKYBuffer_FreeData(&buf); |
|
266 + return ret; |
|
267 +} |
|
268 +CKYStatus |
|
269 CACAPDUFactory_GetProperties(CKYAPDU *apdu) |
|
270 { |
|
271 CKYAPDU_SetCLA(apdu, CKY_CLASS_ISO7816); |
|
272 @@ -549,7 +718,7 @@ |
|
273 } |
|
274 |
|
275 CKYStatus |
|
276 -CACAPDUFactory_VerifyPIN(CKYAPDU *apdu, const char *pin) |
|
277 +CACAPDUFactory_VerifyPIN(CKYAPDU *apdu, CKYByte keyRef, const char *pin) |
|
278 { |
|
279 CKYStatus ret; |
|
280 CKYSize size; |
|
281 @@ -557,7 +726,7 @@ |
|
282 CKYAPDU_SetCLA(apdu, CKY_CLASS_ISO7816); |
|
283 CKYAPDU_SetINS(apdu, CAC_INS_VERIFY_PIN); |
|
284 CKYAPDU_SetP1(apdu, 0x00); |
|
285 - CKYAPDU_SetP2(apdu, 0x00); |
|
286 + CKYAPDU_SetP2(apdu, keyRef); |
|
287 /* no pin, send an empty buffer */ |
|
288 if (!pin) { |
|
289 return CKYAPDU_SetReceiveLen(apdu, 0); |
|
290 @@ -578,3 +747,63 @@ |
|
291 return ret; |
|
292 |
|
293 } |
|
294 + |
|
295 +CKYStatus |
|
296 +PIVAPDUFactory_SignDecrypt(CKYAPDU *apdu, CKYByte chain, CKYByte alg, |
|
297 + CKYByte key, int len, const CKYBuffer *data) |
|
298 +{ |
|
299 + CKYStatus ret; |
|
300 + CKYAPDU_SetCLA(apdu, chain ? CKY_CLASS_ISO7816_CHAIN : |
|
301 + CKY_CLASS_ISO7816); |
|
302 + CKYAPDU_SetINS(apdu, PIV_INS_GEN_AUTHENTICATE); |
|
303 + CKYAPDU_SetP1(apdu, alg); |
|
304 + CKYAPDU_SetP2(apdu, key); |
|
305 + ret = CKYAPDU_SetSendDataBuffer(apdu, data); |
|
306 + if (ret == CKYSUCCESS && chain == 0 && len != 0) { |
|
307 + if (len >= 256) len = 0; |
|
308 + ret = CKYAPDU_AppendReceiveLen(apdu, len); |
|
309 + } |
|
310 + return ret; |
|
311 +} |
|
312 + |
|
313 +CKYStatus |
|
314 +PIVAPDUFactory_GetData(CKYAPDU *apdu, const CKYBuffer *object, CKYByte count) |
|
315 +{ |
|
316 + CKYStatus ret; |
|
317 + CKYBuffer buf; |
|
318 + CKYByte objectSize; |
|
319 + |
|
320 + CKYBuffer_InitEmpty(&buf); |
|
321 + CKYAPDU_SetCLA(apdu, CKY_CLASS_ISO7816); |
|
322 + CKYAPDU_SetINS(apdu, 0xcb); |
|
323 + CKYAPDU_SetP1(apdu, 0x3f); |
|
324 + CKYAPDU_SetP2(apdu, 0xff); |
|
325 + |
|
326 + objectSize = CKYBuffer_Size(object); |
|
327 + |
|
328 + ret = CKYBuffer_Reserve(&buf, 2+objectSize); |
|
329 + if (ret != CKYSUCCESS) { |
|
330 + goto fail; |
|
331 + } |
|
332 + ret = CKYBuffer_AppendChar(&buf, 0x5c); |
|
333 + if (ret != CKYSUCCESS) { |
|
334 + goto fail; |
|
335 + } |
|
336 + ret = CKYBuffer_AppendChar(&buf, objectSize); |
|
337 + if (ret != CKYSUCCESS) { |
|
338 + goto fail; |
|
339 + } |
|
340 + ret = CKYBuffer_AppendCopy(&buf, object); |
|
341 + if (ret != CKYSUCCESS) { |
|
342 + goto fail; |
|
343 + } |
|
344 + ret = CKYAPDU_SetSendDataBuffer(apdu, &buf); |
|
345 + if (ret != CKYSUCCESS) { |
|
346 + goto fail; |
|
347 + } |
|
348 + ret = CKYAPDU_AppendReceiveLen(apdu, count); |
|
349 +fail: |
|
350 + CKYBuffer_FreeData(&buf); |
|
351 + return ret; |
|
352 +} |
|
353 + |