* Makefile.am: Add sc-copykeys program.
[gnupg.git] / scd / sc-copykeys.c
1 /* sc-copykeys.c - A tool to store keys on a smartcard.
2  *      Copyright (C) 2003 Free Software Foundation, Inc.
3  *
4  * This file is part of GnuPG.
5  *
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.
10  *
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.
15  *
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
19  */
20
21 #include <config.h>
22
23 #include <stdio.h>
24 #include <stdlib.h>
25 #include <string.h>
26 #include <assert.h>
27 #include <sys/types.h>
28 #include <sys/stat.h>
29 #include <unistd.h>
30
31 #define JNLIB_NEED_LOG_LOGV
32 #include "scdaemon.h"
33 #include <gcrypt.h>
34
35 #include "../common/ttyio.h"
36 #include "../common/simple-pwquery.h"
37 #include "apdu.h" /* for open_reader */
38 #include "atr.h"
39 #include "app-common.h"
40
41 #define _(a) (a)
42
43
44 enum cmd_and_opt_values 
45 { oVerbose        = 'v',
46   oReaderPort     = 500,
47   oDebug,
48   oDebugAll,
49
50 aTest };
51
52
53 static ARGPARSE_OPTS opts[] = {
54   
55   { 301, NULL, 0, "@Options:\n " },
56
57   { oVerbose, "verbose",   0, "verbose" },
58   { oReaderPort, "reader-port", 1, "|N|connect to reader at port N"},
59   { oDebug,     "debug"     ,4|16, "set debugging flags"},
60   { oDebugAll, "debug-all" ,0, "enable full debugging"},
61   {0}
62 };
63
64
65 static void copykeys (APP app, const char *fname);
66
67
68 static const char *
69 my_strusage (int level)
70 {
71   const char *p;
72   switch (level)
73     {
74     case 11: p = "sc-copykeys (GnuPG)";
75       break;
76     case 13: p = VERSION; break;
77     case 17: p = PRINTABLE_OS_NAME; break;
78     case 19: p = _("Please report bugs to <" PACKAGE_BUGREPORT ">.\n");
79       break;
80     case 1:
81     case 40: p =  _("Usage: sc-copykeys [options] (-h for help)\n");
82       break;
83     case 41: p = _("Syntax: sc-copykeys [options] "
84                    "file-with-key\n"
85                     "Copy keys to a smartcards\n");
86     break;
87     
88     default: p = NULL;
89     }
90   return p;
91 }
92
93 /* Used by gcry for logging */
94 static void
95 my_gcry_logger (void *dummy, int level, const char *fmt, va_list arg_ptr)
96 {
97   /* translate the log levels */
98   switch (level)
99     {
100     case GCRY_LOG_CONT: level = JNLIB_LOG_CONT; break;
101     case GCRY_LOG_INFO: level = JNLIB_LOG_INFO; break;
102     case GCRY_LOG_WARN: level = JNLIB_LOG_WARN; break;
103     case GCRY_LOG_ERROR:level = JNLIB_LOG_ERROR; break;
104     case GCRY_LOG_FATAL:level = JNLIB_LOG_FATAL; break;
105     case GCRY_LOG_BUG:  level = JNLIB_LOG_BUG; break;
106     case GCRY_LOG_DEBUG:level = JNLIB_LOG_DEBUG; break;
107     default:            level = JNLIB_LOG_ERROR; break;  
108     }
109   log_logv (level, fmt, arg_ptr);
110 }
111
112
113 int
114 main (int argc, char **argv )
115 {
116   ARGPARSE_ARGS pargs;
117   int slot, rc;
118   int reader_port = 32768; /* First USB reader. */
119   struct app_ctx_s appbuf;
120
121   memset (&appbuf, 0, sizeof appbuf);
122
123   set_strusage (my_strusage);
124   gcry_control (GCRYCTL_SUSPEND_SECMEM_WARN);
125   log_set_prefix ("sc-copykeys", 1); 
126
127   /* check that the libraries are suitable.  Do it here because
128      the option parsing may need services of the library */
129   if (!gcry_check_version (NEED_LIBGCRYPT_VERSION) )
130     {
131       log_fatal( _("libgcrypt is too old (need %s, have %s)\n"),
132                  NEED_LIBGCRYPT_VERSION, gcry_check_version (NULL) );
133     }
134
135   gcry_set_log_handler (my_gcry_logger, NULL);
136   gcry_control (GCRYCTL_DISABLE_SECMEM, 0); /* FIXME - we want to use it */
137   /* FIXME? gcry_control (GCRYCTL_USE_SECURE_RNDPOOL);*/
138
139   pargs.argc = &argc;
140   pargs.argv = &argv;
141   pargs.flags=  1;  /* do not remove the args */
142   while (arg_parse (&pargs, opts) )
143     {
144       switch (pargs.r_opt)
145         {
146         case oVerbose: opt.verbose++; break;
147         case oDebug: opt.debug |= pargs.r.ret_ulong; break;
148         case oDebugAll: opt.debug = ~0; break;
149         default : pargs.err = 2; break;
150         }
151     }
152   if (log_get_errorcount(0))
153     exit(2);
154
155   if (argc != 1)
156     usage (1);
157
158   slot = apdu_open_reader (reader_port);
159   if (slot == -1)
160     exit (1);
161
162   /* FIXME: Use select_application. */
163   appbuf.slot = slot;
164   rc = app_select_openpgp (&appbuf, &appbuf.serialno, &appbuf.serialnolen);
165   if (rc)
166     {
167       log_error ("selecting openpgp failed: %s\n", gpg_strerror (rc));
168       exit (1);
169     }
170   appbuf.initialized = 1;
171   log_info ("openpgp application selected\n");
172
173   copykeys (&appbuf, *argv);
174
175
176   return 0;
177 }
178
179
180
181 void
182 send_status_info (CTRL ctrl, const char *keyword, ...)
183 {
184   /* DUMMY */
185 }
186
187
188
189 static char *
190 read_file (const char *fname, size_t *r_length)
191 {
192   FILE *fp;
193   struct stat st;
194   char *buf;
195   size_t buflen;
196   
197   fp = fname? fopen (fname, "rb") : stdin;
198   if (!fp)
199     {
200       log_error ("can't open `%s': %s\n",
201                  fname? fname: "[stdin]", strerror (errno));
202       return NULL;
203     }
204   
205   if (fstat (fileno(fp), &st))
206     {
207       log_error ("can't stat `%s': %s\n", 
208                  fname? fname: "[stdin]", strerror (errno));
209       if (fname)
210         fclose (fp);
211       return NULL;
212     }
213
214   buflen = st.st_size;
215   buf = xmalloc (buflen+1);
216   if (fread (buf, buflen, 1, fp) != 1)
217     {
218       log_error ("error reading `%s': %s\n", 
219                  fname? fname: "[stdin]", strerror (errno));
220       if (fname)
221         fclose (fp);
222       xfree (buf);
223       return NULL;
224     }
225   if (fname)
226     fclose (fp);
227
228   *r_length = buflen;
229   return buf;
230 }
231
232
233 static gcry_sexp_t
234 read_key (const char *fname)
235 {
236   char *buf;
237   size_t buflen;
238   gcry_sexp_t private;
239   int rc;
240   
241   buf = read_file (fname, &buflen);
242   if (!buf)
243     return NULL;
244
245   rc = gcry_sexp_new (&private, buf, buflen, 1);
246   if (rc)
247     {
248       log_error ("gcry_sexp_new failed: %s\n", gpg_strerror (rc));
249       return NULL;
250     } 
251   xfree (buf);
252
253   return private;
254 }
255
256
257
258 static gcry_mpi_t *
259 sexp_to_kparms (gcry_sexp_t sexp, unsigned long *created)
260 {
261   gcry_sexp_t list, l2;
262   const char *name;
263   const char *s;
264   size_t n;
265   int i, idx;
266   const char *elems;
267   gcry_mpi_t *array;
268
269   *created = 0;
270   list = gcry_sexp_find_token (sexp, "private-key", 0 );
271   if(!list)
272     return NULL; 
273
274   /* quick hack to get the creation time. */
275   l2 = gcry_sexp_find_token (list, "created", 0);
276   if (l2 && (name = gcry_sexp_nth_data (l2, 1, &n)))
277     {
278       char *tmp = xmalloc (n+1);
279       memcpy (tmp, name, n);
280       tmp[n] = 0;
281       *created = strtoul (tmp, NULL, 10);
282       xfree (tmp);
283     }
284   gcry_sexp_release (l2);
285   l2 = gcry_sexp_cadr (list);
286   gcry_sexp_release (list);
287   list = l2;
288   name = gcry_sexp_nth_data (list, 0, &n);
289   if(!name || n != 3 || memcmp (name, "rsa", 3))
290     {
291       gcry_sexp_release (list);
292       return NULL;
293     }
294
295   /* Parameter names used with RSA. */
296   elems = "nedpqu";
297   array = xcalloc (strlen(elems) + 1, sizeof *array);
298   for (idx=0, s=elems; *s; s++, idx++ ) 
299     {
300       l2 = gcry_sexp_find_token (list, s, 1);
301       if (!l2)
302         {
303           for (i=0; i<idx; i++)
304             gcry_mpi_release (array[i]);
305           xfree (array);
306           gcry_sexp_release (list);
307           return NULL; /* required parameter not found */
308         }
309       array[idx] = gcry_sexp_nth_mpi (l2, 1, GCRYMPI_FMT_USG);
310       gcry_sexp_release (l2);
311       if (!array[idx])
312         {
313           for (i=0; i<idx; i++)
314             gcry_mpi_release (array[i]);
315           xfree (array);
316           gcry_sexp_release (list);
317           return NULL; /* required parameter is invalid */
318         }
319     }
320   
321   gcry_sexp_release (list);
322   return array;
323 }
324
325
326 /* Return true if the SHA1 fingerprint FPR consists only of zeroes. */
327 static int
328 fpr_is_zero (const char *fpr)
329 {
330   int i;
331
332   for (i=0; i < 20 && !fpr[i]; i++)
333     ;
334   return (i == 20);
335 }
336
337
338 static void
339 show_sha1_fpr (const unsigned char *fpr)
340 {
341   int i;
342
343   if (fpr)
344     {
345       for (i=0; i < 20 ; i+=2, fpr += 2 )
346         {
347           if (i == 10 )
348             tty_printf (" ");
349           tty_printf (" %02X%02X", *fpr, fpr[1]);
350         }
351     }
352   else
353     tty_printf (" [none]");
354   tty_printf ("\n");
355 }
356
357 /* Query the card, show a list of already stored keys and ask the user
358    where to store the key.  Returns the key number or 0 for cancel
359    operation. */
360 static int
361 query_card (APP app)
362 {
363   int keyno = 0;
364   char *serialno, *disp_name, *pubkey_url;
365   unsigned char *fpr1, *fpr2, *fpr3;
366
367
368   if (app_openpgp_cardinfo (app,
369                             &serialno,
370                             &disp_name,
371                             &pubkey_url,
372                             &fpr1, &fpr2, &fpr3))
373     return 0;
374
375
376   for (;;)
377     {
378       char *answer;
379
380       tty_printf ("\n");
381
382       tty_printf ("Serial number ....: %s\n",
383                   serialno? serialno : "[none]");
384       tty_printf ("Name of cardholder: %s\n",
385                   disp_name && *disp_name? disp_name : "[not set]");
386       tty_printf ("URL of public key : %s\n",
387                   pubkey_url && *pubkey_url? pubkey_url : "[not set]");
388       tty_printf ("Signature key ....:");
389       show_sha1_fpr (fpr1);
390       tty_printf ("Encryption key....:");
391       show_sha1_fpr (fpr2);
392       tty_printf ("Authentication key:");
393       show_sha1_fpr (fpr3);
394
395       tty_printf ("\n"
396                   "1 - store as signature key and reset usage counter\n"
397                   "2 - store as encryption key\n"
398                   "3 - store as authentication key\n"
399                   "Q - quit\n"
400                   "\n");
401
402       answer = tty_get("Your selection? ");
403       tty_kill_prompt();
404       if (strlen (answer) != 1)
405         ;
406       else if ( *answer == '1' )
407         {
408           if ( (fpr1 && !fpr_is_zero (fpr1)) )
409             {
410               tty_printf ("\n");
411               log_error ("WARNING: signature key does already exists!\n");
412               tty_printf ("\n");
413               if ( tty_get_answer_is_yes ("Replace existing key? ") )
414                 {
415                   keyno = 1;
416                   break;
417                 }
418             }
419           else
420             {
421               keyno = 1;
422               break;
423             }
424         }
425       else if ( *answer == '2' )
426         {
427           if ( (fpr2 && !fpr_is_zero (fpr2)) )
428             {
429               tty_printf ("\n");
430               log_error ("WARNING: encryption key does already exists!\n");
431               tty_printf ("\n");
432               if ( tty_get_answer_is_yes ("Replace existing key? ") )
433                 {
434                   keyno = 2;
435                   break;
436                 }
437             }
438           else
439             {
440               keyno = 2;
441               break;
442             }
443         }
444       else if ( *answer == '3' )
445         {
446           if ( (fpr3 && !fpr_is_zero (fpr3)) )
447             {
448               tty_printf ("\n");
449               log_error ("WARNING: authentication key does already exists!\n");
450               tty_printf ("\n");
451               if ( tty_get_answer_is_yes ("Replace existing key? ") )
452                 {
453                   keyno = 3;
454                   break;
455                 }
456             }
457           else
458             {
459               keyno = 3;
460               break;
461             }
462         }
463       else if ( *answer == 'q' || *answer == 'Q')
464         {
465           keyno = 0;
466           break;
467         }
468     }
469
470   xfree (serialno); 
471   xfree (disp_name); 
472   xfree (pubkey_url);
473   xfree (fpr1);
474   xfree (fpr2);
475   xfree (fpr3);
476
477   return keyno;
478 }
479
480
481 /* Callback function to ask for a PIN. */
482 static int 
483 pincb (void *arg, const char *prompt, char **pinvalue)
484 {
485   char *pin = xstrdup ("12345678");
486
487 /*    pin = simple_pwquery (NULL, NULL, prompt, */
488 /*                          "We need the admin's PIN to store the key on the card", */
489 /*                          NULL); */
490 /*    if (!pin) */
491 /*      return gpg_error (GPG_ERR_CANCELED); */
492
493
494
495   *pinvalue = pin;
496   return 0;
497 }
498
499
500 /* This function expects a file (or NULL for stdin) with the secret
501    and public key parameters.  This file should consist of an
502    S-expression as used by gpg-agent. Only the unprotected format is
503    supported.  Example:
504
505    (private-key
506     (rsa
507      (n #00e0ce9..[some bytes not shown]..51#)
508      (e #010001#)
509      (d #046129F..[some bytes not shown]..81#)
510      (p #00e861b..[some bytes not shown]..f1#)
511      (q #00f7a7c..[some bytes not shown]..61#)
512      (u #304559a..[some bytes not shown]..9b#))
513     (uri http://foo.bar x-foo:whatever_you_want))
514    
515 */
516 static void
517 copykeys (APP app, const char *fname)
518 {
519   int rc;
520   gcry_sexp_t private;
521   gcry_mpi_t *mpis, rsa_n, rsa_e, rsa_p, rsa_q;
522   unsigned int nbits;
523   size_t n;
524   unsigned char *template, *tp;
525   unsigned char m[128], e[4];
526   size_t mlen, elen;
527   unsigned long creation_date;
528   time_t created_at;
529   int keyno;
530
531   if (!strcmp (fname, "-"))
532     fname = NULL;
533
534   private = read_key (fname);
535   if (!private)
536     exit (1);
537   
538   mpis = sexp_to_kparms (private, &creation_date);
539   if (!creation_date)
540     {
541       log_info ("no creation date found - assuming current date\n");
542       created_at = time (NULL);
543     }
544   else
545     created_at = creation_date;
546   gcry_sexp_release (private);
547   if (!mpis)
548     {
549       log_error ("invalid structure of key file or not RSA\n");
550       exit (1);
551     }
552   /* MPIS is now an array with the key parameters as defined by OpenPGP. */
553   rsa_n = mpis[0];
554   rsa_e = mpis[1];
555   gcry_mpi_release (mpis[2]);
556   rsa_p = mpis[3];
557   rsa_q = mpis[4];
558   gcry_mpi_release (mpis[5]);
559   xfree (mpis);
560
561   nbits = gcry_mpi_get_nbits (rsa_e);
562   if (nbits < 2 || nbits > 32)
563     {
564       log_error ("public exponent too large (more than 32 bits)\n");
565       goto failure;
566     }
567   nbits = gcry_mpi_get_nbits (rsa_p);
568   if (nbits != 512)
569     {
570       log_error ("length of first RSA prime is not 512\n");
571       goto failure;
572     }
573   nbits = gcry_mpi_get_nbits (rsa_q);
574   if (nbits != 512)
575     {
576       log_error ("length of second RSA prime is not 512\n");
577       goto failure;
578     }
579
580   nbits = gcry_mpi_get_nbits (rsa_n);
581   if (nbits != 1024)
582     {
583       log_error ("length of RSA modulus is not 1024\n");
584       goto failure;
585     }
586
587   keyno = query_card (app);
588   if (!keyno)
589     goto failure;
590
591   /* Build the private key template as described in section 4.3.3.6 of
592      the specs.
593                    0xC0   <length> public exponent
594                    0xC1   <length> prime p 
595                    0xC2   <length> prime q  */
596   template = tp = xmalloc (1+2 + 1+1+4 + 1+1+64 + 1+1+64);
597   *tp++ = 0xC0;
598   *tp++ = 4;
599   n = 4;
600   rc = gcry_mpi_print (GCRYMPI_FMT_USG, tp, &n, rsa_e);
601   if (rc)
602     {
603       log_error ("mpi_print failed: %s\n", gpg_strerror (rc));
604       goto failure;
605     }
606   assert (n <= 4);
607   memcpy (e, tp, n);
608   elen = n;
609   if (n != 4)
610     {
611       memmove (tp+4-n, tp, 4-n);
612       memset (tp, 0, 4-n);
613     }                 
614   tp += 4;
615
616   *tp++ = 0xC1;
617   *tp++ = 64;
618   n = 64;
619   rc = gcry_mpi_print (GCRYMPI_FMT_USG, tp, &n, rsa_p);
620   if (rc)
621     {
622       log_error ("mpi_print failed: %s\n", gpg_strerror (rc));
623       goto failure;
624     }
625   assert (n == 64);
626   tp += 64;
627
628   *tp++ = 0xC2;
629   *tp++ = 64;
630   n = 64;
631   rc = gcry_mpi_print (GCRYMPI_FMT_USG, tp, &n, rsa_q);
632   if (rc)
633     {
634       log_error ("mpi_print failed: %s\n", gpg_strerror (rc));
635       goto failure;
636     }
637   assert (n == 64);
638   tp += 64;
639   assert (tp - template == 138);
640
641   /* (we need the modulus to calculate the fingerprint) */
642   n = 128;
643   rc = gcry_mpi_print (GCRYMPI_FMT_USG, m, &n, rsa_n);
644   if (rc)
645     {
646       log_error ("mpi_print failed: %s\n", gpg_strerror (rc));
647       goto failure;
648     }
649   assert (n == 128);
650   mlen = 128;
651
652
653   rc = app_openpgp_storekey (app, keyno,
654                              template, tp - template,
655                              created_at,
656                              m, mlen,
657                              e, elen,
658                              pincb, NULL);
659
660   if (rc)
661     {
662       log_error ("error storing key: %s\n", gpg_strerror (rc));
663       goto failure;
664     }
665   log_info ("key successfully stored\n");
666   {
667     unsigned char *mm, *ee;
668     size_t mmlen, eelen;
669     int i;
670
671     rc = app_openpgp_readkey (app, keyno, &mm, &mmlen, &ee, &eelen);
672     if (rc)
673       {
674         log_error ("error reading key back: %s\n", gpg_strerror (rc));
675         goto failure;
676       }
677
678     /* Strip leading zeroes. */
679     for (i=0; i < mmlen && !mm[i]; i++)
680       ;
681     mmlen -= i;
682     memmove (mm, mm+i, mmlen);
683     for (i=0; i < eelen && !ee[i]; i++)
684       ;
685     eelen -= i;
686     memmove (ee, ee+i, eelen);
687
688     if (eelen != elen || mmlen != mlen)
689       {
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);
693         xfree (mm);
694         xfree (ee);
695         goto failure;
696       }
697
698     if (memcmp (m, mm, mlen))
699       {
700         log_error ("key parameter n mismatch\n");
701         log_printhex ("original n: ", m, mlen);
702         log_printhex ("  copied n: ", mm, mlen);
703         xfree (mm);
704         xfree (ee);
705         goto failure;
706       }
707     if (memcmp (e, ee, elen))
708       {
709         log_error ("key parameter e mismatch\n");
710         log_printhex ("original e: ", e, elen);
711         log_printhex ("  copied e: ", ee, elen);
712         xfree (mm);
713         xfree (ee);
714         goto failure;
715       }
716     xfree (mm);
717     xfree (ee);
718   }
719
720
721   gcry_mpi_release (rsa_e);
722   gcry_mpi_release (rsa_p);
723   gcry_mpi_release (rsa_q);
724   gcry_mpi_release (rsa_n);
725   return;
726
727  failure:
728   gcry_mpi_release (rsa_e);
729   gcry_mpi_release (rsa_p);
730   gcry_mpi_release (rsa_q);
731   gcry_mpi_release (rsa_n);
732   exit (1);
733 }
734
735