grub-devel
[Top][All Lists]
Advanced

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

Re: [PATCH] verify: search keyid in hashed signature subpackets


From: Ignat Korchagin
Subject: Re: [PATCH] verify: search keyid in hashed signature subpackets
Date: Wed, 30 Mar 2016 15:09:16 +0100

Implemented as a separate function which should process arbitrary length data. 
As for tests, it seems that the easiest way is to add this signature to 
tests/file_filter. Not sure how should I send you the patch with binary data 
though.

diff --git a/grub-core/commands/verify.c b/grub-core/commands/verify.c
index 166d0aa..cc8fa39 100644
--- a/grub-core/commands/verify.c
+++ b/grub-core/commands/verify.c
@@ -445,6 +445,88 @@ rsa_pad (gcry_mpi_t *hmpi, grub_uint8_t *hval,
   return ret;
 }
 
+static grub_uint64_t
+grub_subpacket_keyid_search (grub_file_t f, grub_ssize_t sub_len,
+                            const gcry_md_spec_t *hash, void *context)
+{
+  grub_uint64_t keyid = 0;
+  grub_uint8_t *readbuf = NULL;
+
+  while (sub_len > 0)
+    {
+      grub_uint8_t szid[5];
+      grub_size_t sz_len;
+      grub_size_t l;
+
+      grub_ssize_t r = grub_file_read (f, szid, 1);
+      if (r != 1)
+        return 0;
+
+      if (szid[0] < 192)
+            {
+          l = szid[0];
+          sz_len = 1;
+        }
+      else if (szid[0] < 255)
+        {
+          r = grub_file_read (f, szid + 1, 1);
+          if (r != 1)
+            return 0;
+
+          l = (((szid[0] & ~192) << GRUB_CHAR_BIT) | szid[1]) + 192;
+          sz_len = 2;
+        }
+      else
+        {
+          r = grub_file_read (f, szid + 1, 4);
+          if (r != 4)
+            return 0;
+
+          l = grub_be_to_cpu32 (grub_get_unaligned32 (szid + 1));
+          sz_len = 5;
+        }
+
+      readbuf = grub_zalloc (l);
+      if (!readbuf)
+        return 0;
+
+      r = grub_file_read (f, readbuf, l);
+      if (r <= 0)
+        goto fail;
+
+      while ((grub_size_t)r < l)
+        {
+          grub_ssize_t rr = grub_file_read (f, readbuf + r, l - 
(grub_size_t)r);
+          if (rr <= 0)
+            goto fail;
+          r += rr;
+        }
+
+      if (*readbuf == 0x10 && l >= 8)
+        keyid = grub_get_unaligned64 (readbuf + 1);
+
+      if (hash && context)
+        {
+          hash->write (context, szid, sz_len);
+          hash->write (context, readbuf, l);
+        }
+
+      grub_free (readbuf);
+      readbuf = NULL;
+
+      sub_len -= sz_len + l;
+    }
+
+fail:
+  if (readbuf)
+    {
+      grub_free (readbuf);
+      return 0;
+    }
+
+  return keyid;
+}
+
 static grub_err_t
 grub_verify_signature_real (char *buf, grub_size_t size,
                            grub_file_t f, grub_file_t sig,
@@ -532,17 +614,7 @@ grub_verify_signature_real (char *buf, grub_size_t size,
 
     hash->write (context, &v, sizeof (v));
     hash->write (context, &v4, sizeof (v4));
-    while (rem)
-      {
-       r = grub_file_read (sig, readbuf,
-                           rem < READBUF_SIZE ? rem : READBUF_SIZE);
-       if (r < 0)
-         goto fail;
-       if (r == 0)
-         break;
-       hash->write (context, readbuf, r);
-       rem -= r;
-      }
+    keyid = grub_subpacket_keyid_search (sig, rem, hash, context);
     hash->write (context, &v, sizeof (v));
     s = 0xff;
     hash->write (context, &s, sizeof (s));
@@ -550,37 +622,11 @@ grub_verify_signature_real (char *buf, grub_size_t size,
     r = grub_file_read (sig, &unhashed_sub, sizeof (unhashed_sub));
     if (r != sizeof (unhashed_sub))
       goto fail;
-    {
-      grub_uint8_t *ptr;
-      grub_uint32_t l;
-      rem = grub_be_to_cpu16 (unhashed_sub);
-      if (rem > READBUF_SIZE)
-       goto fail;
-      r = grub_file_read (sig, readbuf, rem);
-      if (r != rem)
-       goto fail;
-      for (ptr = readbuf; ptr < readbuf + rem; ptr += l)
-       {
-         if (*ptr < 192)
-           l = *ptr++;
-         else if (*ptr < 255)
-           {
-             if (ptr + 1 >= readbuf + rem)
-               break;
-             l = (((ptr[0] & ~192) << GRUB_CHAR_BIT) | ptr[1]) + 192;
-             ptr += 2;
-           }
-         else
-           {
-             if (ptr + 5 >= readbuf + rem)
-               break;
-             l = grub_be_to_cpu32 (grub_get_unaligned32 (ptr + 1));
-             ptr += 5;
-           }
-         if (*ptr == 0x10 && l >= 8)
-           keyid = grub_get_unaligned64 (ptr + 1);
-       }
-    }
+    rem = grub_be_to_cpu16 (unhashed_sub);
+    if (keyid == 0)
+      keyid = grub_subpacket_keyid_search (sig, rem, NULL, NULL);
+    else
+      grub_subpacket_keyid_search (sig, rem, NULL, NULL);
 
     hash->final (context);
 




reply via email to

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