]>
git.zerfleddert.de Git - proxmark3-svn/blob - client/emv/test/cda_test.c
536a5862b81b329027f0c9157ed5c6eedced9042
2 * emv-tools - a set of tools to work with EMV family of smart cards
3 * Copyright (C) 2012, 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.
20 #include "../emv_pk.h"
21 #include "../crypto.h"
24 #include "../emv_pki.h"
30 struct emv_pk c_mchip_05
= {
31 .rid
= { 0xa0, 0x00, 0x00, 0x00, 0x04, },
33 .hash_algo
= HASH_SHA_1
,
36 0xeb, 0xfa, 0x0d, 0x5d,
37 0x06, 0xd8, 0xce, 0x70,
38 0x2d, 0xa3, 0xea, 0xe8,
39 0x90, 0x70, 0x1d, 0x45,
40 0xe2, 0x74, 0xc8, 0x45, },
44 .modulus
= (unsigned char[]){
45 0xb8, 0x04, 0x8a, 0xbc, 0x30, 0xc9, 0x0d, 0x97, 0x63, 0x36, 0x54, 0x3e, 0x3f, 0xd7, 0x09, 0x1c,
46 0x8f, 0xe4, 0x80, 0x0d, 0xf8, 0x20, 0xed, 0x55, 0xe7, 0xe9, 0x48, 0x13, 0xed, 0x00, 0x55, 0x5b,
47 0x57, 0x3f, 0xec, 0xa3, 0xd8, 0x4a, 0xf6, 0x13, 0x1a, 0x65, 0x1d, 0x66, 0xcf, 0xf4, 0x28, 0x4f,
48 0xb1, 0x3b, 0x63, 0x5e, 0xdd, 0x0e, 0xe4, 0x01, 0x76, 0xd8, 0xbf, 0x04, 0xb7, 0xfd, 0x1c, 0x7b,
49 0xac, 0xf9, 0xac, 0x73, 0x27, 0xdf, 0xaa, 0x8a, 0xa7, 0x2d, 0x10, 0xdb, 0x3b, 0x8e, 0x70, 0xb2,
50 0xdd, 0xd8, 0x11, 0xcb, 0x41, 0x96, 0x52, 0x5e, 0xa3, 0x86, 0xac, 0xc3, 0x3c, 0x0d, 0x9d, 0x45,
51 0x75, 0x91, 0x64, 0x69, 0xc4, 0xe4, 0xf5, 0x3e, 0x8e, 0x1c, 0x91, 0x2c, 0xc6, 0x18, 0xcb, 0x22,
52 0xdd, 0xe7, 0xc3, 0x56, 0x8e, 0x90, 0x02, 0x2e, 0x6b, 0xba, 0x77, 0x02, 0x02, 0xe4, 0x52, 0x2a,
53 0x2d, 0xd6, 0x23, 0xd1, 0x80, 0xe2, 0x15, 0xbd, 0x1d, 0x15, 0x07, 0xfe, 0x3d, 0xc9, 0x0c, 0xa3,
54 0x10, 0xd2, 0x7b, 0x3e, 0xfc, 0xcd, 0x8f, 0x83, 0xde, 0x30, 0x52, 0xca, 0xd1, 0xe4, 0x89, 0x38,
55 0xc6, 0x8d, 0x09, 0x5a, 0xac, 0x91, 0xb5, 0xf3, 0x7e, 0x28, 0xbb, 0x49, 0xec, 0x7e, 0xd5, 0x97,
59 const unsigned char c_issuer_cert
[] = {
60 0x17, 0x14, 0x28, 0x4f, 0x76, 0x3b, 0x85, 0x86, 0xee, 0x6d, 0x31, 0x99, 0x51, 0xf7, 0xe6, 0x3f,
61 0xa2, 0x50, 0x76, 0xe5, 0x0d, 0xc9, 0xd3, 0x20, 0x0b, 0xa9, 0x98, 0xd3, 0xa0, 0x52, 0xad, 0xba,
62 0x9a, 0xb6, 0x9a, 0xc6, 0xad, 0x6a, 0xdd, 0x3c, 0xe0, 0x9f, 0x02, 0x78, 0xf4, 0x07, 0x4e, 0xc4,
63 0xee, 0x9b, 0x1d, 0x22, 0x68, 0xa3, 0xe9, 0x53, 0x57, 0x5e, 0x45, 0x4e, 0x50, 0xcd, 0x86, 0x0b,
64 0xf4, 0x24, 0xc5, 0x1c, 0x59, 0x77, 0x12, 0xd2, 0xaa, 0x05, 0x70, 0x89, 0xdd, 0x86, 0x73, 0xe5,
65 0x1b, 0x1e, 0x1d, 0x71, 0x88, 0x03, 0x48, 0x92, 0x07, 0x7a, 0xc1, 0x8a, 0x6a, 0xe2, 0x34, 0x88,
66 0xbe, 0xa9, 0xdf, 0x3b, 0x1a, 0x83, 0xf2, 0xc0, 0x80, 0x0c, 0xd7, 0xc5, 0xcd, 0xf2, 0xfd, 0xe0,
67 0x49, 0x6f, 0x7b, 0xc3, 0x9f, 0xb4, 0xbf, 0x36, 0x32, 0x99, 0xbf, 0xa6, 0x37, 0xb2, 0xec, 0x33,
68 0xc5, 0x07, 0xe3, 0x68, 0x21, 0xee, 0xc2, 0x07, 0x5f, 0x0e, 0x42, 0x0d, 0x38, 0xa1, 0xc9, 0xf3,
69 0x12, 0x72, 0x61, 0xba, 0x31, 0x6c, 0x98, 0x76, 0x74, 0xfa, 0xdb, 0x20, 0xea, 0x7f, 0xeb, 0x75,
70 0xee, 0x45, 0x5d, 0x12, 0x14, 0x6e, 0xa6, 0xf0, 0x2e, 0x8b, 0x01, 0xec, 0x2f, 0xa7, 0xa1, 0x15,
73 const unsigned char c_issuer_rem
[] = {
74 0x6e, 0x63, 0xb7, 0xbc, 0x70, 0xab, 0xdd, 0x09, 0x34, 0x1b, 0x34, 0xc0, 0x32, 0x86, 0xba, 0x9b,
75 0xd8, 0x3b, 0xa7, 0x93, 0x6c, 0x5b, 0x77, 0x98, 0xfb, 0x22, 0xc5, 0xe5, 0x3f, 0xf2, 0x40, 0xa2,
76 0x6d, 0xbd, 0x64, 0x15,
79 const unsigned char c_issuer_exp
[] = {
83 const unsigned char c_icc_cert
[] = {
84 0xa4, 0x2f, 0xbe, 0xb1, 0x56, 0xb9, 0x8d, 0xcb, 0x05, 0x54, 0xda, 0x06, 0x2a, 0xdc, 0xa5, 0x30,
85 0x9a, 0x91, 0xf0, 0x4f, 0xa2, 0xc7, 0xbd, 0x71, 0x02, 0xa8, 0xd7, 0x3f, 0x16, 0xa3, 0xcf, 0xad,
86 0xe8, 0xaa, 0xdf, 0x4f, 0x3f, 0xe2, 0xa2, 0x12, 0x5c, 0xcd, 0xd7, 0x7c, 0x6b, 0x9f, 0x78, 0xb5,
87 0xb4, 0x37, 0x1c, 0xe0, 0x80, 0x57, 0x25, 0xb0, 0xf9, 0xc0, 0x27, 0xaf, 0x14, 0x7d, 0x91, 0xe1,
88 0xff, 0xdb, 0x20, 0x1e, 0x9c, 0x17, 0x0c, 0xe7, 0x77, 0x05, 0x3a, 0x17, 0x2a, 0xd5, 0x26, 0xdc,
89 0xaf, 0xd3, 0x38, 0x95, 0xe1, 0xa9, 0x47, 0x30, 0x5c, 0x5b, 0x16, 0x7f, 0x2e, 0x7c, 0x6f, 0x99,
90 0x15, 0x81, 0xa6, 0x52, 0xee, 0x47, 0x31, 0x54, 0x76, 0x0c, 0x2e, 0xd7, 0x74, 0x21, 0x4e, 0x50,
91 0xdf, 0xec, 0xdd, 0x4c, 0xf2, 0x94, 0xc9, 0x74, 0xb8, 0x9e, 0xbc, 0xa2, 0x5b, 0x5a, 0xb3, 0xc0,
92 0xbe, 0xb5, 0x0d, 0xfa, 0xf7, 0x82, 0xaf, 0xde, 0x14, 0x33, 0xd9, 0x0c, 0xa2, 0xa8, 0x9d, 0x65,
93 0x1e, 0x75, 0xd6, 0x7e, 0xbc, 0x7c, 0x3e, 0x36, 0xf5, 0xa1, 0x65, 0xee, 0x61, 0x32, 0x61, 0x29,
94 0x39, 0xc1, 0xec, 0xd3, 0x99, 0xe4, 0x60, 0x74, 0xb9, 0x96, 0xd9, 0x3a, 0x88, 0xe0, 0x1e, 0x0a,
97 const unsigned char c_icc_exp
[] = {
101 const unsigned char c_sdad_cr
[] = {
102 0x1c, 0x00, 0x9f, 0xc4, 0x86, 0x79, 0x15, 0x7d, 0xbf, 0xf4, 0x5f, 0x65, 0xd3, 0x3f, 0xf7, 0x8d,
103 0x4f, 0xcb, 0xf0, 0xcf, 0x5e, 0xa4, 0x20, 0x8d, 0x10, 0x7a, 0xe9, 0x5a, 0xa3, 0x8c, 0x54, 0x6d,
104 0x0e, 0x5a, 0x18, 0xb8, 0x74, 0x03, 0xa1, 0x2b, 0xd4, 0x47, 0xa8, 0xbb, 0xfc, 0x1e, 0x49, 0xce,
105 0x0b, 0x2e, 0x25, 0x13, 0x89, 0x20, 0x57, 0x03, 0xc9, 0xbb, 0x1a, 0x88, 0xcc, 0x79, 0xf1, 0xdd,
106 0xc2, 0xf9, 0x84, 0x1e, 0xad, 0xf0, 0x7c, 0xe0, 0x7b, 0x62, 0x51, 0x1d, 0xdc, 0x93, 0xdf, 0x59,
107 0xf2, 0x8f, 0x0e, 0x91, 0xf9, 0x23, 0x32, 0xd2, 0x9c, 0xde, 0xf2, 0xbc, 0xcb, 0x10, 0x08, 0x85,
108 0x05, 0x00, 0xef, 0x3e, 0x47, 0x0a, 0x4c, 0xb1, 0x8c, 0xd9, 0x1a, 0xa5, 0xc1, 0xa1, 0x08, 0xf3,
112 const unsigned char c_ssd1
[] = {
113 0x5f, 0x25, 0x03, 0x14, 0x05, 0x01, 0x5f, 0x24, 0x03, 0x15, 0x06, 0x30, 0x5a, 0x08, 0x52, 0x85,
114 0x88, 0x12, 0x54, 0x34, 0x56, 0x53, 0x5f, 0x34, 0x01, 0x01, 0x8e, 0x0c, 0x00, 0x00, 0x00, 0x00,
115 0x00, 0x00, 0x00, 0x00, 0x1e, 0x03, 0x1f, 0x03, 0x9f, 0x07, 0x02, 0xff, 0x00, 0x9f, 0x0d, 0x05,
116 0xbc, 0x50, 0xbc, 0x00, 0x00, 0x9f, 0x0e, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9f, 0x0f, 0x05,
117 0xbc, 0x70, 0xbc, 0x98, 0x00, 0x9f, 0x4a, 0x01, 0x82, 0x5f, 0x28, 0x02, 0x06, 0x43, 0x8c, 0x21,
118 0x9f, 0x02, 0x06, 0x9f, 0x03, 0x06, 0x9f, 0x1a, 0x02, 0x95, 0x05, 0x5f, 0x2a, 0x02, 0x9a, 0x03,
119 0x9c, 0x01, 0x9f, 0x37, 0x04, 0x9f, 0x35, 0x01, 0x9f, 0x45, 0x02, 0x9f, 0x4c, 0x08, 0x9f, 0x34,
120 0x03, 0x8d, 0x0c, 0x91, 0x0a, 0x8a, 0x02, 0x95, 0x05, 0x9f, 0x37, 0x04, 0x9f, 0x4c, 0x08,
123 static const struct tlv ssd1_tlv
= {
124 .len
= sizeof(c_ssd1
),
128 const unsigned char c_pan
[] = {
129 0x52, 0x85, 0x88, 0x12, 0x54, 0x34, 0x56, 0x53,
132 const unsigned char c_dd1
[] = {
133 0x12, 0x34, 0x57, 0x79,
136 const unsigned char c_dd2
[] = {
137 0x9f, 0x27, 0x01, 0x40, 0x9f, 0x36, 0x02, 0x00, 0x10, 0x9f, 0x10, 0x12, 0x00, 0x10, 0x90, 0x40,
138 0x01, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff,
141 const unsigned char c_crm1
[] = {
142 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x43, 0x00, 0x00,
143 0x00, 0x00, 0x00, 0x06, 0x43, 0x14, 0x09, 0x25, 0x50, 0x12, 0x34, 0x57, 0x79, 0x23, 0x00, 0x00,
144 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x03, 0x00,
146 static const struct tlv crm1_tlv
= {
147 .len
= sizeof(c_crm1
),
151 static int cda_test_raw(bool verbose
)
153 const struct emv_pk
*pk
= &c_mchip_05
;
155 struct crypto_pk
*kcp
= crypto_pk_open(PK_RSA
,
156 pk
->modulus
, pk
->mlen
,
161 unsigned char *ipk_data
;
163 ipk_data
= crypto_pk_encrypt(kcp
, c_issuer_cert
, sizeof(c_issuer_cert
), &ipk_data_len
);
164 crypto_pk_close(kcp
);
170 printf("issuer cert:\n");
171 dump_buffer(ipk_data
, ipk_data_len
, stdout
, 0);
174 size_t ipk_pk_len
= ipk_data
[13];
175 unsigned char *ipk_pk
= malloc(ipk_pk_len
);
176 memcpy(ipk_pk
, ipk_data
+ 15, ipk_data_len
- 36);
177 memcpy(ipk_pk
+ ipk_data_len
- 36, c_issuer_rem
, sizeof(c_issuer_rem
));
179 struct crypto_hash
*ch
;
180 ch
= crypto_hash_open(HASH_SHA_1
);
187 crypto_hash_write(ch
, ipk_data
+ 1, 14);
188 crypto_hash_write(ch
, ipk_pk
, ipk_pk_len
);
189 crypto_hash_write(ch
, c_issuer_exp
, sizeof(c_issuer_exp
));
191 unsigned char *h
= crypto_hash_read(ch
);
193 crypto_hash_close(ch
);
200 printf("crypto hash:\n");
201 dump_buffer(h
, 20, stdout
, 0);
204 if (memcmp(ipk_data
+ ipk_data_len
- 21, h
, 20)) {
205 crypto_hash_close(ch
);
211 crypto_hash_close(ch
);
214 struct crypto_pk
*ikcp
= crypto_pk_open(PK_RSA
, ipk_pk
, (int) ipk_pk_len
,
215 c_issuer_exp
, (int) sizeof(c_issuer_exp
));
220 unsigned char *iccpk_data
;
221 size_t iccpk_data_len
;
222 iccpk_data
= crypto_pk_encrypt(ikcp
, c_icc_cert
, sizeof(c_icc_cert
), &iccpk_data_len
);
223 crypto_pk_close(ikcp
);
229 printf("icc cert:\n");
230 dump_buffer(iccpk_data
, iccpk_data_len
, stdout
, 0);
233 size_t iccpk_pk_len
= iccpk_data
[19];
234 unsigned char *iccpk_pk
= malloc(iccpk_pk_len
);
235 memcpy(iccpk_pk
, iccpk_data
+ 21, /*iccpk_data_len - 36*/iccpk_pk_len
);
236 /*memcpy(iccpk_pk + iccpk_data_len - 36, icc_rem, sizeof(icc_rem));*/
238 ch
= crypto_hash_open(HASH_SHA_1
);
245 crypto_hash_write(ch
, iccpk_data
+ 1, iccpk_data_len
- 22);
246 crypto_hash_write(ch
, c_icc_exp
, sizeof(c_icc_exp
));
247 crypto_hash_write(ch
, c_ssd1
, sizeof(c_ssd1
));
249 h
= crypto_hash_read(ch
);
251 crypto_hash_close(ch
);
258 printf("crypto hash1.1:\n");
259 dump_buffer(h
, 20, stdout
, 0);
262 if (memcmp(iccpk_data
+ iccpk_data_len
- 21, h
, 20)) {
263 crypto_hash_close(ch
);
269 crypto_hash_close(ch
);
272 struct crypto_pk
*icckcp
= crypto_pk_open(PK_RSA
, iccpk_pk
, (int) iccpk_pk_len
,
273 c_issuer_exp
, (int) sizeof(c_issuer_exp
));
279 unsigned char *sdad
= crypto_pk_encrypt(icckcp
, c_sdad_cr
, sizeof(c_sdad_cr
), &sdad_len
);
280 crypto_pk_close(icckcp
);
286 dump_buffer(sdad
, sdad_len
, stdout
, 0);
289 ch
= crypto_hash_open(HASH_SHA_1
);
295 crypto_hash_write(ch
, sdad
+ 1, sdad_len
- 22);
296 crypto_hash_write(ch
, c_dd1
, sizeof(c_dd1
));
298 unsigned char *h2
= crypto_hash_read(ch
);
300 crypto_hash_close(ch
);
306 printf("crypto hash2:\n");
307 dump_buffer(h2
, 20, stdout
, 0);
310 crypto_hash_close(ch
);
312 ch
= crypto_hash_open(HASH_SHA_1
);
318 crypto_hash_write(ch
, c_crm1
, sizeof(c_crm1
));
319 crypto_hash_write(ch
, c_dd2
, sizeof(c_dd2
));
321 h
= crypto_hash_read(ch
);
323 crypto_hash_close(ch
);
329 printf("crypto hash2.1:\n");
330 dump_buffer(h
, 20, stdout
, 0);
333 if (memcmp(sdad
+ 5 + 8 + 1 + 8, h
, 20)) {
334 crypto_hash_close(ch
);
339 crypto_hash_close(ch
);
346 static int cda_test_pk(bool verbose
)
348 const struct emv_pk
*pk
= &c_mchip_05
;
351 db
= tlvdb_external(0x90, sizeof(c_issuer_cert
), c_issuer_cert
);
352 tlvdb_add(db
, tlvdb_external(0x9f32, sizeof(c_issuer_exp
), c_issuer_exp
));
353 tlvdb_add(db
, tlvdb_external(0x92, sizeof(c_issuer_rem
), c_issuer_rem
));
354 tlvdb_add(db
, tlvdb_external(0x5a, sizeof(c_pan
), c_pan
));
356 struct emv_pk
*ipk
= emv_pki_recover_issuer_cert(pk
, db
);
358 fprintf(stderr
, "Could not recover Issuer certificate!\n");
363 tlvdb_add(db
, tlvdb_external(0x9f46, sizeof(c_icc_cert
), c_icc_cert
));
364 tlvdb_add(db
, tlvdb_external(0x9f47, sizeof(c_icc_exp
), c_icc_exp
));
365 /*tlvdb_add(db, tlvdb_external(0x9f48, sizeof(issuer_rem), issuer_rem));*/
367 struct emv_pk
*iccpk
= emv_pki_recover_icc_cert(ipk
, db
, &ssd1_tlv
);
369 fprintf(stderr
, "Could not recover ICC certificate!\n");
375 tlvdb_add(db
, tlvdb_fixed(0x9f37, sizeof(c_dd1
), c_dd1
));
377 struct tlvdb
*cda_db
;
378 cda_db
= tlvdb_fixed(0x9f27, 1, (unsigned char[]){ 0x40 });
379 tlvdb_add(cda_db
, tlvdb_fixed(0x9f36, 2, (unsigned char[]) { 0x00, 0x10 }));
380 tlvdb_add(cda_db
, tlvdb_external(0x9f4b, sizeof(c_sdad_cr
), c_sdad_cr
));
381 tlvdb_add(cda_db
, tlvdb_fixed(0x9f10, 0x12,
382 (unsigned char[]) { 0x00, 0x10, 0x90, 0x40, 0x01, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff}));
384 struct tlvdb
*idndb
= emv_pki_perform_cda(iccpk
, db
, cda_db
,
389 fprintf(stderr
, "Could not recover IDN!\n");
397 const struct tlv
*idn
= tlvdb_get(idndb
, 0x9f4c, NULL
);
399 fprintf(stderr
, "IDN not found!\n");
410 dump_buffer(idn
->value
, idn
->len
, stdout
, 0);
422 int exec_cda_test(bool verbose
)
425 fprintf(stdout
, "\n");
427 ret
= cda_test_raw(verbose
);
429 fprintf(stderr
, "CDA raw test: failed\n");
432 fprintf(stdout
, "CDA raw test: passed\n");
434 ret
= cda_test_pk(verbose
);
436 fprintf(stderr
, "CDA test pk: failed\n");
439 fprintf(stdout
, "CDA test pk: passed\n");