]> git.zerfleddert.de Git - proxmark3-svn/blame - client/emv/emv_pki.c
Cleanup armsrc/string.c and string.h (#964)
[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"
d03fb293 21
d03fb293
OM
22#include <stdlib.h>
23#include <string.h>
24#include <stdarg.h>
3783c45a 25#include "crypto.h"
26#include "dump.h"
27#include "util.h"
28#include "ui.h"
d03fb293 29
95b697f0
OM
30static bool strictExecution = true;
31void PKISetStrictExecution(bool se) {
32 strictExecution = se;
33}
34
d03fb293
OM
35static const unsigned char empty_tlv_value[] = {};
36static const struct tlv empty_tlv = {.tag = 0x0, .len = 0, .value = empty_tlv_value};
37
38static size_t emv_pki_hash_psn[256] = { 0, 0, 11, 2, 17, 2, };
39
40static unsigned char *emv_pki_decode_message(const struct emv_pk *enc_pk,
41 uint8_t msgtype,
42 size_t *len,
43 const struct tlv *cert_tlv,
4cdd63b2 44 int tlv_count,
45 ... /* A list of tlv pointers */
d03fb293
OM
46 )
47{
48 struct crypto_pk *kcp;
49 unsigned char *data;
50 size_t data_len;
51 va_list vl;
52
53 if (!enc_pk)
54 return NULL;
55
56 if (!cert_tlv) {
3783c45a 57 PrintAndLogEx(ERR, "Can't find certificate\n");
d03fb293
OM
58 return NULL;
59 }
60
61 if (cert_tlv->len != enc_pk->mlen) {
3783c45a 62 PrintAndLogEx(ERR, "Certificate length (%zd) not equal key length (%zd)\n", cert_tlv->len, enc_pk->mlen);
d03fb293
OM
63 return NULL;
64 }
65 kcp = crypto_pk_open(enc_pk->pk_algo,
66 enc_pk->modulus, enc_pk->mlen,
67 enc_pk->exp, enc_pk->elen);
68 if (!kcp)
69 return NULL;
70
71 data = crypto_pk_encrypt(kcp, cert_tlv->value, cert_tlv->len, &data_len);
72 crypto_pk_close(kcp);
73
3783c45a 74 /*if (true){
75 PrintAndLogEx(INFO, "Recovered data:\n");
d03fb293
OM
76 dump_buffer(data, data_len, stdout, 0);
77 }*/
fbf77474 78
d03fb293 79 if (data[data_len-1] != 0xbc || data[0] != 0x6a || data[1] != msgtype) {
3783c45a 80 PrintAndLogEx(ERR, "Certificate format\n");
d03fb293
OM
81 free(data);
82 return NULL;
83 }
84
85 size_t hash_pos = emv_pki_hash_psn[msgtype];
86 if (hash_pos == 0 || hash_pos > data_len){
3783c45a 87 PrintAndLogEx(ERR, "Can't get hash position in the certificate\n");
d03fb293
OM
88 free(data);
89 return NULL;
90 }
91
92 struct crypto_hash *ch;
93 ch = crypto_hash_open(data[hash_pos]);
94 if (!ch) {
3783c45a 95 PrintAndLogEx(ERR, "Can't do hash\n");
d03fb293
OM
96 free(data);
97 return NULL;
98 }
99
100 size_t hash_len = crypto_hash_get_size(ch);
101 crypto_hash_write(ch, data + 1, data_len - 2 - hash_len);
102
4cdd63b2 103 va_start(vl, tlv_count);
104 for (int i = 0; i < tlv_count; i++) {
d03fb293
OM
105 const struct tlv *add_tlv = va_arg(vl, const struct tlv *);
106 if (!add_tlv)
4cdd63b2 107 continue;
d03fb293
OM
108
109 crypto_hash_write(ch, add_tlv->value, add_tlv->len);
110 }
111 va_end(vl);
112
4cdd63b2 113 uint8_t hash[hash_len];
114 memset(hash, 0, hash_len);
115 memcpy(hash, crypto_hash_read(ch), hash_len);
116 if (memcmp(data + data_len - 1 - hash_len, hash, hash_len)) {
3783c45a 117 PrintAndLogEx(ERR, "Calculated wrong hash\n");
118 PrintAndLogEx(INFO, "decoded: %s\n",sprint_hex(data + data_len - 1 - hash_len, hash_len));
119 PrintAndLogEx(INFO, "calculated: %s\n",sprint_hex(hash, hash_len));
95b697f0
OM
120
121 if (strictExecution) {
122 crypto_hash_close(ch);
123 free(data);
124 return NULL;
125 }
d03fb293
OM
126 }
127
128 crypto_hash_close(ch);
129
130 *len = data_len - hash_len - 1;
131
132 return data;
133}
134
135static unsigned emv_cn_length(const struct tlv *tlv)
136{
137 int i;
138
139 for (i = 0; i < tlv->len; i++) {
140 unsigned char c = tlv->value[i];
141
142 if (c >> 4 == 0xf)
143 return 2 * i;
144
145 if ((c & 0xf) == 0xf)
146 return 2 * i + 1;
147 }
148
149 return 2 * tlv->len;
150}
151
152static unsigned char emv_cn_get(const struct tlv *tlv, unsigned pos)
153{
154 if (pos > tlv->len * 2)
155 return 0xf;
156
157 unsigned char c = tlv->value[pos / 2];
158
159 if (pos % 2)
160 return c & 0xf;
161 else
162 return c >> 4;
163}
164
165static struct emv_pk *emv_pki_decode_key_ex(const struct emv_pk *enc_pk,
166 unsigned char msgtype,
167 const struct tlv *pan_tlv,
168 const struct tlv *cert_tlv,
169 const struct tlv *exp_tlv,
170 const struct tlv *rem_tlv,
171 const struct tlv *add_tlv,
4cdd63b2 172 const struct tlv *sdatl_tlv,
d03fb293
OM
173 bool showData
174 )
175{
176 size_t pan_length;
177 unsigned char *data;
178 size_t data_len;
179 size_t pk_len;
180
181 if (!cert_tlv || !exp_tlv || !pan_tlv)
182 return NULL;
183
184 if (!rem_tlv)
185 rem_tlv = &empty_tlv;
186
187 if (msgtype == 2)
188 pan_length = 4;
189 else if (msgtype == 4)
190 pan_length = 10;
191 else {
3783c45a 192 PrintAndLogEx(ERR, "Message type must be 2 or 4\n");
d03fb293
OM
193 return NULL;
194 }
195
196 data = emv_pki_decode_message(enc_pk, msgtype, &data_len,
197 cert_tlv,
4cdd63b2 198 5,
d03fb293
OM
199 rem_tlv,
200 exp_tlv,
201 add_tlv,
4cdd63b2 202 sdatl_tlv,
d03fb293
OM
203 NULL);
204 if (!data || data_len < 11 + pan_length) {
3783c45a 205 PrintAndLogEx(ERR, "Can't decode message\n");
d03fb293
OM
206 return NULL;
207 }
208
209 if (showData){
3783c45a 210 PrintAndLogEx(INFO, "Recovered data:\n");
d03fb293
OM
211 dump_buffer(data, data_len, stdout, 0);
212 }
213
214 /* Perform the rest of checks here */
215
216 struct tlv pan2_tlv = {
217 .tag = 0x5a,
218 .len = pan_length,
219 .value = &data[2],
220 };
221 unsigned pan_len = emv_cn_length(pan_tlv);
222 unsigned pan2_len = emv_cn_length(&pan2_tlv);
223
224 if (((msgtype == 2) && (pan2_len < 4 || pan2_len > pan_len)) ||
225 ((msgtype == 4) && (pan2_len != pan_len))) {
3783c45a 226 PrintAndLogEx(ERR, "Invalid PAN lengths\n");
d03fb293
OM
227 free(data);
228
229 return NULL;
230 }
231
232 unsigned i;
233 for (i = 0; i < pan2_len; i++)
234 if (emv_cn_get(pan_tlv, i) != emv_cn_get(&pan2_tlv, i)) {
3783c45a 235 PrintAndLogEx(ERR, "PAN data mismatch\n");
236 PrintAndLogEx(INFO, "tlv pan=%s\n", sprint_hex(pan_tlv->value, pan_tlv->len));
237 PrintAndLogEx(INFO, "cert pan=%s\n", sprint_hex(pan2_tlv.value, pan2_tlv.len));
d03fb293
OM
238 free(data);
239
240 return NULL;
241 }
242
243 pk_len = data[9 + pan_length];
244 if (pk_len > data_len - 11 - pan_length + rem_tlv->len) {
3783c45a 245 PrintAndLogEx(ERR, "Invalid pk length\n");
d03fb293
OM
246 free(data);
247 return NULL;
248 }
249
250 if (exp_tlv->len != data[10 + pan_length]) {
251 free(data);
252 return NULL;
253 }
254
255 struct emv_pk *pk = emv_pk_new(pk_len, exp_tlv->len);
256
257 memcpy(pk->rid, enc_pk->rid, 5);
258 pk->index = enc_pk->index;
259
260 pk->hash_algo = data[7 + pan_length];
261 pk->pk_algo = data[8 + pan_length];
262 pk->expire = (data[3 + pan_length] << 16) | (data[2 + pan_length] << 8) | 0x31;
263 memcpy(pk->serial, data + 4 + pan_length, 3);
264 memcpy(pk->pan, data + 2, pan_length);
265 memset(pk->pan + pan_length, 0xff, 10 - pan_length);
266
267 memcpy(pk->modulus, data + 11 + pan_length,
268 pk_len < data_len - (11 + pan_length) ?
269 pk_len :
270 data_len - (11 + pan_length));
271 memcpy(pk->modulus + data_len - (11 + pan_length), rem_tlv->value, rem_tlv->len);
272 memcpy(pk->exp, exp_tlv->value, exp_tlv->len);
273
274 free(data);
275
276 return pk;
277}
278
279static struct emv_pk *emv_pki_decode_key(const struct emv_pk *enc_pk,
280 unsigned char msgtype,
281 const struct tlv *pan_tlv,
282 const struct tlv *cert_tlv,
283 const struct tlv *exp_tlv,
284 const struct tlv *rem_tlv,
4cdd63b2 285 const struct tlv *add_tlv,
286 const struct tlv *sdatl_tlv
d03fb293 287 ) {
4cdd63b2 288 return emv_pki_decode_key_ex(enc_pk, msgtype, pan_tlv, cert_tlv, exp_tlv, rem_tlv, add_tlv, sdatl_tlv, false);
d03fb293
OM
289}
290
291struct emv_pk *emv_pki_recover_issuer_cert(const struct emv_pk *pk, struct tlvdb *db)
292{
293 return emv_pki_decode_key(pk, 2,
294 tlvdb_get(db, 0x5a, NULL),
295 tlvdb_get(db, 0x90, NULL),
296 tlvdb_get(db, 0x9f32, NULL),
297 tlvdb_get(db, 0x92, NULL),
4cdd63b2 298 NULL,
d03fb293
OM
299 NULL);
300}
301
302struct emv_pk *emv_pki_recover_icc_cert(const struct emv_pk *pk, struct tlvdb *db, const struct tlv *sda_tlv)
303{
4cdd63b2 304 size_t sdatl_len;
305 unsigned char *sdatl = emv_pki_sdatl_fill(db, &sdatl_len);
306 struct tlv sda_tdata = {
307 .tag = 0x00, // dummy tag
308 .len = sdatl_len,
309 .value = sdatl
310 };
311
312 struct emv_pk *res = emv_pki_decode_key(pk, 4,
d03fb293
OM
313 tlvdb_get(db, 0x5a, NULL),
314 tlvdb_get(db, 0x9f46, NULL),
315 tlvdb_get(db, 0x9f47, NULL),
316 tlvdb_get(db, 0x9f48, NULL),
4cdd63b2 317 sda_tlv,
318 &sda_tdata);
319
320 free(sdatl); // malloc here: emv_pki_sdatl_fill
321 return res;
d03fb293
OM
322}
323
324struct emv_pk *emv_pki_recover_icc_pe_cert(const struct emv_pk *pk, struct tlvdb *db)
325{
326 return emv_pki_decode_key(pk, 4,
327 tlvdb_get(db, 0x5a, NULL),
328 tlvdb_get(db, 0x9f2d, NULL),
329 tlvdb_get(db, 0x9f2e, NULL),
330 tlvdb_get(db, 0x9f2f, NULL),
4cdd63b2 331 NULL,
d03fb293
OM
332 NULL);
333}
334
4cdd63b2 335unsigned char *emv_pki_sdatl_fill(const struct tlvdb *db, size_t *sdatl_len) {
336 uint8_t buf[2048] = {0};
337 size_t len = 0;
338
339 *sdatl_len = 0;
340
341 const struct tlv *sda_tl = tlvdb_get(db, 0x9f4a, NULL);
342 if (!sda_tl || sda_tl->len <= 0)
343 return NULL;
344
345 for (int i = 0; i < sda_tl->len; i++) {
346 uint32_t tag = sda_tl->value[i]; // here may be multibyte, but now not
347 const struct tlv *elm = tlvdb_get(db, tag, NULL);
348 if (elm) {
349 memcpy(&buf[len], elm->value, elm->len);
350 len += elm->len;
351 }
352 }
353
354 if (len) {
355 *sdatl_len = len;
356 unsigned char *value = malloc(len);
357 memcpy(value, buf, len);
358 return value;
359 }
360
361 return NULL;
362}
363
364
d03fb293
OM
365struct tlvdb *emv_pki_recover_dac_ex(const struct emv_pk *enc_pk, const struct tlvdb *db, const struct tlv *sda_tlv, bool showData)
366{
367 size_t data_len;
4cdd63b2 368
369 // Static Data Authentication Tag List
370 size_t sdatl_len;
371 unsigned char *sdatl = emv_pki_sdatl_fill(db, &sdatl_len);
372 struct tlv sda_tdata = {
373 .tag = 0x00, // dummy tag
374 .len = sdatl_len,
375 .value = sdatl
376 };
377
d03fb293
OM
378 unsigned char *data = emv_pki_decode_message(enc_pk, 3, &data_len,
379 tlvdb_get(db, 0x93, NULL),
4cdd63b2 380 3,
d03fb293 381 sda_tlv,
4cdd63b2 382 &sda_tdata,
d03fb293
OM
383 NULL);
384
4cdd63b2 385 free(sdatl); // malloc here: emv_pki_sdatl_fill
386
d03fb293
OM
387 if (!data || data_len < 5)
388 return NULL;
389
390 if (showData){
3783c45a 391 PrintAndLogEx(INFO, "Recovered data:\n");
d03fb293
OM
392 dump_buffer(data, data_len, stdout, 0);
393 }
394
395 struct tlvdb *dac_db = tlvdb_fixed(0x9f45, 2, data+3);
396
397 free(data);
398
399 return dac_db;
400}
3783c45a 401
d03fb293
OM
402struct tlvdb *emv_pki_recover_dac(const struct emv_pk *enc_pk, const struct tlvdb *db, const struct tlv *sda_tlv) {
403 return emv_pki_recover_dac_ex(enc_pk, db, sda_tlv, false);
404}
405
406struct tlvdb *emv_pki_recover_idn(const struct emv_pk *enc_pk, const struct tlvdb *db, const struct tlv *dyn_tlv) {
407 return emv_pki_recover_idn_ex(enc_pk, db, dyn_tlv, false);
408}
409
410struct tlvdb *emv_pki_recover_idn_ex(const struct emv_pk *enc_pk, const struct tlvdb *db, const struct tlv *dyn_tlv, bool showData)
411{
412 size_t data_len;
413 unsigned char *data = emv_pki_decode_message(enc_pk, 5, &data_len,
414 tlvdb_get(db, 0x9f4b, NULL),
4cdd63b2 415 2,
d03fb293
OM
416 dyn_tlv,
417 NULL);
418
419 if (!data || data_len < 3)
420 return NULL;
421
422 if (data[3] < 2 || data[3] > data_len - 3) {
423 free(data);
424 return NULL;
425 }
426
427 if (showData){
3783c45a 428 PrintAndLogEx(INFO, "Recovered data:\n");
d03fb293
OM
429 dump_buffer(data, data_len, stdout, 0);
430 }
431
432 size_t idn_len = data[4];
433 if (idn_len > data[3] - 1) {
434 free(data);
435 return NULL;
436 }
437
438 // 9f4c ICC Dynamic Number
439 struct tlvdb *idn_db = tlvdb_fixed(0x9f4c, idn_len, data + 5);
440
441 free(data);
442
443 return idn_db;
444}
445
446struct tlvdb *emv_pki_recover_atc_ex(const struct emv_pk *enc_pk, const struct tlvdb *db, bool showData)
447{
448 size_t data_len;
449 unsigned char *data = emv_pki_decode_message(enc_pk, 5, &data_len,
450 tlvdb_get(db, 0x9f4b, NULL),
4cdd63b2 451 5,
d03fb293
OM
452 tlvdb_get(db, 0x9f37, NULL),
453 tlvdb_get(db, 0x9f02, NULL),
454 tlvdb_get(db, 0x5f2a, NULL),
455 tlvdb_get(db, 0x9f69, NULL),
456 NULL);
457
458 if (!data || data_len < 3)
459 return NULL;
460
461 if (data[3] < 2 || data[3] > data_len - 3) {
462 free(data);
463 return NULL;
464 }
465
466 if (showData){
3783c45a 467 PrintAndLogEx(INFO, "Recovered data:\n");
d03fb293
OM
468 dump_buffer(data, data_len, stdout, 0);
469 }
470
471 size_t idn_len = data[4];
472 if (idn_len > data[3] - 1) {
473 free(data);
474 return NULL;
475 }
476
477 // 9f36 Application Transaction Counter (ATC)
478 struct tlvdb *atc_db = tlvdb_fixed(0x9f36, idn_len, data + 5);
479
480 free(data);
481
482 return atc_db;
483}
484
485static bool tlv_hash(void *data, const struct tlv *tlv, int level, bool is_leaf)
486{
487 struct crypto_hash *ch = data;
488 size_t tag_len;
489 unsigned char *tag;
490
491 if (tlv_is_constructed(tlv))
492 return true;
493
494 if (tlv->tag == 0x9f4b)
495 return true;
496
497 tag = tlv_encode(tlv, &tag_len);
498 crypto_hash_write(ch, tag, tag_len);
499 free(tag);
500
501 return true;
502}
503
504struct tlvdb *emv_pki_perform_cda(const struct emv_pk *enc_pk, const struct tlvdb *db,
505 const struct tlvdb *this_db,
506 const struct tlv *pdol_data_tlv,
507 const struct tlv *crm1_tlv,
508 const struct tlv *crm2_tlv)
509{
510 return emv_pki_perform_cda_ex(enc_pk, db, this_db, pdol_data_tlv, crm1_tlv, crm2_tlv, false);
511}
512struct tlvdb *emv_pki_perform_cda_ex(const struct emv_pk *enc_pk, const struct tlvdb *db,
513 const struct tlvdb *this_db, // AC TLV result
514 const struct tlv *pdol_data_tlv, // PDOL
515 const struct tlv *crm1_tlv, // CDOL1
516 const struct tlv *crm2_tlv, // CDOL2
517 bool showData)
518{
519 const struct tlv *un_tlv = tlvdb_get(db, 0x9f37, NULL);
520 const struct tlv *cid_tlv = tlvdb_get(this_db, 0x9f27, NULL);
521
522 if (!un_tlv || !cid_tlv)
523 return NULL;
524
525 size_t data_len = 0;
526 unsigned char *data = emv_pki_decode_message(enc_pk, 5, &data_len,
527 tlvdb_get(this_db, 0x9f4b, NULL),
4cdd63b2 528 2,
d03fb293
OM
529 un_tlv,
530 NULL);
531 if (!data || data_len < 3) {
3783c45a 532 PrintAndLogEx(ERR, "can't decode message. len %zd\n", data_len);
d03fb293
OM
533 return NULL;
534 }
535
536 if (showData){
3783c45a 537 PrintAndLogEx(INFO, "Recovered data:\n");
d03fb293
OM
538 dump_buffer(data, data_len, stdout, 0);
539 }
540
541 if (data[3] < 30 || data[3] > data_len - 4) {
3783c45a 542 PrintAndLogEx(ERR, "Invalid data length\n");
d03fb293
OM
543 free(data);
544 return NULL;
545 }
546
547 if (!cid_tlv || cid_tlv->len != 1 || cid_tlv->value[0] != data[5 + data[4]]) {
3783c45a 548 PrintAndLogEx(ERR, "CID mismatch\n");
d03fb293
OM
549 free(data);
550 return NULL;
551 }
552
553 struct crypto_hash *ch;
554 ch = crypto_hash_open(enc_pk->hash_algo);
555 if (!ch) {
3783c45a 556 PrintAndLogEx(ERR, "Can't create hash\n");
d03fb293
OM
557 free(data);
558 return NULL;
559 }
560
561 if (pdol_data_tlv)
562 crypto_hash_write(ch, pdol_data_tlv->value, pdol_data_tlv->len);
563 if (crm1_tlv)
564 crypto_hash_write(ch, crm1_tlv->value, crm1_tlv->len);
565 if (crm2_tlv)
566 crypto_hash_write(ch, crm2_tlv->value, crm2_tlv->len);
567
568 tlvdb_visit(this_db, tlv_hash, ch, 0);
569
570 if (memcmp(data + 5 + data[4] + 1 + 8, crypto_hash_read(ch), 20)) {
3783c45a 571 PrintAndLogEx(ERR, "Calculated hash error\n");
d03fb293
OM
572 crypto_hash_close(ch);
573 free(data);
574 return NULL;
575 }
576 crypto_hash_close(ch);
577
578 size_t idn_len = data[4];
579 if (idn_len > data[3] - 1) {
3783c45a 580 PrintAndLogEx(ERR, "Invalid IDN length\n");
d03fb293
OM
581 free(data);
582 return NULL;
583 }
584
585 struct tlvdb *idn_db = tlvdb_fixed(0x9f4c, idn_len, data + 5);
586 free(data);
587
588 return idn_db;
589}
Impressum, Datenschutz