blob: f947c9965e06ab3b1e20fec4ea6c05bf3e774e89 [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 Hocdete7f2b732017-01-09 16:15:54 +01003405 else
3406 SSL_CTX_set_ecdh_auto(ctx, 1);
Emmanuel Hocdete7f2b732017-01-09 16:15:54 +01003407 }
3408#endif
Emeric Brun2b58d042012-09-20 17:10:03 +02003409#if defined(SSL_CTX_set_tmp_ecdh) && !defined(OPENSSL_NO_ECDH)
Emmanuel Hocdete7f2b732017-01-09 16:15:54 +01003410 if (!conf_curves) {
Emeric Brun2b58d042012-09-20 17:10:03 +02003411 int i;
3412 EC_KEY *ecdh;
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003413 const char *ecdhe = (ssl_conf && ssl_conf->ecdhe) ? ssl_conf->ecdhe :
3414 (bind_conf->ssl_conf.ecdhe ? bind_conf->ssl_conf.ecdhe : ECDHE_DEFAULT_CURVE);
Emeric Brun2b58d042012-09-20 17:10:03 +02003415
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003416 i = OBJ_sn2nid(ecdhe);
Emeric Brun2b58d042012-09-20 17:10:03 +02003417 if (!i || ((ecdh = EC_KEY_new_by_curve_name(i)) == NULL)) {
3418 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 +01003419 curproxy->id, ecdhe, bind_conf->arg, bind_conf->file, bind_conf->line);
Emeric Brun2b58d042012-09-20 17:10:03 +02003420 cfgerr++;
3421 }
3422 else {
3423 SSL_CTX_set_tmp_ecdh(ctx, ecdh);
3424 EC_KEY_free(ecdh);
3425 }
3426 }
3427#endif
3428
Emeric Brunfc0421f2012-09-07 17:30:07 +02003429 return cfgerr;
3430}
3431
Evan Broderbe554312013-06-27 00:05:25 -07003432static int ssl_sock_srv_hostcheck(const char *pattern, const char *hostname)
3433{
3434 const char *pattern_wildcard, *pattern_left_label_end, *hostname_left_label_end;
3435 size_t prefixlen, suffixlen;
3436
3437 /* Trivial case */
3438 if (strcmp(pattern, hostname) == 0)
3439 return 1;
3440
Evan Broderbe554312013-06-27 00:05:25 -07003441 /* The rest of this logic is based on RFC 6125, section 6.4.3
3442 * (http://tools.ietf.org/html/rfc6125#section-6.4.3) */
3443
Emeric Bruna848dae2013-10-08 11:27:28 +02003444 pattern_wildcard = NULL;
3445 pattern_left_label_end = pattern;
3446 while (*pattern_left_label_end != '.') {
3447 switch (*pattern_left_label_end) {
3448 case 0:
3449 /* End of label not found */
3450 return 0;
3451 case '*':
3452 /* If there is more than one wildcards */
3453 if (pattern_wildcard)
3454 return 0;
3455 pattern_wildcard = pattern_left_label_end;
3456 break;
3457 }
3458 pattern_left_label_end++;
3459 }
3460
3461 /* If it's not trivial and there is no wildcard, it can't
3462 * match */
3463 if (!pattern_wildcard)
Evan Broderbe554312013-06-27 00:05:25 -07003464 return 0;
3465
3466 /* Make sure all labels match except the leftmost */
3467 hostname_left_label_end = strchr(hostname, '.');
3468 if (!hostname_left_label_end
3469 || strcmp(pattern_left_label_end, hostname_left_label_end) != 0)
3470 return 0;
3471
3472 /* Make sure the leftmost label of the hostname is long enough
3473 * that the wildcard can match */
Emeric Brun369da852013-10-08 11:39:35 +02003474 if (hostname_left_label_end - hostname < (pattern_left_label_end - pattern) - 1)
Evan Broderbe554312013-06-27 00:05:25 -07003475 return 0;
3476
3477 /* Finally compare the string on either side of the
3478 * wildcard */
3479 prefixlen = pattern_wildcard - pattern;
3480 suffixlen = pattern_left_label_end - (pattern_wildcard + 1);
Emeric Bruna848dae2013-10-08 11:27:28 +02003481 if ((prefixlen && (memcmp(pattern, hostname, prefixlen) != 0))
3482 || (suffixlen && (memcmp(pattern_wildcard + 1, hostname_left_label_end - suffixlen, suffixlen) != 0)))
Evan Broderbe554312013-06-27 00:05:25 -07003483 return 0;
3484
3485 return 1;
3486}
3487
3488static int ssl_sock_srv_verifycbk(int ok, X509_STORE_CTX *ctx)
3489{
3490 SSL *ssl;
3491 struct connection *conn;
3492 char *servername;
3493
3494 int depth;
3495 X509 *cert;
3496 STACK_OF(GENERAL_NAME) *alt_names;
3497 int i;
3498 X509_NAME *cert_subject;
3499 char *str;
3500
3501 if (ok == 0)
3502 return ok;
3503
3504 ssl = X509_STORE_CTX_get_ex_data(ctx, SSL_get_ex_data_X509_STORE_CTX_idx());
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02003505 conn = SSL_get_app_data(ssl);
Evan Broderbe554312013-06-27 00:05:25 -07003506
3507 servername = objt_server(conn->target)->ssl_ctx.verify_host;
3508
3509 /* We only need to verify the CN on the actual server cert,
3510 * not the indirect CAs */
3511 depth = X509_STORE_CTX_get_error_depth(ctx);
3512 if (depth != 0)
3513 return ok;
3514
3515 /* At this point, the cert is *not* OK unless we can find a
3516 * hostname match */
3517 ok = 0;
3518
3519 cert = X509_STORE_CTX_get_current_cert(ctx);
3520 /* It seems like this might happen if verify peer isn't set */
3521 if (!cert)
3522 return ok;
3523
3524 alt_names = X509_get_ext_d2i(cert, NID_subject_alt_name, NULL, NULL);
3525 if (alt_names) {
3526 for (i = 0; !ok && i < sk_GENERAL_NAME_num(alt_names); i++) {
3527 GENERAL_NAME *name = sk_GENERAL_NAME_value(alt_names, i);
3528 if (name->type == GEN_DNS) {
Emeric Bruna33410c2013-09-17 15:47:48 +02003529#if OPENSSL_VERSION_NUMBER < 0x00907000L
3530 if (ASN1_STRING_to_UTF8((unsigned char **)&str, name->d.ia5) >= 0) {
3531#else
Evan Broderbe554312013-06-27 00:05:25 -07003532 if (ASN1_STRING_to_UTF8((unsigned char **)&str, name->d.dNSName) >= 0) {
Emeric Bruna33410c2013-09-17 15:47:48 +02003533#endif
Evan Broderbe554312013-06-27 00:05:25 -07003534 ok = ssl_sock_srv_hostcheck(str, servername);
3535 OPENSSL_free(str);
3536 }
3537 }
3538 }
Emeric Brun4ad50a42013-09-17 15:19:54 +02003539 sk_GENERAL_NAME_pop_free(alt_names, GENERAL_NAME_free);
Evan Broderbe554312013-06-27 00:05:25 -07003540 }
3541
3542 cert_subject = X509_get_subject_name(cert);
3543 i = -1;
3544 while (!ok && (i = X509_NAME_get_index_by_NID(cert_subject, NID_commonName, i)) != -1) {
3545 X509_NAME_ENTRY *entry = X509_NAME_get_entry(cert_subject, i);
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02003546 ASN1_STRING *value;
3547 value = X509_NAME_ENTRY_get_data(entry);
3548 if (ASN1_STRING_to_UTF8((unsigned char **)&str, value) >= 0) {
Evan Broderbe554312013-06-27 00:05:25 -07003549 ok = ssl_sock_srv_hostcheck(str, servername);
3550 OPENSSL_free(str);
3551 }
3552 }
3553
3554 return ok;
3555}
3556
Emeric Brun94324a42012-10-11 14:00:19 +02003557/* prepare ssl context from servers options. Returns an error count */
Willy Tarreau03209342016-12-22 17:08:28 +01003558int ssl_sock_prepare_srv_ctx(struct server *srv)
Emeric Brun94324a42012-10-11 14:00:19 +02003559{
Willy Tarreau03209342016-12-22 17:08:28 +01003560 struct proxy *curproxy = srv->proxy;
Emeric Brun94324a42012-10-11 14:00:19 +02003561 int cfgerr = 0;
Remi Gacogneaf5c3da2014-05-19 10:29:58 +02003562 long options =
Emeric Brun94324a42012-10-11 14:00:19 +02003563 SSL_OP_ALL | /* all known workarounds for bugs */
3564 SSL_OP_NO_SSLv2 |
3565 SSL_OP_NO_COMPRESSION;
Remi Gacogneaf5c3da2014-05-19 10:29:58 +02003566 long mode =
Emeric Brun94324a42012-10-11 14:00:19 +02003567 SSL_MODE_ENABLE_PARTIAL_WRITE |
3568 SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER |
Willy Tarreau396a1862014-11-13 14:06:52 +01003569 SSL_MODE_RELEASE_BUFFERS |
3570 SSL_MODE_SMALL_BUFFERS;
Emeric Brun850efd52014-01-29 12:24:34 +01003571 int verify = SSL_VERIFY_NONE;
Emmanuel Hocdet4de1ff12017-03-03 12:21:32 +01003572 SSL_CTX *ctx = NULL;
Emeric Brun94324a42012-10-11 14:00:19 +02003573
Thierry Fournier383085f2013-01-24 14:15:43 +01003574 /* Make sure openssl opens /dev/urandom before the chroot */
3575 if (!ssl_initialize_random()) {
3576 Alert("OpenSSL random data generator initialization failed.\n");
3577 cfgerr++;
3578 }
3579
Willy Tarreaufce03112015-01-15 21:32:40 +01003580 /* Automatic memory computations need to know we use SSL there */
3581 global.ssl_used_backend = 1;
3582
3583 /* Initiate SSL context for current server */
Emeric Brun94324a42012-10-11 14:00:19 +02003584 srv->ssl_ctx.reused_sess = NULL;
3585 if (srv->use_ssl)
3586 srv->xprt = &ssl_sock;
3587 if (srv->check.use_ssl)
Cyril Bonté9ce13112014-11-15 22:41:27 +01003588 srv->check.xprt = &ssl_sock;
Emeric Brun94324a42012-10-11 14:00:19 +02003589
Emmanuel Hocdet4de1ff12017-03-03 12:21:32 +01003590#if SSL_OP_NO_TLSv1_2
3591 if (!ctx && srv->ssl_ctx.options & SRV_SSL_O_USE_TLSV12)
3592 ctx = SSL_CTX_new(TLSv1_2_client_method());
3593#endif
3594#if SSL_OP_NO_TLSv1_1
3595 if (!ctx && srv->ssl_ctx.options & SRV_SSL_O_USE_TLSV11)
3596 ctx = SSL_CTX_new(TLSv1_1_client_method());
3597#endif
3598 if (!ctx && srv->ssl_ctx.options & SRV_SSL_O_USE_TLSV10)
3599 ctx = SSL_CTX_new(TLSv1_client_method());
3600#ifndef OPENSSL_NO_SSL3
3601 if (!ctx && srv->ssl_ctx.options & SRV_SSL_O_USE_SSLV3)
3602 ctx = SSL_CTX_new(SSLv3_client_method());
3603#endif
3604 if (!ctx) {
3605 ctx = SSL_CTX_new(SSLv23_client_method());
3606 if (srv->ssl_ctx.options & SRV_SSL_O_NO_SSLV3)
3607 options |= SSL_OP_NO_SSLv3;
3608 if (srv->ssl_ctx.options & SRV_SSL_O_NO_TLSV10)
3609 options |= SSL_OP_NO_TLSv1;
3610 if (srv->ssl_ctx.options & SRV_SSL_O_NO_TLSV11)
3611 options |= SSL_OP_NO_TLSv1_1;
3612 if (srv->ssl_ctx.options & SRV_SSL_O_NO_TLSV12)
3613 options |= SSL_OP_NO_TLSv1_2;
3614 }
3615 if (srv->ssl_ctx.options & SRV_SSL_O_NO_TLS_TICKETS)
3616 options |= SSL_OP_NO_TICKET;
3617 if (!ctx) {
Emeric Brun94324a42012-10-11 14:00:19 +02003618 Alert("config : %s '%s', server '%s': unable to allocate ssl context.\n",
3619 proxy_type_str(curproxy), curproxy->id,
3620 srv->id);
3621 cfgerr++;
3622 return cfgerr;
3623 }
Emmanuel Hocdet4de1ff12017-03-03 12:21:32 +01003624 SSL_CTX_set_options(ctx, options);
3625 SSL_CTX_set_mode(ctx, mode);
3626 srv->ssl_ctx.ctx = ctx;
3627
Emeric Bruna7aa3092012-10-26 12:58:00 +02003628 if (srv->ssl_ctx.client_crt) {
3629 if (SSL_CTX_use_PrivateKey_file(srv->ssl_ctx.ctx, srv->ssl_ctx.client_crt, SSL_FILETYPE_PEM) <= 0) {
3630 Alert("config : %s '%s', server '%s': unable to load SSL private key from PEM file '%s'.\n",
3631 proxy_type_str(curproxy), curproxy->id,
3632 srv->id, srv->ssl_ctx.client_crt);
3633 cfgerr++;
3634 }
3635 else if (SSL_CTX_use_certificate_chain_file(srv->ssl_ctx.ctx, srv->ssl_ctx.client_crt) <= 0) {
3636 Alert("config : %s '%s', server '%s': unable to load ssl certificate from PEM file '%s'.\n",
3637 proxy_type_str(curproxy), curproxy->id,
3638 srv->id, srv->ssl_ctx.client_crt);
3639 cfgerr++;
3640 }
3641 else if (SSL_CTX_check_private_key(srv->ssl_ctx.ctx) <= 0) {
3642 Alert("config : %s '%s', server '%s': inconsistencies between private key and certificate loaded from PEM file '%s'.\n",
3643 proxy_type_str(curproxy), curproxy->id,
3644 srv->id, srv->ssl_ctx.client_crt);
3645 cfgerr++;
3646 }
3647 }
Emeric Brun94324a42012-10-11 14:00:19 +02003648
Emeric Brun850efd52014-01-29 12:24:34 +01003649 if (global.ssl_server_verify == SSL_SERVER_VERIFY_REQUIRED)
3650 verify = SSL_VERIFY_PEER;
Emeric Brun850efd52014-01-29 12:24:34 +01003651 switch (srv->ssl_ctx.verify) {
3652 case SSL_SOCK_VERIFY_NONE:
3653 verify = SSL_VERIFY_NONE;
3654 break;
3655 case SSL_SOCK_VERIFY_REQUIRED:
3656 verify = SSL_VERIFY_PEER;
3657 break;
3658 }
Evan Broderbe554312013-06-27 00:05:25 -07003659 SSL_CTX_set_verify(srv->ssl_ctx.ctx,
Emeric Brun850efd52014-01-29 12:24:34 +01003660 verify,
Evan Broderbe554312013-06-27 00:05:25 -07003661 srv->ssl_ctx.verify_host ? ssl_sock_srv_verifycbk : NULL);
Emeric Brun850efd52014-01-29 12:24:34 +01003662 if (verify & SSL_VERIFY_PEER) {
Emeric Brunef42d922012-10-11 16:11:36 +02003663 if (srv->ssl_ctx.ca_file) {
3664 /* load CAfile to verify */
3665 if (!SSL_CTX_load_verify_locations(srv->ssl_ctx.ctx, srv->ssl_ctx.ca_file, NULL)) {
Willy Tarreau07ba08b2014-02-16 19:22:08 +01003666 Alert("Proxy '%s', server '%s' [%s:%d] unable to load CA file '%s'.\n",
Emeric Brunef42d922012-10-11 16:11:36 +02003667 curproxy->id, srv->id,
3668 srv->conf.file, srv->conf.line, srv->ssl_ctx.ca_file);
3669 cfgerr++;
3670 }
3671 }
Emeric Brun850efd52014-01-29 12:24:34 +01003672 else {
3673 if (global.ssl_server_verify == SSL_SERVER_VERIFY_REQUIRED)
Willy Tarreau07ba08b2014-02-16 19:22:08 +01003674 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 +01003675 curproxy->id, srv->id,
3676 srv->conf.file, srv->conf.line);
3677 else
Willy Tarreau07ba08b2014-02-16 19:22:08 +01003678 Alert("Proxy '%s', server '%s' [%s:%d] verify is enabled but no CA file specified.\n",
Emeric Brun850efd52014-01-29 12:24:34 +01003679 curproxy->id, srv->id,
3680 srv->conf.file, srv->conf.line);
3681 cfgerr++;
3682 }
Emeric Brunef42d922012-10-11 16:11:36 +02003683#ifdef X509_V_FLAG_CRL_CHECK
3684 if (srv->ssl_ctx.crl_file) {
3685 X509_STORE *store = SSL_CTX_get_cert_store(srv->ssl_ctx.ctx);
3686
3687 if (!store || !X509_STORE_load_locations(store, srv->ssl_ctx.crl_file, NULL)) {
Willy Tarreau07ba08b2014-02-16 19:22:08 +01003688 Alert("Proxy '%s', server '%s' [%s:%d] unable to configure CRL file '%s'.\n",
Emeric Brunef42d922012-10-11 16:11:36 +02003689 curproxy->id, srv->id,
3690 srv->conf.file, srv->conf.line, srv->ssl_ctx.crl_file);
3691 cfgerr++;
3692 }
3693 else {
3694 X509_STORE_set_flags(store, X509_V_FLAG_CRL_CHECK|X509_V_FLAG_CRL_CHECK_ALL);
3695 }
3696 }
3697#endif
3698 }
3699
Emeric Brun94324a42012-10-11 14:00:19 +02003700 SSL_CTX_set_session_cache_mode(srv->ssl_ctx.ctx, SSL_SESS_CACHE_OFF);
3701 if (srv->ssl_ctx.ciphers &&
3702 !SSL_CTX_set_cipher_list(srv->ssl_ctx.ctx, srv->ssl_ctx.ciphers)) {
3703 Alert("Proxy '%s', server '%s' [%s:%d] : unable to set SSL cipher list to '%s'.\n",
3704 curproxy->id, srv->id,
3705 srv->conf.file, srv->conf.line, srv->ssl_ctx.ciphers);
3706 cfgerr++;
3707 }
3708
3709 return cfgerr;
3710}
3711
Willy Tarreau2a65ff02012-09-13 17:54:29 +02003712/* Walks down the two trees in bind_conf and prepares all certs. The pointer may
Emeric Brunfc0421f2012-09-07 17:30:07 +02003713 * be NULL, in which case nothing is done. Returns the number of errors
3714 * encountered.
3715 */
Willy Tarreau03209342016-12-22 17:08:28 +01003716int ssl_sock_prepare_all_ctx(struct bind_conf *bind_conf)
Emeric Brunfc0421f2012-09-07 17:30:07 +02003717{
3718 struct ebmb_node *node;
3719 struct sni_ctx *sni;
3720 int err = 0;
3721
Willy Tarreau2a65ff02012-09-13 17:54:29 +02003722 if (!bind_conf || !bind_conf->is_ssl)
Emeric Brunfc0421f2012-09-07 17:30:07 +02003723 return 0;
3724
Willy Tarreaufce03112015-01-15 21:32:40 +01003725 /* Automatic memory computations need to know we use SSL there */
3726 global.ssl_used_frontend = 1;
3727
Emmanuel Hocdetf6b37c62017-03-06 15:34:44 +01003728 /* Make sure openssl opens /dev/urandom before the chroot */
3729 if (!ssl_initialize_random()) {
3730 Alert("OpenSSL random data generator initialization failed.\n");
3731 err++;
3732 }
3733 /* Create initial_ctx used to start the ssl connection before do switchctx */
3734 if (!bind_conf->initial_ctx) {
3735 bind_conf->initial_ctx = ssl_sock_initial_ctx(bind_conf);
3736 /* It should not be necessary to call this function, but it's
3737 necessary first to check and move all initialisation related
3738 to initial_ctx in ssl_sock_initial_ctx. */
3739 err += ssl_sock_prepare_ctx(bind_conf, NULL, bind_conf->initial_ctx);
3740 }
Emeric Brun0bed9942014-10-30 19:25:24 +01003741 if (bind_conf->default_ctx)
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003742 err += ssl_sock_prepare_ctx(bind_conf, bind_conf->default_ssl_conf, bind_conf->default_ctx);
Emeric Brun0bed9942014-10-30 19:25:24 +01003743
Willy Tarreau2a65ff02012-09-13 17:54:29 +02003744 node = ebmb_first(&bind_conf->sni_ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02003745 while (node) {
3746 sni = ebmb_entry(node, struct sni_ctx, name);
Emeric Brun0bed9942014-10-30 19:25:24 +01003747 if (!sni->order && sni->ctx != bind_conf->default_ctx)
3748 /* only initialize the CTX on its first occurrence and
3749 if it is not the default_ctx */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003750 err += ssl_sock_prepare_ctx(bind_conf, sni->conf, sni->ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02003751 node = ebmb_next(node);
3752 }
3753
Willy Tarreau2a65ff02012-09-13 17:54:29 +02003754 node = ebmb_first(&bind_conf->sni_w_ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02003755 while (node) {
3756 sni = ebmb_entry(node, struct sni_ctx, name);
Emeric Brun0bed9942014-10-30 19:25:24 +01003757 if (!sni->order && sni->ctx != bind_conf->default_ctx)
3758 /* only initialize the CTX on its first occurrence and
3759 if it is not the default_ctx */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003760 err += ssl_sock_prepare_ctx(bind_conf, sni->conf, sni->ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02003761 node = ebmb_next(node);
3762 }
3763 return err;
3764}
3765
Willy Tarreau55d37912016-12-21 23:38:39 +01003766/* Prepares all the contexts for a bind_conf and allocates the shared SSL
3767 * context if needed. Returns < 0 on error, 0 on success. The warnings and
3768 * alerts are directly emitted since the rest of the stack does it below.
3769 */
3770int ssl_sock_prepare_bind_conf(struct bind_conf *bind_conf)
3771{
3772 struct proxy *px = bind_conf->frontend;
3773 int alloc_ctx;
3774 int err;
3775
3776 if (!bind_conf->is_ssl) {
3777 if (bind_conf->default_ctx) {
3778 Warning("Proxy '%s': A certificate was specified but SSL was not enabled on bind '%s' at [%s:%d] (use 'ssl').\n",
3779 px->id, bind_conf->arg, bind_conf->file, bind_conf->line);
3780 }
3781 return 0;
3782 }
3783 if (!bind_conf->default_ctx) {
3784 Alert("Proxy '%s': no SSL certificate specified for bind '%s' at [%s:%d] (use 'crt').\n",
3785 px->id, bind_conf->arg, bind_conf->file, bind_conf->line);
3786 return -1;
3787 }
3788
Willy Tarreauef934602016-12-22 23:12:01 +01003789 alloc_ctx = shared_context_init(global.tune.sslcachesize, (!global_ssl.private_cache && (global.nbproc > 1)) ? 1 : 0);
Willy Tarreau55d37912016-12-21 23:38:39 +01003790 if (alloc_ctx < 0) {
3791 if (alloc_ctx == SHCTX_E_INIT_LOCK)
3792 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");
3793 else
3794 Alert("Unable to allocate SSL session cache.\n");
3795 return -1;
3796 }
3797
3798 err = 0;
3799 /* initialize all certificate contexts */
3800 err += ssl_sock_prepare_all_ctx(bind_conf);
3801
3802 /* initialize CA variables if the certificates generation is enabled */
3803 err += ssl_sock_load_ca(bind_conf);
3804
3805 return -err;
3806}
Christopher Faulet77fe80c2015-07-29 13:02:40 +02003807
3808/* release ssl context allocated for servers. */
3809void ssl_sock_free_srv_ctx(struct server *srv)
3810{
3811 if (srv->ssl_ctx.ctx)
3812 SSL_CTX_free(srv->ssl_ctx.ctx);
3813}
3814
Willy Tarreau2a65ff02012-09-13 17:54:29 +02003815/* Walks down the two trees in bind_conf and frees all the certs. The pointer may
Emeric Brunfc0421f2012-09-07 17:30:07 +02003816 * be NULL, in which case nothing is done. The default_ctx is nullified too.
3817 */
Willy Tarreau2a65ff02012-09-13 17:54:29 +02003818void ssl_sock_free_all_ctx(struct bind_conf *bind_conf)
Emeric Brunfc0421f2012-09-07 17:30:07 +02003819{
3820 struct ebmb_node *node, *back;
3821 struct sni_ctx *sni;
3822
Willy Tarreau2a65ff02012-09-13 17:54:29 +02003823 if (!bind_conf || !bind_conf->is_ssl)
Emeric Brunfc0421f2012-09-07 17:30:07 +02003824 return;
3825
Willy Tarreau2a65ff02012-09-13 17:54:29 +02003826 node = ebmb_first(&bind_conf->sni_ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02003827 while (node) {
3828 sni = ebmb_entry(node, struct sni_ctx, name);
3829 back = ebmb_next(node);
3830 ebmb_delete(node);
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003831 if (!sni->order) { /* only free the CTX on its first occurrence */
Emeric Brunfc0421f2012-09-07 17:30:07 +02003832 SSL_CTX_free(sni->ctx);
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003833 ssl_sock_free_ssl_conf(sni->conf);
3834 free(sni->conf);
3835 sni->conf = NULL;
3836 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02003837 free(sni);
3838 node = back;
3839 }
3840
Willy Tarreau2a65ff02012-09-13 17:54:29 +02003841 node = ebmb_first(&bind_conf->sni_w_ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02003842 while (node) {
3843 sni = ebmb_entry(node, struct sni_ctx, name);
3844 back = ebmb_next(node);
3845 ebmb_delete(node);
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003846 if (!sni->order) { /* only free the CTX on its first occurrence */
Emeric Brunfc0421f2012-09-07 17:30:07 +02003847 SSL_CTX_free(sni->ctx);
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003848 ssl_sock_free_ssl_conf(sni->conf);
3849 free(sni->conf);
3850 sni->conf = NULL;
3851 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02003852 free(sni);
3853 node = back;
3854 }
Emmanuel Hocdetf6b37c62017-03-06 15:34:44 +01003855 SSL_CTX_free(bind_conf->initial_ctx);
3856 bind_conf->initial_ctx = NULL;
Willy Tarreau2a65ff02012-09-13 17:54:29 +02003857 bind_conf->default_ctx = NULL;
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003858 bind_conf->default_ssl_conf = NULL;
Emeric Brune1f38db2012-09-03 20:36:47 +02003859}
3860
Willy Tarreau795cdab2016-12-22 17:30:54 +01003861/* Destroys all the contexts for a bind_conf. This is used during deinit(). */
3862void ssl_sock_destroy_bind_conf(struct bind_conf *bind_conf)
3863{
3864 ssl_sock_free_ca(bind_conf);
3865 ssl_sock_free_all_ctx(bind_conf);
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003866 ssl_sock_free_ssl_conf(&bind_conf->ssl_conf);
Willy Tarreau795cdab2016-12-22 17:30:54 +01003867 free(bind_conf->ca_sign_file);
3868 free(bind_conf->ca_sign_pass);
Willy Tarreau795cdab2016-12-22 17:30:54 +01003869 if (bind_conf->keys_ref) {
3870 free(bind_conf->keys_ref->filename);
3871 free(bind_conf->keys_ref->tlskeys);
3872 LIST_DEL(&bind_conf->keys_ref->list);
3873 free(bind_conf->keys_ref);
3874 }
3875 bind_conf->keys_ref = NULL;
Willy Tarreau795cdab2016-12-22 17:30:54 +01003876 bind_conf->ca_sign_pass = NULL;
3877 bind_conf->ca_sign_file = NULL;
Willy Tarreau795cdab2016-12-22 17:30:54 +01003878}
3879
Christopher Faulet31af49d2015-06-09 17:29:50 +02003880/* Load CA cert file and private key used to generate certificates */
3881int
Willy Tarreau03209342016-12-22 17:08:28 +01003882ssl_sock_load_ca(struct bind_conf *bind_conf)
Christopher Faulet31af49d2015-06-09 17:29:50 +02003883{
Willy Tarreau03209342016-12-22 17:08:28 +01003884 struct proxy *px = bind_conf->frontend;
Christopher Faulet31af49d2015-06-09 17:29:50 +02003885 FILE *fp;
3886 X509 *cacert = NULL;
3887 EVP_PKEY *capkey = NULL;
3888 int err = 0;
3889
3890 if (!bind_conf || !bind_conf->generate_certs)
3891 return err;
3892
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +01003893#if (defined SSL_CTRL_SET_TLSEXT_HOSTNAME && !defined SSL_NO_GENERATE_CERTIFICATES)
Willy Tarreauef934602016-12-22 23:12:01 +01003894 if (global_ssl.ctx_cache)
3895 ssl_ctx_lru_tree = lru64_new(global_ssl.ctx_cache);
Christopher Fauletd2cab922015-07-28 16:03:47 +02003896 ssl_ctx_lru_seed = (unsigned int)time(NULL);
Willy Tarreaua84c2672015-10-09 12:10:13 +02003897#endif
Christopher Fauletd2cab922015-07-28 16:03:47 +02003898
Christopher Faulet31af49d2015-06-09 17:29:50 +02003899 if (!bind_conf->ca_sign_file) {
3900 Alert("Proxy '%s': cannot enable certificate generation, "
3901 "no CA certificate File configured at [%s:%d].\n",
3902 px->id, bind_conf->file, bind_conf->line);
Christopher Faulet31af49d2015-06-09 17:29:50 +02003903 goto load_error;
Christopher Fauletc6f02fb2015-10-09 10:53:31 +02003904 }
Christopher Faulet31af49d2015-06-09 17:29:50 +02003905
3906 /* read in the CA certificate */
3907 if (!(fp = fopen(bind_conf->ca_sign_file, "r"))) {
3908 Alert("Proxy '%s': Failed to read CA certificate file '%s' at [%s:%d].\n",
3909 px->id, bind_conf->ca_sign_file, bind_conf->file, bind_conf->line);
Christopher Faulet31af49d2015-06-09 17:29:50 +02003910 goto load_error;
3911 }
3912 if (!(cacert = PEM_read_X509(fp, NULL, NULL, NULL))) {
3913 Alert("Proxy '%s': Failed to read CA certificate file '%s' at [%s:%d].\n",
3914 px->id, bind_conf->ca_sign_file, bind_conf->file, bind_conf->line);
Christopher Fauletc6f02fb2015-10-09 10:53:31 +02003915 goto read_error;
Christopher Faulet31af49d2015-06-09 17:29:50 +02003916 }
Christopher Fauletc6f02fb2015-10-09 10:53:31 +02003917 rewind(fp);
Christopher Faulet31af49d2015-06-09 17:29:50 +02003918 if (!(capkey = PEM_read_PrivateKey(fp, NULL, NULL, bind_conf->ca_sign_pass))) {
3919 Alert("Proxy '%s': Failed to read CA private key file '%s' at [%s:%d].\n",
3920 px->id, bind_conf->ca_sign_file, bind_conf->file, bind_conf->line);
Christopher Fauletc6f02fb2015-10-09 10:53:31 +02003921 goto read_error;
Christopher Faulet31af49d2015-06-09 17:29:50 +02003922 }
Christopher Faulet31af49d2015-06-09 17:29:50 +02003923
Christopher Fauletc6f02fb2015-10-09 10:53:31 +02003924 fclose (fp);
Christopher Faulet31af49d2015-06-09 17:29:50 +02003925 bind_conf->ca_sign_cert = cacert;
3926 bind_conf->ca_sign_pkey = capkey;
3927 return err;
3928
Christopher Fauletc6f02fb2015-10-09 10:53:31 +02003929 read_error:
3930 fclose (fp);
Christopher Faulet31af49d2015-06-09 17:29:50 +02003931 if (capkey) EVP_PKEY_free(capkey);
3932 if (cacert) X509_free(cacert);
Christopher Fauletc6f02fb2015-10-09 10:53:31 +02003933 load_error:
3934 bind_conf->generate_certs = 0;
3935 err++;
Christopher Faulet31af49d2015-06-09 17:29:50 +02003936 return err;
3937}
3938
3939/* Release CA cert and private key used to generate certificated */
3940void
3941ssl_sock_free_ca(struct bind_conf *bind_conf)
3942{
3943 if (!bind_conf)
3944 return;
3945
3946 if (bind_conf->ca_sign_pkey)
3947 EVP_PKEY_free(bind_conf->ca_sign_pkey);
3948 if (bind_conf->ca_sign_cert)
3949 X509_free(bind_conf->ca_sign_cert);
Willy Tarreau94ff03a2016-12-22 17:57:46 +01003950 bind_conf->ca_sign_pkey = NULL;
3951 bind_conf->ca_sign_cert = NULL;
Christopher Faulet31af49d2015-06-09 17:29:50 +02003952}
3953
Emeric Brun46591952012-05-18 15:47:34 +02003954/*
3955 * This function is called if SSL * context is not yet allocated. The function
3956 * is designed to be called before any other data-layer operation and sets the
3957 * handshake flag on the connection. It is safe to call it multiple times.
3958 * It returns 0 on success and -1 in error case.
3959 */
3960static int ssl_sock_init(struct connection *conn)
3961{
3962 /* already initialized */
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02003963 if (conn->xprt_ctx)
Emeric Brun46591952012-05-18 15:47:34 +02003964 return 0;
3965
Willy Tarreau3c728722014-01-23 13:50:42 +01003966 if (!conn_ctrl_ready(conn))
Willy Tarreauf79c8172013-10-21 16:30:56 +02003967 return 0;
3968
Willy Tarreau20879a02012-12-03 16:32:10 +01003969 if (global.maxsslconn && sslconns >= global.maxsslconn) {
3970 conn->err_code = CO_ER_SSL_TOO_MANY;
Willy Tarreau403edff2012-09-06 11:58:37 +02003971 return -1;
Willy Tarreau20879a02012-12-03 16:32:10 +01003972 }
Willy Tarreau403edff2012-09-06 11:58:37 +02003973
Emeric Brun46591952012-05-18 15:47:34 +02003974 /* If it is in client mode initiate SSL session
3975 in connect state otherwise accept state */
Willy Tarreau3fdb3662012-11-12 00:42:33 +01003976 if (objt_server(conn->target)) {
Willy Tarreaufba03cd2014-11-13 13:48:58 +01003977 int may_retry = 1;
3978
3979 retry_connect:
Emeric Brun46591952012-05-18 15:47:34 +02003980 /* Alloc a new SSL session ctx */
Willy Tarreau3fdb3662012-11-12 00:42:33 +01003981 conn->xprt_ctx = SSL_new(objt_server(conn->target)->ssl_ctx.ctx);
Willy Tarreau20879a02012-12-03 16:32:10 +01003982 if (!conn->xprt_ctx) {
Willy Tarreaufba03cd2014-11-13 13:48:58 +01003983 if (may_retry--) {
3984 pool_gc2();
3985 goto retry_connect;
3986 }
Willy Tarreau20879a02012-12-03 16:32:10 +01003987 conn->err_code = CO_ER_SSL_NO_MEM;
Emeric Brun46591952012-05-18 15:47:34 +02003988 return -1;
Willy Tarreau20879a02012-12-03 16:32:10 +01003989 }
Emeric Brun46591952012-05-18 15:47:34 +02003990
Emeric Brun46591952012-05-18 15:47:34 +02003991 /* set fd on SSL session context */
Emeric Brun55476152014-11-12 17:35:37 +01003992 if (!SSL_set_fd(conn->xprt_ctx, conn->t.sock.fd)) {
3993 SSL_free(conn->xprt_ctx);
3994 conn->xprt_ctx = NULL;
Willy Tarreaufba03cd2014-11-13 13:48:58 +01003995 if (may_retry--) {
3996 pool_gc2();
3997 goto retry_connect;
3998 }
Emeric Brun55476152014-11-12 17:35:37 +01003999 conn->err_code = CO_ER_SSL_NO_MEM;
4000 return -1;
4001 }
Emeric Brun46591952012-05-18 15:47:34 +02004002
Evan Broderbe554312013-06-27 00:05:25 -07004003 /* set connection pointer */
Emeric Brun55476152014-11-12 17:35:37 +01004004 if (!SSL_set_app_data(conn->xprt_ctx, conn)) {
4005 SSL_free(conn->xprt_ctx);
4006 conn->xprt_ctx = NULL;
Willy Tarreaufba03cd2014-11-13 13:48:58 +01004007 if (may_retry--) {
4008 pool_gc2();
4009 goto retry_connect;
4010 }
Emeric Brun55476152014-11-12 17:35:37 +01004011 conn->err_code = CO_ER_SSL_NO_MEM;
4012 return -1;
4013 }
4014
4015 SSL_set_connect_state(conn->xprt_ctx);
4016 if (objt_server(conn->target)->ssl_ctx.reused_sess) {
4017 if(!SSL_set_session(conn->xprt_ctx, objt_server(conn->target)->ssl_ctx.reused_sess)) {
4018 SSL_SESSION_free(objt_server(conn->target)->ssl_ctx.reused_sess);
4019 objt_server(conn->target)->ssl_ctx.reused_sess = NULL;
4020 }
4021 }
Evan Broderbe554312013-06-27 00:05:25 -07004022
Emeric Brun46591952012-05-18 15:47:34 +02004023 /* leave init state and start handshake */
Willy Tarreau05737472012-09-04 08:03:39 +02004024 conn->flags |= CO_FL_SSL_WAIT_HS | CO_FL_WAIT_L6_CONN;
Willy Tarreau403edff2012-09-06 11:58:37 +02004025
4026 sslconns++;
Willy Tarreau71b734c2014-01-28 15:19:44 +01004027 totalsslconns++;
Emeric Brun46591952012-05-18 15:47:34 +02004028 return 0;
4029 }
Willy Tarreau3fdb3662012-11-12 00:42:33 +01004030 else if (objt_listener(conn->target)) {
Willy Tarreaufba03cd2014-11-13 13:48:58 +01004031 int may_retry = 1;
4032
4033 retry_accept:
Emeric Brun46591952012-05-18 15:47:34 +02004034 /* Alloc a new SSL session ctx */
Emmanuel Hocdetf6b37c62017-03-06 15:34:44 +01004035 conn->xprt_ctx = SSL_new(objt_listener(conn->target)->bind_conf->initial_ctx);
Willy Tarreau20879a02012-12-03 16:32:10 +01004036 if (!conn->xprt_ctx) {
Willy Tarreaufba03cd2014-11-13 13:48:58 +01004037 if (may_retry--) {
4038 pool_gc2();
4039 goto retry_accept;
4040 }
Willy Tarreau20879a02012-12-03 16:32:10 +01004041 conn->err_code = CO_ER_SSL_NO_MEM;
Emeric Brun46591952012-05-18 15:47:34 +02004042 return -1;
Willy Tarreau20879a02012-12-03 16:32:10 +01004043 }
Emeric Brun46591952012-05-18 15:47:34 +02004044
Emeric Brun46591952012-05-18 15:47:34 +02004045 /* set fd on SSL session context */
Emeric Brun55476152014-11-12 17:35:37 +01004046 if (!SSL_set_fd(conn->xprt_ctx, conn->t.sock.fd)) {
4047 SSL_free(conn->xprt_ctx);
4048 conn->xprt_ctx = NULL;
Willy Tarreaufba03cd2014-11-13 13:48:58 +01004049 if (may_retry--) {
4050 pool_gc2();
4051 goto retry_accept;
4052 }
Emeric Brun55476152014-11-12 17:35:37 +01004053 conn->err_code = CO_ER_SSL_NO_MEM;
4054 return -1;
4055 }
Emeric Brun46591952012-05-18 15:47:34 +02004056
Emeric Brune1f38db2012-09-03 20:36:47 +02004057 /* set connection pointer */
Emeric Brun55476152014-11-12 17:35:37 +01004058 if (!SSL_set_app_data(conn->xprt_ctx, conn)) {
4059 SSL_free(conn->xprt_ctx);
4060 conn->xprt_ctx = NULL;
Willy Tarreaufba03cd2014-11-13 13:48:58 +01004061 if (may_retry--) {
4062 pool_gc2();
4063 goto retry_accept;
4064 }
Emeric Brun55476152014-11-12 17:35:37 +01004065 conn->err_code = CO_ER_SSL_NO_MEM;
4066 return -1;
4067 }
4068
4069 SSL_set_accept_state(conn->xprt_ctx);
Emeric Brune1f38db2012-09-03 20:36:47 +02004070
Emeric Brun46591952012-05-18 15:47:34 +02004071 /* leave init state and start handshake */
Willy Tarreau05737472012-09-04 08:03:39 +02004072 conn->flags |= CO_FL_SSL_WAIT_HS | CO_FL_WAIT_L6_CONN;
Willy Tarreau403edff2012-09-06 11:58:37 +02004073
4074 sslconns++;
Willy Tarreau71b734c2014-01-28 15:19:44 +01004075 totalsslconns++;
Emeric Brun46591952012-05-18 15:47:34 +02004076 return 0;
4077 }
4078 /* don't know how to handle such a target */
Willy Tarreau20879a02012-12-03 16:32:10 +01004079 conn->err_code = CO_ER_SSL_NO_TARGET;
Emeric Brun46591952012-05-18 15:47:34 +02004080 return -1;
4081}
4082
4083
4084/* This is the callback which is used when an SSL handshake is pending. It
4085 * updates the FD status if it wants some polling before being called again.
4086 * It returns 0 if it fails in a fatal way or needs to poll to go further,
4087 * otherwise it returns non-zero and removes itself from the connection's
4088 * flags (the bit is provided in <flag> by the caller).
4089 */
4090int ssl_sock_handshake(struct connection *conn, unsigned int flag)
4091{
4092 int ret;
4093
Willy Tarreau3c728722014-01-23 13:50:42 +01004094 if (!conn_ctrl_ready(conn))
Willy Tarreauf79c8172013-10-21 16:30:56 +02004095 return 0;
4096
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02004097 if (!conn->xprt_ctx)
Emeric Brun46591952012-05-18 15:47:34 +02004098 goto out_error;
4099
Emeric Brun674b7432012-11-08 19:21:55 +01004100 /* If we use SSL_do_handshake to process a reneg initiated by
4101 * the remote peer, it sometimes returns SSL_ERROR_SSL.
4102 * Usually SSL_write and SSL_read are used and process implicitly
4103 * the reneg handshake.
4104 * Here we use SSL_peek as a workaround for reneg.
4105 */
4106 if ((conn->flags & CO_FL_CONNECTED) && SSL_renegotiate_pending(conn->xprt_ctx)) {
4107 char c;
4108
4109 ret = SSL_peek(conn->xprt_ctx, &c, 1);
4110 if (ret <= 0) {
4111 /* handshake may have not been completed, let's find why */
4112 ret = SSL_get_error(conn->xprt_ctx, ret);
4113 if (ret == SSL_ERROR_WANT_WRITE) {
4114 /* SSL handshake needs to write, L4 connection may not be ready */
4115 __conn_sock_stop_recv(conn);
Willy Tarreaue1f50c42014-01-22 20:02:06 +01004116 __conn_sock_want_send(conn);
4117 fd_cant_send(conn->t.sock.fd);
Emeric Brun674b7432012-11-08 19:21:55 +01004118 return 0;
4119 }
4120 else if (ret == SSL_ERROR_WANT_READ) {
4121 /* handshake may have been completed but we have
4122 * no more data to read.
4123 */
4124 if (!SSL_renegotiate_pending(conn->xprt_ctx)) {
4125 ret = 1;
4126 goto reneg_ok;
4127 }
4128 /* SSL handshake needs to read, L4 connection is ready */
4129 if (conn->flags & CO_FL_WAIT_L4_CONN)
4130 conn->flags &= ~CO_FL_WAIT_L4_CONN;
4131 __conn_sock_stop_send(conn);
Willy Tarreaue1f50c42014-01-22 20:02:06 +01004132 __conn_sock_want_recv(conn);
4133 fd_cant_recv(conn->t.sock.fd);
Emeric Brun674b7432012-11-08 19:21:55 +01004134 return 0;
4135 }
4136 else if (ret == SSL_ERROR_SYSCALL) {
4137 /* if errno is null, then connection was successfully established */
4138 if (!errno && conn->flags & CO_FL_WAIT_L4_CONN)
4139 conn->flags &= ~CO_FL_WAIT_L4_CONN;
Willy Tarreau20879a02012-12-03 16:32:10 +01004140 if (!conn->err_code) {
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +01004141#ifdef OPENSSL_NO_HEARTBEATS /* BoringSSL */
4142 conn->err_code = CO_ER_SSL_HANDSHAKE;
4143#else
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004144 int empty_handshake;
Luca Pizzamiglio578b1692016-12-12 10:56:56 +01004145#if (OPENSSL_VERSION_NUMBER >= 0x1010000fL) && !defined(LIBRESSL_VERSION_NUMBER)
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004146 OSSL_HANDSHAKE_STATE state = SSL_get_state((SSL *)conn->xprt_ctx);
4147 empty_handshake = state == TLS_ST_BEFORE;
4148#else
4149 empty_handshake = !((SSL *)conn->xprt_ctx)->packet_length;
4150#endif
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004151 if (empty_handshake) {
Emeric Brun29f037d2014-04-25 19:05:36 +02004152 if (!errno) {
4153 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
4154 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
4155 else
4156 conn->err_code = CO_ER_SSL_EMPTY;
4157 }
4158 else {
4159 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
4160 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
4161 else
4162 conn->err_code = CO_ER_SSL_ABORT;
4163 }
4164 }
4165 else {
4166 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
4167 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
Willy Tarreau20879a02012-12-03 16:32:10 +01004168 else
Emeric Brun29f037d2014-04-25 19:05:36 +02004169 conn->err_code = CO_ER_SSL_HANDSHAKE;
4170 }
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +01004171#endif
Willy Tarreau20879a02012-12-03 16:32:10 +01004172 }
Emeric Brun674b7432012-11-08 19:21:55 +01004173 goto out_error;
4174 }
4175 else {
4176 /* Fail on all other handshake errors */
4177 /* Note: OpenSSL may leave unread bytes in the socket's
4178 * buffer, causing an RST to be emitted upon close() on
4179 * TCP sockets. We first try to drain possibly pending
4180 * data to avoid this as much as possible.
4181 */
Willy Tarreaud85c4852015-03-13 00:40:28 +01004182 conn_sock_drain(conn);
Willy Tarreau20879a02012-12-03 16:32:10 +01004183 if (!conn->err_code)
Willy Tarreauf51c6982014-04-25 20:02:39 +02004184 conn->err_code = (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT) ?
4185 CO_ER_SSL_KILLED_HB : CO_ER_SSL_HANDSHAKE;
Emeric Brun674b7432012-11-08 19:21:55 +01004186 goto out_error;
4187 }
4188 }
4189 /* read some data: consider handshake completed */
4190 goto reneg_ok;
4191 }
4192
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02004193 ret = SSL_do_handshake(conn->xprt_ctx);
Emeric Brun46591952012-05-18 15:47:34 +02004194 if (ret != 1) {
4195 /* handshake did not complete, let's find why */
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02004196 ret = SSL_get_error(conn->xprt_ctx, ret);
Emeric Brun46591952012-05-18 15:47:34 +02004197
4198 if (ret == SSL_ERROR_WANT_WRITE) {
4199 /* SSL handshake needs to write, L4 connection may not be ready */
4200 __conn_sock_stop_recv(conn);
Willy Tarreaue1f50c42014-01-22 20:02:06 +01004201 __conn_sock_want_send(conn);
4202 fd_cant_send(conn->t.sock.fd);
Emeric Brun46591952012-05-18 15:47:34 +02004203 return 0;
4204 }
4205 else if (ret == SSL_ERROR_WANT_READ) {
4206 /* SSL handshake needs to read, L4 connection is ready */
4207 if (conn->flags & CO_FL_WAIT_L4_CONN)
4208 conn->flags &= ~CO_FL_WAIT_L4_CONN;
4209 __conn_sock_stop_send(conn);
Willy Tarreaue1f50c42014-01-22 20:02:06 +01004210 __conn_sock_want_recv(conn);
4211 fd_cant_recv(conn->t.sock.fd);
Emeric Brun46591952012-05-18 15:47:34 +02004212 return 0;
4213 }
Willy Tarreau89230192012-09-28 20:22:13 +02004214 else if (ret == SSL_ERROR_SYSCALL) {
4215 /* if errno is null, then connection was successfully established */
4216 if (!errno && conn->flags & CO_FL_WAIT_L4_CONN)
4217 conn->flags &= ~CO_FL_WAIT_L4_CONN;
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +01004218 if (!conn->err_code) {
4219#ifdef OPENSSL_NO_HEARTBEATS /* BoringSSL */
4220 conn->err_code = CO_ER_SSL_HANDSHAKE;
4221#else
4222 int empty_handshake;
Luca Pizzamiglio578b1692016-12-12 10:56:56 +01004223#if (OPENSSL_VERSION_NUMBER >= 0x1010000fL) && !defined(LIBRESSL_VERSION_NUMBER)
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +01004224 OSSL_HANDSHAKE_STATE state = SSL_get_state((SSL *)conn->xprt_ctx);
4225 empty_handshake = state == TLS_ST_BEFORE;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004226#else
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +01004227 empty_handshake = !((SSL *)conn->xprt_ctx)->packet_length;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004228#endif
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +01004229 if (empty_handshake) {
4230 if (!errno) {
4231 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
4232 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
4233 else
4234 conn->err_code = CO_ER_SSL_EMPTY;
4235 }
4236 else {
4237 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
4238 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
4239 else
4240 conn->err_code = CO_ER_SSL_ABORT;
4241 }
Emeric Brun29f037d2014-04-25 19:05:36 +02004242 }
4243 else {
4244 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
4245 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
4246 else
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +01004247 conn->err_code = CO_ER_SSL_HANDSHAKE;
Emeric Brun29f037d2014-04-25 19:05:36 +02004248 }
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +01004249#endif
Emeric Brun29f037d2014-04-25 19:05:36 +02004250 }
Willy Tarreau89230192012-09-28 20:22:13 +02004251 goto out_error;
4252 }
Emeric Brun46591952012-05-18 15:47:34 +02004253 else {
4254 /* Fail on all other handshake errors */
Willy Tarreau566dc552012-10-19 20:52:18 +02004255 /* Note: OpenSSL may leave unread bytes in the socket's
4256 * buffer, causing an RST to be emitted upon close() on
4257 * TCP sockets. We first try to drain possibly pending
4258 * data to avoid this as much as possible.
4259 */
Willy Tarreaud85c4852015-03-13 00:40:28 +01004260 conn_sock_drain(conn);
Willy Tarreau20879a02012-12-03 16:32:10 +01004261 if (!conn->err_code)
Willy Tarreauf51c6982014-04-25 20:02:39 +02004262 conn->err_code = (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT) ?
4263 CO_ER_SSL_KILLED_HB : CO_ER_SSL_HANDSHAKE;
Emeric Brun46591952012-05-18 15:47:34 +02004264 goto out_error;
4265 }
4266 }
4267
Emeric Brun674b7432012-11-08 19:21:55 +01004268reneg_ok:
Emeric Brun46591952012-05-18 15:47:34 +02004269 /* Handshake succeeded */
Willy Tarreau0c9c2722014-05-28 12:28:58 +02004270 if (!SSL_session_reused(conn->xprt_ctx)) {
4271 if (objt_server(conn->target)) {
4272 update_freq_ctr(&global.ssl_be_keys_per_sec, 1);
4273 if (global.ssl_be_keys_per_sec.curr_ctr > global.ssl_be_keys_max)
4274 global.ssl_be_keys_max = global.ssl_be_keys_per_sec.curr_ctr;
4275
Emeric Brun46591952012-05-18 15:47:34 +02004276 /* check if session was reused, if not store current session on server for reuse */
Willy Tarreau30fd4bd2016-12-22 21:54:21 +01004277 if (objt_server(conn->target)->ssl_ctx.reused_sess) {
Willy Tarreau3fdb3662012-11-12 00:42:33 +01004278 SSL_SESSION_free(objt_server(conn->target)->ssl_ctx.reused_sess);
Willy Tarreau30fd4bd2016-12-22 21:54:21 +01004279 objt_server(conn->target)->ssl_ctx.reused_sess = NULL;
4280 }
Emeric Brun46591952012-05-18 15:47:34 +02004281
Willy Tarreau2a3fb1c2015-02-05 16:47:07 +01004282 if (!(objt_server(conn->target)->ssl_ctx.options & SRV_SSL_O_NO_REUSE))
4283 objt_server(conn->target)->ssl_ctx.reused_sess = SSL_get1_session(conn->xprt_ctx);
Emeric Brun46591952012-05-18 15:47:34 +02004284 }
Willy Tarreau0c9c2722014-05-28 12:28:58 +02004285 else {
4286 update_freq_ctr(&global.ssl_fe_keys_per_sec, 1);
4287 if (global.ssl_fe_keys_per_sec.curr_ctr > global.ssl_fe_keys_max)
4288 global.ssl_fe_keys_max = global.ssl_fe_keys_per_sec.curr_ctr;
4289 }
Emeric Brun46591952012-05-18 15:47:34 +02004290 }
4291
4292 /* The connection is now established at both layers, it's time to leave */
4293 conn->flags &= ~(flag | CO_FL_WAIT_L4_CONN | CO_FL_WAIT_L6_CONN);
4294 return 1;
4295
4296 out_error:
Emeric Brun644cde02012-12-14 11:21:13 +01004297 /* Clear openssl global errors stack */
Thierry FOURNIER / OZON.IO8b068c22016-10-10 11:59:50 +02004298 ssl_sock_dump_errors(conn);
Emeric Brun644cde02012-12-14 11:21:13 +01004299 ERR_clear_error();
4300
Emeric Brun9fa89732012-10-04 17:09:56 +02004301 /* free resumed session if exists */
Willy Tarreau3fdb3662012-11-12 00:42:33 +01004302 if (objt_server(conn->target) && objt_server(conn->target)->ssl_ctx.reused_sess) {
4303 SSL_SESSION_free(objt_server(conn->target)->ssl_ctx.reused_sess);
4304 objt_server(conn->target)->ssl_ctx.reused_sess = NULL;
Emeric Brun9fa89732012-10-04 17:09:56 +02004305 }
4306
Emeric Brun46591952012-05-18 15:47:34 +02004307 /* Fail on all other handshake errors */
4308 conn->flags |= CO_FL_ERROR;
Willy Tarreau20879a02012-12-03 16:32:10 +01004309 if (!conn->err_code)
4310 conn->err_code = CO_ER_SSL_HANDSHAKE;
Emeric Brun46591952012-05-18 15:47:34 +02004311 return 0;
4312}
4313
4314/* Receive up to <count> bytes from connection <conn>'s socket and store them
Willy Tarreauabf08d92014-01-14 11:31:27 +01004315 * into buffer <buf>. Only one call to recv() is performed, unless the
Emeric Brun46591952012-05-18 15:47:34 +02004316 * buffer wraps, in which case a second call may be performed. The connection's
4317 * flags are updated with whatever special event is detected (error, read0,
4318 * empty). The caller is responsible for taking care of those events and
4319 * avoiding the call if inappropriate. The function does not call the
4320 * connection's polling update function, so the caller is responsible for this.
4321 */
4322static int ssl_sock_to_buf(struct connection *conn, struct buffer *buf, int count)
4323{
4324 int ret, done = 0;
Willy Tarreauabf08d92014-01-14 11:31:27 +01004325 int try;
Emeric Brun46591952012-05-18 15:47:34 +02004326
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02004327 if (!conn->xprt_ctx)
Emeric Brun46591952012-05-18 15:47:34 +02004328 goto out_error;
4329
4330 if (conn->flags & CO_FL_HANDSHAKE)
4331 /* a handshake was requested */
4332 return 0;
4333
Willy Tarreauabf08d92014-01-14 11:31:27 +01004334 /* let's realign the buffer to optimize I/O */
4335 if (buffer_empty(buf))
Emeric Brun46591952012-05-18 15:47:34 +02004336 buf->p = buf->data;
Emeric Brun46591952012-05-18 15:47:34 +02004337
4338 /* read the largest possible block. For this, we perform only one call
4339 * to recv() unless the buffer wraps and we exactly fill the first hunk,
4340 * in which case we accept to do it once again. A new attempt is made on
4341 * EINTR too.
4342 */
Willy Tarreau00b0fb92014-01-17 11:09:40 +01004343 while (count > 0) {
Willy Tarreauabf08d92014-01-14 11:31:27 +01004344 /* first check if we have some room after p+i */
4345 try = buf->data + buf->size - (buf->p + buf->i);
4346 /* otherwise continue between data and p-o */
4347 if (try <= 0) {
4348 try = buf->p - (buf->data + buf->o);
4349 if (try <= 0)
4350 break;
4351 }
4352 if (try > count)
4353 try = count;
4354
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02004355 ret = SSL_read(conn->xprt_ctx, bi_end(buf), try);
Emeric Brune1f38db2012-09-03 20:36:47 +02004356 if (conn->flags & CO_FL_ERROR) {
4357 /* CO_FL_ERROR may be set by ssl_sock_infocbk */
Emeric Brun644cde02012-12-14 11:21:13 +01004358 goto out_error;
Emeric Brune1f38db2012-09-03 20:36:47 +02004359 }
Emeric Brun46591952012-05-18 15:47:34 +02004360 if (ret > 0) {
4361 buf->i += ret;
4362 done += ret;
4363 if (ret < try)
4364 break;
4365 count -= ret;
Emeric Brun46591952012-05-18 15:47:34 +02004366 }
4367 else if (ret == 0) {
Emeric Brun644cde02012-12-14 11:21:13 +01004368 ret = SSL_get_error(conn->xprt_ctx, ret);
4369 if (ret != SSL_ERROR_ZERO_RETURN) {
Emeric Brun1c646862012-12-14 12:33:41 +01004370 /* error on protocol or underlying transport */
4371 if ((ret != SSL_ERROR_SYSCALL)
4372 || (errno && (errno != EAGAIN)))
4373 conn->flags |= CO_FL_ERROR;
4374
Emeric Brun644cde02012-12-14 11:21:13 +01004375 /* Clear openssl global errors stack */
Thierry FOURNIER / OZON.IO8b068c22016-10-10 11:59:50 +02004376 ssl_sock_dump_errors(conn);
Emeric Brun644cde02012-12-14 11:21:13 +01004377 ERR_clear_error();
4378 }
Emeric Brun46591952012-05-18 15:47:34 +02004379 goto read0;
4380 }
4381 else {
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02004382 ret = SSL_get_error(conn->xprt_ctx, ret);
Emeric Brun46591952012-05-18 15:47:34 +02004383 if (ret == SSL_ERROR_WANT_WRITE) {
Emeric Brun8af8dd12012-11-08 17:56:20 +01004384 /* handshake is running, and it needs to enable write */
Emeric Brun46591952012-05-18 15:47:34 +02004385 conn->flags |= CO_FL_SSL_WAIT_HS;
Emeric Brun8af8dd12012-11-08 17:56:20 +01004386 __conn_sock_want_send(conn);
Emeric Brun46591952012-05-18 15:47:34 +02004387 break;
4388 }
4389 else if (ret == SSL_ERROR_WANT_READ) {
Emeric Brun282a76a2012-11-08 18:02:56 +01004390 if (SSL_renegotiate_pending(conn->xprt_ctx)) {
4391 /* handshake is running, and it may need to re-enable read */
4392 conn->flags |= CO_FL_SSL_WAIT_HS;
4393 __conn_sock_want_recv(conn);
4394 break;
4395 }
Emeric Brun46591952012-05-18 15:47:34 +02004396 /* we need to poll for retry a read later */
Willy Tarreaue1f50c42014-01-22 20:02:06 +01004397 fd_cant_recv(conn->t.sock.fd);
Emeric Brun46591952012-05-18 15:47:34 +02004398 break;
4399 }
4400 /* otherwise it's a real error */
4401 goto out_error;
4402 }
4403 }
4404 return done;
4405
4406 read0:
4407 conn_sock_read0(conn);
4408 return done;
4409 out_error:
Emeric Brun644cde02012-12-14 11:21:13 +01004410 /* Clear openssl global errors stack */
Thierry FOURNIER / OZON.IO8b068c22016-10-10 11:59:50 +02004411 ssl_sock_dump_errors(conn);
Emeric Brun644cde02012-12-14 11:21:13 +01004412 ERR_clear_error();
4413
Emeric Brun46591952012-05-18 15:47:34 +02004414 conn->flags |= CO_FL_ERROR;
4415 return done;
4416}
4417
4418
4419/* Send all pending bytes from buffer <buf> to connection <conn>'s socket.
Willy Tarreau1049b1f2014-02-02 01:51:17 +01004420 * <flags> may contain some CO_SFL_* flags to hint the system about other
4421 * pending data for example, but this flag is ignored at the moment.
Emeric Brun46591952012-05-18 15:47:34 +02004422 * Only one call to send() is performed, unless the buffer wraps, in which case
4423 * a second call may be performed. The connection's flags are updated with
4424 * whatever special event is detected (error, empty). The caller is responsible
4425 * for taking care of those events and avoiding the call if inappropriate. The
4426 * function does not call the connection's polling update function, so the caller
4427 * is responsible for this.
4428 */
4429static int ssl_sock_from_buf(struct connection *conn, struct buffer *buf, int flags)
4430{
4431 int ret, try, done;
4432
4433 done = 0;
4434
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02004435 if (!conn->xprt_ctx)
Emeric Brun46591952012-05-18 15:47:34 +02004436 goto out_error;
4437
4438 if (conn->flags & CO_FL_HANDSHAKE)
4439 /* a handshake was requested */
4440 return 0;
4441
4442 /* send the largest possible block. For this we perform only one call
4443 * to send() unless the buffer wraps and we exactly fill the first hunk,
4444 * in which case we accept to do it once again.
4445 */
4446 while (buf->o) {
Kevin Hestercad82342013-05-30 15:12:41 -07004447 try = bo_contig_data(buf);
Willy Tarreaubfd59462013-02-21 07:46:09 +01004448
Willy Tarreau7bed9452014-02-02 02:00:24 +01004449 if (!(flags & CO_SFL_STREAMER) &&
Willy Tarreau518cedd2014-02-17 15:43:01 +01004450 !(conn->xprt_st & SSL_SOCK_SEND_UNLIMITED) &&
Willy Tarreauef934602016-12-22 23:12:01 +01004451 global_ssl.max_record && try > global_ssl.max_record) {
4452 try = global_ssl.max_record;
Willy Tarreau518cedd2014-02-17 15:43:01 +01004453 }
4454 else {
4455 /* we need to keep the information about the fact that
4456 * we're not limiting the upcoming send(), because if it
4457 * fails, we'll have to retry with at least as many data.
4458 */
4459 conn->xprt_st |= SSL_SOCK_SEND_UNLIMITED;
4460 }
Willy Tarreaubfd59462013-02-21 07:46:09 +01004461
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02004462 ret = SSL_write(conn->xprt_ctx, bo_ptr(buf), try);
Willy Tarreau518cedd2014-02-17 15:43:01 +01004463
Emeric Brune1f38db2012-09-03 20:36:47 +02004464 if (conn->flags & CO_FL_ERROR) {
4465 /* CO_FL_ERROR may be set by ssl_sock_infocbk */
Emeric Brun644cde02012-12-14 11:21:13 +01004466 goto out_error;
Emeric Brune1f38db2012-09-03 20:36:47 +02004467 }
Emeric Brun46591952012-05-18 15:47:34 +02004468 if (ret > 0) {
Willy Tarreau518cedd2014-02-17 15:43:01 +01004469 conn->xprt_st &= ~SSL_SOCK_SEND_UNLIMITED;
4470
Emeric Brun46591952012-05-18 15:47:34 +02004471 buf->o -= ret;
4472 done += ret;
4473
Willy Tarreau5fb38032012-12-16 19:39:09 +01004474 if (likely(buffer_empty(buf)))
Emeric Brun46591952012-05-18 15:47:34 +02004475 /* optimize data alignment in the buffer */
4476 buf->p = buf->data;
4477
4478 /* if the system buffer is full, don't insist */
4479 if (ret < try)
4480 break;
4481 }
4482 else {
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02004483 ret = SSL_get_error(conn->xprt_ctx, ret);
Emeric Brun46591952012-05-18 15:47:34 +02004484 if (ret == SSL_ERROR_WANT_WRITE) {
Emeric Brun282a76a2012-11-08 18:02:56 +01004485 if (SSL_renegotiate_pending(conn->xprt_ctx)) {
4486 /* handshake is running, and it may need to re-enable write */
4487 conn->flags |= CO_FL_SSL_WAIT_HS;
4488 __conn_sock_want_send(conn);
4489 break;
4490 }
Emeric Brun46591952012-05-18 15:47:34 +02004491 /* we need to poll to retry a write later */
Willy Tarreaue1f50c42014-01-22 20:02:06 +01004492 fd_cant_send(conn->t.sock.fd);
Emeric Brun46591952012-05-18 15:47:34 +02004493 break;
4494 }
4495 else if (ret == SSL_ERROR_WANT_READ) {
Emeric Brun8af8dd12012-11-08 17:56:20 +01004496 /* handshake is running, and it needs to enable read */
Emeric Brun46591952012-05-18 15:47:34 +02004497 conn->flags |= CO_FL_SSL_WAIT_HS;
Emeric Brun8af8dd12012-11-08 17:56:20 +01004498 __conn_sock_want_recv(conn);
Emeric Brun46591952012-05-18 15:47:34 +02004499 break;
4500 }
4501 goto out_error;
4502 }
4503 }
4504 return done;
4505
4506 out_error:
Emeric Brun644cde02012-12-14 11:21:13 +01004507 /* Clear openssl global errors stack */
Thierry FOURNIER / OZON.IO8b068c22016-10-10 11:59:50 +02004508 ssl_sock_dump_errors(conn);
Emeric Brun644cde02012-12-14 11:21:13 +01004509 ERR_clear_error();
4510
Emeric Brun46591952012-05-18 15:47:34 +02004511 conn->flags |= CO_FL_ERROR;
4512 return done;
4513}
4514
Emeric Brun46591952012-05-18 15:47:34 +02004515static void ssl_sock_close(struct connection *conn) {
4516
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02004517 if (conn->xprt_ctx) {
4518 SSL_free(conn->xprt_ctx);
4519 conn->xprt_ctx = NULL;
Willy Tarreau403edff2012-09-06 11:58:37 +02004520 sslconns--;
Emeric Brun46591952012-05-18 15:47:34 +02004521 }
Emeric Brun46591952012-05-18 15:47:34 +02004522}
4523
4524/* This function tries to perform a clean shutdown on an SSL connection, and in
4525 * any case, flags the connection as reusable if no handshake was in progress.
4526 */
4527static void ssl_sock_shutw(struct connection *conn, int clean)
4528{
4529 if (conn->flags & CO_FL_HANDSHAKE)
4530 return;
Emmanuel Hocdet405ff312017-01-08 14:07:39 +01004531 if (!clean)
4532 /* don't sent notify on SSL_shutdown */
Willy Tarreaue3cc3a32017-02-13 11:12:29 +01004533 SSL_set_quiet_shutdown(conn->xprt_ctx, 1);
Emeric Brun46591952012-05-18 15:47:34 +02004534 /* no handshake was in progress, try a clean ssl shutdown */
Emmanuel Hocdet405ff312017-01-08 14:07:39 +01004535 if (SSL_shutdown(conn->xprt_ctx) <= 0) {
Emeric Brun644cde02012-12-14 11:21:13 +01004536 /* Clear openssl global errors stack */
Thierry FOURNIER / OZON.IO8b068c22016-10-10 11:59:50 +02004537 ssl_sock_dump_errors(conn);
Emeric Brun644cde02012-12-14 11:21:13 +01004538 ERR_clear_error();
4539 }
Emeric Brun46591952012-05-18 15:47:34 +02004540}
4541
Willy Tarreauffc3fcd2012-10-12 20:17:54 +02004542/* used for logging, may be changed for a sample fetch later */
4543const char *ssl_sock_get_cipher_name(struct connection *conn)
4544{
4545 if (!conn->xprt && !conn->xprt_ctx)
4546 return NULL;
4547 return SSL_get_cipher_name(conn->xprt_ctx);
4548}
4549
4550/* used for logging, may be changed for a sample fetch later */
4551const char *ssl_sock_get_proto_version(struct connection *conn)
4552{
4553 if (!conn->xprt && !conn->xprt_ctx)
4554 return NULL;
4555 return SSL_get_version(conn->xprt_ctx);
4556}
4557
Willy Tarreau8d598402012-10-22 17:58:39 +02004558/* Extract a serial from a cert, and copy it to a chunk.
4559 * Returns 1 if serial is found and copied, 0 if no serial found and
4560 * -1 if output is not large enough.
4561 */
4562static int
4563ssl_sock_get_serial(X509 *crt, struct chunk *out)
4564{
4565 ASN1_INTEGER *serial;
4566
4567 serial = X509_get_serialNumber(crt);
4568 if (!serial)
4569 return 0;
4570
4571 if (out->size < serial->length)
4572 return -1;
4573
4574 memcpy(out->str, serial->data, serial->length);
4575 out->len = serial->length;
4576 return 1;
4577}
4578
Emeric Brun43e79582014-10-29 19:03:26 +01004579/* Extract a cert to der, and copy it to a chunk.
4580 * Returns 1 if cert is found and copied, 0 on der convertion failure and
4581 * -1 if output is not large enough.
4582 */
4583static int
4584ssl_sock_crt2der(X509 *crt, struct chunk *out)
4585{
4586 int len;
4587 unsigned char *p = (unsigned char *)out->str;;
4588
4589 len =i2d_X509(crt, NULL);
4590 if (len <= 0)
4591 return 1;
4592
4593 if (out->size < len)
4594 return -1;
4595
4596 i2d_X509(crt,&p);
4597 out->len = len;
4598 return 1;
4599}
4600
Emeric Brunce5ad802012-10-22 14:11:22 +02004601
4602/* Copy Date in ASN1_UTCTIME format in struct chunk out.
4603 * Returns 1 if serial is found and copied, 0 if no valid time found
4604 * and -1 if output is not large enough.
4605 */
4606static int
4607ssl_sock_get_time(ASN1_TIME *tm, struct chunk *out)
4608{
4609 if (tm->type == V_ASN1_GENERALIZEDTIME) {
4610 ASN1_GENERALIZEDTIME *gentm = (ASN1_GENERALIZEDTIME *)tm;
4611
4612 if (gentm->length < 12)
4613 return 0;
4614 if (gentm->data[0] != 0x32 || gentm->data[1] != 0x30)
4615 return 0;
4616 if (out->size < gentm->length-2)
4617 return -1;
4618
4619 memcpy(out->str, gentm->data+2, gentm->length-2);
4620 out->len = gentm->length-2;
4621 return 1;
4622 }
4623 else if (tm->type == V_ASN1_UTCTIME) {
4624 ASN1_UTCTIME *utctm = (ASN1_UTCTIME *)tm;
4625
4626 if (utctm->length < 10)
4627 return 0;
4628 if (utctm->data[0] >= 0x35)
4629 return 0;
4630 if (out->size < utctm->length)
4631 return -1;
4632
4633 memcpy(out->str, utctm->data, utctm->length);
4634 out->len = utctm->length;
4635 return 1;
4636 }
4637
4638 return 0;
4639}
4640
Emeric Brun87855892012-10-17 17:39:35 +02004641/* Extract an entry from a X509_NAME and copy its value to an output chunk.
4642 * Returns 1 if entry found, 0 if entry not found, or -1 if output not large enough.
4643 */
4644static int
4645ssl_sock_get_dn_entry(X509_NAME *a, const struct chunk *entry, int pos, struct chunk *out)
4646{
4647 X509_NAME_ENTRY *ne;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004648 ASN1_OBJECT *obj;
4649 ASN1_STRING *data;
4650 const unsigned char *data_ptr;
4651 int data_len;
Emeric Brun87855892012-10-17 17:39:35 +02004652 int i, j, n;
4653 int cur = 0;
4654 const char *s;
4655 char tmp[128];
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004656 int name_count;
4657
4658 name_count = X509_NAME_entry_count(a);
Emeric Brun87855892012-10-17 17:39:35 +02004659
4660 out->len = 0;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004661 for (i = 0; i < name_count; i++) {
Emeric Brun87855892012-10-17 17:39:35 +02004662 if (pos < 0)
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004663 j = (name_count-1) - i;
Emeric Brun87855892012-10-17 17:39:35 +02004664 else
4665 j = i;
4666
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004667 ne = X509_NAME_get_entry(a, j);
4668 obj = X509_NAME_ENTRY_get_object(ne);
4669 data = X509_NAME_ENTRY_get_data(ne);
4670 data_ptr = ASN1_STRING_get0_data(data);
4671 data_len = ASN1_STRING_length(data);
4672 n = OBJ_obj2nid(obj);
Emeric Brun87855892012-10-17 17:39:35 +02004673 if ((n == NID_undef) || ((s = OBJ_nid2sn(n)) == NULL)) {
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004674 i2t_ASN1_OBJECT(tmp, sizeof(tmp), obj);
Emeric Brun87855892012-10-17 17:39:35 +02004675 s = tmp;
4676 }
4677
4678 if (chunk_strcasecmp(entry, s) != 0)
4679 continue;
4680
4681 if (pos < 0)
4682 cur--;
4683 else
4684 cur++;
4685
4686 if (cur != pos)
4687 continue;
4688
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004689 if (data_len > out->size)
Emeric Brun87855892012-10-17 17:39:35 +02004690 return -1;
4691
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004692 memcpy(out->str, data_ptr, data_len);
4693 out->len = data_len;
Emeric Brun87855892012-10-17 17:39:35 +02004694 return 1;
4695 }
4696
4697 return 0;
4698
4699}
4700
4701/* Extract and format full DN from a X509_NAME and copy result into a chunk
4702 * Returns 1 if dn entries exits, 0 if no dn entry found or -1 if output is not large enough.
4703 */
4704static int
4705ssl_sock_get_dn_oneline(X509_NAME *a, struct chunk *out)
4706{
4707 X509_NAME_ENTRY *ne;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004708 ASN1_OBJECT *obj;
4709 ASN1_STRING *data;
4710 const unsigned char *data_ptr;
4711 int data_len;
Emeric Brun87855892012-10-17 17:39:35 +02004712 int i, n, ln;
4713 int l = 0;
4714 const char *s;
4715 char *p;
4716 char tmp[128];
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004717 int name_count;
4718
4719
4720 name_count = X509_NAME_entry_count(a);
Emeric Brun87855892012-10-17 17:39:35 +02004721
4722 out->len = 0;
4723 p = out->str;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004724 for (i = 0; i < name_count; i++) {
4725 ne = X509_NAME_get_entry(a, i);
4726 obj = X509_NAME_ENTRY_get_object(ne);
4727 data = X509_NAME_ENTRY_get_data(ne);
4728 data_ptr = ASN1_STRING_get0_data(data);
4729 data_len = ASN1_STRING_length(data);
4730 n = OBJ_obj2nid(obj);
Emeric Brun87855892012-10-17 17:39:35 +02004731 if ((n == NID_undef) || ((s = OBJ_nid2sn(n)) == NULL)) {
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004732 i2t_ASN1_OBJECT(tmp, sizeof(tmp), obj);
Emeric Brun87855892012-10-17 17:39:35 +02004733 s = tmp;
4734 }
4735 ln = strlen(s);
4736
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004737 l += 1 + ln + 1 + data_len;
Emeric Brun87855892012-10-17 17:39:35 +02004738 if (l > out->size)
4739 return -1;
4740 out->len = l;
4741
4742 *(p++)='/';
4743 memcpy(p, s, ln);
4744 p += ln;
4745 *(p++)='=';
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004746 memcpy(p, data_ptr, data_len);
4747 p += data_len;
Emeric Brun87855892012-10-17 17:39:35 +02004748 }
4749
4750 if (!out->len)
4751 return 0;
4752
4753 return 1;
4754}
4755
David Safb76832014-05-08 23:42:08 -04004756char *ssl_sock_get_version(struct connection *conn)
4757{
4758 if (!ssl_sock_is_ssl(conn))
4759 return NULL;
4760
4761 return (char *)SSL_get_version(conn->xprt_ctx);
4762}
4763
Willy Tarreau119a4082016-12-22 21:58:38 +01004764/* Sets advertised SNI for outgoing connections. Please set <hostname> to NULL
4765 * to disable SNI.
4766 */
Willy Tarreau63076412015-07-10 11:33:32 +02004767void ssl_sock_set_servername(struct connection *conn, const char *hostname)
4768{
4769#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Willy Tarreau119a4082016-12-22 21:58:38 +01004770 char *prev_name;
4771
Willy Tarreau63076412015-07-10 11:33:32 +02004772 if (!ssl_sock_is_ssl(conn))
4773 return;
4774
Willy Tarreau119a4082016-12-22 21:58:38 +01004775 /* if the SNI changes, we must destroy the reusable context so that a
4776 * new connection will present a new SNI. As an optimization we could
4777 * later imagine having a small cache of ssl_ctx to hold a few SNI per
4778 * server.
4779 */
4780 prev_name = (char *)SSL_get_servername(conn->xprt_ctx, TLSEXT_NAMETYPE_host_name);
4781 if ((!prev_name && hostname) ||
4782 (prev_name && (!hostname || strcmp(hostname, prev_name) != 0)))
4783 SSL_set_session(conn->xprt_ctx, NULL);
4784
Willy Tarreau63076412015-07-10 11:33:32 +02004785 SSL_set_tlsext_host_name(conn->xprt_ctx, hostname);
4786#endif
4787}
4788
Emeric Brun0abf8362014-06-24 18:26:41 +02004789/* Extract peer certificate's common name into the chunk dest
4790 * Returns
4791 * the len of the extracted common name
4792 * or 0 if no CN found in DN
4793 * or -1 on error case (i.e. no peer certificate)
4794 */
4795int ssl_sock_get_remote_common_name(struct connection *conn, struct chunk *dest)
David Safb76832014-05-08 23:42:08 -04004796{
4797 X509 *crt = NULL;
4798 X509_NAME *name;
David Safb76832014-05-08 23:42:08 -04004799 const char find_cn[] = "CN";
4800 const struct chunk find_cn_chunk = {
4801 .str = (char *)&find_cn,
4802 .len = sizeof(find_cn)-1
4803 };
Emeric Brun0abf8362014-06-24 18:26:41 +02004804 int result = -1;
David Safb76832014-05-08 23:42:08 -04004805
4806 if (!ssl_sock_is_ssl(conn))
Emeric Brun0abf8362014-06-24 18:26:41 +02004807 goto out;
David Safb76832014-05-08 23:42:08 -04004808
4809 /* SSL_get_peer_certificate, it increase X509 * ref count */
4810 crt = SSL_get_peer_certificate(conn->xprt_ctx);
4811 if (!crt)
4812 goto out;
4813
4814 name = X509_get_subject_name(crt);
4815 if (!name)
4816 goto out;
David Safb76832014-05-08 23:42:08 -04004817
Emeric Brun0abf8362014-06-24 18:26:41 +02004818 result = ssl_sock_get_dn_entry(name, &find_cn_chunk, 1, dest);
4819out:
David Safb76832014-05-08 23:42:08 -04004820 if (crt)
4821 X509_free(crt);
4822
4823 return result;
4824}
4825
Dave McCowan328fb582014-07-30 10:39:13 -04004826/* returns 1 if client passed a certificate for this session, 0 if not */
4827int ssl_sock_get_cert_used_sess(struct connection *conn)
4828{
4829 X509 *crt = NULL;
4830
4831 if (!ssl_sock_is_ssl(conn))
4832 return 0;
4833
4834 /* SSL_get_peer_certificate, it increase X509 * ref count */
4835 crt = SSL_get_peer_certificate(conn->xprt_ctx);
4836 if (!crt)
4837 return 0;
4838
4839 X509_free(crt);
4840 return 1;
4841}
4842
4843/* returns 1 if client passed a certificate for this connection, 0 if not */
4844int ssl_sock_get_cert_used_conn(struct connection *conn)
David Safb76832014-05-08 23:42:08 -04004845{
4846 if (!ssl_sock_is_ssl(conn))
4847 return 0;
4848
4849 return SSL_SOCK_ST_FL_VERIFY_DONE & conn->xprt_st ? 1 : 0;
4850}
4851
4852/* returns result from SSL verify */
4853unsigned int ssl_sock_get_verify_result(struct connection *conn)
4854{
4855 if (!ssl_sock_is_ssl(conn))
4856 return (unsigned int)X509_V_ERR_APPLICATION_VERIFICATION;
4857
4858 return (unsigned int)SSL_get_verify_result(conn->xprt_ctx);
4859}
4860
Willy Tarreau7875d092012-09-10 08:20:03 +02004861/***** Below are some sample fetching functions for ACL/patterns *****/
4862
Emeric Brune64aef12012-09-21 13:15:06 +02004863/* boolean, returns true if client cert was present */
4864static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004865smp_fetch_ssl_fc_has_crt(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brune64aef12012-09-21 13:15:06 +02004866{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004867 struct connection *conn;
4868
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004869 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004870 if (!conn || conn->xprt != &ssl_sock)
Emeric Brune64aef12012-09-21 13:15:06 +02004871 return 0;
4872
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004873 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brune64aef12012-09-21 13:15:06 +02004874 smp->flags |= SMP_F_MAY_CHANGE;
4875 return 0;
4876 }
4877
4878 smp->flags = 0;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004879 smp->data.type = SMP_T_BOOL;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004880 smp->data.u.sint = SSL_SOCK_ST_FL_VERIFY_DONE & conn->xprt_st ? 1 : 0;
Emeric Brune64aef12012-09-21 13:15:06 +02004881
4882 return 1;
4883}
4884
Emeric Brun43e79582014-10-29 19:03:26 +01004885/* binary, returns a certificate in a binary chunk (der/raw).
4886 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
4887 * should be use.
4888 */
4889static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004890smp_fetch_ssl_x_der(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun43e79582014-10-29 19:03:26 +01004891{
4892 int cert_peer = (kw[4] == 'c') ? 1 : 0;
4893 X509 *crt = NULL;
4894 int ret = 0;
4895 struct chunk *smp_trash;
4896 struct connection *conn;
4897
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004898 conn = objt_conn(smp->sess->origin);
Emeric Brun43e79582014-10-29 19:03:26 +01004899 if (!conn || conn->xprt != &ssl_sock)
4900 return 0;
4901
4902 if (!(conn->flags & CO_FL_CONNECTED)) {
4903 smp->flags |= SMP_F_MAY_CHANGE;
4904 return 0;
4905 }
4906
4907 if (cert_peer)
4908 crt = SSL_get_peer_certificate(conn->xprt_ctx);
4909 else
4910 crt = SSL_get_certificate(conn->xprt_ctx);
4911
4912 if (!crt)
4913 goto out;
4914
4915 smp_trash = get_trash_chunk();
4916 if (ssl_sock_crt2der(crt, smp_trash) <= 0)
4917 goto out;
4918
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004919 smp->data.u.str = *smp_trash;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004920 smp->data.type = SMP_T_BIN;
Emeric Brun43e79582014-10-29 19:03:26 +01004921 ret = 1;
4922out:
4923 /* SSL_get_peer_certificate, it increase X509 * ref count */
4924 if (cert_peer && crt)
4925 X509_free(crt);
4926 return ret;
4927}
4928
Emeric Brunba841a12014-04-30 17:05:08 +02004929/* binary, returns serial of certificate in a binary chunk.
4930 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
4931 * should be use.
4932 */
Willy Tarreau8d598402012-10-22 17:58:39 +02004933static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004934smp_fetch_ssl_x_serial(const struct arg *args, struct sample *smp, const char *kw, void *private)
Willy Tarreau8d598402012-10-22 17:58:39 +02004935{
Emeric Brunba841a12014-04-30 17:05:08 +02004936 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Willy Tarreau8d598402012-10-22 17:58:39 +02004937 X509 *crt = NULL;
4938 int ret = 0;
4939 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004940 struct connection *conn;
4941
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004942 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004943 if (!conn || conn->xprt != &ssl_sock)
Willy Tarreau8d598402012-10-22 17:58:39 +02004944 return 0;
4945
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004946 if (!(conn->flags & CO_FL_CONNECTED)) {
Willy Tarreau8d598402012-10-22 17:58:39 +02004947 smp->flags |= SMP_F_MAY_CHANGE;
4948 return 0;
4949 }
4950
Emeric Brunba841a12014-04-30 17:05:08 +02004951 if (cert_peer)
4952 crt = SSL_get_peer_certificate(conn->xprt_ctx);
4953 else
4954 crt = SSL_get_certificate(conn->xprt_ctx);
4955
Willy Tarreau8d598402012-10-22 17:58:39 +02004956 if (!crt)
4957 goto out;
4958
Willy Tarreau47ca5452012-12-23 20:22:19 +01004959 smp_trash = get_trash_chunk();
Willy Tarreau8d598402012-10-22 17:58:39 +02004960 if (ssl_sock_get_serial(crt, smp_trash) <= 0)
4961 goto out;
4962
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004963 smp->data.u.str = *smp_trash;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004964 smp->data.type = SMP_T_BIN;
Willy Tarreau8d598402012-10-22 17:58:39 +02004965 ret = 1;
4966out:
Emeric Brunba841a12014-04-30 17:05:08 +02004967 /* SSL_get_peer_certificate, it increase X509 * ref count */
4968 if (cert_peer && crt)
Willy Tarreau8d598402012-10-22 17:58:39 +02004969 X509_free(crt);
4970 return ret;
4971}
Emeric Brune64aef12012-09-21 13:15:06 +02004972
Emeric Brunba841a12014-04-30 17:05:08 +02004973/* binary, returns the client certificate's SHA-1 fingerprint (SHA-1 hash of DER-encoded certificate) in a binary chunk.
4974 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
4975 * should be use.
4976 */
James Votha051b4a2013-05-14 20:37:59 +02004977static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004978smp_fetch_ssl_x_sha1(const struct arg *args, struct sample *smp, const char *kw, void *private)
James Votha051b4a2013-05-14 20:37:59 +02004979{
Emeric Brunba841a12014-04-30 17:05:08 +02004980 int cert_peer = (kw[4] == 'c') ? 1 : 0;
James Votha051b4a2013-05-14 20:37:59 +02004981 X509 *crt = NULL;
4982 const EVP_MD *digest;
4983 int ret = 0;
4984 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004985 struct connection *conn;
James Votha051b4a2013-05-14 20:37:59 +02004986
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004987 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004988 if (!conn || conn->xprt != &ssl_sock)
4989 return 0;
4990
4991 if (!(conn->flags & CO_FL_CONNECTED)) {
James Votha051b4a2013-05-14 20:37:59 +02004992 smp->flags |= SMP_F_MAY_CHANGE;
4993 return 0;
4994 }
4995
Emeric Brunba841a12014-04-30 17:05:08 +02004996 if (cert_peer)
4997 crt = SSL_get_peer_certificate(conn->xprt_ctx);
4998 else
4999 crt = SSL_get_certificate(conn->xprt_ctx);
James Votha051b4a2013-05-14 20:37:59 +02005000 if (!crt)
5001 goto out;
5002
5003 smp_trash = get_trash_chunk();
5004 digest = EVP_sha1();
5005 X509_digest(crt, digest, (unsigned char *)smp_trash->str, (unsigned int *)&smp_trash->len);
5006
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005007 smp->data.u.str = *smp_trash;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005008 smp->data.type = SMP_T_BIN;
James Votha051b4a2013-05-14 20:37:59 +02005009 ret = 1;
5010out:
Emeric Brunba841a12014-04-30 17:05:08 +02005011 /* SSL_get_peer_certificate, it increase X509 * ref count */
5012 if (cert_peer && crt)
James Votha051b4a2013-05-14 20:37:59 +02005013 X509_free(crt);
5014 return ret;
5015}
5016
Emeric Brunba841a12014-04-30 17:05:08 +02005017/* string, returns certificate's notafter date in ASN1_UTCTIME format.
5018 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
5019 * should be use.
5020 */
Emeric Brunce5ad802012-10-22 14:11:22 +02005021static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005022smp_fetch_ssl_x_notafter(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brunce5ad802012-10-22 14:11:22 +02005023{
Emeric Brunba841a12014-04-30 17:05:08 +02005024 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brunce5ad802012-10-22 14:11:22 +02005025 X509 *crt = NULL;
5026 int ret = 0;
5027 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005028 struct connection *conn;
Emeric Brunce5ad802012-10-22 14:11:22 +02005029
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02005030 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005031 if (!conn || conn->xprt != &ssl_sock)
5032 return 0;
5033
5034 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunce5ad802012-10-22 14:11:22 +02005035 smp->flags |= SMP_F_MAY_CHANGE;
5036 return 0;
5037 }
5038
Emeric Brunba841a12014-04-30 17:05:08 +02005039 if (cert_peer)
5040 crt = SSL_get_peer_certificate(conn->xprt_ctx);
5041 else
5042 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brunce5ad802012-10-22 14:11:22 +02005043 if (!crt)
5044 goto out;
5045
Willy Tarreau47ca5452012-12-23 20:22:19 +01005046 smp_trash = get_trash_chunk();
Emeric Brunce5ad802012-10-22 14:11:22 +02005047 if (ssl_sock_get_time(X509_get_notAfter(crt), smp_trash) <= 0)
5048 goto out;
5049
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005050 smp->data.u.str = *smp_trash;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005051 smp->data.type = SMP_T_STR;
Emeric Brunce5ad802012-10-22 14:11:22 +02005052 ret = 1;
5053out:
Emeric Brunba841a12014-04-30 17:05:08 +02005054 /* SSL_get_peer_certificate, it increase X509 * ref count */
5055 if (cert_peer && crt)
Emeric Brunce5ad802012-10-22 14:11:22 +02005056 X509_free(crt);
5057 return ret;
5058}
5059
Emeric Brunba841a12014-04-30 17:05:08 +02005060/* string, returns a string of a formatted full dn \C=..\O=..\OU=.. \CN=.. of certificate's issuer
5061 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
5062 * should be use.
5063 */
Emeric Brun87855892012-10-17 17:39:35 +02005064static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005065smp_fetch_ssl_x_i_dn(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun87855892012-10-17 17:39:35 +02005066{
Emeric Brunba841a12014-04-30 17:05:08 +02005067 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brun87855892012-10-17 17:39:35 +02005068 X509 *crt = NULL;
5069 X509_NAME *name;
5070 int ret = 0;
5071 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005072 struct connection *conn;
Emeric Brun87855892012-10-17 17:39:35 +02005073
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02005074 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005075 if (!conn || conn->xprt != &ssl_sock)
5076 return 0;
5077
5078 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun87855892012-10-17 17:39:35 +02005079 smp->flags |= SMP_F_MAY_CHANGE;
5080 return 0;
5081 }
5082
Emeric Brunba841a12014-04-30 17:05:08 +02005083 if (cert_peer)
5084 crt = SSL_get_peer_certificate(conn->xprt_ctx);
5085 else
5086 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brun87855892012-10-17 17:39:35 +02005087 if (!crt)
5088 goto out;
5089
5090 name = X509_get_issuer_name(crt);
5091 if (!name)
5092 goto out;
5093
Willy Tarreau47ca5452012-12-23 20:22:19 +01005094 smp_trash = get_trash_chunk();
Emeric Brun87855892012-10-17 17:39:35 +02005095 if (args && args[0].type == ARGT_STR) {
5096 int pos = 1;
5097
5098 if (args[1].type == ARGT_SINT)
5099 pos = args[1].data.sint;
Emeric Brun87855892012-10-17 17:39:35 +02005100
5101 if (ssl_sock_get_dn_entry(name, &args[0].data.str, pos, smp_trash) <= 0)
5102 goto out;
5103 }
5104 else if (ssl_sock_get_dn_oneline(name, smp_trash) <= 0)
5105 goto out;
5106
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005107 smp->data.type = SMP_T_STR;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005108 smp->data.u.str = *smp_trash;
Emeric Brun87855892012-10-17 17:39:35 +02005109 ret = 1;
5110out:
Emeric Brunba841a12014-04-30 17:05:08 +02005111 /* SSL_get_peer_certificate, it increase X509 * ref count */
5112 if (cert_peer && crt)
Emeric Brun87855892012-10-17 17:39:35 +02005113 X509_free(crt);
5114 return ret;
5115}
5116
Emeric Brunba841a12014-04-30 17:05:08 +02005117/* string, returns notbefore date in ASN1_UTCTIME format.
5118 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
5119 * should be use.
5120 */
Emeric Brunce5ad802012-10-22 14:11:22 +02005121static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005122smp_fetch_ssl_x_notbefore(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brunce5ad802012-10-22 14:11:22 +02005123{
Emeric Brunba841a12014-04-30 17:05:08 +02005124 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brunce5ad802012-10-22 14:11:22 +02005125 X509 *crt = NULL;
5126 int ret = 0;
5127 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005128 struct connection *conn;
5129
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02005130 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005131 if (!conn || conn->xprt != &ssl_sock)
Emeric Brunce5ad802012-10-22 14:11:22 +02005132 return 0;
5133
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005134 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunce5ad802012-10-22 14:11:22 +02005135 smp->flags |= SMP_F_MAY_CHANGE;
5136 return 0;
5137 }
5138
Emeric Brunba841a12014-04-30 17:05:08 +02005139 if (cert_peer)
5140 crt = SSL_get_peer_certificate(conn->xprt_ctx);
5141 else
5142 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brunce5ad802012-10-22 14:11:22 +02005143 if (!crt)
5144 goto out;
5145
Willy Tarreau47ca5452012-12-23 20:22:19 +01005146 smp_trash = get_trash_chunk();
Emeric Brunce5ad802012-10-22 14:11:22 +02005147 if (ssl_sock_get_time(X509_get_notBefore(crt), smp_trash) <= 0)
5148 goto out;
5149
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005150 smp->data.u.str = *smp_trash;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005151 smp->data.type = SMP_T_STR;
Emeric Brunce5ad802012-10-22 14:11:22 +02005152 ret = 1;
5153out:
Emeric Brunba841a12014-04-30 17:05:08 +02005154 /* SSL_get_peer_certificate, it increase X509 * ref count */
5155 if (cert_peer && crt)
Emeric Brunce5ad802012-10-22 14:11:22 +02005156 X509_free(crt);
5157 return ret;
5158}
5159
Emeric Brunba841a12014-04-30 17:05:08 +02005160/* string, returns a string of a formatted full dn \C=..\O=..\OU=.. \CN=.. of certificate's subject
5161 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
5162 * should be use.
5163 */
Emeric Brun87855892012-10-17 17:39:35 +02005164static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005165smp_fetch_ssl_x_s_dn(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun87855892012-10-17 17:39:35 +02005166{
Emeric Brunba841a12014-04-30 17:05:08 +02005167 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brun87855892012-10-17 17:39:35 +02005168 X509 *crt = NULL;
5169 X509_NAME *name;
5170 int ret = 0;
5171 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005172 struct connection *conn;
Emeric Brun87855892012-10-17 17:39:35 +02005173
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02005174 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005175 if (!conn || conn->xprt != &ssl_sock)
5176 return 0;
5177
5178 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun87855892012-10-17 17:39:35 +02005179 smp->flags |= SMP_F_MAY_CHANGE;
5180 return 0;
5181 }
5182
Emeric Brunba841a12014-04-30 17:05:08 +02005183 if (cert_peer)
5184 crt = SSL_get_peer_certificate(conn->xprt_ctx);
5185 else
5186 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brun87855892012-10-17 17:39:35 +02005187 if (!crt)
5188 goto out;
5189
5190 name = X509_get_subject_name(crt);
5191 if (!name)
5192 goto out;
5193
Willy Tarreau47ca5452012-12-23 20:22:19 +01005194 smp_trash = get_trash_chunk();
Emeric Brun87855892012-10-17 17:39:35 +02005195 if (args && args[0].type == ARGT_STR) {
5196 int pos = 1;
5197
5198 if (args[1].type == ARGT_SINT)
5199 pos = args[1].data.sint;
Emeric Brun87855892012-10-17 17:39:35 +02005200
5201 if (ssl_sock_get_dn_entry(name, &args[0].data.str, pos, smp_trash) <= 0)
5202 goto out;
5203 }
5204 else if (ssl_sock_get_dn_oneline(name, smp_trash) <= 0)
5205 goto out;
5206
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005207 smp->data.type = SMP_T_STR;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005208 smp->data.u.str = *smp_trash;
Emeric Brun87855892012-10-17 17:39:35 +02005209 ret = 1;
5210out:
Emeric Brunba841a12014-04-30 17:05:08 +02005211 /* SSL_get_peer_certificate, it increase X509 * ref count */
5212 if (cert_peer && crt)
Emeric Brun87855892012-10-17 17:39:35 +02005213 X509_free(crt);
5214 return ret;
5215}
Emeric Brun9143d372012-12-20 15:44:16 +01005216
5217/* integer, returns true if current session use a client certificate */
5218static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005219smp_fetch_ssl_c_used(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun9143d372012-12-20 15:44:16 +01005220{
5221 X509 *crt;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005222 struct connection *conn;
Emeric Brun9143d372012-12-20 15:44:16 +01005223
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02005224 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005225 if (!conn || conn->xprt != &ssl_sock)
5226 return 0;
5227
5228 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun9143d372012-12-20 15:44:16 +01005229 smp->flags |= SMP_F_MAY_CHANGE;
5230 return 0;
5231 }
5232
5233 /* SSL_get_peer_certificate returns a ptr on allocated X509 struct */
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005234 crt = SSL_get_peer_certificate(conn->xprt_ctx);
Emeric Brun9143d372012-12-20 15:44:16 +01005235 if (crt) {
5236 X509_free(crt);
5237 }
5238
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005239 smp->data.type = SMP_T_BOOL;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005240 smp->data.u.sint = (crt != NULL);
Emeric Brun9143d372012-12-20 15:44:16 +01005241 return 1;
5242}
5243
Emeric Brunba841a12014-04-30 17:05:08 +02005244/* integer, returns the certificate version
5245 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
5246 * should be use.
5247 */
Emeric Bruna7359fd2012-10-17 15:03:11 +02005248static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005249smp_fetch_ssl_x_version(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Bruna7359fd2012-10-17 15:03:11 +02005250{
Emeric Brunba841a12014-04-30 17:05:08 +02005251 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Bruna7359fd2012-10-17 15:03:11 +02005252 X509 *crt;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005253 struct connection *conn;
5254
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02005255 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005256 if (!conn || conn->xprt != &ssl_sock)
Emeric Bruna7359fd2012-10-17 15:03:11 +02005257 return 0;
5258
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005259 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Bruna7359fd2012-10-17 15:03:11 +02005260 smp->flags |= SMP_F_MAY_CHANGE;
5261 return 0;
5262 }
5263
Emeric Brunba841a12014-04-30 17:05:08 +02005264 if (cert_peer)
5265 crt = SSL_get_peer_certificate(conn->xprt_ctx);
5266 else
5267 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Bruna7359fd2012-10-17 15:03:11 +02005268 if (!crt)
5269 return 0;
5270
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005271 smp->data.u.sint = (unsigned int)(1 + X509_get_version(crt));
Emeric Brunba841a12014-04-30 17:05:08 +02005272 /* SSL_get_peer_certificate increase X509 * ref count */
5273 if (cert_peer)
5274 X509_free(crt);
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005275 smp->data.type = SMP_T_SINT;
Emeric Bruna7359fd2012-10-17 15:03:11 +02005276
5277 return 1;
5278}
5279
Emeric Brunba841a12014-04-30 17:05:08 +02005280/* string, returns the certificate's signature algorithm.
5281 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
5282 * should be use.
5283 */
Emeric Brun7f56e742012-10-19 18:15:40 +02005284static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005285smp_fetch_ssl_x_sig_alg(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun7f56e742012-10-19 18:15:40 +02005286{
Emeric Brunba841a12014-04-30 17:05:08 +02005287 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brun7f56e742012-10-19 18:15:40 +02005288 X509 *crt;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02005289 __OPENSSL_110_CONST__ ASN1_OBJECT *algorithm;
Emeric Brun7f56e742012-10-19 18:15:40 +02005290 int nid;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005291 struct connection *conn;
Emeric Brun7f56e742012-10-19 18:15:40 +02005292
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02005293 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005294 if (!conn || conn->xprt != &ssl_sock)
5295 return 0;
5296
5297 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun7f56e742012-10-19 18:15:40 +02005298 smp->flags |= SMP_F_MAY_CHANGE;
5299 return 0;
5300 }
5301
Emeric Brunba841a12014-04-30 17:05:08 +02005302 if (cert_peer)
5303 crt = SSL_get_peer_certificate(conn->xprt_ctx);
5304 else
5305 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brun7f56e742012-10-19 18:15:40 +02005306 if (!crt)
5307 return 0;
5308
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02005309 X509_ALGOR_get0(&algorithm, NULL, NULL, X509_get0_tbs_sigalg(crt));
5310 nid = OBJ_obj2nid(algorithm);
Emeric Brun7f56e742012-10-19 18:15:40 +02005311
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005312 smp->data.u.str.str = (char *)OBJ_nid2sn(nid);
5313 if (!smp->data.u.str.str) {
Emeric Brunba841a12014-04-30 17:05:08 +02005314 /* SSL_get_peer_certificate increase X509 * ref count */
5315 if (cert_peer)
5316 X509_free(crt);
Emeric Brun7f56e742012-10-19 18:15:40 +02005317 return 0;
Emeric Brun9bf3ba22013-10-07 14:31:44 +02005318 }
Emeric Brun7f56e742012-10-19 18:15:40 +02005319
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005320 smp->data.type = SMP_T_STR;
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01005321 smp->flags |= SMP_F_CONST;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005322 smp->data.u.str.len = strlen(smp->data.u.str.str);
Emeric Brunba841a12014-04-30 17:05:08 +02005323 /* SSL_get_peer_certificate increase X509 * ref count */
5324 if (cert_peer)
5325 X509_free(crt);
Emeric Brun7f56e742012-10-19 18:15:40 +02005326
5327 return 1;
5328}
5329
Emeric Brunba841a12014-04-30 17:05:08 +02005330/* string, returns the certificate's key algorithm.
5331 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
5332 * should be use.
5333 */
Emeric Brun521a0112012-10-22 12:22:55 +02005334static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005335smp_fetch_ssl_x_key_alg(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun521a0112012-10-22 12:22:55 +02005336{
Emeric Brunba841a12014-04-30 17:05:08 +02005337 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brun521a0112012-10-22 12:22:55 +02005338 X509 *crt;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02005339 ASN1_OBJECT *algorithm;
Emeric Brun521a0112012-10-22 12:22:55 +02005340 int nid;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005341 struct connection *conn;
Emeric Brun521a0112012-10-22 12:22:55 +02005342
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02005343 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005344 if (!conn || conn->xprt != &ssl_sock)
5345 return 0;
5346
5347 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun521a0112012-10-22 12:22:55 +02005348 smp->flags |= SMP_F_MAY_CHANGE;
5349 return 0;
5350 }
5351
Emeric Brunba841a12014-04-30 17:05:08 +02005352 if (cert_peer)
5353 crt = SSL_get_peer_certificate(conn->xprt_ctx);
5354 else
5355 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brun521a0112012-10-22 12:22:55 +02005356 if (!crt)
5357 return 0;
5358
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02005359 X509_PUBKEY_get0_param(&algorithm, NULL, NULL, NULL, X509_get_X509_PUBKEY(crt));
5360 nid = OBJ_obj2nid(algorithm);
Emeric Brun521a0112012-10-22 12:22:55 +02005361
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005362 smp->data.u.str.str = (char *)OBJ_nid2sn(nid);
5363 if (!smp->data.u.str.str) {
Emeric Brunba841a12014-04-30 17:05:08 +02005364 /* SSL_get_peer_certificate increase X509 * ref count */
5365 if (cert_peer)
5366 X509_free(crt);
Emeric Brun521a0112012-10-22 12:22:55 +02005367 return 0;
Emeric Brun9bf3ba22013-10-07 14:31:44 +02005368 }
Emeric Brun521a0112012-10-22 12:22:55 +02005369
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005370 smp->data.type = SMP_T_STR;
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01005371 smp->flags |= SMP_F_CONST;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005372 smp->data.u.str.len = strlen(smp->data.u.str.str);
Emeric Brunba841a12014-04-30 17:05:08 +02005373 if (cert_peer)
5374 X509_free(crt);
Emeric Brun521a0112012-10-22 12:22:55 +02005375
5376 return 1;
5377}
5378
Emeric Brun645ae792014-04-30 14:21:06 +02005379/* boolean, returns true if front conn. transport layer is SSL.
5380 * This function is also usable on backend conn if the fetch keyword 5th
5381 * char is 'b'.
5382 */
Willy Tarreau7875d092012-09-10 08:20:03 +02005383static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005384smp_fetch_ssl_fc(const struct arg *args, struct sample *smp, const char *kw, void *private)
Willy Tarreau7875d092012-09-10 08:20:03 +02005385{
Willy Tarreaue237fe12016-03-10 17:05:28 +01005386 struct connection *conn = objt_conn((kw[4] != 'b') ? smp->sess->origin :
5387 smp->strm ? smp->strm->si[1].end : NULL);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005388
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005389 smp->data.type = SMP_T_BOOL;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005390 smp->data.u.sint = (conn && conn->xprt == &ssl_sock);
Willy Tarreau7875d092012-09-10 08:20:03 +02005391 return 1;
5392}
5393
Emeric Brun2525b6b2012-10-18 15:59:43 +02005394/* boolean, returns true if client present a SNI */
Willy Tarreau7875d092012-09-10 08:20:03 +02005395static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005396smp_fetch_ssl_fc_has_sni(const struct arg *args, struct sample *smp, const char *kw, void *private)
Willy Tarreau7875d092012-09-10 08:20:03 +02005397{
5398#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02005399 struct connection *conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005400
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005401 smp->data.type = SMP_T_BOOL;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005402 smp->data.u.sint = (conn && conn->xprt == &ssl_sock) &&
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005403 conn->xprt_ctx &&
5404 SSL_get_servername(conn->xprt_ctx, TLSEXT_NAMETYPE_host_name) != NULL;
Willy Tarreau7875d092012-09-10 08:20:03 +02005405 return 1;
5406#else
5407 return 0;
5408#endif
5409}
5410
Nenad Merdanovic26ea8222015-05-18 02:28:57 +02005411/* boolean, returns true if client session has been resumed */
5412static int
5413smp_fetch_ssl_fc_is_resumed(const struct arg *args, struct sample *smp, const char *kw, void *private)
5414{
5415 struct connection *conn = objt_conn(smp->sess->origin);
5416
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005417 smp->data.type = SMP_T_BOOL;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005418 smp->data.u.sint = (conn && conn->xprt == &ssl_sock) &&
Nenad Merdanovic26ea8222015-05-18 02:28:57 +02005419 conn->xprt_ctx &&
5420 SSL_session_reused(conn->xprt_ctx);
5421 return 1;
5422}
5423
Emeric Brun645ae792014-04-30 14:21:06 +02005424/* string, returns the used cipher if front conn. transport layer is SSL.
5425 * This function is also usable on backend conn if the fetch keyword 5th
5426 * char is 'b'.
5427 */
Emeric Brun589fcad2012-10-16 14:13:26 +02005428static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005429smp_fetch_ssl_fc_cipher(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun589fcad2012-10-16 14:13:26 +02005430{
Willy Tarreaue237fe12016-03-10 17:05:28 +01005431 struct connection *conn = objt_conn((kw[4] != 'b') ? smp->sess->origin :
5432 smp->strm ? smp->strm->si[1].end : NULL);
Emeric Brun589fcad2012-10-16 14:13:26 +02005433
Willy Tarreaube508f12016-03-10 11:47:01 +01005434 smp->flags = 0;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005435 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
Emeric Brun589fcad2012-10-16 14:13:26 +02005436 return 0;
5437
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005438 smp->data.u.str.str = (char *)SSL_get_cipher_name(conn->xprt_ctx);
5439 if (!smp->data.u.str.str)
Emeric Brun589fcad2012-10-16 14:13:26 +02005440 return 0;
5441
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005442 smp->data.type = SMP_T_STR;
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01005443 smp->flags |= SMP_F_CONST;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005444 smp->data.u.str.len = strlen(smp->data.u.str.str);
Emeric Brun589fcad2012-10-16 14:13:26 +02005445
5446 return 1;
5447}
5448
Emeric Brun645ae792014-04-30 14:21:06 +02005449/* integer, returns the algoritm's keysize if front conn. transport layer
5450 * is SSL.
5451 * This function is also usable on backend conn if the fetch keyword 5th
5452 * char is 'b'.
5453 */
Emeric Brun589fcad2012-10-16 14:13:26 +02005454static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005455smp_fetch_ssl_fc_alg_keysize(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun589fcad2012-10-16 14:13:26 +02005456{
Willy Tarreaue237fe12016-03-10 17:05:28 +01005457 struct connection *conn = objt_conn((kw[4] != 'b') ? smp->sess->origin :
5458 smp->strm ? smp->strm->si[1].end : NULL);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005459
Willy Tarreaue237fe12016-03-10 17:05:28 +01005460 int sint;
Willy Tarreaube508f12016-03-10 11:47:01 +01005461
Emeric Brun589fcad2012-10-16 14:13:26 +02005462 smp->flags = 0;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005463 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
Emeric Brun589fcad2012-10-16 14:13:26 +02005464 return 0;
5465
Thierry FOURNIER07ee64e2015-07-06 23:43:03 +02005466 if (!SSL_get_cipher_bits(conn->xprt_ctx, &sint))
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005467 return 0;
5468
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005469 smp->data.u.sint = sint;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005470 smp->data.type = SMP_T_SINT;
Emeric Brun589fcad2012-10-16 14:13:26 +02005471
5472 return 1;
5473}
5474
Emeric Brun645ae792014-04-30 14:21:06 +02005475/* integer, returns the used keysize if front conn. transport layer is SSL.
5476 * This function is also usable on backend conn if the fetch keyword 5th
5477 * char is 'b'.
5478 */
Emeric Brun589fcad2012-10-16 14:13:26 +02005479static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005480smp_fetch_ssl_fc_use_keysize(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun589fcad2012-10-16 14:13:26 +02005481{
Willy Tarreaue237fe12016-03-10 17:05:28 +01005482 struct connection *conn = objt_conn((kw[4] != 'b') ? smp->sess->origin :
5483 smp->strm ? smp->strm->si[1].end : NULL);
Willy Tarreaube508f12016-03-10 11:47:01 +01005484
Emeric Brun589fcad2012-10-16 14:13:26 +02005485 smp->flags = 0;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005486 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
5487 return 0;
5488
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005489 smp->data.u.sint = (unsigned int)SSL_get_cipher_bits(conn->xprt_ctx, NULL);
5490 if (!smp->data.u.sint)
Emeric Brun589fcad2012-10-16 14:13:26 +02005491 return 0;
5492
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005493 smp->data.type = SMP_T_SINT;
Emeric Brun589fcad2012-10-16 14:13:26 +02005494
5495 return 1;
5496}
5497
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02005498#ifdef OPENSSL_NPN_NEGOTIATED
Willy Tarreau7875d092012-09-10 08:20:03 +02005499static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005500smp_fetch_ssl_fc_npn(const struct arg *args, struct sample *smp, const char *kw, void *private)
Willy Tarreaua33c6542012-10-15 13:19:06 +02005501{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005502 struct connection *conn;
5503
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01005504 smp->flags = SMP_F_CONST;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005505 smp->data.type = SMP_T_STR;
Willy Tarreaua33c6542012-10-15 13:19:06 +02005506
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02005507 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005508 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
5509 return 0;
5510
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005511 smp->data.u.str.str = NULL;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005512 SSL_get0_next_proto_negotiated(conn->xprt_ctx,
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005513 (const unsigned char **)&smp->data.u.str.str, (unsigned *)&smp->data.u.str.len);
Willy Tarreaua33c6542012-10-15 13:19:06 +02005514
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005515 if (!smp->data.u.str.str)
Willy Tarreaua33c6542012-10-15 13:19:06 +02005516 return 0;
5517
5518 return 1;
Willy Tarreaua33c6542012-10-15 13:19:06 +02005519}
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02005520#endif
Willy Tarreaua33c6542012-10-15 13:19:06 +02005521
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01005522#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Willy Tarreauab861d32013-04-02 02:30:41 +02005523static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005524smp_fetch_ssl_fc_alpn(const struct arg *args, struct sample *smp, const char *kw, void *private)
Willy Tarreauab861d32013-04-02 02:30:41 +02005525{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005526 struct connection *conn;
5527
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01005528 smp->flags = SMP_F_CONST;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005529 smp->data.type = SMP_T_STR;
Willy Tarreauab861d32013-04-02 02:30:41 +02005530
Willy Tarreaue26bf052015-05-12 10:30:12 +02005531 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005532 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
Willy Tarreauab861d32013-04-02 02:30:41 +02005533 return 0;
5534
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005535 smp->data.u.str.str = NULL;
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01005536 SSL_get0_alpn_selected(conn->xprt_ctx,
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005537 (const unsigned char **)&smp->data.u.str.str, (unsigned *)&smp->data.u.str.len);
Willy Tarreauab861d32013-04-02 02:30:41 +02005538
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005539 if (!smp->data.u.str.str)
Willy Tarreauab861d32013-04-02 02:30:41 +02005540 return 0;
5541
5542 return 1;
5543}
5544#endif
5545
Emeric Brun645ae792014-04-30 14:21:06 +02005546/* string, returns the used protocol if front conn. transport layer is SSL.
5547 * This function is also usable on backend conn if the fetch keyword 5th
5548 * char is 'b'.
5549 */
Willy Tarreaua33c6542012-10-15 13:19:06 +02005550static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005551smp_fetch_ssl_fc_protocol(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun589fcad2012-10-16 14:13:26 +02005552{
Willy Tarreaue237fe12016-03-10 17:05:28 +01005553 struct connection *conn = objt_conn((kw[4] != 'b') ? smp->sess->origin :
5554 smp->strm ? smp->strm->si[1].end : NULL);
Willy Tarreaube508f12016-03-10 11:47:01 +01005555
Emeric Brun589fcad2012-10-16 14:13:26 +02005556 smp->flags = 0;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005557 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
5558 return 0;
5559
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005560 smp->data.u.str.str = (char *)SSL_get_version(conn->xprt_ctx);
5561 if (!smp->data.u.str.str)
Emeric Brun589fcad2012-10-16 14:13:26 +02005562 return 0;
5563
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005564 smp->data.type = SMP_T_STR;
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01005565 smp->flags = SMP_F_CONST;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005566 smp->data.u.str.len = strlen(smp->data.u.str.str);
Emeric Brun589fcad2012-10-16 14:13:26 +02005567
5568 return 1;
5569}
5570
Willy Tarreau87b09662015-04-03 00:22:06 +02005571/* binary, returns the SSL stream id if front conn. transport layer is SSL.
Emeric Brun645ae792014-04-30 14:21:06 +02005572 * This function is also usable on backend conn if the fetch keyword 5th
5573 * char is 'b'.
5574 */
Emeric Brun589fcad2012-10-16 14:13:26 +02005575static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005576smp_fetch_ssl_fc_session_id(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brunfe68f682012-10-16 14:59:28 +02005577{
5578#if OPENSSL_VERSION_NUMBER > 0x0090800fL
Willy Tarreaue237fe12016-03-10 17:05:28 +01005579 struct connection *conn = objt_conn((kw[4] != 'b') ? smp->sess->origin :
5580 smp->strm ? smp->strm->si[1].end : NULL);
Emeric Brunfe68f682012-10-16 14:59:28 +02005581
Willy Tarreaue237fe12016-03-10 17:05:28 +01005582 SSL_SESSION *ssl_sess;
Willy Tarreaube508f12016-03-10 11:47:01 +01005583
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01005584 smp->flags = SMP_F_CONST;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005585 smp->data.type = SMP_T_BIN;
Emeric Brunfe68f682012-10-16 14:59:28 +02005586
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005587 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
5588 return 0;
5589
Willy Tarreau192252e2015-04-04 01:47:55 +02005590 ssl_sess = SSL_get_session(conn->xprt_ctx);
5591 if (!ssl_sess)
Emeric Brunfe68f682012-10-16 14:59:28 +02005592 return 0;
5593
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005594 smp->data.u.str.str = (char *)SSL_SESSION_get_id(ssl_sess, (unsigned int *)&smp->data.u.str.len);
5595 if (!smp->data.u.str.str || !smp->data.u.str.len)
Emeric Brunfe68f682012-10-16 14:59:28 +02005596 return 0;
5597
5598 return 1;
5599#else
5600 return 0;
5601#endif
5602}
5603
5604static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005605smp_fetch_ssl_fc_sni(const struct arg *args, struct sample *smp, const char *kw, void *private)
Willy Tarreau7875d092012-09-10 08:20:03 +02005606{
5607#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005608 struct connection *conn;
5609
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01005610 smp->flags = SMP_F_CONST;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005611 smp->data.type = SMP_T_STR;
Willy Tarreau7875d092012-09-10 08:20:03 +02005612
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02005613 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005614 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
5615 return 0;
5616
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005617 smp->data.u.str.str = (char *)SSL_get_servername(conn->xprt_ctx, TLSEXT_NAMETYPE_host_name);
5618 if (!smp->data.u.str.str)
Willy Tarreau3e394c92012-09-14 23:56:58 +02005619 return 0;
5620
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005621 smp->data.u.str.len = strlen(smp->data.u.str.str);
Willy Tarreau7875d092012-09-10 08:20:03 +02005622 return 1;
5623#else
5624 return 0;
5625#endif
5626}
5627
David Sc1ad52e2014-04-08 18:48:47 -04005628static int
Thierry FOURNIER5bf77322017-02-25 12:45:22 +01005629smp_fetch_ssl_fc_cl_bin(const struct arg *args, struct sample *smp, const char *kw, void *private)
5630{
Thierry FOURNIER5bf77322017-02-25 12:45:22 +01005631 struct connection *conn;
5632 struct ssl_capture *capture;
5633
5634 conn = objt_conn(smp->sess->origin);
5635 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
5636 return 0;
5637
Emmanuel Hocdetaaee7502017-03-07 18:34:58 +01005638 capture = SSL_get_ex_data(conn->xprt_ctx, ssl_capture_ptr_index);
Thierry FOURNIER5bf77322017-02-25 12:45:22 +01005639 if (!capture)
5640 return 0;
5641
5642 smp->flags = SMP_F_CONST;
5643 smp->data.type = SMP_T_BIN;
5644 smp->data.u.str.str = capture->ciphersuite;
5645 smp->data.u.str.len = capture->ciphersuite_len;
5646 return 1;
Thierry FOURNIER5bf77322017-02-25 12:45:22 +01005647}
5648
5649static int
5650smp_fetch_ssl_fc_cl_hex(const struct arg *args, struct sample *smp, const char *kw, void *private)
5651{
5652 struct chunk *data;
5653
5654 if (!smp_fetch_ssl_fc_cl_bin(args, smp, kw, private))
5655 return 0;
5656
5657 data = get_trash_chunk();
5658 dump_binary(data, smp->data.u.str.str, smp->data.u.str.len);
5659 smp->data.type = SMP_T_BIN;
5660 smp->data.u.str = *data;
5661 return 1;
5662}
5663
5664static int
5665smp_fetch_ssl_fc_cl_xxh64(const struct arg *args, struct sample *smp, const char *kw, void *private)
5666{
Thierry FOURNIER5bf77322017-02-25 12:45:22 +01005667 struct connection *conn;
5668 struct ssl_capture *capture;
5669
5670 conn = objt_conn(smp->sess->origin);
5671 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
5672 return 0;
5673
Emmanuel Hocdetaaee7502017-03-07 18:34:58 +01005674 capture = SSL_get_ex_data(conn->xprt_ctx, ssl_capture_ptr_index);
Thierry FOURNIER5bf77322017-02-25 12:45:22 +01005675 if (!capture)
5676 return 0;
5677
5678 smp->data.type = SMP_T_SINT;
5679 smp->data.u.sint = capture->xxh64;
5680 return 1;
Thierry FOURNIER5bf77322017-02-25 12:45:22 +01005681}
5682
5683static int
5684smp_fetch_ssl_fc_cl_str(const struct arg *args, struct sample *smp, const char *kw, void *private)
5685{
5686#if (OPENSSL_VERSION_NUMBER >= 0x1000200fL) && !defined(OPENSSL_NO_SSL_TRACE)
5687 struct chunk *data;
5688 SSL_CIPHER cipher;
5689 int i;
5690 const char *str;
5691 unsigned char *bin;
5692
5693 if (!smp_fetch_ssl_fc_cl_bin(args, smp, kw, private))
5694 return 0;
5695
5696 /* The cipher algorith must not be SSL_SSLV2, because this
5697 * SSL version seems to not have the same cipher encoding,
5698 * and it is not supported by OpenSSL. Unfortunately, the
5699 * #define SSL_SSLV2, SSL_SSLV3 and others are not available
5700 * with standard defines. We just set the variable to 0,
5701 * ensure that the match with SSL_SSLV2 fails.
5702 */
5703 cipher.algorithm_ssl = 0;
5704
5705 data = get_trash_chunk();
5706 for (i = 0; i + 1 < smp->data.u.str.len; i += 2) {
5707 bin = (unsigned char *)smp->data.u.str.str + i;
5708 cipher.id = (unsigned int)(bin[0] << 8) | bin[1];
5709 str = SSL_CIPHER_standard_name(&cipher);
5710 if (!str || strcmp(str, "UNKNOWN") == 0)
5711 chunk_appendf(data, "%sUNKNOWN(%04x)", i == 0 ? "" : ",", (unsigned int)cipher.id);
5712 else
5713 chunk_appendf(data, "%s%s", i == 0 ? "" : ",", str);
5714 }
5715 smp->data.type = SMP_T_STR;
5716 smp->data.u.str = *data;
5717 return 1;
5718#else
5719 return smp_fetch_ssl_fc_cl_xxh64(args, smp, kw, private);
5720#endif
5721}
5722
5723static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005724smp_fetch_ssl_fc_unique_id(const struct arg *args, struct sample *smp, const char *kw, void *private)
David Sc1ad52e2014-04-08 18:48:47 -04005725{
5726#if OPENSSL_VERSION_NUMBER > 0x0090800fL
Willy Tarreaue237fe12016-03-10 17:05:28 +01005727 struct connection *conn = objt_conn((kw[4] != 'b') ? smp->sess->origin :
5728 smp->strm ? smp->strm->si[1].end : NULL);
5729
David Sc1ad52e2014-04-08 18:48:47 -04005730 int finished_len;
David Sc1ad52e2014-04-08 18:48:47 -04005731 struct chunk *finished_trash;
David Sc1ad52e2014-04-08 18:48:47 -04005732
5733 smp->flags = 0;
David Sc1ad52e2014-04-08 18:48:47 -04005734 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
5735 return 0;
5736
5737 if (!(conn->flags & CO_FL_CONNECTED)) {
5738 smp->flags |= SMP_F_MAY_CHANGE;
5739 return 0;
5740 }
5741
5742 finished_trash = get_trash_chunk();
5743 if (!SSL_session_reused(conn->xprt_ctx))
5744 finished_len = SSL_get_peer_finished(conn->xprt_ctx, finished_trash->str, finished_trash->size);
5745 else
5746 finished_len = SSL_get_finished(conn->xprt_ctx, finished_trash->str, finished_trash->size);
5747
5748 if (!finished_len)
5749 return 0;
5750
Emeric Brunb73a9b02014-04-30 18:49:19 +02005751 finished_trash->len = finished_len;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005752 smp->data.u.str = *finished_trash;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005753 smp->data.type = SMP_T_BIN;
David Sc1ad52e2014-04-08 18:48:47 -04005754
5755 return 1;
5756#else
5757 return 0;
5758#endif
5759}
5760
Emeric Brun2525b6b2012-10-18 15:59:43 +02005761/* integer, returns the first verify error in CA chain of client certificate chain. */
Emeric Brunf282a812012-09-21 15:27:54 +02005762static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005763smp_fetch_ssl_c_ca_err(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brunf282a812012-09-21 15:27:54 +02005764{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005765 struct connection *conn;
5766
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02005767 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005768 if (!conn || conn->xprt != &ssl_sock)
5769 return 0;
5770
5771 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunf282a812012-09-21 15:27:54 +02005772 smp->flags = SMP_F_MAY_CHANGE;
5773 return 0;
5774 }
5775
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005776 smp->data.type = SMP_T_SINT;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005777 smp->data.u.sint = (unsigned long long int)SSL_SOCK_ST_TO_CA_ERROR(conn->xprt_st);
Emeric Brunf282a812012-09-21 15:27:54 +02005778 smp->flags = 0;
5779
5780 return 1;
5781}
5782
Emeric Brun2525b6b2012-10-18 15:59:43 +02005783/* integer, returns the depth of the first verify error in CA chain of client certificate chain. */
Emeric Brunf282a812012-09-21 15:27:54 +02005784static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005785smp_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 +02005786{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005787 struct connection *conn;
5788
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02005789 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005790 if (!conn || conn->xprt != &ssl_sock)
Emeric Brunf282a812012-09-21 15:27:54 +02005791 return 0;
5792
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005793 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunf282a812012-09-21 15:27:54 +02005794 smp->flags = SMP_F_MAY_CHANGE;
5795 return 0;
5796 }
5797
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005798 smp->data.type = SMP_T_SINT;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005799 smp->data.u.sint = (long long int)SSL_SOCK_ST_TO_CAEDEPTH(conn->xprt_st);
Emeric Brunf282a812012-09-21 15:27:54 +02005800 smp->flags = 0;
5801
5802 return 1;
5803}
5804
Emeric Brun2525b6b2012-10-18 15:59:43 +02005805/* integer, returns the first verify error on client certificate */
Emeric Brunf282a812012-09-21 15:27:54 +02005806static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005807smp_fetch_ssl_c_err(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brunf282a812012-09-21 15:27:54 +02005808{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005809 struct connection *conn;
5810
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02005811 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005812 if (!conn || conn->xprt != &ssl_sock)
5813 return 0;
5814
5815 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunf282a812012-09-21 15:27:54 +02005816 smp->flags = SMP_F_MAY_CHANGE;
5817 return 0;
5818 }
5819
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005820 smp->data.type = SMP_T_SINT;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005821 smp->data.u.sint = (long long int)SSL_SOCK_ST_TO_CRTERROR(conn->xprt_st);
Emeric Brunf282a812012-09-21 15:27:54 +02005822 smp->flags = 0;
5823
5824 return 1;
5825}
5826
Emeric Brun2525b6b2012-10-18 15:59:43 +02005827/* integer, returns the verify result on client cert */
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02005828static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005829smp_fetch_ssl_c_verify(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02005830{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005831 struct connection *conn;
5832
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02005833 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005834 if (!conn || conn->xprt != &ssl_sock)
5835 return 0;
5836
5837 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02005838 smp->flags = SMP_F_MAY_CHANGE;
5839 return 0;
5840 }
5841
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005842 if (!conn->xprt_ctx)
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02005843 return 0;
5844
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005845 smp->data.type = SMP_T_SINT;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005846 smp->data.u.sint = (long long int)SSL_get_verify_result(conn->xprt_ctx);
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02005847 smp->flags = 0;
5848
5849 return 1;
5850}
5851
Emeric Brunfb510ea2012-10-05 12:00:26 +02005852/* parse the "ca-file" bind keyword */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01005853static 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 +02005854{
5855 if (!*args[cur_arg + 1]) {
5856 if (err)
5857 memprintf(err, "'%s' : missing CAfile path", args[cur_arg]);
5858 return ERR_ALERT | ERR_FATAL;
5859 }
5860
Willy Tarreauef934602016-12-22 23:12:01 +01005861 if ((*args[cur_arg + 1] != '/') && global_ssl.ca_base)
5862 memprintf(&conf->ca_file, "%s/%s", global_ssl.ca_base, args[cur_arg + 1]);
Emeric Brunef42d922012-10-11 16:11:36 +02005863 else
5864 memprintf(&conf->ca_file, "%s", args[cur_arg + 1]);
Emeric Brunc8e8d122012-10-02 18:42:10 +02005865
Emeric Brund94b3fe2012-09-20 18:23:56 +02005866 return 0;
5867}
Emmanuel Hocdet98263292016-12-29 18:26:15 +01005868static int bind_parse_ca_file(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5869{
5870 return ssl_bind_parse_ca_file(args, cur_arg, px, &conf->ssl_conf, err);
5871}
Emeric Brund94b3fe2012-09-20 18:23:56 +02005872
Christopher Faulet31af49d2015-06-09 17:29:50 +02005873/* parse the "ca-sign-file" bind keyword */
5874static int bind_parse_ca_sign_file(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5875{
5876 if (!*args[cur_arg + 1]) {
5877 if (err)
5878 memprintf(err, "'%s' : missing CAfile path", args[cur_arg]);
5879 return ERR_ALERT | ERR_FATAL;
5880 }
5881
Willy Tarreauef934602016-12-22 23:12:01 +01005882 if ((*args[cur_arg + 1] != '/') && global_ssl.ca_base)
5883 memprintf(&conf->ca_sign_file, "%s/%s", global_ssl.ca_base, args[cur_arg + 1]);
Christopher Faulet31af49d2015-06-09 17:29:50 +02005884 else
5885 memprintf(&conf->ca_sign_file, "%s", args[cur_arg + 1]);
5886
5887 return 0;
5888}
5889
Bertrand Jacquinff13c062016-11-13 16:37:11 +00005890/* parse the "ca-sign-pass" bind keyword */
Christopher Faulet31af49d2015-06-09 17:29:50 +02005891static int bind_parse_ca_sign_pass(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5892{
5893 if (!*args[cur_arg + 1]) {
5894 if (err)
5895 memprintf(err, "'%s' : missing CAkey password", args[cur_arg]);
5896 return ERR_ALERT | ERR_FATAL;
5897 }
5898 memprintf(&conf->ca_sign_pass, "%s", args[cur_arg + 1]);
5899 return 0;
5900}
5901
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005902/* parse the "ciphers" bind keyword */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01005903static 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 +02005904{
5905 if (!*args[cur_arg + 1]) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02005906 memprintf(err, "'%s' : missing cipher suite", args[cur_arg]);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005907 return ERR_ALERT | ERR_FATAL;
5908 }
5909
Emeric Brun76d88952012-10-05 15:47:31 +02005910 free(conf->ciphers);
Willy Tarreau4348fad2012-09-20 16:48:07 +02005911 conf->ciphers = strdup(args[cur_arg + 1]);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005912 return 0;
5913}
Emmanuel Hocdet98263292016-12-29 18:26:15 +01005914static int bind_parse_ciphers(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5915{
5916 return ssl_bind_parse_ciphers(args, cur_arg, px, &conf->ssl_conf, err);
5917}
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005918/* parse the "crt" bind keyword */
Willy Tarreau4348fad2012-09-20 16:48:07 +02005919static 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 +02005920{
Willy Tarreau38011032013-08-13 16:59:39 +02005921 char path[MAXPATHLEN];
Willy Tarreaub75d6922014-04-14 18:05:41 +02005922
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005923 if (!*args[cur_arg + 1]) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02005924 memprintf(err, "'%s' : missing certificate location", args[cur_arg]);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005925 return ERR_ALERT | ERR_FATAL;
5926 }
5927
Willy Tarreauef934602016-12-22 23:12:01 +01005928 if ((*args[cur_arg + 1] != '/' ) && global_ssl.crt_base) {
5929 if ((strlen(global_ssl.crt_base) + 1 + strlen(args[cur_arg + 1]) + 1) > MAXPATHLEN) {
Emeric Brunc8e8d122012-10-02 18:42:10 +02005930 memprintf(err, "'%s' : path too long", args[cur_arg]);
5931 return ERR_ALERT | ERR_FATAL;
5932 }
Willy Tarreauef934602016-12-22 23:12:01 +01005933 snprintf(path, sizeof(path), "%s/%s", global_ssl.crt_base, args[cur_arg + 1]);
Willy Tarreau03209342016-12-22 17:08:28 +01005934 if (ssl_sock_load_cert(path, conf, err) > 0)
Emeric Brunc8e8d122012-10-02 18:42:10 +02005935 return ERR_ALERT | ERR_FATAL;
5936
5937 return 0;
5938 }
5939
Willy Tarreau03209342016-12-22 17:08:28 +01005940 if (ssl_sock_load_cert(args[cur_arg + 1], conf, err) > 0)
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005941 return ERR_ALERT | ERR_FATAL;
Emeric Brund94b3fe2012-09-20 18:23:56 +02005942
5943 return 0;
5944}
5945
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01005946/* parse the "crt-list" bind keyword */
5947static int bind_parse_crt_list(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5948{
5949 if (!*args[cur_arg + 1]) {
5950 memprintf(err, "'%s' : missing certificate location", args[cur_arg]);
5951 return ERR_ALERT | ERR_FATAL;
5952 }
5953
Emmanuel Hocdet98263292016-12-29 18:26:15 +01005954 if (ssl_sock_load_cert_list_file(args[cur_arg + 1], conf, px, err) > 0) {
Willy Tarreauad1731d2013-04-02 17:35:58 +02005955 memprintf(err, "'%s' : %s", args[cur_arg], *err);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01005956 return ERR_ALERT | ERR_FATAL;
Willy Tarreauad1731d2013-04-02 17:35:58 +02005957 }
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01005958
5959 return 0;
5960}
5961
Emeric Brunfb510ea2012-10-05 12:00:26 +02005962/* parse the "crl-file" bind keyword */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01005963static 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 +02005964{
Emeric Brun051cdab2012-10-02 19:25:50 +02005965#ifndef X509_V_FLAG_CRL_CHECK
5966 if (err)
5967 memprintf(err, "'%s' : library does not support CRL verify", args[cur_arg]);
5968 return ERR_ALERT | ERR_FATAL;
5969#else
Emeric Brund94b3fe2012-09-20 18:23:56 +02005970 if (!*args[cur_arg + 1]) {
5971 if (err)
5972 memprintf(err, "'%s' : missing CRLfile path", args[cur_arg]);
5973 return ERR_ALERT | ERR_FATAL;
5974 }
Emeric Brun2b58d042012-09-20 17:10:03 +02005975
Willy Tarreauef934602016-12-22 23:12:01 +01005976 if ((*args[cur_arg + 1] != '/') && global_ssl.ca_base)
5977 memprintf(&conf->crl_file, "%s/%s", global_ssl.ca_base, args[cur_arg + 1]);
Emeric Brunef42d922012-10-11 16:11:36 +02005978 else
5979 memprintf(&conf->crl_file, "%s", args[cur_arg + 1]);
Emeric Brunc8e8d122012-10-02 18:42:10 +02005980
Emeric Brun2b58d042012-09-20 17:10:03 +02005981 return 0;
Emeric Brun051cdab2012-10-02 19:25:50 +02005982#endif
Emeric Brun2b58d042012-09-20 17:10:03 +02005983}
Emmanuel Hocdet98263292016-12-29 18:26:15 +01005984static int bind_parse_crl_file(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5985{
5986 return ssl_bind_parse_crl_file(args, cur_arg, px, &conf->ssl_conf, err);
5987}
Emeric Brun2b58d042012-09-20 17:10:03 +02005988
Emmanuel Hocdete7f2b732017-01-09 16:15:54 +01005989/* parse the "curves" bind keyword keyword */
5990static int ssl_bind_parse_curves(char **args, int cur_arg, struct proxy *px, struct ssl_bind_conf *conf, char **err)
5991{
5992#if OPENSSL_VERSION_NUMBER >= 0x1000200fL
5993 if (!*args[cur_arg + 1]) {
5994 if (err)
5995 memprintf(err, "'%s' : missing curve suite", args[cur_arg]);
5996 return ERR_ALERT | ERR_FATAL;
5997 }
5998 conf->curves = strdup(args[cur_arg + 1]);
5999 return 0;
6000#else
6001 if (err)
6002 memprintf(err, "'%s' : library does not support curve suite", args[cur_arg]);
6003 return ERR_ALERT | ERR_FATAL;
6004#endif
6005}
6006static int bind_parse_curves(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
6007{
6008 return ssl_bind_parse_curves(args, cur_arg, px, &conf->ssl_conf, err);
6009}
6010
Bertrand Jacquinff13c062016-11-13 16:37:11 +00006011/* parse the "ecdhe" bind keyword keyword */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01006012static 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 +02006013{
6014#if OPENSSL_VERSION_NUMBER < 0x0090800fL
6015 if (err)
6016 memprintf(err, "'%s' : library does not support elliptic curve Diffie-Hellman (too old)", args[cur_arg]);
6017 return ERR_ALERT | ERR_FATAL;
6018#elif defined(OPENSSL_NO_ECDH)
6019 if (err)
6020 memprintf(err, "'%s' : library does not support elliptic curve Diffie-Hellman (disabled via OPENSSL_NO_ECDH)", args[cur_arg]);
6021 return ERR_ALERT | ERR_FATAL;
6022#else
6023 if (!*args[cur_arg + 1]) {
6024 if (err)
6025 memprintf(err, "'%s' : missing named curve", args[cur_arg]);
6026 return ERR_ALERT | ERR_FATAL;
6027 }
6028
6029 conf->ecdhe = strdup(args[cur_arg + 1]);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02006030
6031 return 0;
Emeric Brun2b58d042012-09-20 17:10:03 +02006032#endif
Willy Tarreau79eeafa2012-09-14 07:53:05 +02006033}
Emmanuel Hocdet98263292016-12-29 18:26:15 +01006034static int bind_parse_ecdhe(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
6035{
6036 return ssl_bind_parse_ecdhe(args, cur_arg, px, &conf->ssl_conf, err);
6037}
Willy Tarreau79eeafa2012-09-14 07:53:05 +02006038
Bertrand Jacquinff13c062016-11-13 16:37:11 +00006039/* parse the "crt-ignore-err" and "ca-ignore-err" bind keywords */
Emeric Brun81c00f02012-09-21 14:31:21 +02006040static int bind_parse_ignore_err(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
6041{
6042 int code;
6043 char *p = args[cur_arg + 1];
6044 unsigned long long *ignerr = &conf->crt_ignerr;
6045
6046 if (!*p) {
6047 if (err)
6048 memprintf(err, "'%s' : missing error IDs list", args[cur_arg]);
6049 return ERR_ALERT | ERR_FATAL;
6050 }
6051
6052 if (strcmp(args[cur_arg], "ca-ignore-err") == 0)
6053 ignerr = &conf->ca_ignerr;
6054
6055 if (strcmp(p, "all") == 0) {
6056 *ignerr = ~0ULL;
6057 return 0;
6058 }
6059
6060 while (p) {
6061 code = atoi(p);
6062 if ((code <= 0) || (code > 63)) {
6063 if (err)
6064 memprintf(err, "'%s' : ID '%d' out of range (1..63) in error IDs list '%s'",
6065 args[cur_arg], code, args[cur_arg + 1]);
6066 return ERR_ALERT | ERR_FATAL;
6067 }
6068 *ignerr |= 1ULL << code;
6069 p = strchr(p, ',');
6070 if (p)
6071 p++;
6072 }
6073
Emeric Brun2cb7ae52012-10-05 14:14:21 +02006074 return 0;
6075}
6076
6077/* parse the "force-sslv3" bind keyword */
Emmanuel Hocdet4608ed92017-01-20 13:06:27 +01006078static 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 +02006079{
Emmanuel Hocdet4de1ff12017-03-03 12:21:32 +01006080#ifndef OPENSSL_NO_SSL3
Emeric Brun2cb7ae52012-10-05 14:14:21 +02006081 conf->ssl_options |= BC_SSL_O_USE_SSLV3;
6082 return 0;
Emmanuel Hocdet4de1ff12017-03-03 12:21:32 +01006083#else
6084 if (err)
6085 memprintf(err, "'%s' : library does not support protocol SSLv3", args[cur_arg]);
6086 return ERR_ALERT | ERR_FATAL;
6087#endif
Emeric Brun2cb7ae52012-10-05 14:14:21 +02006088}
6089
6090/* parse the "force-tlsv10" bind keyword */
Emmanuel Hocdet4608ed92017-01-20 13:06:27 +01006091static 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 +02006092{
6093 conf->ssl_options |= BC_SSL_O_USE_TLSV10;
Emeric Brun2d0c4822012-10-02 13:45:20 +02006094 return 0;
6095}
6096
Emeric Brun2cb7ae52012-10-05 14:14:21 +02006097/* parse the "force-tlsv11" bind keyword */
Emmanuel Hocdet4608ed92017-01-20 13:06:27 +01006098static 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 +02006099{
6100#if SSL_OP_NO_TLSv1_1
6101 conf->ssl_options |= BC_SSL_O_USE_TLSV11;
6102 return 0;
6103#else
6104 if (err)
6105 memprintf(err, "'%s' : library does not support protocol TLSv1.1", args[cur_arg]);
6106 return ERR_ALERT | ERR_FATAL;
6107#endif
6108}
6109
6110/* parse the "force-tlsv12" bind keyword */
Emmanuel Hocdet4608ed92017-01-20 13:06:27 +01006111static 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 +02006112{
6113#if SSL_OP_NO_TLSv1_2
6114 conf->ssl_options |= BC_SSL_O_USE_TLSV12;
6115 return 0;
6116#else
6117 if (err)
6118 memprintf(err, "'%s' : library does not support protocol TLSv1.2", args[cur_arg]);
6119 return ERR_ALERT | ERR_FATAL;
6120#endif
6121}
Emeric Brun2cb7ae52012-10-05 14:14:21 +02006122
Emeric Brun2d0c4822012-10-02 13:45:20 +02006123/* parse the "no-tls-tickets" bind keyword */
Emmanuel Hocdet4608ed92017-01-20 13:06:27 +01006124static 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 +02006125{
Emeric Brun89675492012-10-05 13:48:26 +02006126 conf->ssl_options |= BC_SSL_O_NO_TLS_TICKETS;
Emeric Brun81c00f02012-09-21 14:31:21 +02006127 return 0;
6128}
Emeric Brun2d0c4822012-10-02 13:45:20 +02006129
Emeric Brun9b3009b2012-10-05 11:55:06 +02006130/* parse the "no-sslv3" bind keyword */
Emmanuel Hocdet4608ed92017-01-20 13:06:27 +01006131static 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 +02006132{
Emeric Brun89675492012-10-05 13:48:26 +02006133 conf->ssl_options |= BC_SSL_O_NO_SSLV3;
Willy Tarreau79eeafa2012-09-14 07:53:05 +02006134 return 0;
6135}
6136
Emeric Brun9b3009b2012-10-05 11:55:06 +02006137/* parse the "no-tlsv10" bind keyword */
Emmanuel Hocdet4608ed92017-01-20 13:06:27 +01006138static 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 +02006139{
Emeric Brun89675492012-10-05 13:48:26 +02006140 conf->ssl_options |= BC_SSL_O_NO_TLSV10;
Emeric Brunc0ff4922012-09-28 19:37:02 +02006141 return 0;
6142}
6143
Emeric Brun9b3009b2012-10-05 11:55:06 +02006144/* parse the "no-tlsv11" bind keyword */
Emmanuel Hocdet4608ed92017-01-20 13:06:27 +01006145static 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 +02006146{
Emeric Brun89675492012-10-05 13:48:26 +02006147 conf->ssl_options |= BC_SSL_O_NO_TLSV11;
Emeric Brunc0ff4922012-09-28 19:37:02 +02006148 return 0;
6149}
6150
Emeric Brun9b3009b2012-10-05 11:55:06 +02006151/* parse the "no-tlsv12" bind keyword */
Emmanuel Hocdet4608ed92017-01-20 13:06:27 +01006152static 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 +02006153{
Emeric Brun89675492012-10-05 13:48:26 +02006154 conf->ssl_options |= BC_SSL_O_NO_TLSV12;
Willy Tarreau79eeafa2012-09-14 07:53:05 +02006155 return 0;
6156}
6157
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02006158/* parse the "npn" bind keyword */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01006159static 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 +02006160{
6161#ifdef OPENSSL_NPN_NEGOTIATED
6162 char *p1, *p2;
6163
6164 if (!*args[cur_arg + 1]) {
6165 memprintf(err, "'%s' : missing the comma-delimited NPN protocol suite", args[cur_arg]);
6166 return ERR_ALERT | ERR_FATAL;
6167 }
6168
6169 free(conf->npn_str);
6170
Willy Tarreau3724da12016-02-12 17:11:12 +01006171 /* the NPN string is built as a suite of (<len> <name>)*,
6172 * so we reuse each comma to store the next <len> and need
6173 * one more for the end of the string.
6174 */
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02006175 conf->npn_len = strlen(args[cur_arg + 1]) + 1;
Willy Tarreau3724da12016-02-12 17:11:12 +01006176 conf->npn_str = calloc(1, conf->npn_len + 1);
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02006177 memcpy(conf->npn_str + 1, args[cur_arg + 1], conf->npn_len);
6178
6179 /* replace commas with the name length */
6180 p1 = conf->npn_str;
6181 p2 = p1 + 1;
6182 while (1) {
6183 p2 = memchr(p1 + 1, ',', conf->npn_str + conf->npn_len - (p1 + 1));
6184 if (!p2)
6185 p2 = p1 + 1 + strlen(p1 + 1);
6186
6187 if (p2 - (p1 + 1) > 255) {
6188 *p2 = '\0';
6189 memprintf(err, "'%s' : NPN protocol name too long : '%s'", args[cur_arg], p1 + 1);
6190 return ERR_ALERT | ERR_FATAL;
6191 }
6192
6193 *p1 = p2 - (p1 + 1);
6194 p1 = p2;
6195
6196 if (!*p2)
6197 break;
6198
6199 *(p2++) = '\0';
6200 }
6201 return 0;
6202#else
6203 if (err)
6204 memprintf(err, "'%s' : library does not support TLS NPN extension", args[cur_arg]);
6205 return ERR_ALERT | ERR_FATAL;
6206#endif
6207}
6208
Emmanuel Hocdet98263292016-12-29 18:26:15 +01006209static int bind_parse_npn(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
6210{
6211 return ssl_bind_parse_npn(args, cur_arg, px, &conf->ssl_conf, err);
6212}
6213
Willy Tarreauab861d32013-04-02 02:30:41 +02006214/* parse the "alpn" bind keyword */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01006215static 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 +02006216{
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01006217#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Willy Tarreauab861d32013-04-02 02:30:41 +02006218 char *p1, *p2;
6219
6220 if (!*args[cur_arg + 1]) {
6221 memprintf(err, "'%s' : missing the comma-delimited ALPN protocol suite", args[cur_arg]);
6222 return ERR_ALERT | ERR_FATAL;
6223 }
6224
6225 free(conf->alpn_str);
6226
Marcoen Hirschbergbef60912016-02-12 17:05:24 +01006227 /* the ALPN string is built as a suite of (<len> <name>)*,
6228 * so we reuse each comma to store the next <len> and need
6229 * one more for the end of the string.
6230 */
Willy Tarreauab861d32013-04-02 02:30:41 +02006231 conf->alpn_len = strlen(args[cur_arg + 1]) + 1;
Marcoen Hirschbergbef60912016-02-12 17:05:24 +01006232 conf->alpn_str = calloc(1, conf->alpn_len + 1);
Willy Tarreauab861d32013-04-02 02:30:41 +02006233 memcpy(conf->alpn_str + 1, args[cur_arg + 1], conf->alpn_len);
6234
6235 /* replace commas with the name length */
6236 p1 = conf->alpn_str;
6237 p2 = p1 + 1;
6238 while (1) {
6239 p2 = memchr(p1 + 1, ',', conf->alpn_str + conf->alpn_len - (p1 + 1));
6240 if (!p2)
6241 p2 = p1 + 1 + strlen(p1 + 1);
6242
6243 if (p2 - (p1 + 1) > 255) {
6244 *p2 = '\0';
6245 memprintf(err, "'%s' : ALPN protocol name too long : '%s'", args[cur_arg], p1 + 1);
6246 return ERR_ALERT | ERR_FATAL;
6247 }
6248
6249 *p1 = p2 - (p1 + 1);
6250 p1 = p2;
6251
6252 if (!*p2)
6253 break;
6254
6255 *(p2++) = '\0';
6256 }
6257 return 0;
6258#else
6259 if (err)
6260 memprintf(err, "'%s' : library does not support TLS ALPN extension", args[cur_arg]);
6261 return ERR_ALERT | ERR_FATAL;
6262#endif
6263}
6264
Emmanuel Hocdet98263292016-12-29 18:26:15 +01006265static int bind_parse_alpn(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
6266{
6267 return ssl_bind_parse_alpn(args, cur_arg, px, &conf->ssl_conf, err);
6268}
6269
Willy Tarreau79eeafa2012-09-14 07:53:05 +02006270/* parse the "ssl" bind keyword */
Willy Tarreau4348fad2012-09-20 16:48:07 +02006271static 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 +02006272{
Willy Tarreau71a8c7c2016-12-21 22:04:54 +01006273 conf->xprt = &ssl_sock;
Willy Tarreau4348fad2012-09-20 16:48:07 +02006274 conf->is_ssl = 1;
Emeric Brun76d88952012-10-05 15:47:31 +02006275
Emmanuel Hocdet98263292016-12-29 18:26:15 +01006276 if (global_ssl.listen_default_ciphers && !conf->ssl_conf.ciphers)
6277 conf->ssl_conf.ciphers = strdup(global_ssl.listen_default_ciphers);
Emmanuel Hocdet4608ed92017-01-20 13:06:27 +01006278 conf->ssl_options |= global_ssl.listen_default_ssloptions;
Emeric Brun76d88952012-10-05 15:47:31 +02006279
Willy Tarreau79eeafa2012-09-14 07:53:05 +02006280 return 0;
6281}
6282
Christopher Faulet31af49d2015-06-09 17:29:50 +02006283/* parse the "generate-certificates" bind keyword */
6284static int bind_parse_generate_certs(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
6285{
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +01006286#if (defined SSL_CTRL_SET_TLSEXT_HOSTNAME && !defined SSL_NO_GENERATE_CERTIFICATES)
Christopher Faulet31af49d2015-06-09 17:29:50 +02006287 conf->generate_certs = 1;
6288#else
6289 memprintf(err, "%sthis version of openssl cannot generate SSL certificates.\n",
6290 err && *err ? *err : "");
6291#endif
6292 return 0;
6293}
6294
Emmanuel Hocdet65623372013-01-24 17:17:15 +01006295/* parse the "strict-sni" bind keyword */
6296static int bind_parse_strict_sni(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
6297{
6298 conf->strict_sni = 1;
6299 return 0;
Nenad Merdanovic05552d42015-02-27 19:56:49 +01006300}
6301
6302/* parse the "tls-ticket-keys" bind keyword */
6303static int bind_parse_tls_ticket_keys(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
6304{
6305#if (defined SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB && TLS_TICKETS_NO > 0)
6306 FILE *f;
6307 int i = 0;
6308 char thisline[LINESIZE];
Nenad Merdanovic146defa2015-05-09 08:46:00 +02006309 struct tls_keys_ref *keys_ref;
Nenad Merdanovic05552d42015-02-27 19:56:49 +01006310
6311 if (!*args[cur_arg + 1]) {
6312 if (err)
6313 memprintf(err, "'%s' : missing TLS ticket keys file path", args[cur_arg]);
6314 return ERR_ALERT | ERR_FATAL;
6315 }
6316
Nenad Merdanovic200b0fa2015-05-09 08:46:01 +02006317 keys_ref = tlskeys_ref_lookup(args[cur_arg + 1]);
6318 if(keys_ref) {
6319 conf->keys_ref = keys_ref;
6320 return 0;
6321 }
6322
Vincent Bernat02779b62016-04-03 13:48:43 +02006323 keys_ref = malloc(sizeof(*keys_ref));
Nenad Merdanovic146defa2015-05-09 08:46:00 +02006324 keys_ref->tlskeys = malloc(TLS_TICKETS_NO * sizeof(struct tls_sess_key));
Nenad Merdanovic05552d42015-02-27 19:56:49 +01006325
6326 if ((f = fopen(args[cur_arg + 1], "r")) == NULL) {
6327 if (err)
6328 memprintf(err, "'%s' : unable to load ssl tickets keys file", args[cur_arg+1]);
6329 return ERR_ALERT | ERR_FATAL;
6330 }
6331
Nenad Merdanovic146defa2015-05-09 08:46:00 +02006332 keys_ref->filename = strdup(args[cur_arg + 1]);
6333
Nenad Merdanovic05552d42015-02-27 19:56:49 +01006334 while (fgets(thisline, sizeof(thisline), f) != NULL) {
6335 int len = strlen(thisline);
6336 /* Strip newline characters from the end */
6337 if(thisline[len - 1] == '\n')
6338 thisline[--len] = 0;
6339
6340 if(thisline[len - 1] == '\r')
6341 thisline[--len] = 0;
6342
Nenad Merdanovic146defa2015-05-09 08:46:00 +02006343 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 +01006344 if (err)
6345 memprintf(err, "'%s' : unable to decode base64 key on line %d", args[cur_arg+1], i + 1);
mildis16aa0152016-06-22 17:46:29 +02006346 fclose(f);
Nenad Merdanovic05552d42015-02-27 19:56:49 +01006347 return ERR_ALERT | ERR_FATAL;
6348 }
6349 i++;
6350 }
6351
6352 if (i < TLS_TICKETS_NO) {
6353 if (err)
6354 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 +02006355 fclose(f);
Nenad Merdanovic05552d42015-02-27 19:56:49 +01006356 return ERR_ALERT | ERR_FATAL;
6357 }
6358
6359 fclose(f);
6360
6361 /* Use penultimate key for encryption, handle when TLS_TICKETS_NO = 1 */
Nenad Merdanovic17891152016-03-25 22:16:57 +01006362 i -= 2;
6363 keys_ref->tls_ticket_enc_index = i < 0 ? 0 : i % TLS_TICKETS_NO;
Nenad Merdanovic200b0fa2015-05-09 08:46:01 +02006364 keys_ref->unique_id = -1;
Nenad Merdanovic146defa2015-05-09 08:46:00 +02006365 conf->keys_ref = keys_ref;
Nenad Merdanovic05552d42015-02-27 19:56:49 +01006366
Nenad Merdanovic200b0fa2015-05-09 08:46:01 +02006367 LIST_ADD(&tlskeys_reference, &keys_ref->list);
6368
Nenad Merdanovic05552d42015-02-27 19:56:49 +01006369 return 0;
6370#else
6371 if (err)
6372 memprintf(err, "'%s' : TLS ticket callback extension not supported", args[cur_arg]);
6373 return ERR_ALERT | ERR_FATAL;
6374#endif /* SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB */
Emmanuel Hocdet65623372013-01-24 17:17:15 +01006375}
6376
Emeric Brund94b3fe2012-09-20 18:23:56 +02006377/* parse the "verify" bind keyword */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01006378static 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 +02006379{
6380 if (!*args[cur_arg + 1]) {
6381 if (err)
6382 memprintf(err, "'%s' : missing verify method", args[cur_arg]);
6383 return ERR_ALERT | ERR_FATAL;
6384 }
6385
6386 if (strcmp(args[cur_arg + 1], "none") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01006387 conf->verify = SSL_SOCK_VERIFY_NONE;
Emeric Brund94b3fe2012-09-20 18:23:56 +02006388 else if (strcmp(args[cur_arg + 1], "optional") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01006389 conf->verify = SSL_SOCK_VERIFY_OPTIONAL;
Emeric Brund94b3fe2012-09-20 18:23:56 +02006390 else if (strcmp(args[cur_arg + 1], "required") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01006391 conf->verify = SSL_SOCK_VERIFY_REQUIRED;
Emeric Brund94b3fe2012-09-20 18:23:56 +02006392 else {
6393 if (err)
6394 memprintf(err, "'%s' : unknown verify method '%s', only 'none', 'optional', and 'required' are supported\n",
6395 args[cur_arg], args[cur_arg + 1]);
6396 return ERR_ALERT | ERR_FATAL;
6397 }
6398
6399 return 0;
6400}
Emmanuel Hocdet98263292016-12-29 18:26:15 +01006401static int bind_parse_verify(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
6402{
6403 return ssl_bind_parse_verify(args, cur_arg, px, &conf->ssl_conf, err);
6404}
Emeric Brund94b3fe2012-09-20 18:23:56 +02006405
Willy Tarreau92faadf2012-10-10 23:04:25 +02006406/************** "server" keywords ****************/
6407
Emeric Brunef42d922012-10-11 16:11:36 +02006408/* parse the "ca-file" server keyword */
6409static int srv_parse_ca_file(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
6410{
6411 if (!*args[*cur_arg + 1]) {
6412 if (err)
6413 memprintf(err, "'%s' : missing CAfile path", args[*cur_arg]);
6414 return ERR_ALERT | ERR_FATAL;
6415 }
6416
Willy Tarreauef934602016-12-22 23:12:01 +01006417 if ((*args[*cur_arg + 1] != '/') && global_ssl.ca_base)
6418 memprintf(&newsrv->ssl_ctx.ca_file, "%s/%s", global_ssl.ca_base, args[*cur_arg + 1]);
Emeric Brunef42d922012-10-11 16:11:36 +02006419 else
6420 memprintf(&newsrv->ssl_ctx.ca_file, "%s", args[*cur_arg + 1]);
6421
6422 return 0;
6423}
6424
Willy Tarreau92faadf2012-10-10 23:04:25 +02006425/* parse the "check-ssl" server keyword */
6426static int srv_parse_check_ssl(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
6427{
6428 newsrv->check.use_ssl = 1;
Willy Tarreauef934602016-12-22 23:12:01 +01006429 if (global_ssl.connect_default_ciphers && !newsrv->ssl_ctx.ciphers)
6430 newsrv->ssl_ctx.ciphers = strdup(global_ssl.connect_default_ciphers);
6431 newsrv->ssl_ctx.options |= global_ssl.connect_default_ssloptions;
Willy Tarreau92faadf2012-10-10 23:04:25 +02006432 return 0;
6433}
6434
6435/* parse the "ciphers" server keyword */
6436static int srv_parse_ciphers(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
6437{
6438 if (!*args[*cur_arg + 1]) {
6439 memprintf(err, "'%s' : missing cipher suite", args[*cur_arg]);
6440 return ERR_ALERT | ERR_FATAL;
6441 }
6442
6443 free(newsrv->ssl_ctx.ciphers);
6444 newsrv->ssl_ctx.ciphers = strdup(args[*cur_arg + 1]);
6445 return 0;
6446}
6447
Emeric Brunef42d922012-10-11 16:11:36 +02006448/* parse the "crl-file" server keyword */
6449static int srv_parse_crl_file(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
6450{
6451#ifndef X509_V_FLAG_CRL_CHECK
6452 if (err)
6453 memprintf(err, "'%s' : library does not support CRL verify", args[*cur_arg]);
6454 return ERR_ALERT | ERR_FATAL;
6455#else
6456 if (!*args[*cur_arg + 1]) {
6457 if (err)
6458 memprintf(err, "'%s' : missing CRLfile path", args[*cur_arg]);
6459 return ERR_ALERT | ERR_FATAL;
6460 }
6461
Willy Tarreauef934602016-12-22 23:12:01 +01006462 if ((*args[*cur_arg + 1] != '/') && global_ssl.ca_base)
6463 memprintf(&newsrv->ssl_ctx.crl_file, "%s/%s", global_ssl.ca_base, args[*cur_arg + 1]);
Emeric Brunef42d922012-10-11 16:11:36 +02006464 else
6465 memprintf(&newsrv->ssl_ctx.crl_file, "%s", args[*cur_arg + 1]);
6466
6467 return 0;
6468#endif
6469}
6470
Emeric Bruna7aa3092012-10-26 12:58:00 +02006471/* parse the "crt" server keyword */
6472static int srv_parse_crt(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
6473{
6474 if (!*args[*cur_arg + 1]) {
6475 if (err)
6476 memprintf(err, "'%s' : missing certificate file path", args[*cur_arg]);
6477 return ERR_ALERT | ERR_FATAL;
6478 }
6479
Willy Tarreauef934602016-12-22 23:12:01 +01006480 if ((*args[*cur_arg + 1] != '/') && global_ssl.crt_base)
6481 memprintf(&newsrv->ssl_ctx.client_crt, "%s/%s", global_ssl.ca_base, args[*cur_arg + 1]);
Emeric Bruna7aa3092012-10-26 12:58:00 +02006482 else
6483 memprintf(&newsrv->ssl_ctx.client_crt, "%s", args[*cur_arg + 1]);
6484
6485 return 0;
6486}
Emeric Brunef42d922012-10-11 16:11:36 +02006487
Willy Tarreau92faadf2012-10-10 23:04:25 +02006488/* parse the "force-sslv3" server keyword */
6489static int srv_parse_force_sslv3(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
6490{
Emmanuel Hocdet4de1ff12017-03-03 12:21:32 +01006491#ifndef OPENSSL_NO_SSL3
Willy Tarreau92faadf2012-10-10 23:04:25 +02006492 newsrv->ssl_ctx.options |= SRV_SSL_O_USE_SSLV3;
6493 return 0;
Emmanuel Hocdet4de1ff12017-03-03 12:21:32 +01006494#else
6495 if (err)
6496 memprintf(err, "'%s' : library does not support protocol SSLv3", args[*cur_arg]);
6497 return ERR_ALERT | ERR_FATAL;
6498#endif
Willy Tarreau92faadf2012-10-10 23:04:25 +02006499}
6500
6501/* parse the "force-tlsv10" server keyword */
6502static int srv_parse_force_tlsv10(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
6503{
6504 newsrv->ssl_ctx.options |= SRV_SSL_O_USE_TLSV10;
6505 return 0;
6506}
6507
6508/* parse the "force-tlsv11" server keyword */
6509static int srv_parse_force_tlsv11(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
6510{
6511#if SSL_OP_NO_TLSv1_1
6512 newsrv->ssl_ctx.options |= SRV_SSL_O_USE_TLSV11;
6513 return 0;
6514#else
6515 if (err)
6516 memprintf(err, "'%s' : library does not support protocol TLSv1.1", args[*cur_arg]);
6517 return ERR_ALERT | ERR_FATAL;
6518#endif
6519}
6520
6521/* parse the "force-tlsv12" server keyword */
6522static int srv_parse_force_tlsv12(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
6523{
6524#if SSL_OP_NO_TLSv1_2
6525 newsrv->ssl_ctx.options |= SRV_SSL_O_USE_TLSV12;
6526 return 0;
6527#else
6528 if (err)
6529 memprintf(err, "'%s' : library does not support protocol TLSv1.2", args[*cur_arg]);
6530 return ERR_ALERT | ERR_FATAL;
6531#endif
6532}
6533
Willy Tarreau2a3fb1c2015-02-05 16:47:07 +01006534/* parse the "no-ssl-reuse" server keyword */
6535static int srv_parse_no_ssl_reuse(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
6536{
6537 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_REUSE;
6538 return 0;
6539}
6540
Willy Tarreau92faadf2012-10-10 23:04:25 +02006541/* parse the "no-sslv3" server keyword */
6542static int srv_parse_no_sslv3(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
6543{
6544 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_SSLV3;
6545 return 0;
6546}
6547
6548/* parse the "no-tlsv10" server keyword */
6549static int srv_parse_no_tlsv10(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
6550{
6551 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_TLSV10;
6552 return 0;
6553}
6554
6555/* parse the "no-tlsv11" server keyword */
6556static int srv_parse_no_tlsv11(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
6557{
6558 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_TLSV11;
6559 return 0;
6560}
6561
6562/* parse the "no-tlsv12" server keyword */
6563static int srv_parse_no_tlsv12(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
6564{
6565 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_TLSV12;
6566 return 0;
6567}
6568
Emeric Brunf9c5c472012-10-11 15:28:34 +02006569/* parse the "no-tls-tickets" server keyword */
6570static int srv_parse_no_tls_tickets(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
6571{
6572 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_TLS_TICKETS;
6573 return 0;
6574}
David Safb76832014-05-08 23:42:08 -04006575/* parse the "send-proxy-v2-ssl" server keyword */
6576static int srv_parse_send_proxy_ssl(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
6577{
6578 newsrv->pp_opts |= SRV_PP_V2;
6579 newsrv->pp_opts |= SRV_PP_V2_SSL;
6580 return 0;
6581}
6582
6583/* parse the "send-proxy-v2-ssl-cn" server keyword */
6584static int srv_parse_send_proxy_cn(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
6585{
6586 newsrv->pp_opts |= SRV_PP_V2;
6587 newsrv->pp_opts |= SRV_PP_V2_SSL;
6588 newsrv->pp_opts |= SRV_PP_V2_SSL_CN;
6589 return 0;
6590}
Emeric Brunf9c5c472012-10-11 15:28:34 +02006591
Willy Tarreau732eac42015-07-09 11:40:25 +02006592/* parse the "sni" server keyword */
6593static int srv_parse_sni(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
6594{
6595#ifndef SSL_CTRL_SET_TLSEXT_HOSTNAME
6596 memprintf(err, "'%s' : the current SSL library doesn't support the SNI TLS extension", args[*cur_arg]);
6597 return ERR_ALERT | ERR_FATAL;
6598#else
Cyril Bonté23d19d62016-03-07 22:13:22 +01006599 int idx;
Willy Tarreau732eac42015-07-09 11:40:25 +02006600 struct sample_expr *expr;
6601
6602 if (!*args[*cur_arg + 1]) {
6603 memprintf(err, "'%s' : missing sni expression", args[*cur_arg]);
6604 return ERR_ALERT | ERR_FATAL;
6605 }
6606
Cyril Bonté23d19d62016-03-07 22:13:22 +01006607 idx = (*cur_arg) + 1;
Willy Tarreau732eac42015-07-09 11:40:25 +02006608 proxy->conf.args.ctx = ARGC_SRV;
6609
Cyril Bonté23d19d62016-03-07 22:13:22 +01006610 expr = sample_parse_expr((char **)args, &idx, px->conf.file, px->conf.line, err, &proxy->conf.args);
Willy Tarreau732eac42015-07-09 11:40:25 +02006611 if (!expr) {
6612 memprintf(err, "error detected while parsing sni expression : %s", *err);
6613 return ERR_ALERT | ERR_FATAL;
6614 }
6615
6616 if (!(expr->fetch->val & SMP_VAL_BE_SRV_CON)) {
6617 memprintf(err, "error detected while parsing sni expression : "
6618 " fetch method '%s' extracts information from '%s', none of which is available here.\n",
Cyril Bonté23d19d62016-03-07 22:13:22 +01006619 args[idx-1], sample_src_names(expr->fetch->use));
Willy Tarreau732eac42015-07-09 11:40:25 +02006620 return ERR_ALERT | ERR_FATAL;
6621 }
6622
6623 px->http_needed |= !!(expr->fetch->use & SMP_USE_HTTP_ANY);
6624 newsrv->ssl_ctx.sni = expr;
6625 return 0;
6626#endif
6627}
6628
Willy Tarreau92faadf2012-10-10 23:04:25 +02006629/* parse the "ssl" server keyword */
6630static int srv_parse_ssl(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
6631{
6632 newsrv->use_ssl = 1;
Willy Tarreauef934602016-12-22 23:12:01 +01006633 if (global_ssl.connect_default_ciphers && !newsrv->ssl_ctx.ciphers)
6634 newsrv->ssl_ctx.ciphers = strdup(global_ssl.connect_default_ciphers);
Willy Tarreau92faadf2012-10-10 23:04:25 +02006635 return 0;
6636}
6637
Emeric Brunef42d922012-10-11 16:11:36 +02006638/* parse the "verify" server keyword */
6639static int srv_parse_verify(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
6640{
6641 if (!*args[*cur_arg + 1]) {
6642 if (err)
6643 memprintf(err, "'%s' : missing verify method", args[*cur_arg]);
6644 return ERR_ALERT | ERR_FATAL;
6645 }
6646
6647 if (strcmp(args[*cur_arg + 1], "none") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01006648 newsrv->ssl_ctx.verify = SSL_SOCK_VERIFY_NONE;
Emeric Brunef42d922012-10-11 16:11:36 +02006649 else if (strcmp(args[*cur_arg + 1], "required") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01006650 newsrv->ssl_ctx.verify = SSL_SOCK_VERIFY_REQUIRED;
Emeric Brunef42d922012-10-11 16:11:36 +02006651 else {
6652 if (err)
6653 memprintf(err, "'%s' : unknown verify method '%s', only 'none' and 'required' are supported\n",
6654 args[*cur_arg], args[*cur_arg + 1]);
6655 return ERR_ALERT | ERR_FATAL;
6656 }
6657
Evan Broderbe554312013-06-27 00:05:25 -07006658 return 0;
6659}
6660
6661/* parse the "verifyhost" server keyword */
6662static int srv_parse_verifyhost(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
6663{
6664 if (!*args[*cur_arg + 1]) {
6665 if (err)
6666 memprintf(err, "'%s' : missing hostname to verify against", args[*cur_arg]);
6667 return ERR_ALERT | ERR_FATAL;
6668 }
6669
6670 newsrv->ssl_ctx.verify_host = strdup(args[*cur_arg + 1]);
6671
Emeric Brunef42d922012-10-11 16:11:36 +02006672 return 0;
6673}
6674
Emeric Brun2c86cbf2014-10-30 15:56:50 +01006675/* parse the "ssl-default-bind-options" keyword in global section */
6676static int ssl_parse_default_bind_options(char **args, int section_type, struct proxy *curpx,
6677 struct proxy *defpx, const char *file, int line,
6678 char **err) {
6679 int i = 1;
6680
6681 if (*(args[i]) == 0) {
6682 memprintf(err, "global statement '%s' expects an option as an argument.", args[0]);
6683 return -1;
6684 }
6685 while (*(args[i])) {
6686 if (!strcmp(args[i], "no-sslv3"))
Willy Tarreauef934602016-12-22 23:12:01 +01006687 global_ssl.listen_default_ssloptions |= BC_SSL_O_NO_SSLV3;
Emeric Brun2c86cbf2014-10-30 15:56:50 +01006688 else if (!strcmp(args[i], "no-tlsv10"))
Willy Tarreauef934602016-12-22 23:12:01 +01006689 global_ssl.listen_default_ssloptions |= BC_SSL_O_NO_TLSV10;
Emeric Brun2c86cbf2014-10-30 15:56:50 +01006690 else if (!strcmp(args[i], "no-tlsv11"))
Willy Tarreauef934602016-12-22 23:12:01 +01006691 global_ssl.listen_default_ssloptions |= BC_SSL_O_NO_TLSV11;
Emeric Brun2c86cbf2014-10-30 15:56:50 +01006692 else if (!strcmp(args[i], "no-tlsv12"))
Willy Tarreauef934602016-12-22 23:12:01 +01006693 global_ssl.listen_default_ssloptions |= BC_SSL_O_NO_TLSV12;
Emeric Brun2c86cbf2014-10-30 15:56:50 +01006694 else if (!strcmp(args[i], "force-sslv3"))
Willy Tarreauef934602016-12-22 23:12:01 +01006695 global_ssl.listen_default_ssloptions |= BC_SSL_O_USE_SSLV3;
Emeric Brun2c86cbf2014-10-30 15:56:50 +01006696 else if (!strcmp(args[i], "force-tlsv10"))
Willy Tarreauef934602016-12-22 23:12:01 +01006697 global_ssl.listen_default_ssloptions |= BC_SSL_O_USE_TLSV10;
Emeric Brun2c86cbf2014-10-30 15:56:50 +01006698 else if (!strcmp(args[i], "force-tlsv11")) {
6699#if SSL_OP_NO_TLSv1_1
Willy Tarreauef934602016-12-22 23:12:01 +01006700 global_ssl.listen_default_ssloptions |= BC_SSL_O_USE_TLSV11;
Emeric Brun2c86cbf2014-10-30 15:56:50 +01006701#else
6702 memprintf(err, "'%s' '%s': library does not support protocol TLSv1.1", args[0], args[i]);
6703 return -1;
6704#endif
6705 }
6706 else if (!strcmp(args[i], "force-tlsv12")) {
6707#if SSL_OP_NO_TLSv1_2
Willy Tarreauef934602016-12-22 23:12:01 +01006708 global_ssl.listen_default_ssloptions |= BC_SSL_O_USE_TLSV12;
Emeric Brun2c86cbf2014-10-30 15:56:50 +01006709#else
6710 memprintf(err, "'%s' '%s': library does not support protocol TLSv1.2", args[0], args[i]);
6711 return -1;
6712#endif
6713 }
6714 else if (!strcmp(args[i], "no-tls-tickets"))
Willy Tarreauef934602016-12-22 23:12:01 +01006715 global_ssl.listen_default_ssloptions |= BC_SSL_O_NO_TLS_TICKETS;
Emeric Brun2c86cbf2014-10-30 15:56:50 +01006716 else {
6717 memprintf(err, "unknown option '%s' on global statement '%s'.", args[i], args[0]);
6718 return -1;
6719 }
6720 i++;
6721 }
6722 return 0;
6723}
6724
6725/* parse the "ssl-default-server-options" keyword in global section */
6726static int ssl_parse_default_server_options(char **args, int section_type, struct proxy *curpx,
6727 struct proxy *defpx, const char *file, int line,
6728 char **err) {
6729 int i = 1;
6730
6731 if (*(args[i]) == 0) {
6732 memprintf(err, "global statement '%s' expects an option as an argument.", args[0]);
6733 return -1;
6734 }
6735 while (*(args[i])) {
6736 if (!strcmp(args[i], "no-sslv3"))
Willy Tarreauef934602016-12-22 23:12:01 +01006737 global_ssl.connect_default_ssloptions |= SRV_SSL_O_NO_SSLV3;
Emeric Brun2c86cbf2014-10-30 15:56:50 +01006738 else if (!strcmp(args[i], "no-tlsv10"))
Willy Tarreauef934602016-12-22 23:12:01 +01006739 global_ssl.connect_default_ssloptions |= SRV_SSL_O_NO_TLSV10;
Emeric Brun2c86cbf2014-10-30 15:56:50 +01006740 else if (!strcmp(args[i], "no-tlsv11"))
Willy Tarreauef934602016-12-22 23:12:01 +01006741 global_ssl.connect_default_ssloptions |= SRV_SSL_O_NO_TLSV11;
Emeric Brun2c86cbf2014-10-30 15:56:50 +01006742 else if (!strcmp(args[i], "no-tlsv12"))
Willy Tarreauef934602016-12-22 23:12:01 +01006743 global_ssl.connect_default_ssloptions |= SRV_SSL_O_NO_TLSV12;
Emeric Brun2c86cbf2014-10-30 15:56:50 +01006744 else if (!strcmp(args[i], "force-sslv3"))
Willy Tarreauef934602016-12-22 23:12:01 +01006745 global_ssl.connect_default_ssloptions |= SRV_SSL_O_USE_SSLV3;
Emeric Brun2c86cbf2014-10-30 15:56:50 +01006746 else if (!strcmp(args[i], "force-tlsv10"))
Willy Tarreauef934602016-12-22 23:12:01 +01006747 global_ssl.connect_default_ssloptions |= SRV_SSL_O_USE_TLSV10;
Emeric Brun2c86cbf2014-10-30 15:56:50 +01006748 else if (!strcmp(args[i], "force-tlsv11")) {
6749#if SSL_OP_NO_TLSv1_1
Willy Tarreauef934602016-12-22 23:12:01 +01006750 global_ssl.connect_default_ssloptions |= SRV_SSL_O_USE_TLSV11;
Emeric Brun2c86cbf2014-10-30 15:56:50 +01006751#else
6752 memprintf(err, "'%s' '%s': library does not support protocol TLSv1.1", args[0], args[i]);
6753 return -1;
6754#endif
6755 }
6756 else if (!strcmp(args[i], "force-tlsv12")) {
6757#if SSL_OP_NO_TLSv1_2
Willy Tarreauef934602016-12-22 23:12:01 +01006758 global_ssl.connect_default_ssloptions |= SRV_SSL_O_USE_TLSV12;
Emeric Brun2c86cbf2014-10-30 15:56:50 +01006759#else
6760 memprintf(err, "'%s' '%s': library does not support protocol TLSv1.2", args[0], args[i]);
6761 return -1;
6762#endif
6763 }
6764 else if (!strcmp(args[i], "no-tls-tickets"))
Willy Tarreauef934602016-12-22 23:12:01 +01006765 global_ssl.connect_default_ssloptions |= SRV_SSL_O_NO_TLS_TICKETS;
Emeric Brun2c86cbf2014-10-30 15:56:50 +01006766 else {
6767 memprintf(err, "unknown option '%s' on global statement '%s'.", args[i], args[0]);
6768 return -1;
6769 }
6770 i++;
6771 }
6772 return 0;
6773}
6774
Willy Tarreau8c3b0fd2016-12-21 22:44:46 +01006775/* parse the "ca-base" / "crt-base" keywords in global section.
6776 * Returns <0 on alert, >0 on warning, 0 on success.
6777 */
6778static int ssl_parse_global_ca_crt_base(char **args, int section_type, struct proxy *curpx,
6779 struct proxy *defpx, const char *file, int line,
6780 char **err)
6781{
6782 char **target;
6783
Willy Tarreauef934602016-12-22 23:12:01 +01006784 target = (args[0][1] == 'a') ? &global_ssl.ca_base : &global_ssl.crt_base;
Willy Tarreau8c3b0fd2016-12-21 22:44:46 +01006785
6786 if (too_many_args(1, args, err, NULL))
6787 return -1;
6788
6789 if (*target) {
6790 memprintf(err, "'%s' already specified.", args[0]);
6791 return -1;
6792 }
6793
6794 if (*(args[1]) == 0) {
6795 memprintf(err, "global statement '%s' expects a directory path as an argument.", args[0]);
6796 return -1;
6797 }
6798 *target = strdup(args[1]);
6799 return 0;
6800}
6801
Willy Tarreauf22e9682016-12-21 23:23:19 +01006802/* parse the "ssl-default-bind-ciphers" / "ssl-default-server-ciphers" keywords
6803 * in global section. Returns <0 on alert, >0 on warning, 0 on success.
6804 */
6805static int ssl_parse_global_ciphers(char **args, int section_type, struct proxy *curpx,
6806 struct proxy *defpx, const char *file, int line,
6807 char **err)
6808{
6809 char **target;
6810
Willy Tarreauef934602016-12-22 23:12:01 +01006811 target = (args[0][12] == 'b') ? &global_ssl.listen_default_ciphers : &global_ssl.connect_default_ciphers;
Willy Tarreauf22e9682016-12-21 23:23:19 +01006812
6813 if (too_many_args(1, args, err, NULL))
6814 return -1;
6815
6816 if (*(args[1]) == 0) {
6817 memprintf(err, "global statement '%s' expects a cipher suite as an argument.", args[0]);
6818 return -1;
6819 }
6820
6821 free(*target);
6822 *target = strdup(args[1]);
6823 return 0;
6824}
6825
Willy Tarreau9ceda382016-12-21 23:13:03 +01006826/* parse various global tune.ssl settings consisting in positive integers.
6827 * Returns <0 on alert, >0 on warning, 0 on success.
6828 */
6829static int ssl_parse_global_int(char **args, int section_type, struct proxy *curpx,
6830 struct proxy *defpx, const char *file, int line,
6831 char **err)
6832{
6833 int *target;
6834
6835 if (strcmp(args[0], "tune.ssl.cachesize") == 0)
6836 target = &global.tune.sslcachesize;
6837 else if (strcmp(args[0], "tune.ssl.maxrecord") == 0)
Willy Tarreauef934602016-12-22 23:12:01 +01006838 target = (int *)&global_ssl.max_record;
Willy Tarreau9ceda382016-12-21 23:13:03 +01006839 else if (strcmp(args[0], "tune.ssl.ssl-ctx-cache-size") == 0)
Willy Tarreauef934602016-12-22 23:12:01 +01006840 target = &global_ssl.ctx_cache;
Willy Tarreau0bea58d2016-12-21 23:17:25 +01006841 else if (strcmp(args[0], "maxsslconn") == 0)
6842 target = &global.maxsslconn;
Thierry FOURNIER5bf77322017-02-25 12:45:22 +01006843 else if (strcmp(args[0], "tune.ssl.capture-cipherlist-size") == 0)
6844 target = &global_ssl.capture_cipherlist;
Willy Tarreau9ceda382016-12-21 23:13:03 +01006845 else {
6846 memprintf(err, "'%s' keyword not unhandled (please report this bug).", args[0]);
6847 return -1;
6848 }
6849
6850 if (too_many_args(1, args, err, NULL))
6851 return -1;
6852
6853 if (*(args[1]) == 0) {
6854 memprintf(err, "'%s' expects an integer argument.", args[0]);
6855 return -1;
6856 }
6857
6858 *target = atoi(args[1]);
6859 if (*target < 0) {
6860 memprintf(err, "'%s' expects a positive numeric value.", args[0]);
6861 return -1;
6862 }
6863 return 0;
Thierry FOURNIER5bf77322017-02-25 12:45:22 +01006864}
6865
6866static int ssl_parse_global_capture_cipherlist(char **args, int section_type, struct proxy *curpx,
6867 struct proxy *defpx, const char *file, int line,
6868 char **err)
6869{
Thierry FOURNIER5bf77322017-02-25 12:45:22 +01006870 int ret;
6871
6872 ret = ssl_parse_global_int(args, section_type, curpx, defpx, file, line, err);
6873 if (ret != 0)
6874 return ret;
6875
6876 if (pool2_ssl_capture) {
6877 memprintf(err, "'%s' is already configured.", args[0]);
6878 return -1;
6879 }
6880
6881 pool2_ssl_capture = create_pool("ssl-capture", sizeof(struct ssl_capture) + global_ssl.capture_cipherlist, MEM_F_SHARED);
6882 if (!pool2_ssl_capture) {
6883 memprintf(err, "Out of memory error.");
6884 return -1;
6885 }
6886 return 0;
Willy Tarreau9ceda382016-12-21 23:13:03 +01006887}
6888
6889/* parse "ssl.force-private-cache".
6890 * Returns <0 on alert, >0 on warning, 0 on success.
6891 */
6892static int ssl_parse_global_private_cache(char **args, int section_type, struct proxy *curpx,
6893 struct proxy *defpx, const char *file, int line,
6894 char **err)
6895{
6896 if (too_many_args(0, args, err, NULL))
6897 return -1;
6898
Willy Tarreauef934602016-12-22 23:12:01 +01006899 global_ssl.private_cache = 1;
Willy Tarreau9ceda382016-12-21 23:13:03 +01006900 return 0;
6901}
6902
6903/* parse "ssl.lifetime".
6904 * Returns <0 on alert, >0 on warning, 0 on success.
6905 */
6906static int ssl_parse_global_lifetime(char **args, int section_type, struct proxy *curpx,
6907 struct proxy *defpx, const char *file, int line,
6908 char **err)
6909{
6910 const char *res;
6911
6912 if (too_many_args(1, args, err, NULL))
6913 return -1;
6914
6915 if (*(args[1]) == 0) {
6916 memprintf(err, "'%s' expects ssl sessions <lifetime> in seconds as argument.", args[0]);
6917 return -1;
6918 }
6919
Willy Tarreauef934602016-12-22 23:12:01 +01006920 res = parse_time_err(args[1], &global_ssl.life_time, TIME_UNIT_S);
Willy Tarreau9ceda382016-12-21 23:13:03 +01006921 if (res) {
6922 memprintf(err, "unexpected character '%c' in argument to <%s>.", *res, args[0]);
6923 return -1;
6924 }
6925 return 0;
6926}
6927
6928#ifndef OPENSSL_NO_DH
Willy Tarreau14e36a12016-12-21 23:28:13 +01006929/* parse "ssl-dh-param-file".
6930 * Returns <0 on alert, >0 on warning, 0 on success.
6931 */
6932static int ssl_parse_global_dh_param_file(char **args, int section_type, struct proxy *curpx,
6933 struct proxy *defpx, const char *file, int line,
6934 char **err)
6935{
6936 if (too_many_args(1, args, err, NULL))
6937 return -1;
6938
6939 if (*(args[1]) == 0) {
6940 memprintf(err, "'%s' expects a file path as an argument.", args[0]);
6941 return -1;
6942 }
6943
6944 if (ssl_sock_load_global_dh_param_from_file(args[1])) {
6945 memprintf(err, "'%s': unable to load DH parameters from file <%s>.", args[0], args[1]);
6946 return -1;
6947 }
6948 return 0;
6949}
6950
Willy Tarreau9ceda382016-12-21 23:13:03 +01006951/* parse "ssl.default-dh-param".
6952 * Returns <0 on alert, >0 on warning, 0 on success.
6953 */
6954static int ssl_parse_global_default_dh(char **args, int section_type, struct proxy *curpx,
6955 struct proxy *defpx, const char *file, int line,
6956 char **err)
6957{
6958 if (too_many_args(1, args, err, NULL))
6959 return -1;
6960
6961 if (*(args[1]) == 0) {
6962 memprintf(err, "'%s' expects an integer argument.", args[0]);
6963 return -1;
6964 }
6965
Willy Tarreauef934602016-12-22 23:12:01 +01006966 global_ssl.default_dh_param = atoi(args[1]);
6967 if (global_ssl.default_dh_param < 1024) {
Willy Tarreau9ceda382016-12-21 23:13:03 +01006968 memprintf(err, "'%s' expects a value >= 1024.", args[0]);
6969 return -1;
6970 }
6971 return 0;
6972}
6973#endif
6974
6975
William Lallemand32af2032016-10-29 18:09:35 +02006976/* This function is used with TLS ticket keys management. It permits to browse
6977 * each reference. The variable <getnext> must contain the current node,
6978 * <end> point to the root node.
6979 */
6980#if (defined SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB && TLS_TICKETS_NO > 0)
6981static inline
6982struct tls_keys_ref *tlskeys_list_get_next(struct tls_keys_ref *getnext, struct list *end)
6983{
6984 struct tls_keys_ref *ref = getnext;
6985
6986 while (1) {
6987
6988 /* Get next list entry. */
6989 ref = LIST_NEXT(&ref->list, struct tls_keys_ref *, list);
6990
6991 /* If the entry is the last of the list, return NULL. */
6992 if (&ref->list == end)
6993 return NULL;
6994
6995 return ref;
6996 }
6997}
6998
6999static inline
7000struct tls_keys_ref *tlskeys_ref_lookup_ref(const char *reference)
7001{
7002 int id;
7003 char *error;
7004
7005 /* If the reference starts by a '#', this is numeric id. */
7006 if (reference[0] == '#') {
7007 /* Try to convert the numeric id. If the conversion fails, the lookup fails. */
7008 id = strtol(reference + 1, &error, 10);
7009 if (*error != '\0')
7010 return NULL;
7011
7012 /* Perform the unique id lookup. */
7013 return tlskeys_ref_lookupid(id);
7014 }
7015
7016 /* Perform the string lookup. */
7017 return tlskeys_ref_lookup(reference);
7018}
7019#endif
7020
7021
7022#if (defined SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB && TLS_TICKETS_NO > 0)
7023
7024static int cli_io_handler_tlskeys_files(struct appctx *appctx);
7025
7026static inline int cli_io_handler_tlskeys_entries(struct appctx *appctx) {
7027 return cli_io_handler_tlskeys_files(appctx);
7028}
7029
Willy Tarreauf5f26e82016-12-16 18:47:27 +01007030/* dumps all tls keys. Relies on cli.i0 (non-null = only list file names), cli.i1
7031 * (next index to be dumped), and cli.p0 (next key reference).
7032 */
William Lallemand32af2032016-10-29 18:09:35 +02007033static int cli_io_handler_tlskeys_files(struct appctx *appctx) {
7034
7035 struct stream_interface *si = appctx->owner;
7036
7037 switch (appctx->st2) {
7038 case STAT_ST_INIT:
7039 /* Display the column headers. If the message cannot be sent,
7040 * quit the fucntion with returning 0. The function is called
7041 * later and restart at the state "STAT_ST_INIT".
7042 */
7043 chunk_reset(&trash);
7044
7045 if (appctx->io_handler == cli_io_handler_tlskeys_entries)
7046 chunk_appendf(&trash, "# id secret\n");
7047 else
7048 chunk_appendf(&trash, "# id (file)\n");
7049
7050 if (bi_putchk(si_ic(si), &trash) == -1) {
7051 si_applet_cant_put(si);
7052 return 0;
7053 }
7054
William Lallemand32af2032016-10-29 18:09:35 +02007055 /* Now, we start the browsing of the references lists.
7056 * Note that the following call to LIST_ELEM return bad pointer. The only
7057 * available field of this pointer is <list>. It is used with the function
7058 * tlskeys_list_get_next() for retruning the first available entry
7059 */
Willy Tarreauf5f26e82016-12-16 18:47:27 +01007060 if (appctx->ctx.cli.p0 == NULL) {
7061 appctx->ctx.cli.p0 = LIST_ELEM(&tlskeys_reference, struct tls_keys_ref *, list);
7062 appctx->ctx.cli.p0 = tlskeys_list_get_next(appctx->ctx.cli.p0, &tlskeys_reference);
William Lallemand32af2032016-10-29 18:09:35 +02007063 }
7064
7065 appctx->st2 = STAT_ST_LIST;
7066 /* fall through */
7067
7068 case STAT_ST_LIST:
Willy Tarreauf5f26e82016-12-16 18:47:27 +01007069 while (appctx->ctx.cli.p0) {
7070 struct tls_keys_ref *ref = appctx->ctx.cli.p0;
7071 int head = ref->tls_ticket_enc_index;
William Lallemand32af2032016-10-29 18:09:35 +02007072
7073 chunk_reset(&trash);
Willy Tarreauf5f26e82016-12-16 18:47:27 +01007074 if (appctx->io_handler == cli_io_handler_tlskeys_entries && appctx->ctx.cli.i1 == 0)
William Lallemand32af2032016-10-29 18:09:35 +02007075 chunk_appendf(&trash, "# ");
Willy Tarreauf5f26e82016-12-16 18:47:27 +01007076
7077 if (appctx->ctx.cli.i1 == 0)
7078 chunk_appendf(&trash, "%d (%s)\n", ref->unique_id, ref->filename);
7079
William Lallemand32af2032016-10-29 18:09:35 +02007080 if (appctx->io_handler == cli_io_handler_tlskeys_entries) {
Willy Tarreauf5f26e82016-12-16 18:47:27 +01007081 while (appctx->ctx.cli.i1 < TLS_TICKETS_NO) {
William Lallemand32af2032016-10-29 18:09:35 +02007082 struct chunk *t2 = get_trash_chunk();
7083
7084 chunk_reset(t2);
7085 /* should never fail here because we dump only a key in the t2 buffer */
Willy Tarreauf5f26e82016-12-16 18:47:27 +01007086 t2->len = a2base64((char *)(ref->tlskeys + (head + 2 + appctx->ctx.cli.i1) % TLS_TICKETS_NO),
William Lallemand32af2032016-10-29 18:09:35 +02007087 sizeof(struct tls_sess_key), t2->str, t2->size);
Willy Tarreauf5f26e82016-12-16 18:47:27 +01007088 chunk_appendf(&trash, "%d.%d %s\n", ref->unique_id, appctx->ctx.cli.i1, t2->str);
William Lallemand32af2032016-10-29 18:09:35 +02007089
7090 if (bi_putchk(si_ic(si), &trash) == -1) {
7091 /* let's try again later from this stream. We add ourselves into
7092 * this stream's users so that it can remove us upon termination.
7093 */
7094 si_applet_cant_put(si);
7095 return 0;
7096 }
Willy Tarreauf5f26e82016-12-16 18:47:27 +01007097 appctx->ctx.cli.i1++;
William Lallemand32af2032016-10-29 18:09:35 +02007098 }
Willy Tarreauf5f26e82016-12-16 18:47:27 +01007099 appctx->ctx.cli.i1 = 0;
William Lallemand32af2032016-10-29 18:09:35 +02007100 }
7101 if (bi_putchk(si_ic(si), &trash) == -1) {
7102 /* let's try again later from this stream. We add ourselves into
7103 * this stream's users so that it can remove us upon termination.
7104 */
7105 si_applet_cant_put(si);
7106 return 0;
7107 }
7108
Willy Tarreauf5f26e82016-12-16 18:47:27 +01007109 if (appctx->ctx.cli.i0 == 0) /* don't display everything if not necessary */
William Lallemand32af2032016-10-29 18:09:35 +02007110 break;
7111
7112 /* get next list entry and check the end of the list */
Willy Tarreauf5f26e82016-12-16 18:47:27 +01007113 appctx->ctx.cli.p0 = tlskeys_list_get_next(appctx->ctx.cli.p0, &tlskeys_reference);
William Lallemand32af2032016-10-29 18:09:35 +02007114 }
7115
7116 appctx->st2 = STAT_ST_FIN;
7117 /* fall through */
7118
7119 default:
7120 appctx->st2 = STAT_ST_FIN;
7121 return 1;
7122 }
7123 return 0;
7124}
7125
Willy Tarreauf5f26e82016-12-16 18:47:27 +01007126/* sets cli.i0 to non-zero if only file lists should be dumped */
William Lallemand32af2032016-10-29 18:09:35 +02007127static int cli_parse_show_tlskeys(char **args, struct appctx *appctx, void *private)
7128{
William Lallemand32af2032016-10-29 18:09:35 +02007129 /* no parameter, shows only file list */
7130 if (!*args[2]) {
Willy Tarreauf5f26e82016-12-16 18:47:27 +01007131 appctx->ctx.cli.i0 = 1;
William Lallemand32af2032016-10-29 18:09:35 +02007132 appctx->io_handler = cli_io_handler_tlskeys_files;
Willy Tarreau3067bfa2016-12-05 14:50:15 +01007133 return 0;
William Lallemand32af2032016-10-29 18:09:35 +02007134 }
7135
7136 if (args[2][0] == '*') {
7137 /* list every TLS ticket keys */
Willy Tarreauf5f26e82016-12-16 18:47:27 +01007138 appctx->ctx.cli.i0 = 1;
William Lallemand32af2032016-10-29 18:09:35 +02007139 } else {
Willy Tarreauf5f26e82016-12-16 18:47:27 +01007140 appctx->ctx.cli.p0 = tlskeys_ref_lookup_ref(args[2]);
7141 if (!appctx->ctx.cli.p0) {
William Lallemand32af2032016-10-29 18:09:35 +02007142 appctx->ctx.cli.msg = "'show tls-keys' unable to locate referenced filename\n";
Willy Tarreau3b6e5472016-11-24 15:53:53 +01007143 appctx->st0 = CLI_ST_PRINT;
William Lallemand32af2032016-10-29 18:09:35 +02007144 return 1;
7145 }
7146 }
William Lallemand32af2032016-10-29 18:09:35 +02007147 appctx->io_handler = cli_io_handler_tlskeys_entries;
Willy Tarreau3067bfa2016-12-05 14:50:15 +01007148 return 0;
William Lallemand32af2032016-10-29 18:09:35 +02007149}
7150
William Lallemand32af2032016-10-29 18:09:35 +02007151static int cli_parse_set_tlskeys(char **args, struct appctx *appctx, void *private)
7152{
Willy Tarreauf5f26e82016-12-16 18:47:27 +01007153 struct tls_keys_ref *ref;
7154
William Lallemand32af2032016-10-29 18:09:35 +02007155 /* Expect two parameters: the filename and the new new TLS key in encoding */
7156 if (!*args[3] || !*args[4]) {
7157 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 +01007158 appctx->st0 = CLI_ST_PRINT;
William Lallemand32af2032016-10-29 18:09:35 +02007159 return 1;
7160 }
7161
Willy Tarreauf5f26e82016-12-16 18:47:27 +01007162 ref = tlskeys_ref_lookup_ref(args[3]);
7163 if (!ref) {
William Lallemand32af2032016-10-29 18:09:35 +02007164 appctx->ctx.cli.msg = "'set ssl tls-key' unable to locate referenced filename\n";
Willy Tarreau3b6e5472016-11-24 15:53:53 +01007165 appctx->st0 = CLI_ST_PRINT;
William Lallemand32af2032016-10-29 18:09:35 +02007166 return 1;
7167 }
7168
7169 trash.len = base64dec(args[4], strlen(args[4]), trash.str, trash.size);
7170 if (trash.len != sizeof(struct tls_sess_key)) {
7171 appctx->ctx.cli.msg = "'set ssl tls-key' received invalid base64 encoded TLS key.\n";
Willy Tarreau3b6e5472016-11-24 15:53:53 +01007172 appctx->st0 = CLI_ST_PRINT;
William Lallemand32af2032016-10-29 18:09:35 +02007173 return 1;
7174 }
7175
Willy Tarreauf5f26e82016-12-16 18:47:27 +01007176 memcpy(ref->tlskeys + ((ref->tls_ticket_enc_index + 2) % TLS_TICKETS_NO), trash.str, trash.len);
7177 ref->tls_ticket_enc_index = (ref->tls_ticket_enc_index + 1) % TLS_TICKETS_NO;
William Lallemand32af2032016-10-29 18:09:35 +02007178
7179 appctx->ctx.cli.msg = "TLS ticket key updated!";
Willy Tarreau3b6e5472016-11-24 15:53:53 +01007180 appctx->st0 = CLI_ST_PRINT;
William Lallemand32af2032016-10-29 18:09:35 +02007181 return 1;
7182
7183}
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +01007184#endif
William Lallemand32af2032016-10-29 18:09:35 +02007185
7186static int cli_parse_set_ocspresponse(char **args, struct appctx *appctx, void *private)
7187{
7188#if (defined SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB && !defined OPENSSL_NO_OCSP)
7189 char *err = NULL;
7190
7191 /* Expect one parameter: the new response in base64 encoding */
7192 if (!*args[3]) {
7193 appctx->ctx.cli.msg = "'set ssl ocsp-response' expects response in base64 encoding.\n";
Willy Tarreau3b6e5472016-11-24 15:53:53 +01007194 appctx->st0 = CLI_ST_PRINT;
William Lallemand32af2032016-10-29 18:09:35 +02007195 return 1;
7196 }
7197
7198 trash.len = base64dec(args[3], strlen(args[3]), trash.str, trash.size);
7199 if (trash.len < 0) {
7200 appctx->ctx.cli.msg = "'set ssl ocsp-response' received invalid base64 encoded response.\n";
Willy Tarreau3b6e5472016-11-24 15:53:53 +01007201 appctx->st0 = CLI_ST_PRINT;
William Lallemand32af2032016-10-29 18:09:35 +02007202 return 1;
7203 }
7204
7205 if (ssl_sock_update_ocsp_response(&trash, &err)) {
7206 if (err) {
7207 memprintf(&err, "%s.\n", err);
7208 appctx->ctx.cli.err = err;
Willy Tarreau3b6e5472016-11-24 15:53:53 +01007209 appctx->st0 = CLI_ST_PRINT_FREE;
William Lallemand32af2032016-10-29 18:09:35 +02007210 }
7211 return 1;
7212 }
7213 appctx->ctx.cli.msg = "OCSP Response updated!";
Willy Tarreau3b6e5472016-11-24 15:53:53 +01007214 appctx->st0 = CLI_ST_PRINT;
William Lallemand32af2032016-10-29 18:09:35 +02007215 return 1;
7216#else
7217 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 +01007218 appctx->st0 = CLI_ST_PRINT;
William Lallemand32af2032016-10-29 18:09:35 +02007219 return 1;
7220#endif
7221
7222}
7223
7224/* register cli keywords */
7225static struct cli_kw_list cli_kws = {{ },{
7226#if (defined SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB && TLS_TICKETS_NO > 0)
7227 { { "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 },
7228 { { "set", "ssl", "tls-keys", NULL }, NULL, cli_parse_set_tlskeys, NULL },
William Lallemand32af2032016-10-29 18:09:35 +02007229#endif
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +01007230 { { "set", "ssl", "ocsp-response", NULL }, NULL, cli_parse_set_ocspresponse, NULL },
William Lallemand32af2032016-10-29 18:09:35 +02007231 { { NULL }, NULL, NULL, NULL }
7232}};
7233
7234
Willy Tarreau7875d092012-09-10 08:20:03 +02007235/* Note: must not be declared <const> as its list will be overwritten.
7236 * Please take care of keeping this list alphabetically sorted.
7237 */
Willy Tarreaudc13c112013-06-21 23:16:39 +02007238static struct sample_fetch_kw_list sample_fetch_keywords = {ILH, {
Emeric Brun645ae792014-04-30 14:21:06 +02007239 { "ssl_bc", smp_fetch_ssl_fc, 0, NULL, SMP_T_BOOL, SMP_USE_L5SRV },
Thierry FOURNIER07ee64e2015-07-06 23:43:03 +02007240 { "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 +02007241 { "ssl_bc_cipher", smp_fetch_ssl_fc_cipher, 0, NULL, SMP_T_STR, SMP_USE_L5SRV },
7242 { "ssl_bc_protocol", smp_fetch_ssl_fc_protocol, 0, NULL, SMP_T_STR, SMP_USE_L5SRV },
Emeric Brunb73a9b02014-04-30 18:49:19 +02007243 { "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 +02007244 { "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 +02007245 { "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 +02007246 { "ssl_c_ca_err", smp_fetch_ssl_c_ca_err, 0, NULL, SMP_T_SINT, SMP_USE_L5CLI },
7247 { "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 +01007248 { "ssl_c_der", smp_fetch_ssl_x_der, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Thierry FOURNIER07ee64e2015-07-06 23:43:03 +02007249 { "ssl_c_err", smp_fetch_ssl_c_err, 0, NULL, SMP_T_SINT, SMP_USE_L5CLI },
Emeric Brunba841a12014-04-30 17:05:08 +02007250 { "ssl_c_i_dn", smp_fetch_ssl_x_i_dn, ARG2(0,STR,SINT), NULL, SMP_T_STR, SMP_USE_L5CLI },
7251 { "ssl_c_key_alg", smp_fetch_ssl_x_key_alg, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
7252 { "ssl_c_notafter", smp_fetch_ssl_x_notafter, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
7253 { "ssl_c_notbefore", smp_fetch_ssl_x_notbefore, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
7254 { "ssl_c_sig_alg", smp_fetch_ssl_x_sig_alg, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
7255 { "ssl_c_s_dn", smp_fetch_ssl_x_s_dn, ARG2(0,STR,SINT), NULL, SMP_T_STR, SMP_USE_L5CLI },
7256 { "ssl_c_serial", smp_fetch_ssl_x_serial, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
7257 { "ssl_c_sha1", smp_fetch_ssl_x_sha1, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Willy Tarreau80aca902013-01-07 15:42:20 +01007258 { "ssl_c_used", smp_fetch_ssl_c_used, 0, NULL, SMP_T_BOOL, SMP_USE_L5CLI },
Thierry FOURNIER07ee64e2015-07-06 23:43:03 +02007259 { "ssl_c_verify", smp_fetch_ssl_c_verify, 0, NULL, SMP_T_SINT, SMP_USE_L5CLI },
7260 { "ssl_c_version", smp_fetch_ssl_x_version, 0, NULL, SMP_T_SINT, SMP_USE_L5CLI },
Emeric Brun43e79582014-10-29 19:03:26 +01007261 { "ssl_f_der", smp_fetch_ssl_x_der, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Emeric Brunba841a12014-04-30 17:05:08 +02007262 { "ssl_f_i_dn", smp_fetch_ssl_x_i_dn, ARG2(0,STR,SINT), NULL, SMP_T_STR, SMP_USE_L5CLI },
7263 { "ssl_f_key_alg", smp_fetch_ssl_x_key_alg, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
7264 { "ssl_f_notafter", smp_fetch_ssl_x_notafter, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
7265 { "ssl_f_notbefore", smp_fetch_ssl_x_notbefore, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
7266 { "ssl_f_sig_alg", smp_fetch_ssl_x_sig_alg, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
7267 { "ssl_f_s_dn", smp_fetch_ssl_x_s_dn, ARG2(0,STR,SINT), NULL, SMP_T_STR, SMP_USE_L5CLI },
7268 { "ssl_f_serial", smp_fetch_ssl_x_serial, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Emeric Brun55f4fa82014-04-30 17:11:25 +02007269 { "ssl_f_sha1", smp_fetch_ssl_x_sha1, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Thierry FOURNIER07ee64e2015-07-06 23:43:03 +02007270 { "ssl_f_version", smp_fetch_ssl_x_version, 0, NULL, SMP_T_SINT, SMP_USE_L5CLI },
Willy Tarreau80aca902013-01-07 15:42:20 +01007271 { "ssl_fc", smp_fetch_ssl_fc, 0, NULL, SMP_T_BOOL, SMP_USE_L5CLI },
Thierry FOURNIER07ee64e2015-07-06 23:43:03 +02007272 { "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 +01007273 { "ssl_fc_cipher", smp_fetch_ssl_fc_cipher, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Willy Tarreau80aca902013-01-07 15:42:20 +01007274 { "ssl_fc_has_crt", smp_fetch_ssl_fc_has_crt, 0, NULL, SMP_T_BOOL, SMP_USE_L5CLI },
7275 { "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 +02007276 { "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 +02007277#ifdef OPENSSL_NPN_NEGOTIATED
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01007278 { "ssl_fc_npn", smp_fetch_ssl_fc_npn, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Willy Tarreaua33c6542012-10-15 13:19:06 +02007279#endif
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01007280#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01007281 { "ssl_fc_alpn", smp_fetch_ssl_fc_alpn, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Willy Tarreauab861d32013-04-02 02:30:41 +02007282#endif
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01007283 { "ssl_fc_protocol", smp_fetch_ssl_fc_protocol, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Emeric Brunb73a9b02014-04-30 18:49:19 +02007284 { "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 +02007285 { "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 +01007286 { "ssl_fc_session_id", smp_fetch_ssl_fc_session_id, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
7287 { "ssl_fc_sni", smp_fetch_ssl_fc_sni, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Thierry FOURNIER5bf77322017-02-25 12:45:22 +01007288 { "ssl_fc_cipherlist_bin", smp_fetch_ssl_fc_cl_bin, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
7289 { "ssl_fc_cipherlist_hex", smp_fetch_ssl_fc_cl_hex, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
7290 { "ssl_fc_cipherlist_str", smp_fetch_ssl_fc_cl_str, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
7291 { "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 +02007292 { NULL, NULL, 0, 0, 0 },
7293}};
7294
7295/* Note: must not be declared <const> as its list will be overwritten.
7296 * Please take care of keeping this list alphabetically sorted.
7297 */
Willy Tarreaudc13c112013-06-21 23:16:39 +02007298static struct acl_kw_list acl_kws = {ILH, {
Thierry FOURNIERc5a4e982014-03-05 16:07:08 +01007299 { "ssl_fc_sni_end", "ssl_fc_sni", PAT_MATCH_END },
7300 { "ssl_fc_sni_reg", "ssl_fc_sni", PAT_MATCH_REG },
Willy Tarreau8ed669b2013-01-11 15:49:37 +01007301 { /* END */ },
Willy Tarreau7875d092012-09-10 08:20:03 +02007302}};
7303
Willy Tarreau79eeafa2012-09-14 07:53:05 +02007304/* Note: must not be declared <const> as its list will be overwritten.
7305 * Please take care of keeping this list alphabetically sorted, doing so helps
7306 * all code contributors.
7307 * Optional keywords are also declared with a NULL ->parse() function so that
7308 * the config parser can report an appropriate error when a known keyword was
7309 * not enabled.
7310 */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01007311static struct ssl_bind_kw ssl_bind_kws[] = {
7312 { "alpn", ssl_bind_parse_alpn, 1 }, /* set ALPN supported protocols */
7313 { "ca-file", ssl_bind_parse_ca_file, 1 }, /* set CAfile to process verify on client cert */
7314 { "ciphers", ssl_bind_parse_ciphers, 1 }, /* set SSL cipher suite */
7315 { "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 +01007316 { "curves", ssl_bind_parse_curves, 1 }, /* set SSL curve suite */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01007317 { "ecdhe", ssl_bind_parse_ecdhe, 1 }, /* defines named curve for elliptic curve Diffie-Hellman */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01007318 { "npn", ssl_bind_parse_npn, 1 }, /* set NPN supported protocols */
7319 { "verify", ssl_bind_parse_verify, 1 }, /* set SSL verify method */
7320 { NULL, NULL, 0 },
7321};
7322
Willy Tarreau51fb7652012-09-18 18:24:39 +02007323static struct bind_kw_list bind_kws = { "SSL", { }, {
Nenad Merdanovic05552d42015-02-27 19:56:49 +01007324 { "alpn", bind_parse_alpn, 1 }, /* set ALPN supported protocols */
7325 { "ca-file", bind_parse_ca_file, 1 }, /* set CAfile to process verify on client cert */
7326 { "ca-ignore-err", bind_parse_ignore_err, 1 }, /* set error IDs to ignore on verify depth > 0 */
Christopher Faulet31af49d2015-06-09 17:29:50 +02007327 { "ca-sign-file", bind_parse_ca_sign_file, 1 }, /* set CAFile used to generate and sign server certs */
7328 { "ca-sign-pass", bind_parse_ca_sign_pass, 1 }, /* set CAKey passphrase */
Nenad Merdanovic05552d42015-02-27 19:56:49 +01007329 { "ciphers", bind_parse_ciphers, 1 }, /* set SSL cipher suite */
7330 { "crl-file", bind_parse_crl_file, 1 }, /* set certificat revocation list file use on client cert verify */
7331 { "crt", bind_parse_crt, 1 }, /* load SSL certificates from this location */
7332 { "crt-ignore-err", bind_parse_ignore_err, 1 }, /* set error IDs to ingore on verify depth == 0 */
7333 { "crt-list", bind_parse_crt_list, 1 }, /* load a list of crt from this location */
Emmanuel Hocdete7f2b732017-01-09 16:15:54 +01007334 { "curves", bind_parse_curves, 1 }, /* set SSL curve suite */
Nenad Merdanovic05552d42015-02-27 19:56:49 +01007335 { "ecdhe", bind_parse_ecdhe, 1 }, /* defines named curve for elliptic curve Diffie-Hellman */
7336 { "force-sslv3", bind_parse_force_sslv3, 0 }, /* force SSLv3 */
7337 { "force-tlsv10", bind_parse_force_tlsv10, 0 }, /* force TLSv10 */
7338 { "force-tlsv11", bind_parse_force_tlsv11, 0 }, /* force TLSv11 */
7339 { "force-tlsv12", bind_parse_force_tlsv12, 0 }, /* force TLSv12 */
Christopher Faulet31af49d2015-06-09 17:29:50 +02007340 { "generate-certificates", bind_parse_generate_certs, 0 }, /* enable the server certificates generation */
Nenad Merdanovic05552d42015-02-27 19:56:49 +01007341 { "no-sslv3", bind_parse_no_sslv3, 0 }, /* disable SSLv3 */
7342 { "no-tlsv10", bind_parse_no_tlsv10, 0 }, /* disable TLSv10 */
7343 { "no-tlsv11", bind_parse_no_tlsv11, 0 }, /* disable TLSv11 */
7344 { "no-tlsv12", bind_parse_no_tlsv12, 0 }, /* disable TLSv12 */
7345 { "no-tls-tickets", bind_parse_no_tls_tickets, 0 }, /* disable session resumption tickets */
7346 { "ssl", bind_parse_ssl, 0 }, /* enable SSL processing */
7347 { "strict-sni", bind_parse_strict_sni, 0 }, /* refuse negotiation if sni doesn't match a certificate */
7348 { "tls-ticket-keys", bind_parse_tls_ticket_keys, 1 }, /* set file to load TLS ticket keys from */
7349 { "verify", bind_parse_verify, 1 }, /* set SSL verify method */
7350 { "npn", bind_parse_npn, 1 }, /* set NPN supported protocols */
Willy Tarreau79eeafa2012-09-14 07:53:05 +02007351 { NULL, NULL, 0 },
7352}};
Emeric Brun46591952012-05-18 15:47:34 +02007353
Willy Tarreau92faadf2012-10-10 23:04:25 +02007354/* Note: must not be declared <const> as its list will be overwritten.
7355 * Please take care of keeping this list alphabetically sorted, doing so helps
7356 * all code contributors.
7357 * Optional keywords are also declared with a NULL ->parse() function so that
7358 * the config parser can report an appropriate error when a known keyword was
7359 * not enabled.
7360 */
7361static struct srv_kw_list srv_kws = { "SSL", { }, {
Emeric Brunef42d922012-10-11 16:11:36 +02007362 { "ca-file", srv_parse_ca_file, 1, 0 }, /* set CAfile to process verify server cert */
Emeric Brunecc91fe2012-10-11 15:05:10 +02007363 { "check-ssl", srv_parse_check_ssl, 0, 0 }, /* enable SSL for health checks */
7364 { "ciphers", srv_parse_ciphers, 1, 0 }, /* select the cipher suite */
Emeric Brunef42d922012-10-11 16:11:36 +02007365 { "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 +02007366 { "crt", srv_parse_crt, 1, 0 }, /* set client certificate */
Emeric Brunecc91fe2012-10-11 15:05:10 +02007367 { "force-sslv3", srv_parse_force_sslv3, 0, 0 }, /* force SSLv3 */
7368 { "force-tlsv10", srv_parse_force_tlsv10, 0, 0 }, /* force TLSv10 */
7369 { "force-tlsv11", srv_parse_force_tlsv11, 0, 0 }, /* force TLSv11 */
7370 { "force-tlsv12", srv_parse_force_tlsv12, 0, 0 }, /* force TLSv12 */
Willy Tarreau2a3fb1c2015-02-05 16:47:07 +01007371 { "no-ssl-reuse", srv_parse_no_ssl_reuse, 0, 0 }, /* disable session reuse */
Emeric Brunecc91fe2012-10-11 15:05:10 +02007372 { "no-sslv3", srv_parse_no_sslv3, 0, 0 }, /* disable SSLv3 */
7373 { "no-tlsv10", srv_parse_no_tlsv10, 0, 0 }, /* disable TLSv10 */
7374 { "no-tlsv11", srv_parse_no_tlsv11, 0, 0 }, /* disable TLSv11 */
7375 { "no-tlsv12", srv_parse_no_tlsv12, 0, 0 }, /* disable TLSv12 */
Emeric Brunf9c5c472012-10-11 15:28:34 +02007376 { "no-tls-tickets", srv_parse_no_tls_tickets, 0, 0 }, /* disable session resumption tickets */
David Safb76832014-05-08 23:42:08 -04007377 { "send-proxy-v2-ssl", srv_parse_send_proxy_ssl, 0, 0 }, /* send PROXY protocol header v2 with SSL info */
7378 { "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 +02007379 { "sni", srv_parse_sni, 1, 0 }, /* send SNI extension */
Emeric Brunecc91fe2012-10-11 15:05:10 +02007380 { "ssl", srv_parse_ssl, 0, 0 }, /* enable SSL processing */
Emeric Brunef42d922012-10-11 16:11:36 +02007381 { "verify", srv_parse_verify, 1, 0 }, /* set SSL verify method */
Evan Broderbe554312013-06-27 00:05:25 -07007382 { "verifyhost", srv_parse_verifyhost, 1, 0 }, /* require that SSL cert verifies for hostname */
Willy Tarreau92faadf2012-10-10 23:04:25 +02007383 { NULL, NULL, 0, 0 },
7384}};
7385
Emeric Brun2c86cbf2014-10-30 15:56:50 +01007386static struct cfg_kw_list cfg_kws = {ILH, {
Willy Tarreau8c3b0fd2016-12-21 22:44:46 +01007387 { CFG_GLOBAL, "ca-base", ssl_parse_global_ca_crt_base },
7388 { CFG_GLOBAL, "crt-base", ssl_parse_global_ca_crt_base },
Willy Tarreau0bea58d2016-12-21 23:17:25 +01007389 { CFG_GLOBAL, "maxsslconn", ssl_parse_global_int },
Emeric Brun2c86cbf2014-10-30 15:56:50 +01007390 { CFG_GLOBAL, "ssl-default-bind-options", ssl_parse_default_bind_options },
7391 { CFG_GLOBAL, "ssl-default-server-options", ssl_parse_default_server_options },
Willy Tarreau14e36a12016-12-21 23:28:13 +01007392#ifndef OPENSSL_NO_DH
7393 { CFG_GLOBAL, "ssl-dh-param-file", ssl_parse_global_dh_param_file },
7394#endif
Willy Tarreau9ceda382016-12-21 23:13:03 +01007395 { CFG_GLOBAL, "tune.ssl.cachesize", ssl_parse_global_int },
7396#ifndef OPENSSL_NO_DH
7397 { CFG_GLOBAL, "tune.ssl.default-dh-param", ssl_parse_global_default_dh },
7398#endif
7399 { CFG_GLOBAL, "tune.ssl.force-private-cache", ssl_parse_global_private_cache },
7400 { CFG_GLOBAL, "tune.ssl.lifetime", ssl_parse_global_lifetime },
7401 { CFG_GLOBAL, "tune.ssl.maxrecord", ssl_parse_global_int },
7402 { CFG_GLOBAL, "tune.ssl.ssl-ctx-cache-size", ssl_parse_global_int },
Thierry FOURNIER5bf77322017-02-25 12:45:22 +01007403 { CFG_GLOBAL, "tune.ssl.capture-cipherlist-size", ssl_parse_global_capture_cipherlist },
Willy Tarreauf22e9682016-12-21 23:23:19 +01007404 { CFG_GLOBAL, "ssl-default-bind-ciphers", ssl_parse_global_ciphers },
7405 { CFG_GLOBAL, "ssl-default-server-ciphers", ssl_parse_global_ciphers },
Emeric Brun2c86cbf2014-10-30 15:56:50 +01007406 { 0, NULL, NULL },
7407}};
7408
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02007409/* transport-layer operations for SSL sockets */
Willy Tarreaud9f5cca2016-12-22 21:08:52 +01007410static struct xprt_ops ssl_sock = {
Emeric Brun46591952012-05-18 15:47:34 +02007411 .snd_buf = ssl_sock_from_buf,
7412 .rcv_buf = ssl_sock_to_buf,
7413 .rcv_pipe = NULL,
7414 .snd_pipe = NULL,
7415 .shutr = NULL,
7416 .shutw = ssl_sock_shutw,
7417 .close = ssl_sock_close,
7418 .init = ssl_sock_init,
Willy Tarreau55d37912016-12-21 23:38:39 +01007419 .prepare_bind_conf = ssl_sock_prepare_bind_conf,
Willy Tarreau795cdab2016-12-22 17:30:54 +01007420 .destroy_bind_conf = ssl_sock_destroy_bind_conf,
Willy Tarreau17d45382016-12-22 21:16:08 +01007421 .prepare_srv = ssl_sock_prepare_srv_ctx,
7422 .destroy_srv = ssl_sock_free_srv_ctx,
Willy Tarreau8e0bb0a2016-11-24 16:58:12 +01007423 .name = "SSL",
Emeric Brun46591952012-05-18 15:47:34 +02007424};
7425
Daniel Jakots54ffb912015-11-06 20:02:41 +01007426#if (OPENSSL_VERSION_NUMBER >= 0x1000200fL && !defined OPENSSL_NO_TLSEXT && !defined OPENSSL_IS_BORINGSSL && !defined LIBRESSL_VERSION_NUMBER)
Janusz Dziemidowicz2c701b52015-03-07 23:03:59 +01007427
7428static void ssl_sock_sctl_free_func(void *parent, void *ptr, CRYPTO_EX_DATA *ad, int idx, long argl, void *argp)
7429{
7430 if (ptr) {
7431 chunk_destroy(ptr);
7432 free(ptr);
7433 }
7434}
7435
7436#endif
Emmanuel Hocdetaaee7502017-03-07 18:34:58 +01007437static void ssl_sock_capture_free_func(void *parent, void *ptr, CRYPTO_EX_DATA *ad, int idx, long argl, void *argp)
7438{
7439 pool_free2(pool2_ssl_capture, ptr);
7440}
Janusz Dziemidowicz2c701b52015-03-07 23:03:59 +01007441
Emeric Brun46591952012-05-18 15:47:34 +02007442__attribute__((constructor))
Willy Tarreau92faadf2012-10-10 23:04:25 +02007443static void __ssl_sock_init(void)
7444{
Willy Tarreauc2c0b612016-12-21 19:23:20 +01007445 char *ptr;
7446
Emeric Brun46591952012-05-18 15:47:34 +02007447 STACK_OF(SSL_COMP)* cm;
7448
Willy Tarreauef934602016-12-22 23:12:01 +01007449 if (global_ssl.listen_default_ciphers)
7450 global_ssl.listen_default_ciphers = strdup(global_ssl.listen_default_ciphers);
7451 if (global_ssl.connect_default_ciphers)
7452 global_ssl.connect_default_ciphers = strdup(global_ssl.connect_default_ciphers);
Willy Tarreau610f04b2014-02-13 11:36:41 +01007453
Willy Tarreau13e14102016-12-22 20:25:26 +01007454 xprt_register(XPRT_SSL, &ssl_sock);
Emeric Brun46591952012-05-18 15:47:34 +02007455 SSL_library_init();
7456 cm = SSL_COMP_get_compression_methods();
7457 sk_SSL_COMP_zero(cm);
Daniel Jakots54ffb912015-11-06 20:02:41 +01007458#if (OPENSSL_VERSION_NUMBER >= 0x1000200fL && !defined OPENSSL_NO_TLSEXT && !defined OPENSSL_IS_BORINGSSL && !defined LIBRESSL_VERSION_NUMBER)
Janusz Dziemidowicz2c701b52015-03-07 23:03:59 +01007459 sctl_ex_index = SSL_CTX_get_ex_new_index(0, NULL, NULL, NULL, ssl_sock_sctl_free_func);
7460#endif
Emmanuel Hocdetaaee7502017-03-07 18:34:58 +01007461 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 +02007462 sample_register_fetches(&sample_fetch_keywords);
7463 acl_register_keywords(&acl_kws);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02007464 bind_register_keywords(&bind_kws);
Willy Tarreau92faadf2012-10-10 23:04:25 +02007465 srv_register_keywords(&srv_kws);
Emeric Brun2c86cbf2014-10-30 15:56:50 +01007466 cfg_register_keywords(&cfg_kws);
William Lallemand32af2032016-10-29 18:09:35 +02007467 cli_register_kw(&cli_kws);
Willy Tarreaud1c57502016-12-22 22:46:15 +01007468#if (defined SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB && TLS_TICKETS_NO > 0)
7469 hap_register_post_check(tlskeys_finalize_config);
7470#endif
Willy Tarreaud92aa5c2015-01-15 21:34:39 +01007471
Willy Tarreauc2c0b612016-12-21 19:23:20 +01007472 ptr = NULL;
7473 memprintf(&ptr, "Built with OpenSSL version : "
7474#ifdef OPENSSL_IS_BORINGSSL
7475 "BoringSSL\n");
7476#else /* OPENSSL_IS_BORINGSSL */
7477 OPENSSL_VERSION_TEXT
7478 "\nRunning on OpenSSL version : %s%s",
7479 SSLeay_version(SSLEAY_VERSION),
7480 ((OPENSSL_VERSION_NUMBER ^ SSLeay()) >> 8) ? " (VERSIONS DIFFER!)" : "");
7481#endif
7482 memprintf(&ptr, "%s\nOpenSSL library supports TLS extensions : "
7483#if OPENSSL_VERSION_NUMBER < 0x00907000L
7484 "no (library version too old)"
7485#elif defined(OPENSSL_NO_TLSEXT)
7486 "no (disabled via OPENSSL_NO_TLSEXT)"
7487#else
7488 "yes"
7489#endif
7490 "", ptr);
7491
7492 memprintf(&ptr, "%s\nOpenSSL library supports SNI : "
7493#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
7494 "yes"
7495#else
7496#ifdef OPENSSL_NO_TLSEXT
7497 "no (because of OPENSSL_NO_TLSEXT)"
7498#else
7499 "no (version might be too old, 0.9.8f min needed)"
7500#endif
7501#endif
7502 "", ptr);
7503
Willy Tarreauc2c0b612016-12-21 19:23:20 +01007504 hap_register_build_opts(ptr, 1);
7505
Willy Tarreaud92aa5c2015-01-15 21:34:39 +01007506 global.ssl_session_max_cost = SSL_SESSION_MAX_COST;
7507 global.ssl_handshake_max_cost = SSL_HANDSHAKE_MAX_COST;
Remi Gacogne4f902b82015-05-28 16:23:00 +02007508
7509#ifndef OPENSSL_NO_DH
7510 ssl_dh_ptr_index = SSL_CTX_get_ex_new_index(0, NULL, NULL, NULL, NULL);
7511#endif
Thierry FOURNIER / OZON.IO8b068c22016-10-10 11:59:50 +02007512
7513 /* Load SSL string for the verbose & debug mode. */
7514 ERR_load_SSL_strings();
Emeric Brun46591952012-05-18 15:47:34 +02007515}
7516
Remi Gacogned3a23c32015-05-28 16:39:47 +02007517__attribute__((destructor))
7518static void __ssl_sock_deinit(void)
7519{
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +01007520#if (defined SSL_CTRL_SET_TLSEXT_HOSTNAME && !defined SSL_NO_GENERATE_CERTIFICATES)
Christopher Faulet31af49d2015-06-09 17:29:50 +02007521 lru64_destroy(ssl_ctx_lru_tree);
Willy Tarreaua84c2672015-10-09 12:10:13 +02007522#endif
Christopher Faulet31af49d2015-06-09 17:29:50 +02007523
Remi Gacogned3a23c32015-05-28 16:39:47 +02007524#ifndef OPENSSL_NO_DH
7525 if (local_dh_1024) {
7526 DH_free(local_dh_1024);
7527 local_dh_1024 = NULL;
7528 }
7529
7530 if (local_dh_2048) {
7531 DH_free(local_dh_2048);
7532 local_dh_2048 = NULL;
7533 }
7534
7535 if (local_dh_4096) {
7536 DH_free(local_dh_4096);
7537 local_dh_4096 = NULL;
7538 }
7539
Remi Gacogne47783ef2015-05-29 15:53:22 +02007540 if (global_dh) {
7541 DH_free(global_dh);
7542 global_dh = NULL;
7543 }
Remi Gacogned3a23c32015-05-28 16:39:47 +02007544#endif
7545
7546 ERR_remove_state(0);
7547 ERR_free_strings();
7548
7549 EVP_cleanup();
7550
7551#if OPENSSL_VERSION_NUMBER >= 0x00907000L
7552 CRYPTO_cleanup_all_ex_data();
7553#endif
7554}
7555
7556
Emeric Brun46591952012-05-18 15:47:34 +02007557/*
7558 * Local variables:
7559 * c-indent-level: 8
7560 * c-basic-offset: 8
7561 * End:
7562 */