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