Preparing a release candidate.
[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 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.  */
714 static gpg_error_t
715 search_control_file (FILE *fp, const char *hexgrip, int *disabled)
716 {
717   int c, i;
718   char *p, line[256];
719   
720   assert (strlen (hexgrip) == 40 );
721
722   rewind (fp);
723   *disabled = 0;
724  next_line:
725   do
726     {
727       if (!fgets (line, DIM(line)-1, fp) )
728         {
729           if (feof (fp))
730             return gpg_error (GPG_ERR_EOF);
731           return gpg_error (gpg_err_code_from_errno (errno));
732         }
733       
734       if (!*line || line[strlen(line)-1] != '\n')
735         {
736           /* Eat until end of line */
737           while ( (c=getc (fp)) != EOF && c != '\n')
738             ;
739           return gpg_error (*line? GPG_ERR_LINE_TOO_LONG
740                                  : GPG_ERR_INCOMPLETE_LINE);
741         }
742       
743       /* Allow for empty lines and spaces */
744       for (p=line; spacep (p); p++)
745         ;
746     }
747   while (!*p || *p == '\n' || *p == '#');
748   
749   *disabled = 0;
750   if (*p == '!')
751     {
752       *disabled = 1;
753       for (p++; spacep (p); p++)
754         ;
755     }
756
757   for (i=0; hexdigitp (p) && i < 40; p++, i++)
758     if (hexgrip[i] != (*p >= 'a'? (*p & 0xdf): *p))
759       goto next_line;
760   if (i != 40 || !(spacep (p) || *p == '\n'))
761     {
762       log_error ("invalid formatted line in ssh control file\n");
763       return gpg_error (GPG_ERR_BAD_DATA);
764     }
765
766   /* Fixme: Get TTL and flags.  */
767
768   return 0; /* Okay:  found it.  */
769 }
770
771
772
773 /* Add an entry to the control file to mark the key with the keygrip
774    HEXGRIP as usable for SSH; i.e. it will be returned when ssh asks
775    for it.  This function is in general used to add a key received
776    through the ssh-add function.  We can assume that the user wants to
777    allow ssh using this key. */
778 static gpg_error_t
779 add_control_entry (ctrl_t ctrl, const char *hexgrip, int ttl)
780 {
781   gpg_error_t err;
782   FILE *fp;
783   int disabled;
784
785   (void)ctrl;
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   (void)request;
1788
1789   /* Prepare buffer stream.  */
1790
1791   key_directory = NULL;
1792   key_secret = NULL;
1793   key_public = NULL;
1794   key_type = NULL;
1795   key_path = NULL;
1796   key_counter = 0;
1797   buffer = NULL;
1798   dir = NULL;
1799   err = 0;
1800
1801   key_blobs = es_mopen (NULL, 0, 0, 1, NULL, NULL, "r+");
1802   if (! key_blobs)
1803     {
1804       err = gpg_error_from_syserror ();
1805       goto out;
1806     }
1807
1808   /* Open key directory.  */
1809   key_directory = make_filename (opt.homedir, GNUPG_PRIVATE_KEYS_DIR, NULL);
1810   if (! key_directory)
1811     {
1812       err = gpg_err_code_from_errno (errno);
1813       goto out;
1814     }
1815   key_directory_n = strlen (key_directory);
1816   
1817   key_path = xtrymalloc (key_directory_n + 46);
1818   if (! key_path)
1819     {
1820       err = gpg_err_code_from_errno (errno);
1821       goto out;
1822     }
1823
1824   sprintf (key_path, "%s/", key_directory);
1825   sprintf (key_path + key_directory_n + 41, ".key");
1826
1827   dir = opendir (key_directory);
1828   if (! dir)
1829     {
1830       err = gpg_err_code_from_errno (errno);
1831       goto out;
1832     }
1833
1834
1835
1836   /* First check whether a key is currently available in the card
1837      reader - this should be allowed even without being listed in
1838      sshcontrol. */
1839
1840   if (!card_key_available (ctrl, &key_public, &cardsn))
1841     {
1842       err = ssh_send_key_public (key_blobs, key_public, cardsn);
1843       gcry_sexp_release (key_public);
1844       key_public = NULL;
1845       xfree (cardsn);
1846       if (err)
1847         goto out;
1848       
1849       key_counter++;
1850     }
1851
1852
1853   /* Then look at all the registered an allowed keys. */
1854
1855
1856   /* Fixme: We should better iterate over the control file and check
1857      whether the key file is there.  This is better in resepct to
1858      performance if tehre are a lot of key sin our key storage. */
1859   /* FIXME: make sure that buffer gets deallocated properly.  */
1860   err = open_control_file (&ctrl_fp, 0);
1861   if (err)
1862     goto out;
1863
1864   while ( (dir_entry = readdir (dir)) )
1865     {
1866       if ((strlen (dir_entry->d_name) == 44)
1867           && (! strncmp (dir_entry->d_name + 40, ".key", 4)))
1868         {
1869           char hexgrip[41];
1870           int disabled;
1871
1872           /* We do only want to return keys listed in our control
1873              file. */
1874           strncpy (hexgrip, dir_entry->d_name, 40);
1875           hexgrip[40] = 0;
1876           if ( strlen (hexgrip) != 40 )
1877             continue;
1878           if (search_control_file (ctrl_fp, hexgrip, &disabled)
1879               || disabled)
1880             continue;
1881
1882           strncpy (key_path + key_directory_n + 1, dir_entry->d_name, 40);
1883
1884           /* Read file content.  */
1885           err = file_to_buffer (key_path, &buffer, &buffer_n);
1886           if (err)
1887             goto out;
1888               
1889           err = gcry_sexp_sscan (&key_secret, NULL, (char*)buffer, buffer_n);
1890           if (err)
1891             goto out;
1892
1893           xfree (buffer);
1894           buffer = NULL;
1895
1896           err = sexp_extract_identifier (key_secret, &key_type);
1897           if (err)
1898             goto out;
1899
1900           err = ssh_key_type_lookup (NULL, key_type, &spec);
1901           if (err)
1902             goto out;
1903
1904           xfree (key_type);
1905           key_type = NULL;
1906
1907           err = key_secret_to_public (&key_public, spec, key_secret);
1908           if (err)
1909             goto out;
1910
1911           gcry_sexp_release (key_secret);
1912           key_secret = NULL;
1913               
1914           err = ssh_send_key_public (key_blobs, key_public, NULL);
1915           if (err)
1916             goto out;
1917
1918           gcry_sexp_release (key_public);
1919           key_public = NULL;
1920
1921           key_counter++;
1922         }
1923     }
1924   
1925   ret = es_fseek (key_blobs, 0, SEEK_SET);
1926   if (ret)
1927     {
1928       err = gpg_error_from_syserror ();
1929       goto out;
1930     }
1931
1932  out:
1933
1934   /* Send response.  */
1935
1936   gcry_sexp_release (key_secret);
1937   gcry_sexp_release (key_public);
1938
1939   if (! err)
1940     {
1941       ret_err = stream_write_byte (response, SSH_RESPONSE_IDENTITIES_ANSWER);
1942       if (ret_err)
1943         goto leave;
1944       ret_err = stream_write_uint32 (response, key_counter);
1945       if (ret_err)
1946         goto leave;
1947       ret_err = stream_copy (response, key_blobs);
1948       if (ret_err)
1949         goto leave;
1950     }
1951   else
1952     {
1953       ret_err = stream_write_byte (response, SSH_RESPONSE_FAILURE);
1954       goto leave;
1955     };
1956
1957  leave:
1958
1959   if (key_blobs)
1960     es_fclose (key_blobs);
1961   if (dir)
1962     closedir (dir);
1963
1964   if (ctrl_fp)
1965     fclose (ctrl_fp);
1966
1967   xfree (key_directory);
1968   xfree (key_path);
1969   xfree (buffer);
1970   xfree (key_type);
1971
1972   return ret_err;
1973 }
1974
1975 /* This function hashes the data contained in DATA of size DATA_N
1976    according to the message digest algorithm specified by MD_ALGORITHM
1977    and writes the message digest to HASH, which needs to large enough
1978    for the digest.  */
1979 static gpg_error_t
1980 data_hash (unsigned char *data, size_t data_n,
1981            int md_algorithm, unsigned char *hash)
1982 {
1983   gcry_md_hash_buffer (md_algorithm, hash, data, data_n);
1984
1985   return 0;
1986 }
1987
1988 /* This function signs the data contained in CTRL, stores the created
1989    signature in newly allocated memory in SIG and it's size in SIG_N;
1990    SIG_ENCODER is the signature encoder to use.  */
1991 static gpg_error_t
1992 data_sign (ctrl_t ctrl, ssh_signature_encoder_t sig_encoder,
1993            unsigned char **sig, size_t *sig_n)
1994 {
1995   gpg_error_t err;
1996   gcry_sexp_t signature_sexp = NULL;
1997   estream_t stream = NULL;
1998   gcry_sexp_t valuelist = NULL;
1999   gcry_sexp_t sublist = NULL;
2000   gcry_mpi_t sig_value = NULL;
2001   unsigned char *sig_blob = NULL;
2002   size_t sig_blob_n = 0;
2003   char *identifier = NULL;
2004   const char *identifier_raw;
2005   size_t identifier_n;
2006   ssh_key_type_spec_t spec;
2007   int ret;
2008   unsigned int i;
2009   const char *elems;
2010   size_t elems_n;
2011   gcry_mpi_t *mpis = NULL;
2012
2013   *sig = NULL;
2014   *sig_n = 0;
2015
2016   ctrl->use_auth_call = 1;
2017   err = agent_pksign_do (ctrl,
2018                          _("Please enter the passphrase "
2019                            "for the ssh key%0A  %c"), &signature_sexp,
2020                          CACHE_MODE_SSH);
2021   ctrl->use_auth_call = 0;
2022   if (err)
2023     goto out;
2024
2025   valuelist = gcry_sexp_nth (signature_sexp, 1);
2026   if (! valuelist)
2027     {
2028       err = gpg_error (GPG_ERR_INV_SEXP);
2029       goto out;
2030     }
2031
2032   stream = es_mopen (NULL, 0, 0, 1, NULL, NULL, "r+");
2033   if (! stream)
2034     {
2035       err = gpg_error_from_syserror ();
2036       goto out;
2037     }
2038
2039   identifier_raw = gcry_sexp_nth_data (valuelist, 0, &identifier_n);
2040   if (! identifier_raw)
2041     {
2042       err = gpg_error (GPG_ERR_INV_SEXP);
2043       goto out;
2044     }
2045
2046   identifier = make_cstring (identifier_raw, identifier_n);
2047   if (! identifier)
2048     {
2049       err = gpg_error_from_syserror ();
2050       goto out;
2051     }
2052
2053   err = ssh_key_type_lookup (NULL, identifier, &spec);
2054   if (err)
2055     goto out;
2056
2057   err = stream_write_cstring (stream, spec.ssh_identifier);
2058   if (err)
2059     goto out;
2060
2061   elems = spec.elems_signature;
2062   elems_n = strlen (elems);
2063
2064   mpis = xtrycalloc (elems_n + 1, sizeof *mpis);
2065   if (!mpis)
2066     {
2067       err = gpg_error_from_syserror ();
2068       goto out;
2069     }
2070
2071   for (i = 0; i < elems_n; i++)
2072     {
2073       sublist = gcry_sexp_find_token (valuelist, spec.elems_signature + i, 1);
2074       if (! sublist)
2075         {
2076           err = gpg_error (GPG_ERR_INV_SEXP);
2077           break;
2078         }
2079
2080       sig_value = gcry_sexp_nth_mpi (sublist, 1, GCRYMPI_FMT_USG);
2081       if (! sig_value)
2082         {
2083           err = gpg_error (GPG_ERR_INTERNAL); /* FIXME?  */
2084           break;
2085         }
2086       gcry_sexp_release (sublist);
2087       sublist = NULL;
2088
2089       mpis[i] = sig_value;
2090     }
2091   if (err)
2092     goto out;
2093
2094   err = (*sig_encoder) (stream, mpis);
2095   if (err)
2096     goto out;
2097
2098   sig_blob_n = es_ftell (stream);
2099   if (sig_blob_n == -1)
2100     {
2101       err = gpg_error_from_syserror ();
2102       goto out;
2103     }
2104
2105   sig_blob = xtrymalloc (sig_blob_n);
2106   if (! sig_blob)
2107     {
2108       err = gpg_error_from_syserror ();
2109       goto out;
2110     }
2111
2112   ret = es_fseek (stream, 0, SEEK_SET);
2113   if (ret)
2114     {
2115       err = gpg_error_from_syserror ();
2116       goto out;
2117     }    
2118
2119   err = stream_read_data (stream, sig_blob, sig_blob_n);
2120   if (err)
2121     goto out;
2122   
2123   *sig = sig_blob;
2124   *sig_n = sig_blob_n;
2125   
2126  out:
2127
2128   if (err)
2129     xfree (sig_blob);
2130
2131   if (stream)
2132     es_fclose (stream);
2133   gcry_sexp_release (valuelist);
2134   gcry_sexp_release (signature_sexp);
2135   gcry_sexp_release (sublist);
2136   mpint_list_free (mpis);
2137   xfree (identifier);
2138
2139   return err;
2140 }
2141
2142 /* Handler for the "sign_request" command.  */
2143 static gpg_error_t
2144 ssh_handler_sign_request (ctrl_t ctrl, estream_t request, estream_t response)
2145 {
2146   gcry_sexp_t key;
2147   ssh_key_type_spec_t spec;
2148   unsigned char hash[MAX_DIGEST_LEN];
2149   unsigned int hash_n;
2150   unsigned char key_grip[20];
2151   unsigned char *key_blob;
2152   u32 key_blob_size;
2153   unsigned char *data;
2154   unsigned char *sig;
2155   size_t sig_n;
2156   u32 data_size;
2157   u32 flags;
2158   gpg_error_t err;
2159   gpg_error_t ret_err;
2160
2161   key_blob = NULL;
2162   data = NULL;
2163   sig = NULL;
2164   key = NULL;
2165
2166   /* Receive key.  */
2167   
2168   err = stream_read_string (request, 0, &key_blob, &key_blob_size);
2169   if (err)
2170     goto out;
2171
2172   err = ssh_read_key_public_from_blob (key_blob, key_blob_size, &key, &spec);
2173   if (err)
2174     goto out;
2175
2176   /* Receive data to sign.  */
2177   err = stream_read_string (request, 0, &data, &data_size);
2178   if (err)
2179     goto out;
2180
2181   /* FIXME?  */
2182   err = stream_read_uint32 (request, &flags);
2183   if (err)
2184     goto out;
2185
2186   /* Hash data.  */
2187   hash_n = gcry_md_get_algo_dlen (GCRY_MD_SHA1);
2188   if (! hash_n)
2189     {
2190       err = gpg_error (GPG_ERR_INTERNAL);
2191       goto out;
2192     }
2193   err = data_hash (data, data_size, GCRY_MD_SHA1, hash);
2194   if (err)
2195     goto out;
2196
2197   /* Calculate key grip.  */
2198   err = ssh_key_grip (key, key_grip);
2199   if (err)
2200     goto out;
2201
2202   /* Sign data.  */
2203
2204   ctrl->digest.algo = GCRY_MD_SHA1;
2205   memcpy (ctrl->digest.value, hash, hash_n);
2206   ctrl->digest.valuelen = hash_n;
2207   ctrl->digest.raw_value = ! (spec.flags & SPEC_FLAG_USE_PKCS1V2);
2208   ctrl->have_keygrip = 1;
2209   memcpy (ctrl->keygrip, key_grip, 20);
2210
2211   err = data_sign (ctrl, spec.signature_encoder, &sig, &sig_n);
2212   
2213  out:
2214
2215   /* Done.  */
2216
2217   if (! err)
2218     {
2219       ret_err = stream_write_byte (response, SSH_RESPONSE_SIGN_RESPONSE);
2220       if (ret_err)
2221         goto leave;
2222       ret_err = stream_write_string (response, sig, sig_n);
2223       if (ret_err)
2224         goto leave;
2225     }
2226   else
2227     {
2228       ret_err = stream_write_byte (response, SSH_RESPONSE_FAILURE);
2229       if (ret_err)
2230         goto leave;
2231     }
2232   
2233  leave:
2234
2235   gcry_sexp_release (key);
2236   xfree (key_blob);
2237   xfree (data);
2238   xfree (sig);
2239
2240   return ret_err;
2241 }
2242
2243 /* This function extracts the comment contained in the key
2244    S-Expression KEY and stores a copy in COMMENT.  Returns usual error
2245    code.  */
2246 static gpg_error_t
2247 ssh_key_extract_comment (gcry_sexp_t key, char **comment)
2248 {
2249   gcry_sexp_t comment_list;
2250   char *comment_new;
2251   const char *data;
2252   size_t data_n;
2253   gpg_error_t err;
2254
2255   comment_list = gcry_sexp_find_token (key, "comment", 0);
2256   if (! comment_list)
2257     {
2258       err = gpg_error (GPG_ERR_INV_SEXP);
2259       goto out;
2260     }
2261   
2262   data = gcry_sexp_nth_data (comment_list, 1, &data_n);
2263   if (! data)
2264     {
2265       err = gpg_error (GPG_ERR_INV_SEXP);
2266       goto out;
2267     }
2268
2269   comment_new = make_cstring (data, data_n);
2270   if (! comment_new)
2271     {
2272       err = gpg_error_from_syserror ();
2273       goto out;
2274     }
2275
2276   *comment = comment_new;
2277   err = 0;
2278
2279  out:
2280
2281   gcry_sexp_release (comment_list);
2282
2283   return err;
2284 }
2285
2286 /* This function converts the key contained in the S-Expression KEY
2287    into a buffer, which is protected by the passphrase PASSPHRASE.
2288    Returns usual error code.  */
2289 static gpg_error_t
2290 ssh_key_to_protected_buffer (gcry_sexp_t key, const char *passphrase,
2291                              unsigned char **buffer, size_t *buffer_n)
2292 {
2293   unsigned char *buffer_new;
2294   unsigned int buffer_new_n;
2295   gpg_error_t err;
2296
2297   err = 0;
2298   buffer_new_n = gcry_sexp_sprint (key, GCRYSEXP_FMT_CANON, NULL, 0);
2299   buffer_new = xtrymalloc_secure (buffer_new_n);
2300   if (! buffer_new)
2301     {
2302       err = gpg_error_from_syserror ();
2303       goto out;
2304     }
2305   
2306   gcry_sexp_sprint (key, GCRYSEXP_FMT_CANON, buffer_new, buffer_new_n);
2307   /* FIXME: guarantee?  */
2308
2309   err = agent_protect (buffer_new, passphrase, buffer, buffer_n);
2310
2311  out:
2312
2313   xfree (buffer_new);
2314
2315   return err;
2316 }
2317
2318
2319
2320 /* Callback function to compare the first entered PIN with the one
2321    currently being entered. */
2322 static int
2323 reenter_compare_cb (struct pin_entry_info_s *pi)
2324 {
2325   const char *pin1 = pi->check_cb_arg;
2326
2327   if (!strcmp (pin1, pi->pin))
2328     return 0; /* okay */
2329   return -1;
2330 }
2331
2332 /* Store the ssh KEY into our local key storage and protect it after
2333    asking for a passphrase.  Cache that passphrase.  TTL is the
2334    maximum caching time for that key.  If the key already exists in
2335    our key storage, don't do anything.  When entering a new key also
2336    add an entry to the sshcontrol file.  */
2337 static gpg_error_t
2338 ssh_identity_register (ctrl_t ctrl, gcry_sexp_t key, int ttl)
2339 {
2340   gpg_error_t err;
2341   unsigned char key_grip_raw[20];
2342   char key_grip[41];
2343   unsigned char *buffer = NULL;
2344   size_t buffer_n;
2345   char *description = NULL;
2346   const char *description2 = _("Please re-enter this passphrase");
2347   char *comment = NULL;
2348   const char *initial_errtext = NULL;
2349   unsigned int i;
2350   struct pin_entry_info_s *pi = NULL, *pi2;
2351
2352   err = ssh_key_grip (key, key_grip_raw);
2353   if (err)
2354     goto out;
2355
2356   /* Check whether the key is already in our key storage.  Don't do
2357      anything then.  */
2358   if ( !agent_key_available (key_grip_raw) )
2359     goto out; /* Yes, key is available.  */
2360
2361   
2362   err = ssh_key_extract_comment (key, &comment);
2363   if (err)
2364     goto out;
2365
2366   if ( asprintf (&description,
2367                  _("Please enter a passphrase to protect"
2368                    " the received secret key%%0A"
2369                    "   %s%%0A"
2370                    "within gpg-agent's key storage"),
2371                  comment ? comment : "?") < 0)
2372     {
2373       err = gpg_error_from_syserror ();
2374       goto out;
2375     }
2376
2377
2378   pi = gcry_calloc_secure (2, sizeof (*pi) + 100 + 1);
2379   if (!pi)
2380     {
2381       err = gpg_error_from_syserror ();
2382       goto out;
2383     }
2384   pi2 = pi + (sizeof *pi + 100 + 1);
2385   pi->max_length = 100;
2386   pi->max_tries = 1;
2387   pi2->max_length = 100;
2388   pi2->max_tries = 1;
2389   pi2->check_cb = reenter_compare_cb;
2390   pi2->check_cb_arg = pi->pin;
2391
2392  next_try:
2393   err = agent_askpin (ctrl, description, NULL, initial_errtext, pi);
2394   initial_errtext = NULL;
2395   if (err)
2396     goto out;
2397
2398   /* Unless the passphrase is empty, ask to confirm it.  */
2399   if (pi->pin && *pi->pin)
2400     {
2401       err = agent_askpin (ctrl, description2, NULL, NULL, pi2);
2402       if (err == -1)
2403         { /* The re-entered one did not match and the user did not
2404              hit cancel. */
2405           initial_errtext = _("does not match - try again");
2406           goto next_try;
2407         }
2408     }
2409
2410   err = ssh_key_to_protected_buffer (key, pi->pin, &buffer, &buffer_n);
2411   if (err)
2412     goto out;
2413
2414   /* Store this key to our key storage.  */
2415   err = agent_write_private_key (key_grip_raw, buffer, buffer_n, 0);
2416   if (err)
2417     goto out;
2418
2419   /* Cache this passphrase. */
2420   for (i = 0; i < 20; i++)
2421     sprintf (key_grip + 2 * i, "%02X", key_grip_raw[i]);
2422
2423   err = agent_put_cache (key_grip, CACHE_MODE_SSH, pi->pin, ttl);
2424   if (err)
2425     goto out;
2426
2427   /* And add an entry to the sshcontrol file.  */
2428   err = add_control_entry (ctrl, key_grip, ttl);
2429
2430
2431  out:
2432   if (pi && pi->max_length)
2433     wipememory (pi->pin, pi->max_length);
2434   xfree (pi);
2435   xfree (buffer);
2436   xfree (comment);
2437   xfree (description); 
2438
2439   return err;
2440 }
2441
2442
2443 /* This function removes the key contained in the S-Expression KEY
2444    from the local key storage, in case it exists there.  Returns usual
2445    error code.  FIXME: this function is a stub.  */
2446 static gpg_error_t
2447 ssh_identity_drop (gcry_sexp_t key)
2448 {
2449   unsigned char key_grip[21] = { 0 };
2450   gpg_error_t err;
2451
2452   err = ssh_key_grip (key, key_grip);
2453   if (err)
2454     goto out;
2455
2456   key_grip[sizeof (key_grip) - 1] = 0;
2457
2458   /* FIXME: What to do here - forgetting the passphrase or deleting
2459      the key from key cache?  */
2460
2461  out:
2462
2463   return err;
2464 }
2465
2466 /* Handler for the "add_identity" command.  */
2467 static gpg_error_t
2468 ssh_handler_add_identity (ctrl_t ctrl, estream_t request, estream_t response)
2469 {
2470   gpg_error_t ret_err;
2471   gpg_error_t err;
2472   gcry_sexp_t key;
2473   unsigned char b;
2474   int confirm;
2475   int ttl;
2476   
2477   confirm = 0;
2478   key = NULL;
2479   ttl = 0;
2480
2481   /* FIXME?  */
2482   err = ssh_receive_key (request, &key, 1, 1, NULL);
2483   if (err)
2484     goto out;
2485
2486   while (1)
2487     {
2488       err = stream_read_byte (request, &b);
2489       if (gpg_err_code (err) == GPG_ERR_EOF)
2490         {
2491           err = 0;
2492           break;
2493         }
2494
2495       switch (b)
2496         {
2497         case SSH_OPT_CONSTRAIN_LIFETIME:
2498           {
2499             u32 n = 0;
2500
2501             err = stream_read_uint32 (request, &n);
2502             if (! err)
2503               ttl = n;
2504             break;
2505           }
2506
2507         case SSH_OPT_CONSTRAIN_CONFIRM:
2508           {
2509             confirm = 1;
2510             break;
2511           }
2512
2513         default:
2514           /* FIXME: log/bad?  */
2515           break;
2516         }
2517     }
2518   if (err)
2519     goto out;
2520
2521   /* FIXME: are constraints used correctly?  */
2522
2523   err = ssh_identity_register (ctrl, key, ttl);
2524
2525  out:
2526
2527   gcry_sexp_release (key);
2528
2529   if (! err)
2530     ret_err = stream_write_byte (response, SSH_RESPONSE_SUCCESS);
2531   else
2532     ret_err = stream_write_byte (response, SSH_RESPONSE_FAILURE);
2533
2534   return ret_err;
2535 }
2536
2537 /* Handler for the "remove_identity" command.  */
2538 static gpg_error_t
2539 ssh_handler_remove_identity (ctrl_t ctrl,
2540                              estream_t request, estream_t response)
2541 {
2542   unsigned char *key_blob;
2543   u32 key_blob_size;
2544   gcry_sexp_t key;
2545   gpg_error_t ret_err;
2546   gpg_error_t err;
2547
2548   (void)ctrl;
2549
2550   /* Receive key.  */
2551
2552   key_blob = NULL;
2553   key = NULL;
2554   
2555   err = stream_read_string (request, 0, &key_blob, &key_blob_size);
2556   if (err)
2557     goto out;
2558
2559   err = ssh_read_key_public_from_blob (key_blob, key_blob_size, &key, NULL);
2560   if (err)
2561     goto out;
2562   
2563   err = ssh_identity_drop (key);
2564
2565  out:
2566
2567   xfree (key_blob);
2568   gcry_sexp_release (key);
2569
2570   if (! err)
2571     ret_err = stream_write_byte (response, SSH_RESPONSE_SUCCESS);
2572   else
2573     ret_err = stream_write_byte (response, SSH_RESPONSE_FAILURE);
2574
2575   return ret_err;
2576 }
2577
2578 /* FIXME: stub function.  Actually useful?  */
2579 static gpg_error_t
2580 ssh_identities_remove_all (void)
2581 {
2582   gpg_error_t err;
2583
2584   err = 0;
2585
2586   /* FIXME: shall we remove _all_ cache entries or only those
2587      registered through the ssh emulation?  */
2588   
2589   return err;
2590 }
2591
2592 /* Handler for the "remove_all_identities" command.  */
2593 static gpg_error_t
2594 ssh_handler_remove_all_identities (ctrl_t ctrl,
2595                                    estream_t request, estream_t response)
2596 {
2597   gpg_error_t ret_err;
2598   gpg_error_t err;
2599
2600   (void)ctrl;
2601   (void)request;
2602   
2603   err = ssh_identities_remove_all ();
2604
2605   if (! err)
2606     ret_err = stream_write_byte (response, SSH_RESPONSE_SUCCESS);
2607   else
2608     ret_err = stream_write_byte (response, SSH_RESPONSE_FAILURE);
2609
2610   return ret_err;
2611 }
2612
2613 /* Lock agent?  FIXME: stub function.  */
2614 static gpg_error_t
2615 ssh_lock (void)
2616 {
2617   gpg_error_t err;
2618
2619   /* FIXME */
2620   log_error ("ssh-agent's lock command is not implemented\n");
2621   err = 0;
2622
2623   return err;
2624 }
2625
2626 /* Unock agent?  FIXME: stub function.  */
2627 static gpg_error_t
2628 ssh_unlock (void)
2629 {
2630   gpg_error_t err;
2631
2632   log_error ("ssh-agent's unlock command is not implemented\n");
2633   err = 0;
2634
2635   return err;
2636 }
2637
2638 /* Handler for the "lock" command.  */
2639 static gpg_error_t
2640 ssh_handler_lock (ctrl_t ctrl, estream_t request, estream_t response)
2641 {
2642   gpg_error_t ret_err;
2643   gpg_error_t err;
2644
2645   (void)ctrl;
2646   (void)request;
2647   
2648   err = ssh_lock ();
2649
2650   if (! err)
2651     ret_err = stream_write_byte (response, SSH_RESPONSE_SUCCESS);
2652   else
2653     ret_err = stream_write_byte (response, SSH_RESPONSE_FAILURE);
2654
2655   return ret_err;
2656 }
2657
2658 /* Handler for the "unlock" command.  */
2659 static gpg_error_t
2660 ssh_handler_unlock (ctrl_t ctrl, estream_t request, estream_t response)
2661 {
2662   gpg_error_t ret_err;
2663   gpg_error_t err;
2664   
2665   (void)ctrl;
2666   (void)request;
2667
2668   err = ssh_unlock ();
2669
2670   if (! err)
2671     ret_err = stream_write_byte (response, SSH_RESPONSE_SUCCESS);
2672   else
2673     ret_err = stream_write_byte (response, SSH_RESPONSE_FAILURE);
2674
2675   return ret_err;
2676 }
2677
2678 \f
2679
2680 /* Return the request specification for the request identified by TYPE
2681    or NULL in case the requested request specification could not be
2682    found.  */
2683 static ssh_request_spec_t *
2684 request_spec_lookup (int type)
2685 {
2686   ssh_request_spec_t *spec;
2687   unsigned int i;
2688
2689   for (i = 0; i < DIM (request_specs); i++)
2690     if (request_specs[i].type == type)
2691       break;
2692   if (i == DIM (request_specs))
2693     {
2694       if (opt.verbose)
2695         log_info ("ssh request %u is not supported\n", type);
2696       spec = NULL;
2697     }
2698   else
2699     spec = request_specs + i;
2700
2701   return spec;
2702 }
2703
2704 /* Process a single request.  The request is read from and the
2705    response is written to STREAM_SOCK.  Uses CTRL as context.  Returns
2706    zero in case of success, non zero in case of failure.  */
2707 static int
2708 ssh_request_process (ctrl_t ctrl, estream_t stream_sock)
2709 {
2710   ssh_request_spec_t *spec;
2711   estream_t response;
2712   estream_t request;
2713   unsigned char request_type;
2714   gpg_error_t err;
2715   int send_err;
2716   int ret;
2717   unsigned char *request_data;
2718   u32 request_data_size;
2719   u32 response_size;
2720
2721   request_data = NULL;
2722   response = NULL;
2723   request = NULL;
2724   send_err = 0;
2725
2726   /* Create memory streams for request/response data.  The entire
2727      request will be stored in secure memory, since it might contain
2728      secret key material.  The response does not have to be stored in
2729      secure memory, since we never give out secret keys. 
2730
2731      Note: we only have little secure memory, but there is NO
2732      possibility of DoS here; only trusted clients are allowed to
2733      connect to the agent.  What could happen is that the agent
2734      returns out-of-secure-memory errors on requests in case the
2735      agent's owner floods his own agent with many large messages.
2736      -moritz */
2737
2738   /* Retrieve request.  */
2739   err = stream_read_string (stream_sock, 1, &request_data, &request_data_size);
2740   if (err)
2741     goto out;
2742
2743   if (opt.verbose > 1)
2744     log_info ("received ssh request of length %u\n",
2745               (unsigned int)request_data_size);
2746
2747   if (! request_data_size)
2748     {
2749       send_err = 1;
2750       goto out;
2751       /* Broken request; FIXME.  */
2752     }
2753
2754   request_type = request_data[0];
2755   spec = request_spec_lookup (request_type);
2756   if (! spec)
2757     {
2758       send_err = 1;
2759       goto out;
2760       /* Unknown request; FIXME.  */
2761     }
2762
2763   if (spec->secret_input)
2764     request = es_mopen (NULL, 0, 0, 1, realloc_secure, gcry_free, "r+");
2765   else
2766     request = es_mopen (NULL, 0, 0, 1, gcry_realloc, gcry_free, "r+");
2767   if (! request)
2768     {
2769       err = gpg_error_from_syserror ();
2770       goto out;
2771     }
2772   ret = es_setvbuf (request, NULL, _IONBF, 0);
2773   if (ret)
2774     {
2775       err = gpg_error_from_syserror ();
2776       goto out;
2777     }
2778   err = stream_write_data (request, request_data + 1, request_data_size - 1);
2779   if (err)
2780     goto out;
2781   es_rewind (request);
2782
2783   response = es_mopen (NULL, 0, 0, 1, NULL, NULL, "r+");
2784   if (! response)
2785     {
2786       err = gpg_error_from_syserror ();
2787       goto out;
2788     }
2789
2790   if (opt.verbose)
2791     log_info ("ssh request handler for %s (%u) started\n",
2792                spec->identifier, spec->type);
2793
2794   err = (*spec->handler) (ctrl, request, response);
2795
2796   if (opt.verbose)
2797     {
2798       if (err)
2799         log_info ("ssh request handler for %s (%u) failed: %s\n",
2800                   spec->identifier, spec->type, gpg_strerror (err));
2801       else
2802         log_info ("ssh request handler for %s (%u) ready\n",
2803                   spec->identifier, spec->type);
2804     }
2805
2806   if (err)
2807     {
2808       send_err = 1;
2809       goto out;
2810     }
2811
2812   response_size = es_ftell (response);
2813   if (opt.verbose > 1)
2814     log_info ("sending ssh response of length %u\n",
2815               (unsigned int)response_size);
2816
2817   err = es_fseek (response, 0, SEEK_SET);
2818   if (err)
2819     {
2820       send_err = 1;
2821       goto out;
2822     }
2823
2824   err = stream_write_uint32 (stream_sock, response_size);
2825   if (err)
2826     {
2827       send_err = 1;
2828       goto out;
2829     }
2830
2831   err = stream_copy (stream_sock, response);
2832   if (err)
2833     goto out;
2834
2835   err = es_fflush (stream_sock);
2836   if (err)
2837     goto out;
2838
2839  out:
2840
2841   if (err && es_feof (stream_sock))
2842     log_error ("error occured while processing request: %s\n",
2843                gpg_strerror (err));
2844
2845   if (send_err)
2846     {
2847       if (opt.verbose > 1)
2848         log_info ("sending ssh error response\n");
2849       err = stream_write_uint32 (stream_sock, 1);
2850       if (err)
2851         goto leave;
2852       err = stream_write_byte (stream_sock, SSH_RESPONSE_FAILURE);
2853       if (err)
2854         goto leave;
2855     }
2856
2857  leave:
2858
2859   if (request)
2860     es_fclose (request);
2861   if (response)
2862     es_fclose (response);
2863   xfree (request_data);         /* FIXME?  */
2864
2865   return !!err;
2866 }
2867
2868 /* Start serving client on SOCK_CLIENT.  */
2869 void
2870 start_command_handler_ssh (ctrl_t ctrl, gnupg_fd_t sock_client)
2871 {
2872   estream_t stream_sock;
2873   gpg_error_t err;
2874   int ret;
2875
2876   /* Because the ssh protocol does not send us information about the
2877      the current TTY setting, we resort here to use those from startup
2878      or those explictly set.  */
2879   if (!ctrl->display && opt.startup_display)
2880     ctrl->display = strdup (opt.startup_display);
2881   if (!ctrl->ttyname && opt.startup_ttyname)
2882     ctrl->ttyname = strdup (opt.startup_ttyname);
2883   if (!ctrl->ttytype && opt.startup_ttytype)
2884     ctrl->ttytype = strdup (opt.startup_ttytype);
2885   if (!ctrl->lc_ctype && opt.startup_lc_ctype)
2886     ctrl->lc_ctype = strdup (opt.startup_lc_ctype);
2887   if (!ctrl->lc_messages && opt.startup_lc_messages)
2888     ctrl->lc_messages = strdup (opt.startup_lc_messages);
2889   if (!ctrl->xauthority && opt.startup_xauthority)
2890     ctrl->xauthority = strdup (opt.startup_xauthority);
2891   if (!ctrl->pinentry_user_data && opt.startup_pinentry_user_data)
2892     ctrl->pinentry_user_data = strdup (opt.startup_pinentry_user_data);
2893
2894
2895   /* Create stream from socket.  */
2896   stream_sock = es_fdopen (FD2INT(sock_client), "r+");
2897   if (!stream_sock)
2898     {
2899       err = gpg_error_from_syserror ();
2900       log_error (_("failed to create stream from socket: %s\n"),
2901                  gpg_strerror (err));
2902       goto out;
2903     }
2904   /* We have to disable the estream buffering, because the estream
2905      core doesn't know about secure memory.  */
2906   ret = es_setvbuf (stream_sock, NULL, _IONBF, 0);
2907   if (ret)
2908     {
2909       err = gpg_error_from_syserror ();
2910       log_error ("failed to disable buffering "
2911                  "on socket stream: %s\n", gpg_strerror (err));
2912       goto out;
2913     }
2914
2915   /* Main processing loop. */
2916   while ( !ssh_request_process (ctrl, stream_sock) )
2917     {
2918       /* Check wether we have reached EOF before trying to read
2919          another request.  */
2920       int c;
2921
2922       c = es_fgetc (stream_sock);
2923       if (c == EOF)
2924         break;
2925       es_ungetc (c, stream_sock);
2926     }
2927
2928   /* Reset the SCD in case it has been used. */
2929   agent_reset_scd (ctrl);
2930
2931
2932  out:
2933   if (stream_sock)
2934     es_fclose (stream_sock);
2935 }