blob: 3924cbb8cc9d726e5366b2fbb6d2f8fa6e02e7d8 [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. */
149} global_ssl = {
150#ifdef LISTEN_DEFAULT_CIPHERS
151 .listen_default_ciphers = LISTEN_DEFAULT_CIPHERS,
152#endif
153#ifdef CONNECT_DEFAULT_CIPHERS
154 .connect_default_ciphers = CONNECT_DEFAULT_CIPHERS,
155#endif
156 .listen_default_ssloptions = BC_SSL_O_NONE,
157 .connect_default_ssloptions = SRV_SSL_O_NONE,
158
159#ifdef DEFAULT_SSL_MAX_RECORD
160 .max_record = DEFAULT_SSL_MAX_RECORD,
161#endif
162 .default_dh_param = SSL_DEFAULT_DH_PARAM,
163 .ctx_cache = DEFAULT_SSL_CTX_CACHE,
164};
165
166
Nenad Merdanovic200b0fa2015-05-09 08:46:01 +0200167#if (defined SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB && TLS_TICKETS_NO > 0)
168struct list tlskeys_reference = LIST_HEAD_INIT(tlskeys_reference);
169#endif
170
Remi Gacogne8de54152014-07-15 11:36:40 +0200171#ifndef OPENSSL_NO_DH
Remi Gacogne4f902b82015-05-28 16:23:00 +0200172static int ssl_dh_ptr_index = -1;
Remi Gacogne47783ef2015-05-29 15:53:22 +0200173static DH *global_dh = NULL;
Remi Gacogne8de54152014-07-15 11:36:40 +0200174static DH *local_dh_1024 = NULL;
175static DH *local_dh_2048 = NULL;
176static DH *local_dh_4096 = NULL;
Remi Gacogne8de54152014-07-15 11:36:40 +0200177#endif /* OPENSSL_NO_DH */
178
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +0100179#if (defined SSL_CTRL_SET_TLSEXT_HOSTNAME && !defined SSL_NO_GENERATE_CERTIFICATES)
Christopher Faulet31af49d2015-06-09 17:29:50 +0200180/* X509V3 Extensions that will be added on generated certificates */
181#define X509V3_EXT_SIZE 5
182static char *x509v3_ext_names[X509V3_EXT_SIZE] = {
183 "basicConstraints",
184 "nsComment",
185 "subjectKeyIdentifier",
186 "authorityKeyIdentifier",
187 "keyUsage",
188};
189static char *x509v3_ext_values[X509V3_EXT_SIZE] = {
190 "CA:FALSE",
191 "\"OpenSSL Generated Certificate\"",
192 "hash",
193 "keyid,issuer:always",
194 "nonRepudiation,digitalSignature,keyEncipherment"
195};
Christopher Faulet31af49d2015-06-09 17:29:50 +0200196/* LRU cache to store generated certificate */
197static struct lru64_head *ssl_ctx_lru_tree = NULL;
198static unsigned int ssl_ctx_lru_seed = 0;
Willy Tarreauc8ad3be2015-06-17 15:48:26 +0200199#endif // SSL_CTRL_SET_TLSEXT_HOSTNAME
200
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +0100201static struct ssl_bind_kw ssl_bind_kws[];
202
yanbzhube2774d2015-12-10 15:07:30 -0500203#if OPENSSL_VERSION_NUMBER >= 0x1000200fL
204/* The order here matters for picking a default context,
205 * keep the most common keytype at the bottom of the list
206 */
207const char *SSL_SOCK_KEYTYPE_NAMES[] = {
208 "dsa",
209 "ecdsa",
210 "rsa"
211};
212#define SSL_SOCK_NUM_KEYTYPES 3
Willy Tarreau30da7ad2015-12-14 11:28:33 +0100213#else
214#define SSL_SOCK_NUM_KEYTYPES 1
yanbzhube2774d2015-12-10 15:07:30 -0500215#endif
216
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +0100217/*
218 * This function gives the detail of the SSL error. It is used only
219 * if the debug mode and the verbose mode are activated. It dump all
220 * the SSL error until the stack was empty.
221 */
222static forceinline void ssl_sock_dump_errors(struct connection *conn)
223{
224 unsigned long ret;
225
226 if (unlikely(global.mode & MODE_DEBUG)) {
227 while(1) {
228 ret = ERR_get_error();
229 if (ret == 0)
230 return;
231 fprintf(stderr, "fd[%04x] OpenSSL error[0x%lx] %s: %s\n",
232 (unsigned short)conn->t.sock.fd, ret,
233 ERR_func_error_string(ret), ERR_reason_error_string(ret));
234 }
235 }
236}
237
Willy Tarreauc8ad3be2015-06-17 15:48:26 +0200238#if (defined SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB && !defined OPENSSL_NO_OCSP)
yanbzhube2774d2015-12-10 15:07:30 -0500239/*
240 * struct alignment works here such that the key.key is the same as key_data
241 * Do not change the placement of key_data
242 */
Willy Tarreauc8ad3be2015-06-17 15:48:26 +0200243struct certificate_ocsp {
244 struct ebmb_node key;
245 unsigned char key_data[OCSP_MAX_CERTID_ASN1_LENGTH];
246 struct chunk response;
247 long expire;
248};
Christopher Faulet31af49d2015-06-09 17:29:50 +0200249
yanbzhube2774d2015-12-10 15:07:30 -0500250struct ocsp_cbk_arg {
251 int is_single;
252 int single_kt;
253 union {
254 struct certificate_ocsp *s_ocsp;
255 /*
256 * m_ocsp will have multiple entries dependent on key type
257 * Entry 0 - DSA
258 * Entry 1 - ECDSA
259 * Entry 2 - RSA
260 */
261 struct certificate_ocsp *m_ocsp[SSL_SOCK_NUM_KEYTYPES];
262 };
263};
264
Emeric Brun4f3c87a2014-06-20 15:46:13 +0200265/*
266 * This function returns the number of seconds elapsed
267 * since the Epoch, 1970-01-01 00:00:00 +0000 (UTC) and the
268 * date presented un ASN1_GENERALIZEDTIME.
269 *
270 * In parsing error case, it returns -1.
271 */
272static long asn1_generalizedtime_to_epoch(ASN1_GENERALIZEDTIME *d)
273{
274 long epoch;
275 char *p, *end;
276 const unsigned short month_offset[12] = {
277 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334
278 };
279 int year, month;
280
281 if (!d || (d->type != V_ASN1_GENERALIZEDTIME)) return -1;
282
283 p = (char *)d->data;
284 end = p + d->length;
285
286 if (end - p < 4) return -1;
287 year = 1000 * (p[0] - '0') + 100 * (p[1] - '0') + 10 * (p[2] - '0') + p[3] - '0';
288 p += 4;
289 if (end - p < 2) return -1;
290 month = 10 * (p[0] - '0') + p[1] - '0';
291 if (month < 1 || month > 12) return -1;
292 /* Compute the number of seconds since 1 jan 1970 and the beginning of current month
293 We consider leap years and the current month (<marsh or not) */
294 epoch = ( ((year - 1970) * 365)
295 + ((year - (month < 3)) / 4 - (year - (month < 3)) / 100 + (year - (month < 3)) / 400)
296 - ((1970 - 1) / 4 - (1970 - 1) / 100 + (1970 - 1) / 400)
297 + month_offset[month-1]
298 ) * 24 * 60 * 60;
299 p += 2;
300 if (end - p < 2) return -1;
301 /* Add the number of seconds of completed days of current month */
302 epoch += (10 * (p[0] - '0') + p[1] - '0' - 1) * 24 * 60 * 60;
303 p += 2;
304 if (end - p < 2) return -1;
305 /* Add the completed hours of the current day */
306 epoch += (10 * (p[0] - '0') + p[1] - '0') * 60 * 60;
307 p += 2;
308 if (end - p < 2) return -1;
309 /* Add the completed minutes of the current hour */
310 epoch += (10 * (p[0] - '0') + p[1] - '0') * 60;
311 p += 2;
312 if (p == end) return -1;
313 /* Test if there is available seconds */
314 if (p[0] < '0' || p[0] > '9')
315 goto nosec;
316 if (end - p < 2) return -1;
317 /* Add the seconds of the current minute */
318 epoch += 10 * (p[0] - '0') + p[1] - '0';
319 p += 2;
320 if (p == end) return -1;
321 /* Ignore seconds float part if present */
322 if (p[0] == '.') {
323 do {
324 if (++p == end) return -1;
325 } while (p[0] >= '0' && p[0] <= '9');
326 }
327
328nosec:
329 if (p[0] == 'Z') {
330 if (end - p != 1) return -1;
331 return epoch;
332 }
333 else if (p[0] == '+') {
334 if (end - p != 5) return -1;
335 /* Apply timezone offset */
336 return epoch - ((10 * (p[1] - '0') + p[2] - '0') * 60 + (10 * (p[3] - '0') + p[4] - '0')) * 60;
337 }
338 else if (p[0] == '-') {
339 if (end - p != 5) return -1;
340 /* Apply timezone offset */
341 return epoch + ((10 * (p[1] - '0') + p[2] - '0') * 60 + (10 * (p[3] - '0') + p[4] - '0')) * 60;
342 }
343
344 return -1;
345}
346
Emeric Brun1d3865b2014-06-20 15:37:32 +0200347static struct eb_root cert_ocsp_tree = EB_ROOT_UNIQUE;
Emeric Brun4147b2e2014-06-16 18:36:30 +0200348
349/* This function starts to check if the OCSP response (in DER format) contained
350 * in chunk 'ocsp_response' is valid (else exits on error).
351 * If 'cid' is not NULL, it will be compared to the OCSP certificate ID
352 * contained in the OCSP Response and exits on error if no match.
353 * If it's a valid OCSP Response:
354 * If 'ocsp' is not NULL, the chunk is copied in the OCSP response's container
355 * pointed by 'ocsp'.
356 * If 'ocsp' is NULL, the function looks up into the OCSP response's
357 * containers tree (using as index the ASN1 form of the OCSP Certificate ID extracted
358 * from the response) and exits on error if not found. Finally, If an OCSP response is
359 * already present in the container, it will be overwritten.
360 *
361 * Note: OCSP response containing more than one OCSP Single response is not
362 * considered valid.
363 *
364 * Returns 0 on success, 1 in error case.
365 */
366static int ssl_sock_load_ocsp_response(struct chunk *ocsp_response, struct certificate_ocsp *ocsp, OCSP_CERTID *cid, char **err)
367{
368 OCSP_RESPONSE *resp;
369 OCSP_BASICRESP *bs = NULL;
370 OCSP_SINGLERESP *sr;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +0200371 OCSP_CERTID *id;
Emeric Brun4147b2e2014-06-16 18:36:30 +0200372 unsigned char *p = (unsigned char *)ocsp_response->str;
373 int rc , count_sr;
Emeric Brun13a6b482014-06-20 15:44:34 +0200374 ASN1_GENERALIZEDTIME *revtime, *thisupd, *nextupd = NULL;
Emeric Brun4147b2e2014-06-16 18:36:30 +0200375 int reason;
376 int ret = 1;
377
378 resp = d2i_OCSP_RESPONSE(NULL, (const unsigned char **)&p, ocsp_response->len);
379 if (!resp) {
380 memprintf(err, "Unable to parse OCSP response");
381 goto out;
382 }
383
384 rc = OCSP_response_status(resp);
385 if (rc != OCSP_RESPONSE_STATUS_SUCCESSFUL) {
386 memprintf(err, "OCSP response status not successful");
387 goto out;
388 }
389
390 bs = OCSP_response_get1_basic(resp);
391 if (!bs) {
392 memprintf(err, "Failed to get basic response from OCSP Response");
393 goto out;
394 }
395
396 count_sr = OCSP_resp_count(bs);
397 if (count_sr > 1) {
398 memprintf(err, "OCSP response ignored because contains multiple single responses (%d)", count_sr);
399 goto out;
400 }
401
402 sr = OCSP_resp_get0(bs, 0);
403 if (!sr) {
404 memprintf(err, "Failed to get OCSP single response");
405 goto out;
406 }
407
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +0200408 id = (OCSP_CERTID*)OCSP_SINGLERESP_get0_id(sr);
409
Emeric Brun4147b2e2014-06-16 18:36:30 +0200410 rc = OCSP_single_get0_status(sr, &reason, &revtime, &thisupd, &nextupd);
411 if (rc != V_OCSP_CERTSTATUS_GOOD) {
412 memprintf(err, "OCSP single response: certificate status not good");
413 goto out;
414 }
415
Emeric Brun13a6b482014-06-20 15:44:34 +0200416 if (!nextupd) {
417 memprintf(err, "OCSP single response: missing nextupdate");
418 goto out;
419 }
420
Emeric Brunc8b27b62014-06-19 14:16:17 +0200421 rc = OCSP_check_validity(thisupd, nextupd, OCSP_MAX_RESPONSE_TIME_SKEW, -1);
Emeric Brun4147b2e2014-06-16 18:36:30 +0200422 if (!rc) {
423 memprintf(err, "OCSP single response: no longer valid.");
424 goto out;
425 }
426
427 if (cid) {
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +0200428 if (OCSP_id_cmp(id, cid)) {
Emeric Brun4147b2e2014-06-16 18:36:30 +0200429 memprintf(err, "OCSP single response: Certificate ID does not match certificate and issuer");
430 goto out;
431 }
432 }
433
434 if (!ocsp) {
435 unsigned char key[OCSP_MAX_CERTID_ASN1_LENGTH];
436 unsigned char *p;
437
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +0200438 rc = i2d_OCSP_CERTID(id, NULL);
Emeric Brun4147b2e2014-06-16 18:36:30 +0200439 if (!rc) {
440 memprintf(err, "OCSP single response: Unable to encode Certificate ID");
441 goto out;
442 }
443
444 if (rc > OCSP_MAX_CERTID_ASN1_LENGTH) {
445 memprintf(err, "OCSP single response: Certificate ID too long");
446 goto out;
447 }
448
449 p = key;
450 memset(key, 0, OCSP_MAX_CERTID_ASN1_LENGTH);
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +0200451 i2d_OCSP_CERTID(id, &p);
Emeric Brun4147b2e2014-06-16 18:36:30 +0200452 ocsp = (struct certificate_ocsp *)ebmb_lookup(&cert_ocsp_tree, key, OCSP_MAX_CERTID_ASN1_LENGTH);
453 if (!ocsp) {
454 memprintf(err, "OCSP single response: Certificate ID does not match any certificate or issuer");
455 goto out;
456 }
457 }
458
459 /* According to comments on "chunk_dup", the
460 previous chunk buffer will be freed */
461 if (!chunk_dup(&ocsp->response, ocsp_response)) {
462 memprintf(err, "OCSP response: Memory allocation error");
463 goto out;
464 }
465
Emeric Brun4f3c87a2014-06-20 15:46:13 +0200466 ocsp->expire = asn1_generalizedtime_to_epoch(nextupd) - OCSP_MAX_RESPONSE_TIME_SKEW;
467
Emeric Brun4147b2e2014-06-16 18:36:30 +0200468 ret = 0;
469out:
470 if (bs)
471 OCSP_BASICRESP_free(bs);
472
473 if (resp)
474 OCSP_RESPONSE_free(resp);
475
476 return ret;
477}
478/*
479 * External function use to update the OCSP response in the OCSP response's
480 * containers tree. The chunk 'ocsp_response' must contain the OCSP response
481 * to update in DER format.
482 *
483 * Returns 0 on success, 1 in error case.
484 */
485int ssl_sock_update_ocsp_response(struct chunk *ocsp_response, char **err)
486{
487 return ssl_sock_load_ocsp_response(ocsp_response, NULL, NULL, err);
488}
489
490/*
491 * This function load the OCSP Resonse in DER format contained in file at
492 * path 'ocsp_path' and call 'ssl_sock_load_ocsp_response'
493 *
494 * Returns 0 on success, 1 in error case.
495 */
496static int ssl_sock_load_ocsp_response_from_file(const char *ocsp_path, struct certificate_ocsp *ocsp, OCSP_CERTID *cid, char **err)
497{
498 int fd = -1;
499 int r = 0;
500 int ret = 1;
501
502 fd = open(ocsp_path, O_RDONLY);
503 if (fd == -1) {
504 memprintf(err, "Error opening OCSP response file");
505 goto end;
506 }
507
508 trash.len = 0;
509 while (trash.len < trash.size) {
510 r = read(fd, trash.str + trash.len, trash.size - trash.len);
511 if (r < 0) {
512 if (errno == EINTR)
513 continue;
514
515 memprintf(err, "Error reading OCSP response from file");
516 goto end;
517 }
518 else if (r == 0) {
519 break;
520 }
521 trash.len += r;
522 }
523
524 close(fd);
525 fd = -1;
526
527 ret = ssl_sock_load_ocsp_response(&trash, ocsp, cid, err);
528end:
529 if (fd != -1)
530 close(fd);
531
532 return ret;
533}
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +0100534#endif
Emeric Brun4147b2e2014-06-16 18:36:30 +0200535
Nenad Merdanovic05552d42015-02-27 19:56:49 +0100536#if (defined SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB && TLS_TICKETS_NO > 0)
537static 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)
538{
539 struct tls_sess_key *keys;
540 struct connection *conn;
541 int head;
542 int i;
543
Vincent Bernat3c2f2f22016-04-03 13:48:42 +0200544 conn = SSL_get_app_data(s);
Nenad Merdanovic146defa2015-05-09 08:46:00 +0200545 keys = objt_listener(conn->target)->bind_conf->keys_ref->tlskeys;
546 head = objt_listener(conn->target)->bind_conf->keys_ref->tls_ticket_enc_index;
Nenad Merdanovic05552d42015-02-27 19:56:49 +0100547
548 if (enc) {
549 memcpy(key_name, keys[head].name, 16);
550
551 if(!RAND_pseudo_bytes(iv, EVP_MAX_IV_LENGTH))
552 return -1;
553
554 if(!EVP_EncryptInit_ex(ectx, EVP_aes_128_cbc(), NULL, keys[head].aes_key, iv))
555 return -1;
556
557 HMAC_Init_ex(hctx, keys[head].hmac_key, 16, HASH_FUNCT(), NULL);
558
559 return 1;
560 } else {
561 for (i = 0; i < TLS_TICKETS_NO; i++) {
562 if (!memcmp(key_name, keys[(head + i) % TLS_TICKETS_NO].name, 16))
563 goto found;
564 }
565 return 0;
566
567 found:
568 HMAC_Init_ex(hctx, keys[(head + i) % TLS_TICKETS_NO].hmac_key, 16, HASH_FUNCT(), NULL);
569 if(!EVP_DecryptInit_ex(ectx, EVP_aes_128_cbc(), NULL, keys[(head + i) % TLS_TICKETS_NO].aes_key, iv))
570 return -1;
571 /* 2 for key renewal, 1 if current key is still valid */
572 return i ? 2 : 1;
573 }
Nenad Merdanovic200b0fa2015-05-09 08:46:01 +0200574}
575
576struct tls_keys_ref *tlskeys_ref_lookup(const char *filename)
577{
578 struct tls_keys_ref *ref;
579
580 list_for_each_entry(ref, &tlskeys_reference, list)
581 if (ref->filename && strcmp(filename, ref->filename) == 0)
582 return ref;
583 return NULL;
584}
585
586struct tls_keys_ref *tlskeys_ref_lookupid(int unique_id)
587{
588 struct tls_keys_ref *ref;
589
590 list_for_each_entry(ref, &tlskeys_reference, list)
591 if (ref->unique_id == unique_id)
592 return ref;
593 return NULL;
594}
595
596int ssl_sock_update_tlskey(char *filename, struct chunk *tlskey, char **err) {
597 struct tls_keys_ref *ref = tlskeys_ref_lookup(filename);
598
599 if(!ref) {
600 memprintf(err, "Unable to locate the referenced filename: %s", filename);
601 return 1;
602 }
603
Pradeep Jindalcc79b002015-08-20 18:25:17 +0530604 memcpy((char *) (ref->tlskeys + ((ref->tls_ticket_enc_index + 2) % TLS_TICKETS_NO)), tlskey->str, tlskey->len);
605 ref->tls_ticket_enc_index = (ref->tls_ticket_enc_index + 1) % TLS_TICKETS_NO;
Nenad Merdanovic200b0fa2015-05-09 08:46:01 +0200606
607 return 0;
Nenad Merdanovic05552d42015-02-27 19:56:49 +0100608}
Nenad Merdanovic200b0fa2015-05-09 08:46:01 +0200609
610/* This function finalize the configuration parsing. Its set all the
Willy Tarreaud1c57502016-12-22 22:46:15 +0100611 * automatic ids. It's called just after the basic checks. It returns
612 * 0 on success otherwise ERR_*.
Nenad Merdanovic200b0fa2015-05-09 08:46:01 +0200613 */
Willy Tarreaud1c57502016-12-22 22:46:15 +0100614static int tlskeys_finalize_config(void)
Nenad Merdanovic200b0fa2015-05-09 08:46:01 +0200615{
616 int i = 0;
617 struct tls_keys_ref *ref, *ref2, *ref3;
618 struct list tkr = LIST_HEAD_INIT(tkr);
619
620 list_for_each_entry(ref, &tlskeys_reference, list) {
621 if (ref->unique_id == -1) {
622 /* Look for the first free id. */
623 while (1) {
624 list_for_each_entry(ref2, &tlskeys_reference, list) {
625 if (ref2->unique_id == i) {
626 i++;
627 break;
628 }
629 }
630 if (&ref2->list == &tlskeys_reference)
631 break;
632 }
633
634 /* Uses the unique id and increment it for the next entry. */
635 ref->unique_id = i;
636 i++;
637 }
638 }
639
640 /* This sort the reference list by id. */
641 list_for_each_entry_safe(ref, ref2, &tlskeys_reference, list) {
642 LIST_DEL(&ref->list);
643 list_for_each_entry(ref3, &tkr, list) {
644 if (ref->unique_id < ref3->unique_id) {
645 LIST_ADDQ(&ref3->list, &ref->list);
646 break;
647 }
648 }
649 if (&ref3->list == &tkr)
650 LIST_ADDQ(&tkr, &ref->list);
651 }
652
653 /* swap root */
654 LIST_ADD(&tkr, &tlskeys_reference);
655 LIST_DEL(&tkr);
Willy Tarreaud1c57502016-12-22 22:46:15 +0100656 return 0;
Nenad Merdanovic200b0fa2015-05-09 08:46:01 +0200657}
Nenad Merdanovic05552d42015-02-27 19:56:49 +0100658#endif /* SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB */
659
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +0100660#ifndef OPENSSL_NO_OCSP
yanbzhube2774d2015-12-10 15:07:30 -0500661int ssl_sock_get_ocsp_arg_kt_index(int evp_keytype)
662{
663 switch (evp_keytype) {
664 case EVP_PKEY_RSA:
665 return 2;
666 case EVP_PKEY_DSA:
667 return 0;
668 case EVP_PKEY_EC:
669 return 1;
670 }
671
672 return -1;
673}
674
Emeric Brun4147b2e2014-06-16 18:36:30 +0200675/*
676 * Callback used to set OCSP status extension content in server hello.
677 */
678int ssl_sock_ocsp_stapling_cbk(SSL *ssl, void *arg)
679{
yanbzhube2774d2015-12-10 15:07:30 -0500680 struct certificate_ocsp *ocsp;
681 struct ocsp_cbk_arg *ocsp_arg;
682 char *ssl_buf;
683 EVP_PKEY *ssl_pkey;
684 int key_type;
685 int index;
686
Vincent Bernat3c2f2f22016-04-03 13:48:42 +0200687 ocsp_arg = arg;
yanbzhube2774d2015-12-10 15:07:30 -0500688
689 ssl_pkey = SSL_get_privatekey(ssl);
690 if (!ssl_pkey)
691 return SSL_TLSEXT_ERR_NOACK;
692
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +0200693 key_type = EVP_PKEY_base_id(ssl_pkey);
yanbzhube2774d2015-12-10 15:07:30 -0500694
695 if (ocsp_arg->is_single && ocsp_arg->single_kt == key_type)
696 ocsp = ocsp_arg->s_ocsp;
697 else {
698 /* For multiple certs per context, we have to find the correct OCSP response based on
699 * the certificate type
700 */
701 index = ssl_sock_get_ocsp_arg_kt_index(key_type);
702
703 if (index < 0)
704 return SSL_TLSEXT_ERR_NOACK;
705
706 ocsp = ocsp_arg->m_ocsp[index];
707
708 }
Emeric Brun4147b2e2014-06-16 18:36:30 +0200709
710 if (!ocsp ||
711 !ocsp->response.str ||
Emeric Brun4f3c87a2014-06-20 15:46:13 +0200712 !ocsp->response.len ||
713 (ocsp->expire < now.tv_sec))
Emeric Brun4147b2e2014-06-16 18:36:30 +0200714 return SSL_TLSEXT_ERR_NOACK;
715
716 ssl_buf = OPENSSL_malloc(ocsp->response.len);
717 if (!ssl_buf)
718 return SSL_TLSEXT_ERR_NOACK;
719
720 memcpy(ssl_buf, ocsp->response.str, ocsp->response.len);
721 SSL_set_tlsext_status_ocsp_resp(ssl, ssl_buf, ocsp->response.len);
722
723 return SSL_TLSEXT_ERR_OK;
724}
725
726/*
727 * This function enables the handling of OCSP status extension on 'ctx' if a
728 * file name 'cert_path' suffixed using ".ocsp" is present.
729 * To enable OCSP status extension, the issuer's certificate is mandatory.
730 * It should be present in the certificate's extra chain builded from file
731 * 'cert_path'. If not found, the issuer certificate is loaded from a file
732 * named 'cert_path' suffixed using '.issuer'.
733 *
734 * In addition, ".ocsp" file content is loaded as a DER format of an OCSP
735 * response. If file is empty or content is not a valid OCSP response,
736 * OCSP status extension is enabled but OCSP response is ignored (a warning
737 * is displayed).
738 *
739 * Returns 1 if no ".ocsp" file found, 0 if OCSP status extension is
740 * succesfully enabled, or -1 in other error case.
741 */
742static int ssl_sock_load_ocsp(SSL_CTX *ctx, const char *cert_path)
743{
744
745 BIO *in = NULL;
746 X509 *x, *xi = NULL, *issuer = NULL;
747 STACK_OF(X509) *chain = NULL;
748 OCSP_CERTID *cid = NULL;
749 SSL *ssl;
750 char ocsp_path[MAXPATHLEN+1];
751 int i, ret = -1;
752 struct stat st;
753 struct certificate_ocsp *ocsp = NULL, *iocsp;
754 char *warn = NULL;
755 unsigned char *p;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +0200756 pem_password_cb *passwd_cb;
757 void *passwd_cb_userdata;
758 void (*callback) (void);
Emeric Brun4147b2e2014-06-16 18:36:30 +0200759
760 snprintf(ocsp_path, MAXPATHLEN+1, "%s.ocsp", cert_path);
761
762 if (stat(ocsp_path, &st))
763 return 1;
764
765 ssl = SSL_new(ctx);
766 if (!ssl)
767 goto out;
768
769 x = SSL_get_certificate(ssl);
770 if (!x)
771 goto out;
772
773 /* Try to lookup for issuer in certificate extra chain */
774#ifdef SSL_CTRL_GET_EXTRA_CHAIN_CERTS
775 SSL_CTX_get_extra_chain_certs(ctx, &chain);
776#else
777 chain = ctx->extra_certs;
778#endif
779 for (i = 0; i < sk_X509_num(chain); i++) {
780 issuer = sk_X509_value(chain, i);
781 if (X509_check_issued(issuer, x) == X509_V_OK)
782 break;
783 else
784 issuer = NULL;
785 }
786
787 /* If not found try to load issuer from a suffixed file */
788 if (!issuer) {
789 char issuer_path[MAXPATHLEN+1];
790
791 in = BIO_new(BIO_s_file());
792 if (!in)
793 goto out;
794
795 snprintf(issuer_path, MAXPATHLEN+1, "%s.issuer", cert_path);
796 if (BIO_read_filename(in, issuer_path) <= 0)
797 goto out;
798
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +0200799 passwd_cb = SSL_CTX_get_default_passwd_cb(ctx);
800 passwd_cb_userdata = SSL_CTX_get_default_passwd_cb_userdata(ctx);
801
802 xi = PEM_read_bio_X509_AUX(in, NULL, passwd_cb, passwd_cb_userdata);
Emeric Brun4147b2e2014-06-16 18:36:30 +0200803 if (!xi)
804 goto out;
805
806 if (X509_check_issued(xi, x) != X509_V_OK)
807 goto out;
808
809 issuer = xi;
810 }
811
812 cid = OCSP_cert_to_id(0, x, issuer);
813 if (!cid)
814 goto out;
815
816 i = i2d_OCSP_CERTID(cid, NULL);
817 if (!i || (i > OCSP_MAX_CERTID_ASN1_LENGTH))
818 goto out;
819
Vincent Bernat02779b62016-04-03 13:48:43 +0200820 ocsp = calloc(1, sizeof(*ocsp));
Emeric Brun4147b2e2014-06-16 18:36:30 +0200821 if (!ocsp)
822 goto out;
823
824 p = ocsp->key_data;
825 i2d_OCSP_CERTID(cid, &p);
826
827 iocsp = (struct certificate_ocsp *)ebmb_insert(&cert_ocsp_tree, &ocsp->key, OCSP_MAX_CERTID_ASN1_LENGTH);
828 if (iocsp == ocsp)
829 ocsp = NULL;
830
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +0200831#ifndef SSL_CTX_get_tlsext_status_cb
832# define SSL_CTX_get_tlsext_status_cb(ctx, cb) \
833 *cb = (void (*) (void))ctx->tlsext_status_cb;
834#endif
835 SSL_CTX_get_tlsext_status_cb(ctx, &callback);
836
837 if (!callback) {
Vincent Bernat02779b62016-04-03 13:48:43 +0200838 struct ocsp_cbk_arg *cb_arg = calloc(1, sizeof(*cb_arg));
Emmanuel Hocdetb7a4c342017-01-06 12:57:46 +0100839 EVP_PKEY *pkey;
yanbzhube2774d2015-12-10 15:07:30 -0500840
841 cb_arg->is_single = 1;
842 cb_arg->s_ocsp = iocsp;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +0200843
Emmanuel Hocdetb7a4c342017-01-06 12:57:46 +0100844 pkey = X509_get_pubkey(x);
845 cb_arg->single_kt = EVP_PKEY_base_id(pkey);
846 EVP_PKEY_free(pkey);
yanbzhube2774d2015-12-10 15:07:30 -0500847
848 SSL_CTX_set_tlsext_status_cb(ctx, ssl_sock_ocsp_stapling_cbk);
849 SSL_CTX_set_tlsext_status_arg(ctx, cb_arg);
850 } else {
851 /*
852 * If the ctx has a status CB, then we have previously set an OCSP staple for this ctx
853 * Update that cb_arg with the new cert's staple
854 */
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +0200855 struct ocsp_cbk_arg *cb_arg;
yanbzhube2774d2015-12-10 15:07:30 -0500856 struct certificate_ocsp *tmp_ocsp;
857 int index;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +0200858 int key_type;
Emmanuel Hocdetb7a4c342017-01-06 12:57:46 +0100859 EVP_PKEY *pkey;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +0200860
861#ifdef SSL_CTX_get_tlsext_status_arg
862 SSL_CTX_ctrl(ctx, SSL_CTRL_GET_TLSEXT_STATUS_REQ_CB_ARG, 0, &cb_arg);
863#else
864 cb_arg = ctx->tlsext_status_arg;
865#endif
yanbzhube2774d2015-12-10 15:07:30 -0500866
867 /*
868 * The following few lines will convert cb_arg from a single ocsp to multi ocsp
869 * the order of operations below matter, take care when changing it
870 */
871 tmp_ocsp = cb_arg->s_ocsp;
872 index = ssl_sock_get_ocsp_arg_kt_index(cb_arg->single_kt);
873 cb_arg->s_ocsp = NULL;
874 cb_arg->m_ocsp[index] = tmp_ocsp;
875 cb_arg->is_single = 0;
876 cb_arg->single_kt = 0;
877
Emmanuel Hocdetb7a4c342017-01-06 12:57:46 +0100878 pkey = X509_get_pubkey(x);
879 key_type = EVP_PKEY_base_id(pkey);
880 EVP_PKEY_free(pkey);
881
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +0200882 index = ssl_sock_get_ocsp_arg_kt_index(key_type);
yanbzhube2774d2015-12-10 15:07:30 -0500883 if (index >= 0 && !cb_arg->m_ocsp[index])
884 cb_arg->m_ocsp[index] = iocsp;
885
886 }
Emeric Brun4147b2e2014-06-16 18:36:30 +0200887
888 ret = 0;
889
890 warn = NULL;
891 if (ssl_sock_load_ocsp_response_from_file(ocsp_path, iocsp, cid, &warn)) {
892 memprintf(&warn, "Loading '%s': %s. Content will be ignored", ocsp_path, warn ? warn : "failure");
893 Warning("%s.\n", warn);
894 }
895
896out:
897 if (ssl)
898 SSL_free(ssl);
899
900 if (in)
901 BIO_free(in);
902
903 if (xi)
904 X509_free(xi);
905
906 if (cid)
907 OCSP_CERTID_free(cid);
908
909 if (ocsp)
910 free(ocsp);
911
912 if (warn)
913 free(warn);
914
915
916 return ret;
917}
918
919#endif
920
Daniel Jakots54ffb912015-11-06 20:02:41 +0100921#if (OPENSSL_VERSION_NUMBER >= 0x1000200fL && !defined OPENSSL_NO_TLSEXT && !defined OPENSSL_IS_BORINGSSL && !defined LIBRESSL_VERSION_NUMBER)
Janusz Dziemidowicz2c701b52015-03-07 23:03:59 +0100922
923#define CT_EXTENSION_TYPE 18
924
925static int sctl_ex_index = -1;
926
927/*
928 * Try to parse Signed Certificate Timestamp List structure. This function
929 * makes only basic test if the data seems like SCTL. No signature validation
930 * is performed.
931 */
932static int ssl_sock_parse_sctl(struct chunk *sctl)
933{
934 int ret = 1;
935 int len, pos, sct_len;
936 unsigned char *data;
937
938 if (sctl->len < 2)
939 goto out;
940
941 data = (unsigned char *)sctl->str;
942 len = (data[0] << 8) | data[1];
943
944 if (len + 2 != sctl->len)
945 goto out;
946
947 data = data + 2;
948 pos = 0;
949 while (pos < len) {
950 if (len - pos < 2)
951 goto out;
952
953 sct_len = (data[pos] << 8) | data[pos + 1];
954 if (pos + sct_len + 2 > len)
955 goto out;
956
957 pos += sct_len + 2;
958 }
959
960 ret = 0;
961
962out:
963 return ret;
964}
965
966static int ssl_sock_load_sctl_from_file(const char *sctl_path, struct chunk **sctl)
967{
968 int fd = -1;
969 int r = 0;
970 int ret = 1;
971
972 *sctl = NULL;
973
974 fd = open(sctl_path, O_RDONLY);
975 if (fd == -1)
976 goto end;
977
978 trash.len = 0;
979 while (trash.len < trash.size) {
980 r = read(fd, trash.str + trash.len, trash.size - trash.len);
981 if (r < 0) {
982 if (errno == EINTR)
983 continue;
984
985 goto end;
986 }
987 else if (r == 0) {
988 break;
989 }
990 trash.len += r;
991 }
992
993 ret = ssl_sock_parse_sctl(&trash);
994 if (ret)
995 goto end;
996
Vincent Bernat02779b62016-04-03 13:48:43 +0200997 *sctl = calloc(1, sizeof(**sctl));
Janusz Dziemidowicz2c701b52015-03-07 23:03:59 +0100998 if (!chunk_dup(*sctl, &trash)) {
999 free(*sctl);
1000 *sctl = NULL;
1001 goto end;
1002 }
1003
1004end:
1005 if (fd != -1)
1006 close(fd);
1007
1008 return ret;
1009}
1010
1011int ssl_sock_sctl_add_cbk(SSL *ssl, unsigned ext_type, const unsigned char **out, size_t *outlen, int *al, void *add_arg)
1012{
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02001013 struct chunk *sctl = add_arg;
Janusz Dziemidowicz2c701b52015-03-07 23:03:59 +01001014
1015 *out = (unsigned char *)sctl->str;
1016 *outlen = sctl->len;
1017
1018 return 1;
1019}
1020
1021int ssl_sock_sctl_parse_cbk(SSL *s, unsigned int ext_type, const unsigned char *in, size_t inlen, int *al, void *parse_arg)
1022{
1023 return 1;
1024}
1025
1026static int ssl_sock_load_sctl(SSL_CTX *ctx, const char *cert_path)
1027{
1028 char sctl_path[MAXPATHLEN+1];
1029 int ret = -1;
1030 struct stat st;
1031 struct chunk *sctl = NULL;
1032
1033 snprintf(sctl_path, MAXPATHLEN+1, "%s.sctl", cert_path);
1034
1035 if (stat(sctl_path, &st))
1036 return 1;
1037
1038 if (ssl_sock_load_sctl_from_file(sctl_path, &sctl))
1039 goto out;
1040
1041 if (!SSL_CTX_add_server_custom_ext(ctx, CT_EXTENSION_TYPE, ssl_sock_sctl_add_cbk, NULL, sctl, ssl_sock_sctl_parse_cbk, NULL)) {
1042 free(sctl);
1043 goto out;
1044 }
1045
1046 SSL_CTX_set_ex_data(ctx, sctl_ex_index, sctl);
1047
1048 ret = 0;
1049
1050out:
1051 return ret;
1052}
1053
1054#endif
1055
Emeric Brune1f38db2012-09-03 20:36:47 +02001056void ssl_sock_infocbk(const SSL *ssl, int where, int ret)
1057{
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02001058 struct connection *conn = SSL_get_app_data(ssl);
Emeric Brund8b2bb52014-01-28 15:43:53 +01001059 BIO *write_bio;
Willy Tarreau622317d2015-02-27 16:36:16 +01001060 (void)ret; /* shut gcc stupid warning */
Emeric Brune1f38db2012-09-03 20:36:47 +02001061
1062 if (where & SSL_CB_HANDSHAKE_START) {
1063 /* Disable renegotiation (CVE-2009-3555) */
Willy Tarreau20879a02012-12-03 16:32:10 +01001064 if (conn->flags & CO_FL_CONNECTED) {
Emeric Brune1f38db2012-09-03 20:36:47 +02001065 conn->flags |= CO_FL_ERROR;
Willy Tarreau20879a02012-12-03 16:32:10 +01001066 conn->err_code = CO_ER_SSL_RENEG;
1067 }
Emeric Brune1f38db2012-09-03 20:36:47 +02001068 }
Emeric Brund8b2bb52014-01-28 15:43:53 +01001069
1070 if ((where & SSL_CB_ACCEPT_LOOP) == SSL_CB_ACCEPT_LOOP) {
1071 if (!(conn->xprt_st & SSL_SOCK_ST_FL_16K_WBFSIZE)) {
1072 /* Long certificate chains optimz
1073 If write and read bios are differents, we
1074 consider that the buffering was activated,
1075 so we rise the output buffer size from 4k
1076 to 16k */
1077 write_bio = SSL_get_wbio(ssl);
1078 if (write_bio != SSL_get_rbio(ssl)) {
1079 BIO_set_write_buffer_size(write_bio, 16384);
1080 conn->xprt_st |= SSL_SOCK_ST_FL_16K_WBFSIZE;
1081 }
1082 }
1083 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02001084}
1085
Emeric Brune64aef12012-09-21 13:15:06 +02001086/* Callback is called for each certificate of the chain during a verify
1087 ok is set to 1 if preverify detect no error on current certificate.
1088 Returns 0 to break the handshake, 1 otherwise. */
Evan Broderbe554312013-06-27 00:05:25 -07001089int ssl_sock_bind_verifycbk(int ok, X509_STORE_CTX *x_store)
Emeric Brune64aef12012-09-21 13:15:06 +02001090{
1091 SSL *ssl;
1092 struct connection *conn;
Emeric Brun81c00f02012-09-21 14:31:21 +02001093 int err, depth;
Emeric Brune64aef12012-09-21 13:15:06 +02001094
1095 ssl = X509_STORE_CTX_get_ex_data(x_store, SSL_get_ex_data_X509_STORE_CTX_idx());
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02001096 conn = SSL_get_app_data(ssl);
Emeric Brune64aef12012-09-21 13:15:06 +02001097
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02001098 conn->xprt_st |= SSL_SOCK_ST_FL_VERIFY_DONE;
Emeric Brune64aef12012-09-21 13:15:06 +02001099
Emeric Brun81c00f02012-09-21 14:31:21 +02001100 if (ok) /* no errors */
1101 return ok;
1102
1103 depth = X509_STORE_CTX_get_error_depth(x_store);
1104 err = X509_STORE_CTX_get_error(x_store);
1105
1106 /* check if CA error needs to be ignored */
1107 if (depth > 0) {
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02001108 if (!SSL_SOCK_ST_TO_CA_ERROR(conn->xprt_st)) {
1109 conn->xprt_st |= SSL_SOCK_CA_ERROR_TO_ST(err);
1110 conn->xprt_st |= SSL_SOCK_CAEDEPTH_TO_ST(depth);
Emeric Brunf282a812012-09-21 15:27:54 +02001111 }
1112
Emeric Brun1eb20ef2012-12-03 13:24:29 +01001113 if (objt_listener(conn->target)->bind_conf->ca_ignerr & (1ULL << err)) {
Thierry FOURNIER / OZON.IO8b068c22016-10-10 11:59:50 +02001114 ssl_sock_dump_errors(conn);
Emeric Brun1eb20ef2012-12-03 13:24:29 +01001115 ERR_clear_error();
Emeric Brun81c00f02012-09-21 14:31:21 +02001116 return 1;
Emeric Brun1eb20ef2012-12-03 13:24:29 +01001117 }
Emeric Brun81c00f02012-09-21 14:31:21 +02001118
Willy Tarreau20879a02012-12-03 16:32:10 +01001119 conn->err_code = CO_ER_SSL_CA_FAIL;
Emeric Brun81c00f02012-09-21 14:31:21 +02001120 return 0;
1121 }
1122
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02001123 if (!SSL_SOCK_ST_TO_CRTERROR(conn->xprt_st))
1124 conn->xprt_st |= SSL_SOCK_CRTERROR_TO_ST(err);
Emeric Brunf282a812012-09-21 15:27:54 +02001125
Emeric Brun81c00f02012-09-21 14:31:21 +02001126 /* check if certificate error needs to be ignored */
Emeric Brun1eb20ef2012-12-03 13:24:29 +01001127 if (objt_listener(conn->target)->bind_conf->crt_ignerr & (1ULL << err)) {
Thierry FOURNIER / OZON.IO8b068c22016-10-10 11:59:50 +02001128 ssl_sock_dump_errors(conn);
Emeric Brun1eb20ef2012-12-03 13:24:29 +01001129 ERR_clear_error();
Emeric Brun81c00f02012-09-21 14:31:21 +02001130 return 1;
Emeric Brun1eb20ef2012-12-03 13:24:29 +01001131 }
Emeric Brun81c00f02012-09-21 14:31:21 +02001132
Willy Tarreau20879a02012-12-03 16:32:10 +01001133 conn->err_code = CO_ER_SSL_CRT_FAIL;
Emeric Brun81c00f02012-09-21 14:31:21 +02001134 return 0;
Emeric Brune64aef12012-09-21 13:15:06 +02001135}
1136
Emeric Brun29f037d2014-04-25 19:05:36 +02001137/* Callback is called for ssl protocol analyse */
1138void ssl_sock_msgcbk(int write_p, int version, int content_type, const void *buf, size_t len, SSL *ssl, void *arg)
1139{
Emeric Brun29f037d2014-04-25 19:05:36 +02001140#ifdef TLS1_RT_HEARTBEAT
1141 /* test heartbeat received (write_p is set to 0
1142 for a received record) */
Willy Tarreauf51c6982014-04-25 20:02:39 +02001143 if ((content_type == TLS1_RT_HEARTBEAT) && (write_p == 0)) {
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02001144 struct connection *conn = SSL_get_app_data(ssl);
Willy Tarreauf51c6982014-04-25 20:02:39 +02001145 const unsigned char *p = buf;
1146 unsigned int payload;
1147
Emeric Brun29f037d2014-04-25 19:05:36 +02001148 conn->xprt_st |= SSL_SOCK_RECV_HEARTBEAT;
Willy Tarreauf51c6982014-04-25 20:02:39 +02001149
1150 /* Check if this is a CVE-2014-0160 exploitation attempt. */
1151 if (*p != TLS1_HB_REQUEST)
1152 return;
1153
Willy Tarreauaeed6722014-04-25 23:59:58 +02001154 if (len < 1 + 2 + 16) /* 1 type + 2 size + 0 payload + 16 padding */
Willy Tarreauf51c6982014-04-25 20:02:39 +02001155 goto kill_it;
1156
1157 payload = (p[1] * 256) + p[2];
Willy Tarreau3b2fdb62014-04-25 23:44:22 +02001158 if (3 + payload + 16 <= len)
Willy Tarreauf51c6982014-04-25 20:02:39 +02001159 return; /* OK no problem */
Willy Tarreauaeed6722014-04-25 23:59:58 +02001160 kill_it:
Willy Tarreau3b2fdb62014-04-25 23:44:22 +02001161 /* We have a clear heartbleed attack (CVE-2014-0160), the
1162 * advertised payload is larger than the advertised packet
1163 * length, so we have garbage in the buffer between the
1164 * payload and the end of the buffer (p+len). We can't know
1165 * if the SSL stack is patched, and we don't know if we can
1166 * safely wipe out the area between p+3+len and payload.
1167 * So instead, we prevent the response from being sent by
1168 * setting the max_send_fragment to 0 and we report an SSL
1169 * error, which will kill this connection. It will be reported
1170 * above as SSL_ERROR_SSL while an other handshake failure with
Willy Tarreauf51c6982014-04-25 20:02:39 +02001171 * a heartbeat message will be reported as SSL_ERROR_SYSCALL.
1172 */
Willy Tarreau3b2fdb62014-04-25 23:44:22 +02001173 ssl->max_send_fragment = 0;
Willy Tarreauf51c6982014-04-25 20:02:39 +02001174 SSLerr(SSL_F_TLS1_HEARTBEAT, SSL_R_SSL_HANDSHAKE_FAILURE);
1175 return;
1176 }
Emeric Brun29f037d2014-04-25 19:05:36 +02001177#endif
1178}
1179
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02001180#ifdef OPENSSL_NPN_NEGOTIATED
1181/* This callback is used so that the server advertises the list of
1182 * negociable protocols for NPN.
1183 */
1184static int ssl_sock_advertise_npn_protos(SSL *s, const unsigned char **data,
1185 unsigned int *len, void *arg)
1186{
Emmanuel Hocdet98263292016-12-29 18:26:15 +01001187 struct ssl_bind_conf *conf = arg;
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02001188
1189 *data = (const unsigned char *)conf->npn_str;
1190 *len = conf->npn_len;
1191 return SSL_TLSEXT_ERR_OK;
1192}
1193#endif
1194
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01001195#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Willy Tarreauab861d32013-04-02 02:30:41 +02001196/* This callback is used so that the server advertises the list of
1197 * negociable protocols for ALPN.
1198 */
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01001199static int ssl_sock_advertise_alpn_protos(SSL *s, const unsigned char **out,
1200 unsigned char *outlen,
1201 const unsigned char *server,
1202 unsigned int server_len, void *arg)
Willy Tarreauab861d32013-04-02 02:30:41 +02001203{
Emmanuel Hocdet98263292016-12-29 18:26:15 +01001204 struct ssl_bind_conf *conf = arg;
Willy Tarreauab861d32013-04-02 02:30:41 +02001205
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01001206 if (SSL_select_next_proto((unsigned char**) out, outlen, (const unsigned char *)conf->alpn_str,
1207 conf->alpn_len, server, server_len) != OPENSSL_NPN_NEGOTIATED) {
1208 return SSL_TLSEXT_ERR_NOACK;
1209 }
Willy Tarreauab861d32013-04-02 02:30:41 +02001210 return SSL_TLSEXT_ERR_OK;
1211}
1212#endif
1213
Willy Tarreauc8ad3be2015-06-17 15:48:26 +02001214#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +01001215#ifndef SSL_NO_GENERATE_CERTIFICATES
Christopher Faulet85b5a1a2015-10-09 11:46:32 +02001216static DH *ssl_get_tmp_dh(SSL *ssl, int export, int keylen);
1217
Christopher Faulet30548802015-06-11 13:39:32 +02001218/* Create a X509 certificate with the specified servername and serial. This
1219 * function returns a SSL_CTX object or NULL if an error occurs. */
Christopher Faulet7969a332015-10-09 11:15:03 +02001220static SSL_CTX *
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001221ssl_sock_do_create_cert(const char *servername, struct bind_conf *bind_conf, SSL *ssl)
Christopher Faulet31af49d2015-06-09 17:29:50 +02001222{
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001223 static unsigned int serial = 0;
1224
Christopher Faulet7969a332015-10-09 11:15:03 +02001225 X509 *cacert = bind_conf->ca_sign_cert;
1226 EVP_PKEY *capkey = bind_conf->ca_sign_pkey;
Christopher Faulet31af49d2015-06-09 17:29:50 +02001227 SSL_CTX *ssl_ctx = NULL;
1228 X509 *newcrt = NULL;
1229 EVP_PKEY *pkey = NULL;
Christopher Faulet31af49d2015-06-09 17:29:50 +02001230 X509_NAME *name;
1231 const EVP_MD *digest;
1232 X509V3_CTX ctx;
1233 unsigned int i;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02001234 int key_type;
Christopher Faulet31af49d2015-06-09 17:29:50 +02001235
Christopher Faulet7969a332015-10-09 11:15:03 +02001236 /* Get the private key of the defautl certificate and use it */
1237 if (!(pkey = SSL_get_privatekey(ssl)))
Christopher Faulet31af49d2015-06-09 17:29:50 +02001238 goto mkcert_error;
1239
1240 /* Create the certificate */
1241 if (!(newcrt = X509_new()))
1242 goto mkcert_error;
1243
1244 /* Set version number for the certificate (X509v3) and the serial
1245 * number */
1246 if (X509_set_version(newcrt, 2L) != 1)
1247 goto mkcert_error;
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001248 if (!serial)
1249 serial = now_ms;
1250 ASN1_INTEGER_set(X509_get_serialNumber(newcrt), serial++);
Christopher Faulet31af49d2015-06-09 17:29:50 +02001251
1252 /* Set duration for the certificate */
1253 if (!X509_gmtime_adj(X509_get_notBefore(newcrt), (long)-60*60*24) ||
1254 !X509_gmtime_adj(X509_get_notAfter(newcrt),(long)60*60*24*365))
1255 goto mkcert_error;
1256
1257 /* set public key in the certificate */
1258 if (X509_set_pubkey(newcrt, pkey) != 1)
1259 goto mkcert_error;
1260
1261 /* Set issuer name from the CA */
1262 if (!(name = X509_get_subject_name(cacert)))
1263 goto mkcert_error;
1264 if (X509_set_issuer_name(newcrt, name) != 1)
1265 goto mkcert_error;
1266
1267 /* Set the subject name using the same, but the CN */
1268 name = X509_NAME_dup(name);
1269 if (X509_NAME_add_entry_by_txt(name, "CN", MBSTRING_ASC,
1270 (const unsigned char *)servername,
1271 -1, -1, 0) != 1) {
1272 X509_NAME_free(name);
1273 goto mkcert_error;
1274 }
1275 if (X509_set_subject_name(newcrt, name) != 1) {
1276 X509_NAME_free(name);
1277 goto mkcert_error;
1278 }
1279 X509_NAME_free(name);
1280
1281 /* Add x509v3 extensions as specified */
1282 X509V3_set_ctx(&ctx, cacert, newcrt, NULL, NULL, 0);
1283 for (i = 0; i < X509V3_EXT_SIZE; i++) {
1284 X509_EXTENSION *ext;
1285
1286 if (!(ext = X509V3_EXT_conf(NULL, &ctx, x509v3_ext_names[i], x509v3_ext_values[i])))
1287 goto mkcert_error;
1288 if (!X509_add_ext(newcrt, ext, -1)) {
1289 X509_EXTENSION_free(ext);
1290 goto mkcert_error;
1291 }
1292 X509_EXTENSION_free(ext);
1293 }
1294
1295 /* Sign the certificate with the CA private key */
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02001296
1297 key_type = EVP_PKEY_base_id(capkey);
1298
1299 if (key_type == EVP_PKEY_DSA)
1300 digest = EVP_sha1();
1301 else if (key_type == EVP_PKEY_RSA)
Christopher Faulet31af49d2015-06-09 17:29:50 +02001302 digest = EVP_sha256();
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02001303 else if (key_type == EVP_PKEY_EC)
Christopher Faulet7969a332015-10-09 11:15:03 +02001304 digest = EVP_sha256();
1305 else {
Christopher Faulete7db2162015-10-19 13:59:24 +02001306#if (OPENSSL_VERSION_NUMBER >= 0x1000000fL)
Christopher Faulet7969a332015-10-09 11:15:03 +02001307 int nid;
1308
1309 if (EVP_PKEY_get_default_digest_nid(capkey, &nid) <= 0)
1310 goto mkcert_error;
1311 if (!(digest = EVP_get_digestbynid(nid)))
1312 goto mkcert_error;
Christopher Faulete7db2162015-10-19 13:59:24 +02001313#else
1314 goto mkcert_error;
1315#endif
Christopher Faulet7969a332015-10-09 11:15:03 +02001316 }
1317
Christopher Faulet31af49d2015-06-09 17:29:50 +02001318 if (!(X509_sign(newcrt, capkey, digest)))
1319 goto mkcert_error;
1320
1321 /* Create and set the new SSL_CTX */
1322 if (!(ssl_ctx = SSL_CTX_new(SSLv23_server_method())))
1323 goto mkcert_error;
1324 if (!SSL_CTX_use_PrivateKey(ssl_ctx, pkey))
1325 goto mkcert_error;
1326 if (!SSL_CTX_use_certificate(ssl_ctx, newcrt))
1327 goto mkcert_error;
1328 if (!SSL_CTX_check_private_key(ssl_ctx))
1329 goto mkcert_error;
1330
1331 if (newcrt) X509_free(newcrt);
Christopher Faulet7969a332015-10-09 11:15:03 +02001332
Christopher Faulet85b5a1a2015-10-09 11:46:32 +02001333 SSL_CTX_set_tmp_dh_callback(ssl_ctx, ssl_get_tmp_dh);
1334#if defined(SSL_CTX_set_tmp_ecdh) && !defined(OPENSSL_NO_ECDH)
1335 {
Emmanuel Hocdet98263292016-12-29 18:26:15 +01001336 const char *ecdhe = (bind_conf->ssl_conf.ecdhe ? bind_conf->ssl_conf.ecdhe : ECDHE_DEFAULT_CURVE);
Christopher Faulet85b5a1a2015-10-09 11:46:32 +02001337 EC_KEY *ecc;
1338 int nid;
1339
1340 if ((nid = OBJ_sn2nid(ecdhe)) == NID_undef)
1341 goto end;
1342 if (!(ecc = EC_KEY_new_by_curve_name(nid)))
1343 goto end;
1344 SSL_CTX_set_tmp_ecdh(ssl_ctx, ecc);
1345 EC_KEY_free(ecc);
1346 }
1347#endif
1348 end:
Christopher Faulet31af49d2015-06-09 17:29:50 +02001349 return ssl_ctx;
1350
1351 mkcert_error:
1352 if (ssl_ctx) SSL_CTX_free(ssl_ctx);
1353 if (newcrt) X509_free(newcrt);
Christopher Faulet31af49d2015-06-09 17:29:50 +02001354 return NULL;
1355}
1356
Christopher Faulet7969a332015-10-09 11:15:03 +02001357SSL_CTX *
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001358ssl_sock_create_cert(struct connection *conn, const char *servername, unsigned int key)
Christopher Faulet7969a332015-10-09 11:15:03 +02001359{
1360 struct bind_conf *bind_conf = objt_listener(conn->target)->bind_conf;
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001361
1362 return ssl_sock_do_create_cert(servername, bind_conf, conn->xprt_ctx);
Christopher Faulet7969a332015-10-09 11:15:03 +02001363}
1364
Christopher Faulet30548802015-06-11 13:39:32 +02001365/* Do a lookup for a certificate in the LRU cache used to store generated
1366 * certificates. */
1367SSL_CTX *
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001368ssl_sock_get_generated_cert(unsigned int key, struct bind_conf *bind_conf)
Christopher Faulet30548802015-06-11 13:39:32 +02001369{
1370 struct lru64 *lru = NULL;
1371
1372 if (ssl_ctx_lru_tree) {
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001373 lru = lru64_lookup(key, ssl_ctx_lru_tree, bind_conf->ca_sign_cert, 0);
Christopher Faulet30548802015-06-11 13:39:32 +02001374 if (lru && lru->domain)
1375 return (SSL_CTX *)lru->data;
1376 }
1377 return NULL;
1378}
1379
Christopher Fauletd2cab922015-07-28 16:03:47 +02001380/* Set a certificate int the LRU cache used to store generated
1381 * certificate. Return 0 on success, otherwise -1 */
1382int
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001383ssl_sock_set_generated_cert(SSL_CTX *ssl_ctx, unsigned int key, struct bind_conf *bind_conf)
Christopher Faulet30548802015-06-11 13:39:32 +02001384{
1385 struct lru64 *lru = NULL;
1386
1387 if (ssl_ctx_lru_tree) {
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001388 lru = lru64_get(key, ssl_ctx_lru_tree, bind_conf->ca_sign_cert, 0);
Christopher Faulet30548802015-06-11 13:39:32 +02001389 if (!lru)
Christopher Fauletd2cab922015-07-28 16:03:47 +02001390 return -1;
Christopher Faulet30548802015-06-11 13:39:32 +02001391 if (lru->domain && lru->data)
1392 lru->free((SSL_CTX *)lru->data);
Christopher Faulet7969a332015-10-09 11:15:03 +02001393 lru64_commit(lru, ssl_ctx, bind_conf->ca_sign_cert, 0, (void (*)(void *))SSL_CTX_free);
Christopher Fauletd2cab922015-07-28 16:03:47 +02001394 return 0;
Christopher Faulet30548802015-06-11 13:39:32 +02001395 }
Christopher Fauletd2cab922015-07-28 16:03:47 +02001396 return -1;
Christopher Faulet30548802015-06-11 13:39:32 +02001397}
1398
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001399/* Compute the key of the certificate. */
Christopher Faulet30548802015-06-11 13:39:32 +02001400unsigned int
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001401ssl_sock_generated_cert_key(const void *data, size_t len)
Christopher Faulet30548802015-06-11 13:39:32 +02001402{
1403 return XXH32(data, len, ssl_ctx_lru_seed);
1404}
1405
Willy Tarreau2f63ef42015-10-20 15:16:01 +02001406/* Generate a cert and immediately assign it to the SSL session so that the cert's
1407 * refcount is maintained regardless of the cert's presence in the LRU cache.
1408 */
Christopher Faulet31af49d2015-06-09 17:29:50 +02001409static SSL_CTX *
Christopher Faulet7969a332015-10-09 11:15:03 +02001410ssl_sock_generate_certificate(const char *servername, struct bind_conf *bind_conf, SSL *ssl)
Christopher Faulet31af49d2015-06-09 17:29:50 +02001411{
1412 X509 *cacert = bind_conf->ca_sign_cert;
Christopher Faulet31af49d2015-06-09 17:29:50 +02001413 SSL_CTX *ssl_ctx = NULL;
1414 struct lru64 *lru = NULL;
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001415 unsigned int key;
Christopher Faulet31af49d2015-06-09 17:29:50 +02001416
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001417 key = ssl_sock_generated_cert_key(servername, strlen(servername));
Christopher Faulet31af49d2015-06-09 17:29:50 +02001418 if (ssl_ctx_lru_tree) {
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001419 lru = lru64_get(key, ssl_ctx_lru_tree, cacert, 0);
Christopher Faulet31af49d2015-06-09 17:29:50 +02001420 if (lru && lru->domain)
1421 ssl_ctx = (SSL_CTX *)lru->data;
Christopher Fauletd2cab922015-07-28 16:03:47 +02001422 if (!ssl_ctx && lru) {
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001423 ssl_ctx = ssl_sock_do_create_cert(servername, bind_conf, ssl);
Christopher Faulet31af49d2015-06-09 17:29:50 +02001424 lru64_commit(lru, ssl_ctx, cacert, 0, (void (*)(void *))SSL_CTX_free);
Christopher Fauletd2cab922015-07-28 16:03:47 +02001425 }
Willy Tarreau2f63ef42015-10-20 15:16:01 +02001426 SSL_set_SSL_CTX(ssl, ssl_ctx);
Christopher Faulet31af49d2015-06-09 17:29:50 +02001427 }
Willy Tarreau2f63ef42015-10-20 15:16:01 +02001428 else {
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001429 ssl_ctx = ssl_sock_do_create_cert(servername, bind_conf, ssl);
Willy Tarreau2f63ef42015-10-20 15:16:01 +02001430 SSL_set_SSL_CTX(ssl, ssl_ctx);
1431 /* No LRU cache, this CTX will be released as soon as the session dies */
1432 SSL_CTX_free(ssl_ctx);
1433 }
Christopher Faulet31af49d2015-06-09 17:29:50 +02001434 return ssl_ctx;
1435}
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +01001436#endif /* !defined SSL_NO_GENERATE_CERTIFICATES */
Christopher Faulet31af49d2015-06-09 17:29:50 +02001437
Emmanuel Hocdet05942112017-02-20 16:11:50 +01001438#ifdef OPENSSL_IS_BORINGSSL
1439
1440static int ssl_sock_switchctx_err_cbk(SSL *ssl, int *al, void *priv)
1441{
1442 (void)al; /* shut gcc stupid warning */
1443 (void)priv;
1444
1445 if (!SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name))
1446 return SSL_TLSEXT_ERR_NOACK;
1447 return SSL_TLSEXT_ERR_OK;
1448}
1449
1450static int ssl_sock_switchctx_cbk(const struct ssl_early_callback_ctx *ctx)
1451{
1452 struct connection *conn;
1453 struct bind_conf *s;
1454 const uint8_t *extension_data;
1455 size_t extension_len;
1456 CBS extension, cipher_suites, server_name_list, host_name, sig_algs;
1457 const SSL_CIPHER *cipher;
1458 uint16_t cipher_suite;
1459 uint8_t name_type, hash, sign;
1460 int has_rsa = 0, has_ecdsa = 0, has_ecdsa_sig = 0;
1461
1462 char *wildp = NULL;
1463 const uint8_t *servername;
1464 struct ebmb_node *node, *n, *node_ecdsa = NULL, *node_rsa = NULL, *node_anonymous = NULL;
1465 int i;
1466
1467 conn = SSL_get_app_data(ctx->ssl);
1468 s = objt_listener(conn->target)->bind_conf;
1469
1470 if (SSL_early_callback_ctx_extension_get(ctx, TLSEXT_TYPE_server_name,
1471 &extension_data, &extension_len)) {
1472 CBS_init(&extension, extension_data, extension_len);
1473
1474 if (!CBS_get_u16_length_prefixed(&extension, &server_name_list)
1475 || !CBS_get_u8(&server_name_list, &name_type)
1476 /* Although the server_name extension was intended to be extensible to
1477 * new name types and multiple names, OpenSSL 1.0.x had a bug which meant
1478 * different name types will cause an error. Further, RFC 4366 originally
1479 * defined syntax inextensibly. RFC 6066 corrected this mistake, but
1480 * adding new name types is no longer feasible.
1481 *
1482 * Act as if the extensibility does not exist to simplify parsing. */
1483 || !CBS_get_u16_length_prefixed(&server_name_list, &host_name)
1484 || CBS_len(&server_name_list) != 0
1485 || CBS_len(&extension) != 0
1486 || name_type != TLSEXT_NAMETYPE_host_name
1487 || CBS_len(&host_name) == 0
1488 || CBS_len(&host_name) > TLSEXT_MAXLEN_host_name
1489 || CBS_contains_zero_byte(&host_name)) {
1490 goto abort;
1491 }
1492 } else {
1493 /* without SNI extension, is the default_ctx (need SSL_TLSEXT_ERR_NOACK) */
1494 if (!s->strict_sni)
1495 return 1;
1496 goto abort;
1497 }
1498
1499 /* extract/check clientHello informations */
1500 if (SSL_early_callback_ctx_extension_get(ctx, TLSEXT_TYPE_signature_algorithms, &extension_data, &extension_len)) {
1501 CBS_init(&extension, extension_data, extension_len);
1502
1503 if (!CBS_get_u16_length_prefixed(&extension, &sig_algs)
1504 || CBS_len(&sig_algs) == 0
1505 || CBS_len(&extension) != 0) {
1506 goto abort;
1507 }
1508 if (CBS_len(&sig_algs) % 2 != 0) {
1509 goto abort;
1510 }
1511 while (CBS_len(&sig_algs) != 0) {
1512 if (!CBS_get_u8(&sig_algs, &hash)
1513 || !CBS_get_u8(&sig_algs, &sign)) {
1514 goto abort;
1515 }
1516 switch (sign) {
1517 case TLSEXT_signature_rsa:
1518 has_rsa = 1;
1519 break;
1520 case TLSEXT_signature_ecdsa:
1521 has_ecdsa_sig = 1;
1522 break;
1523 default:
1524 continue;
1525 }
1526 if (has_ecdsa_sig && has_rsa)
1527 break;
1528 }
1529 } else {
1530 /* without TLSEXT_TYPE_signature_algorithms extension (< TLS 1.2) */
1531 has_rsa = 1;
1532 }
1533 if (has_ecdsa_sig) { /* in very rare case: has ecdsa sign but not a ECDSA cipher */
1534 CBS_init(&cipher_suites, ctx->cipher_suites, ctx->cipher_suites_len);
1535
1536 while (CBS_len(&cipher_suites) != 0) {
1537 if (!CBS_get_u16(&cipher_suites, &cipher_suite)) {
1538 goto abort;
1539 }
1540 cipher = SSL_get_cipher_by_value(cipher_suite);
1541 if (cipher && SSL_CIPHER_is_ECDSA(cipher)) {
1542 has_ecdsa = 1;
1543 break;
1544 }
1545 }
1546 }
1547
1548 servername = CBS_data(&host_name);
1549 for (i = 0; i < trash.size && i < CBS_len(&host_name); i++) {
1550 trash.str[i] = tolower(servername[i]);
1551 if (!wildp && (trash.str[i] == '.'))
1552 wildp = &trash.str[i];
1553 }
1554 trash.str[i] = 0;
1555
1556 /* lookup in full qualified names */
1557 node = ebst_lookup(&s->sni_ctx, trash.str);
1558
1559 /* lookup a not neg filter */
1560 for (n = node; n; n = ebmb_next_dup(n)) {
1561 if (!container_of(n, struct sni_ctx, name)->neg) {
1562 switch(container_of(n, struct sni_ctx, name)->key_sig) {
1563 case TLSEXT_signature_ecdsa:
1564 if (has_ecdsa) {
1565 node_ecdsa = n;
1566 goto find_one;
1567 }
1568 break;
1569 case TLSEXT_signature_rsa:
1570 if (has_rsa && !node_rsa) {
1571 node_rsa = n;
1572 if (!has_ecdsa)
1573 goto find_one;
1574 }
1575 break;
1576 default: /* TLSEXT_signature_anonymous */
1577 if (!node_anonymous)
1578 node_anonymous = n;
1579 break;
1580 }
1581 }
1582 }
1583 if (wildp) {
1584 /* lookup in wildcards names */
1585 node = ebst_lookup(&s->sni_w_ctx, wildp);
1586 for (n = node; n; n = ebmb_next_dup(n)) {
1587 if (!container_of(n, struct sni_ctx, name)->neg) {
1588 switch(container_of(n, struct sni_ctx, name)->key_sig) {
1589 case TLSEXT_signature_ecdsa:
1590 if (has_ecdsa) {
1591 node_ecdsa = n;
1592 goto find_one;
1593 }
1594 break;
1595 case TLSEXT_signature_rsa:
1596 if (has_rsa && !node_rsa) {
1597 node_rsa = n;
1598 if (!has_ecdsa)
1599 goto find_one;
1600 }
1601 break;
1602 default: /* TLSEXT_signature_anonymous */
1603 if (!node_anonymous)
1604 node_anonymous = n;
1605 break;
1606 }
1607 }
1608 }
1609 }
1610 find_one:
1611 /* select by key_signature priority order */
1612 node = node_ecdsa ? node_ecdsa : (node_rsa ? node_rsa : node_anonymous);
1613
1614 if (node) {
1615 /* switch ctx */
1616 SSL_set_SSL_CTX(ctx->ssl, container_of(node, struct sni_ctx, name)->ctx);
1617 return 1;
1618 }
1619 if (!s->strict_sni)
1620 /* no certificate match, is the default_ctx */
1621 /* the client will alert (was SSL_TLSEXT_ERR_ALERT_WARNING, ignored by Boring) */
1622 return 1;
1623 abort:
1624 /* abort handshake (was SSL_TLSEXT_ERR_ALERT_FATAL) */
1625 conn->err_code = CO_ER_SSL_HANDSHAKE;
1626 return -1;
1627}
1628
1629#else /* OPENSSL_IS_BORINGSSL */
1630
Emeric Brunfc0421f2012-09-07 17:30:07 +02001631/* Sets the SSL ctx of <ssl> to match the advertised server name. Returns a
1632 * warning when no match is found, which implies the default (first) cert
1633 * will keep being used.
1634 */
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +01001635static int ssl_sock_switchctx_cbk(SSL *ssl, int *al, void *priv)
Emeric Brunfc0421f2012-09-07 17:30:07 +02001636{
1637 const char *servername;
1638 const char *wildp = NULL;
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001639 struct ebmb_node *node, *n;
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +01001640 struct bind_conf *s = priv;
Emeric Brunfc0421f2012-09-07 17:30:07 +02001641 int i;
1642 (void)al; /* shut gcc stupid warning */
1643
1644 servername = SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name);
Emmanuel Hocdet65623372013-01-24 17:17:15 +01001645 if (!servername) {
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +01001646#if (!defined SSL_NO_GENERATE_CERTIFICATES)
Willy Tarreauf6721452015-07-07 18:04:38 +02001647 if (s->generate_certs) {
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02001648 struct connection *conn = SSL_get_app_data(ssl);
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001649 unsigned int key;
Willy Tarreauf6721452015-07-07 18:04:38 +02001650 SSL_CTX *ctx;
Christopher Faulet30548802015-06-11 13:39:32 +02001651
Willy Tarreauf6721452015-07-07 18:04:38 +02001652 conn_get_to_addr(conn);
1653 if (conn->flags & CO_FL_ADDR_TO_SET) {
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001654 key = ssl_sock_generated_cert_key(&conn->addr.to, get_addr_len(&conn->addr.to));
1655 ctx = ssl_sock_get_generated_cert(key, s);
Willy Tarreauf6721452015-07-07 18:04:38 +02001656 if (ctx) {
1657 /* switch ctx */
1658 SSL_set_SSL_CTX(ssl, ctx);
1659 return SSL_TLSEXT_ERR_OK;
1660 }
Christopher Faulet30548802015-06-11 13:39:32 +02001661 }
1662 }
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +01001663#endif
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001664 return (s->strict_sni ?
1665 SSL_TLSEXT_ERR_ALERT_FATAL :
Emmanuel Hocdet79274e22013-05-31 12:47:44 +02001666 SSL_TLSEXT_ERR_NOACK);
Emmanuel Hocdet65623372013-01-24 17:17:15 +01001667 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02001668
Willy Tarreau19d14ef2012-10-29 16:51:55 +01001669 for (i = 0; i < trash.size; i++) {
Emeric Brunfc0421f2012-09-07 17:30:07 +02001670 if (!servername[i])
1671 break;
Willy Tarreau19d14ef2012-10-29 16:51:55 +01001672 trash.str[i] = tolower(servername[i]);
1673 if (!wildp && (trash.str[i] == '.'))
1674 wildp = &trash.str[i];
Emeric Brunfc0421f2012-09-07 17:30:07 +02001675 }
Willy Tarreau19d14ef2012-10-29 16:51:55 +01001676 trash.str[i] = 0;
Emeric Brunfc0421f2012-09-07 17:30:07 +02001677
1678 /* lookup in full qualified names */
Willy Tarreau19d14ef2012-10-29 16:51:55 +01001679 node = ebst_lookup(&s->sni_ctx, trash.str);
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001680
1681 /* lookup a not neg filter */
1682 for (n = node; n; n = ebmb_next_dup(n)) {
1683 if (!container_of(n, struct sni_ctx, name)->neg) {
1684 node = n;
1685 break;
Emmanuel Hocdet65623372013-01-24 17:17:15 +01001686 }
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001687 }
1688 if (!node && wildp) {
1689 /* lookup in wildcards names */
Emeric Brunfc0421f2012-09-07 17:30:07 +02001690 node = ebst_lookup(&s->sni_w_ctx, wildp);
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001691 }
1692 if (!node || container_of(node, struct sni_ctx, name)->neg) {
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +01001693#if (!defined SSL_NO_GENERATE_CERTIFICATES)
Christopher Faulet31af49d2015-06-09 17:29:50 +02001694 SSL_CTX *ctx;
Christopher Faulet31af49d2015-06-09 17:29:50 +02001695 if (s->generate_certs &&
Christopher Faulet7969a332015-10-09 11:15:03 +02001696 (ctx = ssl_sock_generate_certificate(servername, s, ssl))) {
Christopher Faulet31af49d2015-06-09 17:29:50 +02001697 /* switch ctx */
Christopher Faulet31af49d2015-06-09 17:29:50 +02001698 return SSL_TLSEXT_ERR_OK;
1699 }
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +01001700#endif
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001701 return (s->strict_sni ?
1702 SSL_TLSEXT_ERR_ALERT_FATAL :
1703 SSL_TLSEXT_ERR_ALERT_WARNING);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001704 }
1705
1706 /* switch ctx */
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001707 SSL_set_SSL_CTX(ssl, container_of(node, struct sni_ctx, name)->ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001708 return SSL_TLSEXT_ERR_OK;
1709}
Emmanuel Hocdet05942112017-02-20 16:11:50 +01001710#endif /* (!) OPENSSL_IS_BORINGSSL */
Emeric Brunfc0421f2012-09-07 17:30:07 +02001711#endif /* SSL_CTRL_SET_TLSEXT_HOSTNAME */
1712
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001713#ifndef OPENSSL_NO_DH
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001714
1715static DH * ssl_get_dh_1024(void)
1716{
Remi Gacogned3a341a2015-05-29 16:26:17 +02001717 static unsigned char dh1024_p[]={
1718 0xFA,0xF9,0x2A,0x22,0x2A,0xA7,0x7F,0xE1,0x67,0x4E,0x53,0xF7,
1719 0x56,0x13,0xC3,0xB1,0xE3,0x29,0x6B,0x66,0x31,0x6A,0x7F,0xB3,
1720 0xC2,0x68,0x6B,0xCB,0x1D,0x57,0x39,0x1D,0x1F,0xFF,0x1C,0xC9,
1721 0xA6,0xA4,0x98,0x82,0x31,0x5D,0x25,0xFF,0x8A,0xE0,0x73,0x96,
1722 0x81,0xC8,0x83,0x79,0xC1,0x5A,0x04,0xF8,0x37,0x0D,0xA8,0x3D,
1723 0xAE,0x74,0xBC,0xDB,0xB6,0xA4,0x75,0xD9,0x71,0x8A,0xA0,0x17,
1724 0x9E,0x2D,0xC8,0xA8,0xDF,0x2C,0x5F,0x82,0x95,0xF8,0x92,0x9B,
1725 0xA7,0x33,0x5F,0x89,0x71,0xC8,0x2D,0x6B,0x18,0x86,0xC4,0x94,
1726 0x22,0xA5,0x52,0x8D,0xF6,0xF6,0xD2,0x37,0x92,0x0F,0xA5,0xCC,
1727 0xDB,0x7B,0x1D,0x3D,0xA1,0x31,0xB7,0x80,0x8F,0x0B,0x67,0x5E,
1728 0x36,0xA5,0x60,0x0C,0xF1,0x95,0x33,0x8B,
1729 };
1730 static unsigned char dh1024_g[]={
1731 0x02,
1732 };
1733
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02001734 BIGNUM *p;
1735 BIGNUM *g;
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001736 DH *dh = DH_new();
1737 if (dh) {
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02001738 p = BN_bin2bn(dh1024_p, sizeof dh1024_p, NULL);
1739 g = BN_bin2bn(dh1024_g, sizeof dh1024_g, NULL);
Remi Gacogned3a341a2015-05-29 16:26:17 +02001740
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02001741 if (!p || !g) {
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001742 DH_free(dh);
1743 dh = NULL;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02001744 } else {
1745 DH_set0_pqg(dh, p, NULL, g);
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001746 }
1747 }
1748 return dh;
1749}
1750
1751static DH *ssl_get_dh_2048(void)
1752{
Remi Gacogned3a341a2015-05-29 16:26:17 +02001753 static unsigned char dh2048_p[]={
1754 0xEC,0x86,0xF8,0x70,0xA0,0x33,0x16,0xEC,0x05,0x1A,0x73,0x59,
1755 0xCD,0x1F,0x8B,0xF8,0x29,0xE4,0xD2,0xCF,0x52,0xDD,0xC2,0x24,
1756 0x8D,0xB5,0x38,0x9A,0xFB,0x5C,0xA4,0xE4,0xB2,0xDA,0xCE,0x66,
1757 0x50,0x74,0xA6,0x85,0x4D,0x4B,0x1D,0x30,0xB8,0x2B,0xF3,0x10,
1758 0xE9,0xA7,0x2D,0x05,0x71,0xE7,0x81,0xDF,0x8B,0x59,0x52,0x3B,
1759 0x5F,0x43,0x0B,0x68,0xF1,0xDB,0x07,0xBE,0x08,0x6B,0x1B,0x23,
1760 0xEE,0x4D,0xCC,0x9E,0x0E,0x43,0xA0,0x1E,0xDF,0x43,0x8C,0xEC,
1761 0xBE,0xBE,0x90,0xB4,0x51,0x54,0xB9,0x2F,0x7B,0x64,0x76,0x4E,
1762 0x5D,0xD4,0x2E,0xAE,0xC2,0x9E,0xAE,0x51,0x43,0x59,0xC7,0x77,
1763 0x9C,0x50,0x3C,0x0E,0xED,0x73,0x04,0x5F,0xF1,0x4C,0x76,0x2A,
1764 0xD8,0xF8,0xCF,0xFC,0x34,0x40,0xD1,0xB4,0x42,0x61,0x84,0x66,
1765 0x42,0x39,0x04,0xF8,0x68,0xB2,0x62,0xD7,0x55,0xED,0x1B,0x74,
1766 0x75,0x91,0xE0,0xC5,0x69,0xC1,0x31,0x5C,0xDB,0x7B,0x44,0x2E,
1767 0xCE,0x84,0x58,0x0D,0x1E,0x66,0x0C,0xC8,0x44,0x9E,0xFD,0x40,
1768 0x08,0x67,0x5D,0xFB,0xA7,0x76,0x8F,0x00,0x11,0x87,0xE9,0x93,
1769 0xF9,0x7D,0xC4,0xBC,0x74,0x55,0x20,0xD4,0x4A,0x41,0x2F,0x43,
1770 0x42,0x1A,0xC1,0xF2,0x97,0x17,0x49,0x27,0x37,0x6B,0x2F,0x88,
1771 0x7E,0x1C,0xA0,0xA1,0x89,0x92,0x27,0xD9,0x56,0x5A,0x71,0xC1,
1772 0x56,0x37,0x7E,0x3A,0x9D,0x05,0xE7,0xEE,0x5D,0x8F,0x82,0x17,
1773 0xBC,0xE9,0xC2,0x93,0x30,0x82,0xF9,0xF4,0xC9,0xAE,0x49,0xDB,
1774 0xD0,0x54,0xB4,0xD9,0x75,0x4D,0xFA,0x06,0xB8,0xD6,0x38,0x41,
1775 0xB7,0x1F,0x77,0xF3,
1776 };
1777 static unsigned char dh2048_g[]={
1778 0x02,
1779 };
1780
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02001781 BIGNUM *p;
1782 BIGNUM *g;
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001783 DH *dh = DH_new();
1784 if (dh) {
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02001785 p = BN_bin2bn(dh2048_p, sizeof dh2048_p, NULL);
1786 g = BN_bin2bn(dh2048_g, sizeof dh2048_g, NULL);
Remi Gacogned3a341a2015-05-29 16:26:17 +02001787
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02001788 if (!p || !g) {
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001789 DH_free(dh);
1790 dh = NULL;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02001791 } else {
1792 DH_set0_pqg(dh, p, NULL, g);
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001793 }
1794 }
1795 return dh;
1796}
1797
1798static DH *ssl_get_dh_4096(void)
1799{
Remi Gacogned3a341a2015-05-29 16:26:17 +02001800 static unsigned char dh4096_p[]={
1801 0xDE,0x16,0x94,0xCD,0x99,0x58,0x07,0xF1,0xF7,0x32,0x96,0x11,
1802 0x04,0x82,0xD4,0x84,0x72,0x80,0x99,0x06,0xCA,0xF0,0xA3,0x68,
1803 0x07,0xCE,0x64,0x50,0xE7,0x74,0x45,0x20,0x80,0x5E,0x4D,0xAD,
1804 0xA5,0xB6,0xED,0xFA,0x80,0x6C,0x3B,0x35,0xC4,0x9A,0x14,0x6B,
1805 0x32,0xBB,0xFD,0x1F,0x17,0x8E,0xB7,0x1F,0xD6,0xFA,0x3F,0x7B,
1806 0xEE,0x16,0xA5,0x62,0x33,0x0D,0xED,0xBC,0x4E,0x58,0xE5,0x47,
1807 0x4D,0xE9,0xAB,0x8E,0x38,0xD3,0x6E,0x90,0x57,0xE3,0x22,0x15,
1808 0x33,0xBD,0xF6,0x43,0x45,0xB5,0x10,0x0A,0xBE,0x2C,0xB4,0x35,
1809 0xB8,0x53,0x8D,0xAD,0xFB,0xA7,0x1F,0x85,0x58,0x41,0x7A,0x79,
1810 0x20,0x68,0xB3,0xE1,0x3D,0x08,0x76,0xBF,0x86,0x0D,0x49,0xE3,
1811 0x82,0x71,0x8C,0xB4,0x8D,0x81,0x84,0xD4,0xE7,0xBE,0x91,0xDC,
1812 0x26,0x39,0x48,0x0F,0x35,0xC4,0xCA,0x65,0xE3,0x40,0x93,0x52,
1813 0x76,0x58,0x7D,0xDD,0x51,0x75,0xDC,0x69,0x61,0xBF,0x47,0x2C,
1814 0x16,0x68,0x2D,0xC9,0x29,0xD3,0xE6,0xC0,0x99,0x48,0xA0,0x9A,
1815 0xC8,0x78,0xC0,0x6D,0x81,0x67,0x12,0x61,0x3F,0x71,0xBA,0x41,
1816 0x1F,0x6C,0x89,0x44,0x03,0xBA,0x3B,0x39,0x60,0xAA,0x28,0x55,
1817 0x59,0xAE,0xB8,0xFA,0xCB,0x6F,0xA5,0x1A,0xF7,0x2B,0xDD,0x52,
1818 0x8A,0x8B,0xE2,0x71,0xA6,0x5E,0x7E,0xD8,0x2E,0x18,0xE0,0x66,
1819 0xDF,0xDD,0x22,0x21,0x99,0x52,0x73,0xA6,0x33,0x20,0x65,0x0E,
1820 0x53,0xE7,0x6B,0x9B,0xC5,0xA3,0x2F,0x97,0x65,0x76,0xD3,0x47,
1821 0x23,0x77,0x12,0xB6,0x11,0x7B,0x24,0xED,0xF1,0xEF,0xC0,0xE2,
1822 0xA3,0x7E,0x67,0x05,0x3E,0x96,0x4D,0x45,0xC2,0x18,0xD1,0x73,
1823 0x9E,0x07,0xF3,0x81,0x6E,0x52,0x63,0xF6,0x20,0x76,0xB9,0x13,
1824 0xD2,0x65,0x30,0x18,0x16,0x09,0x16,0x9E,0x8F,0xF1,0xD2,0x10,
1825 0x5A,0xD3,0xD4,0xAF,0x16,0x61,0xDA,0x55,0x2E,0x18,0x5E,0x14,
1826 0x08,0x54,0x2E,0x2A,0x25,0xA2,0x1A,0x9B,0x8B,0x32,0xA9,0xFD,
1827 0xC2,0x48,0x96,0xE1,0x80,0xCA,0xE9,0x22,0x17,0xBB,0xCE,0x3E,
1828 0x9E,0xED,0xC7,0xF1,0x1F,0xEC,0x17,0x21,0xDC,0x7B,0x82,0x48,
1829 0x8E,0xBB,0x4B,0x9D,0x5B,0x04,0x04,0xDA,0xDB,0x39,0xDF,0x01,
1830 0x40,0xC3,0xAA,0x26,0x23,0x89,0x75,0xC6,0x0B,0xD0,0xA2,0x60,
1831 0x6A,0xF1,0xCC,0x65,0x18,0x98,0x1B,0x52,0xD2,0x74,0x61,0xCC,
1832 0xBD,0x60,0xAE,0xA3,0xA0,0x66,0x6A,0x16,0x34,0x92,0x3F,0x41,
1833 0x40,0x31,0x29,0xC0,0x2C,0x63,0xB2,0x07,0x8D,0xEB,0x94,0xB8,
1834 0xE8,0x47,0x92,0x52,0x93,0x6A,0x1B,0x7E,0x1A,0x61,0xB3,0x1B,
1835 0xF0,0xD6,0x72,0x9B,0xF1,0xB0,0xAF,0xBF,0x3E,0x65,0xEF,0x23,
1836 0x1D,0x6F,0xFF,0x70,0xCD,0x8A,0x4C,0x8A,0xA0,0x72,0x9D,0xBE,
1837 0xD4,0xBB,0x24,0x47,0x4A,0x68,0xB5,0xF5,0xC6,0xD5,0x7A,0xCD,
1838 0xCA,0x06,0x41,0x07,0xAD,0xC2,0x1E,0xE6,0x54,0xA7,0xAD,0x03,
1839 0xD9,0x12,0xC1,0x9C,0x13,0xB1,0xC9,0x0A,0x43,0x8E,0x1E,0x08,
1840 0xCE,0x50,0x82,0x73,0x5F,0xA7,0x55,0x1D,0xD9,0x59,0xAC,0xB5,
1841 0xEA,0x02,0x7F,0x6C,0x5B,0x74,0x96,0x98,0x67,0x24,0xA3,0x0F,
1842 0x15,0xFC,0xA9,0x7D,0x3E,0x67,0xD1,0x70,0xF8,0x97,0xF3,0x67,
1843 0xC5,0x8C,0x88,0x44,0x08,0x02,0xC7,0x2B,
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001844 };
Remi Gacogned3a341a2015-05-29 16:26:17 +02001845 static unsigned char dh4096_g[]={
1846 0x02,
1847 };
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001848
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02001849 BIGNUM *p;
1850 BIGNUM *g;
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001851 DH *dh = DH_new();
1852 if (dh) {
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02001853 p = BN_bin2bn(dh4096_p, sizeof dh4096_p, NULL);
1854 g = BN_bin2bn(dh4096_g, sizeof dh4096_g, NULL);
Remi Gacogned3a341a2015-05-29 16:26:17 +02001855
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02001856 if (!p || !g) {
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001857 DH_free(dh);
1858 dh = NULL;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02001859 } else {
1860 DH_set0_pqg(dh, p, NULL, g);
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001861 }
1862 }
1863 return dh;
1864}
1865
1866/* Returns Diffie-Hellman parameters matching the private key length
Willy Tarreauef934602016-12-22 23:12:01 +01001867 but not exceeding global_ssl.default_dh_param */
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001868static DH *ssl_get_tmp_dh(SSL *ssl, int export, int keylen)
1869{
1870 DH *dh = NULL;
1871 EVP_PKEY *pkey = SSL_get_privatekey(ssl);
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02001872 int type;
1873
1874 type = pkey ? EVP_PKEY_base_id(pkey) : EVP_PKEY_NONE;
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001875
1876 /* The keylen supplied by OpenSSL can only be 512 or 1024.
1877 See ssl3_send_server_key_exchange() in ssl/s3_srvr.c
1878 */
1879 if (type == EVP_PKEY_RSA || type == EVP_PKEY_DSA) {
1880 keylen = EVP_PKEY_bits(pkey);
1881 }
1882
Willy Tarreauef934602016-12-22 23:12:01 +01001883 if (keylen > global_ssl.default_dh_param) {
1884 keylen = global_ssl.default_dh_param;
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001885 }
1886
Remi Gacogned3a341a2015-05-29 16:26:17 +02001887 if (keylen >= 4096) {
Remi Gacogne8de54152014-07-15 11:36:40 +02001888 dh = local_dh_4096;
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001889 }
1890 else if (keylen >= 2048) {
Remi Gacogne8de54152014-07-15 11:36:40 +02001891 dh = local_dh_2048;
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001892 }
1893 else {
Remi Gacogne8de54152014-07-15 11:36:40 +02001894 dh = local_dh_1024;
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001895 }
1896
1897 return dh;
1898}
1899
Remi Gacogne47783ef2015-05-29 15:53:22 +02001900static DH * ssl_sock_get_dh_from_file(const char *filename)
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001901{
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001902 DH *dh = NULL;
Remi Gacogne47783ef2015-05-29 15:53:22 +02001903 BIO *in = BIO_new(BIO_s_file());
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001904
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001905 if (in == NULL)
1906 goto end;
1907
Remi Gacogne47783ef2015-05-29 15:53:22 +02001908 if (BIO_read_filename(in, filename) <= 0)
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001909 goto end;
1910
Remi Gacogne47783ef2015-05-29 15:53:22 +02001911 dh = PEM_read_bio_DHparams(in, NULL, NULL, NULL);
1912
1913end:
1914 if (in)
1915 BIO_free(in);
1916
1917 return dh;
1918}
1919
1920int ssl_sock_load_global_dh_param_from_file(const char *filename)
1921{
1922 global_dh = ssl_sock_get_dh_from_file(filename);
1923
1924 if (global_dh) {
1925 return 0;
1926 }
1927
1928 return -1;
1929}
1930
1931/* Loads Diffie-Hellman parameter from a file. Returns 1 if loaded, else -1
1932 if an error occured, and 0 if parameter not found. */
1933int ssl_sock_load_dh_params(SSL_CTX *ctx, const char *file)
1934{
1935 int ret = -1;
1936 DH *dh = ssl_sock_get_dh_from_file(file);
1937
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001938 if (dh) {
1939 ret = 1;
1940 SSL_CTX_set_tmp_dh(ctx, dh);
Remi Gacogne4f902b82015-05-28 16:23:00 +02001941
1942 if (ssl_dh_ptr_index >= 0) {
1943 /* store a pointer to the DH params to avoid complaining about
1944 ssl-default-dh-param not being set for this SSL_CTX */
1945 SSL_CTX_set_ex_data(ctx, ssl_dh_ptr_index, dh);
1946 }
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001947 }
Remi Gacogne47783ef2015-05-29 15:53:22 +02001948 else if (global_dh) {
1949 SSL_CTX_set_tmp_dh(ctx, global_dh);
1950 ret = 0; /* DH params not found */
1951 }
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001952 else {
Emeric Brun41fdb3c2013-04-26 11:05:44 +02001953 /* Clear openssl global errors stack */
1954 ERR_clear_error();
1955
Willy Tarreauef934602016-12-22 23:12:01 +01001956 if (global_ssl.default_dh_param <= 1024) {
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001957 /* we are limited to DH parameter of 1024 bits anyway */
Remi Gacognec7e12632016-07-02 16:26:10 +02001958 if (local_dh_1024 == NULL)
1959 local_dh_1024 = ssl_get_dh_1024();
1960
Remi Gacogne8de54152014-07-15 11:36:40 +02001961 if (local_dh_1024 == NULL)
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001962 goto end;
Willy Tarreau6e774b42014-04-25 21:35:23 +02001963
Remi Gacogne8de54152014-07-15 11:36:40 +02001964 SSL_CTX_set_tmp_dh(ctx, local_dh_1024);
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001965 }
1966 else {
1967 SSL_CTX_set_tmp_dh_callback(ctx, ssl_get_tmp_dh);
1968 }
Willy Tarreau6e774b42014-04-25 21:35:23 +02001969
Emeric Brun41fdb3c2013-04-26 11:05:44 +02001970 ret = 0; /* DH params not found */
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001971 }
Emeric Brun644cde02012-12-14 11:21:13 +01001972
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001973end:
1974 if (dh)
1975 DH_free(dh);
1976
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001977 return ret;
1978}
1979#endif
1980
Emmanuel Hocdet05942112017-02-20 16:11:50 +01001981static int ssl_sock_add_cert_sni(SSL_CTX *ctx, struct bind_conf *s, struct ssl_bind_conf *conf,
1982 uint8_t key_sig, char *name, int order)
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001983{
1984 struct sni_ctx *sc;
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001985 int wild = 0, neg = 0;
Thierry FOURNIER / OZON.IO07c3d782016-10-06 10:56:48 +02001986 struct ebmb_node *node;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001987
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001988 if (*name == '!') {
1989 neg = 1;
1990 name++;
1991 }
1992 if (*name == '*') {
1993 wild = 1;
1994 name++;
1995 }
1996 /* !* filter is a nop */
1997 if (neg && wild)
1998 return order;
1999 if (*name) {
2000 int j, len;
2001 len = strlen(name);
Thierry FOURNIER / OZON.IO07c3d782016-10-06 10:56:48 +02002002 for (j = 0; j < len && j < trash.size; j++)
2003 trash.str[j] = tolower(name[j]);
2004 if (j >= trash.size)
2005 return order;
2006 trash.str[j] = 0;
2007
2008 /* Check for duplicates. */
2009 if (wild)
2010 node = ebst_lookup(&s->sni_w_ctx, trash.str);
2011 else
2012 node = ebst_lookup(&s->sni_ctx, trash.str);
2013 for (; node; node = ebmb_next_dup(node)) {
2014 sc = ebmb_entry(node, struct sni_ctx, name);
Emmanuel Hocdet05942112017-02-20 16:11:50 +01002015 if (sc->ctx == ctx && sc->conf == conf &&
2016 sc->key_sig == key_sig && sc->neg == neg)
Thierry FOURNIER / OZON.IO07c3d782016-10-06 10:56:48 +02002017 return order;
2018 }
2019
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002020 sc = malloc(sizeof(struct sni_ctx) + len + 1);
Thierry FOURNIER / OZON.IO7a3bd3b2016-10-06 10:35:29 +02002021 if (!sc)
2022 return order;
Thierry FOURNIER / OZON.IO07c3d782016-10-06 10:56:48 +02002023 memcpy(sc->name.key, trash.str, len + 1);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002024 sc->ctx = ctx;
Emmanuel Hocdet98263292016-12-29 18:26:15 +01002025 sc->conf = conf;
Emmanuel Hocdet05942112017-02-20 16:11:50 +01002026 sc->key_sig = key_sig;
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02002027 sc->order = order++;
2028 sc->neg = neg;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002029 if (wild)
2030 ebst_insert(&s->sni_w_ctx, &sc->name);
2031 else
2032 ebst_insert(&s->sni_ctx, &sc->name);
2033 }
2034 return order;
2035}
2036
yanbzhu488a4d22015-12-01 15:16:07 -05002037
2038/* The following code is used for loading multiple crt files into
2039 * SSL_CTX's based on CN/SAN
2040 */
Luca Pizzamiglio578b1692016-12-12 10:56:56 +01002041#if OPENSSL_VERSION_NUMBER >= 0x1000200fL && !defined(LIBRESSL_VERSION_NUMBER)
yanbzhu488a4d22015-12-01 15:16:07 -05002042/* This is used to preload the certifcate, private key
2043 * and Cert Chain of a file passed in via the crt
2044 * argument
2045 *
2046 * This way, we do not have to read the file multiple times
2047 */
2048struct cert_key_and_chain {
2049 X509 *cert;
2050 EVP_PKEY *key;
2051 unsigned int num_chain_certs;
2052 /* This is an array of X509 pointers */
2053 X509 **chain_certs;
2054};
2055
yanbzhu08ce6ab2015-12-02 13:01:29 -05002056#define SSL_SOCK_POSSIBLE_KT_COMBOS (1<<(SSL_SOCK_NUM_KEYTYPES))
2057
2058struct key_combo_ctx {
2059 SSL_CTX *ctx;
2060 int order;
2061};
2062
2063/* Map used for processing multiple keypairs for a single purpose
2064 *
2065 * This maps CN/SNI name to certificate type
2066 */
2067struct sni_keytype {
2068 int keytypes; /* BITMASK for keytypes */
2069 struct ebmb_node name; /* node holding the servername value */
2070};
2071
2072
yanbzhu488a4d22015-12-01 15:16:07 -05002073/* Frees the contents of a cert_key_and_chain
2074 */
2075static void ssl_sock_free_cert_key_and_chain_contents(struct cert_key_and_chain *ckch)
2076{
2077 int i;
2078
2079 if (!ckch)
2080 return;
2081
2082 /* Free the certificate and set pointer to NULL */
2083 if (ckch->cert)
2084 X509_free(ckch->cert);
2085 ckch->cert = NULL;
2086
2087 /* Free the key and set pointer to NULL */
2088 if (ckch->key)
2089 EVP_PKEY_free(ckch->key);
2090 ckch->key = NULL;
2091
2092 /* Free each certificate in the chain */
2093 for (i = 0; i < ckch->num_chain_certs; i++) {
2094 if (ckch->chain_certs[i])
2095 X509_free(ckch->chain_certs[i]);
2096 }
2097
2098 /* Free the chain obj itself and set to NULL */
2099 if (ckch->num_chain_certs > 0) {
2100 free(ckch->chain_certs);
2101 ckch->num_chain_certs = 0;
2102 ckch->chain_certs = NULL;
2103 }
2104
2105}
2106
2107/* checks if a key and cert exists in the ckch
2108 */
2109static int ssl_sock_is_ckch_valid(struct cert_key_and_chain *ckch)
2110{
2111 return (ckch->cert != NULL && ckch->key != NULL);
2112}
2113
2114
2115/* Loads the contents of a crt file (path) into a cert_key_and_chain
2116 * This allows us to carry the contents of the file without having to
2117 * read the file multiple times.
2118 *
2119 * returns:
2120 * 0 on Success
2121 * 1 on SSL Failure
2122 * 2 on file not found
2123 */
2124static int ssl_sock_load_crt_file_into_ckch(const char *path, struct cert_key_and_chain *ckch, char **err)
2125{
2126
2127 BIO *in;
2128 X509 *ca = NULL;
2129 int ret = 1;
2130
2131 ssl_sock_free_cert_key_and_chain_contents(ckch);
2132
2133 in = BIO_new(BIO_s_file());
2134 if (in == NULL)
2135 goto end;
2136
2137 if (BIO_read_filename(in, path) <= 0)
2138 goto end;
2139
yanbzhu488a4d22015-12-01 15:16:07 -05002140 /* Read Private Key */
2141 ckch->key = PEM_read_bio_PrivateKey(in, NULL, NULL, NULL);
2142 if (ckch->key == NULL) {
2143 memprintf(err, "%sunable to load private key from file '%s'.\n",
2144 err && *err ? *err : "", path);
2145 goto end;
2146 }
2147
Willy Tarreaubb137a82016-04-06 19:02:38 +02002148 /* Seek back to beginning of file */
Thierry FOURNIER / OZON.IOd44ea3f2016-10-14 00:49:21 +02002149 if (BIO_reset(in) == -1) {
2150 memprintf(err, "%san error occurred while reading the file '%s'.\n",
2151 err && *err ? *err : "", path);
2152 goto end;
2153 }
Willy Tarreaubb137a82016-04-06 19:02:38 +02002154
2155 /* Read Certificate */
2156 ckch->cert = PEM_read_bio_X509_AUX(in, NULL, NULL, NULL);
2157 if (ckch->cert == NULL) {
2158 memprintf(err, "%sunable to load certificate from file '%s'.\n",
2159 err && *err ? *err : "", path);
2160 goto end;
2161 }
2162
yanbzhu488a4d22015-12-01 15:16:07 -05002163 /* Read Certificate Chain */
2164 while ((ca = PEM_read_bio_X509(in, NULL, NULL, NULL))) {
2165 /* Grow the chain certs */
2166 ckch->num_chain_certs++;
2167 ckch->chain_certs = realloc(ckch->chain_certs, (ckch->num_chain_certs * sizeof(X509 *)));
2168
2169 /* use - 1 here since we just incremented it above */
2170 ckch->chain_certs[ckch->num_chain_certs - 1] = ca;
2171 }
2172 ret = ERR_get_error();
2173 if (ret && (ERR_GET_LIB(ret) != ERR_LIB_PEM && ERR_GET_REASON(ret) != PEM_R_NO_START_LINE)) {
2174 memprintf(err, "%sunable to load certificate chain from file '%s'.\n",
2175 err && *err ? *err : "", path);
2176 ret = 1;
2177 goto end;
2178 }
2179
2180 ret = 0;
2181
2182end:
2183
2184 ERR_clear_error();
2185 if (in)
2186 BIO_free(in);
2187
2188 /* Something went wrong in one of the reads */
2189 if (ret != 0)
2190 ssl_sock_free_cert_key_and_chain_contents(ckch);
2191
2192 return ret;
2193}
2194
2195/* Loads the info in ckch into ctx
2196 * Currently, this does not process any information about ocsp, dhparams or
2197 * sctl
2198 * Returns
2199 * 0 on success
2200 * 1 on failure
2201 */
2202static int ssl_sock_put_ckch_into_ctx(const char *path, const struct cert_key_and_chain *ckch, SSL_CTX *ctx, char **err)
2203{
2204 int i = 0;
2205
2206 if (SSL_CTX_use_PrivateKey(ctx, ckch->key) <= 0) {
2207 memprintf(err, "%sunable to load SSL private key into SSL Context '%s'.\n",
2208 err && *err ? *err : "", path);
2209 return 1;
2210 }
2211
2212 if (!SSL_CTX_use_certificate(ctx, ckch->cert)) {
2213 memprintf(err, "%sunable to load SSL certificate into SSL Context '%s'.\n",
2214 err && *err ? *err : "", path);
2215 return 1;
2216 }
2217
yanbzhu488a4d22015-12-01 15:16:07 -05002218 /* Load all certs in the ckch into the ctx_chain for the ssl_ctx */
2219 for (i = 0; i < ckch->num_chain_certs; i++) {
2220 if (!SSL_CTX_add1_chain_cert(ctx, ckch->chain_certs[i])) {
yanbzhu08ce6ab2015-12-02 13:01:29 -05002221 memprintf(err, "%sunable to load chain certificate #%d into SSL Context '%s'. Make sure you are linking against Openssl >= 1.0.2.\n",
2222 err && *err ? *err : "", (i+1), path);
yanbzhu488a4d22015-12-01 15:16:07 -05002223 return 1;
2224 }
2225 }
2226
2227 if (SSL_CTX_check_private_key(ctx) <= 0) {
2228 memprintf(err, "%sinconsistencies between private key and certificate loaded from PEM file '%s'.\n",
2229 err && *err ? *err : "", path);
2230 return 1;
2231 }
2232
2233 return 0;
2234}
2235
yanbzhu08ce6ab2015-12-02 13:01:29 -05002236
2237static void ssl_sock_populate_sni_keytypes_hplr(const char *str, struct eb_root *sni_keytypes, int key_index)
2238{
2239 struct sni_keytype *s_kt = NULL;
2240 struct ebmb_node *node;
2241 int i;
2242
2243 for (i = 0; i < trash.size; i++) {
2244 if (!str[i])
2245 break;
2246 trash.str[i] = tolower(str[i]);
2247 }
2248 trash.str[i] = 0;
2249 node = ebst_lookup(sni_keytypes, trash.str);
2250 if (!node) {
2251 /* CN not found in tree */
2252 s_kt = malloc(sizeof(struct sni_keytype) + i + 1);
2253 /* Using memcpy here instead of strncpy.
2254 * strncpy will cause sig_abrt errors under certain versions of gcc with -O2
2255 * See: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=60792
2256 */
2257 memcpy(s_kt->name.key, trash.str, i+1);
2258 s_kt->keytypes = 0;
2259 ebst_insert(sni_keytypes, &s_kt->name);
2260 } else {
2261 /* CN found in tree */
2262 s_kt = container_of(node, struct sni_keytype, name);
2263 }
2264
2265 /* Mark that this CN has the keytype of key_index via keytypes mask */
2266 s_kt->keytypes |= 1<<key_index;
2267
2268}
2269
2270
2271/* Given a path that does not exist, try to check for path.rsa, path.dsa and path.ecdsa files.
2272 * If any are found, group these files into a set of SSL_CTX*
2273 * based on shared and unique CN and SAN entries. Add these SSL_CTX* to the SNI tree.
2274 *
2275 * This will allow the user to explictly group multiple cert/keys for a single purpose
2276 *
2277 * Returns
2278 * 0 on success
2279 * 1 on failure
2280 */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01002281static int ssl_sock_load_multi_cert(const char *path, struct bind_conf *bind_conf, struct ssl_bind_conf *ssl_conf,
2282 char **sni_filter, int fcount, char **err)
yanbzhu08ce6ab2015-12-02 13:01:29 -05002283{
2284 char fp[MAXPATHLEN+1] = {0};
2285 int n = 0;
2286 int i = 0;
2287 struct cert_key_and_chain certs_and_keys[SSL_SOCK_NUM_KEYTYPES] = { {0} };
2288 struct eb_root sni_keytypes_map = { {0} };
2289 struct ebmb_node *node;
2290 struct ebmb_node *next;
2291 /* Array of SSL_CTX pointers corresponding to each possible combo
2292 * of keytypes
2293 */
2294 struct key_combo_ctx key_combos[SSL_SOCK_POSSIBLE_KT_COMBOS] = { {0} };
2295 int rv = 0;
2296 X509_NAME *xname = NULL;
2297 char *str = NULL;
2298#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
2299 STACK_OF(GENERAL_NAME) *names = NULL;
2300#endif
2301
2302 /* Load all possible certs and keys */
2303 for (n = 0; n < SSL_SOCK_NUM_KEYTYPES; n++) {
2304 struct stat buf;
2305
2306 snprintf(fp, sizeof(fp), "%s.%s", path, SSL_SOCK_KEYTYPE_NAMES[n]);
2307 if (stat(fp, &buf) == 0) {
2308 if (ssl_sock_load_crt_file_into_ckch(fp, &certs_and_keys[n], err) == 1) {
2309 rv = 1;
2310 goto end;
2311 }
2312 }
2313 }
2314
2315 /* Process each ckch and update keytypes for each CN/SAN
2316 * for example, if CN/SAN www.a.com is associated with
2317 * certs with keytype 0 and 2, then at the end of the loop,
2318 * www.a.com will have:
2319 * keyindex = 0 | 1 | 4 = 5
2320 */
2321 for (n = 0; n < SSL_SOCK_NUM_KEYTYPES; n++) {
2322
2323 if (!ssl_sock_is_ckch_valid(&certs_and_keys[n]))
2324 continue;
2325
Emmanuel Hocdetd294aea2016-05-13 11:14:06 +02002326 if (fcount) {
Willy Tarreau24b892f2016-06-20 23:01:57 +02002327 for (i = 0; i < fcount; i++)
Emmanuel Hocdetd294aea2016-05-13 11:14:06 +02002328 ssl_sock_populate_sni_keytypes_hplr(sni_filter[i], &sni_keytypes_map, n);
2329 } else {
2330 /* A lot of the following code is OpenSSL boilerplate for processing CN's and SAN's,
2331 * so the line that contains logic is marked via comments
2332 */
2333 xname = X509_get_subject_name(certs_and_keys[n].cert);
2334 i = -1;
2335 while ((i = X509_NAME_get_index_by_NID(xname, NID_commonName, i)) != -1) {
2336 X509_NAME_ENTRY *entry = X509_NAME_get_entry(xname, i);
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02002337 ASN1_STRING *value;
2338 value = X509_NAME_ENTRY_get_data(entry);
2339 if (ASN1_STRING_to_UTF8((unsigned char **)&str, value) >= 0) {
Emmanuel Hocdetd294aea2016-05-13 11:14:06 +02002340 /* Important line is here */
2341 ssl_sock_populate_sni_keytypes_hplr(str, &sni_keytypes_map, n);
yanbzhu08ce6ab2015-12-02 13:01:29 -05002342
Emmanuel Hocdetd294aea2016-05-13 11:14:06 +02002343 OPENSSL_free(str);
2344 str = NULL;
2345 }
yanbzhu08ce6ab2015-12-02 13:01:29 -05002346 }
yanbzhu08ce6ab2015-12-02 13:01:29 -05002347
Emmanuel Hocdetd294aea2016-05-13 11:14:06 +02002348 /* Do the above logic for each SAN */
yanbzhu08ce6ab2015-12-02 13:01:29 -05002349#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Emmanuel Hocdetd294aea2016-05-13 11:14:06 +02002350 names = X509_get_ext_d2i(certs_and_keys[n].cert, NID_subject_alt_name, NULL, NULL);
2351 if (names) {
2352 for (i = 0; i < sk_GENERAL_NAME_num(names); i++) {
2353 GENERAL_NAME *name = sk_GENERAL_NAME_value(names, i);
yanbzhu08ce6ab2015-12-02 13:01:29 -05002354
Emmanuel Hocdetd294aea2016-05-13 11:14:06 +02002355 if (name->type == GEN_DNS) {
2356 if (ASN1_STRING_to_UTF8((unsigned char **)&str, name->d.dNSName) >= 0) {
2357 /* Important line is here */
2358 ssl_sock_populate_sni_keytypes_hplr(str, &sni_keytypes_map, n);
yanbzhu08ce6ab2015-12-02 13:01:29 -05002359
Emmanuel Hocdetd294aea2016-05-13 11:14:06 +02002360 OPENSSL_free(str);
2361 str = NULL;
2362 }
yanbzhu08ce6ab2015-12-02 13:01:29 -05002363 }
2364 }
2365 }
2366 }
2367#endif /* SSL_CTRL_SET_TLSEXT_HOSTNAME */
2368 }
2369
2370 /* If no files found, return error */
2371 if (eb_is_empty(&sni_keytypes_map)) {
2372 memprintf(err, "%sunable to load SSL certificate file '%s' file does not exist.\n",
2373 err && *err ? *err : "", path);
2374 rv = 1;
2375 goto end;
2376 }
2377
2378 /* We now have a map of CN/SAN to keytypes that are loaded in
2379 * Iterate through the map to create the SSL_CTX's (if needed)
2380 * and add each CTX to the SNI tree
2381 *
2382 * Some math here:
2383 * There are 2^n - 1 possibile combinations, each unique
2384 * combination is denoted by the key in the map. Each key
2385 * has a value between 1 and 2^n - 1. Conveniently, the array
2386 * of SSL_CTX* is sized 2^n. So, we can simply use the i'th
2387 * entry in the array to correspond to the unique combo (key)
2388 * associated with i. This unique key combo (i) will be associated
2389 * with combos[i-1]
2390 */
2391
2392 node = ebmb_first(&sni_keytypes_map);
2393 while (node) {
2394 SSL_CTX *cur_ctx;
Bertrand Jacquin33423092016-11-13 16:37:13 +00002395 char cur_file[MAXPATHLEN+1];
yanbzhu08ce6ab2015-12-02 13:01:29 -05002396
2397 str = (char *)container_of(node, struct sni_keytype, name)->name.key;
2398 i = container_of(node, struct sni_keytype, name)->keytypes;
2399 cur_ctx = key_combos[i-1].ctx;
2400
2401 if (cur_ctx == NULL) {
2402 /* need to create SSL_CTX */
2403 cur_ctx = SSL_CTX_new(SSLv23_server_method());
2404 if (cur_ctx == NULL) {
2405 memprintf(err, "%sunable to allocate SSL context.\n",
2406 err && *err ? *err : "");
2407 rv = 1;
2408 goto end;
2409 }
2410
yanbzhube2774d2015-12-10 15:07:30 -05002411 /* Load all required certs/keys/chains/OCSPs info into SSL_CTX */
yanbzhu08ce6ab2015-12-02 13:01:29 -05002412 for (n = 0; n < SSL_SOCK_NUM_KEYTYPES; n++) {
2413 if (i & (1<<n)) {
2414 /* Key combo contains ckch[n] */
Bertrand Jacquin33423092016-11-13 16:37:13 +00002415 snprintf(cur_file, MAXPATHLEN+1, "%s.%s", path, SSL_SOCK_KEYTYPE_NAMES[n]);
2416 if (ssl_sock_put_ckch_into_ctx(cur_file, &certs_and_keys[n], cur_ctx, err) != 0) {
yanbzhu08ce6ab2015-12-02 13:01:29 -05002417 SSL_CTX_free(cur_ctx);
2418 rv = 1;
2419 goto end;
2420 }
yanbzhube2774d2015-12-10 15:07:30 -05002421
2422#if (defined SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB && !defined OPENSSL_NO_OCSP)
2423 /* Load OCSP Info into context */
Bertrand Jacquin33423092016-11-13 16:37:13 +00002424 if (ssl_sock_load_ocsp(cur_ctx, cur_file) < 0) {
yanbzhube2774d2015-12-10 15:07:30 -05002425 if (err)
2426 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 +00002427 *err ? *err : "", cur_file);
yanbzhube2774d2015-12-10 15:07:30 -05002428 SSL_CTX_free(cur_ctx);
2429 rv = 1;
2430 goto end;
2431 }
2432#endif
yanbzhu08ce6ab2015-12-02 13:01:29 -05002433 }
2434 }
2435
2436 /* Load DH params into the ctx to support DHE keys */
2437#ifndef OPENSSL_NO_DH
2438 if (ssl_dh_ptr_index >= 0)
2439 SSL_CTX_set_ex_data(cur_ctx, ssl_dh_ptr_index, NULL);
2440
2441 rv = ssl_sock_load_dh_params(cur_ctx, NULL);
2442 if (rv < 0) {
2443 if (err)
2444 memprintf(err, "%sunable to load DH parameters from file '%s'.\n",
2445 *err ? *err : "", path);
2446 rv = 1;
2447 goto end;
2448 }
2449#endif
2450
2451 /* Update key_combos */
2452 key_combos[i-1].ctx = cur_ctx;
2453 }
2454
2455 /* Update SNI Tree */
Emmanuel Hocdet05942112017-02-20 16:11:50 +01002456 key_combos[i-1].order = ssl_sock_add_cert_sni(cur_ctx, bind_conf, ssl_conf,
2457 TLSEXT_signature_anonymous, str, key_combos[i-1].order);
yanbzhu08ce6ab2015-12-02 13:01:29 -05002458 node = ebmb_next(node);
2459 }
2460
2461
2462 /* Mark a default context if none exists, using the ctx that has the most shared keys */
2463 if (!bind_conf->default_ctx) {
2464 for (i = SSL_SOCK_POSSIBLE_KT_COMBOS - 1; i >= 0; i--) {
2465 if (key_combos[i].ctx) {
2466 bind_conf->default_ctx = key_combos[i].ctx;
Emmanuel Hocdet98263292016-12-29 18:26:15 +01002467 bind_conf->default_ssl_conf = ssl_conf;
yanbzhu08ce6ab2015-12-02 13:01:29 -05002468 break;
2469 }
2470 }
2471 }
2472
2473end:
2474
2475 if (names)
2476 sk_GENERAL_NAME_pop_free(names, GENERAL_NAME_free);
2477
2478 for (n = 0; n < SSL_SOCK_NUM_KEYTYPES; n++)
2479 ssl_sock_free_cert_key_and_chain_contents(&certs_and_keys[n]);
2480
2481 node = ebmb_first(&sni_keytypes_map);
2482 while (node) {
2483 next = ebmb_next(node);
2484 ebmb_delete(node);
2485 node = next;
2486 }
2487
2488 return rv;
2489}
2490#else
2491/* This is a dummy, that just logs an error and returns error */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01002492static int ssl_sock_load_multi_cert(const char *path, struct bind_conf *bind_conf, struct ssl_bind_conf *ssl_conf,
2493 char **sni_filter, int fcount, char **err)
yanbzhu08ce6ab2015-12-02 13:01:29 -05002494{
2495 memprintf(err, "%sunable to stat SSL certificate from file '%s' : %s.\n",
2496 err && *err ? *err : "", path, strerror(errno));
2497 return 1;
2498}
2499
yanbzhu488a4d22015-12-01 15:16:07 -05002500#endif /* #if OPENSSL_VERSION_NUMBER >= 0x1000200fL: Support for loading multiple certs into a single SSL_CTX */
2501
Emeric Brunfc0421f2012-09-07 17:30:07 +02002502/* Loads a certificate key and CA chain from a file. Returns 0 on error, -1 if
2503 * an early error happens and the caller must call SSL_CTX_free() by itelf.
2504 */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01002505static int ssl_sock_load_cert_chain_file(SSL_CTX *ctx, const char *file, struct bind_conf *s,
2506 struct ssl_bind_conf *ssl_conf, char **sni_filter, int fcount)
Emeric Brunfc0421f2012-09-07 17:30:07 +02002507{
2508 BIO *in;
2509 X509 *x = NULL, *ca;
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02002510 int i, err;
Emeric Brunfc0421f2012-09-07 17:30:07 +02002511 int ret = -1;
2512 int order = 0;
2513 X509_NAME *xname;
2514 char *str;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02002515 pem_password_cb *passwd_cb;
2516 void *passwd_cb_userdata;
Emmanuel Hocdet05942112017-02-20 16:11:50 +01002517 EVP_PKEY *pkey;
2518 uint8_t key_sig = TLSEXT_signature_anonymous;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02002519
Emeric Brunfc0421f2012-09-07 17:30:07 +02002520#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
2521 STACK_OF(GENERAL_NAME) *names;
2522#endif
2523
2524 in = BIO_new(BIO_s_file());
2525 if (in == NULL)
2526 goto end;
2527
2528 if (BIO_read_filename(in, file) <= 0)
2529 goto end;
2530
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02002531
2532 passwd_cb = SSL_CTX_get_default_passwd_cb(ctx);
2533 passwd_cb_userdata = SSL_CTX_get_default_passwd_cb_userdata(ctx);
2534
2535 x = PEM_read_bio_X509_AUX(in, NULL, passwd_cb, passwd_cb_userdata);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002536 if (x == NULL)
2537 goto end;
2538
Emmanuel Hocdet05942112017-02-20 16:11:50 +01002539 pkey = X509_get_pubkey(x);
2540 if (pkey) {
2541 switch(EVP_PKEY_base_id(pkey)) {
2542 case EVP_PKEY_RSA:
2543 key_sig = TLSEXT_signature_rsa;
2544 break;
2545 case EVP_PKEY_EC:
2546 key_sig = TLSEXT_signature_ecdsa;
2547 break;
2548 }
2549 EVP_PKEY_free(pkey);
2550 }
2551
Emeric Brun50bcecc2013-04-22 13:05:23 +02002552 if (fcount) {
2553 while (fcount--)
Emmanuel Hocdet05942112017-02-20 16:11:50 +01002554 order = ssl_sock_add_cert_sni(ctx, s, ssl_conf, key_sig, sni_filter[fcount], order);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002555 }
2556 else {
Emeric Brunfc0421f2012-09-07 17:30:07 +02002557#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002558 names = X509_get_ext_d2i(x, NID_subject_alt_name, NULL, NULL);
2559 if (names) {
2560 for (i = 0; i < sk_GENERAL_NAME_num(names); i++) {
2561 GENERAL_NAME *name = sk_GENERAL_NAME_value(names, i);
2562 if (name->type == GEN_DNS) {
2563 if (ASN1_STRING_to_UTF8((unsigned char **)&str, name->d.dNSName) >= 0) {
Emmanuel Hocdet05942112017-02-20 16:11:50 +01002564 order = ssl_sock_add_cert_sni(ctx, s, ssl_conf, key_sig, str, order);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002565 OPENSSL_free(str);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002566 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02002567 }
2568 }
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002569 sk_GENERAL_NAME_pop_free(names, GENERAL_NAME_free);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002570 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02002571#endif /* SSL_CTRL_SET_TLSEXT_HOSTNAME */
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002572 xname = X509_get_subject_name(x);
2573 i = -1;
2574 while ((i = X509_NAME_get_index_by_NID(xname, NID_commonName, i)) != -1) {
2575 X509_NAME_ENTRY *entry = X509_NAME_get_entry(xname, i);
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02002576 ASN1_STRING *value;
2577
2578 value = X509_NAME_ENTRY_get_data(entry);
2579 if (ASN1_STRING_to_UTF8((unsigned char **)&str, value) >= 0) {
Emmanuel Hocdet05942112017-02-20 16:11:50 +01002580 order = ssl_sock_add_cert_sni(ctx, s, ssl_conf, key_sig, str, order);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002581 OPENSSL_free(str);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002582 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02002583 }
2584 }
2585
2586 ret = 0; /* the caller must not free the SSL_CTX argument anymore */
2587 if (!SSL_CTX_use_certificate(ctx, x))
2588 goto end;
2589
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02002590#ifdef SSL_CTX_clear_extra_chain_certs
2591 SSL_CTX_clear_extra_chain_certs(ctx);
2592#else
Emeric Brunfc0421f2012-09-07 17:30:07 +02002593 if (ctx->extra_certs != NULL) {
2594 sk_X509_pop_free(ctx->extra_certs, X509_free);
2595 ctx->extra_certs = NULL;
2596 }
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02002597#endif
Emeric Brunfc0421f2012-09-07 17:30:07 +02002598
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02002599 while ((ca = PEM_read_bio_X509(in, NULL, passwd_cb, passwd_cb_userdata))) {
Emeric Brunfc0421f2012-09-07 17:30:07 +02002600 if (!SSL_CTX_add_extra_chain_cert(ctx, ca)) {
2601 X509_free(ca);
2602 goto end;
2603 }
2604 }
2605
2606 err = ERR_get_error();
2607 if (!err || (ERR_GET_LIB(err) == ERR_LIB_PEM && ERR_GET_REASON(err) == PEM_R_NO_START_LINE)) {
2608 /* we successfully reached the last cert in the file */
2609 ret = 1;
2610 }
2611 ERR_clear_error();
2612
2613end:
2614 if (x)
2615 X509_free(x);
2616
2617 if (in)
2618 BIO_free(in);
2619
2620 return ret;
2621}
2622
Emmanuel Hocdet98263292016-12-29 18:26:15 +01002623static int ssl_sock_load_cert_file(const char *path, struct bind_conf *bind_conf, struct ssl_bind_conf *ssl_conf,
2624 char **sni_filter, int fcount, char **err)
Emeric Brunfc0421f2012-09-07 17:30:07 +02002625{
2626 int ret;
2627 SSL_CTX *ctx;
2628
2629 ctx = SSL_CTX_new(SSLv23_server_method());
2630 if (!ctx) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02002631 memprintf(err, "%sunable to allocate SSL context for cert '%s'.\n",
2632 err && *err ? *err : "", path);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002633 return 1;
2634 }
2635
2636 if (SSL_CTX_use_PrivateKey_file(ctx, path, SSL_FILETYPE_PEM) <= 0) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02002637 memprintf(err, "%sunable to load SSL private key from PEM file '%s'.\n",
2638 err && *err ? *err : "", path);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002639 SSL_CTX_free(ctx);
2640 return 1;
2641 }
2642
Emmanuel Hocdet98263292016-12-29 18:26:15 +01002643 ret = ssl_sock_load_cert_chain_file(ctx, path, bind_conf, ssl_conf, sni_filter, fcount);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002644 if (ret <= 0) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02002645 memprintf(err, "%sunable to load SSL certificate from PEM file '%s'.\n",
2646 err && *err ? *err : "", path);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002647 if (ret < 0) /* serious error, must do that ourselves */
2648 SSL_CTX_free(ctx);
2649 return 1;
2650 }
Emeric Brun61694ab2012-10-26 13:35:33 +02002651
2652 if (SSL_CTX_check_private_key(ctx) <= 0) {
2653 memprintf(err, "%sinconsistencies between private key and certificate loaded from PEM file '%s'.\n",
2654 err && *err ? *err : "", path);
2655 return 1;
2656 }
2657
Emeric Brunfc0421f2012-09-07 17:30:07 +02002658 /* we must not free the SSL_CTX anymore below, since it's already in
2659 * the tree, so it will be discovered and cleaned in time.
2660 */
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02002661#ifndef OPENSSL_NO_DH
Remi Gacogne4f902b82015-05-28 16:23:00 +02002662 /* store a NULL pointer to indicate we have not yet loaded
2663 a custom DH param file */
2664 if (ssl_dh_ptr_index >= 0) {
2665 SSL_CTX_set_ex_data(ctx, ssl_dh_ptr_index, NULL);
2666 }
2667
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02002668 ret = ssl_sock_load_dh_params(ctx, path);
2669 if (ret < 0) {
2670 if (err)
2671 memprintf(err, "%sunable to load DH parameters from file '%s'.\n",
2672 *err ? *err : "", path);
2673 return 1;
2674 }
2675#endif
2676
Lukas Tribuse4e30f72014-12-09 16:32:51 +01002677#if (defined SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB && !defined OPENSSL_NO_OCSP)
Emeric Brun4147b2e2014-06-16 18:36:30 +02002678 ret = ssl_sock_load_ocsp(ctx, path);
2679 if (ret < 0) {
2680 if (err)
2681 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",
2682 *err ? *err : "", path);
2683 return 1;
2684 }
2685#endif
2686
Daniel Jakots54ffb912015-11-06 20:02:41 +01002687#if (OPENSSL_VERSION_NUMBER >= 0x1000200fL && !defined OPENSSL_NO_TLSEXT && !defined OPENSSL_IS_BORINGSSL && !defined LIBRESSL_VERSION_NUMBER)
Janusz Dziemidowicz2c701b52015-03-07 23:03:59 +01002688 if (sctl_ex_index >= 0) {
2689 ret = ssl_sock_load_sctl(ctx, path);
2690 if (ret < 0) {
2691 if (err)
2692 memprintf(err, "%s '%s.sctl' is present but cannot be read or parsed'.\n",
2693 *err ? *err : "", path);
2694 return 1;
2695 }
2696 }
2697#endif
2698
Emeric Brunfc0421f2012-09-07 17:30:07 +02002699#ifndef SSL_CTRL_SET_TLSEXT_HOSTNAME
Willy Tarreau2a65ff02012-09-13 17:54:29 +02002700 if (bind_conf->default_ctx) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02002701 memprintf(err, "%sthis version of openssl cannot load multiple SSL certificates.\n",
2702 err && *err ? *err : "");
Emeric Brunfc0421f2012-09-07 17:30:07 +02002703 return 1;
2704 }
2705#endif
Emmanuel Hocdet98263292016-12-29 18:26:15 +01002706 if (!bind_conf->default_ctx) {
Willy Tarreau2a65ff02012-09-13 17:54:29 +02002707 bind_conf->default_ctx = ctx;
Emmanuel Hocdet98263292016-12-29 18:26:15 +01002708 bind_conf->default_ssl_conf = ssl_conf;
2709 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02002710
2711 return 0;
2712}
2713
Willy Tarreau03209342016-12-22 17:08:28 +01002714int ssl_sock_load_cert(char *path, struct bind_conf *bind_conf, char **err)
Emeric Brunfc0421f2012-09-07 17:30:07 +02002715{
Cyril Bonté3180f7b2015-01-25 00:16:08 +01002716 struct dirent **de_list;
2717 int i, n;
Emeric Brunfc0421f2012-09-07 17:30:07 +02002718 DIR *dir;
2719 struct stat buf;
Willy Tarreauee2663b2012-12-06 11:36:59 +01002720 char *end;
2721 char fp[MAXPATHLEN+1];
Emeric Brunfc0421f2012-09-07 17:30:07 +02002722 int cfgerr = 0;
yanbzhu63ea8462015-12-09 13:35:14 -05002723#if OPENSSL_VERSION_NUMBER >= 0x1000200fL
2724 int is_bundle;
2725 int j;
2726#endif
Emeric Brunfc0421f2012-09-07 17:30:07 +02002727
yanbzhu08ce6ab2015-12-02 13:01:29 -05002728 if (stat(path, &buf) == 0) {
2729 dir = opendir(path);
2730 if (!dir)
Emmanuel Hocdet98263292016-12-29 18:26:15 +01002731 return ssl_sock_load_cert_file(path, bind_conf, NULL, NULL, 0, err);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002732
yanbzhu08ce6ab2015-12-02 13:01:29 -05002733 /* strip trailing slashes, including first one */
2734 for (end = path + strlen(path) - 1; end >= path && *end == '/'; end--)
2735 *end = 0;
Emeric Brunfc0421f2012-09-07 17:30:07 +02002736
yanbzhu08ce6ab2015-12-02 13:01:29 -05002737 n = scandir(path, &de_list, 0, alphasort);
2738 if (n < 0) {
2739 memprintf(err, "%sunable to scan directory '%s' : %s.\n",
2740 err && *err ? *err : "", path, strerror(errno));
2741 cfgerr++;
2742 }
2743 else {
2744 for (i = 0; i < n; i++) {
2745 struct dirent *de = de_list[i];
Emeric Brun2aab7222014-06-18 18:15:09 +02002746
yanbzhu08ce6ab2015-12-02 13:01:29 -05002747 end = strrchr(de->d_name, '.');
2748 if (end && (!strcmp(end, ".issuer") || !strcmp(end, ".ocsp") || !strcmp(end, ".sctl")))
2749 goto ignore_entry;
Cyril Bonté3180f7b2015-01-25 00:16:08 +01002750
yanbzhu08ce6ab2015-12-02 13:01:29 -05002751 snprintf(fp, sizeof(fp), "%s/%s", path, de->d_name);
2752 if (stat(fp, &buf) != 0) {
2753 memprintf(err, "%sunable to stat SSL certificate from file '%s' : %s.\n",
2754 err && *err ? *err : "", fp, strerror(errno));
2755 cfgerr++;
2756 goto ignore_entry;
2757 }
2758 if (!S_ISREG(buf.st_mode))
2759 goto ignore_entry;
yanbzhu63ea8462015-12-09 13:35:14 -05002760
2761#if OPENSSL_VERSION_NUMBER >= 0x1000200fL
2762 is_bundle = 0;
2763 /* Check if current entry in directory is part of a multi-cert bundle */
2764
2765 if (end) {
2766 for (j = 0; j < SSL_SOCK_NUM_KEYTYPES; j++) {
2767 if (!strcmp(end + 1, SSL_SOCK_KEYTYPE_NAMES[j])) {
2768 is_bundle = 1;
2769 break;
2770 }
2771 }
2772
2773 if (is_bundle) {
2774 char dp[MAXPATHLEN+1] = {0}; /* this will be the filename w/o the keytype */
2775 int dp_len;
2776
2777 dp_len = end - de->d_name;
2778 snprintf(dp, dp_len + 1, "%s", de->d_name);
2779
2780 /* increment i and free de until we get to a non-bundle cert
2781 * Note here that we look at de_list[i + 1] before freeing de
2782 * this is important since ignore_entry will free de
2783 */
2784 while (i + 1 < n && !strncmp(de_list[i + 1]->d_name, dp, dp_len)) {
2785 free(de);
2786 i++;
2787 de = de_list[i];
2788 }
2789
2790 snprintf(fp, sizeof(fp), "%s/%s", path, dp);
Emmanuel Hocdet98263292016-12-29 18:26:15 +01002791 ssl_sock_load_multi_cert(fp, bind_conf, NULL, NULL, 0, err);
yanbzhu63ea8462015-12-09 13:35:14 -05002792
2793 /* Successfully processed the bundle */
2794 goto ignore_entry;
2795 }
2796 }
2797
2798#endif
Emmanuel Hocdet98263292016-12-29 18:26:15 +01002799 cfgerr += ssl_sock_load_cert_file(fp, bind_conf, NULL, NULL, 0, err);
yanbzhu08ce6ab2015-12-02 13:01:29 -05002800ignore_entry:
2801 free(de);
Cyril Bonté3180f7b2015-01-25 00:16:08 +01002802 }
yanbzhu08ce6ab2015-12-02 13:01:29 -05002803 free(de_list);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002804 }
yanbzhu08ce6ab2015-12-02 13:01:29 -05002805 closedir(dir);
2806 return cfgerr;
Emeric Brunfc0421f2012-09-07 17:30:07 +02002807 }
yanbzhu08ce6ab2015-12-02 13:01:29 -05002808
Emmanuel Hocdet98263292016-12-29 18:26:15 +01002809 cfgerr = ssl_sock_load_multi_cert(path, bind_conf, NULL, NULL, 0, err);
yanbzhu08ce6ab2015-12-02 13:01:29 -05002810
Emeric Brunfc0421f2012-09-07 17:30:07 +02002811 return cfgerr;
2812}
2813
Thierry Fournier383085f2013-01-24 14:15:43 +01002814/* Make sure openssl opens /dev/urandom before the chroot. The work is only
2815 * done once. Zero is returned if the operation fails. No error is returned
2816 * if the random is said as not implemented, because we expect that openssl
2817 * will use another method once needed.
2818 */
2819static int ssl_initialize_random()
2820{
2821 unsigned char random;
2822 static int random_initialized = 0;
2823
2824 if (!random_initialized && RAND_bytes(&random, 1) != 0)
2825 random_initialized = 1;
2826
2827 return random_initialized;
2828}
2829
Emmanuel Hocdet98263292016-12-29 18:26:15 +01002830/* release ssl bind conf */
2831void ssl_sock_free_ssl_conf(struct ssl_bind_conf *conf)
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002832{
Emmanuel Hocdet98263292016-12-29 18:26:15 +01002833 if (conf) {
2834#ifdef OPENSSL_NPN_NEGOTIATED
2835 free(conf->npn_str);
2836 conf->npn_str = NULL;
2837#endif
2838#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
2839 free(conf->alpn_str);
2840 conf->alpn_str = NULL;
2841#endif
2842 free(conf->ca_file);
2843 conf->ca_file = NULL;
2844 free(conf->crl_file);
2845 conf->crl_file = NULL;
2846 free(conf->ciphers);
2847 conf->ciphers = NULL;
Emmanuel Hocdete7f2b732017-01-09 16:15:54 +01002848 free(conf->curves);
2849 conf->curves = NULL;
Emmanuel Hocdet98263292016-12-29 18:26:15 +01002850 free(conf->ecdhe);
2851 conf->ecdhe = NULL;
2852 }
2853}
2854
2855int ssl_sock_load_cert_list_file(char *file, struct bind_conf *bind_conf, struct proxy *curproxy, char **err)
2856{
2857 char thisline[CRT_LINESIZE];
2858 char path[MAXPATHLEN+1];
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002859 FILE *f;
yanbzhu1b04e5b2015-12-02 13:54:14 -05002860 struct stat buf;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002861 int linenum = 0;
2862 int cfgerr = 0;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002863
Willy Tarreauad1731d2013-04-02 17:35:58 +02002864 if ((f = fopen(file, "r")) == NULL) {
2865 memprintf(err, "cannot open file '%s' : %s", file, strerror(errno));
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002866 return 1;
Willy Tarreauad1731d2013-04-02 17:35:58 +02002867 }
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002868
2869 while (fgets(thisline, sizeof(thisline), f) != NULL) {
Emmanuel Hocdet98263292016-12-29 18:26:15 +01002870 int arg, newarg, cur_arg, i, ssl_b = 0, ssl_e = 0;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002871 char *end;
Emmanuel Hocdet98263292016-12-29 18:26:15 +01002872 char *args[MAX_CRT_ARGS + 1];
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002873 char *line = thisline;
Emmanuel Hocdet98263292016-12-29 18:26:15 +01002874 char *crt_path;
2875 struct ssl_bind_conf *ssl_conf = NULL;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002876
2877 linenum++;
2878 end = line + strlen(line);
2879 if (end-line == sizeof(thisline)-1 && *(end-1) != '\n') {
2880 /* Check if we reached the limit and the last char is not \n.
2881 * Watch out for the last line without the terminating '\n'!
2882 */
Willy Tarreauad1731d2013-04-02 17:35:58 +02002883 memprintf(err, "line %d too long in file '%s', limit is %d characters",
2884 linenum, file, (int)sizeof(thisline)-1);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002885 cfgerr = 1;
Willy Tarreauad1731d2013-04-02 17:35:58 +02002886 break;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002887 }
2888
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002889 arg = 0;
Emeric Brun50bcecc2013-04-22 13:05:23 +02002890 newarg = 1;
2891 while (*line) {
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002892 if (*line == '#' || *line == '\n' || *line == '\r') {
2893 /* end of string, end of loop */
2894 *line = 0;
2895 break;
Emmanuel Hocdet98263292016-12-29 18:26:15 +01002896 } else if (isspace(*line)) {
Emeric Brun50bcecc2013-04-22 13:05:23 +02002897 newarg = 1;
2898 *line = 0;
Emmanuel Hocdet98263292016-12-29 18:26:15 +01002899 } else if (*line == '[') {
2900 if (ssl_b) {
2901 memprintf(err, "too many '[' on line %d in file '%s'.", linenum, file);
2902 cfgerr = 1;
2903 break;
2904 }
2905 if (!arg) {
2906 memprintf(err, "file must start with a cert on line %d in file '%s'", linenum, file);
2907 cfgerr = 1;
2908 break;
2909 }
2910 ssl_b = arg;
2911 newarg = 1;
2912 *line = 0;
2913 } else if (*line == ']') {
2914 if (ssl_e) {
2915 memprintf(err, "too many ']' on line %d in file '%s'.", linenum, file);
Emeric Brun50bcecc2013-04-22 13:05:23 +02002916 cfgerr = 1;
2917 break;
2918 }
Emmanuel Hocdet98263292016-12-29 18:26:15 +01002919 if (!ssl_b) {
2920 memprintf(err, "missing '[' in line %d in file '%s'.", linenum, file);
2921 cfgerr = 1;
2922 break;
2923 }
2924 ssl_e = arg;
2925 newarg = 1;
2926 *line = 0;
2927 } else if (newarg) {
2928 if (arg == MAX_CRT_ARGS) {
2929 memprintf(err, "too many args on line %d in file '%s'.", linenum, file);
2930 cfgerr = 1;
2931 break;
2932 }
Emeric Brun50bcecc2013-04-22 13:05:23 +02002933 newarg = 0;
2934 args[arg++] = line;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002935 }
Emeric Brun50bcecc2013-04-22 13:05:23 +02002936 line++;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002937 }
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02002938 if (cfgerr)
2939 break;
Emmanuel Hocdet98263292016-12-29 18:26:15 +01002940 args[arg++] = line;
Willy Tarreauad1731d2013-04-02 17:35:58 +02002941
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002942 /* empty line */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01002943 if (!*args[0])
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002944 continue;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002945
Emmanuel Hocdet98263292016-12-29 18:26:15 +01002946 crt_path = args[0];
2947 if (*crt_path != '/' && global_ssl.crt_base) {
2948 if ((strlen(global_ssl.crt_base) + 1 + strlen(crt_path)) > MAXPATHLEN) {
2949 memprintf(err, "'%s' : path too long on line %d in file '%s'",
2950 crt_path, linenum, file);
2951 cfgerr = 1;
2952 break;
2953 }
2954 snprintf(path, sizeof(path), "%s/%s", global_ssl.crt_base, crt_path);
2955 crt_path = path;
2956 }
2957
2958 ssl_conf = calloc(1, sizeof *ssl_conf);
2959 cur_arg = ssl_b ? ssl_b : 1;
2960 while (cur_arg < ssl_e) {
2961 newarg = 0;
2962 for (i = 0; ssl_bind_kws[i].kw != NULL; i++) {
2963 if (strcmp(ssl_bind_kws[i].kw, args[cur_arg]) == 0) {
2964 newarg = 1;
2965 cfgerr = ssl_bind_kws[i].parse(args, cur_arg, curproxy, ssl_conf, err);
2966 if (cur_arg + 1 + ssl_bind_kws[i].skip > ssl_e) {
2967 memprintf(err, "ssl args out of '[]' for %s on line %d in file '%s'",
2968 args[cur_arg], linenum, file);
2969 cfgerr = 1;
2970 }
2971 cur_arg += 1 + ssl_bind_kws[i].skip;
2972 break;
2973 }
2974 }
2975 if (!cfgerr && !newarg) {
2976 memprintf(err, "unknown ssl keyword %s on line %d in file '%s'.",
2977 args[cur_arg], linenum, file);
2978 cfgerr = 1;
2979 break;
2980 }
2981 }
2982 if (cfgerr) {
2983 ssl_sock_free_ssl_conf(ssl_conf);
2984 free(ssl_conf);
2985 ssl_conf = NULL;
2986 break;
2987 }
2988
2989 if (stat(crt_path, &buf) == 0) {
2990 cfgerr = ssl_sock_load_cert_file(crt_path, bind_conf, ssl_conf,
2991 &args[cur_arg], arg - cur_arg - 1, err);
yanbzhu1b04e5b2015-12-02 13:54:14 -05002992 } else {
Emmanuel Hocdet98263292016-12-29 18:26:15 +01002993 cfgerr = ssl_sock_load_multi_cert(crt_path, bind_conf, ssl_conf,
2994 &args[cur_arg], arg - cur_arg - 1, err);
yanbzhu1b04e5b2015-12-02 13:54:14 -05002995 }
2996
Willy Tarreauad1731d2013-04-02 17:35:58 +02002997 if (cfgerr) {
2998 memprintf(err, "error processing line %d in file '%s' : %s", linenum, file, *err);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002999 break;
Willy Tarreauad1731d2013-04-02 17:35:58 +02003000 }
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01003001 }
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01003002 fclose(f);
3003 return cfgerr;
3004}
3005
Emeric Brunfc0421f2012-09-07 17:30:07 +02003006#ifndef SSL_OP_CIPHER_SERVER_PREFERENCE /* needs OpenSSL >= 0.9.7 */
3007#define SSL_OP_CIPHER_SERVER_PREFERENCE 0
3008#endif
3009
3010#ifndef SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION /* needs OpenSSL >= 0.9.7 */
3011#define SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION 0
Willy Tarreau7d588ee2012-11-26 18:47:31 +01003012#define SSL_renegotiate_pending(arg) 0
Emeric Brunfc0421f2012-09-07 17:30:07 +02003013#endif
Emeric Brun2b58d042012-09-20 17:10:03 +02003014#ifndef SSL_OP_SINGLE_ECDH_USE /* needs OpenSSL >= 0.9.8 */
3015#define SSL_OP_SINGLE_ECDH_USE 0
3016#endif
Emeric Brun2d0c4822012-10-02 13:45:20 +02003017#ifndef SSL_OP_NO_TICKET /* needs OpenSSL >= 0.9.8 */
3018#define SSL_OP_NO_TICKET 0
3019#endif
Emeric Brunfc0421f2012-09-07 17:30:07 +02003020#ifndef SSL_OP_NO_COMPRESSION /* needs OpenSSL >= 0.9.9 */
3021#define SSL_OP_NO_COMPRESSION 0
3022#endif
Emeric Brunc0ff4922012-09-28 19:37:02 +02003023#ifndef SSL_OP_NO_TLSv1_1 /* needs OpenSSL >= 1.0.1 */
3024#define SSL_OP_NO_TLSv1_1 0
3025#endif
3026#ifndef SSL_OP_NO_TLSv1_2 /* needs OpenSSL >= 1.0.1 */
3027#define SSL_OP_NO_TLSv1_2 0
3028#endif
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02003029#ifndef SSL_OP_SINGLE_DH_USE /* needs OpenSSL >= 0.9.6 */
3030#define SSL_OP_SINGLE_DH_USE 0
3031#endif
Emeric Brun2b58d042012-09-20 17:10:03 +02003032#ifndef SSL_OP_SINGLE_ECDH_USE /* needs OpenSSL >= 1.0.0 */
3033#define SSL_OP_SINGLE_ECDH_USE 0
3034#endif
Emeric Brunfc0421f2012-09-07 17:30:07 +02003035#ifndef SSL_MODE_RELEASE_BUFFERS /* needs OpenSSL >= 1.0.0 */
3036#define SSL_MODE_RELEASE_BUFFERS 0
3037#endif
Willy Tarreau396a1862014-11-13 14:06:52 +01003038#ifndef SSL_MODE_SMALL_BUFFERS /* needs small_records.patch */
3039#define SSL_MODE_SMALL_BUFFERS 0
3040#endif
Remi Gacognef46cd6e2014-06-12 14:58:40 +02003041
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003042int ssl_sock_prepare_ctx(struct bind_conf *bind_conf, struct ssl_bind_conf *ssl_conf, SSL_CTX *ctx)
Emeric Brunfc0421f2012-09-07 17:30:07 +02003043{
Willy Tarreau03209342016-12-22 17:08:28 +01003044 struct proxy *curproxy = bind_conf->frontend;
Emeric Brunfc0421f2012-09-07 17:30:07 +02003045 int cfgerr = 0;
Emeric Brun850efd52014-01-29 12:24:34 +01003046 int verify = SSL_VERIFY_NONE;
Remi Gacogneaf5c3da2014-05-19 10:29:58 +02003047 long ssloptions =
Emeric Brunfc0421f2012-09-07 17:30:07 +02003048 SSL_OP_ALL | /* all known workarounds for bugs */
3049 SSL_OP_NO_SSLv2 |
3050 SSL_OP_NO_COMPRESSION |
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02003051 SSL_OP_SINGLE_DH_USE |
Emeric Brun2b58d042012-09-20 17:10:03 +02003052 SSL_OP_SINGLE_ECDH_USE |
Emeric Brun3c4bc6e2012-10-04 18:44:19 +02003053 SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION |
3054 SSL_OP_CIPHER_SERVER_PREFERENCE;
Remi Gacogneaf5c3da2014-05-19 10:29:58 +02003055 long sslmode =
Emeric Brunfc0421f2012-09-07 17:30:07 +02003056 SSL_MODE_ENABLE_PARTIAL_WRITE |
3057 SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER |
Willy Tarreau396a1862014-11-13 14:06:52 +01003058 SSL_MODE_RELEASE_BUFFERS |
3059 SSL_MODE_SMALL_BUFFERS;
Remi Gacognef46cd6e2014-06-12 14:58:40 +02003060 STACK_OF(SSL_CIPHER) * ciphers = NULL;
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +01003061 const SSL_CIPHER * cipher = NULL;
Remi Gacognec1eab8c2014-06-12 18:20:11 +02003062 char cipher_description[128];
3063 /* The description of ciphers using an Ephemeral Diffie Hellman key exchange
3064 contains " Kx=DH " or " Kx=DH(". Beware of " Kx=DH/",
3065 which is not ephemeral DH. */
3066 const char dhe_description[] = " Kx=DH ";
3067 const char dhe_export_description[] = " Kx=DH(";
Remi Gacognef46cd6e2014-06-12 14:58:40 +02003068 int idx = 0;
3069 int dhe_found = 0;
Remi Gacogne23d5d372014-10-10 17:04:26 +02003070 SSL *ssl = NULL;
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003071 struct ssl_bind_conf *ssl_conf_cur;
3072 int conf_ssl_options = bind_conf->ssl_conf.ssl_options | (ssl_conf ? ssl_conf->ssl_options : 0);
3073 const char *conf_ciphers;
Emmanuel Hocdete7f2b732017-01-09 16:15:54 +01003074 const char *conf_curves = NULL;
Emeric Brunfc0421f2012-09-07 17:30:07 +02003075
Thierry Fournier383085f2013-01-24 14:15:43 +01003076 /* Make sure openssl opens /dev/urandom before the chroot */
3077 if (!ssl_initialize_random()) {
3078 Alert("OpenSSL random data generator initialization failed.\n");
3079 cfgerr++;
3080 }
3081
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003082 if (conf_ssl_options & BC_SSL_O_NO_SSLV3)
Emeric Brunfc0421f2012-09-07 17:30:07 +02003083 ssloptions |= SSL_OP_NO_SSLv3;
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003084 if (conf_ssl_options & BC_SSL_O_NO_TLSV10)
Emeric Brunfc0421f2012-09-07 17:30:07 +02003085 ssloptions |= SSL_OP_NO_TLSv1;
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003086 if (conf_ssl_options & BC_SSL_O_NO_TLSV11)
Emeric Brunc0ff4922012-09-28 19:37:02 +02003087 ssloptions |= SSL_OP_NO_TLSv1_1;
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003088 if (conf_ssl_options & BC_SSL_O_NO_TLSV12)
Emeric Brunc0ff4922012-09-28 19:37:02 +02003089 ssloptions |= SSL_OP_NO_TLSv1_2;
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003090 if (conf_ssl_options & BC_SSL_O_NO_TLS_TICKETS)
Emeric Brun2d0c4822012-10-02 13:45:20 +02003091 ssloptions |= SSL_OP_NO_TICKET;
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +01003092#ifndef OPENSSL_IS_BORINGSSL
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003093 if (conf_ssl_options & BC_SSL_O_USE_SSLV3) {
Jérémie Courrèges-Anglas17c3f622015-07-25 16:50:52 -06003094#ifndef OPENSSL_NO_SSL3
Emeric Brun2cb7ae52012-10-05 14:14:21 +02003095 SSL_CTX_set_ssl_version(ctx, SSLv3_server_method());
Jérémie Courrèges-Anglas17c3f622015-07-25 16:50:52 -06003096#else
3097 Alert("SSLv3 support requested but unavailable.\n");
3098 cfgerr++;
3099#endif
3100 }
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003101 if (conf_ssl_options & BC_SSL_O_USE_TLSV10)
Emeric Brun2cb7ae52012-10-05 14:14:21 +02003102 SSL_CTX_set_ssl_version(ctx, TLSv1_server_method());
3103#if SSL_OP_NO_TLSv1_1
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003104 if (conf_ssl_options & BC_SSL_O_USE_TLSV11)
Emeric Brun2cb7ae52012-10-05 14:14:21 +02003105 SSL_CTX_set_ssl_version(ctx, TLSv1_1_server_method());
3106#endif
3107#if SSL_OP_NO_TLSv1_2
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003108 if (conf_ssl_options & BC_SSL_O_USE_TLSV12)
Emeric Brun2cb7ae52012-10-05 14:14:21 +02003109 SSL_CTX_set_ssl_version(ctx, TLSv1_2_server_method());
3110#endif
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +01003111#endif
Emeric Brunfc0421f2012-09-07 17:30:07 +02003112 SSL_CTX_set_options(ctx, ssloptions);
3113 SSL_CTX_set_mode(ctx, sslmode);
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003114 switch ((ssl_conf && ssl_conf->verify) ? ssl_conf->verify : bind_conf->ssl_conf.verify) {
Emeric Brun850efd52014-01-29 12:24:34 +01003115 case SSL_SOCK_VERIFY_NONE:
3116 verify = SSL_VERIFY_NONE;
3117 break;
3118 case SSL_SOCK_VERIFY_OPTIONAL:
3119 verify = SSL_VERIFY_PEER;
3120 break;
3121 case SSL_SOCK_VERIFY_REQUIRED:
3122 verify = SSL_VERIFY_PEER|SSL_VERIFY_FAIL_IF_NO_PEER_CERT;
3123 break;
3124 }
3125 SSL_CTX_set_verify(ctx, verify, ssl_sock_bind_verifycbk);
3126 if (verify & SSL_VERIFY_PEER) {
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003127 char *ca_file = (ssl_conf && ssl_conf->ca_file) ? ssl_conf->ca_file : bind_conf->ssl_conf.ca_file;
3128 char *crl_file = (ssl_conf && ssl_conf->crl_file) ? ssl_conf->crl_file : bind_conf->ssl_conf.crl_file;
3129 if (ca_file) {
Emeric Brund94b3fe2012-09-20 18:23:56 +02003130 /* load CAfile to verify */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003131 if (!SSL_CTX_load_verify_locations(ctx, ca_file, NULL)) {
Emeric Brund94b3fe2012-09-20 18:23:56 +02003132 Alert("Proxy '%s': unable to load CA file '%s' for bind '%s' at [%s:%d].\n",
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003133 curproxy->id, ca_file, bind_conf->arg, bind_conf->file, bind_conf->line);
Emeric Brund94b3fe2012-09-20 18:23:56 +02003134 cfgerr++;
3135 }
3136 /* set CA names fo client cert request, function returns void */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003137 SSL_CTX_set_client_CA_list(ctx, SSL_load_client_CA_file(ca_file));
Emeric Brund94b3fe2012-09-20 18:23:56 +02003138 }
Emeric Brun850efd52014-01-29 12:24:34 +01003139 else {
3140 Alert("Proxy '%s': verify is enabled but no CA file specified for bind '%s' at [%s:%d].\n",
3141 curproxy->id, bind_conf->arg, bind_conf->file, bind_conf->line);
3142 cfgerr++;
3143 }
Emeric Brun051cdab2012-10-02 19:25:50 +02003144#ifdef X509_V_FLAG_CRL_CHECK
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003145 if (crl_file) {
Emeric Brund94b3fe2012-09-20 18:23:56 +02003146 X509_STORE *store = SSL_CTX_get_cert_store(ctx);
3147
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003148 if (!store || !X509_STORE_load_locations(store, crl_file, NULL)) {
Emeric Brund94b3fe2012-09-20 18:23:56 +02003149 Alert("Proxy '%s': unable to configure CRL file '%s' for bind '%s' at [%s:%d].\n",
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003150 curproxy->id, crl_file, bind_conf->arg, bind_conf->file, bind_conf->line);
Emeric Brund94b3fe2012-09-20 18:23:56 +02003151 cfgerr++;
3152 }
Emeric Brun561e5742012-10-02 15:20:55 +02003153 else {
3154 X509_STORE_set_flags(store, X509_V_FLAG_CRL_CHECK|X509_V_FLAG_CRL_CHECK_ALL);
3155 }
Emeric Brund94b3fe2012-09-20 18:23:56 +02003156 }
Emeric Brun051cdab2012-10-02 19:25:50 +02003157#endif
Emeric Brun644cde02012-12-14 11:21:13 +01003158 ERR_clear_error();
Emeric Brund94b3fe2012-09-20 18:23:56 +02003159 }
Nenad Merdanovic05552d42015-02-27 19:56:49 +01003160#if (defined SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB && TLS_TICKETS_NO > 0)
Nenad Merdanovic146defa2015-05-09 08:46:00 +02003161 if(bind_conf->keys_ref) {
Nenad Merdanovic05552d42015-02-27 19:56:49 +01003162 if (!SSL_CTX_set_tlsext_ticket_key_cb(ctx, ssl_tlsext_ticket_key_cb)) {
3163 Alert("Proxy '%s': unable to set callback for TLS ticket validation for bind '%s' at [%s:%d].\n",
3164 curproxy->id, bind_conf->arg, bind_conf->file, bind_conf->line);
3165 cfgerr++;
3166 }
3167 }
3168#endif
3169
Willy Tarreauef934602016-12-22 23:12:01 +01003170 if (global_ssl.life_time)
3171 SSL_CTX_set_timeout(ctx, global_ssl.life_time);
Emeric Brun4f65bff2012-11-16 15:11:00 +01003172
Emeric Brunfc0421f2012-09-07 17:30:07 +02003173 shared_context_set_cache(ctx);
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003174 conf_ciphers = (ssl_conf && ssl_conf->ciphers) ? ssl_conf->ciphers : bind_conf->ssl_conf.ciphers;
3175 if (conf_ciphers &&
3176 !SSL_CTX_set_cipher_list(ctx, conf_ciphers)) {
Emeric Brunfc0421f2012-09-07 17:30:07 +02003177 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 +01003178 curproxy->id, conf_ciphers, bind_conf->arg, bind_conf->file, bind_conf->line);
Emeric Brunfc0421f2012-09-07 17:30:07 +02003179 cfgerr++;
3180 }
3181
Remi Gacogne47783ef2015-05-29 15:53:22 +02003182 /* If tune.ssl.default-dh-param has not been set,
3183 neither has ssl-default-dh-file and no static DH
3184 params were in the certificate file. */
Willy Tarreauef934602016-12-22 23:12:01 +01003185 if (global_ssl.default_dh_param == 0 &&
Remi Gacogne47783ef2015-05-29 15:53:22 +02003186 global_dh == NULL &&
Remi Gacogne4f902b82015-05-28 16:23:00 +02003187 (ssl_dh_ptr_index == -1 ||
3188 SSL_CTX_get_ex_data(ctx, ssl_dh_ptr_index) == NULL)) {
Lukas Tribus90132722014-08-18 00:56:33 +02003189
Remi Gacogne23d5d372014-10-10 17:04:26 +02003190 ssl = SSL_new(ctx);
Remi Gacognef46cd6e2014-06-12 14:58:40 +02003191
Remi Gacogne23d5d372014-10-10 17:04:26 +02003192 if (ssl) {
3193 ciphers = SSL_get_ciphers(ssl);
3194
3195 if (ciphers) {
3196 for (idx = 0; idx < sk_SSL_CIPHER_num(ciphers); idx++) {
3197 cipher = sk_SSL_CIPHER_value(ciphers, idx);
3198 if (SSL_CIPHER_description(cipher, cipher_description, sizeof (cipher_description)) == cipher_description) {
3199 if (strstr(cipher_description, dhe_description) != NULL ||
3200 strstr(cipher_description, dhe_export_description) != NULL) {
3201 dhe_found = 1;
3202 break;
3203 }
Remi Gacognec1eab8c2014-06-12 18:20:11 +02003204 }
Remi Gacognef46cd6e2014-06-12 14:58:40 +02003205 }
3206 }
Remi Gacogne23d5d372014-10-10 17:04:26 +02003207 SSL_free(ssl);
3208 ssl = NULL;
Lukas Tribus90132722014-08-18 00:56:33 +02003209 }
Remi Gacognef46cd6e2014-06-12 14:58:40 +02003210
Lukas Tribus90132722014-08-18 00:56:33 +02003211 if (dhe_found) {
3212 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 +02003213 }
3214
Willy Tarreauef934602016-12-22 23:12:01 +01003215 global_ssl.default_dh_param = 1024;
Remi Gacognef46cd6e2014-06-12 14:58:40 +02003216 }
Remi Gacogne8de54152014-07-15 11:36:40 +02003217
3218#ifndef OPENSSL_NO_DH
Willy Tarreauef934602016-12-22 23:12:01 +01003219 if (global_ssl.default_dh_param >= 1024) {
Remi Gacogne8de54152014-07-15 11:36:40 +02003220 if (local_dh_1024 == NULL) {
3221 local_dh_1024 = ssl_get_dh_1024();
3222 }
Willy Tarreauef934602016-12-22 23:12:01 +01003223 if (global_ssl.default_dh_param >= 2048) {
Remi Gacogne8de54152014-07-15 11:36:40 +02003224 if (local_dh_2048 == NULL) {
3225 local_dh_2048 = ssl_get_dh_2048();
3226 }
Willy Tarreauef934602016-12-22 23:12:01 +01003227 if (global_ssl.default_dh_param >= 4096) {
Remi Gacogne8de54152014-07-15 11:36:40 +02003228 if (local_dh_4096 == NULL) {
3229 local_dh_4096 = ssl_get_dh_4096();
3230 }
Remi Gacogne8de54152014-07-15 11:36:40 +02003231 }
3232 }
3233 }
3234#endif /* OPENSSL_NO_DH */
Remi Gacognef46cd6e2014-06-12 14:58:40 +02003235
Emeric Brunfc0421f2012-09-07 17:30:07 +02003236 SSL_CTX_set_info_callback(ctx, ssl_sock_infocbk);
Willy Tarreau5cbe4ef2014-05-08 22:45:11 +02003237#if OPENSSL_VERSION_NUMBER >= 0x00907000L
Emeric Brun29f037d2014-04-25 19:05:36 +02003238 SSL_CTX_set_msg_callback(ctx, ssl_sock_msgcbk);
Willy Tarreau5cbe4ef2014-05-08 22:45:11 +02003239#endif
Emeric Brun29f037d2014-04-25 19:05:36 +02003240
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02003241#ifdef OPENSSL_NPN_NEGOTIATED
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003242 ssl_conf_cur = NULL;
3243 if (ssl_conf && ssl_conf->npn_str)
3244 ssl_conf_cur = ssl_conf;
3245 else if (bind_conf->ssl_conf.npn_str)
3246 ssl_conf_cur = &bind_conf->ssl_conf;
3247 if (ssl_conf_cur)
3248 SSL_CTX_set_next_protos_advertised_cb(ctx, ssl_sock_advertise_npn_protos, ssl_conf_cur);
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02003249#endif
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01003250#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003251 ssl_conf_cur = NULL;
3252 if (ssl_conf && ssl_conf->alpn_str)
3253 ssl_conf_cur = ssl_conf;
3254 else if (bind_conf->ssl_conf.alpn_str)
3255 ssl_conf_cur = &bind_conf->ssl_conf;
3256 if (ssl_conf_cur)
3257 SSL_CTX_set_alpn_select_cb(ctx, ssl_sock_advertise_alpn_protos, ssl_conf_cur);
Willy Tarreauab861d32013-04-02 02:30:41 +02003258#endif
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02003259
Emeric Brunfc0421f2012-09-07 17:30:07 +02003260#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Emmanuel Hocdet05942112017-02-20 16:11:50 +01003261#ifdef OPENSSL_IS_BORINGSSL
3262 SSL_CTX_set_select_certificate_cb(ctx, ssl_sock_switchctx_cbk);
3263 SSL_CTX_set_tlsext_servername_callback(ctx, ssl_sock_switchctx_err_cbk);
3264#else
Emeric Brunfc0421f2012-09-07 17:30:07 +02003265 SSL_CTX_set_tlsext_servername_callback(ctx, ssl_sock_switchctx_cbk);
Willy Tarreau2a65ff02012-09-13 17:54:29 +02003266 SSL_CTX_set_tlsext_servername_arg(ctx, bind_conf);
Emeric Brunfc0421f2012-09-07 17:30:07 +02003267#endif
Emmanuel Hocdet05942112017-02-20 16:11:50 +01003268#endif
Emmanuel Hocdete7f2b732017-01-09 16:15:54 +01003269#if OPENSSL_VERSION_NUMBER >= 0x1000200fL
3270 conf_curves = (ssl_conf && ssl_conf->curves) ? ssl_conf->curves : bind_conf->ssl_conf.curves;
3271 if (conf_curves) {
3272 if (!SSL_CTX_set1_curves_list(ctx, conf_curves)) {
3273 Alert("Proxy '%s': unable to set SSL curves list to '%s' for bind '%s' at [%s:%d].\n",
3274 curproxy->id, conf_curves, bind_conf->arg, bind_conf->file, bind_conf->line);
3275 cfgerr++;
3276 }
Emmanuel Hocdete7f2b732017-01-09 16:15:54 +01003277 else
3278 SSL_CTX_set_ecdh_auto(ctx, 1);
Emmanuel Hocdete7f2b732017-01-09 16:15:54 +01003279 }
3280#endif
Emeric Brun2b58d042012-09-20 17:10:03 +02003281#if defined(SSL_CTX_set_tmp_ecdh) && !defined(OPENSSL_NO_ECDH)
Emmanuel Hocdete7f2b732017-01-09 16:15:54 +01003282 if (!conf_curves) {
Emeric Brun2b58d042012-09-20 17:10:03 +02003283 int i;
3284 EC_KEY *ecdh;
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003285 const char *ecdhe = (ssl_conf && ssl_conf->ecdhe) ? ssl_conf->ecdhe :
3286 (bind_conf->ssl_conf.ecdhe ? bind_conf->ssl_conf.ecdhe : ECDHE_DEFAULT_CURVE);
Emeric Brun2b58d042012-09-20 17:10:03 +02003287
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003288 i = OBJ_sn2nid(ecdhe);
Emeric Brun2b58d042012-09-20 17:10:03 +02003289 if (!i || ((ecdh = EC_KEY_new_by_curve_name(i)) == NULL)) {
3290 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 +01003291 curproxy->id, ecdhe, bind_conf->arg, bind_conf->file, bind_conf->line);
Emeric Brun2b58d042012-09-20 17:10:03 +02003292 cfgerr++;
3293 }
3294 else {
3295 SSL_CTX_set_tmp_ecdh(ctx, ecdh);
3296 EC_KEY_free(ecdh);
3297 }
3298 }
3299#endif
3300
Emeric Brunfc0421f2012-09-07 17:30:07 +02003301 return cfgerr;
3302}
3303
Evan Broderbe554312013-06-27 00:05:25 -07003304static int ssl_sock_srv_hostcheck(const char *pattern, const char *hostname)
3305{
3306 const char *pattern_wildcard, *pattern_left_label_end, *hostname_left_label_end;
3307 size_t prefixlen, suffixlen;
3308
3309 /* Trivial case */
3310 if (strcmp(pattern, hostname) == 0)
3311 return 1;
3312
Evan Broderbe554312013-06-27 00:05:25 -07003313 /* The rest of this logic is based on RFC 6125, section 6.4.3
3314 * (http://tools.ietf.org/html/rfc6125#section-6.4.3) */
3315
Emeric Bruna848dae2013-10-08 11:27:28 +02003316 pattern_wildcard = NULL;
3317 pattern_left_label_end = pattern;
3318 while (*pattern_left_label_end != '.') {
3319 switch (*pattern_left_label_end) {
3320 case 0:
3321 /* End of label not found */
3322 return 0;
3323 case '*':
3324 /* If there is more than one wildcards */
3325 if (pattern_wildcard)
3326 return 0;
3327 pattern_wildcard = pattern_left_label_end;
3328 break;
3329 }
3330 pattern_left_label_end++;
3331 }
3332
3333 /* If it's not trivial and there is no wildcard, it can't
3334 * match */
3335 if (!pattern_wildcard)
Evan Broderbe554312013-06-27 00:05:25 -07003336 return 0;
3337
3338 /* Make sure all labels match except the leftmost */
3339 hostname_left_label_end = strchr(hostname, '.');
3340 if (!hostname_left_label_end
3341 || strcmp(pattern_left_label_end, hostname_left_label_end) != 0)
3342 return 0;
3343
3344 /* Make sure the leftmost label of the hostname is long enough
3345 * that the wildcard can match */
Emeric Brun369da852013-10-08 11:39:35 +02003346 if (hostname_left_label_end - hostname < (pattern_left_label_end - pattern) - 1)
Evan Broderbe554312013-06-27 00:05:25 -07003347 return 0;
3348
3349 /* Finally compare the string on either side of the
3350 * wildcard */
3351 prefixlen = pattern_wildcard - pattern;
3352 suffixlen = pattern_left_label_end - (pattern_wildcard + 1);
Emeric Bruna848dae2013-10-08 11:27:28 +02003353 if ((prefixlen && (memcmp(pattern, hostname, prefixlen) != 0))
3354 || (suffixlen && (memcmp(pattern_wildcard + 1, hostname_left_label_end - suffixlen, suffixlen) != 0)))
Evan Broderbe554312013-06-27 00:05:25 -07003355 return 0;
3356
3357 return 1;
3358}
3359
3360static int ssl_sock_srv_verifycbk(int ok, X509_STORE_CTX *ctx)
3361{
3362 SSL *ssl;
3363 struct connection *conn;
3364 char *servername;
3365
3366 int depth;
3367 X509 *cert;
3368 STACK_OF(GENERAL_NAME) *alt_names;
3369 int i;
3370 X509_NAME *cert_subject;
3371 char *str;
3372
3373 if (ok == 0)
3374 return ok;
3375
3376 ssl = X509_STORE_CTX_get_ex_data(ctx, SSL_get_ex_data_X509_STORE_CTX_idx());
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02003377 conn = SSL_get_app_data(ssl);
Evan Broderbe554312013-06-27 00:05:25 -07003378
3379 servername = objt_server(conn->target)->ssl_ctx.verify_host;
3380
3381 /* We only need to verify the CN on the actual server cert,
3382 * not the indirect CAs */
3383 depth = X509_STORE_CTX_get_error_depth(ctx);
3384 if (depth != 0)
3385 return ok;
3386
3387 /* At this point, the cert is *not* OK unless we can find a
3388 * hostname match */
3389 ok = 0;
3390
3391 cert = X509_STORE_CTX_get_current_cert(ctx);
3392 /* It seems like this might happen if verify peer isn't set */
3393 if (!cert)
3394 return ok;
3395
3396 alt_names = X509_get_ext_d2i(cert, NID_subject_alt_name, NULL, NULL);
3397 if (alt_names) {
3398 for (i = 0; !ok && i < sk_GENERAL_NAME_num(alt_names); i++) {
3399 GENERAL_NAME *name = sk_GENERAL_NAME_value(alt_names, i);
3400 if (name->type == GEN_DNS) {
Emeric Bruna33410c2013-09-17 15:47:48 +02003401#if OPENSSL_VERSION_NUMBER < 0x00907000L
3402 if (ASN1_STRING_to_UTF8((unsigned char **)&str, name->d.ia5) >= 0) {
3403#else
Evan Broderbe554312013-06-27 00:05:25 -07003404 if (ASN1_STRING_to_UTF8((unsigned char **)&str, name->d.dNSName) >= 0) {
Emeric Bruna33410c2013-09-17 15:47:48 +02003405#endif
Evan Broderbe554312013-06-27 00:05:25 -07003406 ok = ssl_sock_srv_hostcheck(str, servername);
3407 OPENSSL_free(str);
3408 }
3409 }
3410 }
Emeric Brun4ad50a42013-09-17 15:19:54 +02003411 sk_GENERAL_NAME_pop_free(alt_names, GENERAL_NAME_free);
Evan Broderbe554312013-06-27 00:05:25 -07003412 }
3413
3414 cert_subject = X509_get_subject_name(cert);
3415 i = -1;
3416 while (!ok && (i = X509_NAME_get_index_by_NID(cert_subject, NID_commonName, i)) != -1) {
3417 X509_NAME_ENTRY *entry = X509_NAME_get_entry(cert_subject, i);
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02003418 ASN1_STRING *value;
3419 value = X509_NAME_ENTRY_get_data(entry);
3420 if (ASN1_STRING_to_UTF8((unsigned char **)&str, value) >= 0) {
Evan Broderbe554312013-06-27 00:05:25 -07003421 ok = ssl_sock_srv_hostcheck(str, servername);
3422 OPENSSL_free(str);
3423 }
3424 }
3425
3426 return ok;
3427}
3428
Emeric Brun94324a42012-10-11 14:00:19 +02003429/* prepare ssl context from servers options. Returns an error count */
Willy Tarreau03209342016-12-22 17:08:28 +01003430int ssl_sock_prepare_srv_ctx(struct server *srv)
Emeric Brun94324a42012-10-11 14:00:19 +02003431{
Willy Tarreau03209342016-12-22 17:08:28 +01003432 struct proxy *curproxy = srv->proxy;
Emeric Brun94324a42012-10-11 14:00:19 +02003433 int cfgerr = 0;
Remi Gacogneaf5c3da2014-05-19 10:29:58 +02003434 long options =
Emeric Brun94324a42012-10-11 14:00:19 +02003435 SSL_OP_ALL | /* all known workarounds for bugs */
3436 SSL_OP_NO_SSLv2 |
3437 SSL_OP_NO_COMPRESSION;
Remi Gacogneaf5c3da2014-05-19 10:29:58 +02003438 long mode =
Emeric Brun94324a42012-10-11 14:00:19 +02003439 SSL_MODE_ENABLE_PARTIAL_WRITE |
3440 SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER |
Willy Tarreau396a1862014-11-13 14:06:52 +01003441 SSL_MODE_RELEASE_BUFFERS |
3442 SSL_MODE_SMALL_BUFFERS;
Emeric Brun850efd52014-01-29 12:24:34 +01003443 int verify = SSL_VERIFY_NONE;
Emeric Brun94324a42012-10-11 14:00:19 +02003444
Thierry Fournier383085f2013-01-24 14:15:43 +01003445 /* Make sure openssl opens /dev/urandom before the chroot */
3446 if (!ssl_initialize_random()) {
3447 Alert("OpenSSL random data generator initialization failed.\n");
3448 cfgerr++;
3449 }
3450
Willy Tarreaufce03112015-01-15 21:32:40 +01003451 /* Automatic memory computations need to know we use SSL there */
3452 global.ssl_used_backend = 1;
3453
3454 /* Initiate SSL context for current server */
Emeric Brun94324a42012-10-11 14:00:19 +02003455 srv->ssl_ctx.reused_sess = NULL;
3456 if (srv->use_ssl)
3457 srv->xprt = &ssl_sock;
3458 if (srv->check.use_ssl)
Cyril Bonté9ce13112014-11-15 22:41:27 +01003459 srv->check.xprt = &ssl_sock;
Emeric Brun94324a42012-10-11 14:00:19 +02003460
3461 srv->ssl_ctx.ctx = SSL_CTX_new(SSLv23_client_method());
3462 if (!srv->ssl_ctx.ctx) {
3463 Alert("config : %s '%s', server '%s': unable to allocate ssl context.\n",
3464 proxy_type_str(curproxy), curproxy->id,
3465 srv->id);
3466 cfgerr++;
3467 return cfgerr;
3468 }
Emeric Bruna7aa3092012-10-26 12:58:00 +02003469 if (srv->ssl_ctx.client_crt) {
3470 if (SSL_CTX_use_PrivateKey_file(srv->ssl_ctx.ctx, srv->ssl_ctx.client_crt, SSL_FILETYPE_PEM) <= 0) {
3471 Alert("config : %s '%s', server '%s': unable to load SSL private key from PEM file '%s'.\n",
3472 proxy_type_str(curproxy), curproxy->id,
3473 srv->id, srv->ssl_ctx.client_crt);
3474 cfgerr++;
3475 }
3476 else if (SSL_CTX_use_certificate_chain_file(srv->ssl_ctx.ctx, srv->ssl_ctx.client_crt) <= 0) {
3477 Alert("config : %s '%s', server '%s': unable to load ssl certificate from PEM file '%s'.\n",
3478 proxy_type_str(curproxy), curproxy->id,
3479 srv->id, srv->ssl_ctx.client_crt);
3480 cfgerr++;
3481 }
3482 else if (SSL_CTX_check_private_key(srv->ssl_ctx.ctx) <= 0) {
3483 Alert("config : %s '%s', server '%s': inconsistencies between private key and certificate loaded from PEM file '%s'.\n",
3484 proxy_type_str(curproxy), curproxy->id,
3485 srv->id, srv->ssl_ctx.client_crt);
3486 cfgerr++;
3487 }
3488 }
Emeric Brun94324a42012-10-11 14:00:19 +02003489
3490 if (srv->ssl_ctx.options & SRV_SSL_O_NO_SSLV3)
3491 options |= SSL_OP_NO_SSLv3;
3492 if (srv->ssl_ctx.options & SRV_SSL_O_NO_TLSV10)
3493 options |= SSL_OP_NO_TLSv1;
3494 if (srv->ssl_ctx.options & SRV_SSL_O_NO_TLSV11)
3495 options |= SSL_OP_NO_TLSv1_1;
3496 if (srv->ssl_ctx.options & SRV_SSL_O_NO_TLSV12)
3497 options |= SSL_OP_NO_TLSv1_2;
Emeric Brunf9c5c472012-10-11 15:28:34 +02003498 if (srv->ssl_ctx.options & SRV_SSL_O_NO_TLS_TICKETS)
3499 options |= SSL_OP_NO_TICKET;
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +01003500#ifndef OPENSSL_IS_BORINGSSL
Jérémie Courrèges-Anglas17c3f622015-07-25 16:50:52 -06003501 if (srv->ssl_ctx.options & SRV_SSL_O_USE_SSLV3) {
3502#ifndef OPENSSL_NO_SSL3
Emeric Brun94324a42012-10-11 14:00:19 +02003503 SSL_CTX_set_ssl_version(srv->ssl_ctx.ctx, SSLv3_client_method());
Jérémie Courrèges-Anglas17c3f622015-07-25 16:50:52 -06003504#else
Thierry FOURNIERbc965342015-08-26 08:21:26 +02003505 Alert("SSLv3 support requested but unavailable.\n");
Jérémie Courrèges-Anglas17c3f622015-07-25 16:50:52 -06003506 cfgerr++;
3507#endif
3508 }
Emeric Brun94324a42012-10-11 14:00:19 +02003509 if (srv->ssl_ctx.options & SRV_SSL_O_USE_TLSV10)
3510 SSL_CTX_set_ssl_version(srv->ssl_ctx.ctx, TLSv1_client_method());
3511#if SSL_OP_NO_TLSv1_1
3512 if (srv->ssl_ctx.options & SRV_SSL_O_USE_TLSV11)
3513 SSL_CTX_set_ssl_version(srv->ssl_ctx.ctx, TLSv1_1_client_method());
3514#endif
3515#if SSL_OP_NO_TLSv1_2
3516 if (srv->ssl_ctx.options & SRV_SSL_O_USE_TLSV12)
3517 SSL_CTX_set_ssl_version(srv->ssl_ctx.ctx, TLSv1_2_client_method());
3518#endif
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +01003519#endif
Emeric Brun94324a42012-10-11 14:00:19 +02003520 SSL_CTX_set_options(srv->ssl_ctx.ctx, options);
3521 SSL_CTX_set_mode(srv->ssl_ctx.ctx, mode);
Emeric Brun850efd52014-01-29 12:24:34 +01003522
3523 if (global.ssl_server_verify == SSL_SERVER_VERIFY_REQUIRED)
3524 verify = SSL_VERIFY_PEER;
3525
3526 switch (srv->ssl_ctx.verify) {
3527 case SSL_SOCK_VERIFY_NONE:
3528 verify = SSL_VERIFY_NONE;
3529 break;
3530 case SSL_SOCK_VERIFY_REQUIRED:
3531 verify = SSL_VERIFY_PEER;
3532 break;
3533 }
Evan Broderbe554312013-06-27 00:05:25 -07003534 SSL_CTX_set_verify(srv->ssl_ctx.ctx,
Emeric Brun850efd52014-01-29 12:24:34 +01003535 verify,
Evan Broderbe554312013-06-27 00:05:25 -07003536 srv->ssl_ctx.verify_host ? ssl_sock_srv_verifycbk : NULL);
Emeric Brun850efd52014-01-29 12:24:34 +01003537 if (verify & SSL_VERIFY_PEER) {
Emeric Brunef42d922012-10-11 16:11:36 +02003538 if (srv->ssl_ctx.ca_file) {
3539 /* load CAfile to verify */
3540 if (!SSL_CTX_load_verify_locations(srv->ssl_ctx.ctx, srv->ssl_ctx.ca_file, NULL)) {
Willy Tarreau07ba08b2014-02-16 19:22:08 +01003541 Alert("Proxy '%s', server '%s' [%s:%d] unable to load CA file '%s'.\n",
Emeric Brunef42d922012-10-11 16:11:36 +02003542 curproxy->id, srv->id,
3543 srv->conf.file, srv->conf.line, srv->ssl_ctx.ca_file);
3544 cfgerr++;
3545 }
3546 }
Emeric Brun850efd52014-01-29 12:24:34 +01003547 else {
3548 if (global.ssl_server_verify == SSL_SERVER_VERIFY_REQUIRED)
Willy Tarreau07ba08b2014-02-16 19:22:08 +01003549 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 +01003550 curproxy->id, srv->id,
3551 srv->conf.file, srv->conf.line);
3552 else
Willy Tarreau07ba08b2014-02-16 19:22:08 +01003553 Alert("Proxy '%s', server '%s' [%s:%d] verify is enabled but no CA file specified.\n",
Emeric Brun850efd52014-01-29 12:24:34 +01003554 curproxy->id, srv->id,
3555 srv->conf.file, srv->conf.line);
3556 cfgerr++;
3557 }
Emeric Brunef42d922012-10-11 16:11:36 +02003558#ifdef X509_V_FLAG_CRL_CHECK
3559 if (srv->ssl_ctx.crl_file) {
3560 X509_STORE *store = SSL_CTX_get_cert_store(srv->ssl_ctx.ctx);
3561
3562 if (!store || !X509_STORE_load_locations(store, srv->ssl_ctx.crl_file, NULL)) {
Willy Tarreau07ba08b2014-02-16 19:22:08 +01003563 Alert("Proxy '%s', server '%s' [%s:%d] unable to configure CRL file '%s'.\n",
Emeric Brunef42d922012-10-11 16:11:36 +02003564 curproxy->id, srv->id,
3565 srv->conf.file, srv->conf.line, srv->ssl_ctx.crl_file);
3566 cfgerr++;
3567 }
3568 else {
3569 X509_STORE_set_flags(store, X509_V_FLAG_CRL_CHECK|X509_V_FLAG_CRL_CHECK_ALL);
3570 }
3571 }
3572#endif
3573 }
3574
Willy Tarreauef934602016-12-22 23:12:01 +01003575 if (global_ssl.life_time)
3576 SSL_CTX_set_timeout(srv->ssl_ctx.ctx, global_ssl.life_time);
Emeric Brun4f65bff2012-11-16 15:11:00 +01003577
Emeric Brun94324a42012-10-11 14:00:19 +02003578 SSL_CTX_set_session_cache_mode(srv->ssl_ctx.ctx, SSL_SESS_CACHE_OFF);
3579 if (srv->ssl_ctx.ciphers &&
3580 !SSL_CTX_set_cipher_list(srv->ssl_ctx.ctx, srv->ssl_ctx.ciphers)) {
3581 Alert("Proxy '%s', server '%s' [%s:%d] : unable to set SSL cipher list to '%s'.\n",
3582 curproxy->id, srv->id,
3583 srv->conf.file, srv->conf.line, srv->ssl_ctx.ciphers);
3584 cfgerr++;
3585 }
3586
3587 return cfgerr;
3588}
3589
Willy Tarreau2a65ff02012-09-13 17:54:29 +02003590/* Walks down the two trees in bind_conf and prepares all certs. The pointer may
Emeric Brunfc0421f2012-09-07 17:30:07 +02003591 * be NULL, in which case nothing is done. Returns the number of errors
3592 * encountered.
3593 */
Willy Tarreau03209342016-12-22 17:08:28 +01003594int ssl_sock_prepare_all_ctx(struct bind_conf *bind_conf)
Emeric Brunfc0421f2012-09-07 17:30:07 +02003595{
3596 struct ebmb_node *node;
3597 struct sni_ctx *sni;
3598 int err = 0;
3599
Willy Tarreau2a65ff02012-09-13 17:54:29 +02003600 if (!bind_conf || !bind_conf->is_ssl)
Emeric Brunfc0421f2012-09-07 17:30:07 +02003601 return 0;
3602
Willy Tarreaufce03112015-01-15 21:32:40 +01003603 /* Automatic memory computations need to know we use SSL there */
3604 global.ssl_used_frontend = 1;
3605
Emeric Brun0bed9942014-10-30 19:25:24 +01003606 if (bind_conf->default_ctx)
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003607 err += ssl_sock_prepare_ctx(bind_conf, bind_conf->default_ssl_conf, bind_conf->default_ctx);
Emeric Brun0bed9942014-10-30 19:25:24 +01003608
Willy Tarreau2a65ff02012-09-13 17:54:29 +02003609 node = ebmb_first(&bind_conf->sni_ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02003610 while (node) {
3611 sni = ebmb_entry(node, struct sni_ctx, name);
Emeric Brun0bed9942014-10-30 19:25:24 +01003612 if (!sni->order && sni->ctx != bind_conf->default_ctx)
3613 /* only initialize the CTX on its first occurrence and
3614 if it is not the default_ctx */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003615 err += ssl_sock_prepare_ctx(bind_conf, sni->conf, sni->ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02003616 node = ebmb_next(node);
3617 }
3618
Willy Tarreau2a65ff02012-09-13 17:54:29 +02003619 node = ebmb_first(&bind_conf->sni_w_ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02003620 while (node) {
3621 sni = ebmb_entry(node, struct sni_ctx, name);
Emeric Brun0bed9942014-10-30 19:25:24 +01003622 if (!sni->order && sni->ctx != bind_conf->default_ctx)
3623 /* only initialize the CTX on its first occurrence and
3624 if it is not the default_ctx */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003625 err += ssl_sock_prepare_ctx(bind_conf, sni->conf, sni->ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02003626 node = ebmb_next(node);
3627 }
3628 return err;
3629}
3630
Willy Tarreau55d37912016-12-21 23:38:39 +01003631/* Prepares all the contexts for a bind_conf and allocates the shared SSL
3632 * context if needed. Returns < 0 on error, 0 on success. The warnings and
3633 * alerts are directly emitted since the rest of the stack does it below.
3634 */
3635int ssl_sock_prepare_bind_conf(struct bind_conf *bind_conf)
3636{
3637 struct proxy *px = bind_conf->frontend;
3638 int alloc_ctx;
3639 int err;
3640
3641 if (!bind_conf->is_ssl) {
3642 if (bind_conf->default_ctx) {
3643 Warning("Proxy '%s': A certificate was specified but SSL was not enabled on bind '%s' at [%s:%d] (use 'ssl').\n",
3644 px->id, bind_conf->arg, bind_conf->file, bind_conf->line);
3645 }
3646 return 0;
3647 }
3648 if (!bind_conf->default_ctx) {
3649 Alert("Proxy '%s': no SSL certificate specified for bind '%s' at [%s:%d] (use 'crt').\n",
3650 px->id, bind_conf->arg, bind_conf->file, bind_conf->line);
3651 return -1;
3652 }
3653
Willy Tarreauef934602016-12-22 23:12:01 +01003654 alloc_ctx = shared_context_init(global.tune.sslcachesize, (!global_ssl.private_cache && (global.nbproc > 1)) ? 1 : 0);
Willy Tarreau55d37912016-12-21 23:38:39 +01003655 if (alloc_ctx < 0) {
3656 if (alloc_ctx == SHCTX_E_INIT_LOCK)
3657 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");
3658 else
3659 Alert("Unable to allocate SSL session cache.\n");
3660 return -1;
3661 }
3662
3663 err = 0;
3664 /* initialize all certificate contexts */
3665 err += ssl_sock_prepare_all_ctx(bind_conf);
3666
3667 /* initialize CA variables if the certificates generation is enabled */
3668 err += ssl_sock_load_ca(bind_conf);
3669
3670 return -err;
3671}
Christopher Faulet77fe80c2015-07-29 13:02:40 +02003672
3673/* release ssl context allocated for servers. */
3674void ssl_sock_free_srv_ctx(struct server *srv)
3675{
3676 if (srv->ssl_ctx.ctx)
3677 SSL_CTX_free(srv->ssl_ctx.ctx);
3678}
3679
Willy Tarreau2a65ff02012-09-13 17:54:29 +02003680/* Walks down the two trees in bind_conf and frees all the certs. The pointer may
Emeric Brunfc0421f2012-09-07 17:30:07 +02003681 * be NULL, in which case nothing is done. The default_ctx is nullified too.
3682 */
Willy Tarreau2a65ff02012-09-13 17:54:29 +02003683void ssl_sock_free_all_ctx(struct bind_conf *bind_conf)
Emeric Brunfc0421f2012-09-07 17:30:07 +02003684{
3685 struct ebmb_node *node, *back;
3686 struct sni_ctx *sni;
3687
Willy Tarreau2a65ff02012-09-13 17:54:29 +02003688 if (!bind_conf || !bind_conf->is_ssl)
Emeric Brunfc0421f2012-09-07 17:30:07 +02003689 return;
3690
Willy Tarreau2a65ff02012-09-13 17:54:29 +02003691 node = ebmb_first(&bind_conf->sni_ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02003692 while (node) {
3693 sni = ebmb_entry(node, struct sni_ctx, name);
3694 back = ebmb_next(node);
3695 ebmb_delete(node);
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003696 if (!sni->order) { /* only free the CTX on its first occurrence */
Emeric Brunfc0421f2012-09-07 17:30:07 +02003697 SSL_CTX_free(sni->ctx);
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003698 ssl_sock_free_ssl_conf(sni->conf);
3699 free(sni->conf);
3700 sni->conf = NULL;
3701 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02003702 free(sni);
3703 node = back;
3704 }
3705
Willy Tarreau2a65ff02012-09-13 17:54:29 +02003706 node = ebmb_first(&bind_conf->sni_w_ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02003707 while (node) {
3708 sni = ebmb_entry(node, struct sni_ctx, name);
3709 back = ebmb_next(node);
3710 ebmb_delete(node);
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003711 if (!sni->order) { /* only free the CTX on its first occurrence */
Emeric Brunfc0421f2012-09-07 17:30:07 +02003712 SSL_CTX_free(sni->ctx);
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003713 ssl_sock_free_ssl_conf(sni->conf);
3714 free(sni->conf);
3715 sni->conf = NULL;
3716 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02003717 free(sni);
3718 node = back;
3719 }
3720
Willy Tarreau2a65ff02012-09-13 17:54:29 +02003721 bind_conf->default_ctx = NULL;
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003722 bind_conf->default_ssl_conf = NULL;
Emeric Brune1f38db2012-09-03 20:36:47 +02003723}
3724
Willy Tarreau795cdab2016-12-22 17:30:54 +01003725/* Destroys all the contexts for a bind_conf. This is used during deinit(). */
3726void ssl_sock_destroy_bind_conf(struct bind_conf *bind_conf)
3727{
3728 ssl_sock_free_ca(bind_conf);
3729 ssl_sock_free_all_ctx(bind_conf);
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003730 ssl_sock_free_ssl_conf(&bind_conf->ssl_conf);
Willy Tarreau795cdab2016-12-22 17:30:54 +01003731 free(bind_conf->ca_sign_file);
3732 free(bind_conf->ca_sign_pass);
Willy Tarreau795cdab2016-12-22 17:30:54 +01003733 if (bind_conf->keys_ref) {
3734 free(bind_conf->keys_ref->filename);
3735 free(bind_conf->keys_ref->tlskeys);
3736 LIST_DEL(&bind_conf->keys_ref->list);
3737 free(bind_conf->keys_ref);
3738 }
3739 bind_conf->keys_ref = NULL;
Willy Tarreau795cdab2016-12-22 17:30:54 +01003740 bind_conf->ca_sign_pass = NULL;
3741 bind_conf->ca_sign_file = NULL;
Willy Tarreau795cdab2016-12-22 17:30:54 +01003742}
3743
Christopher Faulet31af49d2015-06-09 17:29:50 +02003744/* Load CA cert file and private key used to generate certificates */
3745int
Willy Tarreau03209342016-12-22 17:08:28 +01003746ssl_sock_load_ca(struct bind_conf *bind_conf)
Christopher Faulet31af49d2015-06-09 17:29:50 +02003747{
Willy Tarreau03209342016-12-22 17:08:28 +01003748 struct proxy *px = bind_conf->frontend;
Christopher Faulet31af49d2015-06-09 17:29:50 +02003749 FILE *fp;
3750 X509 *cacert = NULL;
3751 EVP_PKEY *capkey = NULL;
3752 int err = 0;
3753
3754 if (!bind_conf || !bind_conf->generate_certs)
3755 return err;
3756
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +01003757#if (defined SSL_CTRL_SET_TLSEXT_HOSTNAME && !defined SSL_NO_GENERATE_CERTIFICATES)
Willy Tarreauef934602016-12-22 23:12:01 +01003758 if (global_ssl.ctx_cache)
3759 ssl_ctx_lru_tree = lru64_new(global_ssl.ctx_cache);
Christopher Fauletd2cab922015-07-28 16:03:47 +02003760 ssl_ctx_lru_seed = (unsigned int)time(NULL);
Willy Tarreaua84c2672015-10-09 12:10:13 +02003761#endif
Christopher Fauletd2cab922015-07-28 16:03:47 +02003762
Christopher Faulet31af49d2015-06-09 17:29:50 +02003763 if (!bind_conf->ca_sign_file) {
3764 Alert("Proxy '%s': cannot enable certificate generation, "
3765 "no CA certificate File configured at [%s:%d].\n",
3766 px->id, bind_conf->file, bind_conf->line);
Christopher Faulet31af49d2015-06-09 17:29:50 +02003767 goto load_error;
Christopher Fauletc6f02fb2015-10-09 10:53:31 +02003768 }
Christopher Faulet31af49d2015-06-09 17:29:50 +02003769
3770 /* read in the CA certificate */
3771 if (!(fp = fopen(bind_conf->ca_sign_file, "r"))) {
3772 Alert("Proxy '%s': Failed to read CA certificate file '%s' at [%s:%d].\n",
3773 px->id, bind_conf->ca_sign_file, bind_conf->file, bind_conf->line);
Christopher Faulet31af49d2015-06-09 17:29:50 +02003774 goto load_error;
3775 }
3776 if (!(cacert = PEM_read_X509(fp, NULL, NULL, NULL))) {
3777 Alert("Proxy '%s': Failed to read CA certificate file '%s' at [%s:%d].\n",
3778 px->id, bind_conf->ca_sign_file, bind_conf->file, bind_conf->line);
Christopher Fauletc6f02fb2015-10-09 10:53:31 +02003779 goto read_error;
Christopher Faulet31af49d2015-06-09 17:29:50 +02003780 }
Christopher Fauletc6f02fb2015-10-09 10:53:31 +02003781 rewind(fp);
Christopher Faulet31af49d2015-06-09 17:29:50 +02003782 if (!(capkey = PEM_read_PrivateKey(fp, NULL, NULL, bind_conf->ca_sign_pass))) {
3783 Alert("Proxy '%s': Failed to read CA private key file '%s' at [%s:%d].\n",
3784 px->id, bind_conf->ca_sign_file, bind_conf->file, bind_conf->line);
Christopher Fauletc6f02fb2015-10-09 10:53:31 +02003785 goto read_error;
Christopher Faulet31af49d2015-06-09 17:29:50 +02003786 }
Christopher Faulet31af49d2015-06-09 17:29:50 +02003787
Christopher Fauletc6f02fb2015-10-09 10:53:31 +02003788 fclose (fp);
Christopher Faulet31af49d2015-06-09 17:29:50 +02003789 bind_conf->ca_sign_cert = cacert;
3790 bind_conf->ca_sign_pkey = capkey;
3791 return err;
3792
Christopher Fauletc6f02fb2015-10-09 10:53:31 +02003793 read_error:
3794 fclose (fp);
Christopher Faulet31af49d2015-06-09 17:29:50 +02003795 if (capkey) EVP_PKEY_free(capkey);
3796 if (cacert) X509_free(cacert);
Christopher Fauletc6f02fb2015-10-09 10:53:31 +02003797 load_error:
3798 bind_conf->generate_certs = 0;
3799 err++;
Christopher Faulet31af49d2015-06-09 17:29:50 +02003800 return err;
3801}
3802
3803/* Release CA cert and private key used to generate certificated */
3804void
3805ssl_sock_free_ca(struct bind_conf *bind_conf)
3806{
3807 if (!bind_conf)
3808 return;
3809
3810 if (bind_conf->ca_sign_pkey)
3811 EVP_PKEY_free(bind_conf->ca_sign_pkey);
3812 if (bind_conf->ca_sign_cert)
3813 X509_free(bind_conf->ca_sign_cert);
Willy Tarreau94ff03a2016-12-22 17:57:46 +01003814 bind_conf->ca_sign_pkey = NULL;
3815 bind_conf->ca_sign_cert = NULL;
Christopher Faulet31af49d2015-06-09 17:29:50 +02003816}
3817
Emeric Brun46591952012-05-18 15:47:34 +02003818/*
3819 * This function is called if SSL * context is not yet allocated. The function
3820 * is designed to be called before any other data-layer operation and sets the
3821 * handshake flag on the connection. It is safe to call it multiple times.
3822 * It returns 0 on success and -1 in error case.
3823 */
3824static int ssl_sock_init(struct connection *conn)
3825{
3826 /* already initialized */
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02003827 if (conn->xprt_ctx)
Emeric Brun46591952012-05-18 15:47:34 +02003828 return 0;
3829
Willy Tarreau3c728722014-01-23 13:50:42 +01003830 if (!conn_ctrl_ready(conn))
Willy Tarreauf79c8172013-10-21 16:30:56 +02003831 return 0;
3832
Willy Tarreau20879a02012-12-03 16:32:10 +01003833 if (global.maxsslconn && sslconns >= global.maxsslconn) {
3834 conn->err_code = CO_ER_SSL_TOO_MANY;
Willy Tarreau403edff2012-09-06 11:58:37 +02003835 return -1;
Willy Tarreau20879a02012-12-03 16:32:10 +01003836 }
Willy Tarreau403edff2012-09-06 11:58:37 +02003837
Emeric Brun46591952012-05-18 15:47:34 +02003838 /* If it is in client mode initiate SSL session
3839 in connect state otherwise accept state */
Willy Tarreau3fdb3662012-11-12 00:42:33 +01003840 if (objt_server(conn->target)) {
Willy Tarreaufba03cd2014-11-13 13:48:58 +01003841 int may_retry = 1;
3842
3843 retry_connect:
Emeric Brun46591952012-05-18 15:47:34 +02003844 /* Alloc a new SSL session ctx */
Willy Tarreau3fdb3662012-11-12 00:42:33 +01003845 conn->xprt_ctx = SSL_new(objt_server(conn->target)->ssl_ctx.ctx);
Willy Tarreau20879a02012-12-03 16:32:10 +01003846 if (!conn->xprt_ctx) {
Willy Tarreaufba03cd2014-11-13 13:48:58 +01003847 if (may_retry--) {
3848 pool_gc2();
3849 goto retry_connect;
3850 }
Willy Tarreau20879a02012-12-03 16:32:10 +01003851 conn->err_code = CO_ER_SSL_NO_MEM;
Emeric Brun46591952012-05-18 15:47:34 +02003852 return -1;
Willy Tarreau20879a02012-12-03 16:32:10 +01003853 }
Emeric Brun46591952012-05-18 15:47:34 +02003854
Emeric Brun46591952012-05-18 15:47:34 +02003855 /* set fd on SSL session context */
Emeric Brun55476152014-11-12 17:35:37 +01003856 if (!SSL_set_fd(conn->xprt_ctx, conn->t.sock.fd)) {
3857 SSL_free(conn->xprt_ctx);
3858 conn->xprt_ctx = NULL;
Willy Tarreaufba03cd2014-11-13 13:48:58 +01003859 if (may_retry--) {
3860 pool_gc2();
3861 goto retry_connect;
3862 }
Emeric Brun55476152014-11-12 17:35:37 +01003863 conn->err_code = CO_ER_SSL_NO_MEM;
3864 return -1;
3865 }
Emeric Brun46591952012-05-18 15:47:34 +02003866
Evan Broderbe554312013-06-27 00:05:25 -07003867 /* set connection pointer */
Emeric Brun55476152014-11-12 17:35:37 +01003868 if (!SSL_set_app_data(conn->xprt_ctx, conn)) {
3869 SSL_free(conn->xprt_ctx);
3870 conn->xprt_ctx = NULL;
Willy Tarreaufba03cd2014-11-13 13:48:58 +01003871 if (may_retry--) {
3872 pool_gc2();
3873 goto retry_connect;
3874 }
Emeric Brun55476152014-11-12 17:35:37 +01003875 conn->err_code = CO_ER_SSL_NO_MEM;
3876 return -1;
3877 }
3878
3879 SSL_set_connect_state(conn->xprt_ctx);
3880 if (objt_server(conn->target)->ssl_ctx.reused_sess) {
3881 if(!SSL_set_session(conn->xprt_ctx, objt_server(conn->target)->ssl_ctx.reused_sess)) {
3882 SSL_SESSION_free(objt_server(conn->target)->ssl_ctx.reused_sess);
3883 objt_server(conn->target)->ssl_ctx.reused_sess = NULL;
3884 }
3885 }
Evan Broderbe554312013-06-27 00:05:25 -07003886
Emeric Brun46591952012-05-18 15:47:34 +02003887 /* leave init state and start handshake */
Willy Tarreau05737472012-09-04 08:03:39 +02003888 conn->flags |= CO_FL_SSL_WAIT_HS | CO_FL_WAIT_L6_CONN;
Willy Tarreau403edff2012-09-06 11:58:37 +02003889
3890 sslconns++;
Willy Tarreau71b734c2014-01-28 15:19:44 +01003891 totalsslconns++;
Emeric Brun46591952012-05-18 15:47:34 +02003892 return 0;
3893 }
Willy Tarreau3fdb3662012-11-12 00:42:33 +01003894 else if (objt_listener(conn->target)) {
Willy Tarreaufba03cd2014-11-13 13:48:58 +01003895 int may_retry = 1;
3896
3897 retry_accept:
Emeric Brun46591952012-05-18 15:47:34 +02003898 /* Alloc a new SSL session ctx */
Willy Tarreau3fdb3662012-11-12 00:42:33 +01003899 conn->xprt_ctx = SSL_new(objt_listener(conn->target)->bind_conf->default_ctx);
Willy Tarreau20879a02012-12-03 16:32:10 +01003900 if (!conn->xprt_ctx) {
Willy Tarreaufba03cd2014-11-13 13:48:58 +01003901 if (may_retry--) {
3902 pool_gc2();
3903 goto retry_accept;
3904 }
Willy Tarreau20879a02012-12-03 16:32:10 +01003905 conn->err_code = CO_ER_SSL_NO_MEM;
Emeric Brun46591952012-05-18 15:47:34 +02003906 return -1;
Willy Tarreau20879a02012-12-03 16:32:10 +01003907 }
Emeric Brun46591952012-05-18 15:47:34 +02003908
Emeric Brun46591952012-05-18 15:47:34 +02003909 /* set fd on SSL session context */
Emeric Brun55476152014-11-12 17:35:37 +01003910 if (!SSL_set_fd(conn->xprt_ctx, conn->t.sock.fd)) {
3911 SSL_free(conn->xprt_ctx);
3912 conn->xprt_ctx = NULL;
Willy Tarreaufba03cd2014-11-13 13:48:58 +01003913 if (may_retry--) {
3914 pool_gc2();
3915 goto retry_accept;
3916 }
Emeric Brun55476152014-11-12 17:35:37 +01003917 conn->err_code = CO_ER_SSL_NO_MEM;
3918 return -1;
3919 }
Emeric Brun46591952012-05-18 15:47:34 +02003920
Emeric Brune1f38db2012-09-03 20:36:47 +02003921 /* set connection pointer */
Emeric Brun55476152014-11-12 17:35:37 +01003922 if (!SSL_set_app_data(conn->xprt_ctx, conn)) {
3923 SSL_free(conn->xprt_ctx);
3924 conn->xprt_ctx = NULL;
Willy Tarreaufba03cd2014-11-13 13:48:58 +01003925 if (may_retry--) {
3926 pool_gc2();
3927 goto retry_accept;
3928 }
Emeric Brun55476152014-11-12 17:35:37 +01003929 conn->err_code = CO_ER_SSL_NO_MEM;
3930 return -1;
3931 }
3932
3933 SSL_set_accept_state(conn->xprt_ctx);
Emeric Brune1f38db2012-09-03 20:36:47 +02003934
Emeric Brun46591952012-05-18 15:47:34 +02003935 /* leave init state and start handshake */
Willy Tarreau05737472012-09-04 08:03:39 +02003936 conn->flags |= CO_FL_SSL_WAIT_HS | CO_FL_WAIT_L6_CONN;
Willy Tarreau403edff2012-09-06 11:58:37 +02003937
3938 sslconns++;
Willy Tarreau71b734c2014-01-28 15:19:44 +01003939 totalsslconns++;
Emeric Brun46591952012-05-18 15:47:34 +02003940 return 0;
3941 }
3942 /* don't know how to handle such a target */
Willy Tarreau20879a02012-12-03 16:32:10 +01003943 conn->err_code = CO_ER_SSL_NO_TARGET;
Emeric Brun46591952012-05-18 15:47:34 +02003944 return -1;
3945}
3946
3947
3948/* This is the callback which is used when an SSL handshake is pending. It
3949 * updates the FD status if it wants some polling before being called again.
3950 * It returns 0 if it fails in a fatal way or needs to poll to go further,
3951 * otherwise it returns non-zero and removes itself from the connection's
3952 * flags (the bit is provided in <flag> by the caller).
3953 */
3954int ssl_sock_handshake(struct connection *conn, unsigned int flag)
3955{
3956 int ret;
3957
Willy Tarreau3c728722014-01-23 13:50:42 +01003958 if (!conn_ctrl_ready(conn))
Willy Tarreauf79c8172013-10-21 16:30:56 +02003959 return 0;
3960
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02003961 if (!conn->xprt_ctx)
Emeric Brun46591952012-05-18 15:47:34 +02003962 goto out_error;
3963
Emeric Brun674b7432012-11-08 19:21:55 +01003964 /* If we use SSL_do_handshake to process a reneg initiated by
3965 * the remote peer, it sometimes returns SSL_ERROR_SSL.
3966 * Usually SSL_write and SSL_read are used and process implicitly
3967 * the reneg handshake.
3968 * Here we use SSL_peek as a workaround for reneg.
3969 */
3970 if ((conn->flags & CO_FL_CONNECTED) && SSL_renegotiate_pending(conn->xprt_ctx)) {
3971 char c;
3972
3973 ret = SSL_peek(conn->xprt_ctx, &c, 1);
3974 if (ret <= 0) {
3975 /* handshake may have not been completed, let's find why */
3976 ret = SSL_get_error(conn->xprt_ctx, ret);
3977 if (ret == SSL_ERROR_WANT_WRITE) {
3978 /* SSL handshake needs to write, L4 connection may not be ready */
3979 __conn_sock_stop_recv(conn);
Willy Tarreaue1f50c42014-01-22 20:02:06 +01003980 __conn_sock_want_send(conn);
3981 fd_cant_send(conn->t.sock.fd);
Emeric Brun674b7432012-11-08 19:21:55 +01003982 return 0;
3983 }
3984 else if (ret == SSL_ERROR_WANT_READ) {
3985 /* handshake may have been completed but we have
3986 * no more data to read.
3987 */
3988 if (!SSL_renegotiate_pending(conn->xprt_ctx)) {
3989 ret = 1;
3990 goto reneg_ok;
3991 }
3992 /* SSL handshake needs to read, L4 connection is ready */
3993 if (conn->flags & CO_FL_WAIT_L4_CONN)
3994 conn->flags &= ~CO_FL_WAIT_L4_CONN;
3995 __conn_sock_stop_send(conn);
Willy Tarreaue1f50c42014-01-22 20:02:06 +01003996 __conn_sock_want_recv(conn);
3997 fd_cant_recv(conn->t.sock.fd);
Emeric Brun674b7432012-11-08 19:21:55 +01003998 return 0;
3999 }
4000 else if (ret == SSL_ERROR_SYSCALL) {
4001 /* if errno is null, then connection was successfully established */
4002 if (!errno && conn->flags & CO_FL_WAIT_L4_CONN)
4003 conn->flags &= ~CO_FL_WAIT_L4_CONN;
Willy Tarreau20879a02012-12-03 16:32:10 +01004004 if (!conn->err_code) {
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +01004005#ifdef OPENSSL_NO_HEARTBEATS /* BoringSSL */
4006 conn->err_code = CO_ER_SSL_HANDSHAKE;
4007#else
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004008 int empty_handshake;
Luca Pizzamiglio578b1692016-12-12 10:56:56 +01004009#if (OPENSSL_VERSION_NUMBER >= 0x1010000fL) && !defined(LIBRESSL_VERSION_NUMBER)
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004010 OSSL_HANDSHAKE_STATE state = SSL_get_state((SSL *)conn->xprt_ctx);
4011 empty_handshake = state == TLS_ST_BEFORE;
4012#else
4013 empty_handshake = !((SSL *)conn->xprt_ctx)->packet_length;
4014#endif
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004015 if (empty_handshake) {
Emeric Brun29f037d2014-04-25 19:05:36 +02004016 if (!errno) {
4017 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
4018 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
4019 else
4020 conn->err_code = CO_ER_SSL_EMPTY;
4021 }
4022 else {
4023 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
4024 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
4025 else
4026 conn->err_code = CO_ER_SSL_ABORT;
4027 }
4028 }
4029 else {
4030 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
4031 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
Willy Tarreau20879a02012-12-03 16:32:10 +01004032 else
Emeric Brun29f037d2014-04-25 19:05:36 +02004033 conn->err_code = CO_ER_SSL_HANDSHAKE;
4034 }
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +01004035#endif
Willy Tarreau20879a02012-12-03 16:32:10 +01004036 }
Emeric Brun674b7432012-11-08 19:21:55 +01004037 goto out_error;
4038 }
4039 else {
4040 /* Fail on all other handshake errors */
4041 /* Note: OpenSSL may leave unread bytes in the socket's
4042 * buffer, causing an RST to be emitted upon close() on
4043 * TCP sockets. We first try to drain possibly pending
4044 * data to avoid this as much as possible.
4045 */
Willy Tarreaud85c4852015-03-13 00:40:28 +01004046 conn_sock_drain(conn);
Willy Tarreau20879a02012-12-03 16:32:10 +01004047 if (!conn->err_code)
Willy Tarreauf51c6982014-04-25 20:02:39 +02004048 conn->err_code = (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT) ?
4049 CO_ER_SSL_KILLED_HB : CO_ER_SSL_HANDSHAKE;
Emeric Brun674b7432012-11-08 19:21:55 +01004050 goto out_error;
4051 }
4052 }
4053 /* read some data: consider handshake completed */
4054 goto reneg_ok;
4055 }
4056
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02004057 ret = SSL_do_handshake(conn->xprt_ctx);
Emeric Brun46591952012-05-18 15:47:34 +02004058 if (ret != 1) {
4059 /* handshake did not complete, let's find why */
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02004060 ret = SSL_get_error(conn->xprt_ctx, ret);
Emeric Brun46591952012-05-18 15:47:34 +02004061
4062 if (ret == SSL_ERROR_WANT_WRITE) {
4063 /* SSL handshake needs to write, L4 connection may not be ready */
4064 __conn_sock_stop_recv(conn);
Willy Tarreaue1f50c42014-01-22 20:02:06 +01004065 __conn_sock_want_send(conn);
4066 fd_cant_send(conn->t.sock.fd);
Emeric Brun46591952012-05-18 15:47:34 +02004067 return 0;
4068 }
4069 else if (ret == SSL_ERROR_WANT_READ) {
4070 /* SSL handshake needs to read, L4 connection is ready */
4071 if (conn->flags & CO_FL_WAIT_L4_CONN)
4072 conn->flags &= ~CO_FL_WAIT_L4_CONN;
4073 __conn_sock_stop_send(conn);
Willy Tarreaue1f50c42014-01-22 20:02:06 +01004074 __conn_sock_want_recv(conn);
4075 fd_cant_recv(conn->t.sock.fd);
Emeric Brun46591952012-05-18 15:47:34 +02004076 return 0;
4077 }
Willy Tarreau89230192012-09-28 20:22:13 +02004078 else if (ret == SSL_ERROR_SYSCALL) {
4079 /* if errno is null, then connection was successfully established */
4080 if (!errno && conn->flags & CO_FL_WAIT_L4_CONN)
4081 conn->flags &= ~CO_FL_WAIT_L4_CONN;
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +01004082 if (!conn->err_code) {
4083#ifdef OPENSSL_NO_HEARTBEATS /* BoringSSL */
4084 conn->err_code = CO_ER_SSL_HANDSHAKE;
4085#else
4086 int empty_handshake;
Luca Pizzamiglio578b1692016-12-12 10:56:56 +01004087#if (OPENSSL_VERSION_NUMBER >= 0x1010000fL) && !defined(LIBRESSL_VERSION_NUMBER)
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +01004088 OSSL_HANDSHAKE_STATE state = SSL_get_state((SSL *)conn->xprt_ctx);
4089 empty_handshake = state == TLS_ST_BEFORE;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004090#else
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +01004091 empty_handshake = !((SSL *)conn->xprt_ctx)->packet_length;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004092#endif
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +01004093 if (empty_handshake) {
4094 if (!errno) {
4095 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
4096 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
4097 else
4098 conn->err_code = CO_ER_SSL_EMPTY;
4099 }
4100 else {
4101 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
4102 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
4103 else
4104 conn->err_code = CO_ER_SSL_ABORT;
4105 }
Emeric Brun29f037d2014-04-25 19:05:36 +02004106 }
4107 else {
4108 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
4109 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
4110 else
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +01004111 conn->err_code = CO_ER_SSL_HANDSHAKE;
Emeric Brun29f037d2014-04-25 19:05:36 +02004112 }
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +01004113#endif
Emeric Brun29f037d2014-04-25 19:05:36 +02004114 }
Willy Tarreau89230192012-09-28 20:22:13 +02004115 goto out_error;
4116 }
Emeric Brun46591952012-05-18 15:47:34 +02004117 else {
4118 /* Fail on all other handshake errors */
Willy Tarreau566dc552012-10-19 20:52:18 +02004119 /* Note: OpenSSL may leave unread bytes in the socket's
4120 * buffer, causing an RST to be emitted upon close() on
4121 * TCP sockets. We first try to drain possibly pending
4122 * data to avoid this as much as possible.
4123 */
Willy Tarreaud85c4852015-03-13 00:40:28 +01004124 conn_sock_drain(conn);
Willy Tarreau20879a02012-12-03 16:32:10 +01004125 if (!conn->err_code)
Willy Tarreauf51c6982014-04-25 20:02:39 +02004126 conn->err_code = (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT) ?
4127 CO_ER_SSL_KILLED_HB : CO_ER_SSL_HANDSHAKE;
Emeric Brun46591952012-05-18 15:47:34 +02004128 goto out_error;
4129 }
4130 }
4131
Emeric Brun674b7432012-11-08 19:21:55 +01004132reneg_ok:
Emeric Brun46591952012-05-18 15:47:34 +02004133 /* Handshake succeeded */
Willy Tarreau0c9c2722014-05-28 12:28:58 +02004134 if (!SSL_session_reused(conn->xprt_ctx)) {
4135 if (objt_server(conn->target)) {
4136 update_freq_ctr(&global.ssl_be_keys_per_sec, 1);
4137 if (global.ssl_be_keys_per_sec.curr_ctr > global.ssl_be_keys_max)
4138 global.ssl_be_keys_max = global.ssl_be_keys_per_sec.curr_ctr;
4139
Emeric Brun46591952012-05-18 15:47:34 +02004140 /* check if session was reused, if not store current session on server for reuse */
Willy Tarreau30fd4bd2016-12-22 21:54:21 +01004141 if (objt_server(conn->target)->ssl_ctx.reused_sess) {
Willy Tarreau3fdb3662012-11-12 00:42:33 +01004142 SSL_SESSION_free(objt_server(conn->target)->ssl_ctx.reused_sess);
Willy Tarreau30fd4bd2016-12-22 21:54:21 +01004143 objt_server(conn->target)->ssl_ctx.reused_sess = NULL;
4144 }
Emeric Brun46591952012-05-18 15:47:34 +02004145
Willy Tarreau2a3fb1c2015-02-05 16:47:07 +01004146 if (!(objt_server(conn->target)->ssl_ctx.options & SRV_SSL_O_NO_REUSE))
4147 objt_server(conn->target)->ssl_ctx.reused_sess = SSL_get1_session(conn->xprt_ctx);
Emeric Brun46591952012-05-18 15:47:34 +02004148 }
Willy Tarreau0c9c2722014-05-28 12:28:58 +02004149 else {
4150 update_freq_ctr(&global.ssl_fe_keys_per_sec, 1);
4151 if (global.ssl_fe_keys_per_sec.curr_ctr > global.ssl_fe_keys_max)
4152 global.ssl_fe_keys_max = global.ssl_fe_keys_per_sec.curr_ctr;
4153 }
Emeric Brun46591952012-05-18 15:47:34 +02004154 }
4155
4156 /* The connection is now established at both layers, it's time to leave */
4157 conn->flags &= ~(flag | CO_FL_WAIT_L4_CONN | CO_FL_WAIT_L6_CONN);
4158 return 1;
4159
4160 out_error:
Emeric Brun644cde02012-12-14 11:21:13 +01004161 /* Clear openssl global errors stack */
Thierry FOURNIER / OZON.IO8b068c22016-10-10 11:59:50 +02004162 ssl_sock_dump_errors(conn);
Emeric Brun644cde02012-12-14 11:21:13 +01004163 ERR_clear_error();
4164
Emeric Brun9fa89732012-10-04 17:09:56 +02004165 /* free resumed session if exists */
Willy Tarreau3fdb3662012-11-12 00:42:33 +01004166 if (objt_server(conn->target) && objt_server(conn->target)->ssl_ctx.reused_sess) {
4167 SSL_SESSION_free(objt_server(conn->target)->ssl_ctx.reused_sess);
4168 objt_server(conn->target)->ssl_ctx.reused_sess = NULL;
Emeric Brun9fa89732012-10-04 17:09:56 +02004169 }
4170
Emeric Brun46591952012-05-18 15:47:34 +02004171 /* Fail on all other handshake errors */
4172 conn->flags |= CO_FL_ERROR;
Willy Tarreau20879a02012-12-03 16:32:10 +01004173 if (!conn->err_code)
4174 conn->err_code = CO_ER_SSL_HANDSHAKE;
Emeric Brun46591952012-05-18 15:47:34 +02004175 return 0;
4176}
4177
4178/* Receive up to <count> bytes from connection <conn>'s socket and store them
Willy Tarreauabf08d92014-01-14 11:31:27 +01004179 * into buffer <buf>. Only one call to recv() is performed, unless the
Emeric Brun46591952012-05-18 15:47:34 +02004180 * buffer wraps, in which case a second call may be performed. The connection's
4181 * flags are updated with whatever special event is detected (error, read0,
4182 * empty). The caller is responsible for taking care of those events and
4183 * avoiding the call if inappropriate. The function does not call the
4184 * connection's polling update function, so the caller is responsible for this.
4185 */
4186static int ssl_sock_to_buf(struct connection *conn, struct buffer *buf, int count)
4187{
4188 int ret, done = 0;
Willy Tarreauabf08d92014-01-14 11:31:27 +01004189 int try;
Emeric Brun46591952012-05-18 15:47:34 +02004190
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02004191 if (!conn->xprt_ctx)
Emeric Brun46591952012-05-18 15:47:34 +02004192 goto out_error;
4193
4194 if (conn->flags & CO_FL_HANDSHAKE)
4195 /* a handshake was requested */
4196 return 0;
4197
Willy Tarreauabf08d92014-01-14 11:31:27 +01004198 /* let's realign the buffer to optimize I/O */
4199 if (buffer_empty(buf))
Emeric Brun46591952012-05-18 15:47:34 +02004200 buf->p = buf->data;
Emeric Brun46591952012-05-18 15:47:34 +02004201
4202 /* read the largest possible block. For this, we perform only one call
4203 * to recv() unless the buffer wraps and we exactly fill the first hunk,
4204 * in which case we accept to do it once again. A new attempt is made on
4205 * EINTR too.
4206 */
Willy Tarreau00b0fb92014-01-17 11:09:40 +01004207 while (count > 0) {
Willy Tarreauabf08d92014-01-14 11:31:27 +01004208 /* first check if we have some room after p+i */
4209 try = buf->data + buf->size - (buf->p + buf->i);
4210 /* otherwise continue between data and p-o */
4211 if (try <= 0) {
4212 try = buf->p - (buf->data + buf->o);
4213 if (try <= 0)
4214 break;
4215 }
4216 if (try > count)
4217 try = count;
4218
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02004219 ret = SSL_read(conn->xprt_ctx, bi_end(buf), try);
Emeric Brune1f38db2012-09-03 20:36:47 +02004220 if (conn->flags & CO_FL_ERROR) {
4221 /* CO_FL_ERROR may be set by ssl_sock_infocbk */
Emeric Brun644cde02012-12-14 11:21:13 +01004222 goto out_error;
Emeric Brune1f38db2012-09-03 20:36:47 +02004223 }
Emeric Brun46591952012-05-18 15:47:34 +02004224 if (ret > 0) {
4225 buf->i += ret;
4226 done += ret;
4227 if (ret < try)
4228 break;
4229 count -= ret;
Emeric Brun46591952012-05-18 15:47:34 +02004230 }
4231 else if (ret == 0) {
Emeric Brun644cde02012-12-14 11:21:13 +01004232 ret = SSL_get_error(conn->xprt_ctx, ret);
4233 if (ret != SSL_ERROR_ZERO_RETURN) {
Emeric Brun1c646862012-12-14 12:33:41 +01004234 /* error on protocol or underlying transport */
4235 if ((ret != SSL_ERROR_SYSCALL)
4236 || (errno && (errno != EAGAIN)))
4237 conn->flags |= CO_FL_ERROR;
4238
Emeric Brun644cde02012-12-14 11:21:13 +01004239 /* Clear openssl global errors stack */
Thierry FOURNIER / OZON.IO8b068c22016-10-10 11:59:50 +02004240 ssl_sock_dump_errors(conn);
Emeric Brun644cde02012-12-14 11:21:13 +01004241 ERR_clear_error();
4242 }
Emeric Brun46591952012-05-18 15:47:34 +02004243 goto read0;
4244 }
4245 else {
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02004246 ret = SSL_get_error(conn->xprt_ctx, ret);
Emeric Brun46591952012-05-18 15:47:34 +02004247 if (ret == SSL_ERROR_WANT_WRITE) {
Emeric Brun8af8dd12012-11-08 17:56:20 +01004248 /* handshake is running, and it needs to enable write */
Emeric Brun46591952012-05-18 15:47:34 +02004249 conn->flags |= CO_FL_SSL_WAIT_HS;
Emeric Brun8af8dd12012-11-08 17:56:20 +01004250 __conn_sock_want_send(conn);
Emeric Brun46591952012-05-18 15:47:34 +02004251 break;
4252 }
4253 else if (ret == SSL_ERROR_WANT_READ) {
Emeric Brun282a76a2012-11-08 18:02:56 +01004254 if (SSL_renegotiate_pending(conn->xprt_ctx)) {
4255 /* handshake is running, and it may need to re-enable read */
4256 conn->flags |= CO_FL_SSL_WAIT_HS;
4257 __conn_sock_want_recv(conn);
4258 break;
4259 }
Emeric Brun46591952012-05-18 15:47:34 +02004260 /* we need to poll for retry a read later */
Willy Tarreaue1f50c42014-01-22 20:02:06 +01004261 fd_cant_recv(conn->t.sock.fd);
Emeric Brun46591952012-05-18 15:47:34 +02004262 break;
4263 }
4264 /* otherwise it's a real error */
4265 goto out_error;
4266 }
4267 }
4268 return done;
4269
4270 read0:
4271 conn_sock_read0(conn);
4272 return done;
4273 out_error:
Emeric Brun644cde02012-12-14 11:21:13 +01004274 /* Clear openssl global errors stack */
Thierry FOURNIER / OZON.IO8b068c22016-10-10 11:59:50 +02004275 ssl_sock_dump_errors(conn);
Emeric Brun644cde02012-12-14 11:21:13 +01004276 ERR_clear_error();
4277
Emeric Brun46591952012-05-18 15:47:34 +02004278 conn->flags |= CO_FL_ERROR;
4279 return done;
4280}
4281
4282
4283/* Send all pending bytes from buffer <buf> to connection <conn>'s socket.
Willy Tarreau1049b1f2014-02-02 01:51:17 +01004284 * <flags> may contain some CO_SFL_* flags to hint the system about other
4285 * pending data for example, but this flag is ignored at the moment.
Emeric Brun46591952012-05-18 15:47:34 +02004286 * Only one call to send() is performed, unless the buffer wraps, in which case
4287 * a second call may be performed. The connection's flags are updated with
4288 * whatever special event is detected (error, empty). The caller is responsible
4289 * for taking care of those events and avoiding the call if inappropriate. The
4290 * function does not call the connection's polling update function, so the caller
4291 * is responsible for this.
4292 */
4293static int ssl_sock_from_buf(struct connection *conn, struct buffer *buf, int flags)
4294{
4295 int ret, try, done;
4296
4297 done = 0;
4298
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02004299 if (!conn->xprt_ctx)
Emeric Brun46591952012-05-18 15:47:34 +02004300 goto out_error;
4301
4302 if (conn->flags & CO_FL_HANDSHAKE)
4303 /* a handshake was requested */
4304 return 0;
4305
4306 /* send the largest possible block. For this we perform only one call
4307 * to send() unless the buffer wraps and we exactly fill the first hunk,
4308 * in which case we accept to do it once again.
4309 */
4310 while (buf->o) {
Kevin Hestercad82342013-05-30 15:12:41 -07004311 try = bo_contig_data(buf);
Willy Tarreaubfd59462013-02-21 07:46:09 +01004312
Willy Tarreau7bed9452014-02-02 02:00:24 +01004313 if (!(flags & CO_SFL_STREAMER) &&
Willy Tarreau518cedd2014-02-17 15:43:01 +01004314 !(conn->xprt_st & SSL_SOCK_SEND_UNLIMITED) &&
Willy Tarreauef934602016-12-22 23:12:01 +01004315 global_ssl.max_record && try > global_ssl.max_record) {
4316 try = global_ssl.max_record;
Willy Tarreau518cedd2014-02-17 15:43:01 +01004317 }
4318 else {
4319 /* we need to keep the information about the fact that
4320 * we're not limiting the upcoming send(), because if it
4321 * fails, we'll have to retry with at least as many data.
4322 */
4323 conn->xprt_st |= SSL_SOCK_SEND_UNLIMITED;
4324 }
Willy Tarreaubfd59462013-02-21 07:46:09 +01004325
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02004326 ret = SSL_write(conn->xprt_ctx, bo_ptr(buf), try);
Willy Tarreau518cedd2014-02-17 15:43:01 +01004327
Emeric Brune1f38db2012-09-03 20:36:47 +02004328 if (conn->flags & CO_FL_ERROR) {
4329 /* CO_FL_ERROR may be set by ssl_sock_infocbk */
Emeric Brun644cde02012-12-14 11:21:13 +01004330 goto out_error;
Emeric Brune1f38db2012-09-03 20:36:47 +02004331 }
Emeric Brun46591952012-05-18 15:47:34 +02004332 if (ret > 0) {
Willy Tarreau518cedd2014-02-17 15:43:01 +01004333 conn->xprt_st &= ~SSL_SOCK_SEND_UNLIMITED;
4334
Emeric Brun46591952012-05-18 15:47:34 +02004335 buf->o -= ret;
4336 done += ret;
4337
Willy Tarreau5fb38032012-12-16 19:39:09 +01004338 if (likely(buffer_empty(buf)))
Emeric Brun46591952012-05-18 15:47:34 +02004339 /* optimize data alignment in the buffer */
4340 buf->p = buf->data;
4341
4342 /* if the system buffer is full, don't insist */
4343 if (ret < try)
4344 break;
4345 }
4346 else {
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02004347 ret = SSL_get_error(conn->xprt_ctx, ret);
Emeric Brun46591952012-05-18 15:47:34 +02004348 if (ret == SSL_ERROR_WANT_WRITE) {
Emeric Brun282a76a2012-11-08 18:02:56 +01004349 if (SSL_renegotiate_pending(conn->xprt_ctx)) {
4350 /* handshake is running, and it may need to re-enable write */
4351 conn->flags |= CO_FL_SSL_WAIT_HS;
4352 __conn_sock_want_send(conn);
4353 break;
4354 }
Emeric Brun46591952012-05-18 15:47:34 +02004355 /* we need to poll to retry a write later */
Willy Tarreaue1f50c42014-01-22 20:02:06 +01004356 fd_cant_send(conn->t.sock.fd);
Emeric Brun46591952012-05-18 15:47:34 +02004357 break;
4358 }
4359 else if (ret == SSL_ERROR_WANT_READ) {
Emeric Brun8af8dd12012-11-08 17:56:20 +01004360 /* handshake is running, and it needs to enable read */
Emeric Brun46591952012-05-18 15:47:34 +02004361 conn->flags |= CO_FL_SSL_WAIT_HS;
Emeric Brun8af8dd12012-11-08 17:56:20 +01004362 __conn_sock_want_recv(conn);
Emeric Brun46591952012-05-18 15:47:34 +02004363 break;
4364 }
4365 goto out_error;
4366 }
4367 }
4368 return done;
4369
4370 out_error:
Emeric Brun644cde02012-12-14 11:21:13 +01004371 /* Clear openssl global errors stack */
Thierry FOURNIER / OZON.IO8b068c22016-10-10 11:59:50 +02004372 ssl_sock_dump_errors(conn);
Emeric Brun644cde02012-12-14 11:21:13 +01004373 ERR_clear_error();
4374
Emeric Brun46591952012-05-18 15:47:34 +02004375 conn->flags |= CO_FL_ERROR;
4376 return done;
4377}
4378
Emeric Brun46591952012-05-18 15:47:34 +02004379static void ssl_sock_close(struct connection *conn) {
4380
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02004381 if (conn->xprt_ctx) {
4382 SSL_free(conn->xprt_ctx);
4383 conn->xprt_ctx = NULL;
Willy Tarreau403edff2012-09-06 11:58:37 +02004384 sslconns--;
Emeric Brun46591952012-05-18 15:47:34 +02004385 }
Emeric Brun46591952012-05-18 15:47:34 +02004386}
4387
4388/* This function tries to perform a clean shutdown on an SSL connection, and in
4389 * any case, flags the connection as reusable if no handshake was in progress.
4390 */
4391static void ssl_sock_shutw(struct connection *conn, int clean)
4392{
4393 if (conn->flags & CO_FL_HANDSHAKE)
4394 return;
Emmanuel Hocdet405ff312017-01-08 14:07:39 +01004395 if (!clean)
4396 /* don't sent notify on SSL_shutdown */
Willy Tarreaue3cc3a32017-02-13 11:12:29 +01004397 SSL_set_quiet_shutdown(conn->xprt_ctx, 1);
Emeric Brun46591952012-05-18 15:47:34 +02004398 /* no handshake was in progress, try a clean ssl shutdown */
Emmanuel Hocdet405ff312017-01-08 14:07:39 +01004399 if (SSL_shutdown(conn->xprt_ctx) <= 0) {
Emeric Brun644cde02012-12-14 11:21:13 +01004400 /* Clear openssl global errors stack */
Thierry FOURNIER / OZON.IO8b068c22016-10-10 11:59:50 +02004401 ssl_sock_dump_errors(conn);
Emeric Brun644cde02012-12-14 11:21:13 +01004402 ERR_clear_error();
4403 }
Emeric Brun46591952012-05-18 15:47:34 +02004404}
4405
Willy Tarreauffc3fcd2012-10-12 20:17:54 +02004406/* used for logging, may be changed for a sample fetch later */
4407const char *ssl_sock_get_cipher_name(struct connection *conn)
4408{
4409 if (!conn->xprt && !conn->xprt_ctx)
4410 return NULL;
4411 return SSL_get_cipher_name(conn->xprt_ctx);
4412}
4413
4414/* used for logging, may be changed for a sample fetch later */
4415const char *ssl_sock_get_proto_version(struct connection *conn)
4416{
4417 if (!conn->xprt && !conn->xprt_ctx)
4418 return NULL;
4419 return SSL_get_version(conn->xprt_ctx);
4420}
4421
Willy Tarreau8d598402012-10-22 17:58:39 +02004422/* Extract a serial from a cert, and copy it to a chunk.
4423 * Returns 1 if serial is found and copied, 0 if no serial found and
4424 * -1 if output is not large enough.
4425 */
4426static int
4427ssl_sock_get_serial(X509 *crt, struct chunk *out)
4428{
4429 ASN1_INTEGER *serial;
4430
4431 serial = X509_get_serialNumber(crt);
4432 if (!serial)
4433 return 0;
4434
4435 if (out->size < serial->length)
4436 return -1;
4437
4438 memcpy(out->str, serial->data, serial->length);
4439 out->len = serial->length;
4440 return 1;
4441}
4442
Emeric Brun43e79582014-10-29 19:03:26 +01004443/* Extract a cert to der, and copy it to a chunk.
4444 * Returns 1 if cert is found and copied, 0 on der convertion failure and
4445 * -1 if output is not large enough.
4446 */
4447static int
4448ssl_sock_crt2der(X509 *crt, struct chunk *out)
4449{
4450 int len;
4451 unsigned char *p = (unsigned char *)out->str;;
4452
4453 len =i2d_X509(crt, NULL);
4454 if (len <= 0)
4455 return 1;
4456
4457 if (out->size < len)
4458 return -1;
4459
4460 i2d_X509(crt,&p);
4461 out->len = len;
4462 return 1;
4463}
4464
Emeric Brunce5ad802012-10-22 14:11:22 +02004465
4466/* Copy Date in ASN1_UTCTIME format in struct chunk out.
4467 * Returns 1 if serial is found and copied, 0 if no valid time found
4468 * and -1 if output is not large enough.
4469 */
4470static int
4471ssl_sock_get_time(ASN1_TIME *tm, struct chunk *out)
4472{
4473 if (tm->type == V_ASN1_GENERALIZEDTIME) {
4474 ASN1_GENERALIZEDTIME *gentm = (ASN1_GENERALIZEDTIME *)tm;
4475
4476 if (gentm->length < 12)
4477 return 0;
4478 if (gentm->data[0] != 0x32 || gentm->data[1] != 0x30)
4479 return 0;
4480 if (out->size < gentm->length-2)
4481 return -1;
4482
4483 memcpy(out->str, gentm->data+2, gentm->length-2);
4484 out->len = gentm->length-2;
4485 return 1;
4486 }
4487 else if (tm->type == V_ASN1_UTCTIME) {
4488 ASN1_UTCTIME *utctm = (ASN1_UTCTIME *)tm;
4489
4490 if (utctm->length < 10)
4491 return 0;
4492 if (utctm->data[0] >= 0x35)
4493 return 0;
4494 if (out->size < utctm->length)
4495 return -1;
4496
4497 memcpy(out->str, utctm->data, utctm->length);
4498 out->len = utctm->length;
4499 return 1;
4500 }
4501
4502 return 0;
4503}
4504
Emeric Brun87855892012-10-17 17:39:35 +02004505/* Extract an entry from a X509_NAME and copy its value to an output chunk.
4506 * Returns 1 if entry found, 0 if entry not found, or -1 if output not large enough.
4507 */
4508static int
4509ssl_sock_get_dn_entry(X509_NAME *a, const struct chunk *entry, int pos, struct chunk *out)
4510{
4511 X509_NAME_ENTRY *ne;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004512 ASN1_OBJECT *obj;
4513 ASN1_STRING *data;
4514 const unsigned char *data_ptr;
4515 int data_len;
Emeric Brun87855892012-10-17 17:39:35 +02004516 int i, j, n;
4517 int cur = 0;
4518 const char *s;
4519 char tmp[128];
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004520 int name_count;
4521
4522 name_count = X509_NAME_entry_count(a);
Emeric Brun87855892012-10-17 17:39:35 +02004523
4524 out->len = 0;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004525 for (i = 0; i < name_count; i++) {
Emeric Brun87855892012-10-17 17:39:35 +02004526 if (pos < 0)
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004527 j = (name_count-1) - i;
Emeric Brun87855892012-10-17 17:39:35 +02004528 else
4529 j = i;
4530
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004531 ne = X509_NAME_get_entry(a, j);
4532 obj = X509_NAME_ENTRY_get_object(ne);
4533 data = X509_NAME_ENTRY_get_data(ne);
4534 data_ptr = ASN1_STRING_get0_data(data);
4535 data_len = ASN1_STRING_length(data);
4536 n = OBJ_obj2nid(obj);
Emeric Brun87855892012-10-17 17:39:35 +02004537 if ((n == NID_undef) || ((s = OBJ_nid2sn(n)) == NULL)) {
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004538 i2t_ASN1_OBJECT(tmp, sizeof(tmp), obj);
Emeric Brun87855892012-10-17 17:39:35 +02004539 s = tmp;
4540 }
4541
4542 if (chunk_strcasecmp(entry, s) != 0)
4543 continue;
4544
4545 if (pos < 0)
4546 cur--;
4547 else
4548 cur++;
4549
4550 if (cur != pos)
4551 continue;
4552
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004553 if (data_len > out->size)
Emeric Brun87855892012-10-17 17:39:35 +02004554 return -1;
4555
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004556 memcpy(out->str, data_ptr, data_len);
4557 out->len = data_len;
Emeric Brun87855892012-10-17 17:39:35 +02004558 return 1;
4559 }
4560
4561 return 0;
4562
4563}
4564
4565/* Extract and format full DN from a X509_NAME and copy result into a chunk
4566 * Returns 1 if dn entries exits, 0 if no dn entry found or -1 if output is not large enough.
4567 */
4568static int
4569ssl_sock_get_dn_oneline(X509_NAME *a, struct chunk *out)
4570{
4571 X509_NAME_ENTRY *ne;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004572 ASN1_OBJECT *obj;
4573 ASN1_STRING *data;
4574 const unsigned char *data_ptr;
4575 int data_len;
Emeric Brun87855892012-10-17 17:39:35 +02004576 int i, n, ln;
4577 int l = 0;
4578 const char *s;
4579 char *p;
4580 char tmp[128];
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004581 int name_count;
4582
4583
4584 name_count = X509_NAME_entry_count(a);
Emeric Brun87855892012-10-17 17:39:35 +02004585
4586 out->len = 0;
4587 p = out->str;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004588 for (i = 0; i < name_count; i++) {
4589 ne = X509_NAME_get_entry(a, i);
4590 obj = X509_NAME_ENTRY_get_object(ne);
4591 data = X509_NAME_ENTRY_get_data(ne);
4592 data_ptr = ASN1_STRING_get0_data(data);
4593 data_len = ASN1_STRING_length(data);
4594 n = OBJ_obj2nid(obj);
Emeric Brun87855892012-10-17 17:39:35 +02004595 if ((n == NID_undef) || ((s = OBJ_nid2sn(n)) == NULL)) {
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004596 i2t_ASN1_OBJECT(tmp, sizeof(tmp), obj);
Emeric Brun87855892012-10-17 17:39:35 +02004597 s = tmp;
4598 }
4599 ln = strlen(s);
4600
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004601 l += 1 + ln + 1 + data_len;
Emeric Brun87855892012-10-17 17:39:35 +02004602 if (l > out->size)
4603 return -1;
4604 out->len = l;
4605
4606 *(p++)='/';
4607 memcpy(p, s, ln);
4608 p += ln;
4609 *(p++)='=';
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004610 memcpy(p, data_ptr, data_len);
4611 p += data_len;
Emeric Brun87855892012-10-17 17:39:35 +02004612 }
4613
4614 if (!out->len)
4615 return 0;
4616
4617 return 1;
4618}
4619
David Safb76832014-05-08 23:42:08 -04004620char *ssl_sock_get_version(struct connection *conn)
4621{
4622 if (!ssl_sock_is_ssl(conn))
4623 return NULL;
4624
4625 return (char *)SSL_get_version(conn->xprt_ctx);
4626}
4627
Willy Tarreau119a4082016-12-22 21:58:38 +01004628/* Sets advertised SNI for outgoing connections. Please set <hostname> to NULL
4629 * to disable SNI.
4630 */
Willy Tarreau63076412015-07-10 11:33:32 +02004631void ssl_sock_set_servername(struct connection *conn, const char *hostname)
4632{
4633#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Willy Tarreau119a4082016-12-22 21:58:38 +01004634 char *prev_name;
4635
Willy Tarreau63076412015-07-10 11:33:32 +02004636 if (!ssl_sock_is_ssl(conn))
4637 return;
4638
Willy Tarreau119a4082016-12-22 21:58:38 +01004639 /* if the SNI changes, we must destroy the reusable context so that a
4640 * new connection will present a new SNI. As an optimization we could
4641 * later imagine having a small cache of ssl_ctx to hold a few SNI per
4642 * server.
4643 */
4644 prev_name = (char *)SSL_get_servername(conn->xprt_ctx, TLSEXT_NAMETYPE_host_name);
4645 if ((!prev_name && hostname) ||
4646 (prev_name && (!hostname || strcmp(hostname, prev_name) != 0)))
4647 SSL_set_session(conn->xprt_ctx, NULL);
4648
Willy Tarreau63076412015-07-10 11:33:32 +02004649 SSL_set_tlsext_host_name(conn->xprt_ctx, hostname);
4650#endif
4651}
4652
Emeric Brun0abf8362014-06-24 18:26:41 +02004653/* Extract peer certificate's common name into the chunk dest
4654 * Returns
4655 * the len of the extracted common name
4656 * or 0 if no CN found in DN
4657 * or -1 on error case (i.e. no peer certificate)
4658 */
4659int ssl_sock_get_remote_common_name(struct connection *conn, struct chunk *dest)
David Safb76832014-05-08 23:42:08 -04004660{
4661 X509 *crt = NULL;
4662 X509_NAME *name;
David Safb76832014-05-08 23:42:08 -04004663 const char find_cn[] = "CN";
4664 const struct chunk find_cn_chunk = {
4665 .str = (char *)&find_cn,
4666 .len = sizeof(find_cn)-1
4667 };
Emeric Brun0abf8362014-06-24 18:26:41 +02004668 int result = -1;
David Safb76832014-05-08 23:42:08 -04004669
4670 if (!ssl_sock_is_ssl(conn))
Emeric Brun0abf8362014-06-24 18:26:41 +02004671 goto out;
David Safb76832014-05-08 23:42:08 -04004672
4673 /* SSL_get_peer_certificate, it increase X509 * ref count */
4674 crt = SSL_get_peer_certificate(conn->xprt_ctx);
4675 if (!crt)
4676 goto out;
4677
4678 name = X509_get_subject_name(crt);
4679 if (!name)
4680 goto out;
David Safb76832014-05-08 23:42:08 -04004681
Emeric Brun0abf8362014-06-24 18:26:41 +02004682 result = ssl_sock_get_dn_entry(name, &find_cn_chunk, 1, dest);
4683out:
David Safb76832014-05-08 23:42:08 -04004684 if (crt)
4685 X509_free(crt);
4686
4687 return result;
4688}
4689
Dave McCowan328fb582014-07-30 10:39:13 -04004690/* returns 1 if client passed a certificate for this session, 0 if not */
4691int ssl_sock_get_cert_used_sess(struct connection *conn)
4692{
4693 X509 *crt = NULL;
4694
4695 if (!ssl_sock_is_ssl(conn))
4696 return 0;
4697
4698 /* SSL_get_peer_certificate, it increase X509 * ref count */
4699 crt = SSL_get_peer_certificate(conn->xprt_ctx);
4700 if (!crt)
4701 return 0;
4702
4703 X509_free(crt);
4704 return 1;
4705}
4706
4707/* returns 1 if client passed a certificate for this connection, 0 if not */
4708int ssl_sock_get_cert_used_conn(struct connection *conn)
David Safb76832014-05-08 23:42:08 -04004709{
4710 if (!ssl_sock_is_ssl(conn))
4711 return 0;
4712
4713 return SSL_SOCK_ST_FL_VERIFY_DONE & conn->xprt_st ? 1 : 0;
4714}
4715
4716/* returns result from SSL verify */
4717unsigned int ssl_sock_get_verify_result(struct connection *conn)
4718{
4719 if (!ssl_sock_is_ssl(conn))
4720 return (unsigned int)X509_V_ERR_APPLICATION_VERIFICATION;
4721
4722 return (unsigned int)SSL_get_verify_result(conn->xprt_ctx);
4723}
4724
Willy Tarreau7875d092012-09-10 08:20:03 +02004725/***** Below are some sample fetching functions for ACL/patterns *****/
4726
Emeric Brune64aef12012-09-21 13:15:06 +02004727/* boolean, returns true if client cert was present */
4728static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004729smp_fetch_ssl_fc_has_crt(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brune64aef12012-09-21 13:15:06 +02004730{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004731 struct connection *conn;
4732
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004733 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004734 if (!conn || conn->xprt != &ssl_sock)
Emeric Brune64aef12012-09-21 13:15:06 +02004735 return 0;
4736
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004737 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brune64aef12012-09-21 13:15:06 +02004738 smp->flags |= SMP_F_MAY_CHANGE;
4739 return 0;
4740 }
4741
4742 smp->flags = 0;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004743 smp->data.type = SMP_T_BOOL;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004744 smp->data.u.sint = SSL_SOCK_ST_FL_VERIFY_DONE & conn->xprt_st ? 1 : 0;
Emeric Brune64aef12012-09-21 13:15:06 +02004745
4746 return 1;
4747}
4748
Emeric Brun43e79582014-10-29 19:03:26 +01004749/* binary, returns a certificate in a binary chunk (der/raw).
4750 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
4751 * should be use.
4752 */
4753static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004754smp_fetch_ssl_x_der(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun43e79582014-10-29 19:03:26 +01004755{
4756 int cert_peer = (kw[4] == 'c') ? 1 : 0;
4757 X509 *crt = NULL;
4758 int ret = 0;
4759 struct chunk *smp_trash;
4760 struct connection *conn;
4761
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004762 conn = objt_conn(smp->sess->origin);
Emeric Brun43e79582014-10-29 19:03:26 +01004763 if (!conn || conn->xprt != &ssl_sock)
4764 return 0;
4765
4766 if (!(conn->flags & CO_FL_CONNECTED)) {
4767 smp->flags |= SMP_F_MAY_CHANGE;
4768 return 0;
4769 }
4770
4771 if (cert_peer)
4772 crt = SSL_get_peer_certificate(conn->xprt_ctx);
4773 else
4774 crt = SSL_get_certificate(conn->xprt_ctx);
4775
4776 if (!crt)
4777 goto out;
4778
4779 smp_trash = get_trash_chunk();
4780 if (ssl_sock_crt2der(crt, smp_trash) <= 0)
4781 goto out;
4782
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004783 smp->data.u.str = *smp_trash;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004784 smp->data.type = SMP_T_BIN;
Emeric Brun43e79582014-10-29 19:03:26 +01004785 ret = 1;
4786out:
4787 /* SSL_get_peer_certificate, it increase X509 * ref count */
4788 if (cert_peer && crt)
4789 X509_free(crt);
4790 return ret;
4791}
4792
Emeric Brunba841a12014-04-30 17:05:08 +02004793/* binary, returns serial of certificate in a binary chunk.
4794 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
4795 * should be use.
4796 */
Willy Tarreau8d598402012-10-22 17:58:39 +02004797static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004798smp_fetch_ssl_x_serial(const struct arg *args, struct sample *smp, const char *kw, void *private)
Willy Tarreau8d598402012-10-22 17:58:39 +02004799{
Emeric Brunba841a12014-04-30 17:05:08 +02004800 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Willy Tarreau8d598402012-10-22 17:58:39 +02004801 X509 *crt = NULL;
4802 int ret = 0;
4803 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004804 struct connection *conn;
4805
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004806 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004807 if (!conn || conn->xprt != &ssl_sock)
Willy Tarreau8d598402012-10-22 17:58:39 +02004808 return 0;
4809
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004810 if (!(conn->flags & CO_FL_CONNECTED)) {
Willy Tarreau8d598402012-10-22 17:58:39 +02004811 smp->flags |= SMP_F_MAY_CHANGE;
4812 return 0;
4813 }
4814
Emeric Brunba841a12014-04-30 17:05:08 +02004815 if (cert_peer)
4816 crt = SSL_get_peer_certificate(conn->xprt_ctx);
4817 else
4818 crt = SSL_get_certificate(conn->xprt_ctx);
4819
Willy Tarreau8d598402012-10-22 17:58:39 +02004820 if (!crt)
4821 goto out;
4822
Willy Tarreau47ca5452012-12-23 20:22:19 +01004823 smp_trash = get_trash_chunk();
Willy Tarreau8d598402012-10-22 17:58:39 +02004824 if (ssl_sock_get_serial(crt, smp_trash) <= 0)
4825 goto out;
4826
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004827 smp->data.u.str = *smp_trash;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004828 smp->data.type = SMP_T_BIN;
Willy Tarreau8d598402012-10-22 17:58:39 +02004829 ret = 1;
4830out:
Emeric Brunba841a12014-04-30 17:05:08 +02004831 /* SSL_get_peer_certificate, it increase X509 * ref count */
4832 if (cert_peer && crt)
Willy Tarreau8d598402012-10-22 17:58:39 +02004833 X509_free(crt);
4834 return ret;
4835}
Emeric Brune64aef12012-09-21 13:15:06 +02004836
Emeric Brunba841a12014-04-30 17:05:08 +02004837/* binary, returns the client certificate's SHA-1 fingerprint (SHA-1 hash of DER-encoded certificate) in a binary chunk.
4838 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
4839 * should be use.
4840 */
James Votha051b4a2013-05-14 20:37:59 +02004841static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004842smp_fetch_ssl_x_sha1(const struct arg *args, struct sample *smp, const char *kw, void *private)
James Votha051b4a2013-05-14 20:37:59 +02004843{
Emeric Brunba841a12014-04-30 17:05:08 +02004844 int cert_peer = (kw[4] == 'c') ? 1 : 0;
James Votha051b4a2013-05-14 20:37:59 +02004845 X509 *crt = NULL;
4846 const EVP_MD *digest;
4847 int ret = 0;
4848 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004849 struct connection *conn;
James Votha051b4a2013-05-14 20:37:59 +02004850
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004851 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004852 if (!conn || conn->xprt != &ssl_sock)
4853 return 0;
4854
4855 if (!(conn->flags & CO_FL_CONNECTED)) {
James Votha051b4a2013-05-14 20:37:59 +02004856 smp->flags |= SMP_F_MAY_CHANGE;
4857 return 0;
4858 }
4859
Emeric Brunba841a12014-04-30 17:05:08 +02004860 if (cert_peer)
4861 crt = SSL_get_peer_certificate(conn->xprt_ctx);
4862 else
4863 crt = SSL_get_certificate(conn->xprt_ctx);
James Votha051b4a2013-05-14 20:37:59 +02004864 if (!crt)
4865 goto out;
4866
4867 smp_trash = get_trash_chunk();
4868 digest = EVP_sha1();
4869 X509_digest(crt, digest, (unsigned char *)smp_trash->str, (unsigned int *)&smp_trash->len);
4870
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004871 smp->data.u.str = *smp_trash;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004872 smp->data.type = SMP_T_BIN;
James Votha051b4a2013-05-14 20:37:59 +02004873 ret = 1;
4874out:
Emeric Brunba841a12014-04-30 17:05:08 +02004875 /* SSL_get_peer_certificate, it increase X509 * ref count */
4876 if (cert_peer && crt)
James Votha051b4a2013-05-14 20:37:59 +02004877 X509_free(crt);
4878 return ret;
4879}
4880
Emeric Brunba841a12014-04-30 17:05:08 +02004881/* string, returns certificate's notafter date in ASN1_UTCTIME format.
4882 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
4883 * should be use.
4884 */
Emeric Brunce5ad802012-10-22 14:11:22 +02004885static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004886smp_fetch_ssl_x_notafter(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brunce5ad802012-10-22 14:11:22 +02004887{
Emeric Brunba841a12014-04-30 17:05:08 +02004888 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brunce5ad802012-10-22 14:11:22 +02004889 X509 *crt = NULL;
4890 int ret = 0;
4891 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004892 struct connection *conn;
Emeric Brunce5ad802012-10-22 14:11:22 +02004893
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004894 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004895 if (!conn || conn->xprt != &ssl_sock)
4896 return 0;
4897
4898 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunce5ad802012-10-22 14:11:22 +02004899 smp->flags |= SMP_F_MAY_CHANGE;
4900 return 0;
4901 }
4902
Emeric Brunba841a12014-04-30 17:05:08 +02004903 if (cert_peer)
4904 crt = SSL_get_peer_certificate(conn->xprt_ctx);
4905 else
4906 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brunce5ad802012-10-22 14:11:22 +02004907 if (!crt)
4908 goto out;
4909
Willy Tarreau47ca5452012-12-23 20:22:19 +01004910 smp_trash = get_trash_chunk();
Emeric Brunce5ad802012-10-22 14:11:22 +02004911 if (ssl_sock_get_time(X509_get_notAfter(crt), smp_trash) <= 0)
4912 goto out;
4913
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004914 smp->data.u.str = *smp_trash;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004915 smp->data.type = SMP_T_STR;
Emeric Brunce5ad802012-10-22 14:11:22 +02004916 ret = 1;
4917out:
Emeric Brunba841a12014-04-30 17:05:08 +02004918 /* SSL_get_peer_certificate, it increase X509 * ref count */
4919 if (cert_peer && crt)
Emeric Brunce5ad802012-10-22 14:11:22 +02004920 X509_free(crt);
4921 return ret;
4922}
4923
Emeric Brunba841a12014-04-30 17:05:08 +02004924/* string, returns a string of a formatted full dn \C=..\O=..\OU=.. \CN=.. of certificate's issuer
4925 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
4926 * should be use.
4927 */
Emeric Brun87855892012-10-17 17:39:35 +02004928static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004929smp_fetch_ssl_x_i_dn(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun87855892012-10-17 17:39:35 +02004930{
Emeric Brunba841a12014-04-30 17:05:08 +02004931 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brun87855892012-10-17 17:39:35 +02004932 X509 *crt = NULL;
4933 X509_NAME *name;
4934 int ret = 0;
4935 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004936 struct connection *conn;
Emeric Brun87855892012-10-17 17:39:35 +02004937
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004938 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004939 if (!conn || conn->xprt != &ssl_sock)
4940 return 0;
4941
4942 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun87855892012-10-17 17:39:35 +02004943 smp->flags |= SMP_F_MAY_CHANGE;
4944 return 0;
4945 }
4946
Emeric Brunba841a12014-04-30 17:05:08 +02004947 if (cert_peer)
4948 crt = SSL_get_peer_certificate(conn->xprt_ctx);
4949 else
4950 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brun87855892012-10-17 17:39:35 +02004951 if (!crt)
4952 goto out;
4953
4954 name = X509_get_issuer_name(crt);
4955 if (!name)
4956 goto out;
4957
Willy Tarreau47ca5452012-12-23 20:22:19 +01004958 smp_trash = get_trash_chunk();
Emeric Brun87855892012-10-17 17:39:35 +02004959 if (args && args[0].type == ARGT_STR) {
4960 int pos = 1;
4961
4962 if (args[1].type == ARGT_SINT)
4963 pos = args[1].data.sint;
Emeric Brun87855892012-10-17 17:39:35 +02004964
4965 if (ssl_sock_get_dn_entry(name, &args[0].data.str, pos, smp_trash) <= 0)
4966 goto out;
4967 }
4968 else if (ssl_sock_get_dn_oneline(name, smp_trash) <= 0)
4969 goto out;
4970
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004971 smp->data.type = SMP_T_STR;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004972 smp->data.u.str = *smp_trash;
Emeric Brun87855892012-10-17 17:39:35 +02004973 ret = 1;
4974out:
Emeric Brunba841a12014-04-30 17:05:08 +02004975 /* SSL_get_peer_certificate, it increase X509 * ref count */
4976 if (cert_peer && crt)
Emeric Brun87855892012-10-17 17:39:35 +02004977 X509_free(crt);
4978 return ret;
4979}
4980
Emeric Brunba841a12014-04-30 17:05:08 +02004981/* string, returns notbefore date in ASN1_UTCTIME format.
4982 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
4983 * should be use.
4984 */
Emeric Brunce5ad802012-10-22 14:11:22 +02004985static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004986smp_fetch_ssl_x_notbefore(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brunce5ad802012-10-22 14:11:22 +02004987{
Emeric Brunba841a12014-04-30 17:05:08 +02004988 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brunce5ad802012-10-22 14:11:22 +02004989 X509 *crt = NULL;
4990 int ret = 0;
4991 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004992 struct connection *conn;
4993
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004994 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004995 if (!conn || conn->xprt != &ssl_sock)
Emeric Brunce5ad802012-10-22 14:11:22 +02004996 return 0;
4997
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004998 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunce5ad802012-10-22 14:11:22 +02004999 smp->flags |= SMP_F_MAY_CHANGE;
5000 return 0;
5001 }
5002
Emeric Brunba841a12014-04-30 17:05:08 +02005003 if (cert_peer)
5004 crt = SSL_get_peer_certificate(conn->xprt_ctx);
5005 else
5006 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brunce5ad802012-10-22 14:11:22 +02005007 if (!crt)
5008 goto out;
5009
Willy Tarreau47ca5452012-12-23 20:22:19 +01005010 smp_trash = get_trash_chunk();
Emeric Brunce5ad802012-10-22 14:11:22 +02005011 if (ssl_sock_get_time(X509_get_notBefore(crt), smp_trash) <= 0)
5012 goto out;
5013
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005014 smp->data.u.str = *smp_trash;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005015 smp->data.type = SMP_T_STR;
Emeric Brunce5ad802012-10-22 14:11:22 +02005016 ret = 1;
5017out:
Emeric Brunba841a12014-04-30 17:05:08 +02005018 /* SSL_get_peer_certificate, it increase X509 * ref count */
5019 if (cert_peer && crt)
Emeric Brunce5ad802012-10-22 14:11:22 +02005020 X509_free(crt);
5021 return ret;
5022}
5023
Emeric Brunba841a12014-04-30 17:05:08 +02005024/* string, returns a string of a formatted full dn \C=..\O=..\OU=.. \CN=.. of certificate's subject
5025 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
5026 * should be use.
5027 */
Emeric Brun87855892012-10-17 17:39:35 +02005028static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005029smp_fetch_ssl_x_s_dn(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun87855892012-10-17 17:39:35 +02005030{
Emeric Brunba841a12014-04-30 17:05:08 +02005031 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brun87855892012-10-17 17:39:35 +02005032 X509 *crt = NULL;
5033 X509_NAME *name;
5034 int ret = 0;
5035 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005036 struct connection *conn;
Emeric Brun87855892012-10-17 17:39:35 +02005037
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02005038 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005039 if (!conn || conn->xprt != &ssl_sock)
5040 return 0;
5041
5042 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun87855892012-10-17 17:39:35 +02005043 smp->flags |= SMP_F_MAY_CHANGE;
5044 return 0;
5045 }
5046
Emeric Brunba841a12014-04-30 17:05:08 +02005047 if (cert_peer)
5048 crt = SSL_get_peer_certificate(conn->xprt_ctx);
5049 else
5050 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brun87855892012-10-17 17:39:35 +02005051 if (!crt)
5052 goto out;
5053
5054 name = X509_get_subject_name(crt);
5055 if (!name)
5056 goto out;
5057
Willy Tarreau47ca5452012-12-23 20:22:19 +01005058 smp_trash = get_trash_chunk();
Emeric Brun87855892012-10-17 17:39:35 +02005059 if (args && args[0].type == ARGT_STR) {
5060 int pos = 1;
5061
5062 if (args[1].type == ARGT_SINT)
5063 pos = args[1].data.sint;
Emeric Brun87855892012-10-17 17:39:35 +02005064
5065 if (ssl_sock_get_dn_entry(name, &args[0].data.str, pos, smp_trash) <= 0)
5066 goto out;
5067 }
5068 else if (ssl_sock_get_dn_oneline(name, smp_trash) <= 0)
5069 goto out;
5070
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005071 smp->data.type = SMP_T_STR;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005072 smp->data.u.str = *smp_trash;
Emeric Brun87855892012-10-17 17:39:35 +02005073 ret = 1;
5074out:
Emeric Brunba841a12014-04-30 17:05:08 +02005075 /* SSL_get_peer_certificate, it increase X509 * ref count */
5076 if (cert_peer && crt)
Emeric Brun87855892012-10-17 17:39:35 +02005077 X509_free(crt);
5078 return ret;
5079}
Emeric Brun9143d372012-12-20 15:44:16 +01005080
5081/* integer, returns true if current session use a client certificate */
5082static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005083smp_fetch_ssl_c_used(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun9143d372012-12-20 15:44:16 +01005084{
5085 X509 *crt;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005086 struct connection *conn;
Emeric Brun9143d372012-12-20 15:44:16 +01005087
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02005088 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005089 if (!conn || conn->xprt != &ssl_sock)
5090 return 0;
5091
5092 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun9143d372012-12-20 15:44:16 +01005093 smp->flags |= SMP_F_MAY_CHANGE;
5094 return 0;
5095 }
5096
5097 /* SSL_get_peer_certificate returns a ptr on allocated X509 struct */
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005098 crt = SSL_get_peer_certificate(conn->xprt_ctx);
Emeric Brun9143d372012-12-20 15:44:16 +01005099 if (crt) {
5100 X509_free(crt);
5101 }
5102
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005103 smp->data.type = SMP_T_BOOL;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005104 smp->data.u.sint = (crt != NULL);
Emeric Brun9143d372012-12-20 15:44:16 +01005105 return 1;
5106}
5107
Emeric Brunba841a12014-04-30 17:05:08 +02005108/* integer, returns the certificate version
5109 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
5110 * should be use.
5111 */
Emeric Bruna7359fd2012-10-17 15:03:11 +02005112static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005113smp_fetch_ssl_x_version(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Bruna7359fd2012-10-17 15:03:11 +02005114{
Emeric Brunba841a12014-04-30 17:05:08 +02005115 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Bruna7359fd2012-10-17 15:03:11 +02005116 X509 *crt;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005117 struct connection *conn;
5118
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02005119 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005120 if (!conn || conn->xprt != &ssl_sock)
Emeric Bruna7359fd2012-10-17 15:03:11 +02005121 return 0;
5122
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005123 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Bruna7359fd2012-10-17 15:03:11 +02005124 smp->flags |= SMP_F_MAY_CHANGE;
5125 return 0;
5126 }
5127
Emeric Brunba841a12014-04-30 17:05:08 +02005128 if (cert_peer)
5129 crt = SSL_get_peer_certificate(conn->xprt_ctx);
5130 else
5131 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Bruna7359fd2012-10-17 15:03:11 +02005132 if (!crt)
5133 return 0;
5134
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005135 smp->data.u.sint = (unsigned int)(1 + X509_get_version(crt));
Emeric Brunba841a12014-04-30 17:05:08 +02005136 /* SSL_get_peer_certificate increase X509 * ref count */
5137 if (cert_peer)
5138 X509_free(crt);
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005139 smp->data.type = SMP_T_SINT;
Emeric Bruna7359fd2012-10-17 15:03:11 +02005140
5141 return 1;
5142}
5143
Emeric Brunba841a12014-04-30 17:05:08 +02005144/* string, returns the certificate's signature algorithm.
5145 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
5146 * should be use.
5147 */
Emeric Brun7f56e742012-10-19 18:15:40 +02005148static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005149smp_fetch_ssl_x_sig_alg(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun7f56e742012-10-19 18:15:40 +02005150{
Emeric Brunba841a12014-04-30 17:05:08 +02005151 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brun7f56e742012-10-19 18:15:40 +02005152 X509 *crt;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02005153 __OPENSSL_110_CONST__ ASN1_OBJECT *algorithm;
Emeric Brun7f56e742012-10-19 18:15:40 +02005154 int nid;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005155 struct connection *conn;
Emeric Brun7f56e742012-10-19 18:15:40 +02005156
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02005157 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005158 if (!conn || conn->xprt != &ssl_sock)
5159 return 0;
5160
5161 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun7f56e742012-10-19 18:15:40 +02005162 smp->flags |= SMP_F_MAY_CHANGE;
5163 return 0;
5164 }
5165
Emeric Brunba841a12014-04-30 17:05:08 +02005166 if (cert_peer)
5167 crt = SSL_get_peer_certificate(conn->xprt_ctx);
5168 else
5169 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brun7f56e742012-10-19 18:15:40 +02005170 if (!crt)
5171 return 0;
5172
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02005173 X509_ALGOR_get0(&algorithm, NULL, NULL, X509_get0_tbs_sigalg(crt));
5174 nid = OBJ_obj2nid(algorithm);
Emeric Brun7f56e742012-10-19 18:15:40 +02005175
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005176 smp->data.u.str.str = (char *)OBJ_nid2sn(nid);
5177 if (!smp->data.u.str.str) {
Emeric Brunba841a12014-04-30 17:05:08 +02005178 /* SSL_get_peer_certificate increase X509 * ref count */
5179 if (cert_peer)
5180 X509_free(crt);
Emeric Brun7f56e742012-10-19 18:15:40 +02005181 return 0;
Emeric Brun9bf3ba22013-10-07 14:31:44 +02005182 }
Emeric Brun7f56e742012-10-19 18:15:40 +02005183
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005184 smp->data.type = SMP_T_STR;
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01005185 smp->flags |= SMP_F_CONST;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005186 smp->data.u.str.len = strlen(smp->data.u.str.str);
Emeric Brunba841a12014-04-30 17:05:08 +02005187 /* SSL_get_peer_certificate increase X509 * ref count */
5188 if (cert_peer)
5189 X509_free(crt);
Emeric Brun7f56e742012-10-19 18:15:40 +02005190
5191 return 1;
5192}
5193
Emeric Brunba841a12014-04-30 17:05:08 +02005194/* string, returns the certificate's key algorithm.
5195 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
5196 * should be use.
5197 */
Emeric Brun521a0112012-10-22 12:22:55 +02005198static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005199smp_fetch_ssl_x_key_alg(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun521a0112012-10-22 12:22:55 +02005200{
Emeric Brunba841a12014-04-30 17:05:08 +02005201 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brun521a0112012-10-22 12:22:55 +02005202 X509 *crt;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02005203 ASN1_OBJECT *algorithm;
Emeric Brun521a0112012-10-22 12:22:55 +02005204 int nid;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005205 struct connection *conn;
Emeric Brun521a0112012-10-22 12:22:55 +02005206
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02005207 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005208 if (!conn || conn->xprt != &ssl_sock)
5209 return 0;
5210
5211 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun521a0112012-10-22 12:22:55 +02005212 smp->flags |= SMP_F_MAY_CHANGE;
5213 return 0;
5214 }
5215
Emeric Brunba841a12014-04-30 17:05:08 +02005216 if (cert_peer)
5217 crt = SSL_get_peer_certificate(conn->xprt_ctx);
5218 else
5219 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brun521a0112012-10-22 12:22:55 +02005220 if (!crt)
5221 return 0;
5222
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02005223 X509_PUBKEY_get0_param(&algorithm, NULL, NULL, NULL, X509_get_X509_PUBKEY(crt));
5224 nid = OBJ_obj2nid(algorithm);
Emeric Brun521a0112012-10-22 12:22:55 +02005225
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005226 smp->data.u.str.str = (char *)OBJ_nid2sn(nid);
5227 if (!smp->data.u.str.str) {
Emeric Brunba841a12014-04-30 17:05:08 +02005228 /* SSL_get_peer_certificate increase X509 * ref count */
5229 if (cert_peer)
5230 X509_free(crt);
Emeric Brun521a0112012-10-22 12:22:55 +02005231 return 0;
Emeric Brun9bf3ba22013-10-07 14:31:44 +02005232 }
Emeric Brun521a0112012-10-22 12:22:55 +02005233
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005234 smp->data.type = SMP_T_STR;
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01005235 smp->flags |= SMP_F_CONST;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005236 smp->data.u.str.len = strlen(smp->data.u.str.str);
Emeric Brunba841a12014-04-30 17:05:08 +02005237 if (cert_peer)
5238 X509_free(crt);
Emeric Brun521a0112012-10-22 12:22:55 +02005239
5240 return 1;
5241}
5242
Emeric Brun645ae792014-04-30 14:21:06 +02005243/* boolean, returns true if front conn. transport layer is SSL.
5244 * This function is also usable on backend conn if the fetch keyword 5th
5245 * char is 'b'.
5246 */
Willy Tarreau7875d092012-09-10 08:20:03 +02005247static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005248smp_fetch_ssl_fc(const struct arg *args, struct sample *smp, const char *kw, void *private)
Willy Tarreau7875d092012-09-10 08:20:03 +02005249{
Willy Tarreaue237fe12016-03-10 17:05:28 +01005250 struct connection *conn = objt_conn((kw[4] != 'b') ? smp->sess->origin :
5251 smp->strm ? smp->strm->si[1].end : NULL);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005252
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005253 smp->data.type = SMP_T_BOOL;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005254 smp->data.u.sint = (conn && conn->xprt == &ssl_sock);
Willy Tarreau7875d092012-09-10 08:20:03 +02005255 return 1;
5256}
5257
Emeric Brun2525b6b2012-10-18 15:59:43 +02005258/* boolean, returns true if client present a SNI */
Willy Tarreau7875d092012-09-10 08:20:03 +02005259static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005260smp_fetch_ssl_fc_has_sni(const struct arg *args, struct sample *smp, const char *kw, void *private)
Willy Tarreau7875d092012-09-10 08:20:03 +02005261{
5262#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02005263 struct connection *conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005264
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005265 smp->data.type = SMP_T_BOOL;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005266 smp->data.u.sint = (conn && conn->xprt == &ssl_sock) &&
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005267 conn->xprt_ctx &&
5268 SSL_get_servername(conn->xprt_ctx, TLSEXT_NAMETYPE_host_name) != NULL;
Willy Tarreau7875d092012-09-10 08:20:03 +02005269 return 1;
5270#else
5271 return 0;
5272#endif
5273}
5274
Nenad Merdanovic26ea8222015-05-18 02:28:57 +02005275/* boolean, returns true if client session has been resumed */
5276static int
5277smp_fetch_ssl_fc_is_resumed(const struct arg *args, struct sample *smp, const char *kw, void *private)
5278{
5279 struct connection *conn = objt_conn(smp->sess->origin);
5280
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005281 smp->data.type = SMP_T_BOOL;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005282 smp->data.u.sint = (conn && conn->xprt == &ssl_sock) &&
Nenad Merdanovic26ea8222015-05-18 02:28:57 +02005283 conn->xprt_ctx &&
5284 SSL_session_reused(conn->xprt_ctx);
5285 return 1;
5286}
5287
Emeric Brun645ae792014-04-30 14:21:06 +02005288/* string, returns the used cipher if front conn. transport layer is SSL.
5289 * This function is also usable on backend conn if the fetch keyword 5th
5290 * char is 'b'.
5291 */
Emeric Brun589fcad2012-10-16 14:13:26 +02005292static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005293smp_fetch_ssl_fc_cipher(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun589fcad2012-10-16 14:13:26 +02005294{
Willy Tarreaue237fe12016-03-10 17:05:28 +01005295 struct connection *conn = objt_conn((kw[4] != 'b') ? smp->sess->origin :
5296 smp->strm ? smp->strm->si[1].end : NULL);
Emeric Brun589fcad2012-10-16 14:13:26 +02005297
Willy Tarreaube508f12016-03-10 11:47:01 +01005298 smp->flags = 0;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005299 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
Emeric Brun589fcad2012-10-16 14:13:26 +02005300 return 0;
5301
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005302 smp->data.u.str.str = (char *)SSL_get_cipher_name(conn->xprt_ctx);
5303 if (!smp->data.u.str.str)
Emeric Brun589fcad2012-10-16 14:13:26 +02005304 return 0;
5305
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005306 smp->data.type = SMP_T_STR;
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01005307 smp->flags |= SMP_F_CONST;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005308 smp->data.u.str.len = strlen(smp->data.u.str.str);
Emeric Brun589fcad2012-10-16 14:13:26 +02005309
5310 return 1;
5311}
5312
Emeric Brun645ae792014-04-30 14:21:06 +02005313/* integer, returns the algoritm's keysize if front conn. transport layer
5314 * is SSL.
5315 * This function is also usable on backend conn if the fetch keyword 5th
5316 * char is 'b'.
5317 */
Emeric Brun589fcad2012-10-16 14:13:26 +02005318static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005319smp_fetch_ssl_fc_alg_keysize(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun589fcad2012-10-16 14:13:26 +02005320{
Willy Tarreaue237fe12016-03-10 17:05:28 +01005321 struct connection *conn = objt_conn((kw[4] != 'b') ? smp->sess->origin :
5322 smp->strm ? smp->strm->si[1].end : NULL);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005323
Willy Tarreaue237fe12016-03-10 17:05:28 +01005324 int sint;
Willy Tarreaube508f12016-03-10 11:47:01 +01005325
Emeric Brun589fcad2012-10-16 14:13:26 +02005326 smp->flags = 0;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005327 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
Emeric Brun589fcad2012-10-16 14:13:26 +02005328 return 0;
5329
Thierry FOURNIER07ee64e2015-07-06 23:43:03 +02005330 if (!SSL_get_cipher_bits(conn->xprt_ctx, &sint))
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005331 return 0;
5332
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005333 smp->data.u.sint = sint;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005334 smp->data.type = SMP_T_SINT;
Emeric Brun589fcad2012-10-16 14:13:26 +02005335
5336 return 1;
5337}
5338
Emeric Brun645ae792014-04-30 14:21:06 +02005339/* integer, returns the used keysize if front conn. transport layer is SSL.
5340 * This function is also usable on backend conn if the fetch keyword 5th
5341 * char is 'b'.
5342 */
Emeric Brun589fcad2012-10-16 14:13:26 +02005343static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005344smp_fetch_ssl_fc_use_keysize(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun589fcad2012-10-16 14:13:26 +02005345{
Willy Tarreaue237fe12016-03-10 17:05:28 +01005346 struct connection *conn = objt_conn((kw[4] != 'b') ? smp->sess->origin :
5347 smp->strm ? smp->strm->si[1].end : NULL);
Willy Tarreaube508f12016-03-10 11:47:01 +01005348
Emeric Brun589fcad2012-10-16 14:13:26 +02005349 smp->flags = 0;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005350 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
5351 return 0;
5352
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005353 smp->data.u.sint = (unsigned int)SSL_get_cipher_bits(conn->xprt_ctx, NULL);
5354 if (!smp->data.u.sint)
Emeric Brun589fcad2012-10-16 14:13:26 +02005355 return 0;
5356
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005357 smp->data.type = SMP_T_SINT;
Emeric Brun589fcad2012-10-16 14:13:26 +02005358
5359 return 1;
5360}
5361
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02005362#ifdef OPENSSL_NPN_NEGOTIATED
Willy Tarreau7875d092012-09-10 08:20:03 +02005363static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005364smp_fetch_ssl_fc_npn(const struct arg *args, struct sample *smp, const char *kw, void *private)
Willy Tarreaua33c6542012-10-15 13:19:06 +02005365{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005366 struct connection *conn;
5367
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01005368 smp->flags = SMP_F_CONST;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005369 smp->data.type = SMP_T_STR;
Willy Tarreaua33c6542012-10-15 13:19:06 +02005370
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02005371 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005372 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
5373 return 0;
5374
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005375 smp->data.u.str.str = NULL;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005376 SSL_get0_next_proto_negotiated(conn->xprt_ctx,
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005377 (const unsigned char **)&smp->data.u.str.str, (unsigned *)&smp->data.u.str.len);
Willy Tarreaua33c6542012-10-15 13:19:06 +02005378
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005379 if (!smp->data.u.str.str)
Willy Tarreaua33c6542012-10-15 13:19:06 +02005380 return 0;
5381
5382 return 1;
Willy Tarreaua33c6542012-10-15 13:19:06 +02005383}
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02005384#endif
Willy Tarreaua33c6542012-10-15 13:19:06 +02005385
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01005386#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Willy Tarreauab861d32013-04-02 02:30:41 +02005387static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005388smp_fetch_ssl_fc_alpn(const struct arg *args, struct sample *smp, const char *kw, void *private)
Willy Tarreauab861d32013-04-02 02:30:41 +02005389{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005390 struct connection *conn;
5391
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01005392 smp->flags = SMP_F_CONST;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005393 smp->data.type = SMP_T_STR;
Willy Tarreauab861d32013-04-02 02:30:41 +02005394
Willy Tarreaue26bf052015-05-12 10:30:12 +02005395 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005396 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
Willy Tarreauab861d32013-04-02 02:30:41 +02005397 return 0;
5398
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005399 smp->data.u.str.str = NULL;
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01005400 SSL_get0_alpn_selected(conn->xprt_ctx,
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005401 (const unsigned char **)&smp->data.u.str.str, (unsigned *)&smp->data.u.str.len);
Willy Tarreauab861d32013-04-02 02:30:41 +02005402
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005403 if (!smp->data.u.str.str)
Willy Tarreauab861d32013-04-02 02:30:41 +02005404 return 0;
5405
5406 return 1;
5407}
5408#endif
5409
Emeric Brun645ae792014-04-30 14:21:06 +02005410/* string, returns the used protocol if front conn. transport layer is SSL.
5411 * This function is also usable on backend conn if the fetch keyword 5th
5412 * char is 'b'.
5413 */
Willy Tarreaua33c6542012-10-15 13:19:06 +02005414static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005415smp_fetch_ssl_fc_protocol(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun589fcad2012-10-16 14:13:26 +02005416{
Willy Tarreaue237fe12016-03-10 17:05:28 +01005417 struct connection *conn = objt_conn((kw[4] != 'b') ? smp->sess->origin :
5418 smp->strm ? smp->strm->si[1].end : NULL);
Willy Tarreaube508f12016-03-10 11:47:01 +01005419
Emeric Brun589fcad2012-10-16 14:13:26 +02005420 smp->flags = 0;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005421 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
5422 return 0;
5423
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005424 smp->data.u.str.str = (char *)SSL_get_version(conn->xprt_ctx);
5425 if (!smp->data.u.str.str)
Emeric Brun589fcad2012-10-16 14:13:26 +02005426 return 0;
5427
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005428 smp->data.type = SMP_T_STR;
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01005429 smp->flags = SMP_F_CONST;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005430 smp->data.u.str.len = strlen(smp->data.u.str.str);
Emeric Brun589fcad2012-10-16 14:13:26 +02005431
5432 return 1;
5433}
5434
Willy Tarreau87b09662015-04-03 00:22:06 +02005435/* binary, returns the SSL stream id if front conn. transport layer is SSL.
Emeric Brun645ae792014-04-30 14:21:06 +02005436 * This function is also usable on backend conn if the fetch keyword 5th
5437 * char is 'b'.
5438 */
Emeric Brun589fcad2012-10-16 14:13:26 +02005439static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005440smp_fetch_ssl_fc_session_id(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brunfe68f682012-10-16 14:59:28 +02005441{
5442#if OPENSSL_VERSION_NUMBER > 0x0090800fL
Willy Tarreaue237fe12016-03-10 17:05:28 +01005443 struct connection *conn = objt_conn((kw[4] != 'b') ? smp->sess->origin :
5444 smp->strm ? smp->strm->si[1].end : NULL);
Emeric Brunfe68f682012-10-16 14:59:28 +02005445
Willy Tarreaue237fe12016-03-10 17:05:28 +01005446 SSL_SESSION *ssl_sess;
Willy Tarreaube508f12016-03-10 11:47:01 +01005447
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01005448 smp->flags = SMP_F_CONST;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005449 smp->data.type = SMP_T_BIN;
Emeric Brunfe68f682012-10-16 14:59:28 +02005450
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005451 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
5452 return 0;
5453
Willy Tarreau192252e2015-04-04 01:47:55 +02005454 ssl_sess = SSL_get_session(conn->xprt_ctx);
5455 if (!ssl_sess)
Emeric Brunfe68f682012-10-16 14:59:28 +02005456 return 0;
5457
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005458 smp->data.u.str.str = (char *)SSL_SESSION_get_id(ssl_sess, (unsigned int *)&smp->data.u.str.len);
5459 if (!smp->data.u.str.str || !smp->data.u.str.len)
Emeric Brunfe68f682012-10-16 14:59:28 +02005460 return 0;
5461
5462 return 1;
5463#else
5464 return 0;
5465#endif
5466}
5467
5468static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005469smp_fetch_ssl_fc_sni(const struct arg *args, struct sample *smp, const char *kw, void *private)
Willy Tarreau7875d092012-09-10 08:20:03 +02005470{
5471#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005472 struct connection *conn;
5473
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01005474 smp->flags = SMP_F_CONST;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005475 smp->data.type = SMP_T_STR;
Willy Tarreau7875d092012-09-10 08:20:03 +02005476
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02005477 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005478 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
5479 return 0;
5480
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005481 smp->data.u.str.str = (char *)SSL_get_servername(conn->xprt_ctx, TLSEXT_NAMETYPE_host_name);
5482 if (!smp->data.u.str.str)
Willy Tarreau3e394c92012-09-14 23:56:58 +02005483 return 0;
5484
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005485 smp->data.u.str.len = strlen(smp->data.u.str.str);
Willy Tarreau7875d092012-09-10 08:20:03 +02005486 return 1;
5487#else
5488 return 0;
5489#endif
5490}
5491
David Sc1ad52e2014-04-08 18:48:47 -04005492static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005493smp_fetch_ssl_fc_unique_id(const struct arg *args, struct sample *smp, const char *kw, void *private)
David Sc1ad52e2014-04-08 18:48:47 -04005494{
5495#if OPENSSL_VERSION_NUMBER > 0x0090800fL
Willy Tarreaue237fe12016-03-10 17:05:28 +01005496 struct connection *conn = objt_conn((kw[4] != 'b') ? smp->sess->origin :
5497 smp->strm ? smp->strm->si[1].end : NULL);
5498
David Sc1ad52e2014-04-08 18:48:47 -04005499 int finished_len;
David Sc1ad52e2014-04-08 18:48:47 -04005500 struct chunk *finished_trash;
David Sc1ad52e2014-04-08 18:48:47 -04005501
5502 smp->flags = 0;
David Sc1ad52e2014-04-08 18:48:47 -04005503 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
5504 return 0;
5505
5506 if (!(conn->flags & CO_FL_CONNECTED)) {
5507 smp->flags |= SMP_F_MAY_CHANGE;
5508 return 0;
5509 }
5510
5511 finished_trash = get_trash_chunk();
5512 if (!SSL_session_reused(conn->xprt_ctx))
5513 finished_len = SSL_get_peer_finished(conn->xprt_ctx, finished_trash->str, finished_trash->size);
5514 else
5515 finished_len = SSL_get_finished(conn->xprt_ctx, finished_trash->str, finished_trash->size);
5516
5517 if (!finished_len)
5518 return 0;
5519
Emeric Brunb73a9b02014-04-30 18:49:19 +02005520 finished_trash->len = finished_len;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005521 smp->data.u.str = *finished_trash;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005522 smp->data.type = SMP_T_BIN;
David Sc1ad52e2014-04-08 18:48:47 -04005523
5524 return 1;
5525#else
5526 return 0;
5527#endif
5528}
5529
Emeric Brun2525b6b2012-10-18 15:59:43 +02005530/* integer, returns the first verify error in CA chain of client certificate chain. */
Emeric Brunf282a812012-09-21 15:27:54 +02005531static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005532smp_fetch_ssl_c_ca_err(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brunf282a812012-09-21 15:27:54 +02005533{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005534 struct connection *conn;
5535
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02005536 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005537 if (!conn || conn->xprt != &ssl_sock)
5538 return 0;
5539
5540 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunf282a812012-09-21 15:27:54 +02005541 smp->flags = SMP_F_MAY_CHANGE;
5542 return 0;
5543 }
5544
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005545 smp->data.type = SMP_T_SINT;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005546 smp->data.u.sint = (unsigned long long int)SSL_SOCK_ST_TO_CA_ERROR(conn->xprt_st);
Emeric Brunf282a812012-09-21 15:27:54 +02005547 smp->flags = 0;
5548
5549 return 1;
5550}
5551
Emeric Brun2525b6b2012-10-18 15:59:43 +02005552/* integer, returns the depth of the first verify error in CA chain of client certificate chain. */
Emeric Brunf282a812012-09-21 15:27:54 +02005553static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005554smp_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 +02005555{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005556 struct connection *conn;
5557
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02005558 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005559 if (!conn || conn->xprt != &ssl_sock)
Emeric Brunf282a812012-09-21 15:27:54 +02005560 return 0;
5561
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005562 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunf282a812012-09-21 15:27:54 +02005563 smp->flags = SMP_F_MAY_CHANGE;
5564 return 0;
5565 }
5566
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005567 smp->data.type = SMP_T_SINT;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005568 smp->data.u.sint = (long long int)SSL_SOCK_ST_TO_CAEDEPTH(conn->xprt_st);
Emeric Brunf282a812012-09-21 15:27:54 +02005569 smp->flags = 0;
5570
5571 return 1;
5572}
5573
Emeric Brun2525b6b2012-10-18 15:59:43 +02005574/* integer, returns the first verify error on client certificate */
Emeric Brunf282a812012-09-21 15:27:54 +02005575static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005576smp_fetch_ssl_c_err(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brunf282a812012-09-21 15:27:54 +02005577{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005578 struct connection *conn;
5579
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02005580 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005581 if (!conn || conn->xprt != &ssl_sock)
5582 return 0;
5583
5584 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunf282a812012-09-21 15:27:54 +02005585 smp->flags = SMP_F_MAY_CHANGE;
5586 return 0;
5587 }
5588
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005589 smp->data.type = SMP_T_SINT;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005590 smp->data.u.sint = (long long int)SSL_SOCK_ST_TO_CRTERROR(conn->xprt_st);
Emeric Brunf282a812012-09-21 15:27:54 +02005591 smp->flags = 0;
5592
5593 return 1;
5594}
5595
Emeric Brun2525b6b2012-10-18 15:59:43 +02005596/* integer, returns the verify result on client cert */
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02005597static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005598smp_fetch_ssl_c_verify(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02005599{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005600 struct connection *conn;
5601
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02005602 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005603 if (!conn || conn->xprt != &ssl_sock)
5604 return 0;
5605
5606 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02005607 smp->flags = SMP_F_MAY_CHANGE;
5608 return 0;
5609 }
5610
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005611 if (!conn->xprt_ctx)
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02005612 return 0;
5613
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005614 smp->data.type = SMP_T_SINT;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005615 smp->data.u.sint = (long long int)SSL_get_verify_result(conn->xprt_ctx);
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02005616 smp->flags = 0;
5617
5618 return 1;
5619}
5620
Emeric Brunfb510ea2012-10-05 12:00:26 +02005621/* parse the "ca-file" bind keyword */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01005622static 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 +02005623{
5624 if (!*args[cur_arg + 1]) {
5625 if (err)
5626 memprintf(err, "'%s' : missing CAfile path", args[cur_arg]);
5627 return ERR_ALERT | ERR_FATAL;
5628 }
5629
Willy Tarreauef934602016-12-22 23:12:01 +01005630 if ((*args[cur_arg + 1] != '/') && global_ssl.ca_base)
5631 memprintf(&conf->ca_file, "%s/%s", global_ssl.ca_base, args[cur_arg + 1]);
Emeric Brunef42d922012-10-11 16:11:36 +02005632 else
5633 memprintf(&conf->ca_file, "%s", args[cur_arg + 1]);
Emeric Brunc8e8d122012-10-02 18:42:10 +02005634
Emeric Brund94b3fe2012-09-20 18:23:56 +02005635 return 0;
5636}
Emmanuel Hocdet98263292016-12-29 18:26:15 +01005637static int bind_parse_ca_file(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5638{
5639 return ssl_bind_parse_ca_file(args, cur_arg, px, &conf->ssl_conf, err);
5640}
Emeric Brund94b3fe2012-09-20 18:23:56 +02005641
Christopher Faulet31af49d2015-06-09 17:29:50 +02005642/* parse the "ca-sign-file" bind keyword */
5643static int bind_parse_ca_sign_file(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5644{
5645 if (!*args[cur_arg + 1]) {
5646 if (err)
5647 memprintf(err, "'%s' : missing CAfile path", args[cur_arg]);
5648 return ERR_ALERT | ERR_FATAL;
5649 }
5650
Willy Tarreauef934602016-12-22 23:12:01 +01005651 if ((*args[cur_arg + 1] != '/') && global_ssl.ca_base)
5652 memprintf(&conf->ca_sign_file, "%s/%s", global_ssl.ca_base, args[cur_arg + 1]);
Christopher Faulet31af49d2015-06-09 17:29:50 +02005653 else
5654 memprintf(&conf->ca_sign_file, "%s", args[cur_arg + 1]);
5655
5656 return 0;
5657}
5658
Bertrand Jacquinff13c062016-11-13 16:37:11 +00005659/* parse the "ca-sign-pass" bind keyword */
Christopher Faulet31af49d2015-06-09 17:29:50 +02005660static int bind_parse_ca_sign_pass(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5661{
5662 if (!*args[cur_arg + 1]) {
5663 if (err)
5664 memprintf(err, "'%s' : missing CAkey password", args[cur_arg]);
5665 return ERR_ALERT | ERR_FATAL;
5666 }
5667 memprintf(&conf->ca_sign_pass, "%s", args[cur_arg + 1]);
5668 return 0;
5669}
5670
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005671/* parse the "ciphers" bind keyword */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01005672static 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 +02005673{
5674 if (!*args[cur_arg + 1]) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02005675 memprintf(err, "'%s' : missing cipher suite", args[cur_arg]);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005676 return ERR_ALERT | ERR_FATAL;
5677 }
5678
Emeric Brun76d88952012-10-05 15:47:31 +02005679 free(conf->ciphers);
Willy Tarreau4348fad2012-09-20 16:48:07 +02005680 conf->ciphers = strdup(args[cur_arg + 1]);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005681 return 0;
5682}
Emmanuel Hocdet98263292016-12-29 18:26:15 +01005683static int bind_parse_ciphers(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5684{
5685 return ssl_bind_parse_ciphers(args, cur_arg, px, &conf->ssl_conf, err);
5686}
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005687/* parse the "crt" bind keyword */
Willy Tarreau4348fad2012-09-20 16:48:07 +02005688static 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 +02005689{
Willy Tarreau38011032013-08-13 16:59:39 +02005690 char path[MAXPATHLEN];
Willy Tarreaub75d6922014-04-14 18:05:41 +02005691
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005692 if (!*args[cur_arg + 1]) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02005693 memprintf(err, "'%s' : missing certificate location", args[cur_arg]);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005694 return ERR_ALERT | ERR_FATAL;
5695 }
5696
Willy Tarreauef934602016-12-22 23:12:01 +01005697 if ((*args[cur_arg + 1] != '/' ) && global_ssl.crt_base) {
5698 if ((strlen(global_ssl.crt_base) + 1 + strlen(args[cur_arg + 1]) + 1) > MAXPATHLEN) {
Emeric Brunc8e8d122012-10-02 18:42:10 +02005699 memprintf(err, "'%s' : path too long", args[cur_arg]);
5700 return ERR_ALERT | ERR_FATAL;
5701 }
Willy Tarreauef934602016-12-22 23:12:01 +01005702 snprintf(path, sizeof(path), "%s/%s", global_ssl.crt_base, args[cur_arg + 1]);
Willy Tarreau03209342016-12-22 17:08:28 +01005703 if (ssl_sock_load_cert(path, conf, err) > 0)
Emeric Brunc8e8d122012-10-02 18:42:10 +02005704 return ERR_ALERT | ERR_FATAL;
5705
5706 return 0;
5707 }
5708
Willy Tarreau03209342016-12-22 17:08:28 +01005709 if (ssl_sock_load_cert(args[cur_arg + 1], conf, err) > 0)
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005710 return ERR_ALERT | ERR_FATAL;
Emeric Brund94b3fe2012-09-20 18:23:56 +02005711
5712 return 0;
5713}
5714
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01005715/* parse the "crt-list" bind keyword */
5716static int bind_parse_crt_list(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5717{
5718 if (!*args[cur_arg + 1]) {
5719 memprintf(err, "'%s' : missing certificate location", args[cur_arg]);
5720 return ERR_ALERT | ERR_FATAL;
5721 }
5722
Emmanuel Hocdet98263292016-12-29 18:26:15 +01005723 if (ssl_sock_load_cert_list_file(args[cur_arg + 1], conf, px, err) > 0) {
Willy Tarreauad1731d2013-04-02 17:35:58 +02005724 memprintf(err, "'%s' : %s", args[cur_arg], *err);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01005725 return ERR_ALERT | ERR_FATAL;
Willy Tarreauad1731d2013-04-02 17:35:58 +02005726 }
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01005727
5728 return 0;
5729}
5730
Emeric Brunfb510ea2012-10-05 12:00:26 +02005731/* parse the "crl-file" bind keyword */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01005732static 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 +02005733{
Emeric Brun051cdab2012-10-02 19:25:50 +02005734#ifndef X509_V_FLAG_CRL_CHECK
5735 if (err)
5736 memprintf(err, "'%s' : library does not support CRL verify", args[cur_arg]);
5737 return ERR_ALERT | ERR_FATAL;
5738#else
Emeric Brund94b3fe2012-09-20 18:23:56 +02005739 if (!*args[cur_arg + 1]) {
5740 if (err)
5741 memprintf(err, "'%s' : missing CRLfile path", args[cur_arg]);
5742 return ERR_ALERT | ERR_FATAL;
5743 }
Emeric Brun2b58d042012-09-20 17:10:03 +02005744
Willy Tarreauef934602016-12-22 23:12:01 +01005745 if ((*args[cur_arg + 1] != '/') && global_ssl.ca_base)
5746 memprintf(&conf->crl_file, "%s/%s", global_ssl.ca_base, args[cur_arg + 1]);
Emeric Brunef42d922012-10-11 16:11:36 +02005747 else
5748 memprintf(&conf->crl_file, "%s", args[cur_arg + 1]);
Emeric Brunc8e8d122012-10-02 18:42:10 +02005749
Emeric Brun2b58d042012-09-20 17:10:03 +02005750 return 0;
Emeric Brun051cdab2012-10-02 19:25:50 +02005751#endif
Emeric Brun2b58d042012-09-20 17:10:03 +02005752}
Emmanuel Hocdet98263292016-12-29 18:26:15 +01005753static int bind_parse_crl_file(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5754{
5755 return ssl_bind_parse_crl_file(args, cur_arg, px, &conf->ssl_conf, err);
5756}
Emeric Brun2b58d042012-09-20 17:10:03 +02005757
Emmanuel Hocdete7f2b732017-01-09 16:15:54 +01005758/* parse the "curves" bind keyword keyword */
5759static int ssl_bind_parse_curves(char **args, int cur_arg, struct proxy *px, struct ssl_bind_conf *conf, char **err)
5760{
5761#if OPENSSL_VERSION_NUMBER >= 0x1000200fL
5762 if (!*args[cur_arg + 1]) {
5763 if (err)
5764 memprintf(err, "'%s' : missing curve suite", args[cur_arg]);
5765 return ERR_ALERT | ERR_FATAL;
5766 }
5767 conf->curves = strdup(args[cur_arg + 1]);
5768 return 0;
5769#else
5770 if (err)
5771 memprintf(err, "'%s' : library does not support curve suite", args[cur_arg]);
5772 return ERR_ALERT | ERR_FATAL;
5773#endif
5774}
5775static int bind_parse_curves(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5776{
5777 return ssl_bind_parse_curves(args, cur_arg, px, &conf->ssl_conf, err);
5778}
5779
Bertrand Jacquinff13c062016-11-13 16:37:11 +00005780/* parse the "ecdhe" bind keyword keyword */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01005781static 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 +02005782{
5783#if OPENSSL_VERSION_NUMBER < 0x0090800fL
5784 if (err)
5785 memprintf(err, "'%s' : library does not support elliptic curve Diffie-Hellman (too old)", args[cur_arg]);
5786 return ERR_ALERT | ERR_FATAL;
5787#elif defined(OPENSSL_NO_ECDH)
5788 if (err)
5789 memprintf(err, "'%s' : library does not support elliptic curve Diffie-Hellman (disabled via OPENSSL_NO_ECDH)", args[cur_arg]);
5790 return ERR_ALERT | ERR_FATAL;
5791#else
5792 if (!*args[cur_arg + 1]) {
5793 if (err)
5794 memprintf(err, "'%s' : missing named curve", args[cur_arg]);
5795 return ERR_ALERT | ERR_FATAL;
5796 }
5797
5798 conf->ecdhe = strdup(args[cur_arg + 1]);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005799
5800 return 0;
Emeric Brun2b58d042012-09-20 17:10:03 +02005801#endif
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005802}
Emmanuel Hocdet98263292016-12-29 18:26:15 +01005803static int bind_parse_ecdhe(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5804{
5805 return ssl_bind_parse_ecdhe(args, cur_arg, px, &conf->ssl_conf, err);
5806}
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005807
Bertrand Jacquinff13c062016-11-13 16:37:11 +00005808/* parse the "crt-ignore-err" and "ca-ignore-err" bind keywords */
Emeric Brun81c00f02012-09-21 14:31:21 +02005809static int bind_parse_ignore_err(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5810{
5811 int code;
5812 char *p = args[cur_arg + 1];
5813 unsigned long long *ignerr = &conf->crt_ignerr;
5814
5815 if (!*p) {
5816 if (err)
5817 memprintf(err, "'%s' : missing error IDs list", args[cur_arg]);
5818 return ERR_ALERT | ERR_FATAL;
5819 }
5820
5821 if (strcmp(args[cur_arg], "ca-ignore-err") == 0)
5822 ignerr = &conf->ca_ignerr;
5823
5824 if (strcmp(p, "all") == 0) {
5825 *ignerr = ~0ULL;
5826 return 0;
5827 }
5828
5829 while (p) {
5830 code = atoi(p);
5831 if ((code <= 0) || (code > 63)) {
5832 if (err)
5833 memprintf(err, "'%s' : ID '%d' out of range (1..63) in error IDs list '%s'",
5834 args[cur_arg], code, args[cur_arg + 1]);
5835 return ERR_ALERT | ERR_FATAL;
5836 }
5837 *ignerr |= 1ULL << code;
5838 p = strchr(p, ',');
5839 if (p)
5840 p++;
5841 }
5842
Emeric Brun2cb7ae52012-10-05 14:14:21 +02005843 return 0;
5844}
5845
5846/* parse the "force-sslv3" bind keyword */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01005847static int ssl_bind_parse_force_sslv3(char **args, int cur_arg, struct proxy *px, struct ssl_bind_conf *conf, char **err)
Emeric Brun2cb7ae52012-10-05 14:14:21 +02005848{
5849 conf->ssl_options |= BC_SSL_O_USE_SSLV3;
5850 return 0;
5851}
Emmanuel Hocdet98263292016-12-29 18:26:15 +01005852static int bind_parse_force_sslv3(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5853{
5854 return ssl_bind_parse_force_sslv3(args, cur_arg, px, &conf->ssl_conf, err);
5855}
Emeric Brun2cb7ae52012-10-05 14:14:21 +02005856
5857/* parse the "force-tlsv10" bind keyword */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01005858static int ssl_bind_parse_force_tlsv10(char **args, int cur_arg, struct proxy *px, struct ssl_bind_conf *conf, char **err)
Emeric Brun2cb7ae52012-10-05 14:14:21 +02005859{
5860 conf->ssl_options |= BC_SSL_O_USE_TLSV10;
Emeric Brun2d0c4822012-10-02 13:45:20 +02005861 return 0;
5862}
Emmanuel Hocdet98263292016-12-29 18:26:15 +01005863static int bind_parse_force_tlsv10(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5864{
5865 return ssl_bind_parse_force_tlsv10(args, cur_arg, px, &conf->ssl_conf, err);
5866}
Emeric Brun2d0c4822012-10-02 13:45:20 +02005867
Emeric Brun2cb7ae52012-10-05 14:14:21 +02005868/* parse the "force-tlsv11" bind keyword */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01005869static int ssl_bind_parse_force_tlsv11(char **args, int cur_arg, struct proxy *px, struct ssl_bind_conf *conf, char **err)
Emeric Brun2cb7ae52012-10-05 14:14:21 +02005870{
5871#if SSL_OP_NO_TLSv1_1
5872 conf->ssl_options |= BC_SSL_O_USE_TLSV11;
5873 return 0;
5874#else
5875 if (err)
5876 memprintf(err, "'%s' : library does not support protocol TLSv1.1", args[cur_arg]);
5877 return ERR_ALERT | ERR_FATAL;
5878#endif
5879}
Emmanuel Hocdet98263292016-12-29 18:26:15 +01005880static int bind_parse_force_tlsv11(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5881{
5882 return ssl_bind_parse_force_tlsv11(args, cur_arg, px, &conf->ssl_conf, err);
5883}
Emeric Brun2cb7ae52012-10-05 14:14:21 +02005884
5885/* parse the "force-tlsv12" bind keyword */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01005886static int ssl_bind_parse_force_tlsv12(char **args, int cur_arg, struct proxy *px, struct ssl_bind_conf *conf, char **err)
Emeric Brun2cb7ae52012-10-05 14:14:21 +02005887{
5888#if SSL_OP_NO_TLSv1_2
5889 conf->ssl_options |= BC_SSL_O_USE_TLSV12;
5890 return 0;
5891#else
5892 if (err)
5893 memprintf(err, "'%s' : library does not support protocol TLSv1.2", args[cur_arg]);
5894 return ERR_ALERT | ERR_FATAL;
5895#endif
5896}
Emmanuel Hocdet98263292016-12-29 18:26:15 +01005897static int bind_parse_force_tlsv12(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5898{
5899 return ssl_bind_parse_force_tlsv12(args, cur_arg, px, &conf->ssl_conf, err);
5900}
Emeric Brun2cb7ae52012-10-05 14:14:21 +02005901
Emeric Brun2d0c4822012-10-02 13:45:20 +02005902/* parse the "no-tls-tickets" bind keyword */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01005903static int ssl_bind_parse_no_tls_tickets(char **args, int cur_arg, struct proxy *px, struct ssl_bind_conf *conf, char **err)
Emeric Brun2d0c4822012-10-02 13:45:20 +02005904{
Emeric Brun89675492012-10-05 13:48:26 +02005905 conf->ssl_options |= BC_SSL_O_NO_TLS_TICKETS;
Emeric Brun81c00f02012-09-21 14:31:21 +02005906 return 0;
5907}
Emmanuel Hocdet98263292016-12-29 18:26:15 +01005908static int bind_parse_no_tls_tickets(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5909{
5910 return ssl_bind_parse_no_tls_tickets(args, cur_arg, px, &conf->ssl_conf, err);
5911}
Emeric Brun2d0c4822012-10-02 13:45:20 +02005912
Emeric Brun9b3009b2012-10-05 11:55:06 +02005913/* parse the "no-sslv3" bind keyword */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01005914static int ssl_bind_parse_no_sslv3(char **args, int cur_arg, struct proxy *px, struct ssl_bind_conf *conf, char **err)
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005915{
Emeric Brun89675492012-10-05 13:48:26 +02005916 conf->ssl_options |= BC_SSL_O_NO_SSLV3;
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005917 return 0;
5918}
Emmanuel Hocdet98263292016-12-29 18:26:15 +01005919static int bind_parse_no_sslv3(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5920{
5921 return ssl_bind_parse_no_sslv3(args, cur_arg, px, &conf->ssl_conf, err);
5922}
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005923
Emeric Brun9b3009b2012-10-05 11:55:06 +02005924/* parse the "no-tlsv10" bind keyword */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01005925static int ssl_bind_parse_no_tlsv10(char **args, int cur_arg, struct proxy *px, struct ssl_bind_conf *conf, char **err)
Emeric Brunc0ff4922012-09-28 19:37:02 +02005926{
Emeric Brun89675492012-10-05 13:48:26 +02005927 conf->ssl_options |= BC_SSL_O_NO_TLSV10;
Emeric Brunc0ff4922012-09-28 19:37:02 +02005928 return 0;
5929}
Emmanuel Hocdet98263292016-12-29 18:26:15 +01005930static int bind_parse_no_tlsv10(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5931{
5932 return ssl_bind_parse_no_tlsv10(args, cur_arg, px, &conf->ssl_conf, err);
5933}
Emeric Brunc0ff4922012-09-28 19:37:02 +02005934
Emeric Brun9b3009b2012-10-05 11:55:06 +02005935/* parse the "no-tlsv11" bind keyword */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01005936static int ssl_bind_parse_no_tlsv11(char **args, int cur_arg, struct proxy *px, struct ssl_bind_conf *conf, char **err)
Emeric Brunc0ff4922012-09-28 19:37:02 +02005937{
Emeric Brun89675492012-10-05 13:48:26 +02005938 conf->ssl_options |= BC_SSL_O_NO_TLSV11;
Emeric Brunc0ff4922012-09-28 19:37:02 +02005939 return 0;
5940}
Emmanuel Hocdet98263292016-12-29 18:26:15 +01005941static int bind_parse_no_tlsv11(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5942{
5943 return ssl_bind_parse_no_tlsv11(args, cur_arg, px, &conf->ssl_conf, err);
5944}
Emeric Brunc0ff4922012-09-28 19:37:02 +02005945
Emeric Brun9b3009b2012-10-05 11:55:06 +02005946/* parse the "no-tlsv12" bind keyword */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01005947static int ssl_bind_parse_no_tlsv12(char **args, int cur_arg, struct proxy *px, struct ssl_bind_conf *conf, char **err)
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005948{
Emeric Brun89675492012-10-05 13:48:26 +02005949 conf->ssl_options |= BC_SSL_O_NO_TLSV12;
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005950 return 0;
5951}
Emmanuel Hocdet98263292016-12-29 18:26:15 +01005952static int bind_parse_no_tlsv12(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5953{
5954 return ssl_bind_parse_no_tlsv12(args, cur_arg, px, &conf->ssl_conf, err);
5955}
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005956
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02005957/* parse the "npn" bind keyword */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01005958static 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 +02005959{
5960#ifdef OPENSSL_NPN_NEGOTIATED
5961 char *p1, *p2;
5962
5963 if (!*args[cur_arg + 1]) {
5964 memprintf(err, "'%s' : missing the comma-delimited NPN protocol suite", args[cur_arg]);
5965 return ERR_ALERT | ERR_FATAL;
5966 }
5967
5968 free(conf->npn_str);
5969
Willy Tarreau3724da12016-02-12 17:11:12 +01005970 /* the NPN string is built as a suite of (<len> <name>)*,
5971 * so we reuse each comma to store the next <len> and need
5972 * one more for the end of the string.
5973 */
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02005974 conf->npn_len = strlen(args[cur_arg + 1]) + 1;
Willy Tarreau3724da12016-02-12 17:11:12 +01005975 conf->npn_str = calloc(1, conf->npn_len + 1);
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02005976 memcpy(conf->npn_str + 1, args[cur_arg + 1], conf->npn_len);
5977
5978 /* replace commas with the name length */
5979 p1 = conf->npn_str;
5980 p2 = p1 + 1;
5981 while (1) {
5982 p2 = memchr(p1 + 1, ',', conf->npn_str + conf->npn_len - (p1 + 1));
5983 if (!p2)
5984 p2 = p1 + 1 + strlen(p1 + 1);
5985
5986 if (p2 - (p1 + 1) > 255) {
5987 *p2 = '\0';
5988 memprintf(err, "'%s' : NPN protocol name too long : '%s'", args[cur_arg], p1 + 1);
5989 return ERR_ALERT | ERR_FATAL;
5990 }
5991
5992 *p1 = p2 - (p1 + 1);
5993 p1 = p2;
5994
5995 if (!*p2)
5996 break;
5997
5998 *(p2++) = '\0';
5999 }
6000 return 0;
6001#else
6002 if (err)
6003 memprintf(err, "'%s' : library does not support TLS NPN extension", args[cur_arg]);
6004 return ERR_ALERT | ERR_FATAL;
6005#endif
6006}
6007
Emmanuel Hocdet98263292016-12-29 18:26:15 +01006008static int bind_parse_npn(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
6009{
6010 return ssl_bind_parse_npn(args, cur_arg, px, &conf->ssl_conf, err);
6011}
6012
Willy Tarreauab861d32013-04-02 02:30:41 +02006013/* parse the "alpn" bind keyword */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01006014static 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 +02006015{
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01006016#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Willy Tarreauab861d32013-04-02 02:30:41 +02006017 char *p1, *p2;
6018
6019 if (!*args[cur_arg + 1]) {
6020 memprintf(err, "'%s' : missing the comma-delimited ALPN protocol suite", args[cur_arg]);
6021 return ERR_ALERT | ERR_FATAL;
6022 }
6023
6024 free(conf->alpn_str);
6025
Marcoen Hirschbergbef60912016-02-12 17:05:24 +01006026 /* the ALPN string is built as a suite of (<len> <name>)*,
6027 * so we reuse each comma to store the next <len> and need
6028 * one more for the end of the string.
6029 */
Willy Tarreauab861d32013-04-02 02:30:41 +02006030 conf->alpn_len = strlen(args[cur_arg + 1]) + 1;
Marcoen Hirschbergbef60912016-02-12 17:05:24 +01006031 conf->alpn_str = calloc(1, conf->alpn_len + 1);
Willy Tarreauab861d32013-04-02 02:30:41 +02006032 memcpy(conf->alpn_str + 1, args[cur_arg + 1], conf->alpn_len);
6033
6034 /* replace commas with the name length */
6035 p1 = conf->alpn_str;
6036 p2 = p1 + 1;
6037 while (1) {
6038 p2 = memchr(p1 + 1, ',', conf->alpn_str + conf->alpn_len - (p1 + 1));
6039 if (!p2)
6040 p2 = p1 + 1 + strlen(p1 + 1);
6041
6042 if (p2 - (p1 + 1) > 255) {
6043 *p2 = '\0';
6044 memprintf(err, "'%s' : ALPN protocol name too long : '%s'", args[cur_arg], p1 + 1);
6045 return ERR_ALERT | ERR_FATAL;
6046 }
6047
6048 *p1 = p2 - (p1 + 1);
6049 p1 = p2;
6050
6051 if (!*p2)
6052 break;
6053
6054 *(p2++) = '\0';
6055 }
6056 return 0;
6057#else
6058 if (err)
6059 memprintf(err, "'%s' : library does not support TLS ALPN extension", args[cur_arg]);
6060 return ERR_ALERT | ERR_FATAL;
6061#endif
6062}
6063
Emmanuel Hocdet98263292016-12-29 18:26:15 +01006064static int bind_parse_alpn(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
6065{
6066 return ssl_bind_parse_alpn(args, cur_arg, px, &conf->ssl_conf, err);
6067}
6068
Willy Tarreau79eeafa2012-09-14 07:53:05 +02006069/* parse the "ssl" bind keyword */
Willy Tarreau4348fad2012-09-20 16:48:07 +02006070static 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 +02006071{
Willy Tarreau71a8c7c2016-12-21 22:04:54 +01006072 conf->xprt = &ssl_sock;
Willy Tarreau4348fad2012-09-20 16:48:07 +02006073 conf->is_ssl = 1;
Emeric Brun76d88952012-10-05 15:47:31 +02006074
Emmanuel Hocdet98263292016-12-29 18:26:15 +01006075 if (global_ssl.listen_default_ciphers && !conf->ssl_conf.ciphers)
6076 conf->ssl_conf.ciphers = strdup(global_ssl.listen_default_ciphers);
6077 conf->ssl_conf.ssl_options |= global_ssl.listen_default_ssloptions;
Emeric Brun76d88952012-10-05 15:47:31 +02006078
Willy Tarreau79eeafa2012-09-14 07:53:05 +02006079 return 0;
6080}
6081
Christopher Faulet31af49d2015-06-09 17:29:50 +02006082/* parse the "generate-certificates" bind keyword */
6083static int bind_parse_generate_certs(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
6084{
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +01006085#if (defined SSL_CTRL_SET_TLSEXT_HOSTNAME && !defined SSL_NO_GENERATE_CERTIFICATES)
Christopher Faulet31af49d2015-06-09 17:29:50 +02006086 conf->generate_certs = 1;
6087#else
6088 memprintf(err, "%sthis version of openssl cannot generate SSL certificates.\n",
6089 err && *err ? *err : "");
6090#endif
6091 return 0;
6092}
6093
Emmanuel Hocdet65623372013-01-24 17:17:15 +01006094/* parse the "strict-sni" bind keyword */
6095static int bind_parse_strict_sni(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
6096{
6097 conf->strict_sni = 1;
6098 return 0;
Nenad Merdanovic05552d42015-02-27 19:56:49 +01006099}
6100
6101/* parse the "tls-ticket-keys" bind keyword */
6102static int bind_parse_tls_ticket_keys(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
6103{
6104#if (defined SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB && TLS_TICKETS_NO > 0)
6105 FILE *f;
6106 int i = 0;
6107 char thisline[LINESIZE];
Nenad Merdanovic146defa2015-05-09 08:46:00 +02006108 struct tls_keys_ref *keys_ref;
Nenad Merdanovic05552d42015-02-27 19:56:49 +01006109
6110 if (!*args[cur_arg + 1]) {
6111 if (err)
6112 memprintf(err, "'%s' : missing TLS ticket keys file path", args[cur_arg]);
6113 return ERR_ALERT | ERR_FATAL;
6114 }
6115
Nenad Merdanovic200b0fa2015-05-09 08:46:01 +02006116 keys_ref = tlskeys_ref_lookup(args[cur_arg + 1]);
6117 if(keys_ref) {
6118 conf->keys_ref = keys_ref;
6119 return 0;
6120 }
6121
Vincent Bernat02779b62016-04-03 13:48:43 +02006122 keys_ref = malloc(sizeof(*keys_ref));
Nenad Merdanovic146defa2015-05-09 08:46:00 +02006123 keys_ref->tlskeys = malloc(TLS_TICKETS_NO * sizeof(struct tls_sess_key));
Nenad Merdanovic05552d42015-02-27 19:56:49 +01006124
6125 if ((f = fopen(args[cur_arg + 1], "r")) == NULL) {
6126 if (err)
6127 memprintf(err, "'%s' : unable to load ssl tickets keys file", args[cur_arg+1]);
6128 return ERR_ALERT | ERR_FATAL;
6129 }
6130
Nenad Merdanovic146defa2015-05-09 08:46:00 +02006131 keys_ref->filename = strdup(args[cur_arg + 1]);
6132
Nenad Merdanovic05552d42015-02-27 19:56:49 +01006133 while (fgets(thisline, sizeof(thisline), f) != NULL) {
6134 int len = strlen(thisline);
6135 /* Strip newline characters from the end */
6136 if(thisline[len - 1] == '\n')
6137 thisline[--len] = 0;
6138
6139 if(thisline[len - 1] == '\r')
6140 thisline[--len] = 0;
6141
Nenad Merdanovic146defa2015-05-09 08:46:00 +02006142 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 +01006143 if (err)
6144 memprintf(err, "'%s' : unable to decode base64 key on line %d", args[cur_arg+1], i + 1);
mildis16aa0152016-06-22 17:46:29 +02006145 fclose(f);
Nenad Merdanovic05552d42015-02-27 19:56:49 +01006146 return ERR_ALERT | ERR_FATAL;
6147 }
6148 i++;
6149 }
6150
6151 if (i < TLS_TICKETS_NO) {
6152 if (err)
6153 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 +02006154 fclose(f);
Nenad Merdanovic05552d42015-02-27 19:56:49 +01006155 return ERR_ALERT | ERR_FATAL;
6156 }
6157
6158 fclose(f);
6159
6160 /* Use penultimate key for encryption, handle when TLS_TICKETS_NO = 1 */
Nenad Merdanovic17891152016-03-25 22:16:57 +01006161 i -= 2;
6162 keys_ref->tls_ticket_enc_index = i < 0 ? 0 : i % TLS_TICKETS_NO;
Nenad Merdanovic200b0fa2015-05-09 08:46:01 +02006163 keys_ref->unique_id = -1;
Nenad Merdanovic146defa2015-05-09 08:46:00 +02006164 conf->keys_ref = keys_ref;
Nenad Merdanovic05552d42015-02-27 19:56:49 +01006165
Nenad Merdanovic200b0fa2015-05-09 08:46:01 +02006166 LIST_ADD(&tlskeys_reference, &keys_ref->list);
6167
Nenad Merdanovic05552d42015-02-27 19:56:49 +01006168 return 0;
6169#else
6170 if (err)
6171 memprintf(err, "'%s' : TLS ticket callback extension not supported", args[cur_arg]);
6172 return ERR_ALERT | ERR_FATAL;
6173#endif /* SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB */
Emmanuel Hocdet65623372013-01-24 17:17:15 +01006174}
6175
Emeric Brund94b3fe2012-09-20 18:23:56 +02006176/* parse the "verify" bind keyword */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01006177static 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 +02006178{
6179 if (!*args[cur_arg + 1]) {
6180 if (err)
6181 memprintf(err, "'%s' : missing verify method", args[cur_arg]);
6182 return ERR_ALERT | ERR_FATAL;
6183 }
6184
6185 if (strcmp(args[cur_arg + 1], "none") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01006186 conf->verify = SSL_SOCK_VERIFY_NONE;
Emeric Brund94b3fe2012-09-20 18:23:56 +02006187 else if (strcmp(args[cur_arg + 1], "optional") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01006188 conf->verify = SSL_SOCK_VERIFY_OPTIONAL;
Emeric Brund94b3fe2012-09-20 18:23:56 +02006189 else if (strcmp(args[cur_arg + 1], "required") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01006190 conf->verify = SSL_SOCK_VERIFY_REQUIRED;
Emeric Brund94b3fe2012-09-20 18:23:56 +02006191 else {
6192 if (err)
6193 memprintf(err, "'%s' : unknown verify method '%s', only 'none', 'optional', and 'required' are supported\n",
6194 args[cur_arg], args[cur_arg + 1]);
6195 return ERR_ALERT | ERR_FATAL;
6196 }
6197
6198 return 0;
6199}
Emmanuel Hocdet98263292016-12-29 18:26:15 +01006200static int bind_parse_verify(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
6201{
6202 return ssl_bind_parse_verify(args, cur_arg, px, &conf->ssl_conf, err);
6203}
Emeric Brund94b3fe2012-09-20 18:23:56 +02006204
Willy Tarreau92faadf2012-10-10 23:04:25 +02006205/************** "server" keywords ****************/
6206
Emeric Brunef42d922012-10-11 16:11:36 +02006207/* parse the "ca-file" server keyword */
6208static int srv_parse_ca_file(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
6209{
6210 if (!*args[*cur_arg + 1]) {
6211 if (err)
6212 memprintf(err, "'%s' : missing CAfile path", args[*cur_arg]);
6213 return ERR_ALERT | ERR_FATAL;
6214 }
6215
Willy Tarreauef934602016-12-22 23:12:01 +01006216 if ((*args[*cur_arg + 1] != '/') && global_ssl.ca_base)
6217 memprintf(&newsrv->ssl_ctx.ca_file, "%s/%s", global_ssl.ca_base, args[*cur_arg + 1]);
Emeric Brunef42d922012-10-11 16:11:36 +02006218 else
6219 memprintf(&newsrv->ssl_ctx.ca_file, "%s", args[*cur_arg + 1]);
6220
6221 return 0;
6222}
6223
Willy Tarreau92faadf2012-10-10 23:04:25 +02006224/* parse the "check-ssl" server keyword */
6225static int srv_parse_check_ssl(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
6226{
6227 newsrv->check.use_ssl = 1;
Willy Tarreauef934602016-12-22 23:12:01 +01006228 if (global_ssl.connect_default_ciphers && !newsrv->ssl_ctx.ciphers)
6229 newsrv->ssl_ctx.ciphers = strdup(global_ssl.connect_default_ciphers);
6230 newsrv->ssl_ctx.options |= global_ssl.connect_default_ssloptions;
Willy Tarreau92faadf2012-10-10 23:04:25 +02006231 return 0;
6232}
6233
6234/* parse the "ciphers" server keyword */
6235static int srv_parse_ciphers(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
6236{
6237 if (!*args[*cur_arg + 1]) {
6238 memprintf(err, "'%s' : missing cipher suite", args[*cur_arg]);
6239 return ERR_ALERT | ERR_FATAL;
6240 }
6241
6242 free(newsrv->ssl_ctx.ciphers);
6243 newsrv->ssl_ctx.ciphers = strdup(args[*cur_arg + 1]);
6244 return 0;
6245}
6246
Emeric Brunef42d922012-10-11 16:11:36 +02006247/* parse the "crl-file" server keyword */
6248static int srv_parse_crl_file(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
6249{
6250#ifndef X509_V_FLAG_CRL_CHECK
6251 if (err)
6252 memprintf(err, "'%s' : library does not support CRL verify", args[*cur_arg]);
6253 return ERR_ALERT | ERR_FATAL;
6254#else
6255 if (!*args[*cur_arg + 1]) {
6256 if (err)
6257 memprintf(err, "'%s' : missing CRLfile path", args[*cur_arg]);
6258 return ERR_ALERT | ERR_FATAL;
6259 }
6260
Willy Tarreauef934602016-12-22 23:12:01 +01006261 if ((*args[*cur_arg + 1] != '/') && global_ssl.ca_base)
6262 memprintf(&newsrv->ssl_ctx.crl_file, "%s/%s", global_ssl.ca_base, args[*cur_arg + 1]);
Emeric Brunef42d922012-10-11 16:11:36 +02006263 else
6264 memprintf(&newsrv->ssl_ctx.crl_file, "%s", args[*cur_arg + 1]);
6265
6266 return 0;
6267#endif
6268}
6269
Emeric Bruna7aa3092012-10-26 12:58:00 +02006270/* parse the "crt" server keyword */
6271static int srv_parse_crt(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
6272{
6273 if (!*args[*cur_arg + 1]) {
6274 if (err)
6275 memprintf(err, "'%s' : missing certificate file path", args[*cur_arg]);
6276 return ERR_ALERT | ERR_FATAL;
6277 }
6278
Willy Tarreauef934602016-12-22 23:12:01 +01006279 if ((*args[*cur_arg + 1] != '/') && global_ssl.crt_base)
6280 memprintf(&newsrv->ssl_ctx.client_crt, "%s/%s", global_ssl.ca_base, args[*cur_arg + 1]);
Emeric Bruna7aa3092012-10-26 12:58:00 +02006281 else
6282 memprintf(&newsrv->ssl_ctx.client_crt, "%s", args[*cur_arg + 1]);
6283
6284 return 0;
6285}
Emeric Brunef42d922012-10-11 16:11:36 +02006286
Willy Tarreau92faadf2012-10-10 23:04:25 +02006287/* parse the "force-sslv3" server keyword */
6288static int srv_parse_force_sslv3(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
6289{
6290 newsrv->ssl_ctx.options |= SRV_SSL_O_USE_SSLV3;
6291 return 0;
6292}
6293
6294/* parse the "force-tlsv10" server keyword */
6295static int srv_parse_force_tlsv10(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
6296{
6297 newsrv->ssl_ctx.options |= SRV_SSL_O_USE_TLSV10;
6298 return 0;
6299}
6300
6301/* parse the "force-tlsv11" server keyword */
6302static int srv_parse_force_tlsv11(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
6303{
6304#if SSL_OP_NO_TLSv1_1
6305 newsrv->ssl_ctx.options |= SRV_SSL_O_USE_TLSV11;
6306 return 0;
6307#else
6308 if (err)
6309 memprintf(err, "'%s' : library does not support protocol TLSv1.1", args[*cur_arg]);
6310 return ERR_ALERT | ERR_FATAL;
6311#endif
6312}
6313
6314/* parse the "force-tlsv12" server keyword */
6315static int srv_parse_force_tlsv12(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
6316{
6317#if SSL_OP_NO_TLSv1_2
6318 newsrv->ssl_ctx.options |= SRV_SSL_O_USE_TLSV12;
6319 return 0;
6320#else
6321 if (err)
6322 memprintf(err, "'%s' : library does not support protocol TLSv1.2", args[*cur_arg]);
6323 return ERR_ALERT | ERR_FATAL;
6324#endif
6325}
6326
Willy Tarreau2a3fb1c2015-02-05 16:47:07 +01006327/* parse the "no-ssl-reuse" server keyword */
6328static int srv_parse_no_ssl_reuse(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
6329{
6330 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_REUSE;
6331 return 0;
6332}
6333
Willy Tarreau92faadf2012-10-10 23:04:25 +02006334/* parse the "no-sslv3" server keyword */
6335static int srv_parse_no_sslv3(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
6336{
6337 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_SSLV3;
6338 return 0;
6339}
6340
6341/* parse the "no-tlsv10" server keyword */
6342static int srv_parse_no_tlsv10(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
6343{
6344 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_TLSV10;
6345 return 0;
6346}
6347
6348/* parse the "no-tlsv11" server keyword */
6349static int srv_parse_no_tlsv11(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
6350{
6351 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_TLSV11;
6352 return 0;
6353}
6354
6355/* parse the "no-tlsv12" server keyword */
6356static int srv_parse_no_tlsv12(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
6357{
6358 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_TLSV12;
6359 return 0;
6360}
6361
Emeric Brunf9c5c472012-10-11 15:28:34 +02006362/* parse the "no-tls-tickets" server keyword */
6363static int srv_parse_no_tls_tickets(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
6364{
6365 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_TLS_TICKETS;
6366 return 0;
6367}
David Safb76832014-05-08 23:42:08 -04006368/* parse the "send-proxy-v2-ssl" server keyword */
6369static int srv_parse_send_proxy_ssl(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
6370{
6371 newsrv->pp_opts |= SRV_PP_V2;
6372 newsrv->pp_opts |= SRV_PP_V2_SSL;
6373 return 0;
6374}
6375
6376/* parse the "send-proxy-v2-ssl-cn" server keyword */
6377static int srv_parse_send_proxy_cn(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
6378{
6379 newsrv->pp_opts |= SRV_PP_V2;
6380 newsrv->pp_opts |= SRV_PP_V2_SSL;
6381 newsrv->pp_opts |= SRV_PP_V2_SSL_CN;
6382 return 0;
6383}
Emeric Brunf9c5c472012-10-11 15:28:34 +02006384
Willy Tarreau732eac42015-07-09 11:40:25 +02006385/* parse the "sni" server keyword */
6386static int srv_parse_sni(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
6387{
6388#ifndef SSL_CTRL_SET_TLSEXT_HOSTNAME
6389 memprintf(err, "'%s' : the current SSL library doesn't support the SNI TLS extension", args[*cur_arg]);
6390 return ERR_ALERT | ERR_FATAL;
6391#else
Cyril Bonté23d19d62016-03-07 22:13:22 +01006392 int idx;
Willy Tarreau732eac42015-07-09 11:40:25 +02006393 struct sample_expr *expr;
6394
6395 if (!*args[*cur_arg + 1]) {
6396 memprintf(err, "'%s' : missing sni expression", args[*cur_arg]);
6397 return ERR_ALERT | ERR_FATAL;
6398 }
6399
Cyril Bonté23d19d62016-03-07 22:13:22 +01006400 idx = (*cur_arg) + 1;
Willy Tarreau732eac42015-07-09 11:40:25 +02006401 proxy->conf.args.ctx = ARGC_SRV;
6402
Cyril Bonté23d19d62016-03-07 22:13:22 +01006403 expr = sample_parse_expr((char **)args, &idx, px->conf.file, px->conf.line, err, &proxy->conf.args);
Willy Tarreau732eac42015-07-09 11:40:25 +02006404 if (!expr) {
6405 memprintf(err, "error detected while parsing sni expression : %s", *err);
6406 return ERR_ALERT | ERR_FATAL;
6407 }
6408
6409 if (!(expr->fetch->val & SMP_VAL_BE_SRV_CON)) {
6410 memprintf(err, "error detected while parsing sni expression : "
6411 " fetch method '%s' extracts information from '%s', none of which is available here.\n",
Cyril Bonté23d19d62016-03-07 22:13:22 +01006412 args[idx-1], sample_src_names(expr->fetch->use));
Willy Tarreau732eac42015-07-09 11:40:25 +02006413 return ERR_ALERT | ERR_FATAL;
6414 }
6415
6416 px->http_needed |= !!(expr->fetch->use & SMP_USE_HTTP_ANY);
6417 newsrv->ssl_ctx.sni = expr;
6418 return 0;
6419#endif
6420}
6421
Willy Tarreau92faadf2012-10-10 23:04:25 +02006422/* parse the "ssl" server keyword */
6423static int srv_parse_ssl(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
6424{
6425 newsrv->use_ssl = 1;
Willy Tarreauef934602016-12-22 23:12:01 +01006426 if (global_ssl.connect_default_ciphers && !newsrv->ssl_ctx.ciphers)
6427 newsrv->ssl_ctx.ciphers = strdup(global_ssl.connect_default_ciphers);
Willy Tarreau92faadf2012-10-10 23:04:25 +02006428 return 0;
6429}
6430
Emeric Brunef42d922012-10-11 16:11:36 +02006431/* parse the "verify" server keyword */
6432static int srv_parse_verify(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
6433{
6434 if (!*args[*cur_arg + 1]) {
6435 if (err)
6436 memprintf(err, "'%s' : missing verify method", args[*cur_arg]);
6437 return ERR_ALERT | ERR_FATAL;
6438 }
6439
6440 if (strcmp(args[*cur_arg + 1], "none") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01006441 newsrv->ssl_ctx.verify = SSL_SOCK_VERIFY_NONE;
Emeric Brunef42d922012-10-11 16:11:36 +02006442 else if (strcmp(args[*cur_arg + 1], "required") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01006443 newsrv->ssl_ctx.verify = SSL_SOCK_VERIFY_REQUIRED;
Emeric Brunef42d922012-10-11 16:11:36 +02006444 else {
6445 if (err)
6446 memprintf(err, "'%s' : unknown verify method '%s', only 'none' and 'required' are supported\n",
6447 args[*cur_arg], args[*cur_arg + 1]);
6448 return ERR_ALERT | ERR_FATAL;
6449 }
6450
Evan Broderbe554312013-06-27 00:05:25 -07006451 return 0;
6452}
6453
6454/* parse the "verifyhost" server keyword */
6455static int srv_parse_verifyhost(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
6456{
6457 if (!*args[*cur_arg + 1]) {
6458 if (err)
6459 memprintf(err, "'%s' : missing hostname to verify against", args[*cur_arg]);
6460 return ERR_ALERT | ERR_FATAL;
6461 }
6462
6463 newsrv->ssl_ctx.verify_host = strdup(args[*cur_arg + 1]);
6464
Emeric Brunef42d922012-10-11 16:11:36 +02006465 return 0;
6466}
6467
Emeric Brun2c86cbf2014-10-30 15:56:50 +01006468/* parse the "ssl-default-bind-options" keyword in global section */
6469static int ssl_parse_default_bind_options(char **args, int section_type, struct proxy *curpx,
6470 struct proxy *defpx, const char *file, int line,
6471 char **err) {
6472 int i = 1;
6473
6474 if (*(args[i]) == 0) {
6475 memprintf(err, "global statement '%s' expects an option as an argument.", args[0]);
6476 return -1;
6477 }
6478 while (*(args[i])) {
6479 if (!strcmp(args[i], "no-sslv3"))
Willy Tarreauef934602016-12-22 23:12:01 +01006480 global_ssl.listen_default_ssloptions |= BC_SSL_O_NO_SSLV3;
Emeric Brun2c86cbf2014-10-30 15:56:50 +01006481 else if (!strcmp(args[i], "no-tlsv10"))
Willy Tarreauef934602016-12-22 23:12:01 +01006482 global_ssl.listen_default_ssloptions |= BC_SSL_O_NO_TLSV10;
Emeric Brun2c86cbf2014-10-30 15:56:50 +01006483 else if (!strcmp(args[i], "no-tlsv11"))
Willy Tarreauef934602016-12-22 23:12:01 +01006484 global_ssl.listen_default_ssloptions |= BC_SSL_O_NO_TLSV11;
Emeric Brun2c86cbf2014-10-30 15:56:50 +01006485 else if (!strcmp(args[i], "no-tlsv12"))
Willy Tarreauef934602016-12-22 23:12:01 +01006486 global_ssl.listen_default_ssloptions |= BC_SSL_O_NO_TLSV12;
Emeric Brun2c86cbf2014-10-30 15:56:50 +01006487 else if (!strcmp(args[i], "force-sslv3"))
Willy Tarreauef934602016-12-22 23:12:01 +01006488 global_ssl.listen_default_ssloptions |= BC_SSL_O_USE_SSLV3;
Emeric Brun2c86cbf2014-10-30 15:56:50 +01006489 else if (!strcmp(args[i], "force-tlsv10"))
Willy Tarreauef934602016-12-22 23:12:01 +01006490 global_ssl.listen_default_ssloptions |= BC_SSL_O_USE_TLSV10;
Emeric Brun2c86cbf2014-10-30 15:56:50 +01006491 else if (!strcmp(args[i], "force-tlsv11")) {
6492#if SSL_OP_NO_TLSv1_1
Willy Tarreauef934602016-12-22 23:12:01 +01006493 global_ssl.listen_default_ssloptions |= BC_SSL_O_USE_TLSV11;
Emeric Brun2c86cbf2014-10-30 15:56:50 +01006494#else
6495 memprintf(err, "'%s' '%s': library does not support protocol TLSv1.1", args[0], args[i]);
6496 return -1;
6497#endif
6498 }
6499 else if (!strcmp(args[i], "force-tlsv12")) {
6500#if SSL_OP_NO_TLSv1_2
Willy Tarreauef934602016-12-22 23:12:01 +01006501 global_ssl.listen_default_ssloptions |= BC_SSL_O_USE_TLSV12;
Emeric Brun2c86cbf2014-10-30 15:56:50 +01006502#else
6503 memprintf(err, "'%s' '%s': library does not support protocol TLSv1.2", args[0], args[i]);
6504 return -1;
6505#endif
6506 }
6507 else if (!strcmp(args[i], "no-tls-tickets"))
Willy Tarreauef934602016-12-22 23:12:01 +01006508 global_ssl.listen_default_ssloptions |= BC_SSL_O_NO_TLS_TICKETS;
Emeric Brun2c86cbf2014-10-30 15:56:50 +01006509 else {
6510 memprintf(err, "unknown option '%s' on global statement '%s'.", args[i], args[0]);
6511 return -1;
6512 }
6513 i++;
6514 }
6515 return 0;
6516}
6517
6518/* parse the "ssl-default-server-options" keyword in global section */
6519static int ssl_parse_default_server_options(char **args, int section_type, struct proxy *curpx,
6520 struct proxy *defpx, const char *file, int line,
6521 char **err) {
6522 int i = 1;
6523
6524 if (*(args[i]) == 0) {
6525 memprintf(err, "global statement '%s' expects an option as an argument.", args[0]);
6526 return -1;
6527 }
6528 while (*(args[i])) {
6529 if (!strcmp(args[i], "no-sslv3"))
Willy Tarreauef934602016-12-22 23:12:01 +01006530 global_ssl.connect_default_ssloptions |= SRV_SSL_O_NO_SSLV3;
Emeric Brun2c86cbf2014-10-30 15:56:50 +01006531 else if (!strcmp(args[i], "no-tlsv10"))
Willy Tarreauef934602016-12-22 23:12:01 +01006532 global_ssl.connect_default_ssloptions |= SRV_SSL_O_NO_TLSV10;
Emeric Brun2c86cbf2014-10-30 15:56:50 +01006533 else if (!strcmp(args[i], "no-tlsv11"))
Willy Tarreauef934602016-12-22 23:12:01 +01006534 global_ssl.connect_default_ssloptions |= SRV_SSL_O_NO_TLSV11;
Emeric Brun2c86cbf2014-10-30 15:56:50 +01006535 else if (!strcmp(args[i], "no-tlsv12"))
Willy Tarreauef934602016-12-22 23:12:01 +01006536 global_ssl.connect_default_ssloptions |= SRV_SSL_O_NO_TLSV12;
Emeric Brun2c86cbf2014-10-30 15:56:50 +01006537 else if (!strcmp(args[i], "force-sslv3"))
Willy Tarreauef934602016-12-22 23:12:01 +01006538 global_ssl.connect_default_ssloptions |= SRV_SSL_O_USE_SSLV3;
Emeric Brun2c86cbf2014-10-30 15:56:50 +01006539 else if (!strcmp(args[i], "force-tlsv10"))
Willy Tarreauef934602016-12-22 23:12:01 +01006540 global_ssl.connect_default_ssloptions |= SRV_SSL_O_USE_TLSV10;
Emeric Brun2c86cbf2014-10-30 15:56:50 +01006541 else if (!strcmp(args[i], "force-tlsv11")) {
6542#if SSL_OP_NO_TLSv1_1
Willy Tarreauef934602016-12-22 23:12:01 +01006543 global_ssl.connect_default_ssloptions |= SRV_SSL_O_USE_TLSV11;
Emeric Brun2c86cbf2014-10-30 15:56:50 +01006544#else
6545 memprintf(err, "'%s' '%s': library does not support protocol TLSv1.1", args[0], args[i]);
6546 return -1;
6547#endif
6548 }
6549 else if (!strcmp(args[i], "force-tlsv12")) {
6550#if SSL_OP_NO_TLSv1_2
Willy Tarreauef934602016-12-22 23:12:01 +01006551 global_ssl.connect_default_ssloptions |= SRV_SSL_O_USE_TLSV12;
Emeric Brun2c86cbf2014-10-30 15:56:50 +01006552#else
6553 memprintf(err, "'%s' '%s': library does not support protocol TLSv1.2", args[0], args[i]);
6554 return -1;
6555#endif
6556 }
6557 else if (!strcmp(args[i], "no-tls-tickets"))
Willy Tarreauef934602016-12-22 23:12:01 +01006558 global_ssl.connect_default_ssloptions |= SRV_SSL_O_NO_TLS_TICKETS;
Emeric Brun2c86cbf2014-10-30 15:56:50 +01006559 else {
6560 memprintf(err, "unknown option '%s' on global statement '%s'.", args[i], args[0]);
6561 return -1;
6562 }
6563 i++;
6564 }
6565 return 0;
6566}
6567
Willy Tarreau8c3b0fd2016-12-21 22:44:46 +01006568/* parse the "ca-base" / "crt-base" keywords in global section.
6569 * Returns <0 on alert, >0 on warning, 0 on success.
6570 */
6571static int ssl_parse_global_ca_crt_base(char **args, int section_type, struct proxy *curpx,
6572 struct proxy *defpx, const char *file, int line,
6573 char **err)
6574{
6575 char **target;
6576
Willy Tarreauef934602016-12-22 23:12:01 +01006577 target = (args[0][1] == 'a') ? &global_ssl.ca_base : &global_ssl.crt_base;
Willy Tarreau8c3b0fd2016-12-21 22:44:46 +01006578
6579 if (too_many_args(1, args, err, NULL))
6580 return -1;
6581
6582 if (*target) {
6583 memprintf(err, "'%s' already specified.", args[0]);
6584 return -1;
6585 }
6586
6587 if (*(args[1]) == 0) {
6588 memprintf(err, "global statement '%s' expects a directory path as an argument.", args[0]);
6589 return -1;
6590 }
6591 *target = strdup(args[1]);
6592 return 0;
6593}
6594
Willy Tarreauf22e9682016-12-21 23:23:19 +01006595/* parse the "ssl-default-bind-ciphers" / "ssl-default-server-ciphers" keywords
6596 * in global section. Returns <0 on alert, >0 on warning, 0 on success.
6597 */
6598static int ssl_parse_global_ciphers(char **args, int section_type, struct proxy *curpx,
6599 struct proxy *defpx, const char *file, int line,
6600 char **err)
6601{
6602 char **target;
6603
Willy Tarreauef934602016-12-22 23:12:01 +01006604 target = (args[0][12] == 'b') ? &global_ssl.listen_default_ciphers : &global_ssl.connect_default_ciphers;
Willy Tarreauf22e9682016-12-21 23:23:19 +01006605
6606 if (too_many_args(1, args, err, NULL))
6607 return -1;
6608
6609 if (*(args[1]) == 0) {
6610 memprintf(err, "global statement '%s' expects a cipher suite as an argument.", args[0]);
6611 return -1;
6612 }
6613
6614 free(*target);
6615 *target = strdup(args[1]);
6616 return 0;
6617}
6618
Willy Tarreau9ceda382016-12-21 23:13:03 +01006619/* parse various global tune.ssl settings consisting in positive integers.
6620 * Returns <0 on alert, >0 on warning, 0 on success.
6621 */
6622static int ssl_parse_global_int(char **args, int section_type, struct proxy *curpx,
6623 struct proxy *defpx, const char *file, int line,
6624 char **err)
6625{
6626 int *target;
6627
6628 if (strcmp(args[0], "tune.ssl.cachesize") == 0)
6629 target = &global.tune.sslcachesize;
6630 else if (strcmp(args[0], "tune.ssl.maxrecord") == 0)
Willy Tarreauef934602016-12-22 23:12:01 +01006631 target = (int *)&global_ssl.max_record;
Willy Tarreau9ceda382016-12-21 23:13:03 +01006632 else if (strcmp(args[0], "tune.ssl.ssl-ctx-cache-size") == 0)
Willy Tarreauef934602016-12-22 23:12:01 +01006633 target = &global_ssl.ctx_cache;
Willy Tarreau0bea58d2016-12-21 23:17:25 +01006634 else if (strcmp(args[0], "maxsslconn") == 0)
6635 target = &global.maxsslconn;
Willy Tarreau9ceda382016-12-21 23:13:03 +01006636 else {
6637 memprintf(err, "'%s' keyword not unhandled (please report this bug).", args[0]);
6638 return -1;
6639 }
6640
6641 if (too_many_args(1, args, err, NULL))
6642 return -1;
6643
6644 if (*(args[1]) == 0) {
6645 memprintf(err, "'%s' expects an integer argument.", args[0]);
6646 return -1;
6647 }
6648
6649 *target = atoi(args[1]);
6650 if (*target < 0) {
6651 memprintf(err, "'%s' expects a positive numeric value.", args[0]);
6652 return -1;
6653 }
6654 return 0;
6655}
6656
6657/* parse "ssl.force-private-cache".
6658 * Returns <0 on alert, >0 on warning, 0 on success.
6659 */
6660static int ssl_parse_global_private_cache(char **args, int section_type, struct proxy *curpx,
6661 struct proxy *defpx, const char *file, int line,
6662 char **err)
6663{
6664 if (too_many_args(0, args, err, NULL))
6665 return -1;
6666
Willy Tarreauef934602016-12-22 23:12:01 +01006667 global_ssl.private_cache = 1;
Willy Tarreau9ceda382016-12-21 23:13:03 +01006668 return 0;
6669}
6670
6671/* parse "ssl.lifetime".
6672 * Returns <0 on alert, >0 on warning, 0 on success.
6673 */
6674static int ssl_parse_global_lifetime(char **args, int section_type, struct proxy *curpx,
6675 struct proxy *defpx, const char *file, int line,
6676 char **err)
6677{
6678 const char *res;
6679
6680 if (too_many_args(1, args, err, NULL))
6681 return -1;
6682
6683 if (*(args[1]) == 0) {
6684 memprintf(err, "'%s' expects ssl sessions <lifetime> in seconds as argument.", args[0]);
6685 return -1;
6686 }
6687
Willy Tarreauef934602016-12-22 23:12:01 +01006688 res = parse_time_err(args[1], &global_ssl.life_time, TIME_UNIT_S);
Willy Tarreau9ceda382016-12-21 23:13:03 +01006689 if (res) {
6690 memprintf(err, "unexpected character '%c' in argument to <%s>.", *res, args[0]);
6691 return -1;
6692 }
6693 return 0;
6694}
6695
6696#ifndef OPENSSL_NO_DH
Willy Tarreau14e36a12016-12-21 23:28:13 +01006697/* parse "ssl-dh-param-file".
6698 * Returns <0 on alert, >0 on warning, 0 on success.
6699 */
6700static int ssl_parse_global_dh_param_file(char **args, int section_type, struct proxy *curpx,
6701 struct proxy *defpx, const char *file, int line,
6702 char **err)
6703{
6704 if (too_many_args(1, args, err, NULL))
6705 return -1;
6706
6707 if (*(args[1]) == 0) {
6708 memprintf(err, "'%s' expects a file path as an argument.", args[0]);
6709 return -1;
6710 }
6711
6712 if (ssl_sock_load_global_dh_param_from_file(args[1])) {
6713 memprintf(err, "'%s': unable to load DH parameters from file <%s>.", args[0], args[1]);
6714 return -1;
6715 }
6716 return 0;
6717}
6718
Willy Tarreau9ceda382016-12-21 23:13:03 +01006719/* parse "ssl.default-dh-param".
6720 * Returns <0 on alert, >0 on warning, 0 on success.
6721 */
6722static int ssl_parse_global_default_dh(char **args, int section_type, struct proxy *curpx,
6723 struct proxy *defpx, const char *file, int line,
6724 char **err)
6725{
6726 if (too_many_args(1, args, err, NULL))
6727 return -1;
6728
6729 if (*(args[1]) == 0) {
6730 memprintf(err, "'%s' expects an integer argument.", args[0]);
6731 return -1;
6732 }
6733
Willy Tarreauef934602016-12-22 23:12:01 +01006734 global_ssl.default_dh_param = atoi(args[1]);
6735 if (global_ssl.default_dh_param < 1024) {
Willy Tarreau9ceda382016-12-21 23:13:03 +01006736 memprintf(err, "'%s' expects a value >= 1024.", args[0]);
6737 return -1;
6738 }
6739 return 0;
6740}
6741#endif
6742
6743
William Lallemand32af2032016-10-29 18:09:35 +02006744/* This function is used with TLS ticket keys management. It permits to browse
6745 * each reference. The variable <getnext> must contain the current node,
6746 * <end> point to the root node.
6747 */
6748#if (defined SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB && TLS_TICKETS_NO > 0)
6749static inline
6750struct tls_keys_ref *tlskeys_list_get_next(struct tls_keys_ref *getnext, struct list *end)
6751{
6752 struct tls_keys_ref *ref = getnext;
6753
6754 while (1) {
6755
6756 /* Get next list entry. */
6757 ref = LIST_NEXT(&ref->list, struct tls_keys_ref *, list);
6758
6759 /* If the entry is the last of the list, return NULL. */
6760 if (&ref->list == end)
6761 return NULL;
6762
6763 return ref;
6764 }
6765}
6766
6767static inline
6768struct tls_keys_ref *tlskeys_ref_lookup_ref(const char *reference)
6769{
6770 int id;
6771 char *error;
6772
6773 /* If the reference starts by a '#', this is numeric id. */
6774 if (reference[0] == '#') {
6775 /* Try to convert the numeric id. If the conversion fails, the lookup fails. */
6776 id = strtol(reference + 1, &error, 10);
6777 if (*error != '\0')
6778 return NULL;
6779
6780 /* Perform the unique id lookup. */
6781 return tlskeys_ref_lookupid(id);
6782 }
6783
6784 /* Perform the string lookup. */
6785 return tlskeys_ref_lookup(reference);
6786}
6787#endif
6788
6789
6790#if (defined SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB && TLS_TICKETS_NO > 0)
6791
6792static int cli_io_handler_tlskeys_files(struct appctx *appctx);
6793
6794static inline int cli_io_handler_tlskeys_entries(struct appctx *appctx) {
6795 return cli_io_handler_tlskeys_files(appctx);
6796}
6797
Willy Tarreauf5f26e82016-12-16 18:47:27 +01006798/* dumps all tls keys. Relies on cli.i0 (non-null = only list file names), cli.i1
6799 * (next index to be dumped), and cli.p0 (next key reference).
6800 */
William Lallemand32af2032016-10-29 18:09:35 +02006801static int cli_io_handler_tlskeys_files(struct appctx *appctx) {
6802
6803 struct stream_interface *si = appctx->owner;
6804
6805 switch (appctx->st2) {
6806 case STAT_ST_INIT:
6807 /* Display the column headers. If the message cannot be sent,
6808 * quit the fucntion with returning 0. The function is called
6809 * later and restart at the state "STAT_ST_INIT".
6810 */
6811 chunk_reset(&trash);
6812
6813 if (appctx->io_handler == cli_io_handler_tlskeys_entries)
6814 chunk_appendf(&trash, "# id secret\n");
6815 else
6816 chunk_appendf(&trash, "# id (file)\n");
6817
6818 if (bi_putchk(si_ic(si), &trash) == -1) {
6819 si_applet_cant_put(si);
6820 return 0;
6821 }
6822
William Lallemand32af2032016-10-29 18:09:35 +02006823 /* Now, we start the browsing of the references lists.
6824 * Note that the following call to LIST_ELEM return bad pointer. The only
6825 * available field of this pointer is <list>. It is used with the function
6826 * tlskeys_list_get_next() for retruning the first available entry
6827 */
Willy Tarreauf5f26e82016-12-16 18:47:27 +01006828 if (appctx->ctx.cli.p0 == NULL) {
6829 appctx->ctx.cli.p0 = LIST_ELEM(&tlskeys_reference, struct tls_keys_ref *, list);
6830 appctx->ctx.cli.p0 = tlskeys_list_get_next(appctx->ctx.cli.p0, &tlskeys_reference);
William Lallemand32af2032016-10-29 18:09:35 +02006831 }
6832
6833 appctx->st2 = STAT_ST_LIST;
6834 /* fall through */
6835
6836 case STAT_ST_LIST:
Willy Tarreauf5f26e82016-12-16 18:47:27 +01006837 while (appctx->ctx.cli.p0) {
6838 struct tls_keys_ref *ref = appctx->ctx.cli.p0;
6839 int head = ref->tls_ticket_enc_index;
William Lallemand32af2032016-10-29 18:09:35 +02006840
6841 chunk_reset(&trash);
Willy Tarreauf5f26e82016-12-16 18:47:27 +01006842 if (appctx->io_handler == cli_io_handler_tlskeys_entries && appctx->ctx.cli.i1 == 0)
William Lallemand32af2032016-10-29 18:09:35 +02006843 chunk_appendf(&trash, "# ");
Willy Tarreauf5f26e82016-12-16 18:47:27 +01006844
6845 if (appctx->ctx.cli.i1 == 0)
6846 chunk_appendf(&trash, "%d (%s)\n", ref->unique_id, ref->filename);
6847
William Lallemand32af2032016-10-29 18:09:35 +02006848 if (appctx->io_handler == cli_io_handler_tlskeys_entries) {
Willy Tarreauf5f26e82016-12-16 18:47:27 +01006849 while (appctx->ctx.cli.i1 < TLS_TICKETS_NO) {
William Lallemand32af2032016-10-29 18:09:35 +02006850 struct chunk *t2 = get_trash_chunk();
6851
6852 chunk_reset(t2);
6853 /* should never fail here because we dump only a key in the t2 buffer */
Willy Tarreauf5f26e82016-12-16 18:47:27 +01006854 t2->len = a2base64((char *)(ref->tlskeys + (head + 2 + appctx->ctx.cli.i1) % TLS_TICKETS_NO),
William Lallemand32af2032016-10-29 18:09:35 +02006855 sizeof(struct tls_sess_key), t2->str, t2->size);
Willy Tarreauf5f26e82016-12-16 18:47:27 +01006856 chunk_appendf(&trash, "%d.%d %s\n", ref->unique_id, appctx->ctx.cli.i1, t2->str);
William Lallemand32af2032016-10-29 18:09:35 +02006857
6858 if (bi_putchk(si_ic(si), &trash) == -1) {
6859 /* let's try again later from this stream. We add ourselves into
6860 * this stream's users so that it can remove us upon termination.
6861 */
6862 si_applet_cant_put(si);
6863 return 0;
6864 }
Willy Tarreauf5f26e82016-12-16 18:47:27 +01006865 appctx->ctx.cli.i1++;
William Lallemand32af2032016-10-29 18:09:35 +02006866 }
Willy Tarreauf5f26e82016-12-16 18:47:27 +01006867 appctx->ctx.cli.i1 = 0;
William Lallemand32af2032016-10-29 18:09:35 +02006868 }
6869 if (bi_putchk(si_ic(si), &trash) == -1) {
6870 /* let's try again later from this stream. We add ourselves into
6871 * this stream's users so that it can remove us upon termination.
6872 */
6873 si_applet_cant_put(si);
6874 return 0;
6875 }
6876
Willy Tarreauf5f26e82016-12-16 18:47:27 +01006877 if (appctx->ctx.cli.i0 == 0) /* don't display everything if not necessary */
William Lallemand32af2032016-10-29 18:09:35 +02006878 break;
6879
6880 /* get next list entry and check the end of the list */
Willy Tarreauf5f26e82016-12-16 18:47:27 +01006881 appctx->ctx.cli.p0 = tlskeys_list_get_next(appctx->ctx.cli.p0, &tlskeys_reference);
William Lallemand32af2032016-10-29 18:09:35 +02006882 }
6883
6884 appctx->st2 = STAT_ST_FIN;
6885 /* fall through */
6886
6887 default:
6888 appctx->st2 = STAT_ST_FIN;
6889 return 1;
6890 }
6891 return 0;
6892}
6893
Willy Tarreauf5f26e82016-12-16 18:47:27 +01006894/* sets cli.i0 to non-zero if only file lists should be dumped */
William Lallemand32af2032016-10-29 18:09:35 +02006895static int cli_parse_show_tlskeys(char **args, struct appctx *appctx, void *private)
6896{
William Lallemand32af2032016-10-29 18:09:35 +02006897 /* no parameter, shows only file list */
6898 if (!*args[2]) {
Willy Tarreauf5f26e82016-12-16 18:47:27 +01006899 appctx->ctx.cli.i0 = 1;
William Lallemand32af2032016-10-29 18:09:35 +02006900 appctx->io_handler = cli_io_handler_tlskeys_files;
Willy Tarreau3067bfa2016-12-05 14:50:15 +01006901 return 0;
William Lallemand32af2032016-10-29 18:09:35 +02006902 }
6903
6904 if (args[2][0] == '*') {
6905 /* list every TLS ticket keys */
Willy Tarreauf5f26e82016-12-16 18:47:27 +01006906 appctx->ctx.cli.i0 = 1;
William Lallemand32af2032016-10-29 18:09:35 +02006907 } else {
Willy Tarreauf5f26e82016-12-16 18:47:27 +01006908 appctx->ctx.cli.p0 = tlskeys_ref_lookup_ref(args[2]);
6909 if (!appctx->ctx.cli.p0) {
William Lallemand32af2032016-10-29 18:09:35 +02006910 appctx->ctx.cli.msg = "'show tls-keys' unable to locate referenced filename\n";
Willy Tarreau3b6e5472016-11-24 15:53:53 +01006911 appctx->st0 = CLI_ST_PRINT;
William Lallemand32af2032016-10-29 18:09:35 +02006912 return 1;
6913 }
6914 }
William Lallemand32af2032016-10-29 18:09:35 +02006915 appctx->io_handler = cli_io_handler_tlskeys_entries;
Willy Tarreau3067bfa2016-12-05 14:50:15 +01006916 return 0;
William Lallemand32af2032016-10-29 18:09:35 +02006917}
6918
William Lallemand32af2032016-10-29 18:09:35 +02006919static int cli_parse_set_tlskeys(char **args, struct appctx *appctx, void *private)
6920{
Willy Tarreauf5f26e82016-12-16 18:47:27 +01006921 struct tls_keys_ref *ref;
6922
William Lallemand32af2032016-10-29 18:09:35 +02006923 /* Expect two parameters: the filename and the new new TLS key in encoding */
6924 if (!*args[3] || !*args[4]) {
6925 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 +01006926 appctx->st0 = CLI_ST_PRINT;
William Lallemand32af2032016-10-29 18:09:35 +02006927 return 1;
6928 }
6929
Willy Tarreauf5f26e82016-12-16 18:47:27 +01006930 ref = tlskeys_ref_lookup_ref(args[3]);
6931 if (!ref) {
William Lallemand32af2032016-10-29 18:09:35 +02006932 appctx->ctx.cli.msg = "'set ssl tls-key' unable to locate referenced filename\n";
Willy Tarreau3b6e5472016-11-24 15:53:53 +01006933 appctx->st0 = CLI_ST_PRINT;
William Lallemand32af2032016-10-29 18:09:35 +02006934 return 1;
6935 }
6936
6937 trash.len = base64dec(args[4], strlen(args[4]), trash.str, trash.size);
6938 if (trash.len != sizeof(struct tls_sess_key)) {
6939 appctx->ctx.cli.msg = "'set ssl tls-key' received invalid base64 encoded TLS key.\n";
Willy Tarreau3b6e5472016-11-24 15:53:53 +01006940 appctx->st0 = CLI_ST_PRINT;
William Lallemand32af2032016-10-29 18:09:35 +02006941 return 1;
6942 }
6943
Willy Tarreauf5f26e82016-12-16 18:47:27 +01006944 memcpy(ref->tlskeys + ((ref->tls_ticket_enc_index + 2) % TLS_TICKETS_NO), trash.str, trash.len);
6945 ref->tls_ticket_enc_index = (ref->tls_ticket_enc_index + 1) % TLS_TICKETS_NO;
William Lallemand32af2032016-10-29 18:09:35 +02006946
6947 appctx->ctx.cli.msg = "TLS ticket key updated!";
Willy Tarreau3b6e5472016-11-24 15:53:53 +01006948 appctx->st0 = CLI_ST_PRINT;
William Lallemand32af2032016-10-29 18:09:35 +02006949 return 1;
6950
6951}
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +01006952#endif
William Lallemand32af2032016-10-29 18:09:35 +02006953
6954static int cli_parse_set_ocspresponse(char **args, struct appctx *appctx, void *private)
6955{
6956#if (defined SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB && !defined OPENSSL_NO_OCSP)
6957 char *err = NULL;
6958
6959 /* Expect one parameter: the new response in base64 encoding */
6960 if (!*args[3]) {
6961 appctx->ctx.cli.msg = "'set ssl ocsp-response' expects response in base64 encoding.\n";
Willy Tarreau3b6e5472016-11-24 15:53:53 +01006962 appctx->st0 = CLI_ST_PRINT;
William Lallemand32af2032016-10-29 18:09:35 +02006963 return 1;
6964 }
6965
6966 trash.len = base64dec(args[3], strlen(args[3]), trash.str, trash.size);
6967 if (trash.len < 0) {
6968 appctx->ctx.cli.msg = "'set ssl ocsp-response' received invalid base64 encoded response.\n";
Willy Tarreau3b6e5472016-11-24 15:53:53 +01006969 appctx->st0 = CLI_ST_PRINT;
William Lallemand32af2032016-10-29 18:09:35 +02006970 return 1;
6971 }
6972
6973 if (ssl_sock_update_ocsp_response(&trash, &err)) {
6974 if (err) {
6975 memprintf(&err, "%s.\n", err);
6976 appctx->ctx.cli.err = err;
Willy Tarreau3b6e5472016-11-24 15:53:53 +01006977 appctx->st0 = CLI_ST_PRINT_FREE;
William Lallemand32af2032016-10-29 18:09:35 +02006978 }
6979 return 1;
6980 }
6981 appctx->ctx.cli.msg = "OCSP Response updated!";
Willy Tarreau3b6e5472016-11-24 15:53:53 +01006982 appctx->st0 = CLI_ST_PRINT;
William Lallemand32af2032016-10-29 18:09:35 +02006983 return 1;
6984#else
6985 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 +01006986 appctx->st0 = CLI_ST_PRINT;
William Lallemand32af2032016-10-29 18:09:35 +02006987 return 1;
6988#endif
6989
6990}
6991
6992/* register cli keywords */
6993static struct cli_kw_list cli_kws = {{ },{
6994#if (defined SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB && TLS_TICKETS_NO > 0)
6995 { { "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 },
6996 { { "set", "ssl", "tls-keys", NULL }, NULL, cli_parse_set_tlskeys, NULL },
William Lallemand32af2032016-10-29 18:09:35 +02006997#endif
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +01006998 { { "set", "ssl", "ocsp-response", NULL }, NULL, cli_parse_set_ocspresponse, NULL },
William Lallemand32af2032016-10-29 18:09:35 +02006999 { { NULL }, NULL, NULL, NULL }
7000}};
7001
7002
Willy Tarreau7875d092012-09-10 08:20:03 +02007003/* Note: must not be declared <const> as its list will be overwritten.
7004 * Please take care of keeping this list alphabetically sorted.
7005 */
Willy Tarreaudc13c112013-06-21 23:16:39 +02007006static struct sample_fetch_kw_list sample_fetch_keywords = {ILH, {
Emeric Brun645ae792014-04-30 14:21:06 +02007007 { "ssl_bc", smp_fetch_ssl_fc, 0, NULL, SMP_T_BOOL, SMP_USE_L5SRV },
Thierry FOURNIER07ee64e2015-07-06 23:43:03 +02007008 { "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 +02007009 { "ssl_bc_cipher", smp_fetch_ssl_fc_cipher, 0, NULL, SMP_T_STR, SMP_USE_L5SRV },
7010 { "ssl_bc_protocol", smp_fetch_ssl_fc_protocol, 0, NULL, SMP_T_STR, SMP_USE_L5SRV },
Emeric Brunb73a9b02014-04-30 18:49:19 +02007011 { "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 +02007012 { "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 +02007013 { "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 +02007014 { "ssl_c_ca_err", smp_fetch_ssl_c_ca_err, 0, NULL, SMP_T_SINT, SMP_USE_L5CLI },
7015 { "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 +01007016 { "ssl_c_der", smp_fetch_ssl_x_der, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Thierry FOURNIER07ee64e2015-07-06 23:43:03 +02007017 { "ssl_c_err", smp_fetch_ssl_c_err, 0, NULL, SMP_T_SINT, SMP_USE_L5CLI },
Emeric Brunba841a12014-04-30 17:05:08 +02007018 { "ssl_c_i_dn", smp_fetch_ssl_x_i_dn, ARG2(0,STR,SINT), NULL, SMP_T_STR, SMP_USE_L5CLI },
7019 { "ssl_c_key_alg", smp_fetch_ssl_x_key_alg, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
7020 { "ssl_c_notafter", smp_fetch_ssl_x_notafter, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
7021 { "ssl_c_notbefore", smp_fetch_ssl_x_notbefore, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
7022 { "ssl_c_sig_alg", smp_fetch_ssl_x_sig_alg, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
7023 { "ssl_c_s_dn", smp_fetch_ssl_x_s_dn, ARG2(0,STR,SINT), NULL, SMP_T_STR, SMP_USE_L5CLI },
7024 { "ssl_c_serial", smp_fetch_ssl_x_serial, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
7025 { "ssl_c_sha1", smp_fetch_ssl_x_sha1, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Willy Tarreau80aca902013-01-07 15:42:20 +01007026 { "ssl_c_used", smp_fetch_ssl_c_used, 0, NULL, SMP_T_BOOL, SMP_USE_L5CLI },
Thierry FOURNIER07ee64e2015-07-06 23:43:03 +02007027 { "ssl_c_verify", smp_fetch_ssl_c_verify, 0, NULL, SMP_T_SINT, SMP_USE_L5CLI },
7028 { "ssl_c_version", smp_fetch_ssl_x_version, 0, NULL, SMP_T_SINT, SMP_USE_L5CLI },
Emeric Brun43e79582014-10-29 19:03:26 +01007029 { "ssl_f_der", smp_fetch_ssl_x_der, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Emeric Brunba841a12014-04-30 17:05:08 +02007030 { "ssl_f_i_dn", smp_fetch_ssl_x_i_dn, ARG2(0,STR,SINT), NULL, SMP_T_STR, SMP_USE_L5CLI },
7031 { "ssl_f_key_alg", smp_fetch_ssl_x_key_alg, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
7032 { "ssl_f_notafter", smp_fetch_ssl_x_notafter, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
7033 { "ssl_f_notbefore", smp_fetch_ssl_x_notbefore, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
7034 { "ssl_f_sig_alg", smp_fetch_ssl_x_sig_alg, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
7035 { "ssl_f_s_dn", smp_fetch_ssl_x_s_dn, ARG2(0,STR,SINT), NULL, SMP_T_STR, SMP_USE_L5CLI },
7036 { "ssl_f_serial", smp_fetch_ssl_x_serial, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Emeric Brun55f4fa82014-04-30 17:11:25 +02007037 { "ssl_f_sha1", smp_fetch_ssl_x_sha1, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Thierry FOURNIER07ee64e2015-07-06 23:43:03 +02007038 { "ssl_f_version", smp_fetch_ssl_x_version, 0, NULL, SMP_T_SINT, SMP_USE_L5CLI },
Willy Tarreau80aca902013-01-07 15:42:20 +01007039 { "ssl_fc", smp_fetch_ssl_fc, 0, NULL, SMP_T_BOOL, SMP_USE_L5CLI },
Thierry FOURNIER07ee64e2015-07-06 23:43:03 +02007040 { "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 +01007041 { "ssl_fc_cipher", smp_fetch_ssl_fc_cipher, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Willy Tarreau80aca902013-01-07 15:42:20 +01007042 { "ssl_fc_has_crt", smp_fetch_ssl_fc_has_crt, 0, NULL, SMP_T_BOOL, SMP_USE_L5CLI },
7043 { "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 +02007044 { "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 +02007045#ifdef OPENSSL_NPN_NEGOTIATED
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01007046 { "ssl_fc_npn", smp_fetch_ssl_fc_npn, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Willy Tarreaua33c6542012-10-15 13:19:06 +02007047#endif
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01007048#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01007049 { "ssl_fc_alpn", smp_fetch_ssl_fc_alpn, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Willy Tarreauab861d32013-04-02 02:30:41 +02007050#endif
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01007051 { "ssl_fc_protocol", smp_fetch_ssl_fc_protocol, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Emeric Brunb73a9b02014-04-30 18:49:19 +02007052 { "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 +02007053 { "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 +01007054 { "ssl_fc_session_id", smp_fetch_ssl_fc_session_id, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
7055 { "ssl_fc_sni", smp_fetch_ssl_fc_sni, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Willy Tarreau7875d092012-09-10 08:20:03 +02007056 { NULL, NULL, 0, 0, 0 },
7057}};
7058
7059/* Note: must not be declared <const> as its list will be overwritten.
7060 * Please take care of keeping this list alphabetically sorted.
7061 */
Willy Tarreaudc13c112013-06-21 23:16:39 +02007062static struct acl_kw_list acl_kws = {ILH, {
Thierry FOURNIERc5a4e982014-03-05 16:07:08 +01007063 { "ssl_fc_sni_end", "ssl_fc_sni", PAT_MATCH_END },
7064 { "ssl_fc_sni_reg", "ssl_fc_sni", PAT_MATCH_REG },
Willy Tarreau8ed669b2013-01-11 15:49:37 +01007065 { /* END */ },
Willy Tarreau7875d092012-09-10 08:20:03 +02007066}};
7067
Willy Tarreau79eeafa2012-09-14 07:53:05 +02007068/* Note: must not be declared <const> as its list will be overwritten.
7069 * Please take care of keeping this list alphabetically sorted, doing so helps
7070 * all code contributors.
7071 * Optional keywords are also declared with a NULL ->parse() function so that
7072 * the config parser can report an appropriate error when a known keyword was
7073 * not enabled.
7074 */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01007075static struct ssl_bind_kw ssl_bind_kws[] = {
7076 { "alpn", ssl_bind_parse_alpn, 1 }, /* set ALPN supported protocols */
7077 { "ca-file", ssl_bind_parse_ca_file, 1 }, /* set CAfile to process verify on client cert */
7078 { "ciphers", ssl_bind_parse_ciphers, 1 }, /* set SSL cipher suite */
7079 { "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 +01007080 { "curves", ssl_bind_parse_curves, 1 }, /* set SSL curve suite */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01007081 { "ecdhe", ssl_bind_parse_ecdhe, 1 }, /* defines named curve for elliptic curve Diffie-Hellman */
7082 { "force-sslv3", ssl_bind_parse_force_sslv3, 0 }, /* force SSLv3 */
7083 { "force-tlsv10", ssl_bind_parse_force_tlsv10, 0 }, /* force TLSv10 */
7084 { "force-tlsv11", ssl_bind_parse_force_tlsv11, 0 }, /* force TLSv11 */
7085 { "force-tlsv12", ssl_bind_parse_force_tlsv12, 0 }, /* force TLSv12 */
7086 { "no-sslv3", ssl_bind_parse_no_sslv3, 0 }, /* disable SSLv3 */
7087 { "no-tlsv10", ssl_bind_parse_no_tlsv10, 0 }, /* disable TLSv10 */
7088 { "no-tlsv11", ssl_bind_parse_no_tlsv11, 0 }, /* disable TLSv11 */
7089 { "no-tlsv12", ssl_bind_parse_no_tlsv12, 0 }, /* disable TLSv12 */
7090 { "no-tls-tickets", ssl_bind_parse_no_tls_tickets, 0 }, /* disable session resumption tickets */
7091 { "npn", ssl_bind_parse_npn, 1 }, /* set NPN supported protocols */
7092 { "verify", ssl_bind_parse_verify, 1 }, /* set SSL verify method */
7093 { NULL, NULL, 0 },
7094};
7095
Willy Tarreau51fb7652012-09-18 18:24:39 +02007096static struct bind_kw_list bind_kws = { "SSL", { }, {
Nenad Merdanovic05552d42015-02-27 19:56:49 +01007097 { "alpn", bind_parse_alpn, 1 }, /* set ALPN supported protocols */
7098 { "ca-file", bind_parse_ca_file, 1 }, /* set CAfile to process verify on client cert */
7099 { "ca-ignore-err", bind_parse_ignore_err, 1 }, /* set error IDs to ignore on verify depth > 0 */
Christopher Faulet31af49d2015-06-09 17:29:50 +02007100 { "ca-sign-file", bind_parse_ca_sign_file, 1 }, /* set CAFile used to generate and sign server certs */
7101 { "ca-sign-pass", bind_parse_ca_sign_pass, 1 }, /* set CAKey passphrase */
Nenad Merdanovic05552d42015-02-27 19:56:49 +01007102 { "ciphers", bind_parse_ciphers, 1 }, /* set SSL cipher suite */
7103 { "crl-file", bind_parse_crl_file, 1 }, /* set certificat revocation list file use on client cert verify */
7104 { "crt", bind_parse_crt, 1 }, /* load SSL certificates from this location */
7105 { "crt-ignore-err", bind_parse_ignore_err, 1 }, /* set error IDs to ingore on verify depth == 0 */
7106 { "crt-list", bind_parse_crt_list, 1 }, /* load a list of crt from this location */
Emmanuel Hocdete7f2b732017-01-09 16:15:54 +01007107 { "curves", bind_parse_curves, 1 }, /* set SSL curve suite */
Nenad Merdanovic05552d42015-02-27 19:56:49 +01007108 { "ecdhe", bind_parse_ecdhe, 1 }, /* defines named curve for elliptic curve Diffie-Hellman */
7109 { "force-sslv3", bind_parse_force_sslv3, 0 }, /* force SSLv3 */
7110 { "force-tlsv10", bind_parse_force_tlsv10, 0 }, /* force TLSv10 */
7111 { "force-tlsv11", bind_parse_force_tlsv11, 0 }, /* force TLSv11 */
7112 { "force-tlsv12", bind_parse_force_tlsv12, 0 }, /* force TLSv12 */
Christopher Faulet31af49d2015-06-09 17:29:50 +02007113 { "generate-certificates", bind_parse_generate_certs, 0 }, /* enable the server certificates generation */
Nenad Merdanovic05552d42015-02-27 19:56:49 +01007114 { "no-sslv3", bind_parse_no_sslv3, 0 }, /* disable SSLv3 */
7115 { "no-tlsv10", bind_parse_no_tlsv10, 0 }, /* disable TLSv10 */
7116 { "no-tlsv11", bind_parse_no_tlsv11, 0 }, /* disable TLSv11 */
7117 { "no-tlsv12", bind_parse_no_tlsv12, 0 }, /* disable TLSv12 */
7118 { "no-tls-tickets", bind_parse_no_tls_tickets, 0 }, /* disable session resumption tickets */
7119 { "ssl", bind_parse_ssl, 0 }, /* enable SSL processing */
7120 { "strict-sni", bind_parse_strict_sni, 0 }, /* refuse negotiation if sni doesn't match a certificate */
7121 { "tls-ticket-keys", bind_parse_tls_ticket_keys, 1 }, /* set file to load TLS ticket keys from */
7122 { "verify", bind_parse_verify, 1 }, /* set SSL verify method */
7123 { "npn", bind_parse_npn, 1 }, /* set NPN supported protocols */
Willy Tarreau79eeafa2012-09-14 07:53:05 +02007124 { NULL, NULL, 0 },
7125}};
Emeric Brun46591952012-05-18 15:47:34 +02007126
Willy Tarreau92faadf2012-10-10 23:04:25 +02007127/* Note: must not be declared <const> as its list will be overwritten.
7128 * Please take care of keeping this list alphabetically sorted, doing so helps
7129 * all code contributors.
7130 * Optional keywords are also declared with a NULL ->parse() function so that
7131 * the config parser can report an appropriate error when a known keyword was
7132 * not enabled.
7133 */
7134static struct srv_kw_list srv_kws = { "SSL", { }, {
Emeric Brunef42d922012-10-11 16:11:36 +02007135 { "ca-file", srv_parse_ca_file, 1, 0 }, /* set CAfile to process verify server cert */
Emeric Brunecc91fe2012-10-11 15:05:10 +02007136 { "check-ssl", srv_parse_check_ssl, 0, 0 }, /* enable SSL for health checks */
7137 { "ciphers", srv_parse_ciphers, 1, 0 }, /* select the cipher suite */
Emeric Brunef42d922012-10-11 16:11:36 +02007138 { "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 +02007139 { "crt", srv_parse_crt, 1, 0 }, /* set client certificate */
Emeric Brunecc91fe2012-10-11 15:05:10 +02007140 { "force-sslv3", srv_parse_force_sslv3, 0, 0 }, /* force SSLv3 */
7141 { "force-tlsv10", srv_parse_force_tlsv10, 0, 0 }, /* force TLSv10 */
7142 { "force-tlsv11", srv_parse_force_tlsv11, 0, 0 }, /* force TLSv11 */
7143 { "force-tlsv12", srv_parse_force_tlsv12, 0, 0 }, /* force TLSv12 */
Willy Tarreau2a3fb1c2015-02-05 16:47:07 +01007144 { "no-ssl-reuse", srv_parse_no_ssl_reuse, 0, 0 }, /* disable session reuse */
Emeric Brunecc91fe2012-10-11 15:05:10 +02007145 { "no-sslv3", srv_parse_no_sslv3, 0, 0 }, /* disable SSLv3 */
7146 { "no-tlsv10", srv_parse_no_tlsv10, 0, 0 }, /* disable TLSv10 */
7147 { "no-tlsv11", srv_parse_no_tlsv11, 0, 0 }, /* disable TLSv11 */
7148 { "no-tlsv12", srv_parse_no_tlsv12, 0, 0 }, /* disable TLSv12 */
Emeric Brunf9c5c472012-10-11 15:28:34 +02007149 { "no-tls-tickets", srv_parse_no_tls_tickets, 0, 0 }, /* disable session resumption tickets */
David Safb76832014-05-08 23:42:08 -04007150 { "send-proxy-v2-ssl", srv_parse_send_proxy_ssl, 0, 0 }, /* send PROXY protocol header v2 with SSL info */
7151 { "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 +02007152 { "sni", srv_parse_sni, 1, 0 }, /* send SNI extension */
Emeric Brunecc91fe2012-10-11 15:05:10 +02007153 { "ssl", srv_parse_ssl, 0, 0 }, /* enable SSL processing */
Emeric Brunef42d922012-10-11 16:11:36 +02007154 { "verify", srv_parse_verify, 1, 0 }, /* set SSL verify method */
Evan Broderbe554312013-06-27 00:05:25 -07007155 { "verifyhost", srv_parse_verifyhost, 1, 0 }, /* require that SSL cert verifies for hostname */
Willy Tarreau92faadf2012-10-10 23:04:25 +02007156 { NULL, NULL, 0, 0 },
7157}};
7158
Emeric Brun2c86cbf2014-10-30 15:56:50 +01007159static struct cfg_kw_list cfg_kws = {ILH, {
Willy Tarreau8c3b0fd2016-12-21 22:44:46 +01007160 { CFG_GLOBAL, "ca-base", ssl_parse_global_ca_crt_base },
7161 { CFG_GLOBAL, "crt-base", ssl_parse_global_ca_crt_base },
Willy Tarreau0bea58d2016-12-21 23:17:25 +01007162 { CFG_GLOBAL, "maxsslconn", ssl_parse_global_int },
Emeric Brun2c86cbf2014-10-30 15:56:50 +01007163 { CFG_GLOBAL, "ssl-default-bind-options", ssl_parse_default_bind_options },
7164 { CFG_GLOBAL, "ssl-default-server-options", ssl_parse_default_server_options },
Willy Tarreau14e36a12016-12-21 23:28:13 +01007165#ifndef OPENSSL_NO_DH
7166 { CFG_GLOBAL, "ssl-dh-param-file", ssl_parse_global_dh_param_file },
7167#endif
Willy Tarreau9ceda382016-12-21 23:13:03 +01007168 { CFG_GLOBAL, "tune.ssl.cachesize", ssl_parse_global_int },
7169#ifndef OPENSSL_NO_DH
7170 { CFG_GLOBAL, "tune.ssl.default-dh-param", ssl_parse_global_default_dh },
7171#endif
7172 { CFG_GLOBAL, "tune.ssl.force-private-cache", ssl_parse_global_private_cache },
7173 { CFG_GLOBAL, "tune.ssl.lifetime", ssl_parse_global_lifetime },
7174 { CFG_GLOBAL, "tune.ssl.maxrecord", ssl_parse_global_int },
7175 { CFG_GLOBAL, "tune.ssl.ssl-ctx-cache-size", ssl_parse_global_int },
Willy Tarreauf22e9682016-12-21 23:23:19 +01007176 { CFG_GLOBAL, "ssl-default-bind-ciphers", ssl_parse_global_ciphers },
7177 { CFG_GLOBAL, "ssl-default-server-ciphers", ssl_parse_global_ciphers },
Emeric Brun2c86cbf2014-10-30 15:56:50 +01007178 { 0, NULL, NULL },
7179}};
7180
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02007181/* transport-layer operations for SSL sockets */
Willy Tarreaud9f5cca2016-12-22 21:08:52 +01007182static struct xprt_ops ssl_sock = {
Emeric Brun46591952012-05-18 15:47:34 +02007183 .snd_buf = ssl_sock_from_buf,
7184 .rcv_buf = ssl_sock_to_buf,
7185 .rcv_pipe = NULL,
7186 .snd_pipe = NULL,
7187 .shutr = NULL,
7188 .shutw = ssl_sock_shutw,
7189 .close = ssl_sock_close,
7190 .init = ssl_sock_init,
Willy Tarreau55d37912016-12-21 23:38:39 +01007191 .prepare_bind_conf = ssl_sock_prepare_bind_conf,
Willy Tarreau795cdab2016-12-22 17:30:54 +01007192 .destroy_bind_conf = ssl_sock_destroy_bind_conf,
Willy Tarreau17d45382016-12-22 21:16:08 +01007193 .prepare_srv = ssl_sock_prepare_srv_ctx,
7194 .destroy_srv = ssl_sock_free_srv_ctx,
Willy Tarreau8e0bb0a2016-11-24 16:58:12 +01007195 .name = "SSL",
Emeric Brun46591952012-05-18 15:47:34 +02007196};
7197
Daniel Jakots54ffb912015-11-06 20:02:41 +01007198#if (OPENSSL_VERSION_NUMBER >= 0x1000200fL && !defined OPENSSL_NO_TLSEXT && !defined OPENSSL_IS_BORINGSSL && !defined LIBRESSL_VERSION_NUMBER)
Janusz Dziemidowicz2c701b52015-03-07 23:03:59 +01007199
7200static void ssl_sock_sctl_free_func(void *parent, void *ptr, CRYPTO_EX_DATA *ad, int idx, long argl, void *argp)
7201{
7202 if (ptr) {
7203 chunk_destroy(ptr);
7204 free(ptr);
7205 }
7206}
7207
7208#endif
7209
Emeric Brun46591952012-05-18 15:47:34 +02007210__attribute__((constructor))
Willy Tarreau92faadf2012-10-10 23:04:25 +02007211static void __ssl_sock_init(void)
7212{
Willy Tarreauc2c0b612016-12-21 19:23:20 +01007213 char *ptr;
7214
Emeric Brun46591952012-05-18 15:47:34 +02007215 STACK_OF(SSL_COMP)* cm;
7216
Willy Tarreauef934602016-12-22 23:12:01 +01007217 if (global_ssl.listen_default_ciphers)
7218 global_ssl.listen_default_ciphers = strdup(global_ssl.listen_default_ciphers);
7219 if (global_ssl.connect_default_ciphers)
7220 global_ssl.connect_default_ciphers = strdup(global_ssl.connect_default_ciphers);
Willy Tarreau610f04b2014-02-13 11:36:41 +01007221
Willy Tarreau13e14102016-12-22 20:25:26 +01007222 xprt_register(XPRT_SSL, &ssl_sock);
Emeric Brun46591952012-05-18 15:47:34 +02007223 SSL_library_init();
7224 cm = SSL_COMP_get_compression_methods();
7225 sk_SSL_COMP_zero(cm);
Daniel Jakots54ffb912015-11-06 20:02:41 +01007226#if (OPENSSL_VERSION_NUMBER >= 0x1000200fL && !defined OPENSSL_NO_TLSEXT && !defined OPENSSL_IS_BORINGSSL && !defined LIBRESSL_VERSION_NUMBER)
Janusz Dziemidowicz2c701b52015-03-07 23:03:59 +01007227 sctl_ex_index = SSL_CTX_get_ex_new_index(0, NULL, NULL, NULL, ssl_sock_sctl_free_func);
7228#endif
Willy Tarreau7875d092012-09-10 08:20:03 +02007229 sample_register_fetches(&sample_fetch_keywords);
7230 acl_register_keywords(&acl_kws);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02007231 bind_register_keywords(&bind_kws);
Willy Tarreau92faadf2012-10-10 23:04:25 +02007232 srv_register_keywords(&srv_kws);
Emeric Brun2c86cbf2014-10-30 15:56:50 +01007233 cfg_register_keywords(&cfg_kws);
William Lallemand32af2032016-10-29 18:09:35 +02007234 cli_register_kw(&cli_kws);
Willy Tarreaud1c57502016-12-22 22:46:15 +01007235#if (defined SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB && TLS_TICKETS_NO > 0)
7236 hap_register_post_check(tlskeys_finalize_config);
7237#endif
Willy Tarreaud92aa5c2015-01-15 21:34:39 +01007238
Willy Tarreauc2c0b612016-12-21 19:23:20 +01007239 ptr = NULL;
7240 memprintf(&ptr, "Built with OpenSSL version : "
7241#ifdef OPENSSL_IS_BORINGSSL
7242 "BoringSSL\n");
7243#else /* OPENSSL_IS_BORINGSSL */
7244 OPENSSL_VERSION_TEXT
7245 "\nRunning on OpenSSL version : %s%s",
7246 SSLeay_version(SSLEAY_VERSION),
7247 ((OPENSSL_VERSION_NUMBER ^ SSLeay()) >> 8) ? " (VERSIONS DIFFER!)" : "");
7248#endif
7249 memprintf(&ptr, "%s\nOpenSSL library supports TLS extensions : "
7250#if OPENSSL_VERSION_NUMBER < 0x00907000L
7251 "no (library version too old)"
7252#elif defined(OPENSSL_NO_TLSEXT)
7253 "no (disabled via OPENSSL_NO_TLSEXT)"
7254#else
7255 "yes"
7256#endif
7257 "", ptr);
7258
7259 memprintf(&ptr, "%s\nOpenSSL library supports SNI : "
7260#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
7261 "yes"
7262#else
7263#ifdef OPENSSL_NO_TLSEXT
7264 "no (because of OPENSSL_NO_TLSEXT)"
7265#else
7266 "no (version might be too old, 0.9.8f min needed)"
7267#endif
7268#endif
7269 "", ptr);
7270
Willy Tarreauc2c0b612016-12-21 19:23:20 +01007271 hap_register_build_opts(ptr, 1);
7272
Willy Tarreaud92aa5c2015-01-15 21:34:39 +01007273 global.ssl_session_max_cost = SSL_SESSION_MAX_COST;
7274 global.ssl_handshake_max_cost = SSL_HANDSHAKE_MAX_COST;
Remi Gacogne4f902b82015-05-28 16:23:00 +02007275
7276#ifndef OPENSSL_NO_DH
7277 ssl_dh_ptr_index = SSL_CTX_get_ex_new_index(0, NULL, NULL, NULL, NULL);
7278#endif
Thierry FOURNIER / OZON.IO8b068c22016-10-10 11:59:50 +02007279
7280 /* Load SSL string for the verbose & debug mode. */
7281 ERR_load_SSL_strings();
Emeric Brun46591952012-05-18 15:47:34 +02007282}
7283
Remi Gacogned3a23c32015-05-28 16:39:47 +02007284__attribute__((destructor))
7285static void __ssl_sock_deinit(void)
7286{
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +01007287#if (defined SSL_CTRL_SET_TLSEXT_HOSTNAME && !defined SSL_NO_GENERATE_CERTIFICATES)
Christopher Faulet31af49d2015-06-09 17:29:50 +02007288 lru64_destroy(ssl_ctx_lru_tree);
Willy Tarreaua84c2672015-10-09 12:10:13 +02007289#endif
Christopher Faulet31af49d2015-06-09 17:29:50 +02007290
Remi Gacogned3a23c32015-05-28 16:39:47 +02007291#ifndef OPENSSL_NO_DH
7292 if (local_dh_1024) {
7293 DH_free(local_dh_1024);
7294 local_dh_1024 = NULL;
7295 }
7296
7297 if (local_dh_2048) {
7298 DH_free(local_dh_2048);
7299 local_dh_2048 = NULL;
7300 }
7301
7302 if (local_dh_4096) {
7303 DH_free(local_dh_4096);
7304 local_dh_4096 = NULL;
7305 }
7306
Remi Gacogne47783ef2015-05-29 15:53:22 +02007307 if (global_dh) {
7308 DH_free(global_dh);
7309 global_dh = NULL;
7310 }
Remi Gacogned3a23c32015-05-28 16:39:47 +02007311#endif
7312
7313 ERR_remove_state(0);
7314 ERR_free_strings();
7315
7316 EVP_cleanup();
7317
7318#if OPENSSL_VERSION_NUMBER >= 0x00907000L
7319 CRYPTO_cleanup_all_ex_data();
7320#endif
7321}
7322
7323
Emeric Brun46591952012-05-18 15:47:34 +02007324/*
7325 * Local variables:
7326 * c-indent-level: 8
7327 * c-basic-offset: 8
7328 * End:
7329 */