gpg-agent: SSH certificate support
NIIBE Yutaka
gniibe at fsij.org
Fri Aug 5 10:48:34 CEST 2016
Hello,
I'm considering adding the support of SSH certificate to gpg-agent.
Looking the code of ssh_handler_request_identities, I cleaned up the
code a bit. Please find a change to limit access to file by
findkey.c.
The idea is extending the function agent_public_key_from_file.
From:
agent_public_key_from_file (ctrl, grip, &key_public)
to:
agent_public_key_from_file (ctrl, grip, &key_public, 1)
Last argument is allowing SSH certificate.
The function read_key_file will be also extended.
From:
read_key_file (const unsigned char *grip, gcry_sexp_t *result)
to:
read_key_file (const unsigned char *grip, gcry_sexp_t *result, int *ssh)
When SSH is not NULL, it means allowing returning SSH certificate.
If the file <KEYGRIP>.key is in Extended Private Key Format and has
OpenSSH-cert field, it will be set as *ssh = 1, and the sexp of RESULT
will be in following format:
(OpenSSH-cert(blob <BLOB of the certificate in binary>))
When SSH is NULL or the file <KEYGRIP>.key is not in Extended Private
Key Format, or it doesn't have OpenSSH-cert field, public key will be
in the format:
(public-key(<ALGO>(...)))
How about that?
Anyway, here is a clean up part.
diff --git a/agent/command-ssh.c b/agent/command-ssh.c
index 48f1b3d..583b4c7 100644
--- a/agent/command-ssh.c
+++ b/agent/command-ssh.c
@@ -814,67 +814,6 @@ stream_copy (estream_t dst, estream_t src)
return err;
}
-
-
-/* Read the content of the file specified by FILENAME into a newly
- create buffer, which is to be stored in BUFFER; store length of
- buffer in BUFFER_N. */
-static gpg_error_t
-file_to_buffer (const char *filename, unsigned char **buffer, size_t
*buffer_n)
-{
- unsigned char *buffer_new;
- struct stat statbuf;
- estream_t stream;
- gpg_error_t err;
- int ret;
-
- *buffer = NULL;
- *buffer_n = 0;
-
- buffer_new = NULL;
- err = 0;
-
- stream = es_fopen (filename, "rb");
- if (! stream)
- {
- err = gpg_error_from_syserror ();
- goto out;
- }
-
- ret = fstat (es_fileno (stream), &statbuf);
- if (ret)
- {
- err = gpg_error_from_syserror ();
- goto out;
- }
-
- buffer_new = xtrymalloc (statbuf.st_size);
- if (! buffer_new)
- {
- err = gpg_error_from_syserror ();
- goto out;
- }
-
- err = stream_read_data (stream, buffer_new, statbuf.st_size);
- if (err)
- goto out;
-
- *buffer = buffer_new;
- *buffer_n = statbuf.st_size;
-
- out:
-
- if (stream)
- es_fclose (stream);
-
- if (err)
- xfree (buffer_new);
-
- return err;
-}
-
-
-
/* Open the ssh control file and create it if not available. With
APPEND passed as true the file will be opened in append mode,
@@ -2683,12 +2622,8 @@ static gpg_error_t
ssh_handler_request_identities (ctrl_t ctrl,
estream_t request, estream_t response)
{
- ssh_key_type_spec_t spec;
- char *key_fname = NULL;
- char *fnameptr;
u32 key_counter;
estream_t key_blobs;
- gcry_sexp_t key_secret;
gcry_sexp_t key_public;
gpg_error_t err;
int ret;
@@ -2700,7 +2635,6 @@ ssh_handler_request_identities (ctrl_t ctrl,
/* Prepare buffer stream. */
- key_secret = NULL;
key_public = NULL;
key_counter = 0;
err = 0;
@@ -2729,29 +2663,6 @@ ssh_handler_request_identities (ctrl_t ctrl,
key_counter++;
}
-
- /* Prepare buffer for key name construction. */
- {
- char *dname;
-
- dname = make_filename (gnupg_homedir (), GNUPG_PRIVATE_KEYS_DIR, NULL);
- if (!dname)
- {
- err = gpg_err_code_from_syserror ();
- goto out;
- }
-
- key_fname = xtrymalloc (strlen (dname) + 1 + 40 + 4 + 1);
- if (!key_fname)
- {
- err = gpg_err_code_from_syserror ();
- xfree (dname);
- goto out;
- }
- fnameptr = stpcpy (stpcpy (key_fname, dname), "/");
- xfree (dname);
- }
-
/* Then look at all the registered and non-disabled keys. */
err = open_control_file (&cf, 0);
if (err)
@@ -2759,52 +2670,27 @@ ssh_handler_request_identities (ctrl_t ctrl,
while (!read_control_file_item (cf))
{
+ unsigned char grip[20];
+
if (!cf->item.valid)
continue; /* Should not happen. */
if (cf->item.disabled)
continue;
assert (strlen (cf->item.hexgrip) == 40);
+ hex2bin (cf->item.hexgrip, grip, sizeof (grip));
- stpcpy (stpcpy (fnameptr, cf->item.hexgrip), ".key");
-
- /* Read file content. */
- {
- unsigned char *buffer;
- size_t buffer_n;
-
- err = file_to_buffer (key_fname, &buffer, &buffer_n);
- if (err)
- {
- log_error ("%s:%d: key '%s' skipped: %s\n",
- cf->fname, cf->lnr, cf->item.hexgrip,
- gpg_strerror (err));
- continue;
- }
-
- err = gcry_sexp_sscan (&key_secret, NULL, (char*)buffer, buffer_n);
- xfree (buffer);
- if (err)
- goto out;
- }
-
- {
- char *key_type = NULL;
-
- err = sexp_extract_identifier (key_secret, &key_type);
- if (err)
- goto out;
-
- err = ssh_key_type_lookup (NULL, key_type, &spec);
- xfree (key_type);
- if (err)
+ err = agent_public_key_from_file (ctrl, grip, &key_public);
+ if (err)
+ {
+ log_error ("failed to read the public key\n");
goto out;
- }
+ }
- err = ssh_send_key_public (key_blobs, key_secret, NULL);
+ err = ssh_send_key_public (key_blobs, key_public, NULL);
if (err)
goto out;
- gcry_sexp_release (key_secret);
- key_secret = NULL;
+ gcry_sexp_release (key_public);
+ key_public = NULL;
key_counter++;
}
@@ -2820,7 +2706,6 @@ ssh_handler_request_identities (ctrl_t ctrl,
out:
/* Send response. */
- gcry_sexp_release (key_secret);
gcry_sexp_release (key_public);
if (!err)
@@ -2838,7 +2723,6 @@ ssh_handler_request_identities (ctrl_t ctrl,
es_fclose (key_blobs);
close_control_file (cf);
- xfree (key_fname);
return ret_err;
}
--
More information about the Gnupg-devel
mailing list