Make the digest and HMAC function of OpenSSL accesable to the user via converters. e.g. They can be used to sign and validate cookies. --- Makefile | 2 +- src/crypto.c | 84 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 85 insertions(+), 1 deletion(-) create mode 100644 src/crypto.c
diff --git a/Makefile b/Makefile index 5d170041..9a3a5024 100644 --- a/Makefile +++ b/Makefile @@ -609,7 +609,7 @@ OPTIONS_LDFLAGS += $(if $(SSL_LIB),-L$(SSL_LIB)) -lssl -lcrypto ifneq ($(USE_DL),) OPTIONS_LDFLAGS += -ldl endif -OPTIONS_OBJS += src/ssl_sock.o +OPTIONS_OBJS += src/crypto.o src/ssl_sock.o endif # The private cache option affect the way the shctx is built diff --git a/src/crypto.c b/src/crypto.c new file mode 100644 index 00000000..dcb343dc --- /dev/null +++ b/src/crypto.c @@ -0,0 +1,84 @@ +/* + * Crypto converters + * + * Copyright 2018 Patrick Gansterer <[email protected]> + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + * + */ + +#include <common/chunk.h> + +#include <proto/arg.h> +#include <proto/sample.h> + +#include <openssl/evp.h> +#include <openssl/hmac.h> + +static int sample_conv_crypto_digest(const struct arg *args, struct sample *smp, void *private) +{ + struct chunk *trash = get_trash_chunk(); + EVP_MD_CTX *ctx = EVP_MD_CTX_new(); + const EVP_MD *evp = EVP_get_digestbyname(args[0].data.str.str); + unsigned char *md = (unsigned char*) trash->str; + unsigned int md_len = trash->size; + + if (!ctx) + return 0; + if (!evp) + return 0; + + if (!EVP_DigestInit(ctx, evp) || + !EVP_DigestUpdate(ctx, smp->data.u.str.str, smp->data.u.str.len) || + !EVP_DigestFinal(ctx, md, &md_len)) { + EVP_MD_CTX_free(ctx); + return 0; + } + + EVP_MD_CTX_free(ctx); + + trash->len = md_len; + smp->data.u.str = *trash; + smp->data.type = SMP_T_BIN; + smp->flags &= ~SMP_F_CONST; + return 1; +} + +static int sample_conv_crypto_hmac(const struct arg *args, struct sample *smp, void *private) +{ + struct chunk *trash = get_trash_chunk(); + const EVP_MD *evp = EVP_get_digestbyname(args[0].data.str.str); + const char* key = args[1].data.str.str; + int key_len = args[1].data.str.len; + unsigned char *md = (unsigned char*) trash->str; + unsigned int md_len = trash->size; + + trash->len = 0; + + if (!evp) + return 0; + + if (!HMAC(evp, key, key_len, (const unsigned char*) smp->data.u.str.str, smp->data.u.str.len, md, &md_len)) + return 0; + + trash->len = md_len; + smp->data.u.str = *trash; + smp->data.type = SMP_T_BIN; + smp->flags &= ~SMP_F_CONST; + return 1; +} + +static struct sample_conv_kw_list sample_conv_kws = {ILH, { + { "digest", sample_conv_crypto_digest, ARG1(1,STR), NULL, SMP_T_BIN, SMP_T_BIN }, + { "hmac", sample_conv_crypto_hmac, ARG2(2,STR,STR), NULL, SMP_T_BIN, SMP_T_BIN }, + { /* END */ }, +}}; + +__attribute__((constructor)) +static void __crypto_init(void) +{ + sample_register_convs(&sample_conv_kws); +} -- 2.17.1

