uri: Add checksum validation
This commit is contained in:
parent
5a6cc57773
commit
2a4cbcecc0
|
@ -33,7 +33,7 @@ extern struct volume *boot_volume;
|
|||
extern bool stage3_loaded;
|
||||
#endif
|
||||
|
||||
extern bool quiet, serial, editor_enabled;
|
||||
extern bool quiet, serial, editor_enabled, hash_mismatch_panic;
|
||||
|
||||
bool parse_resolution(size_t *width, size_t *height, size_t *bpp, const char *buf);
|
||||
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
bool verbose = false;
|
||||
bool quiet = false;
|
||||
bool serial = false;
|
||||
bool hash_mismatch_panic = false;
|
||||
|
||||
uint8_t bcd_to_int(uint8_t val) {
|
||||
return (val & 0x0f) + ((val & 0xf0) >> 4) * 10;
|
||||
|
|
|
@ -9,10 +9,13 @@
|
|||
#include <lib/print.h>
|
||||
#include <pxe/tftp.h>
|
||||
#include <tinf.h>
|
||||
#include <menu.h>
|
||||
#include <lib/readline.h>
|
||||
#include <crypt/blake2b.h>
|
||||
|
||||
// A URI takes the form of: resource://root/path
|
||||
// A URI takes the form of: resource://root/path#hash
|
||||
// The following function splits up a URI into its componenets
|
||||
bool uri_resolve(char *uri, char **resource, char **root, char **path) {
|
||||
bool uri_resolve(char *uri, char **resource, char **root, char **path, char **hash) {
|
||||
size_t length = strlen(uri) + 1;
|
||||
char *buf = ext_mem_alloc(length);
|
||||
memcpy(buf, uri, length);
|
||||
|
@ -51,6 +54,31 @@ bool uri_resolve(char *uri, char **resource, char **root, char **path) {
|
|||
return false;
|
||||
*path = uri;
|
||||
|
||||
// Get hash
|
||||
for (int i = (int)strlen(uri) - 1; i >= 0; i--) {
|
||||
if (uri[i] != '#') {
|
||||
continue;
|
||||
}
|
||||
|
||||
uri[i++] = 0;
|
||||
|
||||
if (hash != NULL) {
|
||||
*hash = uri + i;
|
||||
}
|
||||
|
||||
if (strlen(uri + i) != 128) {
|
||||
panic(true, "Blake2b hash must be 128 characters long");
|
||||
return false;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
for (size_t i = 0; ; i++) {
|
||||
if (uri[i] == 0)
|
||||
break;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -190,8 +218,10 @@ static struct file_handle *uri_boot_dispatch(char *s_part, char *path) {
|
|||
struct file_handle *uri_open(char *uri) {
|
||||
struct file_handle *ret;
|
||||
|
||||
char *resource, *root, *path;
|
||||
uri_resolve(uri, &resource, &root, &path);
|
||||
char *resource = NULL, *root = NULL, *path = NULL, *hash = NULL;
|
||||
if (!uri_resolve(uri, &resource, &root, &path, &hash)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (resource == NULL) {
|
||||
panic(true, "No resource specified for URI `%#`.", uri);
|
||||
|
@ -225,6 +255,32 @@ struct file_handle *uri_open(char *uri) {
|
|||
panic(true, "Resource `%s` not valid.", resource);
|
||||
}
|
||||
|
||||
if (hash != NULL && ret != NULL) {
|
||||
uint8_t out_buf[BLAKE2B_OUT_BYTES];
|
||||
void *file_buf = freadall(ret, MEMMAP_BOOTLOADER_RECLAIMABLE);
|
||||
blake2b(out_buf, file_buf, ret->size);
|
||||
uint8_t hash_buf[BLAKE2B_OUT_BYTES];
|
||||
|
||||
for (size_t i = 0; i < sizeof(hash_buf); i++) {
|
||||
hash_buf[i] = digit_to_int(hash[i * 2]) << 4 | digit_to_int(hash[i * 2 + 1]);
|
||||
}
|
||||
|
||||
if (memcmp(hash_buf, out_buf, sizeof(out_buf)) != 0) {
|
||||
if (hash_mismatch_panic) {
|
||||
panic(true, "Blake2b hash for URI `%#` does not match!", uri);
|
||||
} else {
|
||||
print("WARNING: Blake2b hash for URI `%#` does not match!\n"
|
||||
" Press Y to continue, press any other key otherwise...", uri);
|
||||
|
||||
char ch = getchar();
|
||||
if (ch != 'Y' && ch != 'y') {
|
||||
menu(false);
|
||||
}
|
||||
print("\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (compressed && ret != NULL) {
|
||||
struct file_handle *compressed_fd = ext_mem_alloc(sizeof(struct file_handle));
|
||||
fread(ret, &compressed_fd->size, ret->size - 4, sizeof(uint32_t));
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
#include <stdbool.h>
|
||||
#include <fs/file.h>
|
||||
|
||||
bool uri_resolve(char *uri, char **resource, char **root, char **path);
|
||||
bool uri_resolve(char *uri, char **resource, char **root, char **path, char **hash);
|
||||
struct file_handle *uri_open(char *uri);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -653,6 +653,9 @@ noreturn void _menu(bool first_run) {
|
|||
char *serial_str = config_get_value(NULL, 0, "SERIAL");
|
||||
serial = serial_str != NULL && strcmp(serial_str, "yes") == 0;
|
||||
|
||||
char *hash_mismatch_panic_str = config_get_value(NULL, 0, "HASH_MISMATCH_PANIC");
|
||||
hash_mismatch_panic = hash_mismatch_panic_str == NULL || strcmp(hash_mismatch_panic_str, "yes") == 0;
|
||||
|
||||
char *randomise_mem_str = config_get_value(NULL, 0, "RANDOMISE_MEMORY");
|
||||
if (randomise_mem_str == NULL)
|
||||
randomise_mem_str = config_get_value(NULL, 0, "RANDOMIZE_MEMORY");
|
||||
|
|
Loading…
Reference in New Issue