aboutsummaryrefslogtreecommitdiffstats
path: root/agent
diff options
context:
space:
mode:
Diffstat (limited to 'agent')
-rw-r--r--agent/command-ssh.c18
-rw-r--r--agent/command.c67
-rw-r--r--agent/keyformat.txt8
3 files changed, 79 insertions, 14 deletions
diff --git a/agent/command-ssh.c b/agent/command-ssh.c
index b41177be6..51111a60d 100644
--- a/agent/command-ssh.c
+++ b/agent/command-ssh.c
@@ -2648,7 +2648,8 @@ ssh_send_available_keys (ctrl_t ctrl, estream_t key_blobs, u32 *r_key_counter)
/* Clamp LNR value and set the ordinal.
* Current use of ordinals:
- * 1..99999 - inserted cards (right now only 1)
+ * 1..999 - low value Use-for-ssh.
+ * 1000..99999 - inserted cards (right now only 1000)
* 100000..199999 - listed in sshcontrol
* 200000..299999 - order taken from Use-for-ssh
*/
@@ -2678,18 +2679,25 @@ ssh_send_available_keys (ctrl_t ctrl, estream_t key_blobs, u32 *r_key_counter)
* order of card keys (which are sorted by their s/n), we
* would need to get the use-for-ssh: value from the stub
* file and set an appropriate ordinal. */
- order = 1;
+ order = 1000;
}
else if (is_ssh)
err = agent_public_key_from_file (ctrl, grip, &key_public);
else /* Examine the file if it's suitable for SSH. */
{
err = agent_ssh_key_from_file (ctrl, grip, &key_public, &order);
- if (order < 0 || err)
+ if (err)
order = 0;
+ else if (order < 0)
+ {
+ order = -order;
+ if (order > 999)
+ order = 999;
+ }
else if (order > 99999)
- order = 99999;
- order += 200000;
+ order = 299999;
+ else
+ order += 200000;
}
if (err)
{
diff --git a/agent/command.c b/agent/command.c
index 9481f47c3..dd7cb5e57 100644
--- a/agent/command.c
+++ b/agent/command.c
@@ -3175,9 +3175,10 @@ cmd_delete_key (assuan_context_t ctx, char *line)
#endif
static const char hlp_keytocard[] =
- "KEYTOCARD [--force] <hexgrip> <serialno> <keyref> [<timestamp>]\n"
+ "KEYTOCARD [--force] <hexgrip> <serialno> <keyref> [<timestamp> [<ecdh>]]\n"
"\n"
- "TIMESTAMP is required for OpenPGP and defaults to the Epoch. The\n"
+ "TIMESTAMP is required for OpenPGP and defaults to the Epoch.\n"
+ "ECDH are the hexified ECDH parameters for OpenPGP.\n"
"SERIALNO is used for checking; use \"-\" to disable the check.";
static gpg_error_t
cmd_keytocard (assuan_context_t ctx, char *line)
@@ -3194,6 +3195,9 @@ cmd_keytocard (assuan_context_t ctx, char *line)
size_t keydatalen;
unsigned char *shadow_info = NULL;
time_t timestamp;
+ char *ecdh_params = NULL;
+ unsigned int ecdh_params_len;
+ unsigned int extralen1, extralen2;
if (ctrl->restricted)
return leave_cmd (ctx, gpg_error (GPG_ERR_FORBIDDEN));
@@ -3240,10 +3244,38 @@ cmd_keytocard (assuan_context_t ctx, char *line)
/* Default to the creation time as stored in the private key. The
* parameter is here so that gpg can make sure that the timestamp as
- * used for key creation (and thus the openPGP fingerprint) is
- * used. */
+ * used. It is also important for OpenPGP cards to allow computing
+ * of the fingerprint. Same goes for the ECDH params. */
if (argc > 3)
- timestamp = isotime2epoch (argv[3]);
+ {
+ timestamp = isotime2epoch (argv[3]);
+ if (argc > 4)
+ {
+ size_t n;
+
+ err = parse_hexstring (ctx, argv[4], &n);
+ if (err)
+ goto leave; /* Badly formatted ecdh params. */
+ n /= 2;
+ if (n < 4)
+ {
+ err = set_error (GPG_ERR_ASS_PARAMETER, "ecdh param too short");
+ goto leave;
+ }
+ ecdh_params_len = n;
+ ecdh_params = xtrymalloc (ecdh_params_len);
+ if (!ecdh_params)
+ {
+ err = gpg_error_from_syserror ();
+ goto leave;
+ }
+ if (hex2bin (argv[4], ecdh_params, ecdh_params_len) < 0)
+ {
+ err = set_error (GPG_ERR_BUG, "hex2bin");
+ goto leave;
+ }
+ }
+ }
else if (timestamp == (time_t)(-1))
timestamp = isotime2epoch ("19700101T000000");
@@ -3254,9 +3286,12 @@ cmd_keytocard (assuan_context_t ctx, char *line)
}
/* Note: We can't use make_canon_sexp because we need to allocate a
- * few extra bytes for our hack below. */
+ * few extra bytes for our hack below. The 20 for extralen2
+ * accounts for the sexp length of ecdh_params. */
keydatalen = gcry_sexp_sprint (s_skey, GCRYSEXP_FMT_CANON, NULL, 0);
- keydata = xtrymalloc_secure (keydatalen + 30);
+ extralen1 = 30;
+ extralen2 = ecdh_params? (20+20+ecdh_params_len) : 0;
+ keydata = xtrymalloc_secure (keydatalen + extralen1 + extralen2);
if (keydata == NULL)
{
err = gpg_error_from_syserror ();
@@ -3265,15 +3300,31 @@ cmd_keytocard (assuan_context_t ctx, char *line)
gcry_sexp_sprint (s_skey, GCRYSEXP_FMT_CANON, keydata, keydatalen);
gcry_sexp_release (s_skey);
s_skey = NULL;
+
keydatalen--; /* Decrement for last '\0'. */
+
/* Hack to insert the timestamp "created-at" into the private key. */
- snprintf (keydata+keydatalen-1, 30, KEYTOCARD_TIMESTAMP_FORMAT, timestamp);
+ snprintf (keydata+keydatalen-1, extralen1, KEYTOCARD_TIMESTAMP_FORMAT,
+ timestamp);
keydatalen += 10 + 19 - 1;
+ /* Hack to insert the timestamp "ecdh-params" into the private key. */
+ if (ecdh_params)
+ {
+ snprintf (keydata+keydatalen-1, extralen2, "(11:ecdh-params%u:",
+ ecdh_params_len);
+ keydatalen += strlen (keydata+keydatalen-1) -1;
+ memcpy (keydata+keydatalen, ecdh_params, ecdh_params_len);
+ keydatalen += ecdh_params_len;
+ memcpy (keydata+keydatalen, "))", 3);
+ keydatalen += 2;
+ }
+
err = divert_writekey (ctrl, force, serialno, keyref, keydata, keydatalen);
xfree (keydata);
leave:
+ xfree (ecdh_params);
gcry_sexp_release (s_skey);
xfree (shadow_info);
return leave_cmd (ctx, err);
diff --git a/agent/keyformat.txt b/agent/keyformat.txt
index bbcaa7e2c..fbe999ca1 100644
--- a/agent/keyformat.txt
+++ b/agent/keyformat.txt
@@ -124,7 +124,13 @@ gpg-agent's ssh-agent implementation. This is thus the same as
putting the keygrip into the 'sshcontrol' file. Only one such item
should exist. If another non-zero value between 1 and 99999 is used,
this is taken to establish the order in which the keys are returned to
-ssh; lower numbers are returned first.
+ssh; lower numbers are returned first. If a negative value is used
+this overrides currently active (inserted) cards and thus allows to
+prefer on-disk keys over inserted cards. A value of -1 has the
+highest priority; values are capped at -999 and have a lower priority
+but still above the positive values, inserted cards or the order in
+sshcontrol.
+
*** Use-for-p11
If given and the value is "yes" or "1" the key is allowed for use by