2005-03-02 Moritz Schulte <moritz@g10code.com>
[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, 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);
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 = make_cstring (data, data_n);
1180   if (! comment_new)
1181     {
1182       err = gpg_error_from_errno (errno);
1183       goto out;
1184     }
1185
1186   if (secret)
1187     *secret = is_secret;
1188   *mpis = mpis_new;
1189   *comment = comment_new;
1190
1191  out:
1192
1193   gcry_sexp_release (value_list);
1194   gcry_sexp_release (value_pair);
1195   gcry_sexp_release (comment_list);
1196   
1197   if (err)
1198     {
1199       xfree (comment_new);
1200       mpint_list_free (mpis_new);
1201     }
1202
1203   return err;
1204 }
1205
1206 /* Extract the car from SEXP, and create a newly created C-string 
1207    which is to be stored in IDENTIFIER.  */
1208 static gpg_error_t
1209 sexp_extract_identifier (gcry_sexp_t sexp, char **identifier)
1210 {
1211   char *identifier_new;
1212   gcry_sexp_t sublist;
1213   const char *data;
1214   size_t data_n;
1215   gpg_error_t err;
1216
1217   identifier_new = NULL;
1218   err = 0;
1219   
1220   sublist = gcry_sexp_nth (sexp, 1);
1221   if (! sublist)
1222     {
1223       err = gpg_error (GPG_ERR_INV_SEXP);
1224       goto out;
1225     }
1226
1227   data = gcry_sexp_nth_data (sublist, 0, &data_n);
1228   if (! data)
1229     {
1230       err = gpg_error (GPG_ERR_INV_SEXP);
1231       goto out;
1232     }
1233
1234   identifier_new = make_cstring (data, data_n);
1235   if (! identifier_new)
1236     {
1237       err = gpg_err_code_from_errno (errno);
1238       goto out;
1239     }
1240
1241   *identifier = identifier_new;
1242
1243  out:
1244
1245   gcry_sexp_release (sublist);
1246
1247   return err;
1248 }
1249
1250 \f
1251
1252 /*
1253
1254   Key I/O.
1255
1256 */
1257
1258 /* Search for a key specification entry.  If SSH_NAME is not NULL,
1259    search for an entry whose "ssh_name" is equal to SSH_NAME;
1260    otherwise, search for an entry whose "name" is equal to NAME.
1261    Store found entry in SPEC on success, return error otherwise.  */
1262 static gpg_error_t
1263 ssh_key_type_lookup (const char *ssh_name, const char *name,
1264                      ssh_key_type_spec_t *spec)
1265 {
1266   gpg_error_t err;
1267   unsigned int i;
1268
1269   for (i = 0; i < DIM (ssh_key_types); i++)
1270     if ((ssh_name && (! strcmp (ssh_name, ssh_key_types[i].ssh_identifier)))
1271         || (name && (! strcmp (name, ssh_key_types[i].identifier))))
1272       break;
1273   
1274   if (i == DIM (ssh_key_types))
1275     err = gpg_error (GPG_ERR_NOT_FOUND);
1276   else
1277     {
1278       *spec = ssh_key_types[i];
1279       err = 0;
1280     }
1281
1282   return err;
1283 }
1284
1285 /* Receive a key from STREAM, according to the key specification given
1286    as KEY_SPEC.  Depending on SECRET, receive a secret or a public
1287    key.  If READ_COMMENT is true, receive a comment string as well.
1288    Constructs a new S-Expression from received data and stores it in
1289    KEY_NEW.  Returns zero on success or an error code.  */
1290 static gpg_error_t
1291 ssh_receive_key (estream_t stream, gcry_sexp_t *key_new, int secret,
1292                  int read_comment, ssh_key_type_spec_t *key_spec)
1293 {
1294   gpg_error_t err;
1295   char *key_type;
1296   char *comment;
1297   gcry_sexp_t key;
1298   ssh_key_type_spec_t spec;
1299   gcry_mpi_t *mpi_list;
1300   const char *elems;
1301
1302   mpi_list = NULL;
1303   key_type = NULL;
1304   comment = "";
1305   key = NULL;
1306         
1307   err = stream_read_cstring (stream, &key_type);
1308   if (err)
1309     goto out;
1310
1311   err = ssh_key_type_lookup (key_type, NULL, &spec);
1312   if (err)
1313     goto out;
1314
1315   err = ssh_receive_mpint_list (stream, secret, spec, &mpi_list);
1316   if (err)
1317     goto out;
1318
1319   if (read_comment)
1320     {
1321       err = stream_read_cstring (stream, &comment);
1322       if (err)
1323         goto out;
1324     }
1325
1326   if (secret)
1327     elems = spec.elems_key_secret;
1328   else
1329     elems = spec.elems_key_public;
1330
1331   if (spec.key_modifier)
1332     {
1333       err = (*spec.key_modifier) (elems, mpi_list);
1334       if (err)
1335         goto out;
1336     }
1337
1338   err = sexp_key_construct (&key, spec, secret, mpi_list, comment);
1339   if (err)
1340     goto out;
1341
1342   if (key_spec)
1343     *key_spec = spec;
1344   *key_new = key;
1345   
1346  out:
1347
1348   mpint_list_free (mpi_list);
1349   xfree (key_type);
1350   if (read_comment)
1351     xfree (comment);
1352
1353   return err;
1354 }
1355
1356 /* Converts a key of type TYPE, whose key material is given in MPIS,
1357    into a newly created binary blob, which is to be stored in
1358    BLOB/BLOB_SIZE.  Returns zero on success or an error code.  */
1359 static gpg_error_t
1360 ssh_convert_key_to_blob (unsigned char **blob, size_t *blob_size,
1361                          const char *type, gcry_mpi_t *mpis)
1362 {
1363   unsigned char *blob_new;
1364   long int blob_size_new;
1365   estream_t stream;
1366   gpg_error_t err;
1367   unsigned int i;
1368
1369   blob_new = NULL;
1370   stream = NULL;
1371   err = 0;
1372
1373   stream = es_mopen (NULL, 0, 0, 1, NULL, NULL, "r+");
1374   if (! stream)
1375     {
1376       err = gpg_error_from_errno (errno);
1377       goto out;
1378     }
1379
1380   err = stream_write_cstring (stream, type);
1381   if (err)
1382     goto out;
1383
1384   for (i = 0; mpis[i] && (! err); i++)
1385     err = stream_write_mpi (stream, mpis[i]);
1386   if (err)
1387     goto out;
1388
1389   blob_size_new = es_ftell (stream);
1390   if (blob_size_new == -1)
1391     {
1392       err = gpg_error_from_errno (errno);
1393       goto out;
1394     }
1395   
1396   err = es_fseek (stream, 0, SEEK_SET);
1397   if (err)
1398     goto out;
1399
1400   blob_new = xtrymalloc (blob_size_new);
1401   if (! blob_new)
1402     {
1403       err = gpg_error_from_errno (errno);
1404       goto out;
1405     }
1406
1407   err = stream_read_data (stream, blob_new, blob_size_new);
1408   if (err)
1409     goto out;
1410
1411   *blob = blob_new;
1412   *blob_size = blob_size_new;
1413
1414  out:
1415
1416   if (stream)
1417     es_fclose (stream);
1418   if (err)
1419     xfree (blob_new);
1420
1421   return err;
1422 }
1423                               
1424
1425 /* Write the public key KEY_PUBLIC to STREAM in SSH key format.  If
1426    OVERRIDE_COMMENT is not NULL, it will be used instead of the
1427    comment stored in the key.  */
1428 static gpg_error_t
1429 ssh_send_key_public (estream_t stream, gcry_sexp_t key_public,
1430                      const char *override_comment)
1431 {
1432   ssh_key_type_spec_t spec;
1433   gcry_mpi_t *mpi_list;
1434   char *key_type;
1435   char *comment;
1436   unsigned char *blob;
1437   size_t blob_n;
1438   gpg_error_t err;
1439
1440   key_type = NULL;
1441   mpi_list = NULL;
1442   comment = NULL;
1443   blob = NULL;
1444
1445   err = sexp_extract_identifier (key_public, &key_type);
1446   if (err)
1447     goto out;
1448
1449   err = ssh_key_type_lookup (NULL, key_type, &spec);
1450   if (err)
1451     goto out;
1452
1453   err = sexp_key_extract (key_public, spec, NULL, &mpi_list, &comment);
1454   if (err)
1455     goto out;
1456
1457   err = ssh_convert_key_to_blob (&blob, &blob_n,
1458                                  spec.ssh_identifier, mpi_list);
1459   if (err)
1460     goto out;
1461   
1462   err = stream_write_string (stream, blob, blob_n);
1463   if (err)
1464     goto out;
1465
1466   err = stream_write_cstring (stream,
1467                               override_comment? override_comment : comment);
1468   
1469  out:
1470
1471   mpint_list_free (mpi_list);
1472   xfree (key_type);
1473   xfree (comment);
1474   xfree (blob);
1475
1476   return err;
1477 }
1478
1479 /* Read a public key out of BLOB/BLOB_SIZE according to the key
1480    specification given as KEY_SPEC, storing the new key in KEY_PUBLIC.
1481    Returns zero on success or an error code.  */
1482 static gpg_error_t
1483 ssh_read_key_public_from_blob (unsigned char *blob, size_t blob_size,
1484                                gcry_sexp_t *key_public,
1485                                ssh_key_type_spec_t *key_spec)
1486 {
1487   estream_t blob_stream;
1488   gpg_error_t err;
1489
1490   err = 0;
1491   
1492   blob_stream = es_mopen (NULL, 0, 0, 1, NULL, NULL, "r+");
1493   if (! blob_stream)
1494     {
1495       err = gpg_error_from_errno (errno);
1496       goto out;
1497     }
1498
1499   err = stream_write_data (blob_stream, blob, blob_size);
1500   if (err)
1501     goto out;
1502
1503   err = es_fseek (blob_stream, 0, SEEK_SET);
1504   if (err)
1505     goto out;
1506
1507   err = ssh_receive_key (blob_stream, key_public, 0, 0, key_spec);
1508
1509  out:
1510
1511   if (blob_stream)
1512     es_fclose (blob_stream);
1513
1514   return err;
1515 }
1516
1517 \f
1518
1519 /* Converts the secret key KEY_SECRET into a public key, storing it in
1520    KEY_PUBLIC.  SPEC is the according key specification.  Returns zero
1521    on success or an error code.  */
1522 static gpg_error_t
1523 key_secret_to_public (gcry_sexp_t *key_public,
1524                       ssh_key_type_spec_t spec, gcry_sexp_t key_secret)
1525 {
1526   char *comment;
1527   gcry_mpi_t *mpis;
1528   gpg_error_t err;
1529   int is_secret;
1530
1531   comment = NULL;
1532   mpis = NULL;
1533
1534   err = sexp_key_extract (key_secret, spec, &is_secret, &mpis, &comment);
1535   if (err)
1536     goto out;
1537
1538   err = sexp_key_construct (key_public, spec, 0, mpis, comment);
1539
1540  out:
1541
1542   mpint_list_free (mpis);
1543   xfree (comment);
1544
1545   return err;
1546 }
1547
1548
1549 /* Check whether a smartcard is available and whether it has a usable
1550    key.  Store a copy of that key at R_PK and return 0.  If no key is
1551    available store NULL at R_PK and return an error code.  If CARDSN
1552    is no NULL, a string with the serial number of the card will be
1553    amalloced and stored there. */
1554 static gpg_error_t
1555 card_key_available (ctrl_t ctrl, gcry_sexp_t *r_pk, char **cardsn)
1556 {
1557   gpg_error_t err;
1558   char *appname;
1559   char *serialno = NULL;
1560   unsigned char *pkbuf;
1561   size_t pkbuflen;
1562   gcry_sexp_t s_pk;
1563   unsigned char grip[20];
1564
1565   *r_pk = NULL;
1566   if (cardsn)
1567     *cardsn = NULL;
1568
1569   /* First see whether a card is available and whether the application
1570      is supported.  */
1571   err = agent_card_getattr (ctrl, "APPTYPE", &appname);
1572   if ( gpg_err_code (err) == GPG_ERR_CARD_REMOVED )
1573     {
1574       /* Ask for the serial number to reset the card.  */
1575       err = agent_card_serialno (ctrl, &serialno);
1576       if (err)
1577         {
1578           if (opt.verbose)
1579             log_info (_("error getting serial number of card: %s\n"),
1580                       gpg_strerror (err));
1581           return err;
1582         }
1583       log_info (_("detected card with S/N: %s\n"), serialno);
1584       err = agent_card_getattr (ctrl, "APPTYPE", &appname);
1585     }
1586   if (err)
1587     {
1588       log_error (_("error getting application type of card: %s\n"),
1589                  gpg_strerror (err));
1590       xfree (serialno);
1591       return err;
1592     }
1593   if (strcmp (appname, "OPENPGP"))
1594     {
1595       log_info (_("card application `%s' is not supported\n"), appname);
1596       xfree (appname);
1597       xfree (serialno);
1598       return gpg_error (GPG_ERR_NOT_SUPPORTED);
1599     }
1600   xfree (appname);
1601   appname = NULL;
1602
1603   /* Get the S/N if we don't have it yet.  Use the fast getattr method.  */
1604   if (!serialno && (err = agent_card_getattr (ctrl, "SERIALNO", &serialno)) )
1605     {
1606       log_error (_("error getting serial number of card: %s\n"),
1607                  gpg_strerror (err));
1608       return err;
1609     }
1610
1611   /* Read the public key.  */
1612   err = agent_card_readkey (ctrl, "OPENPGP.3", &pkbuf);
1613   if (err)
1614     {
1615       if (opt.verbose)
1616         log_info (_("no suitable card key found: %s\n"), gpg_strerror (err));
1617       xfree (serialno);
1618       return err;
1619     }
1620
1621   pkbuflen = gcry_sexp_canon_len (pkbuf, 0, NULL, NULL);
1622   err = gcry_sexp_sscan (&s_pk, NULL, pkbuf, pkbuflen);
1623   if (err)
1624     {
1625       log_error ("failed to build S-Exp from received card key: %s\n",
1626                  gpg_strerror (err));
1627       xfree (pkbuf);
1628       xfree (serialno);
1629       return err;
1630     }
1631   
1632   if ( !gcry_pk_get_keygrip (s_pk, grip) )
1633     {
1634       log_debug ("error computing keygrip from received card key\n");
1635       xfree (pkbuf);
1636       gcry_sexp_release (s_pk);
1637       xfree (serialno);
1638       return gpg_error (GPG_ERR_INTERNAL);
1639     }
1640
1641   if ( agent_key_available (grip) )
1642     {
1643       /* (Shadow)-key is not available in our key storage.  */
1644       unsigned char *shadow_info;
1645       unsigned char *tmp;
1646       
1647       shadow_info = make_shadow_info (serialno, "OPENPGP.3");
1648       if (!shadow_info)
1649         {
1650           err = gpg_error_from_errno (errno);
1651           xfree (pkbuf);
1652           gcry_sexp_release (s_pk);
1653           xfree (serialno);
1654           return err;
1655         }
1656       err = agent_shadow_key (pkbuf, shadow_info, &tmp);
1657       xfree (shadow_info);
1658       if (err)
1659         {
1660           log_error (_("shadowing the key failed: %s\n"), gpg_strerror (err));
1661           xfree (pkbuf);
1662           gcry_sexp_release (s_pk);
1663           xfree (serialno);
1664           return err;
1665         }
1666       xfree (pkbuf);
1667       pkbuf = tmp;
1668       pkbuflen = gcry_sexp_canon_len (pkbuf, 0, NULL, NULL);
1669       assert (pkbuflen);
1670
1671       err = agent_write_private_key (grip, pkbuf, pkbuflen, 0);
1672       if (err)
1673         {
1674           log_error (_("error writing key: %s\n"), gpg_strerror (err));
1675           xfree (pkbuf);
1676           gcry_sexp_release (s_pk);
1677           xfree (serialno);
1678           return err;
1679         }
1680     }
1681
1682   if (cardsn)
1683     {
1684       size_t snlen = strlen (serialno);
1685
1686       if (snlen == 32
1687           && !memcmp (serialno, "D27600012401", 12)) /* OpenPGP card. */
1688         *cardsn = xtryasprintf ("cardno:%.12s", serialno+16);
1689       else /* Something is wrong: Print all. */
1690         *cardsn = xtryasprintf ("cardno:%s", serialno);
1691       if (!*cardsn)
1692         {
1693           err = gpg_error_from_errno (errno);
1694           xfree (pkbuf);
1695           gcry_sexp_release (s_pk);
1696           xfree (serialno);
1697           return err;
1698         }
1699     }
1700
1701   xfree (pkbuf);
1702   xfree (serialno);
1703   *r_pk = s_pk;
1704   return 0;
1705 }
1706
1707
1708 \f
1709
1710 /*
1711
1712   Request handler.  
1713
1714 */
1715
1716
1717 /* Handler for the "request_identities" command.  */
1718 static gpg_error_t
1719 ssh_handler_request_identities (ctrl_t ctrl,
1720                                 estream_t request, estream_t response)
1721 {
1722   char *key_type;
1723   ssh_key_type_spec_t spec;
1724   struct dirent *dir_entry;
1725   char *key_directory;
1726   size_t key_directory_n;
1727   char *key_path;
1728   unsigned char *buffer;
1729   size_t buffer_n;
1730   u32 key_counter;
1731   estream_t key_blobs;
1732   gcry_sexp_t key_secret;
1733   gcry_sexp_t key_public;
1734   DIR *dir;
1735   gpg_error_t err;
1736   gpg_error_t ret_err;
1737   int ret;
1738   FILE *ctrl_fp = NULL;
1739   char *cardsn;
1740
1741   /* Prepare buffer stream.  */
1742
1743   key_directory = NULL;
1744   key_secret = NULL;
1745   key_public = NULL;
1746   key_type = NULL;
1747   key_path = NULL;
1748   key_counter = 0;
1749   buffer = NULL;
1750   dir = NULL;
1751   err = 0;
1752
1753   key_blobs = es_mopen (NULL, 0, 0, 1, NULL, NULL, "r+");
1754   if (! key_blobs)
1755     {
1756       err = gpg_error_from_errno (errno);
1757       goto out;
1758     }
1759
1760   /* Open key directory.  */
1761   key_directory = make_filename (opt.homedir, GNUPG_PRIVATE_KEYS_DIR, NULL);
1762   if (! key_directory)
1763     {
1764       err = gpg_err_code_from_errno (errno);
1765       goto out;
1766     }
1767   key_directory_n = strlen (key_directory);
1768   
1769   key_path = xtrymalloc (key_directory_n + 46);
1770   if (! key_path)
1771     {
1772       err = gpg_err_code_from_errno (errno);
1773       goto out;
1774     }
1775
1776   sprintf (key_path, "%s/", key_directory);
1777   sprintf (key_path + key_directory_n + 41, ".key");
1778
1779   dir = opendir (key_directory);
1780   if (! dir)
1781     {
1782       err = gpg_err_code_from_errno (errno);
1783       goto out;
1784     }
1785
1786
1787
1788   /* First check whether a key is currently available in the card
1789      reader - this should be allowed even without being listed in
1790      sshcontrol. */
1791
1792   if (!card_key_available (ctrl, &key_public, &cardsn))
1793     {
1794       err = ssh_send_key_public (key_blobs, key_public, cardsn);
1795       gcry_sexp_release (key_public);
1796       key_public = NULL;
1797       xfree (cardsn);
1798       if (err)
1799         goto out;
1800       
1801       key_counter++;
1802     }
1803
1804
1805   /* Then look at all the registered an allowed keys. */
1806
1807
1808   /* Fixme: We should better iterate over the control file and check
1809      whether the key file is there.  This is better in resepct to
1810      performance if tehre are a lot of key sin our key storage. */
1811   /* FIXME: make sure that buffer gets deallocated properly.  */
1812   err = open_control_file (&ctrl_fp, 0);
1813   if (err)
1814     goto out;
1815
1816   while ( (dir_entry = readdir (dir)) )
1817     {
1818       if ((strlen (dir_entry->d_name) == 44)
1819           && (! strncmp (dir_entry->d_name + 40, ".key", 4)))
1820         {
1821           char hexgrip[41];
1822           int disabled;
1823
1824           /* We do only want to return keys listed in our control
1825              file. */
1826           strncpy (hexgrip, dir_entry->d_name, 40);
1827           hexgrip[40] = 0;
1828           if ( strlen (hexgrip) != 40 )
1829             continue;
1830           if (search_control_file (ctrl_fp, hexgrip, &disabled)
1831               || disabled)
1832             continue;
1833
1834           strncpy (key_path + key_directory_n + 1, dir_entry->d_name, 40);
1835
1836           /* Read file content.  */
1837           err = file_to_buffer (key_path, &buffer, &buffer_n);
1838           if (err)
1839             goto out;
1840               
1841           err = gcry_sexp_sscan (&key_secret, NULL, buffer, buffer_n);
1842           if (err)
1843             goto out;
1844
1845           xfree (buffer);
1846           buffer = NULL;
1847
1848           err = sexp_extract_identifier (key_secret, &key_type);
1849           if (err)
1850             goto out;
1851
1852           err = ssh_key_type_lookup (NULL, key_type, &spec);
1853           if (err)
1854             goto out;
1855
1856           xfree (key_type);
1857           key_type = NULL;
1858
1859           err = key_secret_to_public (&key_public, spec, key_secret);
1860           if (err)
1861             goto out;
1862
1863           gcry_sexp_release (key_secret);
1864           key_secret = NULL;
1865               
1866           err = ssh_send_key_public (key_blobs, key_public, NULL);
1867           if (err)
1868             goto out;
1869
1870           gcry_sexp_release (key_public);
1871           key_public = NULL;
1872
1873           key_counter++;
1874         }
1875     }
1876   
1877   ret = es_fseek (key_blobs, 0, SEEK_SET);
1878   if (ret)
1879     {
1880       err = gpg_error_from_errno (errno);
1881       goto out;
1882     }
1883
1884  out:
1885
1886   /* Send response.  */
1887
1888   gcry_sexp_release (key_secret);
1889   gcry_sexp_release (key_public);
1890
1891   if (! err)
1892     {
1893       ret_err = stream_write_byte (response, SSH_RESPONSE_IDENTITIES_ANSWER);
1894       if (ret_err)
1895         goto leave;
1896       ret_err = stream_write_uint32 (response, key_counter);
1897       if (ret_err)
1898         goto leave;
1899       ret_err = stream_copy (response, key_blobs);
1900       if (ret_err)
1901         goto leave;
1902     }
1903   else
1904     {
1905       ret_err = stream_write_byte (response, SSH_RESPONSE_FAILURE);
1906       goto leave;
1907     };
1908
1909  leave:
1910
1911   if (key_blobs)
1912     es_fclose (key_blobs);
1913   if (dir)
1914     closedir (dir);
1915
1916   if (ctrl_fp)
1917     fclose (ctrl_fp);
1918
1919   free (key_directory);
1920   xfree (key_path);
1921   xfree (buffer);
1922   xfree (key_type);
1923
1924   return ret_err;
1925 }
1926
1927 /*  */
1928 static gpg_error_t
1929 data_hash (unsigned char *data, size_t data_n,
1930            int md_algorithm, unsigned char *hash)
1931 {
1932   gcry_md_hash_buffer (md_algorithm, hash, data, data_n);
1933
1934   return 0;
1935 }
1936
1937
1938 static gpg_error_t
1939 data_sign (ctrl_t ctrl, ssh_signature_encoder_t sig_encoder,
1940            unsigned char **sig, size_t *sig_n)
1941 {
1942   gpg_error_t err;
1943   gcry_sexp_t signature_sexp;
1944   estream_t stream;
1945   gcry_sexp_t valuelist;
1946   gcry_sexp_t sublist;
1947   gcry_mpi_t sig_value;
1948   unsigned char *sig_blob;
1949   size_t sig_blob_n;
1950   char *identifier;
1951   const char *identifier_raw;
1952   size_t identifier_n;
1953   ssh_key_type_spec_t spec;
1954   int ret;
1955   unsigned int i;
1956   const char *elems;
1957   size_t elems_n;
1958   gcry_mpi_t *mpis;
1959
1960   signature_sexp = NULL;
1961   identifier = NULL;
1962   valuelist = NULL;
1963   sublist = NULL;
1964   sig_blob = NULL;
1965   sig_blob_n = 0;
1966   stream = NULL;
1967   sig_value = NULL;
1968   mpis = NULL;
1969
1970   ctrl->use_auth_call = 1;
1971   err = agent_pksign_do (ctrl,
1972                          _("Please enter the passphrase "
1973                            "for the ssh key%0A  %c"), &signature_sexp, 0);
1974   ctrl->use_auth_call = 0;
1975   if (err)
1976     goto out;
1977
1978   valuelist = gcry_sexp_nth (signature_sexp, 1);
1979   if (! valuelist)
1980     {
1981       err = gpg_error (GPG_ERR_INV_SEXP);
1982       goto out;
1983     }
1984
1985   stream = es_mopen (NULL, 0, 0, 1, NULL, NULL, "r+");
1986   if (! stream)
1987     {
1988       err = gpg_error_from_errno (errno);
1989       goto out;
1990     }
1991
1992   identifier_raw = gcry_sexp_nth_data (valuelist, 0, &identifier_n);
1993   if (! identifier_raw)
1994     {
1995       err = gpg_error (GPG_ERR_INV_SEXP);
1996       goto out;
1997     }
1998
1999   identifier = make_cstring (identifier_raw, identifier_n);
2000   if (! identifier)
2001     {
2002       err = gpg_error_from_errno (errno);
2003       goto out;
2004     }
2005
2006   err = ssh_key_type_lookup (NULL, identifier, &spec);
2007   if (err)
2008     goto out;
2009
2010   err = stream_write_cstring (stream, spec.ssh_identifier);
2011   if (err)
2012     goto out;
2013
2014   elems = spec.elems_signature;
2015   elems_n = strlen (elems);
2016
2017   mpis = xtrymalloc (sizeof (*mpis) * (elems_n + 1));
2018   if (! mpis)
2019     {
2020       err = gpg_error_from_errno (errno);
2021       goto out;
2022     }
2023   memset (mpis, 0, sizeof (*mpis) * (elems_n + 1));
2024
2025   for (i = 0; i < elems_n; i++)
2026     {
2027       sublist = gcry_sexp_find_token (valuelist, spec.elems_signature + i, 1);
2028       if (! sublist)
2029         {
2030           err = gpg_error (GPG_ERR_INV_SEXP);
2031           break;
2032         }
2033
2034       sig_value = gcry_sexp_nth_mpi (sublist, 1, GCRYMPI_FMT_USG);
2035       if (! sig_value)
2036         {
2037           err = gpg_error (GPG_ERR_INTERNAL); /* FIXME?  */
2038           break;
2039         }
2040       gcry_sexp_release (sublist);
2041       sublist = NULL;
2042
2043       mpis[i] = sig_value;
2044     }
2045   if (err)
2046     goto out;
2047
2048   err = (*sig_encoder) (stream, mpis);
2049   if (err)
2050     goto out;
2051
2052   sig_blob_n = es_ftell (stream);
2053   if (sig_blob_n == -1)
2054     {
2055       err = gpg_error_from_errno (errno);
2056       goto out;
2057     }
2058
2059   sig_blob = xtrymalloc (sig_blob_n);
2060   if (! sig_blob)
2061     {
2062       err = gpg_error_from_errno (errno);
2063       goto out;
2064     }
2065
2066   ret = es_fseek (stream, 0, SEEK_SET);
2067   if (ret)
2068     {
2069       err = gpg_error_from_errno (errno);
2070       goto out;
2071     }    
2072
2073   err = stream_read_data (stream, sig_blob, sig_blob_n);
2074   if (err)
2075     goto out;
2076   
2077   *sig = (char *) sig_blob;
2078   *sig_n = sig_blob_n;
2079   
2080  out:
2081
2082   if (err)
2083     xfree (sig_blob);
2084
2085   if (stream)
2086     es_fclose (stream);
2087   gcry_sexp_release (valuelist);
2088   gcry_sexp_release (signature_sexp);
2089   gcry_sexp_release (sublist);
2090   mpint_list_free (mpis);
2091   xfree (identifier);
2092
2093   return err;
2094 }
2095
2096 static gpg_error_t
2097 ssh_handler_sign_request (ctrl_t ctrl, estream_t request, estream_t response)
2098 {
2099   gcry_sexp_t key;
2100   ssh_key_type_spec_t spec;
2101   unsigned char hash[MAX_DIGEST_LEN];
2102   unsigned int hash_n;
2103   unsigned char key_grip[20];
2104   unsigned char *key_blob;
2105   u32 key_blob_size;
2106   unsigned char *data;
2107   unsigned char *sig;
2108   size_t sig_n;
2109   u32 data_size;
2110   u32 flags;
2111   void *p;
2112   gpg_error_t err;
2113   gpg_error_t ret_err;
2114
2115   key_blob = NULL;
2116   data = NULL;
2117   sig = NULL;
2118   key = NULL;
2119
2120   /* Receive key.  */
2121   
2122   err = stream_read_string (request, 0, &key_blob, &key_blob_size);
2123   if (err)
2124     goto out;
2125
2126   err = ssh_read_key_public_from_blob (key_blob, key_blob_size, &key, &spec);
2127   if (err)
2128     goto out;
2129
2130   /* Receive data to sign.  */
2131   err = stream_read_string (request, 0, &data, &data_size);
2132   if (err)
2133     goto out;
2134
2135   /* FIXME?  */
2136   err = stream_read_uint32 (request, &flags);
2137   if (err)
2138     goto out;
2139
2140   /* Hash data.  */
2141   hash_n = gcry_md_get_algo_dlen (GCRY_MD_SHA1);
2142   if (! hash_n)
2143     {
2144       err = gpg_error (GPG_ERR_INTERNAL);
2145       goto out;
2146     }
2147   err = data_hash (data, data_size, GCRY_MD_SHA1, hash);
2148   if (err)
2149     goto out;
2150
2151   /* Calculate key grip.  */
2152   p = gcry_pk_get_keygrip (key, key_grip);
2153   if (! p)
2154     {
2155       err = gpg_error (GPG_ERR_INTERNAL); /* FIXME?  */
2156       goto out;
2157     }
2158
2159   /* Sign data.  */
2160
2161   ctrl->digest.algo = GCRY_MD_SHA1;
2162   memcpy (ctrl->digest.value, hash, hash_n);
2163   ctrl->digest.valuelen = hash_n;
2164   ctrl->digest.raw_value = ! (spec.flags & SPEC_FLAG_USE_PKCS1V2);
2165   ctrl->have_keygrip = 1;
2166   memcpy (ctrl->keygrip, key_grip, 20);
2167
2168   err = data_sign (ctrl, spec.signature_encoder, &sig, &sig_n);
2169   
2170  out:
2171
2172   /* Done.  */
2173
2174   if (! err)
2175     {
2176       ret_err = stream_write_byte (response, SSH_RESPONSE_SIGN_RESPONSE);
2177       if (ret_err)
2178         goto leave;
2179       ret_err = stream_write_string (response, sig, sig_n);
2180       if (ret_err)
2181         goto leave;
2182     }
2183   else
2184     {
2185       ret_err = stream_write_byte (response, SSH_RESPONSE_FAILURE);
2186       if (ret_err)
2187         goto leave;
2188     }
2189   
2190  leave:
2191
2192   gcry_sexp_release (key);
2193   xfree (key_blob);
2194   xfree (data);
2195   xfree (sig);
2196
2197   return ret_err;
2198 }
2199
2200
2201 static gpg_error_t
2202 ssh_key_extract_comment (gcry_sexp_t key, char **comment)
2203 {
2204   gcry_sexp_t comment_list;
2205   char *comment_new;
2206   const char *data;
2207   size_t data_n;
2208   gpg_error_t err;
2209
2210   comment_list = gcry_sexp_find_token (key, "comment", 0);
2211   if (! comment_list)
2212     {
2213       err = gpg_error (GPG_ERR_INV_SEXP);
2214       goto out;
2215     }
2216   
2217   data = gcry_sexp_nth_data (comment_list, 1, &data_n);
2218   if (! data)
2219     {
2220       err = gpg_error (GPG_ERR_INV_SEXP);
2221       goto out;
2222     }
2223
2224   comment_new = make_cstring (data, data_n);
2225   if (! comment_new)
2226     {
2227       err = gpg_error_from_errno (errno);
2228       goto out;
2229     }
2230
2231   *comment = comment_new;
2232   err = 0;
2233
2234  out:
2235
2236   gcry_sexp_release (comment_list);
2237
2238   return err;
2239 }
2240
2241 static gpg_error_t
2242 ssh_key_grip (gcry_sexp_t key, char *buffer)
2243 {
2244   gpg_error_t err;
2245   char *p;
2246
2247   /* FIXME: unsigned vs. signed.  */
2248   
2249   p = gcry_pk_get_keygrip (key, buffer);
2250   if (! p)
2251     err = gpg_error (GPG_ERR_INTERNAL); /* FIXME?  */
2252   else
2253     err = 0;
2254
2255   return err;
2256 }
2257
2258 static gpg_error_t
2259 ssh_key_to_buffer (gcry_sexp_t key, const char *passphrase,
2260                    unsigned char **buffer, size_t *buffer_n)
2261 {
2262   unsigned char *buffer_new;
2263   unsigned int buffer_new_n;
2264   gpg_error_t err;
2265
2266   err = 0;
2267   buffer_new_n = gcry_sexp_sprint (key, GCRYSEXP_FMT_CANON, NULL, 0);
2268   buffer_new = xtrymalloc_secure (buffer_new_n);
2269   if (! buffer_new)
2270     {
2271       err = gpg_error_from_errno (errno);
2272       goto out;
2273     }
2274   
2275   gcry_sexp_sprint (key, GCRYSEXP_FMT_CANON, buffer_new, buffer_new_n);
2276   /* FIXME: guarantee?  */
2277
2278   err = agent_protect (buffer_new, passphrase, buffer, buffer_n);
2279
2280  out:
2281
2282   xfree (buffer_new);
2283
2284   return err;
2285 }
2286
2287
2288
2289 /* Store the ssh KEY into our local key storage and protect him after
2290    asking for a passphrase.  Cache that passphrase.  TTL is the
2291    maximum caching time for that key.  If the key already exists in
2292    our key storage, don't do anything.  When entering a new key also
2293    add an entry to the sshcontrol file.  */
2294 static gpg_error_t
2295 ssh_identity_register (ctrl_t ctrl, gcry_sexp_t key, int ttl)
2296 {
2297   gpg_error_t err;
2298   unsigned char key_grip_raw[21];
2299   char key_grip[41];
2300   unsigned char *buffer = NULL;
2301   unsigned int buffer_n;
2302   char *description = NULL;
2303   char *comment = NULL;
2304   unsigned int i;
2305   struct pin_entry_info_s *pi = NULL;
2306
2307   err = ssh_key_grip (key, key_grip_raw);
2308   if (err)
2309     goto out;
2310
2311   key_grip_raw[sizeof (key_grip_raw) - 1] = 0; /* FIXME:  Why?? */
2312
2313   /* Check whether the key is already in our key storage.  Don't do
2314      anything then.  */
2315   if ( !agent_key_available (key_grip_raw) )
2316     goto out; /* Yes, key is available.  */
2317
2318   
2319   err = ssh_key_extract_comment (key, &comment);
2320   if (err)
2321     goto out;
2322
2323   if ( asprintf (&description,
2324                  _("Please enter a passphrase to protect"
2325                    " the received secret key%%0A"
2326                    "   %s%%0A"
2327                    "within gpg-agent's key storage"),
2328                  comment ? comment : "?") < 0)
2329     {
2330       err = gpg_error_from_errno (errno);
2331       goto out;
2332     }
2333
2334
2335   pi = gcry_calloc_secure (1, sizeof (*pi) + 100 + 1);
2336   if (!pi)
2337     {
2338       err = gpg_error_from_errno (errno);
2339       goto out;
2340     }
2341   pi->max_length = 100;
2342   pi->max_tries = 1;
2343   err = agent_askpin (ctrl, description, NULL, pi);
2344   if (err)
2345     goto out;
2346
2347   err = ssh_key_to_buffer (key, pi->pin, &buffer, &buffer_n);
2348   if (err)
2349     goto out;
2350
2351   /* Store this key to our key storage.  */
2352   err = agent_write_private_key (key_grip_raw, buffer, buffer_n, 0);
2353   if (err)
2354     goto out;
2355
2356   /* Cache this passphrase. */
2357   for (i = 0; i < 20; i++)
2358     sprintf (key_grip + 2 * i, "%02X", key_grip_raw[i]);
2359
2360   err = agent_put_cache (key_grip, pi->pin, ttl);
2361   if (err)
2362     goto out;
2363
2364   /* And add an entry to the sshcontrol file.  */
2365   err = add_control_entry (ctrl, key_grip, ttl);
2366
2367
2368  out:
2369   if (pi && pi->max_length)
2370     wipememory (pi->pin, pi->max_length);
2371   xfree (pi);
2372   xfree (buffer);
2373   xfree (comment);
2374   free (description); /* (asprintf allocated, thus regular free.)  */
2375
2376   return err;
2377 }
2378
2379
2380
2381 static gpg_error_t
2382 ssh_identity_drop (gcry_sexp_t key)
2383 {
2384   unsigned char key_grip[21] = { 0 };
2385   gpg_error_t err;
2386
2387   err = ssh_key_grip (key, key_grip);
2388   if (err)
2389     goto out;
2390
2391   key_grip[sizeof (key_grip) - 1] = 0;
2392
2393   /* FIXME: What to do here - forgetting the passphrase or deleting
2394      the key from key cache?  */
2395
2396  out:
2397
2398   return err;
2399 }
2400
2401 static gpg_error_t
2402 ssh_handler_add_identity (ctrl_t ctrl, estream_t request, estream_t response)
2403 {
2404   gpg_error_t ret_err;
2405   gpg_error_t err;
2406   gcry_sexp_t key;
2407   unsigned char b;
2408   int confirm;
2409   int ttl;
2410   
2411   confirm = 0;
2412   key = NULL;
2413   ttl = 0;
2414
2415   /* FIXME?  */
2416   err = ssh_receive_key (request, &key, 1, 1, NULL);
2417   if (err)
2418     goto out;
2419
2420   while (1)
2421     {
2422       err = stream_read_byte (request, &b);
2423       if (gpg_err_code (err) == GPG_ERR_EOF)
2424         {
2425           err = 0;
2426           break;
2427         }
2428
2429       switch (b)
2430         {
2431         case SSH_OPT_CONSTRAIN_LIFETIME:
2432           {
2433             u32 n = 0;
2434
2435             err = stream_read_uint32 (request, &n);
2436             if (! err)
2437               ttl = n;
2438             break;
2439           }
2440
2441         case SSH_OPT_CONSTRAIN_CONFIRM:
2442           {
2443             confirm = 1;
2444             break;
2445           }
2446
2447         default:
2448           /* FIXME: log/bad?  */
2449           break;
2450         }
2451     }
2452   if (err)
2453     goto out;
2454
2455   /* FIXME: are constraints used correctly?  */
2456
2457   err = ssh_identity_register (ctrl, key, ttl);
2458
2459  out:
2460
2461   gcry_sexp_release (key);
2462
2463   ret_err = stream_write_byte (response,
2464                            err ? SSH_RESPONSE_FAILURE : SSH_RESPONSE_SUCCESS);
2465
2466   return ret_err;
2467 }
2468
2469 static gpg_error_t
2470 ssh_handler_remove_identity (ctrl_t ctrl, estream_t request,
2471                              estream_t response)
2472 {
2473   unsigned char *key_blob;
2474   u32 key_blob_size;
2475   gcry_sexp_t key;
2476   gpg_error_t ret_err;
2477   gpg_error_t err;
2478
2479   /* Receive key.  */
2480
2481   key_blob = NULL;
2482   key = NULL;
2483   
2484   err = stream_read_string (request, 0, &key_blob, &key_blob_size);
2485   if (err)
2486     goto out;
2487
2488   err = ssh_read_key_public_from_blob (key_blob, key_blob_size, &key, NULL);
2489   if (err)
2490     goto out;
2491   
2492   err = ssh_identity_drop (key);
2493
2494  out:
2495
2496   xfree (key_blob);
2497   gcry_sexp_release (key);
2498
2499   ret_err = stream_write_byte (response,
2500                            err ? SSH_RESPONSE_FAILURE : SSH_RESPONSE_SUCCESS);
2501
2502   return ret_err;
2503 }
2504
2505 static gpg_error_t
2506 ssh_identities_remove_all (void)
2507 {
2508   gpg_error_t err;
2509
2510   err = 0;
2511
2512   /* FIXME: shall we remove _all_ cache entries or only those
2513      registered through the ssh emulation?  */
2514   
2515   return err;
2516 }
2517
2518 static gpg_error_t
2519 ssh_handler_remove_all_identities (ctrl_t ctrl, estream_t request,
2520                                    estream_t response)
2521 {
2522   gpg_error_t ret_err;
2523   gpg_error_t err;
2524   
2525   err = ssh_identities_remove_all ();
2526   ret_err = stream_write_byte (response,
2527                            err ? SSH_RESPONSE_FAILURE : SSH_RESPONSE_SUCCESS);
2528
2529   return ret_err;
2530 }
2531
2532 static gpg_error_t
2533 ssh_lock (void)
2534 {
2535   gpg_error_t err;
2536
2537   /* FIXME */
2538   log_error ("ssh-agent's lock command is not implemented\n");
2539   err = 0;
2540
2541   return err;
2542 }
2543
2544 static gpg_error_t
2545 ssh_unlock (void)
2546 {
2547   gpg_error_t err;
2548
2549   log_error ("ssh-agent's unlock command is not implemented\n");
2550   err = 0;
2551
2552   return err;
2553 }
2554
2555 static gpg_error_t
2556 ssh_handler_lock (ctrl_t ctrl, estream_t request, estream_t response)
2557 {
2558   gpg_error_t ret_err;
2559   gpg_error_t err;
2560   
2561   err = ssh_lock ();
2562   ret_err = stream_write_byte (response,
2563                            err ? SSH_RESPONSE_FAILURE : SSH_RESPONSE_SUCCESS);
2564
2565   return ret_err;
2566 }
2567
2568 static gpg_error_t
2569 ssh_handler_unlock (ctrl_t ctrl, estream_t request, estream_t response)
2570 {
2571   gpg_error_t ret_err;
2572   gpg_error_t err;
2573   
2574   err = ssh_unlock ();
2575   ret_err = stream_write_byte (response,
2576                            err ? SSH_RESPONSE_FAILURE : SSH_RESPONSE_SUCCESS);
2577
2578   return ret_err;
2579 }
2580
2581 \f
2582
2583 static int
2584 ssh_request_process (ctrl_t ctrl, estream_t stream_sock)
2585 {
2586   estream_t response;
2587   estream_t request;
2588   unsigned char request_type;
2589   gpg_error_t err;
2590   unsigned int i;
2591   int send_err;
2592   int ret;
2593   unsigned char *request_data;
2594   u32 request_data_size;
2595   u32 response_size;
2596
2597   request_data = NULL;
2598   response = NULL;
2599   request = NULL;
2600   send_err = 0;
2601
2602   /* Create memory streams for request/response data.  The entire
2603      request will be stored in secure memory, since it might contain
2604      secret key material.  The response does not have to be stored in
2605      secure memory, since we never give out secret keys. 
2606
2607      FIXME: This is a pretty good DoS.  We only have a limited amount
2608      of secure memory, we can't trhow hin everything we get from a
2609      client -wk */
2610       
2611   /* Retrieve request.  */
2612   err = stream_read_string (stream_sock, 1, &request_data, &request_data_size);
2613   if (err)
2614     goto out;
2615
2616   if (opt.verbose > 1)
2617     log_info ("received ssh request of length %u\n",
2618               (unsigned int)request_data_size);
2619
2620   request = es_mopen (NULL, 0, 0, 1, realloc_secure, gcry_free, "r+");
2621   if (! request)
2622     {
2623       err = gpg_error_from_errno (errno);
2624       goto out;
2625     }
2626   ret = es_setvbuf (request, NULL, _IONBF, 0);
2627   if (ret)
2628     {
2629       err = gpg_error_from_errno (errno);
2630       goto out;
2631     }
2632   err = stream_write_data (request, request_data, request_data_size);
2633   if (err)
2634     goto out;
2635   es_rewind (request);
2636
2637   response = es_mopen (NULL, 0, 0, 1, NULL, NULL, "r+");
2638   if (! response)
2639     {
2640       err = gpg_error_from_errno (errno);
2641       goto out;
2642     }
2643
2644   err = stream_read_byte (request, &request_type);
2645   if (err)
2646     {
2647       send_err = 1;
2648       goto out;
2649     }
2650
2651   for (i = 0; i < DIM (request_specs); i++)
2652     if (request_specs[i].type == request_type)
2653       break;
2654   if (i == DIM (request_specs))
2655     {
2656       log_info ("ssh request %u is not supported\n", request_type);
2657       send_err = 1;
2658       goto out;
2659     }
2660
2661   if (opt.verbose)
2662     log_info ("ssh request handler for %s (%u) started\n",
2663                request_specs[i].identifier, request_specs[i].type);
2664
2665   err = (*request_specs[i].handler) (ctrl, request, response);
2666
2667   if (opt.verbose)
2668     {
2669       if (err)
2670         log_info ("ssh request handler for %s (%u) failed: %s\n",
2671                   request_specs[i].identifier, request_specs[i].type,
2672                   gpg_strerror (err));
2673       else
2674         log_info ("ssh request handler for %s (%u) ready\n",
2675                   request_specs[i].identifier, request_specs[i].type);
2676     }
2677
2678   if (err)
2679     {
2680       send_err = 1;
2681       goto out;
2682     }
2683
2684   response_size = es_ftell (response);
2685   if (opt.verbose > 1)
2686     log_info ("sending ssh response of length %u\n",
2687               (unsigned int)response_size);
2688
2689   err = es_fseek (response, 0, SEEK_SET);
2690   if (err)
2691     {
2692       send_err = 1;
2693       goto out;
2694     }
2695
2696   err = stream_write_uint32 (stream_sock, response_size);
2697   if (err)
2698     {
2699       send_err = 1;
2700       goto out;
2701     }
2702
2703   err = stream_copy (stream_sock, response);
2704   if (err)
2705     goto out;
2706
2707   err = es_fflush (stream_sock);
2708   if (err)
2709     goto out;
2710
2711  out:
2712
2713   if (err && es_feof (stream_sock))
2714     log_error ("error occured while processing request: %s\n",
2715                gpg_strerror (err));
2716
2717   if (send_err)
2718     {
2719       if (opt.verbose > 1)
2720         log_info ("sending ssh error response\n");
2721       err = stream_write_uint32 (stream_sock, 1);
2722       if (err)
2723         goto leave;
2724       err = stream_write_byte (stream_sock, SSH_RESPONSE_FAILURE);
2725       if (err)
2726         goto leave;
2727     }
2728
2729  leave:
2730
2731   if (request)
2732     es_fclose (request);
2733   if (response)
2734     es_fclose (response);
2735   xfree (request_data);         /* FIXME?  */
2736
2737   return !!err;
2738 }
2739
2740 void
2741 start_command_handler_ssh (int sock_client)
2742 {
2743   struct server_control_s ctrl;
2744   estream_t stream_sock;
2745   gpg_error_t err;
2746   int bad;
2747   int ret;
2748
2749   /* Setup control structure.  */
2750
2751   memset (&ctrl, 0, sizeof (ctrl));
2752   agent_init_default_ctrl (&ctrl);
2753   ctrl.connection_fd = sock_client;
2754
2755   /* Because the ssh protocol does not send us information about the
2756      the current TTY setting, we resort here to use those from startup
2757      or those explictly set.  */
2758   if (!ctrl.display && opt.startup_display)
2759     ctrl.display = strdup (opt.startup_display);
2760   if (!ctrl.ttyname && opt.startup_ttyname)
2761     ctrl.ttyname = strdup (opt.startup_ttyname);
2762   if (!ctrl.ttytype && opt.startup_ttytype)
2763     ctrl.ttytype = strdup (opt.startup_ttytype);
2764   if (!ctrl.lc_ctype && opt.startup_lc_ctype)
2765     ctrl.lc_ctype = strdup (opt.startup_lc_ctype);
2766   if (!ctrl.lc_messages && opt.startup_lc_messages)
2767     ctrl.lc_messages = strdup (opt.startup_lc_messages);
2768
2769
2770   /* Create stream from socket.  */
2771   stream_sock = es_fdopen (sock_client, "r+");
2772   if (!stream_sock)
2773     {
2774       err = gpg_error_from_errno (errno);
2775       log_error (_("failed to create stream from socket: %s\n"),
2776                  gpg_strerror (err));
2777       goto out;
2778     }
2779   /* We have to disable the estream buffering, because the estream
2780      core doesn't know about secure memory.  */
2781   ret = es_setvbuf (stream_sock, NULL, _IONBF, 0);
2782   if (ret)
2783     {
2784       err = gpg_error_from_errno (errno);
2785       log_error (_("failed to disable buffering "
2786                    "on socket stream: %s\n"), gpg_strerror (err));
2787       goto out;
2788     }
2789
2790   while (1)
2791     {
2792       bad = ssh_request_process (&ctrl, stream_sock);
2793       if (bad)
2794         break;
2795     };
2796
2797  out:
2798
2799   if (stream_sock)
2800     es_fclose (stream_sock);
2801
2802   free (ctrl.display);
2803   free (ctrl.ttyname);
2804   free (ctrl.ttytype);
2805   free (ctrl.lc_ctype);
2806   free (ctrl.lc_messages);
2807 }