blob: 1e63c5703a672798ebf03eacda3639a48901c858 [file] [log] [blame]
yanbzhu08ce6ab2015-12-02 13:01:29 -05001
Emeric Brun46591952012-05-18 15:47:34 +02002/*
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02003 * SSL/TLS transport layer over SOCK_STREAM sockets
Emeric Brun46591952012-05-18 15:47:34 +02004 *
5 * Copyright (C) 2012 EXCELIANCE, Emeric Brun <ebrun@exceliance.fr>
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation; either version
10 * 2 of the License, or (at your option) any later version.
11 *
Willy Tarreau69845df2012-09-10 09:43:09 +020012 * Acknowledgement:
13 * We'd like to specially thank the Stud project authors for a very clean
14 * and well documented code which helped us understand how the OpenSSL API
15 * ought to be used in non-blocking mode. This is one difficult part which
16 * is not easy to get from the OpenSSL doc, and reading the Stud code made
17 * it much more obvious than the examples in the OpenSSL package. Keep up
18 * the good works, guys !
19 *
20 * Stud is an extremely efficient and scalable SSL/TLS proxy which combines
21 * particularly well with haproxy. For more info about this project, visit :
22 * https://github.com/bumptech/stud
23 *
Emeric Brun46591952012-05-18 15:47:34 +020024 */
25
26#define _GNU_SOURCE
Emeric Brunfc0421f2012-09-07 17:30:07 +020027#include <ctype.h>
28#include <dirent.h>
Emeric Brun46591952012-05-18 15:47:34 +020029#include <errno.h>
30#include <fcntl.h>
31#include <stdio.h>
32#include <stdlib.h>
Emeric Brunfc0421f2012-09-07 17:30:07 +020033#include <string.h>
34#include <unistd.h>
Emeric Brun46591952012-05-18 15:47:34 +020035
36#include <sys/socket.h>
37#include <sys/stat.h>
38#include <sys/types.h>
Christopher Faulet31af49d2015-06-09 17:29:50 +020039#include <netdb.h>
Emeric Brun46591952012-05-18 15:47:34 +020040#include <netinet/tcp.h>
41
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +020042#include <openssl/crypto.h>
Emeric Brun46591952012-05-18 15:47:34 +020043#include <openssl/ssl.h>
Emeric Brunfc0421f2012-09-07 17:30:07 +020044#include <openssl/x509.h>
45#include <openssl/x509v3.h>
46#include <openssl/x509.h>
47#include <openssl/err.h>
Thierry Fournier383085f2013-01-24 14:15:43 +010048#include <openssl/rand.h>
Lukas Tribuse4e30f72014-12-09 16:32:51 +010049#if (defined SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB && !defined OPENSSL_NO_OCSP)
Emeric Brun4147b2e2014-06-16 18:36:30 +020050#include <openssl/ocsp.h>
51#endif
Remi Gacogne4f902b82015-05-28 16:23:00 +020052#ifndef OPENSSL_NO_DH
53#include <openssl/dh.h>
54#endif
Emeric Brun46591952012-05-18 15:47:34 +020055
Christopher Faulet31af49d2015-06-09 17:29:50 +020056#include <import/lru.h>
57#include <import/xxhash.h>
58
Emeric Brun46591952012-05-18 15:47:34 +020059#include <common/buffer.h>
60#include <common/compat.h>
61#include <common/config.h>
62#include <common/debug.h>
Willy Tarreau79eeafa2012-09-14 07:53:05 +020063#include <common/errors.h>
Emeric Brun46591952012-05-18 15:47:34 +020064#include <common/standard.h>
65#include <common/ticks.h>
66#include <common/time.h>
Emeric Brun2c86cbf2014-10-30 15:56:50 +010067#include <common/cfgparse.h>
Nenad Merdanovic05552d42015-02-27 19:56:49 +010068#include <common/base64.h>
Emeric Brun46591952012-05-18 15:47:34 +020069
Emeric Brunfc0421f2012-09-07 17:30:07 +020070#include <ebsttree.h>
71
William Lallemand32af2032016-10-29 18:09:35 +020072#include <types/applet.h>
73#include <types/cli.h>
Emeric Brunfc0421f2012-09-07 17:30:07 +020074#include <types/global.h>
75#include <types/ssl_sock.h>
William Lallemand32af2032016-10-29 18:09:35 +020076#include <types/stats.h>
Emeric Brunfc0421f2012-09-07 17:30:07 +020077
Willy Tarreau7875d092012-09-10 08:20:03 +020078#include <proto/acl.h>
79#include <proto/arg.h>
William Lallemand32af2032016-10-29 18:09:35 +020080#include <proto/channel.h>
Emeric Brun46591952012-05-18 15:47:34 +020081#include <proto/connection.h>
William Lallemand32af2032016-10-29 18:09:35 +020082#include <proto/cli.h>
Emeric Brun46591952012-05-18 15:47:34 +020083#include <proto/fd.h>
84#include <proto/freq_ctr.h>
85#include <proto/frontend.h>
Willy Tarreau79eeafa2012-09-14 07:53:05 +020086#include <proto/listener.h>
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +020087#include <proto/openssl-compat.h>
Thierry FOURNIERed66c292013-11-28 11:05:19 +010088#include <proto/pattern.h>
Christopher Faulet31af49d2015-06-09 17:29:50 +020089#include <proto/proto_tcp.h>
Willy Tarreau92faadf2012-10-10 23:04:25 +020090#include <proto/server.h>
William Lallemand32af2032016-10-29 18:09:35 +020091#include <proto/stream_interface.h>
Emeric Brun46591952012-05-18 15:47:34 +020092#include <proto/log.h>
Emeric Brun94324a42012-10-11 14:00:19 +020093#include <proto/proxy.h>
Emeric Brunfc0421f2012-09-07 17:30:07 +020094#include <proto/shctx.h>
Emeric Brun46591952012-05-18 15:47:34 +020095#include <proto/ssl_sock.h>
Willy Tarreau9ad7bd42015-04-03 19:19:59 +020096#include <proto/stream.h>
Emeric Brun46591952012-05-18 15:47:34 +020097#include <proto/task.h>
98
Willy Tarreau518cedd2014-02-17 15:43:01 +010099/* Warning, these are bits, not integers! */
Emeric Brune64aef12012-09-21 13:15:06 +0200100#define SSL_SOCK_ST_FL_VERIFY_DONE 0x00000001
Emeric Brund8b2bb52014-01-28 15:43:53 +0100101#define SSL_SOCK_ST_FL_16K_WBFSIZE 0x00000002
Willy Tarreau518cedd2014-02-17 15:43:01 +0100102#define SSL_SOCK_SEND_UNLIMITED 0x00000004
Emeric Brun29f037d2014-04-25 19:05:36 +0200103#define SSL_SOCK_RECV_HEARTBEAT 0x00000008
104
Emeric Brunf282a812012-09-21 15:27:54 +0200105/* bits 0xFFFF0000 are reserved to store verify errors */
106
107/* Verify errors macros */
108#define SSL_SOCK_CA_ERROR_TO_ST(e) (((e > 63) ? 63 : e) << (16))
109#define SSL_SOCK_CAEDEPTH_TO_ST(d) (((d > 15) ? 15 : d) << (6+16))
110#define SSL_SOCK_CRTERROR_TO_ST(e) (((e > 63) ? 63 : e) << (4+6+16))
111
112#define SSL_SOCK_ST_TO_CA_ERROR(s) ((s >> (16)) & 63)
113#define SSL_SOCK_ST_TO_CAEDEPTH(s) ((s >> (6+16)) & 15)
114#define SSL_SOCK_ST_TO_CRTERROR(s) ((s >> (4+6+16)) & 63)
Emeric Brune64aef12012-09-21 13:15:06 +0200115
Nenad Merdanovic05552d42015-02-27 19:56:49 +0100116/* Supported hash function for TLS tickets */
117#ifdef OPENSSL_NO_SHA256
118#define HASH_FUNCT EVP_sha1
119#else
120#define HASH_FUNCT EVP_sha256
121#endif /* OPENSSL_NO_SHA256 */
122
Emeric Brun850efd52014-01-29 12:24:34 +0100123/* server and bind verify method, it uses a global value as default */
124enum {
125 SSL_SOCK_VERIFY_DEFAULT = 0,
126 SSL_SOCK_VERIFY_REQUIRED = 1,
127 SSL_SOCK_VERIFY_OPTIONAL = 2,
128 SSL_SOCK_VERIFY_NONE = 3,
129};
130
Willy Tarreau71b734c2014-01-28 15:19:44 +0100131int sslconns = 0;
132int totalsslconns = 0;
Willy Tarreaud9f5cca2016-12-22 21:08:52 +0100133static struct xprt_ops ssl_sock;
Emeric Brune1f38db2012-09-03 20:36:47 +0200134
Willy Tarreauef934602016-12-22 23:12:01 +0100135static struct {
136 char *crt_base; /* base directory path for certificates */
137 char *ca_base; /* base directory path for CAs and CRLs */
138
139 char *listen_default_ciphers;
140 char *connect_default_ciphers;
141 int listen_default_ssloptions;
142 int connect_default_ssloptions;
143
144 int private_cache; /* Force to use a private session cache even if nbproc > 1 */
145 unsigned int life_time; /* SSL session lifetime in seconds */
146 unsigned int max_record; /* SSL max record size */
147 unsigned int default_dh_param; /* SSL maximum DH parameter size */
148 int ctx_cache; /* max number of entries in the ssl_ctx cache. */
Thierry FOURNIER5bf77322017-02-25 12:45:22 +0100149 int capture_cipherlist; /* Size of the cipherlist buffer. */
Willy Tarreauef934602016-12-22 23:12:01 +0100150} global_ssl = {
151#ifdef LISTEN_DEFAULT_CIPHERS
152 .listen_default_ciphers = LISTEN_DEFAULT_CIPHERS,
153#endif
154#ifdef CONNECT_DEFAULT_CIPHERS
155 .connect_default_ciphers = CONNECT_DEFAULT_CIPHERS,
156#endif
157 .listen_default_ssloptions = BC_SSL_O_NONE,
158 .connect_default_ssloptions = SRV_SSL_O_NONE,
159
160#ifdef DEFAULT_SSL_MAX_RECORD
161 .max_record = DEFAULT_SSL_MAX_RECORD,
162#endif
163 .default_dh_param = SSL_DEFAULT_DH_PARAM,
164 .ctx_cache = DEFAULT_SSL_CTX_CACHE,
Thierry FOURNIER5bf77322017-02-25 12:45:22 +0100165 .capture_cipherlist = 0,
Willy Tarreauef934602016-12-22 23:12:01 +0100166};
167
Emmanuel Hocdetaaee7502017-03-07 18:34:58 +0100168/* This memory pool is used for capturing clienthello parameters. */
Thierry FOURNIER5bf77322017-02-25 12:45:22 +0100169struct ssl_capture {
Thierry FOURNIER5bf77322017-02-25 12:45:22 +0100170 unsigned long long int xxh64;
171 unsigned char ciphersuite_len;
172 char ciphersuite[0];
173};
174struct pool_head *pool2_ssl_capture = NULL;
Emmanuel Hocdetaaee7502017-03-07 18:34:58 +0100175static int ssl_capture_ptr_index = -1;
Willy Tarreauef934602016-12-22 23:12:01 +0100176
Nenad Merdanovic200b0fa2015-05-09 08:46:01 +0200177#if (defined SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB && TLS_TICKETS_NO > 0)
178struct list tlskeys_reference = LIST_HEAD_INIT(tlskeys_reference);
179#endif
180
Remi Gacogne8de54152014-07-15 11:36:40 +0200181#ifndef OPENSSL_NO_DH
Remi Gacogne4f902b82015-05-28 16:23:00 +0200182static int ssl_dh_ptr_index = -1;
Remi Gacogne47783ef2015-05-29 15:53:22 +0200183static DH *global_dh = NULL;
Remi Gacogne8de54152014-07-15 11:36:40 +0200184static DH *local_dh_1024 = NULL;
185static DH *local_dh_2048 = NULL;
186static DH *local_dh_4096 = NULL;
Emmanuel Hocdetcc6c2a22017-03-03 17:04:14 +0100187static DH *ssl_get_tmp_dh(SSL *ssl, int export, int keylen);
Remi Gacogne8de54152014-07-15 11:36:40 +0200188#endif /* OPENSSL_NO_DH */
189
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +0100190#if (defined SSL_CTRL_SET_TLSEXT_HOSTNAME && !defined SSL_NO_GENERATE_CERTIFICATES)
Christopher Faulet31af49d2015-06-09 17:29:50 +0200191/* X509V3 Extensions that will be added on generated certificates */
192#define X509V3_EXT_SIZE 5
193static char *x509v3_ext_names[X509V3_EXT_SIZE] = {
194 "basicConstraints",
195 "nsComment",
196 "subjectKeyIdentifier",
197 "authorityKeyIdentifier",
198 "keyUsage",
199};
200static char *x509v3_ext_values[X509V3_EXT_SIZE] = {
201 "CA:FALSE",
202 "\"OpenSSL Generated Certificate\"",
203 "hash",
204 "keyid,issuer:always",
205 "nonRepudiation,digitalSignature,keyEncipherment"
206};
Christopher Faulet31af49d2015-06-09 17:29:50 +0200207/* LRU cache to store generated certificate */
208static struct lru64_head *ssl_ctx_lru_tree = NULL;
209static unsigned int ssl_ctx_lru_seed = 0;
Willy Tarreauc8ad3be2015-06-17 15:48:26 +0200210#endif // SSL_CTRL_SET_TLSEXT_HOSTNAME
211
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +0100212static struct ssl_bind_kw ssl_bind_kws[];
213
yanbzhube2774d2015-12-10 15:07:30 -0500214#if OPENSSL_VERSION_NUMBER >= 0x1000200fL
215/* The order here matters for picking a default context,
216 * keep the most common keytype at the bottom of the list
217 */
218const char *SSL_SOCK_KEYTYPE_NAMES[] = {
219 "dsa",
220 "ecdsa",
221 "rsa"
222};
223#define SSL_SOCK_NUM_KEYTYPES 3
Willy Tarreau30da7ad2015-12-14 11:28:33 +0100224#else
225#define SSL_SOCK_NUM_KEYTYPES 1
yanbzhube2774d2015-12-10 15:07:30 -0500226#endif
227
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +0100228/*
229 * This function gives the detail of the SSL error. It is used only
230 * if the debug mode and the verbose mode are activated. It dump all
231 * the SSL error until the stack was empty.
232 */
233static forceinline void ssl_sock_dump_errors(struct connection *conn)
234{
235 unsigned long ret;
236
237 if (unlikely(global.mode & MODE_DEBUG)) {
238 while(1) {
239 ret = ERR_get_error();
240 if (ret == 0)
241 return;
242 fprintf(stderr, "fd[%04x] OpenSSL error[0x%lx] %s: %s\n",
243 (unsigned short)conn->t.sock.fd, ret,
244 ERR_func_error_string(ret), ERR_reason_error_string(ret));
245 }
246 }
247}
248
Willy Tarreauc8ad3be2015-06-17 15:48:26 +0200249#if (defined SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB && !defined OPENSSL_NO_OCSP)
yanbzhube2774d2015-12-10 15:07:30 -0500250/*
251 * struct alignment works here such that the key.key is the same as key_data
252 * Do not change the placement of key_data
253 */
Willy Tarreauc8ad3be2015-06-17 15:48:26 +0200254struct certificate_ocsp {
255 struct ebmb_node key;
256 unsigned char key_data[OCSP_MAX_CERTID_ASN1_LENGTH];
257 struct chunk response;
258 long expire;
259};
Christopher Faulet31af49d2015-06-09 17:29:50 +0200260
yanbzhube2774d2015-12-10 15:07:30 -0500261struct ocsp_cbk_arg {
262 int is_single;
263 int single_kt;
264 union {
265 struct certificate_ocsp *s_ocsp;
266 /*
267 * m_ocsp will have multiple entries dependent on key type
268 * Entry 0 - DSA
269 * Entry 1 - ECDSA
270 * Entry 2 - RSA
271 */
272 struct certificate_ocsp *m_ocsp[SSL_SOCK_NUM_KEYTYPES];
273 };
274};
275
Emeric Brun4f3c87a2014-06-20 15:46:13 +0200276/*
277 * This function returns the number of seconds elapsed
278 * since the Epoch, 1970-01-01 00:00:00 +0000 (UTC) and the
279 * date presented un ASN1_GENERALIZEDTIME.
280 *
281 * In parsing error case, it returns -1.
282 */
283static long asn1_generalizedtime_to_epoch(ASN1_GENERALIZEDTIME *d)
284{
285 long epoch;
286 char *p, *end;
287 const unsigned short month_offset[12] = {
288 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334
289 };
290 int year, month;
291
292 if (!d || (d->type != V_ASN1_GENERALIZEDTIME)) return -1;
293
294 p = (char *)d->data;
295 end = p + d->length;
296
297 if (end - p < 4) return -1;
298 year = 1000 * (p[0] - '0') + 100 * (p[1] - '0') + 10 * (p[2] - '0') + p[3] - '0';
299 p += 4;
300 if (end - p < 2) return -1;
301 month = 10 * (p[0] - '0') + p[1] - '0';
302 if (month < 1 || month > 12) return -1;
303 /* Compute the number of seconds since 1 jan 1970 and the beginning of current month
304 We consider leap years and the current month (<marsh or not) */
305 epoch = ( ((year - 1970) * 365)
306 + ((year - (month < 3)) / 4 - (year - (month < 3)) / 100 + (year - (month < 3)) / 400)
307 - ((1970 - 1) / 4 - (1970 - 1) / 100 + (1970 - 1) / 400)
308 + month_offset[month-1]
309 ) * 24 * 60 * 60;
310 p += 2;
311 if (end - p < 2) return -1;
312 /* Add the number of seconds of completed days of current month */
313 epoch += (10 * (p[0] - '0') + p[1] - '0' - 1) * 24 * 60 * 60;
314 p += 2;
315 if (end - p < 2) return -1;
316 /* Add the completed hours of the current day */
317 epoch += (10 * (p[0] - '0') + p[1] - '0') * 60 * 60;
318 p += 2;
319 if (end - p < 2) return -1;
320 /* Add the completed minutes of the current hour */
321 epoch += (10 * (p[0] - '0') + p[1] - '0') * 60;
322 p += 2;
323 if (p == end) return -1;
324 /* Test if there is available seconds */
325 if (p[0] < '0' || p[0] > '9')
326 goto nosec;
327 if (end - p < 2) return -1;
328 /* Add the seconds of the current minute */
329 epoch += 10 * (p[0] - '0') + p[1] - '0';
330 p += 2;
331 if (p == end) return -1;
332 /* Ignore seconds float part if present */
333 if (p[0] == '.') {
334 do {
335 if (++p == end) return -1;
336 } while (p[0] >= '0' && p[0] <= '9');
337 }
338
339nosec:
340 if (p[0] == 'Z') {
341 if (end - p != 1) return -1;
342 return epoch;
343 }
344 else if (p[0] == '+') {
345 if (end - p != 5) return -1;
346 /* Apply timezone offset */
347 return epoch - ((10 * (p[1] - '0') + p[2] - '0') * 60 + (10 * (p[3] - '0') + p[4] - '0')) * 60;
348 }
349 else if (p[0] == '-') {
350 if (end - p != 5) return -1;
351 /* Apply timezone offset */
352 return epoch + ((10 * (p[1] - '0') + p[2] - '0') * 60 + (10 * (p[3] - '0') + p[4] - '0')) * 60;
353 }
354
355 return -1;
356}
357
Emeric Brun1d3865b2014-06-20 15:37:32 +0200358static struct eb_root cert_ocsp_tree = EB_ROOT_UNIQUE;
Emeric Brun4147b2e2014-06-16 18:36:30 +0200359
360/* This function starts to check if the OCSP response (in DER format) contained
361 * in chunk 'ocsp_response' is valid (else exits on error).
362 * If 'cid' is not NULL, it will be compared to the OCSP certificate ID
363 * contained in the OCSP Response and exits on error if no match.
364 * If it's a valid OCSP Response:
365 * If 'ocsp' is not NULL, the chunk is copied in the OCSP response's container
366 * pointed by 'ocsp'.
367 * If 'ocsp' is NULL, the function looks up into the OCSP response's
368 * containers tree (using as index the ASN1 form of the OCSP Certificate ID extracted
369 * from the response) and exits on error if not found. Finally, If an OCSP response is
370 * already present in the container, it will be overwritten.
371 *
372 * Note: OCSP response containing more than one OCSP Single response is not
373 * considered valid.
374 *
375 * Returns 0 on success, 1 in error case.
376 */
377static int ssl_sock_load_ocsp_response(struct chunk *ocsp_response, struct certificate_ocsp *ocsp, OCSP_CERTID *cid, char **err)
378{
379 OCSP_RESPONSE *resp;
380 OCSP_BASICRESP *bs = NULL;
381 OCSP_SINGLERESP *sr;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +0200382 OCSP_CERTID *id;
Emeric Brun4147b2e2014-06-16 18:36:30 +0200383 unsigned char *p = (unsigned char *)ocsp_response->str;
384 int rc , count_sr;
Emeric Brun13a6b482014-06-20 15:44:34 +0200385 ASN1_GENERALIZEDTIME *revtime, *thisupd, *nextupd = NULL;
Emeric Brun4147b2e2014-06-16 18:36:30 +0200386 int reason;
387 int ret = 1;
388
389 resp = d2i_OCSP_RESPONSE(NULL, (const unsigned char **)&p, ocsp_response->len);
390 if (!resp) {
391 memprintf(err, "Unable to parse OCSP response");
392 goto out;
393 }
394
395 rc = OCSP_response_status(resp);
396 if (rc != OCSP_RESPONSE_STATUS_SUCCESSFUL) {
397 memprintf(err, "OCSP response status not successful");
398 goto out;
399 }
400
401 bs = OCSP_response_get1_basic(resp);
402 if (!bs) {
403 memprintf(err, "Failed to get basic response from OCSP Response");
404 goto out;
405 }
406
407 count_sr = OCSP_resp_count(bs);
408 if (count_sr > 1) {
409 memprintf(err, "OCSP response ignored because contains multiple single responses (%d)", count_sr);
410 goto out;
411 }
412
413 sr = OCSP_resp_get0(bs, 0);
414 if (!sr) {
415 memprintf(err, "Failed to get OCSP single response");
416 goto out;
417 }
418
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +0200419 id = (OCSP_CERTID*)OCSP_SINGLERESP_get0_id(sr);
420
Emeric Brun4147b2e2014-06-16 18:36:30 +0200421 rc = OCSP_single_get0_status(sr, &reason, &revtime, &thisupd, &nextupd);
422 if (rc != V_OCSP_CERTSTATUS_GOOD) {
423 memprintf(err, "OCSP single response: certificate status not good");
424 goto out;
425 }
426
Emeric Brun13a6b482014-06-20 15:44:34 +0200427 if (!nextupd) {
428 memprintf(err, "OCSP single response: missing nextupdate");
429 goto out;
430 }
431
Emeric Brunc8b27b62014-06-19 14:16:17 +0200432 rc = OCSP_check_validity(thisupd, nextupd, OCSP_MAX_RESPONSE_TIME_SKEW, -1);
Emeric Brun4147b2e2014-06-16 18:36:30 +0200433 if (!rc) {
434 memprintf(err, "OCSP single response: no longer valid.");
435 goto out;
436 }
437
438 if (cid) {
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +0200439 if (OCSP_id_cmp(id, cid)) {
Emeric Brun4147b2e2014-06-16 18:36:30 +0200440 memprintf(err, "OCSP single response: Certificate ID does not match certificate and issuer");
441 goto out;
442 }
443 }
444
445 if (!ocsp) {
446 unsigned char key[OCSP_MAX_CERTID_ASN1_LENGTH];
447 unsigned char *p;
448
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +0200449 rc = i2d_OCSP_CERTID(id, NULL);
Emeric Brun4147b2e2014-06-16 18:36:30 +0200450 if (!rc) {
451 memprintf(err, "OCSP single response: Unable to encode Certificate ID");
452 goto out;
453 }
454
455 if (rc > OCSP_MAX_CERTID_ASN1_LENGTH) {
456 memprintf(err, "OCSP single response: Certificate ID too long");
457 goto out;
458 }
459
460 p = key;
461 memset(key, 0, OCSP_MAX_CERTID_ASN1_LENGTH);
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +0200462 i2d_OCSP_CERTID(id, &p);
Emeric Brun4147b2e2014-06-16 18:36:30 +0200463 ocsp = (struct certificate_ocsp *)ebmb_lookup(&cert_ocsp_tree, key, OCSP_MAX_CERTID_ASN1_LENGTH);
464 if (!ocsp) {
465 memprintf(err, "OCSP single response: Certificate ID does not match any certificate or issuer");
466 goto out;
467 }
468 }
469
470 /* According to comments on "chunk_dup", the
471 previous chunk buffer will be freed */
472 if (!chunk_dup(&ocsp->response, ocsp_response)) {
473 memprintf(err, "OCSP response: Memory allocation error");
474 goto out;
475 }
476
Emeric Brun4f3c87a2014-06-20 15:46:13 +0200477 ocsp->expire = asn1_generalizedtime_to_epoch(nextupd) - OCSP_MAX_RESPONSE_TIME_SKEW;
478
Emeric Brun4147b2e2014-06-16 18:36:30 +0200479 ret = 0;
480out:
Janusz Dziemidowicz8d710492017-03-08 16:59:41 +0100481 ERR_clear_error();
482
Emeric Brun4147b2e2014-06-16 18:36:30 +0200483 if (bs)
484 OCSP_BASICRESP_free(bs);
485
486 if (resp)
487 OCSP_RESPONSE_free(resp);
488
489 return ret;
490}
491/*
492 * External function use to update the OCSP response in the OCSP response's
493 * containers tree. The chunk 'ocsp_response' must contain the OCSP response
494 * to update in DER format.
495 *
496 * Returns 0 on success, 1 in error case.
497 */
498int ssl_sock_update_ocsp_response(struct chunk *ocsp_response, char **err)
499{
500 return ssl_sock_load_ocsp_response(ocsp_response, NULL, NULL, err);
501}
502
503/*
504 * This function load the OCSP Resonse in DER format contained in file at
505 * path 'ocsp_path' and call 'ssl_sock_load_ocsp_response'
506 *
507 * Returns 0 on success, 1 in error case.
508 */
509static int ssl_sock_load_ocsp_response_from_file(const char *ocsp_path, struct certificate_ocsp *ocsp, OCSP_CERTID *cid, char **err)
510{
511 int fd = -1;
512 int r = 0;
513 int ret = 1;
514
515 fd = open(ocsp_path, O_RDONLY);
516 if (fd == -1) {
517 memprintf(err, "Error opening OCSP response file");
518 goto end;
519 }
520
521 trash.len = 0;
522 while (trash.len < trash.size) {
523 r = read(fd, trash.str + trash.len, trash.size - trash.len);
524 if (r < 0) {
525 if (errno == EINTR)
526 continue;
527
528 memprintf(err, "Error reading OCSP response from file");
529 goto end;
530 }
531 else if (r == 0) {
532 break;
533 }
534 trash.len += r;
535 }
536
537 close(fd);
538 fd = -1;
539
540 ret = ssl_sock_load_ocsp_response(&trash, ocsp, cid, err);
541end:
542 if (fd != -1)
543 close(fd);
544
545 return ret;
546}
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +0100547#endif
Emeric Brun4147b2e2014-06-16 18:36:30 +0200548
Nenad Merdanovic05552d42015-02-27 19:56:49 +0100549#if (defined SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB && TLS_TICKETS_NO > 0)
550static int ssl_tlsext_ticket_key_cb(SSL *s, unsigned char key_name[16], unsigned char *iv, EVP_CIPHER_CTX *ectx, HMAC_CTX *hctx, int enc)
551{
552 struct tls_sess_key *keys;
553 struct connection *conn;
554 int head;
555 int i;
556
Vincent Bernat3c2f2f22016-04-03 13:48:42 +0200557 conn = SSL_get_app_data(s);
Nenad Merdanovic146defa2015-05-09 08:46:00 +0200558 keys = objt_listener(conn->target)->bind_conf->keys_ref->tlskeys;
559 head = objt_listener(conn->target)->bind_conf->keys_ref->tls_ticket_enc_index;
Nenad Merdanovic05552d42015-02-27 19:56:49 +0100560
561 if (enc) {
562 memcpy(key_name, keys[head].name, 16);
563
564 if(!RAND_pseudo_bytes(iv, EVP_MAX_IV_LENGTH))
565 return -1;
566
567 if(!EVP_EncryptInit_ex(ectx, EVP_aes_128_cbc(), NULL, keys[head].aes_key, iv))
568 return -1;
569
570 HMAC_Init_ex(hctx, keys[head].hmac_key, 16, HASH_FUNCT(), NULL);
571
572 return 1;
573 } else {
574 for (i = 0; i < TLS_TICKETS_NO; i++) {
575 if (!memcmp(key_name, keys[(head + i) % TLS_TICKETS_NO].name, 16))
576 goto found;
577 }
578 return 0;
579
580 found:
581 HMAC_Init_ex(hctx, keys[(head + i) % TLS_TICKETS_NO].hmac_key, 16, HASH_FUNCT(), NULL);
582 if(!EVP_DecryptInit_ex(ectx, EVP_aes_128_cbc(), NULL, keys[(head + i) % TLS_TICKETS_NO].aes_key, iv))
583 return -1;
584 /* 2 for key renewal, 1 if current key is still valid */
585 return i ? 2 : 1;
586 }
Nenad Merdanovic200b0fa2015-05-09 08:46:01 +0200587}
588
589struct tls_keys_ref *tlskeys_ref_lookup(const char *filename)
590{
591 struct tls_keys_ref *ref;
592
593 list_for_each_entry(ref, &tlskeys_reference, list)
594 if (ref->filename && strcmp(filename, ref->filename) == 0)
595 return ref;
596 return NULL;
597}
598
599struct tls_keys_ref *tlskeys_ref_lookupid(int unique_id)
600{
601 struct tls_keys_ref *ref;
602
603 list_for_each_entry(ref, &tlskeys_reference, list)
604 if (ref->unique_id == unique_id)
605 return ref;
606 return NULL;
607}
608
609int ssl_sock_update_tlskey(char *filename, struct chunk *tlskey, char **err) {
610 struct tls_keys_ref *ref = tlskeys_ref_lookup(filename);
611
612 if(!ref) {
613 memprintf(err, "Unable to locate the referenced filename: %s", filename);
614 return 1;
615 }
616
Pradeep Jindalcc79b002015-08-20 18:25:17 +0530617 memcpy((char *) (ref->tlskeys + ((ref->tls_ticket_enc_index + 2) % TLS_TICKETS_NO)), tlskey->str, tlskey->len);
618 ref->tls_ticket_enc_index = (ref->tls_ticket_enc_index + 1) % TLS_TICKETS_NO;
Nenad Merdanovic200b0fa2015-05-09 08:46:01 +0200619
620 return 0;
Nenad Merdanovic05552d42015-02-27 19:56:49 +0100621}
Nenad Merdanovic200b0fa2015-05-09 08:46:01 +0200622
623/* This function finalize the configuration parsing. Its set all the
Willy Tarreaud1c57502016-12-22 22:46:15 +0100624 * automatic ids. It's called just after the basic checks. It returns
625 * 0 on success otherwise ERR_*.
Nenad Merdanovic200b0fa2015-05-09 08:46:01 +0200626 */
Willy Tarreaud1c57502016-12-22 22:46:15 +0100627static int tlskeys_finalize_config(void)
Nenad Merdanovic200b0fa2015-05-09 08:46:01 +0200628{
629 int i = 0;
630 struct tls_keys_ref *ref, *ref2, *ref3;
631 struct list tkr = LIST_HEAD_INIT(tkr);
632
633 list_for_each_entry(ref, &tlskeys_reference, list) {
634 if (ref->unique_id == -1) {
635 /* Look for the first free id. */
636 while (1) {
637 list_for_each_entry(ref2, &tlskeys_reference, list) {
638 if (ref2->unique_id == i) {
639 i++;
640 break;
641 }
642 }
643 if (&ref2->list == &tlskeys_reference)
644 break;
645 }
646
647 /* Uses the unique id and increment it for the next entry. */
648 ref->unique_id = i;
649 i++;
650 }
651 }
652
653 /* This sort the reference list by id. */
654 list_for_each_entry_safe(ref, ref2, &tlskeys_reference, list) {
655 LIST_DEL(&ref->list);
656 list_for_each_entry(ref3, &tkr, list) {
657 if (ref->unique_id < ref3->unique_id) {
658 LIST_ADDQ(&ref3->list, &ref->list);
659 break;
660 }
661 }
662 if (&ref3->list == &tkr)
663 LIST_ADDQ(&tkr, &ref->list);
664 }
665
666 /* swap root */
667 LIST_ADD(&tkr, &tlskeys_reference);
668 LIST_DEL(&tkr);
Willy Tarreaud1c57502016-12-22 22:46:15 +0100669 return 0;
Nenad Merdanovic200b0fa2015-05-09 08:46:01 +0200670}
Nenad Merdanovic05552d42015-02-27 19:56:49 +0100671#endif /* SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB */
672
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +0100673#ifndef OPENSSL_NO_OCSP
yanbzhube2774d2015-12-10 15:07:30 -0500674int ssl_sock_get_ocsp_arg_kt_index(int evp_keytype)
675{
676 switch (evp_keytype) {
677 case EVP_PKEY_RSA:
678 return 2;
679 case EVP_PKEY_DSA:
680 return 0;
681 case EVP_PKEY_EC:
682 return 1;
683 }
684
685 return -1;
686}
687
Emeric Brun4147b2e2014-06-16 18:36:30 +0200688/*
689 * Callback used to set OCSP status extension content in server hello.
690 */
691int ssl_sock_ocsp_stapling_cbk(SSL *ssl, void *arg)
692{
yanbzhube2774d2015-12-10 15:07:30 -0500693 struct certificate_ocsp *ocsp;
694 struct ocsp_cbk_arg *ocsp_arg;
695 char *ssl_buf;
696 EVP_PKEY *ssl_pkey;
697 int key_type;
698 int index;
699
Vincent Bernat3c2f2f22016-04-03 13:48:42 +0200700 ocsp_arg = arg;
yanbzhube2774d2015-12-10 15:07:30 -0500701
702 ssl_pkey = SSL_get_privatekey(ssl);
703 if (!ssl_pkey)
704 return SSL_TLSEXT_ERR_NOACK;
705
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +0200706 key_type = EVP_PKEY_base_id(ssl_pkey);
yanbzhube2774d2015-12-10 15:07:30 -0500707
708 if (ocsp_arg->is_single && ocsp_arg->single_kt == key_type)
709 ocsp = ocsp_arg->s_ocsp;
710 else {
711 /* For multiple certs per context, we have to find the correct OCSP response based on
712 * the certificate type
713 */
714 index = ssl_sock_get_ocsp_arg_kt_index(key_type);
715
716 if (index < 0)
717 return SSL_TLSEXT_ERR_NOACK;
718
719 ocsp = ocsp_arg->m_ocsp[index];
720
721 }
Emeric Brun4147b2e2014-06-16 18:36:30 +0200722
723 if (!ocsp ||
724 !ocsp->response.str ||
Emeric Brun4f3c87a2014-06-20 15:46:13 +0200725 !ocsp->response.len ||
726 (ocsp->expire < now.tv_sec))
Emeric Brun4147b2e2014-06-16 18:36:30 +0200727 return SSL_TLSEXT_ERR_NOACK;
728
729 ssl_buf = OPENSSL_malloc(ocsp->response.len);
730 if (!ssl_buf)
731 return SSL_TLSEXT_ERR_NOACK;
732
733 memcpy(ssl_buf, ocsp->response.str, ocsp->response.len);
734 SSL_set_tlsext_status_ocsp_resp(ssl, ssl_buf, ocsp->response.len);
735
736 return SSL_TLSEXT_ERR_OK;
737}
738
739/*
740 * This function enables the handling of OCSP status extension on 'ctx' if a
741 * file name 'cert_path' suffixed using ".ocsp" is present.
742 * To enable OCSP status extension, the issuer's certificate is mandatory.
743 * It should be present in the certificate's extra chain builded from file
744 * 'cert_path'. If not found, the issuer certificate is loaded from a file
745 * named 'cert_path' suffixed using '.issuer'.
746 *
747 * In addition, ".ocsp" file content is loaded as a DER format of an OCSP
748 * response. If file is empty or content is not a valid OCSP response,
749 * OCSP status extension is enabled but OCSP response is ignored (a warning
750 * is displayed).
751 *
752 * Returns 1 if no ".ocsp" file found, 0 if OCSP status extension is
753 * succesfully enabled, or -1 in other error case.
754 */
755static int ssl_sock_load_ocsp(SSL_CTX *ctx, const char *cert_path)
756{
757
758 BIO *in = NULL;
759 X509 *x, *xi = NULL, *issuer = NULL;
760 STACK_OF(X509) *chain = NULL;
761 OCSP_CERTID *cid = NULL;
762 SSL *ssl;
763 char ocsp_path[MAXPATHLEN+1];
764 int i, ret = -1;
765 struct stat st;
766 struct certificate_ocsp *ocsp = NULL, *iocsp;
767 char *warn = NULL;
768 unsigned char *p;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +0200769 pem_password_cb *passwd_cb;
770 void *passwd_cb_userdata;
771 void (*callback) (void);
Emeric Brun4147b2e2014-06-16 18:36:30 +0200772
773 snprintf(ocsp_path, MAXPATHLEN+1, "%s.ocsp", cert_path);
774
775 if (stat(ocsp_path, &st))
776 return 1;
777
778 ssl = SSL_new(ctx);
779 if (!ssl)
780 goto out;
781
782 x = SSL_get_certificate(ssl);
783 if (!x)
784 goto out;
785
786 /* Try to lookup for issuer in certificate extra chain */
787#ifdef SSL_CTRL_GET_EXTRA_CHAIN_CERTS
788 SSL_CTX_get_extra_chain_certs(ctx, &chain);
789#else
790 chain = ctx->extra_certs;
791#endif
792 for (i = 0; i < sk_X509_num(chain); i++) {
793 issuer = sk_X509_value(chain, i);
794 if (X509_check_issued(issuer, x) == X509_V_OK)
795 break;
796 else
797 issuer = NULL;
798 }
799
800 /* If not found try to load issuer from a suffixed file */
801 if (!issuer) {
802 char issuer_path[MAXPATHLEN+1];
803
804 in = BIO_new(BIO_s_file());
805 if (!in)
806 goto out;
807
808 snprintf(issuer_path, MAXPATHLEN+1, "%s.issuer", cert_path);
809 if (BIO_read_filename(in, issuer_path) <= 0)
810 goto out;
811
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +0200812 passwd_cb = SSL_CTX_get_default_passwd_cb(ctx);
813 passwd_cb_userdata = SSL_CTX_get_default_passwd_cb_userdata(ctx);
814
815 xi = PEM_read_bio_X509_AUX(in, NULL, passwd_cb, passwd_cb_userdata);
Emeric Brun4147b2e2014-06-16 18:36:30 +0200816 if (!xi)
817 goto out;
818
819 if (X509_check_issued(xi, x) != X509_V_OK)
820 goto out;
821
822 issuer = xi;
823 }
824
825 cid = OCSP_cert_to_id(0, x, issuer);
826 if (!cid)
827 goto out;
828
829 i = i2d_OCSP_CERTID(cid, NULL);
830 if (!i || (i > OCSP_MAX_CERTID_ASN1_LENGTH))
831 goto out;
832
Vincent Bernat02779b62016-04-03 13:48:43 +0200833 ocsp = calloc(1, sizeof(*ocsp));
Emeric Brun4147b2e2014-06-16 18:36:30 +0200834 if (!ocsp)
835 goto out;
836
837 p = ocsp->key_data;
838 i2d_OCSP_CERTID(cid, &p);
839
840 iocsp = (struct certificate_ocsp *)ebmb_insert(&cert_ocsp_tree, &ocsp->key, OCSP_MAX_CERTID_ASN1_LENGTH);
841 if (iocsp == ocsp)
842 ocsp = NULL;
843
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +0200844#ifndef SSL_CTX_get_tlsext_status_cb
845# define SSL_CTX_get_tlsext_status_cb(ctx, cb) \
846 *cb = (void (*) (void))ctx->tlsext_status_cb;
847#endif
848 SSL_CTX_get_tlsext_status_cb(ctx, &callback);
849
850 if (!callback) {
Vincent Bernat02779b62016-04-03 13:48:43 +0200851 struct ocsp_cbk_arg *cb_arg = calloc(1, sizeof(*cb_arg));
Emmanuel Hocdetb7a4c342017-01-06 12:57:46 +0100852 EVP_PKEY *pkey;
yanbzhube2774d2015-12-10 15:07:30 -0500853
854 cb_arg->is_single = 1;
855 cb_arg->s_ocsp = iocsp;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +0200856
Emmanuel Hocdetb7a4c342017-01-06 12:57:46 +0100857 pkey = X509_get_pubkey(x);
858 cb_arg->single_kt = EVP_PKEY_base_id(pkey);
859 EVP_PKEY_free(pkey);
yanbzhube2774d2015-12-10 15:07:30 -0500860
861 SSL_CTX_set_tlsext_status_cb(ctx, ssl_sock_ocsp_stapling_cbk);
862 SSL_CTX_set_tlsext_status_arg(ctx, cb_arg);
863 } else {
864 /*
865 * If the ctx has a status CB, then we have previously set an OCSP staple for this ctx
866 * Update that cb_arg with the new cert's staple
867 */
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +0200868 struct ocsp_cbk_arg *cb_arg;
yanbzhube2774d2015-12-10 15:07:30 -0500869 struct certificate_ocsp *tmp_ocsp;
870 int index;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +0200871 int key_type;
Emmanuel Hocdetb7a4c342017-01-06 12:57:46 +0100872 EVP_PKEY *pkey;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +0200873
874#ifdef SSL_CTX_get_tlsext_status_arg
875 SSL_CTX_ctrl(ctx, SSL_CTRL_GET_TLSEXT_STATUS_REQ_CB_ARG, 0, &cb_arg);
876#else
877 cb_arg = ctx->tlsext_status_arg;
878#endif
yanbzhube2774d2015-12-10 15:07:30 -0500879
880 /*
881 * The following few lines will convert cb_arg from a single ocsp to multi ocsp
882 * the order of operations below matter, take care when changing it
883 */
884 tmp_ocsp = cb_arg->s_ocsp;
885 index = ssl_sock_get_ocsp_arg_kt_index(cb_arg->single_kt);
886 cb_arg->s_ocsp = NULL;
887 cb_arg->m_ocsp[index] = tmp_ocsp;
888 cb_arg->is_single = 0;
889 cb_arg->single_kt = 0;
890
Emmanuel Hocdetb7a4c342017-01-06 12:57:46 +0100891 pkey = X509_get_pubkey(x);
892 key_type = EVP_PKEY_base_id(pkey);
893 EVP_PKEY_free(pkey);
894
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +0200895 index = ssl_sock_get_ocsp_arg_kt_index(key_type);
yanbzhube2774d2015-12-10 15:07:30 -0500896 if (index >= 0 && !cb_arg->m_ocsp[index])
897 cb_arg->m_ocsp[index] = iocsp;
898
899 }
Emeric Brun4147b2e2014-06-16 18:36:30 +0200900
901 ret = 0;
902
903 warn = NULL;
904 if (ssl_sock_load_ocsp_response_from_file(ocsp_path, iocsp, cid, &warn)) {
905 memprintf(&warn, "Loading '%s': %s. Content will be ignored", ocsp_path, warn ? warn : "failure");
906 Warning("%s.\n", warn);
907 }
908
909out:
910 if (ssl)
911 SSL_free(ssl);
912
913 if (in)
914 BIO_free(in);
915
916 if (xi)
917 X509_free(xi);
918
919 if (cid)
920 OCSP_CERTID_free(cid);
921
922 if (ocsp)
923 free(ocsp);
924
925 if (warn)
926 free(warn);
927
928
929 return ret;
930}
931
932#endif
933
Daniel Jakots54ffb912015-11-06 20:02:41 +0100934#if (OPENSSL_VERSION_NUMBER >= 0x1000200fL && !defined OPENSSL_NO_TLSEXT && !defined OPENSSL_IS_BORINGSSL && !defined LIBRESSL_VERSION_NUMBER)
Janusz Dziemidowicz2c701b52015-03-07 23:03:59 +0100935
936#define CT_EXTENSION_TYPE 18
937
938static int sctl_ex_index = -1;
939
940/*
941 * Try to parse Signed Certificate Timestamp List structure. This function
942 * makes only basic test if the data seems like SCTL. No signature validation
943 * is performed.
944 */
945static int ssl_sock_parse_sctl(struct chunk *sctl)
946{
947 int ret = 1;
948 int len, pos, sct_len;
949 unsigned char *data;
950
951 if (sctl->len < 2)
952 goto out;
953
954 data = (unsigned char *)sctl->str;
955 len = (data[0] << 8) | data[1];
956
957 if (len + 2 != sctl->len)
958 goto out;
959
960 data = data + 2;
961 pos = 0;
962 while (pos < len) {
963 if (len - pos < 2)
964 goto out;
965
966 sct_len = (data[pos] << 8) | data[pos + 1];
967 if (pos + sct_len + 2 > len)
968 goto out;
969
970 pos += sct_len + 2;
971 }
972
973 ret = 0;
974
975out:
976 return ret;
977}
978
979static int ssl_sock_load_sctl_from_file(const char *sctl_path, struct chunk **sctl)
980{
981 int fd = -1;
982 int r = 0;
983 int ret = 1;
984
985 *sctl = NULL;
986
987 fd = open(sctl_path, O_RDONLY);
988 if (fd == -1)
989 goto end;
990
991 trash.len = 0;
992 while (trash.len < trash.size) {
993 r = read(fd, trash.str + trash.len, trash.size - trash.len);
994 if (r < 0) {
995 if (errno == EINTR)
996 continue;
997
998 goto end;
999 }
1000 else if (r == 0) {
1001 break;
1002 }
1003 trash.len += r;
1004 }
1005
1006 ret = ssl_sock_parse_sctl(&trash);
1007 if (ret)
1008 goto end;
1009
Vincent Bernat02779b62016-04-03 13:48:43 +02001010 *sctl = calloc(1, sizeof(**sctl));
Janusz Dziemidowicz2c701b52015-03-07 23:03:59 +01001011 if (!chunk_dup(*sctl, &trash)) {
1012 free(*sctl);
1013 *sctl = NULL;
1014 goto end;
1015 }
1016
1017end:
1018 if (fd != -1)
1019 close(fd);
1020
1021 return ret;
1022}
1023
1024int ssl_sock_sctl_add_cbk(SSL *ssl, unsigned ext_type, const unsigned char **out, size_t *outlen, int *al, void *add_arg)
1025{
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02001026 struct chunk *sctl = add_arg;
Janusz Dziemidowicz2c701b52015-03-07 23:03:59 +01001027
1028 *out = (unsigned char *)sctl->str;
1029 *outlen = sctl->len;
1030
1031 return 1;
1032}
1033
1034int ssl_sock_sctl_parse_cbk(SSL *s, unsigned int ext_type, const unsigned char *in, size_t inlen, int *al, void *parse_arg)
1035{
1036 return 1;
1037}
1038
1039static int ssl_sock_load_sctl(SSL_CTX *ctx, const char *cert_path)
1040{
1041 char sctl_path[MAXPATHLEN+1];
1042 int ret = -1;
1043 struct stat st;
1044 struct chunk *sctl = NULL;
1045
1046 snprintf(sctl_path, MAXPATHLEN+1, "%s.sctl", cert_path);
1047
1048 if (stat(sctl_path, &st))
1049 return 1;
1050
1051 if (ssl_sock_load_sctl_from_file(sctl_path, &sctl))
1052 goto out;
1053
1054 if (!SSL_CTX_add_server_custom_ext(ctx, CT_EXTENSION_TYPE, ssl_sock_sctl_add_cbk, NULL, sctl, ssl_sock_sctl_parse_cbk, NULL)) {
1055 free(sctl);
1056 goto out;
1057 }
1058
1059 SSL_CTX_set_ex_data(ctx, sctl_ex_index, sctl);
1060
1061 ret = 0;
1062
1063out:
1064 return ret;
1065}
1066
1067#endif
1068
Emeric Brune1f38db2012-09-03 20:36:47 +02001069void ssl_sock_infocbk(const SSL *ssl, int where, int ret)
1070{
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02001071 struct connection *conn = SSL_get_app_data(ssl);
Emeric Brund8b2bb52014-01-28 15:43:53 +01001072 BIO *write_bio;
Willy Tarreau622317d2015-02-27 16:36:16 +01001073 (void)ret; /* shut gcc stupid warning */
Emeric Brune1f38db2012-09-03 20:36:47 +02001074
1075 if (where & SSL_CB_HANDSHAKE_START) {
1076 /* Disable renegotiation (CVE-2009-3555) */
Willy Tarreau20879a02012-12-03 16:32:10 +01001077 if (conn->flags & CO_FL_CONNECTED) {
Emeric Brune1f38db2012-09-03 20:36:47 +02001078 conn->flags |= CO_FL_ERROR;
Willy Tarreau20879a02012-12-03 16:32:10 +01001079 conn->err_code = CO_ER_SSL_RENEG;
1080 }
Emeric Brune1f38db2012-09-03 20:36:47 +02001081 }
Emeric Brund8b2bb52014-01-28 15:43:53 +01001082
1083 if ((where & SSL_CB_ACCEPT_LOOP) == SSL_CB_ACCEPT_LOOP) {
1084 if (!(conn->xprt_st & SSL_SOCK_ST_FL_16K_WBFSIZE)) {
1085 /* Long certificate chains optimz
1086 If write and read bios are differents, we
1087 consider that the buffering was activated,
1088 so we rise the output buffer size from 4k
1089 to 16k */
1090 write_bio = SSL_get_wbio(ssl);
1091 if (write_bio != SSL_get_rbio(ssl)) {
1092 BIO_set_write_buffer_size(write_bio, 16384);
1093 conn->xprt_st |= SSL_SOCK_ST_FL_16K_WBFSIZE;
1094 }
1095 }
1096 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02001097}
1098
Emeric Brune64aef12012-09-21 13:15:06 +02001099/* Callback is called for each certificate of the chain during a verify
1100 ok is set to 1 if preverify detect no error on current certificate.
1101 Returns 0 to break the handshake, 1 otherwise. */
Evan Broderbe554312013-06-27 00:05:25 -07001102int ssl_sock_bind_verifycbk(int ok, X509_STORE_CTX *x_store)
Emeric Brune64aef12012-09-21 13:15:06 +02001103{
1104 SSL *ssl;
1105 struct connection *conn;
Emeric Brun81c00f02012-09-21 14:31:21 +02001106 int err, depth;
Emeric Brune64aef12012-09-21 13:15:06 +02001107
1108 ssl = X509_STORE_CTX_get_ex_data(x_store, SSL_get_ex_data_X509_STORE_CTX_idx());
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02001109 conn = SSL_get_app_data(ssl);
Emeric Brune64aef12012-09-21 13:15:06 +02001110
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02001111 conn->xprt_st |= SSL_SOCK_ST_FL_VERIFY_DONE;
Emeric Brune64aef12012-09-21 13:15:06 +02001112
Emeric Brun81c00f02012-09-21 14:31:21 +02001113 if (ok) /* no errors */
1114 return ok;
1115
1116 depth = X509_STORE_CTX_get_error_depth(x_store);
1117 err = X509_STORE_CTX_get_error(x_store);
1118
1119 /* check if CA error needs to be ignored */
1120 if (depth > 0) {
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02001121 if (!SSL_SOCK_ST_TO_CA_ERROR(conn->xprt_st)) {
1122 conn->xprt_st |= SSL_SOCK_CA_ERROR_TO_ST(err);
1123 conn->xprt_st |= SSL_SOCK_CAEDEPTH_TO_ST(depth);
Emeric Brunf282a812012-09-21 15:27:54 +02001124 }
1125
Emeric Brun1eb20ef2012-12-03 13:24:29 +01001126 if (objt_listener(conn->target)->bind_conf->ca_ignerr & (1ULL << err)) {
Thierry FOURNIER / OZON.IO8b068c22016-10-10 11:59:50 +02001127 ssl_sock_dump_errors(conn);
Emeric Brun1eb20ef2012-12-03 13:24:29 +01001128 ERR_clear_error();
Emeric Brun81c00f02012-09-21 14:31:21 +02001129 return 1;
Emeric Brun1eb20ef2012-12-03 13:24:29 +01001130 }
Emeric Brun81c00f02012-09-21 14:31:21 +02001131
Willy Tarreau20879a02012-12-03 16:32:10 +01001132 conn->err_code = CO_ER_SSL_CA_FAIL;
Emeric Brun81c00f02012-09-21 14:31:21 +02001133 return 0;
1134 }
1135
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02001136 if (!SSL_SOCK_ST_TO_CRTERROR(conn->xprt_st))
1137 conn->xprt_st |= SSL_SOCK_CRTERROR_TO_ST(err);
Emeric Brunf282a812012-09-21 15:27:54 +02001138
Emeric Brun81c00f02012-09-21 14:31:21 +02001139 /* check if certificate error needs to be ignored */
Emeric Brun1eb20ef2012-12-03 13:24:29 +01001140 if (objt_listener(conn->target)->bind_conf->crt_ignerr & (1ULL << err)) {
Thierry FOURNIER / OZON.IO8b068c22016-10-10 11:59:50 +02001141 ssl_sock_dump_errors(conn);
Emeric Brun1eb20ef2012-12-03 13:24:29 +01001142 ERR_clear_error();
Emeric Brun81c00f02012-09-21 14:31:21 +02001143 return 1;
Emeric Brun1eb20ef2012-12-03 13:24:29 +01001144 }
Emeric Brun81c00f02012-09-21 14:31:21 +02001145
Willy Tarreau20879a02012-12-03 16:32:10 +01001146 conn->err_code = CO_ER_SSL_CRT_FAIL;
Emeric Brun81c00f02012-09-21 14:31:21 +02001147 return 0;
Emeric Brune64aef12012-09-21 13:15:06 +02001148}
1149
Thierry FOURNIER5bf77322017-02-25 12:45:22 +01001150static inline
1151void ssl_sock_parse_clienthello(int write_p, int version, int content_type,
Emmanuel Hocdete3804742017-03-08 11:07:10 +01001152 const void *buf, size_t len, SSL *ssl)
Thierry FOURNIER5bf77322017-02-25 12:45:22 +01001153{
Emmanuel Hocdete3804742017-03-08 11:07:10 +01001154 struct ssl_capture *capture;
Thierry FOURNIER5bf77322017-02-25 12:45:22 +01001155 unsigned char *msg;
1156 unsigned char *end;
Emmanuel Hocdete3804742017-03-08 11:07:10 +01001157 size_t rec_len;
Thierry FOURNIER5bf77322017-02-25 12:45:22 +01001158
1159 /* This function is called for "from client" and "to server"
1160 * connections. The combination of write_p == 0 and content_type == 22
1161 * is only avalaible during "from client" connection.
1162 */
1163
1164 /* "write_p" is set to 0 is the bytes are received messages,
1165 * otherwise it is set to 1.
1166 */
1167 if (write_p != 0)
1168 return;
1169
1170 /* content_type contains the type of message received or sent
1171 * according with the SSL/TLS protocol spec. This message is
1172 * encoded with one byte. The value 256 (two bytes) is used
1173 * for designing the SSL/TLS record layer. According with the
1174 * rfc6101, the expected message (other than 256) are:
1175 * - change_cipher_spec(20)
1176 * - alert(21)
1177 * - handshake(22)
1178 * - application_data(23)
1179 * - (255)
1180 * We are interessed by the handshake and specially the client
1181 * hello.
1182 */
1183 if (content_type != 22)
1184 return;
1185
1186 /* The message length is at least 4 bytes, containing the
1187 * message type and the message length.
1188 */
1189 if (len < 4)
1190 return;
1191
1192 /* First byte of the handshake message id the type of
1193 * message. The konwn types are:
1194 * - hello_request(0)
1195 * - client_hello(1)
1196 * - server_hello(2)
1197 * - certificate(11)
1198 * - server_key_exchange (12)
1199 * - certificate_request(13)
1200 * - server_hello_done(14)
1201 * We are interested by the client hello.
1202 */
1203 msg = (unsigned char *)buf;
1204 if (msg[0] != 1)
1205 return;
1206
1207 /* Next three bytes are the length of the message. The total length
1208 * must be this decoded length + 4. If the length given as argument
1209 * is not the same, we abort the protocol dissector.
1210 */
1211 rec_len = (msg[1] << 16) + (msg[2] << 8) + msg[3];
1212 if (len < rec_len + 4)
1213 return;
1214 msg += 4;
1215 end = msg + rec_len;
1216 if (end < msg)
1217 return;
1218
1219 /* Expect 2 bytes for protocol version (1 byte for major and 1 byte
1220 * for minor, the random, composed by 4 bytes for the unix time and
1221 * 28 bytes for unix payload, and them 1 byte for the session id. So
1222 * we jump 1 + 1 + 4 + 28 + 1 bytes.
1223 */
1224 msg += 1 + 1 + 4 + 28 + 1;
1225 if (msg > end)
1226 return;
1227
1228 /* Next two bytes are the ciphersuite length. */
1229 if (msg + 2 > end)
1230 return;
1231 rec_len = (msg[0] << 8) + msg[1];
1232 msg += 2;
1233 if (msg + rec_len > end || msg + rec_len < msg)
1234 return;
1235
Emmanuel Hocdete3804742017-03-08 11:07:10 +01001236 capture = pool_alloc_dirty(pool2_ssl_capture);
1237 if (!capture)
1238 return;
Thierry FOURNIER5bf77322017-02-25 12:45:22 +01001239 /* Compute the xxh64 of the ciphersuite. */
1240 capture->xxh64 = XXH64(msg, rec_len, 0);
1241
1242 /* Capture the ciphersuite. */
Emmanuel Hocdete3804742017-03-08 11:07:10 +01001243 capture->ciphersuite_len = (global_ssl.capture_cipherlist < rec_len) ?
1244 global_ssl.capture_cipherlist : rec_len;
Thierry FOURNIER5bf77322017-02-25 12:45:22 +01001245 memcpy(capture->ciphersuite, msg, capture->ciphersuite_len);
Emmanuel Hocdete3804742017-03-08 11:07:10 +01001246
1247 SSL_set_ex_data(ssl, ssl_capture_ptr_index, capture);
Thierry FOURNIER5bf77322017-02-25 12:45:22 +01001248}
1249
Emeric Brun29f037d2014-04-25 19:05:36 +02001250/* Callback is called for ssl protocol analyse */
1251void ssl_sock_msgcbk(int write_p, int version, int content_type, const void *buf, size_t len, SSL *ssl, void *arg)
1252{
Emeric Brun29f037d2014-04-25 19:05:36 +02001253#ifdef TLS1_RT_HEARTBEAT
1254 /* test heartbeat received (write_p is set to 0
1255 for a received record) */
Willy Tarreauf51c6982014-04-25 20:02:39 +02001256 if ((content_type == TLS1_RT_HEARTBEAT) && (write_p == 0)) {
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02001257 struct connection *conn = SSL_get_app_data(ssl);
Willy Tarreauf51c6982014-04-25 20:02:39 +02001258 const unsigned char *p = buf;
1259 unsigned int payload;
1260
Emeric Brun29f037d2014-04-25 19:05:36 +02001261 conn->xprt_st |= SSL_SOCK_RECV_HEARTBEAT;
Willy Tarreauf51c6982014-04-25 20:02:39 +02001262
1263 /* Check if this is a CVE-2014-0160 exploitation attempt. */
1264 if (*p != TLS1_HB_REQUEST)
1265 return;
1266
Willy Tarreauaeed6722014-04-25 23:59:58 +02001267 if (len < 1 + 2 + 16) /* 1 type + 2 size + 0 payload + 16 padding */
Willy Tarreauf51c6982014-04-25 20:02:39 +02001268 goto kill_it;
1269
1270 payload = (p[1] * 256) + p[2];
Willy Tarreau3b2fdb62014-04-25 23:44:22 +02001271 if (3 + payload + 16 <= len)
Willy Tarreauf51c6982014-04-25 20:02:39 +02001272 return; /* OK no problem */
Willy Tarreauaeed6722014-04-25 23:59:58 +02001273 kill_it:
Willy Tarreau3b2fdb62014-04-25 23:44:22 +02001274 /* We have a clear heartbleed attack (CVE-2014-0160), the
1275 * advertised payload is larger than the advertised packet
1276 * length, so we have garbage in the buffer between the
1277 * payload and the end of the buffer (p+len). We can't know
1278 * if the SSL stack is patched, and we don't know if we can
1279 * safely wipe out the area between p+3+len and payload.
1280 * So instead, we prevent the response from being sent by
1281 * setting the max_send_fragment to 0 and we report an SSL
1282 * error, which will kill this connection. It will be reported
1283 * above as SSL_ERROR_SSL while an other handshake failure with
Willy Tarreauf51c6982014-04-25 20:02:39 +02001284 * a heartbeat message will be reported as SSL_ERROR_SYSCALL.
1285 */
Willy Tarreau3b2fdb62014-04-25 23:44:22 +02001286 ssl->max_send_fragment = 0;
Willy Tarreauf51c6982014-04-25 20:02:39 +02001287 SSLerr(SSL_F_TLS1_HEARTBEAT, SSL_R_SSL_HANDSHAKE_FAILURE);
1288 return;
1289 }
Emeric Brun29f037d2014-04-25 19:05:36 +02001290#endif
Emmanuel Hocdete3804742017-03-08 11:07:10 +01001291 if (global_ssl.capture_cipherlist > 0)
1292 ssl_sock_parse_clienthello(write_p, version, content_type, buf, len, ssl);
Emeric Brun29f037d2014-04-25 19:05:36 +02001293}
1294
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02001295#ifdef OPENSSL_NPN_NEGOTIATED
1296/* This callback is used so that the server advertises the list of
1297 * negociable protocols for NPN.
1298 */
1299static int ssl_sock_advertise_npn_protos(SSL *s, const unsigned char **data,
1300 unsigned int *len, void *arg)
1301{
Emmanuel Hocdet98263292016-12-29 18:26:15 +01001302 struct ssl_bind_conf *conf = arg;
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02001303
1304 *data = (const unsigned char *)conf->npn_str;
1305 *len = conf->npn_len;
1306 return SSL_TLSEXT_ERR_OK;
1307}
1308#endif
1309
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01001310#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Willy Tarreauab861d32013-04-02 02:30:41 +02001311/* This callback is used so that the server advertises the list of
1312 * negociable protocols for ALPN.
1313 */
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01001314static int ssl_sock_advertise_alpn_protos(SSL *s, const unsigned char **out,
1315 unsigned char *outlen,
1316 const unsigned char *server,
1317 unsigned int server_len, void *arg)
Willy Tarreauab861d32013-04-02 02:30:41 +02001318{
Emmanuel Hocdet98263292016-12-29 18:26:15 +01001319 struct ssl_bind_conf *conf = arg;
Willy Tarreauab861d32013-04-02 02:30:41 +02001320
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01001321 if (SSL_select_next_proto((unsigned char**) out, outlen, (const unsigned char *)conf->alpn_str,
1322 conf->alpn_len, server, server_len) != OPENSSL_NPN_NEGOTIATED) {
1323 return SSL_TLSEXT_ERR_NOACK;
1324 }
Willy Tarreauab861d32013-04-02 02:30:41 +02001325 return SSL_TLSEXT_ERR_OK;
1326}
1327#endif
1328
Willy Tarreauc8ad3be2015-06-17 15:48:26 +02001329#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +01001330#ifndef SSL_NO_GENERATE_CERTIFICATES
Christopher Faulet85b5a1a2015-10-09 11:46:32 +02001331
Christopher Faulet30548802015-06-11 13:39:32 +02001332/* Create a X509 certificate with the specified servername and serial. This
1333 * function returns a SSL_CTX object or NULL if an error occurs. */
Christopher Faulet7969a332015-10-09 11:15:03 +02001334static SSL_CTX *
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001335ssl_sock_do_create_cert(const char *servername, struct bind_conf *bind_conf, SSL *ssl)
Christopher Faulet31af49d2015-06-09 17:29:50 +02001336{
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001337 static unsigned int serial = 0;
1338
Christopher Faulet7969a332015-10-09 11:15:03 +02001339 X509 *cacert = bind_conf->ca_sign_cert;
1340 EVP_PKEY *capkey = bind_conf->ca_sign_pkey;
Christopher Faulet31af49d2015-06-09 17:29:50 +02001341 SSL_CTX *ssl_ctx = NULL;
1342 X509 *newcrt = NULL;
1343 EVP_PKEY *pkey = NULL;
Christopher Faulet31af49d2015-06-09 17:29:50 +02001344 X509_NAME *name;
1345 const EVP_MD *digest;
1346 X509V3_CTX ctx;
1347 unsigned int i;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02001348 int key_type;
Christopher Faulet31af49d2015-06-09 17:29:50 +02001349
Christopher Faulet7969a332015-10-09 11:15:03 +02001350 /* Get the private key of the defautl certificate and use it */
1351 if (!(pkey = SSL_get_privatekey(ssl)))
Christopher Faulet31af49d2015-06-09 17:29:50 +02001352 goto mkcert_error;
1353
1354 /* Create the certificate */
1355 if (!(newcrt = X509_new()))
1356 goto mkcert_error;
1357
1358 /* Set version number for the certificate (X509v3) and the serial
1359 * number */
1360 if (X509_set_version(newcrt, 2L) != 1)
1361 goto mkcert_error;
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001362 if (!serial)
1363 serial = now_ms;
1364 ASN1_INTEGER_set(X509_get_serialNumber(newcrt), serial++);
Christopher Faulet31af49d2015-06-09 17:29:50 +02001365
1366 /* Set duration for the certificate */
1367 if (!X509_gmtime_adj(X509_get_notBefore(newcrt), (long)-60*60*24) ||
1368 !X509_gmtime_adj(X509_get_notAfter(newcrt),(long)60*60*24*365))
1369 goto mkcert_error;
1370
1371 /* set public key in the certificate */
1372 if (X509_set_pubkey(newcrt, pkey) != 1)
1373 goto mkcert_error;
1374
1375 /* Set issuer name from the CA */
1376 if (!(name = X509_get_subject_name(cacert)))
1377 goto mkcert_error;
1378 if (X509_set_issuer_name(newcrt, name) != 1)
1379 goto mkcert_error;
1380
1381 /* Set the subject name using the same, but the CN */
1382 name = X509_NAME_dup(name);
1383 if (X509_NAME_add_entry_by_txt(name, "CN", MBSTRING_ASC,
1384 (const unsigned char *)servername,
1385 -1, -1, 0) != 1) {
1386 X509_NAME_free(name);
1387 goto mkcert_error;
1388 }
1389 if (X509_set_subject_name(newcrt, name) != 1) {
1390 X509_NAME_free(name);
1391 goto mkcert_error;
1392 }
1393 X509_NAME_free(name);
1394
1395 /* Add x509v3 extensions as specified */
1396 X509V3_set_ctx(&ctx, cacert, newcrt, NULL, NULL, 0);
1397 for (i = 0; i < X509V3_EXT_SIZE; i++) {
1398 X509_EXTENSION *ext;
1399
1400 if (!(ext = X509V3_EXT_conf(NULL, &ctx, x509v3_ext_names[i], x509v3_ext_values[i])))
1401 goto mkcert_error;
1402 if (!X509_add_ext(newcrt, ext, -1)) {
1403 X509_EXTENSION_free(ext);
1404 goto mkcert_error;
1405 }
1406 X509_EXTENSION_free(ext);
1407 }
1408
1409 /* Sign the certificate with the CA private key */
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02001410
1411 key_type = EVP_PKEY_base_id(capkey);
1412
1413 if (key_type == EVP_PKEY_DSA)
1414 digest = EVP_sha1();
1415 else if (key_type == EVP_PKEY_RSA)
Christopher Faulet31af49d2015-06-09 17:29:50 +02001416 digest = EVP_sha256();
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02001417 else if (key_type == EVP_PKEY_EC)
Christopher Faulet7969a332015-10-09 11:15:03 +02001418 digest = EVP_sha256();
1419 else {
Christopher Faulete7db2162015-10-19 13:59:24 +02001420#if (OPENSSL_VERSION_NUMBER >= 0x1000000fL)
Christopher Faulet7969a332015-10-09 11:15:03 +02001421 int nid;
1422
1423 if (EVP_PKEY_get_default_digest_nid(capkey, &nid) <= 0)
1424 goto mkcert_error;
1425 if (!(digest = EVP_get_digestbynid(nid)))
1426 goto mkcert_error;
Christopher Faulete7db2162015-10-19 13:59:24 +02001427#else
1428 goto mkcert_error;
1429#endif
Christopher Faulet7969a332015-10-09 11:15:03 +02001430 }
1431
Christopher Faulet31af49d2015-06-09 17:29:50 +02001432 if (!(X509_sign(newcrt, capkey, digest)))
1433 goto mkcert_error;
1434
1435 /* Create and set the new SSL_CTX */
1436 if (!(ssl_ctx = SSL_CTX_new(SSLv23_server_method())))
1437 goto mkcert_error;
1438 if (!SSL_CTX_use_PrivateKey(ssl_ctx, pkey))
1439 goto mkcert_error;
1440 if (!SSL_CTX_use_certificate(ssl_ctx, newcrt))
1441 goto mkcert_error;
1442 if (!SSL_CTX_check_private_key(ssl_ctx))
1443 goto mkcert_error;
1444
1445 if (newcrt) X509_free(newcrt);
Christopher Faulet7969a332015-10-09 11:15:03 +02001446
Emmanuel Hocdetcc6c2a22017-03-03 17:04:14 +01001447#ifndef OPENSSL_NO_DH
Christopher Faulet85b5a1a2015-10-09 11:46:32 +02001448 SSL_CTX_set_tmp_dh_callback(ssl_ctx, ssl_get_tmp_dh);
Emmanuel Hocdetcc6c2a22017-03-03 17:04:14 +01001449#endif
Christopher Faulet85b5a1a2015-10-09 11:46:32 +02001450#if defined(SSL_CTX_set_tmp_ecdh) && !defined(OPENSSL_NO_ECDH)
1451 {
Emmanuel Hocdet98263292016-12-29 18:26:15 +01001452 const char *ecdhe = (bind_conf->ssl_conf.ecdhe ? bind_conf->ssl_conf.ecdhe : ECDHE_DEFAULT_CURVE);
Christopher Faulet85b5a1a2015-10-09 11:46:32 +02001453 EC_KEY *ecc;
1454 int nid;
1455
1456 if ((nid = OBJ_sn2nid(ecdhe)) == NID_undef)
1457 goto end;
1458 if (!(ecc = EC_KEY_new_by_curve_name(nid)))
1459 goto end;
1460 SSL_CTX_set_tmp_ecdh(ssl_ctx, ecc);
1461 EC_KEY_free(ecc);
1462 }
1463#endif
1464 end:
Christopher Faulet31af49d2015-06-09 17:29:50 +02001465 return ssl_ctx;
1466
1467 mkcert_error:
1468 if (ssl_ctx) SSL_CTX_free(ssl_ctx);
1469 if (newcrt) X509_free(newcrt);
Christopher Faulet31af49d2015-06-09 17:29:50 +02001470 return NULL;
1471}
1472
Christopher Faulet7969a332015-10-09 11:15:03 +02001473SSL_CTX *
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001474ssl_sock_create_cert(struct connection *conn, const char *servername, unsigned int key)
Christopher Faulet7969a332015-10-09 11:15:03 +02001475{
1476 struct bind_conf *bind_conf = objt_listener(conn->target)->bind_conf;
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001477
1478 return ssl_sock_do_create_cert(servername, bind_conf, conn->xprt_ctx);
Christopher Faulet7969a332015-10-09 11:15:03 +02001479}
1480
Christopher Faulet30548802015-06-11 13:39:32 +02001481/* Do a lookup for a certificate in the LRU cache used to store generated
1482 * certificates. */
1483SSL_CTX *
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001484ssl_sock_get_generated_cert(unsigned int key, struct bind_conf *bind_conf)
Christopher Faulet30548802015-06-11 13:39:32 +02001485{
1486 struct lru64 *lru = NULL;
1487
1488 if (ssl_ctx_lru_tree) {
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001489 lru = lru64_lookup(key, ssl_ctx_lru_tree, bind_conf->ca_sign_cert, 0);
Christopher Faulet30548802015-06-11 13:39:32 +02001490 if (lru && lru->domain)
1491 return (SSL_CTX *)lru->data;
1492 }
1493 return NULL;
1494}
1495
Christopher Fauletd2cab922015-07-28 16:03:47 +02001496/* Set a certificate int the LRU cache used to store generated
1497 * certificate. Return 0 on success, otherwise -1 */
1498int
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001499ssl_sock_set_generated_cert(SSL_CTX *ssl_ctx, unsigned int key, struct bind_conf *bind_conf)
Christopher Faulet30548802015-06-11 13:39:32 +02001500{
1501 struct lru64 *lru = NULL;
1502
1503 if (ssl_ctx_lru_tree) {
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001504 lru = lru64_get(key, ssl_ctx_lru_tree, bind_conf->ca_sign_cert, 0);
Christopher Faulet30548802015-06-11 13:39:32 +02001505 if (!lru)
Christopher Fauletd2cab922015-07-28 16:03:47 +02001506 return -1;
Christopher Faulet30548802015-06-11 13:39:32 +02001507 if (lru->domain && lru->data)
1508 lru->free((SSL_CTX *)lru->data);
Christopher Faulet7969a332015-10-09 11:15:03 +02001509 lru64_commit(lru, ssl_ctx, bind_conf->ca_sign_cert, 0, (void (*)(void *))SSL_CTX_free);
Christopher Fauletd2cab922015-07-28 16:03:47 +02001510 return 0;
Christopher Faulet30548802015-06-11 13:39:32 +02001511 }
Christopher Fauletd2cab922015-07-28 16:03:47 +02001512 return -1;
Christopher Faulet30548802015-06-11 13:39:32 +02001513}
1514
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001515/* Compute the key of the certificate. */
Christopher Faulet30548802015-06-11 13:39:32 +02001516unsigned int
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001517ssl_sock_generated_cert_key(const void *data, size_t len)
Christopher Faulet30548802015-06-11 13:39:32 +02001518{
1519 return XXH32(data, len, ssl_ctx_lru_seed);
1520}
1521
Willy Tarreau2f63ef42015-10-20 15:16:01 +02001522/* Generate a cert and immediately assign it to the SSL session so that the cert's
1523 * refcount is maintained regardless of the cert's presence in the LRU cache.
1524 */
Christopher Faulet31af49d2015-06-09 17:29:50 +02001525static SSL_CTX *
Christopher Faulet7969a332015-10-09 11:15:03 +02001526ssl_sock_generate_certificate(const char *servername, struct bind_conf *bind_conf, SSL *ssl)
Christopher Faulet31af49d2015-06-09 17:29:50 +02001527{
1528 X509 *cacert = bind_conf->ca_sign_cert;
Christopher Faulet31af49d2015-06-09 17:29:50 +02001529 SSL_CTX *ssl_ctx = NULL;
1530 struct lru64 *lru = NULL;
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001531 unsigned int key;
Christopher Faulet31af49d2015-06-09 17:29:50 +02001532
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001533 key = ssl_sock_generated_cert_key(servername, strlen(servername));
Christopher Faulet31af49d2015-06-09 17:29:50 +02001534 if (ssl_ctx_lru_tree) {
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001535 lru = lru64_get(key, ssl_ctx_lru_tree, cacert, 0);
Christopher Faulet31af49d2015-06-09 17:29:50 +02001536 if (lru && lru->domain)
1537 ssl_ctx = (SSL_CTX *)lru->data;
Christopher Fauletd2cab922015-07-28 16:03:47 +02001538 if (!ssl_ctx && lru) {
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001539 ssl_ctx = ssl_sock_do_create_cert(servername, bind_conf, ssl);
Christopher Faulet31af49d2015-06-09 17:29:50 +02001540 lru64_commit(lru, ssl_ctx, cacert, 0, (void (*)(void *))SSL_CTX_free);
Christopher Fauletd2cab922015-07-28 16:03:47 +02001541 }
Willy Tarreau2f63ef42015-10-20 15:16:01 +02001542 SSL_set_SSL_CTX(ssl, ssl_ctx);
Christopher Faulet31af49d2015-06-09 17:29:50 +02001543 }
Willy Tarreau2f63ef42015-10-20 15:16:01 +02001544 else {
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001545 ssl_ctx = ssl_sock_do_create_cert(servername, bind_conf, ssl);
Willy Tarreau2f63ef42015-10-20 15:16:01 +02001546 SSL_set_SSL_CTX(ssl, ssl_ctx);
1547 /* No LRU cache, this CTX will be released as soon as the session dies */
1548 SSL_CTX_free(ssl_ctx);
1549 }
Christopher Faulet31af49d2015-06-09 17:29:50 +02001550 return ssl_ctx;
1551}
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +01001552#endif /* !defined SSL_NO_GENERATE_CERTIFICATES */
Christopher Faulet31af49d2015-06-09 17:29:50 +02001553
Emmanuel Hocdet530141f2017-03-01 18:54:56 +01001554static void ssl_sock_switchctx_set(SSL *ssl, SSL_CTX *ctx)
1555{
1556 SSL_set_verify(ssl, SSL_CTX_get_verify_mode(ctx), ssl_sock_bind_verifycbk);
1557 SSL_set_client_CA_list(ssl, SSL_dup_CA_list(SSL_CTX_get_client_CA_list(ctx)));
1558 SSL_set_SSL_CTX(ssl, ctx);
1559}
1560
Emmanuel Hocdet05942112017-02-20 16:11:50 +01001561#ifdef OPENSSL_IS_BORINGSSL
1562
1563static int ssl_sock_switchctx_err_cbk(SSL *ssl, int *al, void *priv)
1564{
1565 (void)al; /* shut gcc stupid warning */
1566 (void)priv;
1567
1568 if (!SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name))
1569 return SSL_TLSEXT_ERR_NOACK;
1570 return SSL_TLSEXT_ERR_OK;
1571}
1572
1573static int ssl_sock_switchctx_cbk(const struct ssl_early_callback_ctx *ctx)
1574{
1575 struct connection *conn;
1576 struct bind_conf *s;
1577 const uint8_t *extension_data;
1578 size_t extension_len;
1579 CBS extension, cipher_suites, server_name_list, host_name, sig_algs;
1580 const SSL_CIPHER *cipher;
1581 uint16_t cipher_suite;
1582 uint8_t name_type, hash, sign;
1583 int has_rsa = 0, has_ecdsa = 0, has_ecdsa_sig = 0;
1584
1585 char *wildp = NULL;
1586 const uint8_t *servername;
1587 struct ebmb_node *node, *n, *node_ecdsa = NULL, *node_rsa = NULL, *node_anonymous = NULL;
1588 int i;
1589
1590 conn = SSL_get_app_data(ctx->ssl);
1591 s = objt_listener(conn->target)->bind_conf;
1592
1593 if (SSL_early_callback_ctx_extension_get(ctx, TLSEXT_TYPE_server_name,
1594 &extension_data, &extension_len)) {
1595 CBS_init(&extension, extension_data, extension_len);
1596
1597 if (!CBS_get_u16_length_prefixed(&extension, &server_name_list)
1598 || !CBS_get_u8(&server_name_list, &name_type)
1599 /* Although the server_name extension was intended to be extensible to
1600 * new name types and multiple names, OpenSSL 1.0.x had a bug which meant
1601 * different name types will cause an error. Further, RFC 4366 originally
1602 * defined syntax inextensibly. RFC 6066 corrected this mistake, but
1603 * adding new name types is no longer feasible.
1604 *
1605 * Act as if the extensibility does not exist to simplify parsing. */
1606 || !CBS_get_u16_length_prefixed(&server_name_list, &host_name)
1607 || CBS_len(&server_name_list) != 0
1608 || CBS_len(&extension) != 0
1609 || name_type != TLSEXT_NAMETYPE_host_name
1610 || CBS_len(&host_name) == 0
1611 || CBS_len(&host_name) > TLSEXT_MAXLEN_host_name
1612 || CBS_contains_zero_byte(&host_name)) {
1613 goto abort;
1614 }
1615 } else {
1616 /* without SNI extension, is the default_ctx (need SSL_TLSEXT_ERR_NOACK) */
Emmanuel Hocdetf6b37c62017-03-06 15:34:44 +01001617 if (!s->strict_sni) {
1618 ssl_sock_switchctx_set(ctx->ssl, s->default_ctx);
Emmanuel Hocdet05942112017-02-20 16:11:50 +01001619 return 1;
Emmanuel Hocdetf6b37c62017-03-06 15:34:44 +01001620 }
Emmanuel Hocdet05942112017-02-20 16:11:50 +01001621 goto abort;
1622 }
1623
1624 /* extract/check clientHello informations */
1625 if (SSL_early_callback_ctx_extension_get(ctx, TLSEXT_TYPE_signature_algorithms, &extension_data, &extension_len)) {
1626 CBS_init(&extension, extension_data, extension_len);
1627
1628 if (!CBS_get_u16_length_prefixed(&extension, &sig_algs)
1629 || CBS_len(&sig_algs) == 0
1630 || CBS_len(&extension) != 0) {
1631 goto abort;
1632 }
1633 if (CBS_len(&sig_algs) % 2 != 0) {
1634 goto abort;
1635 }
1636 while (CBS_len(&sig_algs) != 0) {
1637 if (!CBS_get_u8(&sig_algs, &hash)
1638 || !CBS_get_u8(&sig_algs, &sign)) {
1639 goto abort;
1640 }
1641 switch (sign) {
1642 case TLSEXT_signature_rsa:
1643 has_rsa = 1;
1644 break;
1645 case TLSEXT_signature_ecdsa:
1646 has_ecdsa_sig = 1;
1647 break;
1648 default:
1649 continue;
1650 }
1651 if (has_ecdsa_sig && has_rsa)
1652 break;
1653 }
1654 } else {
1655 /* without TLSEXT_TYPE_signature_algorithms extension (< TLS 1.2) */
1656 has_rsa = 1;
1657 }
1658 if (has_ecdsa_sig) { /* in very rare case: has ecdsa sign but not a ECDSA cipher */
1659 CBS_init(&cipher_suites, ctx->cipher_suites, ctx->cipher_suites_len);
1660
1661 while (CBS_len(&cipher_suites) != 0) {
1662 if (!CBS_get_u16(&cipher_suites, &cipher_suite)) {
1663 goto abort;
1664 }
1665 cipher = SSL_get_cipher_by_value(cipher_suite);
1666 if (cipher && SSL_CIPHER_is_ECDSA(cipher)) {
1667 has_ecdsa = 1;
1668 break;
1669 }
1670 }
1671 }
1672
1673 servername = CBS_data(&host_name);
1674 for (i = 0; i < trash.size && i < CBS_len(&host_name); i++) {
1675 trash.str[i] = tolower(servername[i]);
1676 if (!wildp && (trash.str[i] == '.'))
1677 wildp = &trash.str[i];
1678 }
1679 trash.str[i] = 0;
1680
1681 /* lookup in full qualified names */
1682 node = ebst_lookup(&s->sni_ctx, trash.str);
1683
1684 /* lookup a not neg filter */
1685 for (n = node; n; n = ebmb_next_dup(n)) {
1686 if (!container_of(n, struct sni_ctx, name)->neg) {
1687 switch(container_of(n, struct sni_ctx, name)->key_sig) {
1688 case TLSEXT_signature_ecdsa:
1689 if (has_ecdsa) {
1690 node_ecdsa = n;
1691 goto find_one;
1692 }
1693 break;
1694 case TLSEXT_signature_rsa:
1695 if (has_rsa && !node_rsa) {
1696 node_rsa = n;
1697 if (!has_ecdsa)
1698 goto find_one;
1699 }
1700 break;
1701 default: /* TLSEXT_signature_anonymous */
1702 if (!node_anonymous)
1703 node_anonymous = n;
1704 break;
1705 }
1706 }
1707 }
1708 if (wildp) {
1709 /* lookup in wildcards names */
1710 node = ebst_lookup(&s->sni_w_ctx, wildp);
1711 for (n = node; n; n = ebmb_next_dup(n)) {
1712 if (!container_of(n, struct sni_ctx, name)->neg) {
1713 switch(container_of(n, struct sni_ctx, name)->key_sig) {
1714 case TLSEXT_signature_ecdsa:
1715 if (has_ecdsa) {
1716 node_ecdsa = n;
1717 goto find_one;
1718 }
1719 break;
1720 case TLSEXT_signature_rsa:
1721 if (has_rsa && !node_rsa) {
1722 node_rsa = n;
1723 if (!has_ecdsa)
1724 goto find_one;
1725 }
1726 break;
1727 default: /* TLSEXT_signature_anonymous */
1728 if (!node_anonymous)
1729 node_anonymous = n;
1730 break;
1731 }
1732 }
1733 }
1734 }
1735 find_one:
1736 /* select by key_signature priority order */
1737 node = node_ecdsa ? node_ecdsa : (node_rsa ? node_rsa : node_anonymous);
1738
1739 if (node) {
1740 /* switch ctx */
Emmanuel Hocdet530141f2017-03-01 18:54:56 +01001741 ssl_sock_switchctx_set(ctx->ssl, container_of(node, struct sni_ctx, name)->ctx);
Emmanuel Hocdet05942112017-02-20 16:11:50 +01001742 return 1;
1743 }
Emmanuel Hocdetf6b37c62017-03-06 15:34:44 +01001744 if (!s->strict_sni) {
Emmanuel Hocdet05942112017-02-20 16:11:50 +01001745 /* no certificate match, is the default_ctx */
Emmanuel Hocdetf6b37c62017-03-06 15:34:44 +01001746 ssl_sock_switchctx_set(ctx->ssl, s->default_ctx);
Emmanuel Hocdet05942112017-02-20 16:11:50 +01001747 return 1;
Emmanuel Hocdetf6b37c62017-03-06 15:34:44 +01001748 }
Emmanuel Hocdet05942112017-02-20 16:11:50 +01001749 abort:
1750 /* abort handshake (was SSL_TLSEXT_ERR_ALERT_FATAL) */
1751 conn->err_code = CO_ER_SSL_HANDSHAKE;
1752 return -1;
1753}
1754
1755#else /* OPENSSL_IS_BORINGSSL */
1756
Emeric Brunfc0421f2012-09-07 17:30:07 +02001757/* Sets the SSL ctx of <ssl> to match the advertised server name. Returns a
1758 * warning when no match is found, which implies the default (first) cert
1759 * will keep being used.
1760 */
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +01001761static int ssl_sock_switchctx_cbk(SSL *ssl, int *al, void *priv)
Emeric Brunfc0421f2012-09-07 17:30:07 +02001762{
1763 const char *servername;
1764 const char *wildp = NULL;
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001765 struct ebmb_node *node, *n;
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +01001766 struct bind_conf *s = priv;
Emeric Brunfc0421f2012-09-07 17:30:07 +02001767 int i;
1768 (void)al; /* shut gcc stupid warning */
1769
1770 servername = SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name);
Emmanuel Hocdet65623372013-01-24 17:17:15 +01001771 if (!servername) {
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +01001772#if (!defined SSL_NO_GENERATE_CERTIFICATES)
Willy Tarreauf6721452015-07-07 18:04:38 +02001773 if (s->generate_certs) {
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02001774 struct connection *conn = SSL_get_app_data(ssl);
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001775 unsigned int key;
Willy Tarreauf6721452015-07-07 18:04:38 +02001776 SSL_CTX *ctx;
Christopher Faulet30548802015-06-11 13:39:32 +02001777
Willy Tarreauf6721452015-07-07 18:04:38 +02001778 conn_get_to_addr(conn);
1779 if (conn->flags & CO_FL_ADDR_TO_SET) {
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001780 key = ssl_sock_generated_cert_key(&conn->addr.to, get_addr_len(&conn->addr.to));
1781 ctx = ssl_sock_get_generated_cert(key, s);
Willy Tarreauf6721452015-07-07 18:04:38 +02001782 if (ctx) {
1783 /* switch ctx */
1784 SSL_set_SSL_CTX(ssl, ctx);
1785 return SSL_TLSEXT_ERR_OK;
1786 }
Christopher Faulet30548802015-06-11 13:39:32 +02001787 }
1788 }
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +01001789#endif
Emmanuel Hocdetf6b37c62017-03-06 15:34:44 +01001790 if (s->strict_sni)
1791 return SSL_TLSEXT_ERR_ALERT_FATAL;
1792 ssl_sock_switchctx_set(ssl, s->default_ctx);
1793 return SSL_TLSEXT_ERR_NOACK;
Emmanuel Hocdet65623372013-01-24 17:17:15 +01001794 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02001795
Willy Tarreau19d14ef2012-10-29 16:51:55 +01001796 for (i = 0; i < trash.size; i++) {
Emeric Brunfc0421f2012-09-07 17:30:07 +02001797 if (!servername[i])
1798 break;
Willy Tarreau19d14ef2012-10-29 16:51:55 +01001799 trash.str[i] = tolower(servername[i]);
1800 if (!wildp && (trash.str[i] == '.'))
1801 wildp = &trash.str[i];
Emeric Brunfc0421f2012-09-07 17:30:07 +02001802 }
Willy Tarreau19d14ef2012-10-29 16:51:55 +01001803 trash.str[i] = 0;
Emeric Brunfc0421f2012-09-07 17:30:07 +02001804
1805 /* lookup in full qualified names */
Willy Tarreau19d14ef2012-10-29 16:51:55 +01001806 node = ebst_lookup(&s->sni_ctx, trash.str);
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001807
1808 /* lookup a not neg filter */
1809 for (n = node; n; n = ebmb_next_dup(n)) {
1810 if (!container_of(n, struct sni_ctx, name)->neg) {
1811 node = n;
1812 break;
Emmanuel Hocdet65623372013-01-24 17:17:15 +01001813 }
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001814 }
1815 if (!node && wildp) {
1816 /* lookup in wildcards names */
Emeric Brunfc0421f2012-09-07 17:30:07 +02001817 node = ebst_lookup(&s->sni_w_ctx, wildp);
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001818 }
1819 if (!node || container_of(node, struct sni_ctx, name)->neg) {
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +01001820#if (!defined SSL_NO_GENERATE_CERTIFICATES)
Christopher Faulet31af49d2015-06-09 17:29:50 +02001821 SSL_CTX *ctx;
Christopher Faulet31af49d2015-06-09 17:29:50 +02001822 if (s->generate_certs &&
Christopher Faulet7969a332015-10-09 11:15:03 +02001823 (ctx = ssl_sock_generate_certificate(servername, s, ssl))) {
Christopher Faulet31af49d2015-06-09 17:29:50 +02001824 /* switch ctx */
Christopher Faulet31af49d2015-06-09 17:29:50 +02001825 return SSL_TLSEXT_ERR_OK;
1826 }
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +01001827#endif
Emmanuel Hocdetf6b37c62017-03-06 15:34:44 +01001828 if (s->strict_sni)
1829 return SSL_TLSEXT_ERR_ALERT_FATAL;
1830 ssl_sock_switchctx_set(ssl, s->default_ctx);
1831 return SSL_TLSEXT_ERR_OK;
Emeric Brunfc0421f2012-09-07 17:30:07 +02001832 }
1833
1834 /* switch ctx */
Emmanuel Hocdet530141f2017-03-01 18:54:56 +01001835 ssl_sock_switchctx_set(ssl, container_of(node, struct sni_ctx, name)->ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001836 return SSL_TLSEXT_ERR_OK;
1837}
Emmanuel Hocdet05942112017-02-20 16:11:50 +01001838#endif /* (!) OPENSSL_IS_BORINGSSL */
Emeric Brunfc0421f2012-09-07 17:30:07 +02001839#endif /* SSL_CTRL_SET_TLSEXT_HOSTNAME */
1840
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001841#ifndef OPENSSL_NO_DH
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001842
1843static DH * ssl_get_dh_1024(void)
1844{
Remi Gacogned3a341a2015-05-29 16:26:17 +02001845 static unsigned char dh1024_p[]={
1846 0xFA,0xF9,0x2A,0x22,0x2A,0xA7,0x7F,0xE1,0x67,0x4E,0x53,0xF7,
1847 0x56,0x13,0xC3,0xB1,0xE3,0x29,0x6B,0x66,0x31,0x6A,0x7F,0xB3,
1848 0xC2,0x68,0x6B,0xCB,0x1D,0x57,0x39,0x1D,0x1F,0xFF,0x1C,0xC9,
1849 0xA6,0xA4,0x98,0x82,0x31,0x5D,0x25,0xFF,0x8A,0xE0,0x73,0x96,
1850 0x81,0xC8,0x83,0x79,0xC1,0x5A,0x04,0xF8,0x37,0x0D,0xA8,0x3D,
1851 0xAE,0x74,0xBC,0xDB,0xB6,0xA4,0x75,0xD9,0x71,0x8A,0xA0,0x17,
1852 0x9E,0x2D,0xC8,0xA8,0xDF,0x2C,0x5F,0x82,0x95,0xF8,0x92,0x9B,
1853 0xA7,0x33,0x5F,0x89,0x71,0xC8,0x2D,0x6B,0x18,0x86,0xC4,0x94,
1854 0x22,0xA5,0x52,0x8D,0xF6,0xF6,0xD2,0x37,0x92,0x0F,0xA5,0xCC,
1855 0xDB,0x7B,0x1D,0x3D,0xA1,0x31,0xB7,0x80,0x8F,0x0B,0x67,0x5E,
1856 0x36,0xA5,0x60,0x0C,0xF1,0x95,0x33,0x8B,
1857 };
1858 static unsigned char dh1024_g[]={
1859 0x02,
1860 };
1861
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02001862 BIGNUM *p;
1863 BIGNUM *g;
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001864 DH *dh = DH_new();
1865 if (dh) {
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02001866 p = BN_bin2bn(dh1024_p, sizeof dh1024_p, NULL);
1867 g = BN_bin2bn(dh1024_g, sizeof dh1024_g, NULL);
Remi Gacogned3a341a2015-05-29 16:26:17 +02001868
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02001869 if (!p || !g) {
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001870 DH_free(dh);
1871 dh = NULL;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02001872 } else {
1873 DH_set0_pqg(dh, p, NULL, g);
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001874 }
1875 }
1876 return dh;
1877}
1878
1879static DH *ssl_get_dh_2048(void)
1880{
Remi Gacogned3a341a2015-05-29 16:26:17 +02001881 static unsigned char dh2048_p[]={
1882 0xEC,0x86,0xF8,0x70,0xA0,0x33,0x16,0xEC,0x05,0x1A,0x73,0x59,
1883 0xCD,0x1F,0x8B,0xF8,0x29,0xE4,0xD2,0xCF,0x52,0xDD,0xC2,0x24,
1884 0x8D,0xB5,0x38,0x9A,0xFB,0x5C,0xA4,0xE4,0xB2,0xDA,0xCE,0x66,
1885 0x50,0x74,0xA6,0x85,0x4D,0x4B,0x1D,0x30,0xB8,0x2B,0xF3,0x10,
1886 0xE9,0xA7,0x2D,0x05,0x71,0xE7,0x81,0xDF,0x8B,0x59,0x52,0x3B,
1887 0x5F,0x43,0x0B,0x68,0xF1,0xDB,0x07,0xBE,0x08,0x6B,0x1B,0x23,
1888 0xEE,0x4D,0xCC,0x9E,0x0E,0x43,0xA0,0x1E,0xDF,0x43,0x8C,0xEC,
1889 0xBE,0xBE,0x90,0xB4,0x51,0x54,0xB9,0x2F,0x7B,0x64,0x76,0x4E,
1890 0x5D,0xD4,0x2E,0xAE,0xC2,0x9E,0xAE,0x51,0x43,0x59,0xC7,0x77,
1891 0x9C,0x50,0x3C,0x0E,0xED,0x73,0x04,0x5F,0xF1,0x4C,0x76,0x2A,
1892 0xD8,0xF8,0xCF,0xFC,0x34,0x40,0xD1,0xB4,0x42,0x61,0x84,0x66,
1893 0x42,0x39,0x04,0xF8,0x68,0xB2,0x62,0xD7,0x55,0xED,0x1B,0x74,
1894 0x75,0x91,0xE0,0xC5,0x69,0xC1,0x31,0x5C,0xDB,0x7B,0x44,0x2E,
1895 0xCE,0x84,0x58,0x0D,0x1E,0x66,0x0C,0xC8,0x44,0x9E,0xFD,0x40,
1896 0x08,0x67,0x5D,0xFB,0xA7,0x76,0x8F,0x00,0x11,0x87,0xE9,0x93,
1897 0xF9,0x7D,0xC4,0xBC,0x74,0x55,0x20,0xD4,0x4A,0x41,0x2F,0x43,
1898 0x42,0x1A,0xC1,0xF2,0x97,0x17,0x49,0x27,0x37,0x6B,0x2F,0x88,
1899 0x7E,0x1C,0xA0,0xA1,0x89,0x92,0x27,0xD9,0x56,0x5A,0x71,0xC1,
1900 0x56,0x37,0x7E,0x3A,0x9D,0x05,0xE7,0xEE,0x5D,0x8F,0x82,0x17,
1901 0xBC,0xE9,0xC2,0x93,0x30,0x82,0xF9,0xF4,0xC9,0xAE,0x49,0xDB,
1902 0xD0,0x54,0xB4,0xD9,0x75,0x4D,0xFA,0x06,0xB8,0xD6,0x38,0x41,
1903 0xB7,0x1F,0x77,0xF3,
1904 };
1905 static unsigned char dh2048_g[]={
1906 0x02,
1907 };
1908
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02001909 BIGNUM *p;
1910 BIGNUM *g;
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001911 DH *dh = DH_new();
1912 if (dh) {
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02001913 p = BN_bin2bn(dh2048_p, sizeof dh2048_p, NULL);
1914 g = BN_bin2bn(dh2048_g, sizeof dh2048_g, NULL);
Remi Gacogned3a341a2015-05-29 16:26:17 +02001915
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02001916 if (!p || !g) {
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001917 DH_free(dh);
1918 dh = NULL;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02001919 } else {
1920 DH_set0_pqg(dh, p, NULL, g);
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001921 }
1922 }
1923 return dh;
1924}
1925
1926static DH *ssl_get_dh_4096(void)
1927{
Remi Gacogned3a341a2015-05-29 16:26:17 +02001928 static unsigned char dh4096_p[]={
1929 0xDE,0x16,0x94,0xCD,0x99,0x58,0x07,0xF1,0xF7,0x32,0x96,0x11,
1930 0x04,0x82,0xD4,0x84,0x72,0x80,0x99,0x06,0xCA,0xF0,0xA3,0x68,
1931 0x07,0xCE,0x64,0x50,0xE7,0x74,0x45,0x20,0x80,0x5E,0x4D,0xAD,
1932 0xA5,0xB6,0xED,0xFA,0x80,0x6C,0x3B,0x35,0xC4,0x9A,0x14,0x6B,
1933 0x32,0xBB,0xFD,0x1F,0x17,0x8E,0xB7,0x1F,0xD6,0xFA,0x3F,0x7B,
1934 0xEE,0x16,0xA5,0x62,0x33,0x0D,0xED,0xBC,0x4E,0x58,0xE5,0x47,
1935 0x4D,0xE9,0xAB,0x8E,0x38,0xD3,0x6E,0x90,0x57,0xE3,0x22,0x15,
1936 0x33,0xBD,0xF6,0x43,0x45,0xB5,0x10,0x0A,0xBE,0x2C,0xB4,0x35,
1937 0xB8,0x53,0x8D,0xAD,0xFB,0xA7,0x1F,0x85,0x58,0x41,0x7A,0x79,
1938 0x20,0x68,0xB3,0xE1,0x3D,0x08,0x76,0xBF,0x86,0x0D,0x49,0xE3,
1939 0x82,0x71,0x8C,0xB4,0x8D,0x81,0x84,0xD4,0xE7,0xBE,0x91,0xDC,
1940 0x26,0x39,0x48,0x0F,0x35,0xC4,0xCA,0x65,0xE3,0x40,0x93,0x52,
1941 0x76,0x58,0x7D,0xDD,0x51,0x75,0xDC,0x69,0x61,0xBF,0x47,0x2C,
1942 0x16,0x68,0x2D,0xC9,0x29,0xD3,0xE6,0xC0,0x99,0x48,0xA0,0x9A,
1943 0xC8,0x78,0xC0,0x6D,0x81,0x67,0x12,0x61,0x3F,0x71,0xBA,0x41,
1944 0x1F,0x6C,0x89,0x44,0x03,0xBA,0x3B,0x39,0x60,0xAA,0x28,0x55,
1945 0x59,0xAE,0xB8,0xFA,0xCB,0x6F,0xA5,0x1A,0xF7,0x2B,0xDD,0x52,
1946 0x8A,0x8B,0xE2,0x71,0xA6,0x5E,0x7E,0xD8,0x2E,0x18,0xE0,0x66,
1947 0xDF,0xDD,0x22,0x21,0x99,0x52,0x73,0xA6,0x33,0x20,0x65,0x0E,
1948 0x53,0xE7,0x6B,0x9B,0xC5,0xA3,0x2F,0x97,0x65,0x76,0xD3,0x47,
1949 0x23,0x77,0x12,0xB6,0x11,0x7B,0x24,0xED,0xF1,0xEF,0xC0,0xE2,
1950 0xA3,0x7E,0x67,0x05,0x3E,0x96,0x4D,0x45,0xC2,0x18,0xD1,0x73,
1951 0x9E,0x07,0xF3,0x81,0x6E,0x52,0x63,0xF6,0x20,0x76,0xB9,0x13,
1952 0xD2,0x65,0x30,0x18,0x16,0x09,0x16,0x9E,0x8F,0xF1,0xD2,0x10,
1953 0x5A,0xD3,0xD4,0xAF,0x16,0x61,0xDA,0x55,0x2E,0x18,0x5E,0x14,
1954 0x08,0x54,0x2E,0x2A,0x25,0xA2,0x1A,0x9B,0x8B,0x32,0xA9,0xFD,
1955 0xC2,0x48,0x96,0xE1,0x80,0xCA,0xE9,0x22,0x17,0xBB,0xCE,0x3E,
1956 0x9E,0xED,0xC7,0xF1,0x1F,0xEC,0x17,0x21,0xDC,0x7B,0x82,0x48,
1957 0x8E,0xBB,0x4B,0x9D,0x5B,0x04,0x04,0xDA,0xDB,0x39,0xDF,0x01,
1958 0x40,0xC3,0xAA,0x26,0x23,0x89,0x75,0xC6,0x0B,0xD0,0xA2,0x60,
1959 0x6A,0xF1,0xCC,0x65,0x18,0x98,0x1B,0x52,0xD2,0x74,0x61,0xCC,
1960 0xBD,0x60,0xAE,0xA3,0xA0,0x66,0x6A,0x16,0x34,0x92,0x3F,0x41,
1961 0x40,0x31,0x29,0xC0,0x2C,0x63,0xB2,0x07,0x8D,0xEB,0x94,0xB8,
1962 0xE8,0x47,0x92,0x52,0x93,0x6A,0x1B,0x7E,0x1A,0x61,0xB3,0x1B,
1963 0xF0,0xD6,0x72,0x9B,0xF1,0xB0,0xAF,0xBF,0x3E,0x65,0xEF,0x23,
1964 0x1D,0x6F,0xFF,0x70,0xCD,0x8A,0x4C,0x8A,0xA0,0x72,0x9D,0xBE,
1965 0xD4,0xBB,0x24,0x47,0x4A,0x68,0xB5,0xF5,0xC6,0xD5,0x7A,0xCD,
1966 0xCA,0x06,0x41,0x07,0xAD,0xC2,0x1E,0xE6,0x54,0xA7,0xAD,0x03,
1967 0xD9,0x12,0xC1,0x9C,0x13,0xB1,0xC9,0x0A,0x43,0x8E,0x1E,0x08,
1968 0xCE,0x50,0x82,0x73,0x5F,0xA7,0x55,0x1D,0xD9,0x59,0xAC,0xB5,
1969 0xEA,0x02,0x7F,0x6C,0x5B,0x74,0x96,0x98,0x67,0x24,0xA3,0x0F,
1970 0x15,0xFC,0xA9,0x7D,0x3E,0x67,0xD1,0x70,0xF8,0x97,0xF3,0x67,
1971 0xC5,0x8C,0x88,0x44,0x08,0x02,0xC7,0x2B,
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001972 };
Remi Gacogned3a341a2015-05-29 16:26:17 +02001973 static unsigned char dh4096_g[]={
1974 0x02,
1975 };
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001976
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02001977 BIGNUM *p;
1978 BIGNUM *g;
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001979 DH *dh = DH_new();
1980 if (dh) {
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02001981 p = BN_bin2bn(dh4096_p, sizeof dh4096_p, NULL);
1982 g = BN_bin2bn(dh4096_g, sizeof dh4096_g, NULL);
Remi Gacogned3a341a2015-05-29 16:26:17 +02001983
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02001984 if (!p || !g) {
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001985 DH_free(dh);
1986 dh = NULL;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02001987 } else {
1988 DH_set0_pqg(dh, p, NULL, g);
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001989 }
1990 }
1991 return dh;
1992}
1993
1994/* Returns Diffie-Hellman parameters matching the private key length
Willy Tarreauef934602016-12-22 23:12:01 +01001995 but not exceeding global_ssl.default_dh_param */
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001996static DH *ssl_get_tmp_dh(SSL *ssl, int export, int keylen)
1997{
1998 DH *dh = NULL;
1999 EVP_PKEY *pkey = SSL_get_privatekey(ssl);
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02002000 int type;
2001
2002 type = pkey ? EVP_PKEY_base_id(pkey) : EVP_PKEY_NONE;
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002003
2004 /* The keylen supplied by OpenSSL can only be 512 or 1024.
2005 See ssl3_send_server_key_exchange() in ssl/s3_srvr.c
2006 */
2007 if (type == EVP_PKEY_RSA || type == EVP_PKEY_DSA) {
2008 keylen = EVP_PKEY_bits(pkey);
2009 }
2010
Willy Tarreauef934602016-12-22 23:12:01 +01002011 if (keylen > global_ssl.default_dh_param) {
2012 keylen = global_ssl.default_dh_param;
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002013 }
2014
Remi Gacogned3a341a2015-05-29 16:26:17 +02002015 if (keylen >= 4096) {
Remi Gacogne8de54152014-07-15 11:36:40 +02002016 dh = local_dh_4096;
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002017 }
2018 else if (keylen >= 2048) {
Remi Gacogne8de54152014-07-15 11:36:40 +02002019 dh = local_dh_2048;
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002020 }
2021 else {
Remi Gacogne8de54152014-07-15 11:36:40 +02002022 dh = local_dh_1024;
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002023 }
2024
2025 return dh;
2026}
2027
Remi Gacogne47783ef2015-05-29 15:53:22 +02002028static DH * ssl_sock_get_dh_from_file(const char *filename)
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02002029{
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02002030 DH *dh = NULL;
Remi Gacogne47783ef2015-05-29 15:53:22 +02002031 BIO *in = BIO_new(BIO_s_file());
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02002032
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02002033 if (in == NULL)
2034 goto end;
2035
Remi Gacogne47783ef2015-05-29 15:53:22 +02002036 if (BIO_read_filename(in, filename) <= 0)
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02002037 goto end;
2038
Remi Gacogne47783ef2015-05-29 15:53:22 +02002039 dh = PEM_read_bio_DHparams(in, NULL, NULL, NULL);
2040
2041end:
2042 if (in)
2043 BIO_free(in);
2044
2045 return dh;
2046}
2047
2048int ssl_sock_load_global_dh_param_from_file(const char *filename)
2049{
2050 global_dh = ssl_sock_get_dh_from_file(filename);
2051
2052 if (global_dh) {
2053 return 0;
2054 }
2055
2056 return -1;
2057}
2058
2059/* Loads Diffie-Hellman parameter from a file. Returns 1 if loaded, else -1
2060 if an error occured, and 0 if parameter not found. */
2061int ssl_sock_load_dh_params(SSL_CTX *ctx, const char *file)
2062{
2063 int ret = -1;
2064 DH *dh = ssl_sock_get_dh_from_file(file);
2065
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002066 if (dh) {
2067 ret = 1;
2068 SSL_CTX_set_tmp_dh(ctx, dh);
Remi Gacogne4f902b82015-05-28 16:23:00 +02002069
2070 if (ssl_dh_ptr_index >= 0) {
2071 /* store a pointer to the DH params to avoid complaining about
2072 ssl-default-dh-param not being set for this SSL_CTX */
2073 SSL_CTX_set_ex_data(ctx, ssl_dh_ptr_index, dh);
2074 }
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002075 }
Remi Gacogne47783ef2015-05-29 15:53:22 +02002076 else if (global_dh) {
2077 SSL_CTX_set_tmp_dh(ctx, global_dh);
2078 ret = 0; /* DH params not found */
2079 }
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002080 else {
Emeric Brun41fdb3c2013-04-26 11:05:44 +02002081 /* Clear openssl global errors stack */
2082 ERR_clear_error();
2083
Willy Tarreauef934602016-12-22 23:12:01 +01002084 if (global_ssl.default_dh_param <= 1024) {
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002085 /* we are limited to DH parameter of 1024 bits anyway */
Remi Gacognec7e12632016-07-02 16:26:10 +02002086 if (local_dh_1024 == NULL)
2087 local_dh_1024 = ssl_get_dh_1024();
2088
Remi Gacogne8de54152014-07-15 11:36:40 +02002089 if (local_dh_1024 == NULL)
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002090 goto end;
Willy Tarreau6e774b42014-04-25 21:35:23 +02002091
Remi Gacogne8de54152014-07-15 11:36:40 +02002092 SSL_CTX_set_tmp_dh(ctx, local_dh_1024);
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002093 }
2094 else {
2095 SSL_CTX_set_tmp_dh_callback(ctx, ssl_get_tmp_dh);
2096 }
Willy Tarreau6e774b42014-04-25 21:35:23 +02002097
Emeric Brun41fdb3c2013-04-26 11:05:44 +02002098 ret = 0; /* DH params not found */
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02002099 }
Emeric Brun644cde02012-12-14 11:21:13 +01002100
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02002101end:
2102 if (dh)
2103 DH_free(dh);
2104
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02002105 return ret;
2106}
2107#endif
2108
Emmanuel Hocdet05942112017-02-20 16:11:50 +01002109static int ssl_sock_add_cert_sni(SSL_CTX *ctx, struct bind_conf *s, struct ssl_bind_conf *conf,
2110 uint8_t key_sig, char *name, int order)
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002111{
2112 struct sni_ctx *sc;
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02002113 int wild = 0, neg = 0;
Thierry FOURNIER / OZON.IO07c3d782016-10-06 10:56:48 +02002114 struct ebmb_node *node;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002115
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02002116 if (*name == '!') {
2117 neg = 1;
2118 name++;
2119 }
2120 if (*name == '*') {
2121 wild = 1;
2122 name++;
2123 }
2124 /* !* filter is a nop */
2125 if (neg && wild)
2126 return order;
2127 if (*name) {
2128 int j, len;
2129 len = strlen(name);
Thierry FOURNIER / OZON.IO07c3d782016-10-06 10:56:48 +02002130 for (j = 0; j < len && j < trash.size; j++)
2131 trash.str[j] = tolower(name[j]);
2132 if (j >= trash.size)
2133 return order;
2134 trash.str[j] = 0;
2135
2136 /* Check for duplicates. */
2137 if (wild)
2138 node = ebst_lookup(&s->sni_w_ctx, trash.str);
2139 else
2140 node = ebst_lookup(&s->sni_ctx, trash.str);
2141 for (; node; node = ebmb_next_dup(node)) {
2142 sc = ebmb_entry(node, struct sni_ctx, name);
Emmanuel Hocdet05942112017-02-20 16:11:50 +01002143 if (sc->ctx == ctx && sc->conf == conf &&
2144 sc->key_sig == key_sig && sc->neg == neg)
Thierry FOURNIER / OZON.IO07c3d782016-10-06 10:56:48 +02002145 return order;
2146 }
2147
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002148 sc = malloc(sizeof(struct sni_ctx) + len + 1);
Thierry FOURNIER / OZON.IO7a3bd3b2016-10-06 10:35:29 +02002149 if (!sc)
2150 return order;
Thierry FOURNIER / OZON.IO07c3d782016-10-06 10:56:48 +02002151 memcpy(sc->name.key, trash.str, len + 1);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002152 sc->ctx = ctx;
Emmanuel Hocdet98263292016-12-29 18:26:15 +01002153 sc->conf = conf;
Emmanuel Hocdet05942112017-02-20 16:11:50 +01002154 sc->key_sig = key_sig;
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02002155 sc->order = order++;
2156 sc->neg = neg;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002157 if (wild)
2158 ebst_insert(&s->sni_w_ctx, &sc->name);
2159 else
2160 ebst_insert(&s->sni_ctx, &sc->name);
2161 }
2162 return order;
2163}
2164
yanbzhu488a4d22015-12-01 15:16:07 -05002165
2166/* The following code is used for loading multiple crt files into
2167 * SSL_CTX's based on CN/SAN
2168 */
Luca Pizzamiglio578b1692016-12-12 10:56:56 +01002169#if OPENSSL_VERSION_NUMBER >= 0x1000200fL && !defined(LIBRESSL_VERSION_NUMBER)
yanbzhu488a4d22015-12-01 15:16:07 -05002170/* This is used to preload the certifcate, private key
2171 * and Cert Chain of a file passed in via the crt
2172 * argument
2173 *
2174 * This way, we do not have to read the file multiple times
2175 */
2176struct cert_key_and_chain {
2177 X509 *cert;
2178 EVP_PKEY *key;
2179 unsigned int num_chain_certs;
2180 /* This is an array of X509 pointers */
2181 X509 **chain_certs;
2182};
2183
yanbzhu08ce6ab2015-12-02 13:01:29 -05002184#define SSL_SOCK_POSSIBLE_KT_COMBOS (1<<(SSL_SOCK_NUM_KEYTYPES))
2185
2186struct key_combo_ctx {
2187 SSL_CTX *ctx;
2188 int order;
2189};
2190
2191/* Map used for processing multiple keypairs for a single purpose
2192 *
2193 * This maps CN/SNI name to certificate type
2194 */
2195struct sni_keytype {
2196 int keytypes; /* BITMASK for keytypes */
2197 struct ebmb_node name; /* node holding the servername value */
2198};
2199
2200
yanbzhu488a4d22015-12-01 15:16:07 -05002201/* Frees the contents of a cert_key_and_chain
2202 */
2203static void ssl_sock_free_cert_key_and_chain_contents(struct cert_key_and_chain *ckch)
2204{
2205 int i;
2206
2207 if (!ckch)
2208 return;
2209
2210 /* Free the certificate and set pointer to NULL */
2211 if (ckch->cert)
2212 X509_free(ckch->cert);
2213 ckch->cert = NULL;
2214
2215 /* Free the key and set pointer to NULL */
2216 if (ckch->key)
2217 EVP_PKEY_free(ckch->key);
2218 ckch->key = NULL;
2219
2220 /* Free each certificate in the chain */
2221 for (i = 0; i < ckch->num_chain_certs; i++) {
2222 if (ckch->chain_certs[i])
2223 X509_free(ckch->chain_certs[i]);
2224 }
2225
2226 /* Free the chain obj itself and set to NULL */
2227 if (ckch->num_chain_certs > 0) {
2228 free(ckch->chain_certs);
2229 ckch->num_chain_certs = 0;
2230 ckch->chain_certs = NULL;
2231 }
2232
2233}
2234
2235/* checks if a key and cert exists in the ckch
2236 */
2237static int ssl_sock_is_ckch_valid(struct cert_key_and_chain *ckch)
2238{
2239 return (ckch->cert != NULL && ckch->key != NULL);
2240}
2241
2242
2243/* Loads the contents of a crt file (path) into a cert_key_and_chain
2244 * This allows us to carry the contents of the file without having to
2245 * read the file multiple times.
2246 *
2247 * returns:
2248 * 0 on Success
2249 * 1 on SSL Failure
2250 * 2 on file not found
2251 */
2252static int ssl_sock_load_crt_file_into_ckch(const char *path, struct cert_key_and_chain *ckch, char **err)
2253{
2254
2255 BIO *in;
2256 X509 *ca = NULL;
2257 int ret = 1;
2258
2259 ssl_sock_free_cert_key_and_chain_contents(ckch);
2260
2261 in = BIO_new(BIO_s_file());
2262 if (in == NULL)
2263 goto end;
2264
2265 if (BIO_read_filename(in, path) <= 0)
2266 goto end;
2267
yanbzhu488a4d22015-12-01 15:16:07 -05002268 /* Read Private Key */
2269 ckch->key = PEM_read_bio_PrivateKey(in, NULL, NULL, NULL);
2270 if (ckch->key == NULL) {
2271 memprintf(err, "%sunable to load private key from file '%s'.\n",
2272 err && *err ? *err : "", path);
2273 goto end;
2274 }
2275
Willy Tarreaubb137a82016-04-06 19:02:38 +02002276 /* Seek back to beginning of file */
Thierry FOURNIER / OZON.IOd44ea3f2016-10-14 00:49:21 +02002277 if (BIO_reset(in) == -1) {
2278 memprintf(err, "%san error occurred while reading the file '%s'.\n",
2279 err && *err ? *err : "", path);
2280 goto end;
2281 }
Willy Tarreaubb137a82016-04-06 19:02:38 +02002282
2283 /* Read Certificate */
2284 ckch->cert = PEM_read_bio_X509_AUX(in, NULL, NULL, NULL);
2285 if (ckch->cert == NULL) {
2286 memprintf(err, "%sunable to load certificate from file '%s'.\n",
2287 err && *err ? *err : "", path);
2288 goto end;
2289 }
2290
yanbzhu488a4d22015-12-01 15:16:07 -05002291 /* Read Certificate Chain */
2292 while ((ca = PEM_read_bio_X509(in, NULL, NULL, NULL))) {
2293 /* Grow the chain certs */
2294 ckch->num_chain_certs++;
2295 ckch->chain_certs = realloc(ckch->chain_certs, (ckch->num_chain_certs * sizeof(X509 *)));
2296
2297 /* use - 1 here since we just incremented it above */
2298 ckch->chain_certs[ckch->num_chain_certs - 1] = ca;
2299 }
2300 ret = ERR_get_error();
2301 if (ret && (ERR_GET_LIB(ret) != ERR_LIB_PEM && ERR_GET_REASON(ret) != PEM_R_NO_START_LINE)) {
2302 memprintf(err, "%sunable to load certificate chain from file '%s'.\n",
2303 err && *err ? *err : "", path);
2304 ret = 1;
2305 goto end;
2306 }
2307
2308 ret = 0;
2309
2310end:
2311
2312 ERR_clear_error();
2313 if (in)
2314 BIO_free(in);
2315
2316 /* Something went wrong in one of the reads */
2317 if (ret != 0)
2318 ssl_sock_free_cert_key_and_chain_contents(ckch);
2319
2320 return ret;
2321}
2322
2323/* Loads the info in ckch into ctx
2324 * Currently, this does not process any information about ocsp, dhparams or
2325 * sctl
2326 * Returns
2327 * 0 on success
2328 * 1 on failure
2329 */
2330static int ssl_sock_put_ckch_into_ctx(const char *path, const struct cert_key_and_chain *ckch, SSL_CTX *ctx, char **err)
2331{
2332 int i = 0;
2333
2334 if (SSL_CTX_use_PrivateKey(ctx, ckch->key) <= 0) {
2335 memprintf(err, "%sunable to load SSL private key into SSL Context '%s'.\n",
2336 err && *err ? *err : "", path);
2337 return 1;
2338 }
2339
2340 if (!SSL_CTX_use_certificate(ctx, ckch->cert)) {
2341 memprintf(err, "%sunable to load SSL certificate into SSL Context '%s'.\n",
2342 err && *err ? *err : "", path);
2343 return 1;
2344 }
2345
yanbzhu488a4d22015-12-01 15:16:07 -05002346 /* Load all certs in the ckch into the ctx_chain for the ssl_ctx */
2347 for (i = 0; i < ckch->num_chain_certs; i++) {
2348 if (!SSL_CTX_add1_chain_cert(ctx, ckch->chain_certs[i])) {
yanbzhu08ce6ab2015-12-02 13:01:29 -05002349 memprintf(err, "%sunable to load chain certificate #%d into SSL Context '%s'. Make sure you are linking against Openssl >= 1.0.2.\n",
2350 err && *err ? *err : "", (i+1), path);
yanbzhu488a4d22015-12-01 15:16:07 -05002351 return 1;
2352 }
2353 }
2354
2355 if (SSL_CTX_check_private_key(ctx) <= 0) {
2356 memprintf(err, "%sinconsistencies between private key and certificate loaded from PEM file '%s'.\n",
2357 err && *err ? *err : "", path);
2358 return 1;
2359 }
2360
2361 return 0;
2362}
2363
yanbzhu08ce6ab2015-12-02 13:01:29 -05002364
2365static void ssl_sock_populate_sni_keytypes_hplr(const char *str, struct eb_root *sni_keytypes, int key_index)
2366{
2367 struct sni_keytype *s_kt = NULL;
2368 struct ebmb_node *node;
2369 int i;
2370
2371 for (i = 0; i < trash.size; i++) {
2372 if (!str[i])
2373 break;
2374 trash.str[i] = tolower(str[i]);
2375 }
2376 trash.str[i] = 0;
2377 node = ebst_lookup(sni_keytypes, trash.str);
2378 if (!node) {
2379 /* CN not found in tree */
2380 s_kt = malloc(sizeof(struct sni_keytype) + i + 1);
2381 /* Using memcpy here instead of strncpy.
2382 * strncpy will cause sig_abrt errors under certain versions of gcc with -O2
2383 * See: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=60792
2384 */
2385 memcpy(s_kt->name.key, trash.str, i+1);
2386 s_kt->keytypes = 0;
2387 ebst_insert(sni_keytypes, &s_kt->name);
2388 } else {
2389 /* CN found in tree */
2390 s_kt = container_of(node, struct sni_keytype, name);
2391 }
2392
2393 /* Mark that this CN has the keytype of key_index via keytypes mask */
2394 s_kt->keytypes |= 1<<key_index;
2395
2396}
2397
2398
2399/* Given a path that does not exist, try to check for path.rsa, path.dsa and path.ecdsa files.
2400 * If any are found, group these files into a set of SSL_CTX*
2401 * based on shared and unique CN and SAN entries. Add these SSL_CTX* to the SNI tree.
2402 *
2403 * This will allow the user to explictly group multiple cert/keys for a single purpose
2404 *
2405 * Returns
2406 * 0 on success
2407 * 1 on failure
2408 */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01002409static int ssl_sock_load_multi_cert(const char *path, struct bind_conf *bind_conf, struct ssl_bind_conf *ssl_conf,
2410 char **sni_filter, int fcount, char **err)
yanbzhu08ce6ab2015-12-02 13:01:29 -05002411{
2412 char fp[MAXPATHLEN+1] = {0};
2413 int n = 0;
2414 int i = 0;
2415 struct cert_key_and_chain certs_and_keys[SSL_SOCK_NUM_KEYTYPES] = { {0} };
2416 struct eb_root sni_keytypes_map = { {0} };
2417 struct ebmb_node *node;
2418 struct ebmb_node *next;
2419 /* Array of SSL_CTX pointers corresponding to each possible combo
2420 * of keytypes
2421 */
2422 struct key_combo_ctx key_combos[SSL_SOCK_POSSIBLE_KT_COMBOS] = { {0} };
2423 int rv = 0;
2424 X509_NAME *xname = NULL;
2425 char *str = NULL;
2426#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
2427 STACK_OF(GENERAL_NAME) *names = NULL;
2428#endif
2429
2430 /* Load all possible certs and keys */
2431 for (n = 0; n < SSL_SOCK_NUM_KEYTYPES; n++) {
2432 struct stat buf;
2433
2434 snprintf(fp, sizeof(fp), "%s.%s", path, SSL_SOCK_KEYTYPE_NAMES[n]);
2435 if (stat(fp, &buf) == 0) {
2436 if (ssl_sock_load_crt_file_into_ckch(fp, &certs_and_keys[n], err) == 1) {
2437 rv = 1;
2438 goto end;
2439 }
2440 }
2441 }
2442
2443 /* Process each ckch and update keytypes for each CN/SAN
2444 * for example, if CN/SAN www.a.com is associated with
2445 * certs with keytype 0 and 2, then at the end of the loop,
2446 * www.a.com will have:
2447 * keyindex = 0 | 1 | 4 = 5
2448 */
2449 for (n = 0; n < SSL_SOCK_NUM_KEYTYPES; n++) {
2450
2451 if (!ssl_sock_is_ckch_valid(&certs_and_keys[n]))
2452 continue;
2453
Emmanuel Hocdetd294aea2016-05-13 11:14:06 +02002454 if (fcount) {
Willy Tarreau24b892f2016-06-20 23:01:57 +02002455 for (i = 0; i < fcount; i++)
Emmanuel Hocdetd294aea2016-05-13 11:14:06 +02002456 ssl_sock_populate_sni_keytypes_hplr(sni_filter[i], &sni_keytypes_map, n);
2457 } else {
2458 /* A lot of the following code is OpenSSL boilerplate for processing CN's and SAN's,
2459 * so the line that contains logic is marked via comments
2460 */
2461 xname = X509_get_subject_name(certs_and_keys[n].cert);
2462 i = -1;
2463 while ((i = X509_NAME_get_index_by_NID(xname, NID_commonName, i)) != -1) {
2464 X509_NAME_ENTRY *entry = X509_NAME_get_entry(xname, i);
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02002465 ASN1_STRING *value;
2466 value = X509_NAME_ENTRY_get_data(entry);
2467 if (ASN1_STRING_to_UTF8((unsigned char **)&str, value) >= 0) {
Emmanuel Hocdetd294aea2016-05-13 11:14:06 +02002468 /* Important line is here */
2469 ssl_sock_populate_sni_keytypes_hplr(str, &sni_keytypes_map, n);
yanbzhu08ce6ab2015-12-02 13:01:29 -05002470
Emmanuel Hocdetd294aea2016-05-13 11:14:06 +02002471 OPENSSL_free(str);
2472 str = NULL;
2473 }
yanbzhu08ce6ab2015-12-02 13:01:29 -05002474 }
yanbzhu08ce6ab2015-12-02 13:01:29 -05002475
Emmanuel Hocdetd294aea2016-05-13 11:14:06 +02002476 /* Do the above logic for each SAN */
yanbzhu08ce6ab2015-12-02 13:01:29 -05002477#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Emmanuel Hocdetd294aea2016-05-13 11:14:06 +02002478 names = X509_get_ext_d2i(certs_and_keys[n].cert, NID_subject_alt_name, NULL, NULL);
2479 if (names) {
2480 for (i = 0; i < sk_GENERAL_NAME_num(names); i++) {
2481 GENERAL_NAME *name = sk_GENERAL_NAME_value(names, i);
yanbzhu08ce6ab2015-12-02 13:01:29 -05002482
Emmanuel Hocdetd294aea2016-05-13 11:14:06 +02002483 if (name->type == GEN_DNS) {
2484 if (ASN1_STRING_to_UTF8((unsigned char **)&str, name->d.dNSName) >= 0) {
2485 /* Important line is here */
2486 ssl_sock_populate_sni_keytypes_hplr(str, &sni_keytypes_map, n);
yanbzhu08ce6ab2015-12-02 13:01:29 -05002487
Emmanuel Hocdetd294aea2016-05-13 11:14:06 +02002488 OPENSSL_free(str);
2489 str = NULL;
2490 }
yanbzhu08ce6ab2015-12-02 13:01:29 -05002491 }
2492 }
2493 }
2494 }
2495#endif /* SSL_CTRL_SET_TLSEXT_HOSTNAME */
2496 }
2497
2498 /* If no files found, return error */
2499 if (eb_is_empty(&sni_keytypes_map)) {
2500 memprintf(err, "%sunable to load SSL certificate file '%s' file does not exist.\n",
2501 err && *err ? *err : "", path);
2502 rv = 1;
2503 goto end;
2504 }
2505
2506 /* We now have a map of CN/SAN to keytypes that are loaded in
2507 * Iterate through the map to create the SSL_CTX's (if needed)
2508 * and add each CTX to the SNI tree
2509 *
2510 * Some math here:
2511 * There are 2^n - 1 possibile combinations, each unique
2512 * combination is denoted by the key in the map. Each key
2513 * has a value between 1 and 2^n - 1. Conveniently, the array
2514 * of SSL_CTX* is sized 2^n. So, we can simply use the i'th
2515 * entry in the array to correspond to the unique combo (key)
2516 * associated with i. This unique key combo (i) will be associated
2517 * with combos[i-1]
2518 */
2519
2520 node = ebmb_first(&sni_keytypes_map);
2521 while (node) {
2522 SSL_CTX *cur_ctx;
Bertrand Jacquin33423092016-11-13 16:37:13 +00002523 char cur_file[MAXPATHLEN+1];
yanbzhu08ce6ab2015-12-02 13:01:29 -05002524
2525 str = (char *)container_of(node, struct sni_keytype, name)->name.key;
2526 i = container_of(node, struct sni_keytype, name)->keytypes;
2527 cur_ctx = key_combos[i-1].ctx;
2528
2529 if (cur_ctx == NULL) {
2530 /* need to create SSL_CTX */
Emmanuel Hocdetf6b37c62017-03-06 15:34:44 +01002531 cur_ctx = SSL_CTX_new(SSLv23_server_method());
yanbzhu08ce6ab2015-12-02 13:01:29 -05002532 if (cur_ctx == NULL) {
2533 memprintf(err, "%sunable to allocate SSL context.\n",
2534 err && *err ? *err : "");
2535 rv = 1;
2536 goto end;
2537 }
2538
yanbzhube2774d2015-12-10 15:07:30 -05002539 /* Load all required certs/keys/chains/OCSPs info into SSL_CTX */
yanbzhu08ce6ab2015-12-02 13:01:29 -05002540 for (n = 0; n < SSL_SOCK_NUM_KEYTYPES; n++) {
2541 if (i & (1<<n)) {
2542 /* Key combo contains ckch[n] */
Bertrand Jacquin33423092016-11-13 16:37:13 +00002543 snprintf(cur_file, MAXPATHLEN+1, "%s.%s", path, SSL_SOCK_KEYTYPE_NAMES[n]);
2544 if (ssl_sock_put_ckch_into_ctx(cur_file, &certs_and_keys[n], cur_ctx, err) != 0) {
yanbzhu08ce6ab2015-12-02 13:01:29 -05002545 SSL_CTX_free(cur_ctx);
2546 rv = 1;
2547 goto end;
2548 }
yanbzhube2774d2015-12-10 15:07:30 -05002549
2550#if (defined SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB && !defined OPENSSL_NO_OCSP)
2551 /* Load OCSP Info into context */
Bertrand Jacquin33423092016-11-13 16:37:13 +00002552 if (ssl_sock_load_ocsp(cur_ctx, cur_file) < 0) {
yanbzhube2774d2015-12-10 15:07:30 -05002553 if (err)
2554 memprintf(err, "%s '%s.ocsp' is present and activates OCSP but it is impossible to compute the OCSP certificate ID (maybe the issuer could not be found)'.\n",
Bertrand Jacquin5424ee02016-11-13 16:37:14 +00002555 *err ? *err : "", cur_file);
yanbzhube2774d2015-12-10 15:07:30 -05002556 SSL_CTX_free(cur_ctx);
2557 rv = 1;
2558 goto end;
2559 }
2560#endif
yanbzhu08ce6ab2015-12-02 13:01:29 -05002561 }
2562 }
2563
2564 /* Load DH params into the ctx to support DHE keys */
2565#ifndef OPENSSL_NO_DH
2566 if (ssl_dh_ptr_index >= 0)
2567 SSL_CTX_set_ex_data(cur_ctx, ssl_dh_ptr_index, NULL);
2568
2569 rv = ssl_sock_load_dh_params(cur_ctx, NULL);
2570 if (rv < 0) {
2571 if (err)
2572 memprintf(err, "%sunable to load DH parameters from file '%s'.\n",
2573 *err ? *err : "", path);
2574 rv = 1;
2575 goto end;
2576 }
2577#endif
2578
2579 /* Update key_combos */
2580 key_combos[i-1].ctx = cur_ctx;
2581 }
2582
2583 /* Update SNI Tree */
Emmanuel Hocdet05942112017-02-20 16:11:50 +01002584 key_combos[i-1].order = ssl_sock_add_cert_sni(cur_ctx, bind_conf, ssl_conf,
2585 TLSEXT_signature_anonymous, str, key_combos[i-1].order);
yanbzhu08ce6ab2015-12-02 13:01:29 -05002586 node = ebmb_next(node);
2587 }
2588
2589
2590 /* Mark a default context if none exists, using the ctx that has the most shared keys */
2591 if (!bind_conf->default_ctx) {
2592 for (i = SSL_SOCK_POSSIBLE_KT_COMBOS - 1; i >= 0; i--) {
2593 if (key_combos[i].ctx) {
2594 bind_conf->default_ctx = key_combos[i].ctx;
Emmanuel Hocdet98263292016-12-29 18:26:15 +01002595 bind_conf->default_ssl_conf = ssl_conf;
yanbzhu08ce6ab2015-12-02 13:01:29 -05002596 break;
2597 }
2598 }
2599 }
2600
2601end:
2602
2603 if (names)
2604 sk_GENERAL_NAME_pop_free(names, GENERAL_NAME_free);
2605
2606 for (n = 0; n < SSL_SOCK_NUM_KEYTYPES; n++)
2607 ssl_sock_free_cert_key_and_chain_contents(&certs_and_keys[n]);
2608
2609 node = ebmb_first(&sni_keytypes_map);
2610 while (node) {
2611 next = ebmb_next(node);
2612 ebmb_delete(node);
2613 node = next;
2614 }
2615
2616 return rv;
2617}
2618#else
2619/* This is a dummy, that just logs an error and returns error */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01002620static int ssl_sock_load_multi_cert(const char *path, struct bind_conf *bind_conf, struct ssl_bind_conf *ssl_conf,
2621 char **sni_filter, int fcount, char **err)
yanbzhu08ce6ab2015-12-02 13:01:29 -05002622{
2623 memprintf(err, "%sunable to stat SSL certificate from file '%s' : %s.\n",
2624 err && *err ? *err : "", path, strerror(errno));
2625 return 1;
2626}
2627
yanbzhu488a4d22015-12-01 15:16:07 -05002628#endif /* #if OPENSSL_VERSION_NUMBER >= 0x1000200fL: Support for loading multiple certs into a single SSL_CTX */
2629
Emeric Brunfc0421f2012-09-07 17:30:07 +02002630/* Loads a certificate key and CA chain from a file. Returns 0 on error, -1 if
2631 * an early error happens and the caller must call SSL_CTX_free() by itelf.
2632 */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01002633static int ssl_sock_load_cert_chain_file(SSL_CTX *ctx, const char *file, struct bind_conf *s,
2634 struct ssl_bind_conf *ssl_conf, char **sni_filter, int fcount)
Emeric Brunfc0421f2012-09-07 17:30:07 +02002635{
2636 BIO *in;
2637 X509 *x = NULL, *ca;
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02002638 int i, err;
Emeric Brunfc0421f2012-09-07 17:30:07 +02002639 int ret = -1;
2640 int order = 0;
2641 X509_NAME *xname;
2642 char *str;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02002643 pem_password_cb *passwd_cb;
2644 void *passwd_cb_userdata;
Emmanuel Hocdet05942112017-02-20 16:11:50 +01002645 EVP_PKEY *pkey;
2646 uint8_t key_sig = TLSEXT_signature_anonymous;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02002647
Emeric Brunfc0421f2012-09-07 17:30:07 +02002648#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
2649 STACK_OF(GENERAL_NAME) *names;
2650#endif
2651
2652 in = BIO_new(BIO_s_file());
2653 if (in == NULL)
2654 goto end;
2655
2656 if (BIO_read_filename(in, file) <= 0)
2657 goto end;
2658
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02002659
2660 passwd_cb = SSL_CTX_get_default_passwd_cb(ctx);
2661 passwd_cb_userdata = SSL_CTX_get_default_passwd_cb_userdata(ctx);
2662
2663 x = PEM_read_bio_X509_AUX(in, NULL, passwd_cb, passwd_cb_userdata);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002664 if (x == NULL)
2665 goto end;
2666
Emmanuel Hocdet05942112017-02-20 16:11:50 +01002667 pkey = X509_get_pubkey(x);
2668 if (pkey) {
2669 switch(EVP_PKEY_base_id(pkey)) {
2670 case EVP_PKEY_RSA:
2671 key_sig = TLSEXT_signature_rsa;
2672 break;
2673 case EVP_PKEY_EC:
2674 key_sig = TLSEXT_signature_ecdsa;
2675 break;
2676 }
2677 EVP_PKEY_free(pkey);
2678 }
2679
Emeric Brun50bcecc2013-04-22 13:05:23 +02002680 if (fcount) {
2681 while (fcount--)
Emmanuel Hocdet05942112017-02-20 16:11:50 +01002682 order = ssl_sock_add_cert_sni(ctx, s, ssl_conf, key_sig, sni_filter[fcount], order);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002683 }
2684 else {
Emeric Brunfc0421f2012-09-07 17:30:07 +02002685#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002686 names = X509_get_ext_d2i(x, NID_subject_alt_name, NULL, NULL);
2687 if (names) {
2688 for (i = 0; i < sk_GENERAL_NAME_num(names); i++) {
2689 GENERAL_NAME *name = sk_GENERAL_NAME_value(names, i);
2690 if (name->type == GEN_DNS) {
2691 if (ASN1_STRING_to_UTF8((unsigned char **)&str, name->d.dNSName) >= 0) {
Emmanuel Hocdet05942112017-02-20 16:11:50 +01002692 order = ssl_sock_add_cert_sni(ctx, s, ssl_conf, key_sig, str, order);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002693 OPENSSL_free(str);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002694 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02002695 }
2696 }
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002697 sk_GENERAL_NAME_pop_free(names, GENERAL_NAME_free);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002698 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02002699#endif /* SSL_CTRL_SET_TLSEXT_HOSTNAME */
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002700 xname = X509_get_subject_name(x);
2701 i = -1;
2702 while ((i = X509_NAME_get_index_by_NID(xname, NID_commonName, i)) != -1) {
2703 X509_NAME_ENTRY *entry = X509_NAME_get_entry(xname, i);
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02002704 ASN1_STRING *value;
2705
2706 value = X509_NAME_ENTRY_get_data(entry);
2707 if (ASN1_STRING_to_UTF8((unsigned char **)&str, value) >= 0) {
Emmanuel Hocdet05942112017-02-20 16:11:50 +01002708 order = ssl_sock_add_cert_sni(ctx, s, ssl_conf, key_sig, str, order);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002709 OPENSSL_free(str);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002710 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02002711 }
2712 }
2713
2714 ret = 0; /* the caller must not free the SSL_CTX argument anymore */
2715 if (!SSL_CTX_use_certificate(ctx, x))
2716 goto end;
2717
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02002718#ifdef SSL_CTX_clear_extra_chain_certs
2719 SSL_CTX_clear_extra_chain_certs(ctx);
2720#else
Emeric Brunfc0421f2012-09-07 17:30:07 +02002721 if (ctx->extra_certs != NULL) {
2722 sk_X509_pop_free(ctx->extra_certs, X509_free);
2723 ctx->extra_certs = NULL;
2724 }
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02002725#endif
Emeric Brunfc0421f2012-09-07 17:30:07 +02002726
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02002727 while ((ca = PEM_read_bio_X509(in, NULL, passwd_cb, passwd_cb_userdata))) {
Emeric Brunfc0421f2012-09-07 17:30:07 +02002728 if (!SSL_CTX_add_extra_chain_cert(ctx, ca)) {
2729 X509_free(ca);
2730 goto end;
2731 }
2732 }
2733
2734 err = ERR_get_error();
2735 if (!err || (ERR_GET_LIB(err) == ERR_LIB_PEM && ERR_GET_REASON(err) == PEM_R_NO_START_LINE)) {
2736 /* we successfully reached the last cert in the file */
2737 ret = 1;
2738 }
2739 ERR_clear_error();
2740
2741end:
2742 if (x)
2743 X509_free(x);
2744
2745 if (in)
2746 BIO_free(in);
2747
2748 return ret;
2749}
2750
Emmanuel Hocdet98263292016-12-29 18:26:15 +01002751static int ssl_sock_load_cert_file(const char *path, struct bind_conf *bind_conf, struct ssl_bind_conf *ssl_conf,
2752 char **sni_filter, int fcount, char **err)
Emeric Brunfc0421f2012-09-07 17:30:07 +02002753{
2754 int ret;
2755 SSL_CTX *ctx;
2756
Emmanuel Hocdetf6b37c62017-03-06 15:34:44 +01002757 ctx = SSL_CTX_new(SSLv23_server_method());
Emeric Brunfc0421f2012-09-07 17:30:07 +02002758 if (!ctx) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02002759 memprintf(err, "%sunable to allocate SSL context for cert '%s'.\n",
2760 err && *err ? *err : "", path);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002761 return 1;
2762 }
2763
2764 if (SSL_CTX_use_PrivateKey_file(ctx, path, SSL_FILETYPE_PEM) <= 0) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02002765 memprintf(err, "%sunable to load SSL private key from PEM file '%s'.\n",
2766 err && *err ? *err : "", path);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002767 SSL_CTX_free(ctx);
2768 return 1;
2769 }
2770
Emmanuel Hocdet98263292016-12-29 18:26:15 +01002771 ret = ssl_sock_load_cert_chain_file(ctx, path, bind_conf, ssl_conf, sni_filter, fcount);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002772 if (ret <= 0) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02002773 memprintf(err, "%sunable to load SSL certificate from PEM file '%s'.\n",
2774 err && *err ? *err : "", path);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002775 if (ret < 0) /* serious error, must do that ourselves */
2776 SSL_CTX_free(ctx);
2777 return 1;
2778 }
Emeric Brun61694ab2012-10-26 13:35:33 +02002779
2780 if (SSL_CTX_check_private_key(ctx) <= 0) {
2781 memprintf(err, "%sinconsistencies between private key and certificate loaded from PEM file '%s'.\n",
2782 err && *err ? *err : "", path);
2783 return 1;
2784 }
2785
Emeric Brunfc0421f2012-09-07 17:30:07 +02002786 /* we must not free the SSL_CTX anymore below, since it's already in
2787 * the tree, so it will be discovered and cleaned in time.
2788 */
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02002789#ifndef OPENSSL_NO_DH
Remi Gacogne4f902b82015-05-28 16:23:00 +02002790 /* store a NULL pointer to indicate we have not yet loaded
2791 a custom DH param file */
2792 if (ssl_dh_ptr_index >= 0) {
2793 SSL_CTX_set_ex_data(ctx, ssl_dh_ptr_index, NULL);
2794 }
2795
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02002796 ret = ssl_sock_load_dh_params(ctx, path);
2797 if (ret < 0) {
2798 if (err)
2799 memprintf(err, "%sunable to load DH parameters from file '%s'.\n",
2800 *err ? *err : "", path);
2801 return 1;
2802 }
2803#endif
2804
Lukas Tribuse4e30f72014-12-09 16:32:51 +01002805#if (defined SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB && !defined OPENSSL_NO_OCSP)
Emeric Brun4147b2e2014-06-16 18:36:30 +02002806 ret = ssl_sock_load_ocsp(ctx, path);
2807 if (ret < 0) {
2808 if (err)
2809 memprintf(err, "%s '%s.ocsp' is present and activates OCSP but it is impossible to compute the OCSP certificate ID (maybe the issuer could not be found)'.\n",
2810 *err ? *err : "", path);
2811 return 1;
2812 }
2813#endif
2814
Daniel Jakots54ffb912015-11-06 20:02:41 +01002815#if (OPENSSL_VERSION_NUMBER >= 0x1000200fL && !defined OPENSSL_NO_TLSEXT && !defined OPENSSL_IS_BORINGSSL && !defined LIBRESSL_VERSION_NUMBER)
Janusz Dziemidowicz2c701b52015-03-07 23:03:59 +01002816 if (sctl_ex_index >= 0) {
2817 ret = ssl_sock_load_sctl(ctx, path);
2818 if (ret < 0) {
2819 if (err)
2820 memprintf(err, "%s '%s.sctl' is present but cannot be read or parsed'.\n",
2821 *err ? *err : "", path);
2822 return 1;
2823 }
2824 }
2825#endif
2826
Emeric Brunfc0421f2012-09-07 17:30:07 +02002827#ifndef SSL_CTRL_SET_TLSEXT_HOSTNAME
Willy Tarreau2a65ff02012-09-13 17:54:29 +02002828 if (bind_conf->default_ctx) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02002829 memprintf(err, "%sthis version of openssl cannot load multiple SSL certificates.\n",
2830 err && *err ? *err : "");
Emeric Brunfc0421f2012-09-07 17:30:07 +02002831 return 1;
2832 }
2833#endif
Emmanuel Hocdet98263292016-12-29 18:26:15 +01002834 if (!bind_conf->default_ctx) {
Willy Tarreau2a65ff02012-09-13 17:54:29 +02002835 bind_conf->default_ctx = ctx;
Emmanuel Hocdet98263292016-12-29 18:26:15 +01002836 bind_conf->default_ssl_conf = ssl_conf;
2837 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02002838
2839 return 0;
2840}
2841
Willy Tarreau03209342016-12-22 17:08:28 +01002842int ssl_sock_load_cert(char *path, struct bind_conf *bind_conf, char **err)
Emeric Brunfc0421f2012-09-07 17:30:07 +02002843{
Cyril Bonté3180f7b2015-01-25 00:16:08 +01002844 struct dirent **de_list;
2845 int i, n;
Emeric Brunfc0421f2012-09-07 17:30:07 +02002846 DIR *dir;
2847 struct stat buf;
Willy Tarreauee2663b2012-12-06 11:36:59 +01002848 char *end;
2849 char fp[MAXPATHLEN+1];
Emeric Brunfc0421f2012-09-07 17:30:07 +02002850 int cfgerr = 0;
yanbzhu63ea8462015-12-09 13:35:14 -05002851#if OPENSSL_VERSION_NUMBER >= 0x1000200fL
2852 int is_bundle;
2853 int j;
2854#endif
Emeric Brunfc0421f2012-09-07 17:30:07 +02002855
yanbzhu08ce6ab2015-12-02 13:01:29 -05002856 if (stat(path, &buf) == 0) {
2857 dir = opendir(path);
2858 if (!dir)
Emmanuel Hocdet98263292016-12-29 18:26:15 +01002859 return ssl_sock_load_cert_file(path, bind_conf, NULL, NULL, 0, err);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002860
yanbzhu08ce6ab2015-12-02 13:01:29 -05002861 /* strip trailing slashes, including first one */
2862 for (end = path + strlen(path) - 1; end >= path && *end == '/'; end--)
2863 *end = 0;
Emeric Brunfc0421f2012-09-07 17:30:07 +02002864
yanbzhu08ce6ab2015-12-02 13:01:29 -05002865 n = scandir(path, &de_list, 0, alphasort);
2866 if (n < 0) {
2867 memprintf(err, "%sunable to scan directory '%s' : %s.\n",
2868 err && *err ? *err : "", path, strerror(errno));
2869 cfgerr++;
2870 }
2871 else {
2872 for (i = 0; i < n; i++) {
2873 struct dirent *de = de_list[i];
Emeric Brun2aab7222014-06-18 18:15:09 +02002874
yanbzhu08ce6ab2015-12-02 13:01:29 -05002875 end = strrchr(de->d_name, '.');
2876 if (end && (!strcmp(end, ".issuer") || !strcmp(end, ".ocsp") || !strcmp(end, ".sctl")))
2877 goto ignore_entry;
Cyril Bonté3180f7b2015-01-25 00:16:08 +01002878
yanbzhu08ce6ab2015-12-02 13:01:29 -05002879 snprintf(fp, sizeof(fp), "%s/%s", path, de->d_name);
2880 if (stat(fp, &buf) != 0) {
2881 memprintf(err, "%sunable to stat SSL certificate from file '%s' : %s.\n",
2882 err && *err ? *err : "", fp, strerror(errno));
2883 cfgerr++;
2884 goto ignore_entry;
2885 }
2886 if (!S_ISREG(buf.st_mode))
2887 goto ignore_entry;
yanbzhu63ea8462015-12-09 13:35:14 -05002888
2889#if OPENSSL_VERSION_NUMBER >= 0x1000200fL
2890 is_bundle = 0;
2891 /* Check if current entry in directory is part of a multi-cert bundle */
2892
2893 if (end) {
2894 for (j = 0; j < SSL_SOCK_NUM_KEYTYPES; j++) {
2895 if (!strcmp(end + 1, SSL_SOCK_KEYTYPE_NAMES[j])) {
2896 is_bundle = 1;
2897 break;
2898 }
2899 }
2900
2901 if (is_bundle) {
2902 char dp[MAXPATHLEN+1] = {0}; /* this will be the filename w/o the keytype */
2903 int dp_len;
2904
2905 dp_len = end - de->d_name;
2906 snprintf(dp, dp_len + 1, "%s", de->d_name);
2907
2908 /* increment i and free de until we get to a non-bundle cert
2909 * Note here that we look at de_list[i + 1] before freeing de
2910 * this is important since ignore_entry will free de
2911 */
2912 while (i + 1 < n && !strncmp(de_list[i + 1]->d_name, dp, dp_len)) {
2913 free(de);
2914 i++;
2915 de = de_list[i];
2916 }
2917
2918 snprintf(fp, sizeof(fp), "%s/%s", path, dp);
Emmanuel Hocdet98263292016-12-29 18:26:15 +01002919 ssl_sock_load_multi_cert(fp, bind_conf, NULL, NULL, 0, err);
yanbzhu63ea8462015-12-09 13:35:14 -05002920
2921 /* Successfully processed the bundle */
2922 goto ignore_entry;
2923 }
2924 }
2925
2926#endif
Emmanuel Hocdet98263292016-12-29 18:26:15 +01002927 cfgerr += ssl_sock_load_cert_file(fp, bind_conf, NULL, NULL, 0, err);
yanbzhu08ce6ab2015-12-02 13:01:29 -05002928ignore_entry:
2929 free(de);
Cyril Bonté3180f7b2015-01-25 00:16:08 +01002930 }
yanbzhu08ce6ab2015-12-02 13:01:29 -05002931 free(de_list);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002932 }
yanbzhu08ce6ab2015-12-02 13:01:29 -05002933 closedir(dir);
2934 return cfgerr;
Emeric Brunfc0421f2012-09-07 17:30:07 +02002935 }
yanbzhu08ce6ab2015-12-02 13:01:29 -05002936
Emmanuel Hocdet98263292016-12-29 18:26:15 +01002937 cfgerr = ssl_sock_load_multi_cert(path, bind_conf, NULL, NULL, 0, err);
yanbzhu08ce6ab2015-12-02 13:01:29 -05002938
Emeric Brunfc0421f2012-09-07 17:30:07 +02002939 return cfgerr;
2940}
2941
Thierry Fournier383085f2013-01-24 14:15:43 +01002942/* Make sure openssl opens /dev/urandom before the chroot. The work is only
2943 * done once. Zero is returned if the operation fails. No error is returned
2944 * if the random is said as not implemented, because we expect that openssl
2945 * will use another method once needed.
2946 */
2947static int ssl_initialize_random()
2948{
2949 unsigned char random;
2950 static int random_initialized = 0;
2951
2952 if (!random_initialized && RAND_bytes(&random, 1) != 0)
2953 random_initialized = 1;
2954
2955 return random_initialized;
2956}
2957
Emmanuel Hocdet98263292016-12-29 18:26:15 +01002958/* release ssl bind conf */
2959void ssl_sock_free_ssl_conf(struct ssl_bind_conf *conf)
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002960{
Emmanuel Hocdet98263292016-12-29 18:26:15 +01002961 if (conf) {
2962#ifdef OPENSSL_NPN_NEGOTIATED
2963 free(conf->npn_str);
2964 conf->npn_str = NULL;
2965#endif
2966#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
2967 free(conf->alpn_str);
2968 conf->alpn_str = NULL;
2969#endif
2970 free(conf->ca_file);
2971 conf->ca_file = NULL;
2972 free(conf->crl_file);
2973 conf->crl_file = NULL;
2974 free(conf->ciphers);
2975 conf->ciphers = NULL;
Emmanuel Hocdete7f2b732017-01-09 16:15:54 +01002976 free(conf->curves);
2977 conf->curves = NULL;
Emmanuel Hocdet98263292016-12-29 18:26:15 +01002978 free(conf->ecdhe);
2979 conf->ecdhe = NULL;
2980 }
2981}
2982
2983int ssl_sock_load_cert_list_file(char *file, struct bind_conf *bind_conf, struct proxy *curproxy, char **err)
2984{
2985 char thisline[CRT_LINESIZE];
2986 char path[MAXPATHLEN+1];
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002987 FILE *f;
yanbzhu1b04e5b2015-12-02 13:54:14 -05002988 struct stat buf;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002989 int linenum = 0;
2990 int cfgerr = 0;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002991
Willy Tarreauad1731d2013-04-02 17:35:58 +02002992 if ((f = fopen(file, "r")) == NULL) {
2993 memprintf(err, "cannot open file '%s' : %s", file, strerror(errno));
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002994 return 1;
Willy Tarreauad1731d2013-04-02 17:35:58 +02002995 }
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002996
2997 while (fgets(thisline, sizeof(thisline), f) != NULL) {
Emmanuel Hocdet98263292016-12-29 18:26:15 +01002998 int arg, newarg, cur_arg, i, ssl_b = 0, ssl_e = 0;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002999 char *end;
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003000 char *args[MAX_CRT_ARGS + 1];
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01003001 char *line = thisline;
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003002 char *crt_path;
3003 struct ssl_bind_conf *ssl_conf = NULL;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01003004
3005 linenum++;
3006 end = line + strlen(line);
3007 if (end-line == sizeof(thisline)-1 && *(end-1) != '\n') {
3008 /* Check if we reached the limit and the last char is not \n.
3009 * Watch out for the last line without the terminating '\n'!
3010 */
Willy Tarreauad1731d2013-04-02 17:35:58 +02003011 memprintf(err, "line %d too long in file '%s', limit is %d characters",
3012 linenum, file, (int)sizeof(thisline)-1);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01003013 cfgerr = 1;
Willy Tarreauad1731d2013-04-02 17:35:58 +02003014 break;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01003015 }
3016
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01003017 arg = 0;
Emeric Brun50bcecc2013-04-22 13:05:23 +02003018 newarg = 1;
3019 while (*line) {
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01003020 if (*line == '#' || *line == '\n' || *line == '\r') {
3021 /* end of string, end of loop */
3022 *line = 0;
3023 break;
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003024 } else if (isspace(*line)) {
Emeric Brun50bcecc2013-04-22 13:05:23 +02003025 newarg = 1;
3026 *line = 0;
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003027 } else if (*line == '[') {
3028 if (ssl_b) {
3029 memprintf(err, "too many '[' on line %d in file '%s'.", linenum, file);
3030 cfgerr = 1;
3031 break;
3032 }
3033 if (!arg) {
3034 memprintf(err, "file must start with a cert on line %d in file '%s'", linenum, file);
3035 cfgerr = 1;
3036 break;
3037 }
3038 ssl_b = arg;
3039 newarg = 1;
3040 *line = 0;
3041 } else if (*line == ']') {
3042 if (ssl_e) {
3043 memprintf(err, "too many ']' on line %d in file '%s'.", linenum, file);
Emeric Brun50bcecc2013-04-22 13:05:23 +02003044 cfgerr = 1;
3045 break;
3046 }
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003047 if (!ssl_b) {
3048 memprintf(err, "missing '[' in line %d in file '%s'.", linenum, file);
3049 cfgerr = 1;
3050 break;
3051 }
3052 ssl_e = arg;
3053 newarg = 1;
3054 *line = 0;
3055 } else if (newarg) {
3056 if (arg == MAX_CRT_ARGS) {
3057 memprintf(err, "too many args on line %d in file '%s'.", linenum, file);
3058 cfgerr = 1;
3059 break;
3060 }
Emeric Brun50bcecc2013-04-22 13:05:23 +02003061 newarg = 0;
3062 args[arg++] = line;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01003063 }
Emeric Brun50bcecc2013-04-22 13:05:23 +02003064 line++;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01003065 }
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02003066 if (cfgerr)
3067 break;
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003068 args[arg++] = line;
Willy Tarreauad1731d2013-04-02 17:35:58 +02003069
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01003070 /* empty line */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003071 if (!*args[0])
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01003072 continue;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01003073
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003074 crt_path = args[0];
3075 if (*crt_path != '/' && global_ssl.crt_base) {
3076 if ((strlen(global_ssl.crt_base) + 1 + strlen(crt_path)) > MAXPATHLEN) {
3077 memprintf(err, "'%s' : path too long on line %d in file '%s'",
3078 crt_path, linenum, file);
3079 cfgerr = 1;
3080 break;
3081 }
3082 snprintf(path, sizeof(path), "%s/%s", global_ssl.crt_base, crt_path);
3083 crt_path = path;
3084 }
3085
3086 ssl_conf = calloc(1, sizeof *ssl_conf);
3087 cur_arg = ssl_b ? ssl_b : 1;
3088 while (cur_arg < ssl_e) {
3089 newarg = 0;
3090 for (i = 0; ssl_bind_kws[i].kw != NULL; i++) {
3091 if (strcmp(ssl_bind_kws[i].kw, args[cur_arg]) == 0) {
3092 newarg = 1;
3093 cfgerr = ssl_bind_kws[i].parse(args, cur_arg, curproxy, ssl_conf, err);
3094 if (cur_arg + 1 + ssl_bind_kws[i].skip > ssl_e) {
3095 memprintf(err, "ssl args out of '[]' for %s on line %d in file '%s'",
3096 args[cur_arg], linenum, file);
3097 cfgerr = 1;
3098 }
3099 cur_arg += 1 + ssl_bind_kws[i].skip;
3100 break;
3101 }
3102 }
3103 if (!cfgerr && !newarg) {
3104 memprintf(err, "unknown ssl keyword %s on line %d in file '%s'.",
3105 args[cur_arg], linenum, file);
3106 cfgerr = 1;
3107 break;
3108 }
3109 }
3110 if (cfgerr) {
3111 ssl_sock_free_ssl_conf(ssl_conf);
3112 free(ssl_conf);
3113 ssl_conf = NULL;
3114 break;
3115 }
3116
3117 if (stat(crt_path, &buf) == 0) {
3118 cfgerr = ssl_sock_load_cert_file(crt_path, bind_conf, ssl_conf,
3119 &args[cur_arg], arg - cur_arg - 1, err);
yanbzhu1b04e5b2015-12-02 13:54:14 -05003120 } else {
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003121 cfgerr = ssl_sock_load_multi_cert(crt_path, bind_conf, ssl_conf,
3122 &args[cur_arg], arg - cur_arg - 1, err);
yanbzhu1b04e5b2015-12-02 13:54:14 -05003123 }
3124
Willy Tarreauad1731d2013-04-02 17:35:58 +02003125 if (cfgerr) {
3126 memprintf(err, "error processing line %d in file '%s' : %s", linenum, file, *err);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01003127 break;
Willy Tarreauad1731d2013-04-02 17:35:58 +02003128 }
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01003129 }
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01003130 fclose(f);
3131 return cfgerr;
3132}
3133
Emeric Brunfc0421f2012-09-07 17:30:07 +02003134#ifndef SSL_OP_CIPHER_SERVER_PREFERENCE /* needs OpenSSL >= 0.9.7 */
3135#define SSL_OP_CIPHER_SERVER_PREFERENCE 0
3136#endif
3137
3138#ifndef SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION /* needs OpenSSL >= 0.9.7 */
3139#define SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION 0
Willy Tarreau7d588ee2012-11-26 18:47:31 +01003140#define SSL_renegotiate_pending(arg) 0
Emeric Brunfc0421f2012-09-07 17:30:07 +02003141#endif
Emeric Brun2b58d042012-09-20 17:10:03 +02003142#ifndef SSL_OP_SINGLE_ECDH_USE /* needs OpenSSL >= 0.9.8 */
3143#define SSL_OP_SINGLE_ECDH_USE 0
3144#endif
Emeric Brun2d0c4822012-10-02 13:45:20 +02003145#ifndef SSL_OP_NO_TICKET /* needs OpenSSL >= 0.9.8 */
3146#define SSL_OP_NO_TICKET 0
3147#endif
Emeric Brunfc0421f2012-09-07 17:30:07 +02003148#ifndef SSL_OP_NO_COMPRESSION /* needs OpenSSL >= 0.9.9 */
3149#define SSL_OP_NO_COMPRESSION 0
3150#endif
Emeric Brunc0ff4922012-09-28 19:37:02 +02003151#ifndef SSL_OP_NO_TLSv1_1 /* needs OpenSSL >= 1.0.1 */
3152#define SSL_OP_NO_TLSv1_1 0
3153#endif
3154#ifndef SSL_OP_NO_TLSv1_2 /* needs OpenSSL >= 1.0.1 */
3155#define SSL_OP_NO_TLSv1_2 0
3156#endif
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02003157#ifndef SSL_OP_SINGLE_DH_USE /* needs OpenSSL >= 0.9.6 */
3158#define SSL_OP_SINGLE_DH_USE 0
3159#endif
Emeric Brun2b58d042012-09-20 17:10:03 +02003160#ifndef SSL_OP_SINGLE_ECDH_USE /* needs OpenSSL >= 1.0.0 */
3161#define SSL_OP_SINGLE_ECDH_USE 0
3162#endif
Emeric Brunfc0421f2012-09-07 17:30:07 +02003163#ifndef SSL_MODE_RELEASE_BUFFERS /* needs OpenSSL >= 1.0.0 */
3164#define SSL_MODE_RELEASE_BUFFERS 0
3165#endif
Willy Tarreau396a1862014-11-13 14:06:52 +01003166#ifndef SSL_MODE_SMALL_BUFFERS /* needs small_records.patch */
3167#define SSL_MODE_SMALL_BUFFERS 0
3168#endif
Remi Gacognef46cd6e2014-06-12 14:58:40 +02003169
Emmanuel Hocdet4de1ff12017-03-03 12:21:32 +01003170
Emmanuel Hocdetf6b37c62017-03-06 15:34:44 +01003171/* Create an initial CTX used to start the SSL connection before switchctx */
Emmanuel Hocdet4de1ff12017-03-03 12:21:32 +01003172static SSL_CTX *
Emmanuel Hocdetf6b37c62017-03-06 15:34:44 +01003173ssl_sock_initial_ctx(struct bind_conf *bind_conf)
Emeric Brunfc0421f2012-09-07 17:30:07 +02003174{
Emmanuel Hocdet4de1ff12017-03-03 12:21:32 +01003175 SSL_CTX *ctx = NULL;
Remi Gacogneaf5c3da2014-05-19 10:29:58 +02003176 long ssloptions =
Emeric Brunfc0421f2012-09-07 17:30:07 +02003177 SSL_OP_ALL | /* all known workarounds for bugs */
3178 SSL_OP_NO_SSLv2 |
3179 SSL_OP_NO_COMPRESSION |
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02003180 SSL_OP_SINGLE_DH_USE |
Emeric Brun2b58d042012-09-20 17:10:03 +02003181 SSL_OP_SINGLE_ECDH_USE |
Emeric Brun3c4bc6e2012-10-04 18:44:19 +02003182 SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION |
3183 SSL_OP_CIPHER_SERVER_PREFERENCE;
Remi Gacogneaf5c3da2014-05-19 10:29:58 +02003184 long sslmode =
Emeric Brunfc0421f2012-09-07 17:30:07 +02003185 SSL_MODE_ENABLE_PARTIAL_WRITE |
3186 SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER |
Willy Tarreau396a1862014-11-13 14:06:52 +01003187 SSL_MODE_RELEASE_BUFFERS |
3188 SSL_MODE_SMALL_BUFFERS;
Emmanuel Hocdet4608ed92017-01-20 13:06:27 +01003189 int conf_ssl_options = bind_conf->ssl_options;
Emmanuel Hocdet4de1ff12017-03-03 12:21:32 +01003190
3191#if SSL_OP_NO_TLSv1_2
3192 if (!ctx && conf_ssl_options & BC_SSL_O_USE_TLSV12)
3193 ctx = SSL_CTX_new(TLSv1_2_server_method());
3194#endif
3195#if SSL_OP_NO_TLSv1_1
3196 if (!ctx && conf_ssl_options & BC_SSL_O_USE_TLSV11)
3197 ctx = SSL_CTX_new(TLSv1_1_server_method());
3198#endif
3199 if (!ctx && conf_ssl_options & BC_SSL_O_USE_TLSV10)
3200 ctx = SSL_CTX_new(TLSv1_server_method());
3201#ifndef OPENSSL_NO_SSL3
3202 if (!ctx && conf_ssl_options & BC_SSL_O_USE_SSLV3)
3203 ctx = SSL_CTX_new(SSLv3_server_method());
3204#endif
3205 if (!ctx) {
3206 ctx = SSL_CTX_new(SSLv23_server_method());
3207 if (conf_ssl_options & BC_SSL_O_NO_SSLV3)
3208 ssloptions |= SSL_OP_NO_SSLv3;
3209 if (conf_ssl_options & BC_SSL_O_NO_TLSV10)
3210 ssloptions |= SSL_OP_NO_TLSv1;
3211 if (conf_ssl_options & BC_SSL_O_NO_TLSV11)
3212 ssloptions |= SSL_OP_NO_TLSv1_1;
3213 if (conf_ssl_options & BC_SSL_O_NO_TLSV12)
3214 ssloptions |= SSL_OP_NO_TLSv1_2;
3215 }
3216 if (conf_ssl_options & BC_SSL_O_NO_TLS_TICKETS)
3217 ssloptions |= SSL_OP_NO_TICKET;
3218 SSL_CTX_set_options(ctx, ssloptions);
3219 SSL_CTX_set_mode(ctx, sslmode);
3220 if (global_ssl.life_time)
3221 SSL_CTX_set_timeout(ctx, global_ssl.life_time);
Emmanuel Hocdetf6b37c62017-03-06 15:34:44 +01003222
3223#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
3224#ifdef OPENSSL_IS_BORINGSSL
3225 SSL_CTX_set_select_certificate_cb(ctx, ssl_sock_switchctx_cbk);
3226 SSL_CTX_set_tlsext_servername_callback(ctx, ssl_sock_switchctx_err_cbk);
3227#else
3228 SSL_CTX_set_tlsext_servername_callback(ctx, ssl_sock_switchctx_cbk);
3229 SSL_CTX_set_tlsext_servername_arg(ctx, bind_conf);
3230#endif
3231#endif
Emmanuel Hocdet4de1ff12017-03-03 12:21:32 +01003232 return ctx;
3233}
3234
3235int ssl_sock_prepare_ctx(struct bind_conf *bind_conf, struct ssl_bind_conf *ssl_conf, SSL_CTX *ctx)
3236{
3237 struct proxy *curproxy = bind_conf->frontend;
3238 int cfgerr = 0;
3239 int verify = SSL_VERIFY_NONE;
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003240 struct ssl_bind_conf *ssl_conf_cur;
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003241 const char *conf_ciphers;
Emmanuel Hocdete7f2b732017-01-09 16:15:54 +01003242 const char *conf_curves = NULL;
Emeric Brunfc0421f2012-09-07 17:30:07 +02003243
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003244 switch ((ssl_conf && ssl_conf->verify) ? ssl_conf->verify : bind_conf->ssl_conf.verify) {
Emeric Brun850efd52014-01-29 12:24:34 +01003245 case SSL_SOCK_VERIFY_NONE:
3246 verify = SSL_VERIFY_NONE;
3247 break;
3248 case SSL_SOCK_VERIFY_OPTIONAL:
3249 verify = SSL_VERIFY_PEER;
3250 break;
3251 case SSL_SOCK_VERIFY_REQUIRED:
3252 verify = SSL_VERIFY_PEER|SSL_VERIFY_FAIL_IF_NO_PEER_CERT;
3253 break;
3254 }
3255 SSL_CTX_set_verify(ctx, verify, ssl_sock_bind_verifycbk);
3256 if (verify & SSL_VERIFY_PEER) {
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003257 char *ca_file = (ssl_conf && ssl_conf->ca_file) ? ssl_conf->ca_file : bind_conf->ssl_conf.ca_file;
3258 char *crl_file = (ssl_conf && ssl_conf->crl_file) ? ssl_conf->crl_file : bind_conf->ssl_conf.crl_file;
3259 if (ca_file) {
Emeric Brund94b3fe2012-09-20 18:23:56 +02003260 /* load CAfile to verify */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003261 if (!SSL_CTX_load_verify_locations(ctx, ca_file, NULL)) {
Emeric Brund94b3fe2012-09-20 18:23:56 +02003262 Alert("Proxy '%s': unable to load CA file '%s' for bind '%s' at [%s:%d].\n",
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003263 curproxy->id, ca_file, bind_conf->arg, bind_conf->file, bind_conf->line);
Emeric Brund94b3fe2012-09-20 18:23:56 +02003264 cfgerr++;
3265 }
3266 /* set CA names fo client cert request, function returns void */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003267 SSL_CTX_set_client_CA_list(ctx, SSL_load_client_CA_file(ca_file));
Emeric Brund94b3fe2012-09-20 18:23:56 +02003268 }
Emeric Brun850efd52014-01-29 12:24:34 +01003269 else {
3270 Alert("Proxy '%s': verify is enabled but no CA file specified for bind '%s' at [%s:%d].\n",
3271 curproxy->id, bind_conf->arg, bind_conf->file, bind_conf->line);
3272 cfgerr++;
3273 }
Emeric Brun051cdab2012-10-02 19:25:50 +02003274#ifdef X509_V_FLAG_CRL_CHECK
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003275 if (crl_file) {
Emeric Brund94b3fe2012-09-20 18:23:56 +02003276 X509_STORE *store = SSL_CTX_get_cert_store(ctx);
3277
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003278 if (!store || !X509_STORE_load_locations(store, crl_file, NULL)) {
Emeric Brund94b3fe2012-09-20 18:23:56 +02003279 Alert("Proxy '%s': unable to configure CRL file '%s' for bind '%s' at [%s:%d].\n",
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003280 curproxy->id, crl_file, bind_conf->arg, bind_conf->file, bind_conf->line);
Emeric Brund94b3fe2012-09-20 18:23:56 +02003281 cfgerr++;
3282 }
Emeric Brun561e5742012-10-02 15:20:55 +02003283 else {
3284 X509_STORE_set_flags(store, X509_V_FLAG_CRL_CHECK|X509_V_FLAG_CRL_CHECK_ALL);
3285 }
Emeric Brund94b3fe2012-09-20 18:23:56 +02003286 }
Emeric Brun051cdab2012-10-02 19:25:50 +02003287#endif
Emeric Brun644cde02012-12-14 11:21:13 +01003288 ERR_clear_error();
Emeric Brund94b3fe2012-09-20 18:23:56 +02003289 }
Nenad Merdanovic05552d42015-02-27 19:56:49 +01003290#if (defined SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB && TLS_TICKETS_NO > 0)
Nenad Merdanovic146defa2015-05-09 08:46:00 +02003291 if(bind_conf->keys_ref) {
Nenad Merdanovic05552d42015-02-27 19:56:49 +01003292 if (!SSL_CTX_set_tlsext_ticket_key_cb(ctx, ssl_tlsext_ticket_key_cb)) {
3293 Alert("Proxy '%s': unable to set callback for TLS ticket validation for bind '%s' at [%s:%d].\n",
3294 curproxy->id, bind_conf->arg, bind_conf->file, bind_conf->line);
3295 cfgerr++;
3296 }
3297 }
3298#endif
3299
Emeric Brunfc0421f2012-09-07 17:30:07 +02003300 shared_context_set_cache(ctx);
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003301 conf_ciphers = (ssl_conf && ssl_conf->ciphers) ? ssl_conf->ciphers : bind_conf->ssl_conf.ciphers;
3302 if (conf_ciphers &&
3303 !SSL_CTX_set_cipher_list(ctx, conf_ciphers)) {
Emeric Brunfc0421f2012-09-07 17:30:07 +02003304 Alert("Proxy '%s': unable to set SSL cipher list to '%s' for bind '%s' at [%s:%d].\n",
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003305 curproxy->id, conf_ciphers, bind_conf->arg, bind_conf->file, bind_conf->line);
Emeric Brunfc0421f2012-09-07 17:30:07 +02003306 cfgerr++;
3307 }
3308
Emmanuel Hocdetcc6c2a22017-03-03 17:04:14 +01003309#ifndef OPENSSL_NO_DH
Remi Gacogne47783ef2015-05-29 15:53:22 +02003310 /* If tune.ssl.default-dh-param has not been set,
3311 neither has ssl-default-dh-file and no static DH
3312 params were in the certificate file. */
Willy Tarreauef934602016-12-22 23:12:01 +01003313 if (global_ssl.default_dh_param == 0 &&
Remi Gacogne47783ef2015-05-29 15:53:22 +02003314 global_dh == NULL &&
Remi Gacogne4f902b82015-05-28 16:23:00 +02003315 (ssl_dh_ptr_index == -1 ||
3316 SSL_CTX_get_ex_data(ctx, ssl_dh_ptr_index) == NULL)) {
Emmanuel Hocdetcc6c2a22017-03-03 17:04:14 +01003317 STACK_OF(SSL_CIPHER) * ciphers = NULL;
3318 const SSL_CIPHER * cipher = NULL;
3319 char cipher_description[128];
3320 /* The description of ciphers using an Ephemeral Diffie Hellman key exchange
3321 contains " Kx=DH " or " Kx=DH(". Beware of " Kx=DH/",
3322 which is not ephemeral DH. */
3323 const char dhe_description[] = " Kx=DH ";
3324 const char dhe_export_description[] = " Kx=DH(";
3325 int idx = 0;
3326 int dhe_found = 0;
3327 SSL *ssl = NULL;
Lukas Tribus90132722014-08-18 00:56:33 +02003328
Remi Gacogne23d5d372014-10-10 17:04:26 +02003329 ssl = SSL_new(ctx);
Remi Gacognef46cd6e2014-06-12 14:58:40 +02003330
Remi Gacogne23d5d372014-10-10 17:04:26 +02003331 if (ssl) {
3332 ciphers = SSL_get_ciphers(ssl);
3333
3334 if (ciphers) {
3335 for (idx = 0; idx < sk_SSL_CIPHER_num(ciphers); idx++) {
3336 cipher = sk_SSL_CIPHER_value(ciphers, idx);
3337 if (SSL_CIPHER_description(cipher, cipher_description, sizeof (cipher_description)) == cipher_description) {
3338 if (strstr(cipher_description, dhe_description) != NULL ||
3339 strstr(cipher_description, dhe_export_description) != NULL) {
3340 dhe_found = 1;
3341 break;
3342 }
Remi Gacognec1eab8c2014-06-12 18:20:11 +02003343 }
Remi Gacognef46cd6e2014-06-12 14:58:40 +02003344 }
3345 }
Remi Gacogne23d5d372014-10-10 17:04:26 +02003346 SSL_free(ssl);
3347 ssl = NULL;
Lukas Tribus90132722014-08-18 00:56:33 +02003348 }
Remi Gacognef46cd6e2014-06-12 14:58:40 +02003349
Lukas Tribus90132722014-08-18 00:56:33 +02003350 if (dhe_found) {
3351 Warning("Setting tune.ssl.default-dh-param to 1024 by default, if your workload permits it you should set it to at least 2048. Please set a value >= 1024 to make this warning disappear.\n");
Remi Gacognef46cd6e2014-06-12 14:58:40 +02003352 }
3353
Willy Tarreauef934602016-12-22 23:12:01 +01003354 global_ssl.default_dh_param = 1024;
Remi Gacognef46cd6e2014-06-12 14:58:40 +02003355 }
Remi Gacogne8de54152014-07-15 11:36:40 +02003356
Willy Tarreauef934602016-12-22 23:12:01 +01003357 if (global_ssl.default_dh_param >= 1024) {
Remi Gacogne8de54152014-07-15 11:36:40 +02003358 if (local_dh_1024 == NULL) {
3359 local_dh_1024 = ssl_get_dh_1024();
3360 }
Willy Tarreauef934602016-12-22 23:12:01 +01003361 if (global_ssl.default_dh_param >= 2048) {
Remi Gacogne8de54152014-07-15 11:36:40 +02003362 if (local_dh_2048 == NULL) {
3363 local_dh_2048 = ssl_get_dh_2048();
3364 }
Willy Tarreauef934602016-12-22 23:12:01 +01003365 if (global_ssl.default_dh_param >= 4096) {
Remi Gacogne8de54152014-07-15 11:36:40 +02003366 if (local_dh_4096 == NULL) {
3367 local_dh_4096 = ssl_get_dh_4096();
3368 }
Remi Gacogne8de54152014-07-15 11:36:40 +02003369 }
3370 }
3371 }
3372#endif /* OPENSSL_NO_DH */
Remi Gacognef46cd6e2014-06-12 14:58:40 +02003373
Emeric Brunfc0421f2012-09-07 17:30:07 +02003374 SSL_CTX_set_info_callback(ctx, ssl_sock_infocbk);
Willy Tarreau5cbe4ef2014-05-08 22:45:11 +02003375#if OPENSSL_VERSION_NUMBER >= 0x00907000L
Emeric Brun29f037d2014-04-25 19:05:36 +02003376 SSL_CTX_set_msg_callback(ctx, ssl_sock_msgcbk);
Willy Tarreau5cbe4ef2014-05-08 22:45:11 +02003377#endif
Emeric Brun29f037d2014-04-25 19:05:36 +02003378
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02003379#ifdef OPENSSL_NPN_NEGOTIATED
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003380 ssl_conf_cur = NULL;
3381 if (ssl_conf && ssl_conf->npn_str)
3382 ssl_conf_cur = ssl_conf;
3383 else if (bind_conf->ssl_conf.npn_str)
3384 ssl_conf_cur = &bind_conf->ssl_conf;
3385 if (ssl_conf_cur)
3386 SSL_CTX_set_next_protos_advertised_cb(ctx, ssl_sock_advertise_npn_protos, ssl_conf_cur);
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02003387#endif
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01003388#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003389 ssl_conf_cur = NULL;
3390 if (ssl_conf && ssl_conf->alpn_str)
3391 ssl_conf_cur = ssl_conf;
3392 else if (bind_conf->ssl_conf.alpn_str)
3393 ssl_conf_cur = &bind_conf->ssl_conf;
3394 if (ssl_conf_cur)
3395 SSL_CTX_set_alpn_select_cb(ctx, ssl_sock_advertise_alpn_protos, ssl_conf_cur);
Willy Tarreauab861d32013-04-02 02:30:41 +02003396#endif
Emmanuel Hocdete7f2b732017-01-09 16:15:54 +01003397#if OPENSSL_VERSION_NUMBER >= 0x1000200fL
3398 conf_curves = (ssl_conf && ssl_conf->curves) ? ssl_conf->curves : bind_conf->ssl_conf.curves;
3399 if (conf_curves) {
3400 if (!SSL_CTX_set1_curves_list(ctx, conf_curves)) {
3401 Alert("Proxy '%s': unable to set SSL curves list to '%s' for bind '%s' at [%s:%d].\n",
3402 curproxy->id, conf_curves, bind_conf->arg, bind_conf->file, bind_conf->line);
3403 cfgerr++;
3404 }
Emmanuel Hocdeta52bb152017-03-20 11:11:49 +01003405#if defined(SSL_CTX_set_ecdh_auto)
3406 (void)SSL_CTX_set_ecdh_auto(ctx, 1);
3407#endif
Emmanuel Hocdete7f2b732017-01-09 16:15:54 +01003408 }
3409#endif
Emeric Brun2b58d042012-09-20 17:10:03 +02003410#if defined(SSL_CTX_set_tmp_ecdh) && !defined(OPENSSL_NO_ECDH)
Emmanuel Hocdete7f2b732017-01-09 16:15:54 +01003411 if (!conf_curves) {
Emeric Brun2b58d042012-09-20 17:10:03 +02003412 int i;
3413 EC_KEY *ecdh;
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003414 const char *ecdhe = (ssl_conf && ssl_conf->ecdhe) ? ssl_conf->ecdhe :
3415 (bind_conf->ssl_conf.ecdhe ? bind_conf->ssl_conf.ecdhe : ECDHE_DEFAULT_CURVE);
Emeric Brun2b58d042012-09-20 17:10:03 +02003416
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003417 i = OBJ_sn2nid(ecdhe);
Emeric Brun2b58d042012-09-20 17:10:03 +02003418 if (!i || ((ecdh = EC_KEY_new_by_curve_name(i)) == NULL)) {
3419 Alert("Proxy '%s': unable to set elliptic named curve to '%s' for bind '%s' at [%s:%d].\n",
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003420 curproxy->id, ecdhe, bind_conf->arg, bind_conf->file, bind_conf->line);
Emeric Brun2b58d042012-09-20 17:10:03 +02003421 cfgerr++;
3422 }
3423 else {
3424 SSL_CTX_set_tmp_ecdh(ctx, ecdh);
3425 EC_KEY_free(ecdh);
3426 }
3427 }
3428#endif
3429
Emeric Brunfc0421f2012-09-07 17:30:07 +02003430 return cfgerr;
3431}
3432
Evan Broderbe554312013-06-27 00:05:25 -07003433static int ssl_sock_srv_hostcheck(const char *pattern, const char *hostname)
3434{
3435 const char *pattern_wildcard, *pattern_left_label_end, *hostname_left_label_end;
3436 size_t prefixlen, suffixlen;
3437
3438 /* Trivial case */
3439 if (strcmp(pattern, hostname) == 0)
3440 return 1;
3441
Evan Broderbe554312013-06-27 00:05:25 -07003442 /* The rest of this logic is based on RFC 6125, section 6.4.3
3443 * (http://tools.ietf.org/html/rfc6125#section-6.4.3) */
3444
Emeric Bruna848dae2013-10-08 11:27:28 +02003445 pattern_wildcard = NULL;
3446 pattern_left_label_end = pattern;
3447 while (*pattern_left_label_end != '.') {
3448 switch (*pattern_left_label_end) {
3449 case 0:
3450 /* End of label not found */
3451 return 0;
3452 case '*':
3453 /* If there is more than one wildcards */
3454 if (pattern_wildcard)
3455 return 0;
3456 pattern_wildcard = pattern_left_label_end;
3457 break;
3458 }
3459 pattern_left_label_end++;
3460 }
3461
3462 /* If it's not trivial and there is no wildcard, it can't
3463 * match */
3464 if (!pattern_wildcard)
Evan Broderbe554312013-06-27 00:05:25 -07003465 return 0;
3466
3467 /* Make sure all labels match except the leftmost */
3468 hostname_left_label_end = strchr(hostname, '.');
3469 if (!hostname_left_label_end
3470 || strcmp(pattern_left_label_end, hostname_left_label_end) != 0)
3471 return 0;
3472
3473 /* Make sure the leftmost label of the hostname is long enough
3474 * that the wildcard can match */
Emeric Brun369da852013-10-08 11:39:35 +02003475 if (hostname_left_label_end - hostname < (pattern_left_label_end - pattern) - 1)
Evan Broderbe554312013-06-27 00:05:25 -07003476 return 0;
3477
3478 /* Finally compare the string on either side of the
3479 * wildcard */
3480 prefixlen = pattern_wildcard - pattern;
3481 suffixlen = pattern_left_label_end - (pattern_wildcard + 1);
Emeric Bruna848dae2013-10-08 11:27:28 +02003482 if ((prefixlen && (memcmp(pattern, hostname, prefixlen) != 0))
3483 || (suffixlen && (memcmp(pattern_wildcard + 1, hostname_left_label_end - suffixlen, suffixlen) != 0)))
Evan Broderbe554312013-06-27 00:05:25 -07003484 return 0;
3485
3486 return 1;
3487}
3488
3489static int ssl_sock_srv_verifycbk(int ok, X509_STORE_CTX *ctx)
3490{
3491 SSL *ssl;
3492 struct connection *conn;
3493 char *servername;
3494
3495 int depth;
3496 X509 *cert;
3497 STACK_OF(GENERAL_NAME) *alt_names;
3498 int i;
3499 X509_NAME *cert_subject;
3500 char *str;
3501
3502 if (ok == 0)
3503 return ok;
3504
3505 ssl = X509_STORE_CTX_get_ex_data(ctx, SSL_get_ex_data_X509_STORE_CTX_idx());
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02003506 conn = SSL_get_app_data(ssl);
Evan Broderbe554312013-06-27 00:05:25 -07003507
3508 servername = objt_server(conn->target)->ssl_ctx.verify_host;
3509
3510 /* We only need to verify the CN on the actual server cert,
3511 * not the indirect CAs */
3512 depth = X509_STORE_CTX_get_error_depth(ctx);
3513 if (depth != 0)
3514 return ok;
3515
3516 /* At this point, the cert is *not* OK unless we can find a
3517 * hostname match */
3518 ok = 0;
3519
3520 cert = X509_STORE_CTX_get_current_cert(ctx);
3521 /* It seems like this might happen if verify peer isn't set */
3522 if (!cert)
3523 return ok;
3524
3525 alt_names = X509_get_ext_d2i(cert, NID_subject_alt_name, NULL, NULL);
3526 if (alt_names) {
3527 for (i = 0; !ok && i < sk_GENERAL_NAME_num(alt_names); i++) {
3528 GENERAL_NAME *name = sk_GENERAL_NAME_value(alt_names, i);
3529 if (name->type == GEN_DNS) {
Emeric Bruna33410c2013-09-17 15:47:48 +02003530#if OPENSSL_VERSION_NUMBER < 0x00907000L
3531 if (ASN1_STRING_to_UTF8((unsigned char **)&str, name->d.ia5) >= 0) {
3532#else
Evan Broderbe554312013-06-27 00:05:25 -07003533 if (ASN1_STRING_to_UTF8((unsigned char **)&str, name->d.dNSName) >= 0) {
Emeric Bruna33410c2013-09-17 15:47:48 +02003534#endif
Evan Broderbe554312013-06-27 00:05:25 -07003535 ok = ssl_sock_srv_hostcheck(str, servername);
3536 OPENSSL_free(str);
3537 }
3538 }
3539 }
Emeric Brun4ad50a42013-09-17 15:19:54 +02003540 sk_GENERAL_NAME_pop_free(alt_names, GENERAL_NAME_free);
Evan Broderbe554312013-06-27 00:05:25 -07003541 }
3542
3543 cert_subject = X509_get_subject_name(cert);
3544 i = -1;
3545 while (!ok && (i = X509_NAME_get_index_by_NID(cert_subject, NID_commonName, i)) != -1) {
3546 X509_NAME_ENTRY *entry = X509_NAME_get_entry(cert_subject, i);
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02003547 ASN1_STRING *value;
3548 value = X509_NAME_ENTRY_get_data(entry);
3549 if (ASN1_STRING_to_UTF8((unsigned char **)&str, value) >= 0) {
Evan Broderbe554312013-06-27 00:05:25 -07003550 ok = ssl_sock_srv_hostcheck(str, servername);
3551 OPENSSL_free(str);
3552 }
3553 }
3554
3555 return ok;
3556}
3557
Emeric Brun94324a42012-10-11 14:00:19 +02003558/* prepare ssl context from servers options. Returns an error count */
Willy Tarreau03209342016-12-22 17:08:28 +01003559int ssl_sock_prepare_srv_ctx(struct server *srv)
Emeric Brun94324a42012-10-11 14:00:19 +02003560{
Willy Tarreau03209342016-12-22 17:08:28 +01003561 struct proxy *curproxy = srv->proxy;
Emeric Brun94324a42012-10-11 14:00:19 +02003562 int cfgerr = 0;
Remi Gacogneaf5c3da2014-05-19 10:29:58 +02003563 long options =
Emeric Brun94324a42012-10-11 14:00:19 +02003564 SSL_OP_ALL | /* all known workarounds for bugs */
3565 SSL_OP_NO_SSLv2 |
3566 SSL_OP_NO_COMPRESSION;
Remi Gacogneaf5c3da2014-05-19 10:29:58 +02003567 long mode =
Emeric Brun94324a42012-10-11 14:00:19 +02003568 SSL_MODE_ENABLE_PARTIAL_WRITE |
3569 SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER |
Willy Tarreau396a1862014-11-13 14:06:52 +01003570 SSL_MODE_RELEASE_BUFFERS |
3571 SSL_MODE_SMALL_BUFFERS;
Emeric Brun850efd52014-01-29 12:24:34 +01003572 int verify = SSL_VERIFY_NONE;
Emmanuel Hocdet4de1ff12017-03-03 12:21:32 +01003573 SSL_CTX *ctx = NULL;
Emeric Brun94324a42012-10-11 14:00:19 +02003574
Thierry Fournier383085f2013-01-24 14:15:43 +01003575 /* Make sure openssl opens /dev/urandom before the chroot */
3576 if (!ssl_initialize_random()) {
3577 Alert("OpenSSL random data generator initialization failed.\n");
3578 cfgerr++;
3579 }
3580
Willy Tarreaufce03112015-01-15 21:32:40 +01003581 /* Automatic memory computations need to know we use SSL there */
3582 global.ssl_used_backend = 1;
3583
3584 /* Initiate SSL context for current server */
Emeric Brun94324a42012-10-11 14:00:19 +02003585 srv->ssl_ctx.reused_sess = NULL;
3586 if (srv->use_ssl)
3587 srv->xprt = &ssl_sock;
3588 if (srv->check.use_ssl)
Cyril Bonté9ce13112014-11-15 22:41:27 +01003589 srv->check.xprt = &ssl_sock;
Emeric Brun94324a42012-10-11 14:00:19 +02003590
Emmanuel Hocdet4de1ff12017-03-03 12:21:32 +01003591#if SSL_OP_NO_TLSv1_2
3592 if (!ctx && srv->ssl_ctx.options & SRV_SSL_O_USE_TLSV12)
3593 ctx = SSL_CTX_new(TLSv1_2_client_method());
3594#endif
3595#if SSL_OP_NO_TLSv1_1
3596 if (!ctx && srv->ssl_ctx.options & SRV_SSL_O_USE_TLSV11)
3597 ctx = SSL_CTX_new(TLSv1_1_client_method());
3598#endif
3599 if (!ctx && srv->ssl_ctx.options & SRV_SSL_O_USE_TLSV10)
3600 ctx = SSL_CTX_new(TLSv1_client_method());
3601#ifndef OPENSSL_NO_SSL3
3602 if (!ctx && srv->ssl_ctx.options & SRV_SSL_O_USE_SSLV3)
3603 ctx = SSL_CTX_new(SSLv3_client_method());
3604#endif
3605 if (!ctx) {
3606 ctx = SSL_CTX_new(SSLv23_client_method());
3607 if (srv->ssl_ctx.options & SRV_SSL_O_NO_SSLV3)
3608 options |= SSL_OP_NO_SSLv3;
3609 if (srv->ssl_ctx.options & SRV_SSL_O_NO_TLSV10)
3610 options |= SSL_OP_NO_TLSv1;
3611 if (srv->ssl_ctx.options & SRV_SSL_O_NO_TLSV11)
3612 options |= SSL_OP_NO_TLSv1_1;
3613 if (srv->ssl_ctx.options & SRV_SSL_O_NO_TLSV12)
3614 options |= SSL_OP_NO_TLSv1_2;
3615 }
3616 if (srv->ssl_ctx.options & SRV_SSL_O_NO_TLS_TICKETS)
3617 options |= SSL_OP_NO_TICKET;
3618 if (!ctx) {
Emeric Brun94324a42012-10-11 14:00:19 +02003619 Alert("config : %s '%s', server '%s': unable to allocate ssl context.\n",
3620 proxy_type_str(curproxy), curproxy->id,
3621 srv->id);
3622 cfgerr++;
3623 return cfgerr;
3624 }
Emmanuel Hocdet4de1ff12017-03-03 12:21:32 +01003625 SSL_CTX_set_options(ctx, options);
3626 SSL_CTX_set_mode(ctx, mode);
3627 srv->ssl_ctx.ctx = ctx;
3628
Emeric Bruna7aa3092012-10-26 12:58:00 +02003629 if (srv->ssl_ctx.client_crt) {
3630 if (SSL_CTX_use_PrivateKey_file(srv->ssl_ctx.ctx, srv->ssl_ctx.client_crt, SSL_FILETYPE_PEM) <= 0) {
3631 Alert("config : %s '%s', server '%s': unable to load SSL private key from PEM file '%s'.\n",
3632 proxy_type_str(curproxy), curproxy->id,
3633 srv->id, srv->ssl_ctx.client_crt);
3634 cfgerr++;
3635 }
3636 else if (SSL_CTX_use_certificate_chain_file(srv->ssl_ctx.ctx, srv->ssl_ctx.client_crt) <= 0) {
3637 Alert("config : %s '%s', server '%s': unable to load ssl certificate from PEM file '%s'.\n",
3638 proxy_type_str(curproxy), curproxy->id,
3639 srv->id, srv->ssl_ctx.client_crt);
3640 cfgerr++;
3641 }
3642 else if (SSL_CTX_check_private_key(srv->ssl_ctx.ctx) <= 0) {
3643 Alert("config : %s '%s', server '%s': inconsistencies between private key and certificate loaded from PEM file '%s'.\n",
3644 proxy_type_str(curproxy), curproxy->id,
3645 srv->id, srv->ssl_ctx.client_crt);
3646 cfgerr++;
3647 }
3648 }
Emeric Brun94324a42012-10-11 14:00:19 +02003649
Emeric Brun850efd52014-01-29 12:24:34 +01003650 if (global.ssl_server_verify == SSL_SERVER_VERIFY_REQUIRED)
3651 verify = SSL_VERIFY_PEER;
Emeric Brun850efd52014-01-29 12:24:34 +01003652 switch (srv->ssl_ctx.verify) {
3653 case SSL_SOCK_VERIFY_NONE:
3654 verify = SSL_VERIFY_NONE;
3655 break;
3656 case SSL_SOCK_VERIFY_REQUIRED:
3657 verify = SSL_VERIFY_PEER;
3658 break;
3659 }
Evan Broderbe554312013-06-27 00:05:25 -07003660 SSL_CTX_set_verify(srv->ssl_ctx.ctx,
Emeric Brun850efd52014-01-29 12:24:34 +01003661 verify,
Evan Broderbe554312013-06-27 00:05:25 -07003662 srv->ssl_ctx.verify_host ? ssl_sock_srv_verifycbk : NULL);
Emeric Brun850efd52014-01-29 12:24:34 +01003663 if (verify & SSL_VERIFY_PEER) {
Emeric Brunef42d922012-10-11 16:11:36 +02003664 if (srv->ssl_ctx.ca_file) {
3665 /* load CAfile to verify */
3666 if (!SSL_CTX_load_verify_locations(srv->ssl_ctx.ctx, srv->ssl_ctx.ca_file, NULL)) {
Willy Tarreau07ba08b2014-02-16 19:22:08 +01003667 Alert("Proxy '%s', server '%s' [%s:%d] unable to load CA file '%s'.\n",
Emeric Brunef42d922012-10-11 16:11:36 +02003668 curproxy->id, srv->id,
3669 srv->conf.file, srv->conf.line, srv->ssl_ctx.ca_file);
3670 cfgerr++;
3671 }
3672 }
Emeric Brun850efd52014-01-29 12:24:34 +01003673 else {
3674 if (global.ssl_server_verify == SSL_SERVER_VERIFY_REQUIRED)
Willy Tarreau07ba08b2014-02-16 19:22:08 +01003675 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 +01003676 curproxy->id, srv->id,
3677 srv->conf.file, srv->conf.line);
3678 else
Willy Tarreau07ba08b2014-02-16 19:22:08 +01003679 Alert("Proxy '%s', server '%s' [%s:%d] verify is enabled but no CA file specified.\n",
Emeric Brun850efd52014-01-29 12:24:34 +01003680 curproxy->id, srv->id,
3681 srv->conf.file, srv->conf.line);
3682 cfgerr++;
3683 }
Emeric Brunef42d922012-10-11 16:11:36 +02003684#ifdef X509_V_FLAG_CRL_CHECK
3685 if (srv->ssl_ctx.crl_file) {
3686 X509_STORE *store = SSL_CTX_get_cert_store(srv->ssl_ctx.ctx);
3687
3688 if (!store || !X509_STORE_load_locations(store, srv->ssl_ctx.crl_file, NULL)) {
Willy Tarreau07ba08b2014-02-16 19:22:08 +01003689 Alert("Proxy '%s', server '%s' [%s:%d] unable to configure CRL file '%s'.\n",
Emeric Brunef42d922012-10-11 16:11:36 +02003690 curproxy->id, srv->id,
3691 srv->conf.file, srv->conf.line, srv->ssl_ctx.crl_file);
3692 cfgerr++;
3693 }
3694 else {
3695 X509_STORE_set_flags(store, X509_V_FLAG_CRL_CHECK|X509_V_FLAG_CRL_CHECK_ALL);
3696 }
3697 }
3698#endif
3699 }
3700
Emeric Brun94324a42012-10-11 14:00:19 +02003701 SSL_CTX_set_session_cache_mode(srv->ssl_ctx.ctx, SSL_SESS_CACHE_OFF);
3702 if (srv->ssl_ctx.ciphers &&
3703 !SSL_CTX_set_cipher_list(srv->ssl_ctx.ctx, srv->ssl_ctx.ciphers)) {
3704 Alert("Proxy '%s', server '%s' [%s:%d] : unable to set SSL cipher list to '%s'.\n",
3705 curproxy->id, srv->id,
3706 srv->conf.file, srv->conf.line, srv->ssl_ctx.ciphers);
3707 cfgerr++;
3708 }
3709
3710 return cfgerr;
3711}
3712
Willy Tarreau2a65ff02012-09-13 17:54:29 +02003713/* Walks down the two trees in bind_conf and prepares all certs. The pointer may
Emeric Brunfc0421f2012-09-07 17:30:07 +02003714 * be NULL, in which case nothing is done. Returns the number of errors
3715 * encountered.
3716 */
Willy Tarreau03209342016-12-22 17:08:28 +01003717int ssl_sock_prepare_all_ctx(struct bind_conf *bind_conf)
Emeric Brunfc0421f2012-09-07 17:30:07 +02003718{
3719 struct ebmb_node *node;
3720 struct sni_ctx *sni;
3721 int err = 0;
3722
Willy Tarreau2a65ff02012-09-13 17:54:29 +02003723 if (!bind_conf || !bind_conf->is_ssl)
Emeric Brunfc0421f2012-09-07 17:30:07 +02003724 return 0;
3725
Willy Tarreaufce03112015-01-15 21:32:40 +01003726 /* Automatic memory computations need to know we use SSL there */
3727 global.ssl_used_frontend = 1;
3728
Emmanuel Hocdetf6b37c62017-03-06 15:34:44 +01003729 /* Make sure openssl opens /dev/urandom before the chroot */
3730 if (!ssl_initialize_random()) {
3731 Alert("OpenSSL random data generator initialization failed.\n");
3732 err++;
3733 }
3734 /* Create initial_ctx used to start the ssl connection before do switchctx */
3735 if (!bind_conf->initial_ctx) {
3736 bind_conf->initial_ctx = ssl_sock_initial_ctx(bind_conf);
3737 /* It should not be necessary to call this function, but it's
3738 necessary first to check and move all initialisation related
3739 to initial_ctx in ssl_sock_initial_ctx. */
3740 err += ssl_sock_prepare_ctx(bind_conf, NULL, bind_conf->initial_ctx);
3741 }
Emeric Brun0bed9942014-10-30 19:25:24 +01003742 if (bind_conf->default_ctx)
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003743 err += ssl_sock_prepare_ctx(bind_conf, bind_conf->default_ssl_conf, bind_conf->default_ctx);
Emeric Brun0bed9942014-10-30 19:25:24 +01003744
Willy Tarreau2a65ff02012-09-13 17:54:29 +02003745 node = ebmb_first(&bind_conf->sni_ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02003746 while (node) {
3747 sni = ebmb_entry(node, struct sni_ctx, name);
Emeric Brun0bed9942014-10-30 19:25:24 +01003748 if (!sni->order && sni->ctx != bind_conf->default_ctx)
3749 /* only initialize the CTX on its first occurrence and
3750 if it is not the default_ctx */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003751 err += ssl_sock_prepare_ctx(bind_conf, sni->conf, sni->ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02003752 node = ebmb_next(node);
3753 }
3754
Willy Tarreau2a65ff02012-09-13 17:54:29 +02003755 node = ebmb_first(&bind_conf->sni_w_ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02003756 while (node) {
3757 sni = ebmb_entry(node, struct sni_ctx, name);
Emeric Brun0bed9942014-10-30 19:25:24 +01003758 if (!sni->order && sni->ctx != bind_conf->default_ctx)
3759 /* only initialize the CTX on its first occurrence and
3760 if it is not the default_ctx */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003761 err += ssl_sock_prepare_ctx(bind_conf, sni->conf, sni->ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02003762 node = ebmb_next(node);
3763 }
3764 return err;
3765}
3766
Willy Tarreau55d37912016-12-21 23:38:39 +01003767/* Prepares all the contexts for a bind_conf and allocates the shared SSL
3768 * context if needed. Returns < 0 on error, 0 on success. The warnings and
3769 * alerts are directly emitted since the rest of the stack does it below.
3770 */
3771int ssl_sock_prepare_bind_conf(struct bind_conf *bind_conf)
3772{
3773 struct proxy *px = bind_conf->frontend;
3774 int alloc_ctx;
3775 int err;
3776
3777 if (!bind_conf->is_ssl) {
3778 if (bind_conf->default_ctx) {
3779 Warning("Proxy '%s': A certificate was specified but SSL was not enabled on bind '%s' at [%s:%d] (use 'ssl').\n",
3780 px->id, bind_conf->arg, bind_conf->file, bind_conf->line);
3781 }
3782 return 0;
3783 }
3784 if (!bind_conf->default_ctx) {
3785 Alert("Proxy '%s': no SSL certificate specified for bind '%s' at [%s:%d] (use 'crt').\n",
3786 px->id, bind_conf->arg, bind_conf->file, bind_conf->line);
3787 return -1;
3788 }
3789
Willy Tarreauef934602016-12-22 23:12:01 +01003790 alloc_ctx = shared_context_init(global.tune.sslcachesize, (!global_ssl.private_cache && (global.nbproc > 1)) ? 1 : 0);
Willy Tarreau55d37912016-12-21 23:38:39 +01003791 if (alloc_ctx < 0) {
3792 if (alloc_ctx == SHCTX_E_INIT_LOCK)
3793 Alert("Unable to initialize the lock for the shared SSL session cache. You can retry using the global statement 'tune.ssl.force-private-cache' but it could increase CPU usage due to renegotiations if nbproc > 1.\n");
3794 else
3795 Alert("Unable to allocate SSL session cache.\n");
3796 return -1;
3797 }
3798
3799 err = 0;
3800 /* initialize all certificate contexts */
3801 err += ssl_sock_prepare_all_ctx(bind_conf);
3802
3803 /* initialize CA variables if the certificates generation is enabled */
3804 err += ssl_sock_load_ca(bind_conf);
3805
3806 return -err;
3807}
Christopher Faulet77fe80c2015-07-29 13:02:40 +02003808
3809/* release ssl context allocated for servers. */
3810void ssl_sock_free_srv_ctx(struct server *srv)
3811{
3812 if (srv->ssl_ctx.ctx)
3813 SSL_CTX_free(srv->ssl_ctx.ctx);
3814}
3815
Willy Tarreau2a65ff02012-09-13 17:54:29 +02003816/* Walks down the two trees in bind_conf and frees all the certs. The pointer may
Emeric Brunfc0421f2012-09-07 17:30:07 +02003817 * be NULL, in which case nothing is done. The default_ctx is nullified too.
3818 */
Willy Tarreau2a65ff02012-09-13 17:54:29 +02003819void ssl_sock_free_all_ctx(struct bind_conf *bind_conf)
Emeric Brunfc0421f2012-09-07 17:30:07 +02003820{
3821 struct ebmb_node *node, *back;
3822 struct sni_ctx *sni;
3823
Willy Tarreau2a65ff02012-09-13 17:54:29 +02003824 if (!bind_conf || !bind_conf->is_ssl)
Emeric Brunfc0421f2012-09-07 17:30:07 +02003825 return;
3826
Willy Tarreau2a65ff02012-09-13 17:54:29 +02003827 node = ebmb_first(&bind_conf->sni_ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02003828 while (node) {
3829 sni = ebmb_entry(node, struct sni_ctx, name);
3830 back = ebmb_next(node);
3831 ebmb_delete(node);
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003832 if (!sni->order) { /* only free the CTX on its first occurrence */
Emeric Brunfc0421f2012-09-07 17:30:07 +02003833 SSL_CTX_free(sni->ctx);
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003834 ssl_sock_free_ssl_conf(sni->conf);
3835 free(sni->conf);
3836 sni->conf = NULL;
3837 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02003838 free(sni);
3839 node = back;
3840 }
3841
Willy Tarreau2a65ff02012-09-13 17:54:29 +02003842 node = ebmb_first(&bind_conf->sni_w_ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02003843 while (node) {
3844 sni = ebmb_entry(node, struct sni_ctx, name);
3845 back = ebmb_next(node);
3846 ebmb_delete(node);
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003847 if (!sni->order) { /* only free the CTX on its first occurrence */
Emeric Brunfc0421f2012-09-07 17:30:07 +02003848 SSL_CTX_free(sni->ctx);
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003849 ssl_sock_free_ssl_conf(sni->conf);
3850 free(sni->conf);
3851 sni->conf = NULL;
3852 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02003853 free(sni);
3854 node = back;
3855 }
Emmanuel Hocdetf6b37c62017-03-06 15:34:44 +01003856 SSL_CTX_free(bind_conf->initial_ctx);
3857 bind_conf->initial_ctx = NULL;
Willy Tarreau2a65ff02012-09-13 17:54:29 +02003858 bind_conf->default_ctx = NULL;
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003859 bind_conf->default_ssl_conf = NULL;
Emeric Brune1f38db2012-09-03 20:36:47 +02003860}
3861
Willy Tarreau795cdab2016-12-22 17:30:54 +01003862/* Destroys all the contexts for a bind_conf. This is used during deinit(). */
3863void ssl_sock_destroy_bind_conf(struct bind_conf *bind_conf)
3864{
3865 ssl_sock_free_ca(bind_conf);
3866 ssl_sock_free_all_ctx(bind_conf);
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003867 ssl_sock_free_ssl_conf(&bind_conf->ssl_conf);
Willy Tarreau795cdab2016-12-22 17:30:54 +01003868 free(bind_conf->ca_sign_file);
3869 free(bind_conf->ca_sign_pass);
Willy Tarreau795cdab2016-12-22 17:30:54 +01003870 if (bind_conf->keys_ref) {
3871 free(bind_conf->keys_ref->filename);
3872 free(bind_conf->keys_ref->tlskeys);
3873 LIST_DEL(&bind_conf->keys_ref->list);
3874 free(bind_conf->keys_ref);
3875 }
3876 bind_conf->keys_ref = NULL;
Willy Tarreau795cdab2016-12-22 17:30:54 +01003877 bind_conf->ca_sign_pass = NULL;
3878 bind_conf->ca_sign_file = NULL;
Willy Tarreau795cdab2016-12-22 17:30:54 +01003879}
3880
Christopher Faulet31af49d2015-06-09 17:29:50 +02003881/* Load CA cert file and private key used to generate certificates */
3882int
Willy Tarreau03209342016-12-22 17:08:28 +01003883ssl_sock_load_ca(struct bind_conf *bind_conf)
Christopher Faulet31af49d2015-06-09 17:29:50 +02003884{
Willy Tarreau03209342016-12-22 17:08:28 +01003885 struct proxy *px = bind_conf->frontend;
Christopher Faulet31af49d2015-06-09 17:29:50 +02003886 FILE *fp;
3887 X509 *cacert = NULL;
3888 EVP_PKEY *capkey = NULL;
3889 int err = 0;
3890
3891 if (!bind_conf || !bind_conf->generate_certs)
3892 return err;
3893
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +01003894#if (defined SSL_CTRL_SET_TLSEXT_HOSTNAME && !defined SSL_NO_GENERATE_CERTIFICATES)
Willy Tarreauef934602016-12-22 23:12:01 +01003895 if (global_ssl.ctx_cache)
3896 ssl_ctx_lru_tree = lru64_new(global_ssl.ctx_cache);
Christopher Fauletd2cab922015-07-28 16:03:47 +02003897 ssl_ctx_lru_seed = (unsigned int)time(NULL);
Willy Tarreaua84c2672015-10-09 12:10:13 +02003898#endif
Christopher Fauletd2cab922015-07-28 16:03:47 +02003899
Christopher Faulet31af49d2015-06-09 17:29:50 +02003900 if (!bind_conf->ca_sign_file) {
3901 Alert("Proxy '%s': cannot enable certificate generation, "
3902 "no CA certificate File configured at [%s:%d].\n",
3903 px->id, bind_conf->file, bind_conf->line);
Christopher Faulet31af49d2015-06-09 17:29:50 +02003904 goto load_error;
Christopher Fauletc6f02fb2015-10-09 10:53:31 +02003905 }
Christopher Faulet31af49d2015-06-09 17:29:50 +02003906
3907 /* read in the CA certificate */
3908 if (!(fp = fopen(bind_conf->ca_sign_file, "r"))) {
3909 Alert("Proxy '%s': Failed to read CA certificate file '%s' at [%s:%d].\n",
3910 px->id, bind_conf->ca_sign_file, bind_conf->file, bind_conf->line);
Christopher Faulet31af49d2015-06-09 17:29:50 +02003911 goto load_error;
3912 }
3913 if (!(cacert = PEM_read_X509(fp, NULL, NULL, NULL))) {
3914 Alert("Proxy '%s': Failed to read CA certificate file '%s' at [%s:%d].\n",
3915 px->id, bind_conf->ca_sign_file, bind_conf->file, bind_conf->line);
Christopher Fauletc6f02fb2015-10-09 10:53:31 +02003916 goto read_error;
Christopher Faulet31af49d2015-06-09 17:29:50 +02003917 }
Christopher Fauletc6f02fb2015-10-09 10:53:31 +02003918 rewind(fp);
Christopher Faulet31af49d2015-06-09 17:29:50 +02003919 if (!(capkey = PEM_read_PrivateKey(fp, NULL, NULL, bind_conf->ca_sign_pass))) {
3920 Alert("Proxy '%s': Failed to read CA private key file '%s' at [%s:%d].\n",
3921 px->id, bind_conf->ca_sign_file, bind_conf->file, bind_conf->line);
Christopher Fauletc6f02fb2015-10-09 10:53:31 +02003922 goto read_error;
Christopher Faulet31af49d2015-06-09 17:29:50 +02003923 }
Christopher Faulet31af49d2015-06-09 17:29:50 +02003924
Christopher Fauletc6f02fb2015-10-09 10:53:31 +02003925 fclose (fp);
Christopher Faulet31af49d2015-06-09 17:29:50 +02003926 bind_conf->ca_sign_cert = cacert;
3927 bind_conf->ca_sign_pkey = capkey;
3928 return err;
3929
Christopher Fauletc6f02fb2015-10-09 10:53:31 +02003930 read_error:
3931 fclose (fp);
Christopher Faulet31af49d2015-06-09 17:29:50 +02003932 if (capkey) EVP_PKEY_free(capkey);
3933 if (cacert) X509_free(cacert);
Christopher Fauletc6f02fb2015-10-09 10:53:31 +02003934 load_error:
3935 bind_conf->generate_certs = 0;
3936 err++;
Christopher Faulet31af49d2015-06-09 17:29:50 +02003937 return err;
3938}
3939
3940/* Release CA cert and private key used to generate certificated */
3941void
3942ssl_sock_free_ca(struct bind_conf *bind_conf)
3943{
3944 if (!bind_conf)
3945 return;
3946
3947 if (bind_conf->ca_sign_pkey)
3948 EVP_PKEY_free(bind_conf->ca_sign_pkey);
3949 if (bind_conf->ca_sign_cert)
3950 X509_free(bind_conf->ca_sign_cert);
Willy Tarreau94ff03a2016-12-22 17:57:46 +01003951 bind_conf->ca_sign_pkey = NULL;
3952 bind_conf->ca_sign_cert = NULL;
Christopher Faulet31af49d2015-06-09 17:29:50 +02003953}
3954
Emeric Brun46591952012-05-18 15:47:34 +02003955/*
3956 * This function is called if SSL * context is not yet allocated. The function
3957 * is designed to be called before any other data-layer operation and sets the
3958 * handshake flag on the connection. It is safe to call it multiple times.
3959 * It returns 0 on success and -1 in error case.
3960 */
3961static int ssl_sock_init(struct connection *conn)
3962{
3963 /* already initialized */
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02003964 if (conn->xprt_ctx)
Emeric Brun46591952012-05-18 15:47:34 +02003965 return 0;
3966
Willy Tarreau3c728722014-01-23 13:50:42 +01003967 if (!conn_ctrl_ready(conn))
Willy Tarreauf79c8172013-10-21 16:30:56 +02003968 return 0;
3969
Willy Tarreau20879a02012-12-03 16:32:10 +01003970 if (global.maxsslconn && sslconns >= global.maxsslconn) {
3971 conn->err_code = CO_ER_SSL_TOO_MANY;
Willy Tarreau403edff2012-09-06 11:58:37 +02003972 return -1;
Willy Tarreau20879a02012-12-03 16:32:10 +01003973 }
Willy Tarreau403edff2012-09-06 11:58:37 +02003974
Emeric Brun46591952012-05-18 15:47:34 +02003975 /* If it is in client mode initiate SSL session
3976 in connect state otherwise accept state */
Willy Tarreau3fdb3662012-11-12 00:42:33 +01003977 if (objt_server(conn->target)) {
Willy Tarreaufba03cd2014-11-13 13:48:58 +01003978 int may_retry = 1;
3979
3980 retry_connect:
Emeric Brun46591952012-05-18 15:47:34 +02003981 /* Alloc a new SSL session ctx */
Willy Tarreau3fdb3662012-11-12 00:42:33 +01003982 conn->xprt_ctx = SSL_new(objt_server(conn->target)->ssl_ctx.ctx);
Willy Tarreau20879a02012-12-03 16:32:10 +01003983 if (!conn->xprt_ctx) {
Willy Tarreaufba03cd2014-11-13 13:48:58 +01003984 if (may_retry--) {
3985 pool_gc2();
3986 goto retry_connect;
3987 }
Willy Tarreau20879a02012-12-03 16:32:10 +01003988 conn->err_code = CO_ER_SSL_NO_MEM;
Emeric Brun46591952012-05-18 15:47:34 +02003989 return -1;
Willy Tarreau20879a02012-12-03 16:32:10 +01003990 }
Emeric Brun46591952012-05-18 15:47:34 +02003991
Emeric Brun46591952012-05-18 15:47:34 +02003992 /* set fd on SSL session context */
Emeric Brun55476152014-11-12 17:35:37 +01003993 if (!SSL_set_fd(conn->xprt_ctx, conn->t.sock.fd)) {
3994 SSL_free(conn->xprt_ctx);
3995 conn->xprt_ctx = NULL;
Willy Tarreaufba03cd2014-11-13 13:48:58 +01003996 if (may_retry--) {
3997 pool_gc2();
3998 goto retry_connect;
3999 }
Emeric Brun55476152014-11-12 17:35:37 +01004000 conn->err_code = CO_ER_SSL_NO_MEM;
4001 return -1;
4002 }
Emeric Brun46591952012-05-18 15:47:34 +02004003
Evan Broderbe554312013-06-27 00:05:25 -07004004 /* set connection pointer */
Emeric Brun55476152014-11-12 17:35:37 +01004005 if (!SSL_set_app_data(conn->xprt_ctx, conn)) {
4006 SSL_free(conn->xprt_ctx);
4007 conn->xprt_ctx = NULL;
Willy Tarreaufba03cd2014-11-13 13:48:58 +01004008 if (may_retry--) {
4009 pool_gc2();
4010 goto retry_connect;
4011 }
Emeric Brun55476152014-11-12 17:35:37 +01004012 conn->err_code = CO_ER_SSL_NO_MEM;
4013 return -1;
4014 }
4015
4016 SSL_set_connect_state(conn->xprt_ctx);
4017 if (objt_server(conn->target)->ssl_ctx.reused_sess) {
4018 if(!SSL_set_session(conn->xprt_ctx, objt_server(conn->target)->ssl_ctx.reused_sess)) {
4019 SSL_SESSION_free(objt_server(conn->target)->ssl_ctx.reused_sess);
4020 objt_server(conn->target)->ssl_ctx.reused_sess = NULL;
4021 }
4022 }
Evan Broderbe554312013-06-27 00:05:25 -07004023
Emeric Brun46591952012-05-18 15:47:34 +02004024 /* leave init state and start handshake */
Willy Tarreau05737472012-09-04 08:03:39 +02004025 conn->flags |= CO_FL_SSL_WAIT_HS | CO_FL_WAIT_L6_CONN;
Willy Tarreau403edff2012-09-06 11:58:37 +02004026
4027 sslconns++;
Willy Tarreau71b734c2014-01-28 15:19:44 +01004028 totalsslconns++;
Emeric Brun46591952012-05-18 15:47:34 +02004029 return 0;
4030 }
Willy Tarreau3fdb3662012-11-12 00:42:33 +01004031 else if (objt_listener(conn->target)) {
Willy Tarreaufba03cd2014-11-13 13:48:58 +01004032 int may_retry = 1;
4033
4034 retry_accept:
Emeric Brun46591952012-05-18 15:47:34 +02004035 /* Alloc a new SSL session ctx */
Emmanuel Hocdetf6b37c62017-03-06 15:34:44 +01004036 conn->xprt_ctx = SSL_new(objt_listener(conn->target)->bind_conf->initial_ctx);
Willy Tarreau20879a02012-12-03 16:32:10 +01004037 if (!conn->xprt_ctx) {
Willy Tarreaufba03cd2014-11-13 13:48:58 +01004038 if (may_retry--) {
4039 pool_gc2();
4040 goto retry_accept;
4041 }
Willy Tarreau20879a02012-12-03 16:32:10 +01004042 conn->err_code = CO_ER_SSL_NO_MEM;
Emeric Brun46591952012-05-18 15:47:34 +02004043 return -1;
Willy Tarreau20879a02012-12-03 16:32:10 +01004044 }
Emeric Brun46591952012-05-18 15:47:34 +02004045
Emeric Brun46591952012-05-18 15:47:34 +02004046 /* set fd on SSL session context */
Emeric Brun55476152014-11-12 17:35:37 +01004047 if (!SSL_set_fd(conn->xprt_ctx, conn->t.sock.fd)) {
4048 SSL_free(conn->xprt_ctx);
4049 conn->xprt_ctx = NULL;
Willy Tarreaufba03cd2014-11-13 13:48:58 +01004050 if (may_retry--) {
4051 pool_gc2();
4052 goto retry_accept;
4053 }
Emeric Brun55476152014-11-12 17:35:37 +01004054 conn->err_code = CO_ER_SSL_NO_MEM;
4055 return -1;
4056 }
Emeric Brun46591952012-05-18 15:47:34 +02004057
Emeric Brune1f38db2012-09-03 20:36:47 +02004058 /* set connection pointer */
Emeric Brun55476152014-11-12 17:35:37 +01004059 if (!SSL_set_app_data(conn->xprt_ctx, conn)) {
4060 SSL_free(conn->xprt_ctx);
4061 conn->xprt_ctx = NULL;
Willy Tarreaufba03cd2014-11-13 13:48:58 +01004062 if (may_retry--) {
4063 pool_gc2();
4064 goto retry_accept;
4065 }
Emeric Brun55476152014-11-12 17:35:37 +01004066 conn->err_code = CO_ER_SSL_NO_MEM;
4067 return -1;
4068 }
4069
4070 SSL_set_accept_state(conn->xprt_ctx);
Emeric Brune1f38db2012-09-03 20:36:47 +02004071
Emeric Brun46591952012-05-18 15:47:34 +02004072 /* leave init state and start handshake */
Willy Tarreau05737472012-09-04 08:03:39 +02004073 conn->flags |= CO_FL_SSL_WAIT_HS | CO_FL_WAIT_L6_CONN;
Willy Tarreau403edff2012-09-06 11:58:37 +02004074
4075 sslconns++;
Willy Tarreau71b734c2014-01-28 15:19:44 +01004076 totalsslconns++;
Emeric Brun46591952012-05-18 15:47:34 +02004077 return 0;
4078 }
4079 /* don't know how to handle such a target */
Willy Tarreau20879a02012-12-03 16:32:10 +01004080 conn->err_code = CO_ER_SSL_NO_TARGET;
Emeric Brun46591952012-05-18 15:47:34 +02004081 return -1;
4082}
4083
4084
4085/* This is the callback which is used when an SSL handshake is pending. It
4086 * updates the FD status if it wants some polling before being called again.
4087 * It returns 0 if it fails in a fatal way or needs to poll to go further,
4088 * otherwise it returns non-zero and removes itself from the connection's
4089 * flags (the bit is provided in <flag> by the caller).
4090 */
4091int ssl_sock_handshake(struct connection *conn, unsigned int flag)
4092{
4093 int ret;
4094
Willy Tarreau3c728722014-01-23 13:50:42 +01004095 if (!conn_ctrl_ready(conn))
Willy Tarreauf79c8172013-10-21 16:30:56 +02004096 return 0;
4097
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02004098 if (!conn->xprt_ctx)
Emeric Brun46591952012-05-18 15:47:34 +02004099 goto out_error;
4100
Emeric Brun674b7432012-11-08 19:21:55 +01004101 /* If we use SSL_do_handshake to process a reneg initiated by
4102 * the remote peer, it sometimes returns SSL_ERROR_SSL.
4103 * Usually SSL_write and SSL_read are used and process implicitly
4104 * the reneg handshake.
4105 * Here we use SSL_peek as a workaround for reneg.
4106 */
4107 if ((conn->flags & CO_FL_CONNECTED) && SSL_renegotiate_pending(conn->xprt_ctx)) {
4108 char c;
4109
4110 ret = SSL_peek(conn->xprt_ctx, &c, 1);
4111 if (ret <= 0) {
4112 /* handshake may have not been completed, let's find why */
4113 ret = SSL_get_error(conn->xprt_ctx, ret);
4114 if (ret == SSL_ERROR_WANT_WRITE) {
4115 /* SSL handshake needs to write, L4 connection may not be ready */
4116 __conn_sock_stop_recv(conn);
Willy Tarreaue1f50c42014-01-22 20:02:06 +01004117 __conn_sock_want_send(conn);
4118 fd_cant_send(conn->t.sock.fd);
Emeric Brun674b7432012-11-08 19:21:55 +01004119 return 0;
4120 }
4121 else if (ret == SSL_ERROR_WANT_READ) {
4122 /* handshake may have been completed but we have
4123 * no more data to read.
4124 */
4125 if (!SSL_renegotiate_pending(conn->xprt_ctx)) {
4126 ret = 1;
4127 goto reneg_ok;
4128 }
4129 /* SSL handshake needs to read, L4 connection is ready */
4130 if (conn->flags & CO_FL_WAIT_L4_CONN)
4131 conn->flags &= ~CO_FL_WAIT_L4_CONN;
4132 __conn_sock_stop_send(conn);
Willy Tarreaue1f50c42014-01-22 20:02:06 +01004133 __conn_sock_want_recv(conn);
4134 fd_cant_recv(conn->t.sock.fd);
Emeric Brun674b7432012-11-08 19:21:55 +01004135 return 0;
4136 }
4137 else if (ret == SSL_ERROR_SYSCALL) {
4138 /* if errno is null, then connection was successfully established */
4139 if (!errno && conn->flags & CO_FL_WAIT_L4_CONN)
4140 conn->flags &= ~CO_FL_WAIT_L4_CONN;
Willy Tarreau20879a02012-12-03 16:32:10 +01004141 if (!conn->err_code) {
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +01004142#ifdef OPENSSL_NO_HEARTBEATS /* BoringSSL */
4143 conn->err_code = CO_ER_SSL_HANDSHAKE;
4144#else
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004145 int empty_handshake;
Luca Pizzamiglio578b1692016-12-12 10:56:56 +01004146#if (OPENSSL_VERSION_NUMBER >= 0x1010000fL) && !defined(LIBRESSL_VERSION_NUMBER)
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004147 OSSL_HANDSHAKE_STATE state = SSL_get_state((SSL *)conn->xprt_ctx);
4148 empty_handshake = state == TLS_ST_BEFORE;
4149#else
4150 empty_handshake = !((SSL *)conn->xprt_ctx)->packet_length;
4151#endif
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004152 if (empty_handshake) {
Emeric Brun29f037d2014-04-25 19:05:36 +02004153 if (!errno) {
4154 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
4155 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
4156 else
4157 conn->err_code = CO_ER_SSL_EMPTY;
4158 }
4159 else {
4160 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
4161 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
4162 else
4163 conn->err_code = CO_ER_SSL_ABORT;
4164 }
4165 }
4166 else {
4167 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
4168 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
Willy Tarreau20879a02012-12-03 16:32:10 +01004169 else
Emeric Brun29f037d2014-04-25 19:05:36 +02004170 conn->err_code = CO_ER_SSL_HANDSHAKE;
4171 }
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +01004172#endif
Willy Tarreau20879a02012-12-03 16:32:10 +01004173 }
Emeric Brun674b7432012-11-08 19:21:55 +01004174 goto out_error;
4175 }
4176 else {
4177 /* Fail on all other handshake errors */
4178 /* Note: OpenSSL may leave unread bytes in the socket's
4179 * buffer, causing an RST to be emitted upon close() on
4180 * TCP sockets. We first try to drain possibly pending
4181 * data to avoid this as much as possible.
4182 */
Willy Tarreaud85c4852015-03-13 00:40:28 +01004183 conn_sock_drain(conn);
Willy Tarreau20879a02012-12-03 16:32:10 +01004184 if (!conn->err_code)
Willy Tarreauf51c6982014-04-25 20:02:39 +02004185 conn->err_code = (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT) ?
4186 CO_ER_SSL_KILLED_HB : CO_ER_SSL_HANDSHAKE;
Emeric Brun674b7432012-11-08 19:21:55 +01004187 goto out_error;
4188 }
4189 }
4190 /* read some data: consider handshake completed */
4191 goto reneg_ok;
4192 }
4193
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02004194 ret = SSL_do_handshake(conn->xprt_ctx);
Emeric Brun46591952012-05-18 15:47:34 +02004195 if (ret != 1) {
4196 /* handshake did not complete, let's find why */
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02004197 ret = SSL_get_error(conn->xprt_ctx, ret);
Emeric Brun46591952012-05-18 15:47:34 +02004198
4199 if (ret == SSL_ERROR_WANT_WRITE) {
4200 /* SSL handshake needs to write, L4 connection may not be ready */
4201 __conn_sock_stop_recv(conn);
Willy Tarreaue1f50c42014-01-22 20:02:06 +01004202 __conn_sock_want_send(conn);
4203 fd_cant_send(conn->t.sock.fd);
Emeric Brun46591952012-05-18 15:47:34 +02004204 return 0;
4205 }
4206 else if (ret == SSL_ERROR_WANT_READ) {
4207 /* SSL handshake needs to read, L4 connection is ready */
4208 if (conn->flags & CO_FL_WAIT_L4_CONN)
4209 conn->flags &= ~CO_FL_WAIT_L4_CONN;
4210 __conn_sock_stop_send(conn);
Willy Tarreaue1f50c42014-01-22 20:02:06 +01004211 __conn_sock_want_recv(conn);
4212 fd_cant_recv(conn->t.sock.fd);
Emeric Brun46591952012-05-18 15:47:34 +02004213 return 0;
4214 }
Willy Tarreau89230192012-09-28 20:22:13 +02004215 else if (ret == SSL_ERROR_SYSCALL) {
4216 /* if errno is null, then connection was successfully established */
4217 if (!errno && conn->flags & CO_FL_WAIT_L4_CONN)
4218 conn->flags &= ~CO_FL_WAIT_L4_CONN;
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +01004219 if (!conn->err_code) {
4220#ifdef OPENSSL_NO_HEARTBEATS /* BoringSSL */
4221 conn->err_code = CO_ER_SSL_HANDSHAKE;
4222#else
4223 int empty_handshake;
Luca Pizzamiglio578b1692016-12-12 10:56:56 +01004224#if (OPENSSL_VERSION_NUMBER >= 0x1010000fL) && !defined(LIBRESSL_VERSION_NUMBER)
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +01004225 OSSL_HANDSHAKE_STATE state = SSL_get_state((SSL *)conn->xprt_ctx);
4226 empty_handshake = state == TLS_ST_BEFORE;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004227#else
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +01004228 empty_handshake = !((SSL *)conn->xprt_ctx)->packet_length;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004229#endif
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +01004230 if (empty_handshake) {
4231 if (!errno) {
4232 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
4233 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
4234 else
4235 conn->err_code = CO_ER_SSL_EMPTY;
4236 }
4237 else {
4238 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
4239 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
4240 else
4241 conn->err_code = CO_ER_SSL_ABORT;
4242 }
Emeric Brun29f037d2014-04-25 19:05:36 +02004243 }
4244 else {
4245 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
4246 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
4247 else
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +01004248 conn->err_code = CO_ER_SSL_HANDSHAKE;
Emeric Brun29f037d2014-04-25 19:05:36 +02004249 }
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +01004250#endif
Emeric Brun29f037d2014-04-25 19:05:36 +02004251 }
Willy Tarreau89230192012-09-28 20:22:13 +02004252 goto out_error;
4253 }
Emeric Brun46591952012-05-18 15:47:34 +02004254 else {
4255 /* Fail on all other handshake errors */
Willy Tarreau566dc552012-10-19 20:52:18 +02004256 /* Note: OpenSSL may leave unread bytes in the socket's
4257 * buffer, causing an RST to be emitted upon close() on
4258 * TCP sockets. We first try to drain possibly pending
4259 * data to avoid this as much as possible.
4260 */
Willy Tarreaud85c4852015-03-13 00:40:28 +01004261 conn_sock_drain(conn);
Willy Tarreau20879a02012-12-03 16:32:10 +01004262 if (!conn->err_code)
Willy Tarreauf51c6982014-04-25 20:02:39 +02004263 conn->err_code = (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT) ?
4264 CO_ER_SSL_KILLED_HB : CO_ER_SSL_HANDSHAKE;
Emeric Brun46591952012-05-18 15:47:34 +02004265 goto out_error;
4266 }
4267 }
4268
Emeric Brun674b7432012-11-08 19:21:55 +01004269reneg_ok:
Emeric Brun46591952012-05-18 15:47:34 +02004270 /* Handshake succeeded */
Willy Tarreau0c9c2722014-05-28 12:28:58 +02004271 if (!SSL_session_reused(conn->xprt_ctx)) {
4272 if (objt_server(conn->target)) {
4273 update_freq_ctr(&global.ssl_be_keys_per_sec, 1);
4274 if (global.ssl_be_keys_per_sec.curr_ctr > global.ssl_be_keys_max)
4275 global.ssl_be_keys_max = global.ssl_be_keys_per_sec.curr_ctr;
4276
Emeric Brun46591952012-05-18 15:47:34 +02004277 /* check if session was reused, if not store current session on server for reuse */
Willy Tarreau30fd4bd2016-12-22 21:54:21 +01004278 if (objt_server(conn->target)->ssl_ctx.reused_sess) {
Willy Tarreau3fdb3662012-11-12 00:42:33 +01004279 SSL_SESSION_free(objt_server(conn->target)->ssl_ctx.reused_sess);
Willy Tarreau30fd4bd2016-12-22 21:54:21 +01004280 objt_server(conn->target)->ssl_ctx.reused_sess = NULL;
4281 }
Emeric Brun46591952012-05-18 15:47:34 +02004282
Willy Tarreau2a3fb1c2015-02-05 16:47:07 +01004283 if (!(objt_server(conn->target)->ssl_ctx.options & SRV_SSL_O_NO_REUSE))
4284 objt_server(conn->target)->ssl_ctx.reused_sess = SSL_get1_session(conn->xprt_ctx);
Emeric Brun46591952012-05-18 15:47:34 +02004285 }
Willy Tarreau0c9c2722014-05-28 12:28:58 +02004286 else {
4287 update_freq_ctr(&global.ssl_fe_keys_per_sec, 1);
4288 if (global.ssl_fe_keys_per_sec.curr_ctr > global.ssl_fe_keys_max)
4289 global.ssl_fe_keys_max = global.ssl_fe_keys_per_sec.curr_ctr;
4290 }
Emeric Brun46591952012-05-18 15:47:34 +02004291 }
4292
4293 /* The connection is now established at both layers, it's time to leave */
4294 conn->flags &= ~(flag | CO_FL_WAIT_L4_CONN | CO_FL_WAIT_L6_CONN);
4295 return 1;
4296
4297 out_error:
Emeric Brun644cde02012-12-14 11:21:13 +01004298 /* Clear openssl global errors stack */
Thierry FOURNIER / OZON.IO8b068c22016-10-10 11:59:50 +02004299 ssl_sock_dump_errors(conn);
Emeric Brun644cde02012-12-14 11:21:13 +01004300 ERR_clear_error();
4301
Emeric Brun9fa89732012-10-04 17:09:56 +02004302 /* free resumed session if exists */
Willy Tarreau3fdb3662012-11-12 00:42:33 +01004303 if (objt_server(conn->target) && objt_server(conn->target)->ssl_ctx.reused_sess) {
4304 SSL_SESSION_free(objt_server(conn->target)->ssl_ctx.reused_sess);
4305 objt_server(conn->target)->ssl_ctx.reused_sess = NULL;
Emeric Brun9fa89732012-10-04 17:09:56 +02004306 }
4307
Emeric Brun46591952012-05-18 15:47:34 +02004308 /* Fail on all other handshake errors */
4309 conn->flags |= CO_FL_ERROR;
Willy Tarreau20879a02012-12-03 16:32:10 +01004310 if (!conn->err_code)
4311 conn->err_code = CO_ER_SSL_HANDSHAKE;
Emeric Brun46591952012-05-18 15:47:34 +02004312 return 0;
4313}
4314
4315/* Receive up to <count> bytes from connection <conn>'s socket and store them
Willy Tarreauabf08d92014-01-14 11:31:27 +01004316 * into buffer <buf>. Only one call to recv() is performed, unless the
Emeric Brun46591952012-05-18 15:47:34 +02004317 * buffer wraps, in which case a second call may be performed. The connection's
4318 * flags are updated with whatever special event is detected (error, read0,
4319 * empty). The caller is responsible for taking care of those events and
4320 * avoiding the call if inappropriate. The function does not call the
4321 * connection's polling update function, so the caller is responsible for this.
4322 */
4323static int ssl_sock_to_buf(struct connection *conn, struct buffer *buf, int count)
4324{
4325 int ret, done = 0;
Willy Tarreauabf08d92014-01-14 11:31:27 +01004326 int try;
Emeric Brun46591952012-05-18 15:47:34 +02004327
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02004328 if (!conn->xprt_ctx)
Emeric Brun46591952012-05-18 15:47:34 +02004329 goto out_error;
4330
4331 if (conn->flags & CO_FL_HANDSHAKE)
4332 /* a handshake was requested */
4333 return 0;
4334
Willy Tarreauabf08d92014-01-14 11:31:27 +01004335 /* let's realign the buffer to optimize I/O */
4336 if (buffer_empty(buf))
Emeric Brun46591952012-05-18 15:47:34 +02004337 buf->p = buf->data;
Emeric Brun46591952012-05-18 15:47:34 +02004338
4339 /* read the largest possible block. For this, we perform only one call
4340 * to recv() unless the buffer wraps and we exactly fill the first hunk,
4341 * in which case we accept to do it once again. A new attempt is made on
4342 * EINTR too.
4343 */
Willy Tarreau00b0fb92014-01-17 11:09:40 +01004344 while (count > 0) {
Willy Tarreauabf08d92014-01-14 11:31:27 +01004345 /* first check if we have some room after p+i */
4346 try = buf->data + buf->size - (buf->p + buf->i);
4347 /* otherwise continue between data and p-o */
4348 if (try <= 0) {
4349 try = buf->p - (buf->data + buf->o);
4350 if (try <= 0)
4351 break;
4352 }
4353 if (try > count)
4354 try = count;
4355
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02004356 ret = SSL_read(conn->xprt_ctx, bi_end(buf), try);
Emeric Brune1f38db2012-09-03 20:36:47 +02004357 if (conn->flags & CO_FL_ERROR) {
4358 /* CO_FL_ERROR may be set by ssl_sock_infocbk */
Emeric Brun644cde02012-12-14 11:21:13 +01004359 goto out_error;
Emeric Brune1f38db2012-09-03 20:36:47 +02004360 }
Emeric Brun46591952012-05-18 15:47:34 +02004361 if (ret > 0) {
4362 buf->i += ret;
4363 done += ret;
4364 if (ret < try)
4365 break;
4366 count -= ret;
Emeric Brun46591952012-05-18 15:47:34 +02004367 }
4368 else if (ret == 0) {
Emeric Brun644cde02012-12-14 11:21:13 +01004369 ret = SSL_get_error(conn->xprt_ctx, ret);
4370 if (ret != SSL_ERROR_ZERO_RETURN) {
Emeric Brun1c646862012-12-14 12:33:41 +01004371 /* error on protocol or underlying transport */
4372 if ((ret != SSL_ERROR_SYSCALL)
4373 || (errno && (errno != EAGAIN)))
4374 conn->flags |= CO_FL_ERROR;
4375
Emeric Brun644cde02012-12-14 11:21:13 +01004376 /* Clear openssl global errors stack */
Thierry FOURNIER / OZON.IO8b068c22016-10-10 11:59:50 +02004377 ssl_sock_dump_errors(conn);
Emeric Brun644cde02012-12-14 11:21:13 +01004378 ERR_clear_error();
4379 }
Emeric Brun46591952012-05-18 15:47:34 +02004380 goto read0;
4381 }
4382 else {
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02004383 ret = SSL_get_error(conn->xprt_ctx, ret);
Emeric Brun46591952012-05-18 15:47:34 +02004384 if (ret == SSL_ERROR_WANT_WRITE) {
Emeric Brun8af8dd12012-11-08 17:56:20 +01004385 /* handshake is running, and it needs to enable write */
Emeric Brun46591952012-05-18 15:47:34 +02004386 conn->flags |= CO_FL_SSL_WAIT_HS;
Emeric Brun8af8dd12012-11-08 17:56:20 +01004387 __conn_sock_want_send(conn);
Emeric Brun46591952012-05-18 15:47:34 +02004388 break;
4389 }
4390 else if (ret == SSL_ERROR_WANT_READ) {
Emeric Brun282a76a2012-11-08 18:02:56 +01004391 if (SSL_renegotiate_pending(conn->xprt_ctx)) {
4392 /* handshake is running, and it may need to re-enable read */
4393 conn->flags |= CO_FL_SSL_WAIT_HS;
4394 __conn_sock_want_recv(conn);
4395 break;
4396 }
Emeric Brun46591952012-05-18 15:47:34 +02004397 /* we need to poll for retry a read later */
Willy Tarreaue1f50c42014-01-22 20:02:06 +01004398 fd_cant_recv(conn->t.sock.fd);
Emeric Brun46591952012-05-18 15:47:34 +02004399 break;
4400 }
4401 /* otherwise it's a real error */
4402 goto out_error;
4403 }
4404 }
4405 return done;
4406
4407 read0:
4408 conn_sock_read0(conn);
4409 return done;
4410 out_error:
Emeric Brun644cde02012-12-14 11:21:13 +01004411 /* Clear openssl global errors stack */
Thierry FOURNIER / OZON.IO8b068c22016-10-10 11:59:50 +02004412 ssl_sock_dump_errors(conn);
Emeric Brun644cde02012-12-14 11:21:13 +01004413 ERR_clear_error();
4414
Emeric Brun46591952012-05-18 15:47:34 +02004415 conn->flags |= CO_FL_ERROR;
4416 return done;
4417}
4418
4419
4420/* Send all pending bytes from buffer <buf> to connection <conn>'s socket.
Willy Tarreau1049b1f2014-02-02 01:51:17 +01004421 * <flags> may contain some CO_SFL_* flags to hint the system about other
4422 * pending data for example, but this flag is ignored at the moment.
Emeric Brun46591952012-05-18 15:47:34 +02004423 * Only one call to send() is performed, unless the buffer wraps, in which case
4424 * a second call may be performed. The connection's flags are updated with
4425 * whatever special event is detected (error, empty). The caller is responsible
4426 * for taking care of those events and avoiding the call if inappropriate. The
4427 * function does not call the connection's polling update function, so the caller
4428 * is responsible for this.
4429 */
4430static int ssl_sock_from_buf(struct connection *conn, struct buffer *buf, int flags)
4431{
4432 int ret, try, done;
4433
4434 done = 0;
4435
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02004436 if (!conn->xprt_ctx)
Emeric Brun46591952012-05-18 15:47:34 +02004437 goto out_error;
4438
4439 if (conn->flags & CO_FL_HANDSHAKE)
4440 /* a handshake was requested */
4441 return 0;
4442
4443 /* send the largest possible block. For this we perform only one call
4444 * to send() unless the buffer wraps and we exactly fill the first hunk,
4445 * in which case we accept to do it once again.
4446 */
4447 while (buf->o) {
Kevin Hestercad82342013-05-30 15:12:41 -07004448 try = bo_contig_data(buf);
Willy Tarreaubfd59462013-02-21 07:46:09 +01004449
Willy Tarreau7bed9452014-02-02 02:00:24 +01004450 if (!(flags & CO_SFL_STREAMER) &&
Willy Tarreau518cedd2014-02-17 15:43:01 +01004451 !(conn->xprt_st & SSL_SOCK_SEND_UNLIMITED) &&
Willy Tarreauef934602016-12-22 23:12:01 +01004452 global_ssl.max_record && try > global_ssl.max_record) {
4453 try = global_ssl.max_record;
Willy Tarreau518cedd2014-02-17 15:43:01 +01004454 }
4455 else {
4456 /* we need to keep the information about the fact that
4457 * we're not limiting the upcoming send(), because if it
4458 * fails, we'll have to retry with at least as many data.
4459 */
4460 conn->xprt_st |= SSL_SOCK_SEND_UNLIMITED;
4461 }
Willy Tarreaubfd59462013-02-21 07:46:09 +01004462
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02004463 ret = SSL_write(conn->xprt_ctx, bo_ptr(buf), try);
Willy Tarreau518cedd2014-02-17 15:43:01 +01004464
Emeric Brune1f38db2012-09-03 20:36:47 +02004465 if (conn->flags & CO_FL_ERROR) {
4466 /* CO_FL_ERROR may be set by ssl_sock_infocbk */
Emeric Brun644cde02012-12-14 11:21:13 +01004467 goto out_error;
Emeric Brune1f38db2012-09-03 20:36:47 +02004468 }
Emeric Brun46591952012-05-18 15:47:34 +02004469 if (ret > 0) {
Willy Tarreau518cedd2014-02-17 15:43:01 +01004470 conn->xprt_st &= ~SSL_SOCK_SEND_UNLIMITED;
4471
Emeric Brun46591952012-05-18 15:47:34 +02004472 buf->o -= ret;
4473 done += ret;
4474
Willy Tarreau5fb38032012-12-16 19:39:09 +01004475 if (likely(buffer_empty(buf)))
Emeric Brun46591952012-05-18 15:47:34 +02004476 /* optimize data alignment in the buffer */
4477 buf->p = buf->data;
4478
4479 /* if the system buffer is full, don't insist */
4480 if (ret < try)
4481 break;
4482 }
4483 else {
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02004484 ret = SSL_get_error(conn->xprt_ctx, ret);
Emeric Brun46591952012-05-18 15:47:34 +02004485 if (ret == SSL_ERROR_WANT_WRITE) {
Emeric Brun282a76a2012-11-08 18:02:56 +01004486 if (SSL_renegotiate_pending(conn->xprt_ctx)) {
4487 /* handshake is running, and it may need to re-enable write */
4488 conn->flags |= CO_FL_SSL_WAIT_HS;
4489 __conn_sock_want_send(conn);
4490 break;
4491 }
Emeric Brun46591952012-05-18 15:47:34 +02004492 /* we need to poll to retry a write later */
Willy Tarreaue1f50c42014-01-22 20:02:06 +01004493 fd_cant_send(conn->t.sock.fd);
Emeric Brun46591952012-05-18 15:47:34 +02004494 break;
4495 }
4496 else if (ret == SSL_ERROR_WANT_READ) {
Emeric Brun8af8dd12012-11-08 17:56:20 +01004497 /* handshake is running, and it needs to enable read */
Emeric Brun46591952012-05-18 15:47:34 +02004498 conn->flags |= CO_FL_SSL_WAIT_HS;
Emeric Brun8af8dd12012-11-08 17:56:20 +01004499 __conn_sock_want_recv(conn);
Emeric Brun46591952012-05-18 15:47:34 +02004500 break;
4501 }
4502 goto out_error;
4503 }
4504 }
4505 return done;
4506
4507 out_error:
Emeric Brun644cde02012-12-14 11:21:13 +01004508 /* Clear openssl global errors stack */
Thierry FOURNIER / OZON.IO8b068c22016-10-10 11:59:50 +02004509 ssl_sock_dump_errors(conn);
Emeric Brun644cde02012-12-14 11:21:13 +01004510 ERR_clear_error();
4511
Emeric Brun46591952012-05-18 15:47:34 +02004512 conn->flags |= CO_FL_ERROR;
4513 return done;
4514}
4515
Emeric Brun46591952012-05-18 15:47:34 +02004516static void ssl_sock_close(struct connection *conn) {
4517
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02004518 if (conn->xprt_ctx) {
4519 SSL_free(conn->xprt_ctx);
4520 conn->xprt_ctx = NULL;
Willy Tarreau403edff2012-09-06 11:58:37 +02004521 sslconns--;
Emeric Brun46591952012-05-18 15:47:34 +02004522 }
Emeric Brun46591952012-05-18 15:47:34 +02004523}
4524
4525/* This function tries to perform a clean shutdown on an SSL connection, and in
4526 * any case, flags the connection as reusable if no handshake was in progress.
4527 */
4528static void ssl_sock_shutw(struct connection *conn, int clean)
4529{
4530 if (conn->flags & CO_FL_HANDSHAKE)
4531 return;
Emmanuel Hocdet405ff312017-01-08 14:07:39 +01004532 if (!clean)
4533 /* don't sent notify on SSL_shutdown */
Willy Tarreaue3cc3a32017-02-13 11:12:29 +01004534 SSL_set_quiet_shutdown(conn->xprt_ctx, 1);
Emeric Brun46591952012-05-18 15:47:34 +02004535 /* no handshake was in progress, try a clean ssl shutdown */
Emmanuel Hocdet405ff312017-01-08 14:07:39 +01004536 if (SSL_shutdown(conn->xprt_ctx) <= 0) {
Emeric Brun644cde02012-12-14 11:21:13 +01004537 /* Clear openssl global errors stack */
Thierry FOURNIER / OZON.IO8b068c22016-10-10 11:59:50 +02004538 ssl_sock_dump_errors(conn);
Emeric Brun644cde02012-12-14 11:21:13 +01004539 ERR_clear_error();
4540 }
Emeric Brun46591952012-05-18 15:47:34 +02004541}
4542
Willy Tarreauffc3fcd2012-10-12 20:17:54 +02004543/* used for logging, may be changed for a sample fetch later */
4544const char *ssl_sock_get_cipher_name(struct connection *conn)
4545{
4546 if (!conn->xprt && !conn->xprt_ctx)
4547 return NULL;
4548 return SSL_get_cipher_name(conn->xprt_ctx);
4549}
4550
4551/* used for logging, may be changed for a sample fetch later */
4552const char *ssl_sock_get_proto_version(struct connection *conn)
4553{
4554 if (!conn->xprt && !conn->xprt_ctx)
4555 return NULL;
4556 return SSL_get_version(conn->xprt_ctx);
4557}
4558
Willy Tarreau8d598402012-10-22 17:58:39 +02004559/* Extract a serial from a cert, and copy it to a chunk.
4560 * Returns 1 if serial is found and copied, 0 if no serial found and
4561 * -1 if output is not large enough.
4562 */
4563static int
4564ssl_sock_get_serial(X509 *crt, struct chunk *out)
4565{
4566 ASN1_INTEGER *serial;
4567
4568 serial = X509_get_serialNumber(crt);
4569 if (!serial)
4570 return 0;
4571
4572 if (out->size < serial->length)
4573 return -1;
4574
4575 memcpy(out->str, serial->data, serial->length);
4576 out->len = serial->length;
4577 return 1;
4578}
4579
Emeric Brun43e79582014-10-29 19:03:26 +01004580/* Extract a cert to der, and copy it to a chunk.
4581 * Returns 1 if cert is found and copied, 0 on der convertion failure and
4582 * -1 if output is not large enough.
4583 */
4584static int
4585ssl_sock_crt2der(X509 *crt, struct chunk *out)
4586{
4587 int len;
4588 unsigned char *p = (unsigned char *)out->str;;
4589
4590 len =i2d_X509(crt, NULL);
4591 if (len <= 0)
4592 return 1;
4593
4594 if (out->size < len)
4595 return -1;
4596
4597 i2d_X509(crt,&p);
4598 out->len = len;
4599 return 1;
4600}
4601
Emeric Brunce5ad802012-10-22 14:11:22 +02004602
4603/* Copy Date in ASN1_UTCTIME format in struct chunk out.
4604 * Returns 1 if serial is found and copied, 0 if no valid time found
4605 * and -1 if output is not large enough.
4606 */
4607static int
4608ssl_sock_get_time(ASN1_TIME *tm, struct chunk *out)
4609{
4610 if (tm->type == V_ASN1_GENERALIZEDTIME) {
4611 ASN1_GENERALIZEDTIME *gentm = (ASN1_GENERALIZEDTIME *)tm;
4612
4613 if (gentm->length < 12)
4614 return 0;
4615 if (gentm->data[0] != 0x32 || gentm->data[1] != 0x30)
4616 return 0;
4617 if (out->size < gentm->length-2)
4618 return -1;
4619
4620 memcpy(out->str, gentm->data+2, gentm->length-2);
4621 out->len = gentm->length-2;
4622 return 1;
4623 }
4624 else if (tm->type == V_ASN1_UTCTIME) {
4625 ASN1_UTCTIME *utctm = (ASN1_UTCTIME *)tm;
4626
4627 if (utctm->length < 10)
4628 return 0;
4629 if (utctm->data[0] >= 0x35)
4630 return 0;
4631 if (out->size < utctm->length)
4632 return -1;
4633
4634 memcpy(out->str, utctm->data, utctm->length);
4635 out->len = utctm->length;
4636 return 1;
4637 }
4638
4639 return 0;
4640}
4641
Emeric Brun87855892012-10-17 17:39:35 +02004642/* Extract an entry from a X509_NAME and copy its value to an output chunk.
4643 * Returns 1 if entry found, 0 if entry not found, or -1 if output not large enough.
4644 */
4645static int
4646ssl_sock_get_dn_entry(X509_NAME *a, const struct chunk *entry, int pos, struct chunk *out)
4647{
4648 X509_NAME_ENTRY *ne;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004649 ASN1_OBJECT *obj;
4650 ASN1_STRING *data;
4651 const unsigned char *data_ptr;
4652 int data_len;
Emeric Brun87855892012-10-17 17:39:35 +02004653 int i, j, n;
4654 int cur = 0;
4655 const char *s;
4656 char tmp[128];
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004657 int name_count;
4658
4659 name_count = X509_NAME_entry_count(a);
Emeric Brun87855892012-10-17 17:39:35 +02004660
4661 out->len = 0;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004662 for (i = 0; i < name_count; i++) {
Emeric Brun87855892012-10-17 17:39:35 +02004663 if (pos < 0)
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004664 j = (name_count-1) - i;
Emeric Brun87855892012-10-17 17:39:35 +02004665 else
4666 j = i;
4667
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004668 ne = X509_NAME_get_entry(a, j);
4669 obj = X509_NAME_ENTRY_get_object(ne);
4670 data = X509_NAME_ENTRY_get_data(ne);
4671 data_ptr = ASN1_STRING_get0_data(data);
4672 data_len = ASN1_STRING_length(data);
4673 n = OBJ_obj2nid(obj);
Emeric Brun87855892012-10-17 17:39:35 +02004674 if ((n == NID_undef) || ((s = OBJ_nid2sn(n)) == NULL)) {
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004675 i2t_ASN1_OBJECT(tmp, sizeof(tmp), obj);
Emeric Brun87855892012-10-17 17:39:35 +02004676 s = tmp;
4677 }
4678
4679 if (chunk_strcasecmp(entry, s) != 0)
4680 continue;
4681
4682 if (pos < 0)
4683 cur--;
4684 else
4685 cur++;
4686
4687 if (cur != pos)
4688 continue;
4689
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004690 if (data_len > out->size)
Emeric Brun87855892012-10-17 17:39:35 +02004691 return -1;
4692
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004693 memcpy(out->str, data_ptr, data_len);
4694 out->len = data_len;
Emeric Brun87855892012-10-17 17:39:35 +02004695 return 1;
4696 }
4697
4698 return 0;
4699
4700}
4701
4702/* Extract and format full DN from a X509_NAME and copy result into a chunk
4703 * Returns 1 if dn entries exits, 0 if no dn entry found or -1 if output is not large enough.
4704 */
4705static int
4706ssl_sock_get_dn_oneline(X509_NAME *a, struct chunk *out)
4707{
4708 X509_NAME_ENTRY *ne;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004709 ASN1_OBJECT *obj;
4710 ASN1_STRING *data;
4711 const unsigned char *data_ptr;
4712 int data_len;
Emeric Brun87855892012-10-17 17:39:35 +02004713 int i, n, ln;
4714 int l = 0;
4715 const char *s;
4716 char *p;
4717 char tmp[128];
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004718 int name_count;
4719
4720
4721 name_count = X509_NAME_entry_count(a);
Emeric Brun87855892012-10-17 17:39:35 +02004722
4723 out->len = 0;
4724 p = out->str;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004725 for (i = 0; i < name_count; i++) {
4726 ne = X509_NAME_get_entry(a, i);
4727 obj = X509_NAME_ENTRY_get_object(ne);
4728 data = X509_NAME_ENTRY_get_data(ne);
4729 data_ptr = ASN1_STRING_get0_data(data);
4730 data_len = ASN1_STRING_length(data);
4731 n = OBJ_obj2nid(obj);
Emeric Brun87855892012-10-17 17:39:35 +02004732 if ((n == NID_undef) || ((s = OBJ_nid2sn(n)) == NULL)) {
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004733 i2t_ASN1_OBJECT(tmp, sizeof(tmp), obj);
Emeric Brun87855892012-10-17 17:39:35 +02004734 s = tmp;
4735 }
4736 ln = strlen(s);
4737
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004738 l += 1 + ln + 1 + data_len;
Emeric Brun87855892012-10-17 17:39:35 +02004739 if (l > out->size)
4740 return -1;
4741 out->len = l;
4742
4743 *(p++)='/';
4744 memcpy(p, s, ln);
4745 p += ln;
4746 *(p++)='=';
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004747 memcpy(p, data_ptr, data_len);
4748 p += data_len;
Emeric Brun87855892012-10-17 17:39:35 +02004749 }
4750
4751 if (!out->len)
4752 return 0;
4753
4754 return 1;
4755}
4756
David Safb76832014-05-08 23:42:08 -04004757char *ssl_sock_get_version(struct connection *conn)
4758{
4759 if (!ssl_sock_is_ssl(conn))
4760 return NULL;
4761
4762 return (char *)SSL_get_version(conn->xprt_ctx);
4763}
4764
Willy Tarreau119a4082016-12-22 21:58:38 +01004765/* Sets advertised SNI for outgoing connections. Please set <hostname> to NULL
4766 * to disable SNI.
4767 */
Willy Tarreau63076412015-07-10 11:33:32 +02004768void ssl_sock_set_servername(struct connection *conn, const char *hostname)
4769{
4770#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Willy Tarreau119a4082016-12-22 21:58:38 +01004771 char *prev_name;
4772
Willy Tarreau63076412015-07-10 11:33:32 +02004773 if (!ssl_sock_is_ssl(conn))
4774 return;
4775
Willy Tarreau119a4082016-12-22 21:58:38 +01004776 /* if the SNI changes, we must destroy the reusable context so that a
4777 * new connection will present a new SNI. As an optimization we could
4778 * later imagine having a small cache of ssl_ctx to hold a few SNI per
4779 * server.
4780 */
4781 prev_name = (char *)SSL_get_servername(conn->xprt_ctx, TLSEXT_NAMETYPE_host_name);
4782 if ((!prev_name && hostname) ||
4783 (prev_name && (!hostname || strcmp(hostname, prev_name) != 0)))
4784 SSL_set_session(conn->xprt_ctx, NULL);
4785
Willy Tarreau63076412015-07-10 11:33:32 +02004786 SSL_set_tlsext_host_name(conn->xprt_ctx, hostname);
4787#endif
4788}
4789
Emeric Brun0abf8362014-06-24 18:26:41 +02004790/* Extract peer certificate's common name into the chunk dest
4791 * Returns
4792 * the len of the extracted common name
4793 * or 0 if no CN found in DN
4794 * or -1 on error case (i.e. no peer certificate)
4795 */
4796int ssl_sock_get_remote_common_name(struct connection *conn, struct chunk *dest)
David Safb76832014-05-08 23:42:08 -04004797{
4798 X509 *crt = NULL;
4799 X509_NAME *name;
David Safb76832014-05-08 23:42:08 -04004800 const char find_cn[] = "CN";
4801 const struct chunk find_cn_chunk = {
4802 .str = (char *)&find_cn,
4803 .len = sizeof(find_cn)-1
4804 };
Emeric Brun0abf8362014-06-24 18:26:41 +02004805 int result = -1;
David Safb76832014-05-08 23:42:08 -04004806
4807 if (!ssl_sock_is_ssl(conn))
Emeric Brun0abf8362014-06-24 18:26:41 +02004808 goto out;
David Safb76832014-05-08 23:42:08 -04004809
4810 /* SSL_get_peer_certificate, it increase X509 * ref count */
4811 crt = SSL_get_peer_certificate(conn->xprt_ctx);
4812 if (!crt)
4813 goto out;
4814
4815 name = X509_get_subject_name(crt);
4816 if (!name)
4817 goto out;
David Safb76832014-05-08 23:42:08 -04004818
Emeric Brun0abf8362014-06-24 18:26:41 +02004819 result = ssl_sock_get_dn_entry(name, &find_cn_chunk, 1, dest);
4820out:
David Safb76832014-05-08 23:42:08 -04004821 if (crt)
4822 X509_free(crt);
4823
4824 return result;
4825}
4826
Dave McCowan328fb582014-07-30 10:39:13 -04004827/* returns 1 if client passed a certificate for this session, 0 if not */
4828int ssl_sock_get_cert_used_sess(struct connection *conn)
4829{
4830 X509 *crt = NULL;
4831
4832 if (!ssl_sock_is_ssl(conn))
4833 return 0;
4834
4835 /* SSL_get_peer_certificate, it increase X509 * ref count */
4836 crt = SSL_get_peer_certificate(conn->xprt_ctx);
4837 if (!crt)
4838 return 0;
4839
4840 X509_free(crt);
4841 return 1;
4842}
4843
4844/* returns 1 if client passed a certificate for this connection, 0 if not */
4845int ssl_sock_get_cert_used_conn(struct connection *conn)
David Safb76832014-05-08 23:42:08 -04004846{
4847 if (!ssl_sock_is_ssl(conn))
4848 return 0;
4849
4850 return SSL_SOCK_ST_FL_VERIFY_DONE & conn->xprt_st ? 1 : 0;
4851}
4852
4853/* returns result from SSL verify */
4854unsigned int ssl_sock_get_verify_result(struct connection *conn)
4855{
4856 if (!ssl_sock_is_ssl(conn))
4857 return (unsigned int)X509_V_ERR_APPLICATION_VERIFICATION;
4858
4859 return (unsigned int)SSL_get_verify_result(conn->xprt_ctx);
4860}
4861
Willy Tarreau7875d092012-09-10 08:20:03 +02004862/***** Below are some sample fetching functions for ACL/patterns *****/
4863
Emeric Brune64aef12012-09-21 13:15:06 +02004864/* boolean, returns true if client cert was present */
4865static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004866smp_fetch_ssl_fc_has_crt(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brune64aef12012-09-21 13:15:06 +02004867{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004868 struct connection *conn;
4869
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004870 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004871 if (!conn || conn->xprt != &ssl_sock)
Emeric Brune64aef12012-09-21 13:15:06 +02004872 return 0;
4873
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004874 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brune64aef12012-09-21 13:15:06 +02004875 smp->flags |= SMP_F_MAY_CHANGE;
4876 return 0;
4877 }
4878
4879 smp->flags = 0;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004880 smp->data.type = SMP_T_BOOL;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004881 smp->data.u.sint = SSL_SOCK_ST_FL_VERIFY_DONE & conn->xprt_st ? 1 : 0;
Emeric Brune64aef12012-09-21 13:15:06 +02004882
4883 return 1;
4884}
4885
Emeric Brun43e79582014-10-29 19:03:26 +01004886/* binary, returns a certificate in a binary chunk (der/raw).
4887 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
4888 * should be use.
4889 */
4890static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004891smp_fetch_ssl_x_der(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun43e79582014-10-29 19:03:26 +01004892{
4893 int cert_peer = (kw[4] == 'c') ? 1 : 0;
4894 X509 *crt = NULL;
4895 int ret = 0;
4896 struct chunk *smp_trash;
4897 struct connection *conn;
4898
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004899 conn = objt_conn(smp->sess->origin);
Emeric Brun43e79582014-10-29 19:03:26 +01004900 if (!conn || conn->xprt != &ssl_sock)
4901 return 0;
4902
4903 if (!(conn->flags & CO_FL_CONNECTED)) {
4904 smp->flags |= SMP_F_MAY_CHANGE;
4905 return 0;
4906 }
4907
4908 if (cert_peer)
4909 crt = SSL_get_peer_certificate(conn->xprt_ctx);
4910 else
4911 crt = SSL_get_certificate(conn->xprt_ctx);
4912
4913 if (!crt)
4914 goto out;
4915
4916 smp_trash = get_trash_chunk();
4917 if (ssl_sock_crt2der(crt, smp_trash) <= 0)
4918 goto out;
4919
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004920 smp->data.u.str = *smp_trash;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004921 smp->data.type = SMP_T_BIN;
Emeric Brun43e79582014-10-29 19:03:26 +01004922 ret = 1;
4923out:
4924 /* SSL_get_peer_certificate, it increase X509 * ref count */
4925 if (cert_peer && crt)
4926 X509_free(crt);
4927 return ret;
4928}
4929
Emeric Brunba841a12014-04-30 17:05:08 +02004930/* binary, returns serial of certificate in a binary chunk.
4931 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
4932 * should be use.
4933 */
Willy Tarreau8d598402012-10-22 17:58:39 +02004934static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004935smp_fetch_ssl_x_serial(const struct arg *args, struct sample *smp, const char *kw, void *private)
Willy Tarreau8d598402012-10-22 17:58:39 +02004936{
Emeric Brunba841a12014-04-30 17:05:08 +02004937 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Willy Tarreau8d598402012-10-22 17:58:39 +02004938 X509 *crt = NULL;
4939 int ret = 0;
4940 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004941 struct connection *conn;
4942
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004943 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004944 if (!conn || conn->xprt != &ssl_sock)
Willy Tarreau8d598402012-10-22 17:58:39 +02004945 return 0;
4946
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004947 if (!(conn->flags & CO_FL_CONNECTED)) {
Willy Tarreau8d598402012-10-22 17:58:39 +02004948 smp->flags |= SMP_F_MAY_CHANGE;
4949 return 0;
4950 }
4951
Emeric Brunba841a12014-04-30 17:05:08 +02004952 if (cert_peer)
4953 crt = SSL_get_peer_certificate(conn->xprt_ctx);
4954 else
4955 crt = SSL_get_certificate(conn->xprt_ctx);
4956
Willy Tarreau8d598402012-10-22 17:58:39 +02004957 if (!crt)
4958 goto out;
4959
Willy Tarreau47ca5452012-12-23 20:22:19 +01004960 smp_trash = get_trash_chunk();
Willy Tarreau8d598402012-10-22 17:58:39 +02004961 if (ssl_sock_get_serial(crt, smp_trash) <= 0)
4962 goto out;
4963
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004964 smp->data.u.str = *smp_trash;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004965 smp->data.type = SMP_T_BIN;
Willy Tarreau8d598402012-10-22 17:58:39 +02004966 ret = 1;
4967out:
Emeric Brunba841a12014-04-30 17:05:08 +02004968 /* SSL_get_peer_certificate, it increase X509 * ref count */
4969 if (cert_peer && crt)
Willy Tarreau8d598402012-10-22 17:58:39 +02004970 X509_free(crt);
4971 return ret;
4972}
Emeric Brune64aef12012-09-21 13:15:06 +02004973
Emeric Brunba841a12014-04-30 17:05:08 +02004974/* binary, returns the client certificate's SHA-1 fingerprint (SHA-1 hash of DER-encoded certificate) in a binary chunk.
4975 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
4976 * should be use.
4977 */
James Votha051b4a2013-05-14 20:37:59 +02004978static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004979smp_fetch_ssl_x_sha1(const struct arg *args, struct sample *smp, const char *kw, void *private)
James Votha051b4a2013-05-14 20:37:59 +02004980{
Emeric Brunba841a12014-04-30 17:05:08 +02004981 int cert_peer = (kw[4] == 'c') ? 1 : 0;
James Votha051b4a2013-05-14 20:37:59 +02004982 X509 *crt = NULL;
4983 const EVP_MD *digest;
4984 int ret = 0;
4985 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004986 struct connection *conn;
James Votha051b4a2013-05-14 20:37:59 +02004987
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004988 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004989 if (!conn || conn->xprt != &ssl_sock)
4990 return 0;
4991
4992 if (!(conn->flags & CO_FL_CONNECTED)) {
James Votha051b4a2013-05-14 20:37:59 +02004993 smp->flags |= SMP_F_MAY_CHANGE;
4994 return 0;
4995 }
4996
Emeric Brunba841a12014-04-30 17:05:08 +02004997 if (cert_peer)
4998 crt = SSL_get_peer_certificate(conn->xprt_ctx);
4999 else
5000 crt = SSL_get_certificate(conn->xprt_ctx);
James Votha051b4a2013-05-14 20:37:59 +02005001 if (!crt)
5002 goto out;
5003
5004 smp_trash = get_trash_chunk();
5005 digest = EVP_sha1();
5006 X509_digest(crt, digest, (unsigned char *)smp_trash->str, (unsigned int *)&smp_trash->len);
5007
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005008 smp->data.u.str = *smp_trash;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005009 smp->data.type = SMP_T_BIN;
James Votha051b4a2013-05-14 20:37:59 +02005010 ret = 1;
5011out:
Emeric Brunba841a12014-04-30 17:05:08 +02005012 /* SSL_get_peer_certificate, it increase X509 * ref count */
5013 if (cert_peer && crt)
James Votha051b4a2013-05-14 20:37:59 +02005014 X509_free(crt);
5015 return ret;
5016}
5017
Emeric Brunba841a12014-04-30 17:05:08 +02005018/* string, returns certificate's notafter date in ASN1_UTCTIME format.
5019 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
5020 * should be use.
5021 */
Emeric Brunce5ad802012-10-22 14:11:22 +02005022static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005023smp_fetch_ssl_x_notafter(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brunce5ad802012-10-22 14:11:22 +02005024{
Emeric Brunba841a12014-04-30 17:05:08 +02005025 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brunce5ad802012-10-22 14:11:22 +02005026 X509 *crt = NULL;
5027 int ret = 0;
5028 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005029 struct connection *conn;
Emeric Brunce5ad802012-10-22 14:11:22 +02005030
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02005031 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005032 if (!conn || conn->xprt != &ssl_sock)
5033 return 0;
5034
5035 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunce5ad802012-10-22 14:11:22 +02005036 smp->flags |= SMP_F_MAY_CHANGE;
5037 return 0;
5038 }
5039
Emeric Brunba841a12014-04-30 17:05:08 +02005040 if (cert_peer)
5041 crt = SSL_get_peer_certificate(conn->xprt_ctx);
5042 else
5043 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brunce5ad802012-10-22 14:11:22 +02005044 if (!crt)
5045 goto out;
5046
Willy Tarreau47ca5452012-12-23 20:22:19 +01005047 smp_trash = get_trash_chunk();
Emeric Brunce5ad802012-10-22 14:11:22 +02005048 if (ssl_sock_get_time(X509_get_notAfter(crt), smp_trash) <= 0)
5049 goto out;
5050
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005051 smp->data.u.str = *smp_trash;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005052 smp->data.type = SMP_T_STR;
Emeric Brunce5ad802012-10-22 14:11:22 +02005053 ret = 1;
5054out:
Emeric Brunba841a12014-04-30 17:05:08 +02005055 /* SSL_get_peer_certificate, it increase X509 * ref count */
5056 if (cert_peer && crt)
Emeric Brunce5ad802012-10-22 14:11:22 +02005057 X509_free(crt);
5058 return ret;
5059}
5060
Emeric Brunba841a12014-04-30 17:05:08 +02005061/* string, returns a string of a formatted full dn \C=..\O=..\OU=.. \CN=.. of certificate's issuer
5062 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
5063 * should be use.
5064 */
Emeric Brun87855892012-10-17 17:39:35 +02005065static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005066smp_fetch_ssl_x_i_dn(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun87855892012-10-17 17:39:35 +02005067{
Emeric Brunba841a12014-04-30 17:05:08 +02005068 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brun87855892012-10-17 17:39:35 +02005069 X509 *crt = NULL;
5070 X509_NAME *name;
5071 int ret = 0;
5072 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005073 struct connection *conn;
Emeric Brun87855892012-10-17 17:39:35 +02005074
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02005075 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005076 if (!conn || conn->xprt != &ssl_sock)
5077 return 0;
5078
5079 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun87855892012-10-17 17:39:35 +02005080 smp->flags |= SMP_F_MAY_CHANGE;
5081 return 0;
5082 }
5083
Emeric Brunba841a12014-04-30 17:05:08 +02005084 if (cert_peer)
5085 crt = SSL_get_peer_certificate(conn->xprt_ctx);
5086 else
5087 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brun87855892012-10-17 17:39:35 +02005088 if (!crt)
5089 goto out;
5090
5091 name = X509_get_issuer_name(crt);
5092 if (!name)
5093 goto out;
5094
Willy Tarreau47ca5452012-12-23 20:22:19 +01005095 smp_trash = get_trash_chunk();
Emeric Brun87855892012-10-17 17:39:35 +02005096 if (args && args[0].type == ARGT_STR) {
5097 int pos = 1;
5098
5099 if (args[1].type == ARGT_SINT)
5100 pos = args[1].data.sint;
Emeric Brun87855892012-10-17 17:39:35 +02005101
5102 if (ssl_sock_get_dn_entry(name, &args[0].data.str, pos, smp_trash) <= 0)
5103 goto out;
5104 }
5105 else if (ssl_sock_get_dn_oneline(name, smp_trash) <= 0)
5106 goto out;
5107
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005108 smp->data.type = SMP_T_STR;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005109 smp->data.u.str = *smp_trash;
Emeric Brun87855892012-10-17 17:39:35 +02005110 ret = 1;
5111out:
Emeric Brunba841a12014-04-30 17:05:08 +02005112 /* SSL_get_peer_certificate, it increase X509 * ref count */
5113 if (cert_peer && crt)
Emeric Brun87855892012-10-17 17:39:35 +02005114 X509_free(crt);
5115 return ret;
5116}
5117
Emeric Brunba841a12014-04-30 17:05:08 +02005118/* string, returns notbefore date in ASN1_UTCTIME format.
5119 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
5120 * should be use.
5121 */
Emeric Brunce5ad802012-10-22 14:11:22 +02005122static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005123smp_fetch_ssl_x_notbefore(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brunce5ad802012-10-22 14:11:22 +02005124{
Emeric Brunba841a12014-04-30 17:05:08 +02005125 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brunce5ad802012-10-22 14:11:22 +02005126 X509 *crt = NULL;
5127 int ret = 0;
5128 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005129 struct connection *conn;
5130
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02005131 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005132 if (!conn || conn->xprt != &ssl_sock)
Emeric Brunce5ad802012-10-22 14:11:22 +02005133 return 0;
5134
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005135 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunce5ad802012-10-22 14:11:22 +02005136 smp->flags |= SMP_F_MAY_CHANGE;
5137 return 0;
5138 }
5139
Emeric Brunba841a12014-04-30 17:05:08 +02005140 if (cert_peer)
5141 crt = SSL_get_peer_certificate(conn->xprt_ctx);
5142 else
5143 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brunce5ad802012-10-22 14:11:22 +02005144 if (!crt)
5145 goto out;
5146
Willy Tarreau47ca5452012-12-23 20:22:19 +01005147 smp_trash = get_trash_chunk();
Emeric Brunce5ad802012-10-22 14:11:22 +02005148 if (ssl_sock_get_time(X509_get_notBefore(crt), smp_trash) <= 0)
5149 goto out;
5150
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005151 smp->data.u.str = *smp_trash;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005152 smp->data.type = SMP_T_STR;
Emeric Brunce5ad802012-10-22 14:11:22 +02005153 ret = 1;
5154out:
Emeric Brunba841a12014-04-30 17:05:08 +02005155 /* SSL_get_peer_certificate, it increase X509 * ref count */
5156 if (cert_peer && crt)
Emeric Brunce5ad802012-10-22 14:11:22 +02005157 X509_free(crt);
5158 return ret;
5159}
5160
Emeric Brunba841a12014-04-30 17:05:08 +02005161/* string, returns a string of a formatted full dn \C=..\O=..\OU=.. \CN=.. of certificate's subject
5162 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
5163 * should be use.
5164 */
Emeric Brun87855892012-10-17 17:39:35 +02005165static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005166smp_fetch_ssl_x_s_dn(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun87855892012-10-17 17:39:35 +02005167{
Emeric Brunba841a12014-04-30 17:05:08 +02005168 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brun87855892012-10-17 17:39:35 +02005169 X509 *crt = NULL;
5170 X509_NAME *name;
5171 int ret = 0;
5172 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005173 struct connection *conn;
Emeric Brun87855892012-10-17 17:39:35 +02005174
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02005175 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005176 if (!conn || conn->xprt != &ssl_sock)
5177 return 0;
5178
5179 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun87855892012-10-17 17:39:35 +02005180 smp->flags |= SMP_F_MAY_CHANGE;
5181 return 0;
5182 }
5183
Emeric Brunba841a12014-04-30 17:05:08 +02005184 if (cert_peer)
5185 crt = SSL_get_peer_certificate(conn->xprt_ctx);
5186 else
5187 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brun87855892012-10-17 17:39:35 +02005188 if (!crt)
5189 goto out;
5190
5191 name = X509_get_subject_name(crt);
5192 if (!name)
5193 goto out;
5194
Willy Tarreau47ca5452012-12-23 20:22:19 +01005195 smp_trash = get_trash_chunk();
Emeric Brun87855892012-10-17 17:39:35 +02005196 if (args && args[0].type == ARGT_STR) {
5197 int pos = 1;
5198
5199 if (args[1].type == ARGT_SINT)
5200 pos = args[1].data.sint;
Emeric Brun87855892012-10-17 17:39:35 +02005201
5202 if (ssl_sock_get_dn_entry(name, &args[0].data.str, pos, smp_trash) <= 0)
5203 goto out;
5204 }
5205 else if (ssl_sock_get_dn_oneline(name, smp_trash) <= 0)
5206 goto out;
5207
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005208 smp->data.type = SMP_T_STR;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005209 smp->data.u.str = *smp_trash;
Emeric Brun87855892012-10-17 17:39:35 +02005210 ret = 1;
5211out:
Emeric Brunba841a12014-04-30 17:05:08 +02005212 /* SSL_get_peer_certificate, it increase X509 * ref count */
5213 if (cert_peer && crt)
Emeric Brun87855892012-10-17 17:39:35 +02005214 X509_free(crt);
5215 return ret;
5216}
Emeric Brun9143d372012-12-20 15:44:16 +01005217
5218/* integer, returns true if current session use a client certificate */
5219static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005220smp_fetch_ssl_c_used(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun9143d372012-12-20 15:44:16 +01005221{
5222 X509 *crt;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005223 struct connection *conn;
Emeric Brun9143d372012-12-20 15:44:16 +01005224
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02005225 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005226 if (!conn || conn->xprt != &ssl_sock)
5227 return 0;
5228
5229 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun9143d372012-12-20 15:44:16 +01005230 smp->flags |= SMP_F_MAY_CHANGE;
5231 return 0;
5232 }
5233
5234 /* SSL_get_peer_certificate returns a ptr on allocated X509 struct */
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005235 crt = SSL_get_peer_certificate(conn->xprt_ctx);
Emeric Brun9143d372012-12-20 15:44:16 +01005236 if (crt) {
5237 X509_free(crt);
5238 }
5239
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005240 smp->data.type = SMP_T_BOOL;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005241 smp->data.u.sint = (crt != NULL);
Emeric Brun9143d372012-12-20 15:44:16 +01005242 return 1;
5243}
5244
Emeric Brunba841a12014-04-30 17:05:08 +02005245/* integer, returns the certificate version
5246 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
5247 * should be use.
5248 */
Emeric Bruna7359fd2012-10-17 15:03:11 +02005249static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005250smp_fetch_ssl_x_version(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Bruna7359fd2012-10-17 15:03:11 +02005251{
Emeric Brunba841a12014-04-30 17:05:08 +02005252 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Bruna7359fd2012-10-17 15:03:11 +02005253 X509 *crt;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005254 struct connection *conn;
5255
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02005256 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005257 if (!conn || conn->xprt != &ssl_sock)
Emeric Bruna7359fd2012-10-17 15:03:11 +02005258 return 0;
5259
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005260 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Bruna7359fd2012-10-17 15:03:11 +02005261 smp->flags |= SMP_F_MAY_CHANGE;
5262 return 0;
5263 }
5264
Emeric Brunba841a12014-04-30 17:05:08 +02005265 if (cert_peer)
5266 crt = SSL_get_peer_certificate(conn->xprt_ctx);
5267 else
5268 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Bruna7359fd2012-10-17 15:03:11 +02005269 if (!crt)
5270 return 0;
5271
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005272 smp->data.u.sint = (unsigned int)(1 + X509_get_version(crt));
Emeric Brunba841a12014-04-30 17:05:08 +02005273 /* SSL_get_peer_certificate increase X509 * ref count */
5274 if (cert_peer)
5275 X509_free(crt);
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005276 smp->data.type = SMP_T_SINT;
Emeric Bruna7359fd2012-10-17 15:03:11 +02005277
5278 return 1;
5279}
5280
Emeric Brunba841a12014-04-30 17:05:08 +02005281/* string, returns the certificate's signature algorithm.
5282 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
5283 * should be use.
5284 */
Emeric Brun7f56e742012-10-19 18:15:40 +02005285static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005286smp_fetch_ssl_x_sig_alg(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun7f56e742012-10-19 18:15:40 +02005287{
Emeric Brunba841a12014-04-30 17:05:08 +02005288 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brun7f56e742012-10-19 18:15:40 +02005289 X509 *crt;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02005290 __OPENSSL_110_CONST__ ASN1_OBJECT *algorithm;
Emeric Brun7f56e742012-10-19 18:15:40 +02005291 int nid;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005292 struct connection *conn;
Emeric Brun7f56e742012-10-19 18:15:40 +02005293
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02005294 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005295 if (!conn || conn->xprt != &ssl_sock)
5296 return 0;
5297
5298 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun7f56e742012-10-19 18:15:40 +02005299 smp->flags |= SMP_F_MAY_CHANGE;
5300 return 0;
5301 }
5302
Emeric Brunba841a12014-04-30 17:05:08 +02005303 if (cert_peer)
5304 crt = SSL_get_peer_certificate(conn->xprt_ctx);
5305 else
5306 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brun7f56e742012-10-19 18:15:40 +02005307 if (!crt)
5308 return 0;
5309
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02005310 X509_ALGOR_get0(&algorithm, NULL, NULL, X509_get0_tbs_sigalg(crt));
5311 nid = OBJ_obj2nid(algorithm);
Emeric Brun7f56e742012-10-19 18:15:40 +02005312
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005313 smp->data.u.str.str = (char *)OBJ_nid2sn(nid);
5314 if (!smp->data.u.str.str) {
Emeric Brunba841a12014-04-30 17:05:08 +02005315 /* SSL_get_peer_certificate increase X509 * ref count */
5316 if (cert_peer)
5317 X509_free(crt);
Emeric Brun7f56e742012-10-19 18:15:40 +02005318 return 0;
Emeric Brun9bf3ba22013-10-07 14:31:44 +02005319 }
Emeric Brun7f56e742012-10-19 18:15:40 +02005320
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005321 smp->data.type = SMP_T_STR;
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01005322 smp->flags |= SMP_F_CONST;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005323 smp->data.u.str.len = strlen(smp->data.u.str.str);
Emeric Brunba841a12014-04-30 17:05:08 +02005324 /* SSL_get_peer_certificate increase X509 * ref count */
5325 if (cert_peer)
5326 X509_free(crt);
Emeric Brun7f56e742012-10-19 18:15:40 +02005327
5328 return 1;
5329}
5330
Emeric Brunba841a12014-04-30 17:05:08 +02005331/* string, returns the certificate's key algorithm.
5332 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
5333 * should be use.
5334 */
Emeric Brun521a0112012-10-22 12:22:55 +02005335static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005336smp_fetch_ssl_x_key_alg(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun521a0112012-10-22 12:22:55 +02005337{
Emeric Brunba841a12014-04-30 17:05:08 +02005338 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brun521a0112012-10-22 12:22:55 +02005339 X509 *crt;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02005340 ASN1_OBJECT *algorithm;
Emeric Brun521a0112012-10-22 12:22:55 +02005341 int nid;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005342 struct connection *conn;
Emeric Brun521a0112012-10-22 12:22:55 +02005343
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02005344 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005345 if (!conn || conn->xprt != &ssl_sock)
5346 return 0;
5347
5348 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun521a0112012-10-22 12:22:55 +02005349 smp->flags |= SMP_F_MAY_CHANGE;
5350 return 0;
5351 }
5352
Emeric Brunba841a12014-04-30 17:05:08 +02005353 if (cert_peer)
5354 crt = SSL_get_peer_certificate(conn->xprt_ctx);
5355 else
5356 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brun521a0112012-10-22 12:22:55 +02005357 if (!crt)
5358 return 0;
5359
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02005360 X509_PUBKEY_get0_param(&algorithm, NULL, NULL, NULL, X509_get_X509_PUBKEY(crt));
5361 nid = OBJ_obj2nid(algorithm);
Emeric Brun521a0112012-10-22 12:22:55 +02005362
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005363 smp->data.u.str.str = (char *)OBJ_nid2sn(nid);
5364 if (!smp->data.u.str.str) {
Emeric Brunba841a12014-04-30 17:05:08 +02005365 /* SSL_get_peer_certificate increase X509 * ref count */
5366 if (cert_peer)
5367 X509_free(crt);
Emeric Brun521a0112012-10-22 12:22:55 +02005368 return 0;
Emeric Brun9bf3ba22013-10-07 14:31:44 +02005369 }
Emeric Brun521a0112012-10-22 12:22:55 +02005370
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005371 smp->data.type = SMP_T_STR;
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01005372 smp->flags |= SMP_F_CONST;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005373 smp->data.u.str.len = strlen(smp->data.u.str.str);
Emeric Brunba841a12014-04-30 17:05:08 +02005374 if (cert_peer)
5375 X509_free(crt);
Emeric Brun521a0112012-10-22 12:22:55 +02005376
5377 return 1;
5378}
5379
Emeric Brun645ae792014-04-30 14:21:06 +02005380/* boolean, returns true if front conn. transport layer is SSL.
5381 * This function is also usable on backend conn if the fetch keyword 5th
5382 * char is 'b'.
5383 */
Willy Tarreau7875d092012-09-10 08:20:03 +02005384static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005385smp_fetch_ssl_fc(const struct arg *args, struct sample *smp, const char *kw, void *private)
Willy Tarreau7875d092012-09-10 08:20:03 +02005386{
Willy Tarreaue237fe12016-03-10 17:05:28 +01005387 struct connection *conn = objt_conn((kw[4] != 'b') ? smp->sess->origin :
5388 smp->strm ? smp->strm->si[1].end : NULL);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005389
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005390 smp->data.type = SMP_T_BOOL;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005391 smp->data.u.sint = (conn && conn->xprt == &ssl_sock);
Willy Tarreau7875d092012-09-10 08:20:03 +02005392 return 1;
5393}
5394
Emeric Brun2525b6b2012-10-18 15:59:43 +02005395/* boolean, returns true if client present a SNI */
Willy Tarreau7875d092012-09-10 08:20:03 +02005396static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005397smp_fetch_ssl_fc_has_sni(const struct arg *args, struct sample *smp, const char *kw, void *private)
Willy Tarreau7875d092012-09-10 08:20:03 +02005398{
5399#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02005400 struct connection *conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005401
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005402 smp->data.type = SMP_T_BOOL;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005403 smp->data.u.sint = (conn && conn->xprt == &ssl_sock) &&
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005404 conn->xprt_ctx &&
5405 SSL_get_servername(conn->xprt_ctx, TLSEXT_NAMETYPE_host_name) != NULL;
Willy Tarreau7875d092012-09-10 08:20:03 +02005406 return 1;
5407#else
5408 return 0;
5409#endif
5410}
5411
Nenad Merdanovic26ea8222015-05-18 02:28:57 +02005412/* boolean, returns true if client session has been resumed */
5413static int
5414smp_fetch_ssl_fc_is_resumed(const struct arg *args, struct sample *smp, const char *kw, void *private)
5415{
5416 struct connection *conn = objt_conn(smp->sess->origin);
5417
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005418 smp->data.type = SMP_T_BOOL;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005419 smp->data.u.sint = (conn && conn->xprt == &ssl_sock) &&
Nenad Merdanovic26ea8222015-05-18 02:28:57 +02005420 conn->xprt_ctx &&
5421 SSL_session_reused(conn->xprt_ctx);
5422 return 1;
5423}
5424
Emeric Brun645ae792014-04-30 14:21:06 +02005425/* string, returns the used cipher if front conn. transport layer is SSL.
5426 * This function is also usable on backend conn if the fetch keyword 5th
5427 * char is 'b'.
5428 */
Emeric Brun589fcad2012-10-16 14:13:26 +02005429static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005430smp_fetch_ssl_fc_cipher(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun589fcad2012-10-16 14:13:26 +02005431{
Willy Tarreaue237fe12016-03-10 17:05:28 +01005432 struct connection *conn = objt_conn((kw[4] != 'b') ? smp->sess->origin :
5433 smp->strm ? smp->strm->si[1].end : NULL);
Emeric Brun589fcad2012-10-16 14:13:26 +02005434
Willy Tarreaube508f12016-03-10 11:47:01 +01005435 smp->flags = 0;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005436 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
Emeric Brun589fcad2012-10-16 14:13:26 +02005437 return 0;
5438
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005439 smp->data.u.str.str = (char *)SSL_get_cipher_name(conn->xprt_ctx);
5440 if (!smp->data.u.str.str)
Emeric Brun589fcad2012-10-16 14:13:26 +02005441 return 0;
5442
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005443 smp->data.type = SMP_T_STR;
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01005444 smp->flags |= SMP_F_CONST;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005445 smp->data.u.str.len = strlen(smp->data.u.str.str);
Emeric Brun589fcad2012-10-16 14:13:26 +02005446
5447 return 1;
5448}
5449
Emeric Brun645ae792014-04-30 14:21:06 +02005450/* integer, returns the algoritm's keysize if front conn. transport layer
5451 * is SSL.
5452 * This function is also usable on backend conn if the fetch keyword 5th
5453 * char is 'b'.
5454 */
Emeric Brun589fcad2012-10-16 14:13:26 +02005455static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005456smp_fetch_ssl_fc_alg_keysize(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun589fcad2012-10-16 14:13:26 +02005457{
Willy Tarreaue237fe12016-03-10 17:05:28 +01005458 struct connection *conn = objt_conn((kw[4] != 'b') ? smp->sess->origin :
5459 smp->strm ? smp->strm->si[1].end : NULL);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005460
Willy Tarreaue237fe12016-03-10 17:05:28 +01005461 int sint;
Willy Tarreaube508f12016-03-10 11:47:01 +01005462
Emeric Brun589fcad2012-10-16 14:13:26 +02005463 smp->flags = 0;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005464 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
Emeric Brun589fcad2012-10-16 14:13:26 +02005465 return 0;
5466
Thierry FOURNIER07ee64e2015-07-06 23:43:03 +02005467 if (!SSL_get_cipher_bits(conn->xprt_ctx, &sint))
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005468 return 0;
5469
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005470 smp->data.u.sint = sint;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005471 smp->data.type = SMP_T_SINT;
Emeric Brun589fcad2012-10-16 14:13:26 +02005472
5473 return 1;
5474}
5475
Emeric Brun645ae792014-04-30 14:21:06 +02005476/* integer, returns the used keysize if front conn. transport layer is SSL.
5477 * This function is also usable on backend conn if the fetch keyword 5th
5478 * char is 'b'.
5479 */
Emeric Brun589fcad2012-10-16 14:13:26 +02005480static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005481smp_fetch_ssl_fc_use_keysize(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun589fcad2012-10-16 14:13:26 +02005482{
Willy Tarreaue237fe12016-03-10 17:05:28 +01005483 struct connection *conn = objt_conn((kw[4] != 'b') ? smp->sess->origin :
5484 smp->strm ? smp->strm->si[1].end : NULL);
Willy Tarreaube508f12016-03-10 11:47:01 +01005485
Emeric Brun589fcad2012-10-16 14:13:26 +02005486 smp->flags = 0;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005487 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
5488 return 0;
5489
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005490 smp->data.u.sint = (unsigned int)SSL_get_cipher_bits(conn->xprt_ctx, NULL);
5491 if (!smp->data.u.sint)
Emeric Brun589fcad2012-10-16 14:13:26 +02005492 return 0;
5493
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005494 smp->data.type = SMP_T_SINT;
Emeric Brun589fcad2012-10-16 14:13:26 +02005495
5496 return 1;
5497}
5498
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02005499#ifdef OPENSSL_NPN_NEGOTIATED
Willy Tarreau7875d092012-09-10 08:20:03 +02005500static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005501smp_fetch_ssl_fc_npn(const struct arg *args, struct sample *smp, const char *kw, void *private)
Willy Tarreaua33c6542012-10-15 13:19:06 +02005502{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005503 struct connection *conn;
5504
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01005505 smp->flags = SMP_F_CONST;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005506 smp->data.type = SMP_T_STR;
Willy Tarreaua33c6542012-10-15 13:19:06 +02005507
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02005508 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005509 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
5510 return 0;
5511
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005512 smp->data.u.str.str = NULL;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005513 SSL_get0_next_proto_negotiated(conn->xprt_ctx,
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005514 (const unsigned char **)&smp->data.u.str.str, (unsigned *)&smp->data.u.str.len);
Willy Tarreaua33c6542012-10-15 13:19:06 +02005515
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005516 if (!smp->data.u.str.str)
Willy Tarreaua33c6542012-10-15 13:19:06 +02005517 return 0;
5518
5519 return 1;
Willy Tarreaua33c6542012-10-15 13:19:06 +02005520}
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02005521#endif
Willy Tarreaua33c6542012-10-15 13:19:06 +02005522
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01005523#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Willy Tarreauab861d32013-04-02 02:30:41 +02005524static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005525smp_fetch_ssl_fc_alpn(const struct arg *args, struct sample *smp, const char *kw, void *private)
Willy Tarreauab861d32013-04-02 02:30:41 +02005526{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005527 struct connection *conn;
5528
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01005529 smp->flags = SMP_F_CONST;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005530 smp->data.type = SMP_T_STR;
Willy Tarreauab861d32013-04-02 02:30:41 +02005531
Willy Tarreaue26bf052015-05-12 10:30:12 +02005532 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005533 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
Willy Tarreauab861d32013-04-02 02:30:41 +02005534 return 0;
5535
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005536 smp->data.u.str.str = NULL;
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01005537 SSL_get0_alpn_selected(conn->xprt_ctx,
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005538 (const unsigned char **)&smp->data.u.str.str, (unsigned *)&smp->data.u.str.len);
Willy Tarreauab861d32013-04-02 02:30:41 +02005539
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005540 if (!smp->data.u.str.str)
Willy Tarreauab861d32013-04-02 02:30:41 +02005541 return 0;
5542
5543 return 1;
5544}
5545#endif
5546
Emeric Brun645ae792014-04-30 14:21:06 +02005547/* string, returns the used protocol if front conn. transport layer is SSL.
5548 * This function is also usable on backend conn if the fetch keyword 5th
5549 * char is 'b'.
5550 */
Willy Tarreaua33c6542012-10-15 13:19:06 +02005551static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005552smp_fetch_ssl_fc_protocol(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun589fcad2012-10-16 14:13:26 +02005553{
Willy Tarreaue237fe12016-03-10 17:05:28 +01005554 struct connection *conn = objt_conn((kw[4] != 'b') ? smp->sess->origin :
5555 smp->strm ? smp->strm->si[1].end : NULL);
Willy Tarreaube508f12016-03-10 11:47:01 +01005556
Emeric Brun589fcad2012-10-16 14:13:26 +02005557 smp->flags = 0;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005558 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
5559 return 0;
5560
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005561 smp->data.u.str.str = (char *)SSL_get_version(conn->xprt_ctx);
5562 if (!smp->data.u.str.str)
Emeric Brun589fcad2012-10-16 14:13:26 +02005563 return 0;
5564
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005565 smp->data.type = SMP_T_STR;
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01005566 smp->flags = SMP_F_CONST;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005567 smp->data.u.str.len = strlen(smp->data.u.str.str);
Emeric Brun589fcad2012-10-16 14:13:26 +02005568
5569 return 1;
5570}
5571
Willy Tarreau87b09662015-04-03 00:22:06 +02005572/* binary, returns the SSL stream id if front conn. transport layer is SSL.
Emeric Brun645ae792014-04-30 14:21:06 +02005573 * This function is also usable on backend conn if the fetch keyword 5th
5574 * char is 'b'.
5575 */
Emeric Brun589fcad2012-10-16 14:13:26 +02005576static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005577smp_fetch_ssl_fc_session_id(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brunfe68f682012-10-16 14:59:28 +02005578{
5579#if OPENSSL_VERSION_NUMBER > 0x0090800fL
Willy Tarreaue237fe12016-03-10 17:05:28 +01005580 struct connection *conn = objt_conn((kw[4] != 'b') ? smp->sess->origin :
5581 smp->strm ? smp->strm->si[1].end : NULL);
Emeric Brunfe68f682012-10-16 14:59:28 +02005582
Willy Tarreaue237fe12016-03-10 17:05:28 +01005583 SSL_SESSION *ssl_sess;
Willy Tarreaube508f12016-03-10 11:47:01 +01005584
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01005585 smp->flags = SMP_F_CONST;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005586 smp->data.type = SMP_T_BIN;
Emeric Brunfe68f682012-10-16 14:59:28 +02005587
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005588 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
5589 return 0;
5590
Willy Tarreau192252e2015-04-04 01:47:55 +02005591 ssl_sess = SSL_get_session(conn->xprt_ctx);
5592 if (!ssl_sess)
Emeric Brunfe68f682012-10-16 14:59:28 +02005593 return 0;
5594
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005595 smp->data.u.str.str = (char *)SSL_SESSION_get_id(ssl_sess, (unsigned int *)&smp->data.u.str.len);
5596 if (!smp->data.u.str.str || !smp->data.u.str.len)
Emeric Brunfe68f682012-10-16 14:59:28 +02005597 return 0;
5598
5599 return 1;
5600#else
5601 return 0;
5602#endif
5603}
5604
5605static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005606smp_fetch_ssl_fc_sni(const struct arg *args, struct sample *smp, const char *kw, void *private)
Willy Tarreau7875d092012-09-10 08:20:03 +02005607{
5608#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005609 struct connection *conn;
5610
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01005611 smp->flags = SMP_F_CONST;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005612 smp->data.type = SMP_T_STR;
Willy Tarreau7875d092012-09-10 08:20:03 +02005613
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02005614 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005615 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
5616 return 0;
5617
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005618 smp->data.u.str.str = (char *)SSL_get_servername(conn->xprt_ctx, TLSEXT_NAMETYPE_host_name);
5619 if (!smp->data.u.str.str)
Willy Tarreau3e394c92012-09-14 23:56:58 +02005620 return 0;
5621
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005622 smp->data.u.str.len = strlen(smp->data.u.str.str);
Willy Tarreau7875d092012-09-10 08:20:03 +02005623 return 1;
5624#else
5625 return 0;
5626#endif
5627}
5628
David Sc1ad52e2014-04-08 18:48:47 -04005629static int
Thierry FOURNIER5bf77322017-02-25 12:45:22 +01005630smp_fetch_ssl_fc_cl_bin(const struct arg *args, struct sample *smp, const char *kw, void *private)
5631{
Thierry FOURNIER5bf77322017-02-25 12:45:22 +01005632 struct connection *conn;
5633 struct ssl_capture *capture;
5634
5635 conn = objt_conn(smp->sess->origin);
5636 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
5637 return 0;
5638
Emmanuel Hocdetaaee7502017-03-07 18:34:58 +01005639 capture = SSL_get_ex_data(conn->xprt_ctx, ssl_capture_ptr_index);
Thierry FOURNIER5bf77322017-02-25 12:45:22 +01005640 if (!capture)
5641 return 0;
5642
5643 smp->flags = SMP_F_CONST;
5644 smp->data.type = SMP_T_BIN;
5645 smp->data.u.str.str = capture->ciphersuite;
5646 smp->data.u.str.len = capture->ciphersuite_len;
5647 return 1;
Thierry FOURNIER5bf77322017-02-25 12:45:22 +01005648}
5649
5650static int
5651smp_fetch_ssl_fc_cl_hex(const struct arg *args, struct sample *smp, const char *kw, void *private)
5652{
5653 struct chunk *data;
5654
5655 if (!smp_fetch_ssl_fc_cl_bin(args, smp, kw, private))
5656 return 0;
5657
5658 data = get_trash_chunk();
5659 dump_binary(data, smp->data.u.str.str, smp->data.u.str.len);
5660 smp->data.type = SMP_T_BIN;
5661 smp->data.u.str = *data;
5662 return 1;
5663}
5664
5665static int
5666smp_fetch_ssl_fc_cl_xxh64(const struct arg *args, struct sample *smp, const char *kw, void *private)
5667{
Thierry FOURNIER5bf77322017-02-25 12:45:22 +01005668 struct connection *conn;
5669 struct ssl_capture *capture;
5670
5671 conn = objt_conn(smp->sess->origin);
5672 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
5673 return 0;
5674
Emmanuel Hocdetaaee7502017-03-07 18:34:58 +01005675 capture = SSL_get_ex_data(conn->xprt_ctx, ssl_capture_ptr_index);
Thierry FOURNIER5bf77322017-02-25 12:45:22 +01005676 if (!capture)
5677 return 0;
5678
5679 smp->data.type = SMP_T_SINT;
5680 smp->data.u.sint = capture->xxh64;
5681 return 1;
Thierry FOURNIER5bf77322017-02-25 12:45:22 +01005682}
5683
5684static int
5685smp_fetch_ssl_fc_cl_str(const struct arg *args, struct sample *smp, const char *kw, void *private)
5686{
5687#if (OPENSSL_VERSION_NUMBER >= 0x1000200fL) && !defined(OPENSSL_NO_SSL_TRACE)
5688 struct chunk *data;
5689 SSL_CIPHER cipher;
5690 int i;
5691 const char *str;
5692 unsigned char *bin;
5693
5694 if (!smp_fetch_ssl_fc_cl_bin(args, smp, kw, private))
5695 return 0;
5696
5697 /* The cipher algorith must not be SSL_SSLV2, because this
5698 * SSL version seems to not have the same cipher encoding,
5699 * and it is not supported by OpenSSL. Unfortunately, the
5700 * #define SSL_SSLV2, SSL_SSLV3 and others are not available
5701 * with standard defines. We just set the variable to 0,
5702 * ensure that the match with SSL_SSLV2 fails.
5703 */
5704 cipher.algorithm_ssl = 0;
5705
5706 data = get_trash_chunk();
5707 for (i = 0; i + 1 < smp->data.u.str.len; i += 2) {
5708 bin = (unsigned char *)smp->data.u.str.str + i;
5709 cipher.id = (unsigned int)(bin[0] << 8) | bin[1];
5710 str = SSL_CIPHER_standard_name(&cipher);
5711 if (!str || strcmp(str, "UNKNOWN") == 0)
5712 chunk_appendf(data, "%sUNKNOWN(%04x)", i == 0 ? "" : ",", (unsigned int)cipher.id);
5713 else
5714 chunk_appendf(data, "%s%s", i == 0 ? "" : ",", str);
5715 }
5716 smp->data.type = SMP_T_STR;
5717 smp->data.u.str = *data;
5718 return 1;
5719#else
5720 return smp_fetch_ssl_fc_cl_xxh64(args, smp, kw, private);
5721#endif
5722}
5723
5724static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005725smp_fetch_ssl_fc_unique_id(const struct arg *args, struct sample *smp, const char *kw, void *private)
David Sc1ad52e2014-04-08 18:48:47 -04005726{
5727#if OPENSSL_VERSION_NUMBER > 0x0090800fL
Willy Tarreaue237fe12016-03-10 17:05:28 +01005728 struct connection *conn = objt_conn((kw[4] != 'b') ? smp->sess->origin :
5729 smp->strm ? smp->strm->si[1].end : NULL);
5730
David Sc1ad52e2014-04-08 18:48:47 -04005731 int finished_len;
David Sc1ad52e2014-04-08 18:48:47 -04005732 struct chunk *finished_trash;
David Sc1ad52e2014-04-08 18:48:47 -04005733
5734 smp->flags = 0;
David Sc1ad52e2014-04-08 18:48:47 -04005735 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
5736 return 0;
5737
5738 if (!(conn->flags & CO_FL_CONNECTED)) {
5739 smp->flags |= SMP_F_MAY_CHANGE;
5740 return 0;
5741 }
5742
5743 finished_trash = get_trash_chunk();
5744 if (!SSL_session_reused(conn->xprt_ctx))
5745 finished_len = SSL_get_peer_finished(conn->xprt_ctx, finished_trash->str, finished_trash->size);
5746 else
5747 finished_len = SSL_get_finished(conn->xprt_ctx, finished_trash->str, finished_trash->size);
5748
5749 if (!finished_len)
5750 return 0;
5751
Emeric Brunb73a9b02014-04-30 18:49:19 +02005752 finished_trash->len = finished_len;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005753 smp->data.u.str = *finished_trash;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005754 smp->data.type = SMP_T_BIN;
David Sc1ad52e2014-04-08 18:48:47 -04005755
5756 return 1;
5757#else
5758 return 0;
5759#endif
5760}
5761
Emeric Brun2525b6b2012-10-18 15:59:43 +02005762/* integer, returns the first verify error in CA chain of client certificate chain. */
Emeric Brunf282a812012-09-21 15:27:54 +02005763static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005764smp_fetch_ssl_c_ca_err(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brunf282a812012-09-21 15:27:54 +02005765{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005766 struct connection *conn;
5767
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02005768 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005769 if (!conn || conn->xprt != &ssl_sock)
5770 return 0;
5771
5772 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunf282a812012-09-21 15:27:54 +02005773 smp->flags = SMP_F_MAY_CHANGE;
5774 return 0;
5775 }
5776
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005777 smp->data.type = SMP_T_SINT;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005778 smp->data.u.sint = (unsigned long long int)SSL_SOCK_ST_TO_CA_ERROR(conn->xprt_st);
Emeric Brunf282a812012-09-21 15:27:54 +02005779 smp->flags = 0;
5780
5781 return 1;
5782}
5783
Emeric Brun2525b6b2012-10-18 15:59:43 +02005784/* integer, returns the depth of the first verify error in CA chain of client certificate chain. */
Emeric Brunf282a812012-09-21 15:27:54 +02005785static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005786smp_fetch_ssl_c_ca_err_depth(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brunf282a812012-09-21 15:27:54 +02005787{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005788 struct connection *conn;
5789
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02005790 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005791 if (!conn || conn->xprt != &ssl_sock)
Emeric Brunf282a812012-09-21 15:27:54 +02005792 return 0;
5793
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005794 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunf282a812012-09-21 15:27:54 +02005795 smp->flags = SMP_F_MAY_CHANGE;
5796 return 0;
5797 }
5798
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005799 smp->data.type = SMP_T_SINT;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005800 smp->data.u.sint = (long long int)SSL_SOCK_ST_TO_CAEDEPTH(conn->xprt_st);
Emeric Brunf282a812012-09-21 15:27:54 +02005801 smp->flags = 0;
5802
5803 return 1;
5804}
5805
Emeric Brun2525b6b2012-10-18 15:59:43 +02005806/* integer, returns the first verify error on client certificate */
Emeric Brunf282a812012-09-21 15:27:54 +02005807static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005808smp_fetch_ssl_c_err(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brunf282a812012-09-21 15:27:54 +02005809{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005810 struct connection *conn;
5811
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02005812 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005813 if (!conn || conn->xprt != &ssl_sock)
5814 return 0;
5815
5816 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunf282a812012-09-21 15:27:54 +02005817 smp->flags = SMP_F_MAY_CHANGE;
5818 return 0;
5819 }
5820
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005821 smp->data.type = SMP_T_SINT;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005822 smp->data.u.sint = (long long int)SSL_SOCK_ST_TO_CRTERROR(conn->xprt_st);
Emeric Brunf282a812012-09-21 15:27:54 +02005823 smp->flags = 0;
5824
5825 return 1;
5826}
5827
Emeric Brun2525b6b2012-10-18 15:59:43 +02005828/* integer, returns the verify result on client cert */
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02005829static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005830smp_fetch_ssl_c_verify(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02005831{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005832 struct connection *conn;
5833
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02005834 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005835 if (!conn || conn->xprt != &ssl_sock)
5836 return 0;
5837
5838 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02005839 smp->flags = SMP_F_MAY_CHANGE;
5840 return 0;
5841 }
5842
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005843 if (!conn->xprt_ctx)
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02005844 return 0;
5845
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005846 smp->data.type = SMP_T_SINT;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005847 smp->data.u.sint = (long long int)SSL_get_verify_result(conn->xprt_ctx);
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02005848 smp->flags = 0;
5849
5850 return 1;
5851}
5852
Emeric Brunfb510ea2012-10-05 12:00:26 +02005853/* parse the "ca-file" bind keyword */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01005854static int ssl_bind_parse_ca_file(char **args, int cur_arg, struct proxy *px, struct ssl_bind_conf *conf, char **err)
Emeric Brund94b3fe2012-09-20 18:23:56 +02005855{
5856 if (!*args[cur_arg + 1]) {
5857 if (err)
5858 memprintf(err, "'%s' : missing CAfile path", args[cur_arg]);
5859 return ERR_ALERT | ERR_FATAL;
5860 }
5861
Willy Tarreauef934602016-12-22 23:12:01 +01005862 if ((*args[cur_arg + 1] != '/') && global_ssl.ca_base)
5863 memprintf(&conf->ca_file, "%s/%s", global_ssl.ca_base, args[cur_arg + 1]);
Emeric Brunef42d922012-10-11 16:11:36 +02005864 else
5865 memprintf(&conf->ca_file, "%s", args[cur_arg + 1]);
Emeric Brunc8e8d122012-10-02 18:42:10 +02005866
Emeric Brund94b3fe2012-09-20 18:23:56 +02005867 return 0;
5868}
Emmanuel Hocdet98263292016-12-29 18:26:15 +01005869static int bind_parse_ca_file(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5870{
5871 return ssl_bind_parse_ca_file(args, cur_arg, px, &conf->ssl_conf, err);
5872}
Emeric Brund94b3fe2012-09-20 18:23:56 +02005873
Christopher Faulet31af49d2015-06-09 17:29:50 +02005874/* parse the "ca-sign-file" bind keyword */
5875static int bind_parse_ca_sign_file(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5876{
5877 if (!*args[cur_arg + 1]) {
5878 if (err)
5879 memprintf(err, "'%s' : missing CAfile path", args[cur_arg]);
5880 return ERR_ALERT | ERR_FATAL;
5881 }
5882
Willy Tarreauef934602016-12-22 23:12:01 +01005883 if ((*args[cur_arg + 1] != '/') && global_ssl.ca_base)
5884 memprintf(&conf->ca_sign_file, "%s/%s", global_ssl.ca_base, args[cur_arg + 1]);
Christopher Faulet31af49d2015-06-09 17:29:50 +02005885 else
5886 memprintf(&conf->ca_sign_file, "%s", args[cur_arg + 1]);
5887
5888 return 0;
5889}
5890
Bertrand Jacquinff13c062016-11-13 16:37:11 +00005891/* parse the "ca-sign-pass" bind keyword */
Christopher Faulet31af49d2015-06-09 17:29:50 +02005892static int bind_parse_ca_sign_pass(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5893{
5894 if (!*args[cur_arg + 1]) {
5895 if (err)
5896 memprintf(err, "'%s' : missing CAkey password", args[cur_arg]);
5897 return ERR_ALERT | ERR_FATAL;
5898 }
5899 memprintf(&conf->ca_sign_pass, "%s", args[cur_arg + 1]);
5900 return 0;
5901}
5902
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005903/* parse the "ciphers" bind keyword */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01005904static int ssl_bind_parse_ciphers(char **args, int cur_arg, struct proxy *px, struct ssl_bind_conf *conf, char **err)
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005905{
5906 if (!*args[cur_arg + 1]) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02005907 memprintf(err, "'%s' : missing cipher suite", args[cur_arg]);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005908 return ERR_ALERT | ERR_FATAL;
5909 }
5910
Emeric Brun76d88952012-10-05 15:47:31 +02005911 free(conf->ciphers);
Willy Tarreau4348fad2012-09-20 16:48:07 +02005912 conf->ciphers = strdup(args[cur_arg + 1]);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005913 return 0;
5914}
Emmanuel Hocdet98263292016-12-29 18:26:15 +01005915static int bind_parse_ciphers(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5916{
5917 return ssl_bind_parse_ciphers(args, cur_arg, px, &conf->ssl_conf, err);
5918}
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005919/* parse the "crt" bind keyword */
Willy Tarreau4348fad2012-09-20 16:48:07 +02005920static 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 +02005921{
Willy Tarreau38011032013-08-13 16:59:39 +02005922 char path[MAXPATHLEN];
Willy Tarreaub75d6922014-04-14 18:05:41 +02005923
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005924 if (!*args[cur_arg + 1]) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02005925 memprintf(err, "'%s' : missing certificate location", args[cur_arg]);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005926 return ERR_ALERT | ERR_FATAL;
5927 }
5928
Willy Tarreauef934602016-12-22 23:12:01 +01005929 if ((*args[cur_arg + 1] != '/' ) && global_ssl.crt_base) {
5930 if ((strlen(global_ssl.crt_base) + 1 + strlen(args[cur_arg + 1]) + 1) > MAXPATHLEN) {
Emeric Brunc8e8d122012-10-02 18:42:10 +02005931 memprintf(err, "'%s' : path too long", args[cur_arg]);
5932 return ERR_ALERT | ERR_FATAL;
5933 }
Willy Tarreauef934602016-12-22 23:12:01 +01005934 snprintf(path, sizeof(path), "%s/%s", global_ssl.crt_base, args[cur_arg + 1]);
Willy Tarreau03209342016-12-22 17:08:28 +01005935 if (ssl_sock_load_cert(path, conf, err) > 0)
Emeric Brunc8e8d122012-10-02 18:42:10 +02005936 return ERR_ALERT | ERR_FATAL;
5937
5938 return 0;
5939 }
5940
Willy Tarreau03209342016-12-22 17:08:28 +01005941 if (ssl_sock_load_cert(args[cur_arg + 1], conf, err) > 0)
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005942 return ERR_ALERT | ERR_FATAL;
Emeric Brund94b3fe2012-09-20 18:23:56 +02005943
5944 return 0;
5945}
5946
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01005947/* parse the "crt-list" bind keyword */
5948static int bind_parse_crt_list(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5949{
5950 if (!*args[cur_arg + 1]) {
5951 memprintf(err, "'%s' : missing certificate location", args[cur_arg]);
5952 return ERR_ALERT | ERR_FATAL;
5953 }
5954
Emmanuel Hocdet98263292016-12-29 18:26:15 +01005955 if (ssl_sock_load_cert_list_file(args[cur_arg + 1], conf, px, err) > 0) {
Willy Tarreauad1731d2013-04-02 17:35:58 +02005956 memprintf(err, "'%s' : %s", args[cur_arg], *err);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01005957 return ERR_ALERT | ERR_FATAL;
Willy Tarreauad1731d2013-04-02 17:35:58 +02005958 }
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01005959
5960 return 0;
5961}
5962
Emeric Brunfb510ea2012-10-05 12:00:26 +02005963/* parse the "crl-file" bind keyword */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01005964static int ssl_bind_parse_crl_file(char **args, int cur_arg, struct proxy *px, struct ssl_bind_conf *conf, char **err)
Emeric Brund94b3fe2012-09-20 18:23:56 +02005965{
Emeric Brun051cdab2012-10-02 19:25:50 +02005966#ifndef X509_V_FLAG_CRL_CHECK
5967 if (err)
5968 memprintf(err, "'%s' : library does not support CRL verify", args[cur_arg]);
5969 return ERR_ALERT | ERR_FATAL;
5970#else
Emeric Brund94b3fe2012-09-20 18:23:56 +02005971 if (!*args[cur_arg + 1]) {
5972 if (err)
5973 memprintf(err, "'%s' : missing CRLfile path", args[cur_arg]);
5974 return ERR_ALERT | ERR_FATAL;
5975 }
Emeric Brun2b58d042012-09-20 17:10:03 +02005976
Willy Tarreauef934602016-12-22 23:12:01 +01005977 if ((*args[cur_arg + 1] != '/') && global_ssl.ca_base)
5978 memprintf(&conf->crl_file, "%s/%s", global_ssl.ca_base, args[cur_arg + 1]);
Emeric Brunef42d922012-10-11 16:11:36 +02005979 else
5980 memprintf(&conf->crl_file, "%s", args[cur_arg + 1]);
Emeric Brunc8e8d122012-10-02 18:42:10 +02005981
Emeric Brun2b58d042012-09-20 17:10:03 +02005982 return 0;
Emeric Brun051cdab2012-10-02 19:25:50 +02005983#endif
Emeric Brun2b58d042012-09-20 17:10:03 +02005984}
Emmanuel Hocdet98263292016-12-29 18:26:15 +01005985static int bind_parse_crl_file(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5986{
5987 return ssl_bind_parse_crl_file(args, cur_arg, px, &conf->ssl_conf, err);
5988}
Emeric Brun2b58d042012-09-20 17:10:03 +02005989
Emmanuel Hocdete7f2b732017-01-09 16:15:54 +01005990/* parse the "curves" bind keyword keyword */
5991static int ssl_bind_parse_curves(char **args, int cur_arg, struct proxy *px, struct ssl_bind_conf *conf, char **err)
5992{
5993#if OPENSSL_VERSION_NUMBER >= 0x1000200fL
5994 if (!*args[cur_arg + 1]) {
5995 if (err)
5996 memprintf(err, "'%s' : missing curve suite", args[cur_arg]);
5997 return ERR_ALERT | ERR_FATAL;
5998 }
5999 conf->curves = strdup(args[cur_arg + 1]);
6000 return 0;
6001#else
6002 if (err)
6003 memprintf(err, "'%s' : library does not support curve suite", args[cur_arg]);
6004 return ERR_ALERT | ERR_FATAL;
6005#endif
6006}
6007static int bind_parse_curves(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
6008{
6009 return ssl_bind_parse_curves(args, cur_arg, px, &conf->ssl_conf, err);
6010}
6011
Bertrand Jacquinff13c062016-11-13 16:37:11 +00006012/* parse the "ecdhe" bind keyword keyword */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01006013static int ssl_bind_parse_ecdhe(char **args, int cur_arg, struct proxy *px, struct ssl_bind_conf *conf, char **err)
Emeric Brun2b58d042012-09-20 17:10:03 +02006014{
6015#if OPENSSL_VERSION_NUMBER < 0x0090800fL
6016 if (err)
6017 memprintf(err, "'%s' : library does not support elliptic curve Diffie-Hellman (too old)", args[cur_arg]);
6018 return ERR_ALERT | ERR_FATAL;
6019#elif defined(OPENSSL_NO_ECDH)
6020 if (err)
6021 memprintf(err, "'%s' : library does not support elliptic curve Diffie-Hellman (disabled via OPENSSL_NO_ECDH)", args[cur_arg]);
6022 return ERR_ALERT | ERR_FATAL;
6023#else
6024 if (!*args[cur_arg + 1]) {
6025 if (err)
6026 memprintf(err, "'%s' : missing named curve", args[cur_arg]);
6027 return ERR_ALERT | ERR_FATAL;
6028 }
6029
6030 conf->ecdhe = strdup(args[cur_arg + 1]);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02006031
6032 return 0;
Emeric Brun2b58d042012-09-20 17:10:03 +02006033#endif
Willy Tarreau79eeafa2012-09-14 07:53:05 +02006034}
Emmanuel Hocdet98263292016-12-29 18:26:15 +01006035static int bind_parse_ecdhe(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
6036{
6037 return ssl_bind_parse_ecdhe(args, cur_arg, px, &conf->ssl_conf, err);
6038}
Willy Tarreau79eeafa2012-09-14 07:53:05 +02006039
Bertrand Jacquinff13c062016-11-13 16:37:11 +00006040/* parse the "crt-ignore-err" and "ca-ignore-err" bind keywords */
Emeric Brun81c00f02012-09-21 14:31:21 +02006041static int bind_parse_ignore_err(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
6042{
6043 int code;
6044 char *p = args[cur_arg + 1];
6045 unsigned long long *ignerr = &conf->crt_ignerr;
6046
6047 if (!*p) {
6048 if (err)
6049 memprintf(err, "'%s' : missing error IDs list", args[cur_arg]);
6050 return ERR_ALERT | ERR_FATAL;
6051 }
6052
6053 if (strcmp(args[cur_arg], "ca-ignore-err") == 0)
6054 ignerr = &conf->ca_ignerr;
6055
6056 if (strcmp(p, "all") == 0) {
6057 *ignerr = ~0ULL;
6058 return 0;
6059 }
6060
6061 while (p) {
6062 code = atoi(p);
6063 if ((code <= 0) || (code > 63)) {
6064 if (err)
6065 memprintf(err, "'%s' : ID '%d' out of range (1..63) in error IDs list '%s'",
6066 args[cur_arg], code, args[cur_arg + 1]);
6067 return ERR_ALERT | ERR_FATAL;
6068 }
6069 *ignerr |= 1ULL << code;
6070 p = strchr(p, ',');
6071 if (p)
6072 p++;
6073 }
6074
Emeric Brun2cb7ae52012-10-05 14:14:21 +02006075 return 0;
6076}
6077
6078/* parse the "force-sslv3" bind keyword */
Emmanuel Hocdet4608ed92017-01-20 13:06:27 +01006079static int bind_parse_force_sslv3(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
Emeric Brun2cb7ae52012-10-05 14:14:21 +02006080{
Emmanuel Hocdet4de1ff12017-03-03 12:21:32 +01006081#ifndef OPENSSL_NO_SSL3
Emeric Brun2cb7ae52012-10-05 14:14:21 +02006082 conf->ssl_options |= BC_SSL_O_USE_SSLV3;
6083 return 0;
Emmanuel Hocdet4de1ff12017-03-03 12:21:32 +01006084#else
6085 if (err)
6086 memprintf(err, "'%s' : library does not support protocol SSLv3", args[cur_arg]);
6087 return ERR_ALERT | ERR_FATAL;
6088#endif
Emeric Brun2cb7ae52012-10-05 14:14:21 +02006089}
6090
6091/* parse the "force-tlsv10" bind keyword */
Emmanuel Hocdet4608ed92017-01-20 13:06:27 +01006092static int bind_parse_force_tlsv10(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
Emeric Brun2cb7ae52012-10-05 14:14:21 +02006093{
6094 conf->ssl_options |= BC_SSL_O_USE_TLSV10;
Emeric Brun2d0c4822012-10-02 13:45:20 +02006095 return 0;
6096}
6097
Emeric Brun2cb7ae52012-10-05 14:14:21 +02006098/* parse the "force-tlsv11" bind keyword */
Emmanuel Hocdet4608ed92017-01-20 13:06:27 +01006099static int bind_parse_force_tlsv11(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
Emeric Brun2cb7ae52012-10-05 14:14:21 +02006100{
6101#if SSL_OP_NO_TLSv1_1
6102 conf->ssl_options |= BC_SSL_O_USE_TLSV11;
6103 return 0;
6104#else
6105 if (err)
6106 memprintf(err, "'%s' : library does not support protocol TLSv1.1", args[cur_arg]);
6107 return ERR_ALERT | ERR_FATAL;
6108#endif
6109}
6110
6111/* parse the "force-tlsv12" bind keyword */
Emmanuel Hocdet4608ed92017-01-20 13:06:27 +01006112static int bind_parse_force_tlsv12(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
Emeric Brun2cb7ae52012-10-05 14:14:21 +02006113{
6114#if SSL_OP_NO_TLSv1_2
6115 conf->ssl_options |= BC_SSL_O_USE_TLSV12;
6116 return 0;
6117#else
6118 if (err)
6119 memprintf(err, "'%s' : library does not support protocol TLSv1.2", args[cur_arg]);
6120 return ERR_ALERT | ERR_FATAL;
6121#endif
6122}
Emeric Brun2cb7ae52012-10-05 14:14:21 +02006123
Emeric Brun2d0c4822012-10-02 13:45:20 +02006124/* parse the "no-tls-tickets" bind keyword */
Emmanuel Hocdet4608ed92017-01-20 13:06:27 +01006125static int bind_parse_no_tls_tickets(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
Emeric Brun2d0c4822012-10-02 13:45:20 +02006126{
Emeric Brun89675492012-10-05 13:48:26 +02006127 conf->ssl_options |= BC_SSL_O_NO_TLS_TICKETS;
Emeric Brun81c00f02012-09-21 14:31:21 +02006128 return 0;
6129}
Emeric Brun2d0c4822012-10-02 13:45:20 +02006130
Emeric Brun9b3009b2012-10-05 11:55:06 +02006131/* parse the "no-sslv3" bind keyword */
Emmanuel Hocdet4608ed92017-01-20 13:06:27 +01006132static 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 +02006133{
Emeric Brun89675492012-10-05 13:48:26 +02006134 conf->ssl_options |= BC_SSL_O_NO_SSLV3;
Willy Tarreau79eeafa2012-09-14 07:53:05 +02006135 return 0;
6136}
6137
Emeric Brun9b3009b2012-10-05 11:55:06 +02006138/* parse the "no-tlsv10" bind keyword */
Emmanuel Hocdet4608ed92017-01-20 13:06:27 +01006139static 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 +02006140{
Emeric Brun89675492012-10-05 13:48:26 +02006141 conf->ssl_options |= BC_SSL_O_NO_TLSV10;
Emeric Brunc0ff4922012-09-28 19:37:02 +02006142 return 0;
6143}
6144
Emeric Brun9b3009b2012-10-05 11:55:06 +02006145/* parse the "no-tlsv11" bind keyword */
Emmanuel Hocdet4608ed92017-01-20 13:06:27 +01006146static 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 +02006147{
Emeric Brun89675492012-10-05 13:48:26 +02006148 conf->ssl_options |= BC_SSL_O_NO_TLSV11;
Emeric Brunc0ff4922012-09-28 19:37:02 +02006149 return 0;
6150}
6151
Emeric Brun9b3009b2012-10-05 11:55:06 +02006152/* parse the "no-tlsv12" bind keyword */
Emmanuel Hocdet4608ed92017-01-20 13:06:27 +01006153static 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 +02006154{
Emeric Brun89675492012-10-05 13:48:26 +02006155 conf->ssl_options |= BC_SSL_O_NO_TLSV12;
Willy Tarreau79eeafa2012-09-14 07:53:05 +02006156 return 0;
6157}
6158
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02006159/* parse the "npn" bind keyword */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01006160static int ssl_bind_parse_npn(char **args, int cur_arg, struct proxy *px, struct ssl_bind_conf *conf, char **err)
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02006161{
6162#ifdef OPENSSL_NPN_NEGOTIATED
6163 char *p1, *p2;
6164
6165 if (!*args[cur_arg + 1]) {
6166 memprintf(err, "'%s' : missing the comma-delimited NPN protocol suite", args[cur_arg]);
6167 return ERR_ALERT | ERR_FATAL;
6168 }
6169
6170 free(conf->npn_str);
6171
Willy Tarreau3724da12016-02-12 17:11:12 +01006172 /* the NPN string is built as a suite of (<len> <name>)*,
6173 * so we reuse each comma to store the next <len> and need
6174 * one more for the end of the string.
6175 */
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02006176 conf->npn_len = strlen(args[cur_arg + 1]) + 1;
Willy Tarreau3724da12016-02-12 17:11:12 +01006177 conf->npn_str = calloc(1, conf->npn_len + 1);
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02006178 memcpy(conf->npn_str + 1, args[cur_arg + 1], conf->npn_len);
6179
6180 /* replace commas with the name length */
6181 p1 = conf->npn_str;
6182 p2 = p1 + 1;
6183 while (1) {
6184 p2 = memchr(p1 + 1, ',', conf->npn_str + conf->npn_len - (p1 + 1));
6185 if (!p2)
6186 p2 = p1 + 1 + strlen(p1 + 1);
6187
6188 if (p2 - (p1 + 1) > 255) {
6189 *p2 = '\0';
6190 memprintf(err, "'%s' : NPN protocol name too long : '%s'", args[cur_arg], p1 + 1);
6191 return ERR_ALERT | ERR_FATAL;
6192 }
6193
6194 *p1 = p2 - (p1 + 1);
6195 p1 = p2;
6196
6197 if (!*p2)
6198 break;
6199
6200 *(p2++) = '\0';
6201 }
6202 return 0;
6203#else
6204 if (err)
6205 memprintf(err, "'%s' : library does not support TLS NPN extension", args[cur_arg]);
6206 return ERR_ALERT | ERR_FATAL;
6207#endif
6208}
6209
Emmanuel Hocdet98263292016-12-29 18:26:15 +01006210static int bind_parse_npn(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
6211{
6212 return ssl_bind_parse_npn(args, cur_arg, px, &conf->ssl_conf, err);
6213}
6214
Willy Tarreauab861d32013-04-02 02:30:41 +02006215/* parse the "alpn" bind keyword */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01006216static int ssl_bind_parse_alpn(char **args, int cur_arg, struct proxy *px, struct ssl_bind_conf *conf, char **err)
Willy Tarreauab861d32013-04-02 02:30:41 +02006217{
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01006218#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Willy Tarreauab861d32013-04-02 02:30:41 +02006219 char *p1, *p2;
6220
6221 if (!*args[cur_arg + 1]) {
6222 memprintf(err, "'%s' : missing the comma-delimited ALPN protocol suite", args[cur_arg]);
6223 return ERR_ALERT | ERR_FATAL;
6224 }
6225
6226 free(conf->alpn_str);
6227
Marcoen Hirschbergbef60912016-02-12 17:05:24 +01006228 /* the ALPN string is built as a suite of (<len> <name>)*,
6229 * so we reuse each comma to store the next <len> and need
6230 * one more for the end of the string.
6231 */
Willy Tarreauab861d32013-04-02 02:30:41 +02006232 conf->alpn_len = strlen(args[cur_arg + 1]) + 1;
Marcoen Hirschbergbef60912016-02-12 17:05:24 +01006233 conf->alpn_str = calloc(1, conf->alpn_len + 1);
Willy Tarreauab861d32013-04-02 02:30:41 +02006234 memcpy(conf->alpn_str + 1, args[cur_arg + 1], conf->alpn_len);
6235
6236 /* replace commas with the name length */
6237 p1 = conf->alpn_str;
6238 p2 = p1 + 1;
6239 while (1) {
6240 p2 = memchr(p1 + 1, ',', conf->alpn_str + conf->alpn_len - (p1 + 1));
6241 if (!p2)
6242 p2 = p1 + 1 + strlen(p1 + 1);
6243
6244 if (p2 - (p1 + 1) > 255) {
6245 *p2 = '\0';
6246 memprintf(err, "'%s' : ALPN protocol name too long : '%s'", args[cur_arg], p1 + 1);
6247 return ERR_ALERT | ERR_FATAL;
6248 }
6249
6250 *p1 = p2 - (p1 + 1);
6251 p1 = p2;
6252
6253 if (!*p2)
6254 break;
6255
6256 *(p2++) = '\0';
6257 }
6258 return 0;
6259#else
6260 if (err)
6261 memprintf(err, "'%s' : library does not support TLS ALPN extension", args[cur_arg]);
6262 return ERR_ALERT | ERR_FATAL;
6263#endif
6264}
6265
Emmanuel Hocdet98263292016-12-29 18:26:15 +01006266static int bind_parse_alpn(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
6267{
6268 return ssl_bind_parse_alpn(args, cur_arg, px, &conf->ssl_conf, err);
6269}
6270
Willy Tarreau79eeafa2012-09-14 07:53:05 +02006271/* parse the "ssl" bind keyword */
Willy Tarreau4348fad2012-09-20 16:48:07 +02006272static 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 +02006273{
Willy Tarreau71a8c7c2016-12-21 22:04:54 +01006274 conf->xprt = &ssl_sock;
Willy Tarreau4348fad2012-09-20 16:48:07 +02006275 conf->is_ssl = 1;
Emeric Brun76d88952012-10-05 15:47:31 +02006276
Emmanuel Hocdet98263292016-12-29 18:26:15 +01006277 if (global_ssl.listen_default_ciphers && !conf->ssl_conf.ciphers)
6278 conf->ssl_conf.ciphers = strdup(global_ssl.listen_default_ciphers);
Emmanuel Hocdet4608ed92017-01-20 13:06:27 +01006279 conf->ssl_options |= global_ssl.listen_default_ssloptions;
Emeric Brun76d88952012-10-05 15:47:31 +02006280
Willy Tarreau79eeafa2012-09-14 07:53:05 +02006281 return 0;
6282}
6283
Christopher Faulet31af49d2015-06-09 17:29:50 +02006284/* parse the "generate-certificates" bind keyword */
6285static int bind_parse_generate_certs(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
6286{
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +01006287#if (defined SSL_CTRL_SET_TLSEXT_HOSTNAME && !defined SSL_NO_GENERATE_CERTIFICATES)
Christopher Faulet31af49d2015-06-09 17:29:50 +02006288 conf->generate_certs = 1;
6289#else
6290 memprintf(err, "%sthis version of openssl cannot generate SSL certificates.\n",
6291 err && *err ? *err : "");
6292#endif
6293 return 0;
6294}
6295
Emmanuel Hocdet65623372013-01-24 17:17:15 +01006296/* parse the "strict-sni" bind keyword */
6297static int bind_parse_strict_sni(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
6298{
6299 conf->strict_sni = 1;
6300 return 0;
Nenad Merdanovic05552d42015-02-27 19:56:49 +01006301}
6302
6303/* parse the "tls-ticket-keys" bind keyword */
6304static int bind_parse_tls_ticket_keys(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
6305{
6306#if (defined SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB && TLS_TICKETS_NO > 0)
6307 FILE *f;
6308 int i = 0;
6309 char thisline[LINESIZE];
Nenad Merdanovic146defa2015-05-09 08:46:00 +02006310 struct tls_keys_ref *keys_ref;
Nenad Merdanovic05552d42015-02-27 19:56:49 +01006311
6312 if (!*args[cur_arg + 1]) {
6313 if (err)
6314 memprintf(err, "'%s' : missing TLS ticket keys file path", args[cur_arg]);
6315 return ERR_ALERT | ERR_FATAL;
6316 }
6317
Nenad Merdanovic200b0fa2015-05-09 08:46:01 +02006318 keys_ref = tlskeys_ref_lookup(args[cur_arg + 1]);
6319 if(keys_ref) {
6320 conf->keys_ref = keys_ref;
6321 return 0;
6322 }
6323
Vincent Bernat02779b62016-04-03 13:48:43 +02006324 keys_ref = malloc(sizeof(*keys_ref));
Nenad Merdanovic146defa2015-05-09 08:46:00 +02006325 keys_ref->tlskeys = malloc(TLS_TICKETS_NO * sizeof(struct tls_sess_key));
Nenad Merdanovic05552d42015-02-27 19:56:49 +01006326
6327 if ((f = fopen(args[cur_arg + 1], "r")) == NULL) {
6328 if (err)
6329 memprintf(err, "'%s' : unable to load ssl tickets keys file", args[cur_arg+1]);
6330 return ERR_ALERT | ERR_FATAL;
6331 }
6332
Nenad Merdanovic146defa2015-05-09 08:46:00 +02006333 keys_ref->filename = strdup(args[cur_arg + 1]);
6334
Nenad Merdanovic05552d42015-02-27 19:56:49 +01006335 while (fgets(thisline, sizeof(thisline), f) != NULL) {
6336 int len = strlen(thisline);
6337 /* Strip newline characters from the end */
6338 if(thisline[len - 1] == '\n')
6339 thisline[--len] = 0;
6340
6341 if(thisline[len - 1] == '\r')
6342 thisline[--len] = 0;
6343
Nenad Merdanovic146defa2015-05-09 08:46:00 +02006344 if (base64dec(thisline, len, (char *) (keys_ref->tlskeys + i % TLS_TICKETS_NO), sizeof(struct tls_sess_key)) != sizeof(struct tls_sess_key)) {
Nenad Merdanovic05552d42015-02-27 19:56:49 +01006345 if (err)
6346 memprintf(err, "'%s' : unable to decode base64 key on line %d", args[cur_arg+1], i + 1);
mildis16aa0152016-06-22 17:46:29 +02006347 fclose(f);
Nenad Merdanovic05552d42015-02-27 19:56:49 +01006348 return ERR_ALERT | ERR_FATAL;
6349 }
6350 i++;
6351 }
6352
6353 if (i < TLS_TICKETS_NO) {
6354 if (err)
6355 memprintf(err, "'%s' : please supply at least %d keys in the tls-tickets-file", args[cur_arg+1], TLS_TICKETS_NO);
mildis16aa0152016-06-22 17:46:29 +02006356 fclose(f);
Nenad Merdanovic05552d42015-02-27 19:56:49 +01006357 return ERR_ALERT | ERR_FATAL;
6358 }
6359
6360 fclose(f);
6361
6362 /* Use penultimate key for encryption, handle when TLS_TICKETS_NO = 1 */
Nenad Merdanovic17891152016-03-25 22:16:57 +01006363 i -= 2;
6364 keys_ref->tls_ticket_enc_index = i < 0 ? 0 : i % TLS_TICKETS_NO;
Nenad Merdanovic200b0fa2015-05-09 08:46:01 +02006365 keys_ref->unique_id = -1;
Nenad Merdanovic146defa2015-05-09 08:46:00 +02006366 conf->keys_ref = keys_ref;
Nenad Merdanovic05552d42015-02-27 19:56:49 +01006367
Nenad Merdanovic200b0fa2015-05-09 08:46:01 +02006368 LIST_ADD(&tlskeys_reference, &keys_ref->list);
6369
Nenad Merdanovic05552d42015-02-27 19:56:49 +01006370 return 0;
6371#else
6372 if (err)
6373 memprintf(err, "'%s' : TLS ticket callback extension not supported", args[cur_arg]);
6374 return ERR_ALERT | ERR_FATAL;
6375#endif /* SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB */
Emmanuel Hocdet65623372013-01-24 17:17:15 +01006376}
6377
Emeric Brund94b3fe2012-09-20 18:23:56 +02006378/* parse the "verify" bind keyword */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01006379static int ssl_bind_parse_verify(char **args, int cur_arg, struct proxy *px, struct ssl_bind_conf *conf, char **err)
Emeric Brund94b3fe2012-09-20 18:23:56 +02006380{
6381 if (!*args[cur_arg + 1]) {
6382 if (err)
6383 memprintf(err, "'%s' : missing verify method", args[cur_arg]);
6384 return ERR_ALERT | ERR_FATAL;
6385 }
6386
6387 if (strcmp(args[cur_arg + 1], "none") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01006388 conf->verify = SSL_SOCK_VERIFY_NONE;
Emeric Brund94b3fe2012-09-20 18:23:56 +02006389 else if (strcmp(args[cur_arg + 1], "optional") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01006390 conf->verify = SSL_SOCK_VERIFY_OPTIONAL;
Emeric Brund94b3fe2012-09-20 18:23:56 +02006391 else if (strcmp(args[cur_arg + 1], "required") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01006392 conf->verify = SSL_SOCK_VERIFY_REQUIRED;
Emeric Brund94b3fe2012-09-20 18:23:56 +02006393 else {
6394 if (err)
6395 memprintf(err, "'%s' : unknown verify method '%s', only 'none', 'optional', and 'required' are supported\n",
6396 args[cur_arg], args[cur_arg + 1]);
6397 return ERR_ALERT | ERR_FATAL;
6398 }
6399
6400 return 0;
6401}
Emmanuel Hocdet98263292016-12-29 18:26:15 +01006402static int bind_parse_verify(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
6403{
6404 return ssl_bind_parse_verify(args, cur_arg, px, &conf->ssl_conf, err);
6405}
Emeric Brund94b3fe2012-09-20 18:23:56 +02006406
Willy Tarreau92faadf2012-10-10 23:04:25 +02006407/************** "server" keywords ****************/
6408
Emeric Brunef42d922012-10-11 16:11:36 +02006409/* parse the "ca-file" server keyword */
6410static int srv_parse_ca_file(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
6411{
6412 if (!*args[*cur_arg + 1]) {
6413 if (err)
6414 memprintf(err, "'%s' : missing CAfile path", args[*cur_arg]);
6415 return ERR_ALERT | ERR_FATAL;
6416 }
6417
Willy Tarreauef934602016-12-22 23:12:01 +01006418 if ((*args[*cur_arg + 1] != '/') && global_ssl.ca_base)
6419 memprintf(&newsrv->ssl_ctx.ca_file, "%s/%s", global_ssl.ca_base, args[*cur_arg + 1]);
Emeric Brunef42d922012-10-11 16:11:36 +02006420 else
6421 memprintf(&newsrv->ssl_ctx.ca_file, "%s", args[*cur_arg + 1]);
6422
6423 return 0;
6424}
6425
Willy Tarreau92faadf2012-10-10 23:04:25 +02006426/* parse the "check-ssl" server keyword */
6427static int srv_parse_check_ssl(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
6428{
6429 newsrv->check.use_ssl = 1;
Willy Tarreauef934602016-12-22 23:12:01 +01006430 if (global_ssl.connect_default_ciphers && !newsrv->ssl_ctx.ciphers)
6431 newsrv->ssl_ctx.ciphers = strdup(global_ssl.connect_default_ciphers);
6432 newsrv->ssl_ctx.options |= global_ssl.connect_default_ssloptions;
Willy Tarreau92faadf2012-10-10 23:04:25 +02006433 return 0;
6434}
6435
6436/* parse the "ciphers" server keyword */
6437static int srv_parse_ciphers(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
6438{
6439 if (!*args[*cur_arg + 1]) {
6440 memprintf(err, "'%s' : missing cipher suite", args[*cur_arg]);
6441 return ERR_ALERT | ERR_FATAL;
6442 }
6443
6444 free(newsrv->ssl_ctx.ciphers);
6445 newsrv->ssl_ctx.ciphers = strdup(args[*cur_arg + 1]);
6446 return 0;
6447}
6448
Emeric Brunef42d922012-10-11 16:11:36 +02006449/* parse the "crl-file" server keyword */
6450static int srv_parse_crl_file(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
6451{
6452#ifndef X509_V_FLAG_CRL_CHECK
6453 if (err)
6454 memprintf(err, "'%s' : library does not support CRL verify", args[*cur_arg]);
6455 return ERR_ALERT | ERR_FATAL;
6456#else
6457 if (!*args[*cur_arg + 1]) {
6458 if (err)
6459 memprintf(err, "'%s' : missing CRLfile path", args[*cur_arg]);
6460 return ERR_ALERT | ERR_FATAL;
6461 }
6462
Willy Tarreauef934602016-12-22 23:12:01 +01006463 if ((*args[*cur_arg + 1] != '/') && global_ssl.ca_base)
6464 memprintf(&newsrv->ssl_ctx.crl_file, "%s/%s", global_ssl.ca_base, args[*cur_arg + 1]);
Emeric Brunef42d922012-10-11 16:11:36 +02006465 else
6466 memprintf(&newsrv->ssl_ctx.crl_file, "%s", args[*cur_arg + 1]);
6467
6468 return 0;
6469#endif
6470}
6471
Emeric Bruna7aa3092012-10-26 12:58:00 +02006472/* parse the "crt" server keyword */
6473static int srv_parse_crt(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
6474{
6475 if (!*args[*cur_arg + 1]) {
6476 if (err)
6477 memprintf(err, "'%s' : missing certificate file path", args[*cur_arg]);
6478 return ERR_ALERT | ERR_FATAL;
6479 }
6480
Willy Tarreauef934602016-12-22 23:12:01 +01006481 if ((*args[*cur_arg + 1] != '/') && global_ssl.crt_base)
6482 memprintf(&newsrv->ssl_ctx.client_crt, "%s/%s", global_ssl.ca_base, args[*cur_arg + 1]);
Emeric Bruna7aa3092012-10-26 12:58:00 +02006483 else
6484 memprintf(&newsrv->ssl_ctx.client_crt, "%s", args[*cur_arg + 1]);
6485
6486 return 0;
6487}
Emeric Brunef42d922012-10-11 16:11:36 +02006488
Willy Tarreau92faadf2012-10-10 23:04:25 +02006489/* parse the "force-sslv3" server keyword */
6490static int srv_parse_force_sslv3(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
6491{
Emmanuel Hocdet4de1ff12017-03-03 12:21:32 +01006492#ifndef OPENSSL_NO_SSL3
Willy Tarreau92faadf2012-10-10 23:04:25 +02006493 newsrv->ssl_ctx.options |= SRV_SSL_O_USE_SSLV3;
6494 return 0;
Emmanuel Hocdet4de1ff12017-03-03 12:21:32 +01006495#else
6496 if (err)
6497 memprintf(err, "'%s' : library does not support protocol SSLv3", args[*cur_arg]);
6498 return ERR_ALERT | ERR_FATAL;
6499#endif
Willy Tarreau92faadf2012-10-10 23:04:25 +02006500}
6501
6502/* parse the "force-tlsv10" server keyword */
6503static int srv_parse_force_tlsv10(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
6504{
6505 newsrv->ssl_ctx.options |= SRV_SSL_O_USE_TLSV10;
6506 return 0;
6507}
6508
6509/* parse the "force-tlsv11" server keyword */
6510static int srv_parse_force_tlsv11(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
6511{
6512#if SSL_OP_NO_TLSv1_1
6513 newsrv->ssl_ctx.options |= SRV_SSL_O_USE_TLSV11;
6514 return 0;
6515#else
6516 if (err)
6517 memprintf(err, "'%s' : library does not support protocol TLSv1.1", args[*cur_arg]);
6518 return ERR_ALERT | ERR_FATAL;
6519#endif
6520}
6521
6522/* parse the "force-tlsv12" server keyword */
6523static int srv_parse_force_tlsv12(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
6524{
6525#if SSL_OP_NO_TLSv1_2
6526 newsrv->ssl_ctx.options |= SRV_SSL_O_USE_TLSV12;
6527 return 0;
6528#else
6529 if (err)
6530 memprintf(err, "'%s' : library does not support protocol TLSv1.2", args[*cur_arg]);
6531 return ERR_ALERT | ERR_FATAL;
6532#endif
6533}
6534
Willy Tarreau2a3fb1c2015-02-05 16:47:07 +01006535/* parse the "no-ssl-reuse" server keyword */
6536static int srv_parse_no_ssl_reuse(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
6537{
6538 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_REUSE;
6539 return 0;
6540}
6541
Willy Tarreau92faadf2012-10-10 23:04:25 +02006542/* parse the "no-sslv3" server keyword */
6543static int srv_parse_no_sslv3(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
6544{
6545 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_SSLV3;
6546 return 0;
6547}
6548
6549/* parse the "no-tlsv10" server keyword */
6550static int srv_parse_no_tlsv10(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
6551{
6552 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_TLSV10;
6553 return 0;
6554}
6555
6556/* parse the "no-tlsv11" server keyword */
6557static int srv_parse_no_tlsv11(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
6558{
6559 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_TLSV11;
6560 return 0;
6561}
6562
6563/* parse the "no-tlsv12" server keyword */
6564static int srv_parse_no_tlsv12(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
6565{
6566 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_TLSV12;
6567 return 0;
6568}
6569
Emeric Brunf9c5c472012-10-11 15:28:34 +02006570/* parse the "no-tls-tickets" server keyword */
6571static int srv_parse_no_tls_tickets(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
6572{
6573 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_TLS_TICKETS;
6574 return 0;
6575}
David Safb76832014-05-08 23:42:08 -04006576/* parse the "send-proxy-v2-ssl" server keyword */
6577static int srv_parse_send_proxy_ssl(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
6578{
6579 newsrv->pp_opts |= SRV_PP_V2;
6580 newsrv->pp_opts |= SRV_PP_V2_SSL;
6581 return 0;
6582}
6583
6584/* parse the "send-proxy-v2-ssl-cn" server keyword */
6585static int srv_parse_send_proxy_cn(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
6586{
6587 newsrv->pp_opts |= SRV_PP_V2;
6588 newsrv->pp_opts |= SRV_PP_V2_SSL;
6589 newsrv->pp_opts |= SRV_PP_V2_SSL_CN;
6590 return 0;
6591}
Emeric Brunf9c5c472012-10-11 15:28:34 +02006592
Willy Tarreau732eac42015-07-09 11:40:25 +02006593/* parse the "sni" server keyword */
6594static int srv_parse_sni(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
6595{
6596#ifndef SSL_CTRL_SET_TLSEXT_HOSTNAME
6597 memprintf(err, "'%s' : the current SSL library doesn't support the SNI TLS extension", args[*cur_arg]);
6598 return ERR_ALERT | ERR_FATAL;
6599#else
Cyril Bonté23d19d62016-03-07 22:13:22 +01006600 int idx;
Willy Tarreau732eac42015-07-09 11:40:25 +02006601 struct sample_expr *expr;
6602
6603 if (!*args[*cur_arg + 1]) {
6604 memprintf(err, "'%s' : missing sni expression", args[*cur_arg]);
6605 return ERR_ALERT | ERR_FATAL;
6606 }
6607
Cyril Bonté23d19d62016-03-07 22:13:22 +01006608 idx = (*cur_arg) + 1;
Willy Tarreau732eac42015-07-09 11:40:25 +02006609 proxy->conf.args.ctx = ARGC_SRV;
6610
Cyril Bonté23d19d62016-03-07 22:13:22 +01006611 expr = sample_parse_expr((char **)args, &idx, px->conf.file, px->conf.line, err, &proxy->conf.args);
Willy Tarreau732eac42015-07-09 11:40:25 +02006612 if (!expr) {
6613 memprintf(err, "error detected while parsing sni expression : %s", *err);
6614 return ERR_ALERT | ERR_FATAL;
6615 }
6616
6617 if (!(expr->fetch->val & SMP_VAL_BE_SRV_CON)) {
6618 memprintf(err, "error detected while parsing sni expression : "
6619 " fetch method '%s' extracts information from '%s', none of which is available here.\n",
Cyril Bonté23d19d62016-03-07 22:13:22 +01006620 args[idx-1], sample_src_names(expr->fetch->use));
Willy Tarreau732eac42015-07-09 11:40:25 +02006621 return ERR_ALERT | ERR_FATAL;
6622 }
6623
6624 px->http_needed |= !!(expr->fetch->use & SMP_USE_HTTP_ANY);
6625 newsrv->ssl_ctx.sni = expr;
6626 return 0;
6627#endif
6628}
6629
Willy Tarreau92faadf2012-10-10 23:04:25 +02006630/* parse the "ssl" server keyword */
6631static int srv_parse_ssl(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
6632{
6633 newsrv->use_ssl = 1;
Willy Tarreauef934602016-12-22 23:12:01 +01006634 if (global_ssl.connect_default_ciphers && !newsrv->ssl_ctx.ciphers)
6635 newsrv->ssl_ctx.ciphers = strdup(global_ssl.connect_default_ciphers);
Willy Tarreau92faadf2012-10-10 23:04:25 +02006636 return 0;
6637}
6638
Emeric Brunef42d922012-10-11 16:11:36 +02006639/* parse the "verify" server keyword */
6640static int srv_parse_verify(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
6641{
6642 if (!*args[*cur_arg + 1]) {
6643 if (err)
6644 memprintf(err, "'%s' : missing verify method", args[*cur_arg]);
6645 return ERR_ALERT | ERR_FATAL;
6646 }
6647
6648 if (strcmp(args[*cur_arg + 1], "none") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01006649 newsrv->ssl_ctx.verify = SSL_SOCK_VERIFY_NONE;
Emeric Brunef42d922012-10-11 16:11:36 +02006650 else if (strcmp(args[*cur_arg + 1], "required") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01006651 newsrv->ssl_ctx.verify = SSL_SOCK_VERIFY_REQUIRED;
Emeric Brunef42d922012-10-11 16:11:36 +02006652 else {
6653 if (err)
6654 memprintf(err, "'%s' : unknown verify method '%s', only 'none' and 'required' are supported\n",
6655 args[*cur_arg], args[*cur_arg + 1]);
6656 return ERR_ALERT | ERR_FATAL;
6657 }
6658
Evan Broderbe554312013-06-27 00:05:25 -07006659 return 0;
6660}
6661
6662/* parse the "verifyhost" server keyword */
6663static int srv_parse_verifyhost(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
6664{
6665 if (!*args[*cur_arg + 1]) {
6666 if (err)
6667 memprintf(err, "'%s' : missing hostname to verify against", args[*cur_arg]);
6668 return ERR_ALERT | ERR_FATAL;
6669 }
6670
6671 newsrv->ssl_ctx.verify_host = strdup(args[*cur_arg + 1]);
6672
Emeric Brunef42d922012-10-11 16:11:36 +02006673 return 0;
6674}
6675
Emeric Brun2c86cbf2014-10-30 15:56:50 +01006676/* parse the "ssl-default-bind-options" keyword in global section */
6677static int ssl_parse_default_bind_options(char **args, int section_type, struct proxy *curpx,
6678 struct proxy *defpx, const char *file, int line,
6679 char **err) {
6680 int i = 1;
6681
6682 if (*(args[i]) == 0) {
6683 memprintf(err, "global statement '%s' expects an option as an argument.", args[0]);
6684 return -1;
6685 }
6686 while (*(args[i])) {
6687 if (!strcmp(args[i], "no-sslv3"))
Willy Tarreauef934602016-12-22 23:12:01 +01006688 global_ssl.listen_default_ssloptions |= BC_SSL_O_NO_SSLV3;
Emeric Brun2c86cbf2014-10-30 15:56:50 +01006689 else if (!strcmp(args[i], "no-tlsv10"))
Willy Tarreauef934602016-12-22 23:12:01 +01006690 global_ssl.listen_default_ssloptions |= BC_SSL_O_NO_TLSV10;
Emeric Brun2c86cbf2014-10-30 15:56:50 +01006691 else if (!strcmp(args[i], "no-tlsv11"))
Willy Tarreauef934602016-12-22 23:12:01 +01006692 global_ssl.listen_default_ssloptions |= BC_SSL_O_NO_TLSV11;
Emeric Brun2c86cbf2014-10-30 15:56:50 +01006693 else if (!strcmp(args[i], "no-tlsv12"))
Willy Tarreauef934602016-12-22 23:12:01 +01006694 global_ssl.listen_default_ssloptions |= BC_SSL_O_NO_TLSV12;
Emeric Brun2c86cbf2014-10-30 15:56:50 +01006695 else if (!strcmp(args[i], "force-sslv3"))
Willy Tarreauef934602016-12-22 23:12:01 +01006696 global_ssl.listen_default_ssloptions |= BC_SSL_O_USE_SSLV3;
Emeric Brun2c86cbf2014-10-30 15:56:50 +01006697 else if (!strcmp(args[i], "force-tlsv10"))
Willy Tarreauef934602016-12-22 23:12:01 +01006698 global_ssl.listen_default_ssloptions |= BC_SSL_O_USE_TLSV10;
Emeric Brun2c86cbf2014-10-30 15:56:50 +01006699 else if (!strcmp(args[i], "force-tlsv11")) {
6700#if SSL_OP_NO_TLSv1_1
Willy Tarreauef934602016-12-22 23:12:01 +01006701 global_ssl.listen_default_ssloptions |= BC_SSL_O_USE_TLSV11;
Emeric Brun2c86cbf2014-10-30 15:56:50 +01006702#else
6703 memprintf(err, "'%s' '%s': library does not support protocol TLSv1.1", args[0], args[i]);
6704 return -1;
6705#endif
6706 }
6707 else if (!strcmp(args[i], "force-tlsv12")) {
6708#if SSL_OP_NO_TLSv1_2
Willy Tarreauef934602016-12-22 23:12:01 +01006709 global_ssl.listen_default_ssloptions |= BC_SSL_O_USE_TLSV12;
Emeric Brun2c86cbf2014-10-30 15:56:50 +01006710#else
6711 memprintf(err, "'%s' '%s': library does not support protocol TLSv1.2", args[0], args[i]);
6712 return -1;
6713#endif
6714 }
6715 else if (!strcmp(args[i], "no-tls-tickets"))
Willy Tarreauef934602016-12-22 23:12:01 +01006716 global_ssl.listen_default_ssloptions |= BC_SSL_O_NO_TLS_TICKETS;
Emeric Brun2c86cbf2014-10-30 15:56:50 +01006717 else {
6718 memprintf(err, "unknown option '%s' on global statement '%s'.", args[i], args[0]);
6719 return -1;
6720 }
6721 i++;
6722 }
6723 return 0;
6724}
6725
6726/* parse the "ssl-default-server-options" keyword in global section */
6727static int ssl_parse_default_server_options(char **args, int section_type, struct proxy *curpx,
6728 struct proxy *defpx, const char *file, int line,
6729 char **err) {
6730 int i = 1;
6731
6732 if (*(args[i]) == 0) {
6733 memprintf(err, "global statement '%s' expects an option as an argument.", args[0]);
6734 return -1;
6735 }
6736 while (*(args[i])) {
6737 if (!strcmp(args[i], "no-sslv3"))
Willy Tarreauef934602016-12-22 23:12:01 +01006738 global_ssl.connect_default_ssloptions |= SRV_SSL_O_NO_SSLV3;
Emeric Brun2c86cbf2014-10-30 15:56:50 +01006739 else if (!strcmp(args[i], "no-tlsv10"))
Willy Tarreauef934602016-12-22 23:12:01 +01006740 global_ssl.connect_default_ssloptions |= SRV_SSL_O_NO_TLSV10;
Emeric Brun2c86cbf2014-10-30 15:56:50 +01006741 else if (!strcmp(args[i], "no-tlsv11"))
Willy Tarreauef934602016-12-22 23:12:01 +01006742 global_ssl.connect_default_ssloptions |= SRV_SSL_O_NO_TLSV11;
Emeric Brun2c86cbf2014-10-30 15:56:50 +01006743 else if (!strcmp(args[i], "no-tlsv12"))
Willy Tarreauef934602016-12-22 23:12:01 +01006744 global_ssl.connect_default_ssloptions |= SRV_SSL_O_NO_TLSV12;
Emeric Brun2c86cbf2014-10-30 15:56:50 +01006745 else if (!strcmp(args[i], "force-sslv3"))
Willy Tarreauef934602016-12-22 23:12:01 +01006746 global_ssl.connect_default_ssloptions |= SRV_SSL_O_USE_SSLV3;
Emeric Brun2c86cbf2014-10-30 15:56:50 +01006747 else if (!strcmp(args[i], "force-tlsv10"))
Willy Tarreauef934602016-12-22 23:12:01 +01006748 global_ssl.connect_default_ssloptions |= SRV_SSL_O_USE_TLSV10;
Emeric Brun2c86cbf2014-10-30 15:56:50 +01006749 else if (!strcmp(args[i], "force-tlsv11")) {
6750#if SSL_OP_NO_TLSv1_1
Willy Tarreauef934602016-12-22 23:12:01 +01006751 global_ssl.connect_default_ssloptions |= SRV_SSL_O_USE_TLSV11;
Emeric Brun2c86cbf2014-10-30 15:56:50 +01006752#else
6753 memprintf(err, "'%s' '%s': library does not support protocol TLSv1.1", args[0], args[i]);
6754 return -1;
6755#endif
6756 }
6757 else if (!strcmp(args[i], "force-tlsv12")) {
6758#if SSL_OP_NO_TLSv1_2
Willy Tarreauef934602016-12-22 23:12:01 +01006759 global_ssl.connect_default_ssloptions |= SRV_SSL_O_USE_TLSV12;
Emeric Brun2c86cbf2014-10-30 15:56:50 +01006760#else
6761 memprintf(err, "'%s' '%s': library does not support protocol TLSv1.2", args[0], args[i]);
6762 return -1;
6763#endif
6764 }
6765 else if (!strcmp(args[i], "no-tls-tickets"))
Willy Tarreauef934602016-12-22 23:12:01 +01006766 global_ssl.connect_default_ssloptions |= SRV_SSL_O_NO_TLS_TICKETS;
Emeric Brun2c86cbf2014-10-30 15:56:50 +01006767 else {
6768 memprintf(err, "unknown option '%s' on global statement '%s'.", args[i], args[0]);
6769 return -1;
6770 }
6771 i++;
6772 }
6773 return 0;
6774}
6775
Willy Tarreau8c3b0fd2016-12-21 22:44:46 +01006776/* parse the "ca-base" / "crt-base" keywords in global section.
6777 * Returns <0 on alert, >0 on warning, 0 on success.
6778 */
6779static int ssl_parse_global_ca_crt_base(char **args, int section_type, struct proxy *curpx,
6780 struct proxy *defpx, const char *file, int line,
6781 char **err)
6782{
6783 char **target;
6784
Willy Tarreauef934602016-12-22 23:12:01 +01006785 target = (args[0][1] == 'a') ? &global_ssl.ca_base : &global_ssl.crt_base;
Willy Tarreau8c3b0fd2016-12-21 22:44:46 +01006786
6787 if (too_many_args(1, args, err, NULL))
6788 return -1;
6789
6790 if (*target) {
6791 memprintf(err, "'%s' already specified.", args[0]);
6792 return -1;
6793 }
6794
6795 if (*(args[1]) == 0) {
6796 memprintf(err, "global statement '%s' expects a directory path as an argument.", args[0]);
6797 return -1;
6798 }
6799 *target = strdup(args[1]);
6800 return 0;
6801}
6802
Willy Tarreauf22e9682016-12-21 23:23:19 +01006803/* parse the "ssl-default-bind-ciphers" / "ssl-default-server-ciphers" keywords
6804 * in global section. Returns <0 on alert, >0 on warning, 0 on success.
6805 */
6806static int ssl_parse_global_ciphers(char **args, int section_type, struct proxy *curpx,
6807 struct proxy *defpx, const char *file, int line,
6808 char **err)
6809{
6810 char **target;
6811
Willy Tarreauef934602016-12-22 23:12:01 +01006812 target = (args[0][12] == 'b') ? &global_ssl.listen_default_ciphers : &global_ssl.connect_default_ciphers;
Willy Tarreauf22e9682016-12-21 23:23:19 +01006813
6814 if (too_many_args(1, args, err, NULL))
6815 return -1;
6816
6817 if (*(args[1]) == 0) {
6818 memprintf(err, "global statement '%s' expects a cipher suite as an argument.", args[0]);
6819 return -1;
6820 }
6821
6822 free(*target);
6823 *target = strdup(args[1]);
6824 return 0;
6825}
6826
Willy Tarreau9ceda382016-12-21 23:13:03 +01006827/* parse various global tune.ssl settings consisting in positive integers.
6828 * Returns <0 on alert, >0 on warning, 0 on success.
6829 */
6830static int ssl_parse_global_int(char **args, int section_type, struct proxy *curpx,
6831 struct proxy *defpx, const char *file, int line,
6832 char **err)
6833{
6834 int *target;
6835
6836 if (strcmp(args[0], "tune.ssl.cachesize") == 0)
6837 target = &global.tune.sslcachesize;
6838 else if (strcmp(args[0], "tune.ssl.maxrecord") == 0)
Willy Tarreauef934602016-12-22 23:12:01 +01006839 target = (int *)&global_ssl.max_record;
Willy Tarreau9ceda382016-12-21 23:13:03 +01006840 else if (strcmp(args[0], "tune.ssl.ssl-ctx-cache-size") == 0)
Willy Tarreauef934602016-12-22 23:12:01 +01006841 target = &global_ssl.ctx_cache;
Willy Tarreau0bea58d2016-12-21 23:17:25 +01006842 else if (strcmp(args[0], "maxsslconn") == 0)
6843 target = &global.maxsslconn;
Thierry FOURNIER5bf77322017-02-25 12:45:22 +01006844 else if (strcmp(args[0], "tune.ssl.capture-cipherlist-size") == 0)
6845 target = &global_ssl.capture_cipherlist;
Willy Tarreau9ceda382016-12-21 23:13:03 +01006846 else {
6847 memprintf(err, "'%s' keyword not unhandled (please report this bug).", args[0]);
6848 return -1;
6849 }
6850
6851 if (too_many_args(1, args, err, NULL))
6852 return -1;
6853
6854 if (*(args[1]) == 0) {
6855 memprintf(err, "'%s' expects an integer argument.", args[0]);
6856 return -1;
6857 }
6858
6859 *target = atoi(args[1]);
6860 if (*target < 0) {
6861 memprintf(err, "'%s' expects a positive numeric value.", args[0]);
6862 return -1;
6863 }
6864 return 0;
Thierry FOURNIER5bf77322017-02-25 12:45:22 +01006865}
6866
6867static int ssl_parse_global_capture_cipherlist(char **args, int section_type, struct proxy *curpx,
6868 struct proxy *defpx, const char *file, int line,
6869 char **err)
6870{
Thierry FOURNIER5bf77322017-02-25 12:45:22 +01006871 int ret;
6872
6873 ret = ssl_parse_global_int(args, section_type, curpx, defpx, file, line, err);
6874 if (ret != 0)
6875 return ret;
6876
6877 if (pool2_ssl_capture) {
6878 memprintf(err, "'%s' is already configured.", args[0]);
6879 return -1;
6880 }
6881
6882 pool2_ssl_capture = create_pool("ssl-capture", sizeof(struct ssl_capture) + global_ssl.capture_cipherlist, MEM_F_SHARED);
6883 if (!pool2_ssl_capture) {
6884 memprintf(err, "Out of memory error.");
6885 return -1;
6886 }
6887 return 0;
Willy Tarreau9ceda382016-12-21 23:13:03 +01006888}
6889
6890/* parse "ssl.force-private-cache".
6891 * Returns <0 on alert, >0 on warning, 0 on success.
6892 */
6893static int ssl_parse_global_private_cache(char **args, int section_type, struct proxy *curpx,
6894 struct proxy *defpx, const char *file, int line,
6895 char **err)
6896{
6897 if (too_many_args(0, args, err, NULL))
6898 return -1;
6899
Willy Tarreauef934602016-12-22 23:12:01 +01006900 global_ssl.private_cache = 1;
Willy Tarreau9ceda382016-12-21 23:13:03 +01006901 return 0;
6902}
6903
6904/* parse "ssl.lifetime".
6905 * Returns <0 on alert, >0 on warning, 0 on success.
6906 */
6907static int ssl_parse_global_lifetime(char **args, int section_type, struct proxy *curpx,
6908 struct proxy *defpx, const char *file, int line,
6909 char **err)
6910{
6911 const char *res;
6912
6913 if (too_many_args(1, args, err, NULL))
6914 return -1;
6915
6916 if (*(args[1]) == 0) {
6917 memprintf(err, "'%s' expects ssl sessions <lifetime> in seconds as argument.", args[0]);
6918 return -1;
6919 }
6920
Willy Tarreauef934602016-12-22 23:12:01 +01006921 res = parse_time_err(args[1], &global_ssl.life_time, TIME_UNIT_S);
Willy Tarreau9ceda382016-12-21 23:13:03 +01006922 if (res) {
6923 memprintf(err, "unexpected character '%c' in argument to <%s>.", *res, args[0]);
6924 return -1;
6925 }
6926 return 0;
6927}
6928
6929#ifndef OPENSSL_NO_DH
Willy Tarreau14e36a12016-12-21 23:28:13 +01006930/* parse "ssl-dh-param-file".
6931 * Returns <0 on alert, >0 on warning, 0 on success.
6932 */
6933static int ssl_parse_global_dh_param_file(char **args, int section_type, struct proxy *curpx,
6934 struct proxy *defpx, const char *file, int line,
6935 char **err)
6936{
6937 if (too_many_args(1, args, err, NULL))
6938 return -1;
6939
6940 if (*(args[1]) == 0) {
6941 memprintf(err, "'%s' expects a file path as an argument.", args[0]);
6942 return -1;
6943 }
6944
6945 if (ssl_sock_load_global_dh_param_from_file(args[1])) {
6946 memprintf(err, "'%s': unable to load DH parameters from file <%s>.", args[0], args[1]);
6947 return -1;
6948 }
6949 return 0;
6950}
6951
Willy Tarreau9ceda382016-12-21 23:13:03 +01006952/* parse "ssl.default-dh-param".
6953 * Returns <0 on alert, >0 on warning, 0 on success.
6954 */
6955static int ssl_parse_global_default_dh(char **args, int section_type, struct proxy *curpx,
6956 struct proxy *defpx, const char *file, int line,
6957 char **err)
6958{
6959 if (too_many_args(1, args, err, NULL))
6960 return -1;
6961
6962 if (*(args[1]) == 0) {
6963 memprintf(err, "'%s' expects an integer argument.", args[0]);
6964 return -1;
6965 }
6966
Willy Tarreauef934602016-12-22 23:12:01 +01006967 global_ssl.default_dh_param = atoi(args[1]);
6968 if (global_ssl.default_dh_param < 1024) {
Willy Tarreau9ceda382016-12-21 23:13:03 +01006969 memprintf(err, "'%s' expects a value >= 1024.", args[0]);
6970 return -1;
6971 }
6972 return 0;
6973}
6974#endif
6975
6976
William Lallemand32af2032016-10-29 18:09:35 +02006977/* This function is used with TLS ticket keys management. It permits to browse
6978 * each reference. The variable <getnext> must contain the current node,
6979 * <end> point to the root node.
6980 */
6981#if (defined SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB && TLS_TICKETS_NO > 0)
6982static inline
6983struct tls_keys_ref *tlskeys_list_get_next(struct tls_keys_ref *getnext, struct list *end)
6984{
6985 struct tls_keys_ref *ref = getnext;
6986
6987 while (1) {
6988
6989 /* Get next list entry. */
6990 ref = LIST_NEXT(&ref->list, struct tls_keys_ref *, list);
6991
6992 /* If the entry is the last of the list, return NULL. */
6993 if (&ref->list == end)
6994 return NULL;
6995
6996 return ref;
6997 }
6998}
6999
7000static inline
7001struct tls_keys_ref *tlskeys_ref_lookup_ref(const char *reference)
7002{
7003 int id;
7004 char *error;
7005
7006 /* If the reference starts by a '#', this is numeric id. */
7007 if (reference[0] == '#') {
7008 /* Try to convert the numeric id. If the conversion fails, the lookup fails. */
7009 id = strtol(reference + 1, &error, 10);
7010 if (*error != '\0')
7011 return NULL;
7012
7013 /* Perform the unique id lookup. */
7014 return tlskeys_ref_lookupid(id);
7015 }
7016
7017 /* Perform the string lookup. */
7018 return tlskeys_ref_lookup(reference);
7019}
7020#endif
7021
7022
7023#if (defined SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB && TLS_TICKETS_NO > 0)
7024
7025static int cli_io_handler_tlskeys_files(struct appctx *appctx);
7026
7027static inline int cli_io_handler_tlskeys_entries(struct appctx *appctx) {
7028 return cli_io_handler_tlskeys_files(appctx);
7029}
7030
Willy Tarreauf5f26e82016-12-16 18:47:27 +01007031/* dumps all tls keys. Relies on cli.i0 (non-null = only list file names), cli.i1
7032 * (next index to be dumped), and cli.p0 (next key reference).
7033 */
William Lallemand32af2032016-10-29 18:09:35 +02007034static int cli_io_handler_tlskeys_files(struct appctx *appctx) {
7035
7036 struct stream_interface *si = appctx->owner;
7037
7038 switch (appctx->st2) {
7039 case STAT_ST_INIT:
7040 /* Display the column headers. If the message cannot be sent,
7041 * quit the fucntion with returning 0. The function is called
7042 * later and restart at the state "STAT_ST_INIT".
7043 */
7044 chunk_reset(&trash);
7045
7046 if (appctx->io_handler == cli_io_handler_tlskeys_entries)
7047 chunk_appendf(&trash, "# id secret\n");
7048 else
7049 chunk_appendf(&trash, "# id (file)\n");
7050
7051 if (bi_putchk(si_ic(si), &trash) == -1) {
7052 si_applet_cant_put(si);
7053 return 0;
7054 }
7055
William Lallemand32af2032016-10-29 18:09:35 +02007056 /* Now, we start the browsing of the references lists.
7057 * Note that the following call to LIST_ELEM return bad pointer. The only
7058 * available field of this pointer is <list>. It is used with the function
7059 * tlskeys_list_get_next() for retruning the first available entry
7060 */
Willy Tarreauf5f26e82016-12-16 18:47:27 +01007061 if (appctx->ctx.cli.p0 == NULL) {
7062 appctx->ctx.cli.p0 = LIST_ELEM(&tlskeys_reference, struct tls_keys_ref *, list);
7063 appctx->ctx.cli.p0 = tlskeys_list_get_next(appctx->ctx.cli.p0, &tlskeys_reference);
William Lallemand32af2032016-10-29 18:09:35 +02007064 }
7065
7066 appctx->st2 = STAT_ST_LIST;
7067 /* fall through */
7068
7069 case STAT_ST_LIST:
Willy Tarreauf5f26e82016-12-16 18:47:27 +01007070 while (appctx->ctx.cli.p0) {
7071 struct tls_keys_ref *ref = appctx->ctx.cli.p0;
7072 int head = ref->tls_ticket_enc_index;
William Lallemand32af2032016-10-29 18:09:35 +02007073
7074 chunk_reset(&trash);
Willy Tarreauf5f26e82016-12-16 18:47:27 +01007075 if (appctx->io_handler == cli_io_handler_tlskeys_entries && appctx->ctx.cli.i1 == 0)
William Lallemand32af2032016-10-29 18:09:35 +02007076 chunk_appendf(&trash, "# ");
Willy Tarreauf5f26e82016-12-16 18:47:27 +01007077
7078 if (appctx->ctx.cli.i1 == 0)
7079 chunk_appendf(&trash, "%d (%s)\n", ref->unique_id, ref->filename);
7080
William Lallemand32af2032016-10-29 18:09:35 +02007081 if (appctx->io_handler == cli_io_handler_tlskeys_entries) {
Willy Tarreauf5f26e82016-12-16 18:47:27 +01007082 while (appctx->ctx.cli.i1 < TLS_TICKETS_NO) {
William Lallemand32af2032016-10-29 18:09:35 +02007083 struct chunk *t2 = get_trash_chunk();
7084
7085 chunk_reset(t2);
7086 /* should never fail here because we dump only a key in the t2 buffer */
Willy Tarreauf5f26e82016-12-16 18:47:27 +01007087 t2->len = a2base64((char *)(ref->tlskeys + (head + 2 + appctx->ctx.cli.i1) % TLS_TICKETS_NO),
William Lallemand32af2032016-10-29 18:09:35 +02007088 sizeof(struct tls_sess_key), t2->str, t2->size);
Willy Tarreauf5f26e82016-12-16 18:47:27 +01007089 chunk_appendf(&trash, "%d.%d %s\n", ref->unique_id, appctx->ctx.cli.i1, t2->str);
William Lallemand32af2032016-10-29 18:09:35 +02007090
7091 if (bi_putchk(si_ic(si), &trash) == -1) {
7092 /* let's try again later from this stream. We add ourselves into
7093 * this stream's users so that it can remove us upon termination.
7094 */
7095 si_applet_cant_put(si);
7096 return 0;
7097 }
Willy Tarreauf5f26e82016-12-16 18:47:27 +01007098 appctx->ctx.cli.i1++;
William Lallemand32af2032016-10-29 18:09:35 +02007099 }
Willy Tarreauf5f26e82016-12-16 18:47:27 +01007100 appctx->ctx.cli.i1 = 0;
William Lallemand32af2032016-10-29 18:09:35 +02007101 }
7102 if (bi_putchk(si_ic(si), &trash) == -1) {
7103 /* let's try again later from this stream. We add ourselves into
7104 * this stream's users so that it can remove us upon termination.
7105 */
7106 si_applet_cant_put(si);
7107 return 0;
7108 }
7109
Willy Tarreauf5f26e82016-12-16 18:47:27 +01007110 if (appctx->ctx.cli.i0 == 0) /* don't display everything if not necessary */
William Lallemand32af2032016-10-29 18:09:35 +02007111 break;
7112
7113 /* get next list entry and check the end of the list */
Willy Tarreauf5f26e82016-12-16 18:47:27 +01007114 appctx->ctx.cli.p0 = tlskeys_list_get_next(appctx->ctx.cli.p0, &tlskeys_reference);
William Lallemand32af2032016-10-29 18:09:35 +02007115 }
7116
7117 appctx->st2 = STAT_ST_FIN;
7118 /* fall through */
7119
7120 default:
7121 appctx->st2 = STAT_ST_FIN;
7122 return 1;
7123 }
7124 return 0;
7125}
7126
Willy Tarreauf5f26e82016-12-16 18:47:27 +01007127/* sets cli.i0 to non-zero if only file lists should be dumped */
William Lallemand32af2032016-10-29 18:09:35 +02007128static int cli_parse_show_tlskeys(char **args, struct appctx *appctx, void *private)
7129{
William Lallemand32af2032016-10-29 18:09:35 +02007130 /* no parameter, shows only file list */
7131 if (!*args[2]) {
Willy Tarreauf5f26e82016-12-16 18:47:27 +01007132 appctx->ctx.cli.i0 = 1;
William Lallemand32af2032016-10-29 18:09:35 +02007133 appctx->io_handler = cli_io_handler_tlskeys_files;
Willy Tarreau3067bfa2016-12-05 14:50:15 +01007134 return 0;
William Lallemand32af2032016-10-29 18:09:35 +02007135 }
7136
7137 if (args[2][0] == '*') {
7138 /* list every TLS ticket keys */
Willy Tarreauf5f26e82016-12-16 18:47:27 +01007139 appctx->ctx.cli.i0 = 1;
William Lallemand32af2032016-10-29 18:09:35 +02007140 } else {
Willy Tarreauf5f26e82016-12-16 18:47:27 +01007141 appctx->ctx.cli.p0 = tlskeys_ref_lookup_ref(args[2]);
7142 if (!appctx->ctx.cli.p0) {
William Lallemand32af2032016-10-29 18:09:35 +02007143 appctx->ctx.cli.msg = "'show tls-keys' unable to locate referenced filename\n";
Willy Tarreau3b6e5472016-11-24 15:53:53 +01007144 appctx->st0 = CLI_ST_PRINT;
William Lallemand32af2032016-10-29 18:09:35 +02007145 return 1;
7146 }
7147 }
William Lallemand32af2032016-10-29 18:09:35 +02007148 appctx->io_handler = cli_io_handler_tlskeys_entries;
Willy Tarreau3067bfa2016-12-05 14:50:15 +01007149 return 0;
William Lallemand32af2032016-10-29 18:09:35 +02007150}
7151
William Lallemand32af2032016-10-29 18:09:35 +02007152static int cli_parse_set_tlskeys(char **args, struct appctx *appctx, void *private)
7153{
Willy Tarreauf5f26e82016-12-16 18:47:27 +01007154 struct tls_keys_ref *ref;
7155
William Lallemand32af2032016-10-29 18:09:35 +02007156 /* Expect two parameters: the filename and the new new TLS key in encoding */
7157 if (!*args[3] || !*args[4]) {
7158 appctx->ctx.cli.msg = "'set ssl tls-key' expects a filename and the new TLS key in base64 encoding.\n";
Willy Tarreau3b6e5472016-11-24 15:53:53 +01007159 appctx->st0 = CLI_ST_PRINT;
William Lallemand32af2032016-10-29 18:09:35 +02007160 return 1;
7161 }
7162
Willy Tarreauf5f26e82016-12-16 18:47:27 +01007163 ref = tlskeys_ref_lookup_ref(args[3]);
7164 if (!ref) {
William Lallemand32af2032016-10-29 18:09:35 +02007165 appctx->ctx.cli.msg = "'set ssl tls-key' unable to locate referenced filename\n";
Willy Tarreau3b6e5472016-11-24 15:53:53 +01007166 appctx->st0 = CLI_ST_PRINT;
William Lallemand32af2032016-10-29 18:09:35 +02007167 return 1;
7168 }
7169
7170 trash.len = base64dec(args[4], strlen(args[4]), trash.str, trash.size);
7171 if (trash.len != sizeof(struct tls_sess_key)) {
7172 appctx->ctx.cli.msg = "'set ssl tls-key' received invalid base64 encoded TLS key.\n";
Willy Tarreau3b6e5472016-11-24 15:53:53 +01007173 appctx->st0 = CLI_ST_PRINT;
William Lallemand32af2032016-10-29 18:09:35 +02007174 return 1;
7175 }
7176
Willy Tarreauf5f26e82016-12-16 18:47:27 +01007177 memcpy(ref->tlskeys + ((ref->tls_ticket_enc_index + 2) % TLS_TICKETS_NO), trash.str, trash.len);
7178 ref->tls_ticket_enc_index = (ref->tls_ticket_enc_index + 1) % TLS_TICKETS_NO;
William Lallemand32af2032016-10-29 18:09:35 +02007179
7180 appctx->ctx.cli.msg = "TLS ticket key updated!";
Willy Tarreau3b6e5472016-11-24 15:53:53 +01007181 appctx->st0 = CLI_ST_PRINT;
William Lallemand32af2032016-10-29 18:09:35 +02007182 return 1;
7183
7184}
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +01007185#endif
William Lallemand32af2032016-10-29 18:09:35 +02007186
7187static int cli_parse_set_ocspresponse(char **args, struct appctx *appctx, void *private)
7188{
7189#if (defined SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB && !defined OPENSSL_NO_OCSP)
7190 char *err = NULL;
7191
7192 /* Expect one parameter: the new response in base64 encoding */
7193 if (!*args[3]) {
7194 appctx->ctx.cli.msg = "'set ssl ocsp-response' expects response in base64 encoding.\n";
Willy Tarreau3b6e5472016-11-24 15:53:53 +01007195 appctx->st0 = CLI_ST_PRINT;
William Lallemand32af2032016-10-29 18:09:35 +02007196 return 1;
7197 }
7198
7199 trash.len = base64dec(args[3], strlen(args[3]), trash.str, trash.size);
7200 if (trash.len < 0) {
7201 appctx->ctx.cli.msg = "'set ssl ocsp-response' received invalid base64 encoded response.\n";
Willy Tarreau3b6e5472016-11-24 15:53:53 +01007202 appctx->st0 = CLI_ST_PRINT;
William Lallemand32af2032016-10-29 18:09:35 +02007203 return 1;
7204 }
7205
7206 if (ssl_sock_update_ocsp_response(&trash, &err)) {
7207 if (err) {
7208 memprintf(&err, "%s.\n", err);
7209 appctx->ctx.cli.err = err;
Willy Tarreau3b6e5472016-11-24 15:53:53 +01007210 appctx->st0 = CLI_ST_PRINT_FREE;
William Lallemand32af2032016-10-29 18:09:35 +02007211 }
7212 return 1;
7213 }
7214 appctx->ctx.cli.msg = "OCSP Response updated!";
Willy Tarreau3b6e5472016-11-24 15:53:53 +01007215 appctx->st0 = CLI_ST_PRINT;
William Lallemand32af2032016-10-29 18:09:35 +02007216 return 1;
7217#else
7218 appctx->ctx.cli.msg = "HAProxy was compiled against a version of OpenSSL that doesn't support OCSP stapling.\n";
Willy Tarreau3b6e5472016-11-24 15:53:53 +01007219 appctx->st0 = CLI_ST_PRINT;
William Lallemand32af2032016-10-29 18:09:35 +02007220 return 1;
7221#endif
7222
7223}
7224
7225/* register cli keywords */
7226static struct cli_kw_list cli_kws = {{ },{
7227#if (defined SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB && TLS_TICKETS_NO > 0)
7228 { { "show", "tls-keys", NULL }, "show tls-keys [id|*]: show tls keys references or dump tls ticket keys when id specified", cli_parse_show_tlskeys, NULL },
7229 { { "set", "ssl", "tls-keys", NULL }, NULL, cli_parse_set_tlskeys, NULL },
William Lallemand32af2032016-10-29 18:09:35 +02007230#endif
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +01007231 { { "set", "ssl", "ocsp-response", NULL }, NULL, cli_parse_set_ocspresponse, NULL },
William Lallemand32af2032016-10-29 18:09:35 +02007232 { { NULL }, NULL, NULL, NULL }
7233}};
7234
7235
Willy Tarreau7875d092012-09-10 08:20:03 +02007236/* Note: must not be declared <const> as its list will be overwritten.
7237 * Please take care of keeping this list alphabetically sorted.
7238 */
Willy Tarreaudc13c112013-06-21 23:16:39 +02007239static struct sample_fetch_kw_list sample_fetch_keywords = {ILH, {
Emeric Brun645ae792014-04-30 14:21:06 +02007240 { "ssl_bc", smp_fetch_ssl_fc, 0, NULL, SMP_T_BOOL, SMP_USE_L5SRV },
Thierry FOURNIER07ee64e2015-07-06 23:43:03 +02007241 { "ssl_bc_alg_keysize", smp_fetch_ssl_fc_alg_keysize, 0, NULL, SMP_T_SINT, SMP_USE_L5SRV },
Emeric Brun645ae792014-04-30 14:21:06 +02007242 { "ssl_bc_cipher", smp_fetch_ssl_fc_cipher, 0, NULL, SMP_T_STR, SMP_USE_L5SRV },
7243 { "ssl_bc_protocol", smp_fetch_ssl_fc_protocol, 0, NULL, SMP_T_STR, SMP_USE_L5SRV },
Emeric Brunb73a9b02014-04-30 18:49:19 +02007244 { "ssl_bc_unique_id", smp_fetch_ssl_fc_unique_id, 0, NULL, SMP_T_BIN, SMP_USE_L5SRV },
Thierry FOURNIER07ee64e2015-07-06 23:43:03 +02007245 { "ssl_bc_use_keysize", smp_fetch_ssl_fc_use_keysize, 0, NULL, SMP_T_SINT, SMP_USE_L5SRV },
Emeric Brun645ae792014-04-30 14:21:06 +02007246 { "ssl_bc_session_id", smp_fetch_ssl_fc_session_id, 0, NULL, SMP_T_BIN, SMP_USE_L5SRV },
Thierry FOURNIER07ee64e2015-07-06 23:43:03 +02007247 { "ssl_c_ca_err", smp_fetch_ssl_c_ca_err, 0, NULL, SMP_T_SINT, SMP_USE_L5CLI },
7248 { "ssl_c_ca_err_depth", smp_fetch_ssl_c_ca_err_depth, 0, NULL, SMP_T_SINT, SMP_USE_L5CLI },
Emeric Brun43e79582014-10-29 19:03:26 +01007249 { "ssl_c_der", smp_fetch_ssl_x_der, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Thierry FOURNIER07ee64e2015-07-06 23:43:03 +02007250 { "ssl_c_err", smp_fetch_ssl_c_err, 0, NULL, SMP_T_SINT, SMP_USE_L5CLI },
Emeric Brunba841a12014-04-30 17:05:08 +02007251 { "ssl_c_i_dn", smp_fetch_ssl_x_i_dn, ARG2(0,STR,SINT), NULL, SMP_T_STR, SMP_USE_L5CLI },
7252 { "ssl_c_key_alg", smp_fetch_ssl_x_key_alg, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
7253 { "ssl_c_notafter", smp_fetch_ssl_x_notafter, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
7254 { "ssl_c_notbefore", smp_fetch_ssl_x_notbefore, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
7255 { "ssl_c_sig_alg", smp_fetch_ssl_x_sig_alg, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
7256 { "ssl_c_s_dn", smp_fetch_ssl_x_s_dn, ARG2(0,STR,SINT), NULL, SMP_T_STR, SMP_USE_L5CLI },
7257 { "ssl_c_serial", smp_fetch_ssl_x_serial, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
7258 { "ssl_c_sha1", smp_fetch_ssl_x_sha1, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Willy Tarreau80aca902013-01-07 15:42:20 +01007259 { "ssl_c_used", smp_fetch_ssl_c_used, 0, NULL, SMP_T_BOOL, SMP_USE_L5CLI },
Thierry FOURNIER07ee64e2015-07-06 23:43:03 +02007260 { "ssl_c_verify", smp_fetch_ssl_c_verify, 0, NULL, SMP_T_SINT, SMP_USE_L5CLI },
7261 { "ssl_c_version", smp_fetch_ssl_x_version, 0, NULL, SMP_T_SINT, SMP_USE_L5CLI },
Emeric Brun43e79582014-10-29 19:03:26 +01007262 { "ssl_f_der", smp_fetch_ssl_x_der, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Emeric Brunba841a12014-04-30 17:05:08 +02007263 { "ssl_f_i_dn", smp_fetch_ssl_x_i_dn, ARG2(0,STR,SINT), NULL, SMP_T_STR, SMP_USE_L5CLI },
7264 { "ssl_f_key_alg", smp_fetch_ssl_x_key_alg, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
7265 { "ssl_f_notafter", smp_fetch_ssl_x_notafter, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
7266 { "ssl_f_notbefore", smp_fetch_ssl_x_notbefore, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
7267 { "ssl_f_sig_alg", smp_fetch_ssl_x_sig_alg, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
7268 { "ssl_f_s_dn", smp_fetch_ssl_x_s_dn, ARG2(0,STR,SINT), NULL, SMP_T_STR, SMP_USE_L5CLI },
7269 { "ssl_f_serial", smp_fetch_ssl_x_serial, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Emeric Brun55f4fa82014-04-30 17:11:25 +02007270 { "ssl_f_sha1", smp_fetch_ssl_x_sha1, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Thierry FOURNIER07ee64e2015-07-06 23:43:03 +02007271 { "ssl_f_version", smp_fetch_ssl_x_version, 0, NULL, SMP_T_SINT, SMP_USE_L5CLI },
Willy Tarreau80aca902013-01-07 15:42:20 +01007272 { "ssl_fc", smp_fetch_ssl_fc, 0, NULL, SMP_T_BOOL, SMP_USE_L5CLI },
Thierry FOURNIER07ee64e2015-07-06 23:43:03 +02007273 { "ssl_fc_alg_keysize", smp_fetch_ssl_fc_alg_keysize, 0, NULL, SMP_T_SINT, SMP_USE_L5CLI },
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01007274 { "ssl_fc_cipher", smp_fetch_ssl_fc_cipher, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Willy Tarreau80aca902013-01-07 15:42:20 +01007275 { "ssl_fc_has_crt", smp_fetch_ssl_fc_has_crt, 0, NULL, SMP_T_BOOL, SMP_USE_L5CLI },
7276 { "ssl_fc_has_sni", smp_fetch_ssl_fc_has_sni, 0, NULL, SMP_T_BOOL, SMP_USE_L5CLI },
Nenad Merdanovic26ea8222015-05-18 02:28:57 +02007277 { "ssl_fc_is_resumed", smp_fetch_ssl_fc_is_resumed, 0, NULL, SMP_T_BOOL, SMP_USE_L5CLI },
Willy Tarreaua33c6542012-10-15 13:19:06 +02007278#ifdef OPENSSL_NPN_NEGOTIATED
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01007279 { "ssl_fc_npn", smp_fetch_ssl_fc_npn, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Willy Tarreaua33c6542012-10-15 13:19:06 +02007280#endif
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01007281#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01007282 { "ssl_fc_alpn", smp_fetch_ssl_fc_alpn, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Willy Tarreauab861d32013-04-02 02:30:41 +02007283#endif
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01007284 { "ssl_fc_protocol", smp_fetch_ssl_fc_protocol, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Emeric Brunb73a9b02014-04-30 18:49:19 +02007285 { "ssl_fc_unique_id", smp_fetch_ssl_fc_unique_id, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Thierry FOURNIER07ee64e2015-07-06 23:43:03 +02007286 { "ssl_fc_use_keysize", smp_fetch_ssl_fc_use_keysize, 0, NULL, SMP_T_SINT, SMP_USE_L5CLI },
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01007287 { "ssl_fc_session_id", smp_fetch_ssl_fc_session_id, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
7288 { "ssl_fc_sni", smp_fetch_ssl_fc_sni, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Thierry FOURNIER5bf77322017-02-25 12:45:22 +01007289 { "ssl_fc_cipherlist_bin", smp_fetch_ssl_fc_cl_bin, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
7290 { "ssl_fc_cipherlist_hex", smp_fetch_ssl_fc_cl_hex, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
7291 { "ssl_fc_cipherlist_str", smp_fetch_ssl_fc_cl_str, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
7292 { "ssl_fc_cipherlist_xxh", smp_fetch_ssl_fc_cl_xxh64, 0, NULL, SMP_T_SINT, SMP_USE_L5CLI },
Willy Tarreau7875d092012-09-10 08:20:03 +02007293 { NULL, NULL, 0, 0, 0 },
7294}};
7295
7296/* Note: must not be declared <const> as its list will be overwritten.
7297 * Please take care of keeping this list alphabetically sorted.
7298 */
Willy Tarreaudc13c112013-06-21 23:16:39 +02007299static struct acl_kw_list acl_kws = {ILH, {
Thierry FOURNIERc5a4e982014-03-05 16:07:08 +01007300 { "ssl_fc_sni_end", "ssl_fc_sni", PAT_MATCH_END },
7301 { "ssl_fc_sni_reg", "ssl_fc_sni", PAT_MATCH_REG },
Willy Tarreau8ed669b2013-01-11 15:49:37 +01007302 { /* END */ },
Willy Tarreau7875d092012-09-10 08:20:03 +02007303}};
7304
Willy Tarreau79eeafa2012-09-14 07:53:05 +02007305/* Note: must not be declared <const> as its list will be overwritten.
7306 * Please take care of keeping this list alphabetically sorted, doing so helps
7307 * all code contributors.
7308 * Optional keywords are also declared with a NULL ->parse() function so that
7309 * the config parser can report an appropriate error when a known keyword was
7310 * not enabled.
7311 */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01007312static struct ssl_bind_kw ssl_bind_kws[] = {
7313 { "alpn", ssl_bind_parse_alpn, 1 }, /* set ALPN supported protocols */
7314 { "ca-file", ssl_bind_parse_ca_file, 1 }, /* set CAfile to process verify on client cert */
7315 { "ciphers", ssl_bind_parse_ciphers, 1 }, /* set SSL cipher suite */
7316 { "crl-file", ssl_bind_parse_crl_file, 1 }, /* set certificat revocation list file use on client cert verify */
Emmanuel Hocdete7f2b732017-01-09 16:15:54 +01007317 { "curves", ssl_bind_parse_curves, 1 }, /* set SSL curve suite */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01007318 { "ecdhe", ssl_bind_parse_ecdhe, 1 }, /* defines named curve for elliptic curve Diffie-Hellman */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01007319 { "npn", ssl_bind_parse_npn, 1 }, /* set NPN supported protocols */
7320 { "verify", ssl_bind_parse_verify, 1 }, /* set SSL verify method */
7321 { NULL, NULL, 0 },
7322};
7323
Willy Tarreau51fb7652012-09-18 18:24:39 +02007324static struct bind_kw_list bind_kws = { "SSL", { }, {
Nenad Merdanovic05552d42015-02-27 19:56:49 +01007325 { "alpn", bind_parse_alpn, 1 }, /* set ALPN supported protocols */
7326 { "ca-file", bind_parse_ca_file, 1 }, /* set CAfile to process verify on client cert */
7327 { "ca-ignore-err", bind_parse_ignore_err, 1 }, /* set error IDs to ignore on verify depth > 0 */
Christopher Faulet31af49d2015-06-09 17:29:50 +02007328 { "ca-sign-file", bind_parse_ca_sign_file, 1 }, /* set CAFile used to generate and sign server certs */
7329 { "ca-sign-pass", bind_parse_ca_sign_pass, 1 }, /* set CAKey passphrase */
Nenad Merdanovic05552d42015-02-27 19:56:49 +01007330 { "ciphers", bind_parse_ciphers, 1 }, /* set SSL cipher suite */
7331 { "crl-file", bind_parse_crl_file, 1 }, /* set certificat revocation list file use on client cert verify */
7332 { "crt", bind_parse_crt, 1 }, /* load SSL certificates from this location */
7333 { "crt-ignore-err", bind_parse_ignore_err, 1 }, /* set error IDs to ingore on verify depth == 0 */
7334 { "crt-list", bind_parse_crt_list, 1 }, /* load a list of crt from this location */
Emmanuel Hocdete7f2b732017-01-09 16:15:54 +01007335 { "curves", bind_parse_curves, 1 }, /* set SSL curve suite */
Nenad Merdanovic05552d42015-02-27 19:56:49 +01007336 { "ecdhe", bind_parse_ecdhe, 1 }, /* defines named curve for elliptic curve Diffie-Hellman */
7337 { "force-sslv3", bind_parse_force_sslv3, 0 }, /* force SSLv3 */
7338 { "force-tlsv10", bind_parse_force_tlsv10, 0 }, /* force TLSv10 */
7339 { "force-tlsv11", bind_parse_force_tlsv11, 0 }, /* force TLSv11 */
7340 { "force-tlsv12", bind_parse_force_tlsv12, 0 }, /* force TLSv12 */
Christopher Faulet31af49d2015-06-09 17:29:50 +02007341 { "generate-certificates", bind_parse_generate_certs, 0 }, /* enable the server certificates generation */
Nenad Merdanovic05552d42015-02-27 19:56:49 +01007342 { "no-sslv3", bind_parse_no_sslv3, 0 }, /* disable SSLv3 */
7343 { "no-tlsv10", bind_parse_no_tlsv10, 0 }, /* disable TLSv10 */
7344 { "no-tlsv11", bind_parse_no_tlsv11, 0 }, /* disable TLSv11 */
7345 { "no-tlsv12", bind_parse_no_tlsv12, 0 }, /* disable TLSv12 */
7346 { "no-tls-tickets", bind_parse_no_tls_tickets, 0 }, /* disable session resumption tickets */
7347 { "ssl", bind_parse_ssl, 0 }, /* enable SSL processing */
7348 { "strict-sni", bind_parse_strict_sni, 0 }, /* refuse negotiation if sni doesn't match a certificate */
7349 { "tls-ticket-keys", bind_parse_tls_ticket_keys, 1 }, /* set file to load TLS ticket keys from */
7350 { "verify", bind_parse_verify, 1 }, /* set SSL verify method */
7351 { "npn", bind_parse_npn, 1 }, /* set NPN supported protocols */
Willy Tarreau79eeafa2012-09-14 07:53:05 +02007352 { NULL, NULL, 0 },
7353}};
Emeric Brun46591952012-05-18 15:47:34 +02007354
Willy Tarreau92faadf2012-10-10 23:04:25 +02007355/* Note: must not be declared <const> as its list will be overwritten.
7356 * Please take care of keeping this list alphabetically sorted, doing so helps
7357 * all code contributors.
7358 * Optional keywords are also declared with a NULL ->parse() function so that
7359 * the config parser can report an appropriate error when a known keyword was
7360 * not enabled.
7361 */
7362static struct srv_kw_list srv_kws = { "SSL", { }, {
Emeric Brunef42d922012-10-11 16:11:36 +02007363 { "ca-file", srv_parse_ca_file, 1, 0 }, /* set CAfile to process verify server cert */
Emeric Brunecc91fe2012-10-11 15:05:10 +02007364 { "check-ssl", srv_parse_check_ssl, 0, 0 }, /* enable SSL for health checks */
7365 { "ciphers", srv_parse_ciphers, 1, 0 }, /* select the cipher suite */
Emeric Brunef42d922012-10-11 16:11:36 +02007366 { "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 +02007367 { "crt", srv_parse_crt, 1, 0 }, /* set client certificate */
Emeric Brunecc91fe2012-10-11 15:05:10 +02007368 { "force-sslv3", srv_parse_force_sslv3, 0, 0 }, /* force SSLv3 */
7369 { "force-tlsv10", srv_parse_force_tlsv10, 0, 0 }, /* force TLSv10 */
7370 { "force-tlsv11", srv_parse_force_tlsv11, 0, 0 }, /* force TLSv11 */
7371 { "force-tlsv12", srv_parse_force_tlsv12, 0, 0 }, /* force TLSv12 */
Willy Tarreau2a3fb1c2015-02-05 16:47:07 +01007372 { "no-ssl-reuse", srv_parse_no_ssl_reuse, 0, 0 }, /* disable session reuse */
Emeric Brunecc91fe2012-10-11 15:05:10 +02007373 { "no-sslv3", srv_parse_no_sslv3, 0, 0 }, /* disable SSLv3 */
7374 { "no-tlsv10", srv_parse_no_tlsv10, 0, 0 }, /* disable TLSv10 */
7375 { "no-tlsv11", srv_parse_no_tlsv11, 0, 0 }, /* disable TLSv11 */
7376 { "no-tlsv12", srv_parse_no_tlsv12, 0, 0 }, /* disable TLSv12 */
Emeric Brunf9c5c472012-10-11 15:28:34 +02007377 { "no-tls-tickets", srv_parse_no_tls_tickets, 0, 0 }, /* disable session resumption tickets */
David Safb76832014-05-08 23:42:08 -04007378 { "send-proxy-v2-ssl", srv_parse_send_proxy_ssl, 0, 0 }, /* send PROXY protocol header v2 with SSL info */
7379 { "send-proxy-v2-ssl-cn", srv_parse_send_proxy_cn, 0, 0 }, /* send PROXY protocol header v2 with CN */
Willy Tarreau732eac42015-07-09 11:40:25 +02007380 { "sni", srv_parse_sni, 1, 0 }, /* send SNI extension */
Emeric Brunecc91fe2012-10-11 15:05:10 +02007381 { "ssl", srv_parse_ssl, 0, 0 }, /* enable SSL processing */
Emeric Brunef42d922012-10-11 16:11:36 +02007382 { "verify", srv_parse_verify, 1, 0 }, /* set SSL verify method */
Evan Broderbe554312013-06-27 00:05:25 -07007383 { "verifyhost", srv_parse_verifyhost, 1, 0 }, /* require that SSL cert verifies for hostname */
Willy Tarreau92faadf2012-10-10 23:04:25 +02007384 { NULL, NULL, 0, 0 },
7385}};
7386
Emeric Brun2c86cbf2014-10-30 15:56:50 +01007387static struct cfg_kw_list cfg_kws = {ILH, {
Willy Tarreau8c3b0fd2016-12-21 22:44:46 +01007388 { CFG_GLOBAL, "ca-base", ssl_parse_global_ca_crt_base },
7389 { CFG_GLOBAL, "crt-base", ssl_parse_global_ca_crt_base },
Willy Tarreau0bea58d2016-12-21 23:17:25 +01007390 { CFG_GLOBAL, "maxsslconn", ssl_parse_global_int },
Emeric Brun2c86cbf2014-10-30 15:56:50 +01007391 { CFG_GLOBAL, "ssl-default-bind-options", ssl_parse_default_bind_options },
7392 { CFG_GLOBAL, "ssl-default-server-options", ssl_parse_default_server_options },
Willy Tarreau14e36a12016-12-21 23:28:13 +01007393#ifndef OPENSSL_NO_DH
7394 { CFG_GLOBAL, "ssl-dh-param-file", ssl_parse_global_dh_param_file },
7395#endif
Willy Tarreau9ceda382016-12-21 23:13:03 +01007396 { CFG_GLOBAL, "tune.ssl.cachesize", ssl_parse_global_int },
7397#ifndef OPENSSL_NO_DH
7398 { CFG_GLOBAL, "tune.ssl.default-dh-param", ssl_parse_global_default_dh },
7399#endif
7400 { CFG_GLOBAL, "tune.ssl.force-private-cache", ssl_parse_global_private_cache },
7401 { CFG_GLOBAL, "tune.ssl.lifetime", ssl_parse_global_lifetime },
7402 { CFG_GLOBAL, "tune.ssl.maxrecord", ssl_parse_global_int },
7403 { CFG_GLOBAL, "tune.ssl.ssl-ctx-cache-size", ssl_parse_global_int },
Thierry FOURNIER5bf77322017-02-25 12:45:22 +01007404 { CFG_GLOBAL, "tune.ssl.capture-cipherlist-size", ssl_parse_global_capture_cipherlist },
Willy Tarreauf22e9682016-12-21 23:23:19 +01007405 { CFG_GLOBAL, "ssl-default-bind-ciphers", ssl_parse_global_ciphers },
7406 { CFG_GLOBAL, "ssl-default-server-ciphers", ssl_parse_global_ciphers },
Emeric Brun2c86cbf2014-10-30 15:56:50 +01007407 { 0, NULL, NULL },
7408}};
7409
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02007410/* transport-layer operations for SSL sockets */
Willy Tarreaud9f5cca2016-12-22 21:08:52 +01007411static struct xprt_ops ssl_sock = {
Emeric Brun46591952012-05-18 15:47:34 +02007412 .snd_buf = ssl_sock_from_buf,
7413 .rcv_buf = ssl_sock_to_buf,
7414 .rcv_pipe = NULL,
7415 .snd_pipe = NULL,
7416 .shutr = NULL,
7417 .shutw = ssl_sock_shutw,
7418 .close = ssl_sock_close,
7419 .init = ssl_sock_init,
Willy Tarreau55d37912016-12-21 23:38:39 +01007420 .prepare_bind_conf = ssl_sock_prepare_bind_conf,
Willy Tarreau795cdab2016-12-22 17:30:54 +01007421 .destroy_bind_conf = ssl_sock_destroy_bind_conf,
Willy Tarreau17d45382016-12-22 21:16:08 +01007422 .prepare_srv = ssl_sock_prepare_srv_ctx,
7423 .destroy_srv = ssl_sock_free_srv_ctx,
Willy Tarreau8e0bb0a2016-11-24 16:58:12 +01007424 .name = "SSL",
Emeric Brun46591952012-05-18 15:47:34 +02007425};
7426
Daniel Jakots54ffb912015-11-06 20:02:41 +01007427#if (OPENSSL_VERSION_NUMBER >= 0x1000200fL && !defined OPENSSL_NO_TLSEXT && !defined OPENSSL_IS_BORINGSSL && !defined LIBRESSL_VERSION_NUMBER)
Janusz Dziemidowicz2c701b52015-03-07 23:03:59 +01007428
7429static void ssl_sock_sctl_free_func(void *parent, void *ptr, CRYPTO_EX_DATA *ad, int idx, long argl, void *argp)
7430{
7431 if (ptr) {
7432 chunk_destroy(ptr);
7433 free(ptr);
7434 }
7435}
7436
7437#endif
Emmanuel Hocdetaaee7502017-03-07 18:34:58 +01007438static void ssl_sock_capture_free_func(void *parent, void *ptr, CRYPTO_EX_DATA *ad, int idx, long argl, void *argp)
7439{
7440 pool_free2(pool2_ssl_capture, ptr);
7441}
Janusz Dziemidowicz2c701b52015-03-07 23:03:59 +01007442
Emeric Brun46591952012-05-18 15:47:34 +02007443__attribute__((constructor))
Willy Tarreau92faadf2012-10-10 23:04:25 +02007444static void __ssl_sock_init(void)
7445{
Willy Tarreauc2c0b612016-12-21 19:23:20 +01007446 char *ptr;
7447
Emeric Brun46591952012-05-18 15:47:34 +02007448 STACK_OF(SSL_COMP)* cm;
7449
Willy Tarreauef934602016-12-22 23:12:01 +01007450 if (global_ssl.listen_default_ciphers)
7451 global_ssl.listen_default_ciphers = strdup(global_ssl.listen_default_ciphers);
7452 if (global_ssl.connect_default_ciphers)
7453 global_ssl.connect_default_ciphers = strdup(global_ssl.connect_default_ciphers);
Willy Tarreau610f04b2014-02-13 11:36:41 +01007454
Willy Tarreau13e14102016-12-22 20:25:26 +01007455 xprt_register(XPRT_SSL, &ssl_sock);
Emeric Brun46591952012-05-18 15:47:34 +02007456 SSL_library_init();
7457 cm = SSL_COMP_get_compression_methods();
7458 sk_SSL_COMP_zero(cm);
Daniel Jakots54ffb912015-11-06 20:02:41 +01007459#if (OPENSSL_VERSION_NUMBER >= 0x1000200fL && !defined OPENSSL_NO_TLSEXT && !defined OPENSSL_IS_BORINGSSL && !defined LIBRESSL_VERSION_NUMBER)
Janusz Dziemidowicz2c701b52015-03-07 23:03:59 +01007460 sctl_ex_index = SSL_CTX_get_ex_new_index(0, NULL, NULL, NULL, ssl_sock_sctl_free_func);
7461#endif
Emmanuel Hocdetaaee7502017-03-07 18:34:58 +01007462 ssl_capture_ptr_index = SSL_CTX_get_ex_new_index(0, NULL, NULL, NULL, ssl_sock_capture_free_func);
Willy Tarreau7875d092012-09-10 08:20:03 +02007463 sample_register_fetches(&sample_fetch_keywords);
7464 acl_register_keywords(&acl_kws);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02007465 bind_register_keywords(&bind_kws);
Willy Tarreau92faadf2012-10-10 23:04:25 +02007466 srv_register_keywords(&srv_kws);
Emeric Brun2c86cbf2014-10-30 15:56:50 +01007467 cfg_register_keywords(&cfg_kws);
William Lallemand32af2032016-10-29 18:09:35 +02007468 cli_register_kw(&cli_kws);
Willy Tarreaud1c57502016-12-22 22:46:15 +01007469#if (defined SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB && TLS_TICKETS_NO > 0)
7470 hap_register_post_check(tlskeys_finalize_config);
7471#endif
Willy Tarreaud92aa5c2015-01-15 21:34:39 +01007472
Willy Tarreauc2c0b612016-12-21 19:23:20 +01007473 ptr = NULL;
7474 memprintf(&ptr, "Built with OpenSSL version : "
7475#ifdef OPENSSL_IS_BORINGSSL
7476 "BoringSSL\n");
7477#else /* OPENSSL_IS_BORINGSSL */
7478 OPENSSL_VERSION_TEXT
7479 "\nRunning on OpenSSL version : %s%s",
7480 SSLeay_version(SSLEAY_VERSION),
7481 ((OPENSSL_VERSION_NUMBER ^ SSLeay()) >> 8) ? " (VERSIONS DIFFER!)" : "");
7482#endif
7483 memprintf(&ptr, "%s\nOpenSSL library supports TLS extensions : "
7484#if OPENSSL_VERSION_NUMBER < 0x00907000L
7485 "no (library version too old)"
7486#elif defined(OPENSSL_NO_TLSEXT)
7487 "no (disabled via OPENSSL_NO_TLSEXT)"
7488#else
7489 "yes"
7490#endif
7491 "", ptr);
7492
7493 memprintf(&ptr, "%s\nOpenSSL library supports SNI : "
7494#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
7495 "yes"
7496#else
7497#ifdef OPENSSL_NO_TLSEXT
7498 "no (because of OPENSSL_NO_TLSEXT)"
7499#else
7500 "no (version might be too old, 0.9.8f min needed)"
7501#endif
7502#endif
7503 "", ptr);
7504
Willy Tarreauc2c0b612016-12-21 19:23:20 +01007505 hap_register_build_opts(ptr, 1);
7506
Willy Tarreaud92aa5c2015-01-15 21:34:39 +01007507 global.ssl_session_max_cost = SSL_SESSION_MAX_COST;
7508 global.ssl_handshake_max_cost = SSL_HANDSHAKE_MAX_COST;
Remi Gacogne4f902b82015-05-28 16:23:00 +02007509
7510#ifndef OPENSSL_NO_DH
7511 ssl_dh_ptr_index = SSL_CTX_get_ex_new_index(0, NULL, NULL, NULL, NULL);
7512#endif
Thierry FOURNIER / OZON.IO8b068c22016-10-10 11:59:50 +02007513
7514 /* Load SSL string for the verbose & debug mode. */
7515 ERR_load_SSL_strings();
Emeric Brun46591952012-05-18 15:47:34 +02007516}
7517
Remi Gacogned3a23c32015-05-28 16:39:47 +02007518__attribute__((destructor))
7519static void __ssl_sock_deinit(void)
7520{
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +01007521#if (defined SSL_CTRL_SET_TLSEXT_HOSTNAME && !defined SSL_NO_GENERATE_CERTIFICATES)
Christopher Faulet31af49d2015-06-09 17:29:50 +02007522 lru64_destroy(ssl_ctx_lru_tree);
Willy Tarreaua84c2672015-10-09 12:10:13 +02007523#endif
Christopher Faulet31af49d2015-06-09 17:29:50 +02007524
Remi Gacogned3a23c32015-05-28 16:39:47 +02007525#ifndef OPENSSL_NO_DH
7526 if (local_dh_1024) {
7527 DH_free(local_dh_1024);
7528 local_dh_1024 = NULL;
7529 }
7530
7531 if (local_dh_2048) {
7532 DH_free(local_dh_2048);
7533 local_dh_2048 = NULL;
7534 }
7535
7536 if (local_dh_4096) {
7537 DH_free(local_dh_4096);
7538 local_dh_4096 = NULL;
7539 }
7540
Remi Gacogne47783ef2015-05-29 15:53:22 +02007541 if (global_dh) {
7542 DH_free(global_dh);
7543 global_dh = NULL;
7544 }
Remi Gacogned3a23c32015-05-28 16:39:47 +02007545#endif
7546
7547 ERR_remove_state(0);
7548 ERR_free_strings();
7549
7550 EVP_cleanup();
7551
7552#if OPENSSL_VERSION_NUMBER >= 0x00907000L
7553 CRYPTO_cleanup_all_ex_data();
7554#endif
7555}
7556
7557
Emeric Brun46591952012-05-18 15:47:34 +02007558/*
7559 * Local variables:
7560 * c-indent-level: 8
7561 * c-basic-offset: 8
7562 * End:
7563 */