1 /* command-ssh.c - gpg-agent's ssh-agent emulation layer
2 * Copyright (C) 2004, 2005, 2006 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>
41 #define SSH_REQUEST_REQUEST_IDENTITIES 11
42 #define SSH_REQUEST_SIGN_REQUEST 13
43 #define SSH_REQUEST_ADD_IDENTITY 17
44 #define SSH_REQUEST_REMOVE_IDENTITY 18
45 #define SSH_REQUEST_REMOVE_ALL_IDENTITIES 19
46 #define SSH_REQUEST_LOCK 22
47 #define SSH_REQUEST_UNLOCK 23
48 #define SSH_REQUEST_ADD_ID_CONSTRAINED 25
51 #define SSH_OPT_CONSTRAIN_LIFETIME 1
52 #define SSH_OPT_CONSTRAIN_CONFIRM 2
55 #define SSH_RESPONSE_SUCCESS 6
56 #define SSH_RESPONSE_FAILURE 5
57 #define SSH_RESPONSE_IDENTITIES_ANSWER 12
58 #define SSH_RESPONSE_SIGN_RESPONSE 14
60 /* Other constants. */
61 #define SSH_DSA_SIGNATURE_PADDING 20
62 #define SSH_DSA_SIGNATURE_ELEMS 2
63 #define SPEC_FLAG_USE_PKCS1V2 (1 << 0)
66 /* The blurb we put into the header of a newly created control file. */
67 static const char sshcontrolblurb
[] =
68 "# List of allowed ssh keys. Only keys present in this file are used\n"
69 "# in the SSH protocol. The ssh-add tool may add new entries to this\n"
70 "# file to enable them; you may also add them manually. Comment\n"
71 "# lines, like this one, as well as empty lines are ignored. Lines do\n"
72 "# have a certain length limit but this is not serious limitation as\n"
73 "# the format of the entries is fixed and checked by gpg-agent. A\n"
74 "# non-comment line starts with optional white spaces, followed by the\n"
75 "# keygrip of the key given as 40 hex digits, optionally followed by a\n"
76 "# the caching TTL in seconds and another optional field for arbitrary\n"
77 "# flags. Prepend the keygrip with an '!' mark to disable it.\n"
84 /* Return a new uint32 with b0 being the most significant byte and b3
85 being the least significant byte. */
86 #define uint32_construct(b0, b1, b2, b3) \
87 ((b0 << 24) | (b1 << 16) | (b2 << 8) | b3)
96 /* Type for a request handler. */
97 typedef gpg_error_t (*ssh_request_handler_t
) (ctrl_t ctrl
,
101 /* Type, which is used for associating request handlers with the
102 appropriate request IDs. */
103 typedef struct ssh_request_spec
106 ssh_request_handler_t handler
;
107 const char *identifier
;
108 unsigned int secret_input
;
109 } ssh_request_spec_t
;
111 /* Type for "key modifier functions", which are necessary since
112 OpenSSH and GnuPG treat key material slightly different. A key
113 modifier is called right after a new key identity has been received
114 in order to "sanitize" the material. */
115 typedef gpg_error_t (*ssh_key_modifier_t
) (const char *elems
,
118 /* The encoding of a generated signature is dependent on the
119 algorithm; therefore algorithm specific signature encoding
120 functions are necessary. */
121 typedef gpg_error_t (*ssh_signature_encoder_t
) (estream_t signature_blob
,
124 /* Type, which is used for boundling all the algorithm specific
125 information together in a single object. */
126 typedef struct ssh_key_type_spec
128 /* Algorithm identifier as used by OpenSSH. */
129 const char *ssh_identifier
;
131 /* Algorithm identifier as used by GnuPG. */
132 const char *identifier
;
134 /* List of MPI names for secret keys; order matches the one of the
136 const char *elems_key_secret
;
138 /* List of MPI names for public keys; order matches the one of the
140 const char *elems_key_public
;
142 /* List of MPI names for signature data. */
143 const char *elems_signature
;
145 /* List of MPI names for secret keys; order matches the one, which
146 is required by gpg-agent's key access layer. */
147 const char *elems_sexp_order
;
149 /* Key modifier function. Key modifier functions are necessary in
150 order to fix any inconsistencies between the representation of
151 keys on the SSH and on the GnuPG side. */
152 ssh_key_modifier_t key_modifier
;
154 /* Signature encoder function. Signature encoder functions are
155 necessary since the encoding of signatures depends on the used
157 ssh_signature_encoder_t signature_encoder
;
161 } ssh_key_type_spec_t
;
165 static gpg_error_t
ssh_handler_request_identities (ctrl_t ctrl
,
168 static gpg_error_t
ssh_handler_sign_request (ctrl_t ctrl
,
171 static gpg_error_t
ssh_handler_add_identity (ctrl_t ctrl
,
174 static gpg_error_t
ssh_handler_remove_identity (ctrl_t ctrl
,
177 static gpg_error_t
ssh_handler_remove_all_identities (ctrl_t ctrl
,
180 static gpg_error_t
ssh_handler_lock (ctrl_t ctrl
,
183 static gpg_error_t
ssh_handler_unlock (ctrl_t ctrl
,
187 static gpg_error_t
ssh_key_modifier_rsa (const char *elems
, gcry_mpi_t
*mpis
);
188 static gpg_error_t
ssh_signature_encoder_rsa (estream_t signature_blob
,
190 static gpg_error_t
ssh_signature_encoder_dsa (estream_t signature_blob
,
195 /* Global variables. */
198 /* Associating request types with the corresponding request
201 static ssh_request_spec_t request_specs
[] =
203 #define REQUEST_SPEC_DEFINE(id, name, secret_input) \
204 { SSH_REQUEST_##id, ssh_handler_##name, #name, secret_input }
206 REQUEST_SPEC_DEFINE (REQUEST_IDENTITIES
, request_identities
, 1),
207 REQUEST_SPEC_DEFINE (SIGN_REQUEST
, sign_request
, 0),
208 REQUEST_SPEC_DEFINE (ADD_IDENTITY
, add_identity
, 1),
209 REQUEST_SPEC_DEFINE (ADD_ID_CONSTRAINED
, add_identity
, 1),
210 REQUEST_SPEC_DEFINE (REMOVE_IDENTITY
, remove_identity
, 0),
211 REQUEST_SPEC_DEFINE (REMOVE_ALL_IDENTITIES
, remove_all_identities
, 0),
212 REQUEST_SPEC_DEFINE (LOCK
, lock
, 0),
213 REQUEST_SPEC_DEFINE (UNLOCK
, unlock
, 0)
214 #undef REQUEST_SPEC_DEFINE
218 /* Table holding key type specifications. */
219 static ssh_key_type_spec_t ssh_key_types
[] =
222 "ssh-rsa", "rsa", "nedupq", "en", "s", "nedpqu",
223 ssh_key_modifier_rsa
, ssh_signature_encoder_rsa
,
224 SPEC_FLAG_USE_PKCS1V2
227 "ssh-dss", "dsa", "pqgyx", "pqgy", "rs", "pqgyx",
228 NULL
, ssh_signature_encoder_dsa
,
238 General utility functions.
241 /* A secure realloc, i.e. it makes sure to allocate secure memory if A
242 is NULL. This is required because the standard gcry_realloc does
243 not know whether to allocate secure or normal if NULL is passed as
246 realloc_secure (void *a
, size_t n
)
251 p
= gcry_realloc (a
, n
);
253 p
= gcry_malloc_secure (n
);
259 /* Create and return a new C-string from DATA/DATA_N (i.e.: add
260 NUL-termination); return NULL on OOM. */
262 make_cstring (const char *data
, size_t data_n
)
266 s
= xtrymalloc (data_n
+ 1);
269 memcpy (s
, data
, data_n
);
280 Primitive I/O functions.
284 /* Read a byte from STREAM, store it in B. */
286 stream_read_byte (estream_t stream
, unsigned char *b
)
291 ret
= es_fgetc (stream
);
294 if (es_ferror (stream
))
295 err
= gpg_error_from_syserror ();
297 err
= gpg_error (GPG_ERR_EOF
);
309 /* Write the byte contained in B to STREAM. */
311 stream_write_byte (estream_t stream
, unsigned char b
)
316 ret
= es_fputc (b
, stream
);
318 err
= gpg_error_from_syserror ();
325 /* Read a uint32 from STREAM, store it in UINT32. */
327 stream_read_uint32 (estream_t stream
, u32
*uint32
)
329 unsigned char buffer
[4];
334 ret
= es_read (stream
, buffer
, sizeof (buffer
), &bytes_read
);
336 err
= gpg_error_from_syserror ();
339 if (bytes_read
!= sizeof (buffer
))
340 err
= gpg_error (GPG_ERR_EOF
);
345 n
= uint32_construct (buffer
[0], buffer
[1], buffer
[2], buffer
[3]);
354 /* Write the uint32 contained in UINT32 to STREAM. */
356 stream_write_uint32 (estream_t stream
, u32 uint32
)
358 unsigned char buffer
[4];
362 buffer
[0] = uint32
>> 24;
363 buffer
[1] = uint32
>> 16;
364 buffer
[2] = uint32
>> 8;
365 buffer
[3] = uint32
>> 0;
367 ret
= es_write (stream
, buffer
, sizeof (buffer
), NULL
);
369 err
= gpg_error_from_syserror ();
376 /* Read SIZE bytes from STREAM into BUFFER. */
378 stream_read_data (estream_t stream
, unsigned char *buffer
, size_t size
)
384 ret
= es_read (stream
, buffer
, size
, &bytes_read
);
386 err
= gpg_error_from_syserror ();
389 if (bytes_read
!= size
)
390 err
= gpg_error (GPG_ERR_EOF
);
398 /* Write SIZE bytes from BUFFER to STREAM. */
400 stream_write_data (estream_t stream
, const unsigned char *buffer
, size_t size
)
405 ret
= es_write (stream
, buffer
, size
, NULL
);
407 err
= gpg_error_from_syserror ();
414 /* Read a binary string from STREAM into STRING, store size of string
415 in STRING_SIZE; depending on SECURE use secure memory for
418 stream_read_string (estream_t stream
, unsigned int secure
,
419 unsigned char **string
, u32
*string_size
)
422 unsigned char *buffer
= NULL
;
425 /* Read string length. */
426 err
= stream_read_uint32 (stream
, &length
);
430 /* Allocate space. */
432 buffer
= xtrymalloc_secure (length
+ 1);
434 buffer
= xtrymalloc (length
+ 1);
437 err
= gpg_error_from_syserror ();
442 err
= stream_read_data (stream
, buffer
, length
);
446 /* Finalize string object. */
450 *string_size
= length
;
460 /* Read a C-string from STREAM, store copy in STRING. */
462 stream_read_cstring (estream_t stream
, char **string
)
464 unsigned char *buffer
;
467 err
= stream_read_string (stream
, 0, &buffer
, NULL
);
471 *string
= (char *) buffer
;
479 /* Write a binary string from STRING of size STRING_N to STREAM. */
481 stream_write_string (estream_t stream
,
482 const unsigned char *string
, u32 string_n
)
486 err
= stream_write_uint32 (stream
, string_n
);
490 err
= stream_write_data (stream
, string
, string_n
);
497 /* Write a C-string from STRING to STREAM. */
499 stream_write_cstring (estream_t stream
, const char *string
)
503 err
= stream_write_string (stream
,
504 (const unsigned char *) string
, strlen (string
));
509 /* Read an MPI from STREAM, store it in MPINT. Depending on SECURE
510 use secure memory. */
512 stream_read_mpi (estream_t stream
, unsigned int secure
, gcry_mpi_t
*mpint
)
514 unsigned char *mpi_data
;
521 err
= stream_read_string (stream
, secure
, &mpi_data
, &mpi_data_size
);
525 /* To avoid excessive use of secure memory we check that an MPI is
527 if (mpi_data_size
> 520)
529 log_error (_("ssh keys greater than %d bits are not supported\n"), 4096);
530 err
= GPG_ERR_TOO_LARGE
;
534 err
= gcry_mpi_scan (&mpi
, GCRYMPI_FMT_STD
, mpi_data
, mpi_data_size
, NULL
);
547 /* Write the MPI contained in MPINT to STREAM. */
549 stream_write_mpi (estream_t stream
, gcry_mpi_t mpint
)
551 unsigned char *mpi_buffer
;
557 err
= gcry_mpi_aprint (GCRYMPI_FMT_STD
, &mpi_buffer
, &mpi_buffer_n
, mpint
);
561 err
= stream_write_string (stream
, mpi_buffer
, mpi_buffer_n
);
570 /* Copy data from SRC to DST until EOF is reached. */
572 stream_copy (estream_t dst
, estream_t src
)
582 ret
= es_read (src
, buffer
, sizeof (buffer
), &bytes_read
);
583 if (ret
|| (! bytes_read
))
586 err
= gpg_error_from_syserror ();
589 ret
= es_write (dst
, buffer
, bytes_read
, NULL
);
592 err
= gpg_error_from_syserror ();
601 /* Read the content of the file specified by FILENAME into a newly
602 create buffer, which is to be stored in BUFFER; store length of
603 buffer in BUFFER_N. */
605 file_to_buffer (const char *filename
, unsigned char **buffer
, size_t *buffer_n
)
607 unsigned char *buffer_new
;
619 stream
= es_fopen (filename
, "r");
622 err
= gpg_error_from_syserror ();
626 ret
= fstat (es_fileno (stream
), &statbuf
);
629 err
= gpg_error_from_syserror ();
633 buffer_new
= xtrymalloc (statbuf
.st_size
);
636 err
= gpg_error_from_syserror ();
640 err
= stream_read_data (stream
, buffer_new
, statbuf
.st_size
);
644 *buffer
= buffer_new
;
645 *buffer_n
= statbuf
.st_size
;
661 /* Open the ssh control file and create it if not available. With
662 APPEND passed as true the file will be opened in append mode,
663 otherwise in read only mode. On success a file pointer is stored
664 at the address of R_FP. */
666 open_control_file (FILE **r_fp
, int append
)
672 /* Note: As soon as we start to use non blocking functions here
673 (i.e. where Pth might switch threads) we need to employ a
676 fname
= make_filename (opt
.homedir
, "sshcontrol", NULL
);
677 /* FIXME: With "a+" we are not able to check whether this will will
678 be created and thus the blurb needs to be written first. */
679 fp
= fopen (fname
, append
? "a+":"r");
680 if (!fp
&& errno
== ENOENT
)
682 /* Fixme: "x" is a GNU extension. We might want to use the es_
684 fp
= fopen (fname
, "wx");
687 err
= gpg_error (gpg_err_code_from_errno (errno
));
688 log_error (_("can't create `%s': %s\n"), fname
, gpg_strerror (err
));
692 fputs (sshcontrolblurb
, fp
);
694 fp
= fopen (fname
, append
? "a+":"r");
699 err
= gpg_error (gpg_err_code_from_errno (errno
));
700 log_error (_("can't open `%s': %s\n"), fname
, gpg_strerror (err
));
711 /* Search the file at stream FP from the beginning until a matching
712 HEXGRIP is found; return success in this case and store true at
713 DISABLED if the found key has been disabled. */
715 search_control_file (FILE *fp
, const char *hexgrip
, int *disabled
)
720 assert (strlen (hexgrip
) == 40 );
727 if (!fgets (line
, DIM(line
)-1, fp
) )
730 return gpg_error (GPG_ERR_EOF
);
731 return gpg_error (gpg_err_code_from_errno (errno
));
734 if (!*line
|| line
[strlen(line
)-1] != '\n')
736 /* Eat until end of line */
737 while ( (c
=getc (fp
)) != EOF
&& c
!= '\n')
739 return gpg_error (*line
? GPG_ERR_LINE_TOO_LONG
740 : GPG_ERR_INCOMPLETE_LINE
);
743 /* Allow for empty lines and spaces */
744 for (p
=line
; spacep (p
); p
++)
747 while (!*p
|| *p
== '\n' || *p
== '#');
753 for (p
++; spacep (p
); p
++)
757 for (i
=0; hexdigitp (p
) && i
< 40; p
++, i
++)
758 if (hexgrip
[i
] != (*p
>= 'a'? (*p
& 0xdf): *p
))
760 if (i
!= 40 || !(spacep (p
) || *p
== '\n'))
762 log_error ("invalid formatted line in ssh control file\n");
763 return gpg_error (GPG_ERR_BAD_DATA
);
766 /* Fixme: Get TTL and flags. */
768 return 0; /* Okay: found it. */
773 /* Add an entry to the control file to mark the key with the keygrip
774 HEXGRIP as usable for SSH; i.e. it will be returned when ssh asks
775 for it. This function is in general used to add a key received
776 through the ssh-add function. We can assume that the user wants to
777 allow ssh using this key. */
779 add_control_entry (ctrl_t ctrl
, const char *hexgrip
, int ttl
)
787 err
= open_control_file (&fp
, 1);
791 err
= search_control_file (fp
, hexgrip
, &disabled
);
792 if (err
&& gpg_err_code(err
) == GPG_ERR_EOF
)
795 time_t atime
= time (NULL
);
797 /* Not yet in the file - add it. Because the file has been
798 opened in append mode, we simply need to write to it. */
799 tp
= localtime (&atime
);
800 fprintf (fp
, "# Key added on %04d-%02d-%02d %02d:%02d:%02d\n%s %d\n",
801 1900+tp
->tm_year
, tp
->tm_mon
+1, tp
->tm_mday
,
802 tp
->tm_hour
, tp
->tm_min
, tp
->tm_sec
,
820 /* Free the list of MPIs MPI_LIST. */
822 mpint_list_free (gcry_mpi_t
*mpi_list
)
828 for (i
= 0; mpi_list
[i
]; i
++)
829 gcry_mpi_release (mpi_list
[i
]);
834 /* Receive key material MPIs from STREAM according to KEY_SPEC;
835 depending on SECRET expect a public key or secret key. The newly
836 allocated list of MPIs is stored in MPI_LIST. Returns usual error
839 ssh_receive_mpint_list (estream_t stream
, int secret
,
840 ssh_key_type_spec_t key_spec
, gcry_mpi_t
**mpi_list
)
842 unsigned int elems_public_n
;
843 const char *elems_public
;
844 unsigned int elems_n
;
855 elems
= key_spec
.elems_key_secret
;
857 elems
= key_spec
.elems_key_public
;
858 elems_n
= strlen (elems
);
860 elems_public
= key_spec
.elems_key_public
;
861 elems_public_n
= strlen (elems_public
);
863 mpis
= xtrycalloc (elems_n
+ 1, sizeof *mpis
);
866 err
= gpg_error_from_syserror ();
871 for (i
= 0; i
< elems_n
; i
++)
874 elem_is_secret
= ! strchr (elems_public
, elems
[i
]);
875 err
= stream_read_mpi (stream
, elem_is_secret
, &mpis
[i
]);
887 mpint_list_free (mpis
);
894 /* Key modifier function for RSA. */
896 ssh_key_modifier_rsa (const char *elems
, gcry_mpi_t
*mpis
)
902 if (strcmp (elems
, "nedupq"))
903 /* Modifying only necessary for secret keys. */
910 if (gcry_mpi_cmp (p
, q
) > 0)
912 /* P shall be smaller then Q! Swap primes. iqmp becomes u. */
920 /* U needs to be recomputed. */
921 gcry_mpi_invm (u
, p
, q
);
928 /* Signature encoder function for RSA. */
930 ssh_signature_encoder_rsa (estream_t signature_blob
, gcry_mpi_t
*mpis
)
939 err
= gcry_mpi_aprint (GCRYMPI_FMT_USG
, &data
, &data_n
, s
);
943 err
= stream_write_string (signature_blob
, data
, data_n
);
952 /* Signature encoder function for DSA. */
954 ssh_signature_encoder_dsa (estream_t signature_blob
, gcry_mpi_t
*mpis
)
956 unsigned char buffer
[SSH_DSA_SIGNATURE_PADDING
* SSH_DSA_SIGNATURE_ELEMS
];
964 for (i
= 0; i
< 2; i
++)
966 err
= gcry_mpi_aprint (GCRYMPI_FMT_USG
, &data
, &data_n
, mpis
[i
]);
970 if (data_n
> SSH_DSA_SIGNATURE_PADDING
)
972 err
= gpg_error (GPG_ERR_INTERNAL
); /* FIXME? */
976 memset (buffer
+ (i
* SSH_DSA_SIGNATURE_PADDING
), 0,
977 SSH_DSA_SIGNATURE_PADDING
- data_n
);
978 memcpy (buffer
+ (i
* SSH_DSA_SIGNATURE_PADDING
)
979 + (SSH_DSA_SIGNATURE_PADDING
- data_n
), data
, data_n
);
987 err
= stream_write_string (signature_blob
, buffer
, sizeof (buffer
));
1001 /* This function constructs a new S-Expression for the key identified
1002 by the KEY_SPEC, SECRET, MPIS and COMMENT, which is to be stored in
1003 *SEXP. Returns usual error code. */
1005 sexp_key_construct (gcry_sexp_t
*sexp
,
1006 ssh_key_type_spec_t key_spec
, int secret
,
1007 gcry_mpi_t
*mpis
, const char *comment
)
1009 const char *key_identifier
[] = { "public-key", "private-key" };
1010 gcry_sexp_t sexp_new
;
1011 char *sexp_template
;
1012 size_t sexp_template_n
;
1024 elems
= key_spec
.elems_sexp_order
;
1026 elems
= key_spec
.elems_key_public
;
1027 elems_n
= strlen (elems
);
1030 Calculate size for sexp_template_n:
1032 "(%s(%s<mpis>)(comment%s))" -> 20 + sizeof (<mpis>).
1037 sexp_template_n
= 20 + (elems_n
* 5);
1038 sexp_template
= xtrymalloc (sexp_template_n
);
1039 if (! sexp_template
)
1041 err
= gpg_error_from_syserror ();
1045 /* Key identifier, algorithm identifier, mpis, comment. */
1046 arg_list
= xtrymalloc (sizeof (*arg_list
) * (2 + elems_n
+ 1));
1049 err
= gpg_error_from_syserror ();
1054 arg_list
[i
++] = &key_identifier
[secret
];
1055 arg_list
[i
++] = &key_spec
.identifier
;
1058 sexp_template_n
= 0;
1059 sexp_template_n
= sprintf (sexp_template
+ sexp_template_n
, "(%%s(%%s");
1060 for (i
= 0; i
< elems_n
; i
++)
1062 sexp_template_n
+= sprintf (sexp_template
+ sexp_template_n
, "(%c%%m)",
1066 for (j
= 0; j
< elems_n
; j
++)
1067 if (key_spec
.elems_key_secret
[j
] == elems
[i
])
1072 arg_list
[i
+ 2] = &mpis
[j
];
1074 sexp_template_n
+= sprintf (sexp_template
+ sexp_template_n
,
1077 arg_list
[i
+ 2] = &comment
;
1079 err
= gcry_sexp_build_array (&sexp_new
, NULL
, sexp_template
, arg_list
);
1088 xfree (sexp_template
);
1093 /* This functions breaks up the key contained in the S-Expression SEXP
1094 according to KEY_SPEC. The MPIs are bundled in a newly create
1095 list, which is to be stored in MPIS; a newly allocated string
1096 holding the comment will be stored in COMMENT; SECRET will be
1097 filled with a boolean flag specifying what kind of key it is.
1098 Returns usual error code. */
1100 sexp_key_extract (gcry_sexp_t sexp
,
1101 ssh_key_type_spec_t key_spec
, int *secret
,
1102 gcry_mpi_t
**mpis
, char **comment
)
1105 gcry_sexp_t value_list
;
1106 gcry_sexp_t value_pair
;
1107 gcry_sexp_t comment_list
;
1115 gcry_mpi_t
*mpis_new
;
1121 comment_list
= NULL
;
1125 data
= gcry_sexp_nth_data (sexp
, 0, &data_n
);
1128 err
= gpg_error (GPG_ERR_INV_SEXP
);
1132 if ((data_n
== 10 && !strncmp (data
, "public-key", 10))
1133 || (data_n
== 21 && !strncmp (data
, "protected-private-key", 21))
1134 || (data_n
== 20 && !strncmp (data
, "shadowed-private-key", 20)))
1137 elems
= key_spec
.elems_key_public
;
1139 else if (data_n
== 11 && !strncmp (data
, "private-key", 11))
1142 elems
= key_spec
.elems_key_secret
;
1146 err
= gpg_error (GPG_ERR_INV_SEXP
);
1150 elems_n
= strlen (elems
);
1151 mpis_new
= xtrycalloc (elems_n
+ 1, sizeof *mpis_new
);
1154 err
= gpg_error_from_syserror ();
1158 value_list
= gcry_sexp_find_token (sexp
, key_spec
.identifier
, 0);
1161 err
= gpg_error (GPG_ERR_INV_SEXP
);
1165 for (i
= 0; i
< elems_n
; i
++)
1167 value_pair
= gcry_sexp_find_token (value_list
, elems
+ i
, 1);
1170 err
= gpg_error (GPG_ERR_INV_SEXP
);
1174 /* Note that we need to use STD format; i.e. prepend a 0x00 to
1175 indicate a positive number if the high bit is set. */
1176 mpi
= gcry_sexp_nth_mpi (value_pair
, 1, GCRYMPI_FMT_STD
);
1179 err
= gpg_error (GPG_ERR_INV_SEXP
);
1183 gcry_sexp_release (value_pair
);
1189 /* We do not require a comment sublist to be present here. */
1193 comment_list
= gcry_sexp_find_token (sexp
, "comment", 0);
1195 data
= gcry_sexp_nth_data (comment_list
, 1, &data_n
);
1202 comment_new
= make_cstring (data
, data_n
);
1205 err
= gpg_error_from_syserror ();
1210 *secret
= is_secret
;
1212 *comment
= comment_new
;
1216 gcry_sexp_release (value_list
);
1217 gcry_sexp_release (value_pair
);
1218 gcry_sexp_release (comment_list
);
1222 xfree (comment_new
);
1223 mpint_list_free (mpis_new
);
1229 /* Extract the car from SEXP, and create a newly created C-string
1230 which is to be stored in IDENTIFIER. */
1232 sexp_extract_identifier (gcry_sexp_t sexp
, char **identifier
)
1234 char *identifier_new
;
1235 gcry_sexp_t sublist
;
1240 identifier_new
= NULL
;
1243 sublist
= gcry_sexp_nth (sexp
, 1);
1246 err
= gpg_error (GPG_ERR_INV_SEXP
);
1250 data
= gcry_sexp_nth_data (sublist
, 0, &data_n
);
1253 err
= gpg_error (GPG_ERR_INV_SEXP
);
1257 identifier_new
= make_cstring (data
, data_n
);
1258 if (! identifier_new
)
1260 err
= gpg_err_code_from_errno (errno
);
1264 *identifier
= identifier_new
;
1268 gcry_sexp_release (sublist
);
1281 /* Search for a key specification entry. If SSH_NAME is not NULL,
1282 search for an entry whose "ssh_name" is equal to SSH_NAME;
1283 otherwise, search for an entry whose "name" is equal to NAME.
1284 Store found entry in SPEC on success, return error otherwise. */
1286 ssh_key_type_lookup (const char *ssh_name
, const char *name
,
1287 ssh_key_type_spec_t
*spec
)
1292 for (i
= 0; i
< DIM (ssh_key_types
); i
++)
1293 if ((ssh_name
&& (! strcmp (ssh_name
, ssh_key_types
[i
].ssh_identifier
)))
1294 || (name
&& (! strcmp (name
, ssh_key_types
[i
].identifier
))))
1297 if (i
== DIM (ssh_key_types
))
1298 err
= gpg_error (GPG_ERR_NOT_FOUND
);
1301 *spec
= ssh_key_types
[i
];
1308 /* Receive a key from STREAM, according to the key specification given
1309 as KEY_SPEC. Depending on SECRET, receive a secret or a public
1310 key. If READ_COMMENT is true, receive a comment string as well.
1311 Constructs a new S-Expression from received data and stores it in
1312 KEY_NEW. Returns zero on success or an error code. */
1314 ssh_receive_key (estream_t stream
, gcry_sexp_t
*key_new
, int secret
,
1315 int read_comment
, ssh_key_type_spec_t
*key_spec
)
1321 ssh_key_type_spec_t spec
;
1322 gcry_mpi_t
*mpi_list
;
1330 err
= stream_read_cstring (stream
, &key_type
);
1334 err
= ssh_key_type_lookup (key_type
, NULL
, &spec
);
1338 err
= ssh_receive_mpint_list (stream
, secret
, spec
, &mpi_list
);
1344 err
= stream_read_cstring (stream
, &comment
);
1350 elems
= spec
.elems_key_secret
;
1352 elems
= spec
.elems_key_public
;
1354 if (spec
.key_modifier
)
1356 err
= (*spec
.key_modifier
) (elems
, mpi_list
);
1361 err
= sexp_key_construct (&key
, spec
, secret
, mpi_list
, comment
);
1371 mpint_list_free (mpi_list
);
1379 /* Converts a key of type TYPE, whose key material is given in MPIS,
1380 into a newly created binary blob, which is to be stored in
1381 BLOB/BLOB_SIZE. Returns zero on success or an error code. */
1383 ssh_convert_key_to_blob (unsigned char **blob
, size_t *blob_size
,
1384 const char *type
, gcry_mpi_t
*mpis
)
1386 unsigned char *blob_new
;
1387 long int blob_size_new
;
1399 stream
= es_mopen (NULL
, 0, 0, 1, NULL
, NULL
, "r+");
1402 err
= gpg_error_from_syserror ();
1406 err
= stream_write_cstring (stream
, type
);
1410 for (i
= 0; mpis
[i
] && (! err
); i
++)
1411 err
= stream_write_mpi (stream
, mpis
[i
]);
1415 blob_size_new
= es_ftell (stream
);
1416 if (blob_size_new
== -1)
1418 err
= gpg_error_from_syserror ();
1422 err
= es_fseek (stream
, 0, SEEK_SET
);
1426 blob_new
= xtrymalloc (blob_size_new
);
1429 err
= gpg_error_from_syserror ();
1433 err
= stream_read_data (stream
, blob_new
, blob_size_new
);
1438 *blob_size
= blob_size_new
;
1451 /* Write the public key KEY_PUBLIC to STREAM in SSH key format. If
1452 OVERRIDE_COMMENT is not NULL, it will be used instead of the
1453 comment stored in the key. */
1455 ssh_send_key_public (estream_t stream
, gcry_sexp_t key_public
,
1456 const char *override_comment
)
1458 ssh_key_type_spec_t spec
;
1459 gcry_mpi_t
*mpi_list
;
1462 unsigned char *blob
;
1471 err
= sexp_extract_identifier (key_public
, &key_type
);
1475 err
= ssh_key_type_lookup (NULL
, key_type
, &spec
);
1479 err
= sexp_key_extract (key_public
, spec
, NULL
, &mpi_list
, &comment
);
1483 err
= ssh_convert_key_to_blob (&blob
, &blob_n
,
1484 spec
.ssh_identifier
, mpi_list
);
1488 err
= stream_write_string (stream
, blob
, blob_n
);
1492 err
= stream_write_cstring (stream
,
1493 override_comment
? override_comment
: comment
);
1497 mpint_list_free (mpi_list
);
1505 /* Read a public key out of BLOB/BLOB_SIZE according to the key
1506 specification given as KEY_SPEC, storing the new key in KEY_PUBLIC.
1507 Returns zero on success or an error code. */
1509 ssh_read_key_public_from_blob (unsigned char *blob
, size_t blob_size
,
1510 gcry_sexp_t
*key_public
,
1511 ssh_key_type_spec_t
*key_spec
)
1513 estream_t blob_stream
;
1518 blob_stream
= es_mopen (NULL
, 0, 0, 1, NULL
, NULL
, "r+");
1521 err
= gpg_error_from_syserror ();
1525 err
= stream_write_data (blob_stream
, blob
, blob_size
);
1529 err
= es_fseek (blob_stream
, 0, SEEK_SET
);
1533 err
= ssh_receive_key (blob_stream
, key_public
, 0, 0, key_spec
);
1538 es_fclose (blob_stream
);
1545 /* This function calculates the key grip for the key contained in the
1546 S-Expression KEY and writes it to BUFFER, which must be large
1547 enough to hold it. Returns usual error code. */
1549 ssh_key_grip (gcry_sexp_t key
, unsigned char *buffer
)
1551 if (!gcry_pk_get_keygrip (key
, buffer
))
1552 return gpg_error (GPG_ERR_INTERNAL
);
1557 /* Converts the secret key KEY_SECRET into a public key, storing it in
1558 KEY_PUBLIC. SPEC is the according key specification. Returns zero
1559 on success or an error code. */
1561 key_secret_to_public (gcry_sexp_t
*key_public
,
1562 ssh_key_type_spec_t spec
, gcry_sexp_t key_secret
)
1572 err
= sexp_key_extract (key_secret
, spec
, &is_secret
, &mpis
, &comment
);
1576 err
= sexp_key_construct (key_public
, spec
, 0, mpis
, comment
);
1580 mpint_list_free (mpis
);
1587 /* Check whether a smartcard is available and whether it has a usable
1588 key. Store a copy of that key at R_PK and return 0. If no key is
1589 available store NULL at R_PK and return an error code. If CARDSN
1590 is not NULL, a string with the serial number of the card will be
1591 a malloced and stored there. */
1593 card_key_available (ctrl_t ctrl
, gcry_sexp_t
*r_pk
, char **cardsn
)
1597 char *serialno
= NULL
;
1598 unsigned char *pkbuf
;
1601 unsigned char grip
[20];
1607 /* First see whether a card is available and whether the application
1609 err
= agent_card_getattr (ctrl
, "$AUTHKEYID", &authkeyid
);
1610 if ( gpg_err_code (err
) == GPG_ERR_CARD_REMOVED
)
1612 /* Ask for the serial number to reset the card. */
1613 err
= agent_card_serialno (ctrl
, &serialno
);
1617 log_info (_("error getting serial number of card: %s\n"),
1618 gpg_strerror (err
));
1621 log_info (_("detected card with S/N: %s\n"), serialno
);
1622 err
= agent_card_getattr (ctrl
, "$AUTHKEYID", &authkeyid
);
1626 log_error (_("error getting default authentication keyID of card: %s\n"),
1627 gpg_strerror (err
));
1632 /* Get the S/N if we don't have it yet. Use the fast getattr method. */
1633 if (!serialno
&& (err
= agent_card_getattr (ctrl
, "SERIALNO", &serialno
)) )
1635 log_error (_("error getting serial number of card: %s\n"),
1636 gpg_strerror (err
));
1641 /* Read the public key. */
1642 err
= agent_card_readkey (ctrl
, authkeyid
, &pkbuf
);
1646 log_info (_("no suitable card key found: %s\n"), gpg_strerror (err
));
1652 pkbuflen
= gcry_sexp_canon_len (pkbuf
, 0, NULL
, NULL
);
1653 err
= gcry_sexp_sscan (&s_pk
, NULL
, (char*)pkbuf
, pkbuflen
);
1656 log_error ("failed to build S-Exp from received card key: %s\n",
1657 gpg_strerror (err
));
1664 err
= ssh_key_grip (s_pk
, grip
);
1667 log_debug ("error computing keygrip from received card key: %s\n",
1668 gcry_strerror (err
));
1670 gcry_sexp_release (s_pk
);
1676 if ( agent_key_available (grip
) )
1678 /* (Shadow)-key is not available in our key storage. */
1679 unsigned char *shadow_info
;
1682 shadow_info
= make_shadow_info (serialno
, authkeyid
);
1685 err
= gpg_error_from_syserror ();
1687 gcry_sexp_release (s_pk
);
1692 err
= agent_shadow_key (pkbuf
, shadow_info
, &tmp
);
1693 xfree (shadow_info
);
1696 log_error (_("shadowing the key failed: %s\n"), gpg_strerror (err
));
1698 gcry_sexp_release (s_pk
);
1705 pkbuflen
= gcry_sexp_canon_len (pkbuf
, 0, NULL
, NULL
);
1708 err
= agent_write_private_key (grip
, pkbuf
, pkbuflen
, 0);
1711 log_error (_("error writing key: %s\n"), gpg_strerror (err
));
1713 gcry_sexp_release (s_pk
);
1724 /* If the card handler is able to return a short serialnumber,
1725 use that one, else use the complete serialno. */
1726 if (!agent_card_getattr (ctrl
, "$DISPSERIALNO", &dispsn
))
1728 *cardsn
= xtryasprintf ("cardno:%s", dispsn
);
1732 *cardsn
= xtryasprintf ("cardno:%s", serialno
);
1735 err
= gpg_error_from_syserror ();
1737 gcry_sexp_release (s_pk
);
1756 Request handler. Each handler is provided with a CTRL context, a
1757 REQUEST object and a RESPONSE object. The actual request is to be
1758 read from REQUEST, the response needs to be written to RESPONSE.
1763 /* Handler for the "request_identities" command. */
1765 ssh_handler_request_identities (ctrl_t ctrl
,
1766 estream_t request
, estream_t response
)
1769 ssh_key_type_spec_t spec
;
1770 struct dirent
*dir_entry
;
1771 char *key_directory
;
1772 size_t key_directory_n
;
1774 unsigned char *buffer
;
1777 estream_t key_blobs
;
1778 gcry_sexp_t key_secret
;
1779 gcry_sexp_t key_public
;
1783 FILE *ctrl_fp
= NULL
;
1785 gpg_error_t ret_err
;
1789 /* Prepare buffer stream. */
1791 key_directory
= NULL
;
1801 key_blobs
= es_mopen (NULL
, 0, 0, 1, NULL
, NULL
, "r+");
1804 err
= gpg_error_from_syserror ();
1808 /* Open key directory. */
1809 key_directory
= make_filename (opt
.homedir
, GNUPG_PRIVATE_KEYS_DIR
, NULL
);
1810 if (! key_directory
)
1812 err
= gpg_err_code_from_errno (errno
);
1815 key_directory_n
= strlen (key_directory
);
1817 key_path
= xtrymalloc (key_directory_n
+ 46);
1820 err
= gpg_err_code_from_errno (errno
);
1824 sprintf (key_path
, "%s/", key_directory
);
1825 sprintf (key_path
+ key_directory_n
+ 41, ".key");
1827 dir
= opendir (key_directory
);
1830 err
= gpg_err_code_from_errno (errno
);
1836 /* First check whether a key is currently available in the card
1837 reader - this should be allowed even without being listed in
1840 if (!card_key_available (ctrl
, &key_public
, &cardsn
))
1842 err
= ssh_send_key_public (key_blobs
, key_public
, cardsn
);
1843 gcry_sexp_release (key_public
);
1853 /* Then look at all the registered an allowed keys. */
1856 /* Fixme: We should better iterate over the control file and check
1857 whether the key file is there. This is better in resepct to
1858 performance if tehre are a lot of key sin our key storage. */
1859 /* FIXME: make sure that buffer gets deallocated properly. */
1860 err
= open_control_file (&ctrl_fp
, 0);
1864 while ( (dir_entry
= readdir (dir
)) )
1866 if ((strlen (dir_entry
->d_name
) == 44)
1867 && (! strncmp (dir_entry
->d_name
+ 40, ".key", 4)))
1872 /* We do only want to return keys listed in our control
1874 strncpy (hexgrip
, dir_entry
->d_name
, 40);
1876 if ( strlen (hexgrip
) != 40 )
1878 if (search_control_file (ctrl_fp
, hexgrip
, &disabled
)
1882 strncpy (key_path
+ key_directory_n
+ 1, dir_entry
->d_name
, 40);
1884 /* Read file content. */
1885 err
= file_to_buffer (key_path
, &buffer
, &buffer_n
);
1889 err
= gcry_sexp_sscan (&key_secret
, NULL
, (char*)buffer
, buffer_n
);
1896 err
= sexp_extract_identifier (key_secret
, &key_type
);
1900 err
= ssh_key_type_lookup (NULL
, key_type
, &spec
);
1907 err
= key_secret_to_public (&key_public
, spec
, key_secret
);
1911 gcry_sexp_release (key_secret
);
1914 err
= ssh_send_key_public (key_blobs
, key_public
, NULL
);
1918 gcry_sexp_release (key_public
);
1925 ret
= es_fseek (key_blobs
, 0, SEEK_SET
);
1928 err
= gpg_error_from_syserror ();
1934 /* Send response. */
1936 gcry_sexp_release (key_secret
);
1937 gcry_sexp_release (key_public
);
1941 ret_err
= stream_write_byte (response
, SSH_RESPONSE_IDENTITIES_ANSWER
);
1944 ret_err
= stream_write_uint32 (response
, key_counter
);
1947 ret_err
= stream_copy (response
, key_blobs
);
1953 ret_err
= stream_write_byte (response
, SSH_RESPONSE_FAILURE
);
1960 es_fclose (key_blobs
);
1967 xfree (key_directory
);
1975 /* This function hashes the data contained in DATA of size DATA_N
1976 according to the message digest algorithm specified by MD_ALGORITHM
1977 and writes the message digest to HASH, which needs to large enough
1980 data_hash (unsigned char *data
, size_t data_n
,
1981 int md_algorithm
, unsigned char *hash
)
1983 gcry_md_hash_buffer (md_algorithm
, hash
, data
, data_n
);
1988 /* This function signs the data contained in CTRL, stores the created
1989 signature in newly allocated memory in SIG and it's size in SIG_N;
1990 SIG_ENCODER is the signature encoder to use. */
1992 data_sign (ctrl_t ctrl
, ssh_signature_encoder_t sig_encoder
,
1993 unsigned char **sig
, size_t *sig_n
)
1996 gcry_sexp_t signature_sexp
= NULL
;
1997 estream_t stream
= NULL
;
1998 gcry_sexp_t valuelist
= NULL
;
1999 gcry_sexp_t sublist
= NULL
;
2000 gcry_mpi_t sig_value
= NULL
;
2001 unsigned char *sig_blob
= NULL
;
2002 size_t sig_blob_n
= 0;
2003 char *identifier
= NULL
;
2004 const char *identifier_raw
;
2005 size_t identifier_n
;
2006 ssh_key_type_spec_t spec
;
2011 gcry_mpi_t
*mpis
= NULL
;
2016 ctrl
->use_auth_call
= 1;
2017 err
= agent_pksign_do (ctrl
,
2018 _("Please enter the passphrase "
2019 "for the ssh key%0A %c"), &signature_sexp
,
2021 ctrl
->use_auth_call
= 0;
2025 valuelist
= gcry_sexp_nth (signature_sexp
, 1);
2028 err
= gpg_error (GPG_ERR_INV_SEXP
);
2032 stream
= es_mopen (NULL
, 0, 0, 1, NULL
, NULL
, "r+");
2035 err
= gpg_error_from_syserror ();
2039 identifier_raw
= gcry_sexp_nth_data (valuelist
, 0, &identifier_n
);
2040 if (! identifier_raw
)
2042 err
= gpg_error (GPG_ERR_INV_SEXP
);
2046 identifier
= make_cstring (identifier_raw
, identifier_n
);
2049 err
= gpg_error_from_syserror ();
2053 err
= ssh_key_type_lookup (NULL
, identifier
, &spec
);
2057 err
= stream_write_cstring (stream
, spec
.ssh_identifier
);
2061 elems
= spec
.elems_signature
;
2062 elems_n
= strlen (elems
);
2064 mpis
= xtrycalloc (elems_n
+ 1, sizeof *mpis
);
2067 err
= gpg_error_from_syserror ();
2071 for (i
= 0; i
< elems_n
; i
++)
2073 sublist
= gcry_sexp_find_token (valuelist
, spec
.elems_signature
+ i
, 1);
2076 err
= gpg_error (GPG_ERR_INV_SEXP
);
2080 sig_value
= gcry_sexp_nth_mpi (sublist
, 1, GCRYMPI_FMT_USG
);
2083 err
= gpg_error (GPG_ERR_INTERNAL
); /* FIXME? */
2086 gcry_sexp_release (sublist
);
2089 mpis
[i
] = sig_value
;
2094 err
= (*sig_encoder
) (stream
, mpis
);
2098 sig_blob_n
= es_ftell (stream
);
2099 if (sig_blob_n
== -1)
2101 err
= gpg_error_from_syserror ();
2105 sig_blob
= xtrymalloc (sig_blob_n
);
2108 err
= gpg_error_from_syserror ();
2112 ret
= es_fseek (stream
, 0, SEEK_SET
);
2115 err
= gpg_error_from_syserror ();
2119 err
= stream_read_data (stream
, sig_blob
, sig_blob_n
);
2124 *sig_n
= sig_blob_n
;
2133 gcry_sexp_release (valuelist
);
2134 gcry_sexp_release (signature_sexp
);
2135 gcry_sexp_release (sublist
);
2136 mpint_list_free (mpis
);
2142 /* Handler for the "sign_request" command. */
2144 ssh_handler_sign_request (ctrl_t ctrl
, estream_t request
, estream_t response
)
2147 ssh_key_type_spec_t spec
;
2148 unsigned char hash
[MAX_DIGEST_LEN
];
2149 unsigned int hash_n
;
2150 unsigned char key_grip
[20];
2151 unsigned char *key_blob
;
2153 unsigned char *data
;
2159 gpg_error_t ret_err
;
2168 err
= stream_read_string (request
, 0, &key_blob
, &key_blob_size
);
2172 err
= ssh_read_key_public_from_blob (key_blob
, key_blob_size
, &key
, &spec
);
2176 /* Receive data to sign. */
2177 err
= stream_read_string (request
, 0, &data
, &data_size
);
2182 err
= stream_read_uint32 (request
, &flags
);
2187 hash_n
= gcry_md_get_algo_dlen (GCRY_MD_SHA1
);
2190 err
= gpg_error (GPG_ERR_INTERNAL
);
2193 err
= data_hash (data
, data_size
, GCRY_MD_SHA1
, hash
);
2197 /* Calculate key grip. */
2198 err
= ssh_key_grip (key
, key_grip
);
2204 ctrl
->digest
.algo
= GCRY_MD_SHA1
;
2205 memcpy (ctrl
->digest
.value
, hash
, hash_n
);
2206 ctrl
->digest
.valuelen
= hash_n
;
2207 ctrl
->digest
.raw_value
= ! (spec
.flags
& SPEC_FLAG_USE_PKCS1V2
);
2208 ctrl
->have_keygrip
= 1;
2209 memcpy (ctrl
->keygrip
, key_grip
, 20);
2211 err
= data_sign (ctrl
, spec
.signature_encoder
, &sig
, &sig_n
);
2219 ret_err
= stream_write_byte (response
, SSH_RESPONSE_SIGN_RESPONSE
);
2222 ret_err
= stream_write_string (response
, sig
, sig_n
);
2228 ret_err
= stream_write_byte (response
, SSH_RESPONSE_FAILURE
);
2235 gcry_sexp_release (key
);
2243 /* This function extracts the comment contained in the key
2244 S-Expression KEY and stores a copy in COMMENT. Returns usual error
2247 ssh_key_extract_comment (gcry_sexp_t key
, char **comment
)
2249 gcry_sexp_t comment_list
;
2255 comment_list
= gcry_sexp_find_token (key
, "comment", 0);
2258 err
= gpg_error (GPG_ERR_INV_SEXP
);
2262 data
= gcry_sexp_nth_data (comment_list
, 1, &data_n
);
2265 err
= gpg_error (GPG_ERR_INV_SEXP
);
2269 comment_new
= make_cstring (data
, data_n
);
2272 err
= gpg_error_from_syserror ();
2276 *comment
= comment_new
;
2281 gcry_sexp_release (comment_list
);
2286 /* This function converts the key contained in the S-Expression KEY
2287 into a buffer, which is protected by the passphrase PASSPHRASE.
2288 Returns usual error code. */
2290 ssh_key_to_protected_buffer (gcry_sexp_t key
, const char *passphrase
,
2291 unsigned char **buffer
, size_t *buffer_n
)
2293 unsigned char *buffer_new
;
2294 unsigned int buffer_new_n
;
2298 buffer_new_n
= gcry_sexp_sprint (key
, GCRYSEXP_FMT_CANON
, NULL
, 0);
2299 buffer_new
= xtrymalloc_secure (buffer_new_n
);
2302 err
= gpg_error_from_syserror ();
2306 gcry_sexp_sprint (key
, GCRYSEXP_FMT_CANON
, buffer_new
, buffer_new_n
);
2307 /* FIXME: guarantee? */
2309 err
= agent_protect (buffer_new
, passphrase
, buffer
, buffer_n
);
2320 /* Callback function to compare the first entered PIN with the one
2321 currently being entered. */
2323 reenter_compare_cb (struct pin_entry_info_s
*pi
)
2325 const char *pin1
= pi
->check_cb_arg
;
2327 if (!strcmp (pin1
, pi
->pin
))
2328 return 0; /* okay */
2332 /* Store the ssh KEY into our local key storage and protect it after
2333 asking for a passphrase. Cache that passphrase. TTL is the
2334 maximum caching time for that key. If the key already exists in
2335 our key storage, don't do anything. When entering a new key also
2336 add an entry to the sshcontrol file. */
2338 ssh_identity_register (ctrl_t ctrl
, gcry_sexp_t key
, int ttl
)
2341 unsigned char key_grip_raw
[20];
2343 unsigned char *buffer
= NULL
;
2345 char *description
= NULL
;
2346 const char *description2
= _("Please re-enter this passphrase");
2347 char *comment
= NULL
;
2348 const char *initial_errtext
= NULL
;
2350 struct pin_entry_info_s
*pi
= NULL
, *pi2
;
2352 err
= ssh_key_grip (key
, key_grip_raw
);
2356 /* Check whether the key is already in our key storage. Don't do
2358 if ( !agent_key_available (key_grip_raw
) )
2359 goto out
; /* Yes, key is available. */
2362 err
= ssh_key_extract_comment (key
, &comment
);
2366 if ( asprintf (&description
,
2367 _("Please enter a passphrase to protect"
2368 " the received secret key%%0A"
2370 "within gpg-agent's key storage"),
2371 comment
? comment
: "?") < 0)
2373 err
= gpg_error_from_syserror ();
2378 pi
= gcry_calloc_secure (2, sizeof (*pi
) + 100 + 1);
2381 err
= gpg_error_from_syserror ();
2384 pi2
= pi
+ (sizeof *pi
+ 100 + 1);
2385 pi
->max_length
= 100;
2387 pi2
->max_length
= 100;
2389 pi2
->check_cb
= reenter_compare_cb
;
2390 pi2
->check_cb_arg
= pi
->pin
;
2393 err
= agent_askpin (ctrl
, description
, NULL
, initial_errtext
, pi
);
2394 initial_errtext
= NULL
;
2398 /* Unless the passphrase is empty, ask to confirm it. */
2399 if (pi
->pin
&& *pi
->pin
)
2401 err
= agent_askpin (ctrl
, description2
, NULL
, NULL
, pi2
);
2403 { /* The re-entered one did not match and the user did not
2405 initial_errtext
= _("does not match - try again");
2410 err
= ssh_key_to_protected_buffer (key
, pi
->pin
, &buffer
, &buffer_n
);
2414 /* Store this key to our key storage. */
2415 err
= agent_write_private_key (key_grip_raw
, buffer
, buffer_n
, 0);
2419 /* Cache this passphrase. */
2420 for (i
= 0; i
< 20; i
++)
2421 sprintf (key_grip
+ 2 * i
, "%02X", key_grip_raw
[i
]);
2423 err
= agent_put_cache (key_grip
, CACHE_MODE_SSH
, pi
->pin
, ttl
);
2427 /* And add an entry to the sshcontrol file. */
2428 err
= add_control_entry (ctrl
, key_grip
, ttl
);
2432 if (pi
&& pi
->max_length
)
2433 wipememory (pi
->pin
, pi
->max_length
);
2437 xfree (description
);
2443 /* This function removes the key contained in the S-Expression KEY
2444 from the local key storage, in case it exists there. Returns usual
2445 error code. FIXME: this function is a stub. */
2447 ssh_identity_drop (gcry_sexp_t key
)
2449 unsigned char key_grip
[21] = { 0 };
2452 err
= ssh_key_grip (key
, key_grip
);
2456 key_grip
[sizeof (key_grip
) - 1] = 0;
2458 /* FIXME: What to do here - forgetting the passphrase or deleting
2459 the key from key cache? */
2466 /* Handler for the "add_identity" command. */
2468 ssh_handler_add_identity (ctrl_t ctrl
, estream_t request
, estream_t response
)
2470 gpg_error_t ret_err
;
2482 err
= ssh_receive_key (request
, &key
, 1, 1, NULL
);
2488 err
= stream_read_byte (request
, &b
);
2489 if (gpg_err_code (err
) == GPG_ERR_EOF
)
2497 case SSH_OPT_CONSTRAIN_LIFETIME
:
2501 err
= stream_read_uint32 (request
, &n
);
2507 case SSH_OPT_CONSTRAIN_CONFIRM
:
2514 /* FIXME: log/bad? */
2521 /* FIXME: are constraints used correctly? */
2523 err
= ssh_identity_register (ctrl
, key
, ttl
);
2527 gcry_sexp_release (key
);
2530 ret_err
= stream_write_byte (response
, SSH_RESPONSE_SUCCESS
);
2532 ret_err
= stream_write_byte (response
, SSH_RESPONSE_FAILURE
);
2537 /* Handler for the "remove_identity" command. */
2539 ssh_handler_remove_identity (ctrl_t ctrl
,
2540 estream_t request
, estream_t response
)
2542 unsigned char *key_blob
;
2545 gpg_error_t ret_err
;
2555 err
= stream_read_string (request
, 0, &key_blob
, &key_blob_size
);
2559 err
= ssh_read_key_public_from_blob (key_blob
, key_blob_size
, &key
, NULL
);
2563 err
= ssh_identity_drop (key
);
2568 gcry_sexp_release (key
);
2571 ret_err
= stream_write_byte (response
, SSH_RESPONSE_SUCCESS
);
2573 ret_err
= stream_write_byte (response
, SSH_RESPONSE_FAILURE
);
2578 /* FIXME: stub function. Actually useful? */
2580 ssh_identities_remove_all (void)
2586 /* FIXME: shall we remove _all_ cache entries or only those
2587 registered through the ssh emulation? */
2592 /* Handler for the "remove_all_identities" command. */
2594 ssh_handler_remove_all_identities (ctrl_t ctrl
,
2595 estream_t request
, estream_t response
)
2597 gpg_error_t ret_err
;
2603 err
= ssh_identities_remove_all ();
2606 ret_err
= stream_write_byte (response
, SSH_RESPONSE_SUCCESS
);
2608 ret_err
= stream_write_byte (response
, SSH_RESPONSE_FAILURE
);
2613 /* Lock agent? FIXME: stub function. */
2620 log_error ("ssh-agent's lock command is not implemented\n");
2626 /* Unock agent? FIXME: stub function. */
2632 log_error ("ssh-agent's unlock command is not implemented\n");
2638 /* Handler for the "lock" command. */
2640 ssh_handler_lock (ctrl_t ctrl
, estream_t request
, estream_t response
)
2642 gpg_error_t ret_err
;
2651 ret_err
= stream_write_byte (response
, SSH_RESPONSE_SUCCESS
);
2653 ret_err
= stream_write_byte (response
, SSH_RESPONSE_FAILURE
);
2658 /* Handler for the "unlock" command. */
2660 ssh_handler_unlock (ctrl_t ctrl
, estream_t request
, estream_t response
)
2662 gpg_error_t ret_err
;
2668 err
= ssh_unlock ();
2671 ret_err
= stream_write_byte (response
, SSH_RESPONSE_SUCCESS
);
2673 ret_err
= stream_write_byte (response
, SSH_RESPONSE_FAILURE
);
2680 /* Return the request specification for the request identified by TYPE
2681 or NULL in case the requested request specification could not be
2683 static ssh_request_spec_t
*
2684 request_spec_lookup (int type
)
2686 ssh_request_spec_t
*spec
;
2689 for (i
= 0; i
< DIM (request_specs
); i
++)
2690 if (request_specs
[i
].type
== type
)
2692 if (i
== DIM (request_specs
))
2695 log_info ("ssh request %u is not supported\n", type
);
2699 spec
= request_specs
+ i
;
2704 /* Process a single request. The request is read from and the
2705 response is written to STREAM_SOCK. Uses CTRL as context. Returns
2706 zero in case of success, non zero in case of failure. */
2708 ssh_request_process (ctrl_t ctrl
, estream_t stream_sock
)
2710 ssh_request_spec_t
*spec
;
2713 unsigned char request_type
;
2717 unsigned char *request_data
;
2718 u32 request_data_size
;
2721 request_data
= NULL
;
2726 /* Create memory streams for request/response data. The entire
2727 request will be stored in secure memory, since it might contain
2728 secret key material. The response does not have to be stored in
2729 secure memory, since we never give out secret keys.
2731 Note: we only have little secure memory, but there is NO
2732 possibility of DoS here; only trusted clients are allowed to
2733 connect to the agent. What could happen is that the agent
2734 returns out-of-secure-memory errors on requests in case the
2735 agent's owner floods his own agent with many large messages.
2738 /* Retrieve request. */
2739 err
= stream_read_string (stream_sock
, 1, &request_data
, &request_data_size
);
2743 if (opt
.verbose
> 1)
2744 log_info ("received ssh request of length %u\n",
2745 (unsigned int)request_data_size
);
2747 if (! request_data_size
)
2751 /* Broken request; FIXME. */
2754 request_type
= request_data
[0];
2755 spec
= request_spec_lookup (request_type
);
2760 /* Unknown request; FIXME. */
2763 if (spec
->secret_input
)
2764 request
= es_mopen (NULL
, 0, 0, 1, realloc_secure
, gcry_free
, "r+");
2766 request
= es_mopen (NULL
, 0, 0, 1, gcry_realloc
, gcry_free
, "r+");
2769 err
= gpg_error_from_syserror ();
2772 ret
= es_setvbuf (request
, NULL
, _IONBF
, 0);
2775 err
= gpg_error_from_syserror ();
2778 err
= stream_write_data (request
, request_data
+ 1, request_data_size
- 1);
2781 es_rewind (request
);
2783 response
= es_mopen (NULL
, 0, 0, 1, NULL
, NULL
, "r+");
2786 err
= gpg_error_from_syserror ();
2791 log_info ("ssh request handler for %s (%u) started\n",
2792 spec
->identifier
, spec
->type
);
2794 err
= (*spec
->handler
) (ctrl
, request
, response
);
2799 log_info ("ssh request handler for %s (%u) failed: %s\n",
2800 spec
->identifier
, spec
->type
, gpg_strerror (err
));
2802 log_info ("ssh request handler for %s (%u) ready\n",
2803 spec
->identifier
, spec
->type
);
2812 response_size
= es_ftell (response
);
2813 if (opt
.verbose
> 1)
2814 log_info ("sending ssh response of length %u\n",
2815 (unsigned int)response_size
);
2817 err
= es_fseek (response
, 0, SEEK_SET
);
2824 err
= stream_write_uint32 (stream_sock
, response_size
);
2831 err
= stream_copy (stream_sock
, response
);
2835 err
= es_fflush (stream_sock
);
2841 if (err
&& es_feof (stream_sock
))
2842 log_error ("error occured while processing request: %s\n",
2843 gpg_strerror (err
));
2847 if (opt
.verbose
> 1)
2848 log_info ("sending ssh error response\n");
2849 err
= stream_write_uint32 (stream_sock
, 1);
2852 err
= stream_write_byte (stream_sock
, SSH_RESPONSE_FAILURE
);
2860 es_fclose (request
);
2862 es_fclose (response
);
2863 xfree (request_data
); /* FIXME? */
2868 /* Start serving client on SOCK_CLIENT. */
2870 start_command_handler_ssh (ctrl_t ctrl
, gnupg_fd_t sock_client
)
2872 estream_t stream_sock
;
2876 /* Because the ssh protocol does not send us information about the
2877 the current TTY setting, we resort here to use those from startup
2878 or those explictly set. */
2879 if (!ctrl
->display
&& opt
.startup_display
)
2880 ctrl
->display
= strdup (opt
.startup_display
);
2881 if (!ctrl
->ttyname
&& opt
.startup_ttyname
)
2882 ctrl
->ttyname
= strdup (opt
.startup_ttyname
);
2883 if (!ctrl
->ttytype
&& opt
.startup_ttytype
)
2884 ctrl
->ttytype
= strdup (opt
.startup_ttytype
);
2885 if (!ctrl
->lc_ctype
&& opt
.startup_lc_ctype
)
2886 ctrl
->lc_ctype
= strdup (opt
.startup_lc_ctype
);
2887 if (!ctrl
->lc_messages
&& opt
.startup_lc_messages
)
2888 ctrl
->lc_messages
= strdup (opt
.startup_lc_messages
);
2889 if (!ctrl
->xauthority
&& opt
.startup_xauthority
)
2890 ctrl
->xauthority
= strdup (opt
.startup_xauthority
);
2891 if (!ctrl
->pinentry_user_data
&& opt
.startup_pinentry_user_data
)
2892 ctrl
->pinentry_user_data
= strdup (opt
.startup_pinentry_user_data
);
2895 /* Create stream from socket. */
2896 stream_sock
= es_fdopen (FD2INT(sock_client
), "r+");
2899 err
= gpg_error_from_syserror ();
2900 log_error (_("failed to create stream from socket: %s\n"),
2901 gpg_strerror (err
));
2904 /* We have to disable the estream buffering, because the estream
2905 core doesn't know about secure memory. */
2906 ret
= es_setvbuf (stream_sock
, NULL
, _IONBF
, 0);
2909 err
= gpg_error_from_syserror ();
2910 log_error ("failed to disable buffering "
2911 "on socket stream: %s\n", gpg_strerror (err
));
2915 /* Main processing loop. */
2916 while ( !ssh_request_process (ctrl
, stream_sock
) )
2918 /* Check wether we have reached EOF before trying to read
2922 c
= es_fgetc (stream_sock
);
2925 es_ungetc (c
, stream_sock
);
2928 /* Reset the SCD in case it has been used. */
2929 agent_reset_scd (ctrl
);
2934 es_fclose (stream_sock
);