commit 0ebaf0082bfd162e1116889d2b13917efd07d317 from: Stefan Sperling date: Wed Jan 10 20:56:48 2018 UTC verify pack file index checksum commit - b0517dd07105250eb20b57d704d7102f6e4ab18d commit + 0ebaf0082bfd162e1116889d2b13917efd07d317 blob - fbfadeadba8f2824dfcfeb5129b026e607a5e8cb blob + 79deadb93b5f53f5dc7e8ed1b432d74c47ed11e5 --- include/got_error.h +++ 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); blob - f8e642d69cca526a214c92952dda158087d31ad0 blob + 78231e44a41aad957280e0ca742fcd2ac4650539 --- lib/pack.c +++ lib/pack.c @@ -75,7 +75,11 @@ got_packidx_open(struct got_packidx_v2_hdr **packidx, 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) return got_error(GOT_ERR_BAD_PATH); @@ -101,6 +105,8 @@ got_packidx_open(struct got_packidx_v2_hdr **packidx, 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, 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, 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, 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, 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, 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, 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)