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