]> git.ipfire.org Git - location/libloc.git/commitdiff
database: Verify the signature using the mapped data
authorMichael Tremer <michael.tremer@ipfire.org>
Mon, 20 Jul 2026 12:31:30 +0000 (12:31 +0000)
committerMichael Tremer <michael.tremer@ipfire.org>
Mon, 20 Jul 2026 13:59:47 +0000 (13:59 +0000)
Do not alter the position of the file descriptor, we will read the
mapped data for computing the signature.

Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>
src/database.c

index 72e9e751ab94e5408fdcdb10e680b8333d708389..71801045201b7042aad62d6f89c62366c862b036 100644 (file)
@@ -585,7 +585,12 @@ LOC_EXPORT struct loc_database* loc_database_unref(struct loc_database* db) {
 }
 
 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) {
@@ -605,8 +610,6 @@ LOC_EXPORT int loc_database_verify(struct loc_database* db, FILE* f) {
                return -1;
        }
 
-       int r = 0;
-
        EVP_MD_CTX* mdctx = EVP_MD_CTX_new();
 
        // Initialise hash function
@@ -619,22 +622,11 @@ LOC_EXPORT int loc_database_verify(struct loc_database* db, FILE* f) {
                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;
@@ -642,18 +634,15 @@ LOC_EXPORT int loc_database_verify(struct loc_database* db, FILE* f) {
                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));
@@ -661,6 +650,7 @@ LOC_EXPORT int loc_database_verify(struct loc_database* db, FILE* f) {
                        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
@@ -671,6 +661,10 @@ LOC_EXPORT int loc_database_verify(struct loc_database* db, FILE* f) {
 
                                goto CLEANUP;
                        }
+
+                       // Advance the pointer
+                       p += sizeof(header_v1);
+                       l -= sizeof(header_v1);
                        break;
 
                default:
@@ -680,21 +674,13 @@ LOC_EXPORT int loc_database_verify(struct loc_database* db, FILE* f) {
                        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;