1 /*
2 * Copyright (c) 2014-2020 Yubico AB
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are
7 * met:
8 *
9 * * Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 *
12 * * Redistributions in binary form must reproduce the above
13 * copyright notice, this list of conditions and the following
14 * disclaimer in the documentation and/or other materials provided
15 * with the distribution.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
20 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
21 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
22 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
23 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 *
29 */
30
31 #include <stdio.h>
32 #include <stdlib.h>
33 #include <stdbool.h>
34 #include <limits.h>
35 #include <string.h>
36 #include <sys/types.h>
37 #include <sys/stat.h>
38
39 #include "ykpiv.h"
40
41 #ifdef _WIN32
42 #include <windows.h>
43 #include <openssl/applink.c>
44 #else
45 #include <unistd.h>
46 #endif
47
48 #include "../common/openssl-compat.h"
49 #include <openssl/bn.h>
50 #include <openssl/des.h>
51 #include <openssl/pem.h>
52 #include <openssl/pkcs12.h>
53 #include <openssl/rand.h>
54 #include <openssl/rsa.h>
55 #include <openssl/x509v3.h>
56
57 #include "cmdline.h"
58 #include "../common/util.h"
59
60 #define MAX(a,b) (a) > (b) ? (a) : (b)
61
62 #define CHUID 0
63 #define CCC 1
64
65 #define MAX_OID_LEN 19
66
67 #define KEY_LEN 24
68
69 #define YKPIV_ATTESTATION_OID "1.3.6.1.4.1.41482.3"
70
key_file_mode(enum enum_key_format fmt,bool output)71 static enum file_mode key_file_mode(enum enum_key_format fmt, bool output) {
72 if (fmt == key_format_arg_PEM) {
73 if (output) {
74 return OUTPUT_TEXT;
75 }
76 return INPUT_TEXT;
77 }
78 if (output) {
79 return OUTPUT_BIN;
80 }
81 return INPUT_BIN;
82 }
83
data_file_mode(enum enum_format fmt,bool output)84 static enum file_mode data_file_mode(enum enum_format fmt, bool output) {
85 if (fmt == format_arg_binary) {
86 if (output) {
87 return OUTPUT_BIN;
88 }
89 return INPUT_BIN;
90 }
91 if (output) {
92 return OUTPUT_TEXT;
93 }
94 return INPUT_TEXT;
95 }
96
print_version(ykpiv_state * state,const char * output_file_name)97 static void print_version(ykpiv_state *state, const char *output_file_name) {
98 char version[7] = {0};
99 FILE *output_file = open_file(output_file_name, OUTPUT_TEXT);
100 if(!output_file) {
101 return;
102 }
103
104 if(ykpiv_get_version(state, version, sizeof(version)) == YKPIV_OK) {
105 fprintf(output_file, "Application version %s found.\n", version);
106 } else {
107 fprintf(stderr, "Failed to retrieve application version.\n");
108 }
109
110 if(output_file != stdout) {
111 fclose(output_file);
112 }
113 }
114
sign_data(ykpiv_state * state,const unsigned char * in,size_t len,unsigned char * out,size_t * out_len,unsigned char algorithm,int key)115 static bool sign_data(ykpiv_state *state, const unsigned char *in, size_t len, unsigned char *out,
116 size_t *out_len, unsigned char algorithm, int key) {
117
118 unsigned char signinput[1024] = {0};
119 if(YKPIV_IS_RSA(algorithm)) {
120 size_t padlen = algorithm == YKPIV_ALGO_RSA1024 ? 128 : 256;
121 if(RSA_padding_add_PKCS1_type_1(signinput, padlen, in, len) == 0) {
122 fprintf(stderr, "Failed adding padding.\n");
123 return false;
124 }
125 in = signinput;
126 len = padlen;
127 }
128 if(ykpiv_sign_data(state, in, len, out, out_len, algorithm, key) == YKPIV_OK) {
129 return true;
130 }
131 return false;
132 }
133
134 #if !((OPENSSL_VERSION_NUMBER < 0x10100000L) || defined(LIBRESSL_VERSION_NUMBER))
135 static int ec_key_ex_data_idx = -1;
136
137 struct internal_key {
138 ykpiv_state *state;
139 int algorithm;
140 int key;
141 const unsigned char *oid;
142 size_t oid_len;
143 };
144
yk_rsa_meth_sign(int dtype,const unsigned char * m,unsigned int m_length,unsigned char * sigret,unsigned int * siglen,const RSA * rsa)145 int yk_rsa_meth_sign(int dtype, const unsigned char *m, unsigned int m_length,
146 unsigned char *sigret, unsigned int *siglen, const RSA *rsa) {
147 size_t yk_siglen = RSA_size(rsa);
148 const RSA_METHOD *meth = RSA_get_method(rsa);
149 const struct internal_key *key = RSA_meth_get0_app_data(meth);
150 unsigned char message[256] = {0};
151
152 if(key->oid_len) {
153 memcpy(message, key->oid, key->oid_len);
154 memcpy(message + key->oid_len, m, m_length);
155 m_length += key->oid_len;
156 m = message;
157 }
158 if (sign_data(key->state, m, m_length, sigret, &yk_siglen, key->algorithm, key->key)) {
159 *siglen = (unsigned int)yk_siglen;
160 return 1;
161 }
162
163 return 0;
164 }
165
yk_ec_meth_sign(int type,const unsigned char * dgst,int dlen,unsigned char * sig,unsigned int * siglen,const BIGNUM * kinv,const BIGNUM * r,EC_KEY * ec)166 int yk_ec_meth_sign(int type, const unsigned char *dgst, int dlen,
167 unsigned char *sig, unsigned int *siglen, const BIGNUM *kinv,
168 const BIGNUM *r, EC_KEY *ec) {
169 size_t yk_siglen = ECDSA_size(ec);
170 const struct internal_key *key = EC_KEY_get_ex_data(ec, ec_key_ex_data_idx);
171 if (sign_data(key->state, dgst, dlen, sig, &yk_siglen, key->algorithm, key->key)) {
172 *siglen = (unsigned int)yk_siglen;
173 return 1;
174 }
175
176 return 0;
177 }
178
wrap_public_key(ykpiv_state * state,int algorithm,EVP_PKEY * public_key,int key,const unsigned char * oid,size_t oid_len)179 static void wrap_public_key(ykpiv_state *state, int algorithm, EVP_PKEY *public_key,
180 int key, const unsigned char *oid, size_t oid_len) {
181 static struct internal_key int_key;
182 int_key.state = state;
183 int_key.algorithm = algorithm;
184 int_key.key = key;
185 int_key.oid = oid;
186 int_key.oid_len = oid_len;
187 if(YKPIV_IS_RSA(algorithm)) {
188 RSA_METHOD *meth = RSA_meth_dup(RSA_get_default_method());
189 RSA *rsa = EVP_PKEY_get0_RSA(public_key);
190 if(RSA_meth_set0_app_data(meth, &int_key) != 1) {
191 fprintf(stderr, "Failed to set RSA data\n");
192 }
193 if(RSA_meth_set_sign(meth, yk_rsa_meth_sign) != 1) {
194 fprintf(stderr, "Failed to set RSA signature verification method\n");
195 }
196 if(RSA_set_method(rsa, meth) != 1) {
197 fprintf(stderr, "Failed to wrap RSA key\n");
198 }
199 } else {
200 EC_KEY *ec = EVP_PKEY_get0_EC_KEY(public_key);
201 EC_KEY_METHOD *meth = EC_KEY_METHOD_new(EC_KEY_get_method(ec));
202 if (ec_key_ex_data_idx == -1)
203 ec_key_ex_data_idx = EC_KEY_get_ex_new_index(0, NULL, NULL, NULL, 0);
204 if(EC_KEY_set_ex_data(ec, ec_key_ex_data_idx, &int_key) != 1) {
205 fprintf(stderr, "Failed to set EC data\n");
206 }
207 EC_KEY_METHOD_set_sign(meth, yk_ec_meth_sign, NULL, NULL);
208 if(EC_KEY_set_method(ec, meth) != 1) {
209 fprintf(stderr, "Failed to wrap public EC key\n");
210 }
211 }
212 }
213 #endif
214
generate_key(ykpiv_state * state,enum enum_slot slot,enum enum_algorithm algorithm,const char * output_file_name,enum enum_key_format key_format,enum enum_pin_policy pin_policy,enum enum_touch_policy touch_policy)215 static bool generate_key(ykpiv_state *state, enum enum_slot slot,
216 enum enum_algorithm algorithm, const char *output_file_name,
217 enum enum_key_format key_format, enum enum_pin_policy pin_policy,
218 enum enum_touch_policy touch_policy) {
219 int key = 0;
220 bool ret = false;
221 ykpiv_rc res;
222 FILE *output_file = NULL;
223 EVP_PKEY *public_key = NULL;
224 RSA *rsa = NULL;
225 EC_KEY *eckey = NULL;
226 EC_GROUP *group = NULL;
227 EC_POINT *ecpoint = NULL;
228 uint8_t *mod = NULL;
229 uint8_t *exp = NULL;
230 uint8_t *point = NULL;
231 size_t mod_len = 0;
232 size_t exp_len = 0;
233 size_t point_len = 0;
234
235 key = get_slot_hex(slot);
236
237 output_file = open_file(output_file_name, key_file_mode(key_format, true));
238 if(!output_file) {
239 return false;
240 }
241
242 if(algorithm == algorithm_arg_RSA1024) {
243 fprintf(stderr, "\nWARNING. The use of RSA1024 is discouraged by the National Institute of Standards "
244 "and Technology (NIST). See https://www.yubico.com/blog/comparing-asymmetric-encryption-algorithms\n\n");
245 }
246
247 res = ykpiv_util_generate_key(state,
248 (uint8_t)(key & 0xFF),
249 get_piv_algorithm(algorithm),
250 get_pin_policy(pin_policy),
251 get_touch_policy(touch_policy),
252 &mod,
253 &mod_len,
254 &exp,
255 &exp_len,
256 &point,
257 &point_len);
258 if (res != YKPIV_OK) {
259 fprintf(stderr, "Key generation failed.\n");
260 goto generate_out;
261 }
262
263 if(key_format == key_format_arg_PEM) {
264 public_key = EVP_PKEY_new();
265 if(algorithm == algorithm_arg_RSA1024 || algorithm == algorithm_arg_RSA2048) {
266 BIGNUM *bignum_n = NULL;
267 BIGNUM *bignum_e = NULL;
268 rsa = RSA_new();
269 bignum_n = BN_bin2bn(mod, mod_len, NULL);
270 if (bignum_n == NULL) {
271 fprintf(stderr, "Failed to parse public key modulus.\n");
272 goto generate_out;
273 }
274 bignum_e = BN_bin2bn(exp, exp_len, NULL);
275 if(bignum_e == NULL) {
276 fprintf(stderr, "Failed to parse public key exponent.\n");
277 goto generate_out;
278 }
279
280 if(RSA_set0_key(rsa, bignum_n, bignum_e, NULL) != 1) {
281 fprintf(stderr, "Failed to set RSA key\n");
282 goto generate_out;
283 }
284 if(EVP_PKEY_set1_RSA(public_key, rsa) != 1) {
285 fprintf(stderr, "Failed to set RSA public key\n");
286 goto generate_out;
287 }
288 } else if(algorithm == algorithm_arg_ECCP256 || algorithm == algorithm_arg_ECCP384) {
289 int nid;
290
291 if(algorithm == algorithm_arg_ECCP256) {
292 nid = NID_X9_62_prime256v1;
293 } else {
294 nid = NID_secp384r1;
295 }
296 eckey = EC_KEY_new();
297 group = EC_GROUP_new_by_curve_name(nid);
298 EC_GROUP_set_asn1_flag(group, nid);
299 if(EC_KEY_set_group(eckey, group) != 1) {
300 fprintf(stderr, "Failed to set EC group.\n");
301 goto generate_out;
302 }
303 ecpoint = EC_POINT_new(group);
304
305 if(!EC_POINT_oct2point(group, ecpoint, point, point_len, NULL)) {
306 fprintf(stderr, "Failed to load public point.\n");
307 goto generate_out;
308 }
309 if(!EC_KEY_set_public_key(eckey, ecpoint)) {
310 fprintf(stderr, "Failed to set the public key.\n");
311 goto generate_out;
312 }
313 if(EVP_PKEY_set1_EC_KEY(public_key, eckey) != 1) {
314 fprintf(stderr, "Failed to set EC public key.\n");
315 goto generate_out;
316 }
317 } else {
318 fprintf(stderr, "Wrong algorithm.\n");
319 }
320 if(PEM_write_PUBKEY(output_file, public_key) == 1) {
321 ret = true;
322 } else {
323 fprintf(stderr, "Failed to write public key in PEM format\n");
324 goto generate_out;
325 }
326 } else {
327 fprintf(stderr, "Only PEM is supported as public_key output.\n");
328 goto generate_out;
329 }
330
331 generate_out:
332 if (output_file != stdout) {
333 fclose(output_file);
334 }
335 if (group) {
336 EC_GROUP_clear_free(group);
337 }
338 if (ecpoint) {
339 EC_POINT_free(ecpoint);
340 }
341 if (eckey) {
342 EC_KEY_free(eckey);
343 }
344 if (rsa) {
345 RSA_free(rsa);
346 }
347 if (public_key) {
348 EVP_PKEY_free(public_key);
349 }
350 if (point) {
351 ykpiv_util_free(state, point);
352 }
353 if (mod) {
354 ykpiv_util_free(state, mod);
355 }
356 if (exp) {
357 ykpiv_util_free(state, exp);
358 }
359
360 return ret;
361 }
362
reset(ykpiv_state * state)363 static bool reset(ykpiv_state *state) {
364 return ykpiv_util_reset(state) == YKPIV_OK;
365 }
366
set_pin_retries(ykpiv_state * state,int pin_retries,int puk_retries,int verbose)367 static bool set_pin_retries(ykpiv_state *state, int pin_retries, int puk_retries, int verbose) {
368 ykpiv_rc res;
369
370 if(verbose) {
371 fprintf(stderr, "Setting pin retries to %d and puk retries to %d.\n", pin_retries, puk_retries);
372 }
373 res = ykpiv_set_pin_retries(state, pin_retries, puk_retries);
374 if (res == YKPIV_RANGE_ERROR) {
375 fprintf(stderr, "pin and puk retries must be between 1 and 255.\n");
376 }
377 return res == YKPIV_OK;
378 }
379
import_key(ykpiv_state * state,enum enum_key_format key_format,const char * input_file_name,enum enum_slot slot,char * password,enum enum_pin_policy pin_policy,enum enum_touch_policy touch_policy)380 static bool import_key(ykpiv_state *state, enum enum_key_format key_format,
381 const char *input_file_name, enum enum_slot slot, char *password,
382 enum enum_pin_policy pin_policy, enum enum_touch_policy touch_policy) {
383 int key = 0;
384 FILE *input_file = NULL;
385 EVP_PKEY *private_key = NULL;
386 PKCS12 *p12 = NULL;
387 X509 *cert = NULL;
388 bool ret = false;
389 ykpiv_rc rc = YKPIV_GENERIC_ERROR;
390
391 key = get_slot_hex(slot);
392
393 input_file = open_file(input_file_name, key_file_mode(key_format, false));
394 if(!input_file) {
395 return false;
396 }
397
398 if(isatty(fileno(input_file))) {
399 fprintf(stderr, "Please paste the private key...\n");
400 }
401
402 if(key_format == key_format_arg_PEM) {
403 private_key = PEM_read_PrivateKey(input_file, NULL, NULL, password);
404 if(!private_key) {
405 fprintf(stderr, "Failed loading private key for import.\n");
406 goto import_out;
407 }
408 } else if(key_format == key_format_arg_PKCS12) {
409 p12 = d2i_PKCS12_fp(input_file, NULL);
410 if(!p12) {
411 fprintf(stderr, "Failed to load PKCS12 from file.\n");
412 goto import_out;
413 }
414 if(PKCS12_parse(p12, password, &private_key, &cert, NULL) == 0 || private_key == NULL) {
415 fprintf(stderr, "Failed to parse PKCS12 structure. (wrong password?)\n");
416 goto import_out;
417 }
418 } else {
419 /* TODO: more formats go here */
420 fprintf(stderr, "Unknown key format.\n");
421 goto import_out;
422 }
423
424 {
425 unsigned char algorithm = get_algorithm(private_key);
426 unsigned char pp = YKPIV_PINPOLICY_DEFAULT;
427 unsigned char tp = YKPIV_TOUCHPOLICY_DEFAULT;
428
429 if(algorithm == 0) {
430 goto import_out;
431 }
432
433 if(pin_policy != pin_policy__NULL) {
434 pp = get_pin_policy(pin_policy);
435 }
436
437 if(touch_policy != touch_policy__NULL) {
438 tp = get_touch_policy(touch_policy);
439 }
440
441 if(YKPIV_IS_RSA(algorithm)) {
442 RSA *rsa_private_key = EVP_PKEY_get1_RSA(private_key);
443 unsigned char e[4] = {0};
444 unsigned char p[128] = {0};
445 unsigned char q[128] = {0};
446 unsigned char dmp1[128] = {0};
447 unsigned char dmq1[128] = {0};
448 unsigned char iqmp[128] = {0};
449 const BIGNUM *bn_e, *bn_p, *bn_q, *bn_dmp1, *bn_dmq1, *bn_iqmp;
450
451 int element_len = 128;
452 if(algorithm == YKPIV_ALGO_RSA1024) {
453 element_len = 64;
454 }
455
456 RSA_get0_key(rsa_private_key, NULL, &bn_e, NULL);
457 RSA_get0_factors(rsa_private_key, &bn_p, &bn_q);
458 RSA_get0_crt_params(rsa_private_key, &bn_dmp1, &bn_dmq1, &bn_iqmp);
459 if((set_component(e, bn_e, 3) == false) ||
460 !(e[0] == 0x01 && e[1] == 0x00 && e[2] == 0x01)) {
461 fprintf(stderr, "Invalid public exponent for import (only 0x10001 supported)\n");
462 goto import_out;
463 }
464
465 if(set_component(p, bn_p, element_len) == false) {
466 fprintf(stderr, "Failed setting p component.\n");
467 goto import_out;
468 }
469
470 if(set_component(q, bn_q, element_len) == false) {
471 fprintf(stderr, "Failed setting q component.\n");
472 goto import_out;
473 }
474
475 if(set_component(dmp1, bn_dmp1, element_len) == false) {
476 fprintf(stderr, "Failed setting dmp1 component.\n");
477 goto import_out;
478 }
479
480 if(set_component(dmq1, bn_dmq1, element_len) == false) {
481 fprintf(stderr, "Failed setting dmq1 component.\n");
482 goto import_out;
483 }
484
485 if(set_component(iqmp, bn_iqmp, element_len) == false) {
486 fprintf(stderr, "Failed setting iqmp component.\n");
487 goto import_out;
488 }
489
490 rc = ykpiv_import_private_key(state, key, algorithm,
491 p, (size_t)element_len,
492 q, (size_t)element_len,
493 dmp1, (size_t)element_len,
494 dmq1, (size_t)element_len,
495 iqmp, (size_t)element_len,
496 NULL, 0,
497 pp, tp);
498 }
499 else if(YKPIV_IS_EC(algorithm)) {
500 EC_KEY *ec = EVP_PKEY_get1_EC_KEY(private_key);
501 const BIGNUM *s = EC_KEY_get0_private_key(ec);
502 unsigned char s_ptr[48] = {0};
503
504 int element_len = 32;
505 if(algorithm == YKPIV_ALGO_ECCP384) {
506 element_len = 48;
507 }
508
509 if(set_component(s_ptr, s, element_len) == false) {
510 fprintf(stderr, "Failed setting ec private key.\n");
511 goto import_out;
512 }
513
514 rc = ykpiv_import_private_key(state, key, algorithm,
515 NULL, 0,
516 NULL, 0,
517 NULL, 0,
518 NULL, 0,
519 NULL, 0,
520 s_ptr, element_len,
521 pp, tp);
522 }
523
524 ret = true;
525 if(rc != YKPIV_OK) {
526 ret = false;
527 }
528 }
529
530 import_out:
531 if(private_key) {
532 EVP_PKEY_free(private_key);
533 }
534
535 if(p12) {
536 PKCS12_free(p12);
537 }
538
539 if(cert) {
540 X509_free(cert);
541 }
542
543 if(input_file != stdin) {
544 fclose(input_file);
545 }
546
547 return ret;
548 }
549
import_cert(ykpiv_state * state,enum enum_key_format cert_format,const char * input_file_name,enum enum_slot slot,char * password)550 static bool import_cert(ykpiv_state *state, enum enum_key_format cert_format,
551 const char *input_file_name, enum enum_slot slot, char *password) {
552 bool ret = false;
553 FILE *input_file = NULL;
554 X509 *cert = NULL;
555 PKCS12 *p12 = NULL;
556 EVP_PKEY *private_key = NULL;
557 int compress = 0;
558 int cert_len = -1;
559
560 input_file = open_file(input_file_name, key_file_mode(cert_format, false));
561 if(!input_file) {
562 return false;
563 }
564
565 if(isatty(fileno(input_file))) {
566 fprintf(stderr, "Please paste the certificate...\n");
567 }
568
569 if(cert_format == key_format_arg_PEM) {
570 cert = PEM_read_X509(input_file, NULL, NULL, password);
571 if(!cert) {
572 fprintf(stderr, "Failed loading certificate for import.\n");
573 goto import_cert_out;
574 }
575 } else if(cert_format == key_format_arg_DER) {
576 cert = d2i_X509_fp(input_file, NULL);
577 if(!cert) {
578 fprintf(stderr, "Failed loading certificate for import.\n");
579 goto import_cert_out;
580 }
581 } else if(cert_format == key_format_arg_PKCS12) {
582 p12 = d2i_PKCS12_fp(input_file, NULL);
583 if(!p12) {
584 fprintf(stderr, "Failed to load PKCS12 from file.\n");
585 goto import_cert_out;
586 }
587 if(!PKCS12_parse(p12, password, &private_key, &cert, NULL)) {
588 fprintf(stderr, "Failed to parse PKCS12 structure.\n");
589 goto import_cert_out;
590 }
591 } else if (cert_format == key_format_arg_GZIP) {
592 struct stat st;
593
594 if(fstat(fileno(input_file), &st) == -1) {
595 fprintf(stderr, "Failed checking input GZIP file.\n");
596 goto import_cert_out;
597 }
598 if (st.st_size > INT_MAX) {
599 fprintf(stderr, "Size of certificate file too large.\n");
600 goto import_cert_out;
601 }
602 cert_len = st.st_size;
603 compress = 0x01;
604 } else {
605 /* TODO: more formats go here */
606 fprintf(stderr, "Unknown key format.\n");
607 goto import_cert_out;
608 }
609 if(cert_len == -1) {
610 cert_len = i2d_X509(cert, NULL);
611 }
612
613 {
614 unsigned char certdata[YKPIV_OBJ_MAX_SIZE] = {0};
615 unsigned char *certptr = certdata;
616 ykpiv_rc res;
617
618 if(cert_len > YKPIV_OBJ_MAX_SIZE || cert_len < 0) {
619 fprintf(stderr, "Length of certificate is more than can fit.\n");
620 goto import_cert_out;
621 }
622
623 if (compress) {
624 if (fread(certdata, 1, (size_t)cert_len, input_file) != (size_t)cert_len) {
625 fprintf(stderr, "Failed to read compressed certificate\n");
626 goto import_cert_out;
627 }
628 } else {
629 if(i2d_X509(cert, &certptr) < 0) {
630 fprintf(stderr, "Failed to encode X509 certificate\n");
631 goto import_cert_out;
632 }
633 }
634 if ((res = ykpiv_util_write_cert(state, get_slot_hex(slot), certdata, (size_t)cert_len, compress)) != YKPIV_OK) {
635 fprintf(stderr, "Failed commands with device: %s\n", ykpiv_strerror(res));
636 } else {
637 ret = true;
638 }
639 }
640
641 import_cert_out:
642 if(cert) {
643 X509_free(cert);
644 }
645 if(input_file != stdin) {
646 fclose(input_file);
647 }
648 if(p12) {
649 PKCS12_free(p12);
650 }
651 if(private_key) {
652 EVP_PKEY_free(private_key);
653 }
654
655 return ret;
656 }
657
set_cardid(ykpiv_state * state,int verbose,int type)658 static bool set_cardid(ykpiv_state *state, int verbose, int type) {
659 ykpiv_rc res;
660 unsigned char id[MAX(sizeof(ykpiv_cardid), sizeof(ykpiv_cccid))] = {0};
661
662 if(type == CHUID) {
663 res = ykpiv_util_set_cardid(state, NULL);
664 } else {
665 res = ykpiv_util_set_cccid(state, NULL);
666 }
667
668 if(res == YKPIV_OK && verbose) {
669 if (type == CHUID) {
670 res = ykpiv_util_get_cardid(state, (ykpiv_cardid*)id);
671 } else {
672 res = ykpiv_util_get_cccid(state, (ykpiv_cccid*)id);
673 }
674 if (res == YKPIV_OK) {
675 fprintf(stderr, "Set the %s ID to: ", type == CHUID ? "CHUID" : "CCC");
676 dump_data(id, type == CHUID ? YKPIV_CARDID_SIZE : YKPIV_CCCID_SIZE, stderr, true, format_arg_hex);
677 }
678 }
679 return res == YKPIV_OK;
680 }
681
add_ext(STACK_OF (X509_EXTENSION)* exts,const char * oid,const char * name,const char * descr,const unsigned char * data,int len)682 static int add_ext(STACK_OF(X509_EXTENSION) *exts, const char *oid, const char *name, const char *descr, const unsigned char *data, int len) {
683 int nid = OBJ_create(oid, name, descr);
684 if(nid <= 0) {
685 fprintf(stderr, "Failed creating %s extension object.\n", name);
686 return 0;
687 }
688 ASN1_OCTET_STRING *octets = ASN1_OCTET_STRING_new();
689 if(!octets) {
690 fprintf(stderr, "Failed allocating octets for %s extension.\n", name);
691 return 0;
692 }
693 if(!ASN1_OCTET_STRING_set(octets, data, len)) {
694 fprintf(stderr, "Failed setting octets for %s extension.\n", name);
695 return 0;
696 }
697 X509_EXTENSION *ext = X509_EXTENSION_create_by_NID(NULL, nid, 0, octets);
698 if(!ext) {
699 fprintf(stderr, "Failed creating %s extension.\n", name);
700 return 0;
701 }
702 if(!sk_X509_EXTENSION_push(exts, ext)) {
703 fprintf(stderr, "Failed pushing %s extension.\n", name);
704 return 0;
705 }
706 return 1;
707 }
708
request_certificate(ykpiv_state * state,enum enum_key_format key_format,const char * input_file_name,enum enum_slot slot,char * subject,enum enum_hash hash,const char * output_file_name,int attestation)709 static bool request_certificate(ykpiv_state *state, enum enum_key_format key_format,
710 const char *input_file_name, enum enum_slot slot, char *subject, enum enum_hash hash,
711 const char *output_file_name, int attestation) {
712 X509_REQ *req = NULL;
713 X509_NAME *name = NULL;
714 FILE *input_file = NULL;
715 FILE *output_file = NULL;
716 EVP_PKEY *public_key = NULL;
717 const EVP_MD *md;
718 bool ret = false;
719 unsigned char algorithm;
720 int key = 0;
721 size_t oid_len;
722 const unsigned char *oid;
723 #if (OPENSSL_VERSION_NUMBER < 0x10100000L) || defined(LIBRESSL_VERSION_NUMBER)
724 unsigned char digest[EVP_MAX_MD_SIZE + MAX_OID_LEN] = {0};
725 unsigned int md_len;
726 unsigned int digest_len;
727 unsigned char *signinput;
728 size_t len = 0;
729 int nid;
730 ASN1_TYPE null_parameter;
731 #endif
732
733 key = get_slot_hex(slot);
734
735 input_file = open_file(input_file_name, key_file_mode(key_format, false));
736 output_file = open_file(output_file_name, key_file_mode(key_format, true));
737 if(!input_file || !output_file) {
738 goto request_out;
739 }
740
741 req = X509_REQ_new();
742 if(!req) {
743 fprintf(stderr, "Failed to allocate request structure.\n");
744 goto request_out;
745 }
746
747 if(attestation) {
748 unsigned char buf[YKPIV_OBJ_MAX_SIZE] = {0};
749 size_t buflen = sizeof(buf);
750 ykpiv_rc rc;
751
752 if((rc = ykpiv_attest(state, key, buf, &buflen)) == YKPIV_OK) {
753 STACK_OF(X509_EXTENSION) *exts = sk_X509_EXTENSION_new_null();
754 add_ext(exts, YKPIV_ATTESTATION_OID ".11", "ykpiv attestation", "Yubico PIV X.509 Attestation", buf, buflen);
755
756 unsigned char *pb = 0;
757 size_t pblen = 0;
758 if((rc = ykpiv_util_read_cert(state, YKPIV_KEY_ATTESTATION, &pb, &pblen)) == YKPIV_OK && pblen > 0) {
759 add_ext(exts, YKPIV_ATTESTATION_OID ".2", "ykpiv attest cert", "Yubico PIV Attestation Certificate", pb, pblen);
760 ykpiv_util_free(state, pb);
761 } else {
762 fprintf(stderr, "Failed reading attestation certificate: %s.\n", ykpiv_strerror(rc));
763 }
764
765 if(!X509_REQ_add_extensions(req, exts)) {
766 fprintf(stderr, "Failed setting the request extensions.\n");
767 sk_X509_EXTENSION_pop_free(exts, X509_EXTENSION_free);
768 goto request_out;
769 }
770 sk_X509_EXTENSION_pop_free(exts, X509_EXTENSION_free);
771
772 // Extract the public key for the request from the attestation
773 const unsigned char *ptr = buf;
774 X509 *x509 = d2i_X509(NULL, &ptr, buflen);
775 if(x509) {
776 public_key = X509_get_pubkey(x509);
777 X509_free(x509);
778 }
779 if(!public_key) {
780 fprintf(stderr, "Failed extracting public key for request from attestation.\n");
781 goto request_out;
782 }
783 } else {
784 fprintf(stderr, "Failed creating attestation: %s.\n", ykpiv_strerror(rc));
785 goto request_out;
786 }
787 } else {
788 if(isatty(fileno(input_file))) {
789 fprintf(stderr, "Please paste the public key...\n");
790 }
791
792 if(key_format == key_format_arg_PEM) {
793 public_key = PEM_read_PUBKEY(input_file, NULL, NULL, NULL);
794 if(!public_key) {
795 fprintf(stderr, "Failed loading public key for request.\n");
796 goto request_out;
797 }
798 } else {
799 fprintf(stderr, "Only PEM supported for public key input.\n");
800 goto request_out;
801 }
802 }
803
804 algorithm = get_algorithm(public_key);
805 if(algorithm == 0) {
806 goto request_out;
807 }
808
809 md = get_hash(hash, &oid, &oid_len);
810 if(md == NULL) {
811 goto request_out;
812 }
813
814 if(!X509_REQ_set_pubkey(req, public_key)) {
815 fprintf(stderr, "Failed setting the request public key.\n");
816 goto request_out;
817 }
818
819 if(X509_REQ_set_version(req, 0) != 1) {
820 fprintf(stderr, "Failed setting the certificate request version.\n");
821 }
822
823 name = parse_name(subject);
824 if(!name) {
825 fprintf(stderr, "Failed encoding subject as name.\n");
826 goto request_out;
827 }
828 if(!X509_REQ_set_subject_name(req, name)) {
829 fprintf(stderr, "Failed setting the request subject.\n");
830 goto request_out;
831 }
832
833 #if (OPENSSL_VERSION_NUMBER < 0x10100000L) || defined(LIBRESSL_VERSION_NUMBER)
834 null_parameter.type = V_ASN1_NULL;
835 null_parameter.value.ptr = NULL;
836
837 md_len = (unsigned int)EVP_MD_size(md);
838 digest_len = sizeof(digest) - md_len;
839
840 memcpy(digest, oid, oid_len);
841 /* XXX: this should probably use X509_REQ_digest() but that's buggy */
842 if(!ASN1_item_digest(ASN1_ITEM_rptr(X509_REQ_INFO), md, req->req_info,
843 digest + oid_len, &digest_len)) {
844 fprintf(stderr, "Failed doing digest of request.\n");
845 goto request_out;
846 }
847
848 nid = get_hashnid(hash, algorithm);
849 if(nid == 0) {
850 fprintf(stderr, "Unsupported algorithm %x or hash %x\n", algorithm, hash);
851 goto request_out;
852 }
853
854 if(YKPIV_IS_RSA(algorithm)) {
855 signinput = digest;
856 len = oid_len + digest_len;
857 /* if it's RSA the parameter must be NULL, if ec non-present */
858 req->sig_alg->parameter = &null_parameter;
859 } else {
860 signinput = digest + oid_len;
861 len = digest_len;
862 }
863
864 req->sig_alg->algorithm = OBJ_nid2obj(nid);
865 {
866 unsigned char signature[1024] = {0};
867 size_t sig_len = sizeof(signature);
868 if(!sign_data(state, signinput, len, signature, &sig_len, algorithm, key)) {
869 fprintf(stderr, "Failed signing request.\n");
870 goto request_out;
871 }
872 ASN1_STRING_set(req->signature, signature, sig_len);
873 /* mark that all bits should be used. */
874 req->signature->flags = ASN1_STRING_FLAG_BITS_LEFT;
875 }
876 #else
877 /* With opaque structures we can not touch whatever we want, but we need
878 * to embed the sign_data function in the RSA/EC key structures */
879 wrap_public_key(state, algorithm, public_key, key, oid, oid_len);
880
881 if(X509_REQ_sign(req, public_key, md) == 0) {
882 fprintf(stderr, "Failed signing request.\n");
883 goto request_out;
884 }
885 #endif
886
887 if(key_format == key_format_arg_PEM) {
888 if(PEM_write_X509_REQ(output_file, req) == 1) {
889 ret = true;
890 } else {
891 fprintf(stderr, "Failed writing x509 information\n");
892 }
893 } else {
894 fprintf(stderr, "Only PEM support available for certificate requests.\n");
895 }
896
897 request_out:
898 if(input_file && input_file != stdin) {
899 fclose(input_file);
900 }
901 if(output_file && output_file != stdout) {
902 fclose(output_file);
903 }
904 if(public_key) {
905 EVP_PKEY_free(public_key);
906 }
907 if(req) {
908 #if (OPENSSL_VERSION_NUMBER < 0x10100000L) || defined(LIBRESSL_VERSION_NUMBER)
909 if(req->sig_alg->parameter) {
910 req->sig_alg->parameter = NULL;
911 }
912 #endif
913 X509_REQ_free(req);
914 }
915 if(name) {
916 X509_NAME_free(name);
917 }
918 return ret;
919 }
920
921 static const struct {
922 int nid;
923 const char *ext;
924 int critical;
925 } selfsign_extensions[] = {
926 {NID_subject_key_identifier, "hash", 0},
927 {NID_authority_key_identifier, "keyid", 0},
928 {NID_basic_constraints, "CA:true", 1},
929 };
930
selfsign_certificate(ykpiv_state * state,enum enum_key_format key_format,const char * input_file_name,enum enum_slot slot,char * subject,enum enum_hash hash,const int * serial,int validDays,const char * output_file_name)931 static bool selfsign_certificate(ykpiv_state *state, enum enum_key_format key_format,
932 const char *input_file_name, enum enum_slot slot, char *subject, enum enum_hash hash,
933 const int *serial, int validDays, const char *output_file_name) {
934 FILE *input_file = NULL;
935 FILE *output_file = NULL;
936 bool ret = false;
937 EVP_PKEY *public_key = NULL;
938 X509 *x509 = NULL;
939 X509_NAME *name = NULL;
940 const EVP_MD *md;
941 unsigned char algorithm;
942 int key = 0;
943 size_t oid_len;
944 const unsigned char *oid;
945 int nid;
946 ASN1_INTEGER *sno = ASN1_INTEGER_new();
947 BIGNUM *ser = NULL;
948 #if (OPENSSL_VERSION_NUMBER < 0x10100000L) || defined(LIBRESSL_VERSION_NUMBER)
949 unsigned char digest[EVP_MAX_MD_SIZE + MAX_OID_LEN] = {0};
950 unsigned int digest_len;
951 unsigned int md_len;
952 unsigned char *signinput;
953 size_t len = 0;
954 ASN1_TYPE null_parameter;
955 #endif
956
957 key = get_slot_hex(slot);
958
959 input_file = open_file(input_file_name, key_file_mode(key_format, false));
960 output_file = open_file(output_file_name, key_file_mode(key_format, true));
961 if(!input_file || !output_file) {
962 goto selfsign_out;
963 }
964
965 if(isatty(fileno(input_file))) {
966 fprintf(stderr, "Please paste the public key...\n");
967 }
968
969 if(key_format == key_format_arg_PEM) {
970 public_key = PEM_read_PUBKEY(input_file, NULL, NULL, NULL);
971 if(!public_key) {
972 fprintf(stderr, "Failed loading public key for certificate.\n");
973 goto selfsign_out;
974 }
975 } else {
976 fprintf(stderr, "Only PEM supported for public key input.\n");
977 goto selfsign_out;
978 }
979 algorithm = get_algorithm(public_key);
980 if(algorithm == 0) {
981 goto selfsign_out;
982 }
983
984 md = get_hash(hash, &oid, &oid_len);
985 if(md == NULL) {
986 goto selfsign_out;
987 }
988 x509 = X509_new();
989 if(!x509) {
990 fprintf(stderr, "Failed to allocate certificate structure.\n");
991 goto selfsign_out;
992 }
993 if(!X509_set_version(x509, 2)) {
994 fprintf(stderr, "Failed to set certificate version.\n");
995 goto selfsign_out;
996 }
997 if(!X509_set_pubkey(x509, public_key)) {
998 fprintf(stderr, "Failed to set the certificate public key.\n");
999 goto selfsign_out;
1000 }
1001 if(serial) {
1002 if(ASN1_INTEGER_set(sno, *serial) != 1) {
1003 fprintf(stderr, "Failed to read serial number.\n");
1004 goto selfsign_out;
1005 }
1006 } else {
1007 ser = BN_new();
1008 if(!ser) {
1009 fprintf(stderr, "Failed to allocate BIGNUM.\n");
1010 goto selfsign_out;
1011 }
1012 if(!BN_pseudo_rand(ser, 64, 0, 0)) {
1013 fprintf(stderr, "Failed to generate randomness.\n");
1014 goto selfsign_out;
1015 }
1016 if(!BN_to_ASN1_INTEGER(ser, sno)) {
1017 fprintf(stderr, "Failed to set random serial.\n");
1018 goto selfsign_out;
1019 }
1020 }
1021 if(!X509_set_serialNumber(x509, sno)) {
1022 fprintf(stderr, "Failed to set certificate serial.\n");
1023 goto selfsign_out;
1024 }
1025 if(!X509_gmtime_adj(X509_get_notBefore(x509), 0)) {
1026 fprintf(stderr, "Failed to set certificate notBefore.\n");
1027 goto selfsign_out;
1028 }
1029 if(!X509_gmtime_adj(X509_get_notAfter(x509), 60L * 60L * 24L * validDays)) {
1030 fprintf(stderr, "Failed to set certificate notAfter.\n");
1031 goto selfsign_out;
1032 }
1033 name = parse_name(subject);
1034 if(!name) {
1035 fprintf(stderr, "Failed encoding subject as name.\n");
1036 goto selfsign_out;
1037 }
1038 if(!X509_set_subject_name(x509, name)) {
1039 fprintf(stderr, "Failed setting certificate subject.\n");
1040 goto selfsign_out;
1041 }
1042 if(!X509_set_issuer_name(x509, name)) {
1043 fprintf(stderr, "Failed setting certificate issuer.\n");
1044 goto selfsign_out;
1045 }
1046 nid = get_hashnid(hash, algorithm);
1047 if(nid == 0) {
1048 goto selfsign_out;
1049 }
1050
1051 {
1052 X509V3_CTX ctx;
1053 int i;
1054 X509V3_set_ctx(&ctx, x509, x509, NULL, NULL, 0);
1055
1056 for(i = 0; i < sizeof(selfsign_extensions) / sizeof(selfsign_extensions[0]); i++) {
1057 X509_EXTENSION *ext = NULL;
1058 void *ext_struc;
1059 const X509V3_EXT_METHOD *method = X509V3_EXT_get_nid(selfsign_extensions[i].nid);
1060
1061 if(!method) {
1062 fprintf(stderr, "Failed to get extension method for nid %d.\n", selfsign_extensions[i].nid);
1063 goto selfsign_out;
1064 }
1065 if(method->v2i) {
1066 STACK_OF(CONF_VALUE) *nval = X509V3_parse_list(selfsign_extensions[i].ext);
1067 if(!nval) {
1068 fprintf(stderr, "Failed parsing extension value for nid %d.\n", selfsign_extensions[i].nid);
1069 goto selfsign_out;
1070 }
1071 ext_struc = method->v2i(method, &ctx, nval);
1072 } else if(method->s2i) {
1073 ext_struc = method->s2i(method, &ctx, selfsign_extensions[i].ext);
1074 } else {
1075 fprintf(stderr, "Unknown way to construct extension for nid %d.\n", selfsign_extensions[i].nid);
1076 goto selfsign_out;
1077 }
1078
1079 if(!ext_struc) {
1080 fprintf(stderr, "Failed constructing extension value for nid %d.\n", selfsign_extensions[i].nid);
1081 goto selfsign_out;
1082 }
1083
1084 ext = X509V3_EXT_i2d(selfsign_extensions[i].nid, selfsign_extensions[i].critical, ext_struc);
1085 if(!X509_add_ext(x509, ext, -1)) {
1086 fprintf(stderr, "Failed adding extension %d (%d).\n", i, selfsign_extensions[i].nid);
1087 goto selfsign_out;
1088 }
1089 }
1090 }
1091
1092 #if (OPENSSL_VERSION_NUMBER < 0x10100000L) || defined(LIBRESSL_VERSION_NUMBER)
1093 null_parameter.type = V_ASN1_NULL;
1094 null_parameter.value.ptr = NULL;
1095
1096 md_len = (unsigned int)EVP_MD_size(md);
1097 digest_len = sizeof(digest) - md_len;
1098
1099 if(YKPIV_IS_RSA(algorithm)) {
1100 signinput = digest;
1101 len = oid_len + md_len;
1102 /* for RSA parameter must be NULL, for ec non-present */
1103 x509->sig_alg->parameter = &null_parameter;
1104 x509->cert_info->signature->parameter = &null_parameter;
1105 } else {
1106 signinput = digest + oid_len;
1107 len = md_len;
1108 }
1109
1110 x509->sig_alg->algorithm = OBJ_nid2obj(nid);
1111 x509->cert_info->signature->algorithm = x509->sig_alg->algorithm;
1112 memcpy(digest, oid, oid_len);
1113 /* XXX: this should probably use X509_digest() but that looks buggy */
1114 if(!ASN1_item_digest(ASN1_ITEM_rptr(X509_CINF), md, x509->cert_info,
1115 digest + oid_len, &digest_len)) {
1116 fprintf(stderr, "Failed doing digest of certificate.\n");
1117 goto selfsign_out;
1118 }
1119 {
1120 unsigned char signature[1024] = {0};
1121 size_t sig_len = sizeof(signature);
1122 if(!sign_data(state, signinput, len, signature, &sig_len, algorithm, key)) {
1123 fprintf(stderr, "Failed signing certificate.\n");
1124 goto selfsign_out;
1125 }
1126 ASN1_STRING_set(x509->signature, signature, sig_len);
1127 /* setting flags to ASN1_STRING_FLAG_BITS_LEFT here marks that no bits
1128 * should be subtracted from the bit string, thus making sure that the
1129 * certificate can be validated. */
1130 x509->signature->flags = ASN1_STRING_FLAG_BITS_LEFT;
1131 }
1132 #else
1133 /* With opaque structures we can not touch whatever we want, but we need
1134 * to embed the sign_data function in the RSA/EC key structures */
1135 wrap_public_key(state, algorithm, public_key, key, oid, oid_len);
1136
1137 if(X509_sign(x509, public_key, md) == 0) {
1138 fprintf(stderr, "Failed signing certificate.\n");
1139 goto selfsign_out;
1140 }
1141 #endif
1142
1143 if(key_format == key_format_arg_PEM) {
1144 if(PEM_write_X509(output_file, x509) == 1) {
1145 ret = true;
1146 } else {
1147 fprintf(stderr, "Failed writing x509 information\n");
1148 }
1149
1150 } else {
1151 fprintf(stderr, "Only PEM support available for certificate requests.\n");
1152 }
1153
1154 selfsign_out:
1155 if(input_file && input_file != stdin) {
1156 fclose(input_file);
1157 }
1158 if(output_file && output_file != stdout) {
1159 fclose(output_file);
1160 }
1161 if(x509) {
1162 #if (OPENSSL_VERSION_NUMBER < 0x10100000L) || defined(LIBRESSL_VERSION_NUMBER)
1163 if(x509->sig_alg->parameter) {
1164 x509->sig_alg->parameter = NULL;
1165 x509->cert_info->signature->parameter = NULL;
1166 }
1167 #endif
1168 X509_free(x509);
1169 }
1170 if(public_key) {
1171 EVP_PKEY_free(public_key);
1172 }
1173 if(name) {
1174 X509_NAME_free(name);
1175 }
1176 if(ser) {
1177 BN_free(ser);
1178 }
1179 if(sno) {
1180 ASN1_INTEGER_free(sno);
1181 }
1182 return ret;
1183 }
1184
verify_pin(ykpiv_state * state,const char * pin)1185 static bool verify_pin(ykpiv_state *state, const char *pin) {
1186 int tries = -1;
1187 ykpiv_rc res;
1188 int len;
1189 len = strlen(pin);
1190
1191 if(len > 8) {
1192 fprintf(stderr, "Maximum 8 digits of PIN supported.\n");
1193 }
1194
1195 res = ykpiv_verify(state, pin, &tries);
1196 if(res == YKPIV_OK) {
1197 return true;
1198 } else if(res == YKPIV_WRONG_PIN || res == YKPIV_PIN_LOCKED) {
1199 if(tries > 0) {
1200 fprintf(stderr, "Pin verification failed, %d tries left before pin is blocked.\n", tries);
1201 } else {
1202 fprintf(stderr, "Pin code blocked, use unblock-pin action to unblock.\n");
1203 }
1204 } else {
1205 fprintf(stderr, "Pin code verification failed: '%s'\n", ykpiv_strerror(res));
1206 }
1207 return false;
1208 }
1209
1210 /* this function is called for all three of change-pin, change-puk and unblock pin
1211 * since they're very similar in what data they use. */
change_pin(ykpiv_state * state,enum enum_action action,const char * pin,const char * new_pin)1212 static bool change_pin(ykpiv_state *state, enum enum_action action, const char *pin,
1213 const char *new_pin) {
1214 const char *name = action == action_arg_changeMINUS_pin ? "pin" : "puk";
1215 int (*op)(ykpiv_state *state, const char * puk, size_t puk_len,
1216 const char * new_pin, size_t new_pin_len, int *tries) = ykpiv_change_pin;
1217 size_t pin_len;
1218 size_t new_len;
1219 int tries;
1220 ykpiv_rc res;
1221
1222 pin_len = strlen(pin);
1223 new_len = strlen(new_pin);
1224
1225 if(pin_len > 8 || new_len > 8) {
1226 fprintf(stderr, "Maximum 8 digits of PIN supported.\n");
1227 return false;
1228 }
1229
1230 if(new_len < 6) {
1231 fprintf(stderr, "Minimum 6 digits of PIN supported.\n");
1232 return false;
1233 }
1234
1235 if(action == action_arg_unblockMINUS_pin) {
1236 op = ykpiv_unblock_pin;
1237 }
1238 else if(action == action_arg_changeMINUS_puk) {
1239 op = ykpiv_change_puk;
1240 }
1241 res = op(state, pin, pin_len, new_pin, new_len, &tries);
1242
1243 switch (res) {
1244 case YKPIV_OK:
1245 return true;
1246
1247 case YKPIV_WRONG_PIN:
1248 fprintf(stderr, "Failed verifying %s code, now %d tries left before blocked.\n",
1249 name, tries);
1250 return false;
1251
1252 case YKPIV_PIN_LOCKED:
1253 if(action == action_arg_changeMINUS_pin) {
1254 fprintf(stderr, "The pin code is blocked, use the unblock-pin action to unblock it.\n");
1255 } else {
1256 fprintf(stderr, "The puk code is blocked, you will have to reinitialize the application.\n");
1257 }
1258 return false;
1259
1260 default:
1261 fprintf(stderr, "Failed changing/unblocking code, error: %s\n", ykpiv_strerror(res));
1262 return false;
1263 }
1264 }
1265
delete_certificate(ykpiv_state * state,enum enum_slot slot)1266 static bool delete_certificate(ykpiv_state *state, enum enum_slot slot) {
1267 return ykpiv_util_delete_cert(state, get_slot_hex(slot)) == YKPIV_OK;
1268 }
1269
read_certificate(ykpiv_state * state,enum enum_slot slot,enum enum_key_format key_format,const char * output_file_name)1270 static bool read_certificate(ykpiv_state *state, enum enum_slot slot,
1271 enum enum_key_format key_format, const char *output_file_name) {
1272 FILE *output_file;
1273 uint8_t *data = NULL;
1274 const unsigned char *ptr = NULL;
1275 X509 *x509 = NULL;
1276 bool ret = false;
1277 size_t cert_len = 0;
1278
1279 if (key_format != key_format_arg_PEM &&
1280 key_format != key_format_arg_DER &&
1281 key_format != key_format_arg_SSH) {
1282 fprintf(stderr, "Only PEM, DER and SSH format are supported for read-certificate.\n");
1283 return false;
1284 }
1285
1286 output_file = open_file(output_file_name, key_file_mode(key_format, true));
1287 if (!output_file) {
1288 return false;
1289 }
1290
1291 if (ykpiv_util_read_cert(state, get_slot_hex(slot), &data, &cert_len) != YKPIV_OK) {
1292 fprintf(stderr, "Failed fetching certificate.\n");
1293 goto read_cert_out;
1294 }
1295 ptr = data;
1296
1297 if (key_format == key_format_arg_PEM ||
1298 key_format == key_format_arg_SSH) {
1299 x509 = d2i_X509(NULL, (const unsigned char**)&ptr, cert_len);
1300 if (!x509) {
1301 fprintf(stderr, "Failed parsing x509 information.\n");
1302 goto read_cert_out;
1303 }
1304
1305 if (key_format == key_format_arg_PEM) {
1306 if(PEM_write_X509(output_file, x509) == 1) {
1307 ret = true;
1308 } else {
1309 fprintf(stderr, "Failed writing x509 information\n");
1310 }
1311 }
1312 else {
1313 if (!SSH_write_X509(output_file, x509)) {
1314 fprintf(stderr, "Unable to extract public key or not an RSA key.\n");
1315 goto read_cert_out;
1316 }
1317 ret = true;
1318 }
1319 } else { /* key_format_arg_DER */
1320 /* XXX: This will just dump the raw data in tag 0x70.. */
1321 fwrite(ptr, (size_t)cert_len, 1, output_file);
1322 ret = true;
1323 }
1324
1325 read_cert_out:
1326 if (output_file != stdout) {
1327 fclose(output_file);
1328 }
1329 if (x509) {
1330 X509_free(x509);
1331 }
1332 if (data) {
1333 ykpiv_util_free(state, data);
1334 }
1335 return ret;
1336 }
1337
sign_file(ykpiv_state * state,const char * input,const char * output,enum enum_slot slot,enum enum_algorithm algorithm,enum enum_hash hash,int verbosity)1338 static bool sign_file(ykpiv_state *state, const char *input, const char *output,
1339 enum enum_slot slot, enum enum_algorithm algorithm, enum enum_hash hash,
1340 int verbosity) {
1341 FILE *input_file = NULL;
1342 FILE *output_file = NULL;
1343 int key;
1344 unsigned int hash_len;
1345 unsigned char hashed[EVP_MAX_MD_SIZE * 2] = {0};
1346 bool ret = false;
1347 int algo;
1348 const EVP_MD *md;
1349
1350 key = get_slot_hex(slot);
1351
1352 input_file = open_file(input, INPUT_BIN);
1353 if(!input_file) {
1354 return false;
1355 }
1356
1357 if(isatty(fileno(input_file))) {
1358 fprintf(stderr, "Please paste the input...\n");
1359 }
1360
1361 output_file = open_file(output, OUTPUT_BIN);
1362 if(!output_file) {
1363 if(input_file && input_file != stdin) {
1364 fclose(input_file);
1365 }
1366 return false;
1367 }
1368
1369 algo = get_piv_algorithm(algorithm);
1370 if(algo == 0) {
1371 goto out;
1372 }
1373
1374 {
1375 EVP_MD_CTX *mdctx;
1376
1377 md = get_hash(hash, NULL, NULL);
1378 if(md == NULL) {
1379 goto out;
1380 }
1381
1382 mdctx = EVP_MD_CTX_create();
1383 if(EVP_DigestInit_ex(mdctx, md, NULL) != 1) {
1384 fprintf(stderr, "failed to initialize digest operation\n");
1385 goto out;
1386 }
1387 while(!feof(input_file)) {
1388 char buf[1024] = {0};
1389 size_t len = fread(buf, 1, 1024, input_file);
1390 if(EVP_DigestUpdate(mdctx, buf, len) != 1) {
1391 fprintf(stderr, "failed to update digest data\n");
1392 goto out;
1393 }
1394 }
1395 if(EVP_DigestFinal_ex(mdctx, hashed, &hash_len) != 1) {
1396 fprintf(stderr, "failed to finalize digest operation\n");
1397 goto out;
1398 }
1399
1400 if(verbosity) {
1401 fprintf(stderr, "file hashed as: ");
1402 dump_data(hashed, hash_len, stderr, true, format_arg_hex);
1403 }
1404 EVP_MD_CTX_destroy(mdctx);
1405 }
1406
1407 if(YKPIV_IS_RSA(algo)) {
1408 prepare_rsa_signature(hashed, hash_len, hashed, &hash_len, EVP_MD_type(md));
1409 }
1410
1411 {
1412 unsigned char buf[1024] = {0};
1413 size_t len = sizeof(buf);
1414 if(!sign_data(state, hashed, hash_len, buf, &len, algo, key)) {
1415 fprintf(stderr, "failed signing file\n");
1416 goto out;
1417 }
1418
1419 if(verbosity) {
1420 fprintf(stderr, "file signed as: ");
1421 dump_data(buf, len, stderr, true, format_arg_hex);
1422 }
1423 fwrite(buf, 1, len, output_file);
1424 ret = true;
1425 }
1426
1427 out:
1428 if(input_file && input_file != stdin) {
1429 fclose(input_file);
1430 }
1431
1432 if(output_file && output_file != stdout) {
1433 fclose(output_file);
1434 }
1435
1436 return ret;
1437 }
1438
print_cert_info(ykpiv_state * state,enum enum_slot slot,const EVP_MD * md,FILE * output)1439 static void print_cert_info(ykpiv_state *state, enum enum_slot slot, const EVP_MD *md,
1440 FILE *output) {
1441 int object = (int)ykpiv_util_slot_object(get_slot_hex(slot));
1442 int slot_name;
1443 unsigned char data[YKPIV_OBJ_MAX_SIZE] = {0};
1444 const unsigned char *ptr = data;
1445 unsigned long len = sizeof(data);
1446 unsigned long offs, cert_len;
1447 X509 *x509 = NULL;
1448 X509_NAME *subj;
1449 BIO *bio = NULL;
1450
1451 if(ykpiv_fetch_object(state, object, data, &len) != YKPIV_OK) {
1452 return;
1453 }
1454
1455 slot_name = get_slot_hex(slot);
1456
1457 fprintf(output, "Slot %x:\t", slot_name);
1458
1459 if(*ptr++ == 0x70) {
1460 unsigned int md_len = sizeof(data);
1461 const ASN1_TIME *not_before, *not_after;
1462
1463 offs = get_length(ptr, data + len, &cert_len);
1464 if(!offs) {
1465 fprintf(output, "Invalid cert length.\n");
1466 goto cert_out;
1467 }
1468 ptr += offs;
1469 x509 = d2i_X509(NULL, &ptr, cert_len);
1470 if(!x509) {
1471 fprintf(output, "Invalid cert data.\n");
1472 goto cert_out;
1473 }
1474 {
1475 EVP_PKEY *key = X509_get_pubkey(x509);
1476 if(!key) {
1477 fprintf(output, "Parse error.\n");
1478 goto cert_out;
1479 }
1480 fprintf(output, "\n\tAlgorithm:\t");
1481 switch(get_algorithm(key)) {
1482 case YKPIV_ALGO_RSA1024:
1483 fprintf(output, "RSA1024\n");
1484 break;
1485 case YKPIV_ALGO_RSA2048:
1486 fprintf(output, "RSA2048\n");
1487 break;
1488 case YKPIV_ALGO_ECCP256:
1489 fprintf(output, "ECCP256\n");
1490 break;
1491 case YKPIV_ALGO_ECCP384:
1492 fprintf(output, "ECCP384\n");
1493 break;
1494 default:
1495 fprintf(output, "Unknown\n");
1496 }
1497 EVP_PKEY_free(key);
1498 }
1499 subj = X509_get_subject_name(x509);
1500 if(!subj) {
1501 fprintf(output, "Parse error.\n");
1502 goto cert_out;
1503 }
1504 fprintf(output, "\tSubject DN:\t");
1505 if(X509_NAME_print_ex_fp(output, subj, 0, XN_FLAG_COMPAT) != 1) {
1506 fprintf(output, "Failed to write Subject DN.\n");
1507 goto cert_out;
1508 }
1509 fprintf(output, "\n");
1510 subj = X509_get_issuer_name(x509);
1511 if(!subj) {
1512 fprintf(output, "Parse error.\n");
1513 goto cert_out;
1514 }
1515 fprintf(output, "\tIssuer DN:\t");
1516 if(X509_NAME_print_ex_fp(output, subj, 0, XN_FLAG_COMPAT) != 1) {
1517 fprintf(output, "Failed to write Issuer DN.\n");
1518 goto cert_out;
1519 }
1520 fprintf(output, "\n");
1521 if(X509_digest(x509, md, data, &md_len) != 1) {
1522 fprintf(output, "Failed to digest data.\n");
1523 goto cert_out;
1524 }
1525 fprintf(output, "\tFingerprint:\t");
1526 dump_data(data, md_len, output, false, format_arg_hex);
1527
1528 bio = BIO_new_fp(output, BIO_NOCLOSE | BIO_FP_TEXT);
1529 not_before = X509_get_notBefore(x509);
1530 if(not_before) {
1531 fprintf(output, "\tNot Before:\t");
1532 if(ASN1_TIME_print(bio, not_before) != 1) {
1533 fprintf(output, "Failed to write Not Before time.\n");
1534 goto cert_out;
1535 }
1536 fprintf(output, "\n");
1537 }
1538 not_after = X509_get_notAfter(x509);
1539 if(not_after) {
1540 fprintf(output, "\tNot After:\t");
1541 if(ASN1_TIME_print(bio, not_after) != 1) {
1542 fprintf(output, "Failed to write Not After time.\n");
1543 goto cert_out;
1544 }
1545 fprintf(output, "\n");
1546 }
1547 } else {
1548 fprintf(output, "Parse error.\n");
1549 return;
1550 }
1551 cert_out:
1552 if(x509) {
1553 X509_free(x509);
1554 }
1555 if(bio) {
1556 BIO_free(bio);
1557 }
1558 }
1559
status(ykpiv_state * state,enum enum_hash hash,enum enum_slot slot,const char * output_file_name)1560 static bool status(ykpiv_state *state, enum enum_hash hash,
1561 enum enum_slot slot,
1562 const char *output_file_name) {
1563 const EVP_MD *md;
1564 unsigned char buf[YKPIV_OBJ_MAX_SIZE] = {0};
1565 long unsigned len = sizeof(buf);
1566 int i;
1567 uint32_t serial = 0;
1568 FILE *output_file = open_file(output_file_name, OUTPUT_TEXT);
1569
1570 if(!output_file) {
1571 return false;
1572 }
1573
1574 md = get_hash(hash, NULL, NULL);
1575 if(md == NULL) {
1576 return false;
1577 }
1578
1579 fprintf(output_file, "Version:\t");
1580 if (ykpiv_get_version(state, (char*)buf, (size_t)len) != YKPIV_OK) {
1581 fprintf(output_file, "No data available\n");
1582 } else {
1583 fprintf(output_file, "%s\n", (char*)buf);
1584 }
1585
1586 fprintf(output_file, "Serial Number:\t");
1587 if (ykpiv_get_serial(state, &serial) != YKPIV_OK) {
1588 fprintf(output_file, "No data available\n");
1589 } else {
1590 fprintf(output_file, "%d\n", serial);
1591 }
1592
1593 fprintf(output_file, "CHUID:\t");
1594 if(ykpiv_fetch_object(state, YKPIV_OBJ_CHUID, buf, &len) != YKPIV_OK) {
1595 fprintf(output_file, "No data available\n");
1596 } else {
1597 dump_data(buf, len, output_file, false, format_arg_hex);
1598 }
1599
1600 len = sizeof(buf);
1601 fprintf(output_file, "CCC:\t");
1602 if(ykpiv_fetch_object(state, YKPIV_OBJ_CAPABILITY, buf, &len) != YKPIV_OK) {
1603 fprintf(output_file, "No data available\n");
1604 } else {
1605 dump_data(buf, len, output_file, false, format_arg_hex);
1606 }
1607
1608 if (slot == slot__NULL)
1609 for (i = 0; i < 24; i++) {
1610 print_cert_info(state, i, md, output_file);
1611 }
1612 else
1613 print_cert_info(state, slot, md, output_file);
1614
1615 {
1616 int tries;
1617 ykpiv_verify(state, NULL, &tries);
1618 fprintf(output_file, "PIN tries left:\t%d\n", tries);
1619 }
1620
1621 if(output_file != stdout) {
1622 fclose(output_file);
1623 }
1624 return true;
1625 }
1626
test_signature(ykpiv_state * state,enum enum_slot slot,enum enum_hash hash,const char * input_file_name,enum enum_key_format cert_format,int verbose)1627 static bool test_signature(ykpiv_state *state, enum enum_slot slot,
1628 enum enum_hash hash, const char *input_file_name,
1629 enum enum_key_format cert_format, int verbose) {
1630 const EVP_MD *md;
1631 bool ret = false;
1632 unsigned char data[1024] = {0};
1633 unsigned int data_len;
1634 X509 *x509 = NULL;
1635 EVP_PKEY *pubkey = NULL;
1636 FILE *input_file = open_file(input_file_name, key_file_mode(cert_format, false));
1637
1638 if(!input_file) {
1639 fprintf(stderr, "Failed opening input file %s.\n", input_file_name);
1640 return false;
1641 }
1642
1643 if(isatty(fileno(input_file))) {
1644 fprintf(stderr, "Please paste the certificate to verify against...\n");
1645 }
1646
1647 if(cert_format == key_format_arg_PEM) {
1648 x509 = PEM_read_X509(input_file, NULL, NULL, NULL);
1649 } else if(cert_format == key_format_arg_DER) {
1650 x509 = d2i_X509_fp(input_file, NULL);
1651 } else {
1652 fprintf(stderr, "Only PEM or DER format is supported for test-signature.\n");
1653 goto test_out;
1654 }
1655 if(!x509) {
1656 fprintf(stderr, "Failed loading certificate for test-signature.\n");
1657 goto test_out;
1658 }
1659
1660 md = get_hash(hash, NULL, NULL);
1661 if(md == NULL) {
1662 goto test_out;
1663 }
1664
1665 {
1666 unsigned char rand[128] = {0};
1667 EVP_MD_CTX *mdctx;
1668 if(RAND_bytes(rand, sizeof(rand)) <= 0) {
1669 fprintf(stderr, "error: no randomness.\n");
1670 goto test_out;
1671 }
1672
1673 mdctx = EVP_MD_CTX_create();
1674 if(EVP_DigestInit_ex(mdctx, md, NULL) != 1) {
1675 fprintf(stderr, "Failed to initialize digest operation\n");
1676 goto test_out;
1677 }
1678 if(EVP_DigestUpdate(mdctx, rand, 128) != 1) {
1679 fprintf(stderr, "Failed to update digest data\n");
1680 goto test_out;
1681 }
1682 if(EVP_DigestFinal_ex(mdctx, data, &data_len) != 1) {
1683 fprintf(stderr, "Failed to finalize digest operation\n");
1684 goto test_out;
1685 }
1686 if(verbose) {
1687 fprintf(stderr, "Test data hashes as: ");
1688 dump_data(data, data_len, stderr, true, format_arg_hex);
1689 }
1690 EVP_MD_CTX_destroy(mdctx);
1691 }
1692
1693 {
1694 unsigned char signature[1024] = {0};
1695 unsigned char encoded[1024] = {0};
1696 unsigned char *ptr = data;
1697 unsigned int enc_len;
1698 size_t sig_len = sizeof(signature);
1699 int key = 0;
1700 unsigned char algorithm;
1701
1702 pubkey = X509_get_pubkey(x509);
1703 if(!pubkey) {
1704 fprintf(stderr, "Parse error.\n");
1705 goto test_out;
1706 }
1707 algorithm = get_algorithm(pubkey);
1708 if(algorithm == 0) {
1709 goto test_out;
1710 }
1711 key = get_slot_hex(slot);
1712 if(YKPIV_IS_RSA(algorithm)) {
1713 prepare_rsa_signature(data, data_len, encoded, &enc_len, EVP_MD_type(md));
1714 ptr = encoded;
1715 } else {
1716 enc_len = data_len;
1717 }
1718 if(!sign_data(state, ptr, enc_len, signature, &sig_len, algorithm, key)) {
1719 fprintf(stderr, "Failed signing test data.\n");
1720 goto test_out;
1721 }
1722
1723 switch(algorithm) {
1724 case YKPIV_ALGO_RSA1024:
1725 case YKPIV_ALGO_RSA2048:
1726 {
1727 RSA *rsa = EVP_PKEY_get1_RSA(pubkey);
1728 if(!rsa) {
1729 fprintf(stderr, "Failed getting RSA pubkey.\n");
1730 goto test_out;
1731 }
1732
1733 if(RSA_verify(EVP_MD_type(md), data, data_len, signature, sig_len, rsa) == 1) {
1734 fprintf(stderr, "Successful RSA verification.\n");
1735 ret = true;
1736 goto test_out;
1737 } else {
1738 fprintf(stderr, "Failed RSA verification.\n");
1739 goto test_out;
1740 }
1741 }
1742
1743 break;
1744 case YKPIV_ALGO_ECCP256:
1745 case YKPIV_ALGO_ECCP384:
1746 {
1747 EC_KEY *ec = EVP_PKEY_get1_EC_KEY(pubkey);
1748 if(ECDSA_verify(0, data, (int)data_len, signature, (int)sig_len, ec) == 1) {
1749 fprintf(stderr, "Successful ECDSA verification.\n");
1750 ret = true;
1751 goto test_out;
1752 } else {
1753 fprintf(stderr, "Failed ECDSA verification.\n");
1754 goto test_out;
1755 }
1756 }
1757 break;
1758 default:
1759 fprintf(stderr, "Unknown algorithm.\n");
1760 goto test_out;
1761 }
1762 }
1763 test_out:
1764 if(pubkey) {
1765 EVP_PKEY_free(pubkey);
1766 }
1767 if(x509) {
1768 X509_free(x509);
1769 }
1770 if(input_file != stdin) {
1771 fclose(input_file);
1772 }
1773 return ret;
1774 }
1775
test_decipher(ykpiv_state * state,enum enum_slot slot,const char * input_file_name,enum enum_key_format cert_format,int verbose)1776 static bool test_decipher(ykpiv_state *state, enum enum_slot slot,
1777 const char *input_file_name, enum enum_key_format cert_format, int verbose) {
1778 bool ret = false;
1779 X509 *x509 = NULL;
1780 EVP_PKEY *pubkey = NULL;
1781 EC_KEY *tmpkey = NULL;
1782 FILE *input_file = open_file(input_file_name, key_file_mode(cert_format, false));
1783
1784 if(!input_file) {
1785 fprintf(stderr, "Failed opening input file %s.\n", input_file_name);
1786 return false;
1787 }
1788
1789 if(isatty(fileno(input_file))) {
1790 fprintf(stderr, "Please paste the certificate to encrypt for...\n");
1791 }
1792
1793 if(cert_format == key_format_arg_PEM) {
1794 x509 = PEM_read_X509(input_file, NULL, NULL, NULL);
1795 } else if(cert_format == key_format_arg_DER) {
1796 x509 = d2i_X509_fp(input_file, NULL);
1797 } else {
1798 fprintf(stderr, "Only PEM or DER format is supported for test-decipher.\n");
1799 goto decipher_out;
1800 }
1801 if(!x509) {
1802 fprintf(stderr, "Failed loading certificate for test-decipher.\n");
1803 goto decipher_out;
1804 }
1805
1806 {
1807 int key = 0;
1808 unsigned char algorithm;
1809
1810 pubkey = X509_get_pubkey(x509);
1811 if(!pubkey) {
1812 fprintf(stderr, "Parse error.\n");
1813 goto decipher_out;
1814 }
1815 algorithm = get_algorithm(pubkey);
1816 if(algorithm == 0) {
1817 goto decipher_out;
1818 }
1819 key = get_slot_hex(slot);
1820 if(YKPIV_IS_RSA(algorithm)) {
1821 unsigned char secret[32] = {0};
1822 unsigned char secret2[32] = {0};
1823 unsigned char data[256] = {0};
1824 int len;
1825 size_t len2 = sizeof(data);
1826 RSA *rsa = EVP_PKEY_get1_RSA(pubkey);
1827
1828 if(RAND_bytes(secret, sizeof(secret)) <= 0) {
1829 fprintf(stderr, "error: no randomness.\n");
1830 ret = false;
1831 goto decipher_out;
1832 }
1833
1834 len = RSA_public_encrypt(sizeof(secret), secret, data, rsa, RSA_PKCS1_PADDING);
1835 if(len < 0) {
1836 fprintf(stderr, "Failed performing RSA encryption!\n");
1837 goto decipher_out;
1838 }
1839 if(ykpiv_decipher_data(state, data, (size_t)len, data, &len2, algorithm, key) != YKPIV_OK) {
1840 fprintf(stderr, "RSA decrypt failed!\n");
1841 goto decipher_out;
1842 }
1843 /* for some reason we have to give the padding check function data + 1 */
1844 len = RSA_padding_check_PKCS1_type_2(secret2, sizeof(secret2), data + 1, len2 - 1, RSA_size(rsa));
1845 if(len == sizeof(secret)) {
1846 if(verbose) {
1847 fprintf(stderr, "Generated nonce: ");
1848 dump_data(secret, sizeof(secret), stderr, true, format_arg_hex);
1849 fprintf(stderr, "Decrypted nonce: ");
1850 dump_data(secret2, sizeof(secret2), stderr, true, format_arg_hex);
1851 }
1852 if(memcmp(secret, secret2, sizeof(secret)) == 0) {
1853 fprintf(stderr, "Successfully performed RSA decryption!\n");
1854 ret = true;
1855 } else {
1856 fprintf(stderr, "Failed performing RSA decryption!\n");
1857 }
1858 } else {
1859 fprintf(stderr, "Failed unwrapping PKCS1 envelope.\n");
1860 }
1861 } else if(YKPIV_IS_EC(algorithm)) {
1862 unsigned char secret[48] = {0};
1863 unsigned char secret2[48] = {0};
1864 unsigned char public_key[97] = {0};
1865 unsigned char *ptr = public_key;
1866 size_t len = sizeof(secret);
1867 EC_KEY *ec = EVP_PKEY_get1_EC_KEY(pubkey);
1868 int nid;
1869 size_t key_len;
1870
1871 if(algorithm == YKPIV_ALGO_ECCP256) {
1872 nid = NID_X9_62_prime256v1;
1873 key_len = 32;
1874 } else {
1875 nid = NID_secp384r1;
1876 key_len = 48;
1877 }
1878
1879 tmpkey = EC_KEY_new_by_curve_name(nid);
1880 if(EC_KEY_generate_key(tmpkey) != 1) {
1881 fprintf(stderr, "Failed to generate EC key\n");
1882 goto decipher_out;
1883 }
1884 if(ECDH_compute_key(secret, len, EC_KEY_get0_public_key(ec), tmpkey, NULL) == -1) {
1885 fprintf(stderr, "Failed to compute ECDH key\n");
1886 goto decipher_out;
1887 }
1888
1889 if(i2o_ECPublicKey(tmpkey, &ptr) < 0) {
1890 fprintf(stderr, "Failed to parse EC public key\n");
1891 goto decipher_out;
1892 }
1893 if(ykpiv_decipher_data(state, public_key, (key_len * 2) + 1, secret2, &len, algorithm, key) != YKPIV_OK) {
1894 fprintf(stderr, "Failed ECDH exchange!\n");
1895 goto decipher_out;
1896 }
1897 if(verbose) {
1898 fprintf(stderr, "ECDH host generated: ");
1899 dump_data(secret, len, stderr, true, format_arg_hex);
1900 fprintf(stderr, "ECDH card generated: ");
1901 dump_data(secret2, len, stderr, true, format_arg_hex);
1902 }
1903 if(memcmp(secret, secret2, key_len) == 0) {
1904 fprintf(stderr, "Successfully performed ECDH exchange with card.\n");
1905 ret = true;
1906 } else {
1907 fprintf(stderr, "ECDH exchange with card failed!\n");
1908 }
1909 }
1910 }
1911
1912 decipher_out:
1913 if(tmpkey) {
1914 EC_KEY_free(tmpkey);
1915 }
1916 if(pubkey) {
1917 EVP_PKEY_free(pubkey);
1918 }
1919 if(x509) {
1920 X509_free(x509);
1921 }
1922 if(input_file != stdin) {
1923 fclose(input_file);
1924 }
1925 return ret;
1926 }
1927
list_readers(ykpiv_state * state)1928 static bool list_readers(ykpiv_state *state) {
1929 char readers[2048] = {0};
1930 char *reader_ptr;
1931 size_t len = sizeof(readers);
1932 ykpiv_rc rc = ykpiv_list_readers(state, readers, &len);
1933 if(rc != YKPIV_OK) {
1934 fprintf(stderr, "Failed listing readers.\n");
1935 return false;
1936 }
1937 for(reader_ptr = readers; *reader_ptr != '\0'; reader_ptr += strlen(reader_ptr) + 1) {
1938 printf("%s\n", reader_ptr);
1939 }
1940 return true;
1941 }
1942
attest(ykpiv_state * state,enum enum_slot slot,enum enum_key_format key_format,const char * output_file_name)1943 static bool attest(ykpiv_state *state, enum enum_slot slot,
1944 enum enum_key_format key_format, const char *output_file_name) {
1945 unsigned char data[2048] = {0};
1946 size_t len = sizeof(data);
1947 bool ret = false;
1948 X509 *x509 = NULL;
1949 int key;
1950 FILE *output_file = open_file(output_file_name, key_file_mode(key_format, true));
1951 if(!output_file) {
1952 return false;
1953 }
1954
1955 if(key_format != key_format_arg_PEM && key_format != key_format_arg_DER) {
1956 fprintf(stderr, "Only PEM and DER format are supported for attest..\n");
1957 return false;
1958 }
1959
1960 key = get_slot_hex(slot);
1961 if (ykpiv_attest(state, key, data, &len) != YKPIV_OK) {
1962 fprintf(stderr, "Failed to attest data.\n");
1963 goto attest_out;
1964 }
1965
1966 if(key_format == key_format_arg_PEM) {
1967 const unsigned char *ptr = data;
1968 int len2 = (int)len;
1969 x509 = d2i_X509(NULL, &ptr, len2);
1970 if(!x509) {
1971 fprintf(stderr, "Failed parsing x509 information.\n");
1972 goto attest_out;
1973 }
1974 if(PEM_write_X509(output_file, x509) != 1){
1975 fprintf(stderr, "Failed writing x509 information\n");
1976 }
1977 } else {
1978 fwrite(data, len, 1, output_file);
1979 }
1980 ret = true;
1981
1982 attest_out:
1983 if(output_file != stdout) {
1984 fclose(output_file);
1985 }
1986 if(x509) {
1987 X509_free(x509);
1988 }
1989 return ret;
1990 }
1991
write_object(ykpiv_state * state,int id,const char * input_file_name,int verbosity,enum enum_format format)1992 static bool write_object(ykpiv_state *state, int id,
1993 const char *input_file_name, int verbosity, enum enum_format format) {
1994 bool ret = false;
1995 FILE *input_file = NULL;
1996 unsigned char data[YKPIV_OBJ_MAX_SIZE] = {0};
1997 size_t len = sizeof(data);
1998 ykpiv_rc res;
1999
2000 input_file = open_file(input_file_name, data_file_mode(format, false));
2001 if(!input_file) {
2002 return false;
2003 }
2004
2005 if(isatty(fileno(input_file))) {
2006 fprintf(stderr, "Please paste the data...\n");
2007 }
2008
2009 len = read_data(data, len, input_file, format);
2010 if(len == 0) {
2011 fprintf(stderr, "Failed reading data\n");
2012 goto write_out;
2013 }
2014
2015 if(verbosity) {
2016 fprintf(stderr, "Writing %lu bytes of data to object %x.\n", (long unsigned int)len, id);
2017 }
2018
2019 if((res = ykpiv_save_object(state, id, data, len)) != YKPIV_OK) {
2020 fprintf(stderr, "Failed writing data to device: %s\n", ykpiv_strerror(res));
2021 } else {
2022 ret = true;
2023 }
2024
2025 write_out:
2026 if(input_file != stdin) {
2027 fclose(input_file);
2028 }
2029 return ret;
2030 }
2031
read_object(ykpiv_state * state,int id,const char * output_file_name,enum enum_format format)2032 static bool read_object(ykpiv_state *state, int id, const char *output_file_name,
2033 enum enum_format format) {
2034 FILE *output_file = NULL;
2035 unsigned char data[YKPIV_OBJ_MAX_SIZE] = {0};
2036 unsigned long len = sizeof(data);
2037 bool ret = false;
2038
2039 output_file = open_file(output_file_name, data_file_mode(format, true));
2040 if(!output_file) {
2041 return false;
2042 }
2043
2044 if(ykpiv_fetch_object(state, id, data, &len) != YKPIV_OK) {
2045 fprintf(stderr, "Failed fetching object.\n");
2046 goto read_out;
2047 }
2048
2049 dump_data(data, len, output_file, false, format);
2050 ret = true;
2051
2052 read_out:
2053 if(output_file != stdout) {
2054 fclose(output_file);
2055 }
2056 return ret;
2057 }
2058
main(int argc,char * argv[])2059 int main(int argc, char *argv[]) {
2060 struct gengetopt_args_info args_info;
2061 ykpiv_state *state;
2062 int verbosity;
2063 enum enum_action action;
2064 unsigned int i;
2065 int ret = EXIT_SUCCESS;
2066 bool authed = false;
2067 char pwbuf[128] = {0};
2068 char *password;
2069
2070 if(cmdline_parser(argc, argv, &args_info) != 0) {
2071 return EXIT_FAILURE;
2072 }
2073
2074 verbosity = args_info.verbose_arg + (int)args_info.verbose_given;
2075 password = args_info.password_arg;
2076
2077 for(i = 0; i < args_info.action_given; i++) {
2078 action = *(args_info.action_arg + i);
2079 switch(action) {
2080 case action_arg_requestMINUS_certificate:
2081 case action_arg_selfsignMINUS_certificate:
2082 if(!args_info.subject_arg) {
2083 fprintf(stderr, "The '%s' action needs a subject (-S) to operate on.\n",
2084 cmdline_parser_action_values[action]);
2085 cmdline_parser_free(&args_info);
2086 return EXIT_FAILURE;
2087 }
2088 /* fall through */
2089 case action_arg_generate:
2090 case action_arg_importMINUS_key:
2091 case action_arg_importMINUS_certificate:
2092 case action_arg_deleteMINUS_certificate:
2093 case action_arg_readMINUS_certificate:
2094 case action_arg_testMINUS_signature:
2095 case action_arg_testMINUS_decipher:
2096 case action_arg_attest:
2097 if(args_info.slot_arg == slot__NULL) {
2098 fprintf(stderr, "The '%s' action needs a slot (-s) to operate on.\n",
2099 cmdline_parser_action_values[action]);
2100 cmdline_parser_free(&args_info);
2101 return EXIT_FAILURE;
2102 }
2103 break;
2104 case action_arg_pinMINUS_retries:
2105 if(!args_info.pin_retries_given || !args_info.puk_retries_given) {
2106 fprintf(stderr, "The '%s' action needs both --pin-retries and --puk-retries arguments.\n",
2107 cmdline_parser_action_values[action]);
2108 cmdline_parser_free(&args_info);
2109 return EXIT_FAILURE;
2110 }
2111 break;
2112 case action_arg_writeMINUS_object:
2113 case action_arg_readMINUS_object:
2114 if(!args_info.id_given) {
2115 fprintf(stderr, "The '%s' action needs the --id argument.\n",
2116 cmdline_parser_action_values[action]);
2117 cmdline_parser_free(&args_info);
2118 return EXIT_FAILURE;
2119 }
2120 break;
2121 case action_arg_changeMINUS_pin:
2122 case action_arg_changeMINUS_puk:
2123 case action_arg_unblockMINUS_pin:
2124 case action_arg_verifyMINUS_pin:
2125 case action_arg_setMINUS_mgmMINUS_key:
2126 case action_arg_setMINUS_chuid:
2127 case action_arg_setMINUS_ccc:
2128 case action_arg_version:
2129 case action_arg_reset:
2130 case action_arg_status:
2131 case action_arg_listMINUS_readers:
2132 case action__NULL:
2133 default:
2134 continue;
2135 }
2136 }
2137
2138 if(ykpiv_init(&state, verbosity) != YKPIV_OK) {
2139 fprintf(stderr, "Failed initializing library.\n");
2140 cmdline_parser_free(&args_info);
2141 return EXIT_FAILURE;
2142 }
2143
2144 if(ykpiv_connect(state, args_info.reader_arg) != YKPIV_OK) {
2145 fprintf(stderr, "Failed to connect to yubikey.\nTry removing and reconnecting the device.\n");
2146 ykpiv_done(state);
2147 cmdline_parser_free(&args_info);
2148 return EXIT_FAILURE;
2149 }
2150
2151 for(i = 0; i < args_info.action_given; i++) {
2152 action = *(args_info.action_arg + i);
2153 switch(action) {
2154 case action_arg_importMINUS_key:
2155 case action_arg_importMINUS_certificate:
2156 if(args_info.key_format_arg == key_format_arg_PKCS12 && !password) {
2157 if(verbosity) {
2158 fprintf(stderr, "Asking for password since '%s' needs it.\n", cmdline_parser_action_values[action]);
2159 }
2160 if(!read_pw("Password", pwbuf, sizeof(pwbuf), false, args_info.stdin_input_flag)) {
2161 fprintf(stderr, "Failed to get password.\n");
2162 ykpiv_done(state);
2163 cmdline_parser_free(&args_info);
2164 return EXIT_FAILURE;
2165 }
2166 password = pwbuf;
2167 }
2168 /* fall through */
2169 case action_arg_generate:
2170 case action_arg_setMINUS_mgmMINUS_key:
2171 case action_arg_pinMINUS_retries:
2172 case action_arg_setMINUS_chuid:
2173 case action_arg_setMINUS_ccc:
2174 case action_arg_deleteMINUS_certificate:
2175 case action_arg_writeMINUS_object:
2176 if(!authed) {
2177 unsigned char key[KEY_LEN] = {0};
2178 size_t key_len = sizeof(key);
2179 char keybuf[KEY_LEN*2+2] = {0}; /* one extra byte for potential \n */
2180 char *key_ptr = args_info.key_arg;
2181 if(verbosity) {
2182 fprintf(stderr, "Authenticating since action '%s' needs that.\n", cmdline_parser_action_values[action]);
2183 }
2184 if(args_info.key_given && args_info.key_orig == NULL) {
2185 if(!read_pw("management key", keybuf, sizeof(keybuf), false, args_info.stdin_input_flag)) {
2186 fprintf(stderr, "Failed to read management key from stdin,\n");
2187 ykpiv_done(state);
2188 cmdline_parser_free(&args_info);
2189 return EXIT_FAILURE;
2190 }
2191 key_ptr = keybuf;
2192 }
2193 if(ykpiv_hex_decode(key_ptr, strlen(key_ptr), key, &key_len) != YKPIV_OK) {
2194 fprintf(stderr, "Failed decoding key!\n");
2195 ykpiv_done(state);
2196 cmdline_parser_free(&args_info);
2197 return EXIT_FAILURE;
2198 }
2199
2200 if(ykpiv_authenticate(state, key) != YKPIV_OK) {
2201 fprintf(stderr, "Failed authentication with the application.\n");
2202 ykpiv_done(state);
2203 cmdline_parser_free(&args_info);
2204 return EXIT_FAILURE;
2205 }
2206 if(verbosity) {
2207 fprintf(stderr, "Successful application authentication.\n");
2208 }
2209 authed = true;
2210 } else {
2211 if(verbosity) {
2212 fprintf(stderr, "Skipping authentication for '%s' since it's already done.\n", cmdline_parser_action_values[action]);
2213 }
2214 }
2215 break;
2216 case action_arg_version:
2217 case action_arg_reset:
2218 case action_arg_requestMINUS_certificate:
2219 case action_arg_verifyMINUS_pin:
2220 case action_arg_changeMINUS_pin:
2221 case action_arg_changeMINUS_puk:
2222 case action_arg_unblockMINUS_pin:
2223 case action_arg_selfsignMINUS_certificate:
2224 case action_arg_readMINUS_certificate:
2225 case action_arg_status:
2226 case action_arg_testMINUS_signature:
2227 case action_arg_testMINUS_decipher:
2228 case action_arg_listMINUS_readers:
2229 case action_arg_attest:
2230 case action_arg_readMINUS_object:
2231 case action__NULL:
2232 default:
2233 if(verbosity) {
2234 fprintf(stderr, "Action '%s' does not need authentication.\n", cmdline_parser_action_values[action]);
2235 }
2236 }
2237 }
2238
2239
2240 /* openssl setup.. */
2241 #if (OPENSSL_VERSION_NUMBER < 0x10100000L)
2242 OpenSSL_add_all_algorithms();
2243 #endif
2244
2245
2246 for(i = 0; i < args_info.action_given; i++) {
2247 char new_keybuf[KEY_LEN*2+2] = {0}; /* one extra byte for potential \n */
2248 char *new_mgm_key = args_info.new_key_arg;
2249 action = *(args_info.action_arg + i);
2250 if(verbosity) {
2251 fprintf(stderr, "Now processing for action '%s'.\n",
2252 cmdline_parser_action_values[action]);
2253 }
2254 switch(action) {
2255 case action_arg_version:
2256 print_version(state, args_info.output_arg);
2257 break;
2258 case action_arg_generate:
2259 if(generate_key(state, args_info.slot_arg, args_info.algorithm_arg, args_info.output_arg, args_info.key_format_arg,
2260 args_info.pin_policy_arg, args_info.touch_policy_arg) == false) {
2261 ret = EXIT_FAILURE;
2262 } else {
2263 fprintf(stderr, "Successfully generated a new private key.\n");
2264 }
2265 break;
2266 case action_arg_setMINUS_mgmMINUS_key:
2267 if(!new_mgm_key) {
2268 if(!read_pw("new management key", new_keybuf, sizeof(new_keybuf), true, args_info.stdin_input_flag)) {
2269 fprintf(stderr, "Failed to read management key from stdin,\n");
2270 ret = EXIT_FAILURE;
2271 break;
2272 }
2273 new_mgm_key = new_keybuf;
2274 }
2275 if(strlen(new_mgm_key) == (KEY_LEN * 2)){
2276 unsigned char new_key[KEY_LEN] = {0};
2277 size_t new_key_len = sizeof(new_key);
2278 if(ykpiv_hex_decode(new_mgm_key, strlen(new_mgm_key), new_key, &new_key_len) != YKPIV_OK) {
2279 fprintf(stderr, "Failed decoding new key!\n");
2280 ret = EXIT_FAILURE;
2281 } else if(ykpiv_set_mgmkey2(state, new_key, args_info.touch_policy_arg == touch_policy_arg_always ? 1 : 0) != YKPIV_OK) {
2282 fprintf(stderr, "Failed setting the new key!");
2283 if(args_info.touch_policy_arg != touch_policy__NULL) {
2284 fprintf(stderr, " Maybe touch policy is not supported on this key?");
2285 }
2286 fprintf(stderr, "\n");
2287 ret = EXIT_FAILURE;
2288 } else {
2289 fprintf(stderr, "Successfully set new management key.\n");
2290 }
2291 } else {
2292 fprintf(stderr, "The new management key has to be exactly %d hexadecimal characters.\n", KEY_LEN * 2);
2293 ret = EXIT_FAILURE;
2294 }
2295 break;
2296 case action_arg_reset:
2297 if(reset(state) == false) {
2298 fprintf(stderr, "Reset failed, are pincodes blocked?\n");
2299 ret = EXIT_FAILURE;
2300 } else {
2301 fprintf(stderr, "Successfully reset the application.\n");
2302 }
2303 break;
2304 case action_arg_pinMINUS_retries:
2305 if(set_pin_retries(state, args_info.pin_retries_arg, args_info.puk_retries_arg, verbosity) == false) {
2306 fprintf(stderr, "Failed changing pin retries.\n");
2307 ret = EXIT_FAILURE;
2308 } else {
2309 fprintf(stderr, "Successfully changed pin retries to %d and puk retries to %d, both codes have been reset to default now.\n",
2310 args_info.pin_retries_arg, args_info.puk_retries_arg);
2311 }
2312 break;
2313 case action_arg_importMINUS_key:
2314 if(import_key(state, args_info.key_format_arg, args_info.input_arg, args_info.slot_arg, password,
2315 args_info.pin_policy_arg, args_info.touch_policy_arg) == false) {
2316 fprintf(stderr, "Unable to import private key\n");
2317 ret = EXIT_FAILURE;
2318 } else {
2319 fprintf(stderr, "Successfully imported a new private key.\n");
2320 }
2321 break;
2322 case action_arg_importMINUS_certificate:
2323 if(import_cert(state, args_info.key_format_arg, args_info.input_arg, args_info.slot_arg, password) == false) {
2324 ret = EXIT_FAILURE;
2325 } else {
2326 fprintf(stderr, "Successfully imported a new certificate.\n");
2327 }
2328 break;
2329 case action_arg_setMINUS_ccc:
2330 case action_arg_setMINUS_chuid:
2331 if(set_cardid(state, verbosity, action == action_arg_setMINUS_chuid ? CHUID : CCC) == false) {
2332 ret = EXIT_FAILURE;
2333 } else {
2334 fprintf(stderr, "Successfully set new %s.\n", action == action_arg_setMINUS_chuid ? "CHUID" : "CCC");
2335 }
2336 break;
2337 case action_arg_requestMINUS_certificate:
2338 if(request_certificate(state, args_info.key_format_arg, args_info.input_arg,
2339 args_info.slot_arg, args_info.subject_arg, args_info.hash_arg,
2340 args_info.output_arg, args_info.attestation_flag) == false) {
2341 ret = EXIT_FAILURE;
2342 } else {
2343 fprintf(stderr, "Successfully generated a certificate request.\n");
2344 }
2345 break;
2346 case action_arg_verifyMINUS_pin: {
2347 char pinbuf[8+2] = {0};
2348 char *pin = args_info.pin_arg;
2349
2350 if(!pin) {
2351 if (!read_pw("PIN", pinbuf, sizeof(pinbuf), false, args_info.stdin_input_flag)) {
2352 fprintf(stderr, "Failed to get PIN.\n");
2353 ykpiv_done(state);
2354 cmdline_parser_free(&args_info);
2355 return EXIT_FAILURE;
2356 }
2357 pin = pinbuf;
2358 }
2359 if(verify_pin(state, pin)) {
2360 fprintf(stderr, "Successfully verified PIN.\n");
2361 } else {
2362 ret = EXIT_FAILURE;
2363 }
2364 break;
2365 }
2366 case action_arg_changeMINUS_pin:
2367 case action_arg_changeMINUS_puk:
2368 case action_arg_unblockMINUS_pin: {
2369 char pinbuf[8+2] = {0};
2370 char new_pinbuf[8+2] = {0};
2371 char *pin = args_info.pin_arg;
2372 char *new_pin = args_info.new_pin_arg;
2373 const char *name = action == action_arg_changeMINUS_pin ? "pin" : "puk";
2374 const char *new_name = action == action_arg_changeMINUS_puk ? "new puk" : "new pin";
2375
2376 if(!pin) {
2377 if (!read_pw(name, pinbuf, sizeof(pinbuf), false, args_info.stdin_input_flag)) {
2378 fprintf(stderr, "Failed to get %s.\n", name);
2379 ykpiv_done(state);
2380 cmdline_parser_free(&args_info);
2381 return EXIT_FAILURE;
2382 }
2383 pin = pinbuf;
2384 }
2385 if(!new_pin) {
2386 if (!read_pw(new_name, new_pinbuf, sizeof(new_pinbuf), true, args_info.stdin_input_flag)) {
2387 fprintf(stderr, "Failed to get %s.\n", new_name);
2388 ykpiv_done(state);
2389 cmdline_parser_free(&args_info);
2390 return EXIT_FAILURE;
2391 }
2392 new_pin = new_pinbuf;
2393 }
2394 if(change_pin(state, action, pin, new_pin)) {
2395 if(action == action_arg_unblockMINUS_pin) {
2396 fprintf(stderr, "Successfully unblocked the pin code.\n");
2397 } else {
2398 fprintf(stderr, "Successfully changed the %s code.\n",
2399 action == action_arg_changeMINUS_pin ? "pin" : "puk");
2400 }
2401 } else {
2402 ret = EXIT_FAILURE;
2403 }
2404 break;
2405 }
2406 case action_arg_selfsignMINUS_certificate:
2407 if(selfsign_certificate(state, args_info.key_format_arg, args_info.input_arg,
2408 args_info.slot_arg, args_info.subject_arg, args_info.hash_arg,
2409 args_info.serial_given ? &args_info.serial_arg : NULL, args_info.valid_days_arg,
2410 args_info.output_arg) == false) {
2411 ret = EXIT_FAILURE;
2412 } else {
2413 fprintf(stderr, "Successfully generated a new self signed certificate.\n");
2414 }
2415 break;
2416 case action_arg_deleteMINUS_certificate:
2417 if(delete_certificate(state, args_info.slot_arg) == false) {
2418 ret = EXIT_FAILURE;
2419 }
2420 break;
2421 case action_arg_readMINUS_certificate:
2422 if(read_certificate(state, args_info.slot_arg, args_info.key_format_arg,
2423 args_info.output_arg) == false) {
2424 ret = EXIT_FAILURE;
2425 }
2426 break;
2427 case action_arg_status:
2428 if(status(state, args_info.hash_arg, args_info.slot_arg, args_info.output_arg) == false) {
2429 ret = EXIT_FAILURE;
2430 }
2431 break;
2432 case action_arg_testMINUS_signature:
2433 if(test_signature(state, args_info.slot_arg, args_info.hash_arg,
2434 args_info.input_arg, args_info.key_format_arg, verbosity) == false) {
2435 ret = EXIT_FAILURE;
2436 }
2437 break;
2438 case action_arg_testMINUS_decipher:
2439 if(test_decipher(state, args_info.slot_arg, args_info.input_arg,
2440 args_info.key_format_arg, verbosity) == false) {
2441 ret = EXIT_FAILURE;
2442 }
2443 break;
2444 case action_arg_listMINUS_readers:
2445 if(list_readers(state) == false) {
2446 ret = EXIT_FAILURE;
2447 }
2448 break;
2449 case action_arg_writeMINUS_object:
2450 if(write_object(state, args_info.id_arg, args_info.input_arg, verbosity,
2451 args_info.format_arg) == false) {
2452 ret = EXIT_FAILURE;
2453 }
2454 break;
2455 case action_arg_readMINUS_object:
2456 if(read_object(state, args_info.id_arg, args_info.output_arg,
2457 args_info.format_arg) == false) {
2458 ret = EXIT_FAILURE;
2459 }
2460 break;
2461 case action_arg_attest:
2462 if(attest(state, args_info.slot_arg, args_info.key_format_arg,
2463 args_info.output_arg) == false) {
2464 ret = EXIT_FAILURE;
2465 }
2466 break;
2467 case action__NULL:
2468 default:
2469 fprintf(stderr, "Wrong action. %d.\n", action);
2470 ret = EXIT_FAILURE;
2471 }
2472 if(ret == EXIT_FAILURE) {
2473 break;
2474 }
2475 }
2476
2477 if(ret == EXIT_SUCCESS && args_info.sign_flag) {
2478 if(args_info.slot_arg == slot__NULL) {
2479 fprintf(stderr, "The sign action needs a slot (-s) to operate on.\n");
2480 ret = EXIT_FAILURE;
2481 }
2482 else if(sign_file(state, args_info.input_arg, args_info.output_arg,
2483 args_info.slot_arg, args_info.algorithm_arg, args_info.hash_arg,
2484 verbosity)) {
2485 fprintf(stderr, "Signature successful!\n");
2486 } else {
2487 fprintf(stderr, "Failed signing!\n");
2488 ret = EXIT_FAILURE;
2489 }
2490 }
2491
2492 ykpiv_done(state);
2493 #if (OPENSSL_VERSION_NUMBER < 0x10100000L)
2494 EVP_cleanup();
2495 #endif
2496 cmdline_parser_free(&args_info);
2497 return ret;
2498 }
2499