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