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 2 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, write to the Free Software
18
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
27
#include <sys/types.h>
31
#define JNLIB_NEED_LOG_LOGV
35
#include "../common/ttyio.h"
36
#include "../common/simple-pwquery.h"
37
#include "apdu.h" /* for open_reader */
39
#include "app-common.h"
44
enum cmd_and_opt_values
54
static ARGPARSE_OPTS opts[] = {
56
{ 301, NULL, 0, "@Options:\n " },
58
{ oVerbose, "verbose", 0, "verbose" },
59
{ oReaderPort, "reader-port", 2, "|N|connect to reader at port N"},
60
{ octapiDriver, "ctapi-driver", 2, "NAME|use NAME as ctAPI driver"},
61
{ oDebug, "debug" ,4|16, "set debugging flags"},
62
{ oDebugAll, "debug-all" ,0, "enable full debugging"},
67
static void copykeys (APP app, const char *fname);
71
my_strusage (int level)
76
case 11: p = "sc-copykeys (GnuPG)";
78
case 13: p = VERSION; break;
79
case 17: p = PRINTABLE_OS_NAME; break;
80
case 19: p = _("Please report bugs to <" PACKAGE_BUGREPORT ">.\n");
83
case 40: p = _("Usage: sc-copykeys [options] (-h for help)\n");
85
case 41: p = _("Syntax: sc-copykeys [options] "
87
"Copy keys to a smartcards\n");
95
/* Used by gcry for logging */
97
my_gcry_logger (void *dummy, int level, const char *fmt, va_list arg_ptr)
99
/* translate the log levels */
102
case GCRY_LOG_CONT: level = JNLIB_LOG_CONT; break;
103
case GCRY_LOG_INFO: level = JNLIB_LOG_INFO; break;
104
case GCRY_LOG_WARN: level = JNLIB_LOG_WARN; break;
105
case GCRY_LOG_ERROR:level = JNLIB_LOG_ERROR; break;
106
case GCRY_LOG_FATAL:level = JNLIB_LOG_FATAL; break;
107
case GCRY_LOG_BUG: level = JNLIB_LOG_BUG; break;
108
case GCRY_LOG_DEBUG:level = JNLIB_LOG_DEBUG; break;
109
default: level = JNLIB_LOG_ERROR; break;
111
log_logv (level, fmt, arg_ptr);
116
main (int argc, char **argv )
120
const char *reader_port = NULL;
121
struct app_ctx_s appbuf;
123
memset (&appbuf, 0, sizeof appbuf);
125
set_strusage (my_strusage);
126
gcry_control (GCRYCTL_SUSPEND_SECMEM_WARN);
127
log_set_prefix ("sc-copykeys", 1);
129
/* check that the libraries are suitable. Do it here because
130
the option parsing may need services of the library */
131
if (!gcry_check_version (NEED_LIBGCRYPT_VERSION) )
133
log_fatal( _("libgcrypt is too old (need %s, have %s)\n"),
134
NEED_LIBGCRYPT_VERSION, gcry_check_version (NULL) );
137
gcry_set_log_handler (my_gcry_logger, NULL);
138
gcry_control (GCRYCTL_DISABLE_SECMEM, 0); /* FIXME - we want to use it */
139
/* FIXME? gcry_control (GCRYCTL_USE_SECURE_RNDPOOL);*/
143
pargs.flags= 1; /* do not remove the args */
144
while (arg_parse (&pargs, opts) )
148
case oVerbose: opt.verbose++; break;
149
case oDebug: opt.debug |= pargs.r.ret_ulong; break;
150
case oDebugAll: opt.debug = ~0; break;
151
case oReaderPort: reader_port = pargs.r.ret_str; break;
152
case octapiDriver: opt.ctapi_driver = pargs.r.ret_str; break;
153
default : pargs.err = 2; break;
156
if (log_get_errorcount(0))
162
slot = apdu_open_reader (reader_port);
166
/* FIXME: Use select_application. */
168
rc = app_select_openpgp (&appbuf);
171
log_error ("selecting openpgp failed: %s\n", gpg_strerror (rc));
174
appbuf.initialized = 1;
175
log_info ("openpgp application selected\n");
177
copykeys (&appbuf, *argv);
186
send_status_info (CTRL ctrl, const char *keyword, ...)
194
read_file (const char *fname, size_t *r_length)
201
fp = fname? fopen (fname, "rb") : stdin;
204
log_error ("can't open `%s': %s\n",
205
fname? fname: "[stdin]", strerror (errno));
209
if (fstat (fileno(fp), &st))
211
log_error ("can't stat `%s': %s\n",
212
fname? fname: "[stdin]", strerror (errno));
219
buf = xmalloc (buflen+1);
220
if (fread (buf, buflen, 1, fp) != 1)
222
log_error ("error reading `%s': %s\n",
223
fname? fname: "[stdin]", strerror (errno));
238
read_key (const char *fname)
245
buf = read_file (fname, &buflen);
249
rc = gcry_sexp_new (&private, buf, buflen, 1);
252
log_error ("gcry_sexp_new failed: %s\n", gpg_strerror (rc));
263
sexp_to_kparms (gcry_sexp_t sexp, unsigned long *created)
265
gcry_sexp_t list, l2;
274
list = gcry_sexp_find_token (sexp, "private-key", 0 );
278
/* quick hack to get the creation time. */
279
l2 = gcry_sexp_find_token (list, "created", 0);
280
if (l2 && (name = gcry_sexp_nth_data (l2, 1, &n)))
282
char *tmp = xmalloc (n+1);
283
memcpy (tmp, name, n);
285
*created = strtoul (tmp, NULL, 10);
288
gcry_sexp_release (l2);
289
l2 = gcry_sexp_cadr (list);
290
gcry_sexp_release (list);
292
name = gcry_sexp_nth_data (list, 0, &n);
293
if(!name || n != 3 || memcmp (name, "rsa", 3))
295
gcry_sexp_release (list);
299
/* Parameter names used with RSA. */
301
array = xcalloc (strlen(elems) + 1, sizeof *array);
302
for (idx=0, s=elems; *s; s++, idx++ )
304
l2 = gcry_sexp_find_token (list, s, 1);
307
for (i=0; i<idx; i++)
308
gcry_mpi_release (array[i]);
310
gcry_sexp_release (list);
311
return NULL; /* required parameter not found */
313
array[idx] = gcry_sexp_nth_mpi (l2, 1, GCRYMPI_FMT_USG);
314
gcry_sexp_release (l2);
317
for (i=0; i<idx; i++)
318
gcry_mpi_release (array[i]);
320
gcry_sexp_release (list);
321
return NULL; /* required parameter is invalid */
325
gcry_sexp_release (list);
330
/* Return true if the SHA1 fingerprint FPR consists only of zeroes. */
332
fpr_is_zero (const char *fpr)
336
for (i=0; i < 20 && !fpr[i]; i++)
343
show_sha1_fpr (const unsigned char *fpr)
349
for (i=0; i < 20 ; i+=2, fpr += 2 )
353
tty_printf (" %02X%02X", *fpr, fpr[1]);
357
tty_printf (" [none]");
361
/* Query the card, show a list of already stored keys and ask the user
362
where to store the key. Returns the key number or 0 for cancel
368
char *serialno, *disp_name, *pubkey_url;
369
unsigned char *fpr1, *fpr2, *fpr3;
372
if (app_openpgp_cardinfo (app,
376
&fpr1, &fpr2, &fpr3))
386
tty_printf ("Serial number ....: %s\n",
387
serialno? serialno : "[none]");
388
tty_printf ("Name of cardholder: %s\n",
389
disp_name && *disp_name? disp_name : "[not set]");
390
tty_printf ("URL of public key : %s\n",
391
pubkey_url && *pubkey_url? pubkey_url : "[not set]");
392
tty_printf ("Signature key ....:");
393
show_sha1_fpr (fpr1);
394
tty_printf ("Encryption key....:");
395
show_sha1_fpr (fpr2);
396
tty_printf ("Authentication key:");
397
show_sha1_fpr (fpr3);
400
"1 - store as signature key and reset usage counter\n"
401
"2 - store as encryption key\n"
402
"3 - store as authentication key\n"
406
answer = tty_get("Your selection? ");
408
if (strlen (answer) != 1)
410
else if ( *answer == '1' )
412
if ( (fpr1 && !fpr_is_zero (fpr1)) )
415
log_error ("WARNING: signature key does already exists!\n");
417
if ( tty_get_answer_is_yes ("Replace existing key? ") )
429
else if ( *answer == '2' )
431
if ( (fpr2 && !fpr_is_zero (fpr2)) )
434
log_error ("WARNING: encryption key does already exists!\n");
436
if ( tty_get_answer_is_yes ("Replace existing key? ") )
448
else if ( *answer == '3' )
450
if ( (fpr3 && !fpr_is_zero (fpr3)) )
453
log_error ("WARNING: authentication key does already exists!\n");
455
if ( tty_get_answer_is_yes ("Replace existing key? ") )
467
else if ( *answer == 'q' || *answer == 'Q')
485
/* Callback function to ask for a PIN. */
487
pincb (void *arg, const char *prompt, char **pinvalue)
489
char *pin = xstrdup ("12345678");
491
/* pin = simple_pwquery (NULL, NULL, prompt, */
492
/* "We need the admin's PIN to store the key on the card", */
495
/* return gpg_error (GPG_ERR_CANCELED); */
504
/* This function expects a file (or NULL for stdin) with the secret
505
and public key parameters. This file should consist of an
506
S-expression as used by gpg-agent. Only the unprotected format is
511
(n #00e0ce9..[some bytes not shown]..51#)
513
(d #046129F..[some bytes not shown]..81#)
514
(p #00e861b..[some bytes not shown]..f1#)
515
(q #00f7a7c..[some bytes not shown]..61#)
516
(u #304559a..[some bytes not shown]..9b#))
517
(uri http://foo.bar x-foo:whatever_you_want))
521
copykeys (APP app, const char *fname)
525
gcry_mpi_t *mpis, rsa_n, rsa_e, rsa_p, rsa_q;
528
unsigned char *template, *tp;
529
unsigned char m[128], e[4];
531
unsigned long creation_date;
535
if (!strcmp (fname, "-"))
538
private = read_key (fname);
542
mpis = sexp_to_kparms (private, &creation_date);
545
log_info ("no creation date found - assuming current date\n");
546
created_at = time (NULL);
549
created_at = creation_date;
550
gcry_sexp_release (private);
553
log_error ("invalid structure of key file or not RSA\n");
556
/* MPIS is now an array with the key parameters as defined by OpenPGP. */
559
gcry_mpi_release (mpis[2]);
562
gcry_mpi_release (mpis[5]);
565
nbits = gcry_mpi_get_nbits (rsa_e);
566
if (nbits < 2 || nbits > 32)
568
log_error ("public exponent too large (more than 32 bits)\n");
571
nbits = gcry_mpi_get_nbits (rsa_p);
574
log_error ("length of first RSA prime is not 512\n");
577
nbits = gcry_mpi_get_nbits (rsa_q);
580
log_error ("length of second RSA prime is not 512\n");
584
nbits = gcry_mpi_get_nbits (rsa_n);
587
log_error ("length of RSA modulus is not 1024\n");
591
keyno = query_card (app);
595
/* Build the private key template as described in section 4.3.3.6 of
597
0xC0 <length> public exponent
598
0xC1 <length> prime p
599
0xC2 <length> prime q */
600
template = tp = xmalloc (1+2 + 1+1+4 + 1+1+64 + 1+1+64);
603
rc = gcry_mpi_print (GCRYMPI_FMT_USG, tp, 4, &n, rsa_e);
606
log_error ("mpi_print failed: %s\n", gpg_strerror (rc));
614
memmove (tp+4-n, tp, 4-n);
621
rc = gcry_mpi_print (GCRYMPI_FMT_USG, tp, 64, &n, rsa_p);
624
log_error ("mpi_print failed: %s\n", gpg_strerror (rc));
632
rc = gcry_mpi_print (GCRYMPI_FMT_USG, tp, 64, &n, rsa_q);
635
log_error ("mpi_print failed: %s\n", gpg_strerror (rc));
640
assert (tp - template == 138);
642
/* (we need the modulus to calculate the fingerprint) */
643
rc = gcry_mpi_print (GCRYMPI_FMT_USG, m, 128, &n, rsa_n);
646
log_error ("mpi_print failed: %s\n", gpg_strerror (rc));
653
rc = app_openpgp_storekey (app, keyno,
654
template, tp - template,
662
log_error ("error storing key: %s\n", gpg_strerror (rc));
665
log_info ("key successfully stored\n");
667
unsigned char *mm, *ee;
671
rc = app_openpgp_readkey (app, keyno, &mm, &mmlen, &ee, &eelen);
674
log_error ("error reading key back: %s\n", gpg_strerror (rc));
678
/* Strip leading zeroes. */
679
for (i=0; i < mmlen && !mm[i]; i++)
682
memmove (mm, mm+i, mmlen);
683
for (i=0; i < eelen && !ee[i]; i++)
686
memmove (ee, ee+i, eelen);
688
if (eelen != elen || mmlen != mlen)
690
log_error ("key parameter length mismatch (n=%u/%u, e=%u/%u)\n",
691
(unsigned int)mlen, (unsigned int)mmlen,
692
(unsigned int)elen, (unsigned int)eelen);
698
if (memcmp (m, mm, mlen))
700
log_error ("key parameter n mismatch\n");
701
log_printhex ("original n: ", m, mlen);
702
log_printhex (" copied n: ", mm, mlen);
707
if (memcmp (e, ee, elen))
709
log_error ("key parameter e mismatch\n");
710
log_printhex ("original e: ", e, elen);
711
log_printhex (" copied e: ", ee, elen);
721
gcry_mpi_release (rsa_e);
722
gcry_mpi_release (rsa_p);
723
gcry_mpi_release (rsa_q);
724
gcry_mpi_release (rsa_n);
728
gcry_mpi_release (rsa_e);
729
gcry_mpi_release (rsa_p);
730
gcry_mpi_release (rsa_q);
731
gcry_mpi_release (rsa_n);