From b63d203d3ba49483b079fb118a90990c452cd232 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Thu, 5 Oct 2023 14:10:01 +0200 Subject: [PATCH] core: Add key capability flags has_encrypt etc. * src/gpgme.h.in (struct _gpgme_key): Add flags has_encrypt, has_certify, has_sign, and has_authenticate. * src/keylist.c (finish_key): Set these flags. * tests/run-keylist.c (main): Print them. -- GnuPG-bug-id: 6748 --- NEWS | 12 +++++++++--- doc/gpgme.texi | 37 +++++++++++++++++++++++++++++++------ src/gpgme.h.in | 14 +++++++++++++- src/keylist.c | 20 ++++++++++++++++++++ tests/run-keylist.c | 7 ++++++- 5 files changed, 79 insertions(+), 11 deletions(-) diff --git a/NEWS b/NEWS index 6fcb6182..64e03c19 100644 --- a/NEWS +++ b/NEWS @@ -5,13 +5,19 @@ Noteworthy changes in version 1.23.0 (unreleased) * New keylist mode GPGME_KEYLIST_MODE_WITH_V5FPR. [T6705] + * New key capability flags has_*. [T6748] + * qt: Support refreshing keys via WKD. [T6672] * Interface changes relative to the 1.22.0 release: ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - GPGME_KEYLIST_MODE_WITH_V5FPR NEW. - qt: Protocol::wkdRefreshJob NEW. - qt: WKDRefreshJob NEW. + GPGME_KEYLIST_MODE_WITH_V5FPR NEW. + gpgme_key_t EXTENDED: New field has_encrypt. + gpgme_key_t EXTENDED: New field has_sign. + gpgme_key_t EXTENDED: New field has_certify. + gpgme_key_t EXTENDED: New field has_authenticate. + qt: Protocol::wkdRefreshJob NEW. + qt: WKDRefreshJob NEW. Noteworthy changes in version 1.22.0 (2023-08-21) diff --git a/doc/gpgme.texi b/doc/gpgme.texi index bce1b163..8c6420e6 100644 --- a/doc/gpgme.texi +++ b/doc/gpgme.texi @@ -3461,22 +3461,47 @@ listings if the key could not be validated due to missing certificates or unmatched policies. @item unsigned int can_encrypt : 1 -This is true if the key (ie one of its subkeys) can be used for -encryption. +This is true if the key or one of its subkeys can be used for +encryption and the encryption will likely succeed. @item unsigned int can_sign : 1 -This is true if the key (ie one of its subkeys) can be used to create -data signatures. +This is true if the key or one of its subkeys can be used to create +data signatures and the signing will likely succeed. @item unsigned int can_certify : 1 -This is true if the key (ie one of its subkeys) can be used to create +This is true if the key or one of its subkeys can be used to create key certificates. @item unsigned int can_authenticate : 1 @since{0.4.5} This is true if the key (ie one of its subkeys) can be used for -authentication. +authentication and the authentication will likely succeed. + +@item unsigned int has_encrypt : 1 +@since{1.23.0} + +This is true if the key or one of its subkeys is capable of encryption. +Note that this flag is set even if the key is expired. + +@item unsigned int has_sign : 1 +@since{1.23.0} + +This is true if the key or one of its subkeys is capable of signing. +Note that this flag is set even if the key is expired. + +@item unsigned int has_certify : 1 +@since{1.23.0} + +This is true if the key or one of its subkeys is capable of signing. +Note that this flag is set even if the key is expired. + +@item unsigned int has_authenticate : 1 +@since{1.23.0} + +This is true if the key or one of its subkeys is capable of +authentication. Note that this flag is set even if the key is +expired. @item unsigned int is_qualified : 1 @since{1.1.0} diff --git a/src/gpgme.h.in b/src/gpgme.h.in index 7110648e..d44994a6 100644 --- a/src/gpgme.h.in +++ b/src/gpgme.h.in @@ -800,8 +800,20 @@ struct _gpgme_key /* True if subkey is qualified for signatures according to German law. */ unsigned int is_qualified : 1; + /* True if key has at least one encryption subkey. */ + unsigned int has_encrypt : 1; + + /* True if key has at least one signing subkey. */ + unsigned int has_sign : 1; + + /* True if key has a certification capability. */ + unsigned int has_certify : 1; + + /* True if key has at least one authentication subkey. */ + unsigned int has_authenticate : 1; + /* Internal to GPGME, do not use. */ - unsigned int _unused : 17; + unsigned int _unused : 13; /* Origin of this key. */ unsigned int origin : 5; diff --git a/src/keylist.c b/src/keylist.c index 56836b5a..2f6ae824 100644 --- a/src/keylist.c +++ b/src/keylist.c @@ -563,6 +563,26 @@ static void finish_key (gpgme_ctx_t ctx, op_data_t opd) { gpgme_key_t key = opd->tmp_key; + gpgme_subkey_t subkey; + + /* Set the has_foo flags from the subkey capabilities. */ + if (key) + { + /* Note that we could have set has_certify always for OpenPGP + * but for X.509 a key is often not allowed to certify and thus + * we better take it from the subkey capabilities. */ + for (subkey = key->subkeys; subkey; subkey = subkey->next) + { + if (subkey->can_encrypt) + key->has_encrypt = 1; + if (subkey->can_sign) + key->has_sign = 1; + if (subkey->can_certify) + key->has_certify = 1; + if (subkey->can_authenticate) + key->has_authenticate = 1; + } + } opd->tmp_key = NULL; opd->tmp_uid = NULL; diff --git a/tests/run-keylist.c b/tests/run-keylist.c index 46f8f3b2..08f9b8cf 100644 --- a/tests/run-keylist.c +++ b/tests/run-keylist.c @@ -291,11 +291,16 @@ main (int argc, char **argv) int nsigs; printf ("keyid : %s\n", key->subkeys?nonnull (key->subkeys->keyid):"?"); - printf ("caps : %s%s%s%s\n", + printf ("can_cap : %s%s%s%s\n", key->can_encrypt? "e":"", key->can_sign? "s":"", key->can_certify? "c":"", key->can_authenticate? "a":""); + printf ("has_cap : %s%s%s%s\n", + key->has_encrypt? "e":"", + key->has_sign? "s":"", + key->has_certify? "c":"", + key->has_authenticate? "a":""); printf ("flags :%s%s%s%s%s%s%s%s\n", key->secret? " secret":"", key->revoked? " revoked":"",