1 /* sc-copykeys.c - A tool to store keys on a smartcard.
2 * Copyright (C) 2003 Free Software Foundation, Inc.
4 * This file is part of GnuPG.
6 * GnuPG is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 3 of the License, or
9 * (at your option) any later version.
11 * GnuPG is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, see <http://www.gnu.org/licenses/>.
26 #include <sys/types.h>
30 #define JNLIB_NEED_LOG_LOGV
34 #include "../common/ttyio.h"
35 #include "../common/simple-pwquery.h"
36 #include "apdu.h" /* for open_reader */
38 #include "app-common.h"
43 enum cmd_and_opt_values
53 static ARGPARSE_OPTS opts
[] = {
55 { 301, NULL
, 0, "@Options:\n " },
57 { oVerbose
, "verbose", 0, "verbose" },
58 { oReaderPort
, "reader-port", 2, "|N|connect to reader at port N"},
59 { octapiDriver
, "ctapi-driver", 2, "NAME|use NAME as ctAPI driver"},
60 { oDebug
, "debug" ,4|16, "set debugging flags"},
61 { oDebugAll
, "debug-all" ,0, "enable full debugging"},
66 static void copykeys (APP app
, const char *fname
);
70 my_strusage (int level
)
75 case 11: p
= "sc-copykeys (GnuPG)";
77 case 13: p
= VERSION
; break;
78 case 17: p
= PRINTABLE_OS_NAME
; break;
79 case 19: p
= _("Please report bugs to <" PACKAGE_BUGREPORT
">.\n");
82 case 40: p
= _("Usage: sc-copykeys [options] (-h for help)\n");
84 case 41: p
= _("Syntax: sc-copykeys [options] "
86 "Copy keys to a smartcards\n");
96 main (int argc
, char **argv
)
100 const char *reader_port
= NULL
;
101 struct app_ctx_s appbuf
;
103 memset (&appbuf
, 0, sizeof appbuf
);
105 set_strusage (my_strusage
);
106 gcry_control (GCRYCTL_SUSPEND_SECMEM_WARN
);
107 log_set_prefix ("sc-copykeys", 1);
109 /* check that the libraries are suitable. Do it here because
110 the option parsing may need services of the library */
111 if (!gcry_check_version (NEED_LIBGCRYPT_VERSION
) )
113 log_fatal (_("%s is too old (need %s, have %s)\n"), "libgcrypt",
114 NEED_LIBGCRYPT_VERSION
, gcry_check_version (NULL
) );
117 setup_libgcrypt_logging ();
118 gcry_control (GCRYCTL_DISABLE_SECMEM
, 0); /* FIXME - we want to use it */
119 /* FIXME? gcry_control (GCRYCTL_USE_SECURE_RNDPOOL);*/
123 pargs
.flags
= 1; /* do not remove the args */
124 while (arg_parse (&pargs
, opts
) )
128 case oVerbose
: opt
.verbose
++; break;
129 case oDebug
: opt
.debug
|= pargs
.r
.ret_ulong
; break;
130 case oDebugAll
: opt
.debug
= ~0; break;
131 case oReaderPort
: reader_port
= pargs
.r
.ret_str
; break;
132 case octapiDriver
: opt
.ctapi_driver
= pargs
.r
.ret_str
; break;
133 default : pargs
.err
= 2; break;
136 if (log_get_errorcount(0))
142 slot
= apdu_open_reader (reader_port
);
146 /* FIXME: Use select_application. */
148 rc
= app_select_openpgp (&appbuf
);
151 log_error ("selecting openpgp failed: %s\n", gpg_strerror (rc
));
154 appbuf
.initialized
= 1;
155 log_info ("openpgp application selected\n");
157 copykeys (&appbuf
, *argv
);
166 send_status_info (CTRL ctrl
, const char *keyword
, ...)
174 read_file (const char *fname
, size_t *r_length
)
181 fp
= fname
? fopen (fname
, "rb") : stdin
;
184 log_error ("can't open `%s': %s\n",
185 fname
? fname
: "[stdin]", strerror (errno
));
189 if (fstat (fileno(fp
), &st
))
191 log_error ("can't stat `%s': %s\n",
192 fname
? fname
: "[stdin]", strerror (errno
));
199 buf
= xmalloc (buflen
+1);
200 if (fread (buf
, buflen
, 1, fp
) != 1)
202 log_error ("error reading `%s': %s\n",
203 fname
? fname
: "[stdin]", strerror (errno
));
218 read_key (const char *fname
)
225 buf
= read_file (fname
, &buflen
);
229 rc
= gcry_sexp_new (&private, buf
, buflen
, 1);
232 log_error ("gcry_sexp_new failed: %s\n", gpg_strerror (rc
));
243 sexp_to_kparms (gcry_sexp_t sexp
, unsigned long *created
)
245 gcry_sexp_t list
, l2
;
254 list
= gcry_sexp_find_token (sexp
, "private-key", 0 );
258 /* quick hack to get the creation time. */
259 l2
= gcry_sexp_find_token (list
, "created", 0);
260 if (l2
&& (name
= gcry_sexp_nth_data (l2
, 1, &n
)))
262 char *tmp
= xmalloc (n
+1);
263 memcpy (tmp
, name
, n
);
265 *created
= strtoul (tmp
, NULL
, 10);
268 gcry_sexp_release (l2
);
269 l2
= gcry_sexp_cadr (list
);
270 gcry_sexp_release (list
);
272 name
= gcry_sexp_nth_data (list
, 0, &n
);
273 if(!name
|| n
!= 3 || memcmp (name
, "rsa", 3))
275 gcry_sexp_release (list
);
279 /* Parameter names used with RSA. */
281 array
= xcalloc (strlen(elems
) + 1, sizeof *array
);
282 for (idx
=0, s
=elems
; *s
; s
++, idx
++ )
284 l2
= gcry_sexp_find_token (list
, s
, 1);
287 for (i
=0; i
<idx
; i
++)
288 gcry_mpi_release (array
[i
]);
290 gcry_sexp_release (list
);
291 return NULL
; /* required parameter not found */
293 array
[idx
] = gcry_sexp_nth_mpi (l2
, 1, GCRYMPI_FMT_USG
);
294 gcry_sexp_release (l2
);
297 for (i
=0; i
<idx
; i
++)
298 gcry_mpi_release (array
[i
]);
300 gcry_sexp_release (list
);
301 return NULL
; /* required parameter is invalid */
305 gcry_sexp_release (list
);
310 /* Return true if the SHA1 fingerprint FPR consists only of zeroes. */
312 fpr_is_zero (const char *fpr
)
316 for (i
=0; i
< 20 && !fpr
[i
]; i
++)
323 show_sha1_fpr (const unsigned char *fpr
)
329 for (i
=0; i
< 20 ; i
+=2, fpr
+= 2 )
333 tty_printf (" %02X%02X", *fpr
, fpr
[1]);
337 tty_printf (" [none]");
341 /* Query the card, show a list of already stored keys and ask the user
342 where to store the key. Returns the key number or 0 for cancel
348 char *serialno
, *disp_name
, *pubkey_url
;
349 unsigned char *fpr1
, *fpr2
, *fpr3
;
352 if (app_openpgp_cardinfo (app
,
356 &fpr1
, &fpr2
, &fpr3
))
366 tty_printf ("Serial number ....: %s\n",
367 serialno
? serialno
: "[none]");
368 tty_printf ("Name of cardholder: %s\n",
369 disp_name
&& *disp_name
? disp_name
: "[not set]");
370 tty_printf ("URL of public key : %s\n",
371 pubkey_url
&& *pubkey_url
? pubkey_url
: "[not set]");
372 tty_printf ("Signature key ....:");
373 show_sha1_fpr (fpr1
);
374 tty_printf ("Encryption key....:");
375 show_sha1_fpr (fpr2
);
376 tty_printf ("Authentication key:");
377 show_sha1_fpr (fpr3
);
380 "1 - store as signature key and reset usage counter\n"
381 "2 - store as encryption key\n"
382 "3 - store as authentication key\n"
386 answer
= tty_get("Your selection? ");
388 if (strlen (answer
) != 1)
390 else if ( *answer
== '1' )
392 if ( (fpr1
&& !fpr_is_zero (fpr1
)) )
395 log_error ("WARNING: signature key does already exists!\n");
397 if ( tty_get_answer_is_yes ("Replace existing key? ") )
409 else if ( *answer
== '2' )
411 if ( (fpr2
&& !fpr_is_zero (fpr2
)) )
414 log_error ("WARNING: encryption key does already exists!\n");
416 if ( tty_get_answer_is_yes ("Replace existing key? ") )
428 else if ( *answer
== '3' )
430 if ( (fpr3
&& !fpr_is_zero (fpr3
)) )
433 log_error ("WARNING: authentication key does already exists!\n");
435 if ( tty_get_answer_is_yes ("Replace existing key? ") )
447 else if ( *answer
== 'q' || *answer
== 'Q')
465 /* Callback function to ask for a PIN. */
467 pincb (void *arg
, const char *prompt
, char **pinvalue
)
469 char *pin
= xstrdup ("12345678");
471 /* pin = simple_pwquery (NULL, NULL, prompt, */
472 /* "We need the admin's PIN to store the key on the card", */
475 /* return gpg_error (GPG_ERR_CANCELED); */
484 /* This function expects a file (or NULL for stdin) with the secret
485 and public key parameters. This file should consist of an
486 S-expression as used by gpg-agent. Only the unprotected format is
491 (n #00e0ce9..[some bytes not shown]..51#)
493 (d #046129F..[some bytes not shown]..81#)
494 (p #00e861b..[some bytes not shown]..f1#)
495 (q #00f7a7c..[some bytes not shown]..61#)
496 (u #304559a..[some bytes not shown]..9b#))
497 (uri http://foo.bar x-foo:whatever_you_want))
501 copykeys (APP app
, const char *fname
)
505 gcry_mpi_t
*mpis
, rsa_n
, rsa_e
, rsa_p
, rsa_q
;
508 unsigned char *template, *tp
;
509 unsigned char m
[128], e
[4];
511 unsigned long creation_date
;
515 if (!strcmp (fname
, "-"))
518 private = read_key (fname
);
522 mpis
= sexp_to_kparms (private, &creation_date
);
525 log_info ("no creation date found - assuming current date\n");
526 created_at
= time (NULL
);
529 created_at
= creation_date
;
530 gcry_sexp_release (private);
533 log_error ("invalid structure of key file or not RSA\n");
536 /* MPIS is now an array with the key parameters as defined by OpenPGP. */
539 gcry_mpi_release (mpis
[2]);
542 gcry_mpi_release (mpis
[5]);
545 nbits
= gcry_mpi_get_nbits (rsa_e
);
546 if (nbits
< 2 || nbits
> 32)
548 log_error ("public exponent too large (more than 32 bits)\n");
551 nbits
= gcry_mpi_get_nbits (rsa_p
);
554 log_error ("length of first RSA prime is not 512\n");
557 nbits
= gcry_mpi_get_nbits (rsa_q
);
560 log_error ("length of second RSA prime is not 512\n");
564 nbits
= gcry_mpi_get_nbits (rsa_n
);
567 log_error ("length of RSA modulus is not 1024\n");
571 keyno
= query_card (app
);
575 /* Build the private key template as described in section 4.3.3.6 of
577 0xC0 <length> public exponent
578 0xC1 <length> prime p
579 0xC2 <length> prime q */
580 template = tp
= xmalloc (1+2 + 1+1+4 + 1+1+64 + 1+1+64);
583 rc
= gcry_mpi_print (GCRYMPI_FMT_USG
, tp
, 4, &n
, rsa_e
);
586 log_error ("mpi_print failed: %s\n", gpg_strerror (rc
));
594 memmove (tp
+4-n
, tp
, 4-n
);
601 rc
= gcry_mpi_print (GCRYMPI_FMT_USG
, tp
, 64, &n
, rsa_p
);
604 log_error ("mpi_print failed: %s\n", gpg_strerror (rc
));
612 rc
= gcry_mpi_print (GCRYMPI_FMT_USG
, tp
, 64, &n
, rsa_q
);
615 log_error ("mpi_print failed: %s\n", gpg_strerror (rc
));
620 assert (tp
- template == 138);
622 /* (we need the modulus to calculate the fingerprint) */
623 rc
= gcry_mpi_print (GCRYMPI_FMT_USG
, m
, 128, &n
, rsa_n
);
626 log_error ("mpi_print failed: %s\n", gpg_strerror (rc
));
633 rc
= app_openpgp_storekey (app
, keyno
,
634 template, tp
- template,
642 log_error ("error storing key: %s\n", gpg_strerror (rc
));
645 log_info ("key successfully stored\n");
647 unsigned char *mm
, *ee
;
651 rc
= app_openpgp_readkey (app
, keyno
, &mm
, &mmlen
, &ee
, &eelen
);
654 log_error ("error reading key back: %s\n", gpg_strerror (rc
));
658 /* Strip leading zeroes. */
659 for (i
=0; i
< mmlen
&& !mm
[i
]; i
++)
662 memmove (mm
, mm
+i
, mmlen
);
663 for (i
=0; i
< eelen
&& !ee
[i
]; i
++)
666 memmove (ee
, ee
+i
, eelen
);
668 if (eelen
!= elen
|| mmlen
!= mlen
)
670 log_error ("key parameter length mismatch (n=%u/%u, e=%u/%u)\n",
671 (unsigned int)mlen
, (unsigned int)mmlen
,
672 (unsigned int)elen
, (unsigned int)eelen
);
678 if (memcmp (m
, mm
, mlen
))
680 log_error ("key parameter n mismatch\n");
681 log_printhex ("original n: ", m
, mlen
);
682 log_printhex (" copied n: ", mm
, mlen
);
687 if (memcmp (e
, ee
, elen
))
689 log_error ("key parameter e mismatch\n");
690 log_printhex ("original e: ", e
, elen
);
691 log_printhex (" copied e: ", ee
, elen
);
701 gcry_mpi_release (rsa_e
);
702 gcry_mpi_release (rsa_p
);
703 gcry_mpi_release (rsa_q
);
704 gcry_mpi_release (rsa_n
);
708 gcry_mpi_release (rsa_e
);
709 gcry_mpi_release (rsa_p
);
710 gcry_mpi_release (rsa_q
);
711 gcry_mpi_release (rsa_n
);