Commit Diff


commit - 0be5386d2f5cb3b62d4c63218734063b97053417
commit + 3f81ccbdc1260ec6bd1465a10f6cc3a530a991b3
blob - 7672f9da04d627c9c0d625a0aeafe03183f72626
blob + 7941cebcee734db2de13f407678a3b740f02ca32
--- include/got_object.h
+++ include/got_object.h
@@ -14,6 +14,7 @@
  * 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
@@ -26,3 +26,22 @@ int got_parse_sha256_digest(uint8_t *, const char *);
 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
@@ -22,6 +22,7 @@
 #include <errno.h>
 #include <stdio.h>
 #include <stdlib.h>
+#include <string.h>
 #include <limits.h>
 
 #include "got_object.h"
@@ -144,3 +145,43 @@ got_parse_hash_digest(uint8_t *digest, const char *lin
 		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
@@ -74,14 +74,15 @@ const struct got_error *
 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;
@@ -116,7 +117,7 @@ got_packidx_init_hdr(struct got_packidx *p, int verify
 	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);
@@ -147,7 +148,7 @@ got_packidx_init_hdr(struct got_packidx *p, int verify
 	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;
@@ -176,7 +177,7 @@ got_packidx_init_hdr(struct got_packidx *p, int verify
 	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;
 
@@ -204,7 +205,7 @@ got_packidx_init_hdr(struct got_packidx *p, int verify
 		}
 	}
 	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;
 
@@ -229,7 +230,7 @@ got_packidx_init_hdr(struct got_packidx *p, int verify
 		}
 	}
 	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);
 
@@ -254,8 +255,7 @@ got_packidx_init_hdr(struct got_packidx *p, int verify
 		}
 	}
 	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);
 
@@ -297,7 +297,7 @@ got_packidx_init_hdr(struct got_packidx *p, int verify
 		}
 	}
 	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);
@@ -325,10 +325,10 @@ checksum:
 		}
 	}
 	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: