mirror of
git://git.gnupg.org/gnupg.git
synced 2024-12-22 10:19:57 +01:00
scd:p15: Implement do_with_keygrip and capabilities.
* scd/app-p15.c (prepare_verify_pin): Allow use without an AODF. (verify_pin): Ditto. (do_with_keygrip): Implement capability restrictions. Signed-off-by: Werner Koch <wk@gnupg.org>
This commit is contained in:
parent
8149742ddf
commit
61c5b0767f
@ -3100,7 +3100,7 @@ micardo_mse (app_t app, unsigned short fid)
|
|||||||
|
|
||||||
/* Prepare the verification of the PIN for the key PRKDF by checking
|
/* Prepare the verification of the PIN for the key PRKDF by checking
|
||||||
* the AODF and selecting the key file. KEYREF is used for error
|
* the AODF and selecting the key file. KEYREF is used for error
|
||||||
* messages. */
|
* messages. AODF may be NULL if no verification needs to be done. */
|
||||||
static gpg_error_t
|
static gpg_error_t
|
||||||
prepare_verify_pin (app_t app, const char *keyref,
|
prepare_verify_pin (app_t app, const char *keyref,
|
||||||
prkdf_object_t prkdf, aodf_object_t aodf)
|
prkdf_object_t prkdf, aodf_object_t aodf)
|
||||||
@ -3108,29 +3108,32 @@ prepare_verify_pin (app_t app, const char *keyref,
|
|||||||
gpg_error_t err;
|
gpg_error_t err;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
if (opt.verbose)
|
if (aodf)
|
||||||
{
|
{
|
||||||
log_info ("p15: using AODF %04hX id=", aodf->fid);
|
if (opt.verbose)
|
||||||
for (i=0; i < aodf->objidlen; i++)
|
{
|
||||||
log_printf ("%02X", aodf->objid[i]);
|
log_info ("p15: using AODF %04hX id=", aodf->fid);
|
||||||
log_printf ("\n");
|
for (i=0; i < aodf->objidlen; i++)
|
||||||
}
|
log_printf ("%02X", aodf->objid[i]);
|
||||||
|
log_printf ("\n");
|
||||||
|
}
|
||||||
|
|
||||||
if (aodf->authid && opt.verbose)
|
if (aodf->authid && opt.verbose)
|
||||||
log_info ("p15: PIN is controlled by another authentication token\n");
|
log_info ("p15: PIN is controlled by another authentication token\n");
|
||||||
|
|
||||||
if (aodf->pinflags.integrity_protected
|
if (aodf->pinflags.integrity_protected
|
||||||
|| aodf->pinflags.confidentiality_protected)
|
|| aodf->pinflags.confidentiality_protected)
|
||||||
{
|
{
|
||||||
log_error ("p15: "
|
log_error ("p15: PIN verification requires"
|
||||||
"PIN verification requires unsupported protection method\n");
|
" unsupported protection method\n");
|
||||||
return gpg_error (GPG_ERR_BAD_PIN_METHOD);
|
return gpg_error (GPG_ERR_BAD_PIN_METHOD);
|
||||||
}
|
}
|
||||||
if (!aodf->stored_length && aodf->pinflags.needs_padding)
|
if (!aodf->stored_length && aodf->pinflags.needs_padding)
|
||||||
{
|
{
|
||||||
log_error ("p15: "
|
log_error ("p15: PIN verification requires"
|
||||||
"PIN verification requires padding but no length known\n");
|
" padding but no length known\n");
|
||||||
return gpg_error (GPG_ERR_INV_CARD);
|
return gpg_error (GPG_ERR_INV_CARD);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Select the key file. Note that this may change the security
|
/* Select the key file. Note that this may change the security
|
||||||
@ -3145,7 +3148,8 @@ prepare_verify_pin (app_t app, const char *keyref,
|
|||||||
|
|
||||||
|
|
||||||
/* Given the private key object PRKDF and its authentication object
|
/* Given the private key object PRKDF and its authentication object
|
||||||
* AODF ask for the PIN and verify that PIN. */
|
* AODF ask for the PIN and verify that PIN. IF AODF is NULL, no
|
||||||
|
* authentication is done. */
|
||||||
static gpg_error_t
|
static gpg_error_t
|
||||||
verify_pin (app_t app,
|
verify_pin (app_t app,
|
||||||
gpg_error_t (*pincb)(void*, const char *, char **), void *pincb_arg,
|
gpg_error_t (*pincb)(void*, const char *, char **), void *pincb_arg,
|
||||||
@ -3158,6 +3162,9 @@ verify_pin (app_t app,
|
|||||||
const char *s;
|
const char *s;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
if (!aodf)
|
||||||
|
return 0;
|
||||||
|
|
||||||
if (prkdf->pin_verified)
|
if (prkdf->pin_verified)
|
||||||
return 0; /* Already done. */
|
return 0; /* Already done. */
|
||||||
|
|
||||||
@ -3385,10 +3392,7 @@ do_sign (app_t app, ctrl_t ctrl, const char *keyidstr, int hashalgo,
|
|||||||
&& !memcmp (aodf->objid, prkdf->authid, prkdf->authidlen))
|
&& !memcmp (aodf->objid, prkdf->authid, prkdf->authidlen))
|
||||||
break;
|
break;
|
||||||
if (!aodf)
|
if (!aodf)
|
||||||
{
|
log_info ("p15: no authentication for %s needed\n", keyidstr);
|
||||||
log_error ("p15: authentication object for %s missing\n", keyidstr);
|
|
||||||
return gpg_error (GPG_ERR_INV_CARD);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* We need some more info about the key - get the keygrip to
|
/* We need some more info about the key - get the keygrip to
|
||||||
* populate these fields. */
|
* populate these fields. */
|
||||||
@ -3399,7 +3403,6 @@ do_sign (app_t app, ctrl_t ctrl, const char *keyidstr, int hashalgo,
|
|||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Prepare PIN verification. This is split so that we can do
|
/* Prepare PIN verification. This is split so that we can do
|
||||||
* MSE operation for some task after having selected the key file but
|
* MSE operation for some task after having selected the key file but
|
||||||
* before sending the verify APDU. */
|
* before sending the verify APDU. */
|
||||||
@ -3654,10 +3657,7 @@ do_decipher (app_t app, ctrl_t ctrl, const char *keyidstr,
|
|||||||
&& !memcmp (aodf->objid, prkdf->authid, prkdf->authidlen))
|
&& !memcmp (aodf->objid, prkdf->authid, prkdf->authidlen))
|
||||||
break;
|
break;
|
||||||
if (!aodf)
|
if (!aodf)
|
||||||
{
|
log_info ("p15: no authentication for %s needed\n", keyidstr);
|
||||||
log_error ("p15: authentication object for %s missing\n", keyidstr);
|
|
||||||
return gpg_error (GPG_ERR_INV_CARD);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* We need some more info about the key - get the keygrip to
|
/* We need some more info about the key - get the keygrip to
|
||||||
* populate these fields. */
|
* populate these fields. */
|
||||||
@ -3758,7 +3758,6 @@ do_with_keygrip (app_t app, ctrl_t ctrl, int action,
|
|||||||
for (prkdf = app->app_local->private_key_info;
|
for (prkdf = app->app_local->private_key_info;
|
||||||
prkdf; prkdf = prkdf->next)
|
prkdf; prkdf = prkdf->next)
|
||||||
{
|
{
|
||||||
|
|
||||||
if (keygrip_from_prkdf (app, prkdf))
|
if (keygrip_from_prkdf (app, prkdf))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
@ -3774,8 +3773,22 @@ do_with_keygrip (app_t app, ctrl_t ctrl, int action,
|
|||||||
{
|
{
|
||||||
char *keyref;
|
char *keyref;
|
||||||
|
|
||||||
/* FIXME: Consider ... */
|
if (capability == GCRY_PK_USAGE_SIGN)
|
||||||
(void)capability;
|
{
|
||||||
|
if (!(prkdf->usageflags.sign || prkdf->usageflags.sign_recover
|
||||||
|
|| prkdf->usageflags.non_repudiation))
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
else if (capability == GCRY_PK_USAGE_ENCR)
|
||||||
|
{
|
||||||
|
if (!(prkdf->usageflags.decrypt || prkdf->usageflags.unwrap))
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
else if (capability == GCRY_PK_USAGE_AUTH)
|
||||||
|
{
|
||||||
|
if (!(prkdf->usageflags.sign || prkdf->usageflags.sign_recover))
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
keyref = keyref_from_prkdf (app, prkdf);
|
keyref = keyref_from_prkdf (app, prkdf);
|
||||||
if (!keyref)
|
if (!keyref)
|
||||||
@ -3785,6 +3798,7 @@ do_with_keygrip (app_t app, ctrl_t ctrl, int action,
|
|||||||
}
|
}
|
||||||
|
|
||||||
send_keyinfo (ctrl, as_data, prkdf->keygrip, serialno, keyref);
|
send_keyinfo (ctrl, as_data, prkdf->keygrip, serialno, keyref);
|
||||||
|
xfree (keyref);
|
||||||
if (want_keygripstr)
|
if (want_keygripstr)
|
||||||
{
|
{
|
||||||
err = 0; /* Found */
|
err = 0; /* Found */
|
||||||
|
Loading…
x
Reference in New Issue
Block a user