From ac5a1a3ccb7c3e6393bc83d73b545dec9b70e7d1 Mon Sep 17 00:00:00 2001 From: NIIBE Yutaka Date: Tue, 4 Mar 2014 11:54:59 +0900 Subject: [PATCH] agent: API change of agent_key_from_file. * agent/findkey.c (agent_key_from_file): Always return S-expression. * agent/command.c (cmd_passwd): Distinguish by SHADOW_INFO. (cmd_export_key): Likewise. Free SHADOW_INFO. (cmd_keytocard): Likewise. Release S_SKEY. * agent/pkdecrypt.c (agent_pkdecrypt): Likewise. * agent/pksign.c (agent_pksign_do): Likewise. Use the S-expression to know the key type. Signed-off-by: NIIBE Yutaka --- agent/command.c | 32 ++++++++++++++++++++------------ agent/findkey.c | 10 ++++------ agent/pkdecrypt.c | 2 +- agent/pksign.c | 21 +++++---------------- 4 files changed, 30 insertions(+), 35 deletions(-) diff --git a/agent/command.c b/agent/command.c index 4fa40d9f9..d1e53cd44 100644 --- a/agent/command.c +++ b/agent/command.c @@ -1667,7 +1667,7 @@ cmd_passwd (assuan_context_t ctx, char *line) &s_skey, &passphrase); if (err) ; - else if (!s_skey) + else if (shadow_info) { log_error ("changing a smartcard PIN is not yet supported\n"); err = gpg_error (GPG_ERR_NOT_IMPLEMENTED); @@ -2126,6 +2126,7 @@ cmd_export_key (assuan_context_t ctx, char *line) int openpgp; char *cache_nonce; char *passphrase = NULL; + unsigned char *shadow_info = NULL; openpgp = has_option (line, "--openpgp"); cache_nonce = option_value (line, "--cache-nonce"); @@ -2163,15 +2164,13 @@ cmd_export_key (assuan_context_t ctx, char *line) /* Get the key from the file. With the openpgp flag we also ask for the passphrase so that we can use it to re-encrypt it. */ err = agent_key_from_file (ctrl, NULL, ctrl->server_local->keydesc, grip, - NULL, CACHE_MODE_IGNORE, NULL, &s_skey, + &shadow_info, CACHE_MODE_IGNORE, NULL, &s_skey, openpgp ? &passphrase : NULL); if (err) goto leave; - if (!s_skey) + if (shadow_info) { - /* Key is on a smartcard. Actually we should not see this here - because we do not pass a shadow_info variable to the above - function, thus it will return this error directly. */ + /* Key is on a smartcard. */ err = gpg_error (GPG_ERR_UNUSABLE_SECKEY); goto leave; } @@ -2241,6 +2240,7 @@ cmd_export_key (assuan_context_t ctx, char *line) gcry_sexp_release (s_skey); xfree (ctrl->server_local->keydesc); ctrl->server_local->keydesc = NULL; + xfree (shadow_info); return leave_cmd (ctx, err); } @@ -2260,7 +2260,7 @@ cmd_keytocard (assuan_context_t ctx, char *line) unsigned char *keydata; size_t keydatalen, timestamplen; const char *serialno, *timestamp_str, *id; - unsigned char *shadow_info; + unsigned char *shadow_info = NULL; unsigned char *shdkey; time_t timestamp; @@ -2305,12 +2305,20 @@ cmd_keytocard (assuan_context_t ctx, char *line) return gpg_error (GPG_ERR_INV_VALUE); err = agent_key_from_file (ctrl, NULL, ctrl->server_local->keydesc, grip, - NULL, CACHE_MODE_IGNORE, NULL, &s_skey, NULL); + &shadow_info, CACHE_MODE_IGNORE, NULL, + &s_skey, NULL); if (err) - return err; - if (!s_skey) - /* Key is on a smartcard already. */ - return gpg_error (GPG_ERR_UNUSABLE_SECKEY); + { + xfree (shadow_info); + return err; + } + if (shadow_info) + { + /* Key is on a smartcard already. */ + xfree (shadow_info); + gcry_sexp_release (s_skey); + return gpg_error (GPG_ERR_UNUSABLE_SECKEY); + } keydatalen = gcry_sexp_sprint (s_skey, GCRYSEXP_FMT_CANON, NULL, 0); keydata = xtrymalloc_secure (keydatalen + 30); diff --git a/agent/findkey.c b/agent/findkey.c index 6464b02ac..7b24c55ed 100644 --- a/agent/findkey.c +++ b/agent/findkey.c @@ -537,9 +537,9 @@ read_key_file (const unsigned char *grip, gcry_sexp_t *result) /* Return the secret key as an S-Exp in RESULT after locating it using - the GRIP. Stores NULL at RESULT if the operation shall be diverted - to a token; in this case an allocated S-expression with the - shadow_info part from the file is stored at SHADOW_INFO. + the GRIP. If the operation shall be diverted to a token, an + allocated S-expression with the shadow_info part from the file is + stored at SHADOW_INFO; if not NULL will be stored at SHADOW_INFO. CACHE_MODE defines now the cache shall be used. DESC_TEXT may be set to present a custom description for the pinentry. LOOKUP_TTL is an optional function to convey a TTL to the cache manager; we do @@ -562,7 +562,6 @@ agent_key_from_file (ctrl_t ctrl, const char *cache_nonce, unsigned char *buf; size_t len, buflen, erroff; gcry_sexp_t s_skey; - int got_shadow_info = 0; *result = NULL; if (shadow_info) @@ -638,7 +637,6 @@ agent_key_from_file (ctrl_t ctrl, const char *cache_nonce, { memcpy (*shadow_info, s, n); rc = 0; - got_shadow_info = 1; } } if (rc) @@ -654,7 +652,7 @@ agent_key_from_file (ctrl_t ctrl, const char *cache_nonce, } gcry_sexp_release (s_skey); s_skey = NULL; - if (rc || got_shadow_info) + if (rc) { xfree (buf); if (r_passphrase) diff --git a/agent/pkdecrypt.c b/agent/pkdecrypt.c index 9924d6dff..14aa78f75 100644 --- a/agent/pkdecrypt.c +++ b/agent/pkdecrypt.c @@ -79,7 +79,7 @@ agent_pkdecrypt (ctrl_t ctrl, const char *desc_text, goto leave; } - if (!s_skey) + if (shadow_info) { /* divert operation to the smartcard */ if (!gcry_sexp_canon_len (ciphertext, ciphertextlen, NULL, NULL)) diff --git a/agent/pksign.c b/agent/pksign.c index 4d0a240e9..088615011 100644 --- a/agent/pksign.c +++ b/agent/pksign.c @@ -299,31 +299,20 @@ agent_pksign_do (ctrl_t ctrl, const char *cache_nonce, goto leave; } - if (!s_skey) + if (shadow_info) { /* Divert operation to the smartcard */ - gcry_sexp_t s_pkey, l; - const char *name; size_t len; unsigned char *buf = NULL; + int key_type; int is_RSA = 0; int is_ECDSA = 0; - /* Check keytype by public key */ - rc = agent_public_key_from_file (ctrl, ctrl->keygrip, &s_pkey); - if (rc) - { - log_error ("failed to read the public key\n"); - goto leave; - } - l = gcry_sexp_cadr (s_pkey); - name = gcry_sexp_nth_data (l, 0, &len); - if (len == 3 && !memcmp (name, "rsa", 3)) + key_type = agent_is_dsa_key (s_skey); + if (key_type == 0) is_RSA = 1; - else if (len == 5 && !memcmp (name, "ecdsa", 5)) + else if (key_type == GCRY_PK_ECDSA) is_ECDSA = 1; - gcry_sexp_release (l); - gcry_sexp_release (s_pkey); rc = divert_pksign (ctrl, ctrl->digest.value,