Re: [PATCH] MINOR: crypto: Add digest and hmac converters

2020-05-12 Thread Christopher Faulet

Le 08/05/2020 à 10:00, Christopher Faulet a écrit :

Le 07/05/2020 à 18:54, Patrick Gansterer a écrit :

Then here is my next try. ;-)

I've rebased my changes to reflect the recent changes and added the
missing description to the first patch.


Hi Patrick,

Thanks. It looks good for me. I've only a comment. I discussed it with Willy and
William. Instead of creating a new file, we prefer to move these converters in
sample.c. There are already some other hash functions in this file (sha1,
sha2...). So it is a good place for these ones too and it avoids to add a new
file. I also changed the required version in the reg-test scripts to set it to 
2.2.

Sorry, I would have liked to be faster and save you from unnecessary work. I
don't want to ask you to rework your patches again, thus I've amended them.
You'll find them in attachment. If it is ok for you, I'll merge it. Otherwise,
feel free to rework it according to your taste.



Merged now, Thanks !

--
Christopher Faulet



Re: [PATCH] MINOR: crypto: Add digest and hmac converters

2020-05-08 Thread Christopher Faulet

Le 07/05/2020 à 18:54, Patrick Gansterer a écrit :

Then here is my next try. ;-)

I've rebased my changes to reflect the recent changes and added the
missing description to the first patch.


Hi Patrick,

Thanks. It looks good for me. I've only a comment. I discussed it with Willy and 
William. Instead of creating a new file, we prefer to move these converters in 
sample.c. There are already some other hash functions in this file (sha1, 
sha2...). So it is a good place for these ones too and it avoids to add a new 
file. I also changed the required version in the reg-test scripts to set it to 2.2.


Sorry, I would have liked to be faster and save you from unnecessary work. I 
don't want to ask you to rework your patches again, thus I've amended them. 
You'll find them in attachment. If it is ok for you, I'll merge it. Otherwise, 
feel free to rework it according to your taste.


--
Christopher Faulet
>From 546605a62872c9fa8b6a26b1ea33750c3b92b510 Mon Sep 17 00:00:00 2001
From: Patrick Gansterer 
Date: Sun, 17 Jun 2018 11:21:11 +0200
Subject: [PATCH 1/2] MINOR: sample: Move aes_gcm_dec implementation into
 sample.c

aes_gcm_dec is independent of the TLS implementation and fits better
in sample.c file with others hash functions.

[Cf: I slightly updated this patch to move aes_gcm_dec converter in sample.c
 instead the new file crypto.c]

Reviewed-by: Tim Duesterhus 
---
 src/sample.c   | 138 ++-
 src/ssl_sock.c | 142 -
 2 files changed, 137 insertions(+), 143 deletions(-)

diff --git a/src/sample.c b/src/sample.c
index 12724f73d..1be945993 100644
--- a/src/sample.c
+++ b/src/sample.c
@@ -1653,7 +1653,140 @@ static int sample_conv_sha2(const struct arg *arg_p, struct sample *smp, void *p
 	smp->flags &= ~SMP_F_CONST;
 	return 1;
 }
-#endif
+
+#if (HA_OPENSSL_VERSION_NUMBER >= 0x1000100fL)
+static inline int sample_conv_var2smp_str(const struct arg *arg, struct sample *smp)
+{
+	switch (arg->type) {
+	case ARGT_STR:
+		smp->data.type = SMP_T_STR;
+		smp->data.u.str = arg->data.str;
+		return 1;
+	case ARGT_VAR:
+		if (!vars_get_by_desc(>data.var, smp))
+return 0;
+		if (!sample_casts[smp->data.type][SMP_T_STR])
+return 0;
+		if (!sample_casts[smp->data.type][SMP_T_STR](smp))
+return 0;
+		return 1;
+	default:
+		return 0;
+	}
+}
+
+static int check_aes_gcm(struct arg *args, struct sample_conv *conv,
+		  const char *file, int line, char **err)
+{
+	switch(args[0].data.sint) {
+	case 128:
+	case 192:
+	case 256:
+		break;
+	default:
+		memprintf(err, "key size must be 128, 192 or 256 (bits).");
+		return 0;
+	}
+	/* Try to decode a variable. */
+	vars_check_arg([1], NULL);
+	vars_check_arg([2], NULL);
+	vars_check_arg([3], NULL);
+	return 1;
+}
+
+/* Arguments: AES size in bits, nonce, key, tag. The last three arguments are base64 encoded */
+static int sample_conv_aes_gcm_dec(const struct arg *arg_p, struct sample *smp, void *private)
+{
+	struct sample nonce, key, aead_tag;
+	struct buffer *smp_trash, *smp_trash_alloc;
+	EVP_CIPHER_CTX *ctx;
+	int dec_size, ret;
+
+	smp_set_owner(, smp->px, smp->sess, smp->strm, smp->opt);
+	if (!sample_conv_var2smp_str(_p[1], ))
+		return 0;
+
+	smp_set_owner(, smp->px, smp->sess, smp->strm, smp->opt);
+	if (!sample_conv_var2smp_str(_p[2], ))
+		return 0;
+
+	smp_set_owner(_tag, smp->px, smp->sess, smp->strm, smp->opt);
+	if (!sample_conv_var2smp_str(_p[3], _tag))
+		return 0;
+
+	smp_trash = get_trash_chunk();
+	smp_trash_alloc = alloc_trash_chunk();
+	if (!smp_trash_alloc)
+		return 0;
+
+	ctx = EVP_CIPHER_CTX_new();
+
+	if (!ctx)
+		goto err;
+
+	dec_size = base64dec(nonce.data.u.str.area, nonce.data.u.str.data, smp_trash->area, smp_trash->size);
+	if (dec_size < 0)
+		goto err;
+	smp_trash->data = dec_size;
+
+	/* Set cipher type and mode */
+	switch(arg_p[0].data.sint) {
+	case 128:
+		EVP_DecryptInit_ex(ctx, EVP_aes_128_gcm(), NULL, NULL, NULL);
+		break;
+	case 192:
+		EVP_DecryptInit_ex(ctx, EVP_aes_192_gcm(), NULL, NULL, NULL);
+		break;
+	case 256:
+		EVP_DecryptInit_ex(ctx, EVP_aes_256_gcm(), NULL, NULL, NULL);
+		break;
+	}
+
+	EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_IVLEN, smp_trash->data, NULL);
+
+	/* Initialise IV */
+	if(!EVP_DecryptInit_ex(ctx, NULL, NULL, NULL, (unsigned char *) smp_trash->area))
+		goto err;
+
+	dec_size = base64dec(key.data.u.str.area, key.data.u.str.data, smp_trash->area, smp_trash->size);
+	if (dec_size < 0)
+		goto err;
+	smp_trash->data = dec_size;
+
+	/* Initialise key */
+	if (!EVP_DecryptInit_ex(ctx, NULL, NULL, (unsigned char *) smp_trash->area, NULL))
+		goto err;
+
+	if (!EVP_DecryptUpdate(ctx, (unsigned char *) smp_trash->area, (int *) _trash->data,
+		  (unsigned char *) smp->data.u.str.area, (int) smp->data.u.str.data))
+		goto err;
+
+	dec_size = base64dec(aead_tag.data.u.str.area, aead_tag.data.u.str.data, smp_trash_alloc->area, smp_trash_alloc->size);
+	if (dec_size < 0)
+		goto err;
+	

Re: [PATCH] MINOR: crypto: Add digest and hmac converters

2020-05-07 Thread Tim Düsterhus
Patrick,

Am 07.05.20 um 18:54 schrieb Patrick Gansterer:
>> I skipped the patch (that's why I did not ACK the first, but only the
>> second one), because it was a very large change of code that was just
>> moved. Nonetheless I should have noticed the missing body and noted that
>> during my review.
> 
> IMHO, that's a patch you usually do not want review.

Yes, that's why I did not. However the commit message is not directly
part of the patch, so I should have.

>> Please note that I review patches on a voluntary basis. I'm not an
>> "employed first level reviewer".
> 
> That's not what I meant. I thought that when regular participants on
> this list do not spot the errors of first time contributes, it can't be
> that obvious and directing to CONTRIBUTING might not be enough.

I agree with you that Willy's reply was overly blunt in this case.
Especially since you demonstrated an effort to take my review into a
account and he noticed my Ack (implying it can't be too bad).

>> Liking HAProxy and wanting to give something back is my motivation as
>> well. I am very sorry to see how this experience went for you. If it is
>> of any help to you: This is definitely not how it usually goes.
> 
> Then here is my next try. ;-)
> 
> I've rebased my changes to reflect the recent changes and added the
> missing description to the first patch.

I've now taken a look at both patches now and both are:

Reviewed-by: Tim Duesterhus 

Best regards
Tim Düsterhus



Re: [PATCH] MINOR: crypto: Add digest and hmac converters

2020-05-07 Thread Patrick Gansterer
On 07.05.20 18:23, Tim Düsterhus wrote:> This is about your "[PATCH 1/2] 
MINOR: crypto: Move aes_gcm_dec

implementation into new file". It does not contain a body, but instead
just a subject.


Ok, agree.


I skipped the patch (that's why I did not ACK the first, but only the
second one), because it was a very large change of code that was just
moved. Nonetheless I should have noticed the missing body and noted that
during my review.


IMHO, that's a patch you usually do not want review.


Please note that I review patches on a voluntary basis. I'm not an
"employed first level reviewer".


That's not what I meant. I thought that when regular participants on 
this list do not spot the errors of first time contributes, it can't be 
that obvious and directing to CONTRIBUTING might not be enough.



Liking HAProxy and wanting to give something back is my motivation as
well. I am very sorry to see how this experience went for you. If it is
of any help to you: This is definitely not how it usually goes.


Then here is my next try. ;-)

I've rebased my changes to reflect the recent changes and added the 
missing description to the first patch.


- Patrick
>From 9125c6df81e135275c450a0be32bcd0b58ef2099 Mon Sep 17 00:00:00 2001
From: Patrick Gansterer 
Date: Sun, 17 Jun 2018 11:21:11 +0200
Subject: [PATCH 1/2] MINOR: crypto: Move aes_gcm_dec implementation into new
 file

aes_gcm_dec is independent of the TLS implementation and fits better
in a separate file dedicated to crypto functionality.
This gives converters which depend on OpenSSL a clear home.
---
 Makefile   |   2 +-
 src/crypto.c   | 163 +
 src/ssl_sock.c | 142 --
 3 files changed, 164 insertions(+), 143 deletions(-)
 create mode 100644 src/crypto.c

diff --git a/Makefile b/Makefile
index 1e4213989..2dea46368 100644
--- a/Makefile
+++ b/Makefile
@@ -542,7 +542,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 0..74b92eee5
--- /dev/null
+++ b/src/crypto.c
@@ -0,0 +1,163 @@
+/*
+ * Crypto converters
+ *
+ * Copyright 2020 Nenad Merdanovic 
+ *
+ * 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 
+#include 
+#include 
+
+#include 
+#include 
+#include 
+
+#include 
+
+#if (HA_OPENSSL_VERSION_NUMBER >= 0x1000100fL)
+static inline int sample_conv_var2smp_str(const struct arg *arg, struct sample *smp)
+{
+	switch (arg->type) {
+	case ARGT_STR:
+		smp->data.type = SMP_T_STR;
+		smp->data.u.str = arg->data.str;
+		return 1;
+	case ARGT_VAR:
+		if (!vars_get_by_desc(>data.var, smp))
+return 0;
+		if (!sample_casts[smp->data.type][SMP_T_STR])
+return 0;
+		if (!sample_casts[smp->data.type][SMP_T_STR](smp))
+return 0;
+		return 1;
+	default:
+		return 0;
+	}
+}
+
+static int check_aes_gcm(struct arg *args, struct sample_conv *conv,
+		  const char *file, int line, char **err)
+{
+	switch(args[0].data.sint) {
+	case 128:
+	case 192:
+	case 256:
+		break;
+	default:
+		memprintf(err, "key size must be 128, 192 or 256 (bits).");
+		return 0;
+	}
+	/* Try to decode a variable. */
+	vars_check_arg([1], NULL);
+	vars_check_arg([2], NULL);
+	vars_check_arg([3], NULL);
+	return 1;
+}
+
+/* Arguments: AES size in bits, nonce, key, tag. The last three arguments are base64 encoded */
+static int sample_conv_aes_gcm_dec(const struct arg *arg_p, struct sample *smp, void *private)
+{
+	struct sample nonce, key, aead_tag;
+	struct buffer *smp_trash, *smp_trash_alloc;
+	EVP_CIPHER_CTX *ctx;
+	int dec_size, ret;
+
+	smp_set_owner(, smp->px, smp->sess, smp->strm, smp->opt);
+	if (!sample_conv_var2smp_str(_p[1], ))
+		return 0;
+
+	smp_set_owner(, smp->px, smp->sess, smp->strm, smp->opt);
+	if (!sample_conv_var2smp_str(_p[2], ))
+		return 0;
+
+	smp_set_owner(_tag, smp->px, smp->sess, smp->strm, smp->opt);
+	if (!sample_conv_var2smp_str(_p[3], _tag))
+		return 0;
+
+	smp_trash = get_trash_chunk();
+	smp_trash_alloc = alloc_trash_chunk();
+	if (!smp_trash_alloc)
+		return 0;
+
+	ctx = EVP_CIPHER_CTX_new();
+
+	if (!ctx)
+		goto err;
+
+	dec_size = base64dec(nonce.data.u.str.area, nonce.data.u.str.data, smp_trash->area, smp_trash->size);
+	if (dec_size < 0)
+		goto err;
+	smp_trash->data = dec_size;
+
+	/* Set cipher type and mode */
+	switch(arg_p[0].data.sint) {
+	case 128:
+		EVP_DecryptInit_ex(ctx, EVP_aes_128_gcm(), NULL, NULL, NULL);
+		break;
+	case 192:
+		EVP_DecryptInit_ex(ctx, EVP_aes_192_gcm(), NULL, NULL, NULL);
+		break;
+	case 256:
+		

Re: [PATCH] MINOR: crypto: Add digest and hmac converters

2020-05-07 Thread Tim Düsterhus
Patrick,

Am 07.05.20 um 18:04 schrieb Patrick Gansterer:
> On 07.05.20 17:35, Willy Tarreau wrote:
>> Indeed. I encourage to ping again after one week because usually when you
>> restart with a new week of work, the previous one is definitely in old
>> history and will only be revisited by pure luck.
> 
> I don't want to look impatient, so I waited 2 weeks. ;-)
> 
>> With this said, I remember having noticed Tim's ack and was about to take
>> the series until I noticed there was a first patch with no commit message
>> to justify the change and postponed the reply because I had other things
>> to do than to rehash what's already in CONTRIBUTING again and again :-/
> 
> I'm not sure how I should read this. I wrote an explanation into the
> commit message and tried to match already existing messages. If I look
> at commits in the last days like 0e9d87bf06 or de80201460 there are no
> very long commit messages either.
> 
> If I should write an essay about my use case into the commit message I
> could do that, but that's something a "first level reviewer" could
> demand already.

This is about your "[PATCH 1/2] MINOR: crypto: Move aes_gcm_dec
implementation into new file". It does not contain a body, but instead
just a subject.

I skipped the patch (that's why I did not ACK the first, but only the
second one), because it was a very large change of code that was just
moved. Nonetheless I should have noticed the missing body and noted that
during my review.

Please note that I review patches on a voluntary basis. I'm not an
"employed first level reviewer".

> I read the CONTRIBUTING text before submitting my patch, since I don't
> like to repeat myself also, but it's hard to get everything right in the
> first patch. Sorry for that.

The "missing body" Willy was referring to is here, if you'd like to read
up on it:
https://github.com/haproxy/haproxy/blob/f82ea4ae4ca4a6fca70a6e874643db887a39f037/CONTRIBUTING#L562-L567

> I really like haproxy and want to give something back, but I'm not sure
> if I want to do that in the future with the experience I had so far. :-(
> 

Liking HAProxy and wanting to give something back is my motivation as
well. I am very sorry to see how this experience went for you. If it is
of any help to you: This is definitely not how it usually goes.

Best regards
Tim Düsterhus



Re: [PATCH] MINOR: crypto: Add digest and hmac converters

2020-05-07 Thread Patrick Gansterer

On 07.05.20 17:35, Willy Tarreau wrote:

Indeed. I encourage to ping again after one week because usually when you
restart with a new week of work, the previous one is definitely in old
history and will only be revisited by pure luck.


I don't want to look impatient, so I waited 2 weeks. ;-)


With this said, I remember having noticed Tim's ack and was about to take
the series until I noticed there was a first patch with no commit message
to justify the change and postponed the reply because I had other things
to do than to rehash what's already in CONTRIBUTING again and again :-/


I'm not sure how I should read this. I wrote an explanation into the 
commit message and tried to match already existing messages. If I look 
at commits in the last days like 0e9d87bf06 or de80201460 there are no 
very long commit messages either.


If I should write an essay about my use case into the commit message I 
could do that, but that's something a "first level reviewer" could 
demand already.


I read the CONTRIBUTING text before submitting my patch, since I don't 
like to repeat myself also, but it's hard to get everything right in the 
first patch. Sorry for that.


I really like haproxy and want to give something back, but I'm not sure 
if I want to do that in the future with the experience I had so far. :-(


- Patrick



Re: [PATCH] MINOR: crypto: Add digest and hmac converters

2020-05-07 Thread Willy Tarreau
On Thu, May 07, 2020 at 04:48:50PM +0200, Christopher Faulet wrote:
> Le 07/05/2020 à 13:03, Patrick Gansterer a écrit :
> > Hi,
> > 
> > On 22.04.20 18:30, Tim Düsterhus wrote:
> > > I don't find anything to complain about now. I'll now leave it up to the
> > > authority to either apply or complain.
> > 
> > How long does it usually take to get a response?
> > 
> > I posted a similar patch already 2 years ago and never got a response
> > from the maintainers. It would be nice if it could make its way into
> > 2.2, since it's not invasive and has proper testing.
> > If gets rejected I'm ok too, but it would be nice to know at least.
> > 
> > - Patrick
> > 
> 
> Hi Patrick,
> 
> Really sorry. 2 years! You're really patient :) As Tim said, don't hesitate
> to kindly harass us in this situation. It is pretty easy to miss some
> patches, lost in all other mails.

Indeed. I encourage to ping again after one week because usually when you
restart with a new week of work, the previous one is definitely in old
history and will only be revisited by pure luck.

With this said, I remember having noticed Tim's ack and was about to take
the series until I noticed there was a first patch with no commit message
to justify the change and postponed the reply because I had other things
to do than to rehash what's already in CONTRIBUTING again and again :-/

Cheers,
Willy



Re: [PATCH] MINOR: crypto: Add digest and hmac converters

2020-05-07 Thread Christopher Faulet

Le 07/05/2020 à 16:48, Christopher Faulet a écrit :

Le 07/05/2020 à 13:03, Patrick Gansterer a écrit :

Hi,

On 22.04.20 18:30, Tim Düsterhus wrote:

I don't find anything to complain about now. I'll now leave it up to the
authority to either apply or complain.


How long does it usually take to get a response?

I posted a similar patch already 2 years ago and never got a response
from the maintainers. It would be nice if it could make its way into
2.2, since it's not invasive and has proper testing.
If gets rejected I'm ok too, but it would be nice to know at least.

- Patrick



Hi Patrick,

Really sorry. 2 years! You're really patient :) As Tim said, don't hesitate to
kindly harass us in this situation. It is pretty easy to miss some patches, lost
in all other mails.

I will review your patches. At first glance, it looks good for me. I will just
enclose sample_conv_var2smp_str in the #if/#endif to avoid warning with older
openssl versions.



Sorry I misread your patch, it is ok for sample_conv_var2smp_str function...

--
Christopher Faulet



Re: [PATCH] MINOR: crypto: Add digest and hmac converters

2020-05-07 Thread Christopher Faulet

Le 07/05/2020 à 13:03, Patrick Gansterer a écrit :

Hi,

On 22.04.20 18:30, Tim Düsterhus wrote:

I don't find anything to complain about now. I'll now leave it up to the
authority to either apply or complain.


How long does it usually take to get a response?

I posted a similar patch already 2 years ago and never got a response
from the maintainers. It would be nice if it could make its way into
2.2, since it's not invasive and has proper testing.
If gets rejected I'm ok too, but it would be nice to know at least.

- Patrick



Hi Patrick,

Really sorry. 2 years! You're really patient :) As Tim said, don't hesitate to 
kindly harass us in this situation. It is pretty easy to miss some patches, lost 
in all other mails.


I will review your patches. At first glance, it looks good for me. I will just 
enclose sample_conv_var2smp_str in the #if/#endif to avoid warning with older 
openssl versions.


--
Christopher Faulet



Re: [PATCH] MINOR: crypto: Add digest and hmac converters

2020-05-07 Thread Tim Düsterhus
Patrick,

Am 07.05.20 um 13:03 schrieb Patrick Gansterer:
> Hi,
> 
> On 22.04.20 18:30, Tim Düsterhus wrote:
>> I don't find anything to complain about now. I'll now leave it up to the
>> authority to either apply or complain.
> 
> How long does it usually take to get a response?

Usually not this long. If a patch of mine waits longer than 2 weeks I
usually ask again. See also:
https://github.com/haproxy/haproxy/blob/d888f0fc6ee63abf9dbdab49adf14b63f3ccb1ad/CONTRIBUTING#L164

I've added Willy back to the Cc, I already did for the email you just
replied to.

Best regards
Tim Düsterhus



Re: [PATCH] MINOR: crypto: Add digest and hmac converters

2020-04-22 Thread Tim Düsterhus
Patrick,

Am 22.04.20 um 18:23 schrieb Patrick Gansterer:
> thx for the quick review. I attached a new patchset.
> 

I don't find anything to complain about now. I'll now leave it up to the
authority to either apply or complain.

For MINOR: crypto: Add digest and hmac converters

Reviewed-by: Tim Duesterhus 

Best regards
Tim Düsterhus



Re: [PATCH] MINOR: crypto: Add digest and hmac converters

2020-04-22 Thread Patrick Gansterer
Tim,

thx for the quick review. I attached a new patchset.

On Mittwoch, 22. April 2020 18:01:01 CEST Tim Düsterhus wrote:
> Small nit: It should read 'e.g.' (with a dot at the end).

Argh. Can't believe how many typos I made in this lines. ^^

> I believe you support a variable key now. You should add this to the doc
> (and the reg-test) then.

Done.

- Patrick>From 8f6ce045c80e0f67a485233ee602b57b4c311bde Mon Sep 17 00:00:00 2001
From: Patrick Gansterer 
Date: Sun, 17 Jun 2018 11:21:11 +0200
Subject: [PATCH 1/2] MINOR: crypto: Move aes_gcm_dec implementation into new
 file

---
 Makefile   |   2 +-
 src/crypto.c   | 163 +
 src/ssl_sock.c | 142 --
 3 files changed, 164 insertions(+), 143 deletions(-)
 create mode 100644 src/crypto.c

diff --git a/Makefile b/Makefile
index 1e4213989..2dea46368 100644
--- a/Makefile
+++ b/Makefile
@@ -542,7 +542,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 0..74b92eee5
--- /dev/null
+++ b/src/crypto.c
@@ -0,0 +1,163 @@
+/*
+ * Crypto converters
+ *
+ * Copyright 2020 Nenad Merdanovic 
+ *
+ * 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 
+#include 
+#include 
+
+#include 
+#include 
+#include 
+
+#include 
+
+#if (HA_OPENSSL_VERSION_NUMBER >= 0x1000100fL)
+static inline int sample_conv_var2smp_str(const struct arg *arg, struct sample *smp)
+{
+	switch (arg->type) {
+	case ARGT_STR:
+		smp->data.type = SMP_T_STR;
+		smp->data.u.str = arg->data.str;
+		return 1;
+	case ARGT_VAR:
+		if (!vars_get_by_desc(>data.var, smp))
+return 0;
+		if (!sample_casts[smp->data.type][SMP_T_STR])
+return 0;
+		if (!sample_casts[smp->data.type][SMP_T_STR](smp))
+return 0;
+		return 1;
+	default:
+		return 0;
+	}
+}
+
+static int check_aes_gcm(struct arg *args, struct sample_conv *conv,
+		  const char *file, int line, char **err)
+{
+	switch(args[0].data.sint) {
+	case 128:
+	case 192:
+	case 256:
+		break;
+	default:
+		memprintf(err, "key size must be 128, 192 or 256 (bits).");
+		return 0;
+	}
+	/* Try to decode a variable. */
+	vars_check_arg([1], NULL);
+	vars_check_arg([2], NULL);
+	vars_check_arg([3], NULL);
+	return 1;
+}
+
+/* Arguments: AES size in bits, nonce, key, tag. The last three arguments are base64 encoded */
+static int sample_conv_aes_gcm_dec(const struct arg *arg_p, struct sample *smp, void *private)
+{
+	struct sample nonce, key, aead_tag;
+	struct buffer *smp_trash, *smp_trash_alloc;
+	EVP_CIPHER_CTX *ctx;
+	int dec_size, ret;
+
+	smp_set_owner(, smp->px, smp->sess, smp->strm, smp->opt);
+	if (!sample_conv_var2smp_str(_p[1], ))
+		return 0;
+
+	smp_set_owner(, smp->px, smp->sess, smp->strm, smp->opt);
+	if (!sample_conv_var2smp_str(_p[2], ))
+		return 0;
+
+	smp_set_owner(_tag, smp->px, smp->sess, smp->strm, smp->opt);
+	if (!sample_conv_var2smp_str(_p[3], _tag))
+		return 0;
+
+	smp_trash = get_trash_chunk();
+	smp_trash_alloc = alloc_trash_chunk();
+	if (!smp_trash_alloc)
+		return 0;
+
+	ctx = EVP_CIPHER_CTX_new();
+
+	if (!ctx)
+		goto err;
+
+	dec_size = base64dec(nonce.data.u.str.area, nonce.data.u.str.data, smp_trash->area, smp_trash->size);
+	if (dec_size < 0)
+		goto err;
+	smp_trash->data = dec_size;
+
+	/* Set cipher type and mode */
+	switch(arg_p[0].data.sint) {
+	case 128:
+		EVP_DecryptInit_ex(ctx, EVP_aes_128_gcm(), NULL, NULL, NULL);
+		break;
+	case 192:
+		EVP_DecryptInit_ex(ctx, EVP_aes_192_gcm(), NULL, NULL, NULL);
+		break;
+	case 256:
+		EVP_DecryptInit_ex(ctx, EVP_aes_256_gcm(), NULL, NULL, NULL);
+		break;
+	}
+
+	EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_IVLEN, smp_trash->data, NULL);
+
+	/* Initialise IV */
+	if(!EVP_DecryptInit_ex(ctx, NULL, NULL, NULL, (unsigned char *) smp_trash->area))
+		goto err;
+
+	dec_size = base64dec(key.data.u.str.area, key.data.u.str.data, smp_trash->area, smp_trash->size);
+	if (dec_size < 0)
+		goto err;
+	smp_trash->data = dec_size;
+
+	/* Initialise key */
+	if (!EVP_DecryptInit_ex(ctx, NULL, NULL, (unsigned char *) smp_trash->area, NULL))
+		goto err;
+
+	if (!EVP_DecryptUpdate(ctx, (unsigned char *) smp_trash->area, (int *) _trash->data,
+		  (unsigned char *) smp->data.u.str.area, (int) smp->data.u.str.data))
+		goto err;
+
+	dec_size = base64dec(aead_tag.data.u.str.area, aead_tag.data.u.str.data, smp_trash_alloc->area, smp_trash_alloc->size);
+	if (dec_size < 0)
+		goto err;
+	smp_trash_alloc->data = dec_size;
+	dec_size = smp_trash->data;
+
+	EVP_CIPHER_CTX_ctrl(ctx, 

Re: [PATCH] MINOR: crypto: Add digest and hmac converters

2020-04-22 Thread Tim Düsterhus
Patrick,

Am 22.04.20 um 17:41 schrieb Patrick Gansterer:
> diff --git a/doc/configuration.txt b/doc/configuration.txt
> index 2e548b66c..6b5f5ecf9 100644
> --- a/doc/configuration.txt
> +++ b/doc/configuration.txt
> @@ -13918,6 +13918,13 @@ debug([])
>Example:
>  tcp-request connection track-sc0 src,debug(track-sc)
>  
> +digest()
> +  Converts a binary input sample to a message digest. The result is a binary
> +  sample. The algorithm must be an OpenSSL message digest name (e.g sha256).

Small nit: It should read 'e.g.' (with a dot at the end).

> @@ -13972,6 +13979,15 @@ hex2i
>Converts a hex string containing two hex digits per input byte to an
>integer. If the input value cannot be converted, then zero is returned.
>  
> +hmac(, )
> +  Converts a binary input sample to a message authentication code with the 
> given
> +  key. The result is a binary sample. The algorithm must be one of the 
> registered
> +  OpenSSL message digest names (e.g sha256). The key parameter must be base64
> +  encoded.

I believe you support a variable key now. You should add this to the doc
(and the reg-test) then.

> +  Please note that this converter is only available when haproxy has been
> +  compiled with USE_OPENSSL.
> +
>  http_date([])
>Converts an integer supposed to contain a date since epoch to a string
>representing this date in a format suitable for use in HTTP header fields. 
> If

Best regards
Tim Düsterhus



Re: [PATCH] MINOR: crypto: Add digest and hmac converters

2020-04-22 Thread Patrick Gansterer
Tim,

sorry for the troubles. My mail program added automatic line breaks. :-(

I attached the two files now.

- Patrick
>From 8f6ce045c80e0f67a485233ee602b57b4c311bde Mon Sep 17 00:00:00 2001
From: Patrick Gansterer 
Date: Sun, 17 Jun 2018 11:21:11 +0200
Subject: [PATCH 1/2] MINOR: crypto: Move aes_gcm_dec implementation into new
 file

---
 Makefile   |   2 +-
 src/crypto.c   | 163 +
 src/ssl_sock.c | 142 --
 3 files changed, 164 insertions(+), 143 deletions(-)
 create mode 100644 src/crypto.c

diff --git a/Makefile b/Makefile
index 1e4213989..2dea46368 100644
--- a/Makefile
+++ b/Makefile
@@ -542,7 +542,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 0..74b92eee5
--- /dev/null
+++ b/src/crypto.c
@@ -0,0 +1,163 @@
+/*
+ * Crypto converters
+ *
+ * Copyright 2020 Nenad Merdanovic 
+ *
+ * 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 
+#include 
+#include 
+
+#include 
+#include 
+#include 
+
+#include 
+
+#if (HA_OPENSSL_VERSION_NUMBER >= 0x1000100fL)
+static inline int sample_conv_var2smp_str(const struct arg *arg, struct sample *smp)
+{
+	switch (arg->type) {
+	case ARGT_STR:
+		smp->data.type = SMP_T_STR;
+		smp->data.u.str = arg->data.str;
+		return 1;
+	case ARGT_VAR:
+		if (!vars_get_by_desc(>data.var, smp))
+return 0;
+		if (!sample_casts[smp->data.type][SMP_T_STR])
+return 0;
+		if (!sample_casts[smp->data.type][SMP_T_STR](smp))
+return 0;
+		return 1;
+	default:
+		return 0;
+	}
+}
+
+static int check_aes_gcm(struct arg *args, struct sample_conv *conv,
+		  const char *file, int line, char **err)
+{
+	switch(args[0].data.sint) {
+	case 128:
+	case 192:
+	case 256:
+		break;
+	default:
+		memprintf(err, "key size must be 128, 192 or 256 (bits).");
+		return 0;
+	}
+	/* Try to decode a variable. */
+	vars_check_arg([1], NULL);
+	vars_check_arg([2], NULL);
+	vars_check_arg([3], NULL);
+	return 1;
+}
+
+/* Arguments: AES size in bits, nonce, key, tag. The last three arguments are base64 encoded */
+static int sample_conv_aes_gcm_dec(const struct arg *arg_p, struct sample *smp, void *private)
+{
+	struct sample nonce, key, aead_tag;
+	struct buffer *smp_trash, *smp_trash_alloc;
+	EVP_CIPHER_CTX *ctx;
+	int dec_size, ret;
+
+	smp_set_owner(, smp->px, smp->sess, smp->strm, smp->opt);
+	if (!sample_conv_var2smp_str(_p[1], ))
+		return 0;
+
+	smp_set_owner(, smp->px, smp->sess, smp->strm, smp->opt);
+	if (!sample_conv_var2smp_str(_p[2], ))
+		return 0;
+
+	smp_set_owner(_tag, smp->px, smp->sess, smp->strm, smp->opt);
+	if (!sample_conv_var2smp_str(_p[3], _tag))
+		return 0;
+
+	smp_trash = get_trash_chunk();
+	smp_trash_alloc = alloc_trash_chunk();
+	if (!smp_trash_alloc)
+		return 0;
+
+	ctx = EVP_CIPHER_CTX_new();
+
+	if (!ctx)
+		goto err;
+
+	dec_size = base64dec(nonce.data.u.str.area, nonce.data.u.str.data, smp_trash->area, smp_trash->size);
+	if (dec_size < 0)
+		goto err;
+	smp_trash->data = dec_size;
+
+	/* Set cipher type and mode */
+	switch(arg_p[0].data.sint) {
+	case 128:
+		EVP_DecryptInit_ex(ctx, EVP_aes_128_gcm(), NULL, NULL, NULL);
+		break;
+	case 192:
+		EVP_DecryptInit_ex(ctx, EVP_aes_192_gcm(), NULL, NULL, NULL);
+		break;
+	case 256:
+		EVP_DecryptInit_ex(ctx, EVP_aes_256_gcm(), NULL, NULL, NULL);
+		break;
+	}
+
+	EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_IVLEN, smp_trash->data, NULL);
+
+	/* Initialise IV */
+	if(!EVP_DecryptInit_ex(ctx, NULL, NULL, NULL, (unsigned char *) smp_trash->area))
+		goto err;
+
+	dec_size = base64dec(key.data.u.str.area, key.data.u.str.data, smp_trash->area, smp_trash->size);
+	if (dec_size < 0)
+		goto err;
+	smp_trash->data = dec_size;
+
+	/* Initialise key */
+	if (!EVP_DecryptInit_ex(ctx, NULL, NULL, (unsigned char *) smp_trash->area, NULL))
+		goto err;
+
+	if (!EVP_DecryptUpdate(ctx, (unsigned char *) smp_trash->area, (int *) _trash->data,
+		  (unsigned char *) smp->data.u.str.area, (int) smp->data.u.str.data))
+		goto err;
+
+	dec_size = base64dec(aead_tag.data.u.str.area, aead_tag.data.u.str.data, smp_trash_alloc->area, smp_trash_alloc->size);
+	if (dec_size < 0)
+		goto err;
+	smp_trash_alloc->data = dec_size;
+	dec_size = smp_trash->data;
+
+	EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_TAG, smp_trash_alloc->data, (void *) smp_trash_alloc->area);
+	ret = EVP_DecryptFinal_ex(ctx, (unsigned char *) smp_trash->area + smp_trash->data, (int *) _trash->data);
+
+	if (ret <= 0)
+		goto err;
+
+	smp->data.u.str.data = 

Re: [PATCH] MINOR: crypto: Add digest and hmac converters

2020-04-22 Thread Tim Düsterhus
Patrick,

Am 22.04.20 um 17:30 schrieb Patrick Gansterer:
> Tim,
> 
> thanks for the review. I just rebased my old patch today and didn't check 
> what 
> changed in the meantime in the codebase. I created a separate patch to move 
> aes_gcm_dec out of ssl_sock.c since it seams to fit better to my new file.
> 

Not sure what you did there, but the patches are not usable like this,
because they are merged into a large block of text. Either of the
following should work. The first is probably easier for a one time
patche :-)

1. Attach the patches as regular attachments each (= One email with two
attachments).
2. Use the following:

git format-patch -M master --cc=t...@bastelstu.be
--to=haproxy@formilux.org -o outgoing
git send-email outgoing/*.patch
--in-reply-to=6e582bdb-05c4-be8c-5879-8c4aedca1...@bastelstu.be

This will result in two emails with one inline patch each.

Best regards
Tim Düsterhus



Re: [PATCH] MINOR: crypto: Add digest and hmac converters

2020-04-22 Thread Patrick Gansterer
Tim,

thanks for the review. I just rebased my old patch today and didn't check what 
changed in the meantime in the codebase. I created a separate patch to move 
aes_gcm_dec out of ssl_sock.c since it seams to fit better to my new file.

- Patrick

>From 8f6ce045c80e0f67a485233ee602b57b4c311bde Mon Sep 17 00:00:00 2001
From: Patrick Gansterer 
Date: Sun, 17 Jun 2018 11:21:11 +0200
Subject: [PATCH 1/2] MINOR: crypto: Move aes_gcm_dec implementation into new
 file

---
 Makefile   |   2 +-
 src/crypto.c   | 163 +
 src/ssl_sock.c | 142 --
 3 files changed, 164 insertions(+), 143 deletions(-)
 create mode 100644 src/crypto.c

diff --git a/Makefile b/Makefile
index 1e4213989..2dea46368 100644
--- a/Makefile
+++ b/Makefile
@@ -542,7 +542,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 0..74b92eee5
--- /dev/null
+++ b/src/crypto.c
@@ -0,0 +1,163 @@
+/*
+ * Crypto converters
+ *
+ * Copyright 2020 Nenad Merdanovic 
+ *
+ * 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 
+#include 
+#include 
+
+#include 
+#include 
+#include 
+
+#include 
+
+#if (HA_OPENSSL_VERSION_NUMBER >= 0x1000100fL)
+static inline int sample_conv_var2smp_str(const struct arg *arg, struct 
sample *smp)
+{
+   switch (arg->type) {
+   case ARGT_STR:
+   smp->data.type = SMP_T_STR;
+   smp->data.u.str = arg->data.str;
+   return 1;
+   case ARGT_VAR:
+   if (!vars_get_by_desc(>data.var, smp))
+   return 0;
+   if (!sample_casts[smp->data.type][SMP_T_STR])
+   return 0;
+   if (!sample_casts[smp->data.type][SMP_T_STR](smp))
+   return 0;
+   return 1;
+   default:
+   return 0;
+   }
+}
+
+static int check_aes_gcm(struct arg *args, struct sample_conv *conv,
+ const char 
*file, int line, char **err)
+{
+   switch(args[0].data.sint) {
+   case 128:
+   case 192:
+   case 256:
+   break;
+   default:
+   memprintf(err, "key size must be 128, 192 or 256 
(bits).");
+   return 0;
+   }
+   /* Try to decode a variable. */
+   vars_check_arg([1], NULL);
+   vars_check_arg([2], NULL);
+   vars_check_arg([3], NULL);
+   return 1;
+}
+
+/* Arguments: AES size in bits, nonce, key, tag. The last three arguments are 
base64 encoded */
+static int sample_conv_aes_gcm_dec(const struct arg *arg_p, struct sample 
*smp, void *private)
+{
+   struct sample nonce, key, aead_tag;
+   struct buffer *smp_trash, *smp_trash_alloc;
+   EVP_CIPHER_CTX *ctx;
+   int dec_size, ret;
+
+   smp_set_owner(, smp->px, smp->sess, smp->strm, smp->opt);
+   if (!sample_conv_var2smp_str(_p[1], ))
+   return 0;
+
+   smp_set_owner(, smp->px, smp->sess, smp->strm, smp->opt);
+   if (!sample_conv_var2smp_str(_p[2], ))
+   return 0;
+
+   smp_set_owner(_tag, smp->px, smp->sess, smp->strm, smp->opt);
+   if (!sample_conv_var2smp_str(_p[3], _tag))
+   return 0;
+
+   smp_trash = get_trash_chunk();
+   smp_trash_alloc = alloc_trash_chunk();
+   if (!smp_trash_alloc)
+   return 0;
+
+   ctx = EVP_CIPHER_CTX_new();
+
+   if (!ctx)
+   goto err;
+
+   dec_size = base64dec(nonce.data.u.str.area, nonce.data.u.str.data, 
smp_trash->area, smp_trash->size);
+   if (dec_size < 0)
+   goto err;
+   smp_trash->data = dec_size;
+
+   /* Set cipher type and mode */
+   switch(arg_p[0].data.sint) {
+   case 128:
+   EVP_DecryptInit_ex(ctx, EVP_aes_128_gcm(), NULL, NULL, 
NULL);
+   break;
+   case 192:
+   EVP_DecryptInit_ex(ctx, EVP_aes_192_gcm(), NULL, NULL, 
NULL);
+   break;
+   case 256:
+   EVP_DecryptInit_ex(ctx, EVP_aes_256_gcm(), NULL, NULL, 
NULL);
+   break;
+   }
+
+   EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_IVLEN, smp_trash->data, 
NULL);
+
+   /* Initialise IV */
+   if(!EVP_DecryptInit_ex(ctx, NULL, NULL, NULL, (unsigned char *) 
smp_trash->area))
+   goto err;
+
+   dec_size = base64dec(key.data.u.str.area, key.data.u.str.data, 
smp_trash->area, smp_trash->size);
+   if (dec_size < 0)
+

Re: [PATCH] MINOR: crypto: Add digest and hmac converters

2020-04-22 Thread Tim Düsterhus
Patrick,

Am 22.04.20 um 12:40 schrieb Patrick Gansterer:
> diff --git a/doc/configuration.txt b/doc/configuration.txt
> index 2e548b66c..17b2debe5 100644
> --- a/doc/configuration.txt
> +++ b/doc/configuration.txt
> @@ -13918,6 +13918,10 @@ debug([])
>Example:
>  tcp-request connection track-sc0 src,debug(track-sc)
>  
> +digest()
> +  Converts a binary input sample to a message digest. The result is a binary
> +  sample. The algorithm must be an OpenSSL message digest name (e.g sha256).

Add a note that the converter is only available with USE_OPENSSL similar
to the sha2() converted.

> @@ -13972,6 +13976,11 @@ hex2i
>Converts a hex string containing two hex digits per input byte to an
>integer. If the input value cannot be converted, then zero is returned.
>  
> +hmac(, )
> +  Converts a binary input sample to a message authentication code with the 
> given
> +  key. The result is  a binary sample. The algorithm must be one of the
> +  registered OpenSSL message digest names (e.g sha256).

Add a note that the converter is only available with USE_OPENSSL similar
to the sha2() converted.

> diff --git a/src/crypto.c b/src/crypto.c
> new file mode 100644
> index 0..b4f2bfe32
> --- /dev/null
> +++ b/src/crypto.c
> @@ -0,0 +1,84 @@
> +static int sample_conv_crypto_digest(const struct arg *args, struct sample 
> *smp, void *private)
> +{
> + struct buffer *trash = get_trash_chunk();
> + EVP_MD_CTX *ctx = EVP_MD_CTX_new();
> + const EVP_MD *evp = EVP_get_digestbyname(args[0].data.str.area);
> + unsigned char *md = (unsigned char*) trash->area;
> + unsigned int md_len = trash->size;
> +
> + if (!ctx)
> + return 0;
> + if (!evp)
Will this leak ctx?

> + return 0;
> +
> + if (!EVP_DigestInit(ctx, evp) ||
> + !EVP_DigestUpdate(ctx, smp->data.u.str.area, smp->data.u.str.data) 
> ||
> + !EVP_DigestFinal(ctx, md, _len)) {

The OpenSSL manpage says:

> The functions EVP_DigestInit(), EVP_DigestFinal() and EVP_MD_CTX_copy() are 
> obsolete but are retained to maintain compatibility with existing code. New 
> applications should use EVP_DigestInit_ex(), EVP_DigestFinal_ex() and 
> EVP_MD_CTX_copy_ex() because they can efficiently reuse a digest context 
> instead of initializing and cleaning it up on each call and allow non default 
> implementations of digests to be specified.

.

> + EVP_MD_CTX_free(ctx);
> + return 0;
> + }
> +
> + EVP_MD_CTX_free(ctx);
> +
> + trash->data = 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 buffer *trash = get_trash_chunk();
> + const EVP_MD *evp = EVP_get_digestbyname(args[0].data.str.area);
> + const char* key = args[1].data.str.area;
> + int key_len = args[1].data.str.data;

I'd say that the key should have support for taking the key from a
variable similar to aes_gcm_dec(). I'd also say that the parameter
should be base64 encoded to allow for arbitrary bytes.

> + unsigned char *md = (unsigned char*) trash->area;
> + unsigned int md_len = trash->size;
> +
> + trash->data = 0;
> +
> + if (!evp)
> + return 0;
> +
> + if (!HMAC(evp, key, key_len, (const unsigned char*) 
> smp->data.u.str.area, smp->data.u.str.data, md, _len))
> + return 0;
> +
> + trash->data = 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 },

Add a validation function that checks whether the given hash algorithm
is valid at configuration checking time.

Best regards
Tim Düsterhus



[PATCH] MINOR: crypto: Add digest and hmac converters

2020-04-22 Thread Patrick Gansterer
Make the digest and HMAC function of OpenSSL accessible to the user via
converters. They can be used to sign and validate content.
---
 Makefile|  2 +-
 doc/configuration.txt   |  9 
 reg-tests/sample_fetches/hashes.vtc | 22 
 src/crypto.c| 84 +
 4 files changed, 116 insertions(+), 1 deletion(-)
 create mode 100644 src/crypto.c

diff --git a/Makefile b/Makefile
index 1e4213989..2dea46368 100644
--- a/Makefile
+++ b/Makefile
@@ -542,7 +542,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/doc/configuration.txt b/doc/configuration.txt
index 2e548b66c..17b2debe5 100644
--- a/doc/configuration.txt
+++ b/doc/configuration.txt
@@ -13918,6 +13918,10 @@ debug([])
   Example:
 tcp-request connection track-sc0 src,debug(track-sc)
 
+digest()
+  Converts a binary input sample to a message digest. The result is a binary
+  sample. The algorithm must be an OpenSSL message digest name (e.g sha256).
+
 div()
   Divides the input value of type signed integer by , and returns the
   result as an signed integer. If  is null, the largest unsigned
@@ -13972,6 +13976,11 @@ hex2i
   Converts a hex string containing two hex digits per input byte to an
   integer. If the input value cannot be converted, then zero is returned.
 
+hmac(, )
+  Converts a binary input sample to a message authentication code with the 
given
+  key. The result is  a binary sample. The algorithm must be one of the
+  registered OpenSSL message digest names (e.g sha256).
+
 http_date([])
   Converts an integer supposed to contain a date since epoch to a string
   representing this date in a format suitable for use in HTTP header fields. If
diff --git a/reg-tests/sample_fetches/hashes.vtc 
b/reg-tests/sample_fetches/hashes.vtc
index 874f81e41..ca641f86c 100644
--- a/reg-tests/sample_fetches/hashes.vtc
+++ b/reg-tests/sample_fetches/hashes.vtc
@@ -38,6 +38,19 @@ haproxy h1 -conf {
 #http-response set-header x-sha2-384 "%[var(res.key),sha2(384),hex]"
 #http-response set-header x-sha2-512 "%[var(res.key),sha2(512),hex]"
 
+# OpenSSL Digest
+#http-response set-header x-digest-sha1 
"%[var(res.key),digest(sha1),hex]"
+#http-response set-header x-digest-sha224 
"%[var(res.key),digest(sha224),hex]"
+#http-response set-header x-digest-sha256 
"%[var(res.key),digest(sha256),hex]"
+#http-response set-header x-digest-sha384 
"%[var(res.key),digest(sha384),hex]"
+#http-response set-header x-digest-sha512 
"%[var(res.key),digest(sha512),hex]"
+
+# OpenSSL HMAC
+#http-response set-header x-hmac-sha1-short 
"%[var(res.key),hmac(sha1,key),hex]"
+#http-response set-header x-hmac-sha1-long 
"%[var(res.key),hmac(sha1,my_super_secret_long_key),hex]"
+#http-response set-header x-hmac-sha256-short 
"%[var(res.key),hmac(sha256,key),hex]"
+#http-response set-header x-hmac-sha256-long 
"%[var(res.key),hmac(sha256,my_super_secret_long_key),hex]"
+
 # 32-bit hashes, and their avalanche variants
 http-response set-header x-crc32   "%[var(res.key),crc32]"
 http-response set-header x-crc32-1 "%[var(res.key),crc32(1)]"
@@ -80,6 +93,15 @@ client c1 -connect ${h1_fe_sock} {
 #expect resp.http.x-sha2-256 == 
"40AFF2E9D2D8922E47AFD4648E6967497158785FBD1DA870E7110266BF944880"
 #expect resp.http.x-sha2-384 == 
"FFDAEBFF65ED05CF400F0221C4CCFB4B2104FB6A51F87E40BE6C4309386BFDEC2892E9179B34632331A59592737DB5C5"
 #expect resp.http.x-sha2-512 == 
"1E7B80BC8EDC552C8FEEB2780E111477E5BC70465FAC1A77B29B35980C3F0CE4A036A6C9462036824BD56801E62AF7E9FEBA5C22ED8A5AF877BF7DE117DCAC6D"
+#expect resp.http.x-digest-sha1 == resp.http.x-digest-sha1
+#expect resp.http.x-digest-sha224 == resp.http.x-sha2-224
+#expect resp.http.x-digest-sha256 == resp.http.x-sha2-256
+#expect resp.http.x-digest-sha384 == resp.http.x-sha2-384
+#expect resp.http.x-digest-sha512 == resp.http.x-sha2-512
+#expect resp.http.x-hmac-sha1-short == 
"98C6C3B2F2701E0C7B0AC31C09C44EFF006C802C"
+#expect resp.http.x-hmac-sha1-long == 
"0E153DC06F81DEC1352EA9394B12754C718E2600"
+#expect resp.http.x-hmac-sha256-short == 
"6AD0A89813F79E827359742225B46DC811D35E920192CFDF60F4955F14A93680"
+#expect resp.http.x-hmac-sha256-long == 
"C8E39024773AB08D937265FFAF22231F851CF00C96C6EE98DF9E0B66FFE7C089"
 expect resp.http.x-crc32 == "688229491"
 expect resp.http.x-crc32-1 == "4230317029"
 expect resp.http.x-crc32c == "2621708363"
diff --git a/src/crypto.c b/src/crypto.c
new file mode 100644
index 0..b4f2bfe32
--- /dev/null
+++ b/src/crypto.c
@@ -0,0 +1,84 @@
+/*
+ * Crypto converters
+ *
+ * Copyright 2018 Patrick Gansterer 
+ *

Re: [PATCH] MINOR: crypto: Add digest and hmac converters

2018-08-21 Thread Patrick Hemmer


On 2018/6/17 14:02, Baptiste wrote:
>
>
> Le dim. 17 juin 2018 à 14:10, Patrick Gansterer  > a écrit :
>
>
> > On 17 Jun 2018, at 13:36, Baptiste  > wrote:
> >
> > Can they be used to validate oauth tokens too?
>
> Depends on the implementation of the tokens, but if they are
> HMACSHA256 signed JWT, it’s very easy to validate them in a lua
> script now.
>
>
> That's how I am doing it now.
> Just wanted to know if a combination of http rules could do the job.
> And be maybe faster.
>
> Baptiste

Any progress on this? I'd also be interested in seeing native HMAC
functions added, as I'm doing something similar to a HMAC that I'd love
to replace.

-Patrick


Re: [PATCH] MINOR: crypto: Add digest and hmac converters

2018-06-17 Thread Baptiste
Le dim. 17 juin 2018 à 14:10, Patrick Gansterer  a
écrit :

>
> > On 17 Jun 2018, at 13:36, Baptiste  wrote:
> >
> > Can they be used to validate oauth tokens too?
>
> Depends on the implementation of the tokens, but if they are HMACSHA256
> signed JWT, it’s very easy to validate them in a lua script now.
>

That's how I am doing it now.
Just wanted to know if a combination of http rules could do the job. And be
maybe faster.

Baptiste


Re: [PATCH] MINOR: crypto: Add digest and hmac converters

2018-06-17 Thread Patrick Gansterer


> On 17 Jun 2018, at 13:36, Baptiste  wrote:
> 
> Can they be used to validate oauth tokens too?

Depends on the implementation of the tokens, but if they are HMACSHA256 signed 
JWT, it’s very easy to validate them in a lua script now.

> Note: maybe an update for configuration.txt would be helpful too.

Thx for the note. I’ve updated the patch.

- Patrick


[PATCH] MINOR: crypto: Add digest and hmac converters

2018-06-17 Thread Patrick Gansterer
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 +-
 doc/configuration.txt |  9 +
 src/crypto.c  | 84 +++
 3 files changed, 94 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/doc/configuration.txt b/doc/configuration.txt
index e901d7ee..7c9eb55c 100644
--- a/doc/configuration.txt
+++ b/doc/configuration.txt
@@ -12909,6 +12909,10 @@ debug
   type of the input sample. The sample is returned as is on its output. This
   converter only exists when haproxy was built with debugging enabled.
 
+digest()
+  Converts a binary input sample to a message digest. The result is a binary
+  sample. The alorithm must a OpenSSL message digest name (e.g sha256).
+
 div()
   Divides the input value of type signed integer by , and returns the
   result as an signed integer. If  is null, the largest unsigned
@@ -12963,6 +12967,11 @@ hex2i
   Converts a hex string containing two hex digits per input byte to an
   integer. If the input value can not be converted, then zero is returned.
 
+hmac(, )
+  Converts a binary input sample to a message authentication code with the 
given
+  key. The result is  a binary sample. The alorithm must be of the registered
+  OpenSSL message digest names (e.g sha256).
+
 http_date([])
   Converts an integer supposed to contain a date since epoch to a string
   representing this date in a format suitable for use in HTTP header fields. If
diff --git a/src/crypto.c b/src/crypto.c
new file mode 100644
index ..e4a65557
--- /dev/null
+++ b/src/crypto.c
@@ -0,0 +1,84 @@
+/*
+ * Crypto converters
+ *
+ * Copyright 2018 Patrick Gansterer 
+ *
+ * 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 
+
+#include 
+#include 
+
+#include 
+#include 
+
+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, _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, _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(_conv_kws);
+}
-- 
2.17.1




Re: [PATCH] MINOR: crypto: Add digest and hmac converters

2018-06-17 Thread Baptiste
On Sun, Jun 17, 2018 at 11:21 AM, Patrick Gansterer 
wrote:

> 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 ..dcb343dc
> --- /dev/null
> +++ b/src/crypto.c
> @@ -0,0 +1,84 @@
> +/*
> + * Crypto converters
> + *
> + * Copyright 2018 Patrick Gansterer 
> + *
> + * 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 
> +
> +#include 
> +#include 
> +
> +#include 
> +#include 
> +
> +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, _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, _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(_conv_kws);
> +}
> --
> 2.17.1
>

Hi,

Nice ones.
Can they be used to validate oauth tokens too?

Note: maybe an update for configuration.txt would be helpful too.

Baptiste


[PATCH] MINOR: crypto: Add digest and hmac converters

2018-06-17 Thread Patrick Gansterer
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 ..dcb343dc
--- /dev/null
+++ b/src/crypto.c
@@ -0,0 +1,84 @@
+/*
+ * Crypto converters
+ *
+ * Copyright 2018 Patrick Gansterer 
+ *
+ * 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 
+
+#include 
+#include 
+
+#include 
+#include 
+
+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, _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, _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(_conv_kws);
+}
-- 
2.17.1