commit - 0be5386d2f5cb3b62d4c63218734063b97053417
commit + 3f81ccbdc1260ec6bd1465a10f6cc3a530a991b3
blob - 7672f9da04d627c9c0d625a0aeafe03183f72626
blob + 7941cebcee734db2de13f407678a3b740f02ca32
--- include/got_object.h
+++ include/got_object.h
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
+#define GOT_OBJECT_ID_MAXLEN SHA256_DIGEST_LENGTH
#define GOT_OBJECT_ID_HEX_MAXLEN SHA1_DIGEST_STRING_LENGTH
enum got_hash_algorithm {
blob - 1be2c114d68240daa41c9b9ac210889da06b42f5
blob + c70734016d6453f21cfe4275495824160a6b0fd2
--- lib/got_lib_hash.h
+++ lib/got_lib_hash.h
char *got_sha256_digest_to_str(const uint8_t *, char *, size_t);
int got_parse_hash_digest(uint8_t *, const char *, enum got_hash_algorithm);
+
+struct got_hash {
+ SHA1_CTX sha1_ctx;
+ SHA2_CTX sha256_ctx;
+ enum got_hash_algorithm algo;
+};
+
+/*
+ * These functions allow to compute and check hashes.
+ * The hash function used is specified during got_hash_init.
+ * Data can be added with got_hash_update and, once done, the checksum
+ * can be obtained with got_hash_final; its output buffer must be at
+ * least GOT_OBJECT_ID_MAXLEN bytes.
+ * got_hash_cmp is like memcmp() and compares two hash digests.
+ */
+void got_hash_init(struct got_hash *, enum got_hash_algorithm);
+void got_hash_update(struct got_hash *, const void *, size_t);
+void got_hash_final(struct got_hash *, uint8_t *);
+int got_hash_cmp(struct got_hash *, uint8_t *, uint8_t *);
blob - 12bba1c67ab7760ff6e537cfc5be4af481afd7ee
blob + 21a5c5b28f97a2360115141697b94ec051b7d467
--- lib/hash.c
+++ lib/hash.c
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
+#include <string.h>
#include <limits.h>
#include "got_object.h"
return 0;
}
}
+
+void
+got_hash_init(struct got_hash *hash, enum got_hash_algorithm algo)
+{
+ memset(hash, 0, sizeof(*hash));
+ hash->algo = algo;
+
+ if (algo == GOT_HASH_SHA1)
+ SHA1Init(&hash->sha1_ctx);
+ else if (algo == GOT_HASH_SHA256)
+ SHA256Init(&hash->sha256_ctx);
+}
+
+void
+got_hash_update(struct got_hash *hash, const void *data, size_t len)
+{
+ if (hash->algo == GOT_HASH_SHA1)
+ SHA1Update(&hash->sha1_ctx, data, len);
+ else if (hash->algo == GOT_HASH_SHA256)
+ SHA256Update(&hash->sha256_ctx, data, len);
+}
+
+void
+got_hash_final(struct got_hash *hash, uint8_t *out)
+{
+ if (hash->algo == GOT_HASH_SHA1)
+ SHA1Final(out, &hash->sha1_ctx);
+ else if (hash->algo == GOT_HASH_SHA256)
+ SHA256Final(out, &hash->sha256_ctx);
+}
+
+int
+got_hash_cmp(struct got_hash *hash, uint8_t *orig, uint8_t *target)
+{
+ if (hash->algo == GOT_HASH_SHA1)
+ return memcmp(orig, target, SHA1_DIGEST_LENGTH);
+ else if (hash->algo == GOT_HASH_SHA256)
+ return memcmp(orig, target, SHA256_DIGEST_LENGTH);
+ return -1;
+}
blob - d520044fc04a93dd4f53e69a52edbdca55554921
blob + 2a89d71d16ccc445d75c986691f8a7d73085ab30
--- lib/pack.c
+++ lib/pack.c
got_packidx_init_hdr(struct got_packidx *p, int verify, off_t packfile_size)
{
const struct got_error *err = NULL;
+ enum got_hash_algorithm algo = GOT_HASH_SHA1;
struct got_packidx_v2_hdr *h;
- SHA1_CTX ctx;
- uint8_t sha1[SHA1_DIGEST_LENGTH];
+ struct got_hash ctx;
+ uint8_t hash[GOT_OBJECT_ID_MAXLEN];
size_t nobj, len_fanout, len_ids, offset, remain;
ssize_t n;
int i;
- SHA1Init(&ctx);
+ got_hash_init(&ctx, algo);
h = &p->hdr;
offset = 0;
remain -= sizeof(*h->magic);
if (verify)
- SHA1Update(&ctx, (uint8_t *)h->magic, sizeof(*h->magic));
+ got_hash_update(&ctx, h->magic, sizeof(*h->magic));
if (remain < sizeof(*h->version)) {
err = got_error(GOT_ERR_BAD_PACKIDX);
remain -= sizeof(*h->version);
if (verify)
- SHA1Update(&ctx, (uint8_t *)h->version, sizeof(*h->version));
+ got_hash_update(&ctx, h->version, sizeof(*h->version));
len_fanout =
sizeof(*h->fanout_table) * GOT_PACKIDX_V2_FANOUT_TABLE_ITEMS;
if (err)
goto done;
if (verify)
- SHA1Update(&ctx, (uint8_t *)h->fanout_table, len_fanout);
+ got_hash_update(&ctx, h->fanout_table, len_fanout);
offset += len_fanout;
remain -= len_fanout;
}
}
if (verify)
- SHA1Update(&ctx, (uint8_t *)h->sorted_ids, len_ids);
+ got_hash_update(&ctx, h->sorted_ids, len_ids);
offset += len_ids;
remain -= len_ids;
}
}
if (verify)
- SHA1Update(&ctx, (uint8_t *)h->crc32, nobj * sizeof(*h->crc32));
+ got_hash_update(&ctx, h->crc32, nobj * sizeof(*h->crc32));
remain -= nobj * sizeof(*h->crc32);
offset += nobj * sizeof(*h->crc32);
}
}
if (verify)
- SHA1Update(&ctx, (uint8_t *)h->offsets,
- nobj * sizeof(*h->offsets));
+ got_hash_update(&ctx, h->offsets, nobj * sizeof(*h->offsets));
remain -= nobj * sizeof(*h->offsets);
offset += nobj * sizeof(*h->offsets);
}
}
if (verify)
- SHA1Update(&ctx, (uint8_t*)h->large_offsets,
+ got_hash_update(&ctx, h->large_offsets,
p->nlargeobj * sizeof(*h->large_offsets));
remain -= p->nlargeobj * sizeof(*h->large_offsets);
offset += p->nlargeobj * sizeof(*h->large_offsets);
}
}
if (verify) {
- SHA1Update(&ctx, h->trailer->packfile_sha1, SHA1_DIGEST_LENGTH);
- SHA1Final(sha1, &ctx);
- if (memcmp(h->trailer->packidx_sha1, sha1,
- SHA1_DIGEST_LENGTH) != 0)
+ got_hash_update(&ctx, h->trailer->packfile_sha1,
+ SHA1_DIGEST_LENGTH);
+ got_hash_final(&ctx, hash);
+ if (got_hash_cmp(&ctx, hash, h->trailer->packidx_sha1) != 0)
err = got_error(GOT_ERR_PACKIDX_CSUM);
}
done: