summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoe Orton <joe@manyfish.uk>2020-06-08 22:59:29 +0100
committerJoe Orton <jorton@apache.org>2020-06-18 08:01:27 +0100
commit379e5c250d0b8c661364fd435c50232486b33ba9 (patch)
treeac97a4d5a84ac68b4e2b0aad55190f27eefbcf48
parent8af18bb316e0e1d31dd8a5decf20683510409e8b (diff)
downloadneon-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.c24
-rw-r--r--src/ne_string.c41
-rw-r--r--src/ne_string.h12
-rw-r--r--src/neon.vers5
-rw-r--r--test/auth.c48
-rw-r--r--test/string-tests.c18
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)
};