hash-format.c revision c971768955f826fb965d8ffbb13dac93c9bbead8
45312f52ff3a3d4c137447be4c7556500c2f8bf2Timo Sirainen/* Copyright (c) 2010-2014 Dovecot authors, see the included COPYING file */
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen unsigned int bits;
0d70a702dec63d22535684fec6a7247c5f153208Timo Sirainen const char *str;
0d70a702dec63d22535684fec6a7247c5f153208Timo Sirainen unsigned char *digest;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenhash_format_parse(const char *str, unsigned int *idxp,
a94936bafd127680184da114c6a177b37ff656e5Timo Sirainen /* we should have "hash_name}" or "hash_name:bits}" */
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen *error_r = t_strconcat("Unknown hash method: ", name, NULL);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen bits == 0 || bits > (*method_r)->digest_size*8) {
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen *error_r = t_strconcat("Invalid :bits number: ",
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen "Currently :bits must be divisible by 8: ",
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenhash_format_string_analyze(struct hash_format *format, const char *str,
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen const char **error_r)
7c5b51bdf43a98e12c654ad437e0b258c5fffbc1Timo Sirainen unsigned int i;
7c5b51bdf43a98e12c654ad437e0b258c5fffbc1Timo Sirainen list = p_new(format->pool, struct hash_format_list, 1);
b0be0bead3d6963149f7f2a9504b8ab5aced9af5Timo Sirainenint hash_format_init(const char *format_string, struct hash_format **format_r,
7c5b51bdf43a98e12c654ad437e0b258c5fffbc1Timo Sirainen const char **error_r)
3776ed607821b502468bdfd5a4533af3002125d1Timo Sirainen pool = pool_alloconly_create("hash format", 1024);
3776ed607821b502468bdfd5a4533af3002125d1Timo Sirainen ret = hash_format_string_analyze(format, format_string,
7e94cf9d70ce9fdeccb7a85ff400b899e6386f36Timo Sirainenvoid hash_format_loop(struct hash_format *format,
3b80595fcf2001cf7b2fcc6290823e38f4a142fcTimo Sirainen for (list = format->list; list != NULL; list = list->next)
3b80595fcf2001cf7b2fcc6290823e38f4a142fcTimo Sirainen list->method->loop(list->context, data, size);
73b50eecfc31750a312e2f940023f522eb07178cTimo Sirainenvoid hash_format_reset(struct hash_format *format)
3b80595fcf2001cf7b2fcc6290823e38f4a142fcTimo Sirainen for (list = format->list; list != NULL; list = list->next) {
06fb99af33bd380b382d2d4f2994cf9a5bf0bbaeTimo Sirainen memset(list->context, 0, list->method->context_size);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenhash_format_digest(string_t *dest, const struct hash_format_list *list,
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen const unsigned char *digest)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen unsigned int i, orig_len, size = list->bits / 8;
8afec4d1a32b78f540257a27769b372aad753384Timo Sirainen /* drop leading zeros, except if it's the only one */
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen /* drop trailing '=' chars */
73b50eecfc31750a312e2f940023f522eb07178cTimo Sirainenvoid hash_format_write(struct hash_format *format, string_t *dest)
8afec4d1a32b78f540257a27769b372aad753384Timo Sirainen const char *p;
7c5b51bdf43a98e12c654ad437e0b258c5fffbc1Timo Sirainen unsigned int i, max_digest_size = 0;
73b50eecfc31750a312e2f940023f522eb07178cTimo Sirainen for (list = format->list; list != NULL; list = list->next) {
b5ea11802f2bafbec06282a7b3b6704dc5fae584Timo Sirainen if (max_digest_size < list->method->digest_size)
a94936bafd127680184da114c6a177b37ff656e5Timo Sirainen format->digest = p_malloc(format->pool, max_digest_size);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen /* we already verified that the string is ok */
8e7da21696c9f8a6d5e601243fb6172ec85d47b2Timo Sirainen list->method->result(list->context, format->digest);
6d25922a089626f5535d51358e33d3337783a410Timo Sirainen hash_format_digest(dest, list, format->digest);
5ba25fa97ceebd32d8c58a2d38b0b3f7fc5e67ccTimo Sirainenvoid hash_format_deinit(struct hash_format **_format, string_t *dest)