core,cpp: New key flag 'is_de_vs'.
authorWerner Koch <wk@gnupg.org>
Mon, 20 Mar 2017 18:56:10 +0000 (19:56 +0100)
committerWerner Koch <wk@gnupg.org>
Mon, 20 Mar 2017 19:05:16 +0000 (20:05 +0100)
* 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 <wk@gnupg.org>
NEWS
doc/gpgme.texi
lang/cpp/src/key.cpp
lang/cpp/src/key.h
src/gpgme.h.in
src/keylist.c
tests/run-keylist.c

diff --git a/NEWS b/NEWS
index a270af7..f2ab0bf 100644 (file)
--- 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_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: 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: 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.
  qt: CryptoConfig::stringValueList()                NEW.
  gpgme_data_rewind                                  UN-DEPRECATE.
  py: Context.__init__        EXTENDED: New keyword arg home_dir.
index d32a124..337053f 100644 (file)
@@ -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.
 
 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
 @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
index 9eebbf0..31e59e1 100644 (file)
@@ -234,6 +234,11 @@ bool Key::isQualified() const
     return key && key->is_qualified;
 }
 
     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 ;
 const char *Key::issuerSerial() const
 {
     return key ? key->issuer_serial : 0 ;
@@ -469,6 +474,11 @@ bool Subkey::isQualified() const
     return subkey && subkey->is_qualified;
 }
 
     return subkey && subkey->is_qualified;
 }
 
+bool Subkey::isDeVs() const
+{
+    return subkey && subkey->is_de_vs;
+}
+
 bool Subkey::isCardKey() const
 {
     return subkey && subkey->is_cardkey;
 bool Subkey::isCardKey() const
 {
     return subkey && subkey->is_cardkey;
index 8c11a9d..829bd26 100644 (file)
@@ -112,6 +112,7 @@ public:
     bool canCertify() const;
     bool canAuthenticate() const;
     bool isQualified() const;
     bool canCertify() const;
     bool canAuthenticate() const;
     bool isQualified() const;
+    bool isDeVs() const;
 
     bool hasSecret() const;
     GPGMEPP_DEPRECATED bool isSecret() const
 
     bool hasSecret() const;
     GPGMEPP_DEPRECATED bool isSecret() const
@@ -219,6 +220,7 @@ public:
     bool canCertify() const;
     bool canAuthenticate() const;
     bool isQualified() const;
     bool canCertify() const;
     bool canAuthenticate() const;
     bool isQualified() const;
+    bool isDeVs() const;
     bool isCardKey() const;
 
     bool isSecret() const;
     bool isCardKey() const;
 
     bool isSecret() const;
index 032a205..b660cb5 100644 (file)
@@ -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 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.  */
   /* 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;
 
   /* Public key algorithm supported by this subkey.  */
   gpgme_pubkey_algo_t pubkey_algo;
index 2ce0846..de9bbb2 100644 (file)
@@ -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)
 /* 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;
       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;
   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 ();
         }
 
             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:
       break;
 
     case RT_SUB:
@@ -785,6 +806,10 @@ keylist_colon_handler (void *priv, char *line)
             return gpg_error_from_syserror ();
         }
 
             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:
       break;
 
     case RT_UID:
index 93fbeb5..fd9c7c2 100644 (file)
@@ -223,13 +223,14 @@ main (int argc, char **argv)
               key->can_sign? "s":"",
               key->can_certify? "c":"",
               key->can_authenticate? "a":"");
               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->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;
               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":"");
                   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":"",
                   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++)
                   subkey->is_cardkey? " cardkey":"");
         }
       for (nuids=0, uid=key->uids; uid; uid = uid->next, nuids++)