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