blob: 95f979c8e81dc7e54ca126266dcecd8b0e47c466 [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
Willy Tarreauc8ad3be2015-06-17 15:48:26 +0200179#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
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};
196
Emmanuel Hocdet98263292016-12-29 18:26:15 +0100197static struct ssl_bind_kw ssl_bind_kws[];
198
Christopher Faulet31af49d2015-06-09 17:29:50 +0200199/* LRU cache to store generated certificate */
200static struct lru64_head *ssl_ctx_lru_tree = NULL;
201static unsigned int ssl_ctx_lru_seed = 0;
Willy Tarreauc8ad3be2015-06-17 15:48:26 +0200202#endif // SSL_CTRL_SET_TLSEXT_HOSTNAME
203
yanbzhube2774d2015-12-10 15:07:30 -0500204#if OPENSSL_VERSION_NUMBER >= 0x1000200fL
205/* The order here matters for picking a default context,
206 * keep the most common keytype at the bottom of the list
207 */
208const char *SSL_SOCK_KEYTYPE_NAMES[] = {
209 "dsa",
210 "ecdsa",
211 "rsa"
212};
213#define SSL_SOCK_NUM_KEYTYPES 3
Willy Tarreau30da7ad2015-12-14 11:28:33 +0100214#else
215#define SSL_SOCK_NUM_KEYTYPES 1
yanbzhube2774d2015-12-10 15:07:30 -0500216#endif
217
Willy Tarreauc8ad3be2015-06-17 15:48:26 +0200218#if (defined SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB && !defined OPENSSL_NO_OCSP)
yanbzhube2774d2015-12-10 15:07:30 -0500219/*
220 * struct alignment works here such that the key.key is the same as key_data
221 * Do not change the placement of key_data
222 */
Willy Tarreauc8ad3be2015-06-17 15:48:26 +0200223struct certificate_ocsp {
224 struct ebmb_node key;
225 unsigned char key_data[OCSP_MAX_CERTID_ASN1_LENGTH];
226 struct chunk response;
227 long expire;
228};
Christopher Faulet31af49d2015-06-09 17:29:50 +0200229
yanbzhube2774d2015-12-10 15:07:30 -0500230struct ocsp_cbk_arg {
231 int is_single;
232 int single_kt;
233 union {
234 struct certificate_ocsp *s_ocsp;
235 /*
236 * m_ocsp will have multiple entries dependent on key type
237 * Entry 0 - DSA
238 * Entry 1 - ECDSA
239 * Entry 2 - RSA
240 */
241 struct certificate_ocsp *m_ocsp[SSL_SOCK_NUM_KEYTYPES];
242 };
243};
244
Emeric Brun4f3c87a2014-06-20 15:46:13 +0200245/*
Thierry FOURNIER / OZON.IO8b068c22016-10-10 11:59:50 +0200246 * This function gives the detail of the SSL error. It is used only
247 * if the debug mode and the verbose mode are activated. It dump all
248 * the SSL error until the stack was empty.
249 */
250static forceinline void ssl_sock_dump_errors(struct connection *conn)
251{
252 unsigned long ret;
253
254 if (unlikely(global.mode & MODE_DEBUG)) {
255 while(1) {
256 ret = ERR_get_error();
257 if (ret == 0)
258 return;
259 fprintf(stderr, "fd[%04x] OpenSSL error[0x%lx] %s: %s\n",
260 (unsigned short)conn->t.sock.fd, ret,
261 ERR_func_error_string(ret), ERR_reason_error_string(ret));
262 }
263 }
264}
265
266/*
Emeric Brun4f3c87a2014-06-20 15:46:13 +0200267 * This function returns the number of seconds elapsed
268 * since the Epoch, 1970-01-01 00:00:00 +0000 (UTC) and the
269 * date presented un ASN1_GENERALIZEDTIME.
270 *
271 * In parsing error case, it returns -1.
272 */
273static long asn1_generalizedtime_to_epoch(ASN1_GENERALIZEDTIME *d)
274{
275 long epoch;
276 char *p, *end;
277 const unsigned short month_offset[12] = {
278 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334
279 };
280 int year, month;
281
282 if (!d || (d->type != V_ASN1_GENERALIZEDTIME)) return -1;
283
284 p = (char *)d->data;
285 end = p + d->length;
286
287 if (end - p < 4) return -1;
288 year = 1000 * (p[0] - '0') + 100 * (p[1] - '0') + 10 * (p[2] - '0') + p[3] - '0';
289 p += 4;
290 if (end - p < 2) return -1;
291 month = 10 * (p[0] - '0') + p[1] - '0';
292 if (month < 1 || month > 12) return -1;
293 /* Compute the number of seconds since 1 jan 1970 and the beginning of current month
294 We consider leap years and the current month (<marsh or not) */
295 epoch = ( ((year - 1970) * 365)
296 + ((year - (month < 3)) / 4 - (year - (month < 3)) / 100 + (year - (month < 3)) / 400)
297 - ((1970 - 1) / 4 - (1970 - 1) / 100 + (1970 - 1) / 400)
298 + month_offset[month-1]
299 ) * 24 * 60 * 60;
300 p += 2;
301 if (end - p < 2) return -1;
302 /* Add the number of seconds of completed days of current month */
303 epoch += (10 * (p[0] - '0') + p[1] - '0' - 1) * 24 * 60 * 60;
304 p += 2;
305 if (end - p < 2) return -1;
306 /* Add the completed hours of the current day */
307 epoch += (10 * (p[0] - '0') + p[1] - '0') * 60 * 60;
308 p += 2;
309 if (end - p < 2) return -1;
310 /* Add the completed minutes of the current hour */
311 epoch += (10 * (p[0] - '0') + p[1] - '0') * 60;
312 p += 2;
313 if (p == end) return -1;
314 /* Test if there is available seconds */
315 if (p[0] < '0' || p[0] > '9')
316 goto nosec;
317 if (end - p < 2) return -1;
318 /* Add the seconds of the current minute */
319 epoch += 10 * (p[0] - '0') + p[1] - '0';
320 p += 2;
321 if (p == end) return -1;
322 /* Ignore seconds float part if present */
323 if (p[0] == '.') {
324 do {
325 if (++p == end) return -1;
326 } while (p[0] >= '0' && p[0] <= '9');
327 }
328
329nosec:
330 if (p[0] == 'Z') {
331 if (end - p != 1) return -1;
332 return epoch;
333 }
334 else if (p[0] == '+') {
335 if (end - p != 5) return -1;
336 /* Apply timezone offset */
337 return epoch - ((10 * (p[1] - '0') + p[2] - '0') * 60 + (10 * (p[3] - '0') + p[4] - '0')) * 60;
338 }
339 else if (p[0] == '-') {
340 if (end - p != 5) return -1;
341 /* Apply timezone offset */
342 return epoch + ((10 * (p[1] - '0') + p[2] - '0') * 60 + (10 * (p[3] - '0') + p[4] - '0')) * 60;
343 }
344
345 return -1;
346}
347
Emeric Brun1d3865b2014-06-20 15:37:32 +0200348static struct eb_root cert_ocsp_tree = EB_ROOT_UNIQUE;
Emeric Brun4147b2e2014-06-16 18:36:30 +0200349
350/* This function starts to check if the OCSP response (in DER format) contained
351 * in chunk 'ocsp_response' is valid (else exits on error).
352 * If 'cid' is not NULL, it will be compared to the OCSP certificate ID
353 * contained in the OCSP Response and exits on error if no match.
354 * If it's a valid OCSP Response:
355 * If 'ocsp' is not NULL, the chunk is copied in the OCSP response's container
356 * pointed by 'ocsp'.
357 * If 'ocsp' is NULL, the function looks up into the OCSP response's
358 * containers tree (using as index the ASN1 form of the OCSP Certificate ID extracted
359 * from the response) and exits on error if not found. Finally, If an OCSP response is
360 * already present in the container, it will be overwritten.
361 *
362 * Note: OCSP response containing more than one OCSP Single response is not
363 * considered valid.
364 *
365 * Returns 0 on success, 1 in error case.
366 */
367static int ssl_sock_load_ocsp_response(struct chunk *ocsp_response, struct certificate_ocsp *ocsp, OCSP_CERTID *cid, char **err)
368{
369 OCSP_RESPONSE *resp;
370 OCSP_BASICRESP *bs = NULL;
371 OCSP_SINGLERESP *sr;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +0200372 OCSP_CERTID *id;
Emeric Brun4147b2e2014-06-16 18:36:30 +0200373 unsigned char *p = (unsigned char *)ocsp_response->str;
374 int rc , count_sr;
Emeric Brun13a6b482014-06-20 15:44:34 +0200375 ASN1_GENERALIZEDTIME *revtime, *thisupd, *nextupd = NULL;
Emeric Brun4147b2e2014-06-16 18:36:30 +0200376 int reason;
377 int ret = 1;
378
379 resp = d2i_OCSP_RESPONSE(NULL, (const unsigned char **)&p, ocsp_response->len);
380 if (!resp) {
381 memprintf(err, "Unable to parse OCSP response");
382 goto out;
383 }
384
385 rc = OCSP_response_status(resp);
386 if (rc != OCSP_RESPONSE_STATUS_SUCCESSFUL) {
387 memprintf(err, "OCSP response status not successful");
388 goto out;
389 }
390
391 bs = OCSP_response_get1_basic(resp);
392 if (!bs) {
393 memprintf(err, "Failed to get basic response from OCSP Response");
394 goto out;
395 }
396
397 count_sr = OCSP_resp_count(bs);
398 if (count_sr > 1) {
399 memprintf(err, "OCSP response ignored because contains multiple single responses (%d)", count_sr);
400 goto out;
401 }
402
403 sr = OCSP_resp_get0(bs, 0);
404 if (!sr) {
405 memprintf(err, "Failed to get OCSP single response");
406 goto out;
407 }
408
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +0200409 id = (OCSP_CERTID*)OCSP_SINGLERESP_get0_id(sr);
410
Emeric Brun4147b2e2014-06-16 18:36:30 +0200411 rc = OCSP_single_get0_status(sr, &reason, &revtime, &thisupd, &nextupd);
412 if (rc != V_OCSP_CERTSTATUS_GOOD) {
413 memprintf(err, "OCSP single response: certificate status not good");
414 goto out;
415 }
416
Emeric Brun13a6b482014-06-20 15:44:34 +0200417 if (!nextupd) {
418 memprintf(err, "OCSP single response: missing nextupdate");
419 goto out;
420 }
421
Emeric Brunc8b27b62014-06-19 14:16:17 +0200422 rc = OCSP_check_validity(thisupd, nextupd, OCSP_MAX_RESPONSE_TIME_SKEW, -1);
Emeric Brun4147b2e2014-06-16 18:36:30 +0200423 if (!rc) {
424 memprintf(err, "OCSP single response: no longer valid.");
425 goto out;
426 }
427
428 if (cid) {
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +0200429 if (OCSP_id_cmp(id, cid)) {
Emeric Brun4147b2e2014-06-16 18:36:30 +0200430 memprintf(err, "OCSP single response: Certificate ID does not match certificate and issuer");
431 goto out;
432 }
433 }
434
435 if (!ocsp) {
436 unsigned char key[OCSP_MAX_CERTID_ASN1_LENGTH];
437 unsigned char *p;
438
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +0200439 rc = i2d_OCSP_CERTID(id, NULL);
Emeric Brun4147b2e2014-06-16 18:36:30 +0200440 if (!rc) {
441 memprintf(err, "OCSP single response: Unable to encode Certificate ID");
442 goto out;
443 }
444
445 if (rc > OCSP_MAX_CERTID_ASN1_LENGTH) {
446 memprintf(err, "OCSP single response: Certificate ID too long");
447 goto out;
448 }
449
450 p = key;
451 memset(key, 0, OCSP_MAX_CERTID_ASN1_LENGTH);
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +0200452 i2d_OCSP_CERTID(id, &p);
Emeric Brun4147b2e2014-06-16 18:36:30 +0200453 ocsp = (struct certificate_ocsp *)ebmb_lookup(&cert_ocsp_tree, key, OCSP_MAX_CERTID_ASN1_LENGTH);
454 if (!ocsp) {
455 memprintf(err, "OCSP single response: Certificate ID does not match any certificate or issuer");
456 goto out;
457 }
458 }
459
460 /* According to comments on "chunk_dup", the
461 previous chunk buffer will be freed */
462 if (!chunk_dup(&ocsp->response, ocsp_response)) {
463 memprintf(err, "OCSP response: Memory allocation error");
464 goto out;
465 }
466
Emeric Brun4f3c87a2014-06-20 15:46:13 +0200467 ocsp->expire = asn1_generalizedtime_to_epoch(nextupd) - OCSP_MAX_RESPONSE_TIME_SKEW;
468
Emeric Brun4147b2e2014-06-16 18:36:30 +0200469 ret = 0;
470out:
471 if (bs)
472 OCSP_BASICRESP_free(bs);
473
474 if (resp)
475 OCSP_RESPONSE_free(resp);
476
477 return ret;
478}
479/*
480 * External function use to update the OCSP response in the OCSP response's
481 * containers tree. The chunk 'ocsp_response' must contain the OCSP response
482 * to update in DER format.
483 *
484 * Returns 0 on success, 1 in error case.
485 */
486int ssl_sock_update_ocsp_response(struct chunk *ocsp_response, char **err)
487{
488 return ssl_sock_load_ocsp_response(ocsp_response, NULL, NULL, err);
489}
490
491/*
492 * This function load the OCSP Resonse in DER format contained in file at
493 * path 'ocsp_path' and call 'ssl_sock_load_ocsp_response'
494 *
495 * Returns 0 on success, 1 in error case.
496 */
497static int ssl_sock_load_ocsp_response_from_file(const char *ocsp_path, struct certificate_ocsp *ocsp, OCSP_CERTID *cid, char **err)
498{
499 int fd = -1;
500 int r = 0;
501 int ret = 1;
502
503 fd = open(ocsp_path, O_RDONLY);
504 if (fd == -1) {
505 memprintf(err, "Error opening OCSP response file");
506 goto end;
507 }
508
509 trash.len = 0;
510 while (trash.len < trash.size) {
511 r = read(fd, trash.str + trash.len, trash.size - trash.len);
512 if (r < 0) {
513 if (errno == EINTR)
514 continue;
515
516 memprintf(err, "Error reading OCSP response from file");
517 goto end;
518 }
519 else if (r == 0) {
520 break;
521 }
522 trash.len += r;
523 }
524
525 close(fd);
526 fd = -1;
527
528 ret = ssl_sock_load_ocsp_response(&trash, ocsp, cid, err);
529end:
530 if (fd != -1)
531 close(fd);
532
533 return ret;
534}
535
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}
658
Nenad Merdanovic05552d42015-02-27 19:56:49 +0100659#endif /* SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB */
660
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
Christopher Faulet85b5a1a2015-10-09 11:46:32 +02001215static DH *ssl_get_tmp_dh(SSL *ssl, int export, int keylen);
1216
Christopher Faulet30548802015-06-11 13:39:32 +02001217/* Create a X509 certificate with the specified servername and serial. This
1218 * function returns a SSL_CTX object or NULL if an error occurs. */
Christopher Faulet7969a332015-10-09 11:15:03 +02001219static SSL_CTX *
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001220ssl_sock_do_create_cert(const char *servername, struct bind_conf *bind_conf, SSL *ssl)
Christopher Faulet31af49d2015-06-09 17:29:50 +02001221{
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001222 static unsigned int serial = 0;
1223
Christopher Faulet7969a332015-10-09 11:15:03 +02001224 X509 *cacert = bind_conf->ca_sign_cert;
1225 EVP_PKEY *capkey = bind_conf->ca_sign_pkey;
Christopher Faulet31af49d2015-06-09 17:29:50 +02001226 SSL_CTX *ssl_ctx = NULL;
1227 X509 *newcrt = NULL;
1228 EVP_PKEY *pkey = NULL;
Christopher Faulet31af49d2015-06-09 17:29:50 +02001229 X509_NAME *name;
1230 const EVP_MD *digest;
1231 X509V3_CTX ctx;
1232 unsigned int i;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02001233 int key_type;
Christopher Faulet31af49d2015-06-09 17:29:50 +02001234
Christopher Faulet7969a332015-10-09 11:15:03 +02001235 /* Get the private key of the defautl certificate and use it */
1236 if (!(pkey = SSL_get_privatekey(ssl)))
Christopher Faulet31af49d2015-06-09 17:29:50 +02001237 goto mkcert_error;
1238
1239 /* Create the certificate */
1240 if (!(newcrt = X509_new()))
1241 goto mkcert_error;
1242
1243 /* Set version number for the certificate (X509v3) and the serial
1244 * number */
1245 if (X509_set_version(newcrt, 2L) != 1)
1246 goto mkcert_error;
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001247 if (!serial)
1248 serial = now_ms;
1249 ASN1_INTEGER_set(X509_get_serialNumber(newcrt), serial++);
Christopher Faulet31af49d2015-06-09 17:29:50 +02001250
1251 /* Set duration for the certificate */
1252 if (!X509_gmtime_adj(X509_get_notBefore(newcrt), (long)-60*60*24) ||
1253 !X509_gmtime_adj(X509_get_notAfter(newcrt),(long)60*60*24*365))
1254 goto mkcert_error;
1255
1256 /* set public key in the certificate */
1257 if (X509_set_pubkey(newcrt, pkey) != 1)
1258 goto mkcert_error;
1259
1260 /* Set issuer name from the CA */
1261 if (!(name = X509_get_subject_name(cacert)))
1262 goto mkcert_error;
1263 if (X509_set_issuer_name(newcrt, name) != 1)
1264 goto mkcert_error;
1265
1266 /* Set the subject name using the same, but the CN */
1267 name = X509_NAME_dup(name);
1268 if (X509_NAME_add_entry_by_txt(name, "CN", MBSTRING_ASC,
1269 (const unsigned char *)servername,
1270 -1, -1, 0) != 1) {
1271 X509_NAME_free(name);
1272 goto mkcert_error;
1273 }
1274 if (X509_set_subject_name(newcrt, name) != 1) {
1275 X509_NAME_free(name);
1276 goto mkcert_error;
1277 }
1278 X509_NAME_free(name);
1279
1280 /* Add x509v3 extensions as specified */
1281 X509V3_set_ctx(&ctx, cacert, newcrt, NULL, NULL, 0);
1282 for (i = 0; i < X509V3_EXT_SIZE; i++) {
1283 X509_EXTENSION *ext;
1284
1285 if (!(ext = X509V3_EXT_conf(NULL, &ctx, x509v3_ext_names[i], x509v3_ext_values[i])))
1286 goto mkcert_error;
1287 if (!X509_add_ext(newcrt, ext, -1)) {
1288 X509_EXTENSION_free(ext);
1289 goto mkcert_error;
1290 }
1291 X509_EXTENSION_free(ext);
1292 }
1293
1294 /* Sign the certificate with the CA private key */
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02001295
1296 key_type = EVP_PKEY_base_id(capkey);
1297
1298 if (key_type == EVP_PKEY_DSA)
1299 digest = EVP_sha1();
1300 else if (key_type == EVP_PKEY_RSA)
Christopher Faulet31af49d2015-06-09 17:29:50 +02001301 digest = EVP_sha256();
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02001302 else if (key_type == EVP_PKEY_EC)
Christopher Faulet7969a332015-10-09 11:15:03 +02001303 digest = EVP_sha256();
1304 else {
Christopher Faulete7db2162015-10-19 13:59:24 +02001305#if (OPENSSL_VERSION_NUMBER >= 0x1000000fL)
Christopher Faulet7969a332015-10-09 11:15:03 +02001306 int nid;
1307
1308 if (EVP_PKEY_get_default_digest_nid(capkey, &nid) <= 0)
1309 goto mkcert_error;
1310 if (!(digest = EVP_get_digestbynid(nid)))
1311 goto mkcert_error;
Christopher Faulete7db2162015-10-19 13:59:24 +02001312#else
1313 goto mkcert_error;
1314#endif
Christopher Faulet7969a332015-10-09 11:15:03 +02001315 }
1316
Christopher Faulet31af49d2015-06-09 17:29:50 +02001317 if (!(X509_sign(newcrt, capkey, digest)))
1318 goto mkcert_error;
1319
1320 /* Create and set the new SSL_CTX */
1321 if (!(ssl_ctx = SSL_CTX_new(SSLv23_server_method())))
1322 goto mkcert_error;
1323 if (!SSL_CTX_use_PrivateKey(ssl_ctx, pkey))
1324 goto mkcert_error;
1325 if (!SSL_CTX_use_certificate(ssl_ctx, newcrt))
1326 goto mkcert_error;
1327 if (!SSL_CTX_check_private_key(ssl_ctx))
1328 goto mkcert_error;
1329
1330 if (newcrt) X509_free(newcrt);
Christopher Faulet7969a332015-10-09 11:15:03 +02001331
Christopher Faulet85b5a1a2015-10-09 11:46:32 +02001332 SSL_CTX_set_tmp_dh_callback(ssl_ctx, ssl_get_tmp_dh);
1333#if defined(SSL_CTX_set_tmp_ecdh) && !defined(OPENSSL_NO_ECDH)
1334 {
Emmanuel Hocdet98263292016-12-29 18:26:15 +01001335 const char *ecdhe = (bind_conf->ssl_conf.ecdhe ? bind_conf->ssl_conf.ecdhe : ECDHE_DEFAULT_CURVE);
Christopher Faulet85b5a1a2015-10-09 11:46:32 +02001336 EC_KEY *ecc;
1337 int nid;
1338
1339 if ((nid = OBJ_sn2nid(ecdhe)) == NID_undef)
1340 goto end;
1341 if (!(ecc = EC_KEY_new_by_curve_name(nid)))
1342 goto end;
1343 SSL_CTX_set_tmp_ecdh(ssl_ctx, ecc);
1344 EC_KEY_free(ecc);
1345 }
1346#endif
1347 end:
Christopher Faulet31af49d2015-06-09 17:29:50 +02001348 return ssl_ctx;
1349
1350 mkcert_error:
1351 if (ssl_ctx) SSL_CTX_free(ssl_ctx);
1352 if (newcrt) X509_free(newcrt);
Christopher Faulet31af49d2015-06-09 17:29:50 +02001353 return NULL;
1354}
1355
Christopher Faulet7969a332015-10-09 11:15:03 +02001356SSL_CTX *
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001357ssl_sock_create_cert(struct connection *conn, const char *servername, unsigned int key)
Christopher Faulet7969a332015-10-09 11:15:03 +02001358{
1359 struct bind_conf *bind_conf = objt_listener(conn->target)->bind_conf;
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001360
1361 return ssl_sock_do_create_cert(servername, bind_conf, conn->xprt_ctx);
Christopher Faulet7969a332015-10-09 11:15:03 +02001362}
1363
Christopher Faulet30548802015-06-11 13:39:32 +02001364/* Do a lookup for a certificate in the LRU cache used to store generated
1365 * certificates. */
1366SSL_CTX *
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001367ssl_sock_get_generated_cert(unsigned int key, struct bind_conf *bind_conf)
Christopher Faulet30548802015-06-11 13:39:32 +02001368{
1369 struct lru64 *lru = NULL;
1370
1371 if (ssl_ctx_lru_tree) {
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001372 lru = lru64_lookup(key, ssl_ctx_lru_tree, bind_conf->ca_sign_cert, 0);
Christopher Faulet30548802015-06-11 13:39:32 +02001373 if (lru && lru->domain)
1374 return (SSL_CTX *)lru->data;
1375 }
1376 return NULL;
1377}
1378
Christopher Fauletd2cab922015-07-28 16:03:47 +02001379/* Set a certificate int the LRU cache used to store generated
1380 * certificate. Return 0 on success, otherwise -1 */
1381int
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001382ssl_sock_set_generated_cert(SSL_CTX *ssl_ctx, unsigned int key, struct bind_conf *bind_conf)
Christopher Faulet30548802015-06-11 13:39:32 +02001383{
1384 struct lru64 *lru = NULL;
1385
1386 if (ssl_ctx_lru_tree) {
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001387 lru = lru64_get(key, ssl_ctx_lru_tree, bind_conf->ca_sign_cert, 0);
Christopher Faulet30548802015-06-11 13:39:32 +02001388 if (!lru)
Christopher Fauletd2cab922015-07-28 16:03:47 +02001389 return -1;
Christopher Faulet30548802015-06-11 13:39:32 +02001390 if (lru->domain && lru->data)
1391 lru->free((SSL_CTX *)lru->data);
Christopher Faulet7969a332015-10-09 11:15:03 +02001392 lru64_commit(lru, ssl_ctx, bind_conf->ca_sign_cert, 0, (void (*)(void *))SSL_CTX_free);
Christopher Fauletd2cab922015-07-28 16:03:47 +02001393 return 0;
Christopher Faulet30548802015-06-11 13:39:32 +02001394 }
Christopher Fauletd2cab922015-07-28 16:03:47 +02001395 return -1;
Christopher Faulet30548802015-06-11 13:39:32 +02001396}
1397
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001398/* Compute the key of the certificate. */
Christopher Faulet30548802015-06-11 13:39:32 +02001399unsigned int
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001400ssl_sock_generated_cert_key(const void *data, size_t len)
Christopher Faulet30548802015-06-11 13:39:32 +02001401{
1402 return XXH32(data, len, ssl_ctx_lru_seed);
1403}
1404
Willy Tarreau2f63ef42015-10-20 15:16:01 +02001405/* Generate a cert and immediately assign it to the SSL session so that the cert's
1406 * refcount is maintained regardless of the cert's presence in the LRU cache.
1407 */
Christopher Faulet31af49d2015-06-09 17:29:50 +02001408static SSL_CTX *
Christopher Faulet7969a332015-10-09 11:15:03 +02001409ssl_sock_generate_certificate(const char *servername, struct bind_conf *bind_conf, SSL *ssl)
Christopher Faulet31af49d2015-06-09 17:29:50 +02001410{
1411 X509 *cacert = bind_conf->ca_sign_cert;
Christopher Faulet31af49d2015-06-09 17:29:50 +02001412 SSL_CTX *ssl_ctx = NULL;
1413 struct lru64 *lru = NULL;
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001414 unsigned int key;
Christopher Faulet31af49d2015-06-09 17:29:50 +02001415
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001416 key = ssl_sock_generated_cert_key(servername, strlen(servername));
Christopher Faulet31af49d2015-06-09 17:29:50 +02001417 if (ssl_ctx_lru_tree) {
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001418 lru = lru64_get(key, ssl_ctx_lru_tree, cacert, 0);
Christopher Faulet31af49d2015-06-09 17:29:50 +02001419 if (lru && lru->domain)
1420 ssl_ctx = (SSL_CTX *)lru->data;
Christopher Fauletd2cab922015-07-28 16:03:47 +02001421 if (!ssl_ctx && lru) {
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001422 ssl_ctx = ssl_sock_do_create_cert(servername, bind_conf, ssl);
Christopher Faulet31af49d2015-06-09 17:29:50 +02001423 lru64_commit(lru, ssl_ctx, cacert, 0, (void (*)(void *))SSL_CTX_free);
Christopher Fauletd2cab922015-07-28 16:03:47 +02001424 }
Willy Tarreau2f63ef42015-10-20 15:16:01 +02001425 SSL_set_SSL_CTX(ssl, ssl_ctx);
Christopher Faulet31af49d2015-06-09 17:29:50 +02001426 }
Willy Tarreau2f63ef42015-10-20 15:16:01 +02001427 else {
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001428 ssl_ctx = ssl_sock_do_create_cert(servername, bind_conf, ssl);
Willy Tarreau2f63ef42015-10-20 15:16:01 +02001429 SSL_set_SSL_CTX(ssl, ssl_ctx);
1430 /* No LRU cache, this CTX will be released as soon as the session dies */
1431 SSL_CTX_free(ssl_ctx);
1432 }
Christopher Faulet31af49d2015-06-09 17:29:50 +02001433 return ssl_ctx;
1434}
1435
Emeric Brunfc0421f2012-09-07 17:30:07 +02001436/* Sets the SSL ctx of <ssl> to match the advertised server name. Returns a
1437 * warning when no match is found, which implies the default (first) cert
1438 * will keep being used.
1439 */
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001440static int ssl_sock_switchctx_cbk(SSL *ssl, int *al, struct bind_conf *s)
Emeric Brunfc0421f2012-09-07 17:30:07 +02001441{
1442 const char *servername;
1443 const char *wildp = NULL;
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001444 struct ebmb_node *node, *n;
Emeric Brunfc0421f2012-09-07 17:30:07 +02001445 int i;
1446 (void)al; /* shut gcc stupid warning */
1447
1448 servername = SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name);
Emmanuel Hocdet65623372013-01-24 17:17:15 +01001449 if (!servername) {
Willy Tarreauf6721452015-07-07 18:04:38 +02001450 if (s->generate_certs) {
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02001451 struct connection *conn = SSL_get_app_data(ssl);
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001452 unsigned int key;
Willy Tarreauf6721452015-07-07 18:04:38 +02001453 SSL_CTX *ctx;
Christopher Faulet30548802015-06-11 13:39:32 +02001454
Willy Tarreauf6721452015-07-07 18:04:38 +02001455 conn_get_to_addr(conn);
1456 if (conn->flags & CO_FL_ADDR_TO_SET) {
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001457 key = ssl_sock_generated_cert_key(&conn->addr.to, get_addr_len(&conn->addr.to));
1458 ctx = ssl_sock_get_generated_cert(key, s);
Willy Tarreauf6721452015-07-07 18:04:38 +02001459 if (ctx) {
1460 /* switch ctx */
1461 SSL_set_SSL_CTX(ssl, ctx);
1462 return SSL_TLSEXT_ERR_OK;
1463 }
Christopher Faulet30548802015-06-11 13:39:32 +02001464 }
1465 }
1466
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001467 return (s->strict_sni ?
1468 SSL_TLSEXT_ERR_ALERT_FATAL :
Emmanuel Hocdet79274e22013-05-31 12:47:44 +02001469 SSL_TLSEXT_ERR_NOACK);
Emmanuel Hocdet65623372013-01-24 17:17:15 +01001470 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02001471
Willy Tarreau19d14ef2012-10-29 16:51:55 +01001472 for (i = 0; i < trash.size; i++) {
Emeric Brunfc0421f2012-09-07 17:30:07 +02001473 if (!servername[i])
1474 break;
Willy Tarreau19d14ef2012-10-29 16:51:55 +01001475 trash.str[i] = tolower(servername[i]);
1476 if (!wildp && (trash.str[i] == '.'))
1477 wildp = &trash.str[i];
Emeric Brunfc0421f2012-09-07 17:30:07 +02001478 }
Willy Tarreau19d14ef2012-10-29 16:51:55 +01001479 trash.str[i] = 0;
Emeric Brunfc0421f2012-09-07 17:30:07 +02001480
1481 /* lookup in full qualified names */
Willy Tarreau19d14ef2012-10-29 16:51:55 +01001482 node = ebst_lookup(&s->sni_ctx, trash.str);
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001483
1484 /* lookup a not neg filter */
1485 for (n = node; n; n = ebmb_next_dup(n)) {
1486 if (!container_of(n, struct sni_ctx, name)->neg) {
1487 node = n;
1488 break;
Emmanuel Hocdet65623372013-01-24 17:17:15 +01001489 }
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001490 }
1491 if (!node && wildp) {
1492 /* lookup in wildcards names */
Emeric Brunfc0421f2012-09-07 17:30:07 +02001493 node = ebst_lookup(&s->sni_w_ctx, wildp);
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001494 }
1495 if (!node || container_of(node, struct sni_ctx, name)->neg) {
Christopher Faulet31af49d2015-06-09 17:29:50 +02001496 SSL_CTX *ctx;
Christopher Faulet31af49d2015-06-09 17:29:50 +02001497 if (s->generate_certs &&
Christopher Faulet7969a332015-10-09 11:15:03 +02001498 (ctx = ssl_sock_generate_certificate(servername, s, ssl))) {
Christopher Faulet31af49d2015-06-09 17:29:50 +02001499 /* switch ctx */
Christopher Faulet31af49d2015-06-09 17:29:50 +02001500 return SSL_TLSEXT_ERR_OK;
1501 }
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001502 return (s->strict_sni ?
1503 SSL_TLSEXT_ERR_ALERT_FATAL :
1504 SSL_TLSEXT_ERR_ALERT_WARNING);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001505 }
1506
1507 /* switch ctx */
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001508 SSL_set_SSL_CTX(ssl, container_of(node, struct sni_ctx, name)->ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001509 return SSL_TLSEXT_ERR_OK;
1510}
1511#endif /* SSL_CTRL_SET_TLSEXT_HOSTNAME */
1512
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001513#ifndef OPENSSL_NO_DH
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001514
1515static DH * ssl_get_dh_1024(void)
1516{
Remi Gacogned3a341a2015-05-29 16:26:17 +02001517 static unsigned char dh1024_p[]={
1518 0xFA,0xF9,0x2A,0x22,0x2A,0xA7,0x7F,0xE1,0x67,0x4E,0x53,0xF7,
1519 0x56,0x13,0xC3,0xB1,0xE3,0x29,0x6B,0x66,0x31,0x6A,0x7F,0xB3,
1520 0xC2,0x68,0x6B,0xCB,0x1D,0x57,0x39,0x1D,0x1F,0xFF,0x1C,0xC9,
1521 0xA6,0xA4,0x98,0x82,0x31,0x5D,0x25,0xFF,0x8A,0xE0,0x73,0x96,
1522 0x81,0xC8,0x83,0x79,0xC1,0x5A,0x04,0xF8,0x37,0x0D,0xA8,0x3D,
1523 0xAE,0x74,0xBC,0xDB,0xB6,0xA4,0x75,0xD9,0x71,0x8A,0xA0,0x17,
1524 0x9E,0x2D,0xC8,0xA8,0xDF,0x2C,0x5F,0x82,0x95,0xF8,0x92,0x9B,
1525 0xA7,0x33,0x5F,0x89,0x71,0xC8,0x2D,0x6B,0x18,0x86,0xC4,0x94,
1526 0x22,0xA5,0x52,0x8D,0xF6,0xF6,0xD2,0x37,0x92,0x0F,0xA5,0xCC,
1527 0xDB,0x7B,0x1D,0x3D,0xA1,0x31,0xB7,0x80,0x8F,0x0B,0x67,0x5E,
1528 0x36,0xA5,0x60,0x0C,0xF1,0x95,0x33,0x8B,
1529 };
1530 static unsigned char dh1024_g[]={
1531 0x02,
1532 };
1533
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02001534 BIGNUM *p;
1535 BIGNUM *g;
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001536 DH *dh = DH_new();
1537 if (dh) {
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02001538 p = BN_bin2bn(dh1024_p, sizeof dh1024_p, NULL);
1539 g = BN_bin2bn(dh1024_g, sizeof dh1024_g, NULL);
Remi Gacogned3a341a2015-05-29 16:26:17 +02001540
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02001541 if (!p || !g) {
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001542 DH_free(dh);
1543 dh = NULL;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02001544 } else {
1545 DH_set0_pqg(dh, p, NULL, g);
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001546 }
1547 }
1548 return dh;
1549}
1550
1551static DH *ssl_get_dh_2048(void)
1552{
Remi Gacogned3a341a2015-05-29 16:26:17 +02001553 static unsigned char dh2048_p[]={
1554 0xEC,0x86,0xF8,0x70,0xA0,0x33,0x16,0xEC,0x05,0x1A,0x73,0x59,
1555 0xCD,0x1F,0x8B,0xF8,0x29,0xE4,0xD2,0xCF,0x52,0xDD,0xC2,0x24,
1556 0x8D,0xB5,0x38,0x9A,0xFB,0x5C,0xA4,0xE4,0xB2,0xDA,0xCE,0x66,
1557 0x50,0x74,0xA6,0x85,0x4D,0x4B,0x1D,0x30,0xB8,0x2B,0xF3,0x10,
1558 0xE9,0xA7,0x2D,0x05,0x71,0xE7,0x81,0xDF,0x8B,0x59,0x52,0x3B,
1559 0x5F,0x43,0x0B,0x68,0xF1,0xDB,0x07,0xBE,0x08,0x6B,0x1B,0x23,
1560 0xEE,0x4D,0xCC,0x9E,0x0E,0x43,0xA0,0x1E,0xDF,0x43,0x8C,0xEC,
1561 0xBE,0xBE,0x90,0xB4,0x51,0x54,0xB9,0x2F,0x7B,0x64,0x76,0x4E,
1562 0x5D,0xD4,0x2E,0xAE,0xC2,0x9E,0xAE,0x51,0x43,0x59,0xC7,0x77,
1563 0x9C,0x50,0x3C,0x0E,0xED,0x73,0x04,0x5F,0xF1,0x4C,0x76,0x2A,
1564 0xD8,0xF8,0xCF,0xFC,0x34,0x40,0xD1,0xB4,0x42,0x61,0x84,0x66,
1565 0x42,0x39,0x04,0xF8,0x68,0xB2,0x62,0xD7,0x55,0xED,0x1B,0x74,
1566 0x75,0x91,0xE0,0xC5,0x69,0xC1,0x31,0x5C,0xDB,0x7B,0x44,0x2E,
1567 0xCE,0x84,0x58,0x0D,0x1E,0x66,0x0C,0xC8,0x44,0x9E,0xFD,0x40,
1568 0x08,0x67,0x5D,0xFB,0xA7,0x76,0x8F,0x00,0x11,0x87,0xE9,0x93,
1569 0xF9,0x7D,0xC4,0xBC,0x74,0x55,0x20,0xD4,0x4A,0x41,0x2F,0x43,
1570 0x42,0x1A,0xC1,0xF2,0x97,0x17,0x49,0x27,0x37,0x6B,0x2F,0x88,
1571 0x7E,0x1C,0xA0,0xA1,0x89,0x92,0x27,0xD9,0x56,0x5A,0x71,0xC1,
1572 0x56,0x37,0x7E,0x3A,0x9D,0x05,0xE7,0xEE,0x5D,0x8F,0x82,0x17,
1573 0xBC,0xE9,0xC2,0x93,0x30,0x82,0xF9,0xF4,0xC9,0xAE,0x49,0xDB,
1574 0xD0,0x54,0xB4,0xD9,0x75,0x4D,0xFA,0x06,0xB8,0xD6,0x38,0x41,
1575 0xB7,0x1F,0x77,0xF3,
1576 };
1577 static unsigned char dh2048_g[]={
1578 0x02,
1579 };
1580
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02001581 BIGNUM *p;
1582 BIGNUM *g;
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001583 DH *dh = DH_new();
1584 if (dh) {
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02001585 p = BN_bin2bn(dh2048_p, sizeof dh2048_p, NULL);
1586 g = BN_bin2bn(dh2048_g, sizeof dh2048_g, NULL);
Remi Gacogned3a341a2015-05-29 16:26:17 +02001587
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02001588 if (!p || !g) {
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001589 DH_free(dh);
1590 dh = NULL;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02001591 } else {
1592 DH_set0_pqg(dh, p, NULL, g);
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001593 }
1594 }
1595 return dh;
1596}
1597
1598static DH *ssl_get_dh_4096(void)
1599{
Remi Gacogned3a341a2015-05-29 16:26:17 +02001600 static unsigned char dh4096_p[]={
1601 0xDE,0x16,0x94,0xCD,0x99,0x58,0x07,0xF1,0xF7,0x32,0x96,0x11,
1602 0x04,0x82,0xD4,0x84,0x72,0x80,0x99,0x06,0xCA,0xF0,0xA3,0x68,
1603 0x07,0xCE,0x64,0x50,0xE7,0x74,0x45,0x20,0x80,0x5E,0x4D,0xAD,
1604 0xA5,0xB6,0xED,0xFA,0x80,0x6C,0x3B,0x35,0xC4,0x9A,0x14,0x6B,
1605 0x32,0xBB,0xFD,0x1F,0x17,0x8E,0xB7,0x1F,0xD6,0xFA,0x3F,0x7B,
1606 0xEE,0x16,0xA5,0x62,0x33,0x0D,0xED,0xBC,0x4E,0x58,0xE5,0x47,
1607 0x4D,0xE9,0xAB,0x8E,0x38,0xD3,0x6E,0x90,0x57,0xE3,0x22,0x15,
1608 0x33,0xBD,0xF6,0x43,0x45,0xB5,0x10,0x0A,0xBE,0x2C,0xB4,0x35,
1609 0xB8,0x53,0x8D,0xAD,0xFB,0xA7,0x1F,0x85,0x58,0x41,0x7A,0x79,
1610 0x20,0x68,0xB3,0xE1,0x3D,0x08,0x76,0xBF,0x86,0x0D,0x49,0xE3,
1611 0x82,0x71,0x8C,0xB4,0x8D,0x81,0x84,0xD4,0xE7,0xBE,0x91,0xDC,
1612 0x26,0x39,0x48,0x0F,0x35,0xC4,0xCA,0x65,0xE3,0x40,0x93,0x52,
1613 0x76,0x58,0x7D,0xDD,0x51,0x75,0xDC,0x69,0x61,0xBF,0x47,0x2C,
1614 0x16,0x68,0x2D,0xC9,0x29,0xD3,0xE6,0xC0,0x99,0x48,0xA0,0x9A,
1615 0xC8,0x78,0xC0,0x6D,0x81,0x67,0x12,0x61,0x3F,0x71,0xBA,0x41,
1616 0x1F,0x6C,0x89,0x44,0x03,0xBA,0x3B,0x39,0x60,0xAA,0x28,0x55,
1617 0x59,0xAE,0xB8,0xFA,0xCB,0x6F,0xA5,0x1A,0xF7,0x2B,0xDD,0x52,
1618 0x8A,0x8B,0xE2,0x71,0xA6,0x5E,0x7E,0xD8,0x2E,0x18,0xE0,0x66,
1619 0xDF,0xDD,0x22,0x21,0x99,0x52,0x73,0xA6,0x33,0x20,0x65,0x0E,
1620 0x53,0xE7,0x6B,0x9B,0xC5,0xA3,0x2F,0x97,0x65,0x76,0xD3,0x47,
1621 0x23,0x77,0x12,0xB6,0x11,0x7B,0x24,0xED,0xF1,0xEF,0xC0,0xE2,
1622 0xA3,0x7E,0x67,0x05,0x3E,0x96,0x4D,0x45,0xC2,0x18,0xD1,0x73,
1623 0x9E,0x07,0xF3,0x81,0x6E,0x52,0x63,0xF6,0x20,0x76,0xB9,0x13,
1624 0xD2,0x65,0x30,0x18,0x16,0x09,0x16,0x9E,0x8F,0xF1,0xD2,0x10,
1625 0x5A,0xD3,0xD4,0xAF,0x16,0x61,0xDA,0x55,0x2E,0x18,0x5E,0x14,
1626 0x08,0x54,0x2E,0x2A,0x25,0xA2,0x1A,0x9B,0x8B,0x32,0xA9,0xFD,
1627 0xC2,0x48,0x96,0xE1,0x80,0xCA,0xE9,0x22,0x17,0xBB,0xCE,0x3E,
1628 0x9E,0xED,0xC7,0xF1,0x1F,0xEC,0x17,0x21,0xDC,0x7B,0x82,0x48,
1629 0x8E,0xBB,0x4B,0x9D,0x5B,0x04,0x04,0xDA,0xDB,0x39,0xDF,0x01,
1630 0x40,0xC3,0xAA,0x26,0x23,0x89,0x75,0xC6,0x0B,0xD0,0xA2,0x60,
1631 0x6A,0xF1,0xCC,0x65,0x18,0x98,0x1B,0x52,0xD2,0x74,0x61,0xCC,
1632 0xBD,0x60,0xAE,0xA3,0xA0,0x66,0x6A,0x16,0x34,0x92,0x3F,0x41,
1633 0x40,0x31,0x29,0xC0,0x2C,0x63,0xB2,0x07,0x8D,0xEB,0x94,0xB8,
1634 0xE8,0x47,0x92,0x52,0x93,0x6A,0x1B,0x7E,0x1A,0x61,0xB3,0x1B,
1635 0xF0,0xD6,0x72,0x9B,0xF1,0xB0,0xAF,0xBF,0x3E,0x65,0xEF,0x23,
1636 0x1D,0x6F,0xFF,0x70,0xCD,0x8A,0x4C,0x8A,0xA0,0x72,0x9D,0xBE,
1637 0xD4,0xBB,0x24,0x47,0x4A,0x68,0xB5,0xF5,0xC6,0xD5,0x7A,0xCD,
1638 0xCA,0x06,0x41,0x07,0xAD,0xC2,0x1E,0xE6,0x54,0xA7,0xAD,0x03,
1639 0xD9,0x12,0xC1,0x9C,0x13,0xB1,0xC9,0x0A,0x43,0x8E,0x1E,0x08,
1640 0xCE,0x50,0x82,0x73,0x5F,0xA7,0x55,0x1D,0xD9,0x59,0xAC,0xB5,
1641 0xEA,0x02,0x7F,0x6C,0x5B,0x74,0x96,0x98,0x67,0x24,0xA3,0x0F,
1642 0x15,0xFC,0xA9,0x7D,0x3E,0x67,0xD1,0x70,0xF8,0x97,0xF3,0x67,
1643 0xC5,0x8C,0x88,0x44,0x08,0x02,0xC7,0x2B,
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001644 };
Remi Gacogned3a341a2015-05-29 16:26:17 +02001645 static unsigned char dh4096_g[]={
1646 0x02,
1647 };
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001648
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02001649 BIGNUM *p;
1650 BIGNUM *g;
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001651 DH *dh = DH_new();
1652 if (dh) {
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02001653 p = BN_bin2bn(dh4096_p, sizeof dh4096_p, NULL);
1654 g = BN_bin2bn(dh4096_g, sizeof dh4096_g, NULL);
Remi Gacogned3a341a2015-05-29 16:26:17 +02001655
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02001656 if (!p || !g) {
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001657 DH_free(dh);
1658 dh = NULL;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02001659 } else {
1660 DH_set0_pqg(dh, p, NULL, g);
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001661 }
1662 }
1663 return dh;
1664}
1665
1666/* Returns Diffie-Hellman parameters matching the private key length
Willy Tarreauef934602016-12-22 23:12:01 +01001667 but not exceeding global_ssl.default_dh_param */
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001668static DH *ssl_get_tmp_dh(SSL *ssl, int export, int keylen)
1669{
1670 DH *dh = NULL;
1671 EVP_PKEY *pkey = SSL_get_privatekey(ssl);
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02001672 int type;
1673
1674 type = pkey ? EVP_PKEY_base_id(pkey) : EVP_PKEY_NONE;
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001675
1676 /* The keylen supplied by OpenSSL can only be 512 or 1024.
1677 See ssl3_send_server_key_exchange() in ssl/s3_srvr.c
1678 */
1679 if (type == EVP_PKEY_RSA || type == EVP_PKEY_DSA) {
1680 keylen = EVP_PKEY_bits(pkey);
1681 }
1682
Willy Tarreauef934602016-12-22 23:12:01 +01001683 if (keylen > global_ssl.default_dh_param) {
1684 keylen = global_ssl.default_dh_param;
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001685 }
1686
Remi Gacogned3a341a2015-05-29 16:26:17 +02001687 if (keylen >= 4096) {
Remi Gacogne8de54152014-07-15 11:36:40 +02001688 dh = local_dh_4096;
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001689 }
1690 else if (keylen >= 2048) {
Remi Gacogne8de54152014-07-15 11:36:40 +02001691 dh = local_dh_2048;
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001692 }
1693 else {
Remi Gacogne8de54152014-07-15 11:36:40 +02001694 dh = local_dh_1024;
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001695 }
1696
1697 return dh;
1698}
1699
Remi Gacogne47783ef2015-05-29 15:53:22 +02001700static DH * ssl_sock_get_dh_from_file(const char *filename)
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001701{
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001702 DH *dh = NULL;
Remi Gacogne47783ef2015-05-29 15:53:22 +02001703 BIO *in = BIO_new(BIO_s_file());
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001704
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001705 if (in == NULL)
1706 goto end;
1707
Remi Gacogne47783ef2015-05-29 15:53:22 +02001708 if (BIO_read_filename(in, filename) <= 0)
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001709 goto end;
1710
Remi Gacogne47783ef2015-05-29 15:53:22 +02001711 dh = PEM_read_bio_DHparams(in, NULL, NULL, NULL);
1712
1713end:
1714 if (in)
1715 BIO_free(in);
1716
1717 return dh;
1718}
1719
1720int ssl_sock_load_global_dh_param_from_file(const char *filename)
1721{
1722 global_dh = ssl_sock_get_dh_from_file(filename);
1723
1724 if (global_dh) {
1725 return 0;
1726 }
1727
1728 return -1;
1729}
1730
1731/* Loads Diffie-Hellman parameter from a file. Returns 1 if loaded, else -1
1732 if an error occured, and 0 if parameter not found. */
1733int ssl_sock_load_dh_params(SSL_CTX *ctx, const char *file)
1734{
1735 int ret = -1;
1736 DH *dh = ssl_sock_get_dh_from_file(file);
1737
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001738 if (dh) {
1739 ret = 1;
1740 SSL_CTX_set_tmp_dh(ctx, dh);
Remi Gacogne4f902b82015-05-28 16:23:00 +02001741
1742 if (ssl_dh_ptr_index >= 0) {
1743 /* store a pointer to the DH params to avoid complaining about
1744 ssl-default-dh-param not being set for this SSL_CTX */
1745 SSL_CTX_set_ex_data(ctx, ssl_dh_ptr_index, dh);
1746 }
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001747 }
Remi Gacogne47783ef2015-05-29 15:53:22 +02001748 else if (global_dh) {
1749 SSL_CTX_set_tmp_dh(ctx, global_dh);
1750 ret = 0; /* DH params not found */
1751 }
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001752 else {
Emeric Brun41fdb3c2013-04-26 11:05:44 +02001753 /* Clear openssl global errors stack */
1754 ERR_clear_error();
1755
Willy Tarreauef934602016-12-22 23:12:01 +01001756 if (global_ssl.default_dh_param <= 1024) {
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001757 /* we are limited to DH parameter of 1024 bits anyway */
Remi Gacognec7e12632016-07-02 16:26:10 +02001758 if (local_dh_1024 == NULL)
1759 local_dh_1024 = ssl_get_dh_1024();
1760
Remi Gacogne8de54152014-07-15 11:36:40 +02001761 if (local_dh_1024 == NULL)
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001762 goto end;
Willy Tarreau6e774b42014-04-25 21:35:23 +02001763
Remi Gacogne8de54152014-07-15 11:36:40 +02001764 SSL_CTX_set_tmp_dh(ctx, local_dh_1024);
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001765 }
1766 else {
1767 SSL_CTX_set_tmp_dh_callback(ctx, ssl_get_tmp_dh);
1768 }
Willy Tarreau6e774b42014-04-25 21:35:23 +02001769
Emeric Brun41fdb3c2013-04-26 11:05:44 +02001770 ret = 0; /* DH params not found */
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001771 }
Emeric Brun644cde02012-12-14 11:21:13 +01001772
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001773end:
1774 if (dh)
1775 DH_free(dh);
1776
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001777 return ret;
1778}
1779#endif
1780
Emmanuel Hocdet98263292016-12-29 18:26:15 +01001781static int ssl_sock_add_cert_sni(SSL_CTX *ctx, struct bind_conf *s,
1782 struct ssl_bind_conf *conf, char *name, int order)
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001783{
1784 struct sni_ctx *sc;
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001785 int wild = 0, neg = 0;
Thierry FOURNIER / OZON.IO07c3d782016-10-06 10:56:48 +02001786 struct ebmb_node *node;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001787
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001788 if (*name == '!') {
1789 neg = 1;
1790 name++;
1791 }
1792 if (*name == '*') {
1793 wild = 1;
1794 name++;
1795 }
1796 /* !* filter is a nop */
1797 if (neg && wild)
1798 return order;
1799 if (*name) {
1800 int j, len;
1801 len = strlen(name);
Thierry FOURNIER / OZON.IO07c3d782016-10-06 10:56:48 +02001802 for (j = 0; j < len && j < trash.size; j++)
1803 trash.str[j] = tolower(name[j]);
1804 if (j >= trash.size)
1805 return order;
1806 trash.str[j] = 0;
1807
1808 /* Check for duplicates. */
1809 if (wild)
1810 node = ebst_lookup(&s->sni_w_ctx, trash.str);
1811 else
1812 node = ebst_lookup(&s->sni_ctx, trash.str);
1813 for (; node; node = ebmb_next_dup(node)) {
1814 sc = ebmb_entry(node, struct sni_ctx, name);
Emmanuel Hocdet98263292016-12-29 18:26:15 +01001815 if (sc->ctx == ctx && sc->conf == conf && sc->neg == neg)
Thierry FOURNIER / OZON.IO07c3d782016-10-06 10:56:48 +02001816 return order;
1817 }
1818
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001819 sc = malloc(sizeof(struct sni_ctx) + len + 1);
Thierry FOURNIER / OZON.IO7a3bd3b2016-10-06 10:35:29 +02001820 if (!sc)
1821 return order;
Thierry FOURNIER / OZON.IO07c3d782016-10-06 10:56:48 +02001822 memcpy(sc->name.key, trash.str, len + 1);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001823 sc->ctx = ctx;
Emmanuel Hocdet98263292016-12-29 18:26:15 +01001824 sc->conf = conf;
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001825 sc->order = order++;
1826 sc->neg = neg;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001827 if (wild)
1828 ebst_insert(&s->sni_w_ctx, &sc->name);
1829 else
1830 ebst_insert(&s->sni_ctx, &sc->name);
1831 }
1832 return order;
1833}
1834
yanbzhu488a4d22015-12-01 15:16:07 -05001835
1836/* The following code is used for loading multiple crt files into
1837 * SSL_CTX's based on CN/SAN
1838 */
Luca Pizzamiglio578b1692016-12-12 10:56:56 +01001839#if OPENSSL_VERSION_NUMBER >= 0x1000200fL && !defined(LIBRESSL_VERSION_NUMBER)
yanbzhu488a4d22015-12-01 15:16:07 -05001840/* This is used to preload the certifcate, private key
1841 * and Cert Chain of a file passed in via the crt
1842 * argument
1843 *
1844 * This way, we do not have to read the file multiple times
1845 */
1846struct cert_key_and_chain {
1847 X509 *cert;
1848 EVP_PKEY *key;
1849 unsigned int num_chain_certs;
1850 /* This is an array of X509 pointers */
1851 X509 **chain_certs;
1852};
1853
yanbzhu08ce6ab2015-12-02 13:01:29 -05001854#define SSL_SOCK_POSSIBLE_KT_COMBOS (1<<(SSL_SOCK_NUM_KEYTYPES))
1855
1856struct key_combo_ctx {
1857 SSL_CTX *ctx;
1858 int order;
1859};
1860
1861/* Map used for processing multiple keypairs for a single purpose
1862 *
1863 * This maps CN/SNI name to certificate type
1864 */
1865struct sni_keytype {
1866 int keytypes; /* BITMASK for keytypes */
1867 struct ebmb_node name; /* node holding the servername value */
1868};
1869
1870
yanbzhu488a4d22015-12-01 15:16:07 -05001871/* Frees the contents of a cert_key_and_chain
1872 */
1873static void ssl_sock_free_cert_key_and_chain_contents(struct cert_key_and_chain *ckch)
1874{
1875 int i;
1876
1877 if (!ckch)
1878 return;
1879
1880 /* Free the certificate and set pointer to NULL */
1881 if (ckch->cert)
1882 X509_free(ckch->cert);
1883 ckch->cert = NULL;
1884
1885 /* Free the key and set pointer to NULL */
1886 if (ckch->key)
1887 EVP_PKEY_free(ckch->key);
1888 ckch->key = NULL;
1889
1890 /* Free each certificate in the chain */
1891 for (i = 0; i < ckch->num_chain_certs; i++) {
1892 if (ckch->chain_certs[i])
1893 X509_free(ckch->chain_certs[i]);
1894 }
1895
1896 /* Free the chain obj itself and set to NULL */
1897 if (ckch->num_chain_certs > 0) {
1898 free(ckch->chain_certs);
1899 ckch->num_chain_certs = 0;
1900 ckch->chain_certs = NULL;
1901 }
1902
1903}
1904
1905/* checks if a key and cert exists in the ckch
1906 */
1907static int ssl_sock_is_ckch_valid(struct cert_key_and_chain *ckch)
1908{
1909 return (ckch->cert != NULL && ckch->key != NULL);
1910}
1911
1912
1913/* Loads the contents of a crt file (path) into a cert_key_and_chain
1914 * This allows us to carry the contents of the file without having to
1915 * read the file multiple times.
1916 *
1917 * returns:
1918 * 0 on Success
1919 * 1 on SSL Failure
1920 * 2 on file not found
1921 */
1922static int ssl_sock_load_crt_file_into_ckch(const char *path, struct cert_key_and_chain *ckch, char **err)
1923{
1924
1925 BIO *in;
1926 X509 *ca = NULL;
1927 int ret = 1;
1928
1929 ssl_sock_free_cert_key_and_chain_contents(ckch);
1930
1931 in = BIO_new(BIO_s_file());
1932 if (in == NULL)
1933 goto end;
1934
1935 if (BIO_read_filename(in, path) <= 0)
1936 goto end;
1937
yanbzhu488a4d22015-12-01 15:16:07 -05001938 /* Read Private Key */
1939 ckch->key = PEM_read_bio_PrivateKey(in, NULL, NULL, NULL);
1940 if (ckch->key == NULL) {
1941 memprintf(err, "%sunable to load private key from file '%s'.\n",
1942 err && *err ? *err : "", path);
1943 goto end;
1944 }
1945
Willy Tarreaubb137a82016-04-06 19:02:38 +02001946 /* Seek back to beginning of file */
Thierry FOURNIER / OZON.IOd44ea3f2016-10-14 00:49:21 +02001947 if (BIO_reset(in) == -1) {
1948 memprintf(err, "%san error occurred while reading the file '%s'.\n",
1949 err && *err ? *err : "", path);
1950 goto end;
1951 }
Willy Tarreaubb137a82016-04-06 19:02:38 +02001952
1953 /* Read Certificate */
1954 ckch->cert = PEM_read_bio_X509_AUX(in, NULL, NULL, NULL);
1955 if (ckch->cert == NULL) {
1956 memprintf(err, "%sunable to load certificate from file '%s'.\n",
1957 err && *err ? *err : "", path);
1958 goto end;
1959 }
1960
yanbzhu488a4d22015-12-01 15:16:07 -05001961 /* Read Certificate Chain */
1962 while ((ca = PEM_read_bio_X509(in, NULL, NULL, NULL))) {
1963 /* Grow the chain certs */
1964 ckch->num_chain_certs++;
1965 ckch->chain_certs = realloc(ckch->chain_certs, (ckch->num_chain_certs * sizeof(X509 *)));
1966
1967 /* use - 1 here since we just incremented it above */
1968 ckch->chain_certs[ckch->num_chain_certs - 1] = ca;
1969 }
1970 ret = ERR_get_error();
1971 if (ret && (ERR_GET_LIB(ret) != ERR_LIB_PEM && ERR_GET_REASON(ret) != PEM_R_NO_START_LINE)) {
1972 memprintf(err, "%sunable to load certificate chain from file '%s'.\n",
1973 err && *err ? *err : "", path);
1974 ret = 1;
1975 goto end;
1976 }
1977
1978 ret = 0;
1979
1980end:
1981
1982 ERR_clear_error();
1983 if (in)
1984 BIO_free(in);
1985
1986 /* Something went wrong in one of the reads */
1987 if (ret != 0)
1988 ssl_sock_free_cert_key_and_chain_contents(ckch);
1989
1990 return ret;
1991}
1992
1993/* Loads the info in ckch into ctx
1994 * Currently, this does not process any information about ocsp, dhparams or
1995 * sctl
1996 * Returns
1997 * 0 on success
1998 * 1 on failure
1999 */
2000static int ssl_sock_put_ckch_into_ctx(const char *path, const struct cert_key_and_chain *ckch, SSL_CTX *ctx, char **err)
2001{
2002 int i = 0;
2003
2004 if (SSL_CTX_use_PrivateKey(ctx, ckch->key) <= 0) {
2005 memprintf(err, "%sunable to load SSL private key into SSL Context '%s'.\n",
2006 err && *err ? *err : "", path);
2007 return 1;
2008 }
2009
2010 if (!SSL_CTX_use_certificate(ctx, ckch->cert)) {
2011 memprintf(err, "%sunable to load SSL certificate into SSL Context '%s'.\n",
2012 err && *err ? *err : "", path);
2013 return 1;
2014 }
2015
yanbzhu488a4d22015-12-01 15:16:07 -05002016 /* Load all certs in the ckch into the ctx_chain for the ssl_ctx */
2017 for (i = 0; i < ckch->num_chain_certs; i++) {
2018 if (!SSL_CTX_add1_chain_cert(ctx, ckch->chain_certs[i])) {
yanbzhu08ce6ab2015-12-02 13:01:29 -05002019 memprintf(err, "%sunable to load chain certificate #%d into SSL Context '%s'. Make sure you are linking against Openssl >= 1.0.2.\n",
2020 err && *err ? *err : "", (i+1), path);
yanbzhu488a4d22015-12-01 15:16:07 -05002021 return 1;
2022 }
2023 }
2024
2025 if (SSL_CTX_check_private_key(ctx) <= 0) {
2026 memprintf(err, "%sinconsistencies between private key and certificate loaded from PEM file '%s'.\n",
2027 err && *err ? *err : "", path);
2028 return 1;
2029 }
2030
2031 return 0;
2032}
2033
yanbzhu08ce6ab2015-12-02 13:01:29 -05002034
2035static void ssl_sock_populate_sni_keytypes_hplr(const char *str, struct eb_root *sni_keytypes, int key_index)
2036{
2037 struct sni_keytype *s_kt = NULL;
2038 struct ebmb_node *node;
2039 int i;
2040
2041 for (i = 0; i < trash.size; i++) {
2042 if (!str[i])
2043 break;
2044 trash.str[i] = tolower(str[i]);
2045 }
2046 trash.str[i] = 0;
2047 node = ebst_lookup(sni_keytypes, trash.str);
2048 if (!node) {
2049 /* CN not found in tree */
2050 s_kt = malloc(sizeof(struct sni_keytype) + i + 1);
2051 /* Using memcpy here instead of strncpy.
2052 * strncpy will cause sig_abrt errors under certain versions of gcc with -O2
2053 * See: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=60792
2054 */
2055 memcpy(s_kt->name.key, trash.str, i+1);
2056 s_kt->keytypes = 0;
2057 ebst_insert(sni_keytypes, &s_kt->name);
2058 } else {
2059 /* CN found in tree */
2060 s_kt = container_of(node, struct sni_keytype, name);
2061 }
2062
2063 /* Mark that this CN has the keytype of key_index via keytypes mask */
2064 s_kt->keytypes |= 1<<key_index;
2065
2066}
2067
2068
2069/* Given a path that does not exist, try to check for path.rsa, path.dsa and path.ecdsa files.
2070 * If any are found, group these files into a set of SSL_CTX*
2071 * based on shared and unique CN and SAN entries. Add these SSL_CTX* to the SNI tree.
2072 *
2073 * This will allow the user to explictly group multiple cert/keys for a single purpose
2074 *
2075 * Returns
2076 * 0 on success
2077 * 1 on failure
2078 */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01002079static int ssl_sock_load_multi_cert(const char *path, struct bind_conf *bind_conf, struct ssl_bind_conf *ssl_conf,
2080 char **sni_filter, int fcount, char **err)
yanbzhu08ce6ab2015-12-02 13:01:29 -05002081{
2082 char fp[MAXPATHLEN+1] = {0};
2083 int n = 0;
2084 int i = 0;
2085 struct cert_key_and_chain certs_and_keys[SSL_SOCK_NUM_KEYTYPES] = { {0} };
2086 struct eb_root sni_keytypes_map = { {0} };
2087 struct ebmb_node *node;
2088 struct ebmb_node *next;
2089 /* Array of SSL_CTX pointers corresponding to each possible combo
2090 * of keytypes
2091 */
2092 struct key_combo_ctx key_combos[SSL_SOCK_POSSIBLE_KT_COMBOS] = { {0} };
2093 int rv = 0;
2094 X509_NAME *xname = NULL;
2095 char *str = NULL;
2096#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
2097 STACK_OF(GENERAL_NAME) *names = NULL;
2098#endif
2099
2100 /* Load all possible certs and keys */
2101 for (n = 0; n < SSL_SOCK_NUM_KEYTYPES; n++) {
2102 struct stat buf;
2103
2104 snprintf(fp, sizeof(fp), "%s.%s", path, SSL_SOCK_KEYTYPE_NAMES[n]);
2105 if (stat(fp, &buf) == 0) {
2106 if (ssl_sock_load_crt_file_into_ckch(fp, &certs_and_keys[n], err) == 1) {
2107 rv = 1;
2108 goto end;
2109 }
2110 }
2111 }
2112
2113 /* Process each ckch and update keytypes for each CN/SAN
2114 * for example, if CN/SAN www.a.com is associated with
2115 * certs with keytype 0 and 2, then at the end of the loop,
2116 * www.a.com will have:
2117 * keyindex = 0 | 1 | 4 = 5
2118 */
2119 for (n = 0; n < SSL_SOCK_NUM_KEYTYPES; n++) {
2120
2121 if (!ssl_sock_is_ckch_valid(&certs_and_keys[n]))
2122 continue;
2123
Emmanuel Hocdetd294aea2016-05-13 11:14:06 +02002124 if (fcount) {
Willy Tarreau24b892f2016-06-20 23:01:57 +02002125 for (i = 0; i < fcount; i++)
Emmanuel Hocdetd294aea2016-05-13 11:14:06 +02002126 ssl_sock_populate_sni_keytypes_hplr(sni_filter[i], &sni_keytypes_map, n);
2127 } else {
2128 /* A lot of the following code is OpenSSL boilerplate for processing CN's and SAN's,
2129 * so the line that contains logic is marked via comments
2130 */
2131 xname = X509_get_subject_name(certs_and_keys[n].cert);
2132 i = -1;
2133 while ((i = X509_NAME_get_index_by_NID(xname, NID_commonName, i)) != -1) {
2134 X509_NAME_ENTRY *entry = X509_NAME_get_entry(xname, i);
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02002135 ASN1_STRING *value;
2136 value = X509_NAME_ENTRY_get_data(entry);
2137 if (ASN1_STRING_to_UTF8((unsigned char **)&str, value) >= 0) {
Emmanuel Hocdetd294aea2016-05-13 11:14:06 +02002138 /* Important line is here */
2139 ssl_sock_populate_sni_keytypes_hplr(str, &sni_keytypes_map, n);
yanbzhu08ce6ab2015-12-02 13:01:29 -05002140
Emmanuel Hocdetd294aea2016-05-13 11:14:06 +02002141 OPENSSL_free(str);
2142 str = NULL;
2143 }
yanbzhu08ce6ab2015-12-02 13:01:29 -05002144 }
yanbzhu08ce6ab2015-12-02 13:01:29 -05002145
Emmanuel Hocdetd294aea2016-05-13 11:14:06 +02002146 /* Do the above logic for each SAN */
yanbzhu08ce6ab2015-12-02 13:01:29 -05002147#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Emmanuel Hocdetd294aea2016-05-13 11:14:06 +02002148 names = X509_get_ext_d2i(certs_and_keys[n].cert, NID_subject_alt_name, NULL, NULL);
2149 if (names) {
2150 for (i = 0; i < sk_GENERAL_NAME_num(names); i++) {
2151 GENERAL_NAME *name = sk_GENERAL_NAME_value(names, i);
yanbzhu08ce6ab2015-12-02 13:01:29 -05002152
Emmanuel Hocdetd294aea2016-05-13 11:14:06 +02002153 if (name->type == GEN_DNS) {
2154 if (ASN1_STRING_to_UTF8((unsigned char **)&str, name->d.dNSName) >= 0) {
2155 /* Important line is here */
2156 ssl_sock_populate_sni_keytypes_hplr(str, &sni_keytypes_map, n);
yanbzhu08ce6ab2015-12-02 13:01:29 -05002157
Emmanuel Hocdetd294aea2016-05-13 11:14:06 +02002158 OPENSSL_free(str);
2159 str = NULL;
2160 }
yanbzhu08ce6ab2015-12-02 13:01:29 -05002161 }
2162 }
2163 }
2164 }
2165#endif /* SSL_CTRL_SET_TLSEXT_HOSTNAME */
2166 }
2167
2168 /* If no files found, return error */
2169 if (eb_is_empty(&sni_keytypes_map)) {
2170 memprintf(err, "%sunable to load SSL certificate file '%s' file does not exist.\n",
2171 err && *err ? *err : "", path);
2172 rv = 1;
2173 goto end;
2174 }
2175
2176 /* We now have a map of CN/SAN to keytypes that are loaded in
2177 * Iterate through the map to create the SSL_CTX's (if needed)
2178 * and add each CTX to the SNI tree
2179 *
2180 * Some math here:
2181 * There are 2^n - 1 possibile combinations, each unique
2182 * combination is denoted by the key in the map. Each key
2183 * has a value between 1 and 2^n - 1. Conveniently, the array
2184 * of SSL_CTX* is sized 2^n. So, we can simply use the i'th
2185 * entry in the array to correspond to the unique combo (key)
2186 * associated with i. This unique key combo (i) will be associated
2187 * with combos[i-1]
2188 */
2189
2190 node = ebmb_first(&sni_keytypes_map);
2191 while (node) {
2192 SSL_CTX *cur_ctx;
Bertrand Jacquin33423092016-11-13 16:37:13 +00002193 char cur_file[MAXPATHLEN+1];
yanbzhu08ce6ab2015-12-02 13:01:29 -05002194
2195 str = (char *)container_of(node, struct sni_keytype, name)->name.key;
2196 i = container_of(node, struct sni_keytype, name)->keytypes;
2197 cur_ctx = key_combos[i-1].ctx;
2198
2199 if (cur_ctx == NULL) {
2200 /* need to create SSL_CTX */
2201 cur_ctx = SSL_CTX_new(SSLv23_server_method());
2202 if (cur_ctx == NULL) {
2203 memprintf(err, "%sunable to allocate SSL context.\n",
2204 err && *err ? *err : "");
2205 rv = 1;
2206 goto end;
2207 }
2208
yanbzhube2774d2015-12-10 15:07:30 -05002209 /* Load all required certs/keys/chains/OCSPs info into SSL_CTX */
yanbzhu08ce6ab2015-12-02 13:01:29 -05002210 for (n = 0; n < SSL_SOCK_NUM_KEYTYPES; n++) {
2211 if (i & (1<<n)) {
2212 /* Key combo contains ckch[n] */
Bertrand Jacquin33423092016-11-13 16:37:13 +00002213 snprintf(cur_file, MAXPATHLEN+1, "%s.%s", path, SSL_SOCK_KEYTYPE_NAMES[n]);
2214 if (ssl_sock_put_ckch_into_ctx(cur_file, &certs_and_keys[n], cur_ctx, err) != 0) {
yanbzhu08ce6ab2015-12-02 13:01:29 -05002215 SSL_CTX_free(cur_ctx);
2216 rv = 1;
2217 goto end;
2218 }
yanbzhube2774d2015-12-10 15:07:30 -05002219
2220#if (defined SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB && !defined OPENSSL_NO_OCSP)
2221 /* Load OCSP Info into context */
Bertrand Jacquin33423092016-11-13 16:37:13 +00002222 if (ssl_sock_load_ocsp(cur_ctx, cur_file) < 0) {
yanbzhube2774d2015-12-10 15:07:30 -05002223 if (err)
2224 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 +00002225 *err ? *err : "", cur_file);
yanbzhube2774d2015-12-10 15:07:30 -05002226 SSL_CTX_free(cur_ctx);
2227 rv = 1;
2228 goto end;
2229 }
2230#endif
yanbzhu08ce6ab2015-12-02 13:01:29 -05002231 }
2232 }
2233
2234 /* Load DH params into the ctx to support DHE keys */
2235#ifndef OPENSSL_NO_DH
2236 if (ssl_dh_ptr_index >= 0)
2237 SSL_CTX_set_ex_data(cur_ctx, ssl_dh_ptr_index, NULL);
2238
2239 rv = ssl_sock_load_dh_params(cur_ctx, NULL);
2240 if (rv < 0) {
2241 if (err)
2242 memprintf(err, "%sunable to load DH parameters from file '%s'.\n",
2243 *err ? *err : "", path);
2244 rv = 1;
2245 goto end;
2246 }
2247#endif
2248
2249 /* Update key_combos */
2250 key_combos[i-1].ctx = cur_ctx;
2251 }
2252
2253 /* Update SNI Tree */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01002254 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 -05002255 node = ebmb_next(node);
2256 }
2257
2258
2259 /* Mark a default context if none exists, using the ctx that has the most shared keys */
2260 if (!bind_conf->default_ctx) {
2261 for (i = SSL_SOCK_POSSIBLE_KT_COMBOS - 1; i >= 0; i--) {
2262 if (key_combos[i].ctx) {
2263 bind_conf->default_ctx = key_combos[i].ctx;
Emmanuel Hocdet98263292016-12-29 18:26:15 +01002264 bind_conf->default_ssl_conf = ssl_conf;
yanbzhu08ce6ab2015-12-02 13:01:29 -05002265 break;
2266 }
2267 }
2268 }
2269
2270end:
2271
2272 if (names)
2273 sk_GENERAL_NAME_pop_free(names, GENERAL_NAME_free);
2274
2275 for (n = 0; n < SSL_SOCK_NUM_KEYTYPES; n++)
2276 ssl_sock_free_cert_key_and_chain_contents(&certs_and_keys[n]);
2277
2278 node = ebmb_first(&sni_keytypes_map);
2279 while (node) {
2280 next = ebmb_next(node);
2281 ebmb_delete(node);
2282 node = next;
2283 }
2284
2285 return rv;
2286}
2287#else
2288/* This is a dummy, that just logs an error and returns error */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01002289static int ssl_sock_load_multi_cert(const char *path, struct bind_conf *bind_conf, struct ssl_bind_conf *ssl_conf,
2290 char **sni_filter, int fcount, char **err)
yanbzhu08ce6ab2015-12-02 13:01:29 -05002291{
2292 memprintf(err, "%sunable to stat SSL certificate from file '%s' : %s.\n",
2293 err && *err ? *err : "", path, strerror(errno));
2294 return 1;
2295}
2296
yanbzhu488a4d22015-12-01 15:16:07 -05002297#endif /* #if OPENSSL_VERSION_NUMBER >= 0x1000200fL: Support for loading multiple certs into a single SSL_CTX */
2298
Emeric Brunfc0421f2012-09-07 17:30:07 +02002299/* Loads a certificate key and CA chain from a file. Returns 0 on error, -1 if
2300 * an early error happens and the caller must call SSL_CTX_free() by itelf.
2301 */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01002302static int ssl_sock_load_cert_chain_file(SSL_CTX *ctx, const char *file, struct bind_conf *s,
2303 struct ssl_bind_conf *ssl_conf, char **sni_filter, int fcount)
Emeric Brunfc0421f2012-09-07 17:30:07 +02002304{
2305 BIO *in;
2306 X509 *x = NULL, *ca;
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02002307 int i, err;
Emeric Brunfc0421f2012-09-07 17:30:07 +02002308 int ret = -1;
2309 int order = 0;
2310 X509_NAME *xname;
2311 char *str;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02002312 pem_password_cb *passwd_cb;
2313 void *passwd_cb_userdata;
2314
Emeric Brunfc0421f2012-09-07 17:30:07 +02002315#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
2316 STACK_OF(GENERAL_NAME) *names;
2317#endif
2318
2319 in = BIO_new(BIO_s_file());
2320 if (in == NULL)
2321 goto end;
2322
2323 if (BIO_read_filename(in, file) <= 0)
2324 goto end;
2325
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02002326
2327 passwd_cb = SSL_CTX_get_default_passwd_cb(ctx);
2328 passwd_cb_userdata = SSL_CTX_get_default_passwd_cb_userdata(ctx);
2329
2330 x = PEM_read_bio_X509_AUX(in, NULL, passwd_cb, passwd_cb_userdata);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002331 if (x == NULL)
2332 goto end;
2333
Emeric Brun50bcecc2013-04-22 13:05:23 +02002334 if (fcount) {
2335 while (fcount--)
Emmanuel Hocdet98263292016-12-29 18:26:15 +01002336 order = ssl_sock_add_cert_sni(ctx, s, ssl_conf, sni_filter[fcount], order);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002337 }
2338 else {
Emeric Brunfc0421f2012-09-07 17:30:07 +02002339#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002340 names = X509_get_ext_d2i(x, NID_subject_alt_name, NULL, NULL);
2341 if (names) {
2342 for (i = 0; i < sk_GENERAL_NAME_num(names); i++) {
2343 GENERAL_NAME *name = sk_GENERAL_NAME_value(names, i);
2344 if (name->type == GEN_DNS) {
2345 if (ASN1_STRING_to_UTF8((unsigned char **)&str, name->d.dNSName) >= 0) {
Emmanuel Hocdet98263292016-12-29 18:26:15 +01002346 order = ssl_sock_add_cert_sni(ctx, s, ssl_conf, str, order);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002347 OPENSSL_free(str);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002348 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02002349 }
2350 }
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002351 sk_GENERAL_NAME_pop_free(names, GENERAL_NAME_free);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002352 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02002353#endif /* SSL_CTRL_SET_TLSEXT_HOSTNAME */
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002354 xname = X509_get_subject_name(x);
2355 i = -1;
2356 while ((i = X509_NAME_get_index_by_NID(xname, NID_commonName, i)) != -1) {
2357 X509_NAME_ENTRY *entry = X509_NAME_get_entry(xname, i);
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02002358 ASN1_STRING *value;
2359
2360 value = X509_NAME_ENTRY_get_data(entry);
2361 if (ASN1_STRING_to_UTF8((unsigned char **)&str, value) >= 0) {
Emmanuel Hocdet98263292016-12-29 18:26:15 +01002362 order = ssl_sock_add_cert_sni(ctx, s, ssl_conf, str, order);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002363 OPENSSL_free(str);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002364 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02002365 }
2366 }
2367
2368 ret = 0; /* the caller must not free the SSL_CTX argument anymore */
2369 if (!SSL_CTX_use_certificate(ctx, x))
2370 goto end;
2371
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02002372#ifdef SSL_CTX_clear_extra_chain_certs
2373 SSL_CTX_clear_extra_chain_certs(ctx);
2374#else
Emeric Brunfc0421f2012-09-07 17:30:07 +02002375 if (ctx->extra_certs != NULL) {
2376 sk_X509_pop_free(ctx->extra_certs, X509_free);
2377 ctx->extra_certs = NULL;
2378 }
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02002379#endif
Emeric Brunfc0421f2012-09-07 17:30:07 +02002380
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02002381 while ((ca = PEM_read_bio_X509(in, NULL, passwd_cb, passwd_cb_userdata))) {
Emeric Brunfc0421f2012-09-07 17:30:07 +02002382 if (!SSL_CTX_add_extra_chain_cert(ctx, ca)) {
2383 X509_free(ca);
2384 goto end;
2385 }
2386 }
2387
2388 err = ERR_get_error();
2389 if (!err || (ERR_GET_LIB(err) == ERR_LIB_PEM && ERR_GET_REASON(err) == PEM_R_NO_START_LINE)) {
2390 /* we successfully reached the last cert in the file */
2391 ret = 1;
2392 }
2393 ERR_clear_error();
2394
2395end:
2396 if (x)
2397 X509_free(x);
2398
2399 if (in)
2400 BIO_free(in);
2401
2402 return ret;
2403}
2404
Emmanuel Hocdet98263292016-12-29 18:26:15 +01002405static int ssl_sock_load_cert_file(const char *path, struct bind_conf *bind_conf, struct ssl_bind_conf *ssl_conf,
2406 char **sni_filter, int fcount, char **err)
Emeric Brunfc0421f2012-09-07 17:30:07 +02002407{
2408 int ret;
2409 SSL_CTX *ctx;
2410
2411 ctx = SSL_CTX_new(SSLv23_server_method());
2412 if (!ctx) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02002413 memprintf(err, "%sunable to allocate SSL context for cert '%s'.\n",
2414 err && *err ? *err : "", path);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002415 return 1;
2416 }
2417
2418 if (SSL_CTX_use_PrivateKey_file(ctx, path, SSL_FILETYPE_PEM) <= 0) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02002419 memprintf(err, "%sunable to load SSL private key from PEM file '%s'.\n",
2420 err && *err ? *err : "", path);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002421 SSL_CTX_free(ctx);
2422 return 1;
2423 }
2424
Emmanuel Hocdet98263292016-12-29 18:26:15 +01002425 ret = ssl_sock_load_cert_chain_file(ctx, path, bind_conf, ssl_conf, sni_filter, fcount);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002426 if (ret <= 0) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02002427 memprintf(err, "%sunable to load SSL certificate from PEM file '%s'.\n",
2428 err && *err ? *err : "", path);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002429 if (ret < 0) /* serious error, must do that ourselves */
2430 SSL_CTX_free(ctx);
2431 return 1;
2432 }
Emeric Brun61694ab2012-10-26 13:35:33 +02002433
2434 if (SSL_CTX_check_private_key(ctx) <= 0) {
2435 memprintf(err, "%sinconsistencies between private key and certificate loaded from PEM file '%s'.\n",
2436 err && *err ? *err : "", path);
2437 return 1;
2438 }
2439
Emeric Brunfc0421f2012-09-07 17:30:07 +02002440 /* we must not free the SSL_CTX anymore below, since it's already in
2441 * the tree, so it will be discovered and cleaned in time.
2442 */
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02002443#ifndef OPENSSL_NO_DH
Remi Gacogne4f902b82015-05-28 16:23:00 +02002444 /* store a NULL pointer to indicate we have not yet loaded
2445 a custom DH param file */
2446 if (ssl_dh_ptr_index >= 0) {
2447 SSL_CTX_set_ex_data(ctx, ssl_dh_ptr_index, NULL);
2448 }
2449
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02002450 ret = ssl_sock_load_dh_params(ctx, path);
2451 if (ret < 0) {
2452 if (err)
2453 memprintf(err, "%sunable to load DH parameters from file '%s'.\n",
2454 *err ? *err : "", path);
2455 return 1;
2456 }
2457#endif
2458
Lukas Tribuse4e30f72014-12-09 16:32:51 +01002459#if (defined SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB && !defined OPENSSL_NO_OCSP)
Emeric Brun4147b2e2014-06-16 18:36:30 +02002460 ret = ssl_sock_load_ocsp(ctx, path);
2461 if (ret < 0) {
2462 if (err)
2463 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",
2464 *err ? *err : "", path);
2465 return 1;
2466 }
2467#endif
2468
Daniel Jakots54ffb912015-11-06 20:02:41 +01002469#if (OPENSSL_VERSION_NUMBER >= 0x1000200fL && !defined OPENSSL_NO_TLSEXT && !defined OPENSSL_IS_BORINGSSL && !defined LIBRESSL_VERSION_NUMBER)
Janusz Dziemidowicz2c701b52015-03-07 23:03:59 +01002470 if (sctl_ex_index >= 0) {
2471 ret = ssl_sock_load_sctl(ctx, path);
2472 if (ret < 0) {
2473 if (err)
2474 memprintf(err, "%s '%s.sctl' is present but cannot be read or parsed'.\n",
2475 *err ? *err : "", path);
2476 return 1;
2477 }
2478 }
2479#endif
2480
Emeric Brunfc0421f2012-09-07 17:30:07 +02002481#ifndef SSL_CTRL_SET_TLSEXT_HOSTNAME
Willy Tarreau2a65ff02012-09-13 17:54:29 +02002482 if (bind_conf->default_ctx) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02002483 memprintf(err, "%sthis version of openssl cannot load multiple SSL certificates.\n",
2484 err && *err ? *err : "");
Emeric Brunfc0421f2012-09-07 17:30:07 +02002485 return 1;
2486 }
2487#endif
Emmanuel Hocdet98263292016-12-29 18:26:15 +01002488 if (!bind_conf->default_ctx) {
Willy Tarreau2a65ff02012-09-13 17:54:29 +02002489 bind_conf->default_ctx = ctx;
Emmanuel Hocdet98263292016-12-29 18:26:15 +01002490 bind_conf->default_ssl_conf = ssl_conf;
2491 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02002492
2493 return 0;
2494}
2495
Willy Tarreau03209342016-12-22 17:08:28 +01002496int ssl_sock_load_cert(char *path, struct bind_conf *bind_conf, char **err)
Emeric Brunfc0421f2012-09-07 17:30:07 +02002497{
Cyril Bonté3180f7b2015-01-25 00:16:08 +01002498 struct dirent **de_list;
2499 int i, n;
Emeric Brunfc0421f2012-09-07 17:30:07 +02002500 DIR *dir;
2501 struct stat buf;
Willy Tarreauee2663b2012-12-06 11:36:59 +01002502 char *end;
2503 char fp[MAXPATHLEN+1];
Emeric Brunfc0421f2012-09-07 17:30:07 +02002504 int cfgerr = 0;
yanbzhu63ea8462015-12-09 13:35:14 -05002505#if OPENSSL_VERSION_NUMBER >= 0x1000200fL
2506 int is_bundle;
2507 int j;
2508#endif
Emeric Brunfc0421f2012-09-07 17:30:07 +02002509
yanbzhu08ce6ab2015-12-02 13:01:29 -05002510 if (stat(path, &buf) == 0) {
2511 dir = opendir(path);
2512 if (!dir)
Emmanuel Hocdet98263292016-12-29 18:26:15 +01002513 return ssl_sock_load_cert_file(path, bind_conf, NULL, NULL, 0, err);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002514
yanbzhu08ce6ab2015-12-02 13:01:29 -05002515 /* strip trailing slashes, including first one */
2516 for (end = path + strlen(path) - 1; end >= path && *end == '/'; end--)
2517 *end = 0;
Emeric Brunfc0421f2012-09-07 17:30:07 +02002518
yanbzhu08ce6ab2015-12-02 13:01:29 -05002519 n = scandir(path, &de_list, 0, alphasort);
2520 if (n < 0) {
2521 memprintf(err, "%sunable to scan directory '%s' : %s.\n",
2522 err && *err ? *err : "", path, strerror(errno));
2523 cfgerr++;
2524 }
2525 else {
2526 for (i = 0; i < n; i++) {
2527 struct dirent *de = de_list[i];
Emeric Brun2aab7222014-06-18 18:15:09 +02002528
yanbzhu08ce6ab2015-12-02 13:01:29 -05002529 end = strrchr(de->d_name, '.');
2530 if (end && (!strcmp(end, ".issuer") || !strcmp(end, ".ocsp") || !strcmp(end, ".sctl")))
2531 goto ignore_entry;
Cyril Bonté3180f7b2015-01-25 00:16:08 +01002532
yanbzhu08ce6ab2015-12-02 13:01:29 -05002533 snprintf(fp, sizeof(fp), "%s/%s", path, de->d_name);
2534 if (stat(fp, &buf) != 0) {
2535 memprintf(err, "%sunable to stat SSL certificate from file '%s' : %s.\n",
2536 err && *err ? *err : "", fp, strerror(errno));
2537 cfgerr++;
2538 goto ignore_entry;
2539 }
2540 if (!S_ISREG(buf.st_mode))
2541 goto ignore_entry;
yanbzhu63ea8462015-12-09 13:35:14 -05002542
2543#if OPENSSL_VERSION_NUMBER >= 0x1000200fL
2544 is_bundle = 0;
2545 /* Check if current entry in directory is part of a multi-cert bundle */
2546
2547 if (end) {
2548 for (j = 0; j < SSL_SOCK_NUM_KEYTYPES; j++) {
2549 if (!strcmp(end + 1, SSL_SOCK_KEYTYPE_NAMES[j])) {
2550 is_bundle = 1;
2551 break;
2552 }
2553 }
2554
2555 if (is_bundle) {
2556 char dp[MAXPATHLEN+1] = {0}; /* this will be the filename w/o the keytype */
2557 int dp_len;
2558
2559 dp_len = end - de->d_name;
2560 snprintf(dp, dp_len + 1, "%s", de->d_name);
2561
2562 /* increment i and free de until we get to a non-bundle cert
2563 * Note here that we look at de_list[i + 1] before freeing de
2564 * this is important since ignore_entry will free de
2565 */
2566 while (i + 1 < n && !strncmp(de_list[i + 1]->d_name, dp, dp_len)) {
2567 free(de);
2568 i++;
2569 de = de_list[i];
2570 }
2571
2572 snprintf(fp, sizeof(fp), "%s/%s", path, dp);
Emmanuel Hocdet98263292016-12-29 18:26:15 +01002573 ssl_sock_load_multi_cert(fp, bind_conf, NULL, NULL, 0, err);
yanbzhu63ea8462015-12-09 13:35:14 -05002574
2575 /* Successfully processed the bundle */
2576 goto ignore_entry;
2577 }
2578 }
2579
2580#endif
Emmanuel Hocdet98263292016-12-29 18:26:15 +01002581 cfgerr += ssl_sock_load_cert_file(fp, bind_conf, NULL, NULL, 0, err);
yanbzhu08ce6ab2015-12-02 13:01:29 -05002582ignore_entry:
2583 free(de);
Cyril Bonté3180f7b2015-01-25 00:16:08 +01002584 }
yanbzhu08ce6ab2015-12-02 13:01:29 -05002585 free(de_list);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002586 }
yanbzhu08ce6ab2015-12-02 13:01:29 -05002587 closedir(dir);
2588 return cfgerr;
Emeric Brunfc0421f2012-09-07 17:30:07 +02002589 }
yanbzhu08ce6ab2015-12-02 13:01:29 -05002590
Emmanuel Hocdet98263292016-12-29 18:26:15 +01002591 cfgerr = ssl_sock_load_multi_cert(path, bind_conf, NULL, NULL, 0, err);
yanbzhu08ce6ab2015-12-02 13:01:29 -05002592
Emeric Brunfc0421f2012-09-07 17:30:07 +02002593 return cfgerr;
2594}
2595
Thierry Fournier383085f2013-01-24 14:15:43 +01002596/* Make sure openssl opens /dev/urandom before the chroot. The work is only
2597 * done once. Zero is returned if the operation fails. No error is returned
2598 * if the random is said as not implemented, because we expect that openssl
2599 * will use another method once needed.
2600 */
2601static int ssl_initialize_random()
2602{
2603 unsigned char random;
2604 static int random_initialized = 0;
2605
2606 if (!random_initialized && RAND_bytes(&random, 1) != 0)
2607 random_initialized = 1;
2608
2609 return random_initialized;
2610}
2611
Emmanuel Hocdet98263292016-12-29 18:26:15 +01002612/* release ssl bind conf */
2613void ssl_sock_free_ssl_conf(struct ssl_bind_conf *conf)
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002614{
Emmanuel Hocdet98263292016-12-29 18:26:15 +01002615 if (conf) {
2616#ifdef OPENSSL_NPN_NEGOTIATED
2617 free(conf->npn_str);
2618 conf->npn_str = NULL;
2619#endif
2620#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
2621 free(conf->alpn_str);
2622 conf->alpn_str = NULL;
2623#endif
2624 free(conf->ca_file);
2625 conf->ca_file = NULL;
2626 free(conf->crl_file);
2627 conf->crl_file = NULL;
2628 free(conf->ciphers);
2629 conf->ciphers = NULL;
Emmanuel Hocdete7f2b732017-01-09 16:15:54 +01002630 free(conf->curves);
2631 conf->curves = NULL;
Emmanuel Hocdet98263292016-12-29 18:26:15 +01002632 free(conf->ecdhe);
2633 conf->ecdhe = NULL;
2634 }
2635}
2636
2637int ssl_sock_load_cert_list_file(char *file, struct bind_conf *bind_conf, struct proxy *curproxy, char **err)
2638{
2639 char thisline[CRT_LINESIZE];
2640 char path[MAXPATHLEN+1];
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002641 FILE *f;
yanbzhu1b04e5b2015-12-02 13:54:14 -05002642 struct stat buf;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002643 int linenum = 0;
2644 int cfgerr = 0;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002645
Willy Tarreauad1731d2013-04-02 17:35:58 +02002646 if ((f = fopen(file, "r")) == NULL) {
2647 memprintf(err, "cannot open file '%s' : %s", file, strerror(errno));
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002648 return 1;
Willy Tarreauad1731d2013-04-02 17:35:58 +02002649 }
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002650
2651 while (fgets(thisline, sizeof(thisline), f) != NULL) {
Emmanuel Hocdet98263292016-12-29 18:26:15 +01002652 int arg, newarg, cur_arg, i, ssl_b = 0, ssl_e = 0;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002653 char *end;
Emmanuel Hocdet98263292016-12-29 18:26:15 +01002654 char *args[MAX_CRT_ARGS + 1];
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002655 char *line = thisline;
Emmanuel Hocdet98263292016-12-29 18:26:15 +01002656 char *crt_path;
2657 struct ssl_bind_conf *ssl_conf = NULL;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002658
2659 linenum++;
2660 end = line + strlen(line);
2661 if (end-line == sizeof(thisline)-1 && *(end-1) != '\n') {
2662 /* Check if we reached the limit and the last char is not \n.
2663 * Watch out for the last line without the terminating '\n'!
2664 */
Willy Tarreauad1731d2013-04-02 17:35:58 +02002665 memprintf(err, "line %d too long in file '%s', limit is %d characters",
2666 linenum, file, (int)sizeof(thisline)-1);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002667 cfgerr = 1;
Willy Tarreauad1731d2013-04-02 17:35:58 +02002668 break;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002669 }
2670
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002671 arg = 0;
Emeric Brun50bcecc2013-04-22 13:05:23 +02002672 newarg = 1;
2673 while (*line) {
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002674 if (*line == '#' || *line == '\n' || *line == '\r') {
2675 /* end of string, end of loop */
2676 *line = 0;
2677 break;
Emmanuel Hocdet98263292016-12-29 18:26:15 +01002678 } else if (isspace(*line)) {
Emeric Brun50bcecc2013-04-22 13:05:23 +02002679 newarg = 1;
2680 *line = 0;
Emmanuel Hocdet98263292016-12-29 18:26:15 +01002681 } else if (*line == '[') {
2682 if (ssl_b) {
2683 memprintf(err, "too many '[' on line %d in file '%s'.", linenum, file);
2684 cfgerr = 1;
2685 break;
2686 }
2687 if (!arg) {
2688 memprintf(err, "file must start with a cert on line %d in file '%s'", linenum, file);
2689 cfgerr = 1;
2690 break;
2691 }
2692 ssl_b = arg;
2693 newarg = 1;
2694 *line = 0;
2695 } else if (*line == ']') {
2696 if (ssl_e) {
2697 memprintf(err, "too many ']' on line %d in file '%s'.", linenum, file);
Emeric Brun50bcecc2013-04-22 13:05:23 +02002698 cfgerr = 1;
2699 break;
2700 }
Emmanuel Hocdet98263292016-12-29 18:26:15 +01002701 if (!ssl_b) {
2702 memprintf(err, "missing '[' in line %d in file '%s'.", linenum, file);
2703 cfgerr = 1;
2704 break;
2705 }
2706 ssl_e = arg;
2707 newarg = 1;
2708 *line = 0;
2709 } else if (newarg) {
2710 if (arg == MAX_CRT_ARGS) {
2711 memprintf(err, "too many args on line %d in file '%s'.", linenum, file);
2712 cfgerr = 1;
2713 break;
2714 }
Emeric Brun50bcecc2013-04-22 13:05:23 +02002715 newarg = 0;
2716 args[arg++] = line;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002717 }
Emeric Brun50bcecc2013-04-22 13:05:23 +02002718 line++;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002719 }
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02002720 if (cfgerr)
2721 break;
Emmanuel Hocdet98263292016-12-29 18:26:15 +01002722 args[arg++] = line;
Willy Tarreauad1731d2013-04-02 17:35:58 +02002723
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002724 /* empty line */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01002725 if (!*args[0])
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002726 continue;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002727
Emmanuel Hocdet98263292016-12-29 18:26:15 +01002728 crt_path = args[0];
2729 if (*crt_path != '/' && global_ssl.crt_base) {
2730 if ((strlen(global_ssl.crt_base) + 1 + strlen(crt_path)) > MAXPATHLEN) {
2731 memprintf(err, "'%s' : path too long on line %d in file '%s'",
2732 crt_path, linenum, file);
2733 cfgerr = 1;
2734 break;
2735 }
2736 snprintf(path, sizeof(path), "%s/%s", global_ssl.crt_base, crt_path);
2737 crt_path = path;
2738 }
2739
2740 ssl_conf = calloc(1, sizeof *ssl_conf);
2741 cur_arg = ssl_b ? ssl_b : 1;
2742 while (cur_arg < ssl_e) {
2743 newarg = 0;
2744 for (i = 0; ssl_bind_kws[i].kw != NULL; i++) {
2745 if (strcmp(ssl_bind_kws[i].kw, args[cur_arg]) == 0) {
2746 newarg = 1;
2747 cfgerr = ssl_bind_kws[i].parse(args, cur_arg, curproxy, ssl_conf, err);
2748 if (cur_arg + 1 + ssl_bind_kws[i].skip > ssl_e) {
2749 memprintf(err, "ssl args out of '[]' for %s on line %d in file '%s'",
2750 args[cur_arg], linenum, file);
2751 cfgerr = 1;
2752 }
2753 cur_arg += 1 + ssl_bind_kws[i].skip;
2754 break;
2755 }
2756 }
2757 if (!cfgerr && !newarg) {
2758 memprintf(err, "unknown ssl keyword %s on line %d in file '%s'.",
2759 args[cur_arg], linenum, file);
2760 cfgerr = 1;
2761 break;
2762 }
2763 }
2764 if (cfgerr) {
2765 ssl_sock_free_ssl_conf(ssl_conf);
2766 free(ssl_conf);
2767 ssl_conf = NULL;
2768 break;
2769 }
2770
2771 if (stat(crt_path, &buf) == 0) {
2772 cfgerr = ssl_sock_load_cert_file(crt_path, bind_conf, ssl_conf,
2773 &args[cur_arg], arg - cur_arg - 1, err);
yanbzhu1b04e5b2015-12-02 13:54:14 -05002774 } else {
Emmanuel Hocdet98263292016-12-29 18:26:15 +01002775 cfgerr = ssl_sock_load_multi_cert(crt_path, bind_conf, ssl_conf,
2776 &args[cur_arg], arg - cur_arg - 1, err);
yanbzhu1b04e5b2015-12-02 13:54:14 -05002777 }
2778
Willy Tarreauad1731d2013-04-02 17:35:58 +02002779 if (cfgerr) {
2780 memprintf(err, "error processing line %d in file '%s' : %s", linenum, file, *err);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002781 break;
Willy Tarreauad1731d2013-04-02 17:35:58 +02002782 }
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002783 }
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002784 fclose(f);
2785 return cfgerr;
2786}
2787
Emeric Brunfc0421f2012-09-07 17:30:07 +02002788#ifndef SSL_OP_CIPHER_SERVER_PREFERENCE /* needs OpenSSL >= 0.9.7 */
2789#define SSL_OP_CIPHER_SERVER_PREFERENCE 0
2790#endif
2791
2792#ifndef SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION /* needs OpenSSL >= 0.9.7 */
2793#define SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION 0
Willy Tarreau7d588ee2012-11-26 18:47:31 +01002794#define SSL_renegotiate_pending(arg) 0
Emeric Brunfc0421f2012-09-07 17:30:07 +02002795#endif
Emeric Brun2b58d042012-09-20 17:10:03 +02002796#ifndef SSL_OP_SINGLE_ECDH_USE /* needs OpenSSL >= 0.9.8 */
2797#define SSL_OP_SINGLE_ECDH_USE 0
2798#endif
Emeric Brun2d0c4822012-10-02 13:45:20 +02002799#ifndef SSL_OP_NO_TICKET /* needs OpenSSL >= 0.9.8 */
2800#define SSL_OP_NO_TICKET 0
2801#endif
Emeric Brunfc0421f2012-09-07 17:30:07 +02002802#ifndef SSL_OP_NO_COMPRESSION /* needs OpenSSL >= 0.9.9 */
2803#define SSL_OP_NO_COMPRESSION 0
2804#endif
Emeric Brunc0ff4922012-09-28 19:37:02 +02002805#ifndef SSL_OP_NO_TLSv1_1 /* needs OpenSSL >= 1.0.1 */
2806#define SSL_OP_NO_TLSv1_1 0
2807#endif
2808#ifndef SSL_OP_NO_TLSv1_2 /* needs OpenSSL >= 1.0.1 */
2809#define SSL_OP_NO_TLSv1_2 0
2810#endif
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02002811#ifndef SSL_OP_SINGLE_DH_USE /* needs OpenSSL >= 0.9.6 */
2812#define SSL_OP_SINGLE_DH_USE 0
2813#endif
Emeric Brun2b58d042012-09-20 17:10:03 +02002814#ifndef SSL_OP_SINGLE_ECDH_USE /* needs OpenSSL >= 1.0.0 */
2815#define SSL_OP_SINGLE_ECDH_USE 0
2816#endif
Emeric Brunfc0421f2012-09-07 17:30:07 +02002817#ifndef SSL_MODE_RELEASE_BUFFERS /* needs OpenSSL >= 1.0.0 */
2818#define SSL_MODE_RELEASE_BUFFERS 0
2819#endif
Willy Tarreau396a1862014-11-13 14:06:52 +01002820#ifndef SSL_MODE_SMALL_BUFFERS /* needs small_records.patch */
2821#define SSL_MODE_SMALL_BUFFERS 0
2822#endif
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002823
Emmanuel Hocdet98263292016-12-29 18:26:15 +01002824int 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 +02002825{
Willy Tarreau03209342016-12-22 17:08:28 +01002826 struct proxy *curproxy = bind_conf->frontend;
Emeric Brunfc0421f2012-09-07 17:30:07 +02002827 int cfgerr = 0;
Emeric Brun850efd52014-01-29 12:24:34 +01002828 int verify = SSL_VERIFY_NONE;
Remi Gacogneaf5c3da2014-05-19 10:29:58 +02002829 long ssloptions =
Emeric Brunfc0421f2012-09-07 17:30:07 +02002830 SSL_OP_ALL | /* all known workarounds for bugs */
2831 SSL_OP_NO_SSLv2 |
2832 SSL_OP_NO_COMPRESSION |
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02002833 SSL_OP_SINGLE_DH_USE |
Emeric Brun2b58d042012-09-20 17:10:03 +02002834 SSL_OP_SINGLE_ECDH_USE |
Emeric Brun3c4bc6e2012-10-04 18:44:19 +02002835 SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION |
2836 SSL_OP_CIPHER_SERVER_PREFERENCE;
Remi Gacogneaf5c3da2014-05-19 10:29:58 +02002837 long sslmode =
Emeric Brunfc0421f2012-09-07 17:30:07 +02002838 SSL_MODE_ENABLE_PARTIAL_WRITE |
2839 SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER |
Willy Tarreau396a1862014-11-13 14:06:52 +01002840 SSL_MODE_RELEASE_BUFFERS |
2841 SSL_MODE_SMALL_BUFFERS;
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002842 STACK_OF(SSL_CIPHER) * ciphers = NULL;
Willy Tarreaua616ba62014-10-26 06:49:19 +01002843 SSL_CIPHER * cipher = NULL;
Remi Gacognec1eab8c2014-06-12 18:20:11 +02002844 char cipher_description[128];
2845 /* The description of ciphers using an Ephemeral Diffie Hellman key exchange
2846 contains " Kx=DH " or " Kx=DH(". Beware of " Kx=DH/",
2847 which is not ephemeral DH. */
2848 const char dhe_description[] = " Kx=DH ";
2849 const char dhe_export_description[] = " Kx=DH(";
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002850 int idx = 0;
2851 int dhe_found = 0;
Remi Gacogne23d5d372014-10-10 17:04:26 +02002852 SSL *ssl = NULL;
Emmanuel Hocdet98263292016-12-29 18:26:15 +01002853 struct ssl_bind_conf *ssl_conf_cur;
2854 int conf_ssl_options = bind_conf->ssl_conf.ssl_options | (ssl_conf ? ssl_conf->ssl_options : 0);
2855 const char *conf_ciphers;
Emmanuel Hocdete7f2b732017-01-09 16:15:54 +01002856 const char *conf_curves = NULL;
Emeric Brunfc0421f2012-09-07 17:30:07 +02002857
Thierry Fournier383085f2013-01-24 14:15:43 +01002858 /* Make sure openssl opens /dev/urandom before the chroot */
2859 if (!ssl_initialize_random()) {
2860 Alert("OpenSSL random data generator initialization failed.\n");
2861 cfgerr++;
2862 }
2863
Emmanuel Hocdet98263292016-12-29 18:26:15 +01002864 if (conf_ssl_options & BC_SSL_O_NO_SSLV3)
Emeric Brunfc0421f2012-09-07 17:30:07 +02002865 ssloptions |= SSL_OP_NO_SSLv3;
Emmanuel Hocdet98263292016-12-29 18:26:15 +01002866 if (conf_ssl_options & BC_SSL_O_NO_TLSV10)
Emeric Brunfc0421f2012-09-07 17:30:07 +02002867 ssloptions |= SSL_OP_NO_TLSv1;
Emmanuel Hocdet98263292016-12-29 18:26:15 +01002868 if (conf_ssl_options & BC_SSL_O_NO_TLSV11)
Emeric Brunc0ff4922012-09-28 19:37:02 +02002869 ssloptions |= SSL_OP_NO_TLSv1_1;
Emmanuel Hocdet98263292016-12-29 18:26:15 +01002870 if (conf_ssl_options & BC_SSL_O_NO_TLSV12)
Emeric Brunc0ff4922012-09-28 19:37:02 +02002871 ssloptions |= SSL_OP_NO_TLSv1_2;
Emmanuel Hocdet98263292016-12-29 18:26:15 +01002872 if (conf_ssl_options & BC_SSL_O_NO_TLS_TICKETS)
Emeric Brun2d0c4822012-10-02 13:45:20 +02002873 ssloptions |= SSL_OP_NO_TICKET;
Emmanuel Hocdet98263292016-12-29 18:26:15 +01002874 if (conf_ssl_options & BC_SSL_O_USE_SSLV3) {
Jérémie Courrèges-Anglas17c3f622015-07-25 16:50:52 -06002875#ifndef OPENSSL_NO_SSL3
Emeric Brun2cb7ae52012-10-05 14:14:21 +02002876 SSL_CTX_set_ssl_version(ctx, SSLv3_server_method());
Jérémie Courrèges-Anglas17c3f622015-07-25 16:50:52 -06002877#else
2878 Alert("SSLv3 support requested but unavailable.\n");
2879 cfgerr++;
2880#endif
2881 }
Emmanuel Hocdet98263292016-12-29 18:26:15 +01002882 if (conf_ssl_options & BC_SSL_O_USE_TLSV10)
Emeric Brun2cb7ae52012-10-05 14:14:21 +02002883 SSL_CTX_set_ssl_version(ctx, TLSv1_server_method());
2884#if SSL_OP_NO_TLSv1_1
Emmanuel Hocdet98263292016-12-29 18:26:15 +01002885 if (conf_ssl_options & BC_SSL_O_USE_TLSV11)
Emeric Brun2cb7ae52012-10-05 14:14:21 +02002886 SSL_CTX_set_ssl_version(ctx, TLSv1_1_server_method());
2887#endif
2888#if SSL_OP_NO_TLSv1_2
Emmanuel Hocdet98263292016-12-29 18:26:15 +01002889 if (conf_ssl_options & BC_SSL_O_USE_TLSV12)
Emeric Brun2cb7ae52012-10-05 14:14:21 +02002890 SSL_CTX_set_ssl_version(ctx, TLSv1_2_server_method());
2891#endif
Emeric Brunfc0421f2012-09-07 17:30:07 +02002892
2893 SSL_CTX_set_options(ctx, ssloptions);
2894 SSL_CTX_set_mode(ctx, sslmode);
Emmanuel Hocdet98263292016-12-29 18:26:15 +01002895 switch ((ssl_conf && ssl_conf->verify) ? ssl_conf->verify : bind_conf->ssl_conf.verify) {
Emeric Brun850efd52014-01-29 12:24:34 +01002896 case SSL_SOCK_VERIFY_NONE:
2897 verify = SSL_VERIFY_NONE;
2898 break;
2899 case SSL_SOCK_VERIFY_OPTIONAL:
2900 verify = SSL_VERIFY_PEER;
2901 break;
2902 case SSL_SOCK_VERIFY_REQUIRED:
2903 verify = SSL_VERIFY_PEER|SSL_VERIFY_FAIL_IF_NO_PEER_CERT;
2904 break;
2905 }
2906 SSL_CTX_set_verify(ctx, verify, ssl_sock_bind_verifycbk);
2907 if (verify & SSL_VERIFY_PEER) {
Emmanuel Hocdet98263292016-12-29 18:26:15 +01002908 char *ca_file = (ssl_conf && ssl_conf->ca_file) ? ssl_conf->ca_file : bind_conf->ssl_conf.ca_file;
2909 char *crl_file = (ssl_conf && ssl_conf->crl_file) ? ssl_conf->crl_file : bind_conf->ssl_conf.crl_file;
2910 if (ca_file) {
Emeric Brund94b3fe2012-09-20 18:23:56 +02002911 /* load CAfile to verify */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01002912 if (!SSL_CTX_load_verify_locations(ctx, ca_file, NULL)) {
Emeric Brund94b3fe2012-09-20 18:23:56 +02002913 Alert("Proxy '%s': unable to load CA file '%s' for bind '%s' at [%s:%d].\n",
Emmanuel Hocdet98263292016-12-29 18:26:15 +01002914 curproxy->id, ca_file, bind_conf->arg, bind_conf->file, bind_conf->line);
Emeric Brund94b3fe2012-09-20 18:23:56 +02002915 cfgerr++;
2916 }
2917 /* set CA names fo client cert request, function returns void */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01002918 SSL_CTX_set_client_CA_list(ctx, SSL_load_client_CA_file(ca_file));
Emeric Brund94b3fe2012-09-20 18:23:56 +02002919 }
Emeric Brun850efd52014-01-29 12:24:34 +01002920 else {
2921 Alert("Proxy '%s': verify is enabled but no CA file specified for bind '%s' at [%s:%d].\n",
2922 curproxy->id, bind_conf->arg, bind_conf->file, bind_conf->line);
2923 cfgerr++;
2924 }
Emeric Brun051cdab2012-10-02 19:25:50 +02002925#ifdef X509_V_FLAG_CRL_CHECK
Emmanuel Hocdet98263292016-12-29 18:26:15 +01002926 if (crl_file) {
Emeric Brund94b3fe2012-09-20 18:23:56 +02002927 X509_STORE *store = SSL_CTX_get_cert_store(ctx);
2928
Emmanuel Hocdet98263292016-12-29 18:26:15 +01002929 if (!store || !X509_STORE_load_locations(store, crl_file, NULL)) {
Emeric Brund94b3fe2012-09-20 18:23:56 +02002930 Alert("Proxy '%s': unable to configure CRL file '%s' for bind '%s' at [%s:%d].\n",
Emmanuel Hocdet98263292016-12-29 18:26:15 +01002931 curproxy->id, crl_file, bind_conf->arg, bind_conf->file, bind_conf->line);
Emeric Brund94b3fe2012-09-20 18:23:56 +02002932 cfgerr++;
2933 }
Emeric Brun561e5742012-10-02 15:20:55 +02002934 else {
2935 X509_STORE_set_flags(store, X509_V_FLAG_CRL_CHECK|X509_V_FLAG_CRL_CHECK_ALL);
2936 }
Emeric Brund94b3fe2012-09-20 18:23:56 +02002937 }
Emeric Brun051cdab2012-10-02 19:25:50 +02002938#endif
Emeric Brun644cde02012-12-14 11:21:13 +01002939 ERR_clear_error();
Emeric Brund94b3fe2012-09-20 18:23:56 +02002940 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02002941
Nenad Merdanovic05552d42015-02-27 19:56:49 +01002942#if (defined SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB && TLS_TICKETS_NO > 0)
Nenad Merdanovic146defa2015-05-09 08:46:00 +02002943 if(bind_conf->keys_ref) {
Nenad Merdanovic05552d42015-02-27 19:56:49 +01002944 if (!SSL_CTX_set_tlsext_ticket_key_cb(ctx, ssl_tlsext_ticket_key_cb)) {
2945 Alert("Proxy '%s': unable to set callback for TLS ticket validation for bind '%s' at [%s:%d].\n",
2946 curproxy->id, bind_conf->arg, bind_conf->file, bind_conf->line);
2947 cfgerr++;
2948 }
2949 }
2950#endif
2951
Willy Tarreauef934602016-12-22 23:12:01 +01002952 if (global_ssl.life_time)
2953 SSL_CTX_set_timeout(ctx, global_ssl.life_time);
Emeric Brun4f65bff2012-11-16 15:11:00 +01002954
Emeric Brunfc0421f2012-09-07 17:30:07 +02002955 shared_context_set_cache(ctx);
Emmanuel Hocdet98263292016-12-29 18:26:15 +01002956 conf_ciphers = (ssl_conf && ssl_conf->ciphers) ? ssl_conf->ciphers : bind_conf->ssl_conf.ciphers;
2957 if (conf_ciphers &&
2958 !SSL_CTX_set_cipher_list(ctx, conf_ciphers)) {
Emeric Brunfc0421f2012-09-07 17:30:07 +02002959 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 +01002960 curproxy->id, conf_ciphers, bind_conf->arg, bind_conf->file, bind_conf->line);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002961 cfgerr++;
2962 }
2963
Remi Gacogne47783ef2015-05-29 15:53:22 +02002964 /* If tune.ssl.default-dh-param has not been set,
2965 neither has ssl-default-dh-file and no static DH
2966 params were in the certificate file. */
Willy Tarreauef934602016-12-22 23:12:01 +01002967 if (global_ssl.default_dh_param == 0 &&
Remi Gacogne47783ef2015-05-29 15:53:22 +02002968 global_dh == NULL &&
Remi Gacogne4f902b82015-05-28 16:23:00 +02002969 (ssl_dh_ptr_index == -1 ||
2970 SSL_CTX_get_ex_data(ctx, ssl_dh_ptr_index) == NULL)) {
Lukas Tribus90132722014-08-18 00:56:33 +02002971
Remi Gacogne23d5d372014-10-10 17:04:26 +02002972 ssl = SSL_new(ctx);
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002973
Remi Gacogne23d5d372014-10-10 17:04:26 +02002974 if (ssl) {
2975 ciphers = SSL_get_ciphers(ssl);
2976
2977 if (ciphers) {
2978 for (idx = 0; idx < sk_SSL_CIPHER_num(ciphers); idx++) {
2979 cipher = sk_SSL_CIPHER_value(ciphers, idx);
2980 if (SSL_CIPHER_description(cipher, cipher_description, sizeof (cipher_description)) == cipher_description) {
2981 if (strstr(cipher_description, dhe_description) != NULL ||
2982 strstr(cipher_description, dhe_export_description) != NULL) {
2983 dhe_found = 1;
2984 break;
2985 }
Remi Gacognec1eab8c2014-06-12 18:20:11 +02002986 }
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002987 }
2988 }
Remi Gacogne23d5d372014-10-10 17:04:26 +02002989 SSL_free(ssl);
2990 ssl = NULL;
Lukas Tribus90132722014-08-18 00:56:33 +02002991 }
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002992
Lukas Tribus90132722014-08-18 00:56:33 +02002993 if (dhe_found) {
2994 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 +02002995 }
2996
Willy Tarreauef934602016-12-22 23:12:01 +01002997 global_ssl.default_dh_param = 1024;
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002998 }
Remi Gacogne8de54152014-07-15 11:36:40 +02002999
3000#ifndef OPENSSL_NO_DH
Willy Tarreauef934602016-12-22 23:12:01 +01003001 if (global_ssl.default_dh_param >= 1024) {
Remi Gacogne8de54152014-07-15 11:36:40 +02003002 if (local_dh_1024 == NULL) {
3003 local_dh_1024 = ssl_get_dh_1024();
3004 }
Willy Tarreauef934602016-12-22 23:12:01 +01003005 if (global_ssl.default_dh_param >= 2048) {
Remi Gacogne8de54152014-07-15 11:36:40 +02003006 if (local_dh_2048 == NULL) {
3007 local_dh_2048 = ssl_get_dh_2048();
3008 }
Willy Tarreauef934602016-12-22 23:12:01 +01003009 if (global_ssl.default_dh_param >= 4096) {
Remi Gacogne8de54152014-07-15 11:36:40 +02003010 if (local_dh_4096 == NULL) {
3011 local_dh_4096 = ssl_get_dh_4096();
3012 }
Remi Gacogne8de54152014-07-15 11:36:40 +02003013 }
3014 }
3015 }
3016#endif /* OPENSSL_NO_DH */
Remi Gacognef46cd6e2014-06-12 14:58:40 +02003017
Emeric Brunfc0421f2012-09-07 17:30:07 +02003018 SSL_CTX_set_info_callback(ctx, ssl_sock_infocbk);
Willy Tarreau5cbe4ef2014-05-08 22:45:11 +02003019#if OPENSSL_VERSION_NUMBER >= 0x00907000L
Emeric Brun29f037d2014-04-25 19:05:36 +02003020 SSL_CTX_set_msg_callback(ctx, ssl_sock_msgcbk);
Willy Tarreau5cbe4ef2014-05-08 22:45:11 +02003021#endif
Emeric Brun29f037d2014-04-25 19:05:36 +02003022
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02003023#ifdef OPENSSL_NPN_NEGOTIATED
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003024 ssl_conf_cur = NULL;
3025 if (ssl_conf && ssl_conf->npn_str)
3026 ssl_conf_cur = ssl_conf;
3027 else if (bind_conf->ssl_conf.npn_str)
3028 ssl_conf_cur = &bind_conf->ssl_conf;
3029 if (ssl_conf_cur)
3030 SSL_CTX_set_next_protos_advertised_cb(ctx, ssl_sock_advertise_npn_protos, ssl_conf_cur);
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02003031#endif
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01003032#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003033 ssl_conf_cur = NULL;
3034 if (ssl_conf && ssl_conf->alpn_str)
3035 ssl_conf_cur = ssl_conf;
3036 else if (bind_conf->ssl_conf.alpn_str)
3037 ssl_conf_cur = &bind_conf->ssl_conf;
3038 if (ssl_conf_cur)
3039 SSL_CTX_set_alpn_select_cb(ctx, ssl_sock_advertise_alpn_protos, ssl_conf_cur);
Willy Tarreauab861d32013-04-02 02:30:41 +02003040#endif
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02003041
Emeric Brunfc0421f2012-09-07 17:30:07 +02003042#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
3043 SSL_CTX_set_tlsext_servername_callback(ctx, ssl_sock_switchctx_cbk);
Willy Tarreau2a65ff02012-09-13 17:54:29 +02003044 SSL_CTX_set_tlsext_servername_arg(ctx, bind_conf);
Emeric Brunfc0421f2012-09-07 17:30:07 +02003045#endif
Emmanuel Hocdete7f2b732017-01-09 16:15:54 +01003046#if OPENSSL_VERSION_NUMBER >= 0x1000200fL
3047 conf_curves = (ssl_conf && ssl_conf->curves) ? ssl_conf->curves : bind_conf->ssl_conf.curves;
3048 if (conf_curves) {
3049 if (!SSL_CTX_set1_curves_list(ctx, conf_curves)) {
3050 Alert("Proxy '%s': unable to set SSL curves list to '%s' for bind '%s' at [%s:%d].\n",
3051 curproxy->id, conf_curves, bind_conf->arg, bind_conf->file, bind_conf->line);
3052 cfgerr++;
3053 }
3054#ifndef OPENSSL_IS_BORINGSSL
3055 else
3056 SSL_CTX_set_ecdh_auto(ctx, 1);
3057#endif
3058 }
3059#endif
Emeric Brun2b58d042012-09-20 17:10:03 +02003060#if defined(SSL_CTX_set_tmp_ecdh) && !defined(OPENSSL_NO_ECDH)
Emmanuel Hocdete7f2b732017-01-09 16:15:54 +01003061 if (!conf_curves) {
Emeric Brun2b58d042012-09-20 17:10:03 +02003062 int i;
3063 EC_KEY *ecdh;
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003064 const char *ecdhe = (ssl_conf && ssl_conf->ecdhe) ? ssl_conf->ecdhe :
3065 (bind_conf->ssl_conf.ecdhe ? bind_conf->ssl_conf.ecdhe : ECDHE_DEFAULT_CURVE);
Emeric Brun2b58d042012-09-20 17:10:03 +02003066
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003067 i = OBJ_sn2nid(ecdhe);
Emeric Brun2b58d042012-09-20 17:10:03 +02003068 if (!i || ((ecdh = EC_KEY_new_by_curve_name(i)) == NULL)) {
3069 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 +01003070 curproxy->id, ecdhe, bind_conf->arg, bind_conf->file, bind_conf->line);
Emeric Brun2b58d042012-09-20 17:10:03 +02003071 cfgerr++;
3072 }
3073 else {
3074 SSL_CTX_set_tmp_ecdh(ctx, ecdh);
3075 EC_KEY_free(ecdh);
3076 }
3077 }
3078#endif
3079
Emeric Brunfc0421f2012-09-07 17:30:07 +02003080 return cfgerr;
3081}
3082
Evan Broderbe554312013-06-27 00:05:25 -07003083static int ssl_sock_srv_hostcheck(const char *pattern, const char *hostname)
3084{
3085 const char *pattern_wildcard, *pattern_left_label_end, *hostname_left_label_end;
3086 size_t prefixlen, suffixlen;
3087
3088 /* Trivial case */
3089 if (strcmp(pattern, hostname) == 0)
3090 return 1;
3091
Evan Broderbe554312013-06-27 00:05:25 -07003092 /* The rest of this logic is based on RFC 6125, section 6.4.3
3093 * (http://tools.ietf.org/html/rfc6125#section-6.4.3) */
3094
Emeric Bruna848dae2013-10-08 11:27:28 +02003095 pattern_wildcard = NULL;
3096 pattern_left_label_end = pattern;
3097 while (*pattern_left_label_end != '.') {
3098 switch (*pattern_left_label_end) {
3099 case 0:
3100 /* End of label not found */
3101 return 0;
3102 case '*':
3103 /* If there is more than one wildcards */
3104 if (pattern_wildcard)
3105 return 0;
3106 pattern_wildcard = pattern_left_label_end;
3107 break;
3108 }
3109 pattern_left_label_end++;
3110 }
3111
3112 /* If it's not trivial and there is no wildcard, it can't
3113 * match */
3114 if (!pattern_wildcard)
Evan Broderbe554312013-06-27 00:05:25 -07003115 return 0;
3116
3117 /* Make sure all labels match except the leftmost */
3118 hostname_left_label_end = strchr(hostname, '.');
3119 if (!hostname_left_label_end
3120 || strcmp(pattern_left_label_end, hostname_left_label_end) != 0)
3121 return 0;
3122
3123 /* Make sure the leftmost label of the hostname is long enough
3124 * that the wildcard can match */
Emeric Brun369da852013-10-08 11:39:35 +02003125 if (hostname_left_label_end - hostname < (pattern_left_label_end - pattern) - 1)
Evan Broderbe554312013-06-27 00:05:25 -07003126 return 0;
3127
3128 /* Finally compare the string on either side of the
3129 * wildcard */
3130 prefixlen = pattern_wildcard - pattern;
3131 suffixlen = pattern_left_label_end - (pattern_wildcard + 1);
Emeric Bruna848dae2013-10-08 11:27:28 +02003132 if ((prefixlen && (memcmp(pattern, hostname, prefixlen) != 0))
3133 || (suffixlen && (memcmp(pattern_wildcard + 1, hostname_left_label_end - suffixlen, suffixlen) != 0)))
Evan Broderbe554312013-06-27 00:05:25 -07003134 return 0;
3135
3136 return 1;
3137}
3138
3139static int ssl_sock_srv_verifycbk(int ok, X509_STORE_CTX *ctx)
3140{
3141 SSL *ssl;
3142 struct connection *conn;
3143 char *servername;
3144
3145 int depth;
3146 X509 *cert;
3147 STACK_OF(GENERAL_NAME) *alt_names;
3148 int i;
3149 X509_NAME *cert_subject;
3150 char *str;
3151
3152 if (ok == 0)
3153 return ok;
3154
3155 ssl = X509_STORE_CTX_get_ex_data(ctx, SSL_get_ex_data_X509_STORE_CTX_idx());
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02003156 conn = SSL_get_app_data(ssl);
Evan Broderbe554312013-06-27 00:05:25 -07003157
3158 servername = objt_server(conn->target)->ssl_ctx.verify_host;
3159
3160 /* We only need to verify the CN on the actual server cert,
3161 * not the indirect CAs */
3162 depth = X509_STORE_CTX_get_error_depth(ctx);
3163 if (depth != 0)
3164 return ok;
3165
3166 /* At this point, the cert is *not* OK unless we can find a
3167 * hostname match */
3168 ok = 0;
3169
3170 cert = X509_STORE_CTX_get_current_cert(ctx);
3171 /* It seems like this might happen if verify peer isn't set */
3172 if (!cert)
3173 return ok;
3174
3175 alt_names = X509_get_ext_d2i(cert, NID_subject_alt_name, NULL, NULL);
3176 if (alt_names) {
3177 for (i = 0; !ok && i < sk_GENERAL_NAME_num(alt_names); i++) {
3178 GENERAL_NAME *name = sk_GENERAL_NAME_value(alt_names, i);
3179 if (name->type == GEN_DNS) {
Emeric Bruna33410c2013-09-17 15:47:48 +02003180#if OPENSSL_VERSION_NUMBER < 0x00907000L
3181 if (ASN1_STRING_to_UTF8((unsigned char **)&str, name->d.ia5) >= 0) {
3182#else
Evan Broderbe554312013-06-27 00:05:25 -07003183 if (ASN1_STRING_to_UTF8((unsigned char **)&str, name->d.dNSName) >= 0) {
Emeric Bruna33410c2013-09-17 15:47:48 +02003184#endif
Evan Broderbe554312013-06-27 00:05:25 -07003185 ok = ssl_sock_srv_hostcheck(str, servername);
3186 OPENSSL_free(str);
3187 }
3188 }
3189 }
Emeric Brun4ad50a42013-09-17 15:19:54 +02003190 sk_GENERAL_NAME_pop_free(alt_names, GENERAL_NAME_free);
Evan Broderbe554312013-06-27 00:05:25 -07003191 }
3192
3193 cert_subject = X509_get_subject_name(cert);
3194 i = -1;
3195 while (!ok && (i = X509_NAME_get_index_by_NID(cert_subject, NID_commonName, i)) != -1) {
3196 X509_NAME_ENTRY *entry = X509_NAME_get_entry(cert_subject, i);
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02003197 ASN1_STRING *value;
3198 value = X509_NAME_ENTRY_get_data(entry);
3199 if (ASN1_STRING_to_UTF8((unsigned char **)&str, value) >= 0) {
Evan Broderbe554312013-06-27 00:05:25 -07003200 ok = ssl_sock_srv_hostcheck(str, servername);
3201 OPENSSL_free(str);
3202 }
3203 }
3204
3205 return ok;
3206}
3207
Emeric Brun94324a42012-10-11 14:00:19 +02003208/* prepare ssl context from servers options. Returns an error count */
Willy Tarreau03209342016-12-22 17:08:28 +01003209int ssl_sock_prepare_srv_ctx(struct server *srv)
Emeric Brun94324a42012-10-11 14:00:19 +02003210{
Willy Tarreau03209342016-12-22 17:08:28 +01003211 struct proxy *curproxy = srv->proxy;
Emeric Brun94324a42012-10-11 14:00:19 +02003212 int cfgerr = 0;
Remi Gacogneaf5c3da2014-05-19 10:29:58 +02003213 long options =
Emeric Brun94324a42012-10-11 14:00:19 +02003214 SSL_OP_ALL | /* all known workarounds for bugs */
3215 SSL_OP_NO_SSLv2 |
3216 SSL_OP_NO_COMPRESSION;
Remi Gacogneaf5c3da2014-05-19 10:29:58 +02003217 long mode =
Emeric Brun94324a42012-10-11 14:00:19 +02003218 SSL_MODE_ENABLE_PARTIAL_WRITE |
3219 SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER |
Willy Tarreau396a1862014-11-13 14:06:52 +01003220 SSL_MODE_RELEASE_BUFFERS |
3221 SSL_MODE_SMALL_BUFFERS;
Emeric Brun850efd52014-01-29 12:24:34 +01003222 int verify = SSL_VERIFY_NONE;
Emeric Brun94324a42012-10-11 14:00:19 +02003223
Thierry Fournier383085f2013-01-24 14:15:43 +01003224 /* Make sure openssl opens /dev/urandom before the chroot */
3225 if (!ssl_initialize_random()) {
3226 Alert("OpenSSL random data generator initialization failed.\n");
3227 cfgerr++;
3228 }
3229
Willy Tarreaufce03112015-01-15 21:32:40 +01003230 /* Automatic memory computations need to know we use SSL there */
3231 global.ssl_used_backend = 1;
3232
3233 /* Initiate SSL context for current server */
Emeric Brun94324a42012-10-11 14:00:19 +02003234 srv->ssl_ctx.reused_sess = NULL;
3235 if (srv->use_ssl)
3236 srv->xprt = &ssl_sock;
3237 if (srv->check.use_ssl)
Cyril Bonté9ce13112014-11-15 22:41:27 +01003238 srv->check.xprt = &ssl_sock;
Emeric Brun94324a42012-10-11 14:00:19 +02003239
3240 srv->ssl_ctx.ctx = SSL_CTX_new(SSLv23_client_method());
3241 if (!srv->ssl_ctx.ctx) {
3242 Alert("config : %s '%s', server '%s': unable to allocate ssl context.\n",
3243 proxy_type_str(curproxy), curproxy->id,
3244 srv->id);
3245 cfgerr++;
3246 return cfgerr;
3247 }
Emeric Bruna7aa3092012-10-26 12:58:00 +02003248 if (srv->ssl_ctx.client_crt) {
3249 if (SSL_CTX_use_PrivateKey_file(srv->ssl_ctx.ctx, srv->ssl_ctx.client_crt, SSL_FILETYPE_PEM) <= 0) {
3250 Alert("config : %s '%s', server '%s': unable to load SSL private key from PEM file '%s'.\n",
3251 proxy_type_str(curproxy), curproxy->id,
3252 srv->id, srv->ssl_ctx.client_crt);
3253 cfgerr++;
3254 }
3255 else if (SSL_CTX_use_certificate_chain_file(srv->ssl_ctx.ctx, srv->ssl_ctx.client_crt) <= 0) {
3256 Alert("config : %s '%s', server '%s': unable to load ssl certificate from PEM file '%s'.\n",
3257 proxy_type_str(curproxy), curproxy->id,
3258 srv->id, srv->ssl_ctx.client_crt);
3259 cfgerr++;
3260 }
3261 else if (SSL_CTX_check_private_key(srv->ssl_ctx.ctx) <= 0) {
3262 Alert("config : %s '%s', server '%s': inconsistencies between private key and certificate loaded from PEM file '%s'.\n",
3263 proxy_type_str(curproxy), curproxy->id,
3264 srv->id, srv->ssl_ctx.client_crt);
3265 cfgerr++;
3266 }
3267 }
Emeric Brun94324a42012-10-11 14:00:19 +02003268
3269 if (srv->ssl_ctx.options & SRV_SSL_O_NO_SSLV3)
3270 options |= SSL_OP_NO_SSLv3;
3271 if (srv->ssl_ctx.options & SRV_SSL_O_NO_TLSV10)
3272 options |= SSL_OP_NO_TLSv1;
3273 if (srv->ssl_ctx.options & SRV_SSL_O_NO_TLSV11)
3274 options |= SSL_OP_NO_TLSv1_1;
3275 if (srv->ssl_ctx.options & SRV_SSL_O_NO_TLSV12)
3276 options |= SSL_OP_NO_TLSv1_2;
Emeric Brunf9c5c472012-10-11 15:28:34 +02003277 if (srv->ssl_ctx.options & SRV_SSL_O_NO_TLS_TICKETS)
3278 options |= SSL_OP_NO_TICKET;
Jérémie Courrèges-Anglas17c3f622015-07-25 16:50:52 -06003279 if (srv->ssl_ctx.options & SRV_SSL_O_USE_SSLV3) {
3280#ifndef OPENSSL_NO_SSL3
Emeric Brun94324a42012-10-11 14:00:19 +02003281 SSL_CTX_set_ssl_version(srv->ssl_ctx.ctx, SSLv3_client_method());
Jérémie Courrèges-Anglas17c3f622015-07-25 16:50:52 -06003282#else
Thierry FOURNIERbc965342015-08-26 08:21:26 +02003283 Alert("SSLv3 support requested but unavailable.\n");
Jérémie Courrèges-Anglas17c3f622015-07-25 16:50:52 -06003284 cfgerr++;
3285#endif
3286 }
Emeric Brun94324a42012-10-11 14:00:19 +02003287 if (srv->ssl_ctx.options & SRV_SSL_O_USE_TLSV10)
3288 SSL_CTX_set_ssl_version(srv->ssl_ctx.ctx, TLSv1_client_method());
3289#if SSL_OP_NO_TLSv1_1
3290 if (srv->ssl_ctx.options & SRV_SSL_O_USE_TLSV11)
3291 SSL_CTX_set_ssl_version(srv->ssl_ctx.ctx, TLSv1_1_client_method());
3292#endif
3293#if SSL_OP_NO_TLSv1_2
3294 if (srv->ssl_ctx.options & SRV_SSL_O_USE_TLSV12)
3295 SSL_CTX_set_ssl_version(srv->ssl_ctx.ctx, TLSv1_2_client_method());
3296#endif
3297
3298 SSL_CTX_set_options(srv->ssl_ctx.ctx, options);
3299 SSL_CTX_set_mode(srv->ssl_ctx.ctx, mode);
Emeric Brun850efd52014-01-29 12:24:34 +01003300
3301 if (global.ssl_server_verify == SSL_SERVER_VERIFY_REQUIRED)
3302 verify = SSL_VERIFY_PEER;
3303
3304 switch (srv->ssl_ctx.verify) {
3305 case SSL_SOCK_VERIFY_NONE:
3306 verify = SSL_VERIFY_NONE;
3307 break;
3308 case SSL_SOCK_VERIFY_REQUIRED:
3309 verify = SSL_VERIFY_PEER;
3310 break;
3311 }
Evan Broderbe554312013-06-27 00:05:25 -07003312 SSL_CTX_set_verify(srv->ssl_ctx.ctx,
Emeric Brun850efd52014-01-29 12:24:34 +01003313 verify,
Evan Broderbe554312013-06-27 00:05:25 -07003314 srv->ssl_ctx.verify_host ? ssl_sock_srv_verifycbk : NULL);
Emeric Brun850efd52014-01-29 12:24:34 +01003315 if (verify & SSL_VERIFY_PEER) {
Emeric Brunef42d922012-10-11 16:11:36 +02003316 if (srv->ssl_ctx.ca_file) {
3317 /* load CAfile to verify */
3318 if (!SSL_CTX_load_verify_locations(srv->ssl_ctx.ctx, srv->ssl_ctx.ca_file, NULL)) {
Willy Tarreau07ba08b2014-02-16 19:22:08 +01003319 Alert("Proxy '%s', server '%s' [%s:%d] unable to load CA file '%s'.\n",
Emeric Brunef42d922012-10-11 16:11:36 +02003320 curproxy->id, srv->id,
3321 srv->conf.file, srv->conf.line, srv->ssl_ctx.ca_file);
3322 cfgerr++;
3323 }
3324 }
Emeric Brun850efd52014-01-29 12:24:34 +01003325 else {
3326 if (global.ssl_server_verify == SSL_SERVER_VERIFY_REQUIRED)
Willy Tarreau07ba08b2014-02-16 19:22:08 +01003327 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 +01003328 curproxy->id, srv->id,
3329 srv->conf.file, srv->conf.line);
3330 else
Willy Tarreau07ba08b2014-02-16 19:22:08 +01003331 Alert("Proxy '%s', server '%s' [%s:%d] verify is enabled but no CA file specified.\n",
Emeric Brun850efd52014-01-29 12:24:34 +01003332 curproxy->id, srv->id,
3333 srv->conf.file, srv->conf.line);
3334 cfgerr++;
3335 }
Emeric Brunef42d922012-10-11 16:11:36 +02003336#ifdef X509_V_FLAG_CRL_CHECK
3337 if (srv->ssl_ctx.crl_file) {
3338 X509_STORE *store = SSL_CTX_get_cert_store(srv->ssl_ctx.ctx);
3339
3340 if (!store || !X509_STORE_load_locations(store, srv->ssl_ctx.crl_file, NULL)) {
Willy Tarreau07ba08b2014-02-16 19:22:08 +01003341 Alert("Proxy '%s', server '%s' [%s:%d] unable to configure CRL file '%s'.\n",
Emeric Brunef42d922012-10-11 16:11:36 +02003342 curproxy->id, srv->id,
3343 srv->conf.file, srv->conf.line, srv->ssl_ctx.crl_file);
3344 cfgerr++;
3345 }
3346 else {
3347 X509_STORE_set_flags(store, X509_V_FLAG_CRL_CHECK|X509_V_FLAG_CRL_CHECK_ALL);
3348 }
3349 }
3350#endif
3351 }
3352
Willy Tarreauef934602016-12-22 23:12:01 +01003353 if (global_ssl.life_time)
3354 SSL_CTX_set_timeout(srv->ssl_ctx.ctx, global_ssl.life_time);
Emeric Brun4f65bff2012-11-16 15:11:00 +01003355
Emeric Brun94324a42012-10-11 14:00:19 +02003356 SSL_CTX_set_session_cache_mode(srv->ssl_ctx.ctx, SSL_SESS_CACHE_OFF);
3357 if (srv->ssl_ctx.ciphers &&
3358 !SSL_CTX_set_cipher_list(srv->ssl_ctx.ctx, srv->ssl_ctx.ciphers)) {
3359 Alert("Proxy '%s', server '%s' [%s:%d] : unable to set SSL cipher list to '%s'.\n",
3360 curproxy->id, srv->id,
3361 srv->conf.file, srv->conf.line, srv->ssl_ctx.ciphers);
3362 cfgerr++;
3363 }
3364
3365 return cfgerr;
3366}
3367
Willy Tarreau2a65ff02012-09-13 17:54:29 +02003368/* Walks down the two trees in bind_conf and prepares all certs. The pointer may
Emeric Brunfc0421f2012-09-07 17:30:07 +02003369 * be NULL, in which case nothing is done. Returns the number of errors
3370 * encountered.
3371 */
Willy Tarreau03209342016-12-22 17:08:28 +01003372int ssl_sock_prepare_all_ctx(struct bind_conf *bind_conf)
Emeric Brunfc0421f2012-09-07 17:30:07 +02003373{
3374 struct ebmb_node *node;
3375 struct sni_ctx *sni;
3376 int err = 0;
3377
Willy Tarreau2a65ff02012-09-13 17:54:29 +02003378 if (!bind_conf || !bind_conf->is_ssl)
Emeric Brunfc0421f2012-09-07 17:30:07 +02003379 return 0;
3380
Willy Tarreaufce03112015-01-15 21:32:40 +01003381 /* Automatic memory computations need to know we use SSL there */
3382 global.ssl_used_frontend = 1;
3383
Emeric Brun0bed9942014-10-30 19:25:24 +01003384 if (bind_conf->default_ctx)
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003385 err += ssl_sock_prepare_ctx(bind_conf, bind_conf->default_ssl_conf, bind_conf->default_ctx);
Emeric Brun0bed9942014-10-30 19:25:24 +01003386
Willy Tarreau2a65ff02012-09-13 17:54:29 +02003387 node = ebmb_first(&bind_conf->sni_ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02003388 while (node) {
3389 sni = ebmb_entry(node, struct sni_ctx, name);
Emeric Brun0bed9942014-10-30 19:25:24 +01003390 if (!sni->order && sni->ctx != bind_conf->default_ctx)
3391 /* only initialize the CTX on its first occurrence and
3392 if it is not the default_ctx */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003393 err += ssl_sock_prepare_ctx(bind_conf, sni->conf, sni->ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02003394 node = ebmb_next(node);
3395 }
3396
Willy Tarreau2a65ff02012-09-13 17:54:29 +02003397 node = ebmb_first(&bind_conf->sni_w_ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02003398 while (node) {
3399 sni = ebmb_entry(node, struct sni_ctx, name);
Emeric Brun0bed9942014-10-30 19:25:24 +01003400 if (!sni->order && sni->ctx != bind_conf->default_ctx)
3401 /* only initialize the CTX on its first occurrence and
3402 if it is not the default_ctx */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003403 err += ssl_sock_prepare_ctx(bind_conf, sni->conf, sni->ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02003404 node = ebmb_next(node);
3405 }
3406 return err;
3407}
3408
Willy Tarreau55d37912016-12-21 23:38:39 +01003409/* Prepares all the contexts for a bind_conf and allocates the shared SSL
3410 * context if needed. Returns < 0 on error, 0 on success. The warnings and
3411 * alerts are directly emitted since the rest of the stack does it below.
3412 */
3413int ssl_sock_prepare_bind_conf(struct bind_conf *bind_conf)
3414{
3415 struct proxy *px = bind_conf->frontend;
3416 int alloc_ctx;
3417 int err;
3418
3419 if (!bind_conf->is_ssl) {
3420 if (bind_conf->default_ctx) {
3421 Warning("Proxy '%s': A certificate was specified but SSL was not enabled on bind '%s' at [%s:%d] (use 'ssl').\n",
3422 px->id, bind_conf->arg, bind_conf->file, bind_conf->line);
3423 }
3424 return 0;
3425 }
3426 if (!bind_conf->default_ctx) {
3427 Alert("Proxy '%s': no SSL certificate specified for bind '%s' at [%s:%d] (use 'crt').\n",
3428 px->id, bind_conf->arg, bind_conf->file, bind_conf->line);
3429 return -1;
3430 }
3431
Willy Tarreauef934602016-12-22 23:12:01 +01003432 alloc_ctx = shared_context_init(global.tune.sslcachesize, (!global_ssl.private_cache && (global.nbproc > 1)) ? 1 : 0);
Willy Tarreau55d37912016-12-21 23:38:39 +01003433 if (alloc_ctx < 0) {
3434 if (alloc_ctx == SHCTX_E_INIT_LOCK)
3435 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");
3436 else
3437 Alert("Unable to allocate SSL session cache.\n");
3438 return -1;
3439 }
3440
3441 err = 0;
3442 /* initialize all certificate contexts */
3443 err += ssl_sock_prepare_all_ctx(bind_conf);
3444
3445 /* initialize CA variables if the certificates generation is enabled */
3446 err += ssl_sock_load_ca(bind_conf);
3447
3448 return -err;
3449}
Christopher Faulet77fe80c2015-07-29 13:02:40 +02003450
3451/* release ssl context allocated for servers. */
3452void ssl_sock_free_srv_ctx(struct server *srv)
3453{
3454 if (srv->ssl_ctx.ctx)
3455 SSL_CTX_free(srv->ssl_ctx.ctx);
3456}
3457
Willy Tarreau2a65ff02012-09-13 17:54:29 +02003458/* Walks down the two trees in bind_conf and frees all the certs. The pointer may
Emeric Brunfc0421f2012-09-07 17:30:07 +02003459 * be NULL, in which case nothing is done. The default_ctx is nullified too.
3460 */
Willy Tarreau2a65ff02012-09-13 17:54:29 +02003461void ssl_sock_free_all_ctx(struct bind_conf *bind_conf)
Emeric Brunfc0421f2012-09-07 17:30:07 +02003462{
3463 struct ebmb_node *node, *back;
3464 struct sni_ctx *sni;
3465
Willy Tarreau2a65ff02012-09-13 17:54:29 +02003466 if (!bind_conf || !bind_conf->is_ssl)
Emeric Brunfc0421f2012-09-07 17:30:07 +02003467 return;
3468
Willy Tarreau2a65ff02012-09-13 17:54:29 +02003469 node = ebmb_first(&bind_conf->sni_ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02003470 while (node) {
3471 sni = ebmb_entry(node, struct sni_ctx, name);
3472 back = ebmb_next(node);
3473 ebmb_delete(node);
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003474 if (!sni->order) { /* only free the CTX on its first occurrence */
Emeric Brunfc0421f2012-09-07 17:30:07 +02003475 SSL_CTX_free(sni->ctx);
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003476 ssl_sock_free_ssl_conf(sni->conf);
3477 free(sni->conf);
3478 sni->conf = NULL;
3479 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02003480 free(sni);
3481 node = back;
3482 }
3483
Willy Tarreau2a65ff02012-09-13 17:54:29 +02003484 node = ebmb_first(&bind_conf->sni_w_ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02003485 while (node) {
3486 sni = ebmb_entry(node, struct sni_ctx, name);
3487 back = ebmb_next(node);
3488 ebmb_delete(node);
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003489 if (!sni->order) { /* only free the CTX on its first occurrence */
Emeric Brunfc0421f2012-09-07 17:30:07 +02003490 SSL_CTX_free(sni->ctx);
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003491 ssl_sock_free_ssl_conf(sni->conf);
3492 free(sni->conf);
3493 sni->conf = NULL;
3494 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02003495 free(sni);
3496 node = back;
3497 }
3498
Willy Tarreau2a65ff02012-09-13 17:54:29 +02003499 bind_conf->default_ctx = NULL;
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003500 bind_conf->default_ssl_conf = NULL;
Emeric Brune1f38db2012-09-03 20:36:47 +02003501}
3502
Willy Tarreau795cdab2016-12-22 17:30:54 +01003503/* Destroys all the contexts for a bind_conf. This is used during deinit(). */
3504void ssl_sock_destroy_bind_conf(struct bind_conf *bind_conf)
3505{
3506 ssl_sock_free_ca(bind_conf);
3507 ssl_sock_free_all_ctx(bind_conf);
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003508 ssl_sock_free_ssl_conf(&bind_conf->ssl_conf);
Willy Tarreau795cdab2016-12-22 17:30:54 +01003509 free(bind_conf->ca_sign_file);
3510 free(bind_conf->ca_sign_pass);
Willy Tarreau795cdab2016-12-22 17:30:54 +01003511 if (bind_conf->keys_ref) {
3512 free(bind_conf->keys_ref->filename);
3513 free(bind_conf->keys_ref->tlskeys);
3514 LIST_DEL(&bind_conf->keys_ref->list);
3515 free(bind_conf->keys_ref);
3516 }
3517 bind_conf->keys_ref = NULL;
Willy Tarreau795cdab2016-12-22 17:30:54 +01003518 bind_conf->ca_sign_pass = NULL;
3519 bind_conf->ca_sign_file = NULL;
Willy Tarreau795cdab2016-12-22 17:30:54 +01003520}
3521
Christopher Faulet31af49d2015-06-09 17:29:50 +02003522/* Load CA cert file and private key used to generate certificates */
3523int
Willy Tarreau03209342016-12-22 17:08:28 +01003524ssl_sock_load_ca(struct bind_conf *bind_conf)
Christopher Faulet31af49d2015-06-09 17:29:50 +02003525{
Willy Tarreau03209342016-12-22 17:08:28 +01003526 struct proxy *px = bind_conf->frontend;
Christopher Faulet31af49d2015-06-09 17:29:50 +02003527 FILE *fp;
3528 X509 *cacert = NULL;
3529 EVP_PKEY *capkey = NULL;
3530 int err = 0;
3531
3532 if (!bind_conf || !bind_conf->generate_certs)
3533 return err;
3534
Willy Tarreaua84c2672015-10-09 12:10:13 +02003535#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Willy Tarreauef934602016-12-22 23:12:01 +01003536 if (global_ssl.ctx_cache)
3537 ssl_ctx_lru_tree = lru64_new(global_ssl.ctx_cache);
Christopher Fauletd2cab922015-07-28 16:03:47 +02003538 ssl_ctx_lru_seed = (unsigned int)time(NULL);
Willy Tarreaua84c2672015-10-09 12:10:13 +02003539#endif
Christopher Fauletd2cab922015-07-28 16:03:47 +02003540
Christopher Faulet31af49d2015-06-09 17:29:50 +02003541 if (!bind_conf->ca_sign_file) {
3542 Alert("Proxy '%s': cannot enable certificate generation, "
3543 "no CA certificate File configured at [%s:%d].\n",
3544 px->id, bind_conf->file, bind_conf->line);
Christopher Faulet31af49d2015-06-09 17:29:50 +02003545 goto load_error;
Christopher Fauletc6f02fb2015-10-09 10:53:31 +02003546 }
Christopher Faulet31af49d2015-06-09 17:29:50 +02003547
3548 /* read in the CA certificate */
3549 if (!(fp = fopen(bind_conf->ca_sign_file, "r"))) {
3550 Alert("Proxy '%s': Failed to read CA certificate file '%s' at [%s:%d].\n",
3551 px->id, bind_conf->ca_sign_file, bind_conf->file, bind_conf->line);
Christopher Faulet31af49d2015-06-09 17:29:50 +02003552 goto load_error;
3553 }
3554 if (!(cacert = PEM_read_X509(fp, NULL, NULL, NULL))) {
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 Fauletc6f02fb2015-10-09 10:53:31 +02003557 goto read_error;
Christopher Faulet31af49d2015-06-09 17:29:50 +02003558 }
Christopher Fauletc6f02fb2015-10-09 10:53:31 +02003559 rewind(fp);
Christopher Faulet31af49d2015-06-09 17:29:50 +02003560 if (!(capkey = PEM_read_PrivateKey(fp, NULL, NULL, bind_conf->ca_sign_pass))) {
3561 Alert("Proxy '%s': Failed to read CA private key file '%s' at [%s:%d].\n",
3562 px->id, bind_conf->ca_sign_file, bind_conf->file, bind_conf->line);
Christopher Fauletc6f02fb2015-10-09 10:53:31 +02003563 goto read_error;
Christopher Faulet31af49d2015-06-09 17:29:50 +02003564 }
Christopher Faulet31af49d2015-06-09 17:29:50 +02003565
Christopher Fauletc6f02fb2015-10-09 10:53:31 +02003566 fclose (fp);
Christopher Faulet31af49d2015-06-09 17:29:50 +02003567 bind_conf->ca_sign_cert = cacert;
3568 bind_conf->ca_sign_pkey = capkey;
3569 return err;
3570
Christopher Fauletc6f02fb2015-10-09 10:53:31 +02003571 read_error:
3572 fclose (fp);
Christopher Faulet31af49d2015-06-09 17:29:50 +02003573 if (capkey) EVP_PKEY_free(capkey);
3574 if (cacert) X509_free(cacert);
Christopher Fauletc6f02fb2015-10-09 10:53:31 +02003575 load_error:
3576 bind_conf->generate_certs = 0;
3577 err++;
Christopher Faulet31af49d2015-06-09 17:29:50 +02003578 return err;
3579}
3580
3581/* Release CA cert and private key used to generate certificated */
3582void
3583ssl_sock_free_ca(struct bind_conf *bind_conf)
3584{
3585 if (!bind_conf)
3586 return;
3587
3588 if (bind_conf->ca_sign_pkey)
3589 EVP_PKEY_free(bind_conf->ca_sign_pkey);
3590 if (bind_conf->ca_sign_cert)
3591 X509_free(bind_conf->ca_sign_cert);
Willy Tarreau94ff03a2016-12-22 17:57:46 +01003592 bind_conf->ca_sign_pkey = NULL;
3593 bind_conf->ca_sign_cert = NULL;
Christopher Faulet31af49d2015-06-09 17:29:50 +02003594}
3595
Emeric Brun46591952012-05-18 15:47:34 +02003596/*
3597 * This function is called if SSL * context is not yet allocated. The function
3598 * is designed to be called before any other data-layer operation and sets the
3599 * handshake flag on the connection. It is safe to call it multiple times.
3600 * It returns 0 on success and -1 in error case.
3601 */
3602static int ssl_sock_init(struct connection *conn)
3603{
3604 /* already initialized */
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02003605 if (conn->xprt_ctx)
Emeric Brun46591952012-05-18 15:47:34 +02003606 return 0;
3607
Willy Tarreau3c728722014-01-23 13:50:42 +01003608 if (!conn_ctrl_ready(conn))
Willy Tarreauf79c8172013-10-21 16:30:56 +02003609 return 0;
3610
Willy Tarreau20879a02012-12-03 16:32:10 +01003611 if (global.maxsslconn && sslconns >= global.maxsslconn) {
3612 conn->err_code = CO_ER_SSL_TOO_MANY;
Willy Tarreau403edff2012-09-06 11:58:37 +02003613 return -1;
Willy Tarreau20879a02012-12-03 16:32:10 +01003614 }
Willy Tarreau403edff2012-09-06 11:58:37 +02003615
Emeric Brun46591952012-05-18 15:47:34 +02003616 /* If it is in client mode initiate SSL session
3617 in connect state otherwise accept state */
Willy Tarreau3fdb3662012-11-12 00:42:33 +01003618 if (objt_server(conn->target)) {
Willy Tarreaufba03cd2014-11-13 13:48:58 +01003619 int may_retry = 1;
3620
3621 retry_connect:
Emeric Brun46591952012-05-18 15:47:34 +02003622 /* Alloc a new SSL session ctx */
Willy Tarreau3fdb3662012-11-12 00:42:33 +01003623 conn->xprt_ctx = SSL_new(objt_server(conn->target)->ssl_ctx.ctx);
Willy Tarreau20879a02012-12-03 16:32:10 +01003624 if (!conn->xprt_ctx) {
Willy Tarreaufba03cd2014-11-13 13:48:58 +01003625 if (may_retry--) {
3626 pool_gc2();
3627 goto retry_connect;
3628 }
Willy Tarreau20879a02012-12-03 16:32:10 +01003629 conn->err_code = CO_ER_SSL_NO_MEM;
Emeric Brun46591952012-05-18 15:47:34 +02003630 return -1;
Willy Tarreau20879a02012-12-03 16:32:10 +01003631 }
Emeric Brun46591952012-05-18 15:47:34 +02003632
Emeric Brun46591952012-05-18 15:47:34 +02003633 /* set fd on SSL session context */
Emeric Brun55476152014-11-12 17:35:37 +01003634 if (!SSL_set_fd(conn->xprt_ctx, conn->t.sock.fd)) {
3635 SSL_free(conn->xprt_ctx);
3636 conn->xprt_ctx = NULL;
Willy Tarreaufba03cd2014-11-13 13:48:58 +01003637 if (may_retry--) {
3638 pool_gc2();
3639 goto retry_connect;
3640 }
Emeric Brun55476152014-11-12 17:35:37 +01003641 conn->err_code = CO_ER_SSL_NO_MEM;
3642 return -1;
3643 }
Emeric Brun46591952012-05-18 15:47:34 +02003644
Evan Broderbe554312013-06-27 00:05:25 -07003645 /* set connection pointer */
Emeric Brun55476152014-11-12 17:35:37 +01003646 if (!SSL_set_app_data(conn->xprt_ctx, conn)) {
3647 SSL_free(conn->xprt_ctx);
3648 conn->xprt_ctx = NULL;
Willy Tarreaufba03cd2014-11-13 13:48:58 +01003649 if (may_retry--) {
3650 pool_gc2();
3651 goto retry_connect;
3652 }
Emeric Brun55476152014-11-12 17:35:37 +01003653 conn->err_code = CO_ER_SSL_NO_MEM;
3654 return -1;
3655 }
3656
3657 SSL_set_connect_state(conn->xprt_ctx);
3658 if (objt_server(conn->target)->ssl_ctx.reused_sess) {
3659 if(!SSL_set_session(conn->xprt_ctx, objt_server(conn->target)->ssl_ctx.reused_sess)) {
3660 SSL_SESSION_free(objt_server(conn->target)->ssl_ctx.reused_sess);
3661 objt_server(conn->target)->ssl_ctx.reused_sess = NULL;
3662 }
3663 }
Evan Broderbe554312013-06-27 00:05:25 -07003664
Emeric Brun46591952012-05-18 15:47:34 +02003665 /* leave init state and start handshake */
Willy Tarreau05737472012-09-04 08:03:39 +02003666 conn->flags |= CO_FL_SSL_WAIT_HS | CO_FL_WAIT_L6_CONN;
Willy Tarreau403edff2012-09-06 11:58:37 +02003667
3668 sslconns++;
Willy Tarreau71b734c2014-01-28 15:19:44 +01003669 totalsslconns++;
Emeric Brun46591952012-05-18 15:47:34 +02003670 return 0;
3671 }
Willy Tarreau3fdb3662012-11-12 00:42:33 +01003672 else if (objt_listener(conn->target)) {
Willy Tarreaufba03cd2014-11-13 13:48:58 +01003673 int may_retry = 1;
3674
3675 retry_accept:
Emeric Brun46591952012-05-18 15:47:34 +02003676 /* Alloc a new SSL session ctx */
Willy Tarreau3fdb3662012-11-12 00:42:33 +01003677 conn->xprt_ctx = SSL_new(objt_listener(conn->target)->bind_conf->default_ctx);
Willy Tarreau20879a02012-12-03 16:32:10 +01003678 if (!conn->xprt_ctx) {
Willy Tarreaufba03cd2014-11-13 13:48:58 +01003679 if (may_retry--) {
3680 pool_gc2();
3681 goto retry_accept;
3682 }
Willy Tarreau20879a02012-12-03 16:32:10 +01003683 conn->err_code = CO_ER_SSL_NO_MEM;
Emeric Brun46591952012-05-18 15:47:34 +02003684 return -1;
Willy Tarreau20879a02012-12-03 16:32:10 +01003685 }
Emeric Brun46591952012-05-18 15:47:34 +02003686
Emeric Brun46591952012-05-18 15:47:34 +02003687 /* set fd on SSL session context */
Emeric Brun55476152014-11-12 17:35:37 +01003688 if (!SSL_set_fd(conn->xprt_ctx, conn->t.sock.fd)) {
3689 SSL_free(conn->xprt_ctx);
3690 conn->xprt_ctx = NULL;
Willy Tarreaufba03cd2014-11-13 13:48:58 +01003691 if (may_retry--) {
3692 pool_gc2();
3693 goto retry_accept;
3694 }
Emeric Brun55476152014-11-12 17:35:37 +01003695 conn->err_code = CO_ER_SSL_NO_MEM;
3696 return -1;
3697 }
Emeric Brun46591952012-05-18 15:47:34 +02003698
Emeric Brune1f38db2012-09-03 20:36:47 +02003699 /* set connection pointer */
Emeric Brun55476152014-11-12 17:35:37 +01003700 if (!SSL_set_app_data(conn->xprt_ctx, conn)) {
3701 SSL_free(conn->xprt_ctx);
3702 conn->xprt_ctx = NULL;
Willy Tarreaufba03cd2014-11-13 13:48:58 +01003703 if (may_retry--) {
3704 pool_gc2();
3705 goto retry_accept;
3706 }
Emeric Brun55476152014-11-12 17:35:37 +01003707 conn->err_code = CO_ER_SSL_NO_MEM;
3708 return -1;
3709 }
3710
3711 SSL_set_accept_state(conn->xprt_ctx);
Emeric Brune1f38db2012-09-03 20:36:47 +02003712
Emeric Brun46591952012-05-18 15:47:34 +02003713 /* leave init state and start handshake */
Willy Tarreau05737472012-09-04 08:03:39 +02003714 conn->flags |= CO_FL_SSL_WAIT_HS | CO_FL_WAIT_L6_CONN;
Willy Tarreau403edff2012-09-06 11:58:37 +02003715
3716 sslconns++;
Willy Tarreau71b734c2014-01-28 15:19:44 +01003717 totalsslconns++;
Emeric Brun46591952012-05-18 15:47:34 +02003718 return 0;
3719 }
3720 /* don't know how to handle such a target */
Willy Tarreau20879a02012-12-03 16:32:10 +01003721 conn->err_code = CO_ER_SSL_NO_TARGET;
Emeric Brun46591952012-05-18 15:47:34 +02003722 return -1;
3723}
3724
3725
3726/* This is the callback which is used when an SSL handshake is pending. It
3727 * updates the FD status if it wants some polling before being called again.
3728 * It returns 0 if it fails in a fatal way or needs to poll to go further,
3729 * otherwise it returns non-zero and removes itself from the connection's
3730 * flags (the bit is provided in <flag> by the caller).
3731 */
3732int ssl_sock_handshake(struct connection *conn, unsigned int flag)
3733{
3734 int ret;
3735
Willy Tarreau3c728722014-01-23 13:50:42 +01003736 if (!conn_ctrl_ready(conn))
Willy Tarreauf79c8172013-10-21 16:30:56 +02003737 return 0;
3738
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02003739 if (!conn->xprt_ctx)
Emeric Brun46591952012-05-18 15:47:34 +02003740 goto out_error;
3741
Emeric Brun674b7432012-11-08 19:21:55 +01003742 /* If we use SSL_do_handshake to process a reneg initiated by
3743 * the remote peer, it sometimes returns SSL_ERROR_SSL.
3744 * Usually SSL_write and SSL_read are used and process implicitly
3745 * the reneg handshake.
3746 * Here we use SSL_peek as a workaround for reneg.
3747 */
3748 if ((conn->flags & CO_FL_CONNECTED) && SSL_renegotiate_pending(conn->xprt_ctx)) {
3749 char c;
3750
3751 ret = SSL_peek(conn->xprt_ctx, &c, 1);
3752 if (ret <= 0) {
3753 /* handshake may have not been completed, let's find why */
3754 ret = SSL_get_error(conn->xprt_ctx, ret);
3755 if (ret == SSL_ERROR_WANT_WRITE) {
3756 /* SSL handshake needs to write, L4 connection may not be ready */
3757 __conn_sock_stop_recv(conn);
Willy Tarreaue1f50c42014-01-22 20:02:06 +01003758 __conn_sock_want_send(conn);
3759 fd_cant_send(conn->t.sock.fd);
Emeric Brun674b7432012-11-08 19:21:55 +01003760 return 0;
3761 }
3762 else if (ret == SSL_ERROR_WANT_READ) {
3763 /* handshake may have been completed but we have
3764 * no more data to read.
3765 */
3766 if (!SSL_renegotiate_pending(conn->xprt_ctx)) {
3767 ret = 1;
3768 goto reneg_ok;
3769 }
3770 /* SSL handshake needs to read, L4 connection is ready */
3771 if (conn->flags & CO_FL_WAIT_L4_CONN)
3772 conn->flags &= ~CO_FL_WAIT_L4_CONN;
3773 __conn_sock_stop_send(conn);
Willy Tarreaue1f50c42014-01-22 20:02:06 +01003774 __conn_sock_want_recv(conn);
3775 fd_cant_recv(conn->t.sock.fd);
Emeric Brun674b7432012-11-08 19:21:55 +01003776 return 0;
3777 }
3778 else if (ret == SSL_ERROR_SYSCALL) {
3779 /* if errno is null, then connection was successfully established */
3780 if (!errno && conn->flags & CO_FL_WAIT_L4_CONN)
3781 conn->flags &= ~CO_FL_WAIT_L4_CONN;
Willy Tarreau20879a02012-12-03 16:32:10 +01003782 if (!conn->err_code) {
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02003783 int empty_handshake;
Luca Pizzamiglio578b1692016-12-12 10:56:56 +01003784#if (OPENSSL_VERSION_NUMBER >= 0x1010000fL) && !defined(LIBRESSL_VERSION_NUMBER)
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02003785 OSSL_HANDSHAKE_STATE state = SSL_get_state((SSL *)conn->xprt_ctx);
3786 empty_handshake = state == TLS_ST_BEFORE;
3787#else
3788 empty_handshake = !((SSL *)conn->xprt_ctx)->packet_length;
3789#endif
3790
3791 if (empty_handshake) {
Emeric Brun29f037d2014-04-25 19:05:36 +02003792 if (!errno) {
3793 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
3794 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
3795 else
3796 conn->err_code = CO_ER_SSL_EMPTY;
3797 }
3798 else {
3799 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
3800 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
3801 else
3802 conn->err_code = CO_ER_SSL_ABORT;
3803 }
3804 }
3805 else {
3806 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
3807 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
Willy Tarreau20879a02012-12-03 16:32:10 +01003808 else
Emeric Brun29f037d2014-04-25 19:05:36 +02003809 conn->err_code = CO_ER_SSL_HANDSHAKE;
3810 }
Willy Tarreau20879a02012-12-03 16:32:10 +01003811 }
Emeric Brun674b7432012-11-08 19:21:55 +01003812 goto out_error;
3813 }
3814 else {
3815 /* Fail on all other handshake errors */
3816 /* Note: OpenSSL may leave unread bytes in the socket's
3817 * buffer, causing an RST to be emitted upon close() on
3818 * TCP sockets. We first try to drain possibly pending
3819 * data to avoid this as much as possible.
3820 */
Willy Tarreaud85c4852015-03-13 00:40:28 +01003821 conn_sock_drain(conn);
Willy Tarreau20879a02012-12-03 16:32:10 +01003822 if (!conn->err_code)
Willy Tarreauf51c6982014-04-25 20:02:39 +02003823 conn->err_code = (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT) ?
3824 CO_ER_SSL_KILLED_HB : CO_ER_SSL_HANDSHAKE;
Emeric Brun674b7432012-11-08 19:21:55 +01003825 goto out_error;
3826 }
3827 }
3828 /* read some data: consider handshake completed */
3829 goto reneg_ok;
3830 }
3831
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02003832 ret = SSL_do_handshake(conn->xprt_ctx);
Emeric Brun46591952012-05-18 15:47:34 +02003833 if (ret != 1) {
3834 /* handshake did not complete, let's find why */
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02003835 ret = SSL_get_error(conn->xprt_ctx, ret);
Emeric Brun46591952012-05-18 15:47:34 +02003836
3837 if (ret == SSL_ERROR_WANT_WRITE) {
3838 /* SSL handshake needs to write, L4 connection may not be ready */
3839 __conn_sock_stop_recv(conn);
Willy Tarreaue1f50c42014-01-22 20:02:06 +01003840 __conn_sock_want_send(conn);
3841 fd_cant_send(conn->t.sock.fd);
Emeric Brun46591952012-05-18 15:47:34 +02003842 return 0;
3843 }
3844 else if (ret == SSL_ERROR_WANT_READ) {
3845 /* SSL handshake needs to read, L4 connection is ready */
3846 if (conn->flags & CO_FL_WAIT_L4_CONN)
3847 conn->flags &= ~CO_FL_WAIT_L4_CONN;
3848 __conn_sock_stop_send(conn);
Willy Tarreaue1f50c42014-01-22 20:02:06 +01003849 __conn_sock_want_recv(conn);
3850 fd_cant_recv(conn->t.sock.fd);
Emeric Brun46591952012-05-18 15:47:34 +02003851 return 0;
3852 }
Willy Tarreau89230192012-09-28 20:22:13 +02003853 else if (ret == SSL_ERROR_SYSCALL) {
Luca Pizzamiglio578b1692016-12-12 10:56:56 +01003854#if (OPENSSL_VERSION_NUMBER >= 0x1010000fL) && !defined(LIBRESSL_VERSION_NUMBER)
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02003855 OSSL_HANDSHAKE_STATE state;
3856#endif
3857 int empty_handshake;
Willy Tarreau89230192012-09-28 20:22:13 +02003858 /* if errno is null, then connection was successfully established */
3859 if (!errno && conn->flags & CO_FL_WAIT_L4_CONN)
3860 conn->flags &= ~CO_FL_WAIT_L4_CONN;
Willy Tarreau20879a02012-12-03 16:32:10 +01003861
Luca Pizzamiglio578b1692016-12-12 10:56:56 +01003862#if (OPENSSL_VERSION_NUMBER >= 0x1010000fL) && !defined(LIBRESSL_VERSION_NUMBER)
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02003863 state = SSL_get_state((SSL *)conn->xprt_ctx);
3864 empty_handshake = state == TLS_ST_BEFORE;
3865#else
3866 empty_handshake = !((SSL *)conn->xprt_ctx)->packet_length;
3867#endif
3868 if (empty_handshake) {
Emeric Brun29f037d2014-04-25 19:05:36 +02003869 if (!errno) {
3870 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
3871 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
3872 else
3873 conn->err_code = CO_ER_SSL_EMPTY;
3874 }
3875 else {
3876 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
3877 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
3878 else
3879 conn->err_code = CO_ER_SSL_ABORT;
3880 }
3881 }
3882 else {
3883 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
3884 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
Willy Tarreau20879a02012-12-03 16:32:10 +01003885 else
Emeric Brun29f037d2014-04-25 19:05:36 +02003886 conn->err_code = CO_ER_SSL_HANDSHAKE;
3887 }
Willy Tarreau89230192012-09-28 20:22:13 +02003888 goto out_error;
3889 }
Emeric Brun46591952012-05-18 15:47:34 +02003890 else {
3891 /* Fail on all other handshake errors */
Willy Tarreau566dc552012-10-19 20:52:18 +02003892 /* Note: OpenSSL may leave unread bytes in the socket's
3893 * buffer, causing an RST to be emitted upon close() on
3894 * TCP sockets. We first try to drain possibly pending
3895 * data to avoid this as much as possible.
3896 */
Willy Tarreaud85c4852015-03-13 00:40:28 +01003897 conn_sock_drain(conn);
Willy Tarreau20879a02012-12-03 16:32:10 +01003898 if (!conn->err_code)
Willy Tarreauf51c6982014-04-25 20:02:39 +02003899 conn->err_code = (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT) ?
3900 CO_ER_SSL_KILLED_HB : CO_ER_SSL_HANDSHAKE;
Emeric Brun46591952012-05-18 15:47:34 +02003901 goto out_error;
3902 }
3903 }
3904
Emeric Brun674b7432012-11-08 19:21:55 +01003905reneg_ok:
Emeric Brun46591952012-05-18 15:47:34 +02003906 /* Handshake succeeded */
Willy Tarreau0c9c2722014-05-28 12:28:58 +02003907 if (!SSL_session_reused(conn->xprt_ctx)) {
3908 if (objt_server(conn->target)) {
3909 update_freq_ctr(&global.ssl_be_keys_per_sec, 1);
3910 if (global.ssl_be_keys_per_sec.curr_ctr > global.ssl_be_keys_max)
3911 global.ssl_be_keys_max = global.ssl_be_keys_per_sec.curr_ctr;
3912
Emeric Brun46591952012-05-18 15:47:34 +02003913 /* check if session was reused, if not store current session on server for reuse */
Willy Tarreau30fd4bd2016-12-22 21:54:21 +01003914 if (objt_server(conn->target)->ssl_ctx.reused_sess) {
Willy Tarreau3fdb3662012-11-12 00:42:33 +01003915 SSL_SESSION_free(objt_server(conn->target)->ssl_ctx.reused_sess);
Willy Tarreau30fd4bd2016-12-22 21:54:21 +01003916 objt_server(conn->target)->ssl_ctx.reused_sess = NULL;
3917 }
Emeric Brun46591952012-05-18 15:47:34 +02003918
Willy Tarreau2a3fb1c2015-02-05 16:47:07 +01003919 if (!(objt_server(conn->target)->ssl_ctx.options & SRV_SSL_O_NO_REUSE))
3920 objt_server(conn->target)->ssl_ctx.reused_sess = SSL_get1_session(conn->xprt_ctx);
Emeric Brun46591952012-05-18 15:47:34 +02003921 }
Willy Tarreau0c9c2722014-05-28 12:28:58 +02003922 else {
3923 update_freq_ctr(&global.ssl_fe_keys_per_sec, 1);
3924 if (global.ssl_fe_keys_per_sec.curr_ctr > global.ssl_fe_keys_max)
3925 global.ssl_fe_keys_max = global.ssl_fe_keys_per_sec.curr_ctr;
3926 }
Emeric Brun46591952012-05-18 15:47:34 +02003927 }
3928
3929 /* The connection is now established at both layers, it's time to leave */
3930 conn->flags &= ~(flag | CO_FL_WAIT_L4_CONN | CO_FL_WAIT_L6_CONN);
3931 return 1;
3932
3933 out_error:
Emeric Brun644cde02012-12-14 11:21:13 +01003934 /* Clear openssl global errors stack */
Thierry FOURNIER / OZON.IO8b068c22016-10-10 11:59:50 +02003935 ssl_sock_dump_errors(conn);
Emeric Brun644cde02012-12-14 11:21:13 +01003936 ERR_clear_error();
3937
Emeric Brun9fa89732012-10-04 17:09:56 +02003938 /* free resumed session if exists */
Willy Tarreau3fdb3662012-11-12 00:42:33 +01003939 if (objt_server(conn->target) && objt_server(conn->target)->ssl_ctx.reused_sess) {
3940 SSL_SESSION_free(objt_server(conn->target)->ssl_ctx.reused_sess);
3941 objt_server(conn->target)->ssl_ctx.reused_sess = NULL;
Emeric Brun9fa89732012-10-04 17:09:56 +02003942 }
3943
Emeric Brun46591952012-05-18 15:47:34 +02003944 /* Fail on all other handshake errors */
3945 conn->flags |= CO_FL_ERROR;
Willy Tarreau20879a02012-12-03 16:32:10 +01003946 if (!conn->err_code)
3947 conn->err_code = CO_ER_SSL_HANDSHAKE;
Emeric Brun46591952012-05-18 15:47:34 +02003948 return 0;
3949}
3950
3951/* Receive up to <count> bytes from connection <conn>'s socket and store them
Willy Tarreauabf08d92014-01-14 11:31:27 +01003952 * into buffer <buf>. Only one call to recv() is performed, unless the
Emeric Brun46591952012-05-18 15:47:34 +02003953 * buffer wraps, in which case a second call may be performed. The connection's
3954 * flags are updated with whatever special event is detected (error, read0,
3955 * empty). The caller is responsible for taking care of those events and
3956 * avoiding the call if inappropriate. The function does not call the
3957 * connection's polling update function, so the caller is responsible for this.
3958 */
3959static int ssl_sock_to_buf(struct connection *conn, struct buffer *buf, int count)
3960{
3961 int ret, done = 0;
Willy Tarreauabf08d92014-01-14 11:31:27 +01003962 int try;
Emeric Brun46591952012-05-18 15:47:34 +02003963
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02003964 if (!conn->xprt_ctx)
Emeric Brun46591952012-05-18 15:47:34 +02003965 goto out_error;
3966
3967 if (conn->flags & CO_FL_HANDSHAKE)
3968 /* a handshake was requested */
3969 return 0;
3970
Willy Tarreauabf08d92014-01-14 11:31:27 +01003971 /* let's realign the buffer to optimize I/O */
3972 if (buffer_empty(buf))
Emeric Brun46591952012-05-18 15:47:34 +02003973 buf->p = buf->data;
Emeric Brun46591952012-05-18 15:47:34 +02003974
3975 /* read the largest possible block. For this, we perform only one call
3976 * to recv() unless the buffer wraps and we exactly fill the first hunk,
3977 * in which case we accept to do it once again. A new attempt is made on
3978 * EINTR too.
3979 */
Willy Tarreau00b0fb92014-01-17 11:09:40 +01003980 while (count > 0) {
Willy Tarreauabf08d92014-01-14 11:31:27 +01003981 /* first check if we have some room after p+i */
3982 try = buf->data + buf->size - (buf->p + buf->i);
3983 /* otherwise continue between data and p-o */
3984 if (try <= 0) {
3985 try = buf->p - (buf->data + buf->o);
3986 if (try <= 0)
3987 break;
3988 }
3989 if (try > count)
3990 try = count;
3991
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02003992 ret = SSL_read(conn->xprt_ctx, bi_end(buf), try);
Emeric Brune1f38db2012-09-03 20:36:47 +02003993 if (conn->flags & CO_FL_ERROR) {
3994 /* CO_FL_ERROR may be set by ssl_sock_infocbk */
Emeric Brun644cde02012-12-14 11:21:13 +01003995 goto out_error;
Emeric Brune1f38db2012-09-03 20:36:47 +02003996 }
Emeric Brun46591952012-05-18 15:47:34 +02003997 if (ret > 0) {
3998 buf->i += ret;
3999 done += ret;
4000 if (ret < try)
4001 break;
4002 count -= ret;
Emeric Brun46591952012-05-18 15:47:34 +02004003 }
4004 else if (ret == 0) {
Emeric Brun644cde02012-12-14 11:21:13 +01004005 ret = SSL_get_error(conn->xprt_ctx, ret);
4006 if (ret != SSL_ERROR_ZERO_RETURN) {
Emeric Brun1c646862012-12-14 12:33:41 +01004007 /* error on protocol or underlying transport */
4008 if ((ret != SSL_ERROR_SYSCALL)
4009 || (errno && (errno != EAGAIN)))
4010 conn->flags |= CO_FL_ERROR;
4011
Emeric Brun644cde02012-12-14 11:21:13 +01004012 /* Clear openssl global errors stack */
Thierry FOURNIER / OZON.IO8b068c22016-10-10 11:59:50 +02004013 ssl_sock_dump_errors(conn);
Emeric Brun644cde02012-12-14 11:21:13 +01004014 ERR_clear_error();
4015 }
Emeric Brun46591952012-05-18 15:47:34 +02004016 goto read0;
4017 }
4018 else {
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02004019 ret = SSL_get_error(conn->xprt_ctx, ret);
Emeric Brun46591952012-05-18 15:47:34 +02004020 if (ret == SSL_ERROR_WANT_WRITE) {
Emeric Brun8af8dd12012-11-08 17:56:20 +01004021 /* handshake is running, and it needs to enable write */
Emeric Brun46591952012-05-18 15:47:34 +02004022 conn->flags |= CO_FL_SSL_WAIT_HS;
Emeric Brun8af8dd12012-11-08 17:56:20 +01004023 __conn_sock_want_send(conn);
Emeric Brun46591952012-05-18 15:47:34 +02004024 break;
4025 }
4026 else if (ret == SSL_ERROR_WANT_READ) {
Emeric Brun282a76a2012-11-08 18:02:56 +01004027 if (SSL_renegotiate_pending(conn->xprt_ctx)) {
4028 /* handshake is running, and it may need to re-enable read */
4029 conn->flags |= CO_FL_SSL_WAIT_HS;
4030 __conn_sock_want_recv(conn);
4031 break;
4032 }
Emeric Brun46591952012-05-18 15:47:34 +02004033 /* we need to poll for retry a read later */
Willy Tarreaue1f50c42014-01-22 20:02:06 +01004034 fd_cant_recv(conn->t.sock.fd);
Emeric Brun46591952012-05-18 15:47:34 +02004035 break;
4036 }
4037 /* otherwise it's a real error */
4038 goto out_error;
4039 }
4040 }
4041 return done;
4042
4043 read0:
4044 conn_sock_read0(conn);
4045 return done;
4046 out_error:
Emeric Brun644cde02012-12-14 11:21:13 +01004047 /* Clear openssl global errors stack */
Thierry FOURNIER / OZON.IO8b068c22016-10-10 11:59:50 +02004048 ssl_sock_dump_errors(conn);
Emeric Brun644cde02012-12-14 11:21:13 +01004049 ERR_clear_error();
4050
Emeric Brun46591952012-05-18 15:47:34 +02004051 conn->flags |= CO_FL_ERROR;
4052 return done;
4053}
4054
4055
4056/* Send all pending bytes from buffer <buf> to connection <conn>'s socket.
Willy Tarreau1049b1f2014-02-02 01:51:17 +01004057 * <flags> may contain some CO_SFL_* flags to hint the system about other
4058 * pending data for example, but this flag is ignored at the moment.
Emeric Brun46591952012-05-18 15:47:34 +02004059 * Only one call to send() is performed, unless the buffer wraps, in which case
4060 * a second call may be performed. The connection's flags are updated with
4061 * whatever special event is detected (error, empty). The caller is responsible
4062 * for taking care of those events and avoiding the call if inappropriate. The
4063 * function does not call the connection's polling update function, so the caller
4064 * is responsible for this.
4065 */
4066static int ssl_sock_from_buf(struct connection *conn, struct buffer *buf, int flags)
4067{
4068 int ret, try, done;
4069
4070 done = 0;
4071
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02004072 if (!conn->xprt_ctx)
Emeric Brun46591952012-05-18 15:47:34 +02004073 goto out_error;
4074
4075 if (conn->flags & CO_FL_HANDSHAKE)
4076 /* a handshake was requested */
4077 return 0;
4078
4079 /* send the largest possible block. For this we perform only one call
4080 * to send() unless the buffer wraps and we exactly fill the first hunk,
4081 * in which case we accept to do it once again.
4082 */
4083 while (buf->o) {
Kevin Hestercad82342013-05-30 15:12:41 -07004084 try = bo_contig_data(buf);
Willy Tarreaubfd59462013-02-21 07:46:09 +01004085
Willy Tarreau7bed9452014-02-02 02:00:24 +01004086 if (!(flags & CO_SFL_STREAMER) &&
Willy Tarreau518cedd2014-02-17 15:43:01 +01004087 !(conn->xprt_st & SSL_SOCK_SEND_UNLIMITED) &&
Willy Tarreauef934602016-12-22 23:12:01 +01004088 global_ssl.max_record && try > global_ssl.max_record) {
4089 try = global_ssl.max_record;
Willy Tarreau518cedd2014-02-17 15:43:01 +01004090 }
4091 else {
4092 /* we need to keep the information about the fact that
4093 * we're not limiting the upcoming send(), because if it
4094 * fails, we'll have to retry with at least as many data.
4095 */
4096 conn->xprt_st |= SSL_SOCK_SEND_UNLIMITED;
4097 }
Willy Tarreaubfd59462013-02-21 07:46:09 +01004098
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02004099 ret = SSL_write(conn->xprt_ctx, bo_ptr(buf), try);
Willy Tarreau518cedd2014-02-17 15:43:01 +01004100
Emeric Brune1f38db2012-09-03 20:36:47 +02004101 if (conn->flags & CO_FL_ERROR) {
4102 /* CO_FL_ERROR may be set by ssl_sock_infocbk */
Emeric Brun644cde02012-12-14 11:21:13 +01004103 goto out_error;
Emeric Brune1f38db2012-09-03 20:36:47 +02004104 }
Emeric Brun46591952012-05-18 15:47:34 +02004105 if (ret > 0) {
Willy Tarreau518cedd2014-02-17 15:43:01 +01004106 conn->xprt_st &= ~SSL_SOCK_SEND_UNLIMITED;
4107
Emeric Brun46591952012-05-18 15:47:34 +02004108 buf->o -= ret;
4109 done += ret;
4110
Willy Tarreau5fb38032012-12-16 19:39:09 +01004111 if (likely(buffer_empty(buf)))
Emeric Brun46591952012-05-18 15:47:34 +02004112 /* optimize data alignment in the buffer */
4113 buf->p = buf->data;
4114
4115 /* if the system buffer is full, don't insist */
4116 if (ret < try)
4117 break;
4118 }
4119 else {
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02004120 ret = SSL_get_error(conn->xprt_ctx, ret);
Emeric Brun46591952012-05-18 15:47:34 +02004121 if (ret == SSL_ERROR_WANT_WRITE) {
Emeric Brun282a76a2012-11-08 18:02:56 +01004122 if (SSL_renegotiate_pending(conn->xprt_ctx)) {
4123 /* handshake is running, and it may need to re-enable write */
4124 conn->flags |= CO_FL_SSL_WAIT_HS;
4125 __conn_sock_want_send(conn);
4126 break;
4127 }
Emeric Brun46591952012-05-18 15:47:34 +02004128 /* we need to poll to retry a write later */
Willy Tarreaue1f50c42014-01-22 20:02:06 +01004129 fd_cant_send(conn->t.sock.fd);
Emeric Brun46591952012-05-18 15:47:34 +02004130 break;
4131 }
4132 else if (ret == SSL_ERROR_WANT_READ) {
Emeric Brun8af8dd12012-11-08 17:56:20 +01004133 /* handshake is running, and it needs to enable read */
Emeric Brun46591952012-05-18 15:47:34 +02004134 conn->flags |= CO_FL_SSL_WAIT_HS;
Emeric Brun8af8dd12012-11-08 17:56:20 +01004135 __conn_sock_want_recv(conn);
Emeric Brun46591952012-05-18 15:47:34 +02004136 break;
4137 }
4138 goto out_error;
4139 }
4140 }
4141 return done;
4142
4143 out_error:
Emeric Brun644cde02012-12-14 11:21:13 +01004144 /* Clear openssl global errors stack */
Thierry FOURNIER / OZON.IO8b068c22016-10-10 11:59:50 +02004145 ssl_sock_dump_errors(conn);
Emeric Brun644cde02012-12-14 11:21:13 +01004146 ERR_clear_error();
4147
Emeric Brun46591952012-05-18 15:47:34 +02004148 conn->flags |= CO_FL_ERROR;
4149 return done;
4150}
4151
Emeric Brun46591952012-05-18 15:47:34 +02004152static void ssl_sock_close(struct connection *conn) {
4153
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02004154 if (conn->xprt_ctx) {
4155 SSL_free(conn->xprt_ctx);
4156 conn->xprt_ctx = NULL;
Willy Tarreau403edff2012-09-06 11:58:37 +02004157 sslconns--;
Emeric Brun46591952012-05-18 15:47:34 +02004158 }
Emeric Brun46591952012-05-18 15:47:34 +02004159}
4160
4161/* This function tries to perform a clean shutdown on an SSL connection, and in
4162 * any case, flags the connection as reusable if no handshake was in progress.
4163 */
4164static void ssl_sock_shutw(struct connection *conn, int clean)
4165{
4166 if (conn->flags & CO_FL_HANDSHAKE)
4167 return;
Emmanuel Hocdet405ff312017-01-08 14:07:39 +01004168 if (!clean)
4169 /* don't sent notify on SSL_shutdown */
4170 SSL_CTX_set_quiet_shutdown(conn->xprt_ctx, 1);
Emeric Brun46591952012-05-18 15:47:34 +02004171 /* no handshake was in progress, try a clean ssl shutdown */
Emmanuel Hocdet405ff312017-01-08 14:07:39 +01004172 if (SSL_shutdown(conn->xprt_ctx) <= 0) {
Emeric Brun644cde02012-12-14 11:21:13 +01004173 /* Clear openssl global errors stack */
Thierry FOURNIER / OZON.IO8b068c22016-10-10 11:59:50 +02004174 ssl_sock_dump_errors(conn);
Emeric Brun644cde02012-12-14 11:21:13 +01004175 ERR_clear_error();
4176 }
Emeric Brun46591952012-05-18 15:47:34 +02004177}
4178
Willy Tarreauffc3fcd2012-10-12 20:17:54 +02004179/* used for logging, may be changed for a sample fetch later */
4180const char *ssl_sock_get_cipher_name(struct connection *conn)
4181{
4182 if (!conn->xprt && !conn->xprt_ctx)
4183 return NULL;
4184 return SSL_get_cipher_name(conn->xprt_ctx);
4185}
4186
4187/* used for logging, may be changed for a sample fetch later */
4188const char *ssl_sock_get_proto_version(struct connection *conn)
4189{
4190 if (!conn->xprt && !conn->xprt_ctx)
4191 return NULL;
4192 return SSL_get_version(conn->xprt_ctx);
4193}
4194
Willy Tarreau8d598402012-10-22 17:58:39 +02004195/* Extract a serial from a cert, and copy it to a chunk.
4196 * Returns 1 if serial is found and copied, 0 if no serial found and
4197 * -1 if output is not large enough.
4198 */
4199static int
4200ssl_sock_get_serial(X509 *crt, struct chunk *out)
4201{
4202 ASN1_INTEGER *serial;
4203
4204 serial = X509_get_serialNumber(crt);
4205 if (!serial)
4206 return 0;
4207
4208 if (out->size < serial->length)
4209 return -1;
4210
4211 memcpy(out->str, serial->data, serial->length);
4212 out->len = serial->length;
4213 return 1;
4214}
4215
Emeric Brun43e79582014-10-29 19:03:26 +01004216/* Extract a cert to der, and copy it to a chunk.
4217 * Returns 1 if cert is found and copied, 0 on der convertion failure and
4218 * -1 if output is not large enough.
4219 */
4220static int
4221ssl_sock_crt2der(X509 *crt, struct chunk *out)
4222{
4223 int len;
4224 unsigned char *p = (unsigned char *)out->str;;
4225
4226 len =i2d_X509(crt, NULL);
4227 if (len <= 0)
4228 return 1;
4229
4230 if (out->size < len)
4231 return -1;
4232
4233 i2d_X509(crt,&p);
4234 out->len = len;
4235 return 1;
4236}
4237
Emeric Brunce5ad802012-10-22 14:11:22 +02004238
4239/* Copy Date in ASN1_UTCTIME format in struct chunk out.
4240 * Returns 1 if serial is found and copied, 0 if no valid time found
4241 * and -1 if output is not large enough.
4242 */
4243static int
4244ssl_sock_get_time(ASN1_TIME *tm, struct chunk *out)
4245{
4246 if (tm->type == V_ASN1_GENERALIZEDTIME) {
4247 ASN1_GENERALIZEDTIME *gentm = (ASN1_GENERALIZEDTIME *)tm;
4248
4249 if (gentm->length < 12)
4250 return 0;
4251 if (gentm->data[0] != 0x32 || gentm->data[1] != 0x30)
4252 return 0;
4253 if (out->size < gentm->length-2)
4254 return -1;
4255
4256 memcpy(out->str, gentm->data+2, gentm->length-2);
4257 out->len = gentm->length-2;
4258 return 1;
4259 }
4260 else if (tm->type == V_ASN1_UTCTIME) {
4261 ASN1_UTCTIME *utctm = (ASN1_UTCTIME *)tm;
4262
4263 if (utctm->length < 10)
4264 return 0;
4265 if (utctm->data[0] >= 0x35)
4266 return 0;
4267 if (out->size < utctm->length)
4268 return -1;
4269
4270 memcpy(out->str, utctm->data, utctm->length);
4271 out->len = utctm->length;
4272 return 1;
4273 }
4274
4275 return 0;
4276}
4277
Emeric Brun87855892012-10-17 17:39:35 +02004278/* Extract an entry from a X509_NAME and copy its value to an output chunk.
4279 * Returns 1 if entry found, 0 if entry not found, or -1 if output not large enough.
4280 */
4281static int
4282ssl_sock_get_dn_entry(X509_NAME *a, const struct chunk *entry, int pos, struct chunk *out)
4283{
4284 X509_NAME_ENTRY *ne;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004285 ASN1_OBJECT *obj;
4286 ASN1_STRING *data;
4287 const unsigned char *data_ptr;
4288 int data_len;
Emeric Brun87855892012-10-17 17:39:35 +02004289 int i, j, n;
4290 int cur = 0;
4291 const char *s;
4292 char tmp[128];
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004293 int name_count;
4294
4295 name_count = X509_NAME_entry_count(a);
Emeric Brun87855892012-10-17 17:39:35 +02004296
4297 out->len = 0;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004298 for (i = 0; i < name_count; i++) {
Emeric Brun87855892012-10-17 17:39:35 +02004299 if (pos < 0)
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004300 j = (name_count-1) - i;
Emeric Brun87855892012-10-17 17:39:35 +02004301 else
4302 j = i;
4303
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004304 ne = X509_NAME_get_entry(a, j);
4305 obj = X509_NAME_ENTRY_get_object(ne);
4306 data = X509_NAME_ENTRY_get_data(ne);
4307 data_ptr = ASN1_STRING_get0_data(data);
4308 data_len = ASN1_STRING_length(data);
4309 n = OBJ_obj2nid(obj);
Emeric Brun87855892012-10-17 17:39:35 +02004310 if ((n == NID_undef) || ((s = OBJ_nid2sn(n)) == NULL)) {
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004311 i2t_ASN1_OBJECT(tmp, sizeof(tmp), obj);
Emeric Brun87855892012-10-17 17:39:35 +02004312 s = tmp;
4313 }
4314
4315 if (chunk_strcasecmp(entry, s) != 0)
4316 continue;
4317
4318 if (pos < 0)
4319 cur--;
4320 else
4321 cur++;
4322
4323 if (cur != pos)
4324 continue;
4325
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004326 if (data_len > out->size)
Emeric Brun87855892012-10-17 17:39:35 +02004327 return -1;
4328
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004329 memcpy(out->str, data_ptr, data_len);
4330 out->len = data_len;
Emeric Brun87855892012-10-17 17:39:35 +02004331 return 1;
4332 }
4333
4334 return 0;
4335
4336}
4337
4338/* Extract and format full DN from a X509_NAME and copy result into a chunk
4339 * Returns 1 if dn entries exits, 0 if no dn entry found or -1 if output is not large enough.
4340 */
4341static int
4342ssl_sock_get_dn_oneline(X509_NAME *a, struct chunk *out)
4343{
4344 X509_NAME_ENTRY *ne;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004345 ASN1_OBJECT *obj;
4346 ASN1_STRING *data;
4347 const unsigned char *data_ptr;
4348 int data_len;
Emeric Brun87855892012-10-17 17:39:35 +02004349 int i, n, ln;
4350 int l = 0;
4351 const char *s;
4352 char *p;
4353 char tmp[128];
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004354 int name_count;
4355
4356
4357 name_count = X509_NAME_entry_count(a);
Emeric Brun87855892012-10-17 17:39:35 +02004358
4359 out->len = 0;
4360 p = out->str;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004361 for (i = 0; i < name_count; i++) {
4362 ne = X509_NAME_get_entry(a, i);
4363 obj = X509_NAME_ENTRY_get_object(ne);
4364 data = X509_NAME_ENTRY_get_data(ne);
4365 data_ptr = ASN1_STRING_get0_data(data);
4366 data_len = ASN1_STRING_length(data);
4367 n = OBJ_obj2nid(obj);
Emeric Brun87855892012-10-17 17:39:35 +02004368 if ((n == NID_undef) || ((s = OBJ_nid2sn(n)) == NULL)) {
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004369 i2t_ASN1_OBJECT(tmp, sizeof(tmp), obj);
Emeric Brun87855892012-10-17 17:39:35 +02004370 s = tmp;
4371 }
4372 ln = strlen(s);
4373
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004374 l += 1 + ln + 1 + data_len;
Emeric Brun87855892012-10-17 17:39:35 +02004375 if (l > out->size)
4376 return -1;
4377 out->len = l;
4378
4379 *(p++)='/';
4380 memcpy(p, s, ln);
4381 p += ln;
4382 *(p++)='=';
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004383 memcpy(p, data_ptr, data_len);
4384 p += data_len;
Emeric Brun87855892012-10-17 17:39:35 +02004385 }
4386
4387 if (!out->len)
4388 return 0;
4389
4390 return 1;
4391}
4392
David Safb76832014-05-08 23:42:08 -04004393char *ssl_sock_get_version(struct connection *conn)
4394{
4395 if (!ssl_sock_is_ssl(conn))
4396 return NULL;
4397
4398 return (char *)SSL_get_version(conn->xprt_ctx);
4399}
4400
Willy Tarreau119a4082016-12-22 21:58:38 +01004401/* Sets advertised SNI for outgoing connections. Please set <hostname> to NULL
4402 * to disable SNI.
4403 */
Willy Tarreau63076412015-07-10 11:33:32 +02004404void ssl_sock_set_servername(struct connection *conn, const char *hostname)
4405{
4406#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Willy Tarreau119a4082016-12-22 21:58:38 +01004407 char *prev_name;
4408
Willy Tarreau63076412015-07-10 11:33:32 +02004409 if (!ssl_sock_is_ssl(conn))
4410 return;
4411
Willy Tarreau119a4082016-12-22 21:58:38 +01004412 /* if the SNI changes, we must destroy the reusable context so that a
4413 * new connection will present a new SNI. As an optimization we could
4414 * later imagine having a small cache of ssl_ctx to hold a few SNI per
4415 * server.
4416 */
4417 prev_name = (char *)SSL_get_servername(conn->xprt_ctx, TLSEXT_NAMETYPE_host_name);
4418 if ((!prev_name && hostname) ||
4419 (prev_name && (!hostname || strcmp(hostname, prev_name) != 0)))
4420 SSL_set_session(conn->xprt_ctx, NULL);
4421
Willy Tarreau63076412015-07-10 11:33:32 +02004422 SSL_set_tlsext_host_name(conn->xprt_ctx, hostname);
4423#endif
4424}
4425
Emeric Brun0abf8362014-06-24 18:26:41 +02004426/* Extract peer certificate's common name into the chunk dest
4427 * Returns
4428 * the len of the extracted common name
4429 * or 0 if no CN found in DN
4430 * or -1 on error case (i.e. no peer certificate)
4431 */
4432int ssl_sock_get_remote_common_name(struct connection *conn, struct chunk *dest)
David Safb76832014-05-08 23:42:08 -04004433{
4434 X509 *crt = NULL;
4435 X509_NAME *name;
David Safb76832014-05-08 23:42:08 -04004436 const char find_cn[] = "CN";
4437 const struct chunk find_cn_chunk = {
4438 .str = (char *)&find_cn,
4439 .len = sizeof(find_cn)-1
4440 };
Emeric Brun0abf8362014-06-24 18:26:41 +02004441 int result = -1;
David Safb76832014-05-08 23:42:08 -04004442
4443 if (!ssl_sock_is_ssl(conn))
Emeric Brun0abf8362014-06-24 18:26:41 +02004444 goto out;
David Safb76832014-05-08 23:42:08 -04004445
4446 /* SSL_get_peer_certificate, it increase X509 * ref count */
4447 crt = SSL_get_peer_certificate(conn->xprt_ctx);
4448 if (!crt)
4449 goto out;
4450
4451 name = X509_get_subject_name(crt);
4452 if (!name)
4453 goto out;
David Safb76832014-05-08 23:42:08 -04004454
Emeric Brun0abf8362014-06-24 18:26:41 +02004455 result = ssl_sock_get_dn_entry(name, &find_cn_chunk, 1, dest);
4456out:
David Safb76832014-05-08 23:42:08 -04004457 if (crt)
4458 X509_free(crt);
4459
4460 return result;
4461}
4462
Dave McCowan328fb582014-07-30 10:39:13 -04004463/* returns 1 if client passed a certificate for this session, 0 if not */
4464int ssl_sock_get_cert_used_sess(struct connection *conn)
4465{
4466 X509 *crt = NULL;
4467
4468 if (!ssl_sock_is_ssl(conn))
4469 return 0;
4470
4471 /* SSL_get_peer_certificate, it increase X509 * ref count */
4472 crt = SSL_get_peer_certificate(conn->xprt_ctx);
4473 if (!crt)
4474 return 0;
4475
4476 X509_free(crt);
4477 return 1;
4478}
4479
4480/* returns 1 if client passed a certificate for this connection, 0 if not */
4481int ssl_sock_get_cert_used_conn(struct connection *conn)
David Safb76832014-05-08 23:42:08 -04004482{
4483 if (!ssl_sock_is_ssl(conn))
4484 return 0;
4485
4486 return SSL_SOCK_ST_FL_VERIFY_DONE & conn->xprt_st ? 1 : 0;
4487}
4488
4489/* returns result from SSL verify */
4490unsigned int ssl_sock_get_verify_result(struct connection *conn)
4491{
4492 if (!ssl_sock_is_ssl(conn))
4493 return (unsigned int)X509_V_ERR_APPLICATION_VERIFICATION;
4494
4495 return (unsigned int)SSL_get_verify_result(conn->xprt_ctx);
4496}
4497
Willy Tarreau7875d092012-09-10 08:20:03 +02004498/***** Below are some sample fetching functions for ACL/patterns *****/
4499
Emeric Brune64aef12012-09-21 13:15:06 +02004500/* boolean, returns true if client cert was present */
4501static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004502smp_fetch_ssl_fc_has_crt(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brune64aef12012-09-21 13:15:06 +02004503{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004504 struct connection *conn;
4505
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004506 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004507 if (!conn || conn->xprt != &ssl_sock)
Emeric Brune64aef12012-09-21 13:15:06 +02004508 return 0;
4509
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004510 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brune64aef12012-09-21 13:15:06 +02004511 smp->flags |= SMP_F_MAY_CHANGE;
4512 return 0;
4513 }
4514
4515 smp->flags = 0;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004516 smp->data.type = SMP_T_BOOL;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004517 smp->data.u.sint = SSL_SOCK_ST_FL_VERIFY_DONE & conn->xprt_st ? 1 : 0;
Emeric Brune64aef12012-09-21 13:15:06 +02004518
4519 return 1;
4520}
4521
Emeric Brun43e79582014-10-29 19:03:26 +01004522/* binary, returns a certificate in a binary chunk (der/raw).
4523 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
4524 * should be use.
4525 */
4526static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004527smp_fetch_ssl_x_der(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun43e79582014-10-29 19:03:26 +01004528{
4529 int cert_peer = (kw[4] == 'c') ? 1 : 0;
4530 X509 *crt = NULL;
4531 int ret = 0;
4532 struct chunk *smp_trash;
4533 struct connection *conn;
4534
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004535 conn = objt_conn(smp->sess->origin);
Emeric Brun43e79582014-10-29 19:03:26 +01004536 if (!conn || conn->xprt != &ssl_sock)
4537 return 0;
4538
4539 if (!(conn->flags & CO_FL_CONNECTED)) {
4540 smp->flags |= SMP_F_MAY_CHANGE;
4541 return 0;
4542 }
4543
4544 if (cert_peer)
4545 crt = SSL_get_peer_certificate(conn->xprt_ctx);
4546 else
4547 crt = SSL_get_certificate(conn->xprt_ctx);
4548
4549 if (!crt)
4550 goto out;
4551
4552 smp_trash = get_trash_chunk();
4553 if (ssl_sock_crt2der(crt, smp_trash) <= 0)
4554 goto out;
4555
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004556 smp->data.u.str = *smp_trash;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004557 smp->data.type = SMP_T_BIN;
Emeric Brun43e79582014-10-29 19:03:26 +01004558 ret = 1;
4559out:
4560 /* SSL_get_peer_certificate, it increase X509 * ref count */
4561 if (cert_peer && crt)
4562 X509_free(crt);
4563 return ret;
4564}
4565
Emeric Brunba841a12014-04-30 17:05:08 +02004566/* binary, returns serial of certificate in a binary chunk.
4567 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
4568 * should be use.
4569 */
Willy Tarreau8d598402012-10-22 17:58:39 +02004570static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004571smp_fetch_ssl_x_serial(const struct arg *args, struct sample *smp, const char *kw, void *private)
Willy Tarreau8d598402012-10-22 17:58:39 +02004572{
Emeric Brunba841a12014-04-30 17:05:08 +02004573 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Willy Tarreau8d598402012-10-22 17:58:39 +02004574 X509 *crt = NULL;
4575 int ret = 0;
4576 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004577 struct connection *conn;
4578
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004579 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004580 if (!conn || conn->xprt != &ssl_sock)
Willy Tarreau8d598402012-10-22 17:58:39 +02004581 return 0;
4582
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004583 if (!(conn->flags & CO_FL_CONNECTED)) {
Willy Tarreau8d598402012-10-22 17:58:39 +02004584 smp->flags |= SMP_F_MAY_CHANGE;
4585 return 0;
4586 }
4587
Emeric Brunba841a12014-04-30 17:05:08 +02004588 if (cert_peer)
4589 crt = SSL_get_peer_certificate(conn->xprt_ctx);
4590 else
4591 crt = SSL_get_certificate(conn->xprt_ctx);
4592
Willy Tarreau8d598402012-10-22 17:58:39 +02004593 if (!crt)
4594 goto out;
4595
Willy Tarreau47ca5452012-12-23 20:22:19 +01004596 smp_trash = get_trash_chunk();
Willy Tarreau8d598402012-10-22 17:58:39 +02004597 if (ssl_sock_get_serial(crt, smp_trash) <= 0)
4598 goto out;
4599
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004600 smp->data.u.str = *smp_trash;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004601 smp->data.type = SMP_T_BIN;
Willy Tarreau8d598402012-10-22 17:58:39 +02004602 ret = 1;
4603out:
Emeric Brunba841a12014-04-30 17:05:08 +02004604 /* SSL_get_peer_certificate, it increase X509 * ref count */
4605 if (cert_peer && crt)
Willy Tarreau8d598402012-10-22 17:58:39 +02004606 X509_free(crt);
4607 return ret;
4608}
Emeric Brune64aef12012-09-21 13:15:06 +02004609
Emeric Brunba841a12014-04-30 17:05:08 +02004610/* binary, returns the client certificate's SHA-1 fingerprint (SHA-1 hash of DER-encoded certificate) in a binary chunk.
4611 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
4612 * should be use.
4613 */
James Votha051b4a2013-05-14 20:37:59 +02004614static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004615smp_fetch_ssl_x_sha1(const struct arg *args, struct sample *smp, const char *kw, void *private)
James Votha051b4a2013-05-14 20:37:59 +02004616{
Emeric Brunba841a12014-04-30 17:05:08 +02004617 int cert_peer = (kw[4] == 'c') ? 1 : 0;
James Votha051b4a2013-05-14 20:37:59 +02004618 X509 *crt = NULL;
4619 const EVP_MD *digest;
4620 int ret = 0;
4621 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004622 struct connection *conn;
James Votha051b4a2013-05-14 20:37:59 +02004623
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004624 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004625 if (!conn || conn->xprt != &ssl_sock)
4626 return 0;
4627
4628 if (!(conn->flags & CO_FL_CONNECTED)) {
James Votha051b4a2013-05-14 20:37:59 +02004629 smp->flags |= SMP_F_MAY_CHANGE;
4630 return 0;
4631 }
4632
Emeric Brunba841a12014-04-30 17:05:08 +02004633 if (cert_peer)
4634 crt = SSL_get_peer_certificate(conn->xprt_ctx);
4635 else
4636 crt = SSL_get_certificate(conn->xprt_ctx);
James Votha051b4a2013-05-14 20:37:59 +02004637 if (!crt)
4638 goto out;
4639
4640 smp_trash = get_trash_chunk();
4641 digest = EVP_sha1();
4642 X509_digest(crt, digest, (unsigned char *)smp_trash->str, (unsigned int *)&smp_trash->len);
4643
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004644 smp->data.u.str = *smp_trash;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004645 smp->data.type = SMP_T_BIN;
James Votha051b4a2013-05-14 20:37:59 +02004646 ret = 1;
4647out:
Emeric Brunba841a12014-04-30 17:05:08 +02004648 /* SSL_get_peer_certificate, it increase X509 * ref count */
4649 if (cert_peer && crt)
James Votha051b4a2013-05-14 20:37:59 +02004650 X509_free(crt);
4651 return ret;
4652}
4653
Emeric Brunba841a12014-04-30 17:05:08 +02004654/* string, returns certificate's notafter date in ASN1_UTCTIME format.
4655 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
4656 * should be use.
4657 */
Emeric Brunce5ad802012-10-22 14:11:22 +02004658static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004659smp_fetch_ssl_x_notafter(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brunce5ad802012-10-22 14:11:22 +02004660{
Emeric Brunba841a12014-04-30 17:05:08 +02004661 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brunce5ad802012-10-22 14:11:22 +02004662 X509 *crt = NULL;
4663 int ret = 0;
4664 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004665 struct connection *conn;
Emeric Brunce5ad802012-10-22 14:11:22 +02004666
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004667 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004668 if (!conn || conn->xprt != &ssl_sock)
4669 return 0;
4670
4671 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunce5ad802012-10-22 14:11:22 +02004672 smp->flags |= SMP_F_MAY_CHANGE;
4673 return 0;
4674 }
4675
Emeric Brunba841a12014-04-30 17:05:08 +02004676 if (cert_peer)
4677 crt = SSL_get_peer_certificate(conn->xprt_ctx);
4678 else
4679 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brunce5ad802012-10-22 14:11:22 +02004680 if (!crt)
4681 goto out;
4682
Willy Tarreau47ca5452012-12-23 20:22:19 +01004683 smp_trash = get_trash_chunk();
Emeric Brunce5ad802012-10-22 14:11:22 +02004684 if (ssl_sock_get_time(X509_get_notAfter(crt), smp_trash) <= 0)
4685 goto out;
4686
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004687 smp->data.u.str = *smp_trash;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004688 smp->data.type = SMP_T_STR;
Emeric Brunce5ad802012-10-22 14:11:22 +02004689 ret = 1;
4690out:
Emeric Brunba841a12014-04-30 17:05:08 +02004691 /* SSL_get_peer_certificate, it increase X509 * ref count */
4692 if (cert_peer && crt)
Emeric Brunce5ad802012-10-22 14:11:22 +02004693 X509_free(crt);
4694 return ret;
4695}
4696
Emeric Brunba841a12014-04-30 17:05:08 +02004697/* string, returns a string of a formatted full dn \C=..\O=..\OU=.. \CN=.. of certificate's issuer
4698 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
4699 * should be use.
4700 */
Emeric Brun87855892012-10-17 17:39:35 +02004701static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004702smp_fetch_ssl_x_i_dn(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun87855892012-10-17 17:39:35 +02004703{
Emeric Brunba841a12014-04-30 17:05:08 +02004704 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brun87855892012-10-17 17:39:35 +02004705 X509 *crt = NULL;
4706 X509_NAME *name;
4707 int ret = 0;
4708 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004709 struct connection *conn;
Emeric Brun87855892012-10-17 17:39:35 +02004710
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004711 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004712 if (!conn || conn->xprt != &ssl_sock)
4713 return 0;
4714
4715 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun87855892012-10-17 17:39:35 +02004716 smp->flags |= SMP_F_MAY_CHANGE;
4717 return 0;
4718 }
4719
Emeric Brunba841a12014-04-30 17:05:08 +02004720 if (cert_peer)
4721 crt = SSL_get_peer_certificate(conn->xprt_ctx);
4722 else
4723 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brun87855892012-10-17 17:39:35 +02004724 if (!crt)
4725 goto out;
4726
4727 name = X509_get_issuer_name(crt);
4728 if (!name)
4729 goto out;
4730
Willy Tarreau47ca5452012-12-23 20:22:19 +01004731 smp_trash = get_trash_chunk();
Emeric Brun87855892012-10-17 17:39:35 +02004732 if (args && args[0].type == ARGT_STR) {
4733 int pos = 1;
4734
4735 if (args[1].type == ARGT_SINT)
4736 pos = args[1].data.sint;
Emeric Brun87855892012-10-17 17:39:35 +02004737
4738 if (ssl_sock_get_dn_entry(name, &args[0].data.str, pos, smp_trash) <= 0)
4739 goto out;
4740 }
4741 else if (ssl_sock_get_dn_oneline(name, smp_trash) <= 0)
4742 goto out;
4743
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004744 smp->data.type = SMP_T_STR;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004745 smp->data.u.str = *smp_trash;
Emeric Brun87855892012-10-17 17:39:35 +02004746 ret = 1;
4747out:
Emeric Brunba841a12014-04-30 17:05:08 +02004748 /* SSL_get_peer_certificate, it increase X509 * ref count */
4749 if (cert_peer && crt)
Emeric Brun87855892012-10-17 17:39:35 +02004750 X509_free(crt);
4751 return ret;
4752}
4753
Emeric Brunba841a12014-04-30 17:05:08 +02004754/* string, returns notbefore date in ASN1_UTCTIME format.
4755 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
4756 * should be use.
4757 */
Emeric Brunce5ad802012-10-22 14:11:22 +02004758static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004759smp_fetch_ssl_x_notbefore(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brunce5ad802012-10-22 14:11:22 +02004760{
Emeric Brunba841a12014-04-30 17:05:08 +02004761 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brunce5ad802012-10-22 14:11:22 +02004762 X509 *crt = NULL;
4763 int ret = 0;
4764 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004765 struct connection *conn;
4766
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004767 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004768 if (!conn || conn->xprt != &ssl_sock)
Emeric Brunce5ad802012-10-22 14:11:22 +02004769 return 0;
4770
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004771 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunce5ad802012-10-22 14:11:22 +02004772 smp->flags |= SMP_F_MAY_CHANGE;
4773 return 0;
4774 }
4775
Emeric Brunba841a12014-04-30 17:05:08 +02004776 if (cert_peer)
4777 crt = SSL_get_peer_certificate(conn->xprt_ctx);
4778 else
4779 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brunce5ad802012-10-22 14:11:22 +02004780 if (!crt)
4781 goto out;
4782
Willy Tarreau47ca5452012-12-23 20:22:19 +01004783 smp_trash = get_trash_chunk();
Emeric Brunce5ad802012-10-22 14:11:22 +02004784 if (ssl_sock_get_time(X509_get_notBefore(crt), smp_trash) <= 0)
4785 goto out;
4786
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004787 smp->data.u.str = *smp_trash;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004788 smp->data.type = SMP_T_STR;
Emeric Brunce5ad802012-10-22 14:11:22 +02004789 ret = 1;
4790out:
Emeric Brunba841a12014-04-30 17:05:08 +02004791 /* SSL_get_peer_certificate, it increase X509 * ref count */
4792 if (cert_peer && crt)
Emeric Brunce5ad802012-10-22 14:11:22 +02004793 X509_free(crt);
4794 return ret;
4795}
4796
Emeric Brunba841a12014-04-30 17:05:08 +02004797/* string, returns a string of a formatted full dn \C=..\O=..\OU=.. \CN=.. of certificate's subject
4798 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
4799 * should be use.
4800 */
Emeric Brun87855892012-10-17 17:39:35 +02004801static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004802smp_fetch_ssl_x_s_dn(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun87855892012-10-17 17:39:35 +02004803{
Emeric Brunba841a12014-04-30 17:05:08 +02004804 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brun87855892012-10-17 17:39:35 +02004805 X509 *crt = NULL;
4806 X509_NAME *name;
4807 int ret = 0;
4808 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004809 struct connection *conn;
Emeric Brun87855892012-10-17 17:39:35 +02004810
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004811 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004812 if (!conn || conn->xprt != &ssl_sock)
4813 return 0;
4814
4815 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun87855892012-10-17 17:39:35 +02004816 smp->flags |= SMP_F_MAY_CHANGE;
4817 return 0;
4818 }
4819
Emeric Brunba841a12014-04-30 17:05:08 +02004820 if (cert_peer)
4821 crt = SSL_get_peer_certificate(conn->xprt_ctx);
4822 else
4823 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brun87855892012-10-17 17:39:35 +02004824 if (!crt)
4825 goto out;
4826
4827 name = X509_get_subject_name(crt);
4828 if (!name)
4829 goto out;
4830
Willy Tarreau47ca5452012-12-23 20:22:19 +01004831 smp_trash = get_trash_chunk();
Emeric Brun87855892012-10-17 17:39:35 +02004832 if (args && args[0].type == ARGT_STR) {
4833 int pos = 1;
4834
4835 if (args[1].type == ARGT_SINT)
4836 pos = args[1].data.sint;
Emeric Brun87855892012-10-17 17:39:35 +02004837
4838 if (ssl_sock_get_dn_entry(name, &args[0].data.str, pos, smp_trash) <= 0)
4839 goto out;
4840 }
4841 else if (ssl_sock_get_dn_oneline(name, smp_trash) <= 0)
4842 goto out;
4843
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004844 smp->data.type = SMP_T_STR;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004845 smp->data.u.str = *smp_trash;
Emeric Brun87855892012-10-17 17:39:35 +02004846 ret = 1;
4847out:
Emeric Brunba841a12014-04-30 17:05:08 +02004848 /* SSL_get_peer_certificate, it increase X509 * ref count */
4849 if (cert_peer && crt)
Emeric Brun87855892012-10-17 17:39:35 +02004850 X509_free(crt);
4851 return ret;
4852}
Emeric Brun9143d372012-12-20 15:44:16 +01004853
4854/* integer, returns true if current session use a client certificate */
4855static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004856smp_fetch_ssl_c_used(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun9143d372012-12-20 15:44:16 +01004857{
4858 X509 *crt;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004859 struct connection *conn;
Emeric Brun9143d372012-12-20 15:44:16 +01004860
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004861 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004862 if (!conn || conn->xprt != &ssl_sock)
4863 return 0;
4864
4865 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun9143d372012-12-20 15:44:16 +01004866 smp->flags |= SMP_F_MAY_CHANGE;
4867 return 0;
4868 }
4869
4870 /* SSL_get_peer_certificate returns a ptr on allocated X509 struct */
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004871 crt = SSL_get_peer_certificate(conn->xprt_ctx);
Emeric Brun9143d372012-12-20 15:44:16 +01004872 if (crt) {
4873 X509_free(crt);
4874 }
4875
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004876 smp->data.type = SMP_T_BOOL;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004877 smp->data.u.sint = (crt != NULL);
Emeric Brun9143d372012-12-20 15:44:16 +01004878 return 1;
4879}
4880
Emeric Brunba841a12014-04-30 17:05:08 +02004881/* integer, returns the certificate version
4882 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
4883 * should be use.
4884 */
Emeric Bruna7359fd2012-10-17 15:03:11 +02004885static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004886smp_fetch_ssl_x_version(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Bruna7359fd2012-10-17 15:03:11 +02004887{
Emeric Brunba841a12014-04-30 17:05:08 +02004888 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Bruna7359fd2012-10-17 15:03:11 +02004889 X509 *crt;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004890 struct connection *conn;
4891
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004892 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004893 if (!conn || conn->xprt != &ssl_sock)
Emeric Bruna7359fd2012-10-17 15:03:11 +02004894 return 0;
4895
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004896 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Bruna7359fd2012-10-17 15:03:11 +02004897 smp->flags |= SMP_F_MAY_CHANGE;
4898 return 0;
4899 }
4900
Emeric Brunba841a12014-04-30 17:05:08 +02004901 if (cert_peer)
4902 crt = SSL_get_peer_certificate(conn->xprt_ctx);
4903 else
4904 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Bruna7359fd2012-10-17 15:03:11 +02004905 if (!crt)
4906 return 0;
4907
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004908 smp->data.u.sint = (unsigned int)(1 + X509_get_version(crt));
Emeric Brunba841a12014-04-30 17:05:08 +02004909 /* SSL_get_peer_certificate increase X509 * ref count */
4910 if (cert_peer)
4911 X509_free(crt);
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004912 smp->data.type = SMP_T_SINT;
Emeric Bruna7359fd2012-10-17 15:03:11 +02004913
4914 return 1;
4915}
4916
Emeric Brunba841a12014-04-30 17:05:08 +02004917/* string, returns the certificate's signature algorithm.
4918 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
4919 * should be use.
4920 */
Emeric Brun7f56e742012-10-19 18:15:40 +02004921static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004922smp_fetch_ssl_x_sig_alg(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun7f56e742012-10-19 18:15:40 +02004923{
Emeric Brunba841a12014-04-30 17:05:08 +02004924 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brun7f56e742012-10-19 18:15:40 +02004925 X509 *crt;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004926 __OPENSSL_110_CONST__ ASN1_OBJECT *algorithm;
Emeric Brun7f56e742012-10-19 18:15:40 +02004927 int nid;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004928 struct connection *conn;
Emeric Brun7f56e742012-10-19 18:15:40 +02004929
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004930 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004931 if (!conn || conn->xprt != &ssl_sock)
4932 return 0;
4933
4934 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun7f56e742012-10-19 18:15:40 +02004935 smp->flags |= SMP_F_MAY_CHANGE;
4936 return 0;
4937 }
4938
Emeric Brunba841a12014-04-30 17:05:08 +02004939 if (cert_peer)
4940 crt = SSL_get_peer_certificate(conn->xprt_ctx);
4941 else
4942 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brun7f56e742012-10-19 18:15:40 +02004943 if (!crt)
4944 return 0;
4945
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004946 X509_ALGOR_get0(&algorithm, NULL, NULL, X509_get0_tbs_sigalg(crt));
4947 nid = OBJ_obj2nid(algorithm);
Emeric Brun7f56e742012-10-19 18:15:40 +02004948
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004949 smp->data.u.str.str = (char *)OBJ_nid2sn(nid);
4950 if (!smp->data.u.str.str) {
Emeric Brunba841a12014-04-30 17:05:08 +02004951 /* SSL_get_peer_certificate increase X509 * ref count */
4952 if (cert_peer)
4953 X509_free(crt);
Emeric Brun7f56e742012-10-19 18:15:40 +02004954 return 0;
Emeric Brun9bf3ba22013-10-07 14:31:44 +02004955 }
Emeric Brun7f56e742012-10-19 18:15:40 +02004956
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004957 smp->data.type = SMP_T_STR;
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01004958 smp->flags |= SMP_F_CONST;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004959 smp->data.u.str.len = strlen(smp->data.u.str.str);
Emeric Brunba841a12014-04-30 17:05:08 +02004960 /* SSL_get_peer_certificate increase X509 * ref count */
4961 if (cert_peer)
4962 X509_free(crt);
Emeric Brun7f56e742012-10-19 18:15:40 +02004963
4964 return 1;
4965}
4966
Emeric Brunba841a12014-04-30 17:05:08 +02004967/* string, returns the certificate's key algorithm.
4968 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
4969 * should be use.
4970 */
Emeric Brun521a0112012-10-22 12:22:55 +02004971static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004972smp_fetch_ssl_x_key_alg(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun521a0112012-10-22 12:22:55 +02004973{
Emeric Brunba841a12014-04-30 17:05:08 +02004974 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brun521a0112012-10-22 12:22:55 +02004975 X509 *crt;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004976 ASN1_OBJECT *algorithm;
Emeric Brun521a0112012-10-22 12:22:55 +02004977 int nid;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004978 struct connection *conn;
Emeric Brun521a0112012-10-22 12:22:55 +02004979
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004980 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004981 if (!conn || conn->xprt != &ssl_sock)
4982 return 0;
4983
4984 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun521a0112012-10-22 12:22:55 +02004985 smp->flags |= SMP_F_MAY_CHANGE;
4986 return 0;
4987 }
4988
Emeric Brunba841a12014-04-30 17:05:08 +02004989 if (cert_peer)
4990 crt = SSL_get_peer_certificate(conn->xprt_ctx);
4991 else
4992 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brun521a0112012-10-22 12:22:55 +02004993 if (!crt)
4994 return 0;
4995
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004996 X509_PUBKEY_get0_param(&algorithm, NULL, NULL, NULL, X509_get_X509_PUBKEY(crt));
4997 nid = OBJ_obj2nid(algorithm);
Emeric Brun521a0112012-10-22 12:22:55 +02004998
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004999 smp->data.u.str.str = (char *)OBJ_nid2sn(nid);
5000 if (!smp->data.u.str.str) {
Emeric Brunba841a12014-04-30 17:05:08 +02005001 /* SSL_get_peer_certificate increase X509 * ref count */
5002 if (cert_peer)
5003 X509_free(crt);
Emeric Brun521a0112012-10-22 12:22:55 +02005004 return 0;
Emeric Brun9bf3ba22013-10-07 14:31:44 +02005005 }
Emeric Brun521a0112012-10-22 12:22:55 +02005006
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005007 smp->data.type = SMP_T_STR;
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01005008 smp->flags |= SMP_F_CONST;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005009 smp->data.u.str.len = strlen(smp->data.u.str.str);
Emeric Brunba841a12014-04-30 17:05:08 +02005010 if (cert_peer)
5011 X509_free(crt);
Emeric Brun521a0112012-10-22 12:22:55 +02005012
5013 return 1;
5014}
5015
Emeric Brun645ae792014-04-30 14:21:06 +02005016/* boolean, returns true if front conn. transport layer is SSL.
5017 * This function is also usable on backend conn if the fetch keyword 5th
5018 * char is 'b'.
5019 */
Willy Tarreau7875d092012-09-10 08:20:03 +02005020static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005021smp_fetch_ssl_fc(const struct arg *args, struct sample *smp, const char *kw, void *private)
Willy Tarreau7875d092012-09-10 08:20:03 +02005022{
Willy Tarreaue237fe12016-03-10 17:05:28 +01005023 struct connection *conn = objt_conn((kw[4] != 'b') ? smp->sess->origin :
5024 smp->strm ? smp->strm->si[1].end : NULL);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005025
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005026 smp->data.type = SMP_T_BOOL;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005027 smp->data.u.sint = (conn && conn->xprt == &ssl_sock);
Willy Tarreau7875d092012-09-10 08:20:03 +02005028 return 1;
5029}
5030
Emeric Brun2525b6b2012-10-18 15:59:43 +02005031/* boolean, returns true if client present a SNI */
Willy Tarreau7875d092012-09-10 08:20:03 +02005032static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005033smp_fetch_ssl_fc_has_sni(const struct arg *args, struct sample *smp, const char *kw, void *private)
Willy Tarreau7875d092012-09-10 08:20:03 +02005034{
5035#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02005036 struct connection *conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005037
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005038 smp->data.type = SMP_T_BOOL;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005039 smp->data.u.sint = (conn && conn->xprt == &ssl_sock) &&
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005040 conn->xprt_ctx &&
5041 SSL_get_servername(conn->xprt_ctx, TLSEXT_NAMETYPE_host_name) != NULL;
Willy Tarreau7875d092012-09-10 08:20:03 +02005042 return 1;
5043#else
5044 return 0;
5045#endif
5046}
5047
Nenad Merdanovic26ea8222015-05-18 02:28:57 +02005048/* boolean, returns true if client session has been resumed */
5049static int
5050smp_fetch_ssl_fc_is_resumed(const struct arg *args, struct sample *smp, const char *kw, void *private)
5051{
5052 struct connection *conn = objt_conn(smp->sess->origin);
5053
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005054 smp->data.type = SMP_T_BOOL;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005055 smp->data.u.sint = (conn && conn->xprt == &ssl_sock) &&
Nenad Merdanovic26ea8222015-05-18 02:28:57 +02005056 conn->xprt_ctx &&
5057 SSL_session_reused(conn->xprt_ctx);
5058 return 1;
5059}
5060
Emeric Brun645ae792014-04-30 14:21:06 +02005061/* string, returns the used cipher if front conn. transport layer is SSL.
5062 * This function is also usable on backend conn if the fetch keyword 5th
5063 * char is 'b'.
5064 */
Emeric Brun589fcad2012-10-16 14:13:26 +02005065static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005066smp_fetch_ssl_fc_cipher(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun589fcad2012-10-16 14:13:26 +02005067{
Willy Tarreaue237fe12016-03-10 17:05:28 +01005068 struct connection *conn = objt_conn((kw[4] != 'b') ? smp->sess->origin :
5069 smp->strm ? smp->strm->si[1].end : NULL);
Emeric Brun589fcad2012-10-16 14:13:26 +02005070
Willy Tarreaube508f12016-03-10 11:47:01 +01005071 smp->flags = 0;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005072 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
Emeric Brun589fcad2012-10-16 14:13:26 +02005073 return 0;
5074
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005075 smp->data.u.str.str = (char *)SSL_get_cipher_name(conn->xprt_ctx);
5076 if (!smp->data.u.str.str)
Emeric Brun589fcad2012-10-16 14:13:26 +02005077 return 0;
5078
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005079 smp->data.type = SMP_T_STR;
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01005080 smp->flags |= SMP_F_CONST;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005081 smp->data.u.str.len = strlen(smp->data.u.str.str);
Emeric Brun589fcad2012-10-16 14:13:26 +02005082
5083 return 1;
5084}
5085
Emeric Brun645ae792014-04-30 14:21:06 +02005086/* integer, returns the algoritm's keysize if front conn. transport layer
5087 * is SSL.
5088 * This function is also usable on backend conn if the fetch keyword 5th
5089 * char is 'b'.
5090 */
Emeric Brun589fcad2012-10-16 14:13:26 +02005091static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005092smp_fetch_ssl_fc_alg_keysize(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun589fcad2012-10-16 14:13:26 +02005093{
Willy Tarreaue237fe12016-03-10 17:05:28 +01005094 struct connection *conn = objt_conn((kw[4] != 'b') ? smp->sess->origin :
5095 smp->strm ? smp->strm->si[1].end : NULL);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005096
Willy Tarreaue237fe12016-03-10 17:05:28 +01005097 int sint;
Willy Tarreaube508f12016-03-10 11:47:01 +01005098
Emeric Brun589fcad2012-10-16 14:13:26 +02005099 smp->flags = 0;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005100 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
Emeric Brun589fcad2012-10-16 14:13:26 +02005101 return 0;
5102
Thierry FOURNIER07ee64e2015-07-06 23:43:03 +02005103 if (!SSL_get_cipher_bits(conn->xprt_ctx, &sint))
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005104 return 0;
5105
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005106 smp->data.u.sint = sint;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005107 smp->data.type = SMP_T_SINT;
Emeric Brun589fcad2012-10-16 14:13:26 +02005108
5109 return 1;
5110}
5111
Emeric Brun645ae792014-04-30 14:21:06 +02005112/* integer, returns the used keysize if front conn. transport layer is SSL.
5113 * This function is also usable on backend conn if the fetch keyword 5th
5114 * char is 'b'.
5115 */
Emeric Brun589fcad2012-10-16 14:13:26 +02005116static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005117smp_fetch_ssl_fc_use_keysize(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun589fcad2012-10-16 14:13:26 +02005118{
Willy Tarreaue237fe12016-03-10 17:05:28 +01005119 struct connection *conn = objt_conn((kw[4] != 'b') ? smp->sess->origin :
5120 smp->strm ? smp->strm->si[1].end : NULL);
Willy Tarreaube508f12016-03-10 11:47:01 +01005121
Emeric Brun589fcad2012-10-16 14:13:26 +02005122 smp->flags = 0;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005123 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
5124 return 0;
5125
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005126 smp->data.u.sint = (unsigned int)SSL_get_cipher_bits(conn->xprt_ctx, NULL);
5127 if (!smp->data.u.sint)
Emeric Brun589fcad2012-10-16 14:13:26 +02005128 return 0;
5129
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005130 smp->data.type = SMP_T_SINT;
Emeric Brun589fcad2012-10-16 14:13:26 +02005131
5132 return 1;
5133}
5134
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02005135#ifdef OPENSSL_NPN_NEGOTIATED
Willy Tarreau7875d092012-09-10 08:20:03 +02005136static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005137smp_fetch_ssl_fc_npn(const struct arg *args, struct sample *smp, const char *kw, void *private)
Willy Tarreaua33c6542012-10-15 13:19:06 +02005138{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005139 struct connection *conn;
5140
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01005141 smp->flags = SMP_F_CONST;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005142 smp->data.type = SMP_T_STR;
Willy Tarreaua33c6542012-10-15 13:19:06 +02005143
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02005144 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005145 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
5146 return 0;
5147
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005148 smp->data.u.str.str = NULL;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005149 SSL_get0_next_proto_negotiated(conn->xprt_ctx,
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005150 (const unsigned char **)&smp->data.u.str.str, (unsigned *)&smp->data.u.str.len);
Willy Tarreaua33c6542012-10-15 13:19:06 +02005151
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005152 if (!smp->data.u.str.str)
Willy Tarreaua33c6542012-10-15 13:19:06 +02005153 return 0;
5154
5155 return 1;
Willy Tarreaua33c6542012-10-15 13:19:06 +02005156}
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02005157#endif
Willy Tarreaua33c6542012-10-15 13:19:06 +02005158
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01005159#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Willy Tarreauab861d32013-04-02 02:30:41 +02005160static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005161smp_fetch_ssl_fc_alpn(const struct arg *args, struct sample *smp, const char *kw, void *private)
Willy Tarreauab861d32013-04-02 02:30:41 +02005162{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005163 struct connection *conn;
5164
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01005165 smp->flags = SMP_F_CONST;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005166 smp->data.type = SMP_T_STR;
Willy Tarreauab861d32013-04-02 02:30:41 +02005167
Willy Tarreaue26bf052015-05-12 10:30:12 +02005168 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005169 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
Willy Tarreauab861d32013-04-02 02:30:41 +02005170 return 0;
5171
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005172 smp->data.u.str.str = NULL;
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01005173 SSL_get0_alpn_selected(conn->xprt_ctx,
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005174 (const unsigned char **)&smp->data.u.str.str, (unsigned *)&smp->data.u.str.len);
Willy Tarreauab861d32013-04-02 02:30:41 +02005175
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005176 if (!smp->data.u.str.str)
Willy Tarreauab861d32013-04-02 02:30:41 +02005177 return 0;
5178
5179 return 1;
5180}
5181#endif
5182
Emeric Brun645ae792014-04-30 14:21:06 +02005183/* string, returns the used protocol if front conn. transport layer is SSL.
5184 * This function is also usable on backend conn if the fetch keyword 5th
5185 * char is 'b'.
5186 */
Willy Tarreaua33c6542012-10-15 13:19:06 +02005187static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005188smp_fetch_ssl_fc_protocol(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun589fcad2012-10-16 14:13:26 +02005189{
Willy Tarreaue237fe12016-03-10 17:05:28 +01005190 struct connection *conn = objt_conn((kw[4] != 'b') ? smp->sess->origin :
5191 smp->strm ? smp->strm->si[1].end : NULL);
Willy Tarreaube508f12016-03-10 11:47:01 +01005192
Emeric Brun589fcad2012-10-16 14:13:26 +02005193 smp->flags = 0;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005194 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
5195 return 0;
5196
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005197 smp->data.u.str.str = (char *)SSL_get_version(conn->xprt_ctx);
5198 if (!smp->data.u.str.str)
Emeric Brun589fcad2012-10-16 14:13:26 +02005199 return 0;
5200
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005201 smp->data.type = SMP_T_STR;
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01005202 smp->flags = SMP_F_CONST;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005203 smp->data.u.str.len = strlen(smp->data.u.str.str);
Emeric Brun589fcad2012-10-16 14:13:26 +02005204
5205 return 1;
5206}
5207
Willy Tarreau87b09662015-04-03 00:22:06 +02005208/* binary, returns the SSL stream id if front conn. transport layer is SSL.
Emeric Brun645ae792014-04-30 14:21:06 +02005209 * This function is also usable on backend conn if the fetch keyword 5th
5210 * char is 'b'.
5211 */
Emeric Brun589fcad2012-10-16 14:13:26 +02005212static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005213smp_fetch_ssl_fc_session_id(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brunfe68f682012-10-16 14:59:28 +02005214{
5215#if OPENSSL_VERSION_NUMBER > 0x0090800fL
Willy Tarreaue237fe12016-03-10 17:05:28 +01005216 struct connection *conn = objt_conn((kw[4] != 'b') ? smp->sess->origin :
5217 smp->strm ? smp->strm->si[1].end : NULL);
Emeric Brunfe68f682012-10-16 14:59:28 +02005218
Willy Tarreaue237fe12016-03-10 17:05:28 +01005219 SSL_SESSION *ssl_sess;
Willy Tarreaube508f12016-03-10 11:47:01 +01005220
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01005221 smp->flags = SMP_F_CONST;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005222 smp->data.type = SMP_T_BIN;
Emeric Brunfe68f682012-10-16 14:59:28 +02005223
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005224 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
5225 return 0;
5226
Willy Tarreau192252e2015-04-04 01:47:55 +02005227 ssl_sess = SSL_get_session(conn->xprt_ctx);
5228 if (!ssl_sess)
Emeric Brunfe68f682012-10-16 14:59:28 +02005229 return 0;
5230
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005231 smp->data.u.str.str = (char *)SSL_SESSION_get_id(ssl_sess, (unsigned int *)&smp->data.u.str.len);
5232 if (!smp->data.u.str.str || !smp->data.u.str.len)
Emeric Brunfe68f682012-10-16 14:59:28 +02005233 return 0;
5234
5235 return 1;
5236#else
5237 return 0;
5238#endif
5239}
5240
5241static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005242smp_fetch_ssl_fc_sni(const struct arg *args, struct sample *smp, const char *kw, void *private)
Willy Tarreau7875d092012-09-10 08:20:03 +02005243{
5244#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005245 struct connection *conn;
5246
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01005247 smp->flags = SMP_F_CONST;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005248 smp->data.type = SMP_T_STR;
Willy Tarreau7875d092012-09-10 08:20:03 +02005249
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02005250 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005251 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
5252 return 0;
5253
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005254 smp->data.u.str.str = (char *)SSL_get_servername(conn->xprt_ctx, TLSEXT_NAMETYPE_host_name);
5255 if (!smp->data.u.str.str)
Willy Tarreau3e394c92012-09-14 23:56:58 +02005256 return 0;
5257
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005258 smp->data.u.str.len = strlen(smp->data.u.str.str);
Willy Tarreau7875d092012-09-10 08:20:03 +02005259 return 1;
5260#else
5261 return 0;
5262#endif
5263}
5264
David Sc1ad52e2014-04-08 18:48:47 -04005265static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005266smp_fetch_ssl_fc_unique_id(const struct arg *args, struct sample *smp, const char *kw, void *private)
David Sc1ad52e2014-04-08 18:48:47 -04005267{
5268#if OPENSSL_VERSION_NUMBER > 0x0090800fL
Willy Tarreaue237fe12016-03-10 17:05:28 +01005269 struct connection *conn = objt_conn((kw[4] != 'b') ? smp->sess->origin :
5270 smp->strm ? smp->strm->si[1].end : NULL);
5271
David Sc1ad52e2014-04-08 18:48:47 -04005272 int finished_len;
David Sc1ad52e2014-04-08 18:48:47 -04005273 struct chunk *finished_trash;
David Sc1ad52e2014-04-08 18:48:47 -04005274
5275 smp->flags = 0;
David Sc1ad52e2014-04-08 18:48:47 -04005276 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
5277 return 0;
5278
5279 if (!(conn->flags & CO_FL_CONNECTED)) {
5280 smp->flags |= SMP_F_MAY_CHANGE;
5281 return 0;
5282 }
5283
5284 finished_trash = get_trash_chunk();
5285 if (!SSL_session_reused(conn->xprt_ctx))
5286 finished_len = SSL_get_peer_finished(conn->xprt_ctx, finished_trash->str, finished_trash->size);
5287 else
5288 finished_len = SSL_get_finished(conn->xprt_ctx, finished_trash->str, finished_trash->size);
5289
5290 if (!finished_len)
5291 return 0;
5292
Emeric Brunb73a9b02014-04-30 18:49:19 +02005293 finished_trash->len = finished_len;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005294 smp->data.u.str = *finished_trash;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005295 smp->data.type = SMP_T_BIN;
David Sc1ad52e2014-04-08 18:48:47 -04005296
5297 return 1;
5298#else
5299 return 0;
5300#endif
5301}
5302
Emeric Brun2525b6b2012-10-18 15:59:43 +02005303/* integer, returns the first verify error in CA chain of client certificate chain. */
Emeric Brunf282a812012-09-21 15:27:54 +02005304static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005305smp_fetch_ssl_c_ca_err(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brunf282a812012-09-21 15:27:54 +02005306{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005307 struct connection *conn;
5308
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02005309 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005310 if (!conn || conn->xprt != &ssl_sock)
5311 return 0;
5312
5313 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunf282a812012-09-21 15:27:54 +02005314 smp->flags = SMP_F_MAY_CHANGE;
5315 return 0;
5316 }
5317
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005318 smp->data.type = SMP_T_SINT;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005319 smp->data.u.sint = (unsigned long long int)SSL_SOCK_ST_TO_CA_ERROR(conn->xprt_st);
Emeric Brunf282a812012-09-21 15:27:54 +02005320 smp->flags = 0;
5321
5322 return 1;
5323}
5324
Emeric Brun2525b6b2012-10-18 15:59:43 +02005325/* integer, returns the depth of the first verify error in CA chain of client certificate chain. */
Emeric Brunf282a812012-09-21 15:27:54 +02005326static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005327smp_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 +02005328{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005329 struct connection *conn;
5330
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02005331 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005332 if (!conn || conn->xprt != &ssl_sock)
Emeric Brunf282a812012-09-21 15:27:54 +02005333 return 0;
5334
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005335 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunf282a812012-09-21 15:27:54 +02005336 smp->flags = SMP_F_MAY_CHANGE;
5337 return 0;
5338 }
5339
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005340 smp->data.type = SMP_T_SINT;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005341 smp->data.u.sint = (long long int)SSL_SOCK_ST_TO_CAEDEPTH(conn->xprt_st);
Emeric Brunf282a812012-09-21 15:27:54 +02005342 smp->flags = 0;
5343
5344 return 1;
5345}
5346
Emeric Brun2525b6b2012-10-18 15:59:43 +02005347/* integer, returns the first verify error on client certificate */
Emeric Brunf282a812012-09-21 15:27:54 +02005348static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005349smp_fetch_ssl_c_err(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brunf282a812012-09-21 15:27:54 +02005350{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005351 struct connection *conn;
5352
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02005353 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005354 if (!conn || conn->xprt != &ssl_sock)
5355 return 0;
5356
5357 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunf282a812012-09-21 15:27:54 +02005358 smp->flags = SMP_F_MAY_CHANGE;
5359 return 0;
5360 }
5361
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005362 smp->data.type = SMP_T_SINT;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005363 smp->data.u.sint = (long long int)SSL_SOCK_ST_TO_CRTERROR(conn->xprt_st);
Emeric Brunf282a812012-09-21 15:27:54 +02005364 smp->flags = 0;
5365
5366 return 1;
5367}
5368
Emeric Brun2525b6b2012-10-18 15:59:43 +02005369/* integer, returns the verify result on client cert */
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02005370static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005371smp_fetch_ssl_c_verify(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02005372{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005373 struct connection *conn;
5374
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02005375 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005376 if (!conn || conn->xprt != &ssl_sock)
5377 return 0;
5378
5379 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02005380 smp->flags = SMP_F_MAY_CHANGE;
5381 return 0;
5382 }
5383
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005384 if (!conn->xprt_ctx)
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02005385 return 0;
5386
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005387 smp->data.type = SMP_T_SINT;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005388 smp->data.u.sint = (long long int)SSL_get_verify_result(conn->xprt_ctx);
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02005389 smp->flags = 0;
5390
5391 return 1;
5392}
5393
Emeric Brunfb510ea2012-10-05 12:00:26 +02005394/* parse the "ca-file" bind keyword */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01005395static 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 +02005396{
5397 if (!*args[cur_arg + 1]) {
5398 if (err)
5399 memprintf(err, "'%s' : missing CAfile path", args[cur_arg]);
5400 return ERR_ALERT | ERR_FATAL;
5401 }
5402
Willy Tarreauef934602016-12-22 23:12:01 +01005403 if ((*args[cur_arg + 1] != '/') && global_ssl.ca_base)
5404 memprintf(&conf->ca_file, "%s/%s", global_ssl.ca_base, args[cur_arg + 1]);
Emeric Brunef42d922012-10-11 16:11:36 +02005405 else
5406 memprintf(&conf->ca_file, "%s", args[cur_arg + 1]);
Emeric Brunc8e8d122012-10-02 18:42:10 +02005407
Emeric Brund94b3fe2012-09-20 18:23:56 +02005408 return 0;
5409}
Emmanuel Hocdet98263292016-12-29 18:26:15 +01005410static int bind_parse_ca_file(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5411{
5412 return ssl_bind_parse_ca_file(args, cur_arg, px, &conf->ssl_conf, err);
5413}
Emeric Brund94b3fe2012-09-20 18:23:56 +02005414
Christopher Faulet31af49d2015-06-09 17:29:50 +02005415/* parse the "ca-sign-file" bind keyword */
5416static int bind_parse_ca_sign_file(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5417{
5418 if (!*args[cur_arg + 1]) {
5419 if (err)
5420 memprintf(err, "'%s' : missing CAfile path", args[cur_arg]);
5421 return ERR_ALERT | ERR_FATAL;
5422 }
5423
Willy Tarreauef934602016-12-22 23:12:01 +01005424 if ((*args[cur_arg + 1] != '/') && global_ssl.ca_base)
5425 memprintf(&conf->ca_sign_file, "%s/%s", global_ssl.ca_base, args[cur_arg + 1]);
Christopher Faulet31af49d2015-06-09 17:29:50 +02005426 else
5427 memprintf(&conf->ca_sign_file, "%s", args[cur_arg + 1]);
5428
5429 return 0;
5430}
5431
Bertrand Jacquinff13c062016-11-13 16:37:11 +00005432/* parse the "ca-sign-pass" bind keyword */
Christopher Faulet31af49d2015-06-09 17:29:50 +02005433static int bind_parse_ca_sign_pass(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5434{
5435 if (!*args[cur_arg + 1]) {
5436 if (err)
5437 memprintf(err, "'%s' : missing CAkey password", args[cur_arg]);
5438 return ERR_ALERT | ERR_FATAL;
5439 }
5440 memprintf(&conf->ca_sign_pass, "%s", args[cur_arg + 1]);
5441 return 0;
5442}
5443
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005444/* parse the "ciphers" bind keyword */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01005445static 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 +02005446{
5447 if (!*args[cur_arg + 1]) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02005448 memprintf(err, "'%s' : missing cipher suite", args[cur_arg]);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005449 return ERR_ALERT | ERR_FATAL;
5450 }
5451
Emeric Brun76d88952012-10-05 15:47:31 +02005452 free(conf->ciphers);
Willy Tarreau4348fad2012-09-20 16:48:07 +02005453 conf->ciphers = strdup(args[cur_arg + 1]);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005454 return 0;
5455}
Emmanuel Hocdet98263292016-12-29 18:26:15 +01005456static int bind_parse_ciphers(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5457{
5458 return ssl_bind_parse_ciphers(args, cur_arg, px, &conf->ssl_conf, err);
5459}
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005460/* parse the "crt" bind keyword */
Willy Tarreau4348fad2012-09-20 16:48:07 +02005461static 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 +02005462{
Willy Tarreau38011032013-08-13 16:59:39 +02005463 char path[MAXPATHLEN];
Willy Tarreaub75d6922014-04-14 18:05:41 +02005464
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005465 if (!*args[cur_arg + 1]) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02005466 memprintf(err, "'%s' : missing certificate location", args[cur_arg]);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005467 return ERR_ALERT | ERR_FATAL;
5468 }
5469
Willy Tarreauef934602016-12-22 23:12:01 +01005470 if ((*args[cur_arg + 1] != '/' ) && global_ssl.crt_base) {
5471 if ((strlen(global_ssl.crt_base) + 1 + strlen(args[cur_arg + 1]) + 1) > MAXPATHLEN) {
Emeric Brunc8e8d122012-10-02 18:42:10 +02005472 memprintf(err, "'%s' : path too long", args[cur_arg]);
5473 return ERR_ALERT | ERR_FATAL;
5474 }
Willy Tarreauef934602016-12-22 23:12:01 +01005475 snprintf(path, sizeof(path), "%s/%s", global_ssl.crt_base, args[cur_arg + 1]);
Willy Tarreau03209342016-12-22 17:08:28 +01005476 if (ssl_sock_load_cert(path, conf, err) > 0)
Emeric Brunc8e8d122012-10-02 18:42:10 +02005477 return ERR_ALERT | ERR_FATAL;
5478
5479 return 0;
5480 }
5481
Willy Tarreau03209342016-12-22 17:08:28 +01005482 if (ssl_sock_load_cert(args[cur_arg + 1], conf, err) > 0)
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005483 return ERR_ALERT | ERR_FATAL;
Emeric Brund94b3fe2012-09-20 18:23:56 +02005484
5485 return 0;
5486}
5487
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01005488/* parse the "crt-list" bind keyword */
5489static int bind_parse_crt_list(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5490{
5491 if (!*args[cur_arg + 1]) {
5492 memprintf(err, "'%s' : missing certificate location", args[cur_arg]);
5493 return ERR_ALERT | ERR_FATAL;
5494 }
5495
Emmanuel Hocdet98263292016-12-29 18:26:15 +01005496 if (ssl_sock_load_cert_list_file(args[cur_arg + 1], conf, px, err) > 0) {
Willy Tarreauad1731d2013-04-02 17:35:58 +02005497 memprintf(err, "'%s' : %s", args[cur_arg], *err);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01005498 return ERR_ALERT | ERR_FATAL;
Willy Tarreauad1731d2013-04-02 17:35:58 +02005499 }
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01005500
5501 return 0;
5502}
5503
Emeric Brunfb510ea2012-10-05 12:00:26 +02005504/* parse the "crl-file" bind keyword */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01005505static 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 +02005506{
Emeric Brun051cdab2012-10-02 19:25:50 +02005507#ifndef X509_V_FLAG_CRL_CHECK
5508 if (err)
5509 memprintf(err, "'%s' : library does not support CRL verify", args[cur_arg]);
5510 return ERR_ALERT | ERR_FATAL;
5511#else
Emeric Brund94b3fe2012-09-20 18:23:56 +02005512 if (!*args[cur_arg + 1]) {
5513 if (err)
5514 memprintf(err, "'%s' : missing CRLfile path", args[cur_arg]);
5515 return ERR_ALERT | ERR_FATAL;
5516 }
Emeric Brun2b58d042012-09-20 17:10:03 +02005517
Willy Tarreauef934602016-12-22 23:12:01 +01005518 if ((*args[cur_arg + 1] != '/') && global_ssl.ca_base)
5519 memprintf(&conf->crl_file, "%s/%s", global_ssl.ca_base, args[cur_arg + 1]);
Emeric Brunef42d922012-10-11 16:11:36 +02005520 else
5521 memprintf(&conf->crl_file, "%s", args[cur_arg + 1]);
Emeric Brunc8e8d122012-10-02 18:42:10 +02005522
Emeric Brun2b58d042012-09-20 17:10:03 +02005523 return 0;
Emeric Brun051cdab2012-10-02 19:25:50 +02005524#endif
Emeric Brun2b58d042012-09-20 17:10:03 +02005525}
Emmanuel Hocdet98263292016-12-29 18:26:15 +01005526static int bind_parse_crl_file(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5527{
5528 return ssl_bind_parse_crl_file(args, cur_arg, px, &conf->ssl_conf, err);
5529}
Emeric Brun2b58d042012-09-20 17:10:03 +02005530
Emmanuel Hocdete7f2b732017-01-09 16:15:54 +01005531/* parse the "curves" bind keyword keyword */
5532static int ssl_bind_parse_curves(char **args, int cur_arg, struct proxy *px, struct ssl_bind_conf *conf, char **err)
5533{
5534#if OPENSSL_VERSION_NUMBER >= 0x1000200fL
5535 if (!*args[cur_arg + 1]) {
5536 if (err)
5537 memprintf(err, "'%s' : missing curve suite", args[cur_arg]);
5538 return ERR_ALERT | ERR_FATAL;
5539 }
5540 conf->curves = strdup(args[cur_arg + 1]);
5541 return 0;
5542#else
5543 if (err)
5544 memprintf(err, "'%s' : library does not support curve suite", args[cur_arg]);
5545 return ERR_ALERT | ERR_FATAL;
5546#endif
5547}
5548static int bind_parse_curves(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5549{
5550 return ssl_bind_parse_curves(args, cur_arg, px, &conf->ssl_conf, err);
5551}
5552
Bertrand Jacquinff13c062016-11-13 16:37:11 +00005553/* parse the "ecdhe" bind keyword keyword */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01005554static 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 +02005555{
5556#if OPENSSL_VERSION_NUMBER < 0x0090800fL
5557 if (err)
5558 memprintf(err, "'%s' : library does not support elliptic curve Diffie-Hellman (too old)", args[cur_arg]);
5559 return ERR_ALERT | ERR_FATAL;
5560#elif defined(OPENSSL_NO_ECDH)
5561 if (err)
5562 memprintf(err, "'%s' : library does not support elliptic curve Diffie-Hellman (disabled via OPENSSL_NO_ECDH)", args[cur_arg]);
5563 return ERR_ALERT | ERR_FATAL;
5564#else
5565 if (!*args[cur_arg + 1]) {
5566 if (err)
5567 memprintf(err, "'%s' : missing named curve", args[cur_arg]);
5568 return ERR_ALERT | ERR_FATAL;
5569 }
5570
5571 conf->ecdhe = strdup(args[cur_arg + 1]);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005572
5573 return 0;
Emeric Brun2b58d042012-09-20 17:10:03 +02005574#endif
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005575}
Emmanuel Hocdet98263292016-12-29 18:26:15 +01005576static int bind_parse_ecdhe(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5577{
5578 return ssl_bind_parse_ecdhe(args, cur_arg, px, &conf->ssl_conf, err);
5579}
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005580
Bertrand Jacquinff13c062016-11-13 16:37:11 +00005581/* parse the "crt-ignore-err" and "ca-ignore-err" bind keywords */
Emeric Brun81c00f02012-09-21 14:31:21 +02005582static int bind_parse_ignore_err(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5583{
5584 int code;
5585 char *p = args[cur_arg + 1];
5586 unsigned long long *ignerr = &conf->crt_ignerr;
5587
5588 if (!*p) {
5589 if (err)
5590 memprintf(err, "'%s' : missing error IDs list", args[cur_arg]);
5591 return ERR_ALERT | ERR_FATAL;
5592 }
5593
5594 if (strcmp(args[cur_arg], "ca-ignore-err") == 0)
5595 ignerr = &conf->ca_ignerr;
5596
5597 if (strcmp(p, "all") == 0) {
5598 *ignerr = ~0ULL;
5599 return 0;
5600 }
5601
5602 while (p) {
5603 code = atoi(p);
5604 if ((code <= 0) || (code > 63)) {
5605 if (err)
5606 memprintf(err, "'%s' : ID '%d' out of range (1..63) in error IDs list '%s'",
5607 args[cur_arg], code, args[cur_arg + 1]);
5608 return ERR_ALERT | ERR_FATAL;
5609 }
5610 *ignerr |= 1ULL << code;
5611 p = strchr(p, ',');
5612 if (p)
5613 p++;
5614 }
5615
Emeric Brun2cb7ae52012-10-05 14:14:21 +02005616 return 0;
5617}
5618
5619/* parse the "force-sslv3" bind keyword */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01005620static 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 +02005621{
5622 conf->ssl_options |= BC_SSL_O_USE_SSLV3;
5623 return 0;
5624}
Emmanuel Hocdet98263292016-12-29 18:26:15 +01005625static int bind_parse_force_sslv3(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5626{
5627 return ssl_bind_parse_force_sslv3(args, cur_arg, px, &conf->ssl_conf, err);
5628}
Emeric Brun2cb7ae52012-10-05 14:14:21 +02005629
5630/* parse the "force-tlsv10" bind keyword */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01005631static 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 +02005632{
5633 conf->ssl_options |= BC_SSL_O_USE_TLSV10;
Emeric Brun2d0c4822012-10-02 13:45:20 +02005634 return 0;
5635}
Emmanuel Hocdet98263292016-12-29 18:26:15 +01005636static int bind_parse_force_tlsv10(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5637{
5638 return ssl_bind_parse_force_tlsv10(args, cur_arg, px, &conf->ssl_conf, err);
5639}
Emeric Brun2d0c4822012-10-02 13:45:20 +02005640
Emeric Brun2cb7ae52012-10-05 14:14:21 +02005641/* parse the "force-tlsv11" bind keyword */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01005642static 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 +02005643{
5644#if SSL_OP_NO_TLSv1_1
5645 conf->ssl_options |= BC_SSL_O_USE_TLSV11;
5646 return 0;
5647#else
5648 if (err)
5649 memprintf(err, "'%s' : library does not support protocol TLSv1.1", args[cur_arg]);
5650 return ERR_ALERT | ERR_FATAL;
5651#endif
5652}
Emmanuel Hocdet98263292016-12-29 18:26:15 +01005653static int bind_parse_force_tlsv11(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5654{
5655 return ssl_bind_parse_force_tlsv11(args, cur_arg, px, &conf->ssl_conf, err);
5656}
Emeric Brun2cb7ae52012-10-05 14:14:21 +02005657
5658/* parse the "force-tlsv12" bind keyword */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01005659static 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 +02005660{
5661#if SSL_OP_NO_TLSv1_2
5662 conf->ssl_options |= BC_SSL_O_USE_TLSV12;
5663 return 0;
5664#else
5665 if (err)
5666 memprintf(err, "'%s' : library does not support protocol TLSv1.2", args[cur_arg]);
5667 return ERR_ALERT | ERR_FATAL;
5668#endif
5669}
Emmanuel Hocdet98263292016-12-29 18:26:15 +01005670static int bind_parse_force_tlsv12(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5671{
5672 return ssl_bind_parse_force_tlsv12(args, cur_arg, px, &conf->ssl_conf, err);
5673}
Emeric Brun2cb7ae52012-10-05 14:14:21 +02005674
Emeric Brun2d0c4822012-10-02 13:45:20 +02005675/* parse the "no-tls-tickets" bind keyword */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01005676static 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 +02005677{
Emeric Brun89675492012-10-05 13:48:26 +02005678 conf->ssl_options |= BC_SSL_O_NO_TLS_TICKETS;
Emeric Brun81c00f02012-09-21 14:31:21 +02005679 return 0;
5680}
Emmanuel Hocdet98263292016-12-29 18:26:15 +01005681static int bind_parse_no_tls_tickets(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5682{
5683 return ssl_bind_parse_no_tls_tickets(args, cur_arg, px, &conf->ssl_conf, err);
5684}
Emeric Brun2d0c4822012-10-02 13:45:20 +02005685
Emeric Brun9b3009b2012-10-05 11:55:06 +02005686/* parse the "no-sslv3" bind keyword */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01005687static 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 +02005688{
Emeric Brun89675492012-10-05 13:48:26 +02005689 conf->ssl_options |= BC_SSL_O_NO_SSLV3;
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005690 return 0;
5691}
Emmanuel Hocdet98263292016-12-29 18:26:15 +01005692static int bind_parse_no_sslv3(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5693{
5694 return ssl_bind_parse_no_sslv3(args, cur_arg, px, &conf->ssl_conf, err);
5695}
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005696
Emeric Brun9b3009b2012-10-05 11:55:06 +02005697/* parse the "no-tlsv10" bind keyword */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01005698static 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 +02005699{
Emeric Brun89675492012-10-05 13:48:26 +02005700 conf->ssl_options |= BC_SSL_O_NO_TLSV10;
Emeric Brunc0ff4922012-09-28 19:37:02 +02005701 return 0;
5702}
Emmanuel Hocdet98263292016-12-29 18:26:15 +01005703static int bind_parse_no_tlsv10(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5704{
5705 return ssl_bind_parse_no_tlsv10(args, cur_arg, px, &conf->ssl_conf, err);
5706}
Emeric Brunc0ff4922012-09-28 19:37:02 +02005707
Emeric Brun9b3009b2012-10-05 11:55:06 +02005708/* parse the "no-tlsv11" bind keyword */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01005709static 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 +02005710{
Emeric Brun89675492012-10-05 13:48:26 +02005711 conf->ssl_options |= BC_SSL_O_NO_TLSV11;
Emeric Brunc0ff4922012-09-28 19:37:02 +02005712 return 0;
5713}
Emmanuel Hocdet98263292016-12-29 18:26:15 +01005714static int bind_parse_no_tlsv11(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5715{
5716 return ssl_bind_parse_no_tlsv11(args, cur_arg, px, &conf->ssl_conf, err);
5717}
Emeric Brunc0ff4922012-09-28 19:37:02 +02005718
Emeric Brun9b3009b2012-10-05 11:55:06 +02005719/* parse the "no-tlsv12" bind keyword */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01005720static 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 +02005721{
Emeric Brun89675492012-10-05 13:48:26 +02005722 conf->ssl_options |= BC_SSL_O_NO_TLSV12;
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005723 return 0;
5724}
Emmanuel Hocdet98263292016-12-29 18:26:15 +01005725static int bind_parse_no_tlsv12(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5726{
5727 return ssl_bind_parse_no_tlsv12(args, cur_arg, px, &conf->ssl_conf, err);
5728}
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005729
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02005730/* parse the "npn" bind keyword */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01005731static 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 +02005732{
5733#ifdef OPENSSL_NPN_NEGOTIATED
5734 char *p1, *p2;
5735
5736 if (!*args[cur_arg + 1]) {
5737 memprintf(err, "'%s' : missing the comma-delimited NPN protocol suite", args[cur_arg]);
5738 return ERR_ALERT | ERR_FATAL;
5739 }
5740
5741 free(conf->npn_str);
5742
Willy Tarreau3724da12016-02-12 17:11:12 +01005743 /* the NPN string is built as a suite of (<len> <name>)*,
5744 * so we reuse each comma to store the next <len> and need
5745 * one more for the end of the string.
5746 */
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02005747 conf->npn_len = strlen(args[cur_arg + 1]) + 1;
Willy Tarreau3724da12016-02-12 17:11:12 +01005748 conf->npn_str = calloc(1, conf->npn_len + 1);
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02005749 memcpy(conf->npn_str + 1, args[cur_arg + 1], conf->npn_len);
5750
5751 /* replace commas with the name length */
5752 p1 = conf->npn_str;
5753 p2 = p1 + 1;
5754 while (1) {
5755 p2 = memchr(p1 + 1, ',', conf->npn_str + conf->npn_len - (p1 + 1));
5756 if (!p2)
5757 p2 = p1 + 1 + strlen(p1 + 1);
5758
5759 if (p2 - (p1 + 1) > 255) {
5760 *p2 = '\0';
5761 memprintf(err, "'%s' : NPN protocol name too long : '%s'", args[cur_arg], p1 + 1);
5762 return ERR_ALERT | ERR_FATAL;
5763 }
5764
5765 *p1 = p2 - (p1 + 1);
5766 p1 = p2;
5767
5768 if (!*p2)
5769 break;
5770
5771 *(p2++) = '\0';
5772 }
5773 return 0;
5774#else
5775 if (err)
5776 memprintf(err, "'%s' : library does not support TLS NPN extension", args[cur_arg]);
5777 return ERR_ALERT | ERR_FATAL;
5778#endif
5779}
5780
Emmanuel Hocdet98263292016-12-29 18:26:15 +01005781static int bind_parse_npn(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5782{
5783 return ssl_bind_parse_npn(args, cur_arg, px, &conf->ssl_conf, err);
5784}
5785
Willy Tarreauab861d32013-04-02 02:30:41 +02005786/* parse the "alpn" bind keyword */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01005787static 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 +02005788{
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01005789#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Willy Tarreauab861d32013-04-02 02:30:41 +02005790 char *p1, *p2;
5791
5792 if (!*args[cur_arg + 1]) {
5793 memprintf(err, "'%s' : missing the comma-delimited ALPN protocol suite", args[cur_arg]);
5794 return ERR_ALERT | ERR_FATAL;
5795 }
5796
5797 free(conf->alpn_str);
5798
Marcoen Hirschbergbef60912016-02-12 17:05:24 +01005799 /* the ALPN string is built as a suite of (<len> <name>)*,
5800 * so we reuse each comma to store the next <len> and need
5801 * one more for the end of the string.
5802 */
Willy Tarreauab861d32013-04-02 02:30:41 +02005803 conf->alpn_len = strlen(args[cur_arg + 1]) + 1;
Marcoen Hirschbergbef60912016-02-12 17:05:24 +01005804 conf->alpn_str = calloc(1, conf->alpn_len + 1);
Willy Tarreauab861d32013-04-02 02:30:41 +02005805 memcpy(conf->alpn_str + 1, args[cur_arg + 1], conf->alpn_len);
5806
5807 /* replace commas with the name length */
5808 p1 = conf->alpn_str;
5809 p2 = p1 + 1;
5810 while (1) {
5811 p2 = memchr(p1 + 1, ',', conf->alpn_str + conf->alpn_len - (p1 + 1));
5812 if (!p2)
5813 p2 = p1 + 1 + strlen(p1 + 1);
5814
5815 if (p2 - (p1 + 1) > 255) {
5816 *p2 = '\0';
5817 memprintf(err, "'%s' : ALPN protocol name too long : '%s'", args[cur_arg], p1 + 1);
5818 return ERR_ALERT | ERR_FATAL;
5819 }
5820
5821 *p1 = p2 - (p1 + 1);
5822 p1 = p2;
5823
5824 if (!*p2)
5825 break;
5826
5827 *(p2++) = '\0';
5828 }
5829 return 0;
5830#else
5831 if (err)
5832 memprintf(err, "'%s' : library does not support TLS ALPN extension", args[cur_arg]);
5833 return ERR_ALERT | ERR_FATAL;
5834#endif
5835}
5836
Emmanuel Hocdet98263292016-12-29 18:26:15 +01005837static int bind_parse_alpn(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5838{
5839 return ssl_bind_parse_alpn(args, cur_arg, px, &conf->ssl_conf, err);
5840}
5841
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005842/* parse the "ssl" bind keyword */
Willy Tarreau4348fad2012-09-20 16:48:07 +02005843static 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 +02005844{
Willy Tarreau71a8c7c2016-12-21 22:04:54 +01005845 conf->xprt = &ssl_sock;
Willy Tarreau4348fad2012-09-20 16:48:07 +02005846 conf->is_ssl = 1;
Emeric Brun76d88952012-10-05 15:47:31 +02005847
Emmanuel Hocdet98263292016-12-29 18:26:15 +01005848 if (global_ssl.listen_default_ciphers && !conf->ssl_conf.ciphers)
5849 conf->ssl_conf.ciphers = strdup(global_ssl.listen_default_ciphers);
5850 conf->ssl_conf.ssl_options |= global_ssl.listen_default_ssloptions;
Emeric Brun76d88952012-10-05 15:47:31 +02005851
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005852 return 0;
5853}
5854
Christopher Faulet31af49d2015-06-09 17:29:50 +02005855/* parse the "generate-certificates" bind keyword */
5856static int bind_parse_generate_certs(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5857{
5858#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
5859 conf->generate_certs = 1;
5860#else
5861 memprintf(err, "%sthis version of openssl cannot generate SSL certificates.\n",
5862 err && *err ? *err : "");
5863#endif
5864 return 0;
5865}
5866
Emmanuel Hocdet65623372013-01-24 17:17:15 +01005867/* parse the "strict-sni" bind keyword */
5868static int bind_parse_strict_sni(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5869{
5870 conf->strict_sni = 1;
5871 return 0;
Nenad Merdanovic05552d42015-02-27 19:56:49 +01005872}
5873
5874/* parse the "tls-ticket-keys" bind keyword */
5875static int bind_parse_tls_ticket_keys(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5876{
5877#if (defined SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB && TLS_TICKETS_NO > 0)
5878 FILE *f;
5879 int i = 0;
5880 char thisline[LINESIZE];
Nenad Merdanovic146defa2015-05-09 08:46:00 +02005881 struct tls_keys_ref *keys_ref;
Nenad Merdanovic05552d42015-02-27 19:56:49 +01005882
5883 if (!*args[cur_arg + 1]) {
5884 if (err)
5885 memprintf(err, "'%s' : missing TLS ticket keys file path", args[cur_arg]);
5886 return ERR_ALERT | ERR_FATAL;
5887 }
5888
Nenad Merdanovic200b0fa2015-05-09 08:46:01 +02005889 keys_ref = tlskeys_ref_lookup(args[cur_arg + 1]);
5890 if(keys_ref) {
5891 conf->keys_ref = keys_ref;
5892 return 0;
5893 }
5894
Vincent Bernat02779b62016-04-03 13:48:43 +02005895 keys_ref = malloc(sizeof(*keys_ref));
Nenad Merdanovic146defa2015-05-09 08:46:00 +02005896 keys_ref->tlskeys = malloc(TLS_TICKETS_NO * sizeof(struct tls_sess_key));
Nenad Merdanovic05552d42015-02-27 19:56:49 +01005897
5898 if ((f = fopen(args[cur_arg + 1], "r")) == NULL) {
5899 if (err)
5900 memprintf(err, "'%s' : unable to load ssl tickets keys file", args[cur_arg+1]);
5901 return ERR_ALERT | ERR_FATAL;
5902 }
5903
Nenad Merdanovic146defa2015-05-09 08:46:00 +02005904 keys_ref->filename = strdup(args[cur_arg + 1]);
5905
Nenad Merdanovic05552d42015-02-27 19:56:49 +01005906 while (fgets(thisline, sizeof(thisline), f) != NULL) {
5907 int len = strlen(thisline);
5908 /* Strip newline characters from the end */
5909 if(thisline[len - 1] == '\n')
5910 thisline[--len] = 0;
5911
5912 if(thisline[len - 1] == '\r')
5913 thisline[--len] = 0;
5914
Nenad Merdanovic146defa2015-05-09 08:46:00 +02005915 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 +01005916 if (err)
5917 memprintf(err, "'%s' : unable to decode base64 key on line %d", args[cur_arg+1], i + 1);
mildis16aa0152016-06-22 17:46:29 +02005918 fclose(f);
Nenad Merdanovic05552d42015-02-27 19:56:49 +01005919 return ERR_ALERT | ERR_FATAL;
5920 }
5921 i++;
5922 }
5923
5924 if (i < TLS_TICKETS_NO) {
5925 if (err)
5926 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 +02005927 fclose(f);
Nenad Merdanovic05552d42015-02-27 19:56:49 +01005928 return ERR_ALERT | ERR_FATAL;
5929 }
5930
5931 fclose(f);
5932
5933 /* Use penultimate key for encryption, handle when TLS_TICKETS_NO = 1 */
Nenad Merdanovic17891152016-03-25 22:16:57 +01005934 i -= 2;
5935 keys_ref->tls_ticket_enc_index = i < 0 ? 0 : i % TLS_TICKETS_NO;
Nenad Merdanovic200b0fa2015-05-09 08:46:01 +02005936 keys_ref->unique_id = -1;
Nenad Merdanovic146defa2015-05-09 08:46:00 +02005937 conf->keys_ref = keys_ref;
Nenad Merdanovic05552d42015-02-27 19:56:49 +01005938
Nenad Merdanovic200b0fa2015-05-09 08:46:01 +02005939 LIST_ADD(&tlskeys_reference, &keys_ref->list);
5940
Nenad Merdanovic05552d42015-02-27 19:56:49 +01005941 return 0;
5942#else
5943 if (err)
5944 memprintf(err, "'%s' : TLS ticket callback extension not supported", args[cur_arg]);
5945 return ERR_ALERT | ERR_FATAL;
5946#endif /* SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB */
Emmanuel Hocdet65623372013-01-24 17:17:15 +01005947}
5948
Emeric Brund94b3fe2012-09-20 18:23:56 +02005949/* parse the "verify" bind keyword */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01005950static 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 +02005951{
5952 if (!*args[cur_arg + 1]) {
5953 if (err)
5954 memprintf(err, "'%s' : missing verify method", args[cur_arg]);
5955 return ERR_ALERT | ERR_FATAL;
5956 }
5957
5958 if (strcmp(args[cur_arg + 1], "none") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01005959 conf->verify = SSL_SOCK_VERIFY_NONE;
Emeric Brund94b3fe2012-09-20 18:23:56 +02005960 else if (strcmp(args[cur_arg + 1], "optional") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01005961 conf->verify = SSL_SOCK_VERIFY_OPTIONAL;
Emeric Brund94b3fe2012-09-20 18:23:56 +02005962 else if (strcmp(args[cur_arg + 1], "required") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01005963 conf->verify = SSL_SOCK_VERIFY_REQUIRED;
Emeric Brund94b3fe2012-09-20 18:23:56 +02005964 else {
5965 if (err)
5966 memprintf(err, "'%s' : unknown verify method '%s', only 'none', 'optional', and 'required' are supported\n",
5967 args[cur_arg], args[cur_arg + 1]);
5968 return ERR_ALERT | ERR_FATAL;
5969 }
5970
5971 return 0;
5972}
Emmanuel Hocdet98263292016-12-29 18:26:15 +01005973static int bind_parse_verify(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5974{
5975 return ssl_bind_parse_verify(args, cur_arg, px, &conf->ssl_conf, err);
5976}
Emeric Brund94b3fe2012-09-20 18:23:56 +02005977
Willy Tarreau92faadf2012-10-10 23:04:25 +02005978/************** "server" keywords ****************/
5979
Emeric Brunef42d922012-10-11 16:11:36 +02005980/* parse the "ca-file" server keyword */
5981static int srv_parse_ca_file(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5982{
5983 if (!*args[*cur_arg + 1]) {
5984 if (err)
5985 memprintf(err, "'%s' : missing CAfile path", args[*cur_arg]);
5986 return ERR_ALERT | ERR_FATAL;
5987 }
5988
Willy Tarreauef934602016-12-22 23:12:01 +01005989 if ((*args[*cur_arg + 1] != '/') && global_ssl.ca_base)
5990 memprintf(&newsrv->ssl_ctx.ca_file, "%s/%s", global_ssl.ca_base, args[*cur_arg + 1]);
Emeric Brunef42d922012-10-11 16:11:36 +02005991 else
5992 memprintf(&newsrv->ssl_ctx.ca_file, "%s", args[*cur_arg + 1]);
5993
5994 return 0;
5995}
5996
Willy Tarreau92faadf2012-10-10 23:04:25 +02005997/* parse the "check-ssl" server keyword */
5998static int srv_parse_check_ssl(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5999{
6000 newsrv->check.use_ssl = 1;
Willy Tarreauef934602016-12-22 23:12:01 +01006001 if (global_ssl.connect_default_ciphers && !newsrv->ssl_ctx.ciphers)
6002 newsrv->ssl_ctx.ciphers = strdup(global_ssl.connect_default_ciphers);
6003 newsrv->ssl_ctx.options |= global_ssl.connect_default_ssloptions;
Willy Tarreau92faadf2012-10-10 23:04:25 +02006004 return 0;
6005}
6006
6007/* parse the "ciphers" server keyword */
6008static int srv_parse_ciphers(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
6009{
6010 if (!*args[*cur_arg + 1]) {
6011 memprintf(err, "'%s' : missing cipher suite", args[*cur_arg]);
6012 return ERR_ALERT | ERR_FATAL;
6013 }
6014
6015 free(newsrv->ssl_ctx.ciphers);
6016 newsrv->ssl_ctx.ciphers = strdup(args[*cur_arg + 1]);
6017 return 0;
6018}
6019
Emeric Brunef42d922012-10-11 16:11:36 +02006020/* parse the "crl-file" server keyword */
6021static int srv_parse_crl_file(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
6022{
6023#ifndef X509_V_FLAG_CRL_CHECK
6024 if (err)
6025 memprintf(err, "'%s' : library does not support CRL verify", args[*cur_arg]);
6026 return ERR_ALERT | ERR_FATAL;
6027#else
6028 if (!*args[*cur_arg + 1]) {
6029 if (err)
6030 memprintf(err, "'%s' : missing CRLfile path", args[*cur_arg]);
6031 return ERR_ALERT | ERR_FATAL;
6032 }
6033
Willy Tarreauef934602016-12-22 23:12:01 +01006034 if ((*args[*cur_arg + 1] != '/') && global_ssl.ca_base)
6035 memprintf(&newsrv->ssl_ctx.crl_file, "%s/%s", global_ssl.ca_base, args[*cur_arg + 1]);
Emeric Brunef42d922012-10-11 16:11:36 +02006036 else
6037 memprintf(&newsrv->ssl_ctx.crl_file, "%s", args[*cur_arg + 1]);
6038
6039 return 0;
6040#endif
6041}
6042
Emeric Bruna7aa3092012-10-26 12:58:00 +02006043/* parse the "crt" server keyword */
6044static int srv_parse_crt(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
6045{
6046 if (!*args[*cur_arg + 1]) {
6047 if (err)
6048 memprintf(err, "'%s' : missing certificate file path", args[*cur_arg]);
6049 return ERR_ALERT | ERR_FATAL;
6050 }
6051
Willy Tarreauef934602016-12-22 23:12:01 +01006052 if ((*args[*cur_arg + 1] != '/') && global_ssl.crt_base)
6053 memprintf(&newsrv->ssl_ctx.client_crt, "%s/%s", global_ssl.ca_base, args[*cur_arg + 1]);
Emeric Bruna7aa3092012-10-26 12:58:00 +02006054 else
6055 memprintf(&newsrv->ssl_ctx.client_crt, "%s", args[*cur_arg + 1]);
6056
6057 return 0;
6058}
Emeric Brunef42d922012-10-11 16:11:36 +02006059
Willy Tarreau92faadf2012-10-10 23:04:25 +02006060/* parse the "force-sslv3" server keyword */
6061static int srv_parse_force_sslv3(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
6062{
6063 newsrv->ssl_ctx.options |= SRV_SSL_O_USE_SSLV3;
6064 return 0;
6065}
6066
6067/* parse the "force-tlsv10" server keyword */
6068static int srv_parse_force_tlsv10(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
6069{
6070 newsrv->ssl_ctx.options |= SRV_SSL_O_USE_TLSV10;
6071 return 0;
6072}
6073
6074/* parse the "force-tlsv11" server keyword */
6075static int srv_parse_force_tlsv11(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
6076{
6077#if SSL_OP_NO_TLSv1_1
6078 newsrv->ssl_ctx.options |= SRV_SSL_O_USE_TLSV11;
6079 return 0;
6080#else
6081 if (err)
6082 memprintf(err, "'%s' : library does not support protocol TLSv1.1", args[*cur_arg]);
6083 return ERR_ALERT | ERR_FATAL;
6084#endif
6085}
6086
6087/* parse the "force-tlsv12" server keyword */
6088static int srv_parse_force_tlsv12(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
6089{
6090#if SSL_OP_NO_TLSv1_2
6091 newsrv->ssl_ctx.options |= SRV_SSL_O_USE_TLSV12;
6092 return 0;
6093#else
6094 if (err)
6095 memprintf(err, "'%s' : library does not support protocol TLSv1.2", args[*cur_arg]);
6096 return ERR_ALERT | ERR_FATAL;
6097#endif
6098}
6099
Willy Tarreau2a3fb1c2015-02-05 16:47:07 +01006100/* parse the "no-ssl-reuse" server keyword */
6101static int srv_parse_no_ssl_reuse(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
6102{
6103 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_REUSE;
6104 return 0;
6105}
6106
Willy Tarreau92faadf2012-10-10 23:04:25 +02006107/* parse the "no-sslv3" server keyword */
6108static int srv_parse_no_sslv3(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
6109{
6110 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_SSLV3;
6111 return 0;
6112}
6113
6114/* parse the "no-tlsv10" server keyword */
6115static int srv_parse_no_tlsv10(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
6116{
6117 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_TLSV10;
6118 return 0;
6119}
6120
6121/* parse the "no-tlsv11" server keyword */
6122static int srv_parse_no_tlsv11(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
6123{
6124 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_TLSV11;
6125 return 0;
6126}
6127
6128/* parse the "no-tlsv12" server keyword */
6129static int srv_parse_no_tlsv12(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
6130{
6131 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_TLSV12;
6132 return 0;
6133}
6134
Emeric Brunf9c5c472012-10-11 15:28:34 +02006135/* parse the "no-tls-tickets" server keyword */
6136static int srv_parse_no_tls_tickets(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
6137{
6138 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_TLS_TICKETS;
6139 return 0;
6140}
David Safb76832014-05-08 23:42:08 -04006141/* parse the "send-proxy-v2-ssl" server keyword */
6142static int srv_parse_send_proxy_ssl(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
6143{
6144 newsrv->pp_opts |= SRV_PP_V2;
6145 newsrv->pp_opts |= SRV_PP_V2_SSL;
6146 return 0;
6147}
6148
6149/* parse the "send-proxy-v2-ssl-cn" server keyword */
6150static int srv_parse_send_proxy_cn(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
6151{
6152 newsrv->pp_opts |= SRV_PP_V2;
6153 newsrv->pp_opts |= SRV_PP_V2_SSL;
6154 newsrv->pp_opts |= SRV_PP_V2_SSL_CN;
6155 return 0;
6156}
Emeric Brunf9c5c472012-10-11 15:28:34 +02006157
Willy Tarreau732eac42015-07-09 11:40:25 +02006158/* parse the "sni" server keyword */
6159static int srv_parse_sni(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
6160{
6161#ifndef SSL_CTRL_SET_TLSEXT_HOSTNAME
6162 memprintf(err, "'%s' : the current SSL library doesn't support the SNI TLS extension", args[*cur_arg]);
6163 return ERR_ALERT | ERR_FATAL;
6164#else
Cyril Bonté23d19d62016-03-07 22:13:22 +01006165 int idx;
Willy Tarreau732eac42015-07-09 11:40:25 +02006166 struct sample_expr *expr;
6167
6168 if (!*args[*cur_arg + 1]) {
6169 memprintf(err, "'%s' : missing sni expression", args[*cur_arg]);
6170 return ERR_ALERT | ERR_FATAL;
6171 }
6172
Cyril Bonté23d19d62016-03-07 22:13:22 +01006173 idx = (*cur_arg) + 1;
Willy Tarreau732eac42015-07-09 11:40:25 +02006174 proxy->conf.args.ctx = ARGC_SRV;
6175
Cyril Bonté23d19d62016-03-07 22:13:22 +01006176 expr = sample_parse_expr((char **)args, &idx, px->conf.file, px->conf.line, err, &proxy->conf.args);
Willy Tarreau732eac42015-07-09 11:40:25 +02006177 if (!expr) {
6178 memprintf(err, "error detected while parsing sni expression : %s", *err);
6179 return ERR_ALERT | ERR_FATAL;
6180 }
6181
6182 if (!(expr->fetch->val & SMP_VAL_BE_SRV_CON)) {
6183 memprintf(err, "error detected while parsing sni expression : "
6184 " fetch method '%s' extracts information from '%s', none of which is available here.\n",
Cyril Bonté23d19d62016-03-07 22:13:22 +01006185 args[idx-1], sample_src_names(expr->fetch->use));
Willy Tarreau732eac42015-07-09 11:40:25 +02006186 return ERR_ALERT | ERR_FATAL;
6187 }
6188
6189 px->http_needed |= !!(expr->fetch->use & SMP_USE_HTTP_ANY);
6190 newsrv->ssl_ctx.sni = expr;
6191 return 0;
6192#endif
6193}
6194
Willy Tarreau92faadf2012-10-10 23:04:25 +02006195/* parse the "ssl" server keyword */
6196static int srv_parse_ssl(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
6197{
6198 newsrv->use_ssl = 1;
Willy Tarreauef934602016-12-22 23:12:01 +01006199 if (global_ssl.connect_default_ciphers && !newsrv->ssl_ctx.ciphers)
6200 newsrv->ssl_ctx.ciphers = strdup(global_ssl.connect_default_ciphers);
Willy Tarreau92faadf2012-10-10 23:04:25 +02006201 return 0;
6202}
6203
Emeric Brunef42d922012-10-11 16:11:36 +02006204/* parse the "verify" server keyword */
6205static int srv_parse_verify(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
6206{
6207 if (!*args[*cur_arg + 1]) {
6208 if (err)
6209 memprintf(err, "'%s' : missing verify method", args[*cur_arg]);
6210 return ERR_ALERT | ERR_FATAL;
6211 }
6212
6213 if (strcmp(args[*cur_arg + 1], "none") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01006214 newsrv->ssl_ctx.verify = SSL_SOCK_VERIFY_NONE;
Emeric Brunef42d922012-10-11 16:11:36 +02006215 else if (strcmp(args[*cur_arg + 1], "required") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01006216 newsrv->ssl_ctx.verify = SSL_SOCK_VERIFY_REQUIRED;
Emeric Brunef42d922012-10-11 16:11:36 +02006217 else {
6218 if (err)
6219 memprintf(err, "'%s' : unknown verify method '%s', only 'none' and 'required' are supported\n",
6220 args[*cur_arg], args[*cur_arg + 1]);
6221 return ERR_ALERT | ERR_FATAL;
6222 }
6223
Evan Broderbe554312013-06-27 00:05:25 -07006224 return 0;
6225}
6226
6227/* parse the "verifyhost" server keyword */
6228static int srv_parse_verifyhost(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
6229{
6230 if (!*args[*cur_arg + 1]) {
6231 if (err)
6232 memprintf(err, "'%s' : missing hostname to verify against", args[*cur_arg]);
6233 return ERR_ALERT | ERR_FATAL;
6234 }
6235
6236 newsrv->ssl_ctx.verify_host = strdup(args[*cur_arg + 1]);
6237
Emeric Brunef42d922012-10-11 16:11:36 +02006238 return 0;
6239}
6240
Emeric Brun2c86cbf2014-10-30 15:56:50 +01006241/* parse the "ssl-default-bind-options" keyword in global section */
6242static int ssl_parse_default_bind_options(char **args, int section_type, struct proxy *curpx,
6243 struct proxy *defpx, const char *file, int line,
6244 char **err) {
6245 int i = 1;
6246
6247 if (*(args[i]) == 0) {
6248 memprintf(err, "global statement '%s' expects an option as an argument.", args[0]);
6249 return -1;
6250 }
6251 while (*(args[i])) {
6252 if (!strcmp(args[i], "no-sslv3"))
Willy Tarreauef934602016-12-22 23:12:01 +01006253 global_ssl.listen_default_ssloptions |= BC_SSL_O_NO_SSLV3;
Emeric Brun2c86cbf2014-10-30 15:56:50 +01006254 else if (!strcmp(args[i], "no-tlsv10"))
Willy Tarreauef934602016-12-22 23:12:01 +01006255 global_ssl.listen_default_ssloptions |= BC_SSL_O_NO_TLSV10;
Emeric Brun2c86cbf2014-10-30 15:56:50 +01006256 else if (!strcmp(args[i], "no-tlsv11"))
Willy Tarreauef934602016-12-22 23:12:01 +01006257 global_ssl.listen_default_ssloptions |= BC_SSL_O_NO_TLSV11;
Emeric Brun2c86cbf2014-10-30 15:56:50 +01006258 else if (!strcmp(args[i], "no-tlsv12"))
Willy Tarreauef934602016-12-22 23:12:01 +01006259 global_ssl.listen_default_ssloptions |= BC_SSL_O_NO_TLSV12;
Emeric Brun2c86cbf2014-10-30 15:56:50 +01006260 else if (!strcmp(args[i], "force-sslv3"))
Willy Tarreauef934602016-12-22 23:12:01 +01006261 global_ssl.listen_default_ssloptions |= BC_SSL_O_USE_SSLV3;
Emeric Brun2c86cbf2014-10-30 15:56:50 +01006262 else if (!strcmp(args[i], "force-tlsv10"))
Willy Tarreauef934602016-12-22 23:12:01 +01006263 global_ssl.listen_default_ssloptions |= BC_SSL_O_USE_TLSV10;
Emeric Brun2c86cbf2014-10-30 15:56:50 +01006264 else if (!strcmp(args[i], "force-tlsv11")) {
6265#if SSL_OP_NO_TLSv1_1
Willy Tarreauef934602016-12-22 23:12:01 +01006266 global_ssl.listen_default_ssloptions |= BC_SSL_O_USE_TLSV11;
Emeric Brun2c86cbf2014-10-30 15:56:50 +01006267#else
6268 memprintf(err, "'%s' '%s': library does not support protocol TLSv1.1", args[0], args[i]);
6269 return -1;
6270#endif
6271 }
6272 else if (!strcmp(args[i], "force-tlsv12")) {
6273#if SSL_OP_NO_TLSv1_2
Willy Tarreauef934602016-12-22 23:12:01 +01006274 global_ssl.listen_default_ssloptions |= BC_SSL_O_USE_TLSV12;
Emeric Brun2c86cbf2014-10-30 15:56:50 +01006275#else
6276 memprintf(err, "'%s' '%s': library does not support protocol TLSv1.2", args[0], args[i]);
6277 return -1;
6278#endif
6279 }
6280 else if (!strcmp(args[i], "no-tls-tickets"))
Willy Tarreauef934602016-12-22 23:12:01 +01006281 global_ssl.listen_default_ssloptions |= BC_SSL_O_NO_TLS_TICKETS;
Emeric Brun2c86cbf2014-10-30 15:56:50 +01006282 else {
6283 memprintf(err, "unknown option '%s' on global statement '%s'.", args[i], args[0]);
6284 return -1;
6285 }
6286 i++;
6287 }
6288 return 0;
6289}
6290
6291/* parse the "ssl-default-server-options" keyword in global section */
6292static int ssl_parse_default_server_options(char **args, int section_type, struct proxy *curpx,
6293 struct proxy *defpx, const char *file, int line,
6294 char **err) {
6295 int i = 1;
6296
6297 if (*(args[i]) == 0) {
6298 memprintf(err, "global statement '%s' expects an option as an argument.", args[0]);
6299 return -1;
6300 }
6301 while (*(args[i])) {
6302 if (!strcmp(args[i], "no-sslv3"))
Willy Tarreauef934602016-12-22 23:12:01 +01006303 global_ssl.connect_default_ssloptions |= SRV_SSL_O_NO_SSLV3;
Emeric Brun2c86cbf2014-10-30 15:56:50 +01006304 else if (!strcmp(args[i], "no-tlsv10"))
Willy Tarreauef934602016-12-22 23:12:01 +01006305 global_ssl.connect_default_ssloptions |= SRV_SSL_O_NO_TLSV10;
Emeric Brun2c86cbf2014-10-30 15:56:50 +01006306 else if (!strcmp(args[i], "no-tlsv11"))
Willy Tarreauef934602016-12-22 23:12:01 +01006307 global_ssl.connect_default_ssloptions |= SRV_SSL_O_NO_TLSV11;
Emeric Brun2c86cbf2014-10-30 15:56:50 +01006308 else if (!strcmp(args[i], "no-tlsv12"))
Willy Tarreauef934602016-12-22 23:12:01 +01006309 global_ssl.connect_default_ssloptions |= SRV_SSL_O_NO_TLSV12;
Emeric Brun2c86cbf2014-10-30 15:56:50 +01006310 else if (!strcmp(args[i], "force-sslv3"))
Willy Tarreauef934602016-12-22 23:12:01 +01006311 global_ssl.connect_default_ssloptions |= SRV_SSL_O_USE_SSLV3;
Emeric Brun2c86cbf2014-10-30 15:56:50 +01006312 else if (!strcmp(args[i], "force-tlsv10"))
Willy Tarreauef934602016-12-22 23:12:01 +01006313 global_ssl.connect_default_ssloptions |= SRV_SSL_O_USE_TLSV10;
Emeric Brun2c86cbf2014-10-30 15:56:50 +01006314 else if (!strcmp(args[i], "force-tlsv11")) {
6315#if SSL_OP_NO_TLSv1_1
Willy Tarreauef934602016-12-22 23:12:01 +01006316 global_ssl.connect_default_ssloptions |= SRV_SSL_O_USE_TLSV11;
Emeric Brun2c86cbf2014-10-30 15:56:50 +01006317#else
6318 memprintf(err, "'%s' '%s': library does not support protocol TLSv1.1", args[0], args[i]);
6319 return -1;
6320#endif
6321 }
6322 else if (!strcmp(args[i], "force-tlsv12")) {
6323#if SSL_OP_NO_TLSv1_2
Willy Tarreauef934602016-12-22 23:12:01 +01006324 global_ssl.connect_default_ssloptions |= SRV_SSL_O_USE_TLSV12;
Emeric Brun2c86cbf2014-10-30 15:56:50 +01006325#else
6326 memprintf(err, "'%s' '%s': library does not support protocol TLSv1.2", args[0], args[i]);
6327 return -1;
6328#endif
6329 }
6330 else if (!strcmp(args[i], "no-tls-tickets"))
Willy Tarreauef934602016-12-22 23:12:01 +01006331 global_ssl.connect_default_ssloptions |= SRV_SSL_O_NO_TLS_TICKETS;
Emeric Brun2c86cbf2014-10-30 15:56:50 +01006332 else {
6333 memprintf(err, "unknown option '%s' on global statement '%s'.", args[i], args[0]);
6334 return -1;
6335 }
6336 i++;
6337 }
6338 return 0;
6339}
6340
Willy Tarreau8c3b0fd2016-12-21 22:44:46 +01006341/* parse the "ca-base" / "crt-base" keywords in global section.
6342 * Returns <0 on alert, >0 on warning, 0 on success.
6343 */
6344static int ssl_parse_global_ca_crt_base(char **args, int section_type, struct proxy *curpx,
6345 struct proxy *defpx, const char *file, int line,
6346 char **err)
6347{
6348 char **target;
6349
Willy Tarreauef934602016-12-22 23:12:01 +01006350 target = (args[0][1] == 'a') ? &global_ssl.ca_base : &global_ssl.crt_base;
Willy Tarreau8c3b0fd2016-12-21 22:44:46 +01006351
6352 if (too_many_args(1, args, err, NULL))
6353 return -1;
6354
6355 if (*target) {
6356 memprintf(err, "'%s' already specified.", args[0]);
6357 return -1;
6358 }
6359
6360 if (*(args[1]) == 0) {
6361 memprintf(err, "global statement '%s' expects a directory path as an argument.", args[0]);
6362 return -1;
6363 }
6364 *target = strdup(args[1]);
6365 return 0;
6366}
6367
Willy Tarreauf22e9682016-12-21 23:23:19 +01006368/* parse the "ssl-default-bind-ciphers" / "ssl-default-server-ciphers" keywords
6369 * in global section. Returns <0 on alert, >0 on warning, 0 on success.
6370 */
6371static int ssl_parse_global_ciphers(char **args, int section_type, struct proxy *curpx,
6372 struct proxy *defpx, const char *file, int line,
6373 char **err)
6374{
6375 char **target;
6376
Willy Tarreauef934602016-12-22 23:12:01 +01006377 target = (args[0][12] == 'b') ? &global_ssl.listen_default_ciphers : &global_ssl.connect_default_ciphers;
Willy Tarreauf22e9682016-12-21 23:23:19 +01006378
6379 if (too_many_args(1, args, err, NULL))
6380 return -1;
6381
6382 if (*(args[1]) == 0) {
6383 memprintf(err, "global statement '%s' expects a cipher suite as an argument.", args[0]);
6384 return -1;
6385 }
6386
6387 free(*target);
6388 *target = strdup(args[1]);
6389 return 0;
6390}
6391
Willy Tarreau9ceda382016-12-21 23:13:03 +01006392/* parse various global tune.ssl settings consisting in positive integers.
6393 * Returns <0 on alert, >0 on warning, 0 on success.
6394 */
6395static int ssl_parse_global_int(char **args, int section_type, struct proxy *curpx,
6396 struct proxy *defpx, const char *file, int line,
6397 char **err)
6398{
6399 int *target;
6400
6401 if (strcmp(args[0], "tune.ssl.cachesize") == 0)
6402 target = &global.tune.sslcachesize;
6403 else if (strcmp(args[0], "tune.ssl.maxrecord") == 0)
Willy Tarreauef934602016-12-22 23:12:01 +01006404 target = (int *)&global_ssl.max_record;
Willy Tarreau9ceda382016-12-21 23:13:03 +01006405 else if (strcmp(args[0], "tune.ssl.ssl-ctx-cache-size") == 0)
Willy Tarreauef934602016-12-22 23:12:01 +01006406 target = &global_ssl.ctx_cache;
Willy Tarreau0bea58d2016-12-21 23:17:25 +01006407 else if (strcmp(args[0], "maxsslconn") == 0)
6408 target = &global.maxsslconn;
Willy Tarreau9ceda382016-12-21 23:13:03 +01006409 else {
6410 memprintf(err, "'%s' keyword not unhandled (please report this bug).", args[0]);
6411 return -1;
6412 }
6413
6414 if (too_many_args(1, args, err, NULL))
6415 return -1;
6416
6417 if (*(args[1]) == 0) {
6418 memprintf(err, "'%s' expects an integer argument.", args[0]);
6419 return -1;
6420 }
6421
6422 *target = atoi(args[1]);
6423 if (*target < 0) {
6424 memprintf(err, "'%s' expects a positive numeric value.", args[0]);
6425 return -1;
6426 }
6427 return 0;
6428}
6429
6430/* parse "ssl.force-private-cache".
6431 * Returns <0 on alert, >0 on warning, 0 on success.
6432 */
6433static int ssl_parse_global_private_cache(char **args, int section_type, struct proxy *curpx,
6434 struct proxy *defpx, const char *file, int line,
6435 char **err)
6436{
6437 if (too_many_args(0, args, err, NULL))
6438 return -1;
6439
Willy Tarreauef934602016-12-22 23:12:01 +01006440 global_ssl.private_cache = 1;
Willy Tarreau9ceda382016-12-21 23:13:03 +01006441 return 0;
6442}
6443
6444/* parse "ssl.lifetime".
6445 * Returns <0 on alert, >0 on warning, 0 on success.
6446 */
6447static int ssl_parse_global_lifetime(char **args, int section_type, struct proxy *curpx,
6448 struct proxy *defpx, const char *file, int line,
6449 char **err)
6450{
6451 const char *res;
6452
6453 if (too_many_args(1, args, err, NULL))
6454 return -1;
6455
6456 if (*(args[1]) == 0) {
6457 memprintf(err, "'%s' expects ssl sessions <lifetime> in seconds as argument.", args[0]);
6458 return -1;
6459 }
6460
Willy Tarreauef934602016-12-22 23:12:01 +01006461 res = parse_time_err(args[1], &global_ssl.life_time, TIME_UNIT_S);
Willy Tarreau9ceda382016-12-21 23:13:03 +01006462 if (res) {
6463 memprintf(err, "unexpected character '%c' in argument to <%s>.", *res, args[0]);
6464 return -1;
6465 }
6466 return 0;
6467}
6468
6469#ifndef OPENSSL_NO_DH
Willy Tarreau14e36a12016-12-21 23:28:13 +01006470/* parse "ssl-dh-param-file".
6471 * Returns <0 on alert, >0 on warning, 0 on success.
6472 */
6473static int ssl_parse_global_dh_param_file(char **args, int section_type, struct proxy *curpx,
6474 struct proxy *defpx, const char *file, int line,
6475 char **err)
6476{
6477 if (too_many_args(1, args, err, NULL))
6478 return -1;
6479
6480 if (*(args[1]) == 0) {
6481 memprintf(err, "'%s' expects a file path as an argument.", args[0]);
6482 return -1;
6483 }
6484
6485 if (ssl_sock_load_global_dh_param_from_file(args[1])) {
6486 memprintf(err, "'%s': unable to load DH parameters from file <%s>.", args[0], args[1]);
6487 return -1;
6488 }
6489 return 0;
6490}
6491
Willy Tarreau9ceda382016-12-21 23:13:03 +01006492/* parse "ssl.default-dh-param".
6493 * Returns <0 on alert, >0 on warning, 0 on success.
6494 */
6495static int ssl_parse_global_default_dh(char **args, int section_type, struct proxy *curpx,
6496 struct proxy *defpx, const char *file, int line,
6497 char **err)
6498{
6499 if (too_many_args(1, args, err, NULL))
6500 return -1;
6501
6502 if (*(args[1]) == 0) {
6503 memprintf(err, "'%s' expects an integer argument.", args[0]);
6504 return -1;
6505 }
6506
Willy Tarreauef934602016-12-22 23:12:01 +01006507 global_ssl.default_dh_param = atoi(args[1]);
6508 if (global_ssl.default_dh_param < 1024) {
Willy Tarreau9ceda382016-12-21 23:13:03 +01006509 memprintf(err, "'%s' expects a value >= 1024.", args[0]);
6510 return -1;
6511 }
6512 return 0;
6513}
6514#endif
6515
6516
William Lallemand32af2032016-10-29 18:09:35 +02006517/* This function is used with TLS ticket keys management. It permits to browse
6518 * each reference. The variable <getnext> must contain the current node,
6519 * <end> point to the root node.
6520 */
6521#if (defined SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB && TLS_TICKETS_NO > 0)
6522static inline
6523struct tls_keys_ref *tlskeys_list_get_next(struct tls_keys_ref *getnext, struct list *end)
6524{
6525 struct tls_keys_ref *ref = getnext;
6526
6527 while (1) {
6528
6529 /* Get next list entry. */
6530 ref = LIST_NEXT(&ref->list, struct tls_keys_ref *, list);
6531
6532 /* If the entry is the last of the list, return NULL. */
6533 if (&ref->list == end)
6534 return NULL;
6535
6536 return ref;
6537 }
6538}
6539
6540static inline
6541struct tls_keys_ref *tlskeys_ref_lookup_ref(const char *reference)
6542{
6543 int id;
6544 char *error;
6545
6546 /* If the reference starts by a '#', this is numeric id. */
6547 if (reference[0] == '#') {
6548 /* Try to convert the numeric id. If the conversion fails, the lookup fails. */
6549 id = strtol(reference + 1, &error, 10);
6550 if (*error != '\0')
6551 return NULL;
6552
6553 /* Perform the unique id lookup. */
6554 return tlskeys_ref_lookupid(id);
6555 }
6556
6557 /* Perform the string lookup. */
6558 return tlskeys_ref_lookup(reference);
6559}
6560#endif
6561
6562
6563#if (defined SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB && TLS_TICKETS_NO > 0)
6564
6565static int cli_io_handler_tlskeys_files(struct appctx *appctx);
6566
6567static inline int cli_io_handler_tlskeys_entries(struct appctx *appctx) {
6568 return cli_io_handler_tlskeys_files(appctx);
6569}
6570
Willy Tarreauf5f26e82016-12-16 18:47:27 +01006571/* dumps all tls keys. Relies on cli.i0 (non-null = only list file names), cli.i1
6572 * (next index to be dumped), and cli.p0 (next key reference).
6573 */
William Lallemand32af2032016-10-29 18:09:35 +02006574static int cli_io_handler_tlskeys_files(struct appctx *appctx) {
6575
6576 struct stream_interface *si = appctx->owner;
6577
6578 switch (appctx->st2) {
6579 case STAT_ST_INIT:
6580 /* Display the column headers. If the message cannot be sent,
6581 * quit the fucntion with returning 0. The function is called
6582 * later and restart at the state "STAT_ST_INIT".
6583 */
6584 chunk_reset(&trash);
6585
6586 if (appctx->io_handler == cli_io_handler_tlskeys_entries)
6587 chunk_appendf(&trash, "# id secret\n");
6588 else
6589 chunk_appendf(&trash, "# id (file)\n");
6590
6591 if (bi_putchk(si_ic(si), &trash) == -1) {
6592 si_applet_cant_put(si);
6593 return 0;
6594 }
6595
William Lallemand32af2032016-10-29 18:09:35 +02006596 /* Now, we start the browsing of the references lists.
6597 * Note that the following call to LIST_ELEM return bad pointer. The only
6598 * available field of this pointer is <list>. It is used with the function
6599 * tlskeys_list_get_next() for retruning the first available entry
6600 */
Willy Tarreauf5f26e82016-12-16 18:47:27 +01006601 if (appctx->ctx.cli.p0 == NULL) {
6602 appctx->ctx.cli.p0 = LIST_ELEM(&tlskeys_reference, struct tls_keys_ref *, list);
6603 appctx->ctx.cli.p0 = tlskeys_list_get_next(appctx->ctx.cli.p0, &tlskeys_reference);
William Lallemand32af2032016-10-29 18:09:35 +02006604 }
6605
6606 appctx->st2 = STAT_ST_LIST;
6607 /* fall through */
6608
6609 case STAT_ST_LIST:
Willy Tarreauf5f26e82016-12-16 18:47:27 +01006610 while (appctx->ctx.cli.p0) {
6611 struct tls_keys_ref *ref = appctx->ctx.cli.p0;
6612 int head = ref->tls_ticket_enc_index;
William Lallemand32af2032016-10-29 18:09:35 +02006613
6614 chunk_reset(&trash);
Willy Tarreauf5f26e82016-12-16 18:47:27 +01006615 if (appctx->io_handler == cli_io_handler_tlskeys_entries && appctx->ctx.cli.i1 == 0)
William Lallemand32af2032016-10-29 18:09:35 +02006616 chunk_appendf(&trash, "# ");
Willy Tarreauf5f26e82016-12-16 18:47:27 +01006617
6618 if (appctx->ctx.cli.i1 == 0)
6619 chunk_appendf(&trash, "%d (%s)\n", ref->unique_id, ref->filename);
6620
William Lallemand32af2032016-10-29 18:09:35 +02006621 if (appctx->io_handler == cli_io_handler_tlskeys_entries) {
Willy Tarreauf5f26e82016-12-16 18:47:27 +01006622 while (appctx->ctx.cli.i1 < TLS_TICKETS_NO) {
William Lallemand32af2032016-10-29 18:09:35 +02006623 struct chunk *t2 = get_trash_chunk();
6624
6625 chunk_reset(t2);
6626 /* should never fail here because we dump only a key in the t2 buffer */
Willy Tarreauf5f26e82016-12-16 18:47:27 +01006627 t2->len = a2base64((char *)(ref->tlskeys + (head + 2 + appctx->ctx.cli.i1) % TLS_TICKETS_NO),
William Lallemand32af2032016-10-29 18:09:35 +02006628 sizeof(struct tls_sess_key), t2->str, t2->size);
Willy Tarreauf5f26e82016-12-16 18:47:27 +01006629 chunk_appendf(&trash, "%d.%d %s\n", ref->unique_id, appctx->ctx.cli.i1, t2->str);
William Lallemand32af2032016-10-29 18:09:35 +02006630
6631 if (bi_putchk(si_ic(si), &trash) == -1) {
6632 /* let's try again later from this stream. We add ourselves into
6633 * this stream's users so that it can remove us upon termination.
6634 */
6635 si_applet_cant_put(si);
6636 return 0;
6637 }
Willy Tarreauf5f26e82016-12-16 18:47:27 +01006638 appctx->ctx.cli.i1++;
William Lallemand32af2032016-10-29 18:09:35 +02006639 }
Willy Tarreauf5f26e82016-12-16 18:47:27 +01006640 appctx->ctx.cli.i1 = 0;
William Lallemand32af2032016-10-29 18:09:35 +02006641 }
6642 if (bi_putchk(si_ic(si), &trash) == -1) {
6643 /* let's try again later from this stream. We add ourselves into
6644 * this stream's users so that it can remove us upon termination.
6645 */
6646 si_applet_cant_put(si);
6647 return 0;
6648 }
6649
Willy Tarreauf5f26e82016-12-16 18:47:27 +01006650 if (appctx->ctx.cli.i0 == 0) /* don't display everything if not necessary */
William Lallemand32af2032016-10-29 18:09:35 +02006651 break;
6652
6653 /* get next list entry and check the end of the list */
Willy Tarreauf5f26e82016-12-16 18:47:27 +01006654 appctx->ctx.cli.p0 = tlskeys_list_get_next(appctx->ctx.cli.p0, &tlskeys_reference);
William Lallemand32af2032016-10-29 18:09:35 +02006655 }
6656
6657 appctx->st2 = STAT_ST_FIN;
6658 /* fall through */
6659
6660 default:
6661 appctx->st2 = STAT_ST_FIN;
6662 return 1;
6663 }
6664 return 0;
6665}
6666
6667#endif
6668
Willy Tarreauf5f26e82016-12-16 18:47:27 +01006669/* sets cli.i0 to non-zero if only file lists should be dumped */
William Lallemand32af2032016-10-29 18:09:35 +02006670static int cli_parse_show_tlskeys(char **args, struct appctx *appctx, void *private)
6671{
William Lallemand32af2032016-10-29 18:09:35 +02006672 /* no parameter, shows only file list */
6673 if (!*args[2]) {
Willy Tarreauf5f26e82016-12-16 18:47:27 +01006674 appctx->ctx.cli.i0 = 1;
William Lallemand32af2032016-10-29 18:09:35 +02006675 appctx->io_handler = cli_io_handler_tlskeys_files;
Willy Tarreau3067bfa2016-12-05 14:50:15 +01006676 return 0;
William Lallemand32af2032016-10-29 18:09:35 +02006677 }
6678
6679 if (args[2][0] == '*') {
6680 /* list every TLS ticket keys */
Willy Tarreauf5f26e82016-12-16 18:47:27 +01006681 appctx->ctx.cli.i0 = 1;
William Lallemand32af2032016-10-29 18:09:35 +02006682 } else {
Willy Tarreauf5f26e82016-12-16 18:47:27 +01006683 appctx->ctx.cli.p0 = tlskeys_ref_lookup_ref(args[2]);
6684 if (!appctx->ctx.cli.p0) {
William Lallemand32af2032016-10-29 18:09:35 +02006685 appctx->ctx.cli.msg = "'show tls-keys' unable to locate referenced filename\n";
Willy Tarreau3b6e5472016-11-24 15:53:53 +01006686 appctx->st0 = CLI_ST_PRINT;
William Lallemand32af2032016-10-29 18:09:35 +02006687 return 1;
6688 }
6689 }
William Lallemand32af2032016-10-29 18:09:35 +02006690 appctx->io_handler = cli_io_handler_tlskeys_entries;
Willy Tarreau3067bfa2016-12-05 14:50:15 +01006691 return 0;
William Lallemand32af2032016-10-29 18:09:35 +02006692}
6693
6694
6695static int cli_parse_set_tlskeys(char **args, struct appctx *appctx, void *private)
6696{
Willy Tarreauf5f26e82016-12-16 18:47:27 +01006697 struct tls_keys_ref *ref;
6698
William Lallemand32af2032016-10-29 18:09:35 +02006699 /* Expect two parameters: the filename and the new new TLS key in encoding */
6700 if (!*args[3] || !*args[4]) {
6701 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 +01006702 appctx->st0 = CLI_ST_PRINT;
William Lallemand32af2032016-10-29 18:09:35 +02006703 return 1;
6704 }
6705
Willy Tarreauf5f26e82016-12-16 18:47:27 +01006706 ref = tlskeys_ref_lookup_ref(args[3]);
6707 if (!ref) {
William Lallemand32af2032016-10-29 18:09:35 +02006708 appctx->ctx.cli.msg = "'set ssl tls-key' unable to locate referenced filename\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
6713 trash.len = base64dec(args[4], strlen(args[4]), trash.str, trash.size);
6714 if (trash.len != sizeof(struct tls_sess_key)) {
6715 appctx->ctx.cli.msg = "'set ssl tls-key' received invalid base64 encoded TLS key.\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
Willy Tarreauf5f26e82016-12-16 18:47:27 +01006720 memcpy(ref->tlskeys + ((ref->tls_ticket_enc_index + 2) % TLS_TICKETS_NO), trash.str, trash.len);
6721 ref->tls_ticket_enc_index = (ref->tls_ticket_enc_index + 1) % TLS_TICKETS_NO;
William Lallemand32af2032016-10-29 18:09:35 +02006722
6723 appctx->ctx.cli.msg = "TLS ticket key updated!";
Willy Tarreau3b6e5472016-11-24 15:53:53 +01006724 appctx->st0 = CLI_ST_PRINT;
William Lallemand32af2032016-10-29 18:09:35 +02006725 return 1;
6726
6727}
6728
6729static int cli_parse_set_ocspresponse(char **args, struct appctx *appctx, void *private)
6730{
6731#if (defined SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB && !defined OPENSSL_NO_OCSP)
6732 char *err = NULL;
6733
6734 /* Expect one parameter: the new response in base64 encoding */
6735 if (!*args[3]) {
6736 appctx->ctx.cli.msg = "'set ssl ocsp-response' expects response in base64 encoding.\n";
Willy Tarreau3b6e5472016-11-24 15:53:53 +01006737 appctx->st0 = CLI_ST_PRINT;
William Lallemand32af2032016-10-29 18:09:35 +02006738 return 1;
6739 }
6740
6741 trash.len = base64dec(args[3], strlen(args[3]), trash.str, trash.size);
6742 if (trash.len < 0) {
6743 appctx->ctx.cli.msg = "'set ssl ocsp-response' received invalid base64 encoded response.\n";
Willy Tarreau3b6e5472016-11-24 15:53:53 +01006744 appctx->st0 = CLI_ST_PRINT;
William Lallemand32af2032016-10-29 18:09:35 +02006745 return 1;
6746 }
6747
6748 if (ssl_sock_update_ocsp_response(&trash, &err)) {
6749 if (err) {
6750 memprintf(&err, "%s.\n", err);
6751 appctx->ctx.cli.err = err;
Willy Tarreau3b6e5472016-11-24 15:53:53 +01006752 appctx->st0 = CLI_ST_PRINT_FREE;
William Lallemand32af2032016-10-29 18:09:35 +02006753 }
6754 return 1;
6755 }
6756 appctx->ctx.cli.msg = "OCSP Response updated!";
Willy Tarreau3b6e5472016-11-24 15:53:53 +01006757 appctx->st0 = CLI_ST_PRINT;
William Lallemand32af2032016-10-29 18:09:35 +02006758 return 1;
6759#else
6760 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 +01006761 appctx->st0 = CLI_ST_PRINT;
William Lallemand32af2032016-10-29 18:09:35 +02006762 return 1;
6763#endif
6764
6765}
6766
6767/* register cli keywords */
6768static struct cli_kw_list cli_kws = {{ },{
6769#if (defined SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB && TLS_TICKETS_NO > 0)
6770 { { "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 },
6771 { { "set", "ssl", "tls-keys", NULL }, NULL, cli_parse_set_tlskeys, NULL },
6772 { { "set", "ssl", "ocsp-response", NULL }, NULL, cli_parse_set_ocspresponse, NULL },
6773#endif
6774 { { NULL }, NULL, NULL, NULL }
6775}};
6776
6777
6778
Willy Tarreau7875d092012-09-10 08:20:03 +02006779/* Note: must not be declared <const> as its list will be overwritten.
6780 * Please take care of keeping this list alphabetically sorted.
6781 */
Willy Tarreaudc13c112013-06-21 23:16:39 +02006782static struct sample_fetch_kw_list sample_fetch_keywords = {ILH, {
Emeric Brun645ae792014-04-30 14:21:06 +02006783 { "ssl_bc", smp_fetch_ssl_fc, 0, NULL, SMP_T_BOOL, SMP_USE_L5SRV },
Thierry FOURNIER07ee64e2015-07-06 23:43:03 +02006784 { "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 +02006785 { "ssl_bc_cipher", smp_fetch_ssl_fc_cipher, 0, NULL, SMP_T_STR, SMP_USE_L5SRV },
6786 { "ssl_bc_protocol", smp_fetch_ssl_fc_protocol, 0, NULL, SMP_T_STR, SMP_USE_L5SRV },
Emeric Brunb73a9b02014-04-30 18:49:19 +02006787 { "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 +02006788 { "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 +02006789 { "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 +02006790 { "ssl_c_ca_err", smp_fetch_ssl_c_ca_err, 0, NULL, SMP_T_SINT, SMP_USE_L5CLI },
6791 { "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 +01006792 { "ssl_c_der", smp_fetch_ssl_x_der, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Thierry FOURNIER07ee64e2015-07-06 23:43:03 +02006793 { "ssl_c_err", smp_fetch_ssl_c_err, 0, NULL, SMP_T_SINT, SMP_USE_L5CLI },
Emeric Brunba841a12014-04-30 17:05:08 +02006794 { "ssl_c_i_dn", smp_fetch_ssl_x_i_dn, ARG2(0,STR,SINT), NULL, SMP_T_STR, SMP_USE_L5CLI },
6795 { "ssl_c_key_alg", smp_fetch_ssl_x_key_alg, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
6796 { "ssl_c_notafter", smp_fetch_ssl_x_notafter, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
6797 { "ssl_c_notbefore", smp_fetch_ssl_x_notbefore, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
6798 { "ssl_c_sig_alg", smp_fetch_ssl_x_sig_alg, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
6799 { "ssl_c_s_dn", smp_fetch_ssl_x_s_dn, ARG2(0,STR,SINT), NULL, SMP_T_STR, SMP_USE_L5CLI },
6800 { "ssl_c_serial", smp_fetch_ssl_x_serial, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
6801 { "ssl_c_sha1", smp_fetch_ssl_x_sha1, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Willy Tarreau80aca902013-01-07 15:42:20 +01006802 { "ssl_c_used", smp_fetch_ssl_c_used, 0, NULL, SMP_T_BOOL, SMP_USE_L5CLI },
Thierry FOURNIER07ee64e2015-07-06 23:43:03 +02006803 { "ssl_c_verify", smp_fetch_ssl_c_verify, 0, NULL, SMP_T_SINT, SMP_USE_L5CLI },
6804 { "ssl_c_version", smp_fetch_ssl_x_version, 0, NULL, SMP_T_SINT, SMP_USE_L5CLI },
Emeric Brun43e79582014-10-29 19:03:26 +01006805 { "ssl_f_der", smp_fetch_ssl_x_der, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Emeric Brunba841a12014-04-30 17:05:08 +02006806 { "ssl_f_i_dn", smp_fetch_ssl_x_i_dn, ARG2(0,STR,SINT), NULL, SMP_T_STR, SMP_USE_L5CLI },
6807 { "ssl_f_key_alg", smp_fetch_ssl_x_key_alg, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
6808 { "ssl_f_notafter", smp_fetch_ssl_x_notafter, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
6809 { "ssl_f_notbefore", smp_fetch_ssl_x_notbefore, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
6810 { "ssl_f_sig_alg", smp_fetch_ssl_x_sig_alg, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
6811 { "ssl_f_s_dn", smp_fetch_ssl_x_s_dn, ARG2(0,STR,SINT), NULL, SMP_T_STR, SMP_USE_L5CLI },
6812 { "ssl_f_serial", smp_fetch_ssl_x_serial, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Emeric Brun55f4fa82014-04-30 17:11:25 +02006813 { "ssl_f_sha1", smp_fetch_ssl_x_sha1, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Thierry FOURNIER07ee64e2015-07-06 23:43:03 +02006814 { "ssl_f_version", smp_fetch_ssl_x_version, 0, NULL, SMP_T_SINT, SMP_USE_L5CLI },
Willy Tarreau80aca902013-01-07 15:42:20 +01006815 { "ssl_fc", smp_fetch_ssl_fc, 0, NULL, SMP_T_BOOL, SMP_USE_L5CLI },
Thierry FOURNIER07ee64e2015-07-06 23:43:03 +02006816 { "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 +01006817 { "ssl_fc_cipher", smp_fetch_ssl_fc_cipher, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Willy Tarreau80aca902013-01-07 15:42:20 +01006818 { "ssl_fc_has_crt", smp_fetch_ssl_fc_has_crt, 0, NULL, SMP_T_BOOL, SMP_USE_L5CLI },
6819 { "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 +02006820 { "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 +02006821#ifdef OPENSSL_NPN_NEGOTIATED
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01006822 { "ssl_fc_npn", smp_fetch_ssl_fc_npn, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Willy Tarreaua33c6542012-10-15 13:19:06 +02006823#endif
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01006824#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01006825 { "ssl_fc_alpn", smp_fetch_ssl_fc_alpn, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Willy Tarreauab861d32013-04-02 02:30:41 +02006826#endif
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01006827 { "ssl_fc_protocol", smp_fetch_ssl_fc_protocol, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Emeric Brunb73a9b02014-04-30 18:49:19 +02006828 { "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 +02006829 { "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 +01006830 { "ssl_fc_session_id", smp_fetch_ssl_fc_session_id, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
6831 { "ssl_fc_sni", smp_fetch_ssl_fc_sni, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Willy Tarreau7875d092012-09-10 08:20:03 +02006832 { NULL, NULL, 0, 0, 0 },
6833}};
6834
6835/* Note: must not be declared <const> as its list will be overwritten.
6836 * Please take care of keeping this list alphabetically sorted.
6837 */
Willy Tarreaudc13c112013-06-21 23:16:39 +02006838static struct acl_kw_list acl_kws = {ILH, {
Thierry FOURNIERc5a4e982014-03-05 16:07:08 +01006839 { "ssl_fc_sni_end", "ssl_fc_sni", PAT_MATCH_END },
6840 { "ssl_fc_sni_reg", "ssl_fc_sni", PAT_MATCH_REG },
Willy Tarreau8ed669b2013-01-11 15:49:37 +01006841 { /* END */ },
Willy Tarreau7875d092012-09-10 08:20:03 +02006842}};
6843
Willy Tarreau79eeafa2012-09-14 07:53:05 +02006844/* Note: must not be declared <const> as its list will be overwritten.
6845 * Please take care of keeping this list alphabetically sorted, doing so helps
6846 * all code contributors.
6847 * Optional keywords are also declared with a NULL ->parse() function so that
6848 * the config parser can report an appropriate error when a known keyword was
6849 * not enabled.
6850 */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01006851static struct ssl_bind_kw ssl_bind_kws[] = {
6852 { "alpn", ssl_bind_parse_alpn, 1 }, /* set ALPN supported protocols */
6853 { "ca-file", ssl_bind_parse_ca_file, 1 }, /* set CAfile to process verify on client cert */
6854 { "ciphers", ssl_bind_parse_ciphers, 1 }, /* set SSL cipher suite */
6855 { "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 +01006856 { "curves", ssl_bind_parse_curves, 1 }, /* set SSL curve suite */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01006857 { "ecdhe", ssl_bind_parse_ecdhe, 1 }, /* defines named curve for elliptic curve Diffie-Hellman */
6858 { "force-sslv3", ssl_bind_parse_force_sslv3, 0 }, /* force SSLv3 */
6859 { "force-tlsv10", ssl_bind_parse_force_tlsv10, 0 }, /* force TLSv10 */
6860 { "force-tlsv11", ssl_bind_parse_force_tlsv11, 0 }, /* force TLSv11 */
6861 { "force-tlsv12", ssl_bind_parse_force_tlsv12, 0 }, /* force TLSv12 */
6862 { "no-sslv3", ssl_bind_parse_no_sslv3, 0 }, /* disable SSLv3 */
6863 { "no-tlsv10", ssl_bind_parse_no_tlsv10, 0 }, /* disable TLSv10 */
6864 { "no-tlsv11", ssl_bind_parse_no_tlsv11, 0 }, /* disable TLSv11 */
6865 { "no-tlsv12", ssl_bind_parse_no_tlsv12, 0 }, /* disable TLSv12 */
6866 { "no-tls-tickets", ssl_bind_parse_no_tls_tickets, 0 }, /* disable session resumption tickets */
6867 { "npn", ssl_bind_parse_npn, 1 }, /* set NPN supported protocols */
6868 { "verify", ssl_bind_parse_verify, 1 }, /* set SSL verify method */
6869 { NULL, NULL, 0 },
6870};
6871
Willy Tarreau51fb7652012-09-18 18:24:39 +02006872static struct bind_kw_list bind_kws = { "SSL", { }, {
Nenad Merdanovic05552d42015-02-27 19:56:49 +01006873 { "alpn", bind_parse_alpn, 1 }, /* set ALPN supported protocols */
6874 { "ca-file", bind_parse_ca_file, 1 }, /* set CAfile to process verify on client cert */
6875 { "ca-ignore-err", bind_parse_ignore_err, 1 }, /* set error IDs to ignore on verify depth > 0 */
Christopher Faulet31af49d2015-06-09 17:29:50 +02006876 { "ca-sign-file", bind_parse_ca_sign_file, 1 }, /* set CAFile used to generate and sign server certs */
6877 { "ca-sign-pass", bind_parse_ca_sign_pass, 1 }, /* set CAKey passphrase */
Nenad Merdanovic05552d42015-02-27 19:56:49 +01006878 { "ciphers", bind_parse_ciphers, 1 }, /* set SSL cipher suite */
6879 { "crl-file", bind_parse_crl_file, 1 }, /* set certificat revocation list file use on client cert verify */
6880 { "crt", bind_parse_crt, 1 }, /* load SSL certificates from this location */
6881 { "crt-ignore-err", bind_parse_ignore_err, 1 }, /* set error IDs to ingore on verify depth == 0 */
6882 { "crt-list", bind_parse_crt_list, 1 }, /* load a list of crt from this location */
Emmanuel Hocdete7f2b732017-01-09 16:15:54 +01006883 { "curves", bind_parse_curves, 1 }, /* set SSL curve suite */
Nenad Merdanovic05552d42015-02-27 19:56:49 +01006884 { "ecdhe", bind_parse_ecdhe, 1 }, /* defines named curve for elliptic curve Diffie-Hellman */
6885 { "force-sslv3", bind_parse_force_sslv3, 0 }, /* force SSLv3 */
6886 { "force-tlsv10", bind_parse_force_tlsv10, 0 }, /* force TLSv10 */
6887 { "force-tlsv11", bind_parse_force_tlsv11, 0 }, /* force TLSv11 */
6888 { "force-tlsv12", bind_parse_force_tlsv12, 0 }, /* force TLSv12 */
Christopher Faulet31af49d2015-06-09 17:29:50 +02006889 { "generate-certificates", bind_parse_generate_certs, 0 }, /* enable the server certificates generation */
Nenad Merdanovic05552d42015-02-27 19:56:49 +01006890 { "no-sslv3", bind_parse_no_sslv3, 0 }, /* disable SSLv3 */
6891 { "no-tlsv10", bind_parse_no_tlsv10, 0 }, /* disable TLSv10 */
6892 { "no-tlsv11", bind_parse_no_tlsv11, 0 }, /* disable TLSv11 */
6893 { "no-tlsv12", bind_parse_no_tlsv12, 0 }, /* disable TLSv12 */
6894 { "no-tls-tickets", bind_parse_no_tls_tickets, 0 }, /* disable session resumption tickets */
6895 { "ssl", bind_parse_ssl, 0 }, /* enable SSL processing */
6896 { "strict-sni", bind_parse_strict_sni, 0 }, /* refuse negotiation if sni doesn't match a certificate */
6897 { "tls-ticket-keys", bind_parse_tls_ticket_keys, 1 }, /* set file to load TLS ticket keys from */
6898 { "verify", bind_parse_verify, 1 }, /* set SSL verify method */
6899 { "npn", bind_parse_npn, 1 }, /* set NPN supported protocols */
Willy Tarreau79eeafa2012-09-14 07:53:05 +02006900 { NULL, NULL, 0 },
6901}};
Emeric Brun46591952012-05-18 15:47:34 +02006902
Willy Tarreau92faadf2012-10-10 23:04:25 +02006903/* Note: must not be declared <const> as its list will be overwritten.
6904 * Please take care of keeping this list alphabetically sorted, doing so helps
6905 * all code contributors.
6906 * Optional keywords are also declared with a NULL ->parse() function so that
6907 * the config parser can report an appropriate error when a known keyword was
6908 * not enabled.
6909 */
6910static struct srv_kw_list srv_kws = { "SSL", { }, {
Emeric Brunef42d922012-10-11 16:11:36 +02006911 { "ca-file", srv_parse_ca_file, 1, 0 }, /* set CAfile to process verify server cert */
Emeric Brunecc91fe2012-10-11 15:05:10 +02006912 { "check-ssl", srv_parse_check_ssl, 0, 0 }, /* enable SSL for health checks */
6913 { "ciphers", srv_parse_ciphers, 1, 0 }, /* select the cipher suite */
Emeric Brunef42d922012-10-11 16:11:36 +02006914 { "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 +02006915 { "crt", srv_parse_crt, 1, 0 }, /* set client certificate */
Emeric Brunecc91fe2012-10-11 15:05:10 +02006916 { "force-sslv3", srv_parse_force_sslv3, 0, 0 }, /* force SSLv3 */
6917 { "force-tlsv10", srv_parse_force_tlsv10, 0, 0 }, /* force TLSv10 */
6918 { "force-tlsv11", srv_parse_force_tlsv11, 0, 0 }, /* force TLSv11 */
6919 { "force-tlsv12", srv_parse_force_tlsv12, 0, 0 }, /* force TLSv12 */
Willy Tarreau2a3fb1c2015-02-05 16:47:07 +01006920 { "no-ssl-reuse", srv_parse_no_ssl_reuse, 0, 0 }, /* disable session reuse */
Emeric Brunecc91fe2012-10-11 15:05:10 +02006921 { "no-sslv3", srv_parse_no_sslv3, 0, 0 }, /* disable SSLv3 */
6922 { "no-tlsv10", srv_parse_no_tlsv10, 0, 0 }, /* disable TLSv10 */
6923 { "no-tlsv11", srv_parse_no_tlsv11, 0, 0 }, /* disable TLSv11 */
6924 { "no-tlsv12", srv_parse_no_tlsv12, 0, 0 }, /* disable TLSv12 */
Emeric Brunf9c5c472012-10-11 15:28:34 +02006925 { "no-tls-tickets", srv_parse_no_tls_tickets, 0, 0 }, /* disable session resumption tickets */
David Safb76832014-05-08 23:42:08 -04006926 { "send-proxy-v2-ssl", srv_parse_send_proxy_ssl, 0, 0 }, /* send PROXY protocol header v2 with SSL info */
6927 { "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 +02006928 { "sni", srv_parse_sni, 1, 0 }, /* send SNI extension */
Emeric Brunecc91fe2012-10-11 15:05:10 +02006929 { "ssl", srv_parse_ssl, 0, 0 }, /* enable SSL processing */
Emeric Brunef42d922012-10-11 16:11:36 +02006930 { "verify", srv_parse_verify, 1, 0 }, /* set SSL verify method */
Evan Broderbe554312013-06-27 00:05:25 -07006931 { "verifyhost", srv_parse_verifyhost, 1, 0 }, /* require that SSL cert verifies for hostname */
Willy Tarreau92faadf2012-10-10 23:04:25 +02006932 { NULL, NULL, 0, 0 },
6933}};
6934
Emeric Brun2c86cbf2014-10-30 15:56:50 +01006935static struct cfg_kw_list cfg_kws = {ILH, {
Willy Tarreau8c3b0fd2016-12-21 22:44:46 +01006936 { CFG_GLOBAL, "ca-base", ssl_parse_global_ca_crt_base },
6937 { CFG_GLOBAL, "crt-base", ssl_parse_global_ca_crt_base },
Willy Tarreau0bea58d2016-12-21 23:17:25 +01006938 { CFG_GLOBAL, "maxsslconn", ssl_parse_global_int },
Emeric Brun2c86cbf2014-10-30 15:56:50 +01006939 { CFG_GLOBAL, "ssl-default-bind-options", ssl_parse_default_bind_options },
6940 { CFG_GLOBAL, "ssl-default-server-options", ssl_parse_default_server_options },
Willy Tarreau14e36a12016-12-21 23:28:13 +01006941#ifndef OPENSSL_NO_DH
6942 { CFG_GLOBAL, "ssl-dh-param-file", ssl_parse_global_dh_param_file },
6943#endif
Willy Tarreau9ceda382016-12-21 23:13:03 +01006944 { CFG_GLOBAL, "tune.ssl.cachesize", ssl_parse_global_int },
6945#ifndef OPENSSL_NO_DH
6946 { CFG_GLOBAL, "tune.ssl.default-dh-param", ssl_parse_global_default_dh },
6947#endif
6948 { CFG_GLOBAL, "tune.ssl.force-private-cache", ssl_parse_global_private_cache },
6949 { CFG_GLOBAL, "tune.ssl.lifetime", ssl_parse_global_lifetime },
6950 { CFG_GLOBAL, "tune.ssl.maxrecord", ssl_parse_global_int },
6951 { CFG_GLOBAL, "tune.ssl.ssl-ctx-cache-size", ssl_parse_global_int },
Willy Tarreauf22e9682016-12-21 23:23:19 +01006952 { CFG_GLOBAL, "ssl-default-bind-ciphers", ssl_parse_global_ciphers },
6953 { CFG_GLOBAL, "ssl-default-server-ciphers", ssl_parse_global_ciphers },
Emeric Brun2c86cbf2014-10-30 15:56:50 +01006954 { 0, NULL, NULL },
6955}};
6956
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02006957/* transport-layer operations for SSL sockets */
Willy Tarreaud9f5cca2016-12-22 21:08:52 +01006958static struct xprt_ops ssl_sock = {
Emeric Brun46591952012-05-18 15:47:34 +02006959 .snd_buf = ssl_sock_from_buf,
6960 .rcv_buf = ssl_sock_to_buf,
6961 .rcv_pipe = NULL,
6962 .snd_pipe = NULL,
6963 .shutr = NULL,
6964 .shutw = ssl_sock_shutw,
6965 .close = ssl_sock_close,
6966 .init = ssl_sock_init,
Willy Tarreau55d37912016-12-21 23:38:39 +01006967 .prepare_bind_conf = ssl_sock_prepare_bind_conf,
Willy Tarreau795cdab2016-12-22 17:30:54 +01006968 .destroy_bind_conf = ssl_sock_destroy_bind_conf,
Willy Tarreau17d45382016-12-22 21:16:08 +01006969 .prepare_srv = ssl_sock_prepare_srv_ctx,
6970 .destroy_srv = ssl_sock_free_srv_ctx,
Willy Tarreau8e0bb0a2016-11-24 16:58:12 +01006971 .name = "SSL",
Emeric Brun46591952012-05-18 15:47:34 +02006972};
6973
Daniel Jakots54ffb912015-11-06 20:02:41 +01006974#if (OPENSSL_VERSION_NUMBER >= 0x1000200fL && !defined OPENSSL_NO_TLSEXT && !defined OPENSSL_IS_BORINGSSL && !defined LIBRESSL_VERSION_NUMBER)
Janusz Dziemidowicz2c701b52015-03-07 23:03:59 +01006975
6976static void ssl_sock_sctl_free_func(void *parent, void *ptr, CRYPTO_EX_DATA *ad, int idx, long argl, void *argp)
6977{
6978 if (ptr) {
6979 chunk_destroy(ptr);
6980 free(ptr);
6981 }
6982}
6983
6984#endif
6985
Emeric Brun46591952012-05-18 15:47:34 +02006986__attribute__((constructor))
Willy Tarreau92faadf2012-10-10 23:04:25 +02006987static void __ssl_sock_init(void)
6988{
Willy Tarreauc2c0b612016-12-21 19:23:20 +01006989 char *ptr;
6990
Emeric Brun46591952012-05-18 15:47:34 +02006991 STACK_OF(SSL_COMP)* cm;
6992
Willy Tarreauef934602016-12-22 23:12:01 +01006993 if (global_ssl.listen_default_ciphers)
6994 global_ssl.listen_default_ciphers = strdup(global_ssl.listen_default_ciphers);
6995 if (global_ssl.connect_default_ciphers)
6996 global_ssl.connect_default_ciphers = strdup(global_ssl.connect_default_ciphers);
Willy Tarreau610f04b2014-02-13 11:36:41 +01006997
Willy Tarreau13e14102016-12-22 20:25:26 +01006998 xprt_register(XPRT_SSL, &ssl_sock);
Emeric Brun46591952012-05-18 15:47:34 +02006999 SSL_library_init();
7000 cm = SSL_COMP_get_compression_methods();
7001 sk_SSL_COMP_zero(cm);
Daniel Jakots54ffb912015-11-06 20:02:41 +01007002#if (OPENSSL_VERSION_NUMBER >= 0x1000200fL && !defined OPENSSL_NO_TLSEXT && !defined OPENSSL_IS_BORINGSSL && !defined LIBRESSL_VERSION_NUMBER)
Janusz Dziemidowicz2c701b52015-03-07 23:03:59 +01007003 sctl_ex_index = SSL_CTX_get_ex_new_index(0, NULL, NULL, NULL, ssl_sock_sctl_free_func);
7004#endif
Willy Tarreau7875d092012-09-10 08:20:03 +02007005 sample_register_fetches(&sample_fetch_keywords);
7006 acl_register_keywords(&acl_kws);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02007007 bind_register_keywords(&bind_kws);
Willy Tarreau92faadf2012-10-10 23:04:25 +02007008 srv_register_keywords(&srv_kws);
Emeric Brun2c86cbf2014-10-30 15:56:50 +01007009 cfg_register_keywords(&cfg_kws);
William Lallemand32af2032016-10-29 18:09:35 +02007010 cli_register_kw(&cli_kws);
Willy Tarreaud1c57502016-12-22 22:46:15 +01007011#if (defined SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB && TLS_TICKETS_NO > 0)
7012 hap_register_post_check(tlskeys_finalize_config);
7013#endif
Willy Tarreaud92aa5c2015-01-15 21:34:39 +01007014
Willy Tarreauc2c0b612016-12-21 19:23:20 +01007015 ptr = NULL;
7016 memprintf(&ptr, "Built with OpenSSL version : "
7017#ifdef OPENSSL_IS_BORINGSSL
7018 "BoringSSL\n");
7019#else /* OPENSSL_IS_BORINGSSL */
7020 OPENSSL_VERSION_TEXT
7021 "\nRunning on OpenSSL version : %s%s",
7022 SSLeay_version(SSLEAY_VERSION),
7023 ((OPENSSL_VERSION_NUMBER ^ SSLeay()) >> 8) ? " (VERSIONS DIFFER!)" : "");
7024#endif
7025 memprintf(&ptr, "%s\nOpenSSL library supports TLS extensions : "
7026#if OPENSSL_VERSION_NUMBER < 0x00907000L
7027 "no (library version too old)"
7028#elif defined(OPENSSL_NO_TLSEXT)
7029 "no (disabled via OPENSSL_NO_TLSEXT)"
7030#else
7031 "yes"
7032#endif
7033 "", ptr);
7034
7035 memprintf(&ptr, "%s\nOpenSSL library supports SNI : "
7036#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
7037 "yes"
7038#else
7039#ifdef OPENSSL_NO_TLSEXT
7040 "no (because of OPENSSL_NO_TLSEXT)"
7041#else
7042 "no (version might be too old, 0.9.8f min needed)"
7043#endif
7044#endif
7045 "", ptr);
7046
Willy Tarreauc2c0b612016-12-21 19:23:20 +01007047 hap_register_build_opts(ptr, 1);
7048
Willy Tarreaud92aa5c2015-01-15 21:34:39 +01007049 global.ssl_session_max_cost = SSL_SESSION_MAX_COST;
7050 global.ssl_handshake_max_cost = SSL_HANDSHAKE_MAX_COST;
Remi Gacogne4f902b82015-05-28 16:23:00 +02007051
7052#ifndef OPENSSL_NO_DH
7053 ssl_dh_ptr_index = SSL_CTX_get_ex_new_index(0, NULL, NULL, NULL, NULL);
7054#endif
Thierry FOURNIER / OZON.IO8b068c22016-10-10 11:59:50 +02007055
7056 /* Load SSL string for the verbose & debug mode. */
7057 ERR_load_SSL_strings();
Emeric Brun46591952012-05-18 15:47:34 +02007058}
7059
Remi Gacogned3a23c32015-05-28 16:39:47 +02007060__attribute__((destructor))
7061static void __ssl_sock_deinit(void)
7062{
Willy Tarreaua84c2672015-10-09 12:10:13 +02007063#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Christopher Faulet31af49d2015-06-09 17:29:50 +02007064 lru64_destroy(ssl_ctx_lru_tree);
Willy Tarreaua84c2672015-10-09 12:10:13 +02007065#endif
Christopher Faulet31af49d2015-06-09 17:29:50 +02007066
Remi Gacogned3a23c32015-05-28 16:39:47 +02007067#ifndef OPENSSL_NO_DH
7068 if (local_dh_1024) {
7069 DH_free(local_dh_1024);
7070 local_dh_1024 = NULL;
7071 }
7072
7073 if (local_dh_2048) {
7074 DH_free(local_dh_2048);
7075 local_dh_2048 = NULL;
7076 }
7077
7078 if (local_dh_4096) {
7079 DH_free(local_dh_4096);
7080 local_dh_4096 = NULL;
7081 }
7082
Remi Gacogne47783ef2015-05-29 15:53:22 +02007083 if (global_dh) {
7084 DH_free(global_dh);
7085 global_dh = NULL;
7086 }
Remi Gacogned3a23c32015-05-28 16:39:47 +02007087#endif
7088
7089 ERR_remove_state(0);
7090 ERR_free_strings();
7091
7092 EVP_cleanup();
7093
7094#if OPENSSL_VERSION_NUMBER >= 0x00907000L
7095 CRYPTO_cleanup_all_ex_data();
7096#endif
7097}
7098
7099
Emeric Brun46591952012-05-18 15:47:34 +02007100/*
7101 * Local variables:
7102 * c-indent-level: 8
7103 * c-basic-offset: 8
7104 * End:
7105 */