]> git.ipfire.org Git - thirdparty/gnutls.git/commitdiff
Better handling of security parameters to key sizes matching (via a single table...
authorNikos Mavrogiannopoulos <nmav@gnutls.org>
Fri, 23 Jul 2010 21:48:45 +0000 (23:48 +0200)
committerNikos Mavrogiannopoulos <nmav@gnutls.org>
Fri, 23 Jul 2010 21:50:38 +0000 (23:50 +0200)
functions to return the security parameter of a private key.

NEWS
lib/gnutls_algorithms.c
lib/gnutls_algorithms.h
lib/includes/gnutls/openpgp.h
lib/includes/gnutls/x509.h
lib/libgnutls.map
lib/nettle/mpi.c
lib/openpgp/privkey.c
lib/x509/privkey.c
src/certtool.c
tests/pathlen/no-ca-or-pathlen.pem

diff --git a/NEWS b/NEWS
index eeb77a5b7472f9cc65e77b0148976499ad2c5d3f..2731aeab9748f71c88a8980ce4ffc8a5bb12fe6d 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -6,13 +6,15 @@ See the end for copying conditions.
 * Version 2.11.1 (unreleased)
 
 ** libgnutls: Updated documentation and gnutls_pk_params_t mappings
-to ECRYPT II recommendations.
+to ECRYPT II recommendations. Mappings were moved to a single location
+and DSA keys are handled differently (since DSA2 allows for 1024,2048
+and 3072 keys only).
 
 ** libgnutls: HMAC-MD5 no longer used by default.
 
 ** API and ABI modifications:
-No changes since last version.
-
+gnutls_openpgp_privkey_sec_param: ADDED
+gnutls_x509_privkey_sec_param: ADDED
 
 * Version 2.11.0 (released 2010-07-22)
 
index 0bb3d32e5d4950c04f42f66ed1067a6462cfa911..dce0a6f3edc37c9f63af2bdb4d3c448573d1f1a2 100644 (file)
 #include <x509/common.h>
 
 
+typedef struct
+{
+  const char *name;
+  gnutls_sec_param_t sec_param;
+  int bits;            /* security level */
+  int pk_bits;         /* DH, RSA, SRP */
+  int dsa_bits;                /* bits for DSA. Handled differently since
+                        * choice of key size in DSA is political.
+                        */
+  int subgroup_bits;   /* subgroup bits */
+  int ecc_bits;                /* bits for ECC keys */
+} gnutls_sec_params_entry;
+
+static const gnutls_sec_params_entry sec_params[] = {
+  {"Weak", GNUTLS_SEC_PARAM_WEAK, 64, 816, 1024, 128, 128},
+  {"Low", GNUTLS_SEC_PARAM_LOW, 80, 1248, 1024, 160, 160},
+  {"Normal", GNUTLS_SEC_PARAM_NORMAL, 112, 2432, 2048, 224, 224},
+  {"Weak", GNUTLS_SEC_PARAM_HIGH, 128, 3248, 3072, 256, 256},
+  {"Weak", GNUTLS_SEC_PARAM_ULTRA, 256, 15424, 3072, 512, 512},
+  {NULL, 0, 0, 0, 0, 0}
+};
+
+#define GNUTLS_SEC_PARAM_LOOP(b) \
+       { const gnutls_sec_params_entry *p; \
+                for(p = sec_params; p->name != NULL; p++) { b ; } }
+
 
 /* Cred type mappings to KX algorithms 
  * FIXME: The mappings are not 1-1. Some KX such as SRP_RSA require
@@ -135,8 +161,7 @@ static const gnutls_protocol_t supported_protocols[] = {
                 for(p = sup_versions; p->name != NULL; p++) { b ; }
 
 #define GNUTLS_VERSION_ALG_LOOP(a) \
-                        GNUTLS_VERSION_LOOP( if(p->id == version) { a; break; })
-
+       GNUTLS_VERSION_LOOP( if(p->id == version) { a; break; })
 
 struct gnutls_cipher_entry
 {
@@ -2293,28 +2318,30 @@ _gnutls_x509_pk_to_oid (gnutls_pk_algorithm_t algorithm)
 unsigned int gnutls_sec_param_to_pk_bits (gnutls_pk_algorithm_t algo,
                                       gnutls_sec_param_t param)
 {
+unsigned int ret = 0;
 
-  switch(algo)
+  /* handle DSA differently */
+  if (algo == GNUTLS_PK_DSA) 
     {
-      case GNUTLS_PK_RSA:
-      case GNUTLS_PK_DSA:
-        switch(param)
-          {
-            case GNUTLS_SEC_PARAM_LOW:
-              return 1248;
-            case GNUTLS_SEC_PARAM_HIGH:
-              return 2432;
-            case GNUTLS_SEC_PARAM_ULTRA:
-              return 3248;
-            case GNUTLS_SEC_PARAM_NORMAL:
-            default:
-              return 2432;
-          }
-        default:
-          gnutls_assert();
-          return 0;
+       GNUTLS_SEC_PARAM_LOOP ( if (p->sec_param == param) { ret = p->dsa_bits; break; });
+       return ret;
     }
 
+  GNUTLS_SEC_PARAM_LOOP ( if (p->sec_param == param) { ret = p->pk_bits; break; });
+
+  return ret;
+}
+
+/* Returns the corresponding size for subgroup bits (q),
+ * given the group bits (p).
+ */
+unsigned int gnutls_pk_bits_to_subgroup_bits (unsigned int pk_bits)
+{
+unsigned int ret = 0;
+
+  GNUTLS_SEC_PARAM_LOOP ( if (p->pk_bits >= pk_bits) { ret = p->subgroup_bits; break; });
+
+  return ret;
 }
 
 /**
@@ -2330,36 +2357,11 @@ unsigned int gnutls_sec_param_to_pk_bits (gnutls_pk_algorithm_t algo,
 const char *
 gnutls_sec_param_get_name (gnutls_sec_param_t param)
 {
-  const char *p;
+const char* ret = "Unknown";
 
-  switch (param)
-    {
-    case GNUTLS_SEC_PARAM_WEAK:
-      p = "Weak";
-      break;
-
-    case GNUTLS_SEC_PARAM_LOW:
-      p = "Low";
-      break;
-
-    case GNUTLS_SEC_PARAM_NORMAL:
-      p = "Normal";
-      break;
-
-    case GNUTLS_SEC_PARAM_HIGH:
-      p = "High";
-      break;
-  
-    case GNUTLS_SEC_PARAM_ULTRA:
-      p = "Ultra";
-      break;
+  GNUTLS_SEC_PARAM_LOOP ( if (p->sec_param == param) { ret = p->name; break; });
 
-    default:
-      p = "Unknown";
-      break;
-    }
-
-  return p;
+  return ret;
 }
 
 /**
@@ -2377,17 +2379,13 @@ gnutls_sec_param_get_name (gnutls_sec_param_t param)
 gnutls_sec_param_t gnutls_pk_bits_to_sec_param (gnutls_pk_algorithm_t algo,
                                       unsigned int bits)
 {
+  gnutls_sec_param_t ret = GNUTLS_SEC_PARAM_WEAK;
 
-  /* currently we ignore algo */
-  if (bits >= 15423)
-    return GNUTLS_SEC_PARAM_ULTRA;
-  else if (bits >= 3247)
-    return GNUTLS_SEC_PARAM_HIGH;
-  else if (bits >= 2431)
-    return GNUTLS_SEC_PARAM_NORMAL;
-  else if (bits >= 1248)
-    return GNUTLS_SEC_PARAM_LOW;
-  else 
-    return GNUTLS_SEC_PARAM_WEAK;
+  GNUTLS_SEC_PARAM_LOOP ( 
+       if (p->pk_bits > bits) 
+         { break; } 
+       ret = p->sec_param; 
+  );
 
+  return ret;
 }
index a295f18993f067c4e9bcce6b05fed4ed9e87653b..ae17f6dd85c185fa37c4f3d79c30122f7552791e 100644 (file)
@@ -125,4 +125,6 @@ int _gnutls_cipher_priority (gnutls_session_t session,
 int _gnutls_kx_priority (gnutls_session_t session,
                         gnutls_kx_algorithm_t algorithm);
 
+unsigned int gnutls_pk_bits_to_subgroup_bits (unsigned int pk_bits);
+
 #endif
index d45c81858e6bd6d57a566e3c12fee6422f93b2f8..81b73b7c94094ad560b0822bb374e926ebba9575 100644 (file)
@@ -160,6 +160,8 @@ extern "C"
     gnutls_pk_algorithm_t
     gnutls_openpgp_privkey_get_pk_algorithm (gnutls_openpgp_privkey_t key,
                                             unsigned int *bits);
+
+  gnutls_sec_param_t gnutls_openpgp_privkey_sec_param (gnutls_openpgp_privkey_t key);
   int gnutls_openpgp_privkey_import (gnutls_openpgp_privkey_t key,
                                     const gnutls_datum_t * data,
                                     gnutls_openpgp_crt_fmt_t format,
index 59138982e0370bf99e5c7f50c80abd6f53ad25b5..3f07ad435acd11e885d6a447495af1b4a70a0275 100644 (file)
@@ -618,6 +618,7 @@ extern "C"
 
   int gnutls_x509_privkey_init (gnutls_x509_privkey_t * key);
   void gnutls_x509_privkey_deinit (gnutls_x509_privkey_t key);
+  gnutls_sec_param_t gnutls_x509_privkey_sec_param (gnutls_x509_privkey_t key);
   int gnutls_x509_privkey_cpy (gnutls_x509_privkey_t dst,
                               gnutls_x509_privkey_t src);
   int gnutls_x509_privkey_import (gnutls_x509_privkey_t key,
index 88c5c25234828dd2937a4fd22e5db202951f3327..b8d39f72b12524668a706b87f59e965d511fb4f3 100644 (file)
@@ -685,6 +685,8 @@ GNUTLS_2_11
        gnutls_x509_crq_get_preferred_hash_algorithm;
        gnutls_cipher_encrypt2;
        gnutls_cipher_decrypt2;
+       gnutls_openpgp_privkey_sec_param;
+       gnutls_x509_privkey_sec_param;
 } GNUTLS_2_10;
 
 GNUTLS_PRIVATE {
index f70cd9387fdd3a89b96f7f1b465a0abcf9a91122..865104c000dc17b82290d849b2bf523be1e01223 100644 (file)
@@ -396,14 +396,12 @@ inline static int gen_group (mpz_t *prime, mpz_t* generator, unsigned int nbits)
        /* security level enforcement. 
         * Values for q are selected according to ECRYPT II recommendations.
         */
-       if (nbits <= 1248) {
-               q_bytes = 160/8;
-       } else if (nbits <=2432) {
-               q_bytes = 224/8;
-       } else if (nbits <= 3248) {
-               q_bytes = 256/8;
-       } else {
-               q_bytes = 512/8;
+       q_bytes = gnutls_pk_bits_to_subgroup_bits (nbits);
+       q_bytes/=8;
+       
+       if (q_bytes == 0) {
+               gnutls_assert();
+               return GNUTLS_E_INVALID_REQUEST;
        }
        
        if (nbits%8 != 0)
index 71c17c494a20da79e26456a9e3cb63cf9a21e28a..9be4a2c541024529035eb7208b029f090d0da84d 100644 (file)
@@ -74,6 +74,32 @@ gnutls_openpgp_privkey_deinit (gnutls_openpgp_privkey_t key)
   gnutls_free (key);
 }
 
+/**
+ * gnutls_openpgp_privkey_sec_param:
+ * @key: a key structure
+ *
+ * This function will return the security parameter appropriate with
+ * this private key.
+ *
+ * Returns: On success, a valid security parameter is returned otherwise
+ * %GNUTLS_SEC_PARAM_UNKNOWN is returned.
+ **/
+gnutls_sec_param_t
+gnutls_openpgp_privkey_sec_param (gnutls_openpgp_privkey_t key)
+{
+gnutls_pk_algorithm_t algo;
+unsigned int bits;
+
+  algo = gnutls_openpgp_privkey_get_pk_algorithm (key, &bits);
+  if (algo == GNUTLS_PK_UNKNOWN) 
+    {
+      gnutls_assert();
+      return GNUTLS_SEC_PARAM_UNKNOWN;
+    }
+
+  return gnutls_pk_bits_to_sec_param (algo, bits);
+}
+
 /**
  * gnutls_openpgp_privkey_import:
  * @key: The structure to store the parsed key.
index 2b8e21382975ad4d3cde256a267b254482e64df8..964ccb3d9ef07e9f825fca74008b8ef0a380c41e 100644 (file)
@@ -829,6 +829,36 @@ gnutls_x509_privkey_export (gnutls_x509_privkey_t key,
                                  output_data, output_data_size);
 }
 
+/**
+ * gnutls_x509_privkey_sec_param:
+ * @key: a key structure
+ *
+ * This function will return the security parameter appropriate with
+ * this private key.
+ *
+ * Returns: On success, a valid security parameter is returned otherwise
+ * %GNUTLS_SEC_PARAM_UNKNOWN is returned.
+ **/
+gnutls_sec_param_t
+gnutls_x509_privkey_sec_param (gnutls_x509_privkey_t key)
+{
+int ret;
+
+  switch (key->pk_algorithm)
+    {
+      case GNUTLS_PK_RSA:
+        ret = gnutls_pk_bits_to_sec_param (GNUTLS_PK_RSA, _gnutls_mpi_get_nbits(key->params[0]/*m*/));
+        break;
+      case GNUTLS_PK_DSA:
+        ret = gnutls_pk_bits_to_sec_param (GNUTLS_PK_DSA, _gnutls_mpi_get_nbits(key->params[0] /*p*/));
+        break;
+      default:
+        ret = GNUTLS_SEC_PARAM_UNKNOWN;
+    }
+    
+  return ret;
+}
+
 /**
  * gnutls_x509_privkey_export_rsa_raw:
  * @key: a structure that holds the rsa parameters
index 579c098d81f0501d6a91161cb5fb346b689d0e29..107e9ad01603dd00dfe805a054fef7f4f803c278 100644 (file)
@@ -1350,6 +1350,7 @@ pgp_privkey_info (void)
       fprintf (outfile, "\tPublic Key Algorithm: ");
       cprint = gnutls_pk_algorithm_get_name (ret);
       fprintf (outfile, "%s\n", cprint ? cprint : "Unknown");
+      fprintf (outfile, "\tKey Security Level: %s\n", gnutls_sec_param_get_name(gnutls_openpgp_privkey_sec_param(key)));
 
       /* Print the raw public and private keys
        */
@@ -1678,6 +1679,7 @@ privkey_info (void)
 
   cprint = gnutls_pk_algorithm_get_name (ret);
   fprintf (outfile, "%s\n", cprint ? cprint : "Unknown");
+  fprintf (outfile, "\tKey Security Level: %s\n", gnutls_sec_param_get_name(gnutls_x509_privkey_sec_param(key)));
 
   /* Print the raw public and private keys
    */
index 08c9306add139922412f1fc79fb6da508ba31f1e..478a3e18d0b14c31d53362381d3b7e429e1fa04f 100644 (file)
@@ -7,7 +7,7 @@ X.509 Certificate Information:
                Not After: Fri Aug 25 23:59:59 UTC 2000
        Subject: O=VeriSign\, Inc.,OU=VeriSign Trust Network,OU=www.verisign.com/repository/RPA Incorp. by Ref.\,LIAB.LTD(c)98,OU=Persona Not Validated,OU=Digital ID Class 1 - Netscape,CN=Simon Josefsson,EMAIL=simon@josefsson.org
        Subject Public Key Algorithm: RSA
-       Certificate Security Level: Low
+       Certificate Security Level: Weak
                Modulus (bits 1024):
                        c9:0c:ce:8a:fe:71:46:9b:ca:1d:e5:90:12:a5:11:0b
                        c6:2d:c4:33:c6:19:e8:60:59:4e:3f:64:3d:e4:f7:7b