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
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:
32 https://tools.ietf.org/html/draft-miller-ssh-agent
42 #include <sys/types.h>
45 #ifndef HAVE_W32_SYSTEM
46 #include <sys/socket.h>
48 #endif /*!HAVE_W32_SYSTEM*/
49 #ifdef HAVE_SYS_UCRED_H
50 #include <sys/ucred.h>
58 #include "../common/i18n.h"
59 #include "../common/util.h"
60 #include "../common/ssh-utils.h"
66 #define SSH_REQUEST_REQUEST_IDENTITIES 11
67 #define SSH_REQUEST_SIGN_REQUEST 13
68 #define SSH_REQUEST_ADD_IDENTITY 17
69 #define SSH_REQUEST_REMOVE_IDENTITY 18
70 #define SSH_REQUEST_REMOVE_ALL_IDENTITIES 19
71 #define SSH_REQUEST_LOCK 22
72 #define SSH_REQUEST_UNLOCK 23
73 #define SSH_REQUEST_ADD_ID_CONSTRAINED 25
76 #define SSH_OPT_CONSTRAIN_LIFETIME 1
77 #define SSH_OPT_CONSTRAIN_CONFIRM 2
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
85 /* Other constants. */
86 #define SSH_DSA_SIGNATURE_PADDING 20
87 #define SSH_DSA_SIGNATURE_ELEMS 2
88 #define SSH_AGENT_RSA_SHA2_256 0x02
89 #define SSH_AGENT_RSA_SHA2_512 0x04
90 #define SPEC_FLAG_USE_PKCS1V2 (1 << 0)
91 #define SPEC_FLAG_IS_ECDSA (1 << 1)
92 #define SPEC_FLAG_IS_EdDSA (1 << 2) /*(lowercase 'd' on purpose.)*/
93 #define SPEC_FLAG_WITH_CERT (1 << 7)
95 /* The name of the control file. */
96 #define SSH_CONTROL_FILE_NAME "sshcontrol"
98 /* The blurb we put into the header of a newly created control file. */
99 static const char sshcontrolblurb[] =
100 "# List of allowed ssh keys. Only keys present in this file are used\n"
101 "# in the SSH protocol. The ssh-add tool may add new entries to this\n"
102 "# file to enable them; you may also add them manually. Comment\n"
103 "# lines, like this one, as well as empty lines are ignored. Lines do\n"
104 "# have a certain length limit but this is not serious limitation as\n"
105 "# the format of the entries is fixed and checked by gpg-agent. A\n"
106 "# non-comment line starts with optional white spaces, followed by the\n"
107 "# keygrip of the key given as 40 hex digits, optionally followed by a\n"
108 "# caching TTL in seconds, and another optional field for arbitrary\n"
109 "# flags. Prepend the keygrip with an '!' mark to disable it.\n"
115 /* Return a new uint32 with b0 being the most significant byte and b3
116 being the least significant byte. */
117 #define uint32_construct(b0, b1, b2, b3) \
118 ((b0 << 24) | (b1 << 16) | (b2 << 8) | b3)
127 /* Type for a request handler. */
128 typedef gpg_error_t (*ssh_request_handler_t) (ctrl_t ctrl,
133 struct ssh_key_type_spec;
134 typedef struct ssh_key_type_spec ssh_key_type_spec_t;
136 /* Type, which is used for associating request handlers with the
137 appropriate request IDs. */
138 typedef struct ssh_request_spec
141 ssh_request_handler_t handler;
142 const char *identifier;
143 unsigned int secret_input;
144 } ssh_request_spec_t;
146 /* Type for "key modifier functions", which are necessary since
147 OpenSSH and GnuPG treat key material slightly different. A key
148 modifier is called right after a new key identity has been received
149 in order to "sanitize" the material. */
150 typedef gpg_error_t (*ssh_key_modifier_t) (const char *elems,
153 /* The encoding of a generated signature is dependent on the
154 algorithm; therefore algorithm specific signature encoding
155 functions are necessary. */
156 typedef gpg_error_t (*ssh_signature_encoder_t) (ssh_key_type_spec_t *spec,
157 estream_t signature_blob,
160 /* Type, which is used for boundling all the algorithm specific
161 information together in a single object. */
162 struct ssh_key_type_spec
164 /* Algorithm identifier as used by OpenSSH. */
165 const char *ssh_identifier;
167 /* Human readable name of the algorithm. */
170 /* Algorithm identifier as used by GnuPG. */
173 /* List of MPI names for secret keys; order matches the one of the
175 const char *elems_key_secret;
177 /* List of MPI names for public keys; order matches the one of the
179 const char *elems_key_public;
181 /* List of MPI names for signature data. */
182 const char *elems_signature;
184 /* List of MPI names for secret keys; order matches the one, which
185 is required by gpg-agent's key access layer. */
186 const char *elems_sexp_order;
188 /* Key modifier function. Key modifier functions are necessary in
189 order to fix any inconsistencies between the representation of
190 keys on the SSH and on the GnuPG side. */
191 ssh_key_modifier_t key_modifier;
193 /* Signature encoder function. Signature encoder functions are
194 necessary since the encoding of signatures depends on the used
196 ssh_signature_encoder_t signature_encoder;
198 /* The name of the ECC curve or NULL. */
199 const char *curve_name;
201 /* The hash algorithm to be used with this key. 0 for using the
210 /* Definition of an object to access the sshcontrol file. */
211 struct ssh_control_file_s
213 char *fname; /* Name of the file. */
214 FILE *fp; /* This is never NULL. */
215 int lnr; /* The current line number. */
217 int valid; /* True if the data of this structure is valid. */
218 int disabled; /* The item is disabled. */
219 int ttl; /* The TTL of the item. */
220 int confirm; /* The confirm flag is set. */
221 char hexgrip[40+1]; /* The hexgrip of the item (uppercase). */
227 static gpg_error_t ssh_handler_request_identities (ctrl_t ctrl,
230 static gpg_error_t ssh_handler_sign_request (ctrl_t ctrl,
233 static gpg_error_t ssh_handler_add_identity (ctrl_t ctrl,
236 static gpg_error_t ssh_handler_remove_identity (ctrl_t ctrl,
239 static gpg_error_t ssh_handler_remove_all_identities (ctrl_t ctrl,
242 static gpg_error_t ssh_handler_lock (ctrl_t ctrl,
245 static gpg_error_t ssh_handler_unlock (ctrl_t ctrl,
249 static gpg_error_t ssh_key_modifier_rsa (const char *elems, gcry_mpi_t *mpis);
250 static gpg_error_t ssh_signature_encoder_rsa (ssh_key_type_spec_t *spec,
251 estream_t signature_blob,
252 gcry_sexp_t signature);
253 static gpg_error_t ssh_signature_encoder_dsa (ssh_key_type_spec_t *spec,
254 estream_t signature_blob,
255 gcry_sexp_t signature);
256 static gpg_error_t ssh_signature_encoder_ecdsa (ssh_key_type_spec_t *spec,
257 estream_t signature_blob,
258 gcry_sexp_t signature);
259 static gpg_error_t ssh_signature_encoder_eddsa (ssh_key_type_spec_t *spec,
260 estream_t signature_blob,
261 gcry_sexp_t signature);
262 static gpg_error_t ssh_key_extract_comment (gcry_sexp_t key, char **comment);
266 /* Global variables. */
269 /* Associating request types with the corresponding request
272 static const ssh_request_spec_t request_specs[] =
274 #define REQUEST_SPEC_DEFINE(id, name, secret_input) \
275 { SSH_REQUEST_##id, ssh_handler_##name, #name, secret_input }
277 REQUEST_SPEC_DEFINE (REQUEST_IDENTITIES, request_identities, 1),
278 REQUEST_SPEC_DEFINE (SIGN_REQUEST, sign_request, 0),
279 REQUEST_SPEC_DEFINE (ADD_IDENTITY, add_identity, 1),
280 REQUEST_SPEC_DEFINE (ADD_ID_CONSTRAINED, add_identity, 1),
281 REQUEST_SPEC_DEFINE (REMOVE_IDENTITY, remove_identity, 0),
282 REQUEST_SPEC_DEFINE (REMOVE_ALL_IDENTITIES, remove_all_identities, 0),
283 REQUEST_SPEC_DEFINE (LOCK, lock, 0),
284 REQUEST_SPEC_DEFINE (UNLOCK, unlock, 0)
285 #undef REQUEST_SPEC_DEFINE
289 /* Table holding key type specifications. */
290 static const ssh_key_type_spec_t ssh_key_types[] =
293 "ssh-ed25519", "Ed25519", GCRY_PK_EDDSA, "qd", "q", "rs", "qd",
294 NULL, ssh_signature_encoder_eddsa,
295 "Ed25519", 0, SPEC_FLAG_IS_EdDSA
298 "ssh-rsa", "RSA", GCRY_PK_RSA, "nedupq", "en", "s", "nedpqu",
299 ssh_key_modifier_rsa, ssh_signature_encoder_rsa,
300 NULL, 0, SPEC_FLAG_USE_PKCS1V2
303 "ssh-dss", "DSA", GCRY_PK_DSA, "pqgyx", "pqgy", "rs", "pqgyx",
304 NULL, ssh_signature_encoder_dsa,
308 "ecdsa-sha2-nistp256", "ECDSA", GCRY_PK_ECC, "qd", "q", "rs", "qd",
309 NULL, ssh_signature_encoder_ecdsa,
310 "nistp256", GCRY_MD_SHA256, SPEC_FLAG_IS_ECDSA
313 "ecdsa-sha2-nistp384", "ECDSA", GCRY_PK_ECC, "qd", "q", "rs", "qd",
314 NULL, ssh_signature_encoder_ecdsa,
315 "nistp384", GCRY_MD_SHA384, SPEC_FLAG_IS_ECDSA
318 "ecdsa-sha2-nistp521", "ECDSA", GCRY_PK_ECC, "qd", "q", "rs", "qd",
319 NULL, ssh_signature_encoder_ecdsa,
320 "nistp521", GCRY_MD_SHA512, SPEC_FLAG_IS_ECDSA
323 "ssh-ed25519-cert-v01@openssh.com", "Ed25519",
324 GCRY_PK_EDDSA, "qd", "q", "rs", "qd",
325 NULL, ssh_signature_encoder_eddsa,
326 "Ed25519", 0, SPEC_FLAG_IS_EdDSA | SPEC_FLAG_WITH_CERT
329 "ssh-rsa-cert-v01@openssh.com", "RSA",
330 GCRY_PK_RSA, "nedupq", "en", "s", "nedpqu",
331 ssh_key_modifier_rsa, ssh_signature_encoder_rsa,
332 NULL, 0, SPEC_FLAG_USE_PKCS1V2 | SPEC_FLAG_WITH_CERT
335 "ssh-dss-cert-v01@openssh.com", "DSA",
336 GCRY_PK_DSA, "pqgyx", "pqgy", "rs", "pqgyx",
337 NULL, ssh_signature_encoder_dsa,
338 NULL, 0, SPEC_FLAG_WITH_CERT | SPEC_FLAG_WITH_CERT
341 "ecdsa-sha2-nistp256-cert-v01@openssh.com", "ECDSA",
342 GCRY_PK_ECC, "qd", "q", "rs", "qd",
343 NULL, ssh_signature_encoder_ecdsa,
344 "nistp256", GCRY_MD_SHA256, SPEC_FLAG_IS_ECDSA | SPEC_FLAG_WITH_CERT
347 "ecdsa-sha2-nistp384-cert-v01@openssh.com", "ECDSA",
348 GCRY_PK_ECC, "qd", "q", "rs", "qd",
349 NULL, ssh_signature_encoder_ecdsa,
350 "nistp384", GCRY_MD_SHA384, SPEC_FLAG_IS_ECDSA | SPEC_FLAG_WITH_CERT
353 "ecdsa-sha2-nistp521-cert-v01@openssh.com", "ECDSA",
354 GCRY_PK_ECC, "qd", "q", "rs", "qd",
355 NULL, ssh_signature_encoder_ecdsa,
356 "nistp521", GCRY_MD_SHA512, SPEC_FLAG_IS_ECDSA | SPEC_FLAG_WITH_CERT
365 General utility functions.
368 /* A secure realloc, i.e. it makes sure to allocate secure memory if A
369 is NULL. This is required because the standard gcry_realloc does
370 not know whether to allocate secure or normal if NULL is passed as
373 realloc_secure (void *a, size_t n)
378 p = gcry_realloc (a, n);
380 p = gcry_malloc_secure (n);
386 /* Lookup the ssh-identifier for the ECC curve CURVE_NAME. Returns
387 NULL if not found. */
389 ssh_identifier_from_curve_name (const char *curve_name)
393 for (i = 0; i < DIM (ssh_key_types); i++)
394 if (ssh_key_types[i].curve_name
395 && !strcmp (ssh_key_types[i].curve_name, curve_name))
396 return ssh_key_types[i].ssh_identifier;
403 Primitive I/O functions.
407 /* Read a byte from STREAM, store it in B. */
409 stream_read_byte (estream_t stream, unsigned char *b)
414 ret = es_fgetc (stream);
417 if (es_ferror (stream))
418 err = gpg_error_from_syserror ();
420 err = gpg_error (GPG_ERR_EOF);
432 /* Write the byte contained in B to STREAM. */
434 stream_write_byte (estream_t stream, unsigned char b)
439 ret = es_fputc (b, stream);
441 err = gpg_error_from_syserror ();
449 /* Read a uint32 from STREAM, store it in UINT32. */
451 stream_read_uint32 (estream_t stream, u32 *uint32)
453 unsigned char buffer[4];
458 ret = es_read (stream, buffer, sizeof (buffer), &bytes_read);
460 err = gpg_error_from_syserror ();
463 if (bytes_read != sizeof (buffer))
464 err = gpg_error (GPG_ERR_EOF);
469 n = uint32_construct (buffer[0], buffer[1], buffer[2], buffer[3]);
478 /* Write the uint32 contained in UINT32 to STREAM. */
480 stream_write_uint32 (estream_t stream, u32 uint32)
482 unsigned char buffer[4];
486 buffer[0] = uint32 >> 24;
487 buffer[1] = uint32 >> 16;
488 buffer[2] = uint32 >> 8;
489 buffer[3] = uint32 >> 0;
491 ret = es_write (stream, buffer, sizeof (buffer), NULL);
493 err = gpg_error_from_syserror ();
500 /* Read SIZE bytes from STREAM into BUFFER. */
502 stream_read_data (estream_t stream, unsigned char *buffer, size_t size)
508 ret = es_read (stream, buffer, size, &bytes_read);
510 err = gpg_error_from_syserror ();
513 if (bytes_read != size)
514 err = gpg_error (GPG_ERR_EOF);
522 /* Skip over SIZE bytes from STREAM. */
524 stream_read_skip (estream_t stream, size_t size)
527 size_t bytes_to_read, bytes_read;
532 bytes_to_read = size;
533 if (bytes_to_read > sizeof buffer)
534 bytes_to_read = sizeof buffer;
536 ret = es_read (stream, buffer, bytes_to_read, &bytes_read);
538 return gpg_error_from_syserror ();
539 else if (bytes_read != bytes_to_read)
540 return gpg_error (GPG_ERR_EOF);
542 size -= bytes_to_read;
550 /* Write SIZE bytes from BUFFER to STREAM. */
552 stream_write_data (estream_t stream, const unsigned char *buffer, size_t size)
557 ret = es_write (stream, buffer, size, NULL);
559 err = gpg_error_from_syserror ();
566 /* Read a binary string from STREAM into STRING, store size of string
567 in STRING_SIZE. Append a hidden nul so that the result may
568 directly be used as a C string. Depending on SECURE use secure
569 memory for STRING. If STRING is NULL do only a dummy read. */
571 stream_read_string (estream_t stream, unsigned int secure,
572 unsigned char **string, u32 *string_size)
575 unsigned char *buffer = NULL;
581 /* Read string length. */
582 err = stream_read_uint32 (stream, &length);
588 /* Allocate space. */
590 buffer = xtrymalloc_secure (length + 1);
592 buffer = xtrymalloc (length + 1);
595 err = gpg_error_from_syserror ();
600 err = stream_read_data (stream, buffer, length);
604 /* Finalize string object. */
608 else /* Dummy read requested. */
610 err = stream_read_skip (stream, length);
616 *string_size = length;
627 /* Read a binary string from STREAM and store it as an opaque MPI at
628 R_MPI, adding 0x40 (this is the prefix for EdDSA key in OpenPGP).
629 Depending on SECURE use secure memory. If the string is too large
630 for key material return an error. */
632 stream_read_blob (estream_t stream, unsigned int secure, gcry_mpi_t *r_mpi)
635 unsigned char *buffer = NULL;
640 /* Read string length. */
641 err = stream_read_uint32 (stream, &length);
645 /* To avoid excessive use of secure memory we check that an MPI is
647 if (length > (4096/8) + 8)
649 log_error (_("ssh keys greater than %d bits are not supported\n"), 4096);
650 err = GPG_ERR_TOO_LARGE;
654 /* Allocate space. */
656 buffer = xtrymalloc_secure (length+1);
658 buffer = xtrymalloc (length+1);
661 err = gpg_error_from_syserror ();
666 err = stream_read_data (stream, buffer + 1, length);
671 *r_mpi = gcry_mpi_set_opaque (NULL, buffer, 8*(length+1));
680 /* Read a C-string from STREAM, store copy in STRING. */
682 stream_read_cstring (estream_t stream, char **string)
684 return stream_read_string (stream, 0, (unsigned char **)string, NULL);
688 /* Write a binary string from STRING of size STRING_N to STREAM. */
690 stream_write_string (estream_t stream,
691 const unsigned char *string, u32 string_n)
695 err = stream_write_uint32 (stream, string_n);
699 err = stream_write_data (stream, string, string_n);
706 /* Write a C-string from STRING to STREAM. */
708 stream_write_cstring (estream_t stream, const char *string)
712 err = stream_write_string (stream,
713 (const unsigned char *) string, strlen (string));
718 /* Read an MPI from STREAM, store it in MPINT. Depending on SECURE
719 use secure memory. */
721 stream_read_mpi (estream_t stream, unsigned int secure, gcry_mpi_t *mpint)
723 unsigned char *mpi_data;
730 err = stream_read_string (stream, secure, &mpi_data, &mpi_data_size);
734 /* To avoid excessive use of secure memory we check that an MPI is
736 if (mpi_data_size > 520)
738 log_error (_("ssh keys greater than %d bits are not supported\n"), 4096);
739 err = GPG_ERR_TOO_LARGE;
743 err = gcry_mpi_scan (&mpi, GCRYMPI_FMT_STD, mpi_data, mpi_data_size, NULL);
756 /* Write the MPI contained in MPINT to STREAM. */
758 stream_write_mpi (estream_t stream, gcry_mpi_t mpint)
760 unsigned char *mpi_buffer;
766 err = gcry_mpi_aprint (GCRYMPI_FMT_STD, &mpi_buffer, &mpi_buffer_n, mpint);
770 err = stream_write_string (stream, mpi_buffer, mpi_buffer_n);
780 /* Copy data from SRC to DST until EOF is reached. */
782 stream_copy (estream_t dst, estream_t src)
792 ret = es_read (src, buffer, sizeof (buffer), &bytes_read);
793 if (ret || (! bytes_read))
796 err = gpg_error_from_syserror ();
799 ret = es_write (dst, buffer, bytes_read, NULL);
802 err = gpg_error_from_syserror ();
810 /* Open the ssh control file and create it if not available. With
811 APPEND passed as true the file will be opened in append mode,
812 otherwise in read only mode. On success 0 is returned and a new
813 control file object stored at R_CF. On error an error code is
814 returned and NULL is stored at R_CF. */
816 open_control_file (ssh_control_file_t *r_cf, int append)
819 ssh_control_file_t cf;
821 cf = xtrycalloc (1, sizeof *cf);
824 err = gpg_error_from_syserror ();
828 /* Note: As soon as we start to use non blocking functions here
829 (i.e. where Pth might switch threads) we need to employ a
831 cf->fname = make_filename_try (gnupg_homedir (), SSH_CONTROL_FILE_NAME, NULL);
834 err = gpg_error_from_syserror ();
837 /* FIXME: With "a+" we are not able to check whether this will
838 be created and thus the blurb needs to be written first. */
839 cf->fp = fopen (cf->fname, append? "a+":"r");
840 if (!cf->fp && errno == ENOENT)
842 estream_t stream = es_fopen (cf->fname, "wx,mode=-rw-r");
845 err = gpg_error_from_syserror ();
846 log_error (_("can't create '%s': %s\n"),
847 cf->fname, gpg_strerror (err));
850 es_fputs (sshcontrolblurb, stream);
852 cf->fp = fopen (cf->fname, append? "a+":"r");
857 err = gpg_error_from_syserror ();
858 log_error (_("can't open '%s': %s\n"),
859 cf->fname, gpg_strerror (err));
881 rewind_control_file (ssh_control_file_t cf)
883 fseek (cf->fp, 0, SEEK_SET);
890 close_control_file (ssh_control_file_t cf)
901 /* Read the next line from the control file and store the data in CF.
902 Returns 0 on success, GPG_ERR_EOF on EOF, or other error codes. */
904 read_control_file_item (ssh_control_file_t cf)
907 char *p, *pend, line[256];
915 if (!fgets (line, DIM(line)-1, cf->fp) )
918 return gpg_error (GPG_ERR_EOF);
919 return gpg_error_from_syserror ();
923 if (!*line || line[strlen(line)-1] != '\n')
925 /* Eat until end of line */
926 while ( (c=getc (cf->fp)) != EOF && c != '\n')
928 return gpg_error (*line? GPG_ERR_LINE_TOO_LONG
929 : GPG_ERR_INCOMPLETE_LINE);
932 /* Allow for empty lines and spaces */
933 for (p=line; spacep (p); p++)
936 while (!*p || *p == '\n' || *p == '#');
938 cf->item.disabled = 0;
941 cf->item.disabled = 1;
942 for (p++; spacep (p); p++)
946 for (i=0; hexdigitp (p) && i < 40; p++, i++)
947 cf->item.hexgrip[i] = (*p >= 'a'? (*p & 0xdf): *p);
948 cf->item.hexgrip[i] = 0;
949 if (i != 40 || !(spacep (p) || *p == '\n'))
951 log_error ("%s:%d: invalid formatted line\n", cf->fname, cf->lnr);
952 return gpg_error (GPG_ERR_BAD_DATA);
955 ttl = strtol (p, &pend, 10);
957 if (!(spacep (p) || *p == '\n') || (int)ttl < -1)
959 log_error ("%s:%d: invalid TTL value; assuming 0\n", cf->fname, cf->lnr);
964 /* Now check for key-value pairs of the form NAME[=VALUE]. */
965 cf->item.confirm = 0;
968 for (; spacep (p) && *p != '\n'; p++)
970 if (!*p || *p == '\n')
972 n = strcspn (p, "= \t\n");
975 log_error ("%s:%d: assigning a value to a flag is not yet supported; "
976 "flag ignored\n", cf->fname, cf->lnr);
979 else if (n == 7 && !memcmp (p, "confirm", 7))
981 cf->item.confirm = 1;
984 log_error ("%s:%d: invalid flag '%.*s'; ignored\n",
985 cf->fname, cf->lnr, n, p);
989 /* log_debug ("%s:%d: grip=%s ttl=%d%s%s\n", */
990 /* cf->fname, cf->lnr, */
991 /* cf->item.hexgrip, cf->item.ttl, */
992 /* cf->item.disabled? " disabled":"", */
993 /* cf->item.confirm? " confirm":""); */
996 return 0; /* Okay: valid entry found. */
1001 /* Search the control file CF from the beginning until a matching
1002 HEXGRIP is found; return success in this case and store true at
1003 DISABLED if the found key has been disabled. If R_TTL is not NULL
1004 a specified TTL for that key is stored there. If R_CONFIRM is not
1005 NULL it is set to 1 if the key has the confirm flag set. */
1007 search_control_file (ssh_control_file_t cf, const char *hexgrip,
1008 int *r_disabled, int *r_ttl, int *r_confirm)
1012 assert (strlen (hexgrip) == 40 );
1021 rewind_control_file (cf);
1022 while (!(err=read_control_file_item (cf)))
1024 if (!cf->item.valid)
1025 continue; /* Should not happen. */
1026 if (!strcmp (hexgrip, cf->item.hexgrip))
1032 *r_disabled = cf->item.disabled;
1034 *r_ttl = cf->item.ttl;
1036 *r_confirm = cf->item.confirm;
1043 /* Add an entry to the control file to mark the key with the keygrip
1044 HEXGRIP as usable for SSH; i.e. it will be returned when ssh asks
1045 for it. FMTFPR is the fingerprint string. This function is in
1046 general used to add a key received through the ssh-add function.
1047 We can assume that the user wants to allow ssh using this key. */
1049 add_control_entry (ctrl_t ctrl, ssh_key_type_spec_t *spec,
1050 const char *hexgrip, gcry_sexp_t key,
1051 int ttl, int confirm)
1054 ssh_control_file_t cf;
1056 char *fpr_md5 = NULL;
1057 char *fpr_sha256 = NULL;
1061 err = open_control_file (&cf, 1);
1065 err = search_control_file (cf, hexgrip, &disabled, NULL, NULL);
1066 if (err && gpg_err_code(err) == GPG_ERR_EOF)
1069 time_t atime = time (NULL);
1071 err = ssh_get_fingerprint_string (key, GCRY_MD_MD5, &fpr_md5);
1075 err = ssh_get_fingerprint_string (key, GCRY_MD_SHA256, &fpr_sha256);
1079 /* Not yet in the file - add it. Because the file has been
1080 opened in append mode, we simply need to write to it. */
1081 tp = localtime (&atime);
1083 ("# %s key added on: %04d-%02d-%02d %02d:%02d:%02d\n"
1084 "# Fingerprints: %s\n"
1088 1900+tp->tm_year, tp->tm_mon+1, tp->tm_mday,
1089 tp->tm_hour, tp->tm_min, tp->tm_sec,
1090 fpr_md5, fpr_sha256, hexgrip, ttl, confirm? " confirm":"");
1096 close_control_file (cf);
1101 /* Scan the sshcontrol file and return the TTL. */
1103 ttl_from_sshcontrol (const char *hexgrip)
1105 ssh_control_file_t cf;
1108 if (!hexgrip || strlen (hexgrip) != 40)
1109 return 0; /* Wrong input: Use global default. */
1111 if (open_control_file (&cf, 0))
1112 return 0; /* Error: Use the global default TTL. */
1114 if (search_control_file (cf, hexgrip, &disabled, &ttl, NULL)
1116 ttl = 0; /* Use the global default if not found or disabled. */
1118 close_control_file (cf);
1124 /* Scan the sshcontrol file and return the confirm flag. */
1126 confirm_flag_from_sshcontrol (const char *hexgrip)
1128 ssh_control_file_t cf;
1129 int disabled, confirm;
1131 if (!hexgrip || strlen (hexgrip) != 40)
1132 return 1; /* Wrong input: Better ask for confirmation. */
1134 if (open_control_file (&cf, 0))
1135 return 1; /* Error: Better ask for confirmation. */
1137 if (search_control_file (cf, hexgrip, &disabled, NULL, &confirm)
1139 confirm = 0; /* If not found or disabled, there is no reason to
1140 ask for confirmation. */
1142 close_control_file (cf);
1150 /* Open the ssh control file for reading. This is a public version of
1151 open_control_file. The caller must use ssh_close_control_file to
1152 release the returned handle. */
1154 ssh_open_control_file (void)
1156 ssh_control_file_t cf;
1158 /* Then look at all the registered and non-disabled keys. */
1159 if (open_control_file (&cf, 0))
1164 /* Close an ssh control file handle. This is the public version of
1165 close_control_file. CF may be NULL. */
1167 ssh_close_control_file (ssh_control_file_t cf)
1169 close_control_file (cf);
1172 /* Read the next item from the ssh control file. The function returns
1173 0 if a item was read, GPG_ERR_EOF on eof or another error value.
1174 R_HEXGRIP shall either be null or a BUFFER of at least 41 byte.
1175 R_DISABLED, R_TTLm and R_CONFIRM return flags from the control
1176 file; they are only set on success. */
1178 ssh_read_control_file (ssh_control_file_t cf,
1180 int *r_disabled, int *r_ttl, int *r_confirm)
1185 err = read_control_file_item (cf);
1186 while (!err && !cf->item.valid);
1190 strcpy (r_hexgrip, cf->item.hexgrip);
1192 *r_disabled = cf->item.disabled;
1194 *r_ttl = cf->item.ttl;
1196 *r_confirm = cf->item.confirm;
1202 /* Search for a key with HEXGRIP in sshcontrol and return all
1205 ssh_search_control_file (ssh_control_file_t cf,
1206 const char *hexgrip,
1207 int *r_disabled, int *r_ttl, int *r_confirm)
1214 /* We need to make sure that HEXGRIP is all uppercase. The easiest
1215 way to do this and also check its length is by copying to a
1217 for (i=0, s=hexgrip; i < 40 && *s; s++, i++)
1218 uphexgrip[i] = *s >= 'a'? (*s & 0xdf): *s;
1221 err = gpg_error (GPG_ERR_INV_LENGTH);
1223 err = search_control_file (cf, uphexgrip, r_disabled, r_ttl, r_confirm);
1224 if (gpg_err_code (err) == GPG_ERR_EOF)
1225 err = gpg_error (GPG_ERR_NOT_FOUND);
1238 /* Free the list of MPIs MPI_LIST. */
1240 mpint_list_free (gcry_mpi_t *mpi_list)
1246 for (i = 0; mpi_list[i]; i++)
1247 gcry_mpi_release (mpi_list[i]);
1252 /* Receive key material MPIs from STREAM according to KEY_SPEC;
1253 depending on SECRET expect a public key or secret key. CERT is the
1254 certificate blob used if KEY_SPEC indicates the certificate format;
1255 it needs to be positioned to the end of the nonce. The newly
1256 allocated list of MPIs is stored in MPI_LIST. Returns usual error
1259 ssh_receive_mpint_list (estream_t stream, int secret,
1260 ssh_key_type_spec_t *spec, estream_t cert,
1261 gcry_mpi_t **mpi_list)
1263 const char *elems_public;
1264 unsigned int elems_n;
1267 gcry_mpi_t *mpis = NULL;
1268 gpg_error_t err = 0;
1272 elems = spec->elems_key_secret;
1274 elems = spec->elems_key_public;
1275 elems_n = strlen (elems);
1276 elems_public = spec->elems_key_public;
1278 /* Check that either both, CERT and the WITH_CERT flag, are given or
1280 if (!(!!(spec->flags & SPEC_FLAG_WITH_CERT) ^ !cert))
1282 err = gpg_error (GPG_ERR_INV_CERT_OBJ);
1286 mpis = xtrycalloc (elems_n + 1, sizeof *mpis );
1289 err = gpg_error_from_syserror ();
1294 for (i = 0; i < elems_n; i++)
1297 elem_is_secret = !strchr (elems_public, elems[i]);
1299 if (cert && !elem_is_secret)
1300 err = stream_read_mpi (cert, elem_is_secret, &mpis[i]);
1302 err = stream_read_mpi (stream, elem_is_secret, &mpis[i]);
1312 mpint_list_free (mpis);
1319 /* Key modifier function for RSA. */
1321 ssh_key_modifier_rsa (const char *elems, gcry_mpi_t *mpis)
1327 if (strcmp (elems, "nedupq"))
1328 /* Modifying only necessary for secret keys. */
1335 if (gcry_mpi_cmp (p, q) > 0)
1337 /* P shall be smaller then Q! Swap primes. iqmp becomes u. */
1345 /* U needs to be recomputed. */
1346 gcry_mpi_invm (u, p, q);
1353 /* Signature encoder function for RSA. */
1355 ssh_signature_encoder_rsa (ssh_key_type_spec_t *spec,
1356 estream_t signature_blob,
1357 gcry_sexp_t s_signature)
1359 gpg_error_t err = 0;
1360 gcry_sexp_t valuelist = NULL;
1361 gcry_sexp_t sublist = NULL;
1362 gcry_mpi_t sig_value = NULL;
1363 gcry_mpi_t *mpis = NULL;
1368 unsigned char *data;
1372 valuelist = gcry_sexp_nth (s_signature, 1);
1375 err = gpg_error (GPG_ERR_INV_SEXP);
1379 elems = spec->elems_signature;
1380 elems_n = strlen (elems);
1382 mpis = xtrycalloc (elems_n + 1, sizeof *mpis);
1385 err = gpg_error_from_syserror ();
1389 for (i = 0; i < elems_n; i++)
1391 sublist = gcry_sexp_find_token (valuelist, spec->elems_signature + i, 1);
1394 err = gpg_error (GPG_ERR_INV_SEXP);
1398 sig_value = gcry_sexp_nth_mpi (sublist, 1, GCRYMPI_FMT_USG);
1401 err = gpg_error (GPG_ERR_INTERNAL); /* FIXME? */
1404 gcry_sexp_release (sublist);
1407 mpis[i] = sig_value;
1415 err = gcry_mpi_aprint (GCRYMPI_FMT_USG, &data, &data_n, s);
1419 err = stream_write_string (signature_blob, data, data_n);
1423 gcry_sexp_release (valuelist);
1424 gcry_sexp_release (sublist);
1425 mpint_list_free (mpis);
1430 /* Signature encoder function for DSA. */
1432 ssh_signature_encoder_dsa (ssh_key_type_spec_t *spec,
1433 estream_t signature_blob,
1434 gcry_sexp_t s_signature)
1436 gpg_error_t err = 0;
1437 gcry_sexp_t valuelist = NULL;
1438 gcry_sexp_t sublist = NULL;
1439 gcry_mpi_t sig_value = NULL;
1440 gcry_mpi_t *mpis = NULL;
1445 unsigned char buffer[SSH_DSA_SIGNATURE_PADDING * SSH_DSA_SIGNATURE_ELEMS];
1446 unsigned char *data = NULL;
1449 valuelist = gcry_sexp_nth (s_signature, 1);
1452 err = gpg_error (GPG_ERR_INV_SEXP);
1456 elems = spec->elems_signature;
1457 elems_n = strlen (elems);
1459 mpis = xtrycalloc (elems_n + 1, sizeof *mpis);
1462 err = gpg_error_from_syserror ();
1466 for (i = 0; i < elems_n; i++)
1468 sublist = gcry_sexp_find_token (valuelist, spec->elems_signature + i, 1);
1471 err = gpg_error (GPG_ERR_INV_SEXP);
1475 sig_value = gcry_sexp_nth_mpi (sublist, 1, GCRYMPI_FMT_USG);
1478 err = gpg_error (GPG_ERR_INTERNAL); /* FIXME? */
1481 gcry_sexp_release (sublist);
1484 mpis[i] = sig_value;
1489 /* DSA specific code. */
1491 /* FIXME: Why this complicated code? Why collecting boths mpis in a
1492 buffer instead of writing them out one after the other? */
1493 for (i = 0; i < 2; i++)
1495 err = gcry_mpi_aprint (GCRYMPI_FMT_USG, &data, &data_n, mpis[i]);
1499 if (data_n > SSH_DSA_SIGNATURE_PADDING)
1501 err = gpg_error (GPG_ERR_INTERNAL); /* FIXME? */
1505 memset (buffer + (i * SSH_DSA_SIGNATURE_PADDING), 0,
1506 SSH_DSA_SIGNATURE_PADDING - data_n);
1507 memcpy (buffer + (i * SSH_DSA_SIGNATURE_PADDING)
1508 + (SSH_DSA_SIGNATURE_PADDING - data_n), data, data_n);
1516 err = stream_write_string (signature_blob, buffer, sizeof (buffer));
1520 gcry_sexp_release (valuelist);
1521 gcry_sexp_release (sublist);
1522 mpint_list_free (mpis);
1527 /* Signature encoder function for ECDSA. */
1529 ssh_signature_encoder_ecdsa (ssh_key_type_spec_t *spec,
1530 estream_t stream, gcry_sexp_t s_signature)
1532 gpg_error_t err = 0;
1533 gcry_sexp_t valuelist = NULL;
1534 gcry_sexp_t sublist = NULL;
1535 gcry_mpi_t sig_value = NULL;
1536 gcry_mpi_t *mpis = NULL;
1541 unsigned char *data[2] = {NULL, NULL};
1545 valuelist = gcry_sexp_nth (s_signature, 1);
1548 err = gpg_error (GPG_ERR_INV_SEXP);
1552 elems = spec->elems_signature;
1553 elems_n = strlen (elems);
1555 mpis = xtrycalloc (elems_n + 1, sizeof *mpis);
1558 err = gpg_error_from_syserror ();
1562 for (i = 0; i < elems_n; i++)
1564 sublist = gcry_sexp_find_token (valuelist, spec->elems_signature + i, 1);
1567 err = gpg_error (GPG_ERR_INV_SEXP);
1571 sig_value = gcry_sexp_nth_mpi (sublist, 1, GCRYMPI_FMT_USG);
1574 err = gpg_error (GPG_ERR_INTERNAL); /* FIXME? */
1577 gcry_sexp_release (sublist);
1580 mpis[i] = sig_value;
1585 /* ECDSA specific */
1588 for (i = 0; i < DIM(data); i++)
1590 err = gcry_mpi_aprint (GCRYMPI_FMT_STD, &data[i], &data_n[i], mpis[i]);
1593 innerlen += 4 + data_n[i];
1596 err = stream_write_uint32 (stream, innerlen);
1600 for (i = 0; i < DIM(data); i++)
1602 err = stream_write_string (stream, data[i], data_n[i]);
1608 for (i = 0; i < DIM(data); i++)
1610 gcry_sexp_release (valuelist);
1611 gcry_sexp_release (sublist);
1612 mpint_list_free (mpis);
1617 /* Signature encoder function for EdDSA. */
1619 ssh_signature_encoder_eddsa (ssh_key_type_spec_t *spec,
1620 estream_t stream, gcry_sexp_t s_signature)
1622 gpg_error_t err = 0;
1623 gcry_sexp_t valuelist = NULL;
1624 gcry_sexp_t sublist = NULL;
1629 unsigned char *data[2] = {NULL, NULL};
1631 size_t totallen = 0;
1633 valuelist = gcry_sexp_nth (s_signature, 1);
1636 err = gpg_error (GPG_ERR_INV_SEXP);
1640 elems = spec->elems_signature;
1641 elems_n = strlen (elems);
1643 if (elems_n != DIM(data))
1645 err = gpg_error (GPG_ERR_INV_SEXP);
1649 for (i = 0; i < DIM(data); i++)
1651 sublist = gcry_sexp_find_token (valuelist, spec->elems_signature + i, 1);
1654 err = gpg_error (GPG_ERR_INV_SEXP);
1658 data[i] = gcry_sexp_nth_buffer (sublist, 1, &data_n[i]);
1661 err = gpg_error (GPG_ERR_INTERNAL); /* FIXME? */
1664 totallen += data_n[i];
1665 gcry_sexp_release (sublist);
1671 err = stream_write_uint32 (stream, totallen);
1675 for (i = 0; i < DIM(data); i++)
1677 err = stream_write_data (stream, data[i], data_n[i]);
1683 for (i = 0; i < DIM(data); i++)
1685 gcry_sexp_release (valuelist);
1686 gcry_sexp_release (sublist);
1696 /* This function constructs a new S-Expression for the key identified
1697 by the KEY_SPEC, SECRET, CURVE_NAME, MPIS, and COMMENT, which is to
1698 be stored at R_SEXP. Returns an error code. */
1700 sexp_key_construct (gcry_sexp_t *r_sexp,
1701 ssh_key_type_spec_t key_spec, int secret,
1702 const char *curve_name, gcry_mpi_t *mpis,
1703 const char *comment)
1706 gcry_sexp_t sexp_new = NULL;
1707 void *formatbuf = NULL;
1708 void **arg_list = NULL;
1709 estream_t format = NULL;
1710 char *algo_name = NULL;
1712 if ((key_spec.flags & SPEC_FLAG_IS_EdDSA))
1714 /* It is much easier and more readable to use a separate code
1717 err = gpg_error (GPG_ERR_INV_CURVE);
1718 else if (!mpis[0] || !gcry_mpi_get_flag (mpis[0], GCRYMPI_FLAG_OPAQUE))
1719 err = gpg_error (GPG_ERR_BAD_PUBKEY);
1722 || !gcry_mpi_get_flag (mpis[1], GCRYMPI_FLAG_OPAQUE)))
1723 err = gpg_error (GPG_ERR_BAD_SECKEY);
1725 err = gcry_sexp_build (&sexp_new, NULL,
1726 "(private-key(ecc(curve %s)"
1727 "(flags eddsa)(q %m)(d %m))"
1731 comment? comment:"");
1733 err = gcry_sexp_build (&sexp_new, NULL,
1734 "(public-key(ecc(curve %s)"
1735 "(flags eddsa)(q %m))"
1739 comment? comment:"");
1743 const char *key_identifier[] = { "public-key", "private-key" };
1750 elems = key_spec.elems_sexp_order;
1752 elems = key_spec.elems_key_public;
1753 elems_n = strlen (elems);
1755 format = es_fopenmem (0, "a+b");
1758 err = gpg_error_from_syserror ();
1762 /* Key identifier, algorithm identifier, mpis, comment, and a NULL
1764 arg_list = xtrymalloc (sizeof (*arg_list) * (2 + 1 + elems_n + 1 + 1));
1767 err = gpg_error_from_syserror ();
1772 es_fputs ("(%s(%s", format);
1773 arg_list[arg_idx++] = &key_identifier[secret];
1774 algo_name = xtrystrdup (gcry_pk_algo_name (key_spec.algo));
1777 err = gpg_error_from_syserror ();
1781 arg_list[arg_idx++] = &algo_name;
1784 es_fputs ("(curve%s)", format);
1785 arg_list[arg_idx++] = &curve_name;
1788 for (i = 0; i < elems_n; i++)
1790 es_fprintf (format, "(%c%%m)", elems[i]);
1793 for (j = 0; j < elems_n; j++)
1794 if (key_spec.elems_key_secret[j] == elems[i])
1799 arg_list[arg_idx++] = &mpis[j];
1801 es_fputs (")(comment%s))", format);
1802 arg_list[arg_idx++] = &comment;
1803 arg_list[arg_idx] = NULL;
1805 es_putc (0, format);
1806 if (es_ferror (format))
1808 err = gpg_error_from_syserror ();
1811 if (es_fclose_snatch (format, &formatbuf, NULL))
1813 err = gpg_error_from_syserror ();
1818 err = gcry_sexp_build_array (&sexp_new, NULL, formatbuf, arg_list);
1834 /* This function extracts the key from the s-expression SEXP according
1835 to KEY_SPEC and stores it in ssh format at (R_BLOB, R_BLOBLEN). If
1836 WITH_SECRET is true, the secret key parts are also extracted if
1837 possible. Returns 0 on success or an error code. Note that data
1838 stored at R_BLOB must be freed using es_free! */
1840 ssh_key_to_blob (gcry_sexp_t sexp, int with_secret,
1841 ssh_key_type_spec_t key_spec,
1842 void **r_blob, size_t *r_blob_size)
1844 gpg_error_t err = 0;
1845 gcry_sexp_t value_list = NULL;
1846 gcry_sexp_t value_pair = NULL;
1847 char *curve_name = NULL;
1848 estream_t stream = NULL;
1851 const char *elems, *p_elems;
1858 stream = es_fopenmem (0, "r+b");
1861 err = gpg_error_from_syserror ();
1865 /* Get the type of the key extpression. */
1866 data = gcry_sexp_nth_data (sexp, 0, &datalen);
1869 err = gpg_error (GPG_ERR_INV_SEXP);
1873 if ((datalen == 10 && !strncmp (data, "public-key", 10))
1874 || (datalen == 21 && !strncmp (data, "protected-private-key", 21))
1875 || (datalen == 20 && !strncmp (data, "shadowed-private-key", 20)))
1876 elems = key_spec.elems_key_public;
1877 else if (datalen == 11 && !strncmp (data, "private-key", 11))
1878 elems = with_secret? key_spec.elems_key_secret : key_spec.elems_key_public;
1881 err = gpg_error (GPG_ERR_INV_SEXP);
1885 /* Get key value list. */
1886 value_list = gcry_sexp_cadr (sexp);
1889 err = gpg_error (GPG_ERR_INV_SEXP);
1893 /* Write the ssh algorithm identifier. */
1894 if ((key_spec.flags & SPEC_FLAG_IS_ECDSA))
1896 /* Parse the "curve" parameter. We currently expect the curve
1897 name for ECC and not the parameters of the curve. This can
1898 easily be changed but then we need to find the curve name
1899 from the parameters using gcry_pk_get_curve. */
1901 const char *sshname;
1903 gcry_sexp_release (value_pair);
1904 value_pair = gcry_sexp_find_token (value_list, "curve", 5);
1907 err = gpg_error (GPG_ERR_INV_CURVE);
1910 curve_name = gcry_sexp_nth_string (value_pair, 1);
1913 err = gpg_error (GPG_ERR_INV_CURVE); /* (Or out of core.) */
1917 /* Fixme: The mapping should be done by using gcry_pk_get_curve
1918 et al to iterate over all name aliases. */
1919 if (!strcmp (curve_name, "NIST P-256"))
1920 mapped = "nistp256";
1921 else if (!strcmp (curve_name, "NIST P-384"))
1922 mapped = "nistp384";
1923 else if (!strcmp (curve_name, "NIST P-521"))
1924 mapped = "nistp521";
1930 curve_name = xtrystrdup (mapped);
1933 err = gpg_error_from_syserror ();
1938 sshname = ssh_identifier_from_curve_name (curve_name);
1941 err = gpg_error (GPG_ERR_UNKNOWN_CURVE);
1944 err = stream_write_cstring (stream, sshname);
1947 err = stream_write_cstring (stream, curve_name);
1953 /* Note: This is also used for EdDSA. */
1954 err = stream_write_cstring (stream, key_spec.ssh_identifier);
1959 /* Write the parameters. */
1960 for (p_elems = elems; *p_elems; p_elems++)
1962 gcry_sexp_release (value_pair);
1963 value_pair = gcry_sexp_find_token (value_list, p_elems, 1);
1966 err = gpg_error (GPG_ERR_INV_SEXP);
1969 if ((key_spec.flags & SPEC_FLAG_IS_EdDSA))
1972 data = gcry_sexp_nth_data (value_pair, 1, &datalen);
1975 err = gpg_error (GPG_ERR_INV_SEXP);
1978 if (*p_elems == 'q' && datalen)
1979 { /* Remove the prefix 0x40. */
1983 err = stream_write_string (stream, data, datalen);
1991 /* Note that we need to use STD format; i.e. prepend a 0x00
1992 to indicate a positive number if the high bit is set. */
1993 mpi = gcry_sexp_nth_mpi (value_pair, 1, GCRYMPI_FMT_STD);
1996 err = gpg_error (GPG_ERR_INV_SEXP);
1999 err = stream_write_mpi (stream, mpi);
2000 gcry_mpi_release (mpi);
2006 if (es_fclose_snatch (stream, &blob, &blob_size))
2008 err = gpg_error_from_syserror ();
2015 *r_blob_size = blob_size;
2018 gcry_sexp_release (value_list);
2019 gcry_sexp_release (value_pair);
2034 /* Search for a key specification entry. If SSH_NAME is not NULL,
2035 search for an entry whose "ssh_name" is equal to SSH_NAME;
2036 otherwise, search for an entry whose algorithm is equal to ALGO.
2037 Store found entry in SPEC on success, return error otherwise. */
2039 ssh_key_type_lookup (const char *ssh_name, int algo,
2040 ssh_key_type_spec_t *spec)
2045 for (i = 0; i < DIM (ssh_key_types); i++)
2046 if ((ssh_name && (! strcmp (ssh_name, ssh_key_types[i].ssh_identifier)))
2047 || algo == ssh_key_types[i].algo)
2050 if (i == DIM (ssh_key_types))
2051 err = gpg_error (GPG_ERR_NOT_FOUND);
2054 *spec = ssh_key_types[i];
2062 /* Receive a key from STREAM, according to the key specification given
2063 as KEY_SPEC. Depending on SECRET, receive a secret or a public
2064 key. If READ_COMMENT is true, receive a comment string as well.
2065 Constructs a new S-Expression from received data and stores it in
2066 KEY_NEW. Returns zero on success or an error code. */
2068 ssh_receive_key (estream_t stream, gcry_sexp_t *key_new, int secret,
2069 int read_comment, ssh_key_type_spec_t *key_spec)
2072 char *key_type = NULL;
2073 char *comment = NULL;
2074 estream_t cert = NULL;
2075 gcry_sexp_t key = NULL;
2076 ssh_key_type_spec_t spec;
2077 gcry_mpi_t *mpi_list = NULL;
2079 char *curve_name = NULL;
2082 err = stream_read_cstring (stream, &key_type);
2086 err = ssh_key_type_lookup (key_type, 0, &spec);
2090 if ((spec.flags & SPEC_FLAG_WITH_CERT))
2092 /* This is an OpenSSH certificate+private key. The certificate
2093 is an SSH string and which we store in an estream object. */
2094 unsigned char *buffer;
2096 char *cert_key_type;
2098 err = stream_read_string (stream, 0, &buffer, &buflen);
2101 cert = es_fopenmem_init (0, "rb", buffer, buflen);
2105 err = gpg_error_from_syserror ();
2109 /* Check that the key type matches. */
2110 err = stream_read_cstring (cert, &cert_key_type);
2113 if (strcmp (cert_key_type, key_type) )
2115 xfree (cert_key_type);
2116 log_error ("key types in received ssh certificate do not match\n");
2117 err = gpg_error (GPG_ERR_INV_CERT_OBJ);
2120 xfree (cert_key_type);
2122 /* Skip the nonce. */
2123 err = stream_read_string (cert, 0, NULL, NULL);
2128 if ((spec.flags & SPEC_FLAG_IS_EdDSA))
2130 /* The format of an EdDSA key is:
2131 * string key_type ("ssh-ed25519")
2133 * string private_key
2135 * Note that the private key is the concatenation of the private
2136 * key with the public key. Thus there's are 64 bytes; however
2137 * we only want the real 32 byte private key - Libgcrypt expects
2140 mpi_list = xtrycalloc (3, sizeof *mpi_list);
2143 err = gpg_error_from_syserror ();
2147 err = stream_read_blob (cert? cert : stream, 0, &mpi_list[0]);
2153 unsigned char *buffer;
2155 /* Read string length. */
2156 err = stream_read_uint32 (stream, &len);
2159 if (len != 32 && len != 64)
2161 err = gpg_error (GPG_ERR_BAD_SECKEY);
2164 buffer = xtrymalloc_secure (32);
2167 err = gpg_error_from_syserror ();
2170 err = stream_read_data (stream, buffer, 32);
2176 mpi_list[1] = gcry_mpi_set_opaque (NULL, buffer, 8*32);
2180 err = stream_read_skip (stream, 32);
2186 else if ((spec.flags & SPEC_FLAG_IS_ECDSA))
2188 /* The format of an ECDSA key is:
2189 * string key_type ("ecdsa-sha2-nistp256" |
2190 * "ecdsa-sha2-nistp384" |
2191 * "ecdsa-sha2-nistp521" )
2192 * string ecdsa_curve_name
2193 * string ecdsa_public_key
2194 * mpint ecdsa_private
2196 * Note that we use the mpint reader instead of the string
2197 * reader for ecsa_public_key. For the certificate variante
2198 * ecdsa_curve_name+ecdsa_public_key are replaced by the
2201 unsigned char *buffer;
2204 err = stream_read_string (cert? cert : stream, 0, &buffer, NULL);
2207 curve_name = buffer;
2208 /* Fixme: Check that curve_name matches the keytype. */
2209 /* Because Libgcrypt < 1.6 has no support for the "nistpNNN"
2210 curve names, we need to translate them here to Libgcrypt's
2212 if (!strcmp (curve_name, "nistp256"))
2213 mapped = "NIST P-256";
2214 else if (!strcmp (curve_name, "nistp384"))
2215 mapped = "NIST P-384";
2216 else if (!strcmp (curve_name, "nistp521"))
2217 mapped = "NIST P-521";
2223 curve_name = xtrystrdup (mapped);
2226 err = gpg_error_from_syserror ();
2231 err = ssh_receive_mpint_list (stream, secret, &spec, cert, &mpi_list);
2237 err = ssh_receive_mpint_list (stream, secret, &spec, cert, &mpi_list);
2244 err = stream_read_cstring (stream, &comment);
2250 elems = spec.elems_key_secret;
2252 elems = spec.elems_key_public;
2254 if (spec.key_modifier)
2256 err = (*spec.key_modifier) (elems, mpi_list);
2261 if ((spec.flags & SPEC_FLAG_IS_EdDSA))
2265 err = gcry_sexp_build (&key, NULL,
2266 "(private-key(ecc(curve \"Ed25519\")"
2267 "(flags eddsa)(q %m)(d %m))"
2269 mpi_list[0], mpi_list[1],
2270 comment? comment:"");
2274 err = gcry_sexp_build (&key, NULL,
2275 "(public-key(ecc(curve \"Ed25519\")"
2276 "(flags eddsa)(q %m))"
2279 comment? comment:"");
2284 err = sexp_key_construct (&key, spec, secret, curve_name, mpi_list,
2285 comment? comment:"");
2296 mpint_list_free (mpi_list);
2305 /* Write the public key from KEY to STREAM in SSH key format. If
2306 OVERRIDE_COMMENT is not NULL, it will be used instead of the
2307 comment stored in the key. */
2309 ssh_send_key_public (estream_t stream, gcry_sexp_t key,
2310 const char *override_comment)
2312 ssh_key_type_spec_t spec;
2314 char *comment = NULL;
2317 gpg_error_t err = 0;
2319 algo = get_pk_algo_from_key (key);
2323 err = ssh_key_type_lookup (NULL, algo, &spec);
2327 err = ssh_key_to_blob (key, 0, spec, &blob, &bloblen);
2331 err = stream_write_string (stream, blob, bloblen);
2335 if (override_comment)
2336 err = stream_write_cstring (stream, override_comment);
2339 err = ssh_key_extract_comment (key, &comment);
2341 err = stream_write_cstring (stream, "(none)");
2343 err = stream_write_cstring (stream, comment);
2356 /* Read a public key out of BLOB/BLOB_SIZE according to the key
2357 specification given as KEY_SPEC, storing the new key in KEY_PUBLIC.
2358 Returns zero on success or an error code. */
2360 ssh_read_key_public_from_blob (unsigned char *blob, size_t blob_size,
2361 gcry_sexp_t *key_public,
2362 ssh_key_type_spec_t *key_spec)
2365 estream_t blob_stream;
2367 blob_stream = es_fopenmem (0, "r+b");
2370 err = gpg_error_from_syserror ();
2374 err = stream_write_data (blob_stream, blob, blob_size);
2378 err = es_fseek (blob_stream, 0, SEEK_SET);
2382 err = ssh_receive_key (blob_stream, key_public, 0, 0, key_spec);
2385 es_fclose (blob_stream);
2391 /* This function calculates the key grip for the key contained in the
2392 S-Expression KEY and writes it to BUFFER, which must be large
2393 enough to hold it. Returns usual error code. */
2395 ssh_key_grip (gcry_sexp_t key, unsigned char *buffer)
2397 if (!gcry_pk_get_keygrip (key, buffer))
2399 gpg_error_t err = gcry_pk_testkey (key);
2400 return err? err : gpg_error (GPG_ERR_INTERNAL);
2408 card_key_list (ctrl_t ctrl, char **r_serialno, strlist_t *result)
2415 err = agent_card_serialno (ctrl, r_serialno, NULL);
2418 if (gpg_err_code (err) != GPG_ERR_ENODEV && opt.verbose)
2419 log_info (_("error getting serial number of card: %s\n"),
2420 gpg_strerror (err));
2422 /* Nothing available. */
2426 err = agent_card_cardlist (ctrl, result);
2429 xfree (*r_serialno);
2435 /* Check whether a smartcard is available and whether it has a usable
2436 key. Store a copy of that key at R_PK and return 0. If no key is
2437 available store NULL at R_PK and return an error code. If CARDSN
2438 is not NULL, a string with the serial number of the card will be
2439 a malloced and stored there. */
2441 card_key_available (ctrl_t ctrl, gcry_sexp_t *r_pk, char **cardsn)
2445 char *serialno = NULL;
2446 unsigned char *pkbuf;
2449 unsigned char grip[20];
2455 /* First see whether a card is available and whether the application
2457 err = agent_card_getattr (ctrl, "$AUTHKEYID", &authkeyid);
2458 if ( gpg_err_code (err) == GPG_ERR_CARD_REMOVED )
2460 /* Ask for the serial number to reset the card. */
2461 err = agent_card_serialno (ctrl, &serialno, NULL);
2465 log_info (_("error getting serial number of card: %s\n"),
2466 gpg_strerror (err));
2469 log_info (_("detected card with S/N: %s\n"), serialno);
2470 err = agent_card_getattr (ctrl, "$AUTHKEYID", &authkeyid);
2474 log_error (_("no authentication key for ssh on card: %s\n"),
2475 gpg_strerror (err));
2480 /* Get the S/N if we don't have it yet. Use the fast getattr method. */
2481 if (!serialno && (err = agent_card_getattr (ctrl, "SERIALNO", &serialno)) )
2483 log_error (_("error getting serial number of card: %s\n"),
2484 gpg_strerror (err));
2489 /* Read the public key. */
2490 err = agent_card_readkey (ctrl, authkeyid, &pkbuf);
2494 log_info (_("no suitable card key found: %s\n"), gpg_strerror (err));
2500 pkbuflen = gcry_sexp_canon_len (pkbuf, 0, NULL, NULL);
2501 err = gcry_sexp_sscan (&s_pk, NULL, (char*)pkbuf, pkbuflen);
2504 log_error ("failed to build S-Exp from received card key: %s\n",
2505 gpg_strerror (err));
2512 err = ssh_key_grip (s_pk, grip);
2515 log_debug ("error computing keygrip from received card key: %s\n",
2516 gcry_strerror (err));
2518 gcry_sexp_release (s_pk);
2524 if ( agent_key_available (grip) )
2526 /* (Shadow)-key is not available in our key storage. */
2527 err = agent_write_shadow_key (grip, serialno, authkeyid, pkbuf, 0);
2531 gcry_sexp_release (s_pk);
2542 /* If the card handler is able to return a short serialnumber,
2543 use that one, else use the complete serialno. */
2544 if (!agent_card_getattr (ctrl, "$DISPSERIALNO", &dispsn))
2546 *cardsn = xtryasprintf ("cardno:%s", dispsn);
2550 *cardsn = xtryasprintf ("cardno:%s", serialno);
2553 err = gpg_error_from_syserror ();
2555 gcry_sexp_release (s_pk);
2574 Request handler. Each handler is provided with a CTRL context, a
2575 REQUEST object and a RESPONSE object. The actual request is to be
2576 read from REQUEST, the response needs to be written to RESPONSE.
2581 /* Handler for the "request_identities" command. */
2583 ssh_handler_request_identities (ctrl_t ctrl,
2584 estream_t request, estream_t response)
2587 estream_t key_blobs;
2588 gcry_sexp_t key_public;
2591 ssh_control_file_t cf = NULL;
2592 gpg_error_t ret_err;
2596 /* Prepare buffer stream. */
2601 key_blobs = es_fopenmem (0, "r+b");
2604 err = gpg_error_from_syserror ();
2608 /* First check whether a key is currently available in the card
2609 reader - this should be allowed even without being listed in
2612 if (!opt.disable_scdaemon)
2615 strlist_t card_list, sl;
2617 err = card_key_list (ctrl, &serialno, &card_list);
2621 log_info (_("error getting list of cards: %s\n"),
2622 gpg_strerror (err));
2626 for (sl = card_list; sl; sl = sl->next)
2631 err = agent_card_serialno (ctrl, &serialno0, sl->d);
2635 log_info (_("error getting serial number of card: %s\n"),
2636 gpg_strerror (err));
2641 if (card_key_available (ctrl, &key_public, &cardsn))
2644 err = ssh_send_key_public (key_blobs, key_public, cardsn);
2645 gcry_sexp_release (key_public);
2651 free_strlist (card_list);
2659 free_strlist (card_list);
2663 /* Then look at all the registered and non-disabled keys. */
2664 err = open_control_file (&cf, 0);
2668 while (!read_control_file_item (cf))
2670 unsigned char grip[20];
2672 if (!cf->item.valid)
2673 continue; /* Should not happen. */
2674 if (cf->item.disabled)
2676 assert (strlen (cf->item.hexgrip) == 40);
2677 hex2bin (cf->item.hexgrip, grip, sizeof (grip));
2679 err = agent_public_key_from_file (ctrl, grip, &key_public);
2682 log_error ("%s:%d: key '%s' skipped: %s\n",
2683 cf->fname, cf->lnr, cf->item.hexgrip,
2684 gpg_strerror (err));
2688 err = ssh_send_key_public (key_blobs, key_public, NULL);
2691 gcry_sexp_release (key_public);
2698 ret = es_fseek (key_blobs, 0, SEEK_SET);
2701 err = gpg_error_from_syserror ();
2706 /* Send response. */
2708 gcry_sexp_release (key_public);
2712 ret_err = stream_write_byte (response, SSH_RESPONSE_IDENTITIES_ANSWER);
2714 ret_err = stream_write_uint32 (response, key_counter);
2716 ret_err = stream_copy (response, key_blobs);
2720 ret_err = stream_write_byte (response, SSH_RESPONSE_FAILURE);
2723 es_fclose (key_blobs);
2724 close_control_file (cf);
2730 /* This function hashes the data contained in DATA of size DATA_N
2731 according to the message digest algorithm specified by MD_ALGORITHM
2732 and writes the message digest to HASH, which needs to large enough
2735 data_hash (unsigned char *data, size_t data_n,
2736 int md_algorithm, unsigned char *hash)
2738 gcry_md_hash_buffer (md_algorithm, hash, data, data_n);
2744 /* This function signs the data described by CTRL. If HASH is not
2745 NULL, (HASH,HASHLEN) overrides the hash stored in CTRL. This is to
2746 allow the use of signature algorithms that implement the hashing
2747 internally (e.g. Ed25519). On success the created signature is
2748 stored in ssh format at R_SIG and it's size at R_SIGLEN; the caller
2749 must use es_free to releaase this memory. */
2751 data_sign (ctrl_t ctrl, ssh_key_type_spec_t *spec,
2752 const void *hash, size_t hashlen,
2753 unsigned char **r_sig, size_t *r_siglen)
2756 gcry_sexp_t signature_sexp = NULL;
2757 estream_t stream = NULL;
2765 /* Quick check to see whether we have a valid keygrip and convert it
2767 if (!ctrl->have_keygrip)
2769 err = gpg_error (GPG_ERR_NO_SECKEY);
2772 bin2hex (ctrl->keygrip, 20, hexgrip);
2774 /* Ask for confirmation if needed. */
2775 if (confirm_flag_from_sshcontrol (hexgrip))
2779 char *comment = NULL;
2781 err = agent_raw_key_from_file (ctrl, ctrl->keygrip, &key);
2784 err = ssh_get_fingerprint_string (key, opt.ssh_fingerprint_digest, &fpr);
2787 gcry_sexp_t tmpsxp = gcry_sexp_find_token (key, "comment", 0);
2789 comment = gcry_sexp_nth_string (tmpsxp, 1);
2790 gcry_sexp_release (tmpsxp);
2792 gcry_sexp_release (key);
2795 prompt = xtryasprintf (L_("An ssh process requested the use of key%%0A"
2798 "Do you want to allow this?"),
2799 fpr, comment? comment:"");
2801 gcry_free (comment);
2802 err = agent_get_confirmation (ctrl, prompt, L_("Allow"), L_("Deny"), 0);
2808 /* Create signature. */
2809 ctrl->use_auth_call = 1;
2810 err = agent_pksign_do (ctrl, NULL,
2811 L_("Please enter the passphrase "
2812 "for the ssh key%%0A %F%%0A (%c)"),
2814 CACHE_MODE_SSH, ttl_from_sshcontrol,
2816 ctrl->use_auth_call = 0;
2820 stream = es_fopenmem (0, "r+b");
2823 err = gpg_error_from_syserror ();
2827 err = stream_write_cstring (stream, spec->ssh_identifier);
2831 err = spec->signature_encoder (spec, stream, signature_sexp);
2835 err = es_fclose_snatch (stream, &blob, &bloblen);
2840 *r_sig = blob; blob = NULL;
2841 *r_siglen = bloblen;
2846 gcry_sexp_release (signature_sexp);
2852 /* Handler for the "sign_request" command. */
2854 ssh_handler_sign_request (ctrl_t ctrl, estream_t request, estream_t response)
2856 gcry_sexp_t key = NULL;
2857 ssh_key_type_spec_t spec;
2858 unsigned char hash[MAX_DIGEST_LEN];
2859 unsigned int hash_n;
2860 unsigned char key_grip[20];
2861 unsigned char *key_blob = NULL;
2863 unsigned char *data = NULL;
2864 unsigned char *sig = NULL;
2868 gpg_error_t ret_err;
2873 err = stream_read_string (request, 0, &key_blob, &key_blob_size);
2877 err = ssh_read_key_public_from_blob (key_blob, key_blob_size, &key, &spec);
2881 /* Receive data to sign. */
2882 err = stream_read_string (request, 0, &data, &data_size);
2886 /* Flag processing. */
2890 err = stream_read_uint32 (request, &flags);
2894 if (spec.algo == GCRY_PK_RSA)
2896 if ((flags & SSH_AGENT_RSA_SHA2_512))
2898 flags &= ~SSH_AGENT_RSA_SHA2_512;
2899 spec.ssh_identifier = "rsa-sha2-512";
2900 spec.hash_algo = GCRY_MD_SHA512;
2902 if ((flags & SSH_AGENT_RSA_SHA2_256))
2904 /* Note: We prefer SHA256 over SHA512. */
2905 flags &= ~SSH_AGENT_RSA_SHA2_256;
2906 spec.ssh_identifier = "rsa-sha2-256";
2907 spec.hash_algo = GCRY_MD_SHA256;
2911 /* Some flag is present that we do not know about. Note that
2912 * processed or known flags have been cleared at this point. */
2915 err = gpg_error (GPG_ERR_UNKNOWN_OPTION);
2920 hash_algo = spec.hash_algo;
2922 hash_algo = GCRY_MD_SHA1; /* Use the default. */
2923 ctrl->digest.algo = hash_algo;
2924 if ((spec.flags & SPEC_FLAG_USE_PKCS1V2))
2925 ctrl->digest.raw_value = 0;
2927 ctrl->digest.raw_value = 1;
2929 /* Calculate key grip. */
2930 err = ssh_key_grip (key, key_grip);
2933 ctrl->have_keygrip = 1;
2934 memcpy (ctrl->keygrip, key_grip, 20);
2936 /* Hash data unless we use EdDSA. */
2937 if ((spec.flags & SPEC_FLAG_IS_EdDSA))
2939 ctrl->digest.valuelen = 0;
2943 hash_n = gcry_md_get_algo_dlen (hash_algo);
2946 err = gpg_error (GPG_ERR_INTERNAL);
2949 err = data_hash (data, data_size, hash_algo, hash);
2952 memcpy (ctrl->digest.value, hash, hash_n);
2953 ctrl->digest.valuelen = hash_n;
2957 if ((spec.flags & SPEC_FLAG_IS_EdDSA))
2958 err = data_sign (ctrl, &spec, data, data_size, &sig, &sig_n);
2960 err = data_sign (ctrl, &spec, NULL, 0, &sig, &sig_n);
2966 ret_err = stream_write_byte (response, SSH_RESPONSE_SIGN_RESPONSE);
2969 ret_err = stream_write_string (response, sig, sig_n);
2975 log_error ("ssh sign request failed: %s <%s>\n",
2976 gpg_strerror (err), gpg_strsource (err));
2977 ret_err = stream_write_byte (response, SSH_RESPONSE_FAILURE);
2984 gcry_sexp_release (key);
2993 /* This function extracts the comment contained in the key
2994 s-expression KEY and stores a copy in COMMENT. Returns usual error
2997 ssh_key_extract_comment (gcry_sexp_t key, char **r_comment)
2999 gcry_sexp_t comment_list;
3003 comment_list = gcry_sexp_find_token (key, "comment", 0);
3005 return gpg_error (GPG_ERR_INV_SEXP);
3007 *r_comment = gcry_sexp_nth_string (comment_list, 1);
3008 gcry_sexp_release (comment_list);
3010 return gpg_error (GPG_ERR_INV_SEXP);
3016 /* This function converts the key contained in the S-Expression KEY
3017 into a buffer, which is protected by the passphrase PASSPHRASE.
3018 If PASSPHRASE is the empty passphrase, the key is not protected.
3019 Returns usual error code. */
3021 ssh_key_to_protected_buffer (gcry_sexp_t key, const char *passphrase,
3022 unsigned char **buffer, size_t *buffer_n)
3024 unsigned char *buffer_new;
3025 unsigned int buffer_new_n;
3028 buffer_new_n = gcry_sexp_sprint (key, GCRYSEXP_FMT_CANON, NULL, 0);
3029 buffer_new = xtrymalloc_secure (buffer_new_n);
3032 err = gpg_error_from_syserror ();
3036 gcry_sexp_sprint (key, GCRYSEXP_FMT_CANON, buffer_new, buffer_new_n);
3037 /* FIXME: guarantee? */
3040 err = agent_protect (buffer_new, passphrase, buffer, buffer_n, 0, -1);
3043 /* The key derivation function does not support zero length
3044 * strings. Store key unprotected if the user wishes so. */
3045 *buffer = buffer_new;
3046 *buffer_n = buffer_new_n;
3060 /* Callback function to compare the first entered PIN with the one
3061 currently being entered. */
3063 reenter_compare_cb (struct pin_entry_info_s *pi)
3065 const char *pin1 = pi->check_cb_arg;
3067 if (!strcmp (pin1, pi->pin))
3068 return 0; /* okay */
3069 return gpg_error (GPG_ERR_BAD_PASSPHRASE);
3073 /* Store the ssh KEY into our local key storage and protect it after
3074 asking for a passphrase. Cache that passphrase. TTL is the
3075 maximum caching time for that key. If the key already exists in
3076 our key storage, don't do anything. When entering a key also add
3077 an entry to the sshcontrol file. */
3079 ssh_identity_register (ctrl_t ctrl, ssh_key_type_spec_t *spec,
3080 gcry_sexp_t key, int ttl, int confirm)
3083 unsigned char key_grip_raw[20];
3085 unsigned char *buffer = NULL;
3087 char *description = NULL;
3088 const char *description2 = L_("Please re-enter this passphrase");
3089 char *comment = NULL;
3090 char *key_fpr = NULL;
3091 const char *initial_errtext = NULL;
3092 struct pin_entry_info_s *pi = NULL;
3093 struct pin_entry_info_s *pi2 = NULL;
3095 err = ssh_key_grip (key, key_grip_raw);
3099 bin2hex (key_grip_raw, 20, key_grip);
3101 err = ssh_get_fingerprint_string (key, opt.ssh_fingerprint_digest, &key_fpr);
3105 /* Check whether the key is already in our key storage. Don't do
3106 anything then besides (re-)adding it to sshcontrol. */
3107 if ( !agent_key_available (key_grip_raw) )
3108 goto key_exists; /* Yes, key is available. */
3110 err = ssh_key_extract_comment (key, &comment);
3114 if ( asprintf (&description,
3115 L_("Please enter a passphrase to protect"
3116 " the received secret key%%0A"
3119 "within gpg-agent's key storage"),
3120 key_fpr, comment ? comment : "") < 0)
3122 err = gpg_error_from_syserror ();
3126 pi = gcry_calloc_secure (1, sizeof (*pi) + MAX_PASSPHRASE_LEN + 1);
3129 err = gpg_error_from_syserror ();
3132 pi2 = gcry_calloc_secure (1, sizeof (*pi2) + MAX_PASSPHRASE_LEN + 1);
3135 err = gpg_error_from_syserror ();
3138 pi->max_length = MAX_PASSPHRASE_LEN + 1;
3140 pi->with_repeat = 1;
3141 pi2->max_length = MAX_PASSPHRASE_LEN + 1;
3143 pi2->check_cb = reenter_compare_cb;
3144 pi2->check_cb_arg = pi->pin;
3147 err = agent_askpin (ctrl, description, NULL, initial_errtext, pi, NULL, 0);
3148 initial_errtext = NULL;
3152 /* Unless the passphrase is empty or the pinentry told us that
3153 it already did the repetition check, ask to confirm it. */
3154 if (*pi->pin && !pi->repeat_okay)
3156 err = agent_askpin (ctrl, description2, NULL, NULL, pi2, NULL, 0);
3157 if (gpg_err_code (err) == GPG_ERR_BAD_PASSPHRASE)
3158 { /* The re-entered one did not match and the user did not
3160 initial_errtext = L_("does not match - try again");
3165 err = ssh_key_to_protected_buffer (key, pi->pin, &buffer, &buffer_n);
3169 /* Store this key to our key storage. */
3170 err = agent_write_private_key (key_grip_raw, buffer, buffer_n, 0);
3174 /* Cache this passphrase. */
3175 err = agent_put_cache (ctrl, key_grip, CACHE_MODE_SSH, pi->pin, ttl);
3180 /* And add an entry to the sshcontrol file. */
3181 err = add_control_entry (ctrl, spec, key_grip, key, ttl, confirm);
3185 if (pi2 && pi2->max_length)
3186 wipememory (pi2->pin, pi2->max_length);
3188 if (pi && pi->max_length)
3189 wipememory (pi->pin, pi->max_length);
3194 xfree (description);
3200 /* This function removes the key contained in the S-Expression KEY
3201 from the local key storage, in case it exists there. Returns usual
3202 error code. FIXME: this function is a stub. */
3204 ssh_identity_drop (gcry_sexp_t key)
3206 unsigned char key_grip[21] = { 0 };
3209 err = ssh_key_grip (key, key_grip);
3213 key_grip[sizeof (key_grip) - 1] = 0;
3215 /* FIXME: What to do here - forgetting the passphrase or deleting
3216 the key from key cache? */
3223 /* Handler for the "add_identity" command. */
3225 ssh_handler_add_identity (ctrl_t ctrl, estream_t request, estream_t response)
3227 gpg_error_t ret_err;
3228 ssh_key_type_spec_t spec;
3240 err = ssh_receive_key (request, &key, 1, 1, &spec);
3246 err = stream_read_byte (request, &b);
3249 if (gpg_err_code (err) == GPG_ERR_EOF)
3256 case SSH_OPT_CONSTRAIN_LIFETIME:
3260 err = stream_read_uint32 (request, &n);
3266 case SSH_OPT_CONSTRAIN_CONFIRM:
3273 /* FIXME: log/bad? */
3280 err = ssh_identity_register (ctrl, &spec, key, ttl, confirm);
3284 gcry_sexp_release (key);
3287 ret_err = stream_write_byte (response, SSH_RESPONSE_SUCCESS);
3289 ret_err = stream_write_byte (response, SSH_RESPONSE_FAILURE);
3294 /* Handler for the "remove_identity" command. */
3296 ssh_handler_remove_identity (ctrl_t ctrl,
3297 estream_t request, estream_t response)
3299 unsigned char *key_blob;
3302 gpg_error_t ret_err;
3312 err = stream_read_string (request, 0, &key_blob, &key_blob_size);
3316 err = ssh_read_key_public_from_blob (key_blob, key_blob_size, &key, NULL);
3320 err = ssh_identity_drop (key);
3325 gcry_sexp_release (key);
3328 ret_err = stream_write_byte (response, SSH_RESPONSE_SUCCESS);
3330 ret_err = stream_write_byte (response, SSH_RESPONSE_FAILURE);
3335 /* FIXME: stub function. Actually useful? */
3337 ssh_identities_remove_all (void)
3343 /* FIXME: shall we remove _all_ cache entries or only those
3344 registered through the ssh-agent protocol? */
3349 /* Handler for the "remove_all_identities" command. */
3351 ssh_handler_remove_all_identities (ctrl_t ctrl,
3352 estream_t request, estream_t response)
3354 gpg_error_t ret_err;
3360 err = ssh_identities_remove_all ();
3363 ret_err = stream_write_byte (response, SSH_RESPONSE_SUCCESS);
3365 ret_err = stream_write_byte (response, SSH_RESPONSE_FAILURE);
3370 /* Lock agent? FIXME: stub function. */
3377 log_error ("ssh-agent's lock command is not implemented\n");
3383 /* Unock agent? FIXME: stub function. */
3389 log_error ("ssh-agent's unlock command is not implemented\n");
3395 /* Handler for the "lock" command. */
3397 ssh_handler_lock (ctrl_t ctrl, estream_t request, estream_t response)
3399 gpg_error_t ret_err;
3408 ret_err = stream_write_byte (response, SSH_RESPONSE_SUCCESS);
3410 ret_err = stream_write_byte (response, SSH_RESPONSE_FAILURE);
3415 /* Handler for the "unlock" command. */
3417 ssh_handler_unlock (ctrl_t ctrl, estream_t request, estream_t response)
3419 gpg_error_t ret_err;
3425 err = ssh_unlock ();
3428 ret_err = stream_write_byte (response, SSH_RESPONSE_SUCCESS);
3430 ret_err = stream_write_byte (response, SSH_RESPONSE_FAILURE);
3437 /* Return the request specification for the request identified by TYPE
3438 or NULL in case the requested request specification could not be
3440 static const ssh_request_spec_t *
3441 request_spec_lookup (int type)
3443 const ssh_request_spec_t *spec;
3446 for (i = 0; i < DIM (request_specs); i++)
3447 if (request_specs[i].type == type)
3449 if (i == DIM (request_specs))
3452 log_info ("ssh request %u is not supported\n", type);
3456 spec = request_specs + i;
3461 /* Process a single request. The request is read from and the
3462 response is written to STREAM_SOCK. Uses CTRL as context. Returns
3463 zero in case of success, non zero in case of failure. */
3465 ssh_request_process (ctrl_t ctrl, estream_t stream_sock)
3467 const ssh_request_spec_t *spec;
3468 estream_t response = NULL;
3469 estream_t request = NULL;
3470 unsigned char request_type;
3474 unsigned char *request_data = NULL;
3475 u32 request_data_size;
3478 /* Create memory streams for request/response data. The entire
3479 request will be stored in secure memory, since it might contain
3480 secret key material. The response does not have to be stored in
3481 secure memory, since we never give out secret keys.
3483 Note: we only have little secure memory, but there is NO
3484 possibility of DoS here; only trusted clients are allowed to
3485 connect to the agent. What could happen is that the agent
3486 returns out-of-secure-memory errors on requests in case the
3487 agent's owner floods his own agent with many large messages.
3490 /* Retrieve request. */
3491 err = stream_read_string (stream_sock, 1, &request_data, &request_data_size);
3495 if (opt.verbose > 1)
3496 log_info ("received ssh request of length %u\n",
3497 (unsigned int)request_data_size);
3499 if (! request_data_size)
3503 /* Broken request; FIXME. */
3506 request_type = request_data[0];
3507 spec = request_spec_lookup (request_type);
3512 /* Unknown request; FIXME. */
3515 if (spec->secret_input)
3516 request = es_mopen (NULL, 0, 0, 1, realloc_secure, gcry_free, "r+b");
3518 request = es_mopen (NULL, 0, 0, 1, gcry_realloc, gcry_free, "r+b");
3521 err = gpg_error_from_syserror ();
3524 ret = es_setvbuf (request, NULL, _IONBF, 0);
3527 err = gpg_error_from_syserror ();
3530 err = stream_write_data (request, request_data + 1, request_data_size - 1);
3533 es_rewind (request);
3535 response = es_fopenmem (0, "r+b");
3538 err = gpg_error_from_syserror ();
3543 log_info ("ssh request handler for %s (%u) started\n",
3544 spec->identifier, spec->type);
3546 err = (*spec->handler) (ctrl, request, response);
3551 log_info ("ssh request handler for %s (%u) failed: %s\n",
3552 spec->identifier, spec->type, gpg_strerror (err));
3554 log_info ("ssh request handler for %s (%u) ready\n",
3555 spec->identifier, spec->type);
3564 response_size = es_ftell (response);
3565 if (opt.verbose > 1)
3566 log_info ("sending ssh response of length %u\n",
3567 (unsigned int)response_size);
3569 err = es_fseek (response, 0, SEEK_SET);
3576 err = stream_write_uint32 (stream_sock, response_size);
3583 err = stream_copy (stream_sock, response);
3587 err = es_fflush (stream_sock);
3593 if (err && es_feof (stream_sock))
3594 log_error ("error occurred while processing request: %s\n",
3595 gpg_strerror (err));
3599 if (opt.verbose > 1)
3600 log_info ("sending ssh error response\n");
3601 err = stream_write_uint32 (stream_sock, 1);
3604 err = stream_write_byte (stream_sock, SSH_RESPONSE_FAILURE);
3611 es_fclose (request);
3612 es_fclose (response);
3613 xfree (request_data);
3619 /* Return the peer's pid. */
3620 static unsigned long
3621 get_client_pid (int fd)
3623 pid_t client_pid = (pid_t)0;
3627 #ifdef HAVE_STRUCT_SOCKPEERCRED_PID
3628 struct sockpeercred cr;
3632 socklen_t cl = sizeof cr;
3634 if (!getsockopt (fd, SOL_SOCKET, SO_PEERCRED, &cr, &cl))
3636 #if defined (HAVE_STRUCT_SOCKPEERCRED_PID) || defined (HAVE_STRUCT_UCRED_PID)
3637 client_pid = cr.pid;
3638 #elif defined (HAVE_STRUCT_UCRED_CR_PID)
3639 client_pid = cr.cr_pid;
3641 #error "Unknown SO_PEERCRED struct"
3645 #elif defined (LOCAL_PEERPID)
3647 socklen_t len = sizeof (pid_t);
3649 getsockopt (fd, SOL_LOCAL, LOCAL_PEERPID, &client_pid, &len);
3651 #elif defined (LOCAL_PEEREID)
3654 socklen_t unpl = sizeof unp;
3656 if (getsockopt (fd, 0, LOCAL_PEEREID, &unp, &unpl) != -1)
3657 client_pid = unp.unp_pid;
3659 #elif defined (HAVE_GETPEERUCRED)
3661 ucred_t *ucred = NULL;
3663 if (getpeerucred (fd, &ucred) != -1)
3665 client_pid= ucred_getpid (ucred);
3673 return (unsigned long)client_pid;
3677 /* Start serving client on SOCK_CLIENT. */
3679 start_command_handler_ssh (ctrl_t ctrl, gnupg_fd_t sock_client)
3681 estream_t stream_sock = NULL;
3685 err = agent_copy_startup_env (ctrl);
3689 ctrl->client_pid = get_client_pid (FD2INT(sock_client));
3691 /* Create stream from socket. */
3692 stream_sock = es_fdopen (FD2INT(sock_client), "r+");
3695 err = gpg_error_from_syserror ();
3696 log_error (_("failed to create stream from socket: %s\n"),
3697 gpg_strerror (err));
3700 /* We have to disable the estream buffering, because the estream
3701 core doesn't know about secure memory. */
3702 ret = es_setvbuf (stream_sock, NULL, _IONBF, 0);
3705 err = gpg_error_from_syserror ();
3706 log_error ("failed to disable buffering "
3707 "on socket stream: %s\n", gpg_strerror (err));
3711 /* Main processing loop. */
3712 while ( !ssh_request_process (ctrl, stream_sock) )
3714 /* Check whether we have reached EOF before trying to read
3718 c = es_fgetc (stream_sock);
3721 es_ungetc (c, stream_sock);
3724 /* Reset the SCD in case it has been used. */
3725 agent_reset_scd (ctrl);
3730 es_fclose (stream_sock);
3734 #ifdef HAVE_W32_SYSTEM
3735 /* Serve one ssh-agent request. This is used for the Putty support.
3736 REQUEST is the mmapped memory which may be accessed up to a
3737 length of MAXREQLEN. Returns 0 on success which also indicates
3738 that a valid SSH response message is now in REQUEST. */
3740 serve_mmapped_ssh_request (ctrl_t ctrl,
3741 unsigned char *request, size_t maxreqlen)
3745 int valid_response = 0;
3746 const ssh_request_spec_t *spec;
3748 estream_t request_stream, response_stream;
3750 if (agent_copy_startup_env (ctrl))
3751 goto leave; /* Error setting up the environment. */
3754 goto leave; /* Caller error. */
3756 msglen = uint32_construct (request[0], request[1], request[2], request[3]);
3757 if (msglen < 1 || msglen > maxreqlen - 4)
3759 log_error ("ssh message len (%u) out of range", (unsigned int)msglen);
3763 spec = request_spec_lookup (request[4]);
3766 send_err = 1; /* Unknown request type. */
3770 /* Create a stream object with the data part of the request. */
3771 if (spec->secret_input)
3772 request_stream = es_mopen (NULL, 0, 0, 1, realloc_secure, gcry_free, "r+");
3774 request_stream = es_mopen (NULL, 0, 0, 1, gcry_realloc, gcry_free, "r+");
3775 if (!request_stream)
3777 err = gpg_error_from_syserror ();
3780 /* We have to disable the estream buffering, because the estream
3781 core doesn't know about secure memory. */
3782 if (es_setvbuf (request_stream, NULL, _IONBF, 0))
3784 err = gpg_error_from_syserror ();
3787 /* Copy the request to the stream but omit the request type. */
3788 err = stream_write_data (request_stream, request + 5, msglen - 1);
3791 es_rewind (request_stream);
3793 response_stream = es_fopenmem (0, "r+b");
3794 if (!response_stream)
3796 err = gpg_error_from_syserror ();
3801 log_info ("ssh request handler for %s (%u) started\n",
3802 spec->identifier, spec->type);
3804 err = (*spec->handler) (ctrl, request_stream, response_stream);
3809 log_info ("ssh request handler for %s (%u) failed: %s\n",
3810 spec->identifier, spec->type, gpg_strerror (err));
3812 log_info ("ssh request handler for %s (%u) ready\n",
3813 spec->identifier, spec->type);
3816 es_fclose (request_stream);
3817 request_stream = NULL;
3825 /* Put the response back into the mmapped buffer. */
3827 void *response_data;
3828 size_t response_size;
3830 /* NB: In contrast to the request-stream, the response stream
3831 includes the message type byte. */
3832 if (es_fclose_snatch (response_stream, &response_data, &response_size))
3834 log_error ("snatching ssh response failed: %s",
3835 gpg_strerror (gpg_error_from_syserror ()));
3836 send_err = 1; /* Ooops. */
3840 if (opt.verbose > 1)
3841 log_info ("sending ssh response of length %u\n",
3842 (unsigned int)response_size);
3843 if (response_size > maxreqlen - 4)
3845 log_error ("invalid length of the ssh response: %s",
3846 gpg_strerror (GPG_ERR_INTERNAL));
3847 es_free (response_data);
3852 request[0] = response_size >> 24;
3853 request[1] = response_size >> 16;
3854 request[2] = response_size >> 8;
3855 request[3] = response_size >> 0;
3856 memcpy (request+4, response_data, response_size);
3857 es_free (response_data);
3868 request[4] = SSH_RESPONSE_FAILURE;
3872 /* Reset the SCD in case it has been used. */
3873 agent_reset_scd (ctrl);
3875 return valid_response? 0 : -1;
3877 #endif /*HAVE_W32_SYSTEM*/