}
LOC_EXPORT int loc_database_verify(struct loc_database* db, FILE* f) {
- size_t bytes_read = 0;
+ const struct loc_database_magic* magic =
+ (const struct loc_database_magic*)db->data;
+ struct loc_database_header_v1 header_v1 = {};
+ char* p = db->data;
+ size_t l = db->length;
+ int r;
// Cannot do this when no signature is available
if (!db->signature1.data && !db->signature2.data) {
return -1;
}
- int r = 0;
-
EVP_MD_CTX* mdctx = EVP_MD_CTX_new();
// Initialise hash function
goto CLEANUP;
}
- // Reset file to start
- rewind(db->f);
-
- // Read magic
- struct loc_database_magic magic;
- bytes_read = fread(&magic, 1, sizeof(magic), db->f);
- if (bytes_read < sizeof(magic)) {
- ERROR(db->ctx, "Could not read header: %m\n");
- r = 1;
- goto CLEANUP;
- }
-
- hexdump(db->ctx, &magic, sizeof(magic));
+ // Dump the magic
+ hexdump(db->ctx, magic, sizeof(*magic));
// Feed magic into the hash
- r = EVP_DigestVerifyUpdate(mdctx, &magic, sizeof(magic));
+ r = EVP_DigestVerifyUpdate(mdctx, magic, sizeof(*magic));
if (r != 1) {
ERROR(db->ctx, "%s\n", ERR_error_string(ERR_get_error(), NULL));
r = 1;
goto CLEANUP;
}
- // Read the header
- struct loc_database_header_v1 header_v1;
+ // Advance the pointer
+ p += sizeof(*magic);
+ l -= sizeof(*magic);
+ // Read the header
switch (db->version) {
case LOC_DATABASE_VERSION_1:
- bytes_read = fread(&header_v1, 1, sizeof(header_v1), db->f);
- if (bytes_read < sizeof(header_v1)) {
- ERROR(db->ctx, "Could not read header\n");
- r = 1;
-
- goto CLEANUP;
- }
+ // Copy the header so that we can clear the signatures
+ memcpy(&header_v1, db->data + sizeof(*magic), sizeof(header_v1));
// Clear signatures
memset(header_v1.signature1, '\0', sizeof(header_v1.signature1));
memset(header_v1.signature2, '\0', sizeof(header_v1.signature2));
header_v1.signature2_length = 0;
+ // Dump the header
hexdump(db->ctx, &header_v1, sizeof(header_v1));
// Feed header into the hash
goto CLEANUP;
}
+
+ // Advance the pointer
+ p += sizeof(header_v1);
+ l -= sizeof(header_v1);
break;
default:
goto CLEANUP;
}
- // Walk through the file in chunks of 64kB
- char buffer[64 * 1024];
-
- while (!feof(db->f)) {
- bytes_read = fread(buffer, 1, sizeof(buffer), db->f);
-
- hexdump(db->ctx, buffer, bytes_read);
-
- r = EVP_DigestVerifyUpdate(mdctx, buffer, bytes_read);
- if (r != 1) {
- ERROR(db->ctx, "%s\n", ERR_error_string(ERR_get_error(), NULL));
- r = 1;
+ // Hash the rest of the payload
+ r = EVP_DigestVerifyUpdate(mdctx, p, l);
+ if (r != 1) {
+ ERROR(db->ctx, "%s\n", ERR_error_string(ERR_get_error(), NULL));
+ r = 1;
- goto CLEANUP;
- }
+ goto CLEANUP;
}
int sig1_valid = 0;