Fix crash while reading unsupported ssh keys.
[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   unsigned int elems_public_n;
937   const char *elems_public;
938   unsigned int elems_n;
939   const char *elems;
940   int elem_is_secret;
941   gcry_mpi_t *mpis;
942   gpg_error_t err;
943   unsigned int i;
944
945   mpis = NULL;
946   err = 0;
947
948   if (secret)
949     elems = key_spec.elems_key_secret;
950   else
951     elems = key_spec.elems_key_public;
952   elems_n = strlen (elems);
953
954   elems_public = key_spec.elems_key_public;
955   elems_public_n = strlen (elems_public);
956
957   mpis = xtrycalloc (elems_n + 1, sizeof *mpis );
958   if (!mpis)
959     {
960       err = gpg_error_from_syserror ();
961       goto out;
962     }
963
964   elem_is_secret = 0;
965   for (i = 0; i < elems_n; i++)
966     {
967       if (secret)
968         elem_is_secret = ! strchr (elems_public, elems[i]);
969       err = stream_read_mpi (stream, elem_is_secret, &mpis[i]);
970       if (err)
971         break;
972     }
973   if (err)
974     goto out;
975
976   *mpi_list = mpis;
977
978  out:
979
980   if (err)
981     mpint_list_free (mpis);
982
983   return err;
984 }
985
986 \f
987
988 /* Key modifier function for RSA.  */
989 static gpg_error_t
990 ssh_key_modifier_rsa (const char *elems, gcry_mpi_t *mpis)
991 {
992   gcry_mpi_t p;
993   gcry_mpi_t q;
994   gcry_mpi_t u;
995
996   if (strcmp (elems, "nedupq"))
997     /* Modifying only necessary for secret keys.  */
998     goto out;
999
1000   u = mpis[3];
1001   p = mpis[4];
1002   q = mpis[5];
1003
1004   if (gcry_mpi_cmp (p, q) > 0)
1005     {
1006       /* P shall be smaller then Q!  Swap primes.  iqmp becomes u.  */
1007       gcry_mpi_t tmp;
1008
1009       tmp = mpis[4];
1010       mpis[4] = mpis[5];
1011       mpis[5] = tmp;
1012     }
1013   else
1014     /* U needs to be recomputed.  */
1015     gcry_mpi_invm (u, p, q);
1016
1017  out:
1018
1019   return 0;
1020 }
1021
1022 /* Signature encoder function for RSA.  */
1023 static gpg_error_t
1024 ssh_signature_encoder_rsa (estream_t signature_blob, gcry_mpi_t *mpis)
1025 {
1026   unsigned char *data;
1027   size_t data_n;
1028   gpg_error_t err;
1029   gcry_mpi_t s;
1030
1031   s = mpis[0];
1032
1033   err = gcry_mpi_aprint (GCRYMPI_FMT_USG, &data, &data_n, s);
1034   if (err)
1035     goto out;
1036
1037   err = stream_write_string (signature_blob, data, data_n);
1038   xfree (data);
1039
1040  out:
1041
1042   return err;
1043 }
1044
1045
1046 /* Signature encoder function for DSA.  */
1047 static gpg_error_t
1048 ssh_signature_encoder_dsa (estream_t signature_blob, gcry_mpi_t *mpis)
1049 {
1050   unsigned char buffer[SSH_DSA_SIGNATURE_PADDING * SSH_DSA_SIGNATURE_ELEMS];
1051   unsigned char *data;
1052   size_t data_n;
1053   gpg_error_t err;
1054   int i;
1055
1056   data = NULL;
1057
1058   for (i = 0; i < 2; i++)
1059     {
1060       err = gcry_mpi_aprint (GCRYMPI_FMT_USG, &data, &data_n, mpis[i]);
1061       if (err)
1062         break;
1063
1064       if (data_n > SSH_DSA_SIGNATURE_PADDING)
1065         {
1066           err = gpg_error (GPG_ERR_INTERNAL); /* FIXME?  */
1067           break;
1068         }
1069
1070       memset (buffer + (i * SSH_DSA_SIGNATURE_PADDING), 0,
1071               SSH_DSA_SIGNATURE_PADDING - data_n);
1072       memcpy (buffer + (i * SSH_DSA_SIGNATURE_PADDING)
1073               + (SSH_DSA_SIGNATURE_PADDING - data_n), data, data_n);
1074
1075       xfree (data);
1076       data = NULL;
1077     }
1078   if (err)
1079     goto out;
1080
1081   err = stream_write_string (signature_blob, buffer, sizeof (buffer));
1082
1083  out:
1084
1085   xfree (data);
1086
1087   return err;
1088 }
1089
1090 /*
1091    S-Expressions.
1092  */
1093
1094
1095 /* This function constructs a new S-Expression for the key identified
1096    by the KEY_SPEC, SECRET, MPIS and COMMENT, which is to be stored in
1097    *SEXP.  Returns usual error code.  */
1098 static gpg_error_t
1099 sexp_key_construct (gcry_sexp_t *sexp,
1100                     ssh_key_type_spec_t key_spec, int secret,
1101                     gcry_mpi_t *mpis, const char *comment)
1102 {
1103   const char *key_identifier[] = { "public-key", "private-key" };
1104   gcry_sexp_t sexp_new;
1105   char *sexp_template;
1106   size_t sexp_template_n;
1107   gpg_error_t err;
1108   const char *elems;
1109   size_t elems_n;
1110   unsigned int i;
1111   unsigned int j;
1112   void **arg_list;
1113
1114   err = 0;
1115   sexp_new = NULL;
1116   arg_list = NULL;
1117   if (secret)
1118     elems = key_spec.elems_sexp_order;
1119   else
1120     elems = key_spec.elems_key_public;
1121   elems_n = strlen (elems);
1122
1123   /*
1124     Calculate size for sexp_template_n:
1125
1126     "(%s(%s<mpis>)(comment%s))" -> 20 + sizeof (<mpis>).
1127
1128     mpi: (X%m) -> 5.
1129
1130   */
1131   sexp_template_n = 20 + (elems_n * 5);
1132   sexp_template = xtrymalloc (sexp_template_n);
1133   if (! sexp_template)
1134     {
1135       err = gpg_error_from_syserror ();
1136       goto out;
1137     }
1138
1139   /* Key identifier, algorithm identifier, mpis, comment.  */
1140   arg_list = xtrymalloc (sizeof (*arg_list) * (2 + elems_n + 1));
1141   if (! arg_list)
1142     {
1143       err = gpg_error_from_syserror ();
1144       goto out;
1145     }
1146
1147   i = 0;
1148   arg_list[i++] = &key_identifier[secret];
1149   arg_list[i++] = &key_spec.identifier;
1150
1151   *sexp_template = 0;
1152   sexp_template_n = 0;
1153   sexp_template_n = sprintf (sexp_template + sexp_template_n, "(%%s(%%s");
1154   for (i = 0; i < elems_n; i++)
1155     {
1156       sexp_template_n += sprintf (sexp_template + sexp_template_n, "(%c%%m)",
1157                                   elems[i]);
1158       if (secret)
1159         {
1160           for (j = 0; j < elems_n; j++)
1161             if (key_spec.elems_key_secret[j] == elems[i])
1162               break;
1163         }
1164       else
1165         j = i;
1166       arg_list[i + 2] = &mpis[j];
1167     }
1168   sexp_template_n += sprintf (sexp_template + sexp_template_n,
1169                               ")(comment%%s))");
1170
1171   arg_list[i + 2] = &comment;
1172
1173   err = gcry_sexp_build_array (&sexp_new, NULL, sexp_template, arg_list);
1174   if (err)
1175     goto out;
1176
1177   *sexp = sexp_new;
1178
1179  out:
1180
1181   xfree (arg_list);
1182   xfree (sexp_template);
1183
1184   return err;
1185 }
1186
1187 /* This functions breaks up the key contained in the S-Expression SEXP
1188    according to KEY_SPEC.  The MPIs are bundled in a newly create
1189    list, which is to be stored in MPIS; a newly allocated string
1190    holding the comment will be stored in COMMENT; SECRET will be
1191    filled with a boolean flag specifying what kind of key it is.
1192    Returns usual error code.  */
1193 static gpg_error_t
1194 sexp_key_extract (gcry_sexp_t sexp,
1195                   ssh_key_type_spec_t key_spec, int *secret,
1196                   gcry_mpi_t **mpis, char **comment)
1197 {
1198   gpg_error_t err;
1199   gcry_sexp_t value_list;
1200   gcry_sexp_t value_pair;
1201   gcry_sexp_t comment_list;
1202   unsigned int i;
1203   char *comment_new;
1204   const char *data;
1205   size_t data_n;
1206   int is_secret;
1207   size_t elems_n;
1208   const char *elems;
1209   gcry_mpi_t *mpis_new;
1210   gcry_mpi_t mpi;
1211
1212   err = 0;
1213   value_list = NULL;
1214   value_pair = NULL;
1215   comment_list = NULL;
1216   comment_new = NULL;
1217   mpis_new = NULL;
1218
1219   data = gcry_sexp_nth_data (sexp, 0, &data_n);
1220   if (! data)
1221     {
1222       err = gpg_error (GPG_ERR_INV_SEXP);
1223       goto out;
1224     }
1225
1226   if ((data_n == 10 && !strncmp (data, "public-key", 10))
1227       || (data_n == 21 && !strncmp (data, "protected-private-key", 21))
1228       || (data_n == 20 && !strncmp (data, "shadowed-private-key", 20)))
1229     {
1230       is_secret = 0;
1231       elems = key_spec.elems_key_public;
1232     }
1233   else if (data_n == 11 && !strncmp (data, "private-key", 11))
1234     {
1235       is_secret = 1;
1236       elems = key_spec.elems_key_secret;
1237     }
1238   else
1239     {
1240       err = gpg_error (GPG_ERR_INV_SEXP);
1241       goto out;
1242     }
1243
1244   elems_n = strlen (elems);
1245   mpis_new = xtrycalloc (elems_n + 1, sizeof *mpis_new );
1246   if (!mpis_new)
1247     {
1248       err = gpg_error_from_syserror ();
1249       goto out;
1250     }
1251
1252   value_list = gcry_sexp_find_token (sexp, key_spec.identifier, 0);
1253   if (! value_list)
1254     {
1255       err = gpg_error (GPG_ERR_INV_SEXP);
1256       goto out;
1257     }
1258
1259   for (i = 0; i < elems_n; i++)
1260     {
1261       value_pair = gcry_sexp_find_token (value_list, elems + i, 1);
1262       if (! value_pair)
1263         {
1264           err = gpg_error (GPG_ERR_INV_SEXP);
1265           break;
1266         }
1267
1268       /* Note that we need to use STD format; i.e. prepend a 0x00 to
1269          indicate a positive number if the high bit is set. */
1270       mpi = gcry_sexp_nth_mpi (value_pair, 1, GCRYMPI_FMT_STD);
1271       if (! mpi)
1272         {
1273           err = gpg_error (GPG_ERR_INV_SEXP);
1274           break;
1275         }
1276       mpis_new[i] = mpi;
1277       gcry_sexp_release (value_pair);
1278       value_pair = NULL;
1279     }
1280   if (err)
1281     goto out;
1282
1283   /* We do not require a comment sublist to be present here.  */
1284   data = NULL;
1285   data_n = 0;
1286
1287   comment_list = gcry_sexp_find_token (sexp, "comment", 0);
1288   if (comment_list)
1289     data = gcry_sexp_nth_data (comment_list, 1, &data_n);
1290   if (! data)
1291     {
1292       data = "(none)";
1293       data_n = 6;
1294     }
1295
1296   comment_new = make_cstring (data, data_n);
1297   if (! comment_new)
1298     {
1299       err = gpg_error_from_syserror ();
1300       goto out;
1301     }
1302
1303   if (secret)
1304     *secret = is_secret;
1305   *mpis = mpis_new;
1306   *comment = comment_new;
1307
1308  out:
1309
1310   gcry_sexp_release (value_list);
1311   gcry_sexp_release (value_pair);
1312   gcry_sexp_release (comment_list);
1313
1314   if (err)
1315     {
1316       xfree (comment_new);
1317       mpint_list_free (mpis_new);
1318     }
1319
1320   return err;
1321 }
1322
1323 /* Extract the car from SEXP, and create a newly created C-string
1324    which is to be stored in IDENTIFIER.  */
1325 static gpg_error_t
1326 sexp_extract_identifier (gcry_sexp_t sexp, char **identifier)
1327 {
1328   char *identifier_new;
1329   gcry_sexp_t sublist;
1330   const char *data;
1331   size_t data_n;
1332   gpg_error_t err;
1333
1334   identifier_new = NULL;
1335   err = 0;
1336
1337   sublist = gcry_sexp_nth (sexp, 1);
1338   if (! sublist)
1339     {
1340       err = gpg_error (GPG_ERR_INV_SEXP);
1341       goto out;
1342     }
1343
1344   data = gcry_sexp_nth_data (sublist, 0, &data_n);
1345   if (! data)
1346     {
1347       err = gpg_error (GPG_ERR_INV_SEXP);
1348       goto out;
1349     }
1350
1351   identifier_new = make_cstring (data, data_n);
1352   if (! identifier_new)
1353     {
1354       err = gpg_err_code_from_errno (errno);
1355       goto out;
1356     }
1357
1358   *identifier = identifier_new;
1359
1360  out:
1361
1362   gcry_sexp_release (sublist);
1363
1364   return err;
1365 }
1366
1367 \f
1368
1369 /*
1370
1371   Key I/O.
1372
1373 */
1374
1375 /* Search for a key specification entry.  If SSH_NAME is not NULL,
1376    search for an entry whose "ssh_name" is equal to SSH_NAME;
1377    otherwise, search for an entry whose "name" is equal to NAME.
1378    Store found entry in SPEC on success, return error otherwise.  */
1379 static gpg_error_t
1380 ssh_key_type_lookup (const char *ssh_name, const char *name,
1381                      ssh_key_type_spec_t *spec)
1382 {
1383   gpg_error_t err;
1384   unsigned int i;
1385
1386   for (i = 0; i < DIM (ssh_key_types); i++)
1387     if ((ssh_name && (! strcmp (ssh_name, ssh_key_types[i].ssh_identifier)))
1388         || (name && (! strcmp (name, ssh_key_types[i].identifier))))
1389       break;
1390
1391   if (i == DIM (ssh_key_types))
1392     err = gpg_error (GPG_ERR_NOT_FOUND);
1393   else
1394     {
1395       *spec = ssh_key_types[i];
1396       err = 0;
1397     }
1398
1399   return err;
1400 }
1401
1402 /* Receive a key from STREAM, according to the key specification given
1403    as KEY_SPEC.  Depending on SECRET, receive a secret or a public
1404    key.  If READ_COMMENT is true, receive a comment string as well.
1405    Constructs a new S-Expression from received data and stores it in
1406    KEY_NEW.  Returns zero on success or an error code.  */
1407 static gpg_error_t
1408 ssh_receive_key (estream_t stream, gcry_sexp_t *key_new, int secret,
1409                  int read_comment, ssh_key_type_spec_t *key_spec)
1410 {
1411   gpg_error_t err;
1412   char *key_type = NULL;
1413   char *comment = NULL;
1414   gcry_sexp_t key = NULL;
1415   ssh_key_type_spec_t spec;
1416   gcry_mpi_t *mpi_list = NULL;
1417   const char *elems;
1418
1419   err = stream_read_cstring (stream, &key_type);
1420   if (err)
1421     goto out;
1422
1423   err = ssh_key_type_lookup (key_type, NULL, &spec);
1424   if (err)
1425     goto out;
1426
1427   err = ssh_receive_mpint_list (stream, secret, spec, &mpi_list);
1428   if (err)
1429     goto out;
1430
1431   if (read_comment)
1432     {
1433       err = stream_read_cstring (stream, &comment);
1434       if (err)
1435         goto out;
1436     }
1437
1438   if (secret)
1439     elems = spec.elems_key_secret;
1440   else
1441     elems = spec.elems_key_public;
1442
1443   if (spec.key_modifier)
1444     {
1445       err = (*spec.key_modifier) (elems, mpi_list);
1446       if (err)
1447         goto out;
1448     }
1449
1450   err = sexp_key_construct (&key, spec, secret, mpi_list, comment? comment:"");
1451   if (err)
1452     goto out;
1453
1454   if (key_spec)
1455     *key_spec = spec;
1456   *key_new = key;
1457
1458  out:
1459
1460   mpint_list_free (mpi_list);
1461   xfree (key_type);
1462   xfree (comment);
1463
1464   return err;
1465 }
1466
1467 /* Converts a key of type TYPE, whose key material is given in MPIS,
1468    into a newly created binary blob, which is to be stored in
1469    BLOB/BLOB_SIZE.  Returns zero on success or an error code.  */
1470 static gpg_error_t
1471 ssh_convert_key_to_blob (unsigned char **blob, size_t *blob_size,
1472                          const char *type, gcry_mpi_t *mpis)
1473 {
1474   unsigned char *blob_new;
1475   long int blob_size_new;
1476   estream_t stream;
1477   gpg_error_t err;
1478   unsigned int i;
1479
1480   *blob = NULL;
1481   *blob_size = 0;
1482
1483   blob_new = NULL;
1484   stream = NULL;
1485   err = 0;
1486
1487   stream = es_mopen (NULL, 0, 0, 1, NULL, NULL, "r+");
1488   if (! stream)
1489     {
1490       err = gpg_error_from_syserror ();
1491       goto out;
1492     }
1493
1494   err = stream_write_cstring (stream, type);
1495   if (err)
1496     goto out;
1497
1498   for (i = 0; mpis[i] && (! err); i++)
1499     err = stream_write_mpi (stream, mpis[i]);
1500   if (err)
1501     goto out;
1502
1503   blob_size_new = es_ftell (stream);
1504   if (blob_size_new == -1)
1505     {
1506       err = gpg_error_from_syserror ();
1507       goto out;
1508     }
1509
1510   err = es_fseek (stream, 0, SEEK_SET);
1511   if (err)
1512     goto out;
1513
1514   blob_new = xtrymalloc (blob_size_new);
1515   if (! blob_new)
1516     {
1517       err = gpg_error_from_syserror ();
1518       goto out;
1519     }
1520
1521   err = stream_read_data (stream, blob_new, blob_size_new);
1522   if (err)
1523     goto out;
1524
1525   *blob = blob_new;
1526   *blob_size = blob_size_new;
1527
1528  out:
1529
1530   if (stream)
1531     es_fclose (stream);
1532   if (err)
1533     xfree (blob_new);
1534
1535   return err;
1536 }
1537
1538
1539 /* Write the public key KEY_PUBLIC to STREAM in SSH key format.  If
1540    OVERRIDE_COMMENT is not NULL, it will be used instead of the
1541    comment stored in the key.  */
1542 static gpg_error_t
1543 ssh_send_key_public (estream_t stream, gcry_sexp_t key_public,
1544                      const char *override_comment)
1545 {
1546   ssh_key_type_spec_t spec;
1547   gcry_mpi_t *mpi_list;
1548   char *key_type;
1549   char *comment;
1550   unsigned char *blob;
1551   size_t blob_n;
1552   gpg_error_t err;
1553
1554   key_type = NULL;
1555   mpi_list = NULL;
1556   comment = NULL;
1557   blob = NULL;
1558
1559   err = sexp_extract_identifier (key_public, &key_type);
1560   if (err)
1561     goto out;
1562
1563   err = ssh_key_type_lookup (NULL, key_type, &spec);
1564   if (err)
1565     goto out;
1566
1567   err = sexp_key_extract (key_public, spec, NULL, &mpi_list, &comment);
1568   if (err)
1569     goto out;
1570
1571   err = ssh_convert_key_to_blob (&blob, &blob_n,
1572                                  spec.ssh_identifier, mpi_list);
1573   if (err)
1574     goto out;
1575
1576   err = stream_write_string (stream, blob, blob_n);
1577   if (err)
1578     goto out;
1579
1580   err = stream_write_cstring (stream,
1581                               override_comment? override_comment : comment);
1582
1583  out:
1584
1585   mpint_list_free (mpi_list);
1586   xfree (key_type);
1587   xfree (comment);
1588   xfree (blob);
1589
1590   return err;
1591 }
1592
1593 /* Read a public key out of BLOB/BLOB_SIZE according to the key
1594    specification given as KEY_SPEC, storing the new key in KEY_PUBLIC.
1595    Returns zero on success or an error code.  */
1596 static gpg_error_t
1597 ssh_read_key_public_from_blob (unsigned char *blob, size_t blob_size,
1598                                gcry_sexp_t *key_public,
1599                                ssh_key_type_spec_t *key_spec)
1600 {
1601   estream_t blob_stream;
1602   gpg_error_t err;
1603
1604   err = 0;
1605
1606   blob_stream = es_mopen (NULL, 0, 0, 1, NULL, NULL, "r+");
1607   if (! blob_stream)
1608     {
1609       err = gpg_error_from_syserror ();
1610       goto out;
1611     }
1612
1613   err = stream_write_data (blob_stream, blob, blob_size);
1614   if (err)
1615     goto out;
1616
1617   err = es_fseek (blob_stream, 0, SEEK_SET);
1618   if (err)
1619     goto out;
1620
1621   err = ssh_receive_key (blob_stream, key_public, 0, 0, key_spec);
1622
1623  out:
1624
1625   if (blob_stream)
1626     es_fclose (blob_stream);
1627
1628   return err;
1629 }
1630
1631 \f
1632
1633 /* This function calculates the key grip for the key contained in the
1634    S-Expression KEY and writes it to BUFFER, which must be large
1635    enough to hold it.  Returns usual error code.  */
1636 static gpg_error_t
1637 ssh_key_grip (gcry_sexp_t key, unsigned char *buffer)
1638 {
1639   if (!gcry_pk_get_keygrip (key, buffer))
1640     return gpg_error (GPG_ERR_INTERNAL);
1641
1642   return 0;
1643 }
1644
1645
1646 /* Converts the secret key KEY_SECRET into a public key, storing it in
1647    KEY_PUBLIC.  SPEC is the according key specification.  Returns zero
1648    on success or an error code.  */
1649 static gpg_error_t
1650 key_secret_to_public (gcry_sexp_t *key_public,
1651                       ssh_key_type_spec_t spec, gcry_sexp_t key_secret)
1652 {
1653   char *comment;
1654   gcry_mpi_t *mpis;
1655   gpg_error_t err;
1656   int is_secret;
1657
1658   comment = NULL;
1659   mpis = NULL;
1660
1661   err = sexp_key_extract (key_secret, spec, &is_secret, &mpis, &comment);
1662   if (err)
1663     goto out;
1664
1665   err = sexp_key_construct (key_public, spec, 0, mpis, comment);
1666
1667  out:
1668
1669   mpint_list_free (mpis);
1670   xfree (comment);
1671
1672   return err;
1673 }
1674
1675
1676 /* Check whether a smartcard is available and whether it has a usable
1677    key.  Store a copy of that key at R_PK and return 0.  If no key is
1678    available store NULL at R_PK and return an error code.  If CARDSN
1679    is not NULL, a string with the serial number of the card will be
1680    a malloced and stored there. */
1681 static gpg_error_t
1682 card_key_available (ctrl_t ctrl, gcry_sexp_t *r_pk, char **cardsn)
1683 {
1684   gpg_error_t err;
1685   char *authkeyid;
1686   char *serialno = NULL;
1687   unsigned char *pkbuf;
1688   size_t pkbuflen;
1689   gcry_sexp_t s_pk;
1690   unsigned char grip[20];
1691
1692   *r_pk = NULL;
1693   if (cardsn)
1694     *cardsn = NULL;
1695
1696   /* First see whether a card is available and whether the application
1697      is supported.  */
1698   err = agent_card_getattr (ctrl, "$AUTHKEYID", &authkeyid);
1699   if ( gpg_err_code (err) == GPG_ERR_CARD_REMOVED )
1700     {
1701       /* Ask for the serial number to reset the card.  */
1702       err = agent_card_serialno (ctrl, &serialno);
1703       if (err)
1704         {
1705           if (opt.verbose)
1706             log_info (_("error getting serial number of card: %s\n"),
1707                       gpg_strerror (err));
1708           return err;
1709         }
1710       log_info (_("detected card with S/N: %s\n"), serialno);
1711       err = agent_card_getattr (ctrl, "$AUTHKEYID", &authkeyid);
1712     }
1713   if (err)
1714     {
1715       log_error (_("error getting default authentication keyID of card: %s\n"),
1716                  gpg_strerror (err));
1717       xfree (serialno);
1718       return err;
1719     }
1720
1721   /* Get the S/N if we don't have it yet.  Use the fast getattr method.  */
1722   if (!serialno && (err = agent_card_getattr (ctrl, "SERIALNO", &serialno)) )
1723     {
1724       log_error (_("error getting serial number of card: %s\n"),
1725                  gpg_strerror (err));
1726       xfree (authkeyid);
1727       return err;
1728     }
1729
1730   /* Read the public key.  */
1731   err = agent_card_readkey (ctrl, authkeyid, &pkbuf);
1732   if (err)
1733     {
1734       if (opt.verbose)
1735         log_info (_("no suitable card key found: %s\n"), gpg_strerror (err));
1736       xfree (serialno);
1737       xfree (authkeyid);
1738       return err;
1739     }
1740
1741   pkbuflen = gcry_sexp_canon_len (pkbuf, 0, NULL, NULL);
1742   err = gcry_sexp_sscan (&s_pk, NULL, (char*)pkbuf, pkbuflen);
1743   if (err)
1744     {
1745       log_error ("failed to build S-Exp from received card key: %s\n",
1746                  gpg_strerror (err));
1747       xfree (pkbuf);
1748       xfree (serialno);
1749       xfree (authkeyid);
1750       return err;
1751     }
1752
1753   err = ssh_key_grip (s_pk, grip);
1754   if (err)
1755     {
1756       log_debug ("error computing keygrip from received card key: %s\n",
1757                  gcry_strerror (err));
1758       xfree (pkbuf);
1759       gcry_sexp_release (s_pk);
1760       xfree (serialno);
1761       xfree (authkeyid);
1762       return err;
1763     }
1764
1765   if ( agent_key_available (grip) )
1766     {
1767       /* (Shadow)-key is not available in our key storage.  */
1768       unsigned char *shadow_info;
1769       unsigned char *tmp;
1770
1771       shadow_info = make_shadow_info (serialno, authkeyid);
1772       if (!shadow_info)
1773         {
1774           err = gpg_error_from_syserror ();
1775           xfree (pkbuf);
1776           gcry_sexp_release (s_pk);
1777           xfree (serialno);
1778           xfree (authkeyid);
1779           return err;
1780         }
1781       err = agent_shadow_key (pkbuf, shadow_info, &tmp);
1782       xfree (shadow_info);
1783       if (err)
1784         {
1785           log_error (_("shadowing the key failed: %s\n"), gpg_strerror (err));
1786           xfree (pkbuf);
1787           gcry_sexp_release (s_pk);
1788           xfree (serialno);
1789           xfree (authkeyid);
1790           return err;
1791         }
1792       xfree (pkbuf);
1793       pkbuf = tmp;
1794       pkbuflen = gcry_sexp_canon_len (pkbuf, 0, NULL, NULL);
1795       assert (pkbuflen);
1796
1797       err = agent_write_private_key (grip, pkbuf, pkbuflen, 0);
1798       if (err)
1799         {
1800           log_error (_("error writing key: %s\n"), gpg_strerror (err));
1801           xfree (pkbuf);
1802           gcry_sexp_release (s_pk);
1803           xfree (serialno);
1804           xfree (authkeyid);
1805           return err;
1806         }
1807     }
1808
1809   if (cardsn)
1810     {
1811       char *dispsn;
1812
1813       /* If the card handler is able to return a short serialnumber,
1814          use that one, else use the complete serialno. */
1815       if (!agent_card_getattr (ctrl, "$DISPSERIALNO", &dispsn))
1816         {
1817           *cardsn = xtryasprintf ("cardno:%s", dispsn);
1818           xfree (dispsn);
1819         }
1820       else
1821         *cardsn = xtryasprintf ("cardno:%s", serialno);
1822       if (!*cardsn)
1823         {
1824           err = gpg_error_from_syserror ();
1825           xfree (pkbuf);
1826           gcry_sexp_release (s_pk);
1827           xfree (serialno);
1828           xfree (authkeyid);
1829           return err;
1830         }
1831     }
1832
1833   xfree (pkbuf);
1834   xfree (serialno);
1835   xfree (authkeyid);
1836   *r_pk = s_pk;
1837   return 0;
1838 }
1839
1840
1841 \f
1842
1843 /*
1844
1845   Request handler.  Each handler is provided with a CTRL context, a
1846   REQUEST object and a RESPONSE object.  The actual request is to be
1847   read from REQUEST, the response needs to be written to RESPONSE.
1848
1849 */
1850
1851
1852 /* Handler for the "request_identities" command.  */
1853 static gpg_error_t
1854 ssh_handler_request_identities (ctrl_t ctrl,
1855                                 estream_t request, estream_t response)
1856 {
1857   char *key_type;
1858   ssh_key_type_spec_t spec;
1859   struct dirent *dir_entry;
1860   char *key_directory;
1861   size_t key_directory_n;
1862   char *key_path;
1863   unsigned char *buffer;
1864   size_t buffer_n;
1865   u32 key_counter;
1866   estream_t key_blobs;
1867   gcry_sexp_t key_secret;
1868   gcry_sexp_t key_public;
1869   DIR *dir;
1870   gpg_error_t err;
1871   int ret;
1872   FILE *ctrl_fp = NULL;
1873   char *cardsn;
1874   gpg_error_t ret_err;
1875
1876   (void)request;
1877
1878   /* Prepare buffer stream.  */
1879
1880   key_directory = NULL;
1881   key_secret = NULL;
1882   key_public = NULL;
1883   key_type = NULL;
1884   key_path = NULL;
1885   key_counter = 0;
1886   buffer = NULL;
1887   dir = NULL;
1888   err = 0;
1889
1890   key_blobs = es_mopen (NULL, 0, 0, 1, NULL, NULL, "r+");
1891   if (! key_blobs)
1892     {
1893       err = gpg_error_from_syserror ();
1894       goto out;
1895     }
1896
1897   /* Open key directory.  */
1898   key_directory = make_filename (opt.homedir, GNUPG_PRIVATE_KEYS_DIR, NULL);
1899   if (! key_directory)
1900     {
1901       err = gpg_err_code_from_errno (errno);
1902       goto out;
1903     }
1904   key_directory_n = strlen (key_directory);
1905
1906   key_path = xtrymalloc (key_directory_n + 46);
1907   if (! key_path)
1908     {
1909       err = gpg_err_code_from_errno (errno);
1910       goto out;
1911     }
1912
1913   sprintf (key_path, "%s/", key_directory);
1914   sprintf (key_path + key_directory_n + 41, ".key");
1915
1916   dir = opendir (key_directory);
1917   if (! dir)
1918     {
1919       err = gpg_err_code_from_errno (errno);
1920       goto out;
1921     }
1922
1923
1924
1925   /* First check whether a key is currently available in the card
1926      reader - this should be allowed even without being listed in
1927      sshcontrol. */
1928
1929   if (!card_key_available (ctrl, &key_public, &cardsn))
1930     {
1931       err = ssh_send_key_public (key_blobs, key_public, cardsn);
1932       gcry_sexp_release (key_public);
1933       key_public = NULL;
1934       xfree (cardsn);
1935       if (err)
1936         goto out;
1937
1938       key_counter++;
1939     }
1940
1941
1942   /* Then look at all the registered an allowed keys. */
1943
1944
1945   /* Fixme: We should better iterate over the control file and check
1946      whether the key file is there.  This is better in resepct to
1947      performance if tehre are a lot of key sin our key storage. */
1948   /* FIXME: make sure that buffer gets deallocated properly.  */
1949   err = open_control_file (&ctrl_fp, 0);
1950   if (err)
1951     goto out;
1952
1953   while ( (dir_entry = readdir (dir)) )
1954     {
1955       if ((strlen (dir_entry->d_name) == 44)
1956           && (! strncmp (dir_entry->d_name + 40, ".key", 4)))
1957         {
1958           char hexgrip[41];
1959           int disabled;
1960
1961           /* We do only want to return keys listed in our control
1962              file. */
1963           strncpy (hexgrip, dir_entry->d_name, 40);
1964           hexgrip[40] = 0;
1965           if ( strlen (hexgrip) != 40 )
1966             continue;
1967           if (search_control_file (ctrl_fp, hexgrip, &disabled, NULL, NULL)
1968               || disabled)
1969             continue;
1970
1971           strncpy (key_path + key_directory_n + 1, dir_entry->d_name, 40);
1972
1973           /* Read file content.  */
1974           err = file_to_buffer (key_path, &buffer, &buffer_n);
1975           if (err)
1976             goto out;
1977
1978           err = gcry_sexp_sscan (&key_secret, NULL, (char*)buffer, buffer_n);
1979           if (err)
1980             goto out;
1981
1982           xfree (buffer);
1983           buffer = NULL;
1984
1985           err = sexp_extract_identifier (key_secret, &key_type);
1986           if (err)
1987             goto out;
1988
1989           err = ssh_key_type_lookup (NULL, key_type, &spec);
1990           if (err)
1991             goto out;
1992
1993           xfree (key_type);
1994           key_type = NULL;
1995
1996           err = key_secret_to_public (&key_public, spec, key_secret);
1997           if (err)
1998             goto out;
1999
2000           gcry_sexp_release (key_secret);
2001           key_secret = NULL;
2002
2003           err = ssh_send_key_public (key_blobs, key_public, NULL);
2004           if (err)
2005             goto out;
2006
2007           gcry_sexp_release (key_public);
2008           key_public = NULL;
2009
2010           key_counter++;
2011         }
2012     }
2013
2014   ret = es_fseek (key_blobs, 0, SEEK_SET);
2015   if (ret)
2016     {
2017       err = gpg_error_from_syserror ();
2018       goto out;
2019     }
2020
2021  out:
2022
2023   /* Send response.  */
2024
2025   gcry_sexp_release (key_secret);
2026   gcry_sexp_release (key_public);
2027
2028   if (! err)
2029     {
2030       ret_err = stream_write_byte (response, SSH_RESPONSE_IDENTITIES_ANSWER);
2031       if (ret_err)
2032         goto leave;
2033       ret_err = stream_write_uint32 (response, key_counter);
2034       if (ret_err)
2035         goto leave;
2036       ret_err = stream_copy (response, key_blobs);
2037       if (ret_err)
2038         goto leave;
2039     }
2040   else
2041     {
2042       ret_err = stream_write_byte (response, SSH_RESPONSE_FAILURE);
2043       goto leave;
2044     };
2045
2046  leave:
2047
2048   if (key_blobs)
2049     es_fclose (key_blobs);
2050   if (dir)
2051     closedir (dir);
2052
2053   if (ctrl_fp)
2054     fclose (ctrl_fp);
2055
2056   xfree (key_directory);
2057   xfree (key_path);
2058   xfree (buffer);
2059   xfree (key_type);
2060
2061   return ret_err;
2062 }
2063
2064
2065 /* This function hashes the data contained in DATA of size DATA_N
2066    according to the message digest algorithm specified by MD_ALGORITHM
2067    and writes the message digest to HASH, which needs to large enough
2068    for the digest.  */
2069 static gpg_error_t
2070 data_hash (unsigned char *data, size_t data_n,
2071            int md_algorithm, unsigned char *hash)
2072 {
2073   gcry_md_hash_buffer (md_algorithm, hash, data, data_n);
2074
2075   return 0;
2076 }
2077
2078 /* This function signs the data contained in CTRL, stores the created
2079    signature in newly allocated memory in SIG and it's size in SIG_N;
2080    SIG_ENCODER is the signature encoder to use.  */
2081 static gpg_error_t
2082 data_sign (ctrl_t ctrl, ssh_signature_encoder_t sig_encoder,
2083            unsigned char **sig, size_t *sig_n)
2084 {
2085   gpg_error_t err;
2086   gcry_sexp_t signature_sexp = NULL;
2087   estream_t stream = NULL;
2088   gcry_sexp_t valuelist = NULL;
2089   gcry_sexp_t sublist = NULL;
2090   gcry_mpi_t sig_value = NULL;
2091   unsigned char *sig_blob = NULL;
2092   size_t sig_blob_n = 0;
2093   char *identifier = NULL;
2094   const char *identifier_raw;
2095   size_t identifier_n;
2096   ssh_key_type_spec_t spec;
2097   int ret;
2098   unsigned int i;
2099   const char *elems;
2100   size_t elems_n;
2101   gcry_mpi_t *mpis = NULL;
2102   char hexgrip[40+1];
2103
2104   *sig = NULL;
2105   *sig_n = 0;
2106
2107   /* Quick check to see whether we have a valid keygrip and convert it
2108      to hex.  */
2109   if (!ctrl->have_keygrip)
2110     {
2111       err = gpg_error (GPG_ERR_NO_SECKEY);
2112       goto out;
2113     }
2114   bin2hex (ctrl->keygrip, 20, hexgrip);
2115
2116   /* Ask for confirmation if needed.  */
2117   if (confirm_flag_from_sshcontrol (hexgrip))
2118     {
2119       gcry_sexp_t key;
2120       char *fpr, *prompt;
2121       char *comment = NULL;
2122
2123       err = agent_raw_key_from_file (ctrl, ctrl->keygrip, &key);
2124       if (err)
2125         goto out;
2126       err = ssh_get_fingerprint_string (key, &fpr);
2127       if (!err)
2128         {
2129           gcry_sexp_t tmpsxp = gcry_sexp_find_token (key, "comment", 0);
2130           if (tmpsxp)
2131             comment = gcry_sexp_nth_string (tmpsxp, 1);
2132           gcry_sexp_release (tmpsxp);
2133         }
2134       gcry_sexp_release (key);
2135       if (err)
2136         goto out;
2137       prompt = xtryasprintf (_("An ssh process requested the use of key%%0A"
2138                                "  %s%%0A"
2139                                "  (%s)%%0A"
2140                                "Do you want to allow this?"),
2141                              fpr, comment? comment:"");
2142       xfree (fpr);
2143       gcry_free (comment);
2144       err = agent_get_confirmation (ctrl, prompt, _("Allow"), _("Deny"), 0);
2145       xfree (prompt);
2146       if (err)
2147         goto out;
2148     }
2149
2150   /* Create signature.  */
2151   ctrl->use_auth_call = 1;
2152   err = agent_pksign_do (ctrl, NULL,
2153                          _("Please enter the passphrase "
2154                            "for the ssh key%%0A  %F%%0A  (%c)"),
2155                          &signature_sexp,
2156                          CACHE_MODE_SSH, ttl_from_sshcontrol);
2157   ctrl->use_auth_call = 0;
2158   if (err)
2159     goto out;
2160
2161   valuelist = gcry_sexp_nth (signature_sexp, 1);
2162   if (! valuelist)
2163     {
2164       err = gpg_error (GPG_ERR_INV_SEXP);
2165       goto out;
2166     }
2167
2168   stream = es_mopen (NULL, 0, 0, 1, NULL, NULL, "r+");
2169   if (! stream)
2170     {
2171       err = gpg_error_from_syserror ();
2172       goto out;
2173     }
2174
2175   identifier_raw = gcry_sexp_nth_data (valuelist, 0, &identifier_n);
2176   if (! identifier_raw)
2177     {
2178       err = gpg_error (GPG_ERR_INV_SEXP);
2179       goto out;
2180     }
2181
2182   identifier = make_cstring (identifier_raw, identifier_n);
2183   if (! identifier)
2184     {
2185       err = gpg_error_from_syserror ();
2186       goto out;
2187     }
2188
2189   err = ssh_key_type_lookup (NULL, identifier, &spec);
2190   if (err)
2191     goto out;
2192
2193   err = stream_write_cstring (stream, spec.ssh_identifier);
2194   if (err)
2195     goto out;
2196
2197   elems = spec.elems_signature;
2198   elems_n = strlen (elems);
2199
2200   mpis = xtrycalloc (elems_n + 1, sizeof *mpis);
2201   if (!mpis)
2202     {
2203       err = gpg_error_from_syserror ();
2204       goto out;
2205     }
2206
2207   for (i = 0; i < elems_n; i++)
2208     {
2209       sublist = gcry_sexp_find_token (valuelist, spec.elems_signature + i, 1);
2210       if (! sublist)
2211         {
2212           err = gpg_error (GPG_ERR_INV_SEXP);
2213           break;
2214         }
2215
2216       sig_value = gcry_sexp_nth_mpi (sublist, 1, GCRYMPI_FMT_USG);
2217       if (! sig_value)
2218         {
2219           err = gpg_error (GPG_ERR_INTERNAL); /* FIXME?  */
2220           break;
2221         }
2222       gcry_sexp_release (sublist);
2223       sublist = NULL;
2224
2225       mpis[i] = sig_value;
2226     }
2227   if (err)
2228     goto out;
2229
2230   err = (*sig_encoder) (stream, mpis);
2231   if (err)
2232     goto out;
2233
2234   sig_blob_n = es_ftell (stream);
2235   if (sig_blob_n == -1)
2236     {
2237       err = gpg_error_from_syserror ();
2238       goto out;
2239     }
2240
2241   sig_blob = xtrymalloc (sig_blob_n);
2242   if (! sig_blob)
2243     {
2244       err = gpg_error_from_syserror ();
2245       goto out;
2246     }
2247
2248   ret = es_fseek (stream, 0, SEEK_SET);
2249   if (ret)
2250     {
2251       err = gpg_error_from_syserror ();
2252       goto out;
2253     }
2254
2255   err = stream_read_data (stream, sig_blob, sig_blob_n);
2256   if (err)
2257     goto out;
2258
2259   *sig = sig_blob;
2260   *sig_n = sig_blob_n;
2261
2262  out:
2263
2264   if (err)
2265     xfree (sig_blob);
2266
2267   if (stream)
2268     es_fclose (stream);
2269   gcry_sexp_release (valuelist);
2270   gcry_sexp_release (signature_sexp);
2271   gcry_sexp_release (sublist);
2272   mpint_list_free (mpis);
2273   xfree (identifier);
2274
2275   return err;
2276 }
2277
2278 /* Handler for the "sign_request" command.  */
2279 static gpg_error_t
2280 ssh_handler_sign_request (ctrl_t ctrl, estream_t request, estream_t response)
2281 {
2282   gcry_sexp_t key;
2283   ssh_key_type_spec_t spec;
2284   unsigned char hash[MAX_DIGEST_LEN];
2285   unsigned int hash_n;
2286   unsigned char key_grip[20];
2287   unsigned char *key_blob;
2288   u32 key_blob_size;
2289   unsigned char *data;
2290   unsigned char *sig;
2291   size_t sig_n;
2292   u32 data_size;
2293   u32 flags;
2294   gpg_error_t err;
2295   gpg_error_t ret_err;
2296
2297   key_blob = NULL;
2298   data = NULL;
2299   sig = NULL;
2300   key = NULL;
2301
2302   /* Receive key.  */
2303
2304   err = stream_read_string (request, 0, &key_blob, &key_blob_size);
2305   if (err)
2306     goto out;
2307
2308   err = ssh_read_key_public_from_blob (key_blob, key_blob_size, &key, &spec);
2309   if (err)
2310     goto out;
2311
2312   /* Receive data to sign.  */
2313   err = stream_read_string (request, 0, &data, &data_size);
2314   if (err)
2315     goto out;
2316
2317   /* FIXME?  */
2318   err = stream_read_uint32 (request, &flags);
2319   if (err)
2320     goto out;
2321
2322   /* Hash data.  */
2323   hash_n = gcry_md_get_algo_dlen (GCRY_MD_SHA1);
2324   if (! hash_n)
2325     {
2326       err = gpg_error (GPG_ERR_INTERNAL);
2327       goto out;
2328     }
2329   err = data_hash (data, data_size, GCRY_MD_SHA1, hash);
2330   if (err)
2331     goto out;
2332
2333   /* Calculate key grip.  */
2334   err = ssh_key_grip (key, key_grip);
2335   if (err)
2336     goto out;
2337
2338   /* Sign data.  */
2339
2340   ctrl->digest.algo = GCRY_MD_SHA1;
2341   memcpy (ctrl->digest.value, hash, hash_n);
2342   ctrl->digest.valuelen = hash_n;
2343   ctrl->digest.raw_value = ! (spec.flags & SPEC_FLAG_USE_PKCS1V2);
2344   ctrl->have_keygrip = 1;
2345   memcpy (ctrl->keygrip, key_grip, 20);
2346
2347   err = data_sign (ctrl, spec.signature_encoder, &sig, &sig_n);
2348
2349  out:
2350
2351   /* Done.  */
2352
2353   if (! err)
2354     {
2355       ret_err = stream_write_byte (response, SSH_RESPONSE_SIGN_RESPONSE);
2356       if (ret_err)
2357         goto leave;
2358       ret_err = stream_write_string (response, sig, sig_n);
2359       if (ret_err)
2360         goto leave;
2361     }
2362   else
2363     {
2364       ret_err = stream_write_byte (response, SSH_RESPONSE_FAILURE);
2365       if (ret_err)
2366         goto leave;
2367     }
2368
2369  leave:
2370
2371   gcry_sexp_release (key);
2372   xfree (key_blob);
2373   xfree (data);
2374   xfree (sig);
2375
2376   return ret_err;
2377 }
2378
2379 /* This function extracts the comment contained in the key
2380    S-Expression KEY and stores a copy in COMMENT.  Returns usual error
2381    code.  */
2382 static gpg_error_t
2383 ssh_key_extract_comment (gcry_sexp_t key, char **comment)
2384 {
2385   gcry_sexp_t comment_list;
2386   char *comment_new;
2387   const char *data;
2388   size_t data_n;
2389   gpg_error_t err;
2390
2391   comment_list = gcry_sexp_find_token (key, "comment", 0);
2392   if (! comment_list)
2393     {
2394       err = gpg_error (GPG_ERR_INV_SEXP);
2395       goto out;
2396     }
2397
2398   data = gcry_sexp_nth_data (comment_list, 1, &data_n);
2399   if (! data)
2400     {
2401       err = gpg_error (GPG_ERR_INV_SEXP);
2402       goto out;
2403     }
2404
2405   comment_new = make_cstring (data, data_n);
2406   if (! comment_new)
2407     {
2408       err = gpg_error_from_syserror ();
2409       goto out;
2410     }
2411
2412   *comment = comment_new;
2413   err = 0;
2414
2415  out:
2416
2417   gcry_sexp_release (comment_list);
2418
2419   return err;
2420 }
2421
2422 /* This function converts the key contained in the S-Expression KEY
2423    into a buffer, which is protected by the passphrase PASSPHRASE.
2424    Returns usual error code.  */
2425 static gpg_error_t
2426 ssh_key_to_protected_buffer (gcry_sexp_t key, const char *passphrase,
2427                              unsigned char **buffer, size_t *buffer_n)
2428 {
2429   unsigned char *buffer_new;
2430   unsigned int buffer_new_n;
2431   gpg_error_t err;
2432
2433   err = 0;
2434   buffer_new_n = gcry_sexp_sprint (key, GCRYSEXP_FMT_CANON, NULL, 0);
2435   buffer_new = xtrymalloc_secure (buffer_new_n);
2436   if (! buffer_new)
2437     {
2438       err = gpg_error_from_syserror ();
2439       goto out;
2440     }
2441
2442   gcry_sexp_sprint (key, GCRYSEXP_FMT_CANON, buffer_new, buffer_new_n);
2443   /* FIXME: guarantee?  */
2444
2445   err = agent_protect (buffer_new, passphrase, buffer, buffer_n, 0);
2446
2447  out:
2448
2449   xfree (buffer_new);
2450
2451   return err;
2452 }
2453
2454
2455
2456 /* Callback function to compare the first entered PIN with the one
2457    currently being entered. */
2458 static int
2459 reenter_compare_cb (struct pin_entry_info_s *pi)
2460 {
2461   const char *pin1 = pi->check_cb_arg;
2462
2463   if (!strcmp (pin1, pi->pin))
2464     return 0; /* okay */
2465   return -1;
2466 }
2467
2468 /* Store the ssh KEY into our local key storage and protect it after
2469    asking for a passphrase.  Cache that passphrase.  TTL is the
2470    maximum caching time for that key.  If the key already exists in
2471    our key storage, don't do anything.  When entering a new key also
2472    add an entry to the sshcontrol file.  */
2473 static gpg_error_t
2474 ssh_identity_register (ctrl_t ctrl, gcry_sexp_t key, int ttl, int confirm)
2475 {
2476   gpg_error_t err;
2477   unsigned char key_grip_raw[20];
2478   char key_grip[41];
2479   unsigned char *buffer = NULL;
2480   size_t buffer_n;
2481   char *description = NULL;
2482   const char *description2 = _("Please re-enter this passphrase");
2483   char *comment = NULL;
2484   char *key_fpr = NULL;
2485   const char *initial_errtext = NULL;
2486   unsigned int i;
2487   struct pin_entry_info_s *pi = NULL, *pi2;
2488
2489   err = ssh_key_grip (key, key_grip_raw);
2490   if (err)
2491     goto out;
2492
2493   /* Check whether the key is already in our key storage.  Don't do
2494      anything then.  */
2495   if ( !agent_key_available (key_grip_raw) )
2496     goto out; /* Yes, key is available.  */
2497
2498   err = ssh_get_fingerprint_string (key, &key_fpr);
2499   if (err)
2500     goto out;
2501
2502   err = ssh_key_extract_comment (key, &comment);
2503   if (err)
2504     goto out;
2505
2506   if ( asprintf (&description,
2507                  _("Please enter a passphrase to protect"
2508                    " the received secret key%%0A"
2509                    "   %s%%0A"
2510                    "   %s%%0A"
2511                    "within gpg-agent's key storage"),
2512                  key_fpr, comment ? comment : "") < 0)
2513     {
2514       err = gpg_error_from_syserror ();
2515       goto out;
2516     }
2517
2518
2519   pi = gcry_calloc_secure (2, sizeof (*pi) + 100 + 1);
2520   if (!pi)
2521     {
2522       err = gpg_error_from_syserror ();
2523       goto out;
2524     }
2525   pi2 = pi + (sizeof *pi + 100 + 1);
2526   pi->max_length = 100;
2527   pi->max_tries = 1;
2528   pi2->max_length = 100;
2529   pi2->max_tries = 1;
2530   pi2->check_cb = reenter_compare_cb;
2531   pi2->check_cb_arg = pi->pin;
2532
2533  next_try:
2534   err = agent_askpin (ctrl, description, NULL, initial_errtext, pi);
2535   initial_errtext = NULL;
2536   if (err)
2537     goto out;
2538
2539   /* Unless the passphrase is empty, ask to confirm it.  */
2540   if (pi->pin && *pi->pin)
2541     {
2542       err = agent_askpin (ctrl, description2, NULL, NULL, pi2);
2543       if (err == -1)
2544         { /* The re-entered one did not match and the user did not
2545              hit cancel. */
2546           initial_errtext = _("does not match - try again");
2547           goto next_try;
2548         }
2549     }
2550
2551   err = ssh_key_to_protected_buffer (key, pi->pin, &buffer, &buffer_n);
2552   if (err)
2553     goto out;
2554
2555   /* Store this key to our key storage.  */
2556   err = agent_write_private_key (key_grip_raw, buffer, buffer_n, 0);
2557   if (err)
2558     goto out;
2559
2560   /* Cache this passphrase. */
2561   for (i = 0; i < 20; i++)
2562     sprintf (key_grip + 2 * i, "%02X", key_grip_raw[i]);
2563
2564   err = agent_put_cache (key_grip, CACHE_MODE_SSH, pi->pin, ttl);
2565   if (err)
2566     goto out;
2567
2568   /* And add an entry to the sshcontrol file.  */
2569   err = add_control_entry (ctrl, key_grip, key_fpr, ttl, confirm);
2570
2571
2572  out:
2573   if (pi && pi->max_length)
2574     wipememory (pi->pin, pi->max_length);
2575   xfree (pi);
2576   xfree (buffer);
2577   xfree (comment);
2578   xfree (key_fpr);
2579   xfree (description);
2580
2581   return err;
2582 }
2583
2584
2585 /* This function removes the key contained in the S-Expression KEY
2586    from the local key storage, in case it exists there.  Returns usual
2587    error code.  FIXME: this function is a stub.  */
2588 static gpg_error_t
2589 ssh_identity_drop (gcry_sexp_t key)
2590 {
2591   unsigned char key_grip[21] = { 0 };
2592   gpg_error_t err;
2593
2594   err = ssh_key_grip (key, key_grip);
2595   if (err)
2596     goto out;
2597
2598   key_grip[sizeof (key_grip) - 1] = 0;
2599
2600   /* FIXME: What to do here - forgetting the passphrase or deleting
2601      the key from key cache?  */
2602
2603  out:
2604
2605   return err;
2606 }
2607
2608 /* Handler for the "add_identity" command.  */
2609 static gpg_error_t
2610 ssh_handler_add_identity (ctrl_t ctrl, estream_t request, estream_t response)
2611 {
2612   gpg_error_t ret_err;
2613   gpg_error_t err;
2614   gcry_sexp_t key;
2615   unsigned char b;
2616   int confirm;
2617   int ttl;
2618
2619   confirm = 0;
2620   key = NULL;
2621   ttl = 0;
2622
2623   /* FIXME?  */
2624   err = ssh_receive_key (request, &key, 1, 1, NULL);
2625   if (err)
2626     goto out;
2627
2628   while (1)
2629     {
2630       err = stream_read_byte (request, &b);
2631       if (gpg_err_code (err) == GPG_ERR_EOF)
2632         {
2633           err = 0;
2634           break;
2635         }
2636
2637       switch (b)
2638         {
2639         case SSH_OPT_CONSTRAIN_LIFETIME:
2640           {
2641             u32 n = 0;
2642
2643             err = stream_read_uint32 (request, &n);
2644             if (! err)
2645               ttl = n;
2646             break;
2647           }
2648
2649         case SSH_OPT_CONSTRAIN_CONFIRM:
2650           {
2651             confirm = 1;
2652             break;
2653           }
2654
2655         default:
2656           /* FIXME: log/bad?  */
2657           break;
2658         }
2659     }
2660   if (err)
2661     goto out;
2662
2663   err = ssh_identity_register (ctrl, key, ttl, confirm);
2664
2665  out:
2666
2667   gcry_sexp_release (key);
2668
2669   if (! err)
2670     ret_err = stream_write_byte (response, SSH_RESPONSE_SUCCESS);
2671   else
2672     ret_err = stream_write_byte (response, SSH_RESPONSE_FAILURE);
2673
2674   return ret_err;
2675 }
2676
2677 /* Handler for the "remove_identity" command.  */
2678 static gpg_error_t
2679 ssh_handler_remove_identity (ctrl_t ctrl,
2680                              estream_t request, estream_t response)
2681 {
2682   unsigned char *key_blob;
2683   u32 key_blob_size;
2684   gcry_sexp_t key;
2685   gpg_error_t ret_err;
2686   gpg_error_t err;
2687
2688   (void)ctrl;
2689
2690   /* Receive key.  */
2691
2692   key_blob = NULL;
2693   key = NULL;
2694
2695   err = stream_read_string (request, 0, &key_blob, &key_blob_size);
2696   if (err)
2697     goto out;
2698
2699   err = ssh_read_key_public_from_blob (key_blob, key_blob_size, &key, NULL);
2700   if (err)
2701     goto out;
2702
2703   err = ssh_identity_drop (key);
2704
2705  out:
2706
2707   xfree (key_blob);
2708   gcry_sexp_release (key);
2709
2710   if (! err)
2711     ret_err = stream_write_byte (response, SSH_RESPONSE_SUCCESS);
2712   else
2713     ret_err = stream_write_byte (response, SSH_RESPONSE_FAILURE);
2714
2715   return ret_err;
2716 }
2717
2718 /* FIXME: stub function.  Actually useful?  */
2719 static gpg_error_t
2720 ssh_identities_remove_all (void)
2721 {
2722   gpg_error_t err;
2723
2724   err = 0;
2725
2726   /* FIXME: shall we remove _all_ cache entries or only those
2727      registered through the ssh emulation?  */
2728
2729   return err;
2730 }
2731
2732 /* Handler for the "remove_all_identities" command.  */
2733 static gpg_error_t
2734 ssh_handler_remove_all_identities (ctrl_t ctrl,
2735                                    estream_t request, estream_t response)
2736 {
2737   gpg_error_t ret_err;
2738   gpg_error_t err;
2739
2740   (void)ctrl;
2741   (void)request;
2742
2743   err = ssh_identities_remove_all ();
2744
2745   if (! err)
2746     ret_err = stream_write_byte (response, SSH_RESPONSE_SUCCESS);
2747   else
2748     ret_err = stream_write_byte (response, SSH_RESPONSE_FAILURE);
2749
2750   return ret_err;
2751 }
2752
2753 /* Lock agent?  FIXME: stub function.  */
2754 static gpg_error_t
2755 ssh_lock (void)
2756 {
2757   gpg_error_t err;
2758
2759   /* FIXME */
2760   log_error ("ssh-agent's lock command is not implemented\n");
2761   err = 0;
2762
2763   return err;
2764 }
2765
2766 /* Unock agent?  FIXME: stub function.  */
2767 static gpg_error_t
2768 ssh_unlock (void)
2769 {
2770   gpg_error_t err;
2771
2772   log_error ("ssh-agent's unlock command is not implemented\n");
2773   err = 0;
2774
2775   return err;
2776 }
2777
2778 /* Handler for the "lock" command.  */
2779 static gpg_error_t
2780 ssh_handler_lock (ctrl_t ctrl, estream_t request, estream_t response)
2781 {
2782   gpg_error_t ret_err;
2783   gpg_error_t err;
2784
2785   (void)ctrl;
2786   (void)request;
2787
2788   err = ssh_lock ();
2789
2790   if (! err)
2791     ret_err = stream_write_byte (response, SSH_RESPONSE_SUCCESS);
2792   else
2793     ret_err = stream_write_byte (response, SSH_RESPONSE_FAILURE);
2794
2795   return ret_err;
2796 }
2797
2798 /* Handler for the "unlock" command.  */
2799 static gpg_error_t
2800 ssh_handler_unlock (ctrl_t ctrl, estream_t request, estream_t response)
2801 {
2802   gpg_error_t ret_err;
2803   gpg_error_t err;
2804
2805   (void)ctrl;
2806   (void)request;
2807
2808   err = ssh_unlock ();
2809
2810   if (! err)
2811     ret_err = stream_write_byte (response, SSH_RESPONSE_SUCCESS);
2812   else
2813     ret_err = stream_write_byte (response, SSH_RESPONSE_FAILURE);
2814
2815   return ret_err;
2816 }
2817
2818 \f
2819
2820 /* Return the request specification for the request identified by TYPE
2821    or NULL in case the requested request specification could not be
2822    found.  */
2823 static ssh_request_spec_t *
2824 request_spec_lookup (int type)
2825 {
2826   ssh_request_spec_t *spec;
2827   unsigned int i;
2828
2829   for (i = 0; i < DIM (request_specs); i++)
2830     if (request_specs[i].type == type)
2831       break;
2832   if (i == DIM (request_specs))
2833     {
2834       if (opt.verbose)
2835         log_info ("ssh request %u is not supported\n", type);
2836       spec = NULL;
2837     }
2838   else
2839     spec = request_specs + i;
2840
2841   return spec;
2842 }
2843
2844 /* Process a single request.  The request is read from and the
2845    response is written to STREAM_SOCK.  Uses CTRL as context.  Returns
2846    zero in case of success, non zero in case of failure.  */
2847 static int
2848 ssh_request_process (ctrl_t ctrl, estream_t stream_sock)
2849 {
2850   ssh_request_spec_t *spec;
2851   estream_t response;
2852   estream_t request;
2853   unsigned char request_type;
2854   gpg_error_t err;
2855   int send_err;
2856   int ret;
2857   unsigned char *request_data;
2858   u32 request_data_size;
2859   u32 response_size;
2860
2861   request_data = NULL;
2862   response = NULL;
2863   request = NULL;
2864   send_err = 0;
2865
2866   /* Create memory streams for request/response data.  The entire
2867      request will be stored in secure memory, since it might contain
2868      secret key material.  The response does not have to be stored in
2869      secure memory, since we never give out secret keys.
2870
2871      Note: we only have little secure memory, but there is NO
2872      possibility of DoS here; only trusted clients are allowed to
2873      connect to the agent.  What could happen is that the agent
2874      returns out-of-secure-memory errors on requests in case the
2875      agent's owner floods his own agent with many large messages.
2876      -moritz */
2877
2878   /* Retrieve request.  */
2879   err = stream_read_string (stream_sock, 1, &request_data, &request_data_size);
2880   if (err)
2881     goto out;
2882
2883   if (opt.verbose > 1)
2884     log_info ("received ssh request of length %u\n",
2885               (unsigned int)request_data_size);
2886
2887   if (! request_data_size)
2888     {
2889       send_err = 1;
2890       goto out;
2891       /* Broken request; FIXME.  */
2892     }
2893
2894   request_type = request_data[0];
2895   spec = request_spec_lookup (request_type);
2896   if (! spec)
2897     {
2898       send_err = 1;
2899       goto out;
2900       /* Unknown request; FIXME.  */
2901     }
2902
2903   if (spec->secret_input)
2904     request = es_mopen (NULL, 0, 0, 1, realloc_secure, gcry_free, "r+");
2905   else
2906     request = es_mopen (NULL, 0, 0, 1, gcry_realloc, gcry_free, "r+");
2907   if (! request)
2908     {
2909       err = gpg_error_from_syserror ();
2910       goto out;
2911     }
2912   ret = es_setvbuf (request, NULL, _IONBF, 0);
2913   if (ret)
2914     {
2915       err = gpg_error_from_syserror ();
2916       goto out;
2917     }
2918   err = stream_write_data (request, request_data + 1, request_data_size - 1);
2919   if (err)
2920     goto out;
2921   es_rewind (request);
2922
2923   response = es_mopen (NULL, 0, 0, 1, NULL, NULL, "r+");
2924   if (! response)
2925     {
2926       err = gpg_error_from_syserror ();
2927       goto out;
2928     }
2929
2930   if (opt.verbose)
2931     log_info ("ssh request handler for %s (%u) started\n",
2932                spec->identifier, spec->type);
2933
2934   err = (*spec->handler) (ctrl, request, response);
2935
2936   if (opt.verbose)
2937     {
2938       if (err)
2939         log_info ("ssh request handler for %s (%u) failed: %s\n",
2940                   spec->identifier, spec->type, gpg_strerror (err));
2941       else
2942         log_info ("ssh request handler for %s (%u) ready\n",
2943                   spec->identifier, spec->type);
2944     }
2945
2946   if (err)
2947     {
2948       send_err = 1;
2949       goto out;
2950     }
2951
2952   response_size = es_ftell (response);
2953   if (opt.verbose > 1)
2954     log_info ("sending ssh response of length %u\n",
2955               (unsigned int)response_size);
2956
2957   err = es_fseek (response, 0, SEEK_SET);
2958   if (err)
2959     {
2960       send_err = 1;
2961       goto out;
2962     }
2963
2964   err = stream_write_uint32 (stream_sock, response_size);
2965   if (err)
2966     {
2967       send_err = 1;
2968       goto out;
2969     }
2970
2971   err = stream_copy (stream_sock, response);
2972   if (err)
2973     goto out;
2974
2975   err = es_fflush (stream_sock);
2976   if (err)
2977     goto out;
2978
2979  out:
2980
2981   if (err && es_feof (stream_sock))
2982     log_error ("error occured while processing request: %s\n",
2983                gpg_strerror (err));
2984
2985   if (send_err)
2986     {
2987       if (opt.verbose > 1)
2988         log_info ("sending ssh error response\n");
2989       err = stream_write_uint32 (stream_sock, 1);
2990       if (err)
2991         goto leave;
2992       err = stream_write_byte (stream_sock, SSH_RESPONSE_FAILURE);
2993       if (err)
2994         goto leave;
2995     }
2996
2997  leave:
2998
2999   if (request)
3000     es_fclose (request);
3001   if (response)
3002     es_fclose (response);
3003   xfree (request_data);         /* FIXME?  */
3004
3005   return !!err;
3006 }
3007
3008 /* Start serving client on SOCK_CLIENT.  */
3009 void
3010 start_command_handler_ssh (ctrl_t ctrl, gnupg_fd_t sock_client)
3011 {
3012   estream_t stream_sock = NULL;
3013   gpg_error_t err = 0;
3014   int ret;
3015
3016   /* Because the ssh protocol does not send us information about the
3017      the current TTY setting, we resort here to use those from startup
3018      or those explictly set.  */
3019   {
3020     static const char *names[] =
3021       {"GPG_TTY", "DISPLAY", "TERM", "XAUTHORITY", "PINENTRY_USER_DATA", NULL};
3022     int idx;
3023     const char *value;
3024
3025     for (idx=0; !err && names[idx]; idx++)
3026       if (!session_env_getenv (ctrl->session_env, names[idx])
3027           && (value = session_env_getenv (opt.startup_env, names[idx])))
3028         err = session_env_setenv (ctrl->session_env, names[idx], value);
3029
3030     if (!err && !ctrl->lc_ctype && opt.startup_lc_ctype)
3031       if (!(ctrl->lc_ctype = xtrystrdup (opt.startup_lc_ctype)))
3032         err = gpg_error_from_syserror ();
3033
3034     if (!err && !ctrl->lc_messages && opt.startup_lc_messages)
3035       if (!(ctrl->lc_messages = xtrystrdup (opt.startup_lc_messages)))
3036         err = gpg_error_from_syserror ();
3037
3038     if (err)
3039       {
3040         log_error ("error setting default session environment: %s\n",
3041                    gpg_strerror (err));
3042         goto out;
3043       }
3044   }
3045
3046
3047   /* Create stream from socket.  */
3048   stream_sock = es_fdopen (FD2INT(sock_client), "r+");
3049   if (!stream_sock)
3050     {
3051       err = gpg_error_from_syserror ();
3052       log_error (_("failed to create stream from socket: %s\n"),
3053                  gpg_strerror (err));
3054       goto out;
3055     }
3056   /* We have to disable the estream buffering, because the estream
3057      core doesn't know about secure memory.  */
3058   ret = es_setvbuf (stream_sock, NULL, _IONBF, 0);
3059   if (ret)
3060     {
3061       err = gpg_error_from_syserror ();
3062       log_error ("failed to disable buffering "
3063                  "on socket stream: %s\n", gpg_strerror (err));
3064       goto out;
3065     }
3066
3067   /* Main processing loop. */
3068   while ( !ssh_request_process (ctrl, stream_sock) )
3069     {
3070       /* Check wether we have reached EOF before trying to read
3071          another request.  */
3072       int c;
3073
3074       c = es_fgetc (stream_sock);
3075       if (c == EOF)
3076         break;
3077       es_ungetc (c, stream_sock);
3078     }
3079
3080   /* Reset the SCD in case it has been used. */
3081   agent_reset_scd (ctrl);
3082
3083
3084  out:
3085   if (stream_sock)
3086     es_fclose (stream_sock);
3087 }