summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoe Orton <jorton@redhat.com>2020-11-30 15:56:52 +0000
committerJoe Orton <jorton@apache.org>2020-12-06 10:11:52 +0000
commitd11faf1397cdc1442a46929167594feb725c70a3 (patch)
tree6d023599e8e225906b557e5fbad6ea01ad7bd943
parent1a873f59d354474c86741f52e5b3c429639d41b8 (diff)
downloadneon-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.c4
-rw-r--r--src/ne_internal.h4
-rw-r--r--src/ne_openssl.c4
-rw-r--r--src/ne_string.c38
-rw-r--r--src/ne_string.h13
-rw-r--r--test/string-tests.c7
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;
}