scd:p15: Allow to use an auth object label with cmd CHECKPIN.

* scd/app-p15.c (prepare_verify_pin): Allow for PRKDF to be NULL.
(make_pin_prompt): Ditto.
(verify_pin): Ditto.
(do_check_pin): Allow using the Label to specify a PIN.
--

Note that a label may not work in all cases because we can't select
the protected object's EF first.

Signed-off-by: Werner Koch <wk@gnupg.org>
This commit is contained in:
Werner Koch 2021-03-18 16:30:10 +01:00
parent 1ac189f2df
commit 85082a83c2
No known key found for this signature in database
GPG Key ID: E3FDFF218E45B72B
2 changed files with 46 additions and 21 deletions

View File

@ -4438,7 +4438,7 @@ prepare_verify_pin (app_t app, const char *keyref,
log_error ("p15: error selecting D-TRUST's AID for key %s: %s\n",
keyref, gpg_strerror (err));
}
else
else if (prkdf)
{
/* Standard case: Select the key file. Note that this may
* change the security environment thus we need to do it before
@ -4448,6 +4448,11 @@ prepare_verify_pin (app_t app, const char *keyref,
log_error ("p15: error selecting file for key %s: %s\n",
keyref, gpg_strerror (err));
}
else
{
log_info ("p15: skipping EF selection for auth object '%s'\n", keyref);
err = 0;
}
return err;
}
@ -4489,8 +4494,8 @@ get_dispserialno (app_t app, prkdf_object_t prkdf)
}
/* Return an allocated string to be used as prompt. Returns NULL on
* malloc error. */
/* Return an allocated string to be used as prompt. PRKDF may be
* NULL. Returns NULL on malloc error. */
static char *
make_pin_prompt (app_t app, int remaining, const char *firstline,
prkdf_object_t prkdf)
@ -4508,7 +4513,7 @@ make_pin_prompt (app_t app, int remaining, const char *firstline,
"%s"),
"\x1e",
serial,
prkdf->common_name? prkdf->common_name: "",
prkdf && prkdf->common_name? prkdf->common_name: "",
"");
xfree (serial);
if (!result)
@ -4580,22 +4585,23 @@ verify_pin (app_t app,
if (remaining >= 0)
log_info ("p15: PIN has %d attempts left\n", remaining);
/* On error or if less than 3 better ask. */
prkdf->pin_verified = 0;
if (prkdf)
prkdf->pin_verified = 0;
}
}
else
remaining = -1; /* Unknown. */
/* Check whether we already verified it. */
if (prkdf->pin_verified)
if (prkdf && prkdf->pin_verified)
return 0; /* Already done. */
if (prkdf->usageflags.non_repudiation
if (prkdf
&& prkdf->usageflags.non_repudiation
&& (app->app_local->card_type == CARD_TYPE_BELPIC
|| app->app_local->card_product == CARD_PRODUCT_DTRUST))
label = _("||Please enter the PIN for the key to create "
"qualified signatures.");
else if (aodf->pinflags.so_pin)
label = _("|A|Please enter the Admin PIN");
else if (aodf->pinflags.unblocking_pin)
@ -4751,7 +4757,8 @@ verify_pin (app_t app,
}
if (opt.verbose)
log_info ("p15: PIN verification succeeded\n");
prkdf->pin_verified = 1;
if (prkdf)
prkdf->pin_verified = 1;
return 0;
}
@ -5189,21 +5196,35 @@ do_check_pin (app_t app, ctrl_t ctrl, const char *keyidstr,
return gpg_error (GPG_ERR_INV_VALUE);
err = prkdf_object_from_keyidstr (app, keyidstr, &prkdf);
if (err)
if (err
&& gpg_err_code (err) != GPG_ERR_INV_ID
&& gpg_err_code (err) != GPG_ERR_NOT_FOUND)
return err;
/* Find the authentication object to this private key object. */
if (!prkdf->authid)
if (err) /* Not found or invalid - assume it is the label. */
{
log_error ("p15: no authentication object defined for %s\n", keyidstr);
return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION);
prkdf = NULL;
for (aodf = app->app_local->auth_object_info; aodf; aodf = aodf->next)
if (aodf->label && !ascii_strcasecmp (aodf->label, keyidstr))
break;
if (!aodf)
return err; /* Re-use the original error code. */
}
else /* Find the authentication object to this private key object. */
{
if (!prkdf->authid)
{
log_error ("p15: no authentication object defined for %s\n",
keyidstr);
return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION);
}
for (aodf = app->app_local->auth_object_info; aodf; aodf = aodf->next)
if (aodf->objidlen == prkdf->authidlen
&& !memcmp (aodf->objid, prkdf->authid, prkdf->authidlen))
break;
if (!aodf) /* None found. */
return gpg_error (GPG_ERR_NO_PIN);
}
for (aodf = app->app_local->auth_object_info; aodf; aodf = aodf->next)
if (aodf->objidlen == prkdf->authidlen
&& !memcmp (aodf->objid, prkdf->authid, prkdf->authidlen))
break;
if (!aodf) /* None found. */
return gpg_error (GPG_ERR_NO_PIN);
err = prepare_verify_pin (app, keyidstr, prkdf, aodf);
if (!err)

View File

@ -1590,7 +1590,11 @@ static const char hlp_checkpin[] =
" For a definitive list, see the implementation in app-nks.c.\n"
" Note that we call a PW2.* PIN a \"PUK\" despite that since TCOS\n"
" 3.0 they are technically alternative PINs used to mutally\n"
" unblock each other.";
" unblock each other.\n"
"\n"
"For PKCS#15:\n"
"\n"
" The key's ID string or the PIN's label may be used.";
static gpg_error_t
cmd_checkpin (assuan_context_t ctx, char *line)
{