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