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