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