agent: Replace es_mopen by es_fopenmem for ssh.
[gnupg.git] / agent / command-ssh.c
1 /* command-ssh.c - gpg-agent's ssh-agent emulation layer
2  * Copyright (C) 2004, 2005, 2006, 2009, 2012 Free Software Foundation, Inc.
3  * Copyright (C) 2013, 2014 Werner Koch
4  *
5  * This file is part of GnuPG.
6  *
7  * GnuPG is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 3 of the License, or
10  * (at your option) any later version.
11  *
12  * GnuPG is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, see <http://www.gnu.org/licenses/>.
19  */
20
21 /* Only v2 of the ssh-agent protocol is implemented.  Relevant RFCs
22    are:
23
24    RFC-4250 - Protocol Assigned Numbers
25    RFC-4251 - Protocol Architecture
26    RFC-4252 - Authentication Protocol
27    RFC-4253 - Transport Layer Protocol
28    RFC-5656 - ECC support
29
30    The protocol for the agent is defined in OpenSSH's PROTOCL.agent
31    file.
32   */
33
34 #include <config.h>
35
36 #include <stdio.h>
37 #include <stdlib.h>
38 #include <string.h>
39 #include <errno.h>
40 #include <sys/types.h>
41 #include <sys/stat.h>
42 #include <assert.h>
43
44 #include "agent.h"
45
46 #include "i18n.h"
47 #include "../common/ssh-utils.h"
48
49
50 \f
51
52 /* Request types. */
53 #define SSH_REQUEST_REQUEST_IDENTITIES    11
54 #define SSH_REQUEST_SIGN_REQUEST          13
55 #define SSH_REQUEST_ADD_IDENTITY          17
56 #define SSH_REQUEST_REMOVE_IDENTITY       18
57 #define SSH_REQUEST_REMOVE_ALL_IDENTITIES 19
58 #define SSH_REQUEST_LOCK                  22
59 #define SSH_REQUEST_UNLOCK                23
60 #define SSH_REQUEST_ADD_ID_CONSTRAINED    25
61
62 /* Options. */
63 #define SSH_OPT_CONSTRAIN_LIFETIME         1
64 #define SSH_OPT_CONSTRAIN_CONFIRM          2
65
66 /* Response types. */
67 #define SSH_RESPONSE_SUCCESS               6
68 #define SSH_RESPONSE_FAILURE               5
69 #define SSH_RESPONSE_IDENTITIES_ANSWER    12
70 #define SSH_RESPONSE_SIGN_RESPONSE        14
71
72 /* Other constants.  */
73 #define SSH_DSA_SIGNATURE_PADDING 20
74 #define SSH_DSA_SIGNATURE_ELEMS    2
75 #define SPEC_FLAG_USE_PKCS1V2 (1 << 0)
76 #define SPEC_FLAG_IS_ECDSA    (1 << 1)
77 #define SPEC_FLAG_IS_EdDSA    (1 << 2)  /*(lowercase 'd' on purpose.)*/
78
79 /* The name of the control file.  */
80 #define SSH_CONTROL_FILE_NAME "sshcontrol"
81
82 /* The blurb we put into the header of a newly created control file.  */
83 static const char sshcontrolblurb[] =
84 "# List of allowed ssh keys.  Only keys present in this file are used\n"
85 "# in the SSH protocol.  The ssh-add tool may add new entries to this\n"
86 "# file to enable them; you may also add them manually.  Comment\n"
87 "# lines, like this one, as well as empty lines are ignored.  Lines do\n"
88 "# have a certain length limit but this is not serious limitation as\n"
89 "# the format of the entries is fixed and checked by gpg-agent. A\n"
90 "# non-comment line starts with optional white spaces, followed by the\n"
91 "# keygrip of the key given as 40 hex digits, optionally followed by a\n"
92 "# caching TTL in seconds, and another optional field for arbitrary\n"
93 "# flags.   Prepend the keygrip with an '!' mark to disable it.\n"
94 "\n";
95
96
97 /* Macros.  */
98
99 /* Return a new uint32 with b0 being the most significant byte and b3
100    being the least significant byte.  */
101 #define uint32_construct(b0, b1, b2, b3) \
102   ((b0 << 24) | (b1 << 16) | (b2 << 8) | b3)
103
104 \f
105
106
107 /*
108  * Basic types.
109  */
110
111 /* Type for a request handler.  */
112 typedef gpg_error_t (*ssh_request_handler_t) (ctrl_t ctrl,
113                                               estream_t request,
114                                               estream_t response);
115
116
117 struct ssh_key_type_spec;
118 typedef struct ssh_key_type_spec ssh_key_type_spec_t;
119
120 /* Type, which is used for associating request handlers with the
121    appropriate request IDs.  */
122 typedef struct ssh_request_spec
123 {
124   unsigned char type;
125   ssh_request_handler_t handler;
126   const char *identifier;
127   unsigned int secret_input;
128 } ssh_request_spec_t;
129
130 /* Type for "key modifier functions", which are necessary since
131    OpenSSH and GnuPG treat key material slightly different.  A key
132    modifier is called right after a new key identity has been received
133    in order to "sanitize" the material.  */
134 typedef gpg_error_t (*ssh_key_modifier_t) (const char *elems,
135                                            gcry_mpi_t *mpis);
136
137 /* The encoding of a generated signature is dependent on the
138    algorithm; therefore algorithm specific signature encoding
139    functions are necessary.  */
140 typedef gpg_error_t (*ssh_signature_encoder_t) (ssh_key_type_spec_t *spec,
141                                                 estream_t signature_blob,
142                                                 gcry_sexp_t sig);
143
144 /* Type, which is used for boundling all the algorithm specific
145    information together in a single object.  */
146 struct ssh_key_type_spec
147 {
148   /* Algorithm identifier as used by OpenSSH.  */
149   const char *ssh_identifier;
150
151   /* Human readable name of the algorithm.  */
152   const char *name;
153
154   /* Algorithm identifier as used by GnuPG.  */
155   const char *identifier;
156
157   /* List of MPI names for secret keys; order matches the one of the
158      agent protocol.  */
159   const char *elems_key_secret;
160
161   /* List of MPI names for public keys; order matches the one of the
162      agent protocol.  */
163   const char *elems_key_public;
164
165   /* List of MPI names for signature data.  */
166   const char *elems_signature;
167
168   /* List of MPI names for secret keys; order matches the one, which
169      is required by gpg-agent's key access layer.  */
170   const char *elems_sexp_order;
171
172   /* Key modifier function.  Key modifier functions are necessary in
173      order to fix any inconsistencies between the representation of
174      keys on the SSH and on the GnuPG side.  */
175   ssh_key_modifier_t key_modifier;
176
177   /* Signature encoder function.  Signature encoder functions are
178      necessary since the encoding of signatures depends on the used
179      algorithm.  */
180   ssh_signature_encoder_t signature_encoder;
181
182   /* The name of the ECC curve or NULL.  */
183   const char *curve_name;
184
185   /* The hash algorithm to be used with this key.  0 for using the
186      default.  */
187   int hash_algo;
188
189   /* Misc flags.  */
190   unsigned int flags;
191 };
192
193
194 /* Definition of an object to access the sshcontrol file.  */
195 struct ssh_control_file_s
196 {
197   char *fname;  /* Name of the file.  */
198   FILE *fp;     /* This is never NULL. */
199   int lnr;      /* The current line number.  */
200   struct {
201     int valid;           /* True if the data of this structure is valid.  */
202     int disabled;        /* The item is disabled.  */
203     int ttl;             /* The TTL of the item.   */
204     int confirm;         /* The confirm flag is set.  */
205     char hexgrip[40+1];  /* The hexgrip of the item (uppercase).  */
206   } item;
207 };
208
209
210 /* Prototypes.  */
211 static gpg_error_t ssh_handler_request_identities (ctrl_t ctrl,
212                                                    estream_t request,
213                                                    estream_t response);
214 static gpg_error_t ssh_handler_sign_request (ctrl_t ctrl,
215                                              estream_t request,
216                                              estream_t response);
217 static gpg_error_t ssh_handler_add_identity (ctrl_t ctrl,
218                                              estream_t request,
219                                              estream_t response);
220 static gpg_error_t ssh_handler_remove_identity (ctrl_t ctrl,
221                                                 estream_t request,
222                                                 estream_t response);
223 static gpg_error_t ssh_handler_remove_all_identities (ctrl_t ctrl,
224                                                       estream_t request,
225                                                       estream_t response);
226 static gpg_error_t ssh_handler_lock (ctrl_t ctrl,
227                                      estream_t request,
228                                      estream_t response);
229 static gpg_error_t ssh_handler_unlock (ctrl_t ctrl,
230                                        estream_t request,
231                                        estream_t response);
232
233 static gpg_error_t ssh_key_modifier_rsa (const char *elems, gcry_mpi_t *mpis);
234 static gpg_error_t ssh_signature_encoder_rsa (ssh_key_type_spec_t *spec,
235                                               estream_t signature_blob,
236                                               gcry_sexp_t signature);
237 static gpg_error_t ssh_signature_encoder_dsa (ssh_key_type_spec_t *spec,
238                                               estream_t signature_blob,
239                                               gcry_sexp_t signature);
240 static gpg_error_t ssh_signature_encoder_ecdsa (ssh_key_type_spec_t *spec,
241                                                 estream_t signature_blob,
242                                                 gcry_sexp_t signature);
243 static gpg_error_t ssh_signature_encoder_eddsa (ssh_key_type_spec_t *spec,
244                                                 estream_t signature_blob,
245                                                 gcry_sexp_t signature);
246 static gpg_error_t ssh_key_extract_comment (gcry_sexp_t key, char **comment);
247
248
249
250 /* Global variables.  */
251
252
253 /* Associating request types with the corresponding request
254    handlers.  */
255
256 static ssh_request_spec_t request_specs[] =
257   {
258 #define REQUEST_SPEC_DEFINE(id, name, secret_input) \
259   { SSH_REQUEST_##id, ssh_handler_##name, #name, secret_input }
260
261     REQUEST_SPEC_DEFINE (REQUEST_IDENTITIES,    request_identities,    1),
262     REQUEST_SPEC_DEFINE (SIGN_REQUEST,          sign_request,          0),
263     REQUEST_SPEC_DEFINE (ADD_IDENTITY,          add_identity,          1),
264     REQUEST_SPEC_DEFINE (ADD_ID_CONSTRAINED,    add_identity,          1),
265     REQUEST_SPEC_DEFINE (REMOVE_IDENTITY,       remove_identity,       0),
266     REQUEST_SPEC_DEFINE (REMOVE_ALL_IDENTITIES, remove_all_identities, 0),
267     REQUEST_SPEC_DEFINE (LOCK,                  lock,                  0),
268     REQUEST_SPEC_DEFINE (UNLOCK,                unlock,                0)
269 #undef REQUEST_SPEC_DEFINE
270   };
271
272
273 /* Table holding key type specifications.  */
274 static ssh_key_type_spec_t ssh_key_types[] =
275   {
276     {
277       "ssh-ed25519", "Ed25519", "ecc", "qd",  "q", "rs", "qd",
278       NULL,                 ssh_signature_encoder_eddsa,
279       "Ed25519", 0,               SPEC_FLAG_IS_EdDSA
280     },
281     {
282       "ssh-rsa", "RSA", "rsa", "nedupq", "en",   "s",  "nedpqu",
283       ssh_key_modifier_rsa, ssh_signature_encoder_rsa,
284       NULL, 0,                    SPEC_FLAG_USE_PKCS1V2
285     },
286     {
287       "ssh-dss", "DSA", "dsa", "pqgyx",  "pqgy", "rs", "pqgyx",
288       NULL,                 ssh_signature_encoder_dsa,
289       NULL, 0, 0
290     },
291     {
292       "ecdsa-sha2-nistp256", "ECDSA", "ecdsa", "qd",  "q", "rs", "qd",
293       NULL,                 ssh_signature_encoder_ecdsa,
294       "nistp256", GCRY_MD_SHA256, SPEC_FLAG_IS_ECDSA
295     },
296     {
297       "ecdsa-sha2-nistp384", "ECDSA", "ecdsa", "qd",  "q", "rs", "qd",
298       NULL,                 ssh_signature_encoder_ecdsa,
299       "nistp384", GCRY_MD_SHA384, SPEC_FLAG_IS_ECDSA
300     },
301     {
302       "ecdsa-sha2-nistp521", "ECDSA", "ecdsa", "qd",  "q", "rs", "qd",
303       NULL,                 ssh_signature_encoder_ecdsa,
304       "nistp521", GCRY_MD_SHA512, SPEC_FLAG_IS_ECDSA
305     }
306   };
307
308 \f
309
310
311
312 /*
313    General utility functions.
314  */
315
316 /* A secure realloc, i.e. it makes sure to allocate secure memory if A
317    is NULL.  This is required because the standard gcry_realloc does
318    not know whether to allocate secure or normal if NULL is passed as
319    existing buffer.  */
320 static void *
321 realloc_secure (void *a, size_t n)
322 {
323   void *p;
324
325   if (a)
326     p = gcry_realloc (a, n);
327   else
328     p = gcry_malloc_secure (n);
329
330   return p;
331 }
332
333
334 /* Create and return a new C-string from DATA/DATA_N (i.e.: add
335    NUL-termination); return NULL on OOM.  */
336 static char *
337 make_cstring (const char *data, size_t data_n)
338 {
339   char *s;
340
341   s = xtrymalloc (data_n + 1);
342   if (s)
343     {
344       memcpy (s, data, data_n);
345       s[data_n] = 0;
346     }
347
348   return s;
349 }
350
351 /* Lookup the ssh-identifier for the ECC curve CURVE_NAME.  Returns
352    NULL if not found.  */
353 static const char *
354 ssh_identifier_from_curve_name (const char *curve_name)
355 {
356   int i;
357
358   for (i = 0; i < DIM (ssh_key_types); i++)
359     if (ssh_key_types[i].curve_name
360         && !strcmp (ssh_key_types[i].curve_name, curve_name))
361       return ssh_key_types[i].ssh_identifier;
362
363   return NULL;
364 }
365
366
367 /*
368    Primitive I/O functions.
369  */
370
371
372 /* Read a byte from STREAM, store it in B.  */
373 static gpg_error_t
374 stream_read_byte (estream_t stream, unsigned char *b)
375 {
376   gpg_error_t err;
377   int ret;
378
379   ret = es_fgetc (stream);
380   if (ret == EOF)
381     {
382       if (es_ferror (stream))
383         err = gpg_error_from_syserror ();
384       else
385         err = gpg_error (GPG_ERR_EOF);
386       *b = 0;
387     }
388   else
389     {
390       *b = ret & 0xFF;
391       err = 0;
392     }
393
394   return err;
395 }
396
397 /* Write the byte contained in B to STREAM.  */
398 static gpg_error_t
399 stream_write_byte (estream_t stream, unsigned char b)
400 {
401   gpg_error_t err;
402   int ret;
403
404   ret = es_fputc (b, stream);
405   if (ret == EOF)
406     err = gpg_error_from_syserror ();
407   else
408     err = 0;
409
410   return err;
411 }
412
413
414 /* Read a uint32 from STREAM, store it in UINT32.  */
415 static gpg_error_t
416 stream_read_uint32 (estream_t stream, u32 *uint32)
417 {
418   unsigned char buffer[4];
419   size_t bytes_read;
420   gpg_error_t err;
421   int ret;
422
423   ret = es_read (stream, buffer, sizeof (buffer), &bytes_read);
424   if (ret)
425     err = gpg_error_from_syserror ();
426   else
427     {
428       if (bytes_read != sizeof (buffer))
429         err = gpg_error (GPG_ERR_EOF);
430       else
431         {
432           u32 n;
433
434           n = uint32_construct (buffer[0], buffer[1], buffer[2], buffer[3]);
435           *uint32 = n;
436           err = 0;
437         }
438     }
439
440   return err;
441 }
442
443 /* Write the uint32 contained in UINT32 to STREAM.  */
444 static gpg_error_t
445 stream_write_uint32 (estream_t stream, u32 uint32)
446 {
447   unsigned char buffer[4];
448   gpg_error_t err;
449   int ret;
450
451   buffer[0] = uint32 >> 24;
452   buffer[1] = uint32 >> 16;
453   buffer[2] = uint32 >>  8;
454   buffer[3] = uint32 >>  0;
455
456   ret = es_write (stream, buffer, sizeof (buffer), NULL);
457   if (ret)
458     err = gpg_error_from_syserror ();
459   else
460     err = 0;
461
462   return err;
463 }
464
465 /* Read SIZE bytes from STREAM into BUFFER.  */
466 static gpg_error_t
467 stream_read_data (estream_t stream, unsigned char *buffer, size_t size)
468 {
469   gpg_error_t err;
470   size_t bytes_read;
471   int ret;
472
473   ret = es_read (stream, buffer, size, &bytes_read);
474   if (ret)
475     err = gpg_error_from_syserror ();
476   else
477     {
478       if (bytes_read != size)
479         err = gpg_error (GPG_ERR_EOF);
480       else
481         err = 0;
482     }
483
484   return err;
485 }
486
487 /* Skip over SIZE bytes from STREAM.  */
488 static gpg_error_t
489 stream_read_skip (estream_t stream, size_t size)
490 {
491   char buffer[128];
492   size_t bytes_to_read, bytes_read;
493   int ret;
494
495   do
496     {
497       bytes_to_read = size;
498       if (bytes_to_read > sizeof buffer)
499         bytes_to_read = sizeof buffer;
500
501       ret = es_read (stream, buffer, bytes_to_read, &bytes_read);
502       if (ret)
503         return gpg_error_from_syserror ();
504       else if (bytes_read != bytes_to_read)
505         return gpg_error (GPG_ERR_EOF);
506       else
507         size -= bytes_to_read;
508     }
509   while (size);
510
511   return 0;
512 }
513
514
515 /* Write SIZE bytes from BUFFER to STREAM.  */
516 static gpg_error_t
517 stream_write_data (estream_t stream, const unsigned char *buffer, size_t size)
518 {
519   gpg_error_t err;
520   int ret;
521
522   ret = es_write (stream, buffer, size, NULL);
523   if (ret)
524     err = gpg_error_from_syserror ();
525   else
526     err = 0;
527
528   return err;
529 }
530
531 /* Read a binary string from STREAM into STRING, store size of string
532    in STRING_SIZE.  Append a hidden nul so that the result may
533    directly be used as a C string.  Depending on SECURE use secure
534    memory for STRING.  */
535 static gpg_error_t
536 stream_read_string (estream_t stream, unsigned int secure,
537                     unsigned char **string, u32 *string_size)
538 {
539   gpg_error_t err;
540   unsigned char *buffer = NULL;
541   u32 length = 0;
542
543   if (string_size)
544     *string_size = 0;
545
546   /* Read string length.  */
547   err = stream_read_uint32 (stream, &length);
548   if (err)
549     goto out;
550
551   /* Allocate space.  */
552   if (secure)
553     buffer = xtrymalloc_secure (length + 1);
554   else
555     buffer = xtrymalloc (length + 1);
556   if (! buffer)
557     {
558       err = gpg_error_from_syserror ();
559       goto out;
560     }
561
562   /* Read data.  */
563   err = stream_read_data (stream, buffer, length);
564   if (err)
565     goto out;
566
567   /* Finalize string object.  */
568   buffer[length] = 0;
569   *string = buffer;
570   if (string_size)
571     *string_size = length;
572
573  out:
574
575   if (err)
576     xfree (buffer);
577
578   return err;
579 }
580
581
582 /* Read a binary string from STREAM and store it as an opaque MPI at
583    R_MPI.  Depending on SECURE use secure memory.  If the string is
584    too large for key material return an error.  */
585 static gpg_error_t
586 stream_read_blob (estream_t stream, unsigned int secure, gcry_mpi_t *r_mpi)
587 {
588   gpg_error_t err;
589   unsigned char *buffer = NULL;
590   u32 length = 0;
591
592   *r_mpi = NULL;
593
594   /* Read string length.  */
595   err = stream_read_uint32 (stream, &length);
596   if (err)
597     goto leave;
598
599   /* To avoid excessive use of secure memory we check that an MPI is
600      not too large. */
601   if (length > (4096/8) + 8)
602     {
603       log_error (_("ssh keys greater than %d bits are not supported\n"), 4096);
604       err = GPG_ERR_TOO_LARGE;
605       goto leave;
606     }
607
608   /* Allocate space.  */
609   if (secure)
610     buffer = xtrymalloc_secure (length? length:1);
611   else
612     buffer = xtrymalloc (length?length:1);
613   if (!buffer)
614     {
615       err = gpg_error_from_syserror ();
616       goto leave;
617     }
618
619   /* Read data.  */
620   err = stream_read_data (stream, buffer, length);
621   if (err)
622     goto leave;
623
624   *r_mpi = gcry_mpi_set_opaque (NULL, buffer, 8*length);
625   buffer = NULL;
626
627  leave:
628   xfree (buffer);
629   return err;
630 }
631
632
633 /* Read a C-string from STREAM, store copy in STRING.  */
634 static gpg_error_t
635 stream_read_cstring (estream_t stream, char **string)
636 {
637   gpg_error_t err;
638   unsigned char *buffer;
639
640   err = stream_read_string (stream, 0, &buffer, NULL);
641   if (!err)
642     *string = (char *)buffer;
643   return err;
644 }
645
646
647 /* Write a binary string from STRING of size STRING_N to STREAM.  */
648 static gpg_error_t
649 stream_write_string (estream_t stream,
650                      const unsigned char *string, u32 string_n)
651 {
652   gpg_error_t err;
653
654   err = stream_write_uint32 (stream, string_n);
655   if (err)
656     goto out;
657
658   err = stream_write_data (stream, string, string_n);
659
660  out:
661
662   return err;
663 }
664
665 /* Write a C-string from STRING to STREAM.  */
666 static gpg_error_t
667 stream_write_cstring (estream_t stream, const char *string)
668 {
669   gpg_error_t err;
670
671   err = stream_write_string (stream,
672                              (const unsigned char *) string, strlen (string));
673
674   return err;
675 }
676
677 /* Read an MPI from STREAM, store it in MPINT.  Depending on SECURE
678    use secure memory.  */
679 static gpg_error_t
680 stream_read_mpi (estream_t stream, unsigned int secure, gcry_mpi_t *mpint)
681 {
682   unsigned char *mpi_data;
683   u32 mpi_data_size;
684   gpg_error_t err;
685   gcry_mpi_t mpi;
686
687   mpi_data = NULL;
688
689   err = stream_read_string (stream, secure, &mpi_data, &mpi_data_size);
690   if (err)
691     goto out;
692
693   /* To avoid excessive use of secure memory we check that an MPI is
694      not too large. */
695   if (mpi_data_size > 520)
696     {
697       log_error (_("ssh keys greater than %d bits are not supported\n"), 4096);
698       err = GPG_ERR_TOO_LARGE;
699       goto out;
700     }
701
702   err = gcry_mpi_scan (&mpi, GCRYMPI_FMT_STD, mpi_data, mpi_data_size, NULL);
703   if (err)
704     goto out;
705
706   *mpint = mpi;
707
708  out:
709
710   xfree (mpi_data);
711
712   return err;
713 }
714
715 /* Write the MPI contained in MPINT to STREAM.  */
716 static gpg_error_t
717 stream_write_mpi (estream_t stream, gcry_mpi_t mpint)
718 {
719   unsigned char *mpi_buffer;
720   size_t mpi_buffer_n;
721   gpg_error_t err;
722
723   mpi_buffer = NULL;
724
725   err = gcry_mpi_aprint (GCRYMPI_FMT_STD, &mpi_buffer, &mpi_buffer_n, mpint);
726   if (err)
727     goto out;
728
729   err = stream_write_string (stream, mpi_buffer, mpi_buffer_n);
730
731  out:
732
733   xfree (mpi_buffer);
734
735   return err;
736 }
737
738
739 /* Copy data from SRC to DST until EOF is reached.  */
740 static gpg_error_t
741 stream_copy (estream_t dst, estream_t src)
742 {
743   char buffer[BUFSIZ];
744   size_t bytes_read;
745   gpg_error_t err;
746   int ret;
747
748   err = 0;
749   while (1)
750     {
751       ret = es_read (src, buffer, sizeof (buffer), &bytes_read);
752       if (ret || (! bytes_read))
753         {
754           if (ret)
755             err = gpg_error_from_syserror ();
756           break;
757         }
758       ret = es_write (dst, buffer, bytes_read, NULL);
759       if (ret)
760         {
761           err = gpg_error_from_syserror ();
762           break;
763         }
764     }
765
766   return err;
767 }
768
769
770 /* Read the content of the file specified by FILENAME into a newly
771    create buffer, which is to be stored in BUFFER; store length of
772    buffer in BUFFER_N.  */
773 static gpg_error_t
774 file_to_buffer (const char *filename, unsigned char **buffer, size_t *buffer_n)
775 {
776   unsigned char *buffer_new;
777   struct stat statbuf;
778   estream_t stream;
779   gpg_error_t err;
780   int ret;
781
782   *buffer = NULL;
783   *buffer_n = 0;
784
785   buffer_new = NULL;
786   err = 0;
787
788   stream = es_fopen (filename, "rb");
789   if (! stream)
790     {
791       err = gpg_error_from_syserror ();
792       goto out;
793     }
794
795   ret = fstat (es_fileno (stream), &statbuf);
796   if (ret)
797     {
798       err = gpg_error_from_syserror ();
799       goto out;
800     }
801
802   buffer_new = xtrymalloc (statbuf.st_size);
803   if (! buffer_new)
804     {
805       err = gpg_error_from_syserror ();
806       goto out;
807     }
808
809   err = stream_read_data (stream, buffer_new, statbuf.st_size);
810   if (err)
811     goto out;
812
813   *buffer = buffer_new;
814   *buffer_n = statbuf.st_size;
815
816  out:
817
818   if (stream)
819     es_fclose (stream);
820
821   if (err)
822     xfree (buffer_new);
823
824   return err;
825 }
826
827
828
829 \f
830 /* Open the ssh control file and create it if not available.  With
831    APPEND passed as true the file will be opened in append mode,
832    otherwise in read only mode.  On success 0 is returned and a new
833    control file object stored at R_CF.  On error an error code is
834    returned and NULL is stored at R_CF.  */
835 static gpg_error_t
836 open_control_file (ssh_control_file_t *r_cf, int append)
837 {
838   gpg_error_t err;
839   ssh_control_file_t cf;
840
841   cf = xtrycalloc (1, sizeof *cf);
842   if (!cf)
843     {
844       err = gpg_error_from_syserror ();
845       goto leave;
846     }
847
848   /* Note: As soon as we start to use non blocking functions here
849      (i.e. where Pth might switch threads) we need to employ a
850      mutex.  */
851   cf->fname = make_filename_try (opt.homedir, SSH_CONTROL_FILE_NAME, NULL);
852   if (!cf->fname)
853     {
854       err = gpg_error_from_syserror ();
855       goto leave;
856     }
857   /* FIXME: With "a+" we are not able to check whether this will
858      be created and thus the blurb needs to be written first.  */
859   cf->fp = fopen (cf->fname, append? "a+":"r");
860   if (!cf->fp && errno == ENOENT)
861     {
862       estream_t stream = es_fopen (cf->fname, "wx,mode=-rw-r");
863       if (!stream)
864         {
865           err = gpg_error_from_syserror ();
866           log_error (_("can't create '%s': %s\n"),
867                      cf->fname, gpg_strerror (err));
868           goto leave;
869         }
870       es_fputs (sshcontrolblurb, stream);
871       es_fclose (stream);
872       cf->fp = fopen (cf->fname, append? "a+":"r");
873     }
874
875   if (!cf->fp)
876     {
877       err = gpg_error_from_syserror ();
878       log_error (_("can't open '%s': %s\n"),
879                  cf->fname, gpg_strerror (err));
880       goto leave;
881     }
882
883   err = 0;
884
885  leave:
886   if (err && cf)
887     {
888       if (cf->fp)
889         fclose (cf->fp);
890       xfree (cf->fname);
891       xfree (cf);
892     }
893   else
894     *r_cf = cf;
895
896   return err;
897 }
898
899
900 static void
901 rewind_control_file (ssh_control_file_t cf)
902 {
903   fseek (cf->fp, 0, SEEK_SET);
904   cf->lnr = 0;
905   clearerr (cf->fp);
906 }
907
908
909 static void
910 close_control_file (ssh_control_file_t cf)
911 {
912   if (!cf)
913     return;
914   fclose (cf->fp);
915   xfree (cf->fname);
916   xfree (cf);
917 }
918
919
920
921 /* Read the next line from the control file and store the data in CF.
922    Returns 0 on success, GPG_ERR_EOF on EOF, or other error codes. */
923 static gpg_error_t
924 read_control_file_item (ssh_control_file_t cf)
925 {
926   int c, i, n;
927   char *p, *pend, line[256];
928   long ttl = 0;
929
930   cf->item.valid = 0;
931   clearerr (cf->fp);
932
933   do
934     {
935       if (!fgets (line, DIM(line)-1, cf->fp) )
936         {
937           if (feof (cf->fp))
938             return gpg_error (GPG_ERR_EOF);
939           return gpg_error_from_syserror ();
940         }
941       cf->lnr++;
942
943       if (!*line || line[strlen(line)-1] != '\n')
944         {
945           /* Eat until end of line */
946           while ( (c=getc (cf->fp)) != EOF && c != '\n')
947             ;
948           return gpg_error (*line? GPG_ERR_LINE_TOO_LONG
949                                  : GPG_ERR_INCOMPLETE_LINE);
950         }
951
952       /* Allow for empty lines and spaces */
953       for (p=line; spacep (p); p++)
954         ;
955     }
956   while (!*p || *p == '\n' || *p == '#');
957
958   cf->item.disabled = 0;
959   if (*p == '!')
960     {
961       cf->item.disabled = 1;
962       for (p++; spacep (p); p++)
963         ;
964     }
965
966   for (i=0; hexdigitp (p) && i < 40; p++, i++)
967     cf->item.hexgrip[i] = (*p >= 'a'? (*p & 0xdf): *p);
968   cf->item.hexgrip[i] = 0;
969   if (i != 40 || !(spacep (p) || *p == '\n'))
970     {
971       log_error ("%s:%d: invalid formatted line\n", cf->fname, cf->lnr);
972       return gpg_error (GPG_ERR_BAD_DATA);
973     }
974
975   ttl = strtol (p, &pend, 10);
976   p = pend;
977   if (!(spacep (p) || *p == '\n') || (int)ttl < -1)
978     {
979       log_error ("%s:%d: invalid TTL value; assuming 0\n", cf->fname, cf->lnr);
980       cf->item.ttl = 0;
981     }
982   cf->item.ttl = ttl;
983
984   /* Now check for key-value pairs of the form NAME[=VALUE]. */
985   cf->item.confirm = 0;
986   while (*p)
987     {
988       for (; spacep (p) && *p != '\n'; p++)
989         ;
990       if (!*p || *p == '\n')
991         break;
992       n = strcspn (p, "= \t\n");
993       if (p[n] == '=')
994         {
995           log_error ("%s:%d: assigning a value to a flag is not yet supported; "
996                      "flag ignored\n", cf->fname, cf->lnr);
997           p++;
998         }
999       else if (n == 7 && !memcmp (p, "confirm", 7))
1000         {
1001           cf->item.confirm = 1;
1002         }
1003       else
1004         log_error ("%s:%d: invalid flag '%.*s'; ignored\n",
1005                    cf->fname, cf->lnr, n, p);
1006       p += n;
1007     }
1008
1009   /* log_debug ("%s:%d: grip=%s ttl=%d%s%s\n", */
1010   /*            cf->fname, cf->lnr, */
1011   /*            cf->item.hexgrip, cf->item.ttl, */
1012   /*            cf->item.disabled? " disabled":"", */
1013   /*            cf->item.confirm? " confirm":""); */
1014
1015   cf->item.valid = 1;
1016   return 0; /* Okay: valid entry found.  */
1017 }
1018
1019
1020
1021 /* Search the control file CF from the beginning until a matching
1022    HEXGRIP is found; return success in this case and store true at
1023    DISABLED if the found key has been disabled.  If R_TTL is not NULL
1024    a specified TTL for that key is stored there.  If R_CONFIRM is not
1025    NULL it is set to 1 if the key has the confirm flag set. */
1026 static gpg_error_t
1027 search_control_file (ssh_control_file_t cf, const char *hexgrip,
1028                      int *r_disabled, int *r_ttl, int *r_confirm)
1029 {
1030   gpg_error_t err;
1031
1032   assert (strlen (hexgrip) == 40 );
1033
1034   *r_disabled = 0;
1035   if (r_ttl)
1036     *r_ttl = 0;
1037   if (r_confirm)
1038     *r_confirm = 0;
1039
1040   rewind_control_file (cf);
1041   while (!(err=read_control_file_item (cf)))
1042     {
1043       if (!cf->item.valid)
1044         continue; /* Should not happen.  */
1045       if (!strcmp (hexgrip, cf->item.hexgrip))
1046         break;
1047     }
1048   if (!err)
1049     {
1050       *r_disabled = cf->item.disabled;
1051       if (r_ttl)
1052         *r_ttl = cf->item.ttl;
1053       if (r_confirm)
1054         *r_confirm = cf->item.confirm;
1055     }
1056   return err;
1057 }
1058
1059
1060
1061 /* Add an entry to the control file to mark the key with the keygrip
1062    HEXGRIP as usable for SSH; i.e. it will be returned when ssh asks
1063    for it.  FMTFPR is the fingerprint string.  This function is in
1064    general used to add a key received through the ssh-add function.
1065    We can assume that the user wants to allow ssh using this key. */
1066 static gpg_error_t
1067 add_control_entry (ctrl_t ctrl, ssh_key_type_spec_t *spec,
1068                    const char *hexgrip, const char *fmtfpr,
1069                    int ttl, int confirm)
1070 {
1071   gpg_error_t err;
1072   ssh_control_file_t cf;
1073   int disabled;
1074
1075   (void)ctrl;
1076
1077   err = open_control_file (&cf, 1);
1078   if (err)
1079     return err;
1080
1081   err = search_control_file (cf, hexgrip, &disabled, NULL, NULL);
1082   if (err && gpg_err_code(err) == GPG_ERR_EOF)
1083     {
1084       struct tm *tp;
1085       time_t atime = time (NULL);
1086
1087       /* Not yet in the file - add it. Because the file has been
1088          opened in append mode, we simply need to write to it.  */
1089       tp = localtime (&atime);
1090       fprintf (cf->fp,
1091                ("# %s key added on: %04d-%02d-%02d %02d:%02d:%02d\n"
1092                 "# MD5 Fingerprint:  %s\n"
1093                 "%s %d%s\n"),
1094                spec->name,
1095                1900+tp->tm_year, tp->tm_mon+1, tp->tm_mday,
1096                tp->tm_hour, tp->tm_min, tp->tm_sec,
1097                fmtfpr, hexgrip, ttl, confirm? " confirm":"");
1098
1099     }
1100   close_control_file (cf);
1101   return 0;
1102 }
1103
1104
1105 /* Scan the sshcontrol file and return the TTL.  */
1106 static int
1107 ttl_from_sshcontrol (const char *hexgrip)
1108 {
1109   ssh_control_file_t cf;
1110   int disabled, ttl;
1111
1112   if (!hexgrip || strlen (hexgrip) != 40)
1113     return 0;  /* Wrong input: Use global default.  */
1114
1115   if (open_control_file (&cf, 0))
1116     return 0; /* Error: Use the global default TTL.  */
1117
1118   if (search_control_file (cf, hexgrip, &disabled, &ttl, NULL)
1119       || disabled)
1120     ttl = 0;  /* Use the global default if not found or disabled.  */
1121
1122   close_control_file (cf);
1123
1124   return ttl;
1125 }
1126
1127
1128 /* Scan the sshcontrol file and return the confirm flag.  */
1129 static int
1130 confirm_flag_from_sshcontrol (const char *hexgrip)
1131 {
1132   ssh_control_file_t cf;
1133   int disabled, confirm;
1134
1135   if (!hexgrip || strlen (hexgrip) != 40)
1136     return 1;  /* Wrong input: Better ask for confirmation.  */
1137
1138   if (open_control_file (&cf, 0))
1139     return 1; /* Error: Better ask for confirmation.  */
1140
1141   if (search_control_file (cf, hexgrip, &disabled, NULL, &confirm)
1142       || disabled)
1143     confirm = 0;  /* If not found or disabled, there is no reason to
1144                      ask for confirmation.  */
1145
1146   close_control_file (cf);
1147
1148   return confirm;
1149 }
1150
1151
1152 \f
1153
1154 /* Open the ssh control file for reading.  This is a public version of
1155    open_control_file.  The caller must use ssh_close_control_file to
1156    release the retruned handle.  */
1157 ssh_control_file_t
1158 ssh_open_control_file (void)
1159 {
1160   ssh_control_file_t cf;
1161
1162   /* Then look at all the registered and non-disabled keys. */
1163   if (open_control_file (&cf, 0))
1164     return NULL;
1165   return cf;
1166 }
1167
1168 /* Close an ssh control file handle.  This is the public version of
1169    close_control_file.  CF may be NULL.  */
1170 void
1171 ssh_close_control_file (ssh_control_file_t cf)
1172 {
1173   close_control_file (cf);
1174 }
1175
1176 /* Read the next item from the ssh control file.  The function returns
1177    0 if a item was read, GPG_ERR_EOF on eof or another error value.
1178    R_HEXGRIP shall either be null or a BUFFER of at least 41 byte.
1179    R_DISABLED, R_TTLm and R_CONFIRM return flags from the control
1180    file; they are only set on success. */
1181 gpg_error_t
1182 ssh_read_control_file (ssh_control_file_t cf,
1183                        char *r_hexgrip,
1184                        int *r_disabled, int *r_ttl, int *r_confirm)
1185 {
1186   gpg_error_t err;
1187
1188   do
1189     err = read_control_file_item (cf);
1190   while (!err && !cf->item.valid);
1191   if (!err)
1192     {
1193       if (r_hexgrip)
1194         strcpy (r_hexgrip, cf->item.hexgrip);
1195       if (r_disabled)
1196         *r_disabled = cf->item.disabled;
1197       if (r_ttl)
1198         *r_ttl = cf->item.ttl;
1199       if (r_confirm)
1200         *r_confirm = cf->item.confirm;
1201     }
1202   return err;
1203 }
1204
1205
1206 /* Search for a key with HEXGRIP in sshcontrol and return all
1207    info.  */
1208 gpg_error_t
1209 ssh_search_control_file (ssh_control_file_t cf,
1210                          const char *hexgrip,
1211                          int *r_disabled, int *r_ttl, int *r_confirm)
1212 {
1213   gpg_error_t err;
1214   int i;
1215   const char *s;
1216   char uphexgrip[41];
1217
1218   /* We need to make sure that HEXGRIP is all uppercase.  The easiest
1219      way to do this and also check its length is by copying to a
1220      second buffer. */
1221   for (i=0, s=hexgrip; i < 40; s++, i++)
1222     uphexgrip[i] = *s >= 'a'? (*s & 0xdf): *s;
1223   uphexgrip[i] = 0;
1224   if (i != 40)
1225     err = gpg_error (GPG_ERR_INV_LENGTH);
1226   else
1227     err = search_control_file (cf, uphexgrip, r_disabled, r_ttl, r_confirm);
1228   if (gpg_err_code (err) == GPG_ERR_EOF)
1229     err = gpg_error (GPG_ERR_NOT_FOUND);
1230   return err;
1231 }
1232
1233
1234 \f
1235
1236 /*
1237
1238   MPI lists.
1239
1240  */
1241
1242 /* Free the list of MPIs MPI_LIST.  */
1243 static void
1244 mpint_list_free (gcry_mpi_t *mpi_list)
1245 {
1246   if (mpi_list)
1247     {
1248       unsigned int i;
1249
1250       for (i = 0; mpi_list[i]; i++)
1251         gcry_mpi_release (mpi_list[i]);
1252       xfree (mpi_list);
1253     }
1254 }
1255
1256 /* Receive key material MPIs from STREAM according to KEY_SPEC;
1257    depending on SECRET expect a public key or secret key.  The newly
1258    allocated list of MPIs is stored in MPI_LIST.  Returns usual error
1259    code.  */
1260 static gpg_error_t
1261 ssh_receive_mpint_list (estream_t stream, int secret,
1262                         ssh_key_type_spec_t key_spec, gcry_mpi_t **mpi_list)
1263 {
1264   const char *elems_public;
1265   unsigned int elems_n;
1266   const char *elems;
1267   int elem_is_secret;
1268   gcry_mpi_t *mpis;
1269   gpg_error_t err;
1270   unsigned int i;
1271
1272   mpis = NULL;
1273   err = 0;
1274
1275   if (secret)
1276     elems = key_spec.elems_key_secret;
1277   else
1278     elems = key_spec.elems_key_public;
1279   elems_n = strlen (elems);
1280
1281   elems_public = key_spec.elems_key_public;
1282
1283   mpis = xtrycalloc (elems_n + 1, sizeof *mpis );
1284   if (!mpis)
1285     {
1286       err = gpg_error_from_syserror ();
1287       goto out;
1288     }
1289
1290   elem_is_secret = 0;
1291   for (i = 0; i < elems_n; i++)
1292     {
1293       if (secret)
1294         elem_is_secret = ! strchr (elems_public, elems[i]);
1295       err = stream_read_mpi (stream, elem_is_secret, &mpis[i]);
1296       if (err)
1297         break;
1298     }
1299   if (err)
1300     goto out;
1301
1302   *mpi_list = mpis;
1303
1304  out:
1305
1306   if (err)
1307     mpint_list_free (mpis);
1308
1309   return err;
1310 }
1311
1312 \f
1313
1314 /* Key modifier function for RSA.  */
1315 static gpg_error_t
1316 ssh_key_modifier_rsa (const char *elems, gcry_mpi_t *mpis)
1317 {
1318   gcry_mpi_t p;
1319   gcry_mpi_t q;
1320   gcry_mpi_t u;
1321
1322   if (strcmp (elems, "nedupq"))
1323     /* Modifying only necessary for secret keys.  */
1324     goto out;
1325
1326   u = mpis[3];
1327   p = mpis[4];
1328   q = mpis[5];
1329
1330   if (gcry_mpi_cmp (p, q) > 0)
1331     {
1332       /* P shall be smaller then Q!  Swap primes.  iqmp becomes u.  */
1333       gcry_mpi_t tmp;
1334
1335       tmp = mpis[4];
1336       mpis[4] = mpis[5];
1337       mpis[5] = tmp;
1338     }
1339   else
1340     /* U needs to be recomputed.  */
1341     gcry_mpi_invm (u, p, q);
1342
1343  out:
1344
1345   return 0;
1346 }
1347
1348 /* Signature encoder function for RSA.  */
1349 static gpg_error_t
1350 ssh_signature_encoder_rsa (ssh_key_type_spec_t *spec,
1351                            estream_t signature_blob,
1352                            gcry_sexp_t s_signature)
1353 {
1354   gpg_error_t err = 0;
1355   gcry_sexp_t valuelist = NULL;
1356   gcry_sexp_t sublist = NULL;
1357   gcry_mpi_t sig_value = NULL;
1358   gcry_mpi_t *mpis = NULL;
1359   const char *elems;
1360   size_t elems_n;
1361   int i;
1362
1363   unsigned char *data;
1364   size_t data_n;
1365   gcry_mpi_t s;
1366
1367   valuelist = gcry_sexp_nth (s_signature, 1);
1368   if (!valuelist)
1369     {
1370       err = gpg_error (GPG_ERR_INV_SEXP);
1371       goto out;
1372     }
1373
1374   elems = spec->elems_signature;
1375   elems_n = strlen (elems);
1376
1377   mpis = xtrycalloc (elems_n + 1, sizeof *mpis);
1378   if (!mpis)
1379     {
1380       err = gpg_error_from_syserror ();
1381       goto out;
1382     }
1383
1384   for (i = 0; i < elems_n; i++)
1385     {
1386       sublist = gcry_sexp_find_token (valuelist, spec->elems_signature + i, 1);
1387       if (!sublist)
1388         {
1389           err = gpg_error (GPG_ERR_INV_SEXP);
1390           break;
1391         }
1392
1393       sig_value = gcry_sexp_nth_mpi (sublist, 1, GCRYMPI_FMT_USG);
1394       if (!sig_value)
1395         {
1396           err = gpg_error (GPG_ERR_INTERNAL); /* FIXME?  */
1397           break;
1398         }
1399       gcry_sexp_release (sublist);
1400       sublist = NULL;
1401
1402       mpis[i] = sig_value;
1403     }
1404   if (err)
1405     goto out;
1406
1407   /* RSA specific */
1408   s = mpis[0];
1409
1410   err = gcry_mpi_aprint (GCRYMPI_FMT_USG, &data, &data_n, s);
1411   if (err)
1412     goto out;
1413
1414   err = stream_write_string (signature_blob, data, data_n);
1415   xfree (data);
1416
1417  out:
1418   gcry_sexp_release (valuelist);
1419   gcry_sexp_release (sublist);
1420   mpint_list_free (mpis);
1421   return err;
1422 }
1423
1424
1425 /* Signature encoder function for DSA.  */
1426 static gpg_error_t
1427 ssh_signature_encoder_dsa (ssh_key_type_spec_t *spec,
1428                            estream_t signature_blob,
1429                            gcry_sexp_t s_signature)
1430 {
1431   gpg_error_t err = 0;
1432   gcry_sexp_t valuelist = NULL;
1433   gcry_sexp_t sublist = NULL;
1434   gcry_mpi_t sig_value = NULL;
1435   gcry_mpi_t *mpis = NULL;
1436   const char *elems;
1437   size_t elems_n;
1438   int i;
1439
1440   unsigned char buffer[SSH_DSA_SIGNATURE_PADDING * SSH_DSA_SIGNATURE_ELEMS];
1441   unsigned char *data = NULL;
1442   size_t data_n;
1443
1444   valuelist = gcry_sexp_nth (s_signature, 1);
1445   if (!valuelist)
1446     {
1447       err = gpg_error (GPG_ERR_INV_SEXP);
1448       goto out;
1449     }
1450
1451   elems = spec->elems_signature;
1452   elems_n = strlen (elems);
1453
1454   mpis = xtrycalloc (elems_n + 1, sizeof *mpis);
1455   if (!mpis)
1456     {
1457       err = gpg_error_from_syserror ();
1458       goto out;
1459     }
1460
1461   for (i = 0; i < elems_n; i++)
1462     {
1463       sublist = gcry_sexp_find_token (valuelist, spec->elems_signature + i, 1);
1464       if (!sublist)
1465         {
1466           err = gpg_error (GPG_ERR_INV_SEXP);
1467           break;
1468         }
1469
1470       sig_value = gcry_sexp_nth_mpi (sublist, 1, GCRYMPI_FMT_USG);
1471       if (!sig_value)
1472         {
1473           err = gpg_error (GPG_ERR_INTERNAL); /* FIXME?  */
1474           break;
1475         }
1476       gcry_sexp_release (sublist);
1477       sublist = NULL;
1478
1479       mpis[i] = sig_value;
1480     }
1481   if (err)
1482     goto out;
1483
1484   /* DSA specific code.  */
1485
1486   /* FIXME: Why this complicated code?  Why collecting boths mpis in a
1487      buffer instead of writing them out one after the other?  */
1488   for (i = 0; i < 2; i++)
1489     {
1490       err = gcry_mpi_aprint (GCRYMPI_FMT_USG, &data, &data_n, mpis[i]);
1491       if (err)
1492         break;
1493
1494       if (data_n > SSH_DSA_SIGNATURE_PADDING)
1495         {
1496           err = gpg_error (GPG_ERR_INTERNAL); /* FIXME?  */
1497           break;
1498         }
1499
1500       memset (buffer + (i * SSH_DSA_SIGNATURE_PADDING), 0,
1501               SSH_DSA_SIGNATURE_PADDING - data_n);
1502       memcpy (buffer + (i * SSH_DSA_SIGNATURE_PADDING)
1503               + (SSH_DSA_SIGNATURE_PADDING - data_n), data, data_n);
1504
1505       xfree (data);
1506       data = NULL;
1507     }
1508   if (err)
1509     goto out;
1510
1511   err = stream_write_string (signature_blob, buffer, sizeof (buffer));
1512
1513  out:
1514   xfree (data);
1515   gcry_sexp_release (valuelist);
1516   gcry_sexp_release (sublist);
1517   mpint_list_free (mpis);
1518   return err;
1519 }
1520
1521
1522 /* Signature encoder function for ECDSA.  */
1523 static gpg_error_t
1524 ssh_signature_encoder_ecdsa (ssh_key_type_spec_t *spec,
1525                              estream_t stream, gcry_sexp_t s_signature)
1526 {
1527   gpg_error_t err = 0;
1528   gcry_sexp_t valuelist = NULL;
1529   gcry_sexp_t sublist = NULL;
1530   gcry_mpi_t sig_value = NULL;
1531   gcry_mpi_t *mpis = NULL;
1532   const char *elems;
1533   size_t elems_n;
1534   int i;
1535
1536   unsigned char *data[2] = {NULL, NULL};
1537   size_t data_n[2];
1538   size_t innerlen;
1539
1540   valuelist = gcry_sexp_nth (s_signature, 1);
1541   if (!valuelist)
1542     {
1543       err = gpg_error (GPG_ERR_INV_SEXP);
1544       goto out;
1545     }
1546
1547   elems = spec->elems_signature;
1548   elems_n = strlen (elems);
1549
1550   mpis = xtrycalloc (elems_n + 1, sizeof *mpis);
1551   if (!mpis)
1552     {
1553       err = gpg_error_from_syserror ();
1554       goto out;
1555     }
1556
1557   for (i = 0; i < elems_n; i++)
1558     {
1559       sublist = gcry_sexp_find_token (valuelist, spec->elems_signature + i, 1);
1560       if (!sublist)
1561         {
1562           err = gpg_error (GPG_ERR_INV_SEXP);
1563           break;
1564         }
1565
1566       sig_value = gcry_sexp_nth_mpi (sublist, 1, GCRYMPI_FMT_USG);
1567       if (!sig_value)
1568         {
1569           err = gpg_error (GPG_ERR_INTERNAL); /* FIXME?  */
1570           break;
1571         }
1572       gcry_sexp_release (sublist);
1573       sublist = NULL;
1574
1575       mpis[i] = sig_value;
1576     }
1577   if (err)
1578     goto out;
1579
1580   /* ECDSA specific */
1581
1582   innerlen = 0;
1583   for (i = 0; i < DIM(data); i++)
1584     {
1585       err = gcry_mpi_aprint (GCRYMPI_FMT_STD, &data[i], &data_n[i], mpis[i]);
1586       if (err)
1587         goto out;
1588       innerlen += 4 + data_n[i];
1589     }
1590
1591   err = stream_write_uint32 (stream, innerlen);
1592   if (err)
1593     goto out;
1594
1595   for (i = 0; i < DIM(data); i++)
1596     {
1597       err = stream_write_string (stream, data[i], data_n[i]);
1598       if (err)
1599         goto out;
1600     }
1601
1602  out:
1603   for (i = 0; i < DIM(data); i++)
1604     xfree (data[i]);
1605   gcry_sexp_release (valuelist);
1606   gcry_sexp_release (sublist);
1607   mpint_list_free (mpis);
1608   return err;
1609 }
1610
1611
1612 /* Signature encoder function for EdDSA.  */
1613 static gpg_error_t
1614 ssh_signature_encoder_eddsa (ssh_key_type_spec_t *spec,
1615                              estream_t stream, gcry_sexp_t s_signature)
1616 {
1617   gpg_error_t err = 0;
1618   gcry_sexp_t valuelist = NULL;
1619   gcry_sexp_t sublist = NULL;
1620   gcry_mpi_t sig_value = NULL;
1621   gcry_mpi_t *mpis = NULL;
1622   const char *elems;
1623   size_t elems_n;
1624   int i;
1625
1626   unsigned char *data[2] = {NULL, NULL};
1627   size_t data_n[2];
1628   size_t totallen;
1629
1630   valuelist = gcry_sexp_nth (s_signature, 1);
1631   if (!valuelist)
1632     {
1633       err = gpg_error (GPG_ERR_INV_SEXP);
1634       goto out;
1635     }
1636
1637   elems = spec->elems_signature;
1638   elems_n = strlen (elems);
1639
1640   mpis = xtrycalloc (elems_n + 1, sizeof *mpis);
1641   if (!mpis)
1642     {
1643       err = gpg_error_from_syserror ();
1644       goto out;
1645     }
1646
1647   for (i = 0; i < elems_n; i++)
1648     {
1649       sublist = gcry_sexp_find_token (valuelist, spec->elems_signature + i, 1);
1650       if (!sublist)
1651         {
1652           err = gpg_error (GPG_ERR_INV_SEXP);
1653           break;
1654         }
1655
1656       sig_value = gcry_sexp_nth_mpi (sublist, 1, GCRYMPI_FMT_USG);
1657       if (!sig_value)
1658         {
1659           err = gpg_error (GPG_ERR_INTERNAL); /* FIXME?  */
1660           break;
1661         }
1662       gcry_sexp_release (sublist);
1663       sublist = NULL;
1664
1665       mpis[i] = sig_value;
1666     }
1667   if (err)
1668     goto out;
1669
1670   /* EdDSA specific.  Actually TOTALLEN will always be 64.  */
1671
1672   totallen = 0;
1673   for (i = 0; i < DIM(data); i++)
1674     {
1675       err = gcry_mpi_aprint (GCRYMPI_FMT_USG, &data[i], &data_n[i], mpis[i]);
1676       if (err)
1677         goto out;
1678       totallen += data_n[i];
1679     }
1680
1681   gcry_log_debug ("  out: len=%zu\n", totallen);
1682   err = stream_write_uint32 (stream, totallen);
1683   if (err)
1684     goto out;
1685
1686   for (i = 0; i < DIM(data); i++)
1687     {
1688       gcry_log_debughex ("  out", data[i], data_n[i]);
1689       err = stream_write_data (stream, data[i], data_n[i]);
1690       if (err)
1691         goto out;
1692     }
1693
1694  out:
1695   for (i = 0; i < DIM(data); i++)
1696     xfree (data[i]);
1697   gcry_sexp_release (valuelist);
1698   gcry_sexp_release (sublist);
1699   mpint_list_free (mpis);
1700   return err;
1701 }
1702
1703
1704 /*
1705    S-Expressions.
1706  */
1707
1708
1709 /* This function constructs a new S-Expression for the key identified
1710    by the KEY_SPEC, SECRET, CURVE_NAME, MPIS, and COMMENT, which is to
1711    be stored at R_SEXP.  Returns an error code.  */
1712 static gpg_error_t
1713 sexp_key_construct (gcry_sexp_t *r_sexp,
1714                     ssh_key_type_spec_t key_spec, int secret,
1715                     const char *curve_name, gcry_mpi_t *mpis,
1716                     const char *comment)
1717 {
1718   gpg_error_t err;
1719   gcry_sexp_t sexp_new = NULL;
1720   void *formatbuf = NULL;
1721   void **arg_list = NULL;
1722   estream_t format = NULL;
1723
1724
1725   if ((key_spec.flags & SPEC_FLAG_IS_EdDSA))
1726     {
1727       /* It is much easier and more readable to use a separate code
1728          path for EdDSA.  */
1729       if (!curve_name)
1730         err = gpg_error (GPG_ERR_INV_CURVE);
1731       else if (!mpis[0] || !gcry_mpi_get_flag (mpis[0], GCRYMPI_FLAG_OPAQUE))
1732         err = gpg_error (GPG_ERR_BAD_PUBKEY);
1733       else if (secret
1734                && (!mpis[1]
1735                    || !gcry_mpi_get_flag (mpis[1], GCRYMPI_FLAG_OPAQUE)))
1736         err = gpg_error (GPG_ERR_BAD_SECKEY);
1737       else if (secret)
1738         err = gcry_sexp_build (&sexp_new, NULL,
1739                                "(private-key(ecc(curve %s)"
1740                                "(flags eddsa)(q %m)(d %m))"
1741                                "(comment%s))",
1742                                curve_name,
1743                                mpis[0], mpis[1],
1744                                comment? comment:"");
1745       else
1746         err = gcry_sexp_build (&sexp_new, NULL,
1747                                "(public-key(ecc(curve %s)"
1748                                "(flags eddsa)(q %m))"
1749                                "(comment%s))",
1750                                curve_name,
1751                                mpis[0],
1752                                comment? comment:"");
1753     }
1754   else
1755     {
1756       const char *key_identifier[] = { "public-key", "private-key" };
1757       int arg_idx;
1758       const char *elems;
1759       size_t elems_n;
1760       unsigned int i, j;
1761
1762       if (secret)
1763         elems = key_spec.elems_sexp_order;
1764       else
1765         elems = key_spec.elems_key_public;
1766       elems_n = strlen (elems);
1767
1768       format = es_fopenmem (0, "a+b");
1769       if (!format)
1770         {
1771           err = gpg_error_from_syserror ();
1772           goto out;
1773         }
1774
1775       /* Key identifier, algorithm identifier, mpis, comment, and a NULL
1776          as a safeguard. */
1777       arg_list = xtrymalloc (sizeof (*arg_list) * (2 + 1 + elems_n + 1 + 1));
1778       if (!arg_list)
1779         {
1780           err = gpg_error_from_syserror ();
1781           goto out;
1782         }
1783       arg_idx = 0;
1784
1785       es_fputs ("(%s(%s", format);
1786       arg_list[arg_idx++] = &key_identifier[secret];
1787       arg_list[arg_idx++] = &key_spec.identifier;
1788       if (curve_name)
1789         {
1790           es_fputs ("(curve%s)", format);
1791           arg_list[arg_idx++] = &curve_name;
1792         }
1793
1794       for (i = 0; i < elems_n; i++)
1795         {
1796           es_fprintf (format, "(%c%%m)", elems[i]);
1797           if (secret)
1798             {
1799               for (j = 0; j < elems_n; j++)
1800                 if (key_spec.elems_key_secret[j] == elems[i])
1801                   break;
1802             }
1803           else
1804             j = i;
1805           arg_list[arg_idx++] = &mpis[j];
1806         }
1807       es_fputs (")(comment%s))", format);
1808       arg_list[arg_idx++] = &comment;
1809       arg_list[arg_idx] = NULL;
1810
1811       es_putc (0, format);
1812       if (es_ferror (format))
1813         {
1814           err = gpg_error_from_syserror ();
1815           goto out;
1816         }
1817       if (es_fclose_snatch (format, &formatbuf, NULL))
1818         {
1819           err = gpg_error_from_syserror ();
1820           goto out;
1821         }
1822       format = NULL;
1823
1824       err = gcry_sexp_build_array (&sexp_new, NULL, formatbuf, arg_list);
1825     }
1826
1827   if (!err)
1828     *r_sexp = sexp_new;
1829
1830  out:
1831   es_fclose (format);
1832   xfree (arg_list);
1833   xfree (formatbuf);
1834
1835   return err;
1836 }
1837
1838
1839 /* This function extracts the key from the s-expression SEXP according
1840    to KEY_SPEC and stores it in ssh format at (R_BLOB, R_BLOBLEN).  If
1841    WITH_SECRET is true, the secret key parts are also extracted if
1842    possible.  Returns 0 on success or an error code.  Note that data
1843    stored at R_BLOB must be freed using es_free!  */
1844 static gpg_error_t
1845 ssh_key_to_blob (gcry_sexp_t sexp, int with_secret,
1846                  ssh_key_type_spec_t key_spec,
1847                  void **r_blob, size_t *r_blob_size)
1848 {
1849   gpg_error_t err = 0;
1850   gcry_sexp_t value_list = NULL;
1851   gcry_sexp_t value_pair = NULL;
1852   char *curve_name = NULL;
1853   estream_t stream = NULL;
1854   void *blob = NULL;
1855   size_t blob_size;
1856   const char *elems, *p_elems;
1857   const char *data;
1858   size_t datalen;
1859
1860   *r_blob = NULL;
1861   *r_blob_size = 0;
1862
1863   stream = es_fopenmem (0, "r+b");
1864   if (!stream)
1865     {
1866       err = gpg_error_from_syserror ();
1867       goto out;
1868     }
1869
1870   /* Get the type of the key extpression.  */
1871   data = gcry_sexp_nth_data (sexp, 0, &datalen);
1872   if (!data)
1873     {
1874       err = gpg_error (GPG_ERR_INV_SEXP);
1875       goto out;
1876     }
1877
1878   if ((datalen == 10 && !strncmp (data, "public-key", 10))
1879       || (datalen == 21 && !strncmp (data, "protected-private-key", 21))
1880       || (datalen == 20 && !strncmp (data, "shadowed-private-key", 20)))
1881     elems = key_spec.elems_key_public;
1882   else if (datalen == 11 && !strncmp (data, "private-key", 11))
1883     elems = with_secret? key_spec.elems_key_secret : key_spec.elems_key_public;
1884   else
1885     {
1886       err = gpg_error (GPG_ERR_INV_SEXP);
1887       goto out;
1888     }
1889
1890   /* Get the algorithm identifier.  */
1891   value_list = gcry_sexp_find_token (sexp, key_spec.identifier, 0);
1892   if (!value_list)
1893     {
1894       err = gpg_error (GPG_ERR_INV_SEXP);
1895       goto out;
1896     }
1897
1898   /* Write the ssh algorithm identifier.  */
1899   if ((key_spec.flags & SPEC_FLAG_IS_ECDSA))
1900     {
1901       /* Parse the "curve" parameter.  We currently expect the curve
1902          name for ECC and not the parameters of the curve.  This can
1903          easily be changed but then we need to find the curve name
1904          from the parameters using gcry_pk_get_curve.  */
1905       const char *mapped;
1906       const char *sshname;
1907
1908       gcry_sexp_release (value_pair);
1909       value_pair = gcry_sexp_find_token (value_list, "curve", 5);
1910       if (!value_pair)
1911         {
1912           err = gpg_error (GPG_ERR_INV_CURVE);
1913           goto out;
1914         }
1915       curve_name = gcry_sexp_nth_string (value_pair, 1);
1916       if (!curve_name)
1917         {
1918           err = gpg_error (GPG_ERR_INV_CURVE); /* (Or out of core.)  */
1919           goto out;
1920         }
1921
1922       /* Fixme: The mapping should be done by using gcry_pk_get_curve
1923          et al to iterate over all name aliases.  */
1924       if (!strcmp (curve_name, "NIST P-256"))
1925         mapped = "nistp256";
1926       else if (!strcmp (curve_name, "NIST P-384"))
1927         mapped = "nistp384";
1928       else if (!strcmp (curve_name, "NIST P-521"))
1929         mapped = "nistp521";
1930       else
1931         mapped = NULL;
1932       if (mapped)
1933         {
1934           xfree (curve_name);
1935           curve_name = xtrystrdup (mapped);
1936           if (!curve_name)
1937             {
1938               err = gpg_error_from_syserror ();
1939               goto out;
1940             }
1941         }
1942
1943       sshname = ssh_identifier_from_curve_name (curve_name);
1944       if (!sshname)
1945         {
1946           err = gpg_error (GPG_ERR_UNKNOWN_CURVE);
1947           goto out;
1948         }
1949       err = stream_write_cstring (stream, sshname);
1950       if (err)
1951         goto out;
1952       err = stream_write_cstring (stream, curve_name);
1953       if (err)
1954         goto out;
1955     }
1956   else
1957     {
1958       /* Note: This is also used for EdDSA.  */
1959       err = stream_write_cstring (stream, key_spec.ssh_identifier);
1960       if (err)
1961         goto out;
1962     }
1963
1964   /* Write the parameters.  */
1965   for (p_elems = elems; *p_elems; p_elems++)
1966     {
1967       gcry_sexp_release (value_pair);
1968       value_pair = gcry_sexp_find_token (value_list, p_elems, 1);
1969       if (!value_pair)
1970         {
1971           err = gpg_error (GPG_ERR_INV_SEXP);
1972           goto out;
1973         }
1974       if ((key_spec.flags & SPEC_FLAG_IS_EdDSA))
1975         {
1976
1977           data = gcry_sexp_nth_data (value_pair, 1, &datalen);
1978           if (!data)
1979             {
1980               err = gpg_error (GPG_ERR_INV_SEXP);
1981               goto out;
1982             }
1983           err = stream_write_string (stream, data, datalen);
1984           if (err)
1985             goto out;
1986         }
1987       else
1988         {
1989           gcry_mpi_t mpi;
1990
1991           /* Note that we need to use STD format; i.e. prepend a 0x00
1992              to indicate a positive number if the high bit is set. */
1993           mpi = gcry_sexp_nth_mpi (value_pair, 1, GCRYMPI_FMT_STD);
1994           if (!mpi)
1995             {
1996               err = gpg_error (GPG_ERR_INV_SEXP);
1997               goto out;
1998             }
1999           err = stream_write_mpi (stream, mpi);
2000           gcry_mpi_release (mpi);
2001           if (err)
2002             goto out;
2003         }
2004     }
2005
2006   if (es_fclose_snatch (stream, &blob, &blob_size))
2007     {
2008       err = gpg_error_from_syserror ();
2009       goto out;
2010     }
2011   stream = NULL;
2012
2013   *r_blob = blob;
2014   blob = NULL;
2015   *r_blob_size = blob_size;
2016
2017  out:
2018   gcry_sexp_release (value_list);
2019   gcry_sexp_release (value_pair);
2020   xfree (curve_name);
2021   es_fclose (stream);
2022   es_free (blob);
2023
2024   return err;
2025 }
2026
2027 /* Extract the car from SEXP, and create a newly created C-string
2028    which is to be stored in IDENTIFIER.  */
2029 static gpg_error_t
2030 sexp_extract_identifier (gcry_sexp_t sexp, char **identifier)
2031 {
2032   char *identifier_new;
2033   gcry_sexp_t sublist;
2034   const char *data;
2035   size_t data_n;
2036   gpg_error_t err;
2037
2038   identifier_new = NULL;
2039   err = 0;
2040
2041   sublist = gcry_sexp_nth (sexp, 1);
2042   if (! sublist)
2043     {
2044       err = gpg_error (GPG_ERR_INV_SEXP);
2045       goto out;
2046     }
2047
2048   data = gcry_sexp_nth_data (sublist, 0, &data_n);
2049   if (! data)
2050     {
2051       err = gpg_error (GPG_ERR_INV_SEXP);
2052       goto out;
2053     }
2054
2055   identifier_new = make_cstring (data, data_n);
2056   if (! identifier_new)
2057     {
2058       err = gpg_err_code_from_errno (errno);
2059       goto out;
2060     }
2061
2062   *identifier = identifier_new;
2063
2064  out:
2065
2066   gcry_sexp_release (sublist);
2067
2068   return err;
2069 }
2070
2071 \f
2072
2073 /*
2074
2075   Key I/O.
2076
2077 */
2078
2079 /* Search for a key specification entry.  If SSH_NAME is not NULL,
2080    search for an entry whose "ssh_name" is equal to SSH_NAME;
2081    otherwise, search for an entry whose "name" is equal to NAME.
2082    Store found entry in SPEC on success, return error otherwise.  */
2083 static gpg_error_t
2084 ssh_key_type_lookup (const char *ssh_name, const char *name,
2085                      ssh_key_type_spec_t *spec)
2086 {
2087   gpg_error_t err;
2088   unsigned int i;
2089
2090   /* FIXME: Although this sees to work, it not be correct if the
2091      lookup is done via name which might be "ecc" but actually it need
2092      to check the flags to see whether it is eddsa or ecdsa.  Maybe
2093      the entire parameter controlled logic is too complicated and we
2094      would do better by just switching on the ssh_name.  */
2095   for (i = 0; i < DIM (ssh_key_types); i++)
2096     if ((ssh_name && (! strcmp (ssh_name, ssh_key_types[i].ssh_identifier)))
2097         || (name && (! strcmp (name, ssh_key_types[i].identifier))))
2098       break;
2099
2100   if (i == DIM (ssh_key_types))
2101     err = gpg_error (GPG_ERR_NOT_FOUND);
2102   else
2103     {
2104       *spec = ssh_key_types[i];
2105       err = 0;
2106     }
2107
2108   return err;
2109 }
2110
2111
2112 /* Receive a key from STREAM, according to the key specification given
2113    as KEY_SPEC.  Depending on SECRET, receive a secret or a public
2114    key.  If READ_COMMENT is true, receive a comment string as well.
2115    Constructs a new S-Expression from received data and stores it in
2116    KEY_NEW.  Returns zero on success or an error code.  */
2117 static gpg_error_t
2118 ssh_receive_key (estream_t stream, gcry_sexp_t *key_new, int secret,
2119                  int read_comment, ssh_key_type_spec_t *key_spec)
2120 {
2121   gpg_error_t err;
2122   char *key_type = NULL;
2123   char *comment = NULL;
2124   gcry_sexp_t key = NULL;
2125   ssh_key_type_spec_t spec;
2126   gcry_mpi_t *mpi_list = NULL;
2127   const char *elems;
2128   char *curve_name = NULL;
2129
2130
2131   err = stream_read_cstring (stream, &key_type);
2132   if (err)
2133     goto out;
2134
2135   err = ssh_key_type_lookup (key_type, NULL, &spec);
2136   if (err)
2137     goto out;
2138
2139   if ((spec.flags & SPEC_FLAG_IS_EdDSA))
2140     {
2141       /* The format of an EdDSA key is:
2142        *   string       key_type ("ssh-ed25519")
2143        *   string       public_key
2144        *   string       private_key
2145        *
2146        * Note that the private key is the concatenation of the private
2147        * key with the public key.  Thus theres are 64 bytes; however
2148        * we only want the real 32 byte private key - Libgcrypt expects
2149        * this.
2150        */
2151       mpi_list = xtrycalloc (3, sizeof *mpi_list);
2152       if (!mpi_list)
2153         {
2154           err = gpg_error_from_syserror ();
2155           goto out;
2156         }
2157
2158       err = stream_read_blob (stream, 0, &mpi_list[0]);
2159       if (err)
2160         goto out;
2161       if (secret)
2162         {
2163           u32 len = 0;
2164           unsigned char *buffer;
2165
2166           /* Read string length.  */
2167           err = stream_read_uint32 (stream, &len);
2168           if (err)
2169             goto out;
2170           if (len != 32 && len != 64)
2171             {
2172               err = gpg_error (GPG_ERR_BAD_SECKEY);
2173               goto out;
2174             }
2175           buffer = xtrymalloc_secure (32);
2176           if (!buffer)
2177             {
2178               err = gpg_error_from_syserror ();
2179               goto out;
2180             }
2181           err = stream_read_data (stream, buffer, 32);
2182           if (err)
2183             {
2184               xfree (buffer);
2185               goto out;
2186             }
2187           mpi_list[1] = gcry_mpi_set_opaque (NULL, buffer, 8*32);
2188           buffer = NULL;
2189           if (len == 64)
2190             {
2191               err = stream_read_skip (stream, 32);
2192               if (err)
2193                 goto out;
2194             }
2195         }
2196     }
2197   else if ((spec.flags & SPEC_FLAG_IS_ECDSA))
2198     {
2199       /* The format of an ECDSA key is:
2200        *   string       key_type ("ecdsa-sha2-nistp256" |
2201        *                          "ecdsa-sha2-nistp384" |
2202        *                          "ecdsa-sha2-nistp521" )
2203        *   string       ecdsa_curve_name
2204        *   string       ecdsa_public_key
2205        *   mpint        ecdsa_private
2206        *
2207        * Note that we use the mpint reader instead of the string
2208        * reader for ecsa_public_key.
2209        */
2210       unsigned char *buffer;
2211       const char *mapped;
2212
2213       err = stream_read_string (stream, 0, &buffer, NULL);
2214       if (err)
2215         goto out;
2216       curve_name = buffer;
2217       /* Fixme: Check that curve_name matches the keytype.  */
2218       /* Because Libgcrypt < 1.6 has no support for the "nistpNNN"
2219          curve names, we need to translate them here to Libgcrypt's
2220          native names.  */
2221       if (!strcmp (curve_name, "nistp256"))
2222         mapped = "NIST P-256";
2223       else if (!strcmp (curve_name, "nistp384"))
2224         mapped = "NIST P-384";
2225       else if (!strcmp (curve_name, "nistp521"))
2226         mapped = "NIST P-521";
2227       else
2228         mapped = NULL;
2229       if (mapped)
2230         {
2231           xfree (curve_name);
2232           curve_name = xtrystrdup (mapped);
2233           if (!curve_name)
2234             {
2235               err = gpg_error_from_syserror ();
2236               goto out;
2237             }
2238         }
2239
2240       err = ssh_receive_mpint_list (stream, secret, spec, &mpi_list);
2241       if (err)
2242         goto out;
2243     }
2244   else
2245     {
2246       err = ssh_receive_mpint_list (stream, secret, spec, &mpi_list);
2247       if (err)
2248         goto out;
2249     }
2250
2251   if (read_comment)
2252     {
2253       err = stream_read_cstring (stream, &comment);
2254       if (err)
2255         goto out;
2256     }
2257
2258   if (secret)
2259     elems = spec.elems_key_secret;
2260   else
2261     elems = spec.elems_key_public;
2262
2263   if (spec.key_modifier)
2264     {
2265       err = (*spec.key_modifier) (elems, mpi_list);
2266       if (err)
2267         goto out;
2268     }
2269
2270   if ((spec.flags & SPEC_FLAG_IS_EdDSA))
2271     {
2272       if (secret)
2273         {
2274           err = gcry_sexp_build (&key, NULL,
2275                                  "(private-key(ecc(curve \"Ed25519\")"
2276                                  "(flags eddsa)(q %m)(d %m))"
2277                                  "(comment%s))",
2278                                  mpi_list[0], mpi_list[1],
2279                                  comment? comment:"");
2280         }
2281       else
2282         {
2283           err = gcry_sexp_build (&key, NULL,
2284                                  "(public-key(ecc(curve \"Ed25519\")"
2285                                  "(flags eddsa)(q %m))"
2286                                  "(comment%s))",
2287                                  mpi_list[0],
2288                                  comment? comment:"");
2289         }
2290     }
2291   else
2292     {
2293       err = sexp_key_construct (&key, spec, secret, curve_name, mpi_list,
2294                                 comment? comment:"");
2295       if (err)
2296         goto out;
2297     }
2298
2299   if (key_spec)
2300     *key_spec = spec;
2301   *key_new = key;
2302
2303  out:
2304   mpint_list_free (mpi_list);
2305   xfree (curve_name);
2306   xfree (key_type);
2307   xfree (comment);
2308
2309   return err;
2310 }
2311
2312
2313 /* Write the public key from KEY to STREAM in SSH key format.  If
2314    OVERRIDE_COMMENT is not NULL, it will be used instead of the
2315    comment stored in the key.  */
2316 static gpg_error_t
2317 ssh_send_key_public (estream_t stream, gcry_sexp_t key,
2318                      const char *override_comment)
2319 {
2320   ssh_key_type_spec_t spec;
2321   char *key_type = NULL;
2322   char *comment = NULL;
2323   void *blob = NULL;
2324   size_t bloblen;
2325   gpg_error_t err;
2326
2327   err = sexp_extract_identifier (key, &key_type);
2328   if (err)
2329     goto out;
2330
2331   err = ssh_key_type_lookup (NULL, key_type, &spec);
2332   if (err)
2333     goto out;
2334
2335   err = ssh_key_to_blob (key, 0, spec, &blob, &bloblen);
2336   if (err)
2337     goto out;
2338
2339   err = stream_write_string (stream, blob, bloblen);
2340   if (err)
2341     goto out;
2342
2343   if (override_comment)
2344     err = stream_write_cstring (stream, override_comment);
2345   else
2346     {
2347       err = ssh_key_extract_comment (key, &comment);
2348       if (!err)
2349         err = stream_write_cstring (stream, comment);
2350     }
2351   if (err)
2352     goto out;
2353
2354  out:
2355   xfree (key_type);
2356   xfree (comment);
2357   es_free (blob);
2358
2359   return err;
2360 }
2361
2362
2363 /* Read a public key out of BLOB/BLOB_SIZE according to the key
2364    specification given as KEY_SPEC, storing the new key in KEY_PUBLIC.
2365    Returns zero on success or an error code.  */
2366 static gpg_error_t
2367 ssh_read_key_public_from_blob (unsigned char *blob, size_t blob_size,
2368                                gcry_sexp_t *key_public,
2369                                ssh_key_type_spec_t *key_spec)
2370 {
2371   gpg_error_t err;
2372   estream_t blob_stream;
2373
2374   blob_stream = es_fopenmem (0, "r+b");
2375   if (!blob_stream)
2376     {
2377       err = gpg_error_from_syserror ();
2378       goto out;
2379     }
2380
2381   err = stream_write_data (blob_stream, blob, blob_size);
2382   if (err)
2383     goto out;
2384
2385   err = es_fseek (blob_stream, 0, SEEK_SET);
2386   if (err)
2387     goto out;
2388
2389   err = ssh_receive_key (blob_stream, key_public, 0, 0, key_spec);
2390
2391  out:
2392   es_fclose (blob_stream);
2393   return err;
2394 }
2395
2396 \f
2397
2398 /* This function calculates the key grip for the key contained in the
2399    S-Expression KEY and writes it to BUFFER, which must be large
2400    enough to hold it.  Returns usual error code.  */
2401 static gpg_error_t
2402 ssh_key_grip (gcry_sexp_t key, unsigned char *buffer)
2403 {
2404   if (!gcry_pk_get_keygrip (key, buffer))
2405     {
2406       gpg_error_t err = gcry_pk_testkey (key);
2407       return err? err : gpg_error (GPG_ERR_INTERNAL);
2408     }
2409
2410   return 0;
2411 }
2412
2413
2414 /* Check whether a smartcard is available and whether it has a usable
2415    key.  Store a copy of that key at R_PK and return 0.  If no key is
2416    available store NULL at R_PK and return an error code.  If CARDSN
2417    is not NULL, a string with the serial number of the card will be
2418    a malloced and stored there. */
2419 static gpg_error_t
2420 card_key_available (ctrl_t ctrl, gcry_sexp_t *r_pk, char **cardsn)
2421 {
2422   gpg_error_t err;
2423   char *authkeyid;
2424   char *serialno = NULL;
2425   unsigned char *pkbuf;
2426   size_t pkbuflen;
2427   gcry_sexp_t s_pk;
2428   unsigned char grip[20];
2429
2430   *r_pk = NULL;
2431   if (cardsn)
2432     *cardsn = NULL;
2433
2434   /* First see whether a card is available and whether the application
2435      is supported.  */
2436   err = agent_card_getattr (ctrl, "$AUTHKEYID", &authkeyid);
2437   if ( gpg_err_code (err) == GPG_ERR_CARD_REMOVED )
2438     {
2439       /* Ask for the serial number to reset the card.  */
2440       err = agent_card_serialno (ctrl, &serialno);
2441       if (err)
2442         {
2443           if (opt.verbose)
2444             log_info (_("error getting serial number of card: %s\n"),
2445                       gpg_strerror (err));
2446           return err;
2447         }
2448       log_info (_("detected card with S/N: %s\n"), serialno);
2449       err = agent_card_getattr (ctrl, "$AUTHKEYID", &authkeyid);
2450     }
2451   if (err)
2452     {
2453       log_error (_("no authentication key for ssh on card: %s\n"),
2454                  gpg_strerror (err));
2455       xfree (serialno);
2456       return err;
2457     }
2458
2459   /* Get the S/N if we don't have it yet.  Use the fast getattr method.  */
2460   if (!serialno && (err = agent_card_getattr (ctrl, "SERIALNO", &serialno)) )
2461     {
2462       log_error (_("error getting serial number of card: %s\n"),
2463                  gpg_strerror (err));
2464       xfree (authkeyid);
2465       return err;
2466     }
2467
2468   /* Read the public key.  */
2469   err = agent_card_readkey (ctrl, authkeyid, &pkbuf);
2470   if (err)
2471     {
2472       if (opt.verbose)
2473         log_info (_("no suitable card key found: %s\n"), gpg_strerror (err));
2474       xfree (serialno);
2475       xfree (authkeyid);
2476       return err;
2477     }
2478
2479   pkbuflen = gcry_sexp_canon_len (pkbuf, 0, NULL, NULL);
2480   err = gcry_sexp_sscan (&s_pk, NULL, (char*)pkbuf, pkbuflen);
2481   if (err)
2482     {
2483       log_error ("failed to build S-Exp from received card key: %s\n",
2484                  gpg_strerror (err));
2485       xfree (pkbuf);
2486       xfree (serialno);
2487       xfree (authkeyid);
2488       return err;
2489     }
2490
2491   err = ssh_key_grip (s_pk, grip);
2492   if (err)
2493     {
2494       log_debug ("error computing keygrip from received card key: %s\n",
2495                  gcry_strerror (err));
2496       xfree (pkbuf);
2497       gcry_sexp_release (s_pk);
2498       xfree (serialno);
2499       xfree (authkeyid);
2500       return err;
2501     }
2502
2503   if ( agent_key_available (grip) )
2504     {
2505       /* (Shadow)-key is not available in our key storage.  */
2506       unsigned char *shadow_info;
2507       unsigned char *tmp;
2508
2509       shadow_info = make_shadow_info (serialno, authkeyid);
2510       if (!shadow_info)
2511         {
2512           err = gpg_error_from_syserror ();
2513           xfree (pkbuf);
2514           gcry_sexp_release (s_pk);
2515           xfree (serialno);
2516           xfree (authkeyid);
2517           return err;
2518         }
2519       err = agent_shadow_key (pkbuf, shadow_info, &tmp);
2520       xfree (shadow_info);
2521       if (err)
2522         {
2523           log_error (_("shadowing the key failed: %s\n"), gpg_strerror (err));
2524           xfree (pkbuf);
2525           gcry_sexp_release (s_pk);
2526           xfree (serialno);
2527           xfree (authkeyid);
2528           return err;
2529         }
2530       xfree (pkbuf);
2531       pkbuf = tmp;
2532       pkbuflen = gcry_sexp_canon_len (pkbuf, 0, NULL, NULL);
2533       assert (pkbuflen);
2534
2535       err = agent_write_private_key (grip, pkbuf, pkbuflen, 0);
2536       if (err)
2537         {
2538           log_error (_("error writing key: %s\n"), gpg_strerror (err));
2539           xfree (pkbuf);
2540           gcry_sexp_release (s_pk);
2541           xfree (serialno);
2542           xfree (authkeyid);
2543           return err;
2544         }
2545     }
2546
2547   if (cardsn)
2548     {
2549       char *dispsn;
2550
2551       /* If the card handler is able to return a short serialnumber,
2552          use that one, else use the complete serialno. */
2553       if (!agent_card_getattr (ctrl, "$DISPSERIALNO", &dispsn))
2554         {
2555           *cardsn = xtryasprintf ("cardno:%s", dispsn);
2556           xfree (dispsn);
2557         }
2558       else
2559         *cardsn = xtryasprintf ("cardno:%s", serialno);
2560       if (!*cardsn)
2561         {
2562           err = gpg_error_from_syserror ();
2563           xfree (pkbuf);
2564           gcry_sexp_release (s_pk);
2565           xfree (serialno);
2566           xfree (authkeyid);
2567           return err;
2568         }
2569     }
2570
2571   xfree (pkbuf);
2572   xfree (serialno);
2573   xfree (authkeyid);
2574   *r_pk = s_pk;
2575   return 0;
2576 }
2577
2578
2579 \f
2580
2581 /*
2582
2583   Request handler.  Each handler is provided with a CTRL context, a
2584   REQUEST object and a RESPONSE object.  The actual request is to be
2585   read from REQUEST, the response needs to be written to RESPONSE.
2586
2587 */
2588
2589
2590 /* Handler for the "request_identities" command.  */
2591 static gpg_error_t
2592 ssh_handler_request_identities (ctrl_t ctrl,
2593                                 estream_t request, estream_t response)
2594 {
2595   ssh_key_type_spec_t spec;
2596   char *key_fname = NULL;
2597   char *fnameptr;
2598   u32 key_counter;
2599   estream_t key_blobs;
2600   gcry_sexp_t key_secret;
2601   gcry_sexp_t key_public;
2602   gpg_error_t err;
2603   int ret;
2604   ssh_control_file_t cf = NULL;
2605   char *cardsn;
2606   gpg_error_t ret_err;
2607
2608   (void)request;
2609
2610   /* Prepare buffer stream.  */
2611
2612   key_secret = NULL;
2613   key_public = NULL;
2614   key_counter = 0;
2615   err = 0;
2616
2617   key_blobs = es_fopenmem (0, "r+b");
2618   if (! key_blobs)
2619     {
2620       err = gpg_error_from_syserror ();
2621       goto out;
2622     }
2623
2624   /* First check whether a key is currently available in the card
2625      reader - this should be allowed even without being listed in
2626      sshcontrol. */
2627
2628   if (!opt.disable_scdaemon
2629       && !card_key_available (ctrl, &key_public, &cardsn))
2630     {
2631       err = ssh_send_key_public (key_blobs, key_public, cardsn);
2632       gcry_sexp_release (key_public);
2633       key_public = NULL;
2634       xfree (cardsn);
2635       if (err)
2636         goto out;
2637
2638       key_counter++;
2639     }
2640
2641
2642   /* Prepare buffer for key name construction.  */
2643   {
2644     char *dname;
2645
2646     dname = make_filename (opt.homedir, GNUPG_PRIVATE_KEYS_DIR, NULL);
2647     if (!dname)
2648       {
2649         err = gpg_err_code_from_syserror ();
2650         goto out;
2651       }
2652
2653     key_fname = xtrymalloc (strlen (dname) + 1 + 40 + 4 + 1);
2654     if (!key_fname)
2655       {
2656         err = gpg_err_code_from_syserror ();
2657         xfree (dname);
2658         goto out;
2659       }
2660     fnameptr = stpcpy (stpcpy (key_fname, dname), "/");
2661     xfree (dname);
2662   }
2663
2664   /* Then look at all the registered and non-disabled keys. */
2665   err = open_control_file (&cf, 0);
2666   if (err)
2667     goto out;
2668
2669   while (!read_control_file_item (cf))
2670     {
2671       if (!cf->item.valid)
2672         continue; /* Should not happen.  */
2673       if (cf->item.disabled)
2674         continue;
2675       assert (strlen (cf->item.hexgrip) == 40);
2676
2677       stpcpy (stpcpy (fnameptr, cf->item.hexgrip), ".key");
2678
2679       /* Read file content.  */
2680       {
2681         unsigned char *buffer;
2682         size_t buffer_n;
2683
2684         err = file_to_buffer (key_fname, &buffer, &buffer_n);
2685         if (err)
2686           {
2687             log_error ("%s:%d: key '%s' skipped: %s\n",
2688                        cf->fname, cf->lnr, cf->item.hexgrip,
2689                        gpg_strerror (err));
2690             continue;
2691           }
2692
2693         err = gcry_sexp_sscan (&key_secret, NULL, (char*)buffer, buffer_n);
2694         xfree (buffer);
2695         if (err)
2696           goto out;
2697       }
2698
2699       {
2700         char *key_type = NULL;
2701
2702         err = sexp_extract_identifier (key_secret, &key_type);
2703         if (err)
2704           goto out;
2705
2706         err = ssh_key_type_lookup (NULL, key_type, &spec);
2707         xfree (key_type);
2708         if (err)
2709           goto out;
2710       }
2711
2712       err = ssh_send_key_public (key_blobs, key_secret, NULL);
2713       if (err)
2714         goto out;
2715       gcry_sexp_release (key_secret);
2716       key_secret = NULL;
2717
2718       key_counter++;
2719     }
2720   err = 0;
2721
2722   ret = es_fseek (key_blobs, 0, SEEK_SET);
2723   if (ret)
2724     {
2725       err = gpg_error_from_syserror ();
2726       goto out;
2727     }
2728
2729  out:
2730   /* Send response.  */
2731
2732   gcry_sexp_release (key_secret);
2733   gcry_sexp_release (key_public);
2734
2735   if (!err)
2736     {
2737       ret_err = stream_write_byte (response, SSH_RESPONSE_IDENTITIES_ANSWER);
2738       if (!ret_err)
2739         ret_err = stream_write_uint32 (response, key_counter);
2740       if (!ret_err)
2741         ret_err = stream_copy (response, key_blobs);
2742     }
2743   else
2744     {
2745       ret_err = stream_write_byte (response, SSH_RESPONSE_FAILURE);
2746     }
2747
2748   es_fclose (key_blobs);
2749   close_control_file (cf);
2750   xfree (key_fname);
2751
2752   return ret_err;
2753 }
2754
2755
2756 /* This function hashes the data contained in DATA of size DATA_N
2757    according to the message digest algorithm specified by MD_ALGORITHM
2758    and writes the message digest to HASH, which needs to large enough
2759    for the digest.  */
2760 static gpg_error_t
2761 data_hash (unsigned char *data, size_t data_n,
2762            int md_algorithm, unsigned char *hash)
2763 {
2764   gcry_md_hash_buffer (md_algorithm, hash, data, data_n);
2765
2766   return 0;
2767 }
2768
2769
2770 /* This function signs the data described by CTRL. If HASH is is not
2771    NULL, (HASH,HASHLEN) overrides the hash stored in CTRL.  This is to
2772    allow the use of signature algorithms that implement the hashing
2773    internally (e.g. Ed25519).  On success the created signature is
2774    stored in ssh format at R_SIG and it's size at R_SIGLEN; the caller
2775    must use es_free to releaase this memory.  */
2776 static gpg_error_t
2777 data_sign (ctrl_t ctrl, ssh_key_type_spec_t *spec,
2778            const void *hash, size_t hashlen,
2779            unsigned char **r_sig, size_t *r_siglen)
2780 {
2781   gpg_error_t err;
2782   gcry_sexp_t signature_sexp = NULL;
2783   estream_t stream = NULL;
2784   void *blob = NULL;
2785   size_t bloblen;
2786   char hexgrip[40+1];
2787
2788   *r_sig = NULL;
2789   *r_siglen = 0;
2790
2791   /* Quick check to see whether we have a valid keygrip and convert it
2792      to hex.  */
2793   if (!ctrl->have_keygrip)
2794     {
2795       err = gpg_error (GPG_ERR_NO_SECKEY);
2796       goto out;
2797     }
2798   bin2hex (ctrl->keygrip, 20, hexgrip);
2799
2800   /* Ask for confirmation if needed.  */
2801   if (confirm_flag_from_sshcontrol (hexgrip))
2802     {
2803       gcry_sexp_t key;
2804       char *fpr, *prompt;
2805       char *comment = NULL;
2806
2807       err = agent_raw_key_from_file (ctrl, ctrl->keygrip, &key);
2808       if (err)
2809         goto out;
2810       err = ssh_get_fingerprint_string (key, &fpr);
2811       if (!err)
2812         {
2813           gcry_sexp_t tmpsxp = gcry_sexp_find_token (key, "comment", 0);
2814           if (tmpsxp)
2815             comment = gcry_sexp_nth_string (tmpsxp, 1);
2816           gcry_sexp_release (tmpsxp);
2817         }
2818       gcry_sexp_release (key);
2819       if (err)
2820         goto out;
2821       prompt = xtryasprintf (_("An ssh process requested the use of key%%0A"
2822                                "  %s%%0A"
2823                                "  (%s)%%0A"
2824                                "Do you want to allow this?"),
2825                              fpr, comment? comment:"");
2826       xfree (fpr);
2827       gcry_free (comment);
2828       err = agent_get_confirmation (ctrl, prompt, _("Allow"), _("Deny"), 0);
2829       xfree (prompt);
2830       if (err)
2831         goto out;
2832     }
2833
2834   /* Create signature.  */
2835   ctrl->use_auth_call = 1;
2836   err = agent_pksign_do (ctrl, NULL,
2837                          _("Please enter the passphrase "
2838                            "for the ssh key%%0A  %F%%0A  (%c)"),
2839                          &signature_sexp,
2840                          CACHE_MODE_SSH, ttl_from_sshcontrol,
2841                          hash, hashlen);
2842   ctrl->use_auth_call = 0;
2843   if (err)
2844     goto out;
2845
2846   stream = es_fopenmem (0, "r+b");
2847   if (!stream)
2848     {
2849       err = gpg_error_from_syserror ();
2850       goto out;
2851     }
2852
2853   err = stream_write_cstring (stream, spec->ssh_identifier);
2854   if (err)
2855     goto out;
2856
2857   err = spec->signature_encoder (spec, stream, signature_sexp);
2858   if (err)
2859     goto out;
2860
2861   err = es_fclose_snatch (stream, &blob, &bloblen);
2862   if (err)
2863     goto out;
2864   stream = NULL;
2865
2866   *r_sig = blob; blob = NULL;
2867   *r_siglen = bloblen;
2868
2869  out:
2870   xfree (blob);
2871   es_fclose (stream);
2872   gcry_sexp_release (signature_sexp);
2873
2874   return err;
2875 }
2876
2877
2878 /* Handler for the "sign_request" command.  */
2879 static gpg_error_t
2880 ssh_handler_sign_request (ctrl_t ctrl, estream_t request, estream_t response)
2881 {
2882   gcry_sexp_t key = NULL;
2883   ssh_key_type_spec_t spec;
2884   unsigned char hash[MAX_DIGEST_LEN];
2885   unsigned int hash_n;
2886   unsigned char key_grip[20];
2887   unsigned char *key_blob = NULL;
2888   u32 key_blob_size;
2889   unsigned char *data = NULL;
2890   unsigned char *sig = NULL;
2891   size_t sig_n;
2892   u32 data_size;
2893   u32 flags;
2894   gpg_error_t err;
2895   gpg_error_t ret_err;
2896   int hash_algo;
2897
2898   /* Receive key.  */
2899
2900   err = stream_read_string (request, 0, &key_blob, &key_blob_size);
2901   if (err)
2902     goto out;
2903
2904   err = ssh_read_key_public_from_blob (key_blob, key_blob_size, &key, &spec);
2905   if (err)
2906     goto out;
2907
2908   /* Receive data to sign.  */
2909   err = stream_read_string (request, 0, &data, &data_size);
2910   if (err)
2911     goto out;
2912
2913   /* FIXME?  */
2914   err = stream_read_uint32 (request, &flags);
2915   if (err)
2916     goto out;
2917
2918   hash_algo = spec.hash_algo;
2919   if (!hash_algo)
2920     hash_algo = GCRY_MD_SHA1;  /* Use the default.  */
2921   ctrl->digest.algo = hash_algo;
2922   if ((spec.flags & SPEC_FLAG_USE_PKCS1V2))
2923     ctrl->digest.raw_value = 0;
2924   else
2925     ctrl->digest.raw_value = 1;
2926
2927   /* Calculate key grip.  */
2928   err = ssh_key_grip (key, key_grip);
2929   if (err)
2930     goto out;
2931   ctrl->have_keygrip = 1;
2932   memcpy (ctrl->keygrip, key_grip, 20);
2933
2934   /* Hash data unless we use EdDSA.  */
2935   if ((spec.flags & SPEC_FLAG_IS_EdDSA))
2936     {
2937       ctrl->digest.valuelen = 0;
2938     }
2939   else
2940     {
2941       hash_n = gcry_md_get_algo_dlen (hash_algo);
2942       if (!hash_n)
2943         {
2944           err = gpg_error (GPG_ERR_INTERNAL);
2945           goto out;
2946         }
2947       err = data_hash (data, data_size, hash_algo, hash);
2948       if (err)
2949         goto out;
2950       memcpy (ctrl->digest.value, hash, hash_n);
2951       ctrl->digest.valuelen = hash_n;
2952     }
2953
2954   /* Sign data.  */
2955   if ((spec.flags & SPEC_FLAG_IS_EdDSA))
2956     err = data_sign (ctrl, &spec, data, data_size, &sig, &sig_n);
2957   else
2958     err = data_sign (ctrl, &spec, NULL, 0, &sig, &sig_n);
2959
2960  out:
2961   /* Done.  */
2962   if (!err)
2963     {
2964       ret_err = stream_write_byte (response, SSH_RESPONSE_SIGN_RESPONSE);
2965       if (ret_err)
2966         goto leave;
2967       ret_err = stream_write_string (response, sig, sig_n);
2968       if (ret_err)
2969         goto leave;
2970     }
2971   else
2972     {
2973       log_error ("ssh sign request failed: %s <%s>\n",
2974                  gpg_strerror (err), gpg_strsource (err));
2975       ret_err = stream_write_byte (response, SSH_RESPONSE_FAILURE);
2976       if (ret_err)
2977         goto leave;
2978     }
2979
2980  leave:
2981
2982   gcry_sexp_release (key);
2983   xfree (key_blob);
2984   xfree (data);
2985   es_free (sig);
2986
2987   return ret_err;
2988 }
2989
2990
2991 /* This function extracts the comment contained in the key
2992    s-expression KEY and stores a copy in COMMENT.  Returns usual error
2993    code.  */
2994 static gpg_error_t
2995 ssh_key_extract_comment (gcry_sexp_t key, char **r_comment)
2996 {
2997   gcry_sexp_t comment_list;
2998
2999   *r_comment = NULL;
3000
3001   comment_list = gcry_sexp_find_token (key, "comment", 0);
3002   if (!comment_list)
3003     return gpg_error (GPG_ERR_INV_SEXP);
3004
3005   *r_comment = gcry_sexp_nth_string (comment_list, 1);
3006   gcry_sexp_release (comment_list);
3007   if (!*r_comment)
3008     return gpg_error (GPG_ERR_INV_SEXP);
3009
3010   return 0;
3011 }
3012
3013
3014 /* This function converts the key contained in the S-Expression KEY
3015    into a buffer, which is protected by the passphrase PASSPHRASE.
3016    Returns usual error code.  */
3017 static gpg_error_t
3018 ssh_key_to_protected_buffer (gcry_sexp_t key, const char *passphrase,
3019                              unsigned char **buffer, size_t *buffer_n)
3020 {
3021   unsigned char *buffer_new;
3022   unsigned int buffer_new_n;
3023   gpg_error_t err;
3024
3025   err = 0;
3026   buffer_new_n = gcry_sexp_sprint (key, GCRYSEXP_FMT_CANON, NULL, 0);
3027   buffer_new = xtrymalloc_secure (buffer_new_n);
3028   if (! buffer_new)
3029     {
3030       err = gpg_error_from_syserror ();
3031       goto out;
3032     }
3033
3034   gcry_sexp_sprint (key, GCRYSEXP_FMT_CANON, buffer_new, buffer_new_n);
3035   /* FIXME: guarantee?  */
3036
3037   err = agent_protect (buffer_new, passphrase, buffer, buffer_n, 0);
3038
3039  out:
3040
3041   xfree (buffer_new);
3042
3043   return err;
3044 }
3045
3046
3047
3048 /* Callback function to compare the first entered PIN with the one
3049    currently being entered. */
3050 static int
3051 reenter_compare_cb (struct pin_entry_info_s *pi)
3052 {
3053   const char *pin1 = pi->check_cb_arg;
3054
3055   if (!strcmp (pin1, pi->pin))
3056     return 0; /* okay */
3057   return -1;
3058 }
3059
3060
3061 /* Store the ssh KEY into our local key storage and protect it after
3062    asking for a passphrase.  Cache that passphrase.  TTL is the
3063    maximum caching time for that key.  If the key already exists in
3064    our key storage, don't do anything.  When entering a new key also
3065    add an entry to the sshcontrol file.  */
3066 static gpg_error_t
3067 ssh_identity_register (ctrl_t ctrl, ssh_key_type_spec_t *spec,
3068                        gcry_sexp_t key, int ttl, int confirm)
3069 {
3070   gpg_error_t err;
3071   unsigned char key_grip_raw[20];
3072   char key_grip[41];
3073   unsigned char *buffer = NULL;
3074   size_t buffer_n;
3075   char *description = NULL;
3076   const char *description2 = _("Please re-enter this passphrase");
3077   char *comment = NULL;
3078   char *key_fpr = NULL;
3079   const char *initial_errtext = NULL;
3080   unsigned int i;
3081   struct pin_entry_info_s *pi = NULL, *pi2;
3082
3083   err = ssh_key_grip (key, key_grip_raw);
3084   if (err)
3085     goto out;
3086
3087   /* Check whether the key is already in our key storage.  Don't do
3088      anything then.  */
3089   if ( !agent_key_available (key_grip_raw) )
3090     goto out; /* Yes, key is available.  */
3091
3092   err = ssh_get_fingerprint_string (key, &key_fpr);
3093   if (err)
3094     goto out;
3095
3096   err = ssh_key_extract_comment (key, &comment);
3097   if (err)
3098     goto out;
3099
3100   if ( asprintf (&description,
3101                  _("Please enter a passphrase to protect"
3102                    " the received secret key%%0A"
3103                    "   %s%%0A"
3104                    "   %s%%0A"
3105                    "within gpg-agent's key storage"),
3106                  key_fpr, comment ? comment : "") < 0)
3107     {
3108       err = gpg_error_from_syserror ();
3109       goto out;
3110     }
3111
3112   pi = gcry_calloc_secure (2, sizeof (*pi) + 100 + 1);
3113   if (!pi)
3114     {
3115       err = gpg_error_from_syserror ();
3116       goto out;
3117     }
3118   pi2 = pi + (sizeof *pi + 100 + 1);
3119   pi->max_length = 100;
3120   pi->max_tries = 1;
3121   pi2->max_length = 100;
3122   pi2->max_tries = 1;
3123   pi2->check_cb = reenter_compare_cb;
3124   pi2->check_cb_arg = pi->pin;
3125
3126  next_try:
3127   err = agent_askpin (ctrl, description, NULL, initial_errtext, pi);
3128   initial_errtext = NULL;
3129   if (err)
3130     goto out;
3131
3132   /* Unless the passphrase is empty, ask to confirm it.  */
3133   if (pi->pin && *pi->pin)
3134     {
3135       err = agent_askpin (ctrl, description2, NULL, NULL, pi2);
3136       if (err == -1)
3137         { /* The re-entered one did not match and the user did not
3138              hit cancel. */
3139           initial_errtext = _("does not match - try again");
3140           goto next_try;
3141         }
3142     }
3143
3144   err = ssh_key_to_protected_buffer (key, pi->pin, &buffer, &buffer_n);
3145   if (err)
3146     goto out;
3147
3148   /* Store this key to our key storage.  */
3149   err = agent_write_private_key (key_grip_raw, buffer, buffer_n, 0);
3150   if (err)
3151     goto out;
3152
3153   /* Cache this passphrase. */
3154   for (i = 0; i < 20; i++)
3155     sprintf (key_grip + 2 * i, "%02X", key_grip_raw[i]);
3156
3157   err = agent_put_cache (key_grip, CACHE_MODE_SSH, pi->pin, ttl);
3158   if (err)
3159     goto out;
3160
3161   /* And add an entry to the sshcontrol file.  */
3162   err = add_control_entry (ctrl, spec, key_grip, key_fpr, ttl, confirm);
3163
3164
3165  out:
3166   if (pi && pi->max_length)
3167     wipememory (pi->pin, pi->max_length);
3168   xfree (pi);
3169   xfree (buffer);
3170   xfree (comment);
3171   xfree (key_fpr);
3172   xfree (description);
3173
3174   return err;
3175 }
3176
3177
3178 /* This function removes the key contained in the S-Expression KEY
3179    from the local key storage, in case it exists there.  Returns usual
3180    error code.  FIXME: this function is a stub.  */
3181 static gpg_error_t
3182 ssh_identity_drop (gcry_sexp_t key)
3183 {
3184   unsigned char key_grip[21] = { 0 };
3185   gpg_error_t err;
3186
3187   err = ssh_key_grip (key, key_grip);
3188   if (err)
3189     goto out;
3190
3191   key_grip[sizeof (key_grip) - 1] = 0;
3192
3193   /* FIXME: What to do here - forgetting the passphrase or deleting
3194      the key from key cache?  */
3195
3196  out:
3197
3198   return err;
3199 }
3200
3201 /* Handler for the "add_identity" command.  */
3202 static gpg_error_t
3203 ssh_handler_add_identity (ctrl_t ctrl, estream_t request, estream_t response)
3204 {
3205   gpg_error_t ret_err;
3206   ssh_key_type_spec_t spec;
3207   gpg_error_t err;
3208   gcry_sexp_t key;
3209   unsigned char b;
3210   int confirm;
3211   int ttl;
3212
3213   confirm = 0;
3214   key = NULL;
3215   ttl = 0;
3216
3217   /* FIXME?  */
3218   err = ssh_receive_key (request, &key, 1, 1, &spec);
3219   if (err)
3220     goto out;
3221
3222   while (1)
3223     {
3224       err = stream_read_byte (request, &b);
3225       if (gpg_err_code (err) == GPG_ERR_EOF)
3226         {
3227           err = 0;
3228           break;
3229         }
3230
3231       switch (b)
3232         {
3233         case SSH_OPT_CONSTRAIN_LIFETIME:
3234           {
3235             u32 n = 0;
3236
3237             err = stream_read_uint32 (request, &n);
3238             if (! err)
3239               ttl = n;
3240             break;
3241           }
3242
3243         case SSH_OPT_CONSTRAIN_CONFIRM:
3244           {
3245             confirm = 1;
3246             break;
3247           }
3248
3249         default:
3250           /* FIXME: log/bad?  */
3251           break;
3252         }
3253     }
3254   if (err)
3255     goto out;
3256
3257   err = ssh_identity_register (ctrl, &spec, key, ttl, confirm);
3258
3259  out:
3260
3261   gcry_sexp_release (key);
3262
3263   if (! err)
3264     ret_err = stream_write_byte (response, SSH_RESPONSE_SUCCESS);
3265   else
3266     ret_err = stream_write_byte (response, SSH_RESPONSE_FAILURE);
3267
3268   return ret_err;
3269 }
3270
3271 /* Handler for the "remove_identity" command.  */
3272 static gpg_error_t
3273 ssh_handler_remove_identity (ctrl_t ctrl,
3274                              estream_t request, estream_t response)
3275 {
3276   unsigned char *key_blob;
3277   u32 key_blob_size;
3278   gcry_sexp_t key;
3279   gpg_error_t ret_err;
3280   gpg_error_t err;
3281
3282   (void)ctrl;
3283
3284   /* Receive key.  */
3285
3286   key_blob = NULL;
3287   key = NULL;
3288
3289   err = stream_read_string (request, 0, &key_blob, &key_blob_size);
3290   if (err)
3291     goto out;
3292
3293   err = ssh_read_key_public_from_blob (key_blob, key_blob_size, &key, NULL);
3294   if (err)
3295     goto out;
3296
3297   err = ssh_identity_drop (key);
3298
3299  out:
3300
3301   xfree (key_blob);
3302   gcry_sexp_release (key);
3303
3304   if (! err)
3305     ret_err = stream_write_byte (response, SSH_RESPONSE_SUCCESS);
3306   else
3307     ret_err = stream_write_byte (response, SSH_RESPONSE_FAILURE);
3308
3309   return ret_err;
3310 }
3311
3312 /* FIXME: stub function.  Actually useful?  */
3313 static gpg_error_t
3314 ssh_identities_remove_all (void)
3315 {
3316   gpg_error_t err;
3317
3318   err = 0;
3319
3320   /* FIXME: shall we remove _all_ cache entries or only those
3321      registered through the ssh emulation?  */
3322
3323   return err;
3324 }
3325
3326 /* Handler for the "remove_all_identities" command.  */
3327 static gpg_error_t
3328 ssh_handler_remove_all_identities (ctrl_t ctrl,
3329                                    estream_t request, estream_t response)
3330 {
3331   gpg_error_t ret_err;
3332   gpg_error_t err;
3333
3334   (void)ctrl;
3335   (void)request;
3336
3337   err = ssh_identities_remove_all ();
3338
3339   if (! err)
3340     ret_err = stream_write_byte (response, SSH_RESPONSE_SUCCESS);
3341   else
3342     ret_err = stream_write_byte (response, SSH_RESPONSE_FAILURE);
3343
3344   return ret_err;
3345 }
3346
3347 /* Lock agent?  FIXME: stub function.  */
3348 static gpg_error_t
3349 ssh_lock (void)
3350 {
3351   gpg_error_t err;
3352
3353   /* FIXME */
3354   log_error ("ssh-agent's lock command is not implemented\n");
3355   err = 0;
3356
3357   return err;
3358 }
3359
3360 /* Unock agent?  FIXME: stub function.  */
3361 static gpg_error_t
3362 ssh_unlock (void)
3363 {
3364   gpg_error_t err;
3365
3366   log_error ("ssh-agent's unlock command is not implemented\n");
3367   err = 0;
3368
3369   return err;
3370 }
3371
3372 /* Handler for the "lock" command.  */
3373 static gpg_error_t
3374 ssh_handler_lock (ctrl_t ctrl, estream_t request, estream_t response)
3375 {
3376   gpg_error_t ret_err;
3377   gpg_error_t err;
3378
3379   (void)ctrl;
3380   (void)request;
3381
3382   err = ssh_lock ();
3383
3384   if (! err)
3385     ret_err = stream_write_byte (response, SSH_RESPONSE_SUCCESS);
3386   else
3387     ret_err = stream_write_byte (response, SSH_RESPONSE_FAILURE);
3388
3389   return ret_err;
3390 }
3391
3392 /* Handler for the "unlock" command.  */
3393 static gpg_error_t
3394 ssh_handler_unlock (ctrl_t ctrl, estream_t request, estream_t response)
3395 {
3396   gpg_error_t ret_err;
3397   gpg_error_t err;
3398
3399   (void)ctrl;
3400   (void)request;
3401
3402   err = ssh_unlock ();
3403
3404   if (! err)
3405     ret_err = stream_write_byte (response, SSH_RESPONSE_SUCCESS);
3406   else
3407     ret_err = stream_write_byte (response, SSH_RESPONSE_FAILURE);
3408
3409   return ret_err;
3410 }
3411
3412 \f
3413
3414 /* Return the request specification for the request identified by TYPE
3415    or NULL in case the requested request specification could not be
3416    found.  */
3417 static ssh_request_spec_t *
3418 request_spec_lookup (int type)
3419 {
3420   ssh_request_spec_t *spec;
3421   unsigned int i;
3422
3423   for (i = 0; i < DIM (request_specs); i++)
3424     if (request_specs[i].type == type)
3425       break;
3426   if (i == DIM (request_specs))
3427     {
3428       if (opt.verbose)
3429         log_info ("ssh request %u is not supported\n", type);
3430       spec = NULL;
3431     }
3432   else
3433     spec = request_specs + i;
3434
3435   return spec;
3436 }
3437
3438 /* Process a single request.  The request is read from and the
3439    response is written to STREAM_SOCK.  Uses CTRL as context.  Returns
3440    zero in case of success, non zero in case of failure.  */
3441 static int
3442 ssh_request_process (ctrl_t ctrl, estream_t stream_sock)
3443 {
3444   ssh_request_spec_t *spec;
3445   estream_t response = NULL;
3446   estream_t request = NULL;
3447   unsigned char request_type;
3448   gpg_error_t err;
3449   int send_err = 0;
3450   int ret;
3451   unsigned char *request_data = NULL;
3452   u32 request_data_size;
3453   u32 response_size;
3454
3455   /* Create memory streams for request/response data.  The entire
3456      request will be stored in secure memory, since it might contain
3457      secret key material.  The response does not have to be stored in
3458      secure memory, since we never give out secret keys.
3459
3460      Note: we only have little secure memory, but there is NO
3461      possibility of DoS here; only trusted clients are allowed to
3462      connect to the agent.  What could happen is that the agent
3463      returns out-of-secure-memory errors on requests in case the
3464      agent's owner floods his own agent with many large messages.
3465      -moritz */
3466
3467   /* Retrieve request.  */
3468   err = stream_read_string (stream_sock, 1, &request_data, &request_data_size);
3469   if (err)
3470     goto out;
3471
3472   if (opt.verbose > 1)
3473     log_info ("received ssh request of length %u\n",
3474               (unsigned int)request_data_size);
3475
3476   if (! request_data_size)
3477     {
3478       send_err = 1;
3479       goto out;
3480       /* Broken request; FIXME.  */
3481     }
3482
3483   request_type = request_data[0];
3484   spec = request_spec_lookup (request_type);
3485   if (! spec)
3486     {
3487       send_err = 1;
3488       goto out;
3489       /* Unknown request; FIXME.  */
3490     }
3491
3492   if (spec->secret_input)
3493     request = es_mopen (NULL, 0, 0, 1, realloc_secure, gcry_free, "r+b");
3494   else
3495     request = es_mopen (NULL, 0, 0, 1, gcry_realloc, gcry_free, "r+b");
3496   if (! request)
3497     {
3498       err = gpg_error_from_syserror ();
3499       goto out;
3500     }
3501   ret = es_setvbuf (request, NULL, _IONBF, 0);
3502   if (ret)
3503     {
3504       err = gpg_error_from_syserror ();
3505       goto out;
3506     }
3507   err = stream_write_data (request, request_data + 1, request_data_size - 1);
3508   if (err)
3509     goto out;
3510   es_rewind (request);
3511
3512   response = es_fopenmem (0, "r+b");
3513   if (! response)
3514     {
3515       err = gpg_error_from_syserror ();
3516       goto out;
3517     }
3518
3519   if (opt.verbose)
3520     log_info ("ssh request handler for %s (%u) started\n",
3521                spec->identifier, spec->type);
3522
3523   err = (*spec->handler) (ctrl, request, response);
3524
3525   if (opt.verbose)
3526     {
3527       if (err)
3528         log_info ("ssh request handler for %s (%u) failed: %s\n",
3529                   spec->identifier, spec->type, gpg_strerror (err));
3530       else
3531         log_info ("ssh request handler for %s (%u) ready\n",
3532                   spec->identifier, spec->type);
3533     }
3534
3535   if (err)
3536     {
3537       send_err = 1;
3538       goto out;
3539     }
3540
3541   response_size = es_ftell (response);
3542   if (opt.verbose > 1)
3543     log_info ("sending ssh response of length %u\n",
3544               (unsigned int)response_size);
3545
3546   err = es_fseek (response, 0, SEEK_SET);
3547   if (err)
3548     {
3549       send_err = 1;
3550       goto out;
3551     }
3552
3553   err = stream_write_uint32 (stream_sock, response_size);
3554   if (err)
3555     {
3556       send_err = 1;
3557       goto out;
3558     }
3559
3560   err = stream_copy (stream_sock, response);
3561   if (err)
3562     goto out;
3563
3564   err = es_fflush (stream_sock);
3565   if (err)
3566     goto out;
3567
3568  out:
3569
3570   if (err && es_feof (stream_sock))
3571     log_error ("error occured while processing request: %s\n",
3572                gpg_strerror (err));
3573
3574   if (send_err)
3575     {
3576       if (opt.verbose > 1)
3577         log_info ("sending ssh error response\n");
3578       err = stream_write_uint32 (stream_sock, 1);
3579       if (err)
3580         goto leave;
3581       err = stream_write_byte (stream_sock, SSH_RESPONSE_FAILURE);
3582       if (err)
3583         goto leave;
3584     }
3585
3586  leave:
3587
3588   es_fclose (request);
3589   es_fclose (response);
3590   xfree (request_data);
3591
3592   return !!err;
3593 }
3594
3595
3596 /* Because the ssh protocol does not send us information about the
3597    current TTY setting, we use this function to use those from startup
3598    or those explictly set.  */
3599 static gpg_error_t
3600 setup_ssh_env (ctrl_t ctrl)
3601 {
3602   static const char *names[] =
3603     {"GPG_TTY", "DISPLAY", "TERM", "XAUTHORITY", "PINENTRY_USER_DATA", NULL};
3604   gpg_error_t err = 0;
3605   int idx;
3606   const char *value;
3607
3608   for (idx=0; !err && names[idx]; idx++)
3609       if ((value = session_env_getenv (opt.startup_env, names[idx])))
3610       err = session_env_setenv (ctrl->session_env, names[idx], value);
3611
3612   if (!err && !ctrl->lc_ctype && opt.startup_lc_ctype)
3613     if (!(ctrl->lc_ctype = xtrystrdup (opt.startup_lc_ctype)))
3614       err = gpg_error_from_syserror ();
3615
3616   if (!err && !ctrl->lc_messages && opt.startup_lc_messages)
3617     if (!(ctrl->lc_messages = xtrystrdup (opt.startup_lc_messages)))
3618       err = gpg_error_from_syserror ();
3619
3620   if (err)
3621     log_error ("error setting default session environment: %s\n",
3622                gpg_strerror (err));
3623
3624   return err;
3625 }
3626
3627
3628 /* Start serving client on SOCK_CLIENT.  */
3629 void
3630 start_command_handler_ssh (ctrl_t ctrl, gnupg_fd_t sock_client)
3631 {
3632   estream_t stream_sock = NULL;
3633   gpg_error_t err;
3634   int ret;
3635
3636   err = setup_ssh_env (ctrl);
3637   if (err)
3638     goto out;
3639
3640   /* Create stream from socket.  */
3641   stream_sock = es_fdopen (FD2INT(sock_client), "r+");
3642   if (!stream_sock)
3643     {
3644       err = gpg_error_from_syserror ();
3645       log_error (_("failed to create stream from socket: %s\n"),
3646                  gpg_strerror (err));
3647       goto out;
3648     }
3649   /* We have to disable the estream buffering, because the estream
3650      core doesn't know about secure memory.  */
3651   ret = es_setvbuf (stream_sock, NULL, _IONBF, 0);
3652   if (ret)
3653     {
3654       err = gpg_error_from_syserror ();
3655       log_error ("failed to disable buffering "
3656                  "on socket stream: %s\n", gpg_strerror (err));
3657       goto out;
3658     }
3659
3660   /* Main processing loop. */
3661   while ( !ssh_request_process (ctrl, stream_sock) )
3662     {
3663       /* Check wether we have reached EOF before trying to read
3664          another request.  */
3665       int c;
3666
3667       c = es_fgetc (stream_sock);
3668       if (c == EOF)
3669         break;
3670       es_ungetc (c, stream_sock);
3671     }
3672
3673   /* Reset the SCD in case it has been used. */
3674   agent_reset_scd (ctrl);
3675
3676
3677  out:
3678   if (stream_sock)
3679     es_fclose (stream_sock);
3680 }
3681
3682
3683 #ifdef HAVE_W32_SYSTEM
3684 /* Serve one ssh-agent request.  This is used for the Putty support.
3685    REQUEST is the the mmapped memory which may be accessed up to a
3686    length of MAXREQLEN.  Returns 0 on success which also indicates
3687    that a valid SSH response message is now in REQUEST.  */
3688 int
3689 serve_mmapped_ssh_request (ctrl_t ctrl,
3690                            unsigned char *request, size_t maxreqlen)
3691 {
3692   gpg_error_t err;
3693   int send_err = 0;
3694   int valid_response = 0;
3695   ssh_request_spec_t *spec;
3696   u32 msglen;
3697   estream_t request_stream, response_stream;
3698
3699   if (setup_ssh_env (ctrl))
3700     goto leave; /* Error setting up the environment.  */
3701
3702   if (maxreqlen < 5)
3703     goto leave; /* Caller error.  */
3704
3705   msglen = uint32_construct (request[0], request[1], request[2], request[3]);
3706   if (msglen < 1 || msglen > maxreqlen - 4)
3707     {
3708       log_error ("ssh message len (%u) out of range", (unsigned int)msglen);
3709       goto leave;
3710     }
3711
3712   spec = request_spec_lookup (request[4]);
3713   if (!spec)
3714     {
3715       send_err = 1;  /* Unknown request type.  */
3716       goto leave;
3717     }
3718
3719   /* Create a stream object with the data part of the request.  */
3720   if (spec->secret_input)
3721     request_stream = es_mopen (NULL, 0, 0, 1, realloc_secure, gcry_free, "r+");
3722   else
3723     request_stream = es_mopen (NULL, 0, 0, 1, gcry_realloc, gcry_free, "r+");
3724   if (!request_stream)
3725     {
3726       err = gpg_error_from_syserror ();
3727       goto leave;
3728     }
3729   /* We have to disable the estream buffering, because the estream
3730      core doesn't know about secure memory.  */
3731   if (es_setvbuf (request_stream, NULL, _IONBF, 0))
3732     {
3733       err = gpg_error_from_syserror ();
3734       goto leave;
3735     }
3736   /* Copy the request to the stream but omit the request type.  */
3737   err = stream_write_data (request_stream, request + 5, msglen - 1);
3738   if (err)
3739     goto leave;
3740   es_rewind (request_stream);
3741
3742   response_stream = es_fopenmem (0, "r+b");
3743   if (!response_stream)
3744     {
3745       err = gpg_error_from_syserror ();
3746       goto leave;
3747     }
3748
3749   if (opt.verbose)
3750     log_info ("ssh request handler for %s (%u) started\n",
3751                spec->identifier, spec->type);
3752
3753   err = (*spec->handler) (ctrl, request_stream, response_stream);
3754
3755   if (opt.verbose)
3756     {
3757       if (err)
3758         log_info ("ssh request handler for %s (%u) failed: %s\n",
3759                   spec->identifier, spec->type, gpg_strerror (err));
3760       else
3761         log_info ("ssh request handler for %s (%u) ready\n",
3762                   spec->identifier, spec->type);
3763     }
3764
3765   es_fclose (request_stream);
3766   request_stream = NULL;
3767
3768   if (err)
3769     {
3770       send_err = 1;
3771       goto leave;
3772     }
3773
3774   /* Put the response back into the mmapped buffer.  */
3775   {
3776     void *response_data;
3777     size_t response_size;
3778
3779     /* NB: In contrast to the request-stream, the response stream
3780        includes the the message type byte.  */
3781     if (es_fclose_snatch (response_stream, &response_data, &response_size))
3782       {
3783         log_error ("snatching ssh response failed: %s",
3784                    gpg_strerror (gpg_error_from_syserror ()));
3785         send_err = 1; /* Ooops.  */
3786         goto leave;
3787       }
3788
3789     if (opt.verbose > 1)
3790       log_info ("sending ssh response of length %u\n",
3791                 (unsigned int)response_size);
3792     if (response_size > maxreqlen - 4)
3793       {
3794         log_error ("invalid length of the ssh response: %s",
3795                    gpg_strerror (GPG_ERR_INTERNAL));
3796         es_free (response_data);
3797         send_err = 1;
3798         goto leave;
3799       }
3800
3801     request[0] = response_size >> 24;
3802     request[1] = response_size >> 16;
3803     request[2] = response_size >>  8;
3804     request[3] = response_size >>  0;
3805     memcpy (request+4, response_data, response_size);
3806     es_free (response_data);
3807     valid_response = 1;
3808   }
3809
3810  leave:
3811   if (send_err)
3812     {
3813       request[0] = 0;
3814       request[1] = 0;
3815       request[2] = 0;
3816       request[3] = 1;
3817       request[4] = SSH_RESPONSE_FAILURE;
3818       valid_response = 1;
3819     }
3820
3821   /* Reset the SCD in case it has been used. */
3822   agent_reset_scd (ctrl);
3823
3824   return valid_response? 0 : -1;
3825 }
3826 #endif /*HAVE_W32_SYSTEM*/