d038768fe27b1c4846fdfc6cf87479e5768a3504
[gnupg.git] / agent / command-ssh.c
1 /* command-ssh.c - gpg-agent's ssh-agent emulation layer
2  * Copyright (C) 2004, 2005, 2006 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 2 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, write to the Free Software
18  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
19  * USA.
20  */
21
22 /* Only v2 of the ssh-agent protocol is implemented.  */
23
24 #include <config.h>
25
26 #include <stdio.h>
27 #include <stdlib.h>
28 #include <string.h>
29 #include <errno.h>
30 #include <sys/types.h>
31 #include <sys/stat.h>
32 #include <dirent.h>
33 #include <assert.h>
34
35 #include "agent.h"
36
37 #include "estream.h"
38 #include "i18n.h"
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_errno (errno);
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_errno (errno);
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_errno (errno);
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_errno (errno);
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_errno (errno);
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_errno (errno);
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;
425   u32 length;
426
427   buffer = NULL;
428
429   /* Read string length.  */
430   err = stream_read_uint32 (stream, &length);
431   if (err)
432     goto out;
433
434   /* Allocate space.  */
435   if (secure)
436     buffer = xtrymalloc_secure (length + 1);
437   else
438     buffer = xtrymalloc (length + 1);
439   if (! buffer)
440     {
441       err = gpg_error_from_errno (errno);
442       goto out;
443     }
444
445   /* Read data.  */
446   err = stream_read_data (stream, buffer, length);
447   if (err)
448     goto out;
449
450   /* Finalize string object.  */
451   buffer[length] = 0;
452   *string = buffer;
453   if (string_size)
454     *string_size = length;
455
456  out:
457
458   if (err)
459     xfree (buffer);
460
461   return err;
462 }
463
464 /* Read a C-string from STREAM, store copy in STRING.  */
465 static gpg_error_t
466 stream_read_cstring (estream_t stream, char **string)
467 {
468   unsigned char *buffer;
469   gpg_error_t err;
470
471   err = stream_read_string (stream, 0, &buffer, NULL);
472   if (err)
473     goto out;
474   
475   *string = (char *) buffer;
476
477  out:
478
479   return err;
480 }
481
482
483 /* Write a binary string from STRING of size STRING_N to STREAM.  */
484 static gpg_error_t
485 stream_write_string (estream_t stream,
486                      const unsigned char *string, u32 string_n)
487 {
488   gpg_error_t err;
489
490   err = stream_write_uint32 (stream, string_n);
491   if (err)
492     goto out;
493
494   err = stream_write_data (stream, string, string_n);
495
496  out:
497
498   return err;
499 }
500
501 /* Write a C-string from STRING to STREAM.  */
502 static gpg_error_t
503 stream_write_cstring (estream_t stream, const char *string)
504 {
505   gpg_error_t err;
506
507   err = stream_write_string (stream,
508                              (const unsigned char *) string, strlen (string));
509
510   return err;
511 }                         
512
513 /* Read an MPI from STREAM, store it in MPINT.  Depending on SECURE
514    use secure memory.  */
515 static gpg_error_t
516 stream_read_mpi (estream_t stream, unsigned int secure, gcry_mpi_t *mpint)
517 {
518   unsigned char *mpi_data;
519   u32 mpi_data_size;
520   gpg_error_t err;
521   gcry_mpi_t mpi;
522
523   mpi_data = NULL;
524
525   err = stream_read_string (stream, secure, &mpi_data, &mpi_data_size);
526   if (err)
527     goto out;
528
529   /* To avoid excessive use of secure memory we check that an MPI is
530      not too large. */
531   if (mpi_data_size > 520)
532     {
533       log_error (_("ssh keys greater than %d bits are not supported\n"), 4096);
534       err = GPG_ERR_TOO_LARGE;
535       goto out;
536     }
537
538   err = gcry_mpi_scan (&mpi, GCRYMPI_FMT_STD, mpi_data, mpi_data_size, NULL);
539   if (err)
540     goto out;
541
542   *mpint = mpi;
543
544  out:
545
546   xfree (mpi_data);
547
548   return err;
549 }
550
551 /* Write the MPI contained in MPINT to STREAM.  */
552 static gpg_error_t
553 stream_write_mpi (estream_t stream, gcry_mpi_t mpint)
554 {
555   unsigned char *mpi_buffer;
556   size_t mpi_buffer_n;
557   gpg_error_t err;
558
559   mpi_buffer = NULL;
560
561   err = gcry_mpi_aprint (GCRYMPI_FMT_STD, &mpi_buffer, &mpi_buffer_n, mpint);
562   if (err)
563     goto out;
564
565   err = stream_write_string (stream, mpi_buffer, mpi_buffer_n);
566
567  out:
568
569   xfree (mpi_buffer);
570
571   return err;
572 }
573
574 /* Copy data from SRC to DST until EOF is reached.  */
575 static gpg_error_t
576 stream_copy (estream_t dst, estream_t src)
577 {
578   char buffer[BUFSIZ];
579   size_t bytes_read;
580   gpg_error_t err;
581   int ret;
582
583   err = 0;
584   while (1)
585     {
586       ret = es_read (src, buffer, sizeof (buffer), &bytes_read);
587       if (ret || (! bytes_read))
588         {
589           if (ret)
590             err = gpg_error_from_errno (errno);
591           break;
592         }
593       ret = es_write (dst, buffer, bytes_read, NULL);
594       if (ret)
595         {
596           err = gpg_error_from_errno (errno);
597           break;
598         }
599     }
600
601   return err;
602 }
603
604
605 /* Read the content of the file specified by FILENAME into a newly
606    create buffer, which is to be stored in BUFFER; store length of
607    buffer in BUFFER_N.  */
608 static gpg_error_t
609 file_to_buffer (const char *filename, unsigned char **buffer, size_t *buffer_n)
610 {
611   unsigned char *buffer_new;
612   struct stat statbuf;
613   estream_t stream;
614   gpg_error_t err;
615   int ret;
616
617   *buffer = NULL;
618   *buffer_n = 0;
619
620   buffer_new = NULL;
621   err = 0;
622   
623   stream = es_fopen (filename, "r");
624   if (! stream)
625     {
626       err = gpg_error_from_errno (errno);
627       goto out;
628     }
629
630   ret = fstat (es_fileno (stream), &statbuf);
631   if (ret)
632     {
633       err = gpg_error_from_errno (errno);
634       goto out;
635     }
636
637   buffer_new = xtrymalloc (statbuf.st_size);
638   if (! buffer_new)
639     {
640       err = gpg_error_from_errno (errno);
641       goto out;
642     }
643
644   err = stream_read_data (stream, buffer_new, statbuf.st_size);
645   if (err)
646     goto out;
647
648   *buffer = buffer_new;
649   *buffer_n = statbuf.st_size;
650
651  out:
652
653   if (stream)
654     es_fclose (stream);
655
656   if (err)
657     xfree (buffer_new);
658
659   return err;
660 }
661
662
663
664 \f
665 /* Open the ssh control file and create it if not available. With
666    APPEND passed as true the file will be opened in append mode,
667    otherwise in read only mode.  On success a file pointer is stored
668    at the address of R_FP. */
669 static gpg_error_t
670 open_control_file (FILE **r_fp, int append)
671 {
672   gpg_error_t err;
673   char *fname;
674   FILE *fp;
675
676   /* Note: As soon as we start to use non blocking functions here
677      (i.e. where Pth might switch threads) we need to employ a
678      mutex.  */
679   *r_fp = NULL;
680   fname = make_filename (opt.homedir, "sshcontrol", NULL);
681   /* FIXME: With "a+" we are not able to check whether this will will
682      be created and thus the blurb needs to be written first.  */
683   fp = fopen (fname, append? "a+":"r");
684   if (!fp && errno == ENOENT)
685     {
686       /* Fixme: "x" is a GNU extension.  We might want to use the es_
687          functions here.  */
688       fp = fopen (fname, "wx");  
689       if (!fp)
690         {
691           err = gpg_error (gpg_err_code_from_errno (errno));
692           log_error (_("can't create `%s': %s\n"), fname, gpg_strerror (err));
693           xfree (fname);
694           return err;
695         }
696       fputs (sshcontrolblurb, fp);
697       fclose (fp);
698       fp = fopen (fname, append? "a+":"r");
699     }
700
701   if (!fp)
702     {
703       err = gpg_error (gpg_err_code_from_errno (errno));
704       log_error (_("can't open `%s': %s\n"), fname, gpg_strerror (err));
705       xfree (fname);
706       return err;
707     }
708   
709   *r_fp = fp;  
710
711   return 0;
712 }
713
714
715 /* Search the file at stream FP from the beginning until a matching
716    HEXGRIP is found; return success in this case and store true at
717    DISABLED if the found key has been disabled.  */
718 static gpg_error_t
719 search_control_file (FILE *fp, const char *hexgrip, int *disabled)
720 {
721   int c, i;
722   char *p, line[256];
723   
724   assert (strlen (hexgrip) == 40 );
725
726   rewind (fp);
727   *disabled = 0;
728  next_line:
729   do
730     {
731       if (!fgets (line, DIM(line)-1, fp) )
732         {
733           if (feof (fp))
734             return gpg_error (GPG_ERR_EOF);
735           return gpg_error (gpg_err_code_from_errno (errno));
736         }
737       
738       if (!*line || line[strlen(line)-1] != '\n')
739         {
740           /* Eat until end of line */
741           while ( (c=getc (fp)) != EOF && c != '\n')
742             ;
743           return gpg_error (*line? GPG_ERR_LINE_TOO_LONG
744                                  : GPG_ERR_INCOMPLETE_LINE);
745         }
746       
747       /* Allow for empty lines and spaces */
748       for (p=line; spacep (p); p++)
749         ;
750     }
751   while (!*p || *p == '\n' || *p == '#');
752   
753   *disabled = 0;
754   if (*p == '!')
755     {
756       *disabled = 1;
757       for (p++; spacep (p); p++)
758         ;
759     }
760
761   for (i=0; hexdigitp (p) && i < 40; p++, i++)
762     if (hexgrip[i] != (*p >= 'a'? (*p & 0xdf): *p))
763       goto next_line;
764   if (i != 40 || !(spacep (p) || *p == '\n'))
765     {
766       log_error ("invalid formatted line in ssh control file\n");
767       return gpg_error (GPG_ERR_BAD_DATA);
768     }
769
770   /* Fixme: Get TTL and flags.  */
771
772   return 0; /* Okay:  found it.  */
773 }
774
775
776
777 /* Add an entry to the control file to mark the key with the keygrip
778    HEXGRIP as usable for SSH; i.e. it will be returned when ssh asks
779    for it.  This function is in general used to add a key received
780    through the ssh-add function.  We can assume that the user wants to
781    allow ssh using this key. */
782 static gpg_error_t
783 add_control_entry (ctrl_t ctrl, const char *hexgrip, int ttl)
784 {
785   gpg_error_t err;
786   FILE *fp;
787   int disabled;
788
789   err = open_control_file (&fp, 1);
790   if (err)
791     return err;
792
793   err = search_control_file (fp, hexgrip, &disabled);
794   if (err && gpg_err_code(err) == GPG_ERR_EOF)
795     {
796       struct tm *tp;
797       time_t atime = time (NULL);
798
799       /* Not yet in the file - add it. Becuase the file has been
800          opened in append mode, we simply need to write to it.  */
801       tp = localtime (&atime);
802       fprintf (fp, "# Key added on %04d-%02d-%02d %02d:%02d:%02d\n%s %d\n",
803                1900+tp->tm_year, tp->tm_mon+1, tp->tm_mday,
804                tp->tm_hour, tp->tm_min, tp->tm_sec,
805                hexgrip, ttl);
806                
807     }
808   fclose (fp);
809   return 0;
810 }
811
812
813
814 \f
815
816 /*
817
818   MPI lists. 
819
820  */
821
822 /* Free the list of MPIs MPI_LIST.  */
823 static void
824 mpint_list_free (gcry_mpi_t *mpi_list)
825 {
826   if (mpi_list)
827     {
828       unsigned int i;
829
830       for (i = 0; mpi_list[i]; i++)
831         gcry_mpi_release (mpi_list[i]);
832       xfree (mpi_list);
833     }
834 }
835
836 /* Receive key material MPIs from STREAM according to KEY_SPEC;
837    depending on SECRET expect a public key or secret key.  The newly
838    allocated list of MPIs is stored in MPI_LIST.  Returns usual error
839    code.  */
840 static gpg_error_t
841 ssh_receive_mpint_list (estream_t stream, int secret,
842                         ssh_key_type_spec_t key_spec, gcry_mpi_t **mpi_list)
843 {
844   unsigned int elems_public_n;
845   const char *elems_public;
846   unsigned int elems_n;
847   const char *elems;
848   int elem_is_secret;
849   gcry_mpi_t *mpis;
850   gpg_error_t err;
851   unsigned int i;
852
853   mpis = NULL;
854   err = 0;
855   
856   if (secret)
857     elems = key_spec.elems_key_secret;
858   else
859     elems = key_spec.elems_key_public;
860   elems_n = strlen (elems);
861
862   elems_public = key_spec.elems_key_public;
863   elems_public_n = strlen (elems_public);
864
865   mpis = xtrycalloc (elems_n + 1, sizeof *mpis );
866   if (!mpis)
867     {
868       err = gpg_error_from_errno (errno);
869       goto out;
870     }
871
872   elem_is_secret = 0;
873   for (i = 0; i < elems_n; i++)
874     {
875       if (secret)
876         elem_is_secret = ! strchr (elems_public, elems[i]);
877       err = stream_read_mpi (stream, elem_is_secret, &mpis[i]);
878       if (err)
879         break;
880     }
881   if (err)
882     goto out;
883
884   *mpi_list = mpis;
885
886  out:
887
888   if (err)
889     mpint_list_free (mpis);
890
891   return err;
892 }
893
894 \f
895
896 /* Key modifier function for RSA.  */
897 static gpg_error_t
898 ssh_key_modifier_rsa (const char *elems, gcry_mpi_t *mpis)
899 {
900   gcry_mpi_t p;
901   gcry_mpi_t q;
902   gcry_mpi_t u;
903
904   if (strcmp (elems, "nedupq"))
905     /* Modifying only necessary for secret keys.  */
906     goto out;
907
908   u = mpis[3];
909   p = mpis[4];
910   q = mpis[5];
911
912   if (gcry_mpi_cmp (p, q) > 0)
913     {
914       /* P shall be smaller then Q!  Swap primes.  iqmp becomes u.  */
915       gcry_mpi_t tmp;
916
917       tmp = mpis[4];
918       mpis[4] = mpis[5];
919       mpis[5] = tmp;
920     }
921   else
922     /* U needs to be recomputed.  */
923     gcry_mpi_invm (u, p, q);
924
925  out:
926
927   return 0;
928 }
929
930 /* Signature encoder function for RSA.  */
931 static gpg_error_t
932 ssh_signature_encoder_rsa (estream_t signature_blob, gcry_mpi_t *mpis)
933 {
934   unsigned char *data;
935   size_t data_n;
936   gpg_error_t err;
937   gcry_mpi_t s;
938
939   s = mpis[0];
940
941   err = gcry_mpi_aprint (GCRYMPI_FMT_USG, &data, &data_n, s);
942   if (err)
943     goto out;
944
945   err = stream_write_string (signature_blob, data, data_n);
946   xfree (data);
947
948  out:
949
950   return err;
951 }
952
953
954 /* Signature encoder function for DSA.  */
955 static gpg_error_t
956 ssh_signature_encoder_dsa (estream_t signature_blob, gcry_mpi_t *mpis)
957 {
958   unsigned char buffer[SSH_DSA_SIGNATURE_PADDING * SSH_DSA_SIGNATURE_ELEMS];
959   unsigned char *data;
960   size_t data_n;
961   gpg_error_t err;
962   int i;
963
964   data = NULL;
965
966   for (i = 0; i < 2; i++)
967     {
968       err = gcry_mpi_aprint (GCRYMPI_FMT_USG, &data, &data_n, mpis[i]);
969       if (err)
970         break;
971
972       if (data_n > SSH_DSA_SIGNATURE_PADDING)
973         {
974           err = gpg_error (GPG_ERR_INTERNAL); /* FIXME?  */
975           break;
976         }
977       
978       memset (buffer + (i * SSH_DSA_SIGNATURE_PADDING), 0,
979               SSH_DSA_SIGNATURE_PADDING - data_n);
980       memcpy (buffer + (i * SSH_DSA_SIGNATURE_PADDING)
981               + (SSH_DSA_SIGNATURE_PADDING - data_n), data, data_n);
982
983       xfree (data);
984       data = NULL;
985     }
986   if (err)
987     goto out;
988
989   err = stream_write_string (signature_blob, buffer, sizeof (buffer));
990
991  out:
992
993   xfree (data);
994
995   return err;
996 }
997
998 /* 
999    S-Expressions. 
1000  */
1001
1002
1003 /* This function constructs a new S-Expression for the key identified
1004    by the KEY_SPEC, SECRET, MPIS and COMMENT, which is to be stored in
1005    *SEXP.  Returns usual error code.  */
1006 static gpg_error_t
1007 sexp_key_construct (gcry_sexp_t *sexp,
1008                     ssh_key_type_spec_t key_spec, int secret,
1009                     gcry_mpi_t *mpis, const char *comment)
1010 {
1011   const char *key_identifier[] = { "public-key", "private-key" };
1012   gcry_sexp_t sexp_new;
1013   char *sexp_template;
1014   size_t sexp_template_n;
1015   gpg_error_t err;
1016   const char *elems;
1017   size_t elems_n;
1018   unsigned int i;
1019   unsigned int j;
1020   void **arg_list;
1021
1022   err = 0;
1023   sexp_new = NULL;
1024   arg_list = NULL;
1025   if (secret)
1026     elems = key_spec.elems_sexp_order;
1027   else
1028     elems = key_spec.elems_key_public;
1029   elems_n = strlen (elems);
1030
1031   /*
1032     Calculate size for sexp_template_n:
1033
1034     "(%s(%s<mpis>)(comment%s))" -> 20 + sizeof (<mpis>).
1035
1036     mpi: (X%m) -> 5.
1037
1038   */
1039   sexp_template_n = 20 + (elems_n * 5);
1040   sexp_template = xtrymalloc (sexp_template_n);
1041   if (! sexp_template)
1042     {
1043       err = gpg_error_from_errno (errno);
1044       goto out;
1045     }
1046
1047   /* Key identifier, algorithm identifier, mpis, comment.  */
1048   arg_list = xtrymalloc (sizeof (*arg_list) * (2 + elems_n + 1));
1049   if (! arg_list)
1050     {
1051       err = gpg_error_from_errno (errno);
1052       goto out;
1053     }
1054
1055   i = 0;
1056   arg_list[i++] = &key_identifier[secret];
1057   arg_list[i++] = &key_spec.identifier;
1058
1059   *sexp_template = 0;
1060   sexp_template_n = 0;
1061   sexp_template_n = sprintf (sexp_template + sexp_template_n, "(%%s(%%s");
1062   for (i = 0; i < elems_n; i++)
1063     {
1064       sexp_template_n += sprintf (sexp_template + sexp_template_n, "(%c%%m)",
1065                                   elems[i]);
1066       if (secret)
1067         {
1068           for (j = 0; j < elems_n; j++)
1069             if (key_spec.elems_key_secret[j] == elems[i])
1070               break;
1071         }
1072       else
1073         j = i;
1074       arg_list[i + 2] = &mpis[j];
1075     }
1076   sexp_template_n += sprintf (sexp_template + sexp_template_n,
1077                               ")(comment%%s))");
1078
1079   arg_list[i + 2] = &comment;
1080
1081   err = gcry_sexp_build_array (&sexp_new, NULL, sexp_template, arg_list);
1082   if (err)
1083     goto out;
1084
1085   *sexp = sexp_new;
1086
1087  out:
1088
1089   xfree (arg_list);
1090   xfree (sexp_template);
1091
1092   return err;
1093 }
1094
1095 /* This functions breaks up the key contained in the S-Expression SEXP
1096    according to KEY_SPEC.  The MPIs are bundled in a newly create
1097    list, which is to be stored in MPIS; a newly allocated string
1098    holding the comment will be stored in COMMENT; SECRET will be
1099    filled with a boolean flag specifying what kind of key it is.
1100    Returns usual error code.  */
1101 static gpg_error_t
1102 sexp_key_extract (gcry_sexp_t sexp,
1103                   ssh_key_type_spec_t key_spec, int *secret,
1104                   gcry_mpi_t **mpis, char **comment)
1105 {
1106   gpg_error_t err;
1107   gcry_sexp_t value_list;
1108   gcry_sexp_t value_pair;
1109   gcry_sexp_t comment_list;
1110   unsigned int i;
1111   char *comment_new;
1112   const char *data;
1113   size_t data_n;
1114   int is_secret;
1115   size_t elems_n;
1116   const char *elems;
1117   gcry_mpi_t *mpis_new;
1118   gcry_mpi_t mpi;
1119
1120   err = 0;
1121   value_list = NULL;
1122   value_pair = NULL;
1123   comment_list = NULL;
1124   comment_new = NULL;
1125   mpis_new = NULL;
1126
1127   data = gcry_sexp_nth_data (sexp, 0, &data_n);
1128   if (! data)
1129     {
1130       err = gpg_error (GPG_ERR_INV_SEXP);
1131       goto out;
1132     }
1133
1134   if ((data_n == 10 && !strncmp (data, "public-key", 10))
1135       || (data_n == 21 && !strncmp (data, "protected-private-key", 21))
1136       || (data_n == 20 && !strncmp (data, "shadowed-private-key", 20)))
1137     {
1138       is_secret = 0;
1139       elems = key_spec.elems_key_public;
1140     }
1141   else if (data_n == 11 && !strncmp (data, "private-key", 11))
1142     {
1143       is_secret = 1;
1144       elems = key_spec.elems_key_secret;
1145     }
1146   else
1147     {
1148       err = gpg_error (GPG_ERR_INV_SEXP);
1149       goto out;
1150     }
1151
1152   elems_n = strlen (elems);
1153   mpis_new = xtrycalloc (elems_n + 1, sizeof *mpis_new );
1154   if (!mpis_new)
1155     {
1156       err = gpg_error_from_errno (errno);
1157       goto out;
1158     }
1159
1160   value_list = gcry_sexp_find_token (sexp, key_spec.identifier, 0);
1161   if (! value_list)
1162     {
1163       err = gpg_error (GPG_ERR_INV_SEXP);
1164       goto out;
1165     }
1166
1167   for (i = 0; i < elems_n; i++)
1168     {
1169       value_pair = gcry_sexp_find_token (value_list, elems + i, 1);
1170       if (! value_pair)
1171         {
1172           err = gpg_error (GPG_ERR_INV_SEXP);
1173           break;
1174         }
1175
1176       /* Note that we need to use STD format; i.e. prepend a 0x00 to
1177          indicate a positive number if the high bit is set. */
1178       mpi = gcry_sexp_nth_mpi (value_pair, 1, GCRYMPI_FMT_STD);
1179       if (! mpi)
1180         {
1181           err = gpg_error (GPG_ERR_INV_SEXP);
1182           break;
1183         }
1184       mpis_new[i] = mpi;
1185       gcry_sexp_release (value_pair);
1186       value_pair = NULL;
1187     }
1188   if (err)
1189     goto out;
1190
1191   /* We do not require a comment sublist to be present here.  */
1192   data = NULL;
1193   data_n = 0;
1194
1195   comment_list = gcry_sexp_find_token (sexp, "comment", 0);
1196   if (comment_list)
1197     data = gcry_sexp_nth_data (comment_list, 1, &data_n);
1198   if (! data)
1199     {
1200       data = "(none)";
1201       data_n = 6;
1202     }
1203
1204   comment_new = make_cstring (data, data_n);
1205   if (! comment_new)
1206     {
1207       err = gpg_error_from_errno (errno);
1208       goto out;
1209     }
1210
1211   if (secret)
1212     *secret = is_secret;
1213   *mpis = mpis_new;
1214   *comment = comment_new;
1215
1216  out:
1217
1218   gcry_sexp_release (value_list);
1219   gcry_sexp_release (value_pair);
1220   gcry_sexp_release (comment_list);
1221   
1222   if (err)
1223     {
1224       xfree (comment_new);
1225       mpint_list_free (mpis_new);
1226     }
1227
1228   return err;
1229 }
1230
1231 /* Extract the car from SEXP, and create a newly created C-string 
1232    which is to be stored in IDENTIFIER.  */
1233 static gpg_error_t
1234 sexp_extract_identifier (gcry_sexp_t sexp, char **identifier)
1235 {
1236   char *identifier_new;
1237   gcry_sexp_t sublist;
1238   const char *data;
1239   size_t data_n;
1240   gpg_error_t err;
1241
1242   identifier_new = NULL;
1243   err = 0;
1244   
1245   sublist = gcry_sexp_nth (sexp, 1);
1246   if (! sublist)
1247     {
1248       err = gpg_error (GPG_ERR_INV_SEXP);
1249       goto out;
1250     }
1251
1252   data = gcry_sexp_nth_data (sublist, 0, &data_n);
1253   if (! data)
1254     {
1255       err = gpg_error (GPG_ERR_INV_SEXP);
1256       goto out;
1257     }
1258
1259   identifier_new = make_cstring (data, data_n);
1260   if (! identifier_new)
1261     {
1262       err = gpg_err_code_from_errno (errno);
1263       goto out;
1264     }
1265
1266   *identifier = identifier_new;
1267
1268  out:
1269
1270   gcry_sexp_release (sublist);
1271
1272   return err;
1273 }
1274
1275 \f
1276
1277 /*
1278
1279   Key I/O.
1280
1281 */
1282
1283 /* Search for a key specification entry.  If SSH_NAME is not NULL,
1284    search for an entry whose "ssh_name" is equal to SSH_NAME;
1285    otherwise, search for an entry whose "name" is equal to NAME.
1286    Store found entry in SPEC on success, return error otherwise.  */
1287 static gpg_error_t
1288 ssh_key_type_lookup (const char *ssh_name, const char *name,
1289                      ssh_key_type_spec_t *spec)
1290 {
1291   gpg_error_t err;
1292   unsigned int i;
1293
1294   for (i = 0; i < DIM (ssh_key_types); i++)
1295     if ((ssh_name && (! strcmp (ssh_name, ssh_key_types[i].ssh_identifier)))
1296         || (name && (! strcmp (name, ssh_key_types[i].identifier))))
1297       break;
1298   
1299   if (i == DIM (ssh_key_types))
1300     err = gpg_error (GPG_ERR_NOT_FOUND);
1301   else
1302     {
1303       *spec = ssh_key_types[i];
1304       err = 0;
1305     }
1306
1307   return err;
1308 }
1309
1310 /* Receive a key from STREAM, according to the key specification given
1311    as KEY_SPEC.  Depending on SECRET, receive a secret or a public
1312    key.  If READ_COMMENT is true, receive a comment string as well.
1313    Constructs a new S-Expression from received data and stores it in
1314    KEY_NEW.  Returns zero on success or an error code.  */
1315 static gpg_error_t
1316 ssh_receive_key (estream_t stream, gcry_sexp_t *key_new, int secret,
1317                  int read_comment, ssh_key_type_spec_t *key_spec)
1318 {
1319   gpg_error_t err;
1320   char *key_type;
1321   char *comment;
1322   gcry_sexp_t key;
1323   ssh_key_type_spec_t spec;
1324   gcry_mpi_t *mpi_list;
1325   const char *elems;
1326
1327   mpi_list = NULL;
1328   key_type = NULL;
1329   comment = "";
1330   key = NULL;
1331         
1332   err = stream_read_cstring (stream, &key_type);
1333   if (err)
1334     goto out;
1335
1336   err = ssh_key_type_lookup (key_type, NULL, &spec);
1337   if (err)
1338     goto out;
1339
1340   err = ssh_receive_mpint_list (stream, secret, spec, &mpi_list);
1341   if (err)
1342     goto out;
1343
1344   if (read_comment)
1345     {
1346       err = stream_read_cstring (stream, &comment);
1347       if (err)
1348         goto out;
1349     }
1350
1351   if (secret)
1352     elems = spec.elems_key_secret;
1353   else
1354     elems = spec.elems_key_public;
1355
1356   if (spec.key_modifier)
1357     {
1358       err = (*spec.key_modifier) (elems, mpi_list);
1359       if (err)
1360         goto out;
1361     }
1362
1363   err = sexp_key_construct (&key, spec, secret, mpi_list, comment);
1364   if (err)
1365     goto out;
1366
1367   if (key_spec)
1368     *key_spec = spec;
1369   *key_new = key;
1370   
1371  out:
1372
1373   mpint_list_free (mpi_list);
1374   xfree (key_type);
1375   if (read_comment)
1376     xfree (comment);
1377
1378   return err;
1379 }
1380
1381 /* Converts a key of type TYPE, whose key material is given in MPIS,
1382    into a newly created binary blob, which is to be stored in
1383    BLOB/BLOB_SIZE.  Returns zero on success or an error code.  */
1384 static gpg_error_t
1385 ssh_convert_key_to_blob (unsigned char **blob, size_t *blob_size,
1386                          const char *type, gcry_mpi_t *mpis)
1387 {
1388   unsigned char *blob_new;
1389   long int blob_size_new;
1390   estream_t stream;
1391   gpg_error_t err;
1392   unsigned int i;
1393
1394   *blob = NULL;
1395   *blob_size = 0;
1396
1397   blob_new = NULL;
1398   stream = NULL;
1399   err = 0;
1400
1401   stream = es_mopen (NULL, 0, 0, 1, NULL, NULL, "r+");
1402   if (! stream)
1403     {
1404       err = gpg_error_from_errno (errno);
1405       goto out;
1406     }
1407
1408   err = stream_write_cstring (stream, type);
1409   if (err)
1410     goto out;
1411
1412   for (i = 0; mpis[i] && (! err); i++)
1413     err = stream_write_mpi (stream, mpis[i]);
1414   if (err)
1415     goto out;
1416
1417   blob_size_new = es_ftell (stream);
1418   if (blob_size_new == -1)
1419     {
1420       err = gpg_error_from_errno (errno);
1421       goto out;
1422     }
1423   
1424   err = es_fseek (stream, 0, SEEK_SET);
1425   if (err)
1426     goto out;
1427
1428   blob_new = xtrymalloc (blob_size_new);
1429   if (! blob_new)
1430     {
1431       err = gpg_error_from_errno (errno);
1432       goto out;
1433     }
1434
1435   err = stream_read_data (stream, blob_new, blob_size_new);
1436   if (err)
1437     goto out;
1438
1439   *blob = blob_new;
1440   *blob_size = blob_size_new;
1441
1442  out:
1443
1444   if (stream)
1445     es_fclose (stream);
1446   if (err)
1447     xfree (blob_new);
1448
1449   return err;
1450 }
1451                               
1452
1453 /* Write the public key KEY_PUBLIC to STREAM in SSH key format.  If
1454    OVERRIDE_COMMENT is not NULL, it will be used instead of the
1455    comment stored in the key.  */
1456 static gpg_error_t
1457 ssh_send_key_public (estream_t stream, gcry_sexp_t key_public,
1458                      const char *override_comment)
1459 {
1460   ssh_key_type_spec_t spec;
1461   gcry_mpi_t *mpi_list;
1462   char *key_type;
1463   char *comment;
1464   unsigned char *blob;
1465   size_t blob_n;
1466   gpg_error_t err;
1467
1468   key_type = NULL;
1469   mpi_list = NULL;
1470   comment = NULL;
1471   blob = NULL;
1472
1473   err = sexp_extract_identifier (key_public, &key_type);
1474   if (err)
1475     goto out;
1476
1477   err = ssh_key_type_lookup (NULL, key_type, &spec);
1478   if (err)
1479     goto out;
1480
1481   err = sexp_key_extract (key_public, spec, NULL, &mpi_list, &comment);
1482   if (err)
1483     goto out;
1484
1485   err = ssh_convert_key_to_blob (&blob, &blob_n,
1486                                  spec.ssh_identifier, mpi_list);
1487   if (err)
1488     goto out;
1489   
1490   err = stream_write_string (stream, blob, blob_n);
1491   if (err)
1492     goto out;
1493
1494   err = stream_write_cstring (stream,
1495                               override_comment? override_comment : comment);
1496   
1497  out:
1498
1499   mpint_list_free (mpi_list);
1500   xfree (key_type);
1501   xfree (comment);
1502   xfree (blob);
1503
1504   return err;
1505 }
1506
1507 /* Read a public key out of BLOB/BLOB_SIZE according to the key
1508    specification given as KEY_SPEC, storing the new key in KEY_PUBLIC.
1509    Returns zero on success or an error code.  */
1510 static gpg_error_t
1511 ssh_read_key_public_from_blob (unsigned char *blob, size_t blob_size,
1512                                gcry_sexp_t *key_public,
1513                                ssh_key_type_spec_t *key_spec)
1514 {
1515   estream_t blob_stream;
1516   gpg_error_t err;
1517
1518   err = 0;
1519   
1520   blob_stream = es_mopen (NULL, 0, 0, 1, NULL, NULL, "r+");
1521   if (! blob_stream)
1522     {
1523       err = gpg_error_from_errno (errno);
1524       goto out;
1525     }
1526
1527   err = stream_write_data (blob_stream, blob, blob_size);
1528   if (err)
1529     goto out;
1530
1531   err = es_fseek (blob_stream, 0, SEEK_SET);
1532   if (err)
1533     goto out;
1534
1535   err = ssh_receive_key (blob_stream, key_public, 0, 0, key_spec);
1536
1537  out:
1538
1539   if (blob_stream)
1540     es_fclose (blob_stream);
1541
1542   return err;
1543 }
1544
1545 \f
1546
1547 /* This function calculates the key grip for the key contained in the
1548    S-Expression KEY and writes it to BUFFER, which must be large
1549    enough to hold it.  Returns usual error code.  */
1550 static gpg_error_t
1551 ssh_key_grip (gcry_sexp_t key, unsigned char *buffer)
1552 {
1553   if (!gcry_pk_get_keygrip (key, buffer))
1554     return gpg_error (GPG_ERR_INTERNAL);
1555
1556   return 0;
1557 }
1558
1559 /* Converts the secret key KEY_SECRET into a public key, storing it in
1560    KEY_PUBLIC.  SPEC is the according key specification.  Returns zero
1561    on success or an error code.  */
1562 static gpg_error_t
1563 key_secret_to_public (gcry_sexp_t *key_public,
1564                       ssh_key_type_spec_t spec, gcry_sexp_t key_secret)
1565 {
1566   char *comment;
1567   gcry_mpi_t *mpis;
1568   gpg_error_t err;
1569   int is_secret;
1570
1571   comment = NULL;
1572   mpis = NULL;
1573
1574   err = sexp_key_extract (key_secret, spec, &is_secret, &mpis, &comment);
1575   if (err)
1576     goto out;
1577
1578   err = sexp_key_construct (key_public, spec, 0, mpis, comment);
1579
1580  out:
1581
1582   mpint_list_free (mpis);
1583   xfree (comment);
1584
1585   return err;
1586 }
1587
1588
1589 /* Check whether a smartcard is available and whether it has a usable
1590    key.  Store a copy of that key at R_PK and return 0.  If no key is
1591    available store NULL at R_PK and return an error code.  If CARDSN
1592    is not NULL, a string with the serial number of the card will be
1593    a malloced and stored there. */
1594 static gpg_error_t
1595 card_key_available (ctrl_t ctrl, gcry_sexp_t *r_pk, char **cardsn)
1596 {
1597   gpg_error_t err;
1598   char *authkeyid;
1599   char *serialno = NULL;
1600   unsigned char *pkbuf;
1601   size_t pkbuflen;
1602   gcry_sexp_t s_pk;
1603   unsigned char grip[20];
1604
1605   *r_pk = NULL;
1606   if (cardsn)
1607     *cardsn = NULL;
1608
1609   /* First see whether a card is available and whether the application
1610      is supported.  */
1611   err = agent_card_getattr (ctrl, "$AUTHKEYID", &authkeyid);
1612   if ( gpg_err_code (err) == GPG_ERR_CARD_REMOVED )
1613     {
1614       /* Ask for the serial number to reset the card.  */
1615       err = agent_card_serialno (ctrl, &serialno);
1616       if (err)
1617         {
1618           if (opt.verbose)
1619             log_info (_("error getting serial number of card: %s\n"),
1620                       gpg_strerror (err));
1621           return err;
1622         }
1623       log_info (_("detected card with S/N: %s\n"), serialno);
1624       err = agent_card_getattr (ctrl, "$AUTHKEYID", &authkeyid);
1625     }
1626   if (err)
1627     {
1628       log_error (_("error getting default authentication keyID of card: %s\n"),
1629                  gpg_strerror (err));
1630       xfree (serialno);
1631       return err;
1632     }
1633
1634   /* Get the S/N if we don't have it yet.  Use the fast getattr method.  */
1635   if (!serialno && (err = agent_card_getattr (ctrl, "SERIALNO", &serialno)) )
1636     {
1637       log_error (_("error getting serial number of card: %s\n"),
1638                  gpg_strerror (err));
1639       xfree (authkeyid);
1640       return err;
1641     }
1642
1643   /* Read the public key.  */
1644   err = agent_card_readkey (ctrl, authkeyid, &pkbuf);
1645   if (err)
1646     {
1647       if (opt.verbose)
1648         log_info (_("no suitable card key found: %s\n"), gpg_strerror (err));
1649       xfree (serialno);
1650       xfree (authkeyid);
1651       return err;
1652     }
1653
1654   pkbuflen = gcry_sexp_canon_len (pkbuf, 0, NULL, NULL);
1655   err = gcry_sexp_sscan (&s_pk, NULL, (char*)pkbuf, pkbuflen);
1656   if (err)
1657     {
1658       log_error ("failed to build S-Exp from received card key: %s\n",
1659                  gpg_strerror (err));
1660       xfree (pkbuf);
1661       xfree (serialno);
1662       xfree (authkeyid);
1663       return err;
1664     }
1665
1666   err = ssh_key_grip (s_pk, grip);
1667   if (err)
1668     {
1669       log_debug ("error computing keygrip from received card key: %s\n",
1670                  gcry_strerror (err));
1671       xfree (pkbuf);
1672       gcry_sexp_release (s_pk);
1673       xfree (serialno);
1674       xfree (authkeyid);
1675       return err;
1676     }
1677
1678   if ( agent_key_available (grip) )
1679     {
1680       /* (Shadow)-key is not available in our key storage.  */
1681       unsigned char *shadow_info;
1682       unsigned char *tmp;
1683       
1684       shadow_info = make_shadow_info (serialno, authkeyid);
1685       if (!shadow_info)
1686         {
1687           err = gpg_error_from_errno (errno);
1688           xfree (pkbuf);
1689           gcry_sexp_release (s_pk);
1690           xfree (serialno);
1691           xfree (authkeyid);
1692           return err;
1693         }
1694       err = agent_shadow_key (pkbuf, shadow_info, &tmp);
1695       xfree (shadow_info);
1696       if (err)
1697         {
1698           log_error (_("shadowing the key failed: %s\n"), gpg_strerror (err));
1699           xfree (pkbuf);
1700           gcry_sexp_release (s_pk);
1701           xfree (serialno);
1702           xfree (authkeyid);
1703           return err;
1704         }
1705       xfree (pkbuf);
1706       pkbuf = tmp;
1707       pkbuflen = gcry_sexp_canon_len (pkbuf, 0, NULL, NULL);
1708       assert (pkbuflen);
1709
1710       err = agent_write_private_key (grip, pkbuf, pkbuflen, 0);
1711       if (err)
1712         {
1713           log_error (_("error writing key: %s\n"), gpg_strerror (err));
1714           xfree (pkbuf);
1715           gcry_sexp_release (s_pk);
1716           xfree (serialno);
1717           xfree (authkeyid);
1718           return err;
1719         }
1720     }
1721
1722   if (cardsn)
1723     {
1724       char *dispsn;
1725
1726       /* If the card handler is able to return a short serialnumber,
1727          use that one, else use the complete serialno. */
1728       if (!agent_card_getattr (ctrl, "$DISPSERIALNO", &dispsn))
1729         {
1730           *cardsn = xtryasprintf ("cardno:%s", dispsn);
1731           xfree (dispsn);
1732         }
1733       else
1734         *cardsn = xtryasprintf ("cardno:%s", serialno);
1735       if (!*cardsn)
1736         {
1737           err = gpg_error_from_errno (errno);
1738           xfree (pkbuf);
1739           gcry_sexp_release (s_pk);
1740           xfree (serialno);
1741           xfree (authkeyid);
1742           return err;
1743         }
1744     }
1745
1746   xfree (pkbuf);
1747   xfree (serialno);
1748   xfree (authkeyid);
1749   *r_pk = s_pk;
1750   return 0;
1751 }
1752
1753
1754 \f
1755
1756 /*
1757
1758   Request handler.  Each handler is provided with a CTRL context, a
1759   REQUEST object and a RESPONSE object.  The actual request is to be
1760   read from REQUEST, the response needs to be written to RESPONSE.
1761
1762 */
1763
1764
1765 /* Handler for the "request_identities" command.  */
1766 static gpg_error_t
1767 ssh_handler_request_identities (ctrl_t ctrl,
1768                                 estream_t request, estream_t response)
1769 {
1770   char *key_type;
1771   ssh_key_type_spec_t spec;
1772   struct dirent *dir_entry;
1773   char *key_directory;
1774   size_t key_directory_n;
1775   char *key_path;
1776   unsigned char *buffer;
1777   size_t buffer_n;
1778   u32 key_counter;
1779   estream_t key_blobs;
1780   gcry_sexp_t key_secret;
1781   gcry_sexp_t key_public;
1782   DIR *dir;
1783   gpg_error_t err;
1784   int ret;
1785   FILE *ctrl_fp = NULL;
1786   char *cardsn;
1787   gpg_error_t ret_err;
1788
1789   /* Prepare buffer stream.  */
1790
1791   key_directory = NULL;
1792   key_secret = NULL;
1793   key_public = NULL;
1794   key_type = NULL;
1795   key_path = NULL;
1796   key_counter = 0;
1797   buffer = NULL;
1798   dir = NULL;
1799   err = 0;
1800
1801   key_blobs = es_mopen (NULL, 0, 0, 1, NULL, NULL, "r+");
1802   if (! key_blobs)
1803     {
1804       err = gpg_error_from_errno (errno);
1805       goto out;
1806     }
1807
1808   /* Open key directory.  */
1809   key_directory = make_filename (opt.homedir, GNUPG_PRIVATE_KEYS_DIR, NULL);
1810   if (! key_directory)
1811     {
1812       err = gpg_err_code_from_errno (errno);
1813       goto out;
1814     }
1815   key_directory_n = strlen (key_directory);
1816   
1817   key_path = xtrymalloc (key_directory_n + 46);
1818   if (! key_path)
1819     {
1820       err = gpg_err_code_from_errno (errno);
1821       goto out;
1822     }
1823
1824   sprintf (key_path, "%s/", key_directory);
1825   sprintf (key_path + key_directory_n + 41, ".key");
1826
1827   dir = opendir (key_directory);
1828   if (! dir)
1829     {
1830       err = gpg_err_code_from_errno (errno);
1831       goto out;
1832     }
1833
1834
1835
1836   /* First check whether a key is currently available in the card
1837      reader - this should be allowed even without being listed in
1838      sshcontrol. */
1839
1840   if (!card_key_available (ctrl, &key_public, &cardsn))
1841     {
1842       err = ssh_send_key_public (key_blobs, key_public, cardsn);
1843       gcry_sexp_release (key_public);
1844       key_public = NULL;
1845       xfree (cardsn);
1846       if (err)
1847         goto out;
1848       
1849       key_counter++;
1850     }
1851
1852
1853   /* Then look at all the registered an allowed keys. */
1854
1855
1856   /* Fixme: We should better iterate over the control file and check
1857      whether the key file is there.  This is better in resepct to
1858      performance if tehre are a lot of key sin our key storage. */
1859   /* FIXME: make sure that buffer gets deallocated properly.  */
1860   err = open_control_file (&ctrl_fp, 0);
1861   if (err)
1862     goto out;
1863
1864   while ( (dir_entry = readdir (dir)) )
1865     {
1866       if ((strlen (dir_entry->d_name) == 44)
1867           && (! strncmp (dir_entry->d_name + 40, ".key", 4)))
1868         {
1869           char hexgrip[41];
1870           int disabled;
1871
1872           /* We do only want to return keys listed in our control
1873              file. */
1874           strncpy (hexgrip, dir_entry->d_name, 40);
1875           hexgrip[40] = 0;
1876           if ( strlen (hexgrip) != 40 )
1877             continue;
1878           if (search_control_file (ctrl_fp, hexgrip, &disabled)
1879               || disabled)
1880             continue;
1881
1882           strncpy (key_path + key_directory_n + 1, dir_entry->d_name, 40);
1883
1884           /* Read file content.  */
1885           err = file_to_buffer (key_path, &buffer, &buffer_n);
1886           if (err)
1887             goto out;
1888               
1889           err = gcry_sexp_sscan (&key_secret, NULL, (char*)buffer, buffer_n);
1890           if (err)
1891             goto out;
1892
1893           xfree (buffer);
1894           buffer = NULL;
1895
1896           err = sexp_extract_identifier (key_secret, &key_type);
1897           if (err)
1898             goto out;
1899
1900           err = ssh_key_type_lookup (NULL, key_type, &spec);
1901           if (err)
1902             goto out;
1903
1904           xfree (key_type);
1905           key_type = NULL;
1906
1907           err = key_secret_to_public (&key_public, spec, key_secret);
1908           if (err)
1909             goto out;
1910
1911           gcry_sexp_release (key_secret);
1912           key_secret = NULL;
1913               
1914           err = ssh_send_key_public (key_blobs, key_public, NULL);
1915           if (err)
1916             goto out;
1917
1918           gcry_sexp_release (key_public);
1919           key_public = NULL;
1920
1921           key_counter++;
1922         }
1923     }
1924   
1925   ret = es_fseek (key_blobs, 0, SEEK_SET);
1926   if (ret)
1927     {
1928       err = gpg_error_from_errno (errno);
1929       goto out;
1930     }
1931
1932  out:
1933
1934   /* Send response.  */
1935
1936   gcry_sexp_release (key_secret);
1937   gcry_sexp_release (key_public);
1938
1939   if (! err)
1940     {
1941       ret_err = stream_write_byte (response, SSH_RESPONSE_IDENTITIES_ANSWER);
1942       if (ret_err)
1943         goto leave;
1944       ret_err = stream_write_uint32 (response, key_counter);
1945       if (ret_err)
1946         goto leave;
1947       ret_err = stream_copy (response, key_blobs);
1948       if (ret_err)
1949         goto leave;
1950     }
1951   else
1952     {
1953       ret_err = stream_write_byte (response, SSH_RESPONSE_FAILURE);
1954       goto leave;
1955     };
1956
1957  leave:
1958
1959   if (key_blobs)
1960     es_fclose (key_blobs);
1961   if (dir)
1962     closedir (dir);
1963
1964   if (ctrl_fp)
1965     fclose (ctrl_fp);
1966
1967   free (key_directory);
1968   xfree (key_path);
1969   xfree (buffer);
1970   xfree (key_type);
1971
1972   return ret_err;
1973 }
1974
1975 /* This function hashes the data contained in DATA of size DATA_N
1976    according to the message digest algorithm specified by MD_ALGORITHM
1977    and writes the message digest to HASH, which needs to large enough
1978    for the digest.  */
1979 static gpg_error_t
1980 data_hash (unsigned char *data, size_t data_n,
1981            int md_algorithm, unsigned char *hash)
1982 {
1983   gcry_md_hash_buffer (md_algorithm, hash, data, data_n);
1984
1985   return 0;
1986 }
1987
1988 /* This function signs the data contained in CTRL, stores the created
1989    signature in newly allocated memory in SIG and it's size in SIG_N;
1990    SIG_ENCODER is the signature encoder to use.  */
1991 static gpg_error_t
1992 data_sign (ctrl_t ctrl, ssh_signature_encoder_t sig_encoder,
1993            unsigned char **sig, size_t *sig_n)
1994 {
1995   gpg_error_t err;
1996   gcry_sexp_t signature_sexp = NULL;
1997   estream_t stream = NULL;
1998   gcry_sexp_t valuelist = NULL;
1999   gcry_sexp_t sublist = NULL;
2000   gcry_mpi_t sig_value = NULL;
2001   unsigned char *sig_blob = NULL;
2002   size_t sig_blob_n = 0;
2003   char *identifier = NULL;
2004   const char *identifier_raw;
2005   size_t identifier_n;
2006   ssh_key_type_spec_t spec;
2007   int ret;
2008   unsigned int i;
2009   const char *elems;
2010   size_t elems_n;
2011   gcry_mpi_t *mpis = NULL;
2012
2013   *sig = NULL;
2014   *sig_n = 0;
2015
2016   ctrl->use_auth_call = 1;
2017   err = agent_pksign_do (ctrl,
2018                          _("Please enter the passphrase "
2019                            "for the ssh key%0A  %c"), &signature_sexp,
2020                          CACHE_MODE_SSH);
2021   ctrl->use_auth_call = 0;
2022   if (err)
2023     goto out;
2024
2025   valuelist = gcry_sexp_nth (signature_sexp, 1);
2026   if (! valuelist)
2027     {
2028       err = gpg_error (GPG_ERR_INV_SEXP);
2029       goto out;
2030     }
2031
2032   stream = es_mopen (NULL, 0, 0, 1, NULL, NULL, "r+");
2033   if (! stream)
2034     {
2035       err = gpg_error_from_errno (errno);
2036       goto out;
2037     }
2038
2039   identifier_raw = gcry_sexp_nth_data (valuelist, 0, &identifier_n);
2040   if (! identifier_raw)
2041     {
2042       err = gpg_error (GPG_ERR_INV_SEXP);
2043       goto out;
2044     }
2045
2046   identifier = make_cstring (identifier_raw, identifier_n);
2047   if (! identifier)
2048     {
2049       err = gpg_error_from_errno (errno);
2050       goto out;
2051     }
2052
2053   err = ssh_key_type_lookup (NULL, identifier, &spec);
2054   if (err)
2055     goto out;
2056
2057   err = stream_write_cstring (stream, spec.ssh_identifier);
2058   if (err)
2059     goto out;
2060
2061   elems = spec.elems_signature;
2062   elems_n = strlen (elems);
2063
2064   mpis = xtrycalloc (elems_n + 1, sizeof *mpis);
2065   if (!mpis)
2066     {
2067       err = gpg_error_from_errno (errno);
2068       goto out;
2069     }
2070
2071   for (i = 0; i < elems_n; i++)
2072     {
2073       sublist = gcry_sexp_find_token (valuelist, spec.elems_signature + i, 1);
2074       if (! sublist)
2075         {
2076           err = gpg_error (GPG_ERR_INV_SEXP);
2077           break;
2078         }
2079
2080       sig_value = gcry_sexp_nth_mpi (sublist, 1, GCRYMPI_FMT_USG);
2081       if (! sig_value)
2082         {
2083           err = gpg_error (GPG_ERR_INTERNAL); /* FIXME?  */
2084           break;
2085         }
2086       gcry_sexp_release (sublist);
2087       sublist = NULL;
2088
2089       mpis[i] = sig_value;
2090     }
2091   if (err)
2092     goto out;
2093
2094   err = (*sig_encoder) (stream, mpis);
2095   if (err)
2096     goto out;
2097
2098   sig_blob_n = es_ftell (stream);
2099   if (sig_blob_n == -1)
2100     {
2101       err = gpg_error_from_errno (errno);
2102       goto out;
2103     }
2104
2105   sig_blob = xtrymalloc (sig_blob_n);
2106   if (! sig_blob)
2107     {
2108       err = gpg_error_from_errno (errno);
2109       goto out;
2110     }
2111
2112   ret = es_fseek (stream, 0, SEEK_SET);
2113   if (ret)
2114     {
2115       err = gpg_error_from_errno (errno);
2116       goto out;
2117     }    
2118
2119   err = stream_read_data (stream, sig_blob, sig_blob_n);
2120   if (err)
2121     goto out;
2122   
2123   *sig = sig_blob;
2124   *sig_n = sig_blob_n;
2125   
2126  out:
2127
2128   if (err)
2129     xfree (sig_blob);
2130
2131   if (stream)
2132     es_fclose (stream);
2133   gcry_sexp_release (valuelist);
2134   gcry_sexp_release (signature_sexp);
2135   gcry_sexp_release (sublist);
2136   mpint_list_free (mpis);
2137   xfree (identifier);
2138
2139   return err;
2140 }
2141
2142 /* Handler for the "sign_request" command.  */
2143 static gpg_error_t
2144 ssh_handler_sign_request (ctrl_t ctrl, estream_t request, estream_t response)
2145 {
2146   gcry_sexp_t key;
2147   ssh_key_type_spec_t spec;
2148   unsigned char hash[MAX_DIGEST_LEN];
2149   unsigned int hash_n;
2150   unsigned char key_grip[20];
2151   unsigned char *key_blob;
2152   u32 key_blob_size;
2153   unsigned char *data;
2154   unsigned char *sig;
2155   size_t sig_n;
2156   u32 data_size;
2157   u32 flags;
2158   gpg_error_t err;
2159   gpg_error_t ret_err;
2160
2161   key_blob = NULL;
2162   data = NULL;
2163   sig = NULL;
2164   key = NULL;
2165
2166   /* Receive key.  */
2167   
2168   err = stream_read_string (request, 0, &key_blob, &key_blob_size);
2169   if (err)
2170     goto out;
2171
2172   err = ssh_read_key_public_from_blob (key_blob, key_blob_size, &key, &spec);
2173   if (err)
2174     goto out;
2175
2176   /* Receive data to sign.  */
2177   err = stream_read_string (request, 0, &data, &data_size);
2178   if (err)
2179     goto out;
2180
2181   /* FIXME?  */
2182   err = stream_read_uint32 (request, &flags);
2183   if (err)
2184     goto out;
2185
2186   /* Hash data.  */
2187   hash_n = gcry_md_get_algo_dlen (GCRY_MD_SHA1);
2188   if (! hash_n)
2189     {
2190       err = gpg_error (GPG_ERR_INTERNAL);
2191       goto out;
2192     }
2193   err = data_hash (data, data_size, GCRY_MD_SHA1, hash);
2194   if (err)
2195     goto out;
2196
2197   /* Calculate key grip.  */
2198   err = ssh_key_grip (key, key_grip);
2199   if (err)
2200     goto out;
2201
2202   /* Sign data.  */
2203
2204   ctrl->digest.algo = GCRY_MD_SHA1;
2205   memcpy (ctrl->digest.value, hash, hash_n);
2206   ctrl->digest.valuelen = hash_n;
2207   ctrl->digest.raw_value = ! (spec.flags & SPEC_FLAG_USE_PKCS1V2);
2208   ctrl->have_keygrip = 1;
2209   memcpy (ctrl->keygrip, key_grip, 20);
2210
2211   err = data_sign (ctrl, spec.signature_encoder, &sig, &sig_n);
2212   
2213  out:
2214
2215   /* Done.  */
2216
2217   if (! err)
2218     {
2219       ret_err = stream_write_byte (response, SSH_RESPONSE_SIGN_RESPONSE);
2220       if (ret_err)
2221         goto leave;
2222       ret_err = stream_write_string (response, sig, sig_n);
2223       if (ret_err)
2224         goto leave;
2225     }
2226   else
2227     {
2228       ret_err = stream_write_byte (response, SSH_RESPONSE_FAILURE);
2229       if (ret_err)
2230         goto leave;
2231     }
2232   
2233  leave:
2234
2235   gcry_sexp_release (key);
2236   xfree (key_blob);
2237   xfree (data);
2238   xfree (sig);
2239
2240   return ret_err;
2241 }
2242
2243 /* This function extracts the comment contained in the key
2244    S-Expression KEY and stores a copy in COMMENT.  Returns usual error
2245    code.  */
2246 static gpg_error_t
2247 ssh_key_extract_comment (gcry_sexp_t key, char **comment)
2248 {
2249   gcry_sexp_t comment_list;
2250   char *comment_new;
2251   const char *data;
2252   size_t data_n;
2253   gpg_error_t err;
2254
2255   comment_list = gcry_sexp_find_token (key, "comment", 0);
2256   if (! comment_list)
2257     {
2258       err = gpg_error (GPG_ERR_INV_SEXP);
2259       goto out;
2260     }
2261   
2262   data = gcry_sexp_nth_data (comment_list, 1, &data_n);
2263   if (! data)
2264     {
2265       err = gpg_error (GPG_ERR_INV_SEXP);
2266       goto out;
2267     }
2268
2269   comment_new = make_cstring (data, data_n);
2270   if (! comment_new)
2271     {
2272       err = gpg_error_from_errno (errno);
2273       goto out;
2274     }
2275
2276   *comment = comment_new;
2277   err = 0;
2278
2279  out:
2280
2281   gcry_sexp_release (comment_list);
2282
2283   return err;
2284 }
2285
2286 /* This function converts the key contained in the S-Expression KEY
2287    into a buffer, which is protected by the passphrase PASSPHRASE.
2288    Returns usual error code.  */
2289 static gpg_error_t
2290 ssh_key_to_protected_buffer (gcry_sexp_t key, const char *passphrase,
2291                              unsigned char **buffer, size_t *buffer_n)
2292 {
2293   unsigned char *buffer_new;
2294   unsigned int buffer_new_n;
2295   gpg_error_t err;
2296
2297   err = 0;
2298   buffer_new_n = gcry_sexp_sprint (key, GCRYSEXP_FMT_CANON, NULL, 0);
2299   buffer_new = xtrymalloc_secure (buffer_new_n);
2300   if (! buffer_new)
2301     {
2302       err = gpg_error_from_errno (errno);
2303       goto out;
2304     }
2305   
2306   gcry_sexp_sprint (key, GCRYSEXP_FMT_CANON, buffer_new, buffer_new_n);
2307   /* FIXME: guarantee?  */
2308
2309   err = agent_protect (buffer_new, passphrase, buffer, buffer_n);
2310
2311  out:
2312
2313   xfree (buffer_new);
2314
2315   return err;
2316 }
2317
2318
2319
2320 /* Store the ssh KEY into our local key storage and protect it after
2321    asking for a passphrase.  Cache that passphrase.  TTL is the
2322    maximum caching time for that key.  If the key already exists in
2323    our key storage, don't do anything.  When entering a new key also
2324    add an entry to the sshcontrol file.  */
2325 static gpg_error_t
2326 ssh_identity_register (ctrl_t ctrl, gcry_sexp_t key, int ttl)
2327 {
2328   gpg_error_t err;
2329   unsigned char key_grip_raw[20];
2330   char key_grip[41];
2331   unsigned char *buffer = NULL;
2332   unsigned int buffer_n;
2333   char *description = NULL;
2334   char *comment = NULL;
2335   unsigned int i;
2336   struct pin_entry_info_s *pi = NULL;
2337
2338   err = ssh_key_grip (key, key_grip_raw);
2339   if (err)
2340     goto out;
2341
2342   /* Check whether the key is already in our key storage.  Don't do
2343      anything then.  */
2344   if ( !agent_key_available (key_grip_raw) )
2345     goto out; /* Yes, key is available.  */
2346
2347   
2348   err = ssh_key_extract_comment (key, &comment);
2349   if (err)
2350     goto out;
2351
2352   if ( asprintf (&description,
2353                  _("Please enter a passphrase to protect"
2354                    " the received secret key%%0A"
2355                    "   %s%%0A"
2356                    "within gpg-agent's key storage"),
2357                  comment ? comment : "?") < 0)
2358     {
2359       err = gpg_error_from_errno (errno);
2360       goto out;
2361     }
2362
2363
2364   pi = gcry_calloc_secure (1, sizeof (*pi) + 100 + 1);
2365   if (!pi)
2366     {
2367       err = gpg_error_from_errno (errno);
2368       goto out;
2369     }
2370   pi->max_length = 100;
2371   pi->max_tries = 1;
2372   err = agent_askpin (ctrl, description, NULL, NULL, pi);
2373   if (err)
2374     goto out;
2375
2376   err = ssh_key_to_protected_buffer (key, pi->pin, &buffer, &buffer_n);
2377   if (err)
2378     goto out;
2379
2380   /* Store this key to our key storage.  */
2381   err = agent_write_private_key (key_grip_raw, buffer, buffer_n, 0);
2382   if (err)
2383     goto out;
2384
2385   /* Cache this passphrase. */
2386   for (i = 0; i < 20; i++)
2387     sprintf (key_grip + 2 * i, "%02X", key_grip_raw[i]);
2388
2389   err = agent_put_cache (key_grip, CACHE_MODE_SSH, pi->pin, ttl);
2390   if (err)
2391     goto out;
2392
2393   /* And add an entry to the sshcontrol file.  */
2394   err = add_control_entry (ctrl, key_grip, ttl);
2395
2396
2397  out:
2398   if (pi && pi->max_length)
2399     wipememory (pi->pin, pi->max_length);
2400   xfree (pi);
2401   xfree (buffer);
2402   xfree (comment);
2403   free (description); /* (asprintf allocated, thus regular free.)  */
2404
2405   return err;
2406 }
2407
2408
2409 /* This function removes the key contained in the S-Expression KEY
2410    from the local key storage, in case it exists there.  Returns usual
2411    error code.  FIXME: this function is a stub.  */
2412 static gpg_error_t
2413 ssh_identity_drop (gcry_sexp_t key)
2414 {
2415   unsigned char key_grip[21] = { 0 };
2416   gpg_error_t err;
2417
2418   err = ssh_key_grip (key, key_grip);
2419   if (err)
2420     goto out;
2421
2422   key_grip[sizeof (key_grip) - 1] = 0;
2423
2424   /* FIXME: What to do here - forgetting the passphrase or deleting
2425      the key from key cache?  */
2426
2427  out:
2428
2429   return err;
2430 }
2431
2432 /* Handler for the "add_identity" command.  */
2433 static gpg_error_t
2434 ssh_handler_add_identity (ctrl_t ctrl, estream_t request, estream_t response)
2435 {
2436   gpg_error_t ret_err;
2437   gpg_error_t err;
2438   gcry_sexp_t key;
2439   unsigned char b;
2440   int confirm;
2441   int ttl;
2442   
2443   confirm = 0;
2444   key = NULL;
2445   ttl = 0;
2446
2447   /* FIXME?  */
2448   err = ssh_receive_key (request, &key, 1, 1, NULL);
2449   if (err)
2450     goto out;
2451
2452   while (1)
2453     {
2454       err = stream_read_byte (request, &b);
2455       if (gpg_err_code (err) == GPG_ERR_EOF)
2456         {
2457           err = 0;
2458           break;
2459         }
2460
2461       switch (b)
2462         {
2463         case SSH_OPT_CONSTRAIN_LIFETIME:
2464           {
2465             u32 n = 0;
2466
2467             err = stream_read_uint32 (request, &n);
2468             if (! err)
2469               ttl = n;
2470             break;
2471           }
2472
2473         case SSH_OPT_CONSTRAIN_CONFIRM:
2474           {
2475             confirm = 1;
2476             break;
2477           }
2478
2479         default:
2480           /* FIXME: log/bad?  */
2481           break;
2482         }
2483     }
2484   if (err)
2485     goto out;
2486
2487   /* FIXME: are constraints used correctly?  */
2488
2489   err = ssh_identity_register (ctrl, key, ttl);
2490
2491  out:
2492
2493   gcry_sexp_release (key);
2494
2495   if (! err)
2496     ret_err = stream_write_byte (response, SSH_RESPONSE_SUCCESS);
2497   else
2498     ret_err = stream_write_byte (response, SSH_RESPONSE_FAILURE);
2499
2500   return ret_err;
2501 }
2502
2503 /* Handler for the "remove_identity" command.  */
2504 static gpg_error_t
2505 ssh_handler_remove_identity (ctrl_t ctrl,
2506                              estream_t request, estream_t response)
2507 {
2508   unsigned char *key_blob;
2509   u32 key_blob_size;
2510   gcry_sexp_t key;
2511   gpg_error_t ret_err;
2512   gpg_error_t err;
2513
2514   /* Receive key.  */
2515
2516   key_blob = NULL;
2517   key = NULL;
2518   
2519   err = stream_read_string (request, 0, &key_blob, &key_blob_size);
2520   if (err)
2521     goto out;
2522
2523   err = ssh_read_key_public_from_blob (key_blob, key_blob_size, &key, NULL);
2524   if (err)
2525     goto out;
2526   
2527   err = ssh_identity_drop (key);
2528
2529  out:
2530
2531   xfree (key_blob);
2532   gcry_sexp_release (key);
2533
2534   if (! err)
2535     ret_err = stream_write_byte (response, SSH_RESPONSE_SUCCESS);
2536   else
2537     ret_err = stream_write_byte (response, SSH_RESPONSE_FAILURE);
2538
2539   return ret_err;
2540 }
2541
2542 /* FIXME: stub function.  Actually useful?  */
2543 static gpg_error_t
2544 ssh_identities_remove_all (void)
2545 {
2546   gpg_error_t err;
2547
2548   err = 0;
2549
2550   /* FIXME: shall we remove _all_ cache entries or only those
2551      registered through the ssh emulation?  */
2552   
2553   return err;
2554 }
2555
2556 /* Handler for the "remove_all_identities" command.  */
2557 static gpg_error_t
2558 ssh_handler_remove_all_identities (ctrl_t ctrl,
2559                                    estream_t request, estream_t response)
2560 {
2561   gpg_error_t ret_err;
2562   gpg_error_t err;
2563   
2564   err = ssh_identities_remove_all ();
2565
2566   if (! err)
2567     ret_err = stream_write_byte (response, SSH_RESPONSE_SUCCESS);
2568   else
2569     ret_err = stream_write_byte (response, SSH_RESPONSE_FAILURE);
2570
2571   return ret_err;
2572 }
2573
2574 /* Lock agent?  FIXME: stub function.  */
2575 static gpg_error_t
2576 ssh_lock (void)
2577 {
2578   gpg_error_t err;
2579
2580   /* FIXME */
2581   log_error ("ssh-agent's lock command is not implemented\n");
2582   err = 0;
2583
2584   return err;
2585 }
2586
2587 /* Unock agent?  FIXME: stub function.  */
2588 static gpg_error_t
2589 ssh_unlock (void)
2590 {
2591   gpg_error_t err;
2592
2593   log_error ("ssh-agent's unlock command is not implemented\n");
2594   err = 0;
2595
2596   return err;
2597 }
2598
2599 /* Handler for the "lock" command.  */
2600 static gpg_error_t
2601 ssh_handler_lock (ctrl_t ctrl, estream_t request, estream_t response)
2602 {
2603   gpg_error_t ret_err;
2604   gpg_error_t err;
2605   
2606   err = ssh_lock ();
2607
2608   if (! err)
2609     ret_err = stream_write_byte (response, SSH_RESPONSE_SUCCESS);
2610   else
2611     ret_err = stream_write_byte (response, SSH_RESPONSE_FAILURE);
2612
2613   return ret_err;
2614 }
2615
2616 /* Handler for the "unlock" command.  */
2617 static gpg_error_t
2618 ssh_handler_unlock (ctrl_t ctrl, estream_t request, estream_t response)
2619 {
2620   gpg_error_t ret_err;
2621   gpg_error_t err;
2622   
2623   err = ssh_unlock ();
2624
2625   if (! err)
2626     ret_err = stream_write_byte (response, SSH_RESPONSE_SUCCESS);
2627   else
2628     ret_err = stream_write_byte (response, SSH_RESPONSE_FAILURE);
2629
2630   return ret_err;
2631 }
2632
2633 \f
2634
2635 /* Return the request specification for the request identified by TYPE
2636    or NULL in case the requested request specification could not be
2637    found.  */
2638 static ssh_request_spec_t *
2639 request_spec_lookup (int type)
2640 {
2641   ssh_request_spec_t *spec;
2642   unsigned int i;
2643
2644   for (i = 0; i < DIM (request_specs); i++)
2645     if (request_specs[i].type == type)
2646       break;
2647   if (i == DIM (request_specs))
2648     {
2649       log_info ("ssh request %u is not supported\n", type);
2650       spec = NULL;
2651     }
2652   else
2653     spec = request_specs + i;
2654
2655   return spec;
2656 }
2657
2658 /* Process a single request.  The request is read from and the
2659    response is written to STREAM_SOCK.  Uses CTRL as context.  Returns
2660    zero in case of success, non zero in case of failure.  */
2661 static int
2662 ssh_request_process (ctrl_t ctrl, estream_t stream_sock)
2663 {
2664   ssh_request_spec_t *spec;
2665   estream_t response;
2666   estream_t request;
2667   unsigned char request_type;
2668   gpg_error_t err;
2669   int send_err;
2670   int ret;
2671   unsigned char *request_data;
2672   u32 request_data_size;
2673   u32 response_size;
2674
2675   request_data = NULL;
2676   response = NULL;
2677   request = NULL;
2678   send_err = 0;
2679
2680   /* Create memory streams for request/response data.  The entire
2681      request will be stored in secure memory, since it might contain
2682      secret key material.  The response does not have to be stored in
2683      secure memory, since we never give out secret keys. 
2684
2685      Note: we only have little secure memory, but there is NO
2686      possibility of DoS here; only trusted clients are allowed to
2687      connect to the agent.  What could happen is that the agent
2688      returns out-of-secure-memory errors on requests in case the
2689      agent's owner floods his own agent with many large messages.
2690      -moritz */
2691
2692   /* Retrieve request.  */
2693   err = stream_read_string (stream_sock, 1, &request_data, &request_data_size);
2694   if (err)
2695     goto out;
2696
2697   if (opt.verbose > 1)
2698     log_info ("received ssh request of length %u\n",
2699               (unsigned int)request_data_size);
2700
2701   if (! request_data_size)
2702     {
2703       send_err = 1;
2704       goto out;
2705       /* Broken request; FIXME.  */
2706     }
2707
2708   request_type = request_data[0];
2709   spec = request_spec_lookup (request_type);
2710   if (! spec)
2711     {
2712       send_err = 1;
2713       goto out;
2714       /* Unknown request; FIXME.  */
2715     }
2716
2717   if (spec->secret_input)
2718     request = es_mopen (NULL, 0, 0, 1, realloc_secure, gcry_free, "r+");
2719   else
2720     request = es_mopen (NULL, 0, 0, 1, gcry_realloc, gcry_free, "r+");
2721   if (! request)
2722     {
2723       err = gpg_error_from_errno (errno);
2724       goto out;
2725     }
2726   ret = es_setvbuf (request, NULL, _IONBF, 0);
2727   if (ret)
2728     {
2729       err = gpg_error_from_errno (errno);
2730       goto out;
2731     }
2732   err = stream_write_data (request, request_data + 1, request_data_size - 1);
2733   if (err)
2734     goto out;
2735   es_rewind (request);
2736
2737   response = es_mopen (NULL, 0, 0, 1, NULL, NULL, "r+");
2738   if (! response)
2739     {
2740       err = gpg_error_from_errno (errno);
2741       goto out;
2742     }
2743
2744   if (opt.verbose)
2745     log_info ("ssh request handler for %s (%u) started\n",
2746                spec->identifier, spec->type);
2747
2748   err = (*spec->handler) (ctrl, request, response);
2749
2750   if (opt.verbose)
2751     {
2752       if (err)
2753         log_info ("ssh request handler for %s (%u) failed: %s\n",
2754                   spec->identifier, spec->type, gpg_strerror (err));
2755       else
2756         log_info ("ssh request handler for %s (%u) ready\n",
2757                   spec->identifier, spec->type);
2758     }
2759
2760   if (err)
2761     {
2762       send_err = 1;
2763       goto out;
2764     }
2765
2766   response_size = es_ftell (response);
2767   if (opt.verbose > 1)
2768     log_info ("sending ssh response of length %u\n",
2769               (unsigned int)response_size);
2770
2771   err = es_fseek (response, 0, SEEK_SET);
2772   if (err)
2773     {
2774       send_err = 1;
2775       goto out;
2776     }
2777
2778   err = stream_write_uint32 (stream_sock, response_size);
2779   if (err)
2780     {
2781       send_err = 1;
2782       goto out;
2783     }
2784
2785   err = stream_copy (stream_sock, response);
2786   if (err)
2787     goto out;
2788
2789   err = es_fflush (stream_sock);
2790   if (err)
2791     goto out;
2792
2793  out:
2794
2795   if (err && es_feof (stream_sock))
2796     log_error ("error occured while processing request: %s\n",
2797                gpg_strerror (err));
2798
2799   if (send_err)
2800     {
2801       if (opt.verbose > 1)
2802         log_info ("sending ssh error response\n");
2803       err = stream_write_uint32 (stream_sock, 1);
2804       if (err)
2805         goto leave;
2806       err = stream_write_byte (stream_sock, SSH_RESPONSE_FAILURE);
2807       if (err)
2808         goto leave;
2809     }
2810
2811  leave:
2812
2813   if (request)
2814     es_fclose (request);
2815   if (response)
2816     es_fclose (response);
2817   xfree (request_data);         /* FIXME?  */
2818
2819   return !!err;
2820 }
2821
2822 /* Start serving client on SOCK_CLIENT.  */
2823 void
2824 start_command_handler_ssh (int sock_client)
2825 {
2826   struct server_control_s ctrl;
2827   estream_t stream_sock;
2828   gpg_error_t err;
2829   int ret;
2830
2831   /* Setup control structure.  */
2832
2833   memset (&ctrl, 0, sizeof (ctrl));
2834   agent_init_default_ctrl (&ctrl);
2835   ctrl.connection_fd = sock_client;
2836
2837   /* Because the ssh protocol does not send us information about the
2838      the current TTY setting, we resort here to use those from startup
2839      or those explictly set.  */
2840   if (!ctrl.display && opt.startup_display)
2841     ctrl.display = strdup (opt.startup_display);
2842   if (!ctrl.ttyname && opt.startup_ttyname)
2843     ctrl.ttyname = strdup (opt.startup_ttyname);
2844   if (!ctrl.ttytype && opt.startup_ttytype)
2845     ctrl.ttytype = strdup (opt.startup_ttytype);
2846   if (!ctrl.lc_ctype && opt.startup_lc_ctype)
2847     ctrl.lc_ctype = strdup (opt.startup_lc_ctype);
2848   if (!ctrl.lc_messages && opt.startup_lc_messages)
2849     ctrl.lc_messages = strdup (opt.startup_lc_messages);
2850
2851
2852   /* Create stream from socket.  */
2853   stream_sock = es_fdopen (sock_client, "r+");
2854   if (!stream_sock)
2855     {
2856       err = gpg_error_from_errno (errno);
2857       log_error (_("failed to create stream from socket: %s\n"),
2858                  gpg_strerror (err));
2859       goto out;
2860     }
2861   /* We have to disable the estream buffering, because the estream
2862      core doesn't know about secure memory.  */
2863   ret = es_setvbuf (stream_sock, NULL, _IONBF, 0);
2864   if (ret)
2865     {
2866       err = gpg_error_from_errno (errno);
2867       log_error (_("failed to disable buffering "
2868                    "on socket stream: %s\n"), gpg_strerror (err));
2869       goto out;
2870     }
2871
2872   /* Main processing loop. */
2873   while ( !ssh_request_process (&ctrl, stream_sock) )
2874     ;
2875
2876   /* Reset the SCD in case it has been used. */
2877   agent_reset_scd (&ctrl);
2878
2879
2880  out:
2881   if (stream_sock)
2882     es_fclose (stream_sock);
2883
2884   free (ctrl.display);
2885   free (ctrl.ttyname);
2886   free (ctrl.ttytype);
2887   free (ctrl.lc_ctype);
2888   free (ctrl.lc_messages);
2889 }