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 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 if (hash
->algo
== GOT_HASH_SHA1
)
209 SHA1Final(id
->sha1
, &hash
->sha1_ctx
);
215 got_hash_cmp(enum got_hash_algorithm algo
, uint8_t *b1
, uint8_t *b2
)
217 if (algo
== GOT_HASH_SHA1
)
218 return memcmp(b1
, b2
, SHA1_DIGEST_LENGTH
);
219 else if (algo
== GOT_HASH_SHA256
)
220 return memcmp(b1
, b2
, SHA256_DIGEST_LENGTH
);