Changed to GPLv3.
[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   free (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 /* Store the ssh KEY into our local key storage and protect it after
2317    asking for a passphrase.  Cache that passphrase.  TTL is the
2318    maximum caching time for that key.  If the key already exists in
2319    our key storage, don't do anything.  When entering a new key also
2320    add an entry to the sshcontrol file.  */
2321 static gpg_error_t
2322 ssh_identity_register (ctrl_t ctrl, gcry_sexp_t key, int ttl)
2323 {
2324   gpg_error_t err;
2325   unsigned char key_grip_raw[20];
2326   char key_grip[41];
2327   unsigned char *buffer = NULL;
2328   size_t buffer_n;
2329   char *description = NULL;
2330   char *comment = NULL;
2331   unsigned int i;
2332   struct pin_entry_info_s *pi = NULL;
2333
2334   err = ssh_key_grip (key, key_grip_raw);
2335   if (err)
2336     goto out;
2337
2338   /* Check whether the key is already in our key storage.  Don't do
2339      anything then.  */
2340   if ( !agent_key_available (key_grip_raw) )
2341     goto out; /* Yes, key is available.  */
2342
2343   
2344   err = ssh_key_extract_comment (key, &comment);
2345   if (err)
2346     goto out;
2347
2348   if ( asprintf (&description,
2349                  _("Please enter a passphrase to protect"
2350                    " the received secret key%%0A"
2351                    "   %s%%0A"
2352                    "within gpg-agent's key storage"),
2353                  comment ? comment : "?") < 0)
2354     {
2355       err = gpg_error_from_syserror ();
2356       goto out;
2357     }
2358
2359
2360   pi = gcry_calloc_secure (1, sizeof (*pi) + 100 + 1);
2361   if (!pi)
2362     {
2363       err = gpg_error_from_syserror ();
2364       goto out;
2365     }
2366   pi->max_length = 100;
2367   pi->max_tries = 1;
2368   err = agent_askpin (ctrl, description, NULL, NULL, pi);
2369   if (err)
2370     goto out;
2371
2372   err = ssh_key_to_protected_buffer (key, pi->pin, &buffer, &buffer_n);
2373   if (err)
2374     goto out;
2375
2376   /* Store this key to our key storage.  */
2377   err = agent_write_private_key (key_grip_raw, buffer, buffer_n, 0);
2378   if (err)
2379     goto out;
2380
2381   /* Cache this passphrase. */
2382   for (i = 0; i < 20; i++)
2383     sprintf (key_grip + 2 * i, "%02X", key_grip_raw[i]);
2384
2385   err = agent_put_cache (key_grip, CACHE_MODE_SSH, pi->pin, ttl);
2386   if (err)
2387     goto out;
2388
2389   /* And add an entry to the sshcontrol file.  */
2390   err = add_control_entry (ctrl, key_grip, ttl);
2391
2392
2393  out:
2394   if (pi && pi->max_length)
2395     wipememory (pi->pin, pi->max_length);
2396   xfree (pi);
2397   xfree (buffer);
2398   xfree (comment);
2399   free (description); /* (asprintf allocated, thus regular free.)  */
2400
2401   return err;
2402 }
2403
2404
2405 /* This function removes the key contained in the S-Expression KEY
2406    from the local key storage, in case it exists there.  Returns usual
2407    error code.  FIXME: this function is a stub.  */
2408 static gpg_error_t
2409 ssh_identity_drop (gcry_sexp_t key)
2410 {
2411   unsigned char key_grip[21] = { 0 };
2412   gpg_error_t err;
2413
2414   err = ssh_key_grip (key, key_grip);
2415   if (err)
2416     goto out;
2417
2418   key_grip[sizeof (key_grip) - 1] = 0;
2419
2420   /* FIXME: What to do here - forgetting the passphrase or deleting
2421      the key from key cache?  */
2422
2423  out:
2424
2425   return err;
2426 }
2427
2428 /* Handler for the "add_identity" command.  */
2429 static gpg_error_t
2430 ssh_handler_add_identity (ctrl_t ctrl, estream_t request, estream_t response)
2431 {
2432   gpg_error_t ret_err;
2433   gpg_error_t err;
2434   gcry_sexp_t key;
2435   unsigned char b;
2436   int confirm;
2437   int ttl;
2438   
2439   confirm = 0;
2440   key = NULL;
2441   ttl = 0;
2442
2443   /* FIXME?  */
2444   err = ssh_receive_key (request, &key, 1, 1, NULL);
2445   if (err)
2446     goto out;
2447
2448   while (1)
2449     {
2450       err = stream_read_byte (request, &b);
2451       if (gpg_err_code (err) == GPG_ERR_EOF)
2452         {
2453           err = 0;
2454           break;
2455         }
2456
2457       switch (b)
2458         {
2459         case SSH_OPT_CONSTRAIN_LIFETIME:
2460           {
2461             u32 n = 0;
2462
2463             err = stream_read_uint32 (request, &n);
2464             if (! err)
2465               ttl = n;
2466             break;
2467           }
2468
2469         case SSH_OPT_CONSTRAIN_CONFIRM:
2470           {
2471             confirm = 1;
2472             break;
2473           }
2474
2475         default:
2476           /* FIXME: log/bad?  */
2477           break;
2478         }
2479     }
2480   if (err)
2481     goto out;
2482
2483   /* FIXME: are constraints used correctly?  */
2484
2485   err = ssh_identity_register (ctrl, key, ttl);
2486
2487  out:
2488
2489   gcry_sexp_release (key);
2490
2491   if (! err)
2492     ret_err = stream_write_byte (response, SSH_RESPONSE_SUCCESS);
2493   else
2494     ret_err = stream_write_byte (response, SSH_RESPONSE_FAILURE);
2495
2496   return ret_err;
2497 }
2498
2499 /* Handler for the "remove_identity" command.  */
2500 static gpg_error_t
2501 ssh_handler_remove_identity (ctrl_t ctrl,
2502                              estream_t request, estream_t response)
2503 {
2504   unsigned char *key_blob;
2505   u32 key_blob_size;
2506   gcry_sexp_t key;
2507   gpg_error_t ret_err;
2508   gpg_error_t err;
2509
2510   /* Receive key.  */
2511
2512   key_blob = NULL;
2513   key = NULL;
2514   
2515   err = stream_read_string (request, 0, &key_blob, &key_blob_size);
2516   if (err)
2517     goto out;
2518
2519   err = ssh_read_key_public_from_blob (key_blob, key_blob_size, &key, NULL);
2520   if (err)
2521     goto out;
2522   
2523   err = ssh_identity_drop (key);
2524
2525  out:
2526
2527   xfree (key_blob);
2528   gcry_sexp_release (key);
2529
2530   if (! err)
2531     ret_err = stream_write_byte (response, SSH_RESPONSE_SUCCESS);
2532   else
2533     ret_err = stream_write_byte (response, SSH_RESPONSE_FAILURE);
2534
2535   return ret_err;
2536 }
2537
2538 /* FIXME: stub function.  Actually useful?  */
2539 static gpg_error_t
2540 ssh_identities_remove_all (void)
2541 {
2542   gpg_error_t err;
2543
2544   err = 0;
2545
2546   /* FIXME: shall we remove _all_ cache entries or only those
2547      registered through the ssh emulation?  */
2548   
2549   return err;
2550 }
2551
2552 /* Handler for the "remove_all_identities" command.  */
2553 static gpg_error_t
2554 ssh_handler_remove_all_identities (ctrl_t ctrl,
2555                                    estream_t request, estream_t response)
2556 {
2557   gpg_error_t ret_err;
2558   gpg_error_t err;
2559   
2560   err = ssh_identities_remove_all ();
2561
2562   if (! err)
2563     ret_err = stream_write_byte (response, SSH_RESPONSE_SUCCESS);
2564   else
2565     ret_err = stream_write_byte (response, SSH_RESPONSE_FAILURE);
2566
2567   return ret_err;
2568 }
2569
2570 /* Lock agent?  FIXME: stub function.  */
2571 static gpg_error_t
2572 ssh_lock (void)
2573 {
2574   gpg_error_t err;
2575
2576   /* FIXME */
2577   log_error ("ssh-agent's lock command is not implemented\n");
2578   err = 0;
2579
2580   return err;
2581 }
2582
2583 /* Unock agent?  FIXME: stub function.  */
2584 static gpg_error_t
2585 ssh_unlock (void)
2586 {
2587   gpg_error_t err;
2588
2589   log_error ("ssh-agent's unlock command is not implemented\n");
2590   err = 0;
2591
2592   return err;
2593 }
2594
2595 /* Handler for the "lock" command.  */
2596 static gpg_error_t
2597 ssh_handler_lock (ctrl_t ctrl, estream_t request, estream_t response)
2598 {
2599   gpg_error_t ret_err;
2600   gpg_error_t err;
2601   
2602   err = ssh_lock ();
2603
2604   if (! err)
2605     ret_err = stream_write_byte (response, SSH_RESPONSE_SUCCESS);
2606   else
2607     ret_err = stream_write_byte (response, SSH_RESPONSE_FAILURE);
2608
2609   return ret_err;
2610 }
2611
2612 /* Handler for the "unlock" command.  */
2613 static gpg_error_t
2614 ssh_handler_unlock (ctrl_t ctrl, estream_t request, estream_t response)
2615 {
2616   gpg_error_t ret_err;
2617   gpg_error_t err;
2618   
2619   err = ssh_unlock ();
2620
2621   if (! err)
2622     ret_err = stream_write_byte (response, SSH_RESPONSE_SUCCESS);
2623   else
2624     ret_err = stream_write_byte (response, SSH_RESPONSE_FAILURE);
2625
2626   return ret_err;
2627 }
2628
2629 \f
2630
2631 /* Return the request specification for the request identified by TYPE
2632    or NULL in case the requested request specification could not be
2633    found.  */
2634 static ssh_request_spec_t *
2635 request_spec_lookup (int type)
2636 {
2637   ssh_request_spec_t *spec;
2638   unsigned int i;
2639
2640   for (i = 0; i < DIM (request_specs); i++)
2641     if (request_specs[i].type == type)
2642       break;
2643   if (i == DIM (request_specs))
2644     {
2645       if (opt.verbose)
2646         log_info ("ssh request %u is not supported\n", type);
2647       spec = NULL;
2648     }
2649   else
2650     spec = request_specs + i;
2651
2652   return spec;
2653 }
2654
2655 /* Process a single request.  The request is read from and the
2656    response is written to STREAM_SOCK.  Uses CTRL as context.  Returns
2657    zero in case of success, non zero in case of failure.  */
2658 static int
2659 ssh_request_process (ctrl_t ctrl, estream_t stream_sock)
2660 {
2661   ssh_request_spec_t *spec;
2662   estream_t response;
2663   estream_t request;
2664   unsigned char request_type;
2665   gpg_error_t err;
2666   int send_err;
2667   int ret;
2668   unsigned char *request_data;
2669   u32 request_data_size;
2670   u32 response_size;
2671
2672   request_data = NULL;
2673   response = NULL;
2674   request = NULL;
2675   send_err = 0;
2676
2677   /* Create memory streams for request/response data.  The entire
2678      request will be stored in secure memory, since it might contain
2679      secret key material.  The response does not have to be stored in
2680      secure memory, since we never give out secret keys. 
2681
2682      Note: we only have little secure memory, but there is NO
2683      possibility of DoS here; only trusted clients are allowed to
2684      connect to the agent.  What could happen is that the agent
2685      returns out-of-secure-memory errors on requests in case the
2686      agent's owner floods his own agent with many large messages.
2687      -moritz */
2688
2689   /* Retrieve request.  */
2690   err = stream_read_string (stream_sock, 1, &request_data, &request_data_size);
2691   if (err)
2692     goto out;
2693
2694   if (opt.verbose > 1)
2695     log_info ("received ssh request of length %u\n",
2696               (unsigned int)request_data_size);
2697
2698   if (! request_data_size)
2699     {
2700       send_err = 1;
2701       goto out;
2702       /* Broken request; FIXME.  */
2703     }
2704
2705   request_type = request_data[0];
2706   spec = request_spec_lookup (request_type);
2707   if (! spec)
2708     {
2709       send_err = 1;
2710       goto out;
2711       /* Unknown request; FIXME.  */
2712     }
2713
2714   if (spec->secret_input)
2715     request = es_mopen (NULL, 0, 0, 1, realloc_secure, gcry_free, "r+");
2716   else
2717     request = es_mopen (NULL, 0, 0, 1, gcry_realloc, gcry_free, "r+");
2718   if (! request)
2719     {
2720       err = gpg_error_from_syserror ();
2721       goto out;
2722     }
2723   ret = es_setvbuf (request, NULL, _IONBF, 0);
2724   if (ret)
2725     {
2726       err = gpg_error_from_syserror ();
2727       goto out;
2728     }
2729   err = stream_write_data (request, request_data + 1, request_data_size - 1);
2730   if (err)
2731     goto out;
2732   es_rewind (request);
2733
2734   response = es_mopen (NULL, 0, 0, 1, NULL, NULL, "r+");
2735   if (! response)
2736     {
2737       err = gpg_error_from_syserror ();
2738       goto out;
2739     }
2740
2741   if (opt.verbose)
2742     log_info ("ssh request handler for %s (%u) started\n",
2743                spec->identifier, spec->type);
2744
2745   err = (*spec->handler) (ctrl, request, response);
2746
2747   if (opt.verbose)
2748     {
2749       if (err)
2750         log_info ("ssh request handler for %s (%u) failed: %s\n",
2751                   spec->identifier, spec->type, gpg_strerror (err));
2752       else
2753         log_info ("ssh request handler for %s (%u) ready\n",
2754                   spec->identifier, spec->type);
2755     }
2756
2757   if (err)
2758     {
2759       send_err = 1;
2760       goto out;
2761     }
2762
2763   response_size = es_ftell (response);
2764   if (opt.verbose > 1)
2765     log_info ("sending ssh response of length %u\n",
2766               (unsigned int)response_size);
2767
2768   err = es_fseek (response, 0, SEEK_SET);
2769   if (err)
2770     {
2771       send_err = 1;
2772       goto out;
2773     }
2774
2775   err = stream_write_uint32 (stream_sock, response_size);
2776   if (err)
2777     {
2778       send_err = 1;
2779       goto out;
2780     }
2781
2782   err = stream_copy (stream_sock, response);
2783   if (err)
2784     goto out;
2785
2786   err = es_fflush (stream_sock);
2787   if (err)
2788     goto out;
2789
2790  out:
2791
2792   if (err && es_feof (stream_sock))
2793     log_error ("error occured while processing request: %s\n",
2794                gpg_strerror (err));
2795
2796   if (send_err)
2797     {
2798       if (opt.verbose > 1)
2799         log_info ("sending ssh error response\n");
2800       err = stream_write_uint32 (stream_sock, 1);
2801       if (err)
2802         goto leave;
2803       err = stream_write_byte (stream_sock, SSH_RESPONSE_FAILURE);
2804       if (err)
2805         goto leave;
2806     }
2807
2808  leave:
2809
2810   if (request)
2811     es_fclose (request);
2812   if (response)
2813     es_fclose (response);
2814   xfree (request_data);         /* FIXME?  */
2815
2816   return !!err;
2817 }
2818
2819 /* Start serving client on SOCK_CLIENT.  */
2820 void
2821 start_command_handler_ssh (ctrl_t ctrl, int sock_client)
2822 {
2823   estream_t stream_sock;
2824   gpg_error_t err;
2825   int ret;
2826
2827   /* Setup control structure.  */
2828   ctrl->connection_fd = sock_client;
2829
2830   /* Because the ssh protocol does not send us information about the
2831      the current TTY setting, we resort here to use those from startup
2832      or those explictly set.  */
2833   if (!ctrl->display && opt.startup_display)
2834     ctrl->display = strdup (opt.startup_display);
2835   if (!ctrl->ttyname && opt.startup_ttyname)
2836     ctrl->ttyname = strdup (opt.startup_ttyname);
2837   if (!ctrl->ttytype && opt.startup_ttytype)
2838     ctrl->ttytype = strdup (opt.startup_ttytype);
2839   if (!ctrl->lc_ctype && opt.startup_lc_ctype)
2840     ctrl->lc_ctype = strdup (opt.startup_lc_ctype);
2841   if (!ctrl->lc_messages && opt.startup_lc_messages)
2842     ctrl->lc_messages = strdup (opt.startup_lc_messages);
2843
2844
2845   /* Create stream from socket.  */
2846   stream_sock = es_fdopen (sock_client, "r+");
2847   if (!stream_sock)
2848     {
2849       err = gpg_error_from_syserror ();
2850       log_error (_("failed to create stream from socket: %s\n"),
2851                  gpg_strerror (err));
2852       goto out;
2853     }
2854   /* We have to disable the estream buffering, because the estream
2855      core doesn't know about secure memory.  */
2856   ret = es_setvbuf (stream_sock, NULL, _IONBF, 0);
2857   if (ret)
2858     {
2859       err = gpg_error_from_syserror ();
2860       log_error ("failed to disable buffering "
2861                  "on socket stream: %s\n", gpg_strerror (err));
2862       goto out;
2863     }
2864
2865   /* Main processing loop. */
2866   while ( !ssh_request_process (ctrl, stream_sock) )
2867     {
2868       /* Check wether we have reached EOF before trying to read
2869          another request.  */
2870       int c;
2871
2872       c = es_fgetc (stream_sock);
2873       if (c == EOF)
2874         break;
2875       es_ungetc (c, stream_sock);
2876     }
2877
2878   /* Reset the SCD in case it has been used. */
2879   agent_reset_scd (ctrl);
2880
2881
2882  out:
2883   if (stream_sock)
2884     es_fclose (stream_sock);
2885 }