From ea9686ec71a2dd2225ce2b6d6d4038821d36205f Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Mon, 20 Mar 2017 19:56:10 +0100 Subject: [PATCH] core,cpp: New key flag 'is_de_vs'. * src/gpgme.h.in (_gpgme_subkey): New flag is_de_vs. * tests/run-keylist.c (main): Print that flag. * src/keylist.c (parse_pub_field18): New. (keylist_colon_handler): Parse compliance flags. * lang/cpp/src/key.cpp (Key::isDeVs): New. (Subkey::isDeVs): New. * lang/cpp/src/key.h (class Key): New method isDeVs. (class Subkey): New method isDeVs. Signed-off-by: Werner Koch --- NEWS | 3 +++ doc/gpgme.texi | 6 ++++++ lang/cpp/src/key.cpp | 10 ++++++++++ lang/cpp/src/key.h | 2 ++ src/gpgme.h.in | 5 ++++- src/keylist.c | 27 ++++++++++++++++++++++++++- tests/run-keylist.c | 10 ++++++---- 7 files changed, 57 insertions(+), 6 deletions(-) diff --git a/NEWS b/NEWS index a270af78..f2ab0bf3 100644 --- a/NEWS +++ b/NEWS @@ -10,14 +10,17 @@ Noteworthy changes in version 1.8.1 (unreleased) gpgme_op_createkey CHANGED: Meaning of 'expire' parameter. gpgme_op_createsubkey CHANGED: Meaning of 'expire' parameter. GPGME_CREATE_NOEXPIRE NEW. + gpgme_subkey_t EXTENDED: New field is_de_vs. cpp: Context::revUid(const Key&, const char*) NEW. cpp: Context::startRevUid(const Key&, const char*) NEW. cpp: Context::addUid(const Key&, const char*) NEW. cpp: Context::startAddUid(const Key&, const char*) NEW. cpp: Key::UserID::revoke() NEW. cpp: Key::addUid() NEW. + cpp: Key::isDeVs NEW. cpp: GpgGenCardKeyInteractor NEW. cpp: Subkey::keyGrip NEW. + cpp: Subkey::isDeVs NEW. qt: CryptoConfig::stringValueList() NEW. gpgme_data_rewind UN-DEPRECATE. py: Context.__init__ EXTENDED: New keyword arg home_dir. diff --git a/doc/gpgme.texi b/doc/gpgme.texi index d32a1242..337053fb 100644 --- a/doc/gpgme.texi +++ b/doc/gpgme.texi @@ -3156,6 +3156,12 @@ This is true if the subkey can be used for authentication. This is true if the subkey can be used for qualified signatures according to local government regulations. +@item unsigned int is_de_vs : 1 +This is true if the subkey complies with the rules for classified +information in Germany at the restricted level (VS-NfD). This are +currently RSA keys of at least 2048 bits or ECDH/ECDSA keys using a +Brainpool curve. + @item unsigned int secret : 1 This is true if the subkey is a secret key. Note that it will be false if the key is actually a stub key; i.e. a secret key operation diff --git a/lang/cpp/src/key.cpp b/lang/cpp/src/key.cpp index 9eebbf01..31e59e19 100644 --- a/lang/cpp/src/key.cpp +++ b/lang/cpp/src/key.cpp @@ -234,6 +234,11 @@ bool Key::isQualified() const return key && key->is_qualified; } +bool Key::isDeVs() const +{ + return key && key->subkeys && key->subkeys->is_de_vs; +} + const char *Key::issuerSerial() const { return key ? key->issuer_serial : 0 ; @@ -469,6 +474,11 @@ bool Subkey::isQualified() const return subkey && subkey->is_qualified; } +bool Subkey::isDeVs() const +{ + return subkey && subkey->is_de_vs; +} + bool Subkey::isCardKey() const { return subkey && subkey->is_cardkey; diff --git a/lang/cpp/src/key.h b/lang/cpp/src/key.h index 8c11a9d4..829bd266 100644 --- a/lang/cpp/src/key.h +++ b/lang/cpp/src/key.h @@ -112,6 +112,7 @@ public: bool canCertify() const; bool canAuthenticate() const; bool isQualified() const; + bool isDeVs() const; bool hasSecret() const; GPGMEPP_DEPRECATED bool isSecret() const @@ -219,6 +220,7 @@ public: bool canCertify() const; bool canAuthenticate() const; bool isQualified() const; + bool isDeVs() const; bool isCardKey() const; bool isSecret() const; diff --git a/src/gpgme.h.in b/src/gpgme.h.in index 032a205f..b660cb51 100644 --- a/src/gpgme.h.in +++ b/src/gpgme.h.in @@ -538,8 +538,11 @@ struct _gpgme_subkey /* True if the secret key is stored on a smart card. */ unsigned int is_cardkey : 1; + /* True if the key is compliant to the de-vs mode. */ + unsigned int is_de_vs : 1; + /* Internal to GPGME, do not use. */ - unsigned int _unused : 21; + unsigned int _unused : 20; /* Public key algorithm supported by this subkey. */ gpgme_pubkey_algo_t pubkey_algo; diff --git a/src/keylist.c b/src/keylist.c index 2ce08462..de9bbb2f 100644 --- a/src/keylist.c +++ b/src/keylist.c @@ -416,6 +416,23 @@ parse_sec_field15 (gpgme_key_t key, gpgme_subkey_t subkey, char *field) } +/* Parse the compliance field. */ +static void +parse_pub_field18 (gpgme_subkey_t subkey, char *field) +{ + char *p, *endp; + unsigned long ul; + + for (p = field; p && (ul = strtoul (p, &endp, 10)) && p != endp; p = endp) + { + switch (ul) + { + case 23: subkey->is_de_vs = 1; break; + } + } +} + + /* Parse a tfs record. */ static gpg_error_t parse_tfs_record (gpgme_user_id_t uid, char **field, int nfield) @@ -535,7 +552,7 @@ keylist_colon_handler (void *priv, char *line) RT_SSB, RT_SEC, RT_CRT, RT_CRS, RT_REV, RT_SPK } rectype = RT_NONE; -#define NR_FIELDS 17 +#define NR_FIELDS 18 char *field[NR_FIELDS]; int fields = 0; void *hook; @@ -712,6 +729,10 @@ keylist_colon_handler (void *priv, char *line) return gpg_error_from_syserror (); } + /* Field 18 has the compliance flags. */ + if (fields >= 17 && *field[17]) + parse_pub_field18 (subkey, field[17]); + break; case RT_SUB: @@ -785,6 +806,10 @@ keylist_colon_handler (void *priv, char *line) return gpg_error_from_syserror (); } + /* Field 18 has the compliance flags. */ + if (fields >= 17 && *field[17]) + parse_pub_field18 (subkey, field[17]); + break; case RT_UID: diff --git a/tests/run-keylist.c b/tests/run-keylist.c index 93fbeb5f..fd9c7c20 100644 --- a/tests/run-keylist.c +++ b/tests/run-keylist.c @@ -223,13 +223,14 @@ main (int argc, char **argv) key->can_sign? "s":"", key->can_certify? "c":"", key->can_authenticate? "a":""); - printf ("flags :%s%s%s%s%s%s%s\n", + printf ("flags :%s%s%s%s%s%s%s%s\n", key->secret? " secret":"", key->revoked? " revoked":"", key->expired? " expired":"", key->disabled? " disabled":"", key->invalid? " invalid":"", - key->is_qualified? " qualifid":"", + key->is_qualified? " qualified":"", + key->subkeys && key->subkeys->is_de_vs? " de-vs":"", key->subkeys && key->subkeys->is_cardkey? " cardkey":""); subkey = key->subkeys; @@ -248,14 +249,15 @@ main (int argc, char **argv) subkey->can_sign? "s":"", subkey->can_certify? "c":"", subkey->can_authenticate? "a":""); - printf ("flags %2d:%s%s%s%s%s%s%s\n", + printf ("flags %2d:%s%s%s%s%s%s%s%s\n", nsub, subkey->secret? " secret":"", subkey->revoked? " revoked":"", subkey->expired? " expired":"", subkey->disabled? " disabled":"", subkey->invalid? " invalid":"", - subkey->is_qualified? " qualifid":"", + subkey->is_qualified? " qualified":"", + subkey->is_de_vs? " de-vs":"", subkey->is_cardkey? " cardkey":""); } for (nuids=0, uid=key->uids; uid; uid = uid->next, nuids++)