1 /* command-ssh.c - gpg-agent's ssh-agent emulation layer
2 * Copyright (C) 2004, 2005, 2006, 2009 Free Software Foundation, Inc.
4 * This file is part of GnuPG.
6 * GnuPG is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 3 of the License, or
9 * (at your option) any later version.
11 * GnuPG is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, see <http://www.gnu.org/licenses/>.
20 /* Only v2 of the ssh-agent protocol is implemented. */
28 #include <sys/types.h>
36 #include "../common/ssh-utils.h"
42 #define SSH_REQUEST_REQUEST_IDENTITIES 11
43 #define SSH_REQUEST_SIGN_REQUEST 13
44 #define SSH_REQUEST_ADD_IDENTITY 17
45 #define SSH_REQUEST_REMOVE_IDENTITY 18
46 #define SSH_REQUEST_REMOVE_ALL_IDENTITIES 19
47 #define SSH_REQUEST_LOCK 22
48 #define SSH_REQUEST_UNLOCK 23
49 #define SSH_REQUEST_ADD_ID_CONSTRAINED 25
52 #define SSH_OPT_CONSTRAIN_LIFETIME 1
53 #define SSH_OPT_CONSTRAIN_CONFIRM 2
56 #define SSH_RESPONSE_SUCCESS 6
57 #define SSH_RESPONSE_FAILURE 5
58 #define SSH_RESPONSE_IDENTITIES_ANSWER 12
59 #define SSH_RESPONSE_SIGN_RESPONSE 14
61 /* Other constants. */
62 #define SSH_DSA_SIGNATURE_PADDING 20
63 #define SSH_DSA_SIGNATURE_ELEMS 2
64 #define SPEC_FLAG_USE_PKCS1V2 (1 << 0)
67 /* The blurb we put into the header of a newly created control file. */
68 static const char sshcontrolblurb[] =
69 "# List of allowed ssh keys. Only keys present in this file are used\n"
70 "# in the SSH protocol. The ssh-add tool may add new entries to this\n"
71 "# file to enable them; you may also add them manually. Comment\n"
72 "# lines, like this one, as well as empty lines are ignored. Lines do\n"
73 "# have a certain length limit but this is not serious limitation as\n"
74 "# the format of the entries is fixed and checked by gpg-agent. A\n"
75 "# non-comment line starts with optional white spaces, followed by the\n"
76 "# keygrip of the key given as 40 hex digits, optionally followed by a\n"
77 "# the caching TTL in seconds and another optional field for arbitrary\n"
78 "# flags. Prepend the keygrip with an '!' mark to disable it.\n"
85 /* Return a new uint32 with b0 being the most significant byte and b3
86 being the least significant byte. */
87 #define uint32_construct(b0, b1, b2, b3) \
88 ((b0 << 24) | (b1 << 16) | (b2 << 8) | b3)
97 /* Type for a request handler. */
98 typedef gpg_error_t (*ssh_request_handler_t) (ctrl_t ctrl,
102 /* Type, which is used for associating request handlers with the
103 appropriate request IDs. */
104 typedef struct ssh_request_spec
107 ssh_request_handler_t handler;
108 const char *identifier;
109 unsigned int secret_input;
110 } ssh_request_spec_t;
112 /* Type for "key modifier functions", which are necessary since
113 OpenSSH and GnuPG treat key material slightly different. A key
114 modifier is called right after a new key identity has been received
115 in order to "sanitize" the material. */
116 typedef gpg_error_t (*ssh_key_modifier_t) (const char *elems,
119 /* The encoding of a generated signature is dependent on the
120 algorithm; therefore algorithm specific signature encoding
121 functions are necessary. */
122 typedef gpg_error_t (*ssh_signature_encoder_t) (estream_t signature_blob,
125 /* Type, which is used for boundling all the algorithm specific
126 information together in a single object. */
127 typedef struct ssh_key_type_spec
129 /* Algorithm identifier as used by OpenSSH. */
130 const char *ssh_identifier;
132 /* Algorithm identifier as used by GnuPG. */
133 const char *identifier;
135 /* List of MPI names for secret keys; order matches the one of the
137 const char *elems_key_secret;
139 /* List of MPI names for public keys; order matches the one of the
141 const char *elems_key_public;
143 /* List of MPI names for signature data. */
144 const char *elems_signature;
146 /* List of MPI names for secret keys; order matches the one, which
147 is required by gpg-agent's key access layer. */
148 const char *elems_sexp_order;
150 /* Key modifier function. Key modifier functions are necessary in
151 order to fix any inconsistencies between the representation of
152 keys on the SSH and on the GnuPG side. */
153 ssh_key_modifier_t key_modifier;
155 /* Signature encoder function. Signature encoder functions are
156 necessary since the encoding of signatures depends on the used
158 ssh_signature_encoder_t signature_encoder;
162 } ssh_key_type_spec_t;
166 static gpg_error_t ssh_handler_request_identities (ctrl_t ctrl,
169 static gpg_error_t ssh_handler_sign_request (ctrl_t ctrl,
172 static gpg_error_t ssh_handler_add_identity (ctrl_t ctrl,
175 static gpg_error_t ssh_handler_remove_identity (ctrl_t ctrl,
178 static gpg_error_t ssh_handler_remove_all_identities (ctrl_t ctrl,
181 static gpg_error_t ssh_handler_lock (ctrl_t ctrl,
184 static gpg_error_t ssh_handler_unlock (ctrl_t ctrl,
188 static gpg_error_t ssh_key_modifier_rsa (const char *elems, gcry_mpi_t *mpis);
189 static gpg_error_t ssh_signature_encoder_rsa (estream_t signature_blob,
191 static gpg_error_t ssh_signature_encoder_dsa (estream_t signature_blob,
196 /* Global variables. */
199 /* Associating request types with the corresponding request
202 static ssh_request_spec_t request_specs[] =
204 #define REQUEST_SPEC_DEFINE(id, name, secret_input) \
205 { SSH_REQUEST_##id, ssh_handler_##name, #name, secret_input }
207 REQUEST_SPEC_DEFINE (REQUEST_IDENTITIES, request_identities, 1),
208 REQUEST_SPEC_DEFINE (SIGN_REQUEST, sign_request, 0),
209 REQUEST_SPEC_DEFINE (ADD_IDENTITY, add_identity, 1),
210 REQUEST_SPEC_DEFINE (ADD_ID_CONSTRAINED, add_identity, 1),
211 REQUEST_SPEC_DEFINE (REMOVE_IDENTITY, remove_identity, 0),
212 REQUEST_SPEC_DEFINE (REMOVE_ALL_IDENTITIES, remove_all_identities, 0),
213 REQUEST_SPEC_DEFINE (LOCK, lock, 0),
214 REQUEST_SPEC_DEFINE (UNLOCK, unlock, 0)
215 #undef REQUEST_SPEC_DEFINE
219 /* Table holding key type specifications. */
220 static ssh_key_type_spec_t ssh_key_types[] =
223 "ssh-rsa", "rsa", "nedupq", "en", "s", "nedpqu",
224 ssh_key_modifier_rsa, ssh_signature_encoder_rsa,
225 SPEC_FLAG_USE_PKCS1V2
228 "ssh-dss", "dsa", "pqgyx", "pqgy", "rs", "pqgyx",
229 NULL, ssh_signature_encoder_dsa,
239 General utility functions.
242 /* A secure realloc, i.e. it makes sure to allocate secure memory if A
243 is NULL. This is required because the standard gcry_realloc does
244 not know whether to allocate secure or normal if NULL is passed as
247 realloc_secure (void *a, size_t n)
252 p = gcry_realloc (a, n);
254 p = gcry_malloc_secure (n);
260 /* Create and return a new C-string from DATA/DATA_N (i.e.: add
261 NUL-termination); return NULL on OOM. */
263 make_cstring (const char *data, size_t data_n)
267 s = xtrymalloc (data_n + 1);
270 memcpy (s, data, data_n);
281 Primitive I/O functions.
285 /* Read a byte from STREAM, store it in B. */
287 stream_read_byte (estream_t stream, unsigned char *b)
292 ret = es_fgetc (stream);
295 if (es_ferror (stream))
296 err = gpg_error_from_syserror ();
298 err = gpg_error (GPG_ERR_EOF);
310 /* Write the byte contained in B to STREAM. */
312 stream_write_byte (estream_t stream, unsigned char b)
317 ret = es_fputc (b, stream);
319 err = gpg_error_from_syserror ();
326 /* Read a uint32 from STREAM, store it in UINT32. */
328 stream_read_uint32 (estream_t stream, u32 *uint32)
330 unsigned char buffer[4];
335 ret = es_read (stream, buffer, sizeof (buffer), &bytes_read);
337 err = gpg_error_from_syserror ();
340 if (bytes_read != sizeof (buffer))
341 err = gpg_error (GPG_ERR_EOF);
346 n = uint32_construct (buffer[0], buffer[1], buffer[2], buffer[3]);
355 /* Write the uint32 contained in UINT32 to STREAM. */
357 stream_write_uint32 (estream_t stream, u32 uint32)
359 unsigned char buffer[4];
363 buffer[0] = uint32 >> 24;
364 buffer[1] = uint32 >> 16;
365 buffer[2] = uint32 >> 8;
366 buffer[3] = uint32 >> 0;
368 ret = es_write (stream, buffer, sizeof (buffer), NULL);
370 err = gpg_error_from_syserror ();
377 /* Read SIZE bytes from STREAM into BUFFER. */
379 stream_read_data (estream_t stream, unsigned char *buffer, size_t size)
385 ret = es_read (stream, buffer, size, &bytes_read);
387 err = gpg_error_from_syserror ();
390 if (bytes_read != size)
391 err = gpg_error (GPG_ERR_EOF);
399 /* Write SIZE bytes from BUFFER to STREAM. */
401 stream_write_data (estream_t stream, const unsigned char *buffer, size_t size)
406 ret = es_write (stream, buffer, size, NULL);
408 err = gpg_error_from_syserror ();
415 /* Read a binary string from STREAM into STRING, store size of string
416 in STRING_SIZE; depending on SECURE use secure memory for
419 stream_read_string (estream_t stream, unsigned int secure,
420 unsigned char **string, u32 *string_size)
423 unsigned char *buffer = NULL;
426 /* Read string length. */
427 err = stream_read_uint32 (stream, &length);
431 /* Allocate space. */
433 buffer = xtrymalloc_secure (length + 1);
435 buffer = xtrymalloc (length + 1);
438 err = gpg_error_from_syserror ();
443 err = stream_read_data (stream, buffer, length);
447 /* Finalize string object. */
451 *string_size = length;
461 /* Read a C-string from STREAM, store copy in STRING. */
463 stream_read_cstring (estream_t stream, char **string)
465 unsigned char *buffer;
468 err = stream_read_string (stream, 0, &buffer, NULL);
472 *string = (char *) buffer;
480 /* Write a binary string from STRING of size STRING_N to STREAM. */
482 stream_write_string (estream_t stream,
483 const unsigned char *string, u32 string_n)
487 err = stream_write_uint32 (stream, string_n);
491 err = stream_write_data (stream, string, string_n);
498 /* Write a C-string from STRING to STREAM. */
500 stream_write_cstring (estream_t stream, const char *string)
504 err = stream_write_string (stream,
505 (const unsigned char *) string, strlen (string));
510 /* Read an MPI from STREAM, store it in MPINT. Depending on SECURE
511 use secure memory. */
513 stream_read_mpi (estream_t stream, unsigned int secure, gcry_mpi_t *mpint)
515 unsigned char *mpi_data;
522 err = stream_read_string (stream, secure, &mpi_data, &mpi_data_size);
526 /* To avoid excessive use of secure memory we check that an MPI is
528 if (mpi_data_size > 520)
530 log_error (_("ssh keys greater than %d bits are not supported\n"), 4096);
531 err = GPG_ERR_TOO_LARGE;
535 err = gcry_mpi_scan (&mpi, GCRYMPI_FMT_STD, mpi_data, mpi_data_size, NULL);
548 /* Write the MPI contained in MPINT to STREAM. */
550 stream_write_mpi (estream_t stream, gcry_mpi_t mpint)
552 unsigned char *mpi_buffer;
558 err = gcry_mpi_aprint (GCRYMPI_FMT_STD, &mpi_buffer, &mpi_buffer_n, mpint);
562 err = stream_write_string (stream, mpi_buffer, mpi_buffer_n);
571 /* Copy data from SRC to DST until EOF is reached. */
573 stream_copy (estream_t dst, estream_t src)
583 ret = es_read (src, buffer, sizeof (buffer), &bytes_read);
584 if (ret || (! bytes_read))
587 err = gpg_error_from_syserror ();
590 ret = es_write (dst, buffer, bytes_read, NULL);
593 err = gpg_error_from_syserror ();
602 /* Read the content of the file specified by FILENAME into a newly
603 create buffer, which is to be stored in BUFFER; store length of
604 buffer in BUFFER_N. */
606 file_to_buffer (const char *filename, unsigned char **buffer, size_t *buffer_n)
608 unsigned char *buffer_new;
620 stream = es_fopen (filename, "r");
623 err = gpg_error_from_syserror ();
627 ret = fstat (es_fileno (stream), &statbuf);
630 err = gpg_error_from_syserror ();
634 buffer_new = xtrymalloc (statbuf.st_size);
637 err = gpg_error_from_syserror ();
641 err = stream_read_data (stream, buffer_new, statbuf.st_size);
645 *buffer = buffer_new;
646 *buffer_n = statbuf.st_size;
662 /* Open the ssh control file and create it if not available. With
663 APPEND passed as true the file will be opened in append mode,
664 otherwise in read only mode. On success a file pointer is stored
665 at the address of R_FP. */
667 open_control_file (FILE **r_fp, int append)
673 /* Note: As soon as we start to use non blocking functions here
674 (i.e. where Pth might switch threads) we need to employ a
677 fname = make_filename (opt.homedir, "sshcontrol", NULL);
678 /* FIXME: With "a+" we are not able to check whether this will will
679 be created and thus the blurb needs to be written first. */
680 fp = fopen (fname, append? "a+":"r");
681 if (!fp && errno == ENOENT)
683 estream_t stream = es_fopen (fname, "wx,mode=-rw-r");
686 err = gpg_error_from_syserror ();
687 log_error (_("can't create `%s': %s\n"), fname, gpg_strerror (err));
691 es_fputs (sshcontrolblurb, stream);
693 fp = fopen (fname, append? "a+":"r");
698 err = gpg_error (gpg_err_code_from_errno (errno));
699 log_error (_("can't open `%s': %s\n"), fname, gpg_strerror (err));
710 /* Search the file at stream FP from the beginning until a matching
711 HEXGRIP is found; return success in this case and store true at
712 DISABLED if the found key has been disabled. If R_TTL is not NULL
713 a specified TTL for that key is stored there. If R_CONFIRM is not
714 NULL it is set to 1 if the key has the confirm flag set. */
716 search_control_file (FILE *fp, const char *hexgrip,
717 int *r_disabled, int *r_ttl, int *r_confirm)
720 char *p, *pend, line[256];
723 const char fname[] = "sshcontrol";
725 assert (strlen (hexgrip) == 40 );
730 fseek (fp, 0, SEEK_SET);
736 if (!fgets (line, DIM(line)-1, fp) )
739 return gpg_error (GPG_ERR_EOF);
740 return gpg_error (gpg_err_code_from_errno (errno));
744 if (!*line || line[strlen(line)-1] != '\n')
746 /* Eat until end of line */
747 while ( (c=getc (fp)) != EOF && c != '\n')
749 return gpg_error (*line? GPG_ERR_LINE_TOO_LONG
750 : GPG_ERR_INCOMPLETE_LINE);
753 /* Allow for empty lines and spaces */
754 for (p=line; spacep (p); p++)
757 while (!*p || *p == '\n' || *p == '#');
763 for (p++; spacep (p); p++)
767 for (i=0; hexdigitp (p) && i < 40; p++, i++)
768 if (hexgrip[i] != (*p >= 'a'? (*p & 0xdf): *p))
770 if (i != 40 || !(spacep (p) || *p == '\n'))
772 log_error ("invalid formatted line in `%s', line %d\n", fname, lnr);
773 return gpg_error (GPG_ERR_BAD_DATA);
776 ttl = strtol (p, &pend, 10);
778 if (!(spacep (p) || *p == '\n') || ttl < -1)
780 log_error ("invalid TTL value in `%s', line %d; assuming 0\n",
787 /* Now check for key-value pairs of the form NAME[=VALUE]. */
790 for (; spacep (p) && *p != '\n'; p++)
792 if (!*p || *p == '\n')
794 n = strcspn (p, "= \t\n");
797 log_error ("assigning a value to a flag is not yet supported; "
798 "in `%s', line %d; flag ignored\n", fname, lnr);
801 else if (n == 7 && !memcmp (p, "confirm", 7))
807 log_error ("invalid flag `%.*s' in `%s', line %d; ignored\n",
812 return 0; /* Okay: found it. */
817 /* Add an entry to the control file to mark the key with the keygrip
818 HEXGRIP as usable for SSH; i.e. it will be returned when ssh asks
819 for it. FMTFPR is the fingerprint string. This function is in
820 general used to add a key received through the ssh-add function.
821 We can assume that the user wants to allow ssh using this key. */
823 add_control_entry (ctrl_t ctrl, const char *hexgrip, const char *fmtfpr,
824 int ttl, int confirm)
832 err = open_control_file (&fp, 1);
836 err = search_control_file (fp, hexgrip, &disabled, NULL, NULL);
837 if (err && gpg_err_code(err) == GPG_ERR_EOF)
840 time_t atime = time (NULL);
842 /* Not yet in the file - add it. Because the file has been
843 opened in append mode, we simply need to write to it. */
844 tp = localtime (&atime);
845 fprintf (fp, ("# Key added on: %04d-%02d-%02d %02d:%02d:%02d\n"
846 "# Fingerprint: %s\n"
848 1900+tp->tm_year, tp->tm_mon+1, tp->tm_mday,
849 tp->tm_hour, tp->tm_min, tp->tm_sec,
850 fmtfpr, hexgrip, ttl, confirm? " confirm":"");
858 /* Scan the sshcontrol file and return the TTL. */
860 ttl_from_sshcontrol (const char *hexgrip)
865 if (!hexgrip || strlen (hexgrip) != 40)
866 return 0; /* Wrong input: Use global default. */
868 if (open_control_file (&fp, 0))
869 return 0; /* Error: Use the global default TTL. */
871 if (search_control_file (fp, hexgrip, &disabled, &ttl, NULL)
873 ttl = 0; /* Use the global default if not found or disabled. */
881 /* Scan the sshcontrol file and return the confirm flag. */
883 confirm_flag_from_sshcontrol (const char *hexgrip)
886 int disabled, confirm;
888 if (!hexgrip || strlen (hexgrip) != 40)
889 return 1; /* Wrong input: Better ask for confirmation. */
891 if (open_control_file (&fp, 0))
892 return 1; /* Error: Better ask for confirmation. */
894 if (search_control_file (fp, hexgrip, &disabled, NULL, &confirm)
896 confirm = 0; /* If not found or disabled, there is no reason to
897 ask for confirmation. */
914 /* Free the list of MPIs MPI_LIST. */
916 mpint_list_free (gcry_mpi_t *mpi_list)
922 for (i = 0; mpi_list[i]; i++)
923 gcry_mpi_release (mpi_list[i]);
928 /* Receive key material MPIs from STREAM according to KEY_SPEC;
929 depending on SECRET expect a public key or secret key. The newly
930 allocated list of MPIs is stored in MPI_LIST. Returns usual error
933 ssh_receive_mpint_list (estream_t stream, int secret,
934 ssh_key_type_spec_t key_spec, gcry_mpi_t **mpi_list)
936 unsigned int elems_public_n;
937 const char *elems_public;
938 unsigned int elems_n;
949 elems = key_spec.elems_key_secret;
951 elems = key_spec.elems_key_public;
952 elems_n = strlen (elems);
954 elems_public = key_spec.elems_key_public;
955 elems_public_n = strlen (elems_public);
957 mpis = xtrycalloc (elems_n + 1, sizeof *mpis );
960 err = gpg_error_from_syserror ();
965 for (i = 0; i < elems_n; i++)
968 elem_is_secret = ! strchr (elems_public, elems[i]);
969 err = stream_read_mpi (stream, elem_is_secret, &mpis[i]);
981 mpint_list_free (mpis);
988 /* Key modifier function for RSA. */
990 ssh_key_modifier_rsa (const char *elems, gcry_mpi_t *mpis)
996 if (strcmp (elems, "nedupq"))
997 /* Modifying only necessary for secret keys. */
1004 if (gcry_mpi_cmp (p, q) > 0)
1006 /* P shall be smaller then Q! Swap primes. iqmp becomes u. */
1014 /* U needs to be recomputed. */
1015 gcry_mpi_invm (u, p, q);
1022 /* Signature encoder function for RSA. */
1024 ssh_signature_encoder_rsa (estream_t signature_blob, gcry_mpi_t *mpis)
1026 unsigned char *data;
1033 err = gcry_mpi_aprint (GCRYMPI_FMT_USG, &data, &data_n, s);
1037 err = stream_write_string (signature_blob, data, data_n);
1046 /* Signature encoder function for DSA. */
1048 ssh_signature_encoder_dsa (estream_t signature_blob, gcry_mpi_t *mpis)
1050 unsigned char buffer[SSH_DSA_SIGNATURE_PADDING * SSH_DSA_SIGNATURE_ELEMS];
1051 unsigned char *data;
1058 for (i = 0; i < 2; i++)
1060 err = gcry_mpi_aprint (GCRYMPI_FMT_USG, &data, &data_n, mpis[i]);
1064 if (data_n > SSH_DSA_SIGNATURE_PADDING)
1066 err = gpg_error (GPG_ERR_INTERNAL); /* FIXME? */
1070 memset (buffer + (i * SSH_DSA_SIGNATURE_PADDING), 0,
1071 SSH_DSA_SIGNATURE_PADDING - data_n);
1072 memcpy (buffer + (i * SSH_DSA_SIGNATURE_PADDING)
1073 + (SSH_DSA_SIGNATURE_PADDING - data_n), data, data_n);
1081 err = stream_write_string (signature_blob, buffer, sizeof (buffer));
1095 /* This function constructs a new S-Expression for the key identified
1096 by the KEY_SPEC, SECRET, MPIS and COMMENT, which is to be stored in
1097 *SEXP. Returns usual error code. */
1099 sexp_key_construct (gcry_sexp_t *sexp,
1100 ssh_key_type_spec_t key_spec, int secret,
1101 gcry_mpi_t *mpis, const char *comment)
1103 const char *key_identifier[] = { "public-key", "private-key" };
1104 gcry_sexp_t sexp_new;
1105 char *sexp_template;
1106 size_t sexp_template_n;
1118 elems = key_spec.elems_sexp_order;
1120 elems = key_spec.elems_key_public;
1121 elems_n = strlen (elems);
1124 Calculate size for sexp_template_n:
1126 "(%s(%s<mpis>)(comment%s))" -> 20 + sizeof (<mpis>).
1131 sexp_template_n = 20 + (elems_n * 5);
1132 sexp_template = xtrymalloc (sexp_template_n);
1133 if (! sexp_template)
1135 err = gpg_error_from_syserror ();
1139 /* Key identifier, algorithm identifier, mpis, comment. */
1140 arg_list = xtrymalloc (sizeof (*arg_list) * (2 + elems_n + 1));
1143 err = gpg_error_from_syserror ();
1148 arg_list[i++] = &key_identifier[secret];
1149 arg_list[i++] = &key_spec.identifier;
1152 sexp_template_n = 0;
1153 sexp_template_n = sprintf (sexp_template + sexp_template_n, "(%%s(%%s");
1154 for (i = 0; i < elems_n; i++)
1156 sexp_template_n += sprintf (sexp_template + sexp_template_n, "(%c%%m)",
1160 for (j = 0; j < elems_n; j++)
1161 if (key_spec.elems_key_secret[j] == elems[i])
1166 arg_list[i + 2] = &mpis[j];
1168 sexp_template_n += sprintf (sexp_template + sexp_template_n,
1171 arg_list[i + 2] = &comment;
1173 err = gcry_sexp_build_array (&sexp_new, NULL, sexp_template, arg_list);
1182 xfree (sexp_template);
1187 /* This functions breaks up the key contained in the S-Expression SEXP
1188 according to KEY_SPEC. The MPIs are bundled in a newly create
1189 list, which is to be stored in MPIS; a newly allocated string
1190 holding the comment will be stored in COMMENT; SECRET will be
1191 filled with a boolean flag specifying what kind of key it is.
1192 Returns usual error code. */
1194 sexp_key_extract (gcry_sexp_t sexp,
1195 ssh_key_type_spec_t key_spec, int *secret,
1196 gcry_mpi_t **mpis, char **comment)
1199 gcry_sexp_t value_list;
1200 gcry_sexp_t value_pair;
1201 gcry_sexp_t comment_list;
1209 gcry_mpi_t *mpis_new;
1215 comment_list = NULL;
1219 data = gcry_sexp_nth_data (sexp, 0, &data_n);
1222 err = gpg_error (GPG_ERR_INV_SEXP);
1226 if ((data_n == 10 && !strncmp (data, "public-key", 10))
1227 || (data_n == 21 && !strncmp (data, "protected-private-key", 21))
1228 || (data_n == 20 && !strncmp (data, "shadowed-private-key", 20)))
1231 elems = key_spec.elems_key_public;
1233 else if (data_n == 11 && !strncmp (data, "private-key", 11))
1236 elems = key_spec.elems_key_secret;
1240 err = gpg_error (GPG_ERR_INV_SEXP);
1244 elems_n = strlen (elems);
1245 mpis_new = xtrycalloc (elems_n + 1, sizeof *mpis_new );
1248 err = gpg_error_from_syserror ();
1252 value_list = gcry_sexp_find_token (sexp, key_spec.identifier, 0);
1255 err = gpg_error (GPG_ERR_INV_SEXP);
1259 for (i = 0; i < elems_n; i++)
1261 value_pair = gcry_sexp_find_token (value_list, elems + i, 1);
1264 err = gpg_error (GPG_ERR_INV_SEXP);
1268 /* Note that we need to use STD format; i.e. prepend a 0x00 to
1269 indicate a positive number if the high bit is set. */
1270 mpi = gcry_sexp_nth_mpi (value_pair, 1, GCRYMPI_FMT_STD);
1273 err = gpg_error (GPG_ERR_INV_SEXP);
1277 gcry_sexp_release (value_pair);
1283 /* We do not require a comment sublist to be present here. */
1287 comment_list = gcry_sexp_find_token (sexp, "comment", 0);
1289 data = gcry_sexp_nth_data (comment_list, 1, &data_n);
1296 comment_new = make_cstring (data, data_n);
1299 err = gpg_error_from_syserror ();
1304 *secret = is_secret;
1306 *comment = comment_new;
1310 gcry_sexp_release (value_list);
1311 gcry_sexp_release (value_pair);
1312 gcry_sexp_release (comment_list);
1316 xfree (comment_new);
1317 mpint_list_free (mpis_new);
1323 /* Extract the car from SEXP, and create a newly created C-string
1324 which is to be stored in IDENTIFIER. */
1326 sexp_extract_identifier (gcry_sexp_t sexp, char **identifier)
1328 char *identifier_new;
1329 gcry_sexp_t sublist;
1334 identifier_new = NULL;
1337 sublist = gcry_sexp_nth (sexp, 1);
1340 err = gpg_error (GPG_ERR_INV_SEXP);
1344 data = gcry_sexp_nth_data (sublist, 0, &data_n);
1347 err = gpg_error (GPG_ERR_INV_SEXP);
1351 identifier_new = make_cstring (data, data_n);
1352 if (! identifier_new)
1354 err = gpg_err_code_from_errno (errno);
1358 *identifier = identifier_new;
1362 gcry_sexp_release (sublist);
1375 /* Search for a key specification entry. If SSH_NAME is not NULL,
1376 search for an entry whose "ssh_name" is equal to SSH_NAME;
1377 otherwise, search for an entry whose "name" is equal to NAME.
1378 Store found entry in SPEC on success, return error otherwise. */
1380 ssh_key_type_lookup (const char *ssh_name, const char *name,
1381 ssh_key_type_spec_t *spec)
1386 for (i = 0; i < DIM (ssh_key_types); i++)
1387 if ((ssh_name && (! strcmp (ssh_name, ssh_key_types[i].ssh_identifier)))
1388 || (name && (! strcmp (name, ssh_key_types[i].identifier))))
1391 if (i == DIM (ssh_key_types))
1392 err = gpg_error (GPG_ERR_NOT_FOUND);
1395 *spec = ssh_key_types[i];
1402 /* Receive a key from STREAM, according to the key specification given
1403 as KEY_SPEC. Depending on SECRET, receive a secret or a public
1404 key. If READ_COMMENT is true, receive a comment string as well.
1405 Constructs a new S-Expression from received data and stores it in
1406 KEY_NEW. Returns zero on success or an error code. */
1408 ssh_receive_key (estream_t stream, gcry_sexp_t *key_new, int secret,
1409 int read_comment, ssh_key_type_spec_t *key_spec)
1412 char *key_type = NULL;
1413 char *comment = NULL;
1414 gcry_sexp_t key = NULL;
1415 ssh_key_type_spec_t spec;
1416 gcry_mpi_t *mpi_list = NULL;
1419 err = stream_read_cstring (stream, &key_type);
1423 err = ssh_key_type_lookup (key_type, NULL, &spec);
1427 err = ssh_receive_mpint_list (stream, secret, spec, &mpi_list);
1433 err = stream_read_cstring (stream, &comment);
1439 elems = spec.elems_key_secret;
1441 elems = spec.elems_key_public;
1443 if (spec.key_modifier)
1445 err = (*spec.key_modifier) (elems, mpi_list);
1450 err = sexp_key_construct (&key, spec, secret, mpi_list, comment? comment:"");
1460 mpint_list_free (mpi_list);
1467 /* Converts a key of type TYPE, whose key material is given in MPIS,
1468 into a newly created binary blob, which is to be stored in
1469 BLOB/BLOB_SIZE. Returns zero on success or an error code. */
1471 ssh_convert_key_to_blob (unsigned char **blob, size_t *blob_size,
1472 const char *type, gcry_mpi_t *mpis)
1474 unsigned char *blob_new;
1475 long int blob_size_new;
1487 stream = es_mopen (NULL, 0, 0, 1, NULL, NULL, "r+");
1490 err = gpg_error_from_syserror ();
1494 err = stream_write_cstring (stream, type);
1498 for (i = 0; mpis[i] && (! err); i++)
1499 err = stream_write_mpi (stream, mpis[i]);
1503 blob_size_new = es_ftell (stream);
1504 if (blob_size_new == -1)
1506 err = gpg_error_from_syserror ();
1510 err = es_fseek (stream, 0, SEEK_SET);
1514 blob_new = xtrymalloc (blob_size_new);
1517 err = gpg_error_from_syserror ();
1521 err = stream_read_data (stream, blob_new, blob_size_new);
1526 *blob_size = blob_size_new;
1539 /* Write the public key KEY_PUBLIC to STREAM in SSH key format. If
1540 OVERRIDE_COMMENT is not NULL, it will be used instead of the
1541 comment stored in the key. */
1543 ssh_send_key_public (estream_t stream, gcry_sexp_t key_public,
1544 const char *override_comment)
1546 ssh_key_type_spec_t spec;
1547 gcry_mpi_t *mpi_list;
1550 unsigned char *blob;
1559 err = sexp_extract_identifier (key_public, &key_type);
1563 err = ssh_key_type_lookup (NULL, key_type, &spec);
1567 err = sexp_key_extract (key_public, spec, NULL, &mpi_list, &comment);
1571 err = ssh_convert_key_to_blob (&blob, &blob_n,
1572 spec.ssh_identifier, mpi_list);
1576 err = stream_write_string (stream, blob, blob_n);
1580 err = stream_write_cstring (stream,
1581 override_comment? override_comment : comment);
1585 mpint_list_free (mpi_list);
1593 /* Read a public key out of BLOB/BLOB_SIZE according to the key
1594 specification given as KEY_SPEC, storing the new key in KEY_PUBLIC.
1595 Returns zero on success or an error code. */
1597 ssh_read_key_public_from_blob (unsigned char *blob, size_t blob_size,
1598 gcry_sexp_t *key_public,
1599 ssh_key_type_spec_t *key_spec)
1601 estream_t blob_stream;
1606 blob_stream = es_mopen (NULL, 0, 0, 1, NULL, NULL, "r+");
1609 err = gpg_error_from_syserror ();
1613 err = stream_write_data (blob_stream, blob, blob_size);
1617 err = es_fseek (blob_stream, 0, SEEK_SET);
1621 err = ssh_receive_key (blob_stream, key_public, 0, 0, key_spec);
1626 es_fclose (blob_stream);
1633 /* This function calculates the key grip for the key contained in the
1634 S-Expression KEY and writes it to BUFFER, which must be large
1635 enough to hold it. Returns usual error code. */
1637 ssh_key_grip (gcry_sexp_t key, unsigned char *buffer)
1639 if (!gcry_pk_get_keygrip (key, buffer))
1640 return gpg_error (GPG_ERR_INTERNAL);
1646 /* Converts the secret key KEY_SECRET into a public key, storing it in
1647 KEY_PUBLIC. SPEC is the according key specification. Returns zero
1648 on success or an error code. */
1650 key_secret_to_public (gcry_sexp_t *key_public,
1651 ssh_key_type_spec_t spec, gcry_sexp_t key_secret)
1661 err = sexp_key_extract (key_secret, spec, &is_secret, &mpis, &comment);
1665 err = sexp_key_construct (key_public, spec, 0, mpis, comment);
1669 mpint_list_free (mpis);
1676 /* Check whether a smartcard is available and whether it has a usable
1677 key. Store a copy of that key at R_PK and return 0. If no key is
1678 available store NULL at R_PK and return an error code. If CARDSN
1679 is not NULL, a string with the serial number of the card will be
1680 a malloced and stored there. */
1682 card_key_available (ctrl_t ctrl, gcry_sexp_t *r_pk, char **cardsn)
1686 char *serialno = NULL;
1687 unsigned char *pkbuf;
1690 unsigned char grip[20];
1696 /* First see whether a card is available and whether the application
1698 err = agent_card_getattr (ctrl, "$AUTHKEYID", &authkeyid);
1699 if ( gpg_err_code (err) == GPG_ERR_CARD_REMOVED )
1701 /* Ask for the serial number to reset the card. */
1702 err = agent_card_serialno (ctrl, &serialno);
1706 log_info (_("error getting serial number of card: %s\n"),
1707 gpg_strerror (err));
1710 log_info (_("detected card with S/N: %s\n"), serialno);
1711 err = agent_card_getattr (ctrl, "$AUTHKEYID", &authkeyid);
1715 log_error (_("error getting default authentication keyID of card: %s\n"),
1716 gpg_strerror (err));
1721 /* Get the S/N if we don't have it yet. Use the fast getattr method. */
1722 if (!serialno && (err = agent_card_getattr (ctrl, "SERIALNO", &serialno)) )
1724 log_error (_("error getting serial number of card: %s\n"),
1725 gpg_strerror (err));
1730 /* Read the public key. */
1731 err = agent_card_readkey (ctrl, authkeyid, &pkbuf);
1735 log_info (_("no suitable card key found: %s\n"), gpg_strerror (err));
1741 pkbuflen = gcry_sexp_canon_len (pkbuf, 0, NULL, NULL);
1742 err = gcry_sexp_sscan (&s_pk, NULL, (char*)pkbuf, pkbuflen);
1745 log_error ("failed to build S-Exp from received card key: %s\n",
1746 gpg_strerror (err));
1753 err = ssh_key_grip (s_pk, grip);
1756 log_debug ("error computing keygrip from received card key: %s\n",
1757 gcry_strerror (err));
1759 gcry_sexp_release (s_pk);
1765 if ( agent_key_available (grip) )
1767 /* (Shadow)-key is not available in our key storage. */
1768 unsigned char *shadow_info;
1771 shadow_info = make_shadow_info (serialno, authkeyid);
1774 err = gpg_error_from_syserror ();
1776 gcry_sexp_release (s_pk);
1781 err = agent_shadow_key (pkbuf, shadow_info, &tmp);
1782 xfree (shadow_info);
1785 log_error (_("shadowing the key failed: %s\n"), gpg_strerror (err));
1787 gcry_sexp_release (s_pk);
1794 pkbuflen = gcry_sexp_canon_len (pkbuf, 0, NULL, NULL);
1797 err = agent_write_private_key (grip, pkbuf, pkbuflen, 0);
1800 log_error (_("error writing key: %s\n"), gpg_strerror (err));
1802 gcry_sexp_release (s_pk);
1813 /* If the card handler is able to return a short serialnumber,
1814 use that one, else use the complete serialno. */
1815 if (!agent_card_getattr (ctrl, "$DISPSERIALNO", &dispsn))
1817 *cardsn = xtryasprintf ("cardno:%s", dispsn);
1821 *cardsn = xtryasprintf ("cardno:%s", serialno);
1824 err = gpg_error_from_syserror ();
1826 gcry_sexp_release (s_pk);
1845 Request handler. Each handler is provided with a CTRL context, a
1846 REQUEST object and a RESPONSE object. The actual request is to be
1847 read from REQUEST, the response needs to be written to RESPONSE.
1852 /* Handler for the "request_identities" command. */
1854 ssh_handler_request_identities (ctrl_t ctrl,
1855 estream_t request, estream_t response)
1858 ssh_key_type_spec_t spec;
1859 struct dirent *dir_entry;
1860 char *key_directory;
1861 size_t key_directory_n;
1863 unsigned char *buffer;
1866 estream_t key_blobs;
1867 gcry_sexp_t key_secret;
1868 gcry_sexp_t key_public;
1872 FILE *ctrl_fp = NULL;
1874 gpg_error_t ret_err;
1878 /* Prepare buffer stream. */
1880 key_directory = NULL;
1890 key_blobs = es_mopen (NULL, 0, 0, 1, NULL, NULL, "r+");
1893 err = gpg_error_from_syserror ();
1897 /* Open key directory. */
1898 key_directory = make_filename (opt.homedir, GNUPG_PRIVATE_KEYS_DIR, NULL);
1899 if (! key_directory)
1901 err = gpg_err_code_from_errno (errno);
1904 key_directory_n = strlen (key_directory);
1906 key_path = xtrymalloc (key_directory_n + 46);
1909 err = gpg_err_code_from_errno (errno);
1913 sprintf (key_path, "%s/", key_directory);
1914 sprintf (key_path + key_directory_n + 41, ".key");
1916 dir = opendir (key_directory);
1919 err = gpg_err_code_from_errno (errno);
1925 /* First check whether a key is currently available in the card
1926 reader - this should be allowed even without being listed in
1929 if (!card_key_available (ctrl, &key_public, &cardsn))
1931 err = ssh_send_key_public (key_blobs, key_public, cardsn);
1932 gcry_sexp_release (key_public);
1942 /* Then look at all the registered an allowed keys. */
1945 /* Fixme: We should better iterate over the control file and check
1946 whether the key file is there. This is better in resepct to
1947 performance if tehre are a lot of key sin our key storage. */
1948 /* FIXME: make sure that buffer gets deallocated properly. */
1949 err = open_control_file (&ctrl_fp, 0);
1953 while ( (dir_entry = readdir (dir)) )
1955 if ((strlen (dir_entry->d_name) == 44)
1956 && (! strncmp (dir_entry->d_name + 40, ".key", 4)))
1961 /* We do only want to return keys listed in our control
1963 strncpy (hexgrip, dir_entry->d_name, 40);
1965 if ( strlen (hexgrip) != 40 )
1967 if (search_control_file (ctrl_fp, hexgrip, &disabled, NULL, NULL)
1971 strncpy (key_path + key_directory_n + 1, dir_entry->d_name, 40);
1973 /* Read file content. */
1974 err = file_to_buffer (key_path, &buffer, &buffer_n);
1978 err = gcry_sexp_sscan (&key_secret, NULL, (char*)buffer, buffer_n);
1985 err = sexp_extract_identifier (key_secret, &key_type);
1989 err = ssh_key_type_lookup (NULL, key_type, &spec);
1996 err = key_secret_to_public (&key_public, spec, key_secret);
2000 gcry_sexp_release (key_secret);
2003 err = ssh_send_key_public (key_blobs, key_public, NULL);
2007 gcry_sexp_release (key_public);
2014 ret = es_fseek (key_blobs, 0, SEEK_SET);
2017 err = gpg_error_from_syserror ();
2023 /* Send response. */
2025 gcry_sexp_release (key_secret);
2026 gcry_sexp_release (key_public);
2030 ret_err = stream_write_byte (response, SSH_RESPONSE_IDENTITIES_ANSWER);
2033 ret_err = stream_write_uint32 (response, key_counter);
2036 ret_err = stream_copy (response, key_blobs);
2042 ret_err = stream_write_byte (response, SSH_RESPONSE_FAILURE);
2049 es_fclose (key_blobs);
2056 xfree (key_directory);
2065 /* This function hashes the data contained in DATA of size DATA_N
2066 according to the message digest algorithm specified by MD_ALGORITHM
2067 and writes the message digest to HASH, which needs to large enough
2070 data_hash (unsigned char *data, size_t data_n,
2071 int md_algorithm, unsigned char *hash)
2073 gcry_md_hash_buffer (md_algorithm, hash, data, data_n);
2078 /* This function signs the data contained in CTRL, stores the created
2079 signature in newly allocated memory in SIG and it's size in SIG_N;
2080 SIG_ENCODER is the signature encoder to use. */
2082 data_sign (ctrl_t ctrl, ssh_signature_encoder_t sig_encoder,
2083 unsigned char **sig, size_t *sig_n)
2086 gcry_sexp_t signature_sexp = NULL;
2087 estream_t stream = NULL;
2088 gcry_sexp_t valuelist = NULL;
2089 gcry_sexp_t sublist = NULL;
2090 gcry_mpi_t sig_value = NULL;
2091 unsigned char *sig_blob = NULL;
2092 size_t sig_blob_n = 0;
2093 char *identifier = NULL;
2094 const char *identifier_raw;
2095 size_t identifier_n;
2096 ssh_key_type_spec_t spec;
2101 gcry_mpi_t *mpis = NULL;
2107 /* Quick check to see whether we have a valid keygrip and convert it
2109 if (!ctrl->have_keygrip)
2111 err = gpg_error (GPG_ERR_NO_SECKEY);
2114 bin2hex (ctrl->keygrip, 20, hexgrip);
2116 /* Ask for confirmation if needed. */
2117 if (confirm_flag_from_sshcontrol (hexgrip))
2121 char *comment = NULL;
2123 err = agent_raw_key_from_file (ctrl, ctrl->keygrip, &key);
2126 err = ssh_get_fingerprint_string (key, &fpr);
2129 gcry_sexp_t tmpsxp = gcry_sexp_find_token (key, "comment", 0);
2131 comment = gcry_sexp_nth_string (tmpsxp, 1);
2132 gcry_sexp_release (tmpsxp);
2134 gcry_sexp_release (key);
2137 prompt = xtryasprintf (_("An ssh process requested the use of key%%0A"
2140 "Do you want to allow this?"),
2141 fpr, comment? comment:"");
2143 gcry_free (comment);
2144 err = agent_get_confirmation (ctrl, prompt, _("Allow"), _("Deny"), 0);
2150 /* Create signature. */
2151 ctrl->use_auth_call = 1;
2152 err = agent_pksign_do (ctrl, NULL,
2153 _("Please enter the passphrase "
2154 "for the ssh key%%0A %F%%0A (%c)"),
2156 CACHE_MODE_SSH, ttl_from_sshcontrol);
2157 ctrl->use_auth_call = 0;
2161 valuelist = gcry_sexp_nth (signature_sexp, 1);
2164 err = gpg_error (GPG_ERR_INV_SEXP);
2168 stream = es_mopen (NULL, 0, 0, 1, NULL, NULL, "r+");
2171 err = gpg_error_from_syserror ();
2175 identifier_raw = gcry_sexp_nth_data (valuelist, 0, &identifier_n);
2176 if (! identifier_raw)
2178 err = gpg_error (GPG_ERR_INV_SEXP);
2182 identifier = make_cstring (identifier_raw, identifier_n);
2185 err = gpg_error_from_syserror ();
2189 err = ssh_key_type_lookup (NULL, identifier, &spec);
2193 err = stream_write_cstring (stream, spec.ssh_identifier);
2197 elems = spec.elems_signature;
2198 elems_n = strlen (elems);
2200 mpis = xtrycalloc (elems_n + 1, sizeof *mpis);
2203 err = gpg_error_from_syserror ();
2207 for (i = 0; i < elems_n; i++)
2209 sublist = gcry_sexp_find_token (valuelist, spec.elems_signature + i, 1);
2212 err = gpg_error (GPG_ERR_INV_SEXP);
2216 sig_value = gcry_sexp_nth_mpi (sublist, 1, GCRYMPI_FMT_USG);
2219 err = gpg_error (GPG_ERR_INTERNAL); /* FIXME? */
2222 gcry_sexp_release (sublist);
2225 mpis[i] = sig_value;
2230 err = (*sig_encoder) (stream, mpis);
2234 sig_blob_n = es_ftell (stream);
2235 if (sig_blob_n == -1)
2237 err = gpg_error_from_syserror ();
2241 sig_blob = xtrymalloc (sig_blob_n);
2244 err = gpg_error_from_syserror ();
2248 ret = es_fseek (stream, 0, SEEK_SET);
2251 err = gpg_error_from_syserror ();
2255 err = stream_read_data (stream, sig_blob, sig_blob_n);
2260 *sig_n = sig_blob_n;
2269 gcry_sexp_release (valuelist);
2270 gcry_sexp_release (signature_sexp);
2271 gcry_sexp_release (sublist);
2272 mpint_list_free (mpis);
2278 /* Handler for the "sign_request" command. */
2280 ssh_handler_sign_request (ctrl_t ctrl, estream_t request, estream_t response)
2283 ssh_key_type_spec_t spec;
2284 unsigned char hash[MAX_DIGEST_LEN];
2285 unsigned int hash_n;
2286 unsigned char key_grip[20];
2287 unsigned char *key_blob;
2289 unsigned char *data;
2295 gpg_error_t ret_err;
2304 err = stream_read_string (request, 0, &key_blob, &key_blob_size);
2308 err = ssh_read_key_public_from_blob (key_blob, key_blob_size, &key, &spec);
2312 /* Receive data to sign. */
2313 err = stream_read_string (request, 0, &data, &data_size);
2318 err = stream_read_uint32 (request, &flags);
2323 hash_n = gcry_md_get_algo_dlen (GCRY_MD_SHA1);
2326 err = gpg_error (GPG_ERR_INTERNAL);
2329 err = data_hash (data, data_size, GCRY_MD_SHA1, hash);
2333 /* Calculate key grip. */
2334 err = ssh_key_grip (key, key_grip);
2340 ctrl->digest.algo = GCRY_MD_SHA1;
2341 memcpy (ctrl->digest.value, hash, hash_n);
2342 ctrl->digest.valuelen = hash_n;
2343 ctrl->digest.raw_value = ! (spec.flags & SPEC_FLAG_USE_PKCS1V2);
2344 ctrl->have_keygrip = 1;
2345 memcpy (ctrl->keygrip, key_grip, 20);
2347 err = data_sign (ctrl, spec.signature_encoder, &sig, &sig_n);
2355 ret_err = stream_write_byte (response, SSH_RESPONSE_SIGN_RESPONSE);
2358 ret_err = stream_write_string (response, sig, sig_n);
2364 ret_err = stream_write_byte (response, SSH_RESPONSE_FAILURE);
2371 gcry_sexp_release (key);
2379 /* This function extracts the comment contained in the key
2380 S-Expression KEY and stores a copy in COMMENT. Returns usual error
2383 ssh_key_extract_comment (gcry_sexp_t key, char **comment)
2385 gcry_sexp_t comment_list;
2391 comment_list = gcry_sexp_find_token (key, "comment", 0);
2394 err = gpg_error (GPG_ERR_INV_SEXP);
2398 data = gcry_sexp_nth_data (comment_list, 1, &data_n);
2401 err = gpg_error (GPG_ERR_INV_SEXP);
2405 comment_new = make_cstring (data, data_n);
2408 err = gpg_error_from_syserror ();
2412 *comment = comment_new;
2417 gcry_sexp_release (comment_list);
2422 /* This function converts the key contained in the S-Expression KEY
2423 into a buffer, which is protected by the passphrase PASSPHRASE.
2424 Returns usual error code. */
2426 ssh_key_to_protected_buffer (gcry_sexp_t key, const char *passphrase,
2427 unsigned char **buffer, size_t *buffer_n)
2429 unsigned char *buffer_new;
2430 unsigned int buffer_new_n;
2434 buffer_new_n = gcry_sexp_sprint (key, GCRYSEXP_FMT_CANON, NULL, 0);
2435 buffer_new = xtrymalloc_secure (buffer_new_n);
2438 err = gpg_error_from_syserror ();
2442 gcry_sexp_sprint (key, GCRYSEXP_FMT_CANON, buffer_new, buffer_new_n);
2443 /* FIXME: guarantee? */
2445 err = agent_protect (buffer_new, passphrase, buffer, buffer_n, 0);
2456 /* Callback function to compare the first entered PIN with the one
2457 currently being entered. */
2459 reenter_compare_cb (struct pin_entry_info_s *pi)
2461 const char *pin1 = pi->check_cb_arg;
2463 if (!strcmp (pin1, pi->pin))
2464 return 0; /* okay */
2468 /* Store the ssh KEY into our local key storage and protect it after
2469 asking for a passphrase. Cache that passphrase. TTL is the
2470 maximum caching time for that key. If the key already exists in
2471 our key storage, don't do anything. When entering a new key also
2472 add an entry to the sshcontrol file. */
2474 ssh_identity_register (ctrl_t ctrl, gcry_sexp_t key, int ttl, int confirm)
2477 unsigned char key_grip_raw[20];
2479 unsigned char *buffer = NULL;
2481 char *description = NULL;
2482 const char *description2 = _("Please re-enter this passphrase");
2483 char *comment = NULL;
2484 char *key_fpr = NULL;
2485 const char *initial_errtext = NULL;
2487 struct pin_entry_info_s *pi = NULL, *pi2;
2489 err = ssh_key_grip (key, key_grip_raw);
2493 /* Check whether the key is already in our key storage. Don't do
2495 if ( !agent_key_available (key_grip_raw) )
2496 goto out; /* Yes, key is available. */
2498 err = ssh_get_fingerprint_string (key, &key_fpr);
2502 err = ssh_key_extract_comment (key, &comment);
2506 if ( asprintf (&description,
2507 _("Please enter a passphrase to protect"
2508 " the received secret key%%0A"
2511 "within gpg-agent's key storage"),
2512 key_fpr, comment ? comment : "") < 0)
2514 err = gpg_error_from_syserror ();
2519 pi = gcry_calloc_secure (2, sizeof (*pi) + 100 + 1);
2522 err = gpg_error_from_syserror ();
2525 pi2 = pi + (sizeof *pi + 100 + 1);
2526 pi->max_length = 100;
2528 pi2->max_length = 100;
2530 pi2->check_cb = reenter_compare_cb;
2531 pi2->check_cb_arg = pi->pin;
2534 err = agent_askpin (ctrl, description, NULL, initial_errtext, pi);
2535 initial_errtext = NULL;
2539 /* Unless the passphrase is empty, ask to confirm it. */
2540 if (pi->pin && *pi->pin)
2542 err = agent_askpin (ctrl, description2, NULL, NULL, pi2);
2544 { /* The re-entered one did not match and the user did not
2546 initial_errtext = _("does not match - try again");
2551 err = ssh_key_to_protected_buffer (key, pi->pin, &buffer, &buffer_n);
2555 /* Store this key to our key storage. */
2556 err = agent_write_private_key (key_grip_raw, buffer, buffer_n, 0);
2560 /* Cache this passphrase. */
2561 for (i = 0; i < 20; i++)
2562 sprintf (key_grip + 2 * i, "%02X", key_grip_raw[i]);
2564 err = agent_put_cache (key_grip, CACHE_MODE_SSH, pi->pin, ttl);
2568 /* And add an entry to the sshcontrol file. */
2569 err = add_control_entry (ctrl, key_grip, key_fpr, ttl, confirm);
2573 if (pi && pi->max_length)
2574 wipememory (pi->pin, pi->max_length);
2579 xfree (description);
2585 /* This function removes the key contained in the S-Expression KEY
2586 from the local key storage, in case it exists there. Returns usual
2587 error code. FIXME: this function is a stub. */
2589 ssh_identity_drop (gcry_sexp_t key)
2591 unsigned char key_grip[21] = { 0 };
2594 err = ssh_key_grip (key, key_grip);
2598 key_grip[sizeof (key_grip) - 1] = 0;
2600 /* FIXME: What to do here - forgetting the passphrase or deleting
2601 the key from key cache? */
2608 /* Handler for the "add_identity" command. */
2610 ssh_handler_add_identity (ctrl_t ctrl, estream_t request, estream_t response)
2612 gpg_error_t ret_err;
2624 err = ssh_receive_key (request, &key, 1, 1, NULL);
2630 err = stream_read_byte (request, &b);
2631 if (gpg_err_code (err) == GPG_ERR_EOF)
2639 case SSH_OPT_CONSTRAIN_LIFETIME:
2643 err = stream_read_uint32 (request, &n);
2649 case SSH_OPT_CONSTRAIN_CONFIRM:
2656 /* FIXME: log/bad? */
2663 err = ssh_identity_register (ctrl, key, ttl, confirm);
2667 gcry_sexp_release (key);
2670 ret_err = stream_write_byte (response, SSH_RESPONSE_SUCCESS);
2672 ret_err = stream_write_byte (response, SSH_RESPONSE_FAILURE);
2677 /* Handler for the "remove_identity" command. */
2679 ssh_handler_remove_identity (ctrl_t ctrl,
2680 estream_t request, estream_t response)
2682 unsigned char *key_blob;
2685 gpg_error_t ret_err;
2695 err = stream_read_string (request, 0, &key_blob, &key_blob_size);
2699 err = ssh_read_key_public_from_blob (key_blob, key_blob_size, &key, NULL);
2703 err = ssh_identity_drop (key);
2708 gcry_sexp_release (key);
2711 ret_err = stream_write_byte (response, SSH_RESPONSE_SUCCESS);
2713 ret_err = stream_write_byte (response, SSH_RESPONSE_FAILURE);
2718 /* FIXME: stub function. Actually useful? */
2720 ssh_identities_remove_all (void)
2726 /* FIXME: shall we remove _all_ cache entries or only those
2727 registered through the ssh emulation? */
2732 /* Handler for the "remove_all_identities" command. */
2734 ssh_handler_remove_all_identities (ctrl_t ctrl,
2735 estream_t request, estream_t response)
2737 gpg_error_t ret_err;
2743 err = ssh_identities_remove_all ();
2746 ret_err = stream_write_byte (response, SSH_RESPONSE_SUCCESS);
2748 ret_err = stream_write_byte (response, SSH_RESPONSE_FAILURE);
2753 /* Lock agent? FIXME: stub function. */
2760 log_error ("ssh-agent's lock command is not implemented\n");
2766 /* Unock agent? FIXME: stub function. */
2772 log_error ("ssh-agent's unlock command is not implemented\n");
2778 /* Handler for the "lock" command. */
2780 ssh_handler_lock (ctrl_t ctrl, estream_t request, estream_t response)
2782 gpg_error_t ret_err;
2791 ret_err = stream_write_byte (response, SSH_RESPONSE_SUCCESS);
2793 ret_err = stream_write_byte (response, SSH_RESPONSE_FAILURE);
2798 /* Handler for the "unlock" command. */
2800 ssh_handler_unlock (ctrl_t ctrl, estream_t request, estream_t response)
2802 gpg_error_t ret_err;
2808 err = ssh_unlock ();
2811 ret_err = stream_write_byte (response, SSH_RESPONSE_SUCCESS);
2813 ret_err = stream_write_byte (response, SSH_RESPONSE_FAILURE);
2820 /* Return the request specification for the request identified by TYPE
2821 or NULL in case the requested request specification could not be
2823 static ssh_request_spec_t *
2824 request_spec_lookup (int type)
2826 ssh_request_spec_t *spec;
2829 for (i = 0; i < DIM (request_specs); i++)
2830 if (request_specs[i].type == type)
2832 if (i == DIM (request_specs))
2835 log_info ("ssh request %u is not supported\n", type);
2839 spec = request_specs + i;
2844 /* Process a single request. The request is read from and the
2845 response is written to STREAM_SOCK. Uses CTRL as context. Returns
2846 zero in case of success, non zero in case of failure. */
2848 ssh_request_process (ctrl_t ctrl, estream_t stream_sock)
2850 ssh_request_spec_t *spec;
2853 unsigned char request_type;
2857 unsigned char *request_data;
2858 u32 request_data_size;
2861 request_data = NULL;
2866 /* Create memory streams for request/response data. The entire
2867 request will be stored in secure memory, since it might contain
2868 secret key material. The response does not have to be stored in
2869 secure memory, since we never give out secret keys.
2871 Note: we only have little secure memory, but there is NO
2872 possibility of DoS here; only trusted clients are allowed to
2873 connect to the agent. What could happen is that the agent
2874 returns out-of-secure-memory errors on requests in case the
2875 agent's owner floods his own agent with many large messages.
2878 /* Retrieve request. */
2879 err = stream_read_string (stream_sock, 1, &request_data, &request_data_size);
2883 if (opt.verbose > 1)
2884 log_info ("received ssh request of length %u\n",
2885 (unsigned int)request_data_size);
2887 if (! request_data_size)
2891 /* Broken request; FIXME. */
2894 request_type = request_data[0];
2895 spec = request_spec_lookup (request_type);
2900 /* Unknown request; FIXME. */
2903 if (spec->secret_input)
2904 request = es_mopen (NULL, 0, 0, 1, realloc_secure, gcry_free, "r+");
2906 request = es_mopen (NULL, 0, 0, 1, gcry_realloc, gcry_free, "r+");
2909 err = gpg_error_from_syserror ();
2912 ret = es_setvbuf (request, NULL, _IONBF, 0);
2915 err = gpg_error_from_syserror ();
2918 err = stream_write_data (request, request_data + 1, request_data_size - 1);
2921 es_rewind (request);
2923 response = es_mopen (NULL, 0, 0, 1, NULL, NULL, "r+");
2926 err = gpg_error_from_syserror ();
2931 log_info ("ssh request handler for %s (%u) started\n",
2932 spec->identifier, spec->type);
2934 err = (*spec->handler) (ctrl, request, response);
2939 log_info ("ssh request handler for %s (%u) failed: %s\n",
2940 spec->identifier, spec->type, gpg_strerror (err));
2942 log_info ("ssh request handler for %s (%u) ready\n",
2943 spec->identifier, spec->type);
2952 response_size = es_ftell (response);
2953 if (opt.verbose > 1)
2954 log_info ("sending ssh response of length %u\n",
2955 (unsigned int)response_size);
2957 err = es_fseek (response, 0, SEEK_SET);
2964 err = stream_write_uint32 (stream_sock, response_size);
2971 err = stream_copy (stream_sock, response);
2975 err = es_fflush (stream_sock);
2981 if (err && es_feof (stream_sock))
2982 log_error ("error occured while processing request: %s\n",
2983 gpg_strerror (err));
2987 if (opt.verbose > 1)
2988 log_info ("sending ssh error response\n");
2989 err = stream_write_uint32 (stream_sock, 1);
2992 err = stream_write_byte (stream_sock, SSH_RESPONSE_FAILURE);
3000 es_fclose (request);
3002 es_fclose (response);
3003 xfree (request_data); /* FIXME? */
3008 /* Start serving client on SOCK_CLIENT. */
3010 start_command_handler_ssh (ctrl_t ctrl, gnupg_fd_t sock_client)
3012 estream_t stream_sock = NULL;
3013 gpg_error_t err = 0;
3016 /* Because the ssh protocol does not send us information about the
3017 the current TTY setting, we resort here to use those from startup
3018 or those explictly set. */
3020 static const char *names[] =
3021 {"GPG_TTY", "DISPLAY", "TERM", "XAUTHORITY", "PINENTRY_USER_DATA", NULL};
3025 for (idx=0; !err && names[idx]; idx++)
3026 if (!session_env_getenv (ctrl->session_env, names[idx])
3027 && (value = session_env_getenv (opt.startup_env, names[idx])))
3028 err = session_env_setenv (ctrl->session_env, names[idx], value);
3030 if (!err && !ctrl->lc_ctype && opt.startup_lc_ctype)
3031 if (!(ctrl->lc_ctype = xtrystrdup (opt.startup_lc_ctype)))
3032 err = gpg_error_from_syserror ();
3034 if (!err && !ctrl->lc_messages && opt.startup_lc_messages)
3035 if (!(ctrl->lc_messages = xtrystrdup (opt.startup_lc_messages)))
3036 err = gpg_error_from_syserror ();
3040 log_error ("error setting default session environment: %s\n",
3041 gpg_strerror (err));
3047 /* Create stream from socket. */
3048 stream_sock = es_fdopen (FD2INT(sock_client), "r+");
3051 err = gpg_error_from_syserror ();
3052 log_error (_("failed to create stream from socket: %s\n"),
3053 gpg_strerror (err));
3056 /* We have to disable the estream buffering, because the estream
3057 core doesn't know about secure memory. */
3058 ret = es_setvbuf (stream_sock, NULL, _IONBF, 0);
3061 err = gpg_error_from_syserror ();
3062 log_error ("failed to disable buffering "
3063 "on socket stream: %s\n", gpg_strerror (err));
3067 /* Main processing loop. */
3068 while ( !ssh_request_process (ctrl, stream_sock) )
3070 /* Check wether we have reached EOF before trying to read
3074 c = es_fgetc (stream_sock);
3077 es_ungetc (c, stream_sock);
3080 /* Reset the SCD in case it has been used. */
3081 agent_reset_scd (ctrl);
3086 es_fclose (stream_sock);