(data_sign): Removed empty statement.
[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 no 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 *appname;
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, "APPTYPE", &appname);
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, "APPTYPE", &appname);
1619     }
1620   if (err)
1621     {
1622       log_error (_("error getting application type of card: %s\n"),
1623                  gpg_strerror (err));
1624       xfree (serialno);
1625       return err;
1626     }
1627   if (strcmp (appname, "OPENPGP"))
1628     {
1629       log_info (_("card application `%s' is not supported\n"), appname);
1630       xfree (appname);
1631       xfree (serialno);
1632       return gpg_error (GPG_ERR_NOT_SUPPORTED);
1633     }
1634   xfree (appname);
1635   appname = NULL;
1636
1637   /* Get the S/N if we don't have it yet.  Use the fast getattr method.  */
1638   if (!serialno && (err = agent_card_getattr (ctrl, "SERIALNO", &serialno)) )
1639     {
1640       log_error (_("error getting serial number of card: %s\n"),
1641                  gpg_strerror (err));
1642       return err;
1643     }
1644
1645   /* Read the public key.  */
1646   err = agent_card_readkey (ctrl, "OPENPGP.3", &pkbuf);
1647   if (err)
1648     {
1649       if (opt.verbose)
1650         log_info (_("no suitable card key found: %s\n"), gpg_strerror (err));
1651       xfree (serialno);
1652       return err;
1653     }
1654
1655   pkbuflen = gcry_sexp_canon_len (pkbuf, 0, NULL, NULL);
1656   err = gcry_sexp_sscan (&s_pk, NULL, (char*)pkbuf, pkbuflen);
1657   if (err)
1658     {
1659       log_error ("failed to build S-Exp from received card key: %s\n",
1660                  gpg_strerror (err));
1661       xfree (pkbuf);
1662       xfree (serialno);
1663       return err;
1664     }
1665
1666   err = ssh_key_grip (s_pk, grip);
1667   if (err)
1668     {
1669       log_debug ("error computing keygrip from received card key: %s\n",
1670                  gcry_strerror (err));
1671       xfree (pkbuf);
1672       gcry_sexp_release (s_pk);
1673       xfree (serialno);
1674       return err;
1675     }
1676
1677   if ( agent_key_available (grip) )
1678     {
1679       /* (Shadow)-key is not available in our key storage.  */
1680       unsigned char *shadow_info;
1681       unsigned char *tmp;
1682       
1683       shadow_info = make_shadow_info (serialno, "OPENPGP.3");
1684       if (!shadow_info)
1685         {
1686           err = gpg_error_from_errno (errno);
1687           xfree (pkbuf);
1688           gcry_sexp_release (s_pk);
1689           xfree (serialno);
1690           return err;
1691         }
1692       err = agent_shadow_key (pkbuf, shadow_info, &tmp);
1693       xfree (shadow_info);
1694       if (err)
1695         {
1696           log_error (_("shadowing the key failed: %s\n"), gpg_strerror (err));
1697           xfree (pkbuf);
1698           gcry_sexp_release (s_pk);
1699           xfree (serialno);
1700           return err;
1701         }
1702       xfree (pkbuf);
1703       pkbuf = tmp;
1704       pkbuflen = gcry_sexp_canon_len (pkbuf, 0, NULL, NULL);
1705       assert (pkbuflen);
1706
1707       err = agent_write_private_key (grip, pkbuf, pkbuflen, 0);
1708       if (err)
1709         {
1710           log_error (_("error writing key: %s\n"), gpg_strerror (err));
1711           xfree (pkbuf);
1712           gcry_sexp_release (s_pk);
1713           xfree (serialno);
1714           return err;
1715         }
1716     }
1717
1718   if (cardsn)
1719     {
1720       size_t snlen = strlen (serialno);
1721
1722       if (snlen == 32
1723           && !memcmp (serialno, "D27600012401", 12)) /* OpenPGP card. */
1724         *cardsn = xtryasprintf ("cardno:%.12s", serialno+16);
1725       else /* Something is wrong: Print all. */
1726         *cardsn = xtryasprintf ("cardno:%s", serialno);
1727       if (!*cardsn)
1728         {
1729           err = gpg_error_from_errno (errno);
1730           xfree (pkbuf);
1731           gcry_sexp_release (s_pk);
1732           xfree (serialno);
1733           return err;
1734         }
1735     }
1736
1737   xfree (pkbuf);
1738   xfree (serialno);
1739   *r_pk = s_pk;
1740   return 0;
1741 }
1742
1743
1744 \f
1745
1746 /*
1747
1748   Request handler.  Each handler is provided with a CTRL context, a
1749   REQUEST object and a RESPONSE object.  The actual request is to be
1750   read from REQUEST, the response needs to be written to RESPONSE.
1751
1752 */
1753
1754
1755 /* Handler for the "request_identities" command.  */
1756 static gpg_error_t
1757 ssh_handler_request_identities (ctrl_t ctrl,
1758                                 estream_t request, estream_t response)
1759 {
1760   char *key_type;
1761   ssh_key_type_spec_t spec;
1762   struct dirent *dir_entry;
1763   char *key_directory;
1764   size_t key_directory_n;
1765   char *key_path;
1766   unsigned char *buffer;
1767   size_t buffer_n;
1768   u32 key_counter;
1769   estream_t key_blobs;
1770   gcry_sexp_t key_secret;
1771   gcry_sexp_t key_public;
1772   DIR *dir;
1773   gpg_error_t err;
1774   int ret;
1775   FILE *ctrl_fp = NULL;
1776   char *cardsn;
1777   gpg_error_t ret_err;
1778
1779   /* Prepare buffer stream.  */
1780
1781   key_directory = NULL;
1782   key_secret = NULL;
1783   key_public = NULL;
1784   key_type = NULL;
1785   key_path = NULL;
1786   key_counter = 0;
1787   buffer = NULL;
1788   dir = NULL;
1789   err = 0;
1790
1791   key_blobs = es_mopen (NULL, 0, 0, 1, NULL, NULL, "r+");
1792   if (! key_blobs)
1793     {
1794       err = gpg_error_from_errno (errno);
1795       goto out;
1796     }
1797
1798   /* Open key directory.  */
1799   key_directory = make_filename (opt.homedir, GNUPG_PRIVATE_KEYS_DIR, NULL);
1800   if (! key_directory)
1801     {
1802       err = gpg_err_code_from_errno (errno);
1803       goto out;
1804     }
1805   key_directory_n = strlen (key_directory);
1806   
1807   key_path = xtrymalloc (key_directory_n + 46);
1808   if (! key_path)
1809     {
1810       err = gpg_err_code_from_errno (errno);
1811       goto out;
1812     }
1813
1814   sprintf (key_path, "%s/", key_directory);
1815   sprintf (key_path + key_directory_n + 41, ".key");
1816
1817   dir = opendir (key_directory);
1818   if (! dir)
1819     {
1820       err = gpg_err_code_from_errno (errno);
1821       goto out;
1822     }
1823
1824
1825
1826   /* First check whether a key is currently available in the card
1827      reader - this should be allowed even without being listed in
1828      sshcontrol. */
1829
1830   if (!card_key_available (ctrl, &key_public, &cardsn))
1831     {
1832       err = ssh_send_key_public (key_blobs, key_public, cardsn);
1833       gcry_sexp_release (key_public);
1834       key_public = NULL;
1835       xfree (cardsn);
1836       if (err)
1837         goto out;
1838       
1839       key_counter++;
1840     }
1841
1842
1843   /* Then look at all the registered an allowed keys. */
1844
1845
1846   /* Fixme: We should better iterate over the control file and check
1847      whether the key file is there.  This is better in resepct to
1848      performance if tehre are a lot of key sin our key storage. */
1849   /* FIXME: make sure that buffer gets deallocated properly.  */
1850   err = open_control_file (&ctrl_fp, 0);
1851   if (err)
1852     goto out;
1853
1854   while ( (dir_entry = readdir (dir)) )
1855     {
1856       if ((strlen (dir_entry->d_name) == 44)
1857           && (! strncmp (dir_entry->d_name + 40, ".key", 4)))
1858         {
1859           char hexgrip[41];
1860           int disabled;
1861
1862           /* We do only want to return keys listed in our control
1863              file. */
1864           strncpy (hexgrip, dir_entry->d_name, 40);
1865           hexgrip[40] = 0;
1866           if ( strlen (hexgrip) != 40 )
1867             continue;
1868           if (search_control_file (ctrl_fp, hexgrip, &disabled)
1869               || disabled)
1870             continue;
1871
1872           strncpy (key_path + key_directory_n + 1, dir_entry->d_name, 40);
1873
1874           /* Read file content.  */
1875           err = file_to_buffer (key_path, &buffer, &buffer_n);
1876           if (err)
1877             goto out;
1878               
1879           err = gcry_sexp_sscan (&key_secret, NULL, (char*)buffer, buffer_n);
1880           if (err)
1881             goto out;
1882
1883           xfree (buffer);
1884           buffer = NULL;
1885
1886           err = sexp_extract_identifier (key_secret, &key_type);
1887           if (err)
1888             goto out;
1889
1890           err = ssh_key_type_lookup (NULL, key_type, &spec);
1891           if (err)
1892             goto out;
1893
1894           xfree (key_type);
1895           key_type = NULL;
1896
1897           err = key_secret_to_public (&key_public, spec, key_secret);
1898           if (err)
1899             goto out;
1900
1901           gcry_sexp_release (key_secret);
1902           key_secret = NULL;
1903               
1904           err = ssh_send_key_public (key_blobs, key_public, NULL);
1905           if (err)
1906             goto out;
1907
1908           gcry_sexp_release (key_public);
1909           key_public = NULL;
1910
1911           key_counter++;
1912         }
1913     }
1914   
1915   ret = es_fseek (key_blobs, 0, SEEK_SET);
1916   if (ret)
1917     {
1918       err = gpg_error_from_errno (errno);
1919       goto out;
1920     }
1921
1922  out:
1923
1924   /* Send response.  */
1925
1926   gcry_sexp_release (key_secret);
1927   gcry_sexp_release (key_public);
1928
1929   if (! err)
1930     {
1931       ret_err = stream_write_byte (response, SSH_RESPONSE_IDENTITIES_ANSWER);
1932       if (ret_err)
1933         goto leave;
1934       ret_err = stream_write_uint32 (response, key_counter);
1935       if (ret_err)
1936         goto leave;
1937       ret_err = stream_copy (response, key_blobs);
1938       if (ret_err)
1939         goto leave;
1940     }
1941   else
1942     {
1943       ret_err = stream_write_byte (response, SSH_RESPONSE_FAILURE);
1944       goto leave;
1945     };
1946
1947  leave:
1948
1949   if (key_blobs)
1950     es_fclose (key_blobs);
1951   if (dir)
1952     closedir (dir);
1953
1954   if (ctrl_fp)
1955     fclose (ctrl_fp);
1956
1957   free (key_directory);
1958   xfree (key_path);
1959   xfree (buffer);
1960   xfree (key_type);
1961
1962   return ret_err;
1963 }
1964
1965 /* This function hashes the data contained in DATA of size DATA_N
1966    according to the message digest algorithm specified by MD_ALGORITHM
1967    and writes the message digest to HASH, which needs to large enough
1968    for the digest.  */
1969 static gpg_error_t
1970 data_hash (unsigned char *data, size_t data_n,
1971            int md_algorithm, unsigned char *hash)
1972 {
1973   gcry_md_hash_buffer (md_algorithm, hash, data, data_n);
1974
1975   return 0;
1976 }
1977
1978 /* This function signs the data contained in CTRL, stores the created
1979    signature in newly allocated memory in SIG and it's size in SIG_N;
1980    SIG_ENCODER is the signature encoder to use.  */
1981 static gpg_error_t
1982 data_sign (ctrl_t ctrl, ssh_signature_encoder_t sig_encoder,
1983            unsigned char **sig, size_t *sig_n)
1984 {
1985   gpg_error_t err;
1986   gcry_sexp_t signature_sexp = NULL;
1987   estream_t stream = NULL;
1988   gcry_sexp_t valuelist = NULL;
1989   gcry_sexp_t sublist = NULL;
1990   gcry_mpi_t sig_value = NULL;
1991   unsigned char *sig_blob = NULL;
1992   size_t sig_blob_n = 0;
1993   char *identifier = NULL;
1994   const char *identifier_raw;
1995   size_t identifier_n;
1996   ssh_key_type_spec_t spec;
1997   int ret;
1998   unsigned int i;
1999   const char *elems;
2000   size_t elems_n;
2001   gcry_mpi_t *mpis = NULL;
2002
2003   *sig = NULL;
2004   *sig_n = 0;
2005
2006   ctrl->use_auth_call = 1;
2007   err = agent_pksign_do (ctrl,
2008                          _("Please enter the passphrase "
2009                            "for the ssh key%0A  %c"), &signature_sexp,
2010                          CACHE_MODE_SSH);
2011   ctrl->use_auth_call = 0;
2012   if (err)
2013     goto out;
2014
2015   valuelist = gcry_sexp_nth (signature_sexp, 1);
2016   if (! valuelist)
2017     {
2018       err = gpg_error (GPG_ERR_INV_SEXP);
2019       goto out;
2020     }
2021
2022   stream = es_mopen (NULL, 0, 0, 1, NULL, NULL, "r+");
2023   if (! stream)
2024     {
2025       err = gpg_error_from_errno (errno);
2026       goto out;
2027     }
2028
2029   identifier_raw = gcry_sexp_nth_data (valuelist, 0, &identifier_n);
2030   if (! identifier_raw)
2031     {
2032       err = gpg_error (GPG_ERR_INV_SEXP);
2033       goto out;
2034     }
2035
2036   identifier = make_cstring (identifier_raw, identifier_n);
2037   if (! identifier)
2038     {
2039       err = gpg_error_from_errno (errno);
2040       goto out;
2041     }
2042
2043   err = ssh_key_type_lookup (NULL, identifier, &spec);
2044   if (err)
2045     goto out;
2046
2047   err = stream_write_cstring (stream, spec.ssh_identifier);
2048   if (err)
2049     goto out;
2050
2051   elems = spec.elems_signature;
2052   elems_n = strlen (elems);
2053
2054   mpis = xtrymalloc (sizeof (*mpis) * (elems_n + 1));
2055   if (! mpis)
2056     {
2057       err = gpg_error_from_errno (errno);
2058       goto out;
2059     }
2060   memset (mpis, 0, sizeof (*mpis) * (elems_n + 1));
2061
2062   for (i = 0; i < elems_n; i++)
2063     {
2064       sublist = gcry_sexp_find_token (valuelist, spec.elems_signature + i, 1);
2065       if (! sublist)
2066         {
2067           err = gpg_error (GPG_ERR_INV_SEXP);
2068           break;
2069         }
2070
2071       sig_value = gcry_sexp_nth_mpi (sublist, 1, GCRYMPI_FMT_USG);
2072       if (! sig_value)
2073         {
2074           err = gpg_error (GPG_ERR_INTERNAL); /* FIXME?  */
2075           break;
2076         }
2077       gcry_sexp_release (sublist);
2078       sublist = NULL;
2079
2080       mpis[i] = sig_value;
2081     }
2082   if (err)
2083     goto out;
2084
2085   err = (*sig_encoder) (stream, mpis);
2086   if (err)
2087     goto out;
2088
2089   sig_blob_n = es_ftell (stream);
2090   if (sig_blob_n == -1)
2091     {
2092       err = gpg_error_from_errno (errno);
2093       goto out;
2094     }
2095
2096   sig_blob = xtrymalloc (sig_blob_n);
2097   if (! sig_blob)
2098     {
2099       err = gpg_error_from_errno (errno);
2100       goto out;
2101     }
2102
2103   ret = es_fseek (stream, 0, SEEK_SET);
2104   if (ret)
2105     {
2106       err = gpg_error_from_errno (errno);
2107       goto out;
2108     }    
2109
2110   err = stream_read_data (stream, sig_blob, sig_blob_n);
2111   if (err)
2112     goto out;
2113   
2114   *sig = sig_blob;
2115   *sig_n = sig_blob_n;
2116   
2117  out:
2118
2119   if (err)
2120     xfree (sig_blob);
2121
2122   if (stream)
2123     es_fclose (stream);
2124   gcry_sexp_release (valuelist);
2125   gcry_sexp_release (signature_sexp);
2126   gcry_sexp_release (sublist);
2127   mpint_list_free (mpis);
2128   xfree (identifier);
2129
2130   return err;
2131 }
2132
2133 /* Handler for the "sign_request" command.  */
2134 static gpg_error_t
2135 ssh_handler_sign_request (ctrl_t ctrl, estream_t request, estream_t response)
2136 {
2137   gcry_sexp_t key;
2138   ssh_key_type_spec_t spec;
2139   unsigned char hash[MAX_DIGEST_LEN];
2140   unsigned int hash_n;
2141   unsigned char key_grip[20];
2142   unsigned char *key_blob;
2143   u32 key_blob_size;
2144   unsigned char *data;
2145   unsigned char *sig;
2146   size_t sig_n;
2147   u32 data_size;
2148   u32 flags;
2149   gpg_error_t err;
2150   gpg_error_t ret_err;
2151
2152   key_blob = NULL;
2153   data = NULL;
2154   sig = NULL;
2155   key = NULL;
2156
2157   /* Receive key.  */
2158   
2159   err = stream_read_string (request, 0, &key_blob, &key_blob_size);
2160   if (err)
2161     goto out;
2162
2163   err = ssh_read_key_public_from_blob (key_blob, key_blob_size, &key, &spec);
2164   if (err)
2165     goto out;
2166
2167   /* Receive data to sign.  */
2168   err = stream_read_string (request, 0, &data, &data_size);
2169   if (err)
2170     goto out;
2171
2172   /* FIXME?  */
2173   err = stream_read_uint32 (request, &flags);
2174   if (err)
2175     goto out;
2176
2177   /* Hash data.  */
2178   hash_n = gcry_md_get_algo_dlen (GCRY_MD_SHA1);
2179   if (! hash_n)
2180     {
2181       err = gpg_error (GPG_ERR_INTERNAL);
2182       goto out;
2183     }
2184   err = data_hash (data, data_size, GCRY_MD_SHA1, hash);
2185   if (err)
2186     goto out;
2187
2188   /* Calculate key grip.  */
2189   err = ssh_key_grip (key, key_grip);
2190   if (err)
2191     goto out;
2192
2193   /* Sign data.  */
2194
2195   ctrl->digest.algo = GCRY_MD_SHA1;
2196   memcpy (ctrl->digest.value, hash, hash_n);
2197   ctrl->digest.valuelen = hash_n;
2198   ctrl->digest.raw_value = ! (spec.flags & SPEC_FLAG_USE_PKCS1V2);
2199   ctrl->have_keygrip = 1;
2200   memcpy (ctrl->keygrip, key_grip, 20);
2201
2202   err = data_sign (ctrl, spec.signature_encoder, &sig, &sig_n);
2203   
2204  out:
2205
2206   /* Done.  */
2207
2208   if (! err)
2209     {
2210       ret_err = stream_write_byte (response, SSH_RESPONSE_SIGN_RESPONSE);
2211       if (ret_err)
2212         goto leave;
2213       ret_err = stream_write_string (response, sig, sig_n);
2214       if (ret_err)
2215         goto leave;
2216     }
2217   else
2218     {
2219       ret_err = stream_write_byte (response, SSH_RESPONSE_FAILURE);
2220       if (ret_err)
2221         goto leave;
2222     }
2223   
2224  leave:
2225
2226   gcry_sexp_release (key);
2227   xfree (key_blob);
2228   xfree (data);
2229   xfree (sig);
2230
2231   return ret_err;
2232 }
2233
2234 /* This function extracts the comment contained in the key
2235    S-Expression KEY and stores a copy in COMMENT.  Returns usual error
2236    code.  */
2237 static gpg_error_t
2238 ssh_key_extract_comment (gcry_sexp_t key, char **comment)
2239 {
2240   gcry_sexp_t comment_list;
2241   char *comment_new;
2242   const char *data;
2243   size_t data_n;
2244   gpg_error_t err;
2245
2246   comment_list = gcry_sexp_find_token (key, "comment", 0);
2247   if (! comment_list)
2248     {
2249       err = gpg_error (GPG_ERR_INV_SEXP);
2250       goto out;
2251     }
2252   
2253   data = gcry_sexp_nth_data (comment_list, 1, &data_n);
2254   if (! data)
2255     {
2256       err = gpg_error (GPG_ERR_INV_SEXP);
2257       goto out;
2258     }
2259
2260   comment_new = make_cstring (data, data_n);
2261   if (! comment_new)
2262     {
2263       err = gpg_error_from_errno (errno);
2264       goto out;
2265     }
2266
2267   *comment = comment_new;
2268   err = 0;
2269
2270  out:
2271
2272   gcry_sexp_release (comment_list);
2273
2274   return err;
2275 }
2276
2277 /* This function converts the key contained in the S-Expression KEY
2278    into a buffer, which is protected by the passphrase PASSPHRASE.
2279    Returns usual error code.  */
2280 static gpg_error_t
2281 ssh_key_to_protected_buffer (gcry_sexp_t key, const char *passphrase,
2282                              unsigned char **buffer, size_t *buffer_n)
2283 {
2284   unsigned char *buffer_new;
2285   unsigned int buffer_new_n;
2286   gpg_error_t err;
2287
2288   err = 0;
2289   buffer_new_n = gcry_sexp_sprint (key, GCRYSEXP_FMT_CANON, NULL, 0);
2290   buffer_new = xtrymalloc_secure (buffer_new_n);
2291   if (! buffer_new)
2292     {
2293       err = gpg_error_from_errno (errno);
2294       goto out;
2295     }
2296   
2297   gcry_sexp_sprint (key, GCRYSEXP_FMT_CANON, buffer_new, buffer_new_n);
2298   /* FIXME: guarantee?  */
2299
2300   err = agent_protect (buffer_new, passphrase, buffer, buffer_n);
2301
2302  out:
2303
2304   xfree (buffer_new);
2305
2306   return err;
2307 }
2308
2309
2310
2311 /* Store the ssh KEY into our local key storage and protect it after
2312    asking for a passphrase.  Cache that passphrase.  TTL is the
2313    maximum caching time for that key.  If the key already exists in
2314    our key storage, don't do anything.  When entering a new key also
2315    add an entry to the sshcontrol file.  */
2316 static gpg_error_t
2317 ssh_identity_register (ctrl_t ctrl, gcry_sexp_t key, int ttl)
2318 {
2319   gpg_error_t err;
2320   unsigned char key_grip_raw[21];
2321   char key_grip[41];
2322   unsigned char *buffer = NULL;
2323   unsigned int buffer_n;
2324   char *description = NULL;
2325   char *comment = NULL;
2326   unsigned int i;
2327   struct pin_entry_info_s *pi = NULL;
2328
2329   err = ssh_key_grip (key, key_grip_raw);
2330   if (err)
2331     goto out;
2332
2333   key_grip_raw[sizeof (key_grip_raw) - 1] = 0; /* FIXME:  Why?? */
2334
2335   /* Check whether the key is already in our key storage.  Don't do
2336      anything then.  */
2337   if ( !agent_key_available (key_grip_raw) )
2338     goto out; /* Yes, key is available.  */
2339
2340   
2341   err = ssh_key_extract_comment (key, &comment);
2342   if (err)
2343     goto out;
2344
2345   if ( asprintf (&description,
2346                  _("Please enter a passphrase to protect"
2347                    " the received secret key%%0A"
2348                    "   %s%%0A"
2349                    "within gpg-agent's key storage"),
2350                  comment ? comment : "?") < 0)
2351     {
2352       err = gpg_error_from_errno (errno);
2353       goto out;
2354     }
2355
2356
2357   pi = gcry_calloc_secure (1, sizeof (*pi) + 100 + 1);
2358   if (!pi)
2359     {
2360       err = gpg_error_from_errno (errno);
2361       goto out;
2362     }
2363   pi->max_length = 100;
2364   pi->max_tries = 1;
2365   err = agent_askpin (ctrl, description, NULL, NULL, pi);
2366   if (err)
2367     goto out;
2368
2369   err = ssh_key_to_protected_buffer (key, pi->pin, &buffer, &buffer_n);
2370   if (err)
2371     goto out;
2372
2373   /* Store this key to our key storage.  */
2374   err = agent_write_private_key (key_grip_raw, buffer, buffer_n, 0);
2375   if (err)
2376     goto out;
2377
2378   /* Cache this passphrase. */
2379   for (i = 0; i < 20; i++)
2380     sprintf (key_grip + 2 * i, "%02X", key_grip_raw[i]);
2381
2382   err = agent_put_cache (key_grip, CACHE_MODE_SSH, pi->pin, ttl);
2383   if (err)
2384     goto out;
2385
2386   /* And add an entry to the sshcontrol file.  */
2387   err = add_control_entry (ctrl, key_grip, ttl);
2388
2389
2390  out:
2391   if (pi && pi->max_length)
2392     wipememory (pi->pin, pi->max_length);
2393   xfree (pi);
2394   xfree (buffer);
2395   xfree (comment);
2396   free (description); /* (asprintf allocated, thus regular free.)  */
2397
2398   return err;
2399 }
2400
2401
2402 /* This function removes the key contained in the S-Expression KEY
2403    from the local key storage, in case it exists there.  Returns usual
2404    error code.  FIXME: this function is a stub.  */
2405 static gpg_error_t
2406 ssh_identity_drop (gcry_sexp_t key)
2407 {
2408   unsigned char key_grip[21] = { 0 };
2409   gpg_error_t err;
2410
2411   err = ssh_key_grip (key, key_grip);
2412   if (err)
2413     goto out;
2414
2415   key_grip[sizeof (key_grip) - 1] = 0;
2416
2417   /* FIXME: What to do here - forgetting the passphrase or deleting
2418      the key from key cache?  */
2419
2420  out:
2421
2422   return err;
2423 }
2424
2425 /* Handler for the "add_identity" command.  */
2426 static gpg_error_t
2427 ssh_handler_add_identity (ctrl_t ctrl, estream_t request, estream_t response)
2428 {
2429   gpg_error_t ret_err;
2430   gpg_error_t err;
2431   gcry_sexp_t key;
2432   unsigned char b;
2433   int confirm;
2434   int ttl;
2435   
2436   confirm = 0;
2437   key = NULL;
2438   ttl = 0;
2439
2440   /* FIXME?  */
2441   err = ssh_receive_key (request, &key, 1, 1, NULL);
2442   if (err)
2443     goto out;
2444
2445   while (1)
2446     {
2447       err = stream_read_byte (request, &b);
2448       if (gpg_err_code (err) == GPG_ERR_EOF)
2449         {
2450           err = 0;
2451           break;
2452         }
2453
2454       switch (b)
2455         {
2456         case SSH_OPT_CONSTRAIN_LIFETIME:
2457           {
2458             u32 n = 0;
2459
2460             err = stream_read_uint32 (request, &n);
2461             if (! err)
2462               ttl = n;
2463             break;
2464           }
2465
2466         case SSH_OPT_CONSTRAIN_CONFIRM:
2467           {
2468             confirm = 1;
2469             break;
2470           }
2471
2472         default:
2473           /* FIXME: log/bad?  */
2474           break;
2475         }
2476     }
2477   if (err)
2478     goto out;
2479
2480   /* FIXME: are constraints used correctly?  */
2481
2482   err = ssh_identity_register (ctrl, key, ttl);
2483
2484  out:
2485
2486   gcry_sexp_release (key);
2487
2488   if (! err)
2489     ret_err = stream_write_byte (response, SSH_RESPONSE_SUCCESS);
2490   else
2491     ret_err = stream_write_byte (response, SSH_RESPONSE_FAILURE);
2492
2493   return ret_err;
2494 }
2495
2496 /* Handler for the "remove_identity" command.  */
2497 static gpg_error_t
2498 ssh_handler_remove_identity (ctrl_t ctrl,
2499                              estream_t request, estream_t response)
2500 {
2501   unsigned char *key_blob;
2502   u32 key_blob_size;
2503   gcry_sexp_t key;
2504   gpg_error_t ret_err;
2505   gpg_error_t err;
2506
2507   /* Receive key.  */
2508
2509   key_blob = NULL;
2510   key = NULL;
2511   
2512   err = stream_read_string (request, 0, &key_blob, &key_blob_size);
2513   if (err)
2514     goto out;
2515
2516   err = ssh_read_key_public_from_blob (key_blob, key_blob_size, &key, NULL);
2517   if (err)
2518     goto out;
2519   
2520   err = ssh_identity_drop (key);
2521
2522  out:
2523
2524   xfree (key_blob);
2525   gcry_sexp_release (key);
2526
2527   if (! err)
2528     ret_err = stream_write_byte (response, SSH_RESPONSE_SUCCESS);
2529   else
2530     ret_err = stream_write_byte (response, SSH_RESPONSE_FAILURE);
2531
2532   return ret_err;
2533 }
2534
2535 /* FIXME: stub function.  Actually useful?  */
2536 static gpg_error_t
2537 ssh_identities_remove_all (void)
2538 {
2539   gpg_error_t err;
2540
2541   err = 0;
2542
2543   /* FIXME: shall we remove _all_ cache entries or only those
2544      registered through the ssh emulation?  */
2545   
2546   return err;
2547 }
2548
2549 /* Handler for the "remove_all_identities" command.  */
2550 static gpg_error_t
2551 ssh_handler_remove_all_identities (ctrl_t ctrl,
2552                                    estream_t request, estream_t response)
2553 {
2554   gpg_error_t ret_err;
2555   gpg_error_t err;
2556   
2557   err = ssh_identities_remove_all ();
2558
2559   if (! err)
2560     ret_err = stream_write_byte (response, SSH_RESPONSE_SUCCESS);
2561   else
2562     ret_err = stream_write_byte (response, SSH_RESPONSE_FAILURE);
2563
2564   return ret_err;
2565 }
2566
2567 /* Lock agent?  FIXME: stub function.  */
2568 static gpg_error_t
2569 ssh_lock (void)
2570 {
2571   gpg_error_t err;
2572
2573   /* FIXME */
2574   log_error ("ssh-agent's lock command is not implemented\n");
2575   err = 0;
2576
2577   return err;
2578 }
2579
2580 /* Unock agent?  FIXME: stub function.  */
2581 static gpg_error_t
2582 ssh_unlock (void)
2583 {
2584   gpg_error_t err;
2585
2586   log_error ("ssh-agent's unlock command is not implemented\n");
2587   err = 0;
2588
2589   return err;
2590 }
2591
2592 /* Handler for the "lock" command.  */
2593 static gpg_error_t
2594 ssh_handler_lock (ctrl_t ctrl, estream_t request, estream_t response)
2595 {
2596   gpg_error_t ret_err;
2597   gpg_error_t err;
2598   
2599   err = ssh_lock ();
2600
2601   if (! err)
2602     ret_err = stream_write_byte (response, SSH_RESPONSE_SUCCESS);
2603   else
2604     ret_err = stream_write_byte (response, SSH_RESPONSE_FAILURE);
2605
2606   return ret_err;
2607 }
2608
2609 /* Handler for the "unlock" command.  */
2610 static gpg_error_t
2611 ssh_handler_unlock (ctrl_t ctrl, estream_t request, estream_t response)
2612 {
2613   gpg_error_t ret_err;
2614   gpg_error_t err;
2615   
2616   err = ssh_unlock ();
2617
2618   if (! err)
2619     ret_err = stream_write_byte (response, SSH_RESPONSE_SUCCESS);
2620   else
2621     ret_err = stream_write_byte (response, SSH_RESPONSE_FAILURE);
2622
2623   return ret_err;
2624 }
2625
2626 \f
2627
2628 /* Return the request specification for the request identified by TYPE
2629    or NULL in case the requested request specification could not be
2630    found.  */
2631 static ssh_request_spec_t *
2632 request_spec_lookup (int type)
2633 {
2634   ssh_request_spec_t *spec;
2635   unsigned int i;
2636
2637   for (i = 0; i < DIM (request_specs); i++)
2638     if (request_specs[i].type == type)
2639       break;
2640   if (i == DIM (request_specs))
2641     {
2642       log_info ("ssh request %u is not supported\n", type);
2643       spec = NULL;
2644     }
2645   else
2646     spec = request_specs + i;
2647
2648   return spec;
2649 }
2650
2651 /* Process a single request.  The request is read from and the
2652    response is written to STREAM_SOCK.  Uses CTRL as context.  Returns
2653    zero in case of success, non zero in case of failure.  */
2654 static int
2655 ssh_request_process (ctrl_t ctrl, estream_t stream_sock)
2656 {
2657   ssh_request_spec_t *spec;
2658   estream_t response;
2659   estream_t request;
2660   unsigned char request_type;
2661   gpg_error_t err;
2662   int send_err;
2663   int ret;
2664   unsigned char *request_data;
2665   u32 request_data_size;
2666   u32 response_size;
2667
2668   request_data = NULL;
2669   response = NULL;
2670   request = NULL;
2671   send_err = 0;
2672
2673   /* Create memory streams for request/response data.  The entire
2674      request will be stored in secure memory, since it might contain
2675      secret key material.  The response does not have to be stored in
2676      secure memory, since we never give out secret keys. 
2677
2678      FIXME: This is a pretty good DoS.  We only have a limited amount
2679      of secure memory, we can't throw in everything we get from a
2680      client -wk */
2681       
2682   /* Retrieve request.  */
2683   err = stream_read_string (stream_sock, 1, &request_data, &request_data_size);
2684   if (err)
2685     goto out;
2686
2687   if (opt.verbose > 1)
2688     log_info ("received ssh request of length %u\n",
2689               (unsigned int)request_data_size);
2690
2691   if (! request_data_size)
2692     {
2693       send_err = 1;
2694       goto out;
2695       /* Broken request; FIXME.  */
2696     }
2697
2698   request_type = request_data[0];
2699   spec = request_spec_lookup (request_type);
2700   if (! spec)
2701     {
2702       send_err = 1;
2703       goto out;
2704       /* Unknown request; FIXME.  */
2705     }
2706
2707   if (spec->secret_input)
2708     request = es_mopen (NULL, 0, 0, 1, realloc_secure, gcry_free, "r+");
2709   else
2710     request = es_mopen (NULL, 0, 0, 1, gcry_realloc, gcry_free, "r+");
2711   if (! request)
2712     {
2713       err = gpg_error_from_errno (errno);
2714       goto out;
2715     }
2716   ret = es_setvbuf (request, NULL, _IONBF, 0);
2717   if (ret)
2718     {
2719       err = gpg_error_from_errno (errno);
2720       goto out;
2721     }
2722   err = stream_write_data (request, request_data + 1, request_data_size - 1);
2723   if (err)
2724     goto out;
2725   es_rewind (request);
2726
2727   response = es_mopen (NULL, 0, 0, 1, NULL, NULL, "r+");
2728   if (! response)
2729     {
2730       err = gpg_error_from_errno (errno);
2731       goto out;
2732     }
2733
2734   if (opt.verbose)
2735     log_info ("ssh request handler for %s (%u) started\n",
2736                spec->identifier, spec->type);
2737
2738   err = (*spec->handler) (ctrl, request, response);
2739
2740   if (opt.verbose)
2741     {
2742       if (err)
2743         log_info ("ssh request handler for %s (%u) failed: %s\n",
2744                   spec->identifier, spec->type, gpg_strerror (err));
2745       else
2746         log_info ("ssh request handler for %s (%u) ready\n",
2747                   spec->identifier, spec->type);
2748     }
2749
2750   if (err)
2751     {
2752       send_err = 1;
2753       goto out;
2754     }
2755
2756   response_size = es_ftell (response);
2757   if (opt.verbose > 1)
2758     log_info ("sending ssh response of length %u\n",
2759               (unsigned int)response_size);
2760
2761   err = es_fseek (response, 0, SEEK_SET);
2762   if (err)
2763     {
2764       send_err = 1;
2765       goto out;
2766     }
2767
2768   err = stream_write_uint32 (stream_sock, response_size);
2769   if (err)
2770     {
2771       send_err = 1;
2772       goto out;
2773     }
2774
2775   err = stream_copy (stream_sock, response);
2776   if (err)
2777     goto out;
2778
2779   err = es_fflush (stream_sock);
2780   if (err)
2781     goto out;
2782
2783  out:
2784
2785   if (err && es_feof (stream_sock))
2786     log_error ("error occured while processing request: %s\n",
2787                gpg_strerror (err));
2788
2789   if (send_err)
2790     {
2791       if (opt.verbose > 1)
2792         log_info ("sending ssh error response\n");
2793       err = stream_write_uint32 (stream_sock, 1);
2794       if (err)
2795         goto leave;
2796       err = stream_write_byte (stream_sock, SSH_RESPONSE_FAILURE);
2797       if (err)
2798         goto leave;
2799     }
2800
2801  leave:
2802
2803   if (request)
2804     es_fclose (request);
2805   if (response)
2806     es_fclose (response);
2807   xfree (request_data);         /* FIXME?  */
2808
2809   return !!err;
2810 }
2811
2812 /* Start serving client on SOCK_CLIENT.  */
2813 void
2814 start_command_handler_ssh (int sock_client)
2815 {
2816   struct server_control_s ctrl;
2817   estream_t stream_sock;
2818   gpg_error_t err;
2819   int ret;
2820
2821   /* Setup control structure.  */
2822
2823   memset (&ctrl, 0, sizeof (ctrl));
2824   agent_init_default_ctrl (&ctrl);
2825   ctrl.connection_fd = sock_client;
2826
2827   /* Because the ssh protocol does not send us information about the
2828      the current TTY setting, we resort here to use those from startup
2829      or those explictly set.  */
2830   if (!ctrl.display && opt.startup_display)
2831     ctrl.display = strdup (opt.startup_display);
2832   if (!ctrl.ttyname && opt.startup_ttyname)
2833     ctrl.ttyname = strdup (opt.startup_ttyname);
2834   if (!ctrl.ttytype && opt.startup_ttytype)
2835     ctrl.ttytype = strdup (opt.startup_ttytype);
2836   if (!ctrl.lc_ctype && opt.startup_lc_ctype)
2837     ctrl.lc_ctype = strdup (opt.startup_lc_ctype);
2838   if (!ctrl.lc_messages && opt.startup_lc_messages)
2839     ctrl.lc_messages = strdup (opt.startup_lc_messages);
2840
2841
2842   /* Create stream from socket.  */
2843   stream_sock = es_fdopen (sock_client, "r+");
2844   if (!stream_sock)
2845     {
2846       err = gpg_error_from_errno (errno);
2847       log_error (_("failed to create stream from socket: %s\n"),
2848                  gpg_strerror (err));
2849       goto out;
2850     }
2851   /* We have to disable the estream buffering, because the estream
2852      core doesn't know about secure memory.  */
2853   ret = es_setvbuf (stream_sock, NULL, _IONBF, 0);
2854   if (ret)
2855     {
2856       err = gpg_error_from_errno (errno);
2857       log_error (_("failed to disable buffering "
2858                    "on socket stream: %s\n"), gpg_strerror (err));
2859       goto out;
2860     }
2861
2862   /* Main processing loop. */
2863   while ( !ssh_request_process (&ctrl, stream_sock) )
2864     ;
2865
2866   /* Reset the SCD in case it has been used. */
2867   agent_reset_scd (&ctrl);
2868
2869
2870  out:
2871   if (stream_sock)
2872     es_fclose (stream_sock);
2873
2874   free (ctrl.display);
2875   free (ctrl.ttyname);
2876   free (ctrl.ttytype);
2877   free (ctrl.lc_ctype);
2878   free (ctrl.lc_messages);
2879 }