commit a1f06df2e1e5a293a55ebaf1b6707de629843295 from: Omar Polo date: Sat Feb 04 14:01:14 2023 UTC stuff to get `got log -p' working commit - 6583092f7f08b82a9004b2cb84625d3a74f6add6 commit + a1f06df2e1e5a293a55ebaf1b6707de629843295 blob - 4bb7ecf2163c2d7807d4697feab533b7c1e26e1a blob + ad55ae60228e6f5628adae6d65087eb9de3ef68e --- lib/got_lib_object_parse.h +++ lib/got_lib_object_parse.h @@ -37,14 +37,15 @@ struct got_parsed_tree_entry { size_t namelen; /* strlen(name) */ mode_t mode; /* Mode parsed from tree buffer. */ uint8_t *id; /* Points to ID in parsed tree buffer. */ + size_t idlen; }; const struct got_error *got_object_parse_tree(struct got_parsed_tree_entry **, - size_t *, size_t *, uint8_t *, size_t); + size_t *, size_t *, uint8_t *, size_t, int); const struct got_error *got_object_read_tree(struct got_parsed_tree_entry **, size_t *, size_t *, uint8_t **, int, struct got_object_id *); const struct got_error *got_object_parse_tag(struct got_tag_object **, - uint8_t *, size_t); + uint8_t *, size_t, int); const struct got_error *got_object_read_tag(struct got_tag_object **, int, struct got_object_id *, size_t); const struct got_error *got_read_file_to_mem(uint8_t **, size_t *, FILE *); blob - 1b4b7bc8fc2baddfd1f3353725f35bd6ac9af0cf blob + 47d4a6408bd84242ec7ee5ee332f7379c9893a74 --- lib/got_lib_privsep.h +++ lib/got_lib_privsep.h @@ -256,7 +256,8 @@ struct got_imsg_commit_object { } __attribute__((__packed__)); struct got_imsg_tree_entry { - char id[SHA1_DIGEST_LENGTH]; + char id[SHA256_DIGEST_LENGTH]; + int algo; mode_t mode; size_t namelen; /* Followed by namelen bytes of entry's name, not NUL-terminated. */ blob - 0e0092a04fcb2d9a40bcfacc9cfbd86fc7d919cb blob + 74cd39adeed51e4d24a86b74d1072ef84947a588 --- lib/object_parse.c +++ lib/object_parse.c @@ -297,18 +297,26 @@ got_object_read_raw(uint8_t **outbuf, off_t *size, siz const struct got_error *err = NULL; struct got_object *obj; struct got_inflate_checksum csum; + uint8_t sha256[SHA256_DIGEST_LENGTH]; + SHA2_CTX sha256_ctx; uint8_t sha1[SHA1_DIGEST_LENGTH]; SHA1_CTX sha1_ctx; size_t len, consumed; FILE *f = NULL; + int r; *outbuf = NULL; *size = 0; *hdrlen = 0; - SHA1Init(&sha1_ctx); - memset(&csum, 0, sizeof(csum)); - csum.output_sha1 = &sha1_ctx; + memset(&csum, 0, sizeof(csum)); + if (expected_id->algo == GOT_HASH_SHA256) { + SHA256Init(&sha256_ctx); + csum.output_sha256 = &sha256_ctx; + } else { + SHA1Init(&sha1_ctx); + csum.output_sha1 = &sha1_ctx; + } if (lseek(infd, SEEK_SET, 0) == -1) return got_error_from_errno("lseek"); @@ -349,8 +357,15 @@ got_object_read_raw(uint8_t **outbuf, off_t *size, siz goto done; } - SHA1Final(sha1, &sha1_ctx); - if (memcmp(expected_id->hash, sha1, SHA1_DIGEST_LENGTH) != 0) { + if (expected_id->algo == GOT_HASH_SHA256) { + SHA256Final(sha256, &sha256_ctx); + r = memcmp(expected_id->hash, sha256, sizeof(sha256)); + } else { + SHA1Final(sha1, &sha1_ctx); + r = memcmp(expected_id->hash, sha1, sizeof(sha1)); + } + + if (r != 0) { err = got_error_checksum(expected_id); goto done; } @@ -658,6 +673,7 @@ got_object_parse_commit(struct got_commit_object **com err = got_error(GOT_ERR_BAD_OBJ_DATA); goto done; } + (*commit)->tree_id->algo = algo; remain -= digest_strlen; s += digest_strlen; } else { @@ -833,7 +849,7 @@ got_object_tree_close(struct got_tree_object *tree) static const struct got_error * parse_tree_entry(struct got_parsed_tree_entry *pte, size_t *elen, char *buf, - size_t maxlen) + size_t maxlen, size_t idlen) { char *p, *space; @@ -857,14 +873,15 @@ parse_tree_entry(struct got_parsed_tree_entry *pte, si p++; } - if (*elen > maxlen || maxlen - *elen < SHA1_DIGEST_LENGTH) + if (*elen > maxlen || maxlen - *elen < idlen) return got_error(GOT_ERR_BAD_OBJ_DATA); pte->name = space + 1; pte->namelen = strlen(pte->name); buf += *elen; pte->id = buf; - *elen += SHA1_DIGEST_LENGTH; + pte->idlen = idlen; + *elen += idlen; return NULL; } @@ -878,14 +895,18 @@ pte_cmp(const void *pa, const void *pb) const struct got_error * got_object_parse_tree(struct got_parsed_tree_entry **entries, size_t *nentries, - size_t *nentries_alloc, uint8_t *buf, size_t len) + size_t *nentries_alloc, uint8_t *buf, size_t len, int algo) { const struct got_error *err = NULL; size_t remain = len; const size_t nalloc = 16; struct got_parsed_tree_entry *pte; + size_t idlen = SHA256_DIGEST_LENGTH; int i; + if (algo != GOT_HASH_SHA256) + idlen = SHA1_DIGEST_LENGTH; + *nentries = 0; if (remain == 0) return NULL; /* tree is empty */ @@ -905,7 +926,7 @@ got_object_parse_tree(struct got_parsed_tree_entry **e } pte = &(*entries)[*nentries]; - err = parse_tree_entry(pte, &elen, buf, remain); + err = parse_tree_entry(pte, &elen, buf, remain, idlen); if (err) goto done; buf += elen; @@ -946,18 +967,28 @@ got_object_read_tree(struct got_parsed_tree_entry **en struct got_object *obj = NULL; size_t len; struct got_inflate_checksum csum; + SHA2_CTX sha256_ctx; SHA1_CTX sha1_ctx; struct got_object_id id; - SHA1Init(&sha1_ctx); memset(&csum, 0, sizeof(csum)); - csum.output_sha1 = &sha1_ctx; + id.algo = expected_id->algo; + if (expected_id->algo == GOT_HASH_SHA256) { + SHA256Init(&sha256_ctx); + csum.output_sha256 = &sha256_ctx; + } else { + SHA1Init(&sha1_ctx); + csum.output_sha1 = &sha1_ctx; + } err = got_inflate_to_mem_fd(p, &len, NULL, &csum, 0, fd); if (err) return err; - SHA1Final(id.hash, &sha1_ctx); + if (expected_id->algo == GOT_HASH_SHA256) + SHA256Final(id.hash, &sha256_ctx); + else + SHA1Final(id.hash, &sha1_ctx); if (got_object_id_cmp(expected_id, &id) != 0) { err = got_error_checksum(expected_id); goto done; @@ -975,7 +1006,7 @@ got_object_read_tree(struct got_parsed_tree_entry **en /* Skip object header. */ len -= obj->hdrlen; err = got_object_parse_tree(entries, nentries, nentries_alloc, - *p + obj->hdrlen, len); + *p + obj->hdrlen, len, expected_id->algo); done: if (obj) got_object_close(obj); @@ -998,13 +1029,17 @@ got_object_tag_close(struct got_tag_object *tag) } const struct got_error * -got_object_parse_tag(struct got_tag_object **tag, uint8_t *buf, size_t len) +got_object_parse_tag(struct got_tag_object **tag, uint8_t *buf, size_t len, + int algo) { const struct got_error *err = NULL; size_t remain = len; char *s = buf; - size_t label_len; + size_t label_len, digest_strlen = SHA256_DIGEST_STRING_LENGTH; + if (algo != GOT_HASH_SHA256) + digest_strlen = SHA1_DIGEST_STRING_LENGTH; + if (remain == 0) return got_error(GOT_ERR_BAD_OBJ_DATA); @@ -1015,17 +1050,18 @@ got_object_parse_tag(struct got_tag_object **tag, uint label_len = strlen(GOT_TAG_LABEL_OBJECT); if (strncmp(s, GOT_TAG_LABEL_OBJECT, label_len) == 0) { remain -= label_len; - if (remain < SHA1_DIGEST_STRING_LENGTH) { + if (remain < digest_strlen) { err = got_error(GOT_ERR_BAD_OBJ_DATA); goto done; } s += label_len; - if (!got_parse_sha1_digest((*tag)->id.hash, s)) { + if (!got_parse_hash_digest((*tag)->id.hash, s, algo, NULL)) { err = got_error(GOT_ERR_BAD_OBJ_DATA); goto done; } - remain -= SHA1_DIGEST_STRING_LENGTH; - s += SHA1_DIGEST_STRING_LENGTH; + (*tag)->id.algo = algo; + remain -= digest_strlen; + s += digest_strlen; } else { err = got_error(GOT_ERR_BAD_OBJ_DATA); goto done; @@ -1185,19 +1221,29 @@ got_object_read_tag(struct got_tag_object **tag, int f size_t len; uint8_t *p; struct got_inflate_checksum csum; + SHA2_CTX sha256_ctx; SHA1_CTX sha1_ctx; struct got_object_id id; - SHA1Init(&sha1_ctx); memset(&csum, 0, sizeof(csum)); - csum.output_sha1 = &sha1_ctx; + id.algo = expected_id->algo; + if (expected_id->algo == GOT_HASH_SHA256) { + SHA256Init(&sha256_ctx); + csum.output_sha256 = &sha256_ctx; + } else { + SHA1Init(&sha1_ctx); + csum.output_sha1 = &sha1_ctx; + } err = got_inflate_to_mem_fd(&p, &len, NULL, &csum, expected_size, fd); if (err) return err; - SHA1Final(id.hash, &sha1_ctx); + if (expected_id->algo == GOT_HASH_SHA256) + SHA256Final(id.hash, &sha256_ctx); + else + SHA1Final(id.hash, &sha1_ctx); if (got_object_id_cmp(expected_id, &id) != 0) { err = got_error_checksum(expected_id); goto done; @@ -1214,7 +1260,7 @@ got_object_read_tag(struct got_tag_object **tag, int f /* Skip object header. */ len -= obj->hdrlen; - err = got_object_parse_tag(tag, p + obj->hdrlen, len); + err = got_object_parse_tag(tag, p + obj->hdrlen, len, expected_id->algo); done: free(p); if (obj) blob - aaa7df19451129acb5dbcfbda0fa6a8a6a9a3ed6 blob + 88d46c62a322e8a2c03c181310e5a4c500fa2e1d --- lib/privsep.c +++ lib/privsep.c @@ -1405,17 +1405,27 @@ send_tree_entries_batch(struct imsgbuf *ibuf, return got_error_from_errno("imsg_add TREE_ENTRY"); for (i = idx0; i <= idxN; i++) { + static const char gap[12]; /* for sha1-inside-sha256 alignment */ struct got_parsed_tree_entry *pte = &entries[i]; + int algo = GOT_HASH_SHA256; - /* Keep in sync with struct got_imsg_tree_entry definition! */ - if (imsg_add(wbuf, pte->id, SHA1_DIGEST_LENGTH) == -1) + if (pte->idlen != SHA256_DIGEST_LENGTH) + algo = GOT_HASH_SHA1; + + /* Keep in sync with struct got_imsg_tree_entry definition! */ + if (imsg_add(wbuf, pte->id, pte->idlen) == -1) return got_error_from_errno("imsg_add TREE_ENTRY"); + if (pte->idlen != SHA256_DIGEST_LENGTH && + imsg_add(wbuf, gap, sizeof(gap)) == -1) + return got_error_from_errno("imsg_add TREE_ENTRY"); + if (imsg_add(wbuf, &algo, sizeof(algo)) == -1) + return got_error_from_errno("imsg_add TREE_ENTRY"); if (imsg_add(wbuf, &pte->mode, sizeof(pte->mode)) == -1) return got_error_from_errno("imsg_add TREE_ENTRY"); if (imsg_add(wbuf, &pte->namelen, sizeof(pte->namelen)) == -1) return got_error_from_errno("imsg_add TREE_ENTRY"); - /* Remaining bytes are the entry's name. */ + /* Remaining bytes are the id and entry's name. */ if (imsg_add(wbuf, pte->name, pte->namelen) == -1) return got_error_from_errno("imsg_add TREE_ENTRY"); } @@ -1436,7 +1446,7 @@ send_tree_entries(struct imsgbuf *ibuf, struct got_par i = 0; for (j = 0; j < nentries; j++) { struct got_parsed_tree_entry *pte = &entries[j]; - size_t len = SHA1_DIGEST_LENGTH + sizeof(pte->mode) + + size_t len = SHA256_DIGEST_LENGTH + sizeof(pte->mode) + sizeof(pte->namelen) + pte->namelen; if (j > 0 && @@ -1534,7 +1544,8 @@ recv_tree_entries(void *data, size_t datalen, struct g te_name = buf + sizeof(ite); memcpy(te->name, te_name, ite.namelen); te->name[ite.namelen] = '\0'; - memcpy(te->id.hash, ite.id, SHA1_DIGEST_LENGTH); + memcpy(te->id.hash, ite.id, sizeof(te->id.hash)); + te->id.algo = ite.algo; te->mode = ite.mode; te->idx = *nentries; (*nentries)++; blob - d277332c05168baa15e867e91596533533345bb1 blob + 0861f8c76416b827bb112dd92d105552bd74a8fe --- libexec/got-read-blob/got-read-blob.c +++ libexec/got-read-blob/got-read-blob.c @@ -77,12 +77,9 @@ main(int argc, char *argv[]) struct got_object_id id; struct got_object_id expected_id; struct got_inflate_checksum csum; + SHA2_CTX sha256_ctx; SHA1_CTX sha1_ctx; - SHA1Init(&sha1_ctx); - memset(&csum, 0, sizeof(csum)); - csum.output_sha1 = &sha1_ctx; - memset(&imsg, 0, sizeof(imsg)); imsg.fd = -1; memset(&imsg_outfd, 0, sizeof(imsg_outfd)); @@ -145,6 +142,16 @@ main(int argc, char *argv[]) goto done; } + memset(&csum, 0, sizeof(csum)); + id.algo = expected_id.algo; + if (expected_id.algo == GOT_HASH_SHA256) { + SHA256Init(&sha256_ctx); + csum.output_sha256 = &sha256_ctx; + } else { + SHA1Init(&sha1_ctx); + csum.output_sha1 = &sha1_ctx; + } + err = got_object_read_header(&obj, imsg.fd); if (err) goto done; @@ -170,7 +177,10 @@ main(int argc, char *argv[]) if (err) goto done; } - SHA1Final(id.hash, &sha1_ctx); + if (expected_id.algo == GOT_HASH_SHA256) + SHA256Final(id.hash, &sha256_ctx); + else + SHA1Final(id.hash, &sha1_ctx); if (got_object_id_cmp(&expected_id, &id) != 0) { err = got_error_checksum(&expected_id); goto done; blob - a7bc1b886b3ad07fbe8c6c1b889b4c23b1c07c28 blob + fa7e848b2a4b1ace5b5ac7c12b5d44e8474b980b --- libexec/got-read-pack/got-read-pack.c +++ libexec/got-read-pack/got-read-pack.c @@ -212,7 +212,7 @@ open_tree(uint8_t **buf, struct got_parsed_tree_entry obj->size = len; err = got_object_parse_tree(entries, nentries, nentries_alloc, - *buf, len); + *buf, len, id->algo); done: got_object_close(obj); if (err) { @@ -411,7 +411,7 @@ tag_request(struct imsg *imsg, struct imsgbuf *ibuf, s goto done; obj->size = len; - err = got_object_parse_tag(&tag, buf, len); + err = got_object_parse_tag(&tag, buf, len, GOT_HASH_SHA1); if (err) goto done; @@ -1437,7 +1437,7 @@ enumeration_request(struct imsg *imsg, struct imsgbuf if (err) goto done; obj->size = len; - err = got_object_parse_tag(&tag, buf, len); + err = got_object_parse_tag(&tag, buf, len, GOT_HASH_SHA1); if (err) { free(buf); goto done;