1 /* command-ssh.c - gpg-agent's ssh-agent emulation layer
2 * Copyright (C) 2004-2006, 2009, 2012 Free Software Foundation, Inc.
3 * Copyright (C) 2004-2006, 2009, 2012-2014 Werner Koch
5 * This file is part of GnuPG.
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.
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.
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/>.
21 /* Only v2 of the ssh-agent protocol is implemented. Relevant RFCs
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
30 The protocol for the agent is defined in OpenSSH's PROTOCL.agent
40 #include <sys/types.h>
48 #include "ssh-utils.h"
54 #define SSH_REQUEST_REQUEST_IDENTITIES 11
55 #define SSH_REQUEST_SIGN_REQUEST 13
56 #define SSH_REQUEST_ADD_IDENTITY 17
57 #define SSH_REQUEST_REMOVE_IDENTITY 18
58 #define SSH_REQUEST_REMOVE_ALL_IDENTITIES 19
59 #define SSH_REQUEST_LOCK 22
60 #define SSH_REQUEST_UNLOCK 23
61 #define SSH_REQUEST_ADD_ID_CONSTRAINED 25
64 #define SSH_OPT_CONSTRAIN_LIFETIME 1
65 #define SSH_OPT_CONSTRAIN_CONFIRM 2
68 #define SSH_RESPONSE_SUCCESS 6
69 #define SSH_RESPONSE_FAILURE 5
70 #define SSH_RESPONSE_IDENTITIES_ANSWER 12
71 #define SSH_RESPONSE_SIGN_RESPONSE 14
73 /* Other constants. */
74 #define SSH_DSA_SIGNATURE_PADDING 20
75 #define SSH_DSA_SIGNATURE_ELEMS 2
76 #define SPEC_FLAG_USE_PKCS1V2 (1 << 0)
77 #define SPEC_FLAG_IS_ECDSA (1 << 1)
78 #define SPEC_FLAG_IS_EdDSA (1 << 2) /*(lowercase 'd' on purpose.)*/
79 #define SPEC_FLAG_WITH_CERT (1 << 7)
81 /* The name of the control file. */
82 #define SSH_CONTROL_FILE_NAME "sshcontrol"
84 /* The blurb we put into the header of a newly created control file. */
85 static const char sshcontrolblurb[] =
86 "# List of allowed ssh keys. Only keys present in this file are used\n"
87 "# in the SSH protocol. The ssh-add tool may add new entries to this\n"
88 "# file to enable them; you may also add them manually. Comment\n"
89 "# lines, like this one, as well as empty lines are ignored. Lines do\n"
90 "# have a certain length limit but this is not serious limitation as\n"
91 "# the format of the entries is fixed and checked by gpg-agent. A\n"
92 "# non-comment line starts with optional white spaces, followed by the\n"
93 "# keygrip of the key given as 40 hex digits, optionally followed by a\n"
94 "# caching TTL in seconds, and another optional field for arbitrary\n"
95 "# flags. Prepend the keygrip with an '!' mark to disable it.\n"
101 /* Return a new uint32 with b0 being the most significant byte and b3
102 being the least significant byte. */
103 #define uint32_construct(b0, b1, b2, b3) \
104 ((b0 << 24) | (b1 << 16) | (b2 << 8) | b3)
113 /* Type for a request handler. */
114 typedef gpg_error_t (*ssh_request_handler_t) (ctrl_t ctrl,
119 struct ssh_key_type_spec;
120 typedef struct ssh_key_type_spec ssh_key_type_spec_t;
122 /* Type, which is used for associating request handlers with the
123 appropriate request IDs. */
124 typedef struct ssh_request_spec
127 ssh_request_handler_t handler;
128 const char *identifier;
129 unsigned int secret_input;
130 } ssh_request_spec_t;
132 /* Type for "key modifier functions", which are necessary since
133 OpenSSH and GnuPG treat key material slightly different. A key
134 modifier is called right after a new key identity has been received
135 in order to "sanitize" the material. */
136 typedef gpg_error_t (*ssh_key_modifier_t) (const char *elems,
139 /* The encoding of a generated signature is dependent on the
140 algorithm; therefore algorithm specific signature encoding
141 functions are necessary. */
142 typedef gpg_error_t (*ssh_signature_encoder_t) (ssh_key_type_spec_t *spec,
143 estream_t signature_blob,
146 /* Type, which is used for boundling all the algorithm specific
147 information together in a single object. */
148 struct ssh_key_type_spec
150 /* Algorithm identifier as used by OpenSSH. */
151 const char *ssh_identifier;
153 /* Human readable name of the algorithm. */
156 /* Algorithm identifier as used by GnuPG. */
159 /* List of MPI names for secret keys; order matches the one of the
161 const char *elems_key_secret;
163 /* List of MPI names for public keys; order matches the one of the
165 const char *elems_key_public;
167 /* List of MPI names for signature data. */
168 const char *elems_signature;
170 /* List of MPI names for secret keys; order matches the one, which
171 is required by gpg-agent's key access layer. */
172 const char *elems_sexp_order;
174 /* Key modifier function. Key modifier functions are necessary in
175 order to fix any inconsistencies between the representation of
176 keys on the SSH and on the GnuPG side. */
177 ssh_key_modifier_t key_modifier;
179 /* Signature encoder function. Signature encoder functions are
180 necessary since the encoding of signatures depends on the used
182 ssh_signature_encoder_t signature_encoder;
184 /* The name of the ECC curve or NULL. */
185 const char *curve_name;
187 /* The hash algorithm to be used with this key. 0 for using the
196 /* Definition of an object to access the sshcontrol file. */
197 struct ssh_control_file_s
199 char *fname; /* Name of the file. */
200 FILE *fp; /* This is never NULL. */
201 int lnr; /* The current line number. */
203 int valid; /* True if the data of this structure is valid. */
204 int disabled; /* The item is disabled. */
205 int ttl; /* The TTL of the item. */
206 int confirm; /* The confirm flag is set. */
207 char hexgrip[40+1]; /* The hexgrip of the item (uppercase). */
213 static gpg_error_t ssh_handler_request_identities (ctrl_t ctrl,
216 static gpg_error_t ssh_handler_sign_request (ctrl_t ctrl,
219 static gpg_error_t ssh_handler_add_identity (ctrl_t ctrl,
222 static gpg_error_t ssh_handler_remove_identity (ctrl_t ctrl,
225 static gpg_error_t ssh_handler_remove_all_identities (ctrl_t ctrl,
228 static gpg_error_t ssh_handler_lock (ctrl_t ctrl,
231 static gpg_error_t ssh_handler_unlock (ctrl_t ctrl,
235 static gpg_error_t ssh_key_modifier_rsa (const char *elems, gcry_mpi_t *mpis);
236 static gpg_error_t ssh_signature_encoder_rsa (ssh_key_type_spec_t *spec,
237 estream_t signature_blob,
238 gcry_sexp_t signature);
239 static gpg_error_t ssh_signature_encoder_dsa (ssh_key_type_spec_t *spec,
240 estream_t signature_blob,
241 gcry_sexp_t signature);
242 static gpg_error_t ssh_signature_encoder_ecdsa (ssh_key_type_spec_t *spec,
243 estream_t signature_blob,
244 gcry_sexp_t signature);
245 static gpg_error_t ssh_signature_encoder_eddsa (ssh_key_type_spec_t *spec,
246 estream_t signature_blob,
247 gcry_sexp_t signature);
248 static gpg_error_t ssh_key_extract_comment (gcry_sexp_t key, char **comment);
252 /* Global variables. */
255 /* Associating request types with the corresponding request
258 static ssh_request_spec_t request_specs[] =
260 #define REQUEST_SPEC_DEFINE(id, name, secret_input) \
261 { SSH_REQUEST_##id, ssh_handler_##name, #name, secret_input }
263 REQUEST_SPEC_DEFINE (REQUEST_IDENTITIES, request_identities, 1),
264 REQUEST_SPEC_DEFINE (SIGN_REQUEST, sign_request, 0),
265 REQUEST_SPEC_DEFINE (ADD_IDENTITY, add_identity, 1),
266 REQUEST_SPEC_DEFINE (ADD_ID_CONSTRAINED, add_identity, 1),
267 REQUEST_SPEC_DEFINE (REMOVE_IDENTITY, remove_identity, 0),
268 REQUEST_SPEC_DEFINE (REMOVE_ALL_IDENTITIES, remove_all_identities, 0),
269 REQUEST_SPEC_DEFINE (LOCK, lock, 0),
270 REQUEST_SPEC_DEFINE (UNLOCK, unlock, 0)
271 #undef REQUEST_SPEC_DEFINE
275 /* Table holding key type specifications. */
276 static ssh_key_type_spec_t ssh_key_types[] =
279 "ssh-ed25519", "Ed25519", GCRY_PK_EDDSA, "qd", "q", "rs", "qd",
280 NULL, ssh_signature_encoder_eddsa,
281 "Ed25519", 0, SPEC_FLAG_IS_EdDSA
284 "ssh-rsa", "RSA", GCRY_PK_RSA, "nedupq", "en", "s", "nedpqu",
285 ssh_key_modifier_rsa, ssh_signature_encoder_rsa,
286 NULL, 0, SPEC_FLAG_USE_PKCS1V2
289 "ssh-dss", "DSA", GCRY_PK_DSA, "pqgyx", "pqgy", "rs", "pqgyx",
290 NULL, ssh_signature_encoder_dsa,
294 "ecdsa-sha2-nistp256", "ECDSA", GCRY_PK_ECC, "qd", "q", "rs", "qd",
295 NULL, ssh_signature_encoder_ecdsa,
296 "nistp256", GCRY_MD_SHA256, SPEC_FLAG_IS_ECDSA
299 "ecdsa-sha2-nistp384", "ECDSA", GCRY_PK_ECC, "qd", "q", "rs", "qd",
300 NULL, ssh_signature_encoder_ecdsa,
301 "nistp384", GCRY_MD_SHA384, SPEC_FLAG_IS_ECDSA
304 "ecdsa-sha2-nistp521", "ECDSA", GCRY_PK_ECC, "qd", "q", "rs", "qd",
305 NULL, ssh_signature_encoder_ecdsa,
306 "nistp521", GCRY_MD_SHA512, SPEC_FLAG_IS_ECDSA
309 "ssh-ed25519-cert-v01@openssh.com", "Ed25519",
310 GCRY_PK_EDDSA, "qd", "q", "rs", "qd",
311 NULL, ssh_signature_encoder_eddsa,
312 "Ed25519", 0, SPEC_FLAG_IS_EdDSA | SPEC_FLAG_WITH_CERT
315 "ssh-rsa-cert-v01@openssh.com", "RSA",
316 GCRY_PK_RSA, "nedupq", "en", "s", "nedpqu",
317 ssh_key_modifier_rsa, ssh_signature_encoder_rsa,
318 NULL, 0, SPEC_FLAG_USE_PKCS1V2 | SPEC_FLAG_WITH_CERT
321 "ssh-dss-cert-v01@openssh.com", "DSA",
322 GCRY_PK_DSA, "pqgyx", "pqgy", "rs", "pqgyx",
323 NULL, ssh_signature_encoder_dsa,
324 NULL, 0, SPEC_FLAG_WITH_CERT | SPEC_FLAG_WITH_CERT
327 "ecdsa-sha2-nistp256-cert-v01@openssh.com", "ECDSA",
328 GCRY_PK_ECC, "qd", "q", "rs", "qd",
329 NULL, ssh_signature_encoder_ecdsa,
330 "nistp256", GCRY_MD_SHA256, SPEC_FLAG_IS_ECDSA | SPEC_FLAG_WITH_CERT
333 "ecdsa-sha2-nistp384-cert-v01@openssh.com", "ECDSA",
334 GCRY_PK_ECC, "qd", "q", "rs", "qd",
335 NULL, ssh_signature_encoder_ecdsa,
336 "nistp384", GCRY_MD_SHA384, SPEC_FLAG_IS_ECDSA | SPEC_FLAG_WITH_CERT
339 "ecdsa-sha2-nistp521-cert-v01@openssh.com", "ECDSA",
340 GCRY_PK_ECC, "qd", "q", "rs", "qd",
341 NULL, ssh_signature_encoder_ecdsa,
342 "nistp521", GCRY_MD_SHA512, SPEC_FLAG_IS_ECDSA | SPEC_FLAG_WITH_CERT
351 General utility functions.
354 /* A secure realloc, i.e. it makes sure to allocate secure memory if A
355 is NULL. This is required because the standard gcry_realloc does
356 not know whether to allocate secure or normal if NULL is passed as
359 realloc_secure (void *a, size_t n)
364 p = gcry_realloc (a, n);
366 p = gcry_malloc_secure (n);
372 /* Lookup the ssh-identifier for the ECC curve CURVE_NAME. Returns
373 NULL if not found. */
375 ssh_identifier_from_curve_name (const char *curve_name)
379 for (i = 0; i < DIM (ssh_key_types); i++)
380 if (ssh_key_types[i].curve_name
381 && !strcmp (ssh_key_types[i].curve_name, curve_name))
382 return ssh_key_types[i].ssh_identifier;
389 Primitive I/O functions.
393 /* Read a byte from STREAM, store it in B. */
395 stream_read_byte (estream_t stream, unsigned char *b)
400 ret = es_fgetc (stream);
403 if (es_ferror (stream))
404 err = gpg_error_from_syserror ();
406 err = gpg_error (GPG_ERR_EOF);
418 /* Write the byte contained in B to STREAM. */
420 stream_write_byte (estream_t stream, unsigned char b)
425 ret = es_fputc (b, stream);
427 err = gpg_error_from_syserror ();
435 /* Read a uint32 from STREAM, store it in UINT32. */
437 stream_read_uint32 (estream_t stream, u32 *uint32)
439 unsigned char buffer[4];
444 ret = es_read (stream, buffer, sizeof (buffer), &bytes_read);
446 err = gpg_error_from_syserror ();
449 if (bytes_read != sizeof (buffer))
450 err = gpg_error (GPG_ERR_EOF);
455 n = uint32_construct (buffer[0], buffer[1], buffer[2], buffer[3]);
464 /* Write the uint32 contained in UINT32 to STREAM. */
466 stream_write_uint32 (estream_t stream, u32 uint32)
468 unsigned char buffer[4];
472 buffer[0] = uint32 >> 24;
473 buffer[1] = uint32 >> 16;
474 buffer[2] = uint32 >> 8;
475 buffer[3] = uint32 >> 0;
477 ret = es_write (stream, buffer, sizeof (buffer), NULL);
479 err = gpg_error_from_syserror ();
486 /* Read SIZE bytes from STREAM into BUFFER. */
488 stream_read_data (estream_t stream, unsigned char *buffer, size_t size)
494 ret = es_read (stream, buffer, size, &bytes_read);
496 err = gpg_error_from_syserror ();
499 if (bytes_read != size)
500 err = gpg_error (GPG_ERR_EOF);
508 /* Skip over SIZE bytes from STREAM. */
510 stream_read_skip (estream_t stream, size_t size)
513 size_t bytes_to_read, bytes_read;
518 bytes_to_read = size;
519 if (bytes_to_read > sizeof buffer)
520 bytes_to_read = sizeof buffer;
522 ret = es_read (stream, buffer, bytes_to_read, &bytes_read);
524 return gpg_error_from_syserror ();
525 else if (bytes_read != bytes_to_read)
526 return gpg_error (GPG_ERR_EOF);
528 size -= bytes_to_read;
536 /* Write SIZE bytes from BUFFER to STREAM. */
538 stream_write_data (estream_t stream, const unsigned char *buffer, size_t size)
543 ret = es_write (stream, buffer, size, NULL);
545 err = gpg_error_from_syserror ();
552 /* Read a binary string from STREAM into STRING, store size of string
553 in STRING_SIZE. Append a hidden nul so that the result may
554 directly be used as a C string. Depending on SECURE use secure
555 memory for STRING. If STRING is NULL do only a dummy read. */
557 stream_read_string (estream_t stream, unsigned int secure,
558 unsigned char **string, u32 *string_size)
561 unsigned char *buffer = NULL;
567 /* Read string length. */
568 err = stream_read_uint32 (stream, &length);
574 /* Allocate space. */
576 buffer = xtrymalloc_secure (length + 1);
578 buffer = xtrymalloc (length + 1);
581 err = gpg_error_from_syserror ();
586 err = stream_read_data (stream, buffer, length);
590 /* Finalize string object. */
594 else /* Dummy read requested. */
596 err = stream_read_skip (stream, length);
602 *string_size = length;
613 /* Read a binary string from STREAM and store it as an opaque MPI at
614 R_MPI, adding 0x40 (this is the prefix for EdDSA key in OpenPGP).
615 Depending on SECURE use secure memory. If the string is too large
616 for key material return an error. */
618 stream_read_blob (estream_t stream, unsigned int secure, gcry_mpi_t *r_mpi)
621 unsigned char *buffer = NULL;
626 /* Read string length. */
627 err = stream_read_uint32 (stream, &length);
631 /* To avoid excessive use of secure memory we check that an MPI is
633 if (length > (4096/8) + 8)
635 log_error (_("ssh keys greater than %d bits are not supported\n"), 4096);
636 err = GPG_ERR_TOO_LARGE;
640 /* Allocate space. */
642 buffer = xtrymalloc_secure (length+1);
644 buffer = xtrymalloc (length+1);
647 err = gpg_error_from_syserror ();
652 err = stream_read_data (stream, buffer + 1, length);
657 *r_mpi = gcry_mpi_set_opaque (NULL, buffer, 8*(length+1));
666 /* Read a C-string from STREAM, store copy in STRING. */
668 stream_read_cstring (estream_t stream, char **string)
671 unsigned char *buffer;
673 err = stream_read_string (stream, 0, &buffer, NULL);
675 *string = (char *)buffer;
680 /* Write a binary string from STRING of size STRING_N to STREAM. */
682 stream_write_string (estream_t stream,
683 const unsigned char *string, u32 string_n)
687 err = stream_write_uint32 (stream, string_n);
691 err = stream_write_data (stream, string, string_n);
698 /* Write a C-string from STRING to STREAM. */
700 stream_write_cstring (estream_t stream, const char *string)
704 err = stream_write_string (stream,
705 (const unsigned char *) string, strlen (string));
710 /* Read an MPI from STREAM, store it in MPINT. Depending on SECURE
711 use secure memory. */
713 stream_read_mpi (estream_t stream, unsigned int secure, gcry_mpi_t *mpint)
715 unsigned char *mpi_data;
722 err = stream_read_string (stream, secure, &mpi_data, &mpi_data_size);
726 /* To avoid excessive use of secure memory we check that an MPI is
728 if (mpi_data_size > 520)
730 log_error (_("ssh keys greater than %d bits are not supported\n"), 4096);
731 err = GPG_ERR_TOO_LARGE;
735 err = gcry_mpi_scan (&mpi, GCRYMPI_FMT_STD, mpi_data, mpi_data_size, NULL);
748 /* Write the MPI contained in MPINT to STREAM. */
750 stream_write_mpi (estream_t stream, gcry_mpi_t mpint)
752 unsigned char *mpi_buffer;
758 err = gcry_mpi_aprint (GCRYMPI_FMT_STD, &mpi_buffer, &mpi_buffer_n, mpint);
762 err = stream_write_string (stream, mpi_buffer, mpi_buffer_n);
772 /* Copy data from SRC to DST until EOF is reached. */
774 stream_copy (estream_t dst, estream_t src)
784 ret = es_read (src, buffer, sizeof (buffer), &bytes_read);
785 if (ret || (! bytes_read))
788 err = gpg_error_from_syserror ();
791 ret = es_write (dst, buffer, bytes_read, NULL);
794 err = gpg_error_from_syserror ();
802 /* Open the ssh control file and create it if not available. With
803 APPEND passed as true the file will be opened in append mode,
804 otherwise in read only mode. On success 0 is returned and a new
805 control file object stored at R_CF. On error an error code is
806 returned and NULL is stored at R_CF. */
808 open_control_file (ssh_control_file_t *r_cf, int append)
811 ssh_control_file_t cf;
813 cf = xtrycalloc (1, sizeof *cf);
816 err = gpg_error_from_syserror ();
820 /* Note: As soon as we start to use non blocking functions here
821 (i.e. where Pth might switch threads) we need to employ a
823 cf->fname = make_filename_try (gnupg_homedir (), SSH_CONTROL_FILE_NAME, NULL);
826 err = gpg_error_from_syserror ();
829 /* FIXME: With "a+" we are not able to check whether this will
830 be created and thus the blurb needs to be written first. */
831 cf->fp = fopen (cf->fname, append? "a+":"r");
832 if (!cf->fp && errno == ENOENT)
834 estream_t stream = es_fopen (cf->fname, "wx,mode=-rw-r");
837 err = gpg_error_from_syserror ();
838 log_error (_("can't create '%s': %s\n"),
839 cf->fname, gpg_strerror (err));
842 es_fputs (sshcontrolblurb, stream);
844 cf->fp = fopen (cf->fname, append? "a+":"r");
849 err = gpg_error_from_syserror ();
850 log_error (_("can't open '%s': %s\n"),
851 cf->fname, gpg_strerror (err));
873 rewind_control_file (ssh_control_file_t cf)
875 fseek (cf->fp, 0, SEEK_SET);
882 close_control_file (ssh_control_file_t cf)
893 /* Read the next line from the control file and store the data in CF.
894 Returns 0 on success, GPG_ERR_EOF on EOF, or other error codes. */
896 read_control_file_item (ssh_control_file_t cf)
899 char *p, *pend, line[256];
907 if (!fgets (line, DIM(line)-1, cf->fp) )
910 return gpg_error (GPG_ERR_EOF);
911 return gpg_error_from_syserror ();
915 if (!*line || line[strlen(line)-1] != '\n')
917 /* Eat until end of line */
918 while ( (c=getc (cf->fp)) != EOF && c != '\n')
920 return gpg_error (*line? GPG_ERR_LINE_TOO_LONG
921 : GPG_ERR_INCOMPLETE_LINE);
924 /* Allow for empty lines and spaces */
925 for (p=line; spacep (p); p++)
928 while (!*p || *p == '\n' || *p == '#');
930 cf->item.disabled = 0;
933 cf->item.disabled = 1;
934 for (p++; spacep (p); p++)
938 for (i=0; hexdigitp (p) && i < 40; p++, i++)
939 cf->item.hexgrip[i] = (*p >= 'a'? (*p & 0xdf): *p);
940 cf->item.hexgrip[i] = 0;
941 if (i != 40 || !(spacep (p) || *p == '\n'))
943 log_error ("%s:%d: invalid formatted line\n", cf->fname, cf->lnr);
944 return gpg_error (GPG_ERR_BAD_DATA);
947 ttl = strtol (p, &pend, 10);
949 if (!(spacep (p) || *p == '\n') || (int)ttl < -1)
951 log_error ("%s:%d: invalid TTL value; assuming 0\n", cf->fname, cf->lnr);
956 /* Now check for key-value pairs of the form NAME[=VALUE]. */
957 cf->item.confirm = 0;
960 for (; spacep (p) && *p != '\n'; p++)
962 if (!*p || *p == '\n')
964 n = strcspn (p, "= \t\n");
967 log_error ("%s:%d: assigning a value to a flag is not yet supported; "
968 "flag ignored\n", cf->fname, cf->lnr);
971 else if (n == 7 && !memcmp (p, "confirm", 7))
973 cf->item.confirm = 1;
976 log_error ("%s:%d: invalid flag '%.*s'; ignored\n",
977 cf->fname, cf->lnr, n, p);
981 /* log_debug ("%s:%d: grip=%s ttl=%d%s%s\n", */
982 /* cf->fname, cf->lnr, */
983 /* cf->item.hexgrip, cf->item.ttl, */
984 /* cf->item.disabled? " disabled":"", */
985 /* cf->item.confirm? " confirm":""); */
988 return 0; /* Okay: valid entry found. */
993 /* Search the control file CF from the beginning until a matching
994 HEXGRIP is found; return success in this case and store true at
995 DISABLED if the found key has been disabled. If R_TTL is not NULL
996 a specified TTL for that key is stored there. If R_CONFIRM is not
997 NULL it is set to 1 if the key has the confirm flag set. */
999 search_control_file (ssh_control_file_t cf, const char *hexgrip,
1000 int *r_disabled, int *r_ttl, int *r_confirm)
1004 assert (strlen (hexgrip) == 40 );
1013 rewind_control_file (cf);
1014 while (!(err=read_control_file_item (cf)))
1016 if (!cf->item.valid)
1017 continue; /* Should not happen. */
1018 if (!strcmp (hexgrip, cf->item.hexgrip))
1024 *r_disabled = cf->item.disabled;
1026 *r_ttl = cf->item.ttl;
1028 *r_confirm = cf->item.confirm;
1035 /* Add an entry to the control file to mark the key with the keygrip
1036 HEXGRIP as usable for SSH; i.e. it will be returned when ssh asks
1037 for it. FMTFPR is the fingerprint string. This function is in
1038 general used to add a key received through the ssh-add function.
1039 We can assume that the user wants to allow ssh using this key. */
1041 add_control_entry (ctrl_t ctrl, ssh_key_type_spec_t *spec,
1042 const char *hexgrip, const char *fmtfpr,
1043 int ttl, int confirm)
1046 ssh_control_file_t cf;
1051 err = open_control_file (&cf, 1);
1055 err = search_control_file (cf, hexgrip, &disabled, NULL, NULL);
1056 if (err && gpg_err_code(err) == GPG_ERR_EOF)
1059 time_t atime = time (NULL);
1061 /* Not yet in the file - add it. Because the file has been
1062 opened in append mode, we simply need to write to it. */
1063 tp = localtime (&atime);
1065 ("# %s key added on: %04d-%02d-%02d %02d:%02d:%02d\n"
1066 "# MD5 Fingerprint: %s\n"
1069 1900+tp->tm_year, tp->tm_mon+1, tp->tm_mday,
1070 tp->tm_hour, tp->tm_min, tp->tm_sec,
1071 fmtfpr, hexgrip, ttl, confirm? " confirm":"");
1074 close_control_file (cf);
1079 /* Scan the sshcontrol file and return the TTL. */
1081 ttl_from_sshcontrol (const char *hexgrip)
1083 ssh_control_file_t cf;
1086 if (!hexgrip || strlen (hexgrip) != 40)
1087 return 0; /* Wrong input: Use global default. */
1089 if (open_control_file (&cf, 0))
1090 return 0; /* Error: Use the global default TTL. */
1092 if (search_control_file (cf, hexgrip, &disabled, &ttl, NULL)
1094 ttl = 0; /* Use the global default if not found or disabled. */
1096 close_control_file (cf);
1102 /* Scan the sshcontrol file and return the confirm flag. */
1104 confirm_flag_from_sshcontrol (const char *hexgrip)
1106 ssh_control_file_t cf;
1107 int disabled, confirm;
1109 if (!hexgrip || strlen (hexgrip) != 40)
1110 return 1; /* Wrong input: Better ask for confirmation. */
1112 if (open_control_file (&cf, 0))
1113 return 1; /* Error: Better ask for confirmation. */
1115 if (search_control_file (cf, hexgrip, &disabled, NULL, &confirm)
1117 confirm = 0; /* If not found or disabled, there is no reason to
1118 ask for confirmation. */
1120 close_control_file (cf);
1128 /* Open the ssh control file for reading. This is a public version of
1129 open_control_file. The caller must use ssh_close_control_file to
1130 release the returned handle. */
1132 ssh_open_control_file (void)
1134 ssh_control_file_t cf;
1136 /* Then look at all the registered and non-disabled keys. */
1137 if (open_control_file (&cf, 0))
1142 /* Close an ssh control file handle. This is the public version of
1143 close_control_file. CF may be NULL. */
1145 ssh_close_control_file (ssh_control_file_t cf)
1147 close_control_file (cf);
1150 /* Read the next item from the ssh control file. The function returns
1151 0 if a item was read, GPG_ERR_EOF on eof or another error value.
1152 R_HEXGRIP shall either be null or a BUFFER of at least 41 byte.
1153 R_DISABLED, R_TTLm and R_CONFIRM return flags from the control
1154 file; they are only set on success. */
1156 ssh_read_control_file (ssh_control_file_t cf,
1158 int *r_disabled, int *r_ttl, int *r_confirm)
1163 err = read_control_file_item (cf);
1164 while (!err && !cf->item.valid);
1168 strcpy (r_hexgrip, cf->item.hexgrip);
1170 *r_disabled = cf->item.disabled;
1172 *r_ttl = cf->item.ttl;
1174 *r_confirm = cf->item.confirm;
1180 /* Search for a key with HEXGRIP in sshcontrol and return all
1183 ssh_search_control_file (ssh_control_file_t cf,
1184 const char *hexgrip,
1185 int *r_disabled, int *r_ttl, int *r_confirm)
1192 /* We need to make sure that HEXGRIP is all uppercase. The easiest
1193 way to do this and also check its length is by copying to a
1195 for (i=0, s=hexgrip; i < 40 && *s; s++, i++)
1196 uphexgrip[i] = *s >= 'a'? (*s & 0xdf): *s;
1199 err = gpg_error (GPG_ERR_INV_LENGTH);
1201 err = search_control_file (cf, uphexgrip, r_disabled, r_ttl, r_confirm);
1202 if (gpg_err_code (err) == GPG_ERR_EOF)
1203 err = gpg_error (GPG_ERR_NOT_FOUND);
1216 /* Free the list of MPIs MPI_LIST. */
1218 mpint_list_free (gcry_mpi_t *mpi_list)
1224 for (i = 0; mpi_list[i]; i++)
1225 gcry_mpi_release (mpi_list[i]);
1230 /* Receive key material MPIs from STREAM according to KEY_SPEC;
1231 depending on SECRET expect a public key or secret key. CERT is the
1232 certificate blob used if KEY_SPEC indicates the certificate format;
1233 it needs to be positioned to the end of the nonce. The newly
1234 allocated list of MPIs is stored in MPI_LIST. Returns usual error
1237 ssh_receive_mpint_list (estream_t stream, int secret,
1238 ssh_key_type_spec_t *spec, estream_t cert,
1239 gcry_mpi_t **mpi_list)
1241 const char *elems_public;
1242 unsigned int elems_n;
1245 gcry_mpi_t *mpis = NULL;
1246 gpg_error_t err = 0;
1250 elems = spec->elems_key_secret;
1252 elems = spec->elems_key_public;
1253 elems_n = strlen (elems);
1254 elems_public = spec->elems_key_public;
1256 /* Check that either both, CERT and the WITH_CERT flag, are given or
1258 if (!(!!(spec->flags & SPEC_FLAG_WITH_CERT) ^ !cert))
1260 err = gpg_error (GPG_ERR_INV_CERT_OBJ);
1264 mpis = xtrycalloc (elems_n + 1, sizeof *mpis );
1267 err = gpg_error_from_syserror ();
1272 for (i = 0; i < elems_n; i++)
1275 elem_is_secret = !strchr (elems_public, elems[i]);
1277 if (cert && !elem_is_secret)
1278 err = stream_read_mpi (cert, elem_is_secret, &mpis[i]);
1280 err = stream_read_mpi (stream, elem_is_secret, &mpis[i]);
1290 mpint_list_free (mpis);
1297 /* Key modifier function for RSA. */
1299 ssh_key_modifier_rsa (const char *elems, gcry_mpi_t *mpis)
1305 if (strcmp (elems, "nedupq"))
1306 /* Modifying only necessary for secret keys. */
1313 if (gcry_mpi_cmp (p, q) > 0)
1315 /* P shall be smaller then Q! Swap primes. iqmp becomes u. */
1323 /* U needs to be recomputed. */
1324 gcry_mpi_invm (u, p, q);
1331 /* Signature encoder function for RSA. */
1333 ssh_signature_encoder_rsa (ssh_key_type_spec_t *spec,
1334 estream_t signature_blob,
1335 gcry_sexp_t s_signature)
1337 gpg_error_t err = 0;
1338 gcry_sexp_t valuelist = NULL;
1339 gcry_sexp_t sublist = NULL;
1340 gcry_mpi_t sig_value = NULL;
1341 gcry_mpi_t *mpis = NULL;
1346 unsigned char *data;
1350 valuelist = gcry_sexp_nth (s_signature, 1);
1353 err = gpg_error (GPG_ERR_INV_SEXP);
1357 elems = spec->elems_signature;
1358 elems_n = strlen (elems);
1360 mpis = xtrycalloc (elems_n + 1, sizeof *mpis);
1363 err = gpg_error_from_syserror ();
1367 for (i = 0; i < elems_n; i++)
1369 sublist = gcry_sexp_find_token (valuelist, spec->elems_signature + i, 1);
1372 err = gpg_error (GPG_ERR_INV_SEXP);
1376 sig_value = gcry_sexp_nth_mpi (sublist, 1, GCRYMPI_FMT_USG);
1379 err = gpg_error (GPG_ERR_INTERNAL); /* FIXME? */
1382 gcry_sexp_release (sublist);
1385 mpis[i] = sig_value;
1393 err = gcry_mpi_aprint (GCRYMPI_FMT_USG, &data, &data_n, s);
1397 err = stream_write_string (signature_blob, data, data_n);
1401 gcry_sexp_release (valuelist);
1402 gcry_sexp_release (sublist);
1403 mpint_list_free (mpis);
1408 /* Signature encoder function for DSA. */
1410 ssh_signature_encoder_dsa (ssh_key_type_spec_t *spec,
1411 estream_t signature_blob,
1412 gcry_sexp_t s_signature)
1414 gpg_error_t err = 0;
1415 gcry_sexp_t valuelist = NULL;
1416 gcry_sexp_t sublist = NULL;
1417 gcry_mpi_t sig_value = NULL;
1418 gcry_mpi_t *mpis = NULL;
1423 unsigned char buffer[SSH_DSA_SIGNATURE_PADDING * SSH_DSA_SIGNATURE_ELEMS];
1424 unsigned char *data = NULL;
1427 valuelist = gcry_sexp_nth (s_signature, 1);
1430 err = gpg_error (GPG_ERR_INV_SEXP);
1434 elems = spec->elems_signature;
1435 elems_n = strlen (elems);
1437 mpis = xtrycalloc (elems_n + 1, sizeof *mpis);
1440 err = gpg_error_from_syserror ();
1444 for (i = 0; i < elems_n; i++)
1446 sublist = gcry_sexp_find_token (valuelist, spec->elems_signature + i, 1);
1449 err = gpg_error (GPG_ERR_INV_SEXP);
1453 sig_value = gcry_sexp_nth_mpi (sublist, 1, GCRYMPI_FMT_USG);
1456 err = gpg_error (GPG_ERR_INTERNAL); /* FIXME? */
1459 gcry_sexp_release (sublist);
1462 mpis[i] = sig_value;
1467 /* DSA specific code. */
1469 /* FIXME: Why this complicated code? Why collecting boths mpis in a
1470 buffer instead of writing them out one after the other? */
1471 for (i = 0; i < 2; i++)
1473 err = gcry_mpi_aprint (GCRYMPI_FMT_USG, &data, &data_n, mpis[i]);
1477 if (data_n > SSH_DSA_SIGNATURE_PADDING)
1479 err = gpg_error (GPG_ERR_INTERNAL); /* FIXME? */
1483 memset (buffer + (i * SSH_DSA_SIGNATURE_PADDING), 0,
1484 SSH_DSA_SIGNATURE_PADDING - data_n);
1485 memcpy (buffer + (i * SSH_DSA_SIGNATURE_PADDING)
1486 + (SSH_DSA_SIGNATURE_PADDING - data_n), data, data_n);
1494 err = stream_write_string (signature_blob, buffer, sizeof (buffer));
1498 gcry_sexp_release (valuelist);
1499 gcry_sexp_release (sublist);
1500 mpint_list_free (mpis);
1505 /* Signature encoder function for ECDSA. */
1507 ssh_signature_encoder_ecdsa (ssh_key_type_spec_t *spec,
1508 estream_t stream, gcry_sexp_t s_signature)
1510 gpg_error_t err = 0;
1511 gcry_sexp_t valuelist = NULL;
1512 gcry_sexp_t sublist = NULL;
1513 gcry_mpi_t sig_value = NULL;
1514 gcry_mpi_t *mpis = NULL;
1519 unsigned char *data[2] = {NULL, NULL};
1523 valuelist = gcry_sexp_nth (s_signature, 1);
1526 err = gpg_error (GPG_ERR_INV_SEXP);
1530 elems = spec->elems_signature;
1531 elems_n = strlen (elems);
1533 mpis = xtrycalloc (elems_n + 1, sizeof *mpis);
1536 err = gpg_error_from_syserror ();
1540 for (i = 0; i < elems_n; i++)
1542 sublist = gcry_sexp_find_token (valuelist, spec->elems_signature + i, 1);
1545 err = gpg_error (GPG_ERR_INV_SEXP);
1549 sig_value = gcry_sexp_nth_mpi (sublist, 1, GCRYMPI_FMT_USG);
1552 err = gpg_error (GPG_ERR_INTERNAL); /* FIXME? */
1555 gcry_sexp_release (sublist);
1558 mpis[i] = sig_value;
1563 /* ECDSA specific */
1566 for (i = 0; i < DIM(data); i++)
1568 err = gcry_mpi_aprint (GCRYMPI_FMT_STD, &data[i], &data_n[i], mpis[i]);
1571 innerlen += 4 + data_n[i];
1574 err = stream_write_uint32 (stream, innerlen);
1578 for (i = 0; i < DIM(data); i++)
1580 err = stream_write_string (stream, data[i], data_n[i]);
1586 for (i = 0; i < DIM(data); i++)
1588 gcry_sexp_release (valuelist);
1589 gcry_sexp_release (sublist);
1590 mpint_list_free (mpis);
1595 /* Signature encoder function for EdDSA. */
1597 ssh_signature_encoder_eddsa (ssh_key_type_spec_t *spec,
1598 estream_t stream, gcry_sexp_t s_signature)
1600 gpg_error_t err = 0;
1601 gcry_sexp_t valuelist = NULL;
1602 gcry_sexp_t sublist = NULL;
1607 unsigned char *data[2] = {NULL, NULL};
1609 size_t totallen = 0;
1611 valuelist = gcry_sexp_nth (s_signature, 1);
1614 err = gpg_error (GPG_ERR_INV_SEXP);
1618 elems = spec->elems_signature;
1619 elems_n = strlen (elems);
1621 if (elems_n != DIM(data))
1623 err = gpg_error (GPG_ERR_INV_SEXP);
1627 for (i = 0; i < DIM(data); i++)
1629 sublist = gcry_sexp_find_token (valuelist, spec->elems_signature + i, 1);
1632 err = gpg_error (GPG_ERR_INV_SEXP);
1636 data[i] = gcry_sexp_nth_buffer (sublist, 1, &data_n[i]);
1639 err = gpg_error (GPG_ERR_INTERNAL); /* FIXME? */
1642 totallen += data_n[i];
1643 gcry_sexp_release (sublist);
1649 err = stream_write_uint32 (stream, totallen);
1653 for (i = 0; i < DIM(data); i++)
1655 err = stream_write_data (stream, data[i], data_n[i]);
1661 for (i = 0; i < DIM(data); i++)
1663 gcry_sexp_release (valuelist);
1664 gcry_sexp_release (sublist);
1674 /* This function constructs a new S-Expression for the key identified
1675 by the KEY_SPEC, SECRET, CURVE_NAME, MPIS, and COMMENT, which is to
1676 be stored at R_SEXP. Returns an error code. */
1678 sexp_key_construct (gcry_sexp_t *r_sexp,
1679 ssh_key_type_spec_t key_spec, int secret,
1680 const char *curve_name, gcry_mpi_t *mpis,
1681 const char *comment)
1684 gcry_sexp_t sexp_new = NULL;
1685 void *formatbuf = NULL;
1686 void **arg_list = NULL;
1687 estream_t format = NULL;
1688 char *algo_name = NULL;
1690 if ((key_spec.flags & SPEC_FLAG_IS_EdDSA))
1692 /* It is much easier and more readable to use a separate code
1695 err = gpg_error (GPG_ERR_INV_CURVE);
1696 else if (!mpis[0] || !gcry_mpi_get_flag (mpis[0], GCRYMPI_FLAG_OPAQUE))
1697 err = gpg_error (GPG_ERR_BAD_PUBKEY);
1700 || !gcry_mpi_get_flag (mpis[1], GCRYMPI_FLAG_OPAQUE)))
1701 err = gpg_error (GPG_ERR_BAD_SECKEY);
1703 err = gcry_sexp_build (&sexp_new, NULL,
1704 "(private-key(ecc(curve %s)"
1705 "(flags eddsa)(q %m)(d %m))"
1709 comment? comment:"");
1711 err = gcry_sexp_build (&sexp_new, NULL,
1712 "(public-key(ecc(curve %s)"
1713 "(flags eddsa)(q %m))"
1717 comment? comment:"");
1721 const char *key_identifier[] = { "public-key", "private-key" };
1728 elems = key_spec.elems_sexp_order;
1730 elems = key_spec.elems_key_public;
1731 elems_n = strlen (elems);
1733 format = es_fopenmem (0, "a+b");
1736 err = gpg_error_from_syserror ();
1740 /* Key identifier, algorithm identifier, mpis, comment, and a NULL
1742 arg_list = xtrymalloc (sizeof (*arg_list) * (2 + 1 + elems_n + 1 + 1));
1745 err = gpg_error_from_syserror ();
1750 es_fputs ("(%s(%s", format);
1751 arg_list[arg_idx++] = &key_identifier[secret];
1752 algo_name = xtrystrdup (gcry_pk_algo_name (key_spec.algo));
1755 err = gpg_error_from_syserror ();
1759 arg_list[arg_idx++] = &algo_name;
1762 es_fputs ("(curve%s)", format);
1763 arg_list[arg_idx++] = &curve_name;
1766 for (i = 0; i < elems_n; i++)
1768 es_fprintf (format, "(%c%%m)", elems[i]);
1771 for (j = 0; j < elems_n; j++)
1772 if (key_spec.elems_key_secret[j] == elems[i])
1777 arg_list[arg_idx++] = &mpis[j];
1779 es_fputs (")(comment%s))", format);
1780 arg_list[arg_idx++] = &comment;
1781 arg_list[arg_idx] = NULL;
1783 es_putc (0, format);
1784 if (es_ferror (format))
1786 err = gpg_error_from_syserror ();
1789 if (es_fclose_snatch (format, &formatbuf, NULL))
1791 err = gpg_error_from_syserror ();
1796 err = gcry_sexp_build_array (&sexp_new, NULL, formatbuf, arg_list);
1812 /* This function extracts the key from the s-expression SEXP according
1813 to KEY_SPEC and stores it in ssh format at (R_BLOB, R_BLOBLEN). If
1814 WITH_SECRET is true, the secret key parts are also extracted if
1815 possible. Returns 0 on success or an error code. Note that data
1816 stored at R_BLOB must be freed using es_free! */
1818 ssh_key_to_blob (gcry_sexp_t sexp, int with_secret,
1819 ssh_key_type_spec_t key_spec,
1820 void **r_blob, size_t *r_blob_size)
1822 gpg_error_t err = 0;
1823 gcry_sexp_t value_list = NULL;
1824 gcry_sexp_t value_pair = NULL;
1825 char *curve_name = NULL;
1826 estream_t stream = NULL;
1829 const char *elems, *p_elems;
1836 stream = es_fopenmem (0, "r+b");
1839 err = gpg_error_from_syserror ();
1843 /* Get the type of the key extpression. */
1844 data = gcry_sexp_nth_data (sexp, 0, &datalen);
1847 err = gpg_error (GPG_ERR_INV_SEXP);
1851 if ((datalen == 10 && !strncmp (data, "public-key", 10))
1852 || (datalen == 21 && !strncmp (data, "protected-private-key", 21))
1853 || (datalen == 20 && !strncmp (data, "shadowed-private-key", 20)))
1854 elems = key_spec.elems_key_public;
1855 else if (datalen == 11 && !strncmp (data, "private-key", 11))
1856 elems = with_secret? key_spec.elems_key_secret : key_spec.elems_key_public;
1859 err = gpg_error (GPG_ERR_INV_SEXP);
1863 /* Get key value list. */
1864 value_list = gcry_sexp_cadr (sexp);
1867 err = gpg_error (GPG_ERR_INV_SEXP);
1871 /* Write the ssh algorithm identifier. */
1872 if ((key_spec.flags & SPEC_FLAG_IS_ECDSA))
1874 /* Parse the "curve" parameter. We currently expect the curve
1875 name for ECC and not the parameters of the curve. This can
1876 easily be changed but then we need to find the curve name
1877 from the parameters using gcry_pk_get_curve. */
1879 const char *sshname;
1881 gcry_sexp_release (value_pair);
1882 value_pair = gcry_sexp_find_token (value_list, "curve", 5);
1885 err = gpg_error (GPG_ERR_INV_CURVE);
1888 curve_name = gcry_sexp_nth_string (value_pair, 1);
1891 err = gpg_error (GPG_ERR_INV_CURVE); /* (Or out of core.) */
1895 /* Fixme: The mapping should be done by using gcry_pk_get_curve
1896 et al to iterate over all name aliases. */
1897 if (!strcmp (curve_name, "NIST P-256"))
1898 mapped = "nistp256";
1899 else if (!strcmp (curve_name, "NIST P-384"))
1900 mapped = "nistp384";
1901 else if (!strcmp (curve_name, "NIST P-521"))
1902 mapped = "nistp521";
1908 curve_name = xtrystrdup (mapped);
1911 err = gpg_error_from_syserror ();
1916 sshname = ssh_identifier_from_curve_name (curve_name);
1919 err = gpg_error (GPG_ERR_UNKNOWN_CURVE);
1922 err = stream_write_cstring (stream, sshname);
1925 err = stream_write_cstring (stream, curve_name);
1931 /* Note: This is also used for EdDSA. */
1932 err = stream_write_cstring (stream, key_spec.ssh_identifier);
1937 /* Write the parameters. */
1938 for (p_elems = elems; *p_elems; p_elems++)
1940 gcry_sexp_release (value_pair);
1941 value_pair = gcry_sexp_find_token (value_list, p_elems, 1);
1944 err = gpg_error (GPG_ERR_INV_SEXP);
1947 if ((key_spec.flags & SPEC_FLAG_IS_EdDSA))
1950 data = gcry_sexp_nth_data (value_pair, 1, &datalen);
1953 err = gpg_error (GPG_ERR_INV_SEXP);
1956 if (*p_elems == 'q' && datalen)
1957 { /* Remove the prefix 0x40. */
1961 err = stream_write_string (stream, data, datalen);
1969 /* Note that we need to use STD format; i.e. prepend a 0x00
1970 to indicate a positive number if the high bit is set. */
1971 mpi = gcry_sexp_nth_mpi (value_pair, 1, GCRYMPI_FMT_STD);
1974 err = gpg_error (GPG_ERR_INV_SEXP);
1977 err = stream_write_mpi (stream, mpi);
1978 gcry_mpi_release (mpi);
1984 if (es_fclose_snatch (stream, &blob, &blob_size))
1986 err = gpg_error_from_syserror ();
1993 *r_blob_size = blob_size;
1996 gcry_sexp_release (value_list);
1997 gcry_sexp_release (value_pair);
2012 /* Search for a key specification entry. If SSH_NAME is not NULL,
2013 search for an entry whose "ssh_name" is equal to SSH_NAME;
2014 otherwise, search for an entry whose algorithm is equal to ALGO.
2015 Store found entry in SPEC on success, return error otherwise. */
2017 ssh_key_type_lookup (const char *ssh_name, int algo,
2018 ssh_key_type_spec_t *spec)
2023 for (i = 0; i < DIM (ssh_key_types); i++)
2024 if ((ssh_name && (! strcmp (ssh_name, ssh_key_types[i].ssh_identifier)))
2025 || algo == ssh_key_types[i].algo)
2028 if (i == DIM (ssh_key_types))
2029 err = gpg_error (GPG_ERR_NOT_FOUND);
2032 *spec = ssh_key_types[i];
2040 /* Receive a key from STREAM, according to the key specification given
2041 as KEY_SPEC. Depending on SECRET, receive a secret or a public
2042 key. If READ_COMMENT is true, receive a comment string as well.
2043 Constructs a new S-Expression from received data and stores it in
2044 KEY_NEW. Returns zero on success or an error code. */
2046 ssh_receive_key (estream_t stream, gcry_sexp_t *key_new, int secret,
2047 int read_comment, ssh_key_type_spec_t *key_spec)
2050 char *key_type = NULL;
2051 char *comment = NULL;
2052 estream_t cert = NULL;
2053 gcry_sexp_t key = NULL;
2054 ssh_key_type_spec_t spec;
2055 gcry_mpi_t *mpi_list = NULL;
2057 char *curve_name = NULL;
2060 err = stream_read_cstring (stream, &key_type);
2064 err = ssh_key_type_lookup (key_type, 0, &spec);
2068 if ((spec.flags & SPEC_FLAG_WITH_CERT))
2070 /* This is an OpenSSH certificate+private key. The certificate
2071 is an SSH string and which we store in an estream object. */
2072 unsigned char *buffer;
2074 char *cert_key_type;
2076 err = stream_read_string (stream, 0, &buffer, &buflen);
2079 cert = es_fopenmem_init (0, "rb", buffer, buflen);
2083 err = gpg_error_from_syserror ();
2087 /* Check that the key type matches. */
2088 err = stream_read_cstring (cert, &cert_key_type);
2091 if (strcmp (cert_key_type, key_type) )
2093 xfree (cert_key_type);
2094 log_error ("key types in received ssh certificate do not match\n");
2095 err = gpg_error (GPG_ERR_INV_CERT_OBJ);
2098 xfree (cert_key_type);
2100 /* Skip the nonce. */
2101 err = stream_read_string (cert, 0, NULL, NULL);
2106 if ((spec.flags & SPEC_FLAG_IS_EdDSA))
2108 /* The format of an EdDSA key is:
2109 * string key_type ("ssh-ed25519")
2111 * string private_key
2113 * Note that the private key is the concatenation of the private
2114 * key with the public key. Thus theres are 64 bytes; however
2115 * we only want the real 32 byte private key - Libgcrypt expects
2118 mpi_list = xtrycalloc (3, sizeof *mpi_list);
2121 err = gpg_error_from_syserror ();
2125 err = stream_read_blob (cert? cert : stream, 0, &mpi_list[0]);
2131 unsigned char *buffer;
2133 /* Read string length. */
2134 err = stream_read_uint32 (stream, &len);
2137 if (len != 32 && len != 64)
2139 err = gpg_error (GPG_ERR_BAD_SECKEY);
2142 buffer = xtrymalloc_secure (32);
2145 err = gpg_error_from_syserror ();
2148 err = stream_read_data (stream, buffer, 32);
2154 mpi_list[1] = gcry_mpi_set_opaque (NULL, buffer, 8*32);
2158 err = stream_read_skip (stream, 32);
2164 else if ((spec.flags & SPEC_FLAG_IS_ECDSA))
2166 /* The format of an ECDSA key is:
2167 * string key_type ("ecdsa-sha2-nistp256" |
2168 * "ecdsa-sha2-nistp384" |
2169 * "ecdsa-sha2-nistp521" )
2170 * string ecdsa_curve_name
2171 * string ecdsa_public_key
2172 * mpint ecdsa_private
2174 * Note that we use the mpint reader instead of the string
2175 * reader for ecsa_public_key. For the certificate variante
2176 * ecdsa_curve_name+ecdsa_public_key are replaced by the
2179 unsigned char *buffer;
2182 err = stream_read_string (cert? cert : stream, 0, &buffer, NULL);
2185 curve_name = buffer;
2186 /* Fixme: Check that curve_name matches the keytype. */
2187 /* Because Libgcrypt < 1.6 has no support for the "nistpNNN"
2188 curve names, we need to translate them here to Libgcrypt's
2190 if (!strcmp (curve_name, "nistp256"))
2191 mapped = "NIST P-256";
2192 else if (!strcmp (curve_name, "nistp384"))
2193 mapped = "NIST P-384";
2194 else if (!strcmp (curve_name, "nistp521"))
2195 mapped = "NIST P-521";
2201 curve_name = xtrystrdup (mapped);
2204 err = gpg_error_from_syserror ();
2209 err = ssh_receive_mpint_list (stream, secret, &spec, cert, &mpi_list);
2215 err = ssh_receive_mpint_list (stream, secret, &spec, cert, &mpi_list);
2222 err = stream_read_cstring (stream, &comment);
2228 elems = spec.elems_key_secret;
2230 elems = spec.elems_key_public;
2232 if (spec.key_modifier)
2234 err = (*spec.key_modifier) (elems, mpi_list);
2239 if ((spec.flags & SPEC_FLAG_IS_EdDSA))
2243 err = gcry_sexp_build (&key, NULL,
2244 "(private-key(ecc(curve \"Ed25519\")"
2245 "(flags eddsa)(q %m)(d %m))"
2247 mpi_list[0], mpi_list[1],
2248 comment? comment:"");
2252 err = gcry_sexp_build (&key, NULL,
2253 "(public-key(ecc(curve \"Ed25519\")"
2254 "(flags eddsa)(q %m))"
2257 comment? comment:"");
2262 err = sexp_key_construct (&key, spec, secret, curve_name, mpi_list,
2263 comment? comment:"");
2274 mpint_list_free (mpi_list);
2283 /* Write the public key from KEY to STREAM in SSH key format. If
2284 OVERRIDE_COMMENT is not NULL, it will be used instead of the
2285 comment stored in the key. */
2287 ssh_send_key_public (estream_t stream, gcry_sexp_t key,
2288 const char *override_comment)
2290 ssh_key_type_spec_t spec;
2292 char *comment = NULL;
2295 gpg_error_t err = 0;
2297 algo = get_pk_algo_from_key (key);
2301 err = ssh_key_type_lookup (NULL, algo, &spec);
2305 err = ssh_key_to_blob (key, 0, spec, &blob, &bloblen);
2309 err = stream_write_string (stream, blob, bloblen);
2313 if (override_comment)
2314 err = stream_write_cstring (stream, override_comment);
2317 err = ssh_key_extract_comment (key, &comment);
2319 err = stream_write_cstring (stream, "(none)");
2321 err = stream_write_cstring (stream, comment);
2334 /* Read a public key out of BLOB/BLOB_SIZE according to the key
2335 specification given as KEY_SPEC, storing the new key in KEY_PUBLIC.
2336 Returns zero on success or an error code. */
2338 ssh_read_key_public_from_blob (unsigned char *blob, size_t blob_size,
2339 gcry_sexp_t *key_public,
2340 ssh_key_type_spec_t *key_spec)
2343 estream_t blob_stream;
2345 blob_stream = es_fopenmem (0, "r+b");
2348 err = gpg_error_from_syserror ();
2352 err = stream_write_data (blob_stream, blob, blob_size);
2356 err = es_fseek (blob_stream, 0, SEEK_SET);
2360 err = ssh_receive_key (blob_stream, key_public, 0, 0, key_spec);
2363 es_fclose (blob_stream);
2369 /* This function calculates the key grip for the key contained in the
2370 S-Expression KEY and writes it to BUFFER, which must be large
2371 enough to hold it. Returns usual error code. */
2373 ssh_key_grip (gcry_sexp_t key, unsigned char *buffer)
2375 if (!gcry_pk_get_keygrip (key, buffer))
2377 gpg_error_t err = gcry_pk_testkey (key);
2378 return err? err : gpg_error (GPG_ERR_INTERNAL);
2385 /* Check whether a smartcard is available and whether it has a usable
2386 key. Store a copy of that key at R_PK and return 0. If no key is
2387 available store NULL at R_PK and return an error code. If CARDSN
2388 is not NULL, a string with the serial number of the card will be
2389 a malloced and stored there. */
2391 card_key_available (ctrl_t ctrl, gcry_sexp_t *r_pk, char **cardsn)
2395 char *serialno = NULL;
2396 unsigned char *pkbuf;
2399 unsigned char grip[20];
2405 /* First see whether a card is available and whether the application
2407 err = agent_card_getattr (ctrl, "$AUTHKEYID", &authkeyid);
2408 if ( gpg_err_code (err) == GPG_ERR_CARD_REMOVED )
2410 /* Ask for the serial number to reset the card. */
2411 err = agent_card_serialno (ctrl, &serialno);
2415 log_info (_("error getting serial number of card: %s\n"),
2416 gpg_strerror (err));
2419 log_info (_("detected card with S/N: %s\n"), serialno);
2420 err = agent_card_getattr (ctrl, "$AUTHKEYID", &authkeyid);
2424 log_error (_("no authentication key for ssh on card: %s\n"),
2425 gpg_strerror (err));
2430 /* Get the S/N if we don't have it yet. Use the fast getattr method. */
2431 if (!serialno && (err = agent_card_getattr (ctrl, "SERIALNO", &serialno)) )
2433 log_error (_("error getting serial number of card: %s\n"),
2434 gpg_strerror (err));
2439 /* Read the public key. */
2440 err = agent_card_readkey (ctrl, authkeyid, &pkbuf);
2444 log_info (_("no suitable card key found: %s\n"), gpg_strerror (err));
2450 pkbuflen = gcry_sexp_canon_len (pkbuf, 0, NULL, NULL);
2451 err = gcry_sexp_sscan (&s_pk, NULL, (char*)pkbuf, pkbuflen);
2454 log_error ("failed to build S-Exp from received card key: %s\n",
2455 gpg_strerror (err));
2462 err = ssh_key_grip (s_pk, grip);
2465 log_debug ("error computing keygrip from received card key: %s\n",
2466 gcry_strerror (err));
2468 gcry_sexp_release (s_pk);
2474 if ( agent_key_available (grip) )
2476 /* (Shadow)-key is not available in our key storage. */
2477 err = agent_write_shadow_key (grip, serialno, authkeyid, pkbuf, 0);
2481 gcry_sexp_release (s_pk);
2492 /* If the card handler is able to return a short serialnumber,
2493 use that one, else use the complete serialno. */
2494 if (!agent_card_getattr (ctrl, "$DISPSERIALNO", &dispsn))
2496 *cardsn = xtryasprintf ("cardno:%s", dispsn);
2500 *cardsn = xtryasprintf ("cardno:%s", serialno);
2503 err = gpg_error_from_syserror ();
2505 gcry_sexp_release (s_pk);
2524 Request handler. Each handler is provided with a CTRL context, a
2525 REQUEST object and a RESPONSE object. The actual request is to be
2526 read from REQUEST, the response needs to be written to RESPONSE.
2531 /* Handler for the "request_identities" command. */
2533 ssh_handler_request_identities (ctrl_t ctrl,
2534 estream_t request, estream_t response)
2537 estream_t key_blobs;
2538 gcry_sexp_t key_public;
2541 ssh_control_file_t cf = NULL;
2543 gpg_error_t ret_err;
2547 /* Prepare buffer stream. */
2553 key_blobs = es_fopenmem (0, "r+b");
2556 err = gpg_error_from_syserror ();
2560 /* First check whether a key is currently available in the card
2561 reader - this should be allowed even without being listed in
2564 if (!opt.disable_scdaemon
2565 && !card_key_available (ctrl, &key_public, &cardsn))
2567 err = ssh_send_key_public (key_blobs, key_public, cardsn);
2568 gcry_sexp_release (key_public);
2577 /* Then look at all the registered and non-disabled keys. */
2578 err = open_control_file (&cf, 0);
2582 while (!read_control_file_item (cf))
2584 unsigned char grip[20];
2586 if (!cf->item.valid)
2587 continue; /* Should not happen. */
2588 if (cf->item.disabled)
2590 assert (strlen (cf->item.hexgrip) == 40);
2591 hex2bin (cf->item.hexgrip, grip, sizeof (grip));
2593 err = agent_public_key_from_file (ctrl, grip, &key_public);
2596 log_error ("%s:%d: key '%s' skipped: %s\n",
2597 cf->fname, cf->lnr, cf->item.hexgrip,
2598 gpg_strerror (err));
2602 err = ssh_send_key_public (key_blobs, key_public, NULL);
2605 gcry_sexp_release (key_public);
2612 ret = es_fseek (key_blobs, 0, SEEK_SET);
2615 err = gpg_error_from_syserror ();
2620 /* Send response. */
2622 gcry_sexp_release (key_public);
2626 ret_err = stream_write_byte (response, SSH_RESPONSE_IDENTITIES_ANSWER);
2628 ret_err = stream_write_uint32 (response, key_counter);
2630 ret_err = stream_copy (response, key_blobs);
2634 ret_err = stream_write_byte (response, SSH_RESPONSE_FAILURE);
2637 es_fclose (key_blobs);
2638 close_control_file (cf);
2644 /* This function hashes the data contained in DATA of size DATA_N
2645 according to the message digest algorithm specified by MD_ALGORITHM
2646 and writes the message digest to HASH, which needs to large enough
2649 data_hash (unsigned char *data, size_t data_n,
2650 int md_algorithm, unsigned char *hash)
2652 gcry_md_hash_buffer (md_algorithm, hash, data, data_n);
2658 /* This function signs the data described by CTRL. If HASH is is not
2659 NULL, (HASH,HASHLEN) overrides the hash stored in CTRL. This is to
2660 allow the use of signature algorithms that implement the hashing
2661 internally (e.g. Ed25519). On success the created signature is
2662 stored in ssh format at R_SIG and it's size at R_SIGLEN; the caller
2663 must use es_free to releaase this memory. */
2665 data_sign (ctrl_t ctrl, ssh_key_type_spec_t *spec,
2666 const void *hash, size_t hashlen,
2667 unsigned char **r_sig, size_t *r_siglen)
2670 gcry_sexp_t signature_sexp = NULL;
2671 estream_t stream = NULL;
2679 /* Quick check to see whether we have a valid keygrip and convert it
2681 if (!ctrl->have_keygrip)
2683 err = gpg_error (GPG_ERR_NO_SECKEY);
2686 bin2hex (ctrl->keygrip, 20, hexgrip);
2688 /* Ask for confirmation if needed. */
2689 if (confirm_flag_from_sshcontrol (hexgrip))
2693 char *comment = NULL;
2695 err = agent_raw_key_from_file (ctrl, ctrl->keygrip, &key);
2698 err = ssh_get_fingerprint_string (key, &fpr);
2701 gcry_sexp_t tmpsxp = gcry_sexp_find_token (key, "comment", 0);
2703 comment = gcry_sexp_nth_string (tmpsxp, 1);
2704 gcry_sexp_release (tmpsxp);
2706 gcry_sexp_release (key);
2709 prompt = xtryasprintf (L_("An ssh process requested the use of key%%0A"
2712 "Do you want to allow this?"),
2713 fpr, comment? comment:"");
2715 gcry_free (comment);
2716 err = agent_get_confirmation (ctrl, prompt, L_("Allow"), L_("Deny"), 0);
2722 /* Create signature. */
2723 ctrl->use_auth_call = 1;
2724 err = agent_pksign_do (ctrl, NULL,
2725 L_("Please enter the passphrase "
2726 "for the ssh key%%0A %F%%0A (%c)"),
2728 CACHE_MODE_SSH, ttl_from_sshcontrol,
2730 ctrl->use_auth_call = 0;
2734 stream = es_fopenmem (0, "r+b");
2737 err = gpg_error_from_syserror ();
2741 err = stream_write_cstring (stream, spec->ssh_identifier);
2745 err = spec->signature_encoder (spec, stream, signature_sexp);
2749 err = es_fclose_snatch (stream, &blob, &bloblen);
2754 *r_sig = blob; blob = NULL;
2755 *r_siglen = bloblen;
2760 gcry_sexp_release (signature_sexp);
2766 /* Handler for the "sign_request" command. */
2768 ssh_handler_sign_request (ctrl_t ctrl, estream_t request, estream_t response)
2770 gcry_sexp_t key = NULL;
2771 ssh_key_type_spec_t spec;
2772 unsigned char hash[MAX_DIGEST_LEN];
2773 unsigned int hash_n;
2774 unsigned char key_grip[20];
2775 unsigned char *key_blob = NULL;
2777 unsigned char *data = NULL;
2778 unsigned char *sig = NULL;
2783 gpg_error_t ret_err;
2788 err = stream_read_string (request, 0, &key_blob, &key_blob_size);
2792 err = ssh_read_key_public_from_blob (key_blob, key_blob_size, &key, &spec);
2796 /* Receive data to sign. */
2797 err = stream_read_string (request, 0, &data, &data_size);
2802 err = stream_read_uint32 (request, &flags);
2806 hash_algo = spec.hash_algo;
2808 hash_algo = GCRY_MD_SHA1; /* Use the default. */
2809 ctrl->digest.algo = hash_algo;
2810 if ((spec.flags & SPEC_FLAG_USE_PKCS1V2))
2811 ctrl->digest.raw_value = 0;
2813 ctrl->digest.raw_value = 1;
2815 /* Calculate key grip. */
2816 err = ssh_key_grip (key, key_grip);
2819 ctrl->have_keygrip = 1;
2820 memcpy (ctrl->keygrip, key_grip, 20);
2822 /* Hash data unless we use EdDSA. */
2823 if ((spec.flags & SPEC_FLAG_IS_EdDSA))
2825 ctrl->digest.valuelen = 0;
2829 hash_n = gcry_md_get_algo_dlen (hash_algo);
2832 err = gpg_error (GPG_ERR_INTERNAL);
2835 err = data_hash (data, data_size, hash_algo, hash);
2838 memcpy (ctrl->digest.value, hash, hash_n);
2839 ctrl->digest.valuelen = hash_n;
2843 if ((spec.flags & SPEC_FLAG_IS_EdDSA))
2844 err = data_sign (ctrl, &spec, data, data_size, &sig, &sig_n);
2846 err = data_sign (ctrl, &spec, NULL, 0, &sig, &sig_n);
2852 ret_err = stream_write_byte (response, SSH_RESPONSE_SIGN_RESPONSE);
2855 ret_err = stream_write_string (response, sig, sig_n);
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);
2870 gcry_sexp_release (key);
2879 /* This function extracts the comment contained in the key
2880 s-expression KEY and stores a copy in COMMENT. Returns usual error
2883 ssh_key_extract_comment (gcry_sexp_t key, char **r_comment)
2885 gcry_sexp_t comment_list;
2889 comment_list = gcry_sexp_find_token (key, "comment", 0);
2891 return gpg_error (GPG_ERR_INV_SEXP);
2893 *r_comment = gcry_sexp_nth_string (comment_list, 1);
2894 gcry_sexp_release (comment_list);
2896 return gpg_error (GPG_ERR_INV_SEXP);
2902 /* This function converts the key contained in the S-Expression KEY
2903 into a buffer, which is protected by the passphrase PASSPHRASE.
2904 Returns usual error code. */
2906 ssh_key_to_protected_buffer (gcry_sexp_t key, const char *passphrase,
2907 unsigned char **buffer, size_t *buffer_n)
2909 unsigned char *buffer_new;
2910 unsigned int buffer_new_n;
2914 buffer_new_n = gcry_sexp_sprint (key, GCRYSEXP_FMT_CANON, NULL, 0);
2915 buffer_new = xtrymalloc_secure (buffer_new_n);
2918 err = gpg_error_from_syserror ();
2922 gcry_sexp_sprint (key, GCRYSEXP_FMT_CANON, buffer_new, buffer_new_n);
2923 /* FIXME: guarantee? */
2925 err = agent_protect (buffer_new, passphrase, buffer, buffer_n, 0, -1);
2936 /* Callback function to compare the first entered PIN with the one
2937 currently being entered. */
2939 reenter_compare_cb (struct pin_entry_info_s *pi)
2941 const char *pin1 = pi->check_cb_arg;
2943 if (!strcmp (pin1, pi->pin))
2944 return 0; /* okay */
2945 return gpg_error (GPG_ERR_BAD_PASSPHRASE);
2949 /* Store the ssh KEY into our local key storage and protect it after
2950 asking for a passphrase. Cache that passphrase. TTL is the
2951 maximum caching time for that key. If the key already exists in
2952 our key storage, don't do anything. When entering a key also add
2953 an entry to the sshcontrol file. */
2955 ssh_identity_register (ctrl_t ctrl, ssh_key_type_spec_t *spec,
2956 gcry_sexp_t key, int ttl, int confirm)
2959 unsigned char key_grip_raw[20];
2961 unsigned char *buffer = NULL;
2963 char *description = NULL;
2964 const char *description2 = L_("Please re-enter this passphrase");
2965 char *comment = NULL;
2966 char *key_fpr = NULL;
2967 const char *initial_errtext = NULL;
2968 struct pin_entry_info_s *pi = NULL;
2969 struct pin_entry_info_s *pi2 = NULL;
2971 err = ssh_key_grip (key, key_grip_raw);
2975 bin2hex (key_grip_raw, 20, key_grip);
2977 err = ssh_get_fingerprint_string (key, &key_fpr);
2981 /* Check whether the key is already in our key storage. Don't do
2982 anything then besides (re-)adding it to sshcontrol. */
2983 if ( !agent_key_available (key_grip_raw) )
2984 goto key_exists; /* Yes, key is available. */
2986 err = ssh_key_extract_comment (key, &comment);
2990 if ( asprintf (&description,
2991 L_("Please enter a passphrase to protect"
2992 " the received secret key%%0A"
2995 "within gpg-agent's key storage"),
2996 key_fpr, comment ? comment : "") < 0)
2998 err = gpg_error_from_syserror ();
3002 pi = gcry_calloc_secure (1, sizeof (*pi) + MAX_PASSPHRASE_LEN + 1);
3005 err = gpg_error_from_syserror ();
3008 pi2 = gcry_calloc_secure (1, sizeof (*pi2) + MAX_PASSPHRASE_LEN + 1);
3011 err = gpg_error_from_syserror ();
3014 pi->max_length = MAX_PASSPHRASE_LEN + 1;
3016 pi->with_repeat = 1;
3017 pi2->max_length = MAX_PASSPHRASE_LEN + 1;
3019 pi2->check_cb = reenter_compare_cb;
3020 pi2->check_cb_arg = pi->pin;
3023 err = agent_askpin (ctrl, description, NULL, initial_errtext, pi, NULL, 0);
3024 initial_errtext = NULL;
3028 /* Unless the passphrase is empty or the pinentry told us that
3029 it already did the repetition check, ask to confirm it. */
3030 if (*pi->pin && !pi->repeat_okay)
3032 err = agent_askpin (ctrl, description2, NULL, NULL, pi2, NULL, 0);
3033 if (gpg_err_code (err) == GPG_ERR_BAD_PASSPHRASE)
3034 { /* The re-entered one did not match and the user did not
3036 initial_errtext = L_("does not match - try again");
3041 err = ssh_key_to_protected_buffer (key, pi->pin, &buffer, &buffer_n);
3045 /* Store this key to our key storage. */
3046 err = agent_write_private_key (key_grip_raw, buffer, buffer_n, 0);
3050 /* Cache this passphrase. */
3051 err = agent_put_cache (key_grip, CACHE_MODE_SSH, pi->pin, ttl);
3056 /* And add an entry to the sshcontrol file. */
3057 err = add_control_entry (ctrl, spec, key_grip, key_fpr, ttl, confirm);
3061 if (pi2 && pi2->max_length)
3062 wipememory (pi2->pin, pi2->max_length);
3064 if (pi && pi->max_length)
3065 wipememory (pi->pin, pi->max_length);
3070 xfree (description);
3076 /* This function removes the key contained in the S-Expression KEY
3077 from the local key storage, in case it exists there. Returns usual
3078 error code. FIXME: this function is a stub. */
3080 ssh_identity_drop (gcry_sexp_t key)
3082 unsigned char key_grip[21] = { 0 };
3085 err = ssh_key_grip (key, key_grip);
3089 key_grip[sizeof (key_grip) - 1] = 0;
3091 /* FIXME: What to do here - forgetting the passphrase or deleting
3092 the key from key cache? */
3099 /* Handler for the "add_identity" command. */
3101 ssh_handler_add_identity (ctrl_t ctrl, estream_t request, estream_t response)
3103 gpg_error_t ret_err;
3104 ssh_key_type_spec_t spec;
3116 err = ssh_receive_key (request, &key, 1, 1, &spec);
3122 err = stream_read_byte (request, &b);
3123 if (gpg_err_code (err) == GPG_ERR_EOF)
3131 case SSH_OPT_CONSTRAIN_LIFETIME:
3135 err = stream_read_uint32 (request, &n);
3141 case SSH_OPT_CONSTRAIN_CONFIRM:
3148 /* FIXME: log/bad? */
3155 err = ssh_identity_register (ctrl, &spec, key, ttl, confirm);
3159 gcry_sexp_release (key);
3162 ret_err = stream_write_byte (response, SSH_RESPONSE_SUCCESS);
3164 ret_err = stream_write_byte (response, SSH_RESPONSE_FAILURE);
3169 /* Handler for the "remove_identity" command. */
3171 ssh_handler_remove_identity (ctrl_t ctrl,
3172 estream_t request, estream_t response)
3174 unsigned char *key_blob;
3177 gpg_error_t ret_err;
3187 err = stream_read_string (request, 0, &key_blob, &key_blob_size);
3191 err = ssh_read_key_public_from_blob (key_blob, key_blob_size, &key, NULL);
3195 err = ssh_identity_drop (key);
3200 gcry_sexp_release (key);
3203 ret_err = stream_write_byte (response, SSH_RESPONSE_SUCCESS);
3205 ret_err = stream_write_byte (response, SSH_RESPONSE_FAILURE);
3210 /* FIXME: stub function. Actually useful? */
3212 ssh_identities_remove_all (void)
3218 /* FIXME: shall we remove _all_ cache entries or only those
3219 registered through the ssh emulation? */
3224 /* Handler for the "remove_all_identities" command. */
3226 ssh_handler_remove_all_identities (ctrl_t ctrl,
3227 estream_t request, estream_t response)
3229 gpg_error_t ret_err;
3235 err = ssh_identities_remove_all ();
3238 ret_err = stream_write_byte (response, SSH_RESPONSE_SUCCESS);
3240 ret_err = stream_write_byte (response, SSH_RESPONSE_FAILURE);
3245 /* Lock agent? FIXME: stub function. */
3252 log_error ("ssh-agent's lock command is not implemented\n");
3258 /* Unock agent? FIXME: stub function. */
3264 log_error ("ssh-agent's unlock command is not implemented\n");
3270 /* Handler for the "lock" command. */
3272 ssh_handler_lock (ctrl_t ctrl, estream_t request, estream_t response)
3274 gpg_error_t ret_err;
3283 ret_err = stream_write_byte (response, SSH_RESPONSE_SUCCESS);
3285 ret_err = stream_write_byte (response, SSH_RESPONSE_FAILURE);
3290 /* Handler for the "unlock" command. */
3292 ssh_handler_unlock (ctrl_t ctrl, estream_t request, estream_t response)
3294 gpg_error_t ret_err;
3300 err = ssh_unlock ();
3303 ret_err = stream_write_byte (response, SSH_RESPONSE_SUCCESS);
3305 ret_err = stream_write_byte (response, SSH_RESPONSE_FAILURE);
3312 /* Return the request specification for the request identified by TYPE
3313 or NULL in case the requested request specification could not be
3315 static ssh_request_spec_t *
3316 request_spec_lookup (int type)
3318 ssh_request_spec_t *spec;
3321 for (i = 0; i < DIM (request_specs); i++)
3322 if (request_specs[i].type == type)
3324 if (i == DIM (request_specs))
3327 log_info ("ssh request %u is not supported\n", type);
3331 spec = request_specs + i;
3336 /* Process a single request. The request is read from and the
3337 response is written to STREAM_SOCK. Uses CTRL as context. Returns
3338 zero in case of success, non zero in case of failure. */
3340 ssh_request_process (ctrl_t ctrl, estream_t stream_sock)
3342 ssh_request_spec_t *spec;
3343 estream_t response = NULL;
3344 estream_t request = NULL;
3345 unsigned char request_type;
3349 unsigned char *request_data = NULL;
3350 u32 request_data_size;
3353 /* Create memory streams for request/response data. The entire
3354 request will be stored in secure memory, since it might contain
3355 secret key material. The response does not have to be stored in
3356 secure memory, since we never give out secret keys.
3358 Note: we only have little secure memory, but there is NO
3359 possibility of DoS here; only trusted clients are allowed to
3360 connect to the agent. What could happen is that the agent
3361 returns out-of-secure-memory errors on requests in case the
3362 agent's owner floods his own agent with many large messages.
3365 /* Retrieve request. */
3366 err = stream_read_string (stream_sock, 1, &request_data, &request_data_size);
3370 if (opt.verbose > 1)
3371 log_info ("received ssh request of length %u\n",
3372 (unsigned int)request_data_size);
3374 if (! request_data_size)
3378 /* Broken request; FIXME. */
3381 request_type = request_data[0];
3382 spec = request_spec_lookup (request_type);
3387 /* Unknown request; FIXME. */
3390 if (spec->secret_input)
3391 request = es_mopen (NULL, 0, 0, 1, realloc_secure, gcry_free, "r+b");
3393 request = es_mopen (NULL, 0, 0, 1, gcry_realloc, gcry_free, "r+b");
3396 err = gpg_error_from_syserror ();
3399 ret = es_setvbuf (request, NULL, _IONBF, 0);
3402 err = gpg_error_from_syserror ();
3405 err = stream_write_data (request, request_data + 1, request_data_size - 1);
3408 es_rewind (request);
3410 response = es_fopenmem (0, "r+b");
3413 err = gpg_error_from_syserror ();
3418 log_info ("ssh request handler for %s (%u) started\n",
3419 spec->identifier, spec->type);
3421 err = (*spec->handler) (ctrl, request, response);
3426 log_info ("ssh request handler for %s (%u) failed: %s\n",
3427 spec->identifier, spec->type, gpg_strerror (err));
3429 log_info ("ssh request handler for %s (%u) ready\n",
3430 spec->identifier, spec->type);
3439 response_size = es_ftell (response);
3440 if (opt.verbose > 1)
3441 log_info ("sending ssh response of length %u\n",
3442 (unsigned int)response_size);
3444 err = es_fseek (response, 0, SEEK_SET);
3451 err = stream_write_uint32 (stream_sock, response_size);
3458 err = stream_copy (stream_sock, response);
3462 err = es_fflush (stream_sock);
3468 if (err && es_feof (stream_sock))
3469 log_error ("error occurred while processing request: %s\n",
3470 gpg_strerror (err));
3474 if (opt.verbose > 1)
3475 log_info ("sending ssh error response\n");
3476 err = stream_write_uint32 (stream_sock, 1);
3479 err = stream_write_byte (stream_sock, SSH_RESPONSE_FAILURE);
3486 es_fclose (request);
3487 es_fclose (response);
3488 xfree (request_data);
3494 /* Start serving client on SOCK_CLIENT. */
3496 start_command_handler_ssh (ctrl_t ctrl, gnupg_fd_t sock_client)
3498 estream_t stream_sock = NULL;
3502 err = agent_copy_startup_env (ctrl);
3506 /* Create stream from socket. */
3507 stream_sock = es_fdopen (FD2INT(sock_client), "r+");
3510 err = gpg_error_from_syserror ();
3511 log_error (_("failed to create stream from socket: %s\n"),
3512 gpg_strerror (err));
3515 /* We have to disable the estream buffering, because the estream
3516 core doesn't know about secure memory. */
3517 ret = es_setvbuf (stream_sock, NULL, _IONBF, 0);
3520 err = gpg_error_from_syserror ();
3521 log_error ("failed to disable buffering "
3522 "on socket stream: %s\n", gpg_strerror (err));
3526 /* Main processing loop. */
3527 while ( !ssh_request_process (ctrl, stream_sock) )
3529 /* Check wether we have reached EOF before trying to read
3533 c = es_fgetc (stream_sock);
3536 es_ungetc (c, stream_sock);
3539 /* Reset the SCD in case it has been used. */
3540 agent_reset_scd (ctrl);
3545 es_fclose (stream_sock);
3549 #ifdef HAVE_W32_SYSTEM
3550 /* Serve one ssh-agent request. This is used for the Putty support.
3551 REQUEST is the the mmapped memory which may be accessed up to a
3552 length of MAXREQLEN. Returns 0 on success which also indicates
3553 that a valid SSH response message is now in REQUEST. */
3555 serve_mmapped_ssh_request (ctrl_t ctrl,
3556 unsigned char *request, size_t maxreqlen)
3560 int valid_response = 0;
3561 ssh_request_spec_t *spec;
3563 estream_t request_stream, response_stream;
3565 if (agent_copy_startup_env (ctrl))
3566 goto leave; /* Error setting up the environment. */
3569 goto leave; /* Caller error. */
3571 msglen = uint32_construct (request[0], request[1], request[2], request[3]);
3572 if (msglen < 1 || msglen > maxreqlen - 4)
3574 log_error ("ssh message len (%u) out of range", (unsigned int)msglen);
3578 spec = request_spec_lookup (request[4]);
3581 send_err = 1; /* Unknown request type. */
3585 /* Create a stream object with the data part of the request. */
3586 if (spec->secret_input)
3587 request_stream = es_mopen (NULL, 0, 0, 1, realloc_secure, gcry_free, "r+");
3589 request_stream = es_mopen (NULL, 0, 0, 1, gcry_realloc, gcry_free, "r+");
3590 if (!request_stream)
3592 err = gpg_error_from_syserror ();
3595 /* We have to disable the estream buffering, because the estream
3596 core doesn't know about secure memory. */
3597 if (es_setvbuf (request_stream, NULL, _IONBF, 0))
3599 err = gpg_error_from_syserror ();
3602 /* Copy the request to the stream but omit the request type. */
3603 err = stream_write_data (request_stream, request + 5, msglen - 1);
3606 es_rewind (request_stream);
3608 response_stream = es_fopenmem (0, "r+b");
3609 if (!response_stream)
3611 err = gpg_error_from_syserror ();
3616 log_info ("ssh request handler for %s (%u) started\n",
3617 spec->identifier, spec->type);
3619 err = (*spec->handler) (ctrl, request_stream, response_stream);
3624 log_info ("ssh request handler for %s (%u) failed: %s\n",
3625 spec->identifier, spec->type, gpg_strerror (err));
3627 log_info ("ssh request handler for %s (%u) ready\n",
3628 spec->identifier, spec->type);
3631 es_fclose (request_stream);
3632 request_stream = NULL;
3640 /* Put the response back into the mmapped buffer. */
3642 void *response_data;
3643 size_t response_size;
3645 /* NB: In contrast to the request-stream, the response stream
3646 includes the the message type byte. */
3647 if (es_fclose_snatch (response_stream, &response_data, &response_size))
3649 log_error ("snatching ssh response failed: %s",
3650 gpg_strerror (gpg_error_from_syserror ()));
3651 send_err = 1; /* Ooops. */
3655 if (opt.verbose > 1)
3656 log_info ("sending ssh response of length %u\n",
3657 (unsigned int)response_size);
3658 if (response_size > maxreqlen - 4)
3660 log_error ("invalid length of the ssh response: %s",
3661 gpg_strerror (GPG_ERR_INTERNAL));
3662 es_free (response_data);
3667 request[0] = response_size >> 24;
3668 request[1] = response_size >> 16;
3669 request[2] = response_size >> 8;
3670 request[3] = response_size >> 0;
3671 memcpy (request+4, response_data, response_size);
3672 es_free (response_data);
3683 request[4] = SSH_RESPONSE_FAILURE;
3687 /* Reset the SCD in case it has been used. */
3688 agent_reset_scd (ctrl);
3690 return valid_response? 0 : -1;
3692 #endif /*HAVE_W32_SYSTEM*/