1
0
mirror of git://git.gnupg.org/gnupg.git synced 2024-12-22 10:19:57 +01:00

scd:p15: Take derive usage into account for decryption.

* scd/app-p15.c (set_usage_string): Map usageflags.derive also to 'e'.
(do_auth): Allow usageflags.sign_recover.
(do_decipher): Allow usageflags.derive.
(do_with_keygrip): Take usageflags.derive into account.
(do_gettatr): Ditto.
(do_decipher): Take a missing AODF for authentication not needed.
--

This is required for D-Trust ECC cards.

The AODF thing is unrelated but seems to be a good idea.

GnuPG-bug-id: 7000
This commit is contained in:
Werner Koch 2024-02-20 09:15:25 +01:00
parent 2810b93464
commit ad4bc3e04d
No known key found for this signature in database
GPG Key ID: E3FDFF218E45B72B

View File

@ -305,7 +305,7 @@ struct prkdf_object_s
keyaccess_flags_t accessflags; keyaccess_flags_t accessflags;
/* Extended key usage flags. Only used if .valid is set. This /* Extended key usage flags. Only used if .valid is set. This
* information is computed from an associated certificate15. */ * information is computed from an associated certificate. */
struct { struct {
unsigned int valid:1; unsigned int valid:1;
unsigned int sign:1; unsigned int sign:1;
@ -4214,7 +4214,8 @@ set_usage_string (char usage[5], prkdf_object_t prkdf)
&& (!prkdf->extusage.valid || prkdf->extusage.sign)) && (!prkdf->extusage.valid || prkdf->extusage.sign))
usage[usagelen++] = 'c'; usage[usagelen++] = 'c';
if ((prkdf->usageflags.decrypt if ((prkdf->usageflags.decrypt
|| prkdf->usageflags.unwrap) || prkdf->usageflags.unwrap
|| prkdf->usageflags.derive)
&& (!prkdf->extusage.valid || prkdf->extusage.encr)) && (!prkdf->extusage.valid || prkdf->extusage.encr))
usage[usagelen++] = 'e'; usage[usagelen++] = 'e';
if ((prkdf->usageflags.sign if ((prkdf->usageflags.sign
@ -4683,7 +4684,8 @@ do_getattr (app_t app, ctrl_t ctrl, const char *name)
if ((name[1] == 'A' && (prkdf->usageflags.sign if ((name[1] == 'A' && (prkdf->usageflags.sign
|| prkdf->usageflags.sign_recover)) || prkdf->usageflags.sign_recover))
|| (name[1] == 'E' && (prkdf->usageflags.decrypt || (name[1] == 'E' && (prkdf->usageflags.decrypt
|| prkdf->usageflags.unwrap)) || prkdf->usageflags.unwrap
|| prkdf->usageflags.derive))
|| (name[1] == 'S' && (prkdf->usageflags.sign || (name[1] == 'S' && (prkdf->usageflags.sign
|| prkdf->usageflags.sign_recover))) || prkdf->usageflags.sign_recover)))
break; break;
@ -5927,7 +5929,8 @@ do_auth (app_t app, ctrl_t ctrl, const char *keyidstr,
err = prkdf_object_from_keyidstr (app, keyidstr, &prkdf); err = prkdf_object_from_keyidstr (app, keyidstr, &prkdf);
if (err) if (err)
return err; return err;
if (!(prkdf->usageflags.sign || prkdf->gpgusage.auth)) if (!(prkdf->usageflags.sign || prkdf->usageflags.sign_recover
|| prkdf->gpgusage.auth))
{ {
log_error ("p15: key %s may not be used for authentication\n", keyidstr); log_error ("p15: key %s may not be used for authentication\n", keyidstr);
return gpg_error (GPG_ERR_WRONG_KEY_USAGE); return gpg_error (GPG_ERR_WRONG_KEY_USAGE);
@ -5970,6 +5973,7 @@ do_decipher (app_t app, ctrl_t ctrl, const char *keyidstr,
return err; return err;
if (!(prkdf->usageflags.decrypt if (!(prkdf->usageflags.decrypt
|| prkdf->usageflags.unwrap || prkdf->usageflags.unwrap
|| prkdf->usageflags.derive
|| prkdf->gpgusage.encr )) || prkdf->gpgusage.encr ))
{ {
log_error ("p15: key %s may not be used for decryption\n", keyidstr); log_error ("p15: key %s may not be used for decryption\n", keyidstr);
@ -5979,17 +5983,18 @@ do_decipher (app_t app, ctrl_t ctrl, const char *keyidstr,
/* Find the authentication object to this private key object. */ /* Find the authentication object to this private key object. */
if (!prkdf->authid) if (!prkdf->authid)
{ {
log_error ("p15: no authentication object defined for %s\n", keyidstr); log_info ("p15: no authentication object defined for %s\n", keyidstr);
/* fixme: we might want to go ahead and do without PIN aodf = NULL;
verification. */ }
return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION); else
{
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)
log_info ("p15: no authentication for %s needed\n", keyidstr);
} }
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)
log_info ("p15: no authentication for %s needed\n", keyidstr);
/* 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. */
@ -6274,7 +6279,8 @@ do_with_keygrip (app_t app, ctrl_t ctrl, int action,
} }
else if (capability == GCRY_PK_USAGE_ENCR) else if (capability == GCRY_PK_USAGE_ENCR)
{ {
if (!(prkdf->usageflags.decrypt || prkdf->usageflags.unwrap)) if (!(prkdf->usageflags.decrypt || prkdf->usageflags.unwrap
|| prkdf->usageflags.derive))
continue; continue;
} }
else if (capability == GCRY_PK_USAGE_AUTH) else if (capability == GCRY_PK_USAGE_AUTH)