bcb4e51a409d94ae670de96afb8483a4f7855294Stephan Bosch/* Copyright (c) 2010-2018 Dovecot authors, see the included COPYING file */
37bd98570b30513255a19cc52de16594bc4256e0Timo Sirainenhash_format_parse(const char *str, unsigned int *idxp,
37bd98570b30513255a19cc52de16594bc4256e0Timo Sirainen /* we should have "hash_name}" or "hash_name:bits}" */
37bd98570b30513255a19cc52de16594bc4256e0Timo Sirainen *error_r = t_strconcat("Unknown hash method: ", name, NULL);
37bd98570b30513255a19cc52de16594bc4256e0Timo Sirainen bits == 0 || bits > (*method_r)->digest_size*8) {
37bd98570b30513255a19cc52de16594bc4256e0Timo Sirainen *error_r = t_strconcat("Invalid :bits number: ",
37bd98570b30513255a19cc52de16594bc4256e0Timo Sirainen "Currently :bits must be divisible by 8: ",
37bd98570b30513255a19cc52de16594bc4256e0Timo Sirainenhash_format_string_analyze(struct hash_format *format, const char *str,
37bd98570b30513255a19cc52de16594bc4256e0Timo Sirainen const char **error_r)
37bd98570b30513255a19cc52de16594bc4256e0Timo Sirainen unsigned int i;
37bd98570b30513255a19cc52de16594bc4256e0Timo Sirainen list = p_new(format->pool, struct hash_format_list, 1);
37bd98570b30513255a19cc52de16594bc4256e0Timo Sirainenint hash_format_init(const char *format_string, struct hash_format **format_r,
37bd98570b30513255a19cc52de16594bc4256e0Timo Sirainen const char **error_r)
37bd98570b30513255a19cc52de16594bc4256e0Timo Sirainen pool = pool_alloconly_create("hash format", 1024);
37bd98570b30513255a19cc52de16594bc4256e0Timo Sirainen ret = hash_format_string_analyze(format, format_string,
37bd98570b30513255a19cc52de16594bc4256e0Timo Sirainenvoid hash_format_loop(struct hash_format *format,
37bd98570b30513255a19cc52de16594bc4256e0Timo Sirainen for (list = format->list; list != NULL; list = list->next)
37bd98570b30513255a19cc52de16594bc4256e0Timo Sirainen list->method->loop(list->context, data, size);
ddd1adf19cacc6186fbc713d255e1e82086d7751Timo Sirainenvoid hash_format_reset(struct hash_format *format)
ddd1adf19cacc6186fbc713d255e1e82086d7751Timo Sirainen for (list = format->list; list != NULL; list = list->next) {
ddd1adf19cacc6186fbc713d255e1e82086d7751Timo Sirainen memset(list->context, 0, list->method->context_size);
37bd98570b30513255a19cc52de16594bc4256e0Timo Sirainenhash_format_digest(string_t *dest, const struct hash_format_list *list,
37bd98570b30513255a19cc52de16594bc4256e0Timo Sirainen const unsigned char *digest)
37bd98570b30513255a19cc52de16594bc4256e0Timo Sirainen unsigned int i, orig_len, size = list->bits / 8;
37bd98570b30513255a19cc52de16594bc4256e0Timo Sirainen /* drop leading zeros, except if it's the only one */
37bd98570b30513255a19cc52de16594bc4256e0Timo Sirainen /* drop trailing '=' chars */
ddd1adf19cacc6186fbc713d255e1e82086d7751Timo Sirainenvoid hash_format_write(struct hash_format *format, string_t *dest)
37bd98570b30513255a19cc52de16594bc4256e0Timo Sirainen const char *p;
37bd98570b30513255a19cc52de16594bc4256e0Timo Sirainen for (list = format->list; list != NULL; list = list->next) {
37bd98570b30513255a19cc52de16594bc4256e0Timo Sirainen if (max_digest_size < list->method->digest_size)
ddd1adf19cacc6186fbc713d255e1e82086d7751Timo Sirainen format->digest = p_malloc(format->pool, max_digest_size);
37bd98570b30513255a19cc52de16594bc4256e0Timo Sirainen /* we already verified that the string is ok */
ddd1adf19cacc6186fbc713d255e1e82086d7751Timo Sirainen list->method->result(list->context, format->digest);
ddd1adf19cacc6186fbc713d255e1e82086d7751Timo Sirainen hash_format_digest(dest, list, format->digest);
ddd1adf19cacc6186fbc713d255e1e82086d7751Timo Sirainenvoid hash_format_deinit(struct hash_format **_format, string_t *dest)