Welcome! Log In Create A New Profile

Advanced

TLS-PSK support for haproxy?

Posted by Gil Bahat 
Gil Bahat
TLS-PSK support for haproxy?
October 25, 2015 05:30AM
Hi,

I was wondering if HAProxy can do TLS-PSK. this cipher setting is
advantageous in several scenarios, in particular with low-end clients or
with stunnel backends. However, since I could not find any configuration
option that denotes the preshared key, I would assume that this is not
supported by HAProxy.

Is TLS-PSK support?

if not, it should be rather easy to implement, because it basically entails
another conf option which would be passed to OpenSSL during initialization.

Regards,

Gil Bahat,
DevOps Engineer,
Magisto Ltd.
Igor Pav
Re: TLS-PSK support for haproxy?
December 31, 2016 06:20PM
Sounds good for SSL backend, is this possible?

On Sun, Oct 25, 2015 at 12:22 PM, Gil Bahat <[email protected]> wrote:
> Hi,
>
> I was wondering if HAProxy can do TLS-PSK. this cipher setting is
> advantageous in several scenarios, in particular with low-end clients or
> with stunnel backends. However, since I could not find any configuration
> option that denotes the preshared key, I would assume that this is not
> supported by HAProxy.
>
> Is TLS-PSK support?
>
> if not, it should be rather easy to implement, because it basically entails
> another conf option which would be passed to OpenSSL during initialization.
>
> Regards,
>
> Gil Bahat,
> DevOps Engineer,
> Magisto Ltd.
Willy Tarreau
Re: TLS-PSK support for haproxy?
January 01, 2017 09:40AM
On Sun, Jan 01, 2017 at 01:16:37AM +0800, Igor Pav wrote:
> Sounds good for SSL backend, is this possible?

Indeed that sounds interesting for such use cases. I have no idea what it
requires to set it up nor what needs to be configurable. Does anyone have
any pointer to any product supporting it ?

Willy
Igor Pav
Re: TLS-PSK support for haproxy?
January 01, 2017 04:50PM
Stunnel supports it, https://www.stunnel.org/auth.html, quite simple.

On Sun, Jan 1, 2017 at 4:34 PM, Willy Tarreau <[email protected]> wrote:
> On Sun, Jan 01, 2017 at 01:16:37AM +0800, Igor Pav wrote:
>> Sounds good for SSL backend, is this possible?
>
> Indeed that sounds interesting for such use cases. I have no idea what it
> requires to set it up nor what needs to be configurable. Does anyone have
> any pointer to any product supporting it ?
>
> Willy
Gil Bahat
Re: TLS-PSK support for haproxy?
January 02, 2017 10:20AM
yes, stunnel was my original inspiration for this request, I wanted HAproxy
to communicate with stunnel-backed services. actually, stunnel implements
both PSK server and PSK client and it would make sense for HAproxy to have
both. TLS 1.3 also appears to significantly improve PSK with combinations
such as RSA-PSK and ECDHE-PSK, so that appears to have future usability as
well.

Regards,

Gil

On Sun, Jan 1, 2017 at 5:41 PM, Igor Pav <[email protected]> wrote:

> Stunnel supports it, https://www.stunnel.org/auth.html, quite simple.
>
> On Sun, Jan 1, 2017 at 4:34 PM, Willy Tarreau <[email protected]> wrote:
> > On Sun, Jan 01, 2017 at 01:16:37AM +0800, Igor Pav wrote:
> >> Sounds good for SSL backend, is this possible?
> >
> > Indeed that sounds interesting for such use cases. I have no idea what it
> > requires to set it up nor what needs to be configurable. Does anyone have
> > any pointer to any product supporting it ?
> >
> > Willy
>
Nenad Merdanovic
Re: TLS-PSK support for haproxy?
January 05, 2017 04:30AM
I have a working patch for this, but it's very ugly currently (minimal
error checking, no warnings/messages, no docs, very basic tests done
only, etc.)

I expect to have a version for review by EOW (depending on the workload,
maybe a bit sooner).

Regards,
Nenad

On 1/2/2017 10:11 AM, Gil Bahat wrote:
> yes, stunnel was my original inspiration for this request, I wanted
> HAproxy to communicate with stunnel-backed services. actually, stunnel
> implements both PSK server and PSK client and it would make sense for
> HAproxy to have both. TLS 1.3 also appears to significantly improve PSK
> with combinations such as RSA-PSK and ECDHE-PSK, so that appears to have
> future usability as well.
>
> Regards,
>
> Gil
>
> On Sun, Jan 1, 2017 at 5:41 PM, Igor Pav <[email protected]
> <mailto:[email protected]>> wrote:
>
> Stunnel supports it, https://www.stunnel.org/auth.html
> https://www.stunnel.org/auth.html, quite simple.
>
> On Sun, Jan 1, 2017 at 4:34 PM, Willy Tarreau <[email protected]
> <mailto:[email protected]>> wrote:
> > On Sun, Jan 01, 2017 at 01:16:37AM +0800, Igor Pav wrote:
> >> Sounds good for SSL backend, is this possible?
> >
> > Indeed that sounds interesting for such use cases. I have no idea
> what it
> > requires to set it up nor what needs to be configurable. Does
> anyone have
> > any pointer to any product supporting it ?
> >
> > Willy
>
>
Emeric Brun
Re: TLS-PSK support for haproxy?
January 05, 2017 04:50PM
On 01/05/2017 04:22 AM, Nenad Merdanovic wrote:
> I have a working patch for this, but it's very ugly currently (minimal
> error checking, no warnings/messages, no docs, very basic tests done
> only, etc.)
>
> I expect to have a version for review by EOW (depending on the workload,
> maybe a bit sooner).
>
> Regards,
> Nenad

Great news Nenad!

Emeric
Nenad Merdanovic
Re: TLS-PSK support for haproxy?
January 09, 2017 01:10AM
Hello,

On 1/5/2017 4:47 PM, Emeric Brun wrote:
> On 01/05/2017 04:22 AM, Nenad Merdanovic wrote:
>> I have a working patch for this, but it's very ugly currently (minimal
>> error checking, no warnings/messages, no docs, very basic tests done
>> only, etc.)
>>
>> I expect to have a version for review by EOW (depending on the workload,
>> maybe a bit sooner).
>>
>> Regards,
>> Nenad
>
> Great news Nenad!

I haven't really had as much time as I wanted for this, but I am
attaching a patch that I think is good enough for review as I don't
expect design decisions to change.

There are some minor things I want to improve (rename things like
'psk_key'), add some ifdefs for OPENSSL_NO_PSK and write the
documentation of course. Depending on the client/server side:
- On the bind line, there is a psk-file keyword that loads a series of
PSKs and any can be used
- On the server line, there is a psk keyword, that takes the same format
as the file (<identity>:<key>) and is used for the backend connection.

I'll send a full Git patch if this looks OK within the next few days.

Regards,
Nenad
diff --git a/include/types/listener.h b/include/types/listener.h
index 03f4a72b..4dc5a05b 100644
--- a/include/types/listener.h
+++ b/include/types/listener.h
@@ -134,6 +134,7 @@ struct bind_conf {
int strict_sni; /* refuse negotiation if sni doesn't match a certificate */
struct eb_root sni_ctx; /* sni_ctx tree of all known certs full-names sorted by name */
struct eb_root sni_w_ctx; /* sni_ctx tree of all known certs wildcards sorted by name */
+ struct eb_root psk; /* PSK tree, keyed by identity */
struct tls_keys_ref *keys_ref; /* TLS ticket keys reference */

char *ca_sign_file; /* CAFile used to generate and sign server certificates */
diff --git a/include/types/server.h b/include/types/server.h
index 5092eb7d..f0cf8bd4 100644
--- a/include/types/server.h
+++ b/include/types/server.h
@@ -261,6 +261,8 @@ struct server {
char *ca_file; /* CAfile to use on verify */
char *crl_file; /* CRLfile to use on verify */
char *client_crt; /* client certificate to send */
+ char *psk_identity; /* PSK identity */
+ char *psk_key; /* PSK key */
struct sample_expr *sni; /* sample expression for SNI */
} ssl_ctx;
#endif
diff --git a/include/types/ssl_sock.h b/include/types/ssl_sock.h
index e71ba793..6a24a2ec 100644
--- a/include/types/ssl_sock.h
+++ b/include/types/ssl_sock.h
@@ -25,6 +25,12 @@
#include <openssl/ssl.h>
#include <ebmbtree.h>

+struct psk_pair {
+ char *key;
+ char *identity;
+ struct ebmb_node node;
+};
+
struct sni_ctx {
SSL_CTX *ctx; /* context associated to the certificate */
int order; /* load order for the certificate */
diff --git a/src/ssl_sock.c b/src/ssl_sock.c
index acf1c39c..717ad323 100644
--- a/src/ssl_sock.c
+++ b/src/ssl_sock.c
@@ -531,6 +531,29 @@ end:
return ret;
}

+static int ssl_srv_psk_cb(SSL *ssl, char *identity, unsigned char *psk, unsigned int max_psk_len)
+{
+ struct connection *conn;
+ struct ebmb_node *node;
+ struct psk_pair *pp;
+
+ conn = SSL_get_app_data(ssl);
+
+ node = ebst_lookup(&objt_listener(conn->target)->bind_conf->psk, identity);
+
+ if (!node)
+ return 0;
+
+ pp = ebmb_entry(node, struct psk_pair, node);
+
+ if(strlen(pp->key) > max_psk_len)
+ return 0;
+
+ memcpy(psk, pp->key, strlen(pp->key));
+
+ return(strlen(pp->key));
+}
+
#if (defined SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB && TLS_TICKETS_NO > 0)
static int ssl_tlsext_ticket_key_cb(SSL *s, unsigned char key_name[16], unsigned char *iv, EVP_CIPHER_CTX *ectx, HMAC_CTX *hctx, int enc)
{
@@ -2827,6 +2850,9 @@ int ssl_sock_prepare_ctx(struct bind_conf *bind_conf, SSL_CTX *ctx)
}
#endif

+ if(ebmb_first(&bind_conf->psk))
+ SSL_CTX_set_psk_server_callback(ctx, ssl_srv_psk_cb);
+
if (global_ssl.life_time)
SSL_CTX_set_timeout(ctx, global_ssl.life_time);

@@ -2988,6 +3014,30 @@ static int ssl_sock_srv_hostcheck(const char *pattern, const char *hostname)
return 1;
}

+static int ssl_sock_client_psk_cb(SSL *ssl, const char *hint, char *identity, unsigned int max_identity_len, unsigned char *psk, unsigned int max_psk_len)
+{
+ struct connection *conn;
+ struct server *srv;
+ int ret;
+
+ (void) hint;
+
+ conn = SSL_get_app_data(ssl);
+ srv = objt_server(conn->target);
+
+ if(strlen(srv->ssl_ctx.psk_identity) + 1 > max_identity_len)
+ return 0;
+
+ strncpy(identity, srv->ssl_ctx.psk_identity, max_identity_len);
+
+ if(strlen(srv->ssl_ctx.psk_key) > max_psk_len)
+ return 0;
+
+ memcpy(psk, srv->ssl_ctx.psk_key, strlen(srv->ssl_ctx.psk_key));
+
+ return(strlen(srv->ssl_ctx.psk_key));
+}
+
static int ssl_sock_srv_verifycbk(int ok, X509_STORE_CTX *ctx)
{
SSL *ssl;
@@ -3214,6 +3264,9 @@ int ssl_sock_prepare_srv_ctx(struct server *srv)
cfgerr++;
}

+ if (srv->ssl_ctx.psk_identity && srv->ssl_ctx.psk_key)
+ SSL_CTX_set_psk_client_callback(srv->ssl_ctx.ctx, ssl_sock_client_psk_cb);
+
return cfgerr;
}

@@ -5608,6 +5661,57 @@ static int bind_parse_alpn(char **args, int cur_arg, struct proxy *px, struct bi
#endif
}

+
+/* parse the "psk-file" bind keyword */
+static int bind_parse_psk_file(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
+{
+ FILE *f;
+ int i = 0;
+ char thisline[LINESIZE];
+ struct psk_pair *pp;
+ char *key;
+
+ if (!*args[cur_arg + 1]) {
+ if (err)
+ memprintf(err, "'%s' : missing PSK file path", args[cur_arg]);
+ return ERR_ALERT | ERR_FATAL;
+ }
+
+ if ((f = fopen(args[cur_arg + 1], "r")) == NULL) {
+ if (err)
+ memprintf(err, "'%s' : unable to load ssl PSK file", args[cur_arg+1]);
+ return ERR_ALERT | ERR_FATAL;
+ }
+
+ while (fgets(thisline, sizeof(thisline), f) != NULL) {
+ int len = strlen(thisline);
+ i++;
+ /* Strip newline characters from the end */
+ if(thisline[len - 1] == '\n')
+ thisline[--len] = 0;
+
+ if(thisline[len - 1] == '\r')
+ thisline[--len] = 0;
+
+ key = strchr(thisline, ':');
+ if (!key || key == thisline || key == thisline + len - 1) {
+ if (err)
+ memprintf(err, "'%s' : unable to load ssl PSK file, syntax error at line %d", args[cur_arg+1], i);
+ return ERR_ALERT | ERR_FATAL;
+ }
+
+ *key++ = '\0';
+
+ pp = calloc(1, sizeof(*pp) + strlen(thisline) + 1);
+ memcpy(pp->node.key, thisline, strlen(thisline) + 1);
+ pp->key = strdup(key);
+ pp->identity = strdup(thisline);
+
+ ebst_insert(&conf->psk, &pp->node);
+ }
+}
+
+
/* parse the "ssl" bind keyword */
static int bind_parse_ssl(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
{
@@ -5903,6 +6007,28 @@ static int srv_parse_no_tls_tickets(char **args, int *cur_arg, struct proxy *px,
newsrv->ssl_ctx.options |= SRV_SSL_O_NO_TLS_TICKETS;
return 0;
}
+
+static int srv_parse_psk(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
+{
+ char *key;
+
+ if (!*args[*cur_arg + 1]) {
+ memprintf(err, "'%s' : missing PSK pair in format <identity>:<key>", args[*cur_arg]);
+ return ERR_ALERT | ERR_FATAL;
+ }
+
+ key = strchr(args[*cur_arg+1], ':');
+ if (!key || key == args[*cur_arg+1] || key == args[*cur_arg+1] + strlen(args[*cur_arg+1]) - 1) {
+ if (err)
+ memprintf(err, "'%s' : unable to load ssl PSK file in format <identity>:<key>", args[*cur_arg+1]);
+ return ERR_ALERT | ERR_FATAL;
+ }
+
+ *key++ = '\0';
+ newsrv->ssl_ctx.psk_identity = strdup(args[*cur_arg+1]);
+ newsrv->ssl_ctx.psk_key = strdup(key);
+}
+
/* parse the "send-proxy-v2-ssl" server keyword */
static int srv_parse_send_proxy_ssl(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
{
@@ -6635,6 +6761,7 @@ static struct bind_kw_list bind_kws = { "SSL", { }, {
{ "no-tlsv11", bind_parse_no_tlsv11, 0 }, /* disable TLSv11 */
{ "no-tlsv12", bind_parse_no_tlsv12, 0 }, /* disable TLSv12 */
{ "no-tls-tickets", bind_parse_no_tls_tickets, 0 }, /* disable session resumption tickets */
+ { "psk-file", bind_parse_psk_file, 1 }, /* load the file containing PSKs */
{ "ssl", bind_parse_ssl, 0 }, /* enable SSL processing */
{ "strict-sni", bind_parse_strict_sni, 0 }, /* refuse negotiation if sni doesn't match a certificate */
{ "tls-ticket-keys", bind_parse_tls_ticket_keys, 1 }, /* set file to load TLS ticket keys from */
@@ -6666,6 +6793,7 @@ static struct srv_kw_list srv_kws = { "SSL", { }, {
{ "no-tlsv11", srv_parse_no_tlsv11, 0, 0 }, /* disable TLSv11 */
{ "no-tlsv12", srv_parse_no_tlsv12, 0, 0 }, /* disable TLSv12 */
{ "no-tls-tickets", srv_parse_no_tls_tickets, 0, 0 }, /* disable session resumption tickets */
+ { "psk", srv_parse_psk, 1, 0 }, /* PSK */
{ "send-proxy-v2-ssl", srv_parse_send_proxy_ssl, 0, 0 }, /* send PROXY protocol header v2 with SSL info */
{ "send-proxy-v2-ssl-cn", srv_parse_send_proxy_cn, 0, 0 }, /* send PROXY protocol header v2 with CN */
{ "sni", srv_parse_sni, 1, 0 }, /* send SNI extension */
Igor Pav
Re: TLS-PSK support for haproxy?
January 21, 2017 05:20PM
Tested and it works! Could we expect a rtt reduce?

On Mon, Jan 9, 2017 at 8:07 AM, Nenad Merdanovic <[email protected]> wrote:
> Hello,
>
> On 1/5/2017 4:47 PM, Emeric Brun wrote:
>> On 01/05/2017 04:22 AM, Nenad Merdanovic wrote:
>>> I have a working patch for this, but it's very ugly currently (minimal
>>> error checking, no warnings/messages, no docs, very basic tests done
>>> only, etc.)
>>>
>>> I expect to have a version for review by EOW (depending on the workload,
>>> maybe a bit sooner).
>>>
>>> Regards,
>>> Nenad
>>
>> Great news Nenad!
>
> I haven't really had as much time as I wanted for this, but I am
> attaching a patch that I think is good enough for review as I don't
> expect design decisions to change.
>
> There are some minor things I want to improve (rename things like
> 'psk_key'), add some ifdefs for OPENSSL_NO_PSK and write the
> documentation of course. Depending on the client/server side:
> - On the bind line, there is a psk-file keyword that loads a series of
> PSKs and any can be used
> - On the server line, there is a psk keyword, that takes the same format
> as the file (<identity>:<key>) and is used for the backend connection.
>
> I'll send a full Git patch if this looks OK within the next few days.
>
> Regards,
> Nenad
Nenad Merdanovic
[PATCH] MEDIUM: ssl: Add TLS-PSK client and server side support
February 03, 2017 02:30AM
From: Nenad Merdanovic <[email protected]>

Signed-off-by: Nenad Merdanovic <[email protected]>
---
doc/configuration.txt | 10 ++++
include/types/listener.h | 1 +
include/types/server.h | 2 +
include/types/ssl_sock.h | 5 ++
src/ssl_sock.c | 133 +++++++++++++++++++++++++++++++++++++++++++++++
5 files changed, 151 insertions(+)

diff --git a/doc/configuration.txt b/doc/configuration.txt
index 43a6c3e1..08b646f5 100644
--- a/doc/configuration.txt
+++ b/doc/configuration.txt
@@ -10492,6 +10492,10 @@ process [ all | odd | even | <number 1-64>[-<number 1-64>] ]
and allow a smoother inter-process load balancing. Currently Linux 3.9 and
above is known for supporting this. See also "bind-process" and "nbproc".

+psk-file <file>
+ Enables use of PSK cipher suites with PSKs stored in the specified file.
+ The entries should be in form "identity:key", one per line.
+
ssl
This setting is only available when support for OpenSSL was built in. It
enables SSL deciphering on connections instantiated from this listener. A
@@ -11110,6 +11114,12 @@ port <port>

Supported in default-server: Yes

+psk <identity:key>
+ Sets the PSK to use when connecting to the backend server over SSL, if the PSK
+ cipher suite is negotiated. The entry must be in form "identity:key".
+
+ Supported in default-server: No
+
redir <prefix>
The "redir" parameter enables the redirection mode for all GET and HEAD
requests addressing this server. This means that instead of having HAProxy
diff --git a/include/types/listener.h b/include/types/listener.h
index d813deb3..98e34a38 100644
--- a/include/types/listener.h
+++ b/include/types/listener.h
@@ -147,6 +147,7 @@ struct bind_conf {
int strict_sni; /* refuse negotiation if sni doesn't match a certificate */
struct eb_root sni_ctx; /* sni_ctx tree of all known certs full-names sorted by name */
struct eb_root sni_w_ctx; /* sni_ctx tree of all known certs wildcards sorted by name */
+ struct eb_root psk; /* PSK tree, keyed by identity */
struct tls_keys_ref *keys_ref; /* TLS ticket keys reference */

char *ca_sign_file; /* CAFile used to generate and sign server certificates */
diff --git a/include/types/server.h b/include/types/server.h
index 51b7e535..25aa4bbd 100644
--- a/include/types/server.h
+++ b/include/types/server.h
@@ -262,6 +262,8 @@ struct server {
char *ca_file; /* CAfile to use on verify */
char *crl_file; /* CRLfile to use on verify */
char *client_crt; /* client certificate to send */
+ char *psk_identity; /* PSK identity */
+ char *psk_key; /* PSK key */
struct sample_expr *sni; /* sample expression for SNI */
} ssl_ctx;
#endif
diff --git a/include/types/ssl_sock.h b/include/types/ssl_sock.h
index a384f055..b51ddf49 100644
--- a/include/types/ssl_sock.h
+++ b/include/types/ssl_sock.h
@@ -26,6 +26,11 @@
#include <openssl/ssl.h>
#include <ebmbtree.h>

+struct psk_pair {
+ char *key;
+ struct ebmb_node node;
+};
+
struct sni_ctx {
SSL_CTX *ctx; /* context associated to the certificate */
int order; /* load order for the certificate */
diff --git a/src/ssl_sock.c b/src/ssl_sock.c
index 232a4970..664581c2 100644
--- a/src/ssl_sock.c
+++ b/src/ssl_sock.c
@@ -533,6 +533,31 @@ end:
}
#endif

+static int ssl_srv_psk_cb(SSL *ssl, char *identity, unsigned char *psk, unsigned int max_psk_len)
+{
+ struct connection *conn;
+ struct ebmb_node *node;
+ struct psk_pair *pp;
+ int keylen;
+
+ conn = SSL_get_app_data(ssl);
+
+ node = ebst_lookup(&objt_listener(conn->target)->bind_conf->psk, identity);
+
+ if (!node)
+ return 0;
+
+ pp = ebmb_entry(node, struct psk_pair, node);
+
+ keylen = strlen(pp->key);
+ if(keylen > max_psk_len)
+ return 0;
+
+ memcpy(psk, pp->key, keylen);
+
+ return keylen;
+}
+
#if (defined SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB && TLS_TICKETS_NO > 0)
static int ssl_tlsext_ticket_key_cb(SSL *s, unsigned char key_name[16], unsigned char *iv, EVP_CIPHER_CTX *ectx, HMAC_CTX *hctx, int enc)
{
@@ -2955,6 +2980,9 @@ int ssl_sock_prepare_ctx(struct bind_conf *bind_conf, struct ssl_bind_conf *ssl_
}
#endif

+ if(ebmb_first(&bind_conf->psk))
+ SSL_CTX_set_psk_server_callback(ctx, ssl_srv_psk_cb);
+
if (global_ssl.life_time)
SSL_CTX_set_timeout(ctx, global_ssl.life_time);

@@ -3140,6 +3168,32 @@ static int ssl_sock_srv_hostcheck(const char *pattern, const char *hostname)
return 1;
}

+static int ssl_sock_client_psk_cb(SSL *ssl, const char *hint, char *identity, unsigned int max_identity_len, unsigned char *psk, unsigned int max_psk_len)
+{
+ struct connection *conn;
+ struct server *srv;
+ int keylen;
+ int ret;
+
+ (void) hint;
+
+ conn = SSL_get_app_data(ssl);
+ srv = objt_server(conn->target);
+
+ if(strlen(srv->ssl_ctx.psk_identity) + 1 > max_identity_len)
+ return 0;
+
+ strcpy(identity, srv->ssl_ctx.psk_identity);
+
+ keylen = strlen(srv->ssl_ctx.psk_key);
+ if(keylen > max_psk_len)
+ return 0;
+
+ memcpy(psk, srv->ssl_ctx.psk_key, keylen);
+
+ return keylen;
+}
+
static int ssl_sock_srv_verifycbk(int ok, X509_STORE_CTX *ctx)
{
SSL *ssl;
@@ -3367,6 +3421,9 @@ int ssl_sock_prepare_srv_ctx(struct server *srv)
cfgerr++;
}

+ if (srv->ssl_ctx.psk_identity && srv->ssl_ctx.psk_key)
+ SSL_CTX_set_psk_client_callback(srv->ssl_ctx.ctx, ssl_sock_client_psk_cb);
+
return cfgerr;
}

@@ -5849,6 +5906,56 @@ static int bind_parse_alpn(char **args, int cur_arg, struct proxy *px, struct bi
return ssl_bind_parse_alpn(args, cur_arg, px, &conf->ssl_conf, err);
}

+/* parse the "psk-file" bind keyword */
+static int bind_parse_psk_file(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
+{
+ FILE *f;
+ int i = 0;
+ char thisline[LINESIZE];
+ struct psk_pair *pp;
+ char *key;
+
+ if (!*args[cur_arg + 1]) {
+ if (err)
+ memprintf(err, "'%s' : missing PSK file path", args[cur_arg]);
+ return ERR_ALERT | ERR_FATAL;
+ }
+
+ if ((f = fopen(args[cur_arg + 1], "r")) == NULL) {
+ if (err)
+ memprintf(err, "'%s' : unable to load ssl PSK file", args[cur_arg+1]);
+ return ERR_ALERT | ERR_FATAL;
+ }
+
+ while (fgets(thisline, sizeof(thisline), f) != NULL) {
+ int len = strlen(thisline);
+ i++;
+ /* Strip newline characters from the end */
+ if(thisline[len - 1] == '\n')
+ thisline[--len] = 0;
+
+ if(thisline[len - 1] == '\r')
+ thisline[--len] = 0;
+
+ key = strchr(thisline, ':');
+ if (!key || key == thisline || key == thisline + len - 1) {
+ if (err)
+ memprintf(err, "'%s' : unable to load ssl PSK file, syntax error at line %d", args[cur_arg+1], i);
+ return ERR_ALERT | ERR_FATAL;
+ }
+
+ *key++ = '\0';
+
+ pp = calloc(1, sizeof(*pp) + strlen(thisline) + 1);
+ memcpy(pp->node.key, thisline, strlen(thisline) + 1);
+ pp->key = strdup(key);
+
+ ebst_insert(&conf->psk, &pp->node);
+ }
+
+ return 0;
+}
+
/* parse the "ssl" bind keyword */
static int bind_parse_ssl(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
{
@@ -6148,6 +6255,30 @@ static int srv_parse_no_tls_tickets(char **args, int *cur_arg, struct proxy *px,
newsrv->ssl_ctx.options |= SRV_SSL_O_NO_TLS_TICKETS;
return 0;
}
+
+static int srv_parse_psk(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
+{
+ char *key;
+
+ if (!*args[*cur_arg + 1]) {
+ memprintf(err, "'%s' : missing PSK pair in format <identity>:<key>", args[*cur_arg]);
+ return ERR_ALERT | ERR_FATAL;
+ }
+
+ key = strchr(args[*cur_arg + 1], ':');
+ if (!key || key == args[*cur_arg + 1] || key == args[*cur_arg + 1] + strlen(args[*cur_arg + 1]) - 1) {
+ if (err)
+ memprintf(err, "'%s' : unable to load ssl PSK file in format <identity>:<key>", args[*cur_arg+1]);
+ return ERR_ALERT | ERR_FATAL;
+ }
+
+ *key++ = '\0';
+ newsrv->ssl_ctx.psk_identity = strdup(args[*cur_arg+1]);
+ newsrv->ssl_ctx.psk_key = strdup(key);
+
+ return 0;
+}
+
/* parse the "send-proxy-v2-ssl" server keyword */
static int srv_parse_send_proxy_ssl(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
{
@@ -6899,6 +7030,7 @@ static struct bind_kw_list bind_kws = { "SSL", { }, {
{ "no-tlsv11", bind_parse_no_tlsv11, 0 }, /* disable TLSv11 */
{ "no-tlsv12", bind_parse_no_tlsv12, 0 }, /* disable TLSv12 */
{ "no-tls-tickets", bind_parse_no_tls_tickets, 0 }, /* disable session resumption tickets */
+ { "psk-file", bind_parse_psk_file, 1 }, /* load the file containing PSKs */
{ "ssl", bind_parse_ssl, 0 }, /* enable SSL processing */
{ "strict-sni", bind_parse_strict_sni, 0 }, /* refuse negotiation if sni doesn't match a certificate */
{ "tls-ticket-keys", bind_parse_tls_ticket_keys, 1 }, /* set file to load TLS ticket keys from */
@@ -6930,6 +7062,7 @@ static struct srv_kw_list srv_kws = { "SSL", { }, {
{ "no-tlsv11", srv_parse_no_tlsv11, 0, 0 }, /* disable TLSv11 */
{ "no-tlsv12", srv_parse_no_tlsv12, 0, 0 }, /* disable TLSv12 */
{ "no-tls-tickets", srv_parse_no_tls_tickets, 0, 0 }, /* disable session resumption tickets */
+ { "psk", srv_parse_psk, 1, 0 }, /* PSK */
{ "send-proxy-v2-ssl", srv_parse_send_proxy_ssl, 0, 0 }, /* send PROXY protocol header v2 with SSL info */
{ "send-proxy-v2-ssl-cn", srv_parse_send_proxy_cn, 0, 0 }, /* send PROXY protocol header v2 with CN */
{ "sni", srv_parse_sni, 1, 0 }, /* send SNI extension */
--
2.11.0
Robin H. Johnson
Re: [PATCH] MEDIUM: ssl: Add TLS-PSK client and server side support
February 03, 2017 10:30PM
On Fri, Feb 03, 2017 at 02:19:29AM +0100, Nenad Merdanovic wrote:
> +psk-file <file>
> + Enables use of PSK cipher suites with PSKs stored in the specified file.
> + The entries should be in form "identity:key", one per line.
> +
Rather than new file handling routine, could you instead hook this into
using a map? As a side bonus, it becomes trivially possible to update
the map at runtime.

--
Robin Hugh Johnson
E-Mail : robbat2@orbis-terrarum.net
Home Page : http://www.orbis-terrarum.net/?l=people.robbat2
ICQ# : 30269588 or 41961639
GnuPG FP : 11ACBA4F 4778E3F6 E4EDF38E B27B944E 34884E85
Hi,

On 02/03/2017 10:22 PM, Robin H. Johnson wrote:
> On Fri, Feb 03, 2017 at 02:19:29AM +0100, Nenad Merdanovic wrote:
>> +psk-file <file>
>> + Enables use of PSK cipher suites with PSKs stored in the specified file.
>> + The entries should be in form "identity:key", one per line.
>> +
> Rather than new file handling routine, could you instead hook this into
> using a map? As a side bonus, it becomes trivially possible to update
> the map at runtime.
>

I think Robin has a good point but it could be merged like this and managed as a map in a second time.

Willy, i think you can merge it.

Emeric
Hi,


> Le 22 févr. 2017 à 17:26, Emeric Brun <[email protected]> a écrit :
>
> Hi,
>
> On 02/03/2017 10:22 PM, Robin H. Johnson wrote:
>> On Fri, Feb 03, 2017 at 02:19:29AM +0100, Nenad Merdanovic wrote:
>>> +psk-file <file>
>>> + Enables use of PSK cipher suites with PSKs stored in the specified file.
>>> + The entries should be in form "identity:key", one per line.
>>> +
>> Rather than new file handling routine, could you instead hook this into
>> using a map? As a side bonus, it becomes trivially possible to update
>> the map at runtime.
>>
>
> I think Robin has a good point but it could be merged like this and managed as a map in a second time.
>
> Willy, i think you can merge it.
>

PSK seems to be a good candidate for 'crt-list' (per certificate configuration).

Manu
Sorry, only registered users may post in this forum.

Click here to login