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