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