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 "got_compat.h"
19 #include <sys/types.h>
20 #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 if (id1
->algo
!= id2
->algo
)
51 return memcmp(id1
->hash
, id2
->hash
, got_hash_digest_length(id1
->algo
));
54 const struct got_error
*
55 got_object_id_str(char **outbuf
, struct got_object_id
*id
)
57 static const size_t len
= GOT_OBJECT_ID_HEX_MAXLEN
;
59 *outbuf
= malloc(len
);
61 return got_error_from_errno("malloc");
63 if (got_object_id_hex(id
, *outbuf
, len
) == NULL
) {
66 return got_error(GOT_ERR_BAD_OBJ_ID_STR
);
73 got_parse_xdigit(uint8_t *val
, const char *hex
)
79 lval
= strtol(hex
, &ep
, 16);
80 if (hex
[0] == '\0' || *ep
!= '\0')
82 if (errno
== ERANGE
&& (lval
== LONG_MAX
|| lval
== LONG_MIN
))
90 parse_digest(uint8_t *digest
, int len
, const char *line
)
93 char hex
[3] = {'\0', '\0', '\0'};
96 for (i
= 0; i
< len
; i
++) {
97 if (line
[0] == '\0' || line
[1] == '\0')
99 for (j
= 0; j
< 2; j
++) {
103 if (!got_parse_xdigit(&b
, hex
))
112 digest_to_str(const uint8_t *digest
, int len
, char *buf
)
114 const char hex
[] = "0123456789abcdef";
118 for (i
= 0; i
< len
; i
++) {
119 *p
++ = hex
[digest
[i
] >> 4];
120 *p
++ = hex
[digest
[i
] & 0xf];
128 got_sha1_digest_to_str(const uint8_t *digest
, char *buf
, size_t size
)
130 if (size
< SHA1_DIGEST_STRING_LENGTH
)
132 return digest_to_str(digest
, SHA1_DIGEST_LENGTH
, buf
);
136 got_sha256_digest_to_str(const uint8_t *digest
, char *buf
, size_t size
)
138 if (size
< SHA256_DIGEST_STRING_LENGTH
)
140 return digest_to_str(digest
, SHA256_DIGEST_LENGTH
, buf
);
144 got_hash_digest_to_str(const uint8_t *digest
, char *buf
, size_t size
,
145 enum got_hash_algorithm algo
)
149 return got_sha1_digest_to_str(digest
, buf
, size
);
150 case GOT_HASH_SHA256
:
151 return got_sha256_digest_to_str(digest
, buf
, size
);
159 got_parse_hash_digest(uint8_t *digest
, const char *line
,
160 enum got_hash_algorithm algo
)
164 return parse_digest(digest
, SHA1_DIGEST_LENGTH
, line
);
165 case GOT_HASH_SHA256
:
166 return parse_digest(digest
, SHA256_DIGEST_LENGTH
, line
);
173 got_object_id_hex(struct got_object_id
*id
, char *buf
, size_t len
)
175 if (id
->algo
== GOT_HASH_SHA1
)
176 return got_sha1_digest_to_str(id
->hash
, buf
, len
);
177 if (id
->algo
== GOT_HASH_SHA256
)
178 return got_sha256_digest_to_str(id
->hash
, buf
, len
);
183 got_parse_object_id(struct got_object_id
*id
, const char *line
,
184 enum got_hash_algorithm algo
)
186 memset(id
, 0, sizeof(*id
));
188 return got_parse_hash_digest(id
->hash
, line
, algo
);
192 got_hash_init(struct got_hash
*hash
, enum got_hash_algorithm algo
)
194 memset(hash
, 0, sizeof(*hash
));
197 if (algo
== GOT_HASH_SHA1
)
198 SHA1Init(&hash
->sha1_ctx
);
199 else if (algo
== GOT_HASH_SHA256
)
200 SHA256Init(&hash
->sha256_ctx
);
206 got_hash_update(struct got_hash
*hash
, const void *data
, size_t len
)
208 if (hash
->algo
== GOT_HASH_SHA1
)
209 SHA1Update(&hash
->sha1_ctx
, data
, len
);
210 else if (hash
->algo
== GOT_HASH_SHA256
)
211 SHA256Update(&hash
->sha256_ctx
, data
, len
);
217 got_hash_final(struct got_hash
*hash
, uint8_t *out
)
219 if (hash
->algo
== GOT_HASH_SHA1
)
220 SHA1Final(out
, &hash
->sha1_ctx
);
221 else if (hash
->algo
== GOT_HASH_SHA256
)
222 SHA256Final(out
, &hash
->sha256_ctx
);
228 got_hash_final_object_id(struct got_hash
*hash
, struct got_object_id
*id
)
230 memset(id
, 0, sizeof(*id
));
231 id
->algo
= hash
->algo
;
232 if (hash
->algo
== GOT_HASH_SHA1
)
233 SHA1Final(id
->hash
, &hash
->sha1_ctx
);
234 else if (hash
->algo
== GOT_HASH_SHA256
)
235 SHA256Final(id
->hash
, &hash
->sha256_ctx
);
241 got_hash_cmp(enum got_hash_algorithm algo
, uint8_t *b1
, uint8_t *b2
)
243 if (algo
== GOT_HASH_SHA1
)
244 return memcmp(b1
, b2
, SHA1_DIGEST_LENGTH
);
245 else if (algo
== GOT_HASH_SHA256
)
246 return memcmp(b1
, b2
, SHA256_DIGEST_LENGTH
);