verify framework.

This commit is contained in:
Vladimir Serbinenko committed 2017-05-09 16:12:18 +02:00
1 parent aa93127ed8
commit 09bd17faaa
6 files changed
+477 -284

No files matched your search

+256 -283
View File
@@ -30,16 +30,10 @@
#include <grub/env.h>
#include <grub/kernel.h>
#include <grub/extcmd.h>
#include <grub/verify.h>
GRUB_MOD_LICENSE ("GPLv3+");
struct grub_verified
{
grub_file_t file;
void *buf;
};
typedef struct grub_verified *grub_verified_t;
enum
{
OPTION_SKIP_SIG = 0
@@ -445,22 +439,26 @@ rsa_pad (gcry_mpi_t *hmpi, grub_uint8_t *hval,
return ret;
}
struct grub_pubkey_context
{
grub_file_t sig;
struct signature_v4_header v4;
grub_uint8_t v;
const gcry_md_spec_t *hash;
void *hash_context;
};
static grub_err_t
grub_verify_signature_real (char *buf, grub_size_t size,
grub_file_t f, grub_file_t sig,
struct grub_public_key *pkey)
grub_verify_signature_init (struct grub_pubkey_context *ctxt, grub_file_t sig)
{
grub_size_t len;
grub_uint8_t v;
grub_uint8_t h;
grub_uint8_t t;
grub_uint8_t pk;
const gcry_md_spec_t *hash;
struct signature_v4_header v4;
grub_err_t err;
grub_size_t i;
gcry_mpi_t mpis[10];
grub_uint8_t type = 0;
grub_uint8_t pk;
grub_memset (ctxt, 0, sizeof (*ctxt));
err = read_packet_header (sig, &type, &len);
if (err)
@@ -469,18 +467,18 @@ grub_verify_signature_real (char *buf, grub_size_t size,
if (type != 0x2)
return grub_error (GRUB_ERR_BAD_SIGNATURE, N_("bad signature"));
if (grub_file_read (sig, &v, sizeof (v)) != sizeof (v))
if (grub_file_read (sig, &ctxt->v, sizeof (ctxt->v)) != sizeof (ctxt->v))
return grub_error (GRUB_ERR_BAD_SIGNATURE, N_("bad signature"));
if (v != 4)
if (ctxt->v != 4)
return grub_error (GRUB_ERR_BAD_SIGNATURE, N_("bad signature"));
if (grub_file_read (sig, &v4, sizeof (v4)) != sizeof (v4))
if (grub_file_read (sig, &ctxt->v4, sizeof (ctxt->v4)) != sizeof (ctxt->v4))
return grub_error (GRUB_ERR_BAD_SIGNATURE, N_("bad signature"));
h = v4.hash;
t = v4.type;
pk = v4.pkeyalgo;
h = ctxt->v4.hash;
t = ctxt->v4.type;
pk = ctxt->v4.pkeyalgo;
if (t != 0)
return grub_error (GRUB_ERR_BAD_SIGNATURE, N_("bad signature"));
@@ -491,183 +489,232 @@ grub_verify_signature_real (char *buf, grub_size_t size,
if (pk >= ARRAY_SIZE (pkalgos) || pkalgos[pk].name == NULL)
return grub_error (GRUB_ERR_BAD_SIGNATURE, N_("bad signature"));
hash = grub_crypto_lookup_md_by_name (hashes[h]);
if (!hash)
ctxt->hash = grub_crypto_lookup_md_by_name (hashes[h]);
if (!ctxt->hash)
return grub_error (GRUB_ERR_BAD_SIGNATURE, "hash `%s' not loaded", hashes[h]);
grub_dprintf ("crypt", "alive\n");
{
void *context = NULL;
unsigned char *hval;
grub_ssize_t rem = grub_be_to_cpu16 (v4.hashed_sub);
grub_uint32_t headlen = grub_cpu_to_be32 (rem + 6);
grub_uint8_t s;
grub_uint16_t unhashed_sub;
grub_ssize_t r;
grub_uint8_t hash_start[2];
gcry_mpi_t hmpi;
grub_uint64_t keyid = 0;
struct grub_public_subkey *sk;
grub_uint8_t *readbuf = NULL;
ctxt->sig = sig;
context = grub_zalloc (hash->contextsize);
readbuf = grub_zalloc (READBUF_SIZE);
if (!context || !readbuf)
goto fail;
ctxt->hash_context = grub_zalloc (ctxt->hash->contextsize);
if (!ctxt->hash_context)
return grub_errno;
hash->init (context);
if (buf)
hash->write (context, buf, size);
else
while (1)
{
r = grub_file_read (f, readbuf, READBUF_SIZE);
if (r < 0)
goto fail;
if (r == 0)
break;
hash->write (context, readbuf, r);
}
ctxt->hash->init (ctxt->hash_context);
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))
goto fail;
return GRUB_ERR_NONE;
}
static grub_err_t
grub_pubkey_write (void *ctxt_, void *buf, grub_size_t size)
{
struct grub_pubkey_context *ctxt = ctxt_;
ctxt->hash->write (ctxt->hash_context, buf, size);
return GRUB_ERR_NONE;
}
static grub_err_t
grub_verify_signature_real (struct grub_pubkey_context *ctxt,
struct grub_public_key *pkey)
{
gcry_mpi_t mpis[10];
grub_uint8_t pk = ctxt->v4.pkeyalgo;
grub_size_t i;
grub_uint8_t *readbuf = NULL;
unsigned char *hval;
grub_ssize_t rem = grub_be_to_cpu16 (ctxt->v4.hashed_sub);
grub_uint32_t headlen = grub_cpu_to_be32 (rem + 6);
grub_uint8_t s;
grub_uint16_t unhashed_sub;
grub_ssize_t r;
grub_uint8_t hash_start[2];
gcry_mpi_t hmpi;
grub_uint64_t keyid = 0;
struct grub_public_subkey *sk;
readbuf = grub_malloc (READBUF_SIZE);
if (!readbuf)
goto fail;
ctxt->hash->write (ctxt->hash_context, &ctxt->v, sizeof (ctxt->v));
ctxt->hash->write (ctxt->hash_context, &ctxt->v4, sizeof (ctxt->v4));
while (rem)
{
grub_uint8_t *ptr;
grub_uint32_t l;
rem = grub_be_to_cpu16 (unhashed_sub);
if (rem > READBUF_SIZE)
r = grub_file_read (ctxt->sig, readbuf,
rem < READBUF_SIZE ? rem : READBUF_SIZE);
if (r < 0)
goto fail;
r = grub_file_read (sig, readbuf, rem);
if (r != rem)
if (r == 0)
break;
ctxt->hash->write (ctxt->hash_context, readbuf, r);
rem -= r;
}
ctxt->hash->write (ctxt->hash_context, &ctxt->v, sizeof (ctxt->v));
s = 0xff;
ctxt->hash->write (ctxt->hash_context, &s, sizeof (s));
ctxt->hash->write (ctxt->hash_context, &headlen, sizeof (headlen));
r = grub_file_read (ctxt->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 (ctxt->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);
}
}
ctxt->hash->final (ctxt->hash_context);
grub_dprintf ("crypt", "alive\n");
hval = ctxt->hash->read (ctxt->hash_context);
if (grub_file_read (ctxt->sig, hash_start, sizeof (hash_start)) != sizeof (hash_start))
goto fail;
if (grub_memcmp (hval, hash_start, sizeof (hash_start)) != 0)
goto fail;
grub_dprintf ("crypt", "@ %x\n", (int)grub_file_tell (ctxt->sig));
for (i = 0; i < pkalgos[pk].nmpisig; i++)
{
grub_uint16_t l;
grub_size_t lb;
grub_dprintf ("crypt", "alive\n");
if (grub_file_read (ctxt->sig, &l, sizeof (l)) != sizeof (l))
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);
}
grub_dprintf ("crypt", "alive\n");
lb = (grub_be_to_cpu16 (l) + 7) / 8;
grub_dprintf ("crypt", "l = 0x%04x\n", grub_be_to_cpu16 (l));
if (lb > READBUF_SIZE - sizeof (grub_uint16_t))
goto fail;
grub_dprintf ("crypt", "alive\n");
if (grub_file_read (ctxt->sig, readbuf + sizeof (grub_uint16_t), lb) != (grub_ssize_t) lb)
goto fail;
grub_dprintf ("crypt", "alive\n");
grub_memcpy (readbuf, &l, sizeof (l));
grub_dprintf ("crypt", "alive\n");
if (gcry_mpi_scan (&mpis[i], GCRYMPI_FMT_PGP,
readbuf, lb + sizeof (grub_uint16_t), 0))
goto fail;
grub_dprintf ("crypt", "alive\n");
}
hash->final (context);
grub_dprintf ("crypt", "alive\n");
hval = hash->read (context);
if (grub_file_read (sig, hash_start, sizeof (hash_start)) != sizeof (hash_start))
if (pkey)
sk = grub_crypto_pk_locate_subkey (keyid, pkey);
else
sk = grub_crypto_pk_locate_subkey_in_trustdb (keyid);
if (!sk)
{
/* TRANSLATORS: %08x is 32-bit key id. */
grub_error (GRUB_ERR_BAD_SIGNATURE, N_("public key %08x not found"),
keyid);
goto fail;
if (grub_memcmp (hval, hash_start, sizeof (hash_start)) != 0)
}
if (pkalgos[pk].pad (&hmpi, hval, ctxt->hash, sk))
goto fail;
if (!*pkalgos[pk].algo)
{
grub_dl_load (pkalgos[pk].module);
grub_errno = GRUB_ERR_NONE;
}
if (!*pkalgos[pk].algo)
{
grub_error (GRUB_ERR_BAD_SIGNATURE, N_("module `%s' isn't loaded"),
pkalgos[pk].module);
goto fail;
}
if ((*pkalgos[pk].algo)->verify (0, hmpi, mpis, sk->mpis, 0, 0))
goto fail;
grub_dprintf ("crypt", "@ %x\n", (int)grub_file_tell (sig));
grub_free (readbuf);
for (i = 0; i < pkalgos[pk].nmpisig; i++)
{
grub_uint16_t l;
grub_size_t lb;
grub_dprintf ("crypt", "alive\n");
if (grub_file_read (sig, &l, sizeof (l)) != sizeof (l))
goto fail;
grub_dprintf ("crypt", "alive\n");
lb = (grub_be_to_cpu16 (l) + 7) / 8;
grub_dprintf ("crypt", "l = 0x%04x\n", grub_be_to_cpu16 (l));
if (lb > READBUF_SIZE - sizeof (grub_uint16_t))
goto fail;
grub_dprintf ("crypt", "alive\n");
if (grub_file_read (sig, readbuf + sizeof (grub_uint16_t), lb) != (grub_ssize_t) lb)
goto fail;
grub_dprintf ("crypt", "alive\n");
grub_memcpy (readbuf, &l, sizeof (l));
grub_dprintf ("crypt", "alive\n");
return GRUB_ERR_NONE;
if (gcry_mpi_scan (&mpis[i], GCRYMPI_FMT_PGP,
readbuf, lb + sizeof (grub_uint16_t), 0))
goto fail;
grub_dprintf ("crypt", "alive\n");
}
fail:
grub_free (readbuf);
if (!grub_errno)
return grub_error (GRUB_ERR_BAD_SIGNATURE, N_("bad signature"));
return grub_errno;
}
if (pkey)
sk = grub_crypto_pk_locate_subkey (keyid, pkey);
else
sk = grub_crypto_pk_locate_subkey_in_trustdb (keyid);
if (!sk)
{
/* TRANSLATORS: %08x is 32-bit key id. */
grub_error (GRUB_ERR_BAD_SIGNATURE, N_("public key %08x not found"),
keyid);
goto fail;
}
static void
grub_pubkey_close_real (struct grub_pubkey_context *ctxt)
{
if (ctxt->sig)
grub_file_close (ctxt->sig);
if (ctxt->hash_context)
grub_free (ctxt->hash_context);
}
if (pkalgos[pk].pad (&hmpi, hval, hash, sk))
goto fail;
if (!*pkalgos[pk].algo)
{
grub_dl_load (pkalgos[pk].module);
grub_errno = GRUB_ERR_NONE;
}
if (!*pkalgos[pk].algo)
{
grub_error (GRUB_ERR_BAD_SIGNATURE, N_("module `%s' isn't loaded"),
pkalgos[pk].module);
goto fail;
}
if ((*pkalgos[pk].algo)->verify (0, hmpi, mpis, sk->mpis, 0, 0))
goto fail;
grub_free (context);
grub_free (readbuf);
return GRUB_ERR_NONE;
fail:
grub_free (context);
grub_free (readbuf);
if (!grub_errno)
return grub_error (GRUB_ERR_BAD_SIGNATURE, N_("bad signature"));
return grub_errno;
}
static void
grub_pubkey_close (void *ctxt)
{
grub_pubkey_close_real (ctxt);
grub_free (ctxt);
}
grub_err_t
grub_verify_signature (grub_file_t f, grub_file_t sig,
struct grub_public_key *pkey)
{
return grub_verify_signature_real (0, 0, f, sig, pkey);
grub_err_t err;
struct grub_pubkey_context ctxt;
grub_uint8_t *readbuf = NULL;
err = grub_verify_signature_init (&ctxt, sig);
if (err)
return err;
readbuf = grub_zalloc (READBUF_SIZE);
if (!readbuf)
goto fail;
while (1)
{
grub_ssize_t r;
r = grub_file_read (f, readbuf, READBUF_SIZE);
if (r < 0)
goto fail;
if (r == 0)
break;
err = grub_pubkey_write (&ctxt, readbuf, r);
if (err)
return err;
}
grub_verify_signature_real (&ctxt, pkey);
fail:
grub_pubkey_close_real (&ctxt);
return grub_errno;
}
static grub_err_t
@@ -819,134 +866,52 @@ grub_cmd_verify_signature (grub_extcmd_context_t ctxt,
static int sec = 0;
static void
verified_free (grub_verified_t verified)
{
if (verified)
{
grub_free (verified->buf);
grub_free (verified);
}
}
static grub_ssize_t
verified_read (struct grub_file *file, char *buf, grub_size_t len)
{
grub_verified_t verified = file->data;
grub_memcpy (buf, (char *) verified->buf + file->offset, len);
return len;
}
static grub_err_t
verified_close (struct grub_file *file)
{
grub_verified_t verified = file->data;
grub_file_close (verified->file);
verified_free (verified);
file->data = 0;
/* device and name are freed by parent */
file->device = 0;
file->name = 0;
return grub_errno;
}
struct grub_fs verified_fs =
{
.name = "verified_read",
.read = verified_read,
.close = verified_close
};
static grub_file_t
grub_pubkey_open (grub_file_t io, enum grub_file_type type)
grub_pubkey_init (grub_file_t io, enum grub_file_type type __attribute__ ((unused)),
void **context, enum grub_verify_flags *flags)
{
grub_file_t sig;
char *fsuf, *ptr;
grub_err_t err;
grub_file_t ret;
grub_verified_t verified;
if ((type & GRUB_FILE_TYPE_MASK) == GRUB_FILE_TYPE_SIGNATURE
|| (type & GRUB_FILE_TYPE_MASK) == GRUB_FILE_TYPE_VERIFY_SIGNATURE
|| (type & GRUB_FILE_TYPE_SKIP_SIGNATURE))
return io;
if (!sec)
return io;
if (io->device->disk &&
(io->device->disk->dev->id == GRUB_DISK_DEVICE_MEMDISK_ID
|| io->device->disk->dev->id == GRUB_DISK_DEVICE_PROCFS_ID))
return io;
{
*flags = GRUB_VERIFY_FLAGS_SKIP_VERIFICATION;
return GRUB_ERR_NONE;
}
fsuf = grub_malloc (grub_strlen (io->name) + sizeof (".sig"));
if (!fsuf)
return NULL;
return grub_errno;
ptr = grub_stpcpy (fsuf, io->name);
grub_memcpy (ptr, ".sig", sizeof (".sig"));
sig = grub_file_open (fsuf, GRUB_FILE_TYPE_SIGNATURE);
grub_free (fsuf);
if (!sig)
return NULL;
return grub_errno;
ret = grub_malloc (sizeof (*ret));
if (!ret)
{
grub_free (fsuf);
return NULL;
}
*ret = *io;
ret->fs = &verified_fs;
ret->not_easily_seekable = 0;
if (ret->size >> (sizeof (grub_size_t) * GRUB_CHAR_BIT - 1))
{
grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET,
"big file signature isn't implemented yet");
grub_file_close (sig);
grub_free (ret);
return NULL;
}
verified = grub_malloc (sizeof (*verified));
if (!verified)
struct grub_pubkey_context *ctxt = grub_malloc (sizeof (*ctxt));
if (!ctxt)
{
grub_file_close (sig);
grub_free (ret);
return NULL;
return grub_errno;
}
verified->buf = grub_malloc (ret->size);
if (!verified->buf)
{
grub_file_close (sig);
verified_free (verified);
grub_free (ret);
return NULL;
}
if (grub_file_read (io, verified->buf, ret->size) != (grub_ssize_t) ret->size)
{
if (!grub_errno)
grub_error (GRUB_ERR_FILE_READ_ERROR, N_("premature end of file %s"),
io->name);
grub_file_close (sig);
verified_free (verified);
grub_free (ret);
return NULL;
}
err = grub_verify_signature_real (verified->buf, ret->size, 0, sig, NULL);
grub_file_close (sig);
err = grub_verify_signature_init (ctxt, sig);
if (err)
{
verified_free (verified);
grub_free (ret);
return NULL;
grub_pubkey_close (ctxt);
return err;
}
verified->file = io;
ret->data = verified;
return ret;
*context = ctxt;
return GRUB_ERR_NONE;
}
static grub_err_t
grub_pubkey_fini (void *ctxt)
{
return grub_verify_signature_real (ctxt, NULL);
}
static char *
@@ -970,8 +935,16 @@ struct grub_fs pseudo_fs =
{
.name = "pseudo",
.read = pseudo_read
};
};
struct grub_file_verifier grub_pubkey_verifier =
{
.name = "pgp",
.init = grub_pubkey_init,
.fini = grub_pubkey_fini,
.write = grub_pubkey_write,
.close = grub_pubkey_close,
};
static grub_extcmd_t cmd, cmd_trust;
static grub_command_t cmd_distrust, cmd_list;
@@ -986,8 +959,6 @@ GRUB_MOD_INIT(verify)
sec = 1;
else
sec = 0;
grub_file_filter_register (GRUB_FILE_FILTER_PUBKEY, grub_pubkey_open);
grub_register_variable_hook ("check_signatures", 0, grub_env_write_sec);
grub_env_export ("check_signatures");
@@ -1033,11 +1004,13 @@ GRUB_MOD_INIT(verify)
cmd_distrust = grub_register_command ("distrust", grub_cmd_distrust,
N_("PUBKEY_ID"),
N_("Remove PUBKEY_ID from trusted keys."));
grub_verifier_register (&grub_pubkey_verifier);
}
GRUB_MOD_FINI(verify)
{
grub_file_filter_unregister (GRUB_FILE_FILTER_PUBKEY);
grub_verifier_unregister (&grub_pubkey_verifier);
grub_unregister_extcmd (cmd);
grub_unregister_extcmd (cmd_trust);
grub_unregister_command (cmd_list);
+172
View File
@@ -0,0 +1,172 @@
#include <grub/file.h>
#include <grub/verify.h>
#include <grub/dl.h>
GRUB_MOD_LICENSE ("GPLv3+");
struct grub_file_verifier *grub_file_verifiers;
struct grub_verified
{
grub_file_t file;
void *buf;
};
typedef struct grub_verified *grub_verified_t;
static void
verified_free (grub_verified_t verified)
{
if (verified)
{
grub_free (verified->buf);
grub_free (verified);
}
}
static grub_ssize_t
verified_read (struct grub_file *file, char *buf, grub_size_t len)
{
grub_verified_t verified = file->data;
grub_memcpy (buf, (char *) verified->buf + file->offset, len);
return len;
}
static grub_err_t
verified_close (struct grub_file *file)
{
grub_verified_t verified = file->data;
grub_file_close (verified->file);
verified_free (verified);
file->data = 0;
/* device and name are freed by parent */
file->device = 0;
file->name = 0;
return grub_errno;
}
struct grub_fs verified_fs =
{
.name = "verified_read",
.read = verified_read,
.close = verified_close
};
static grub_file_t
grub_verify_helper_open (grub_file_t io, enum grub_file_type type)
{
grub_verified_t verified = 0;
struct grub_file_verifier *ver;
void *context;
grub_file_t ret = 0;
grub_err_t err;
if ((type & GRUB_FILE_TYPE_MASK) == GRUB_FILE_TYPE_SIGNATURE
|| (type & GRUB_FILE_TYPE_MASK) == GRUB_FILE_TYPE_VERIFY_SIGNATURE
|| (type & GRUB_FILE_TYPE_SKIP_SIGNATURE))
return io;
if (io->device->disk &&
(io->device->disk->dev->id == GRUB_DISK_DEVICE_MEMDISK_ID
|| io->device->disk->dev->id == GRUB_DISK_DEVICE_PROCFS_ID))
return io;
FOR_LIST_ELEMENTS(ver, grub_file_verifiers)
{
enum grub_verify_flags flags = 0;
err = ver->init (io, type, &context, &flags);
if (err)
goto fail_noclose;
if (!(flags & GRUB_VERIFY_FLAGS_SKIP_VERIFICATION))
break;
}
if (!ver)
/* No verifiers wanted to verify. Just return underlying file. */
return io;
ret = grub_malloc (sizeof (*ret));
if (!ret)
{
goto fail;
}
*ret = *io;
ret->fs = &verified_fs;
ret->not_easily_seekable = 0;
if (ret->size >> (sizeof (grub_size_t) * GRUB_CHAR_BIT - 1))
{
grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET,
"big file signature isn't implemented yet");
goto fail;
}
verified = grub_malloc (sizeof (*verified));
if (!verified)
{
goto fail;
}
verified->buf = grub_malloc (ret->size);
if (!verified->buf)
{
goto fail;
}
if (grub_file_read (io, verified->buf, ret->size) != (grub_ssize_t) ret->size)
{
if (!grub_errno)
grub_error (GRUB_ERR_FILE_READ_ERROR, N_("premature end of file %s"),
io->name);
goto fail;
}
err = ver->write (context, verified->buf, ret->size);
if (err)
goto fail;
err = ver->fini (context);
if (err)
goto fail;
ver->close (context);
FOR_LIST_ELEMENTS_NEXT(ver, grub_file_verifiers)
{
enum grub_verify_flags flags = 0;
err = ver->init (io, type, &context, &flags);
if (err)
goto fail_noclose;
if (flags & GRUB_VERIFY_FLAGS_SKIP_VERIFICATION)
continue;
err = ver->write (context, verified->buf, ret->size);
if (err)
goto fail;
err = ver->fini (context);
if (err)
goto fail;
ver->close (context);
}
verified->file = io;
ret->data = verified;
return ret;
fail:
ver->close (context);
fail_noclose:
verified_free (verified);
grub_free (ret);
return NULL;
}
GRUB_MOD_INIT(verify_helper)
{
grub_file_filter_register (GRUB_FILE_FILTER_VERIFY, grub_verify_helper_open);
}
GRUB_MOD_FINI(verify_helper)
{
grub_file_filter_unregister (GRUB_FILE_FILTER_VERIFY);
}