2 * GRUB -- GRand Unified Bootloader
3 * Copyright (C) 2017 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/>.
21 #include <grub/file.h>
22 #include <grub/verify.h>
25 GRUB_MOD_LICENSE ("GPLv3+");
27 struct grub_file_verifier
*grub_file_verifiers
;
34 typedef struct grub_verified
*grub_verified_t
;
37 verified_free (grub_verified_t verified
)
41 grub_free (verified
->buf
);
47 verified_read (struct grub_file
*file
, char *buf
, grub_size_t len
)
49 grub_verified_t verified
= file
->data
;
51 grub_memcpy (buf
, (char *) verified
->buf
+ file
->offset
, len
);
56 verified_close (struct grub_file
*file
)
58 grub_verified_t verified
= file
->data
;
60 grub_file_close (verified
->file
);
61 verified_free (verified
);
64 /* Device and name are freed by parent. */
71 struct grub_fs verified_fs
=
73 .name
= "verified_read",
74 .fs_read
= verified_read
,
75 .fs_close
= verified_close
79 grub_verifiers_open (grub_file_t io
, enum grub_file_type type
)
81 grub_verified_t verified
= NULL
;
82 struct grub_file_verifier
*ver
;
88 grub_dprintf ("verify", "file: %s type: %d\n", io
->name
, type
);
90 if ((type
& GRUB_FILE_TYPE_MASK
) == GRUB_FILE_TYPE_SIGNATURE
91 || (type
& GRUB_FILE_TYPE_MASK
) == GRUB_FILE_TYPE_VERIFY_SIGNATURE
92 || (type
& GRUB_FILE_TYPE_SKIP_SIGNATURE
))
95 if (io
->device
->disk
&&
96 (io
->device
->disk
->dev
->id
== GRUB_DISK_DEVICE_MEMDISK_ID
97 || io
->device
->disk
->dev
->id
== GRUB_DISK_DEVICE_PROCFS_ID
))
100 FOR_LIST_ELEMENTS(ver
, grub_file_verifiers
)
102 enum grub_verify_flags flags
= 0;
103 err
= ver
->init (io
, type
, &context
, &flags
);
106 if (flags
& GRUB_VERIFY_FLAGS_DEFER_AUTH
)
111 if (!(flags
& GRUB_VERIFY_FLAGS_SKIP_VERIFICATION
))
119 grub_error (GRUB_ERR_ACCESS_DENIED
,
120 N_("verification requested but nobody cares: %s"), io
->name
);
124 /* No verifiers wanted to verify. Just return underlying file. */
128 ret
= grub_malloc (sizeof (*ret
));
135 ret
->fs
= &verified_fs
;
136 ret
->not_easily_seekable
= 0;
137 if (ret
->size
>> (sizeof (grub_size_t
) * GRUB_CHAR_BIT
- 1))
139 grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET
,
140 N_("big file signature isn't implemented yet"));
143 verified
= grub_malloc (sizeof (*verified
));
148 verified
->buf
= grub_malloc (ret
->size
);
153 if (grub_file_read (io
, verified
->buf
, ret
->size
) != (grub_ssize_t
) ret
->size
)
156 grub_error (GRUB_ERR_FILE_READ_ERROR
, N_("premature end of file %s"),
161 err
= ver
->write (context
, verified
->buf
, ret
->size
);
165 err
= ver
->fini
? ver
->fini (context
) : GRUB_ERR_NONE
;
170 ver
->close (context
);
172 FOR_LIST_ELEMENTS_NEXT(ver
, grub_file_verifiers
)
174 enum grub_verify_flags flags
= 0;
175 err
= ver
->init (io
, type
, &context
, &flags
);
178 if (flags
& GRUB_VERIFY_FLAGS_SKIP_VERIFICATION
||
179 /* Verification done earlier. So, we are happy here. */
180 flags
& GRUB_VERIFY_FLAGS_DEFER_AUTH
)
182 err
= ver
->write (context
, verified
->buf
, ret
->size
);
186 err
= ver
->fini
? ver
->fini (context
) : GRUB_ERR_NONE
;
191 ver
->close (context
);
195 ret
->data
= verified
;
199 ver
->close (context
);
201 verified_free (verified
);
207 grub_verify_string (char *str
, enum grub_verify_string_type type
)
209 struct grub_file_verifier
*ver
;
210 FOR_LIST_ELEMENTS(ver
, grub_file_verifiers
)
213 err
= ver
->verify_string
? ver
->verify_string (str
, type
) : GRUB_ERR_NONE
;
217 return GRUB_ERR_NONE
;
220 GRUB_MOD_INIT(verifiers
)
222 grub_file_filter_register (GRUB_FILE_FILTER_VERIFY
, grub_verifiers_open
);
225 GRUB_MOD_FINI(verifiers
)
227 grub_file_filter_unregister (GRUB_FILE_FILTER_VERIFY
);