blob: 490003f40bd1b0c5da87768f20714da38a679679 [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;
Emeric Brune1f38db2012-09-03 20:36:47 +0200133
Nenad Merdanovic200b0fa2015-05-09 08:46:01 +0200134#if (defined SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB && TLS_TICKETS_NO > 0)
135struct list tlskeys_reference = LIST_HEAD_INIT(tlskeys_reference);
136#endif
137
Remi Gacogne8de54152014-07-15 11:36:40 +0200138#ifndef OPENSSL_NO_DH
Remi Gacogne4f902b82015-05-28 16:23:00 +0200139static int ssl_dh_ptr_index = -1;
Remi Gacogne47783ef2015-05-29 15:53:22 +0200140static DH *global_dh = NULL;
Remi Gacogne8de54152014-07-15 11:36:40 +0200141static DH *local_dh_1024 = NULL;
142static DH *local_dh_2048 = NULL;
143static DH *local_dh_4096 = NULL;
Remi Gacogne8de54152014-07-15 11:36:40 +0200144#endif /* OPENSSL_NO_DH */
145
Willy Tarreauc8ad3be2015-06-17 15:48:26 +0200146#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Christopher Faulet31af49d2015-06-09 17:29:50 +0200147/* X509V3 Extensions that will be added on generated certificates */
148#define X509V3_EXT_SIZE 5
149static char *x509v3_ext_names[X509V3_EXT_SIZE] = {
150 "basicConstraints",
151 "nsComment",
152 "subjectKeyIdentifier",
153 "authorityKeyIdentifier",
154 "keyUsage",
155};
156static char *x509v3_ext_values[X509V3_EXT_SIZE] = {
157 "CA:FALSE",
158 "\"OpenSSL Generated Certificate\"",
159 "hash",
160 "keyid,issuer:always",
161 "nonRepudiation,digitalSignature,keyEncipherment"
162};
163
164/* LRU cache to store generated certificate */
165static struct lru64_head *ssl_ctx_lru_tree = NULL;
166static unsigned int ssl_ctx_lru_seed = 0;
Willy Tarreauc8ad3be2015-06-17 15:48:26 +0200167#endif // SSL_CTRL_SET_TLSEXT_HOSTNAME
168
yanbzhube2774d2015-12-10 15:07:30 -0500169#if OPENSSL_VERSION_NUMBER >= 0x1000200fL
170/* The order here matters for picking a default context,
171 * keep the most common keytype at the bottom of the list
172 */
173const char *SSL_SOCK_KEYTYPE_NAMES[] = {
174 "dsa",
175 "ecdsa",
176 "rsa"
177};
178#define SSL_SOCK_NUM_KEYTYPES 3
Willy Tarreau30da7ad2015-12-14 11:28:33 +0100179#else
180#define SSL_SOCK_NUM_KEYTYPES 1
yanbzhube2774d2015-12-10 15:07:30 -0500181#endif
182
Willy Tarreauc8ad3be2015-06-17 15:48:26 +0200183#if (defined SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB && !defined OPENSSL_NO_OCSP)
yanbzhube2774d2015-12-10 15:07:30 -0500184/*
185 * struct alignment works here such that the key.key is the same as key_data
186 * Do not change the placement of key_data
187 */
Willy Tarreauc8ad3be2015-06-17 15:48:26 +0200188struct certificate_ocsp {
189 struct ebmb_node key;
190 unsigned char key_data[OCSP_MAX_CERTID_ASN1_LENGTH];
191 struct chunk response;
192 long expire;
193};
Christopher Faulet31af49d2015-06-09 17:29:50 +0200194
yanbzhube2774d2015-12-10 15:07:30 -0500195struct ocsp_cbk_arg {
196 int is_single;
197 int single_kt;
198 union {
199 struct certificate_ocsp *s_ocsp;
200 /*
201 * m_ocsp will have multiple entries dependent on key type
202 * Entry 0 - DSA
203 * Entry 1 - ECDSA
204 * Entry 2 - RSA
205 */
206 struct certificate_ocsp *m_ocsp[SSL_SOCK_NUM_KEYTYPES];
207 };
208};
209
Emeric Brun4f3c87a2014-06-20 15:46:13 +0200210/*
Thierry FOURNIER / OZON.IO8b068c22016-10-10 11:59:50 +0200211 * This function gives the detail of the SSL error. It is used only
212 * if the debug mode and the verbose mode are activated. It dump all
213 * the SSL error until the stack was empty.
214 */
215static forceinline void ssl_sock_dump_errors(struct connection *conn)
216{
217 unsigned long ret;
218
219 if (unlikely(global.mode & MODE_DEBUG)) {
220 while(1) {
221 ret = ERR_get_error();
222 if (ret == 0)
223 return;
224 fprintf(stderr, "fd[%04x] OpenSSL error[0x%lx] %s: %s\n",
225 (unsigned short)conn->t.sock.fd, ret,
226 ERR_func_error_string(ret), ERR_reason_error_string(ret));
227 }
228 }
229}
230
231/*
Emeric Brun4f3c87a2014-06-20 15:46:13 +0200232 * This function returns the number of seconds elapsed
233 * since the Epoch, 1970-01-01 00:00:00 +0000 (UTC) and the
234 * date presented un ASN1_GENERALIZEDTIME.
235 *
236 * In parsing error case, it returns -1.
237 */
238static long asn1_generalizedtime_to_epoch(ASN1_GENERALIZEDTIME *d)
239{
240 long epoch;
241 char *p, *end;
242 const unsigned short month_offset[12] = {
243 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334
244 };
245 int year, month;
246
247 if (!d || (d->type != V_ASN1_GENERALIZEDTIME)) return -1;
248
249 p = (char *)d->data;
250 end = p + d->length;
251
252 if (end - p < 4) return -1;
253 year = 1000 * (p[0] - '0') + 100 * (p[1] - '0') + 10 * (p[2] - '0') + p[3] - '0';
254 p += 4;
255 if (end - p < 2) return -1;
256 month = 10 * (p[0] - '0') + p[1] - '0';
257 if (month < 1 || month > 12) return -1;
258 /* Compute the number of seconds since 1 jan 1970 and the beginning of current month
259 We consider leap years and the current month (<marsh or not) */
260 epoch = ( ((year - 1970) * 365)
261 + ((year - (month < 3)) / 4 - (year - (month < 3)) / 100 + (year - (month < 3)) / 400)
262 - ((1970 - 1) / 4 - (1970 - 1) / 100 + (1970 - 1) / 400)
263 + month_offset[month-1]
264 ) * 24 * 60 * 60;
265 p += 2;
266 if (end - p < 2) return -1;
267 /* Add the number of seconds of completed days of current month */
268 epoch += (10 * (p[0] - '0') + p[1] - '0' - 1) * 24 * 60 * 60;
269 p += 2;
270 if (end - p < 2) return -1;
271 /* Add the completed hours of the current day */
272 epoch += (10 * (p[0] - '0') + p[1] - '0') * 60 * 60;
273 p += 2;
274 if (end - p < 2) return -1;
275 /* Add the completed minutes of the current hour */
276 epoch += (10 * (p[0] - '0') + p[1] - '0') * 60;
277 p += 2;
278 if (p == end) return -1;
279 /* Test if there is available seconds */
280 if (p[0] < '0' || p[0] > '9')
281 goto nosec;
282 if (end - p < 2) return -1;
283 /* Add the seconds of the current minute */
284 epoch += 10 * (p[0] - '0') + p[1] - '0';
285 p += 2;
286 if (p == end) return -1;
287 /* Ignore seconds float part if present */
288 if (p[0] == '.') {
289 do {
290 if (++p == end) return -1;
291 } while (p[0] >= '0' && p[0] <= '9');
292 }
293
294nosec:
295 if (p[0] == 'Z') {
296 if (end - p != 1) return -1;
297 return epoch;
298 }
299 else if (p[0] == '+') {
300 if (end - p != 5) return -1;
301 /* Apply timezone offset */
302 return epoch - ((10 * (p[1] - '0') + p[2] - '0') * 60 + (10 * (p[3] - '0') + p[4] - '0')) * 60;
303 }
304 else if (p[0] == '-') {
305 if (end - p != 5) return -1;
306 /* Apply timezone offset */
307 return epoch + ((10 * (p[1] - '0') + p[2] - '0') * 60 + (10 * (p[3] - '0') + p[4] - '0')) * 60;
308 }
309
310 return -1;
311}
312
Emeric Brun1d3865b2014-06-20 15:37:32 +0200313static struct eb_root cert_ocsp_tree = EB_ROOT_UNIQUE;
Emeric Brun4147b2e2014-06-16 18:36:30 +0200314
315/* This function starts to check if the OCSP response (in DER format) contained
316 * in chunk 'ocsp_response' is valid (else exits on error).
317 * If 'cid' is not NULL, it will be compared to the OCSP certificate ID
318 * contained in the OCSP Response and exits on error if no match.
319 * If it's a valid OCSP Response:
320 * If 'ocsp' is not NULL, the chunk is copied in the OCSP response's container
321 * pointed by 'ocsp'.
322 * If 'ocsp' is NULL, the function looks up into the OCSP response's
323 * containers tree (using as index the ASN1 form of the OCSP Certificate ID extracted
324 * from the response) and exits on error if not found. Finally, If an OCSP response is
325 * already present in the container, it will be overwritten.
326 *
327 * Note: OCSP response containing more than one OCSP Single response is not
328 * considered valid.
329 *
330 * Returns 0 on success, 1 in error case.
331 */
332static int ssl_sock_load_ocsp_response(struct chunk *ocsp_response, struct certificate_ocsp *ocsp, OCSP_CERTID *cid, char **err)
333{
334 OCSP_RESPONSE *resp;
335 OCSP_BASICRESP *bs = NULL;
336 OCSP_SINGLERESP *sr;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +0200337 OCSP_CERTID *id;
Emeric Brun4147b2e2014-06-16 18:36:30 +0200338 unsigned char *p = (unsigned char *)ocsp_response->str;
339 int rc , count_sr;
Emeric Brun13a6b482014-06-20 15:44:34 +0200340 ASN1_GENERALIZEDTIME *revtime, *thisupd, *nextupd = NULL;
Emeric Brun4147b2e2014-06-16 18:36:30 +0200341 int reason;
342 int ret = 1;
343
344 resp = d2i_OCSP_RESPONSE(NULL, (const unsigned char **)&p, ocsp_response->len);
345 if (!resp) {
346 memprintf(err, "Unable to parse OCSP response");
347 goto out;
348 }
349
350 rc = OCSP_response_status(resp);
351 if (rc != OCSP_RESPONSE_STATUS_SUCCESSFUL) {
352 memprintf(err, "OCSP response status not successful");
353 goto out;
354 }
355
356 bs = OCSP_response_get1_basic(resp);
357 if (!bs) {
358 memprintf(err, "Failed to get basic response from OCSP Response");
359 goto out;
360 }
361
362 count_sr = OCSP_resp_count(bs);
363 if (count_sr > 1) {
364 memprintf(err, "OCSP response ignored because contains multiple single responses (%d)", count_sr);
365 goto out;
366 }
367
368 sr = OCSP_resp_get0(bs, 0);
369 if (!sr) {
370 memprintf(err, "Failed to get OCSP single response");
371 goto out;
372 }
373
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +0200374 id = (OCSP_CERTID*)OCSP_SINGLERESP_get0_id(sr);
375
Emeric Brun4147b2e2014-06-16 18:36:30 +0200376 rc = OCSP_single_get0_status(sr, &reason, &revtime, &thisupd, &nextupd);
377 if (rc != V_OCSP_CERTSTATUS_GOOD) {
378 memprintf(err, "OCSP single response: certificate status not good");
379 goto out;
380 }
381
Emeric Brun13a6b482014-06-20 15:44:34 +0200382 if (!nextupd) {
383 memprintf(err, "OCSP single response: missing nextupdate");
384 goto out;
385 }
386
Emeric Brunc8b27b62014-06-19 14:16:17 +0200387 rc = OCSP_check_validity(thisupd, nextupd, OCSP_MAX_RESPONSE_TIME_SKEW, -1);
Emeric Brun4147b2e2014-06-16 18:36:30 +0200388 if (!rc) {
389 memprintf(err, "OCSP single response: no longer valid.");
390 goto out;
391 }
392
393 if (cid) {
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +0200394 if (OCSP_id_cmp(id, cid)) {
Emeric Brun4147b2e2014-06-16 18:36:30 +0200395 memprintf(err, "OCSP single response: Certificate ID does not match certificate and issuer");
396 goto out;
397 }
398 }
399
400 if (!ocsp) {
401 unsigned char key[OCSP_MAX_CERTID_ASN1_LENGTH];
402 unsigned char *p;
403
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +0200404 rc = i2d_OCSP_CERTID(id, NULL);
Emeric Brun4147b2e2014-06-16 18:36:30 +0200405 if (!rc) {
406 memprintf(err, "OCSP single response: Unable to encode Certificate ID");
407 goto out;
408 }
409
410 if (rc > OCSP_MAX_CERTID_ASN1_LENGTH) {
411 memprintf(err, "OCSP single response: Certificate ID too long");
412 goto out;
413 }
414
415 p = key;
416 memset(key, 0, OCSP_MAX_CERTID_ASN1_LENGTH);
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +0200417 i2d_OCSP_CERTID(id, &p);
Emeric Brun4147b2e2014-06-16 18:36:30 +0200418 ocsp = (struct certificate_ocsp *)ebmb_lookup(&cert_ocsp_tree, key, OCSP_MAX_CERTID_ASN1_LENGTH);
419 if (!ocsp) {
420 memprintf(err, "OCSP single response: Certificate ID does not match any certificate or issuer");
421 goto out;
422 }
423 }
424
425 /* According to comments on "chunk_dup", the
426 previous chunk buffer will be freed */
427 if (!chunk_dup(&ocsp->response, ocsp_response)) {
428 memprintf(err, "OCSP response: Memory allocation error");
429 goto out;
430 }
431
Emeric Brun4f3c87a2014-06-20 15:46:13 +0200432 ocsp->expire = asn1_generalizedtime_to_epoch(nextupd) - OCSP_MAX_RESPONSE_TIME_SKEW;
433
Emeric Brun4147b2e2014-06-16 18:36:30 +0200434 ret = 0;
435out:
436 if (bs)
437 OCSP_BASICRESP_free(bs);
438
439 if (resp)
440 OCSP_RESPONSE_free(resp);
441
442 return ret;
443}
444/*
445 * External function use to update the OCSP response in the OCSP response's
446 * containers tree. The chunk 'ocsp_response' must contain the OCSP response
447 * to update in DER format.
448 *
449 * Returns 0 on success, 1 in error case.
450 */
451int ssl_sock_update_ocsp_response(struct chunk *ocsp_response, char **err)
452{
453 return ssl_sock_load_ocsp_response(ocsp_response, NULL, NULL, err);
454}
455
456/*
457 * This function load the OCSP Resonse in DER format contained in file at
458 * path 'ocsp_path' and call 'ssl_sock_load_ocsp_response'
459 *
460 * Returns 0 on success, 1 in error case.
461 */
462static int ssl_sock_load_ocsp_response_from_file(const char *ocsp_path, struct certificate_ocsp *ocsp, OCSP_CERTID *cid, char **err)
463{
464 int fd = -1;
465 int r = 0;
466 int ret = 1;
467
468 fd = open(ocsp_path, O_RDONLY);
469 if (fd == -1) {
470 memprintf(err, "Error opening OCSP response file");
471 goto end;
472 }
473
474 trash.len = 0;
475 while (trash.len < trash.size) {
476 r = read(fd, trash.str + trash.len, trash.size - trash.len);
477 if (r < 0) {
478 if (errno == EINTR)
479 continue;
480
481 memprintf(err, "Error reading OCSP response from file");
482 goto end;
483 }
484 else if (r == 0) {
485 break;
486 }
487 trash.len += r;
488 }
489
490 close(fd);
491 fd = -1;
492
493 ret = ssl_sock_load_ocsp_response(&trash, ocsp, cid, err);
494end:
495 if (fd != -1)
496 close(fd);
497
498 return ret;
499}
500
Nenad Merdanovic05552d42015-02-27 19:56:49 +0100501#if (defined SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB && TLS_TICKETS_NO > 0)
502static 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)
503{
504 struct tls_sess_key *keys;
505 struct connection *conn;
506 int head;
507 int i;
508
Vincent Bernat3c2f2f22016-04-03 13:48:42 +0200509 conn = SSL_get_app_data(s);
Nenad Merdanovic146defa2015-05-09 08:46:00 +0200510 keys = objt_listener(conn->target)->bind_conf->keys_ref->tlskeys;
511 head = objt_listener(conn->target)->bind_conf->keys_ref->tls_ticket_enc_index;
Nenad Merdanovic05552d42015-02-27 19:56:49 +0100512
513 if (enc) {
514 memcpy(key_name, keys[head].name, 16);
515
516 if(!RAND_pseudo_bytes(iv, EVP_MAX_IV_LENGTH))
517 return -1;
518
519 if(!EVP_EncryptInit_ex(ectx, EVP_aes_128_cbc(), NULL, keys[head].aes_key, iv))
520 return -1;
521
522 HMAC_Init_ex(hctx, keys[head].hmac_key, 16, HASH_FUNCT(), NULL);
523
524 return 1;
525 } else {
526 for (i = 0; i < TLS_TICKETS_NO; i++) {
527 if (!memcmp(key_name, keys[(head + i) % TLS_TICKETS_NO].name, 16))
528 goto found;
529 }
530 return 0;
531
532 found:
533 HMAC_Init_ex(hctx, keys[(head + i) % TLS_TICKETS_NO].hmac_key, 16, HASH_FUNCT(), NULL);
534 if(!EVP_DecryptInit_ex(ectx, EVP_aes_128_cbc(), NULL, keys[(head + i) % TLS_TICKETS_NO].aes_key, iv))
535 return -1;
536 /* 2 for key renewal, 1 if current key is still valid */
537 return i ? 2 : 1;
538 }
Nenad Merdanovic200b0fa2015-05-09 08:46:01 +0200539}
540
541struct tls_keys_ref *tlskeys_ref_lookup(const char *filename)
542{
543 struct tls_keys_ref *ref;
544
545 list_for_each_entry(ref, &tlskeys_reference, list)
546 if (ref->filename && strcmp(filename, ref->filename) == 0)
547 return ref;
548 return NULL;
549}
550
551struct tls_keys_ref *tlskeys_ref_lookupid(int unique_id)
552{
553 struct tls_keys_ref *ref;
554
555 list_for_each_entry(ref, &tlskeys_reference, list)
556 if (ref->unique_id == unique_id)
557 return ref;
558 return NULL;
559}
560
561int ssl_sock_update_tlskey(char *filename, struct chunk *tlskey, char **err) {
562 struct tls_keys_ref *ref = tlskeys_ref_lookup(filename);
563
564 if(!ref) {
565 memprintf(err, "Unable to locate the referenced filename: %s", filename);
566 return 1;
567 }
568
Pradeep Jindalcc79b002015-08-20 18:25:17 +0530569 memcpy((char *) (ref->tlskeys + ((ref->tls_ticket_enc_index + 2) % TLS_TICKETS_NO)), tlskey->str, tlskey->len);
570 ref->tls_ticket_enc_index = (ref->tls_ticket_enc_index + 1) % TLS_TICKETS_NO;
Nenad Merdanovic200b0fa2015-05-09 08:46:01 +0200571
572 return 0;
Nenad Merdanovic05552d42015-02-27 19:56:49 +0100573}
Nenad Merdanovic200b0fa2015-05-09 08:46:01 +0200574
575/* This function finalize the configuration parsing. Its set all the
576 * automatic ids
577 */
578void tlskeys_finalize_config(void)
579{
580 int i = 0;
581 struct tls_keys_ref *ref, *ref2, *ref3;
582 struct list tkr = LIST_HEAD_INIT(tkr);
583
584 list_for_each_entry(ref, &tlskeys_reference, list) {
585 if (ref->unique_id == -1) {
586 /* Look for the first free id. */
587 while (1) {
588 list_for_each_entry(ref2, &tlskeys_reference, list) {
589 if (ref2->unique_id == i) {
590 i++;
591 break;
592 }
593 }
594 if (&ref2->list == &tlskeys_reference)
595 break;
596 }
597
598 /* Uses the unique id and increment it for the next entry. */
599 ref->unique_id = i;
600 i++;
601 }
602 }
603
604 /* This sort the reference list by id. */
605 list_for_each_entry_safe(ref, ref2, &tlskeys_reference, list) {
606 LIST_DEL(&ref->list);
607 list_for_each_entry(ref3, &tkr, list) {
608 if (ref->unique_id < ref3->unique_id) {
609 LIST_ADDQ(&ref3->list, &ref->list);
610 break;
611 }
612 }
613 if (&ref3->list == &tkr)
614 LIST_ADDQ(&tkr, &ref->list);
615 }
616
617 /* swap root */
618 LIST_ADD(&tkr, &tlskeys_reference);
619 LIST_DEL(&tkr);
620}
621
Nenad Merdanovic05552d42015-02-27 19:56:49 +0100622#endif /* SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB */
623
yanbzhube2774d2015-12-10 15:07:30 -0500624int ssl_sock_get_ocsp_arg_kt_index(int evp_keytype)
625{
626 switch (evp_keytype) {
627 case EVP_PKEY_RSA:
628 return 2;
629 case EVP_PKEY_DSA:
630 return 0;
631 case EVP_PKEY_EC:
632 return 1;
633 }
634
635 return -1;
636}
637
Emeric Brun4147b2e2014-06-16 18:36:30 +0200638/*
639 * Callback used to set OCSP status extension content in server hello.
640 */
641int ssl_sock_ocsp_stapling_cbk(SSL *ssl, void *arg)
642{
yanbzhube2774d2015-12-10 15:07:30 -0500643 struct certificate_ocsp *ocsp;
644 struct ocsp_cbk_arg *ocsp_arg;
645 char *ssl_buf;
646 EVP_PKEY *ssl_pkey;
647 int key_type;
648 int index;
649
Vincent Bernat3c2f2f22016-04-03 13:48:42 +0200650 ocsp_arg = arg;
yanbzhube2774d2015-12-10 15:07:30 -0500651
652 ssl_pkey = SSL_get_privatekey(ssl);
653 if (!ssl_pkey)
654 return SSL_TLSEXT_ERR_NOACK;
655
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +0200656 key_type = EVP_PKEY_base_id(ssl_pkey);
yanbzhube2774d2015-12-10 15:07:30 -0500657
658 if (ocsp_arg->is_single && ocsp_arg->single_kt == key_type)
659 ocsp = ocsp_arg->s_ocsp;
660 else {
661 /* For multiple certs per context, we have to find the correct OCSP response based on
662 * the certificate type
663 */
664 index = ssl_sock_get_ocsp_arg_kt_index(key_type);
665
666 if (index < 0)
667 return SSL_TLSEXT_ERR_NOACK;
668
669 ocsp = ocsp_arg->m_ocsp[index];
670
671 }
Emeric Brun4147b2e2014-06-16 18:36:30 +0200672
673 if (!ocsp ||
674 !ocsp->response.str ||
Emeric Brun4f3c87a2014-06-20 15:46:13 +0200675 !ocsp->response.len ||
676 (ocsp->expire < now.tv_sec))
Emeric Brun4147b2e2014-06-16 18:36:30 +0200677 return SSL_TLSEXT_ERR_NOACK;
678
679 ssl_buf = OPENSSL_malloc(ocsp->response.len);
680 if (!ssl_buf)
681 return SSL_TLSEXT_ERR_NOACK;
682
683 memcpy(ssl_buf, ocsp->response.str, ocsp->response.len);
684 SSL_set_tlsext_status_ocsp_resp(ssl, ssl_buf, ocsp->response.len);
685
686 return SSL_TLSEXT_ERR_OK;
687}
688
689/*
690 * This function enables the handling of OCSP status extension on 'ctx' if a
691 * file name 'cert_path' suffixed using ".ocsp" is present.
692 * To enable OCSP status extension, the issuer's certificate is mandatory.
693 * It should be present in the certificate's extra chain builded from file
694 * 'cert_path'. If not found, the issuer certificate is loaded from a file
695 * named 'cert_path' suffixed using '.issuer'.
696 *
697 * In addition, ".ocsp" file content is loaded as a DER format of an OCSP
698 * response. If file is empty or content is not a valid OCSP response,
699 * OCSP status extension is enabled but OCSP response is ignored (a warning
700 * is displayed).
701 *
702 * Returns 1 if no ".ocsp" file found, 0 if OCSP status extension is
703 * succesfully enabled, or -1 in other error case.
704 */
705static int ssl_sock_load_ocsp(SSL_CTX *ctx, const char *cert_path)
706{
707
708 BIO *in = NULL;
709 X509 *x, *xi = NULL, *issuer = NULL;
710 STACK_OF(X509) *chain = NULL;
711 OCSP_CERTID *cid = NULL;
712 SSL *ssl;
713 char ocsp_path[MAXPATHLEN+1];
714 int i, ret = -1;
715 struct stat st;
716 struct certificate_ocsp *ocsp = NULL, *iocsp;
717 char *warn = NULL;
718 unsigned char *p;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +0200719 pem_password_cb *passwd_cb;
720 void *passwd_cb_userdata;
721 void (*callback) (void);
Emeric Brun4147b2e2014-06-16 18:36:30 +0200722
723 snprintf(ocsp_path, MAXPATHLEN+1, "%s.ocsp", cert_path);
724
725 if (stat(ocsp_path, &st))
726 return 1;
727
728 ssl = SSL_new(ctx);
729 if (!ssl)
730 goto out;
731
732 x = SSL_get_certificate(ssl);
733 if (!x)
734 goto out;
735
736 /* Try to lookup for issuer in certificate extra chain */
737#ifdef SSL_CTRL_GET_EXTRA_CHAIN_CERTS
738 SSL_CTX_get_extra_chain_certs(ctx, &chain);
739#else
740 chain = ctx->extra_certs;
741#endif
742 for (i = 0; i < sk_X509_num(chain); i++) {
743 issuer = sk_X509_value(chain, i);
744 if (X509_check_issued(issuer, x) == X509_V_OK)
745 break;
746 else
747 issuer = NULL;
748 }
749
750 /* If not found try to load issuer from a suffixed file */
751 if (!issuer) {
752 char issuer_path[MAXPATHLEN+1];
753
754 in = BIO_new(BIO_s_file());
755 if (!in)
756 goto out;
757
758 snprintf(issuer_path, MAXPATHLEN+1, "%s.issuer", cert_path);
759 if (BIO_read_filename(in, issuer_path) <= 0)
760 goto out;
761
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +0200762 passwd_cb = SSL_CTX_get_default_passwd_cb(ctx);
763 passwd_cb_userdata = SSL_CTX_get_default_passwd_cb_userdata(ctx);
764
765 xi = PEM_read_bio_X509_AUX(in, NULL, passwd_cb, passwd_cb_userdata);
Emeric Brun4147b2e2014-06-16 18:36:30 +0200766 if (!xi)
767 goto out;
768
769 if (X509_check_issued(xi, x) != X509_V_OK)
770 goto out;
771
772 issuer = xi;
773 }
774
775 cid = OCSP_cert_to_id(0, x, issuer);
776 if (!cid)
777 goto out;
778
779 i = i2d_OCSP_CERTID(cid, NULL);
780 if (!i || (i > OCSP_MAX_CERTID_ASN1_LENGTH))
781 goto out;
782
Vincent Bernat02779b62016-04-03 13:48:43 +0200783 ocsp = calloc(1, sizeof(*ocsp));
Emeric Brun4147b2e2014-06-16 18:36:30 +0200784 if (!ocsp)
785 goto out;
786
787 p = ocsp->key_data;
788 i2d_OCSP_CERTID(cid, &p);
789
790 iocsp = (struct certificate_ocsp *)ebmb_insert(&cert_ocsp_tree, &ocsp->key, OCSP_MAX_CERTID_ASN1_LENGTH);
791 if (iocsp == ocsp)
792 ocsp = NULL;
793
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +0200794#ifndef SSL_CTX_get_tlsext_status_cb
795# define SSL_CTX_get_tlsext_status_cb(ctx, cb) \
796 *cb = (void (*) (void))ctx->tlsext_status_cb;
797#endif
798 SSL_CTX_get_tlsext_status_cb(ctx, &callback);
799
800 if (!callback) {
Vincent Bernat02779b62016-04-03 13:48:43 +0200801 struct ocsp_cbk_arg *cb_arg = calloc(1, sizeof(*cb_arg));
yanbzhube2774d2015-12-10 15:07:30 -0500802
803 cb_arg->is_single = 1;
804 cb_arg->s_ocsp = iocsp;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +0200805
806 cb_arg->single_kt = EVP_PKEY_base_id(X509_get_pubkey(x));
yanbzhube2774d2015-12-10 15:07:30 -0500807
808 SSL_CTX_set_tlsext_status_cb(ctx, ssl_sock_ocsp_stapling_cbk);
809 SSL_CTX_set_tlsext_status_arg(ctx, cb_arg);
810 } else {
811 /*
812 * If the ctx has a status CB, then we have previously set an OCSP staple for this ctx
813 * Update that cb_arg with the new cert's staple
814 */
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +0200815 struct ocsp_cbk_arg *cb_arg;
yanbzhube2774d2015-12-10 15:07:30 -0500816 struct certificate_ocsp *tmp_ocsp;
817 int index;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +0200818 int key_type;
819
820#ifdef SSL_CTX_get_tlsext_status_arg
821 SSL_CTX_ctrl(ctx, SSL_CTRL_GET_TLSEXT_STATUS_REQ_CB_ARG, 0, &cb_arg);
822#else
823 cb_arg = ctx->tlsext_status_arg;
824#endif
yanbzhube2774d2015-12-10 15:07:30 -0500825
826 /*
827 * The following few lines will convert cb_arg from a single ocsp to multi ocsp
828 * the order of operations below matter, take care when changing it
829 */
830 tmp_ocsp = cb_arg->s_ocsp;
831 index = ssl_sock_get_ocsp_arg_kt_index(cb_arg->single_kt);
832 cb_arg->s_ocsp = NULL;
833 cb_arg->m_ocsp[index] = tmp_ocsp;
834 cb_arg->is_single = 0;
835 cb_arg->single_kt = 0;
836
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +0200837 key_type = EVP_PKEY_base_id(X509_get_pubkey(x));
838 index = ssl_sock_get_ocsp_arg_kt_index(key_type);
yanbzhube2774d2015-12-10 15:07:30 -0500839 if (index >= 0 && !cb_arg->m_ocsp[index])
840 cb_arg->m_ocsp[index] = iocsp;
841
842 }
Emeric Brun4147b2e2014-06-16 18:36:30 +0200843
844 ret = 0;
845
846 warn = NULL;
847 if (ssl_sock_load_ocsp_response_from_file(ocsp_path, iocsp, cid, &warn)) {
848 memprintf(&warn, "Loading '%s': %s. Content will be ignored", ocsp_path, warn ? warn : "failure");
849 Warning("%s.\n", warn);
850 }
851
852out:
853 if (ssl)
854 SSL_free(ssl);
855
856 if (in)
857 BIO_free(in);
858
859 if (xi)
860 X509_free(xi);
861
862 if (cid)
863 OCSP_CERTID_free(cid);
864
865 if (ocsp)
866 free(ocsp);
867
868 if (warn)
869 free(warn);
870
871
872 return ret;
873}
874
875#endif
876
Daniel Jakots54ffb912015-11-06 20:02:41 +0100877#if (OPENSSL_VERSION_NUMBER >= 0x1000200fL && !defined OPENSSL_NO_TLSEXT && !defined OPENSSL_IS_BORINGSSL && !defined LIBRESSL_VERSION_NUMBER)
Janusz Dziemidowicz2c701b52015-03-07 23:03:59 +0100878
879#define CT_EXTENSION_TYPE 18
880
881static int sctl_ex_index = -1;
882
883/*
884 * Try to parse Signed Certificate Timestamp List structure. This function
885 * makes only basic test if the data seems like SCTL. No signature validation
886 * is performed.
887 */
888static int ssl_sock_parse_sctl(struct chunk *sctl)
889{
890 int ret = 1;
891 int len, pos, sct_len;
892 unsigned char *data;
893
894 if (sctl->len < 2)
895 goto out;
896
897 data = (unsigned char *)sctl->str;
898 len = (data[0] << 8) | data[1];
899
900 if (len + 2 != sctl->len)
901 goto out;
902
903 data = data + 2;
904 pos = 0;
905 while (pos < len) {
906 if (len - pos < 2)
907 goto out;
908
909 sct_len = (data[pos] << 8) | data[pos + 1];
910 if (pos + sct_len + 2 > len)
911 goto out;
912
913 pos += sct_len + 2;
914 }
915
916 ret = 0;
917
918out:
919 return ret;
920}
921
922static int ssl_sock_load_sctl_from_file(const char *sctl_path, struct chunk **sctl)
923{
924 int fd = -1;
925 int r = 0;
926 int ret = 1;
927
928 *sctl = NULL;
929
930 fd = open(sctl_path, O_RDONLY);
931 if (fd == -1)
932 goto end;
933
934 trash.len = 0;
935 while (trash.len < trash.size) {
936 r = read(fd, trash.str + trash.len, trash.size - trash.len);
937 if (r < 0) {
938 if (errno == EINTR)
939 continue;
940
941 goto end;
942 }
943 else if (r == 0) {
944 break;
945 }
946 trash.len += r;
947 }
948
949 ret = ssl_sock_parse_sctl(&trash);
950 if (ret)
951 goto end;
952
Vincent Bernat02779b62016-04-03 13:48:43 +0200953 *sctl = calloc(1, sizeof(**sctl));
Janusz Dziemidowicz2c701b52015-03-07 23:03:59 +0100954 if (!chunk_dup(*sctl, &trash)) {
955 free(*sctl);
956 *sctl = NULL;
957 goto end;
958 }
959
960end:
961 if (fd != -1)
962 close(fd);
963
964 return ret;
965}
966
967int ssl_sock_sctl_add_cbk(SSL *ssl, unsigned ext_type, const unsigned char **out, size_t *outlen, int *al, void *add_arg)
968{
Vincent Bernat3c2f2f22016-04-03 13:48:42 +0200969 struct chunk *sctl = add_arg;
Janusz Dziemidowicz2c701b52015-03-07 23:03:59 +0100970
971 *out = (unsigned char *)sctl->str;
972 *outlen = sctl->len;
973
974 return 1;
975}
976
977int ssl_sock_sctl_parse_cbk(SSL *s, unsigned int ext_type, const unsigned char *in, size_t inlen, int *al, void *parse_arg)
978{
979 return 1;
980}
981
982static int ssl_sock_load_sctl(SSL_CTX *ctx, const char *cert_path)
983{
984 char sctl_path[MAXPATHLEN+1];
985 int ret = -1;
986 struct stat st;
987 struct chunk *sctl = NULL;
988
989 snprintf(sctl_path, MAXPATHLEN+1, "%s.sctl", cert_path);
990
991 if (stat(sctl_path, &st))
992 return 1;
993
994 if (ssl_sock_load_sctl_from_file(sctl_path, &sctl))
995 goto out;
996
997 if (!SSL_CTX_add_server_custom_ext(ctx, CT_EXTENSION_TYPE, ssl_sock_sctl_add_cbk, NULL, sctl, ssl_sock_sctl_parse_cbk, NULL)) {
998 free(sctl);
999 goto out;
1000 }
1001
1002 SSL_CTX_set_ex_data(ctx, sctl_ex_index, sctl);
1003
1004 ret = 0;
1005
1006out:
1007 return ret;
1008}
1009
1010#endif
1011
Emeric Brune1f38db2012-09-03 20:36:47 +02001012void ssl_sock_infocbk(const SSL *ssl, int where, int ret)
1013{
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02001014 struct connection *conn = SSL_get_app_data(ssl);
Emeric Brund8b2bb52014-01-28 15:43:53 +01001015 BIO *write_bio;
Willy Tarreau622317d2015-02-27 16:36:16 +01001016 (void)ret; /* shut gcc stupid warning */
Emeric Brune1f38db2012-09-03 20:36:47 +02001017
1018 if (where & SSL_CB_HANDSHAKE_START) {
1019 /* Disable renegotiation (CVE-2009-3555) */
Willy Tarreau20879a02012-12-03 16:32:10 +01001020 if (conn->flags & CO_FL_CONNECTED) {
Emeric Brune1f38db2012-09-03 20:36:47 +02001021 conn->flags |= CO_FL_ERROR;
Willy Tarreau20879a02012-12-03 16:32:10 +01001022 conn->err_code = CO_ER_SSL_RENEG;
1023 }
Emeric Brune1f38db2012-09-03 20:36:47 +02001024 }
Emeric Brund8b2bb52014-01-28 15:43:53 +01001025
1026 if ((where & SSL_CB_ACCEPT_LOOP) == SSL_CB_ACCEPT_LOOP) {
1027 if (!(conn->xprt_st & SSL_SOCK_ST_FL_16K_WBFSIZE)) {
1028 /* Long certificate chains optimz
1029 If write and read bios are differents, we
1030 consider that the buffering was activated,
1031 so we rise the output buffer size from 4k
1032 to 16k */
1033 write_bio = SSL_get_wbio(ssl);
1034 if (write_bio != SSL_get_rbio(ssl)) {
1035 BIO_set_write_buffer_size(write_bio, 16384);
1036 conn->xprt_st |= SSL_SOCK_ST_FL_16K_WBFSIZE;
1037 }
1038 }
1039 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02001040}
1041
Emeric Brune64aef12012-09-21 13:15:06 +02001042/* Callback is called for each certificate of the chain during a verify
1043 ok is set to 1 if preverify detect no error on current certificate.
1044 Returns 0 to break the handshake, 1 otherwise. */
Evan Broderbe554312013-06-27 00:05:25 -07001045int ssl_sock_bind_verifycbk(int ok, X509_STORE_CTX *x_store)
Emeric Brune64aef12012-09-21 13:15:06 +02001046{
1047 SSL *ssl;
1048 struct connection *conn;
Emeric Brun81c00f02012-09-21 14:31:21 +02001049 int err, depth;
Emeric Brune64aef12012-09-21 13:15:06 +02001050
1051 ssl = X509_STORE_CTX_get_ex_data(x_store, SSL_get_ex_data_X509_STORE_CTX_idx());
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02001052 conn = SSL_get_app_data(ssl);
Emeric Brune64aef12012-09-21 13:15:06 +02001053
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02001054 conn->xprt_st |= SSL_SOCK_ST_FL_VERIFY_DONE;
Emeric Brune64aef12012-09-21 13:15:06 +02001055
Emeric Brun81c00f02012-09-21 14:31:21 +02001056 if (ok) /* no errors */
1057 return ok;
1058
1059 depth = X509_STORE_CTX_get_error_depth(x_store);
1060 err = X509_STORE_CTX_get_error(x_store);
1061
1062 /* check if CA error needs to be ignored */
1063 if (depth > 0) {
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02001064 if (!SSL_SOCK_ST_TO_CA_ERROR(conn->xprt_st)) {
1065 conn->xprt_st |= SSL_SOCK_CA_ERROR_TO_ST(err);
1066 conn->xprt_st |= SSL_SOCK_CAEDEPTH_TO_ST(depth);
Emeric Brunf282a812012-09-21 15:27:54 +02001067 }
1068
Emeric Brun1eb20ef2012-12-03 13:24:29 +01001069 if (objt_listener(conn->target)->bind_conf->ca_ignerr & (1ULL << err)) {
Thierry FOURNIER / OZON.IO8b068c22016-10-10 11:59:50 +02001070 ssl_sock_dump_errors(conn);
Emeric Brun1eb20ef2012-12-03 13:24:29 +01001071 ERR_clear_error();
Emeric Brun81c00f02012-09-21 14:31:21 +02001072 return 1;
Emeric Brun1eb20ef2012-12-03 13:24:29 +01001073 }
Emeric Brun81c00f02012-09-21 14:31:21 +02001074
Willy Tarreau20879a02012-12-03 16:32:10 +01001075 conn->err_code = CO_ER_SSL_CA_FAIL;
Emeric Brun81c00f02012-09-21 14:31:21 +02001076 return 0;
1077 }
1078
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02001079 if (!SSL_SOCK_ST_TO_CRTERROR(conn->xprt_st))
1080 conn->xprt_st |= SSL_SOCK_CRTERROR_TO_ST(err);
Emeric Brunf282a812012-09-21 15:27:54 +02001081
Emeric Brun81c00f02012-09-21 14:31:21 +02001082 /* check if certificate error needs to be ignored */
Emeric Brun1eb20ef2012-12-03 13:24:29 +01001083 if (objt_listener(conn->target)->bind_conf->crt_ignerr & (1ULL << err)) {
Thierry FOURNIER / OZON.IO8b068c22016-10-10 11:59:50 +02001084 ssl_sock_dump_errors(conn);
Emeric Brun1eb20ef2012-12-03 13:24:29 +01001085 ERR_clear_error();
Emeric Brun81c00f02012-09-21 14:31:21 +02001086 return 1;
Emeric Brun1eb20ef2012-12-03 13:24:29 +01001087 }
Emeric Brun81c00f02012-09-21 14:31:21 +02001088
Willy Tarreau20879a02012-12-03 16:32:10 +01001089 conn->err_code = CO_ER_SSL_CRT_FAIL;
Emeric Brun81c00f02012-09-21 14:31:21 +02001090 return 0;
Emeric Brune64aef12012-09-21 13:15:06 +02001091}
1092
Emeric Brun29f037d2014-04-25 19:05:36 +02001093/* Callback is called for ssl protocol analyse */
1094void ssl_sock_msgcbk(int write_p, int version, int content_type, const void *buf, size_t len, SSL *ssl, void *arg)
1095{
Emeric Brun29f037d2014-04-25 19:05:36 +02001096#ifdef TLS1_RT_HEARTBEAT
1097 /* test heartbeat received (write_p is set to 0
1098 for a received record) */
Willy Tarreauf51c6982014-04-25 20:02:39 +02001099 if ((content_type == TLS1_RT_HEARTBEAT) && (write_p == 0)) {
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02001100 struct connection *conn = SSL_get_app_data(ssl);
Willy Tarreauf51c6982014-04-25 20:02:39 +02001101 const unsigned char *p = buf;
1102 unsigned int payload;
1103
Emeric Brun29f037d2014-04-25 19:05:36 +02001104 conn->xprt_st |= SSL_SOCK_RECV_HEARTBEAT;
Willy Tarreauf51c6982014-04-25 20:02:39 +02001105
1106 /* Check if this is a CVE-2014-0160 exploitation attempt. */
1107 if (*p != TLS1_HB_REQUEST)
1108 return;
1109
Willy Tarreauaeed6722014-04-25 23:59:58 +02001110 if (len < 1 + 2 + 16) /* 1 type + 2 size + 0 payload + 16 padding */
Willy Tarreauf51c6982014-04-25 20:02:39 +02001111 goto kill_it;
1112
1113 payload = (p[1] * 256) + p[2];
Willy Tarreau3b2fdb62014-04-25 23:44:22 +02001114 if (3 + payload + 16 <= len)
Willy Tarreauf51c6982014-04-25 20:02:39 +02001115 return; /* OK no problem */
Willy Tarreauaeed6722014-04-25 23:59:58 +02001116 kill_it:
Willy Tarreau3b2fdb62014-04-25 23:44:22 +02001117 /* We have a clear heartbleed attack (CVE-2014-0160), the
1118 * advertised payload is larger than the advertised packet
1119 * length, so we have garbage in the buffer between the
1120 * payload and the end of the buffer (p+len). We can't know
1121 * if the SSL stack is patched, and we don't know if we can
1122 * safely wipe out the area between p+3+len and payload.
1123 * So instead, we prevent the response from being sent by
1124 * setting the max_send_fragment to 0 and we report an SSL
1125 * error, which will kill this connection. It will be reported
1126 * above as SSL_ERROR_SSL while an other handshake failure with
Willy Tarreauf51c6982014-04-25 20:02:39 +02001127 * a heartbeat message will be reported as SSL_ERROR_SYSCALL.
1128 */
Willy Tarreau3b2fdb62014-04-25 23:44:22 +02001129 ssl->max_send_fragment = 0;
Willy Tarreauf51c6982014-04-25 20:02:39 +02001130 SSLerr(SSL_F_TLS1_HEARTBEAT, SSL_R_SSL_HANDSHAKE_FAILURE);
1131 return;
1132 }
Emeric Brun29f037d2014-04-25 19:05:36 +02001133#endif
1134}
1135
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02001136#ifdef OPENSSL_NPN_NEGOTIATED
1137/* This callback is used so that the server advertises the list of
1138 * negociable protocols for NPN.
1139 */
1140static int ssl_sock_advertise_npn_protos(SSL *s, const unsigned char **data,
1141 unsigned int *len, void *arg)
1142{
1143 struct bind_conf *conf = arg;
1144
1145 *data = (const unsigned char *)conf->npn_str;
1146 *len = conf->npn_len;
1147 return SSL_TLSEXT_ERR_OK;
1148}
1149#endif
1150
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01001151#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Willy Tarreauab861d32013-04-02 02:30:41 +02001152/* This callback is used so that the server advertises the list of
1153 * negociable protocols for ALPN.
1154 */
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01001155static int ssl_sock_advertise_alpn_protos(SSL *s, const unsigned char **out,
1156 unsigned char *outlen,
1157 const unsigned char *server,
1158 unsigned int server_len, void *arg)
Willy Tarreauab861d32013-04-02 02:30:41 +02001159{
1160 struct bind_conf *conf = arg;
1161
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01001162 if (SSL_select_next_proto((unsigned char**) out, outlen, (const unsigned char *)conf->alpn_str,
1163 conf->alpn_len, server, server_len) != OPENSSL_NPN_NEGOTIATED) {
1164 return SSL_TLSEXT_ERR_NOACK;
1165 }
Willy Tarreauab861d32013-04-02 02:30:41 +02001166 return SSL_TLSEXT_ERR_OK;
1167}
1168#endif
1169
Willy Tarreauc8ad3be2015-06-17 15:48:26 +02001170#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Christopher Faulet85b5a1a2015-10-09 11:46:32 +02001171static DH *ssl_get_tmp_dh(SSL *ssl, int export, int keylen);
1172
Christopher Faulet30548802015-06-11 13:39:32 +02001173/* Create a X509 certificate with the specified servername and serial. This
1174 * function returns a SSL_CTX object or NULL if an error occurs. */
Christopher Faulet7969a332015-10-09 11:15:03 +02001175static SSL_CTX *
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001176ssl_sock_do_create_cert(const char *servername, struct bind_conf *bind_conf, SSL *ssl)
Christopher Faulet31af49d2015-06-09 17:29:50 +02001177{
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001178 static unsigned int serial = 0;
1179
Christopher Faulet7969a332015-10-09 11:15:03 +02001180 X509 *cacert = bind_conf->ca_sign_cert;
1181 EVP_PKEY *capkey = bind_conf->ca_sign_pkey;
Christopher Faulet31af49d2015-06-09 17:29:50 +02001182 SSL_CTX *ssl_ctx = NULL;
1183 X509 *newcrt = NULL;
1184 EVP_PKEY *pkey = NULL;
Christopher Faulet31af49d2015-06-09 17:29:50 +02001185 X509_NAME *name;
1186 const EVP_MD *digest;
1187 X509V3_CTX ctx;
1188 unsigned int i;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02001189 int key_type;
Christopher Faulet31af49d2015-06-09 17:29:50 +02001190
Christopher Faulet7969a332015-10-09 11:15:03 +02001191 /* Get the private key of the defautl certificate and use it */
1192 if (!(pkey = SSL_get_privatekey(ssl)))
Christopher Faulet31af49d2015-06-09 17:29:50 +02001193 goto mkcert_error;
1194
1195 /* Create the certificate */
1196 if (!(newcrt = X509_new()))
1197 goto mkcert_error;
1198
1199 /* Set version number for the certificate (X509v3) and the serial
1200 * number */
1201 if (X509_set_version(newcrt, 2L) != 1)
1202 goto mkcert_error;
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001203 if (!serial)
1204 serial = now_ms;
1205 ASN1_INTEGER_set(X509_get_serialNumber(newcrt), serial++);
Christopher Faulet31af49d2015-06-09 17:29:50 +02001206
1207 /* Set duration for the certificate */
1208 if (!X509_gmtime_adj(X509_get_notBefore(newcrt), (long)-60*60*24) ||
1209 !X509_gmtime_adj(X509_get_notAfter(newcrt),(long)60*60*24*365))
1210 goto mkcert_error;
1211
1212 /* set public key in the certificate */
1213 if (X509_set_pubkey(newcrt, pkey) != 1)
1214 goto mkcert_error;
1215
1216 /* Set issuer name from the CA */
1217 if (!(name = X509_get_subject_name(cacert)))
1218 goto mkcert_error;
1219 if (X509_set_issuer_name(newcrt, name) != 1)
1220 goto mkcert_error;
1221
1222 /* Set the subject name using the same, but the CN */
1223 name = X509_NAME_dup(name);
1224 if (X509_NAME_add_entry_by_txt(name, "CN", MBSTRING_ASC,
1225 (const unsigned char *)servername,
1226 -1, -1, 0) != 1) {
1227 X509_NAME_free(name);
1228 goto mkcert_error;
1229 }
1230 if (X509_set_subject_name(newcrt, name) != 1) {
1231 X509_NAME_free(name);
1232 goto mkcert_error;
1233 }
1234 X509_NAME_free(name);
1235
1236 /* Add x509v3 extensions as specified */
1237 X509V3_set_ctx(&ctx, cacert, newcrt, NULL, NULL, 0);
1238 for (i = 0; i < X509V3_EXT_SIZE; i++) {
1239 X509_EXTENSION *ext;
1240
1241 if (!(ext = X509V3_EXT_conf(NULL, &ctx, x509v3_ext_names[i], x509v3_ext_values[i])))
1242 goto mkcert_error;
1243 if (!X509_add_ext(newcrt, ext, -1)) {
1244 X509_EXTENSION_free(ext);
1245 goto mkcert_error;
1246 }
1247 X509_EXTENSION_free(ext);
1248 }
1249
1250 /* Sign the certificate with the CA private key */
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02001251
1252 key_type = EVP_PKEY_base_id(capkey);
1253
1254 if (key_type == EVP_PKEY_DSA)
1255 digest = EVP_sha1();
1256 else if (key_type == EVP_PKEY_RSA)
Christopher Faulet31af49d2015-06-09 17:29:50 +02001257 digest = EVP_sha256();
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02001258 else if (key_type == EVP_PKEY_EC)
Christopher Faulet7969a332015-10-09 11:15:03 +02001259 digest = EVP_sha256();
1260 else {
Christopher Faulete7db2162015-10-19 13:59:24 +02001261#if (OPENSSL_VERSION_NUMBER >= 0x1000000fL)
Christopher Faulet7969a332015-10-09 11:15:03 +02001262 int nid;
1263
1264 if (EVP_PKEY_get_default_digest_nid(capkey, &nid) <= 0)
1265 goto mkcert_error;
1266 if (!(digest = EVP_get_digestbynid(nid)))
1267 goto mkcert_error;
Christopher Faulete7db2162015-10-19 13:59:24 +02001268#else
1269 goto mkcert_error;
1270#endif
Christopher Faulet7969a332015-10-09 11:15:03 +02001271 }
1272
Christopher Faulet31af49d2015-06-09 17:29:50 +02001273 if (!(X509_sign(newcrt, capkey, digest)))
1274 goto mkcert_error;
1275
1276 /* Create and set the new SSL_CTX */
1277 if (!(ssl_ctx = SSL_CTX_new(SSLv23_server_method())))
1278 goto mkcert_error;
1279 if (!SSL_CTX_use_PrivateKey(ssl_ctx, pkey))
1280 goto mkcert_error;
1281 if (!SSL_CTX_use_certificate(ssl_ctx, newcrt))
1282 goto mkcert_error;
1283 if (!SSL_CTX_check_private_key(ssl_ctx))
1284 goto mkcert_error;
1285
1286 if (newcrt) X509_free(newcrt);
Christopher Faulet7969a332015-10-09 11:15:03 +02001287
Christopher Faulet85b5a1a2015-10-09 11:46:32 +02001288 SSL_CTX_set_tmp_dh_callback(ssl_ctx, ssl_get_tmp_dh);
1289#if defined(SSL_CTX_set_tmp_ecdh) && !defined(OPENSSL_NO_ECDH)
1290 {
1291 const char *ecdhe = (bind_conf->ecdhe ? bind_conf->ecdhe : ECDHE_DEFAULT_CURVE);
1292 EC_KEY *ecc;
1293 int nid;
1294
1295 if ((nid = OBJ_sn2nid(ecdhe)) == NID_undef)
1296 goto end;
1297 if (!(ecc = EC_KEY_new_by_curve_name(nid)))
1298 goto end;
1299 SSL_CTX_set_tmp_ecdh(ssl_ctx, ecc);
1300 EC_KEY_free(ecc);
1301 }
1302#endif
1303 end:
Christopher Faulet31af49d2015-06-09 17:29:50 +02001304 return ssl_ctx;
1305
1306 mkcert_error:
1307 if (ssl_ctx) SSL_CTX_free(ssl_ctx);
1308 if (newcrt) X509_free(newcrt);
Christopher Faulet31af49d2015-06-09 17:29:50 +02001309 return NULL;
1310}
1311
Christopher Faulet7969a332015-10-09 11:15:03 +02001312SSL_CTX *
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001313ssl_sock_create_cert(struct connection *conn, const char *servername, unsigned int key)
Christopher Faulet7969a332015-10-09 11:15:03 +02001314{
1315 struct bind_conf *bind_conf = objt_listener(conn->target)->bind_conf;
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001316
1317 return ssl_sock_do_create_cert(servername, bind_conf, conn->xprt_ctx);
Christopher Faulet7969a332015-10-09 11:15:03 +02001318}
1319
Christopher Faulet30548802015-06-11 13:39:32 +02001320/* Do a lookup for a certificate in the LRU cache used to store generated
1321 * certificates. */
1322SSL_CTX *
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001323ssl_sock_get_generated_cert(unsigned int key, struct bind_conf *bind_conf)
Christopher Faulet30548802015-06-11 13:39:32 +02001324{
1325 struct lru64 *lru = NULL;
1326
1327 if (ssl_ctx_lru_tree) {
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001328 lru = lru64_lookup(key, ssl_ctx_lru_tree, bind_conf->ca_sign_cert, 0);
Christopher Faulet30548802015-06-11 13:39:32 +02001329 if (lru && lru->domain)
1330 return (SSL_CTX *)lru->data;
1331 }
1332 return NULL;
1333}
1334
Christopher Fauletd2cab922015-07-28 16:03:47 +02001335/* Set a certificate int the LRU cache used to store generated
1336 * certificate. Return 0 on success, otherwise -1 */
1337int
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001338ssl_sock_set_generated_cert(SSL_CTX *ssl_ctx, unsigned int key, struct bind_conf *bind_conf)
Christopher Faulet30548802015-06-11 13:39:32 +02001339{
1340 struct lru64 *lru = NULL;
1341
1342 if (ssl_ctx_lru_tree) {
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001343 lru = lru64_get(key, ssl_ctx_lru_tree, bind_conf->ca_sign_cert, 0);
Christopher Faulet30548802015-06-11 13:39:32 +02001344 if (!lru)
Christopher Fauletd2cab922015-07-28 16:03:47 +02001345 return -1;
Christopher Faulet30548802015-06-11 13:39:32 +02001346 if (lru->domain && lru->data)
1347 lru->free((SSL_CTX *)lru->data);
Christopher Faulet7969a332015-10-09 11:15:03 +02001348 lru64_commit(lru, ssl_ctx, bind_conf->ca_sign_cert, 0, (void (*)(void *))SSL_CTX_free);
Christopher Fauletd2cab922015-07-28 16:03:47 +02001349 return 0;
Christopher Faulet30548802015-06-11 13:39:32 +02001350 }
Christopher Fauletd2cab922015-07-28 16:03:47 +02001351 return -1;
Christopher Faulet30548802015-06-11 13:39:32 +02001352}
1353
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001354/* Compute the key of the certificate. */
Christopher Faulet30548802015-06-11 13:39:32 +02001355unsigned int
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001356ssl_sock_generated_cert_key(const void *data, size_t len)
Christopher Faulet30548802015-06-11 13:39:32 +02001357{
1358 return XXH32(data, len, ssl_ctx_lru_seed);
1359}
1360
Willy Tarreau2f63ef42015-10-20 15:16:01 +02001361/* Generate a cert and immediately assign it to the SSL session so that the cert's
1362 * refcount is maintained regardless of the cert's presence in the LRU cache.
1363 */
Christopher Faulet31af49d2015-06-09 17:29:50 +02001364static SSL_CTX *
Christopher Faulet7969a332015-10-09 11:15:03 +02001365ssl_sock_generate_certificate(const char *servername, struct bind_conf *bind_conf, SSL *ssl)
Christopher Faulet31af49d2015-06-09 17:29:50 +02001366{
1367 X509 *cacert = bind_conf->ca_sign_cert;
Christopher Faulet31af49d2015-06-09 17:29:50 +02001368 SSL_CTX *ssl_ctx = NULL;
1369 struct lru64 *lru = NULL;
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001370 unsigned int key;
Christopher Faulet31af49d2015-06-09 17:29:50 +02001371
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001372 key = ssl_sock_generated_cert_key(servername, strlen(servername));
Christopher Faulet31af49d2015-06-09 17:29:50 +02001373 if (ssl_ctx_lru_tree) {
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001374 lru = lru64_get(key, ssl_ctx_lru_tree, cacert, 0);
Christopher Faulet31af49d2015-06-09 17:29:50 +02001375 if (lru && lru->domain)
1376 ssl_ctx = (SSL_CTX *)lru->data;
Christopher Fauletd2cab922015-07-28 16:03:47 +02001377 if (!ssl_ctx && lru) {
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001378 ssl_ctx = ssl_sock_do_create_cert(servername, bind_conf, ssl);
Christopher Faulet31af49d2015-06-09 17:29:50 +02001379 lru64_commit(lru, ssl_ctx, cacert, 0, (void (*)(void *))SSL_CTX_free);
Christopher Fauletd2cab922015-07-28 16:03:47 +02001380 }
Willy Tarreau2f63ef42015-10-20 15:16:01 +02001381 SSL_set_SSL_CTX(ssl, ssl_ctx);
Christopher Faulet31af49d2015-06-09 17:29:50 +02001382 }
Willy Tarreau2f63ef42015-10-20 15:16:01 +02001383 else {
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001384 ssl_ctx = ssl_sock_do_create_cert(servername, bind_conf, ssl);
Willy Tarreau2f63ef42015-10-20 15:16:01 +02001385 SSL_set_SSL_CTX(ssl, ssl_ctx);
1386 /* No LRU cache, this CTX will be released as soon as the session dies */
1387 SSL_CTX_free(ssl_ctx);
1388 }
Christopher Faulet31af49d2015-06-09 17:29:50 +02001389 return ssl_ctx;
1390}
1391
Emeric Brunfc0421f2012-09-07 17:30:07 +02001392/* Sets the SSL ctx of <ssl> to match the advertised server name. Returns a
1393 * warning when no match is found, which implies the default (first) cert
1394 * will keep being used.
1395 */
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001396static int ssl_sock_switchctx_cbk(SSL *ssl, int *al, struct bind_conf *s)
Emeric Brunfc0421f2012-09-07 17:30:07 +02001397{
1398 const char *servername;
1399 const char *wildp = NULL;
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001400 struct ebmb_node *node, *n;
Emeric Brunfc0421f2012-09-07 17:30:07 +02001401 int i;
1402 (void)al; /* shut gcc stupid warning */
1403
1404 servername = SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name);
Emmanuel Hocdet65623372013-01-24 17:17:15 +01001405 if (!servername) {
Willy Tarreauf6721452015-07-07 18:04:38 +02001406 if (s->generate_certs) {
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02001407 struct connection *conn = SSL_get_app_data(ssl);
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001408 unsigned int key;
Willy Tarreauf6721452015-07-07 18:04:38 +02001409 SSL_CTX *ctx;
Christopher Faulet30548802015-06-11 13:39:32 +02001410
Willy Tarreauf6721452015-07-07 18:04:38 +02001411 conn_get_to_addr(conn);
1412 if (conn->flags & CO_FL_ADDR_TO_SET) {
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001413 key = ssl_sock_generated_cert_key(&conn->addr.to, get_addr_len(&conn->addr.to));
1414 ctx = ssl_sock_get_generated_cert(key, s);
Willy Tarreauf6721452015-07-07 18:04:38 +02001415 if (ctx) {
1416 /* switch ctx */
1417 SSL_set_SSL_CTX(ssl, ctx);
1418 return SSL_TLSEXT_ERR_OK;
1419 }
Christopher Faulet30548802015-06-11 13:39:32 +02001420 }
1421 }
1422
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001423 return (s->strict_sni ?
1424 SSL_TLSEXT_ERR_ALERT_FATAL :
Emmanuel Hocdet79274e22013-05-31 12:47:44 +02001425 SSL_TLSEXT_ERR_NOACK);
Emmanuel Hocdet65623372013-01-24 17:17:15 +01001426 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02001427
Willy Tarreau19d14ef2012-10-29 16:51:55 +01001428 for (i = 0; i < trash.size; i++) {
Emeric Brunfc0421f2012-09-07 17:30:07 +02001429 if (!servername[i])
1430 break;
Willy Tarreau19d14ef2012-10-29 16:51:55 +01001431 trash.str[i] = tolower(servername[i]);
1432 if (!wildp && (trash.str[i] == '.'))
1433 wildp = &trash.str[i];
Emeric Brunfc0421f2012-09-07 17:30:07 +02001434 }
Willy Tarreau19d14ef2012-10-29 16:51:55 +01001435 trash.str[i] = 0;
Emeric Brunfc0421f2012-09-07 17:30:07 +02001436
1437 /* lookup in full qualified names */
Willy Tarreau19d14ef2012-10-29 16:51:55 +01001438 node = ebst_lookup(&s->sni_ctx, trash.str);
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001439
1440 /* lookup a not neg filter */
1441 for (n = node; n; n = ebmb_next_dup(n)) {
1442 if (!container_of(n, struct sni_ctx, name)->neg) {
1443 node = n;
1444 break;
Emmanuel Hocdet65623372013-01-24 17:17:15 +01001445 }
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001446 }
1447 if (!node && wildp) {
1448 /* lookup in wildcards names */
Emeric Brunfc0421f2012-09-07 17:30:07 +02001449 node = ebst_lookup(&s->sni_w_ctx, wildp);
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001450 }
1451 if (!node || container_of(node, struct sni_ctx, name)->neg) {
Christopher Faulet31af49d2015-06-09 17:29:50 +02001452 SSL_CTX *ctx;
Christopher Faulet31af49d2015-06-09 17:29:50 +02001453 if (s->generate_certs &&
Christopher Faulet7969a332015-10-09 11:15:03 +02001454 (ctx = ssl_sock_generate_certificate(servername, s, ssl))) {
Christopher Faulet31af49d2015-06-09 17:29:50 +02001455 /* switch ctx */
Christopher Faulet31af49d2015-06-09 17:29:50 +02001456 return SSL_TLSEXT_ERR_OK;
1457 }
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001458 return (s->strict_sni ?
1459 SSL_TLSEXT_ERR_ALERT_FATAL :
1460 SSL_TLSEXT_ERR_ALERT_WARNING);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001461 }
1462
1463 /* switch ctx */
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001464 SSL_set_SSL_CTX(ssl, container_of(node, struct sni_ctx, name)->ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001465 return SSL_TLSEXT_ERR_OK;
1466}
1467#endif /* SSL_CTRL_SET_TLSEXT_HOSTNAME */
1468
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001469#ifndef OPENSSL_NO_DH
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001470
1471static DH * ssl_get_dh_1024(void)
1472{
Remi Gacogned3a341a2015-05-29 16:26:17 +02001473 static unsigned char dh1024_p[]={
1474 0xFA,0xF9,0x2A,0x22,0x2A,0xA7,0x7F,0xE1,0x67,0x4E,0x53,0xF7,
1475 0x56,0x13,0xC3,0xB1,0xE3,0x29,0x6B,0x66,0x31,0x6A,0x7F,0xB3,
1476 0xC2,0x68,0x6B,0xCB,0x1D,0x57,0x39,0x1D,0x1F,0xFF,0x1C,0xC9,
1477 0xA6,0xA4,0x98,0x82,0x31,0x5D,0x25,0xFF,0x8A,0xE0,0x73,0x96,
1478 0x81,0xC8,0x83,0x79,0xC1,0x5A,0x04,0xF8,0x37,0x0D,0xA8,0x3D,
1479 0xAE,0x74,0xBC,0xDB,0xB6,0xA4,0x75,0xD9,0x71,0x8A,0xA0,0x17,
1480 0x9E,0x2D,0xC8,0xA8,0xDF,0x2C,0x5F,0x82,0x95,0xF8,0x92,0x9B,
1481 0xA7,0x33,0x5F,0x89,0x71,0xC8,0x2D,0x6B,0x18,0x86,0xC4,0x94,
1482 0x22,0xA5,0x52,0x8D,0xF6,0xF6,0xD2,0x37,0x92,0x0F,0xA5,0xCC,
1483 0xDB,0x7B,0x1D,0x3D,0xA1,0x31,0xB7,0x80,0x8F,0x0B,0x67,0x5E,
1484 0x36,0xA5,0x60,0x0C,0xF1,0x95,0x33,0x8B,
1485 };
1486 static unsigned char dh1024_g[]={
1487 0x02,
1488 };
1489
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02001490 BIGNUM *p;
1491 BIGNUM *g;
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001492 DH *dh = DH_new();
1493 if (dh) {
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02001494 p = BN_bin2bn(dh1024_p, sizeof dh1024_p, NULL);
1495 g = BN_bin2bn(dh1024_g, sizeof dh1024_g, NULL);
Remi Gacogned3a341a2015-05-29 16:26:17 +02001496
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02001497 if (!p || !g) {
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001498 DH_free(dh);
1499 dh = NULL;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02001500 } else {
1501 DH_set0_pqg(dh, p, NULL, g);
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001502 }
1503 }
1504 return dh;
1505}
1506
1507static DH *ssl_get_dh_2048(void)
1508{
Remi Gacogned3a341a2015-05-29 16:26:17 +02001509 static unsigned char dh2048_p[]={
1510 0xEC,0x86,0xF8,0x70,0xA0,0x33,0x16,0xEC,0x05,0x1A,0x73,0x59,
1511 0xCD,0x1F,0x8B,0xF8,0x29,0xE4,0xD2,0xCF,0x52,0xDD,0xC2,0x24,
1512 0x8D,0xB5,0x38,0x9A,0xFB,0x5C,0xA4,0xE4,0xB2,0xDA,0xCE,0x66,
1513 0x50,0x74,0xA6,0x85,0x4D,0x4B,0x1D,0x30,0xB8,0x2B,0xF3,0x10,
1514 0xE9,0xA7,0x2D,0x05,0x71,0xE7,0x81,0xDF,0x8B,0x59,0x52,0x3B,
1515 0x5F,0x43,0x0B,0x68,0xF1,0xDB,0x07,0xBE,0x08,0x6B,0x1B,0x23,
1516 0xEE,0x4D,0xCC,0x9E,0x0E,0x43,0xA0,0x1E,0xDF,0x43,0x8C,0xEC,
1517 0xBE,0xBE,0x90,0xB4,0x51,0x54,0xB9,0x2F,0x7B,0x64,0x76,0x4E,
1518 0x5D,0xD4,0x2E,0xAE,0xC2,0x9E,0xAE,0x51,0x43,0x59,0xC7,0x77,
1519 0x9C,0x50,0x3C,0x0E,0xED,0x73,0x04,0x5F,0xF1,0x4C,0x76,0x2A,
1520 0xD8,0xF8,0xCF,0xFC,0x34,0x40,0xD1,0xB4,0x42,0x61,0x84,0x66,
1521 0x42,0x39,0x04,0xF8,0x68,0xB2,0x62,0xD7,0x55,0xED,0x1B,0x74,
1522 0x75,0x91,0xE0,0xC5,0x69,0xC1,0x31,0x5C,0xDB,0x7B,0x44,0x2E,
1523 0xCE,0x84,0x58,0x0D,0x1E,0x66,0x0C,0xC8,0x44,0x9E,0xFD,0x40,
1524 0x08,0x67,0x5D,0xFB,0xA7,0x76,0x8F,0x00,0x11,0x87,0xE9,0x93,
1525 0xF9,0x7D,0xC4,0xBC,0x74,0x55,0x20,0xD4,0x4A,0x41,0x2F,0x43,
1526 0x42,0x1A,0xC1,0xF2,0x97,0x17,0x49,0x27,0x37,0x6B,0x2F,0x88,
1527 0x7E,0x1C,0xA0,0xA1,0x89,0x92,0x27,0xD9,0x56,0x5A,0x71,0xC1,
1528 0x56,0x37,0x7E,0x3A,0x9D,0x05,0xE7,0xEE,0x5D,0x8F,0x82,0x17,
1529 0xBC,0xE9,0xC2,0x93,0x30,0x82,0xF9,0xF4,0xC9,0xAE,0x49,0xDB,
1530 0xD0,0x54,0xB4,0xD9,0x75,0x4D,0xFA,0x06,0xB8,0xD6,0x38,0x41,
1531 0xB7,0x1F,0x77,0xF3,
1532 };
1533 static unsigned char dh2048_g[]={
1534 0x02,
1535 };
1536
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02001537 BIGNUM *p;
1538 BIGNUM *g;
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001539 DH *dh = DH_new();
1540 if (dh) {
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02001541 p = BN_bin2bn(dh2048_p, sizeof dh2048_p, NULL);
1542 g = BN_bin2bn(dh2048_g, sizeof dh2048_g, NULL);
Remi Gacogned3a341a2015-05-29 16:26:17 +02001543
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02001544 if (!p || !g) {
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001545 DH_free(dh);
1546 dh = NULL;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02001547 } else {
1548 DH_set0_pqg(dh, p, NULL, g);
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001549 }
1550 }
1551 return dh;
1552}
1553
1554static DH *ssl_get_dh_4096(void)
1555{
Remi Gacogned3a341a2015-05-29 16:26:17 +02001556 static unsigned char dh4096_p[]={
1557 0xDE,0x16,0x94,0xCD,0x99,0x58,0x07,0xF1,0xF7,0x32,0x96,0x11,
1558 0x04,0x82,0xD4,0x84,0x72,0x80,0x99,0x06,0xCA,0xF0,0xA3,0x68,
1559 0x07,0xCE,0x64,0x50,0xE7,0x74,0x45,0x20,0x80,0x5E,0x4D,0xAD,
1560 0xA5,0xB6,0xED,0xFA,0x80,0x6C,0x3B,0x35,0xC4,0x9A,0x14,0x6B,
1561 0x32,0xBB,0xFD,0x1F,0x17,0x8E,0xB7,0x1F,0xD6,0xFA,0x3F,0x7B,
1562 0xEE,0x16,0xA5,0x62,0x33,0x0D,0xED,0xBC,0x4E,0x58,0xE5,0x47,
1563 0x4D,0xE9,0xAB,0x8E,0x38,0xD3,0x6E,0x90,0x57,0xE3,0x22,0x15,
1564 0x33,0xBD,0xF6,0x43,0x45,0xB5,0x10,0x0A,0xBE,0x2C,0xB4,0x35,
1565 0xB8,0x53,0x8D,0xAD,0xFB,0xA7,0x1F,0x85,0x58,0x41,0x7A,0x79,
1566 0x20,0x68,0xB3,0xE1,0x3D,0x08,0x76,0xBF,0x86,0x0D,0x49,0xE3,
1567 0x82,0x71,0x8C,0xB4,0x8D,0x81,0x84,0xD4,0xE7,0xBE,0x91,0xDC,
1568 0x26,0x39,0x48,0x0F,0x35,0xC4,0xCA,0x65,0xE3,0x40,0x93,0x52,
1569 0x76,0x58,0x7D,0xDD,0x51,0x75,0xDC,0x69,0x61,0xBF,0x47,0x2C,
1570 0x16,0x68,0x2D,0xC9,0x29,0xD3,0xE6,0xC0,0x99,0x48,0xA0,0x9A,
1571 0xC8,0x78,0xC0,0x6D,0x81,0x67,0x12,0x61,0x3F,0x71,0xBA,0x41,
1572 0x1F,0x6C,0x89,0x44,0x03,0xBA,0x3B,0x39,0x60,0xAA,0x28,0x55,
1573 0x59,0xAE,0xB8,0xFA,0xCB,0x6F,0xA5,0x1A,0xF7,0x2B,0xDD,0x52,
1574 0x8A,0x8B,0xE2,0x71,0xA6,0x5E,0x7E,0xD8,0x2E,0x18,0xE0,0x66,
1575 0xDF,0xDD,0x22,0x21,0x99,0x52,0x73,0xA6,0x33,0x20,0x65,0x0E,
1576 0x53,0xE7,0x6B,0x9B,0xC5,0xA3,0x2F,0x97,0x65,0x76,0xD3,0x47,
1577 0x23,0x77,0x12,0xB6,0x11,0x7B,0x24,0xED,0xF1,0xEF,0xC0,0xE2,
1578 0xA3,0x7E,0x67,0x05,0x3E,0x96,0x4D,0x45,0xC2,0x18,0xD1,0x73,
1579 0x9E,0x07,0xF3,0x81,0x6E,0x52,0x63,0xF6,0x20,0x76,0xB9,0x13,
1580 0xD2,0x65,0x30,0x18,0x16,0x09,0x16,0x9E,0x8F,0xF1,0xD2,0x10,
1581 0x5A,0xD3,0xD4,0xAF,0x16,0x61,0xDA,0x55,0x2E,0x18,0x5E,0x14,
1582 0x08,0x54,0x2E,0x2A,0x25,0xA2,0x1A,0x9B,0x8B,0x32,0xA9,0xFD,
1583 0xC2,0x48,0x96,0xE1,0x80,0xCA,0xE9,0x22,0x17,0xBB,0xCE,0x3E,
1584 0x9E,0xED,0xC7,0xF1,0x1F,0xEC,0x17,0x21,0xDC,0x7B,0x82,0x48,
1585 0x8E,0xBB,0x4B,0x9D,0x5B,0x04,0x04,0xDA,0xDB,0x39,0xDF,0x01,
1586 0x40,0xC3,0xAA,0x26,0x23,0x89,0x75,0xC6,0x0B,0xD0,0xA2,0x60,
1587 0x6A,0xF1,0xCC,0x65,0x18,0x98,0x1B,0x52,0xD2,0x74,0x61,0xCC,
1588 0xBD,0x60,0xAE,0xA3,0xA0,0x66,0x6A,0x16,0x34,0x92,0x3F,0x41,
1589 0x40,0x31,0x29,0xC0,0x2C,0x63,0xB2,0x07,0x8D,0xEB,0x94,0xB8,
1590 0xE8,0x47,0x92,0x52,0x93,0x6A,0x1B,0x7E,0x1A,0x61,0xB3,0x1B,
1591 0xF0,0xD6,0x72,0x9B,0xF1,0xB0,0xAF,0xBF,0x3E,0x65,0xEF,0x23,
1592 0x1D,0x6F,0xFF,0x70,0xCD,0x8A,0x4C,0x8A,0xA0,0x72,0x9D,0xBE,
1593 0xD4,0xBB,0x24,0x47,0x4A,0x68,0xB5,0xF5,0xC6,0xD5,0x7A,0xCD,
1594 0xCA,0x06,0x41,0x07,0xAD,0xC2,0x1E,0xE6,0x54,0xA7,0xAD,0x03,
1595 0xD9,0x12,0xC1,0x9C,0x13,0xB1,0xC9,0x0A,0x43,0x8E,0x1E,0x08,
1596 0xCE,0x50,0x82,0x73,0x5F,0xA7,0x55,0x1D,0xD9,0x59,0xAC,0xB5,
1597 0xEA,0x02,0x7F,0x6C,0x5B,0x74,0x96,0x98,0x67,0x24,0xA3,0x0F,
1598 0x15,0xFC,0xA9,0x7D,0x3E,0x67,0xD1,0x70,0xF8,0x97,0xF3,0x67,
1599 0xC5,0x8C,0x88,0x44,0x08,0x02,0xC7,0x2B,
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001600 };
Remi Gacogned3a341a2015-05-29 16:26:17 +02001601 static unsigned char dh4096_g[]={
1602 0x02,
1603 };
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001604
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02001605 BIGNUM *p;
1606 BIGNUM *g;
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001607 DH *dh = DH_new();
1608 if (dh) {
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02001609 p = BN_bin2bn(dh4096_p, sizeof dh4096_p, NULL);
1610 g = BN_bin2bn(dh4096_g, sizeof dh4096_g, NULL);
Remi Gacogned3a341a2015-05-29 16:26:17 +02001611
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02001612 if (!p || !g) {
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001613 DH_free(dh);
1614 dh = NULL;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02001615 } else {
1616 DH_set0_pqg(dh, p, NULL, g);
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001617 }
1618 }
1619 return dh;
1620}
1621
1622/* Returns Diffie-Hellman parameters matching the private key length
1623 but not exceeding global.tune.ssl_default_dh_param */
1624static DH *ssl_get_tmp_dh(SSL *ssl, int export, int keylen)
1625{
1626 DH *dh = NULL;
1627 EVP_PKEY *pkey = SSL_get_privatekey(ssl);
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02001628 int type;
1629
1630 type = pkey ? EVP_PKEY_base_id(pkey) : EVP_PKEY_NONE;
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001631
1632 /* The keylen supplied by OpenSSL can only be 512 or 1024.
1633 See ssl3_send_server_key_exchange() in ssl/s3_srvr.c
1634 */
1635 if (type == EVP_PKEY_RSA || type == EVP_PKEY_DSA) {
1636 keylen = EVP_PKEY_bits(pkey);
1637 }
1638
1639 if (keylen > global.tune.ssl_default_dh_param) {
1640 keylen = global.tune.ssl_default_dh_param;
1641 }
1642
Remi Gacogned3a341a2015-05-29 16:26:17 +02001643 if (keylen >= 4096) {
Remi Gacogne8de54152014-07-15 11:36:40 +02001644 dh = local_dh_4096;
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001645 }
1646 else if (keylen >= 2048) {
Remi Gacogne8de54152014-07-15 11:36:40 +02001647 dh = local_dh_2048;
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001648 }
1649 else {
Remi Gacogne8de54152014-07-15 11:36:40 +02001650 dh = local_dh_1024;
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001651 }
1652
1653 return dh;
1654}
1655
Remi Gacogne47783ef2015-05-29 15:53:22 +02001656static DH * ssl_sock_get_dh_from_file(const char *filename)
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001657{
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001658 DH *dh = NULL;
Remi Gacogne47783ef2015-05-29 15:53:22 +02001659 BIO *in = BIO_new(BIO_s_file());
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001660
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001661 if (in == NULL)
1662 goto end;
1663
Remi Gacogne47783ef2015-05-29 15:53:22 +02001664 if (BIO_read_filename(in, filename) <= 0)
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001665 goto end;
1666
Remi Gacogne47783ef2015-05-29 15:53:22 +02001667 dh = PEM_read_bio_DHparams(in, NULL, NULL, NULL);
1668
1669end:
1670 if (in)
1671 BIO_free(in);
1672
1673 return dh;
1674}
1675
1676int ssl_sock_load_global_dh_param_from_file(const char *filename)
1677{
1678 global_dh = ssl_sock_get_dh_from_file(filename);
1679
1680 if (global_dh) {
1681 return 0;
1682 }
1683
1684 return -1;
1685}
1686
1687/* Loads Diffie-Hellman parameter from a file. Returns 1 if loaded, else -1
1688 if an error occured, and 0 if parameter not found. */
1689int ssl_sock_load_dh_params(SSL_CTX *ctx, const char *file)
1690{
1691 int ret = -1;
1692 DH *dh = ssl_sock_get_dh_from_file(file);
1693
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001694 if (dh) {
1695 ret = 1;
1696 SSL_CTX_set_tmp_dh(ctx, dh);
Remi Gacogne4f902b82015-05-28 16:23:00 +02001697
1698 if (ssl_dh_ptr_index >= 0) {
1699 /* store a pointer to the DH params to avoid complaining about
1700 ssl-default-dh-param not being set for this SSL_CTX */
1701 SSL_CTX_set_ex_data(ctx, ssl_dh_ptr_index, dh);
1702 }
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001703 }
Remi Gacogne47783ef2015-05-29 15:53:22 +02001704 else if (global_dh) {
1705 SSL_CTX_set_tmp_dh(ctx, global_dh);
1706 ret = 0; /* DH params not found */
1707 }
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001708 else {
Emeric Brun41fdb3c2013-04-26 11:05:44 +02001709 /* Clear openssl global errors stack */
1710 ERR_clear_error();
1711
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001712 if (global.tune.ssl_default_dh_param <= 1024) {
1713 /* we are limited to DH parameter of 1024 bits anyway */
Remi Gacognec7e12632016-07-02 16:26:10 +02001714 if (local_dh_1024 == NULL)
1715 local_dh_1024 = ssl_get_dh_1024();
1716
Remi Gacogne8de54152014-07-15 11:36:40 +02001717 if (local_dh_1024 == NULL)
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001718 goto end;
Willy Tarreau6e774b42014-04-25 21:35:23 +02001719
Remi Gacogne8de54152014-07-15 11:36:40 +02001720 SSL_CTX_set_tmp_dh(ctx, local_dh_1024);
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001721 }
1722 else {
1723 SSL_CTX_set_tmp_dh_callback(ctx, ssl_get_tmp_dh);
1724 }
Willy Tarreau6e774b42014-04-25 21:35:23 +02001725
Emeric Brun41fdb3c2013-04-26 11:05:44 +02001726 ret = 0; /* DH params not found */
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001727 }
Emeric Brun644cde02012-12-14 11:21:13 +01001728
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001729end:
1730 if (dh)
1731 DH_free(dh);
1732
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001733 return ret;
1734}
1735#endif
1736
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001737static int ssl_sock_add_cert_sni(SSL_CTX *ctx, struct bind_conf *s, char *name, int order)
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001738{
1739 struct sni_ctx *sc;
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001740 int wild = 0, neg = 0;
Thierry FOURNIER / OZON.IO07c3d782016-10-06 10:56:48 +02001741 struct ebmb_node *node;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001742
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001743 if (*name == '!') {
1744 neg = 1;
1745 name++;
1746 }
1747 if (*name == '*') {
1748 wild = 1;
1749 name++;
1750 }
1751 /* !* filter is a nop */
1752 if (neg && wild)
1753 return order;
1754 if (*name) {
1755 int j, len;
1756 len = strlen(name);
Thierry FOURNIER / OZON.IO07c3d782016-10-06 10:56:48 +02001757 for (j = 0; j < len && j < trash.size; j++)
1758 trash.str[j] = tolower(name[j]);
1759 if (j >= trash.size)
1760 return order;
1761 trash.str[j] = 0;
1762
1763 /* Check for duplicates. */
1764 if (wild)
1765 node = ebst_lookup(&s->sni_w_ctx, trash.str);
1766 else
1767 node = ebst_lookup(&s->sni_ctx, trash.str);
1768 for (; node; node = ebmb_next_dup(node)) {
1769 sc = ebmb_entry(node, struct sni_ctx, name);
1770 if (sc->ctx == ctx && sc->neg == neg)
1771 return order;
1772 }
1773
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001774 sc = malloc(sizeof(struct sni_ctx) + len + 1);
Thierry FOURNIER / OZON.IO7a3bd3b2016-10-06 10:35:29 +02001775 if (!sc)
1776 return order;
Thierry FOURNIER / OZON.IO07c3d782016-10-06 10:56:48 +02001777 memcpy(sc->name.key, trash.str, len + 1);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001778 sc->ctx = ctx;
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001779 sc->order = order++;
1780 sc->neg = neg;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001781 if (wild)
1782 ebst_insert(&s->sni_w_ctx, &sc->name);
1783 else
1784 ebst_insert(&s->sni_ctx, &sc->name);
1785 }
1786 return order;
1787}
1788
yanbzhu488a4d22015-12-01 15:16:07 -05001789
1790/* The following code is used for loading multiple crt files into
1791 * SSL_CTX's based on CN/SAN
1792 */
Luca Pizzamiglio578b1692016-12-12 10:56:56 +01001793#if OPENSSL_VERSION_NUMBER >= 0x1000200fL && !defined(LIBRESSL_VERSION_NUMBER)
yanbzhu488a4d22015-12-01 15:16:07 -05001794/* This is used to preload the certifcate, private key
1795 * and Cert Chain of a file passed in via the crt
1796 * argument
1797 *
1798 * This way, we do not have to read the file multiple times
1799 */
1800struct cert_key_and_chain {
1801 X509 *cert;
1802 EVP_PKEY *key;
1803 unsigned int num_chain_certs;
1804 /* This is an array of X509 pointers */
1805 X509 **chain_certs;
1806};
1807
yanbzhu08ce6ab2015-12-02 13:01:29 -05001808#define SSL_SOCK_POSSIBLE_KT_COMBOS (1<<(SSL_SOCK_NUM_KEYTYPES))
1809
1810struct key_combo_ctx {
1811 SSL_CTX *ctx;
1812 int order;
1813};
1814
1815/* Map used for processing multiple keypairs for a single purpose
1816 *
1817 * This maps CN/SNI name to certificate type
1818 */
1819struct sni_keytype {
1820 int keytypes; /* BITMASK for keytypes */
1821 struct ebmb_node name; /* node holding the servername value */
1822};
1823
1824
yanbzhu488a4d22015-12-01 15:16:07 -05001825/* Frees the contents of a cert_key_and_chain
1826 */
1827static void ssl_sock_free_cert_key_and_chain_contents(struct cert_key_and_chain *ckch)
1828{
1829 int i;
1830
1831 if (!ckch)
1832 return;
1833
1834 /* Free the certificate and set pointer to NULL */
1835 if (ckch->cert)
1836 X509_free(ckch->cert);
1837 ckch->cert = NULL;
1838
1839 /* Free the key and set pointer to NULL */
1840 if (ckch->key)
1841 EVP_PKEY_free(ckch->key);
1842 ckch->key = NULL;
1843
1844 /* Free each certificate in the chain */
1845 for (i = 0; i < ckch->num_chain_certs; i++) {
1846 if (ckch->chain_certs[i])
1847 X509_free(ckch->chain_certs[i]);
1848 }
1849
1850 /* Free the chain obj itself and set to NULL */
1851 if (ckch->num_chain_certs > 0) {
1852 free(ckch->chain_certs);
1853 ckch->num_chain_certs = 0;
1854 ckch->chain_certs = NULL;
1855 }
1856
1857}
1858
1859/* checks if a key and cert exists in the ckch
1860 */
1861static int ssl_sock_is_ckch_valid(struct cert_key_and_chain *ckch)
1862{
1863 return (ckch->cert != NULL && ckch->key != NULL);
1864}
1865
1866
1867/* Loads the contents of a crt file (path) into a cert_key_and_chain
1868 * This allows us to carry the contents of the file without having to
1869 * read the file multiple times.
1870 *
1871 * returns:
1872 * 0 on Success
1873 * 1 on SSL Failure
1874 * 2 on file not found
1875 */
1876static int ssl_sock_load_crt_file_into_ckch(const char *path, struct cert_key_and_chain *ckch, char **err)
1877{
1878
1879 BIO *in;
1880 X509 *ca = NULL;
1881 int ret = 1;
1882
1883 ssl_sock_free_cert_key_and_chain_contents(ckch);
1884
1885 in = BIO_new(BIO_s_file());
1886 if (in == NULL)
1887 goto end;
1888
1889 if (BIO_read_filename(in, path) <= 0)
1890 goto end;
1891
yanbzhu488a4d22015-12-01 15:16:07 -05001892 /* Read Private Key */
1893 ckch->key = PEM_read_bio_PrivateKey(in, NULL, NULL, NULL);
1894 if (ckch->key == NULL) {
1895 memprintf(err, "%sunable to load private key from file '%s'.\n",
1896 err && *err ? *err : "", path);
1897 goto end;
1898 }
1899
Willy Tarreaubb137a82016-04-06 19:02:38 +02001900 /* Seek back to beginning of file */
Thierry FOURNIER / OZON.IOd44ea3f2016-10-14 00:49:21 +02001901 if (BIO_reset(in) == -1) {
1902 memprintf(err, "%san error occurred while reading the file '%s'.\n",
1903 err && *err ? *err : "", path);
1904 goto end;
1905 }
Willy Tarreaubb137a82016-04-06 19:02:38 +02001906
1907 /* Read Certificate */
1908 ckch->cert = PEM_read_bio_X509_AUX(in, NULL, NULL, NULL);
1909 if (ckch->cert == NULL) {
1910 memprintf(err, "%sunable to load certificate from file '%s'.\n",
1911 err && *err ? *err : "", path);
1912 goto end;
1913 }
1914
yanbzhu488a4d22015-12-01 15:16:07 -05001915 /* Read Certificate Chain */
1916 while ((ca = PEM_read_bio_X509(in, NULL, NULL, NULL))) {
1917 /* Grow the chain certs */
1918 ckch->num_chain_certs++;
1919 ckch->chain_certs = realloc(ckch->chain_certs, (ckch->num_chain_certs * sizeof(X509 *)));
1920
1921 /* use - 1 here since we just incremented it above */
1922 ckch->chain_certs[ckch->num_chain_certs - 1] = ca;
1923 }
1924 ret = ERR_get_error();
1925 if (ret && (ERR_GET_LIB(ret) != ERR_LIB_PEM && ERR_GET_REASON(ret) != PEM_R_NO_START_LINE)) {
1926 memprintf(err, "%sunable to load certificate chain from file '%s'.\n",
1927 err && *err ? *err : "", path);
1928 ret = 1;
1929 goto end;
1930 }
1931
1932 ret = 0;
1933
1934end:
1935
1936 ERR_clear_error();
1937 if (in)
1938 BIO_free(in);
1939
1940 /* Something went wrong in one of the reads */
1941 if (ret != 0)
1942 ssl_sock_free_cert_key_and_chain_contents(ckch);
1943
1944 return ret;
1945}
1946
1947/* Loads the info in ckch into ctx
1948 * Currently, this does not process any information about ocsp, dhparams or
1949 * sctl
1950 * Returns
1951 * 0 on success
1952 * 1 on failure
1953 */
1954static int ssl_sock_put_ckch_into_ctx(const char *path, const struct cert_key_and_chain *ckch, SSL_CTX *ctx, char **err)
1955{
1956 int i = 0;
1957
1958 if (SSL_CTX_use_PrivateKey(ctx, ckch->key) <= 0) {
1959 memprintf(err, "%sunable to load SSL private key into SSL Context '%s'.\n",
1960 err && *err ? *err : "", path);
1961 return 1;
1962 }
1963
1964 if (!SSL_CTX_use_certificate(ctx, ckch->cert)) {
1965 memprintf(err, "%sunable to load SSL certificate into SSL Context '%s'.\n",
1966 err && *err ? *err : "", path);
1967 return 1;
1968 }
1969
yanbzhu488a4d22015-12-01 15:16:07 -05001970 /* Load all certs in the ckch into the ctx_chain for the ssl_ctx */
1971 for (i = 0; i < ckch->num_chain_certs; i++) {
1972 if (!SSL_CTX_add1_chain_cert(ctx, ckch->chain_certs[i])) {
yanbzhu08ce6ab2015-12-02 13:01:29 -05001973 memprintf(err, "%sunable to load chain certificate #%d into SSL Context '%s'. Make sure you are linking against Openssl >= 1.0.2.\n",
1974 err && *err ? *err : "", (i+1), path);
yanbzhu488a4d22015-12-01 15:16:07 -05001975 return 1;
1976 }
1977 }
1978
1979 if (SSL_CTX_check_private_key(ctx) <= 0) {
1980 memprintf(err, "%sinconsistencies between private key and certificate loaded from PEM file '%s'.\n",
1981 err && *err ? *err : "", path);
1982 return 1;
1983 }
1984
1985 return 0;
1986}
1987
yanbzhu08ce6ab2015-12-02 13:01:29 -05001988
1989static void ssl_sock_populate_sni_keytypes_hplr(const char *str, struct eb_root *sni_keytypes, int key_index)
1990{
1991 struct sni_keytype *s_kt = NULL;
1992 struct ebmb_node *node;
1993 int i;
1994
1995 for (i = 0; i < trash.size; i++) {
1996 if (!str[i])
1997 break;
1998 trash.str[i] = tolower(str[i]);
1999 }
2000 trash.str[i] = 0;
2001 node = ebst_lookup(sni_keytypes, trash.str);
2002 if (!node) {
2003 /* CN not found in tree */
2004 s_kt = malloc(sizeof(struct sni_keytype) + i + 1);
2005 /* Using memcpy here instead of strncpy.
2006 * strncpy will cause sig_abrt errors under certain versions of gcc with -O2
2007 * See: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=60792
2008 */
2009 memcpy(s_kt->name.key, trash.str, i+1);
2010 s_kt->keytypes = 0;
2011 ebst_insert(sni_keytypes, &s_kt->name);
2012 } else {
2013 /* CN found in tree */
2014 s_kt = container_of(node, struct sni_keytype, name);
2015 }
2016
2017 /* Mark that this CN has the keytype of key_index via keytypes mask */
2018 s_kt->keytypes |= 1<<key_index;
2019
2020}
2021
2022
2023/* Given a path that does not exist, try to check for path.rsa, path.dsa and path.ecdsa files.
2024 * If any are found, group these files into a set of SSL_CTX*
2025 * based on shared and unique CN and SAN entries. Add these SSL_CTX* to the SNI tree.
2026 *
2027 * This will allow the user to explictly group multiple cert/keys for a single purpose
2028 *
2029 * Returns
2030 * 0 on success
2031 * 1 on failure
2032 */
Willy Tarreau03209342016-12-22 17:08:28 +01002033static int ssl_sock_load_multi_cert(const char *path, struct bind_conf *bind_conf, char **sni_filter, int fcount, char **err)
yanbzhu08ce6ab2015-12-02 13:01:29 -05002034{
2035 char fp[MAXPATHLEN+1] = {0};
2036 int n = 0;
2037 int i = 0;
2038 struct cert_key_and_chain certs_and_keys[SSL_SOCK_NUM_KEYTYPES] = { {0} };
2039 struct eb_root sni_keytypes_map = { {0} };
2040 struct ebmb_node *node;
2041 struct ebmb_node *next;
2042 /* Array of SSL_CTX pointers corresponding to each possible combo
2043 * of keytypes
2044 */
2045 struct key_combo_ctx key_combos[SSL_SOCK_POSSIBLE_KT_COMBOS] = { {0} };
2046 int rv = 0;
2047 X509_NAME *xname = NULL;
2048 char *str = NULL;
2049#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
2050 STACK_OF(GENERAL_NAME) *names = NULL;
2051#endif
2052
2053 /* Load all possible certs and keys */
2054 for (n = 0; n < SSL_SOCK_NUM_KEYTYPES; n++) {
2055 struct stat buf;
2056
2057 snprintf(fp, sizeof(fp), "%s.%s", path, SSL_SOCK_KEYTYPE_NAMES[n]);
2058 if (stat(fp, &buf) == 0) {
2059 if (ssl_sock_load_crt_file_into_ckch(fp, &certs_and_keys[n], err) == 1) {
2060 rv = 1;
2061 goto end;
2062 }
2063 }
2064 }
2065
2066 /* Process each ckch and update keytypes for each CN/SAN
2067 * for example, if CN/SAN www.a.com is associated with
2068 * certs with keytype 0 and 2, then at the end of the loop,
2069 * www.a.com will have:
2070 * keyindex = 0 | 1 | 4 = 5
2071 */
2072 for (n = 0; n < SSL_SOCK_NUM_KEYTYPES; n++) {
2073
2074 if (!ssl_sock_is_ckch_valid(&certs_and_keys[n]))
2075 continue;
2076
Emmanuel Hocdetd294aea2016-05-13 11:14:06 +02002077 if (fcount) {
Willy Tarreau24b892f2016-06-20 23:01:57 +02002078 for (i = 0; i < fcount; i++)
Emmanuel Hocdetd294aea2016-05-13 11:14:06 +02002079 ssl_sock_populate_sni_keytypes_hplr(sni_filter[i], &sni_keytypes_map, n);
2080 } else {
2081 /* A lot of the following code is OpenSSL boilerplate for processing CN's and SAN's,
2082 * so the line that contains logic is marked via comments
2083 */
2084 xname = X509_get_subject_name(certs_and_keys[n].cert);
2085 i = -1;
2086 while ((i = X509_NAME_get_index_by_NID(xname, NID_commonName, i)) != -1) {
2087 X509_NAME_ENTRY *entry = X509_NAME_get_entry(xname, i);
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02002088 ASN1_STRING *value;
2089 value = X509_NAME_ENTRY_get_data(entry);
2090 if (ASN1_STRING_to_UTF8((unsigned char **)&str, value) >= 0) {
Emmanuel Hocdetd294aea2016-05-13 11:14:06 +02002091 /* Important line is here */
2092 ssl_sock_populate_sni_keytypes_hplr(str, &sni_keytypes_map, n);
yanbzhu08ce6ab2015-12-02 13:01:29 -05002093
Emmanuel Hocdetd294aea2016-05-13 11:14:06 +02002094 OPENSSL_free(str);
2095 str = NULL;
2096 }
yanbzhu08ce6ab2015-12-02 13:01:29 -05002097 }
yanbzhu08ce6ab2015-12-02 13:01:29 -05002098
Emmanuel Hocdetd294aea2016-05-13 11:14:06 +02002099 /* Do the above logic for each SAN */
yanbzhu08ce6ab2015-12-02 13:01:29 -05002100#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Emmanuel Hocdetd294aea2016-05-13 11:14:06 +02002101 names = X509_get_ext_d2i(certs_and_keys[n].cert, NID_subject_alt_name, NULL, NULL);
2102 if (names) {
2103 for (i = 0; i < sk_GENERAL_NAME_num(names); i++) {
2104 GENERAL_NAME *name = sk_GENERAL_NAME_value(names, i);
yanbzhu08ce6ab2015-12-02 13:01:29 -05002105
Emmanuel Hocdetd294aea2016-05-13 11:14:06 +02002106 if (name->type == GEN_DNS) {
2107 if (ASN1_STRING_to_UTF8((unsigned char **)&str, name->d.dNSName) >= 0) {
2108 /* Important line is here */
2109 ssl_sock_populate_sni_keytypes_hplr(str, &sni_keytypes_map, n);
yanbzhu08ce6ab2015-12-02 13:01:29 -05002110
Emmanuel Hocdetd294aea2016-05-13 11:14:06 +02002111 OPENSSL_free(str);
2112 str = NULL;
2113 }
yanbzhu08ce6ab2015-12-02 13:01:29 -05002114 }
2115 }
2116 }
2117 }
2118#endif /* SSL_CTRL_SET_TLSEXT_HOSTNAME */
2119 }
2120
2121 /* If no files found, return error */
2122 if (eb_is_empty(&sni_keytypes_map)) {
2123 memprintf(err, "%sunable to load SSL certificate file '%s' file does not exist.\n",
2124 err && *err ? *err : "", path);
2125 rv = 1;
2126 goto end;
2127 }
2128
2129 /* We now have a map of CN/SAN to keytypes that are loaded in
2130 * Iterate through the map to create the SSL_CTX's (if needed)
2131 * and add each CTX to the SNI tree
2132 *
2133 * Some math here:
2134 * There are 2^n - 1 possibile combinations, each unique
2135 * combination is denoted by the key in the map. Each key
2136 * has a value between 1 and 2^n - 1. Conveniently, the array
2137 * of SSL_CTX* is sized 2^n. So, we can simply use the i'th
2138 * entry in the array to correspond to the unique combo (key)
2139 * associated with i. This unique key combo (i) will be associated
2140 * with combos[i-1]
2141 */
2142
2143 node = ebmb_first(&sni_keytypes_map);
2144 while (node) {
2145 SSL_CTX *cur_ctx;
Bertrand Jacquin33423092016-11-13 16:37:13 +00002146 char cur_file[MAXPATHLEN+1];
yanbzhu08ce6ab2015-12-02 13:01:29 -05002147
2148 str = (char *)container_of(node, struct sni_keytype, name)->name.key;
2149 i = container_of(node, struct sni_keytype, name)->keytypes;
2150 cur_ctx = key_combos[i-1].ctx;
2151
2152 if (cur_ctx == NULL) {
2153 /* need to create SSL_CTX */
2154 cur_ctx = SSL_CTX_new(SSLv23_server_method());
2155 if (cur_ctx == NULL) {
2156 memprintf(err, "%sunable to allocate SSL context.\n",
2157 err && *err ? *err : "");
2158 rv = 1;
2159 goto end;
2160 }
2161
yanbzhube2774d2015-12-10 15:07:30 -05002162 /* Load all required certs/keys/chains/OCSPs info into SSL_CTX */
yanbzhu08ce6ab2015-12-02 13:01:29 -05002163 for (n = 0; n < SSL_SOCK_NUM_KEYTYPES; n++) {
2164 if (i & (1<<n)) {
2165 /* Key combo contains ckch[n] */
Bertrand Jacquin33423092016-11-13 16:37:13 +00002166 snprintf(cur_file, MAXPATHLEN+1, "%s.%s", path, SSL_SOCK_KEYTYPE_NAMES[n]);
2167 if (ssl_sock_put_ckch_into_ctx(cur_file, &certs_and_keys[n], cur_ctx, err) != 0) {
yanbzhu08ce6ab2015-12-02 13:01:29 -05002168 SSL_CTX_free(cur_ctx);
2169 rv = 1;
2170 goto end;
2171 }
yanbzhube2774d2015-12-10 15:07:30 -05002172
2173#if (defined SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB && !defined OPENSSL_NO_OCSP)
2174 /* Load OCSP Info into context */
Bertrand Jacquin33423092016-11-13 16:37:13 +00002175 if (ssl_sock_load_ocsp(cur_ctx, cur_file) < 0) {
yanbzhube2774d2015-12-10 15:07:30 -05002176 if (err)
2177 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 +00002178 *err ? *err : "", cur_file);
yanbzhube2774d2015-12-10 15:07:30 -05002179 SSL_CTX_free(cur_ctx);
2180 rv = 1;
2181 goto end;
2182 }
2183#endif
yanbzhu08ce6ab2015-12-02 13:01:29 -05002184 }
2185 }
2186
2187 /* Load DH params into the ctx to support DHE keys */
2188#ifndef OPENSSL_NO_DH
2189 if (ssl_dh_ptr_index >= 0)
2190 SSL_CTX_set_ex_data(cur_ctx, ssl_dh_ptr_index, NULL);
2191
2192 rv = ssl_sock_load_dh_params(cur_ctx, NULL);
2193 if (rv < 0) {
2194 if (err)
2195 memprintf(err, "%sunable to load DH parameters from file '%s'.\n",
2196 *err ? *err : "", path);
2197 rv = 1;
2198 goto end;
2199 }
2200#endif
2201
2202 /* Update key_combos */
2203 key_combos[i-1].ctx = cur_ctx;
2204 }
2205
2206 /* Update SNI Tree */
Emmanuel Hocdetd294aea2016-05-13 11:14:06 +02002207 key_combos[i-1].order = ssl_sock_add_cert_sni(cur_ctx, bind_conf, str, key_combos[i-1].order);
yanbzhu08ce6ab2015-12-02 13:01:29 -05002208 node = ebmb_next(node);
2209 }
2210
2211
2212 /* Mark a default context if none exists, using the ctx that has the most shared keys */
2213 if (!bind_conf->default_ctx) {
2214 for (i = SSL_SOCK_POSSIBLE_KT_COMBOS - 1; i >= 0; i--) {
2215 if (key_combos[i].ctx) {
2216 bind_conf->default_ctx = key_combos[i].ctx;
2217 break;
2218 }
2219 }
2220 }
2221
2222end:
2223
2224 if (names)
2225 sk_GENERAL_NAME_pop_free(names, GENERAL_NAME_free);
2226
2227 for (n = 0; n < SSL_SOCK_NUM_KEYTYPES; n++)
2228 ssl_sock_free_cert_key_and_chain_contents(&certs_and_keys[n]);
2229
2230 node = ebmb_first(&sni_keytypes_map);
2231 while (node) {
2232 next = ebmb_next(node);
2233 ebmb_delete(node);
2234 node = next;
2235 }
2236
2237 return rv;
2238}
2239#else
2240/* This is a dummy, that just logs an error and returns error */
Willy Tarreau03209342016-12-22 17:08:28 +01002241static int ssl_sock_load_multi_cert(const char *path, struct bind_conf *bind_conf, char **sni_filter, int fcount, char **err)
yanbzhu08ce6ab2015-12-02 13:01:29 -05002242{
2243 memprintf(err, "%sunable to stat SSL certificate from file '%s' : %s.\n",
2244 err && *err ? *err : "", path, strerror(errno));
2245 return 1;
2246}
2247
yanbzhu488a4d22015-12-01 15:16:07 -05002248#endif /* #if OPENSSL_VERSION_NUMBER >= 0x1000200fL: Support for loading multiple certs into a single SSL_CTX */
2249
Emeric Brunfc0421f2012-09-07 17:30:07 +02002250/* Loads a certificate key and CA chain from a file. Returns 0 on error, -1 if
2251 * an early error happens and the caller must call SSL_CTX_free() by itelf.
2252 */
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02002253static int ssl_sock_load_cert_chain_file(SSL_CTX *ctx, const char *file, struct bind_conf *s, char **sni_filter, int fcount)
Emeric Brunfc0421f2012-09-07 17:30:07 +02002254{
2255 BIO *in;
2256 X509 *x = NULL, *ca;
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02002257 int i, err;
Emeric Brunfc0421f2012-09-07 17:30:07 +02002258 int ret = -1;
2259 int order = 0;
2260 X509_NAME *xname;
2261 char *str;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02002262 pem_password_cb *passwd_cb;
2263 void *passwd_cb_userdata;
2264
Emeric Brunfc0421f2012-09-07 17:30:07 +02002265#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
2266 STACK_OF(GENERAL_NAME) *names;
2267#endif
2268
2269 in = BIO_new(BIO_s_file());
2270 if (in == NULL)
2271 goto end;
2272
2273 if (BIO_read_filename(in, file) <= 0)
2274 goto end;
2275
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02002276
2277 passwd_cb = SSL_CTX_get_default_passwd_cb(ctx);
2278 passwd_cb_userdata = SSL_CTX_get_default_passwd_cb_userdata(ctx);
2279
2280 x = PEM_read_bio_X509_AUX(in, NULL, passwd_cb, passwd_cb_userdata);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002281 if (x == NULL)
2282 goto end;
2283
Emeric Brun50bcecc2013-04-22 13:05:23 +02002284 if (fcount) {
2285 while (fcount--)
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02002286 order = ssl_sock_add_cert_sni(ctx, s, sni_filter[fcount], order);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002287 }
2288 else {
Emeric Brunfc0421f2012-09-07 17:30:07 +02002289#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002290 names = X509_get_ext_d2i(x, NID_subject_alt_name, NULL, NULL);
2291 if (names) {
2292 for (i = 0; i < sk_GENERAL_NAME_num(names); i++) {
2293 GENERAL_NAME *name = sk_GENERAL_NAME_value(names, i);
2294 if (name->type == GEN_DNS) {
2295 if (ASN1_STRING_to_UTF8((unsigned char **)&str, name->d.dNSName) >= 0) {
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02002296 order = ssl_sock_add_cert_sni(ctx, s, str, order);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002297 OPENSSL_free(str);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002298 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02002299 }
2300 }
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002301 sk_GENERAL_NAME_pop_free(names, GENERAL_NAME_free);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002302 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02002303#endif /* SSL_CTRL_SET_TLSEXT_HOSTNAME */
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002304 xname = X509_get_subject_name(x);
2305 i = -1;
2306 while ((i = X509_NAME_get_index_by_NID(xname, NID_commonName, i)) != -1) {
2307 X509_NAME_ENTRY *entry = X509_NAME_get_entry(xname, i);
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02002308 ASN1_STRING *value;
2309
2310 value = X509_NAME_ENTRY_get_data(entry);
2311 if (ASN1_STRING_to_UTF8((unsigned char **)&str, value) >= 0) {
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02002312 order = ssl_sock_add_cert_sni(ctx, s, str, order);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002313 OPENSSL_free(str);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002314 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02002315 }
2316 }
2317
2318 ret = 0; /* the caller must not free the SSL_CTX argument anymore */
2319 if (!SSL_CTX_use_certificate(ctx, x))
2320 goto end;
2321
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02002322#ifdef SSL_CTX_clear_extra_chain_certs
2323 SSL_CTX_clear_extra_chain_certs(ctx);
2324#else
Emeric Brunfc0421f2012-09-07 17:30:07 +02002325 if (ctx->extra_certs != NULL) {
2326 sk_X509_pop_free(ctx->extra_certs, X509_free);
2327 ctx->extra_certs = NULL;
2328 }
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02002329#endif
Emeric Brunfc0421f2012-09-07 17:30:07 +02002330
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02002331 while ((ca = PEM_read_bio_X509(in, NULL, passwd_cb, passwd_cb_userdata))) {
Emeric Brunfc0421f2012-09-07 17:30:07 +02002332 if (!SSL_CTX_add_extra_chain_cert(ctx, ca)) {
2333 X509_free(ca);
2334 goto end;
2335 }
2336 }
2337
2338 err = ERR_get_error();
2339 if (!err || (ERR_GET_LIB(err) == ERR_LIB_PEM && ERR_GET_REASON(err) == PEM_R_NO_START_LINE)) {
2340 /* we successfully reached the last cert in the file */
2341 ret = 1;
2342 }
2343 ERR_clear_error();
2344
2345end:
2346 if (x)
2347 X509_free(x);
2348
2349 if (in)
2350 BIO_free(in);
2351
2352 return ret;
2353}
2354
Willy Tarreau03209342016-12-22 17:08:28 +01002355static int ssl_sock_load_cert_file(const char *path, struct bind_conf *bind_conf, char **sni_filter, int fcount, char **err)
Emeric Brunfc0421f2012-09-07 17:30:07 +02002356{
2357 int ret;
2358 SSL_CTX *ctx;
2359
2360 ctx = SSL_CTX_new(SSLv23_server_method());
2361 if (!ctx) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02002362 memprintf(err, "%sunable to allocate SSL context for cert '%s'.\n",
2363 err && *err ? *err : "", path);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002364 return 1;
2365 }
2366
2367 if (SSL_CTX_use_PrivateKey_file(ctx, path, SSL_FILETYPE_PEM) <= 0) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02002368 memprintf(err, "%sunable to load SSL private key from PEM file '%s'.\n",
2369 err && *err ? *err : "", path);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002370 SSL_CTX_free(ctx);
2371 return 1;
2372 }
2373
Emeric Brun50bcecc2013-04-22 13:05:23 +02002374 ret = ssl_sock_load_cert_chain_file(ctx, path, bind_conf, sni_filter, fcount);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002375 if (ret <= 0) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02002376 memprintf(err, "%sunable to load SSL certificate from PEM file '%s'.\n",
2377 err && *err ? *err : "", path);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002378 if (ret < 0) /* serious error, must do that ourselves */
2379 SSL_CTX_free(ctx);
2380 return 1;
2381 }
Emeric Brun61694ab2012-10-26 13:35:33 +02002382
2383 if (SSL_CTX_check_private_key(ctx) <= 0) {
2384 memprintf(err, "%sinconsistencies between private key and certificate loaded from PEM file '%s'.\n",
2385 err && *err ? *err : "", path);
2386 return 1;
2387 }
2388
Emeric Brunfc0421f2012-09-07 17:30:07 +02002389 /* we must not free the SSL_CTX anymore below, since it's already in
2390 * the tree, so it will be discovered and cleaned in time.
2391 */
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02002392#ifndef OPENSSL_NO_DH
Remi Gacogne4f902b82015-05-28 16:23:00 +02002393 /* store a NULL pointer to indicate we have not yet loaded
2394 a custom DH param file */
2395 if (ssl_dh_ptr_index >= 0) {
2396 SSL_CTX_set_ex_data(ctx, ssl_dh_ptr_index, NULL);
2397 }
2398
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02002399 ret = ssl_sock_load_dh_params(ctx, path);
2400 if (ret < 0) {
2401 if (err)
2402 memprintf(err, "%sunable to load DH parameters from file '%s'.\n",
2403 *err ? *err : "", path);
2404 return 1;
2405 }
2406#endif
2407
Lukas Tribuse4e30f72014-12-09 16:32:51 +01002408#if (defined SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB && !defined OPENSSL_NO_OCSP)
Emeric Brun4147b2e2014-06-16 18:36:30 +02002409 ret = ssl_sock_load_ocsp(ctx, path);
2410 if (ret < 0) {
2411 if (err)
2412 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",
2413 *err ? *err : "", path);
2414 return 1;
2415 }
2416#endif
2417
Daniel Jakots54ffb912015-11-06 20:02:41 +01002418#if (OPENSSL_VERSION_NUMBER >= 0x1000200fL && !defined OPENSSL_NO_TLSEXT && !defined OPENSSL_IS_BORINGSSL && !defined LIBRESSL_VERSION_NUMBER)
Janusz Dziemidowicz2c701b52015-03-07 23:03:59 +01002419 if (sctl_ex_index >= 0) {
2420 ret = ssl_sock_load_sctl(ctx, path);
2421 if (ret < 0) {
2422 if (err)
2423 memprintf(err, "%s '%s.sctl' is present but cannot be read or parsed'.\n",
2424 *err ? *err : "", path);
2425 return 1;
2426 }
2427 }
2428#endif
2429
Emeric Brunfc0421f2012-09-07 17:30:07 +02002430#ifndef SSL_CTRL_SET_TLSEXT_HOSTNAME
Willy Tarreau2a65ff02012-09-13 17:54:29 +02002431 if (bind_conf->default_ctx) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02002432 memprintf(err, "%sthis version of openssl cannot load multiple SSL certificates.\n",
2433 err && *err ? *err : "");
Emeric Brunfc0421f2012-09-07 17:30:07 +02002434 return 1;
2435 }
2436#endif
Willy Tarreau2a65ff02012-09-13 17:54:29 +02002437 if (!bind_conf->default_ctx)
2438 bind_conf->default_ctx = ctx;
Emeric Brunfc0421f2012-09-07 17:30:07 +02002439
2440 return 0;
2441}
2442
Willy Tarreau03209342016-12-22 17:08:28 +01002443int ssl_sock_load_cert(char *path, struct bind_conf *bind_conf, char **err)
Emeric Brunfc0421f2012-09-07 17:30:07 +02002444{
Cyril Bonté3180f7b2015-01-25 00:16:08 +01002445 struct dirent **de_list;
2446 int i, n;
Emeric Brunfc0421f2012-09-07 17:30:07 +02002447 DIR *dir;
2448 struct stat buf;
Willy Tarreauee2663b2012-12-06 11:36:59 +01002449 char *end;
2450 char fp[MAXPATHLEN+1];
Emeric Brunfc0421f2012-09-07 17:30:07 +02002451 int cfgerr = 0;
yanbzhu63ea8462015-12-09 13:35:14 -05002452#if OPENSSL_VERSION_NUMBER >= 0x1000200fL
2453 int is_bundle;
2454 int j;
2455#endif
Emeric Brunfc0421f2012-09-07 17:30:07 +02002456
yanbzhu08ce6ab2015-12-02 13:01:29 -05002457 if (stat(path, &buf) == 0) {
2458 dir = opendir(path);
2459 if (!dir)
Willy Tarreau03209342016-12-22 17:08:28 +01002460 return ssl_sock_load_cert_file(path, bind_conf, NULL, 0, err);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002461
yanbzhu08ce6ab2015-12-02 13:01:29 -05002462 /* strip trailing slashes, including first one */
2463 for (end = path + strlen(path) - 1; end >= path && *end == '/'; end--)
2464 *end = 0;
Emeric Brunfc0421f2012-09-07 17:30:07 +02002465
yanbzhu08ce6ab2015-12-02 13:01:29 -05002466 n = scandir(path, &de_list, 0, alphasort);
2467 if (n < 0) {
2468 memprintf(err, "%sunable to scan directory '%s' : %s.\n",
2469 err && *err ? *err : "", path, strerror(errno));
2470 cfgerr++;
2471 }
2472 else {
2473 for (i = 0; i < n; i++) {
2474 struct dirent *de = de_list[i];
Emeric Brun2aab7222014-06-18 18:15:09 +02002475
yanbzhu08ce6ab2015-12-02 13:01:29 -05002476 end = strrchr(de->d_name, '.');
2477 if (end && (!strcmp(end, ".issuer") || !strcmp(end, ".ocsp") || !strcmp(end, ".sctl")))
2478 goto ignore_entry;
Cyril Bonté3180f7b2015-01-25 00:16:08 +01002479
yanbzhu08ce6ab2015-12-02 13:01:29 -05002480 snprintf(fp, sizeof(fp), "%s/%s", path, de->d_name);
2481 if (stat(fp, &buf) != 0) {
2482 memprintf(err, "%sunable to stat SSL certificate from file '%s' : %s.\n",
2483 err && *err ? *err : "", fp, strerror(errno));
2484 cfgerr++;
2485 goto ignore_entry;
2486 }
2487 if (!S_ISREG(buf.st_mode))
2488 goto ignore_entry;
yanbzhu63ea8462015-12-09 13:35:14 -05002489
2490#if OPENSSL_VERSION_NUMBER >= 0x1000200fL
2491 is_bundle = 0;
2492 /* Check if current entry in directory is part of a multi-cert bundle */
2493
2494 if (end) {
2495 for (j = 0; j < SSL_SOCK_NUM_KEYTYPES; j++) {
2496 if (!strcmp(end + 1, SSL_SOCK_KEYTYPE_NAMES[j])) {
2497 is_bundle = 1;
2498 break;
2499 }
2500 }
2501
2502 if (is_bundle) {
2503 char dp[MAXPATHLEN+1] = {0}; /* this will be the filename w/o the keytype */
2504 int dp_len;
2505
2506 dp_len = end - de->d_name;
2507 snprintf(dp, dp_len + 1, "%s", de->d_name);
2508
2509 /* increment i and free de until we get to a non-bundle cert
2510 * Note here that we look at de_list[i + 1] before freeing de
2511 * this is important since ignore_entry will free de
2512 */
2513 while (i + 1 < n && !strncmp(de_list[i + 1]->d_name, dp, dp_len)) {
2514 free(de);
2515 i++;
2516 de = de_list[i];
2517 }
2518
2519 snprintf(fp, sizeof(fp), "%s/%s", path, dp);
Willy Tarreau03209342016-12-22 17:08:28 +01002520 ssl_sock_load_multi_cert(fp, bind_conf, NULL, 0, err);
yanbzhu63ea8462015-12-09 13:35:14 -05002521
2522 /* Successfully processed the bundle */
2523 goto ignore_entry;
2524 }
2525 }
2526
2527#endif
Willy Tarreau03209342016-12-22 17:08:28 +01002528 cfgerr += ssl_sock_load_cert_file(fp, bind_conf, NULL, 0, err);
yanbzhu08ce6ab2015-12-02 13:01:29 -05002529ignore_entry:
2530 free(de);
Cyril Bonté3180f7b2015-01-25 00:16:08 +01002531 }
yanbzhu08ce6ab2015-12-02 13:01:29 -05002532 free(de_list);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002533 }
yanbzhu08ce6ab2015-12-02 13:01:29 -05002534 closedir(dir);
2535 return cfgerr;
Emeric Brunfc0421f2012-09-07 17:30:07 +02002536 }
yanbzhu08ce6ab2015-12-02 13:01:29 -05002537
Willy Tarreau03209342016-12-22 17:08:28 +01002538 cfgerr = ssl_sock_load_multi_cert(path, bind_conf, NULL, 0, err);
yanbzhu08ce6ab2015-12-02 13:01:29 -05002539
Emeric Brunfc0421f2012-09-07 17:30:07 +02002540 return cfgerr;
2541}
2542
Thierry Fournier383085f2013-01-24 14:15:43 +01002543/* Make sure openssl opens /dev/urandom before the chroot. The work is only
2544 * done once. Zero is returned if the operation fails. No error is returned
2545 * if the random is said as not implemented, because we expect that openssl
2546 * will use another method once needed.
2547 */
2548static int ssl_initialize_random()
2549{
2550 unsigned char random;
2551 static int random_initialized = 0;
2552
2553 if (!random_initialized && RAND_bytes(&random, 1) != 0)
2554 random_initialized = 1;
2555
2556 return random_initialized;
2557}
2558
Willy Tarreau03209342016-12-22 17:08:28 +01002559int ssl_sock_load_cert_list_file(char *file, struct bind_conf *bind_conf, char **err)
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002560{
Emmanuel Hocdet5e0e6e42016-05-13 11:18:50 +02002561 char thisline[LINESIZE*CRTLIST_FACTOR];
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002562 FILE *f;
yanbzhu1b04e5b2015-12-02 13:54:14 -05002563 struct stat buf;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002564 int linenum = 0;
2565 int cfgerr = 0;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002566
Willy Tarreauad1731d2013-04-02 17:35:58 +02002567 if ((f = fopen(file, "r")) == NULL) {
2568 memprintf(err, "cannot open file '%s' : %s", file, strerror(errno));
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002569 return 1;
Willy Tarreauad1731d2013-04-02 17:35:58 +02002570 }
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002571
2572 while (fgets(thisline, sizeof(thisline), f) != NULL) {
2573 int arg;
Emeric Brun50bcecc2013-04-22 13:05:23 +02002574 int newarg;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002575 char *end;
Emmanuel Hocdet5e0e6e42016-05-13 11:18:50 +02002576 char *args[MAX_LINE_ARGS*CRTLIST_FACTOR + 1];
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002577 char *line = thisline;
2578
2579 linenum++;
2580 end = line + strlen(line);
2581 if (end-line == sizeof(thisline)-1 && *(end-1) != '\n') {
2582 /* Check if we reached the limit and the last char is not \n.
2583 * Watch out for the last line without the terminating '\n'!
2584 */
Willy Tarreauad1731d2013-04-02 17:35:58 +02002585 memprintf(err, "line %d too long in file '%s', limit is %d characters",
2586 linenum, file, (int)sizeof(thisline)-1);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002587 cfgerr = 1;
Willy Tarreauad1731d2013-04-02 17:35:58 +02002588 break;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002589 }
2590
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002591 arg = 0;
Emeric Brun50bcecc2013-04-22 13:05:23 +02002592 newarg = 1;
2593 while (*line) {
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002594 if (*line == '#' || *line == '\n' || *line == '\r') {
2595 /* end of string, end of loop */
2596 *line = 0;
2597 break;
2598 }
2599 else if (isspace(*line)) {
Emeric Brun50bcecc2013-04-22 13:05:23 +02002600 newarg = 1;
2601 *line = 0;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002602 }
Emeric Brun50bcecc2013-04-22 13:05:23 +02002603 else if (newarg) {
Emmanuel Hocdet5e0e6e42016-05-13 11:18:50 +02002604 if (arg == MAX_LINE_ARGS*CRTLIST_FACTOR) {
Emeric Brun50bcecc2013-04-22 13:05:23 +02002605 memprintf(err, "too many args on line %d in file '%s'.",
2606 linenum, file);
2607 cfgerr = 1;
2608 break;
2609 }
2610 newarg = 0;
2611 args[arg++] = line;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002612 }
Emeric Brun50bcecc2013-04-22 13:05:23 +02002613 line++;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002614 }
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02002615 if (cfgerr)
2616 break;
Willy Tarreauad1731d2013-04-02 17:35:58 +02002617
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002618 /* empty line */
Emeric Brun50bcecc2013-04-22 13:05:23 +02002619 if (!arg)
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002620 continue;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002621
yanbzhu1b04e5b2015-12-02 13:54:14 -05002622 if (stat(args[0], &buf) == 0) {
Willy Tarreau03209342016-12-22 17:08:28 +01002623 cfgerr = ssl_sock_load_cert_file(args[0], bind_conf, &args[1], arg-1, err);
yanbzhu1b04e5b2015-12-02 13:54:14 -05002624 } else {
Willy Tarreau03209342016-12-22 17:08:28 +01002625 cfgerr = ssl_sock_load_multi_cert(args[0], bind_conf, &args[1], arg-1, err);
yanbzhu1b04e5b2015-12-02 13:54:14 -05002626 }
2627
Willy Tarreauad1731d2013-04-02 17:35:58 +02002628 if (cfgerr) {
2629 memprintf(err, "error processing line %d in file '%s' : %s", linenum, file, *err);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002630 break;
Willy Tarreauad1731d2013-04-02 17:35:58 +02002631 }
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002632 }
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002633 fclose(f);
2634 return cfgerr;
2635}
2636
Emeric Brunfc0421f2012-09-07 17:30:07 +02002637#ifndef SSL_OP_CIPHER_SERVER_PREFERENCE /* needs OpenSSL >= 0.9.7 */
2638#define SSL_OP_CIPHER_SERVER_PREFERENCE 0
2639#endif
2640
2641#ifndef SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION /* needs OpenSSL >= 0.9.7 */
2642#define SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION 0
Willy Tarreau7d588ee2012-11-26 18:47:31 +01002643#define SSL_renegotiate_pending(arg) 0
Emeric Brunfc0421f2012-09-07 17:30:07 +02002644#endif
Emeric Brun2b58d042012-09-20 17:10:03 +02002645#ifndef SSL_OP_SINGLE_ECDH_USE /* needs OpenSSL >= 0.9.8 */
2646#define SSL_OP_SINGLE_ECDH_USE 0
2647#endif
Emeric Brun2d0c4822012-10-02 13:45:20 +02002648#ifndef SSL_OP_NO_TICKET /* needs OpenSSL >= 0.9.8 */
2649#define SSL_OP_NO_TICKET 0
2650#endif
Emeric Brunfc0421f2012-09-07 17:30:07 +02002651#ifndef SSL_OP_NO_COMPRESSION /* needs OpenSSL >= 0.9.9 */
2652#define SSL_OP_NO_COMPRESSION 0
2653#endif
Emeric Brunc0ff4922012-09-28 19:37:02 +02002654#ifndef SSL_OP_NO_TLSv1_1 /* needs OpenSSL >= 1.0.1 */
2655#define SSL_OP_NO_TLSv1_1 0
2656#endif
2657#ifndef SSL_OP_NO_TLSv1_2 /* needs OpenSSL >= 1.0.1 */
2658#define SSL_OP_NO_TLSv1_2 0
2659#endif
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02002660#ifndef SSL_OP_SINGLE_DH_USE /* needs OpenSSL >= 0.9.6 */
2661#define SSL_OP_SINGLE_DH_USE 0
2662#endif
Emeric Brun2b58d042012-09-20 17:10:03 +02002663#ifndef SSL_OP_SINGLE_ECDH_USE /* needs OpenSSL >= 1.0.0 */
2664#define SSL_OP_SINGLE_ECDH_USE 0
2665#endif
Emeric Brunfc0421f2012-09-07 17:30:07 +02002666#ifndef SSL_MODE_RELEASE_BUFFERS /* needs OpenSSL >= 1.0.0 */
2667#define SSL_MODE_RELEASE_BUFFERS 0
2668#endif
Willy Tarreau396a1862014-11-13 14:06:52 +01002669#ifndef SSL_MODE_SMALL_BUFFERS /* needs small_records.patch */
2670#define SSL_MODE_SMALL_BUFFERS 0
2671#endif
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002672
Willy Tarreau03209342016-12-22 17:08:28 +01002673int ssl_sock_prepare_ctx(struct bind_conf *bind_conf, SSL_CTX *ctx)
Emeric Brunfc0421f2012-09-07 17:30:07 +02002674{
Willy Tarreau03209342016-12-22 17:08:28 +01002675 struct proxy *curproxy = bind_conf->frontend;
Emeric Brunfc0421f2012-09-07 17:30:07 +02002676 int cfgerr = 0;
Emeric Brun850efd52014-01-29 12:24:34 +01002677 int verify = SSL_VERIFY_NONE;
Remi Gacogneaf5c3da2014-05-19 10:29:58 +02002678 long ssloptions =
Emeric Brunfc0421f2012-09-07 17:30:07 +02002679 SSL_OP_ALL | /* all known workarounds for bugs */
2680 SSL_OP_NO_SSLv2 |
2681 SSL_OP_NO_COMPRESSION |
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02002682 SSL_OP_SINGLE_DH_USE |
Emeric Brun2b58d042012-09-20 17:10:03 +02002683 SSL_OP_SINGLE_ECDH_USE |
Emeric Brun3c4bc6e2012-10-04 18:44:19 +02002684 SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION |
2685 SSL_OP_CIPHER_SERVER_PREFERENCE;
Remi Gacogneaf5c3da2014-05-19 10:29:58 +02002686 long sslmode =
Emeric Brunfc0421f2012-09-07 17:30:07 +02002687 SSL_MODE_ENABLE_PARTIAL_WRITE |
2688 SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER |
Willy Tarreau396a1862014-11-13 14:06:52 +01002689 SSL_MODE_RELEASE_BUFFERS |
2690 SSL_MODE_SMALL_BUFFERS;
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002691 STACK_OF(SSL_CIPHER) * ciphers = NULL;
Willy Tarreaua616ba62014-10-26 06:49:19 +01002692 SSL_CIPHER * cipher = NULL;
Remi Gacognec1eab8c2014-06-12 18:20:11 +02002693 char cipher_description[128];
2694 /* The description of ciphers using an Ephemeral Diffie Hellman key exchange
2695 contains " Kx=DH " or " Kx=DH(". Beware of " Kx=DH/",
2696 which is not ephemeral DH. */
2697 const char dhe_description[] = " Kx=DH ";
2698 const char dhe_export_description[] = " Kx=DH(";
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002699 int idx = 0;
2700 int dhe_found = 0;
Remi Gacogne23d5d372014-10-10 17:04:26 +02002701 SSL *ssl = NULL;
Emeric Brunfc0421f2012-09-07 17:30:07 +02002702
Thierry Fournier383085f2013-01-24 14:15:43 +01002703 /* Make sure openssl opens /dev/urandom before the chroot */
2704 if (!ssl_initialize_random()) {
2705 Alert("OpenSSL random data generator initialization failed.\n");
2706 cfgerr++;
2707 }
2708
Emeric Brun89675492012-10-05 13:48:26 +02002709 if (bind_conf->ssl_options & BC_SSL_O_NO_SSLV3)
Emeric Brunfc0421f2012-09-07 17:30:07 +02002710 ssloptions |= SSL_OP_NO_SSLv3;
Emeric Brun89675492012-10-05 13:48:26 +02002711 if (bind_conf->ssl_options & BC_SSL_O_NO_TLSV10)
Emeric Brunfc0421f2012-09-07 17:30:07 +02002712 ssloptions |= SSL_OP_NO_TLSv1;
Emeric Brun89675492012-10-05 13:48:26 +02002713 if (bind_conf->ssl_options & BC_SSL_O_NO_TLSV11)
Emeric Brunc0ff4922012-09-28 19:37:02 +02002714 ssloptions |= SSL_OP_NO_TLSv1_1;
Emeric Brun89675492012-10-05 13:48:26 +02002715 if (bind_conf->ssl_options & BC_SSL_O_NO_TLSV12)
Emeric Brunc0ff4922012-09-28 19:37:02 +02002716 ssloptions |= SSL_OP_NO_TLSv1_2;
Emeric Brun89675492012-10-05 13:48:26 +02002717 if (bind_conf->ssl_options & BC_SSL_O_NO_TLS_TICKETS)
Emeric Brun2d0c4822012-10-02 13:45:20 +02002718 ssloptions |= SSL_OP_NO_TICKET;
Jérémie Courrèges-Anglas17c3f622015-07-25 16:50:52 -06002719 if (bind_conf->ssl_options & BC_SSL_O_USE_SSLV3) {
2720#ifndef OPENSSL_NO_SSL3
Emeric Brun2cb7ae52012-10-05 14:14:21 +02002721 SSL_CTX_set_ssl_version(ctx, SSLv3_server_method());
Jérémie Courrèges-Anglas17c3f622015-07-25 16:50:52 -06002722#else
2723 Alert("SSLv3 support requested but unavailable.\n");
2724 cfgerr++;
2725#endif
2726 }
Emeric Brun2cb7ae52012-10-05 14:14:21 +02002727 if (bind_conf->ssl_options & BC_SSL_O_USE_TLSV10)
2728 SSL_CTX_set_ssl_version(ctx, TLSv1_server_method());
2729#if SSL_OP_NO_TLSv1_1
2730 if (bind_conf->ssl_options & BC_SSL_O_USE_TLSV11)
2731 SSL_CTX_set_ssl_version(ctx, TLSv1_1_server_method());
2732#endif
2733#if SSL_OP_NO_TLSv1_2
2734 if (bind_conf->ssl_options & BC_SSL_O_USE_TLSV12)
2735 SSL_CTX_set_ssl_version(ctx, TLSv1_2_server_method());
2736#endif
Emeric Brunfc0421f2012-09-07 17:30:07 +02002737
2738 SSL_CTX_set_options(ctx, ssloptions);
2739 SSL_CTX_set_mode(ctx, sslmode);
Emeric Brun850efd52014-01-29 12:24:34 +01002740 switch (bind_conf->verify) {
2741 case SSL_SOCK_VERIFY_NONE:
2742 verify = SSL_VERIFY_NONE;
2743 break;
2744 case SSL_SOCK_VERIFY_OPTIONAL:
2745 verify = SSL_VERIFY_PEER;
2746 break;
2747 case SSL_SOCK_VERIFY_REQUIRED:
2748 verify = SSL_VERIFY_PEER|SSL_VERIFY_FAIL_IF_NO_PEER_CERT;
2749 break;
2750 }
2751 SSL_CTX_set_verify(ctx, verify, ssl_sock_bind_verifycbk);
2752 if (verify & SSL_VERIFY_PEER) {
Emeric Brunfb510ea2012-10-05 12:00:26 +02002753 if (bind_conf->ca_file) {
Emeric Brund94b3fe2012-09-20 18:23:56 +02002754 /* load CAfile to verify */
Emeric Brunfb510ea2012-10-05 12:00:26 +02002755 if (!SSL_CTX_load_verify_locations(ctx, bind_conf->ca_file, NULL)) {
Emeric Brund94b3fe2012-09-20 18:23:56 +02002756 Alert("Proxy '%s': unable to load CA file '%s' for bind '%s' at [%s:%d].\n",
Emeric Brunfb510ea2012-10-05 12:00:26 +02002757 curproxy->id, bind_conf->ca_file, bind_conf->arg, bind_conf->file, bind_conf->line);
Emeric Brund94b3fe2012-09-20 18:23:56 +02002758 cfgerr++;
2759 }
2760 /* set CA names fo client cert request, function returns void */
Emeric Brunfb510ea2012-10-05 12:00:26 +02002761 SSL_CTX_set_client_CA_list(ctx, SSL_load_client_CA_file(bind_conf->ca_file));
Emeric Brund94b3fe2012-09-20 18:23:56 +02002762 }
Emeric Brun850efd52014-01-29 12:24:34 +01002763 else {
2764 Alert("Proxy '%s': verify is enabled but no CA file specified for bind '%s' at [%s:%d].\n",
2765 curproxy->id, bind_conf->arg, bind_conf->file, bind_conf->line);
2766 cfgerr++;
2767 }
Emeric Brun051cdab2012-10-02 19:25:50 +02002768#ifdef X509_V_FLAG_CRL_CHECK
Emeric Brunfb510ea2012-10-05 12:00:26 +02002769 if (bind_conf->crl_file) {
Emeric Brund94b3fe2012-09-20 18:23:56 +02002770 X509_STORE *store = SSL_CTX_get_cert_store(ctx);
2771
Emeric Brunfb510ea2012-10-05 12:00:26 +02002772 if (!store || !X509_STORE_load_locations(store, bind_conf->crl_file, NULL)) {
Emeric Brund94b3fe2012-09-20 18:23:56 +02002773 Alert("Proxy '%s': unable to configure CRL file '%s' for bind '%s' at [%s:%d].\n",
Alexander Rigbofc65af02015-04-07 14:02:16 +02002774 curproxy->id, bind_conf->crl_file, bind_conf->arg, bind_conf->file, bind_conf->line);
Emeric Brund94b3fe2012-09-20 18:23:56 +02002775 cfgerr++;
2776 }
Emeric Brun561e5742012-10-02 15:20:55 +02002777 else {
2778 X509_STORE_set_flags(store, X509_V_FLAG_CRL_CHECK|X509_V_FLAG_CRL_CHECK_ALL);
2779 }
Emeric Brund94b3fe2012-09-20 18:23:56 +02002780 }
Emeric Brun051cdab2012-10-02 19:25:50 +02002781#endif
Emeric Brun644cde02012-12-14 11:21:13 +01002782 ERR_clear_error();
Emeric Brund94b3fe2012-09-20 18:23:56 +02002783 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02002784
Nenad Merdanovic05552d42015-02-27 19:56:49 +01002785#if (defined SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB && TLS_TICKETS_NO > 0)
Nenad Merdanovic146defa2015-05-09 08:46:00 +02002786 if(bind_conf->keys_ref) {
Nenad Merdanovic05552d42015-02-27 19:56:49 +01002787 if (!SSL_CTX_set_tlsext_ticket_key_cb(ctx, ssl_tlsext_ticket_key_cb)) {
2788 Alert("Proxy '%s': unable to set callback for TLS ticket validation for bind '%s' at [%s:%d].\n",
2789 curproxy->id, bind_conf->arg, bind_conf->file, bind_conf->line);
2790 cfgerr++;
2791 }
2792 }
2793#endif
2794
Emeric Brun4f65bff2012-11-16 15:11:00 +01002795 if (global.tune.ssllifetime)
2796 SSL_CTX_set_timeout(ctx, global.tune.ssllifetime);
2797
Emeric Brunfc0421f2012-09-07 17:30:07 +02002798 shared_context_set_cache(ctx);
Willy Tarreau2a65ff02012-09-13 17:54:29 +02002799 if (bind_conf->ciphers &&
2800 !SSL_CTX_set_cipher_list(ctx, bind_conf->ciphers)) {
Emeric Brunfc0421f2012-09-07 17:30:07 +02002801 Alert("Proxy '%s': unable to set SSL cipher list to '%s' for bind '%s' at [%s:%d].\n",
Willy Tarreau2a65ff02012-09-13 17:54:29 +02002802 curproxy->id, bind_conf->ciphers, bind_conf->arg, bind_conf->file, bind_conf->line);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002803 cfgerr++;
2804 }
2805
Remi Gacogne47783ef2015-05-29 15:53:22 +02002806 /* If tune.ssl.default-dh-param has not been set,
2807 neither has ssl-default-dh-file and no static DH
2808 params were in the certificate file. */
Remi Gacogne4f902b82015-05-28 16:23:00 +02002809 if (global.tune.ssl_default_dh_param == 0 &&
Remi Gacogne47783ef2015-05-29 15:53:22 +02002810 global_dh == NULL &&
Remi Gacogne4f902b82015-05-28 16:23:00 +02002811 (ssl_dh_ptr_index == -1 ||
2812 SSL_CTX_get_ex_data(ctx, ssl_dh_ptr_index) == NULL)) {
Lukas Tribus90132722014-08-18 00:56:33 +02002813
Remi Gacogne23d5d372014-10-10 17:04:26 +02002814 ssl = SSL_new(ctx);
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002815
Remi Gacogne23d5d372014-10-10 17:04:26 +02002816 if (ssl) {
2817 ciphers = SSL_get_ciphers(ssl);
2818
2819 if (ciphers) {
2820 for (idx = 0; idx < sk_SSL_CIPHER_num(ciphers); idx++) {
2821 cipher = sk_SSL_CIPHER_value(ciphers, idx);
2822 if (SSL_CIPHER_description(cipher, cipher_description, sizeof (cipher_description)) == cipher_description) {
2823 if (strstr(cipher_description, dhe_description) != NULL ||
2824 strstr(cipher_description, dhe_export_description) != NULL) {
2825 dhe_found = 1;
2826 break;
2827 }
Remi Gacognec1eab8c2014-06-12 18:20:11 +02002828 }
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002829 }
2830 }
Remi Gacogne23d5d372014-10-10 17:04:26 +02002831 SSL_free(ssl);
2832 ssl = NULL;
Lukas Tribus90132722014-08-18 00:56:33 +02002833 }
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002834
Lukas Tribus90132722014-08-18 00:56:33 +02002835 if (dhe_found) {
2836 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 +02002837 }
2838
2839 global.tune.ssl_default_dh_param = 1024;
2840 }
Remi Gacogne8de54152014-07-15 11:36:40 +02002841
2842#ifndef OPENSSL_NO_DH
2843 if (global.tune.ssl_default_dh_param >= 1024) {
2844 if (local_dh_1024 == NULL) {
2845 local_dh_1024 = ssl_get_dh_1024();
2846 }
2847 if (global.tune.ssl_default_dh_param >= 2048) {
2848 if (local_dh_2048 == NULL) {
2849 local_dh_2048 = ssl_get_dh_2048();
2850 }
2851 if (global.tune.ssl_default_dh_param >= 4096) {
2852 if (local_dh_4096 == NULL) {
2853 local_dh_4096 = ssl_get_dh_4096();
2854 }
Remi Gacogne8de54152014-07-15 11:36:40 +02002855 }
2856 }
2857 }
2858#endif /* OPENSSL_NO_DH */
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002859
Emeric Brunfc0421f2012-09-07 17:30:07 +02002860 SSL_CTX_set_info_callback(ctx, ssl_sock_infocbk);
Willy Tarreau5cbe4ef2014-05-08 22:45:11 +02002861#if OPENSSL_VERSION_NUMBER >= 0x00907000L
Emeric Brun29f037d2014-04-25 19:05:36 +02002862 SSL_CTX_set_msg_callback(ctx, ssl_sock_msgcbk);
Willy Tarreau5cbe4ef2014-05-08 22:45:11 +02002863#endif
Emeric Brun29f037d2014-04-25 19:05:36 +02002864
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02002865#ifdef OPENSSL_NPN_NEGOTIATED
2866 if (bind_conf->npn_str)
2867 SSL_CTX_set_next_protos_advertised_cb(ctx, ssl_sock_advertise_npn_protos, bind_conf);
2868#endif
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01002869#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Willy Tarreauab861d32013-04-02 02:30:41 +02002870 if (bind_conf->alpn_str)
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01002871 SSL_CTX_set_alpn_select_cb(ctx, ssl_sock_advertise_alpn_protos, bind_conf);
Willy Tarreauab861d32013-04-02 02:30:41 +02002872#endif
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02002873
Emeric Brunfc0421f2012-09-07 17:30:07 +02002874#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
2875 SSL_CTX_set_tlsext_servername_callback(ctx, ssl_sock_switchctx_cbk);
Willy Tarreau2a65ff02012-09-13 17:54:29 +02002876 SSL_CTX_set_tlsext_servername_arg(ctx, bind_conf);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002877#endif
Emeric Brun2b58d042012-09-20 17:10:03 +02002878#if defined(SSL_CTX_set_tmp_ecdh) && !defined(OPENSSL_NO_ECDH)
Emeric Brun6924ef82013-03-06 14:08:53 +01002879 {
Emeric Brun2b58d042012-09-20 17:10:03 +02002880 int i;
2881 EC_KEY *ecdh;
2882
Emeric Brun6924ef82013-03-06 14:08:53 +01002883 i = OBJ_sn2nid(bind_conf->ecdhe ? bind_conf->ecdhe : ECDHE_DEFAULT_CURVE);
Emeric Brun2b58d042012-09-20 17:10:03 +02002884 if (!i || ((ecdh = EC_KEY_new_by_curve_name(i)) == NULL)) {
2885 Alert("Proxy '%s': unable to set elliptic named curve to '%s' for bind '%s' at [%s:%d].\n",
Emeric Brun6924ef82013-03-06 14:08:53 +01002886 curproxy->id, bind_conf->ecdhe ? bind_conf->ecdhe : ECDHE_DEFAULT_CURVE,
2887 bind_conf->arg, bind_conf->file, bind_conf->line);
Emeric Brun2b58d042012-09-20 17:10:03 +02002888 cfgerr++;
2889 }
2890 else {
2891 SSL_CTX_set_tmp_ecdh(ctx, ecdh);
2892 EC_KEY_free(ecdh);
2893 }
2894 }
2895#endif
2896
Emeric Brunfc0421f2012-09-07 17:30:07 +02002897 return cfgerr;
2898}
2899
Evan Broderbe554312013-06-27 00:05:25 -07002900static int ssl_sock_srv_hostcheck(const char *pattern, const char *hostname)
2901{
2902 const char *pattern_wildcard, *pattern_left_label_end, *hostname_left_label_end;
2903 size_t prefixlen, suffixlen;
2904
2905 /* Trivial case */
2906 if (strcmp(pattern, hostname) == 0)
2907 return 1;
2908
Evan Broderbe554312013-06-27 00:05:25 -07002909 /* The rest of this logic is based on RFC 6125, section 6.4.3
2910 * (http://tools.ietf.org/html/rfc6125#section-6.4.3) */
2911
Emeric Bruna848dae2013-10-08 11:27:28 +02002912 pattern_wildcard = NULL;
2913 pattern_left_label_end = pattern;
2914 while (*pattern_left_label_end != '.') {
2915 switch (*pattern_left_label_end) {
2916 case 0:
2917 /* End of label not found */
2918 return 0;
2919 case '*':
2920 /* If there is more than one wildcards */
2921 if (pattern_wildcard)
2922 return 0;
2923 pattern_wildcard = pattern_left_label_end;
2924 break;
2925 }
2926 pattern_left_label_end++;
2927 }
2928
2929 /* If it's not trivial and there is no wildcard, it can't
2930 * match */
2931 if (!pattern_wildcard)
Evan Broderbe554312013-06-27 00:05:25 -07002932 return 0;
2933
2934 /* Make sure all labels match except the leftmost */
2935 hostname_left_label_end = strchr(hostname, '.');
2936 if (!hostname_left_label_end
2937 || strcmp(pattern_left_label_end, hostname_left_label_end) != 0)
2938 return 0;
2939
2940 /* Make sure the leftmost label of the hostname is long enough
2941 * that the wildcard can match */
Emeric Brun369da852013-10-08 11:39:35 +02002942 if (hostname_left_label_end - hostname < (pattern_left_label_end - pattern) - 1)
Evan Broderbe554312013-06-27 00:05:25 -07002943 return 0;
2944
2945 /* Finally compare the string on either side of the
2946 * wildcard */
2947 prefixlen = pattern_wildcard - pattern;
2948 suffixlen = pattern_left_label_end - (pattern_wildcard + 1);
Emeric Bruna848dae2013-10-08 11:27:28 +02002949 if ((prefixlen && (memcmp(pattern, hostname, prefixlen) != 0))
2950 || (suffixlen && (memcmp(pattern_wildcard + 1, hostname_left_label_end - suffixlen, suffixlen) != 0)))
Evan Broderbe554312013-06-27 00:05:25 -07002951 return 0;
2952
2953 return 1;
2954}
2955
2956static int ssl_sock_srv_verifycbk(int ok, X509_STORE_CTX *ctx)
2957{
2958 SSL *ssl;
2959 struct connection *conn;
2960 char *servername;
2961
2962 int depth;
2963 X509 *cert;
2964 STACK_OF(GENERAL_NAME) *alt_names;
2965 int i;
2966 X509_NAME *cert_subject;
2967 char *str;
2968
2969 if (ok == 0)
2970 return ok;
2971
2972 ssl = X509_STORE_CTX_get_ex_data(ctx, SSL_get_ex_data_X509_STORE_CTX_idx());
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02002973 conn = SSL_get_app_data(ssl);
Evan Broderbe554312013-06-27 00:05:25 -07002974
2975 servername = objt_server(conn->target)->ssl_ctx.verify_host;
2976
2977 /* We only need to verify the CN on the actual server cert,
2978 * not the indirect CAs */
2979 depth = X509_STORE_CTX_get_error_depth(ctx);
2980 if (depth != 0)
2981 return ok;
2982
2983 /* At this point, the cert is *not* OK unless we can find a
2984 * hostname match */
2985 ok = 0;
2986
2987 cert = X509_STORE_CTX_get_current_cert(ctx);
2988 /* It seems like this might happen if verify peer isn't set */
2989 if (!cert)
2990 return ok;
2991
2992 alt_names = X509_get_ext_d2i(cert, NID_subject_alt_name, NULL, NULL);
2993 if (alt_names) {
2994 for (i = 0; !ok && i < sk_GENERAL_NAME_num(alt_names); i++) {
2995 GENERAL_NAME *name = sk_GENERAL_NAME_value(alt_names, i);
2996 if (name->type == GEN_DNS) {
Emeric Bruna33410c2013-09-17 15:47:48 +02002997#if OPENSSL_VERSION_NUMBER < 0x00907000L
2998 if (ASN1_STRING_to_UTF8((unsigned char **)&str, name->d.ia5) >= 0) {
2999#else
Evan Broderbe554312013-06-27 00:05:25 -07003000 if (ASN1_STRING_to_UTF8((unsigned char **)&str, name->d.dNSName) >= 0) {
Emeric Bruna33410c2013-09-17 15:47:48 +02003001#endif
Evan Broderbe554312013-06-27 00:05:25 -07003002 ok = ssl_sock_srv_hostcheck(str, servername);
3003 OPENSSL_free(str);
3004 }
3005 }
3006 }
Emeric Brun4ad50a42013-09-17 15:19:54 +02003007 sk_GENERAL_NAME_pop_free(alt_names, GENERAL_NAME_free);
Evan Broderbe554312013-06-27 00:05:25 -07003008 }
3009
3010 cert_subject = X509_get_subject_name(cert);
3011 i = -1;
3012 while (!ok && (i = X509_NAME_get_index_by_NID(cert_subject, NID_commonName, i)) != -1) {
3013 X509_NAME_ENTRY *entry = X509_NAME_get_entry(cert_subject, i);
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02003014 ASN1_STRING *value;
3015 value = X509_NAME_ENTRY_get_data(entry);
3016 if (ASN1_STRING_to_UTF8((unsigned char **)&str, value) >= 0) {
Evan Broderbe554312013-06-27 00:05:25 -07003017 ok = ssl_sock_srv_hostcheck(str, servername);
3018 OPENSSL_free(str);
3019 }
3020 }
3021
3022 return ok;
3023}
3024
Emeric Brun94324a42012-10-11 14:00:19 +02003025/* prepare ssl context from servers options. Returns an error count */
Willy Tarreau03209342016-12-22 17:08:28 +01003026int ssl_sock_prepare_srv_ctx(struct server *srv)
Emeric Brun94324a42012-10-11 14:00:19 +02003027{
Willy Tarreau03209342016-12-22 17:08:28 +01003028 struct proxy *curproxy = srv->proxy;
Emeric Brun94324a42012-10-11 14:00:19 +02003029 int cfgerr = 0;
Remi Gacogneaf5c3da2014-05-19 10:29:58 +02003030 long options =
Emeric Brun94324a42012-10-11 14:00:19 +02003031 SSL_OP_ALL | /* all known workarounds for bugs */
3032 SSL_OP_NO_SSLv2 |
3033 SSL_OP_NO_COMPRESSION;
Remi Gacogneaf5c3da2014-05-19 10:29:58 +02003034 long mode =
Emeric Brun94324a42012-10-11 14:00:19 +02003035 SSL_MODE_ENABLE_PARTIAL_WRITE |
3036 SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER |
Willy Tarreau396a1862014-11-13 14:06:52 +01003037 SSL_MODE_RELEASE_BUFFERS |
3038 SSL_MODE_SMALL_BUFFERS;
Emeric Brun850efd52014-01-29 12:24:34 +01003039 int verify = SSL_VERIFY_NONE;
Emeric Brun94324a42012-10-11 14:00:19 +02003040
Thierry Fournier383085f2013-01-24 14:15:43 +01003041 /* Make sure openssl opens /dev/urandom before the chroot */
3042 if (!ssl_initialize_random()) {
3043 Alert("OpenSSL random data generator initialization failed.\n");
3044 cfgerr++;
3045 }
3046
Willy Tarreaufce03112015-01-15 21:32:40 +01003047 /* Automatic memory computations need to know we use SSL there */
3048 global.ssl_used_backend = 1;
3049
3050 /* Initiate SSL context for current server */
Emeric Brun94324a42012-10-11 14:00:19 +02003051 srv->ssl_ctx.reused_sess = NULL;
3052 if (srv->use_ssl)
3053 srv->xprt = &ssl_sock;
3054 if (srv->check.use_ssl)
Cyril Bonté9ce13112014-11-15 22:41:27 +01003055 srv->check.xprt = &ssl_sock;
Emeric Brun94324a42012-10-11 14:00:19 +02003056
3057 srv->ssl_ctx.ctx = SSL_CTX_new(SSLv23_client_method());
3058 if (!srv->ssl_ctx.ctx) {
3059 Alert("config : %s '%s', server '%s': unable to allocate ssl context.\n",
3060 proxy_type_str(curproxy), curproxy->id,
3061 srv->id);
3062 cfgerr++;
3063 return cfgerr;
3064 }
Emeric Bruna7aa3092012-10-26 12:58:00 +02003065 if (srv->ssl_ctx.client_crt) {
3066 if (SSL_CTX_use_PrivateKey_file(srv->ssl_ctx.ctx, srv->ssl_ctx.client_crt, SSL_FILETYPE_PEM) <= 0) {
3067 Alert("config : %s '%s', server '%s': unable to load SSL private key from PEM file '%s'.\n",
3068 proxy_type_str(curproxy), curproxy->id,
3069 srv->id, srv->ssl_ctx.client_crt);
3070 cfgerr++;
3071 }
3072 else if (SSL_CTX_use_certificate_chain_file(srv->ssl_ctx.ctx, srv->ssl_ctx.client_crt) <= 0) {
3073 Alert("config : %s '%s', server '%s': unable to load ssl certificate from PEM file '%s'.\n",
3074 proxy_type_str(curproxy), curproxy->id,
3075 srv->id, srv->ssl_ctx.client_crt);
3076 cfgerr++;
3077 }
3078 else if (SSL_CTX_check_private_key(srv->ssl_ctx.ctx) <= 0) {
3079 Alert("config : %s '%s', server '%s': inconsistencies between private key and certificate loaded from PEM file '%s'.\n",
3080 proxy_type_str(curproxy), curproxy->id,
3081 srv->id, srv->ssl_ctx.client_crt);
3082 cfgerr++;
3083 }
3084 }
Emeric Brun94324a42012-10-11 14:00:19 +02003085
3086 if (srv->ssl_ctx.options & SRV_SSL_O_NO_SSLV3)
3087 options |= SSL_OP_NO_SSLv3;
3088 if (srv->ssl_ctx.options & SRV_SSL_O_NO_TLSV10)
3089 options |= SSL_OP_NO_TLSv1;
3090 if (srv->ssl_ctx.options & SRV_SSL_O_NO_TLSV11)
3091 options |= SSL_OP_NO_TLSv1_1;
3092 if (srv->ssl_ctx.options & SRV_SSL_O_NO_TLSV12)
3093 options |= SSL_OP_NO_TLSv1_2;
Emeric Brunf9c5c472012-10-11 15:28:34 +02003094 if (srv->ssl_ctx.options & SRV_SSL_O_NO_TLS_TICKETS)
3095 options |= SSL_OP_NO_TICKET;
Jérémie Courrèges-Anglas17c3f622015-07-25 16:50:52 -06003096 if (srv->ssl_ctx.options & SRV_SSL_O_USE_SSLV3) {
3097#ifndef OPENSSL_NO_SSL3
Emeric Brun94324a42012-10-11 14:00:19 +02003098 SSL_CTX_set_ssl_version(srv->ssl_ctx.ctx, SSLv3_client_method());
Jérémie Courrèges-Anglas17c3f622015-07-25 16:50:52 -06003099#else
Thierry FOURNIERbc965342015-08-26 08:21:26 +02003100 Alert("SSLv3 support requested but unavailable.\n");
Jérémie Courrèges-Anglas17c3f622015-07-25 16:50:52 -06003101 cfgerr++;
3102#endif
3103 }
Emeric Brun94324a42012-10-11 14:00:19 +02003104 if (srv->ssl_ctx.options & SRV_SSL_O_USE_TLSV10)
3105 SSL_CTX_set_ssl_version(srv->ssl_ctx.ctx, TLSv1_client_method());
3106#if SSL_OP_NO_TLSv1_1
3107 if (srv->ssl_ctx.options & SRV_SSL_O_USE_TLSV11)
3108 SSL_CTX_set_ssl_version(srv->ssl_ctx.ctx, TLSv1_1_client_method());
3109#endif
3110#if SSL_OP_NO_TLSv1_2
3111 if (srv->ssl_ctx.options & SRV_SSL_O_USE_TLSV12)
3112 SSL_CTX_set_ssl_version(srv->ssl_ctx.ctx, TLSv1_2_client_method());
3113#endif
3114
3115 SSL_CTX_set_options(srv->ssl_ctx.ctx, options);
3116 SSL_CTX_set_mode(srv->ssl_ctx.ctx, mode);
Emeric Brun850efd52014-01-29 12:24:34 +01003117
3118 if (global.ssl_server_verify == SSL_SERVER_VERIFY_REQUIRED)
3119 verify = SSL_VERIFY_PEER;
3120
3121 switch (srv->ssl_ctx.verify) {
3122 case SSL_SOCK_VERIFY_NONE:
3123 verify = SSL_VERIFY_NONE;
3124 break;
3125 case SSL_SOCK_VERIFY_REQUIRED:
3126 verify = SSL_VERIFY_PEER;
3127 break;
3128 }
Evan Broderbe554312013-06-27 00:05:25 -07003129 SSL_CTX_set_verify(srv->ssl_ctx.ctx,
Emeric Brun850efd52014-01-29 12:24:34 +01003130 verify,
Evan Broderbe554312013-06-27 00:05:25 -07003131 srv->ssl_ctx.verify_host ? ssl_sock_srv_verifycbk : NULL);
Emeric Brun850efd52014-01-29 12:24:34 +01003132 if (verify & SSL_VERIFY_PEER) {
Emeric Brunef42d922012-10-11 16:11:36 +02003133 if (srv->ssl_ctx.ca_file) {
3134 /* load CAfile to verify */
3135 if (!SSL_CTX_load_verify_locations(srv->ssl_ctx.ctx, srv->ssl_ctx.ca_file, NULL)) {
Willy Tarreau07ba08b2014-02-16 19:22:08 +01003136 Alert("Proxy '%s', server '%s' [%s:%d] unable to load CA file '%s'.\n",
Emeric Brunef42d922012-10-11 16:11:36 +02003137 curproxy->id, srv->id,
3138 srv->conf.file, srv->conf.line, srv->ssl_ctx.ca_file);
3139 cfgerr++;
3140 }
3141 }
Emeric Brun850efd52014-01-29 12:24:34 +01003142 else {
3143 if (global.ssl_server_verify == SSL_SERVER_VERIFY_REQUIRED)
Willy Tarreau07ba08b2014-02-16 19:22:08 +01003144 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 +01003145 curproxy->id, srv->id,
3146 srv->conf.file, srv->conf.line);
3147 else
Willy Tarreau07ba08b2014-02-16 19:22:08 +01003148 Alert("Proxy '%s', server '%s' [%s:%d] verify is enabled but no CA file specified.\n",
Emeric Brun850efd52014-01-29 12:24:34 +01003149 curproxy->id, srv->id,
3150 srv->conf.file, srv->conf.line);
3151 cfgerr++;
3152 }
Emeric Brunef42d922012-10-11 16:11:36 +02003153#ifdef X509_V_FLAG_CRL_CHECK
3154 if (srv->ssl_ctx.crl_file) {
3155 X509_STORE *store = SSL_CTX_get_cert_store(srv->ssl_ctx.ctx);
3156
3157 if (!store || !X509_STORE_load_locations(store, srv->ssl_ctx.crl_file, NULL)) {
Willy Tarreau07ba08b2014-02-16 19:22:08 +01003158 Alert("Proxy '%s', server '%s' [%s:%d] unable to configure CRL file '%s'.\n",
Emeric Brunef42d922012-10-11 16:11:36 +02003159 curproxy->id, srv->id,
3160 srv->conf.file, srv->conf.line, srv->ssl_ctx.crl_file);
3161 cfgerr++;
3162 }
3163 else {
3164 X509_STORE_set_flags(store, X509_V_FLAG_CRL_CHECK|X509_V_FLAG_CRL_CHECK_ALL);
3165 }
3166 }
3167#endif
3168 }
3169
Emeric Brun4f65bff2012-11-16 15:11:00 +01003170 if (global.tune.ssllifetime)
3171 SSL_CTX_set_timeout(srv->ssl_ctx.ctx, global.tune.ssllifetime);
3172
Emeric Brun94324a42012-10-11 14:00:19 +02003173 SSL_CTX_set_session_cache_mode(srv->ssl_ctx.ctx, SSL_SESS_CACHE_OFF);
3174 if (srv->ssl_ctx.ciphers &&
3175 !SSL_CTX_set_cipher_list(srv->ssl_ctx.ctx, srv->ssl_ctx.ciphers)) {
3176 Alert("Proxy '%s', server '%s' [%s:%d] : unable to set SSL cipher list to '%s'.\n",
3177 curproxy->id, srv->id,
3178 srv->conf.file, srv->conf.line, srv->ssl_ctx.ciphers);
3179 cfgerr++;
3180 }
3181
3182 return cfgerr;
3183}
3184
Willy Tarreau2a65ff02012-09-13 17:54:29 +02003185/* Walks down the two trees in bind_conf and prepares all certs. The pointer may
Emeric Brunfc0421f2012-09-07 17:30:07 +02003186 * be NULL, in which case nothing is done. Returns the number of errors
3187 * encountered.
3188 */
Willy Tarreau03209342016-12-22 17:08:28 +01003189int ssl_sock_prepare_all_ctx(struct bind_conf *bind_conf)
Emeric Brunfc0421f2012-09-07 17:30:07 +02003190{
3191 struct ebmb_node *node;
3192 struct sni_ctx *sni;
3193 int err = 0;
3194
Willy Tarreau2a65ff02012-09-13 17:54:29 +02003195 if (!bind_conf || !bind_conf->is_ssl)
Emeric Brunfc0421f2012-09-07 17:30:07 +02003196 return 0;
3197
Willy Tarreaufce03112015-01-15 21:32:40 +01003198 /* Automatic memory computations need to know we use SSL there */
3199 global.ssl_used_frontend = 1;
3200
Emeric Brun0bed9942014-10-30 19:25:24 +01003201 if (bind_conf->default_ctx)
Willy Tarreau03209342016-12-22 17:08:28 +01003202 err += ssl_sock_prepare_ctx(bind_conf, bind_conf->default_ctx);
Emeric Brun0bed9942014-10-30 19:25:24 +01003203
Willy Tarreau2a65ff02012-09-13 17:54:29 +02003204 node = ebmb_first(&bind_conf->sni_ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02003205 while (node) {
3206 sni = ebmb_entry(node, struct sni_ctx, name);
Emeric Brun0bed9942014-10-30 19:25:24 +01003207 if (!sni->order && sni->ctx != bind_conf->default_ctx)
3208 /* only initialize the CTX on its first occurrence and
3209 if it is not the default_ctx */
Willy Tarreau03209342016-12-22 17:08:28 +01003210 err += ssl_sock_prepare_ctx(bind_conf, sni->ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02003211 node = ebmb_next(node);
3212 }
3213
Willy Tarreau2a65ff02012-09-13 17:54:29 +02003214 node = ebmb_first(&bind_conf->sni_w_ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02003215 while (node) {
3216 sni = ebmb_entry(node, struct sni_ctx, name);
Emeric Brun0bed9942014-10-30 19:25:24 +01003217 if (!sni->order && sni->ctx != bind_conf->default_ctx)
3218 /* only initialize the CTX on its first occurrence and
3219 if it is not the default_ctx */
Willy Tarreau03209342016-12-22 17:08:28 +01003220 err += ssl_sock_prepare_ctx(bind_conf, sni->ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02003221 node = ebmb_next(node);
3222 }
3223 return err;
3224}
3225
Willy Tarreau55d37912016-12-21 23:38:39 +01003226/* Prepares all the contexts for a bind_conf and allocates the shared SSL
3227 * context if needed. Returns < 0 on error, 0 on success. The warnings and
3228 * alerts are directly emitted since the rest of the stack does it below.
3229 */
3230int ssl_sock_prepare_bind_conf(struct bind_conf *bind_conf)
3231{
3232 struct proxy *px = bind_conf->frontend;
3233 int alloc_ctx;
3234 int err;
3235
3236 if (!bind_conf->is_ssl) {
3237 if (bind_conf->default_ctx) {
3238 Warning("Proxy '%s': A certificate was specified but SSL was not enabled on bind '%s' at [%s:%d] (use 'ssl').\n",
3239 px->id, bind_conf->arg, bind_conf->file, bind_conf->line);
3240 }
3241 return 0;
3242 }
3243 if (!bind_conf->default_ctx) {
3244 Alert("Proxy '%s': no SSL certificate specified for bind '%s' at [%s:%d] (use 'crt').\n",
3245 px->id, bind_conf->arg, bind_conf->file, bind_conf->line);
3246 return -1;
3247 }
3248
3249 alloc_ctx = shared_context_init(global.tune.sslcachesize, (!global.tune.sslprivatecache && (global.nbproc > 1)) ? 1 : 0);
3250 if (alloc_ctx < 0) {
3251 if (alloc_ctx == SHCTX_E_INIT_LOCK)
3252 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");
3253 else
3254 Alert("Unable to allocate SSL session cache.\n");
3255 return -1;
3256 }
3257
3258 err = 0;
3259 /* initialize all certificate contexts */
3260 err += ssl_sock_prepare_all_ctx(bind_conf);
3261
3262 /* initialize CA variables if the certificates generation is enabled */
3263 err += ssl_sock_load_ca(bind_conf);
3264
3265 return -err;
3266}
Christopher Faulet77fe80c2015-07-29 13:02:40 +02003267
3268/* release ssl context allocated for servers. */
3269void ssl_sock_free_srv_ctx(struct server *srv)
3270{
3271 if (srv->ssl_ctx.ctx)
3272 SSL_CTX_free(srv->ssl_ctx.ctx);
3273}
3274
Willy Tarreau2a65ff02012-09-13 17:54:29 +02003275/* Walks down the two trees in bind_conf and frees all the certs. The pointer may
Emeric Brunfc0421f2012-09-07 17:30:07 +02003276 * be NULL, in which case nothing is done. The default_ctx is nullified too.
3277 */
Willy Tarreau2a65ff02012-09-13 17:54:29 +02003278void ssl_sock_free_all_ctx(struct bind_conf *bind_conf)
Emeric Brunfc0421f2012-09-07 17:30:07 +02003279{
3280 struct ebmb_node *node, *back;
3281 struct sni_ctx *sni;
3282
Willy Tarreau2a65ff02012-09-13 17:54:29 +02003283 if (!bind_conf || !bind_conf->is_ssl)
Emeric Brunfc0421f2012-09-07 17:30:07 +02003284 return;
3285
Willy Tarreau2a65ff02012-09-13 17:54:29 +02003286 node = ebmb_first(&bind_conf->sni_ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02003287 while (node) {
3288 sni = ebmb_entry(node, struct sni_ctx, name);
3289 back = ebmb_next(node);
3290 ebmb_delete(node);
3291 if (!sni->order) /* only free the CTX on its first occurrence */
3292 SSL_CTX_free(sni->ctx);
3293 free(sni);
3294 node = back;
3295 }
3296
Willy Tarreau2a65ff02012-09-13 17:54:29 +02003297 node = ebmb_first(&bind_conf->sni_w_ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02003298 while (node) {
3299 sni = ebmb_entry(node, struct sni_ctx, name);
3300 back = ebmb_next(node);
3301 ebmb_delete(node);
3302 if (!sni->order) /* only free the CTX on its first occurrence */
3303 SSL_CTX_free(sni->ctx);
3304 free(sni);
3305 node = back;
3306 }
3307
Willy Tarreau2a65ff02012-09-13 17:54:29 +02003308 bind_conf->default_ctx = NULL;
Emeric Brune1f38db2012-09-03 20:36:47 +02003309}
3310
Christopher Faulet31af49d2015-06-09 17:29:50 +02003311/* Load CA cert file and private key used to generate certificates */
3312int
Willy Tarreau03209342016-12-22 17:08:28 +01003313ssl_sock_load_ca(struct bind_conf *bind_conf)
Christopher Faulet31af49d2015-06-09 17:29:50 +02003314{
Willy Tarreau03209342016-12-22 17:08:28 +01003315 struct proxy *px = bind_conf->frontend;
Christopher Faulet31af49d2015-06-09 17:29:50 +02003316 FILE *fp;
3317 X509 *cacert = NULL;
3318 EVP_PKEY *capkey = NULL;
3319 int err = 0;
3320
3321 if (!bind_conf || !bind_conf->generate_certs)
3322 return err;
3323
Willy Tarreaua84c2672015-10-09 12:10:13 +02003324#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Christopher Fauletd2cab922015-07-28 16:03:47 +02003325 if (global.tune.ssl_ctx_cache)
3326 ssl_ctx_lru_tree = lru64_new(global.tune.ssl_ctx_cache);
3327 ssl_ctx_lru_seed = (unsigned int)time(NULL);
Willy Tarreaua84c2672015-10-09 12:10:13 +02003328#endif
Christopher Fauletd2cab922015-07-28 16:03:47 +02003329
Christopher Faulet31af49d2015-06-09 17:29:50 +02003330 if (!bind_conf->ca_sign_file) {
3331 Alert("Proxy '%s': cannot enable certificate generation, "
3332 "no CA certificate File configured at [%s:%d].\n",
3333 px->id, bind_conf->file, bind_conf->line);
Christopher Faulet31af49d2015-06-09 17:29:50 +02003334 goto load_error;
Christopher Fauletc6f02fb2015-10-09 10:53:31 +02003335 }
Christopher Faulet31af49d2015-06-09 17:29:50 +02003336
3337 /* read in the CA certificate */
3338 if (!(fp = fopen(bind_conf->ca_sign_file, "r"))) {
3339 Alert("Proxy '%s': Failed to read CA certificate file '%s' at [%s:%d].\n",
3340 px->id, bind_conf->ca_sign_file, bind_conf->file, bind_conf->line);
Christopher Faulet31af49d2015-06-09 17:29:50 +02003341 goto load_error;
3342 }
3343 if (!(cacert = PEM_read_X509(fp, NULL, NULL, NULL))) {
3344 Alert("Proxy '%s': Failed to read CA certificate file '%s' at [%s:%d].\n",
3345 px->id, bind_conf->ca_sign_file, bind_conf->file, bind_conf->line);
Christopher Fauletc6f02fb2015-10-09 10:53:31 +02003346 goto read_error;
Christopher Faulet31af49d2015-06-09 17:29:50 +02003347 }
Christopher Fauletc6f02fb2015-10-09 10:53:31 +02003348 rewind(fp);
Christopher Faulet31af49d2015-06-09 17:29:50 +02003349 if (!(capkey = PEM_read_PrivateKey(fp, NULL, NULL, bind_conf->ca_sign_pass))) {
3350 Alert("Proxy '%s': Failed to read CA private key file '%s' at [%s:%d].\n",
3351 px->id, bind_conf->ca_sign_file, bind_conf->file, bind_conf->line);
Christopher Fauletc6f02fb2015-10-09 10:53:31 +02003352 goto read_error;
Christopher Faulet31af49d2015-06-09 17:29:50 +02003353 }
Christopher Faulet31af49d2015-06-09 17:29:50 +02003354
Christopher Fauletc6f02fb2015-10-09 10:53:31 +02003355 fclose (fp);
Christopher Faulet31af49d2015-06-09 17:29:50 +02003356 bind_conf->ca_sign_cert = cacert;
3357 bind_conf->ca_sign_pkey = capkey;
3358 return err;
3359
Christopher Fauletc6f02fb2015-10-09 10:53:31 +02003360 read_error:
3361 fclose (fp);
Christopher Faulet31af49d2015-06-09 17:29:50 +02003362 if (capkey) EVP_PKEY_free(capkey);
3363 if (cacert) X509_free(cacert);
Christopher Fauletc6f02fb2015-10-09 10:53:31 +02003364 load_error:
3365 bind_conf->generate_certs = 0;
3366 err++;
Christopher Faulet31af49d2015-06-09 17:29:50 +02003367 return err;
3368}
3369
3370/* Release CA cert and private key used to generate certificated */
3371void
3372ssl_sock_free_ca(struct bind_conf *bind_conf)
3373{
3374 if (!bind_conf)
3375 return;
3376
3377 if (bind_conf->ca_sign_pkey)
3378 EVP_PKEY_free(bind_conf->ca_sign_pkey);
3379 if (bind_conf->ca_sign_cert)
3380 X509_free(bind_conf->ca_sign_cert);
Willy Tarreau94ff03a2016-12-22 17:57:46 +01003381 bind_conf->ca_sign_pkey = NULL;
3382 bind_conf->ca_sign_cert = NULL;
Christopher Faulet31af49d2015-06-09 17:29:50 +02003383}
3384
Emeric Brun46591952012-05-18 15:47:34 +02003385/*
3386 * This function is called if SSL * context is not yet allocated. The function
3387 * is designed to be called before any other data-layer operation and sets the
3388 * handshake flag on the connection. It is safe to call it multiple times.
3389 * It returns 0 on success and -1 in error case.
3390 */
3391static int ssl_sock_init(struct connection *conn)
3392{
3393 /* already initialized */
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02003394 if (conn->xprt_ctx)
Emeric Brun46591952012-05-18 15:47:34 +02003395 return 0;
3396
Willy Tarreau3c728722014-01-23 13:50:42 +01003397 if (!conn_ctrl_ready(conn))
Willy Tarreauf79c8172013-10-21 16:30:56 +02003398 return 0;
3399
Willy Tarreau20879a02012-12-03 16:32:10 +01003400 if (global.maxsslconn && sslconns >= global.maxsslconn) {
3401 conn->err_code = CO_ER_SSL_TOO_MANY;
Willy Tarreau403edff2012-09-06 11:58:37 +02003402 return -1;
Willy Tarreau20879a02012-12-03 16:32:10 +01003403 }
Willy Tarreau403edff2012-09-06 11:58:37 +02003404
Emeric Brun46591952012-05-18 15:47:34 +02003405 /* If it is in client mode initiate SSL session
3406 in connect state otherwise accept state */
Willy Tarreau3fdb3662012-11-12 00:42:33 +01003407 if (objt_server(conn->target)) {
Willy Tarreaufba03cd2014-11-13 13:48:58 +01003408 int may_retry = 1;
3409
3410 retry_connect:
Emeric Brun46591952012-05-18 15:47:34 +02003411 /* Alloc a new SSL session ctx */
Willy Tarreau3fdb3662012-11-12 00:42:33 +01003412 conn->xprt_ctx = SSL_new(objt_server(conn->target)->ssl_ctx.ctx);
Willy Tarreau20879a02012-12-03 16:32:10 +01003413 if (!conn->xprt_ctx) {
Willy Tarreaufba03cd2014-11-13 13:48:58 +01003414 if (may_retry--) {
3415 pool_gc2();
3416 goto retry_connect;
3417 }
Willy Tarreau20879a02012-12-03 16:32:10 +01003418 conn->err_code = CO_ER_SSL_NO_MEM;
Emeric Brun46591952012-05-18 15:47:34 +02003419 return -1;
Willy Tarreau20879a02012-12-03 16:32:10 +01003420 }
Emeric Brun46591952012-05-18 15:47:34 +02003421
Emeric Brun46591952012-05-18 15:47:34 +02003422 /* set fd on SSL session context */
Emeric Brun55476152014-11-12 17:35:37 +01003423 if (!SSL_set_fd(conn->xprt_ctx, conn->t.sock.fd)) {
3424 SSL_free(conn->xprt_ctx);
3425 conn->xprt_ctx = NULL;
Willy Tarreaufba03cd2014-11-13 13:48:58 +01003426 if (may_retry--) {
3427 pool_gc2();
3428 goto retry_connect;
3429 }
Emeric Brun55476152014-11-12 17:35:37 +01003430 conn->err_code = CO_ER_SSL_NO_MEM;
3431 return -1;
3432 }
Emeric Brun46591952012-05-18 15:47:34 +02003433
Evan Broderbe554312013-06-27 00:05:25 -07003434 /* set connection pointer */
Emeric Brun55476152014-11-12 17:35:37 +01003435 if (!SSL_set_app_data(conn->xprt_ctx, conn)) {
3436 SSL_free(conn->xprt_ctx);
3437 conn->xprt_ctx = NULL;
Willy Tarreaufba03cd2014-11-13 13:48:58 +01003438 if (may_retry--) {
3439 pool_gc2();
3440 goto retry_connect;
3441 }
Emeric Brun55476152014-11-12 17:35:37 +01003442 conn->err_code = CO_ER_SSL_NO_MEM;
3443 return -1;
3444 }
3445
3446 SSL_set_connect_state(conn->xprt_ctx);
3447 if (objt_server(conn->target)->ssl_ctx.reused_sess) {
3448 if(!SSL_set_session(conn->xprt_ctx, objt_server(conn->target)->ssl_ctx.reused_sess)) {
3449 SSL_SESSION_free(objt_server(conn->target)->ssl_ctx.reused_sess);
3450 objt_server(conn->target)->ssl_ctx.reused_sess = NULL;
3451 }
3452 }
Evan Broderbe554312013-06-27 00:05:25 -07003453
Emeric Brun46591952012-05-18 15:47:34 +02003454 /* leave init state and start handshake */
Willy Tarreau05737472012-09-04 08:03:39 +02003455 conn->flags |= CO_FL_SSL_WAIT_HS | CO_FL_WAIT_L6_CONN;
Willy Tarreau403edff2012-09-06 11:58:37 +02003456
3457 sslconns++;
Willy Tarreau71b734c2014-01-28 15:19:44 +01003458 totalsslconns++;
Emeric Brun46591952012-05-18 15:47:34 +02003459 return 0;
3460 }
Willy Tarreau3fdb3662012-11-12 00:42:33 +01003461 else if (objt_listener(conn->target)) {
Willy Tarreaufba03cd2014-11-13 13:48:58 +01003462 int may_retry = 1;
3463
3464 retry_accept:
Emeric Brun46591952012-05-18 15:47:34 +02003465 /* Alloc a new SSL session ctx */
Willy Tarreau3fdb3662012-11-12 00:42:33 +01003466 conn->xprt_ctx = SSL_new(objt_listener(conn->target)->bind_conf->default_ctx);
Willy Tarreau20879a02012-12-03 16:32:10 +01003467 if (!conn->xprt_ctx) {
Willy Tarreaufba03cd2014-11-13 13:48:58 +01003468 if (may_retry--) {
3469 pool_gc2();
3470 goto retry_accept;
3471 }
Willy Tarreau20879a02012-12-03 16:32:10 +01003472 conn->err_code = CO_ER_SSL_NO_MEM;
Emeric Brun46591952012-05-18 15:47:34 +02003473 return -1;
Willy Tarreau20879a02012-12-03 16:32:10 +01003474 }
Emeric Brun46591952012-05-18 15:47:34 +02003475
Emeric Brun46591952012-05-18 15:47:34 +02003476 /* set fd on SSL session context */
Emeric Brun55476152014-11-12 17:35:37 +01003477 if (!SSL_set_fd(conn->xprt_ctx, conn->t.sock.fd)) {
3478 SSL_free(conn->xprt_ctx);
3479 conn->xprt_ctx = NULL;
Willy Tarreaufba03cd2014-11-13 13:48:58 +01003480 if (may_retry--) {
3481 pool_gc2();
3482 goto retry_accept;
3483 }
Emeric Brun55476152014-11-12 17:35:37 +01003484 conn->err_code = CO_ER_SSL_NO_MEM;
3485 return -1;
3486 }
Emeric Brun46591952012-05-18 15:47:34 +02003487
Emeric Brune1f38db2012-09-03 20:36:47 +02003488 /* set connection pointer */
Emeric Brun55476152014-11-12 17:35:37 +01003489 if (!SSL_set_app_data(conn->xprt_ctx, conn)) {
3490 SSL_free(conn->xprt_ctx);
3491 conn->xprt_ctx = NULL;
Willy Tarreaufba03cd2014-11-13 13:48:58 +01003492 if (may_retry--) {
3493 pool_gc2();
3494 goto retry_accept;
3495 }
Emeric Brun55476152014-11-12 17:35:37 +01003496 conn->err_code = CO_ER_SSL_NO_MEM;
3497 return -1;
3498 }
3499
3500 SSL_set_accept_state(conn->xprt_ctx);
Emeric Brune1f38db2012-09-03 20:36:47 +02003501
Emeric Brun46591952012-05-18 15:47:34 +02003502 /* leave init state and start handshake */
Willy Tarreau05737472012-09-04 08:03:39 +02003503 conn->flags |= CO_FL_SSL_WAIT_HS | CO_FL_WAIT_L6_CONN;
Willy Tarreau403edff2012-09-06 11:58:37 +02003504
3505 sslconns++;
Willy Tarreau71b734c2014-01-28 15:19:44 +01003506 totalsslconns++;
Emeric Brun46591952012-05-18 15:47:34 +02003507 return 0;
3508 }
3509 /* don't know how to handle such a target */
Willy Tarreau20879a02012-12-03 16:32:10 +01003510 conn->err_code = CO_ER_SSL_NO_TARGET;
Emeric Brun46591952012-05-18 15:47:34 +02003511 return -1;
3512}
3513
3514
3515/* This is the callback which is used when an SSL handshake is pending. It
3516 * updates the FD status if it wants some polling before being called again.
3517 * It returns 0 if it fails in a fatal way or needs to poll to go further,
3518 * otherwise it returns non-zero and removes itself from the connection's
3519 * flags (the bit is provided in <flag> by the caller).
3520 */
3521int ssl_sock_handshake(struct connection *conn, unsigned int flag)
3522{
3523 int ret;
3524
Willy Tarreau3c728722014-01-23 13:50:42 +01003525 if (!conn_ctrl_ready(conn))
Willy Tarreauf79c8172013-10-21 16:30:56 +02003526 return 0;
3527
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02003528 if (!conn->xprt_ctx)
Emeric Brun46591952012-05-18 15:47:34 +02003529 goto out_error;
3530
Emeric Brun674b7432012-11-08 19:21:55 +01003531 /* If we use SSL_do_handshake to process a reneg initiated by
3532 * the remote peer, it sometimes returns SSL_ERROR_SSL.
3533 * Usually SSL_write and SSL_read are used and process implicitly
3534 * the reneg handshake.
3535 * Here we use SSL_peek as a workaround for reneg.
3536 */
3537 if ((conn->flags & CO_FL_CONNECTED) && SSL_renegotiate_pending(conn->xprt_ctx)) {
3538 char c;
3539
3540 ret = SSL_peek(conn->xprt_ctx, &c, 1);
3541 if (ret <= 0) {
3542 /* handshake may have not been completed, let's find why */
3543 ret = SSL_get_error(conn->xprt_ctx, ret);
3544 if (ret == SSL_ERROR_WANT_WRITE) {
3545 /* SSL handshake needs to write, L4 connection may not be ready */
3546 __conn_sock_stop_recv(conn);
Willy Tarreaue1f50c42014-01-22 20:02:06 +01003547 __conn_sock_want_send(conn);
3548 fd_cant_send(conn->t.sock.fd);
Emeric Brun674b7432012-11-08 19:21:55 +01003549 return 0;
3550 }
3551 else if (ret == SSL_ERROR_WANT_READ) {
3552 /* handshake may have been completed but we have
3553 * no more data to read.
3554 */
3555 if (!SSL_renegotiate_pending(conn->xprt_ctx)) {
3556 ret = 1;
3557 goto reneg_ok;
3558 }
3559 /* SSL handshake needs to read, L4 connection is ready */
3560 if (conn->flags & CO_FL_WAIT_L4_CONN)
3561 conn->flags &= ~CO_FL_WAIT_L4_CONN;
3562 __conn_sock_stop_send(conn);
Willy Tarreaue1f50c42014-01-22 20:02:06 +01003563 __conn_sock_want_recv(conn);
3564 fd_cant_recv(conn->t.sock.fd);
Emeric Brun674b7432012-11-08 19:21:55 +01003565 return 0;
3566 }
3567 else if (ret == SSL_ERROR_SYSCALL) {
3568 /* if errno is null, then connection was successfully established */
3569 if (!errno && conn->flags & CO_FL_WAIT_L4_CONN)
3570 conn->flags &= ~CO_FL_WAIT_L4_CONN;
Willy Tarreau20879a02012-12-03 16:32:10 +01003571 if (!conn->err_code) {
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02003572 int empty_handshake;
Luca Pizzamiglio578b1692016-12-12 10:56:56 +01003573#if (OPENSSL_VERSION_NUMBER >= 0x1010000fL) && !defined(LIBRESSL_VERSION_NUMBER)
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02003574 OSSL_HANDSHAKE_STATE state = SSL_get_state((SSL *)conn->xprt_ctx);
3575 empty_handshake = state == TLS_ST_BEFORE;
3576#else
3577 empty_handshake = !((SSL *)conn->xprt_ctx)->packet_length;
3578#endif
3579
3580 if (empty_handshake) {
Emeric Brun29f037d2014-04-25 19:05:36 +02003581 if (!errno) {
3582 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
3583 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
3584 else
3585 conn->err_code = CO_ER_SSL_EMPTY;
3586 }
3587 else {
3588 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
3589 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
3590 else
3591 conn->err_code = CO_ER_SSL_ABORT;
3592 }
3593 }
3594 else {
3595 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
3596 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
Willy Tarreau20879a02012-12-03 16:32:10 +01003597 else
Emeric Brun29f037d2014-04-25 19:05:36 +02003598 conn->err_code = CO_ER_SSL_HANDSHAKE;
3599 }
Willy Tarreau20879a02012-12-03 16:32:10 +01003600 }
Emeric Brun674b7432012-11-08 19:21:55 +01003601 goto out_error;
3602 }
3603 else {
3604 /* Fail on all other handshake errors */
3605 /* Note: OpenSSL may leave unread bytes in the socket's
3606 * buffer, causing an RST to be emitted upon close() on
3607 * TCP sockets. We first try to drain possibly pending
3608 * data to avoid this as much as possible.
3609 */
Willy Tarreaud85c4852015-03-13 00:40:28 +01003610 conn_sock_drain(conn);
Willy Tarreau20879a02012-12-03 16:32:10 +01003611 if (!conn->err_code)
Willy Tarreauf51c6982014-04-25 20:02:39 +02003612 conn->err_code = (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT) ?
3613 CO_ER_SSL_KILLED_HB : CO_ER_SSL_HANDSHAKE;
Emeric Brun674b7432012-11-08 19:21:55 +01003614 goto out_error;
3615 }
3616 }
3617 /* read some data: consider handshake completed */
3618 goto reneg_ok;
3619 }
3620
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02003621 ret = SSL_do_handshake(conn->xprt_ctx);
Emeric Brun46591952012-05-18 15:47:34 +02003622 if (ret != 1) {
3623 /* handshake did not complete, let's find why */
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02003624 ret = SSL_get_error(conn->xprt_ctx, ret);
Emeric Brun46591952012-05-18 15:47:34 +02003625
3626 if (ret == SSL_ERROR_WANT_WRITE) {
3627 /* SSL handshake needs to write, L4 connection may not be ready */
3628 __conn_sock_stop_recv(conn);
Willy Tarreaue1f50c42014-01-22 20:02:06 +01003629 __conn_sock_want_send(conn);
3630 fd_cant_send(conn->t.sock.fd);
Emeric Brun46591952012-05-18 15:47:34 +02003631 return 0;
3632 }
3633 else if (ret == SSL_ERROR_WANT_READ) {
3634 /* SSL handshake needs to read, L4 connection is ready */
3635 if (conn->flags & CO_FL_WAIT_L4_CONN)
3636 conn->flags &= ~CO_FL_WAIT_L4_CONN;
3637 __conn_sock_stop_send(conn);
Willy Tarreaue1f50c42014-01-22 20:02:06 +01003638 __conn_sock_want_recv(conn);
3639 fd_cant_recv(conn->t.sock.fd);
Emeric Brun46591952012-05-18 15:47:34 +02003640 return 0;
3641 }
Willy Tarreau89230192012-09-28 20:22:13 +02003642 else if (ret == SSL_ERROR_SYSCALL) {
Luca Pizzamiglio578b1692016-12-12 10:56:56 +01003643#if (OPENSSL_VERSION_NUMBER >= 0x1010000fL) && !defined(LIBRESSL_VERSION_NUMBER)
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02003644 OSSL_HANDSHAKE_STATE state;
3645#endif
3646 int empty_handshake;
Willy Tarreau89230192012-09-28 20:22:13 +02003647 /* if errno is null, then connection was successfully established */
3648 if (!errno && conn->flags & CO_FL_WAIT_L4_CONN)
3649 conn->flags &= ~CO_FL_WAIT_L4_CONN;
Willy Tarreau20879a02012-12-03 16:32:10 +01003650
Luca Pizzamiglio578b1692016-12-12 10:56:56 +01003651#if (OPENSSL_VERSION_NUMBER >= 0x1010000fL) && !defined(LIBRESSL_VERSION_NUMBER)
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02003652 state = SSL_get_state((SSL *)conn->xprt_ctx);
3653 empty_handshake = state == TLS_ST_BEFORE;
3654#else
3655 empty_handshake = !((SSL *)conn->xprt_ctx)->packet_length;
3656#endif
3657 if (empty_handshake) {
Emeric Brun29f037d2014-04-25 19:05:36 +02003658 if (!errno) {
3659 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
3660 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
3661 else
3662 conn->err_code = CO_ER_SSL_EMPTY;
3663 }
3664 else {
3665 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
3666 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
3667 else
3668 conn->err_code = CO_ER_SSL_ABORT;
3669 }
3670 }
3671 else {
3672 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
3673 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
Willy Tarreau20879a02012-12-03 16:32:10 +01003674 else
Emeric Brun29f037d2014-04-25 19:05:36 +02003675 conn->err_code = CO_ER_SSL_HANDSHAKE;
3676 }
Willy Tarreau89230192012-09-28 20:22:13 +02003677 goto out_error;
3678 }
Emeric Brun46591952012-05-18 15:47:34 +02003679 else {
3680 /* Fail on all other handshake errors */
Willy Tarreau566dc552012-10-19 20:52:18 +02003681 /* Note: OpenSSL may leave unread bytes in the socket's
3682 * buffer, causing an RST to be emitted upon close() on
3683 * TCP sockets. We first try to drain possibly pending
3684 * data to avoid this as much as possible.
3685 */
Willy Tarreaud85c4852015-03-13 00:40:28 +01003686 conn_sock_drain(conn);
Willy Tarreau20879a02012-12-03 16:32:10 +01003687 if (!conn->err_code)
Willy Tarreauf51c6982014-04-25 20:02:39 +02003688 conn->err_code = (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT) ?
3689 CO_ER_SSL_KILLED_HB : CO_ER_SSL_HANDSHAKE;
Emeric Brun46591952012-05-18 15:47:34 +02003690 goto out_error;
3691 }
3692 }
3693
Emeric Brun674b7432012-11-08 19:21:55 +01003694reneg_ok:
Emeric Brun46591952012-05-18 15:47:34 +02003695 /* Handshake succeeded */
Willy Tarreau0c9c2722014-05-28 12:28:58 +02003696 if (!SSL_session_reused(conn->xprt_ctx)) {
3697 if (objt_server(conn->target)) {
3698 update_freq_ctr(&global.ssl_be_keys_per_sec, 1);
3699 if (global.ssl_be_keys_per_sec.curr_ctr > global.ssl_be_keys_max)
3700 global.ssl_be_keys_max = global.ssl_be_keys_per_sec.curr_ctr;
3701
Emeric Brun46591952012-05-18 15:47:34 +02003702 /* check if session was reused, if not store current session on server for reuse */
Willy Tarreau30fd4bd2016-12-22 21:54:21 +01003703 if (objt_server(conn->target)->ssl_ctx.reused_sess) {
Willy Tarreau3fdb3662012-11-12 00:42:33 +01003704 SSL_SESSION_free(objt_server(conn->target)->ssl_ctx.reused_sess);
Willy Tarreau30fd4bd2016-12-22 21:54:21 +01003705 objt_server(conn->target)->ssl_ctx.reused_sess = NULL;
3706 }
Emeric Brun46591952012-05-18 15:47:34 +02003707
Willy Tarreau2a3fb1c2015-02-05 16:47:07 +01003708 if (!(objt_server(conn->target)->ssl_ctx.options & SRV_SSL_O_NO_REUSE))
3709 objt_server(conn->target)->ssl_ctx.reused_sess = SSL_get1_session(conn->xprt_ctx);
Emeric Brun46591952012-05-18 15:47:34 +02003710 }
Willy Tarreau0c9c2722014-05-28 12:28:58 +02003711 else {
3712 update_freq_ctr(&global.ssl_fe_keys_per_sec, 1);
3713 if (global.ssl_fe_keys_per_sec.curr_ctr > global.ssl_fe_keys_max)
3714 global.ssl_fe_keys_max = global.ssl_fe_keys_per_sec.curr_ctr;
3715 }
Emeric Brun46591952012-05-18 15:47:34 +02003716 }
3717
3718 /* The connection is now established at both layers, it's time to leave */
3719 conn->flags &= ~(flag | CO_FL_WAIT_L4_CONN | CO_FL_WAIT_L6_CONN);
3720 return 1;
3721
3722 out_error:
Emeric Brun644cde02012-12-14 11:21:13 +01003723 /* Clear openssl global errors stack */
Thierry FOURNIER / OZON.IO8b068c22016-10-10 11:59:50 +02003724 ssl_sock_dump_errors(conn);
Emeric Brun644cde02012-12-14 11:21:13 +01003725 ERR_clear_error();
3726
Emeric Brun9fa89732012-10-04 17:09:56 +02003727 /* free resumed session if exists */
Willy Tarreau3fdb3662012-11-12 00:42:33 +01003728 if (objt_server(conn->target) && objt_server(conn->target)->ssl_ctx.reused_sess) {
3729 SSL_SESSION_free(objt_server(conn->target)->ssl_ctx.reused_sess);
3730 objt_server(conn->target)->ssl_ctx.reused_sess = NULL;
Emeric Brun9fa89732012-10-04 17:09:56 +02003731 }
3732
Emeric Brun46591952012-05-18 15:47:34 +02003733 /* Fail on all other handshake errors */
3734 conn->flags |= CO_FL_ERROR;
Willy Tarreau20879a02012-12-03 16:32:10 +01003735 if (!conn->err_code)
3736 conn->err_code = CO_ER_SSL_HANDSHAKE;
Emeric Brun46591952012-05-18 15:47:34 +02003737 return 0;
3738}
3739
3740/* Receive up to <count> bytes from connection <conn>'s socket and store them
Willy Tarreauabf08d92014-01-14 11:31:27 +01003741 * into buffer <buf>. Only one call to recv() is performed, unless the
Emeric Brun46591952012-05-18 15:47:34 +02003742 * buffer wraps, in which case a second call may be performed. The connection's
3743 * flags are updated with whatever special event is detected (error, read0,
3744 * empty). The caller is responsible for taking care of those events and
3745 * avoiding the call if inappropriate. The function does not call the
3746 * connection's polling update function, so the caller is responsible for this.
3747 */
3748static int ssl_sock_to_buf(struct connection *conn, struct buffer *buf, int count)
3749{
3750 int ret, done = 0;
Willy Tarreauabf08d92014-01-14 11:31:27 +01003751 int try;
Emeric Brun46591952012-05-18 15:47:34 +02003752
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02003753 if (!conn->xprt_ctx)
Emeric Brun46591952012-05-18 15:47:34 +02003754 goto out_error;
3755
3756 if (conn->flags & CO_FL_HANDSHAKE)
3757 /* a handshake was requested */
3758 return 0;
3759
Willy Tarreauabf08d92014-01-14 11:31:27 +01003760 /* let's realign the buffer to optimize I/O */
3761 if (buffer_empty(buf))
Emeric Brun46591952012-05-18 15:47:34 +02003762 buf->p = buf->data;
Emeric Brun46591952012-05-18 15:47:34 +02003763
3764 /* read the largest possible block. For this, we perform only one call
3765 * to recv() unless the buffer wraps and we exactly fill the first hunk,
3766 * in which case we accept to do it once again. A new attempt is made on
3767 * EINTR too.
3768 */
Willy Tarreau00b0fb92014-01-17 11:09:40 +01003769 while (count > 0) {
Willy Tarreauabf08d92014-01-14 11:31:27 +01003770 /* first check if we have some room after p+i */
3771 try = buf->data + buf->size - (buf->p + buf->i);
3772 /* otherwise continue between data and p-o */
3773 if (try <= 0) {
3774 try = buf->p - (buf->data + buf->o);
3775 if (try <= 0)
3776 break;
3777 }
3778 if (try > count)
3779 try = count;
3780
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02003781 ret = SSL_read(conn->xprt_ctx, bi_end(buf), try);
Emeric Brune1f38db2012-09-03 20:36:47 +02003782 if (conn->flags & CO_FL_ERROR) {
3783 /* CO_FL_ERROR may be set by ssl_sock_infocbk */
Emeric Brun644cde02012-12-14 11:21:13 +01003784 goto out_error;
Emeric Brune1f38db2012-09-03 20:36:47 +02003785 }
Emeric Brun46591952012-05-18 15:47:34 +02003786 if (ret > 0) {
3787 buf->i += ret;
3788 done += ret;
3789 if (ret < try)
3790 break;
3791 count -= ret;
Emeric Brun46591952012-05-18 15:47:34 +02003792 }
3793 else if (ret == 0) {
Emeric Brun644cde02012-12-14 11:21:13 +01003794 ret = SSL_get_error(conn->xprt_ctx, ret);
3795 if (ret != SSL_ERROR_ZERO_RETURN) {
Emeric Brun1c646862012-12-14 12:33:41 +01003796 /* error on protocol or underlying transport */
3797 if ((ret != SSL_ERROR_SYSCALL)
3798 || (errno && (errno != EAGAIN)))
3799 conn->flags |= CO_FL_ERROR;
3800
Emeric Brun644cde02012-12-14 11:21:13 +01003801 /* Clear openssl global errors stack */
Thierry FOURNIER / OZON.IO8b068c22016-10-10 11:59:50 +02003802 ssl_sock_dump_errors(conn);
Emeric Brun644cde02012-12-14 11:21:13 +01003803 ERR_clear_error();
3804 }
Emeric Brun46591952012-05-18 15:47:34 +02003805 goto read0;
3806 }
3807 else {
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02003808 ret = SSL_get_error(conn->xprt_ctx, ret);
Emeric Brun46591952012-05-18 15:47:34 +02003809 if (ret == SSL_ERROR_WANT_WRITE) {
Emeric Brun8af8dd12012-11-08 17:56:20 +01003810 /* handshake is running, and it needs to enable write */
Emeric Brun46591952012-05-18 15:47:34 +02003811 conn->flags |= CO_FL_SSL_WAIT_HS;
Emeric Brun8af8dd12012-11-08 17:56:20 +01003812 __conn_sock_want_send(conn);
Emeric Brun46591952012-05-18 15:47:34 +02003813 break;
3814 }
3815 else if (ret == SSL_ERROR_WANT_READ) {
Emeric Brun282a76a2012-11-08 18:02:56 +01003816 if (SSL_renegotiate_pending(conn->xprt_ctx)) {
3817 /* handshake is running, and it may need to re-enable read */
3818 conn->flags |= CO_FL_SSL_WAIT_HS;
3819 __conn_sock_want_recv(conn);
3820 break;
3821 }
Emeric Brun46591952012-05-18 15:47:34 +02003822 /* we need to poll for retry a read later */
Willy Tarreaue1f50c42014-01-22 20:02:06 +01003823 fd_cant_recv(conn->t.sock.fd);
Emeric Brun46591952012-05-18 15:47:34 +02003824 break;
3825 }
3826 /* otherwise it's a real error */
3827 goto out_error;
3828 }
3829 }
3830 return done;
3831
3832 read0:
3833 conn_sock_read0(conn);
3834 return done;
3835 out_error:
Emeric Brun644cde02012-12-14 11:21:13 +01003836 /* Clear openssl global errors stack */
Thierry FOURNIER / OZON.IO8b068c22016-10-10 11:59:50 +02003837 ssl_sock_dump_errors(conn);
Emeric Brun644cde02012-12-14 11:21:13 +01003838 ERR_clear_error();
3839
Emeric Brun46591952012-05-18 15:47:34 +02003840 conn->flags |= CO_FL_ERROR;
3841 return done;
3842}
3843
3844
3845/* Send all pending bytes from buffer <buf> to connection <conn>'s socket.
Willy Tarreau1049b1f2014-02-02 01:51:17 +01003846 * <flags> may contain some CO_SFL_* flags to hint the system about other
3847 * pending data for example, but this flag is ignored at the moment.
Emeric Brun46591952012-05-18 15:47:34 +02003848 * Only one call to send() is performed, unless the buffer wraps, in which case
3849 * a second call may be performed. The connection's flags are updated with
3850 * whatever special event is detected (error, empty). The caller is responsible
3851 * for taking care of those events and avoiding the call if inappropriate. The
3852 * function does not call the connection's polling update function, so the caller
3853 * is responsible for this.
3854 */
3855static int ssl_sock_from_buf(struct connection *conn, struct buffer *buf, int flags)
3856{
3857 int ret, try, done;
3858
3859 done = 0;
3860
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02003861 if (!conn->xprt_ctx)
Emeric Brun46591952012-05-18 15:47:34 +02003862 goto out_error;
3863
3864 if (conn->flags & CO_FL_HANDSHAKE)
3865 /* a handshake was requested */
3866 return 0;
3867
3868 /* send the largest possible block. For this we perform only one call
3869 * to send() unless the buffer wraps and we exactly fill the first hunk,
3870 * in which case we accept to do it once again.
3871 */
3872 while (buf->o) {
Kevin Hestercad82342013-05-30 15:12:41 -07003873 try = bo_contig_data(buf);
Willy Tarreaubfd59462013-02-21 07:46:09 +01003874
Willy Tarreau7bed9452014-02-02 02:00:24 +01003875 if (!(flags & CO_SFL_STREAMER) &&
Willy Tarreau518cedd2014-02-17 15:43:01 +01003876 !(conn->xprt_st & SSL_SOCK_SEND_UNLIMITED) &&
3877 global.tune.ssl_max_record && try > global.tune.ssl_max_record) {
Willy Tarreaubfd59462013-02-21 07:46:09 +01003878 try = global.tune.ssl_max_record;
Willy Tarreau518cedd2014-02-17 15:43:01 +01003879 }
3880 else {
3881 /* we need to keep the information about the fact that
3882 * we're not limiting the upcoming send(), because if it
3883 * fails, we'll have to retry with at least as many data.
3884 */
3885 conn->xprt_st |= SSL_SOCK_SEND_UNLIMITED;
3886 }
Willy Tarreaubfd59462013-02-21 07:46:09 +01003887
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02003888 ret = SSL_write(conn->xprt_ctx, bo_ptr(buf), try);
Willy Tarreau518cedd2014-02-17 15:43:01 +01003889
Emeric Brune1f38db2012-09-03 20:36:47 +02003890 if (conn->flags & CO_FL_ERROR) {
3891 /* CO_FL_ERROR may be set by ssl_sock_infocbk */
Emeric Brun644cde02012-12-14 11:21:13 +01003892 goto out_error;
Emeric Brune1f38db2012-09-03 20:36:47 +02003893 }
Emeric Brun46591952012-05-18 15:47:34 +02003894 if (ret > 0) {
Willy Tarreau518cedd2014-02-17 15:43:01 +01003895 conn->xprt_st &= ~SSL_SOCK_SEND_UNLIMITED;
3896
Emeric Brun46591952012-05-18 15:47:34 +02003897 buf->o -= ret;
3898 done += ret;
3899
Willy Tarreau5fb38032012-12-16 19:39:09 +01003900 if (likely(buffer_empty(buf)))
Emeric Brun46591952012-05-18 15:47:34 +02003901 /* optimize data alignment in the buffer */
3902 buf->p = buf->data;
3903
3904 /* if the system buffer is full, don't insist */
3905 if (ret < try)
3906 break;
3907 }
3908 else {
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02003909 ret = SSL_get_error(conn->xprt_ctx, ret);
Emeric Brun46591952012-05-18 15:47:34 +02003910 if (ret == SSL_ERROR_WANT_WRITE) {
Emeric Brun282a76a2012-11-08 18:02:56 +01003911 if (SSL_renegotiate_pending(conn->xprt_ctx)) {
3912 /* handshake is running, and it may need to re-enable write */
3913 conn->flags |= CO_FL_SSL_WAIT_HS;
3914 __conn_sock_want_send(conn);
3915 break;
3916 }
Emeric Brun46591952012-05-18 15:47:34 +02003917 /* we need to poll to retry a write later */
Willy Tarreaue1f50c42014-01-22 20:02:06 +01003918 fd_cant_send(conn->t.sock.fd);
Emeric Brun46591952012-05-18 15:47:34 +02003919 break;
3920 }
3921 else if (ret == SSL_ERROR_WANT_READ) {
Emeric Brun8af8dd12012-11-08 17:56:20 +01003922 /* handshake is running, and it needs to enable read */
Emeric Brun46591952012-05-18 15:47:34 +02003923 conn->flags |= CO_FL_SSL_WAIT_HS;
Emeric Brun8af8dd12012-11-08 17:56:20 +01003924 __conn_sock_want_recv(conn);
Emeric Brun46591952012-05-18 15:47:34 +02003925 break;
3926 }
3927 goto out_error;
3928 }
3929 }
3930 return done;
3931
3932 out_error:
Emeric Brun644cde02012-12-14 11:21:13 +01003933 /* Clear openssl global errors stack */
Thierry FOURNIER / OZON.IO8b068c22016-10-10 11:59:50 +02003934 ssl_sock_dump_errors(conn);
Emeric Brun644cde02012-12-14 11:21:13 +01003935 ERR_clear_error();
3936
Emeric Brun46591952012-05-18 15:47:34 +02003937 conn->flags |= CO_FL_ERROR;
3938 return done;
3939}
3940
Emeric Brun46591952012-05-18 15:47:34 +02003941static void ssl_sock_close(struct connection *conn) {
3942
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02003943 if (conn->xprt_ctx) {
3944 SSL_free(conn->xprt_ctx);
3945 conn->xprt_ctx = NULL;
Willy Tarreau403edff2012-09-06 11:58:37 +02003946 sslconns--;
Emeric Brun46591952012-05-18 15:47:34 +02003947 }
Emeric Brun46591952012-05-18 15:47:34 +02003948}
3949
3950/* This function tries to perform a clean shutdown on an SSL connection, and in
3951 * any case, flags the connection as reusable if no handshake was in progress.
3952 */
3953static void ssl_sock_shutw(struct connection *conn, int clean)
3954{
3955 if (conn->flags & CO_FL_HANDSHAKE)
3956 return;
3957 /* no handshake was in progress, try a clean ssl shutdown */
Emeric Brun644cde02012-12-14 11:21:13 +01003958 if (clean && (SSL_shutdown(conn->xprt_ctx) <= 0)) {
3959 /* Clear openssl global errors stack */
Thierry FOURNIER / OZON.IO8b068c22016-10-10 11:59:50 +02003960 ssl_sock_dump_errors(conn);
Emeric Brun644cde02012-12-14 11:21:13 +01003961 ERR_clear_error();
3962 }
Emeric Brun46591952012-05-18 15:47:34 +02003963
3964 /* force flag on ssl to keep session in cache regardless shutdown result */
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02003965 SSL_set_shutdown(conn->xprt_ctx, SSL_SENT_SHUTDOWN);
Emeric Brun46591952012-05-18 15:47:34 +02003966}
3967
Willy Tarreauffc3fcd2012-10-12 20:17:54 +02003968/* used for logging, may be changed for a sample fetch later */
3969const char *ssl_sock_get_cipher_name(struct connection *conn)
3970{
3971 if (!conn->xprt && !conn->xprt_ctx)
3972 return NULL;
3973 return SSL_get_cipher_name(conn->xprt_ctx);
3974}
3975
3976/* used for logging, may be changed for a sample fetch later */
3977const char *ssl_sock_get_proto_version(struct connection *conn)
3978{
3979 if (!conn->xprt && !conn->xprt_ctx)
3980 return NULL;
3981 return SSL_get_version(conn->xprt_ctx);
3982}
3983
Willy Tarreau8d598402012-10-22 17:58:39 +02003984/* Extract a serial from a cert, and copy it to a chunk.
3985 * Returns 1 if serial is found and copied, 0 if no serial found and
3986 * -1 if output is not large enough.
3987 */
3988static int
3989ssl_sock_get_serial(X509 *crt, struct chunk *out)
3990{
3991 ASN1_INTEGER *serial;
3992
3993 serial = X509_get_serialNumber(crt);
3994 if (!serial)
3995 return 0;
3996
3997 if (out->size < serial->length)
3998 return -1;
3999
4000 memcpy(out->str, serial->data, serial->length);
4001 out->len = serial->length;
4002 return 1;
4003}
4004
Emeric Brun43e79582014-10-29 19:03:26 +01004005/* Extract a cert to der, and copy it to a chunk.
4006 * Returns 1 if cert is found and copied, 0 on der convertion failure and
4007 * -1 if output is not large enough.
4008 */
4009static int
4010ssl_sock_crt2der(X509 *crt, struct chunk *out)
4011{
4012 int len;
4013 unsigned char *p = (unsigned char *)out->str;;
4014
4015 len =i2d_X509(crt, NULL);
4016 if (len <= 0)
4017 return 1;
4018
4019 if (out->size < len)
4020 return -1;
4021
4022 i2d_X509(crt,&p);
4023 out->len = len;
4024 return 1;
4025}
4026
Emeric Brunce5ad802012-10-22 14:11:22 +02004027
4028/* Copy Date in ASN1_UTCTIME format in struct chunk out.
4029 * Returns 1 if serial is found and copied, 0 if no valid time found
4030 * and -1 if output is not large enough.
4031 */
4032static int
4033ssl_sock_get_time(ASN1_TIME *tm, struct chunk *out)
4034{
4035 if (tm->type == V_ASN1_GENERALIZEDTIME) {
4036 ASN1_GENERALIZEDTIME *gentm = (ASN1_GENERALIZEDTIME *)tm;
4037
4038 if (gentm->length < 12)
4039 return 0;
4040 if (gentm->data[0] != 0x32 || gentm->data[1] != 0x30)
4041 return 0;
4042 if (out->size < gentm->length-2)
4043 return -1;
4044
4045 memcpy(out->str, gentm->data+2, gentm->length-2);
4046 out->len = gentm->length-2;
4047 return 1;
4048 }
4049 else if (tm->type == V_ASN1_UTCTIME) {
4050 ASN1_UTCTIME *utctm = (ASN1_UTCTIME *)tm;
4051
4052 if (utctm->length < 10)
4053 return 0;
4054 if (utctm->data[0] >= 0x35)
4055 return 0;
4056 if (out->size < utctm->length)
4057 return -1;
4058
4059 memcpy(out->str, utctm->data, utctm->length);
4060 out->len = utctm->length;
4061 return 1;
4062 }
4063
4064 return 0;
4065}
4066
Emeric Brun87855892012-10-17 17:39:35 +02004067/* Extract an entry from a X509_NAME and copy its value to an output chunk.
4068 * Returns 1 if entry found, 0 if entry not found, or -1 if output not large enough.
4069 */
4070static int
4071ssl_sock_get_dn_entry(X509_NAME *a, const struct chunk *entry, int pos, struct chunk *out)
4072{
4073 X509_NAME_ENTRY *ne;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004074 ASN1_OBJECT *obj;
4075 ASN1_STRING *data;
4076 const unsigned char *data_ptr;
4077 int data_len;
Emeric Brun87855892012-10-17 17:39:35 +02004078 int i, j, n;
4079 int cur = 0;
4080 const char *s;
4081 char tmp[128];
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004082 int name_count;
4083
4084 name_count = X509_NAME_entry_count(a);
Emeric Brun87855892012-10-17 17:39:35 +02004085
4086 out->len = 0;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004087 for (i = 0; i < name_count; i++) {
Emeric Brun87855892012-10-17 17:39:35 +02004088 if (pos < 0)
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004089 j = (name_count-1) - i;
Emeric Brun87855892012-10-17 17:39:35 +02004090 else
4091 j = i;
4092
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004093 ne = X509_NAME_get_entry(a, j);
4094 obj = X509_NAME_ENTRY_get_object(ne);
4095 data = X509_NAME_ENTRY_get_data(ne);
4096 data_ptr = ASN1_STRING_get0_data(data);
4097 data_len = ASN1_STRING_length(data);
4098 n = OBJ_obj2nid(obj);
Emeric Brun87855892012-10-17 17:39:35 +02004099 if ((n == NID_undef) || ((s = OBJ_nid2sn(n)) == NULL)) {
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004100 i2t_ASN1_OBJECT(tmp, sizeof(tmp), obj);
Emeric Brun87855892012-10-17 17:39:35 +02004101 s = tmp;
4102 }
4103
4104 if (chunk_strcasecmp(entry, s) != 0)
4105 continue;
4106
4107 if (pos < 0)
4108 cur--;
4109 else
4110 cur++;
4111
4112 if (cur != pos)
4113 continue;
4114
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004115 if (data_len > out->size)
Emeric Brun87855892012-10-17 17:39:35 +02004116 return -1;
4117
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004118 memcpy(out->str, data_ptr, data_len);
4119 out->len = data_len;
Emeric Brun87855892012-10-17 17:39:35 +02004120 return 1;
4121 }
4122
4123 return 0;
4124
4125}
4126
4127/* Extract and format full DN from a X509_NAME and copy result into a chunk
4128 * Returns 1 if dn entries exits, 0 if no dn entry found or -1 if output is not large enough.
4129 */
4130static int
4131ssl_sock_get_dn_oneline(X509_NAME *a, struct chunk *out)
4132{
4133 X509_NAME_ENTRY *ne;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004134 ASN1_OBJECT *obj;
4135 ASN1_STRING *data;
4136 const unsigned char *data_ptr;
4137 int data_len;
Emeric Brun87855892012-10-17 17:39:35 +02004138 int i, n, ln;
4139 int l = 0;
4140 const char *s;
4141 char *p;
4142 char tmp[128];
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004143 int name_count;
4144
4145
4146 name_count = X509_NAME_entry_count(a);
Emeric Brun87855892012-10-17 17:39:35 +02004147
4148 out->len = 0;
4149 p = out->str;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004150 for (i = 0; i < name_count; i++) {
4151 ne = X509_NAME_get_entry(a, i);
4152 obj = X509_NAME_ENTRY_get_object(ne);
4153 data = X509_NAME_ENTRY_get_data(ne);
4154 data_ptr = ASN1_STRING_get0_data(data);
4155 data_len = ASN1_STRING_length(data);
4156 n = OBJ_obj2nid(obj);
Emeric Brun87855892012-10-17 17:39:35 +02004157 if ((n == NID_undef) || ((s = OBJ_nid2sn(n)) == NULL)) {
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004158 i2t_ASN1_OBJECT(tmp, sizeof(tmp), obj);
Emeric Brun87855892012-10-17 17:39:35 +02004159 s = tmp;
4160 }
4161 ln = strlen(s);
4162
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004163 l += 1 + ln + 1 + data_len;
Emeric Brun87855892012-10-17 17:39:35 +02004164 if (l > out->size)
4165 return -1;
4166 out->len = l;
4167
4168 *(p++)='/';
4169 memcpy(p, s, ln);
4170 p += ln;
4171 *(p++)='=';
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004172 memcpy(p, data_ptr, data_len);
4173 p += data_len;
Emeric Brun87855892012-10-17 17:39:35 +02004174 }
4175
4176 if (!out->len)
4177 return 0;
4178
4179 return 1;
4180}
4181
David Safb76832014-05-08 23:42:08 -04004182char *ssl_sock_get_version(struct connection *conn)
4183{
4184 if (!ssl_sock_is_ssl(conn))
4185 return NULL;
4186
4187 return (char *)SSL_get_version(conn->xprt_ctx);
4188}
4189
Willy Tarreau63076412015-07-10 11:33:32 +02004190void ssl_sock_set_servername(struct connection *conn, const char *hostname)
4191{
4192#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
4193 if (!ssl_sock_is_ssl(conn))
4194 return;
4195
4196 SSL_set_tlsext_host_name(conn->xprt_ctx, hostname);
4197#endif
4198}
4199
Emeric Brun0abf8362014-06-24 18:26:41 +02004200/* Extract peer certificate's common name into the chunk dest
4201 * Returns
4202 * the len of the extracted common name
4203 * or 0 if no CN found in DN
4204 * or -1 on error case (i.e. no peer certificate)
4205 */
4206int ssl_sock_get_remote_common_name(struct connection *conn, struct chunk *dest)
David Safb76832014-05-08 23:42:08 -04004207{
4208 X509 *crt = NULL;
4209 X509_NAME *name;
David Safb76832014-05-08 23:42:08 -04004210 const char find_cn[] = "CN";
4211 const struct chunk find_cn_chunk = {
4212 .str = (char *)&find_cn,
4213 .len = sizeof(find_cn)-1
4214 };
Emeric Brun0abf8362014-06-24 18:26:41 +02004215 int result = -1;
David Safb76832014-05-08 23:42:08 -04004216
4217 if (!ssl_sock_is_ssl(conn))
Emeric Brun0abf8362014-06-24 18:26:41 +02004218 goto out;
David Safb76832014-05-08 23:42:08 -04004219
4220 /* SSL_get_peer_certificate, it increase X509 * ref count */
4221 crt = SSL_get_peer_certificate(conn->xprt_ctx);
4222 if (!crt)
4223 goto out;
4224
4225 name = X509_get_subject_name(crt);
4226 if (!name)
4227 goto out;
David Safb76832014-05-08 23:42:08 -04004228
Emeric Brun0abf8362014-06-24 18:26:41 +02004229 result = ssl_sock_get_dn_entry(name, &find_cn_chunk, 1, dest);
4230out:
David Safb76832014-05-08 23:42:08 -04004231 if (crt)
4232 X509_free(crt);
4233
4234 return result;
4235}
4236
Dave McCowan328fb582014-07-30 10:39:13 -04004237/* returns 1 if client passed a certificate for this session, 0 if not */
4238int ssl_sock_get_cert_used_sess(struct connection *conn)
4239{
4240 X509 *crt = NULL;
4241
4242 if (!ssl_sock_is_ssl(conn))
4243 return 0;
4244
4245 /* SSL_get_peer_certificate, it increase X509 * ref count */
4246 crt = SSL_get_peer_certificate(conn->xprt_ctx);
4247 if (!crt)
4248 return 0;
4249
4250 X509_free(crt);
4251 return 1;
4252}
4253
4254/* returns 1 if client passed a certificate for this connection, 0 if not */
4255int ssl_sock_get_cert_used_conn(struct connection *conn)
David Safb76832014-05-08 23:42:08 -04004256{
4257 if (!ssl_sock_is_ssl(conn))
4258 return 0;
4259
4260 return SSL_SOCK_ST_FL_VERIFY_DONE & conn->xprt_st ? 1 : 0;
4261}
4262
4263/* returns result from SSL verify */
4264unsigned int ssl_sock_get_verify_result(struct connection *conn)
4265{
4266 if (!ssl_sock_is_ssl(conn))
4267 return (unsigned int)X509_V_ERR_APPLICATION_VERIFICATION;
4268
4269 return (unsigned int)SSL_get_verify_result(conn->xprt_ctx);
4270}
4271
Willy Tarreau7875d092012-09-10 08:20:03 +02004272/***** Below are some sample fetching functions for ACL/patterns *****/
4273
Emeric Brune64aef12012-09-21 13:15:06 +02004274/* boolean, returns true if client cert was present */
4275static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004276smp_fetch_ssl_fc_has_crt(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brune64aef12012-09-21 13:15:06 +02004277{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004278 struct connection *conn;
4279
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004280 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004281 if (!conn || conn->xprt != &ssl_sock)
Emeric Brune64aef12012-09-21 13:15:06 +02004282 return 0;
4283
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004284 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brune64aef12012-09-21 13:15:06 +02004285 smp->flags |= SMP_F_MAY_CHANGE;
4286 return 0;
4287 }
4288
4289 smp->flags = 0;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004290 smp->data.type = SMP_T_BOOL;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004291 smp->data.u.sint = SSL_SOCK_ST_FL_VERIFY_DONE & conn->xprt_st ? 1 : 0;
Emeric Brune64aef12012-09-21 13:15:06 +02004292
4293 return 1;
4294}
4295
Emeric Brun43e79582014-10-29 19:03:26 +01004296/* binary, returns a certificate in a binary chunk (der/raw).
4297 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
4298 * should be use.
4299 */
4300static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004301smp_fetch_ssl_x_der(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun43e79582014-10-29 19:03:26 +01004302{
4303 int cert_peer = (kw[4] == 'c') ? 1 : 0;
4304 X509 *crt = NULL;
4305 int ret = 0;
4306 struct chunk *smp_trash;
4307 struct connection *conn;
4308
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004309 conn = objt_conn(smp->sess->origin);
Emeric Brun43e79582014-10-29 19:03:26 +01004310 if (!conn || conn->xprt != &ssl_sock)
4311 return 0;
4312
4313 if (!(conn->flags & CO_FL_CONNECTED)) {
4314 smp->flags |= SMP_F_MAY_CHANGE;
4315 return 0;
4316 }
4317
4318 if (cert_peer)
4319 crt = SSL_get_peer_certificate(conn->xprt_ctx);
4320 else
4321 crt = SSL_get_certificate(conn->xprt_ctx);
4322
4323 if (!crt)
4324 goto out;
4325
4326 smp_trash = get_trash_chunk();
4327 if (ssl_sock_crt2der(crt, smp_trash) <= 0)
4328 goto out;
4329
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004330 smp->data.u.str = *smp_trash;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004331 smp->data.type = SMP_T_BIN;
Emeric Brun43e79582014-10-29 19:03:26 +01004332 ret = 1;
4333out:
4334 /* SSL_get_peer_certificate, it increase X509 * ref count */
4335 if (cert_peer && crt)
4336 X509_free(crt);
4337 return ret;
4338}
4339
Emeric Brunba841a12014-04-30 17:05:08 +02004340/* binary, returns serial of certificate in a binary chunk.
4341 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
4342 * should be use.
4343 */
Willy Tarreau8d598402012-10-22 17:58:39 +02004344static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004345smp_fetch_ssl_x_serial(const struct arg *args, struct sample *smp, const char *kw, void *private)
Willy Tarreau8d598402012-10-22 17:58:39 +02004346{
Emeric Brunba841a12014-04-30 17:05:08 +02004347 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Willy Tarreau8d598402012-10-22 17:58:39 +02004348 X509 *crt = NULL;
4349 int ret = 0;
4350 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004351 struct connection *conn;
4352
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004353 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004354 if (!conn || conn->xprt != &ssl_sock)
Willy Tarreau8d598402012-10-22 17:58:39 +02004355 return 0;
4356
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004357 if (!(conn->flags & CO_FL_CONNECTED)) {
Willy Tarreau8d598402012-10-22 17:58:39 +02004358 smp->flags |= SMP_F_MAY_CHANGE;
4359 return 0;
4360 }
4361
Emeric Brunba841a12014-04-30 17:05:08 +02004362 if (cert_peer)
4363 crt = SSL_get_peer_certificate(conn->xprt_ctx);
4364 else
4365 crt = SSL_get_certificate(conn->xprt_ctx);
4366
Willy Tarreau8d598402012-10-22 17:58:39 +02004367 if (!crt)
4368 goto out;
4369
Willy Tarreau47ca5452012-12-23 20:22:19 +01004370 smp_trash = get_trash_chunk();
Willy Tarreau8d598402012-10-22 17:58:39 +02004371 if (ssl_sock_get_serial(crt, smp_trash) <= 0)
4372 goto out;
4373
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004374 smp->data.u.str = *smp_trash;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004375 smp->data.type = SMP_T_BIN;
Willy Tarreau8d598402012-10-22 17:58:39 +02004376 ret = 1;
4377out:
Emeric Brunba841a12014-04-30 17:05:08 +02004378 /* SSL_get_peer_certificate, it increase X509 * ref count */
4379 if (cert_peer && crt)
Willy Tarreau8d598402012-10-22 17:58:39 +02004380 X509_free(crt);
4381 return ret;
4382}
Emeric Brune64aef12012-09-21 13:15:06 +02004383
Emeric Brunba841a12014-04-30 17:05:08 +02004384/* binary, returns the client certificate's SHA-1 fingerprint (SHA-1 hash of DER-encoded certificate) in a binary chunk.
4385 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
4386 * should be use.
4387 */
James Votha051b4a2013-05-14 20:37:59 +02004388static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004389smp_fetch_ssl_x_sha1(const struct arg *args, struct sample *smp, const char *kw, void *private)
James Votha051b4a2013-05-14 20:37:59 +02004390{
Emeric Brunba841a12014-04-30 17:05:08 +02004391 int cert_peer = (kw[4] == 'c') ? 1 : 0;
James Votha051b4a2013-05-14 20:37:59 +02004392 X509 *crt = NULL;
4393 const EVP_MD *digest;
4394 int ret = 0;
4395 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004396 struct connection *conn;
James Votha051b4a2013-05-14 20:37:59 +02004397
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004398 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004399 if (!conn || conn->xprt != &ssl_sock)
4400 return 0;
4401
4402 if (!(conn->flags & CO_FL_CONNECTED)) {
James Votha051b4a2013-05-14 20:37:59 +02004403 smp->flags |= SMP_F_MAY_CHANGE;
4404 return 0;
4405 }
4406
Emeric Brunba841a12014-04-30 17:05:08 +02004407 if (cert_peer)
4408 crt = SSL_get_peer_certificate(conn->xprt_ctx);
4409 else
4410 crt = SSL_get_certificate(conn->xprt_ctx);
James Votha051b4a2013-05-14 20:37:59 +02004411 if (!crt)
4412 goto out;
4413
4414 smp_trash = get_trash_chunk();
4415 digest = EVP_sha1();
4416 X509_digest(crt, digest, (unsigned char *)smp_trash->str, (unsigned int *)&smp_trash->len);
4417
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004418 smp->data.u.str = *smp_trash;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004419 smp->data.type = SMP_T_BIN;
James Votha051b4a2013-05-14 20:37:59 +02004420 ret = 1;
4421out:
Emeric Brunba841a12014-04-30 17:05:08 +02004422 /* SSL_get_peer_certificate, it increase X509 * ref count */
4423 if (cert_peer && crt)
James Votha051b4a2013-05-14 20:37:59 +02004424 X509_free(crt);
4425 return ret;
4426}
4427
Emeric Brunba841a12014-04-30 17:05:08 +02004428/* string, returns certificate's notafter date in ASN1_UTCTIME format.
4429 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
4430 * should be use.
4431 */
Emeric Brunce5ad802012-10-22 14:11:22 +02004432static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004433smp_fetch_ssl_x_notafter(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brunce5ad802012-10-22 14:11:22 +02004434{
Emeric Brunba841a12014-04-30 17:05:08 +02004435 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brunce5ad802012-10-22 14:11:22 +02004436 X509 *crt = NULL;
4437 int ret = 0;
4438 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004439 struct connection *conn;
Emeric Brunce5ad802012-10-22 14:11:22 +02004440
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004441 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004442 if (!conn || conn->xprt != &ssl_sock)
4443 return 0;
4444
4445 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunce5ad802012-10-22 14:11:22 +02004446 smp->flags |= SMP_F_MAY_CHANGE;
4447 return 0;
4448 }
4449
Emeric Brunba841a12014-04-30 17:05:08 +02004450 if (cert_peer)
4451 crt = SSL_get_peer_certificate(conn->xprt_ctx);
4452 else
4453 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brunce5ad802012-10-22 14:11:22 +02004454 if (!crt)
4455 goto out;
4456
Willy Tarreau47ca5452012-12-23 20:22:19 +01004457 smp_trash = get_trash_chunk();
Emeric Brunce5ad802012-10-22 14:11:22 +02004458 if (ssl_sock_get_time(X509_get_notAfter(crt), smp_trash) <= 0)
4459 goto out;
4460
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004461 smp->data.u.str = *smp_trash;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004462 smp->data.type = SMP_T_STR;
Emeric Brunce5ad802012-10-22 14:11:22 +02004463 ret = 1;
4464out:
Emeric Brunba841a12014-04-30 17:05:08 +02004465 /* SSL_get_peer_certificate, it increase X509 * ref count */
4466 if (cert_peer && crt)
Emeric Brunce5ad802012-10-22 14:11:22 +02004467 X509_free(crt);
4468 return ret;
4469}
4470
Emeric Brunba841a12014-04-30 17:05:08 +02004471/* string, returns a string of a formatted full dn \C=..\O=..\OU=.. \CN=.. of certificate's issuer
4472 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
4473 * should be use.
4474 */
Emeric Brun87855892012-10-17 17:39:35 +02004475static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004476smp_fetch_ssl_x_i_dn(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun87855892012-10-17 17:39:35 +02004477{
Emeric Brunba841a12014-04-30 17:05:08 +02004478 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brun87855892012-10-17 17:39:35 +02004479 X509 *crt = NULL;
4480 X509_NAME *name;
4481 int ret = 0;
4482 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004483 struct connection *conn;
Emeric Brun87855892012-10-17 17:39:35 +02004484
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004485 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004486 if (!conn || conn->xprt != &ssl_sock)
4487 return 0;
4488
4489 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun87855892012-10-17 17:39:35 +02004490 smp->flags |= SMP_F_MAY_CHANGE;
4491 return 0;
4492 }
4493
Emeric Brunba841a12014-04-30 17:05:08 +02004494 if (cert_peer)
4495 crt = SSL_get_peer_certificate(conn->xprt_ctx);
4496 else
4497 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brun87855892012-10-17 17:39:35 +02004498 if (!crt)
4499 goto out;
4500
4501 name = X509_get_issuer_name(crt);
4502 if (!name)
4503 goto out;
4504
Willy Tarreau47ca5452012-12-23 20:22:19 +01004505 smp_trash = get_trash_chunk();
Emeric Brun87855892012-10-17 17:39:35 +02004506 if (args && args[0].type == ARGT_STR) {
4507 int pos = 1;
4508
4509 if (args[1].type == ARGT_SINT)
4510 pos = args[1].data.sint;
Emeric Brun87855892012-10-17 17:39:35 +02004511
4512 if (ssl_sock_get_dn_entry(name, &args[0].data.str, pos, smp_trash) <= 0)
4513 goto out;
4514 }
4515 else if (ssl_sock_get_dn_oneline(name, smp_trash) <= 0)
4516 goto out;
4517
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004518 smp->data.type = SMP_T_STR;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004519 smp->data.u.str = *smp_trash;
Emeric Brun87855892012-10-17 17:39:35 +02004520 ret = 1;
4521out:
Emeric Brunba841a12014-04-30 17:05:08 +02004522 /* SSL_get_peer_certificate, it increase X509 * ref count */
4523 if (cert_peer && crt)
Emeric Brun87855892012-10-17 17:39:35 +02004524 X509_free(crt);
4525 return ret;
4526}
4527
Emeric Brunba841a12014-04-30 17:05:08 +02004528/* string, returns notbefore date in ASN1_UTCTIME format.
4529 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
4530 * should be use.
4531 */
Emeric Brunce5ad802012-10-22 14:11:22 +02004532static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004533smp_fetch_ssl_x_notbefore(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brunce5ad802012-10-22 14:11:22 +02004534{
Emeric Brunba841a12014-04-30 17:05:08 +02004535 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brunce5ad802012-10-22 14:11:22 +02004536 X509 *crt = NULL;
4537 int ret = 0;
4538 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004539 struct connection *conn;
4540
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004541 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004542 if (!conn || conn->xprt != &ssl_sock)
Emeric Brunce5ad802012-10-22 14:11:22 +02004543 return 0;
4544
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004545 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunce5ad802012-10-22 14:11:22 +02004546 smp->flags |= SMP_F_MAY_CHANGE;
4547 return 0;
4548 }
4549
Emeric Brunba841a12014-04-30 17:05:08 +02004550 if (cert_peer)
4551 crt = SSL_get_peer_certificate(conn->xprt_ctx);
4552 else
4553 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brunce5ad802012-10-22 14:11:22 +02004554 if (!crt)
4555 goto out;
4556
Willy Tarreau47ca5452012-12-23 20:22:19 +01004557 smp_trash = get_trash_chunk();
Emeric Brunce5ad802012-10-22 14:11:22 +02004558 if (ssl_sock_get_time(X509_get_notBefore(crt), smp_trash) <= 0)
4559 goto out;
4560
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004561 smp->data.u.str = *smp_trash;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004562 smp->data.type = SMP_T_STR;
Emeric Brunce5ad802012-10-22 14:11:22 +02004563 ret = 1;
4564out:
Emeric Brunba841a12014-04-30 17:05:08 +02004565 /* SSL_get_peer_certificate, it increase X509 * ref count */
4566 if (cert_peer && crt)
Emeric Brunce5ad802012-10-22 14:11:22 +02004567 X509_free(crt);
4568 return ret;
4569}
4570
Emeric Brunba841a12014-04-30 17:05:08 +02004571/* string, returns a string of a formatted full dn \C=..\O=..\OU=.. \CN=.. of certificate's subject
4572 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
4573 * should be use.
4574 */
Emeric Brun87855892012-10-17 17:39:35 +02004575static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004576smp_fetch_ssl_x_s_dn(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun87855892012-10-17 17:39:35 +02004577{
Emeric Brunba841a12014-04-30 17:05:08 +02004578 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brun87855892012-10-17 17:39:35 +02004579 X509 *crt = NULL;
4580 X509_NAME *name;
4581 int ret = 0;
4582 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004583 struct connection *conn;
Emeric Brun87855892012-10-17 17:39:35 +02004584
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004585 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004586 if (!conn || conn->xprt != &ssl_sock)
4587 return 0;
4588
4589 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun87855892012-10-17 17:39:35 +02004590 smp->flags |= SMP_F_MAY_CHANGE;
4591 return 0;
4592 }
4593
Emeric Brunba841a12014-04-30 17:05:08 +02004594 if (cert_peer)
4595 crt = SSL_get_peer_certificate(conn->xprt_ctx);
4596 else
4597 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brun87855892012-10-17 17:39:35 +02004598 if (!crt)
4599 goto out;
4600
4601 name = X509_get_subject_name(crt);
4602 if (!name)
4603 goto out;
4604
Willy Tarreau47ca5452012-12-23 20:22:19 +01004605 smp_trash = get_trash_chunk();
Emeric Brun87855892012-10-17 17:39:35 +02004606 if (args && args[0].type == ARGT_STR) {
4607 int pos = 1;
4608
4609 if (args[1].type == ARGT_SINT)
4610 pos = args[1].data.sint;
Emeric Brun87855892012-10-17 17:39:35 +02004611
4612 if (ssl_sock_get_dn_entry(name, &args[0].data.str, pos, smp_trash) <= 0)
4613 goto out;
4614 }
4615 else if (ssl_sock_get_dn_oneline(name, smp_trash) <= 0)
4616 goto out;
4617
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004618 smp->data.type = SMP_T_STR;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004619 smp->data.u.str = *smp_trash;
Emeric Brun87855892012-10-17 17:39:35 +02004620 ret = 1;
4621out:
Emeric Brunba841a12014-04-30 17:05:08 +02004622 /* SSL_get_peer_certificate, it increase X509 * ref count */
4623 if (cert_peer && crt)
Emeric Brun87855892012-10-17 17:39:35 +02004624 X509_free(crt);
4625 return ret;
4626}
Emeric Brun9143d372012-12-20 15:44:16 +01004627
4628/* integer, returns true if current session use a client certificate */
4629static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004630smp_fetch_ssl_c_used(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun9143d372012-12-20 15:44:16 +01004631{
4632 X509 *crt;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004633 struct connection *conn;
Emeric Brun9143d372012-12-20 15:44:16 +01004634
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004635 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004636 if (!conn || conn->xprt != &ssl_sock)
4637 return 0;
4638
4639 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun9143d372012-12-20 15:44:16 +01004640 smp->flags |= SMP_F_MAY_CHANGE;
4641 return 0;
4642 }
4643
4644 /* SSL_get_peer_certificate returns a ptr on allocated X509 struct */
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004645 crt = SSL_get_peer_certificate(conn->xprt_ctx);
Emeric Brun9143d372012-12-20 15:44:16 +01004646 if (crt) {
4647 X509_free(crt);
4648 }
4649
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004650 smp->data.type = SMP_T_BOOL;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004651 smp->data.u.sint = (crt != NULL);
Emeric Brun9143d372012-12-20 15:44:16 +01004652 return 1;
4653}
4654
Emeric Brunba841a12014-04-30 17:05:08 +02004655/* integer, returns the certificate version
4656 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
4657 * should be use.
4658 */
Emeric Bruna7359fd2012-10-17 15:03:11 +02004659static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004660smp_fetch_ssl_x_version(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Bruna7359fd2012-10-17 15:03:11 +02004661{
Emeric Brunba841a12014-04-30 17:05:08 +02004662 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Bruna7359fd2012-10-17 15:03:11 +02004663 X509 *crt;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004664 struct connection *conn;
4665
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004666 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004667 if (!conn || conn->xprt != &ssl_sock)
Emeric Bruna7359fd2012-10-17 15:03:11 +02004668 return 0;
4669
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004670 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Bruna7359fd2012-10-17 15:03:11 +02004671 smp->flags |= SMP_F_MAY_CHANGE;
4672 return 0;
4673 }
4674
Emeric Brunba841a12014-04-30 17:05:08 +02004675 if (cert_peer)
4676 crt = SSL_get_peer_certificate(conn->xprt_ctx);
4677 else
4678 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Bruna7359fd2012-10-17 15:03:11 +02004679 if (!crt)
4680 return 0;
4681
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004682 smp->data.u.sint = (unsigned int)(1 + X509_get_version(crt));
Emeric Brunba841a12014-04-30 17:05:08 +02004683 /* SSL_get_peer_certificate increase X509 * ref count */
4684 if (cert_peer)
4685 X509_free(crt);
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004686 smp->data.type = SMP_T_SINT;
Emeric Bruna7359fd2012-10-17 15:03:11 +02004687
4688 return 1;
4689}
4690
Emeric Brunba841a12014-04-30 17:05:08 +02004691/* string, returns the certificate's signature algorithm.
4692 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
4693 * should be use.
4694 */
Emeric Brun7f56e742012-10-19 18:15:40 +02004695static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004696smp_fetch_ssl_x_sig_alg(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun7f56e742012-10-19 18:15:40 +02004697{
Emeric Brunba841a12014-04-30 17:05:08 +02004698 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brun7f56e742012-10-19 18:15:40 +02004699 X509 *crt;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004700 __OPENSSL_110_CONST__ ASN1_OBJECT *algorithm;
Emeric Brun7f56e742012-10-19 18:15:40 +02004701 int nid;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004702 struct connection *conn;
Emeric Brun7f56e742012-10-19 18:15:40 +02004703
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004704 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004705 if (!conn || conn->xprt != &ssl_sock)
4706 return 0;
4707
4708 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun7f56e742012-10-19 18:15:40 +02004709 smp->flags |= SMP_F_MAY_CHANGE;
4710 return 0;
4711 }
4712
Emeric Brunba841a12014-04-30 17:05:08 +02004713 if (cert_peer)
4714 crt = SSL_get_peer_certificate(conn->xprt_ctx);
4715 else
4716 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brun7f56e742012-10-19 18:15:40 +02004717 if (!crt)
4718 return 0;
4719
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004720 X509_ALGOR_get0(&algorithm, NULL, NULL, X509_get0_tbs_sigalg(crt));
4721 nid = OBJ_obj2nid(algorithm);
Emeric Brun7f56e742012-10-19 18:15:40 +02004722
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004723 smp->data.u.str.str = (char *)OBJ_nid2sn(nid);
4724 if (!smp->data.u.str.str) {
Emeric Brunba841a12014-04-30 17:05:08 +02004725 /* SSL_get_peer_certificate increase X509 * ref count */
4726 if (cert_peer)
4727 X509_free(crt);
Emeric Brun7f56e742012-10-19 18:15:40 +02004728 return 0;
Emeric Brun9bf3ba22013-10-07 14:31:44 +02004729 }
Emeric Brun7f56e742012-10-19 18:15:40 +02004730
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004731 smp->data.type = SMP_T_STR;
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01004732 smp->flags |= SMP_F_CONST;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004733 smp->data.u.str.len = strlen(smp->data.u.str.str);
Emeric Brunba841a12014-04-30 17:05:08 +02004734 /* SSL_get_peer_certificate increase X509 * ref count */
4735 if (cert_peer)
4736 X509_free(crt);
Emeric Brun7f56e742012-10-19 18:15:40 +02004737
4738 return 1;
4739}
4740
Emeric Brunba841a12014-04-30 17:05:08 +02004741/* string, returns the certificate's key algorithm.
4742 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
4743 * should be use.
4744 */
Emeric Brun521a0112012-10-22 12:22:55 +02004745static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004746smp_fetch_ssl_x_key_alg(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun521a0112012-10-22 12:22:55 +02004747{
Emeric Brunba841a12014-04-30 17:05:08 +02004748 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brun521a0112012-10-22 12:22:55 +02004749 X509 *crt;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004750 ASN1_OBJECT *algorithm;
Emeric Brun521a0112012-10-22 12:22:55 +02004751 int nid;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004752 struct connection *conn;
Emeric Brun521a0112012-10-22 12:22:55 +02004753
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004754 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004755 if (!conn || conn->xprt != &ssl_sock)
4756 return 0;
4757
4758 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun521a0112012-10-22 12:22:55 +02004759 smp->flags |= SMP_F_MAY_CHANGE;
4760 return 0;
4761 }
4762
Emeric Brunba841a12014-04-30 17:05:08 +02004763 if (cert_peer)
4764 crt = SSL_get_peer_certificate(conn->xprt_ctx);
4765 else
4766 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brun521a0112012-10-22 12:22:55 +02004767 if (!crt)
4768 return 0;
4769
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004770 X509_PUBKEY_get0_param(&algorithm, NULL, NULL, NULL, X509_get_X509_PUBKEY(crt));
4771 nid = OBJ_obj2nid(algorithm);
Emeric Brun521a0112012-10-22 12:22:55 +02004772
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004773 smp->data.u.str.str = (char *)OBJ_nid2sn(nid);
4774 if (!smp->data.u.str.str) {
Emeric Brunba841a12014-04-30 17:05:08 +02004775 /* SSL_get_peer_certificate increase X509 * ref count */
4776 if (cert_peer)
4777 X509_free(crt);
Emeric Brun521a0112012-10-22 12:22:55 +02004778 return 0;
Emeric Brun9bf3ba22013-10-07 14:31:44 +02004779 }
Emeric Brun521a0112012-10-22 12:22:55 +02004780
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004781 smp->data.type = SMP_T_STR;
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01004782 smp->flags |= SMP_F_CONST;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004783 smp->data.u.str.len = strlen(smp->data.u.str.str);
Emeric Brunba841a12014-04-30 17:05:08 +02004784 if (cert_peer)
4785 X509_free(crt);
Emeric Brun521a0112012-10-22 12:22:55 +02004786
4787 return 1;
4788}
4789
Emeric Brun645ae792014-04-30 14:21:06 +02004790/* boolean, returns true if front conn. transport layer is SSL.
4791 * This function is also usable on backend conn if the fetch keyword 5th
4792 * char is 'b'.
4793 */
Willy Tarreau7875d092012-09-10 08:20:03 +02004794static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004795smp_fetch_ssl_fc(const struct arg *args, struct sample *smp, const char *kw, void *private)
Willy Tarreau7875d092012-09-10 08:20:03 +02004796{
Willy Tarreaue237fe12016-03-10 17:05:28 +01004797 struct connection *conn = objt_conn((kw[4] != 'b') ? smp->sess->origin :
4798 smp->strm ? smp->strm->si[1].end : NULL);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004799
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004800 smp->data.type = SMP_T_BOOL;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004801 smp->data.u.sint = (conn && conn->xprt == &ssl_sock);
Willy Tarreau7875d092012-09-10 08:20:03 +02004802 return 1;
4803}
4804
Emeric Brun2525b6b2012-10-18 15:59:43 +02004805/* boolean, returns true if client present a SNI */
Willy Tarreau7875d092012-09-10 08:20:03 +02004806static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004807smp_fetch_ssl_fc_has_sni(const struct arg *args, struct sample *smp, const char *kw, void *private)
Willy Tarreau7875d092012-09-10 08:20:03 +02004808{
4809#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004810 struct connection *conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004811
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004812 smp->data.type = SMP_T_BOOL;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004813 smp->data.u.sint = (conn && conn->xprt == &ssl_sock) &&
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004814 conn->xprt_ctx &&
4815 SSL_get_servername(conn->xprt_ctx, TLSEXT_NAMETYPE_host_name) != NULL;
Willy Tarreau7875d092012-09-10 08:20:03 +02004816 return 1;
4817#else
4818 return 0;
4819#endif
4820}
4821
Nenad Merdanovic26ea8222015-05-18 02:28:57 +02004822/* boolean, returns true if client session has been resumed */
4823static int
4824smp_fetch_ssl_fc_is_resumed(const struct arg *args, struct sample *smp, const char *kw, void *private)
4825{
4826 struct connection *conn = objt_conn(smp->sess->origin);
4827
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004828 smp->data.type = SMP_T_BOOL;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004829 smp->data.u.sint = (conn && conn->xprt == &ssl_sock) &&
Nenad Merdanovic26ea8222015-05-18 02:28:57 +02004830 conn->xprt_ctx &&
4831 SSL_session_reused(conn->xprt_ctx);
4832 return 1;
4833}
4834
Emeric Brun645ae792014-04-30 14:21:06 +02004835/* string, returns the used cipher if front conn. transport layer is SSL.
4836 * This function is also usable on backend conn if the fetch keyword 5th
4837 * char is 'b'.
4838 */
Emeric Brun589fcad2012-10-16 14:13:26 +02004839static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004840smp_fetch_ssl_fc_cipher(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun589fcad2012-10-16 14:13:26 +02004841{
Willy Tarreaue237fe12016-03-10 17:05:28 +01004842 struct connection *conn = objt_conn((kw[4] != 'b') ? smp->sess->origin :
4843 smp->strm ? smp->strm->si[1].end : NULL);
Emeric Brun589fcad2012-10-16 14:13:26 +02004844
Willy Tarreaube508f12016-03-10 11:47:01 +01004845 smp->flags = 0;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004846 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
Emeric Brun589fcad2012-10-16 14:13:26 +02004847 return 0;
4848
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004849 smp->data.u.str.str = (char *)SSL_get_cipher_name(conn->xprt_ctx);
4850 if (!smp->data.u.str.str)
Emeric Brun589fcad2012-10-16 14:13:26 +02004851 return 0;
4852
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004853 smp->data.type = SMP_T_STR;
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01004854 smp->flags |= SMP_F_CONST;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004855 smp->data.u.str.len = strlen(smp->data.u.str.str);
Emeric Brun589fcad2012-10-16 14:13:26 +02004856
4857 return 1;
4858}
4859
Emeric Brun645ae792014-04-30 14:21:06 +02004860/* integer, returns the algoritm's keysize if front conn. transport layer
4861 * is SSL.
4862 * This function is also usable on backend conn if the fetch keyword 5th
4863 * char is 'b'.
4864 */
Emeric Brun589fcad2012-10-16 14:13:26 +02004865static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004866smp_fetch_ssl_fc_alg_keysize(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun589fcad2012-10-16 14:13:26 +02004867{
Willy Tarreaue237fe12016-03-10 17:05:28 +01004868 struct connection *conn = objt_conn((kw[4] != 'b') ? smp->sess->origin :
4869 smp->strm ? smp->strm->si[1].end : NULL);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004870
Willy Tarreaue237fe12016-03-10 17:05:28 +01004871 int sint;
Willy Tarreaube508f12016-03-10 11:47:01 +01004872
Emeric Brun589fcad2012-10-16 14:13:26 +02004873 smp->flags = 0;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004874 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
Emeric Brun589fcad2012-10-16 14:13:26 +02004875 return 0;
4876
Thierry FOURNIER07ee64e2015-07-06 23:43:03 +02004877 if (!SSL_get_cipher_bits(conn->xprt_ctx, &sint))
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004878 return 0;
4879
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004880 smp->data.u.sint = sint;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004881 smp->data.type = SMP_T_SINT;
Emeric Brun589fcad2012-10-16 14:13:26 +02004882
4883 return 1;
4884}
4885
Emeric Brun645ae792014-04-30 14:21:06 +02004886/* integer, returns the used keysize if front conn. transport layer is SSL.
4887 * This function is also usable on backend conn if the fetch keyword 5th
4888 * char is 'b'.
4889 */
Emeric Brun589fcad2012-10-16 14:13:26 +02004890static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004891smp_fetch_ssl_fc_use_keysize(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun589fcad2012-10-16 14:13:26 +02004892{
Willy Tarreaue237fe12016-03-10 17:05:28 +01004893 struct connection *conn = objt_conn((kw[4] != 'b') ? smp->sess->origin :
4894 smp->strm ? smp->strm->si[1].end : NULL);
Willy Tarreaube508f12016-03-10 11:47:01 +01004895
Emeric Brun589fcad2012-10-16 14:13:26 +02004896 smp->flags = 0;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004897 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
4898 return 0;
4899
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004900 smp->data.u.sint = (unsigned int)SSL_get_cipher_bits(conn->xprt_ctx, NULL);
4901 if (!smp->data.u.sint)
Emeric Brun589fcad2012-10-16 14:13:26 +02004902 return 0;
4903
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004904 smp->data.type = SMP_T_SINT;
Emeric Brun589fcad2012-10-16 14:13:26 +02004905
4906 return 1;
4907}
4908
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02004909#ifdef OPENSSL_NPN_NEGOTIATED
Willy Tarreau7875d092012-09-10 08:20:03 +02004910static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004911smp_fetch_ssl_fc_npn(const struct arg *args, struct sample *smp, const char *kw, void *private)
Willy Tarreaua33c6542012-10-15 13:19:06 +02004912{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004913 struct connection *conn;
4914
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01004915 smp->flags = SMP_F_CONST;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004916 smp->data.type = SMP_T_STR;
Willy Tarreaua33c6542012-10-15 13:19:06 +02004917
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004918 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004919 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
4920 return 0;
4921
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004922 smp->data.u.str.str = NULL;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004923 SSL_get0_next_proto_negotiated(conn->xprt_ctx,
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004924 (const unsigned char **)&smp->data.u.str.str, (unsigned *)&smp->data.u.str.len);
Willy Tarreaua33c6542012-10-15 13:19:06 +02004925
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004926 if (!smp->data.u.str.str)
Willy Tarreaua33c6542012-10-15 13:19:06 +02004927 return 0;
4928
4929 return 1;
Willy Tarreaua33c6542012-10-15 13:19:06 +02004930}
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02004931#endif
Willy Tarreaua33c6542012-10-15 13:19:06 +02004932
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01004933#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Willy Tarreauab861d32013-04-02 02:30:41 +02004934static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004935smp_fetch_ssl_fc_alpn(const struct arg *args, struct sample *smp, const char *kw, void *private)
Willy Tarreauab861d32013-04-02 02:30:41 +02004936{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004937 struct connection *conn;
4938
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01004939 smp->flags = SMP_F_CONST;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004940 smp->data.type = SMP_T_STR;
Willy Tarreauab861d32013-04-02 02:30:41 +02004941
Willy Tarreaue26bf052015-05-12 10:30:12 +02004942 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004943 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
Willy Tarreauab861d32013-04-02 02:30:41 +02004944 return 0;
4945
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004946 smp->data.u.str.str = NULL;
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01004947 SSL_get0_alpn_selected(conn->xprt_ctx,
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004948 (const unsigned char **)&smp->data.u.str.str, (unsigned *)&smp->data.u.str.len);
Willy Tarreauab861d32013-04-02 02:30:41 +02004949
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004950 if (!smp->data.u.str.str)
Willy Tarreauab861d32013-04-02 02:30:41 +02004951 return 0;
4952
4953 return 1;
4954}
4955#endif
4956
Emeric Brun645ae792014-04-30 14:21:06 +02004957/* string, returns the used protocol if front conn. transport layer is SSL.
4958 * This function is also usable on backend conn if the fetch keyword 5th
4959 * char is 'b'.
4960 */
Willy Tarreaua33c6542012-10-15 13:19:06 +02004961static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004962smp_fetch_ssl_fc_protocol(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun589fcad2012-10-16 14:13:26 +02004963{
Willy Tarreaue237fe12016-03-10 17:05:28 +01004964 struct connection *conn = objt_conn((kw[4] != 'b') ? smp->sess->origin :
4965 smp->strm ? smp->strm->si[1].end : NULL);
Willy Tarreaube508f12016-03-10 11:47:01 +01004966
Emeric Brun589fcad2012-10-16 14:13:26 +02004967 smp->flags = 0;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004968 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
4969 return 0;
4970
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004971 smp->data.u.str.str = (char *)SSL_get_version(conn->xprt_ctx);
4972 if (!smp->data.u.str.str)
Emeric Brun589fcad2012-10-16 14:13:26 +02004973 return 0;
4974
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004975 smp->data.type = SMP_T_STR;
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01004976 smp->flags = SMP_F_CONST;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004977 smp->data.u.str.len = strlen(smp->data.u.str.str);
Emeric Brun589fcad2012-10-16 14:13:26 +02004978
4979 return 1;
4980}
4981
Willy Tarreau87b09662015-04-03 00:22:06 +02004982/* binary, returns the SSL stream id if front conn. transport layer is SSL.
Emeric Brun645ae792014-04-30 14:21:06 +02004983 * This function is also usable on backend conn if the fetch keyword 5th
4984 * char is 'b'.
4985 */
Emeric Brun589fcad2012-10-16 14:13:26 +02004986static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004987smp_fetch_ssl_fc_session_id(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brunfe68f682012-10-16 14:59:28 +02004988{
4989#if OPENSSL_VERSION_NUMBER > 0x0090800fL
Willy Tarreaue237fe12016-03-10 17:05:28 +01004990 struct connection *conn = objt_conn((kw[4] != 'b') ? smp->sess->origin :
4991 smp->strm ? smp->strm->si[1].end : NULL);
Emeric Brunfe68f682012-10-16 14:59:28 +02004992
Willy Tarreaue237fe12016-03-10 17:05:28 +01004993 SSL_SESSION *ssl_sess;
Willy Tarreaube508f12016-03-10 11:47:01 +01004994
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01004995 smp->flags = SMP_F_CONST;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004996 smp->data.type = SMP_T_BIN;
Emeric Brunfe68f682012-10-16 14:59:28 +02004997
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004998 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
4999 return 0;
5000
Willy Tarreau192252e2015-04-04 01:47:55 +02005001 ssl_sess = SSL_get_session(conn->xprt_ctx);
5002 if (!ssl_sess)
Emeric Brunfe68f682012-10-16 14:59:28 +02005003 return 0;
5004
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005005 smp->data.u.str.str = (char *)SSL_SESSION_get_id(ssl_sess, (unsigned int *)&smp->data.u.str.len);
5006 if (!smp->data.u.str.str || !smp->data.u.str.len)
Emeric Brunfe68f682012-10-16 14:59:28 +02005007 return 0;
5008
5009 return 1;
5010#else
5011 return 0;
5012#endif
5013}
5014
5015static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005016smp_fetch_ssl_fc_sni(const struct arg *args, struct sample *smp, const char *kw, void *private)
Willy Tarreau7875d092012-09-10 08:20:03 +02005017{
5018#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005019 struct connection *conn;
5020
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01005021 smp->flags = SMP_F_CONST;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005022 smp->data.type = SMP_T_STR;
Willy Tarreau7875d092012-09-10 08:20:03 +02005023
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02005024 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005025 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
5026 return 0;
5027
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005028 smp->data.u.str.str = (char *)SSL_get_servername(conn->xprt_ctx, TLSEXT_NAMETYPE_host_name);
5029 if (!smp->data.u.str.str)
Willy Tarreau3e394c92012-09-14 23:56:58 +02005030 return 0;
5031
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005032 smp->data.u.str.len = strlen(smp->data.u.str.str);
Willy Tarreau7875d092012-09-10 08:20:03 +02005033 return 1;
5034#else
5035 return 0;
5036#endif
5037}
5038
David Sc1ad52e2014-04-08 18:48:47 -04005039static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005040smp_fetch_ssl_fc_unique_id(const struct arg *args, struct sample *smp, const char *kw, void *private)
David Sc1ad52e2014-04-08 18:48:47 -04005041{
5042#if OPENSSL_VERSION_NUMBER > 0x0090800fL
Willy Tarreaue237fe12016-03-10 17:05:28 +01005043 struct connection *conn = objt_conn((kw[4] != 'b') ? smp->sess->origin :
5044 smp->strm ? smp->strm->si[1].end : NULL);
5045
David Sc1ad52e2014-04-08 18:48:47 -04005046 int finished_len;
David Sc1ad52e2014-04-08 18:48:47 -04005047 struct chunk *finished_trash;
David Sc1ad52e2014-04-08 18:48:47 -04005048
5049 smp->flags = 0;
David Sc1ad52e2014-04-08 18:48:47 -04005050 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
5051 return 0;
5052
5053 if (!(conn->flags & CO_FL_CONNECTED)) {
5054 smp->flags |= SMP_F_MAY_CHANGE;
5055 return 0;
5056 }
5057
5058 finished_trash = get_trash_chunk();
5059 if (!SSL_session_reused(conn->xprt_ctx))
5060 finished_len = SSL_get_peer_finished(conn->xprt_ctx, finished_trash->str, finished_trash->size);
5061 else
5062 finished_len = SSL_get_finished(conn->xprt_ctx, finished_trash->str, finished_trash->size);
5063
5064 if (!finished_len)
5065 return 0;
5066
Emeric Brunb73a9b02014-04-30 18:49:19 +02005067 finished_trash->len = finished_len;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005068 smp->data.u.str = *finished_trash;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005069 smp->data.type = SMP_T_BIN;
David Sc1ad52e2014-04-08 18:48:47 -04005070
5071 return 1;
5072#else
5073 return 0;
5074#endif
5075}
5076
Emeric Brun2525b6b2012-10-18 15:59:43 +02005077/* integer, returns the first verify error in CA chain of client certificate chain. */
Emeric Brunf282a812012-09-21 15:27:54 +02005078static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005079smp_fetch_ssl_c_ca_err(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brunf282a812012-09-21 15:27:54 +02005080{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005081 struct connection *conn;
5082
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02005083 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005084 if (!conn || conn->xprt != &ssl_sock)
5085 return 0;
5086
5087 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunf282a812012-09-21 15:27:54 +02005088 smp->flags = SMP_F_MAY_CHANGE;
5089 return 0;
5090 }
5091
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005092 smp->data.type = SMP_T_SINT;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005093 smp->data.u.sint = (unsigned long long int)SSL_SOCK_ST_TO_CA_ERROR(conn->xprt_st);
Emeric Brunf282a812012-09-21 15:27:54 +02005094 smp->flags = 0;
5095
5096 return 1;
5097}
5098
Emeric Brun2525b6b2012-10-18 15:59:43 +02005099/* integer, returns the depth of the first verify error in CA chain of client certificate chain. */
Emeric Brunf282a812012-09-21 15:27:54 +02005100static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005101smp_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 +02005102{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005103 struct connection *conn;
5104
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02005105 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005106 if (!conn || conn->xprt != &ssl_sock)
Emeric Brunf282a812012-09-21 15:27:54 +02005107 return 0;
5108
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005109 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunf282a812012-09-21 15:27:54 +02005110 smp->flags = SMP_F_MAY_CHANGE;
5111 return 0;
5112 }
5113
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005114 smp->data.type = SMP_T_SINT;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005115 smp->data.u.sint = (long long int)SSL_SOCK_ST_TO_CAEDEPTH(conn->xprt_st);
Emeric Brunf282a812012-09-21 15:27:54 +02005116 smp->flags = 0;
5117
5118 return 1;
5119}
5120
Emeric Brun2525b6b2012-10-18 15:59:43 +02005121/* integer, returns the first verify error on client certificate */
Emeric Brunf282a812012-09-21 15:27:54 +02005122static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005123smp_fetch_ssl_c_err(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brunf282a812012-09-21 15:27:54 +02005124{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005125 struct connection *conn;
5126
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02005127 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005128 if (!conn || conn->xprt != &ssl_sock)
5129 return 0;
5130
5131 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunf282a812012-09-21 15:27:54 +02005132 smp->flags = SMP_F_MAY_CHANGE;
5133 return 0;
5134 }
5135
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005136 smp->data.type = SMP_T_SINT;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005137 smp->data.u.sint = (long long int)SSL_SOCK_ST_TO_CRTERROR(conn->xprt_st);
Emeric Brunf282a812012-09-21 15:27:54 +02005138 smp->flags = 0;
5139
5140 return 1;
5141}
5142
Emeric Brun2525b6b2012-10-18 15:59:43 +02005143/* integer, returns the verify result on client cert */
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02005144static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005145smp_fetch_ssl_c_verify(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02005146{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005147 struct connection *conn;
5148
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02005149 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005150 if (!conn || conn->xprt != &ssl_sock)
5151 return 0;
5152
5153 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02005154 smp->flags = SMP_F_MAY_CHANGE;
5155 return 0;
5156 }
5157
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005158 if (!conn->xprt_ctx)
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02005159 return 0;
5160
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005161 smp->data.type = SMP_T_SINT;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005162 smp->data.u.sint = (long long int)SSL_get_verify_result(conn->xprt_ctx);
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02005163 smp->flags = 0;
5164
5165 return 1;
5166}
5167
Emeric Brunfb510ea2012-10-05 12:00:26 +02005168/* parse the "ca-file" bind keyword */
5169static int bind_parse_ca_file(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
Emeric Brund94b3fe2012-09-20 18:23:56 +02005170{
5171 if (!*args[cur_arg + 1]) {
5172 if (err)
5173 memprintf(err, "'%s' : missing CAfile path", args[cur_arg]);
5174 return ERR_ALERT | ERR_FATAL;
5175 }
5176
Emeric Brunef42d922012-10-11 16:11:36 +02005177 if ((*args[cur_arg + 1] != '/') && global.ca_base)
5178 memprintf(&conf->ca_file, "%s/%s", global.ca_base, args[cur_arg + 1]);
5179 else
5180 memprintf(&conf->ca_file, "%s", args[cur_arg + 1]);
Emeric Brunc8e8d122012-10-02 18:42:10 +02005181
Emeric Brund94b3fe2012-09-20 18:23:56 +02005182 return 0;
5183}
5184
Christopher Faulet31af49d2015-06-09 17:29:50 +02005185/* parse the "ca-sign-file" bind keyword */
5186static int bind_parse_ca_sign_file(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5187{
5188 if (!*args[cur_arg + 1]) {
5189 if (err)
5190 memprintf(err, "'%s' : missing CAfile path", args[cur_arg]);
5191 return ERR_ALERT | ERR_FATAL;
5192 }
5193
5194 if ((*args[cur_arg + 1] != '/') && global.ca_base)
5195 memprintf(&conf->ca_sign_file, "%s/%s", global.ca_base, args[cur_arg + 1]);
5196 else
5197 memprintf(&conf->ca_sign_file, "%s", args[cur_arg + 1]);
5198
5199 return 0;
5200}
5201
Bertrand Jacquinff13c062016-11-13 16:37:11 +00005202/* parse the "ca-sign-pass" bind keyword */
Christopher Faulet31af49d2015-06-09 17:29:50 +02005203static int bind_parse_ca_sign_pass(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5204{
5205 if (!*args[cur_arg + 1]) {
5206 if (err)
5207 memprintf(err, "'%s' : missing CAkey password", args[cur_arg]);
5208 return ERR_ALERT | ERR_FATAL;
5209 }
5210 memprintf(&conf->ca_sign_pass, "%s", args[cur_arg + 1]);
5211 return 0;
5212}
5213
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005214/* parse the "ciphers" bind keyword */
Willy Tarreau4348fad2012-09-20 16:48:07 +02005215static int bind_parse_ciphers(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005216{
5217 if (!*args[cur_arg + 1]) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02005218 memprintf(err, "'%s' : missing cipher suite", args[cur_arg]);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005219 return ERR_ALERT | ERR_FATAL;
5220 }
5221
Emeric Brun76d88952012-10-05 15:47:31 +02005222 free(conf->ciphers);
Willy Tarreau4348fad2012-09-20 16:48:07 +02005223 conf->ciphers = strdup(args[cur_arg + 1]);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005224 return 0;
5225}
5226
5227/* parse the "crt" bind keyword */
Willy Tarreau4348fad2012-09-20 16:48:07 +02005228static 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 +02005229{
Willy Tarreau38011032013-08-13 16:59:39 +02005230 char path[MAXPATHLEN];
Willy Tarreaub75d6922014-04-14 18:05:41 +02005231
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005232 if (!*args[cur_arg + 1]) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02005233 memprintf(err, "'%s' : missing certificate location", args[cur_arg]);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005234 return ERR_ALERT | ERR_FATAL;
5235 }
5236
Emeric Brunc8e8d122012-10-02 18:42:10 +02005237 if ((*args[cur_arg + 1] != '/' ) && global.crt_base) {
Willy Tarreau38011032013-08-13 16:59:39 +02005238 if ((strlen(global.crt_base) + 1 + strlen(args[cur_arg + 1]) + 1) > MAXPATHLEN) {
Emeric Brunc8e8d122012-10-02 18:42:10 +02005239 memprintf(err, "'%s' : path too long", args[cur_arg]);
5240 return ERR_ALERT | ERR_FATAL;
5241 }
Willy Tarreaub75d6922014-04-14 18:05:41 +02005242 snprintf(path, sizeof(path), "%s/%s", global.crt_base, args[cur_arg + 1]);
Willy Tarreau03209342016-12-22 17:08:28 +01005243 if (ssl_sock_load_cert(path, conf, err) > 0)
Emeric Brunc8e8d122012-10-02 18:42:10 +02005244 return ERR_ALERT | ERR_FATAL;
5245
5246 return 0;
5247 }
5248
Willy Tarreau03209342016-12-22 17:08:28 +01005249 if (ssl_sock_load_cert(args[cur_arg + 1], conf, err) > 0)
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005250 return ERR_ALERT | ERR_FATAL;
Emeric Brund94b3fe2012-09-20 18:23:56 +02005251
5252 return 0;
5253}
5254
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01005255/* parse the "crt-list" bind keyword */
5256static int bind_parse_crt_list(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5257{
5258 if (!*args[cur_arg + 1]) {
5259 memprintf(err, "'%s' : missing certificate location", args[cur_arg]);
5260 return ERR_ALERT | ERR_FATAL;
5261 }
5262
Willy Tarreau03209342016-12-22 17:08:28 +01005263 if (ssl_sock_load_cert_list_file(args[cur_arg + 1], conf, err) > 0) {
Willy Tarreauad1731d2013-04-02 17:35:58 +02005264 memprintf(err, "'%s' : %s", args[cur_arg], *err);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01005265 return ERR_ALERT | ERR_FATAL;
Willy Tarreauad1731d2013-04-02 17:35:58 +02005266 }
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01005267
5268 return 0;
5269}
5270
Emeric Brunfb510ea2012-10-05 12:00:26 +02005271/* parse the "crl-file" bind keyword */
5272static int bind_parse_crl_file(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
Emeric Brund94b3fe2012-09-20 18:23:56 +02005273{
Emeric Brun051cdab2012-10-02 19:25:50 +02005274#ifndef X509_V_FLAG_CRL_CHECK
5275 if (err)
5276 memprintf(err, "'%s' : library does not support CRL verify", args[cur_arg]);
5277 return ERR_ALERT | ERR_FATAL;
5278#else
Emeric Brund94b3fe2012-09-20 18:23:56 +02005279 if (!*args[cur_arg + 1]) {
5280 if (err)
5281 memprintf(err, "'%s' : missing CRLfile path", args[cur_arg]);
5282 return ERR_ALERT | ERR_FATAL;
5283 }
Emeric Brun2b58d042012-09-20 17:10:03 +02005284
Emeric Brunef42d922012-10-11 16:11:36 +02005285 if ((*args[cur_arg + 1] != '/') && global.ca_base)
5286 memprintf(&conf->crl_file, "%s/%s", global.ca_base, args[cur_arg + 1]);
5287 else
5288 memprintf(&conf->crl_file, "%s", args[cur_arg + 1]);
Emeric Brunc8e8d122012-10-02 18:42:10 +02005289
Emeric Brun2b58d042012-09-20 17:10:03 +02005290 return 0;
Emeric Brun051cdab2012-10-02 19:25:50 +02005291#endif
Emeric Brun2b58d042012-09-20 17:10:03 +02005292}
5293
Bertrand Jacquinff13c062016-11-13 16:37:11 +00005294/* parse the "ecdhe" bind keyword keyword */
Emeric Brun2b58d042012-09-20 17:10:03 +02005295static int bind_parse_ecdhe(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5296{
5297#if OPENSSL_VERSION_NUMBER < 0x0090800fL
5298 if (err)
5299 memprintf(err, "'%s' : library does not support elliptic curve Diffie-Hellman (too old)", args[cur_arg]);
5300 return ERR_ALERT | ERR_FATAL;
5301#elif defined(OPENSSL_NO_ECDH)
5302 if (err)
5303 memprintf(err, "'%s' : library does not support elliptic curve Diffie-Hellman (disabled via OPENSSL_NO_ECDH)", args[cur_arg]);
5304 return ERR_ALERT | ERR_FATAL;
5305#else
5306 if (!*args[cur_arg + 1]) {
5307 if (err)
5308 memprintf(err, "'%s' : missing named curve", args[cur_arg]);
5309 return ERR_ALERT | ERR_FATAL;
5310 }
5311
5312 conf->ecdhe = strdup(args[cur_arg + 1]);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005313
5314 return 0;
Emeric Brun2b58d042012-09-20 17:10:03 +02005315#endif
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005316}
5317
Bertrand Jacquinff13c062016-11-13 16:37:11 +00005318/* parse the "crt-ignore-err" and "ca-ignore-err" bind keywords */
Emeric Brun81c00f02012-09-21 14:31:21 +02005319static int bind_parse_ignore_err(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5320{
5321 int code;
5322 char *p = args[cur_arg + 1];
5323 unsigned long long *ignerr = &conf->crt_ignerr;
5324
5325 if (!*p) {
5326 if (err)
5327 memprintf(err, "'%s' : missing error IDs list", args[cur_arg]);
5328 return ERR_ALERT | ERR_FATAL;
5329 }
5330
5331 if (strcmp(args[cur_arg], "ca-ignore-err") == 0)
5332 ignerr = &conf->ca_ignerr;
5333
5334 if (strcmp(p, "all") == 0) {
5335 *ignerr = ~0ULL;
5336 return 0;
5337 }
5338
5339 while (p) {
5340 code = atoi(p);
5341 if ((code <= 0) || (code > 63)) {
5342 if (err)
5343 memprintf(err, "'%s' : ID '%d' out of range (1..63) in error IDs list '%s'",
5344 args[cur_arg], code, args[cur_arg + 1]);
5345 return ERR_ALERT | ERR_FATAL;
5346 }
5347 *ignerr |= 1ULL << code;
5348 p = strchr(p, ',');
5349 if (p)
5350 p++;
5351 }
5352
Emeric Brun2cb7ae52012-10-05 14:14:21 +02005353 return 0;
5354}
5355
5356/* parse the "force-sslv3" bind keyword */
5357static int bind_parse_force_sslv3(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5358{
5359 conf->ssl_options |= BC_SSL_O_USE_SSLV3;
5360 return 0;
5361}
5362
5363/* parse the "force-tlsv10" bind keyword */
5364static int bind_parse_force_tlsv10(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5365{
5366 conf->ssl_options |= BC_SSL_O_USE_TLSV10;
Emeric Brun2d0c4822012-10-02 13:45:20 +02005367 return 0;
5368}
5369
Emeric Brun2cb7ae52012-10-05 14:14:21 +02005370/* parse the "force-tlsv11" bind keyword */
5371static int bind_parse_force_tlsv11(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5372{
5373#if SSL_OP_NO_TLSv1_1
5374 conf->ssl_options |= BC_SSL_O_USE_TLSV11;
5375 return 0;
5376#else
5377 if (err)
5378 memprintf(err, "'%s' : library does not support protocol TLSv1.1", args[cur_arg]);
5379 return ERR_ALERT | ERR_FATAL;
5380#endif
5381}
5382
5383/* parse the "force-tlsv12" bind keyword */
5384static int bind_parse_force_tlsv12(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5385{
5386#if SSL_OP_NO_TLSv1_2
5387 conf->ssl_options |= BC_SSL_O_USE_TLSV12;
5388 return 0;
5389#else
5390 if (err)
5391 memprintf(err, "'%s' : library does not support protocol TLSv1.2", args[cur_arg]);
5392 return ERR_ALERT | ERR_FATAL;
5393#endif
5394}
5395
5396
Emeric Brun2d0c4822012-10-02 13:45:20 +02005397/* parse the "no-tls-tickets" bind keyword */
5398static int bind_parse_no_tls_tickets(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5399{
Emeric Brun89675492012-10-05 13:48:26 +02005400 conf->ssl_options |= BC_SSL_O_NO_TLS_TICKETS;
Emeric Brun81c00f02012-09-21 14:31:21 +02005401 return 0;
5402}
5403
Emeric Brun2d0c4822012-10-02 13:45:20 +02005404
Emeric Brun9b3009b2012-10-05 11:55:06 +02005405/* parse the "no-sslv3" bind keyword */
5406static int bind_parse_no_sslv3(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005407{
Emeric Brun89675492012-10-05 13:48:26 +02005408 conf->ssl_options |= BC_SSL_O_NO_SSLV3;
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005409 return 0;
5410}
5411
Emeric Brun9b3009b2012-10-05 11:55:06 +02005412/* parse the "no-tlsv10" bind keyword */
5413static int bind_parse_no_tlsv10(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
Emeric Brunc0ff4922012-09-28 19:37:02 +02005414{
Emeric Brun89675492012-10-05 13:48:26 +02005415 conf->ssl_options |= BC_SSL_O_NO_TLSV10;
Emeric Brunc0ff4922012-09-28 19:37:02 +02005416 return 0;
5417}
5418
Emeric Brun9b3009b2012-10-05 11:55:06 +02005419/* parse the "no-tlsv11" bind keyword */
5420static int bind_parse_no_tlsv11(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
Emeric Brunc0ff4922012-09-28 19:37:02 +02005421{
Emeric Brun89675492012-10-05 13:48:26 +02005422 conf->ssl_options |= BC_SSL_O_NO_TLSV11;
Emeric Brunc0ff4922012-09-28 19:37:02 +02005423 return 0;
5424}
5425
Emeric Brun9b3009b2012-10-05 11:55:06 +02005426/* parse the "no-tlsv12" bind keyword */
5427static int bind_parse_no_tlsv12(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005428{
Emeric Brun89675492012-10-05 13:48:26 +02005429 conf->ssl_options |= BC_SSL_O_NO_TLSV12;
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005430 return 0;
5431}
5432
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02005433/* parse the "npn" bind keyword */
5434static int bind_parse_npn(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5435{
5436#ifdef OPENSSL_NPN_NEGOTIATED
5437 char *p1, *p2;
5438
5439 if (!*args[cur_arg + 1]) {
5440 memprintf(err, "'%s' : missing the comma-delimited NPN protocol suite", args[cur_arg]);
5441 return ERR_ALERT | ERR_FATAL;
5442 }
5443
5444 free(conf->npn_str);
5445
Willy Tarreau3724da12016-02-12 17:11:12 +01005446 /* the NPN string is built as a suite of (<len> <name>)*,
5447 * so we reuse each comma to store the next <len> and need
5448 * one more for the end of the string.
5449 */
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02005450 conf->npn_len = strlen(args[cur_arg + 1]) + 1;
Willy Tarreau3724da12016-02-12 17:11:12 +01005451 conf->npn_str = calloc(1, conf->npn_len + 1);
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02005452 memcpy(conf->npn_str + 1, args[cur_arg + 1], conf->npn_len);
5453
5454 /* replace commas with the name length */
5455 p1 = conf->npn_str;
5456 p2 = p1 + 1;
5457 while (1) {
5458 p2 = memchr(p1 + 1, ',', conf->npn_str + conf->npn_len - (p1 + 1));
5459 if (!p2)
5460 p2 = p1 + 1 + strlen(p1 + 1);
5461
5462 if (p2 - (p1 + 1) > 255) {
5463 *p2 = '\0';
5464 memprintf(err, "'%s' : NPN protocol name too long : '%s'", args[cur_arg], p1 + 1);
5465 return ERR_ALERT | ERR_FATAL;
5466 }
5467
5468 *p1 = p2 - (p1 + 1);
5469 p1 = p2;
5470
5471 if (!*p2)
5472 break;
5473
5474 *(p2++) = '\0';
5475 }
5476 return 0;
5477#else
5478 if (err)
5479 memprintf(err, "'%s' : library does not support TLS NPN extension", args[cur_arg]);
5480 return ERR_ALERT | ERR_FATAL;
5481#endif
5482}
5483
Willy Tarreauab861d32013-04-02 02:30:41 +02005484/* parse the "alpn" bind keyword */
5485static int bind_parse_alpn(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5486{
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01005487#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Willy Tarreauab861d32013-04-02 02:30:41 +02005488 char *p1, *p2;
5489
5490 if (!*args[cur_arg + 1]) {
5491 memprintf(err, "'%s' : missing the comma-delimited ALPN protocol suite", args[cur_arg]);
5492 return ERR_ALERT | ERR_FATAL;
5493 }
5494
5495 free(conf->alpn_str);
5496
Marcoen Hirschbergbef60912016-02-12 17:05:24 +01005497 /* the ALPN string is built as a suite of (<len> <name>)*,
5498 * so we reuse each comma to store the next <len> and need
5499 * one more for the end of the string.
5500 */
Willy Tarreauab861d32013-04-02 02:30:41 +02005501 conf->alpn_len = strlen(args[cur_arg + 1]) + 1;
Marcoen Hirschbergbef60912016-02-12 17:05:24 +01005502 conf->alpn_str = calloc(1, conf->alpn_len + 1);
Willy Tarreauab861d32013-04-02 02:30:41 +02005503 memcpy(conf->alpn_str + 1, args[cur_arg + 1], conf->alpn_len);
5504
5505 /* replace commas with the name length */
5506 p1 = conf->alpn_str;
5507 p2 = p1 + 1;
5508 while (1) {
5509 p2 = memchr(p1 + 1, ',', conf->alpn_str + conf->alpn_len - (p1 + 1));
5510 if (!p2)
5511 p2 = p1 + 1 + strlen(p1 + 1);
5512
5513 if (p2 - (p1 + 1) > 255) {
5514 *p2 = '\0';
5515 memprintf(err, "'%s' : ALPN protocol name too long : '%s'", args[cur_arg], p1 + 1);
5516 return ERR_ALERT | ERR_FATAL;
5517 }
5518
5519 *p1 = p2 - (p1 + 1);
5520 p1 = p2;
5521
5522 if (!*p2)
5523 break;
5524
5525 *(p2++) = '\0';
5526 }
5527 return 0;
5528#else
5529 if (err)
5530 memprintf(err, "'%s' : library does not support TLS ALPN extension", args[cur_arg]);
5531 return ERR_ALERT | ERR_FATAL;
5532#endif
5533}
5534
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005535/* parse the "ssl" bind keyword */
Willy Tarreau4348fad2012-09-20 16:48:07 +02005536static 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 +02005537{
Willy Tarreau71a8c7c2016-12-21 22:04:54 +01005538 conf->xprt = &ssl_sock;
Willy Tarreau4348fad2012-09-20 16:48:07 +02005539 conf->is_ssl = 1;
Emeric Brun76d88952012-10-05 15:47:31 +02005540
5541 if (global.listen_default_ciphers && !conf->ciphers)
5542 conf->ciphers = strdup(global.listen_default_ciphers);
Emeric Brun2c86cbf2014-10-30 15:56:50 +01005543 conf->ssl_options |= global.listen_default_ssloptions;
Emeric Brun76d88952012-10-05 15:47:31 +02005544
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005545 return 0;
5546}
5547
Christopher Faulet31af49d2015-06-09 17:29:50 +02005548/* parse the "generate-certificates" bind keyword */
5549static int bind_parse_generate_certs(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5550{
5551#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
5552 conf->generate_certs = 1;
5553#else
5554 memprintf(err, "%sthis version of openssl cannot generate SSL certificates.\n",
5555 err && *err ? *err : "");
5556#endif
5557 return 0;
5558}
5559
Emmanuel Hocdet65623372013-01-24 17:17:15 +01005560/* parse the "strict-sni" bind keyword */
5561static int bind_parse_strict_sni(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5562{
5563 conf->strict_sni = 1;
5564 return 0;
Nenad Merdanovic05552d42015-02-27 19:56:49 +01005565}
5566
5567/* parse the "tls-ticket-keys" bind keyword */
5568static int bind_parse_tls_ticket_keys(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5569{
5570#if (defined SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB && TLS_TICKETS_NO > 0)
5571 FILE *f;
5572 int i = 0;
5573 char thisline[LINESIZE];
Nenad Merdanovic146defa2015-05-09 08:46:00 +02005574 struct tls_keys_ref *keys_ref;
Nenad Merdanovic05552d42015-02-27 19:56:49 +01005575
5576 if (!*args[cur_arg + 1]) {
5577 if (err)
5578 memprintf(err, "'%s' : missing TLS ticket keys file path", args[cur_arg]);
5579 return ERR_ALERT | ERR_FATAL;
5580 }
5581
Nenad Merdanovic200b0fa2015-05-09 08:46:01 +02005582 keys_ref = tlskeys_ref_lookup(args[cur_arg + 1]);
5583 if(keys_ref) {
5584 conf->keys_ref = keys_ref;
5585 return 0;
5586 }
5587
Vincent Bernat02779b62016-04-03 13:48:43 +02005588 keys_ref = malloc(sizeof(*keys_ref));
Nenad Merdanovic146defa2015-05-09 08:46:00 +02005589 keys_ref->tlskeys = malloc(TLS_TICKETS_NO * sizeof(struct tls_sess_key));
Nenad Merdanovic05552d42015-02-27 19:56:49 +01005590
5591 if ((f = fopen(args[cur_arg + 1], "r")) == NULL) {
5592 if (err)
5593 memprintf(err, "'%s' : unable to load ssl tickets keys file", args[cur_arg+1]);
5594 return ERR_ALERT | ERR_FATAL;
5595 }
5596
Nenad Merdanovic146defa2015-05-09 08:46:00 +02005597 keys_ref->filename = strdup(args[cur_arg + 1]);
5598
Nenad Merdanovic05552d42015-02-27 19:56:49 +01005599 while (fgets(thisline, sizeof(thisline), f) != NULL) {
5600 int len = strlen(thisline);
5601 /* Strip newline characters from the end */
5602 if(thisline[len - 1] == '\n')
5603 thisline[--len] = 0;
5604
5605 if(thisline[len - 1] == '\r')
5606 thisline[--len] = 0;
5607
Nenad Merdanovic146defa2015-05-09 08:46:00 +02005608 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 +01005609 if (err)
5610 memprintf(err, "'%s' : unable to decode base64 key on line %d", args[cur_arg+1], i + 1);
mildis16aa0152016-06-22 17:46:29 +02005611 fclose(f);
Nenad Merdanovic05552d42015-02-27 19:56:49 +01005612 return ERR_ALERT | ERR_FATAL;
5613 }
5614 i++;
5615 }
5616
5617 if (i < TLS_TICKETS_NO) {
5618 if (err)
5619 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 +02005620 fclose(f);
Nenad Merdanovic05552d42015-02-27 19:56:49 +01005621 return ERR_ALERT | ERR_FATAL;
5622 }
5623
5624 fclose(f);
5625
5626 /* Use penultimate key for encryption, handle when TLS_TICKETS_NO = 1 */
Nenad Merdanovic17891152016-03-25 22:16:57 +01005627 i -= 2;
5628 keys_ref->tls_ticket_enc_index = i < 0 ? 0 : i % TLS_TICKETS_NO;
Nenad Merdanovic200b0fa2015-05-09 08:46:01 +02005629 keys_ref->unique_id = -1;
Nenad Merdanovic146defa2015-05-09 08:46:00 +02005630 conf->keys_ref = keys_ref;
Nenad Merdanovic05552d42015-02-27 19:56:49 +01005631
Nenad Merdanovic200b0fa2015-05-09 08:46:01 +02005632 LIST_ADD(&tlskeys_reference, &keys_ref->list);
5633
Nenad Merdanovic05552d42015-02-27 19:56:49 +01005634 return 0;
5635#else
5636 if (err)
5637 memprintf(err, "'%s' : TLS ticket callback extension not supported", args[cur_arg]);
5638 return ERR_ALERT | ERR_FATAL;
5639#endif /* SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB */
Emmanuel Hocdet65623372013-01-24 17:17:15 +01005640}
5641
Emeric Brund94b3fe2012-09-20 18:23:56 +02005642/* parse the "verify" bind keyword */
5643static int bind_parse_verify(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5644{
5645 if (!*args[cur_arg + 1]) {
5646 if (err)
5647 memprintf(err, "'%s' : missing verify method", args[cur_arg]);
5648 return ERR_ALERT | ERR_FATAL;
5649 }
5650
5651 if (strcmp(args[cur_arg + 1], "none") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01005652 conf->verify = SSL_SOCK_VERIFY_NONE;
Emeric Brund94b3fe2012-09-20 18:23:56 +02005653 else if (strcmp(args[cur_arg + 1], "optional") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01005654 conf->verify = SSL_SOCK_VERIFY_OPTIONAL;
Emeric Brund94b3fe2012-09-20 18:23:56 +02005655 else if (strcmp(args[cur_arg + 1], "required") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01005656 conf->verify = SSL_SOCK_VERIFY_REQUIRED;
Emeric Brund94b3fe2012-09-20 18:23:56 +02005657 else {
5658 if (err)
5659 memprintf(err, "'%s' : unknown verify method '%s', only 'none', 'optional', and 'required' are supported\n",
5660 args[cur_arg], args[cur_arg + 1]);
5661 return ERR_ALERT | ERR_FATAL;
5662 }
5663
5664 return 0;
5665}
5666
Willy Tarreau92faadf2012-10-10 23:04:25 +02005667/************** "server" keywords ****************/
5668
Emeric Brunef42d922012-10-11 16:11:36 +02005669/* parse the "ca-file" server keyword */
5670static int srv_parse_ca_file(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5671{
5672 if (!*args[*cur_arg + 1]) {
5673 if (err)
5674 memprintf(err, "'%s' : missing CAfile path", args[*cur_arg]);
5675 return ERR_ALERT | ERR_FATAL;
5676 }
5677
5678 if ((*args[*cur_arg + 1] != '/') && global.ca_base)
5679 memprintf(&newsrv->ssl_ctx.ca_file, "%s/%s", global.ca_base, args[*cur_arg + 1]);
5680 else
5681 memprintf(&newsrv->ssl_ctx.ca_file, "%s", args[*cur_arg + 1]);
5682
5683 return 0;
5684}
5685
Willy Tarreau92faadf2012-10-10 23:04:25 +02005686/* parse the "check-ssl" server keyword */
5687static int srv_parse_check_ssl(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5688{
5689 newsrv->check.use_ssl = 1;
5690 if (global.connect_default_ciphers && !newsrv->ssl_ctx.ciphers)
5691 newsrv->ssl_ctx.ciphers = strdup(global.connect_default_ciphers);
Emeric Brun2c86cbf2014-10-30 15:56:50 +01005692 newsrv->ssl_ctx.options |= global.connect_default_ssloptions;
Willy Tarreau92faadf2012-10-10 23:04:25 +02005693 return 0;
5694}
5695
5696/* parse the "ciphers" server keyword */
5697static int srv_parse_ciphers(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5698{
5699 if (!*args[*cur_arg + 1]) {
5700 memprintf(err, "'%s' : missing cipher suite", args[*cur_arg]);
5701 return ERR_ALERT | ERR_FATAL;
5702 }
5703
5704 free(newsrv->ssl_ctx.ciphers);
5705 newsrv->ssl_ctx.ciphers = strdup(args[*cur_arg + 1]);
5706 return 0;
5707}
5708
Emeric Brunef42d922012-10-11 16:11:36 +02005709/* parse the "crl-file" server keyword */
5710static int srv_parse_crl_file(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5711{
5712#ifndef X509_V_FLAG_CRL_CHECK
5713 if (err)
5714 memprintf(err, "'%s' : library does not support CRL verify", args[*cur_arg]);
5715 return ERR_ALERT | ERR_FATAL;
5716#else
5717 if (!*args[*cur_arg + 1]) {
5718 if (err)
5719 memprintf(err, "'%s' : missing CRLfile path", args[*cur_arg]);
5720 return ERR_ALERT | ERR_FATAL;
5721 }
5722
5723 if ((*args[*cur_arg + 1] != '/') && global.ca_base)
5724 memprintf(&newsrv->ssl_ctx.crl_file, "%s/%s", global.ca_base, args[*cur_arg + 1]);
5725 else
5726 memprintf(&newsrv->ssl_ctx.crl_file, "%s", args[*cur_arg + 1]);
5727
5728 return 0;
5729#endif
5730}
5731
Emeric Bruna7aa3092012-10-26 12:58:00 +02005732/* parse the "crt" server keyword */
5733static int srv_parse_crt(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5734{
5735 if (!*args[*cur_arg + 1]) {
5736 if (err)
5737 memprintf(err, "'%s' : missing certificate file path", args[*cur_arg]);
5738 return ERR_ALERT | ERR_FATAL;
5739 }
5740
5741 if ((*args[*cur_arg + 1] != '/') && global.crt_base)
5742 memprintf(&newsrv->ssl_ctx.client_crt, "%s/%s", global.ca_base, args[*cur_arg + 1]);
5743 else
5744 memprintf(&newsrv->ssl_ctx.client_crt, "%s", args[*cur_arg + 1]);
5745
5746 return 0;
5747}
Emeric Brunef42d922012-10-11 16:11:36 +02005748
Willy Tarreau92faadf2012-10-10 23:04:25 +02005749/* parse the "force-sslv3" server keyword */
5750static int srv_parse_force_sslv3(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5751{
5752 newsrv->ssl_ctx.options |= SRV_SSL_O_USE_SSLV3;
5753 return 0;
5754}
5755
5756/* parse the "force-tlsv10" server keyword */
5757static int srv_parse_force_tlsv10(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5758{
5759 newsrv->ssl_ctx.options |= SRV_SSL_O_USE_TLSV10;
5760 return 0;
5761}
5762
5763/* parse the "force-tlsv11" server keyword */
5764static int srv_parse_force_tlsv11(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5765{
5766#if SSL_OP_NO_TLSv1_1
5767 newsrv->ssl_ctx.options |= SRV_SSL_O_USE_TLSV11;
5768 return 0;
5769#else
5770 if (err)
5771 memprintf(err, "'%s' : library does not support protocol TLSv1.1", args[*cur_arg]);
5772 return ERR_ALERT | ERR_FATAL;
5773#endif
5774}
5775
5776/* parse the "force-tlsv12" server keyword */
5777static int srv_parse_force_tlsv12(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5778{
5779#if SSL_OP_NO_TLSv1_2
5780 newsrv->ssl_ctx.options |= SRV_SSL_O_USE_TLSV12;
5781 return 0;
5782#else
5783 if (err)
5784 memprintf(err, "'%s' : library does not support protocol TLSv1.2", args[*cur_arg]);
5785 return ERR_ALERT | ERR_FATAL;
5786#endif
5787}
5788
Willy Tarreau2a3fb1c2015-02-05 16:47:07 +01005789/* parse the "no-ssl-reuse" server keyword */
5790static int srv_parse_no_ssl_reuse(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5791{
5792 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_REUSE;
5793 return 0;
5794}
5795
Willy Tarreau92faadf2012-10-10 23:04:25 +02005796/* parse the "no-sslv3" server keyword */
5797static int srv_parse_no_sslv3(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5798{
5799 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_SSLV3;
5800 return 0;
5801}
5802
5803/* parse the "no-tlsv10" server keyword */
5804static int srv_parse_no_tlsv10(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5805{
5806 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_TLSV10;
5807 return 0;
5808}
5809
5810/* parse the "no-tlsv11" server keyword */
5811static int srv_parse_no_tlsv11(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5812{
5813 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_TLSV11;
5814 return 0;
5815}
5816
5817/* parse the "no-tlsv12" server keyword */
5818static int srv_parse_no_tlsv12(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5819{
5820 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_TLSV12;
5821 return 0;
5822}
5823
Emeric Brunf9c5c472012-10-11 15:28:34 +02005824/* parse the "no-tls-tickets" server keyword */
5825static int srv_parse_no_tls_tickets(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5826{
5827 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_TLS_TICKETS;
5828 return 0;
5829}
David Safb76832014-05-08 23:42:08 -04005830/* parse the "send-proxy-v2-ssl" server keyword */
5831static int srv_parse_send_proxy_ssl(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5832{
5833 newsrv->pp_opts |= SRV_PP_V2;
5834 newsrv->pp_opts |= SRV_PP_V2_SSL;
5835 return 0;
5836}
5837
5838/* parse the "send-proxy-v2-ssl-cn" server keyword */
5839static int srv_parse_send_proxy_cn(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5840{
5841 newsrv->pp_opts |= SRV_PP_V2;
5842 newsrv->pp_opts |= SRV_PP_V2_SSL;
5843 newsrv->pp_opts |= SRV_PP_V2_SSL_CN;
5844 return 0;
5845}
Emeric Brunf9c5c472012-10-11 15:28:34 +02005846
Willy Tarreau732eac42015-07-09 11:40:25 +02005847/* parse the "sni" server keyword */
5848static int srv_parse_sni(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5849{
5850#ifndef SSL_CTRL_SET_TLSEXT_HOSTNAME
5851 memprintf(err, "'%s' : the current SSL library doesn't support the SNI TLS extension", args[*cur_arg]);
5852 return ERR_ALERT | ERR_FATAL;
5853#else
Cyril Bonté23d19d62016-03-07 22:13:22 +01005854 int idx;
Willy Tarreau732eac42015-07-09 11:40:25 +02005855 struct sample_expr *expr;
5856
5857 if (!*args[*cur_arg + 1]) {
5858 memprintf(err, "'%s' : missing sni expression", args[*cur_arg]);
5859 return ERR_ALERT | ERR_FATAL;
5860 }
5861
Cyril Bonté23d19d62016-03-07 22:13:22 +01005862 idx = (*cur_arg) + 1;
Willy Tarreau732eac42015-07-09 11:40:25 +02005863 proxy->conf.args.ctx = ARGC_SRV;
5864
Cyril Bonté23d19d62016-03-07 22:13:22 +01005865 expr = sample_parse_expr((char **)args, &idx, px->conf.file, px->conf.line, err, &proxy->conf.args);
Willy Tarreau732eac42015-07-09 11:40:25 +02005866 if (!expr) {
5867 memprintf(err, "error detected while parsing sni expression : %s", *err);
5868 return ERR_ALERT | ERR_FATAL;
5869 }
5870
5871 if (!(expr->fetch->val & SMP_VAL_BE_SRV_CON)) {
5872 memprintf(err, "error detected while parsing sni expression : "
5873 " fetch method '%s' extracts information from '%s', none of which is available here.\n",
Cyril Bonté23d19d62016-03-07 22:13:22 +01005874 args[idx-1], sample_src_names(expr->fetch->use));
Willy Tarreau732eac42015-07-09 11:40:25 +02005875 return ERR_ALERT | ERR_FATAL;
5876 }
5877
5878 px->http_needed |= !!(expr->fetch->use & SMP_USE_HTTP_ANY);
5879 newsrv->ssl_ctx.sni = expr;
5880 return 0;
5881#endif
5882}
5883
Willy Tarreau92faadf2012-10-10 23:04:25 +02005884/* parse the "ssl" server keyword */
5885static int srv_parse_ssl(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5886{
5887 newsrv->use_ssl = 1;
5888 if (global.connect_default_ciphers && !newsrv->ssl_ctx.ciphers)
5889 newsrv->ssl_ctx.ciphers = strdup(global.connect_default_ciphers);
5890 return 0;
5891}
5892
Emeric Brunef42d922012-10-11 16:11:36 +02005893/* parse the "verify" server keyword */
5894static int srv_parse_verify(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5895{
5896 if (!*args[*cur_arg + 1]) {
5897 if (err)
5898 memprintf(err, "'%s' : missing verify method", args[*cur_arg]);
5899 return ERR_ALERT | ERR_FATAL;
5900 }
5901
5902 if (strcmp(args[*cur_arg + 1], "none") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01005903 newsrv->ssl_ctx.verify = SSL_SOCK_VERIFY_NONE;
Emeric Brunef42d922012-10-11 16:11:36 +02005904 else if (strcmp(args[*cur_arg + 1], "required") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01005905 newsrv->ssl_ctx.verify = SSL_SOCK_VERIFY_REQUIRED;
Emeric Brunef42d922012-10-11 16:11:36 +02005906 else {
5907 if (err)
5908 memprintf(err, "'%s' : unknown verify method '%s', only 'none' and 'required' are supported\n",
5909 args[*cur_arg], args[*cur_arg + 1]);
5910 return ERR_ALERT | ERR_FATAL;
5911 }
5912
Evan Broderbe554312013-06-27 00:05:25 -07005913 return 0;
5914}
5915
5916/* parse the "verifyhost" server keyword */
5917static int srv_parse_verifyhost(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5918{
5919 if (!*args[*cur_arg + 1]) {
5920 if (err)
5921 memprintf(err, "'%s' : missing hostname to verify against", args[*cur_arg]);
5922 return ERR_ALERT | ERR_FATAL;
5923 }
5924
5925 newsrv->ssl_ctx.verify_host = strdup(args[*cur_arg + 1]);
5926
Emeric Brunef42d922012-10-11 16:11:36 +02005927 return 0;
5928}
5929
Emeric Brun2c86cbf2014-10-30 15:56:50 +01005930/* parse the "ssl-default-bind-options" keyword in global section */
5931static int ssl_parse_default_bind_options(char **args, int section_type, struct proxy *curpx,
5932 struct proxy *defpx, const char *file, int line,
5933 char **err) {
5934 int i = 1;
5935
5936 if (*(args[i]) == 0) {
5937 memprintf(err, "global statement '%s' expects an option as an argument.", args[0]);
5938 return -1;
5939 }
5940 while (*(args[i])) {
5941 if (!strcmp(args[i], "no-sslv3"))
5942 global.listen_default_ssloptions |= BC_SSL_O_NO_SSLV3;
5943 else if (!strcmp(args[i], "no-tlsv10"))
5944 global.listen_default_ssloptions |= BC_SSL_O_NO_TLSV10;
5945 else if (!strcmp(args[i], "no-tlsv11"))
5946 global.listen_default_ssloptions |= BC_SSL_O_NO_TLSV11;
5947 else if (!strcmp(args[i], "no-tlsv12"))
5948 global.listen_default_ssloptions |= BC_SSL_O_NO_TLSV12;
5949 else if (!strcmp(args[i], "force-sslv3"))
5950 global.listen_default_ssloptions |= BC_SSL_O_USE_SSLV3;
5951 else if (!strcmp(args[i], "force-tlsv10"))
5952 global.listen_default_ssloptions |= BC_SSL_O_USE_TLSV10;
5953 else if (!strcmp(args[i], "force-tlsv11")) {
5954#if SSL_OP_NO_TLSv1_1
5955 global.listen_default_ssloptions |= BC_SSL_O_USE_TLSV11;
5956#else
5957 memprintf(err, "'%s' '%s': library does not support protocol TLSv1.1", args[0], args[i]);
5958 return -1;
5959#endif
5960 }
5961 else if (!strcmp(args[i], "force-tlsv12")) {
5962#if SSL_OP_NO_TLSv1_2
5963 global.listen_default_ssloptions |= BC_SSL_O_USE_TLSV12;
5964#else
5965 memprintf(err, "'%s' '%s': library does not support protocol TLSv1.2", args[0], args[i]);
5966 return -1;
5967#endif
5968 }
5969 else if (!strcmp(args[i], "no-tls-tickets"))
5970 global.listen_default_ssloptions |= BC_SSL_O_NO_TLS_TICKETS;
5971 else {
5972 memprintf(err, "unknown option '%s' on global statement '%s'.", args[i], args[0]);
5973 return -1;
5974 }
5975 i++;
5976 }
5977 return 0;
5978}
5979
5980/* parse the "ssl-default-server-options" keyword in global section */
5981static int ssl_parse_default_server_options(char **args, int section_type, struct proxy *curpx,
5982 struct proxy *defpx, const char *file, int line,
5983 char **err) {
5984 int i = 1;
5985
5986 if (*(args[i]) == 0) {
5987 memprintf(err, "global statement '%s' expects an option as an argument.", args[0]);
5988 return -1;
5989 }
5990 while (*(args[i])) {
5991 if (!strcmp(args[i], "no-sslv3"))
5992 global.connect_default_ssloptions |= SRV_SSL_O_NO_SSLV3;
5993 else if (!strcmp(args[i], "no-tlsv10"))
5994 global.connect_default_ssloptions |= SRV_SSL_O_NO_TLSV10;
5995 else if (!strcmp(args[i], "no-tlsv11"))
5996 global.connect_default_ssloptions |= SRV_SSL_O_NO_TLSV11;
5997 else if (!strcmp(args[i], "no-tlsv12"))
5998 global.connect_default_ssloptions |= SRV_SSL_O_NO_TLSV12;
5999 else if (!strcmp(args[i], "force-sslv3"))
6000 global.connect_default_ssloptions |= SRV_SSL_O_USE_SSLV3;
6001 else if (!strcmp(args[i], "force-tlsv10"))
6002 global.connect_default_ssloptions |= SRV_SSL_O_USE_TLSV10;
6003 else if (!strcmp(args[i], "force-tlsv11")) {
6004#if SSL_OP_NO_TLSv1_1
6005 global.connect_default_ssloptions |= SRV_SSL_O_USE_TLSV11;
6006#else
6007 memprintf(err, "'%s' '%s': library does not support protocol TLSv1.1", args[0], args[i]);
6008 return -1;
6009#endif
6010 }
6011 else if (!strcmp(args[i], "force-tlsv12")) {
6012#if SSL_OP_NO_TLSv1_2
6013 global.connect_default_ssloptions |= SRV_SSL_O_USE_TLSV12;
6014#else
6015 memprintf(err, "'%s' '%s': library does not support protocol TLSv1.2", args[0], args[i]);
6016 return -1;
6017#endif
6018 }
6019 else if (!strcmp(args[i], "no-tls-tickets"))
6020 global.connect_default_ssloptions |= SRV_SSL_O_NO_TLS_TICKETS;
6021 else {
6022 memprintf(err, "unknown option '%s' on global statement '%s'.", args[i], args[0]);
6023 return -1;
6024 }
6025 i++;
6026 }
6027 return 0;
6028}
6029
Willy Tarreau8c3b0fd2016-12-21 22:44:46 +01006030/* parse the "ca-base" / "crt-base" keywords in global section.
6031 * Returns <0 on alert, >0 on warning, 0 on success.
6032 */
6033static int ssl_parse_global_ca_crt_base(char **args, int section_type, struct proxy *curpx,
6034 struct proxy *defpx, const char *file, int line,
6035 char **err)
6036{
6037 char **target;
6038
6039 target = (args[0][1] == 'a') ? &global.ca_base : &global.crt_base;
6040
6041 if (too_many_args(1, args, err, NULL))
6042 return -1;
6043
6044 if (*target) {
6045 memprintf(err, "'%s' already specified.", args[0]);
6046 return -1;
6047 }
6048
6049 if (*(args[1]) == 0) {
6050 memprintf(err, "global statement '%s' expects a directory path as an argument.", args[0]);
6051 return -1;
6052 }
6053 *target = strdup(args[1]);
6054 return 0;
6055}
6056
Willy Tarreauf22e9682016-12-21 23:23:19 +01006057/* parse the "ssl-default-bind-ciphers" / "ssl-default-server-ciphers" keywords
6058 * in global section. Returns <0 on alert, >0 on warning, 0 on success.
6059 */
6060static int ssl_parse_global_ciphers(char **args, int section_type, struct proxy *curpx,
6061 struct proxy *defpx, const char *file, int line,
6062 char **err)
6063{
6064 char **target;
6065
6066 target = (args[0][12] == 'b') ? &global.listen_default_ciphers : &global.connect_default_ciphers;
6067
6068 if (too_many_args(1, args, err, NULL))
6069 return -1;
6070
6071 if (*(args[1]) == 0) {
6072 memprintf(err, "global statement '%s' expects a cipher suite as an argument.", args[0]);
6073 return -1;
6074 }
6075
6076 free(*target);
6077 *target = strdup(args[1]);
6078 return 0;
6079}
6080
Willy Tarreau9ceda382016-12-21 23:13:03 +01006081/* parse various global tune.ssl settings consisting in positive integers.
6082 * Returns <0 on alert, >0 on warning, 0 on success.
6083 */
6084static int ssl_parse_global_int(char **args, int section_type, struct proxy *curpx,
6085 struct proxy *defpx, const char *file, int line,
6086 char **err)
6087{
6088 int *target;
6089
6090 if (strcmp(args[0], "tune.ssl.cachesize") == 0)
6091 target = &global.tune.sslcachesize;
6092 else if (strcmp(args[0], "tune.ssl.maxrecord") == 0)
6093 target = (int *)&global.tune.ssl_max_record;
6094 else if (strcmp(args[0], "tune.ssl.ssl-ctx-cache-size") == 0)
6095 target = &global.tune.ssl_ctx_cache;
Willy Tarreau0bea58d2016-12-21 23:17:25 +01006096 else if (strcmp(args[0], "maxsslconn") == 0)
6097 target = &global.maxsslconn;
Willy Tarreau9ceda382016-12-21 23:13:03 +01006098 else {
6099 memprintf(err, "'%s' keyword not unhandled (please report this bug).", args[0]);
6100 return -1;
6101 }
6102
6103 if (too_many_args(1, args, err, NULL))
6104 return -1;
6105
6106 if (*(args[1]) == 0) {
6107 memprintf(err, "'%s' expects an integer argument.", args[0]);
6108 return -1;
6109 }
6110
6111 *target = atoi(args[1]);
6112 if (*target < 0) {
6113 memprintf(err, "'%s' expects a positive numeric value.", args[0]);
6114 return -1;
6115 }
6116 return 0;
6117}
6118
6119/* parse "ssl.force-private-cache".
6120 * Returns <0 on alert, >0 on warning, 0 on success.
6121 */
6122static int ssl_parse_global_private_cache(char **args, int section_type, struct proxy *curpx,
6123 struct proxy *defpx, const char *file, int line,
6124 char **err)
6125{
6126 if (too_many_args(0, args, err, NULL))
6127 return -1;
6128
6129 global.tune.sslprivatecache = 1;
6130 return 0;
6131}
6132
6133/* parse "ssl.lifetime".
6134 * Returns <0 on alert, >0 on warning, 0 on success.
6135 */
6136static int ssl_parse_global_lifetime(char **args, int section_type, struct proxy *curpx,
6137 struct proxy *defpx, const char *file, int line,
6138 char **err)
6139{
6140 const char *res;
6141
6142 if (too_many_args(1, args, err, NULL))
6143 return -1;
6144
6145 if (*(args[1]) == 0) {
6146 memprintf(err, "'%s' expects ssl sessions <lifetime> in seconds as argument.", args[0]);
6147 return -1;
6148 }
6149
6150 res = parse_time_err(args[1], &global.tune.ssllifetime, TIME_UNIT_S);
6151 if (res) {
6152 memprintf(err, "unexpected character '%c' in argument to <%s>.", *res, args[0]);
6153 return -1;
6154 }
6155 return 0;
6156}
6157
6158#ifndef OPENSSL_NO_DH
Willy Tarreau14e36a12016-12-21 23:28:13 +01006159/* parse "ssl-dh-param-file".
6160 * Returns <0 on alert, >0 on warning, 0 on success.
6161 */
6162static int ssl_parse_global_dh_param_file(char **args, int section_type, struct proxy *curpx,
6163 struct proxy *defpx, const char *file, int line,
6164 char **err)
6165{
6166 if (too_many_args(1, args, err, NULL))
6167 return -1;
6168
6169 if (*(args[1]) == 0) {
6170 memprintf(err, "'%s' expects a file path as an argument.", args[0]);
6171 return -1;
6172 }
6173
6174 if (ssl_sock_load_global_dh_param_from_file(args[1])) {
6175 memprintf(err, "'%s': unable to load DH parameters from file <%s>.", args[0], args[1]);
6176 return -1;
6177 }
6178 return 0;
6179}
6180
Willy Tarreau9ceda382016-12-21 23:13:03 +01006181/* parse "ssl.default-dh-param".
6182 * Returns <0 on alert, >0 on warning, 0 on success.
6183 */
6184static int ssl_parse_global_default_dh(char **args, int section_type, struct proxy *curpx,
6185 struct proxy *defpx, const char *file, int line,
6186 char **err)
6187{
6188 if (too_many_args(1, args, err, NULL))
6189 return -1;
6190
6191 if (*(args[1]) == 0) {
6192 memprintf(err, "'%s' expects an integer argument.", args[0]);
6193 return -1;
6194 }
6195
6196 global.tune.ssl_default_dh_param = atoi(args[1]);
6197 if (global.tune.ssl_default_dh_param < 1024) {
6198 memprintf(err, "'%s' expects a value >= 1024.", args[0]);
6199 return -1;
6200 }
6201 return 0;
6202}
6203#endif
6204
6205
William Lallemand32af2032016-10-29 18:09:35 +02006206/* This function is used with TLS ticket keys management. It permits to browse
6207 * each reference. The variable <getnext> must contain the current node,
6208 * <end> point to the root node.
6209 */
6210#if (defined SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB && TLS_TICKETS_NO > 0)
6211static inline
6212struct tls_keys_ref *tlskeys_list_get_next(struct tls_keys_ref *getnext, struct list *end)
6213{
6214 struct tls_keys_ref *ref = getnext;
6215
6216 while (1) {
6217
6218 /* Get next list entry. */
6219 ref = LIST_NEXT(&ref->list, struct tls_keys_ref *, list);
6220
6221 /* If the entry is the last of the list, return NULL. */
6222 if (&ref->list == end)
6223 return NULL;
6224
6225 return ref;
6226 }
6227}
6228
6229static inline
6230struct tls_keys_ref *tlskeys_ref_lookup_ref(const char *reference)
6231{
6232 int id;
6233 char *error;
6234
6235 /* If the reference starts by a '#', this is numeric id. */
6236 if (reference[0] == '#') {
6237 /* Try to convert the numeric id. If the conversion fails, the lookup fails. */
6238 id = strtol(reference + 1, &error, 10);
6239 if (*error != '\0')
6240 return NULL;
6241
6242 /* Perform the unique id lookup. */
6243 return tlskeys_ref_lookupid(id);
6244 }
6245
6246 /* Perform the string lookup. */
6247 return tlskeys_ref_lookup(reference);
6248}
6249#endif
6250
6251
6252#if (defined SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB && TLS_TICKETS_NO > 0)
6253
6254static int cli_io_handler_tlskeys_files(struct appctx *appctx);
6255
6256static inline int cli_io_handler_tlskeys_entries(struct appctx *appctx) {
6257 return cli_io_handler_tlskeys_files(appctx);
6258}
6259
Willy Tarreauf5f26e82016-12-16 18:47:27 +01006260/* dumps all tls keys. Relies on cli.i0 (non-null = only list file names), cli.i1
6261 * (next index to be dumped), and cli.p0 (next key reference).
6262 */
William Lallemand32af2032016-10-29 18:09:35 +02006263static int cli_io_handler_tlskeys_files(struct appctx *appctx) {
6264
6265 struct stream_interface *si = appctx->owner;
6266
6267 switch (appctx->st2) {
6268 case STAT_ST_INIT:
6269 /* Display the column headers. If the message cannot be sent,
6270 * quit the fucntion with returning 0. The function is called
6271 * later and restart at the state "STAT_ST_INIT".
6272 */
6273 chunk_reset(&trash);
6274
6275 if (appctx->io_handler == cli_io_handler_tlskeys_entries)
6276 chunk_appendf(&trash, "# id secret\n");
6277 else
6278 chunk_appendf(&trash, "# id (file)\n");
6279
6280 if (bi_putchk(si_ic(si), &trash) == -1) {
6281 si_applet_cant_put(si);
6282 return 0;
6283 }
6284
William Lallemand32af2032016-10-29 18:09:35 +02006285 /* Now, we start the browsing of the references lists.
6286 * Note that the following call to LIST_ELEM return bad pointer. The only
6287 * available field of this pointer is <list>. It is used with the function
6288 * tlskeys_list_get_next() for retruning the first available entry
6289 */
Willy Tarreauf5f26e82016-12-16 18:47:27 +01006290 if (appctx->ctx.cli.p0 == NULL) {
6291 appctx->ctx.cli.p0 = LIST_ELEM(&tlskeys_reference, struct tls_keys_ref *, list);
6292 appctx->ctx.cli.p0 = tlskeys_list_get_next(appctx->ctx.cli.p0, &tlskeys_reference);
William Lallemand32af2032016-10-29 18:09:35 +02006293 }
6294
6295 appctx->st2 = STAT_ST_LIST;
6296 /* fall through */
6297
6298 case STAT_ST_LIST:
Willy Tarreauf5f26e82016-12-16 18:47:27 +01006299 while (appctx->ctx.cli.p0) {
6300 struct tls_keys_ref *ref = appctx->ctx.cli.p0;
6301 int head = ref->tls_ticket_enc_index;
William Lallemand32af2032016-10-29 18:09:35 +02006302
6303 chunk_reset(&trash);
Willy Tarreauf5f26e82016-12-16 18:47:27 +01006304 if (appctx->io_handler == cli_io_handler_tlskeys_entries && appctx->ctx.cli.i1 == 0)
William Lallemand32af2032016-10-29 18:09:35 +02006305 chunk_appendf(&trash, "# ");
Willy Tarreauf5f26e82016-12-16 18:47:27 +01006306
6307 if (appctx->ctx.cli.i1 == 0)
6308 chunk_appendf(&trash, "%d (%s)\n", ref->unique_id, ref->filename);
6309
William Lallemand32af2032016-10-29 18:09:35 +02006310 if (appctx->io_handler == cli_io_handler_tlskeys_entries) {
Willy Tarreauf5f26e82016-12-16 18:47:27 +01006311 while (appctx->ctx.cli.i1 < TLS_TICKETS_NO) {
William Lallemand32af2032016-10-29 18:09:35 +02006312 struct chunk *t2 = get_trash_chunk();
6313
6314 chunk_reset(t2);
6315 /* should never fail here because we dump only a key in the t2 buffer */
Willy Tarreauf5f26e82016-12-16 18:47:27 +01006316 t2->len = a2base64((char *)(ref->tlskeys + (head + 2 + appctx->ctx.cli.i1) % TLS_TICKETS_NO),
William Lallemand32af2032016-10-29 18:09:35 +02006317 sizeof(struct tls_sess_key), t2->str, t2->size);
Willy Tarreauf5f26e82016-12-16 18:47:27 +01006318 chunk_appendf(&trash, "%d.%d %s\n", ref->unique_id, appctx->ctx.cli.i1, t2->str);
William Lallemand32af2032016-10-29 18:09:35 +02006319
6320 if (bi_putchk(si_ic(si), &trash) == -1) {
6321 /* let's try again later from this stream. We add ourselves into
6322 * this stream's users so that it can remove us upon termination.
6323 */
6324 si_applet_cant_put(si);
6325 return 0;
6326 }
Willy Tarreauf5f26e82016-12-16 18:47:27 +01006327 appctx->ctx.cli.i1++;
William Lallemand32af2032016-10-29 18:09:35 +02006328 }
Willy Tarreauf5f26e82016-12-16 18:47:27 +01006329 appctx->ctx.cli.i1 = 0;
William Lallemand32af2032016-10-29 18:09:35 +02006330 }
6331 if (bi_putchk(si_ic(si), &trash) == -1) {
6332 /* let's try again later from this stream. We add ourselves into
6333 * this stream's users so that it can remove us upon termination.
6334 */
6335 si_applet_cant_put(si);
6336 return 0;
6337 }
6338
Willy Tarreauf5f26e82016-12-16 18:47:27 +01006339 if (appctx->ctx.cli.i0 == 0) /* don't display everything if not necessary */
William Lallemand32af2032016-10-29 18:09:35 +02006340 break;
6341
6342 /* get next list entry and check the end of the list */
Willy Tarreauf5f26e82016-12-16 18:47:27 +01006343 appctx->ctx.cli.p0 = tlskeys_list_get_next(appctx->ctx.cli.p0, &tlskeys_reference);
William Lallemand32af2032016-10-29 18:09:35 +02006344 }
6345
6346 appctx->st2 = STAT_ST_FIN;
6347 /* fall through */
6348
6349 default:
6350 appctx->st2 = STAT_ST_FIN;
6351 return 1;
6352 }
6353 return 0;
6354}
6355
6356#endif
6357
Willy Tarreauf5f26e82016-12-16 18:47:27 +01006358/* sets cli.i0 to non-zero if only file lists should be dumped */
William Lallemand32af2032016-10-29 18:09:35 +02006359static int cli_parse_show_tlskeys(char **args, struct appctx *appctx, void *private)
6360{
William Lallemand32af2032016-10-29 18:09:35 +02006361 /* no parameter, shows only file list */
6362 if (!*args[2]) {
Willy Tarreauf5f26e82016-12-16 18:47:27 +01006363 appctx->ctx.cli.i0 = 1;
William Lallemand32af2032016-10-29 18:09:35 +02006364 appctx->io_handler = cli_io_handler_tlskeys_files;
Willy Tarreau3067bfa2016-12-05 14:50:15 +01006365 return 0;
William Lallemand32af2032016-10-29 18:09:35 +02006366 }
6367
6368 if (args[2][0] == '*') {
6369 /* list every TLS ticket keys */
Willy Tarreauf5f26e82016-12-16 18:47:27 +01006370 appctx->ctx.cli.i0 = 1;
William Lallemand32af2032016-10-29 18:09:35 +02006371 } else {
Willy Tarreauf5f26e82016-12-16 18:47:27 +01006372 appctx->ctx.cli.p0 = tlskeys_ref_lookup_ref(args[2]);
6373 if (!appctx->ctx.cli.p0) {
William Lallemand32af2032016-10-29 18:09:35 +02006374 appctx->ctx.cli.msg = "'show tls-keys' unable to locate referenced filename\n";
Willy Tarreau3b6e5472016-11-24 15:53:53 +01006375 appctx->st0 = CLI_ST_PRINT;
William Lallemand32af2032016-10-29 18:09:35 +02006376 return 1;
6377 }
6378 }
William Lallemand32af2032016-10-29 18:09:35 +02006379 appctx->io_handler = cli_io_handler_tlskeys_entries;
Willy Tarreau3067bfa2016-12-05 14:50:15 +01006380 return 0;
William Lallemand32af2032016-10-29 18:09:35 +02006381}
6382
6383
6384static int cli_parse_set_tlskeys(char **args, struct appctx *appctx, void *private)
6385{
Willy Tarreauf5f26e82016-12-16 18:47:27 +01006386 struct tls_keys_ref *ref;
6387
William Lallemand32af2032016-10-29 18:09:35 +02006388 /* Expect two parameters: the filename and the new new TLS key in encoding */
6389 if (!*args[3] || !*args[4]) {
6390 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 +01006391 appctx->st0 = CLI_ST_PRINT;
William Lallemand32af2032016-10-29 18:09:35 +02006392 return 1;
6393 }
6394
Willy Tarreauf5f26e82016-12-16 18:47:27 +01006395 ref = tlskeys_ref_lookup_ref(args[3]);
6396 if (!ref) {
William Lallemand32af2032016-10-29 18:09:35 +02006397 appctx->ctx.cli.msg = "'set ssl tls-key' unable to locate referenced filename\n";
Willy Tarreau3b6e5472016-11-24 15:53:53 +01006398 appctx->st0 = CLI_ST_PRINT;
William Lallemand32af2032016-10-29 18:09:35 +02006399 return 1;
6400 }
6401
6402 trash.len = base64dec(args[4], strlen(args[4]), trash.str, trash.size);
6403 if (trash.len != sizeof(struct tls_sess_key)) {
6404 appctx->ctx.cli.msg = "'set ssl tls-key' received invalid base64 encoded TLS key.\n";
Willy Tarreau3b6e5472016-11-24 15:53:53 +01006405 appctx->st0 = CLI_ST_PRINT;
William Lallemand32af2032016-10-29 18:09:35 +02006406 return 1;
6407 }
6408
Willy Tarreauf5f26e82016-12-16 18:47:27 +01006409 memcpy(ref->tlskeys + ((ref->tls_ticket_enc_index + 2) % TLS_TICKETS_NO), trash.str, trash.len);
6410 ref->tls_ticket_enc_index = (ref->tls_ticket_enc_index + 1) % TLS_TICKETS_NO;
William Lallemand32af2032016-10-29 18:09:35 +02006411
6412 appctx->ctx.cli.msg = "TLS ticket key updated!";
Willy Tarreau3b6e5472016-11-24 15:53:53 +01006413 appctx->st0 = CLI_ST_PRINT;
William Lallemand32af2032016-10-29 18:09:35 +02006414 return 1;
6415
6416}
6417
6418static int cli_parse_set_ocspresponse(char **args, struct appctx *appctx, void *private)
6419{
6420#if (defined SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB && !defined OPENSSL_NO_OCSP)
6421 char *err = NULL;
6422
6423 /* Expect one parameter: the new response in base64 encoding */
6424 if (!*args[3]) {
6425 appctx->ctx.cli.msg = "'set ssl ocsp-response' expects response in base64 encoding.\n";
Willy Tarreau3b6e5472016-11-24 15:53:53 +01006426 appctx->st0 = CLI_ST_PRINT;
William Lallemand32af2032016-10-29 18:09:35 +02006427 return 1;
6428 }
6429
6430 trash.len = base64dec(args[3], strlen(args[3]), trash.str, trash.size);
6431 if (trash.len < 0) {
6432 appctx->ctx.cli.msg = "'set ssl ocsp-response' received invalid base64 encoded response.\n";
Willy Tarreau3b6e5472016-11-24 15:53:53 +01006433 appctx->st0 = CLI_ST_PRINT;
William Lallemand32af2032016-10-29 18:09:35 +02006434 return 1;
6435 }
6436
6437 if (ssl_sock_update_ocsp_response(&trash, &err)) {
6438 if (err) {
6439 memprintf(&err, "%s.\n", err);
6440 appctx->ctx.cli.err = err;
Willy Tarreau3b6e5472016-11-24 15:53:53 +01006441 appctx->st0 = CLI_ST_PRINT_FREE;
William Lallemand32af2032016-10-29 18:09:35 +02006442 }
6443 return 1;
6444 }
6445 appctx->ctx.cli.msg = "OCSP Response updated!";
Willy Tarreau3b6e5472016-11-24 15:53:53 +01006446 appctx->st0 = CLI_ST_PRINT;
William Lallemand32af2032016-10-29 18:09:35 +02006447 return 1;
6448#else
6449 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 +01006450 appctx->st0 = CLI_ST_PRINT;
William Lallemand32af2032016-10-29 18:09:35 +02006451 return 1;
6452#endif
6453
6454}
6455
6456/* register cli keywords */
6457static struct cli_kw_list cli_kws = {{ },{
6458#if (defined SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB && TLS_TICKETS_NO > 0)
6459 { { "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 },
6460 { { "set", "ssl", "tls-keys", NULL }, NULL, cli_parse_set_tlskeys, NULL },
6461 { { "set", "ssl", "ocsp-response", NULL }, NULL, cli_parse_set_ocspresponse, NULL },
6462#endif
6463 { { NULL }, NULL, NULL, NULL }
6464}};
6465
6466
6467
Willy Tarreau7875d092012-09-10 08:20:03 +02006468/* Note: must not be declared <const> as its list will be overwritten.
6469 * Please take care of keeping this list alphabetically sorted.
6470 */
Willy Tarreaudc13c112013-06-21 23:16:39 +02006471static struct sample_fetch_kw_list sample_fetch_keywords = {ILH, {
Emeric Brun645ae792014-04-30 14:21:06 +02006472 { "ssl_bc", smp_fetch_ssl_fc, 0, NULL, SMP_T_BOOL, SMP_USE_L5SRV },
Thierry FOURNIER07ee64e2015-07-06 23:43:03 +02006473 { "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 +02006474 { "ssl_bc_cipher", smp_fetch_ssl_fc_cipher, 0, NULL, SMP_T_STR, SMP_USE_L5SRV },
6475 { "ssl_bc_protocol", smp_fetch_ssl_fc_protocol, 0, NULL, SMP_T_STR, SMP_USE_L5SRV },
Emeric Brunb73a9b02014-04-30 18:49:19 +02006476 { "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 +02006477 { "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 +02006478 { "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 +02006479 { "ssl_c_ca_err", smp_fetch_ssl_c_ca_err, 0, NULL, SMP_T_SINT, SMP_USE_L5CLI },
6480 { "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 +01006481 { "ssl_c_der", smp_fetch_ssl_x_der, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Thierry FOURNIER07ee64e2015-07-06 23:43:03 +02006482 { "ssl_c_err", smp_fetch_ssl_c_err, 0, NULL, SMP_T_SINT, SMP_USE_L5CLI },
Emeric Brunba841a12014-04-30 17:05:08 +02006483 { "ssl_c_i_dn", smp_fetch_ssl_x_i_dn, ARG2(0,STR,SINT), NULL, SMP_T_STR, SMP_USE_L5CLI },
6484 { "ssl_c_key_alg", smp_fetch_ssl_x_key_alg, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
6485 { "ssl_c_notafter", smp_fetch_ssl_x_notafter, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
6486 { "ssl_c_notbefore", smp_fetch_ssl_x_notbefore, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
6487 { "ssl_c_sig_alg", smp_fetch_ssl_x_sig_alg, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
6488 { "ssl_c_s_dn", smp_fetch_ssl_x_s_dn, ARG2(0,STR,SINT), NULL, SMP_T_STR, SMP_USE_L5CLI },
6489 { "ssl_c_serial", smp_fetch_ssl_x_serial, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
6490 { "ssl_c_sha1", smp_fetch_ssl_x_sha1, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Willy Tarreau80aca902013-01-07 15:42:20 +01006491 { "ssl_c_used", smp_fetch_ssl_c_used, 0, NULL, SMP_T_BOOL, SMP_USE_L5CLI },
Thierry FOURNIER07ee64e2015-07-06 23:43:03 +02006492 { "ssl_c_verify", smp_fetch_ssl_c_verify, 0, NULL, SMP_T_SINT, SMP_USE_L5CLI },
6493 { "ssl_c_version", smp_fetch_ssl_x_version, 0, NULL, SMP_T_SINT, SMP_USE_L5CLI },
Emeric Brun43e79582014-10-29 19:03:26 +01006494 { "ssl_f_der", smp_fetch_ssl_x_der, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Emeric Brunba841a12014-04-30 17:05:08 +02006495 { "ssl_f_i_dn", smp_fetch_ssl_x_i_dn, ARG2(0,STR,SINT), NULL, SMP_T_STR, SMP_USE_L5CLI },
6496 { "ssl_f_key_alg", smp_fetch_ssl_x_key_alg, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
6497 { "ssl_f_notafter", smp_fetch_ssl_x_notafter, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
6498 { "ssl_f_notbefore", smp_fetch_ssl_x_notbefore, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
6499 { "ssl_f_sig_alg", smp_fetch_ssl_x_sig_alg, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
6500 { "ssl_f_s_dn", smp_fetch_ssl_x_s_dn, ARG2(0,STR,SINT), NULL, SMP_T_STR, SMP_USE_L5CLI },
6501 { "ssl_f_serial", smp_fetch_ssl_x_serial, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Emeric Brun55f4fa82014-04-30 17:11:25 +02006502 { "ssl_f_sha1", smp_fetch_ssl_x_sha1, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Thierry FOURNIER07ee64e2015-07-06 23:43:03 +02006503 { "ssl_f_version", smp_fetch_ssl_x_version, 0, NULL, SMP_T_SINT, SMP_USE_L5CLI },
Willy Tarreau80aca902013-01-07 15:42:20 +01006504 { "ssl_fc", smp_fetch_ssl_fc, 0, NULL, SMP_T_BOOL, SMP_USE_L5CLI },
Thierry FOURNIER07ee64e2015-07-06 23:43:03 +02006505 { "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 +01006506 { "ssl_fc_cipher", smp_fetch_ssl_fc_cipher, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Willy Tarreau80aca902013-01-07 15:42:20 +01006507 { "ssl_fc_has_crt", smp_fetch_ssl_fc_has_crt, 0, NULL, SMP_T_BOOL, SMP_USE_L5CLI },
6508 { "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 +02006509 { "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 +02006510#ifdef OPENSSL_NPN_NEGOTIATED
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01006511 { "ssl_fc_npn", smp_fetch_ssl_fc_npn, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Willy Tarreaua33c6542012-10-15 13:19:06 +02006512#endif
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01006513#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01006514 { "ssl_fc_alpn", smp_fetch_ssl_fc_alpn, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Willy Tarreauab861d32013-04-02 02:30:41 +02006515#endif
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01006516 { "ssl_fc_protocol", smp_fetch_ssl_fc_protocol, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Emeric Brunb73a9b02014-04-30 18:49:19 +02006517 { "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 +02006518 { "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 +01006519 { "ssl_fc_session_id", smp_fetch_ssl_fc_session_id, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
6520 { "ssl_fc_sni", smp_fetch_ssl_fc_sni, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Willy Tarreau7875d092012-09-10 08:20:03 +02006521 { NULL, NULL, 0, 0, 0 },
6522}};
6523
6524/* Note: must not be declared <const> as its list will be overwritten.
6525 * Please take care of keeping this list alphabetically sorted.
6526 */
Willy Tarreaudc13c112013-06-21 23:16:39 +02006527static struct acl_kw_list acl_kws = {ILH, {
Thierry FOURNIERc5a4e982014-03-05 16:07:08 +01006528 { "ssl_fc_sni_end", "ssl_fc_sni", PAT_MATCH_END },
6529 { "ssl_fc_sni_reg", "ssl_fc_sni", PAT_MATCH_REG },
Willy Tarreau8ed669b2013-01-11 15:49:37 +01006530 { /* END */ },
Willy Tarreau7875d092012-09-10 08:20:03 +02006531}};
6532
Willy Tarreau79eeafa2012-09-14 07:53:05 +02006533/* Note: must not be declared <const> as its list will be overwritten.
6534 * Please take care of keeping this list alphabetically sorted, doing so helps
6535 * all code contributors.
6536 * Optional keywords are also declared with a NULL ->parse() function so that
6537 * the config parser can report an appropriate error when a known keyword was
6538 * not enabled.
6539 */
Willy Tarreau51fb7652012-09-18 18:24:39 +02006540static struct bind_kw_list bind_kws = { "SSL", { }, {
Nenad Merdanovic05552d42015-02-27 19:56:49 +01006541 { "alpn", bind_parse_alpn, 1 }, /* set ALPN supported protocols */
6542 { "ca-file", bind_parse_ca_file, 1 }, /* set CAfile to process verify on client cert */
6543 { "ca-ignore-err", bind_parse_ignore_err, 1 }, /* set error IDs to ignore on verify depth > 0 */
Christopher Faulet31af49d2015-06-09 17:29:50 +02006544 { "ca-sign-file", bind_parse_ca_sign_file, 1 }, /* set CAFile used to generate and sign server certs */
6545 { "ca-sign-pass", bind_parse_ca_sign_pass, 1 }, /* set CAKey passphrase */
Nenad Merdanovic05552d42015-02-27 19:56:49 +01006546 { "ciphers", bind_parse_ciphers, 1 }, /* set SSL cipher suite */
6547 { "crl-file", bind_parse_crl_file, 1 }, /* set certificat revocation list file use on client cert verify */
6548 { "crt", bind_parse_crt, 1 }, /* load SSL certificates from this location */
6549 { "crt-ignore-err", bind_parse_ignore_err, 1 }, /* set error IDs to ingore on verify depth == 0 */
6550 { "crt-list", bind_parse_crt_list, 1 }, /* load a list of crt from this location */
6551 { "ecdhe", bind_parse_ecdhe, 1 }, /* defines named curve for elliptic curve Diffie-Hellman */
6552 { "force-sslv3", bind_parse_force_sslv3, 0 }, /* force SSLv3 */
6553 { "force-tlsv10", bind_parse_force_tlsv10, 0 }, /* force TLSv10 */
6554 { "force-tlsv11", bind_parse_force_tlsv11, 0 }, /* force TLSv11 */
6555 { "force-tlsv12", bind_parse_force_tlsv12, 0 }, /* force TLSv12 */
Christopher Faulet31af49d2015-06-09 17:29:50 +02006556 { "generate-certificates", bind_parse_generate_certs, 0 }, /* enable the server certificates generation */
Nenad Merdanovic05552d42015-02-27 19:56:49 +01006557 { "no-sslv3", bind_parse_no_sslv3, 0 }, /* disable SSLv3 */
6558 { "no-tlsv10", bind_parse_no_tlsv10, 0 }, /* disable TLSv10 */
6559 { "no-tlsv11", bind_parse_no_tlsv11, 0 }, /* disable TLSv11 */
6560 { "no-tlsv12", bind_parse_no_tlsv12, 0 }, /* disable TLSv12 */
6561 { "no-tls-tickets", bind_parse_no_tls_tickets, 0 }, /* disable session resumption tickets */
6562 { "ssl", bind_parse_ssl, 0 }, /* enable SSL processing */
6563 { "strict-sni", bind_parse_strict_sni, 0 }, /* refuse negotiation if sni doesn't match a certificate */
6564 { "tls-ticket-keys", bind_parse_tls_ticket_keys, 1 }, /* set file to load TLS ticket keys from */
6565 { "verify", bind_parse_verify, 1 }, /* set SSL verify method */
6566 { "npn", bind_parse_npn, 1 }, /* set NPN supported protocols */
Willy Tarreau79eeafa2012-09-14 07:53:05 +02006567 { NULL, NULL, 0 },
6568}};
Emeric Brun46591952012-05-18 15:47:34 +02006569
Willy Tarreau92faadf2012-10-10 23:04:25 +02006570/* Note: must not be declared <const> as its list will be overwritten.
6571 * Please take care of keeping this list alphabetically sorted, doing so helps
6572 * all code contributors.
6573 * Optional keywords are also declared with a NULL ->parse() function so that
6574 * the config parser can report an appropriate error when a known keyword was
6575 * not enabled.
6576 */
6577static struct srv_kw_list srv_kws = { "SSL", { }, {
Emeric Brunef42d922012-10-11 16:11:36 +02006578 { "ca-file", srv_parse_ca_file, 1, 0 }, /* set CAfile to process verify server cert */
Emeric Brunecc91fe2012-10-11 15:05:10 +02006579 { "check-ssl", srv_parse_check_ssl, 0, 0 }, /* enable SSL for health checks */
6580 { "ciphers", srv_parse_ciphers, 1, 0 }, /* select the cipher suite */
Emeric Brunef42d922012-10-11 16:11:36 +02006581 { "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 +02006582 { "crt", srv_parse_crt, 1, 0 }, /* set client certificate */
Emeric Brunecc91fe2012-10-11 15:05:10 +02006583 { "force-sslv3", srv_parse_force_sslv3, 0, 0 }, /* force SSLv3 */
6584 { "force-tlsv10", srv_parse_force_tlsv10, 0, 0 }, /* force TLSv10 */
6585 { "force-tlsv11", srv_parse_force_tlsv11, 0, 0 }, /* force TLSv11 */
6586 { "force-tlsv12", srv_parse_force_tlsv12, 0, 0 }, /* force TLSv12 */
Willy Tarreau2a3fb1c2015-02-05 16:47:07 +01006587 { "no-ssl-reuse", srv_parse_no_ssl_reuse, 0, 0 }, /* disable session reuse */
Emeric Brunecc91fe2012-10-11 15:05:10 +02006588 { "no-sslv3", srv_parse_no_sslv3, 0, 0 }, /* disable SSLv3 */
6589 { "no-tlsv10", srv_parse_no_tlsv10, 0, 0 }, /* disable TLSv10 */
6590 { "no-tlsv11", srv_parse_no_tlsv11, 0, 0 }, /* disable TLSv11 */
6591 { "no-tlsv12", srv_parse_no_tlsv12, 0, 0 }, /* disable TLSv12 */
Emeric Brunf9c5c472012-10-11 15:28:34 +02006592 { "no-tls-tickets", srv_parse_no_tls_tickets, 0, 0 }, /* disable session resumption tickets */
David Safb76832014-05-08 23:42:08 -04006593 { "send-proxy-v2-ssl", srv_parse_send_proxy_ssl, 0, 0 }, /* send PROXY protocol header v2 with SSL info */
6594 { "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 +02006595 { "sni", srv_parse_sni, 1, 0 }, /* send SNI extension */
Emeric Brunecc91fe2012-10-11 15:05:10 +02006596 { "ssl", srv_parse_ssl, 0, 0 }, /* enable SSL processing */
Emeric Brunef42d922012-10-11 16:11:36 +02006597 { "verify", srv_parse_verify, 1, 0 }, /* set SSL verify method */
Evan Broderbe554312013-06-27 00:05:25 -07006598 { "verifyhost", srv_parse_verifyhost, 1, 0 }, /* require that SSL cert verifies for hostname */
Willy Tarreau92faadf2012-10-10 23:04:25 +02006599 { NULL, NULL, 0, 0 },
6600}};
6601
Emeric Brun2c86cbf2014-10-30 15:56:50 +01006602static struct cfg_kw_list cfg_kws = {ILH, {
Willy Tarreau8c3b0fd2016-12-21 22:44:46 +01006603 { CFG_GLOBAL, "ca-base", ssl_parse_global_ca_crt_base },
6604 { CFG_GLOBAL, "crt-base", ssl_parse_global_ca_crt_base },
Willy Tarreau0bea58d2016-12-21 23:17:25 +01006605 { CFG_GLOBAL, "maxsslconn", ssl_parse_global_int },
Emeric Brun2c86cbf2014-10-30 15:56:50 +01006606 { CFG_GLOBAL, "ssl-default-bind-options", ssl_parse_default_bind_options },
6607 { CFG_GLOBAL, "ssl-default-server-options", ssl_parse_default_server_options },
Willy Tarreau14e36a12016-12-21 23:28:13 +01006608#ifndef OPENSSL_NO_DH
6609 { CFG_GLOBAL, "ssl-dh-param-file", ssl_parse_global_dh_param_file },
6610#endif
Willy Tarreau9ceda382016-12-21 23:13:03 +01006611 { CFG_GLOBAL, "tune.ssl.cachesize", ssl_parse_global_int },
6612#ifndef OPENSSL_NO_DH
6613 { CFG_GLOBAL, "tune.ssl.default-dh-param", ssl_parse_global_default_dh },
6614#endif
6615 { CFG_GLOBAL, "tune.ssl.force-private-cache", ssl_parse_global_private_cache },
6616 { CFG_GLOBAL, "tune.ssl.lifetime", ssl_parse_global_lifetime },
6617 { CFG_GLOBAL, "tune.ssl.maxrecord", ssl_parse_global_int },
6618 { CFG_GLOBAL, "tune.ssl.ssl-ctx-cache-size", ssl_parse_global_int },
Willy Tarreauf22e9682016-12-21 23:23:19 +01006619 { CFG_GLOBAL, "ssl-default-bind-ciphers", ssl_parse_global_ciphers },
6620 { CFG_GLOBAL, "ssl-default-server-ciphers", ssl_parse_global_ciphers },
Emeric Brun2c86cbf2014-10-30 15:56:50 +01006621 { 0, NULL, NULL },
6622}};
6623
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02006624/* transport-layer operations for SSL sockets */
6625struct xprt_ops ssl_sock = {
Emeric Brun46591952012-05-18 15:47:34 +02006626 .snd_buf = ssl_sock_from_buf,
6627 .rcv_buf = ssl_sock_to_buf,
6628 .rcv_pipe = NULL,
6629 .snd_pipe = NULL,
6630 .shutr = NULL,
6631 .shutw = ssl_sock_shutw,
6632 .close = ssl_sock_close,
6633 .init = ssl_sock_init,
Willy Tarreau55d37912016-12-21 23:38:39 +01006634 .prepare_bind_conf = ssl_sock_prepare_bind_conf,
Willy Tarreau8e0bb0a2016-11-24 16:58:12 +01006635 .name = "SSL",
Emeric Brun46591952012-05-18 15:47:34 +02006636};
6637
Daniel Jakots54ffb912015-11-06 20:02:41 +01006638#if (OPENSSL_VERSION_NUMBER >= 0x1000200fL && !defined OPENSSL_NO_TLSEXT && !defined OPENSSL_IS_BORINGSSL && !defined LIBRESSL_VERSION_NUMBER)
Janusz Dziemidowicz2c701b52015-03-07 23:03:59 +01006639
6640static void ssl_sock_sctl_free_func(void *parent, void *ptr, CRYPTO_EX_DATA *ad, int idx, long argl, void *argp)
6641{
6642 if (ptr) {
6643 chunk_destroy(ptr);
6644 free(ptr);
6645 }
6646}
6647
6648#endif
6649
Emeric Brun46591952012-05-18 15:47:34 +02006650__attribute__((constructor))
Willy Tarreau92faadf2012-10-10 23:04:25 +02006651static void __ssl_sock_init(void)
6652{
Willy Tarreauc2c0b612016-12-21 19:23:20 +01006653 char *ptr;
6654
Emeric Brun46591952012-05-18 15:47:34 +02006655 STACK_OF(SSL_COMP)* cm;
6656
Willy Tarreau610f04b2014-02-13 11:36:41 +01006657#ifdef LISTEN_DEFAULT_CIPHERS
6658 global.listen_default_ciphers = LISTEN_DEFAULT_CIPHERS;
6659#endif
6660#ifdef CONNECT_DEFAULT_CIPHERS
6661 global.connect_default_ciphers = CONNECT_DEFAULT_CIPHERS;
6662#endif
6663 if (global.listen_default_ciphers)
6664 global.listen_default_ciphers = strdup(global.listen_default_ciphers);
6665 if (global.connect_default_ciphers)
6666 global.connect_default_ciphers = strdup(global.connect_default_ciphers);
Emeric Brun2c86cbf2014-10-30 15:56:50 +01006667 global.listen_default_ssloptions = BC_SSL_O_NONE;
6668 global.connect_default_ssloptions = SRV_SSL_O_NONE;
Willy Tarreau610f04b2014-02-13 11:36:41 +01006669
Emeric Brun46591952012-05-18 15:47:34 +02006670 SSL_library_init();
6671 cm = SSL_COMP_get_compression_methods();
6672 sk_SSL_COMP_zero(cm);
Daniel Jakots54ffb912015-11-06 20:02:41 +01006673#if (OPENSSL_VERSION_NUMBER >= 0x1000200fL && !defined OPENSSL_NO_TLSEXT && !defined OPENSSL_IS_BORINGSSL && !defined LIBRESSL_VERSION_NUMBER)
Janusz Dziemidowicz2c701b52015-03-07 23:03:59 +01006674 sctl_ex_index = SSL_CTX_get_ex_new_index(0, NULL, NULL, NULL, ssl_sock_sctl_free_func);
6675#endif
Willy Tarreau7875d092012-09-10 08:20:03 +02006676 sample_register_fetches(&sample_fetch_keywords);
6677 acl_register_keywords(&acl_kws);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02006678 bind_register_keywords(&bind_kws);
Willy Tarreau92faadf2012-10-10 23:04:25 +02006679 srv_register_keywords(&srv_kws);
Emeric Brun2c86cbf2014-10-30 15:56:50 +01006680 cfg_register_keywords(&cfg_kws);
William Lallemand32af2032016-10-29 18:09:35 +02006681 cli_register_kw(&cli_kws);
Willy Tarreaud92aa5c2015-01-15 21:34:39 +01006682
Willy Tarreauc2c0b612016-12-21 19:23:20 +01006683 ptr = NULL;
6684 memprintf(&ptr, "Built with OpenSSL version : "
6685#ifdef OPENSSL_IS_BORINGSSL
6686 "BoringSSL\n");
6687#else /* OPENSSL_IS_BORINGSSL */
6688 OPENSSL_VERSION_TEXT
6689 "\nRunning on OpenSSL version : %s%s",
6690 SSLeay_version(SSLEAY_VERSION),
6691 ((OPENSSL_VERSION_NUMBER ^ SSLeay()) >> 8) ? " (VERSIONS DIFFER!)" : "");
6692#endif
6693 memprintf(&ptr, "%s\nOpenSSL library supports TLS extensions : "
6694#if OPENSSL_VERSION_NUMBER < 0x00907000L
6695 "no (library version too old)"
6696#elif defined(OPENSSL_NO_TLSEXT)
6697 "no (disabled via OPENSSL_NO_TLSEXT)"
6698#else
6699 "yes"
6700#endif
6701 "", ptr);
6702
6703 memprintf(&ptr, "%s\nOpenSSL library supports SNI : "
6704#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
6705 "yes"
6706#else
6707#ifdef OPENSSL_NO_TLSEXT
6708 "no (because of OPENSSL_NO_TLSEXT)"
6709#else
6710 "no (version might be too old, 0.9.8f min needed)"
6711#endif
6712#endif
6713 "", ptr);
6714
6715 memprintf(&ptr, "%s\nOpenSSL library supports prefer-server-ciphers : "
6716#ifdef SSL_OP_CIPHER_SERVER_PREFERENCE
6717 "yes"
6718#else
6719 "no (0.9.7 or later needed)"
6720#endif
6721 "", ptr);
6722 hap_register_build_opts(ptr, 1);
6723
Willy Tarreaud92aa5c2015-01-15 21:34:39 +01006724 global.ssl_session_max_cost = SSL_SESSION_MAX_COST;
6725 global.ssl_handshake_max_cost = SSL_HANDSHAKE_MAX_COST;
Remi Gacogne4f902b82015-05-28 16:23:00 +02006726
6727#ifndef OPENSSL_NO_DH
6728 ssl_dh_ptr_index = SSL_CTX_get_ex_new_index(0, NULL, NULL, NULL, NULL);
6729#endif
Thierry FOURNIER / OZON.IO8b068c22016-10-10 11:59:50 +02006730
6731 /* Load SSL string for the verbose & debug mode. */
6732 ERR_load_SSL_strings();
Emeric Brun46591952012-05-18 15:47:34 +02006733}
6734
Remi Gacogned3a23c32015-05-28 16:39:47 +02006735__attribute__((destructor))
6736static void __ssl_sock_deinit(void)
6737{
Willy Tarreaua84c2672015-10-09 12:10:13 +02006738#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Christopher Faulet31af49d2015-06-09 17:29:50 +02006739 lru64_destroy(ssl_ctx_lru_tree);
Willy Tarreaua84c2672015-10-09 12:10:13 +02006740#endif
Christopher Faulet31af49d2015-06-09 17:29:50 +02006741
Remi Gacogned3a23c32015-05-28 16:39:47 +02006742#ifndef OPENSSL_NO_DH
6743 if (local_dh_1024) {
6744 DH_free(local_dh_1024);
6745 local_dh_1024 = NULL;
6746 }
6747
6748 if (local_dh_2048) {
6749 DH_free(local_dh_2048);
6750 local_dh_2048 = NULL;
6751 }
6752
6753 if (local_dh_4096) {
6754 DH_free(local_dh_4096);
6755 local_dh_4096 = NULL;
6756 }
6757
Remi Gacogne47783ef2015-05-29 15:53:22 +02006758 if (global_dh) {
6759 DH_free(global_dh);
6760 global_dh = NULL;
6761 }
Remi Gacogned3a23c32015-05-28 16:39:47 +02006762#endif
6763
6764 ERR_remove_state(0);
6765 ERR_free_strings();
6766
6767 EVP_cleanup();
6768
6769#if OPENSSL_VERSION_NUMBER >= 0x00907000L
6770 CRYPTO_cleanup_all_ex_data();
6771#endif
6772}
6773
6774
Emeric Brun46591952012-05-18 15:47:34 +02006775/*
6776 * Local variables:
6777 * c-indent-level: 8
6778 * c-basic-offset: 8
6779 * End:
6780 */