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