2 * Copyright (c) 2018 Stefan Sperling <stsp@openbsd.org>
4 * Permission to use, copy, modify, and distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17 #include <sys/types.h>
18 #include <sys/queue.h>
28 #include "got_object.h"
29 #include "got_error.h"
31 #include "got_lib_hash.h"
33 struct got_object_id *
34 got_object_id_dup(struct got_object_id *id1)
36 struct got_object_id *id2;
38 id2 = malloc(sizeof(*id2));
41 memcpy(id2, id1, sizeof(*id2));
46 got_object_id_cmp(const struct got_object_id *id1,
47 const struct got_object_id *id2)
49 return memcmp(id1->sha1, id2->sha1, SHA1_DIGEST_LENGTH);
52 const struct got_error *
53 got_object_id_str(char **outbuf, struct got_object_id *id)
55 static const size_t len = GOT_OBJECT_ID_HEX_MAXLEN;
57 *outbuf = malloc(len);
59 return got_error_from_errno("malloc");
61 if (got_object_id_hex(id, *outbuf, len) == NULL) {
64 return got_error(GOT_ERR_BAD_OBJ_ID_STR);
71 got_parse_xdigit(uint8_t *val, const char *hex)
77 lval = strtol(hex, &ep, 16);
78 if (hex[0] == '\0' || *ep != '\0')
80 if (errno == ERANGE && (lval == LONG_MAX || lval == LONG_MIN))
88 parse_digest(uint8_t *digest, int len, const char *line)
91 char hex[3] = {'\0', '\0', '\0'};
94 for (i = 0; i < len; i++) {
95 if (line[0] == '\0' || line[1] == '\0')
97 for (j = 0; j < 2; j++) {
101 if (!got_parse_xdigit(&b, hex))
110 digest_to_str(const uint8_t *digest, int len, char *buf)
112 const char hex[] = "0123456789abcdef";
116 for (i = 0; i < len; i++) {
117 *p++ = hex[digest[i] >> 4];
118 *p++ = hex[digest[i] & 0xf];
126 got_sha1_digest_to_str(const uint8_t *digest, char *buf, size_t size)
128 if (size < SHA1_DIGEST_STRING_LENGTH)
130 return digest_to_str(digest, SHA1_DIGEST_LENGTH, buf);
134 got_sha256_digest_to_str(const uint8_t *digest, char *buf, size_t size)
136 if (size < SHA256_DIGEST_STRING_LENGTH)
138 return digest_to_str(digest, SHA256_DIGEST_LENGTH, buf);
142 got_parse_hash_digest(uint8_t *digest, const char *line,
143 enum got_hash_algorithm algo)
147 return parse_digest(digest, SHA1_DIGEST_LENGTH, line);
148 case GOT_HASH_SHA256:
149 return parse_digest(digest, SHA256_DIGEST_LENGTH, line);
156 got_object_id_hex(struct got_object_id *id, char *buf, size_t len)
158 return got_sha1_digest_to_str(id->sha1, buf, len);
162 got_parse_object_id(struct got_object_id *id, const char *line,
163 enum got_hash_algorithm algo)
165 memset(id, 0, sizeof(*id));
167 /* XXX: temporary until we grow got_object_id */
168 if (algo != GOT_HASH_SHA1)
171 return got_parse_hash_digest(id->sha1, line, algo);
175 got_hash_init(struct got_hash *hash, enum got_hash_algorithm algo)
177 memset(hash, 0, sizeof(*hash));
180 if (algo == GOT_HASH_SHA1)
181 SHA1Init(&hash->sha1_ctx);
182 else if (algo == GOT_HASH_SHA256)
183 SHA256Init(&hash->sha256_ctx);
187 got_hash_update(struct got_hash *hash, const void *data, size_t len)
189 if (hash->algo == GOT_HASH_SHA1)
190 SHA1Update(&hash->sha1_ctx, data, len);
191 else if (hash->algo == GOT_HASH_SHA256)
192 SHA256Update(&hash->sha256_ctx, data, len);
196 got_hash_final(struct got_hash *hash, uint8_t *out)
198 if (hash->algo == GOT_HASH_SHA1)
199 SHA1Final(out, &hash->sha1_ctx);
200 else if (hash->algo == GOT_HASH_SHA256)
201 SHA256Final(out, &hash->sha256_ctx);
205 got_hash_final_object_id(struct got_hash *hash, struct got_object_id *id)
207 memset(id, 0, sizeof(*id));
208 got_hash_final(hash, id->sha1);
212 got_hash_cmp(enum got_hash_algorithm algo, uint8_t *b1, uint8_t *b2)
214 if (algo == GOT_HASH_SHA1)
215 return memcmp(b1, b2, SHA1_DIGEST_LENGTH);
216 else if (algo == GOT_HASH_SHA256)
217 return memcmp(b1, b2, SHA256_DIGEST_LENGTH);