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