blob: 232a4970f654588440fcdb3cbcc2536dcf8406c5 [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
Emeric Brunfc0421f2012-09-07 17:30:07 +02001438/* Sets the SSL ctx of <ssl> to match the advertised server name. Returns a
1439 * warning when no match is found, which implies the default (first) cert
1440 * will keep being used.
1441 */
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +01001442static int ssl_sock_switchctx_cbk(SSL *ssl, int *al, void *priv)
Emeric Brunfc0421f2012-09-07 17:30:07 +02001443{
1444 const char *servername;
1445 const char *wildp = NULL;
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001446 struct ebmb_node *node, *n;
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +01001447 struct bind_conf *s = priv;
Emeric Brunfc0421f2012-09-07 17:30:07 +02001448 int i;
1449 (void)al; /* shut gcc stupid warning */
1450
1451 servername = SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name);
Emmanuel Hocdet65623372013-01-24 17:17:15 +01001452 if (!servername) {
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +01001453#if (!defined SSL_NO_GENERATE_CERTIFICATES)
Willy Tarreauf6721452015-07-07 18:04:38 +02001454 if (s->generate_certs) {
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02001455 struct connection *conn = SSL_get_app_data(ssl);
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001456 unsigned int key;
Willy Tarreauf6721452015-07-07 18:04:38 +02001457 SSL_CTX *ctx;
Christopher Faulet30548802015-06-11 13:39:32 +02001458
Willy Tarreauf6721452015-07-07 18:04:38 +02001459 conn_get_to_addr(conn);
1460 if (conn->flags & CO_FL_ADDR_TO_SET) {
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001461 key = ssl_sock_generated_cert_key(&conn->addr.to, get_addr_len(&conn->addr.to));
1462 ctx = ssl_sock_get_generated_cert(key, s);
Willy Tarreauf6721452015-07-07 18:04:38 +02001463 if (ctx) {
1464 /* switch ctx */
1465 SSL_set_SSL_CTX(ssl, ctx);
1466 return SSL_TLSEXT_ERR_OK;
1467 }
Christopher Faulet30548802015-06-11 13:39:32 +02001468 }
1469 }
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +01001470#endif
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001471 return (s->strict_sni ?
1472 SSL_TLSEXT_ERR_ALERT_FATAL :
Emmanuel Hocdet79274e22013-05-31 12:47:44 +02001473 SSL_TLSEXT_ERR_NOACK);
Emmanuel Hocdet65623372013-01-24 17:17:15 +01001474 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02001475
Willy Tarreau19d14ef2012-10-29 16:51:55 +01001476 for (i = 0; i < trash.size; i++) {
Emeric Brunfc0421f2012-09-07 17:30:07 +02001477 if (!servername[i])
1478 break;
Willy Tarreau19d14ef2012-10-29 16:51:55 +01001479 trash.str[i] = tolower(servername[i]);
1480 if (!wildp && (trash.str[i] == '.'))
1481 wildp = &trash.str[i];
Emeric Brunfc0421f2012-09-07 17:30:07 +02001482 }
Willy Tarreau19d14ef2012-10-29 16:51:55 +01001483 trash.str[i] = 0;
Emeric Brunfc0421f2012-09-07 17:30:07 +02001484
1485 /* lookup in full qualified names */
Willy Tarreau19d14ef2012-10-29 16:51:55 +01001486 node = ebst_lookup(&s->sni_ctx, trash.str);
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001487
1488 /* lookup a not neg filter */
1489 for (n = node; n; n = ebmb_next_dup(n)) {
1490 if (!container_of(n, struct sni_ctx, name)->neg) {
1491 node = n;
1492 break;
Emmanuel Hocdet65623372013-01-24 17:17:15 +01001493 }
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001494 }
1495 if (!node && wildp) {
1496 /* lookup in wildcards names */
Emeric Brunfc0421f2012-09-07 17:30:07 +02001497 node = ebst_lookup(&s->sni_w_ctx, wildp);
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001498 }
1499 if (!node || container_of(node, struct sni_ctx, name)->neg) {
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +01001500#if (!defined SSL_NO_GENERATE_CERTIFICATES)
Christopher Faulet31af49d2015-06-09 17:29:50 +02001501 SSL_CTX *ctx;
Christopher Faulet31af49d2015-06-09 17:29:50 +02001502 if (s->generate_certs &&
Christopher Faulet7969a332015-10-09 11:15:03 +02001503 (ctx = ssl_sock_generate_certificate(servername, s, ssl))) {
Christopher Faulet31af49d2015-06-09 17:29:50 +02001504 /* switch ctx */
Christopher Faulet31af49d2015-06-09 17:29:50 +02001505 return SSL_TLSEXT_ERR_OK;
1506 }
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +01001507#endif
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001508 return (s->strict_sni ?
1509 SSL_TLSEXT_ERR_ALERT_FATAL :
1510 SSL_TLSEXT_ERR_ALERT_WARNING);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001511 }
1512
1513 /* switch ctx */
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001514 SSL_set_SSL_CTX(ssl, container_of(node, struct sni_ctx, name)->ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001515 return SSL_TLSEXT_ERR_OK;
1516}
1517#endif /* SSL_CTRL_SET_TLSEXT_HOSTNAME */
1518
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001519#ifndef OPENSSL_NO_DH
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001520
1521static DH * ssl_get_dh_1024(void)
1522{
Remi Gacogned3a341a2015-05-29 16:26:17 +02001523 static unsigned char dh1024_p[]={
1524 0xFA,0xF9,0x2A,0x22,0x2A,0xA7,0x7F,0xE1,0x67,0x4E,0x53,0xF7,
1525 0x56,0x13,0xC3,0xB1,0xE3,0x29,0x6B,0x66,0x31,0x6A,0x7F,0xB3,
1526 0xC2,0x68,0x6B,0xCB,0x1D,0x57,0x39,0x1D,0x1F,0xFF,0x1C,0xC9,
1527 0xA6,0xA4,0x98,0x82,0x31,0x5D,0x25,0xFF,0x8A,0xE0,0x73,0x96,
1528 0x81,0xC8,0x83,0x79,0xC1,0x5A,0x04,0xF8,0x37,0x0D,0xA8,0x3D,
1529 0xAE,0x74,0xBC,0xDB,0xB6,0xA4,0x75,0xD9,0x71,0x8A,0xA0,0x17,
1530 0x9E,0x2D,0xC8,0xA8,0xDF,0x2C,0x5F,0x82,0x95,0xF8,0x92,0x9B,
1531 0xA7,0x33,0x5F,0x89,0x71,0xC8,0x2D,0x6B,0x18,0x86,0xC4,0x94,
1532 0x22,0xA5,0x52,0x8D,0xF6,0xF6,0xD2,0x37,0x92,0x0F,0xA5,0xCC,
1533 0xDB,0x7B,0x1D,0x3D,0xA1,0x31,0xB7,0x80,0x8F,0x0B,0x67,0x5E,
1534 0x36,0xA5,0x60,0x0C,0xF1,0x95,0x33,0x8B,
1535 };
1536 static unsigned char dh1024_g[]={
1537 0x02,
1538 };
1539
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02001540 BIGNUM *p;
1541 BIGNUM *g;
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001542 DH *dh = DH_new();
1543 if (dh) {
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02001544 p = BN_bin2bn(dh1024_p, sizeof dh1024_p, NULL);
1545 g = BN_bin2bn(dh1024_g, sizeof dh1024_g, NULL);
Remi Gacogned3a341a2015-05-29 16:26:17 +02001546
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02001547 if (!p || !g) {
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001548 DH_free(dh);
1549 dh = NULL;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02001550 } else {
1551 DH_set0_pqg(dh, p, NULL, g);
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001552 }
1553 }
1554 return dh;
1555}
1556
1557static DH *ssl_get_dh_2048(void)
1558{
Remi Gacogned3a341a2015-05-29 16:26:17 +02001559 static unsigned char dh2048_p[]={
1560 0xEC,0x86,0xF8,0x70,0xA0,0x33,0x16,0xEC,0x05,0x1A,0x73,0x59,
1561 0xCD,0x1F,0x8B,0xF8,0x29,0xE4,0xD2,0xCF,0x52,0xDD,0xC2,0x24,
1562 0x8D,0xB5,0x38,0x9A,0xFB,0x5C,0xA4,0xE4,0xB2,0xDA,0xCE,0x66,
1563 0x50,0x74,0xA6,0x85,0x4D,0x4B,0x1D,0x30,0xB8,0x2B,0xF3,0x10,
1564 0xE9,0xA7,0x2D,0x05,0x71,0xE7,0x81,0xDF,0x8B,0x59,0x52,0x3B,
1565 0x5F,0x43,0x0B,0x68,0xF1,0xDB,0x07,0xBE,0x08,0x6B,0x1B,0x23,
1566 0xEE,0x4D,0xCC,0x9E,0x0E,0x43,0xA0,0x1E,0xDF,0x43,0x8C,0xEC,
1567 0xBE,0xBE,0x90,0xB4,0x51,0x54,0xB9,0x2F,0x7B,0x64,0x76,0x4E,
1568 0x5D,0xD4,0x2E,0xAE,0xC2,0x9E,0xAE,0x51,0x43,0x59,0xC7,0x77,
1569 0x9C,0x50,0x3C,0x0E,0xED,0x73,0x04,0x5F,0xF1,0x4C,0x76,0x2A,
1570 0xD8,0xF8,0xCF,0xFC,0x34,0x40,0xD1,0xB4,0x42,0x61,0x84,0x66,
1571 0x42,0x39,0x04,0xF8,0x68,0xB2,0x62,0xD7,0x55,0xED,0x1B,0x74,
1572 0x75,0x91,0xE0,0xC5,0x69,0xC1,0x31,0x5C,0xDB,0x7B,0x44,0x2E,
1573 0xCE,0x84,0x58,0x0D,0x1E,0x66,0x0C,0xC8,0x44,0x9E,0xFD,0x40,
1574 0x08,0x67,0x5D,0xFB,0xA7,0x76,0x8F,0x00,0x11,0x87,0xE9,0x93,
1575 0xF9,0x7D,0xC4,0xBC,0x74,0x55,0x20,0xD4,0x4A,0x41,0x2F,0x43,
1576 0x42,0x1A,0xC1,0xF2,0x97,0x17,0x49,0x27,0x37,0x6B,0x2F,0x88,
1577 0x7E,0x1C,0xA0,0xA1,0x89,0x92,0x27,0xD9,0x56,0x5A,0x71,0xC1,
1578 0x56,0x37,0x7E,0x3A,0x9D,0x05,0xE7,0xEE,0x5D,0x8F,0x82,0x17,
1579 0xBC,0xE9,0xC2,0x93,0x30,0x82,0xF9,0xF4,0xC9,0xAE,0x49,0xDB,
1580 0xD0,0x54,0xB4,0xD9,0x75,0x4D,0xFA,0x06,0xB8,0xD6,0x38,0x41,
1581 0xB7,0x1F,0x77,0xF3,
1582 };
1583 static unsigned char dh2048_g[]={
1584 0x02,
1585 };
1586
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02001587 BIGNUM *p;
1588 BIGNUM *g;
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001589 DH *dh = DH_new();
1590 if (dh) {
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02001591 p = BN_bin2bn(dh2048_p, sizeof dh2048_p, NULL);
1592 g = BN_bin2bn(dh2048_g, sizeof dh2048_g, NULL);
Remi Gacogned3a341a2015-05-29 16:26:17 +02001593
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02001594 if (!p || !g) {
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001595 DH_free(dh);
1596 dh = NULL;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02001597 } else {
1598 DH_set0_pqg(dh, p, NULL, g);
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001599 }
1600 }
1601 return dh;
1602}
1603
1604static DH *ssl_get_dh_4096(void)
1605{
Remi Gacogned3a341a2015-05-29 16:26:17 +02001606 static unsigned char dh4096_p[]={
1607 0xDE,0x16,0x94,0xCD,0x99,0x58,0x07,0xF1,0xF7,0x32,0x96,0x11,
1608 0x04,0x82,0xD4,0x84,0x72,0x80,0x99,0x06,0xCA,0xF0,0xA3,0x68,
1609 0x07,0xCE,0x64,0x50,0xE7,0x74,0x45,0x20,0x80,0x5E,0x4D,0xAD,
1610 0xA5,0xB6,0xED,0xFA,0x80,0x6C,0x3B,0x35,0xC4,0x9A,0x14,0x6B,
1611 0x32,0xBB,0xFD,0x1F,0x17,0x8E,0xB7,0x1F,0xD6,0xFA,0x3F,0x7B,
1612 0xEE,0x16,0xA5,0x62,0x33,0x0D,0xED,0xBC,0x4E,0x58,0xE5,0x47,
1613 0x4D,0xE9,0xAB,0x8E,0x38,0xD3,0x6E,0x90,0x57,0xE3,0x22,0x15,
1614 0x33,0xBD,0xF6,0x43,0x45,0xB5,0x10,0x0A,0xBE,0x2C,0xB4,0x35,
1615 0xB8,0x53,0x8D,0xAD,0xFB,0xA7,0x1F,0x85,0x58,0x41,0x7A,0x79,
1616 0x20,0x68,0xB3,0xE1,0x3D,0x08,0x76,0xBF,0x86,0x0D,0x49,0xE3,
1617 0x82,0x71,0x8C,0xB4,0x8D,0x81,0x84,0xD4,0xE7,0xBE,0x91,0xDC,
1618 0x26,0x39,0x48,0x0F,0x35,0xC4,0xCA,0x65,0xE3,0x40,0x93,0x52,
1619 0x76,0x58,0x7D,0xDD,0x51,0x75,0xDC,0x69,0x61,0xBF,0x47,0x2C,
1620 0x16,0x68,0x2D,0xC9,0x29,0xD3,0xE6,0xC0,0x99,0x48,0xA0,0x9A,
1621 0xC8,0x78,0xC0,0x6D,0x81,0x67,0x12,0x61,0x3F,0x71,0xBA,0x41,
1622 0x1F,0x6C,0x89,0x44,0x03,0xBA,0x3B,0x39,0x60,0xAA,0x28,0x55,
1623 0x59,0xAE,0xB8,0xFA,0xCB,0x6F,0xA5,0x1A,0xF7,0x2B,0xDD,0x52,
1624 0x8A,0x8B,0xE2,0x71,0xA6,0x5E,0x7E,0xD8,0x2E,0x18,0xE0,0x66,
1625 0xDF,0xDD,0x22,0x21,0x99,0x52,0x73,0xA6,0x33,0x20,0x65,0x0E,
1626 0x53,0xE7,0x6B,0x9B,0xC5,0xA3,0x2F,0x97,0x65,0x76,0xD3,0x47,
1627 0x23,0x77,0x12,0xB6,0x11,0x7B,0x24,0xED,0xF1,0xEF,0xC0,0xE2,
1628 0xA3,0x7E,0x67,0x05,0x3E,0x96,0x4D,0x45,0xC2,0x18,0xD1,0x73,
1629 0x9E,0x07,0xF3,0x81,0x6E,0x52,0x63,0xF6,0x20,0x76,0xB9,0x13,
1630 0xD2,0x65,0x30,0x18,0x16,0x09,0x16,0x9E,0x8F,0xF1,0xD2,0x10,
1631 0x5A,0xD3,0xD4,0xAF,0x16,0x61,0xDA,0x55,0x2E,0x18,0x5E,0x14,
1632 0x08,0x54,0x2E,0x2A,0x25,0xA2,0x1A,0x9B,0x8B,0x32,0xA9,0xFD,
1633 0xC2,0x48,0x96,0xE1,0x80,0xCA,0xE9,0x22,0x17,0xBB,0xCE,0x3E,
1634 0x9E,0xED,0xC7,0xF1,0x1F,0xEC,0x17,0x21,0xDC,0x7B,0x82,0x48,
1635 0x8E,0xBB,0x4B,0x9D,0x5B,0x04,0x04,0xDA,0xDB,0x39,0xDF,0x01,
1636 0x40,0xC3,0xAA,0x26,0x23,0x89,0x75,0xC6,0x0B,0xD0,0xA2,0x60,
1637 0x6A,0xF1,0xCC,0x65,0x18,0x98,0x1B,0x52,0xD2,0x74,0x61,0xCC,
1638 0xBD,0x60,0xAE,0xA3,0xA0,0x66,0x6A,0x16,0x34,0x92,0x3F,0x41,
1639 0x40,0x31,0x29,0xC0,0x2C,0x63,0xB2,0x07,0x8D,0xEB,0x94,0xB8,
1640 0xE8,0x47,0x92,0x52,0x93,0x6A,0x1B,0x7E,0x1A,0x61,0xB3,0x1B,
1641 0xF0,0xD6,0x72,0x9B,0xF1,0xB0,0xAF,0xBF,0x3E,0x65,0xEF,0x23,
1642 0x1D,0x6F,0xFF,0x70,0xCD,0x8A,0x4C,0x8A,0xA0,0x72,0x9D,0xBE,
1643 0xD4,0xBB,0x24,0x47,0x4A,0x68,0xB5,0xF5,0xC6,0xD5,0x7A,0xCD,
1644 0xCA,0x06,0x41,0x07,0xAD,0xC2,0x1E,0xE6,0x54,0xA7,0xAD,0x03,
1645 0xD9,0x12,0xC1,0x9C,0x13,0xB1,0xC9,0x0A,0x43,0x8E,0x1E,0x08,
1646 0xCE,0x50,0x82,0x73,0x5F,0xA7,0x55,0x1D,0xD9,0x59,0xAC,0xB5,
1647 0xEA,0x02,0x7F,0x6C,0x5B,0x74,0x96,0x98,0x67,0x24,0xA3,0x0F,
1648 0x15,0xFC,0xA9,0x7D,0x3E,0x67,0xD1,0x70,0xF8,0x97,0xF3,0x67,
1649 0xC5,0x8C,0x88,0x44,0x08,0x02,0xC7,0x2B,
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001650 };
Remi Gacogned3a341a2015-05-29 16:26:17 +02001651 static unsigned char dh4096_g[]={
1652 0x02,
1653 };
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001654
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02001655 BIGNUM *p;
1656 BIGNUM *g;
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001657 DH *dh = DH_new();
1658 if (dh) {
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02001659 p = BN_bin2bn(dh4096_p, sizeof dh4096_p, NULL);
1660 g = BN_bin2bn(dh4096_g, sizeof dh4096_g, NULL);
Remi Gacogned3a341a2015-05-29 16:26:17 +02001661
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02001662 if (!p || !g) {
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001663 DH_free(dh);
1664 dh = NULL;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02001665 } else {
1666 DH_set0_pqg(dh, p, NULL, g);
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001667 }
1668 }
1669 return dh;
1670}
1671
1672/* Returns Diffie-Hellman parameters matching the private key length
Willy Tarreauef934602016-12-22 23:12:01 +01001673 but not exceeding global_ssl.default_dh_param */
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001674static DH *ssl_get_tmp_dh(SSL *ssl, int export, int keylen)
1675{
1676 DH *dh = NULL;
1677 EVP_PKEY *pkey = SSL_get_privatekey(ssl);
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02001678 int type;
1679
1680 type = pkey ? EVP_PKEY_base_id(pkey) : EVP_PKEY_NONE;
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001681
1682 /* The keylen supplied by OpenSSL can only be 512 or 1024.
1683 See ssl3_send_server_key_exchange() in ssl/s3_srvr.c
1684 */
1685 if (type == EVP_PKEY_RSA || type == EVP_PKEY_DSA) {
1686 keylen = EVP_PKEY_bits(pkey);
1687 }
1688
Willy Tarreauef934602016-12-22 23:12:01 +01001689 if (keylen > global_ssl.default_dh_param) {
1690 keylen = global_ssl.default_dh_param;
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001691 }
1692
Remi Gacogned3a341a2015-05-29 16:26:17 +02001693 if (keylen >= 4096) {
Remi Gacogne8de54152014-07-15 11:36:40 +02001694 dh = local_dh_4096;
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001695 }
1696 else if (keylen >= 2048) {
Remi Gacogne8de54152014-07-15 11:36:40 +02001697 dh = local_dh_2048;
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001698 }
1699 else {
Remi Gacogne8de54152014-07-15 11:36:40 +02001700 dh = local_dh_1024;
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001701 }
1702
1703 return dh;
1704}
1705
Remi Gacogne47783ef2015-05-29 15:53:22 +02001706static DH * ssl_sock_get_dh_from_file(const char *filename)
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001707{
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001708 DH *dh = NULL;
Remi Gacogne47783ef2015-05-29 15:53:22 +02001709 BIO *in = BIO_new(BIO_s_file());
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001710
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001711 if (in == NULL)
1712 goto end;
1713
Remi Gacogne47783ef2015-05-29 15:53:22 +02001714 if (BIO_read_filename(in, filename) <= 0)
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001715 goto end;
1716
Remi Gacogne47783ef2015-05-29 15:53:22 +02001717 dh = PEM_read_bio_DHparams(in, NULL, NULL, NULL);
1718
1719end:
1720 if (in)
1721 BIO_free(in);
1722
1723 return dh;
1724}
1725
1726int ssl_sock_load_global_dh_param_from_file(const char *filename)
1727{
1728 global_dh = ssl_sock_get_dh_from_file(filename);
1729
1730 if (global_dh) {
1731 return 0;
1732 }
1733
1734 return -1;
1735}
1736
1737/* Loads Diffie-Hellman parameter from a file. Returns 1 if loaded, else -1
1738 if an error occured, and 0 if parameter not found. */
1739int ssl_sock_load_dh_params(SSL_CTX *ctx, const char *file)
1740{
1741 int ret = -1;
1742 DH *dh = ssl_sock_get_dh_from_file(file);
1743
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001744 if (dh) {
1745 ret = 1;
1746 SSL_CTX_set_tmp_dh(ctx, dh);
Remi Gacogne4f902b82015-05-28 16:23:00 +02001747
1748 if (ssl_dh_ptr_index >= 0) {
1749 /* store a pointer to the DH params to avoid complaining about
1750 ssl-default-dh-param not being set for this SSL_CTX */
1751 SSL_CTX_set_ex_data(ctx, ssl_dh_ptr_index, dh);
1752 }
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001753 }
Remi Gacogne47783ef2015-05-29 15:53:22 +02001754 else if (global_dh) {
1755 SSL_CTX_set_tmp_dh(ctx, global_dh);
1756 ret = 0; /* DH params not found */
1757 }
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001758 else {
Emeric Brun41fdb3c2013-04-26 11:05:44 +02001759 /* Clear openssl global errors stack */
1760 ERR_clear_error();
1761
Willy Tarreauef934602016-12-22 23:12:01 +01001762 if (global_ssl.default_dh_param <= 1024) {
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001763 /* we are limited to DH parameter of 1024 bits anyway */
Remi Gacognec7e12632016-07-02 16:26:10 +02001764 if (local_dh_1024 == NULL)
1765 local_dh_1024 = ssl_get_dh_1024();
1766
Remi Gacogne8de54152014-07-15 11:36:40 +02001767 if (local_dh_1024 == NULL)
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001768 goto end;
Willy Tarreau6e774b42014-04-25 21:35:23 +02001769
Remi Gacogne8de54152014-07-15 11:36:40 +02001770 SSL_CTX_set_tmp_dh(ctx, local_dh_1024);
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001771 }
1772 else {
1773 SSL_CTX_set_tmp_dh_callback(ctx, ssl_get_tmp_dh);
1774 }
Willy Tarreau6e774b42014-04-25 21:35:23 +02001775
Emeric Brun41fdb3c2013-04-26 11:05:44 +02001776 ret = 0; /* DH params not found */
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001777 }
Emeric Brun644cde02012-12-14 11:21:13 +01001778
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001779end:
1780 if (dh)
1781 DH_free(dh);
1782
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001783 return ret;
1784}
1785#endif
1786
Emmanuel Hocdet98263292016-12-29 18:26:15 +01001787static int ssl_sock_add_cert_sni(SSL_CTX *ctx, struct bind_conf *s,
1788 struct ssl_bind_conf *conf, char *name, int order)
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001789{
1790 struct sni_ctx *sc;
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001791 int wild = 0, neg = 0;
Thierry FOURNIER / OZON.IO07c3d782016-10-06 10:56:48 +02001792 struct ebmb_node *node;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001793
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001794 if (*name == '!') {
1795 neg = 1;
1796 name++;
1797 }
1798 if (*name == '*') {
1799 wild = 1;
1800 name++;
1801 }
1802 /* !* filter is a nop */
1803 if (neg && wild)
1804 return order;
1805 if (*name) {
1806 int j, len;
1807 len = strlen(name);
Thierry FOURNIER / OZON.IO07c3d782016-10-06 10:56:48 +02001808 for (j = 0; j < len && j < trash.size; j++)
1809 trash.str[j] = tolower(name[j]);
1810 if (j >= trash.size)
1811 return order;
1812 trash.str[j] = 0;
1813
1814 /* Check for duplicates. */
1815 if (wild)
1816 node = ebst_lookup(&s->sni_w_ctx, trash.str);
1817 else
1818 node = ebst_lookup(&s->sni_ctx, trash.str);
1819 for (; node; node = ebmb_next_dup(node)) {
1820 sc = ebmb_entry(node, struct sni_ctx, name);
Emmanuel Hocdet98263292016-12-29 18:26:15 +01001821 if (sc->ctx == ctx && sc->conf == conf && sc->neg == neg)
Thierry FOURNIER / OZON.IO07c3d782016-10-06 10:56:48 +02001822 return order;
1823 }
1824
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001825 sc = malloc(sizeof(struct sni_ctx) + len + 1);
Thierry FOURNIER / OZON.IO7a3bd3b2016-10-06 10:35:29 +02001826 if (!sc)
1827 return order;
Thierry FOURNIER / OZON.IO07c3d782016-10-06 10:56:48 +02001828 memcpy(sc->name.key, trash.str, len + 1);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001829 sc->ctx = ctx;
Emmanuel Hocdet98263292016-12-29 18:26:15 +01001830 sc->conf = conf;
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001831 sc->order = order++;
1832 sc->neg = neg;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001833 if (wild)
1834 ebst_insert(&s->sni_w_ctx, &sc->name);
1835 else
1836 ebst_insert(&s->sni_ctx, &sc->name);
1837 }
1838 return order;
1839}
1840
yanbzhu488a4d22015-12-01 15:16:07 -05001841
1842/* The following code is used for loading multiple crt files into
1843 * SSL_CTX's based on CN/SAN
1844 */
Luca Pizzamiglio578b1692016-12-12 10:56:56 +01001845#if OPENSSL_VERSION_NUMBER >= 0x1000200fL && !defined(LIBRESSL_VERSION_NUMBER)
yanbzhu488a4d22015-12-01 15:16:07 -05001846/* This is used to preload the certifcate, private key
1847 * and Cert Chain of a file passed in via the crt
1848 * argument
1849 *
1850 * This way, we do not have to read the file multiple times
1851 */
1852struct cert_key_and_chain {
1853 X509 *cert;
1854 EVP_PKEY *key;
1855 unsigned int num_chain_certs;
1856 /* This is an array of X509 pointers */
1857 X509 **chain_certs;
1858};
1859
yanbzhu08ce6ab2015-12-02 13:01:29 -05001860#define SSL_SOCK_POSSIBLE_KT_COMBOS (1<<(SSL_SOCK_NUM_KEYTYPES))
1861
1862struct key_combo_ctx {
1863 SSL_CTX *ctx;
1864 int order;
1865};
1866
1867/* Map used for processing multiple keypairs for a single purpose
1868 *
1869 * This maps CN/SNI name to certificate type
1870 */
1871struct sni_keytype {
1872 int keytypes; /* BITMASK for keytypes */
1873 struct ebmb_node name; /* node holding the servername value */
1874};
1875
1876
yanbzhu488a4d22015-12-01 15:16:07 -05001877/* Frees the contents of a cert_key_and_chain
1878 */
1879static void ssl_sock_free_cert_key_and_chain_contents(struct cert_key_and_chain *ckch)
1880{
1881 int i;
1882
1883 if (!ckch)
1884 return;
1885
1886 /* Free the certificate and set pointer to NULL */
1887 if (ckch->cert)
1888 X509_free(ckch->cert);
1889 ckch->cert = NULL;
1890
1891 /* Free the key and set pointer to NULL */
1892 if (ckch->key)
1893 EVP_PKEY_free(ckch->key);
1894 ckch->key = NULL;
1895
1896 /* Free each certificate in the chain */
1897 for (i = 0; i < ckch->num_chain_certs; i++) {
1898 if (ckch->chain_certs[i])
1899 X509_free(ckch->chain_certs[i]);
1900 }
1901
1902 /* Free the chain obj itself and set to NULL */
1903 if (ckch->num_chain_certs > 0) {
1904 free(ckch->chain_certs);
1905 ckch->num_chain_certs = 0;
1906 ckch->chain_certs = NULL;
1907 }
1908
1909}
1910
1911/* checks if a key and cert exists in the ckch
1912 */
1913static int ssl_sock_is_ckch_valid(struct cert_key_and_chain *ckch)
1914{
1915 return (ckch->cert != NULL && ckch->key != NULL);
1916}
1917
1918
1919/* Loads the contents of a crt file (path) into a cert_key_and_chain
1920 * This allows us to carry the contents of the file without having to
1921 * read the file multiple times.
1922 *
1923 * returns:
1924 * 0 on Success
1925 * 1 on SSL Failure
1926 * 2 on file not found
1927 */
1928static int ssl_sock_load_crt_file_into_ckch(const char *path, struct cert_key_and_chain *ckch, char **err)
1929{
1930
1931 BIO *in;
1932 X509 *ca = NULL;
1933 int ret = 1;
1934
1935 ssl_sock_free_cert_key_and_chain_contents(ckch);
1936
1937 in = BIO_new(BIO_s_file());
1938 if (in == NULL)
1939 goto end;
1940
1941 if (BIO_read_filename(in, path) <= 0)
1942 goto end;
1943
yanbzhu488a4d22015-12-01 15:16:07 -05001944 /* Read Private Key */
1945 ckch->key = PEM_read_bio_PrivateKey(in, NULL, NULL, NULL);
1946 if (ckch->key == NULL) {
1947 memprintf(err, "%sunable to load private key from file '%s'.\n",
1948 err && *err ? *err : "", path);
1949 goto end;
1950 }
1951
Willy Tarreaubb137a82016-04-06 19:02:38 +02001952 /* Seek back to beginning of file */
Thierry FOURNIER / OZON.IOd44ea3f2016-10-14 00:49:21 +02001953 if (BIO_reset(in) == -1) {
1954 memprintf(err, "%san error occurred while reading the file '%s'.\n",
1955 err && *err ? *err : "", path);
1956 goto end;
1957 }
Willy Tarreaubb137a82016-04-06 19:02:38 +02001958
1959 /* Read Certificate */
1960 ckch->cert = PEM_read_bio_X509_AUX(in, NULL, NULL, NULL);
1961 if (ckch->cert == NULL) {
1962 memprintf(err, "%sunable to load certificate from file '%s'.\n",
1963 err && *err ? *err : "", path);
1964 goto end;
1965 }
1966
yanbzhu488a4d22015-12-01 15:16:07 -05001967 /* Read Certificate Chain */
1968 while ((ca = PEM_read_bio_X509(in, NULL, NULL, NULL))) {
1969 /* Grow the chain certs */
1970 ckch->num_chain_certs++;
1971 ckch->chain_certs = realloc(ckch->chain_certs, (ckch->num_chain_certs * sizeof(X509 *)));
1972
1973 /* use - 1 here since we just incremented it above */
1974 ckch->chain_certs[ckch->num_chain_certs - 1] = ca;
1975 }
1976 ret = ERR_get_error();
1977 if (ret && (ERR_GET_LIB(ret) != ERR_LIB_PEM && ERR_GET_REASON(ret) != PEM_R_NO_START_LINE)) {
1978 memprintf(err, "%sunable to load certificate chain from file '%s'.\n",
1979 err && *err ? *err : "", path);
1980 ret = 1;
1981 goto end;
1982 }
1983
1984 ret = 0;
1985
1986end:
1987
1988 ERR_clear_error();
1989 if (in)
1990 BIO_free(in);
1991
1992 /* Something went wrong in one of the reads */
1993 if (ret != 0)
1994 ssl_sock_free_cert_key_and_chain_contents(ckch);
1995
1996 return ret;
1997}
1998
1999/* Loads the info in ckch into ctx
2000 * Currently, this does not process any information about ocsp, dhparams or
2001 * sctl
2002 * Returns
2003 * 0 on success
2004 * 1 on failure
2005 */
2006static int ssl_sock_put_ckch_into_ctx(const char *path, const struct cert_key_and_chain *ckch, SSL_CTX *ctx, char **err)
2007{
2008 int i = 0;
2009
2010 if (SSL_CTX_use_PrivateKey(ctx, ckch->key) <= 0) {
2011 memprintf(err, "%sunable to load SSL private key into SSL Context '%s'.\n",
2012 err && *err ? *err : "", path);
2013 return 1;
2014 }
2015
2016 if (!SSL_CTX_use_certificate(ctx, ckch->cert)) {
2017 memprintf(err, "%sunable to load SSL certificate into SSL Context '%s'.\n",
2018 err && *err ? *err : "", path);
2019 return 1;
2020 }
2021
yanbzhu488a4d22015-12-01 15:16:07 -05002022 /* Load all certs in the ckch into the ctx_chain for the ssl_ctx */
2023 for (i = 0; i < ckch->num_chain_certs; i++) {
2024 if (!SSL_CTX_add1_chain_cert(ctx, ckch->chain_certs[i])) {
yanbzhu08ce6ab2015-12-02 13:01:29 -05002025 memprintf(err, "%sunable to load chain certificate #%d into SSL Context '%s'. Make sure you are linking against Openssl >= 1.0.2.\n",
2026 err && *err ? *err : "", (i+1), path);
yanbzhu488a4d22015-12-01 15:16:07 -05002027 return 1;
2028 }
2029 }
2030
2031 if (SSL_CTX_check_private_key(ctx) <= 0) {
2032 memprintf(err, "%sinconsistencies between private key and certificate loaded from PEM file '%s'.\n",
2033 err && *err ? *err : "", path);
2034 return 1;
2035 }
2036
2037 return 0;
2038}
2039
yanbzhu08ce6ab2015-12-02 13:01:29 -05002040
2041static void ssl_sock_populate_sni_keytypes_hplr(const char *str, struct eb_root *sni_keytypes, int key_index)
2042{
2043 struct sni_keytype *s_kt = NULL;
2044 struct ebmb_node *node;
2045 int i;
2046
2047 for (i = 0; i < trash.size; i++) {
2048 if (!str[i])
2049 break;
2050 trash.str[i] = tolower(str[i]);
2051 }
2052 trash.str[i] = 0;
2053 node = ebst_lookup(sni_keytypes, trash.str);
2054 if (!node) {
2055 /* CN not found in tree */
2056 s_kt = malloc(sizeof(struct sni_keytype) + i + 1);
2057 /* Using memcpy here instead of strncpy.
2058 * strncpy will cause sig_abrt errors under certain versions of gcc with -O2
2059 * See: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=60792
2060 */
2061 memcpy(s_kt->name.key, trash.str, i+1);
2062 s_kt->keytypes = 0;
2063 ebst_insert(sni_keytypes, &s_kt->name);
2064 } else {
2065 /* CN found in tree */
2066 s_kt = container_of(node, struct sni_keytype, name);
2067 }
2068
2069 /* Mark that this CN has the keytype of key_index via keytypes mask */
2070 s_kt->keytypes |= 1<<key_index;
2071
2072}
2073
2074
2075/* Given a path that does not exist, try to check for path.rsa, path.dsa and path.ecdsa files.
2076 * If any are found, group these files into a set of SSL_CTX*
2077 * based on shared and unique CN and SAN entries. Add these SSL_CTX* to the SNI tree.
2078 *
2079 * This will allow the user to explictly group multiple cert/keys for a single purpose
2080 *
2081 * Returns
2082 * 0 on success
2083 * 1 on failure
2084 */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01002085static int ssl_sock_load_multi_cert(const char *path, struct bind_conf *bind_conf, struct ssl_bind_conf *ssl_conf,
2086 char **sni_filter, int fcount, char **err)
yanbzhu08ce6ab2015-12-02 13:01:29 -05002087{
2088 char fp[MAXPATHLEN+1] = {0};
2089 int n = 0;
2090 int i = 0;
2091 struct cert_key_and_chain certs_and_keys[SSL_SOCK_NUM_KEYTYPES] = { {0} };
2092 struct eb_root sni_keytypes_map = { {0} };
2093 struct ebmb_node *node;
2094 struct ebmb_node *next;
2095 /* Array of SSL_CTX pointers corresponding to each possible combo
2096 * of keytypes
2097 */
2098 struct key_combo_ctx key_combos[SSL_SOCK_POSSIBLE_KT_COMBOS] = { {0} };
2099 int rv = 0;
2100 X509_NAME *xname = NULL;
2101 char *str = NULL;
2102#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
2103 STACK_OF(GENERAL_NAME) *names = NULL;
2104#endif
2105
2106 /* Load all possible certs and keys */
2107 for (n = 0; n < SSL_SOCK_NUM_KEYTYPES; n++) {
2108 struct stat buf;
2109
2110 snprintf(fp, sizeof(fp), "%s.%s", path, SSL_SOCK_KEYTYPE_NAMES[n]);
2111 if (stat(fp, &buf) == 0) {
2112 if (ssl_sock_load_crt_file_into_ckch(fp, &certs_and_keys[n], err) == 1) {
2113 rv = 1;
2114 goto end;
2115 }
2116 }
2117 }
2118
2119 /* Process each ckch and update keytypes for each CN/SAN
2120 * for example, if CN/SAN www.a.com is associated with
2121 * certs with keytype 0 and 2, then at the end of the loop,
2122 * www.a.com will have:
2123 * keyindex = 0 | 1 | 4 = 5
2124 */
2125 for (n = 0; n < SSL_SOCK_NUM_KEYTYPES; n++) {
2126
2127 if (!ssl_sock_is_ckch_valid(&certs_and_keys[n]))
2128 continue;
2129
Emmanuel Hocdetd294aea2016-05-13 11:14:06 +02002130 if (fcount) {
Willy Tarreau24b892f2016-06-20 23:01:57 +02002131 for (i = 0; i < fcount; i++)
Emmanuel Hocdetd294aea2016-05-13 11:14:06 +02002132 ssl_sock_populate_sni_keytypes_hplr(sni_filter[i], &sni_keytypes_map, n);
2133 } else {
2134 /* A lot of the following code is OpenSSL boilerplate for processing CN's and SAN's,
2135 * so the line that contains logic is marked via comments
2136 */
2137 xname = X509_get_subject_name(certs_and_keys[n].cert);
2138 i = -1;
2139 while ((i = X509_NAME_get_index_by_NID(xname, NID_commonName, i)) != -1) {
2140 X509_NAME_ENTRY *entry = X509_NAME_get_entry(xname, i);
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02002141 ASN1_STRING *value;
2142 value = X509_NAME_ENTRY_get_data(entry);
2143 if (ASN1_STRING_to_UTF8((unsigned char **)&str, value) >= 0) {
Emmanuel Hocdetd294aea2016-05-13 11:14:06 +02002144 /* Important line is here */
2145 ssl_sock_populate_sni_keytypes_hplr(str, &sni_keytypes_map, n);
yanbzhu08ce6ab2015-12-02 13:01:29 -05002146
Emmanuel Hocdetd294aea2016-05-13 11:14:06 +02002147 OPENSSL_free(str);
2148 str = NULL;
2149 }
yanbzhu08ce6ab2015-12-02 13:01:29 -05002150 }
yanbzhu08ce6ab2015-12-02 13:01:29 -05002151
Emmanuel Hocdetd294aea2016-05-13 11:14:06 +02002152 /* Do the above logic for each SAN */
yanbzhu08ce6ab2015-12-02 13:01:29 -05002153#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Emmanuel Hocdetd294aea2016-05-13 11:14:06 +02002154 names = X509_get_ext_d2i(certs_and_keys[n].cert, NID_subject_alt_name, NULL, NULL);
2155 if (names) {
2156 for (i = 0; i < sk_GENERAL_NAME_num(names); i++) {
2157 GENERAL_NAME *name = sk_GENERAL_NAME_value(names, i);
yanbzhu08ce6ab2015-12-02 13:01:29 -05002158
Emmanuel Hocdetd294aea2016-05-13 11:14:06 +02002159 if (name->type == GEN_DNS) {
2160 if (ASN1_STRING_to_UTF8((unsigned char **)&str, name->d.dNSName) >= 0) {
2161 /* Important line is here */
2162 ssl_sock_populate_sni_keytypes_hplr(str, &sni_keytypes_map, n);
yanbzhu08ce6ab2015-12-02 13:01:29 -05002163
Emmanuel Hocdetd294aea2016-05-13 11:14:06 +02002164 OPENSSL_free(str);
2165 str = NULL;
2166 }
yanbzhu08ce6ab2015-12-02 13:01:29 -05002167 }
2168 }
2169 }
2170 }
2171#endif /* SSL_CTRL_SET_TLSEXT_HOSTNAME */
2172 }
2173
2174 /* If no files found, return error */
2175 if (eb_is_empty(&sni_keytypes_map)) {
2176 memprintf(err, "%sunable to load SSL certificate file '%s' file does not exist.\n",
2177 err && *err ? *err : "", path);
2178 rv = 1;
2179 goto end;
2180 }
2181
2182 /* We now have a map of CN/SAN to keytypes that are loaded in
2183 * Iterate through the map to create the SSL_CTX's (if needed)
2184 * and add each CTX to the SNI tree
2185 *
2186 * Some math here:
2187 * There are 2^n - 1 possibile combinations, each unique
2188 * combination is denoted by the key in the map. Each key
2189 * has a value between 1 and 2^n - 1. Conveniently, the array
2190 * of SSL_CTX* is sized 2^n. So, we can simply use the i'th
2191 * entry in the array to correspond to the unique combo (key)
2192 * associated with i. This unique key combo (i) will be associated
2193 * with combos[i-1]
2194 */
2195
2196 node = ebmb_first(&sni_keytypes_map);
2197 while (node) {
2198 SSL_CTX *cur_ctx;
Bertrand Jacquin33423092016-11-13 16:37:13 +00002199 char cur_file[MAXPATHLEN+1];
yanbzhu08ce6ab2015-12-02 13:01:29 -05002200
2201 str = (char *)container_of(node, struct sni_keytype, name)->name.key;
2202 i = container_of(node, struct sni_keytype, name)->keytypes;
2203 cur_ctx = key_combos[i-1].ctx;
2204
2205 if (cur_ctx == NULL) {
2206 /* need to create SSL_CTX */
2207 cur_ctx = SSL_CTX_new(SSLv23_server_method());
2208 if (cur_ctx == NULL) {
2209 memprintf(err, "%sunable to allocate SSL context.\n",
2210 err && *err ? *err : "");
2211 rv = 1;
2212 goto end;
2213 }
2214
yanbzhube2774d2015-12-10 15:07:30 -05002215 /* Load all required certs/keys/chains/OCSPs info into SSL_CTX */
yanbzhu08ce6ab2015-12-02 13:01:29 -05002216 for (n = 0; n < SSL_SOCK_NUM_KEYTYPES; n++) {
2217 if (i & (1<<n)) {
2218 /* Key combo contains ckch[n] */
Bertrand Jacquin33423092016-11-13 16:37:13 +00002219 snprintf(cur_file, MAXPATHLEN+1, "%s.%s", path, SSL_SOCK_KEYTYPE_NAMES[n]);
2220 if (ssl_sock_put_ckch_into_ctx(cur_file, &certs_and_keys[n], cur_ctx, err) != 0) {
yanbzhu08ce6ab2015-12-02 13:01:29 -05002221 SSL_CTX_free(cur_ctx);
2222 rv = 1;
2223 goto end;
2224 }
yanbzhube2774d2015-12-10 15:07:30 -05002225
2226#if (defined SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB && !defined OPENSSL_NO_OCSP)
2227 /* Load OCSP Info into context */
Bertrand Jacquin33423092016-11-13 16:37:13 +00002228 if (ssl_sock_load_ocsp(cur_ctx, cur_file) < 0) {
yanbzhube2774d2015-12-10 15:07:30 -05002229 if (err)
2230 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 +00002231 *err ? *err : "", cur_file);
yanbzhube2774d2015-12-10 15:07:30 -05002232 SSL_CTX_free(cur_ctx);
2233 rv = 1;
2234 goto end;
2235 }
2236#endif
yanbzhu08ce6ab2015-12-02 13:01:29 -05002237 }
2238 }
2239
2240 /* Load DH params into the ctx to support DHE keys */
2241#ifndef OPENSSL_NO_DH
2242 if (ssl_dh_ptr_index >= 0)
2243 SSL_CTX_set_ex_data(cur_ctx, ssl_dh_ptr_index, NULL);
2244
2245 rv = ssl_sock_load_dh_params(cur_ctx, NULL);
2246 if (rv < 0) {
2247 if (err)
2248 memprintf(err, "%sunable to load DH parameters from file '%s'.\n",
2249 *err ? *err : "", path);
2250 rv = 1;
2251 goto end;
2252 }
2253#endif
2254
2255 /* Update key_combos */
2256 key_combos[i-1].ctx = cur_ctx;
2257 }
2258
2259 /* Update SNI Tree */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01002260 key_combos[i-1].order = ssl_sock_add_cert_sni(cur_ctx, bind_conf, ssl_conf, str, key_combos[i-1].order);
yanbzhu08ce6ab2015-12-02 13:01:29 -05002261 node = ebmb_next(node);
2262 }
2263
2264
2265 /* Mark a default context if none exists, using the ctx that has the most shared keys */
2266 if (!bind_conf->default_ctx) {
2267 for (i = SSL_SOCK_POSSIBLE_KT_COMBOS - 1; i >= 0; i--) {
2268 if (key_combos[i].ctx) {
2269 bind_conf->default_ctx = key_combos[i].ctx;
Emmanuel Hocdet98263292016-12-29 18:26:15 +01002270 bind_conf->default_ssl_conf = ssl_conf;
yanbzhu08ce6ab2015-12-02 13:01:29 -05002271 break;
2272 }
2273 }
2274 }
2275
2276end:
2277
2278 if (names)
2279 sk_GENERAL_NAME_pop_free(names, GENERAL_NAME_free);
2280
2281 for (n = 0; n < SSL_SOCK_NUM_KEYTYPES; n++)
2282 ssl_sock_free_cert_key_and_chain_contents(&certs_and_keys[n]);
2283
2284 node = ebmb_first(&sni_keytypes_map);
2285 while (node) {
2286 next = ebmb_next(node);
2287 ebmb_delete(node);
2288 node = next;
2289 }
2290
2291 return rv;
2292}
2293#else
2294/* This is a dummy, that just logs an error and returns error */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01002295static int ssl_sock_load_multi_cert(const char *path, struct bind_conf *bind_conf, struct ssl_bind_conf *ssl_conf,
2296 char **sni_filter, int fcount, char **err)
yanbzhu08ce6ab2015-12-02 13:01:29 -05002297{
2298 memprintf(err, "%sunable to stat SSL certificate from file '%s' : %s.\n",
2299 err && *err ? *err : "", path, strerror(errno));
2300 return 1;
2301}
2302
yanbzhu488a4d22015-12-01 15:16:07 -05002303#endif /* #if OPENSSL_VERSION_NUMBER >= 0x1000200fL: Support for loading multiple certs into a single SSL_CTX */
2304
Emeric Brunfc0421f2012-09-07 17:30:07 +02002305/* Loads a certificate key and CA chain from a file. Returns 0 on error, -1 if
2306 * an early error happens and the caller must call SSL_CTX_free() by itelf.
2307 */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01002308static int ssl_sock_load_cert_chain_file(SSL_CTX *ctx, const char *file, struct bind_conf *s,
2309 struct ssl_bind_conf *ssl_conf, char **sni_filter, int fcount)
Emeric Brunfc0421f2012-09-07 17:30:07 +02002310{
2311 BIO *in;
2312 X509 *x = NULL, *ca;
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02002313 int i, err;
Emeric Brunfc0421f2012-09-07 17:30:07 +02002314 int ret = -1;
2315 int order = 0;
2316 X509_NAME *xname;
2317 char *str;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02002318 pem_password_cb *passwd_cb;
2319 void *passwd_cb_userdata;
2320
Emeric Brunfc0421f2012-09-07 17:30:07 +02002321#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
2322 STACK_OF(GENERAL_NAME) *names;
2323#endif
2324
2325 in = BIO_new(BIO_s_file());
2326 if (in == NULL)
2327 goto end;
2328
2329 if (BIO_read_filename(in, file) <= 0)
2330 goto end;
2331
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02002332
2333 passwd_cb = SSL_CTX_get_default_passwd_cb(ctx);
2334 passwd_cb_userdata = SSL_CTX_get_default_passwd_cb_userdata(ctx);
2335
2336 x = PEM_read_bio_X509_AUX(in, NULL, passwd_cb, passwd_cb_userdata);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002337 if (x == NULL)
2338 goto end;
2339
Emeric Brun50bcecc2013-04-22 13:05:23 +02002340 if (fcount) {
2341 while (fcount--)
Emmanuel Hocdet98263292016-12-29 18:26:15 +01002342 order = ssl_sock_add_cert_sni(ctx, s, ssl_conf, sni_filter[fcount], order);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002343 }
2344 else {
Emeric Brunfc0421f2012-09-07 17:30:07 +02002345#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002346 names = X509_get_ext_d2i(x, NID_subject_alt_name, NULL, NULL);
2347 if (names) {
2348 for (i = 0; i < sk_GENERAL_NAME_num(names); i++) {
2349 GENERAL_NAME *name = sk_GENERAL_NAME_value(names, i);
2350 if (name->type == GEN_DNS) {
2351 if (ASN1_STRING_to_UTF8((unsigned char **)&str, name->d.dNSName) >= 0) {
Emmanuel Hocdet98263292016-12-29 18:26:15 +01002352 order = ssl_sock_add_cert_sni(ctx, s, ssl_conf, str, order);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002353 OPENSSL_free(str);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002354 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02002355 }
2356 }
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002357 sk_GENERAL_NAME_pop_free(names, GENERAL_NAME_free);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002358 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02002359#endif /* SSL_CTRL_SET_TLSEXT_HOSTNAME */
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002360 xname = X509_get_subject_name(x);
2361 i = -1;
2362 while ((i = X509_NAME_get_index_by_NID(xname, NID_commonName, i)) != -1) {
2363 X509_NAME_ENTRY *entry = X509_NAME_get_entry(xname, i);
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02002364 ASN1_STRING *value;
2365
2366 value = X509_NAME_ENTRY_get_data(entry);
2367 if (ASN1_STRING_to_UTF8((unsigned char **)&str, value) >= 0) {
Emmanuel Hocdet98263292016-12-29 18:26:15 +01002368 order = ssl_sock_add_cert_sni(ctx, s, ssl_conf, str, order);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002369 OPENSSL_free(str);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002370 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02002371 }
2372 }
2373
2374 ret = 0; /* the caller must not free the SSL_CTX argument anymore */
2375 if (!SSL_CTX_use_certificate(ctx, x))
2376 goto end;
2377
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02002378#ifdef SSL_CTX_clear_extra_chain_certs
2379 SSL_CTX_clear_extra_chain_certs(ctx);
2380#else
Emeric Brunfc0421f2012-09-07 17:30:07 +02002381 if (ctx->extra_certs != NULL) {
2382 sk_X509_pop_free(ctx->extra_certs, X509_free);
2383 ctx->extra_certs = NULL;
2384 }
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02002385#endif
Emeric Brunfc0421f2012-09-07 17:30:07 +02002386
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02002387 while ((ca = PEM_read_bio_X509(in, NULL, passwd_cb, passwd_cb_userdata))) {
Emeric Brunfc0421f2012-09-07 17:30:07 +02002388 if (!SSL_CTX_add_extra_chain_cert(ctx, ca)) {
2389 X509_free(ca);
2390 goto end;
2391 }
2392 }
2393
2394 err = ERR_get_error();
2395 if (!err || (ERR_GET_LIB(err) == ERR_LIB_PEM && ERR_GET_REASON(err) == PEM_R_NO_START_LINE)) {
2396 /* we successfully reached the last cert in the file */
2397 ret = 1;
2398 }
2399 ERR_clear_error();
2400
2401end:
2402 if (x)
2403 X509_free(x);
2404
2405 if (in)
2406 BIO_free(in);
2407
2408 return ret;
2409}
2410
Emmanuel Hocdet98263292016-12-29 18:26:15 +01002411static int ssl_sock_load_cert_file(const char *path, struct bind_conf *bind_conf, struct ssl_bind_conf *ssl_conf,
2412 char **sni_filter, int fcount, char **err)
Emeric Brunfc0421f2012-09-07 17:30:07 +02002413{
2414 int ret;
2415 SSL_CTX *ctx;
2416
2417 ctx = SSL_CTX_new(SSLv23_server_method());
2418 if (!ctx) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02002419 memprintf(err, "%sunable to allocate SSL context for cert '%s'.\n",
2420 err && *err ? *err : "", path);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002421 return 1;
2422 }
2423
2424 if (SSL_CTX_use_PrivateKey_file(ctx, path, SSL_FILETYPE_PEM) <= 0) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02002425 memprintf(err, "%sunable to load SSL private key from PEM file '%s'.\n",
2426 err && *err ? *err : "", path);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002427 SSL_CTX_free(ctx);
2428 return 1;
2429 }
2430
Emmanuel Hocdet98263292016-12-29 18:26:15 +01002431 ret = ssl_sock_load_cert_chain_file(ctx, path, bind_conf, ssl_conf, sni_filter, fcount);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002432 if (ret <= 0) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02002433 memprintf(err, "%sunable to load SSL certificate from PEM file '%s'.\n",
2434 err && *err ? *err : "", path);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002435 if (ret < 0) /* serious error, must do that ourselves */
2436 SSL_CTX_free(ctx);
2437 return 1;
2438 }
Emeric Brun61694ab2012-10-26 13:35:33 +02002439
2440 if (SSL_CTX_check_private_key(ctx) <= 0) {
2441 memprintf(err, "%sinconsistencies between private key and certificate loaded from PEM file '%s'.\n",
2442 err && *err ? *err : "", path);
2443 return 1;
2444 }
2445
Emeric Brunfc0421f2012-09-07 17:30:07 +02002446 /* we must not free the SSL_CTX anymore below, since it's already in
2447 * the tree, so it will be discovered and cleaned in time.
2448 */
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02002449#ifndef OPENSSL_NO_DH
Remi Gacogne4f902b82015-05-28 16:23:00 +02002450 /* store a NULL pointer to indicate we have not yet loaded
2451 a custom DH param file */
2452 if (ssl_dh_ptr_index >= 0) {
2453 SSL_CTX_set_ex_data(ctx, ssl_dh_ptr_index, NULL);
2454 }
2455
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02002456 ret = ssl_sock_load_dh_params(ctx, path);
2457 if (ret < 0) {
2458 if (err)
2459 memprintf(err, "%sunable to load DH parameters from file '%s'.\n",
2460 *err ? *err : "", path);
2461 return 1;
2462 }
2463#endif
2464
Lukas Tribuse4e30f72014-12-09 16:32:51 +01002465#if (defined SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB && !defined OPENSSL_NO_OCSP)
Emeric Brun4147b2e2014-06-16 18:36:30 +02002466 ret = ssl_sock_load_ocsp(ctx, path);
2467 if (ret < 0) {
2468 if (err)
2469 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",
2470 *err ? *err : "", path);
2471 return 1;
2472 }
2473#endif
2474
Daniel Jakots54ffb912015-11-06 20:02:41 +01002475#if (OPENSSL_VERSION_NUMBER >= 0x1000200fL && !defined OPENSSL_NO_TLSEXT && !defined OPENSSL_IS_BORINGSSL && !defined LIBRESSL_VERSION_NUMBER)
Janusz Dziemidowicz2c701b52015-03-07 23:03:59 +01002476 if (sctl_ex_index >= 0) {
2477 ret = ssl_sock_load_sctl(ctx, path);
2478 if (ret < 0) {
2479 if (err)
2480 memprintf(err, "%s '%s.sctl' is present but cannot be read or parsed'.\n",
2481 *err ? *err : "", path);
2482 return 1;
2483 }
2484 }
2485#endif
2486
Emeric Brunfc0421f2012-09-07 17:30:07 +02002487#ifndef SSL_CTRL_SET_TLSEXT_HOSTNAME
Willy Tarreau2a65ff02012-09-13 17:54:29 +02002488 if (bind_conf->default_ctx) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02002489 memprintf(err, "%sthis version of openssl cannot load multiple SSL certificates.\n",
2490 err && *err ? *err : "");
Emeric Brunfc0421f2012-09-07 17:30:07 +02002491 return 1;
2492 }
2493#endif
Emmanuel Hocdet98263292016-12-29 18:26:15 +01002494 if (!bind_conf->default_ctx) {
Willy Tarreau2a65ff02012-09-13 17:54:29 +02002495 bind_conf->default_ctx = ctx;
Emmanuel Hocdet98263292016-12-29 18:26:15 +01002496 bind_conf->default_ssl_conf = ssl_conf;
2497 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02002498
2499 return 0;
2500}
2501
Willy Tarreau03209342016-12-22 17:08:28 +01002502int ssl_sock_load_cert(char *path, struct bind_conf *bind_conf, char **err)
Emeric Brunfc0421f2012-09-07 17:30:07 +02002503{
Cyril Bonté3180f7b2015-01-25 00:16:08 +01002504 struct dirent **de_list;
2505 int i, n;
Emeric Brunfc0421f2012-09-07 17:30:07 +02002506 DIR *dir;
2507 struct stat buf;
Willy Tarreauee2663b2012-12-06 11:36:59 +01002508 char *end;
2509 char fp[MAXPATHLEN+1];
Emeric Brunfc0421f2012-09-07 17:30:07 +02002510 int cfgerr = 0;
yanbzhu63ea8462015-12-09 13:35:14 -05002511#if OPENSSL_VERSION_NUMBER >= 0x1000200fL
2512 int is_bundle;
2513 int j;
2514#endif
Emeric Brunfc0421f2012-09-07 17:30:07 +02002515
yanbzhu08ce6ab2015-12-02 13:01:29 -05002516 if (stat(path, &buf) == 0) {
2517 dir = opendir(path);
2518 if (!dir)
Emmanuel Hocdet98263292016-12-29 18:26:15 +01002519 return ssl_sock_load_cert_file(path, bind_conf, NULL, NULL, 0, err);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002520
yanbzhu08ce6ab2015-12-02 13:01:29 -05002521 /* strip trailing slashes, including first one */
2522 for (end = path + strlen(path) - 1; end >= path && *end == '/'; end--)
2523 *end = 0;
Emeric Brunfc0421f2012-09-07 17:30:07 +02002524
yanbzhu08ce6ab2015-12-02 13:01:29 -05002525 n = scandir(path, &de_list, 0, alphasort);
2526 if (n < 0) {
2527 memprintf(err, "%sunable to scan directory '%s' : %s.\n",
2528 err && *err ? *err : "", path, strerror(errno));
2529 cfgerr++;
2530 }
2531 else {
2532 for (i = 0; i < n; i++) {
2533 struct dirent *de = de_list[i];
Emeric Brun2aab7222014-06-18 18:15:09 +02002534
yanbzhu08ce6ab2015-12-02 13:01:29 -05002535 end = strrchr(de->d_name, '.');
2536 if (end && (!strcmp(end, ".issuer") || !strcmp(end, ".ocsp") || !strcmp(end, ".sctl")))
2537 goto ignore_entry;
Cyril Bonté3180f7b2015-01-25 00:16:08 +01002538
yanbzhu08ce6ab2015-12-02 13:01:29 -05002539 snprintf(fp, sizeof(fp), "%s/%s", path, de->d_name);
2540 if (stat(fp, &buf) != 0) {
2541 memprintf(err, "%sunable to stat SSL certificate from file '%s' : %s.\n",
2542 err && *err ? *err : "", fp, strerror(errno));
2543 cfgerr++;
2544 goto ignore_entry;
2545 }
2546 if (!S_ISREG(buf.st_mode))
2547 goto ignore_entry;
yanbzhu63ea8462015-12-09 13:35:14 -05002548
2549#if OPENSSL_VERSION_NUMBER >= 0x1000200fL
2550 is_bundle = 0;
2551 /* Check if current entry in directory is part of a multi-cert bundle */
2552
2553 if (end) {
2554 for (j = 0; j < SSL_SOCK_NUM_KEYTYPES; j++) {
2555 if (!strcmp(end + 1, SSL_SOCK_KEYTYPE_NAMES[j])) {
2556 is_bundle = 1;
2557 break;
2558 }
2559 }
2560
2561 if (is_bundle) {
2562 char dp[MAXPATHLEN+1] = {0}; /* this will be the filename w/o the keytype */
2563 int dp_len;
2564
2565 dp_len = end - de->d_name;
2566 snprintf(dp, dp_len + 1, "%s", de->d_name);
2567
2568 /* increment i and free de until we get to a non-bundle cert
2569 * Note here that we look at de_list[i + 1] before freeing de
2570 * this is important since ignore_entry will free de
2571 */
2572 while (i + 1 < n && !strncmp(de_list[i + 1]->d_name, dp, dp_len)) {
2573 free(de);
2574 i++;
2575 de = de_list[i];
2576 }
2577
2578 snprintf(fp, sizeof(fp), "%s/%s", path, dp);
Emmanuel Hocdet98263292016-12-29 18:26:15 +01002579 ssl_sock_load_multi_cert(fp, bind_conf, NULL, NULL, 0, err);
yanbzhu63ea8462015-12-09 13:35:14 -05002580
2581 /* Successfully processed the bundle */
2582 goto ignore_entry;
2583 }
2584 }
2585
2586#endif
Emmanuel Hocdet98263292016-12-29 18:26:15 +01002587 cfgerr += ssl_sock_load_cert_file(fp, bind_conf, NULL, NULL, 0, err);
yanbzhu08ce6ab2015-12-02 13:01:29 -05002588ignore_entry:
2589 free(de);
Cyril Bonté3180f7b2015-01-25 00:16:08 +01002590 }
yanbzhu08ce6ab2015-12-02 13:01:29 -05002591 free(de_list);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002592 }
yanbzhu08ce6ab2015-12-02 13:01:29 -05002593 closedir(dir);
2594 return cfgerr;
Emeric Brunfc0421f2012-09-07 17:30:07 +02002595 }
yanbzhu08ce6ab2015-12-02 13:01:29 -05002596
Emmanuel Hocdet98263292016-12-29 18:26:15 +01002597 cfgerr = ssl_sock_load_multi_cert(path, bind_conf, NULL, NULL, 0, err);
yanbzhu08ce6ab2015-12-02 13:01:29 -05002598
Emeric Brunfc0421f2012-09-07 17:30:07 +02002599 return cfgerr;
2600}
2601
Thierry Fournier383085f2013-01-24 14:15:43 +01002602/* Make sure openssl opens /dev/urandom before the chroot. The work is only
2603 * done once. Zero is returned if the operation fails. No error is returned
2604 * if the random is said as not implemented, because we expect that openssl
2605 * will use another method once needed.
2606 */
2607static int ssl_initialize_random()
2608{
2609 unsigned char random;
2610 static int random_initialized = 0;
2611
2612 if (!random_initialized && RAND_bytes(&random, 1) != 0)
2613 random_initialized = 1;
2614
2615 return random_initialized;
2616}
2617
Emmanuel Hocdet98263292016-12-29 18:26:15 +01002618/* release ssl bind conf */
2619void ssl_sock_free_ssl_conf(struct ssl_bind_conf *conf)
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002620{
Emmanuel Hocdet98263292016-12-29 18:26:15 +01002621 if (conf) {
2622#ifdef OPENSSL_NPN_NEGOTIATED
2623 free(conf->npn_str);
2624 conf->npn_str = NULL;
2625#endif
2626#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
2627 free(conf->alpn_str);
2628 conf->alpn_str = NULL;
2629#endif
2630 free(conf->ca_file);
2631 conf->ca_file = NULL;
2632 free(conf->crl_file);
2633 conf->crl_file = NULL;
2634 free(conf->ciphers);
2635 conf->ciphers = NULL;
Emmanuel Hocdete7f2b732017-01-09 16:15:54 +01002636 free(conf->curves);
2637 conf->curves = NULL;
Emmanuel Hocdet98263292016-12-29 18:26:15 +01002638 free(conf->ecdhe);
2639 conf->ecdhe = NULL;
2640 }
2641}
2642
2643int ssl_sock_load_cert_list_file(char *file, struct bind_conf *bind_conf, struct proxy *curproxy, char **err)
2644{
2645 char thisline[CRT_LINESIZE];
2646 char path[MAXPATHLEN+1];
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002647 FILE *f;
yanbzhu1b04e5b2015-12-02 13:54:14 -05002648 struct stat buf;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002649 int linenum = 0;
2650 int cfgerr = 0;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002651
Willy Tarreauad1731d2013-04-02 17:35:58 +02002652 if ((f = fopen(file, "r")) == NULL) {
2653 memprintf(err, "cannot open file '%s' : %s", file, strerror(errno));
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002654 return 1;
Willy Tarreauad1731d2013-04-02 17:35:58 +02002655 }
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002656
2657 while (fgets(thisline, sizeof(thisline), f) != NULL) {
Emmanuel Hocdet98263292016-12-29 18:26:15 +01002658 int arg, newarg, cur_arg, i, ssl_b = 0, ssl_e = 0;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002659 char *end;
Emmanuel Hocdet98263292016-12-29 18:26:15 +01002660 char *args[MAX_CRT_ARGS + 1];
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002661 char *line = thisline;
Emmanuel Hocdet98263292016-12-29 18:26:15 +01002662 char *crt_path;
2663 struct ssl_bind_conf *ssl_conf = NULL;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002664
2665 linenum++;
2666 end = line + strlen(line);
2667 if (end-line == sizeof(thisline)-1 && *(end-1) != '\n') {
2668 /* Check if we reached the limit and the last char is not \n.
2669 * Watch out for the last line without the terminating '\n'!
2670 */
Willy Tarreauad1731d2013-04-02 17:35:58 +02002671 memprintf(err, "line %d too long in file '%s', limit is %d characters",
2672 linenum, file, (int)sizeof(thisline)-1);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002673 cfgerr = 1;
Willy Tarreauad1731d2013-04-02 17:35:58 +02002674 break;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002675 }
2676
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002677 arg = 0;
Emeric Brun50bcecc2013-04-22 13:05:23 +02002678 newarg = 1;
2679 while (*line) {
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002680 if (*line == '#' || *line == '\n' || *line == '\r') {
2681 /* end of string, end of loop */
2682 *line = 0;
2683 break;
Emmanuel Hocdet98263292016-12-29 18:26:15 +01002684 } else if (isspace(*line)) {
Emeric Brun50bcecc2013-04-22 13:05:23 +02002685 newarg = 1;
2686 *line = 0;
Emmanuel Hocdet98263292016-12-29 18:26:15 +01002687 } else if (*line == '[') {
2688 if (ssl_b) {
2689 memprintf(err, "too many '[' on line %d in file '%s'.", linenum, file);
2690 cfgerr = 1;
2691 break;
2692 }
2693 if (!arg) {
2694 memprintf(err, "file must start with a cert on line %d in file '%s'", linenum, file);
2695 cfgerr = 1;
2696 break;
2697 }
2698 ssl_b = arg;
2699 newarg = 1;
2700 *line = 0;
2701 } else if (*line == ']') {
2702 if (ssl_e) {
2703 memprintf(err, "too many ']' on line %d in file '%s'.", linenum, file);
Emeric Brun50bcecc2013-04-22 13:05:23 +02002704 cfgerr = 1;
2705 break;
2706 }
Emmanuel Hocdet98263292016-12-29 18:26:15 +01002707 if (!ssl_b) {
2708 memprintf(err, "missing '[' in line %d in file '%s'.", linenum, file);
2709 cfgerr = 1;
2710 break;
2711 }
2712 ssl_e = arg;
2713 newarg = 1;
2714 *line = 0;
2715 } else if (newarg) {
2716 if (arg == MAX_CRT_ARGS) {
2717 memprintf(err, "too many args on line %d in file '%s'.", linenum, file);
2718 cfgerr = 1;
2719 break;
2720 }
Emeric Brun50bcecc2013-04-22 13:05:23 +02002721 newarg = 0;
2722 args[arg++] = line;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002723 }
Emeric Brun50bcecc2013-04-22 13:05:23 +02002724 line++;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002725 }
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02002726 if (cfgerr)
2727 break;
Emmanuel Hocdet98263292016-12-29 18:26:15 +01002728 args[arg++] = line;
Willy Tarreauad1731d2013-04-02 17:35:58 +02002729
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002730 /* empty line */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01002731 if (!*args[0])
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002732 continue;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002733
Emmanuel Hocdet98263292016-12-29 18:26:15 +01002734 crt_path = args[0];
2735 if (*crt_path != '/' && global_ssl.crt_base) {
2736 if ((strlen(global_ssl.crt_base) + 1 + strlen(crt_path)) > MAXPATHLEN) {
2737 memprintf(err, "'%s' : path too long on line %d in file '%s'",
2738 crt_path, linenum, file);
2739 cfgerr = 1;
2740 break;
2741 }
2742 snprintf(path, sizeof(path), "%s/%s", global_ssl.crt_base, crt_path);
2743 crt_path = path;
2744 }
2745
2746 ssl_conf = calloc(1, sizeof *ssl_conf);
2747 cur_arg = ssl_b ? ssl_b : 1;
2748 while (cur_arg < ssl_e) {
2749 newarg = 0;
2750 for (i = 0; ssl_bind_kws[i].kw != NULL; i++) {
2751 if (strcmp(ssl_bind_kws[i].kw, args[cur_arg]) == 0) {
2752 newarg = 1;
2753 cfgerr = ssl_bind_kws[i].parse(args, cur_arg, curproxy, ssl_conf, err);
2754 if (cur_arg + 1 + ssl_bind_kws[i].skip > ssl_e) {
2755 memprintf(err, "ssl args out of '[]' for %s on line %d in file '%s'",
2756 args[cur_arg], linenum, file);
2757 cfgerr = 1;
2758 }
2759 cur_arg += 1 + ssl_bind_kws[i].skip;
2760 break;
2761 }
2762 }
2763 if (!cfgerr && !newarg) {
2764 memprintf(err, "unknown ssl keyword %s on line %d in file '%s'.",
2765 args[cur_arg], linenum, file);
2766 cfgerr = 1;
2767 break;
2768 }
2769 }
2770 if (cfgerr) {
2771 ssl_sock_free_ssl_conf(ssl_conf);
2772 free(ssl_conf);
2773 ssl_conf = NULL;
2774 break;
2775 }
2776
2777 if (stat(crt_path, &buf) == 0) {
2778 cfgerr = ssl_sock_load_cert_file(crt_path, bind_conf, ssl_conf,
2779 &args[cur_arg], arg - cur_arg - 1, err);
yanbzhu1b04e5b2015-12-02 13:54:14 -05002780 } else {
Emmanuel Hocdet98263292016-12-29 18:26:15 +01002781 cfgerr = ssl_sock_load_multi_cert(crt_path, bind_conf, ssl_conf,
2782 &args[cur_arg], arg - cur_arg - 1, err);
yanbzhu1b04e5b2015-12-02 13:54:14 -05002783 }
2784
Willy Tarreauad1731d2013-04-02 17:35:58 +02002785 if (cfgerr) {
2786 memprintf(err, "error processing line %d in file '%s' : %s", linenum, file, *err);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002787 break;
Willy Tarreauad1731d2013-04-02 17:35:58 +02002788 }
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002789 }
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002790 fclose(f);
2791 return cfgerr;
2792}
2793
Emeric Brunfc0421f2012-09-07 17:30:07 +02002794#ifndef SSL_OP_CIPHER_SERVER_PREFERENCE /* needs OpenSSL >= 0.9.7 */
2795#define SSL_OP_CIPHER_SERVER_PREFERENCE 0
2796#endif
2797
2798#ifndef SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION /* needs OpenSSL >= 0.9.7 */
2799#define SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION 0
Willy Tarreau7d588ee2012-11-26 18:47:31 +01002800#define SSL_renegotiate_pending(arg) 0
Emeric Brunfc0421f2012-09-07 17:30:07 +02002801#endif
Emeric Brun2b58d042012-09-20 17:10:03 +02002802#ifndef SSL_OP_SINGLE_ECDH_USE /* needs OpenSSL >= 0.9.8 */
2803#define SSL_OP_SINGLE_ECDH_USE 0
2804#endif
Emeric Brun2d0c4822012-10-02 13:45:20 +02002805#ifndef SSL_OP_NO_TICKET /* needs OpenSSL >= 0.9.8 */
2806#define SSL_OP_NO_TICKET 0
2807#endif
Emeric Brunfc0421f2012-09-07 17:30:07 +02002808#ifndef SSL_OP_NO_COMPRESSION /* needs OpenSSL >= 0.9.9 */
2809#define SSL_OP_NO_COMPRESSION 0
2810#endif
Emeric Brunc0ff4922012-09-28 19:37:02 +02002811#ifndef SSL_OP_NO_TLSv1_1 /* needs OpenSSL >= 1.0.1 */
2812#define SSL_OP_NO_TLSv1_1 0
2813#endif
2814#ifndef SSL_OP_NO_TLSv1_2 /* needs OpenSSL >= 1.0.1 */
2815#define SSL_OP_NO_TLSv1_2 0
2816#endif
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02002817#ifndef SSL_OP_SINGLE_DH_USE /* needs OpenSSL >= 0.9.6 */
2818#define SSL_OP_SINGLE_DH_USE 0
2819#endif
Emeric Brun2b58d042012-09-20 17:10:03 +02002820#ifndef SSL_OP_SINGLE_ECDH_USE /* needs OpenSSL >= 1.0.0 */
2821#define SSL_OP_SINGLE_ECDH_USE 0
2822#endif
Emeric Brunfc0421f2012-09-07 17:30:07 +02002823#ifndef SSL_MODE_RELEASE_BUFFERS /* needs OpenSSL >= 1.0.0 */
2824#define SSL_MODE_RELEASE_BUFFERS 0
2825#endif
Willy Tarreau396a1862014-11-13 14:06:52 +01002826#ifndef SSL_MODE_SMALL_BUFFERS /* needs small_records.patch */
2827#define SSL_MODE_SMALL_BUFFERS 0
2828#endif
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002829
Emmanuel Hocdet98263292016-12-29 18:26:15 +01002830int 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 +02002831{
Willy Tarreau03209342016-12-22 17:08:28 +01002832 struct proxy *curproxy = bind_conf->frontend;
Emeric Brunfc0421f2012-09-07 17:30:07 +02002833 int cfgerr = 0;
Emeric Brun850efd52014-01-29 12:24:34 +01002834 int verify = SSL_VERIFY_NONE;
Remi Gacogneaf5c3da2014-05-19 10:29:58 +02002835 long ssloptions =
Emeric Brunfc0421f2012-09-07 17:30:07 +02002836 SSL_OP_ALL | /* all known workarounds for bugs */
2837 SSL_OP_NO_SSLv2 |
2838 SSL_OP_NO_COMPRESSION |
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02002839 SSL_OP_SINGLE_DH_USE |
Emeric Brun2b58d042012-09-20 17:10:03 +02002840 SSL_OP_SINGLE_ECDH_USE |
Emeric Brun3c4bc6e2012-10-04 18:44:19 +02002841 SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION |
2842 SSL_OP_CIPHER_SERVER_PREFERENCE;
Remi Gacogneaf5c3da2014-05-19 10:29:58 +02002843 long sslmode =
Emeric Brunfc0421f2012-09-07 17:30:07 +02002844 SSL_MODE_ENABLE_PARTIAL_WRITE |
2845 SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER |
Willy Tarreau396a1862014-11-13 14:06:52 +01002846 SSL_MODE_RELEASE_BUFFERS |
2847 SSL_MODE_SMALL_BUFFERS;
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002848 STACK_OF(SSL_CIPHER) * ciphers = NULL;
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +01002849 const SSL_CIPHER * cipher = NULL;
Remi Gacognec1eab8c2014-06-12 18:20:11 +02002850 char cipher_description[128];
2851 /* The description of ciphers using an Ephemeral Diffie Hellman key exchange
2852 contains " Kx=DH " or " Kx=DH(". Beware of " Kx=DH/",
2853 which is not ephemeral DH. */
2854 const char dhe_description[] = " Kx=DH ";
2855 const char dhe_export_description[] = " Kx=DH(";
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002856 int idx = 0;
2857 int dhe_found = 0;
Remi Gacogne23d5d372014-10-10 17:04:26 +02002858 SSL *ssl = NULL;
Emmanuel Hocdet98263292016-12-29 18:26:15 +01002859 struct ssl_bind_conf *ssl_conf_cur;
2860 int conf_ssl_options = bind_conf->ssl_conf.ssl_options | (ssl_conf ? ssl_conf->ssl_options : 0);
2861 const char *conf_ciphers;
Emmanuel Hocdete7f2b732017-01-09 16:15:54 +01002862 const char *conf_curves = NULL;
Emeric Brunfc0421f2012-09-07 17:30:07 +02002863
Thierry Fournier383085f2013-01-24 14:15:43 +01002864 /* Make sure openssl opens /dev/urandom before the chroot */
2865 if (!ssl_initialize_random()) {
2866 Alert("OpenSSL random data generator initialization failed.\n");
2867 cfgerr++;
2868 }
2869
Emmanuel Hocdet98263292016-12-29 18:26:15 +01002870 if (conf_ssl_options & BC_SSL_O_NO_SSLV3)
Emeric Brunfc0421f2012-09-07 17:30:07 +02002871 ssloptions |= SSL_OP_NO_SSLv3;
Emmanuel Hocdet98263292016-12-29 18:26:15 +01002872 if (conf_ssl_options & BC_SSL_O_NO_TLSV10)
Emeric Brunfc0421f2012-09-07 17:30:07 +02002873 ssloptions |= SSL_OP_NO_TLSv1;
Emmanuel Hocdet98263292016-12-29 18:26:15 +01002874 if (conf_ssl_options & BC_SSL_O_NO_TLSV11)
Emeric Brunc0ff4922012-09-28 19:37:02 +02002875 ssloptions |= SSL_OP_NO_TLSv1_1;
Emmanuel Hocdet98263292016-12-29 18:26:15 +01002876 if (conf_ssl_options & BC_SSL_O_NO_TLSV12)
Emeric Brunc0ff4922012-09-28 19:37:02 +02002877 ssloptions |= SSL_OP_NO_TLSv1_2;
Emmanuel Hocdet98263292016-12-29 18:26:15 +01002878 if (conf_ssl_options & BC_SSL_O_NO_TLS_TICKETS)
Emeric Brun2d0c4822012-10-02 13:45:20 +02002879 ssloptions |= SSL_OP_NO_TICKET;
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +01002880#ifndef OPENSSL_IS_BORINGSSL
Emmanuel Hocdet98263292016-12-29 18:26:15 +01002881 if (conf_ssl_options & BC_SSL_O_USE_SSLV3) {
Jérémie Courrèges-Anglas17c3f622015-07-25 16:50:52 -06002882#ifndef OPENSSL_NO_SSL3
Emeric Brun2cb7ae52012-10-05 14:14:21 +02002883 SSL_CTX_set_ssl_version(ctx, SSLv3_server_method());
Jérémie Courrèges-Anglas17c3f622015-07-25 16:50:52 -06002884#else
2885 Alert("SSLv3 support requested but unavailable.\n");
2886 cfgerr++;
2887#endif
2888 }
Emmanuel Hocdet98263292016-12-29 18:26:15 +01002889 if (conf_ssl_options & BC_SSL_O_USE_TLSV10)
Emeric Brun2cb7ae52012-10-05 14:14:21 +02002890 SSL_CTX_set_ssl_version(ctx, TLSv1_server_method());
2891#if SSL_OP_NO_TLSv1_1
Emmanuel Hocdet98263292016-12-29 18:26:15 +01002892 if (conf_ssl_options & BC_SSL_O_USE_TLSV11)
Emeric Brun2cb7ae52012-10-05 14:14:21 +02002893 SSL_CTX_set_ssl_version(ctx, TLSv1_1_server_method());
2894#endif
2895#if SSL_OP_NO_TLSv1_2
Emmanuel Hocdet98263292016-12-29 18:26:15 +01002896 if (conf_ssl_options & BC_SSL_O_USE_TLSV12)
Emeric Brun2cb7ae52012-10-05 14:14:21 +02002897 SSL_CTX_set_ssl_version(ctx, TLSv1_2_server_method());
2898#endif
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +01002899#endif
Emeric Brunfc0421f2012-09-07 17:30:07 +02002900 SSL_CTX_set_options(ctx, ssloptions);
2901 SSL_CTX_set_mode(ctx, sslmode);
Emmanuel Hocdet98263292016-12-29 18:26:15 +01002902 switch ((ssl_conf && ssl_conf->verify) ? ssl_conf->verify : bind_conf->ssl_conf.verify) {
Emeric Brun850efd52014-01-29 12:24:34 +01002903 case SSL_SOCK_VERIFY_NONE:
2904 verify = SSL_VERIFY_NONE;
2905 break;
2906 case SSL_SOCK_VERIFY_OPTIONAL:
2907 verify = SSL_VERIFY_PEER;
2908 break;
2909 case SSL_SOCK_VERIFY_REQUIRED:
2910 verify = SSL_VERIFY_PEER|SSL_VERIFY_FAIL_IF_NO_PEER_CERT;
2911 break;
2912 }
2913 SSL_CTX_set_verify(ctx, verify, ssl_sock_bind_verifycbk);
2914 if (verify & SSL_VERIFY_PEER) {
Emmanuel Hocdet98263292016-12-29 18:26:15 +01002915 char *ca_file = (ssl_conf && ssl_conf->ca_file) ? ssl_conf->ca_file : bind_conf->ssl_conf.ca_file;
2916 char *crl_file = (ssl_conf && ssl_conf->crl_file) ? ssl_conf->crl_file : bind_conf->ssl_conf.crl_file;
2917 if (ca_file) {
Emeric Brund94b3fe2012-09-20 18:23:56 +02002918 /* load CAfile to verify */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01002919 if (!SSL_CTX_load_verify_locations(ctx, ca_file, NULL)) {
Emeric Brund94b3fe2012-09-20 18:23:56 +02002920 Alert("Proxy '%s': unable to load CA file '%s' for bind '%s' at [%s:%d].\n",
Emmanuel Hocdet98263292016-12-29 18:26:15 +01002921 curproxy->id, ca_file, bind_conf->arg, bind_conf->file, bind_conf->line);
Emeric Brund94b3fe2012-09-20 18:23:56 +02002922 cfgerr++;
2923 }
2924 /* set CA names fo client cert request, function returns void */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01002925 SSL_CTX_set_client_CA_list(ctx, SSL_load_client_CA_file(ca_file));
Emeric Brund94b3fe2012-09-20 18:23:56 +02002926 }
Emeric Brun850efd52014-01-29 12:24:34 +01002927 else {
2928 Alert("Proxy '%s': verify is enabled but no CA file specified for bind '%s' at [%s:%d].\n",
2929 curproxy->id, bind_conf->arg, bind_conf->file, bind_conf->line);
2930 cfgerr++;
2931 }
Emeric Brun051cdab2012-10-02 19:25:50 +02002932#ifdef X509_V_FLAG_CRL_CHECK
Emmanuel Hocdet98263292016-12-29 18:26:15 +01002933 if (crl_file) {
Emeric Brund94b3fe2012-09-20 18:23:56 +02002934 X509_STORE *store = SSL_CTX_get_cert_store(ctx);
2935
Emmanuel Hocdet98263292016-12-29 18:26:15 +01002936 if (!store || !X509_STORE_load_locations(store, crl_file, NULL)) {
Emeric Brund94b3fe2012-09-20 18:23:56 +02002937 Alert("Proxy '%s': unable to configure CRL file '%s' for bind '%s' at [%s:%d].\n",
Emmanuel Hocdet98263292016-12-29 18:26:15 +01002938 curproxy->id, crl_file, bind_conf->arg, bind_conf->file, bind_conf->line);
Emeric Brund94b3fe2012-09-20 18:23:56 +02002939 cfgerr++;
2940 }
Emeric Brun561e5742012-10-02 15:20:55 +02002941 else {
2942 X509_STORE_set_flags(store, X509_V_FLAG_CRL_CHECK|X509_V_FLAG_CRL_CHECK_ALL);
2943 }
Emeric Brund94b3fe2012-09-20 18:23:56 +02002944 }
Emeric Brun051cdab2012-10-02 19:25:50 +02002945#endif
Emeric Brun644cde02012-12-14 11:21:13 +01002946 ERR_clear_error();
Emeric Brund94b3fe2012-09-20 18:23:56 +02002947 }
Nenad Merdanovic05552d42015-02-27 19:56:49 +01002948#if (defined SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB && TLS_TICKETS_NO > 0)
Nenad Merdanovic146defa2015-05-09 08:46:00 +02002949 if(bind_conf->keys_ref) {
Nenad Merdanovic05552d42015-02-27 19:56:49 +01002950 if (!SSL_CTX_set_tlsext_ticket_key_cb(ctx, ssl_tlsext_ticket_key_cb)) {
2951 Alert("Proxy '%s': unable to set callback for TLS ticket validation for bind '%s' at [%s:%d].\n",
2952 curproxy->id, bind_conf->arg, bind_conf->file, bind_conf->line);
2953 cfgerr++;
2954 }
2955 }
2956#endif
2957
Willy Tarreauef934602016-12-22 23:12:01 +01002958 if (global_ssl.life_time)
2959 SSL_CTX_set_timeout(ctx, global_ssl.life_time);
Emeric Brun4f65bff2012-11-16 15:11:00 +01002960
Emeric Brunfc0421f2012-09-07 17:30:07 +02002961 shared_context_set_cache(ctx);
Emmanuel Hocdet98263292016-12-29 18:26:15 +01002962 conf_ciphers = (ssl_conf && ssl_conf->ciphers) ? ssl_conf->ciphers : bind_conf->ssl_conf.ciphers;
2963 if (conf_ciphers &&
2964 !SSL_CTX_set_cipher_list(ctx, conf_ciphers)) {
Emeric Brunfc0421f2012-09-07 17:30:07 +02002965 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 +01002966 curproxy->id, conf_ciphers, bind_conf->arg, bind_conf->file, bind_conf->line);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002967 cfgerr++;
2968 }
2969
Remi Gacogne47783ef2015-05-29 15:53:22 +02002970 /* If tune.ssl.default-dh-param has not been set,
2971 neither has ssl-default-dh-file and no static DH
2972 params were in the certificate file. */
Willy Tarreauef934602016-12-22 23:12:01 +01002973 if (global_ssl.default_dh_param == 0 &&
Remi Gacogne47783ef2015-05-29 15:53:22 +02002974 global_dh == NULL &&
Remi Gacogne4f902b82015-05-28 16:23:00 +02002975 (ssl_dh_ptr_index == -1 ||
2976 SSL_CTX_get_ex_data(ctx, ssl_dh_ptr_index) == NULL)) {
Lukas Tribus90132722014-08-18 00:56:33 +02002977
Remi Gacogne23d5d372014-10-10 17:04:26 +02002978 ssl = SSL_new(ctx);
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002979
Remi Gacogne23d5d372014-10-10 17:04:26 +02002980 if (ssl) {
2981 ciphers = SSL_get_ciphers(ssl);
2982
2983 if (ciphers) {
2984 for (idx = 0; idx < sk_SSL_CIPHER_num(ciphers); idx++) {
2985 cipher = sk_SSL_CIPHER_value(ciphers, idx);
2986 if (SSL_CIPHER_description(cipher, cipher_description, sizeof (cipher_description)) == cipher_description) {
2987 if (strstr(cipher_description, dhe_description) != NULL ||
2988 strstr(cipher_description, dhe_export_description) != NULL) {
2989 dhe_found = 1;
2990 break;
2991 }
Remi Gacognec1eab8c2014-06-12 18:20:11 +02002992 }
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002993 }
2994 }
Remi Gacogne23d5d372014-10-10 17:04:26 +02002995 SSL_free(ssl);
2996 ssl = NULL;
Lukas Tribus90132722014-08-18 00:56:33 +02002997 }
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002998
Lukas Tribus90132722014-08-18 00:56:33 +02002999 if (dhe_found) {
3000 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 +02003001 }
3002
Willy Tarreauef934602016-12-22 23:12:01 +01003003 global_ssl.default_dh_param = 1024;
Remi Gacognef46cd6e2014-06-12 14:58:40 +02003004 }
Remi Gacogne8de54152014-07-15 11:36:40 +02003005
3006#ifndef OPENSSL_NO_DH
Willy Tarreauef934602016-12-22 23:12:01 +01003007 if (global_ssl.default_dh_param >= 1024) {
Remi Gacogne8de54152014-07-15 11:36:40 +02003008 if (local_dh_1024 == NULL) {
3009 local_dh_1024 = ssl_get_dh_1024();
3010 }
Willy Tarreauef934602016-12-22 23:12:01 +01003011 if (global_ssl.default_dh_param >= 2048) {
Remi Gacogne8de54152014-07-15 11:36:40 +02003012 if (local_dh_2048 == NULL) {
3013 local_dh_2048 = ssl_get_dh_2048();
3014 }
Willy Tarreauef934602016-12-22 23:12:01 +01003015 if (global_ssl.default_dh_param >= 4096) {
Remi Gacogne8de54152014-07-15 11:36:40 +02003016 if (local_dh_4096 == NULL) {
3017 local_dh_4096 = ssl_get_dh_4096();
3018 }
Remi Gacogne8de54152014-07-15 11:36:40 +02003019 }
3020 }
3021 }
3022#endif /* OPENSSL_NO_DH */
Remi Gacognef46cd6e2014-06-12 14:58:40 +02003023
Emeric Brunfc0421f2012-09-07 17:30:07 +02003024 SSL_CTX_set_info_callback(ctx, ssl_sock_infocbk);
Willy Tarreau5cbe4ef2014-05-08 22:45:11 +02003025#if OPENSSL_VERSION_NUMBER >= 0x00907000L
Emeric Brun29f037d2014-04-25 19:05:36 +02003026 SSL_CTX_set_msg_callback(ctx, ssl_sock_msgcbk);
Willy Tarreau5cbe4ef2014-05-08 22:45:11 +02003027#endif
Emeric Brun29f037d2014-04-25 19:05:36 +02003028
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02003029#ifdef OPENSSL_NPN_NEGOTIATED
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003030 ssl_conf_cur = NULL;
3031 if (ssl_conf && ssl_conf->npn_str)
3032 ssl_conf_cur = ssl_conf;
3033 else if (bind_conf->ssl_conf.npn_str)
3034 ssl_conf_cur = &bind_conf->ssl_conf;
3035 if (ssl_conf_cur)
3036 SSL_CTX_set_next_protos_advertised_cb(ctx, ssl_sock_advertise_npn_protos, ssl_conf_cur);
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02003037#endif
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01003038#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003039 ssl_conf_cur = NULL;
3040 if (ssl_conf && ssl_conf->alpn_str)
3041 ssl_conf_cur = ssl_conf;
3042 else if (bind_conf->ssl_conf.alpn_str)
3043 ssl_conf_cur = &bind_conf->ssl_conf;
3044 if (ssl_conf_cur)
3045 SSL_CTX_set_alpn_select_cb(ctx, ssl_sock_advertise_alpn_protos, ssl_conf_cur);
Willy Tarreauab861d32013-04-02 02:30:41 +02003046#endif
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02003047
Emeric Brunfc0421f2012-09-07 17:30:07 +02003048#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
3049 SSL_CTX_set_tlsext_servername_callback(ctx, ssl_sock_switchctx_cbk);
Willy Tarreau2a65ff02012-09-13 17:54:29 +02003050 SSL_CTX_set_tlsext_servername_arg(ctx, bind_conf);
Emeric Brunfc0421f2012-09-07 17:30:07 +02003051#endif
Emmanuel Hocdete7f2b732017-01-09 16:15:54 +01003052#if OPENSSL_VERSION_NUMBER >= 0x1000200fL
3053 conf_curves = (ssl_conf && ssl_conf->curves) ? ssl_conf->curves : bind_conf->ssl_conf.curves;
3054 if (conf_curves) {
3055 if (!SSL_CTX_set1_curves_list(ctx, conf_curves)) {
3056 Alert("Proxy '%s': unable to set SSL curves list to '%s' for bind '%s' at [%s:%d].\n",
3057 curproxy->id, conf_curves, bind_conf->arg, bind_conf->file, bind_conf->line);
3058 cfgerr++;
3059 }
Emmanuel Hocdete7f2b732017-01-09 16:15:54 +01003060 else
3061 SSL_CTX_set_ecdh_auto(ctx, 1);
Emmanuel Hocdete7f2b732017-01-09 16:15:54 +01003062 }
3063#endif
Emeric Brun2b58d042012-09-20 17:10:03 +02003064#if defined(SSL_CTX_set_tmp_ecdh) && !defined(OPENSSL_NO_ECDH)
Emmanuel Hocdete7f2b732017-01-09 16:15:54 +01003065 if (!conf_curves) {
Emeric Brun2b58d042012-09-20 17:10:03 +02003066 int i;
3067 EC_KEY *ecdh;
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003068 const char *ecdhe = (ssl_conf && ssl_conf->ecdhe) ? ssl_conf->ecdhe :
3069 (bind_conf->ssl_conf.ecdhe ? bind_conf->ssl_conf.ecdhe : ECDHE_DEFAULT_CURVE);
Emeric Brun2b58d042012-09-20 17:10:03 +02003070
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003071 i = OBJ_sn2nid(ecdhe);
Emeric Brun2b58d042012-09-20 17:10:03 +02003072 if (!i || ((ecdh = EC_KEY_new_by_curve_name(i)) == NULL)) {
3073 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 +01003074 curproxy->id, ecdhe, bind_conf->arg, bind_conf->file, bind_conf->line);
Emeric Brun2b58d042012-09-20 17:10:03 +02003075 cfgerr++;
3076 }
3077 else {
3078 SSL_CTX_set_tmp_ecdh(ctx, ecdh);
3079 EC_KEY_free(ecdh);
3080 }
3081 }
3082#endif
3083
Emeric Brunfc0421f2012-09-07 17:30:07 +02003084 return cfgerr;
3085}
3086
Evan Broderbe554312013-06-27 00:05:25 -07003087static int ssl_sock_srv_hostcheck(const char *pattern, const char *hostname)
3088{
3089 const char *pattern_wildcard, *pattern_left_label_end, *hostname_left_label_end;
3090 size_t prefixlen, suffixlen;
3091
3092 /* Trivial case */
3093 if (strcmp(pattern, hostname) == 0)
3094 return 1;
3095
Evan Broderbe554312013-06-27 00:05:25 -07003096 /* The rest of this logic is based on RFC 6125, section 6.4.3
3097 * (http://tools.ietf.org/html/rfc6125#section-6.4.3) */
3098
Emeric Bruna848dae2013-10-08 11:27:28 +02003099 pattern_wildcard = NULL;
3100 pattern_left_label_end = pattern;
3101 while (*pattern_left_label_end != '.') {
3102 switch (*pattern_left_label_end) {
3103 case 0:
3104 /* End of label not found */
3105 return 0;
3106 case '*':
3107 /* If there is more than one wildcards */
3108 if (pattern_wildcard)
3109 return 0;
3110 pattern_wildcard = pattern_left_label_end;
3111 break;
3112 }
3113 pattern_left_label_end++;
3114 }
3115
3116 /* If it's not trivial and there is no wildcard, it can't
3117 * match */
3118 if (!pattern_wildcard)
Evan Broderbe554312013-06-27 00:05:25 -07003119 return 0;
3120
3121 /* Make sure all labels match except the leftmost */
3122 hostname_left_label_end = strchr(hostname, '.');
3123 if (!hostname_left_label_end
3124 || strcmp(pattern_left_label_end, hostname_left_label_end) != 0)
3125 return 0;
3126
3127 /* Make sure the leftmost label of the hostname is long enough
3128 * that the wildcard can match */
Emeric Brun369da852013-10-08 11:39:35 +02003129 if (hostname_left_label_end - hostname < (pattern_left_label_end - pattern) - 1)
Evan Broderbe554312013-06-27 00:05:25 -07003130 return 0;
3131
3132 /* Finally compare the string on either side of the
3133 * wildcard */
3134 prefixlen = pattern_wildcard - pattern;
3135 suffixlen = pattern_left_label_end - (pattern_wildcard + 1);
Emeric Bruna848dae2013-10-08 11:27:28 +02003136 if ((prefixlen && (memcmp(pattern, hostname, prefixlen) != 0))
3137 || (suffixlen && (memcmp(pattern_wildcard + 1, hostname_left_label_end - suffixlen, suffixlen) != 0)))
Evan Broderbe554312013-06-27 00:05:25 -07003138 return 0;
3139
3140 return 1;
3141}
3142
3143static int ssl_sock_srv_verifycbk(int ok, X509_STORE_CTX *ctx)
3144{
3145 SSL *ssl;
3146 struct connection *conn;
3147 char *servername;
3148
3149 int depth;
3150 X509 *cert;
3151 STACK_OF(GENERAL_NAME) *alt_names;
3152 int i;
3153 X509_NAME *cert_subject;
3154 char *str;
3155
3156 if (ok == 0)
3157 return ok;
3158
3159 ssl = X509_STORE_CTX_get_ex_data(ctx, SSL_get_ex_data_X509_STORE_CTX_idx());
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02003160 conn = SSL_get_app_data(ssl);
Evan Broderbe554312013-06-27 00:05:25 -07003161
3162 servername = objt_server(conn->target)->ssl_ctx.verify_host;
3163
3164 /* We only need to verify the CN on the actual server cert,
3165 * not the indirect CAs */
3166 depth = X509_STORE_CTX_get_error_depth(ctx);
3167 if (depth != 0)
3168 return ok;
3169
3170 /* At this point, the cert is *not* OK unless we can find a
3171 * hostname match */
3172 ok = 0;
3173
3174 cert = X509_STORE_CTX_get_current_cert(ctx);
3175 /* It seems like this might happen if verify peer isn't set */
3176 if (!cert)
3177 return ok;
3178
3179 alt_names = X509_get_ext_d2i(cert, NID_subject_alt_name, NULL, NULL);
3180 if (alt_names) {
3181 for (i = 0; !ok && i < sk_GENERAL_NAME_num(alt_names); i++) {
3182 GENERAL_NAME *name = sk_GENERAL_NAME_value(alt_names, i);
3183 if (name->type == GEN_DNS) {
Emeric Bruna33410c2013-09-17 15:47:48 +02003184#if OPENSSL_VERSION_NUMBER < 0x00907000L
3185 if (ASN1_STRING_to_UTF8((unsigned char **)&str, name->d.ia5) >= 0) {
3186#else
Evan Broderbe554312013-06-27 00:05:25 -07003187 if (ASN1_STRING_to_UTF8((unsigned char **)&str, name->d.dNSName) >= 0) {
Emeric Bruna33410c2013-09-17 15:47:48 +02003188#endif
Evan Broderbe554312013-06-27 00:05:25 -07003189 ok = ssl_sock_srv_hostcheck(str, servername);
3190 OPENSSL_free(str);
3191 }
3192 }
3193 }
Emeric Brun4ad50a42013-09-17 15:19:54 +02003194 sk_GENERAL_NAME_pop_free(alt_names, GENERAL_NAME_free);
Evan Broderbe554312013-06-27 00:05:25 -07003195 }
3196
3197 cert_subject = X509_get_subject_name(cert);
3198 i = -1;
3199 while (!ok && (i = X509_NAME_get_index_by_NID(cert_subject, NID_commonName, i)) != -1) {
3200 X509_NAME_ENTRY *entry = X509_NAME_get_entry(cert_subject, i);
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02003201 ASN1_STRING *value;
3202 value = X509_NAME_ENTRY_get_data(entry);
3203 if (ASN1_STRING_to_UTF8((unsigned char **)&str, value) >= 0) {
Evan Broderbe554312013-06-27 00:05:25 -07003204 ok = ssl_sock_srv_hostcheck(str, servername);
3205 OPENSSL_free(str);
3206 }
3207 }
3208
3209 return ok;
3210}
3211
Emeric Brun94324a42012-10-11 14:00:19 +02003212/* prepare ssl context from servers options. Returns an error count */
Willy Tarreau03209342016-12-22 17:08:28 +01003213int ssl_sock_prepare_srv_ctx(struct server *srv)
Emeric Brun94324a42012-10-11 14:00:19 +02003214{
Willy Tarreau03209342016-12-22 17:08:28 +01003215 struct proxy *curproxy = srv->proxy;
Emeric Brun94324a42012-10-11 14:00:19 +02003216 int cfgerr = 0;
Remi Gacogneaf5c3da2014-05-19 10:29:58 +02003217 long options =
Emeric Brun94324a42012-10-11 14:00:19 +02003218 SSL_OP_ALL | /* all known workarounds for bugs */
3219 SSL_OP_NO_SSLv2 |
3220 SSL_OP_NO_COMPRESSION;
Remi Gacogneaf5c3da2014-05-19 10:29:58 +02003221 long mode =
Emeric Brun94324a42012-10-11 14:00:19 +02003222 SSL_MODE_ENABLE_PARTIAL_WRITE |
3223 SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER |
Willy Tarreau396a1862014-11-13 14:06:52 +01003224 SSL_MODE_RELEASE_BUFFERS |
3225 SSL_MODE_SMALL_BUFFERS;
Emeric Brun850efd52014-01-29 12:24:34 +01003226 int verify = SSL_VERIFY_NONE;
Emeric Brun94324a42012-10-11 14:00:19 +02003227
Thierry Fournier383085f2013-01-24 14:15:43 +01003228 /* Make sure openssl opens /dev/urandom before the chroot */
3229 if (!ssl_initialize_random()) {
3230 Alert("OpenSSL random data generator initialization failed.\n");
3231 cfgerr++;
3232 }
3233
Willy Tarreaufce03112015-01-15 21:32:40 +01003234 /* Automatic memory computations need to know we use SSL there */
3235 global.ssl_used_backend = 1;
3236
3237 /* Initiate SSL context for current server */
Emeric Brun94324a42012-10-11 14:00:19 +02003238 srv->ssl_ctx.reused_sess = NULL;
3239 if (srv->use_ssl)
3240 srv->xprt = &ssl_sock;
3241 if (srv->check.use_ssl)
Cyril Bonté9ce13112014-11-15 22:41:27 +01003242 srv->check.xprt = &ssl_sock;
Emeric Brun94324a42012-10-11 14:00:19 +02003243
3244 srv->ssl_ctx.ctx = SSL_CTX_new(SSLv23_client_method());
3245 if (!srv->ssl_ctx.ctx) {
3246 Alert("config : %s '%s', server '%s': unable to allocate ssl context.\n",
3247 proxy_type_str(curproxy), curproxy->id,
3248 srv->id);
3249 cfgerr++;
3250 return cfgerr;
3251 }
Emeric Bruna7aa3092012-10-26 12:58:00 +02003252 if (srv->ssl_ctx.client_crt) {
3253 if (SSL_CTX_use_PrivateKey_file(srv->ssl_ctx.ctx, srv->ssl_ctx.client_crt, SSL_FILETYPE_PEM) <= 0) {
3254 Alert("config : %s '%s', server '%s': unable to load SSL private key from PEM file '%s'.\n",
3255 proxy_type_str(curproxy), curproxy->id,
3256 srv->id, srv->ssl_ctx.client_crt);
3257 cfgerr++;
3258 }
3259 else if (SSL_CTX_use_certificate_chain_file(srv->ssl_ctx.ctx, srv->ssl_ctx.client_crt) <= 0) {
3260 Alert("config : %s '%s', server '%s': unable to load ssl certificate from PEM file '%s'.\n",
3261 proxy_type_str(curproxy), curproxy->id,
3262 srv->id, srv->ssl_ctx.client_crt);
3263 cfgerr++;
3264 }
3265 else if (SSL_CTX_check_private_key(srv->ssl_ctx.ctx) <= 0) {
3266 Alert("config : %s '%s', server '%s': inconsistencies between private key and certificate loaded from PEM file '%s'.\n",
3267 proxy_type_str(curproxy), curproxy->id,
3268 srv->id, srv->ssl_ctx.client_crt);
3269 cfgerr++;
3270 }
3271 }
Emeric Brun94324a42012-10-11 14:00:19 +02003272
3273 if (srv->ssl_ctx.options & SRV_SSL_O_NO_SSLV3)
3274 options |= SSL_OP_NO_SSLv3;
3275 if (srv->ssl_ctx.options & SRV_SSL_O_NO_TLSV10)
3276 options |= SSL_OP_NO_TLSv1;
3277 if (srv->ssl_ctx.options & SRV_SSL_O_NO_TLSV11)
3278 options |= SSL_OP_NO_TLSv1_1;
3279 if (srv->ssl_ctx.options & SRV_SSL_O_NO_TLSV12)
3280 options |= SSL_OP_NO_TLSv1_2;
Emeric Brunf9c5c472012-10-11 15:28:34 +02003281 if (srv->ssl_ctx.options & SRV_SSL_O_NO_TLS_TICKETS)
3282 options |= SSL_OP_NO_TICKET;
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +01003283#ifndef OPENSSL_IS_BORINGSSL
Jérémie Courrèges-Anglas17c3f622015-07-25 16:50:52 -06003284 if (srv->ssl_ctx.options & SRV_SSL_O_USE_SSLV3) {
3285#ifndef OPENSSL_NO_SSL3
Emeric Brun94324a42012-10-11 14:00:19 +02003286 SSL_CTX_set_ssl_version(srv->ssl_ctx.ctx, SSLv3_client_method());
Jérémie Courrèges-Anglas17c3f622015-07-25 16:50:52 -06003287#else
Thierry FOURNIERbc965342015-08-26 08:21:26 +02003288 Alert("SSLv3 support requested but unavailable.\n");
Jérémie Courrèges-Anglas17c3f622015-07-25 16:50:52 -06003289 cfgerr++;
3290#endif
3291 }
Emeric Brun94324a42012-10-11 14:00:19 +02003292 if (srv->ssl_ctx.options & SRV_SSL_O_USE_TLSV10)
3293 SSL_CTX_set_ssl_version(srv->ssl_ctx.ctx, TLSv1_client_method());
3294#if SSL_OP_NO_TLSv1_1
3295 if (srv->ssl_ctx.options & SRV_SSL_O_USE_TLSV11)
3296 SSL_CTX_set_ssl_version(srv->ssl_ctx.ctx, TLSv1_1_client_method());
3297#endif
3298#if SSL_OP_NO_TLSv1_2
3299 if (srv->ssl_ctx.options & SRV_SSL_O_USE_TLSV12)
3300 SSL_CTX_set_ssl_version(srv->ssl_ctx.ctx, TLSv1_2_client_method());
3301#endif
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +01003302#endif
Emeric Brun94324a42012-10-11 14:00:19 +02003303 SSL_CTX_set_options(srv->ssl_ctx.ctx, options);
3304 SSL_CTX_set_mode(srv->ssl_ctx.ctx, mode);
Emeric Brun850efd52014-01-29 12:24:34 +01003305
3306 if (global.ssl_server_verify == SSL_SERVER_VERIFY_REQUIRED)
3307 verify = SSL_VERIFY_PEER;
3308
3309 switch (srv->ssl_ctx.verify) {
3310 case SSL_SOCK_VERIFY_NONE:
3311 verify = SSL_VERIFY_NONE;
3312 break;
3313 case SSL_SOCK_VERIFY_REQUIRED:
3314 verify = SSL_VERIFY_PEER;
3315 break;
3316 }
Evan Broderbe554312013-06-27 00:05:25 -07003317 SSL_CTX_set_verify(srv->ssl_ctx.ctx,
Emeric Brun850efd52014-01-29 12:24:34 +01003318 verify,
Evan Broderbe554312013-06-27 00:05:25 -07003319 srv->ssl_ctx.verify_host ? ssl_sock_srv_verifycbk : NULL);
Emeric Brun850efd52014-01-29 12:24:34 +01003320 if (verify & SSL_VERIFY_PEER) {
Emeric Brunef42d922012-10-11 16:11:36 +02003321 if (srv->ssl_ctx.ca_file) {
3322 /* load CAfile to verify */
3323 if (!SSL_CTX_load_verify_locations(srv->ssl_ctx.ctx, srv->ssl_ctx.ca_file, NULL)) {
Willy Tarreau07ba08b2014-02-16 19:22:08 +01003324 Alert("Proxy '%s', server '%s' [%s:%d] unable to load CA file '%s'.\n",
Emeric Brunef42d922012-10-11 16:11:36 +02003325 curproxy->id, srv->id,
3326 srv->conf.file, srv->conf.line, srv->ssl_ctx.ca_file);
3327 cfgerr++;
3328 }
3329 }
Emeric Brun850efd52014-01-29 12:24:34 +01003330 else {
3331 if (global.ssl_server_verify == SSL_SERVER_VERIFY_REQUIRED)
Willy Tarreau07ba08b2014-02-16 19:22:08 +01003332 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 +01003333 curproxy->id, srv->id,
3334 srv->conf.file, srv->conf.line);
3335 else
Willy Tarreau07ba08b2014-02-16 19:22:08 +01003336 Alert("Proxy '%s', server '%s' [%s:%d] verify is enabled but no CA file specified.\n",
Emeric Brun850efd52014-01-29 12:24:34 +01003337 curproxy->id, srv->id,
3338 srv->conf.file, srv->conf.line);
3339 cfgerr++;
3340 }
Emeric Brunef42d922012-10-11 16:11:36 +02003341#ifdef X509_V_FLAG_CRL_CHECK
3342 if (srv->ssl_ctx.crl_file) {
3343 X509_STORE *store = SSL_CTX_get_cert_store(srv->ssl_ctx.ctx);
3344
3345 if (!store || !X509_STORE_load_locations(store, srv->ssl_ctx.crl_file, NULL)) {
Willy Tarreau07ba08b2014-02-16 19:22:08 +01003346 Alert("Proxy '%s', server '%s' [%s:%d] unable to configure CRL file '%s'.\n",
Emeric Brunef42d922012-10-11 16:11:36 +02003347 curproxy->id, srv->id,
3348 srv->conf.file, srv->conf.line, srv->ssl_ctx.crl_file);
3349 cfgerr++;
3350 }
3351 else {
3352 X509_STORE_set_flags(store, X509_V_FLAG_CRL_CHECK|X509_V_FLAG_CRL_CHECK_ALL);
3353 }
3354 }
3355#endif
3356 }
3357
Willy Tarreauef934602016-12-22 23:12:01 +01003358 if (global_ssl.life_time)
3359 SSL_CTX_set_timeout(srv->ssl_ctx.ctx, global_ssl.life_time);
Emeric Brun4f65bff2012-11-16 15:11:00 +01003360
Emeric Brun94324a42012-10-11 14:00:19 +02003361 SSL_CTX_set_session_cache_mode(srv->ssl_ctx.ctx, SSL_SESS_CACHE_OFF);
3362 if (srv->ssl_ctx.ciphers &&
3363 !SSL_CTX_set_cipher_list(srv->ssl_ctx.ctx, srv->ssl_ctx.ciphers)) {
3364 Alert("Proxy '%s', server '%s' [%s:%d] : unable to set SSL cipher list to '%s'.\n",
3365 curproxy->id, srv->id,
3366 srv->conf.file, srv->conf.line, srv->ssl_ctx.ciphers);
3367 cfgerr++;
3368 }
3369
3370 return cfgerr;
3371}
3372
Willy Tarreau2a65ff02012-09-13 17:54:29 +02003373/* Walks down the two trees in bind_conf and prepares all certs. The pointer may
Emeric Brunfc0421f2012-09-07 17:30:07 +02003374 * be NULL, in which case nothing is done. Returns the number of errors
3375 * encountered.
3376 */
Willy Tarreau03209342016-12-22 17:08:28 +01003377int ssl_sock_prepare_all_ctx(struct bind_conf *bind_conf)
Emeric Brunfc0421f2012-09-07 17:30:07 +02003378{
3379 struct ebmb_node *node;
3380 struct sni_ctx *sni;
3381 int err = 0;
3382
Willy Tarreau2a65ff02012-09-13 17:54:29 +02003383 if (!bind_conf || !bind_conf->is_ssl)
Emeric Brunfc0421f2012-09-07 17:30:07 +02003384 return 0;
3385
Willy Tarreaufce03112015-01-15 21:32:40 +01003386 /* Automatic memory computations need to know we use SSL there */
3387 global.ssl_used_frontend = 1;
3388
Emeric Brun0bed9942014-10-30 19:25:24 +01003389 if (bind_conf->default_ctx)
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003390 err += ssl_sock_prepare_ctx(bind_conf, bind_conf->default_ssl_conf, bind_conf->default_ctx);
Emeric Brun0bed9942014-10-30 19:25:24 +01003391
Willy Tarreau2a65ff02012-09-13 17:54:29 +02003392 node = ebmb_first(&bind_conf->sni_ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02003393 while (node) {
3394 sni = ebmb_entry(node, struct sni_ctx, name);
Emeric Brun0bed9942014-10-30 19:25:24 +01003395 if (!sni->order && sni->ctx != bind_conf->default_ctx)
3396 /* only initialize the CTX on its first occurrence and
3397 if it is not the default_ctx */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003398 err += ssl_sock_prepare_ctx(bind_conf, sni->conf, sni->ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02003399 node = ebmb_next(node);
3400 }
3401
Willy Tarreau2a65ff02012-09-13 17:54:29 +02003402 node = ebmb_first(&bind_conf->sni_w_ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02003403 while (node) {
3404 sni = ebmb_entry(node, struct sni_ctx, name);
Emeric Brun0bed9942014-10-30 19:25:24 +01003405 if (!sni->order && sni->ctx != bind_conf->default_ctx)
3406 /* only initialize the CTX on its first occurrence and
3407 if it is not the default_ctx */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003408 err += ssl_sock_prepare_ctx(bind_conf, sni->conf, sni->ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02003409 node = ebmb_next(node);
3410 }
3411 return err;
3412}
3413
Willy Tarreau55d37912016-12-21 23:38:39 +01003414/* Prepares all the contexts for a bind_conf and allocates the shared SSL
3415 * context if needed. Returns < 0 on error, 0 on success. The warnings and
3416 * alerts are directly emitted since the rest of the stack does it below.
3417 */
3418int ssl_sock_prepare_bind_conf(struct bind_conf *bind_conf)
3419{
3420 struct proxy *px = bind_conf->frontend;
3421 int alloc_ctx;
3422 int err;
3423
3424 if (!bind_conf->is_ssl) {
3425 if (bind_conf->default_ctx) {
3426 Warning("Proxy '%s': A certificate was specified but SSL was not enabled on bind '%s' at [%s:%d] (use 'ssl').\n",
3427 px->id, bind_conf->arg, bind_conf->file, bind_conf->line);
3428 }
3429 return 0;
3430 }
3431 if (!bind_conf->default_ctx) {
3432 Alert("Proxy '%s': no SSL certificate specified for bind '%s' at [%s:%d] (use 'crt').\n",
3433 px->id, bind_conf->arg, bind_conf->file, bind_conf->line);
3434 return -1;
3435 }
3436
Willy Tarreauef934602016-12-22 23:12:01 +01003437 alloc_ctx = shared_context_init(global.tune.sslcachesize, (!global_ssl.private_cache && (global.nbproc > 1)) ? 1 : 0);
Willy Tarreau55d37912016-12-21 23:38:39 +01003438 if (alloc_ctx < 0) {
3439 if (alloc_ctx == SHCTX_E_INIT_LOCK)
3440 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");
3441 else
3442 Alert("Unable to allocate SSL session cache.\n");
3443 return -1;
3444 }
3445
3446 err = 0;
3447 /* initialize all certificate contexts */
3448 err += ssl_sock_prepare_all_ctx(bind_conf);
3449
3450 /* initialize CA variables if the certificates generation is enabled */
3451 err += ssl_sock_load_ca(bind_conf);
3452
3453 return -err;
3454}
Christopher Faulet77fe80c2015-07-29 13:02:40 +02003455
3456/* release ssl context allocated for servers. */
3457void ssl_sock_free_srv_ctx(struct server *srv)
3458{
3459 if (srv->ssl_ctx.ctx)
3460 SSL_CTX_free(srv->ssl_ctx.ctx);
3461}
3462
Willy Tarreau2a65ff02012-09-13 17:54:29 +02003463/* Walks down the two trees in bind_conf and frees all the certs. The pointer may
Emeric Brunfc0421f2012-09-07 17:30:07 +02003464 * be NULL, in which case nothing is done. The default_ctx is nullified too.
3465 */
Willy Tarreau2a65ff02012-09-13 17:54:29 +02003466void ssl_sock_free_all_ctx(struct bind_conf *bind_conf)
Emeric Brunfc0421f2012-09-07 17:30:07 +02003467{
3468 struct ebmb_node *node, *back;
3469 struct sni_ctx *sni;
3470
Willy Tarreau2a65ff02012-09-13 17:54:29 +02003471 if (!bind_conf || !bind_conf->is_ssl)
Emeric Brunfc0421f2012-09-07 17:30:07 +02003472 return;
3473
Willy Tarreau2a65ff02012-09-13 17:54:29 +02003474 node = ebmb_first(&bind_conf->sni_ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02003475 while (node) {
3476 sni = ebmb_entry(node, struct sni_ctx, name);
3477 back = ebmb_next(node);
3478 ebmb_delete(node);
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003479 if (!sni->order) { /* only free the CTX on its first occurrence */
Emeric Brunfc0421f2012-09-07 17:30:07 +02003480 SSL_CTX_free(sni->ctx);
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003481 ssl_sock_free_ssl_conf(sni->conf);
3482 free(sni->conf);
3483 sni->conf = NULL;
3484 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02003485 free(sni);
3486 node = back;
3487 }
3488
Willy Tarreau2a65ff02012-09-13 17:54:29 +02003489 node = ebmb_first(&bind_conf->sni_w_ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02003490 while (node) {
3491 sni = ebmb_entry(node, struct sni_ctx, name);
3492 back = ebmb_next(node);
3493 ebmb_delete(node);
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003494 if (!sni->order) { /* only free the CTX on its first occurrence */
Emeric Brunfc0421f2012-09-07 17:30:07 +02003495 SSL_CTX_free(sni->ctx);
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003496 ssl_sock_free_ssl_conf(sni->conf);
3497 free(sni->conf);
3498 sni->conf = NULL;
3499 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02003500 free(sni);
3501 node = back;
3502 }
3503
Willy Tarreau2a65ff02012-09-13 17:54:29 +02003504 bind_conf->default_ctx = NULL;
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003505 bind_conf->default_ssl_conf = NULL;
Emeric Brune1f38db2012-09-03 20:36:47 +02003506}
3507
Willy Tarreau795cdab2016-12-22 17:30:54 +01003508/* Destroys all the contexts for a bind_conf. This is used during deinit(). */
3509void ssl_sock_destroy_bind_conf(struct bind_conf *bind_conf)
3510{
3511 ssl_sock_free_ca(bind_conf);
3512 ssl_sock_free_all_ctx(bind_conf);
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003513 ssl_sock_free_ssl_conf(&bind_conf->ssl_conf);
Willy Tarreau795cdab2016-12-22 17:30:54 +01003514 free(bind_conf->ca_sign_file);
3515 free(bind_conf->ca_sign_pass);
Willy Tarreau795cdab2016-12-22 17:30:54 +01003516 if (bind_conf->keys_ref) {
3517 free(bind_conf->keys_ref->filename);
3518 free(bind_conf->keys_ref->tlskeys);
3519 LIST_DEL(&bind_conf->keys_ref->list);
3520 free(bind_conf->keys_ref);
3521 }
3522 bind_conf->keys_ref = NULL;
Willy Tarreau795cdab2016-12-22 17:30:54 +01003523 bind_conf->ca_sign_pass = NULL;
3524 bind_conf->ca_sign_file = NULL;
Willy Tarreau795cdab2016-12-22 17:30:54 +01003525}
3526
Christopher Faulet31af49d2015-06-09 17:29:50 +02003527/* Load CA cert file and private key used to generate certificates */
3528int
Willy Tarreau03209342016-12-22 17:08:28 +01003529ssl_sock_load_ca(struct bind_conf *bind_conf)
Christopher Faulet31af49d2015-06-09 17:29:50 +02003530{
Willy Tarreau03209342016-12-22 17:08:28 +01003531 struct proxy *px = bind_conf->frontend;
Christopher Faulet31af49d2015-06-09 17:29:50 +02003532 FILE *fp;
3533 X509 *cacert = NULL;
3534 EVP_PKEY *capkey = NULL;
3535 int err = 0;
3536
3537 if (!bind_conf || !bind_conf->generate_certs)
3538 return err;
3539
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +01003540#if (defined SSL_CTRL_SET_TLSEXT_HOSTNAME && !defined SSL_NO_GENERATE_CERTIFICATES)
Willy Tarreauef934602016-12-22 23:12:01 +01003541 if (global_ssl.ctx_cache)
3542 ssl_ctx_lru_tree = lru64_new(global_ssl.ctx_cache);
Christopher Fauletd2cab922015-07-28 16:03:47 +02003543 ssl_ctx_lru_seed = (unsigned int)time(NULL);
Willy Tarreaua84c2672015-10-09 12:10:13 +02003544#endif
Christopher Fauletd2cab922015-07-28 16:03:47 +02003545
Christopher Faulet31af49d2015-06-09 17:29:50 +02003546 if (!bind_conf->ca_sign_file) {
3547 Alert("Proxy '%s': cannot enable certificate generation, "
3548 "no CA certificate File configured at [%s:%d].\n",
3549 px->id, bind_conf->file, bind_conf->line);
Christopher Faulet31af49d2015-06-09 17:29:50 +02003550 goto load_error;
Christopher Fauletc6f02fb2015-10-09 10:53:31 +02003551 }
Christopher Faulet31af49d2015-06-09 17:29:50 +02003552
3553 /* read in the CA certificate */
3554 if (!(fp = fopen(bind_conf->ca_sign_file, "r"))) {
3555 Alert("Proxy '%s': Failed to read CA certificate file '%s' at [%s:%d].\n",
3556 px->id, bind_conf->ca_sign_file, bind_conf->file, bind_conf->line);
Christopher Faulet31af49d2015-06-09 17:29:50 +02003557 goto load_error;
3558 }
3559 if (!(cacert = PEM_read_X509(fp, NULL, NULL, NULL))) {
3560 Alert("Proxy '%s': Failed to read CA certificate file '%s' at [%s:%d].\n",
3561 px->id, bind_conf->ca_sign_file, bind_conf->file, bind_conf->line);
Christopher Fauletc6f02fb2015-10-09 10:53:31 +02003562 goto read_error;
Christopher Faulet31af49d2015-06-09 17:29:50 +02003563 }
Christopher Fauletc6f02fb2015-10-09 10:53:31 +02003564 rewind(fp);
Christopher Faulet31af49d2015-06-09 17:29:50 +02003565 if (!(capkey = PEM_read_PrivateKey(fp, NULL, NULL, bind_conf->ca_sign_pass))) {
3566 Alert("Proxy '%s': Failed to read CA private key file '%s' at [%s:%d].\n",
3567 px->id, bind_conf->ca_sign_file, bind_conf->file, bind_conf->line);
Christopher Fauletc6f02fb2015-10-09 10:53:31 +02003568 goto read_error;
Christopher Faulet31af49d2015-06-09 17:29:50 +02003569 }
Christopher Faulet31af49d2015-06-09 17:29:50 +02003570
Christopher Fauletc6f02fb2015-10-09 10:53:31 +02003571 fclose (fp);
Christopher Faulet31af49d2015-06-09 17:29:50 +02003572 bind_conf->ca_sign_cert = cacert;
3573 bind_conf->ca_sign_pkey = capkey;
3574 return err;
3575
Christopher Fauletc6f02fb2015-10-09 10:53:31 +02003576 read_error:
3577 fclose (fp);
Christopher Faulet31af49d2015-06-09 17:29:50 +02003578 if (capkey) EVP_PKEY_free(capkey);
3579 if (cacert) X509_free(cacert);
Christopher Fauletc6f02fb2015-10-09 10:53:31 +02003580 load_error:
3581 bind_conf->generate_certs = 0;
3582 err++;
Christopher Faulet31af49d2015-06-09 17:29:50 +02003583 return err;
3584}
3585
3586/* Release CA cert and private key used to generate certificated */
3587void
3588ssl_sock_free_ca(struct bind_conf *bind_conf)
3589{
3590 if (!bind_conf)
3591 return;
3592
3593 if (bind_conf->ca_sign_pkey)
3594 EVP_PKEY_free(bind_conf->ca_sign_pkey);
3595 if (bind_conf->ca_sign_cert)
3596 X509_free(bind_conf->ca_sign_cert);
Willy Tarreau94ff03a2016-12-22 17:57:46 +01003597 bind_conf->ca_sign_pkey = NULL;
3598 bind_conf->ca_sign_cert = NULL;
Christopher Faulet31af49d2015-06-09 17:29:50 +02003599}
3600
Emeric Brun46591952012-05-18 15:47:34 +02003601/*
3602 * This function is called if SSL * context is not yet allocated. The function
3603 * is designed to be called before any other data-layer operation and sets the
3604 * handshake flag on the connection. It is safe to call it multiple times.
3605 * It returns 0 on success and -1 in error case.
3606 */
3607static int ssl_sock_init(struct connection *conn)
3608{
3609 /* already initialized */
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02003610 if (conn->xprt_ctx)
Emeric Brun46591952012-05-18 15:47:34 +02003611 return 0;
3612
Willy Tarreau3c728722014-01-23 13:50:42 +01003613 if (!conn_ctrl_ready(conn))
Willy Tarreauf79c8172013-10-21 16:30:56 +02003614 return 0;
3615
Willy Tarreau20879a02012-12-03 16:32:10 +01003616 if (global.maxsslconn && sslconns >= global.maxsslconn) {
3617 conn->err_code = CO_ER_SSL_TOO_MANY;
Willy Tarreau403edff2012-09-06 11:58:37 +02003618 return -1;
Willy Tarreau20879a02012-12-03 16:32:10 +01003619 }
Willy Tarreau403edff2012-09-06 11:58:37 +02003620
Emeric Brun46591952012-05-18 15:47:34 +02003621 /* If it is in client mode initiate SSL session
3622 in connect state otherwise accept state */
Willy Tarreau3fdb3662012-11-12 00:42:33 +01003623 if (objt_server(conn->target)) {
Willy Tarreaufba03cd2014-11-13 13:48:58 +01003624 int may_retry = 1;
3625
3626 retry_connect:
Emeric Brun46591952012-05-18 15:47:34 +02003627 /* Alloc a new SSL session ctx */
Willy Tarreau3fdb3662012-11-12 00:42:33 +01003628 conn->xprt_ctx = SSL_new(objt_server(conn->target)->ssl_ctx.ctx);
Willy Tarreau20879a02012-12-03 16:32:10 +01003629 if (!conn->xprt_ctx) {
Willy Tarreaufba03cd2014-11-13 13:48:58 +01003630 if (may_retry--) {
3631 pool_gc2();
3632 goto retry_connect;
3633 }
Willy Tarreau20879a02012-12-03 16:32:10 +01003634 conn->err_code = CO_ER_SSL_NO_MEM;
Emeric Brun46591952012-05-18 15:47:34 +02003635 return -1;
Willy Tarreau20879a02012-12-03 16:32:10 +01003636 }
Emeric Brun46591952012-05-18 15:47:34 +02003637
Emeric Brun46591952012-05-18 15:47:34 +02003638 /* set fd on SSL session context */
Emeric Brun55476152014-11-12 17:35:37 +01003639 if (!SSL_set_fd(conn->xprt_ctx, conn->t.sock.fd)) {
3640 SSL_free(conn->xprt_ctx);
3641 conn->xprt_ctx = NULL;
Willy Tarreaufba03cd2014-11-13 13:48:58 +01003642 if (may_retry--) {
3643 pool_gc2();
3644 goto retry_connect;
3645 }
Emeric Brun55476152014-11-12 17:35:37 +01003646 conn->err_code = CO_ER_SSL_NO_MEM;
3647 return -1;
3648 }
Emeric Brun46591952012-05-18 15:47:34 +02003649
Evan Broderbe554312013-06-27 00:05:25 -07003650 /* set connection pointer */
Emeric Brun55476152014-11-12 17:35:37 +01003651 if (!SSL_set_app_data(conn->xprt_ctx, conn)) {
3652 SSL_free(conn->xprt_ctx);
3653 conn->xprt_ctx = NULL;
Willy Tarreaufba03cd2014-11-13 13:48:58 +01003654 if (may_retry--) {
3655 pool_gc2();
3656 goto retry_connect;
3657 }
Emeric Brun55476152014-11-12 17:35:37 +01003658 conn->err_code = CO_ER_SSL_NO_MEM;
3659 return -1;
3660 }
3661
3662 SSL_set_connect_state(conn->xprt_ctx);
3663 if (objt_server(conn->target)->ssl_ctx.reused_sess) {
3664 if(!SSL_set_session(conn->xprt_ctx, objt_server(conn->target)->ssl_ctx.reused_sess)) {
3665 SSL_SESSION_free(objt_server(conn->target)->ssl_ctx.reused_sess);
3666 objt_server(conn->target)->ssl_ctx.reused_sess = NULL;
3667 }
3668 }
Evan Broderbe554312013-06-27 00:05:25 -07003669
Emeric Brun46591952012-05-18 15:47:34 +02003670 /* leave init state and start handshake */
Willy Tarreau05737472012-09-04 08:03:39 +02003671 conn->flags |= CO_FL_SSL_WAIT_HS | CO_FL_WAIT_L6_CONN;
Willy Tarreau403edff2012-09-06 11:58:37 +02003672
3673 sslconns++;
Willy Tarreau71b734c2014-01-28 15:19:44 +01003674 totalsslconns++;
Emeric Brun46591952012-05-18 15:47:34 +02003675 return 0;
3676 }
Willy Tarreau3fdb3662012-11-12 00:42:33 +01003677 else if (objt_listener(conn->target)) {
Willy Tarreaufba03cd2014-11-13 13:48:58 +01003678 int may_retry = 1;
3679
3680 retry_accept:
Emeric Brun46591952012-05-18 15:47:34 +02003681 /* Alloc a new SSL session ctx */
Willy Tarreau3fdb3662012-11-12 00:42:33 +01003682 conn->xprt_ctx = SSL_new(objt_listener(conn->target)->bind_conf->default_ctx);
Willy Tarreau20879a02012-12-03 16:32:10 +01003683 if (!conn->xprt_ctx) {
Willy Tarreaufba03cd2014-11-13 13:48:58 +01003684 if (may_retry--) {
3685 pool_gc2();
3686 goto retry_accept;
3687 }
Willy Tarreau20879a02012-12-03 16:32:10 +01003688 conn->err_code = CO_ER_SSL_NO_MEM;
Emeric Brun46591952012-05-18 15:47:34 +02003689 return -1;
Willy Tarreau20879a02012-12-03 16:32:10 +01003690 }
Emeric Brun46591952012-05-18 15:47:34 +02003691
Emeric Brun46591952012-05-18 15:47:34 +02003692 /* set fd on SSL session context */
Emeric Brun55476152014-11-12 17:35:37 +01003693 if (!SSL_set_fd(conn->xprt_ctx, conn->t.sock.fd)) {
3694 SSL_free(conn->xprt_ctx);
3695 conn->xprt_ctx = NULL;
Willy Tarreaufba03cd2014-11-13 13:48:58 +01003696 if (may_retry--) {
3697 pool_gc2();
3698 goto retry_accept;
3699 }
Emeric Brun55476152014-11-12 17:35:37 +01003700 conn->err_code = CO_ER_SSL_NO_MEM;
3701 return -1;
3702 }
Emeric Brun46591952012-05-18 15:47:34 +02003703
Emeric Brune1f38db2012-09-03 20:36:47 +02003704 /* set connection pointer */
Emeric Brun55476152014-11-12 17:35:37 +01003705 if (!SSL_set_app_data(conn->xprt_ctx, conn)) {
3706 SSL_free(conn->xprt_ctx);
3707 conn->xprt_ctx = NULL;
Willy Tarreaufba03cd2014-11-13 13:48:58 +01003708 if (may_retry--) {
3709 pool_gc2();
3710 goto retry_accept;
3711 }
Emeric Brun55476152014-11-12 17:35:37 +01003712 conn->err_code = CO_ER_SSL_NO_MEM;
3713 return -1;
3714 }
3715
3716 SSL_set_accept_state(conn->xprt_ctx);
Emeric Brune1f38db2012-09-03 20:36:47 +02003717
Emeric Brun46591952012-05-18 15:47:34 +02003718 /* leave init state and start handshake */
Willy Tarreau05737472012-09-04 08:03:39 +02003719 conn->flags |= CO_FL_SSL_WAIT_HS | CO_FL_WAIT_L6_CONN;
Willy Tarreau403edff2012-09-06 11:58:37 +02003720
3721 sslconns++;
Willy Tarreau71b734c2014-01-28 15:19:44 +01003722 totalsslconns++;
Emeric Brun46591952012-05-18 15:47:34 +02003723 return 0;
3724 }
3725 /* don't know how to handle such a target */
Willy Tarreau20879a02012-12-03 16:32:10 +01003726 conn->err_code = CO_ER_SSL_NO_TARGET;
Emeric Brun46591952012-05-18 15:47:34 +02003727 return -1;
3728}
3729
3730
3731/* This is the callback which is used when an SSL handshake is pending. It
3732 * updates the FD status if it wants some polling before being called again.
3733 * It returns 0 if it fails in a fatal way or needs to poll to go further,
3734 * otherwise it returns non-zero and removes itself from the connection's
3735 * flags (the bit is provided in <flag> by the caller).
3736 */
3737int ssl_sock_handshake(struct connection *conn, unsigned int flag)
3738{
3739 int ret;
3740
Willy Tarreau3c728722014-01-23 13:50:42 +01003741 if (!conn_ctrl_ready(conn))
Willy Tarreauf79c8172013-10-21 16:30:56 +02003742 return 0;
3743
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02003744 if (!conn->xprt_ctx)
Emeric Brun46591952012-05-18 15:47:34 +02003745 goto out_error;
3746
Emeric Brun674b7432012-11-08 19:21:55 +01003747 /* If we use SSL_do_handshake to process a reneg initiated by
3748 * the remote peer, it sometimes returns SSL_ERROR_SSL.
3749 * Usually SSL_write and SSL_read are used and process implicitly
3750 * the reneg handshake.
3751 * Here we use SSL_peek as a workaround for reneg.
3752 */
3753 if ((conn->flags & CO_FL_CONNECTED) && SSL_renegotiate_pending(conn->xprt_ctx)) {
3754 char c;
3755
3756 ret = SSL_peek(conn->xprt_ctx, &c, 1);
3757 if (ret <= 0) {
3758 /* handshake may have not been completed, let's find why */
3759 ret = SSL_get_error(conn->xprt_ctx, ret);
3760 if (ret == SSL_ERROR_WANT_WRITE) {
3761 /* SSL handshake needs to write, L4 connection may not be ready */
3762 __conn_sock_stop_recv(conn);
Willy Tarreaue1f50c42014-01-22 20:02:06 +01003763 __conn_sock_want_send(conn);
3764 fd_cant_send(conn->t.sock.fd);
Emeric Brun674b7432012-11-08 19:21:55 +01003765 return 0;
3766 }
3767 else if (ret == SSL_ERROR_WANT_READ) {
3768 /* handshake may have been completed but we have
3769 * no more data to read.
3770 */
3771 if (!SSL_renegotiate_pending(conn->xprt_ctx)) {
3772 ret = 1;
3773 goto reneg_ok;
3774 }
3775 /* SSL handshake needs to read, L4 connection is ready */
3776 if (conn->flags & CO_FL_WAIT_L4_CONN)
3777 conn->flags &= ~CO_FL_WAIT_L4_CONN;
3778 __conn_sock_stop_send(conn);
Willy Tarreaue1f50c42014-01-22 20:02:06 +01003779 __conn_sock_want_recv(conn);
3780 fd_cant_recv(conn->t.sock.fd);
Emeric Brun674b7432012-11-08 19:21:55 +01003781 return 0;
3782 }
3783 else if (ret == SSL_ERROR_SYSCALL) {
3784 /* if errno is null, then connection was successfully established */
3785 if (!errno && conn->flags & CO_FL_WAIT_L4_CONN)
3786 conn->flags &= ~CO_FL_WAIT_L4_CONN;
Willy Tarreau20879a02012-12-03 16:32:10 +01003787 if (!conn->err_code) {
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +01003788#ifdef OPENSSL_NO_HEARTBEATS /* BoringSSL */
3789 conn->err_code = CO_ER_SSL_HANDSHAKE;
3790#else
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02003791 int empty_handshake;
Luca Pizzamiglio578b1692016-12-12 10:56:56 +01003792#if (OPENSSL_VERSION_NUMBER >= 0x1010000fL) && !defined(LIBRESSL_VERSION_NUMBER)
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02003793 OSSL_HANDSHAKE_STATE state = SSL_get_state((SSL *)conn->xprt_ctx);
3794 empty_handshake = state == TLS_ST_BEFORE;
3795#else
3796 empty_handshake = !((SSL *)conn->xprt_ctx)->packet_length;
3797#endif
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02003798 if (empty_handshake) {
Emeric Brun29f037d2014-04-25 19:05:36 +02003799 if (!errno) {
3800 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
3801 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
3802 else
3803 conn->err_code = CO_ER_SSL_EMPTY;
3804 }
3805 else {
3806 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
3807 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
3808 else
3809 conn->err_code = CO_ER_SSL_ABORT;
3810 }
3811 }
3812 else {
3813 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
3814 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
Willy Tarreau20879a02012-12-03 16:32:10 +01003815 else
Emeric Brun29f037d2014-04-25 19:05:36 +02003816 conn->err_code = CO_ER_SSL_HANDSHAKE;
3817 }
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +01003818#endif
Willy Tarreau20879a02012-12-03 16:32:10 +01003819 }
Emeric Brun674b7432012-11-08 19:21:55 +01003820 goto out_error;
3821 }
3822 else {
3823 /* Fail on all other handshake errors */
3824 /* Note: OpenSSL may leave unread bytes in the socket's
3825 * buffer, causing an RST to be emitted upon close() on
3826 * TCP sockets. We first try to drain possibly pending
3827 * data to avoid this as much as possible.
3828 */
Willy Tarreaud85c4852015-03-13 00:40:28 +01003829 conn_sock_drain(conn);
Willy Tarreau20879a02012-12-03 16:32:10 +01003830 if (!conn->err_code)
Willy Tarreauf51c6982014-04-25 20:02:39 +02003831 conn->err_code = (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT) ?
3832 CO_ER_SSL_KILLED_HB : CO_ER_SSL_HANDSHAKE;
Emeric Brun674b7432012-11-08 19:21:55 +01003833 goto out_error;
3834 }
3835 }
3836 /* read some data: consider handshake completed */
3837 goto reneg_ok;
3838 }
3839
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02003840 ret = SSL_do_handshake(conn->xprt_ctx);
Emeric Brun46591952012-05-18 15:47:34 +02003841 if (ret != 1) {
3842 /* handshake did not complete, let's find why */
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02003843 ret = SSL_get_error(conn->xprt_ctx, ret);
Emeric Brun46591952012-05-18 15:47:34 +02003844
3845 if (ret == SSL_ERROR_WANT_WRITE) {
3846 /* SSL handshake needs to write, L4 connection may not be ready */
3847 __conn_sock_stop_recv(conn);
Willy Tarreaue1f50c42014-01-22 20:02:06 +01003848 __conn_sock_want_send(conn);
3849 fd_cant_send(conn->t.sock.fd);
Emeric Brun46591952012-05-18 15:47:34 +02003850 return 0;
3851 }
3852 else if (ret == SSL_ERROR_WANT_READ) {
3853 /* SSL handshake needs to read, L4 connection is ready */
3854 if (conn->flags & CO_FL_WAIT_L4_CONN)
3855 conn->flags &= ~CO_FL_WAIT_L4_CONN;
3856 __conn_sock_stop_send(conn);
Willy Tarreaue1f50c42014-01-22 20:02:06 +01003857 __conn_sock_want_recv(conn);
3858 fd_cant_recv(conn->t.sock.fd);
Emeric Brun46591952012-05-18 15:47:34 +02003859 return 0;
3860 }
Willy Tarreau89230192012-09-28 20:22:13 +02003861 else if (ret == SSL_ERROR_SYSCALL) {
3862 /* if errno is null, then connection was successfully established */
3863 if (!errno && conn->flags & CO_FL_WAIT_L4_CONN)
3864 conn->flags &= ~CO_FL_WAIT_L4_CONN;
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +01003865 if (!conn->err_code) {
3866#ifdef OPENSSL_NO_HEARTBEATS /* BoringSSL */
3867 conn->err_code = CO_ER_SSL_HANDSHAKE;
3868#else
3869 int empty_handshake;
Luca Pizzamiglio578b1692016-12-12 10:56:56 +01003870#if (OPENSSL_VERSION_NUMBER >= 0x1010000fL) && !defined(LIBRESSL_VERSION_NUMBER)
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +01003871 OSSL_HANDSHAKE_STATE state = SSL_get_state((SSL *)conn->xprt_ctx);
3872 empty_handshake = state == TLS_ST_BEFORE;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02003873#else
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +01003874 empty_handshake = !((SSL *)conn->xprt_ctx)->packet_length;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02003875#endif
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +01003876 if (empty_handshake) {
3877 if (!errno) {
3878 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
3879 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
3880 else
3881 conn->err_code = CO_ER_SSL_EMPTY;
3882 }
3883 else {
3884 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
3885 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
3886 else
3887 conn->err_code = CO_ER_SSL_ABORT;
3888 }
Emeric Brun29f037d2014-04-25 19:05:36 +02003889 }
3890 else {
3891 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
3892 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
3893 else
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +01003894 conn->err_code = CO_ER_SSL_HANDSHAKE;
Emeric Brun29f037d2014-04-25 19:05:36 +02003895 }
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +01003896#endif
Emeric Brun29f037d2014-04-25 19:05:36 +02003897 }
Willy Tarreau89230192012-09-28 20:22:13 +02003898 goto out_error;
3899 }
Emeric Brun46591952012-05-18 15:47:34 +02003900 else {
3901 /* Fail on all other handshake errors */
Willy Tarreau566dc552012-10-19 20:52:18 +02003902 /* Note: OpenSSL may leave unread bytes in the socket's
3903 * buffer, causing an RST to be emitted upon close() on
3904 * TCP sockets. We first try to drain possibly pending
3905 * data to avoid this as much as possible.
3906 */
Willy Tarreaud85c4852015-03-13 00:40:28 +01003907 conn_sock_drain(conn);
Willy Tarreau20879a02012-12-03 16:32:10 +01003908 if (!conn->err_code)
Willy Tarreauf51c6982014-04-25 20:02:39 +02003909 conn->err_code = (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT) ?
3910 CO_ER_SSL_KILLED_HB : CO_ER_SSL_HANDSHAKE;
Emeric Brun46591952012-05-18 15:47:34 +02003911 goto out_error;
3912 }
3913 }
3914
Emeric Brun674b7432012-11-08 19:21:55 +01003915reneg_ok:
Emeric Brun46591952012-05-18 15:47:34 +02003916 /* Handshake succeeded */
Willy Tarreau0c9c2722014-05-28 12:28:58 +02003917 if (!SSL_session_reused(conn->xprt_ctx)) {
3918 if (objt_server(conn->target)) {
3919 update_freq_ctr(&global.ssl_be_keys_per_sec, 1);
3920 if (global.ssl_be_keys_per_sec.curr_ctr > global.ssl_be_keys_max)
3921 global.ssl_be_keys_max = global.ssl_be_keys_per_sec.curr_ctr;
3922
Emeric Brun46591952012-05-18 15:47:34 +02003923 /* check if session was reused, if not store current session on server for reuse */
Willy Tarreau30fd4bd2016-12-22 21:54:21 +01003924 if (objt_server(conn->target)->ssl_ctx.reused_sess) {
Willy Tarreau3fdb3662012-11-12 00:42:33 +01003925 SSL_SESSION_free(objt_server(conn->target)->ssl_ctx.reused_sess);
Willy Tarreau30fd4bd2016-12-22 21:54:21 +01003926 objt_server(conn->target)->ssl_ctx.reused_sess = NULL;
3927 }
Emeric Brun46591952012-05-18 15:47:34 +02003928
Willy Tarreau2a3fb1c2015-02-05 16:47:07 +01003929 if (!(objt_server(conn->target)->ssl_ctx.options & SRV_SSL_O_NO_REUSE))
3930 objt_server(conn->target)->ssl_ctx.reused_sess = SSL_get1_session(conn->xprt_ctx);
Emeric Brun46591952012-05-18 15:47:34 +02003931 }
Willy Tarreau0c9c2722014-05-28 12:28:58 +02003932 else {
3933 update_freq_ctr(&global.ssl_fe_keys_per_sec, 1);
3934 if (global.ssl_fe_keys_per_sec.curr_ctr > global.ssl_fe_keys_max)
3935 global.ssl_fe_keys_max = global.ssl_fe_keys_per_sec.curr_ctr;
3936 }
Emeric Brun46591952012-05-18 15:47:34 +02003937 }
3938
3939 /* The connection is now established at both layers, it's time to leave */
3940 conn->flags &= ~(flag | CO_FL_WAIT_L4_CONN | CO_FL_WAIT_L6_CONN);
3941 return 1;
3942
3943 out_error:
Emeric Brun644cde02012-12-14 11:21:13 +01003944 /* Clear openssl global errors stack */
Thierry FOURNIER / OZON.IO8b068c22016-10-10 11:59:50 +02003945 ssl_sock_dump_errors(conn);
Emeric Brun644cde02012-12-14 11:21:13 +01003946 ERR_clear_error();
3947
Emeric Brun9fa89732012-10-04 17:09:56 +02003948 /* free resumed session if exists */
Willy Tarreau3fdb3662012-11-12 00:42:33 +01003949 if (objt_server(conn->target) && objt_server(conn->target)->ssl_ctx.reused_sess) {
3950 SSL_SESSION_free(objt_server(conn->target)->ssl_ctx.reused_sess);
3951 objt_server(conn->target)->ssl_ctx.reused_sess = NULL;
Emeric Brun9fa89732012-10-04 17:09:56 +02003952 }
3953
Emeric Brun46591952012-05-18 15:47:34 +02003954 /* Fail on all other handshake errors */
3955 conn->flags |= CO_FL_ERROR;
Willy Tarreau20879a02012-12-03 16:32:10 +01003956 if (!conn->err_code)
3957 conn->err_code = CO_ER_SSL_HANDSHAKE;
Emeric Brun46591952012-05-18 15:47:34 +02003958 return 0;
3959}
3960
3961/* Receive up to <count> bytes from connection <conn>'s socket and store them
Willy Tarreauabf08d92014-01-14 11:31:27 +01003962 * into buffer <buf>. Only one call to recv() is performed, unless the
Emeric Brun46591952012-05-18 15:47:34 +02003963 * buffer wraps, in which case a second call may be performed. The connection's
3964 * flags are updated with whatever special event is detected (error, read0,
3965 * empty). The caller is responsible for taking care of those events and
3966 * avoiding the call if inappropriate. The function does not call the
3967 * connection's polling update function, so the caller is responsible for this.
3968 */
3969static int ssl_sock_to_buf(struct connection *conn, struct buffer *buf, int count)
3970{
3971 int ret, done = 0;
Willy Tarreauabf08d92014-01-14 11:31:27 +01003972 int try;
Emeric Brun46591952012-05-18 15:47:34 +02003973
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02003974 if (!conn->xprt_ctx)
Emeric Brun46591952012-05-18 15:47:34 +02003975 goto out_error;
3976
3977 if (conn->flags & CO_FL_HANDSHAKE)
3978 /* a handshake was requested */
3979 return 0;
3980
Willy Tarreauabf08d92014-01-14 11:31:27 +01003981 /* let's realign the buffer to optimize I/O */
3982 if (buffer_empty(buf))
Emeric Brun46591952012-05-18 15:47:34 +02003983 buf->p = buf->data;
Emeric Brun46591952012-05-18 15:47:34 +02003984
3985 /* read the largest possible block. For this, we perform only one call
3986 * to recv() unless the buffer wraps and we exactly fill the first hunk,
3987 * in which case we accept to do it once again. A new attempt is made on
3988 * EINTR too.
3989 */
Willy Tarreau00b0fb92014-01-17 11:09:40 +01003990 while (count > 0) {
Willy Tarreauabf08d92014-01-14 11:31:27 +01003991 /* first check if we have some room after p+i */
3992 try = buf->data + buf->size - (buf->p + buf->i);
3993 /* otherwise continue between data and p-o */
3994 if (try <= 0) {
3995 try = buf->p - (buf->data + buf->o);
3996 if (try <= 0)
3997 break;
3998 }
3999 if (try > count)
4000 try = count;
4001
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02004002 ret = SSL_read(conn->xprt_ctx, bi_end(buf), try);
Emeric Brune1f38db2012-09-03 20:36:47 +02004003 if (conn->flags & CO_FL_ERROR) {
4004 /* CO_FL_ERROR may be set by ssl_sock_infocbk */
Emeric Brun644cde02012-12-14 11:21:13 +01004005 goto out_error;
Emeric Brune1f38db2012-09-03 20:36:47 +02004006 }
Emeric Brun46591952012-05-18 15:47:34 +02004007 if (ret > 0) {
4008 buf->i += ret;
4009 done += ret;
4010 if (ret < try)
4011 break;
4012 count -= ret;
Emeric Brun46591952012-05-18 15:47:34 +02004013 }
4014 else if (ret == 0) {
Emeric Brun644cde02012-12-14 11:21:13 +01004015 ret = SSL_get_error(conn->xprt_ctx, ret);
4016 if (ret != SSL_ERROR_ZERO_RETURN) {
Emeric Brun1c646862012-12-14 12:33:41 +01004017 /* error on protocol or underlying transport */
4018 if ((ret != SSL_ERROR_SYSCALL)
4019 || (errno && (errno != EAGAIN)))
4020 conn->flags |= CO_FL_ERROR;
4021
Emeric Brun644cde02012-12-14 11:21:13 +01004022 /* Clear openssl global errors stack */
Thierry FOURNIER / OZON.IO8b068c22016-10-10 11:59:50 +02004023 ssl_sock_dump_errors(conn);
Emeric Brun644cde02012-12-14 11:21:13 +01004024 ERR_clear_error();
4025 }
Emeric Brun46591952012-05-18 15:47:34 +02004026 goto read0;
4027 }
4028 else {
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02004029 ret = SSL_get_error(conn->xprt_ctx, ret);
Emeric Brun46591952012-05-18 15:47:34 +02004030 if (ret == SSL_ERROR_WANT_WRITE) {
Emeric Brun8af8dd12012-11-08 17:56:20 +01004031 /* handshake is running, and it needs to enable write */
Emeric Brun46591952012-05-18 15:47:34 +02004032 conn->flags |= CO_FL_SSL_WAIT_HS;
Emeric Brun8af8dd12012-11-08 17:56:20 +01004033 __conn_sock_want_send(conn);
Emeric Brun46591952012-05-18 15:47:34 +02004034 break;
4035 }
4036 else if (ret == SSL_ERROR_WANT_READ) {
Emeric Brun282a76a2012-11-08 18:02:56 +01004037 if (SSL_renegotiate_pending(conn->xprt_ctx)) {
4038 /* handshake is running, and it may need to re-enable read */
4039 conn->flags |= CO_FL_SSL_WAIT_HS;
4040 __conn_sock_want_recv(conn);
4041 break;
4042 }
Emeric Brun46591952012-05-18 15:47:34 +02004043 /* we need to poll for retry a read later */
Willy Tarreaue1f50c42014-01-22 20:02:06 +01004044 fd_cant_recv(conn->t.sock.fd);
Emeric Brun46591952012-05-18 15:47:34 +02004045 break;
4046 }
4047 /* otherwise it's a real error */
4048 goto out_error;
4049 }
4050 }
4051 return done;
4052
4053 read0:
4054 conn_sock_read0(conn);
4055 return done;
4056 out_error:
Emeric Brun644cde02012-12-14 11:21:13 +01004057 /* Clear openssl global errors stack */
Thierry FOURNIER / OZON.IO8b068c22016-10-10 11:59:50 +02004058 ssl_sock_dump_errors(conn);
Emeric Brun644cde02012-12-14 11:21:13 +01004059 ERR_clear_error();
4060
Emeric Brun46591952012-05-18 15:47:34 +02004061 conn->flags |= CO_FL_ERROR;
4062 return done;
4063}
4064
4065
4066/* Send all pending bytes from buffer <buf> to connection <conn>'s socket.
Willy Tarreau1049b1f2014-02-02 01:51:17 +01004067 * <flags> may contain some CO_SFL_* flags to hint the system about other
4068 * pending data for example, but this flag is ignored at the moment.
Emeric Brun46591952012-05-18 15:47:34 +02004069 * Only one call to send() is performed, unless the buffer wraps, in which case
4070 * a second call may be performed. The connection's flags are updated with
4071 * whatever special event is detected (error, empty). The caller is responsible
4072 * for taking care of those events and avoiding the call if inappropriate. The
4073 * function does not call the connection's polling update function, so the caller
4074 * is responsible for this.
4075 */
4076static int ssl_sock_from_buf(struct connection *conn, struct buffer *buf, int flags)
4077{
4078 int ret, try, done;
4079
4080 done = 0;
4081
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02004082 if (!conn->xprt_ctx)
Emeric Brun46591952012-05-18 15:47:34 +02004083 goto out_error;
4084
4085 if (conn->flags & CO_FL_HANDSHAKE)
4086 /* a handshake was requested */
4087 return 0;
4088
4089 /* send the largest possible block. For this we perform only one call
4090 * to send() unless the buffer wraps and we exactly fill the first hunk,
4091 * in which case we accept to do it once again.
4092 */
4093 while (buf->o) {
Kevin Hestercad82342013-05-30 15:12:41 -07004094 try = bo_contig_data(buf);
Willy Tarreaubfd59462013-02-21 07:46:09 +01004095
Willy Tarreau7bed9452014-02-02 02:00:24 +01004096 if (!(flags & CO_SFL_STREAMER) &&
Willy Tarreau518cedd2014-02-17 15:43:01 +01004097 !(conn->xprt_st & SSL_SOCK_SEND_UNLIMITED) &&
Willy Tarreauef934602016-12-22 23:12:01 +01004098 global_ssl.max_record && try > global_ssl.max_record) {
4099 try = global_ssl.max_record;
Willy Tarreau518cedd2014-02-17 15:43:01 +01004100 }
4101 else {
4102 /* we need to keep the information about the fact that
4103 * we're not limiting the upcoming send(), because if it
4104 * fails, we'll have to retry with at least as many data.
4105 */
4106 conn->xprt_st |= SSL_SOCK_SEND_UNLIMITED;
4107 }
Willy Tarreaubfd59462013-02-21 07:46:09 +01004108
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02004109 ret = SSL_write(conn->xprt_ctx, bo_ptr(buf), try);
Willy Tarreau518cedd2014-02-17 15:43:01 +01004110
Emeric Brune1f38db2012-09-03 20:36:47 +02004111 if (conn->flags & CO_FL_ERROR) {
4112 /* CO_FL_ERROR may be set by ssl_sock_infocbk */
Emeric Brun644cde02012-12-14 11:21:13 +01004113 goto out_error;
Emeric Brune1f38db2012-09-03 20:36:47 +02004114 }
Emeric Brun46591952012-05-18 15:47:34 +02004115 if (ret > 0) {
Willy Tarreau518cedd2014-02-17 15:43:01 +01004116 conn->xprt_st &= ~SSL_SOCK_SEND_UNLIMITED;
4117
Emeric Brun46591952012-05-18 15:47:34 +02004118 buf->o -= ret;
4119 done += ret;
4120
Willy Tarreau5fb38032012-12-16 19:39:09 +01004121 if (likely(buffer_empty(buf)))
Emeric Brun46591952012-05-18 15:47:34 +02004122 /* optimize data alignment in the buffer */
4123 buf->p = buf->data;
4124
4125 /* if the system buffer is full, don't insist */
4126 if (ret < try)
4127 break;
4128 }
4129 else {
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02004130 ret = SSL_get_error(conn->xprt_ctx, ret);
Emeric Brun46591952012-05-18 15:47:34 +02004131 if (ret == SSL_ERROR_WANT_WRITE) {
Emeric Brun282a76a2012-11-08 18:02:56 +01004132 if (SSL_renegotiate_pending(conn->xprt_ctx)) {
4133 /* handshake is running, and it may need to re-enable write */
4134 conn->flags |= CO_FL_SSL_WAIT_HS;
4135 __conn_sock_want_send(conn);
4136 break;
4137 }
Emeric Brun46591952012-05-18 15:47:34 +02004138 /* we need to poll to retry a write later */
Willy Tarreaue1f50c42014-01-22 20:02:06 +01004139 fd_cant_send(conn->t.sock.fd);
Emeric Brun46591952012-05-18 15:47:34 +02004140 break;
4141 }
4142 else if (ret == SSL_ERROR_WANT_READ) {
Emeric Brun8af8dd12012-11-08 17:56:20 +01004143 /* handshake is running, and it needs to enable read */
Emeric Brun46591952012-05-18 15:47:34 +02004144 conn->flags |= CO_FL_SSL_WAIT_HS;
Emeric Brun8af8dd12012-11-08 17:56:20 +01004145 __conn_sock_want_recv(conn);
Emeric Brun46591952012-05-18 15:47:34 +02004146 break;
4147 }
4148 goto out_error;
4149 }
4150 }
4151 return done;
4152
4153 out_error:
Emeric Brun644cde02012-12-14 11:21:13 +01004154 /* Clear openssl global errors stack */
Thierry FOURNIER / OZON.IO8b068c22016-10-10 11:59:50 +02004155 ssl_sock_dump_errors(conn);
Emeric Brun644cde02012-12-14 11:21:13 +01004156 ERR_clear_error();
4157
Emeric Brun46591952012-05-18 15:47:34 +02004158 conn->flags |= CO_FL_ERROR;
4159 return done;
4160}
4161
Emeric Brun46591952012-05-18 15:47:34 +02004162static void ssl_sock_close(struct connection *conn) {
4163
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02004164 if (conn->xprt_ctx) {
4165 SSL_free(conn->xprt_ctx);
4166 conn->xprt_ctx = NULL;
Willy Tarreau403edff2012-09-06 11:58:37 +02004167 sslconns--;
Emeric Brun46591952012-05-18 15:47:34 +02004168 }
Emeric Brun46591952012-05-18 15:47:34 +02004169}
4170
4171/* This function tries to perform a clean shutdown on an SSL connection, and in
4172 * any case, flags the connection as reusable if no handshake was in progress.
4173 */
4174static void ssl_sock_shutw(struct connection *conn, int clean)
4175{
4176 if (conn->flags & CO_FL_HANDSHAKE)
4177 return;
Emmanuel Hocdet405ff312017-01-08 14:07:39 +01004178 if (!clean)
4179 /* don't sent notify on SSL_shutdown */
4180 SSL_CTX_set_quiet_shutdown(conn->xprt_ctx, 1);
Emeric Brun46591952012-05-18 15:47:34 +02004181 /* no handshake was in progress, try a clean ssl shutdown */
Emmanuel Hocdet405ff312017-01-08 14:07:39 +01004182 if (SSL_shutdown(conn->xprt_ctx) <= 0) {
Emeric Brun644cde02012-12-14 11:21:13 +01004183 /* Clear openssl global errors stack */
Thierry FOURNIER / OZON.IO8b068c22016-10-10 11:59:50 +02004184 ssl_sock_dump_errors(conn);
Emeric Brun644cde02012-12-14 11:21:13 +01004185 ERR_clear_error();
4186 }
Emeric Brun46591952012-05-18 15:47:34 +02004187}
4188
Willy Tarreauffc3fcd2012-10-12 20:17:54 +02004189/* used for logging, may be changed for a sample fetch later */
4190const char *ssl_sock_get_cipher_name(struct connection *conn)
4191{
4192 if (!conn->xprt && !conn->xprt_ctx)
4193 return NULL;
4194 return SSL_get_cipher_name(conn->xprt_ctx);
4195}
4196
4197/* used for logging, may be changed for a sample fetch later */
4198const char *ssl_sock_get_proto_version(struct connection *conn)
4199{
4200 if (!conn->xprt && !conn->xprt_ctx)
4201 return NULL;
4202 return SSL_get_version(conn->xprt_ctx);
4203}
4204
Willy Tarreau8d598402012-10-22 17:58:39 +02004205/* Extract a serial from a cert, and copy it to a chunk.
4206 * Returns 1 if serial is found and copied, 0 if no serial found and
4207 * -1 if output is not large enough.
4208 */
4209static int
4210ssl_sock_get_serial(X509 *crt, struct chunk *out)
4211{
4212 ASN1_INTEGER *serial;
4213
4214 serial = X509_get_serialNumber(crt);
4215 if (!serial)
4216 return 0;
4217
4218 if (out->size < serial->length)
4219 return -1;
4220
4221 memcpy(out->str, serial->data, serial->length);
4222 out->len = serial->length;
4223 return 1;
4224}
4225
Emeric Brun43e79582014-10-29 19:03:26 +01004226/* Extract a cert to der, and copy it to a chunk.
4227 * Returns 1 if cert is found and copied, 0 on der convertion failure and
4228 * -1 if output is not large enough.
4229 */
4230static int
4231ssl_sock_crt2der(X509 *crt, struct chunk *out)
4232{
4233 int len;
4234 unsigned char *p = (unsigned char *)out->str;;
4235
4236 len =i2d_X509(crt, NULL);
4237 if (len <= 0)
4238 return 1;
4239
4240 if (out->size < len)
4241 return -1;
4242
4243 i2d_X509(crt,&p);
4244 out->len = len;
4245 return 1;
4246}
4247
Emeric Brunce5ad802012-10-22 14:11:22 +02004248
4249/* Copy Date in ASN1_UTCTIME format in struct chunk out.
4250 * Returns 1 if serial is found and copied, 0 if no valid time found
4251 * and -1 if output is not large enough.
4252 */
4253static int
4254ssl_sock_get_time(ASN1_TIME *tm, struct chunk *out)
4255{
4256 if (tm->type == V_ASN1_GENERALIZEDTIME) {
4257 ASN1_GENERALIZEDTIME *gentm = (ASN1_GENERALIZEDTIME *)tm;
4258
4259 if (gentm->length < 12)
4260 return 0;
4261 if (gentm->data[0] != 0x32 || gentm->data[1] != 0x30)
4262 return 0;
4263 if (out->size < gentm->length-2)
4264 return -1;
4265
4266 memcpy(out->str, gentm->data+2, gentm->length-2);
4267 out->len = gentm->length-2;
4268 return 1;
4269 }
4270 else if (tm->type == V_ASN1_UTCTIME) {
4271 ASN1_UTCTIME *utctm = (ASN1_UTCTIME *)tm;
4272
4273 if (utctm->length < 10)
4274 return 0;
4275 if (utctm->data[0] >= 0x35)
4276 return 0;
4277 if (out->size < utctm->length)
4278 return -1;
4279
4280 memcpy(out->str, utctm->data, utctm->length);
4281 out->len = utctm->length;
4282 return 1;
4283 }
4284
4285 return 0;
4286}
4287
Emeric Brun87855892012-10-17 17:39:35 +02004288/* Extract an entry from a X509_NAME and copy its value to an output chunk.
4289 * Returns 1 if entry found, 0 if entry not found, or -1 if output not large enough.
4290 */
4291static int
4292ssl_sock_get_dn_entry(X509_NAME *a, const struct chunk *entry, int pos, struct chunk *out)
4293{
4294 X509_NAME_ENTRY *ne;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004295 ASN1_OBJECT *obj;
4296 ASN1_STRING *data;
4297 const unsigned char *data_ptr;
4298 int data_len;
Emeric Brun87855892012-10-17 17:39:35 +02004299 int i, j, n;
4300 int cur = 0;
4301 const char *s;
4302 char tmp[128];
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004303 int name_count;
4304
4305 name_count = X509_NAME_entry_count(a);
Emeric Brun87855892012-10-17 17:39:35 +02004306
4307 out->len = 0;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004308 for (i = 0; i < name_count; i++) {
Emeric Brun87855892012-10-17 17:39:35 +02004309 if (pos < 0)
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004310 j = (name_count-1) - i;
Emeric Brun87855892012-10-17 17:39:35 +02004311 else
4312 j = i;
4313
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004314 ne = X509_NAME_get_entry(a, j);
4315 obj = X509_NAME_ENTRY_get_object(ne);
4316 data = X509_NAME_ENTRY_get_data(ne);
4317 data_ptr = ASN1_STRING_get0_data(data);
4318 data_len = ASN1_STRING_length(data);
4319 n = OBJ_obj2nid(obj);
Emeric Brun87855892012-10-17 17:39:35 +02004320 if ((n == NID_undef) || ((s = OBJ_nid2sn(n)) == NULL)) {
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004321 i2t_ASN1_OBJECT(tmp, sizeof(tmp), obj);
Emeric Brun87855892012-10-17 17:39:35 +02004322 s = tmp;
4323 }
4324
4325 if (chunk_strcasecmp(entry, s) != 0)
4326 continue;
4327
4328 if (pos < 0)
4329 cur--;
4330 else
4331 cur++;
4332
4333 if (cur != pos)
4334 continue;
4335
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004336 if (data_len > out->size)
Emeric Brun87855892012-10-17 17:39:35 +02004337 return -1;
4338
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004339 memcpy(out->str, data_ptr, data_len);
4340 out->len = data_len;
Emeric Brun87855892012-10-17 17:39:35 +02004341 return 1;
4342 }
4343
4344 return 0;
4345
4346}
4347
4348/* Extract and format full DN from a X509_NAME and copy result into a chunk
4349 * Returns 1 if dn entries exits, 0 if no dn entry found or -1 if output is not large enough.
4350 */
4351static int
4352ssl_sock_get_dn_oneline(X509_NAME *a, struct chunk *out)
4353{
4354 X509_NAME_ENTRY *ne;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004355 ASN1_OBJECT *obj;
4356 ASN1_STRING *data;
4357 const unsigned char *data_ptr;
4358 int data_len;
Emeric Brun87855892012-10-17 17:39:35 +02004359 int i, n, ln;
4360 int l = 0;
4361 const char *s;
4362 char *p;
4363 char tmp[128];
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004364 int name_count;
4365
4366
4367 name_count = X509_NAME_entry_count(a);
Emeric Brun87855892012-10-17 17:39:35 +02004368
4369 out->len = 0;
4370 p = out->str;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004371 for (i = 0; i < name_count; i++) {
4372 ne = X509_NAME_get_entry(a, i);
4373 obj = X509_NAME_ENTRY_get_object(ne);
4374 data = X509_NAME_ENTRY_get_data(ne);
4375 data_ptr = ASN1_STRING_get0_data(data);
4376 data_len = ASN1_STRING_length(data);
4377 n = OBJ_obj2nid(obj);
Emeric Brun87855892012-10-17 17:39:35 +02004378 if ((n == NID_undef) || ((s = OBJ_nid2sn(n)) == NULL)) {
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004379 i2t_ASN1_OBJECT(tmp, sizeof(tmp), obj);
Emeric Brun87855892012-10-17 17:39:35 +02004380 s = tmp;
4381 }
4382 ln = strlen(s);
4383
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004384 l += 1 + ln + 1 + data_len;
Emeric Brun87855892012-10-17 17:39:35 +02004385 if (l > out->size)
4386 return -1;
4387 out->len = l;
4388
4389 *(p++)='/';
4390 memcpy(p, s, ln);
4391 p += ln;
4392 *(p++)='=';
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004393 memcpy(p, data_ptr, data_len);
4394 p += data_len;
Emeric Brun87855892012-10-17 17:39:35 +02004395 }
4396
4397 if (!out->len)
4398 return 0;
4399
4400 return 1;
4401}
4402
David Safb76832014-05-08 23:42:08 -04004403char *ssl_sock_get_version(struct connection *conn)
4404{
4405 if (!ssl_sock_is_ssl(conn))
4406 return NULL;
4407
4408 return (char *)SSL_get_version(conn->xprt_ctx);
4409}
4410
Willy Tarreau119a4082016-12-22 21:58:38 +01004411/* Sets advertised SNI for outgoing connections. Please set <hostname> to NULL
4412 * to disable SNI.
4413 */
Willy Tarreau63076412015-07-10 11:33:32 +02004414void ssl_sock_set_servername(struct connection *conn, const char *hostname)
4415{
4416#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Willy Tarreau119a4082016-12-22 21:58:38 +01004417 char *prev_name;
4418
Willy Tarreau63076412015-07-10 11:33:32 +02004419 if (!ssl_sock_is_ssl(conn))
4420 return;
4421
Willy Tarreau119a4082016-12-22 21:58:38 +01004422 /* if the SNI changes, we must destroy the reusable context so that a
4423 * new connection will present a new SNI. As an optimization we could
4424 * later imagine having a small cache of ssl_ctx to hold a few SNI per
4425 * server.
4426 */
4427 prev_name = (char *)SSL_get_servername(conn->xprt_ctx, TLSEXT_NAMETYPE_host_name);
4428 if ((!prev_name && hostname) ||
4429 (prev_name && (!hostname || strcmp(hostname, prev_name) != 0)))
4430 SSL_set_session(conn->xprt_ctx, NULL);
4431
Willy Tarreau63076412015-07-10 11:33:32 +02004432 SSL_set_tlsext_host_name(conn->xprt_ctx, hostname);
4433#endif
4434}
4435
Emeric Brun0abf8362014-06-24 18:26:41 +02004436/* Extract peer certificate's common name into the chunk dest
4437 * Returns
4438 * the len of the extracted common name
4439 * or 0 if no CN found in DN
4440 * or -1 on error case (i.e. no peer certificate)
4441 */
4442int ssl_sock_get_remote_common_name(struct connection *conn, struct chunk *dest)
David Safb76832014-05-08 23:42:08 -04004443{
4444 X509 *crt = NULL;
4445 X509_NAME *name;
David Safb76832014-05-08 23:42:08 -04004446 const char find_cn[] = "CN";
4447 const struct chunk find_cn_chunk = {
4448 .str = (char *)&find_cn,
4449 .len = sizeof(find_cn)-1
4450 };
Emeric Brun0abf8362014-06-24 18:26:41 +02004451 int result = -1;
David Safb76832014-05-08 23:42:08 -04004452
4453 if (!ssl_sock_is_ssl(conn))
Emeric Brun0abf8362014-06-24 18:26:41 +02004454 goto out;
David Safb76832014-05-08 23:42:08 -04004455
4456 /* SSL_get_peer_certificate, it increase X509 * ref count */
4457 crt = SSL_get_peer_certificate(conn->xprt_ctx);
4458 if (!crt)
4459 goto out;
4460
4461 name = X509_get_subject_name(crt);
4462 if (!name)
4463 goto out;
David Safb76832014-05-08 23:42:08 -04004464
Emeric Brun0abf8362014-06-24 18:26:41 +02004465 result = ssl_sock_get_dn_entry(name, &find_cn_chunk, 1, dest);
4466out:
David Safb76832014-05-08 23:42:08 -04004467 if (crt)
4468 X509_free(crt);
4469
4470 return result;
4471}
4472
Dave McCowan328fb582014-07-30 10:39:13 -04004473/* returns 1 if client passed a certificate for this session, 0 if not */
4474int ssl_sock_get_cert_used_sess(struct connection *conn)
4475{
4476 X509 *crt = NULL;
4477
4478 if (!ssl_sock_is_ssl(conn))
4479 return 0;
4480
4481 /* SSL_get_peer_certificate, it increase X509 * ref count */
4482 crt = SSL_get_peer_certificate(conn->xprt_ctx);
4483 if (!crt)
4484 return 0;
4485
4486 X509_free(crt);
4487 return 1;
4488}
4489
4490/* returns 1 if client passed a certificate for this connection, 0 if not */
4491int ssl_sock_get_cert_used_conn(struct connection *conn)
David Safb76832014-05-08 23:42:08 -04004492{
4493 if (!ssl_sock_is_ssl(conn))
4494 return 0;
4495
4496 return SSL_SOCK_ST_FL_VERIFY_DONE & conn->xprt_st ? 1 : 0;
4497}
4498
4499/* returns result from SSL verify */
4500unsigned int ssl_sock_get_verify_result(struct connection *conn)
4501{
4502 if (!ssl_sock_is_ssl(conn))
4503 return (unsigned int)X509_V_ERR_APPLICATION_VERIFICATION;
4504
4505 return (unsigned int)SSL_get_verify_result(conn->xprt_ctx);
4506}
4507
Willy Tarreau7875d092012-09-10 08:20:03 +02004508/***** Below are some sample fetching functions for ACL/patterns *****/
4509
Emeric Brune64aef12012-09-21 13:15:06 +02004510/* boolean, returns true if client cert was present */
4511static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004512smp_fetch_ssl_fc_has_crt(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brune64aef12012-09-21 13:15:06 +02004513{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004514 struct connection *conn;
4515
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004516 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004517 if (!conn || conn->xprt != &ssl_sock)
Emeric Brune64aef12012-09-21 13:15:06 +02004518 return 0;
4519
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004520 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brune64aef12012-09-21 13:15:06 +02004521 smp->flags |= SMP_F_MAY_CHANGE;
4522 return 0;
4523 }
4524
4525 smp->flags = 0;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004526 smp->data.type = SMP_T_BOOL;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004527 smp->data.u.sint = SSL_SOCK_ST_FL_VERIFY_DONE & conn->xprt_st ? 1 : 0;
Emeric Brune64aef12012-09-21 13:15:06 +02004528
4529 return 1;
4530}
4531
Emeric Brun43e79582014-10-29 19:03:26 +01004532/* binary, returns a certificate in a binary chunk (der/raw).
4533 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
4534 * should be use.
4535 */
4536static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004537smp_fetch_ssl_x_der(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun43e79582014-10-29 19:03:26 +01004538{
4539 int cert_peer = (kw[4] == 'c') ? 1 : 0;
4540 X509 *crt = NULL;
4541 int ret = 0;
4542 struct chunk *smp_trash;
4543 struct connection *conn;
4544
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004545 conn = objt_conn(smp->sess->origin);
Emeric Brun43e79582014-10-29 19:03:26 +01004546 if (!conn || conn->xprt != &ssl_sock)
4547 return 0;
4548
4549 if (!(conn->flags & CO_FL_CONNECTED)) {
4550 smp->flags |= SMP_F_MAY_CHANGE;
4551 return 0;
4552 }
4553
4554 if (cert_peer)
4555 crt = SSL_get_peer_certificate(conn->xprt_ctx);
4556 else
4557 crt = SSL_get_certificate(conn->xprt_ctx);
4558
4559 if (!crt)
4560 goto out;
4561
4562 smp_trash = get_trash_chunk();
4563 if (ssl_sock_crt2der(crt, smp_trash) <= 0)
4564 goto out;
4565
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004566 smp->data.u.str = *smp_trash;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004567 smp->data.type = SMP_T_BIN;
Emeric Brun43e79582014-10-29 19:03:26 +01004568 ret = 1;
4569out:
4570 /* SSL_get_peer_certificate, it increase X509 * ref count */
4571 if (cert_peer && crt)
4572 X509_free(crt);
4573 return ret;
4574}
4575
Emeric Brunba841a12014-04-30 17:05:08 +02004576/* binary, returns serial of certificate in a binary chunk.
4577 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
4578 * should be use.
4579 */
Willy Tarreau8d598402012-10-22 17:58:39 +02004580static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004581smp_fetch_ssl_x_serial(const struct arg *args, struct sample *smp, const char *kw, void *private)
Willy Tarreau8d598402012-10-22 17:58:39 +02004582{
Emeric Brunba841a12014-04-30 17:05:08 +02004583 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Willy Tarreau8d598402012-10-22 17:58:39 +02004584 X509 *crt = NULL;
4585 int ret = 0;
4586 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004587 struct connection *conn;
4588
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004589 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004590 if (!conn || conn->xprt != &ssl_sock)
Willy Tarreau8d598402012-10-22 17:58:39 +02004591 return 0;
4592
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004593 if (!(conn->flags & CO_FL_CONNECTED)) {
Willy Tarreau8d598402012-10-22 17:58:39 +02004594 smp->flags |= SMP_F_MAY_CHANGE;
4595 return 0;
4596 }
4597
Emeric Brunba841a12014-04-30 17:05:08 +02004598 if (cert_peer)
4599 crt = SSL_get_peer_certificate(conn->xprt_ctx);
4600 else
4601 crt = SSL_get_certificate(conn->xprt_ctx);
4602
Willy Tarreau8d598402012-10-22 17:58:39 +02004603 if (!crt)
4604 goto out;
4605
Willy Tarreau47ca5452012-12-23 20:22:19 +01004606 smp_trash = get_trash_chunk();
Willy Tarreau8d598402012-10-22 17:58:39 +02004607 if (ssl_sock_get_serial(crt, smp_trash) <= 0)
4608 goto out;
4609
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004610 smp->data.u.str = *smp_trash;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004611 smp->data.type = SMP_T_BIN;
Willy Tarreau8d598402012-10-22 17:58:39 +02004612 ret = 1;
4613out:
Emeric Brunba841a12014-04-30 17:05:08 +02004614 /* SSL_get_peer_certificate, it increase X509 * ref count */
4615 if (cert_peer && crt)
Willy Tarreau8d598402012-10-22 17:58:39 +02004616 X509_free(crt);
4617 return ret;
4618}
Emeric Brune64aef12012-09-21 13:15:06 +02004619
Emeric Brunba841a12014-04-30 17:05:08 +02004620/* binary, returns the client certificate's SHA-1 fingerprint (SHA-1 hash of DER-encoded certificate) in a binary chunk.
4621 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
4622 * should be use.
4623 */
James Votha051b4a2013-05-14 20:37:59 +02004624static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004625smp_fetch_ssl_x_sha1(const struct arg *args, struct sample *smp, const char *kw, void *private)
James Votha051b4a2013-05-14 20:37:59 +02004626{
Emeric Brunba841a12014-04-30 17:05:08 +02004627 int cert_peer = (kw[4] == 'c') ? 1 : 0;
James Votha051b4a2013-05-14 20:37:59 +02004628 X509 *crt = NULL;
4629 const EVP_MD *digest;
4630 int ret = 0;
4631 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004632 struct connection *conn;
James Votha051b4a2013-05-14 20:37:59 +02004633
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004634 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004635 if (!conn || conn->xprt != &ssl_sock)
4636 return 0;
4637
4638 if (!(conn->flags & CO_FL_CONNECTED)) {
James Votha051b4a2013-05-14 20:37:59 +02004639 smp->flags |= SMP_F_MAY_CHANGE;
4640 return 0;
4641 }
4642
Emeric Brunba841a12014-04-30 17:05:08 +02004643 if (cert_peer)
4644 crt = SSL_get_peer_certificate(conn->xprt_ctx);
4645 else
4646 crt = SSL_get_certificate(conn->xprt_ctx);
James Votha051b4a2013-05-14 20:37:59 +02004647 if (!crt)
4648 goto out;
4649
4650 smp_trash = get_trash_chunk();
4651 digest = EVP_sha1();
4652 X509_digest(crt, digest, (unsigned char *)smp_trash->str, (unsigned int *)&smp_trash->len);
4653
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004654 smp->data.u.str = *smp_trash;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004655 smp->data.type = SMP_T_BIN;
James Votha051b4a2013-05-14 20:37:59 +02004656 ret = 1;
4657out:
Emeric Brunba841a12014-04-30 17:05:08 +02004658 /* SSL_get_peer_certificate, it increase X509 * ref count */
4659 if (cert_peer && crt)
James Votha051b4a2013-05-14 20:37:59 +02004660 X509_free(crt);
4661 return ret;
4662}
4663
Emeric Brunba841a12014-04-30 17:05:08 +02004664/* string, returns certificate's notafter date in ASN1_UTCTIME format.
4665 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
4666 * should be use.
4667 */
Emeric Brunce5ad802012-10-22 14:11:22 +02004668static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004669smp_fetch_ssl_x_notafter(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brunce5ad802012-10-22 14:11:22 +02004670{
Emeric Brunba841a12014-04-30 17:05:08 +02004671 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brunce5ad802012-10-22 14:11:22 +02004672 X509 *crt = NULL;
4673 int ret = 0;
4674 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004675 struct connection *conn;
Emeric Brunce5ad802012-10-22 14:11:22 +02004676
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004677 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004678 if (!conn || conn->xprt != &ssl_sock)
4679 return 0;
4680
4681 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunce5ad802012-10-22 14:11:22 +02004682 smp->flags |= SMP_F_MAY_CHANGE;
4683 return 0;
4684 }
4685
Emeric Brunba841a12014-04-30 17:05:08 +02004686 if (cert_peer)
4687 crt = SSL_get_peer_certificate(conn->xprt_ctx);
4688 else
4689 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brunce5ad802012-10-22 14:11:22 +02004690 if (!crt)
4691 goto out;
4692
Willy Tarreau47ca5452012-12-23 20:22:19 +01004693 smp_trash = get_trash_chunk();
Emeric Brunce5ad802012-10-22 14:11:22 +02004694 if (ssl_sock_get_time(X509_get_notAfter(crt), smp_trash) <= 0)
4695 goto out;
4696
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004697 smp->data.u.str = *smp_trash;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004698 smp->data.type = SMP_T_STR;
Emeric Brunce5ad802012-10-22 14:11:22 +02004699 ret = 1;
4700out:
Emeric Brunba841a12014-04-30 17:05:08 +02004701 /* SSL_get_peer_certificate, it increase X509 * ref count */
4702 if (cert_peer && crt)
Emeric Brunce5ad802012-10-22 14:11:22 +02004703 X509_free(crt);
4704 return ret;
4705}
4706
Emeric Brunba841a12014-04-30 17:05:08 +02004707/* string, returns a string of a formatted full dn \C=..\O=..\OU=.. \CN=.. of certificate's issuer
4708 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
4709 * should be use.
4710 */
Emeric Brun87855892012-10-17 17:39:35 +02004711static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004712smp_fetch_ssl_x_i_dn(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun87855892012-10-17 17:39:35 +02004713{
Emeric Brunba841a12014-04-30 17:05:08 +02004714 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brun87855892012-10-17 17:39:35 +02004715 X509 *crt = NULL;
4716 X509_NAME *name;
4717 int ret = 0;
4718 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004719 struct connection *conn;
Emeric Brun87855892012-10-17 17:39:35 +02004720
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004721 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004722 if (!conn || conn->xprt != &ssl_sock)
4723 return 0;
4724
4725 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun87855892012-10-17 17:39:35 +02004726 smp->flags |= SMP_F_MAY_CHANGE;
4727 return 0;
4728 }
4729
Emeric Brunba841a12014-04-30 17:05:08 +02004730 if (cert_peer)
4731 crt = SSL_get_peer_certificate(conn->xprt_ctx);
4732 else
4733 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brun87855892012-10-17 17:39:35 +02004734 if (!crt)
4735 goto out;
4736
4737 name = X509_get_issuer_name(crt);
4738 if (!name)
4739 goto out;
4740
Willy Tarreau47ca5452012-12-23 20:22:19 +01004741 smp_trash = get_trash_chunk();
Emeric Brun87855892012-10-17 17:39:35 +02004742 if (args && args[0].type == ARGT_STR) {
4743 int pos = 1;
4744
4745 if (args[1].type == ARGT_SINT)
4746 pos = args[1].data.sint;
Emeric Brun87855892012-10-17 17:39:35 +02004747
4748 if (ssl_sock_get_dn_entry(name, &args[0].data.str, pos, smp_trash) <= 0)
4749 goto out;
4750 }
4751 else if (ssl_sock_get_dn_oneline(name, smp_trash) <= 0)
4752 goto out;
4753
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004754 smp->data.type = SMP_T_STR;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004755 smp->data.u.str = *smp_trash;
Emeric Brun87855892012-10-17 17:39:35 +02004756 ret = 1;
4757out:
Emeric Brunba841a12014-04-30 17:05:08 +02004758 /* SSL_get_peer_certificate, it increase X509 * ref count */
4759 if (cert_peer && crt)
Emeric Brun87855892012-10-17 17:39:35 +02004760 X509_free(crt);
4761 return ret;
4762}
4763
Emeric Brunba841a12014-04-30 17:05:08 +02004764/* string, returns notbefore date in ASN1_UTCTIME format.
4765 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
4766 * should be use.
4767 */
Emeric Brunce5ad802012-10-22 14:11:22 +02004768static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004769smp_fetch_ssl_x_notbefore(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brunce5ad802012-10-22 14:11:22 +02004770{
Emeric Brunba841a12014-04-30 17:05:08 +02004771 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brunce5ad802012-10-22 14:11:22 +02004772 X509 *crt = NULL;
4773 int ret = 0;
4774 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004775 struct connection *conn;
4776
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004777 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004778 if (!conn || conn->xprt != &ssl_sock)
Emeric Brunce5ad802012-10-22 14:11:22 +02004779 return 0;
4780
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004781 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunce5ad802012-10-22 14:11:22 +02004782 smp->flags |= SMP_F_MAY_CHANGE;
4783 return 0;
4784 }
4785
Emeric Brunba841a12014-04-30 17:05:08 +02004786 if (cert_peer)
4787 crt = SSL_get_peer_certificate(conn->xprt_ctx);
4788 else
4789 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brunce5ad802012-10-22 14:11:22 +02004790 if (!crt)
4791 goto out;
4792
Willy Tarreau47ca5452012-12-23 20:22:19 +01004793 smp_trash = get_trash_chunk();
Emeric Brunce5ad802012-10-22 14:11:22 +02004794 if (ssl_sock_get_time(X509_get_notBefore(crt), smp_trash) <= 0)
4795 goto out;
4796
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004797 smp->data.u.str = *smp_trash;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004798 smp->data.type = SMP_T_STR;
Emeric Brunce5ad802012-10-22 14:11:22 +02004799 ret = 1;
4800out:
Emeric Brunba841a12014-04-30 17:05:08 +02004801 /* SSL_get_peer_certificate, it increase X509 * ref count */
4802 if (cert_peer && crt)
Emeric Brunce5ad802012-10-22 14:11:22 +02004803 X509_free(crt);
4804 return ret;
4805}
4806
Emeric Brunba841a12014-04-30 17:05:08 +02004807/* string, returns a string of a formatted full dn \C=..\O=..\OU=.. \CN=.. of certificate's subject
4808 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
4809 * should be use.
4810 */
Emeric Brun87855892012-10-17 17:39:35 +02004811static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004812smp_fetch_ssl_x_s_dn(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun87855892012-10-17 17:39:35 +02004813{
Emeric Brunba841a12014-04-30 17:05:08 +02004814 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brun87855892012-10-17 17:39:35 +02004815 X509 *crt = NULL;
4816 X509_NAME *name;
4817 int ret = 0;
4818 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004819 struct connection *conn;
Emeric Brun87855892012-10-17 17:39:35 +02004820
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004821 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004822 if (!conn || conn->xprt != &ssl_sock)
4823 return 0;
4824
4825 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun87855892012-10-17 17:39:35 +02004826 smp->flags |= SMP_F_MAY_CHANGE;
4827 return 0;
4828 }
4829
Emeric Brunba841a12014-04-30 17:05:08 +02004830 if (cert_peer)
4831 crt = SSL_get_peer_certificate(conn->xprt_ctx);
4832 else
4833 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brun87855892012-10-17 17:39:35 +02004834 if (!crt)
4835 goto out;
4836
4837 name = X509_get_subject_name(crt);
4838 if (!name)
4839 goto out;
4840
Willy Tarreau47ca5452012-12-23 20:22:19 +01004841 smp_trash = get_trash_chunk();
Emeric Brun87855892012-10-17 17:39:35 +02004842 if (args && args[0].type == ARGT_STR) {
4843 int pos = 1;
4844
4845 if (args[1].type == ARGT_SINT)
4846 pos = args[1].data.sint;
Emeric Brun87855892012-10-17 17:39:35 +02004847
4848 if (ssl_sock_get_dn_entry(name, &args[0].data.str, pos, smp_trash) <= 0)
4849 goto out;
4850 }
4851 else if (ssl_sock_get_dn_oneline(name, smp_trash) <= 0)
4852 goto out;
4853
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004854 smp->data.type = SMP_T_STR;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004855 smp->data.u.str = *smp_trash;
Emeric Brun87855892012-10-17 17:39:35 +02004856 ret = 1;
4857out:
Emeric Brunba841a12014-04-30 17:05:08 +02004858 /* SSL_get_peer_certificate, it increase X509 * ref count */
4859 if (cert_peer && crt)
Emeric Brun87855892012-10-17 17:39:35 +02004860 X509_free(crt);
4861 return ret;
4862}
Emeric Brun9143d372012-12-20 15:44:16 +01004863
4864/* integer, returns true if current session use a client certificate */
4865static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004866smp_fetch_ssl_c_used(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun9143d372012-12-20 15:44:16 +01004867{
4868 X509 *crt;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004869 struct connection *conn;
Emeric Brun9143d372012-12-20 15:44:16 +01004870
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004871 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004872 if (!conn || conn->xprt != &ssl_sock)
4873 return 0;
4874
4875 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun9143d372012-12-20 15:44:16 +01004876 smp->flags |= SMP_F_MAY_CHANGE;
4877 return 0;
4878 }
4879
4880 /* SSL_get_peer_certificate returns a ptr on allocated X509 struct */
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004881 crt = SSL_get_peer_certificate(conn->xprt_ctx);
Emeric Brun9143d372012-12-20 15:44:16 +01004882 if (crt) {
4883 X509_free(crt);
4884 }
4885
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004886 smp->data.type = SMP_T_BOOL;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004887 smp->data.u.sint = (crt != NULL);
Emeric Brun9143d372012-12-20 15:44:16 +01004888 return 1;
4889}
4890
Emeric Brunba841a12014-04-30 17:05:08 +02004891/* integer, returns the certificate version
4892 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
4893 * should be use.
4894 */
Emeric Bruna7359fd2012-10-17 15:03:11 +02004895static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004896smp_fetch_ssl_x_version(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Bruna7359fd2012-10-17 15:03:11 +02004897{
Emeric Brunba841a12014-04-30 17:05:08 +02004898 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Bruna7359fd2012-10-17 15:03:11 +02004899 X509 *crt;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004900 struct connection *conn;
4901
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004902 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004903 if (!conn || conn->xprt != &ssl_sock)
Emeric Bruna7359fd2012-10-17 15:03:11 +02004904 return 0;
4905
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004906 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Bruna7359fd2012-10-17 15:03:11 +02004907 smp->flags |= SMP_F_MAY_CHANGE;
4908 return 0;
4909 }
4910
Emeric Brunba841a12014-04-30 17:05:08 +02004911 if (cert_peer)
4912 crt = SSL_get_peer_certificate(conn->xprt_ctx);
4913 else
4914 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Bruna7359fd2012-10-17 15:03:11 +02004915 if (!crt)
4916 return 0;
4917
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004918 smp->data.u.sint = (unsigned int)(1 + X509_get_version(crt));
Emeric Brunba841a12014-04-30 17:05:08 +02004919 /* SSL_get_peer_certificate increase X509 * ref count */
4920 if (cert_peer)
4921 X509_free(crt);
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004922 smp->data.type = SMP_T_SINT;
Emeric Bruna7359fd2012-10-17 15:03:11 +02004923
4924 return 1;
4925}
4926
Emeric Brunba841a12014-04-30 17:05:08 +02004927/* string, returns the certificate's signature algorithm.
4928 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
4929 * should be use.
4930 */
Emeric Brun7f56e742012-10-19 18:15:40 +02004931static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004932smp_fetch_ssl_x_sig_alg(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun7f56e742012-10-19 18:15:40 +02004933{
Emeric Brunba841a12014-04-30 17:05:08 +02004934 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brun7f56e742012-10-19 18:15:40 +02004935 X509 *crt;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004936 __OPENSSL_110_CONST__ ASN1_OBJECT *algorithm;
Emeric Brun7f56e742012-10-19 18:15:40 +02004937 int nid;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004938 struct connection *conn;
Emeric Brun7f56e742012-10-19 18:15:40 +02004939
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004940 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004941 if (!conn || conn->xprt != &ssl_sock)
4942 return 0;
4943
4944 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun7f56e742012-10-19 18:15:40 +02004945 smp->flags |= SMP_F_MAY_CHANGE;
4946 return 0;
4947 }
4948
Emeric Brunba841a12014-04-30 17:05:08 +02004949 if (cert_peer)
4950 crt = SSL_get_peer_certificate(conn->xprt_ctx);
4951 else
4952 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brun7f56e742012-10-19 18:15:40 +02004953 if (!crt)
4954 return 0;
4955
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004956 X509_ALGOR_get0(&algorithm, NULL, NULL, X509_get0_tbs_sigalg(crt));
4957 nid = OBJ_obj2nid(algorithm);
Emeric Brun7f56e742012-10-19 18:15:40 +02004958
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004959 smp->data.u.str.str = (char *)OBJ_nid2sn(nid);
4960 if (!smp->data.u.str.str) {
Emeric Brunba841a12014-04-30 17:05:08 +02004961 /* SSL_get_peer_certificate increase X509 * ref count */
4962 if (cert_peer)
4963 X509_free(crt);
Emeric Brun7f56e742012-10-19 18:15:40 +02004964 return 0;
Emeric Brun9bf3ba22013-10-07 14:31:44 +02004965 }
Emeric Brun7f56e742012-10-19 18:15:40 +02004966
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004967 smp->data.type = SMP_T_STR;
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01004968 smp->flags |= SMP_F_CONST;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004969 smp->data.u.str.len = strlen(smp->data.u.str.str);
Emeric Brunba841a12014-04-30 17:05:08 +02004970 /* SSL_get_peer_certificate increase X509 * ref count */
4971 if (cert_peer)
4972 X509_free(crt);
Emeric Brun7f56e742012-10-19 18:15:40 +02004973
4974 return 1;
4975}
4976
Emeric Brunba841a12014-04-30 17:05:08 +02004977/* string, returns the certificate's key algorithm.
4978 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
4979 * should be use.
4980 */
Emeric Brun521a0112012-10-22 12:22:55 +02004981static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004982smp_fetch_ssl_x_key_alg(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun521a0112012-10-22 12:22:55 +02004983{
Emeric Brunba841a12014-04-30 17:05:08 +02004984 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brun521a0112012-10-22 12:22:55 +02004985 X509 *crt;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004986 ASN1_OBJECT *algorithm;
Emeric Brun521a0112012-10-22 12:22:55 +02004987 int nid;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004988 struct connection *conn;
Emeric Brun521a0112012-10-22 12:22:55 +02004989
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004990 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004991 if (!conn || conn->xprt != &ssl_sock)
4992 return 0;
4993
4994 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun521a0112012-10-22 12:22:55 +02004995 smp->flags |= SMP_F_MAY_CHANGE;
4996 return 0;
4997 }
4998
Emeric Brunba841a12014-04-30 17:05:08 +02004999 if (cert_peer)
5000 crt = SSL_get_peer_certificate(conn->xprt_ctx);
5001 else
5002 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brun521a0112012-10-22 12:22:55 +02005003 if (!crt)
5004 return 0;
5005
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02005006 X509_PUBKEY_get0_param(&algorithm, NULL, NULL, NULL, X509_get_X509_PUBKEY(crt));
5007 nid = OBJ_obj2nid(algorithm);
Emeric Brun521a0112012-10-22 12:22:55 +02005008
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005009 smp->data.u.str.str = (char *)OBJ_nid2sn(nid);
5010 if (!smp->data.u.str.str) {
Emeric Brunba841a12014-04-30 17:05:08 +02005011 /* SSL_get_peer_certificate increase X509 * ref count */
5012 if (cert_peer)
5013 X509_free(crt);
Emeric Brun521a0112012-10-22 12:22:55 +02005014 return 0;
Emeric Brun9bf3ba22013-10-07 14:31:44 +02005015 }
Emeric Brun521a0112012-10-22 12:22:55 +02005016
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005017 smp->data.type = SMP_T_STR;
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01005018 smp->flags |= SMP_F_CONST;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005019 smp->data.u.str.len = strlen(smp->data.u.str.str);
Emeric Brunba841a12014-04-30 17:05:08 +02005020 if (cert_peer)
5021 X509_free(crt);
Emeric Brun521a0112012-10-22 12:22:55 +02005022
5023 return 1;
5024}
5025
Emeric Brun645ae792014-04-30 14:21:06 +02005026/* boolean, returns true if front conn. transport layer is SSL.
5027 * This function is also usable on backend conn if the fetch keyword 5th
5028 * char is 'b'.
5029 */
Willy Tarreau7875d092012-09-10 08:20:03 +02005030static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005031smp_fetch_ssl_fc(const struct arg *args, struct sample *smp, const char *kw, void *private)
Willy Tarreau7875d092012-09-10 08:20:03 +02005032{
Willy Tarreaue237fe12016-03-10 17:05:28 +01005033 struct connection *conn = objt_conn((kw[4] != 'b') ? smp->sess->origin :
5034 smp->strm ? smp->strm->si[1].end : NULL);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005035
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005036 smp->data.type = SMP_T_BOOL;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005037 smp->data.u.sint = (conn && conn->xprt == &ssl_sock);
Willy Tarreau7875d092012-09-10 08:20:03 +02005038 return 1;
5039}
5040
Emeric Brun2525b6b2012-10-18 15:59:43 +02005041/* boolean, returns true if client present a SNI */
Willy Tarreau7875d092012-09-10 08:20:03 +02005042static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005043smp_fetch_ssl_fc_has_sni(const struct arg *args, struct sample *smp, const char *kw, void *private)
Willy Tarreau7875d092012-09-10 08:20:03 +02005044{
5045#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02005046 struct connection *conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005047
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005048 smp->data.type = SMP_T_BOOL;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005049 smp->data.u.sint = (conn && conn->xprt == &ssl_sock) &&
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005050 conn->xprt_ctx &&
5051 SSL_get_servername(conn->xprt_ctx, TLSEXT_NAMETYPE_host_name) != NULL;
Willy Tarreau7875d092012-09-10 08:20:03 +02005052 return 1;
5053#else
5054 return 0;
5055#endif
5056}
5057
Nenad Merdanovic26ea8222015-05-18 02:28:57 +02005058/* boolean, returns true if client session has been resumed */
5059static int
5060smp_fetch_ssl_fc_is_resumed(const struct arg *args, struct sample *smp, const char *kw, void *private)
5061{
5062 struct connection *conn = objt_conn(smp->sess->origin);
5063
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005064 smp->data.type = SMP_T_BOOL;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005065 smp->data.u.sint = (conn && conn->xprt == &ssl_sock) &&
Nenad Merdanovic26ea8222015-05-18 02:28:57 +02005066 conn->xprt_ctx &&
5067 SSL_session_reused(conn->xprt_ctx);
5068 return 1;
5069}
5070
Emeric Brun645ae792014-04-30 14:21:06 +02005071/* string, returns the used cipher if front conn. transport layer is SSL.
5072 * This function is also usable on backend conn if the fetch keyword 5th
5073 * char is 'b'.
5074 */
Emeric Brun589fcad2012-10-16 14:13:26 +02005075static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005076smp_fetch_ssl_fc_cipher(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun589fcad2012-10-16 14:13:26 +02005077{
Willy Tarreaue237fe12016-03-10 17:05:28 +01005078 struct connection *conn = objt_conn((kw[4] != 'b') ? smp->sess->origin :
5079 smp->strm ? smp->strm->si[1].end : NULL);
Emeric Brun589fcad2012-10-16 14:13:26 +02005080
Willy Tarreaube508f12016-03-10 11:47:01 +01005081 smp->flags = 0;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005082 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
Emeric Brun589fcad2012-10-16 14:13:26 +02005083 return 0;
5084
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005085 smp->data.u.str.str = (char *)SSL_get_cipher_name(conn->xprt_ctx);
5086 if (!smp->data.u.str.str)
Emeric Brun589fcad2012-10-16 14:13:26 +02005087 return 0;
5088
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005089 smp->data.type = SMP_T_STR;
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01005090 smp->flags |= SMP_F_CONST;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005091 smp->data.u.str.len = strlen(smp->data.u.str.str);
Emeric Brun589fcad2012-10-16 14:13:26 +02005092
5093 return 1;
5094}
5095
Emeric Brun645ae792014-04-30 14:21:06 +02005096/* integer, returns the algoritm's keysize if front conn. transport layer
5097 * is SSL.
5098 * This function is also usable on backend conn if the fetch keyword 5th
5099 * char is 'b'.
5100 */
Emeric Brun589fcad2012-10-16 14:13:26 +02005101static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005102smp_fetch_ssl_fc_alg_keysize(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun589fcad2012-10-16 14:13:26 +02005103{
Willy Tarreaue237fe12016-03-10 17:05:28 +01005104 struct connection *conn = objt_conn((kw[4] != 'b') ? smp->sess->origin :
5105 smp->strm ? smp->strm->si[1].end : NULL);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005106
Willy Tarreaue237fe12016-03-10 17:05:28 +01005107 int sint;
Willy Tarreaube508f12016-03-10 11:47:01 +01005108
Emeric Brun589fcad2012-10-16 14:13:26 +02005109 smp->flags = 0;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005110 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
Emeric Brun589fcad2012-10-16 14:13:26 +02005111 return 0;
5112
Thierry FOURNIER07ee64e2015-07-06 23:43:03 +02005113 if (!SSL_get_cipher_bits(conn->xprt_ctx, &sint))
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005114 return 0;
5115
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005116 smp->data.u.sint = sint;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005117 smp->data.type = SMP_T_SINT;
Emeric Brun589fcad2012-10-16 14:13:26 +02005118
5119 return 1;
5120}
5121
Emeric Brun645ae792014-04-30 14:21:06 +02005122/* integer, returns the used keysize if front conn. transport layer is SSL.
5123 * This function is also usable on backend conn if the fetch keyword 5th
5124 * char is 'b'.
5125 */
Emeric Brun589fcad2012-10-16 14:13:26 +02005126static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005127smp_fetch_ssl_fc_use_keysize(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun589fcad2012-10-16 14:13:26 +02005128{
Willy Tarreaue237fe12016-03-10 17:05:28 +01005129 struct connection *conn = objt_conn((kw[4] != 'b') ? smp->sess->origin :
5130 smp->strm ? smp->strm->si[1].end : NULL);
Willy Tarreaube508f12016-03-10 11:47:01 +01005131
Emeric Brun589fcad2012-10-16 14:13:26 +02005132 smp->flags = 0;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005133 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
5134 return 0;
5135
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005136 smp->data.u.sint = (unsigned int)SSL_get_cipher_bits(conn->xprt_ctx, NULL);
5137 if (!smp->data.u.sint)
Emeric Brun589fcad2012-10-16 14:13:26 +02005138 return 0;
5139
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005140 smp->data.type = SMP_T_SINT;
Emeric Brun589fcad2012-10-16 14:13:26 +02005141
5142 return 1;
5143}
5144
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02005145#ifdef OPENSSL_NPN_NEGOTIATED
Willy Tarreau7875d092012-09-10 08:20:03 +02005146static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005147smp_fetch_ssl_fc_npn(const struct arg *args, struct sample *smp, const char *kw, void *private)
Willy Tarreaua33c6542012-10-15 13:19:06 +02005148{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005149 struct connection *conn;
5150
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01005151 smp->flags = SMP_F_CONST;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005152 smp->data.type = SMP_T_STR;
Willy Tarreaua33c6542012-10-15 13:19:06 +02005153
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02005154 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005155 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
5156 return 0;
5157
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005158 smp->data.u.str.str = NULL;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005159 SSL_get0_next_proto_negotiated(conn->xprt_ctx,
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005160 (const unsigned char **)&smp->data.u.str.str, (unsigned *)&smp->data.u.str.len);
Willy Tarreaua33c6542012-10-15 13:19:06 +02005161
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005162 if (!smp->data.u.str.str)
Willy Tarreaua33c6542012-10-15 13:19:06 +02005163 return 0;
5164
5165 return 1;
Willy Tarreaua33c6542012-10-15 13:19:06 +02005166}
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02005167#endif
Willy Tarreaua33c6542012-10-15 13:19:06 +02005168
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01005169#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Willy Tarreauab861d32013-04-02 02:30:41 +02005170static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005171smp_fetch_ssl_fc_alpn(const struct arg *args, struct sample *smp, const char *kw, void *private)
Willy Tarreauab861d32013-04-02 02:30:41 +02005172{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005173 struct connection *conn;
5174
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01005175 smp->flags = SMP_F_CONST;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005176 smp->data.type = SMP_T_STR;
Willy Tarreauab861d32013-04-02 02:30:41 +02005177
Willy Tarreaue26bf052015-05-12 10:30:12 +02005178 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005179 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
Willy Tarreauab861d32013-04-02 02:30:41 +02005180 return 0;
5181
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005182 smp->data.u.str.str = NULL;
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01005183 SSL_get0_alpn_selected(conn->xprt_ctx,
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005184 (const unsigned char **)&smp->data.u.str.str, (unsigned *)&smp->data.u.str.len);
Willy Tarreauab861d32013-04-02 02:30:41 +02005185
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005186 if (!smp->data.u.str.str)
Willy Tarreauab861d32013-04-02 02:30:41 +02005187 return 0;
5188
5189 return 1;
5190}
5191#endif
5192
Emeric Brun645ae792014-04-30 14:21:06 +02005193/* string, returns the used protocol if front conn. transport layer is SSL.
5194 * This function is also usable on backend conn if the fetch keyword 5th
5195 * char is 'b'.
5196 */
Willy Tarreaua33c6542012-10-15 13:19:06 +02005197static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005198smp_fetch_ssl_fc_protocol(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun589fcad2012-10-16 14:13:26 +02005199{
Willy Tarreaue237fe12016-03-10 17:05:28 +01005200 struct connection *conn = objt_conn((kw[4] != 'b') ? smp->sess->origin :
5201 smp->strm ? smp->strm->si[1].end : NULL);
Willy Tarreaube508f12016-03-10 11:47:01 +01005202
Emeric Brun589fcad2012-10-16 14:13:26 +02005203 smp->flags = 0;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005204 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
5205 return 0;
5206
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005207 smp->data.u.str.str = (char *)SSL_get_version(conn->xprt_ctx);
5208 if (!smp->data.u.str.str)
Emeric Brun589fcad2012-10-16 14:13:26 +02005209 return 0;
5210
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005211 smp->data.type = SMP_T_STR;
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01005212 smp->flags = SMP_F_CONST;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005213 smp->data.u.str.len = strlen(smp->data.u.str.str);
Emeric Brun589fcad2012-10-16 14:13:26 +02005214
5215 return 1;
5216}
5217
Willy Tarreau87b09662015-04-03 00:22:06 +02005218/* binary, returns the SSL stream id if front conn. transport layer is SSL.
Emeric Brun645ae792014-04-30 14:21:06 +02005219 * This function is also usable on backend conn if the fetch keyword 5th
5220 * char is 'b'.
5221 */
Emeric Brun589fcad2012-10-16 14:13:26 +02005222static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005223smp_fetch_ssl_fc_session_id(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brunfe68f682012-10-16 14:59:28 +02005224{
5225#if OPENSSL_VERSION_NUMBER > 0x0090800fL
Willy Tarreaue237fe12016-03-10 17:05:28 +01005226 struct connection *conn = objt_conn((kw[4] != 'b') ? smp->sess->origin :
5227 smp->strm ? smp->strm->si[1].end : NULL);
Emeric Brunfe68f682012-10-16 14:59:28 +02005228
Willy Tarreaue237fe12016-03-10 17:05:28 +01005229 SSL_SESSION *ssl_sess;
Willy Tarreaube508f12016-03-10 11:47:01 +01005230
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01005231 smp->flags = SMP_F_CONST;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005232 smp->data.type = SMP_T_BIN;
Emeric Brunfe68f682012-10-16 14:59:28 +02005233
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005234 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
5235 return 0;
5236
Willy Tarreau192252e2015-04-04 01:47:55 +02005237 ssl_sess = SSL_get_session(conn->xprt_ctx);
5238 if (!ssl_sess)
Emeric Brunfe68f682012-10-16 14:59:28 +02005239 return 0;
5240
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005241 smp->data.u.str.str = (char *)SSL_SESSION_get_id(ssl_sess, (unsigned int *)&smp->data.u.str.len);
5242 if (!smp->data.u.str.str || !smp->data.u.str.len)
Emeric Brunfe68f682012-10-16 14:59:28 +02005243 return 0;
5244
5245 return 1;
5246#else
5247 return 0;
5248#endif
5249}
5250
5251static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005252smp_fetch_ssl_fc_sni(const struct arg *args, struct sample *smp, const char *kw, void *private)
Willy Tarreau7875d092012-09-10 08:20:03 +02005253{
5254#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005255 struct connection *conn;
5256
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01005257 smp->flags = SMP_F_CONST;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005258 smp->data.type = SMP_T_STR;
Willy Tarreau7875d092012-09-10 08:20:03 +02005259
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02005260 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005261 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
5262 return 0;
5263
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005264 smp->data.u.str.str = (char *)SSL_get_servername(conn->xprt_ctx, TLSEXT_NAMETYPE_host_name);
5265 if (!smp->data.u.str.str)
Willy Tarreau3e394c92012-09-14 23:56:58 +02005266 return 0;
5267
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005268 smp->data.u.str.len = strlen(smp->data.u.str.str);
Willy Tarreau7875d092012-09-10 08:20:03 +02005269 return 1;
5270#else
5271 return 0;
5272#endif
5273}
5274
David Sc1ad52e2014-04-08 18:48:47 -04005275static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005276smp_fetch_ssl_fc_unique_id(const struct arg *args, struct sample *smp, const char *kw, void *private)
David Sc1ad52e2014-04-08 18:48:47 -04005277{
5278#if OPENSSL_VERSION_NUMBER > 0x0090800fL
Willy Tarreaue237fe12016-03-10 17:05:28 +01005279 struct connection *conn = objt_conn((kw[4] != 'b') ? smp->sess->origin :
5280 smp->strm ? smp->strm->si[1].end : NULL);
5281
David Sc1ad52e2014-04-08 18:48:47 -04005282 int finished_len;
David Sc1ad52e2014-04-08 18:48:47 -04005283 struct chunk *finished_trash;
David Sc1ad52e2014-04-08 18:48:47 -04005284
5285 smp->flags = 0;
David Sc1ad52e2014-04-08 18:48:47 -04005286 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
5287 return 0;
5288
5289 if (!(conn->flags & CO_FL_CONNECTED)) {
5290 smp->flags |= SMP_F_MAY_CHANGE;
5291 return 0;
5292 }
5293
5294 finished_trash = get_trash_chunk();
5295 if (!SSL_session_reused(conn->xprt_ctx))
5296 finished_len = SSL_get_peer_finished(conn->xprt_ctx, finished_trash->str, finished_trash->size);
5297 else
5298 finished_len = SSL_get_finished(conn->xprt_ctx, finished_trash->str, finished_trash->size);
5299
5300 if (!finished_len)
5301 return 0;
5302
Emeric Brunb73a9b02014-04-30 18:49:19 +02005303 finished_trash->len = finished_len;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005304 smp->data.u.str = *finished_trash;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005305 smp->data.type = SMP_T_BIN;
David Sc1ad52e2014-04-08 18:48:47 -04005306
5307 return 1;
5308#else
5309 return 0;
5310#endif
5311}
5312
Emeric Brun2525b6b2012-10-18 15:59:43 +02005313/* integer, returns the first verify error in CA chain of client certificate chain. */
Emeric Brunf282a812012-09-21 15:27:54 +02005314static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005315smp_fetch_ssl_c_ca_err(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brunf282a812012-09-21 15:27:54 +02005316{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005317 struct connection *conn;
5318
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02005319 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005320 if (!conn || conn->xprt != &ssl_sock)
5321 return 0;
5322
5323 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunf282a812012-09-21 15:27:54 +02005324 smp->flags = SMP_F_MAY_CHANGE;
5325 return 0;
5326 }
5327
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005328 smp->data.type = SMP_T_SINT;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005329 smp->data.u.sint = (unsigned long long int)SSL_SOCK_ST_TO_CA_ERROR(conn->xprt_st);
Emeric Brunf282a812012-09-21 15:27:54 +02005330 smp->flags = 0;
5331
5332 return 1;
5333}
5334
Emeric Brun2525b6b2012-10-18 15:59:43 +02005335/* integer, returns the depth of the first verify error in CA chain of client certificate chain. */
Emeric Brunf282a812012-09-21 15:27:54 +02005336static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005337smp_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 +02005338{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005339 struct connection *conn;
5340
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02005341 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005342 if (!conn || conn->xprt != &ssl_sock)
Emeric Brunf282a812012-09-21 15:27:54 +02005343 return 0;
5344
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005345 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunf282a812012-09-21 15:27:54 +02005346 smp->flags = SMP_F_MAY_CHANGE;
5347 return 0;
5348 }
5349
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005350 smp->data.type = SMP_T_SINT;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005351 smp->data.u.sint = (long long int)SSL_SOCK_ST_TO_CAEDEPTH(conn->xprt_st);
Emeric Brunf282a812012-09-21 15:27:54 +02005352 smp->flags = 0;
5353
5354 return 1;
5355}
5356
Emeric Brun2525b6b2012-10-18 15:59:43 +02005357/* integer, returns the first verify error on client certificate */
Emeric Brunf282a812012-09-21 15:27:54 +02005358static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005359smp_fetch_ssl_c_err(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brunf282a812012-09-21 15:27:54 +02005360{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005361 struct connection *conn;
5362
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02005363 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005364 if (!conn || conn->xprt != &ssl_sock)
5365 return 0;
5366
5367 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunf282a812012-09-21 15:27:54 +02005368 smp->flags = SMP_F_MAY_CHANGE;
5369 return 0;
5370 }
5371
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005372 smp->data.type = SMP_T_SINT;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005373 smp->data.u.sint = (long long int)SSL_SOCK_ST_TO_CRTERROR(conn->xprt_st);
Emeric Brunf282a812012-09-21 15:27:54 +02005374 smp->flags = 0;
5375
5376 return 1;
5377}
5378
Emeric Brun2525b6b2012-10-18 15:59:43 +02005379/* integer, returns the verify result on client cert */
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02005380static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005381smp_fetch_ssl_c_verify(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02005382{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005383 struct connection *conn;
5384
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02005385 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005386 if (!conn || conn->xprt != &ssl_sock)
5387 return 0;
5388
5389 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02005390 smp->flags = SMP_F_MAY_CHANGE;
5391 return 0;
5392 }
5393
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005394 if (!conn->xprt_ctx)
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02005395 return 0;
5396
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005397 smp->data.type = SMP_T_SINT;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005398 smp->data.u.sint = (long long int)SSL_get_verify_result(conn->xprt_ctx);
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02005399 smp->flags = 0;
5400
5401 return 1;
5402}
5403
Emeric Brunfb510ea2012-10-05 12:00:26 +02005404/* parse the "ca-file" bind keyword */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01005405static 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 +02005406{
5407 if (!*args[cur_arg + 1]) {
5408 if (err)
5409 memprintf(err, "'%s' : missing CAfile path", args[cur_arg]);
5410 return ERR_ALERT | ERR_FATAL;
5411 }
5412
Willy Tarreauef934602016-12-22 23:12:01 +01005413 if ((*args[cur_arg + 1] != '/') && global_ssl.ca_base)
5414 memprintf(&conf->ca_file, "%s/%s", global_ssl.ca_base, args[cur_arg + 1]);
Emeric Brunef42d922012-10-11 16:11:36 +02005415 else
5416 memprintf(&conf->ca_file, "%s", args[cur_arg + 1]);
Emeric Brunc8e8d122012-10-02 18:42:10 +02005417
Emeric Brund94b3fe2012-09-20 18:23:56 +02005418 return 0;
5419}
Emmanuel Hocdet98263292016-12-29 18:26:15 +01005420static int bind_parse_ca_file(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5421{
5422 return ssl_bind_parse_ca_file(args, cur_arg, px, &conf->ssl_conf, err);
5423}
Emeric Brund94b3fe2012-09-20 18:23:56 +02005424
Christopher Faulet31af49d2015-06-09 17:29:50 +02005425/* parse the "ca-sign-file" bind keyword */
5426static int bind_parse_ca_sign_file(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5427{
5428 if (!*args[cur_arg + 1]) {
5429 if (err)
5430 memprintf(err, "'%s' : missing CAfile path", args[cur_arg]);
5431 return ERR_ALERT | ERR_FATAL;
5432 }
5433
Willy Tarreauef934602016-12-22 23:12:01 +01005434 if ((*args[cur_arg + 1] != '/') && global_ssl.ca_base)
5435 memprintf(&conf->ca_sign_file, "%s/%s", global_ssl.ca_base, args[cur_arg + 1]);
Christopher Faulet31af49d2015-06-09 17:29:50 +02005436 else
5437 memprintf(&conf->ca_sign_file, "%s", args[cur_arg + 1]);
5438
5439 return 0;
5440}
5441
Bertrand Jacquinff13c062016-11-13 16:37:11 +00005442/* parse the "ca-sign-pass" bind keyword */
Christopher Faulet31af49d2015-06-09 17:29:50 +02005443static int bind_parse_ca_sign_pass(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5444{
5445 if (!*args[cur_arg + 1]) {
5446 if (err)
5447 memprintf(err, "'%s' : missing CAkey password", args[cur_arg]);
5448 return ERR_ALERT | ERR_FATAL;
5449 }
5450 memprintf(&conf->ca_sign_pass, "%s", args[cur_arg + 1]);
5451 return 0;
5452}
5453
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005454/* parse the "ciphers" bind keyword */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01005455static 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 +02005456{
5457 if (!*args[cur_arg + 1]) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02005458 memprintf(err, "'%s' : missing cipher suite", args[cur_arg]);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005459 return ERR_ALERT | ERR_FATAL;
5460 }
5461
Emeric Brun76d88952012-10-05 15:47:31 +02005462 free(conf->ciphers);
Willy Tarreau4348fad2012-09-20 16:48:07 +02005463 conf->ciphers = strdup(args[cur_arg + 1]);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005464 return 0;
5465}
Emmanuel Hocdet98263292016-12-29 18:26:15 +01005466static int bind_parse_ciphers(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5467{
5468 return ssl_bind_parse_ciphers(args, cur_arg, px, &conf->ssl_conf, err);
5469}
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005470/* parse the "crt" bind keyword */
Willy Tarreau4348fad2012-09-20 16:48:07 +02005471static 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 +02005472{
Willy Tarreau38011032013-08-13 16:59:39 +02005473 char path[MAXPATHLEN];
Willy Tarreaub75d6922014-04-14 18:05:41 +02005474
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005475 if (!*args[cur_arg + 1]) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02005476 memprintf(err, "'%s' : missing certificate location", args[cur_arg]);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005477 return ERR_ALERT | ERR_FATAL;
5478 }
5479
Willy Tarreauef934602016-12-22 23:12:01 +01005480 if ((*args[cur_arg + 1] != '/' ) && global_ssl.crt_base) {
5481 if ((strlen(global_ssl.crt_base) + 1 + strlen(args[cur_arg + 1]) + 1) > MAXPATHLEN) {
Emeric Brunc8e8d122012-10-02 18:42:10 +02005482 memprintf(err, "'%s' : path too long", args[cur_arg]);
5483 return ERR_ALERT | ERR_FATAL;
5484 }
Willy Tarreauef934602016-12-22 23:12:01 +01005485 snprintf(path, sizeof(path), "%s/%s", global_ssl.crt_base, args[cur_arg + 1]);
Willy Tarreau03209342016-12-22 17:08:28 +01005486 if (ssl_sock_load_cert(path, conf, err) > 0)
Emeric Brunc8e8d122012-10-02 18:42:10 +02005487 return ERR_ALERT | ERR_FATAL;
5488
5489 return 0;
5490 }
5491
Willy Tarreau03209342016-12-22 17:08:28 +01005492 if (ssl_sock_load_cert(args[cur_arg + 1], conf, err) > 0)
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005493 return ERR_ALERT | ERR_FATAL;
Emeric Brund94b3fe2012-09-20 18:23:56 +02005494
5495 return 0;
5496}
5497
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01005498/* parse the "crt-list" bind keyword */
5499static int bind_parse_crt_list(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5500{
5501 if (!*args[cur_arg + 1]) {
5502 memprintf(err, "'%s' : missing certificate location", args[cur_arg]);
5503 return ERR_ALERT | ERR_FATAL;
5504 }
5505
Emmanuel Hocdet98263292016-12-29 18:26:15 +01005506 if (ssl_sock_load_cert_list_file(args[cur_arg + 1], conf, px, err) > 0) {
Willy Tarreauad1731d2013-04-02 17:35:58 +02005507 memprintf(err, "'%s' : %s", args[cur_arg], *err);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01005508 return ERR_ALERT | ERR_FATAL;
Willy Tarreauad1731d2013-04-02 17:35:58 +02005509 }
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01005510
5511 return 0;
5512}
5513
Emeric Brunfb510ea2012-10-05 12:00:26 +02005514/* parse the "crl-file" bind keyword */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01005515static 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 +02005516{
Emeric Brun051cdab2012-10-02 19:25:50 +02005517#ifndef X509_V_FLAG_CRL_CHECK
5518 if (err)
5519 memprintf(err, "'%s' : library does not support CRL verify", args[cur_arg]);
5520 return ERR_ALERT | ERR_FATAL;
5521#else
Emeric Brund94b3fe2012-09-20 18:23:56 +02005522 if (!*args[cur_arg + 1]) {
5523 if (err)
5524 memprintf(err, "'%s' : missing CRLfile path", args[cur_arg]);
5525 return ERR_ALERT | ERR_FATAL;
5526 }
Emeric Brun2b58d042012-09-20 17:10:03 +02005527
Willy Tarreauef934602016-12-22 23:12:01 +01005528 if ((*args[cur_arg + 1] != '/') && global_ssl.ca_base)
5529 memprintf(&conf->crl_file, "%s/%s", global_ssl.ca_base, args[cur_arg + 1]);
Emeric Brunef42d922012-10-11 16:11:36 +02005530 else
5531 memprintf(&conf->crl_file, "%s", args[cur_arg + 1]);
Emeric Brunc8e8d122012-10-02 18:42:10 +02005532
Emeric Brun2b58d042012-09-20 17:10:03 +02005533 return 0;
Emeric Brun051cdab2012-10-02 19:25:50 +02005534#endif
Emeric Brun2b58d042012-09-20 17:10:03 +02005535}
Emmanuel Hocdet98263292016-12-29 18:26:15 +01005536static int bind_parse_crl_file(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5537{
5538 return ssl_bind_parse_crl_file(args, cur_arg, px, &conf->ssl_conf, err);
5539}
Emeric Brun2b58d042012-09-20 17:10:03 +02005540
Emmanuel Hocdete7f2b732017-01-09 16:15:54 +01005541/* parse the "curves" bind keyword keyword */
5542static int ssl_bind_parse_curves(char **args, int cur_arg, struct proxy *px, struct ssl_bind_conf *conf, char **err)
5543{
5544#if OPENSSL_VERSION_NUMBER >= 0x1000200fL
5545 if (!*args[cur_arg + 1]) {
5546 if (err)
5547 memprintf(err, "'%s' : missing curve suite", args[cur_arg]);
5548 return ERR_ALERT | ERR_FATAL;
5549 }
5550 conf->curves = strdup(args[cur_arg + 1]);
5551 return 0;
5552#else
5553 if (err)
5554 memprintf(err, "'%s' : library does not support curve suite", args[cur_arg]);
5555 return ERR_ALERT | ERR_FATAL;
5556#endif
5557}
5558static int bind_parse_curves(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5559{
5560 return ssl_bind_parse_curves(args, cur_arg, px, &conf->ssl_conf, err);
5561}
5562
Bertrand Jacquinff13c062016-11-13 16:37:11 +00005563/* parse the "ecdhe" bind keyword keyword */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01005564static 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 +02005565{
5566#if OPENSSL_VERSION_NUMBER < 0x0090800fL
5567 if (err)
5568 memprintf(err, "'%s' : library does not support elliptic curve Diffie-Hellman (too old)", args[cur_arg]);
5569 return ERR_ALERT | ERR_FATAL;
5570#elif defined(OPENSSL_NO_ECDH)
5571 if (err)
5572 memprintf(err, "'%s' : library does not support elliptic curve Diffie-Hellman (disabled via OPENSSL_NO_ECDH)", args[cur_arg]);
5573 return ERR_ALERT | ERR_FATAL;
5574#else
5575 if (!*args[cur_arg + 1]) {
5576 if (err)
5577 memprintf(err, "'%s' : missing named curve", args[cur_arg]);
5578 return ERR_ALERT | ERR_FATAL;
5579 }
5580
5581 conf->ecdhe = strdup(args[cur_arg + 1]);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005582
5583 return 0;
Emeric Brun2b58d042012-09-20 17:10:03 +02005584#endif
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005585}
Emmanuel Hocdet98263292016-12-29 18:26:15 +01005586static int bind_parse_ecdhe(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5587{
5588 return ssl_bind_parse_ecdhe(args, cur_arg, px, &conf->ssl_conf, err);
5589}
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005590
Bertrand Jacquinff13c062016-11-13 16:37:11 +00005591/* parse the "crt-ignore-err" and "ca-ignore-err" bind keywords */
Emeric Brun81c00f02012-09-21 14:31:21 +02005592static int bind_parse_ignore_err(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5593{
5594 int code;
5595 char *p = args[cur_arg + 1];
5596 unsigned long long *ignerr = &conf->crt_ignerr;
5597
5598 if (!*p) {
5599 if (err)
5600 memprintf(err, "'%s' : missing error IDs list", args[cur_arg]);
5601 return ERR_ALERT | ERR_FATAL;
5602 }
5603
5604 if (strcmp(args[cur_arg], "ca-ignore-err") == 0)
5605 ignerr = &conf->ca_ignerr;
5606
5607 if (strcmp(p, "all") == 0) {
5608 *ignerr = ~0ULL;
5609 return 0;
5610 }
5611
5612 while (p) {
5613 code = atoi(p);
5614 if ((code <= 0) || (code > 63)) {
5615 if (err)
5616 memprintf(err, "'%s' : ID '%d' out of range (1..63) in error IDs list '%s'",
5617 args[cur_arg], code, args[cur_arg + 1]);
5618 return ERR_ALERT | ERR_FATAL;
5619 }
5620 *ignerr |= 1ULL << code;
5621 p = strchr(p, ',');
5622 if (p)
5623 p++;
5624 }
5625
Emeric Brun2cb7ae52012-10-05 14:14:21 +02005626 return 0;
5627}
5628
5629/* parse the "force-sslv3" bind keyword */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01005630static 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 +02005631{
5632 conf->ssl_options |= BC_SSL_O_USE_SSLV3;
5633 return 0;
5634}
Emmanuel Hocdet98263292016-12-29 18:26:15 +01005635static int bind_parse_force_sslv3(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5636{
5637 return ssl_bind_parse_force_sslv3(args, cur_arg, px, &conf->ssl_conf, err);
5638}
Emeric Brun2cb7ae52012-10-05 14:14:21 +02005639
5640/* parse the "force-tlsv10" bind keyword */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01005641static 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 +02005642{
5643 conf->ssl_options |= BC_SSL_O_USE_TLSV10;
Emeric Brun2d0c4822012-10-02 13:45:20 +02005644 return 0;
5645}
Emmanuel Hocdet98263292016-12-29 18:26:15 +01005646static int bind_parse_force_tlsv10(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5647{
5648 return ssl_bind_parse_force_tlsv10(args, cur_arg, px, &conf->ssl_conf, err);
5649}
Emeric Brun2d0c4822012-10-02 13:45:20 +02005650
Emeric Brun2cb7ae52012-10-05 14:14:21 +02005651/* parse the "force-tlsv11" bind keyword */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01005652static 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 +02005653{
5654#if SSL_OP_NO_TLSv1_1
5655 conf->ssl_options |= BC_SSL_O_USE_TLSV11;
5656 return 0;
5657#else
5658 if (err)
5659 memprintf(err, "'%s' : library does not support protocol TLSv1.1", args[cur_arg]);
5660 return ERR_ALERT | ERR_FATAL;
5661#endif
5662}
Emmanuel Hocdet98263292016-12-29 18:26:15 +01005663static int bind_parse_force_tlsv11(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5664{
5665 return ssl_bind_parse_force_tlsv11(args, cur_arg, px, &conf->ssl_conf, err);
5666}
Emeric Brun2cb7ae52012-10-05 14:14:21 +02005667
5668/* parse the "force-tlsv12" bind keyword */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01005669static 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 +02005670{
5671#if SSL_OP_NO_TLSv1_2
5672 conf->ssl_options |= BC_SSL_O_USE_TLSV12;
5673 return 0;
5674#else
5675 if (err)
5676 memprintf(err, "'%s' : library does not support protocol TLSv1.2", args[cur_arg]);
5677 return ERR_ALERT | ERR_FATAL;
5678#endif
5679}
Emmanuel Hocdet98263292016-12-29 18:26:15 +01005680static int bind_parse_force_tlsv12(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5681{
5682 return ssl_bind_parse_force_tlsv12(args, cur_arg, px, &conf->ssl_conf, err);
5683}
Emeric Brun2cb7ae52012-10-05 14:14:21 +02005684
Emeric Brun2d0c4822012-10-02 13:45:20 +02005685/* parse the "no-tls-tickets" bind keyword */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01005686static 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 +02005687{
Emeric Brun89675492012-10-05 13:48:26 +02005688 conf->ssl_options |= BC_SSL_O_NO_TLS_TICKETS;
Emeric Brun81c00f02012-09-21 14:31:21 +02005689 return 0;
5690}
Emmanuel Hocdet98263292016-12-29 18:26:15 +01005691static int bind_parse_no_tls_tickets(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5692{
5693 return ssl_bind_parse_no_tls_tickets(args, cur_arg, px, &conf->ssl_conf, err);
5694}
Emeric Brun2d0c4822012-10-02 13:45:20 +02005695
Emeric Brun9b3009b2012-10-05 11:55:06 +02005696/* parse the "no-sslv3" bind keyword */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01005697static 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 +02005698{
Emeric Brun89675492012-10-05 13:48:26 +02005699 conf->ssl_options |= BC_SSL_O_NO_SSLV3;
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005700 return 0;
5701}
Emmanuel Hocdet98263292016-12-29 18:26:15 +01005702static int bind_parse_no_sslv3(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5703{
5704 return ssl_bind_parse_no_sslv3(args, cur_arg, px, &conf->ssl_conf, err);
5705}
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005706
Emeric Brun9b3009b2012-10-05 11:55:06 +02005707/* parse the "no-tlsv10" bind keyword */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01005708static 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 +02005709{
Emeric Brun89675492012-10-05 13:48:26 +02005710 conf->ssl_options |= BC_SSL_O_NO_TLSV10;
Emeric Brunc0ff4922012-09-28 19:37:02 +02005711 return 0;
5712}
Emmanuel Hocdet98263292016-12-29 18:26:15 +01005713static int bind_parse_no_tlsv10(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5714{
5715 return ssl_bind_parse_no_tlsv10(args, cur_arg, px, &conf->ssl_conf, err);
5716}
Emeric Brunc0ff4922012-09-28 19:37:02 +02005717
Emeric Brun9b3009b2012-10-05 11:55:06 +02005718/* parse the "no-tlsv11" bind keyword */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01005719static 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 +02005720{
Emeric Brun89675492012-10-05 13:48:26 +02005721 conf->ssl_options |= BC_SSL_O_NO_TLSV11;
Emeric Brunc0ff4922012-09-28 19:37:02 +02005722 return 0;
5723}
Emmanuel Hocdet98263292016-12-29 18:26:15 +01005724static int bind_parse_no_tlsv11(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5725{
5726 return ssl_bind_parse_no_tlsv11(args, cur_arg, px, &conf->ssl_conf, err);
5727}
Emeric Brunc0ff4922012-09-28 19:37:02 +02005728
Emeric Brun9b3009b2012-10-05 11:55:06 +02005729/* parse the "no-tlsv12" bind keyword */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01005730static 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 +02005731{
Emeric Brun89675492012-10-05 13:48:26 +02005732 conf->ssl_options |= BC_SSL_O_NO_TLSV12;
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005733 return 0;
5734}
Emmanuel Hocdet98263292016-12-29 18:26:15 +01005735static int bind_parse_no_tlsv12(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5736{
5737 return ssl_bind_parse_no_tlsv12(args, cur_arg, px, &conf->ssl_conf, err);
5738}
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005739
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02005740/* parse the "npn" bind keyword */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01005741static 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 +02005742{
5743#ifdef OPENSSL_NPN_NEGOTIATED
5744 char *p1, *p2;
5745
5746 if (!*args[cur_arg + 1]) {
5747 memprintf(err, "'%s' : missing the comma-delimited NPN protocol suite", args[cur_arg]);
5748 return ERR_ALERT | ERR_FATAL;
5749 }
5750
5751 free(conf->npn_str);
5752
Willy Tarreau3724da12016-02-12 17:11:12 +01005753 /* the NPN string is built as a suite of (<len> <name>)*,
5754 * so we reuse each comma to store the next <len> and need
5755 * one more for the end of the string.
5756 */
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02005757 conf->npn_len = strlen(args[cur_arg + 1]) + 1;
Willy Tarreau3724da12016-02-12 17:11:12 +01005758 conf->npn_str = calloc(1, conf->npn_len + 1);
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02005759 memcpy(conf->npn_str + 1, args[cur_arg + 1], conf->npn_len);
5760
5761 /* replace commas with the name length */
5762 p1 = conf->npn_str;
5763 p2 = p1 + 1;
5764 while (1) {
5765 p2 = memchr(p1 + 1, ',', conf->npn_str + conf->npn_len - (p1 + 1));
5766 if (!p2)
5767 p2 = p1 + 1 + strlen(p1 + 1);
5768
5769 if (p2 - (p1 + 1) > 255) {
5770 *p2 = '\0';
5771 memprintf(err, "'%s' : NPN protocol name too long : '%s'", args[cur_arg], p1 + 1);
5772 return ERR_ALERT | ERR_FATAL;
5773 }
5774
5775 *p1 = p2 - (p1 + 1);
5776 p1 = p2;
5777
5778 if (!*p2)
5779 break;
5780
5781 *(p2++) = '\0';
5782 }
5783 return 0;
5784#else
5785 if (err)
5786 memprintf(err, "'%s' : library does not support TLS NPN extension", args[cur_arg]);
5787 return ERR_ALERT | ERR_FATAL;
5788#endif
5789}
5790
Emmanuel Hocdet98263292016-12-29 18:26:15 +01005791static int bind_parse_npn(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5792{
5793 return ssl_bind_parse_npn(args, cur_arg, px, &conf->ssl_conf, err);
5794}
5795
Willy Tarreauab861d32013-04-02 02:30:41 +02005796/* parse the "alpn" bind keyword */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01005797static 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 +02005798{
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01005799#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Willy Tarreauab861d32013-04-02 02:30:41 +02005800 char *p1, *p2;
5801
5802 if (!*args[cur_arg + 1]) {
5803 memprintf(err, "'%s' : missing the comma-delimited ALPN protocol suite", args[cur_arg]);
5804 return ERR_ALERT | ERR_FATAL;
5805 }
5806
5807 free(conf->alpn_str);
5808
Marcoen Hirschbergbef60912016-02-12 17:05:24 +01005809 /* the ALPN string is built as a suite of (<len> <name>)*,
5810 * so we reuse each comma to store the next <len> and need
5811 * one more for the end of the string.
5812 */
Willy Tarreauab861d32013-04-02 02:30:41 +02005813 conf->alpn_len = strlen(args[cur_arg + 1]) + 1;
Marcoen Hirschbergbef60912016-02-12 17:05:24 +01005814 conf->alpn_str = calloc(1, conf->alpn_len + 1);
Willy Tarreauab861d32013-04-02 02:30:41 +02005815 memcpy(conf->alpn_str + 1, args[cur_arg + 1], conf->alpn_len);
5816
5817 /* replace commas with the name length */
5818 p1 = conf->alpn_str;
5819 p2 = p1 + 1;
5820 while (1) {
5821 p2 = memchr(p1 + 1, ',', conf->alpn_str + conf->alpn_len - (p1 + 1));
5822 if (!p2)
5823 p2 = p1 + 1 + strlen(p1 + 1);
5824
5825 if (p2 - (p1 + 1) > 255) {
5826 *p2 = '\0';
5827 memprintf(err, "'%s' : ALPN protocol name too long : '%s'", args[cur_arg], p1 + 1);
5828 return ERR_ALERT | ERR_FATAL;
5829 }
5830
5831 *p1 = p2 - (p1 + 1);
5832 p1 = p2;
5833
5834 if (!*p2)
5835 break;
5836
5837 *(p2++) = '\0';
5838 }
5839 return 0;
5840#else
5841 if (err)
5842 memprintf(err, "'%s' : library does not support TLS ALPN extension", args[cur_arg]);
5843 return ERR_ALERT | ERR_FATAL;
5844#endif
5845}
5846
Emmanuel Hocdet98263292016-12-29 18:26:15 +01005847static int bind_parse_alpn(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5848{
5849 return ssl_bind_parse_alpn(args, cur_arg, px, &conf->ssl_conf, err);
5850}
5851
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005852/* parse the "ssl" bind keyword */
Willy Tarreau4348fad2012-09-20 16:48:07 +02005853static 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 +02005854{
Willy Tarreau71a8c7c2016-12-21 22:04:54 +01005855 conf->xprt = &ssl_sock;
Willy Tarreau4348fad2012-09-20 16:48:07 +02005856 conf->is_ssl = 1;
Emeric Brun76d88952012-10-05 15:47:31 +02005857
Emmanuel Hocdet98263292016-12-29 18:26:15 +01005858 if (global_ssl.listen_default_ciphers && !conf->ssl_conf.ciphers)
5859 conf->ssl_conf.ciphers = strdup(global_ssl.listen_default_ciphers);
5860 conf->ssl_conf.ssl_options |= global_ssl.listen_default_ssloptions;
Emeric Brun76d88952012-10-05 15:47:31 +02005861
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005862 return 0;
5863}
5864
Christopher Faulet31af49d2015-06-09 17:29:50 +02005865/* parse the "generate-certificates" bind keyword */
5866static int bind_parse_generate_certs(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5867{
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +01005868#if (defined SSL_CTRL_SET_TLSEXT_HOSTNAME && !defined SSL_NO_GENERATE_CERTIFICATES)
Christopher Faulet31af49d2015-06-09 17:29:50 +02005869 conf->generate_certs = 1;
5870#else
5871 memprintf(err, "%sthis version of openssl cannot generate SSL certificates.\n",
5872 err && *err ? *err : "");
5873#endif
5874 return 0;
5875}
5876
Emmanuel Hocdet65623372013-01-24 17:17:15 +01005877/* parse the "strict-sni" bind keyword */
5878static int bind_parse_strict_sni(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5879{
5880 conf->strict_sni = 1;
5881 return 0;
Nenad Merdanovic05552d42015-02-27 19:56:49 +01005882}
5883
5884/* parse the "tls-ticket-keys" bind keyword */
5885static int bind_parse_tls_ticket_keys(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5886{
5887#if (defined SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB && TLS_TICKETS_NO > 0)
5888 FILE *f;
5889 int i = 0;
5890 char thisline[LINESIZE];
Nenad Merdanovic146defa2015-05-09 08:46:00 +02005891 struct tls_keys_ref *keys_ref;
Nenad Merdanovic05552d42015-02-27 19:56:49 +01005892
5893 if (!*args[cur_arg + 1]) {
5894 if (err)
5895 memprintf(err, "'%s' : missing TLS ticket keys file path", args[cur_arg]);
5896 return ERR_ALERT | ERR_FATAL;
5897 }
5898
Nenad Merdanovic200b0fa2015-05-09 08:46:01 +02005899 keys_ref = tlskeys_ref_lookup(args[cur_arg + 1]);
5900 if(keys_ref) {
5901 conf->keys_ref = keys_ref;
5902 return 0;
5903 }
5904
Vincent Bernat02779b62016-04-03 13:48:43 +02005905 keys_ref = malloc(sizeof(*keys_ref));
Nenad Merdanovic146defa2015-05-09 08:46:00 +02005906 keys_ref->tlskeys = malloc(TLS_TICKETS_NO * sizeof(struct tls_sess_key));
Nenad Merdanovic05552d42015-02-27 19:56:49 +01005907
5908 if ((f = fopen(args[cur_arg + 1], "r")) == NULL) {
5909 if (err)
5910 memprintf(err, "'%s' : unable to load ssl tickets keys file", args[cur_arg+1]);
5911 return ERR_ALERT | ERR_FATAL;
5912 }
5913
Nenad Merdanovic146defa2015-05-09 08:46:00 +02005914 keys_ref->filename = strdup(args[cur_arg + 1]);
5915
Nenad Merdanovic05552d42015-02-27 19:56:49 +01005916 while (fgets(thisline, sizeof(thisline), f) != NULL) {
5917 int len = strlen(thisline);
5918 /* Strip newline characters from the end */
5919 if(thisline[len - 1] == '\n')
5920 thisline[--len] = 0;
5921
5922 if(thisline[len - 1] == '\r')
5923 thisline[--len] = 0;
5924
Nenad Merdanovic146defa2015-05-09 08:46:00 +02005925 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 +01005926 if (err)
5927 memprintf(err, "'%s' : unable to decode base64 key on line %d", args[cur_arg+1], i + 1);
mildis16aa0152016-06-22 17:46:29 +02005928 fclose(f);
Nenad Merdanovic05552d42015-02-27 19:56:49 +01005929 return ERR_ALERT | ERR_FATAL;
5930 }
5931 i++;
5932 }
5933
5934 if (i < TLS_TICKETS_NO) {
5935 if (err)
5936 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 +02005937 fclose(f);
Nenad Merdanovic05552d42015-02-27 19:56:49 +01005938 return ERR_ALERT | ERR_FATAL;
5939 }
5940
5941 fclose(f);
5942
5943 /* Use penultimate key for encryption, handle when TLS_TICKETS_NO = 1 */
Nenad Merdanovic17891152016-03-25 22:16:57 +01005944 i -= 2;
5945 keys_ref->tls_ticket_enc_index = i < 0 ? 0 : i % TLS_TICKETS_NO;
Nenad Merdanovic200b0fa2015-05-09 08:46:01 +02005946 keys_ref->unique_id = -1;
Nenad Merdanovic146defa2015-05-09 08:46:00 +02005947 conf->keys_ref = keys_ref;
Nenad Merdanovic05552d42015-02-27 19:56:49 +01005948
Nenad Merdanovic200b0fa2015-05-09 08:46:01 +02005949 LIST_ADD(&tlskeys_reference, &keys_ref->list);
5950
Nenad Merdanovic05552d42015-02-27 19:56:49 +01005951 return 0;
5952#else
5953 if (err)
5954 memprintf(err, "'%s' : TLS ticket callback extension not supported", args[cur_arg]);
5955 return ERR_ALERT | ERR_FATAL;
5956#endif /* SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB */
Emmanuel Hocdet65623372013-01-24 17:17:15 +01005957}
5958
Emeric Brund94b3fe2012-09-20 18:23:56 +02005959/* parse the "verify" bind keyword */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01005960static 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 +02005961{
5962 if (!*args[cur_arg + 1]) {
5963 if (err)
5964 memprintf(err, "'%s' : missing verify method", args[cur_arg]);
5965 return ERR_ALERT | ERR_FATAL;
5966 }
5967
5968 if (strcmp(args[cur_arg + 1], "none") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01005969 conf->verify = SSL_SOCK_VERIFY_NONE;
Emeric Brund94b3fe2012-09-20 18:23:56 +02005970 else if (strcmp(args[cur_arg + 1], "optional") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01005971 conf->verify = SSL_SOCK_VERIFY_OPTIONAL;
Emeric Brund94b3fe2012-09-20 18:23:56 +02005972 else if (strcmp(args[cur_arg + 1], "required") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01005973 conf->verify = SSL_SOCK_VERIFY_REQUIRED;
Emeric Brund94b3fe2012-09-20 18:23:56 +02005974 else {
5975 if (err)
5976 memprintf(err, "'%s' : unknown verify method '%s', only 'none', 'optional', and 'required' are supported\n",
5977 args[cur_arg], args[cur_arg + 1]);
5978 return ERR_ALERT | ERR_FATAL;
5979 }
5980
5981 return 0;
5982}
Emmanuel Hocdet98263292016-12-29 18:26:15 +01005983static int bind_parse_verify(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5984{
5985 return ssl_bind_parse_verify(args, cur_arg, px, &conf->ssl_conf, err);
5986}
Emeric Brund94b3fe2012-09-20 18:23:56 +02005987
Willy Tarreau92faadf2012-10-10 23:04:25 +02005988/************** "server" keywords ****************/
5989
Emeric Brunef42d922012-10-11 16:11:36 +02005990/* parse the "ca-file" server keyword */
5991static int srv_parse_ca_file(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5992{
5993 if (!*args[*cur_arg + 1]) {
5994 if (err)
5995 memprintf(err, "'%s' : missing CAfile path", args[*cur_arg]);
5996 return ERR_ALERT | ERR_FATAL;
5997 }
5998
Willy Tarreauef934602016-12-22 23:12:01 +01005999 if ((*args[*cur_arg + 1] != '/') && global_ssl.ca_base)
6000 memprintf(&newsrv->ssl_ctx.ca_file, "%s/%s", global_ssl.ca_base, args[*cur_arg + 1]);
Emeric Brunef42d922012-10-11 16:11:36 +02006001 else
6002 memprintf(&newsrv->ssl_ctx.ca_file, "%s", args[*cur_arg + 1]);
6003
6004 return 0;
6005}
6006
Willy Tarreau92faadf2012-10-10 23:04:25 +02006007/* parse the "check-ssl" server keyword */
6008static int srv_parse_check_ssl(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
6009{
6010 newsrv->check.use_ssl = 1;
Willy Tarreauef934602016-12-22 23:12:01 +01006011 if (global_ssl.connect_default_ciphers && !newsrv->ssl_ctx.ciphers)
6012 newsrv->ssl_ctx.ciphers = strdup(global_ssl.connect_default_ciphers);
6013 newsrv->ssl_ctx.options |= global_ssl.connect_default_ssloptions;
Willy Tarreau92faadf2012-10-10 23:04:25 +02006014 return 0;
6015}
6016
6017/* parse the "ciphers" server keyword */
6018static int srv_parse_ciphers(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
6019{
6020 if (!*args[*cur_arg + 1]) {
6021 memprintf(err, "'%s' : missing cipher suite", args[*cur_arg]);
6022 return ERR_ALERT | ERR_FATAL;
6023 }
6024
6025 free(newsrv->ssl_ctx.ciphers);
6026 newsrv->ssl_ctx.ciphers = strdup(args[*cur_arg + 1]);
6027 return 0;
6028}
6029
Emeric Brunef42d922012-10-11 16:11:36 +02006030/* parse the "crl-file" server keyword */
6031static int srv_parse_crl_file(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
6032{
6033#ifndef X509_V_FLAG_CRL_CHECK
6034 if (err)
6035 memprintf(err, "'%s' : library does not support CRL verify", args[*cur_arg]);
6036 return ERR_ALERT | ERR_FATAL;
6037#else
6038 if (!*args[*cur_arg + 1]) {
6039 if (err)
6040 memprintf(err, "'%s' : missing CRLfile path", args[*cur_arg]);
6041 return ERR_ALERT | ERR_FATAL;
6042 }
6043
Willy Tarreauef934602016-12-22 23:12:01 +01006044 if ((*args[*cur_arg + 1] != '/') && global_ssl.ca_base)
6045 memprintf(&newsrv->ssl_ctx.crl_file, "%s/%s", global_ssl.ca_base, args[*cur_arg + 1]);
Emeric Brunef42d922012-10-11 16:11:36 +02006046 else
6047 memprintf(&newsrv->ssl_ctx.crl_file, "%s", args[*cur_arg + 1]);
6048
6049 return 0;
6050#endif
6051}
6052
Emeric Bruna7aa3092012-10-26 12:58:00 +02006053/* parse the "crt" server keyword */
6054static int srv_parse_crt(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
6055{
6056 if (!*args[*cur_arg + 1]) {
6057 if (err)
6058 memprintf(err, "'%s' : missing certificate file path", args[*cur_arg]);
6059 return ERR_ALERT | ERR_FATAL;
6060 }
6061
Willy Tarreauef934602016-12-22 23:12:01 +01006062 if ((*args[*cur_arg + 1] != '/') && global_ssl.crt_base)
6063 memprintf(&newsrv->ssl_ctx.client_crt, "%s/%s", global_ssl.ca_base, args[*cur_arg + 1]);
Emeric Bruna7aa3092012-10-26 12:58:00 +02006064 else
6065 memprintf(&newsrv->ssl_ctx.client_crt, "%s", args[*cur_arg + 1]);
6066
6067 return 0;
6068}
Emeric Brunef42d922012-10-11 16:11:36 +02006069
Willy Tarreau92faadf2012-10-10 23:04:25 +02006070/* parse the "force-sslv3" server keyword */
6071static int srv_parse_force_sslv3(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
6072{
6073 newsrv->ssl_ctx.options |= SRV_SSL_O_USE_SSLV3;
6074 return 0;
6075}
6076
6077/* parse the "force-tlsv10" server keyword */
6078static int srv_parse_force_tlsv10(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
6079{
6080 newsrv->ssl_ctx.options |= SRV_SSL_O_USE_TLSV10;
6081 return 0;
6082}
6083
6084/* parse the "force-tlsv11" server keyword */
6085static int srv_parse_force_tlsv11(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
6086{
6087#if SSL_OP_NO_TLSv1_1
6088 newsrv->ssl_ctx.options |= SRV_SSL_O_USE_TLSV11;
6089 return 0;
6090#else
6091 if (err)
6092 memprintf(err, "'%s' : library does not support protocol TLSv1.1", args[*cur_arg]);
6093 return ERR_ALERT | ERR_FATAL;
6094#endif
6095}
6096
6097/* parse the "force-tlsv12" server keyword */
6098static int srv_parse_force_tlsv12(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
6099{
6100#if SSL_OP_NO_TLSv1_2
6101 newsrv->ssl_ctx.options |= SRV_SSL_O_USE_TLSV12;
6102 return 0;
6103#else
6104 if (err)
6105 memprintf(err, "'%s' : library does not support protocol TLSv1.2", args[*cur_arg]);
6106 return ERR_ALERT | ERR_FATAL;
6107#endif
6108}
6109
Willy Tarreau2a3fb1c2015-02-05 16:47:07 +01006110/* parse the "no-ssl-reuse" server keyword */
6111static int srv_parse_no_ssl_reuse(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
6112{
6113 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_REUSE;
6114 return 0;
6115}
6116
Willy Tarreau92faadf2012-10-10 23:04:25 +02006117/* parse the "no-sslv3" server keyword */
6118static int srv_parse_no_sslv3(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
6119{
6120 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_SSLV3;
6121 return 0;
6122}
6123
6124/* parse the "no-tlsv10" server keyword */
6125static int srv_parse_no_tlsv10(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
6126{
6127 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_TLSV10;
6128 return 0;
6129}
6130
6131/* parse the "no-tlsv11" server keyword */
6132static int srv_parse_no_tlsv11(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
6133{
6134 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_TLSV11;
6135 return 0;
6136}
6137
6138/* parse the "no-tlsv12" server keyword */
6139static int srv_parse_no_tlsv12(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
6140{
6141 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_TLSV12;
6142 return 0;
6143}
6144
Emeric Brunf9c5c472012-10-11 15:28:34 +02006145/* parse the "no-tls-tickets" server keyword */
6146static int srv_parse_no_tls_tickets(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
6147{
6148 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_TLS_TICKETS;
6149 return 0;
6150}
David Safb76832014-05-08 23:42:08 -04006151/* parse the "send-proxy-v2-ssl" server keyword */
6152static int srv_parse_send_proxy_ssl(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
6153{
6154 newsrv->pp_opts |= SRV_PP_V2;
6155 newsrv->pp_opts |= SRV_PP_V2_SSL;
6156 return 0;
6157}
6158
6159/* parse the "send-proxy-v2-ssl-cn" server keyword */
6160static int srv_parse_send_proxy_cn(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
6161{
6162 newsrv->pp_opts |= SRV_PP_V2;
6163 newsrv->pp_opts |= SRV_PP_V2_SSL;
6164 newsrv->pp_opts |= SRV_PP_V2_SSL_CN;
6165 return 0;
6166}
Emeric Brunf9c5c472012-10-11 15:28:34 +02006167
Willy Tarreau732eac42015-07-09 11:40:25 +02006168/* parse the "sni" server keyword */
6169static int srv_parse_sni(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
6170{
6171#ifndef SSL_CTRL_SET_TLSEXT_HOSTNAME
6172 memprintf(err, "'%s' : the current SSL library doesn't support the SNI TLS extension", args[*cur_arg]);
6173 return ERR_ALERT | ERR_FATAL;
6174#else
Cyril Bonté23d19d62016-03-07 22:13:22 +01006175 int idx;
Willy Tarreau732eac42015-07-09 11:40:25 +02006176 struct sample_expr *expr;
6177
6178 if (!*args[*cur_arg + 1]) {
6179 memprintf(err, "'%s' : missing sni expression", args[*cur_arg]);
6180 return ERR_ALERT | ERR_FATAL;
6181 }
6182
Cyril Bonté23d19d62016-03-07 22:13:22 +01006183 idx = (*cur_arg) + 1;
Willy Tarreau732eac42015-07-09 11:40:25 +02006184 proxy->conf.args.ctx = ARGC_SRV;
6185
Cyril Bonté23d19d62016-03-07 22:13:22 +01006186 expr = sample_parse_expr((char **)args, &idx, px->conf.file, px->conf.line, err, &proxy->conf.args);
Willy Tarreau732eac42015-07-09 11:40:25 +02006187 if (!expr) {
6188 memprintf(err, "error detected while parsing sni expression : %s", *err);
6189 return ERR_ALERT | ERR_FATAL;
6190 }
6191
6192 if (!(expr->fetch->val & SMP_VAL_BE_SRV_CON)) {
6193 memprintf(err, "error detected while parsing sni expression : "
6194 " fetch method '%s' extracts information from '%s', none of which is available here.\n",
Cyril Bonté23d19d62016-03-07 22:13:22 +01006195 args[idx-1], sample_src_names(expr->fetch->use));
Willy Tarreau732eac42015-07-09 11:40:25 +02006196 return ERR_ALERT | ERR_FATAL;
6197 }
6198
6199 px->http_needed |= !!(expr->fetch->use & SMP_USE_HTTP_ANY);
6200 newsrv->ssl_ctx.sni = expr;
6201 return 0;
6202#endif
6203}
6204
Willy Tarreau92faadf2012-10-10 23:04:25 +02006205/* parse the "ssl" server keyword */
6206static int srv_parse_ssl(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
6207{
6208 newsrv->use_ssl = 1;
Willy Tarreauef934602016-12-22 23:12:01 +01006209 if (global_ssl.connect_default_ciphers && !newsrv->ssl_ctx.ciphers)
6210 newsrv->ssl_ctx.ciphers = strdup(global_ssl.connect_default_ciphers);
Willy Tarreau92faadf2012-10-10 23:04:25 +02006211 return 0;
6212}
6213
Emeric Brunef42d922012-10-11 16:11:36 +02006214/* parse the "verify" server keyword */
6215static int srv_parse_verify(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
6216{
6217 if (!*args[*cur_arg + 1]) {
6218 if (err)
6219 memprintf(err, "'%s' : missing verify method", args[*cur_arg]);
6220 return ERR_ALERT | ERR_FATAL;
6221 }
6222
6223 if (strcmp(args[*cur_arg + 1], "none") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01006224 newsrv->ssl_ctx.verify = SSL_SOCK_VERIFY_NONE;
Emeric Brunef42d922012-10-11 16:11:36 +02006225 else if (strcmp(args[*cur_arg + 1], "required") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01006226 newsrv->ssl_ctx.verify = SSL_SOCK_VERIFY_REQUIRED;
Emeric Brunef42d922012-10-11 16:11:36 +02006227 else {
6228 if (err)
6229 memprintf(err, "'%s' : unknown verify method '%s', only 'none' and 'required' are supported\n",
6230 args[*cur_arg], args[*cur_arg + 1]);
6231 return ERR_ALERT | ERR_FATAL;
6232 }
6233
Evan Broderbe554312013-06-27 00:05:25 -07006234 return 0;
6235}
6236
6237/* parse the "verifyhost" server keyword */
6238static int srv_parse_verifyhost(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
6239{
6240 if (!*args[*cur_arg + 1]) {
6241 if (err)
6242 memprintf(err, "'%s' : missing hostname to verify against", args[*cur_arg]);
6243 return ERR_ALERT | ERR_FATAL;
6244 }
6245
6246 newsrv->ssl_ctx.verify_host = strdup(args[*cur_arg + 1]);
6247
Emeric Brunef42d922012-10-11 16:11:36 +02006248 return 0;
6249}
6250
Emeric Brun2c86cbf2014-10-30 15:56:50 +01006251/* parse the "ssl-default-bind-options" keyword in global section */
6252static int ssl_parse_default_bind_options(char **args, int section_type, struct proxy *curpx,
6253 struct proxy *defpx, const char *file, int line,
6254 char **err) {
6255 int i = 1;
6256
6257 if (*(args[i]) == 0) {
6258 memprintf(err, "global statement '%s' expects an option as an argument.", args[0]);
6259 return -1;
6260 }
6261 while (*(args[i])) {
6262 if (!strcmp(args[i], "no-sslv3"))
Willy Tarreauef934602016-12-22 23:12:01 +01006263 global_ssl.listen_default_ssloptions |= BC_SSL_O_NO_SSLV3;
Emeric Brun2c86cbf2014-10-30 15:56:50 +01006264 else if (!strcmp(args[i], "no-tlsv10"))
Willy Tarreauef934602016-12-22 23:12:01 +01006265 global_ssl.listen_default_ssloptions |= BC_SSL_O_NO_TLSV10;
Emeric Brun2c86cbf2014-10-30 15:56:50 +01006266 else if (!strcmp(args[i], "no-tlsv11"))
Willy Tarreauef934602016-12-22 23:12:01 +01006267 global_ssl.listen_default_ssloptions |= BC_SSL_O_NO_TLSV11;
Emeric Brun2c86cbf2014-10-30 15:56:50 +01006268 else if (!strcmp(args[i], "no-tlsv12"))
Willy Tarreauef934602016-12-22 23:12:01 +01006269 global_ssl.listen_default_ssloptions |= BC_SSL_O_NO_TLSV12;
Emeric Brun2c86cbf2014-10-30 15:56:50 +01006270 else if (!strcmp(args[i], "force-sslv3"))
Willy Tarreauef934602016-12-22 23:12:01 +01006271 global_ssl.listen_default_ssloptions |= BC_SSL_O_USE_SSLV3;
Emeric Brun2c86cbf2014-10-30 15:56:50 +01006272 else if (!strcmp(args[i], "force-tlsv10"))
Willy Tarreauef934602016-12-22 23:12:01 +01006273 global_ssl.listen_default_ssloptions |= BC_SSL_O_USE_TLSV10;
Emeric Brun2c86cbf2014-10-30 15:56:50 +01006274 else if (!strcmp(args[i], "force-tlsv11")) {
6275#if SSL_OP_NO_TLSv1_1
Willy Tarreauef934602016-12-22 23:12:01 +01006276 global_ssl.listen_default_ssloptions |= BC_SSL_O_USE_TLSV11;
Emeric Brun2c86cbf2014-10-30 15:56:50 +01006277#else
6278 memprintf(err, "'%s' '%s': library does not support protocol TLSv1.1", args[0], args[i]);
6279 return -1;
6280#endif
6281 }
6282 else if (!strcmp(args[i], "force-tlsv12")) {
6283#if SSL_OP_NO_TLSv1_2
Willy Tarreauef934602016-12-22 23:12:01 +01006284 global_ssl.listen_default_ssloptions |= BC_SSL_O_USE_TLSV12;
Emeric Brun2c86cbf2014-10-30 15:56:50 +01006285#else
6286 memprintf(err, "'%s' '%s': library does not support protocol TLSv1.2", args[0], args[i]);
6287 return -1;
6288#endif
6289 }
6290 else if (!strcmp(args[i], "no-tls-tickets"))
Willy Tarreauef934602016-12-22 23:12:01 +01006291 global_ssl.listen_default_ssloptions |= BC_SSL_O_NO_TLS_TICKETS;
Emeric Brun2c86cbf2014-10-30 15:56:50 +01006292 else {
6293 memprintf(err, "unknown option '%s' on global statement '%s'.", args[i], args[0]);
6294 return -1;
6295 }
6296 i++;
6297 }
6298 return 0;
6299}
6300
6301/* parse the "ssl-default-server-options" keyword in global section */
6302static int ssl_parse_default_server_options(char **args, int section_type, struct proxy *curpx,
6303 struct proxy *defpx, const char *file, int line,
6304 char **err) {
6305 int i = 1;
6306
6307 if (*(args[i]) == 0) {
6308 memprintf(err, "global statement '%s' expects an option as an argument.", args[0]);
6309 return -1;
6310 }
6311 while (*(args[i])) {
6312 if (!strcmp(args[i], "no-sslv3"))
Willy Tarreauef934602016-12-22 23:12:01 +01006313 global_ssl.connect_default_ssloptions |= SRV_SSL_O_NO_SSLV3;
Emeric Brun2c86cbf2014-10-30 15:56:50 +01006314 else if (!strcmp(args[i], "no-tlsv10"))
Willy Tarreauef934602016-12-22 23:12:01 +01006315 global_ssl.connect_default_ssloptions |= SRV_SSL_O_NO_TLSV10;
Emeric Brun2c86cbf2014-10-30 15:56:50 +01006316 else if (!strcmp(args[i], "no-tlsv11"))
Willy Tarreauef934602016-12-22 23:12:01 +01006317 global_ssl.connect_default_ssloptions |= SRV_SSL_O_NO_TLSV11;
Emeric Brun2c86cbf2014-10-30 15:56:50 +01006318 else if (!strcmp(args[i], "no-tlsv12"))
Willy Tarreauef934602016-12-22 23:12:01 +01006319 global_ssl.connect_default_ssloptions |= SRV_SSL_O_NO_TLSV12;
Emeric Brun2c86cbf2014-10-30 15:56:50 +01006320 else if (!strcmp(args[i], "force-sslv3"))
Willy Tarreauef934602016-12-22 23:12:01 +01006321 global_ssl.connect_default_ssloptions |= SRV_SSL_O_USE_SSLV3;
Emeric Brun2c86cbf2014-10-30 15:56:50 +01006322 else if (!strcmp(args[i], "force-tlsv10"))
Willy Tarreauef934602016-12-22 23:12:01 +01006323 global_ssl.connect_default_ssloptions |= SRV_SSL_O_USE_TLSV10;
Emeric Brun2c86cbf2014-10-30 15:56:50 +01006324 else if (!strcmp(args[i], "force-tlsv11")) {
6325#if SSL_OP_NO_TLSv1_1
Willy Tarreauef934602016-12-22 23:12:01 +01006326 global_ssl.connect_default_ssloptions |= SRV_SSL_O_USE_TLSV11;
Emeric Brun2c86cbf2014-10-30 15:56:50 +01006327#else
6328 memprintf(err, "'%s' '%s': library does not support protocol TLSv1.1", args[0], args[i]);
6329 return -1;
6330#endif
6331 }
6332 else if (!strcmp(args[i], "force-tlsv12")) {
6333#if SSL_OP_NO_TLSv1_2
Willy Tarreauef934602016-12-22 23:12:01 +01006334 global_ssl.connect_default_ssloptions |= SRV_SSL_O_USE_TLSV12;
Emeric Brun2c86cbf2014-10-30 15:56:50 +01006335#else
6336 memprintf(err, "'%s' '%s': library does not support protocol TLSv1.2", args[0], args[i]);
6337 return -1;
6338#endif
6339 }
6340 else if (!strcmp(args[i], "no-tls-tickets"))
Willy Tarreauef934602016-12-22 23:12:01 +01006341 global_ssl.connect_default_ssloptions |= SRV_SSL_O_NO_TLS_TICKETS;
Emeric Brun2c86cbf2014-10-30 15:56:50 +01006342 else {
6343 memprintf(err, "unknown option '%s' on global statement '%s'.", args[i], args[0]);
6344 return -1;
6345 }
6346 i++;
6347 }
6348 return 0;
6349}
6350
Willy Tarreau8c3b0fd2016-12-21 22:44:46 +01006351/* parse the "ca-base" / "crt-base" keywords in global section.
6352 * Returns <0 on alert, >0 on warning, 0 on success.
6353 */
6354static int ssl_parse_global_ca_crt_base(char **args, int section_type, struct proxy *curpx,
6355 struct proxy *defpx, const char *file, int line,
6356 char **err)
6357{
6358 char **target;
6359
Willy Tarreauef934602016-12-22 23:12:01 +01006360 target = (args[0][1] == 'a') ? &global_ssl.ca_base : &global_ssl.crt_base;
Willy Tarreau8c3b0fd2016-12-21 22:44:46 +01006361
6362 if (too_many_args(1, args, err, NULL))
6363 return -1;
6364
6365 if (*target) {
6366 memprintf(err, "'%s' already specified.", args[0]);
6367 return -1;
6368 }
6369
6370 if (*(args[1]) == 0) {
6371 memprintf(err, "global statement '%s' expects a directory path as an argument.", args[0]);
6372 return -1;
6373 }
6374 *target = strdup(args[1]);
6375 return 0;
6376}
6377
Willy Tarreauf22e9682016-12-21 23:23:19 +01006378/* parse the "ssl-default-bind-ciphers" / "ssl-default-server-ciphers" keywords
6379 * in global section. Returns <0 on alert, >0 on warning, 0 on success.
6380 */
6381static int ssl_parse_global_ciphers(char **args, int section_type, struct proxy *curpx,
6382 struct proxy *defpx, const char *file, int line,
6383 char **err)
6384{
6385 char **target;
6386
Willy Tarreauef934602016-12-22 23:12:01 +01006387 target = (args[0][12] == 'b') ? &global_ssl.listen_default_ciphers : &global_ssl.connect_default_ciphers;
Willy Tarreauf22e9682016-12-21 23:23:19 +01006388
6389 if (too_many_args(1, args, err, NULL))
6390 return -1;
6391
6392 if (*(args[1]) == 0) {
6393 memprintf(err, "global statement '%s' expects a cipher suite as an argument.", args[0]);
6394 return -1;
6395 }
6396
6397 free(*target);
6398 *target = strdup(args[1]);
6399 return 0;
6400}
6401
Willy Tarreau9ceda382016-12-21 23:13:03 +01006402/* parse various global tune.ssl settings consisting in positive integers.
6403 * Returns <0 on alert, >0 on warning, 0 on success.
6404 */
6405static int ssl_parse_global_int(char **args, int section_type, struct proxy *curpx,
6406 struct proxy *defpx, const char *file, int line,
6407 char **err)
6408{
6409 int *target;
6410
6411 if (strcmp(args[0], "tune.ssl.cachesize") == 0)
6412 target = &global.tune.sslcachesize;
6413 else if (strcmp(args[0], "tune.ssl.maxrecord") == 0)
Willy Tarreauef934602016-12-22 23:12:01 +01006414 target = (int *)&global_ssl.max_record;
Willy Tarreau9ceda382016-12-21 23:13:03 +01006415 else if (strcmp(args[0], "tune.ssl.ssl-ctx-cache-size") == 0)
Willy Tarreauef934602016-12-22 23:12:01 +01006416 target = &global_ssl.ctx_cache;
Willy Tarreau0bea58d2016-12-21 23:17:25 +01006417 else if (strcmp(args[0], "maxsslconn") == 0)
6418 target = &global.maxsslconn;
Willy Tarreau9ceda382016-12-21 23:13:03 +01006419 else {
6420 memprintf(err, "'%s' keyword not unhandled (please report this bug).", args[0]);
6421 return -1;
6422 }
6423
6424 if (too_many_args(1, args, err, NULL))
6425 return -1;
6426
6427 if (*(args[1]) == 0) {
6428 memprintf(err, "'%s' expects an integer argument.", args[0]);
6429 return -1;
6430 }
6431
6432 *target = atoi(args[1]);
6433 if (*target < 0) {
6434 memprintf(err, "'%s' expects a positive numeric value.", args[0]);
6435 return -1;
6436 }
6437 return 0;
6438}
6439
6440/* parse "ssl.force-private-cache".
6441 * Returns <0 on alert, >0 on warning, 0 on success.
6442 */
6443static int ssl_parse_global_private_cache(char **args, int section_type, struct proxy *curpx,
6444 struct proxy *defpx, const char *file, int line,
6445 char **err)
6446{
6447 if (too_many_args(0, args, err, NULL))
6448 return -1;
6449
Willy Tarreauef934602016-12-22 23:12:01 +01006450 global_ssl.private_cache = 1;
Willy Tarreau9ceda382016-12-21 23:13:03 +01006451 return 0;
6452}
6453
6454/* parse "ssl.lifetime".
6455 * Returns <0 on alert, >0 on warning, 0 on success.
6456 */
6457static int ssl_parse_global_lifetime(char **args, int section_type, struct proxy *curpx,
6458 struct proxy *defpx, const char *file, int line,
6459 char **err)
6460{
6461 const char *res;
6462
6463 if (too_many_args(1, args, err, NULL))
6464 return -1;
6465
6466 if (*(args[1]) == 0) {
6467 memprintf(err, "'%s' expects ssl sessions <lifetime> in seconds as argument.", args[0]);
6468 return -1;
6469 }
6470
Willy Tarreauef934602016-12-22 23:12:01 +01006471 res = parse_time_err(args[1], &global_ssl.life_time, TIME_UNIT_S);
Willy Tarreau9ceda382016-12-21 23:13:03 +01006472 if (res) {
6473 memprintf(err, "unexpected character '%c' in argument to <%s>.", *res, args[0]);
6474 return -1;
6475 }
6476 return 0;
6477}
6478
6479#ifndef OPENSSL_NO_DH
Willy Tarreau14e36a12016-12-21 23:28:13 +01006480/* parse "ssl-dh-param-file".
6481 * Returns <0 on alert, >0 on warning, 0 on success.
6482 */
6483static int ssl_parse_global_dh_param_file(char **args, int section_type, struct proxy *curpx,
6484 struct proxy *defpx, const char *file, int line,
6485 char **err)
6486{
6487 if (too_many_args(1, args, err, NULL))
6488 return -1;
6489
6490 if (*(args[1]) == 0) {
6491 memprintf(err, "'%s' expects a file path as an argument.", args[0]);
6492 return -1;
6493 }
6494
6495 if (ssl_sock_load_global_dh_param_from_file(args[1])) {
6496 memprintf(err, "'%s': unable to load DH parameters from file <%s>.", args[0], args[1]);
6497 return -1;
6498 }
6499 return 0;
6500}
6501
Willy Tarreau9ceda382016-12-21 23:13:03 +01006502/* parse "ssl.default-dh-param".
6503 * Returns <0 on alert, >0 on warning, 0 on success.
6504 */
6505static int ssl_parse_global_default_dh(char **args, int section_type, struct proxy *curpx,
6506 struct proxy *defpx, const char *file, int line,
6507 char **err)
6508{
6509 if (too_many_args(1, args, err, NULL))
6510 return -1;
6511
6512 if (*(args[1]) == 0) {
6513 memprintf(err, "'%s' expects an integer argument.", args[0]);
6514 return -1;
6515 }
6516
Willy Tarreauef934602016-12-22 23:12:01 +01006517 global_ssl.default_dh_param = atoi(args[1]);
6518 if (global_ssl.default_dh_param < 1024) {
Willy Tarreau9ceda382016-12-21 23:13:03 +01006519 memprintf(err, "'%s' expects a value >= 1024.", args[0]);
6520 return -1;
6521 }
6522 return 0;
6523}
6524#endif
6525
6526
William Lallemand32af2032016-10-29 18:09:35 +02006527/* This function is used with TLS ticket keys management. It permits to browse
6528 * each reference. The variable <getnext> must contain the current node,
6529 * <end> point to the root node.
6530 */
6531#if (defined SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB && TLS_TICKETS_NO > 0)
6532static inline
6533struct tls_keys_ref *tlskeys_list_get_next(struct tls_keys_ref *getnext, struct list *end)
6534{
6535 struct tls_keys_ref *ref = getnext;
6536
6537 while (1) {
6538
6539 /* Get next list entry. */
6540 ref = LIST_NEXT(&ref->list, struct tls_keys_ref *, list);
6541
6542 /* If the entry is the last of the list, return NULL. */
6543 if (&ref->list == end)
6544 return NULL;
6545
6546 return ref;
6547 }
6548}
6549
6550static inline
6551struct tls_keys_ref *tlskeys_ref_lookup_ref(const char *reference)
6552{
6553 int id;
6554 char *error;
6555
6556 /* If the reference starts by a '#', this is numeric id. */
6557 if (reference[0] == '#') {
6558 /* Try to convert the numeric id. If the conversion fails, the lookup fails. */
6559 id = strtol(reference + 1, &error, 10);
6560 if (*error != '\0')
6561 return NULL;
6562
6563 /* Perform the unique id lookup. */
6564 return tlskeys_ref_lookupid(id);
6565 }
6566
6567 /* Perform the string lookup. */
6568 return tlskeys_ref_lookup(reference);
6569}
6570#endif
6571
6572
6573#if (defined SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB && TLS_TICKETS_NO > 0)
6574
6575static int cli_io_handler_tlskeys_files(struct appctx *appctx);
6576
6577static inline int cli_io_handler_tlskeys_entries(struct appctx *appctx) {
6578 return cli_io_handler_tlskeys_files(appctx);
6579}
6580
Willy Tarreauf5f26e82016-12-16 18:47:27 +01006581/* dumps all tls keys. Relies on cli.i0 (non-null = only list file names), cli.i1
6582 * (next index to be dumped), and cli.p0 (next key reference).
6583 */
William Lallemand32af2032016-10-29 18:09:35 +02006584static int cli_io_handler_tlskeys_files(struct appctx *appctx) {
6585
6586 struct stream_interface *si = appctx->owner;
6587
6588 switch (appctx->st2) {
6589 case STAT_ST_INIT:
6590 /* Display the column headers. If the message cannot be sent,
6591 * quit the fucntion with returning 0. The function is called
6592 * later and restart at the state "STAT_ST_INIT".
6593 */
6594 chunk_reset(&trash);
6595
6596 if (appctx->io_handler == cli_io_handler_tlskeys_entries)
6597 chunk_appendf(&trash, "# id secret\n");
6598 else
6599 chunk_appendf(&trash, "# id (file)\n");
6600
6601 if (bi_putchk(si_ic(si), &trash) == -1) {
6602 si_applet_cant_put(si);
6603 return 0;
6604 }
6605
William Lallemand32af2032016-10-29 18:09:35 +02006606 /* Now, we start the browsing of the references lists.
6607 * Note that the following call to LIST_ELEM return bad pointer. The only
6608 * available field of this pointer is <list>. It is used with the function
6609 * tlskeys_list_get_next() for retruning the first available entry
6610 */
Willy Tarreauf5f26e82016-12-16 18:47:27 +01006611 if (appctx->ctx.cli.p0 == NULL) {
6612 appctx->ctx.cli.p0 = LIST_ELEM(&tlskeys_reference, struct tls_keys_ref *, list);
6613 appctx->ctx.cli.p0 = tlskeys_list_get_next(appctx->ctx.cli.p0, &tlskeys_reference);
William Lallemand32af2032016-10-29 18:09:35 +02006614 }
6615
6616 appctx->st2 = STAT_ST_LIST;
6617 /* fall through */
6618
6619 case STAT_ST_LIST:
Willy Tarreauf5f26e82016-12-16 18:47:27 +01006620 while (appctx->ctx.cli.p0) {
6621 struct tls_keys_ref *ref = appctx->ctx.cli.p0;
6622 int head = ref->tls_ticket_enc_index;
William Lallemand32af2032016-10-29 18:09:35 +02006623
6624 chunk_reset(&trash);
Willy Tarreauf5f26e82016-12-16 18:47:27 +01006625 if (appctx->io_handler == cli_io_handler_tlskeys_entries && appctx->ctx.cli.i1 == 0)
William Lallemand32af2032016-10-29 18:09:35 +02006626 chunk_appendf(&trash, "# ");
Willy Tarreauf5f26e82016-12-16 18:47:27 +01006627
6628 if (appctx->ctx.cli.i1 == 0)
6629 chunk_appendf(&trash, "%d (%s)\n", ref->unique_id, ref->filename);
6630
William Lallemand32af2032016-10-29 18:09:35 +02006631 if (appctx->io_handler == cli_io_handler_tlskeys_entries) {
Willy Tarreauf5f26e82016-12-16 18:47:27 +01006632 while (appctx->ctx.cli.i1 < TLS_TICKETS_NO) {
William Lallemand32af2032016-10-29 18:09:35 +02006633 struct chunk *t2 = get_trash_chunk();
6634
6635 chunk_reset(t2);
6636 /* should never fail here because we dump only a key in the t2 buffer */
Willy Tarreauf5f26e82016-12-16 18:47:27 +01006637 t2->len = a2base64((char *)(ref->tlskeys + (head + 2 + appctx->ctx.cli.i1) % TLS_TICKETS_NO),
William Lallemand32af2032016-10-29 18:09:35 +02006638 sizeof(struct tls_sess_key), t2->str, t2->size);
Willy Tarreauf5f26e82016-12-16 18:47:27 +01006639 chunk_appendf(&trash, "%d.%d %s\n", ref->unique_id, appctx->ctx.cli.i1, t2->str);
William Lallemand32af2032016-10-29 18:09:35 +02006640
6641 if (bi_putchk(si_ic(si), &trash) == -1) {
6642 /* let's try again later from this stream. We add ourselves into
6643 * this stream's users so that it can remove us upon termination.
6644 */
6645 si_applet_cant_put(si);
6646 return 0;
6647 }
Willy Tarreauf5f26e82016-12-16 18:47:27 +01006648 appctx->ctx.cli.i1++;
William Lallemand32af2032016-10-29 18:09:35 +02006649 }
Willy Tarreauf5f26e82016-12-16 18:47:27 +01006650 appctx->ctx.cli.i1 = 0;
William Lallemand32af2032016-10-29 18:09:35 +02006651 }
6652 if (bi_putchk(si_ic(si), &trash) == -1) {
6653 /* let's try again later from this stream. We add ourselves into
6654 * this stream's users so that it can remove us upon termination.
6655 */
6656 si_applet_cant_put(si);
6657 return 0;
6658 }
6659
Willy Tarreauf5f26e82016-12-16 18:47:27 +01006660 if (appctx->ctx.cli.i0 == 0) /* don't display everything if not necessary */
William Lallemand32af2032016-10-29 18:09:35 +02006661 break;
6662
6663 /* get next list entry and check the end of the list */
Willy Tarreauf5f26e82016-12-16 18:47:27 +01006664 appctx->ctx.cli.p0 = tlskeys_list_get_next(appctx->ctx.cli.p0, &tlskeys_reference);
William Lallemand32af2032016-10-29 18:09:35 +02006665 }
6666
6667 appctx->st2 = STAT_ST_FIN;
6668 /* fall through */
6669
6670 default:
6671 appctx->st2 = STAT_ST_FIN;
6672 return 1;
6673 }
6674 return 0;
6675}
6676
Willy Tarreauf5f26e82016-12-16 18:47:27 +01006677/* sets cli.i0 to non-zero if only file lists should be dumped */
William Lallemand32af2032016-10-29 18:09:35 +02006678static int cli_parse_show_tlskeys(char **args, struct appctx *appctx, void *private)
6679{
William Lallemand32af2032016-10-29 18:09:35 +02006680 /* no parameter, shows only file list */
6681 if (!*args[2]) {
Willy Tarreauf5f26e82016-12-16 18:47:27 +01006682 appctx->ctx.cli.i0 = 1;
William Lallemand32af2032016-10-29 18:09:35 +02006683 appctx->io_handler = cli_io_handler_tlskeys_files;
Willy Tarreau3067bfa2016-12-05 14:50:15 +01006684 return 0;
William Lallemand32af2032016-10-29 18:09:35 +02006685 }
6686
6687 if (args[2][0] == '*') {
6688 /* list every TLS ticket keys */
Willy Tarreauf5f26e82016-12-16 18:47:27 +01006689 appctx->ctx.cli.i0 = 1;
William Lallemand32af2032016-10-29 18:09:35 +02006690 } else {
Willy Tarreauf5f26e82016-12-16 18:47:27 +01006691 appctx->ctx.cli.p0 = tlskeys_ref_lookup_ref(args[2]);
6692 if (!appctx->ctx.cli.p0) {
William Lallemand32af2032016-10-29 18:09:35 +02006693 appctx->ctx.cli.msg = "'show tls-keys' unable to locate referenced filename\n";
Willy Tarreau3b6e5472016-11-24 15:53:53 +01006694 appctx->st0 = CLI_ST_PRINT;
William Lallemand32af2032016-10-29 18:09:35 +02006695 return 1;
6696 }
6697 }
William Lallemand32af2032016-10-29 18:09:35 +02006698 appctx->io_handler = cli_io_handler_tlskeys_entries;
Willy Tarreau3067bfa2016-12-05 14:50:15 +01006699 return 0;
William Lallemand32af2032016-10-29 18:09:35 +02006700}
6701
William Lallemand32af2032016-10-29 18:09:35 +02006702static int cli_parse_set_tlskeys(char **args, struct appctx *appctx, void *private)
6703{
Willy Tarreauf5f26e82016-12-16 18:47:27 +01006704 struct tls_keys_ref *ref;
6705
William Lallemand32af2032016-10-29 18:09:35 +02006706 /* Expect two parameters: the filename and the new new TLS key in encoding */
6707 if (!*args[3] || !*args[4]) {
6708 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 +01006709 appctx->st0 = CLI_ST_PRINT;
William Lallemand32af2032016-10-29 18:09:35 +02006710 return 1;
6711 }
6712
Willy Tarreauf5f26e82016-12-16 18:47:27 +01006713 ref = tlskeys_ref_lookup_ref(args[3]);
6714 if (!ref) {
William Lallemand32af2032016-10-29 18:09:35 +02006715 appctx->ctx.cli.msg = "'set ssl tls-key' unable to locate referenced filename\n";
Willy Tarreau3b6e5472016-11-24 15:53:53 +01006716 appctx->st0 = CLI_ST_PRINT;
William Lallemand32af2032016-10-29 18:09:35 +02006717 return 1;
6718 }
6719
6720 trash.len = base64dec(args[4], strlen(args[4]), trash.str, trash.size);
6721 if (trash.len != sizeof(struct tls_sess_key)) {
6722 appctx->ctx.cli.msg = "'set ssl tls-key' received invalid base64 encoded TLS key.\n";
Willy Tarreau3b6e5472016-11-24 15:53:53 +01006723 appctx->st0 = CLI_ST_PRINT;
William Lallemand32af2032016-10-29 18:09:35 +02006724 return 1;
6725 }
6726
Willy Tarreauf5f26e82016-12-16 18:47:27 +01006727 memcpy(ref->tlskeys + ((ref->tls_ticket_enc_index + 2) % TLS_TICKETS_NO), trash.str, trash.len);
6728 ref->tls_ticket_enc_index = (ref->tls_ticket_enc_index + 1) % TLS_TICKETS_NO;
William Lallemand32af2032016-10-29 18:09:35 +02006729
6730 appctx->ctx.cli.msg = "TLS ticket key updated!";
Willy Tarreau3b6e5472016-11-24 15:53:53 +01006731 appctx->st0 = CLI_ST_PRINT;
William Lallemand32af2032016-10-29 18:09:35 +02006732 return 1;
6733
6734}
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +01006735#endif
William Lallemand32af2032016-10-29 18:09:35 +02006736
6737static int cli_parse_set_ocspresponse(char **args, struct appctx *appctx, void *private)
6738{
6739#if (defined SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB && !defined OPENSSL_NO_OCSP)
6740 char *err = NULL;
6741
6742 /* Expect one parameter: the new response in base64 encoding */
6743 if (!*args[3]) {
6744 appctx->ctx.cli.msg = "'set ssl ocsp-response' expects response in base64 encoding.\n";
Willy Tarreau3b6e5472016-11-24 15:53:53 +01006745 appctx->st0 = CLI_ST_PRINT;
William Lallemand32af2032016-10-29 18:09:35 +02006746 return 1;
6747 }
6748
6749 trash.len = base64dec(args[3], strlen(args[3]), trash.str, trash.size);
6750 if (trash.len < 0) {
6751 appctx->ctx.cli.msg = "'set ssl ocsp-response' received invalid base64 encoded response.\n";
Willy Tarreau3b6e5472016-11-24 15:53:53 +01006752 appctx->st0 = CLI_ST_PRINT;
William Lallemand32af2032016-10-29 18:09:35 +02006753 return 1;
6754 }
6755
6756 if (ssl_sock_update_ocsp_response(&trash, &err)) {
6757 if (err) {
6758 memprintf(&err, "%s.\n", err);
6759 appctx->ctx.cli.err = err;
Willy Tarreau3b6e5472016-11-24 15:53:53 +01006760 appctx->st0 = CLI_ST_PRINT_FREE;
William Lallemand32af2032016-10-29 18:09:35 +02006761 }
6762 return 1;
6763 }
6764 appctx->ctx.cli.msg = "OCSP Response updated!";
Willy Tarreau3b6e5472016-11-24 15:53:53 +01006765 appctx->st0 = CLI_ST_PRINT;
William Lallemand32af2032016-10-29 18:09:35 +02006766 return 1;
6767#else
6768 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 +01006769 appctx->st0 = CLI_ST_PRINT;
William Lallemand32af2032016-10-29 18:09:35 +02006770 return 1;
6771#endif
6772
6773}
6774
6775/* register cli keywords */
6776static struct cli_kw_list cli_kws = {{ },{
6777#if (defined SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB && TLS_TICKETS_NO > 0)
6778 { { "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 },
6779 { { "set", "ssl", "tls-keys", NULL }, NULL, cli_parse_set_tlskeys, NULL },
William Lallemand32af2032016-10-29 18:09:35 +02006780#endif
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +01006781 { { "set", "ssl", "ocsp-response", NULL }, NULL, cli_parse_set_ocspresponse, NULL },
William Lallemand32af2032016-10-29 18:09:35 +02006782 { { NULL }, NULL, NULL, NULL }
6783}};
6784
6785
Willy Tarreau7875d092012-09-10 08:20:03 +02006786/* Note: must not be declared <const> as its list will be overwritten.
6787 * Please take care of keeping this list alphabetically sorted.
6788 */
Willy Tarreaudc13c112013-06-21 23:16:39 +02006789static struct sample_fetch_kw_list sample_fetch_keywords = {ILH, {
Emeric Brun645ae792014-04-30 14:21:06 +02006790 { "ssl_bc", smp_fetch_ssl_fc, 0, NULL, SMP_T_BOOL, SMP_USE_L5SRV },
Thierry FOURNIER07ee64e2015-07-06 23:43:03 +02006791 { "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 +02006792 { "ssl_bc_cipher", smp_fetch_ssl_fc_cipher, 0, NULL, SMP_T_STR, SMP_USE_L5SRV },
6793 { "ssl_bc_protocol", smp_fetch_ssl_fc_protocol, 0, NULL, SMP_T_STR, SMP_USE_L5SRV },
Emeric Brunb73a9b02014-04-30 18:49:19 +02006794 { "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 +02006795 { "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 +02006796 { "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 +02006797 { "ssl_c_ca_err", smp_fetch_ssl_c_ca_err, 0, NULL, SMP_T_SINT, SMP_USE_L5CLI },
6798 { "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 +01006799 { "ssl_c_der", smp_fetch_ssl_x_der, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Thierry FOURNIER07ee64e2015-07-06 23:43:03 +02006800 { "ssl_c_err", smp_fetch_ssl_c_err, 0, NULL, SMP_T_SINT, SMP_USE_L5CLI },
Emeric Brunba841a12014-04-30 17:05:08 +02006801 { "ssl_c_i_dn", smp_fetch_ssl_x_i_dn, ARG2(0,STR,SINT), NULL, SMP_T_STR, SMP_USE_L5CLI },
6802 { "ssl_c_key_alg", smp_fetch_ssl_x_key_alg, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
6803 { "ssl_c_notafter", smp_fetch_ssl_x_notafter, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
6804 { "ssl_c_notbefore", smp_fetch_ssl_x_notbefore, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
6805 { "ssl_c_sig_alg", smp_fetch_ssl_x_sig_alg, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
6806 { "ssl_c_s_dn", smp_fetch_ssl_x_s_dn, ARG2(0,STR,SINT), NULL, SMP_T_STR, SMP_USE_L5CLI },
6807 { "ssl_c_serial", smp_fetch_ssl_x_serial, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
6808 { "ssl_c_sha1", smp_fetch_ssl_x_sha1, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Willy Tarreau80aca902013-01-07 15:42:20 +01006809 { "ssl_c_used", smp_fetch_ssl_c_used, 0, NULL, SMP_T_BOOL, SMP_USE_L5CLI },
Thierry FOURNIER07ee64e2015-07-06 23:43:03 +02006810 { "ssl_c_verify", smp_fetch_ssl_c_verify, 0, NULL, SMP_T_SINT, SMP_USE_L5CLI },
6811 { "ssl_c_version", smp_fetch_ssl_x_version, 0, NULL, SMP_T_SINT, SMP_USE_L5CLI },
Emeric Brun43e79582014-10-29 19:03:26 +01006812 { "ssl_f_der", smp_fetch_ssl_x_der, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Emeric Brunba841a12014-04-30 17:05:08 +02006813 { "ssl_f_i_dn", smp_fetch_ssl_x_i_dn, ARG2(0,STR,SINT), NULL, SMP_T_STR, SMP_USE_L5CLI },
6814 { "ssl_f_key_alg", smp_fetch_ssl_x_key_alg, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
6815 { "ssl_f_notafter", smp_fetch_ssl_x_notafter, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
6816 { "ssl_f_notbefore", smp_fetch_ssl_x_notbefore, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
6817 { "ssl_f_sig_alg", smp_fetch_ssl_x_sig_alg, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
6818 { "ssl_f_s_dn", smp_fetch_ssl_x_s_dn, ARG2(0,STR,SINT), NULL, SMP_T_STR, SMP_USE_L5CLI },
6819 { "ssl_f_serial", smp_fetch_ssl_x_serial, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Emeric Brun55f4fa82014-04-30 17:11:25 +02006820 { "ssl_f_sha1", smp_fetch_ssl_x_sha1, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Thierry FOURNIER07ee64e2015-07-06 23:43:03 +02006821 { "ssl_f_version", smp_fetch_ssl_x_version, 0, NULL, SMP_T_SINT, SMP_USE_L5CLI },
Willy Tarreau80aca902013-01-07 15:42:20 +01006822 { "ssl_fc", smp_fetch_ssl_fc, 0, NULL, SMP_T_BOOL, SMP_USE_L5CLI },
Thierry FOURNIER07ee64e2015-07-06 23:43:03 +02006823 { "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 +01006824 { "ssl_fc_cipher", smp_fetch_ssl_fc_cipher, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Willy Tarreau80aca902013-01-07 15:42:20 +01006825 { "ssl_fc_has_crt", smp_fetch_ssl_fc_has_crt, 0, NULL, SMP_T_BOOL, SMP_USE_L5CLI },
6826 { "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 +02006827 { "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 +02006828#ifdef OPENSSL_NPN_NEGOTIATED
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01006829 { "ssl_fc_npn", smp_fetch_ssl_fc_npn, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Willy Tarreaua33c6542012-10-15 13:19:06 +02006830#endif
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01006831#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01006832 { "ssl_fc_alpn", smp_fetch_ssl_fc_alpn, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Willy Tarreauab861d32013-04-02 02:30:41 +02006833#endif
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01006834 { "ssl_fc_protocol", smp_fetch_ssl_fc_protocol, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Emeric Brunb73a9b02014-04-30 18:49:19 +02006835 { "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 +02006836 { "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 +01006837 { "ssl_fc_session_id", smp_fetch_ssl_fc_session_id, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
6838 { "ssl_fc_sni", smp_fetch_ssl_fc_sni, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Willy Tarreau7875d092012-09-10 08:20:03 +02006839 { NULL, NULL, 0, 0, 0 },
6840}};
6841
6842/* Note: must not be declared <const> as its list will be overwritten.
6843 * Please take care of keeping this list alphabetically sorted.
6844 */
Willy Tarreaudc13c112013-06-21 23:16:39 +02006845static struct acl_kw_list acl_kws = {ILH, {
Thierry FOURNIERc5a4e982014-03-05 16:07:08 +01006846 { "ssl_fc_sni_end", "ssl_fc_sni", PAT_MATCH_END },
6847 { "ssl_fc_sni_reg", "ssl_fc_sni", PAT_MATCH_REG },
Willy Tarreau8ed669b2013-01-11 15:49:37 +01006848 { /* END */ },
Willy Tarreau7875d092012-09-10 08:20:03 +02006849}};
6850
Willy Tarreau79eeafa2012-09-14 07:53:05 +02006851/* Note: must not be declared <const> as its list will be overwritten.
6852 * Please take care of keeping this list alphabetically sorted, doing so helps
6853 * all code contributors.
6854 * Optional keywords are also declared with a NULL ->parse() function so that
6855 * the config parser can report an appropriate error when a known keyword was
6856 * not enabled.
6857 */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01006858static struct ssl_bind_kw ssl_bind_kws[] = {
6859 { "alpn", ssl_bind_parse_alpn, 1 }, /* set ALPN supported protocols */
6860 { "ca-file", ssl_bind_parse_ca_file, 1 }, /* set CAfile to process verify on client cert */
6861 { "ciphers", ssl_bind_parse_ciphers, 1 }, /* set SSL cipher suite */
6862 { "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 +01006863 { "curves", ssl_bind_parse_curves, 1 }, /* set SSL curve suite */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01006864 { "ecdhe", ssl_bind_parse_ecdhe, 1 }, /* defines named curve for elliptic curve Diffie-Hellman */
6865 { "force-sslv3", ssl_bind_parse_force_sslv3, 0 }, /* force SSLv3 */
6866 { "force-tlsv10", ssl_bind_parse_force_tlsv10, 0 }, /* force TLSv10 */
6867 { "force-tlsv11", ssl_bind_parse_force_tlsv11, 0 }, /* force TLSv11 */
6868 { "force-tlsv12", ssl_bind_parse_force_tlsv12, 0 }, /* force TLSv12 */
6869 { "no-sslv3", ssl_bind_parse_no_sslv3, 0 }, /* disable SSLv3 */
6870 { "no-tlsv10", ssl_bind_parse_no_tlsv10, 0 }, /* disable TLSv10 */
6871 { "no-tlsv11", ssl_bind_parse_no_tlsv11, 0 }, /* disable TLSv11 */
6872 { "no-tlsv12", ssl_bind_parse_no_tlsv12, 0 }, /* disable TLSv12 */
6873 { "no-tls-tickets", ssl_bind_parse_no_tls_tickets, 0 }, /* disable session resumption tickets */
6874 { "npn", ssl_bind_parse_npn, 1 }, /* set NPN supported protocols */
6875 { "verify", ssl_bind_parse_verify, 1 }, /* set SSL verify method */
6876 { NULL, NULL, 0 },
6877};
6878
Willy Tarreau51fb7652012-09-18 18:24:39 +02006879static struct bind_kw_list bind_kws = { "SSL", { }, {
Nenad Merdanovic05552d42015-02-27 19:56:49 +01006880 { "alpn", bind_parse_alpn, 1 }, /* set ALPN supported protocols */
6881 { "ca-file", bind_parse_ca_file, 1 }, /* set CAfile to process verify on client cert */
6882 { "ca-ignore-err", bind_parse_ignore_err, 1 }, /* set error IDs to ignore on verify depth > 0 */
Christopher Faulet31af49d2015-06-09 17:29:50 +02006883 { "ca-sign-file", bind_parse_ca_sign_file, 1 }, /* set CAFile used to generate and sign server certs */
6884 { "ca-sign-pass", bind_parse_ca_sign_pass, 1 }, /* set CAKey passphrase */
Nenad Merdanovic05552d42015-02-27 19:56:49 +01006885 { "ciphers", bind_parse_ciphers, 1 }, /* set SSL cipher suite */
6886 { "crl-file", bind_parse_crl_file, 1 }, /* set certificat revocation list file use on client cert verify */
6887 { "crt", bind_parse_crt, 1 }, /* load SSL certificates from this location */
6888 { "crt-ignore-err", bind_parse_ignore_err, 1 }, /* set error IDs to ingore on verify depth == 0 */
6889 { "crt-list", bind_parse_crt_list, 1 }, /* load a list of crt from this location */
Emmanuel Hocdete7f2b732017-01-09 16:15:54 +01006890 { "curves", bind_parse_curves, 1 }, /* set SSL curve suite */
Nenad Merdanovic05552d42015-02-27 19:56:49 +01006891 { "ecdhe", bind_parse_ecdhe, 1 }, /* defines named curve for elliptic curve Diffie-Hellman */
6892 { "force-sslv3", bind_parse_force_sslv3, 0 }, /* force SSLv3 */
6893 { "force-tlsv10", bind_parse_force_tlsv10, 0 }, /* force TLSv10 */
6894 { "force-tlsv11", bind_parse_force_tlsv11, 0 }, /* force TLSv11 */
6895 { "force-tlsv12", bind_parse_force_tlsv12, 0 }, /* force TLSv12 */
Christopher Faulet31af49d2015-06-09 17:29:50 +02006896 { "generate-certificates", bind_parse_generate_certs, 0 }, /* enable the server certificates generation */
Nenad Merdanovic05552d42015-02-27 19:56:49 +01006897 { "no-sslv3", bind_parse_no_sslv3, 0 }, /* disable SSLv3 */
6898 { "no-tlsv10", bind_parse_no_tlsv10, 0 }, /* disable TLSv10 */
6899 { "no-tlsv11", bind_parse_no_tlsv11, 0 }, /* disable TLSv11 */
6900 { "no-tlsv12", bind_parse_no_tlsv12, 0 }, /* disable TLSv12 */
6901 { "no-tls-tickets", bind_parse_no_tls_tickets, 0 }, /* disable session resumption tickets */
6902 { "ssl", bind_parse_ssl, 0 }, /* enable SSL processing */
6903 { "strict-sni", bind_parse_strict_sni, 0 }, /* refuse negotiation if sni doesn't match a certificate */
6904 { "tls-ticket-keys", bind_parse_tls_ticket_keys, 1 }, /* set file to load TLS ticket keys from */
6905 { "verify", bind_parse_verify, 1 }, /* set SSL verify method */
6906 { "npn", bind_parse_npn, 1 }, /* set NPN supported protocols */
Willy Tarreau79eeafa2012-09-14 07:53:05 +02006907 { NULL, NULL, 0 },
6908}};
Emeric Brun46591952012-05-18 15:47:34 +02006909
Willy Tarreau92faadf2012-10-10 23:04:25 +02006910/* Note: must not be declared <const> as its list will be overwritten.
6911 * Please take care of keeping this list alphabetically sorted, doing so helps
6912 * all code contributors.
6913 * Optional keywords are also declared with a NULL ->parse() function so that
6914 * the config parser can report an appropriate error when a known keyword was
6915 * not enabled.
6916 */
6917static struct srv_kw_list srv_kws = { "SSL", { }, {
Emeric Brunef42d922012-10-11 16:11:36 +02006918 { "ca-file", srv_parse_ca_file, 1, 0 }, /* set CAfile to process verify server cert */
Emeric Brunecc91fe2012-10-11 15:05:10 +02006919 { "check-ssl", srv_parse_check_ssl, 0, 0 }, /* enable SSL for health checks */
6920 { "ciphers", srv_parse_ciphers, 1, 0 }, /* select the cipher suite */
Emeric Brunef42d922012-10-11 16:11:36 +02006921 { "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 +02006922 { "crt", srv_parse_crt, 1, 0 }, /* set client certificate */
Emeric Brunecc91fe2012-10-11 15:05:10 +02006923 { "force-sslv3", srv_parse_force_sslv3, 0, 0 }, /* force SSLv3 */
6924 { "force-tlsv10", srv_parse_force_tlsv10, 0, 0 }, /* force TLSv10 */
6925 { "force-tlsv11", srv_parse_force_tlsv11, 0, 0 }, /* force TLSv11 */
6926 { "force-tlsv12", srv_parse_force_tlsv12, 0, 0 }, /* force TLSv12 */
Willy Tarreau2a3fb1c2015-02-05 16:47:07 +01006927 { "no-ssl-reuse", srv_parse_no_ssl_reuse, 0, 0 }, /* disable session reuse */
Emeric Brunecc91fe2012-10-11 15:05:10 +02006928 { "no-sslv3", srv_parse_no_sslv3, 0, 0 }, /* disable SSLv3 */
6929 { "no-tlsv10", srv_parse_no_tlsv10, 0, 0 }, /* disable TLSv10 */
6930 { "no-tlsv11", srv_parse_no_tlsv11, 0, 0 }, /* disable TLSv11 */
6931 { "no-tlsv12", srv_parse_no_tlsv12, 0, 0 }, /* disable TLSv12 */
Emeric Brunf9c5c472012-10-11 15:28:34 +02006932 { "no-tls-tickets", srv_parse_no_tls_tickets, 0, 0 }, /* disable session resumption tickets */
David Safb76832014-05-08 23:42:08 -04006933 { "send-proxy-v2-ssl", srv_parse_send_proxy_ssl, 0, 0 }, /* send PROXY protocol header v2 with SSL info */
6934 { "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 +02006935 { "sni", srv_parse_sni, 1, 0 }, /* send SNI extension */
Emeric Brunecc91fe2012-10-11 15:05:10 +02006936 { "ssl", srv_parse_ssl, 0, 0 }, /* enable SSL processing */
Emeric Brunef42d922012-10-11 16:11:36 +02006937 { "verify", srv_parse_verify, 1, 0 }, /* set SSL verify method */
Evan Broderbe554312013-06-27 00:05:25 -07006938 { "verifyhost", srv_parse_verifyhost, 1, 0 }, /* require that SSL cert verifies for hostname */
Willy Tarreau92faadf2012-10-10 23:04:25 +02006939 { NULL, NULL, 0, 0 },
6940}};
6941
Emeric Brun2c86cbf2014-10-30 15:56:50 +01006942static struct cfg_kw_list cfg_kws = {ILH, {
Willy Tarreau8c3b0fd2016-12-21 22:44:46 +01006943 { CFG_GLOBAL, "ca-base", ssl_parse_global_ca_crt_base },
6944 { CFG_GLOBAL, "crt-base", ssl_parse_global_ca_crt_base },
Willy Tarreau0bea58d2016-12-21 23:17:25 +01006945 { CFG_GLOBAL, "maxsslconn", ssl_parse_global_int },
Emeric Brun2c86cbf2014-10-30 15:56:50 +01006946 { CFG_GLOBAL, "ssl-default-bind-options", ssl_parse_default_bind_options },
6947 { CFG_GLOBAL, "ssl-default-server-options", ssl_parse_default_server_options },
Willy Tarreau14e36a12016-12-21 23:28:13 +01006948#ifndef OPENSSL_NO_DH
6949 { CFG_GLOBAL, "ssl-dh-param-file", ssl_parse_global_dh_param_file },
6950#endif
Willy Tarreau9ceda382016-12-21 23:13:03 +01006951 { CFG_GLOBAL, "tune.ssl.cachesize", ssl_parse_global_int },
6952#ifndef OPENSSL_NO_DH
6953 { CFG_GLOBAL, "tune.ssl.default-dh-param", ssl_parse_global_default_dh },
6954#endif
6955 { CFG_GLOBAL, "tune.ssl.force-private-cache", ssl_parse_global_private_cache },
6956 { CFG_GLOBAL, "tune.ssl.lifetime", ssl_parse_global_lifetime },
6957 { CFG_GLOBAL, "tune.ssl.maxrecord", ssl_parse_global_int },
6958 { CFG_GLOBAL, "tune.ssl.ssl-ctx-cache-size", ssl_parse_global_int },
Willy Tarreauf22e9682016-12-21 23:23:19 +01006959 { CFG_GLOBAL, "ssl-default-bind-ciphers", ssl_parse_global_ciphers },
6960 { CFG_GLOBAL, "ssl-default-server-ciphers", ssl_parse_global_ciphers },
Emeric Brun2c86cbf2014-10-30 15:56:50 +01006961 { 0, NULL, NULL },
6962}};
6963
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02006964/* transport-layer operations for SSL sockets */
Willy Tarreaud9f5cca2016-12-22 21:08:52 +01006965static struct xprt_ops ssl_sock = {
Emeric Brun46591952012-05-18 15:47:34 +02006966 .snd_buf = ssl_sock_from_buf,
6967 .rcv_buf = ssl_sock_to_buf,
6968 .rcv_pipe = NULL,
6969 .snd_pipe = NULL,
6970 .shutr = NULL,
6971 .shutw = ssl_sock_shutw,
6972 .close = ssl_sock_close,
6973 .init = ssl_sock_init,
Willy Tarreau55d37912016-12-21 23:38:39 +01006974 .prepare_bind_conf = ssl_sock_prepare_bind_conf,
Willy Tarreau795cdab2016-12-22 17:30:54 +01006975 .destroy_bind_conf = ssl_sock_destroy_bind_conf,
Willy Tarreau17d45382016-12-22 21:16:08 +01006976 .prepare_srv = ssl_sock_prepare_srv_ctx,
6977 .destroy_srv = ssl_sock_free_srv_ctx,
Willy Tarreau8e0bb0a2016-11-24 16:58:12 +01006978 .name = "SSL",
Emeric Brun46591952012-05-18 15:47:34 +02006979};
6980
Daniel Jakots54ffb912015-11-06 20:02:41 +01006981#if (OPENSSL_VERSION_NUMBER >= 0x1000200fL && !defined OPENSSL_NO_TLSEXT && !defined OPENSSL_IS_BORINGSSL && !defined LIBRESSL_VERSION_NUMBER)
Janusz Dziemidowicz2c701b52015-03-07 23:03:59 +01006982
6983static void ssl_sock_sctl_free_func(void *parent, void *ptr, CRYPTO_EX_DATA *ad, int idx, long argl, void *argp)
6984{
6985 if (ptr) {
6986 chunk_destroy(ptr);
6987 free(ptr);
6988 }
6989}
6990
6991#endif
6992
Emeric Brun46591952012-05-18 15:47:34 +02006993__attribute__((constructor))
Willy Tarreau92faadf2012-10-10 23:04:25 +02006994static void __ssl_sock_init(void)
6995{
Willy Tarreauc2c0b612016-12-21 19:23:20 +01006996 char *ptr;
6997
Emeric Brun46591952012-05-18 15:47:34 +02006998 STACK_OF(SSL_COMP)* cm;
6999
Willy Tarreauef934602016-12-22 23:12:01 +01007000 if (global_ssl.listen_default_ciphers)
7001 global_ssl.listen_default_ciphers = strdup(global_ssl.listen_default_ciphers);
7002 if (global_ssl.connect_default_ciphers)
7003 global_ssl.connect_default_ciphers = strdup(global_ssl.connect_default_ciphers);
Willy Tarreau610f04b2014-02-13 11:36:41 +01007004
Willy Tarreau13e14102016-12-22 20:25:26 +01007005 xprt_register(XPRT_SSL, &ssl_sock);
Emeric Brun46591952012-05-18 15:47:34 +02007006 SSL_library_init();
7007 cm = SSL_COMP_get_compression_methods();
7008 sk_SSL_COMP_zero(cm);
Daniel Jakots54ffb912015-11-06 20:02:41 +01007009#if (OPENSSL_VERSION_NUMBER >= 0x1000200fL && !defined OPENSSL_NO_TLSEXT && !defined OPENSSL_IS_BORINGSSL && !defined LIBRESSL_VERSION_NUMBER)
Janusz Dziemidowicz2c701b52015-03-07 23:03:59 +01007010 sctl_ex_index = SSL_CTX_get_ex_new_index(0, NULL, NULL, NULL, ssl_sock_sctl_free_func);
7011#endif
Willy Tarreau7875d092012-09-10 08:20:03 +02007012 sample_register_fetches(&sample_fetch_keywords);
7013 acl_register_keywords(&acl_kws);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02007014 bind_register_keywords(&bind_kws);
Willy Tarreau92faadf2012-10-10 23:04:25 +02007015 srv_register_keywords(&srv_kws);
Emeric Brun2c86cbf2014-10-30 15:56:50 +01007016 cfg_register_keywords(&cfg_kws);
William Lallemand32af2032016-10-29 18:09:35 +02007017 cli_register_kw(&cli_kws);
Willy Tarreaud1c57502016-12-22 22:46:15 +01007018#if (defined SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB && TLS_TICKETS_NO > 0)
7019 hap_register_post_check(tlskeys_finalize_config);
7020#endif
Willy Tarreaud92aa5c2015-01-15 21:34:39 +01007021
Willy Tarreauc2c0b612016-12-21 19:23:20 +01007022 ptr = NULL;
7023 memprintf(&ptr, "Built with OpenSSL version : "
7024#ifdef OPENSSL_IS_BORINGSSL
7025 "BoringSSL\n");
7026#else /* OPENSSL_IS_BORINGSSL */
7027 OPENSSL_VERSION_TEXT
7028 "\nRunning on OpenSSL version : %s%s",
7029 SSLeay_version(SSLEAY_VERSION),
7030 ((OPENSSL_VERSION_NUMBER ^ SSLeay()) >> 8) ? " (VERSIONS DIFFER!)" : "");
7031#endif
7032 memprintf(&ptr, "%s\nOpenSSL library supports TLS extensions : "
7033#if OPENSSL_VERSION_NUMBER < 0x00907000L
7034 "no (library version too old)"
7035#elif defined(OPENSSL_NO_TLSEXT)
7036 "no (disabled via OPENSSL_NO_TLSEXT)"
7037#else
7038 "yes"
7039#endif
7040 "", ptr);
7041
7042 memprintf(&ptr, "%s\nOpenSSL library supports SNI : "
7043#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
7044 "yes"
7045#else
7046#ifdef OPENSSL_NO_TLSEXT
7047 "no (because of OPENSSL_NO_TLSEXT)"
7048#else
7049 "no (version might be too old, 0.9.8f min needed)"
7050#endif
7051#endif
7052 "", ptr);
7053
Willy Tarreauc2c0b612016-12-21 19:23:20 +01007054 hap_register_build_opts(ptr, 1);
7055
Willy Tarreaud92aa5c2015-01-15 21:34:39 +01007056 global.ssl_session_max_cost = SSL_SESSION_MAX_COST;
7057 global.ssl_handshake_max_cost = SSL_HANDSHAKE_MAX_COST;
Remi Gacogne4f902b82015-05-28 16:23:00 +02007058
7059#ifndef OPENSSL_NO_DH
7060 ssl_dh_ptr_index = SSL_CTX_get_ex_new_index(0, NULL, NULL, NULL, NULL);
7061#endif
Thierry FOURNIER / OZON.IO8b068c22016-10-10 11:59:50 +02007062
7063 /* Load SSL string for the verbose & debug mode. */
7064 ERR_load_SSL_strings();
Emeric Brun46591952012-05-18 15:47:34 +02007065}
7066
Remi Gacogned3a23c32015-05-28 16:39:47 +02007067__attribute__((destructor))
7068static void __ssl_sock_deinit(void)
7069{
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +01007070#if (defined SSL_CTRL_SET_TLSEXT_HOSTNAME && !defined SSL_NO_GENERATE_CERTIFICATES)
Christopher Faulet31af49d2015-06-09 17:29:50 +02007071 lru64_destroy(ssl_ctx_lru_tree);
Willy Tarreaua84c2672015-10-09 12:10:13 +02007072#endif
Christopher Faulet31af49d2015-06-09 17:29:50 +02007073
Remi Gacogned3a23c32015-05-28 16:39:47 +02007074#ifndef OPENSSL_NO_DH
7075 if (local_dh_1024) {
7076 DH_free(local_dh_1024);
7077 local_dh_1024 = NULL;
7078 }
7079
7080 if (local_dh_2048) {
7081 DH_free(local_dh_2048);
7082 local_dh_2048 = NULL;
7083 }
7084
7085 if (local_dh_4096) {
7086 DH_free(local_dh_4096);
7087 local_dh_4096 = NULL;
7088 }
7089
Remi Gacogne47783ef2015-05-29 15:53:22 +02007090 if (global_dh) {
7091 DH_free(global_dh);
7092 global_dh = NULL;
7093 }
Remi Gacogned3a23c32015-05-28 16:39:47 +02007094#endif
7095
7096 ERR_remove_state(0);
7097 ERR_free_strings();
7098
7099 EVP_cleanup();
7100
7101#if OPENSSL_VERSION_NUMBER >= 0x00907000L
7102 CRYPTO_cleanup_all_ex_data();
7103#endif
7104}
7105
7106
Emeric Brun46591952012-05-18 15:47:34 +02007107/*
7108 * Local variables:
7109 * c-indent-level: 8
7110 * c-basic-offset: 8
7111 * End:
7112 */