]> git.zerfleddert.de Git - proxmark3-svn/blame - client/emv/emv_pki.c
added destroy
[proxmark3-svn] / client / emv / emv_pki.c
CommitLineData
d03fb293
OM
1/*
2 * libopenemv - a library to work with EMV family of smart cards
3 * Copyright (C) 2015 Dmitry Eremin-Solenikov
4 *
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2.1 of the License, or (at your option) any later version.
9 *
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
14 */
15
16#ifdef HAVE_CONFIG_H
17#include <config.h>
18#endif
19
20#include "emv_pki.h"
21#include "crypto.h"
22#include "dump.h"
23#include "util.h"
24
25#include <stdio.h>
26#include <stdlib.h>
27#include <string.h>
28#include <stdarg.h>
29
30static const unsigned char empty_tlv_value[] = {};
31static const struct tlv empty_tlv = {.tag = 0x0, .len = 0, .value = empty_tlv_value};
32
33static size_t emv_pki_hash_psn[256] = { 0, 0, 11, 2, 17, 2, };
34
35static unsigned char *emv_pki_decode_message(const struct emv_pk *enc_pk,
36 uint8_t msgtype,
37 size_t *len,
38 const struct tlv *cert_tlv,
39 ... /* A list of tlv pointers, end with NULL */
40 )
41{
42 struct crypto_pk *kcp;
43 unsigned char *data;
44 size_t data_len;
45 va_list vl;
46
47 if (!enc_pk)
48 return NULL;
49
50 if (!cert_tlv) {
51 printf("ERROR: Can't find certificate\n");
52 return NULL;
53 }
54
55 if (cert_tlv->len != enc_pk->mlen) {
b838c4ff 56 printf("ERROR: Certificate length (%zd) not equal key length (%zd)\n", cert_tlv->len, enc_pk->mlen);
d03fb293
OM
57 return NULL;
58 }
59 kcp = crypto_pk_open(enc_pk->pk_algo,
60 enc_pk->modulus, enc_pk->mlen,
61 enc_pk->exp, enc_pk->elen);
62 if (!kcp)
63 return NULL;
64
65 data = crypto_pk_encrypt(kcp, cert_tlv->value, cert_tlv->len, &data_len);
66 crypto_pk_close(kcp);
67
68/* if (true){
69 printf("Recovered data:\n");
70 dump_buffer(data, data_len, stdout, 0);
71 }*/
72
73 if (data[data_len-1] != 0xbc || data[0] != 0x6a || data[1] != msgtype) {
74 printf("ERROR: Certificate format\n");
75 free(data);
76 return NULL;
77 }
78
79 size_t hash_pos = emv_pki_hash_psn[msgtype];
80 if (hash_pos == 0 || hash_pos > data_len){
81 printf("ERROR: Cant get hash position in the certificate\n");
82 free(data);
83 return NULL;
84 }
85
86 struct crypto_hash *ch;
87 ch = crypto_hash_open(data[hash_pos]);
88 if (!ch) {
89 printf("ERROR: Cant do hash\n");
90 free(data);
91 return NULL;
92 }
93
94 size_t hash_len = crypto_hash_get_size(ch);
95 crypto_hash_write(ch, data + 1, data_len - 2 - hash_len);
96
97 va_start(vl, cert_tlv);
98 while (true) {
99 const struct tlv *add_tlv = va_arg(vl, const struct tlv *);
100 if (!add_tlv)
101 break;
102
103 crypto_hash_write(ch, add_tlv->value, add_tlv->len);
104 }
105 va_end(vl);
106
107 if (memcmp(data + data_len - 1 - hash_len, crypto_hash_read(ch), hash_len)) {
108 printf("ERROR: Calculated wrong hash\n");
109 printf("decoded: %s\n",sprint_hex(data + data_len - 1 - hash_len, hash_len));
110 printf("calculated: %s\n",sprint_hex(crypto_hash_read(ch), hash_len));
111 crypto_hash_close(ch);
112 free(data);
113 return NULL;
114 }
115
116 crypto_hash_close(ch);
117
118 *len = data_len - hash_len - 1;
119
120 return data;
121}
122
123static unsigned emv_cn_length(const struct tlv *tlv)
124{
125 int i;
126
127 for (i = 0; i < tlv->len; i++) {
128 unsigned char c = tlv->value[i];
129
130 if (c >> 4 == 0xf)
131 return 2 * i;
132
133 if ((c & 0xf) == 0xf)
134 return 2 * i + 1;
135 }
136
137 return 2 * tlv->len;
138}
139
140static unsigned char emv_cn_get(const struct tlv *tlv, unsigned pos)
141{
142 if (pos > tlv->len * 2)
143 return 0xf;
144
145 unsigned char c = tlv->value[pos / 2];
146
147 if (pos % 2)
148 return c & 0xf;
149 else
150 return c >> 4;
151}
152
153static struct emv_pk *emv_pki_decode_key_ex(const struct emv_pk *enc_pk,
154 unsigned char msgtype,
155 const struct tlv *pan_tlv,
156 const struct tlv *cert_tlv,
157 const struct tlv *exp_tlv,
158 const struct tlv *rem_tlv,
159 const struct tlv *add_tlv,
160 bool showData
161 )
162{
163 size_t pan_length;
164 unsigned char *data;
165 size_t data_len;
166 size_t pk_len;
167
168 if (!cert_tlv || !exp_tlv || !pan_tlv)
169 return NULL;
170
171 if (!rem_tlv)
172 rem_tlv = &empty_tlv;
173
174 if (msgtype == 2)
175 pan_length = 4;
176 else if (msgtype == 4)
177 pan_length = 10;
178 else {
179 printf("ERROR: Message type must be 2 or 4\n");
180 return NULL;
181 }
182
183 data = emv_pki_decode_message(enc_pk, msgtype, &data_len,
184 cert_tlv,
185 rem_tlv,
186 exp_tlv,
187 add_tlv,
188 NULL);
189 if (!data || data_len < 11 + pan_length) {
190 printf("ERROR: Can't decode message\n");
191 return NULL;
192 }
193
194 if (showData){
195 printf("Recovered data:\n");
196 dump_buffer(data, data_len, stdout, 0);
197 }
198
199 /* Perform the rest of checks here */
200
201 struct tlv pan2_tlv = {
202 .tag = 0x5a,
203 .len = pan_length,
204 .value = &data[2],
205 };
206 unsigned pan_len = emv_cn_length(pan_tlv);
207 unsigned pan2_len = emv_cn_length(&pan2_tlv);
208
209 if (((msgtype == 2) && (pan2_len < 4 || pan2_len > pan_len)) ||
210 ((msgtype == 4) && (pan2_len != pan_len))) {
211 printf("ERROR: Invalid PAN lengths\n");
212 free(data);
213
214 return NULL;
215 }
216
217 unsigned i;
218 for (i = 0; i < pan2_len; i++)
219 if (emv_cn_get(pan_tlv, i) != emv_cn_get(&pan2_tlv, i)) {
220 printf("ERROR: PAN data mismatch\n");
221 printf("tlv pan=%s\n", sprint_hex(pan_tlv->value, pan_tlv->len));
222 printf("cert pan=%s\n", sprint_hex(pan2_tlv.value, pan2_tlv.len));
223 free(data);
224
225 return NULL;
226 }
227
228 pk_len = data[9 + pan_length];
229 if (pk_len > data_len - 11 - pan_length + rem_tlv->len) {
230 printf("ERROR: Invalid pk length\n");
231 free(data);
232 return NULL;
233 }
234
235 if (exp_tlv->len != data[10 + pan_length]) {
236 free(data);
237 return NULL;
238 }
239
240 struct emv_pk *pk = emv_pk_new(pk_len, exp_tlv->len);
241
242 memcpy(pk->rid, enc_pk->rid, 5);
243 pk->index = enc_pk->index;
244
245 pk->hash_algo = data[7 + pan_length];
246 pk->pk_algo = data[8 + pan_length];
247 pk->expire = (data[3 + pan_length] << 16) | (data[2 + pan_length] << 8) | 0x31;
248 memcpy(pk->serial, data + 4 + pan_length, 3);
249 memcpy(pk->pan, data + 2, pan_length);
250 memset(pk->pan + pan_length, 0xff, 10 - pan_length);
251
252 memcpy(pk->modulus, data + 11 + pan_length,
253 pk_len < data_len - (11 + pan_length) ?
254 pk_len :
255 data_len - (11 + pan_length));
256 memcpy(pk->modulus + data_len - (11 + pan_length), rem_tlv->value, rem_tlv->len);
257 memcpy(pk->exp, exp_tlv->value, exp_tlv->len);
258
259 free(data);
260
261 return pk;
262}
263
264static struct emv_pk *emv_pki_decode_key(const struct emv_pk *enc_pk,
265 unsigned char msgtype,
266 const struct tlv *pan_tlv,
267 const struct tlv *cert_tlv,
268 const struct tlv *exp_tlv,
269 const struct tlv *rem_tlv,
270 const struct tlv *add_tlv
271 ) {
272 return emv_pki_decode_key_ex(enc_pk, msgtype, pan_tlv, cert_tlv, exp_tlv, rem_tlv, add_tlv, false);
273}
274
275struct emv_pk *emv_pki_recover_issuer_cert(const struct emv_pk *pk, struct tlvdb *db)
276{
277 return emv_pki_decode_key(pk, 2,
278 tlvdb_get(db, 0x5a, NULL),
279 tlvdb_get(db, 0x90, NULL),
280 tlvdb_get(db, 0x9f32, NULL),
281 tlvdb_get(db, 0x92, NULL),
282 NULL);
283}
284
285struct emv_pk *emv_pki_recover_icc_cert(const struct emv_pk *pk, struct tlvdb *db, const struct tlv *sda_tlv)
286{
287 return emv_pki_decode_key(pk, 4,
288 tlvdb_get(db, 0x5a, NULL),
289 tlvdb_get(db, 0x9f46, NULL),
290 tlvdb_get(db, 0x9f47, NULL),
291 tlvdb_get(db, 0x9f48, NULL),
292 sda_tlv);
293}
294
295struct emv_pk *emv_pki_recover_icc_pe_cert(const struct emv_pk *pk, struct tlvdb *db)
296{
297 return emv_pki_decode_key(pk, 4,
298 tlvdb_get(db, 0x5a, NULL),
299 tlvdb_get(db, 0x9f2d, NULL),
300 tlvdb_get(db, 0x9f2e, NULL),
301 tlvdb_get(db, 0x9f2f, NULL),
302 NULL);
303}
304
305struct tlvdb *emv_pki_recover_dac_ex(const struct emv_pk *enc_pk, const struct tlvdb *db, const struct tlv *sda_tlv, bool showData)
306{
307 size_t data_len;
308 unsigned char *data = emv_pki_decode_message(enc_pk, 3, &data_len,
309 tlvdb_get(db, 0x93, NULL),
310 sda_tlv,
311 NULL);
312
313 if (!data || data_len < 5)
314 return NULL;
315
316 if (showData){
317 printf("Recovered data:\n");
318 dump_buffer(data, data_len, stdout, 0);
319 }
320
321 struct tlvdb *dac_db = tlvdb_fixed(0x9f45, 2, data+3);
322
323 free(data);
324
325 return dac_db;
326}
327struct tlvdb *emv_pki_recover_dac(const struct emv_pk *enc_pk, const struct tlvdb *db, const struct tlv *sda_tlv) {
328 return emv_pki_recover_dac_ex(enc_pk, db, sda_tlv, false);
329}
330
331struct tlvdb *emv_pki_recover_idn(const struct emv_pk *enc_pk, const struct tlvdb *db, const struct tlv *dyn_tlv) {
332 return emv_pki_recover_idn_ex(enc_pk, db, dyn_tlv, false);
333}
334
335struct tlvdb *emv_pki_recover_idn_ex(const struct emv_pk *enc_pk, const struct tlvdb *db, const struct tlv *dyn_tlv, bool showData)
336{
337 size_t data_len;
338 unsigned char *data = emv_pki_decode_message(enc_pk, 5, &data_len,
339 tlvdb_get(db, 0x9f4b, NULL),
340 dyn_tlv,
341 NULL);
342
343 if (!data || data_len < 3)
344 return NULL;
345
346 if (data[3] < 2 || data[3] > data_len - 3) {
347 free(data);
348 return NULL;
349 }
350
351 if (showData){
352 printf("Recovered data:\n");
353 dump_buffer(data, data_len, stdout, 0);
354 }
355
356 size_t idn_len = data[4];
357 if (idn_len > data[3] - 1) {
358 free(data);
359 return NULL;
360 }
361
362 // 9f4c ICC Dynamic Number
363 struct tlvdb *idn_db = tlvdb_fixed(0x9f4c, idn_len, data + 5);
364
365 free(data);
366
367 return idn_db;
368}
369
370struct tlvdb *emv_pki_recover_atc_ex(const struct emv_pk *enc_pk, const struct tlvdb *db, bool showData)
371{
372 size_t data_len;
373 unsigned char *data = emv_pki_decode_message(enc_pk, 5, &data_len,
374 tlvdb_get(db, 0x9f4b, NULL),
375 tlvdb_get(db, 0x9f37, NULL),
376 tlvdb_get(db, 0x9f02, NULL),
377 tlvdb_get(db, 0x5f2a, NULL),
378 tlvdb_get(db, 0x9f69, NULL),
379 NULL);
380
381 if (!data || data_len < 3)
382 return NULL;
383
384 if (data[3] < 2 || data[3] > data_len - 3) {
385 free(data);
386 return NULL;
387 }
388
389 if (showData){
390 printf("Recovered data:\n");
391 dump_buffer(data, data_len, stdout, 0);
392 }
393
394 size_t idn_len = data[4];
395 if (idn_len > data[3] - 1) {
396 free(data);
397 return NULL;
398 }
399
400 // 9f36 Application Transaction Counter (ATC)
401 struct tlvdb *atc_db = tlvdb_fixed(0x9f36, idn_len, data + 5);
402
403 free(data);
404
405 return atc_db;
406}
407
408static bool tlv_hash(void *data, const struct tlv *tlv, int level, bool is_leaf)
409{
410 struct crypto_hash *ch = data;
411 size_t tag_len;
412 unsigned char *tag;
413
414 if (tlv_is_constructed(tlv))
415 return true;
416
417 if (tlv->tag == 0x9f4b)
418 return true;
419
420 tag = tlv_encode(tlv, &tag_len);
421 crypto_hash_write(ch, tag, tag_len);
422 free(tag);
423
424 return true;
425}
426
427struct tlvdb *emv_pki_perform_cda(const struct emv_pk *enc_pk, const struct tlvdb *db,
428 const struct tlvdb *this_db,
429 const struct tlv *pdol_data_tlv,
430 const struct tlv *crm1_tlv,
431 const struct tlv *crm2_tlv)
432{
433 return emv_pki_perform_cda_ex(enc_pk, db, this_db, pdol_data_tlv, crm1_tlv, crm2_tlv, false);
434}
435struct tlvdb *emv_pki_perform_cda_ex(const struct emv_pk *enc_pk, const struct tlvdb *db,
436 const struct tlvdb *this_db, // AC TLV result
437 const struct tlv *pdol_data_tlv, // PDOL
438 const struct tlv *crm1_tlv, // CDOL1
439 const struct tlv *crm2_tlv, // CDOL2
440 bool showData)
441{
442 const struct tlv *un_tlv = tlvdb_get(db, 0x9f37, NULL);
443 const struct tlv *cid_tlv = tlvdb_get(this_db, 0x9f27, NULL);
444
445 if (!un_tlv || !cid_tlv)
446 return NULL;
447
448 size_t data_len = 0;
449 unsigned char *data = emv_pki_decode_message(enc_pk, 5, &data_len,
450 tlvdb_get(this_db, 0x9f4b, NULL),
451 un_tlv,
452 NULL);
453 if (!data || data_len < 3) {
b838c4ff 454 printf("ERROR: can't decode message. len %zd\n", data_len);
d03fb293
OM
455 return NULL;
456 }
457
458 if (showData){
459 printf("Recovered data:\n");
460 dump_buffer(data, data_len, stdout, 0);
461 }
462
463 if (data[3] < 30 || data[3] > data_len - 4) {
464 printf("ERROR: Invalid data length\n");
465 free(data);
466 return NULL;
467 }
468
469 if (!cid_tlv || cid_tlv->len != 1 || cid_tlv->value[0] != data[5 + data[4]]) {
470 printf("ERROR: CID mismatch\n");
471 free(data);
472 return NULL;
473 }
474
475 struct crypto_hash *ch;
476 ch = crypto_hash_open(enc_pk->hash_algo);
477 if (!ch) {
478 printf("ERROR: can't create hash\n");
479 free(data);
480 return NULL;
481 }
482
483 if (pdol_data_tlv)
484 crypto_hash_write(ch, pdol_data_tlv->value, pdol_data_tlv->len);
485 if (crm1_tlv)
486 crypto_hash_write(ch, crm1_tlv->value, crm1_tlv->len);
487 if (crm2_tlv)
488 crypto_hash_write(ch, crm2_tlv->value, crm2_tlv->len);
489
490 tlvdb_visit(this_db, tlv_hash, ch, 0);
491
492 if (memcmp(data + 5 + data[4] + 1 + 8, crypto_hash_read(ch), 20)) {
493 printf("ERROR: calculated hash error\n");
494 crypto_hash_close(ch);
495 free(data);
496 return NULL;
497 }
498 crypto_hash_close(ch);
499
500 size_t idn_len = data[4];
501 if (idn_len > data[3] - 1) {
502 printf("ERROR: Invalid IDN length\n");
503 free(data);
504 return NULL;
505 }
506
507 struct tlvdb *idn_db = tlvdb_fixed(0x9f4c, idn_len, data + 5);
508 free(data);
509
510 return idn_db;
511}
Impressum, Datenschutz