agent: Add pin length field to the shadowed private key format.
[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 (_("no authentication key for ssh on 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 (!opt.disable_scdaemon
1928       && !card_key_available (ctrl, &key_public, &cardsn))
1929     {
1930       err = ssh_send_key_public (key_blobs, key_public, cardsn);
1931       gcry_sexp_release (key_public);
1932       key_public = NULL;
1933       xfree (cardsn);
1934       if (err)
1935         goto out;
1936
1937       key_counter++;
1938     }
1939
1940
1941   /* Then look at all the registered an allowed keys. */
1942
1943
1944   /* Fixme: We should better iterate over the control file and check
1945      whether the key file is there.  This is better in resepct to
1946      performance if tehre are a lot of key sin our key storage. */
1947   /* FIXME: make sure that buffer gets deallocated properly.  */
1948   err = open_control_file (&ctrl_fp, 0);
1949   if (err)
1950     goto out;
1951
1952   while ( (dir_entry = readdir (dir)) )
1953     {
1954       if ((strlen (dir_entry->d_name) == 44)
1955           && (! strncmp (dir_entry->d_name + 40, ".key", 4)))
1956         {
1957           char hexgrip[41];
1958           int disabled;
1959
1960           /* We do only want to return keys listed in our control
1961              file. */
1962           strncpy (hexgrip, dir_entry->d_name, 40);
1963           hexgrip[40] = 0;
1964           if ( strlen (hexgrip) != 40 )
1965             continue;
1966           if (search_control_file (ctrl_fp, hexgrip, &disabled, NULL, NULL)
1967               || disabled)
1968             continue;
1969
1970           strncpy (key_path + key_directory_n + 1, dir_entry->d_name, 40);
1971
1972           /* Read file content.  */
1973           err = file_to_buffer (key_path, &buffer, &buffer_n);
1974           if (err)
1975             goto out;
1976
1977           err = gcry_sexp_sscan (&key_secret, NULL, (char*)buffer, buffer_n);
1978           if (err)
1979             goto out;
1980
1981           xfree (buffer);
1982           buffer = NULL;
1983
1984           err = sexp_extract_identifier (key_secret, &key_type);
1985           if (err)
1986             goto out;
1987
1988           err = ssh_key_type_lookup (NULL, key_type, &spec);
1989           if (err)
1990             goto out;
1991
1992           xfree (key_type);
1993           key_type = NULL;
1994
1995           err = key_secret_to_public (&key_public, spec, key_secret);
1996           if (err)
1997             goto out;
1998
1999           gcry_sexp_release (key_secret);
2000           key_secret = NULL;
2001
2002           err = ssh_send_key_public (key_blobs, key_public, NULL);
2003           if (err)
2004             goto out;
2005
2006           gcry_sexp_release (key_public);
2007           key_public = NULL;
2008
2009           key_counter++;
2010         }
2011     }
2012
2013   ret = es_fseek (key_blobs, 0, SEEK_SET);
2014   if (ret)
2015     {
2016       err = gpg_error_from_syserror ();
2017       goto out;
2018     }
2019
2020  out:
2021
2022   /* Send response.  */
2023
2024   gcry_sexp_release (key_secret);
2025   gcry_sexp_release (key_public);
2026
2027   if (! err)
2028     {
2029       ret_err = stream_write_byte (response, SSH_RESPONSE_IDENTITIES_ANSWER);
2030       if (ret_err)
2031         goto leave;
2032       ret_err = stream_write_uint32 (response, key_counter);
2033       if (ret_err)
2034         goto leave;
2035       ret_err = stream_copy (response, key_blobs);
2036       if (ret_err)
2037         goto leave;
2038     }
2039   else
2040     {
2041       ret_err = stream_write_byte (response, SSH_RESPONSE_FAILURE);
2042       goto leave;
2043     };
2044
2045  leave:
2046
2047   if (key_blobs)
2048     es_fclose (key_blobs);
2049   if (dir)
2050     closedir (dir);
2051
2052   if (ctrl_fp)
2053     fclose (ctrl_fp);
2054
2055   xfree (key_directory);
2056   xfree (key_path);
2057   xfree (buffer);
2058   xfree (key_type);
2059
2060   return ret_err;
2061 }
2062
2063
2064 /* This function hashes the data contained in DATA of size DATA_N
2065    according to the message digest algorithm specified by MD_ALGORITHM
2066    and writes the message digest to HASH, which needs to large enough
2067    for the digest.  */
2068 static gpg_error_t
2069 data_hash (unsigned char *data, size_t data_n,
2070            int md_algorithm, unsigned char *hash)
2071 {
2072   gcry_md_hash_buffer (md_algorithm, hash, data, data_n);
2073
2074   return 0;
2075 }
2076
2077 /* This function signs the data contained in CTRL, stores the created
2078    signature in newly allocated memory in SIG and it's size in SIG_N;
2079    SIG_ENCODER is the signature encoder to use.  */
2080 static gpg_error_t
2081 data_sign (ctrl_t ctrl, ssh_signature_encoder_t sig_encoder,
2082            unsigned char **sig, size_t *sig_n)
2083 {
2084   gpg_error_t err;
2085   gcry_sexp_t signature_sexp = NULL;
2086   estream_t stream = NULL;
2087   gcry_sexp_t valuelist = NULL;
2088   gcry_sexp_t sublist = NULL;
2089   gcry_mpi_t sig_value = NULL;
2090   unsigned char *sig_blob = NULL;
2091   size_t sig_blob_n = 0;
2092   char *identifier = NULL;
2093   const char *identifier_raw;
2094   size_t identifier_n;
2095   ssh_key_type_spec_t spec;
2096   int ret;
2097   unsigned int i;
2098   const char *elems;
2099   size_t elems_n;
2100   gcry_mpi_t *mpis = NULL;
2101   char hexgrip[40+1];
2102
2103   *sig = NULL;
2104   *sig_n = 0;
2105
2106   /* Quick check to see whether we have a valid keygrip and convert it
2107      to hex.  */
2108   if (!ctrl->have_keygrip)
2109     {
2110       err = gpg_error (GPG_ERR_NO_SECKEY);
2111       goto out;
2112     }
2113   bin2hex (ctrl->keygrip, 20, hexgrip);
2114
2115   /* Ask for confirmation if needed.  */
2116   if (confirm_flag_from_sshcontrol (hexgrip))
2117     {
2118       gcry_sexp_t key;
2119       char *fpr, *prompt;
2120       char *comment = NULL;
2121
2122       err = agent_raw_key_from_file (ctrl, ctrl->keygrip, &key);
2123       if (err)
2124         goto out;
2125       err = ssh_get_fingerprint_string (key, &fpr);
2126       if (!err)
2127         {
2128           gcry_sexp_t tmpsxp = gcry_sexp_find_token (key, "comment", 0);
2129           if (tmpsxp)
2130             comment = gcry_sexp_nth_string (tmpsxp, 1);
2131           gcry_sexp_release (tmpsxp);
2132         }
2133       gcry_sexp_release (key);
2134       if (err)
2135         goto out;
2136       prompt = xtryasprintf (_("An ssh process requested the use of key%%0A"
2137                                "  %s%%0A"
2138                                "  (%s)%%0A"
2139                                "Do you want to allow this?"),
2140                              fpr, comment? comment:"");
2141       xfree (fpr);
2142       gcry_free (comment);
2143       err = agent_get_confirmation (ctrl, prompt, _("Allow"), _("Deny"), 0);
2144       xfree (prompt);
2145       if (err)
2146         goto out;
2147     }
2148
2149   /* Create signature.  */
2150   ctrl->use_auth_call = 1;
2151   err = agent_pksign_do (ctrl, NULL,
2152                          _("Please enter the passphrase "
2153                            "for the ssh key%%0A  %F%%0A  (%c)"),
2154                          &signature_sexp,
2155                          CACHE_MODE_SSH, ttl_from_sshcontrol);
2156   ctrl->use_auth_call = 0;
2157   if (err)
2158     goto out;
2159
2160   valuelist = gcry_sexp_nth (signature_sexp, 1);
2161   if (! valuelist)
2162     {
2163       err = gpg_error (GPG_ERR_INV_SEXP);
2164       goto out;
2165     }
2166
2167   stream = es_mopen (NULL, 0, 0, 1, NULL, NULL, "r+");
2168   if (! stream)
2169     {
2170       err = gpg_error_from_syserror ();
2171       goto out;
2172     }
2173
2174   identifier_raw = gcry_sexp_nth_data (valuelist, 0, &identifier_n);
2175   if (! identifier_raw)
2176     {
2177       err = gpg_error (GPG_ERR_INV_SEXP);
2178       goto out;
2179     }
2180
2181   identifier = make_cstring (identifier_raw, identifier_n);
2182   if (! identifier)
2183     {
2184       err = gpg_error_from_syserror ();
2185       goto out;
2186     }
2187
2188   err = ssh_key_type_lookup (NULL, identifier, &spec);
2189   if (err)
2190     goto out;
2191
2192   err = stream_write_cstring (stream, spec.ssh_identifier);
2193   if (err)
2194     goto out;
2195
2196   elems = spec.elems_signature;
2197   elems_n = strlen (elems);
2198
2199   mpis = xtrycalloc (elems_n + 1, sizeof *mpis);
2200   if (!mpis)
2201     {
2202       err = gpg_error_from_syserror ();
2203       goto out;
2204     }
2205
2206   for (i = 0; i < elems_n; i++)
2207     {
2208       sublist = gcry_sexp_find_token (valuelist, spec.elems_signature + i, 1);
2209       if (! sublist)
2210         {
2211           err = gpg_error (GPG_ERR_INV_SEXP);
2212           break;
2213         }
2214
2215       sig_value = gcry_sexp_nth_mpi (sublist, 1, GCRYMPI_FMT_USG);
2216       if (! sig_value)
2217         {
2218           err = gpg_error (GPG_ERR_INTERNAL); /* FIXME?  */
2219           break;
2220         }
2221       gcry_sexp_release (sublist);
2222       sublist = NULL;
2223
2224       mpis[i] = sig_value;
2225     }
2226   if (err)
2227     goto out;
2228
2229   err = (*sig_encoder) (stream, mpis);
2230   if (err)
2231     goto out;
2232
2233   sig_blob_n = es_ftell (stream);
2234   if (sig_blob_n == -1)
2235     {
2236       err = gpg_error_from_syserror ();
2237       goto out;
2238     }
2239
2240   sig_blob = xtrymalloc (sig_blob_n);
2241   if (! sig_blob)
2242     {
2243       err = gpg_error_from_syserror ();
2244       goto out;
2245     }
2246
2247   ret = es_fseek (stream, 0, SEEK_SET);
2248   if (ret)
2249     {
2250       err = gpg_error_from_syserror ();
2251       goto out;
2252     }
2253
2254   err = stream_read_data (stream, sig_blob, sig_blob_n);
2255   if (err)
2256     goto out;
2257
2258   *sig = sig_blob;
2259   *sig_n = sig_blob_n;
2260
2261  out:
2262
2263   if (err)
2264     xfree (sig_blob);
2265
2266   if (stream)
2267     es_fclose (stream);
2268   gcry_sexp_release (valuelist);
2269   gcry_sexp_release (signature_sexp);
2270   gcry_sexp_release (sublist);
2271   mpint_list_free (mpis);
2272   xfree (identifier);
2273
2274   return err;
2275 }
2276
2277 /* Handler for the "sign_request" command.  */
2278 static gpg_error_t
2279 ssh_handler_sign_request (ctrl_t ctrl, estream_t request, estream_t response)
2280 {
2281   gcry_sexp_t key;
2282   ssh_key_type_spec_t spec;
2283   unsigned char hash[MAX_DIGEST_LEN];
2284   unsigned int hash_n;
2285   unsigned char key_grip[20];
2286   unsigned char *key_blob;
2287   u32 key_blob_size;
2288   unsigned char *data;
2289   unsigned char *sig;
2290   size_t sig_n;
2291   u32 data_size;
2292   u32 flags;
2293   gpg_error_t err;
2294   gpg_error_t ret_err;
2295
2296   key_blob = NULL;
2297   data = NULL;
2298   sig = NULL;
2299   key = NULL;
2300
2301   /* Receive key.  */
2302
2303   err = stream_read_string (request, 0, &key_blob, &key_blob_size);
2304   if (err)
2305     goto out;
2306
2307   err = ssh_read_key_public_from_blob (key_blob, key_blob_size, &key, &spec);
2308   if (err)
2309     goto out;
2310
2311   /* Receive data to sign.  */
2312   err = stream_read_string (request, 0, &data, &data_size);
2313   if (err)
2314     goto out;
2315
2316   /* FIXME?  */
2317   err = stream_read_uint32 (request, &flags);
2318   if (err)
2319     goto out;
2320
2321   /* Hash data.  */
2322   hash_n = gcry_md_get_algo_dlen (GCRY_MD_SHA1);
2323   if (! hash_n)
2324     {
2325       err = gpg_error (GPG_ERR_INTERNAL);
2326       goto out;
2327     }
2328   err = data_hash (data, data_size, GCRY_MD_SHA1, hash);
2329   if (err)
2330     goto out;
2331
2332   /* Calculate key grip.  */
2333   err = ssh_key_grip (key, key_grip);
2334   if (err)
2335     goto out;
2336
2337   /* Sign data.  */
2338
2339   ctrl->digest.algo = GCRY_MD_SHA1;
2340   memcpy (ctrl->digest.value, hash, hash_n);
2341   ctrl->digest.valuelen = hash_n;
2342   ctrl->digest.raw_value = ! (spec.flags & SPEC_FLAG_USE_PKCS1V2);
2343   ctrl->have_keygrip = 1;
2344   memcpy (ctrl->keygrip, key_grip, 20);
2345
2346   err = data_sign (ctrl, spec.signature_encoder, &sig, &sig_n);
2347
2348  out:
2349
2350   /* Done.  */
2351
2352   if (! err)
2353     {
2354       ret_err = stream_write_byte (response, SSH_RESPONSE_SIGN_RESPONSE);
2355       if (ret_err)
2356         goto leave;
2357       ret_err = stream_write_string (response, sig, sig_n);
2358       if (ret_err)
2359         goto leave;
2360     }
2361   else
2362     {
2363       ret_err = stream_write_byte (response, SSH_RESPONSE_FAILURE);
2364       if (ret_err)
2365         goto leave;
2366     }
2367
2368  leave:
2369
2370   gcry_sexp_release (key);
2371   xfree (key_blob);
2372   xfree (data);
2373   xfree (sig);
2374
2375   return ret_err;
2376 }
2377
2378 /* This function extracts the comment contained in the key
2379    S-Expression KEY and stores a copy in COMMENT.  Returns usual error
2380    code.  */
2381 static gpg_error_t
2382 ssh_key_extract_comment (gcry_sexp_t key, char **comment)
2383 {
2384   gcry_sexp_t comment_list;
2385   char *comment_new;
2386   const char *data;
2387   size_t data_n;
2388   gpg_error_t err;
2389
2390   comment_list = gcry_sexp_find_token (key, "comment", 0);
2391   if (! comment_list)
2392     {
2393       err = gpg_error (GPG_ERR_INV_SEXP);
2394       goto out;
2395     }
2396
2397   data = gcry_sexp_nth_data (comment_list, 1, &data_n);
2398   if (! data)
2399     {
2400       err = gpg_error (GPG_ERR_INV_SEXP);
2401       goto out;
2402     }
2403
2404   comment_new = make_cstring (data, data_n);
2405   if (! comment_new)
2406     {
2407       err = gpg_error_from_syserror ();
2408       goto out;
2409     }
2410
2411   *comment = comment_new;
2412   err = 0;
2413
2414  out:
2415
2416   gcry_sexp_release (comment_list);
2417
2418   return err;
2419 }
2420
2421 /* This function converts the key contained in the S-Expression KEY
2422    into a buffer, which is protected by the passphrase PASSPHRASE.
2423    Returns usual error code.  */
2424 static gpg_error_t
2425 ssh_key_to_protected_buffer (gcry_sexp_t key, const char *passphrase,
2426                              unsigned char **buffer, size_t *buffer_n)
2427 {
2428   unsigned char *buffer_new;
2429   unsigned int buffer_new_n;
2430   gpg_error_t err;
2431
2432   err = 0;
2433   buffer_new_n = gcry_sexp_sprint (key, GCRYSEXP_FMT_CANON, NULL, 0);
2434   buffer_new = xtrymalloc_secure (buffer_new_n);
2435   if (! buffer_new)
2436     {
2437       err = gpg_error_from_syserror ();
2438       goto out;
2439     }
2440
2441   gcry_sexp_sprint (key, GCRYSEXP_FMT_CANON, buffer_new, buffer_new_n);
2442   /* FIXME: guarantee?  */
2443
2444   err = agent_protect (buffer_new, passphrase, buffer, buffer_n, 0);
2445
2446  out:
2447
2448   xfree (buffer_new);
2449
2450   return err;
2451 }
2452
2453
2454
2455 /* Callback function to compare the first entered PIN with the one
2456    currently being entered. */
2457 static int
2458 reenter_compare_cb (struct pin_entry_info_s *pi)
2459 {
2460   const char *pin1 = pi->check_cb_arg;
2461
2462   if (!strcmp (pin1, pi->pin))
2463     return 0; /* okay */
2464   return -1;
2465 }
2466
2467 /* Store the ssh KEY into our local key storage and protect it after
2468    asking for a passphrase.  Cache that passphrase.  TTL is the
2469    maximum caching time for that key.  If the key already exists in
2470    our key storage, don't do anything.  When entering a new key also
2471    add an entry to the sshcontrol file.  */
2472 static gpg_error_t
2473 ssh_identity_register (ctrl_t ctrl, gcry_sexp_t key, int ttl, int confirm)
2474 {
2475   gpg_error_t err;
2476   unsigned char key_grip_raw[20];
2477   char key_grip[41];
2478   unsigned char *buffer = NULL;
2479   size_t buffer_n;
2480   char *description = NULL;
2481   const char *description2 = _("Please re-enter this passphrase");
2482   char *comment = NULL;
2483   char *key_fpr = NULL;
2484   const char *initial_errtext = NULL;
2485   unsigned int i;
2486   struct pin_entry_info_s *pi = NULL, *pi2;
2487
2488   err = ssh_key_grip (key, key_grip_raw);
2489   if (err)
2490     goto out;
2491
2492   /* Check whether the key is already in our key storage.  Don't do
2493      anything then.  */
2494   if ( !agent_key_available (key_grip_raw) )
2495     goto out; /* Yes, key is available.  */
2496
2497   err = ssh_get_fingerprint_string (key, &key_fpr);
2498   if (err)
2499     goto out;
2500
2501   err = ssh_key_extract_comment (key, &comment);
2502   if (err)
2503     goto out;
2504
2505   if ( asprintf (&description,
2506                  _("Please enter a passphrase to protect"
2507                    " the received secret key%%0A"
2508                    "   %s%%0A"
2509                    "   %s%%0A"
2510                    "within gpg-agent's key storage"),
2511                  key_fpr, comment ? comment : "") < 0)
2512     {
2513       err = gpg_error_from_syserror ();
2514       goto out;
2515     }
2516
2517
2518   pi = gcry_calloc_secure (2, sizeof (*pi) + 100 + 1);
2519   if (!pi)
2520     {
2521       err = gpg_error_from_syserror ();
2522       goto out;
2523     }
2524   pi2 = pi + (sizeof *pi + 100 + 1);
2525   pi->max_length = 100;
2526   pi->max_tries = 1;
2527   pi2->max_length = 100;
2528   pi2->max_tries = 1;
2529   pi2->check_cb = reenter_compare_cb;
2530   pi2->check_cb_arg = pi->pin;
2531
2532  next_try:
2533   err = agent_askpin (ctrl, description, NULL, initial_errtext, pi);
2534   initial_errtext = NULL;
2535   if (err)
2536     goto out;
2537
2538   /* Unless the passphrase is empty, ask to confirm it.  */
2539   if (pi->pin && *pi->pin)
2540     {
2541       err = agent_askpin (ctrl, description2, NULL, NULL, pi2);
2542       if (err == -1)
2543         { /* The re-entered one did not match and the user did not
2544              hit cancel. */
2545           initial_errtext = _("does not match - try again");
2546           goto next_try;
2547         }
2548     }
2549
2550   err = ssh_key_to_protected_buffer (key, pi->pin, &buffer, &buffer_n);
2551   if (err)
2552     goto out;
2553
2554   /* Store this key to our key storage.  */
2555   err = agent_write_private_key (key_grip_raw, buffer, buffer_n, 0);
2556   if (err)
2557     goto out;
2558
2559   /* Cache this passphrase. */
2560   for (i = 0; i < 20; i++)
2561     sprintf (key_grip + 2 * i, "%02X", key_grip_raw[i]);
2562
2563   err = agent_put_cache (key_grip, CACHE_MODE_SSH, pi->pin, ttl);
2564   if (err)
2565     goto out;
2566
2567   /* And add an entry to the sshcontrol file.  */
2568   err = add_control_entry (ctrl, key_grip, key_fpr, ttl, confirm);
2569
2570
2571  out:
2572   if (pi && pi->max_length)
2573     wipememory (pi->pin, pi->max_length);
2574   xfree (pi);
2575   xfree (buffer);
2576   xfree (comment);
2577   xfree (key_fpr);
2578   xfree (description);
2579
2580   return err;
2581 }
2582
2583
2584 /* This function removes the key contained in the S-Expression KEY
2585    from the local key storage, in case it exists there.  Returns usual
2586    error code.  FIXME: this function is a stub.  */
2587 static gpg_error_t
2588 ssh_identity_drop (gcry_sexp_t key)
2589 {
2590   unsigned char key_grip[21] = { 0 };
2591   gpg_error_t err;
2592
2593   err = ssh_key_grip (key, key_grip);
2594   if (err)
2595     goto out;
2596
2597   key_grip[sizeof (key_grip) - 1] = 0;
2598
2599   /* FIXME: What to do here - forgetting the passphrase or deleting
2600      the key from key cache?  */
2601
2602  out:
2603
2604   return err;
2605 }
2606
2607 /* Handler for the "add_identity" command.  */
2608 static gpg_error_t
2609 ssh_handler_add_identity (ctrl_t ctrl, estream_t request, estream_t response)
2610 {
2611   gpg_error_t ret_err;
2612   gpg_error_t err;
2613   gcry_sexp_t key;
2614   unsigned char b;
2615   int confirm;
2616   int ttl;
2617
2618   confirm = 0;
2619   key = NULL;
2620   ttl = 0;
2621
2622   /* FIXME?  */
2623   err = ssh_receive_key (request, &key, 1, 1, NULL);
2624   if (err)
2625     goto out;
2626
2627   while (1)
2628     {
2629       err = stream_read_byte (request, &b);
2630       if (gpg_err_code (err) == GPG_ERR_EOF)
2631         {
2632           err = 0;
2633           break;
2634         }
2635
2636       switch (b)
2637         {
2638         case SSH_OPT_CONSTRAIN_LIFETIME:
2639           {
2640             u32 n = 0;
2641
2642             err = stream_read_uint32 (request, &n);
2643             if (! err)
2644               ttl = n;
2645             break;
2646           }
2647
2648         case SSH_OPT_CONSTRAIN_CONFIRM:
2649           {
2650             confirm = 1;
2651             break;
2652           }
2653
2654         default:
2655           /* FIXME: log/bad?  */
2656           break;
2657         }
2658     }
2659   if (err)
2660     goto out;
2661
2662   err = ssh_identity_register (ctrl, key, ttl, confirm);
2663
2664  out:
2665
2666   gcry_sexp_release (key);
2667
2668   if (! err)
2669     ret_err = stream_write_byte (response, SSH_RESPONSE_SUCCESS);
2670   else
2671     ret_err = stream_write_byte (response, SSH_RESPONSE_FAILURE);
2672
2673   return ret_err;
2674 }
2675
2676 /* Handler for the "remove_identity" command.  */
2677 static gpg_error_t
2678 ssh_handler_remove_identity (ctrl_t ctrl,
2679                              estream_t request, estream_t response)
2680 {
2681   unsigned char *key_blob;
2682   u32 key_blob_size;
2683   gcry_sexp_t key;
2684   gpg_error_t ret_err;
2685   gpg_error_t err;
2686
2687   (void)ctrl;
2688
2689   /* Receive key.  */
2690
2691   key_blob = NULL;
2692   key = NULL;
2693
2694   err = stream_read_string (request, 0, &key_blob, &key_blob_size);
2695   if (err)
2696     goto out;
2697
2698   err = ssh_read_key_public_from_blob (key_blob, key_blob_size, &key, NULL);
2699   if (err)
2700     goto out;
2701
2702   err = ssh_identity_drop (key);
2703
2704  out:
2705
2706   xfree (key_blob);
2707   gcry_sexp_release (key);
2708
2709   if (! err)
2710     ret_err = stream_write_byte (response, SSH_RESPONSE_SUCCESS);
2711   else
2712     ret_err = stream_write_byte (response, SSH_RESPONSE_FAILURE);
2713
2714   return ret_err;
2715 }
2716
2717 /* FIXME: stub function.  Actually useful?  */
2718 static gpg_error_t
2719 ssh_identities_remove_all (void)
2720 {
2721   gpg_error_t err;
2722
2723   err = 0;
2724
2725   /* FIXME: shall we remove _all_ cache entries or only those
2726      registered through the ssh emulation?  */
2727
2728   return err;
2729 }
2730
2731 /* Handler for the "remove_all_identities" command.  */
2732 static gpg_error_t
2733 ssh_handler_remove_all_identities (ctrl_t ctrl,
2734                                    estream_t request, estream_t response)
2735 {
2736   gpg_error_t ret_err;
2737   gpg_error_t err;
2738
2739   (void)ctrl;
2740   (void)request;
2741
2742   err = ssh_identities_remove_all ();
2743
2744   if (! err)
2745     ret_err = stream_write_byte (response, SSH_RESPONSE_SUCCESS);
2746   else
2747     ret_err = stream_write_byte (response, SSH_RESPONSE_FAILURE);
2748
2749   return ret_err;
2750 }
2751
2752 /* Lock agent?  FIXME: stub function.  */
2753 static gpg_error_t
2754 ssh_lock (void)
2755 {
2756   gpg_error_t err;
2757
2758   /* FIXME */
2759   log_error ("ssh-agent's lock command is not implemented\n");
2760   err = 0;
2761
2762   return err;
2763 }
2764
2765 /* Unock agent?  FIXME: stub function.  */
2766 static gpg_error_t
2767 ssh_unlock (void)
2768 {
2769   gpg_error_t err;
2770
2771   log_error ("ssh-agent's unlock command is not implemented\n");
2772   err = 0;
2773
2774   return err;
2775 }
2776
2777 /* Handler for the "lock" command.  */
2778 static gpg_error_t
2779 ssh_handler_lock (ctrl_t ctrl, estream_t request, estream_t response)
2780 {
2781   gpg_error_t ret_err;
2782   gpg_error_t err;
2783
2784   (void)ctrl;
2785   (void)request;
2786
2787   err = ssh_lock ();
2788
2789   if (! err)
2790     ret_err = stream_write_byte (response, SSH_RESPONSE_SUCCESS);
2791   else
2792     ret_err = stream_write_byte (response, SSH_RESPONSE_FAILURE);
2793
2794   return ret_err;
2795 }
2796
2797 /* Handler for the "unlock" command.  */
2798 static gpg_error_t
2799 ssh_handler_unlock (ctrl_t ctrl, estream_t request, estream_t response)
2800 {
2801   gpg_error_t ret_err;
2802   gpg_error_t err;
2803
2804   (void)ctrl;
2805   (void)request;
2806
2807   err = ssh_unlock ();
2808
2809   if (! err)
2810     ret_err = stream_write_byte (response, SSH_RESPONSE_SUCCESS);
2811   else
2812     ret_err = stream_write_byte (response, SSH_RESPONSE_FAILURE);
2813
2814   return ret_err;
2815 }
2816
2817 \f
2818
2819 /* Return the request specification for the request identified by TYPE
2820    or NULL in case the requested request specification could not be
2821    found.  */
2822 static ssh_request_spec_t *
2823 request_spec_lookup (int type)
2824 {
2825   ssh_request_spec_t *spec;
2826   unsigned int i;
2827
2828   for (i = 0; i < DIM (request_specs); i++)
2829     if (request_specs[i].type == type)
2830       break;
2831   if (i == DIM (request_specs))
2832     {
2833       if (opt.verbose)
2834         log_info ("ssh request %u is not supported\n", type);
2835       spec = NULL;
2836     }
2837   else
2838     spec = request_specs + i;
2839
2840   return spec;
2841 }
2842
2843 /* Process a single request.  The request is read from and the
2844    response is written to STREAM_SOCK.  Uses CTRL as context.  Returns
2845    zero in case of success, non zero in case of failure.  */
2846 static int
2847 ssh_request_process (ctrl_t ctrl, estream_t stream_sock)
2848 {
2849   ssh_request_spec_t *spec;
2850   estream_t response;
2851   estream_t request;
2852   unsigned char request_type;
2853   gpg_error_t err;
2854   int send_err;
2855   int ret;
2856   unsigned char *request_data;
2857   u32 request_data_size;
2858   u32 response_size;
2859
2860   request_data = NULL;
2861   response = NULL;
2862   request = NULL;
2863   send_err = 0;
2864
2865   /* Create memory streams for request/response data.  The entire
2866      request will be stored in secure memory, since it might contain
2867      secret key material.  The response does not have to be stored in
2868      secure memory, since we never give out secret keys.
2869
2870      Note: we only have little secure memory, but there is NO
2871      possibility of DoS here; only trusted clients are allowed to
2872      connect to the agent.  What could happen is that the agent
2873      returns out-of-secure-memory errors on requests in case the
2874      agent's owner floods his own agent with many large messages.
2875      -moritz */
2876
2877   /* Retrieve request.  */
2878   err = stream_read_string (stream_sock, 1, &request_data, &request_data_size);
2879   if (err)
2880     goto out;
2881
2882   if (opt.verbose > 1)
2883     log_info ("received ssh request of length %u\n",
2884               (unsigned int)request_data_size);
2885
2886   if (! request_data_size)
2887     {
2888       send_err = 1;
2889       goto out;
2890       /* Broken request; FIXME.  */
2891     }
2892
2893   request_type = request_data[0];
2894   spec = request_spec_lookup (request_type);
2895   if (! spec)
2896     {
2897       send_err = 1;
2898       goto out;
2899       /* Unknown request; FIXME.  */
2900     }
2901
2902   if (spec->secret_input)
2903     request = es_mopen (NULL, 0, 0, 1, realloc_secure, gcry_free, "r+");
2904   else
2905     request = es_mopen (NULL, 0, 0, 1, gcry_realloc, gcry_free, "r+");
2906   if (! request)
2907     {
2908       err = gpg_error_from_syserror ();
2909       goto out;
2910     }
2911   ret = es_setvbuf (request, NULL, _IONBF, 0);
2912   if (ret)
2913     {
2914       err = gpg_error_from_syserror ();
2915       goto out;
2916     }
2917   err = stream_write_data (request, request_data + 1, request_data_size - 1);
2918   if (err)
2919     goto out;
2920   es_rewind (request);
2921
2922   response = es_mopen (NULL, 0, 0, 1, NULL, NULL, "r+");
2923   if (! response)
2924     {
2925       err = gpg_error_from_syserror ();
2926       goto out;
2927     }
2928
2929   if (opt.verbose)
2930     log_info ("ssh request handler for %s (%u) started\n",
2931                spec->identifier, spec->type);
2932
2933   err = (*spec->handler) (ctrl, request, response);
2934
2935   if (opt.verbose)
2936     {
2937       if (err)
2938         log_info ("ssh request handler for %s (%u) failed: %s\n",
2939                   spec->identifier, spec->type, gpg_strerror (err));
2940       else
2941         log_info ("ssh request handler for %s (%u) ready\n",
2942                   spec->identifier, spec->type);
2943     }
2944
2945   if (err)
2946     {
2947       send_err = 1;
2948       goto out;
2949     }
2950
2951   response_size = es_ftell (response);
2952   if (opt.verbose > 1)
2953     log_info ("sending ssh response of length %u\n",
2954               (unsigned int)response_size);
2955
2956   err = es_fseek (response, 0, SEEK_SET);
2957   if (err)
2958     {
2959       send_err = 1;
2960       goto out;
2961     }
2962
2963   err = stream_write_uint32 (stream_sock, response_size);
2964   if (err)
2965     {
2966       send_err = 1;
2967       goto out;
2968     }
2969
2970   err = stream_copy (stream_sock, response);
2971   if (err)
2972     goto out;
2973
2974   err = es_fflush (stream_sock);
2975   if (err)
2976     goto out;
2977
2978  out:
2979
2980   if (err && es_feof (stream_sock))
2981     log_error ("error occured while processing request: %s\n",
2982                gpg_strerror (err));
2983
2984   if (send_err)
2985     {
2986       if (opt.verbose > 1)
2987         log_info ("sending ssh error response\n");
2988       err = stream_write_uint32 (stream_sock, 1);
2989       if (err)
2990         goto leave;
2991       err = stream_write_byte (stream_sock, SSH_RESPONSE_FAILURE);
2992       if (err)
2993         goto leave;
2994     }
2995
2996  leave:
2997
2998   if (request)
2999     es_fclose (request);
3000   if (response)
3001     es_fclose (response);
3002   xfree (request_data);         /* FIXME?  */
3003
3004   return !!err;
3005 }
3006
3007 /* Start serving client on SOCK_CLIENT.  */
3008 void
3009 start_command_handler_ssh (ctrl_t ctrl, gnupg_fd_t sock_client)
3010 {
3011   estream_t stream_sock = NULL;
3012   gpg_error_t err = 0;
3013   int ret;
3014
3015   /* Because the ssh protocol does not send us information about the
3016      the current TTY setting, we resort here to use those from startup
3017      or those explictly set.  */
3018   {
3019     static const char *names[] =
3020       {"GPG_TTY", "DISPLAY", "TERM", "XAUTHORITY", "PINENTRY_USER_DATA", NULL};
3021     int idx;
3022     const char *value;
3023
3024     for (idx=0; !err && names[idx]; idx++)
3025       if (!session_env_getenv (ctrl->session_env, names[idx])
3026           && (value = session_env_getenv (opt.startup_env, names[idx])))
3027         err = session_env_setenv (ctrl->session_env, names[idx], value);
3028
3029     if (!err && !ctrl->lc_ctype && opt.startup_lc_ctype)
3030       if (!(ctrl->lc_ctype = xtrystrdup (opt.startup_lc_ctype)))
3031         err = gpg_error_from_syserror ();
3032
3033     if (!err && !ctrl->lc_messages && opt.startup_lc_messages)
3034       if (!(ctrl->lc_messages = xtrystrdup (opt.startup_lc_messages)))
3035         err = gpg_error_from_syserror ();
3036
3037     if (err)
3038       {
3039         log_error ("error setting default session environment: %s\n",
3040                    gpg_strerror (err));
3041         goto out;
3042       }
3043   }
3044
3045
3046   /* Create stream from socket.  */
3047   stream_sock = es_fdopen (FD2INT(sock_client), "r+");
3048   if (!stream_sock)
3049     {
3050       err = gpg_error_from_syserror ();
3051       log_error (_("failed to create stream from socket: %s\n"),
3052                  gpg_strerror (err));
3053       goto out;
3054     }
3055   /* We have to disable the estream buffering, because the estream
3056      core doesn't know about secure memory.  */
3057   ret = es_setvbuf (stream_sock, NULL, _IONBF, 0);
3058   if (ret)
3059     {
3060       err = gpg_error_from_syserror ();
3061       log_error ("failed to disable buffering "
3062                  "on socket stream: %s\n", gpg_strerror (err));
3063       goto out;
3064     }
3065
3066   /* Main processing loop. */
3067   while ( !ssh_request_process (ctrl, stream_sock) )
3068     {
3069       /* Check wether we have reached EOF before trying to read
3070          another request.  */
3071       int c;
3072
3073       c = es_fgetc (stream_sock);
3074       if (c == EOF)
3075         break;
3076       es_ungetc (c, stream_sock);
3077     }
3078
3079   /* Reset the SCD in case it has been used. */
3080   agent_reset_scd (ctrl);
3081
3082
3083  out:
3084   if (stream_sock)
3085     es_fclose (stream_sock);
3086 }