]> cvs.zerfleddert.de Git - proxmark3-svn/blob - client/emv/test/cda_test.c
Redesign of lf hid card format handler as discussed with @marshmellow42
[proxmark3-svn] / client / emv / test / cda_test.c
1 /*
2 * emv-tools - a set of tools to work with EMV family of smart cards
3 * Copyright (C) 2012, 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_pk.h"
21 #include "../crypto.h"
22 #include "../dump.h"
23 #include "../tlv.h"
24 #include "../emv_pki.h"
25
26 #include <stdio.h>
27 #include <string.h>
28 #include <stdlib.h>
29
30 struct emv_pk c_mchip_05 = {
31 .rid = { 0xa0, 0x00, 0x00, 0x00, 0x04, },
32 .index = 5,
33 .hash_algo = HASH_SHA_1,
34 .pk_algo = PK_RSA,
35 .hash = {
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, },
41 .exp = { 0x03, },
42 .elen = 1,
43 .mlen = 1408 / 8,
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,
56 },
57 };
58
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,
71 };
72
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,
77 };
78
79 const unsigned char c_issuer_exp[] = {
80 0x03,
81 };
82
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,
95 };
96
97 const unsigned char c_icc_exp[] = {
98 0x03,
99 };
100
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,
109
110 };
111
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,
121 0x39, 0x00,
122 };
123 static const struct tlv ssd1_tlv = {
124 .len = sizeof(c_ssd1),
125 .value = c_ssd1,
126 };
127
128 const unsigned char c_pan[] = {
129 0x52, 0x85, 0x88, 0x12, 0x54, 0x34, 0x56, 0x53,
130 };
131
132 const unsigned char c_dd1[] = {
133 0x12, 0x34, 0x57, 0x79,
134 };
135
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,
139 };
140
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,
145 };
146 static const struct tlv crm1_tlv = {
147 .len = sizeof(c_crm1),
148 .value = c_crm1,
149 };
150
151 static int cda_test_raw(bool verbose)
152 {
153 const struct emv_pk *pk = &c_mchip_05;
154
155 struct crypto_pk *kcp = crypto_pk_open(PK_RSA,
156 pk->modulus, pk->mlen,
157 pk->exp, pk->elen);
158 if (!kcp)
159 return 1;
160
161 unsigned char *ipk_data;
162 size_t ipk_data_len;
163 ipk_data = crypto_pk_encrypt(kcp, c_issuer_cert, sizeof(c_issuer_cert), &ipk_data_len);
164 crypto_pk_close(kcp);
165
166 if (!ipk_data)
167 return 1;
168
169 if (verbose) {
170 printf("issuer cert:\n");
171 dump_buffer(ipk_data, ipk_data_len, stdout, 0);
172 }
173
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));
178
179 struct crypto_hash *ch;
180 ch = crypto_hash_open(HASH_SHA_1);
181 if (!ch) {
182 free(ipk_pk);
183 free(ipk_data);
184 return 1;
185 }
186
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));
190
191 unsigned char *h = crypto_hash_read(ch);
192 if (!h) {
193 crypto_hash_close(ch);
194 free(ipk_pk);
195 free(ipk_data);
196 return 1;
197 }
198
199 if (verbose) {
200 printf("crypto hash:\n");
201 dump_buffer(h, 20, stdout, 0);
202 }
203
204 if (memcmp(ipk_data + ipk_data_len - 21, h, 20)) {
205 crypto_hash_close(ch);
206 free(ipk_pk);
207 free(ipk_data);
208 return 1;
209 }
210
211 crypto_hash_close(ch);
212 free(ipk_data);
213
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));
216 free(ipk_pk);
217 if (!ikcp)
218 return 1;
219
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);
224
225 if (!iccpk_data)
226 return 1;
227
228 if (verbose) {
229 printf("icc cert:\n");
230 dump_buffer(iccpk_data, iccpk_data_len, stdout, 0);
231 }
232
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));*/
237
238 ch = crypto_hash_open(HASH_SHA_1);
239 if (!ch) {
240 free(iccpk_pk);
241 free(iccpk_data);
242 return 1;
243 }
244
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));
248
249 h = crypto_hash_read(ch);
250 if (!h) {
251 crypto_hash_close(ch);
252 free(iccpk_pk);
253 free(iccpk_data);
254 return 1;
255 }
256
257 if (verbose) {
258 printf("crypto hash1.1:\n");
259 dump_buffer(h, 20, stdout, 0);
260 }
261
262 if (memcmp(iccpk_data + iccpk_data_len - 21, h, 20)) {
263 crypto_hash_close(ch);
264 free(iccpk_pk);
265 free(iccpk_data);
266 return 1;
267 }
268
269 crypto_hash_close(ch);
270 free(iccpk_data);
271
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));
274 free(iccpk_pk);
275 if (!icckcp)
276 return 1;
277
278 size_t sdad_len;
279 unsigned char *sdad = crypto_pk_encrypt(icckcp, c_sdad_cr, sizeof(c_sdad_cr), &sdad_len);
280 crypto_pk_close(icckcp);
281 if (!sdad)
282 return 1;
283
284 if (verbose) {
285 printf("SDAD:\n");
286 dump_buffer(sdad, sdad_len, stdout, 0);
287 }
288
289 ch = crypto_hash_open(HASH_SHA_1);
290 if (!ch) {
291 free(sdad);
292 return 1;
293 }
294
295 crypto_hash_write(ch, sdad + 1, sdad_len - 22);
296 crypto_hash_write(ch, c_dd1, sizeof(c_dd1));
297
298 unsigned char *h2 = crypto_hash_read(ch);
299 if (!h2) {
300 crypto_hash_close(ch);
301 free(sdad);
302 return 1;
303 }
304
305 if (verbose) {
306 printf("crypto hash2:\n");
307 dump_buffer(h2, 20, stdout, 0);
308 }
309
310 crypto_hash_close(ch);
311
312 ch = crypto_hash_open(HASH_SHA_1);
313 if (!ch) {
314 free(sdad);
315 return 1;
316 }
317
318 crypto_hash_write(ch, c_crm1, sizeof(c_crm1));
319 crypto_hash_write(ch, c_dd2, sizeof(c_dd2));
320
321 h = crypto_hash_read(ch);
322 if (!h) {
323 crypto_hash_close(ch);
324 free(sdad);
325 return 1;
326 }
327
328 if (verbose) {
329 printf("crypto hash2.1:\n");
330 dump_buffer(h, 20, stdout, 0);
331 }
332
333 if (memcmp(sdad + 5 + 8 + 1 + 8, h, 20)) {
334 crypto_hash_close(ch);
335 free(sdad);
336 return 1;
337 }
338
339 crypto_hash_close(ch);
340
341 free(sdad);
342
343 return 0;
344 }
345
346 static int cda_test_pk(bool verbose)
347 {
348 const struct emv_pk *pk = &c_mchip_05;
349 struct tlvdb *db;
350
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));
355
356 struct emv_pk *ipk = emv_pki_recover_issuer_cert(pk, db);
357 if (!ipk) {
358 fprintf(stderr, "Could not recover Issuer certificate!\n");
359 tlvdb_free(db);
360 return 2;
361 }
362
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));*/
366
367 struct emv_pk *iccpk = emv_pki_recover_icc_cert(ipk, db, &ssd1_tlv);
368 if (!iccpk) {
369 fprintf(stderr, "Could not recover ICC certificate!\n");
370 emv_pk_free(ipk);
371 tlvdb_free(db);
372 return 2;
373 }
374
375 tlvdb_add(db, tlvdb_fixed(0x9f37, sizeof(c_dd1), c_dd1));
376
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}));
383
384 struct tlvdb *idndb = emv_pki_perform_cda(iccpk, db, cda_db,
385 NULL,
386 &crm1_tlv,
387 NULL);
388 if (!idndb) {
389 fprintf(stderr, "Could not recover IDN!\n");
390 tlvdb_free(cda_db);
391 emv_pk_free(iccpk);
392 emv_pk_free(ipk);
393 tlvdb_free(db);
394 return 2;
395 }
396
397 const struct tlv *idn = tlvdb_get(idndb, 0x9f4c, NULL);
398 if (!idn) {
399 fprintf(stderr, "IDN not found!\n");
400 tlvdb_free(idndb);
401 tlvdb_free(cda_db);
402 emv_pk_free(iccpk);
403 emv_pk_free(ipk);
404 tlvdb_free(db);
405 return 2;
406 }
407
408 if (verbose) {
409 printf("IDN:\n");
410 dump_buffer(idn->value, idn->len, stdout, 0);
411 }
412
413 tlvdb_free(idndb);
414 tlvdb_free(cda_db);
415 emv_pk_free(iccpk);
416 emv_pk_free(ipk);
417 tlvdb_free(db);
418
419 return 0;
420 }
421
422 int exec_cda_test(bool verbose)
423 {
424 int ret;
425 fprintf(stdout, "\n");
426
427 ret = cda_test_raw(verbose);
428 if (ret) {
429 fprintf(stderr, "CDA raw test: failed\n");
430 return ret;
431 }
432 fprintf(stdout, "CDA raw test: passed\n");
433
434 ret = cda_test_pk(verbose);
435 if (ret) {
436 fprintf(stderr, "CDA test pk: failed\n");
437 return ret;
438 }
439 fprintf(stdout, "CDA test pk: passed\n");
440
441 return 0;
442 }
Impressum, Datenschutz