diff options
author | Joe Orton <joe@manyfish.uk> | 2020-06-08 22:59:29 +0100 |
---|---|---|
committer | Joe Orton <jorton@apache.org> | 2020-06-18 08:01:27 +0100 |
commit | 379e5c250d0b8c661364fd435c50232486b33ba9 (patch) | |
tree | ac97a4d5a84ac68b4e2b0aad55190f27eefbcf48 | |
parent | 8af18bb316e0e1d31dd8a5decf20683510409e8b (diff) | |
download | neon-git-379e5c250d0b8c661364fd435c50232486b33ba9.tar.gz |
Define ne_strhash, ne_vstrhash functions.
* src/neon.vers, src/ne_string.h: Declare ne_strhash,
ne_vstrhash as new API.
* src/ne_string.c (ne_strhash): New function.
(ne_vstrhash): New function (non-OpenSSL 1.1 builds)
* src/ne_openssl.c (ne_vstrhash): Define for 1.1 builds.
* test/auth.c (hash): Reimplement using ne_vstrhash().
-rw-r--r-- | src/ne_openssl.c | 24 | ||||
-rw-r--r-- | src/ne_string.c | 41 | ||||
-rw-r--r-- | src/ne_string.h | 12 | ||||
-rw-r--r-- | src/neon.vers | 5 | ||||
-rw-r--r-- | test/auth.c | 48 | ||||
-rw-r--r-- | test/string-tests.c | 18 |
6 files changed, 110 insertions, 38 deletions
diff --git a/src/ne_openssl.c b/src/ne_openssl.c index 52e758b..84c1b7e 100644 --- a/src/ne_openssl.c +++ b/src/ne_openssl.c @@ -1139,6 +1139,30 @@ int ne_ssl_cert_digest(const ne_ssl_certificate *cert, char *digest) return 0; } +#ifdef HAVE_OPENSSL11 +char *ne_vstrhash(unsigned int flags, va_list ap) +{ + EVP_MD_CTX *ctx = EVP_MD_CTX_new(); + const EVP_MD *md; + unsigned char v[EVP_MAX_MD_SIZE]; + char ret[33]; + const char *arg; + + md = EVP_md5(); + + if (EVP_DigestInit(ctx, md) != 1) return NULL; + + while ((arg = va_arg(ap, const char *)) != NULL) + EVP_DigestUpdate(ctx, arg, strlen(arg)); + + EVP_DigestFinal_ex(ctx, v, NULL); + ne_md5_to_ascii(v, ret); + EVP_MD_CTX_free(ctx); + + return ne_strdup(ret); +} +#endif + #if defined(NE_HAVE_TS_SSL) && OPENSSL_VERSION_NUMBER < 0x10100000L /* From OpenSSL 1.1.0 locking callbacks are no longer needed. */ #define WITH_OPENSSL_LOCKING (1) diff --git a/src/ne_string.c b/src/ne_string.c index 2d222f4..bec7b06 100644 --- a/src/ne_string.c +++ b/src/ne_string.c @@ -39,6 +39,11 @@ #include "ne_alloc.h" #include "ne_string.h" +#if !defined(HAVE_OPENSSL11) +#include "ne_md5.h" +#define NEED_VSTRHASH +#endif + char *ne_token(char **str, char separator) { char *ret = *str, *pnt = strchr(*str, separator); @@ -614,3 +619,39 @@ int ne_strncasecmp(const char *s1, const char *s2, size_t n) return c1 - c2; } + +char *ne_strhash(unsigned int flags, ...) +{ + va_list ap; + char *rv; + + if (flags != NE_STRHASH_MD5) return NULL; + + va_start(ap, flags); + rv = ne_vstrhash(flags, ap); + va_end(ap); + + return rv; +} + +#ifdef NEED_VSTRHASH +char *ne_vstrhash(unsigned int flags, va_list ap) +{ + char ret[33]; + const char *arg; + struct ne_md5_ctx *ctx; + + if (flags != NE_STRHASH_MD5) return NULL; + + ctx = ne_md5_create_ctx(); + if (!ctx) return NULL; + + while ((arg = va_arg(ap, const char *)) != NULL) + ne_md5_process_bytes(arg, strlen(arg), ctx); + + ne_md5_finish_ascii(ctx, ret); + ne_md5_destroy_ctx(ctx); + + return ne_strdup(ret); +} +#endif diff --git a/src/ne_string.h b/src/ne_string.h index 813b33b..8baea5a 100644 --- a/src/ne_string.h +++ b/src/ne_string.h @@ -149,6 +149,18 @@ char *ne_strnqdup(const unsigned char *data, size_t len); char *ne_concat(const char *str, ...) ne_attribute_sentinel; +/* Calculate hash over concatenation of NUL-terminated const char * + * string arguments, up to a terminating NULL pointer, and return as a + * malloc-allocated ASCII hex string. Uses hash type specified by + * 'flags', which must be non-zero. Returns NULL if the hash type is + * not supported or an internal error occurs. */ +#define NE_STRHASH_MD5 (0x0001) +char *ne_strhash(unsigned int flags, ...) + ne_attribute_sentinel; +/* Equivalent of ne_strhash(), taking va_list argument; the behaviour + * is otherwise identical. */ +char *ne_vstrhash(unsigned int flags, va_list ap); + /* Wrapper for snprintf: always NUL-terminates returned buffer, and * returns strlen(str). */ size_t ne_snprintf(char *str, size_t size, const char *fmt, ...) diff --git a/src/neon.vers b/src/neon.vers index 3fed94d..de4b327 100644 --- a/src/neon.vers +++ b/src/neon.vers @@ -25,3 +25,8 @@ NEON_0_31 { ne_path_escapef; ne_207_set_flags; }; + +NEON_0_32 { + ne_strhash; + ne_vstrhash; +}; diff --git a/test/auth.c b/test/auth.c index bdd1867..622b945 100644 --- a/test/auth.c +++ b/test/auth.c @@ -29,11 +29,8 @@ #include <unistd.h> #endif -#ifdef HAVE_OPENSSL11 -#include <openssl/evp.h> -#endif #include "ne_md5.h" - +#include "ne_string.h" #include "ne_request.h" #include "ne_auth.h" #include "ne_basic.h" @@ -418,57 +415,32 @@ struct digest_state { int uhash_bool; }; -#ifdef HAVE_OPENSSL11 -#define hash_process(str, len, ctx) if (EVP_DigestUpdate(ctx, str, len) != 1) return -1 -#define hash_reset(ctx) if (EVP_DigestInit(ctx, md) != 1) return -1 -#define hash_create(ctx) hash_reset(ctx) -#define hash_final(ctx, out) do { unsigned char v[EVP_MAX_MD_SIZE]; EVP_DigestFinal_ex(ctx, v, NULL); ne_md5_to_ascii(v, out); } while (0) -#define hash_destroy(ctx) EVP_MD_CTX_free(ctx) -#else -#define hash_process(str, len, ctx) ne_md5_process_bytes(str, len, ctx) -#define hash_reset(ctx) ne_md5_reset_ctx(ctx) -#define hash_final(ctx, out) ne_md5_finish_ascii(ctx, out) -#define hash_destroy(ctx) ne_md5_destroy_ctx(ctx); -#endif - static char *hash(struct digest_parms *p, char digest[33], ...) ne_attribute_sentinel; static char *hash(struct digest_parms *p, char digest[33], ...) { va_list ap; - const char *arg; -#ifdef HAVE_OPENSSL11 - EVP_MD_CTX *ctx = EVP_MD_CTX_new(); - const EVP_MD *md; -#else - struct ne_md5_ctx *ctx; -#endif + unsigned int flags; + char *h; -#ifdef HAVE_OPENSSL11 - switch (parms->alg) { + switch (p->alg) { case ALG_SHA256_SESS: case ALG_SHA256: - md = EVP_sha256(); + abort(); break; default: - md = EVP_md5(); + flags = NE_STRHASH_MD5; break; } - if (EVP_DigestInit(ctx, md) != 1) return NULL; -#else - ctx = ne_md5_create_ctx(); -#endif - va_start(ap, digest); - while ((arg = va_arg(ap, char *)) != NULL) - hash_process(arg, strlen(arg), ctx); + h = ne_vstrhash(flags, ap); va_end(ap); - hash_final(ctx, digest); - hash_destroy(ctx); - + if (h == NULL) abort(); + memcpy(digest, h, 33); + ne_free(h); return digest; } diff --git a/test/string-tests.c b/test/string-tests.c index 2f1f2ff..68fac46 100644 --- a/test/string-tests.c +++ b/test/string-tests.c @@ -650,6 +650,23 @@ static int qappend(void) return OK; } +static int strhash(void) +{ + char *h; + + ONN("zero flags must return NULL", ne_strhash(0, "", NULL) != NULL); + + h = ne_strhash(NE_STRHASH_MD5, "", NULL); + ONCMP(h, "d41d8cd98f00b204e9800998ecf8427e"); + ne_free(h); + + h = ne_strhash(NE_STRHASH_MD5, "foo", "ba", "r", NULL); + ONCMP(h, "3858f62230ac3c915f300c664312c63f"); + ne_free(h); + + return OK; +} + ne_test tests[] = { T(simple), T(buf_concat), @@ -678,6 +695,7 @@ ne_test tests[] = { T(casencmp), T(buf_print), T(qappend), + T(strhash), T(NULL) }; |