]>
git.zerfleddert.de Git - proxmark3-svn/blob - client/emv/emv_pki.c
da102291876fd69a29dcd4a78585dd6074ecb2e5
2 * libopenemv - a library to work with EMV family of smart cards
3 * Copyright (C) 2015 Dmitry Eremin-Solenikov
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.
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.
30 static bool strictExecution
= true;
31 void PKISetStrictExecution(bool se
) {
35 static const unsigned char empty_tlv_value
[] = {};
36 static const struct tlv empty_tlv
= {.tag
= 0x0, .len
= 0, .value
= empty_tlv_value
};
38 static size_t emv_pki_hash_psn
[256] = { 0, 0, 11, 2, 17, 2, };
40 static unsigned char *emv_pki_decode_message(const struct emv_pk
*enc_pk
,
43 const struct tlv
*cert_tlv
,
44 ... /* A list of tlv pointers, end with NULL */
47 struct crypto_pk
*kcp
;
56 printf("ERROR: Can't find certificate\n");
60 if (cert_tlv
->len
!= enc_pk
->mlen
) {
61 printf("ERROR: Certificate length (%zd) not equal key length (%zd)\n", cert_tlv
->len
, enc_pk
->mlen
);
64 kcp
= crypto_pk_open(enc_pk
->pk_algo
,
65 enc_pk
->modulus
, enc_pk
->mlen
,
66 enc_pk
->exp
, enc_pk
->elen
);
70 data
= crypto_pk_encrypt(kcp
, cert_tlv
->value
, cert_tlv
->len
, &data_len
);
74 printf("Recovered data:\n");
75 dump_buffer(data, data_len, stdout, 0);
78 if (data
[data_len
-1] != 0xbc || data
[0] != 0x6a || data
[1] != msgtype
) {
79 printf("ERROR: Certificate format\n");
84 size_t hash_pos
= emv_pki_hash_psn
[msgtype
];
85 if (hash_pos
== 0 || hash_pos
> data_len
){
86 printf("ERROR: Cant get hash position in the certificate\n");
91 struct crypto_hash
*ch
;
92 ch
= crypto_hash_open(data
[hash_pos
]);
94 printf("ERROR: Cant do hash\n");
99 size_t hash_len
= crypto_hash_get_size(ch
);
100 crypto_hash_write(ch
, data
+ 1, data_len
- 2 - hash_len
);
102 va_start(vl
, cert_tlv
);
104 const struct tlv
*add_tlv
= va_arg(vl
, const struct tlv
*);
108 crypto_hash_write(ch
, add_tlv
->value
, add_tlv
->len
);
112 if (memcmp(data
+ data_len
- 1 - hash_len
, crypto_hash_read(ch
), hash_len
)) {
113 printf("ERROR: Calculated wrong hash\n");
114 printf("decoded: %s\n",sprint_hex(data
+ data_len
- 1 - hash_len
, hash_len
));
115 printf("calculated: %s\n",sprint_hex(crypto_hash_read(ch
), hash_len
));
117 if (strictExecution
) {
118 crypto_hash_close(ch
);
124 crypto_hash_close(ch
);
126 *len
= data_len
- hash_len
- 1;
131 static unsigned emv_cn_length(const struct tlv
*tlv
)
135 for (i
= 0; i
< tlv
->len
; i
++) {
136 unsigned char c
= tlv
->value
[i
];
141 if ((c
& 0xf) == 0xf)
148 static unsigned char emv_cn_get(const struct tlv
*tlv
, unsigned pos
)
150 if (pos
> tlv
->len
* 2)
153 unsigned char c
= tlv
->value
[pos
/ 2];
161 static struct emv_pk
*emv_pki_decode_key_ex(const struct emv_pk
*enc_pk
,
162 unsigned char msgtype
,
163 const struct tlv
*pan_tlv
,
164 const struct tlv
*cert_tlv
,
165 const struct tlv
*exp_tlv
,
166 const struct tlv
*rem_tlv
,
167 const struct tlv
*add_tlv
,
176 if (!cert_tlv
|| !exp_tlv
|| !pan_tlv
)
180 rem_tlv
= &empty_tlv
;
184 else if (msgtype
== 4)
187 printf("ERROR: Message type must be 2 or 4\n");
191 data
= emv_pki_decode_message(enc_pk
, msgtype
, &data_len
,
197 if (!data
|| data_len
< 11 + pan_length
) {
198 printf("ERROR: Can't decode message\n");
203 printf("Recovered data:\n");
204 dump_buffer(data
, data_len
, stdout
, 0);
207 /* Perform the rest of checks here */
209 struct tlv pan2_tlv
= {
214 unsigned pan_len
= emv_cn_length(pan_tlv
);
215 unsigned pan2_len
= emv_cn_length(&pan2_tlv
);
217 if (((msgtype
== 2) && (pan2_len
< 4 || pan2_len
> pan_len
)) ||
218 ((msgtype
== 4) && (pan2_len
!= pan_len
))) {
219 printf("ERROR: Invalid PAN lengths\n");
226 for (i
= 0; i
< pan2_len
; i
++)
227 if (emv_cn_get(pan_tlv
, i
) != emv_cn_get(&pan2_tlv
, i
)) {
228 printf("ERROR: PAN data mismatch\n");
229 printf("tlv pan=%s\n", sprint_hex(pan_tlv
->value
, pan_tlv
->len
));
230 printf("cert pan=%s\n", sprint_hex(pan2_tlv
.value
, pan2_tlv
.len
));
236 pk_len
= data
[9 + pan_length
];
237 if (pk_len
> data_len
- 11 - pan_length
+ rem_tlv
->len
) {
238 printf("ERROR: Invalid pk length\n");
243 if (exp_tlv
->len
!= data
[10 + pan_length
]) {
248 struct emv_pk
*pk
= emv_pk_new(pk_len
, exp_tlv
->len
);
250 memcpy(pk
->rid
, enc_pk
->rid
, 5);
251 pk
->index
= enc_pk
->index
;
253 pk
->hash_algo
= data
[7 + pan_length
];
254 pk
->pk_algo
= data
[8 + pan_length
];
255 pk
->expire
= (data
[3 + pan_length
] << 16) | (data
[2 + pan_length
] << 8) | 0x31;
256 memcpy(pk
->serial
, data
+ 4 + pan_length
, 3);
257 memcpy(pk
->pan
, data
+ 2, pan_length
);
258 memset(pk
->pan
+ pan_length
, 0xff, 10 - pan_length
);
260 memcpy(pk
->modulus
, data
+ 11 + pan_length
,
261 pk_len
< data_len
- (11 + pan_length
) ?
263 data_len
- (11 + pan_length
));
264 memcpy(pk
->modulus
+ data_len
- (11 + pan_length
), rem_tlv
->value
, rem_tlv
->len
);
265 memcpy(pk
->exp
, exp_tlv
->value
, exp_tlv
->len
);
272 static struct emv_pk
*emv_pki_decode_key(const struct emv_pk
*enc_pk
,
273 unsigned char msgtype
,
274 const struct tlv
*pan_tlv
,
275 const struct tlv
*cert_tlv
,
276 const struct tlv
*exp_tlv
,
277 const struct tlv
*rem_tlv
,
278 const struct tlv
*add_tlv
280 return emv_pki_decode_key_ex(enc_pk
, msgtype
, pan_tlv
, cert_tlv
, exp_tlv
, rem_tlv
, add_tlv
, false);
283 struct emv_pk
*emv_pki_recover_issuer_cert(const struct emv_pk
*pk
, struct tlvdb
*db
)
285 return emv_pki_decode_key(pk
, 2,
286 tlvdb_get(db
, 0x5a, NULL
),
287 tlvdb_get(db
, 0x90, NULL
),
288 tlvdb_get(db
, 0x9f32, NULL
),
289 tlvdb_get(db
, 0x92, NULL
),
293 struct emv_pk
*emv_pki_recover_icc_cert(const struct emv_pk
*pk
, struct tlvdb
*db
, const struct tlv
*sda_tlv
)
295 return emv_pki_decode_key(pk
, 4,
296 tlvdb_get(db
, 0x5a, NULL
),
297 tlvdb_get(db
, 0x9f46, NULL
),
298 tlvdb_get(db
, 0x9f47, NULL
),
299 tlvdb_get(db
, 0x9f48, NULL
),
303 struct emv_pk
*emv_pki_recover_icc_pe_cert(const struct emv_pk
*pk
, struct tlvdb
*db
)
305 return emv_pki_decode_key(pk
, 4,
306 tlvdb_get(db
, 0x5a, NULL
),
307 tlvdb_get(db
, 0x9f2d, NULL
),
308 tlvdb_get(db
, 0x9f2e, NULL
),
309 tlvdb_get(db
, 0x9f2f, NULL
),
313 struct tlvdb
*emv_pki_recover_dac_ex(const struct emv_pk
*enc_pk
, const struct tlvdb
*db
, const struct tlv
*sda_tlv
, bool showData
)
316 unsigned char *data
= emv_pki_decode_message(enc_pk
, 3, &data_len
,
317 tlvdb_get(db
, 0x93, NULL
),
321 if (!data
|| data_len
< 5)
325 printf("Recovered data:\n");
326 dump_buffer(data
, data_len
, stdout
, 0);
329 struct tlvdb
*dac_db
= tlvdb_fixed(0x9f45, 2, data
+3);
335 struct tlvdb
*emv_pki_recover_dac(const struct emv_pk
*enc_pk
, const struct tlvdb
*db
, const struct tlv
*sda_tlv
) {
336 return emv_pki_recover_dac_ex(enc_pk
, db
, sda_tlv
, false);
339 struct tlvdb
*emv_pki_recover_idn(const struct emv_pk
*enc_pk
, const struct tlvdb
*db
, const struct tlv
*dyn_tlv
) {
340 return emv_pki_recover_idn_ex(enc_pk
, db
, dyn_tlv
, false);
343 struct tlvdb
*emv_pki_recover_idn_ex(const struct emv_pk
*enc_pk
, const struct tlvdb
*db
, const struct tlv
*dyn_tlv
, bool showData
)
346 unsigned char *data
= emv_pki_decode_message(enc_pk
, 5, &data_len
,
347 tlvdb_get(db
, 0x9f4b, NULL
),
351 if (!data
|| data_len
< 3)
354 if (data
[3] < 2 || data
[3] > data_len
- 3) {
360 printf("Recovered data:\n");
361 dump_buffer(data
, data_len
, stdout
, 0);
364 size_t idn_len
= data
[4];
365 if (idn_len
> data
[3] - 1) {
370 // 9f4c ICC Dynamic Number
371 struct tlvdb
*idn_db
= tlvdb_fixed(0x9f4c, idn_len
, data
+ 5);
378 struct tlvdb
*emv_pki_recover_atc_ex(const struct emv_pk
*enc_pk
, const struct tlvdb
*db
, bool showData
)
381 unsigned char *data
= emv_pki_decode_message(enc_pk
, 5, &data_len
,
382 tlvdb_get(db
, 0x9f4b, NULL
),
383 tlvdb_get(db
, 0x9f37, NULL
),
384 tlvdb_get(db
, 0x9f02, NULL
),
385 tlvdb_get(db
, 0x5f2a, NULL
),
386 tlvdb_get(db
, 0x9f69, NULL
),
389 if (!data
|| data_len
< 3)
392 if (data
[3] < 2 || data
[3] > data_len
- 3) {
398 printf("Recovered data:\n");
399 dump_buffer(data
, data_len
, stdout
, 0);
402 size_t idn_len
= data
[4];
403 if (idn_len
> data
[3] - 1) {
408 // 9f36 Application Transaction Counter (ATC)
409 struct tlvdb
*atc_db
= tlvdb_fixed(0x9f36, idn_len
, data
+ 5);
416 static bool tlv_hash(void *data
, const struct tlv
*tlv
, int level
, bool is_leaf
)
418 struct crypto_hash
*ch
= data
;
422 if (tlv_is_constructed(tlv
))
425 if (tlv
->tag
== 0x9f4b)
428 tag
= tlv_encode(tlv
, &tag_len
);
429 crypto_hash_write(ch
, tag
, tag_len
);
435 struct tlvdb
*emv_pki_perform_cda(const struct emv_pk
*enc_pk
, const struct tlvdb
*db
,
436 const struct tlvdb
*this_db
,
437 const struct tlv
*pdol_data_tlv
,
438 const struct tlv
*crm1_tlv
,
439 const struct tlv
*crm2_tlv
)
441 return emv_pki_perform_cda_ex(enc_pk
, db
, this_db
, pdol_data_tlv
, crm1_tlv
, crm2_tlv
, false);
443 struct tlvdb
*emv_pki_perform_cda_ex(const struct emv_pk
*enc_pk
, const struct tlvdb
*db
,
444 const struct tlvdb
*this_db
, // AC TLV result
445 const struct tlv
*pdol_data_tlv
, // PDOL
446 const struct tlv
*crm1_tlv
, // CDOL1
447 const struct tlv
*crm2_tlv
, // CDOL2
450 const struct tlv
*un_tlv
= tlvdb_get(db
, 0x9f37, NULL
);
451 const struct tlv
*cid_tlv
= tlvdb_get(this_db
, 0x9f27, NULL
);
453 if (!un_tlv
|| !cid_tlv
)
457 unsigned char *data
= emv_pki_decode_message(enc_pk
, 5, &data_len
,
458 tlvdb_get(this_db
, 0x9f4b, NULL
),
461 if (!data
|| data_len
< 3) {
462 printf("ERROR: can't decode message. len %zd\n", data_len
);
467 printf("Recovered data:\n");
468 dump_buffer(data
, data_len
, stdout
, 0);
471 if (data
[3] < 30 || data
[3] > data_len
- 4) {
472 printf("ERROR: Invalid data length\n");
477 if (!cid_tlv
|| cid_tlv
->len
!= 1 || cid_tlv
->value
[0] != data
[5 + data
[4]]) {
478 printf("ERROR: CID mismatch\n");
483 struct crypto_hash
*ch
;
484 ch
= crypto_hash_open(enc_pk
->hash_algo
);
486 printf("ERROR: can't create hash\n");
492 crypto_hash_write(ch
, pdol_data_tlv
->value
, pdol_data_tlv
->len
);
494 crypto_hash_write(ch
, crm1_tlv
->value
, crm1_tlv
->len
);
496 crypto_hash_write(ch
, crm2_tlv
->value
, crm2_tlv
->len
);
498 tlvdb_visit(this_db
, tlv_hash
, ch
, 0);
500 if (memcmp(data
+ 5 + data
[4] + 1 + 8, crypto_hash_read(ch
), 20)) {
501 printf("ERROR: calculated hash error\n");
502 crypto_hash_close(ch
);
506 crypto_hash_close(ch
);
508 size_t idn_len
= data
[4];
509 if (idn_len
> data
[3] - 1) {
510 printf("ERROR: Invalid IDN length\n");
515 struct tlvdb
*idn_db
= tlvdb_fixed(0x9f4c, idn_len
, data
+ 5);