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