From 7401d5c1100a35dd5eafa602fad6d334dea98225 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Sat, 22 Mar 2014 14:23:33 +0100 Subject: [PATCH] add utilities for calculating http digest hashes Signed-off-by: Felix Fietkau --- uclient-utils.c | 68 +++++++++++++++++++++++++++++++++++++++++++++++++ uclient-utils.h | 14 ++++++++++ 2 files changed, 82 insertions(+) diff --git a/uclient-utils.c b/uclient-utils.c index 0d09974..66a4f15 100644 --- a/uclient-utils.c +++ b/uclient-utils.c @@ -1,7 +1,11 @@ #include #include +#include #include +#include +#include + #include "uclient-utils.h" static const char *b64 = @@ -75,3 +79,67 @@ int uclient_urldecode(const char *in, char *out, bool decode_plus) *out = 0; return ret; } + +static char hex_digit(char val) +{ + val += val > 9 ? 'a' - 10 : '0'; + return val; +} + +void bin_to_hex(char *dest, const void *buf, int len) +{ + const uint8_t *data = buf; + int i; + + for (i = 0; i < len; i++) { + *(dest++) = hex_digit(data[i] >> 4); + *(dest++) = hex_digit(data[i] & 0xf); + } + *dest = 0; +} + +static void http_create_hash(char *dest, const char * const * str, int n_str) +{ + uint32_t hash[4]; + md5_ctx_t md5; + int i; + + md5_begin(&md5); + for (i = 0; i < n_str; i++) { + if (i) + md5_hash(":", 1, &md5); + md5_hash(str[i], strlen(str[i]), &md5); + } + md5_end(hash, &md5); + bin_to_hex(dest, &hash, sizeof(hash)); +} + +void http_digest_calculate_auth_hash(char *dest, const char *user, const char *realm, const char *password) +{ + const char *hash_str[] = { + user, + realm, + password + }; + + http_create_hash(dest, hash_str, ARRAY_SIZE(hash_str)); +} + +void http_digest_calculate_response(char *dest, const struct http_digest_data *data) +{ + const char *h_a2_strings[] = { + data->method, + data->uri, + }; + const char *resp_strings[] = { + data->auth_hash, + data->nonce, + data->nc, + data->cnonce, + data->qop, + dest, /* initialized to H(A2) first */ + }; + + http_create_hash(dest, h_a2_strings, ARRAY_SIZE(h_a2_strings)); + http_create_hash(dest, resp_strings, ARRAY_SIZE(resp_strings)); +} diff --git a/uclient-utils.h b/uclient-utils.h index a7eaf1c..83ab09a 100644 --- a/uclient-utils.h +++ b/uclient-utils.h @@ -3,14 +3,28 @@ #include +struct http_digest_data { + const char *uri; + const char *method; + + const char *auth_hash; /* H(A1) */ + const char *qop; + const char *nc; + const char *nonce; + const char *cnonce; +}; + static inline int base64_len(int len) { return ((len + 2) / 3) * 4; } void base64_encode(const void *inbuf, unsigned int len, void *out); +void bin_to_hex(char *dest, const void *buf, int len); int uclient_urldecode(const char *in, char *out, bool decode_plus); +void http_digest_calculate_auth_hash(char *dest, const char *user, const char *realm, const char *password); +void http_digest_calculate_response(char *dest, const struct http_digest_data *data); #endif -- 2.25.1