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>
26 #include "got_compat.h"
28 #include "got_object.h"
30 #include "got_lib_hash.h"
33 got_parse_xdigit(uint8_t *val
, const char *hex
)
39 lval
= strtol(hex
, &ep
, 16);
40 if (hex
[0] == '\0' || *ep
!= '\0')
42 if (errno
== ERANGE
&& (lval
== LONG_MAX
|| lval
== LONG_MIN
))
50 parse_digest(uint8_t *digest
, int len
, const char *line
)
53 char hex
[3] = {'\0', '\0', '\0'};
56 for (i
= 0; i
< len
; i
++) {
57 if (line
[0] == '\0' || line
[1] == '\0')
59 for (j
= 0; j
< 2; j
++) {
63 if (!got_parse_xdigit(&b
, hex
))
72 digest_to_str(const uint8_t *digest
, int len
, char *buf
)
74 const char hex
[] = "0123456789abcdef";
78 for (i
= 0; i
< len
; i
++) {
79 *p
++ = hex
[digest
[i
] >> 4];
80 *p
++ = hex
[digest
[i
] & 0xf];
88 got_sha1_digest_to_str(const uint8_t *digest
, char *buf
, size_t size
)
90 if (size
< SHA1_DIGEST_STRING_LENGTH
)
92 return digest_to_str(digest
, SHA1_DIGEST_LENGTH
, buf
);
96 got_sha256_digest_to_str(const uint8_t *digest
, char *buf
, size_t size
)
98 if (size
< SHA256_DIGEST_STRING_LENGTH
)
100 return digest_to_str(digest
, SHA256_DIGEST_LENGTH
, buf
);
104 got_parse_hash_digest(uint8_t *digest
, const char *line
,
105 enum got_hash_algorithm algo
)
109 return parse_digest(digest
, SHA1_DIGEST_LENGTH
, line
);
110 case GOT_HASH_SHA256
:
111 return parse_digest(digest
, SHA256_DIGEST_LENGTH
, line
);
118 got_parse_object_id(struct got_object_id
*id
, const char *line
,
119 enum got_hash_algorithm algo
)
121 memset(id
, 0, sizeof(*id
));
123 /* XXX: temporary until we grow got_object_id */
124 if (algo
!= GOT_HASH_SHA1
)
127 return got_parse_hash_digest(id
->sha1
, line
, algo
);
131 got_hash_init(struct got_hash
*hash
, enum got_hash_algorithm algo
)
133 memset(hash
, 0, sizeof(*hash
));
136 if (algo
== GOT_HASH_SHA1
)
137 SHA1Init(&hash
->sha1_ctx
);
138 else if (algo
== GOT_HASH_SHA256
)
139 SHA256Init(&hash
->sha256_ctx
);
143 got_hash_update(struct got_hash
*hash
, const void *data
, size_t len
)
145 if (hash
->algo
== GOT_HASH_SHA1
)
146 SHA1Update(&hash
->sha1_ctx
, data
, len
);
147 else if (hash
->algo
== GOT_HASH_SHA256
)
148 SHA256Update(&hash
->sha256_ctx
, data
, len
);
152 got_hash_final(struct got_hash
*hash
, uint8_t *out
)
154 if (hash
->algo
== GOT_HASH_SHA1
)
155 SHA1Final(out
, &hash
->sha1_ctx
);
156 else if (hash
->algo
== GOT_HASH_SHA256
)
157 SHA256Final(out
, &hash
->sha256_ctx
);
161 got_hash_final_object_id(struct got_hash
*hash
, struct got_object_id
*id
)
163 memset(id
, 0, sizeof(*id
));
164 got_hash_final(hash
, id
->sha1
);
168 got_hash_cmp(enum got_hash_algorithm algo
, uint8_t *b1
, uint8_t *b2
)
170 if (algo
== GOT_HASH_SHA1
)
171 return memcmp(b1
, b2
, SHA1_DIGEST_LENGTH
);
172 else if (algo
== GOT_HASH_SHA256
)
173 return memcmp(b1
, b2
, SHA256_DIGEST_LENGTH
);