1#include "cache.h"
2#include "pack.h"
3
4static int verify_packfile(struct packed_git *p)
5{
6 unsigned long index_size = p->index_size;
7 void *index_base = p->index_base;
8 SHA_CTX ctx;
9 unsigned char sha1[20];
10 unsigned long pack_size = p->pack_size;
11 void *pack_base;
12 struct pack_header *hdr;
13 int nr_objects;
14
15 hdr = p->pack_base;
16 if (hdr->hdr_signature != htonl(PACK_SIGNATURE))
17 return error("Packfile signature mismatch", p->pack_name);
18 if (hdr->hdr_version != htonl(PACK_VERSION))
19 return error("Packfile version %d different from ours %d",
20 ntohl(hdr->hdr_version), PACK_VERSION);
21 nr_objects = ntohl(hdr->hdr_entries);
22 if (num_packed_objects(p) != nr_objects)
23 return error("Packfile claims to have %d objects, "
24 "while idx size expects %d", nr_objects,
25 num_packed_objects(p));
26
27 SHA1_Init(&ctx);
28 pack_base = p->pack_base;
29 SHA1_Update(&ctx, pack_base, pack_size - 20);
30 SHA1_Final(sha1, &ctx);
31 if (memcmp(sha1, index_base + index_size - 40, 20))
32 return error("Packfile %s SHA1 mismatch with idx",
33 p->pack_name);
34 if (memcmp(sha1, pack_base + pack_size - 20, 20))
35 return error("Packfile %s SHA1 mismatch with itself",
36 p->pack_name);
37 return 0;
38}
39
40
41int verify_pack(struct packed_git *p)
42{
43 unsigned long index_size = p->index_size;
44 void *index_base = p->index_base;
45 SHA_CTX ctx;
46 unsigned char sha1[20];
47 int ret;
48
49 /* Verify SHA1 sum of the index file */
50 SHA1_Init(&ctx);
51 SHA1_Update(&ctx, index_base, index_size - 20);
52 SHA1_Final(sha1, &ctx);
53 if (memcmp(sha1, index_base + index_size - 20, 20))
54 return error("Packfile index for %s SHA1 mismatch",
55 p->pack_name);
56
57 /* Verify pack file */
58 use_packed_git(p);
59 ret = verify_packfile(p);
60 unuse_packed_git(p);
61 return ret;
62}