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