emacs-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Emacs-diffs] scratch/tzz/nettle dfd9227: WIP: GnuTLS digests are comple


From: Teodor Zlatanov
Subject: [Emacs-diffs] scratch/tzz/nettle dfd9227: WIP: GnuTLS digests are completely separate from MAC algorithms now
Date: Tue, 4 Apr 2017 15:46:57 -0400 (EDT)

branch: scratch/tzz/nettle
commit dfd92272ad1c8b417461dd94649e0a9be5b9b61e
Author: Ted Zlatanov <address@hidden>
Commit: Ted Zlatanov <address@hidden>

    WIP: GnuTLS digests are completely separate from MAC algorithms now
---
 src/gnutls.c                  | 259 ++++++++++++++++++++++++------------------
 test/lisp/net/gnutls-tests.el |  14 ++-
 2 files changed, 160 insertions(+), 113 deletions(-)

diff --git a/src/gnutls.c b/src/gnutls.c
index 081d290..e747259 100644
--- a/src/gnutls.c
+++ b/src/gnutls.c
@@ -1773,8 +1773,7 @@ DEFUN ("gnutls-macs", Fgnutls_macs, Sgnutls_macs, 0, 0, 0,
        doc: /* Return alist of GnuTLS mac-algorithm method
 descriptions as plists.  Use the value of the alist (extract it with
 `alist-get' for instance) with `gnutls-hash-mac'.  The alist key is
-the mac-algorithm method name. The related digest algorithm ID is also
-included when applicable. */)
+the mac-algorithm method name. */)
      (void)
 {
   Lisp_Object mac_algorithms = Qnil;
@@ -1783,18 +1782,9 @@ included when applicable. */)
     {
       const gnutls_mac_algorithm_t gma = macs[pos];
 
-      Lisp_Object mp = Qnil;
-
       const char* name = gnutls_mac_get_name (gma);
-      const gnutls_digest_algorithm_t gda = gnutls_digest_get_id (name);
-      if (gda != GNUTLS_DIG_UNKNOWN)
-        {
-          // Add the internally meaningful digest-algorithm ID.
-          mp = Fcons (QCdigest_algorithm_id,
-                      Fcons (make_number (gda), mp));
-        }
 
-      Lisp_Object mp2 = listn (CONSTYPE_HEAP, 9,
+      Lisp_Object mp = listn (CONSTYPE_HEAP, 11,
                               // The string description of the mac-algorithm 
ID.
                               build_unibyte_string (name),
                               // The internally meaningful mac-algorithm ID.
@@ -1803,180 +1793,220 @@ included when applicable. */)
                               // The type (vs. other GnuTLS objects).
                               QCtype,
                               Qgnutls_type_mac_algorithm,
+                              // The output length.
+                              QCmac_algorithm_length,
+                              make_number (gnutls_hmac_get_len (gma)),
                               // The key size.
                               QCmac_algorithm_keysize,
                               make_number (gnutls_mac_get_key_size (gma)),
                               // The nonce size.
                               QCmac_algorithm_noncesize,
                               make_number (gnutls_mac_get_nonce_size (gma)));
-      mac_algorithms = Fcons (CALLN (Fappend, mp2, mp), mac_algorithms);
+      mac_algorithms = Fcons (mp, mac_algorithms);
     }
 
   return mac_algorithms;
 }
 
-/* When the key is Qnil, we run in digest mode. */
-Lisp_Object
-emacs_gnutls_hash (Lisp_Object method, Lisp_Object key, Lisp_Object input)
+DEFUN ("gnutls-digests", Fgnutls_digests, Sgnutls_digests, 0, 0, 0,
+       doc: /* Return alist of GnuTLS digest-algorithm method
+descriptions as plists.  Use the value of the alist (extract it with
+`alist-get' for instance) with `gnutls-hash-digest'.  The alist key is
+the digest-algorithm method name. */)
+     (void)
 {
-  bool digest_mode = NILP (key);
+  Lisp_Object digest_algorithms = Qnil;
+  const gnutls_digest_algorithm_t* digests = gnutls_digest_list ();
+  for (size_t pos = 0; digests[pos] != 0; pos++)
+    {
+      const gnutls_digest_algorithm_t gda = digests[pos];
+
+      const char* name = gnutls_digest_get_name (gda);
+
+      Lisp_Object mp = listn (CONSTYPE_HEAP, 7,
+                              // The string description of the 
digest-algorithm ID.
+                              build_unibyte_string (name),
+                              // The internally meaningful digest-algorithm ID.
+                              QCdigest_algorithm_id,
+                              make_number (gda),
+                              QCtype,
+                              Qgnutls_type_digest_algorithm,
+                              // The digest length.
+                              QCdigest_algorithm_length,
+                              make_number (gnutls_hash_get_len (gda)));
+
+      digest_algorithms = Fcons (mp, digest_algorithms);
+    }
+
+  return digest_algorithms;
+}
+
+DEFUN ("gnutls-hash-mac", Fgnutls_hash_mac, Sgnutls_hash_mac, 3, 3, 0,
+       doc: /* Hash INPUT string with HASH-METHOD and KEY string into a 
unibyte string.
+
+Returns nil on error. INPUT and KEY should be unibyte strings.
+
+The alist of MAC algorithms can be obtained with `gnutls-macs`. The
+HASH-METHOD may be a string matching a key in that alist, or a plist
+with the `:mac-algorithm-id' numeric property, or the number itself. */)
+     (Lisp_Object hash_method, Lisp_Object key, Lisp_Object input)
+{
+  CHECK_STRING (input);
+  CHECK_STRING (key);
+
   Lisp_Object output = Qnil;
   int ret = GNUTLS_E_SUCCESS;
 
-  const char* desc = (digest_mode ? "digest" : "hash");
-
   gnutls_mac_algorithm_t gma = GNUTLS_MAC_UNKNOWN;
-  gnutls_digest_algorithm_t gda = GNUTLS_DIG_UNKNOWN;
 
-  Lisp_Object mac = Qnil;
-  if (STRINGP (method))
+  Lisp_Object info = Qnil;
+  if (STRINGP (hash_method))
     {
-      mac = XCDR (Fassoc (method, Fgnutls_macs ()));
+      info = XCDR (Fassoc (hash_method, Fgnutls_macs ()));
     }
-  else if (INTEGERP (method))
+  else if (INTEGERP (hash_method))
     {
-      if (digest_mode)
-        {
-          gda = XINT (method);
-        }
-      else
-        {
-          gma = XINT (method);
-        }
+      gma = XINT (hash_method);
     }
   else
     {
-      mac = method;
+      info = hash_method;
     }
 
-  if (!NILP (mac) && CONSP (mac))
+  if (!NILP (info) && CONSP (info))
     {
-      Lisp_Object v = Fplist_get (mac, digest_mode ? QCdigest_algorithm_id : 
QCmac_algorithm_id);
+      Lisp_Object v = Fplist_get (info, QCmac_algorithm_id);
       if (INTEGERP (v))
         {
-          if (digest_mode)
-            {
-              gda = XINT (v);
-            }
-          else
-            {
-              gma = XINT (v);
-            }
+          gma = XINT (v);
         }
     }
 
-  if ( (digest_mode && gda == GNUTLS_MAC_UNKNOWN) ||
-       (!digest_mode && gma == GNUTLS_MAC_UNKNOWN))
+  if (gma == GNUTLS_MAC_UNKNOWN)
     {
-      error ("GnuTLS %s-method was invalid or not found", desc);
+      error ("GnuTLS MAC-method was invalid or not found");
       return Qnil;
     }
 
   gnutls_hmac_hd_t hmac;
-  gnutls_hash_hd_t hash;
-  if (digest_mode)
-    {
-      ret = gnutls_hash_init (&hash, gda);
-    }
-  else
-    {
-      ret = gnutls_hmac_init (&hmac, gma, SSDATA (key), SCHARS (key));
-    }
+  ret = gnutls_hmac_init (&hmac, gma, SSDATA (key), SCHARS (key));
 
   if (ret < GNUTLS_E_SUCCESS)
     {
       const char* str = gnutls_strerror (ret);
       if (!str)
         str = "unknown";
-      error ("GnuTLS %s initialization failed: %s", desc, str);
+      error ("GnuTLS MAC initialization failed: %s", str);
       return Qnil;
     }
 
-  size_t digest_length = digest_mode ? gnutls_hash_get_len (gda) : 
gnutls_hmac_get_len (gma);
+  size_t digest_length = gnutls_hmac_get_len (gma);
   void *digest = xzalloc (digest_length);
 
-  if (digest_mode)
-    {
-      ret = gnutls_hash (hash, SSDATA (input), SCHARS (input));
-    }
-  else
-    {
-      ret = gnutls_hmac (hmac, SSDATA (input), SCHARS (input));
-    }
+  ret = gnutls_hmac (hmac, SSDATA (input), SCHARS (input));
 
   if (ret < GNUTLS_E_SUCCESS)
     {
-      if (digest_mode)
-        {
-          gnutls_hash_deinit (hash, digest);
-        }
-      else
-        {
-          gnutls_hmac_deinit (hmac, digest);
-        }
+      gnutls_hmac_deinit (hmac, digest);
 
       xfree (digest);
       const char* str = gnutls_strerror (ret);
       if (!str)
         str = "unknown";
-      error ("GnuTLS %s application failed: %s", desc, str);
+      error ("GnuTLS MAC application failed: %s", str);
       return Qnil;
     }
 
-  if (digest_mode)
+  gnutls_hmac_output (hmac, digest);
+  output = make_unibyte_string (digest, digest_length);
+  gnutls_hmac_deinit (hmac, digest);
+
+  xfree (digest);
+  return output;
+}
+
+DEFUN ("gnutls-hash-digest", Fgnutls_hash_digest, Sgnutls_hash_digest, 2, 2, 0,
+       doc: /* Digest INPUT string with DIGEST-METHOD into a unibyte string.
+
+Returns nil on error. INPUT should be a unibyte string.
+
+The alist of digest algorithms can be obtained with `gnutls-digests`.
+The DIGEST-METHOD may be a string matching a key in that alist, or
+a plist with the `:digest-algorithm-id' numeric property, or the number
+itself. */)
+     (Lisp_Object digest_method, Lisp_Object input)
+{
+  CHECK_STRING (input);
+
+  Lisp_Object output = Qnil;
+  int ret = GNUTLS_E_SUCCESS;
+
+  gnutls_digest_algorithm_t gda = GNUTLS_DIG_UNKNOWN;
+
+  Lisp_Object info = Qnil;
+  if (STRINGP (digest_method))
+    {
+      info = XCDR (Fassoc (digest_method, Fgnutls_digests ()));
+    }
+  else if (INTEGERP (digest_method))
     {
-      gnutls_hash_output (hash, digest);
+      gda = XINT (digest_method);
     }
   else
     {
-      gnutls_hmac_output (hmac, digest);
+      info = digest_method;
     }
 
-  output = make_unibyte_string (digest, digest_length);
-
-  if (digest_mode)
+  if (!NILP (info) && CONSP (info))
     {
-      gnutls_hash_deinit (hash, digest);
+      Lisp_Object v = Fplist_get (info, QCdigest_algorithm_id);
+      if (INTEGERP (v))
+        {
+          gda = XINT (v);
+        }
     }
-  else
+
+  if (gda == GNUTLS_DIG_UNKNOWN)
     {
-      gnutls_hmac_deinit (hmac, digest);
+      error ("GnuTLS digest-method was invalid or not found");
+      return Qnil;
     }
 
-  xfree (digest);
-  return output;
-}
+  gnutls_hash_hd_t hash;
+  ret = gnutls_hash_init (&hash, gda);
 
-DEFUN ("gnutls-hash-mac", Fgnutls_hash_mac, Sgnutls_hash_mac, 3, 3, 0,
-       doc: /* Hash INPUT string with HASH-METHOD and KEY string into a 
unibyte string.
+  if (ret < GNUTLS_E_SUCCESS)
+    {
+      const char* str = gnutls_strerror (ret);
+      if (!str)
+        str = "unknown";
+      error ("GnuTLS digest initialization failed: %s", str);
+      return Qnil;
+    }
 
-Returns nil on error. INPUT and KEY should be unibyte strings.
+  size_t digest_length = gnutls_hash_get_len (gda);
+  void *digest = xzalloc (digest_length);
 
-The alist of MAC algorithms can be obtained with `gnutls-macs`. The
-HASH-METHOD may be a string matching a key in that alist, or a plist
-with the `:mac-algorithm-id' numeric property, or the number itself. */)
-     (Lisp_Object hash_method, Lisp_Object key, Lisp_Object input)
-{
-  CHECK_STRING (input);
-  CHECK_STRING (key);
-  return emacs_gnutls_hash (hash_method, key, input);
-}
+  ret = gnutls_hash (hash, SSDATA (input), SCHARS (input));
 
-DEFUN ("gnutls-hash-digest", Fgnutls_hash_digest, Sgnutls_hash_digest, 2, 2, 0,
-       doc: /* Digest INPUT string with HASH-METHOD into a unibyte string.
+  if (ret < GNUTLS_E_SUCCESS)
+    {
+      gnutls_hash_deinit (hash, digest);
 
-Returns nil on error. INPUT and KEY should be unibyte strings.
+      xfree (digest);
+      const char* str = gnutls_strerror (ret);
+      if (!str)
+        str = "unknown";
+      error ("GnuTLS digest application failed: %s", str);
+      return Qnil;
+    }
 
-The alist of MAC algorithms can be obtained with `gnutls-macs`. Note
-that some MAC algorithms can't be used as digests, and the name used
-to specify a digest algorithm is the name of the MAC algorithm. The
-DIGEST-METHOD may be a string matching a key in that alist (as long as
-the matching plist has a `:digest-algorithm-id'), or a plist with the
-`:digest-algorithm-id' numeric property, or the number itself. */)
-     (Lisp_Object hash_method, Lisp_Object input)
-{
-  CHECK_STRING (input);
-  return emacs_gnutls_hash (hash_method, Qnil, input);
+  gnutls_hash_output (hash, digest);
+  output = make_unibyte_string (digest, digest_length);
+  gnutls_hash_deinit (hash, digest);
+
+  xfree (digest);
+  return output;
 }
 
 #endif
@@ -2046,13 +2076,17 @@ syms_of_gnutls (void)
   DEFSYM (QCcipher_iv, ":cipher-iv-size");
 
   DEFSYM (QCmac_algorithm_id, ":mac-algorithm-id");
-  DEFSYM (QCdigest_algorithm_id, ":digest-algorithm-id");
   DEFSYM (QCmac_algorithm_noncesize, ":mac-algorithm-noncesize");
   DEFSYM (QCmac_algorithm_keysize, ":mac-algorithm-keysize");
+  DEFSYM (QCmac_algorithm_length, ":mac-algorithm-length");
+
+  DEFSYM (QCdigest_algorithm_id, ":digest-algorithm-id");
+  DEFSYM (QCdigest_algorithm_length, ":digest-algorithm-length");
 
   DEFSYM (QCtype, ":type");
   DEFSYM (Qgnutls_type_cipher, "gnutls-symmetric-cipher");
   DEFSYM (Qgnutls_type_mac_algorithm, "gnutls-mac-algorithm");
+  DEFSYM (Qgnutls_type_digest_algorithm, "gnutls-digest-algorithm");
 
   DEFSYM (Qgnutls_e_interrupted, "gnutls-e-interrupted");
   Fput (Qgnutls_e_interrupted, Qgnutls_code,
@@ -2083,6 +2117,7 @@ syms_of_gnutls (void)
 
   defsubr (&Sgnutls_ciphers);
   defsubr (&Sgnutls_macs);
+  defsubr (&Sgnutls_digests);
   defsubr (&Sgnutls_hash_mac);
   defsubr (&Sgnutls_hash_digest);
 
diff --git a/test/lisp/net/gnutls-tests.el b/test/lisp/net/gnutls-tests.el
index 4987160..7984c55 100644
--- a/test/lisp/net/gnutls-tests.el
+++ b/test/lisp/net/gnutls-tests.el
@@ -36,6 +36,11 @@
    (append '("MD5" "SHA1" "SHA224" "SHA256" "SHA384" "SHA512")
            (mapcar 'car (gnutls-macs)))))
 
+(defvar gnutls-tests-tested-digests
+  (remove-duplicates
+   (append '("MD5" "SHA1" "SHA224" "SHA256" "SHA384" "SHA512")
+           (mapcar 'car (gnutls-digests)))))
+
 (defvar gnutls-tests-tested-ciphers
   (remove-duplicates
    (append '("AES-128-CCM" "DES-CBC" "CAMELLIA-192-CBC" "AES-128-GCM" 
"3DES-CBC")
@@ -53,13 +58,20 @@
 (ert-deftest test-gnutls-000-availability ()
   "Test the Nettle hashes and ciphers availability."
   (let ((macs (gnutls-macs))
+        (digests (gnutls-digests))
         (ciphers (gnutls-ciphers)))
     (dolist (name gnutls-tests-tested-macs)
       (let ((plist (cdr (assoc name macs))))
         (gnutls-tests-message "Checking MAC %s %S" name plist)
-        (dolist (prop '(:mac-algorithm-id :mac-algorithm-keysize 
:mac-algorithm-noncesize))
+        (dolist (prop '(:mac-algorithm-id :mac-algorithm-length 
:mac-algorithm-keysize :mac-algorithm-noncesize))
           (should (plist-get plist prop)))
         (should (eq 'gnutls-mac-algorithm (plist-get plist :type)))))
+    (dolist (name gnutls-tests-tested-digests)
+      (let ((plist (cdr (assoc name digests))))
+        (gnutls-tests-message "Checking digest %s %S" name plist)
+        (dolist (prop '(:digest-algorithm-id :digest-algorithm-length))
+          (should (plist-get plist prop)))
+        (should (eq 'gnutls-digest-algorithm (plist-get plist :type)))))
     (dolist (name gnutls-tests-tested-ciphers)
       (let ((plist (cdr (assoc name ciphers))))
         (gnutls-tests-message "Checking cipher %s %S" name plist)



reply via email to

[Prev in Thread] Current Thread [Next in Thread]