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