Avoid using the protect-tool to import pkcs#12.
[gnupg.git] / agent / command-ssh.c
1 /* command-ssh.c - gpg-agent's ssh-agent emulation layer
2  * Copyright (C) 2004, 2005, 2006, 2009 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 3 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, see <http://www.gnu.org/licenses/>.
18  */
19
20 /* Only v2 of the ssh-agent protocol is implemented.  */
21
22 #include <config.h>
23
24 #include <stdio.h>
25 #include <stdlib.h>
26 #include <string.h>
27 #include <errno.h>
28 #include <sys/types.h>
29 #include <sys/stat.h>
30 #include <dirent.h>
31 #include <assert.h>
32
33 #include "agent.h"
34
35 #include "i18n.h"
36
37 \f
38
39 /* Request types. */
40 #define SSH_REQUEST_REQUEST_IDENTITIES    11
41 #define SSH_REQUEST_SIGN_REQUEST          13
42 #define SSH_REQUEST_ADD_IDENTITY          17
43 #define SSH_REQUEST_REMOVE_IDENTITY       18
44 #define SSH_REQUEST_REMOVE_ALL_IDENTITIES 19
45 #define SSH_REQUEST_LOCK                  22
46 #define SSH_REQUEST_UNLOCK                23
47 #define SSH_REQUEST_ADD_ID_CONSTRAINED    25
48
49 /* Options. */
50 #define SSH_OPT_CONSTRAIN_LIFETIME         1
51 #define SSH_OPT_CONSTRAIN_CONFIRM          2
52
53 /* Response types. */
54 #define SSH_RESPONSE_SUCCESS               6
55 #define SSH_RESPONSE_FAILURE               5
56 #define SSH_RESPONSE_IDENTITIES_ANSWER    12
57 #define SSH_RESPONSE_SIGN_RESPONSE        14
58
59 /* Other constants.  */
60 #define SSH_DSA_SIGNATURE_PADDING 20
61 #define SSH_DSA_SIGNATURE_ELEMS    2
62 #define SPEC_FLAG_USE_PKCS1V2 (1 << 0)
63
64
65 /* The blurb we put into the header of a newly created control file.  */
66 static const char sshcontrolblurb[] =
67 "# List of allowed ssh keys.  Only keys present in this file are used\n"
68 "# in the SSH protocol.  The ssh-add tool may add new entries to this\n"
69 "# file to enable them; you may also add them manually.  Comment\n"
70 "# lines, like this one, as well as empty lines are ignored.  Lines do\n"
71 "# have a certain length limit but this is not serious limitation as\n" 
72 "# the format of the entries is fixed and checked by gpg-agent. A\n"
73 "# non-comment line starts with optional white spaces, followed by the\n"
74 "# keygrip of the key given as 40 hex digits, optionally followed by a\n"
75 "# the caching TTL in seconds and another optional field for arbitrary\n"
76 "# flags.   Prepend the keygrip with an '!' mark to disable it.\n"
77 "\n";
78
79
80
81 /* Macros.  */
82
83 /* Return a new uint32 with b0 being the most significant byte and b3
84    being the least significant byte.  */
85 #define uint32_construct(b0, b1, b2, b3) \
86   ((b0 << 24) | (b1 << 16) | (b2 << 8) | b3)
87
88 \f
89
90
91 /*
92  * Basic types.
93  */
94
95 /* Type for a request handler.  */
96 typedef gpg_error_t (*ssh_request_handler_t) (ctrl_t ctrl,
97                                               estream_t request,
98                                               estream_t response);
99
100 /* Type, which is used for associating request handlers with the
101    appropriate request IDs.  */
102 typedef struct ssh_request_spec
103 {
104   unsigned char type;
105   ssh_request_handler_t handler;
106   const char *identifier;
107   unsigned int secret_input;
108 } ssh_request_spec_t;
109
110 /* Type for "key modifier functions", which are necessary since
111    OpenSSH and GnuPG treat key material slightly different.  A key
112    modifier is called right after a new key identity has been received
113    in order to "sanitize" the material.  */
114 typedef gpg_error_t (*ssh_key_modifier_t) (const char *elems,
115                                            gcry_mpi_t *mpis);
116
117 /* The encoding of a generated signature is dependent on the
118    algorithm; therefore algorithm specific signature encoding
119    functions are necessary.  */
120 typedef gpg_error_t (*ssh_signature_encoder_t) (estream_t signature_blob,
121                                                 gcry_mpi_t *mpis);
122
123 /* Type, which is used for boundling all the algorithm specific
124    information together in a single object.  */
125 typedef struct ssh_key_type_spec
126 {
127   /* Algorithm identifier as used by OpenSSH.  */
128   const char *ssh_identifier;
129
130   /* Algorithm identifier as used by GnuPG.  */
131   const char *identifier;
132
133   /* List of MPI names for secret keys; order matches the one of the
134      agent protocol.  */
135   const char *elems_key_secret;
136
137   /* List of MPI names for public keys; order matches the one of the
138      agent protocol.  */
139   const char *elems_key_public;
140
141   /* List of MPI names for signature data.  */
142   const char *elems_signature;
143
144   /* List of MPI names for secret keys; order matches the one, which
145      is required by gpg-agent's key access layer.  */
146   const char *elems_sexp_order;
147
148   /* Key modifier function.  Key modifier functions are necessary in
149      order to fix any inconsistencies between the representation of
150      keys on the SSH and on the GnuPG side.  */
151   ssh_key_modifier_t key_modifier;
152
153   /* Signature encoder function.  Signature encoder functions are
154      necessary since the encoding of signatures depends on the used
155      algorithm.  */
156   ssh_signature_encoder_t signature_encoder;
157
158   /* Misc flags.  */
159   unsigned int flags;
160 } ssh_key_type_spec_t;
161
162
163 /* Prototypes.  */
164 static gpg_error_t ssh_handler_request_identities (ctrl_t ctrl,
165                                                    estream_t request,
166                                                    estream_t response);
167 static gpg_error_t ssh_handler_sign_request (ctrl_t ctrl,
168                                              estream_t request,
169                                              estream_t response);
170 static gpg_error_t ssh_handler_add_identity (ctrl_t ctrl,
171                                              estream_t request,
172                                              estream_t response);
173 static gpg_error_t ssh_handler_remove_identity (ctrl_t ctrl,
174                                                 estream_t request,
175                                                 estream_t response);
176 static gpg_error_t ssh_handler_remove_all_identities (ctrl_t ctrl,
177                                                       estream_t request,
178                                                       estream_t response);
179 static gpg_error_t ssh_handler_lock (ctrl_t ctrl,
180                                      estream_t request,
181                                      estream_t response);
182 static gpg_error_t ssh_handler_unlock (ctrl_t ctrl,
183                                        estream_t request,
184                                        estream_t response);
185
186 static gpg_error_t ssh_key_modifier_rsa (const char *elems, gcry_mpi_t *mpis);
187 static gpg_error_t ssh_signature_encoder_rsa (estream_t signature_blob,
188                                               gcry_mpi_t *mpis);
189 static gpg_error_t ssh_signature_encoder_dsa (estream_t signature_blob,
190                                               gcry_mpi_t *mpis);
191
192
193
194 /* Global variables.  */
195    
196
197 /* Associating request types with the corresponding request
198    handlers.  */
199
200 static ssh_request_spec_t request_specs[] =
201   {
202 #define REQUEST_SPEC_DEFINE(id, name, secret_input) \
203   { SSH_REQUEST_##id, ssh_handler_##name, #name, secret_input }
204
205     REQUEST_SPEC_DEFINE (REQUEST_IDENTITIES,    request_identities,    1),
206     REQUEST_SPEC_DEFINE (SIGN_REQUEST,          sign_request,          0),
207     REQUEST_SPEC_DEFINE (ADD_IDENTITY,          add_identity,          1),
208     REQUEST_SPEC_DEFINE (ADD_ID_CONSTRAINED,    add_identity,          1),
209     REQUEST_SPEC_DEFINE (REMOVE_IDENTITY,       remove_identity,       0),
210     REQUEST_SPEC_DEFINE (REMOVE_ALL_IDENTITIES, remove_all_identities, 0),
211     REQUEST_SPEC_DEFINE (LOCK,                  lock,                  0),
212     REQUEST_SPEC_DEFINE (UNLOCK,                unlock,                0)
213 #undef REQUEST_SPEC_DEFINE
214   };
215
216
217 /* Table holding key type specifications.  */
218 static ssh_key_type_spec_t ssh_key_types[] =
219   {
220     {
221       "ssh-rsa", "rsa", "nedupq", "en",   "s",  "nedpqu",
222       ssh_key_modifier_rsa, ssh_signature_encoder_rsa,
223       SPEC_FLAG_USE_PKCS1V2
224     },
225     {
226       "ssh-dss", "dsa", "pqgyx",  "pqgy", "rs", "pqgyx",
227       NULL,                 ssh_signature_encoder_dsa,
228       0
229     },
230   };
231
232 \f
233
234
235
236 /*
237    General utility functions. 
238  */
239
240 /* A secure realloc, i.e. it makes sure to allocate secure memory if A
241    is NULL.  This is required because the standard gcry_realloc does
242    not know whether to allocate secure or normal if NULL is passed as
243    existing buffer.  */
244 static void *
245 realloc_secure (void *a, size_t n)
246 {
247   void *p;
248   
249   if (a)
250     p = gcry_realloc (a, n);
251   else
252     p = gcry_malloc_secure (n);
253
254   return p;
255 }
256
257
258 /* Create and return a new C-string from DATA/DATA_N (i.e.: add
259    NUL-termination); return NULL on OOM.  */
260 static char *
261 make_cstring (const char *data, size_t data_n)
262 {
263   char *s;
264
265   s = xtrymalloc (data_n + 1);
266   if (s)
267     {
268       memcpy (s, data, data_n);
269       s[data_n] = 0;
270     }
271
272   return s;
273 }
274
275
276
277
278 /* 
279    Primitive I/O functions.  
280  */
281
282
283 /* Read a byte from STREAM, store it in B.  */
284 static gpg_error_t
285 stream_read_byte (estream_t stream, unsigned char *b)
286 {
287   gpg_error_t err;
288   int ret;
289
290   ret = es_fgetc (stream);
291   if (ret == EOF)
292     {
293       if (es_ferror (stream))
294         err = gpg_error_from_syserror ();
295       else
296         err = gpg_error (GPG_ERR_EOF);
297       *b = 0;
298     }
299   else
300     {
301       *b = ret & 0xFF;
302       err = 0;
303     }
304
305   return err;
306 }
307
308 /* Write the byte contained in B to STREAM.  */
309 static gpg_error_t
310 stream_write_byte (estream_t stream, unsigned char b)
311 {
312   gpg_error_t err;
313   int ret;
314
315   ret = es_fputc (b, stream);
316   if (ret == EOF)
317     err = gpg_error_from_syserror ();
318   else
319     err = 0;
320
321   return err;
322 }
323
324 /* Read a uint32 from STREAM, store it in UINT32.  */
325 static gpg_error_t
326 stream_read_uint32 (estream_t stream, u32 *uint32)
327 {
328   unsigned char buffer[4];
329   size_t bytes_read;
330   gpg_error_t err;
331   int ret;
332
333   ret = es_read (stream, buffer, sizeof (buffer), &bytes_read);
334   if (ret)
335     err = gpg_error_from_syserror ();
336   else
337     {
338       if (bytes_read != sizeof (buffer))
339         err = gpg_error (GPG_ERR_EOF);
340       else
341         {
342           u32 n;
343
344           n = uint32_construct (buffer[0], buffer[1], buffer[2], buffer[3]);
345           *uint32 = n;
346           err = 0;
347         }
348     }
349
350   return err;
351 }
352
353 /* Write the uint32 contained in UINT32 to STREAM.  */
354 static gpg_error_t
355 stream_write_uint32 (estream_t stream, u32 uint32)
356 {
357   unsigned char buffer[4];
358   gpg_error_t err;
359   int ret;
360
361   buffer[0] = uint32 >> 24;
362   buffer[1] = uint32 >> 16;
363   buffer[2] = uint32 >>  8;
364   buffer[3] = uint32 >>  0;
365
366   ret = es_write (stream, buffer, sizeof (buffer), NULL);
367   if (ret)
368     err = gpg_error_from_syserror ();
369   else
370     err = 0;
371
372   return err;
373 }
374
375 /* Read SIZE bytes from STREAM into BUFFER.  */
376 static gpg_error_t
377 stream_read_data (estream_t stream, unsigned char *buffer, size_t size)
378 {
379   gpg_error_t err;
380   size_t bytes_read;
381   int ret;
382
383   ret = es_read (stream, buffer, size, &bytes_read);
384   if (ret)
385     err = gpg_error_from_syserror ();
386   else
387     {
388       if (bytes_read != size)
389         err = gpg_error (GPG_ERR_EOF);
390       else
391         err = 0;
392     }
393
394   return err;
395 }
396
397 /* Write SIZE bytes from BUFFER to STREAM.  */
398 static gpg_error_t
399 stream_write_data (estream_t stream, const unsigned char *buffer, size_t size)
400 {
401   gpg_error_t err;
402   int ret;
403
404   ret = es_write (stream, buffer, size, NULL);
405   if (ret)
406     err = gpg_error_from_syserror ();
407   else
408     err = 0;
409
410   return err;
411 }
412
413 /* Read a binary string from STREAM into STRING, store size of string
414    in STRING_SIZE; depending on SECURE use secure memory for
415    string.  */
416 static gpg_error_t
417 stream_read_string (estream_t stream, unsigned int secure,
418                     unsigned char **string, u32 *string_size)
419 {
420   gpg_error_t err;
421   unsigned char *buffer = NULL;
422   u32 length = 0;
423
424   /* Read string length.  */
425   err = stream_read_uint32 (stream, &length);
426   if (err)
427     goto out;
428
429   /* Allocate space.  */
430   if (secure)
431     buffer = xtrymalloc_secure (length + 1);
432   else
433     buffer = xtrymalloc (length + 1);
434   if (! buffer)
435     {
436       err = gpg_error_from_syserror ();
437       goto out;
438     }
439
440   /* Read data.  */
441   err = stream_read_data (stream, buffer, length);
442   if (err)
443     goto out;
444
445   /* Finalize string object.  */
446   buffer[length] = 0;
447   *string = buffer;
448   if (string_size)
449     *string_size = length;
450
451  out:
452
453   if (err)
454     xfree (buffer);
455
456   return err;
457 }
458
459 /* Read a C-string from STREAM, store copy in STRING.  */
460 static gpg_error_t
461 stream_read_cstring (estream_t stream, char **string)
462 {
463   unsigned char *buffer;
464   gpg_error_t err;
465
466   err = stream_read_string (stream, 0, &buffer, NULL);
467   if (err)
468     goto out;
469   
470   *string = (char *) buffer;
471
472  out:
473
474   return err;
475 }
476
477
478 /* Write a binary string from STRING of size STRING_N to STREAM.  */
479 static gpg_error_t
480 stream_write_string (estream_t stream,
481                      const unsigned char *string, u32 string_n)
482 {
483   gpg_error_t err;
484
485   err = stream_write_uint32 (stream, string_n);
486   if (err)
487     goto out;
488
489   err = stream_write_data (stream, string, string_n);
490
491  out:
492
493   return err;
494 }
495
496 /* Write a C-string from STRING to STREAM.  */
497 static gpg_error_t
498 stream_write_cstring (estream_t stream, const char *string)
499 {
500   gpg_error_t err;
501
502   err = stream_write_string (stream,
503                              (const unsigned char *) string, strlen (string));
504
505   return err;
506 }                         
507
508 /* Read an MPI from STREAM, store it in MPINT.  Depending on SECURE
509    use secure memory.  */
510 static gpg_error_t
511 stream_read_mpi (estream_t stream, unsigned int secure, gcry_mpi_t *mpint)
512 {
513   unsigned char *mpi_data;
514   u32 mpi_data_size;
515   gpg_error_t err;
516   gcry_mpi_t mpi;
517
518   mpi_data = NULL;
519
520   err = stream_read_string (stream, secure, &mpi_data, &mpi_data_size);
521   if (err)
522     goto out;
523
524   /* To avoid excessive use of secure memory we check that an MPI is
525      not too large. */
526   if (mpi_data_size > 520)
527     {
528       log_error (_("ssh keys greater than %d bits are not supported\n"), 4096);
529       err = GPG_ERR_TOO_LARGE;
530       goto out;
531     }
532
533   err = gcry_mpi_scan (&mpi, GCRYMPI_FMT_STD, mpi_data, mpi_data_size, NULL);
534   if (err)
535     goto out;
536
537   *mpint = mpi;
538
539  out:
540
541   xfree (mpi_data);
542
543   return err;
544 }
545
546 /* Write the MPI contained in MPINT to STREAM.  */
547 static gpg_error_t
548 stream_write_mpi (estream_t stream, gcry_mpi_t mpint)
549 {
550   unsigned char *mpi_buffer;
551   size_t mpi_buffer_n;
552   gpg_error_t err;
553
554   mpi_buffer = NULL;
555
556   err = gcry_mpi_aprint (GCRYMPI_FMT_STD, &mpi_buffer, &mpi_buffer_n, mpint);
557   if (err)
558     goto out;
559
560   err = stream_write_string (stream, mpi_buffer, mpi_buffer_n);
561
562  out:
563
564   xfree (mpi_buffer);
565
566   return err;
567 }
568
569 /* Copy data from SRC to DST until EOF is reached.  */
570 static gpg_error_t
571 stream_copy (estream_t dst, estream_t src)
572 {
573   char buffer[BUFSIZ];
574   size_t bytes_read;
575   gpg_error_t err;
576   int ret;
577
578   err = 0;
579   while (1)
580     {
581       ret = es_read (src, buffer, sizeof (buffer), &bytes_read);
582       if (ret || (! bytes_read))
583         {
584           if (ret)
585             err = gpg_error_from_syserror ();
586           break;
587         }
588       ret = es_write (dst, buffer, bytes_read, NULL);
589       if (ret)
590         {
591           err = gpg_error_from_syserror ();
592           break;
593         }
594     }
595
596   return err;
597 }
598
599
600 /* Read the content of the file specified by FILENAME into a newly
601    create buffer, which is to be stored in BUFFER; store length of
602    buffer in BUFFER_N.  */
603 static gpg_error_t
604 file_to_buffer (const char *filename, unsigned char **buffer, size_t *buffer_n)
605 {
606   unsigned char *buffer_new;
607   struct stat statbuf;
608   estream_t stream;
609   gpg_error_t err;
610   int ret;
611
612   *buffer = NULL;
613   *buffer_n = 0;
614
615   buffer_new = NULL;
616   err = 0;
617   
618   stream = es_fopen (filename, "r");
619   if (! stream)
620     {
621       err = gpg_error_from_syserror ();
622       goto out;
623     }
624
625   ret = fstat (es_fileno (stream), &statbuf);
626   if (ret)
627     {
628       err = gpg_error_from_syserror ();
629       goto out;
630     }
631
632   buffer_new = xtrymalloc (statbuf.st_size);
633   if (! buffer_new)
634     {
635       err = gpg_error_from_syserror ();
636       goto out;
637     }
638
639   err = stream_read_data (stream, buffer_new, statbuf.st_size);
640   if (err)
641     goto out;
642
643   *buffer = buffer_new;
644   *buffer_n = statbuf.st_size;
645
646  out:
647
648   if (stream)
649     es_fclose (stream);
650
651   if (err)
652     xfree (buffer_new);
653
654   return err;
655 }
656
657
658
659 \f
660 /* Open the ssh control file and create it if not available. With
661    APPEND passed as true the file will be opened in append mode,
662    otherwise in read only mode.  On success a file pointer is stored
663    at the address of R_FP. */
664 static gpg_error_t
665 open_control_file (FILE **r_fp, int append)
666 {
667   gpg_error_t err;
668   char *fname;
669   FILE *fp;
670
671   /* Note: As soon as we start to use non blocking functions here
672      (i.e. where Pth might switch threads) we need to employ a
673      mutex.  */
674   *r_fp = NULL;
675   fname = make_filename (opt.homedir, "sshcontrol", NULL);
676   /* FIXME: With "a+" we are not able to check whether this will will
677      be created and thus the blurb needs to be written first.  */
678   fp = fopen (fname, append? "a+":"r");
679   if (!fp && errno == ENOENT)
680     {
681       /* Fixme: "x" is a GNU extension.  We might want to use the es_
682          functions here.  */
683       fp = fopen (fname, "wx");  
684       if (!fp)
685         {
686           err = gpg_error (gpg_err_code_from_errno (errno));
687           log_error (_("can't create `%s': %s\n"), fname, gpg_strerror (err));
688           xfree (fname);
689           return err;
690         }
691       fputs (sshcontrolblurb, fp);
692       fclose (fp);
693       fp = fopen (fname, append? "a+":"r");
694     }
695
696   if (!fp)
697     {
698       err = gpg_error (gpg_err_code_from_errno (errno));
699       log_error (_("can't open `%s': %s\n"), fname, gpg_strerror (err));
700       xfree (fname);
701       return err;
702     }
703   
704   *r_fp = fp;  
705
706   return 0;
707 }
708
709
710 /* Search the file at stream FP from the beginning until a matching
711    HEXGRIP is found; return success in this case and store true at
712    DISABLED if the found key has been disabled.  If R_TTL is not NULL
713    a specified TTL for that key is stored there. */
714 static gpg_error_t
715 search_control_file (FILE *fp, const char *hexgrip, 
716                      int *r_disabled, int *r_ttl)
717 {
718   int c, i;
719   char *p, *pend, line[256];
720   long ttl;
721
722   assert (strlen (hexgrip) == 40 );
723
724   fseek (fp, 0, SEEK_SET);
725   clearerr (fp);
726   *r_disabled = 0;
727  next_line:
728   do
729     {
730       if (!fgets (line, DIM(line)-1, fp) )
731         {
732           if (feof (fp))
733             return gpg_error (GPG_ERR_EOF);
734           return gpg_error (gpg_err_code_from_errno (errno));
735         }
736       
737       if (!*line || line[strlen(line)-1] != '\n')
738         {
739           /* Eat until end of line */
740           while ( (c=getc (fp)) != EOF && c != '\n')
741             ;
742           return gpg_error (*line? GPG_ERR_LINE_TOO_LONG
743                                  : GPG_ERR_INCOMPLETE_LINE);
744         }
745       
746       /* Allow for empty lines and spaces */
747       for (p=line; spacep (p); p++)
748         ;
749     }
750   while (!*p || *p == '\n' || *p == '#');
751   
752   *r_disabled = 0;
753   if (*p == '!')
754     {
755       *r_disabled = 1;
756       for (p++; spacep (p); p++)
757         ;
758     }
759
760   for (i=0; hexdigitp (p) && i < 40; p++, i++)
761     if (hexgrip[i] != (*p >= 'a'? (*p & 0xdf): *p))
762       goto next_line;
763   if (i != 40 || !(spacep (p) || *p == '\n'))
764     {
765       log_error ("invalid formatted line in ssh control file\n");
766       return gpg_error (GPG_ERR_BAD_DATA);
767     }
768
769   ttl = strtol (p, &pend, 10);
770   p = pend;
771   if (!(spacep (p) || *p == '\n') || ttl < -1)
772     {
773       log_error ("invalid TTL value in ssh control file; assuming 0\n");
774       ttl = 0;
775     }
776   if (r_ttl)
777     *r_ttl = ttl;
778
779   /* Here is the place to parse flags if we need them.  */  
780
781   return 0; /* Okay:  found it.  */
782 }
783
784
785
786 /* Add an entry to the control file to mark the key with the keygrip
787    HEXGRIP as usable for SSH; i.e. it will be returned when ssh asks
788    for it.  This function is in general used to add a key received
789    through the ssh-add function.  We can assume that the user wants to
790    allow ssh using this key. */
791 static gpg_error_t
792 add_control_entry (ctrl_t ctrl, const char *hexgrip, int ttl)
793 {
794   gpg_error_t err;
795   FILE *fp;
796   int disabled;
797
798   (void)ctrl;
799
800   err = open_control_file (&fp, 1);
801   if (err)
802     return err;
803
804   err = search_control_file (fp, hexgrip, &disabled, NULL);
805   if (err && gpg_err_code(err) == GPG_ERR_EOF)
806     {
807       struct tm *tp;
808       time_t atime = time (NULL);
809
810       /* Not yet in the file - add it. Because the file has been
811          opened in append mode, we simply need to write to it.  */
812       tp = localtime (&atime);
813       fprintf (fp, "# Key added on %04d-%02d-%02d %02d:%02d:%02d\n%s %d\n",
814                1900+tp->tm_year, tp->tm_mon+1, tp->tm_mday,
815                tp->tm_hour, tp->tm_min, tp->tm_sec,
816                hexgrip, ttl);
817                
818     }
819   fclose (fp);
820   return 0;
821 }
822
823
824 /* Scan the sshcontrol file and return the TTL.  */
825 static int
826 ttl_from_sshcontrol (const char *hexgrip)
827 {
828   FILE *fp;
829   int disabled, ttl;
830
831   if (!hexgrip || strlen (hexgrip) != 40)
832     return 0;  /* Wrong input: Use global default.  */
833
834   if (open_control_file (&fp, 0))
835     return 0; /* Error: Use the global default TTL.  */
836
837   if (search_control_file (fp, hexgrip, &disabled, &ttl)
838       || disabled)
839     ttl = 0;  /* Use the global default if not found or disabled.  */
840
841   fclose (fp); 
842
843   return ttl;
844 }
845
846
847
848 \f
849
850 /*
851
852   MPI lists. 
853
854  */
855
856 /* Free the list of MPIs MPI_LIST.  */
857 static void
858 mpint_list_free (gcry_mpi_t *mpi_list)
859 {
860   if (mpi_list)
861     {
862       unsigned int i;
863
864       for (i = 0; mpi_list[i]; i++)
865         gcry_mpi_release (mpi_list[i]);
866       xfree (mpi_list);
867     }
868 }
869
870 /* Receive key material MPIs from STREAM according to KEY_SPEC;
871    depending on SECRET expect a public key or secret key.  The newly
872    allocated list of MPIs is stored in MPI_LIST.  Returns usual error
873    code.  */
874 static gpg_error_t
875 ssh_receive_mpint_list (estream_t stream, int secret,
876                         ssh_key_type_spec_t key_spec, gcry_mpi_t **mpi_list)
877 {
878   unsigned int elems_public_n;
879   const char *elems_public;
880   unsigned int elems_n;
881   const char *elems;
882   int elem_is_secret;
883   gcry_mpi_t *mpis;
884   gpg_error_t err;
885   unsigned int i;
886
887   mpis = NULL;
888   err = 0;
889   
890   if (secret)
891     elems = key_spec.elems_key_secret;
892   else
893     elems = key_spec.elems_key_public;
894   elems_n = strlen (elems);
895
896   elems_public = key_spec.elems_key_public;
897   elems_public_n = strlen (elems_public);
898
899   mpis = xtrycalloc (elems_n + 1, sizeof *mpis );
900   if (!mpis)
901     {
902       err = gpg_error_from_syserror ();
903       goto out;
904     }
905
906   elem_is_secret = 0;
907   for (i = 0; i < elems_n; i++)
908     {
909       if (secret)
910         elem_is_secret = ! strchr (elems_public, elems[i]);
911       err = stream_read_mpi (stream, elem_is_secret, &mpis[i]);
912       if (err)
913         break;
914     }
915   if (err)
916     goto out;
917
918   *mpi_list = mpis;
919
920  out:
921
922   if (err)
923     mpint_list_free (mpis);
924
925   return err;
926 }
927
928 \f
929
930 /* Key modifier function for RSA.  */
931 static gpg_error_t
932 ssh_key_modifier_rsa (const char *elems, gcry_mpi_t *mpis)
933 {
934   gcry_mpi_t p;
935   gcry_mpi_t q;
936   gcry_mpi_t u;
937
938   if (strcmp (elems, "nedupq"))
939     /* Modifying only necessary for secret keys.  */
940     goto out;
941
942   u = mpis[3];
943   p = mpis[4];
944   q = mpis[5];
945
946   if (gcry_mpi_cmp (p, q) > 0)
947     {
948       /* P shall be smaller then Q!  Swap primes.  iqmp becomes u.  */
949       gcry_mpi_t tmp;
950
951       tmp = mpis[4];
952       mpis[4] = mpis[5];
953       mpis[5] = tmp;
954     }
955   else
956     /* U needs to be recomputed.  */
957     gcry_mpi_invm (u, p, q);
958
959  out:
960
961   return 0;
962 }
963
964 /* Signature encoder function for RSA.  */
965 static gpg_error_t
966 ssh_signature_encoder_rsa (estream_t signature_blob, gcry_mpi_t *mpis)
967 {
968   unsigned char *data;
969   size_t data_n;
970   gpg_error_t err;
971   gcry_mpi_t s;
972
973   s = mpis[0];
974
975   err = gcry_mpi_aprint (GCRYMPI_FMT_USG, &data, &data_n, s);
976   if (err)
977     goto out;
978
979   err = stream_write_string (signature_blob, data, data_n);
980   xfree (data);
981
982  out:
983
984   return err;
985 }
986
987
988 /* Signature encoder function for DSA.  */
989 static gpg_error_t
990 ssh_signature_encoder_dsa (estream_t signature_blob, gcry_mpi_t *mpis)
991 {
992   unsigned char buffer[SSH_DSA_SIGNATURE_PADDING * SSH_DSA_SIGNATURE_ELEMS];
993   unsigned char *data;
994   size_t data_n;
995   gpg_error_t err;
996   int i;
997
998   data = NULL;
999
1000   for (i = 0; i < 2; i++)
1001     {
1002       err = gcry_mpi_aprint (GCRYMPI_FMT_USG, &data, &data_n, mpis[i]);
1003       if (err)
1004         break;
1005
1006       if (data_n > SSH_DSA_SIGNATURE_PADDING)
1007         {
1008           err = gpg_error (GPG_ERR_INTERNAL); /* FIXME?  */
1009           break;
1010         }
1011       
1012       memset (buffer + (i * SSH_DSA_SIGNATURE_PADDING), 0,
1013               SSH_DSA_SIGNATURE_PADDING - data_n);
1014       memcpy (buffer + (i * SSH_DSA_SIGNATURE_PADDING)
1015               + (SSH_DSA_SIGNATURE_PADDING - data_n), data, data_n);
1016
1017       xfree (data);
1018       data = NULL;
1019     }
1020   if (err)
1021     goto out;
1022
1023   err = stream_write_string (signature_blob, buffer, sizeof (buffer));
1024
1025  out:
1026
1027   xfree (data);
1028
1029   return err;
1030 }
1031
1032 /* 
1033    S-Expressions. 
1034  */
1035
1036
1037 /* This function constructs a new S-Expression for the key identified
1038    by the KEY_SPEC, SECRET, MPIS and COMMENT, which is to be stored in
1039    *SEXP.  Returns usual error code.  */
1040 static gpg_error_t
1041 sexp_key_construct (gcry_sexp_t *sexp,
1042                     ssh_key_type_spec_t key_spec, int secret,
1043                     gcry_mpi_t *mpis, const char *comment)
1044 {
1045   const char *key_identifier[] = { "public-key", "private-key" };
1046   gcry_sexp_t sexp_new;
1047   char *sexp_template;
1048   size_t sexp_template_n;
1049   gpg_error_t err;
1050   const char *elems;
1051   size_t elems_n;
1052   unsigned int i;
1053   unsigned int j;
1054   void **arg_list;
1055
1056   err = 0;
1057   sexp_new = NULL;
1058   arg_list = NULL;
1059   if (secret)
1060     elems = key_spec.elems_sexp_order;
1061   else
1062     elems = key_spec.elems_key_public;
1063   elems_n = strlen (elems);
1064
1065   /*
1066     Calculate size for sexp_template_n:
1067
1068     "(%s(%s<mpis>)(comment%s))" -> 20 + sizeof (<mpis>).
1069
1070     mpi: (X%m) -> 5.
1071
1072   */
1073   sexp_template_n = 20 + (elems_n * 5);
1074   sexp_template = xtrymalloc (sexp_template_n);
1075   if (! sexp_template)
1076     {
1077       err = gpg_error_from_syserror ();
1078       goto out;
1079     }
1080
1081   /* Key identifier, algorithm identifier, mpis, comment.  */
1082   arg_list = xtrymalloc (sizeof (*arg_list) * (2 + elems_n + 1));
1083   if (! arg_list)
1084     {
1085       err = gpg_error_from_syserror ();
1086       goto out;
1087     }
1088
1089   i = 0;
1090   arg_list[i++] = &key_identifier[secret];
1091   arg_list[i++] = &key_spec.identifier;
1092
1093   *sexp_template = 0;
1094   sexp_template_n = 0;
1095   sexp_template_n = sprintf (sexp_template + sexp_template_n, "(%%s(%%s");
1096   for (i = 0; i < elems_n; i++)
1097     {
1098       sexp_template_n += sprintf (sexp_template + sexp_template_n, "(%c%%m)",
1099                                   elems[i]);
1100       if (secret)
1101         {
1102           for (j = 0; j < elems_n; j++)
1103             if (key_spec.elems_key_secret[j] == elems[i])
1104               break;
1105         }
1106       else
1107         j = i;
1108       arg_list[i + 2] = &mpis[j];
1109     }
1110   sexp_template_n += sprintf (sexp_template + sexp_template_n,
1111                               ")(comment%%s))");
1112
1113   arg_list[i + 2] = &comment;
1114
1115   err = gcry_sexp_build_array (&sexp_new, NULL, sexp_template, arg_list);
1116   if (err)
1117     goto out;
1118
1119   *sexp = sexp_new;
1120
1121  out:
1122
1123   xfree (arg_list);
1124   xfree (sexp_template);
1125
1126   return err;
1127 }
1128
1129 /* This functions breaks up the key contained in the S-Expression SEXP
1130    according to KEY_SPEC.  The MPIs are bundled in a newly create
1131    list, which is to be stored in MPIS; a newly allocated string
1132    holding the comment will be stored in COMMENT; SECRET will be
1133    filled with a boolean flag specifying what kind of key it is.
1134    Returns usual error code.  */
1135 static gpg_error_t
1136 sexp_key_extract (gcry_sexp_t sexp,
1137                   ssh_key_type_spec_t key_spec, int *secret,
1138                   gcry_mpi_t **mpis, char **comment)
1139 {
1140   gpg_error_t err;
1141   gcry_sexp_t value_list;
1142   gcry_sexp_t value_pair;
1143   gcry_sexp_t comment_list;
1144   unsigned int i;
1145   char *comment_new;
1146   const char *data;
1147   size_t data_n;
1148   int is_secret;
1149   size_t elems_n;
1150   const char *elems;
1151   gcry_mpi_t *mpis_new;
1152   gcry_mpi_t mpi;
1153
1154   err = 0;
1155   value_list = NULL;
1156   value_pair = NULL;
1157   comment_list = NULL;
1158   comment_new = NULL;
1159   mpis_new = NULL;
1160
1161   data = gcry_sexp_nth_data (sexp, 0, &data_n);
1162   if (! data)
1163     {
1164       err = gpg_error (GPG_ERR_INV_SEXP);
1165       goto out;
1166     }
1167
1168   if ((data_n == 10 && !strncmp (data, "public-key", 10))
1169       || (data_n == 21 && !strncmp (data, "protected-private-key", 21))
1170       || (data_n == 20 && !strncmp (data, "shadowed-private-key", 20)))
1171     {
1172       is_secret = 0;
1173       elems = key_spec.elems_key_public;
1174     }
1175   else if (data_n == 11 && !strncmp (data, "private-key", 11))
1176     {
1177       is_secret = 1;
1178       elems = key_spec.elems_key_secret;
1179     }
1180   else
1181     {
1182       err = gpg_error (GPG_ERR_INV_SEXP);
1183       goto out;
1184     }
1185
1186   elems_n = strlen (elems);
1187   mpis_new = xtrycalloc (elems_n + 1, sizeof *mpis_new );
1188   if (!mpis_new)
1189     {
1190       err = gpg_error_from_syserror ();
1191       goto out;
1192     }
1193
1194   value_list = gcry_sexp_find_token (sexp, key_spec.identifier, 0);
1195   if (! value_list)
1196     {
1197       err = gpg_error (GPG_ERR_INV_SEXP);
1198       goto out;
1199     }
1200
1201   for (i = 0; i < elems_n; i++)
1202     {
1203       value_pair = gcry_sexp_find_token (value_list, elems + i, 1);
1204       if (! value_pair)
1205         {
1206           err = gpg_error (GPG_ERR_INV_SEXP);
1207           break;
1208         }
1209
1210       /* Note that we need to use STD format; i.e. prepend a 0x00 to
1211          indicate a positive number if the high bit is set. */
1212       mpi = gcry_sexp_nth_mpi (value_pair, 1, GCRYMPI_FMT_STD);
1213       if (! mpi)
1214         {
1215           err = gpg_error (GPG_ERR_INV_SEXP);
1216           break;
1217         }
1218       mpis_new[i] = mpi;
1219       gcry_sexp_release (value_pair);
1220       value_pair = NULL;
1221     }
1222   if (err)
1223     goto out;
1224
1225   /* We do not require a comment sublist to be present here.  */
1226   data = NULL;
1227   data_n = 0;
1228
1229   comment_list = gcry_sexp_find_token (sexp, "comment", 0);
1230   if (comment_list)
1231     data = gcry_sexp_nth_data (comment_list, 1, &data_n);
1232   if (! data)
1233     {
1234       data = "(none)";
1235       data_n = 6;
1236     }
1237
1238   comment_new = make_cstring (data, data_n);
1239   if (! comment_new)
1240     {
1241       err = gpg_error_from_syserror ();
1242       goto out;
1243     }
1244
1245   if (secret)
1246     *secret = is_secret;
1247   *mpis = mpis_new;
1248   *comment = comment_new;
1249
1250  out:
1251
1252   gcry_sexp_release (value_list);
1253   gcry_sexp_release (value_pair);
1254   gcry_sexp_release (comment_list);
1255   
1256   if (err)
1257     {
1258       xfree (comment_new);
1259       mpint_list_free (mpis_new);
1260     }
1261
1262   return err;
1263 }
1264
1265 /* Extract the car from SEXP, and create a newly created C-string 
1266    which is to be stored in IDENTIFIER.  */
1267 static gpg_error_t
1268 sexp_extract_identifier (gcry_sexp_t sexp, char **identifier)
1269 {
1270   char *identifier_new;
1271   gcry_sexp_t sublist;
1272   const char *data;
1273   size_t data_n;
1274   gpg_error_t err;
1275
1276   identifier_new = NULL;
1277   err = 0;
1278   
1279   sublist = gcry_sexp_nth (sexp, 1);
1280   if (! sublist)
1281     {
1282       err = gpg_error (GPG_ERR_INV_SEXP);
1283       goto out;
1284     }
1285
1286   data = gcry_sexp_nth_data (sublist, 0, &data_n);
1287   if (! data)
1288     {
1289       err = gpg_error (GPG_ERR_INV_SEXP);
1290       goto out;
1291     }
1292
1293   identifier_new = make_cstring (data, data_n);
1294   if (! identifier_new)
1295     {
1296       err = gpg_err_code_from_errno (errno);
1297       goto out;
1298     }
1299
1300   *identifier = identifier_new;
1301
1302  out:
1303
1304   gcry_sexp_release (sublist);
1305
1306   return err;
1307 }
1308
1309 \f
1310
1311 /*
1312
1313   Key I/O.
1314
1315 */
1316
1317 /* Search for a key specification entry.  If SSH_NAME is not NULL,
1318    search for an entry whose "ssh_name" is equal to SSH_NAME;
1319    otherwise, search for an entry whose "name" is equal to NAME.
1320    Store found entry in SPEC on success, return error otherwise.  */
1321 static gpg_error_t
1322 ssh_key_type_lookup (const char *ssh_name, const char *name,
1323                      ssh_key_type_spec_t *spec)
1324 {
1325   gpg_error_t err;
1326   unsigned int i;
1327
1328   for (i = 0; i < DIM (ssh_key_types); i++)
1329     if ((ssh_name && (! strcmp (ssh_name, ssh_key_types[i].ssh_identifier)))
1330         || (name && (! strcmp (name, ssh_key_types[i].identifier))))
1331       break;
1332   
1333   if (i == DIM (ssh_key_types))
1334     err = gpg_error (GPG_ERR_NOT_FOUND);
1335   else
1336     {
1337       *spec = ssh_key_types[i];
1338       err = 0;
1339     }
1340
1341   return err;
1342 }
1343
1344 /* Receive a key from STREAM, according to the key specification given
1345    as KEY_SPEC.  Depending on SECRET, receive a secret or a public
1346    key.  If READ_COMMENT is true, receive a comment string as well.
1347    Constructs a new S-Expression from received data and stores it in
1348    KEY_NEW.  Returns zero on success or an error code.  */
1349 static gpg_error_t
1350 ssh_receive_key (estream_t stream, gcry_sexp_t *key_new, int secret,
1351                  int read_comment, ssh_key_type_spec_t *key_spec)
1352 {
1353   gpg_error_t err;
1354   char *key_type;
1355   char *comment;
1356   gcry_sexp_t key;
1357   ssh_key_type_spec_t spec;
1358   gcry_mpi_t *mpi_list;
1359   const char *elems;
1360
1361   mpi_list = NULL;
1362   key_type = NULL;
1363   comment = "";
1364   key = NULL;
1365         
1366   err = stream_read_cstring (stream, &key_type);
1367   if (err)
1368     goto out;
1369
1370   err = ssh_key_type_lookup (key_type, NULL, &spec);
1371   if (err)
1372     goto out;
1373
1374   err = ssh_receive_mpint_list (stream, secret, spec, &mpi_list);
1375   if (err)
1376     goto out;
1377
1378   if (read_comment)
1379     {
1380       err = stream_read_cstring (stream, &comment);
1381       if (err)
1382         goto out;
1383     }
1384
1385   if (secret)
1386     elems = spec.elems_key_secret;
1387   else
1388     elems = spec.elems_key_public;
1389
1390   if (spec.key_modifier)
1391     {
1392       err = (*spec.key_modifier) (elems, mpi_list);
1393       if (err)
1394         goto out;
1395     }
1396
1397   err = sexp_key_construct (&key, spec, secret, mpi_list, comment);
1398   if (err)
1399     goto out;
1400
1401   if (key_spec)
1402     *key_spec = spec;
1403   *key_new = key;
1404   
1405  out:
1406
1407   mpint_list_free (mpi_list);
1408   xfree (key_type);
1409   if (read_comment)
1410     xfree (comment);
1411
1412   return err;
1413 }
1414
1415 /* Converts a key of type TYPE, whose key material is given in MPIS,
1416    into a newly created binary blob, which is to be stored in
1417    BLOB/BLOB_SIZE.  Returns zero on success or an error code.  */
1418 static gpg_error_t
1419 ssh_convert_key_to_blob (unsigned char **blob, size_t *blob_size,
1420                          const char *type, gcry_mpi_t *mpis)
1421 {
1422   unsigned char *blob_new;
1423   long int blob_size_new;
1424   estream_t stream;
1425   gpg_error_t err;
1426   unsigned int i;
1427
1428   *blob = NULL;
1429   *blob_size = 0;
1430
1431   blob_new = NULL;
1432   stream = NULL;
1433   err = 0;
1434
1435   stream = es_mopen (NULL, 0, 0, 1, NULL, NULL, "r+");
1436   if (! stream)
1437     {
1438       err = gpg_error_from_syserror ();
1439       goto out;
1440     }
1441
1442   err = stream_write_cstring (stream, type);
1443   if (err)
1444     goto out;
1445
1446   for (i = 0; mpis[i] && (! err); i++)
1447     err = stream_write_mpi (stream, mpis[i]);
1448   if (err)
1449     goto out;
1450
1451   blob_size_new = es_ftell (stream);
1452   if (blob_size_new == -1)
1453     {
1454       err = gpg_error_from_syserror ();
1455       goto out;
1456     }
1457   
1458   err = es_fseek (stream, 0, SEEK_SET);
1459   if (err)
1460     goto out;
1461
1462   blob_new = xtrymalloc (blob_size_new);
1463   if (! blob_new)
1464     {
1465       err = gpg_error_from_syserror ();
1466       goto out;
1467     }
1468
1469   err = stream_read_data (stream, blob_new, blob_size_new);
1470   if (err)
1471     goto out;
1472
1473   *blob = blob_new;
1474   *blob_size = blob_size_new;
1475
1476  out:
1477
1478   if (stream)
1479     es_fclose (stream);
1480   if (err)
1481     xfree (blob_new);
1482
1483   return err;
1484 }
1485                               
1486
1487 /* Write the public key KEY_PUBLIC to STREAM in SSH key format.  If
1488    OVERRIDE_COMMENT is not NULL, it will be used instead of the
1489    comment stored in the key.  */
1490 static gpg_error_t
1491 ssh_send_key_public (estream_t stream, gcry_sexp_t key_public,
1492                      const char *override_comment)
1493 {
1494   ssh_key_type_spec_t spec;
1495   gcry_mpi_t *mpi_list;
1496   char *key_type;
1497   char *comment;
1498   unsigned char *blob;
1499   size_t blob_n;
1500   gpg_error_t err;
1501
1502   key_type = NULL;
1503   mpi_list = NULL;
1504   comment = NULL;
1505   blob = NULL;
1506
1507   err = sexp_extract_identifier (key_public, &key_type);
1508   if (err)
1509     goto out;
1510
1511   err = ssh_key_type_lookup (NULL, key_type, &spec);
1512   if (err)
1513     goto out;
1514
1515   err = sexp_key_extract (key_public, spec, NULL, &mpi_list, &comment);
1516   if (err)
1517     goto out;
1518
1519   err = ssh_convert_key_to_blob (&blob, &blob_n,
1520                                  spec.ssh_identifier, mpi_list);
1521   if (err)
1522     goto out;
1523   
1524   err = stream_write_string (stream, blob, blob_n);
1525   if (err)
1526     goto out;
1527
1528   err = stream_write_cstring (stream,
1529                               override_comment? override_comment : comment);
1530   
1531  out:
1532
1533   mpint_list_free (mpi_list);
1534   xfree (key_type);
1535   xfree (comment);
1536   xfree (blob);
1537
1538   return err;
1539 }
1540
1541 /* Read a public key out of BLOB/BLOB_SIZE according to the key
1542    specification given as KEY_SPEC, storing the new key in KEY_PUBLIC.
1543    Returns zero on success or an error code.  */
1544 static gpg_error_t
1545 ssh_read_key_public_from_blob (unsigned char *blob, size_t blob_size,
1546                                gcry_sexp_t *key_public,
1547                                ssh_key_type_spec_t *key_spec)
1548 {
1549   estream_t blob_stream;
1550   gpg_error_t err;
1551
1552   err = 0;
1553   
1554   blob_stream = es_mopen (NULL, 0, 0, 1, NULL, NULL, "r+");
1555   if (! blob_stream)
1556     {
1557       err = gpg_error_from_syserror ();
1558       goto out;
1559     }
1560
1561   err = stream_write_data (blob_stream, blob, blob_size);
1562   if (err)
1563     goto out;
1564
1565   err = es_fseek (blob_stream, 0, SEEK_SET);
1566   if (err)
1567     goto out;
1568
1569   err = ssh_receive_key (blob_stream, key_public, 0, 0, key_spec);
1570
1571  out:
1572
1573   if (blob_stream)
1574     es_fclose (blob_stream);
1575
1576   return err;
1577 }
1578
1579 \f
1580
1581 /* This function calculates the key grip for the key contained in the
1582    S-Expression KEY and writes it to BUFFER, which must be large
1583    enough to hold it.  Returns usual error code.  */
1584 static gpg_error_t
1585 ssh_key_grip (gcry_sexp_t key, unsigned char *buffer)
1586 {
1587   if (!gcry_pk_get_keygrip (key, buffer))
1588     return gpg_error (GPG_ERR_INTERNAL);
1589
1590   return 0;
1591 }
1592
1593 /* Converts the secret key KEY_SECRET into a public key, storing it in
1594    KEY_PUBLIC.  SPEC is the according key specification.  Returns zero
1595    on success or an error code.  */
1596 static gpg_error_t
1597 key_secret_to_public (gcry_sexp_t *key_public,
1598                       ssh_key_type_spec_t spec, gcry_sexp_t key_secret)
1599 {
1600   char *comment;
1601   gcry_mpi_t *mpis;
1602   gpg_error_t err;
1603   int is_secret;
1604
1605   comment = NULL;
1606   mpis = NULL;
1607
1608   err = sexp_key_extract (key_secret, spec, &is_secret, &mpis, &comment);
1609   if (err)
1610     goto out;
1611
1612   err = sexp_key_construct (key_public, spec, 0, mpis, comment);
1613
1614  out:
1615
1616   mpint_list_free (mpis);
1617   xfree (comment);
1618
1619   return err;
1620 }
1621
1622
1623 /* Check whether a smartcard is available and whether it has a usable
1624    key.  Store a copy of that key at R_PK and return 0.  If no key is
1625    available store NULL at R_PK and return an error code.  If CARDSN
1626    is not NULL, a string with the serial number of the card will be
1627    a malloced and stored there. */
1628 static gpg_error_t
1629 card_key_available (ctrl_t ctrl, gcry_sexp_t *r_pk, char **cardsn)
1630 {
1631   gpg_error_t err;
1632   char *authkeyid;
1633   char *serialno = NULL;
1634   unsigned char *pkbuf;
1635   size_t pkbuflen;
1636   gcry_sexp_t s_pk;
1637   unsigned char grip[20];
1638
1639   *r_pk = NULL;
1640   if (cardsn)
1641     *cardsn = NULL;
1642
1643   /* First see whether a card is available and whether the application
1644      is supported.  */
1645   err = agent_card_getattr (ctrl, "$AUTHKEYID", &authkeyid);
1646   if ( gpg_err_code (err) == GPG_ERR_CARD_REMOVED )
1647     {
1648       /* Ask for the serial number to reset the card.  */
1649       err = agent_card_serialno (ctrl, &serialno);
1650       if (err)
1651         {
1652           if (opt.verbose)
1653             log_info (_("error getting serial number of card: %s\n"),
1654                       gpg_strerror (err));
1655           return err;
1656         }
1657       log_info (_("detected card with S/N: %s\n"), serialno);
1658       err = agent_card_getattr (ctrl, "$AUTHKEYID", &authkeyid);
1659     }
1660   if (err)
1661     {
1662       log_error (_("error getting default authentication keyID of card: %s\n"),
1663                  gpg_strerror (err));
1664       xfree (serialno);
1665       return err;
1666     }
1667
1668   /* Get the S/N if we don't have it yet.  Use the fast getattr method.  */
1669   if (!serialno && (err = agent_card_getattr (ctrl, "SERIALNO", &serialno)) )
1670     {
1671       log_error (_("error getting serial number of card: %s\n"),
1672                  gpg_strerror (err));
1673       xfree (authkeyid);
1674       return err;
1675     }
1676
1677   /* Read the public key.  */
1678   err = agent_card_readkey (ctrl, authkeyid, &pkbuf);
1679   if (err)
1680     {
1681       if (opt.verbose)
1682         log_info (_("no suitable card key found: %s\n"), gpg_strerror (err));
1683       xfree (serialno);
1684       xfree (authkeyid);
1685       return err;
1686     }
1687
1688   pkbuflen = gcry_sexp_canon_len (pkbuf, 0, NULL, NULL);
1689   err = gcry_sexp_sscan (&s_pk, NULL, (char*)pkbuf, pkbuflen);
1690   if (err)
1691     {
1692       log_error ("failed to build S-Exp from received card key: %s\n",
1693                  gpg_strerror (err));
1694       xfree (pkbuf);
1695       xfree (serialno);
1696       xfree (authkeyid);
1697       return err;
1698     }
1699
1700   err = ssh_key_grip (s_pk, grip);
1701   if (err)
1702     {
1703       log_debug ("error computing keygrip from received card key: %s\n",
1704                  gcry_strerror (err));
1705       xfree (pkbuf);
1706       gcry_sexp_release (s_pk);
1707       xfree (serialno);
1708       xfree (authkeyid);
1709       return err;
1710     }
1711
1712   if ( agent_key_available (grip) )
1713     {
1714       /* (Shadow)-key is not available in our key storage.  */
1715       unsigned char *shadow_info;
1716       unsigned char *tmp;
1717       
1718       shadow_info = make_shadow_info (serialno, authkeyid);
1719       if (!shadow_info)
1720         {
1721           err = gpg_error_from_syserror ();
1722           xfree (pkbuf);
1723           gcry_sexp_release (s_pk);
1724           xfree (serialno);
1725           xfree (authkeyid);
1726           return err;
1727         }
1728       err = agent_shadow_key (pkbuf, shadow_info, &tmp);
1729       xfree (shadow_info);
1730       if (err)
1731         {
1732           log_error (_("shadowing the key failed: %s\n"), gpg_strerror (err));
1733           xfree (pkbuf);
1734           gcry_sexp_release (s_pk);
1735           xfree (serialno);
1736           xfree (authkeyid);
1737           return err;
1738         }
1739       xfree (pkbuf);
1740       pkbuf = tmp;
1741       pkbuflen = gcry_sexp_canon_len (pkbuf, 0, NULL, NULL);
1742       assert (pkbuflen);
1743
1744       err = agent_write_private_key (grip, pkbuf, pkbuflen, 0);
1745       if (err)
1746         {
1747           log_error (_("error writing key: %s\n"), gpg_strerror (err));
1748           xfree (pkbuf);
1749           gcry_sexp_release (s_pk);
1750           xfree (serialno);
1751           xfree (authkeyid);
1752           return err;
1753         }
1754     }
1755
1756   if (cardsn)
1757     {
1758       char *dispsn;
1759
1760       /* If the card handler is able to return a short serialnumber,
1761          use that one, else use the complete serialno. */
1762       if (!agent_card_getattr (ctrl, "$DISPSERIALNO", &dispsn))
1763         {
1764           *cardsn = xtryasprintf ("cardno:%s", dispsn);
1765           xfree (dispsn);
1766         }
1767       else
1768         *cardsn = xtryasprintf ("cardno:%s", serialno);
1769       if (!*cardsn)
1770         {
1771           err = gpg_error_from_syserror ();
1772           xfree (pkbuf);
1773           gcry_sexp_release (s_pk);
1774           xfree (serialno);
1775           xfree (authkeyid);
1776           return err;
1777         }
1778     }
1779
1780   xfree (pkbuf);
1781   xfree (serialno);
1782   xfree (authkeyid);
1783   *r_pk = s_pk;
1784   return 0;
1785 }
1786
1787
1788 \f
1789
1790 /*
1791
1792   Request handler.  Each handler is provided with a CTRL context, a
1793   REQUEST object and a RESPONSE object.  The actual request is to be
1794   read from REQUEST, the response needs to be written to RESPONSE.
1795
1796 */
1797
1798
1799 /* Handler for the "request_identities" command.  */
1800 static gpg_error_t
1801 ssh_handler_request_identities (ctrl_t ctrl,
1802                                 estream_t request, estream_t response)
1803 {
1804   char *key_type;
1805   ssh_key_type_spec_t spec;
1806   struct dirent *dir_entry;
1807   char *key_directory;
1808   size_t key_directory_n;
1809   char *key_path;
1810   unsigned char *buffer;
1811   size_t buffer_n;
1812   u32 key_counter;
1813   estream_t key_blobs;
1814   gcry_sexp_t key_secret;
1815   gcry_sexp_t key_public;
1816   DIR *dir;
1817   gpg_error_t err;
1818   int ret;
1819   FILE *ctrl_fp = NULL;
1820   char *cardsn;
1821   gpg_error_t ret_err;
1822
1823   (void)request;
1824
1825   /* Prepare buffer stream.  */
1826
1827   key_directory = NULL;
1828   key_secret = NULL;
1829   key_public = NULL;
1830   key_type = NULL;
1831   key_path = NULL;
1832   key_counter = 0;
1833   buffer = NULL;
1834   dir = NULL;
1835   err = 0;
1836
1837   key_blobs = es_mopen (NULL, 0, 0, 1, NULL, NULL, "r+");
1838   if (! key_blobs)
1839     {
1840       err = gpg_error_from_syserror ();
1841       goto out;
1842     }
1843
1844   /* Open key directory.  */
1845   key_directory = make_filename (opt.homedir, GNUPG_PRIVATE_KEYS_DIR, NULL);
1846   if (! key_directory)
1847     {
1848       err = gpg_err_code_from_errno (errno);
1849       goto out;
1850     }
1851   key_directory_n = strlen (key_directory);
1852   
1853   key_path = xtrymalloc (key_directory_n + 46);
1854   if (! key_path)
1855     {
1856       err = gpg_err_code_from_errno (errno);
1857       goto out;
1858     }
1859
1860   sprintf (key_path, "%s/", key_directory);
1861   sprintf (key_path + key_directory_n + 41, ".key");
1862
1863   dir = opendir (key_directory);
1864   if (! dir)
1865     {
1866       err = gpg_err_code_from_errno (errno);
1867       goto out;
1868     }
1869
1870
1871
1872   /* First check whether a key is currently available in the card
1873      reader - this should be allowed even without being listed in
1874      sshcontrol. */
1875
1876   if (!card_key_available (ctrl, &key_public, &cardsn))
1877     {
1878       err = ssh_send_key_public (key_blobs, key_public, cardsn);
1879       gcry_sexp_release (key_public);
1880       key_public = NULL;
1881       xfree (cardsn);
1882       if (err)
1883         goto out;
1884       
1885       key_counter++;
1886     }
1887
1888
1889   /* Then look at all the registered an allowed keys. */
1890
1891
1892   /* Fixme: We should better iterate over the control file and check
1893      whether the key file is there.  This is better in resepct to
1894      performance if tehre are a lot of key sin our key storage. */
1895   /* FIXME: make sure that buffer gets deallocated properly.  */
1896   err = open_control_file (&ctrl_fp, 0);
1897   if (err)
1898     goto out;
1899
1900   while ( (dir_entry = readdir (dir)) )
1901     {
1902       if ((strlen (dir_entry->d_name) == 44)
1903           && (! strncmp (dir_entry->d_name + 40, ".key", 4)))
1904         {
1905           char hexgrip[41];
1906           int disabled;
1907
1908           /* We do only want to return keys listed in our control
1909              file. */
1910           strncpy (hexgrip, dir_entry->d_name, 40);
1911           hexgrip[40] = 0;
1912           if ( strlen (hexgrip) != 40 )
1913             continue;
1914           if (search_control_file (ctrl_fp, hexgrip, &disabled, NULL)
1915               || disabled)
1916             continue;
1917
1918           strncpy (key_path + key_directory_n + 1, dir_entry->d_name, 40);
1919
1920           /* Read file content.  */
1921           err = file_to_buffer (key_path, &buffer, &buffer_n);
1922           if (err)
1923             goto out;
1924               
1925           err = gcry_sexp_sscan (&key_secret, NULL, (char*)buffer, buffer_n);
1926           if (err)
1927             goto out;
1928
1929           xfree (buffer);
1930           buffer = NULL;
1931
1932           err = sexp_extract_identifier (key_secret, &key_type);
1933           if (err)
1934             goto out;
1935
1936           err = ssh_key_type_lookup (NULL, key_type, &spec);
1937           if (err)
1938             goto out;
1939
1940           xfree (key_type);
1941           key_type = NULL;
1942
1943           err = key_secret_to_public (&key_public, spec, key_secret);
1944           if (err)
1945             goto out;
1946
1947           gcry_sexp_release (key_secret);
1948           key_secret = NULL;
1949               
1950           err = ssh_send_key_public (key_blobs, key_public, NULL);
1951           if (err)
1952             goto out;
1953
1954           gcry_sexp_release (key_public);
1955           key_public = NULL;
1956
1957           key_counter++;
1958         }
1959     }
1960   
1961   ret = es_fseek (key_blobs, 0, SEEK_SET);
1962   if (ret)
1963     {
1964       err = gpg_error_from_syserror ();
1965       goto out;
1966     }
1967
1968  out:
1969
1970   /* Send response.  */
1971
1972   gcry_sexp_release (key_secret);
1973   gcry_sexp_release (key_public);
1974
1975   if (! err)
1976     {
1977       ret_err = stream_write_byte (response, SSH_RESPONSE_IDENTITIES_ANSWER);
1978       if (ret_err)
1979         goto leave;
1980       ret_err = stream_write_uint32 (response, key_counter);
1981       if (ret_err)
1982         goto leave;
1983       ret_err = stream_copy (response, key_blobs);
1984       if (ret_err)
1985         goto leave;
1986     }
1987   else
1988     {
1989       ret_err = stream_write_byte (response, SSH_RESPONSE_FAILURE);
1990       goto leave;
1991     };
1992
1993  leave:
1994
1995   if (key_blobs)
1996     es_fclose (key_blobs);
1997   if (dir)
1998     closedir (dir);
1999
2000   if (ctrl_fp)
2001     fclose (ctrl_fp);
2002
2003   xfree (key_directory);
2004   xfree (key_path);
2005   xfree (buffer);
2006   xfree (key_type);
2007
2008   return ret_err;
2009 }
2010
2011
2012 /* This function hashes the data contained in DATA of size DATA_N
2013    according to the message digest algorithm specified by MD_ALGORITHM
2014    and writes the message digest to HASH, which needs to large enough
2015    for the digest.  */
2016 static gpg_error_t
2017 data_hash (unsigned char *data, size_t data_n,
2018            int md_algorithm, unsigned char *hash)
2019 {
2020   gcry_md_hash_buffer (md_algorithm, hash, data, data_n);
2021
2022   return 0;
2023 }
2024
2025 /* This function signs the data contained in CTRL, stores the created
2026    signature in newly allocated memory in SIG and it's size in SIG_N;
2027    SIG_ENCODER is the signature encoder to use.  */
2028 static gpg_error_t
2029 data_sign (ctrl_t ctrl, ssh_signature_encoder_t sig_encoder,
2030            unsigned char **sig, size_t *sig_n)
2031 {
2032   gpg_error_t err;
2033   gcry_sexp_t signature_sexp = NULL;
2034   estream_t stream = NULL;
2035   gcry_sexp_t valuelist = NULL;
2036   gcry_sexp_t sublist = NULL;
2037   gcry_mpi_t sig_value = NULL;
2038   unsigned char *sig_blob = NULL;
2039   size_t sig_blob_n = 0;
2040   char *identifier = NULL;
2041   const char *identifier_raw;
2042   size_t identifier_n;
2043   ssh_key_type_spec_t spec;
2044   int ret;
2045   unsigned int i;
2046   const char *elems;
2047   size_t elems_n;
2048   gcry_mpi_t *mpis = NULL;
2049
2050   *sig = NULL;
2051   *sig_n = 0;
2052
2053   ctrl->use_auth_call = 1;
2054   err = agent_pksign_do (ctrl,
2055                          _("Please enter the passphrase "
2056                            "for the ssh key%0A  %c"), &signature_sexp,
2057                          CACHE_MODE_SSH, ttl_from_sshcontrol);
2058   ctrl->use_auth_call = 0;
2059   if (err)
2060     goto out;
2061
2062   valuelist = gcry_sexp_nth (signature_sexp, 1);
2063   if (! valuelist)
2064     {
2065       err = gpg_error (GPG_ERR_INV_SEXP);
2066       goto out;
2067     }
2068
2069   stream = es_mopen (NULL, 0, 0, 1, NULL, NULL, "r+");
2070   if (! stream)
2071     {
2072       err = gpg_error_from_syserror ();
2073       goto out;
2074     }
2075
2076   identifier_raw = gcry_sexp_nth_data (valuelist, 0, &identifier_n);
2077   if (! identifier_raw)
2078     {
2079       err = gpg_error (GPG_ERR_INV_SEXP);
2080       goto out;
2081     }
2082
2083   identifier = make_cstring (identifier_raw, identifier_n);
2084   if (! identifier)
2085     {
2086       err = gpg_error_from_syserror ();
2087       goto out;
2088     }
2089
2090   err = ssh_key_type_lookup (NULL, identifier, &spec);
2091   if (err)
2092     goto out;
2093
2094   err = stream_write_cstring (stream, spec.ssh_identifier);
2095   if (err)
2096     goto out;
2097
2098   elems = spec.elems_signature;
2099   elems_n = strlen (elems);
2100
2101   mpis = xtrycalloc (elems_n + 1, sizeof *mpis);
2102   if (!mpis)
2103     {
2104       err = gpg_error_from_syserror ();
2105       goto out;
2106     }
2107
2108   for (i = 0; i < elems_n; i++)
2109     {
2110       sublist = gcry_sexp_find_token (valuelist, spec.elems_signature + i, 1);
2111       if (! sublist)
2112         {
2113           err = gpg_error (GPG_ERR_INV_SEXP);
2114           break;
2115         }
2116
2117       sig_value = gcry_sexp_nth_mpi (sublist, 1, GCRYMPI_FMT_USG);
2118       if (! sig_value)
2119         {
2120           err = gpg_error (GPG_ERR_INTERNAL); /* FIXME?  */
2121           break;
2122         }
2123       gcry_sexp_release (sublist);
2124       sublist = NULL;
2125
2126       mpis[i] = sig_value;
2127     }
2128   if (err)
2129     goto out;
2130
2131   err = (*sig_encoder) (stream, mpis);
2132   if (err)
2133     goto out;
2134
2135   sig_blob_n = es_ftell (stream);
2136   if (sig_blob_n == -1)
2137     {
2138       err = gpg_error_from_syserror ();
2139       goto out;
2140     }
2141
2142   sig_blob = xtrymalloc (sig_blob_n);
2143   if (! sig_blob)
2144     {
2145       err = gpg_error_from_syserror ();
2146       goto out;
2147     }
2148
2149   ret = es_fseek (stream, 0, SEEK_SET);
2150   if (ret)
2151     {
2152       err = gpg_error_from_syserror ();
2153       goto out;
2154     }    
2155
2156   err = stream_read_data (stream, sig_blob, sig_blob_n);
2157   if (err)
2158     goto out;
2159   
2160   *sig = sig_blob;
2161   *sig_n = sig_blob_n;
2162   
2163  out:
2164
2165   if (err)
2166     xfree (sig_blob);
2167
2168   if (stream)
2169     es_fclose (stream);
2170   gcry_sexp_release (valuelist);
2171   gcry_sexp_release (signature_sexp);
2172   gcry_sexp_release (sublist);
2173   mpint_list_free (mpis);
2174   xfree (identifier);
2175
2176   return err;
2177 }
2178
2179 /* Handler for the "sign_request" command.  */
2180 static gpg_error_t
2181 ssh_handler_sign_request (ctrl_t ctrl, estream_t request, estream_t response)
2182 {
2183   gcry_sexp_t key;
2184   ssh_key_type_spec_t spec;
2185   unsigned char hash[MAX_DIGEST_LEN];
2186   unsigned int hash_n;
2187   unsigned char key_grip[20];
2188   unsigned char *key_blob;
2189   u32 key_blob_size;
2190   unsigned char *data;
2191   unsigned char *sig;
2192   size_t sig_n;
2193   u32 data_size;
2194   u32 flags;
2195   gpg_error_t err;
2196   gpg_error_t ret_err;
2197
2198   key_blob = NULL;
2199   data = NULL;
2200   sig = NULL;
2201   key = NULL;
2202
2203   /* Receive key.  */
2204   
2205   err = stream_read_string (request, 0, &key_blob, &key_blob_size);
2206   if (err)
2207     goto out;
2208
2209   err = ssh_read_key_public_from_blob (key_blob, key_blob_size, &key, &spec);
2210   if (err)
2211     goto out;
2212
2213   /* Receive data to sign.  */
2214   err = stream_read_string (request, 0, &data, &data_size);
2215   if (err)
2216     goto out;
2217
2218   /* FIXME?  */
2219   err = stream_read_uint32 (request, &flags);
2220   if (err)
2221     goto out;
2222
2223   /* Hash data.  */
2224   hash_n = gcry_md_get_algo_dlen (GCRY_MD_SHA1);
2225   if (! hash_n)
2226     {
2227       err = gpg_error (GPG_ERR_INTERNAL);
2228       goto out;
2229     }
2230   err = data_hash (data, data_size, GCRY_MD_SHA1, hash);
2231   if (err)
2232     goto out;
2233
2234   /* Calculate key grip.  */
2235   err = ssh_key_grip (key, key_grip);
2236   if (err)
2237     goto out;
2238
2239   /* Sign data.  */
2240
2241   ctrl->digest.algo = GCRY_MD_SHA1;
2242   memcpy (ctrl->digest.value, hash, hash_n);
2243   ctrl->digest.valuelen = hash_n;
2244   ctrl->digest.raw_value = ! (spec.flags & SPEC_FLAG_USE_PKCS1V2);
2245   ctrl->have_keygrip = 1;
2246   memcpy (ctrl->keygrip, key_grip, 20);
2247
2248   err = data_sign (ctrl, spec.signature_encoder, &sig, &sig_n);
2249   
2250  out:
2251
2252   /* Done.  */
2253
2254   if (! err)
2255     {
2256       ret_err = stream_write_byte (response, SSH_RESPONSE_SIGN_RESPONSE);
2257       if (ret_err)
2258         goto leave;
2259       ret_err = stream_write_string (response, sig, sig_n);
2260       if (ret_err)
2261         goto leave;
2262     }
2263   else
2264     {
2265       ret_err = stream_write_byte (response, SSH_RESPONSE_FAILURE);
2266       if (ret_err)
2267         goto leave;
2268     }
2269   
2270  leave:
2271
2272   gcry_sexp_release (key);
2273   xfree (key_blob);
2274   xfree (data);
2275   xfree (sig);
2276
2277   return ret_err;
2278 }
2279
2280 /* This function extracts the comment contained in the key
2281    S-Expression KEY and stores a copy in COMMENT.  Returns usual error
2282    code.  */
2283 static gpg_error_t
2284 ssh_key_extract_comment (gcry_sexp_t key, char **comment)
2285 {
2286   gcry_sexp_t comment_list;
2287   char *comment_new;
2288   const char *data;
2289   size_t data_n;
2290   gpg_error_t err;
2291
2292   comment_list = gcry_sexp_find_token (key, "comment", 0);
2293   if (! comment_list)
2294     {
2295       err = gpg_error (GPG_ERR_INV_SEXP);
2296       goto out;
2297     }
2298   
2299   data = gcry_sexp_nth_data (comment_list, 1, &data_n);
2300   if (! data)
2301     {
2302       err = gpg_error (GPG_ERR_INV_SEXP);
2303       goto out;
2304     }
2305
2306   comment_new = make_cstring (data, data_n);
2307   if (! comment_new)
2308     {
2309       err = gpg_error_from_syserror ();
2310       goto out;
2311     }
2312
2313   *comment = comment_new;
2314   err = 0;
2315
2316  out:
2317
2318   gcry_sexp_release (comment_list);
2319
2320   return err;
2321 }
2322
2323 /* This function converts the key contained in the S-Expression KEY
2324    into a buffer, which is protected by the passphrase PASSPHRASE.
2325    Returns usual error code.  */
2326 static gpg_error_t
2327 ssh_key_to_protected_buffer (gcry_sexp_t key, const char *passphrase,
2328                              unsigned char **buffer, size_t *buffer_n)
2329 {
2330   unsigned char *buffer_new;
2331   unsigned int buffer_new_n;
2332   gpg_error_t err;
2333
2334   err = 0;
2335   buffer_new_n = gcry_sexp_sprint (key, GCRYSEXP_FMT_CANON, NULL, 0);
2336   buffer_new = xtrymalloc_secure (buffer_new_n);
2337   if (! buffer_new)
2338     {
2339       err = gpg_error_from_syserror ();
2340       goto out;
2341     }
2342   
2343   gcry_sexp_sprint (key, GCRYSEXP_FMT_CANON, buffer_new, buffer_new_n);
2344   /* FIXME: guarantee?  */
2345
2346   err = agent_protect (buffer_new, passphrase, buffer, buffer_n);
2347
2348  out:
2349
2350   xfree (buffer_new);
2351
2352   return err;
2353 }
2354
2355
2356
2357 /* Callback function to compare the first entered PIN with the one
2358    currently being entered. */
2359 static int
2360 reenter_compare_cb (struct pin_entry_info_s *pi)
2361 {
2362   const char *pin1 = pi->check_cb_arg;
2363
2364   if (!strcmp (pin1, pi->pin))
2365     return 0; /* okay */
2366   return -1;
2367 }
2368
2369 /* Store the ssh KEY into our local key storage and protect it after
2370    asking for a passphrase.  Cache that passphrase.  TTL is the
2371    maximum caching time for that key.  If the key already exists in
2372    our key storage, don't do anything.  When entering a new key also
2373    add an entry to the sshcontrol file.  */
2374 static gpg_error_t
2375 ssh_identity_register (ctrl_t ctrl, gcry_sexp_t key, int ttl)
2376 {
2377   gpg_error_t err;
2378   unsigned char key_grip_raw[20];
2379   char key_grip[41];
2380   unsigned char *buffer = NULL;
2381   size_t buffer_n;
2382   char *description = NULL;
2383   const char *description2 = _("Please re-enter this passphrase");
2384   char *comment = NULL;
2385   const char *initial_errtext = NULL;
2386   unsigned int i;
2387   struct pin_entry_info_s *pi = NULL, *pi2;
2388
2389   err = ssh_key_grip (key, key_grip_raw);
2390   if (err)
2391     goto out;
2392
2393   /* Check whether the key is already in our key storage.  Don't do
2394      anything then.  */
2395   if ( !agent_key_available (key_grip_raw) )
2396     goto out; /* Yes, key is available.  */
2397
2398   
2399   err = ssh_key_extract_comment (key, &comment);
2400   if (err)
2401     goto out;
2402
2403   if ( asprintf (&description,
2404                  _("Please enter a passphrase to protect"
2405                    " the received secret key%%0A"
2406                    "   %s%%0A"
2407                    "within gpg-agent's key storage"),
2408                  comment ? comment : "?") < 0)
2409     {
2410       err = gpg_error_from_syserror ();
2411       goto out;
2412     }
2413
2414
2415   pi = gcry_calloc_secure (2, sizeof (*pi) + 100 + 1);
2416   if (!pi)
2417     {
2418       err = gpg_error_from_syserror ();
2419       goto out;
2420     }
2421   pi2 = pi + (sizeof *pi + 100 + 1);
2422   pi->max_length = 100;
2423   pi->max_tries = 1;
2424   pi2->max_length = 100;
2425   pi2->max_tries = 1;
2426   pi2->check_cb = reenter_compare_cb;
2427   pi2->check_cb_arg = pi->pin;
2428
2429  next_try:
2430   err = agent_askpin (ctrl, description, NULL, initial_errtext, pi);
2431   initial_errtext = NULL;
2432   if (err)
2433     goto out;
2434
2435   /* Unless the passphrase is empty, ask to confirm it.  */
2436   if (pi->pin && *pi->pin)
2437     {
2438       err = agent_askpin (ctrl, description2, NULL, NULL, pi2);
2439       if (err == -1)
2440         { /* The re-entered one did not match and the user did not
2441              hit cancel. */
2442           initial_errtext = _("does not match - try again");
2443           goto next_try;
2444         }
2445     }
2446
2447   err = ssh_key_to_protected_buffer (key, pi->pin, &buffer, &buffer_n);
2448   if (err)
2449     goto out;
2450
2451   /* Store this key to our key storage.  */
2452   err = agent_write_private_key (key_grip_raw, buffer, buffer_n, 0);
2453   if (err)
2454     goto out;
2455
2456   /* Cache this passphrase. */
2457   for (i = 0; i < 20; i++)
2458     sprintf (key_grip + 2 * i, "%02X", key_grip_raw[i]);
2459
2460   err = agent_put_cache (key_grip, CACHE_MODE_SSH, pi->pin, ttl);
2461   if (err)
2462     goto out;
2463
2464   /* And add an entry to the sshcontrol file.  */
2465   err = add_control_entry (ctrl, key_grip, ttl);
2466
2467
2468  out:
2469   if (pi && pi->max_length)
2470     wipememory (pi->pin, pi->max_length);
2471   xfree (pi);
2472   xfree (buffer);
2473   xfree (comment);
2474   xfree (description); 
2475
2476   return err;
2477 }
2478
2479
2480 /* This function removes the key contained in the S-Expression KEY
2481    from the local key storage, in case it exists there.  Returns usual
2482    error code.  FIXME: this function is a stub.  */
2483 static gpg_error_t
2484 ssh_identity_drop (gcry_sexp_t key)
2485 {
2486   unsigned char key_grip[21] = { 0 };
2487   gpg_error_t err;
2488
2489   err = ssh_key_grip (key, key_grip);
2490   if (err)
2491     goto out;
2492
2493   key_grip[sizeof (key_grip) - 1] = 0;
2494
2495   /* FIXME: What to do here - forgetting the passphrase or deleting
2496      the key from key cache?  */
2497
2498  out:
2499
2500   return err;
2501 }
2502
2503 /* Handler for the "add_identity" command.  */
2504 static gpg_error_t
2505 ssh_handler_add_identity (ctrl_t ctrl, estream_t request, estream_t response)
2506 {
2507   gpg_error_t ret_err;
2508   gpg_error_t err;
2509   gcry_sexp_t key;
2510   unsigned char b;
2511   int confirm;
2512   int ttl;
2513   
2514   confirm = 0;
2515   key = NULL;
2516   ttl = 0;
2517
2518   /* FIXME?  */
2519   err = ssh_receive_key (request, &key, 1, 1, NULL);
2520   if (err)
2521     goto out;
2522
2523   while (1)
2524     {
2525       err = stream_read_byte (request, &b);
2526       if (gpg_err_code (err) == GPG_ERR_EOF)
2527         {
2528           err = 0;
2529           break;
2530         }
2531
2532       switch (b)
2533         {
2534         case SSH_OPT_CONSTRAIN_LIFETIME:
2535           {
2536             u32 n = 0;
2537
2538             err = stream_read_uint32 (request, &n);
2539             if (! err)
2540               ttl = n;
2541             break;
2542           }
2543
2544         case SSH_OPT_CONSTRAIN_CONFIRM:
2545           {
2546             confirm = 1;
2547             break;
2548           }
2549
2550         default:
2551           /* FIXME: log/bad?  */
2552           break;
2553         }
2554     }
2555   if (err)
2556     goto out;
2557
2558   /* FIXME: are constraints used correctly?  */
2559
2560   err = ssh_identity_register (ctrl, key, ttl);
2561
2562  out:
2563
2564   gcry_sexp_release (key);
2565
2566   if (! err)
2567     ret_err = stream_write_byte (response, SSH_RESPONSE_SUCCESS);
2568   else
2569     ret_err = stream_write_byte (response, SSH_RESPONSE_FAILURE);
2570
2571   return ret_err;
2572 }
2573
2574 /* Handler for the "remove_identity" command.  */
2575 static gpg_error_t
2576 ssh_handler_remove_identity (ctrl_t ctrl,
2577                              estream_t request, estream_t response)
2578 {
2579   unsigned char *key_blob;
2580   u32 key_blob_size;
2581   gcry_sexp_t key;
2582   gpg_error_t ret_err;
2583   gpg_error_t err;
2584
2585   (void)ctrl;
2586
2587   /* Receive key.  */
2588
2589   key_blob = NULL;
2590   key = NULL;
2591   
2592   err = stream_read_string (request, 0, &key_blob, &key_blob_size);
2593   if (err)
2594     goto out;
2595
2596   err = ssh_read_key_public_from_blob (key_blob, key_blob_size, &key, NULL);
2597   if (err)
2598     goto out;
2599   
2600   err = ssh_identity_drop (key);
2601
2602  out:
2603
2604   xfree (key_blob);
2605   gcry_sexp_release (key);
2606
2607   if (! err)
2608     ret_err = stream_write_byte (response, SSH_RESPONSE_SUCCESS);
2609   else
2610     ret_err = stream_write_byte (response, SSH_RESPONSE_FAILURE);
2611
2612   return ret_err;
2613 }
2614
2615 /* FIXME: stub function.  Actually useful?  */
2616 static gpg_error_t
2617 ssh_identities_remove_all (void)
2618 {
2619   gpg_error_t err;
2620
2621   err = 0;
2622
2623   /* FIXME: shall we remove _all_ cache entries or only those
2624      registered through the ssh emulation?  */
2625   
2626   return err;
2627 }
2628
2629 /* Handler for the "remove_all_identities" command.  */
2630 static gpg_error_t
2631 ssh_handler_remove_all_identities (ctrl_t ctrl,
2632                                    estream_t request, estream_t response)
2633 {
2634   gpg_error_t ret_err;
2635   gpg_error_t err;
2636
2637   (void)ctrl;
2638   (void)request;
2639   
2640   err = ssh_identities_remove_all ();
2641
2642   if (! err)
2643     ret_err = stream_write_byte (response, SSH_RESPONSE_SUCCESS);
2644   else
2645     ret_err = stream_write_byte (response, SSH_RESPONSE_FAILURE);
2646
2647   return ret_err;
2648 }
2649
2650 /* Lock agent?  FIXME: stub function.  */
2651 static gpg_error_t
2652 ssh_lock (void)
2653 {
2654   gpg_error_t err;
2655
2656   /* FIXME */
2657   log_error ("ssh-agent's lock command is not implemented\n");
2658   err = 0;
2659
2660   return err;
2661 }
2662
2663 /* Unock agent?  FIXME: stub function.  */
2664 static gpg_error_t
2665 ssh_unlock (void)
2666 {
2667   gpg_error_t err;
2668
2669   log_error ("ssh-agent's unlock command is not implemented\n");
2670   err = 0;
2671
2672   return err;
2673 }
2674
2675 /* Handler for the "lock" command.  */
2676 static gpg_error_t
2677 ssh_handler_lock (ctrl_t ctrl, estream_t request, estream_t response)
2678 {
2679   gpg_error_t ret_err;
2680   gpg_error_t err;
2681
2682   (void)ctrl;
2683   (void)request;
2684   
2685   err = ssh_lock ();
2686
2687   if (! err)
2688     ret_err = stream_write_byte (response, SSH_RESPONSE_SUCCESS);
2689   else
2690     ret_err = stream_write_byte (response, SSH_RESPONSE_FAILURE);
2691
2692   return ret_err;
2693 }
2694
2695 /* Handler for the "unlock" command.  */
2696 static gpg_error_t
2697 ssh_handler_unlock (ctrl_t ctrl, estream_t request, estream_t response)
2698 {
2699   gpg_error_t ret_err;
2700   gpg_error_t err;
2701   
2702   (void)ctrl;
2703   (void)request;
2704
2705   err = ssh_unlock ();
2706
2707   if (! err)
2708     ret_err = stream_write_byte (response, SSH_RESPONSE_SUCCESS);
2709   else
2710     ret_err = stream_write_byte (response, SSH_RESPONSE_FAILURE);
2711
2712   return ret_err;
2713 }
2714
2715 \f
2716
2717 /* Return the request specification for the request identified by TYPE
2718    or NULL in case the requested request specification could not be
2719    found.  */
2720 static ssh_request_spec_t *
2721 request_spec_lookup (int type)
2722 {
2723   ssh_request_spec_t *spec;
2724   unsigned int i;
2725
2726   for (i = 0; i < DIM (request_specs); i++)
2727     if (request_specs[i].type == type)
2728       break;
2729   if (i == DIM (request_specs))
2730     {
2731       if (opt.verbose)
2732         log_info ("ssh request %u is not supported\n", type);
2733       spec = NULL;
2734     }
2735   else
2736     spec = request_specs + i;
2737
2738   return spec;
2739 }
2740
2741 /* Process a single request.  The request is read from and the
2742    response is written to STREAM_SOCK.  Uses CTRL as context.  Returns
2743    zero in case of success, non zero in case of failure.  */
2744 static int
2745 ssh_request_process (ctrl_t ctrl, estream_t stream_sock)
2746 {
2747   ssh_request_spec_t *spec;
2748   estream_t response;
2749   estream_t request;
2750   unsigned char request_type;
2751   gpg_error_t err;
2752   int send_err;
2753   int ret;
2754   unsigned char *request_data;
2755   u32 request_data_size;
2756   u32 response_size;
2757
2758   request_data = NULL;
2759   response = NULL;
2760   request = NULL;
2761   send_err = 0;
2762
2763   /* Create memory streams for request/response data.  The entire
2764      request will be stored in secure memory, since it might contain
2765      secret key material.  The response does not have to be stored in
2766      secure memory, since we never give out secret keys. 
2767
2768      Note: we only have little secure memory, but there is NO
2769      possibility of DoS here; only trusted clients are allowed to
2770      connect to the agent.  What could happen is that the agent
2771      returns out-of-secure-memory errors on requests in case the
2772      agent's owner floods his own agent with many large messages.
2773      -moritz */
2774
2775   /* Retrieve request.  */
2776   err = stream_read_string (stream_sock, 1, &request_data, &request_data_size);
2777   if (err)
2778     goto out;
2779
2780   if (opt.verbose > 1)
2781     log_info ("received ssh request of length %u\n",
2782               (unsigned int)request_data_size);
2783
2784   if (! request_data_size)
2785     {
2786       send_err = 1;
2787       goto out;
2788       /* Broken request; FIXME.  */
2789     }
2790
2791   request_type = request_data[0];
2792   spec = request_spec_lookup (request_type);
2793   if (! spec)
2794     {
2795       send_err = 1;
2796       goto out;
2797       /* Unknown request; FIXME.  */
2798     }
2799
2800   if (spec->secret_input)
2801     request = es_mopen (NULL, 0, 0, 1, realloc_secure, gcry_free, "r+");
2802   else
2803     request = es_mopen (NULL, 0, 0, 1, gcry_realloc, gcry_free, "r+");
2804   if (! request)
2805     {
2806       err = gpg_error_from_syserror ();
2807       goto out;
2808     }
2809   ret = es_setvbuf (request, NULL, _IONBF, 0);
2810   if (ret)
2811     {
2812       err = gpg_error_from_syserror ();
2813       goto out;
2814     }
2815   err = stream_write_data (request, request_data + 1, request_data_size - 1);
2816   if (err)
2817     goto out;
2818   es_rewind (request);
2819
2820   response = es_mopen (NULL, 0, 0, 1, NULL, NULL, "r+");
2821   if (! response)
2822     {
2823       err = gpg_error_from_syserror ();
2824       goto out;
2825     }
2826
2827   if (opt.verbose)
2828     log_info ("ssh request handler for %s (%u) started\n",
2829                spec->identifier, spec->type);
2830
2831   err = (*spec->handler) (ctrl, request, response);
2832
2833   if (opt.verbose)
2834     {
2835       if (err)
2836         log_info ("ssh request handler for %s (%u) failed: %s\n",
2837                   spec->identifier, spec->type, gpg_strerror (err));
2838       else
2839         log_info ("ssh request handler for %s (%u) ready\n",
2840                   spec->identifier, spec->type);
2841     }
2842
2843   if (err)
2844     {
2845       send_err = 1;
2846       goto out;
2847     }
2848
2849   response_size = es_ftell (response);
2850   if (opt.verbose > 1)
2851     log_info ("sending ssh response of length %u\n",
2852               (unsigned int)response_size);
2853
2854   err = es_fseek (response, 0, SEEK_SET);
2855   if (err)
2856     {
2857       send_err = 1;
2858       goto out;
2859     }
2860
2861   err = stream_write_uint32 (stream_sock, response_size);
2862   if (err)
2863     {
2864       send_err = 1;
2865       goto out;
2866     }
2867
2868   err = stream_copy (stream_sock, response);
2869   if (err)
2870     goto out;
2871
2872   err = es_fflush (stream_sock);
2873   if (err)
2874     goto out;
2875
2876  out:
2877
2878   if (err && es_feof (stream_sock))
2879     log_error ("error occured while processing request: %s\n",
2880                gpg_strerror (err));
2881
2882   if (send_err)
2883     {
2884       if (opt.verbose > 1)
2885         log_info ("sending ssh error response\n");
2886       err = stream_write_uint32 (stream_sock, 1);
2887       if (err)
2888         goto leave;
2889       err = stream_write_byte (stream_sock, SSH_RESPONSE_FAILURE);
2890       if (err)
2891         goto leave;
2892     }
2893
2894  leave:
2895
2896   if (request)
2897     es_fclose (request);
2898   if (response)
2899     es_fclose (response);
2900   xfree (request_data);         /* FIXME?  */
2901
2902   return !!err;
2903 }
2904
2905 /* Start serving client on SOCK_CLIENT.  */
2906 void
2907 start_command_handler_ssh (ctrl_t ctrl, gnupg_fd_t sock_client)
2908 {
2909   estream_t stream_sock = NULL;
2910   gpg_error_t err = 0;
2911   int ret;
2912
2913   /* Because the ssh protocol does not send us information about the
2914      the current TTY setting, we resort here to use those from startup
2915      or those explictly set.  */
2916   {
2917     static const char *names[] = 
2918       {"GPG_TTY", "DISPLAY", "TERM", "XAUTHORITY", "PINENTRY_USER_DATA", NULL};
2919     int idx;
2920     const char *value;
2921
2922     for (idx=0; !err && names[idx]; idx++)
2923       if (!session_env_getenv (ctrl->session_env, names[idx])
2924           && (value = session_env_getenv (opt.startup_env, names[idx])))
2925         err = session_env_setenv (ctrl->session_env, names[idx], value);
2926     
2927     if (!err && !ctrl->lc_ctype && opt.startup_lc_ctype)
2928       if (!(ctrl->lc_ctype = xtrystrdup (opt.startup_lc_ctype)))
2929         err = gpg_error_from_syserror ();
2930
2931     if (!err && !ctrl->lc_messages && opt.startup_lc_messages)
2932       if (!(ctrl->lc_messages = xtrystrdup (opt.startup_lc_messages)))
2933         err = gpg_error_from_syserror ();
2934
2935     if (err)
2936       {
2937         log_error ("error setting default session environment: %s\n", 
2938                    gpg_strerror (err));
2939         goto out;
2940       }
2941   }
2942
2943
2944   /* Create stream from socket.  */
2945   stream_sock = es_fdopen (FD2INT(sock_client), "r+");
2946   if (!stream_sock)
2947     {
2948       err = gpg_error_from_syserror ();
2949       log_error (_("failed to create stream from socket: %s\n"),
2950                  gpg_strerror (err));
2951       goto out;
2952     }
2953   /* We have to disable the estream buffering, because the estream
2954      core doesn't know about secure memory.  */
2955   ret = es_setvbuf (stream_sock, NULL, _IONBF, 0);
2956   if (ret)
2957     {
2958       err = gpg_error_from_syserror ();
2959       log_error ("failed to disable buffering "
2960                  "on socket stream: %s\n", gpg_strerror (err));
2961       goto out;
2962     }
2963
2964   /* Main processing loop. */
2965   while ( !ssh_request_process (ctrl, stream_sock) )
2966     {
2967       /* Check wether we have reached EOF before trying to read
2968          another request.  */
2969       int c;
2970
2971       c = es_fgetc (stream_sock);
2972       if (c == EOF)
2973         break;
2974       es_ungetc (c, stream_sock);
2975     }
2976
2977   /* Reset the SCD in case it has been used. */
2978   agent_reset_scd (ctrl);
2979
2980
2981  out:
2982   if (stream_sock)
2983     es_fclose (stream_sock);
2984 }