2 * GRUB -- GRand Unified Bootloader
3 * Copyright (C) 2013 Free Software Foundation, Inc.
5 * GRUB is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, either version 3 of the License, or
8 * (at your option) any later version.
10 * GRUB is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with GRUB. If not, see <http://www.gnu.org/licenses/>.
19 #include <grub/types.h>
20 #include <grub/misc.h>
24 #include <grub/file.h>
25 #include <grub/command.h>
26 #include <grub/crypto.h>
27 #include <grub/i18n.h>
28 #include <grub/gcrypt/gcrypt.h>
29 #include <grub/pubkey.h>
31 #include <grub/kernel.h>
32 #include <grub/extcmd.h>
34 GRUB_MOD_LICENSE ("GPLv3+");
41 typedef struct grub_verified
*grub_verified_t
;
48 static const struct grub_arg_option options
[] =
51 N_("Skip signature-checking of the public key file."), 0, ARG_TYPE_NONE
},
56 read_packet_header (grub_file_t sig
, grub_uint8_t
*out_type
, grub_size_t
*len
)
64 switch (grub_file_read (sig
, &type
, sizeof (type
)))
76 /* TRANSLATORS: it's about GNUPG signatures. */
77 return grub_error (GRUB_ERR_BAD_SIGNATURE
, N_("bad signature"));
87 return grub_error (GRUB_ERR_BAD_SIGNATURE
, N_("bad signature"));
90 *out_type
= (type
& 0x3f);
91 if (grub_file_read (sig
, &l
, sizeof (l
)) != 1)
92 return grub_error (GRUB_ERR_BAD_SIGNATURE
, N_("bad signature"));
100 *len
= (l
- 192) << GRUB_CHAR_BIT
;
101 if (grub_file_read (sig
, &l
, sizeof (l
)) != 1)
102 return grub_error (GRUB_ERR_BAD_SIGNATURE
, N_("bad signature"));
108 if (grub_file_read (sig
, &l32
, sizeof (l32
)) != sizeof (l32
))
109 return grub_error (GRUB_ERR_BAD_SIGNATURE
, N_("bad signature"));
110 *len
= grub_be_to_cpu32 (l32
);
113 return grub_error (GRUB_ERR_BAD_SIGNATURE
, N_("bad signature"));
115 *out_type
= ((type
>> 2) & 0xf);
119 if (grub_file_read (sig
, &l
, sizeof (l
)) != sizeof (l
))
120 return grub_error (GRUB_ERR_BAD_SIGNATURE
, N_("bad signature"));
124 if (grub_file_read (sig
, &l16
, sizeof (l16
)) != sizeof (l16
))
125 return grub_error (GRUB_ERR_BAD_SIGNATURE
, N_("bad signature"));
126 *len
= grub_be_to_cpu16 (l16
);
129 if (grub_file_read (sig
, &l32
, sizeof (l32
)) != sizeof (l32
))
130 return grub_error (GRUB_ERR_BAD_SIGNATURE
, N_("bad signature"));
131 *len
= grub_be_to_cpu32 (l32
);
134 return grub_error (GRUB_ERR_BAD_SIGNATURE
, N_("bad signature"));
137 struct signature_v4_header
140 grub_uint8_t pkeyalgo
;
142 grub_uint16_t hashed_sub
;
145 const char *hashes
[] = {
148 [0x03] = "ripemd160",
155 struct gcry_pk_spec
*grub_crypto_pk_dsa
;
156 struct gcry_pk_spec
*grub_crypto_pk_ecdsa
;
157 struct gcry_pk_spec
*grub_crypto_pk_rsa
;
160 dsa_pad (gcry_mpi_t
*hmpi
, grub_uint8_t
*hval
,
161 const gcry_md_spec_t
*hash
, struct grub_public_subkey
*sk
);
163 rsa_pad (gcry_mpi_t
*hmpi
, grub_uint8_t
*hval
,
164 const gcry_md_spec_t
*hash
, struct grub_public_subkey
*sk
);
171 struct gcry_pk_spec
**algo
;
172 int (*pad
) (gcry_mpi_t
*hmpi
, grub_uint8_t
*hval
,
173 const gcry_md_spec_t
*hash
, struct grub_public_subkey
*sk
);
177 [1] = { "rsa", 1, 2, &grub_crypto_pk_rsa
, rsa_pad
, "gcry_rsa" },
178 [3] = { "rsa", 1, 2, &grub_crypto_pk_rsa
, rsa_pad
, "gcry_rsa" },
179 [17] = { "dsa", 2, 4, &grub_crypto_pk_dsa
, dsa_pad
, "gcry_dsa" },
182 struct grub_public_key
184 struct grub_public_key
*next
;
185 struct grub_public_subkey
*subkeys
;
188 struct grub_public_subkey
190 struct grub_public_subkey
*next
;
192 grub_uint32_t fingerprint
[5];
197 free_pk (struct grub_public_key
*pk
)
199 struct grub_public_subkey
*nsk
, *sk
;
200 for (sk
= pk
->subkeys
; sk
; sk
= nsk
)
203 for (i
= 0; i
< ARRAY_SIZE (sk
->mpis
); i
++)
205 gcry_mpi_release (sk
->mpis
[i
]);
212 #define READBUF_SIZE 4096
214 struct grub_public_key
*
215 grub_load_public_key (grub_file_t f
)
218 struct grub_public_key
*ret
;
219 struct grub_public_subkey
**last
= 0;
220 void *fingerprint_context
= NULL
;
221 grub_uint8_t
*buffer
= NULL
;
223 ret
= grub_zalloc (sizeof (*ret
));
226 grub_free (fingerprint_context
);
230 buffer
= grub_zalloc (READBUF_SIZE
);
231 fingerprint_context
= grub_zalloc (GRUB_MD_SHA1
->contextsize
);
233 if (!buffer
|| !fingerprint_context
)
236 last
= &ret
->subkeys
;
243 grub_uint32_t creation_time
;
245 struct grub_public_subkey
*sk
;
247 grub_uint16_t len_be
;
249 err
= read_packet_header (f
, &type
, &len
);
257 grub_free (fingerprint_context
);
262 grub_dprintf ("crypt", "len = %x\n", (int) len
);
264 pend
= grub_file_tell (f
) + len
;
265 if (type
!= 6 && type
!= 14
266 && type
!= 5 && type
!= 7)
268 grub_file_seek (f
, pend
);
272 if (grub_file_read (f
, &v
, sizeof (v
)) != sizeof (v
))
274 grub_error (GRUB_ERR_BAD_SIGNATURE
, N_("bad signature"));
278 grub_dprintf ("crypt", "v = %x\n", v
);
282 grub_error (GRUB_ERR_BAD_SIGNATURE
, N_("bad signature"));
285 if (grub_file_read (f
, &creation_time
, sizeof (creation_time
)) != sizeof (creation_time
))
287 grub_error (GRUB_ERR_BAD_SIGNATURE
, N_("bad signature"));
291 grub_dprintf ("crypt", "time = %x\n", creation_time
);
293 if (grub_file_read (f
, &pk
, sizeof (pk
)) != sizeof (pk
))
295 grub_error (GRUB_ERR_BAD_SIGNATURE
, N_("bad signature"));
299 grub_dprintf ("crypt", "pk = %x\n", pk
);
301 if (pk
>= ARRAY_SIZE (pkalgos
) || pkalgos
[pk
].name
== NULL
)
303 grub_file_seek (f
, pend
);
307 sk
= grub_zalloc (sizeof (struct grub_public_subkey
));
311 grub_memset (fingerprint_context
, 0, GRUB_MD_SHA1
->contextsize
);
312 GRUB_MD_SHA1
->init (fingerprint_context
);
313 GRUB_MD_SHA1
->write (fingerprint_context
, "\x99", 1);
314 len_be
= grub_cpu_to_be16 (len
);
315 GRUB_MD_SHA1
->write (fingerprint_context
, &len_be
, sizeof (len_be
));
316 GRUB_MD_SHA1
->write (fingerprint_context
, &v
, sizeof (v
));
317 GRUB_MD_SHA1
->write (fingerprint_context
, &creation_time
, sizeof (creation_time
));
318 GRUB_MD_SHA1
->write (fingerprint_context
, &pk
, sizeof (pk
));
320 for (i
= 0; i
< pkalgos
[pk
].nmpipub
; i
++)
324 if (grub_file_read (f
, &l
, sizeof (l
)) != sizeof (l
))
326 grub_error (GRUB_ERR_BAD_SIGNATURE
, N_("bad signature"));
330 lb
= (grub_be_to_cpu16 (l
) + GRUB_CHAR_BIT
- 1) / GRUB_CHAR_BIT
;
331 if (lb
> READBUF_SIZE
- sizeof (grub_uint16_t
))
333 grub_error (GRUB_ERR_BAD_SIGNATURE
, N_("bad signature"));
336 if (grub_file_read (f
, buffer
+ sizeof (grub_uint16_t
), lb
) != (grub_ssize_t
) lb
)
338 grub_error (GRUB_ERR_BAD_SIGNATURE
, N_("bad signature"));
341 grub_memcpy (buffer
, &l
, sizeof (l
));
343 GRUB_MD_SHA1
->write (fingerprint_context
, buffer
, lb
+ sizeof (grub_uint16_t
));
345 if (gcry_mpi_scan (&sk
->mpis
[i
], GCRYMPI_FMT_PGP
,
346 buffer
, lb
+ sizeof (grub_uint16_t
), 0))
348 grub_error (GRUB_ERR_BAD_SIGNATURE
, N_("bad signature"));
353 GRUB_MD_SHA1
->final (fingerprint_context
);
355 grub_memcpy (sk
->fingerprint
, GRUB_MD_SHA1
->read (fingerprint_context
), 20);
360 grub_dprintf ("crypt", "actual pos: %x, expected: %x\n", (int)grub_file_tell (f
), (int)pend
);
362 grub_file_seek (f
, pend
);
366 grub_free (fingerprint_context
);
371 struct grub_public_key
*grub_pk_trusted
;
373 struct grub_public_subkey
*
374 grub_crypto_pk_locate_subkey (grub_uint64_t keyid
, struct grub_public_key
*pkey
)
376 struct grub_public_subkey
*sk
;
377 for (sk
= pkey
->subkeys
; sk
; sk
= sk
->next
)
378 if (grub_memcmp (sk
->fingerprint
+ 3, &keyid
, 8) == 0)
383 struct grub_public_subkey
*
384 grub_crypto_pk_locate_subkey_in_trustdb (grub_uint64_t keyid
)
386 struct grub_public_key
*pkey
;
387 struct grub_public_subkey
*sk
;
388 for (pkey
= grub_pk_trusted
; pkey
; pkey
= pkey
->next
)
390 sk
= grub_crypto_pk_locate_subkey (keyid
, pkey
);
399 dsa_pad (gcry_mpi_t
*hmpi
, grub_uint8_t
*hval
,
400 const gcry_md_spec_t
*hash
, struct grub_public_subkey
*sk
)
402 unsigned nbits
= gcry_mpi_get_nbits (sk
->mpis
[1]);
403 grub_dprintf ("crypt", "must be %u bits got %d bits\n", nbits
,
404 (int)(8 * hash
->mdlen
));
405 return gcry_mpi_scan (hmpi
, GCRYMPI_FMT_USG
, hval
,
406 nbits
/ 8 < (unsigned) hash
->mdlen
? nbits
/ 8
407 : (unsigned) hash
->mdlen
, 0);
411 rsa_pad (gcry_mpi_t
*hmpi
, grub_uint8_t
*hval
,
412 const gcry_md_spec_t
*hash
, struct grub_public_subkey
*sk
)
414 grub_size_t tlen
, emlen
, fflen
;
415 grub_uint8_t
*em
, *emptr
;
416 unsigned nbits
= gcry_mpi_get_nbits (sk
->mpis
[0]);
418 tlen
= hash
->mdlen
+ hash
->asnlen
;
419 emlen
= (nbits
+ 7) / 8;
420 if (emlen
< tlen
+ 11)
423 em
= grub_malloc (emlen
);
429 fflen
= emlen
- tlen
- 3;
430 for (emptr
= em
+ 2; emptr
< em
+ 2 + fflen
; emptr
++)
433 grub_memcpy (emptr
, hash
->asnoid
, hash
->asnlen
);
434 emptr
+= hash
->asnlen
;
435 grub_memcpy (emptr
, hval
, hash
->mdlen
);
437 ret
= gcry_mpi_scan (hmpi
, GCRYMPI_FMT_USG
, em
, emlen
, 0);
443 grub_verify_signature_real (char *buf
, grub_size_t size
,
444 grub_file_t f
, grub_file_t sig
,
445 struct grub_public_key
*pkey
)
452 const gcry_md_spec_t
*hash
;
453 struct signature_v4_header v4
;
459 err
= read_packet_header (sig
, &type
, &len
);
464 return grub_error (GRUB_ERR_BAD_SIGNATURE
, N_("bad signature"));
466 if (grub_file_read (sig
, &v
, sizeof (v
)) != sizeof (v
))
467 return grub_error (GRUB_ERR_BAD_SIGNATURE
, N_("bad signature"));
470 return grub_error (GRUB_ERR_BAD_SIGNATURE
, N_("bad signature"));
472 if (grub_file_read (sig
, &v4
, sizeof (v4
)) != sizeof (v4
))
473 return grub_error (GRUB_ERR_BAD_SIGNATURE
, N_("bad signature"));
480 return grub_error (GRUB_ERR_BAD_SIGNATURE
, N_("bad signature"));
482 if (h
>= ARRAY_SIZE (hashes
) || hashes
[h
] == NULL
)
483 return grub_error (GRUB_ERR_BAD_SIGNATURE
, "unknown hash");
485 if (pk
>= ARRAY_SIZE (pkalgos
) || pkalgos
[pk
].name
== NULL
)
486 return grub_error (GRUB_ERR_BAD_SIGNATURE
, N_("bad signature"));
488 hash
= grub_crypto_lookup_md_by_name (hashes
[h
]);
490 return grub_error (GRUB_ERR_BAD_SIGNATURE
, "hash `%s' not loaded", hashes
[h
]);
492 grub_dprintf ("crypt", "alive\n");
495 void *context
= NULL
;
497 grub_ssize_t rem
= grub_be_to_cpu16 (v4
.hashed_sub
);
498 grub_uint32_t headlen
= grub_cpu_to_be32 (rem
+ 6);
500 grub_uint16_t unhashed_sub
;
502 grub_uint8_t hash_start
[2];
504 grub_uint64_t keyid
= 0;
505 struct grub_public_subkey
*sk
;
506 grub_uint8_t
*readbuf
= NULL
;
508 context
= grub_zalloc (hash
->contextsize
);
509 readbuf
= grub_zalloc (READBUF_SIZE
);
510 if (!context
|| !readbuf
)
513 hash
->init (context
);
515 hash
->write (context
, buf
, size
);
519 r
= grub_file_read (f
, readbuf
, READBUF_SIZE
);
524 hash
->write (context
, readbuf
, r
);
527 hash
->write (context
, &v
, sizeof (v
));
528 hash
->write (context
, &v4
, sizeof (v4
));
531 r
= grub_file_read (sig
, readbuf
,
532 rem
< READBUF_SIZE
? rem
: READBUF_SIZE
);
537 hash
->write (context
, readbuf
, r
);
540 hash
->write (context
, &v
, sizeof (v
));
542 hash
->write (context
, &s
, sizeof (s
));
543 hash
->write (context
, &headlen
, sizeof (headlen
));
544 r
= grub_file_read (sig
, &unhashed_sub
, sizeof (unhashed_sub
));
545 if (r
!= sizeof (unhashed_sub
))
550 rem
= grub_be_to_cpu16 (unhashed_sub
);
551 if (rem
> READBUF_SIZE
)
553 r
= grub_file_read (sig
, readbuf
, rem
);
556 for (ptr
= readbuf
; ptr
< readbuf
+ rem
; ptr
+= l
)
562 if (ptr
+ 1 >= readbuf
+ rem
)
564 l
= (((ptr
[0] & ~192) << GRUB_CHAR_BIT
) | ptr
[1]) + 192;
569 if (ptr
+ 5 >= readbuf
+ rem
)
571 l
= grub_be_to_cpu32 (grub_get_unaligned32 (ptr
+ 1));
574 if (*ptr
== 0x10 && l
>= 8)
575 keyid
= grub_get_unaligned64 (ptr
+ 1);
579 hash
->final (context
);
581 grub_dprintf ("crypt", "alive\n");
583 hval
= hash
->read (context
);
585 if (grub_file_read (sig
, hash_start
, sizeof (hash_start
)) != sizeof (hash_start
))
587 if (grub_memcmp (hval
, hash_start
, sizeof (hash_start
)) != 0)
590 grub_dprintf ("crypt", "@ %x\n", (int)grub_file_tell (sig
));
592 for (i
= 0; i
< pkalgos
[pk
].nmpisig
; i
++)
596 grub_dprintf ("crypt", "alive\n");
597 if (grub_file_read (sig
, &l
, sizeof (l
)) != sizeof (l
))
599 grub_dprintf ("crypt", "alive\n");
600 lb
= (grub_be_to_cpu16 (l
) + 7) / 8;
601 grub_dprintf ("crypt", "l = 0x%04x\n", grub_be_to_cpu16 (l
));
602 if (lb
> READBUF_SIZE
- sizeof (grub_uint16_t
))
604 grub_dprintf ("crypt", "alive\n");
605 if (grub_file_read (sig
, readbuf
+ sizeof (grub_uint16_t
), lb
) != (grub_ssize_t
) lb
)
607 grub_dprintf ("crypt", "alive\n");
608 grub_memcpy (readbuf
, &l
, sizeof (l
));
609 grub_dprintf ("crypt", "alive\n");
611 if (gcry_mpi_scan (&mpis
[i
], GCRYMPI_FMT_PGP
,
612 readbuf
, lb
+ sizeof (grub_uint16_t
), 0))
614 grub_dprintf ("crypt", "alive\n");
618 sk
= grub_crypto_pk_locate_subkey (keyid
, pkey
);
620 sk
= grub_crypto_pk_locate_subkey_in_trustdb (keyid
);
623 /* TRANSLATORS: %08x is 32-bit key id. */
624 grub_error (GRUB_ERR_BAD_SIGNATURE
, N_("public key %08x not found"),
629 if (pkalgos
[pk
].pad (&hmpi
, hval
, hash
, sk
))
631 if (!*pkalgos
[pk
].algo
)
633 grub_dl_load (pkalgos
[pk
].module
);
634 grub_errno
= GRUB_ERR_NONE
;
637 if (!*pkalgos
[pk
].algo
)
639 grub_error (GRUB_ERR_BAD_SIGNATURE
, N_("module `%s' isn't loaded"),
643 if ((*pkalgos
[pk
].algo
)->verify (0, hmpi
, mpis
, sk
->mpis
, 0, 0))
649 return GRUB_ERR_NONE
;
655 return grub_error (GRUB_ERR_BAD_SIGNATURE
, N_("bad signature"));
661 grub_verify_signature (grub_file_t f
, grub_file_t sig
,
662 struct grub_public_key
*pkey
)
664 return grub_verify_signature_real (0, 0, f
, sig
, pkey
);
668 grub_cmd_trust (grub_extcmd_context_t ctxt
,
669 int argc
, char **args
)
672 struct grub_public_key
*pk
= NULL
;
675 return grub_error (GRUB_ERR_BAD_ARGUMENT
, N_("one argument expected"));
677 grub_file_filter_disable_compression ();
678 if (ctxt
->state
[OPTION_SKIP_SIG
].set
)
679 grub_file_filter_disable_pubkey ();
680 pkf
= grub_file_open (args
[0]);
683 pk
= grub_load_public_key (pkf
);
686 grub_file_close (pkf
);
689 grub_file_close (pkf
);
691 pk
->next
= grub_pk_trusted
;
692 grub_pk_trusted
= pk
;
694 return GRUB_ERR_NONE
;
698 grub_cmd_list (grub_command_t cmd
__attribute__ ((unused
)),
699 int argc
__attribute__ ((unused
)),
700 char **args
__attribute__ ((unused
)))
702 struct grub_public_key
*pk
= NULL
;
703 struct grub_public_subkey
*sk
= NULL
;
705 for (pk
= grub_pk_trusted
; pk
; pk
= pk
->next
)
706 for (sk
= pk
->subkeys
; sk
; sk
= sk
->next
)
709 for (i
= 0; i
< 20; i
+= 2)
710 grub_printf ("%02x%02x ", ((grub_uint8_t
*) sk
->fingerprint
)[i
],
711 ((grub_uint8_t
*) sk
->fingerprint
)[i
+ 1]);
715 return GRUB_ERR_NONE
;
719 grub_cmd_distrust (grub_command_t cmd
__attribute__ ((unused
)),
720 int argc
, char **args
)
722 grub_uint32_t keyid
, keyid_be
;
723 struct grub_public_key
**pkey
;
724 struct grub_public_subkey
*sk
;
727 return grub_error (GRUB_ERR_BAD_ARGUMENT
, N_("one argument expected"));
728 keyid
= grub_strtoull (args
[0], 0, 16);
731 keyid_be
= grub_cpu_to_be32 (keyid
);
733 for (pkey
= &grub_pk_trusted
; *pkey
; pkey
= &((*pkey
)->next
))
735 struct grub_public_key
*next
;
736 for (sk
= (*pkey
)->subkeys
; sk
; sk
= sk
->next
)
737 if (grub_memcmp (sk
->fingerprint
+ 4, &keyid_be
, 4) == 0)
741 next
= (*pkey
)->next
;
744 return GRUB_ERR_NONE
;
746 /* TRANSLATORS: %08x is 32-bit key id. */
747 return grub_error (GRUB_ERR_BAD_SIGNATURE
, N_("public key %08x not found"), keyid
);
751 grub_cmd_verify_signature (grub_extcmd_context_t ctxt
,
752 int argc
, char **args
)
754 grub_file_t f
= NULL
, sig
= NULL
;
755 grub_err_t err
= GRUB_ERR_NONE
;
756 struct grub_public_key
*pk
= NULL
;
758 grub_dprintf ("crypt", "alive\n");
761 return grub_error (GRUB_ERR_BAD_ARGUMENT
, N_("two arguments expected"));
763 grub_dprintf ("crypt", "alive\n");
768 grub_file_filter_disable_compression ();
769 if (ctxt
->state
[OPTION_SKIP_SIG
].set
)
770 grub_file_filter_disable_pubkey ();
771 pkf
= grub_file_open (args
[2]);
774 pk
= grub_load_public_key (pkf
);
777 grub_file_close (pkf
);
780 grub_file_close (pkf
);
783 grub_file_filter_disable_all ();
784 f
= grub_file_open (args
[0]);
791 grub_file_filter_disable_all ();
792 sig
= grub_file_open (args
[1]);
799 err
= grub_verify_signature (f
, sig
, pk
);
802 grub_file_close (sig
);
813 verified_free (grub_verified_t verified
)
817 grub_free (verified
->buf
);
818 grub_free (verified
);
823 verified_read (struct grub_file
*file
, char *buf
, grub_size_t len
)
825 grub_verified_t verified
= file
->data
;
827 grub_memcpy (buf
, (char *) verified
->buf
+ file
->offset
, len
);
832 verified_close (struct grub_file
*file
)
834 grub_verified_t verified
= file
->data
;
836 grub_file_close (verified
->file
);
837 verified_free (verified
);
840 /* device and name are freed by parent */
847 struct grub_fs verified_fs
=
849 .name
= "verified_read",
850 .read
= verified_read
,
851 .close
= verified_close
855 grub_pubkey_open (grub_file_t io
, const char *filename
)
860 grub_file_filter_t curfilt
[GRUB_FILE_FILTER_MAX
];
862 grub_verified_t verified
;
866 if (io
->device
->disk
&&
867 (io
->device
->disk
->dev
->id
== GRUB_DISK_DEVICE_MEMDISK_ID
868 || io
->device
->disk
->dev
->id
== GRUB_DISK_DEVICE_PROCFS_ID
))
870 fsuf
= grub_malloc (grub_strlen (filename
) + sizeof (".sig"));
873 ptr
= grub_stpcpy (fsuf
, filename
);
874 grub_memcpy (ptr
, ".sig", sizeof (".sig"));
876 grub_memcpy (curfilt
, grub_file_filters_enabled
,
878 grub_file_filter_disable_all ();
879 sig
= grub_file_open (fsuf
);
880 grub_memcpy (grub_file_filters_enabled
, curfilt
,
886 ret
= grub_malloc (sizeof (*ret
));
889 grub_file_close (sig
);
894 ret
->fs
= &verified_fs
;
895 ret
->not_easily_seekable
= 0;
896 if (ret
->size
>> (sizeof (grub_size_t
) * GRUB_CHAR_BIT
- 1))
898 grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET
,
899 "big file signature isn't implemented yet");
900 grub_file_close (sig
);
904 verified
= grub_malloc (sizeof (*verified
));
907 grub_file_close (sig
);
911 verified
->buf
= grub_malloc (ret
->size
);
914 grub_file_close (sig
);
915 grub_free (verified
);
919 if (grub_file_read (io
, verified
->buf
, ret
->size
) != (grub_ssize_t
) ret
->size
)
922 grub_error (GRUB_ERR_FILE_READ_ERROR
, N_("premature end of file %s"),
924 grub_file_close (sig
);
925 verified_free (verified
);
930 err
= grub_verify_signature_real (verified
->buf
, ret
->size
, 0, sig
, NULL
);
931 grub_file_close (sig
);
934 verified_free (verified
);
939 ret
->data
= verified
;
944 grub_env_write_sec (struct grub_env_var
*var
__attribute__ ((unused
)),
947 sec
= (*val
== '1') || (*val
== 'e');
948 return grub_strdup (sec
? "enforce" : "no");
952 pseudo_read (struct grub_file
*file
, char *buf
, grub_size_t len
)
954 grub_memcpy (buf
, (grub_uint8_t
*) file
->data
+ file
->offset
, len
);
959 /* Filesystem descriptor. */
960 struct grub_fs pseudo_fs
=
967 static grub_extcmd_t cmd
, cmd_trust
;
968 static grub_command_t cmd_distrust
, cmd_list
;
970 GRUB_MOD_INIT(verify
)
973 struct grub_module_header
*header
;
975 val
= grub_env_get ("check_signatures");
976 if (val
&& (val
[0] == '1' || val
[0] == 'e'))
981 grub_file_filter_register (GRUB_FILE_FILTER_PUBKEY
, grub_pubkey_open
);
983 grub_register_variable_hook ("check_signatures", 0, grub_env_write_sec
);
984 grub_env_export ("check_signatures");
989 struct grub_file pseudo_file
;
990 struct grub_public_key
*pk
= NULL
;
992 grub_memset (&pseudo_file
, 0, sizeof (pseudo_file
));
994 /* Not an ELF module, skip. */
995 if (header
->type
!= OBJ_TYPE_PUBKEY
)
998 pseudo_file
.fs
= &pseudo_fs
;
999 pseudo_file
.size
= (header
->size
- sizeof (struct grub_module_header
));
1000 pseudo_file
.data
= (char *) header
+ sizeof (struct grub_module_header
);
1002 pk
= grub_load_public_key (&pseudo_file
);
1004 grub_fatal ("error loading initial key: %s\n", grub_errmsg
);
1006 pk
->next
= grub_pk_trusted
;
1007 grub_pk_trusted
= pk
;
1011 grub_env_set ("check_signatures", grub_pk_trusted
? "enforce" : "no");
1013 cmd
= grub_register_extcmd ("verify_detached", grub_cmd_verify_signature
, 0,
1014 N_("[-s|--skip-sig] FILE SIGNATURE_FILE [PUBKEY_FILE]"),
1015 N_("Verify detached signature."),
1017 cmd_trust
= grub_register_extcmd ("trust", grub_cmd_trust
, 0,
1018 N_("[-s|--skip-sig] PUBKEY_FILE"),
1019 N_("Add PUBKEY_FILE to trusted keys."),
1021 cmd_list
= grub_register_command ("list_trusted", grub_cmd_list
,
1023 N_("Show the list of trusted keys."));
1024 cmd_distrust
= grub_register_command ("distrust", grub_cmd_distrust
,
1026 N_("Remove PUBKEY_ID from trusted keys."));
1029 GRUB_MOD_FINI(verify
)
1031 grub_file_filter_unregister (GRUB_FILE_FILTER_PUBKEY
);
1032 grub_unregister_extcmd (cmd
);
1033 grub_unregister_extcmd (cmd_trust
);
1034 grub_unregister_command (cmd_list
);
1035 grub_unregister_command (cmd_distrust
);