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