Commit Diff


commit - 4123af3c87c004ce1cbcb2b9e33521eb235603f1
commit + 0be5386d2f5cb3b62d4c63218734063b97053417
blob - 6a161bc20df5aaa7789395593ab2ffc6fbe4b1fb
blob + 7672f9da04d627c9c0d625a0aeafe03183f72626
--- include/got_object.h
+++ include/got_object.h
@@ -16,6 +16,11 @@
 
 #define GOT_OBJECT_ID_HEX_MAXLEN SHA1_DIGEST_STRING_LENGTH
 
+enum got_hash_algorithm {
+	GOT_HASH_SHA1,
+	GOT_HASH_SHA256,
+};
+
 struct got_object_id {
 	u_int8_t sha1[SHA1_DIGEST_LENGTH];
 };
blob - 141cb2590fa14834c63381929a0a7438ae3e4556
blob + 1be2c114d68240daa41c9b9ac210889da06b42f5
--- lib/got_lib_hash.h
+++ lib/got_lib_hash.h
@@ -15,7 +15,14 @@
  */
 
 #define GOT_SHA1_STRING_ZERO "0000000000000000000000000000000000000000"
+#define GOT_SHA256_STRING_ZERO "0000000000000000000000000000000000000000000000000000000000000000"
 
 int got_parse_xdigit(uint8_t *, const char *);
+
 int got_parse_sha1_digest(uint8_t *, const char *);
 char *got_sha1_digest_to_str(const uint8_t *, char *, size_t);
+
+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);
blob - fb4d3a30adf9281507aea3424f4c2711b1d3a28c
blob + 12bba1c67ab7760ff6e537cfc5be4af481afd7ee
--- lib/hash.c
+++ lib/hash.c
@@ -15,6 +15,8 @@
  */
 
 #include <sys/types.h>
+#include <sys/queue.h>
+
 #include <sha1.h>
 #include <sha2.h>
 #include <errno.h>
@@ -22,6 +24,8 @@
 #include <stdlib.h>
 #include <limits.h>
 
+#include "got_object.h"
+
 #include "got_lib_hash.h"
 
 int
@@ -83,3 +87,60 @@ got_sha1_digest_to_str(const uint8_t *digest, char *bu
 
 	return buf;
 }
+
+int
+got_parse_sha256_digest(uint8_t *digest, const char *line)
+{
+	uint8_t b = 0;
+	char hex[3] = {'\0', '\0', '\0'};
+	int i, j;
+
+	for (i = 0; i < SHA256_DIGEST_LENGTH; i++) {
+		if (line[0] == '\0' || line[1] == '\0')
+			return 0;
+		for (j = 0; j < 2; j++) {
+			hex[j] = *line;
+			line++;
+		}
+		if (!got_parse_xdigit(&b, hex))
+			return 0;
+		digest[i] = b;
+	}
+
+	return 1;
+}
+
+char *
+got_sha256_digest_to_str(const uint8_t *digest, char *buf, size_t size)
+{
+	char *p = buf;
+	char hex[3];
+	int i;
+
+	if (size < SHA256_DIGEST_STRING_LENGTH)
+		return NULL;
+
+	for (i = 0; i < SHA256_DIGEST_LENGTH; i++) {
+		snprintf(hex, sizeof(hex), "%.2x", digest[i]);
+		p[0] = hex[0];
+		p[1] = hex[1];
+		p += 2;
+	}
+	p[0] = '\0';
+
+	return buf;
+}
+
+int
+got_parse_hash_digest(uint8_t *digest, const char *line,
+    enum got_hash_algorithm algo)
+{
+	switch (algo) {
+	case GOT_HASH_SHA1:
+		return got_parse_sha1_digest(digest, line);
+	case GOT_HASH_SHA256:
+		return got_parse_sha256_digest(digest, line);
+	default:
+		return 0;
+	}
+}
blob - 67c3bc37ea78571d6f3c25478ae3e612ee235f22
blob + daec14e2a587f99d1ec39131795c9a0f39b2d29b
--- lib/object_parse.c
+++ lib/object_parse.c
@@ -620,6 +620,7 @@ got_object_parse_commit(struct got_commit_object **com
     size_t len)
 {
 	const struct got_error *err = NULL;
+	enum got_hash_algorithm algo = GOT_HASH_SHA1;
 	char *s = buf;
 	size_t label_len;
 	ssize_t remain = (ssize_t)len;
@@ -639,7 +640,7 @@ got_object_parse_commit(struct got_commit_object **com
 			goto done;
 		}
 		s += label_len;
-		if (!got_parse_sha1_digest((*commit)->tree_id->sha1, s)) {
+		if (!got_parse_hash_digest((*commit)->tree_id->sha1, s, algo)) {
 			err = got_error(GOT_ERR_BAD_OBJ_DATA);
 			goto done;
 		}
@@ -974,6 +975,7 @@ const struct got_error *
 got_object_parse_tag(struct got_tag_object **tag, uint8_t *buf, size_t len)
 {
 	const struct got_error *err = NULL;
+	enum got_hash_algorithm algo = GOT_HASH_SHA1;
 	size_t remain = len;
 	char *s = buf;
 	size_t label_len;
@@ -993,7 +995,7 @@ got_object_parse_tag(struct got_tag_object **tag, uint
 			goto done;
 		}
 		s += label_len;
-		if (!got_parse_sha1_digest((*tag)->id.sha1, s)) {
+		if (!got_parse_hash_digest((*tag)->id.sha1, s, algo)) {
 			err = got_error(GOT_ERR_BAD_OBJ_DATA);
 			goto done;
 		}
blob - b7e19bcfc7a34cea70cf48a5c32ab66ee4acb857
blob + 822d23e36daa2ec8baf6ed8a425b1b3982747390
--- lib/reference.c
+++ lib/reference.c
@@ -155,6 +155,7 @@ static const struct got_error *
 parse_ref_line(struct got_reference **ref, const char *name, const char *line,
     time_t mtime)
 {
+	enum got_hash_algorithm algo = GOT_HASH_SHA1;
 	struct got_object_id id;
 
 	if (strncmp(line, "ref: ", 5) == 0) {
@@ -162,7 +163,7 @@ parse_ref_line(struct got_reference **ref, const char 
 		return parse_symref(ref, name, line);
 	}
 
-	if (!got_parse_sha1_digest(id.sha1, line))
+	if (!got_parse_hash_digest(id.sha1, line, algo))
 		return got_error(GOT_ERR_BAD_REF_DATA);
 
 	return alloc_ref(ref, name, &id, 0, mtime);
@@ -292,6 +293,7 @@ static const struct got_error *
 parse_packed_ref_line(struct got_reference **ref, const char *abs_refname,
     const char *line, time_t mtime)
 {
+	enum got_hash_algorithm algo = GOT_HASH_SHA1;
 	struct got_object_id id;
 	const char *name;
 
@@ -300,7 +302,7 @@ parse_packed_ref_line(struct got_reference **ref, cons
 	if (line[0] == '#' || line[0] == '^')
 		return NULL;
 
-	if (!got_parse_sha1_digest(id.sha1, line))
+	if (!got_parse_hash_digest(id.sha1, line, algo))
 		return got_error(GOT_ERR_BAD_REF_DATA);
 
 	if (abs_refname) {
blob - abff91e2c234cdd1c87f05d07d2a9d02a0cc98e4
blob + 7557fdbf38bd4ea36129a027cef620639766bd8d
--- lib/repository.c
+++ lib/repository.c
@@ -1738,6 +1738,7 @@ match_loose_object(struct got_object_id **unique_id, c
 	}
 	while ((dent = readdir(dir)) != NULL) {
 		int cmp;
+		enum got_hash_algorithm algo = GOT_HASH_SHA1;
 
 		free(id_str);
 		id_str = NULL;
@@ -1751,7 +1752,7 @@ match_loose_object(struct got_object_id **unique_id, c
 			goto done;
 		}
 
-		if (!got_parse_sha1_digest(id.sha1, id_str))
+		if (!got_parse_hash_digest(id.sha1, id_str, algo))
 			continue;
 
 		/*
@@ -2291,6 +2292,7 @@ got_repo_get_loose_object_info(int *nobjects, off_t *o
 			char *id_str;
 			int fd;
 			struct stat sb;
+			enum got_hash_algorithm algo = GOT_HASH_SHA1;
 
 			if (strcmp(dent->d_name, ".") == 0 ||
 			    strcmp(dent->d_name, "..") == 0)
@@ -2301,7 +2303,7 @@ got_repo_get_loose_object_info(int *nobjects, off_t *o
 				goto done;
 			}
 
-			if (!got_parse_sha1_digest(id.sha1, id_str)) {
+			if (!got_parse_hash_digest(id.sha1, id_str, algo)) {
 				free(id_str);
 				continue;
 			}
blob - eba5987fa2e3e7da18812041236ffef62f62f1c2
blob + 9f47cd62da86a7219a88652640b642fbcc8aa43b
--- lib/serve.c
+++ lib/serve.c
@@ -36,6 +36,7 @@
 #include "got_path.h"
 #include "got_version.h"
 #include "got_reference.h"
+#include "got_object.h"
 
 #include "got_lib_pkt.h"
 #include "got_lib_dial.h"