blob: 525c7b557ac80ccf7bee8483ffd1636c6c98f173 [file] [log] [blame]
Emeric Brun46591952012-05-18 15:47:34 +02001/*
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02002 * SSL/TLS transport layer over SOCK_STREAM sockets
Emeric Brun46591952012-05-18 15:47:34 +02003 *
4 * Copyright (C) 2012 EXCELIANCE, Emeric Brun <ebrun@exceliance.fr>
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version
9 * 2 of the License, or (at your option) any later version.
10 *
Willy Tarreau69845df2012-09-10 09:43:09 +020011 * Acknowledgement:
12 * We'd like to specially thank the Stud project authors for a very clean
13 * and well documented code which helped us understand how the OpenSSL API
14 * ought to be used in non-blocking mode. This is one difficult part which
15 * is not easy to get from the OpenSSL doc, and reading the Stud code made
16 * it much more obvious than the examples in the OpenSSL package. Keep up
17 * the good works, guys !
18 *
19 * Stud is an extremely efficient and scalable SSL/TLS proxy which combines
20 * particularly well with haproxy. For more info about this project, visit :
21 * https://github.com/bumptech/stud
22 *
Emeric Brun46591952012-05-18 15:47:34 +020023 */
24
25#define _GNU_SOURCE
Emeric Brunfc0421f2012-09-07 17:30:07 +020026#include <ctype.h>
27#include <dirent.h>
Emeric Brun46591952012-05-18 15:47:34 +020028#include <errno.h>
29#include <fcntl.h>
30#include <stdio.h>
31#include <stdlib.h>
Emeric Brunfc0421f2012-09-07 17:30:07 +020032#include <string.h>
33#include <unistd.h>
Emeric Brun46591952012-05-18 15:47:34 +020034
35#include <sys/socket.h>
36#include <sys/stat.h>
37#include <sys/types.h>
38
39#include <netinet/tcp.h>
40
41#include <openssl/ssl.h>
Emeric Brunfc0421f2012-09-07 17:30:07 +020042#include <openssl/x509.h>
43#include <openssl/x509v3.h>
44#include <openssl/x509.h>
45#include <openssl/err.h>
Thierry Fournier383085f2013-01-24 14:15:43 +010046#include <openssl/rand.h>
Emeric Brun46591952012-05-18 15:47:34 +020047
David Sc1ad52e2014-04-08 18:48:47 -040048#include <common/base64.h>
Emeric Brun46591952012-05-18 15:47:34 +020049#include <common/buffer.h>
50#include <common/compat.h>
51#include <common/config.h>
52#include <common/debug.h>
Willy Tarreau79eeafa2012-09-14 07:53:05 +020053#include <common/errors.h>
Emeric Brun46591952012-05-18 15:47:34 +020054#include <common/standard.h>
55#include <common/ticks.h>
56#include <common/time.h>
57
Emeric Brunfc0421f2012-09-07 17:30:07 +020058#include <ebsttree.h>
59
60#include <types/global.h>
61#include <types/ssl_sock.h>
62
Willy Tarreau7875d092012-09-10 08:20:03 +020063#include <proto/acl.h>
64#include <proto/arg.h>
Emeric Brun46591952012-05-18 15:47:34 +020065#include <proto/connection.h>
66#include <proto/fd.h>
67#include <proto/freq_ctr.h>
68#include <proto/frontend.h>
Willy Tarreau79eeafa2012-09-14 07:53:05 +020069#include <proto/listener.h>
Thierry FOURNIERed66c292013-11-28 11:05:19 +010070#include <proto/pattern.h>
Willy Tarreau92faadf2012-10-10 23:04:25 +020071#include <proto/server.h>
Emeric Brun46591952012-05-18 15:47:34 +020072#include <proto/log.h>
Emeric Brun94324a42012-10-11 14:00:19 +020073#include <proto/proxy.h>
Emeric Brunfc0421f2012-09-07 17:30:07 +020074#include <proto/shctx.h>
Emeric Brun46591952012-05-18 15:47:34 +020075#include <proto/ssl_sock.h>
76#include <proto/task.h>
77
Willy Tarreau518cedd2014-02-17 15:43:01 +010078/* Warning, these are bits, not integers! */
Emeric Brune64aef12012-09-21 13:15:06 +020079#define SSL_SOCK_ST_FL_VERIFY_DONE 0x00000001
Emeric Brund8b2bb52014-01-28 15:43:53 +010080#define SSL_SOCK_ST_FL_16K_WBFSIZE 0x00000002
Willy Tarreau518cedd2014-02-17 15:43:01 +010081#define SSL_SOCK_SEND_UNLIMITED 0x00000004
Emeric Brunf282a812012-09-21 15:27:54 +020082/* bits 0xFFFF0000 are reserved to store verify errors */
83
84/* Verify errors macros */
85#define SSL_SOCK_CA_ERROR_TO_ST(e) (((e > 63) ? 63 : e) << (16))
86#define SSL_SOCK_CAEDEPTH_TO_ST(d) (((d > 15) ? 15 : d) << (6+16))
87#define SSL_SOCK_CRTERROR_TO_ST(e) (((e > 63) ? 63 : e) << (4+6+16))
88
89#define SSL_SOCK_ST_TO_CA_ERROR(s) ((s >> (16)) & 63)
90#define SSL_SOCK_ST_TO_CAEDEPTH(s) ((s >> (6+16)) & 15)
91#define SSL_SOCK_ST_TO_CRTERROR(s) ((s >> (4+6+16)) & 63)
Emeric Brune64aef12012-09-21 13:15:06 +020092
Emeric Brun850efd52014-01-29 12:24:34 +010093/* server and bind verify method, it uses a global value as default */
94enum {
95 SSL_SOCK_VERIFY_DEFAULT = 0,
96 SSL_SOCK_VERIFY_REQUIRED = 1,
97 SSL_SOCK_VERIFY_OPTIONAL = 2,
98 SSL_SOCK_VERIFY_NONE = 3,
99};
100
Willy Tarreau71b734c2014-01-28 15:19:44 +0100101int sslconns = 0;
102int totalsslconns = 0;
Emeric Brune1f38db2012-09-03 20:36:47 +0200103
104void ssl_sock_infocbk(const SSL *ssl, int where, int ret)
105{
106 struct connection *conn = (struct connection *)SSL_get_app_data(ssl);
107 (void)ret; /* shut gcc stupid warning */
Emeric Brund8b2bb52014-01-28 15:43:53 +0100108 BIO *write_bio;
Emeric Brune1f38db2012-09-03 20:36:47 +0200109
110 if (where & SSL_CB_HANDSHAKE_START) {
111 /* Disable renegotiation (CVE-2009-3555) */
Willy Tarreau20879a02012-12-03 16:32:10 +0100112 if (conn->flags & CO_FL_CONNECTED) {
Emeric Brune1f38db2012-09-03 20:36:47 +0200113 conn->flags |= CO_FL_ERROR;
Willy Tarreau20879a02012-12-03 16:32:10 +0100114 conn->err_code = CO_ER_SSL_RENEG;
115 }
Emeric Brune1f38db2012-09-03 20:36:47 +0200116 }
Emeric Brund8b2bb52014-01-28 15:43:53 +0100117
118 if ((where & SSL_CB_ACCEPT_LOOP) == SSL_CB_ACCEPT_LOOP) {
119 if (!(conn->xprt_st & SSL_SOCK_ST_FL_16K_WBFSIZE)) {
120 /* Long certificate chains optimz
121 If write and read bios are differents, we
122 consider that the buffering was activated,
123 so we rise the output buffer size from 4k
124 to 16k */
125 write_bio = SSL_get_wbio(ssl);
126 if (write_bio != SSL_get_rbio(ssl)) {
127 BIO_set_write_buffer_size(write_bio, 16384);
128 conn->xprt_st |= SSL_SOCK_ST_FL_16K_WBFSIZE;
129 }
130 }
131 }
Emeric Brunfc0421f2012-09-07 17:30:07 +0200132}
133
Emeric Brune64aef12012-09-21 13:15:06 +0200134/* Callback is called for each certificate of the chain during a verify
135 ok is set to 1 if preverify detect no error on current certificate.
136 Returns 0 to break the handshake, 1 otherwise. */
Evan Broderbe554312013-06-27 00:05:25 -0700137int ssl_sock_bind_verifycbk(int ok, X509_STORE_CTX *x_store)
Emeric Brune64aef12012-09-21 13:15:06 +0200138{
139 SSL *ssl;
140 struct connection *conn;
Emeric Brun81c00f02012-09-21 14:31:21 +0200141 int err, depth;
Emeric Brune64aef12012-09-21 13:15:06 +0200142
143 ssl = X509_STORE_CTX_get_ex_data(x_store, SSL_get_ex_data_X509_STORE_CTX_idx());
144 conn = (struct connection *)SSL_get_app_data(ssl);
145
Willy Tarreauf7bc57c2012-10-03 00:19:48 +0200146 conn->xprt_st |= SSL_SOCK_ST_FL_VERIFY_DONE;
Emeric Brune64aef12012-09-21 13:15:06 +0200147
Emeric Brun81c00f02012-09-21 14:31:21 +0200148 if (ok) /* no errors */
149 return ok;
150
151 depth = X509_STORE_CTX_get_error_depth(x_store);
152 err = X509_STORE_CTX_get_error(x_store);
153
154 /* check if CA error needs to be ignored */
155 if (depth > 0) {
Willy Tarreauf7bc57c2012-10-03 00:19:48 +0200156 if (!SSL_SOCK_ST_TO_CA_ERROR(conn->xprt_st)) {
157 conn->xprt_st |= SSL_SOCK_CA_ERROR_TO_ST(err);
158 conn->xprt_st |= SSL_SOCK_CAEDEPTH_TO_ST(depth);
Emeric Brunf282a812012-09-21 15:27:54 +0200159 }
160
Emeric Brun1eb20ef2012-12-03 13:24:29 +0100161 if (objt_listener(conn->target)->bind_conf->ca_ignerr & (1ULL << err)) {
162 ERR_clear_error();
Emeric Brun81c00f02012-09-21 14:31:21 +0200163 return 1;
Emeric Brun1eb20ef2012-12-03 13:24:29 +0100164 }
Emeric Brun81c00f02012-09-21 14:31:21 +0200165
Willy Tarreau20879a02012-12-03 16:32:10 +0100166 conn->err_code = CO_ER_SSL_CA_FAIL;
Emeric Brun81c00f02012-09-21 14:31:21 +0200167 return 0;
168 }
169
Willy Tarreauf7bc57c2012-10-03 00:19:48 +0200170 if (!SSL_SOCK_ST_TO_CRTERROR(conn->xprt_st))
171 conn->xprt_st |= SSL_SOCK_CRTERROR_TO_ST(err);
Emeric Brunf282a812012-09-21 15:27:54 +0200172
Emeric Brun81c00f02012-09-21 14:31:21 +0200173 /* check if certificate error needs to be ignored */
Emeric Brun1eb20ef2012-12-03 13:24:29 +0100174 if (objt_listener(conn->target)->bind_conf->crt_ignerr & (1ULL << err)) {
175 ERR_clear_error();
Emeric Brun81c00f02012-09-21 14:31:21 +0200176 return 1;
Emeric Brun1eb20ef2012-12-03 13:24:29 +0100177 }
Emeric Brun81c00f02012-09-21 14:31:21 +0200178
Willy Tarreau20879a02012-12-03 16:32:10 +0100179 conn->err_code = CO_ER_SSL_CRT_FAIL;
Emeric Brun81c00f02012-09-21 14:31:21 +0200180 return 0;
Emeric Brune64aef12012-09-21 13:15:06 +0200181}
182
Willy Tarreau6c9a3d52012-10-18 18:57:14 +0200183#ifdef OPENSSL_NPN_NEGOTIATED
184/* This callback is used so that the server advertises the list of
185 * negociable protocols for NPN.
186 */
187static int ssl_sock_advertise_npn_protos(SSL *s, const unsigned char **data,
188 unsigned int *len, void *arg)
189{
190 struct bind_conf *conf = arg;
191
192 *data = (const unsigned char *)conf->npn_str;
193 *len = conf->npn_len;
194 return SSL_TLSEXT_ERR_OK;
195}
196#endif
197
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +0100198#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Willy Tarreauab861d32013-04-02 02:30:41 +0200199/* This callback is used so that the server advertises the list of
200 * negociable protocols for ALPN.
201 */
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +0100202static int ssl_sock_advertise_alpn_protos(SSL *s, const unsigned char **out,
203 unsigned char *outlen,
204 const unsigned char *server,
205 unsigned int server_len, void *arg)
Willy Tarreauab861d32013-04-02 02:30:41 +0200206{
207 struct bind_conf *conf = arg;
208
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +0100209 if (SSL_select_next_proto((unsigned char**) out, outlen, (const unsigned char *)conf->alpn_str,
210 conf->alpn_len, server, server_len) != OPENSSL_NPN_NEGOTIATED) {
211 return SSL_TLSEXT_ERR_NOACK;
212 }
Willy Tarreauab861d32013-04-02 02:30:41 +0200213 return SSL_TLSEXT_ERR_OK;
214}
215#endif
216
Emeric Brunfc0421f2012-09-07 17:30:07 +0200217#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
218/* Sets the SSL ctx of <ssl> to match the advertised server name. Returns a
219 * warning when no match is found, which implies the default (first) cert
220 * will keep being used.
221 */
Willy Tarreau2a65ff02012-09-13 17:54:29 +0200222static int ssl_sock_switchctx_cbk(SSL *ssl, int *al, struct bind_conf *s)
Emeric Brunfc0421f2012-09-07 17:30:07 +0200223{
224 const char *servername;
225 const char *wildp = NULL;
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +0200226 struct ebmb_node *node, *n;
Emeric Brunfc0421f2012-09-07 17:30:07 +0200227 int i;
228 (void)al; /* shut gcc stupid warning */
229
230 servername = SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name);
Emmanuel Hocdet65623372013-01-24 17:17:15 +0100231 if (!servername) {
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +0200232 return (s->strict_sni ?
233 SSL_TLSEXT_ERR_ALERT_FATAL :
Emmanuel Hocdet79274e22013-05-31 12:47:44 +0200234 SSL_TLSEXT_ERR_NOACK);
Emmanuel Hocdet65623372013-01-24 17:17:15 +0100235 }
Emeric Brunfc0421f2012-09-07 17:30:07 +0200236
Willy Tarreau19d14ef2012-10-29 16:51:55 +0100237 for (i = 0; i < trash.size; i++) {
Emeric Brunfc0421f2012-09-07 17:30:07 +0200238 if (!servername[i])
239 break;
Willy Tarreau19d14ef2012-10-29 16:51:55 +0100240 trash.str[i] = tolower(servername[i]);
241 if (!wildp && (trash.str[i] == '.'))
242 wildp = &trash.str[i];
Emeric Brunfc0421f2012-09-07 17:30:07 +0200243 }
Willy Tarreau19d14ef2012-10-29 16:51:55 +0100244 trash.str[i] = 0;
Emeric Brunfc0421f2012-09-07 17:30:07 +0200245
246 /* lookup in full qualified names */
Willy Tarreau19d14ef2012-10-29 16:51:55 +0100247 node = ebst_lookup(&s->sni_ctx, trash.str);
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +0200248
249 /* lookup a not neg filter */
250 for (n = node; n; n = ebmb_next_dup(n)) {
251 if (!container_of(n, struct sni_ctx, name)->neg) {
252 node = n;
253 break;
Emmanuel Hocdet65623372013-01-24 17:17:15 +0100254 }
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +0200255 }
256 if (!node && wildp) {
257 /* lookup in wildcards names */
Emeric Brunfc0421f2012-09-07 17:30:07 +0200258 node = ebst_lookup(&s->sni_w_ctx, wildp);
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +0200259 }
260 if (!node || container_of(node, struct sni_ctx, name)->neg) {
261 return (s->strict_sni ?
262 SSL_TLSEXT_ERR_ALERT_FATAL :
263 SSL_TLSEXT_ERR_ALERT_WARNING);
Emeric Brunfc0421f2012-09-07 17:30:07 +0200264 }
265
266 /* switch ctx */
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +0200267 SSL_set_SSL_CTX(ssl, container_of(node, struct sni_ctx, name)->ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +0200268 return SSL_TLSEXT_ERR_OK;
269}
270#endif /* SSL_CTRL_SET_TLSEXT_HOSTNAME */
271
Emeric Bruna4bcd9a2012-09-20 16:19:02 +0200272#ifndef OPENSSL_NO_DH
Remi Gacogne9ece05f2014-04-14 16:47:31 +0200273
274static DH *ssl_get_dh_1024(void)
275{
276 DH *dh = DH_new();
277 if (dh) {
278 dh->p = get_rfc2409_prime_1024(NULL);
279 /* See RFC 2409, Section 6 "Oakley Groups"
280 for the reason why we use 2 as a generator.
281 */
282 BN_dec2bn(&dh->g, "2");
283 if (!dh->p || !dh->g) {
284 DH_free(dh);
285 dh = NULL;
286 }
287 }
288 return dh;
289}
290
291static DH *ssl_get_dh_2048(void)
292{
293 DH *dh = DH_new();
294 if (dh) {
295 dh->p = get_rfc3526_prime_2048(NULL);
296 /* See RFC 3526, Section 3 "2048-bit MODP Group"
297 for the reason why we use 2 as a generator.
298 */
299 BN_dec2bn(&dh->g, "2");
300 if (!dh->p || !dh->g) {
301 DH_free(dh);
302 dh = NULL;
303 }
304 }
305 return dh;
306}
307
308static DH *ssl_get_dh_3072(void)
309{
310 DH *dh = DH_new();
311 if (dh) {
312 dh->p = get_rfc3526_prime_3072(NULL);
313 /* See RFC 3526, Section 4 "3072-bit MODP Group"
314 for the reason why we use 2 as a generator.
315 */
316 BN_dec2bn(&dh->g, "2");
317 if (!dh->p || !dh->g) {
318 DH_free(dh);
319 dh = NULL;
320 }
321 }
322 return dh;
323}
324
325static DH *ssl_get_dh_4096(void)
326{
327 DH *dh = DH_new();
328 if (dh) {
329 dh->p = get_rfc3526_prime_4096(NULL);
330 /* See RFC 3526, Section 5 "4096-bit MODP Group"
331 for the reason why we use 2 as a generator.
332 */
333 BN_dec2bn(&dh->g, "2");
334 if (!dh->p || !dh->g) {
335 DH_free(dh);
336 dh = NULL;
337 }
338 }
339 return dh;
340}
341
342static DH *ssl_get_dh_6144(void)
343{
344 DH *dh = DH_new();
345 if (dh) {
346 dh->p = get_rfc3526_prime_6144(NULL);
347 /* See RFC 3526, Section 6 "6144-bit MODP Group"
348 for the reason why we use 2 as a generator.
349 */
350 BN_dec2bn(&dh->g, "2");
351 if (!dh->p || !dh->g) {
352 DH_free(dh);
353 dh = NULL;
354 }
355 }
356 return dh;
357}
358
359static DH *ssl_get_dh_8192(void)
360{
361 DH *dh = DH_new();
362 if (dh) {
363 dh->p = get_rfc3526_prime_8192(NULL);
364 /* See RFC 3526, Section 7 "8192-bit MODP Group"
365 for the reason why we use 2 as a generator.
366 */
367 BN_dec2bn(&dh->g, "2");
368 if (!dh->p || !dh->g) {
369 DH_free(dh);
370 dh = NULL;
371 }
372 }
373 return dh;
374}
375
376/* Returns Diffie-Hellman parameters matching the private key length */
377static DH *ssl_get_tmp_dh(SSL *ssl, int export, int keylen)
378{
379 DH *dh = NULL;
380 EVP_PKEY *pkey = SSL_get_privatekey(ssl);
381 int type = pkey ? EVP_PKEY_type(pkey->type) : EVP_PKEY_NONE;
382
383 if (type == EVP_PKEY_RSA || type == EVP_PKEY_DSA) {
384 keylen = EVP_PKEY_bits(pkey);
385 }
386
387 if (keylen >= 8192) {
388 dh = ssl_get_dh_8192();
389 }
390 else if (keylen >= 6144) {
391 dh = ssl_get_dh_6144();
392 }
393 else if (keylen >= 4096) {
394 dh = ssl_get_dh_4096();
395 }
396 else if (keylen >= 3072) {
397 dh = ssl_get_dh_3072();
398 }
399 else if (keylen >= 2048) {
400 dh = ssl_get_dh_2048();
401 }
402 else {
403 dh = ssl_get_dh_1024();
404 }
405
406 return dh;
407}
408
Emeric Bruna4bcd9a2012-09-20 16:19:02 +0200409/* Loads Diffie-Hellman parameter from a file. Returns 1 if loaded, else -1
410 if an error occured, and 0 if parameter not found. */
Remi Gacogne9ece05f2014-04-14 16:47:31 +0200411static int ssl_sock_load_dh_params(SSL_CTX *ctx, const char *file)
Emeric Bruna4bcd9a2012-09-20 16:19:02 +0200412{
413 int ret = -1;
414 BIO *in;
415 DH *dh = NULL;
416
417 in = BIO_new(BIO_s_file());
418 if (in == NULL)
419 goto end;
420
421 if (BIO_read_filename(in, file) <= 0)
422 goto end;
423
424 dh = PEM_read_bio_DHparams(in, NULL, ctx->default_passwd_callback, ctx->default_passwd_callback_userdata);
Remi Gacogne9ece05f2014-04-14 16:47:31 +0200425 if (dh) {
426 ret = 1;
427 SSL_CTX_set_tmp_dh(ctx, dh);
428 }
429 else {
Emeric Brun41fdb3c2013-04-26 11:05:44 +0200430 /* Clear openssl global errors stack */
431 ERR_clear_error();
432
Remi Gacogne9ece05f2014-04-14 16:47:31 +0200433 SSL_CTX_set_tmp_dh_callback(ctx, ssl_get_tmp_dh);
Emeric Brun41fdb3c2013-04-26 11:05:44 +0200434 ret = 0; /* DH params not found */
Emeric Bruna4bcd9a2012-09-20 16:19:02 +0200435 }
Emeric Brun644cde02012-12-14 11:21:13 +0100436
Emeric Bruna4bcd9a2012-09-20 16:19:02 +0200437end:
438 if (dh)
439 DH_free(dh);
440
441 if (in)
Emeric Brun41fdb3c2013-04-26 11:05:44 +0200442 BIO_free(in);
Emeric Bruna4bcd9a2012-09-20 16:19:02 +0200443
444 return ret;
445}
446#endif
447
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +0200448static int ssl_sock_add_cert_sni(SSL_CTX *ctx, struct bind_conf *s, char *name, int order)
Emmanuel Hocdetfe616562013-01-22 15:31:15 +0100449{
450 struct sni_ctx *sc;
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +0200451 int wild = 0, neg = 0;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +0100452
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +0200453 if (*name == '!') {
454 neg = 1;
455 name++;
456 }
457 if (*name == '*') {
458 wild = 1;
459 name++;
460 }
461 /* !* filter is a nop */
462 if (neg && wild)
463 return order;
464 if (*name) {
465 int j, len;
466 len = strlen(name);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +0100467 sc = malloc(sizeof(struct sni_ctx) + len + 1);
468 for (j = 0; j < len; j++)
469 sc->name.key[j] = tolower(name[j]);
470 sc->name.key[len] = 0;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +0100471 sc->ctx = ctx;
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +0200472 sc->order = order++;
473 sc->neg = neg;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +0100474 if (wild)
475 ebst_insert(&s->sni_w_ctx, &sc->name);
476 else
477 ebst_insert(&s->sni_ctx, &sc->name);
478 }
479 return order;
480}
481
Emeric Brunfc0421f2012-09-07 17:30:07 +0200482/* Loads a certificate key and CA chain from a file. Returns 0 on error, -1 if
483 * an early error happens and the caller must call SSL_CTX_free() by itelf.
484 */
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +0200485static int ssl_sock_load_cert_chain_file(SSL_CTX *ctx, const char *file, struct bind_conf *s, char **sni_filter, int fcount)
Emeric Brunfc0421f2012-09-07 17:30:07 +0200486{
487 BIO *in;
488 X509 *x = NULL, *ca;
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +0200489 int i, err;
Emeric Brunfc0421f2012-09-07 17:30:07 +0200490 int ret = -1;
491 int order = 0;
492 X509_NAME *xname;
493 char *str;
Emeric Brunfc0421f2012-09-07 17:30:07 +0200494#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
495 STACK_OF(GENERAL_NAME) *names;
496#endif
497
498 in = BIO_new(BIO_s_file());
499 if (in == NULL)
500 goto end;
501
502 if (BIO_read_filename(in, file) <= 0)
503 goto end;
504
505 x = PEM_read_bio_X509_AUX(in, NULL, ctx->default_passwd_callback, ctx->default_passwd_callback_userdata);
506 if (x == NULL)
507 goto end;
508
Emeric Brun50bcecc2013-04-22 13:05:23 +0200509 if (fcount) {
510 while (fcount--)
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +0200511 order = ssl_sock_add_cert_sni(ctx, s, sni_filter[fcount], order);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +0100512 }
513 else {
Emeric Brunfc0421f2012-09-07 17:30:07 +0200514#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Emmanuel Hocdetfe616562013-01-22 15:31:15 +0100515 names = X509_get_ext_d2i(x, NID_subject_alt_name, NULL, NULL);
516 if (names) {
517 for (i = 0; i < sk_GENERAL_NAME_num(names); i++) {
518 GENERAL_NAME *name = sk_GENERAL_NAME_value(names, i);
519 if (name->type == GEN_DNS) {
520 if (ASN1_STRING_to_UTF8((unsigned char **)&str, name->d.dNSName) >= 0) {
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +0200521 order = ssl_sock_add_cert_sni(ctx, s, str, order);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +0100522 OPENSSL_free(str);
Emeric Brunfc0421f2012-09-07 17:30:07 +0200523 }
Emeric Brunfc0421f2012-09-07 17:30:07 +0200524 }
525 }
Emmanuel Hocdetfe616562013-01-22 15:31:15 +0100526 sk_GENERAL_NAME_pop_free(names, GENERAL_NAME_free);
Emeric Brunfc0421f2012-09-07 17:30:07 +0200527 }
Emeric Brunfc0421f2012-09-07 17:30:07 +0200528#endif /* SSL_CTRL_SET_TLSEXT_HOSTNAME */
Emmanuel Hocdetfe616562013-01-22 15:31:15 +0100529 xname = X509_get_subject_name(x);
530 i = -1;
531 while ((i = X509_NAME_get_index_by_NID(xname, NID_commonName, i)) != -1) {
532 X509_NAME_ENTRY *entry = X509_NAME_get_entry(xname, i);
533 if (ASN1_STRING_to_UTF8((unsigned char **)&str, entry->value) >= 0) {
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +0200534 order = ssl_sock_add_cert_sni(ctx, s, str, order);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +0100535 OPENSSL_free(str);
Emeric Brunfc0421f2012-09-07 17:30:07 +0200536 }
Emeric Brunfc0421f2012-09-07 17:30:07 +0200537 }
538 }
539
540 ret = 0; /* the caller must not free the SSL_CTX argument anymore */
541 if (!SSL_CTX_use_certificate(ctx, x))
542 goto end;
543
544 if (ctx->extra_certs != NULL) {
545 sk_X509_pop_free(ctx->extra_certs, X509_free);
546 ctx->extra_certs = NULL;
547 }
548
549 while ((ca = PEM_read_bio_X509(in, NULL, ctx->default_passwd_callback, ctx->default_passwd_callback_userdata))) {
550 if (!SSL_CTX_add_extra_chain_cert(ctx, ca)) {
551 X509_free(ca);
552 goto end;
553 }
554 }
555
556 err = ERR_get_error();
557 if (!err || (ERR_GET_LIB(err) == ERR_LIB_PEM && ERR_GET_REASON(err) == PEM_R_NO_START_LINE)) {
558 /* we successfully reached the last cert in the file */
559 ret = 1;
560 }
561 ERR_clear_error();
562
563end:
564 if (x)
565 X509_free(x);
566
567 if (in)
568 BIO_free(in);
569
570 return ret;
571}
572
Emeric Brun50bcecc2013-04-22 13:05:23 +0200573static int ssl_sock_load_cert_file(const char *path, struct bind_conf *bind_conf, struct proxy *curproxy, char **sni_filter, int fcount, char **err)
Emeric Brunfc0421f2012-09-07 17:30:07 +0200574{
575 int ret;
576 SSL_CTX *ctx;
577
578 ctx = SSL_CTX_new(SSLv23_server_method());
579 if (!ctx) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +0200580 memprintf(err, "%sunable to allocate SSL context for cert '%s'.\n",
581 err && *err ? *err : "", path);
Emeric Brunfc0421f2012-09-07 17:30:07 +0200582 return 1;
583 }
584
585 if (SSL_CTX_use_PrivateKey_file(ctx, path, SSL_FILETYPE_PEM) <= 0) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +0200586 memprintf(err, "%sunable to load SSL private key from PEM file '%s'.\n",
587 err && *err ? *err : "", path);
Emeric Brunfc0421f2012-09-07 17:30:07 +0200588 SSL_CTX_free(ctx);
589 return 1;
590 }
591
Emeric Brun50bcecc2013-04-22 13:05:23 +0200592 ret = ssl_sock_load_cert_chain_file(ctx, path, bind_conf, sni_filter, fcount);
Emeric Brunfc0421f2012-09-07 17:30:07 +0200593 if (ret <= 0) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +0200594 memprintf(err, "%sunable to load SSL certificate from PEM file '%s'.\n",
595 err && *err ? *err : "", path);
Emeric Brunfc0421f2012-09-07 17:30:07 +0200596 if (ret < 0) /* serious error, must do that ourselves */
597 SSL_CTX_free(ctx);
598 return 1;
599 }
Emeric Brun61694ab2012-10-26 13:35:33 +0200600
601 if (SSL_CTX_check_private_key(ctx) <= 0) {
602 memprintf(err, "%sinconsistencies between private key and certificate loaded from PEM file '%s'.\n",
603 err && *err ? *err : "", path);
604 return 1;
605 }
606
Emeric Brunfc0421f2012-09-07 17:30:07 +0200607 /* we must not free the SSL_CTX anymore below, since it's already in
608 * the tree, so it will be discovered and cleaned in time.
609 */
Emeric Bruna4bcd9a2012-09-20 16:19:02 +0200610#ifndef OPENSSL_NO_DH
611 ret = ssl_sock_load_dh_params(ctx, path);
612 if (ret < 0) {
613 if (err)
614 memprintf(err, "%sunable to load DH parameters from file '%s'.\n",
615 *err ? *err : "", path);
616 return 1;
617 }
618#endif
619
Emeric Brunfc0421f2012-09-07 17:30:07 +0200620#ifndef SSL_CTRL_SET_TLSEXT_HOSTNAME
Willy Tarreau2a65ff02012-09-13 17:54:29 +0200621 if (bind_conf->default_ctx) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +0200622 memprintf(err, "%sthis version of openssl cannot load multiple SSL certificates.\n",
623 err && *err ? *err : "");
Emeric Brunfc0421f2012-09-07 17:30:07 +0200624 return 1;
625 }
626#endif
Willy Tarreau2a65ff02012-09-13 17:54:29 +0200627 if (!bind_conf->default_ctx)
628 bind_conf->default_ctx = ctx;
Emeric Brunfc0421f2012-09-07 17:30:07 +0200629
630 return 0;
631}
632
Willy Tarreau79eeafa2012-09-14 07:53:05 +0200633int ssl_sock_load_cert(char *path, struct bind_conf *bind_conf, struct proxy *curproxy, char **err)
Emeric Brunfc0421f2012-09-07 17:30:07 +0200634{
635 struct dirent *de;
636 DIR *dir;
637 struct stat buf;
Willy Tarreauee2663b2012-12-06 11:36:59 +0100638 char *end;
639 char fp[MAXPATHLEN+1];
Emeric Brunfc0421f2012-09-07 17:30:07 +0200640 int cfgerr = 0;
641
642 if (!(dir = opendir(path)))
Emeric Brun50bcecc2013-04-22 13:05:23 +0200643 return ssl_sock_load_cert_file(path, bind_conf, curproxy, NULL, 0, err);
Emeric Brunfc0421f2012-09-07 17:30:07 +0200644
645 /* strip trailing slashes, including first one */
646 for (end = path + strlen(path) - 1; end >= path && *end == '/'; end--)
647 *end = 0;
648
Emeric Brunfc0421f2012-09-07 17:30:07 +0200649 while ((de = readdir(dir))) {
Willy Tarreauee2663b2012-12-06 11:36:59 +0100650 snprintf(fp, sizeof(fp), "%s/%s", path, de->d_name);
Emeric Brunfc0421f2012-09-07 17:30:07 +0200651 if (stat(fp, &buf) != 0) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +0200652 memprintf(err, "%sunable to stat SSL certificate from file '%s' : %s.\n",
653 err && *err ? *err : "", fp, strerror(errno));
Emeric Brunfc0421f2012-09-07 17:30:07 +0200654 cfgerr++;
655 continue;
656 }
657 if (!S_ISREG(buf.st_mode))
658 continue;
Emeric Brun50bcecc2013-04-22 13:05:23 +0200659 cfgerr += ssl_sock_load_cert_file(fp, bind_conf, curproxy, NULL, 0, err);
Emeric Brunfc0421f2012-09-07 17:30:07 +0200660 }
Emeric Brunfc0421f2012-09-07 17:30:07 +0200661 closedir(dir);
662 return cfgerr;
663}
664
Thierry Fournier383085f2013-01-24 14:15:43 +0100665/* Make sure openssl opens /dev/urandom before the chroot. The work is only
666 * done once. Zero is returned if the operation fails. No error is returned
667 * if the random is said as not implemented, because we expect that openssl
668 * will use another method once needed.
669 */
670static int ssl_initialize_random()
671{
672 unsigned char random;
673 static int random_initialized = 0;
674
675 if (!random_initialized && RAND_bytes(&random, 1) != 0)
676 random_initialized = 1;
677
678 return random_initialized;
679}
680
Emmanuel Hocdetfe616562013-01-22 15:31:15 +0100681int ssl_sock_load_cert_list_file(char *file, struct bind_conf *bind_conf, struct proxy *curproxy, char **err)
682{
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +0200683 char thisline[LINESIZE];
Emmanuel Hocdetfe616562013-01-22 15:31:15 +0100684 FILE *f;
685 int linenum = 0;
686 int cfgerr = 0;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +0100687
Willy Tarreauad1731d2013-04-02 17:35:58 +0200688 if ((f = fopen(file, "r")) == NULL) {
689 memprintf(err, "cannot open file '%s' : %s", file, strerror(errno));
Emmanuel Hocdetfe616562013-01-22 15:31:15 +0100690 return 1;
Willy Tarreauad1731d2013-04-02 17:35:58 +0200691 }
Emmanuel Hocdetfe616562013-01-22 15:31:15 +0100692
693 while (fgets(thisline, sizeof(thisline), f) != NULL) {
694 int arg;
Emeric Brun50bcecc2013-04-22 13:05:23 +0200695 int newarg;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +0100696 char *end;
697 char *args[MAX_LINE_ARGS + 1];
698 char *line = thisline;
699
700 linenum++;
701 end = line + strlen(line);
702 if (end-line == sizeof(thisline)-1 && *(end-1) != '\n') {
703 /* Check if we reached the limit and the last char is not \n.
704 * Watch out for the last line without the terminating '\n'!
705 */
Willy Tarreauad1731d2013-04-02 17:35:58 +0200706 memprintf(err, "line %d too long in file '%s', limit is %d characters",
707 linenum, file, (int)sizeof(thisline)-1);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +0100708 cfgerr = 1;
Willy Tarreauad1731d2013-04-02 17:35:58 +0200709 break;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +0100710 }
711
Emmanuel Hocdetfe616562013-01-22 15:31:15 +0100712 arg = 0;
Emeric Brun50bcecc2013-04-22 13:05:23 +0200713 newarg = 1;
714 while (*line) {
Emmanuel Hocdetfe616562013-01-22 15:31:15 +0100715 if (*line == '#' || *line == '\n' || *line == '\r') {
716 /* end of string, end of loop */
717 *line = 0;
718 break;
719 }
720 else if (isspace(*line)) {
Emeric Brun50bcecc2013-04-22 13:05:23 +0200721 newarg = 1;
722 *line = 0;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +0100723 }
Emeric Brun50bcecc2013-04-22 13:05:23 +0200724 else if (newarg) {
725 if (arg == MAX_LINE_ARGS) {
726 memprintf(err, "too many args on line %d in file '%s'.",
727 linenum, file);
728 cfgerr = 1;
729 break;
730 }
731 newarg = 0;
732 args[arg++] = line;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +0100733 }
Emeric Brun50bcecc2013-04-22 13:05:23 +0200734 line++;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +0100735 }
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +0200736 if (cfgerr)
737 break;
Willy Tarreauad1731d2013-04-02 17:35:58 +0200738
Emmanuel Hocdetfe616562013-01-22 15:31:15 +0100739 /* empty line */
Emeric Brun50bcecc2013-04-22 13:05:23 +0200740 if (!arg)
Emmanuel Hocdetfe616562013-01-22 15:31:15 +0100741 continue;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +0100742
Emeric Brun50bcecc2013-04-22 13:05:23 +0200743 cfgerr = ssl_sock_load_cert_file(args[0], bind_conf, curproxy, &args[1], arg-1, err);
Willy Tarreauad1731d2013-04-02 17:35:58 +0200744 if (cfgerr) {
745 memprintf(err, "error processing line %d in file '%s' : %s", linenum, file, *err);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +0100746 break;
Willy Tarreauad1731d2013-04-02 17:35:58 +0200747 }
Emmanuel Hocdetfe616562013-01-22 15:31:15 +0100748 }
Emmanuel Hocdetfe616562013-01-22 15:31:15 +0100749 fclose(f);
750 return cfgerr;
751}
752
Emeric Brunfc0421f2012-09-07 17:30:07 +0200753#ifndef SSL_OP_CIPHER_SERVER_PREFERENCE /* needs OpenSSL >= 0.9.7 */
754#define SSL_OP_CIPHER_SERVER_PREFERENCE 0
755#endif
756
757#ifndef SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION /* needs OpenSSL >= 0.9.7 */
758#define SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION 0
Willy Tarreau7d588ee2012-11-26 18:47:31 +0100759#define SSL_renegotiate_pending(arg) 0
Emeric Brunfc0421f2012-09-07 17:30:07 +0200760#endif
Emeric Brun2b58d042012-09-20 17:10:03 +0200761#ifndef SSL_OP_SINGLE_ECDH_USE /* needs OpenSSL >= 0.9.8 */
762#define SSL_OP_SINGLE_ECDH_USE 0
763#endif
Emeric Brun2d0c4822012-10-02 13:45:20 +0200764#ifndef SSL_OP_NO_TICKET /* needs OpenSSL >= 0.9.8 */
765#define SSL_OP_NO_TICKET 0
766#endif
Emeric Brunfc0421f2012-09-07 17:30:07 +0200767#ifndef SSL_OP_NO_COMPRESSION /* needs OpenSSL >= 0.9.9 */
768#define SSL_OP_NO_COMPRESSION 0
769#endif
Emeric Brunc0ff4922012-09-28 19:37:02 +0200770#ifndef SSL_OP_NO_TLSv1_1 /* needs OpenSSL >= 1.0.1 */
771#define SSL_OP_NO_TLSv1_1 0
772#endif
773#ifndef SSL_OP_NO_TLSv1_2 /* needs OpenSSL >= 1.0.1 */
774#define SSL_OP_NO_TLSv1_2 0
775#endif
Emeric Bruna4bcd9a2012-09-20 16:19:02 +0200776#ifndef SSL_OP_SINGLE_DH_USE /* needs OpenSSL >= 0.9.6 */
777#define SSL_OP_SINGLE_DH_USE 0
778#endif
Emeric Brun2b58d042012-09-20 17:10:03 +0200779#ifndef SSL_OP_SINGLE_ECDH_USE /* needs OpenSSL >= 1.0.0 */
780#define SSL_OP_SINGLE_ECDH_USE 0
781#endif
Emeric Brunfc0421f2012-09-07 17:30:07 +0200782#ifndef SSL_MODE_RELEASE_BUFFERS /* needs OpenSSL >= 1.0.0 */
783#define SSL_MODE_RELEASE_BUFFERS 0
784#endif
Willy Tarreau2a65ff02012-09-13 17:54:29 +0200785int ssl_sock_prepare_ctx(struct bind_conf *bind_conf, SSL_CTX *ctx, struct proxy *curproxy)
Emeric Brunfc0421f2012-09-07 17:30:07 +0200786{
787 int cfgerr = 0;
Emeric Brun850efd52014-01-29 12:24:34 +0100788 int verify = SSL_VERIFY_NONE;
Emeric Brunfc0421f2012-09-07 17:30:07 +0200789 int ssloptions =
790 SSL_OP_ALL | /* all known workarounds for bugs */
791 SSL_OP_NO_SSLv2 |
792 SSL_OP_NO_COMPRESSION |
Emeric Bruna4bcd9a2012-09-20 16:19:02 +0200793 SSL_OP_SINGLE_DH_USE |
Emeric Brun2b58d042012-09-20 17:10:03 +0200794 SSL_OP_SINGLE_ECDH_USE |
Emeric Brun3c4bc6e2012-10-04 18:44:19 +0200795 SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION |
796 SSL_OP_CIPHER_SERVER_PREFERENCE;
Emeric Brunfc0421f2012-09-07 17:30:07 +0200797 int sslmode =
798 SSL_MODE_ENABLE_PARTIAL_WRITE |
799 SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER |
800 SSL_MODE_RELEASE_BUFFERS;
801
Thierry Fournier383085f2013-01-24 14:15:43 +0100802 /* Make sure openssl opens /dev/urandom before the chroot */
803 if (!ssl_initialize_random()) {
804 Alert("OpenSSL random data generator initialization failed.\n");
805 cfgerr++;
806 }
807
Emeric Brun89675492012-10-05 13:48:26 +0200808 if (bind_conf->ssl_options & BC_SSL_O_NO_SSLV3)
Emeric Brunfc0421f2012-09-07 17:30:07 +0200809 ssloptions |= SSL_OP_NO_SSLv3;
Emeric Brun89675492012-10-05 13:48:26 +0200810 if (bind_conf->ssl_options & BC_SSL_O_NO_TLSV10)
Emeric Brunfc0421f2012-09-07 17:30:07 +0200811 ssloptions |= SSL_OP_NO_TLSv1;
Emeric Brun89675492012-10-05 13:48:26 +0200812 if (bind_conf->ssl_options & BC_SSL_O_NO_TLSV11)
Emeric Brunc0ff4922012-09-28 19:37:02 +0200813 ssloptions |= SSL_OP_NO_TLSv1_1;
Emeric Brun89675492012-10-05 13:48:26 +0200814 if (bind_conf->ssl_options & BC_SSL_O_NO_TLSV12)
Emeric Brunc0ff4922012-09-28 19:37:02 +0200815 ssloptions |= SSL_OP_NO_TLSv1_2;
Emeric Brun89675492012-10-05 13:48:26 +0200816 if (bind_conf->ssl_options & BC_SSL_O_NO_TLS_TICKETS)
Emeric Brun2d0c4822012-10-02 13:45:20 +0200817 ssloptions |= SSL_OP_NO_TICKET;
Emeric Brun2cb7ae52012-10-05 14:14:21 +0200818 if (bind_conf->ssl_options & BC_SSL_O_USE_SSLV3)
819 SSL_CTX_set_ssl_version(ctx, SSLv3_server_method());
820 if (bind_conf->ssl_options & BC_SSL_O_USE_TLSV10)
821 SSL_CTX_set_ssl_version(ctx, TLSv1_server_method());
822#if SSL_OP_NO_TLSv1_1
823 if (bind_conf->ssl_options & BC_SSL_O_USE_TLSV11)
824 SSL_CTX_set_ssl_version(ctx, TLSv1_1_server_method());
825#endif
826#if SSL_OP_NO_TLSv1_2
827 if (bind_conf->ssl_options & BC_SSL_O_USE_TLSV12)
828 SSL_CTX_set_ssl_version(ctx, TLSv1_2_server_method());
829#endif
Emeric Brunfc0421f2012-09-07 17:30:07 +0200830
831 SSL_CTX_set_options(ctx, ssloptions);
832 SSL_CTX_set_mode(ctx, sslmode);
Emeric Brun850efd52014-01-29 12:24:34 +0100833 switch (bind_conf->verify) {
834 case SSL_SOCK_VERIFY_NONE:
835 verify = SSL_VERIFY_NONE;
836 break;
837 case SSL_SOCK_VERIFY_OPTIONAL:
838 verify = SSL_VERIFY_PEER;
839 break;
840 case SSL_SOCK_VERIFY_REQUIRED:
841 verify = SSL_VERIFY_PEER|SSL_VERIFY_FAIL_IF_NO_PEER_CERT;
842 break;
843 }
844 SSL_CTX_set_verify(ctx, verify, ssl_sock_bind_verifycbk);
845 if (verify & SSL_VERIFY_PEER) {
Emeric Brunfb510ea2012-10-05 12:00:26 +0200846 if (bind_conf->ca_file) {
Emeric Brund94b3fe2012-09-20 18:23:56 +0200847 /* load CAfile to verify */
Emeric Brunfb510ea2012-10-05 12:00:26 +0200848 if (!SSL_CTX_load_verify_locations(ctx, bind_conf->ca_file, NULL)) {
Emeric Brund94b3fe2012-09-20 18:23:56 +0200849 Alert("Proxy '%s': unable to load CA file '%s' for bind '%s' at [%s:%d].\n",
Emeric Brunfb510ea2012-10-05 12:00:26 +0200850 curproxy->id, bind_conf->ca_file, bind_conf->arg, bind_conf->file, bind_conf->line);
Emeric Brund94b3fe2012-09-20 18:23:56 +0200851 cfgerr++;
852 }
853 /* set CA names fo client cert request, function returns void */
Emeric Brunfb510ea2012-10-05 12:00:26 +0200854 SSL_CTX_set_client_CA_list(ctx, SSL_load_client_CA_file(bind_conf->ca_file));
Emeric Brund94b3fe2012-09-20 18:23:56 +0200855 }
Emeric Brun850efd52014-01-29 12:24:34 +0100856 else {
857 Alert("Proxy '%s': verify is enabled but no CA file specified for bind '%s' at [%s:%d].\n",
858 curproxy->id, bind_conf->arg, bind_conf->file, bind_conf->line);
859 cfgerr++;
860 }
Emeric Brun051cdab2012-10-02 19:25:50 +0200861#ifdef X509_V_FLAG_CRL_CHECK
Emeric Brunfb510ea2012-10-05 12:00:26 +0200862 if (bind_conf->crl_file) {
Emeric Brund94b3fe2012-09-20 18:23:56 +0200863 X509_STORE *store = SSL_CTX_get_cert_store(ctx);
864
Emeric Brunfb510ea2012-10-05 12:00:26 +0200865 if (!store || !X509_STORE_load_locations(store, bind_conf->crl_file, NULL)) {
Emeric Brund94b3fe2012-09-20 18:23:56 +0200866 Alert("Proxy '%s': unable to configure CRL file '%s' for bind '%s' at [%s:%d].\n",
Emeric Brunfb510ea2012-10-05 12:00:26 +0200867 curproxy->id, bind_conf->ca_file, bind_conf->arg, bind_conf->file, bind_conf->line);
Emeric Brund94b3fe2012-09-20 18:23:56 +0200868 cfgerr++;
869 }
Emeric Brun561e5742012-10-02 15:20:55 +0200870 else {
871 X509_STORE_set_flags(store, X509_V_FLAG_CRL_CHECK|X509_V_FLAG_CRL_CHECK_ALL);
872 }
Emeric Brund94b3fe2012-09-20 18:23:56 +0200873 }
Emeric Brun051cdab2012-10-02 19:25:50 +0200874#endif
Emeric Brun644cde02012-12-14 11:21:13 +0100875 ERR_clear_error();
Emeric Brund94b3fe2012-09-20 18:23:56 +0200876 }
Emeric Brunfc0421f2012-09-07 17:30:07 +0200877
Emeric Brun4f65bff2012-11-16 15:11:00 +0100878 if (global.tune.ssllifetime)
879 SSL_CTX_set_timeout(ctx, global.tune.ssllifetime);
880
Emeric Brunfc0421f2012-09-07 17:30:07 +0200881 shared_context_set_cache(ctx);
Willy Tarreau2a65ff02012-09-13 17:54:29 +0200882 if (bind_conf->ciphers &&
883 !SSL_CTX_set_cipher_list(ctx, bind_conf->ciphers)) {
Emeric Brunfc0421f2012-09-07 17:30:07 +0200884 Alert("Proxy '%s': unable to set SSL cipher list to '%s' for bind '%s' at [%s:%d].\n",
Willy Tarreau2a65ff02012-09-13 17:54:29 +0200885 curproxy->id, bind_conf->ciphers, bind_conf->arg, bind_conf->file, bind_conf->line);
Emeric Brunfc0421f2012-09-07 17:30:07 +0200886 cfgerr++;
887 }
888
889 SSL_CTX_set_info_callback(ctx, ssl_sock_infocbk);
Willy Tarreau6c9a3d52012-10-18 18:57:14 +0200890#ifdef OPENSSL_NPN_NEGOTIATED
891 if (bind_conf->npn_str)
892 SSL_CTX_set_next_protos_advertised_cb(ctx, ssl_sock_advertise_npn_protos, bind_conf);
893#endif
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +0100894#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Willy Tarreauab861d32013-04-02 02:30:41 +0200895 if (bind_conf->alpn_str)
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +0100896 SSL_CTX_set_alpn_select_cb(ctx, ssl_sock_advertise_alpn_protos, bind_conf);
Willy Tarreauab861d32013-04-02 02:30:41 +0200897#endif
Willy Tarreau6c9a3d52012-10-18 18:57:14 +0200898
Emeric Brunfc0421f2012-09-07 17:30:07 +0200899#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
900 SSL_CTX_set_tlsext_servername_callback(ctx, ssl_sock_switchctx_cbk);
Willy Tarreau2a65ff02012-09-13 17:54:29 +0200901 SSL_CTX_set_tlsext_servername_arg(ctx, bind_conf);
Emeric Brunfc0421f2012-09-07 17:30:07 +0200902#endif
Emeric Brun2b58d042012-09-20 17:10:03 +0200903#if defined(SSL_CTX_set_tmp_ecdh) && !defined(OPENSSL_NO_ECDH)
Emeric Brun6924ef82013-03-06 14:08:53 +0100904 {
Emeric Brun2b58d042012-09-20 17:10:03 +0200905 int i;
906 EC_KEY *ecdh;
907
Emeric Brun6924ef82013-03-06 14:08:53 +0100908 i = OBJ_sn2nid(bind_conf->ecdhe ? bind_conf->ecdhe : ECDHE_DEFAULT_CURVE);
Emeric Brun2b58d042012-09-20 17:10:03 +0200909 if (!i || ((ecdh = EC_KEY_new_by_curve_name(i)) == NULL)) {
910 Alert("Proxy '%s': unable to set elliptic named curve to '%s' for bind '%s' at [%s:%d].\n",
Emeric Brun6924ef82013-03-06 14:08:53 +0100911 curproxy->id, bind_conf->ecdhe ? bind_conf->ecdhe : ECDHE_DEFAULT_CURVE,
912 bind_conf->arg, bind_conf->file, bind_conf->line);
Emeric Brun2b58d042012-09-20 17:10:03 +0200913 cfgerr++;
914 }
915 else {
916 SSL_CTX_set_tmp_ecdh(ctx, ecdh);
917 EC_KEY_free(ecdh);
918 }
919 }
920#endif
921
Emeric Brunfc0421f2012-09-07 17:30:07 +0200922 return cfgerr;
923}
924
Evan Broderbe554312013-06-27 00:05:25 -0700925static int ssl_sock_srv_hostcheck(const char *pattern, const char *hostname)
926{
927 const char *pattern_wildcard, *pattern_left_label_end, *hostname_left_label_end;
928 size_t prefixlen, suffixlen;
929
930 /* Trivial case */
931 if (strcmp(pattern, hostname) == 0)
932 return 1;
933
Evan Broderbe554312013-06-27 00:05:25 -0700934 /* The rest of this logic is based on RFC 6125, section 6.4.3
935 * (http://tools.ietf.org/html/rfc6125#section-6.4.3) */
936
Emeric Bruna848dae2013-10-08 11:27:28 +0200937 pattern_wildcard = NULL;
938 pattern_left_label_end = pattern;
939 while (*pattern_left_label_end != '.') {
940 switch (*pattern_left_label_end) {
941 case 0:
942 /* End of label not found */
943 return 0;
944 case '*':
945 /* If there is more than one wildcards */
946 if (pattern_wildcard)
947 return 0;
948 pattern_wildcard = pattern_left_label_end;
949 break;
950 }
951 pattern_left_label_end++;
952 }
953
954 /* If it's not trivial and there is no wildcard, it can't
955 * match */
956 if (!pattern_wildcard)
Evan Broderbe554312013-06-27 00:05:25 -0700957 return 0;
958
959 /* Make sure all labels match except the leftmost */
960 hostname_left_label_end = strchr(hostname, '.');
961 if (!hostname_left_label_end
962 || strcmp(pattern_left_label_end, hostname_left_label_end) != 0)
963 return 0;
964
965 /* Make sure the leftmost label of the hostname is long enough
966 * that the wildcard can match */
Emeric Brun369da852013-10-08 11:39:35 +0200967 if (hostname_left_label_end - hostname < (pattern_left_label_end - pattern) - 1)
Evan Broderbe554312013-06-27 00:05:25 -0700968 return 0;
969
970 /* Finally compare the string on either side of the
971 * wildcard */
972 prefixlen = pattern_wildcard - pattern;
973 suffixlen = pattern_left_label_end - (pattern_wildcard + 1);
Emeric Bruna848dae2013-10-08 11:27:28 +0200974 if ((prefixlen && (memcmp(pattern, hostname, prefixlen) != 0))
975 || (suffixlen && (memcmp(pattern_wildcard + 1, hostname_left_label_end - suffixlen, suffixlen) != 0)))
Evan Broderbe554312013-06-27 00:05:25 -0700976 return 0;
977
978 return 1;
979}
980
981static int ssl_sock_srv_verifycbk(int ok, X509_STORE_CTX *ctx)
982{
983 SSL *ssl;
984 struct connection *conn;
985 char *servername;
986
987 int depth;
988 X509 *cert;
989 STACK_OF(GENERAL_NAME) *alt_names;
990 int i;
991 X509_NAME *cert_subject;
992 char *str;
993
994 if (ok == 0)
995 return ok;
996
997 ssl = X509_STORE_CTX_get_ex_data(ctx, SSL_get_ex_data_X509_STORE_CTX_idx());
998 conn = (struct connection *)SSL_get_app_data(ssl);
999
1000 servername = objt_server(conn->target)->ssl_ctx.verify_host;
1001
1002 /* We only need to verify the CN on the actual server cert,
1003 * not the indirect CAs */
1004 depth = X509_STORE_CTX_get_error_depth(ctx);
1005 if (depth != 0)
1006 return ok;
1007
1008 /* At this point, the cert is *not* OK unless we can find a
1009 * hostname match */
1010 ok = 0;
1011
1012 cert = X509_STORE_CTX_get_current_cert(ctx);
1013 /* It seems like this might happen if verify peer isn't set */
1014 if (!cert)
1015 return ok;
1016
1017 alt_names = X509_get_ext_d2i(cert, NID_subject_alt_name, NULL, NULL);
1018 if (alt_names) {
1019 for (i = 0; !ok && i < sk_GENERAL_NAME_num(alt_names); i++) {
1020 GENERAL_NAME *name = sk_GENERAL_NAME_value(alt_names, i);
1021 if (name->type == GEN_DNS) {
Emeric Bruna33410c2013-09-17 15:47:48 +02001022#if OPENSSL_VERSION_NUMBER < 0x00907000L
1023 if (ASN1_STRING_to_UTF8((unsigned char **)&str, name->d.ia5) >= 0) {
1024#else
Evan Broderbe554312013-06-27 00:05:25 -07001025 if (ASN1_STRING_to_UTF8((unsigned char **)&str, name->d.dNSName) >= 0) {
Emeric Bruna33410c2013-09-17 15:47:48 +02001026#endif
Evan Broderbe554312013-06-27 00:05:25 -07001027 ok = ssl_sock_srv_hostcheck(str, servername);
1028 OPENSSL_free(str);
1029 }
1030 }
1031 }
Emeric Brun4ad50a42013-09-17 15:19:54 +02001032 sk_GENERAL_NAME_pop_free(alt_names, GENERAL_NAME_free);
Evan Broderbe554312013-06-27 00:05:25 -07001033 }
1034
1035 cert_subject = X509_get_subject_name(cert);
1036 i = -1;
1037 while (!ok && (i = X509_NAME_get_index_by_NID(cert_subject, NID_commonName, i)) != -1) {
1038 X509_NAME_ENTRY *entry = X509_NAME_get_entry(cert_subject, i);
1039 if (ASN1_STRING_to_UTF8((unsigned char **)&str, entry->value) >= 0) {
1040 ok = ssl_sock_srv_hostcheck(str, servername);
1041 OPENSSL_free(str);
1042 }
1043 }
1044
1045 return ok;
1046}
1047
Emeric Brun94324a42012-10-11 14:00:19 +02001048/* prepare ssl context from servers options. Returns an error count */
1049int ssl_sock_prepare_srv_ctx(struct server *srv, struct proxy *curproxy)
1050{
1051 int cfgerr = 0;
1052 int options =
1053 SSL_OP_ALL | /* all known workarounds for bugs */
1054 SSL_OP_NO_SSLv2 |
1055 SSL_OP_NO_COMPRESSION;
1056 int mode =
1057 SSL_MODE_ENABLE_PARTIAL_WRITE |
1058 SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER |
1059 SSL_MODE_RELEASE_BUFFERS;
Emeric Brun850efd52014-01-29 12:24:34 +01001060 int verify = SSL_VERIFY_NONE;
Emeric Brun94324a42012-10-11 14:00:19 +02001061
Thierry Fournier383085f2013-01-24 14:15:43 +01001062 /* Make sure openssl opens /dev/urandom before the chroot */
1063 if (!ssl_initialize_random()) {
1064 Alert("OpenSSL random data generator initialization failed.\n");
1065 cfgerr++;
1066 }
1067
Emeric Brun94324a42012-10-11 14:00:19 +02001068 /* Initiate SSL context for current server */
1069 srv->ssl_ctx.reused_sess = NULL;
1070 if (srv->use_ssl)
1071 srv->xprt = &ssl_sock;
1072 if (srv->check.use_ssl)
Simon Horman66183002013-02-23 10:16:43 +09001073 srv->check_common.xprt = &ssl_sock;
Emeric Brun94324a42012-10-11 14:00:19 +02001074
1075 srv->ssl_ctx.ctx = SSL_CTX_new(SSLv23_client_method());
1076 if (!srv->ssl_ctx.ctx) {
1077 Alert("config : %s '%s', server '%s': unable to allocate ssl context.\n",
1078 proxy_type_str(curproxy), curproxy->id,
1079 srv->id);
1080 cfgerr++;
1081 return cfgerr;
1082 }
Emeric Bruna7aa3092012-10-26 12:58:00 +02001083 if (srv->ssl_ctx.client_crt) {
1084 if (SSL_CTX_use_PrivateKey_file(srv->ssl_ctx.ctx, srv->ssl_ctx.client_crt, SSL_FILETYPE_PEM) <= 0) {
1085 Alert("config : %s '%s', server '%s': unable to load SSL private key from PEM file '%s'.\n",
1086 proxy_type_str(curproxy), curproxy->id,
1087 srv->id, srv->ssl_ctx.client_crt);
1088 cfgerr++;
1089 }
1090 else if (SSL_CTX_use_certificate_chain_file(srv->ssl_ctx.ctx, srv->ssl_ctx.client_crt) <= 0) {
1091 Alert("config : %s '%s', server '%s': unable to load ssl certificate from PEM file '%s'.\n",
1092 proxy_type_str(curproxy), curproxy->id,
1093 srv->id, srv->ssl_ctx.client_crt);
1094 cfgerr++;
1095 }
1096 else if (SSL_CTX_check_private_key(srv->ssl_ctx.ctx) <= 0) {
1097 Alert("config : %s '%s', server '%s': inconsistencies between private key and certificate loaded from PEM file '%s'.\n",
1098 proxy_type_str(curproxy), curproxy->id,
1099 srv->id, srv->ssl_ctx.client_crt);
1100 cfgerr++;
1101 }
1102 }
Emeric Brun94324a42012-10-11 14:00:19 +02001103
1104 if (srv->ssl_ctx.options & SRV_SSL_O_NO_SSLV3)
1105 options |= SSL_OP_NO_SSLv3;
1106 if (srv->ssl_ctx.options & SRV_SSL_O_NO_TLSV10)
1107 options |= SSL_OP_NO_TLSv1;
1108 if (srv->ssl_ctx.options & SRV_SSL_O_NO_TLSV11)
1109 options |= SSL_OP_NO_TLSv1_1;
1110 if (srv->ssl_ctx.options & SRV_SSL_O_NO_TLSV12)
1111 options |= SSL_OP_NO_TLSv1_2;
Emeric Brunf9c5c472012-10-11 15:28:34 +02001112 if (srv->ssl_ctx.options & SRV_SSL_O_NO_TLS_TICKETS)
1113 options |= SSL_OP_NO_TICKET;
Emeric Brun94324a42012-10-11 14:00:19 +02001114 if (srv->ssl_ctx.options & SRV_SSL_O_USE_SSLV3)
1115 SSL_CTX_set_ssl_version(srv->ssl_ctx.ctx, SSLv3_client_method());
1116 if (srv->ssl_ctx.options & SRV_SSL_O_USE_TLSV10)
1117 SSL_CTX_set_ssl_version(srv->ssl_ctx.ctx, TLSv1_client_method());
1118#if SSL_OP_NO_TLSv1_1
1119 if (srv->ssl_ctx.options & SRV_SSL_O_USE_TLSV11)
1120 SSL_CTX_set_ssl_version(srv->ssl_ctx.ctx, TLSv1_1_client_method());
1121#endif
1122#if SSL_OP_NO_TLSv1_2
1123 if (srv->ssl_ctx.options & SRV_SSL_O_USE_TLSV12)
1124 SSL_CTX_set_ssl_version(srv->ssl_ctx.ctx, TLSv1_2_client_method());
1125#endif
1126
1127 SSL_CTX_set_options(srv->ssl_ctx.ctx, options);
1128 SSL_CTX_set_mode(srv->ssl_ctx.ctx, mode);
Emeric Brun850efd52014-01-29 12:24:34 +01001129
1130 if (global.ssl_server_verify == SSL_SERVER_VERIFY_REQUIRED)
1131 verify = SSL_VERIFY_PEER;
1132
1133 switch (srv->ssl_ctx.verify) {
1134 case SSL_SOCK_VERIFY_NONE:
1135 verify = SSL_VERIFY_NONE;
1136 break;
1137 case SSL_SOCK_VERIFY_REQUIRED:
1138 verify = SSL_VERIFY_PEER;
1139 break;
1140 }
Evan Broderbe554312013-06-27 00:05:25 -07001141 SSL_CTX_set_verify(srv->ssl_ctx.ctx,
Emeric Brun850efd52014-01-29 12:24:34 +01001142 verify,
Evan Broderbe554312013-06-27 00:05:25 -07001143 srv->ssl_ctx.verify_host ? ssl_sock_srv_verifycbk : NULL);
Emeric Brun850efd52014-01-29 12:24:34 +01001144 if (verify & SSL_VERIFY_PEER) {
Emeric Brunef42d922012-10-11 16:11:36 +02001145 if (srv->ssl_ctx.ca_file) {
1146 /* load CAfile to verify */
1147 if (!SSL_CTX_load_verify_locations(srv->ssl_ctx.ctx, srv->ssl_ctx.ca_file, NULL)) {
Willy Tarreau07ba08b2014-02-16 19:22:08 +01001148 Alert("Proxy '%s', server '%s' [%s:%d] unable to load CA file '%s'.\n",
Emeric Brunef42d922012-10-11 16:11:36 +02001149 curproxy->id, srv->id,
1150 srv->conf.file, srv->conf.line, srv->ssl_ctx.ca_file);
1151 cfgerr++;
1152 }
1153 }
Emeric Brun850efd52014-01-29 12:24:34 +01001154 else {
1155 if (global.ssl_server_verify == SSL_SERVER_VERIFY_REQUIRED)
Willy Tarreau07ba08b2014-02-16 19:22:08 +01001156 Alert("Proxy '%s', server '%s' [%s:%d] verify is enabled by default but no CA file specified. If you're running on a LAN where you're certain to trust the server's certificate, please set an explicit 'verify none' statement on the 'server' line, or use 'ssl-server-verify none' in the global section to disable server-side verifications by default.\n",
Emeric Brun850efd52014-01-29 12:24:34 +01001157 curproxy->id, srv->id,
1158 srv->conf.file, srv->conf.line);
1159 else
Willy Tarreau07ba08b2014-02-16 19:22:08 +01001160 Alert("Proxy '%s', server '%s' [%s:%d] verify is enabled but no CA file specified.\n",
Emeric Brun850efd52014-01-29 12:24:34 +01001161 curproxy->id, srv->id,
1162 srv->conf.file, srv->conf.line);
1163 cfgerr++;
1164 }
Emeric Brunef42d922012-10-11 16:11:36 +02001165#ifdef X509_V_FLAG_CRL_CHECK
1166 if (srv->ssl_ctx.crl_file) {
1167 X509_STORE *store = SSL_CTX_get_cert_store(srv->ssl_ctx.ctx);
1168
1169 if (!store || !X509_STORE_load_locations(store, srv->ssl_ctx.crl_file, NULL)) {
Willy Tarreau07ba08b2014-02-16 19:22:08 +01001170 Alert("Proxy '%s', server '%s' [%s:%d] unable to configure CRL file '%s'.\n",
Emeric Brunef42d922012-10-11 16:11:36 +02001171 curproxy->id, srv->id,
1172 srv->conf.file, srv->conf.line, srv->ssl_ctx.crl_file);
1173 cfgerr++;
1174 }
1175 else {
1176 X509_STORE_set_flags(store, X509_V_FLAG_CRL_CHECK|X509_V_FLAG_CRL_CHECK_ALL);
1177 }
1178 }
1179#endif
1180 }
1181
Emeric Brun4f65bff2012-11-16 15:11:00 +01001182 if (global.tune.ssllifetime)
1183 SSL_CTX_set_timeout(srv->ssl_ctx.ctx, global.tune.ssllifetime);
1184
Emeric Brun94324a42012-10-11 14:00:19 +02001185 SSL_CTX_set_session_cache_mode(srv->ssl_ctx.ctx, SSL_SESS_CACHE_OFF);
1186 if (srv->ssl_ctx.ciphers &&
1187 !SSL_CTX_set_cipher_list(srv->ssl_ctx.ctx, srv->ssl_ctx.ciphers)) {
1188 Alert("Proxy '%s', server '%s' [%s:%d] : unable to set SSL cipher list to '%s'.\n",
1189 curproxy->id, srv->id,
1190 srv->conf.file, srv->conf.line, srv->ssl_ctx.ciphers);
1191 cfgerr++;
1192 }
1193
1194 return cfgerr;
1195}
1196
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001197/* Walks down the two trees in bind_conf and prepares all certs. The pointer may
Emeric Brunfc0421f2012-09-07 17:30:07 +02001198 * be NULL, in which case nothing is done. Returns the number of errors
1199 * encountered.
1200 */
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001201int ssl_sock_prepare_all_ctx(struct bind_conf *bind_conf, struct proxy *px)
Emeric Brunfc0421f2012-09-07 17:30:07 +02001202{
1203 struct ebmb_node *node;
1204 struct sni_ctx *sni;
1205 int err = 0;
1206
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001207 if (!bind_conf || !bind_conf->is_ssl)
Emeric Brunfc0421f2012-09-07 17:30:07 +02001208 return 0;
1209
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001210 node = ebmb_first(&bind_conf->sni_ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001211 while (node) {
1212 sni = ebmb_entry(node, struct sni_ctx, name);
1213 if (!sni->order) /* only initialize the CTX on its first occurrence */
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001214 err += ssl_sock_prepare_ctx(bind_conf, sni->ctx, px);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001215 node = ebmb_next(node);
1216 }
1217
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001218 node = ebmb_first(&bind_conf->sni_w_ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001219 while (node) {
1220 sni = ebmb_entry(node, struct sni_ctx, name);
1221 if (!sni->order) /* only initialize the CTX on its first occurrence */
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001222 err += ssl_sock_prepare_ctx(bind_conf, sni->ctx, px);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001223 node = ebmb_next(node);
1224 }
1225 return err;
1226}
1227
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001228/* Walks down the two trees in bind_conf and frees all the certs. The pointer may
Emeric Brunfc0421f2012-09-07 17:30:07 +02001229 * be NULL, in which case nothing is done. The default_ctx is nullified too.
1230 */
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001231void ssl_sock_free_all_ctx(struct bind_conf *bind_conf)
Emeric Brunfc0421f2012-09-07 17:30:07 +02001232{
1233 struct ebmb_node *node, *back;
1234 struct sni_ctx *sni;
1235
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001236 if (!bind_conf || !bind_conf->is_ssl)
Emeric Brunfc0421f2012-09-07 17:30:07 +02001237 return;
1238
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001239 node = ebmb_first(&bind_conf->sni_ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001240 while (node) {
1241 sni = ebmb_entry(node, struct sni_ctx, name);
1242 back = ebmb_next(node);
1243 ebmb_delete(node);
1244 if (!sni->order) /* only free the CTX on its first occurrence */
1245 SSL_CTX_free(sni->ctx);
1246 free(sni);
1247 node = back;
1248 }
1249
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001250 node = ebmb_first(&bind_conf->sni_w_ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001251 while (node) {
1252 sni = ebmb_entry(node, struct sni_ctx, name);
1253 back = ebmb_next(node);
1254 ebmb_delete(node);
1255 if (!sni->order) /* only free the CTX on its first occurrence */
1256 SSL_CTX_free(sni->ctx);
1257 free(sni);
1258 node = back;
1259 }
1260
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001261 bind_conf->default_ctx = NULL;
Emeric Brune1f38db2012-09-03 20:36:47 +02001262}
1263
Emeric Brun46591952012-05-18 15:47:34 +02001264/*
1265 * This function is called if SSL * context is not yet allocated. The function
1266 * is designed to be called before any other data-layer operation and sets the
1267 * handshake flag on the connection. It is safe to call it multiple times.
1268 * It returns 0 on success and -1 in error case.
1269 */
1270static int ssl_sock_init(struct connection *conn)
1271{
1272 /* already initialized */
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02001273 if (conn->xprt_ctx)
Emeric Brun46591952012-05-18 15:47:34 +02001274 return 0;
1275
Willy Tarreau3c728722014-01-23 13:50:42 +01001276 if (!conn_ctrl_ready(conn))
Willy Tarreauf79c8172013-10-21 16:30:56 +02001277 return 0;
1278
Willy Tarreau20879a02012-12-03 16:32:10 +01001279 if (global.maxsslconn && sslconns >= global.maxsslconn) {
1280 conn->err_code = CO_ER_SSL_TOO_MANY;
Willy Tarreau403edff2012-09-06 11:58:37 +02001281 return -1;
Willy Tarreau20879a02012-12-03 16:32:10 +01001282 }
Willy Tarreau403edff2012-09-06 11:58:37 +02001283
Emeric Brun46591952012-05-18 15:47:34 +02001284 /* If it is in client mode initiate SSL session
1285 in connect state otherwise accept state */
Willy Tarreau3fdb3662012-11-12 00:42:33 +01001286 if (objt_server(conn->target)) {
Emeric Brun46591952012-05-18 15:47:34 +02001287 /* Alloc a new SSL session ctx */
Willy Tarreau3fdb3662012-11-12 00:42:33 +01001288 conn->xprt_ctx = SSL_new(objt_server(conn->target)->ssl_ctx.ctx);
Willy Tarreau20879a02012-12-03 16:32:10 +01001289 if (!conn->xprt_ctx) {
1290 conn->err_code = CO_ER_SSL_NO_MEM;
Emeric Brun46591952012-05-18 15:47:34 +02001291 return -1;
Willy Tarreau20879a02012-12-03 16:32:10 +01001292 }
Emeric Brun46591952012-05-18 15:47:34 +02001293
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02001294 SSL_set_connect_state(conn->xprt_ctx);
Willy Tarreau3fdb3662012-11-12 00:42:33 +01001295 if (objt_server(conn->target)->ssl_ctx.reused_sess)
1296 SSL_set_session(conn->xprt_ctx, objt_server(conn->target)->ssl_ctx.reused_sess);
Emeric Brun46591952012-05-18 15:47:34 +02001297
1298 /* set fd on SSL session context */
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02001299 SSL_set_fd(conn->xprt_ctx, conn->t.sock.fd);
Emeric Brun46591952012-05-18 15:47:34 +02001300
Evan Broderbe554312013-06-27 00:05:25 -07001301 /* set connection pointer */
1302 SSL_set_app_data(conn->xprt_ctx, conn);
1303
Emeric Brun46591952012-05-18 15:47:34 +02001304 /* leave init state and start handshake */
Willy Tarreau05737472012-09-04 08:03:39 +02001305 conn->flags |= CO_FL_SSL_WAIT_HS | CO_FL_WAIT_L6_CONN;
Willy Tarreau403edff2012-09-06 11:58:37 +02001306
1307 sslconns++;
Willy Tarreau71b734c2014-01-28 15:19:44 +01001308 totalsslconns++;
Emeric Brun46591952012-05-18 15:47:34 +02001309 return 0;
1310 }
Willy Tarreau3fdb3662012-11-12 00:42:33 +01001311 else if (objt_listener(conn->target)) {
Emeric Brun46591952012-05-18 15:47:34 +02001312 /* Alloc a new SSL session ctx */
Willy Tarreau3fdb3662012-11-12 00:42:33 +01001313 conn->xprt_ctx = SSL_new(objt_listener(conn->target)->bind_conf->default_ctx);
Willy Tarreau20879a02012-12-03 16:32:10 +01001314 if (!conn->xprt_ctx) {
1315 conn->err_code = CO_ER_SSL_NO_MEM;
Emeric Brun46591952012-05-18 15:47:34 +02001316 return -1;
Willy Tarreau20879a02012-12-03 16:32:10 +01001317 }
Emeric Brun46591952012-05-18 15:47:34 +02001318
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02001319 SSL_set_accept_state(conn->xprt_ctx);
Emeric Brun46591952012-05-18 15:47:34 +02001320
1321 /* set fd on SSL session context */
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02001322 SSL_set_fd(conn->xprt_ctx, conn->t.sock.fd);
Emeric Brun46591952012-05-18 15:47:34 +02001323
Emeric Brune1f38db2012-09-03 20:36:47 +02001324 /* set connection pointer */
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02001325 SSL_set_app_data(conn->xprt_ctx, conn);
Emeric Brune1f38db2012-09-03 20:36:47 +02001326
Emeric Brun46591952012-05-18 15:47:34 +02001327 /* leave init state and start handshake */
Willy Tarreau05737472012-09-04 08:03:39 +02001328 conn->flags |= CO_FL_SSL_WAIT_HS | CO_FL_WAIT_L6_CONN;
Willy Tarreau403edff2012-09-06 11:58:37 +02001329
1330 sslconns++;
Willy Tarreau71b734c2014-01-28 15:19:44 +01001331 totalsslconns++;
Emeric Brun46591952012-05-18 15:47:34 +02001332 return 0;
1333 }
1334 /* don't know how to handle such a target */
Willy Tarreau20879a02012-12-03 16:32:10 +01001335 conn->err_code = CO_ER_SSL_NO_TARGET;
Emeric Brun46591952012-05-18 15:47:34 +02001336 return -1;
1337}
1338
1339
1340/* This is the callback which is used when an SSL handshake is pending. It
1341 * updates the FD status if it wants some polling before being called again.
1342 * It returns 0 if it fails in a fatal way or needs to poll to go further,
1343 * otherwise it returns non-zero and removes itself from the connection's
1344 * flags (the bit is provided in <flag> by the caller).
1345 */
1346int ssl_sock_handshake(struct connection *conn, unsigned int flag)
1347{
1348 int ret;
1349
Willy Tarreau3c728722014-01-23 13:50:42 +01001350 if (!conn_ctrl_ready(conn))
Willy Tarreauf79c8172013-10-21 16:30:56 +02001351 return 0;
1352
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02001353 if (!conn->xprt_ctx)
Emeric Brun46591952012-05-18 15:47:34 +02001354 goto out_error;
1355
Emeric Brun674b7432012-11-08 19:21:55 +01001356 /* If we use SSL_do_handshake to process a reneg initiated by
1357 * the remote peer, it sometimes returns SSL_ERROR_SSL.
1358 * Usually SSL_write and SSL_read are used and process implicitly
1359 * the reneg handshake.
1360 * Here we use SSL_peek as a workaround for reneg.
1361 */
1362 if ((conn->flags & CO_FL_CONNECTED) && SSL_renegotiate_pending(conn->xprt_ctx)) {
1363 char c;
1364
1365 ret = SSL_peek(conn->xprt_ctx, &c, 1);
1366 if (ret <= 0) {
1367 /* handshake may have not been completed, let's find why */
1368 ret = SSL_get_error(conn->xprt_ctx, ret);
1369 if (ret == SSL_ERROR_WANT_WRITE) {
1370 /* SSL handshake needs to write, L4 connection may not be ready */
1371 __conn_sock_stop_recv(conn);
Willy Tarreaue1f50c42014-01-22 20:02:06 +01001372 __conn_sock_want_send(conn);
1373 fd_cant_send(conn->t.sock.fd);
Emeric Brun674b7432012-11-08 19:21:55 +01001374 return 0;
1375 }
1376 else if (ret == SSL_ERROR_WANT_READ) {
1377 /* handshake may have been completed but we have
1378 * no more data to read.
1379 */
1380 if (!SSL_renegotiate_pending(conn->xprt_ctx)) {
1381 ret = 1;
1382 goto reneg_ok;
1383 }
1384 /* SSL handshake needs to read, L4 connection is ready */
1385 if (conn->flags & CO_FL_WAIT_L4_CONN)
1386 conn->flags &= ~CO_FL_WAIT_L4_CONN;
1387 __conn_sock_stop_send(conn);
Willy Tarreaue1f50c42014-01-22 20:02:06 +01001388 __conn_sock_want_recv(conn);
1389 fd_cant_recv(conn->t.sock.fd);
Emeric Brun674b7432012-11-08 19:21:55 +01001390 return 0;
1391 }
1392 else if (ret == SSL_ERROR_SYSCALL) {
1393 /* if errno is null, then connection was successfully established */
1394 if (!errno && conn->flags & CO_FL_WAIT_L4_CONN)
1395 conn->flags &= ~CO_FL_WAIT_L4_CONN;
Willy Tarreau20879a02012-12-03 16:32:10 +01001396 if (!conn->err_code) {
1397 if (!((SSL *)conn->xprt_ctx)->packet_length)
1398 if (!errno)
1399 conn->err_code = CO_ER_SSL_EMPTY;
1400 else
1401 conn->err_code = CO_ER_SSL_ABORT;
1402 else
1403 conn->err_code = CO_ER_SSL_HANDSHAKE;
1404 }
Emeric Brun674b7432012-11-08 19:21:55 +01001405 goto out_error;
1406 }
1407 else {
1408 /* Fail on all other handshake errors */
1409 /* Note: OpenSSL may leave unread bytes in the socket's
1410 * buffer, causing an RST to be emitted upon close() on
1411 * TCP sockets. We first try to drain possibly pending
1412 * data to avoid this as much as possible.
1413 */
Willy Tarreau46be2e52014-01-20 12:10:52 +01001414 conn_drain(conn);
Willy Tarreau20879a02012-12-03 16:32:10 +01001415 if (!conn->err_code)
1416 conn->err_code = CO_ER_SSL_HANDSHAKE;
Emeric Brun674b7432012-11-08 19:21:55 +01001417 goto out_error;
1418 }
1419 }
1420 /* read some data: consider handshake completed */
1421 goto reneg_ok;
1422 }
1423
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02001424 ret = SSL_do_handshake(conn->xprt_ctx);
Emeric Brun46591952012-05-18 15:47:34 +02001425 if (ret != 1) {
1426 /* handshake did not complete, let's find why */
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02001427 ret = SSL_get_error(conn->xprt_ctx, ret);
Emeric Brun46591952012-05-18 15:47:34 +02001428
1429 if (ret == SSL_ERROR_WANT_WRITE) {
1430 /* SSL handshake needs to write, L4 connection may not be ready */
1431 __conn_sock_stop_recv(conn);
Willy Tarreaue1f50c42014-01-22 20:02:06 +01001432 __conn_sock_want_send(conn);
1433 fd_cant_send(conn->t.sock.fd);
Emeric Brun46591952012-05-18 15:47:34 +02001434 return 0;
1435 }
1436 else if (ret == SSL_ERROR_WANT_READ) {
1437 /* SSL handshake needs to read, L4 connection is ready */
1438 if (conn->flags & CO_FL_WAIT_L4_CONN)
1439 conn->flags &= ~CO_FL_WAIT_L4_CONN;
1440 __conn_sock_stop_send(conn);
Willy Tarreaue1f50c42014-01-22 20:02:06 +01001441 __conn_sock_want_recv(conn);
1442 fd_cant_recv(conn->t.sock.fd);
Emeric Brun46591952012-05-18 15:47:34 +02001443 return 0;
1444 }
Willy Tarreau89230192012-09-28 20:22:13 +02001445 else if (ret == SSL_ERROR_SYSCALL) {
1446 /* if errno is null, then connection was successfully established */
1447 if (!errno && conn->flags & CO_FL_WAIT_L4_CONN)
1448 conn->flags &= ~CO_FL_WAIT_L4_CONN;
Willy Tarreau20879a02012-12-03 16:32:10 +01001449
1450 if (!((SSL *)conn->xprt_ctx)->packet_length)
1451 if (!errno)
1452 conn->err_code = CO_ER_SSL_EMPTY;
1453 else
1454 conn->err_code = CO_ER_SSL_ABORT;
1455 else
1456 conn->err_code = CO_ER_SSL_HANDSHAKE;
Willy Tarreau89230192012-09-28 20:22:13 +02001457 goto out_error;
1458 }
Emeric Brun46591952012-05-18 15:47:34 +02001459 else {
1460 /* Fail on all other handshake errors */
Willy Tarreau566dc552012-10-19 20:52:18 +02001461 /* Note: OpenSSL may leave unread bytes in the socket's
1462 * buffer, causing an RST to be emitted upon close() on
1463 * TCP sockets. We first try to drain possibly pending
1464 * data to avoid this as much as possible.
1465 */
Willy Tarreau46be2e52014-01-20 12:10:52 +01001466 conn_drain(conn);
Willy Tarreau20879a02012-12-03 16:32:10 +01001467 if (!conn->err_code)
1468 conn->err_code = CO_ER_SSL_HANDSHAKE;
Emeric Brun46591952012-05-18 15:47:34 +02001469 goto out_error;
1470 }
1471 }
1472
Emeric Brun674b7432012-11-08 19:21:55 +01001473reneg_ok:
1474
Emeric Brun46591952012-05-18 15:47:34 +02001475 /* Handshake succeeded */
Willy Tarreau3fdb3662012-11-12 00:42:33 +01001476 if (objt_server(conn->target)) {
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02001477 if (!SSL_session_reused(conn->xprt_ctx)) {
Emeric Brun46591952012-05-18 15:47:34 +02001478 /* check if session was reused, if not store current session on server for reuse */
Willy Tarreau3fdb3662012-11-12 00:42:33 +01001479 if (objt_server(conn->target)->ssl_ctx.reused_sess)
1480 SSL_SESSION_free(objt_server(conn->target)->ssl_ctx.reused_sess);
Emeric Brun46591952012-05-18 15:47:34 +02001481
Willy Tarreau3fdb3662012-11-12 00:42:33 +01001482 objt_server(conn->target)->ssl_ctx.reused_sess = SSL_get1_session(conn->xprt_ctx);
Emeric Brun46591952012-05-18 15:47:34 +02001483 }
1484 }
1485
1486 /* The connection is now established at both layers, it's time to leave */
1487 conn->flags &= ~(flag | CO_FL_WAIT_L4_CONN | CO_FL_WAIT_L6_CONN);
1488 return 1;
1489
1490 out_error:
Emeric Brun644cde02012-12-14 11:21:13 +01001491 /* Clear openssl global errors stack */
1492 ERR_clear_error();
1493
Emeric Brun9fa89732012-10-04 17:09:56 +02001494 /* free resumed session if exists */
Willy Tarreau3fdb3662012-11-12 00:42:33 +01001495 if (objt_server(conn->target) && objt_server(conn->target)->ssl_ctx.reused_sess) {
1496 SSL_SESSION_free(objt_server(conn->target)->ssl_ctx.reused_sess);
1497 objt_server(conn->target)->ssl_ctx.reused_sess = NULL;
Emeric Brun9fa89732012-10-04 17:09:56 +02001498 }
1499
Emeric Brun46591952012-05-18 15:47:34 +02001500 /* Fail on all other handshake errors */
1501 conn->flags |= CO_FL_ERROR;
Willy Tarreau20879a02012-12-03 16:32:10 +01001502 if (!conn->err_code)
1503 conn->err_code = CO_ER_SSL_HANDSHAKE;
Emeric Brun46591952012-05-18 15:47:34 +02001504 return 0;
1505}
1506
1507/* Receive up to <count> bytes from connection <conn>'s socket and store them
Willy Tarreauabf08d92014-01-14 11:31:27 +01001508 * into buffer <buf>. Only one call to recv() is performed, unless the
Emeric Brun46591952012-05-18 15:47:34 +02001509 * buffer wraps, in which case a second call may be performed. The connection's
1510 * flags are updated with whatever special event is detected (error, read0,
1511 * empty). The caller is responsible for taking care of those events and
1512 * avoiding the call if inappropriate. The function does not call the
1513 * connection's polling update function, so the caller is responsible for this.
1514 */
1515static int ssl_sock_to_buf(struct connection *conn, struct buffer *buf, int count)
1516{
1517 int ret, done = 0;
Willy Tarreauabf08d92014-01-14 11:31:27 +01001518 int try;
Emeric Brun46591952012-05-18 15:47:34 +02001519
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02001520 if (!conn->xprt_ctx)
Emeric Brun46591952012-05-18 15:47:34 +02001521 goto out_error;
1522
1523 if (conn->flags & CO_FL_HANDSHAKE)
1524 /* a handshake was requested */
1525 return 0;
1526
Willy Tarreauabf08d92014-01-14 11:31:27 +01001527 /* let's realign the buffer to optimize I/O */
1528 if (buffer_empty(buf))
Emeric Brun46591952012-05-18 15:47:34 +02001529 buf->p = buf->data;
Emeric Brun46591952012-05-18 15:47:34 +02001530
1531 /* read the largest possible block. For this, we perform only one call
1532 * to recv() unless the buffer wraps and we exactly fill the first hunk,
1533 * in which case we accept to do it once again. A new attempt is made on
1534 * EINTR too.
1535 */
Willy Tarreau00b0fb92014-01-17 11:09:40 +01001536 while (count > 0) {
Willy Tarreauabf08d92014-01-14 11:31:27 +01001537 /* first check if we have some room after p+i */
1538 try = buf->data + buf->size - (buf->p + buf->i);
1539 /* otherwise continue between data and p-o */
1540 if (try <= 0) {
1541 try = buf->p - (buf->data + buf->o);
1542 if (try <= 0)
1543 break;
1544 }
1545 if (try > count)
1546 try = count;
1547
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02001548 ret = SSL_read(conn->xprt_ctx, bi_end(buf), try);
Emeric Brune1f38db2012-09-03 20:36:47 +02001549 if (conn->flags & CO_FL_ERROR) {
1550 /* CO_FL_ERROR may be set by ssl_sock_infocbk */
Emeric Brun644cde02012-12-14 11:21:13 +01001551 goto out_error;
Emeric Brune1f38db2012-09-03 20:36:47 +02001552 }
Emeric Brun46591952012-05-18 15:47:34 +02001553 if (ret > 0) {
1554 buf->i += ret;
1555 done += ret;
1556 if (ret < try)
1557 break;
1558 count -= ret;
Emeric Brun46591952012-05-18 15:47:34 +02001559 }
1560 else if (ret == 0) {
Emeric Brun644cde02012-12-14 11:21:13 +01001561 ret = SSL_get_error(conn->xprt_ctx, ret);
1562 if (ret != SSL_ERROR_ZERO_RETURN) {
Emeric Brun1c646862012-12-14 12:33:41 +01001563 /* error on protocol or underlying transport */
1564 if ((ret != SSL_ERROR_SYSCALL)
1565 || (errno && (errno != EAGAIN)))
1566 conn->flags |= CO_FL_ERROR;
1567
Emeric Brun644cde02012-12-14 11:21:13 +01001568 /* Clear openssl global errors stack */
1569 ERR_clear_error();
1570 }
Emeric Brun46591952012-05-18 15:47:34 +02001571 goto read0;
1572 }
1573 else {
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02001574 ret = SSL_get_error(conn->xprt_ctx, ret);
Emeric Brun46591952012-05-18 15:47:34 +02001575 if (ret == SSL_ERROR_WANT_WRITE) {
Emeric Brun8af8dd12012-11-08 17:56:20 +01001576 /* handshake is running, and it needs to enable write */
Emeric Brun46591952012-05-18 15:47:34 +02001577 conn->flags |= CO_FL_SSL_WAIT_HS;
Emeric Brun8af8dd12012-11-08 17:56:20 +01001578 __conn_sock_want_send(conn);
Emeric Brun46591952012-05-18 15:47:34 +02001579 break;
1580 }
1581 else if (ret == SSL_ERROR_WANT_READ) {
Emeric Brun282a76a2012-11-08 18:02:56 +01001582 if (SSL_renegotiate_pending(conn->xprt_ctx)) {
1583 /* handshake is running, and it may need to re-enable read */
1584 conn->flags |= CO_FL_SSL_WAIT_HS;
1585 __conn_sock_want_recv(conn);
1586 break;
1587 }
Emeric Brun46591952012-05-18 15:47:34 +02001588 /* we need to poll for retry a read later */
Willy Tarreaue1f50c42014-01-22 20:02:06 +01001589 fd_cant_recv(conn->t.sock.fd);
Emeric Brun46591952012-05-18 15:47:34 +02001590 break;
1591 }
1592 /* otherwise it's a real error */
1593 goto out_error;
1594 }
1595 }
1596 return done;
1597
1598 read0:
1599 conn_sock_read0(conn);
1600 return done;
1601 out_error:
Emeric Brun644cde02012-12-14 11:21:13 +01001602 /* Clear openssl global errors stack */
1603 ERR_clear_error();
1604
Emeric Brun46591952012-05-18 15:47:34 +02001605 conn->flags |= CO_FL_ERROR;
1606 return done;
1607}
1608
1609
1610/* Send all pending bytes from buffer <buf> to connection <conn>'s socket.
Willy Tarreau1049b1f2014-02-02 01:51:17 +01001611 * <flags> may contain some CO_SFL_* flags to hint the system about other
1612 * pending data for example, but this flag is ignored at the moment.
Emeric Brun46591952012-05-18 15:47:34 +02001613 * Only one call to send() is performed, unless the buffer wraps, in which case
1614 * a second call may be performed. The connection's flags are updated with
1615 * whatever special event is detected (error, empty). The caller is responsible
1616 * for taking care of those events and avoiding the call if inappropriate. The
1617 * function does not call the connection's polling update function, so the caller
1618 * is responsible for this.
1619 */
1620static int ssl_sock_from_buf(struct connection *conn, struct buffer *buf, int flags)
1621{
1622 int ret, try, done;
1623
1624 done = 0;
1625
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02001626 if (!conn->xprt_ctx)
Emeric Brun46591952012-05-18 15:47:34 +02001627 goto out_error;
1628
1629 if (conn->flags & CO_FL_HANDSHAKE)
1630 /* a handshake was requested */
1631 return 0;
1632
1633 /* send the largest possible block. For this we perform only one call
1634 * to send() unless the buffer wraps and we exactly fill the first hunk,
1635 * in which case we accept to do it once again.
1636 */
1637 while (buf->o) {
Kevin Hestercad82342013-05-30 15:12:41 -07001638 try = bo_contig_data(buf);
Willy Tarreaubfd59462013-02-21 07:46:09 +01001639
Willy Tarreau7bed9452014-02-02 02:00:24 +01001640 if (!(flags & CO_SFL_STREAMER) &&
Willy Tarreau518cedd2014-02-17 15:43:01 +01001641 !(conn->xprt_st & SSL_SOCK_SEND_UNLIMITED) &&
1642 global.tune.ssl_max_record && try > global.tune.ssl_max_record) {
Willy Tarreaubfd59462013-02-21 07:46:09 +01001643 try = global.tune.ssl_max_record;
Willy Tarreau518cedd2014-02-17 15:43:01 +01001644 }
1645 else {
1646 /* we need to keep the information about the fact that
1647 * we're not limiting the upcoming send(), because if it
1648 * fails, we'll have to retry with at least as many data.
1649 */
1650 conn->xprt_st |= SSL_SOCK_SEND_UNLIMITED;
1651 }
Willy Tarreaubfd59462013-02-21 07:46:09 +01001652
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02001653 ret = SSL_write(conn->xprt_ctx, bo_ptr(buf), try);
Willy Tarreau518cedd2014-02-17 15:43:01 +01001654
Emeric Brune1f38db2012-09-03 20:36:47 +02001655 if (conn->flags & CO_FL_ERROR) {
1656 /* CO_FL_ERROR may be set by ssl_sock_infocbk */
Emeric Brun644cde02012-12-14 11:21:13 +01001657 goto out_error;
Emeric Brune1f38db2012-09-03 20:36:47 +02001658 }
Emeric Brun46591952012-05-18 15:47:34 +02001659 if (ret > 0) {
Willy Tarreau518cedd2014-02-17 15:43:01 +01001660 conn->xprt_st &= ~SSL_SOCK_SEND_UNLIMITED;
1661
Emeric Brun46591952012-05-18 15:47:34 +02001662 buf->o -= ret;
1663 done += ret;
1664
Willy Tarreau5fb38032012-12-16 19:39:09 +01001665 if (likely(buffer_empty(buf)))
Emeric Brun46591952012-05-18 15:47:34 +02001666 /* optimize data alignment in the buffer */
1667 buf->p = buf->data;
1668
1669 /* if the system buffer is full, don't insist */
1670 if (ret < try)
1671 break;
1672 }
1673 else {
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02001674 ret = SSL_get_error(conn->xprt_ctx, ret);
Emeric Brun46591952012-05-18 15:47:34 +02001675 if (ret == SSL_ERROR_WANT_WRITE) {
Emeric Brun282a76a2012-11-08 18:02:56 +01001676 if (SSL_renegotiate_pending(conn->xprt_ctx)) {
1677 /* handshake is running, and it may need to re-enable write */
1678 conn->flags |= CO_FL_SSL_WAIT_HS;
1679 __conn_sock_want_send(conn);
1680 break;
1681 }
Emeric Brun46591952012-05-18 15:47:34 +02001682 /* we need to poll to retry a write later */
Willy Tarreaue1f50c42014-01-22 20:02:06 +01001683 fd_cant_send(conn->t.sock.fd);
Emeric Brun46591952012-05-18 15:47:34 +02001684 break;
1685 }
1686 else if (ret == SSL_ERROR_WANT_READ) {
Emeric Brun8af8dd12012-11-08 17:56:20 +01001687 /* handshake is running, and it needs to enable read */
Emeric Brun46591952012-05-18 15:47:34 +02001688 conn->flags |= CO_FL_SSL_WAIT_HS;
Emeric Brun8af8dd12012-11-08 17:56:20 +01001689 __conn_sock_want_recv(conn);
Emeric Brun46591952012-05-18 15:47:34 +02001690 break;
1691 }
1692 goto out_error;
1693 }
1694 }
1695 return done;
1696
1697 out_error:
Emeric Brun644cde02012-12-14 11:21:13 +01001698 /* Clear openssl global errors stack */
1699 ERR_clear_error();
1700
Emeric Brun46591952012-05-18 15:47:34 +02001701 conn->flags |= CO_FL_ERROR;
1702 return done;
1703}
1704
Emeric Brun46591952012-05-18 15:47:34 +02001705static void ssl_sock_close(struct connection *conn) {
1706
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02001707 if (conn->xprt_ctx) {
1708 SSL_free(conn->xprt_ctx);
1709 conn->xprt_ctx = NULL;
Willy Tarreau403edff2012-09-06 11:58:37 +02001710 sslconns--;
Emeric Brun46591952012-05-18 15:47:34 +02001711 }
Emeric Brun46591952012-05-18 15:47:34 +02001712}
1713
1714/* This function tries to perform a clean shutdown on an SSL connection, and in
1715 * any case, flags the connection as reusable if no handshake was in progress.
1716 */
1717static void ssl_sock_shutw(struct connection *conn, int clean)
1718{
1719 if (conn->flags & CO_FL_HANDSHAKE)
1720 return;
1721 /* no handshake was in progress, try a clean ssl shutdown */
Emeric Brun644cde02012-12-14 11:21:13 +01001722 if (clean && (SSL_shutdown(conn->xprt_ctx) <= 0)) {
1723 /* Clear openssl global errors stack */
1724 ERR_clear_error();
1725 }
Emeric Brun46591952012-05-18 15:47:34 +02001726
1727 /* force flag on ssl to keep session in cache regardless shutdown result */
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02001728 SSL_set_shutdown(conn->xprt_ctx, SSL_SENT_SHUTDOWN);
Emeric Brun46591952012-05-18 15:47:34 +02001729}
1730
Willy Tarreauffc3fcd2012-10-12 20:17:54 +02001731/* used for logging, may be changed for a sample fetch later */
1732const char *ssl_sock_get_cipher_name(struct connection *conn)
1733{
1734 if (!conn->xprt && !conn->xprt_ctx)
1735 return NULL;
1736 return SSL_get_cipher_name(conn->xprt_ctx);
1737}
1738
1739/* used for logging, may be changed for a sample fetch later */
1740const char *ssl_sock_get_proto_version(struct connection *conn)
1741{
1742 if (!conn->xprt && !conn->xprt_ctx)
1743 return NULL;
1744 return SSL_get_version(conn->xprt_ctx);
1745}
1746
Willy Tarreau8d598402012-10-22 17:58:39 +02001747/* Extract a serial from a cert, and copy it to a chunk.
1748 * Returns 1 if serial is found and copied, 0 if no serial found and
1749 * -1 if output is not large enough.
1750 */
1751static int
1752ssl_sock_get_serial(X509 *crt, struct chunk *out)
1753{
1754 ASN1_INTEGER *serial;
1755
1756 serial = X509_get_serialNumber(crt);
1757 if (!serial)
1758 return 0;
1759
1760 if (out->size < serial->length)
1761 return -1;
1762
1763 memcpy(out->str, serial->data, serial->length);
1764 out->len = serial->length;
1765 return 1;
1766}
1767
Emeric Brunce5ad802012-10-22 14:11:22 +02001768
1769/* Copy Date in ASN1_UTCTIME format in struct chunk out.
1770 * Returns 1 if serial is found and copied, 0 if no valid time found
1771 * and -1 if output is not large enough.
1772 */
1773static int
1774ssl_sock_get_time(ASN1_TIME *tm, struct chunk *out)
1775{
1776 if (tm->type == V_ASN1_GENERALIZEDTIME) {
1777 ASN1_GENERALIZEDTIME *gentm = (ASN1_GENERALIZEDTIME *)tm;
1778
1779 if (gentm->length < 12)
1780 return 0;
1781 if (gentm->data[0] != 0x32 || gentm->data[1] != 0x30)
1782 return 0;
1783 if (out->size < gentm->length-2)
1784 return -1;
1785
1786 memcpy(out->str, gentm->data+2, gentm->length-2);
1787 out->len = gentm->length-2;
1788 return 1;
1789 }
1790 else if (tm->type == V_ASN1_UTCTIME) {
1791 ASN1_UTCTIME *utctm = (ASN1_UTCTIME *)tm;
1792
1793 if (utctm->length < 10)
1794 return 0;
1795 if (utctm->data[0] >= 0x35)
1796 return 0;
1797 if (out->size < utctm->length)
1798 return -1;
1799
1800 memcpy(out->str, utctm->data, utctm->length);
1801 out->len = utctm->length;
1802 return 1;
1803 }
1804
1805 return 0;
1806}
1807
Emeric Brun87855892012-10-17 17:39:35 +02001808/* Extract an entry from a X509_NAME and copy its value to an output chunk.
1809 * Returns 1 if entry found, 0 if entry not found, or -1 if output not large enough.
1810 */
1811static int
1812ssl_sock_get_dn_entry(X509_NAME *a, const struct chunk *entry, int pos, struct chunk *out)
1813{
1814 X509_NAME_ENTRY *ne;
1815 int i, j, n;
1816 int cur = 0;
1817 const char *s;
1818 char tmp[128];
1819
1820 out->len = 0;
1821 for (i = 0; i < sk_X509_NAME_ENTRY_num(a->entries); i++) {
1822 if (pos < 0)
1823 j = (sk_X509_NAME_ENTRY_num(a->entries)-1) - i;
1824 else
1825 j = i;
1826
1827 ne = sk_X509_NAME_ENTRY_value(a->entries, j);
1828 n = OBJ_obj2nid(ne->object);
1829 if ((n == NID_undef) || ((s = OBJ_nid2sn(n)) == NULL)) {
1830 i2t_ASN1_OBJECT(tmp, sizeof(tmp), ne->object);
1831 s = tmp;
1832 }
1833
1834 if (chunk_strcasecmp(entry, s) != 0)
1835 continue;
1836
1837 if (pos < 0)
1838 cur--;
1839 else
1840 cur++;
1841
1842 if (cur != pos)
1843 continue;
1844
1845 if (ne->value->length > out->size)
1846 return -1;
1847
1848 memcpy(out->str, ne->value->data, ne->value->length);
1849 out->len = ne->value->length;
1850 return 1;
1851 }
1852
1853 return 0;
1854
1855}
1856
1857/* Extract and format full DN from a X509_NAME and copy result into a chunk
1858 * Returns 1 if dn entries exits, 0 if no dn entry found or -1 if output is not large enough.
1859 */
1860static int
1861ssl_sock_get_dn_oneline(X509_NAME *a, struct chunk *out)
1862{
1863 X509_NAME_ENTRY *ne;
1864 int i, n, ln;
1865 int l = 0;
1866 const char *s;
1867 char *p;
1868 char tmp[128];
1869
1870 out->len = 0;
1871 p = out->str;
1872 for (i = 0; i < sk_X509_NAME_ENTRY_num(a->entries); i++) {
1873 ne = sk_X509_NAME_ENTRY_value(a->entries, i);
1874 n = OBJ_obj2nid(ne->object);
1875 if ((n == NID_undef) || ((s = OBJ_nid2sn(n)) == NULL)) {
1876 i2t_ASN1_OBJECT(tmp, sizeof(tmp), ne->object);
1877 s = tmp;
1878 }
1879 ln = strlen(s);
1880
1881 l += 1 + ln + 1 + ne->value->length;
1882 if (l > out->size)
1883 return -1;
1884 out->len = l;
1885
1886 *(p++)='/';
1887 memcpy(p, s, ln);
1888 p += ln;
1889 *(p++)='=';
1890 memcpy(p, ne->value->data, ne->value->length);
1891 p += ne->value->length;
1892 }
1893
1894 if (!out->len)
1895 return 0;
1896
1897 return 1;
1898}
1899
Willy Tarreau7875d092012-09-10 08:20:03 +02001900/***** Below are some sample fetching functions for ACL/patterns *****/
1901
Emeric Brune64aef12012-09-21 13:15:06 +02001902/* boolean, returns true if client cert was present */
1903static int
Emeric Brun2525b6b2012-10-18 15:59:43 +02001904smp_fetch_ssl_fc_has_crt(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02001905 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brune64aef12012-09-21 13:15:06 +02001906{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02001907 struct connection *conn;
1908
1909 if (!l4)
1910 return 0;
1911
1912 conn = objt_conn(l4->si[0].end);
1913 if (!conn || conn->xprt != &ssl_sock)
Emeric Brune64aef12012-09-21 13:15:06 +02001914 return 0;
1915
Willy Tarreaub363a1f2013-10-01 10:45:07 +02001916 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brune64aef12012-09-21 13:15:06 +02001917 smp->flags |= SMP_F_MAY_CHANGE;
1918 return 0;
1919 }
1920
1921 smp->flags = 0;
1922 smp->type = SMP_T_BOOL;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02001923 smp->data.uint = SSL_SOCK_ST_FL_VERIFY_DONE & conn->xprt_st ? 1 : 0;
Emeric Brune64aef12012-09-21 13:15:06 +02001924
1925 return 1;
1926}
1927
Willy Tarreau8d598402012-10-22 17:58:39 +02001928/* bin, returns serial in a binary chunk */
1929static int
1930smp_fetch_ssl_c_serial(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02001931 const struct arg *args, struct sample *smp, const char *kw)
Willy Tarreau8d598402012-10-22 17:58:39 +02001932{
1933 X509 *crt = NULL;
1934 int ret = 0;
1935 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02001936 struct connection *conn;
1937
1938 if (!l4)
1939 return 0;
Willy Tarreau8d598402012-10-22 17:58:39 +02001940
Willy Tarreaub363a1f2013-10-01 10:45:07 +02001941 conn = objt_conn(l4->si[0].end);
1942 if (!conn || conn->xprt != &ssl_sock)
Willy Tarreau8d598402012-10-22 17:58:39 +02001943 return 0;
1944
Willy Tarreaub363a1f2013-10-01 10:45:07 +02001945 if (!(conn->flags & CO_FL_CONNECTED)) {
Willy Tarreau8d598402012-10-22 17:58:39 +02001946 smp->flags |= SMP_F_MAY_CHANGE;
1947 return 0;
1948 }
1949
1950 /* SSL_get_peer_certificate, it increase X509 * ref count */
Willy Tarreaub363a1f2013-10-01 10:45:07 +02001951 crt = SSL_get_peer_certificate(conn->xprt_ctx);
Willy Tarreau8d598402012-10-22 17:58:39 +02001952 if (!crt)
1953 goto out;
1954
Willy Tarreau47ca5452012-12-23 20:22:19 +01001955 smp_trash = get_trash_chunk();
Willy Tarreau8d598402012-10-22 17:58:39 +02001956 if (ssl_sock_get_serial(crt, smp_trash) <= 0)
1957 goto out;
1958
1959 smp->data.str = *smp_trash;
1960 smp->type = SMP_T_BIN;
1961 ret = 1;
1962out:
1963 if (crt)
1964 X509_free(crt);
1965 return ret;
1966}
Emeric Brune64aef12012-09-21 13:15:06 +02001967
James Votha051b4a2013-05-14 20:37:59 +02001968/* bin, returns the client certificate's SHA-1 fingerprint (SHA-1 hash of DER-encoded certificate) in a binary chunk */
1969static int
1970smp_fetch_ssl_c_sha1(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02001971 const struct arg *args, struct sample *smp, const char *kw)
James Votha051b4a2013-05-14 20:37:59 +02001972{
1973 X509 *crt = NULL;
1974 const EVP_MD *digest;
1975 int ret = 0;
1976 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02001977 struct connection *conn;
James Votha051b4a2013-05-14 20:37:59 +02001978
Willy Tarreaub363a1f2013-10-01 10:45:07 +02001979 if (!l4)
James Votha051b4a2013-05-14 20:37:59 +02001980 return 0;
1981
Willy Tarreaub363a1f2013-10-01 10:45:07 +02001982 conn = objt_conn(l4->si[0].end);
1983 if (!conn || conn->xprt != &ssl_sock)
1984 return 0;
1985
1986 if (!(conn->flags & CO_FL_CONNECTED)) {
James Votha051b4a2013-05-14 20:37:59 +02001987 smp->flags |= SMP_F_MAY_CHANGE;
1988 return 0;
1989 }
1990
1991 /* SSL_get_peer_certificate, it increase X509 * ref count */
Willy Tarreaub363a1f2013-10-01 10:45:07 +02001992 crt = SSL_get_peer_certificate(conn->xprt_ctx);
James Votha051b4a2013-05-14 20:37:59 +02001993 if (!crt)
1994 goto out;
1995
1996 smp_trash = get_trash_chunk();
1997 digest = EVP_sha1();
1998 X509_digest(crt, digest, (unsigned char *)smp_trash->str, (unsigned int *)&smp_trash->len);
1999
2000 smp->data.str = *smp_trash;
2001 smp->type = SMP_T_BIN;
2002 ret = 1;
2003out:
2004 if (crt)
2005 X509_free(crt);
2006 return ret;
2007}
2008
Emeric Brunce5ad802012-10-22 14:11:22 +02002009/*str, returns notafter date in ASN1_UTCTIME format */
2010static int
2011smp_fetch_ssl_c_notafter(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002012 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brunce5ad802012-10-22 14:11:22 +02002013{
2014 X509 *crt = NULL;
2015 int ret = 0;
2016 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002017 struct connection *conn;
Emeric Brunce5ad802012-10-22 14:11:22 +02002018
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002019 if (!l4)
Emeric Brunce5ad802012-10-22 14:11:22 +02002020 return 0;
2021
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002022 conn = objt_conn(l4->si[0].end);
2023 if (!conn || conn->xprt != &ssl_sock)
2024 return 0;
2025
2026 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunce5ad802012-10-22 14:11:22 +02002027 smp->flags |= SMP_F_MAY_CHANGE;
2028 return 0;
2029 }
2030
2031 /* SSL_get_peer_certificate, it increase X509 * ref count */
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002032 crt = SSL_get_peer_certificate(conn->xprt_ctx);
Emeric Brunce5ad802012-10-22 14:11:22 +02002033 if (!crt)
2034 goto out;
2035
Willy Tarreau47ca5452012-12-23 20:22:19 +01002036 smp_trash = get_trash_chunk();
Emeric Brunce5ad802012-10-22 14:11:22 +02002037 if (ssl_sock_get_time(X509_get_notAfter(crt), smp_trash) <= 0)
2038 goto out;
2039
2040 smp->data.str = *smp_trash;
2041 smp->type = SMP_T_STR;
2042 ret = 1;
2043out:
2044 if (crt)
2045 X509_free(crt);
2046 return ret;
2047}
2048
Emeric Brun87855892012-10-17 17:39:35 +02002049/* str, returns a string of a formatted full dn \C=..\O=..\OU=.. \CN=.. */
2050static int
2051smp_fetch_ssl_c_i_dn(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002052 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brun87855892012-10-17 17:39:35 +02002053{
2054 X509 *crt = NULL;
2055 X509_NAME *name;
2056 int ret = 0;
2057 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002058 struct connection *conn;
Emeric Brun87855892012-10-17 17:39:35 +02002059
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002060 if (!l4)
Emeric Brun87855892012-10-17 17:39:35 +02002061 return 0;
2062
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002063 conn = objt_conn(l4->si[0].end);
2064 if (!conn || conn->xprt != &ssl_sock)
2065 return 0;
2066
2067 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun87855892012-10-17 17:39:35 +02002068 smp->flags |= SMP_F_MAY_CHANGE;
2069 return 0;
2070 }
2071
2072 /* SSL_get_peer_certificate, it increase X509 * ref count */
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002073 crt = SSL_get_peer_certificate(conn->xprt_ctx);
Emeric Brun87855892012-10-17 17:39:35 +02002074 if (!crt)
2075 goto out;
2076
2077 name = X509_get_issuer_name(crt);
2078 if (!name)
2079 goto out;
2080
Willy Tarreau47ca5452012-12-23 20:22:19 +01002081 smp_trash = get_trash_chunk();
Emeric Brun87855892012-10-17 17:39:35 +02002082 if (args && args[0].type == ARGT_STR) {
2083 int pos = 1;
2084
2085 if (args[1].type == ARGT_SINT)
2086 pos = args[1].data.sint;
2087 else if (args[1].type == ARGT_UINT)
2088 pos =(int)args[1].data.uint;
2089
2090 if (ssl_sock_get_dn_entry(name, &args[0].data.str, pos, smp_trash) <= 0)
2091 goto out;
2092 }
2093 else if (ssl_sock_get_dn_oneline(name, smp_trash) <= 0)
2094 goto out;
2095
2096 smp->type = SMP_T_STR;
2097 smp->data.str = *smp_trash;
2098 ret = 1;
2099out:
2100 if (crt)
2101 X509_free(crt);
2102 return ret;
2103}
2104
Emeric Brunce5ad802012-10-22 14:11:22 +02002105/*str, returns notbefore date in ASN1_UTCTIME format */
2106static int
2107smp_fetch_ssl_c_notbefore(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002108 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brunce5ad802012-10-22 14:11:22 +02002109{
2110 X509 *crt = NULL;
2111 int ret = 0;
2112 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002113 struct connection *conn;
2114
2115 if (!l4)
2116 return 0;
Emeric Brunce5ad802012-10-22 14:11:22 +02002117
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002118 conn = objt_conn(l4->si[0].end);
2119 if (!conn || conn->xprt != &ssl_sock)
Emeric Brunce5ad802012-10-22 14:11:22 +02002120 return 0;
2121
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002122 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunce5ad802012-10-22 14:11:22 +02002123 smp->flags |= SMP_F_MAY_CHANGE;
2124 return 0;
2125 }
2126
2127 /* SSL_get_peer_certificate, it increase X509 * ref count */
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002128 crt = SSL_get_peer_certificate(conn->xprt_ctx);
Emeric Brunce5ad802012-10-22 14:11:22 +02002129 if (!crt)
2130 goto out;
2131
Willy Tarreau47ca5452012-12-23 20:22:19 +01002132 smp_trash = get_trash_chunk();
Emeric Brunce5ad802012-10-22 14:11:22 +02002133 if (ssl_sock_get_time(X509_get_notBefore(crt), smp_trash) <= 0)
2134 goto out;
2135
2136 smp->data.str = *smp_trash;
2137 smp->type = SMP_T_STR;
2138 ret = 1;
2139out:
2140 if (crt)
2141 X509_free(crt);
2142 return ret;
2143}
2144
Emeric Brun87855892012-10-17 17:39:35 +02002145/* str, returns a string of a formatted full dn \C=..\O=..\OU=.. \CN=.. */
2146static int
2147smp_fetch_ssl_c_s_dn(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002148 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brun87855892012-10-17 17:39:35 +02002149{
2150 X509 *crt = NULL;
2151 X509_NAME *name;
2152 int ret = 0;
2153 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002154 struct connection *conn;
Emeric Brun87855892012-10-17 17:39:35 +02002155
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002156 if (!l4)
Emeric Brun87855892012-10-17 17:39:35 +02002157 return 0;
2158
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002159 conn = objt_conn(l4->si[0].end);
2160 if (!conn || conn->xprt != &ssl_sock)
2161 return 0;
2162
2163 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun87855892012-10-17 17:39:35 +02002164 smp->flags |= SMP_F_MAY_CHANGE;
2165 return 0;
2166 }
2167
2168 /* SSL_get_peer_certificate, it increase X509 * ref count */
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002169 crt = SSL_get_peer_certificate(conn->xprt_ctx);
Emeric Brun87855892012-10-17 17:39:35 +02002170 if (!crt)
2171 goto out;
2172
2173 name = X509_get_subject_name(crt);
2174 if (!name)
2175 goto out;
2176
Willy Tarreau47ca5452012-12-23 20:22:19 +01002177 smp_trash = get_trash_chunk();
Emeric Brun87855892012-10-17 17:39:35 +02002178 if (args && args[0].type == ARGT_STR) {
2179 int pos = 1;
2180
2181 if (args[1].type == ARGT_SINT)
2182 pos = args[1].data.sint;
2183 else if (args[1].type == ARGT_UINT)
2184 pos =(int)args[1].data.uint;
2185
2186 if (ssl_sock_get_dn_entry(name, &args[0].data.str, pos, smp_trash) <= 0)
2187 goto out;
2188 }
2189 else if (ssl_sock_get_dn_oneline(name, smp_trash) <= 0)
2190 goto out;
2191
2192 smp->type = SMP_T_STR;
2193 smp->data.str = *smp_trash;
2194 ret = 1;
2195out:
2196 if (crt)
2197 X509_free(crt);
2198 return ret;
2199}
Emeric Brun9143d372012-12-20 15:44:16 +01002200
2201/* integer, returns true if current session use a client certificate */
2202static int
2203smp_fetch_ssl_c_used(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002204 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brun9143d372012-12-20 15:44:16 +01002205{
2206 X509 *crt;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002207 struct connection *conn;
Emeric Brun9143d372012-12-20 15:44:16 +01002208
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002209 if (!l4)
Emeric Brun9143d372012-12-20 15:44:16 +01002210 return 0;
2211
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002212 conn = objt_conn(l4->si[0].end);
2213 if (!conn || conn->xprt != &ssl_sock)
2214 return 0;
2215
2216 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun9143d372012-12-20 15:44:16 +01002217 smp->flags |= SMP_F_MAY_CHANGE;
2218 return 0;
2219 }
2220
2221 /* SSL_get_peer_certificate returns a ptr on allocated X509 struct */
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002222 crt = SSL_get_peer_certificate(conn->xprt_ctx);
Emeric Brun9143d372012-12-20 15:44:16 +01002223 if (crt) {
2224 X509_free(crt);
2225 }
2226
2227 smp->type = SMP_T_BOOL;
2228 smp->data.uint = (crt != NULL);
2229 return 1;
2230}
2231
Emeric Bruna7359fd2012-10-17 15:03:11 +02002232/* integer, returns the client certificate version */
2233static int
2234smp_fetch_ssl_c_version(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002235 const struct arg *args, struct sample *smp, const char *kw)
Emeric Bruna7359fd2012-10-17 15:03:11 +02002236{
2237 X509 *crt;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002238 struct connection *conn;
2239
2240 if (!l4)
2241 return 0;
Emeric Bruna7359fd2012-10-17 15:03:11 +02002242
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002243 conn = objt_conn(l4->si[0].end);
2244 if (!conn || conn->xprt != &ssl_sock)
Emeric Bruna7359fd2012-10-17 15:03:11 +02002245 return 0;
2246
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002247 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Bruna7359fd2012-10-17 15:03:11 +02002248 smp->flags |= SMP_F_MAY_CHANGE;
2249 return 0;
2250 }
2251
2252 /* SSL_get_peer_certificate returns a ptr on allocated X509 struct */
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002253 crt = SSL_get_peer_certificate(conn->xprt_ctx);
Emeric Bruna7359fd2012-10-17 15:03:11 +02002254 if (!crt)
2255 return 0;
2256
2257 smp->data.uint = (unsigned int)(1 + X509_get_version(crt));
2258 X509_free(crt);
2259 smp->type = SMP_T_UINT;
2260
2261 return 1;
2262}
2263
Emeric Brun7f56e742012-10-19 18:15:40 +02002264/* str, returns the client certificate sig alg */
2265static int
2266smp_fetch_ssl_c_sig_alg(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002267 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brun7f56e742012-10-19 18:15:40 +02002268{
2269 X509 *crt;
2270 int nid;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002271 struct connection *conn;
Emeric Brun7f56e742012-10-19 18:15:40 +02002272
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002273 if (!l4)
Emeric Brun7f56e742012-10-19 18:15:40 +02002274 return 0;
2275
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002276 conn = objt_conn(l4->si[0].end);
2277 if (!conn || conn->xprt != &ssl_sock)
2278 return 0;
2279
2280 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun7f56e742012-10-19 18:15:40 +02002281 smp->flags |= SMP_F_MAY_CHANGE;
2282 return 0;
2283 }
2284
2285 /* SSL_get_peer_certificate increase X509 * ref count */
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002286 crt = SSL_get_peer_certificate(conn->xprt_ctx);
Emeric Brun7f56e742012-10-19 18:15:40 +02002287 if (!crt)
2288 return 0;
2289
2290 nid = OBJ_obj2nid((ASN1_OBJECT *)(crt->cert_info->signature->algorithm));
2291
2292 smp->data.str.str = (char *)OBJ_nid2sn(nid);
Emeric Brun9bf3ba22013-10-07 14:31:44 +02002293 if (!smp->data.str.str) {
2294 X509_free(crt);
Emeric Brun7f56e742012-10-19 18:15:40 +02002295 return 0;
Emeric Brun9bf3ba22013-10-07 14:31:44 +02002296 }
Emeric Brun7f56e742012-10-19 18:15:40 +02002297
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01002298 smp->type = SMP_T_STR;
2299 smp->flags |= SMP_F_CONST;
Emeric Brun7f56e742012-10-19 18:15:40 +02002300 smp->data.str.len = strlen(smp->data.str.str);
2301 X509_free(crt);
2302
2303 return 1;
2304}
2305
Emeric Brun521a0112012-10-22 12:22:55 +02002306/* str, returns the client certificate key alg */
2307static int
2308smp_fetch_ssl_c_key_alg(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002309 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brun521a0112012-10-22 12:22:55 +02002310{
2311 X509 *crt;
2312 int nid;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002313 struct connection *conn;
Emeric Brun521a0112012-10-22 12:22:55 +02002314
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002315 if (!l4)
Emeric Brun521a0112012-10-22 12:22:55 +02002316 return 0;
2317
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002318 conn = objt_conn(l4->si[0].end);
2319 if (!conn || conn->xprt != &ssl_sock)
2320 return 0;
2321
2322 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun521a0112012-10-22 12:22:55 +02002323 smp->flags |= SMP_F_MAY_CHANGE;
2324 return 0;
2325 }
2326
2327 /* SSL_get_peer_certificate increase X509 * ref count */
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002328 crt = SSL_get_peer_certificate(conn->xprt_ctx);
Emeric Brun521a0112012-10-22 12:22:55 +02002329 if (!crt)
2330 return 0;
2331
2332 nid = OBJ_obj2nid((ASN1_OBJECT *)(crt->cert_info->key->algor->algorithm));
2333
2334 smp->data.str.str = (char *)OBJ_nid2sn(nid);
Emeric Brun9bf3ba22013-10-07 14:31:44 +02002335 if (!smp->data.str.str) {
2336 X509_free(crt);
Emeric Brun521a0112012-10-22 12:22:55 +02002337 return 0;
Emeric Brun9bf3ba22013-10-07 14:31:44 +02002338 }
Emeric Brun521a0112012-10-22 12:22:55 +02002339
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01002340 smp->type = SMP_T_STR;
2341 smp->flags |= SMP_F_CONST;
Emeric Brun521a0112012-10-22 12:22:55 +02002342 smp->data.str.len = strlen(smp->data.str.str);
2343 X509_free(crt);
2344
2345 return 1;
2346}
2347
Emeric Brun2525b6b2012-10-18 15:59:43 +02002348/* boolean, returns true if front conn. transport layer is SSL */
Willy Tarreau7875d092012-09-10 08:20:03 +02002349static int
Emeric Brun2525b6b2012-10-18 15:59:43 +02002350smp_fetch_ssl_fc(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002351 const struct arg *args, struct sample *smp, const char *kw)
Willy Tarreau7875d092012-09-10 08:20:03 +02002352{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002353 struct connection *conn = objt_conn(l4->si[0].end);
2354
Willy Tarreau7875d092012-09-10 08:20:03 +02002355 smp->type = SMP_T_BOOL;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002356 smp->data.uint = (conn && conn->xprt == &ssl_sock);
Willy Tarreau7875d092012-09-10 08:20:03 +02002357 return 1;
2358}
2359
Emeric Brun2525b6b2012-10-18 15:59:43 +02002360/* boolean, returns true if client present a SNI */
Willy Tarreau7875d092012-09-10 08:20:03 +02002361static int
Emeric Brun2525b6b2012-10-18 15:59:43 +02002362smp_fetch_ssl_fc_has_sni(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002363 const struct arg *args, struct sample *smp, const char *kw)
Willy Tarreau7875d092012-09-10 08:20:03 +02002364{
2365#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002366 struct connection *conn = objt_conn(l4->si[0].end);
2367
Willy Tarreau7875d092012-09-10 08:20:03 +02002368 smp->type = SMP_T_BOOL;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002369 smp->data.uint = (conn && conn->xprt == &ssl_sock) &&
2370 conn->xprt_ctx &&
2371 SSL_get_servername(conn->xprt_ctx, TLSEXT_NAMETYPE_host_name) != NULL;
Willy Tarreau7875d092012-09-10 08:20:03 +02002372 return 1;
2373#else
2374 return 0;
2375#endif
2376}
2377
Willy Tarreau8d598402012-10-22 17:58:39 +02002378/* bin, returns serial in a binary chunk */
2379static int
2380smp_fetch_ssl_f_serial(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002381 const struct arg *args, struct sample *smp, const char *kw)
Willy Tarreau8d598402012-10-22 17:58:39 +02002382{
2383 X509 *crt = NULL;
2384 int ret = 0;
2385 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002386 struct connection *conn;
2387
2388 if (!l4)
2389 return 0;
Willy Tarreau8d598402012-10-22 17:58:39 +02002390
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002391 conn = objt_conn(l4->si[0].end);
2392 if (!conn || conn->xprt != &ssl_sock)
Willy Tarreau8d598402012-10-22 17:58:39 +02002393 return 0;
2394
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002395 if (!(conn->flags & CO_FL_CONNECTED)) {
Willy Tarreau8d598402012-10-22 17:58:39 +02002396 smp->flags |= SMP_F_MAY_CHANGE;
2397 return 0;
2398 }
2399
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002400 crt = SSL_get_certificate(conn->xprt_ctx);
Willy Tarreau8d598402012-10-22 17:58:39 +02002401 if (!crt)
2402 goto out;
2403
Willy Tarreau47ca5452012-12-23 20:22:19 +01002404 smp_trash = get_trash_chunk();
Willy Tarreau8d598402012-10-22 17:58:39 +02002405 if (ssl_sock_get_serial(crt, smp_trash) <= 0)
2406 goto out;
2407
2408 smp->data.str = *smp_trash;
2409 smp->type = SMP_T_BIN;
2410 ret = 1;
2411out:
2412 return ret;
2413}
Emeric Brunce5ad802012-10-22 14:11:22 +02002414/*str, returns notafter date in ASN1_UTCTIME format */
2415static int
2416smp_fetch_ssl_f_notafter(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002417 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brunce5ad802012-10-22 14:11:22 +02002418{
2419 X509 *crt = NULL;
2420 int ret = 0;
2421 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002422 struct connection *conn;
Emeric Brunce5ad802012-10-22 14:11:22 +02002423
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002424 if (!l4)
Emeric Brunce5ad802012-10-22 14:11:22 +02002425 return 0;
2426
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002427 conn = objt_conn(l4->si[0].end);
2428 if (!conn || conn->xprt != &ssl_sock)
2429 return 0;
2430
2431 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunce5ad802012-10-22 14:11:22 +02002432 smp->flags |= SMP_F_MAY_CHANGE;
2433 return 0;
2434 }
2435
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002436 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brunce5ad802012-10-22 14:11:22 +02002437 if (!crt)
2438 goto out;
2439
Willy Tarreau47ca5452012-12-23 20:22:19 +01002440 smp_trash = get_trash_chunk();
Emeric Brunce5ad802012-10-22 14:11:22 +02002441 if (ssl_sock_get_time(X509_get_notAfter(crt), smp_trash) <= 0)
2442 goto out;
2443
2444 smp->data.str = *smp_trash;
2445 smp->type = SMP_T_STR;
2446 ret = 1;
2447out:
2448 return ret;
2449}
2450
2451/*str, returns notbefore date in ASN1_UTCTIME format */
2452static int
2453smp_fetch_ssl_f_notbefore(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002454 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brunce5ad802012-10-22 14:11:22 +02002455{
2456 X509 *crt = NULL;
2457 int ret = 0;
2458 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002459 struct connection *conn;
Emeric Brunce5ad802012-10-22 14:11:22 +02002460
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002461 if (!l4)
Emeric Brunce5ad802012-10-22 14:11:22 +02002462 return 0;
2463
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002464 conn = objt_conn(l4->si[0].end);
2465 if (!conn || conn->xprt != &ssl_sock)
2466 return 0;
2467
2468 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunce5ad802012-10-22 14:11:22 +02002469 smp->flags |= SMP_F_MAY_CHANGE;
2470 return 0;
2471 }
2472
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002473 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brunce5ad802012-10-22 14:11:22 +02002474 if (!crt)
2475 goto out;
2476
Willy Tarreau47ca5452012-12-23 20:22:19 +01002477 smp_trash = get_trash_chunk();
Emeric Brunce5ad802012-10-22 14:11:22 +02002478 if (ssl_sock_get_time(X509_get_notBefore(crt), smp_trash) <= 0)
2479 goto out;
2480
2481 smp->data.str = *smp_trash;
2482 smp->type = SMP_T_STR;
2483 ret = 1;
2484out:
2485 return ret;
2486}
Willy Tarreau8d598402012-10-22 17:58:39 +02002487
Emeric Bruna7359fd2012-10-17 15:03:11 +02002488/* integer, returns the frontend certificate version */
2489static int
2490smp_fetch_ssl_f_version(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002491 const struct arg *args, struct sample *smp, const char *kw)
Emeric Bruna7359fd2012-10-17 15:03:11 +02002492{
2493 X509 *crt;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002494 struct connection *conn;
Emeric Bruna7359fd2012-10-17 15:03:11 +02002495
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002496 if (!l4)
Emeric Bruna7359fd2012-10-17 15:03:11 +02002497 return 0;
2498
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002499 conn = objt_conn(l4->si[0].end);
2500 if (!conn || conn->xprt != &ssl_sock)
2501 return 0;
2502
2503 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Bruna7359fd2012-10-17 15:03:11 +02002504 smp->flags |= SMP_F_MAY_CHANGE;
2505 return 0;
2506 }
2507
2508 /* SSL_get_certificate returns a ptr on an SSL * internal sub struct */
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002509 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Bruna7359fd2012-10-17 15:03:11 +02002510 if (!crt)
2511 return 0;
2512
2513 smp->data.uint = (unsigned int)(1 + X509_get_version(crt));
2514 smp->type = SMP_T_UINT;
2515
2516 return 1;
2517}
2518
Emeric Brun7f56e742012-10-19 18:15:40 +02002519/* str, returns the client certificate sig alg */
2520static int
2521smp_fetch_ssl_f_sig_alg(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002522 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brun7f56e742012-10-19 18:15:40 +02002523{
2524 X509 *crt;
2525 int nid;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002526 struct connection *conn;
Emeric Brun7f56e742012-10-19 18:15:40 +02002527
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002528 if (!l4)
Emeric Brun7f56e742012-10-19 18:15:40 +02002529 return 0;
2530
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002531 conn = objt_conn(l4->si[0].end);
2532 if (!conn || conn->xprt != &ssl_sock)
2533 return 0;
2534
2535 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun7f56e742012-10-19 18:15:40 +02002536 smp->flags |= SMP_F_MAY_CHANGE;
2537 return 0;
2538 }
2539
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002540 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brun7f56e742012-10-19 18:15:40 +02002541 if (!crt)
2542 return 0;
2543
2544 nid = OBJ_obj2nid((ASN1_OBJECT *)(crt->cert_info->signature->algorithm));
2545
2546 smp->data.str.str = (char *)OBJ_nid2sn(nid);
2547 if (!smp->data.str.str)
2548 return 0;
2549
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01002550 smp->type = SMP_T_STR;
2551 smp->flags |= SMP_F_CONST;
Emeric Brun7f56e742012-10-19 18:15:40 +02002552 smp->data.str.len = strlen(smp->data.str.str);
2553
2554 return 1;
2555}
2556
Emeric Brun521a0112012-10-22 12:22:55 +02002557/* str, returns the client certificate key alg */
2558static int
2559smp_fetch_ssl_f_key_alg(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002560 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brun521a0112012-10-22 12:22:55 +02002561{
2562 X509 *crt;
2563 int nid;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002564 struct connection *conn;
2565
2566 if (!l4)
2567 return 0;
Emeric Brun521a0112012-10-22 12:22:55 +02002568
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002569 conn = objt_conn(l4->si[0].end);
2570 if (!conn || conn->xprt != &ssl_sock)
Emeric Brun521a0112012-10-22 12:22:55 +02002571 return 0;
2572
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002573 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun521a0112012-10-22 12:22:55 +02002574 smp->flags |= SMP_F_MAY_CHANGE;
2575 return 0;
2576 }
2577
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002578 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brun521a0112012-10-22 12:22:55 +02002579 if (!crt)
2580 return 0;
2581
2582 nid = OBJ_obj2nid((ASN1_OBJECT *)(crt->cert_info->key->algor->algorithm));
2583
2584 smp->data.str.str = (char *)OBJ_nid2sn(nid);
2585 if (!smp->data.str.str)
2586 return 0;
2587
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01002588 smp->type = SMP_T_STR;
2589 smp->flags |= SMP_F_CONST;
Emeric Brun521a0112012-10-22 12:22:55 +02002590 smp->data.str.len = strlen(smp->data.str.str);
2591
2592 return 1;
2593}
2594
Emeric Brun87855892012-10-17 17:39:35 +02002595/* str, returns a string of a formatted full dn \C=..\O=..\OU=.. \CN=.. */
2596static int
2597smp_fetch_ssl_f_i_dn(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002598 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brun87855892012-10-17 17:39:35 +02002599{
2600 X509 *crt = NULL;
2601 X509_NAME *name;
2602 int ret = 0;
2603 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002604 struct connection *conn;
2605
2606 if (!l4)
2607 return 0;
Emeric Brun87855892012-10-17 17:39:35 +02002608
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002609 conn = objt_conn(l4->si[0].end);
2610 if (!conn || conn->xprt != &ssl_sock)
Emeric Brun87855892012-10-17 17:39:35 +02002611 return 0;
2612
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002613 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun87855892012-10-17 17:39:35 +02002614 smp->flags |= SMP_F_MAY_CHANGE;
2615 return 0;
2616 }
2617
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002618 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brun87855892012-10-17 17:39:35 +02002619 if (!crt)
2620 goto out;
2621
2622 name = X509_get_issuer_name(crt);
2623 if (!name)
2624 goto out;
2625
Willy Tarreau47ca5452012-12-23 20:22:19 +01002626 smp_trash = get_trash_chunk();
Emeric Brun87855892012-10-17 17:39:35 +02002627 if (args && args[0].type == ARGT_STR) {
2628 int pos = 1;
2629
2630 if (args[1].type == ARGT_SINT)
2631 pos = args[1].data.sint;
2632 else if (args[1].type == ARGT_UINT)
2633 pos =(int)args[1].data.uint;
2634
2635 if (ssl_sock_get_dn_entry(name, &args[0].data.str, pos, smp_trash) <= 0)
2636 goto out;
2637 }
2638 else if (ssl_sock_get_dn_oneline(name, smp_trash) <= 0)
2639 goto out;
2640
2641 smp->type = SMP_T_STR;
2642 smp->data.str = *smp_trash;
2643 ret = 1;
2644out:
2645 return ret;
2646}
2647
2648/* str, returns a string of a formatted full dn \C=..\O=..\OU=.. \CN=.. */
2649static int
2650smp_fetch_ssl_f_s_dn(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002651 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brun87855892012-10-17 17:39:35 +02002652{
2653 X509 *crt = NULL;
2654 X509_NAME *name;
2655 int ret = 0;
2656 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002657 struct connection *conn;
2658
2659 if (!l4)
2660 return 0;
Emeric Brun87855892012-10-17 17:39:35 +02002661
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002662 conn = objt_conn(l4->si[0].end);
2663 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
Emeric Brun87855892012-10-17 17:39:35 +02002664 return 0;
2665
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002666 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun87855892012-10-17 17:39:35 +02002667 smp->flags |= SMP_F_MAY_CHANGE;
2668 return 0;
2669 }
2670
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002671 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brun87855892012-10-17 17:39:35 +02002672 if (!crt)
2673 goto out;
2674
2675 name = X509_get_subject_name(crt);
2676 if (!name)
2677 goto out;
2678
Willy Tarreau47ca5452012-12-23 20:22:19 +01002679 smp_trash = get_trash_chunk();
Emeric Brun87855892012-10-17 17:39:35 +02002680 if (args && args[0].type == ARGT_STR) {
2681 int pos = 1;
2682
2683 if (args[1].type == ARGT_SINT)
2684 pos = args[1].data.sint;
2685 else if (args[1].type == ARGT_UINT)
2686 pos =(int)args[1].data.uint;
2687
2688 if (ssl_sock_get_dn_entry(name, &args[0].data.str, pos, smp_trash) <= 0)
2689 goto out;
2690 }
2691 else if (ssl_sock_get_dn_oneline(name, smp_trash) <= 0)
2692 goto out;
2693
2694 smp->type = SMP_T_STR;
2695 smp->data.str = *smp_trash;
2696 ret = 1;
2697out:
2698 return ret;
2699}
2700
Emeric Brun589fcad2012-10-16 14:13:26 +02002701static int
2702smp_fetch_ssl_fc_cipher(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002703 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brun589fcad2012-10-16 14:13:26 +02002704{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002705 struct connection *conn;
2706
Emeric Brun589fcad2012-10-16 14:13:26 +02002707 smp->flags = 0;
2708
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002709 if (!l4)
2710 return 0;
2711
2712 conn = objt_conn(l4->si[0].end);
2713 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
Emeric Brun589fcad2012-10-16 14:13:26 +02002714 return 0;
2715
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002716 smp->data.str.str = (char *)SSL_get_cipher_name(conn->xprt_ctx);
Emeric Brun589fcad2012-10-16 14:13:26 +02002717 if (!smp->data.str.str)
2718 return 0;
2719
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01002720 smp->type = SMP_T_STR;
2721 smp->flags |= SMP_F_CONST;
Emeric Brun589fcad2012-10-16 14:13:26 +02002722 smp->data.str.len = strlen(smp->data.str.str);
2723
2724 return 1;
2725}
2726
2727static int
2728smp_fetch_ssl_fc_alg_keysize(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002729 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brun589fcad2012-10-16 14:13:26 +02002730{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002731 struct connection *conn;
2732
Emeric Brun589fcad2012-10-16 14:13:26 +02002733 smp->flags = 0;
2734
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002735 if (!l4)
Emeric Brun589fcad2012-10-16 14:13:26 +02002736 return 0;
2737
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002738 conn = objt_conn(l4->si[0].end);
2739 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
Emeric Brun589fcad2012-10-16 14:13:26 +02002740 return 0;
2741
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002742 if (!SSL_get_cipher_bits(conn->xprt_ctx, (int *)&smp->data.uint))
2743 return 0;
2744
Emeric Brun589fcad2012-10-16 14:13:26 +02002745 smp->type = SMP_T_UINT;
2746
2747 return 1;
2748}
2749
2750static int
2751smp_fetch_ssl_fc_use_keysize(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002752 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brun589fcad2012-10-16 14:13:26 +02002753{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002754 struct connection *conn;
2755
Emeric Brun589fcad2012-10-16 14:13:26 +02002756 smp->flags = 0;
2757
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002758 if (!l4)
Emeric Brun589fcad2012-10-16 14:13:26 +02002759 return 0;
2760
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002761 conn = objt_conn(l4->si[0].end);
2762 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
2763 return 0;
2764
2765 smp->data.uint = (unsigned int)SSL_get_cipher_bits(conn->xprt_ctx, NULL);
Emeric Brun589fcad2012-10-16 14:13:26 +02002766 if (!smp->data.uint)
2767 return 0;
2768
2769 smp->type = SMP_T_UINT;
2770
2771 return 1;
2772}
2773
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02002774#ifdef OPENSSL_NPN_NEGOTIATED
Willy Tarreau7875d092012-09-10 08:20:03 +02002775static int
Emeric Brun2525b6b2012-10-18 15:59:43 +02002776smp_fetch_ssl_fc_npn(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002777 const struct arg *args, struct sample *smp, const char *kw)
Willy Tarreaua33c6542012-10-15 13:19:06 +02002778{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002779 struct connection *conn;
2780
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01002781 smp->flags = SMP_F_CONST;
2782 smp->type = SMP_T_STR;
Willy Tarreaua33c6542012-10-15 13:19:06 +02002783
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002784 if (!l4)
Willy Tarreaua33c6542012-10-15 13:19:06 +02002785 return 0;
2786
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002787 conn = objt_conn(l4->si[0].end);
2788 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
2789 return 0;
2790
Willy Tarreaua33c6542012-10-15 13:19:06 +02002791 smp->data.str.str = NULL;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002792 SSL_get0_next_proto_negotiated(conn->xprt_ctx,
Willy Tarreaua33c6542012-10-15 13:19:06 +02002793 (const unsigned char **)&smp->data.str.str, (unsigned *)&smp->data.str.len);
2794
2795 if (!smp->data.str.str)
2796 return 0;
2797
2798 return 1;
Willy Tarreaua33c6542012-10-15 13:19:06 +02002799}
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02002800#endif
Willy Tarreaua33c6542012-10-15 13:19:06 +02002801
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01002802#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Willy Tarreauab861d32013-04-02 02:30:41 +02002803static int
2804smp_fetch_ssl_fc_alpn(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002805 const struct arg *args, struct sample *smp, const char *kw)
Willy Tarreauab861d32013-04-02 02:30:41 +02002806{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002807 struct connection *conn;
2808
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01002809 smp->flags = SMP_F_CONST;
2810 smp->type = SMP_T_STR;
Willy Tarreauab861d32013-04-02 02:30:41 +02002811
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002812 if (!l4)
2813 return 0;
2814
2815 conn = objt_conn(l4->si[0].end);
2816 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
Willy Tarreauab861d32013-04-02 02:30:41 +02002817 return 0;
2818
2819 smp->data.str.str = NULL;
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01002820 SSL_get0_alpn_selected(conn->xprt_ctx,
Willy Tarreauab861d32013-04-02 02:30:41 +02002821 (const unsigned char **)&smp->data.str.str, (unsigned *)&smp->data.str.len);
2822
2823 if (!smp->data.str.str)
2824 return 0;
2825
2826 return 1;
2827}
2828#endif
2829
Willy Tarreaua33c6542012-10-15 13:19:06 +02002830static int
Emeric Brun589fcad2012-10-16 14:13:26 +02002831smp_fetch_ssl_fc_protocol(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002832 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brun589fcad2012-10-16 14:13:26 +02002833{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002834 struct connection *conn;
2835
Emeric Brun589fcad2012-10-16 14:13:26 +02002836 smp->flags = 0;
2837
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002838 if (!l4)
Emeric Brun589fcad2012-10-16 14:13:26 +02002839 return 0;
2840
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002841 conn = objt_conn(l4->si[0].end);
2842 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
2843 return 0;
2844
2845 smp->data.str.str = (char *)SSL_get_version(conn->xprt_ctx);
Emeric Brun589fcad2012-10-16 14:13:26 +02002846 if (!smp->data.str.str)
2847 return 0;
2848
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01002849 smp->type = SMP_T_STR;
2850 smp->flags = SMP_F_CONST;
Emeric Brun589fcad2012-10-16 14:13:26 +02002851 smp->data.str.len = strlen(smp->data.str.str);
2852
2853 return 1;
2854}
2855
2856static int
Emeric Brunfe68f682012-10-16 14:59:28 +02002857smp_fetch_ssl_fc_session_id(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002858 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brunfe68f682012-10-16 14:59:28 +02002859{
2860#if OPENSSL_VERSION_NUMBER > 0x0090800fL
2861 SSL_SESSION *sess;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002862 struct connection *conn;
Emeric Brunfe68f682012-10-16 14:59:28 +02002863
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01002864 smp->flags = SMP_F_CONST;
2865 smp->type = SMP_T_BIN;
Emeric Brunfe68f682012-10-16 14:59:28 +02002866
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002867 if (!l4)
Emeric Brunfe68f682012-10-16 14:59:28 +02002868 return 0;
2869
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002870 conn = objt_conn(l4->si[0].end);
2871 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
2872 return 0;
2873
2874 sess = SSL_get_session(conn->xprt_ctx);
Emeric Brunfe68f682012-10-16 14:59:28 +02002875 if (!sess)
2876 return 0;
2877
2878 smp->data.str.str = (char *)SSL_SESSION_get_id(sess, (unsigned int *)&smp->data.str.len);
2879 if (!smp->data.str.str || !&smp->data.str.len)
2880 return 0;
2881
2882 return 1;
2883#else
2884 return 0;
2885#endif
2886}
2887
2888static int
Emeric Brun2525b6b2012-10-18 15:59:43 +02002889smp_fetch_ssl_fc_sni(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002890 const struct arg *args, struct sample *smp, const char *kw)
Willy Tarreau7875d092012-09-10 08:20:03 +02002891{
2892#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002893 struct connection *conn;
2894
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01002895 smp->flags = SMP_F_CONST;
2896 smp->type = SMP_T_STR;
Willy Tarreau7875d092012-09-10 08:20:03 +02002897
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002898 if (!l4)
Willy Tarreau7875d092012-09-10 08:20:03 +02002899 return 0;
2900
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002901 conn = objt_conn(l4->si[0].end);
2902 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
2903 return 0;
2904
2905 smp->data.str.str = (char *)SSL_get_servername(conn->xprt_ctx, TLSEXT_NAMETYPE_host_name);
Willy Tarreau3e394c92012-09-14 23:56:58 +02002906 if (!smp->data.str.str)
2907 return 0;
2908
Willy Tarreau7875d092012-09-10 08:20:03 +02002909 smp->data.str.len = strlen(smp->data.str.str);
2910 return 1;
2911#else
2912 return 0;
2913#endif
2914}
2915
David Sc1ad52e2014-04-08 18:48:47 -04002916static int
2917smp_fetch_ssl_fc_unique_id(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
2918 const struct arg *args, struct sample *smp, const char *kw)
2919{
2920#if OPENSSL_VERSION_NUMBER > 0x0090800fL
2921 struct connection *conn;
2922 int finished_len;
2923 int b64_len;
2924 struct chunk *finished_trash;
2925 struct chunk *smp_trash;
2926
2927 smp->flags = 0;
2928
2929 if (!l4)
2930 return 0;
2931
2932 conn = objt_conn(l4->si[0].end);
2933 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
2934 return 0;
2935
2936 if (!(conn->flags & CO_FL_CONNECTED)) {
2937 smp->flags |= SMP_F_MAY_CHANGE;
2938 return 0;
2939 }
2940
2941 finished_trash = get_trash_chunk();
2942 if (!SSL_session_reused(conn->xprt_ctx))
2943 finished_len = SSL_get_peer_finished(conn->xprt_ctx, finished_trash->str, finished_trash->size);
2944 else
2945 finished_len = SSL_get_finished(conn->xprt_ctx, finished_trash->str, finished_trash->size);
2946
2947 if (!finished_len)
2948 return 0;
2949
2950 smp_trash = get_trash_chunk();
2951 b64_len = a2base64(finished_trash->str, finished_len, smp_trash->str, smp_trash->size);
2952 if (b64_len < 0)
2953 return 0;
2954
2955 smp->data.str.str = smp_trash->str;
Willy Tarreau073edf32014-04-09 15:40:42 +02002956 smp->type = SMP_T_STR;
2957 smp->flags |= SMP_F_CONST;
David Sc1ad52e2014-04-08 18:48:47 -04002958 smp->data.str.len = b64_len;
2959
2960 return 1;
2961#else
2962 return 0;
2963#endif
2964}
2965
Emeric Brun2525b6b2012-10-18 15:59:43 +02002966/* integer, returns the first verify error in CA chain of client certificate chain. */
Emeric Brunf282a812012-09-21 15:27:54 +02002967static int
Emeric Brun2525b6b2012-10-18 15:59:43 +02002968smp_fetch_ssl_c_ca_err(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002969 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brunf282a812012-09-21 15:27:54 +02002970{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002971 struct connection *conn;
2972
2973 if (!l4)
Emeric Brunf282a812012-09-21 15:27:54 +02002974 return 0;
2975
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002976 conn = objt_conn(l4->si[0].end);
2977 if (!conn || conn->xprt != &ssl_sock)
2978 return 0;
2979
2980 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunf282a812012-09-21 15:27:54 +02002981 smp->flags = SMP_F_MAY_CHANGE;
2982 return 0;
2983 }
2984
2985 smp->type = SMP_T_UINT;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002986 smp->data.uint = (unsigned int)SSL_SOCK_ST_TO_CA_ERROR(conn->xprt_st);
Emeric Brunf282a812012-09-21 15:27:54 +02002987 smp->flags = 0;
2988
2989 return 1;
2990}
2991
Emeric Brun2525b6b2012-10-18 15:59:43 +02002992/* integer, returns the depth of the first verify error in CA chain of client certificate chain. */
Emeric Brunf282a812012-09-21 15:27:54 +02002993static int
Emeric Brun2525b6b2012-10-18 15:59:43 +02002994smp_fetch_ssl_c_ca_err_depth(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002995 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brunf282a812012-09-21 15:27:54 +02002996{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002997 struct connection *conn;
2998
2999 if (!l4)
3000 return 0;
3001
3002 conn = objt_conn(l4->si[0].end);
3003 if (!conn || conn->xprt != &ssl_sock)
Emeric Brunf282a812012-09-21 15:27:54 +02003004 return 0;
3005
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003006 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunf282a812012-09-21 15:27:54 +02003007 smp->flags = SMP_F_MAY_CHANGE;
3008 return 0;
3009 }
3010
3011 smp->type = SMP_T_UINT;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003012 smp->data.uint = (unsigned int)SSL_SOCK_ST_TO_CAEDEPTH(conn->xprt_st);
Emeric Brunf282a812012-09-21 15:27:54 +02003013 smp->flags = 0;
3014
3015 return 1;
3016}
3017
Emeric Brun2525b6b2012-10-18 15:59:43 +02003018/* integer, returns the first verify error on client certificate */
Emeric Brunf282a812012-09-21 15:27:54 +02003019static int
Emeric Brun2525b6b2012-10-18 15:59:43 +02003020smp_fetch_ssl_c_err(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003021 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brunf282a812012-09-21 15:27:54 +02003022{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003023 struct connection *conn;
3024
3025 if (!l4)
Emeric Brunf282a812012-09-21 15:27:54 +02003026 return 0;
3027
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003028 conn = objt_conn(l4->si[0].end);
3029 if (!conn || conn->xprt != &ssl_sock)
3030 return 0;
3031
3032 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunf282a812012-09-21 15:27:54 +02003033 smp->flags = SMP_F_MAY_CHANGE;
3034 return 0;
3035 }
3036
3037 smp->type = SMP_T_UINT;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003038 smp->data.uint = (unsigned int)SSL_SOCK_ST_TO_CRTERROR(conn->xprt_st);
Emeric Brunf282a812012-09-21 15:27:54 +02003039 smp->flags = 0;
3040
3041 return 1;
3042}
3043
Emeric Brun2525b6b2012-10-18 15:59:43 +02003044/* integer, returns the verify result on client cert */
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02003045static int
Emeric Brun2525b6b2012-10-18 15:59:43 +02003046smp_fetch_ssl_c_verify(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003047 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02003048{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003049 struct connection *conn;
3050
3051 if (!l4)
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02003052 return 0;
3053
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003054 conn = objt_conn(l4->si[0].end);
3055 if (!conn || conn->xprt != &ssl_sock)
3056 return 0;
3057
3058 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02003059 smp->flags = SMP_F_MAY_CHANGE;
3060 return 0;
3061 }
3062
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003063 if (!conn->xprt_ctx)
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02003064 return 0;
3065
3066 smp->type = SMP_T_UINT;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003067 smp->data.uint = (unsigned int)SSL_get_verify_result(conn->xprt_ctx);
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02003068 smp->flags = 0;
3069
3070 return 1;
3071}
3072
Emeric Brunfb510ea2012-10-05 12:00:26 +02003073/* parse the "ca-file" bind keyword */
3074static int bind_parse_ca_file(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
Emeric Brund94b3fe2012-09-20 18:23:56 +02003075{
3076 if (!*args[cur_arg + 1]) {
3077 if (err)
3078 memprintf(err, "'%s' : missing CAfile path", args[cur_arg]);
3079 return ERR_ALERT | ERR_FATAL;
3080 }
3081
Emeric Brunef42d922012-10-11 16:11:36 +02003082 if ((*args[cur_arg + 1] != '/') && global.ca_base)
3083 memprintf(&conf->ca_file, "%s/%s", global.ca_base, args[cur_arg + 1]);
3084 else
3085 memprintf(&conf->ca_file, "%s", args[cur_arg + 1]);
Emeric Brunc8e8d122012-10-02 18:42:10 +02003086
Emeric Brund94b3fe2012-09-20 18:23:56 +02003087 return 0;
3088}
3089
Willy Tarreau79eeafa2012-09-14 07:53:05 +02003090/* parse the "ciphers" bind keyword */
Willy Tarreau4348fad2012-09-20 16:48:07 +02003091static int bind_parse_ciphers(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
Willy Tarreau79eeafa2012-09-14 07:53:05 +02003092{
3093 if (!*args[cur_arg + 1]) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02003094 memprintf(err, "'%s' : missing cipher suite", args[cur_arg]);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02003095 return ERR_ALERT | ERR_FATAL;
3096 }
3097
Emeric Brun76d88952012-10-05 15:47:31 +02003098 free(conf->ciphers);
Willy Tarreau4348fad2012-09-20 16:48:07 +02003099 conf->ciphers = strdup(args[cur_arg + 1]);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02003100 return 0;
3101}
3102
3103/* parse the "crt" bind keyword */
Willy Tarreau4348fad2012-09-20 16:48:07 +02003104static int bind_parse_crt(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
Willy Tarreau79eeafa2012-09-14 07:53:05 +02003105{
Willy Tarreau38011032013-08-13 16:59:39 +02003106 char path[MAXPATHLEN];
Willy Tarreaub75d6922014-04-14 18:05:41 +02003107
Willy Tarreau79eeafa2012-09-14 07:53:05 +02003108 if (!*args[cur_arg + 1]) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02003109 memprintf(err, "'%s' : missing certificate location", args[cur_arg]);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02003110 return ERR_ALERT | ERR_FATAL;
3111 }
3112
Emeric Brunc8e8d122012-10-02 18:42:10 +02003113 if ((*args[cur_arg + 1] != '/' ) && global.crt_base) {
Willy Tarreau38011032013-08-13 16:59:39 +02003114 if ((strlen(global.crt_base) + 1 + strlen(args[cur_arg + 1]) + 1) > MAXPATHLEN) {
Emeric Brunc8e8d122012-10-02 18:42:10 +02003115 memprintf(err, "'%s' : path too long", args[cur_arg]);
3116 return ERR_ALERT | ERR_FATAL;
3117 }
Willy Tarreaub75d6922014-04-14 18:05:41 +02003118 snprintf(path, sizeof(path), "%s/%s", global.crt_base, args[cur_arg + 1]);
Emeric Brunc8e8d122012-10-02 18:42:10 +02003119 if (ssl_sock_load_cert(path, conf, px, err) > 0)
3120 return ERR_ALERT | ERR_FATAL;
3121
3122 return 0;
3123 }
3124
Willy Tarreau4348fad2012-09-20 16:48:07 +02003125 if (ssl_sock_load_cert(args[cur_arg + 1], conf, px, err) > 0)
Willy Tarreau79eeafa2012-09-14 07:53:05 +02003126 return ERR_ALERT | ERR_FATAL;
Emeric Brund94b3fe2012-09-20 18:23:56 +02003127
3128 return 0;
3129}
3130
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01003131/* parse the "crt-list" bind keyword */
3132static int bind_parse_crt_list(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
3133{
3134 if (!*args[cur_arg + 1]) {
3135 memprintf(err, "'%s' : missing certificate location", args[cur_arg]);
3136 return ERR_ALERT | ERR_FATAL;
3137 }
3138
Willy Tarreauad1731d2013-04-02 17:35:58 +02003139 if (ssl_sock_load_cert_list_file(args[cur_arg + 1], conf, px, err) > 0) {
3140 memprintf(err, "'%s' : %s", args[cur_arg], *err);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01003141 return ERR_ALERT | ERR_FATAL;
Willy Tarreauad1731d2013-04-02 17:35:58 +02003142 }
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01003143
3144 return 0;
3145}
3146
Emeric Brunfb510ea2012-10-05 12:00:26 +02003147/* parse the "crl-file" bind keyword */
3148static int bind_parse_crl_file(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
Emeric Brund94b3fe2012-09-20 18:23:56 +02003149{
Emeric Brun051cdab2012-10-02 19:25:50 +02003150#ifndef X509_V_FLAG_CRL_CHECK
3151 if (err)
3152 memprintf(err, "'%s' : library does not support CRL verify", args[cur_arg]);
3153 return ERR_ALERT | ERR_FATAL;
3154#else
Emeric Brund94b3fe2012-09-20 18:23:56 +02003155 if (!*args[cur_arg + 1]) {
3156 if (err)
3157 memprintf(err, "'%s' : missing CRLfile path", args[cur_arg]);
3158 return ERR_ALERT | ERR_FATAL;
3159 }
Emeric Brun2b58d042012-09-20 17:10:03 +02003160
Emeric Brunef42d922012-10-11 16:11:36 +02003161 if ((*args[cur_arg + 1] != '/') && global.ca_base)
3162 memprintf(&conf->crl_file, "%s/%s", global.ca_base, args[cur_arg + 1]);
3163 else
3164 memprintf(&conf->crl_file, "%s", args[cur_arg + 1]);
Emeric Brunc8e8d122012-10-02 18:42:10 +02003165
Emeric Brun2b58d042012-09-20 17:10:03 +02003166 return 0;
Emeric Brun051cdab2012-10-02 19:25:50 +02003167#endif
Emeric Brun2b58d042012-09-20 17:10:03 +02003168}
3169
3170/* parse the "ecdhe" bind keyword keywords */
3171static int bind_parse_ecdhe(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
3172{
3173#if OPENSSL_VERSION_NUMBER < 0x0090800fL
3174 if (err)
3175 memprintf(err, "'%s' : library does not support elliptic curve Diffie-Hellman (too old)", args[cur_arg]);
3176 return ERR_ALERT | ERR_FATAL;
3177#elif defined(OPENSSL_NO_ECDH)
3178 if (err)
3179 memprintf(err, "'%s' : library does not support elliptic curve Diffie-Hellman (disabled via OPENSSL_NO_ECDH)", args[cur_arg]);
3180 return ERR_ALERT | ERR_FATAL;
3181#else
3182 if (!*args[cur_arg + 1]) {
3183 if (err)
3184 memprintf(err, "'%s' : missing named curve", args[cur_arg]);
3185 return ERR_ALERT | ERR_FATAL;
3186 }
3187
3188 conf->ecdhe = strdup(args[cur_arg + 1]);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02003189
3190 return 0;
Emeric Brun2b58d042012-09-20 17:10:03 +02003191#endif
Willy Tarreau79eeafa2012-09-14 07:53:05 +02003192}
3193
Emeric Brun81c00f02012-09-21 14:31:21 +02003194/* parse the "crt_ignerr" and "ca_ignerr" bind keywords */
3195static int bind_parse_ignore_err(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
3196{
3197 int code;
3198 char *p = args[cur_arg + 1];
3199 unsigned long long *ignerr = &conf->crt_ignerr;
3200
3201 if (!*p) {
3202 if (err)
3203 memprintf(err, "'%s' : missing error IDs list", args[cur_arg]);
3204 return ERR_ALERT | ERR_FATAL;
3205 }
3206
3207 if (strcmp(args[cur_arg], "ca-ignore-err") == 0)
3208 ignerr = &conf->ca_ignerr;
3209
3210 if (strcmp(p, "all") == 0) {
3211 *ignerr = ~0ULL;
3212 return 0;
3213 }
3214
3215 while (p) {
3216 code = atoi(p);
3217 if ((code <= 0) || (code > 63)) {
3218 if (err)
3219 memprintf(err, "'%s' : ID '%d' out of range (1..63) in error IDs list '%s'",
3220 args[cur_arg], code, args[cur_arg + 1]);
3221 return ERR_ALERT | ERR_FATAL;
3222 }
3223 *ignerr |= 1ULL << code;
3224 p = strchr(p, ',');
3225 if (p)
3226 p++;
3227 }
3228
Emeric Brun2cb7ae52012-10-05 14:14:21 +02003229 return 0;
3230}
3231
3232/* parse the "force-sslv3" bind keyword */
3233static int bind_parse_force_sslv3(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
3234{
3235 conf->ssl_options |= BC_SSL_O_USE_SSLV3;
3236 return 0;
3237}
3238
3239/* parse the "force-tlsv10" bind keyword */
3240static int bind_parse_force_tlsv10(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
3241{
3242 conf->ssl_options |= BC_SSL_O_USE_TLSV10;
Emeric Brun2d0c4822012-10-02 13:45:20 +02003243 return 0;
3244}
3245
Emeric Brun2cb7ae52012-10-05 14:14:21 +02003246/* parse the "force-tlsv11" bind keyword */
3247static int bind_parse_force_tlsv11(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
3248{
3249#if SSL_OP_NO_TLSv1_1
3250 conf->ssl_options |= BC_SSL_O_USE_TLSV11;
3251 return 0;
3252#else
3253 if (err)
3254 memprintf(err, "'%s' : library does not support protocol TLSv1.1", args[cur_arg]);
3255 return ERR_ALERT | ERR_FATAL;
3256#endif
3257}
3258
3259/* parse the "force-tlsv12" bind keyword */
3260static int bind_parse_force_tlsv12(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
3261{
3262#if SSL_OP_NO_TLSv1_2
3263 conf->ssl_options |= BC_SSL_O_USE_TLSV12;
3264 return 0;
3265#else
3266 if (err)
3267 memprintf(err, "'%s' : library does not support protocol TLSv1.2", args[cur_arg]);
3268 return ERR_ALERT | ERR_FATAL;
3269#endif
3270}
3271
3272
Emeric Brun2d0c4822012-10-02 13:45:20 +02003273/* parse the "no-tls-tickets" bind keyword */
3274static int bind_parse_no_tls_tickets(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
3275{
Emeric Brun89675492012-10-05 13:48:26 +02003276 conf->ssl_options |= BC_SSL_O_NO_TLS_TICKETS;
Emeric Brun81c00f02012-09-21 14:31:21 +02003277 return 0;
3278}
3279
Emeric Brun2d0c4822012-10-02 13:45:20 +02003280
Emeric Brun9b3009b2012-10-05 11:55:06 +02003281/* parse the "no-sslv3" bind keyword */
3282static int bind_parse_no_sslv3(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
Willy Tarreau79eeafa2012-09-14 07:53:05 +02003283{
Emeric Brun89675492012-10-05 13:48:26 +02003284 conf->ssl_options |= BC_SSL_O_NO_SSLV3;
Willy Tarreau79eeafa2012-09-14 07:53:05 +02003285 return 0;
3286}
3287
Emeric Brun9b3009b2012-10-05 11:55:06 +02003288/* parse the "no-tlsv10" bind keyword */
3289static int bind_parse_no_tlsv10(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
Emeric Brunc0ff4922012-09-28 19:37:02 +02003290{
Emeric Brun89675492012-10-05 13:48:26 +02003291 conf->ssl_options |= BC_SSL_O_NO_TLSV10;
Emeric Brunc0ff4922012-09-28 19:37:02 +02003292 return 0;
3293}
3294
Emeric Brun9b3009b2012-10-05 11:55:06 +02003295/* parse the "no-tlsv11" bind keyword */
3296static int bind_parse_no_tlsv11(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
Emeric Brunc0ff4922012-09-28 19:37:02 +02003297{
Emeric Brun89675492012-10-05 13:48:26 +02003298 conf->ssl_options |= BC_SSL_O_NO_TLSV11;
Emeric Brunc0ff4922012-09-28 19:37:02 +02003299 return 0;
3300}
3301
Emeric Brun9b3009b2012-10-05 11:55:06 +02003302/* parse the "no-tlsv12" bind keyword */
3303static int bind_parse_no_tlsv12(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
Willy Tarreau79eeafa2012-09-14 07:53:05 +02003304{
Emeric Brun89675492012-10-05 13:48:26 +02003305 conf->ssl_options |= BC_SSL_O_NO_TLSV12;
Willy Tarreau79eeafa2012-09-14 07:53:05 +02003306 return 0;
3307}
3308
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02003309/* parse the "npn" bind keyword */
3310static int bind_parse_npn(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
3311{
3312#ifdef OPENSSL_NPN_NEGOTIATED
3313 char *p1, *p2;
3314
3315 if (!*args[cur_arg + 1]) {
3316 memprintf(err, "'%s' : missing the comma-delimited NPN protocol suite", args[cur_arg]);
3317 return ERR_ALERT | ERR_FATAL;
3318 }
3319
3320 free(conf->npn_str);
3321
3322 /* the NPN string is built as a suite of (<len> <name>)* */
3323 conf->npn_len = strlen(args[cur_arg + 1]) + 1;
3324 conf->npn_str = calloc(1, conf->npn_len);
3325 memcpy(conf->npn_str + 1, args[cur_arg + 1], conf->npn_len);
3326
3327 /* replace commas with the name length */
3328 p1 = conf->npn_str;
3329 p2 = p1 + 1;
3330 while (1) {
3331 p2 = memchr(p1 + 1, ',', conf->npn_str + conf->npn_len - (p1 + 1));
3332 if (!p2)
3333 p2 = p1 + 1 + strlen(p1 + 1);
3334
3335 if (p2 - (p1 + 1) > 255) {
3336 *p2 = '\0';
3337 memprintf(err, "'%s' : NPN protocol name too long : '%s'", args[cur_arg], p1 + 1);
3338 return ERR_ALERT | ERR_FATAL;
3339 }
3340
3341 *p1 = p2 - (p1 + 1);
3342 p1 = p2;
3343
3344 if (!*p2)
3345 break;
3346
3347 *(p2++) = '\0';
3348 }
3349 return 0;
3350#else
3351 if (err)
3352 memprintf(err, "'%s' : library does not support TLS NPN extension", args[cur_arg]);
3353 return ERR_ALERT | ERR_FATAL;
3354#endif
3355}
3356
Willy Tarreauab861d32013-04-02 02:30:41 +02003357/* parse the "alpn" bind keyword */
3358static int bind_parse_alpn(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
3359{
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01003360#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Willy Tarreauab861d32013-04-02 02:30:41 +02003361 char *p1, *p2;
3362
3363 if (!*args[cur_arg + 1]) {
3364 memprintf(err, "'%s' : missing the comma-delimited ALPN protocol suite", args[cur_arg]);
3365 return ERR_ALERT | ERR_FATAL;
3366 }
3367
3368 free(conf->alpn_str);
3369
3370 /* the ALPN string is built as a suite of (<len> <name>)* */
3371 conf->alpn_len = strlen(args[cur_arg + 1]) + 1;
3372 conf->alpn_str = calloc(1, conf->alpn_len);
3373 memcpy(conf->alpn_str + 1, args[cur_arg + 1], conf->alpn_len);
3374
3375 /* replace commas with the name length */
3376 p1 = conf->alpn_str;
3377 p2 = p1 + 1;
3378 while (1) {
3379 p2 = memchr(p1 + 1, ',', conf->alpn_str + conf->alpn_len - (p1 + 1));
3380 if (!p2)
3381 p2 = p1 + 1 + strlen(p1 + 1);
3382
3383 if (p2 - (p1 + 1) > 255) {
3384 *p2 = '\0';
3385 memprintf(err, "'%s' : ALPN protocol name too long : '%s'", args[cur_arg], p1 + 1);
3386 return ERR_ALERT | ERR_FATAL;
3387 }
3388
3389 *p1 = p2 - (p1 + 1);
3390 p1 = p2;
3391
3392 if (!*p2)
3393 break;
3394
3395 *(p2++) = '\0';
3396 }
3397 return 0;
3398#else
3399 if (err)
3400 memprintf(err, "'%s' : library does not support TLS ALPN extension", args[cur_arg]);
3401 return ERR_ALERT | ERR_FATAL;
3402#endif
3403}
3404
Willy Tarreau79eeafa2012-09-14 07:53:05 +02003405/* parse the "ssl" bind keyword */
Willy Tarreau4348fad2012-09-20 16:48:07 +02003406static int bind_parse_ssl(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
Willy Tarreau79eeafa2012-09-14 07:53:05 +02003407{
Willy Tarreau81796be2012-09-22 19:11:47 +02003408 struct listener *l;
3409
Willy Tarreau4348fad2012-09-20 16:48:07 +02003410 conf->is_ssl = 1;
Emeric Brun76d88952012-10-05 15:47:31 +02003411
3412 if (global.listen_default_ciphers && !conf->ciphers)
3413 conf->ciphers = strdup(global.listen_default_ciphers);
3414
Willy Tarreau81796be2012-09-22 19:11:47 +02003415 list_for_each_entry(l, &conf->listeners, by_bind)
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02003416 l->xprt = &ssl_sock;
Willy Tarreau81796be2012-09-22 19:11:47 +02003417
Willy Tarreau79eeafa2012-09-14 07:53:05 +02003418 return 0;
3419}
3420
Emmanuel Hocdet65623372013-01-24 17:17:15 +01003421/* parse the "strict-sni" bind keyword */
3422static int bind_parse_strict_sni(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
3423{
3424 conf->strict_sni = 1;
3425 return 0;
3426}
3427
Emeric Brund94b3fe2012-09-20 18:23:56 +02003428/* parse the "verify" bind keyword */
3429static int bind_parse_verify(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
3430{
3431 if (!*args[cur_arg + 1]) {
3432 if (err)
3433 memprintf(err, "'%s' : missing verify method", args[cur_arg]);
3434 return ERR_ALERT | ERR_FATAL;
3435 }
3436
3437 if (strcmp(args[cur_arg + 1], "none") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01003438 conf->verify = SSL_SOCK_VERIFY_NONE;
Emeric Brund94b3fe2012-09-20 18:23:56 +02003439 else if (strcmp(args[cur_arg + 1], "optional") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01003440 conf->verify = SSL_SOCK_VERIFY_OPTIONAL;
Emeric Brund94b3fe2012-09-20 18:23:56 +02003441 else if (strcmp(args[cur_arg + 1], "required") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01003442 conf->verify = SSL_SOCK_VERIFY_REQUIRED;
Emeric Brund94b3fe2012-09-20 18:23:56 +02003443 else {
3444 if (err)
3445 memprintf(err, "'%s' : unknown verify method '%s', only 'none', 'optional', and 'required' are supported\n",
3446 args[cur_arg], args[cur_arg + 1]);
3447 return ERR_ALERT | ERR_FATAL;
3448 }
3449
3450 return 0;
3451}
3452
Willy Tarreau92faadf2012-10-10 23:04:25 +02003453/************** "server" keywords ****************/
3454
Emeric Brunef42d922012-10-11 16:11:36 +02003455/* parse the "ca-file" server keyword */
3456static int srv_parse_ca_file(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
3457{
3458 if (!*args[*cur_arg + 1]) {
3459 if (err)
3460 memprintf(err, "'%s' : missing CAfile path", args[*cur_arg]);
3461 return ERR_ALERT | ERR_FATAL;
3462 }
3463
3464 if ((*args[*cur_arg + 1] != '/') && global.ca_base)
3465 memprintf(&newsrv->ssl_ctx.ca_file, "%s/%s", global.ca_base, args[*cur_arg + 1]);
3466 else
3467 memprintf(&newsrv->ssl_ctx.ca_file, "%s", args[*cur_arg + 1]);
3468
3469 return 0;
3470}
3471
Willy Tarreau92faadf2012-10-10 23:04:25 +02003472/* parse the "check-ssl" server keyword */
3473static int srv_parse_check_ssl(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
3474{
3475 newsrv->check.use_ssl = 1;
3476 if (global.connect_default_ciphers && !newsrv->ssl_ctx.ciphers)
3477 newsrv->ssl_ctx.ciphers = strdup(global.connect_default_ciphers);
3478 return 0;
3479}
3480
3481/* parse the "ciphers" server keyword */
3482static int srv_parse_ciphers(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
3483{
3484 if (!*args[*cur_arg + 1]) {
3485 memprintf(err, "'%s' : missing cipher suite", args[*cur_arg]);
3486 return ERR_ALERT | ERR_FATAL;
3487 }
3488
3489 free(newsrv->ssl_ctx.ciphers);
3490 newsrv->ssl_ctx.ciphers = strdup(args[*cur_arg + 1]);
3491 return 0;
3492}
3493
Emeric Brunef42d922012-10-11 16:11:36 +02003494/* parse the "crl-file" server keyword */
3495static int srv_parse_crl_file(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
3496{
3497#ifndef X509_V_FLAG_CRL_CHECK
3498 if (err)
3499 memprintf(err, "'%s' : library does not support CRL verify", args[*cur_arg]);
3500 return ERR_ALERT | ERR_FATAL;
3501#else
3502 if (!*args[*cur_arg + 1]) {
3503 if (err)
3504 memprintf(err, "'%s' : missing CRLfile path", args[*cur_arg]);
3505 return ERR_ALERT | ERR_FATAL;
3506 }
3507
3508 if ((*args[*cur_arg + 1] != '/') && global.ca_base)
3509 memprintf(&newsrv->ssl_ctx.crl_file, "%s/%s", global.ca_base, args[*cur_arg + 1]);
3510 else
3511 memprintf(&newsrv->ssl_ctx.crl_file, "%s", args[*cur_arg + 1]);
3512
3513 return 0;
3514#endif
3515}
3516
Emeric Bruna7aa3092012-10-26 12:58:00 +02003517/* parse the "crt" server keyword */
3518static int srv_parse_crt(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
3519{
3520 if (!*args[*cur_arg + 1]) {
3521 if (err)
3522 memprintf(err, "'%s' : missing certificate file path", args[*cur_arg]);
3523 return ERR_ALERT | ERR_FATAL;
3524 }
3525
3526 if ((*args[*cur_arg + 1] != '/') && global.crt_base)
3527 memprintf(&newsrv->ssl_ctx.client_crt, "%s/%s", global.ca_base, args[*cur_arg + 1]);
3528 else
3529 memprintf(&newsrv->ssl_ctx.client_crt, "%s", args[*cur_arg + 1]);
3530
3531 return 0;
3532}
Emeric Brunef42d922012-10-11 16:11:36 +02003533
Willy Tarreau92faadf2012-10-10 23:04:25 +02003534/* parse the "force-sslv3" server keyword */
3535static int srv_parse_force_sslv3(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
3536{
3537 newsrv->ssl_ctx.options |= SRV_SSL_O_USE_SSLV3;
3538 return 0;
3539}
3540
3541/* parse the "force-tlsv10" server keyword */
3542static int srv_parse_force_tlsv10(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
3543{
3544 newsrv->ssl_ctx.options |= SRV_SSL_O_USE_TLSV10;
3545 return 0;
3546}
3547
3548/* parse the "force-tlsv11" server keyword */
3549static int srv_parse_force_tlsv11(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
3550{
3551#if SSL_OP_NO_TLSv1_1
3552 newsrv->ssl_ctx.options |= SRV_SSL_O_USE_TLSV11;
3553 return 0;
3554#else
3555 if (err)
3556 memprintf(err, "'%s' : library does not support protocol TLSv1.1", args[*cur_arg]);
3557 return ERR_ALERT | ERR_FATAL;
3558#endif
3559}
3560
3561/* parse the "force-tlsv12" server keyword */
3562static int srv_parse_force_tlsv12(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
3563{
3564#if SSL_OP_NO_TLSv1_2
3565 newsrv->ssl_ctx.options |= SRV_SSL_O_USE_TLSV12;
3566 return 0;
3567#else
3568 if (err)
3569 memprintf(err, "'%s' : library does not support protocol TLSv1.2", args[*cur_arg]);
3570 return ERR_ALERT | ERR_FATAL;
3571#endif
3572}
3573
3574/* parse the "no-sslv3" server keyword */
3575static int srv_parse_no_sslv3(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
3576{
3577 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_SSLV3;
3578 return 0;
3579}
3580
3581/* parse the "no-tlsv10" server keyword */
3582static int srv_parse_no_tlsv10(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
3583{
3584 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_TLSV10;
3585 return 0;
3586}
3587
3588/* parse the "no-tlsv11" server keyword */
3589static int srv_parse_no_tlsv11(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
3590{
3591 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_TLSV11;
3592 return 0;
3593}
3594
3595/* parse the "no-tlsv12" server keyword */
3596static int srv_parse_no_tlsv12(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
3597{
3598 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_TLSV12;
3599 return 0;
3600}
3601
Emeric Brunf9c5c472012-10-11 15:28:34 +02003602/* parse the "no-tls-tickets" server keyword */
3603static int srv_parse_no_tls_tickets(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
3604{
3605 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_TLS_TICKETS;
3606 return 0;
3607}
3608
Willy Tarreau92faadf2012-10-10 23:04:25 +02003609/* parse the "ssl" server keyword */
3610static int srv_parse_ssl(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
3611{
3612 newsrv->use_ssl = 1;
3613 if (global.connect_default_ciphers && !newsrv->ssl_ctx.ciphers)
3614 newsrv->ssl_ctx.ciphers = strdup(global.connect_default_ciphers);
3615 return 0;
3616}
3617
Emeric Brunef42d922012-10-11 16:11:36 +02003618/* parse the "verify" server keyword */
3619static int srv_parse_verify(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
3620{
3621 if (!*args[*cur_arg + 1]) {
3622 if (err)
3623 memprintf(err, "'%s' : missing verify method", args[*cur_arg]);
3624 return ERR_ALERT | ERR_FATAL;
3625 }
3626
3627 if (strcmp(args[*cur_arg + 1], "none") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01003628 newsrv->ssl_ctx.verify = SSL_SOCK_VERIFY_NONE;
Emeric Brunef42d922012-10-11 16:11:36 +02003629 else if (strcmp(args[*cur_arg + 1], "required") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01003630 newsrv->ssl_ctx.verify = SSL_SOCK_VERIFY_REQUIRED;
Emeric Brunef42d922012-10-11 16:11:36 +02003631 else {
3632 if (err)
3633 memprintf(err, "'%s' : unknown verify method '%s', only 'none' and 'required' are supported\n",
3634 args[*cur_arg], args[*cur_arg + 1]);
3635 return ERR_ALERT | ERR_FATAL;
3636 }
3637
Evan Broderbe554312013-06-27 00:05:25 -07003638 return 0;
3639}
3640
3641/* parse the "verifyhost" server keyword */
3642static int srv_parse_verifyhost(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
3643{
3644 if (!*args[*cur_arg + 1]) {
3645 if (err)
3646 memprintf(err, "'%s' : missing hostname to verify against", args[*cur_arg]);
3647 return ERR_ALERT | ERR_FATAL;
3648 }
3649
3650 newsrv->ssl_ctx.verify_host = strdup(args[*cur_arg + 1]);
3651
Emeric Brunef42d922012-10-11 16:11:36 +02003652 return 0;
3653}
3654
Willy Tarreau7875d092012-09-10 08:20:03 +02003655/* Note: must not be declared <const> as its list will be overwritten.
3656 * Please take care of keeping this list alphabetically sorted.
3657 */
Willy Tarreaudc13c112013-06-21 23:16:39 +02003658static struct sample_fetch_kw_list sample_fetch_keywords = {ILH, {
Willy Tarreau80aca902013-01-07 15:42:20 +01003659 { "ssl_c_ca_err", smp_fetch_ssl_c_ca_err, 0, NULL, SMP_T_UINT, SMP_USE_L5CLI },
3660 { "ssl_c_ca_err_depth", smp_fetch_ssl_c_ca_err_depth, 0, NULL, SMP_T_UINT, SMP_USE_L5CLI },
3661 { "ssl_c_err", smp_fetch_ssl_c_err, 0, NULL, SMP_T_UINT, SMP_USE_L5CLI },
3662 { "ssl_c_i_dn", smp_fetch_ssl_c_i_dn, ARG2(0,STR,SINT), NULL, SMP_T_STR, SMP_USE_L5CLI },
3663 { "ssl_c_key_alg", smp_fetch_ssl_c_key_alg, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
3664 { "ssl_c_notafter", smp_fetch_ssl_c_notafter, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
3665 { "ssl_c_notbefore", smp_fetch_ssl_c_notbefore, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
3666 { "ssl_c_sig_alg", smp_fetch_ssl_c_sig_alg, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
3667 { "ssl_c_s_dn", smp_fetch_ssl_c_s_dn, ARG2(0,STR,SINT), NULL, SMP_T_STR, SMP_USE_L5CLI },
3668 { "ssl_c_serial", smp_fetch_ssl_c_serial, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
James Votha051b4a2013-05-14 20:37:59 +02003669 { "ssl_c_sha1", smp_fetch_ssl_c_sha1, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Willy Tarreau80aca902013-01-07 15:42:20 +01003670 { "ssl_c_used", smp_fetch_ssl_c_used, 0, NULL, SMP_T_BOOL, SMP_USE_L5CLI },
3671 { "ssl_c_verify", smp_fetch_ssl_c_verify, 0, NULL, SMP_T_UINT, SMP_USE_L5CLI },
3672 { "ssl_c_version", smp_fetch_ssl_c_version, 0, NULL, SMP_T_UINT, SMP_USE_L5CLI },
3673 { "ssl_f_i_dn", smp_fetch_ssl_f_i_dn, ARG2(0,STR,SINT), NULL, SMP_T_STR, SMP_USE_L5CLI },
3674 { "ssl_f_key_alg", smp_fetch_ssl_f_key_alg, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
3675 { "ssl_f_notafter", smp_fetch_ssl_f_notafter, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
3676 { "ssl_f_notbefore", smp_fetch_ssl_f_notbefore, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
3677 { "ssl_f_sig_alg", smp_fetch_ssl_f_sig_alg, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
3678 { "ssl_f_s_dn", smp_fetch_ssl_f_s_dn, ARG2(0,STR,SINT), NULL, SMP_T_STR, SMP_USE_L5CLI },
3679 { "ssl_f_serial", smp_fetch_ssl_f_serial, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
3680 { "ssl_f_version", smp_fetch_ssl_f_version, 0, NULL, SMP_T_UINT, SMP_USE_L5CLI },
3681 { "ssl_fc", smp_fetch_ssl_fc, 0, NULL, SMP_T_BOOL, SMP_USE_L5CLI },
3682 { "ssl_fc_alg_keysize", smp_fetch_ssl_fc_alg_keysize, 0, NULL, SMP_T_UINT, SMP_USE_L5CLI },
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01003683 { "ssl_fc_cipher", smp_fetch_ssl_fc_cipher, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Willy Tarreau80aca902013-01-07 15:42:20 +01003684 { "ssl_fc_has_crt", smp_fetch_ssl_fc_has_crt, 0, NULL, SMP_T_BOOL, SMP_USE_L5CLI },
3685 { "ssl_fc_has_sni", smp_fetch_ssl_fc_has_sni, 0, NULL, SMP_T_BOOL, SMP_USE_L5CLI },
Willy Tarreaua33c6542012-10-15 13:19:06 +02003686#ifdef OPENSSL_NPN_NEGOTIATED
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01003687 { "ssl_fc_npn", smp_fetch_ssl_fc_npn, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Willy Tarreaua33c6542012-10-15 13:19:06 +02003688#endif
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01003689#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01003690 { "ssl_fc_alpn", smp_fetch_ssl_fc_alpn, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Willy Tarreauab861d32013-04-02 02:30:41 +02003691#endif
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01003692 { "ssl_fc_protocol", smp_fetch_ssl_fc_protocol, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Willy Tarreau073edf32014-04-09 15:40:42 +02003693 { "ssl_fc_unique_id", smp_fetch_ssl_fc_unique_id, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Willy Tarreau80aca902013-01-07 15:42:20 +01003694 { "ssl_fc_use_keysize", smp_fetch_ssl_fc_use_keysize, 0, NULL, SMP_T_UINT, SMP_USE_L5CLI },
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01003695 { "ssl_fc_session_id", smp_fetch_ssl_fc_session_id, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
3696 { "ssl_fc_sni", smp_fetch_ssl_fc_sni, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Willy Tarreau7875d092012-09-10 08:20:03 +02003697 { NULL, NULL, 0, 0, 0 },
3698}};
3699
3700/* Note: must not be declared <const> as its list will be overwritten.
3701 * Please take care of keeping this list alphabetically sorted.
3702 */
Willy Tarreaudc13c112013-06-21 23:16:39 +02003703static struct acl_kw_list acl_kws = {ILH, {
Thierry FOURNIERc5a4e982014-03-05 16:07:08 +01003704 { "ssl_c_i_dn", NULL, PAT_MATCH_STR },
3705 { "ssl_c_key_alg", NULL, PAT_MATCH_STR },
3706 { "ssl_c_notafter", NULL, PAT_MATCH_STR },
3707 { "ssl_c_notbefore", NULL, PAT_MATCH_STR },
3708 { "ssl_c_sig_alg", NULL, PAT_MATCH_STR },
3709 { "ssl_c_s_dn", NULL, PAT_MATCH_STR },
3710 { "ssl_c_serial", NULL, PAT_MATCH_BIN },
3711 { "ssl_f_i_dn", NULL, PAT_MATCH_STR },
3712 { "ssl_f_key_alg", NULL, PAT_MATCH_STR },
3713 { "ssl_f_notafter", NULL, PAT_MATCH_STR },
3714 { "ssl_f_notbefore", NULL, PAT_MATCH_STR },
3715 { "ssl_f_sig_alg", NULL, PAT_MATCH_STR },
3716 { "ssl_f_s_dn", NULL, PAT_MATCH_STR },
3717 { "ssl_f_serial", NULL, PAT_MATCH_BIN },
3718 { "ssl_fc_cipher", NULL, PAT_MATCH_STR },
Willy Tarreaua33c6542012-10-15 13:19:06 +02003719#ifdef OPENSSL_NPN_NEGOTIATED
Thierry FOURNIERc5a4e982014-03-05 16:07:08 +01003720 { "ssl_fc_npn", NULL, PAT_MATCH_STR },
Willy Tarreaua33c6542012-10-15 13:19:06 +02003721#endif
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01003722#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Thierry FOURNIERc5a4e982014-03-05 16:07:08 +01003723 { "ssl_fc_alpn", NULL, PAT_MATCH_STR },
Willy Tarreauab861d32013-04-02 02:30:41 +02003724#endif
Thierry FOURNIERc5a4e982014-03-05 16:07:08 +01003725 { "ssl_fc_protocol", NULL, PAT_MATCH_STR },
3726 { "ssl_fc_sni", "ssl_fc_sni", PAT_MATCH_STR },
3727 { "ssl_fc_sni_end", "ssl_fc_sni", PAT_MATCH_END },
3728 { "ssl_fc_sni_reg", "ssl_fc_sni", PAT_MATCH_REG },
Willy Tarreau8ed669b2013-01-11 15:49:37 +01003729 { /* END */ },
Willy Tarreau7875d092012-09-10 08:20:03 +02003730}};
3731
Willy Tarreau79eeafa2012-09-14 07:53:05 +02003732/* Note: must not be declared <const> as its list will be overwritten.
3733 * Please take care of keeping this list alphabetically sorted, doing so helps
3734 * all code contributors.
3735 * Optional keywords are also declared with a NULL ->parse() function so that
3736 * the config parser can report an appropriate error when a known keyword was
3737 * not enabled.
3738 */
Willy Tarreau51fb7652012-09-18 18:24:39 +02003739static struct bind_kw_list bind_kws = { "SSL", { }, {
Willy Tarreauab861d32013-04-02 02:30:41 +02003740 { "alpn", bind_parse_alpn, 1 }, /* set ALPN supported protocols */
Emeric Brunfb510ea2012-10-05 12:00:26 +02003741 { "ca-file", bind_parse_ca_file, 1 }, /* set CAfile to process verify on client cert */
Emeric Brun2d0c4822012-10-02 13:45:20 +02003742 { "ca-ignore-err", bind_parse_ignore_err, 1 }, /* set error IDs to ignore on verify depth > 0 */
3743 { "ciphers", bind_parse_ciphers, 1 }, /* set SSL cipher suite */
Emeric Brunfb510ea2012-10-05 12:00:26 +02003744 { "crl-file", bind_parse_crl_file, 1 }, /* set certificat revocation list file use on client cert verify */
Emeric Brun2d0c4822012-10-02 13:45:20 +02003745 { "crt", bind_parse_crt, 1 }, /* load SSL certificates from this location */
3746 { "crt-ignore-err", bind_parse_ignore_err, 1 }, /* set error IDs to ingore on verify depth == 0 */
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01003747 { "crt-list", bind_parse_crt_list, 1 }, /* load a list of crt from this location */
Emeric Brun2d0c4822012-10-02 13:45:20 +02003748 { "ecdhe", bind_parse_ecdhe, 1 }, /* defines named curve for elliptic curve Diffie-Hellman */
Emeric Brun2cb7ae52012-10-05 14:14:21 +02003749 { "force-sslv3", bind_parse_force_sslv3, 0 }, /* force SSLv3 */
3750 { "force-tlsv10", bind_parse_force_tlsv10, 0 }, /* force TLSv10 */
3751 { "force-tlsv11", bind_parse_force_tlsv11, 0 }, /* force TLSv11 */
3752 { "force-tlsv12", bind_parse_force_tlsv12, 0 }, /* force TLSv12 */
Emeric Brun9b3009b2012-10-05 11:55:06 +02003753 { "no-sslv3", bind_parse_no_sslv3, 0 }, /* disable SSLv3 */
3754 { "no-tlsv10", bind_parse_no_tlsv10, 0 }, /* disable TLSv10 */
3755 { "no-tlsv11", bind_parse_no_tlsv11, 0 }, /* disable TLSv11 */
3756 { "no-tlsv12", bind_parse_no_tlsv12, 0 }, /* disable TLSv12 */
Emeric Brun2d0c4822012-10-02 13:45:20 +02003757 { "no-tls-tickets", bind_parse_no_tls_tickets, 0 }, /* disable session resumption tickets */
Emeric Brun2d0c4822012-10-02 13:45:20 +02003758 { "ssl", bind_parse_ssl, 0 }, /* enable SSL processing */
Emmanuel Hocdet65623372013-01-24 17:17:15 +01003759 { "strict-sni", bind_parse_strict_sni, 0 }, /* refuse negotiation if sni doesn't match a certificate */
Emeric Brun2d0c4822012-10-02 13:45:20 +02003760 { "verify", bind_parse_verify, 1 }, /* set SSL verify method */
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02003761 { "npn", bind_parse_npn, 1 }, /* set NPN supported protocols */
Willy Tarreau79eeafa2012-09-14 07:53:05 +02003762 { NULL, NULL, 0 },
3763}};
Emeric Brun46591952012-05-18 15:47:34 +02003764
Willy Tarreau92faadf2012-10-10 23:04:25 +02003765/* Note: must not be declared <const> as its list will be overwritten.
3766 * Please take care of keeping this list alphabetically sorted, doing so helps
3767 * all code contributors.
3768 * Optional keywords are also declared with a NULL ->parse() function so that
3769 * the config parser can report an appropriate error when a known keyword was
3770 * not enabled.
3771 */
3772static struct srv_kw_list srv_kws = { "SSL", { }, {
Emeric Brunef42d922012-10-11 16:11:36 +02003773 { "ca-file", srv_parse_ca_file, 1, 0 }, /* set CAfile to process verify server cert */
Emeric Brunecc91fe2012-10-11 15:05:10 +02003774 { "check-ssl", srv_parse_check_ssl, 0, 0 }, /* enable SSL for health checks */
3775 { "ciphers", srv_parse_ciphers, 1, 0 }, /* select the cipher suite */
Emeric Brunef42d922012-10-11 16:11:36 +02003776 { "crl-file", srv_parse_crl_file, 1, 0 }, /* set certificate revocation list file use on server cert verify */
Emeric Bruna7aa3092012-10-26 12:58:00 +02003777 { "crt", srv_parse_crt, 1, 0 }, /* set client certificate */
Emeric Brunecc91fe2012-10-11 15:05:10 +02003778 { "force-sslv3", srv_parse_force_sslv3, 0, 0 }, /* force SSLv3 */
3779 { "force-tlsv10", srv_parse_force_tlsv10, 0, 0 }, /* force TLSv10 */
3780 { "force-tlsv11", srv_parse_force_tlsv11, 0, 0 }, /* force TLSv11 */
3781 { "force-tlsv12", srv_parse_force_tlsv12, 0, 0 }, /* force TLSv12 */
3782 { "no-sslv3", srv_parse_no_sslv3, 0, 0 }, /* disable SSLv3 */
3783 { "no-tlsv10", srv_parse_no_tlsv10, 0, 0 }, /* disable TLSv10 */
3784 { "no-tlsv11", srv_parse_no_tlsv11, 0, 0 }, /* disable TLSv11 */
3785 { "no-tlsv12", srv_parse_no_tlsv12, 0, 0 }, /* disable TLSv12 */
Emeric Brunf9c5c472012-10-11 15:28:34 +02003786 { "no-tls-tickets", srv_parse_no_tls_tickets, 0, 0 }, /* disable session resumption tickets */
Emeric Brunecc91fe2012-10-11 15:05:10 +02003787 { "ssl", srv_parse_ssl, 0, 0 }, /* enable SSL processing */
Emeric Brunef42d922012-10-11 16:11:36 +02003788 { "verify", srv_parse_verify, 1, 0 }, /* set SSL verify method */
Evan Broderbe554312013-06-27 00:05:25 -07003789 { "verifyhost", srv_parse_verifyhost, 1, 0 }, /* require that SSL cert verifies for hostname */
Willy Tarreau92faadf2012-10-10 23:04:25 +02003790 { NULL, NULL, 0, 0 },
3791}};
3792
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02003793/* transport-layer operations for SSL sockets */
3794struct xprt_ops ssl_sock = {
Emeric Brun46591952012-05-18 15:47:34 +02003795 .snd_buf = ssl_sock_from_buf,
3796 .rcv_buf = ssl_sock_to_buf,
3797 .rcv_pipe = NULL,
3798 .snd_pipe = NULL,
3799 .shutr = NULL,
3800 .shutw = ssl_sock_shutw,
3801 .close = ssl_sock_close,
3802 .init = ssl_sock_init,
3803};
3804
3805__attribute__((constructor))
Willy Tarreau92faadf2012-10-10 23:04:25 +02003806static void __ssl_sock_init(void)
3807{
Emeric Brun46591952012-05-18 15:47:34 +02003808 STACK_OF(SSL_COMP)* cm;
3809
Willy Tarreau610f04b2014-02-13 11:36:41 +01003810#ifdef LISTEN_DEFAULT_CIPHERS
3811 global.listen_default_ciphers = LISTEN_DEFAULT_CIPHERS;
3812#endif
3813#ifdef CONNECT_DEFAULT_CIPHERS
3814 global.connect_default_ciphers = CONNECT_DEFAULT_CIPHERS;
3815#endif
3816 if (global.listen_default_ciphers)
3817 global.listen_default_ciphers = strdup(global.listen_default_ciphers);
3818 if (global.connect_default_ciphers)
3819 global.connect_default_ciphers = strdup(global.connect_default_ciphers);
3820
Emeric Brun46591952012-05-18 15:47:34 +02003821 SSL_library_init();
3822 cm = SSL_COMP_get_compression_methods();
3823 sk_SSL_COMP_zero(cm);
Willy Tarreau7875d092012-09-10 08:20:03 +02003824 sample_register_fetches(&sample_fetch_keywords);
3825 acl_register_keywords(&acl_kws);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02003826 bind_register_keywords(&bind_kws);
Willy Tarreau92faadf2012-10-10 23:04:25 +02003827 srv_register_keywords(&srv_kws);
Emeric Brun46591952012-05-18 15:47:34 +02003828}
3829
3830/*
3831 * Local variables:
3832 * c-indent-level: 8
3833 * c-basic-offset: 8
3834 * End:
3835 */