2 be288a59 2023-02-23 thomas * Copyright (c) 2018 Stefan Sperling <stsp@openbsd.org>
4 be288a59 2023-02-23 thomas * Permission to use, copy, modify, and distribute this software for any
5 be288a59 2023-02-23 thomas * purpose with or without fee is hereby granted, provided that the above
6 be288a59 2023-02-23 thomas * copyright notice and this permission notice appear in all copies.
8 be288a59 2023-02-23 thomas * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 be288a59 2023-02-23 thomas * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 be288a59 2023-02-23 thomas * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 be288a59 2023-02-23 thomas * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 be288a59 2023-02-23 thomas * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 be288a59 2023-02-23 thomas * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 be288a59 2023-02-23 thomas * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17 68069cf6 2023-03-08 thomas #include "got_compat.h"
19 be288a59 2023-02-23 thomas #include <sys/types.h>
20 c8ae092d 2023-02-23 thomas #include <sys/queue.h>
22 be288a59 2023-02-23 thomas #include <errno.h>
23 be288a59 2023-02-23 thomas #include <stdio.h>
24 be288a59 2023-02-23 thomas #include <stdlib.h>
25 c8ae092d 2023-02-23 thomas #include <string.h>
26 be288a59 2023-02-23 thomas #include <limits.h>
28 c8ae092d 2023-02-23 thomas #include "got_object.h"
30 be288a59 2023-02-23 thomas #include "got_lib_hash.h"
33 be288a59 2023-02-23 thomas got_parse_xdigit(uint8_t *val, const char *hex)
36 be288a59 2023-02-23 thomas long lval;
38 be288a59 2023-02-23 thomas errno = 0;
39 be288a59 2023-02-23 thomas lval = strtol(hex, &ep, 16);
40 be288a59 2023-02-23 thomas if (hex[0] == '\0' || *ep != '\0')
42 be288a59 2023-02-23 thomas if (errno == ERANGE && (lval == LONG_MAX || lval == LONG_MIN))
45 be288a59 2023-02-23 thomas *val = (uint8_t)lval;
49 c8ae092d 2023-02-23 thomas static int
50 c8ae092d 2023-02-23 thomas parse_digest(uint8_t *digest, int len, const char *line)
52 be288a59 2023-02-23 thomas uint8_t b = 0;
53 be288a59 2023-02-23 thomas char hex[3] = {'\0', '\0', '\0'};
56 c8ae092d 2023-02-23 thomas for (i = 0; i < len; i++) {
57 be288a59 2023-02-23 thomas if (line[0] == '\0' || line[1] == '\0')
59 be288a59 2023-02-23 thomas for (j = 0; j < 2; j++) {
60 be288a59 2023-02-23 thomas hex[j] = *line;
63 be288a59 2023-02-23 thomas if (!got_parse_xdigit(&b, hex))
65 be288a59 2023-02-23 thomas digest[i] = b;
71 c8ae092d 2023-02-23 thomas static char *
72 c8ae092d 2023-02-23 thomas digest_to_str(const uint8_t *digest, int len, char *buf)
74 6853f3b1 2023-02-24 thomas const char hex[] = "0123456789abcdef";
75 be288a59 2023-02-23 thomas char *p = buf;
78 c8ae092d 2023-02-23 thomas for (i = 0; i < len; i++) {
79 6853f3b1 2023-02-24 thomas *p++ = hex[digest[i] >> 4];
80 6853f3b1 2023-02-24 thomas *p++ = hex[digest[i] & 0xf];
82 6853f3b1 2023-02-24 thomas *p = '\0';
84 be288a59 2023-02-23 thomas return buf;
88 c8ae092d 2023-02-23 thomas got_sha1_digest_to_str(const uint8_t *digest, char *buf, size_t size)
90 c8ae092d 2023-02-23 thomas if (size < SHA1_DIGEST_STRING_LENGTH)
91 c8ae092d 2023-02-23 thomas return NULL;
92 c8ae092d 2023-02-23 thomas return digest_to_str(digest, SHA1_DIGEST_LENGTH, buf);
96 c8ae092d 2023-02-23 thomas got_sha256_digest_to_str(const uint8_t *digest, char *buf, size_t size)
98 c8ae092d 2023-02-23 thomas if (size < SHA256_DIGEST_STRING_LENGTH)
99 c8ae092d 2023-02-23 thomas return NULL;
100 c8ae092d 2023-02-23 thomas return digest_to_str(digest, SHA256_DIGEST_LENGTH, buf);
104 c8ae092d 2023-02-23 thomas got_parse_hash_digest(uint8_t *digest, const char *line,
105 c8ae092d 2023-02-23 thomas enum got_hash_algorithm algo)
107 c8ae092d 2023-02-23 thomas switch (algo) {
108 c8ae092d 2023-02-23 thomas case GOT_HASH_SHA1:
109 c8ae092d 2023-02-23 thomas return parse_digest(digest, SHA1_DIGEST_LENGTH, line);
110 c8ae092d 2023-02-23 thomas case GOT_HASH_SHA256:
111 c8ae092d 2023-02-23 thomas return parse_digest(digest, SHA256_DIGEST_LENGTH, line);
113 c8ae092d 2023-02-23 thomas return 0;
118 c8ae092d 2023-02-23 thomas got_parse_object_id(struct got_object_id *id, const char *line,
119 c8ae092d 2023-02-23 thomas enum got_hash_algorithm algo)
121 c8ae092d 2023-02-23 thomas memset(id, 0, sizeof(*id));
123 c8ae092d 2023-02-23 thomas /* XXX: temporary until we grow got_object_id */
124 c8ae092d 2023-02-23 thomas if (algo != GOT_HASH_SHA1)
125 c8ae092d 2023-02-23 thomas return 0;
127 c8ae092d 2023-02-23 thomas return got_parse_hash_digest(id->sha1, line, algo);
131 b16893ba 2023-02-24 thomas got_hash_init(struct got_hash *hash, enum got_hash_algorithm algo)
133 b16893ba 2023-02-24 thomas memset(hash, 0, sizeof(*hash));
134 b16893ba 2023-02-24 thomas hash->algo = algo;
136 b16893ba 2023-02-24 thomas if (algo == GOT_HASH_SHA1)
137 b16893ba 2023-02-24 thomas SHA1Init(&hash->sha1_ctx);
138 b16893ba 2023-02-24 thomas else if (algo == GOT_HASH_SHA256)
139 b16893ba 2023-02-24 thomas SHA256Init(&hash->sha256_ctx);
143 b16893ba 2023-02-24 thomas got_hash_update(struct got_hash *hash, const void *data, size_t len)
145 b16893ba 2023-02-24 thomas if (hash->algo == GOT_HASH_SHA1)
146 b16893ba 2023-02-24 thomas SHA1Update(&hash->sha1_ctx, data, len);
147 b16893ba 2023-02-24 thomas else if (hash->algo == GOT_HASH_SHA256)
148 b16893ba 2023-02-24 thomas SHA256Update(&hash->sha256_ctx, data, len);
152 b16893ba 2023-02-24 thomas got_hash_final(struct got_hash *hash, uint8_t *out)
154 b16893ba 2023-02-24 thomas if (hash->algo == GOT_HASH_SHA1)
155 b16893ba 2023-02-24 thomas SHA1Final(out, &hash->sha1_ctx);
156 b16893ba 2023-02-24 thomas else if (hash->algo == GOT_HASH_SHA256)
157 b16893ba 2023-02-24 thomas SHA256Final(out, &hash->sha256_ctx);
161 b16893ba 2023-02-24 thomas got_hash_final_object_id(struct got_hash *hash, struct got_object_id *id)
163 b16893ba 2023-02-24 thomas memset(id, 0, sizeof(*id));
164 b16893ba 2023-02-24 thomas got_hash_final(hash, id->sha1);
168 b16893ba 2023-02-24 thomas got_hash_cmp(enum got_hash_algorithm algo, uint8_t *b1, uint8_t *b2)
170 b16893ba 2023-02-24 thomas if (algo == GOT_HASH_SHA1)
171 b16893ba 2023-02-24 thomas return memcmp(b1, b2, SHA1_DIGEST_LENGTH);
172 b16893ba 2023-02-24 thomas else if (algo == GOT_HASH_SHA256)
173 b16893ba 2023-02-24 thomas return memcmp(b1, b2, SHA256_DIGEST_LENGTH);
174 b16893ba 2023-02-24 thomas return -1;