Reworked passing of envars to Pinentry.
[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 "estream.h"
36 #include "i18n.h"
37
38 \f
39
40 /* Request types. */
41 #define SSH_REQUEST_REQUEST_IDENTITIES    11
42 #define SSH_REQUEST_SIGN_REQUEST          13
43 #define SSH_REQUEST_ADD_IDENTITY          17
44 #define SSH_REQUEST_REMOVE_IDENTITY       18
45 #define SSH_REQUEST_REMOVE_ALL_IDENTITIES 19
46 #define SSH_REQUEST_LOCK                  22
47 #define SSH_REQUEST_UNLOCK                23
48 #define SSH_REQUEST_ADD_ID_CONSTRAINED    25
49
50 /* Options. */
51 #define SSH_OPT_CONSTRAIN_LIFETIME         1
52 #define SSH_OPT_CONSTRAIN_CONFIRM          2
53
54 /* Response types. */
55 #define SSH_RESPONSE_SUCCESS               6
56 #define SSH_RESPONSE_FAILURE               5
57 #define SSH_RESPONSE_IDENTITIES_ANSWER    12
58 #define SSH_RESPONSE_SIGN_RESPONSE        14
59
60 /* Other constants.  */
61 #define SSH_DSA_SIGNATURE_PADDING 20
62 #define SSH_DSA_SIGNATURE_ELEMS    2
63 #define SPEC_FLAG_USE_PKCS1V2 (1 << 0)
64
65
66 /* The blurb we put into the header of a newly created control file.  */
67 static const char sshcontrolblurb[] =
68 "# List of allowed ssh keys.  Only keys present in this file are used\n"
69 "# in the SSH protocol.  The ssh-add tool may add new entries to this\n"
70 "# file to enable them; you may also add them manually.  Comment\n"
71 "# lines, like this one, as well as empty lines are ignored.  Lines do\n"
72 "# have a certain length limit but this is not serious limitation as\n" 
73 "# the format of the entries is fixed and checked by gpg-agent. A\n"
74 "# non-comment line starts with optional white spaces, followed by the\n"
75 "# keygrip of the key given as 40 hex digits, optionally followed by a\n"
76 "# the caching TTL in seconds and another optional field for arbitrary\n"
77 "# flags.   Prepend the keygrip with an '!' mark to disable it.\n"
78 "\n";
79
80
81
82 /* Macros.  */
83
84 /* Return a new uint32 with b0 being the most significant byte and b3
85    being the least significant byte.  */
86 #define uint32_construct(b0, b1, b2, b3) \
87   ((b0 << 24) | (b1 << 16) | (b2 << 8) | b3)
88
89 \f
90
91
92 /*
93  * Basic types.
94  */
95
96 /* Type for a request handler.  */
97 typedef gpg_error_t (*ssh_request_handler_t) (ctrl_t ctrl,
98                                               estream_t request,
99                                               estream_t response);
100
101 /* Type, which is used for associating request handlers with the
102    appropriate request IDs.  */
103 typedef struct ssh_request_spec
104 {
105   unsigned char type;
106   ssh_request_handler_t handler;
107   const char *identifier;
108   unsigned int secret_input;
109 } ssh_request_spec_t;
110
111 /* Type for "key modifier functions", which are necessary since
112    OpenSSH and GnuPG treat key material slightly different.  A key
113    modifier is called right after a new key identity has been received
114    in order to "sanitize" the material.  */
115 typedef gpg_error_t (*ssh_key_modifier_t) (const char *elems,
116                                            gcry_mpi_t *mpis);
117
118 /* The encoding of a generated signature is dependent on the
119    algorithm; therefore algorithm specific signature encoding
120    functions are necessary.  */
121 typedef gpg_error_t (*ssh_signature_encoder_t) (estream_t signature_blob,
122                                                 gcry_mpi_t *mpis);
123
124 /* Type, which is used for boundling all the algorithm specific
125    information together in a single object.  */
126 typedef struct ssh_key_type_spec
127 {
128   /* Algorithm identifier as used by OpenSSH.  */
129   const char *ssh_identifier;
130
131   /* Algorithm identifier as used by GnuPG.  */
132   const char *identifier;
133
134   /* List of MPI names for secret keys; order matches the one of the
135      agent protocol.  */
136   const char *elems_key_secret;
137
138   /* List of MPI names for public keys; order matches the one of the
139      agent protocol.  */
140   const char *elems_key_public;
141
142   /* List of MPI names for signature data.  */
143   const char *elems_signature;
144
145   /* List of MPI names for secret keys; order matches the one, which
146      is required by gpg-agent's key access layer.  */
147   const char *elems_sexp_order;
148
149   /* Key modifier function.  Key modifier functions are necessary in
150      order to fix any inconsistencies between the representation of
151      keys on the SSH and on the GnuPG side.  */
152   ssh_key_modifier_t key_modifier;
153
154   /* Signature encoder function.  Signature encoder functions are
155      necessary since the encoding of signatures depends on the used
156      algorithm.  */
157   ssh_signature_encoder_t signature_encoder;
158
159   /* Misc flags.  */
160   unsigned int flags;
161 } ssh_key_type_spec_t;
162
163
164 /* Prototypes.  */
165 static gpg_error_t ssh_handler_request_identities (ctrl_t ctrl,
166                                                    estream_t request,
167                                                    estream_t response);
168 static gpg_error_t ssh_handler_sign_request (ctrl_t ctrl,
169                                              estream_t request,
170                                              estream_t response);
171 static gpg_error_t ssh_handler_add_identity (ctrl_t ctrl,
172                                              estream_t request,
173                                              estream_t response);
174 static gpg_error_t ssh_handler_remove_identity (ctrl_t ctrl,
175                                                 estream_t request,
176                                                 estream_t response);
177 static gpg_error_t ssh_handler_remove_all_identities (ctrl_t ctrl,
178                                                       estream_t request,
179                                                       estream_t response);
180 static gpg_error_t ssh_handler_lock (ctrl_t ctrl,
181                                      estream_t request,
182                                      estream_t response);
183 static gpg_error_t ssh_handler_unlock (ctrl_t ctrl,
184                                        estream_t request,
185                                        estream_t response);
186
187 static gpg_error_t ssh_key_modifier_rsa (const char *elems, gcry_mpi_t *mpis);
188 static gpg_error_t ssh_signature_encoder_rsa (estream_t signature_blob,
189                                               gcry_mpi_t *mpis);
190 static gpg_error_t ssh_signature_encoder_dsa (estream_t signature_blob,
191                                               gcry_mpi_t *mpis);
192
193
194
195 /* Global variables.  */
196    
197
198 /* Associating request types with the corresponding request
199    handlers.  */
200
201 static ssh_request_spec_t request_specs[] =
202   {
203 #define REQUEST_SPEC_DEFINE(id, name, secret_input) \
204   { SSH_REQUEST_##id, ssh_handler_##name, #name, secret_input }
205
206     REQUEST_SPEC_DEFINE (REQUEST_IDENTITIES,    request_identities,    1),
207     REQUEST_SPEC_DEFINE (SIGN_REQUEST,          sign_request,          0),
208     REQUEST_SPEC_DEFINE (ADD_IDENTITY,          add_identity,          1),
209     REQUEST_SPEC_DEFINE (ADD_ID_CONSTRAINED,    add_identity,          1),
210     REQUEST_SPEC_DEFINE (REMOVE_IDENTITY,       remove_identity,       0),
211     REQUEST_SPEC_DEFINE (REMOVE_ALL_IDENTITIES, remove_all_identities, 0),
212     REQUEST_SPEC_DEFINE (LOCK,                  lock,                  0),
213     REQUEST_SPEC_DEFINE (UNLOCK,                unlock,                0)
214 #undef REQUEST_SPEC_DEFINE
215   };
216
217
218 /* Table holding key type specifications.  */
219 static ssh_key_type_spec_t ssh_key_types[] =
220   {
221     {
222       "ssh-rsa", "rsa", "nedupq", "en",   "s",  "nedpqu",
223       ssh_key_modifier_rsa, ssh_signature_encoder_rsa,
224       SPEC_FLAG_USE_PKCS1V2
225     },
226     {
227       "ssh-dss", "dsa", "pqgyx",  "pqgy", "rs", "pqgyx",
228       NULL,                 ssh_signature_encoder_dsa,
229       0
230     },
231   };
232
233 \f
234
235
236
237 /*
238    General utility functions. 
239  */
240
241 /* A secure realloc, i.e. it makes sure to allocate secure memory if A
242    is NULL.  This is required because the standard gcry_realloc does
243    not know whether to allocate secure or normal if NULL is passed as
244    existing buffer.  */
245 static void *
246 realloc_secure (void *a, size_t n)
247 {
248   void *p;
249   
250   if (a)
251     p = gcry_realloc (a, n);
252   else
253     p = gcry_malloc_secure (n);
254
255   return p;
256 }
257
258
259 /* Create and return a new C-string from DATA/DATA_N (i.e.: add
260    NUL-termination); return NULL on OOM.  */
261 static char *
262 make_cstring (const char *data, size_t data_n)
263 {
264   char *s;
265
266   s = xtrymalloc (data_n + 1);
267   if (s)
268     {
269       memcpy (s, data, data_n);
270       s[data_n] = 0;
271     }
272
273   return s;
274 }
275
276
277
278
279 /* 
280    Primitive I/O functions.  
281  */
282
283
284 /* Read a byte from STREAM, store it in B.  */
285 static gpg_error_t
286 stream_read_byte (estream_t stream, unsigned char *b)
287 {
288   gpg_error_t err;
289   int ret;
290
291   ret = es_fgetc (stream);
292   if (ret == EOF)
293     {
294       if (es_ferror (stream))
295         err = gpg_error_from_syserror ();
296       else
297         err = gpg_error (GPG_ERR_EOF);
298       *b = 0;
299     }
300   else
301     {
302       *b = ret & 0xFF;
303       err = 0;
304     }
305
306   return err;
307 }
308
309 /* Write the byte contained in B to STREAM.  */
310 static gpg_error_t
311 stream_write_byte (estream_t stream, unsigned char b)
312 {
313   gpg_error_t err;
314   int ret;
315
316   ret = es_fputc (b, stream);
317   if (ret == EOF)
318     err = gpg_error_from_syserror ();
319   else
320     err = 0;
321
322   return err;
323 }
324
325 /* Read a uint32 from STREAM, store it in UINT32.  */
326 static gpg_error_t
327 stream_read_uint32 (estream_t stream, u32 *uint32)
328 {
329   unsigned char buffer[4];
330   size_t bytes_read;
331   gpg_error_t err;
332   int ret;
333
334   ret = es_read (stream, buffer, sizeof (buffer), &bytes_read);
335   if (ret)
336     err = gpg_error_from_syserror ();
337   else
338     {
339       if (bytes_read != sizeof (buffer))
340         err = gpg_error (GPG_ERR_EOF);
341       else
342         {
343           u32 n;
344
345           n = uint32_construct (buffer[0], buffer[1], buffer[2], buffer[3]);
346           *uint32 = n;
347           err = 0;
348         }
349     }
350
351   return err;
352 }
353
354 /* Write the uint32 contained in UINT32 to STREAM.  */
355 static gpg_error_t
356 stream_write_uint32 (estream_t stream, u32 uint32)
357 {
358   unsigned char buffer[4];
359   gpg_error_t err;
360   int ret;
361
362   buffer[0] = uint32 >> 24;
363   buffer[1] = uint32 >> 16;
364   buffer[2] = uint32 >>  8;
365   buffer[3] = uint32 >>  0;
366
367   ret = es_write (stream, buffer, sizeof (buffer), NULL);
368   if (ret)
369     err = gpg_error_from_syserror ();
370   else
371     err = 0;
372
373   return err;
374 }
375
376 /* Read SIZE bytes from STREAM into BUFFER.  */
377 static gpg_error_t
378 stream_read_data (estream_t stream, unsigned char *buffer, size_t size)
379 {
380   gpg_error_t err;
381   size_t bytes_read;
382   int ret;
383
384   ret = es_read (stream, buffer, size, &bytes_read);
385   if (ret)
386     err = gpg_error_from_syserror ();
387   else
388     {
389       if (bytes_read != size)
390         err = gpg_error (GPG_ERR_EOF);
391       else
392         err = 0;
393     }
394
395   return err;
396 }
397
398 /* Write SIZE bytes from BUFFER to STREAM.  */
399 static gpg_error_t
400 stream_write_data (estream_t stream, const unsigned char *buffer, size_t size)
401 {
402   gpg_error_t err;
403   int ret;
404
405   ret = es_write (stream, buffer, size, NULL);
406   if (ret)
407     err = gpg_error_from_syserror ();
408   else
409     err = 0;
410
411   return err;
412 }
413
414 /* Read a binary string from STREAM into STRING, store size of string
415    in STRING_SIZE; depending on SECURE use secure memory for
416    string.  */
417 static gpg_error_t
418 stream_read_string (estream_t stream, unsigned int secure,
419                     unsigned char **string, u32 *string_size)
420 {
421   gpg_error_t err;
422   unsigned char *buffer = NULL;
423   u32 length = 0;
424
425   /* Read string length.  */
426   err = stream_read_uint32 (stream, &length);
427   if (err)
428     goto out;
429
430   /* Allocate space.  */
431   if (secure)
432     buffer = xtrymalloc_secure (length + 1);
433   else
434     buffer = xtrymalloc (length + 1);
435   if (! buffer)
436     {
437       err = gpg_error_from_syserror ();
438       goto out;
439     }
440
441   /* Read data.  */
442   err = stream_read_data (stream, buffer, length);
443   if (err)
444     goto out;
445
446   /* Finalize string object.  */
447   buffer[length] = 0;
448   *string = buffer;
449   if (string_size)
450     *string_size = length;
451
452  out:
453
454   if (err)
455     xfree (buffer);
456
457   return err;
458 }
459
460 /* Read a C-string from STREAM, store copy in STRING.  */
461 static gpg_error_t
462 stream_read_cstring (estream_t stream, char **string)
463 {
464   unsigned char *buffer;
465   gpg_error_t err;
466
467   err = stream_read_string (stream, 0, &buffer, NULL);
468   if (err)
469     goto out;
470   
471   *string = (char *) buffer;
472
473  out:
474
475   return err;
476 }
477
478
479 /* Write a binary string from STRING of size STRING_N to STREAM.  */
480 static gpg_error_t
481 stream_write_string (estream_t stream,
482                      const unsigned char *string, u32 string_n)
483 {
484   gpg_error_t err;
485
486   err = stream_write_uint32 (stream, string_n);
487   if (err)
488     goto out;
489
490   err = stream_write_data (stream, string, string_n);
491
492  out:
493
494   return err;
495 }
496
497 /* Write a C-string from STRING to STREAM.  */
498 static gpg_error_t
499 stream_write_cstring (estream_t stream, const char *string)
500 {
501   gpg_error_t err;
502
503   err = stream_write_string (stream,
504                              (const unsigned char *) string, strlen (string));
505
506   return err;
507 }                         
508
509 /* Read an MPI from STREAM, store it in MPINT.  Depending on SECURE
510    use secure memory.  */
511 static gpg_error_t
512 stream_read_mpi (estream_t stream, unsigned int secure, gcry_mpi_t *mpint)
513 {
514   unsigned char *mpi_data;
515   u32 mpi_data_size;
516   gpg_error_t err;
517   gcry_mpi_t mpi;
518
519   mpi_data = NULL;
520
521   err = stream_read_string (stream, secure, &mpi_data, &mpi_data_size);
522   if (err)
523     goto out;
524
525   /* To avoid excessive use of secure memory we check that an MPI is
526      not too large. */
527   if (mpi_data_size > 520)
528     {
529       log_error (_("ssh keys greater than %d bits are not supported\n"), 4096);
530       err = GPG_ERR_TOO_LARGE;
531       goto out;
532     }
533
534   err = gcry_mpi_scan (&mpi, GCRYMPI_FMT_STD, mpi_data, mpi_data_size, NULL);
535   if (err)
536     goto out;
537
538   *mpint = mpi;
539
540  out:
541
542   xfree (mpi_data);
543
544   return err;
545 }
546
547 /* Write the MPI contained in MPINT to STREAM.  */
548 static gpg_error_t
549 stream_write_mpi (estream_t stream, gcry_mpi_t mpint)
550 {
551   unsigned char *mpi_buffer;
552   size_t mpi_buffer_n;
553   gpg_error_t err;
554
555   mpi_buffer = NULL;
556
557   err = gcry_mpi_aprint (GCRYMPI_FMT_STD, &mpi_buffer, &mpi_buffer_n, mpint);
558   if (err)
559     goto out;
560
561   err = stream_write_string (stream, mpi_buffer, mpi_buffer_n);
562
563  out:
564
565   xfree (mpi_buffer);
566
567   return err;
568 }
569
570 /* Copy data from SRC to DST until EOF is reached.  */
571 static gpg_error_t
572 stream_copy (estream_t dst, estream_t src)
573 {
574   char buffer[BUFSIZ];
575   size_t bytes_read;
576   gpg_error_t err;
577   int ret;
578
579   err = 0;
580   while (1)
581     {
582       ret = es_read (src, buffer, sizeof (buffer), &bytes_read);
583       if (ret || (! bytes_read))
584         {
585           if (ret)
586             err = gpg_error_from_syserror ();
587           break;
588         }
589       ret = es_write (dst, buffer, bytes_read, NULL);
590       if (ret)
591         {
592           err = gpg_error_from_syserror ();
593           break;
594         }
595     }
596
597   return err;
598 }
599
600
601 /* Read the content of the file specified by FILENAME into a newly
602    create buffer, which is to be stored in BUFFER; store length of
603    buffer in BUFFER_N.  */
604 static gpg_error_t
605 file_to_buffer (const char *filename, unsigned char **buffer, size_t *buffer_n)
606 {
607   unsigned char *buffer_new;
608   struct stat statbuf;
609   estream_t stream;
610   gpg_error_t err;
611   int ret;
612
613   *buffer = NULL;
614   *buffer_n = 0;
615
616   buffer_new = NULL;
617   err = 0;
618   
619   stream = es_fopen (filename, "r");
620   if (! stream)
621     {
622       err = gpg_error_from_syserror ();
623       goto out;
624     }
625
626   ret = fstat (es_fileno (stream), &statbuf);
627   if (ret)
628     {
629       err = gpg_error_from_syserror ();
630       goto out;
631     }
632
633   buffer_new = xtrymalloc (statbuf.st_size);
634   if (! buffer_new)
635     {
636       err = gpg_error_from_syserror ();
637       goto out;
638     }
639
640   err = stream_read_data (stream, buffer_new, statbuf.st_size);
641   if (err)
642     goto out;
643
644   *buffer = buffer_new;
645   *buffer_n = statbuf.st_size;
646
647  out:
648
649   if (stream)
650     es_fclose (stream);
651
652   if (err)
653     xfree (buffer_new);
654
655   return err;
656 }
657
658
659
660 \f
661 /* Open the ssh control file and create it if not available. With
662    APPEND passed as true the file will be opened in append mode,
663    otherwise in read only mode.  On success a file pointer is stored
664    at the address of R_FP. */
665 static gpg_error_t
666 open_control_file (FILE **r_fp, int append)
667 {
668   gpg_error_t err;
669   char *fname;
670   FILE *fp;
671
672   /* Note: As soon as we start to use non blocking functions here
673      (i.e. where Pth might switch threads) we need to employ a
674      mutex.  */
675   *r_fp = NULL;
676   fname = make_filename (opt.homedir, "sshcontrol", NULL);
677   /* FIXME: With "a+" we are not able to check whether this will will
678      be created and thus the blurb needs to be written first.  */
679   fp = fopen (fname, append? "a+":"r");
680   if (!fp && errno == ENOENT)
681     {
682       /* Fixme: "x" is a GNU extension.  We might want to use the es_
683          functions here.  */
684       fp = fopen (fname, "wx");  
685       if (!fp)
686         {
687           err = gpg_error (gpg_err_code_from_errno (errno));
688           log_error (_("can't create `%s': %s\n"), fname, gpg_strerror (err));
689           xfree (fname);
690           return err;
691         }
692       fputs (sshcontrolblurb, fp);
693       fclose (fp);
694       fp = fopen (fname, append? "a+":"r");
695     }
696
697   if (!fp)
698     {
699       err = gpg_error (gpg_err_code_from_errno (errno));
700       log_error (_("can't open `%s': %s\n"), fname, gpg_strerror (err));
701       xfree (fname);
702       return err;
703     }
704   
705   *r_fp = fp;  
706
707   return 0;
708 }
709
710
711 /* Search the file at stream FP from the beginning until a matching
712    HEXGRIP is found; return success in this case and store true at
713    DISABLED if the found key has been disabled.  If R_TTL is not NULL
714    a specified TTL for that key is stored there. */
715 static gpg_error_t
716 search_control_file (FILE *fp, const char *hexgrip, 
717                      int *r_disabled, int *r_ttl)
718 {
719   int c, i;
720   char *p, *pend, line[256];
721   long ttl;
722
723   assert (strlen (hexgrip) == 40 );
724
725   rewind (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 }