diff options
Diffstat (limited to 'agent')
-rw-r--r-- | agent/command-ssh.c | 18 | ||||
-rw-r--r-- | agent/command.c | 67 | ||||
-rw-r--r-- | agent/keyformat.txt | 8 |
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 |