Hello,
I see that Metalink's checksum verification is limited to sha256.

I cannot find an option to enable md5, sha1, sha384, or sha512.

Attached to this message there is a patch to add md5, sha1, sha384, and sha512 
computation to the Metalink module.

Let me know what you think.

-- 
Matthew White <[email protected]>
>From 735ac5ec0ce5c5405a1e75880c204afd098efbea Mon Sep 17 00:00:00 2001
From: Matthew White <[email protected]>
Date: Thu, 28 Jul 2016 10:59:11 +0200
Subject: [PATCH] Support Metalink's md5, sha1, sha256, sha384, and sha512
 hashes

Metalink's checksum verification was limited to sha256. This patch
implements computation for md5, sha1, sha384, and sha512.

* bootstrap.conf: crypto/sha512
* src/metalink.c: Compute md5, sha1, sha256, sha384, and sha512
---
 bootstrap.conf |  1 +
 src/metalink.c | 76 +++++++++++++++++++++++++++++++++++++++++++++++++++-------
 2 files changed, 69 insertions(+), 8 deletions(-)

diff --git a/bootstrap.conf b/bootstrap.conf
index 3925d55..5187e96 100644
--- a/bootstrap.conf
+++ b/bootstrap.conf
@@ -67,6 +67,7 @@ mkostemp
 crypto/md5
 crypto/sha1
 crypto/sha256
+crypto/sha512
 quote
 quotearg
 recv
diff --git a/src/metalink.c b/src/metalink.c
index 18f5f5d..6b278be 100644
--- a/src/metalink.c
+++ b/src/metalink.c
@@ -34,7 +34,10 @@ as that of the covered work.  */
 #include "retr.h"
 #include "exits.h"
 #include "utils.h"
+#include "md5.h"
+#include "sha1.h"
 #include "sha256.h"
+#include "sha512.h"
 #include "xstrndup.h"
 #include <errno.h>
 #include <unistd.h> /* For unlink.  */
@@ -177,14 +180,35 @@ retrieve_from_metalink (const metalink_t* metalink)
 
               for (mchksum_ptr = mfile->checksums; *mchksum_ptr; mchksum_ptr++)
                 {
+                  hash_ok = false;
+
+                  char md5[MD5_DIGEST_SIZE];
+                  char md5_txt[2 * MD5_DIGEST_SIZE + 1];
+
+                  char sha1[SHA1_DIGEST_SIZE];
+                  char sha1_txt[2 * SHA1_DIGEST_SIZE + 1];
+
                   char sha256[SHA256_DIGEST_SIZE];
                   char sha256_txt[2 * SHA256_DIGEST_SIZE + 1];
 
+                  char sha384[SHA384_DIGEST_SIZE];
+                  char sha384_txt[2 * SHA384_DIGEST_SIZE + 1];
+
+                  char sha512[SHA512_DIGEST_SIZE];
+                  char sha512_txt[2 * SHA512_DIGEST_SIZE + 1];
+
                   mchksum = *mchksum_ptr;
 
                   /* I have seen both variants...  */
-                  if (strcasecmp (mchksum->type, "sha256")
-                      && strcasecmp (mchksum->type, "sha-256"))
+                  if (strcasecmp (mchksum->type, "md5")
+                      && strcasecmp (mchksum->type, "sha1")
+                      && strcasecmp (mchksum->type, "sha-1")
+                      && strcasecmp (mchksum->type, "sha256")
+                      && strcasecmp (mchksum->type, "sha-256")
+                      && strcasecmp (mchksum->type, "sha384")
+                      && strcasecmp (mchksum->type, "sha-384")
+                      && strcasecmp (mchksum->type, "sha512")
+                      && strcasecmp (mchksum->type, "sha-512"))
                     {
                       DEBUGP (("Ignoring unsupported checksum type %s.\n",
                                quote (mchksum->type)));
@@ -194,22 +218,58 @@ retrieve_from_metalink (const metalink_t* metalink)
                   logprintf (LOG_VERBOSE, _("Computing checksum for %s\n"),
                              quote (mfile->name));
 
-                  sha256_stream (local_file, sha256);
-                  wg_hex_to_string (sha256_txt, sha256, SHA256_DIGEST_SIZE);
                   DEBUGP (("Declared hash: %s\n", mchksum->hash));
-                  DEBUGP (("Computed hash: %s\n", sha256_txt));
-                  if (!strcmp (sha256_txt, mchksum->hash))
+
+                  if (strcasecmp (mchksum->type, "md5") == 0)
+                    {
+                      md5_stream (local_file, md5);
+                      wg_hex_to_string (md5_txt, md5, MD5_DIGEST_SIZE);
+                      DEBUGP (("Computed hash: %s\n", md5_txt));
+                      if (!strcmp (md5_txt, mchksum->hash)) hash_ok = true;
+                    }
+                  else if (strcasecmp (mchksum->type, "sha1") == 0
+                           || strcasecmp (mchksum->type, "sha-1") == 0)
+                    {
+                      sha1_stream (local_file, sha1);
+                      wg_hex_to_string (sha1_txt, sha1, SHA1_DIGEST_SIZE);
+                      DEBUGP (("Computed hash: %s\n", sha1_txt));
+                      if (!strcmp (sha1_txt, mchksum->hash)) hash_ok = true;
+                    }
+                  else if (strcasecmp (mchksum->type, "sha256") == 0
+                           || strcasecmp (mchksum->type, "sha-256") == 0)
+                    {
+                      sha256_stream (local_file, sha256);
+                      wg_hex_to_string (sha256_txt, sha256, SHA256_DIGEST_SIZE);
+                      DEBUGP (("Computed hash: %s\n", sha256_txt));
+                      if (!strcmp (sha256_txt, mchksum->hash)) hash_ok = true;
+                    }
+                  else if (strcasecmp (mchksum->type, "sha384") == 0
+                           || strcasecmp (mchksum->type, "sha-384") == 0)
+                    {
+                      sha384_stream (local_file, sha384);
+                      wg_hex_to_string (sha384_txt, sha384, SHA384_DIGEST_SIZE);
+                      DEBUGP (("Computed hash: %s\n", sha384_txt));
+                      if (!strcmp (sha384_txt, mchksum->hash)) hash_ok = true;
+                    }
+                  else if (strcasecmp (mchksum->type, "sha512") == 0
+                           || strcasecmp (mchksum->type, "sha-512") == 0)
+                    {
+                      sha512_stream (local_file, sha512);
+                      wg_hex_to_string (sha512_txt, sha512, SHA512_DIGEST_SIZE);
+                      DEBUGP (("Computed hash: %s\n", sha512_txt));
+                      if (!strcmp (sha512_txt, mchksum->hash)) hash_ok = true;
+                    }
+
+                  if (hash_ok == true)
                     {
                       logputs (LOG_VERBOSE,
                                _("Checksum matches.\n"));
-                      hash_ok = true;
                     }
                   else
                     {
                       logprintf (LOG_NOTQUIET,
                                  _("Checksum mismatch for file %s.\n"),
                                  quote (mfile->name));
-                      hash_ok = false;
                     }
 
                   /* Stop as soon as we checked the supported checksum.  */
-- 
2.7.3

Reply via email to