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