diff options
author | Joe Orton <jorton@redhat.com> | 2020-11-30 15:56:52 +0000 |
---|---|---|
committer | Joe Orton <jorton@apache.org> | 2020-12-06 10:11:52 +0000 |
commit | d11faf1397cdc1442a46929167594feb725c70a3 (patch) | |
tree | 6d023599e8e225906b557e5fbad6ea01ad7bd943 | |
parent | 1a873f59d354474c86741f52e5b3c429639d41b8 (diff) | |
download | neon-git-d11faf1397cdc1442a46929167594feb725c70a3.tar.gz |
Support colon- and space-separated output for ne_strhash/ne_vstrhash.
* src/ne_internal.h: Add flags argument to ne__strhash2hex, define
NE_HASH_ALGMASK.
* src/ne_string.h: Define NE_HASH_COLON, NE_HASH_SPACE, update flags
description for ne_strhash.
* src/ne_string.c (ne__strhash2hex): Take flags argument, use colon
and space separated output as required.
(ne_vstrhash): Use ne__strhash2hex, NE_HASH_ALGMASK.
* test/string-tests.c (strhash, strhash_sha_512_256): Tests for
NE_HASH_COLON and NE_HASH_SPACE.
* src/ne_openssl.c, ne_gnutls.c (ne_vstrhash): Pass flags to
ne__strhash2hex, use NE_HASH_ALGMASK.
-rw-r--r-- | src/ne_gnutls.c | 4 | ||||
-rw-r--r-- | src/ne_internal.h | 4 | ||||
-rw-r--r-- | src/ne_openssl.c | 4 | ||||
-rw-r--r-- | src/ne_string.c | 38 | ||||
-rw-r--r-- | src/ne_string.h | 13 | ||||
-rw-r--r-- | test/string-tests.c | 7 |
6 files changed, 52 insertions, 18 deletions
diff --git a/src/ne_gnutls.c b/src/ne_gnutls.c index 7d7e661..d709590 100644 --- a/src/ne_gnutls.c +++ b/src/ne_gnutls.c @@ -1516,7 +1516,7 @@ char *ne_vstrhash(unsigned int flags, va_list ap) unsigned len; char *rv; - switch (flags) { + switch (flags & NE_HASH_ALGMASK) { case NE_HASH_MD5: alg = GNUTLS_DIG_MD5; break; case NE_HASH_SHA256: alg = GNUTLS_DIG_SHA256; break; default: return NULL; @@ -1532,7 +1532,7 @@ char *ne_vstrhash(unsigned int flags, va_list ap) out = ne_malloc(len); gnutls_hash_deinit(hd, out); - rv = ne__strhash2hex(out, len); + rv = ne__strhash2hex(out, len, flags); ne_free(out); return rv; } diff --git a/src/ne_internal.h b/src/ne_internal.h index 910842b..e9fc455 100644 --- a/src/ne_internal.h +++ b/src/ne_internal.h @@ -83,8 +83,10 @@ #endif #endif /* NE_LFS */ +#define NE_HASH_ALGMASK (0x000f) + /* Return malloc-allocated ASCII hexadecimal representation of * input. */ -NE_PRIVATE char *ne__strhash2hex(unsigned char *digest, size_t len); +NE_PRIVATE char *ne__strhash2hex(const unsigned char *digest, size_t len, unsigned int flags); #endif /* NE_INTERNAL_H */ diff --git a/src/ne_openssl.c b/src/ne_openssl.c index 49ffaa8..b6da323 100644 --- a/src/ne_openssl.c +++ b/src/ne_openssl.c @@ -1147,7 +1147,7 @@ char *ne_vstrhash(unsigned int flags, va_list ap) unsigned int vlen; const char *arg; - switch (flags) { + switch (flags & NE_HASH_ALGMASK) { case NE_HASH_MD5: md = EVP_md5(); break; case NE_HASH_SHA256: md = EVP_sha256(); break; #ifdef HAVE_OPENSSL11 @@ -1165,7 +1165,7 @@ char *ne_vstrhash(unsigned int flags, va_list ap) EVP_DigestFinal_ex(ctx, v, &vlen); EVP_MD_CTX_free(ctx); - return ne__strhash2hex(v, vlen); + return ne__strhash2hex(v, vlen, flags); } #if defined(NE_HAVE_TS_SSL) && OPENSSL_VERSION_NUMBER < 0x10100000L diff --git a/src/ne_string.c b/src/ne_string.c index ce683cc..30bb468 100644 --- a/src/ne_string.c +++ b/src/ne_string.c @@ -35,6 +35,7 @@ #endif #include <stdio.h> +#include <assert.h> #include "ne_alloc.h" #include "ne_string.h" @@ -636,11 +637,11 @@ char *ne_strhash(unsigned int flags, ...) #ifdef NEED_VSTRHASH char *ne_vstrhash(unsigned int flags, va_list ap) { - char ret[33]; const char *arg; struct ne_md5_ctx *ctx; + unsigned int resbuf[4]; - if (flags != NE_HASH_MD5) return NULL; + if ((flags & NE_HASH_ALGMASK) != NE_HASH_MD5) return NULL; ctx = ne_md5_create_ctx(); if (!ctx) return NULL; @@ -648,24 +649,43 @@ char *ne_vstrhash(unsigned int flags, va_list ap) while ((arg = va_arg(ap, const char *)) != NULL) ne_md5_process_bytes(arg, strlen(arg), ctx); - ne_md5_finish_ascii(ctx, ret); + ne_md5_finish_ctx(ctx, resbuf); ne_md5_destroy_ctx(ctx); - return ne_strdup(ret); + return ne__strhash2hex((void *)&resbuf, sizeof resbuf, flags); } #endif -char *ne__strhash2hex(unsigned char *digest, size_t len) +char *ne__strhash2hex(const unsigned char *digest, size_t len, + unsigned int flags) { - char *rv = ne_malloc(len * 2 + 1); + unsigned char sep = '\0'; + size_t step = 2; + char *rv, *p; size_t n; + assert(len > 0); + + if ((flags & NE_HASH_COLON)) { + step = 3; + sep = ':'; + } + else if ((flags & NE_HASH_SPACE)) { + step = 3; + sep = ' '; + } + + p = rv = ne_malloc(len * step + 1); + for (n = 0; n < len; n++) { - rv[n*2] = NE_HEX2ASC(digest[n] >> 4); - rv[n*2+1] = NE_HEX2ASC(digest[n] & 0x0f); + *p++ = NE_HEX2ASC(digest[n] >> 4); + *p++ = NE_HEX2ASC(digest[n] & 0x0f); + if (sep) *p++ = sep; } - rv[len*2] = '\0'; + if (sep) p--; + + *p = '\0'; return rv; } diff --git a/src/ne_string.h b/src/ne_string.h index 8b18c5a..01b69a4 100644 --- a/src/ne_string.h +++ b/src/ne_string.h @@ -152,16 +152,21 @@ char *ne_strnqdup(const unsigned char *data, size_t len) char *ne_concat(const char *str, ...) ne_attribute_sentinel; -/* Hash algorithms. */ +/* Hash algorithms: */ #define NE_HASH_MD5 (0x0001) /* MD5 */ #define NE_HASH_SHA256 (0x0002) /* SHA-2-256 */ #define NE_HASH_SHA512_256 (0x0003) /* SHA-2-512 */ +/* Optional hash output formatting options: */ +#define NE_HASH_COLON (0x1000) /* Colon-separated pairs */ +#define NE_HASH_SPACE (0x2000) /* Space-separated pairs */ + /* 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 equal exactly one of the NE_HASH_ values above. - * Returns NULL if the hash type is not supported or an internal error + * malloc-allocated ASCII hex string. 'flags' comprises exactly one + * of the algorithms indicated by the NE_HASH_* values above, which + * may optionally be combined with the formatting options. Returns + * NULL if the hash type is not supported or an internal error * occurs. */ char *ne_strhash(unsigned int flags, ...) ne_attribute_sentinel ne_attribute_malloc; diff --git a/test/string-tests.c b/test/string-tests.c index 39d8c57..294e581 100644 --- a/test/string-tests.c +++ b/test/string-tests.c @@ -672,9 +672,13 @@ static int strhash(void) { ONN("zero flags must return NULL", ne_strhash(0, "", NULL) != NULL); ONN("zero flags must return NULL for vstrhash", test_vstrhash(0, "", NULL) != NULL); + + ONN("no alg flags must return NULL", ne_strhash(NE_HASH_COLON, "", NULL) != NULL); + ONN("no alg flags must return NULL", ne_strhash(NE_HASH_SPACE, "", NULL) != NULL); ONVEC((NE_HASH_MD5, "", NULL), "d41d8cd98f00b204e9800998ecf8427e"); ONVEC((NE_HASH_MD5, "foo", "ba", "r", NULL), "3858f62230ac3c915f300c664312c63f"); + ONVEC((NE_HASH_MD5|NE_HASH_SPACE, "foo", "ba", "r", NULL), "38 58 f6 22 30 ac 3c 91 5f 30 0c 66 43 12 c6 3f"); return OK; } @@ -701,6 +705,7 @@ static int strhash_sha_256(void) #define TEST2_512_256_1 "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijkl" #define TEST2_512_256_2 "mnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu" #define TEST2_512_256_MD "3928e184fb8690f840da3988121d31be65cb9d3ef83ee6146feac861e19b563a" +#define TEST2_512_256_MDC "39:28:e1:84:fb:86:90:f8:40:da:39:88:12:1d:31:be:65:cb:9d:3e:f8:3e:e6:14:6f:ea:c8:61:e1:9b:56:3a" static int strhash_sha_512_256(void) { @@ -714,6 +719,8 @@ static int strhash_sha_512_256(void) ONVEC((NE_HASH_SHA512_256, TEST1_512_256, NULL), TEST1_512_256_MD); ONVEC((NE_HASH_SHA512_256, TEST2_512_256_1, TEST2_512_256_2, NULL), TEST2_512_256_MD); + ONVEC((NE_HASH_SHA512_256|NE_HASH_COLON, TEST2_512_256_1, TEST2_512_256_2, NULL), + TEST2_512_256_MDC); return OK; } |