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