Well the code was copied from handling unhashed subpackets and has
same assumptions. I do agree that it does not handle arbitrary length
data. But if you consider it wrong, it should be changed for both
hashed and unhashed packets. Currently, for example, if the length of
unhashed subpackets will be longer than READBUF_SIZE, the signature
check will fail as well.

On Wed, Mar 30, 2016 at 5:44 AM, Andrei Borzenkov <arvidj...@gmail.com> wrote:
>
> 29.03.2016 22:02, Ignat Korchagin пишет:
> > Currently GRUB2 verify logic searches PGP keyid only in unhashed subpackets 
> > of PGP signature packet. As a result, signatures generated with GoLang 
> > openpgp package (https://godoc.org/golang.org/x/crypto/openpgp) could not 
> > be verified, because this package puts keyid in hashed subpackets and GRUB 
> > code never initializes the keyid variable, therefore is not able to find 
> > "verification key" with id 0x0.
> >
> > diff --git a/grub-core/commands/verify.c b/grub-core/commands/verify.c
> > index 166d0aa..dde37c4 100644
> > --- a/grub-core/commands/verify.c
> > +++ b/grub-core/commands/verify.c
> > @@ -532,33 +532,15 @@
> >
> >      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;
> > -      }
> > -    hash->write (context, &v, sizeof (v));
> > -    s = 0xff;
> > -    hash->write (context, &s, sizeof (s));
> > -    hash->write (context, &headlen, sizeof (headlen));
> > -    r = grub_file_read (sig, &unhashed_sub, sizeof (unhashed_sub));
> > -    if (r != sizeof (unhashed_sub))
> > +    if (rem > READBUF_SIZE)
> > +      goto fail;
>
> This changes behavior. It accepted hashed subpackets of arbitrary length
> before. If this was not appropriate, please explain why.
>
> > +    r = grub_file_read (sig, readbuf, rem);
> > +    if (r != rem)
> >        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)
> > @@ -581,6 +563,46 @@
> >           keyid = grub_get_unaligned64 (ptr + 1);
> >       }
> >      }
> > +    hash->write (context, readbuf, r);
> > +    hash->write (context, &v, sizeof (v));
> > +    s = 0xff;
> > +    hash->write (context, &s, sizeof (s));
> > +    hash->write (context, &headlen, sizeof (headlen));
> > +    r = grub_file_read (sig, &unhashed_sub, sizeof (unhashed_sub));
> > +    if (r != sizeof (unhashed_sub))
> > +      goto fail;
> > +    if (keyid == 0)
> > +      {
> > +        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);
> > +       }
> > +      }
> >
> >      hash->final (context);
> >
> >
> >
> > _______________________________________________
> > Grub-devel mailing list
> > Grub-devel@gnu.org
> > https://lists.gnu.org/mailman/listinfo/grub-devel
> >
>
>
> _______________________________________________
> Grub-devel mailing list
> Grub-devel@gnu.org
> https://lists.gnu.org/mailman/listinfo/grub-devel

_______________________________________________
Grub-devel mailing list
Grub-devel@gnu.org
https://lists.gnu.org/mailman/listinfo/grub-devel

Reply via email to