ssh: Make the mode extension "x" portable by a call to es_fopen.
[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 "estream.h"
36 #include "i18n.h"
37 #include "../common/ssh-utils.h"
38
39
40 \f
41
42 /* Request types. */
43 #define SSH_REQUEST_REQUEST_IDENTITIES    11
44 #define SSH_REQUEST_SIGN_REQUEST          13
45 #define SSH_REQUEST_ADD_IDENTITY          17
46 #define SSH_REQUEST_REMOVE_IDENTITY       18
47 #define SSH_REQUEST_REMOVE_ALL_IDENTITIES 19
48 #define SSH_REQUEST_LOCK                  22
49 #define SSH_REQUEST_UNLOCK                23
50 #define SSH_REQUEST_ADD_ID_CONSTRAINED    25
51
52 /* Options. */
53 #define SSH_OPT_CONSTRAIN_LIFETIME         1
54 #define SSH_OPT_CONSTRAIN_CONFIRM          2
55
56 /* Response types. */
57 #define SSH_RESPONSE_SUCCESS               6
58 #define SSH_RESPONSE_FAILURE               5
59 #define SSH_RESPONSE_IDENTITIES_ANSWER    12
60 #define SSH_RESPONSE_SIGN_RESPONSE        14
61
62 /* Other constants.  */
63 #define SSH_DSA_SIGNATURE_PADDING 20
64 #define SSH_DSA_SIGNATURE_ELEMS    2
65 #define SPEC_FLAG_USE_PKCS1V2 (1 << 0)
66
67
68 /* The blurb we put into the header of a newly created control file.  */
69 static const char sshcontrolblurb[] =
70 "# List of allowed ssh keys.  Only keys present in this file are used\n"
71 "# in the SSH protocol.  The ssh-add tool may add new entries to this\n"
72 "# file to enable them; you may also add them manually.  Comment\n"
73 "# lines, like this one, as well as empty lines are ignored.  Lines do\n"
74 "# have a certain length limit but this is not serious limitation as\n"
75 "# the format of the entries is fixed and checked by gpg-agent. A\n"
76 "# non-comment line starts with optional white spaces, followed by the\n"
77 "# keygrip of the key given as 40 hex digits, optionally followed by a\n"
78 "# the caching TTL in seconds and another optional field for arbitrary\n"
79 "# flags.   Prepend the keygrip with an '!' mark to disable it.\n"
80 "\n";
81
82
83
84 /* Macros.  */
85
86 /* Return a new uint32 with b0 being the most significant byte and b3
87    being the least significant byte.  */
88 #define uint32_construct(b0, b1, b2, b3) \
89   ((b0 << 24) | (b1 << 16) | (b2 << 8) | b3)
90
91 \f
92
93
94 /*
95  * Basic types.
96  */
97
98 /* Type for a request handler.  */
99 typedef gpg_error_t (*ssh_request_handler_t) (ctrl_t ctrl,
100                                               estream_t request,
101                                               estream_t response);
102
103 /* Type, which is used for associating request handlers with the
104    appropriate request IDs.  */
105 typedef struct ssh_request_spec
106 {
107   unsigned char type;
108   ssh_request_handler_t handler;
109   const char *identifier;
110   unsigned int secret_input;
111 } ssh_request_spec_t;
112
113 /* Type for "key modifier functions", which are necessary since
114    OpenSSH and GnuPG treat key material slightly different.  A key
115    modifier is called right after a new key identity has been received
116    in order to "sanitize" the material.  */
117 typedef gpg_error_t (*ssh_key_modifier_t) (const char *elems,
118                                            gcry_mpi_t *mpis);
119
120 /* The encoding of a generated signature is dependent on the
121    algorithm; therefore algorithm specific signature encoding
122    functions are necessary.  */
123 typedef gpg_error_t (*ssh_signature_encoder_t) (estream_t signature_blob,
124                                                 gcry_mpi_t *mpis);
125
126 /* Type, which is used for boundling all the algorithm specific
127    information together in a single object.  */
128 typedef struct ssh_key_type_spec
129 {
130   /* Algorithm identifier as used by OpenSSH.  */
131   const char *ssh_identifier;
132
133   /* Algorithm identifier as used by GnuPG.  */
134   const char *identifier;
135
136   /* List of MPI names for secret keys; order matches the one of the
137      agent protocol.  */
138   const char *elems_key_secret;
139
140   /* List of MPI names for public keys; order matches the one of the
141      agent protocol.  */
142   const char *elems_key_public;
143
144   /* List of MPI names for signature data.  */
145   const char *elems_signature;
146
147   /* List of MPI names for secret keys; order matches the one, which
148      is required by gpg-agent's key access layer.  */
149   const char *elems_sexp_order;
150
151   /* Key modifier function.  Key modifier functions are necessary in
152      order to fix any inconsistencies between the representation of
153      keys on the SSH and on the GnuPG side.  */
154   ssh_key_modifier_t key_modifier;
155
156   /* Signature encoder function.  Signature encoder functions are
157      necessary since the encoding of signatures depends on the used
158      algorithm.  */
159   ssh_signature_encoder_t signature_encoder;
160
161   /* Misc flags.  */
162   unsigned int flags;
163 } ssh_key_type_spec_t;
164
165
166 /* Prototypes.  */
167 static gpg_error_t ssh_handler_request_identities (ctrl_t ctrl,
168                                                    estream_t request,
169                                                    estream_t response);
170 static gpg_error_t ssh_handler_sign_request (ctrl_t ctrl,
171                                              estream_t request,
172                                              estream_t response);
173 static gpg_error_t ssh_handler_add_identity (ctrl_t ctrl,
174                                              estream_t request,
175                                              estream_t response);
176 static gpg_error_t ssh_handler_remove_identity (ctrl_t ctrl,
177                                                 estream_t request,
178                                                 estream_t response);
179 static gpg_error_t ssh_handler_remove_all_identities (ctrl_t ctrl,
180                                                       estream_t request,
181                                                       estream_t response);
182 static gpg_error_t ssh_handler_lock (ctrl_t ctrl,
183                                      estream_t request,
184                                      estream_t response);
185 static gpg_error_t ssh_handler_unlock (ctrl_t ctrl,
186                                        estream_t request,
187                                        estream_t response);
188
189 static gpg_error_t ssh_key_modifier_rsa (const char *elems, gcry_mpi_t *mpis);
190 static gpg_error_t ssh_signature_encoder_rsa (estream_t signature_blob,
191                                               gcry_mpi_t *mpis);
192 static gpg_error_t ssh_signature_encoder_dsa (estream_t signature_blob,
193                                               gcry_mpi_t *mpis);
194
195
196
197 /* Global variables.  */
198
199
200 /* Associating request types with the corresponding request
201    handlers.  */
202
203 static ssh_request_spec_t request_specs[] =
204   {
205 #define REQUEST_SPEC_DEFINE(id, name, secret_input) \
206   { SSH_REQUEST_##id, ssh_handler_##name, #name, secret_input }
207
208     REQUEST_SPEC_DEFINE (REQUEST_IDENTITIES,    request_identities,    1),
209     REQUEST_SPEC_DEFINE (SIGN_REQUEST,          sign_request,          0),
210     REQUEST_SPEC_DEFINE (ADD_IDENTITY,          add_identity,          1),
211     REQUEST_SPEC_DEFINE (ADD_ID_CONSTRAINED,    add_identity,          1),
212     REQUEST_SPEC_DEFINE (REMOVE_IDENTITY,       remove_identity,       0),
213     REQUEST_SPEC_DEFINE (REMOVE_ALL_IDENTITIES, remove_all_identities, 0),
214     REQUEST_SPEC_DEFINE (LOCK,                  lock,                  0),
215     REQUEST_SPEC_DEFINE (UNLOCK,                unlock,                0)
216 #undef REQUEST_SPEC_DEFINE
217   };
218
219
220 /* Table holding key type specifications.  */
221 static ssh_key_type_spec_t ssh_key_types[] =
222   {
223     {
224       "ssh-rsa", "rsa", "nedupq", "en",   "s",  "nedpqu",
225       ssh_key_modifier_rsa, ssh_signature_encoder_rsa,
226       SPEC_FLAG_USE_PKCS1V2
227     },
228     {
229       "ssh-dss", "dsa", "pqgyx",  "pqgy", "rs", "pqgyx",
230       NULL,                 ssh_signature_encoder_dsa,
231       0
232     },
233   };
234
235 \f
236
237
238
239 /*
240    General utility functions.
241  */
242
243 /* A secure realloc, i.e. it makes sure to allocate secure memory if A
244    is NULL.  This is required because the standard gcry_realloc does
245    not know whether to allocate secure or normal if NULL is passed as
246    existing buffer.  */
247 static void *
248 realloc_secure (void *a, size_t n)
249 {
250   void *p;
251
252   if (a)
253     p = gcry_realloc (a, n);
254   else
255     p = gcry_malloc_secure (n);
256
257   return p;
258 }
259
260
261 /* Create and return a new C-string from DATA/DATA_N (i.e.: add
262    NUL-termination); return NULL on OOM.  */
263 static char *
264 make_cstring (const char *data, size_t data_n)
265 {
266   char *s;
267
268   s = xtrymalloc (data_n + 1);
269   if (s)
270     {
271       memcpy (s, data, data_n);
272       s[data_n] = 0;
273     }
274
275   return s;
276 }
277
278
279
280
281 /*
282    Primitive I/O functions.
283  */
284
285
286 /* Read a byte from STREAM, store it in B.  */
287 static gpg_error_t
288 stream_read_byte (estream_t stream, unsigned char *b)
289 {
290   gpg_error_t err;
291   int ret;
292
293   ret = es_fgetc (stream);
294   if (ret == EOF)
295     {
296       if (es_ferror (stream))
297         err = gpg_error_from_syserror ();
298       else
299         err = gpg_error (GPG_ERR_EOF);
300       *b = 0;
301     }
302   else
303     {
304       *b = ret & 0xFF;
305       err = 0;
306     }
307
308   return err;
309 }
310
311 /* Write the byte contained in B to STREAM.  */
312 static gpg_error_t
313 stream_write_byte (estream_t stream, unsigned char b)
314 {
315   gpg_error_t err;
316   int ret;
317
318   ret = es_fputc (b, stream);
319   if (ret == EOF)
320     err = gpg_error_from_syserror ();
321   else
322     err = 0;
323
324   return err;
325 }
326
327 /* Read a uint32 from STREAM, store it in UINT32.  */
328 static gpg_error_t
329 stream_read_uint32 (estream_t stream, u32 *uint32)
330 {
331   unsigned char buffer[4];
332   size_t bytes_read;
333   gpg_error_t err;
334   int ret;
335
336   ret = es_read (stream, buffer, sizeof (buffer), &bytes_read);
337   if (ret)
338     err = gpg_error_from_syserror ();
339   else
340     {
341       if (bytes_read != sizeof (buffer))
342         err = gpg_error (GPG_ERR_EOF);
343       else
344         {
345           u32 n;
346
347           n = uint32_construct (buffer[0], buffer[1], buffer[2], buffer[3]);
348           *uint32 = n;
349           err = 0;
350         }
351     }
352
353   return err;
354 }
355
356 /* Write the uint32 contained in UINT32 to STREAM.  */
357 static gpg_error_t
358 stream_write_uint32 (estream_t stream, u32 uint32)
359 {
360   unsigned char buffer[4];
361   gpg_error_t err;
362   int ret;
363
364   buffer[0] = uint32 >> 24;
365   buffer[1] = uint32 >> 16;
366   buffer[2] = uint32 >>  8;
367   buffer[3] = uint32 >>  0;
368
369   ret = es_write (stream, buffer, sizeof (buffer), NULL);
370   if (ret)
371     err = gpg_error_from_syserror ();
372   else
373     err = 0;
374
375   return err;
376 }
377
378 /* Read SIZE bytes from STREAM into BUFFER.  */
379 static gpg_error_t
380 stream_read_data (estream_t stream, unsigned char *buffer, size_t size)
381 {
382   gpg_error_t err;
383   size_t bytes_read;
384   int ret;
385
386   ret = es_read (stream, buffer, size, &bytes_read);
387   if (ret)
388     err = gpg_error_from_syserror ();
389   else
390     {
391       if (bytes_read != size)
392         err = gpg_error (GPG_ERR_EOF);
393       else
394         err = 0;
395     }
396
397   return err;
398 }
399
400 /* Write SIZE bytes from BUFFER to STREAM.  */
401 static gpg_error_t
402 stream_write_data (estream_t stream, const unsigned char *buffer, size_t size)
403 {
404   gpg_error_t err;
405   int ret;
406
407   ret = es_write (stream, buffer, size, NULL);
408   if (ret)
409     err = gpg_error_from_syserror ();
410   else
411     err = 0;
412
413   return err;
414 }
415
416 /* Read a binary string from STREAM into STRING, store size of string
417    in STRING_SIZE; depending on SECURE use secure memory for
418    string.  */
419 static gpg_error_t
420 stream_read_string (estream_t stream, unsigned int secure,
421                     unsigned char **string, u32 *string_size)
422 {
423   gpg_error_t err;
424   unsigned char *buffer = NULL;
425   u32 length = 0;
426
427   /* Read string length.  */
428   err = stream_read_uint32 (stream, &length);
429   if (err)
430     goto out;
431
432   /* Allocate space.  */
433   if (secure)
434     buffer = xtrymalloc_secure (length + 1);
435   else
436     buffer = xtrymalloc (length + 1);
437   if (! buffer)
438     {
439       err = gpg_error_from_syserror ();
440       goto out;
441     }
442
443   /* Read data.  */
444   err = stream_read_data (stream, buffer, length);
445   if (err)
446     goto out;
447
448   /* Finalize string object.  */
449   buffer[length] = 0;
450   *string = buffer;
451   if (string_size)
452     *string_size = length;
453
454  out:
455
456   if (err)
457     xfree (buffer);
458
459   return err;
460 }
461
462 /* Read a C-string from STREAM, store copy in STRING.  */
463 static gpg_error_t
464 stream_read_cstring (estream_t stream, char **string)
465 {
466   unsigned char *buffer;
467   gpg_error_t err;
468
469   err = stream_read_string (stream, 0, &buffer, NULL);
470   if (err)
471     goto out;
472
473   *string = (char *) buffer;
474
475  out:
476
477   return err;
478 }
479
480
481 /* Write a binary string from STRING of size STRING_N to STREAM.  */
482 static gpg_error_t
483 stream_write_string (estream_t stream,
484                      const unsigned char *string, u32 string_n)
485 {
486   gpg_error_t err;
487
488   err = stream_write_uint32 (stream, string_n);
489   if (err)
490     goto out;
491
492   err = stream_write_data (stream, string, string_n);
493
494  out:
495
496   return err;
497 }
498
499 /* Write a C-string from STRING to STREAM.  */
500 static gpg_error_t
501 stream_write_cstring (estream_t stream, const char *string)
502 {
503   gpg_error_t err;
504
505   err = stream_write_string (stream,
506                              (const unsigned char *) string, strlen (string));
507
508   return err;
509 }
510
511 /* Read an MPI from STREAM, store it in MPINT.  Depending on SECURE
512    use secure memory.  */
513 static gpg_error_t
514 stream_read_mpi (estream_t stream, unsigned int secure, gcry_mpi_t *mpint)
515 {
516   unsigned char *mpi_data;
517   u32 mpi_data_size;
518   gpg_error_t err;
519   gcry_mpi_t mpi;
520
521   mpi_data = NULL;
522
523   err = stream_read_string (stream, secure, &mpi_data, &mpi_data_size);
524   if (err)
525     goto out;
526
527   /* To avoid excessive use of secure memory we check that an MPI is
528      not too large. */
529   if (mpi_data_size > 520)
530     {
531       log_error (_("ssh keys greater than %d bits are not supported\n"), 4096);
532       err = GPG_ERR_TOO_LARGE;
533       goto out;
534     }
535
536   err = gcry_mpi_scan (&mpi, GCRYMPI_FMT_STD, mpi_data, mpi_data_size, NULL);
537   if (err)
538     goto out;
539
540   *mpint = mpi;
541
542  out:
543
544   xfree (mpi_data);
545
546   return err;
547 }
548
549 /* Write the MPI contained in MPINT to STREAM.  */
550 static gpg_error_t
551 stream_write_mpi (estream_t stream, gcry_mpi_t mpint)
552 {
553   unsigned char *mpi_buffer;
554   size_t mpi_buffer_n;
555   gpg_error_t err;
556
557   mpi_buffer = NULL;
558
559   err = gcry_mpi_aprint (GCRYMPI_FMT_STD, &mpi_buffer, &mpi_buffer_n, mpint);
560   if (err)
561     goto out;
562
563   err = stream_write_string (stream, mpi_buffer, mpi_buffer_n);
564
565  out:
566
567   xfree (mpi_buffer);
568
569   return err;
570 }
571
572 /* Copy data from SRC to DST until EOF is reached.  */
573 static gpg_error_t
574 stream_copy (estream_t dst, estream_t src)
575 {
576   char buffer[BUFSIZ];
577   size_t bytes_read;
578   gpg_error_t err;
579   int ret;
580
581   err = 0;
582   while (1)
583     {
584       ret = es_read (src, buffer, sizeof (buffer), &bytes_read);
585       if (ret || (! bytes_read))
586         {
587           if (ret)
588             err = gpg_error_from_syserror ();
589           break;
590         }
591       ret = es_write (dst, buffer, bytes_read, NULL);
592       if (ret)
593         {
594           err = gpg_error_from_syserror ();
595           break;
596         }
597     }
598
599   return err;
600 }
601
602
603 /* Read the content of the file specified by FILENAME into a newly
604    create buffer, which is to be stored in BUFFER; store length of
605    buffer in BUFFER_N.  */
606 static gpg_error_t
607 file_to_buffer (const char *filename, unsigned char **buffer, size_t *buffer_n)
608 {
609   unsigned char *buffer_new;
610   struct stat statbuf;
611   estream_t stream;
612   gpg_error_t err;
613   int ret;
614
615   *buffer = NULL;
616   *buffer_n = 0;
617
618   buffer_new = NULL;
619   err = 0;
620
621   stream = es_fopen (filename, "r");
622   if (! stream)
623     {
624       err = gpg_error_from_syserror ();
625       goto out;
626     }
627
628   ret = fstat (es_fileno (stream), &statbuf);
629   if (ret)
630     {
631       err = gpg_error_from_syserror ();
632       goto out;
633     }
634
635   buffer_new = xtrymalloc (statbuf.st_size);
636   if (! buffer_new)
637     {
638       err = gpg_error_from_syserror ();
639       goto out;
640     }
641
642   err = stream_read_data (stream, buffer_new, statbuf.st_size);
643   if (err)
644     goto out;
645
646   *buffer = buffer_new;
647   *buffer_n = statbuf.st_size;
648
649  out:
650
651   if (stream)
652     es_fclose (stream);
653
654   if (err)
655     xfree (buffer_new);
656
657   return err;
658 }
659
660
661
662 \f
663 /* Open the ssh control file and create it if not available. With
664    APPEND passed as true the file will be opened in append mode,
665    otherwise in read only mode.  On success a file pointer is stored
666    at the address of R_FP. */
667 static gpg_error_t
668 open_control_file (FILE **r_fp, int append)
669 {
670   gpg_error_t err;
671   char *fname;
672   FILE *fp;
673
674   /* Note: As soon as we start to use non blocking functions here
675      (i.e. where Pth might switch threads) we need to employ a
676      mutex.  */
677   *r_fp = NULL;
678   fname = make_filename (opt.homedir, "sshcontrol", NULL);
679   /* FIXME: With "a+" we are not able to check whether this will will
680      be created and thus the blurb needs to be written first.  */
681   fp = fopen (fname, append? "a+":"r");
682   if (!fp && errno == ENOENT)
683     {
684       estream_t stream = es_fopen (fname, "wx,mode=-rw-r");
685       if (!stream)
686         {
687           err = gpg_error_from_syserror ();
688           log_error (_("can't create `%s': %s\n"), fname, gpg_strerror (err));
689           xfree (fname);
690           return err;
691         }
692       es_fputs (sshcontrolblurb, stream);
693       es_fclose (stream);
694       fp = fopen (fname, append? "a+":"r");
695     }
696
697   if (!fp)
698     {
699       err = gpg_error (gpg_err_code_from_errno (errno));
700       log_error (_("can't open `%s': %s\n"), fname, gpg_strerror (err));
701       xfree (fname);
702       return err;
703     }
704
705   *r_fp = fp;
706
707   return 0;
708 }
709
710
711 /* Search the file at stream FP from the beginning until a matching
712    HEXGRIP is found; return success in this case and store true at
713    DISABLED if the found key has been disabled.  If R_TTL is not NULL
714    a specified TTL for that key is stored there.  If R_CONFIRM is not
715    NULL it is set to 1 if the key has the confirm flag set. */
716 static gpg_error_t
717 search_control_file (FILE *fp, const char *hexgrip,
718                      int *r_disabled, int *r_ttl, int *r_confirm)
719 {
720   int c, i, n;
721   char *p, *pend, line[256];
722   long ttl;
723   int lnr = 0;
724   const char fname[] = "sshcontrol";
725
726   assert (strlen (hexgrip) == 40 );
727
728   if (r_confirm)
729     *r_confirm = 0;
730
731   fseek (fp, 0, SEEK_SET);
732   clearerr (fp);
733   *r_disabled = 0;
734  next_line:
735   do
736     {
737       if (!fgets (line, DIM(line)-1, fp) )
738         {
739           if (feof (fp))
740             return gpg_error (GPG_ERR_EOF);
741           return gpg_error (gpg_err_code_from_errno (errno));
742         }
743       lnr++;
744
745       if (!*line || line[strlen(line)-1] != '\n')
746         {
747           /* Eat until end of line */
748           while ( (c=getc (fp)) != EOF && c != '\n')
749             ;
750           return gpg_error (*line? GPG_ERR_LINE_TOO_LONG
751                                  : GPG_ERR_INCOMPLETE_LINE);
752         }
753
754       /* Allow for empty lines and spaces */
755       for (p=line; spacep (p); p++)
756         ;
757     }
758   while (!*p || *p == '\n' || *p == '#');
759
760   *r_disabled = 0;
761   if (*p == '!')
762     {
763       *r_disabled = 1;
764       for (p++; spacep (p); p++)
765         ;
766     }
767
768   for (i=0; hexdigitp (p) && i < 40; p++, i++)
769     if (hexgrip[i] != (*p >= 'a'? (*p & 0xdf): *p))
770       goto next_line;
771   if (i != 40 || !(spacep (p) || *p == '\n'))
772     {
773       log_error ("invalid formatted line in `%s', line %d\n", fname, lnr);
774       return gpg_error (GPG_ERR_BAD_DATA);
775     }
776
777   ttl = strtol (p, &pend, 10);
778   p = pend;
779   if (!(spacep (p) || *p == '\n') || ttl < -1)
780     {
781       log_error ("invalid TTL value in `%s', line %d; assuming 0\n",
782                  fname, lnr);
783       ttl = 0;
784     }
785   if (r_ttl)
786     *r_ttl = ttl;
787
788   /* Now check for key-value pairs of the form NAME[=VALUE]. */
789   while (*p)
790     {
791       for (; spacep (p) && *p != '\n'; p++)
792         ;
793       if (!*p || *p == '\n')
794         break;
795       n = strcspn (p, "= \t\n");
796       if (p[n] == '=')
797         {
798           log_error ("assigning a value to a flag is not yet supported; "
799                      "in `%s', line %d; flag ignored\n", fname, lnr);
800           p++;
801         }
802       else if (n == 7 && !memcmp (p, "confirm", 7))
803         {
804           if (r_confirm)
805             *r_confirm = 1;
806         }
807       else
808         log_error ("invalid flag `%.*s' in `%s', line %d; ignored\n",
809                    n, p, fname, lnr);
810       p += n;
811     }
812
813   return 0; /* Okay:  found it.  */
814 }
815
816
817
818 /* Add an entry to the control file to mark the key with the keygrip
819    HEXGRIP as usable for SSH; i.e. it will be returned when ssh asks
820    for it.  FMTFPR is the fingerprint string.  This function is in
821    general used to add a key received through the ssh-add function.
822    We can assume that the user wants to allow ssh using this key. */
823 static gpg_error_t
824 add_control_entry (ctrl_t ctrl, const char *hexgrip, const char *fmtfpr,
825                    int ttl, int confirm)
826 {
827   gpg_error_t err;
828   FILE *fp;
829   int disabled;
830
831   (void)ctrl;
832
833   err = open_control_file (&fp, 1);
834   if (err)
835     return err;
836
837   err = search_control_file (fp, hexgrip, &disabled, NULL, NULL);
838   if (err && gpg_err_code(err) == GPG_ERR_EOF)
839     {
840       struct tm *tp;
841       time_t atime = time (NULL);
842
843       /* Not yet in the file - add it. Because the file has been
844          opened in append mode, we simply need to write to it.  */
845       tp = localtime (&atime);
846       fprintf (fp, ("# Key added on: %04d-%02d-%02d %02d:%02d:%02d\n"
847                     "# Fingerprint:  %s\n"
848                     "%s %d%s\n"),
849                1900+tp->tm_year, tp->tm_mon+1, tp->tm_mday,
850                tp->tm_hour, tp->tm_min, tp->tm_sec,
851                fmtfpr, hexgrip, ttl, confirm? " confirm":"");
852
853     }
854   fclose (fp);
855   return 0;
856 }
857
858
859 /* Scan the sshcontrol file and return the TTL.  */
860 static int
861 ttl_from_sshcontrol (const char *hexgrip)
862 {
863   FILE *fp;
864   int disabled, ttl;
865
866   if (!hexgrip || strlen (hexgrip) != 40)
867     return 0;  /* Wrong input: Use global default.  */
868
869   if (open_control_file (&fp, 0))
870     return 0; /* Error: Use the global default TTL.  */
871
872   if (search_control_file (fp, hexgrip, &disabled, &ttl, NULL)
873       || disabled)
874     ttl = 0;  /* Use the global default if not found or disabled.  */
875
876   fclose (fp);
877
878   return ttl;
879 }
880
881
882 /* Scan the sshcontrol file and return the confirm flag.  */
883 static int
884 confirm_flag_from_sshcontrol (const char *hexgrip)
885 {
886   FILE *fp;
887   int disabled, confirm;
888
889   if (!hexgrip || strlen (hexgrip) != 40)
890     return 1;  /* Wrong input: Better ask for confirmation.  */
891
892   if (open_control_file (&fp, 0))
893     return 1; /* Error: Better ask for confirmation.  */
894
895   if (search_control_file (fp, hexgrip, &disabled, NULL, &confirm)
896       || disabled)
897     confirm = 0;  /* If not found or disabled, there is no reason to
898                      ask for confirmation.  */
899
900   fclose (fp);
901
902   return confirm;
903 }
904
905
906
907 \f
908
909 /*
910
911   MPI lists.
912
913  */
914
915 /* Free the list of MPIs MPI_LIST.  */
916 static void
917 mpint_list_free (gcry_mpi_t *mpi_list)
918 {
919   if (mpi_list)
920     {
921       unsigned int i;
922
923       for (i = 0; mpi_list[i]; i++)
924         gcry_mpi_release (mpi_list[i]);
925       xfree (mpi_list);
926     }
927 }
928
929 /* Receive key material MPIs from STREAM according to KEY_SPEC;
930    depending on SECRET expect a public key or secret key.  The newly
931    allocated list of MPIs is stored in MPI_LIST.  Returns usual error
932    code.  */
933 static gpg_error_t
934 ssh_receive_mpint_list (estream_t stream, int secret,
935                         ssh_key_type_spec_t key_spec, gcry_mpi_t **mpi_list)
936 {
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
956   mpis = xtrycalloc (elems_n + 1, sizeof *mpis );
957   if (!mpis)
958     {
959       err = gpg_error_from_syserror ();
960       goto out;
961     }
962
963   elem_is_secret = 0;
964   for (i = 0; i < elems_n; i++)
965     {
966       if (secret)
967         elem_is_secret = ! strchr (elems_public, elems[i]);
968       err = stream_read_mpi (stream, elem_is_secret, &mpis[i]);
969       if (err)
970         break;
971     }
972   if (err)
973     goto out;
974
975   *mpi_list = mpis;
976
977  out:
978
979   if (err)
980     mpint_list_free (mpis);
981
982   return err;
983 }
984
985 \f
986
987 /* Key modifier function for RSA.  */
988 static gpg_error_t
989 ssh_key_modifier_rsa (const char *elems, gcry_mpi_t *mpis)
990 {
991   gcry_mpi_t p;
992   gcry_mpi_t q;
993   gcry_mpi_t u;
994
995   if (strcmp (elems, "nedupq"))
996     /* Modifying only necessary for secret keys.  */
997     goto out;
998
999   u = mpis[3];
1000   p = mpis[4];
1001   q = mpis[5];
1002
1003   if (gcry_mpi_cmp (p, q) > 0)
1004     {
1005       /* P shall be smaller then Q!  Swap primes.  iqmp becomes u.  */
1006       gcry_mpi_t tmp;
1007
1008       tmp = mpis[4];
1009       mpis[4] = mpis[5];
1010       mpis[5] = tmp;
1011     }
1012   else
1013     /* U needs to be recomputed.  */
1014     gcry_mpi_invm (u, p, q);
1015
1016  out:
1017
1018   return 0;
1019 }
1020
1021 /* Signature encoder function for RSA.  */
1022 static gpg_error_t
1023 ssh_signature_encoder_rsa (estream_t signature_blob, gcry_mpi_t *mpis)
1024 {
1025   unsigned char *data;
1026   size_t data_n;
1027   gpg_error_t err;
1028   gcry_mpi_t s;
1029
1030   s = mpis[0];
1031
1032   err = gcry_mpi_aprint (GCRYMPI_FMT_USG, &data, &data_n, s);
1033   if (err)
1034     goto out;
1035
1036   err = stream_write_string (signature_blob, data, data_n);
1037   xfree (data);
1038
1039  out:
1040
1041   return err;
1042 }
1043
1044
1045 /* Signature encoder function for DSA.  */
1046 static gpg_error_t
1047 ssh_signature_encoder_dsa (estream_t signature_blob, gcry_mpi_t *mpis)
1048 {
1049   unsigned char buffer[SSH_DSA_SIGNATURE_PADDING * SSH_DSA_SIGNATURE_ELEMS];
1050   unsigned char *data;
1051   size_t data_n;
1052   gpg_error_t err;
1053   int i;
1054
1055   data = NULL;
1056
1057   for (i = 0; i < 2; i++)
1058     {
1059       err = gcry_mpi_aprint (GCRYMPI_FMT_USG, &data, &data_n, mpis[i]);
1060       if (err)
1061         break;
1062
1063       if (data_n > SSH_DSA_SIGNATURE_PADDING)
1064         {
1065           err = gpg_error (GPG_ERR_INTERNAL); /* FIXME?  */
1066           break;
1067         }
1068
1069       memset (buffer + (i * SSH_DSA_SIGNATURE_PADDING), 0,
1070               SSH_DSA_SIGNATURE_PADDING - data_n);
1071       memcpy (buffer + (i * SSH_DSA_SIGNATURE_PADDING)
1072               + (SSH_DSA_SIGNATURE_PADDING - data_n), data, data_n);
1073
1074       xfree (data);
1075       data = NULL;
1076     }
1077   if (err)
1078     goto out;
1079
1080   err = stream_write_string (signature_blob, buffer, sizeof (buffer));
1081
1082  out:
1083
1084   xfree (data);
1085
1086   return err;
1087 }
1088
1089 /*
1090    S-Expressions.
1091  */
1092
1093
1094 /* This function constructs a new S-Expression for the key identified
1095    by the KEY_SPEC, SECRET, MPIS and COMMENT, which is to be stored in
1096    *SEXP.  Returns usual error code.  */
1097 static gpg_error_t
1098 sexp_key_construct (gcry_sexp_t *sexp,
1099                     ssh_key_type_spec_t key_spec, int secret,
1100                     gcry_mpi_t *mpis, const char *comment)
1101 {
1102   const char *key_identifier[] = { "public-key", "private-key" };
1103   gcry_sexp_t sexp_new;
1104   char *sexp_template;
1105   size_t sexp_template_n;
1106   gpg_error_t err;
1107   const char *elems;
1108   size_t elems_n;
1109   unsigned int i;
1110   unsigned int j;
1111   void **arg_list;
1112
1113   err = 0;
1114   sexp_new = NULL;
1115   arg_list = NULL;
1116   if (secret)
1117     elems = key_spec.elems_sexp_order;
1118   else
1119     elems = key_spec.elems_key_public;
1120   elems_n = strlen (elems);
1121
1122   /*
1123     Calculate size for sexp_template_n:
1124
1125     "(%s(%s<mpis>)(comment%s))" -> 20 + sizeof (<mpis>).
1126
1127     mpi: (X%m) -> 5.
1128
1129   */
1130   sexp_template_n = 20 + (elems_n * 5);
1131   sexp_template = xtrymalloc (sexp_template_n);
1132   if (! sexp_template)
1133     {
1134       err = gpg_error_from_syserror ();
1135       goto out;
1136     }
1137
1138   /* Key identifier, algorithm identifier, mpis, comment.  */
1139   arg_list = xtrymalloc (sizeof (*arg_list) * (2 + elems_n + 1));
1140   if (! arg_list)
1141     {
1142       err = gpg_error_from_syserror ();
1143       goto out;
1144     }
1145
1146   i = 0;
1147   arg_list[i++] = &key_identifier[secret];
1148   arg_list[i++] = &key_spec.identifier;
1149
1150   *sexp_template = 0;
1151   sexp_template_n = 0;
1152   sexp_template_n = sprintf (sexp_template + sexp_template_n, "(%%s(%%s");
1153   for (i = 0; i < elems_n; i++)
1154     {
1155       sexp_template_n += sprintf (sexp_template + sexp_template_n, "(%c%%m)",
1156                                   elems[i]);
1157       if (secret)
1158         {
1159           for (j = 0; j < elems_n; j++)
1160             if (key_spec.elems_key_secret[j] == elems[i])
1161               break;
1162         }
1163       else
1164         j = i;
1165       arg_list[i + 2] = &mpis[j];
1166     }
1167   sexp_template_n += sprintf (sexp_template + sexp_template_n,
1168                               ")(comment%%s))");
1169
1170   arg_list[i + 2] = &comment;
1171
1172   err = gcry_sexp_build_array (&sexp_new, NULL, sexp_template, arg_list);
1173   if (err)
1174     goto out;
1175
1176   *sexp = sexp_new;
1177
1178  out:
1179
1180   xfree (arg_list);
1181   xfree (sexp_template);
1182
1183   return err;
1184 }
1185
1186 /* This functions breaks up the key contained in the S-Expression SEXP
1187    according to KEY_SPEC.  The MPIs are bundled in a newly create
1188    list, which is to be stored in MPIS; a newly allocated string
1189    holding the comment will be stored in COMMENT; SECRET will be
1190    filled with a boolean flag specifying what kind of key it is.
1191    Returns usual error code.  */
1192 static gpg_error_t
1193 sexp_key_extract (gcry_sexp_t sexp,
1194                   ssh_key_type_spec_t key_spec, int *secret,
1195                   gcry_mpi_t **mpis, char **comment)
1196 {
1197   gpg_error_t err;
1198   gcry_sexp_t value_list;
1199   gcry_sexp_t value_pair;
1200   gcry_sexp_t comment_list;
1201   unsigned int i;
1202   char *comment_new;
1203   const char *data;
1204   size_t data_n;
1205   int is_secret;
1206   size_t elems_n;
1207   const char *elems;
1208   gcry_mpi_t *mpis_new;
1209   gcry_mpi_t mpi;
1210
1211   err = 0;
1212   value_list = NULL;
1213   value_pair = NULL;
1214   comment_list = NULL;
1215   comment_new = NULL;
1216   mpis_new = NULL;
1217
1218   data = gcry_sexp_nth_data (sexp, 0, &data_n);
1219   if (! data)
1220     {
1221       err = gpg_error (GPG_ERR_INV_SEXP);
1222       goto out;
1223     }
1224
1225   if ((data_n == 10 && !strncmp (data, "public-key", 10))
1226       || (data_n == 21 && !strncmp (data, "protected-private-key", 21))
1227       || (data_n == 20 && !strncmp (data, "shadowed-private-key", 20)))
1228     {
1229       is_secret = 0;
1230       elems = key_spec.elems_key_public;
1231     }
1232   else if (data_n == 11 && !strncmp (data, "private-key", 11))
1233     {
1234       is_secret = 1;
1235       elems = key_spec.elems_key_secret;
1236     }
1237   else
1238     {
1239       err = gpg_error (GPG_ERR_INV_SEXP);
1240       goto out;
1241     }
1242
1243   elems_n = strlen (elems);
1244   mpis_new = xtrycalloc (elems_n + 1, sizeof *mpis_new );
1245   if (!mpis_new)
1246     {
1247       err = gpg_error_from_syserror ();
1248       goto out;
1249     }
1250
1251   value_list = gcry_sexp_find_token (sexp, key_spec.identifier, 0);
1252   if (! value_list)
1253     {
1254       err = gpg_error (GPG_ERR_INV_SEXP);
1255       goto out;
1256     }
1257
1258   for (i = 0; i < elems_n; i++)
1259     {
1260       value_pair = gcry_sexp_find_token (value_list, elems + i, 1);
1261       if (! value_pair)
1262         {
1263           err = gpg_error (GPG_ERR_INV_SEXP);
1264           break;
1265         }
1266
1267       /* Note that we need to use STD format; i.e. prepend a 0x00 to
1268          indicate a positive number if the high bit is set. */
1269       mpi = gcry_sexp_nth_mpi (value_pair, 1, GCRYMPI_FMT_STD);
1270       if (! mpi)
1271         {
1272           err = gpg_error (GPG_ERR_INV_SEXP);
1273           break;
1274         }
1275       mpis_new[i] = mpi;
1276       gcry_sexp_release (value_pair);
1277       value_pair = NULL;
1278     }
1279   if (err)
1280     goto out;
1281
1282   /* We do not require a comment sublist to be present here.  */
1283   data = NULL;
1284   data_n = 0;
1285
1286   comment_list = gcry_sexp_find_token (sexp, "comment", 0);
1287   if (comment_list)
1288     data = gcry_sexp_nth_data (comment_list, 1, &data_n);
1289   if (! data)
1290     {
1291       data = "(none)";
1292       data_n = 6;
1293     }
1294
1295   comment_new = make_cstring (data, data_n);
1296   if (! comment_new)
1297     {
1298       err = gpg_error_from_syserror ();
1299       goto out;
1300     }
1301
1302   if (secret)
1303     *secret = is_secret;
1304   *mpis = mpis_new;
1305   *comment = comment_new;
1306
1307  out:
1308
1309   gcry_sexp_release (value_list);
1310   gcry_sexp_release (value_pair);
1311   gcry_sexp_release (comment_list);
1312
1313   if (err)
1314     {
1315       xfree (comment_new);
1316       mpint_list_free (mpis_new);
1317     }
1318
1319   return err;
1320 }
1321
1322 /* Extract the car from SEXP, and create a newly created C-string
1323    which is to be stored in IDENTIFIER.  */
1324 static gpg_error_t
1325 sexp_extract_identifier (gcry_sexp_t sexp, char **identifier)
1326 {
1327   char *identifier_new;
1328   gcry_sexp_t sublist;
1329   const char *data;
1330   size_t data_n;
1331   gpg_error_t err;
1332
1333   identifier_new = NULL;
1334   err = 0;
1335
1336   sublist = gcry_sexp_nth (sexp, 1);
1337   if (! sublist)
1338     {
1339       err = gpg_error (GPG_ERR_INV_SEXP);
1340       goto out;
1341     }
1342
1343   data = gcry_sexp_nth_data (sublist, 0, &data_n);
1344   if (! data)
1345     {
1346       err = gpg_error (GPG_ERR_INV_SEXP);
1347       goto out;
1348     }
1349
1350   identifier_new = make_cstring (data, data_n);
1351   if (! identifier_new)
1352     {
1353       err = gpg_err_code_from_errno (errno);
1354       goto out;
1355     }
1356
1357   *identifier = identifier_new;
1358
1359  out:
1360
1361   gcry_sexp_release (sublist);
1362
1363   return err;
1364 }
1365
1366 \f
1367
1368 /*
1369
1370   Key I/O.
1371
1372 */
1373
1374 /* Search for a key specification entry.  If SSH_NAME is not NULL,
1375    search for an entry whose "ssh_name" is equal to SSH_NAME;
1376    otherwise, search for an entry whose "name" is equal to NAME.
1377    Store found entry in SPEC on success, return error otherwise.  */
1378 static gpg_error_t
1379 ssh_key_type_lookup (const char *ssh_name, const char *name,
1380                      ssh_key_type_spec_t *spec)
1381 {
1382   gpg_error_t err;
1383   unsigned int i;
1384
1385   for (i = 0; i < DIM (ssh_key_types); i++)
1386     if ((ssh_name && (! strcmp (ssh_name, ssh_key_types[i].ssh_identifier)))
1387         || (name && (! strcmp (name, ssh_key_types[i].identifier))))
1388       break;
1389
1390   if (i == DIM (ssh_key_types))
1391     err = gpg_error (GPG_ERR_NOT_FOUND);
1392   else
1393     {
1394       *spec = ssh_key_types[i];
1395       err = 0;
1396     }
1397
1398   return err;
1399 }
1400
1401 /* Receive a key from STREAM, according to the key specification given
1402    as KEY_SPEC.  Depending on SECRET, receive a secret or a public
1403    key.  If READ_COMMENT is true, receive a comment string as well.
1404    Constructs a new S-Expression from received data and stores it in
1405    KEY_NEW.  Returns zero on success or an error code.  */
1406 static gpg_error_t
1407 ssh_receive_key (estream_t stream, gcry_sexp_t *key_new, int secret,
1408                  int read_comment, ssh_key_type_spec_t *key_spec)
1409 {
1410   gpg_error_t err;
1411   char *key_type = NULL;
1412   char *comment = NULL;
1413   gcry_sexp_t key = NULL;
1414   ssh_key_type_spec_t spec;
1415   gcry_mpi_t *mpi_list = NULL;
1416   const char *elems;
1417
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,
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);
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 }