verify pack file index checksum
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113
diff --git a/include/got_error.h b/include/got_error.h
index fbfadea..79deadb 100644
--- a/include/got_error.h
+++ b/include/got_error.h
@@ -30,6 +30,7 @@
#define GOT_ERR_BAD_OBJ_DATA 0x0012
#define GOT_ERR_FILE_OPEN 0x0013
#define GOT_ERR_BAD_PACKIDX 0x0014
+#define GOT_ERR_PACKIDX_CSUM 0x0015
static const struct got_error {
int code;
@@ -50,6 +51,7 @@ static const struct got_error {
{ GOT_ERR_BAD_OBJ_DATA, "bad object data" },
{ GOT_ERR_FILE_OPEN, "could not open file" },
{ GOT_ERR_BAD_PACKIDX, "bad pack index file" },
+ { GOT_ERR_PACKIDX_CSUM, "pack index file checksum error" },
};
const struct got_error * got_error(int code);
diff --git a/lib/pack.c b/lib/pack.c
index f8e642d..78231e4 100644
--- a/lib/pack.c
+++ b/lib/pack.c
@@ -75,6 +75,10 @@ got_packidx_open(struct got_packidx_v2_hdr **packidx, const char *path)
FILE *f;
const struct got_error *err = NULL;
size_t n, nobj, packfile_size;
+ SHA1_CTX ctx;
+ uint8_t sha1[SHA1_DIGEST_LENGTH];
+
+ SHA1Init(&ctx);
f = fopen(path, "rb");
if (f == NULL)
@@ -101,6 +105,8 @@ got_packidx_open(struct got_packidx_v2_hdr **packidx, const char *path)
goto done;
}
+ SHA1Update(&ctx, (uint8_t *)&p->magic, sizeof(p->magic));
+
n = fread(&p->version, sizeof(p->version), 1, f);
if (n != 1) {
err = got_error(ferror(f) ? GOT_ERR_IO : GOT_ERR_BAD_PACKIDX);
@@ -112,6 +118,8 @@ got_packidx_open(struct got_packidx_v2_hdr **packidx, const char *path)
goto done;
}
+ SHA1Update(&ctx, (uint8_t *)&p->version, sizeof(p->version));
+
n = fread(&p->fanout_table, sizeof(p->fanout_table), 1, f);
if (n != 1) {
err = got_error(ferror(f) ? GOT_ERR_IO : GOT_ERR_BAD_PACKIDX);
@@ -122,6 +130,8 @@ got_packidx_open(struct got_packidx_v2_hdr **packidx, const char *path)
if (err)
goto done;
+ SHA1Update(&ctx, (uint8_t *)p->fanout_table, sizeof(p->fanout_table));
+
nobj = betoh32(p->fanout_table[0xff]);
p->sorted_ids = calloc(nobj, sizeof(*p->sorted_ids));
@@ -136,6 +146,9 @@ got_packidx_open(struct got_packidx_v2_hdr **packidx, const char *path)
goto done;
}
+ SHA1Update(&ctx, (uint8_t *)p->sorted_ids,
+ nobj * sizeof(*p->sorted_ids));
+
p->offsets = calloc(nobj, sizeof(*p->offsets));
if (p->offsets == NULL) {
err = got_error(GOT_ERR_NO_MEM);
@@ -148,6 +161,8 @@ got_packidx_open(struct got_packidx_v2_hdr **packidx, const char *path)
goto done;
}
+ SHA1Update(&ctx, (uint8_t *)p->offsets, nobj * sizeof(*p->offsets));
+
p->crc32 = calloc(nobj, sizeof(*p->crc32));
if (p->crc32 == NULL) {
err = got_error(GOT_ERR_NO_MEM);
@@ -160,6 +175,8 @@ got_packidx_open(struct got_packidx_v2_hdr **packidx, const char *path)
goto done;
}
+ SHA1Update(&ctx, (uint8_t *)p->crc32, nobj * sizeof(*p->crc32));
+
/* Large file offsets are contained only in files > 2GB. */
if (packfile_size <= 0x80000000)
goto checksum;
@@ -176,6 +193,9 @@ got_packidx_open(struct got_packidx_v2_hdr **packidx, const char *path)
goto done;
}
+ SHA1Update(&ctx, (uint8_t*)p->large_offsets,
+ nobj * sizeof(*p->large_offsets));
+
checksum:
n = fread(&p->trailer, sizeof(p->trailer), 1, f);
@@ -184,8 +204,10 @@ checksum:
goto done;
}
- /* TODO verify checksum */
-
+ SHA1Update(&ctx, p->trailer.pack_file_sha1, SHA1_DIGEST_LENGTH);
+ SHA1Final(sha1, &ctx);
+ if (memcmp(p->trailer.pack_idx_sha1, sha1, SHA1_DIGEST_LENGTH) != 0)
+ err = got_error(GOT_ERR_PACKIDX_CSUM);
done:
fclose(f);
if (err)