1
0
mirror of git://git.gnupg.org/gnupg.git synced 2025-05-14 08:13:25 +02:00

agent: Support the use case of composite PQC for prompting.

* agent/findkey.c (agent_key_from_file): Take care of the case
where GRIP==CTRL->keygrip1.
* agent/pkdecrypt.c (composite_pgp_kem_decrypt): Use NULL for the
GRIP, it's for crypto operation where prompt is expected.

--

GnuPG-bug-id: 7648
Signed-off-by: NIIBE Yutaka <gniibe@fsij.org>
This commit is contained in:
NIIBE Yutaka 2025-05-14 11:41:31 +09:00
parent d5a4a2dc89
commit 45a11327f3
No known key found for this signature in database
GPG Key ID: 640114AF89DE6054
2 changed files with 35 additions and 27 deletions

View File

@ -1345,22 +1345,23 @@ prompt_for_card (ctrl_t ctrl, const unsigned char *grip,
/* Return the secret key as an S-Exp in RESULT after locating it using /* Return the secret key as an S-Exp in RESULT after locating it using
the GRIP. Caller should set GRIP=NULL, when a key in a file is the GRIP. Caller should set GRIP=NULL, when a key in a file is
intended to be used for cryptographic operation. In this case, intended to be used for cryptographic operation (except the case of
CTRL->keygrip is used to locate the file, and it may ask a user for GRIP==CTRL->keygrip1 for PQC). When GRIP==NULL, CTRL->keygrip is
confirmation. If the operation shall be diverted to a token, an used to locate the file. When GRIP==NULL or GRIP==CTRL->keygrip1,
allocated S-expression with the shadow_info part from the file is it may ask a user for confirmation. If the operation shall be
stored at SHADOW_INFO; if not NULL will be stored at SHADOW_INFO. diverted to a token, an allocated S-expression with the shadow_info
CACHE_MODE defines now the cache shall be used. DESC_TEXT may be part from the file is stored at SHADOW_INFO; if not NULL will be
set to present a custom description for the pinentry. LOOKUP_TTL stored at SHADOW_INFO. CACHE_MODE defines now the cache shall be
is an optional function to convey a TTL to the cache manager; we do used. DESC_TEXT may be set to present a custom description for the
not simply pass the TTL value because the value is only needed if pinentry. LOOKUP_TTL is an optional function to convey a TTL to
an unprotect action was needed and looking up the TTL may have some the cache manager; we do not simply pass the TTL value because the
overhead (e.g. scanning the sshcontrol file). If a CACHE_NONCE is value is only needed if an unprotect action was needed and looking
given that cache item is first tried to get a passphrase. If up the TTL may have some overhead (e.g. scanning the sshcontrol
R_PASSPHRASE is not NULL, the function succeeded and the key was file). If a CACHE_NONCE is given that cache item is first tried to
protected the used passphrase (entered or from the cache) is stored get a passphrase. If R_PASSPHRASE is not NULL, the function
there; if not NULL will be stored. The caller needs to free the succeeded and the key was protected the used passphrase (entered or
returned passphrase. */ from the cache) is stored there; if not NULL will be stored. The
caller needs to free the returned passphrase. */
gpg_error_t gpg_error_t
agent_key_from_file (ctrl_t ctrl, const char *cache_nonce, agent_key_from_file (ctrl_t ctrl, const char *cache_nonce,
const char *desc_text, const char *desc_text,
@ -1375,6 +1376,7 @@ agent_key_from_file (ctrl_t ctrl, const char *cache_nonce,
gcry_sexp_t s_skey; gcry_sexp_t s_skey;
nvc_t keymeta = NULL; nvc_t keymeta = NULL;
char *desc_text_buffer = NULL; /* Used in case we extend DESC_TEXT. */ char *desc_text_buffer = NULL; /* Used in case we extend DESC_TEXT. */
int for_crypto_operation = 0;
*result = NULL; *result = NULL;
if (shadow_info) if (shadow_info)
@ -1384,11 +1386,18 @@ agent_key_from_file (ctrl_t ctrl, const char *cache_nonce,
if (r_timestamp) if (r_timestamp)
*r_timestamp = (time_t)(-1); *r_timestamp = (time_t)(-1);
if (!grip && !ctrl->have_keygrip) if (!grip)
return gpg_error (GPG_ERR_NO_SECKEY); {
if (!ctrl->have_keygrip)
return gpg_error (GPG_ERR_NO_SECKEY);
for_crypto_operation = 1;
grip = ctrl->keygrip;
}
else if (grip == ctrl->keygrip1)
/* This is the use case for composite PQC, */
for_crypto_operation = 1;
err = read_key_file (ctrl, grip? grip : ctrl->keygrip, err = read_key_file (ctrl, grip, &s_skey, &keymeta, NULL);
&s_skey, &keymeta, NULL);
if (err) if (err)
{ {
if (gpg_err_code (err) == GPG_ERR_ENOENT) if (gpg_err_code (err) == GPG_ERR_ENOENT)
@ -1418,7 +1427,7 @@ agent_key_from_file (ctrl_t ctrl, const char *cache_nonce,
*r_timestamp = isotime2epoch (created); *r_timestamp = isotime2epoch (created);
} }
if (!grip && keymeta) if (for_crypto_operation && keymeta)
{ {
const char *ask_confirmation = nvc_get_string (keymeta, "Confirm:"); const char *ask_confirmation = nvc_get_string (keymeta, "Confirm:");
@ -1520,8 +1529,7 @@ agent_key_from_file (ctrl_t ctrl, const char *cache_nonce,
if (!err) if (!err)
{ {
err = unprotect (ctrl, cache_nonce, desc_text_final, &buf, err = unprotect (ctrl, cache_nonce, desc_text_final, &buf, grip,
grip? grip : ctrl->keygrip,
cache_mode, lookup_ttl, r_passphrase); cache_mode, lookup_ttl, r_passphrase);
if (err) if (err)
log_error ("failed to unprotect the secret key: %s\n", log_error ("failed to unprotect the secret key: %s\n",
@ -1556,9 +1564,9 @@ agent_key_from_file (ctrl_t ctrl, const char *cache_nonce,
* When it's a key on card (not on tpm2), make sure * When it's a key on card (not on tpm2), make sure
* it's available. * it's available.
*/ */
if (strcmp (shadow_type, "t1-v1") == 0 && !grip) if (strcmp (shadow_type, "t1-v1") == 0
err = prompt_for_card (ctrl, ctrl->keygrip, && for_crypto_operation)
keymeta, *shadow_info); err = prompt_for_card (ctrl, grip, keymeta, *shadow_info);
} }
} }
else else

View File

@ -583,7 +583,7 @@ composite_pgp_kem_decrypt (ctrl_t ctrl, const char *desc_text,
gcry_buffer_t fixed_info = { 0, 0, 0, NULL }; gcry_buffer_t fixed_info = { 0, 0, 0, NULL };
err = agent_key_from_file (ctrl, NULL, desc_text, err = agent_key_from_file (ctrl, NULL, desc_text,
ctrl->keygrip, &shadow_info0, NULL, &shadow_info0,
CACHE_MODE_NORMAL, NULL, &s_skey0, NULL, NULL); CACHE_MODE_NORMAL, NULL, &s_skey0, NULL, NULL);
if (err && gpg_err_code (err) != GPG_ERR_NO_SECKEY) if (err && gpg_err_code (err) != GPG_ERR_NO_SECKEY)
{ {