blob: 617c00297a42f1b9e99af5afe0636bcefc13ac6d [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 */
Emmanuel Hocdetd294aea2016-05-13 11:14:06 +02002033static int ssl_sock_load_multi_cert(const char *path, struct bind_conf *bind_conf, struct proxy *curproxy, 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 */
Emmanuel Hocdetd294aea2016-05-13 11:14:06 +02002241static int ssl_sock_load_multi_cert(const char *path, struct bind_conf *bind_conf, struct proxy *curproxy, 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
Emeric Brun50bcecc2013-04-22 13:05:23 +02002355static int ssl_sock_load_cert_file(const char *path, struct bind_conf *bind_conf, struct proxy *curproxy, 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 Tarreau79eeafa2012-09-14 07:53:05 +02002443int ssl_sock_load_cert(char *path, struct bind_conf *bind_conf, struct proxy *curproxy, 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)
2460 return ssl_sock_load_cert_file(path, bind_conf, curproxy, 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);
Emmanuel Hocdetd294aea2016-05-13 11:14:06 +02002520 ssl_sock_load_multi_cert(fp, bind_conf, curproxy, NULL, 0, err);
yanbzhu63ea8462015-12-09 13:35:14 -05002521
2522 /* Successfully processed the bundle */
2523 goto ignore_entry;
2524 }
2525 }
2526
2527#endif
yanbzhu08ce6ab2015-12-02 13:01:29 -05002528 cfgerr += ssl_sock_load_cert_file(fp, bind_conf, curproxy, NULL, 0, err);
2529ignore_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
Emmanuel Hocdetd294aea2016-05-13 11:14:06 +02002538 cfgerr = ssl_sock_load_multi_cert(path, bind_conf, curproxy, 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
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002559int ssl_sock_load_cert_list_file(char *file, struct bind_conf *bind_conf, struct proxy *curproxy, char **err)
2560{
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) {
2623 cfgerr = ssl_sock_load_cert_file(args[0], bind_conf, curproxy, &args[1], arg-1, err);
2624 } else {
Emmanuel Hocdetd294aea2016-05-13 11:14:06 +02002625 cfgerr = ssl_sock_load_multi_cert(args[0], bind_conf, curproxy, &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 Tarreau2a65ff02012-09-13 17:54:29 +02002673int ssl_sock_prepare_ctx(struct bind_conf *bind_conf, SSL_CTX *ctx, struct proxy *curproxy)
Emeric Brunfc0421f2012-09-07 17:30:07 +02002674{
2675 int cfgerr = 0;
Emeric Brun850efd52014-01-29 12:24:34 +01002676 int verify = SSL_VERIFY_NONE;
Remi Gacogneaf5c3da2014-05-19 10:29:58 +02002677 long ssloptions =
Emeric Brunfc0421f2012-09-07 17:30:07 +02002678 SSL_OP_ALL | /* all known workarounds for bugs */
2679 SSL_OP_NO_SSLv2 |
2680 SSL_OP_NO_COMPRESSION |
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02002681 SSL_OP_SINGLE_DH_USE |
Emeric Brun2b58d042012-09-20 17:10:03 +02002682 SSL_OP_SINGLE_ECDH_USE |
Emeric Brun3c4bc6e2012-10-04 18:44:19 +02002683 SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION |
2684 SSL_OP_CIPHER_SERVER_PREFERENCE;
Remi Gacogneaf5c3da2014-05-19 10:29:58 +02002685 long sslmode =
Emeric Brunfc0421f2012-09-07 17:30:07 +02002686 SSL_MODE_ENABLE_PARTIAL_WRITE |
2687 SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER |
Willy Tarreau396a1862014-11-13 14:06:52 +01002688 SSL_MODE_RELEASE_BUFFERS |
2689 SSL_MODE_SMALL_BUFFERS;
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002690 STACK_OF(SSL_CIPHER) * ciphers = NULL;
Willy Tarreaua616ba62014-10-26 06:49:19 +01002691 SSL_CIPHER * cipher = NULL;
Remi Gacognec1eab8c2014-06-12 18:20:11 +02002692 char cipher_description[128];
2693 /* The description of ciphers using an Ephemeral Diffie Hellman key exchange
2694 contains " Kx=DH " or " Kx=DH(". Beware of " Kx=DH/",
2695 which is not ephemeral DH. */
2696 const char dhe_description[] = " Kx=DH ";
2697 const char dhe_export_description[] = " Kx=DH(";
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002698 int idx = 0;
2699 int dhe_found = 0;
Remi Gacogne23d5d372014-10-10 17:04:26 +02002700 SSL *ssl = NULL;
Emeric Brunfc0421f2012-09-07 17:30:07 +02002701
Thierry Fournier383085f2013-01-24 14:15:43 +01002702 /* Make sure openssl opens /dev/urandom before the chroot */
2703 if (!ssl_initialize_random()) {
2704 Alert("OpenSSL random data generator initialization failed.\n");
2705 cfgerr++;
2706 }
2707
Emeric Brun89675492012-10-05 13:48:26 +02002708 if (bind_conf->ssl_options & BC_SSL_O_NO_SSLV3)
Emeric Brunfc0421f2012-09-07 17:30:07 +02002709 ssloptions |= SSL_OP_NO_SSLv3;
Emeric Brun89675492012-10-05 13:48:26 +02002710 if (bind_conf->ssl_options & BC_SSL_O_NO_TLSV10)
Emeric Brunfc0421f2012-09-07 17:30:07 +02002711 ssloptions |= SSL_OP_NO_TLSv1;
Emeric Brun89675492012-10-05 13:48:26 +02002712 if (bind_conf->ssl_options & BC_SSL_O_NO_TLSV11)
Emeric Brunc0ff4922012-09-28 19:37:02 +02002713 ssloptions |= SSL_OP_NO_TLSv1_1;
Emeric Brun89675492012-10-05 13:48:26 +02002714 if (bind_conf->ssl_options & BC_SSL_O_NO_TLSV12)
Emeric Brunc0ff4922012-09-28 19:37:02 +02002715 ssloptions |= SSL_OP_NO_TLSv1_2;
Emeric Brun89675492012-10-05 13:48:26 +02002716 if (bind_conf->ssl_options & BC_SSL_O_NO_TLS_TICKETS)
Emeric Brun2d0c4822012-10-02 13:45:20 +02002717 ssloptions |= SSL_OP_NO_TICKET;
Jérémie Courrèges-Anglas17c3f622015-07-25 16:50:52 -06002718 if (bind_conf->ssl_options & BC_SSL_O_USE_SSLV3) {
2719#ifndef OPENSSL_NO_SSL3
Emeric Brun2cb7ae52012-10-05 14:14:21 +02002720 SSL_CTX_set_ssl_version(ctx, SSLv3_server_method());
Jérémie Courrèges-Anglas17c3f622015-07-25 16:50:52 -06002721#else
2722 Alert("SSLv3 support requested but unavailable.\n");
2723 cfgerr++;
2724#endif
2725 }
Emeric Brun2cb7ae52012-10-05 14:14:21 +02002726 if (bind_conf->ssl_options & BC_SSL_O_USE_TLSV10)
2727 SSL_CTX_set_ssl_version(ctx, TLSv1_server_method());
2728#if SSL_OP_NO_TLSv1_1
2729 if (bind_conf->ssl_options & BC_SSL_O_USE_TLSV11)
2730 SSL_CTX_set_ssl_version(ctx, TLSv1_1_server_method());
2731#endif
2732#if SSL_OP_NO_TLSv1_2
2733 if (bind_conf->ssl_options & BC_SSL_O_USE_TLSV12)
2734 SSL_CTX_set_ssl_version(ctx, TLSv1_2_server_method());
2735#endif
Emeric Brunfc0421f2012-09-07 17:30:07 +02002736
2737 SSL_CTX_set_options(ctx, ssloptions);
2738 SSL_CTX_set_mode(ctx, sslmode);
Emeric Brun850efd52014-01-29 12:24:34 +01002739 switch (bind_conf->verify) {
2740 case SSL_SOCK_VERIFY_NONE:
2741 verify = SSL_VERIFY_NONE;
2742 break;
2743 case SSL_SOCK_VERIFY_OPTIONAL:
2744 verify = SSL_VERIFY_PEER;
2745 break;
2746 case SSL_SOCK_VERIFY_REQUIRED:
2747 verify = SSL_VERIFY_PEER|SSL_VERIFY_FAIL_IF_NO_PEER_CERT;
2748 break;
2749 }
2750 SSL_CTX_set_verify(ctx, verify, ssl_sock_bind_verifycbk);
2751 if (verify & SSL_VERIFY_PEER) {
Emeric Brunfb510ea2012-10-05 12:00:26 +02002752 if (bind_conf->ca_file) {
Emeric Brund94b3fe2012-09-20 18:23:56 +02002753 /* load CAfile to verify */
Emeric Brunfb510ea2012-10-05 12:00:26 +02002754 if (!SSL_CTX_load_verify_locations(ctx, bind_conf->ca_file, NULL)) {
Emeric Brund94b3fe2012-09-20 18:23:56 +02002755 Alert("Proxy '%s': unable to load CA file '%s' for bind '%s' at [%s:%d].\n",
Emeric Brunfb510ea2012-10-05 12:00:26 +02002756 curproxy->id, bind_conf->ca_file, bind_conf->arg, bind_conf->file, bind_conf->line);
Emeric Brund94b3fe2012-09-20 18:23:56 +02002757 cfgerr++;
2758 }
2759 /* set CA names fo client cert request, function returns void */
Emeric Brunfb510ea2012-10-05 12:00:26 +02002760 SSL_CTX_set_client_CA_list(ctx, SSL_load_client_CA_file(bind_conf->ca_file));
Emeric Brund94b3fe2012-09-20 18:23:56 +02002761 }
Emeric Brun850efd52014-01-29 12:24:34 +01002762 else {
2763 Alert("Proxy '%s': verify is enabled but no CA file specified for bind '%s' at [%s:%d].\n",
2764 curproxy->id, bind_conf->arg, bind_conf->file, bind_conf->line);
2765 cfgerr++;
2766 }
Emeric Brun051cdab2012-10-02 19:25:50 +02002767#ifdef X509_V_FLAG_CRL_CHECK
Emeric Brunfb510ea2012-10-05 12:00:26 +02002768 if (bind_conf->crl_file) {
Emeric Brund94b3fe2012-09-20 18:23:56 +02002769 X509_STORE *store = SSL_CTX_get_cert_store(ctx);
2770
Emeric Brunfb510ea2012-10-05 12:00:26 +02002771 if (!store || !X509_STORE_load_locations(store, bind_conf->crl_file, NULL)) {
Emeric Brund94b3fe2012-09-20 18:23:56 +02002772 Alert("Proxy '%s': unable to configure CRL file '%s' for bind '%s' at [%s:%d].\n",
Alexander Rigbofc65af02015-04-07 14:02:16 +02002773 curproxy->id, bind_conf->crl_file, bind_conf->arg, bind_conf->file, bind_conf->line);
Emeric Brund94b3fe2012-09-20 18:23:56 +02002774 cfgerr++;
2775 }
Emeric Brun561e5742012-10-02 15:20:55 +02002776 else {
2777 X509_STORE_set_flags(store, X509_V_FLAG_CRL_CHECK|X509_V_FLAG_CRL_CHECK_ALL);
2778 }
Emeric Brund94b3fe2012-09-20 18:23:56 +02002779 }
Emeric Brun051cdab2012-10-02 19:25:50 +02002780#endif
Emeric Brun644cde02012-12-14 11:21:13 +01002781 ERR_clear_error();
Emeric Brund94b3fe2012-09-20 18:23:56 +02002782 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02002783
Nenad Merdanovic05552d42015-02-27 19:56:49 +01002784#if (defined SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB && TLS_TICKETS_NO > 0)
Nenad Merdanovic146defa2015-05-09 08:46:00 +02002785 if(bind_conf->keys_ref) {
Nenad Merdanovic05552d42015-02-27 19:56:49 +01002786 if (!SSL_CTX_set_tlsext_ticket_key_cb(ctx, ssl_tlsext_ticket_key_cb)) {
2787 Alert("Proxy '%s': unable to set callback for TLS ticket validation for bind '%s' at [%s:%d].\n",
2788 curproxy->id, bind_conf->arg, bind_conf->file, bind_conf->line);
2789 cfgerr++;
2790 }
2791 }
2792#endif
2793
Emeric Brun4f65bff2012-11-16 15:11:00 +01002794 if (global.tune.ssllifetime)
2795 SSL_CTX_set_timeout(ctx, global.tune.ssllifetime);
2796
Emeric Brunfc0421f2012-09-07 17:30:07 +02002797 shared_context_set_cache(ctx);
Willy Tarreau2a65ff02012-09-13 17:54:29 +02002798 if (bind_conf->ciphers &&
2799 !SSL_CTX_set_cipher_list(ctx, bind_conf->ciphers)) {
Emeric Brunfc0421f2012-09-07 17:30:07 +02002800 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 +02002801 curproxy->id, bind_conf->ciphers, bind_conf->arg, bind_conf->file, bind_conf->line);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002802 cfgerr++;
2803 }
2804
Remi Gacogne47783ef2015-05-29 15:53:22 +02002805 /* If tune.ssl.default-dh-param has not been set,
2806 neither has ssl-default-dh-file and no static DH
2807 params were in the certificate file. */
Remi Gacogne4f902b82015-05-28 16:23:00 +02002808 if (global.tune.ssl_default_dh_param == 0 &&
Remi Gacogne47783ef2015-05-29 15:53:22 +02002809 global_dh == NULL &&
Remi Gacogne4f902b82015-05-28 16:23:00 +02002810 (ssl_dh_ptr_index == -1 ||
2811 SSL_CTX_get_ex_data(ctx, ssl_dh_ptr_index) == NULL)) {
Lukas Tribus90132722014-08-18 00:56:33 +02002812
Remi Gacogne23d5d372014-10-10 17:04:26 +02002813 ssl = SSL_new(ctx);
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002814
Remi Gacogne23d5d372014-10-10 17:04:26 +02002815 if (ssl) {
2816 ciphers = SSL_get_ciphers(ssl);
2817
2818 if (ciphers) {
2819 for (idx = 0; idx < sk_SSL_CIPHER_num(ciphers); idx++) {
2820 cipher = sk_SSL_CIPHER_value(ciphers, idx);
2821 if (SSL_CIPHER_description(cipher, cipher_description, sizeof (cipher_description)) == cipher_description) {
2822 if (strstr(cipher_description, dhe_description) != NULL ||
2823 strstr(cipher_description, dhe_export_description) != NULL) {
2824 dhe_found = 1;
2825 break;
2826 }
Remi Gacognec1eab8c2014-06-12 18:20:11 +02002827 }
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002828 }
2829 }
Remi Gacogne23d5d372014-10-10 17:04:26 +02002830 SSL_free(ssl);
2831 ssl = NULL;
Lukas Tribus90132722014-08-18 00:56:33 +02002832 }
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002833
Lukas Tribus90132722014-08-18 00:56:33 +02002834 if (dhe_found) {
2835 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 +02002836 }
2837
2838 global.tune.ssl_default_dh_param = 1024;
2839 }
Remi Gacogne8de54152014-07-15 11:36:40 +02002840
2841#ifndef OPENSSL_NO_DH
2842 if (global.tune.ssl_default_dh_param >= 1024) {
2843 if (local_dh_1024 == NULL) {
2844 local_dh_1024 = ssl_get_dh_1024();
2845 }
2846 if (global.tune.ssl_default_dh_param >= 2048) {
2847 if (local_dh_2048 == NULL) {
2848 local_dh_2048 = ssl_get_dh_2048();
2849 }
2850 if (global.tune.ssl_default_dh_param >= 4096) {
2851 if (local_dh_4096 == NULL) {
2852 local_dh_4096 = ssl_get_dh_4096();
2853 }
Remi Gacogne8de54152014-07-15 11:36:40 +02002854 }
2855 }
2856 }
2857#endif /* OPENSSL_NO_DH */
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002858
Emeric Brunfc0421f2012-09-07 17:30:07 +02002859 SSL_CTX_set_info_callback(ctx, ssl_sock_infocbk);
Willy Tarreau5cbe4ef2014-05-08 22:45:11 +02002860#if OPENSSL_VERSION_NUMBER >= 0x00907000L
Emeric Brun29f037d2014-04-25 19:05:36 +02002861 SSL_CTX_set_msg_callback(ctx, ssl_sock_msgcbk);
Willy Tarreau5cbe4ef2014-05-08 22:45:11 +02002862#endif
Emeric Brun29f037d2014-04-25 19:05:36 +02002863
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02002864#ifdef OPENSSL_NPN_NEGOTIATED
2865 if (bind_conf->npn_str)
2866 SSL_CTX_set_next_protos_advertised_cb(ctx, ssl_sock_advertise_npn_protos, bind_conf);
2867#endif
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01002868#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Willy Tarreauab861d32013-04-02 02:30:41 +02002869 if (bind_conf->alpn_str)
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01002870 SSL_CTX_set_alpn_select_cb(ctx, ssl_sock_advertise_alpn_protos, bind_conf);
Willy Tarreauab861d32013-04-02 02:30:41 +02002871#endif
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02002872
Emeric Brunfc0421f2012-09-07 17:30:07 +02002873#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
2874 SSL_CTX_set_tlsext_servername_callback(ctx, ssl_sock_switchctx_cbk);
Willy Tarreau2a65ff02012-09-13 17:54:29 +02002875 SSL_CTX_set_tlsext_servername_arg(ctx, bind_conf);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002876#endif
Emeric Brun2b58d042012-09-20 17:10:03 +02002877#if defined(SSL_CTX_set_tmp_ecdh) && !defined(OPENSSL_NO_ECDH)
Emeric Brun6924ef82013-03-06 14:08:53 +01002878 {
Emeric Brun2b58d042012-09-20 17:10:03 +02002879 int i;
2880 EC_KEY *ecdh;
2881
Emeric Brun6924ef82013-03-06 14:08:53 +01002882 i = OBJ_sn2nid(bind_conf->ecdhe ? bind_conf->ecdhe : ECDHE_DEFAULT_CURVE);
Emeric Brun2b58d042012-09-20 17:10:03 +02002883 if (!i || ((ecdh = EC_KEY_new_by_curve_name(i)) == NULL)) {
2884 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 +01002885 curproxy->id, bind_conf->ecdhe ? bind_conf->ecdhe : ECDHE_DEFAULT_CURVE,
2886 bind_conf->arg, bind_conf->file, bind_conf->line);
Emeric Brun2b58d042012-09-20 17:10:03 +02002887 cfgerr++;
2888 }
2889 else {
2890 SSL_CTX_set_tmp_ecdh(ctx, ecdh);
2891 EC_KEY_free(ecdh);
2892 }
2893 }
2894#endif
2895
Emeric Brunfc0421f2012-09-07 17:30:07 +02002896 return cfgerr;
2897}
2898
Evan Broderbe554312013-06-27 00:05:25 -07002899static int ssl_sock_srv_hostcheck(const char *pattern, const char *hostname)
2900{
2901 const char *pattern_wildcard, *pattern_left_label_end, *hostname_left_label_end;
2902 size_t prefixlen, suffixlen;
2903
2904 /* Trivial case */
2905 if (strcmp(pattern, hostname) == 0)
2906 return 1;
2907
Evan Broderbe554312013-06-27 00:05:25 -07002908 /* The rest of this logic is based on RFC 6125, section 6.4.3
2909 * (http://tools.ietf.org/html/rfc6125#section-6.4.3) */
2910
Emeric Bruna848dae2013-10-08 11:27:28 +02002911 pattern_wildcard = NULL;
2912 pattern_left_label_end = pattern;
2913 while (*pattern_left_label_end != '.') {
2914 switch (*pattern_left_label_end) {
2915 case 0:
2916 /* End of label not found */
2917 return 0;
2918 case '*':
2919 /* If there is more than one wildcards */
2920 if (pattern_wildcard)
2921 return 0;
2922 pattern_wildcard = pattern_left_label_end;
2923 break;
2924 }
2925 pattern_left_label_end++;
2926 }
2927
2928 /* If it's not trivial and there is no wildcard, it can't
2929 * match */
2930 if (!pattern_wildcard)
Evan Broderbe554312013-06-27 00:05:25 -07002931 return 0;
2932
2933 /* Make sure all labels match except the leftmost */
2934 hostname_left_label_end = strchr(hostname, '.');
2935 if (!hostname_left_label_end
2936 || strcmp(pattern_left_label_end, hostname_left_label_end) != 0)
2937 return 0;
2938
2939 /* Make sure the leftmost label of the hostname is long enough
2940 * that the wildcard can match */
Emeric Brun369da852013-10-08 11:39:35 +02002941 if (hostname_left_label_end - hostname < (pattern_left_label_end - pattern) - 1)
Evan Broderbe554312013-06-27 00:05:25 -07002942 return 0;
2943
2944 /* Finally compare the string on either side of the
2945 * wildcard */
2946 prefixlen = pattern_wildcard - pattern;
2947 suffixlen = pattern_left_label_end - (pattern_wildcard + 1);
Emeric Bruna848dae2013-10-08 11:27:28 +02002948 if ((prefixlen && (memcmp(pattern, hostname, prefixlen) != 0))
2949 || (suffixlen && (memcmp(pattern_wildcard + 1, hostname_left_label_end - suffixlen, suffixlen) != 0)))
Evan Broderbe554312013-06-27 00:05:25 -07002950 return 0;
2951
2952 return 1;
2953}
2954
2955static int ssl_sock_srv_verifycbk(int ok, X509_STORE_CTX *ctx)
2956{
2957 SSL *ssl;
2958 struct connection *conn;
2959 char *servername;
2960
2961 int depth;
2962 X509 *cert;
2963 STACK_OF(GENERAL_NAME) *alt_names;
2964 int i;
2965 X509_NAME *cert_subject;
2966 char *str;
2967
2968 if (ok == 0)
2969 return ok;
2970
2971 ssl = X509_STORE_CTX_get_ex_data(ctx, SSL_get_ex_data_X509_STORE_CTX_idx());
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02002972 conn = SSL_get_app_data(ssl);
Evan Broderbe554312013-06-27 00:05:25 -07002973
2974 servername = objt_server(conn->target)->ssl_ctx.verify_host;
2975
2976 /* We only need to verify the CN on the actual server cert,
2977 * not the indirect CAs */
2978 depth = X509_STORE_CTX_get_error_depth(ctx);
2979 if (depth != 0)
2980 return ok;
2981
2982 /* At this point, the cert is *not* OK unless we can find a
2983 * hostname match */
2984 ok = 0;
2985
2986 cert = X509_STORE_CTX_get_current_cert(ctx);
2987 /* It seems like this might happen if verify peer isn't set */
2988 if (!cert)
2989 return ok;
2990
2991 alt_names = X509_get_ext_d2i(cert, NID_subject_alt_name, NULL, NULL);
2992 if (alt_names) {
2993 for (i = 0; !ok && i < sk_GENERAL_NAME_num(alt_names); i++) {
2994 GENERAL_NAME *name = sk_GENERAL_NAME_value(alt_names, i);
2995 if (name->type == GEN_DNS) {
Emeric Bruna33410c2013-09-17 15:47:48 +02002996#if OPENSSL_VERSION_NUMBER < 0x00907000L
2997 if (ASN1_STRING_to_UTF8((unsigned char **)&str, name->d.ia5) >= 0) {
2998#else
Evan Broderbe554312013-06-27 00:05:25 -07002999 if (ASN1_STRING_to_UTF8((unsigned char **)&str, name->d.dNSName) >= 0) {
Emeric Bruna33410c2013-09-17 15:47:48 +02003000#endif
Evan Broderbe554312013-06-27 00:05:25 -07003001 ok = ssl_sock_srv_hostcheck(str, servername);
3002 OPENSSL_free(str);
3003 }
3004 }
3005 }
Emeric Brun4ad50a42013-09-17 15:19:54 +02003006 sk_GENERAL_NAME_pop_free(alt_names, GENERAL_NAME_free);
Evan Broderbe554312013-06-27 00:05:25 -07003007 }
3008
3009 cert_subject = X509_get_subject_name(cert);
3010 i = -1;
3011 while (!ok && (i = X509_NAME_get_index_by_NID(cert_subject, NID_commonName, i)) != -1) {
3012 X509_NAME_ENTRY *entry = X509_NAME_get_entry(cert_subject, i);
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02003013 ASN1_STRING *value;
3014 value = X509_NAME_ENTRY_get_data(entry);
3015 if (ASN1_STRING_to_UTF8((unsigned char **)&str, value) >= 0) {
Evan Broderbe554312013-06-27 00:05:25 -07003016 ok = ssl_sock_srv_hostcheck(str, servername);
3017 OPENSSL_free(str);
3018 }
3019 }
3020
3021 return ok;
3022}
3023
Emeric Brun94324a42012-10-11 14:00:19 +02003024/* prepare ssl context from servers options. Returns an error count */
3025int ssl_sock_prepare_srv_ctx(struct server *srv, struct proxy *curproxy)
3026{
3027 int cfgerr = 0;
Remi Gacogneaf5c3da2014-05-19 10:29:58 +02003028 long options =
Emeric Brun94324a42012-10-11 14:00:19 +02003029 SSL_OP_ALL | /* all known workarounds for bugs */
3030 SSL_OP_NO_SSLv2 |
3031 SSL_OP_NO_COMPRESSION;
Remi Gacogneaf5c3da2014-05-19 10:29:58 +02003032 long mode =
Emeric Brun94324a42012-10-11 14:00:19 +02003033 SSL_MODE_ENABLE_PARTIAL_WRITE |
3034 SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER |
Willy Tarreau396a1862014-11-13 14:06:52 +01003035 SSL_MODE_RELEASE_BUFFERS |
3036 SSL_MODE_SMALL_BUFFERS;
Emeric Brun850efd52014-01-29 12:24:34 +01003037 int verify = SSL_VERIFY_NONE;
Emeric Brun94324a42012-10-11 14:00:19 +02003038
Thierry Fournier383085f2013-01-24 14:15:43 +01003039 /* Make sure openssl opens /dev/urandom before the chroot */
3040 if (!ssl_initialize_random()) {
3041 Alert("OpenSSL random data generator initialization failed.\n");
3042 cfgerr++;
3043 }
3044
Willy Tarreaufce03112015-01-15 21:32:40 +01003045 /* Automatic memory computations need to know we use SSL there */
3046 global.ssl_used_backend = 1;
3047
3048 /* Initiate SSL context for current server */
Emeric Brun94324a42012-10-11 14:00:19 +02003049 srv->ssl_ctx.reused_sess = NULL;
3050 if (srv->use_ssl)
3051 srv->xprt = &ssl_sock;
3052 if (srv->check.use_ssl)
Cyril Bonté9ce13112014-11-15 22:41:27 +01003053 srv->check.xprt = &ssl_sock;
Emeric Brun94324a42012-10-11 14:00:19 +02003054
3055 srv->ssl_ctx.ctx = SSL_CTX_new(SSLv23_client_method());
3056 if (!srv->ssl_ctx.ctx) {
3057 Alert("config : %s '%s', server '%s': unable to allocate ssl context.\n",
3058 proxy_type_str(curproxy), curproxy->id,
3059 srv->id);
3060 cfgerr++;
3061 return cfgerr;
3062 }
Emeric Bruna7aa3092012-10-26 12:58:00 +02003063 if (srv->ssl_ctx.client_crt) {
3064 if (SSL_CTX_use_PrivateKey_file(srv->ssl_ctx.ctx, srv->ssl_ctx.client_crt, SSL_FILETYPE_PEM) <= 0) {
3065 Alert("config : %s '%s', server '%s': unable to load SSL private key from PEM file '%s'.\n",
3066 proxy_type_str(curproxy), curproxy->id,
3067 srv->id, srv->ssl_ctx.client_crt);
3068 cfgerr++;
3069 }
3070 else if (SSL_CTX_use_certificate_chain_file(srv->ssl_ctx.ctx, srv->ssl_ctx.client_crt) <= 0) {
3071 Alert("config : %s '%s', server '%s': unable to load ssl certificate from PEM file '%s'.\n",
3072 proxy_type_str(curproxy), curproxy->id,
3073 srv->id, srv->ssl_ctx.client_crt);
3074 cfgerr++;
3075 }
3076 else if (SSL_CTX_check_private_key(srv->ssl_ctx.ctx) <= 0) {
3077 Alert("config : %s '%s', server '%s': inconsistencies between private key and certificate loaded from PEM file '%s'.\n",
3078 proxy_type_str(curproxy), curproxy->id,
3079 srv->id, srv->ssl_ctx.client_crt);
3080 cfgerr++;
3081 }
3082 }
Emeric Brun94324a42012-10-11 14:00:19 +02003083
3084 if (srv->ssl_ctx.options & SRV_SSL_O_NO_SSLV3)
3085 options |= SSL_OP_NO_SSLv3;
3086 if (srv->ssl_ctx.options & SRV_SSL_O_NO_TLSV10)
3087 options |= SSL_OP_NO_TLSv1;
3088 if (srv->ssl_ctx.options & SRV_SSL_O_NO_TLSV11)
3089 options |= SSL_OP_NO_TLSv1_1;
3090 if (srv->ssl_ctx.options & SRV_SSL_O_NO_TLSV12)
3091 options |= SSL_OP_NO_TLSv1_2;
Emeric Brunf9c5c472012-10-11 15:28:34 +02003092 if (srv->ssl_ctx.options & SRV_SSL_O_NO_TLS_TICKETS)
3093 options |= SSL_OP_NO_TICKET;
Jérémie Courrèges-Anglas17c3f622015-07-25 16:50:52 -06003094 if (srv->ssl_ctx.options & SRV_SSL_O_USE_SSLV3) {
3095#ifndef OPENSSL_NO_SSL3
Emeric Brun94324a42012-10-11 14:00:19 +02003096 SSL_CTX_set_ssl_version(srv->ssl_ctx.ctx, SSLv3_client_method());
Jérémie Courrèges-Anglas17c3f622015-07-25 16:50:52 -06003097#else
Thierry FOURNIERbc965342015-08-26 08:21:26 +02003098 Alert("SSLv3 support requested but unavailable.\n");
Jérémie Courrèges-Anglas17c3f622015-07-25 16:50:52 -06003099 cfgerr++;
3100#endif
3101 }
Emeric Brun94324a42012-10-11 14:00:19 +02003102 if (srv->ssl_ctx.options & SRV_SSL_O_USE_TLSV10)
3103 SSL_CTX_set_ssl_version(srv->ssl_ctx.ctx, TLSv1_client_method());
3104#if SSL_OP_NO_TLSv1_1
3105 if (srv->ssl_ctx.options & SRV_SSL_O_USE_TLSV11)
3106 SSL_CTX_set_ssl_version(srv->ssl_ctx.ctx, TLSv1_1_client_method());
3107#endif
3108#if SSL_OP_NO_TLSv1_2
3109 if (srv->ssl_ctx.options & SRV_SSL_O_USE_TLSV12)
3110 SSL_CTX_set_ssl_version(srv->ssl_ctx.ctx, TLSv1_2_client_method());
3111#endif
3112
3113 SSL_CTX_set_options(srv->ssl_ctx.ctx, options);
3114 SSL_CTX_set_mode(srv->ssl_ctx.ctx, mode);
Emeric Brun850efd52014-01-29 12:24:34 +01003115
3116 if (global.ssl_server_verify == SSL_SERVER_VERIFY_REQUIRED)
3117 verify = SSL_VERIFY_PEER;
3118
3119 switch (srv->ssl_ctx.verify) {
3120 case SSL_SOCK_VERIFY_NONE:
3121 verify = SSL_VERIFY_NONE;
3122 break;
3123 case SSL_SOCK_VERIFY_REQUIRED:
3124 verify = SSL_VERIFY_PEER;
3125 break;
3126 }
Evan Broderbe554312013-06-27 00:05:25 -07003127 SSL_CTX_set_verify(srv->ssl_ctx.ctx,
Emeric Brun850efd52014-01-29 12:24:34 +01003128 verify,
Evan Broderbe554312013-06-27 00:05:25 -07003129 srv->ssl_ctx.verify_host ? ssl_sock_srv_verifycbk : NULL);
Emeric Brun850efd52014-01-29 12:24:34 +01003130 if (verify & SSL_VERIFY_PEER) {
Emeric Brunef42d922012-10-11 16:11:36 +02003131 if (srv->ssl_ctx.ca_file) {
3132 /* load CAfile to verify */
3133 if (!SSL_CTX_load_verify_locations(srv->ssl_ctx.ctx, srv->ssl_ctx.ca_file, NULL)) {
Willy Tarreau07ba08b2014-02-16 19:22:08 +01003134 Alert("Proxy '%s', server '%s' [%s:%d] unable to load CA file '%s'.\n",
Emeric Brunef42d922012-10-11 16:11:36 +02003135 curproxy->id, srv->id,
3136 srv->conf.file, srv->conf.line, srv->ssl_ctx.ca_file);
3137 cfgerr++;
3138 }
3139 }
Emeric Brun850efd52014-01-29 12:24:34 +01003140 else {
3141 if (global.ssl_server_verify == SSL_SERVER_VERIFY_REQUIRED)
Willy Tarreau07ba08b2014-02-16 19:22:08 +01003142 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 +01003143 curproxy->id, srv->id,
3144 srv->conf.file, srv->conf.line);
3145 else
Willy Tarreau07ba08b2014-02-16 19:22:08 +01003146 Alert("Proxy '%s', server '%s' [%s:%d] verify is enabled but no CA file specified.\n",
Emeric Brun850efd52014-01-29 12:24:34 +01003147 curproxy->id, srv->id,
3148 srv->conf.file, srv->conf.line);
3149 cfgerr++;
3150 }
Emeric Brunef42d922012-10-11 16:11:36 +02003151#ifdef X509_V_FLAG_CRL_CHECK
3152 if (srv->ssl_ctx.crl_file) {
3153 X509_STORE *store = SSL_CTX_get_cert_store(srv->ssl_ctx.ctx);
3154
3155 if (!store || !X509_STORE_load_locations(store, srv->ssl_ctx.crl_file, NULL)) {
Willy Tarreau07ba08b2014-02-16 19:22:08 +01003156 Alert("Proxy '%s', server '%s' [%s:%d] unable to configure CRL file '%s'.\n",
Emeric Brunef42d922012-10-11 16:11:36 +02003157 curproxy->id, srv->id,
3158 srv->conf.file, srv->conf.line, srv->ssl_ctx.crl_file);
3159 cfgerr++;
3160 }
3161 else {
3162 X509_STORE_set_flags(store, X509_V_FLAG_CRL_CHECK|X509_V_FLAG_CRL_CHECK_ALL);
3163 }
3164 }
3165#endif
3166 }
3167
Emeric Brun4f65bff2012-11-16 15:11:00 +01003168 if (global.tune.ssllifetime)
3169 SSL_CTX_set_timeout(srv->ssl_ctx.ctx, global.tune.ssllifetime);
3170
Emeric Brun94324a42012-10-11 14:00:19 +02003171 SSL_CTX_set_session_cache_mode(srv->ssl_ctx.ctx, SSL_SESS_CACHE_OFF);
3172 if (srv->ssl_ctx.ciphers &&
3173 !SSL_CTX_set_cipher_list(srv->ssl_ctx.ctx, srv->ssl_ctx.ciphers)) {
3174 Alert("Proxy '%s', server '%s' [%s:%d] : unable to set SSL cipher list to '%s'.\n",
3175 curproxy->id, srv->id,
3176 srv->conf.file, srv->conf.line, srv->ssl_ctx.ciphers);
3177 cfgerr++;
3178 }
3179
3180 return cfgerr;
3181}
3182
Willy Tarreau2a65ff02012-09-13 17:54:29 +02003183/* Walks down the two trees in bind_conf and prepares all certs. The pointer may
Emeric Brunfc0421f2012-09-07 17:30:07 +02003184 * be NULL, in which case nothing is done. Returns the number of errors
3185 * encountered.
3186 */
Willy Tarreau2a65ff02012-09-13 17:54:29 +02003187int ssl_sock_prepare_all_ctx(struct bind_conf *bind_conf, struct proxy *px)
Emeric Brunfc0421f2012-09-07 17:30:07 +02003188{
3189 struct ebmb_node *node;
3190 struct sni_ctx *sni;
3191 int err = 0;
3192
Willy Tarreau2a65ff02012-09-13 17:54:29 +02003193 if (!bind_conf || !bind_conf->is_ssl)
Emeric Brunfc0421f2012-09-07 17:30:07 +02003194 return 0;
3195
Willy Tarreaufce03112015-01-15 21:32:40 +01003196 /* Automatic memory computations need to know we use SSL there */
3197 global.ssl_used_frontend = 1;
3198
Emeric Brun0bed9942014-10-30 19:25:24 +01003199 if (bind_conf->default_ctx)
3200 err += ssl_sock_prepare_ctx(bind_conf, bind_conf->default_ctx, px);
3201
Willy Tarreau2a65ff02012-09-13 17:54:29 +02003202 node = ebmb_first(&bind_conf->sni_ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02003203 while (node) {
3204 sni = ebmb_entry(node, struct sni_ctx, name);
Emeric Brun0bed9942014-10-30 19:25:24 +01003205 if (!sni->order && sni->ctx != bind_conf->default_ctx)
3206 /* only initialize the CTX on its first occurrence and
3207 if it is not the default_ctx */
Willy Tarreau2a65ff02012-09-13 17:54:29 +02003208 err += ssl_sock_prepare_ctx(bind_conf, sni->ctx, px);
Emeric Brunfc0421f2012-09-07 17:30:07 +02003209 node = ebmb_next(node);
3210 }
3211
Willy Tarreau2a65ff02012-09-13 17:54:29 +02003212 node = ebmb_first(&bind_conf->sni_w_ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02003213 while (node) {
3214 sni = ebmb_entry(node, struct sni_ctx, name);
Emeric Brun0bed9942014-10-30 19:25:24 +01003215 if (!sni->order && sni->ctx != bind_conf->default_ctx)
3216 /* only initialize the CTX on its first occurrence and
3217 if it is not the default_ctx */
Willy Tarreau2a65ff02012-09-13 17:54:29 +02003218 err += ssl_sock_prepare_ctx(bind_conf, sni->ctx, px);
Emeric Brunfc0421f2012-09-07 17:30:07 +02003219 node = ebmb_next(node);
3220 }
3221 return err;
3222}
3223
Christopher Faulet77fe80c2015-07-29 13:02:40 +02003224
3225/* release ssl context allocated for servers. */
3226void ssl_sock_free_srv_ctx(struct server *srv)
3227{
3228 if (srv->ssl_ctx.ctx)
3229 SSL_CTX_free(srv->ssl_ctx.ctx);
3230}
3231
Willy Tarreau2a65ff02012-09-13 17:54:29 +02003232/* Walks down the two trees in bind_conf and frees all the certs. The pointer may
Emeric Brunfc0421f2012-09-07 17:30:07 +02003233 * be NULL, in which case nothing is done. The default_ctx is nullified too.
3234 */
Willy Tarreau2a65ff02012-09-13 17:54:29 +02003235void ssl_sock_free_all_ctx(struct bind_conf *bind_conf)
Emeric Brunfc0421f2012-09-07 17:30:07 +02003236{
3237 struct ebmb_node *node, *back;
3238 struct sni_ctx *sni;
3239
Willy Tarreau2a65ff02012-09-13 17:54:29 +02003240 if (!bind_conf || !bind_conf->is_ssl)
Emeric Brunfc0421f2012-09-07 17:30:07 +02003241 return;
3242
Willy Tarreau2a65ff02012-09-13 17:54:29 +02003243 node = ebmb_first(&bind_conf->sni_ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02003244 while (node) {
3245 sni = ebmb_entry(node, struct sni_ctx, name);
3246 back = ebmb_next(node);
3247 ebmb_delete(node);
3248 if (!sni->order) /* only free the CTX on its first occurrence */
3249 SSL_CTX_free(sni->ctx);
3250 free(sni);
3251 node = back;
3252 }
3253
Willy Tarreau2a65ff02012-09-13 17:54:29 +02003254 node = ebmb_first(&bind_conf->sni_w_ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02003255 while (node) {
3256 sni = ebmb_entry(node, struct sni_ctx, name);
3257 back = ebmb_next(node);
3258 ebmb_delete(node);
3259 if (!sni->order) /* only free the CTX on its first occurrence */
3260 SSL_CTX_free(sni->ctx);
3261 free(sni);
3262 node = back;
3263 }
3264
Willy Tarreau2a65ff02012-09-13 17:54:29 +02003265 bind_conf->default_ctx = NULL;
Emeric Brune1f38db2012-09-03 20:36:47 +02003266}
3267
Christopher Faulet31af49d2015-06-09 17:29:50 +02003268/* Load CA cert file and private key used to generate certificates */
3269int
3270ssl_sock_load_ca(struct bind_conf *bind_conf, struct proxy *px)
3271{
3272 FILE *fp;
3273 X509 *cacert = NULL;
3274 EVP_PKEY *capkey = NULL;
3275 int err = 0;
3276
3277 if (!bind_conf || !bind_conf->generate_certs)
3278 return err;
3279
Willy Tarreaua84c2672015-10-09 12:10:13 +02003280#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Christopher Fauletd2cab922015-07-28 16:03:47 +02003281 if (global.tune.ssl_ctx_cache)
3282 ssl_ctx_lru_tree = lru64_new(global.tune.ssl_ctx_cache);
3283 ssl_ctx_lru_seed = (unsigned int)time(NULL);
Willy Tarreaua84c2672015-10-09 12:10:13 +02003284#endif
Christopher Fauletd2cab922015-07-28 16:03:47 +02003285
Christopher Faulet31af49d2015-06-09 17:29:50 +02003286 if (!bind_conf->ca_sign_file) {
3287 Alert("Proxy '%s': cannot enable certificate generation, "
3288 "no CA certificate File configured at [%s:%d].\n",
3289 px->id, bind_conf->file, bind_conf->line);
Christopher Faulet31af49d2015-06-09 17:29:50 +02003290 goto load_error;
Christopher Fauletc6f02fb2015-10-09 10:53:31 +02003291 }
Christopher Faulet31af49d2015-06-09 17:29:50 +02003292
3293 /* read in the CA certificate */
3294 if (!(fp = fopen(bind_conf->ca_sign_file, "r"))) {
3295 Alert("Proxy '%s': Failed to read CA certificate file '%s' at [%s:%d].\n",
3296 px->id, bind_conf->ca_sign_file, bind_conf->file, bind_conf->line);
Christopher Faulet31af49d2015-06-09 17:29:50 +02003297 goto load_error;
3298 }
3299 if (!(cacert = PEM_read_X509(fp, NULL, NULL, NULL))) {
3300 Alert("Proxy '%s': Failed to read CA certificate file '%s' at [%s:%d].\n",
3301 px->id, bind_conf->ca_sign_file, bind_conf->file, bind_conf->line);
Christopher Fauletc6f02fb2015-10-09 10:53:31 +02003302 goto read_error;
Christopher Faulet31af49d2015-06-09 17:29:50 +02003303 }
Christopher Fauletc6f02fb2015-10-09 10:53:31 +02003304 rewind(fp);
Christopher Faulet31af49d2015-06-09 17:29:50 +02003305 if (!(capkey = PEM_read_PrivateKey(fp, NULL, NULL, bind_conf->ca_sign_pass))) {
3306 Alert("Proxy '%s': Failed to read CA private key file '%s' at [%s:%d].\n",
3307 px->id, bind_conf->ca_sign_file, bind_conf->file, bind_conf->line);
Christopher Fauletc6f02fb2015-10-09 10:53:31 +02003308 goto read_error;
Christopher Faulet31af49d2015-06-09 17:29:50 +02003309 }
Christopher Faulet31af49d2015-06-09 17:29:50 +02003310
Christopher Fauletc6f02fb2015-10-09 10:53:31 +02003311 fclose (fp);
Christopher Faulet31af49d2015-06-09 17:29:50 +02003312 bind_conf->ca_sign_cert = cacert;
3313 bind_conf->ca_sign_pkey = capkey;
3314 return err;
3315
Christopher Fauletc6f02fb2015-10-09 10:53:31 +02003316 read_error:
3317 fclose (fp);
Christopher Faulet31af49d2015-06-09 17:29:50 +02003318 if (capkey) EVP_PKEY_free(capkey);
3319 if (cacert) X509_free(cacert);
Christopher Fauletc6f02fb2015-10-09 10:53:31 +02003320 load_error:
3321 bind_conf->generate_certs = 0;
3322 err++;
Christopher Faulet31af49d2015-06-09 17:29:50 +02003323 return err;
3324}
3325
3326/* Release CA cert and private key used to generate certificated */
3327void
3328ssl_sock_free_ca(struct bind_conf *bind_conf)
3329{
3330 if (!bind_conf)
3331 return;
3332
3333 if (bind_conf->ca_sign_pkey)
3334 EVP_PKEY_free(bind_conf->ca_sign_pkey);
3335 if (bind_conf->ca_sign_cert)
3336 X509_free(bind_conf->ca_sign_cert);
Willy Tarreau94ff03a2016-12-22 17:57:46 +01003337 bind_conf->ca_sign_pkey = NULL;
3338 bind_conf->ca_sign_cert = NULL;
Christopher Faulet31af49d2015-06-09 17:29:50 +02003339}
3340
Emeric Brun46591952012-05-18 15:47:34 +02003341/*
3342 * This function is called if SSL * context is not yet allocated. The function
3343 * is designed to be called before any other data-layer operation and sets the
3344 * handshake flag on the connection. It is safe to call it multiple times.
3345 * It returns 0 on success and -1 in error case.
3346 */
3347static int ssl_sock_init(struct connection *conn)
3348{
3349 /* already initialized */
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02003350 if (conn->xprt_ctx)
Emeric Brun46591952012-05-18 15:47:34 +02003351 return 0;
3352
Willy Tarreau3c728722014-01-23 13:50:42 +01003353 if (!conn_ctrl_ready(conn))
Willy Tarreauf79c8172013-10-21 16:30:56 +02003354 return 0;
3355
Willy Tarreau20879a02012-12-03 16:32:10 +01003356 if (global.maxsslconn && sslconns >= global.maxsslconn) {
3357 conn->err_code = CO_ER_SSL_TOO_MANY;
Willy Tarreau403edff2012-09-06 11:58:37 +02003358 return -1;
Willy Tarreau20879a02012-12-03 16:32:10 +01003359 }
Willy Tarreau403edff2012-09-06 11:58:37 +02003360
Emeric Brun46591952012-05-18 15:47:34 +02003361 /* If it is in client mode initiate SSL session
3362 in connect state otherwise accept state */
Willy Tarreau3fdb3662012-11-12 00:42:33 +01003363 if (objt_server(conn->target)) {
Willy Tarreaufba03cd2014-11-13 13:48:58 +01003364 int may_retry = 1;
3365
3366 retry_connect:
Emeric Brun46591952012-05-18 15:47:34 +02003367 /* Alloc a new SSL session ctx */
Willy Tarreau3fdb3662012-11-12 00:42:33 +01003368 conn->xprt_ctx = SSL_new(objt_server(conn->target)->ssl_ctx.ctx);
Willy Tarreau20879a02012-12-03 16:32:10 +01003369 if (!conn->xprt_ctx) {
Willy Tarreaufba03cd2014-11-13 13:48:58 +01003370 if (may_retry--) {
3371 pool_gc2();
3372 goto retry_connect;
3373 }
Willy Tarreau20879a02012-12-03 16:32:10 +01003374 conn->err_code = CO_ER_SSL_NO_MEM;
Emeric Brun46591952012-05-18 15:47:34 +02003375 return -1;
Willy Tarreau20879a02012-12-03 16:32:10 +01003376 }
Emeric Brun46591952012-05-18 15:47:34 +02003377
Emeric Brun46591952012-05-18 15:47:34 +02003378 /* set fd on SSL session context */
Emeric Brun55476152014-11-12 17:35:37 +01003379 if (!SSL_set_fd(conn->xprt_ctx, conn->t.sock.fd)) {
3380 SSL_free(conn->xprt_ctx);
3381 conn->xprt_ctx = NULL;
Willy Tarreaufba03cd2014-11-13 13:48:58 +01003382 if (may_retry--) {
3383 pool_gc2();
3384 goto retry_connect;
3385 }
Emeric Brun55476152014-11-12 17:35:37 +01003386 conn->err_code = CO_ER_SSL_NO_MEM;
3387 return -1;
3388 }
Emeric Brun46591952012-05-18 15:47:34 +02003389
Evan Broderbe554312013-06-27 00:05:25 -07003390 /* set connection pointer */
Emeric Brun55476152014-11-12 17:35:37 +01003391 if (!SSL_set_app_data(conn->xprt_ctx, conn)) {
3392 SSL_free(conn->xprt_ctx);
3393 conn->xprt_ctx = NULL;
Willy Tarreaufba03cd2014-11-13 13:48:58 +01003394 if (may_retry--) {
3395 pool_gc2();
3396 goto retry_connect;
3397 }
Emeric Brun55476152014-11-12 17:35:37 +01003398 conn->err_code = CO_ER_SSL_NO_MEM;
3399 return -1;
3400 }
3401
3402 SSL_set_connect_state(conn->xprt_ctx);
3403 if (objt_server(conn->target)->ssl_ctx.reused_sess) {
3404 if(!SSL_set_session(conn->xprt_ctx, objt_server(conn->target)->ssl_ctx.reused_sess)) {
3405 SSL_SESSION_free(objt_server(conn->target)->ssl_ctx.reused_sess);
3406 objt_server(conn->target)->ssl_ctx.reused_sess = NULL;
3407 }
3408 }
Evan Broderbe554312013-06-27 00:05:25 -07003409
Emeric Brun46591952012-05-18 15:47:34 +02003410 /* leave init state and start handshake */
Willy Tarreau05737472012-09-04 08:03:39 +02003411 conn->flags |= CO_FL_SSL_WAIT_HS | CO_FL_WAIT_L6_CONN;
Willy Tarreau403edff2012-09-06 11:58:37 +02003412
3413 sslconns++;
Willy Tarreau71b734c2014-01-28 15:19:44 +01003414 totalsslconns++;
Emeric Brun46591952012-05-18 15:47:34 +02003415 return 0;
3416 }
Willy Tarreau3fdb3662012-11-12 00:42:33 +01003417 else if (objt_listener(conn->target)) {
Willy Tarreaufba03cd2014-11-13 13:48:58 +01003418 int may_retry = 1;
3419
3420 retry_accept:
Emeric Brun46591952012-05-18 15:47:34 +02003421 /* Alloc a new SSL session ctx */
Willy Tarreau3fdb3662012-11-12 00:42:33 +01003422 conn->xprt_ctx = SSL_new(objt_listener(conn->target)->bind_conf->default_ctx);
Willy Tarreau20879a02012-12-03 16:32:10 +01003423 if (!conn->xprt_ctx) {
Willy Tarreaufba03cd2014-11-13 13:48:58 +01003424 if (may_retry--) {
3425 pool_gc2();
3426 goto retry_accept;
3427 }
Willy Tarreau20879a02012-12-03 16:32:10 +01003428 conn->err_code = CO_ER_SSL_NO_MEM;
Emeric Brun46591952012-05-18 15:47:34 +02003429 return -1;
Willy Tarreau20879a02012-12-03 16:32:10 +01003430 }
Emeric Brun46591952012-05-18 15:47:34 +02003431
Emeric Brun46591952012-05-18 15:47:34 +02003432 /* set fd on SSL session context */
Emeric Brun55476152014-11-12 17:35:37 +01003433 if (!SSL_set_fd(conn->xprt_ctx, conn->t.sock.fd)) {
3434 SSL_free(conn->xprt_ctx);
3435 conn->xprt_ctx = NULL;
Willy Tarreaufba03cd2014-11-13 13:48:58 +01003436 if (may_retry--) {
3437 pool_gc2();
3438 goto retry_accept;
3439 }
Emeric Brun55476152014-11-12 17:35:37 +01003440 conn->err_code = CO_ER_SSL_NO_MEM;
3441 return -1;
3442 }
Emeric Brun46591952012-05-18 15:47:34 +02003443
Emeric Brune1f38db2012-09-03 20:36:47 +02003444 /* set connection pointer */
Emeric Brun55476152014-11-12 17:35:37 +01003445 if (!SSL_set_app_data(conn->xprt_ctx, conn)) {
3446 SSL_free(conn->xprt_ctx);
3447 conn->xprt_ctx = NULL;
Willy Tarreaufba03cd2014-11-13 13:48:58 +01003448 if (may_retry--) {
3449 pool_gc2();
3450 goto retry_accept;
3451 }
Emeric Brun55476152014-11-12 17:35:37 +01003452 conn->err_code = CO_ER_SSL_NO_MEM;
3453 return -1;
3454 }
3455
3456 SSL_set_accept_state(conn->xprt_ctx);
Emeric Brune1f38db2012-09-03 20:36:47 +02003457
Emeric Brun46591952012-05-18 15:47:34 +02003458 /* leave init state and start handshake */
Willy Tarreau05737472012-09-04 08:03:39 +02003459 conn->flags |= CO_FL_SSL_WAIT_HS | CO_FL_WAIT_L6_CONN;
Willy Tarreau403edff2012-09-06 11:58:37 +02003460
3461 sslconns++;
Willy Tarreau71b734c2014-01-28 15:19:44 +01003462 totalsslconns++;
Emeric Brun46591952012-05-18 15:47:34 +02003463 return 0;
3464 }
3465 /* don't know how to handle such a target */
Willy Tarreau20879a02012-12-03 16:32:10 +01003466 conn->err_code = CO_ER_SSL_NO_TARGET;
Emeric Brun46591952012-05-18 15:47:34 +02003467 return -1;
3468}
3469
3470
3471/* This is the callback which is used when an SSL handshake is pending. It
3472 * updates the FD status if it wants some polling before being called again.
3473 * It returns 0 if it fails in a fatal way or needs to poll to go further,
3474 * otherwise it returns non-zero and removes itself from the connection's
3475 * flags (the bit is provided in <flag> by the caller).
3476 */
3477int ssl_sock_handshake(struct connection *conn, unsigned int flag)
3478{
3479 int ret;
3480
Willy Tarreau3c728722014-01-23 13:50:42 +01003481 if (!conn_ctrl_ready(conn))
Willy Tarreauf79c8172013-10-21 16:30:56 +02003482 return 0;
3483
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02003484 if (!conn->xprt_ctx)
Emeric Brun46591952012-05-18 15:47:34 +02003485 goto out_error;
3486
Emeric Brun674b7432012-11-08 19:21:55 +01003487 /* If we use SSL_do_handshake to process a reneg initiated by
3488 * the remote peer, it sometimes returns SSL_ERROR_SSL.
3489 * Usually SSL_write and SSL_read are used and process implicitly
3490 * the reneg handshake.
3491 * Here we use SSL_peek as a workaround for reneg.
3492 */
3493 if ((conn->flags & CO_FL_CONNECTED) && SSL_renegotiate_pending(conn->xprt_ctx)) {
3494 char c;
3495
3496 ret = SSL_peek(conn->xprt_ctx, &c, 1);
3497 if (ret <= 0) {
3498 /* handshake may have not been completed, let's find why */
3499 ret = SSL_get_error(conn->xprt_ctx, ret);
3500 if (ret == SSL_ERROR_WANT_WRITE) {
3501 /* SSL handshake needs to write, L4 connection may not be ready */
3502 __conn_sock_stop_recv(conn);
Willy Tarreaue1f50c42014-01-22 20:02:06 +01003503 __conn_sock_want_send(conn);
3504 fd_cant_send(conn->t.sock.fd);
Emeric Brun674b7432012-11-08 19:21:55 +01003505 return 0;
3506 }
3507 else if (ret == SSL_ERROR_WANT_READ) {
3508 /* handshake may have been completed but we have
3509 * no more data to read.
3510 */
3511 if (!SSL_renegotiate_pending(conn->xprt_ctx)) {
3512 ret = 1;
3513 goto reneg_ok;
3514 }
3515 /* SSL handshake needs to read, L4 connection is ready */
3516 if (conn->flags & CO_FL_WAIT_L4_CONN)
3517 conn->flags &= ~CO_FL_WAIT_L4_CONN;
3518 __conn_sock_stop_send(conn);
Willy Tarreaue1f50c42014-01-22 20:02:06 +01003519 __conn_sock_want_recv(conn);
3520 fd_cant_recv(conn->t.sock.fd);
Emeric Brun674b7432012-11-08 19:21:55 +01003521 return 0;
3522 }
3523 else if (ret == SSL_ERROR_SYSCALL) {
3524 /* if errno is null, then connection was successfully established */
3525 if (!errno && conn->flags & CO_FL_WAIT_L4_CONN)
3526 conn->flags &= ~CO_FL_WAIT_L4_CONN;
Willy Tarreau20879a02012-12-03 16:32:10 +01003527 if (!conn->err_code) {
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02003528 int empty_handshake;
Luca Pizzamiglio578b1692016-12-12 10:56:56 +01003529#if (OPENSSL_VERSION_NUMBER >= 0x1010000fL) && !defined(LIBRESSL_VERSION_NUMBER)
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02003530 OSSL_HANDSHAKE_STATE state = SSL_get_state((SSL *)conn->xprt_ctx);
3531 empty_handshake = state == TLS_ST_BEFORE;
3532#else
3533 empty_handshake = !((SSL *)conn->xprt_ctx)->packet_length;
3534#endif
3535
3536 if (empty_handshake) {
Emeric Brun29f037d2014-04-25 19:05:36 +02003537 if (!errno) {
3538 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
3539 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
3540 else
3541 conn->err_code = CO_ER_SSL_EMPTY;
3542 }
3543 else {
3544 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
3545 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
3546 else
3547 conn->err_code = CO_ER_SSL_ABORT;
3548 }
3549 }
3550 else {
3551 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
3552 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
Willy Tarreau20879a02012-12-03 16:32:10 +01003553 else
Emeric Brun29f037d2014-04-25 19:05:36 +02003554 conn->err_code = CO_ER_SSL_HANDSHAKE;
3555 }
Willy Tarreau20879a02012-12-03 16:32:10 +01003556 }
Emeric Brun674b7432012-11-08 19:21:55 +01003557 goto out_error;
3558 }
3559 else {
3560 /* Fail on all other handshake errors */
3561 /* Note: OpenSSL may leave unread bytes in the socket's
3562 * buffer, causing an RST to be emitted upon close() on
3563 * TCP sockets. We first try to drain possibly pending
3564 * data to avoid this as much as possible.
3565 */
Willy Tarreaud85c4852015-03-13 00:40:28 +01003566 conn_sock_drain(conn);
Willy Tarreau20879a02012-12-03 16:32:10 +01003567 if (!conn->err_code)
Willy Tarreauf51c6982014-04-25 20:02:39 +02003568 conn->err_code = (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT) ?
3569 CO_ER_SSL_KILLED_HB : CO_ER_SSL_HANDSHAKE;
Emeric Brun674b7432012-11-08 19:21:55 +01003570 goto out_error;
3571 }
3572 }
3573 /* read some data: consider handshake completed */
3574 goto reneg_ok;
3575 }
3576
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02003577 ret = SSL_do_handshake(conn->xprt_ctx);
Emeric Brun46591952012-05-18 15:47:34 +02003578 if (ret != 1) {
3579 /* handshake did not complete, let's find why */
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02003580 ret = SSL_get_error(conn->xprt_ctx, ret);
Emeric Brun46591952012-05-18 15:47:34 +02003581
3582 if (ret == SSL_ERROR_WANT_WRITE) {
3583 /* SSL handshake needs to write, L4 connection may not be ready */
3584 __conn_sock_stop_recv(conn);
Willy Tarreaue1f50c42014-01-22 20:02:06 +01003585 __conn_sock_want_send(conn);
3586 fd_cant_send(conn->t.sock.fd);
Emeric Brun46591952012-05-18 15:47:34 +02003587 return 0;
3588 }
3589 else if (ret == SSL_ERROR_WANT_READ) {
3590 /* SSL handshake needs to read, L4 connection is ready */
3591 if (conn->flags & CO_FL_WAIT_L4_CONN)
3592 conn->flags &= ~CO_FL_WAIT_L4_CONN;
3593 __conn_sock_stop_send(conn);
Willy Tarreaue1f50c42014-01-22 20:02:06 +01003594 __conn_sock_want_recv(conn);
3595 fd_cant_recv(conn->t.sock.fd);
Emeric Brun46591952012-05-18 15:47:34 +02003596 return 0;
3597 }
Willy Tarreau89230192012-09-28 20:22:13 +02003598 else if (ret == SSL_ERROR_SYSCALL) {
Luca Pizzamiglio578b1692016-12-12 10:56:56 +01003599#if (OPENSSL_VERSION_NUMBER >= 0x1010000fL) && !defined(LIBRESSL_VERSION_NUMBER)
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02003600 OSSL_HANDSHAKE_STATE state;
3601#endif
3602 int empty_handshake;
Willy Tarreau89230192012-09-28 20:22:13 +02003603 /* if errno is null, then connection was successfully established */
3604 if (!errno && conn->flags & CO_FL_WAIT_L4_CONN)
3605 conn->flags &= ~CO_FL_WAIT_L4_CONN;
Willy Tarreau20879a02012-12-03 16:32:10 +01003606
Luca Pizzamiglio578b1692016-12-12 10:56:56 +01003607#if (OPENSSL_VERSION_NUMBER >= 0x1010000fL) && !defined(LIBRESSL_VERSION_NUMBER)
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02003608 state = SSL_get_state((SSL *)conn->xprt_ctx);
3609 empty_handshake = state == TLS_ST_BEFORE;
3610#else
3611 empty_handshake = !((SSL *)conn->xprt_ctx)->packet_length;
3612#endif
3613 if (empty_handshake) {
Emeric Brun29f037d2014-04-25 19:05:36 +02003614 if (!errno) {
3615 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
3616 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
3617 else
3618 conn->err_code = CO_ER_SSL_EMPTY;
3619 }
3620 else {
3621 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
3622 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
3623 else
3624 conn->err_code = CO_ER_SSL_ABORT;
3625 }
3626 }
3627 else {
3628 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
3629 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
Willy Tarreau20879a02012-12-03 16:32:10 +01003630 else
Emeric Brun29f037d2014-04-25 19:05:36 +02003631 conn->err_code = CO_ER_SSL_HANDSHAKE;
3632 }
Willy Tarreau89230192012-09-28 20:22:13 +02003633 goto out_error;
3634 }
Emeric Brun46591952012-05-18 15:47:34 +02003635 else {
3636 /* Fail on all other handshake errors */
Willy Tarreau566dc552012-10-19 20:52:18 +02003637 /* Note: OpenSSL may leave unread bytes in the socket's
3638 * buffer, causing an RST to be emitted upon close() on
3639 * TCP sockets. We first try to drain possibly pending
3640 * data to avoid this as much as possible.
3641 */
Willy Tarreaud85c4852015-03-13 00:40:28 +01003642 conn_sock_drain(conn);
Willy Tarreau20879a02012-12-03 16:32:10 +01003643 if (!conn->err_code)
Willy Tarreauf51c6982014-04-25 20:02:39 +02003644 conn->err_code = (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT) ?
3645 CO_ER_SSL_KILLED_HB : CO_ER_SSL_HANDSHAKE;
Emeric Brun46591952012-05-18 15:47:34 +02003646 goto out_error;
3647 }
3648 }
3649
Emeric Brun674b7432012-11-08 19:21:55 +01003650reneg_ok:
Emeric Brun46591952012-05-18 15:47:34 +02003651 /* Handshake succeeded */
Willy Tarreau0c9c2722014-05-28 12:28:58 +02003652 if (!SSL_session_reused(conn->xprt_ctx)) {
3653 if (objt_server(conn->target)) {
3654 update_freq_ctr(&global.ssl_be_keys_per_sec, 1);
3655 if (global.ssl_be_keys_per_sec.curr_ctr > global.ssl_be_keys_max)
3656 global.ssl_be_keys_max = global.ssl_be_keys_per_sec.curr_ctr;
3657
Emeric Brun46591952012-05-18 15:47:34 +02003658 /* check if session was reused, if not store current session on server for reuse */
Willy Tarreau30fd4bd2016-12-22 21:54:21 +01003659 if (objt_server(conn->target)->ssl_ctx.reused_sess) {
Willy Tarreau3fdb3662012-11-12 00:42:33 +01003660 SSL_SESSION_free(objt_server(conn->target)->ssl_ctx.reused_sess);
Willy Tarreau30fd4bd2016-12-22 21:54:21 +01003661 objt_server(conn->target)->ssl_ctx.reused_sess = NULL;
3662 }
Emeric Brun46591952012-05-18 15:47:34 +02003663
Willy Tarreau2a3fb1c2015-02-05 16:47:07 +01003664 if (!(objt_server(conn->target)->ssl_ctx.options & SRV_SSL_O_NO_REUSE))
3665 objt_server(conn->target)->ssl_ctx.reused_sess = SSL_get1_session(conn->xprt_ctx);
Emeric Brun46591952012-05-18 15:47:34 +02003666 }
Willy Tarreau0c9c2722014-05-28 12:28:58 +02003667 else {
3668 update_freq_ctr(&global.ssl_fe_keys_per_sec, 1);
3669 if (global.ssl_fe_keys_per_sec.curr_ctr > global.ssl_fe_keys_max)
3670 global.ssl_fe_keys_max = global.ssl_fe_keys_per_sec.curr_ctr;
3671 }
Emeric Brun46591952012-05-18 15:47:34 +02003672 }
3673
3674 /* The connection is now established at both layers, it's time to leave */
3675 conn->flags &= ~(flag | CO_FL_WAIT_L4_CONN | CO_FL_WAIT_L6_CONN);
3676 return 1;
3677
3678 out_error:
Emeric Brun644cde02012-12-14 11:21:13 +01003679 /* Clear openssl global errors stack */
Thierry FOURNIER / OZON.IO8b068c22016-10-10 11:59:50 +02003680 ssl_sock_dump_errors(conn);
Emeric Brun644cde02012-12-14 11:21:13 +01003681 ERR_clear_error();
3682
Emeric Brun9fa89732012-10-04 17:09:56 +02003683 /* free resumed session if exists */
Willy Tarreau3fdb3662012-11-12 00:42:33 +01003684 if (objt_server(conn->target) && objt_server(conn->target)->ssl_ctx.reused_sess) {
3685 SSL_SESSION_free(objt_server(conn->target)->ssl_ctx.reused_sess);
3686 objt_server(conn->target)->ssl_ctx.reused_sess = NULL;
Emeric Brun9fa89732012-10-04 17:09:56 +02003687 }
3688
Emeric Brun46591952012-05-18 15:47:34 +02003689 /* Fail on all other handshake errors */
3690 conn->flags |= CO_FL_ERROR;
Willy Tarreau20879a02012-12-03 16:32:10 +01003691 if (!conn->err_code)
3692 conn->err_code = CO_ER_SSL_HANDSHAKE;
Emeric Brun46591952012-05-18 15:47:34 +02003693 return 0;
3694}
3695
3696/* Receive up to <count> bytes from connection <conn>'s socket and store them
Willy Tarreauabf08d92014-01-14 11:31:27 +01003697 * into buffer <buf>. Only one call to recv() is performed, unless the
Emeric Brun46591952012-05-18 15:47:34 +02003698 * buffer wraps, in which case a second call may be performed. The connection's
3699 * flags are updated with whatever special event is detected (error, read0,
3700 * empty). The caller is responsible for taking care of those events and
3701 * avoiding the call if inappropriate. The function does not call the
3702 * connection's polling update function, so the caller is responsible for this.
3703 */
3704static int ssl_sock_to_buf(struct connection *conn, struct buffer *buf, int count)
3705{
3706 int ret, done = 0;
Willy Tarreauabf08d92014-01-14 11:31:27 +01003707 int try;
Emeric Brun46591952012-05-18 15:47:34 +02003708
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02003709 if (!conn->xprt_ctx)
Emeric Brun46591952012-05-18 15:47:34 +02003710 goto out_error;
3711
3712 if (conn->flags & CO_FL_HANDSHAKE)
3713 /* a handshake was requested */
3714 return 0;
3715
Willy Tarreauabf08d92014-01-14 11:31:27 +01003716 /* let's realign the buffer to optimize I/O */
3717 if (buffer_empty(buf))
Emeric Brun46591952012-05-18 15:47:34 +02003718 buf->p = buf->data;
Emeric Brun46591952012-05-18 15:47:34 +02003719
3720 /* read the largest possible block. For this, we perform only one call
3721 * to recv() unless the buffer wraps and we exactly fill the first hunk,
3722 * in which case we accept to do it once again. A new attempt is made on
3723 * EINTR too.
3724 */
Willy Tarreau00b0fb92014-01-17 11:09:40 +01003725 while (count > 0) {
Willy Tarreauabf08d92014-01-14 11:31:27 +01003726 /* first check if we have some room after p+i */
3727 try = buf->data + buf->size - (buf->p + buf->i);
3728 /* otherwise continue between data and p-o */
3729 if (try <= 0) {
3730 try = buf->p - (buf->data + buf->o);
3731 if (try <= 0)
3732 break;
3733 }
3734 if (try > count)
3735 try = count;
3736
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02003737 ret = SSL_read(conn->xprt_ctx, bi_end(buf), try);
Emeric Brune1f38db2012-09-03 20:36:47 +02003738 if (conn->flags & CO_FL_ERROR) {
3739 /* CO_FL_ERROR may be set by ssl_sock_infocbk */
Emeric Brun644cde02012-12-14 11:21:13 +01003740 goto out_error;
Emeric Brune1f38db2012-09-03 20:36:47 +02003741 }
Emeric Brun46591952012-05-18 15:47:34 +02003742 if (ret > 0) {
3743 buf->i += ret;
3744 done += ret;
3745 if (ret < try)
3746 break;
3747 count -= ret;
Emeric Brun46591952012-05-18 15:47:34 +02003748 }
3749 else if (ret == 0) {
Emeric Brun644cde02012-12-14 11:21:13 +01003750 ret = SSL_get_error(conn->xprt_ctx, ret);
3751 if (ret != SSL_ERROR_ZERO_RETURN) {
Emeric Brun1c646862012-12-14 12:33:41 +01003752 /* error on protocol or underlying transport */
3753 if ((ret != SSL_ERROR_SYSCALL)
3754 || (errno && (errno != EAGAIN)))
3755 conn->flags |= CO_FL_ERROR;
3756
Emeric Brun644cde02012-12-14 11:21:13 +01003757 /* Clear openssl global errors stack */
Thierry FOURNIER / OZON.IO8b068c22016-10-10 11:59:50 +02003758 ssl_sock_dump_errors(conn);
Emeric Brun644cde02012-12-14 11:21:13 +01003759 ERR_clear_error();
3760 }
Emeric Brun46591952012-05-18 15:47:34 +02003761 goto read0;
3762 }
3763 else {
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02003764 ret = SSL_get_error(conn->xprt_ctx, ret);
Emeric Brun46591952012-05-18 15:47:34 +02003765 if (ret == SSL_ERROR_WANT_WRITE) {
Emeric Brun8af8dd12012-11-08 17:56:20 +01003766 /* handshake is running, and it needs to enable write */
Emeric Brun46591952012-05-18 15:47:34 +02003767 conn->flags |= CO_FL_SSL_WAIT_HS;
Emeric Brun8af8dd12012-11-08 17:56:20 +01003768 __conn_sock_want_send(conn);
Emeric Brun46591952012-05-18 15:47:34 +02003769 break;
3770 }
3771 else if (ret == SSL_ERROR_WANT_READ) {
Emeric Brun282a76a2012-11-08 18:02:56 +01003772 if (SSL_renegotiate_pending(conn->xprt_ctx)) {
3773 /* handshake is running, and it may need to re-enable read */
3774 conn->flags |= CO_FL_SSL_WAIT_HS;
3775 __conn_sock_want_recv(conn);
3776 break;
3777 }
Emeric Brun46591952012-05-18 15:47:34 +02003778 /* we need to poll for retry a read later */
Willy Tarreaue1f50c42014-01-22 20:02:06 +01003779 fd_cant_recv(conn->t.sock.fd);
Emeric Brun46591952012-05-18 15:47:34 +02003780 break;
3781 }
3782 /* otherwise it's a real error */
3783 goto out_error;
3784 }
3785 }
3786 return done;
3787
3788 read0:
3789 conn_sock_read0(conn);
3790 return done;
3791 out_error:
Emeric Brun644cde02012-12-14 11:21:13 +01003792 /* Clear openssl global errors stack */
Thierry FOURNIER / OZON.IO8b068c22016-10-10 11:59:50 +02003793 ssl_sock_dump_errors(conn);
Emeric Brun644cde02012-12-14 11:21:13 +01003794 ERR_clear_error();
3795
Emeric Brun46591952012-05-18 15:47:34 +02003796 conn->flags |= CO_FL_ERROR;
3797 return done;
3798}
3799
3800
3801/* Send all pending bytes from buffer <buf> to connection <conn>'s socket.
Willy Tarreau1049b1f2014-02-02 01:51:17 +01003802 * <flags> may contain some CO_SFL_* flags to hint the system about other
3803 * pending data for example, but this flag is ignored at the moment.
Emeric Brun46591952012-05-18 15:47:34 +02003804 * Only one call to send() is performed, unless the buffer wraps, in which case
3805 * a second call may be performed. The connection's flags are updated with
3806 * whatever special event is detected (error, empty). The caller is responsible
3807 * for taking care of those events and avoiding the call if inappropriate. The
3808 * function does not call the connection's polling update function, so the caller
3809 * is responsible for this.
3810 */
3811static int ssl_sock_from_buf(struct connection *conn, struct buffer *buf, int flags)
3812{
3813 int ret, try, done;
3814
3815 done = 0;
3816
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02003817 if (!conn->xprt_ctx)
Emeric Brun46591952012-05-18 15:47:34 +02003818 goto out_error;
3819
3820 if (conn->flags & CO_FL_HANDSHAKE)
3821 /* a handshake was requested */
3822 return 0;
3823
3824 /* send the largest possible block. For this we perform only one call
3825 * to send() unless the buffer wraps and we exactly fill the first hunk,
3826 * in which case we accept to do it once again.
3827 */
3828 while (buf->o) {
Kevin Hestercad82342013-05-30 15:12:41 -07003829 try = bo_contig_data(buf);
Willy Tarreaubfd59462013-02-21 07:46:09 +01003830
Willy Tarreau7bed9452014-02-02 02:00:24 +01003831 if (!(flags & CO_SFL_STREAMER) &&
Willy Tarreau518cedd2014-02-17 15:43:01 +01003832 !(conn->xprt_st & SSL_SOCK_SEND_UNLIMITED) &&
3833 global.tune.ssl_max_record && try > global.tune.ssl_max_record) {
Willy Tarreaubfd59462013-02-21 07:46:09 +01003834 try = global.tune.ssl_max_record;
Willy Tarreau518cedd2014-02-17 15:43:01 +01003835 }
3836 else {
3837 /* we need to keep the information about the fact that
3838 * we're not limiting the upcoming send(), because if it
3839 * fails, we'll have to retry with at least as many data.
3840 */
3841 conn->xprt_st |= SSL_SOCK_SEND_UNLIMITED;
3842 }
Willy Tarreaubfd59462013-02-21 07:46:09 +01003843
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02003844 ret = SSL_write(conn->xprt_ctx, bo_ptr(buf), try);
Willy Tarreau518cedd2014-02-17 15:43:01 +01003845
Emeric Brune1f38db2012-09-03 20:36:47 +02003846 if (conn->flags & CO_FL_ERROR) {
3847 /* CO_FL_ERROR may be set by ssl_sock_infocbk */
Emeric Brun644cde02012-12-14 11:21:13 +01003848 goto out_error;
Emeric Brune1f38db2012-09-03 20:36:47 +02003849 }
Emeric Brun46591952012-05-18 15:47:34 +02003850 if (ret > 0) {
Willy Tarreau518cedd2014-02-17 15:43:01 +01003851 conn->xprt_st &= ~SSL_SOCK_SEND_UNLIMITED;
3852
Emeric Brun46591952012-05-18 15:47:34 +02003853 buf->o -= ret;
3854 done += ret;
3855
Willy Tarreau5fb38032012-12-16 19:39:09 +01003856 if (likely(buffer_empty(buf)))
Emeric Brun46591952012-05-18 15:47:34 +02003857 /* optimize data alignment in the buffer */
3858 buf->p = buf->data;
3859
3860 /* if the system buffer is full, don't insist */
3861 if (ret < try)
3862 break;
3863 }
3864 else {
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02003865 ret = SSL_get_error(conn->xprt_ctx, ret);
Emeric Brun46591952012-05-18 15:47:34 +02003866 if (ret == SSL_ERROR_WANT_WRITE) {
Emeric Brun282a76a2012-11-08 18:02:56 +01003867 if (SSL_renegotiate_pending(conn->xprt_ctx)) {
3868 /* handshake is running, and it may need to re-enable write */
3869 conn->flags |= CO_FL_SSL_WAIT_HS;
3870 __conn_sock_want_send(conn);
3871 break;
3872 }
Emeric Brun46591952012-05-18 15:47:34 +02003873 /* we need to poll to retry a write later */
Willy Tarreaue1f50c42014-01-22 20:02:06 +01003874 fd_cant_send(conn->t.sock.fd);
Emeric Brun46591952012-05-18 15:47:34 +02003875 break;
3876 }
3877 else if (ret == SSL_ERROR_WANT_READ) {
Emeric Brun8af8dd12012-11-08 17:56:20 +01003878 /* handshake is running, and it needs to enable read */
Emeric Brun46591952012-05-18 15:47:34 +02003879 conn->flags |= CO_FL_SSL_WAIT_HS;
Emeric Brun8af8dd12012-11-08 17:56:20 +01003880 __conn_sock_want_recv(conn);
Emeric Brun46591952012-05-18 15:47:34 +02003881 break;
3882 }
3883 goto out_error;
3884 }
3885 }
3886 return done;
3887
3888 out_error:
Emeric Brun644cde02012-12-14 11:21:13 +01003889 /* Clear openssl global errors stack */
Thierry FOURNIER / OZON.IO8b068c22016-10-10 11:59:50 +02003890 ssl_sock_dump_errors(conn);
Emeric Brun644cde02012-12-14 11:21:13 +01003891 ERR_clear_error();
3892
Emeric Brun46591952012-05-18 15:47:34 +02003893 conn->flags |= CO_FL_ERROR;
3894 return done;
3895}
3896
Emeric Brun46591952012-05-18 15:47:34 +02003897static void ssl_sock_close(struct connection *conn) {
3898
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02003899 if (conn->xprt_ctx) {
3900 SSL_free(conn->xprt_ctx);
3901 conn->xprt_ctx = NULL;
Willy Tarreau403edff2012-09-06 11:58:37 +02003902 sslconns--;
Emeric Brun46591952012-05-18 15:47:34 +02003903 }
Emeric Brun46591952012-05-18 15:47:34 +02003904}
3905
3906/* This function tries to perform a clean shutdown on an SSL connection, and in
3907 * any case, flags the connection as reusable if no handshake was in progress.
3908 */
3909static void ssl_sock_shutw(struct connection *conn, int clean)
3910{
3911 if (conn->flags & CO_FL_HANDSHAKE)
3912 return;
3913 /* no handshake was in progress, try a clean ssl shutdown */
Emeric Brun644cde02012-12-14 11:21:13 +01003914 if (clean && (SSL_shutdown(conn->xprt_ctx) <= 0)) {
3915 /* Clear openssl global errors stack */
Thierry FOURNIER / OZON.IO8b068c22016-10-10 11:59:50 +02003916 ssl_sock_dump_errors(conn);
Emeric Brun644cde02012-12-14 11:21:13 +01003917 ERR_clear_error();
3918 }
Emeric Brun46591952012-05-18 15:47:34 +02003919
3920 /* force flag on ssl to keep session in cache regardless shutdown result */
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02003921 SSL_set_shutdown(conn->xprt_ctx, SSL_SENT_SHUTDOWN);
Emeric Brun46591952012-05-18 15:47:34 +02003922}
3923
Willy Tarreauffc3fcd2012-10-12 20:17:54 +02003924/* used for logging, may be changed for a sample fetch later */
3925const char *ssl_sock_get_cipher_name(struct connection *conn)
3926{
3927 if (!conn->xprt && !conn->xprt_ctx)
3928 return NULL;
3929 return SSL_get_cipher_name(conn->xprt_ctx);
3930}
3931
3932/* used for logging, may be changed for a sample fetch later */
3933const char *ssl_sock_get_proto_version(struct connection *conn)
3934{
3935 if (!conn->xprt && !conn->xprt_ctx)
3936 return NULL;
3937 return SSL_get_version(conn->xprt_ctx);
3938}
3939
Willy Tarreau8d598402012-10-22 17:58:39 +02003940/* Extract a serial from a cert, and copy it to a chunk.
3941 * Returns 1 if serial is found and copied, 0 if no serial found and
3942 * -1 if output is not large enough.
3943 */
3944static int
3945ssl_sock_get_serial(X509 *crt, struct chunk *out)
3946{
3947 ASN1_INTEGER *serial;
3948
3949 serial = X509_get_serialNumber(crt);
3950 if (!serial)
3951 return 0;
3952
3953 if (out->size < serial->length)
3954 return -1;
3955
3956 memcpy(out->str, serial->data, serial->length);
3957 out->len = serial->length;
3958 return 1;
3959}
3960
Emeric Brun43e79582014-10-29 19:03:26 +01003961/* Extract a cert to der, and copy it to a chunk.
3962 * Returns 1 if cert is found and copied, 0 on der convertion failure and
3963 * -1 if output is not large enough.
3964 */
3965static int
3966ssl_sock_crt2der(X509 *crt, struct chunk *out)
3967{
3968 int len;
3969 unsigned char *p = (unsigned char *)out->str;;
3970
3971 len =i2d_X509(crt, NULL);
3972 if (len <= 0)
3973 return 1;
3974
3975 if (out->size < len)
3976 return -1;
3977
3978 i2d_X509(crt,&p);
3979 out->len = len;
3980 return 1;
3981}
3982
Emeric Brunce5ad802012-10-22 14:11:22 +02003983
3984/* Copy Date in ASN1_UTCTIME format in struct chunk out.
3985 * Returns 1 if serial is found and copied, 0 if no valid time found
3986 * and -1 if output is not large enough.
3987 */
3988static int
3989ssl_sock_get_time(ASN1_TIME *tm, struct chunk *out)
3990{
3991 if (tm->type == V_ASN1_GENERALIZEDTIME) {
3992 ASN1_GENERALIZEDTIME *gentm = (ASN1_GENERALIZEDTIME *)tm;
3993
3994 if (gentm->length < 12)
3995 return 0;
3996 if (gentm->data[0] != 0x32 || gentm->data[1] != 0x30)
3997 return 0;
3998 if (out->size < gentm->length-2)
3999 return -1;
4000
4001 memcpy(out->str, gentm->data+2, gentm->length-2);
4002 out->len = gentm->length-2;
4003 return 1;
4004 }
4005 else if (tm->type == V_ASN1_UTCTIME) {
4006 ASN1_UTCTIME *utctm = (ASN1_UTCTIME *)tm;
4007
4008 if (utctm->length < 10)
4009 return 0;
4010 if (utctm->data[0] >= 0x35)
4011 return 0;
4012 if (out->size < utctm->length)
4013 return -1;
4014
4015 memcpy(out->str, utctm->data, utctm->length);
4016 out->len = utctm->length;
4017 return 1;
4018 }
4019
4020 return 0;
4021}
4022
Emeric Brun87855892012-10-17 17:39:35 +02004023/* Extract an entry from a X509_NAME and copy its value to an output chunk.
4024 * Returns 1 if entry found, 0 if entry not found, or -1 if output not large enough.
4025 */
4026static int
4027ssl_sock_get_dn_entry(X509_NAME *a, const struct chunk *entry, int pos, struct chunk *out)
4028{
4029 X509_NAME_ENTRY *ne;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004030 ASN1_OBJECT *obj;
4031 ASN1_STRING *data;
4032 const unsigned char *data_ptr;
4033 int data_len;
Emeric Brun87855892012-10-17 17:39:35 +02004034 int i, j, n;
4035 int cur = 0;
4036 const char *s;
4037 char tmp[128];
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004038 int name_count;
4039
4040 name_count = X509_NAME_entry_count(a);
Emeric Brun87855892012-10-17 17:39:35 +02004041
4042 out->len = 0;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004043 for (i = 0; i < name_count; i++) {
Emeric Brun87855892012-10-17 17:39:35 +02004044 if (pos < 0)
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004045 j = (name_count-1) - i;
Emeric Brun87855892012-10-17 17:39:35 +02004046 else
4047 j = i;
4048
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004049 ne = X509_NAME_get_entry(a, j);
4050 obj = X509_NAME_ENTRY_get_object(ne);
4051 data = X509_NAME_ENTRY_get_data(ne);
4052 data_ptr = ASN1_STRING_get0_data(data);
4053 data_len = ASN1_STRING_length(data);
4054 n = OBJ_obj2nid(obj);
Emeric Brun87855892012-10-17 17:39:35 +02004055 if ((n == NID_undef) || ((s = OBJ_nid2sn(n)) == NULL)) {
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004056 i2t_ASN1_OBJECT(tmp, sizeof(tmp), obj);
Emeric Brun87855892012-10-17 17:39:35 +02004057 s = tmp;
4058 }
4059
4060 if (chunk_strcasecmp(entry, s) != 0)
4061 continue;
4062
4063 if (pos < 0)
4064 cur--;
4065 else
4066 cur++;
4067
4068 if (cur != pos)
4069 continue;
4070
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004071 if (data_len > out->size)
Emeric Brun87855892012-10-17 17:39:35 +02004072 return -1;
4073
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004074 memcpy(out->str, data_ptr, data_len);
4075 out->len = data_len;
Emeric Brun87855892012-10-17 17:39:35 +02004076 return 1;
4077 }
4078
4079 return 0;
4080
4081}
4082
4083/* Extract and format full DN from a X509_NAME and copy result into a chunk
4084 * Returns 1 if dn entries exits, 0 if no dn entry found or -1 if output is not large enough.
4085 */
4086static int
4087ssl_sock_get_dn_oneline(X509_NAME *a, struct chunk *out)
4088{
4089 X509_NAME_ENTRY *ne;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004090 ASN1_OBJECT *obj;
4091 ASN1_STRING *data;
4092 const unsigned char *data_ptr;
4093 int data_len;
Emeric Brun87855892012-10-17 17:39:35 +02004094 int i, n, ln;
4095 int l = 0;
4096 const char *s;
4097 char *p;
4098 char tmp[128];
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004099 int name_count;
4100
4101
4102 name_count = X509_NAME_entry_count(a);
Emeric Brun87855892012-10-17 17:39:35 +02004103
4104 out->len = 0;
4105 p = out->str;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004106 for (i = 0; i < name_count; i++) {
4107 ne = X509_NAME_get_entry(a, i);
4108 obj = X509_NAME_ENTRY_get_object(ne);
4109 data = X509_NAME_ENTRY_get_data(ne);
4110 data_ptr = ASN1_STRING_get0_data(data);
4111 data_len = ASN1_STRING_length(data);
4112 n = OBJ_obj2nid(obj);
Emeric Brun87855892012-10-17 17:39:35 +02004113 if ((n == NID_undef) || ((s = OBJ_nid2sn(n)) == NULL)) {
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004114 i2t_ASN1_OBJECT(tmp, sizeof(tmp), obj);
Emeric Brun87855892012-10-17 17:39:35 +02004115 s = tmp;
4116 }
4117 ln = strlen(s);
4118
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004119 l += 1 + ln + 1 + data_len;
Emeric Brun87855892012-10-17 17:39:35 +02004120 if (l > out->size)
4121 return -1;
4122 out->len = l;
4123
4124 *(p++)='/';
4125 memcpy(p, s, ln);
4126 p += ln;
4127 *(p++)='=';
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004128 memcpy(p, data_ptr, data_len);
4129 p += data_len;
Emeric Brun87855892012-10-17 17:39:35 +02004130 }
4131
4132 if (!out->len)
4133 return 0;
4134
4135 return 1;
4136}
4137
David Safb76832014-05-08 23:42:08 -04004138char *ssl_sock_get_version(struct connection *conn)
4139{
4140 if (!ssl_sock_is_ssl(conn))
4141 return NULL;
4142
4143 return (char *)SSL_get_version(conn->xprt_ctx);
4144}
4145
Willy Tarreau63076412015-07-10 11:33:32 +02004146void ssl_sock_set_servername(struct connection *conn, const char *hostname)
4147{
4148#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
4149 if (!ssl_sock_is_ssl(conn))
4150 return;
4151
4152 SSL_set_tlsext_host_name(conn->xprt_ctx, hostname);
4153#endif
4154}
4155
Emeric Brun0abf8362014-06-24 18:26:41 +02004156/* Extract peer certificate's common name into the chunk dest
4157 * Returns
4158 * the len of the extracted common name
4159 * or 0 if no CN found in DN
4160 * or -1 on error case (i.e. no peer certificate)
4161 */
4162int ssl_sock_get_remote_common_name(struct connection *conn, struct chunk *dest)
David Safb76832014-05-08 23:42:08 -04004163{
4164 X509 *crt = NULL;
4165 X509_NAME *name;
David Safb76832014-05-08 23:42:08 -04004166 const char find_cn[] = "CN";
4167 const struct chunk find_cn_chunk = {
4168 .str = (char *)&find_cn,
4169 .len = sizeof(find_cn)-1
4170 };
Emeric Brun0abf8362014-06-24 18:26:41 +02004171 int result = -1;
David Safb76832014-05-08 23:42:08 -04004172
4173 if (!ssl_sock_is_ssl(conn))
Emeric Brun0abf8362014-06-24 18:26:41 +02004174 goto out;
David Safb76832014-05-08 23:42:08 -04004175
4176 /* SSL_get_peer_certificate, it increase X509 * ref count */
4177 crt = SSL_get_peer_certificate(conn->xprt_ctx);
4178 if (!crt)
4179 goto out;
4180
4181 name = X509_get_subject_name(crt);
4182 if (!name)
4183 goto out;
David Safb76832014-05-08 23:42:08 -04004184
Emeric Brun0abf8362014-06-24 18:26:41 +02004185 result = ssl_sock_get_dn_entry(name, &find_cn_chunk, 1, dest);
4186out:
David Safb76832014-05-08 23:42:08 -04004187 if (crt)
4188 X509_free(crt);
4189
4190 return result;
4191}
4192
Dave McCowan328fb582014-07-30 10:39:13 -04004193/* returns 1 if client passed a certificate for this session, 0 if not */
4194int ssl_sock_get_cert_used_sess(struct connection *conn)
4195{
4196 X509 *crt = NULL;
4197
4198 if (!ssl_sock_is_ssl(conn))
4199 return 0;
4200
4201 /* SSL_get_peer_certificate, it increase X509 * ref count */
4202 crt = SSL_get_peer_certificate(conn->xprt_ctx);
4203 if (!crt)
4204 return 0;
4205
4206 X509_free(crt);
4207 return 1;
4208}
4209
4210/* returns 1 if client passed a certificate for this connection, 0 if not */
4211int ssl_sock_get_cert_used_conn(struct connection *conn)
David Safb76832014-05-08 23:42:08 -04004212{
4213 if (!ssl_sock_is_ssl(conn))
4214 return 0;
4215
4216 return SSL_SOCK_ST_FL_VERIFY_DONE & conn->xprt_st ? 1 : 0;
4217}
4218
4219/* returns result from SSL verify */
4220unsigned int ssl_sock_get_verify_result(struct connection *conn)
4221{
4222 if (!ssl_sock_is_ssl(conn))
4223 return (unsigned int)X509_V_ERR_APPLICATION_VERIFICATION;
4224
4225 return (unsigned int)SSL_get_verify_result(conn->xprt_ctx);
4226}
4227
Willy Tarreau7875d092012-09-10 08:20:03 +02004228/***** Below are some sample fetching functions for ACL/patterns *****/
4229
Emeric Brune64aef12012-09-21 13:15:06 +02004230/* boolean, returns true if client cert was present */
4231static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004232smp_fetch_ssl_fc_has_crt(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brune64aef12012-09-21 13:15:06 +02004233{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004234 struct connection *conn;
4235
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004236 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004237 if (!conn || conn->xprt != &ssl_sock)
Emeric Brune64aef12012-09-21 13:15:06 +02004238 return 0;
4239
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004240 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brune64aef12012-09-21 13:15:06 +02004241 smp->flags |= SMP_F_MAY_CHANGE;
4242 return 0;
4243 }
4244
4245 smp->flags = 0;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004246 smp->data.type = SMP_T_BOOL;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004247 smp->data.u.sint = SSL_SOCK_ST_FL_VERIFY_DONE & conn->xprt_st ? 1 : 0;
Emeric Brune64aef12012-09-21 13:15:06 +02004248
4249 return 1;
4250}
4251
Emeric Brun43e79582014-10-29 19:03:26 +01004252/* binary, returns a certificate in a binary chunk (der/raw).
4253 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
4254 * should be use.
4255 */
4256static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004257smp_fetch_ssl_x_der(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun43e79582014-10-29 19:03:26 +01004258{
4259 int cert_peer = (kw[4] == 'c') ? 1 : 0;
4260 X509 *crt = NULL;
4261 int ret = 0;
4262 struct chunk *smp_trash;
4263 struct connection *conn;
4264
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004265 conn = objt_conn(smp->sess->origin);
Emeric Brun43e79582014-10-29 19:03:26 +01004266 if (!conn || conn->xprt != &ssl_sock)
4267 return 0;
4268
4269 if (!(conn->flags & CO_FL_CONNECTED)) {
4270 smp->flags |= SMP_F_MAY_CHANGE;
4271 return 0;
4272 }
4273
4274 if (cert_peer)
4275 crt = SSL_get_peer_certificate(conn->xprt_ctx);
4276 else
4277 crt = SSL_get_certificate(conn->xprt_ctx);
4278
4279 if (!crt)
4280 goto out;
4281
4282 smp_trash = get_trash_chunk();
4283 if (ssl_sock_crt2der(crt, smp_trash) <= 0)
4284 goto out;
4285
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004286 smp->data.u.str = *smp_trash;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004287 smp->data.type = SMP_T_BIN;
Emeric Brun43e79582014-10-29 19:03:26 +01004288 ret = 1;
4289out:
4290 /* SSL_get_peer_certificate, it increase X509 * ref count */
4291 if (cert_peer && crt)
4292 X509_free(crt);
4293 return ret;
4294}
4295
Emeric Brunba841a12014-04-30 17:05:08 +02004296/* binary, returns serial of certificate in a binary chunk.
4297 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
4298 * should be use.
4299 */
Willy Tarreau8d598402012-10-22 17:58:39 +02004300static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004301smp_fetch_ssl_x_serial(const struct arg *args, struct sample *smp, const char *kw, void *private)
Willy Tarreau8d598402012-10-22 17:58:39 +02004302{
Emeric Brunba841a12014-04-30 17:05:08 +02004303 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Willy Tarreau8d598402012-10-22 17:58:39 +02004304 X509 *crt = NULL;
4305 int ret = 0;
4306 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004307 struct connection *conn;
4308
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004309 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004310 if (!conn || conn->xprt != &ssl_sock)
Willy Tarreau8d598402012-10-22 17:58:39 +02004311 return 0;
4312
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004313 if (!(conn->flags & CO_FL_CONNECTED)) {
Willy Tarreau8d598402012-10-22 17:58:39 +02004314 smp->flags |= SMP_F_MAY_CHANGE;
4315 return 0;
4316 }
4317
Emeric Brunba841a12014-04-30 17:05:08 +02004318 if (cert_peer)
4319 crt = SSL_get_peer_certificate(conn->xprt_ctx);
4320 else
4321 crt = SSL_get_certificate(conn->xprt_ctx);
4322
Willy Tarreau8d598402012-10-22 17:58:39 +02004323 if (!crt)
4324 goto out;
4325
Willy Tarreau47ca5452012-12-23 20:22:19 +01004326 smp_trash = get_trash_chunk();
Willy Tarreau8d598402012-10-22 17:58:39 +02004327 if (ssl_sock_get_serial(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;
Willy Tarreau8d598402012-10-22 17:58:39 +02004332 ret = 1;
4333out:
Emeric Brunba841a12014-04-30 17:05:08 +02004334 /* SSL_get_peer_certificate, it increase X509 * ref count */
4335 if (cert_peer && crt)
Willy Tarreau8d598402012-10-22 17:58:39 +02004336 X509_free(crt);
4337 return ret;
4338}
Emeric Brune64aef12012-09-21 13:15:06 +02004339
Emeric Brunba841a12014-04-30 17:05:08 +02004340/* binary, returns the client certificate's SHA-1 fingerprint (SHA-1 hash of DER-encoded 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 */
James Votha051b4a2013-05-14 20:37:59 +02004344static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004345smp_fetch_ssl_x_sha1(const struct arg *args, struct sample *smp, const char *kw, void *private)
James Votha051b4a2013-05-14 20:37:59 +02004346{
Emeric Brunba841a12014-04-30 17:05:08 +02004347 int cert_peer = (kw[4] == 'c') ? 1 : 0;
James Votha051b4a2013-05-14 20:37:59 +02004348 X509 *crt = NULL;
4349 const EVP_MD *digest;
4350 int ret = 0;
4351 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004352 struct connection *conn;
James Votha051b4a2013-05-14 20:37:59 +02004353
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004354 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004355 if (!conn || conn->xprt != &ssl_sock)
4356 return 0;
4357
4358 if (!(conn->flags & CO_FL_CONNECTED)) {
James Votha051b4a2013-05-14 20:37:59 +02004359 smp->flags |= SMP_F_MAY_CHANGE;
4360 return 0;
4361 }
4362
Emeric Brunba841a12014-04-30 17:05:08 +02004363 if (cert_peer)
4364 crt = SSL_get_peer_certificate(conn->xprt_ctx);
4365 else
4366 crt = SSL_get_certificate(conn->xprt_ctx);
James Votha051b4a2013-05-14 20:37:59 +02004367 if (!crt)
4368 goto out;
4369
4370 smp_trash = get_trash_chunk();
4371 digest = EVP_sha1();
4372 X509_digest(crt, digest, (unsigned char *)smp_trash->str, (unsigned int *)&smp_trash->len);
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;
James Votha051b4a2013-05-14 20:37:59 +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)
James Votha051b4a2013-05-14 20:37:59 +02004380 X509_free(crt);
4381 return ret;
4382}
4383
Emeric Brunba841a12014-04-30 17:05:08 +02004384/* string, returns certificate's notafter date in ASN1_UTCTIME format.
4385 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
4386 * should be use.
4387 */
Emeric Brunce5ad802012-10-22 14:11:22 +02004388static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004389smp_fetch_ssl_x_notafter(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brunce5ad802012-10-22 14:11:22 +02004390{
Emeric Brunba841a12014-04-30 17:05:08 +02004391 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brunce5ad802012-10-22 14:11:22 +02004392 X509 *crt = NULL;
4393 int ret = 0;
4394 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004395 struct connection *conn;
Emeric Brunce5ad802012-10-22 14:11:22 +02004396
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004397 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004398 if (!conn || conn->xprt != &ssl_sock)
4399 return 0;
4400
4401 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunce5ad802012-10-22 14:11:22 +02004402 smp->flags |= SMP_F_MAY_CHANGE;
4403 return 0;
4404 }
4405
Emeric Brunba841a12014-04-30 17:05:08 +02004406 if (cert_peer)
4407 crt = SSL_get_peer_certificate(conn->xprt_ctx);
4408 else
4409 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brunce5ad802012-10-22 14:11:22 +02004410 if (!crt)
4411 goto out;
4412
Willy Tarreau47ca5452012-12-23 20:22:19 +01004413 smp_trash = get_trash_chunk();
Emeric Brunce5ad802012-10-22 14:11:22 +02004414 if (ssl_sock_get_time(X509_get_notAfter(crt), smp_trash) <= 0)
4415 goto out;
4416
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004417 smp->data.u.str = *smp_trash;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004418 smp->data.type = SMP_T_STR;
Emeric Brunce5ad802012-10-22 14:11:22 +02004419 ret = 1;
4420out:
Emeric Brunba841a12014-04-30 17:05:08 +02004421 /* SSL_get_peer_certificate, it increase X509 * ref count */
4422 if (cert_peer && crt)
Emeric Brunce5ad802012-10-22 14:11:22 +02004423 X509_free(crt);
4424 return ret;
4425}
4426
Emeric Brunba841a12014-04-30 17:05:08 +02004427/* string, returns a string of a formatted full dn \C=..\O=..\OU=.. \CN=.. of certificate's issuer
4428 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
4429 * should be use.
4430 */
Emeric Brun87855892012-10-17 17:39:35 +02004431static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004432smp_fetch_ssl_x_i_dn(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun87855892012-10-17 17:39:35 +02004433{
Emeric Brunba841a12014-04-30 17:05:08 +02004434 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brun87855892012-10-17 17:39:35 +02004435 X509 *crt = NULL;
4436 X509_NAME *name;
4437 int ret = 0;
4438 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004439 struct connection *conn;
Emeric Brun87855892012-10-17 17:39:35 +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 Brun87855892012-10-17 17:39:35 +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 Brun87855892012-10-17 17:39:35 +02004454 if (!crt)
4455 goto out;
4456
4457 name = X509_get_issuer_name(crt);
4458 if (!name)
4459 goto out;
4460
Willy Tarreau47ca5452012-12-23 20:22:19 +01004461 smp_trash = get_trash_chunk();
Emeric Brun87855892012-10-17 17:39:35 +02004462 if (args && args[0].type == ARGT_STR) {
4463 int pos = 1;
4464
4465 if (args[1].type == ARGT_SINT)
4466 pos = args[1].data.sint;
Emeric Brun87855892012-10-17 17:39:35 +02004467
4468 if (ssl_sock_get_dn_entry(name, &args[0].data.str, pos, smp_trash) <= 0)
4469 goto out;
4470 }
4471 else if (ssl_sock_get_dn_oneline(name, smp_trash) <= 0)
4472 goto out;
4473
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004474 smp->data.type = SMP_T_STR;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004475 smp->data.u.str = *smp_trash;
Emeric Brun87855892012-10-17 17:39:35 +02004476 ret = 1;
4477out:
Emeric Brunba841a12014-04-30 17:05:08 +02004478 /* SSL_get_peer_certificate, it increase X509 * ref count */
4479 if (cert_peer && crt)
Emeric Brun87855892012-10-17 17:39:35 +02004480 X509_free(crt);
4481 return ret;
4482}
4483
Emeric Brunba841a12014-04-30 17:05:08 +02004484/* string, returns notbefore date in ASN1_UTCTIME format.
4485 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
4486 * should be use.
4487 */
Emeric Brunce5ad802012-10-22 14:11:22 +02004488static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004489smp_fetch_ssl_x_notbefore(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brunce5ad802012-10-22 14:11:22 +02004490{
Emeric Brunba841a12014-04-30 17:05:08 +02004491 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brunce5ad802012-10-22 14:11:22 +02004492 X509 *crt = NULL;
4493 int ret = 0;
4494 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004495 struct connection *conn;
4496
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004497 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004498 if (!conn || conn->xprt != &ssl_sock)
Emeric Brunce5ad802012-10-22 14:11:22 +02004499 return 0;
4500
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004501 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunce5ad802012-10-22 14:11:22 +02004502 smp->flags |= SMP_F_MAY_CHANGE;
4503 return 0;
4504 }
4505
Emeric Brunba841a12014-04-30 17:05:08 +02004506 if (cert_peer)
4507 crt = SSL_get_peer_certificate(conn->xprt_ctx);
4508 else
4509 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brunce5ad802012-10-22 14:11:22 +02004510 if (!crt)
4511 goto out;
4512
Willy Tarreau47ca5452012-12-23 20:22:19 +01004513 smp_trash = get_trash_chunk();
Emeric Brunce5ad802012-10-22 14:11:22 +02004514 if (ssl_sock_get_time(X509_get_notBefore(crt), smp_trash) <= 0)
4515 goto out;
4516
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004517 smp->data.u.str = *smp_trash;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004518 smp->data.type = SMP_T_STR;
Emeric Brunce5ad802012-10-22 14:11:22 +02004519 ret = 1;
4520out:
Emeric Brunba841a12014-04-30 17:05:08 +02004521 /* SSL_get_peer_certificate, it increase X509 * ref count */
4522 if (cert_peer && crt)
Emeric Brunce5ad802012-10-22 14:11:22 +02004523 X509_free(crt);
4524 return ret;
4525}
4526
Emeric Brunba841a12014-04-30 17:05:08 +02004527/* string, returns a string of a formatted full dn \C=..\O=..\OU=.. \CN=.. of certificate's subject
4528 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
4529 * should be use.
4530 */
Emeric Brun87855892012-10-17 17:39:35 +02004531static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004532smp_fetch_ssl_x_s_dn(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun87855892012-10-17 17:39:35 +02004533{
Emeric Brunba841a12014-04-30 17:05:08 +02004534 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brun87855892012-10-17 17:39:35 +02004535 X509 *crt = NULL;
4536 X509_NAME *name;
4537 int ret = 0;
4538 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004539 struct connection *conn;
Emeric Brun87855892012-10-17 17:39:35 +02004540
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)
4543 return 0;
4544
4545 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun87855892012-10-17 17:39:35 +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 Brun87855892012-10-17 17:39:35 +02004554 if (!crt)
4555 goto out;
4556
4557 name = X509_get_subject_name(crt);
4558 if (!name)
4559 goto out;
4560
Willy Tarreau47ca5452012-12-23 20:22:19 +01004561 smp_trash = get_trash_chunk();
Emeric Brun87855892012-10-17 17:39:35 +02004562 if (args && args[0].type == ARGT_STR) {
4563 int pos = 1;
4564
4565 if (args[1].type == ARGT_SINT)
4566 pos = args[1].data.sint;
Emeric Brun87855892012-10-17 17:39:35 +02004567
4568 if (ssl_sock_get_dn_entry(name, &args[0].data.str, pos, smp_trash) <= 0)
4569 goto out;
4570 }
4571 else if (ssl_sock_get_dn_oneline(name, smp_trash) <= 0)
4572 goto out;
4573
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004574 smp->data.type = SMP_T_STR;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004575 smp->data.u.str = *smp_trash;
Emeric Brun87855892012-10-17 17:39:35 +02004576 ret = 1;
4577out:
Emeric Brunba841a12014-04-30 17:05:08 +02004578 /* SSL_get_peer_certificate, it increase X509 * ref count */
4579 if (cert_peer && crt)
Emeric Brun87855892012-10-17 17:39:35 +02004580 X509_free(crt);
4581 return ret;
4582}
Emeric Brun9143d372012-12-20 15:44:16 +01004583
4584/* integer, returns true if current session use a client certificate */
4585static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004586smp_fetch_ssl_c_used(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun9143d372012-12-20 15:44:16 +01004587{
4588 X509 *crt;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004589 struct connection *conn;
Emeric Brun9143d372012-12-20 15:44:16 +01004590
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004591 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004592 if (!conn || conn->xprt != &ssl_sock)
4593 return 0;
4594
4595 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun9143d372012-12-20 15:44:16 +01004596 smp->flags |= SMP_F_MAY_CHANGE;
4597 return 0;
4598 }
4599
4600 /* SSL_get_peer_certificate returns a ptr on allocated X509 struct */
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004601 crt = SSL_get_peer_certificate(conn->xprt_ctx);
Emeric Brun9143d372012-12-20 15:44:16 +01004602 if (crt) {
4603 X509_free(crt);
4604 }
4605
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004606 smp->data.type = SMP_T_BOOL;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004607 smp->data.u.sint = (crt != NULL);
Emeric Brun9143d372012-12-20 15:44:16 +01004608 return 1;
4609}
4610
Emeric Brunba841a12014-04-30 17:05:08 +02004611/* integer, returns the certificate version
4612 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
4613 * should be use.
4614 */
Emeric Bruna7359fd2012-10-17 15:03:11 +02004615static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004616smp_fetch_ssl_x_version(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Bruna7359fd2012-10-17 15:03:11 +02004617{
Emeric Brunba841a12014-04-30 17:05:08 +02004618 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Bruna7359fd2012-10-17 15:03:11 +02004619 X509 *crt;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004620 struct connection *conn;
4621
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004622 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004623 if (!conn || conn->xprt != &ssl_sock)
Emeric Bruna7359fd2012-10-17 15:03:11 +02004624 return 0;
4625
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004626 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Bruna7359fd2012-10-17 15:03:11 +02004627 smp->flags |= SMP_F_MAY_CHANGE;
4628 return 0;
4629 }
4630
Emeric Brunba841a12014-04-30 17:05:08 +02004631 if (cert_peer)
4632 crt = SSL_get_peer_certificate(conn->xprt_ctx);
4633 else
4634 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Bruna7359fd2012-10-17 15:03:11 +02004635 if (!crt)
4636 return 0;
4637
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004638 smp->data.u.sint = (unsigned int)(1 + X509_get_version(crt));
Emeric Brunba841a12014-04-30 17:05:08 +02004639 /* SSL_get_peer_certificate increase X509 * ref count */
4640 if (cert_peer)
4641 X509_free(crt);
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004642 smp->data.type = SMP_T_SINT;
Emeric Bruna7359fd2012-10-17 15:03:11 +02004643
4644 return 1;
4645}
4646
Emeric Brunba841a12014-04-30 17:05:08 +02004647/* string, returns the certificate's signature algorithm.
4648 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
4649 * should be use.
4650 */
Emeric Brun7f56e742012-10-19 18:15:40 +02004651static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004652smp_fetch_ssl_x_sig_alg(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun7f56e742012-10-19 18:15:40 +02004653{
Emeric Brunba841a12014-04-30 17:05:08 +02004654 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brun7f56e742012-10-19 18:15:40 +02004655 X509 *crt;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004656 __OPENSSL_110_CONST__ ASN1_OBJECT *algorithm;
Emeric Brun7f56e742012-10-19 18:15:40 +02004657 int nid;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004658 struct connection *conn;
Emeric Brun7f56e742012-10-19 18:15:40 +02004659
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004660 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004661 if (!conn || conn->xprt != &ssl_sock)
4662 return 0;
4663
4664 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun7f56e742012-10-19 18:15:40 +02004665 smp->flags |= SMP_F_MAY_CHANGE;
4666 return 0;
4667 }
4668
Emeric Brunba841a12014-04-30 17:05:08 +02004669 if (cert_peer)
4670 crt = SSL_get_peer_certificate(conn->xprt_ctx);
4671 else
4672 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brun7f56e742012-10-19 18:15:40 +02004673 if (!crt)
4674 return 0;
4675
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004676 X509_ALGOR_get0(&algorithm, NULL, NULL, X509_get0_tbs_sigalg(crt));
4677 nid = OBJ_obj2nid(algorithm);
Emeric Brun7f56e742012-10-19 18:15:40 +02004678
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004679 smp->data.u.str.str = (char *)OBJ_nid2sn(nid);
4680 if (!smp->data.u.str.str) {
Emeric Brunba841a12014-04-30 17:05:08 +02004681 /* SSL_get_peer_certificate increase X509 * ref count */
4682 if (cert_peer)
4683 X509_free(crt);
Emeric Brun7f56e742012-10-19 18:15:40 +02004684 return 0;
Emeric Brun9bf3ba22013-10-07 14:31:44 +02004685 }
Emeric Brun7f56e742012-10-19 18:15:40 +02004686
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004687 smp->data.type = SMP_T_STR;
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01004688 smp->flags |= SMP_F_CONST;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004689 smp->data.u.str.len = strlen(smp->data.u.str.str);
Emeric Brunba841a12014-04-30 17:05:08 +02004690 /* SSL_get_peer_certificate increase X509 * ref count */
4691 if (cert_peer)
4692 X509_free(crt);
Emeric Brun7f56e742012-10-19 18:15:40 +02004693
4694 return 1;
4695}
4696
Emeric Brunba841a12014-04-30 17:05:08 +02004697/* string, returns the certificate's key algorithm.
4698 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
4699 * should be use.
4700 */
Emeric Brun521a0112012-10-22 12:22:55 +02004701static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004702smp_fetch_ssl_x_key_alg(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun521a0112012-10-22 12:22:55 +02004703{
Emeric Brunba841a12014-04-30 17:05:08 +02004704 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brun521a0112012-10-22 12:22:55 +02004705 X509 *crt;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004706 ASN1_OBJECT *algorithm;
Emeric Brun521a0112012-10-22 12:22:55 +02004707 int nid;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004708 struct connection *conn;
Emeric Brun521a0112012-10-22 12:22:55 +02004709
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004710 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004711 if (!conn || conn->xprt != &ssl_sock)
4712 return 0;
4713
4714 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun521a0112012-10-22 12:22:55 +02004715 smp->flags |= SMP_F_MAY_CHANGE;
4716 return 0;
4717 }
4718
Emeric Brunba841a12014-04-30 17:05:08 +02004719 if (cert_peer)
4720 crt = SSL_get_peer_certificate(conn->xprt_ctx);
4721 else
4722 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brun521a0112012-10-22 12:22:55 +02004723 if (!crt)
4724 return 0;
4725
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004726 X509_PUBKEY_get0_param(&algorithm, NULL, NULL, NULL, X509_get_X509_PUBKEY(crt));
4727 nid = OBJ_obj2nid(algorithm);
Emeric Brun521a0112012-10-22 12:22:55 +02004728
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004729 smp->data.u.str.str = (char *)OBJ_nid2sn(nid);
4730 if (!smp->data.u.str.str) {
Emeric Brunba841a12014-04-30 17:05:08 +02004731 /* SSL_get_peer_certificate increase X509 * ref count */
4732 if (cert_peer)
4733 X509_free(crt);
Emeric Brun521a0112012-10-22 12:22:55 +02004734 return 0;
Emeric Brun9bf3ba22013-10-07 14:31:44 +02004735 }
Emeric Brun521a0112012-10-22 12:22:55 +02004736
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004737 smp->data.type = SMP_T_STR;
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01004738 smp->flags |= SMP_F_CONST;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004739 smp->data.u.str.len = strlen(smp->data.u.str.str);
Emeric Brunba841a12014-04-30 17:05:08 +02004740 if (cert_peer)
4741 X509_free(crt);
Emeric Brun521a0112012-10-22 12:22:55 +02004742
4743 return 1;
4744}
4745
Emeric Brun645ae792014-04-30 14:21:06 +02004746/* boolean, returns true if front conn. transport layer is SSL.
4747 * This function is also usable on backend conn if the fetch keyword 5th
4748 * char is 'b'.
4749 */
Willy Tarreau7875d092012-09-10 08:20:03 +02004750static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004751smp_fetch_ssl_fc(const struct arg *args, struct sample *smp, const char *kw, void *private)
Willy Tarreau7875d092012-09-10 08:20:03 +02004752{
Willy Tarreaue237fe12016-03-10 17:05:28 +01004753 struct connection *conn = objt_conn((kw[4] != 'b') ? smp->sess->origin :
4754 smp->strm ? smp->strm->si[1].end : NULL);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004755
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004756 smp->data.type = SMP_T_BOOL;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004757 smp->data.u.sint = (conn && conn->xprt == &ssl_sock);
Willy Tarreau7875d092012-09-10 08:20:03 +02004758 return 1;
4759}
4760
Emeric Brun2525b6b2012-10-18 15:59:43 +02004761/* boolean, returns true if client present a SNI */
Willy Tarreau7875d092012-09-10 08:20:03 +02004762static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004763smp_fetch_ssl_fc_has_sni(const struct arg *args, struct sample *smp, const char *kw, void *private)
Willy Tarreau7875d092012-09-10 08:20:03 +02004764{
4765#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004766 struct connection *conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004767
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004768 smp->data.type = SMP_T_BOOL;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004769 smp->data.u.sint = (conn && conn->xprt == &ssl_sock) &&
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004770 conn->xprt_ctx &&
4771 SSL_get_servername(conn->xprt_ctx, TLSEXT_NAMETYPE_host_name) != NULL;
Willy Tarreau7875d092012-09-10 08:20:03 +02004772 return 1;
4773#else
4774 return 0;
4775#endif
4776}
4777
Nenad Merdanovic26ea8222015-05-18 02:28:57 +02004778/* boolean, returns true if client session has been resumed */
4779static int
4780smp_fetch_ssl_fc_is_resumed(const struct arg *args, struct sample *smp, const char *kw, void *private)
4781{
4782 struct connection *conn = objt_conn(smp->sess->origin);
4783
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004784 smp->data.type = SMP_T_BOOL;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004785 smp->data.u.sint = (conn && conn->xprt == &ssl_sock) &&
Nenad Merdanovic26ea8222015-05-18 02:28:57 +02004786 conn->xprt_ctx &&
4787 SSL_session_reused(conn->xprt_ctx);
4788 return 1;
4789}
4790
Emeric Brun645ae792014-04-30 14:21:06 +02004791/* string, returns the used cipher if front conn. transport layer is SSL.
4792 * This function is also usable on backend conn if the fetch keyword 5th
4793 * char is 'b'.
4794 */
Emeric Brun589fcad2012-10-16 14:13:26 +02004795static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004796smp_fetch_ssl_fc_cipher(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun589fcad2012-10-16 14:13:26 +02004797{
Willy Tarreaue237fe12016-03-10 17:05:28 +01004798 struct connection *conn = objt_conn((kw[4] != 'b') ? smp->sess->origin :
4799 smp->strm ? smp->strm->si[1].end : NULL);
Emeric Brun589fcad2012-10-16 14:13:26 +02004800
Willy Tarreaube508f12016-03-10 11:47:01 +01004801 smp->flags = 0;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004802 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
Emeric Brun589fcad2012-10-16 14:13:26 +02004803 return 0;
4804
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004805 smp->data.u.str.str = (char *)SSL_get_cipher_name(conn->xprt_ctx);
4806 if (!smp->data.u.str.str)
Emeric Brun589fcad2012-10-16 14:13:26 +02004807 return 0;
4808
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004809 smp->data.type = SMP_T_STR;
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01004810 smp->flags |= SMP_F_CONST;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004811 smp->data.u.str.len = strlen(smp->data.u.str.str);
Emeric Brun589fcad2012-10-16 14:13:26 +02004812
4813 return 1;
4814}
4815
Emeric Brun645ae792014-04-30 14:21:06 +02004816/* integer, returns the algoritm's keysize if front conn. transport layer
4817 * is SSL.
4818 * This function is also usable on backend conn if the fetch keyword 5th
4819 * char is 'b'.
4820 */
Emeric Brun589fcad2012-10-16 14:13:26 +02004821static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004822smp_fetch_ssl_fc_alg_keysize(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun589fcad2012-10-16 14:13:26 +02004823{
Willy Tarreaue237fe12016-03-10 17:05:28 +01004824 struct connection *conn = objt_conn((kw[4] != 'b') ? smp->sess->origin :
4825 smp->strm ? smp->strm->si[1].end : NULL);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004826
Willy Tarreaue237fe12016-03-10 17:05:28 +01004827 int sint;
Willy Tarreaube508f12016-03-10 11:47:01 +01004828
Emeric Brun589fcad2012-10-16 14:13:26 +02004829 smp->flags = 0;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004830 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
Emeric Brun589fcad2012-10-16 14:13:26 +02004831 return 0;
4832
Thierry FOURNIER07ee64e2015-07-06 23:43:03 +02004833 if (!SSL_get_cipher_bits(conn->xprt_ctx, &sint))
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004834 return 0;
4835
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004836 smp->data.u.sint = sint;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004837 smp->data.type = SMP_T_SINT;
Emeric Brun589fcad2012-10-16 14:13:26 +02004838
4839 return 1;
4840}
4841
Emeric Brun645ae792014-04-30 14:21:06 +02004842/* integer, returns the used keysize if front conn. transport layer is SSL.
4843 * This function is also usable on backend conn if the fetch keyword 5th
4844 * char is 'b'.
4845 */
Emeric Brun589fcad2012-10-16 14:13:26 +02004846static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004847smp_fetch_ssl_fc_use_keysize(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun589fcad2012-10-16 14:13:26 +02004848{
Willy Tarreaue237fe12016-03-10 17:05:28 +01004849 struct connection *conn = objt_conn((kw[4] != 'b') ? smp->sess->origin :
4850 smp->strm ? smp->strm->si[1].end : NULL);
Willy Tarreaube508f12016-03-10 11:47:01 +01004851
Emeric Brun589fcad2012-10-16 14:13:26 +02004852 smp->flags = 0;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004853 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
4854 return 0;
4855
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004856 smp->data.u.sint = (unsigned int)SSL_get_cipher_bits(conn->xprt_ctx, NULL);
4857 if (!smp->data.u.sint)
Emeric Brun589fcad2012-10-16 14:13:26 +02004858 return 0;
4859
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004860 smp->data.type = SMP_T_SINT;
Emeric Brun589fcad2012-10-16 14:13:26 +02004861
4862 return 1;
4863}
4864
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02004865#ifdef OPENSSL_NPN_NEGOTIATED
Willy Tarreau7875d092012-09-10 08:20:03 +02004866static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004867smp_fetch_ssl_fc_npn(const struct arg *args, struct sample *smp, const char *kw, void *private)
Willy Tarreaua33c6542012-10-15 13:19:06 +02004868{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004869 struct connection *conn;
4870
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01004871 smp->flags = SMP_F_CONST;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004872 smp->data.type = SMP_T_STR;
Willy Tarreaua33c6542012-10-15 13:19:06 +02004873
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004874 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004875 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
4876 return 0;
4877
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004878 smp->data.u.str.str = NULL;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004879 SSL_get0_next_proto_negotiated(conn->xprt_ctx,
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004880 (const unsigned char **)&smp->data.u.str.str, (unsigned *)&smp->data.u.str.len);
Willy Tarreaua33c6542012-10-15 13:19:06 +02004881
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004882 if (!smp->data.u.str.str)
Willy Tarreaua33c6542012-10-15 13:19:06 +02004883 return 0;
4884
4885 return 1;
Willy Tarreaua33c6542012-10-15 13:19:06 +02004886}
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02004887#endif
Willy Tarreaua33c6542012-10-15 13:19:06 +02004888
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01004889#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Willy Tarreauab861d32013-04-02 02:30:41 +02004890static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004891smp_fetch_ssl_fc_alpn(const struct arg *args, struct sample *smp, const char *kw, void *private)
Willy Tarreauab861d32013-04-02 02:30:41 +02004892{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004893 struct connection *conn;
4894
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01004895 smp->flags = SMP_F_CONST;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004896 smp->data.type = SMP_T_STR;
Willy Tarreauab861d32013-04-02 02:30:41 +02004897
Willy Tarreaue26bf052015-05-12 10:30:12 +02004898 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004899 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
Willy Tarreauab861d32013-04-02 02:30:41 +02004900 return 0;
4901
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004902 smp->data.u.str.str = NULL;
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01004903 SSL_get0_alpn_selected(conn->xprt_ctx,
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004904 (const unsigned char **)&smp->data.u.str.str, (unsigned *)&smp->data.u.str.len);
Willy Tarreauab861d32013-04-02 02:30:41 +02004905
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004906 if (!smp->data.u.str.str)
Willy Tarreauab861d32013-04-02 02:30:41 +02004907 return 0;
4908
4909 return 1;
4910}
4911#endif
4912
Emeric Brun645ae792014-04-30 14:21:06 +02004913/* string, returns the used protocol if front conn. transport layer is SSL.
4914 * This function is also usable on backend conn if the fetch keyword 5th
4915 * char is 'b'.
4916 */
Willy Tarreaua33c6542012-10-15 13:19:06 +02004917static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004918smp_fetch_ssl_fc_protocol(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun589fcad2012-10-16 14:13:26 +02004919{
Willy Tarreaue237fe12016-03-10 17:05:28 +01004920 struct connection *conn = objt_conn((kw[4] != 'b') ? smp->sess->origin :
4921 smp->strm ? smp->strm->si[1].end : NULL);
Willy Tarreaube508f12016-03-10 11:47:01 +01004922
Emeric Brun589fcad2012-10-16 14:13:26 +02004923 smp->flags = 0;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004924 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
4925 return 0;
4926
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004927 smp->data.u.str.str = (char *)SSL_get_version(conn->xprt_ctx);
4928 if (!smp->data.u.str.str)
Emeric Brun589fcad2012-10-16 14:13:26 +02004929 return 0;
4930
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004931 smp->data.type = SMP_T_STR;
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01004932 smp->flags = SMP_F_CONST;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004933 smp->data.u.str.len = strlen(smp->data.u.str.str);
Emeric Brun589fcad2012-10-16 14:13:26 +02004934
4935 return 1;
4936}
4937
Willy Tarreau87b09662015-04-03 00:22:06 +02004938/* binary, returns the SSL stream id if front conn. transport layer is SSL.
Emeric Brun645ae792014-04-30 14:21:06 +02004939 * This function is also usable on backend conn if the fetch keyword 5th
4940 * char is 'b'.
4941 */
Emeric Brun589fcad2012-10-16 14:13:26 +02004942static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004943smp_fetch_ssl_fc_session_id(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brunfe68f682012-10-16 14:59:28 +02004944{
4945#if OPENSSL_VERSION_NUMBER > 0x0090800fL
Willy Tarreaue237fe12016-03-10 17:05:28 +01004946 struct connection *conn = objt_conn((kw[4] != 'b') ? smp->sess->origin :
4947 smp->strm ? smp->strm->si[1].end : NULL);
Emeric Brunfe68f682012-10-16 14:59:28 +02004948
Willy Tarreaue237fe12016-03-10 17:05:28 +01004949 SSL_SESSION *ssl_sess;
Willy Tarreaube508f12016-03-10 11:47:01 +01004950
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01004951 smp->flags = SMP_F_CONST;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004952 smp->data.type = SMP_T_BIN;
Emeric Brunfe68f682012-10-16 14:59:28 +02004953
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004954 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
4955 return 0;
4956
Willy Tarreau192252e2015-04-04 01:47:55 +02004957 ssl_sess = SSL_get_session(conn->xprt_ctx);
4958 if (!ssl_sess)
Emeric Brunfe68f682012-10-16 14:59:28 +02004959 return 0;
4960
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004961 smp->data.u.str.str = (char *)SSL_SESSION_get_id(ssl_sess, (unsigned int *)&smp->data.u.str.len);
4962 if (!smp->data.u.str.str || !smp->data.u.str.len)
Emeric Brunfe68f682012-10-16 14:59:28 +02004963 return 0;
4964
4965 return 1;
4966#else
4967 return 0;
4968#endif
4969}
4970
4971static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004972smp_fetch_ssl_fc_sni(const struct arg *args, struct sample *smp, const char *kw, void *private)
Willy Tarreau7875d092012-09-10 08:20:03 +02004973{
4974#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004975 struct connection *conn;
4976
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01004977 smp->flags = SMP_F_CONST;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004978 smp->data.type = SMP_T_STR;
Willy Tarreau7875d092012-09-10 08:20:03 +02004979
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004980 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004981 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
4982 return 0;
4983
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004984 smp->data.u.str.str = (char *)SSL_get_servername(conn->xprt_ctx, TLSEXT_NAMETYPE_host_name);
4985 if (!smp->data.u.str.str)
Willy Tarreau3e394c92012-09-14 23:56:58 +02004986 return 0;
4987
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004988 smp->data.u.str.len = strlen(smp->data.u.str.str);
Willy Tarreau7875d092012-09-10 08:20:03 +02004989 return 1;
4990#else
4991 return 0;
4992#endif
4993}
4994
David Sc1ad52e2014-04-08 18:48:47 -04004995static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004996smp_fetch_ssl_fc_unique_id(const struct arg *args, struct sample *smp, const char *kw, void *private)
David Sc1ad52e2014-04-08 18:48:47 -04004997{
4998#if OPENSSL_VERSION_NUMBER > 0x0090800fL
Willy Tarreaue237fe12016-03-10 17:05:28 +01004999 struct connection *conn = objt_conn((kw[4] != 'b') ? smp->sess->origin :
5000 smp->strm ? smp->strm->si[1].end : NULL);
5001
David Sc1ad52e2014-04-08 18:48:47 -04005002 int finished_len;
David Sc1ad52e2014-04-08 18:48:47 -04005003 struct chunk *finished_trash;
David Sc1ad52e2014-04-08 18:48:47 -04005004
5005 smp->flags = 0;
David Sc1ad52e2014-04-08 18:48:47 -04005006 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
5007 return 0;
5008
5009 if (!(conn->flags & CO_FL_CONNECTED)) {
5010 smp->flags |= SMP_F_MAY_CHANGE;
5011 return 0;
5012 }
5013
5014 finished_trash = get_trash_chunk();
5015 if (!SSL_session_reused(conn->xprt_ctx))
5016 finished_len = SSL_get_peer_finished(conn->xprt_ctx, finished_trash->str, finished_trash->size);
5017 else
5018 finished_len = SSL_get_finished(conn->xprt_ctx, finished_trash->str, finished_trash->size);
5019
5020 if (!finished_len)
5021 return 0;
5022
Emeric Brunb73a9b02014-04-30 18:49:19 +02005023 finished_trash->len = finished_len;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005024 smp->data.u.str = *finished_trash;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005025 smp->data.type = SMP_T_BIN;
David Sc1ad52e2014-04-08 18:48:47 -04005026
5027 return 1;
5028#else
5029 return 0;
5030#endif
5031}
5032
Emeric Brun2525b6b2012-10-18 15:59:43 +02005033/* integer, returns the first verify error in CA chain of client certificate chain. */
Emeric Brunf282a812012-09-21 15:27:54 +02005034static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005035smp_fetch_ssl_c_ca_err(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brunf282a812012-09-21 15:27:54 +02005036{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005037 struct connection *conn;
5038
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02005039 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005040 if (!conn || conn->xprt != &ssl_sock)
5041 return 0;
5042
5043 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunf282a812012-09-21 15:27:54 +02005044 smp->flags = SMP_F_MAY_CHANGE;
5045 return 0;
5046 }
5047
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005048 smp->data.type = SMP_T_SINT;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005049 smp->data.u.sint = (unsigned long long int)SSL_SOCK_ST_TO_CA_ERROR(conn->xprt_st);
Emeric Brunf282a812012-09-21 15:27:54 +02005050 smp->flags = 0;
5051
5052 return 1;
5053}
5054
Emeric Brun2525b6b2012-10-18 15:59:43 +02005055/* integer, returns the depth of the first verify error in CA chain of client certificate chain. */
Emeric Brunf282a812012-09-21 15:27:54 +02005056static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005057smp_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 +02005058{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005059 struct connection *conn;
5060
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02005061 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005062 if (!conn || conn->xprt != &ssl_sock)
Emeric Brunf282a812012-09-21 15:27:54 +02005063 return 0;
5064
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005065 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunf282a812012-09-21 15:27:54 +02005066 smp->flags = SMP_F_MAY_CHANGE;
5067 return 0;
5068 }
5069
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005070 smp->data.type = SMP_T_SINT;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005071 smp->data.u.sint = (long long int)SSL_SOCK_ST_TO_CAEDEPTH(conn->xprt_st);
Emeric Brunf282a812012-09-21 15:27:54 +02005072 smp->flags = 0;
5073
5074 return 1;
5075}
5076
Emeric Brun2525b6b2012-10-18 15:59:43 +02005077/* integer, returns the first verify error on client certificate */
Emeric Brunf282a812012-09-21 15:27:54 +02005078static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005079smp_fetch_ssl_c_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 = (long long int)SSL_SOCK_ST_TO_CRTERROR(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 verify result on client cert */
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02005100static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005101smp_fetch_ssl_c_verify(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brunbaf8ffb2012-09-21 15:27:20 +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)
5107 return 0;
5108
5109 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02005110 smp->flags = SMP_F_MAY_CHANGE;
5111 return 0;
5112 }
5113
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005114 if (!conn->xprt_ctx)
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02005115 return 0;
5116
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005117 smp->data.type = SMP_T_SINT;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005118 smp->data.u.sint = (long long int)SSL_get_verify_result(conn->xprt_ctx);
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02005119 smp->flags = 0;
5120
5121 return 1;
5122}
5123
Emeric Brunfb510ea2012-10-05 12:00:26 +02005124/* parse the "ca-file" bind keyword */
5125static 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 +02005126{
5127 if (!*args[cur_arg + 1]) {
5128 if (err)
5129 memprintf(err, "'%s' : missing CAfile path", args[cur_arg]);
5130 return ERR_ALERT | ERR_FATAL;
5131 }
5132
Emeric Brunef42d922012-10-11 16:11:36 +02005133 if ((*args[cur_arg + 1] != '/') && global.ca_base)
5134 memprintf(&conf->ca_file, "%s/%s", global.ca_base, args[cur_arg + 1]);
5135 else
5136 memprintf(&conf->ca_file, "%s", args[cur_arg + 1]);
Emeric Brunc8e8d122012-10-02 18:42:10 +02005137
Emeric Brund94b3fe2012-09-20 18:23:56 +02005138 return 0;
5139}
5140
Christopher Faulet31af49d2015-06-09 17:29:50 +02005141/* parse the "ca-sign-file" bind keyword */
5142static int bind_parse_ca_sign_file(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5143{
5144 if (!*args[cur_arg + 1]) {
5145 if (err)
5146 memprintf(err, "'%s' : missing CAfile path", args[cur_arg]);
5147 return ERR_ALERT | ERR_FATAL;
5148 }
5149
5150 if ((*args[cur_arg + 1] != '/') && global.ca_base)
5151 memprintf(&conf->ca_sign_file, "%s/%s", global.ca_base, args[cur_arg + 1]);
5152 else
5153 memprintf(&conf->ca_sign_file, "%s", args[cur_arg + 1]);
5154
5155 return 0;
5156}
5157
Bertrand Jacquinff13c062016-11-13 16:37:11 +00005158/* parse the "ca-sign-pass" bind keyword */
Christopher Faulet31af49d2015-06-09 17:29:50 +02005159static int bind_parse_ca_sign_pass(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5160{
5161 if (!*args[cur_arg + 1]) {
5162 if (err)
5163 memprintf(err, "'%s' : missing CAkey password", args[cur_arg]);
5164 return ERR_ALERT | ERR_FATAL;
5165 }
5166 memprintf(&conf->ca_sign_pass, "%s", args[cur_arg + 1]);
5167 return 0;
5168}
5169
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005170/* parse the "ciphers" bind keyword */
Willy Tarreau4348fad2012-09-20 16:48:07 +02005171static 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 +02005172{
5173 if (!*args[cur_arg + 1]) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02005174 memprintf(err, "'%s' : missing cipher suite", args[cur_arg]);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005175 return ERR_ALERT | ERR_FATAL;
5176 }
5177
Emeric Brun76d88952012-10-05 15:47:31 +02005178 free(conf->ciphers);
Willy Tarreau4348fad2012-09-20 16:48:07 +02005179 conf->ciphers = strdup(args[cur_arg + 1]);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005180 return 0;
5181}
5182
5183/* parse the "crt" bind keyword */
Willy Tarreau4348fad2012-09-20 16:48:07 +02005184static 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 +02005185{
Willy Tarreau38011032013-08-13 16:59:39 +02005186 char path[MAXPATHLEN];
Willy Tarreaub75d6922014-04-14 18:05:41 +02005187
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005188 if (!*args[cur_arg + 1]) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02005189 memprintf(err, "'%s' : missing certificate location", args[cur_arg]);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005190 return ERR_ALERT | ERR_FATAL;
5191 }
5192
Emeric Brunc8e8d122012-10-02 18:42:10 +02005193 if ((*args[cur_arg + 1] != '/' ) && global.crt_base) {
Willy Tarreau38011032013-08-13 16:59:39 +02005194 if ((strlen(global.crt_base) + 1 + strlen(args[cur_arg + 1]) + 1) > MAXPATHLEN) {
Emeric Brunc8e8d122012-10-02 18:42:10 +02005195 memprintf(err, "'%s' : path too long", args[cur_arg]);
5196 return ERR_ALERT | ERR_FATAL;
5197 }
Willy Tarreaub75d6922014-04-14 18:05:41 +02005198 snprintf(path, sizeof(path), "%s/%s", global.crt_base, args[cur_arg + 1]);
Emeric Brunc8e8d122012-10-02 18:42:10 +02005199 if (ssl_sock_load_cert(path, conf, px, err) > 0)
5200 return ERR_ALERT | ERR_FATAL;
5201
5202 return 0;
5203 }
5204
Willy Tarreau4348fad2012-09-20 16:48:07 +02005205 if (ssl_sock_load_cert(args[cur_arg + 1], conf, px, err) > 0)
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005206 return ERR_ALERT | ERR_FATAL;
Emeric Brund94b3fe2012-09-20 18:23:56 +02005207
5208 return 0;
5209}
5210
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01005211/* parse the "crt-list" bind keyword */
5212static int bind_parse_crt_list(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5213{
5214 if (!*args[cur_arg + 1]) {
5215 memprintf(err, "'%s' : missing certificate location", args[cur_arg]);
5216 return ERR_ALERT | ERR_FATAL;
5217 }
5218
Willy Tarreauad1731d2013-04-02 17:35:58 +02005219 if (ssl_sock_load_cert_list_file(args[cur_arg + 1], conf, px, err) > 0) {
5220 memprintf(err, "'%s' : %s", args[cur_arg], *err);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01005221 return ERR_ALERT | ERR_FATAL;
Willy Tarreauad1731d2013-04-02 17:35:58 +02005222 }
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01005223
5224 return 0;
5225}
5226
Emeric Brunfb510ea2012-10-05 12:00:26 +02005227/* parse the "crl-file" bind keyword */
5228static 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 +02005229{
Emeric Brun051cdab2012-10-02 19:25:50 +02005230#ifndef X509_V_FLAG_CRL_CHECK
5231 if (err)
5232 memprintf(err, "'%s' : library does not support CRL verify", args[cur_arg]);
5233 return ERR_ALERT | ERR_FATAL;
5234#else
Emeric Brund94b3fe2012-09-20 18:23:56 +02005235 if (!*args[cur_arg + 1]) {
5236 if (err)
5237 memprintf(err, "'%s' : missing CRLfile path", args[cur_arg]);
5238 return ERR_ALERT | ERR_FATAL;
5239 }
Emeric Brun2b58d042012-09-20 17:10:03 +02005240
Emeric Brunef42d922012-10-11 16:11:36 +02005241 if ((*args[cur_arg + 1] != '/') && global.ca_base)
5242 memprintf(&conf->crl_file, "%s/%s", global.ca_base, args[cur_arg + 1]);
5243 else
5244 memprintf(&conf->crl_file, "%s", args[cur_arg + 1]);
Emeric Brunc8e8d122012-10-02 18:42:10 +02005245
Emeric Brun2b58d042012-09-20 17:10:03 +02005246 return 0;
Emeric Brun051cdab2012-10-02 19:25:50 +02005247#endif
Emeric Brun2b58d042012-09-20 17:10:03 +02005248}
5249
Bertrand Jacquinff13c062016-11-13 16:37:11 +00005250/* parse the "ecdhe" bind keyword keyword */
Emeric Brun2b58d042012-09-20 17:10:03 +02005251static int bind_parse_ecdhe(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5252{
5253#if OPENSSL_VERSION_NUMBER < 0x0090800fL
5254 if (err)
5255 memprintf(err, "'%s' : library does not support elliptic curve Diffie-Hellman (too old)", args[cur_arg]);
5256 return ERR_ALERT | ERR_FATAL;
5257#elif defined(OPENSSL_NO_ECDH)
5258 if (err)
5259 memprintf(err, "'%s' : library does not support elliptic curve Diffie-Hellman (disabled via OPENSSL_NO_ECDH)", args[cur_arg]);
5260 return ERR_ALERT | ERR_FATAL;
5261#else
5262 if (!*args[cur_arg + 1]) {
5263 if (err)
5264 memprintf(err, "'%s' : missing named curve", args[cur_arg]);
5265 return ERR_ALERT | ERR_FATAL;
5266 }
5267
5268 conf->ecdhe = strdup(args[cur_arg + 1]);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005269
5270 return 0;
Emeric Brun2b58d042012-09-20 17:10:03 +02005271#endif
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005272}
5273
Bertrand Jacquinff13c062016-11-13 16:37:11 +00005274/* parse the "crt-ignore-err" and "ca-ignore-err" bind keywords */
Emeric Brun81c00f02012-09-21 14:31:21 +02005275static int bind_parse_ignore_err(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5276{
5277 int code;
5278 char *p = args[cur_arg + 1];
5279 unsigned long long *ignerr = &conf->crt_ignerr;
5280
5281 if (!*p) {
5282 if (err)
5283 memprintf(err, "'%s' : missing error IDs list", args[cur_arg]);
5284 return ERR_ALERT | ERR_FATAL;
5285 }
5286
5287 if (strcmp(args[cur_arg], "ca-ignore-err") == 0)
5288 ignerr = &conf->ca_ignerr;
5289
5290 if (strcmp(p, "all") == 0) {
5291 *ignerr = ~0ULL;
5292 return 0;
5293 }
5294
5295 while (p) {
5296 code = atoi(p);
5297 if ((code <= 0) || (code > 63)) {
5298 if (err)
5299 memprintf(err, "'%s' : ID '%d' out of range (1..63) in error IDs list '%s'",
5300 args[cur_arg], code, args[cur_arg + 1]);
5301 return ERR_ALERT | ERR_FATAL;
5302 }
5303 *ignerr |= 1ULL << code;
5304 p = strchr(p, ',');
5305 if (p)
5306 p++;
5307 }
5308
Emeric Brun2cb7ae52012-10-05 14:14:21 +02005309 return 0;
5310}
5311
5312/* parse the "force-sslv3" bind keyword */
5313static int bind_parse_force_sslv3(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5314{
5315 conf->ssl_options |= BC_SSL_O_USE_SSLV3;
5316 return 0;
5317}
5318
5319/* parse the "force-tlsv10" bind keyword */
5320static int bind_parse_force_tlsv10(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5321{
5322 conf->ssl_options |= BC_SSL_O_USE_TLSV10;
Emeric Brun2d0c4822012-10-02 13:45:20 +02005323 return 0;
5324}
5325
Emeric Brun2cb7ae52012-10-05 14:14:21 +02005326/* parse the "force-tlsv11" bind keyword */
5327static int bind_parse_force_tlsv11(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5328{
5329#if SSL_OP_NO_TLSv1_1
5330 conf->ssl_options |= BC_SSL_O_USE_TLSV11;
5331 return 0;
5332#else
5333 if (err)
5334 memprintf(err, "'%s' : library does not support protocol TLSv1.1", args[cur_arg]);
5335 return ERR_ALERT | ERR_FATAL;
5336#endif
5337}
5338
5339/* parse the "force-tlsv12" bind keyword */
5340static int bind_parse_force_tlsv12(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5341{
5342#if SSL_OP_NO_TLSv1_2
5343 conf->ssl_options |= BC_SSL_O_USE_TLSV12;
5344 return 0;
5345#else
5346 if (err)
5347 memprintf(err, "'%s' : library does not support protocol TLSv1.2", args[cur_arg]);
5348 return ERR_ALERT | ERR_FATAL;
5349#endif
5350}
5351
5352
Emeric Brun2d0c4822012-10-02 13:45:20 +02005353/* parse the "no-tls-tickets" bind keyword */
5354static int bind_parse_no_tls_tickets(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5355{
Emeric Brun89675492012-10-05 13:48:26 +02005356 conf->ssl_options |= BC_SSL_O_NO_TLS_TICKETS;
Emeric Brun81c00f02012-09-21 14:31:21 +02005357 return 0;
5358}
5359
Emeric Brun2d0c4822012-10-02 13:45:20 +02005360
Emeric Brun9b3009b2012-10-05 11:55:06 +02005361/* parse the "no-sslv3" bind keyword */
5362static 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 +02005363{
Emeric Brun89675492012-10-05 13:48:26 +02005364 conf->ssl_options |= BC_SSL_O_NO_SSLV3;
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005365 return 0;
5366}
5367
Emeric Brun9b3009b2012-10-05 11:55:06 +02005368/* parse the "no-tlsv10" bind keyword */
5369static 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 +02005370{
Emeric Brun89675492012-10-05 13:48:26 +02005371 conf->ssl_options |= BC_SSL_O_NO_TLSV10;
Emeric Brunc0ff4922012-09-28 19:37:02 +02005372 return 0;
5373}
5374
Emeric Brun9b3009b2012-10-05 11:55:06 +02005375/* parse the "no-tlsv11" bind keyword */
5376static 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 +02005377{
Emeric Brun89675492012-10-05 13:48:26 +02005378 conf->ssl_options |= BC_SSL_O_NO_TLSV11;
Emeric Brunc0ff4922012-09-28 19:37:02 +02005379 return 0;
5380}
5381
Emeric Brun9b3009b2012-10-05 11:55:06 +02005382/* parse the "no-tlsv12" bind keyword */
5383static 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 +02005384{
Emeric Brun89675492012-10-05 13:48:26 +02005385 conf->ssl_options |= BC_SSL_O_NO_TLSV12;
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005386 return 0;
5387}
5388
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02005389/* parse the "npn" bind keyword */
5390static int bind_parse_npn(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5391{
5392#ifdef OPENSSL_NPN_NEGOTIATED
5393 char *p1, *p2;
5394
5395 if (!*args[cur_arg + 1]) {
5396 memprintf(err, "'%s' : missing the comma-delimited NPN protocol suite", args[cur_arg]);
5397 return ERR_ALERT | ERR_FATAL;
5398 }
5399
5400 free(conf->npn_str);
5401
Willy Tarreau3724da12016-02-12 17:11:12 +01005402 /* the NPN string is built as a suite of (<len> <name>)*,
5403 * so we reuse each comma to store the next <len> and need
5404 * one more for the end of the string.
5405 */
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02005406 conf->npn_len = strlen(args[cur_arg + 1]) + 1;
Willy Tarreau3724da12016-02-12 17:11:12 +01005407 conf->npn_str = calloc(1, conf->npn_len + 1);
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02005408 memcpy(conf->npn_str + 1, args[cur_arg + 1], conf->npn_len);
5409
5410 /* replace commas with the name length */
5411 p1 = conf->npn_str;
5412 p2 = p1 + 1;
5413 while (1) {
5414 p2 = memchr(p1 + 1, ',', conf->npn_str + conf->npn_len - (p1 + 1));
5415 if (!p2)
5416 p2 = p1 + 1 + strlen(p1 + 1);
5417
5418 if (p2 - (p1 + 1) > 255) {
5419 *p2 = '\0';
5420 memprintf(err, "'%s' : NPN protocol name too long : '%s'", args[cur_arg], p1 + 1);
5421 return ERR_ALERT | ERR_FATAL;
5422 }
5423
5424 *p1 = p2 - (p1 + 1);
5425 p1 = p2;
5426
5427 if (!*p2)
5428 break;
5429
5430 *(p2++) = '\0';
5431 }
5432 return 0;
5433#else
5434 if (err)
5435 memprintf(err, "'%s' : library does not support TLS NPN extension", args[cur_arg]);
5436 return ERR_ALERT | ERR_FATAL;
5437#endif
5438}
5439
Willy Tarreauab861d32013-04-02 02:30:41 +02005440/* parse the "alpn" bind keyword */
5441static int bind_parse_alpn(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5442{
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01005443#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Willy Tarreauab861d32013-04-02 02:30:41 +02005444 char *p1, *p2;
5445
5446 if (!*args[cur_arg + 1]) {
5447 memprintf(err, "'%s' : missing the comma-delimited ALPN protocol suite", args[cur_arg]);
5448 return ERR_ALERT | ERR_FATAL;
5449 }
5450
5451 free(conf->alpn_str);
5452
Marcoen Hirschbergbef60912016-02-12 17:05:24 +01005453 /* the ALPN string is built as a suite of (<len> <name>)*,
5454 * so we reuse each comma to store the next <len> and need
5455 * one more for the end of the string.
5456 */
Willy Tarreauab861d32013-04-02 02:30:41 +02005457 conf->alpn_len = strlen(args[cur_arg + 1]) + 1;
Marcoen Hirschbergbef60912016-02-12 17:05:24 +01005458 conf->alpn_str = calloc(1, conf->alpn_len + 1);
Willy Tarreauab861d32013-04-02 02:30:41 +02005459 memcpy(conf->alpn_str + 1, args[cur_arg + 1], conf->alpn_len);
5460
5461 /* replace commas with the name length */
5462 p1 = conf->alpn_str;
5463 p2 = p1 + 1;
5464 while (1) {
5465 p2 = memchr(p1 + 1, ',', conf->alpn_str + conf->alpn_len - (p1 + 1));
5466 if (!p2)
5467 p2 = p1 + 1 + strlen(p1 + 1);
5468
5469 if (p2 - (p1 + 1) > 255) {
5470 *p2 = '\0';
5471 memprintf(err, "'%s' : ALPN protocol name too long : '%s'", args[cur_arg], p1 + 1);
5472 return ERR_ALERT | ERR_FATAL;
5473 }
5474
5475 *p1 = p2 - (p1 + 1);
5476 p1 = p2;
5477
5478 if (!*p2)
5479 break;
5480
5481 *(p2++) = '\0';
5482 }
5483 return 0;
5484#else
5485 if (err)
5486 memprintf(err, "'%s' : library does not support TLS ALPN extension", args[cur_arg]);
5487 return ERR_ALERT | ERR_FATAL;
5488#endif
5489}
5490
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005491/* parse the "ssl" bind keyword */
Willy Tarreau4348fad2012-09-20 16:48:07 +02005492static 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 +02005493{
Willy Tarreau71a8c7c2016-12-21 22:04:54 +01005494 conf->xprt = &ssl_sock;
Willy Tarreau4348fad2012-09-20 16:48:07 +02005495 conf->is_ssl = 1;
Emeric Brun76d88952012-10-05 15:47:31 +02005496
5497 if (global.listen_default_ciphers && !conf->ciphers)
5498 conf->ciphers = strdup(global.listen_default_ciphers);
Emeric Brun2c86cbf2014-10-30 15:56:50 +01005499 conf->ssl_options |= global.listen_default_ssloptions;
Emeric Brun76d88952012-10-05 15:47:31 +02005500
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005501 return 0;
5502}
5503
Christopher Faulet31af49d2015-06-09 17:29:50 +02005504/* parse the "generate-certificates" bind keyword */
5505static int bind_parse_generate_certs(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5506{
5507#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
5508 conf->generate_certs = 1;
5509#else
5510 memprintf(err, "%sthis version of openssl cannot generate SSL certificates.\n",
5511 err && *err ? *err : "");
5512#endif
5513 return 0;
5514}
5515
Emmanuel Hocdet65623372013-01-24 17:17:15 +01005516/* parse the "strict-sni" bind keyword */
5517static int bind_parse_strict_sni(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5518{
5519 conf->strict_sni = 1;
5520 return 0;
Nenad Merdanovic05552d42015-02-27 19:56:49 +01005521}
5522
5523/* parse the "tls-ticket-keys" bind keyword */
5524static int bind_parse_tls_ticket_keys(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5525{
5526#if (defined SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB && TLS_TICKETS_NO > 0)
5527 FILE *f;
5528 int i = 0;
5529 char thisline[LINESIZE];
Nenad Merdanovic146defa2015-05-09 08:46:00 +02005530 struct tls_keys_ref *keys_ref;
Nenad Merdanovic05552d42015-02-27 19:56:49 +01005531
5532 if (!*args[cur_arg + 1]) {
5533 if (err)
5534 memprintf(err, "'%s' : missing TLS ticket keys file path", args[cur_arg]);
5535 return ERR_ALERT | ERR_FATAL;
5536 }
5537
Nenad Merdanovic200b0fa2015-05-09 08:46:01 +02005538 keys_ref = tlskeys_ref_lookup(args[cur_arg + 1]);
5539 if(keys_ref) {
5540 conf->keys_ref = keys_ref;
5541 return 0;
5542 }
5543
Vincent Bernat02779b62016-04-03 13:48:43 +02005544 keys_ref = malloc(sizeof(*keys_ref));
Nenad Merdanovic146defa2015-05-09 08:46:00 +02005545 keys_ref->tlskeys = malloc(TLS_TICKETS_NO * sizeof(struct tls_sess_key));
Nenad Merdanovic05552d42015-02-27 19:56:49 +01005546
5547 if ((f = fopen(args[cur_arg + 1], "r")) == NULL) {
5548 if (err)
5549 memprintf(err, "'%s' : unable to load ssl tickets keys file", args[cur_arg+1]);
5550 return ERR_ALERT | ERR_FATAL;
5551 }
5552
Nenad Merdanovic146defa2015-05-09 08:46:00 +02005553 keys_ref->filename = strdup(args[cur_arg + 1]);
5554
Nenad Merdanovic05552d42015-02-27 19:56:49 +01005555 while (fgets(thisline, sizeof(thisline), f) != NULL) {
5556 int len = strlen(thisline);
5557 /* Strip newline characters from the end */
5558 if(thisline[len - 1] == '\n')
5559 thisline[--len] = 0;
5560
5561 if(thisline[len - 1] == '\r')
5562 thisline[--len] = 0;
5563
Nenad Merdanovic146defa2015-05-09 08:46:00 +02005564 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 +01005565 if (err)
5566 memprintf(err, "'%s' : unable to decode base64 key on line %d", args[cur_arg+1], i + 1);
mildis16aa0152016-06-22 17:46:29 +02005567 fclose(f);
Nenad Merdanovic05552d42015-02-27 19:56:49 +01005568 return ERR_ALERT | ERR_FATAL;
5569 }
5570 i++;
5571 }
5572
5573 if (i < TLS_TICKETS_NO) {
5574 if (err)
5575 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 +02005576 fclose(f);
Nenad Merdanovic05552d42015-02-27 19:56:49 +01005577 return ERR_ALERT | ERR_FATAL;
5578 }
5579
5580 fclose(f);
5581
5582 /* Use penultimate key for encryption, handle when TLS_TICKETS_NO = 1 */
Nenad Merdanovic17891152016-03-25 22:16:57 +01005583 i -= 2;
5584 keys_ref->tls_ticket_enc_index = i < 0 ? 0 : i % TLS_TICKETS_NO;
Nenad Merdanovic200b0fa2015-05-09 08:46:01 +02005585 keys_ref->unique_id = -1;
Nenad Merdanovic146defa2015-05-09 08:46:00 +02005586 conf->keys_ref = keys_ref;
Nenad Merdanovic05552d42015-02-27 19:56:49 +01005587
Nenad Merdanovic200b0fa2015-05-09 08:46:01 +02005588 LIST_ADD(&tlskeys_reference, &keys_ref->list);
5589
Nenad Merdanovic05552d42015-02-27 19:56:49 +01005590 return 0;
5591#else
5592 if (err)
5593 memprintf(err, "'%s' : TLS ticket callback extension not supported", args[cur_arg]);
5594 return ERR_ALERT | ERR_FATAL;
5595#endif /* SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB */
Emmanuel Hocdet65623372013-01-24 17:17:15 +01005596}
5597
Emeric Brund94b3fe2012-09-20 18:23:56 +02005598/* parse the "verify" bind keyword */
5599static int bind_parse_verify(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5600{
5601 if (!*args[cur_arg + 1]) {
5602 if (err)
5603 memprintf(err, "'%s' : missing verify method", args[cur_arg]);
5604 return ERR_ALERT | ERR_FATAL;
5605 }
5606
5607 if (strcmp(args[cur_arg + 1], "none") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01005608 conf->verify = SSL_SOCK_VERIFY_NONE;
Emeric Brund94b3fe2012-09-20 18:23:56 +02005609 else if (strcmp(args[cur_arg + 1], "optional") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01005610 conf->verify = SSL_SOCK_VERIFY_OPTIONAL;
Emeric Brund94b3fe2012-09-20 18:23:56 +02005611 else if (strcmp(args[cur_arg + 1], "required") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01005612 conf->verify = SSL_SOCK_VERIFY_REQUIRED;
Emeric Brund94b3fe2012-09-20 18:23:56 +02005613 else {
5614 if (err)
5615 memprintf(err, "'%s' : unknown verify method '%s', only 'none', 'optional', and 'required' are supported\n",
5616 args[cur_arg], args[cur_arg + 1]);
5617 return ERR_ALERT | ERR_FATAL;
5618 }
5619
5620 return 0;
5621}
5622
Willy Tarreau92faadf2012-10-10 23:04:25 +02005623/************** "server" keywords ****************/
5624
Emeric Brunef42d922012-10-11 16:11:36 +02005625/* parse the "ca-file" server keyword */
5626static int srv_parse_ca_file(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5627{
5628 if (!*args[*cur_arg + 1]) {
5629 if (err)
5630 memprintf(err, "'%s' : missing CAfile path", args[*cur_arg]);
5631 return ERR_ALERT | ERR_FATAL;
5632 }
5633
5634 if ((*args[*cur_arg + 1] != '/') && global.ca_base)
5635 memprintf(&newsrv->ssl_ctx.ca_file, "%s/%s", global.ca_base, args[*cur_arg + 1]);
5636 else
5637 memprintf(&newsrv->ssl_ctx.ca_file, "%s", args[*cur_arg + 1]);
5638
5639 return 0;
5640}
5641
Willy Tarreau92faadf2012-10-10 23:04:25 +02005642/* parse the "check-ssl" server keyword */
5643static int srv_parse_check_ssl(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5644{
5645 newsrv->check.use_ssl = 1;
5646 if (global.connect_default_ciphers && !newsrv->ssl_ctx.ciphers)
5647 newsrv->ssl_ctx.ciphers = strdup(global.connect_default_ciphers);
Emeric Brun2c86cbf2014-10-30 15:56:50 +01005648 newsrv->ssl_ctx.options |= global.connect_default_ssloptions;
Willy Tarreau92faadf2012-10-10 23:04:25 +02005649 return 0;
5650}
5651
5652/* parse the "ciphers" server keyword */
5653static int srv_parse_ciphers(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5654{
5655 if (!*args[*cur_arg + 1]) {
5656 memprintf(err, "'%s' : missing cipher suite", args[*cur_arg]);
5657 return ERR_ALERT | ERR_FATAL;
5658 }
5659
5660 free(newsrv->ssl_ctx.ciphers);
5661 newsrv->ssl_ctx.ciphers = strdup(args[*cur_arg + 1]);
5662 return 0;
5663}
5664
Emeric Brunef42d922012-10-11 16:11:36 +02005665/* parse the "crl-file" server keyword */
5666static int srv_parse_crl_file(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5667{
5668#ifndef X509_V_FLAG_CRL_CHECK
5669 if (err)
5670 memprintf(err, "'%s' : library does not support CRL verify", args[*cur_arg]);
5671 return ERR_ALERT | ERR_FATAL;
5672#else
5673 if (!*args[*cur_arg + 1]) {
5674 if (err)
5675 memprintf(err, "'%s' : missing CRLfile path", args[*cur_arg]);
5676 return ERR_ALERT | ERR_FATAL;
5677 }
5678
5679 if ((*args[*cur_arg + 1] != '/') && global.ca_base)
5680 memprintf(&newsrv->ssl_ctx.crl_file, "%s/%s", global.ca_base, args[*cur_arg + 1]);
5681 else
5682 memprintf(&newsrv->ssl_ctx.crl_file, "%s", args[*cur_arg + 1]);
5683
5684 return 0;
5685#endif
5686}
5687
Emeric Bruna7aa3092012-10-26 12:58:00 +02005688/* parse the "crt" server keyword */
5689static int srv_parse_crt(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5690{
5691 if (!*args[*cur_arg + 1]) {
5692 if (err)
5693 memprintf(err, "'%s' : missing certificate file path", args[*cur_arg]);
5694 return ERR_ALERT | ERR_FATAL;
5695 }
5696
5697 if ((*args[*cur_arg + 1] != '/') && global.crt_base)
5698 memprintf(&newsrv->ssl_ctx.client_crt, "%s/%s", global.ca_base, args[*cur_arg + 1]);
5699 else
5700 memprintf(&newsrv->ssl_ctx.client_crt, "%s", args[*cur_arg + 1]);
5701
5702 return 0;
5703}
Emeric Brunef42d922012-10-11 16:11:36 +02005704
Willy Tarreau92faadf2012-10-10 23:04:25 +02005705/* parse the "force-sslv3" server keyword */
5706static int srv_parse_force_sslv3(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5707{
5708 newsrv->ssl_ctx.options |= SRV_SSL_O_USE_SSLV3;
5709 return 0;
5710}
5711
5712/* parse the "force-tlsv10" server keyword */
5713static int srv_parse_force_tlsv10(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5714{
5715 newsrv->ssl_ctx.options |= SRV_SSL_O_USE_TLSV10;
5716 return 0;
5717}
5718
5719/* parse the "force-tlsv11" server keyword */
5720static int srv_parse_force_tlsv11(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5721{
5722#if SSL_OP_NO_TLSv1_1
5723 newsrv->ssl_ctx.options |= SRV_SSL_O_USE_TLSV11;
5724 return 0;
5725#else
5726 if (err)
5727 memprintf(err, "'%s' : library does not support protocol TLSv1.1", args[*cur_arg]);
5728 return ERR_ALERT | ERR_FATAL;
5729#endif
5730}
5731
5732/* parse the "force-tlsv12" server keyword */
5733static int srv_parse_force_tlsv12(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5734{
5735#if SSL_OP_NO_TLSv1_2
5736 newsrv->ssl_ctx.options |= SRV_SSL_O_USE_TLSV12;
5737 return 0;
5738#else
5739 if (err)
5740 memprintf(err, "'%s' : library does not support protocol TLSv1.2", args[*cur_arg]);
5741 return ERR_ALERT | ERR_FATAL;
5742#endif
5743}
5744
Willy Tarreau2a3fb1c2015-02-05 16:47:07 +01005745/* parse the "no-ssl-reuse" server keyword */
5746static int srv_parse_no_ssl_reuse(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5747{
5748 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_REUSE;
5749 return 0;
5750}
5751
Willy Tarreau92faadf2012-10-10 23:04:25 +02005752/* parse the "no-sslv3" server keyword */
5753static int srv_parse_no_sslv3(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5754{
5755 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_SSLV3;
5756 return 0;
5757}
5758
5759/* parse the "no-tlsv10" server keyword */
5760static int srv_parse_no_tlsv10(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5761{
5762 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_TLSV10;
5763 return 0;
5764}
5765
5766/* parse the "no-tlsv11" server keyword */
5767static int srv_parse_no_tlsv11(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5768{
5769 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_TLSV11;
5770 return 0;
5771}
5772
5773/* parse the "no-tlsv12" server keyword */
5774static int srv_parse_no_tlsv12(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5775{
5776 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_TLSV12;
5777 return 0;
5778}
5779
Emeric Brunf9c5c472012-10-11 15:28:34 +02005780/* parse the "no-tls-tickets" server keyword */
5781static int srv_parse_no_tls_tickets(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5782{
5783 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_TLS_TICKETS;
5784 return 0;
5785}
David Safb76832014-05-08 23:42:08 -04005786/* parse the "send-proxy-v2-ssl" server keyword */
5787static int srv_parse_send_proxy_ssl(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5788{
5789 newsrv->pp_opts |= SRV_PP_V2;
5790 newsrv->pp_opts |= SRV_PP_V2_SSL;
5791 return 0;
5792}
5793
5794/* parse the "send-proxy-v2-ssl-cn" server keyword */
5795static int srv_parse_send_proxy_cn(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5796{
5797 newsrv->pp_opts |= SRV_PP_V2;
5798 newsrv->pp_opts |= SRV_PP_V2_SSL;
5799 newsrv->pp_opts |= SRV_PP_V2_SSL_CN;
5800 return 0;
5801}
Emeric Brunf9c5c472012-10-11 15:28:34 +02005802
Willy Tarreau732eac42015-07-09 11:40:25 +02005803/* parse the "sni" server keyword */
5804static int srv_parse_sni(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5805{
5806#ifndef SSL_CTRL_SET_TLSEXT_HOSTNAME
5807 memprintf(err, "'%s' : the current SSL library doesn't support the SNI TLS extension", args[*cur_arg]);
5808 return ERR_ALERT | ERR_FATAL;
5809#else
Cyril Bonté23d19d62016-03-07 22:13:22 +01005810 int idx;
Willy Tarreau732eac42015-07-09 11:40:25 +02005811 struct sample_expr *expr;
5812
5813 if (!*args[*cur_arg + 1]) {
5814 memprintf(err, "'%s' : missing sni expression", args[*cur_arg]);
5815 return ERR_ALERT | ERR_FATAL;
5816 }
5817
Cyril Bonté23d19d62016-03-07 22:13:22 +01005818 idx = (*cur_arg) + 1;
Willy Tarreau732eac42015-07-09 11:40:25 +02005819 proxy->conf.args.ctx = ARGC_SRV;
5820
Cyril Bonté23d19d62016-03-07 22:13:22 +01005821 expr = sample_parse_expr((char **)args, &idx, px->conf.file, px->conf.line, err, &proxy->conf.args);
Willy Tarreau732eac42015-07-09 11:40:25 +02005822 if (!expr) {
5823 memprintf(err, "error detected while parsing sni expression : %s", *err);
5824 return ERR_ALERT | ERR_FATAL;
5825 }
5826
5827 if (!(expr->fetch->val & SMP_VAL_BE_SRV_CON)) {
5828 memprintf(err, "error detected while parsing sni expression : "
5829 " fetch method '%s' extracts information from '%s', none of which is available here.\n",
Cyril Bonté23d19d62016-03-07 22:13:22 +01005830 args[idx-1], sample_src_names(expr->fetch->use));
Willy Tarreau732eac42015-07-09 11:40:25 +02005831 return ERR_ALERT | ERR_FATAL;
5832 }
5833
5834 px->http_needed |= !!(expr->fetch->use & SMP_USE_HTTP_ANY);
5835 newsrv->ssl_ctx.sni = expr;
5836 return 0;
5837#endif
5838}
5839
Willy Tarreau92faadf2012-10-10 23:04:25 +02005840/* parse the "ssl" server keyword */
5841static int srv_parse_ssl(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5842{
5843 newsrv->use_ssl = 1;
5844 if (global.connect_default_ciphers && !newsrv->ssl_ctx.ciphers)
5845 newsrv->ssl_ctx.ciphers = strdup(global.connect_default_ciphers);
5846 return 0;
5847}
5848
Emeric Brunef42d922012-10-11 16:11:36 +02005849/* parse the "verify" server keyword */
5850static int srv_parse_verify(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5851{
5852 if (!*args[*cur_arg + 1]) {
5853 if (err)
5854 memprintf(err, "'%s' : missing verify method", args[*cur_arg]);
5855 return ERR_ALERT | ERR_FATAL;
5856 }
5857
5858 if (strcmp(args[*cur_arg + 1], "none") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01005859 newsrv->ssl_ctx.verify = SSL_SOCK_VERIFY_NONE;
Emeric Brunef42d922012-10-11 16:11:36 +02005860 else if (strcmp(args[*cur_arg + 1], "required") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01005861 newsrv->ssl_ctx.verify = SSL_SOCK_VERIFY_REQUIRED;
Emeric Brunef42d922012-10-11 16:11:36 +02005862 else {
5863 if (err)
5864 memprintf(err, "'%s' : unknown verify method '%s', only 'none' and 'required' are supported\n",
5865 args[*cur_arg], args[*cur_arg + 1]);
5866 return ERR_ALERT | ERR_FATAL;
5867 }
5868
Evan Broderbe554312013-06-27 00:05:25 -07005869 return 0;
5870}
5871
5872/* parse the "verifyhost" server keyword */
5873static int srv_parse_verifyhost(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5874{
5875 if (!*args[*cur_arg + 1]) {
5876 if (err)
5877 memprintf(err, "'%s' : missing hostname to verify against", args[*cur_arg]);
5878 return ERR_ALERT | ERR_FATAL;
5879 }
5880
5881 newsrv->ssl_ctx.verify_host = strdup(args[*cur_arg + 1]);
5882
Emeric Brunef42d922012-10-11 16:11:36 +02005883 return 0;
5884}
5885
Emeric Brun2c86cbf2014-10-30 15:56:50 +01005886/* parse the "ssl-default-bind-options" keyword in global section */
5887static int ssl_parse_default_bind_options(char **args, int section_type, struct proxy *curpx,
5888 struct proxy *defpx, const char *file, int line,
5889 char **err) {
5890 int i = 1;
5891
5892 if (*(args[i]) == 0) {
5893 memprintf(err, "global statement '%s' expects an option as an argument.", args[0]);
5894 return -1;
5895 }
5896 while (*(args[i])) {
5897 if (!strcmp(args[i], "no-sslv3"))
5898 global.listen_default_ssloptions |= BC_SSL_O_NO_SSLV3;
5899 else if (!strcmp(args[i], "no-tlsv10"))
5900 global.listen_default_ssloptions |= BC_SSL_O_NO_TLSV10;
5901 else if (!strcmp(args[i], "no-tlsv11"))
5902 global.listen_default_ssloptions |= BC_SSL_O_NO_TLSV11;
5903 else if (!strcmp(args[i], "no-tlsv12"))
5904 global.listen_default_ssloptions |= BC_SSL_O_NO_TLSV12;
5905 else if (!strcmp(args[i], "force-sslv3"))
5906 global.listen_default_ssloptions |= BC_SSL_O_USE_SSLV3;
5907 else if (!strcmp(args[i], "force-tlsv10"))
5908 global.listen_default_ssloptions |= BC_SSL_O_USE_TLSV10;
5909 else if (!strcmp(args[i], "force-tlsv11")) {
5910#if SSL_OP_NO_TLSv1_1
5911 global.listen_default_ssloptions |= BC_SSL_O_USE_TLSV11;
5912#else
5913 memprintf(err, "'%s' '%s': library does not support protocol TLSv1.1", args[0], args[i]);
5914 return -1;
5915#endif
5916 }
5917 else if (!strcmp(args[i], "force-tlsv12")) {
5918#if SSL_OP_NO_TLSv1_2
5919 global.listen_default_ssloptions |= BC_SSL_O_USE_TLSV12;
5920#else
5921 memprintf(err, "'%s' '%s': library does not support protocol TLSv1.2", args[0], args[i]);
5922 return -1;
5923#endif
5924 }
5925 else if (!strcmp(args[i], "no-tls-tickets"))
5926 global.listen_default_ssloptions |= BC_SSL_O_NO_TLS_TICKETS;
5927 else {
5928 memprintf(err, "unknown option '%s' on global statement '%s'.", args[i], args[0]);
5929 return -1;
5930 }
5931 i++;
5932 }
5933 return 0;
5934}
5935
5936/* parse the "ssl-default-server-options" keyword in global section */
5937static int ssl_parse_default_server_options(char **args, int section_type, struct proxy *curpx,
5938 struct proxy *defpx, const char *file, int line,
5939 char **err) {
5940 int i = 1;
5941
5942 if (*(args[i]) == 0) {
5943 memprintf(err, "global statement '%s' expects an option as an argument.", args[0]);
5944 return -1;
5945 }
5946 while (*(args[i])) {
5947 if (!strcmp(args[i], "no-sslv3"))
5948 global.connect_default_ssloptions |= SRV_SSL_O_NO_SSLV3;
5949 else if (!strcmp(args[i], "no-tlsv10"))
5950 global.connect_default_ssloptions |= SRV_SSL_O_NO_TLSV10;
5951 else if (!strcmp(args[i], "no-tlsv11"))
5952 global.connect_default_ssloptions |= SRV_SSL_O_NO_TLSV11;
5953 else if (!strcmp(args[i], "no-tlsv12"))
5954 global.connect_default_ssloptions |= SRV_SSL_O_NO_TLSV12;
5955 else if (!strcmp(args[i], "force-sslv3"))
5956 global.connect_default_ssloptions |= SRV_SSL_O_USE_SSLV3;
5957 else if (!strcmp(args[i], "force-tlsv10"))
5958 global.connect_default_ssloptions |= SRV_SSL_O_USE_TLSV10;
5959 else if (!strcmp(args[i], "force-tlsv11")) {
5960#if SSL_OP_NO_TLSv1_1
5961 global.connect_default_ssloptions |= SRV_SSL_O_USE_TLSV11;
5962#else
5963 memprintf(err, "'%s' '%s': library does not support protocol TLSv1.1", args[0], args[i]);
5964 return -1;
5965#endif
5966 }
5967 else if (!strcmp(args[i], "force-tlsv12")) {
5968#if SSL_OP_NO_TLSv1_2
5969 global.connect_default_ssloptions |= SRV_SSL_O_USE_TLSV12;
5970#else
5971 memprintf(err, "'%s' '%s': library does not support protocol TLSv1.2", args[0], args[i]);
5972 return -1;
5973#endif
5974 }
5975 else if (!strcmp(args[i], "no-tls-tickets"))
5976 global.connect_default_ssloptions |= SRV_SSL_O_NO_TLS_TICKETS;
5977 else {
5978 memprintf(err, "unknown option '%s' on global statement '%s'.", args[i], args[0]);
5979 return -1;
5980 }
5981 i++;
5982 }
5983 return 0;
5984}
5985
Willy Tarreau8c3b0fd2016-12-21 22:44:46 +01005986/* parse the "ca-base" / "crt-base" keywords in global section.
5987 * Returns <0 on alert, >0 on warning, 0 on success.
5988 */
5989static int ssl_parse_global_ca_crt_base(char **args, int section_type, struct proxy *curpx,
5990 struct proxy *defpx, const char *file, int line,
5991 char **err)
5992{
5993 char **target;
5994
5995 target = (args[0][1] == 'a') ? &global.ca_base : &global.crt_base;
5996
5997 if (too_many_args(1, args, err, NULL))
5998 return -1;
5999
6000 if (*target) {
6001 memprintf(err, "'%s' already specified.", args[0]);
6002 return -1;
6003 }
6004
6005 if (*(args[1]) == 0) {
6006 memprintf(err, "global statement '%s' expects a directory path as an argument.", args[0]);
6007 return -1;
6008 }
6009 *target = strdup(args[1]);
6010 return 0;
6011}
6012
Willy Tarreauf22e9682016-12-21 23:23:19 +01006013/* parse the "ssl-default-bind-ciphers" / "ssl-default-server-ciphers" keywords
6014 * in global section. Returns <0 on alert, >0 on warning, 0 on success.
6015 */
6016static int ssl_parse_global_ciphers(char **args, int section_type, struct proxy *curpx,
6017 struct proxy *defpx, const char *file, int line,
6018 char **err)
6019{
6020 char **target;
6021
6022 target = (args[0][12] == 'b') ? &global.listen_default_ciphers : &global.connect_default_ciphers;
6023
6024 if (too_many_args(1, args, err, NULL))
6025 return -1;
6026
6027 if (*(args[1]) == 0) {
6028 memprintf(err, "global statement '%s' expects a cipher suite as an argument.", args[0]);
6029 return -1;
6030 }
6031
6032 free(*target);
6033 *target = strdup(args[1]);
6034 return 0;
6035}
6036
Willy Tarreau9ceda382016-12-21 23:13:03 +01006037/* parse various global tune.ssl settings consisting in positive integers.
6038 * Returns <0 on alert, >0 on warning, 0 on success.
6039 */
6040static int ssl_parse_global_int(char **args, int section_type, struct proxy *curpx,
6041 struct proxy *defpx, const char *file, int line,
6042 char **err)
6043{
6044 int *target;
6045
6046 if (strcmp(args[0], "tune.ssl.cachesize") == 0)
6047 target = &global.tune.sslcachesize;
6048 else if (strcmp(args[0], "tune.ssl.maxrecord") == 0)
6049 target = (int *)&global.tune.ssl_max_record;
6050 else if (strcmp(args[0], "tune.ssl.ssl-ctx-cache-size") == 0)
6051 target = &global.tune.ssl_ctx_cache;
Willy Tarreau0bea58d2016-12-21 23:17:25 +01006052 else if (strcmp(args[0], "maxsslconn") == 0)
6053 target = &global.maxsslconn;
Willy Tarreau9ceda382016-12-21 23:13:03 +01006054 else {
6055 memprintf(err, "'%s' keyword not unhandled (please report this bug).", args[0]);
6056 return -1;
6057 }
6058
6059 if (too_many_args(1, args, err, NULL))
6060 return -1;
6061
6062 if (*(args[1]) == 0) {
6063 memprintf(err, "'%s' expects an integer argument.", args[0]);
6064 return -1;
6065 }
6066
6067 *target = atoi(args[1]);
6068 if (*target < 0) {
6069 memprintf(err, "'%s' expects a positive numeric value.", args[0]);
6070 return -1;
6071 }
6072 return 0;
6073}
6074
6075/* parse "ssl.force-private-cache".
6076 * Returns <0 on alert, >0 on warning, 0 on success.
6077 */
6078static int ssl_parse_global_private_cache(char **args, int section_type, struct proxy *curpx,
6079 struct proxy *defpx, const char *file, int line,
6080 char **err)
6081{
6082 if (too_many_args(0, args, err, NULL))
6083 return -1;
6084
6085 global.tune.sslprivatecache = 1;
6086 return 0;
6087}
6088
6089/* parse "ssl.lifetime".
6090 * Returns <0 on alert, >0 on warning, 0 on success.
6091 */
6092static int ssl_parse_global_lifetime(char **args, int section_type, struct proxy *curpx,
6093 struct proxy *defpx, const char *file, int line,
6094 char **err)
6095{
6096 const char *res;
6097
6098 if (too_many_args(1, args, err, NULL))
6099 return -1;
6100
6101 if (*(args[1]) == 0) {
6102 memprintf(err, "'%s' expects ssl sessions <lifetime> in seconds as argument.", args[0]);
6103 return -1;
6104 }
6105
6106 res = parse_time_err(args[1], &global.tune.ssllifetime, TIME_UNIT_S);
6107 if (res) {
6108 memprintf(err, "unexpected character '%c' in argument to <%s>.", *res, args[0]);
6109 return -1;
6110 }
6111 return 0;
6112}
6113
6114#ifndef OPENSSL_NO_DH
Willy Tarreau14e36a12016-12-21 23:28:13 +01006115/* parse "ssl-dh-param-file".
6116 * Returns <0 on alert, >0 on warning, 0 on success.
6117 */
6118static int ssl_parse_global_dh_param_file(char **args, int section_type, struct proxy *curpx,
6119 struct proxy *defpx, const char *file, int line,
6120 char **err)
6121{
6122 if (too_many_args(1, args, err, NULL))
6123 return -1;
6124
6125 if (*(args[1]) == 0) {
6126 memprintf(err, "'%s' expects a file path as an argument.", args[0]);
6127 return -1;
6128 }
6129
6130 if (ssl_sock_load_global_dh_param_from_file(args[1])) {
6131 memprintf(err, "'%s': unable to load DH parameters from file <%s>.", args[0], args[1]);
6132 return -1;
6133 }
6134 return 0;
6135}
6136
Willy Tarreau9ceda382016-12-21 23:13:03 +01006137/* parse "ssl.default-dh-param".
6138 * Returns <0 on alert, >0 on warning, 0 on success.
6139 */
6140static int ssl_parse_global_default_dh(char **args, int section_type, struct proxy *curpx,
6141 struct proxy *defpx, const char *file, int line,
6142 char **err)
6143{
6144 if (too_many_args(1, args, err, NULL))
6145 return -1;
6146
6147 if (*(args[1]) == 0) {
6148 memprintf(err, "'%s' expects an integer argument.", args[0]);
6149 return -1;
6150 }
6151
6152 global.tune.ssl_default_dh_param = atoi(args[1]);
6153 if (global.tune.ssl_default_dh_param < 1024) {
6154 memprintf(err, "'%s' expects a value >= 1024.", args[0]);
6155 return -1;
6156 }
6157 return 0;
6158}
6159#endif
6160
6161
William Lallemand32af2032016-10-29 18:09:35 +02006162/* This function is used with TLS ticket keys management. It permits to browse
6163 * each reference. The variable <getnext> must contain the current node,
6164 * <end> point to the root node.
6165 */
6166#if (defined SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB && TLS_TICKETS_NO > 0)
6167static inline
6168struct tls_keys_ref *tlskeys_list_get_next(struct tls_keys_ref *getnext, struct list *end)
6169{
6170 struct tls_keys_ref *ref = getnext;
6171
6172 while (1) {
6173
6174 /* Get next list entry. */
6175 ref = LIST_NEXT(&ref->list, struct tls_keys_ref *, list);
6176
6177 /* If the entry is the last of the list, return NULL. */
6178 if (&ref->list == end)
6179 return NULL;
6180
6181 return ref;
6182 }
6183}
6184
6185static inline
6186struct tls_keys_ref *tlskeys_ref_lookup_ref(const char *reference)
6187{
6188 int id;
6189 char *error;
6190
6191 /* If the reference starts by a '#', this is numeric id. */
6192 if (reference[0] == '#') {
6193 /* Try to convert the numeric id. If the conversion fails, the lookup fails. */
6194 id = strtol(reference + 1, &error, 10);
6195 if (*error != '\0')
6196 return NULL;
6197
6198 /* Perform the unique id lookup. */
6199 return tlskeys_ref_lookupid(id);
6200 }
6201
6202 /* Perform the string lookup. */
6203 return tlskeys_ref_lookup(reference);
6204}
6205#endif
6206
6207
6208#if (defined SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB && TLS_TICKETS_NO > 0)
6209
6210static int cli_io_handler_tlskeys_files(struct appctx *appctx);
6211
6212static inline int cli_io_handler_tlskeys_entries(struct appctx *appctx) {
6213 return cli_io_handler_tlskeys_files(appctx);
6214}
6215
Willy Tarreauf5f26e82016-12-16 18:47:27 +01006216/* dumps all tls keys. Relies on cli.i0 (non-null = only list file names), cli.i1
6217 * (next index to be dumped), and cli.p0 (next key reference).
6218 */
William Lallemand32af2032016-10-29 18:09:35 +02006219static int cli_io_handler_tlskeys_files(struct appctx *appctx) {
6220
6221 struct stream_interface *si = appctx->owner;
6222
6223 switch (appctx->st2) {
6224 case STAT_ST_INIT:
6225 /* Display the column headers. If the message cannot be sent,
6226 * quit the fucntion with returning 0. The function is called
6227 * later and restart at the state "STAT_ST_INIT".
6228 */
6229 chunk_reset(&trash);
6230
6231 if (appctx->io_handler == cli_io_handler_tlskeys_entries)
6232 chunk_appendf(&trash, "# id secret\n");
6233 else
6234 chunk_appendf(&trash, "# id (file)\n");
6235
6236 if (bi_putchk(si_ic(si), &trash) == -1) {
6237 si_applet_cant_put(si);
6238 return 0;
6239 }
6240
William Lallemand32af2032016-10-29 18:09:35 +02006241 /* Now, we start the browsing of the references lists.
6242 * Note that the following call to LIST_ELEM return bad pointer. The only
6243 * available field of this pointer is <list>. It is used with the function
6244 * tlskeys_list_get_next() for retruning the first available entry
6245 */
Willy Tarreauf5f26e82016-12-16 18:47:27 +01006246 if (appctx->ctx.cli.p0 == NULL) {
6247 appctx->ctx.cli.p0 = LIST_ELEM(&tlskeys_reference, struct tls_keys_ref *, list);
6248 appctx->ctx.cli.p0 = tlskeys_list_get_next(appctx->ctx.cli.p0, &tlskeys_reference);
William Lallemand32af2032016-10-29 18:09:35 +02006249 }
6250
6251 appctx->st2 = STAT_ST_LIST;
6252 /* fall through */
6253
6254 case STAT_ST_LIST:
Willy Tarreauf5f26e82016-12-16 18:47:27 +01006255 while (appctx->ctx.cli.p0) {
6256 struct tls_keys_ref *ref = appctx->ctx.cli.p0;
6257 int head = ref->tls_ticket_enc_index;
William Lallemand32af2032016-10-29 18:09:35 +02006258
6259 chunk_reset(&trash);
Willy Tarreauf5f26e82016-12-16 18:47:27 +01006260 if (appctx->io_handler == cli_io_handler_tlskeys_entries && appctx->ctx.cli.i1 == 0)
William Lallemand32af2032016-10-29 18:09:35 +02006261 chunk_appendf(&trash, "# ");
Willy Tarreauf5f26e82016-12-16 18:47:27 +01006262
6263 if (appctx->ctx.cli.i1 == 0)
6264 chunk_appendf(&trash, "%d (%s)\n", ref->unique_id, ref->filename);
6265
William Lallemand32af2032016-10-29 18:09:35 +02006266 if (appctx->io_handler == cli_io_handler_tlskeys_entries) {
Willy Tarreauf5f26e82016-12-16 18:47:27 +01006267 while (appctx->ctx.cli.i1 < TLS_TICKETS_NO) {
William Lallemand32af2032016-10-29 18:09:35 +02006268 struct chunk *t2 = get_trash_chunk();
6269
6270 chunk_reset(t2);
6271 /* should never fail here because we dump only a key in the t2 buffer */
Willy Tarreauf5f26e82016-12-16 18:47:27 +01006272 t2->len = a2base64((char *)(ref->tlskeys + (head + 2 + appctx->ctx.cli.i1) % TLS_TICKETS_NO),
William Lallemand32af2032016-10-29 18:09:35 +02006273 sizeof(struct tls_sess_key), t2->str, t2->size);
Willy Tarreauf5f26e82016-12-16 18:47:27 +01006274 chunk_appendf(&trash, "%d.%d %s\n", ref->unique_id, appctx->ctx.cli.i1, t2->str);
William Lallemand32af2032016-10-29 18:09:35 +02006275
6276 if (bi_putchk(si_ic(si), &trash) == -1) {
6277 /* let's try again later from this stream. We add ourselves into
6278 * this stream's users so that it can remove us upon termination.
6279 */
6280 si_applet_cant_put(si);
6281 return 0;
6282 }
Willy Tarreauf5f26e82016-12-16 18:47:27 +01006283 appctx->ctx.cli.i1++;
William Lallemand32af2032016-10-29 18:09:35 +02006284 }
Willy Tarreauf5f26e82016-12-16 18:47:27 +01006285 appctx->ctx.cli.i1 = 0;
William Lallemand32af2032016-10-29 18:09:35 +02006286 }
6287 if (bi_putchk(si_ic(si), &trash) == -1) {
6288 /* let's try again later from this stream. We add ourselves into
6289 * this stream's users so that it can remove us upon termination.
6290 */
6291 si_applet_cant_put(si);
6292 return 0;
6293 }
6294
Willy Tarreauf5f26e82016-12-16 18:47:27 +01006295 if (appctx->ctx.cli.i0 == 0) /* don't display everything if not necessary */
William Lallemand32af2032016-10-29 18:09:35 +02006296 break;
6297
6298 /* get next list entry and check the end of the list */
Willy Tarreauf5f26e82016-12-16 18:47:27 +01006299 appctx->ctx.cli.p0 = tlskeys_list_get_next(appctx->ctx.cli.p0, &tlskeys_reference);
William Lallemand32af2032016-10-29 18:09:35 +02006300 }
6301
6302 appctx->st2 = STAT_ST_FIN;
6303 /* fall through */
6304
6305 default:
6306 appctx->st2 = STAT_ST_FIN;
6307 return 1;
6308 }
6309 return 0;
6310}
6311
6312#endif
6313
Willy Tarreauf5f26e82016-12-16 18:47:27 +01006314/* sets cli.i0 to non-zero if only file lists should be dumped */
William Lallemand32af2032016-10-29 18:09:35 +02006315static int cli_parse_show_tlskeys(char **args, struct appctx *appctx, void *private)
6316{
William Lallemand32af2032016-10-29 18:09:35 +02006317 /* no parameter, shows only file list */
6318 if (!*args[2]) {
Willy Tarreauf5f26e82016-12-16 18:47:27 +01006319 appctx->ctx.cli.i0 = 1;
William Lallemand32af2032016-10-29 18:09:35 +02006320 appctx->io_handler = cli_io_handler_tlskeys_files;
Willy Tarreau3067bfa2016-12-05 14:50:15 +01006321 return 0;
William Lallemand32af2032016-10-29 18:09:35 +02006322 }
6323
6324 if (args[2][0] == '*') {
6325 /* list every TLS ticket keys */
Willy Tarreauf5f26e82016-12-16 18:47:27 +01006326 appctx->ctx.cli.i0 = 1;
William Lallemand32af2032016-10-29 18:09:35 +02006327 } else {
Willy Tarreauf5f26e82016-12-16 18:47:27 +01006328 appctx->ctx.cli.p0 = tlskeys_ref_lookup_ref(args[2]);
6329 if (!appctx->ctx.cli.p0) {
William Lallemand32af2032016-10-29 18:09:35 +02006330 appctx->ctx.cli.msg = "'show tls-keys' unable to locate referenced filename\n";
Willy Tarreau3b6e5472016-11-24 15:53:53 +01006331 appctx->st0 = CLI_ST_PRINT;
William Lallemand32af2032016-10-29 18:09:35 +02006332 return 1;
6333 }
6334 }
William Lallemand32af2032016-10-29 18:09:35 +02006335 appctx->io_handler = cli_io_handler_tlskeys_entries;
Willy Tarreau3067bfa2016-12-05 14:50:15 +01006336 return 0;
William Lallemand32af2032016-10-29 18:09:35 +02006337}
6338
6339
6340static int cli_parse_set_tlskeys(char **args, struct appctx *appctx, void *private)
6341{
Willy Tarreauf5f26e82016-12-16 18:47:27 +01006342 struct tls_keys_ref *ref;
6343
William Lallemand32af2032016-10-29 18:09:35 +02006344 /* Expect two parameters: the filename and the new new TLS key in encoding */
6345 if (!*args[3] || !*args[4]) {
6346 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 +01006347 appctx->st0 = CLI_ST_PRINT;
William Lallemand32af2032016-10-29 18:09:35 +02006348 return 1;
6349 }
6350
Willy Tarreauf5f26e82016-12-16 18:47:27 +01006351 ref = tlskeys_ref_lookup_ref(args[3]);
6352 if (!ref) {
William Lallemand32af2032016-10-29 18:09:35 +02006353 appctx->ctx.cli.msg = "'set ssl tls-key' unable to locate referenced filename\n";
Willy Tarreau3b6e5472016-11-24 15:53:53 +01006354 appctx->st0 = CLI_ST_PRINT;
William Lallemand32af2032016-10-29 18:09:35 +02006355 return 1;
6356 }
6357
6358 trash.len = base64dec(args[4], strlen(args[4]), trash.str, trash.size);
6359 if (trash.len != sizeof(struct tls_sess_key)) {
6360 appctx->ctx.cli.msg = "'set ssl tls-key' received invalid base64 encoded TLS key.\n";
Willy Tarreau3b6e5472016-11-24 15:53:53 +01006361 appctx->st0 = CLI_ST_PRINT;
William Lallemand32af2032016-10-29 18:09:35 +02006362 return 1;
6363 }
6364
Willy Tarreauf5f26e82016-12-16 18:47:27 +01006365 memcpy(ref->tlskeys + ((ref->tls_ticket_enc_index + 2) % TLS_TICKETS_NO), trash.str, trash.len);
6366 ref->tls_ticket_enc_index = (ref->tls_ticket_enc_index + 1) % TLS_TICKETS_NO;
William Lallemand32af2032016-10-29 18:09:35 +02006367
6368 appctx->ctx.cli.msg = "TLS ticket key updated!";
Willy Tarreau3b6e5472016-11-24 15:53:53 +01006369 appctx->st0 = CLI_ST_PRINT;
William Lallemand32af2032016-10-29 18:09:35 +02006370 return 1;
6371
6372}
6373
6374static int cli_parse_set_ocspresponse(char **args, struct appctx *appctx, void *private)
6375{
6376#if (defined SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB && !defined OPENSSL_NO_OCSP)
6377 char *err = NULL;
6378
6379 /* Expect one parameter: the new response in base64 encoding */
6380 if (!*args[3]) {
6381 appctx->ctx.cli.msg = "'set ssl ocsp-response' expects response in base64 encoding.\n";
Willy Tarreau3b6e5472016-11-24 15:53:53 +01006382 appctx->st0 = CLI_ST_PRINT;
William Lallemand32af2032016-10-29 18:09:35 +02006383 return 1;
6384 }
6385
6386 trash.len = base64dec(args[3], strlen(args[3]), trash.str, trash.size);
6387 if (trash.len < 0) {
6388 appctx->ctx.cli.msg = "'set ssl ocsp-response' received invalid base64 encoded response.\n";
Willy Tarreau3b6e5472016-11-24 15:53:53 +01006389 appctx->st0 = CLI_ST_PRINT;
William Lallemand32af2032016-10-29 18:09:35 +02006390 return 1;
6391 }
6392
6393 if (ssl_sock_update_ocsp_response(&trash, &err)) {
6394 if (err) {
6395 memprintf(&err, "%s.\n", err);
6396 appctx->ctx.cli.err = err;
Willy Tarreau3b6e5472016-11-24 15:53:53 +01006397 appctx->st0 = CLI_ST_PRINT_FREE;
William Lallemand32af2032016-10-29 18:09:35 +02006398 }
6399 return 1;
6400 }
6401 appctx->ctx.cli.msg = "OCSP Response updated!";
Willy Tarreau3b6e5472016-11-24 15:53:53 +01006402 appctx->st0 = CLI_ST_PRINT;
William Lallemand32af2032016-10-29 18:09:35 +02006403 return 1;
6404#else
6405 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 +01006406 appctx->st0 = CLI_ST_PRINT;
William Lallemand32af2032016-10-29 18:09:35 +02006407 return 1;
6408#endif
6409
6410}
6411
6412/* register cli keywords */
6413static struct cli_kw_list cli_kws = {{ },{
6414#if (defined SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB && TLS_TICKETS_NO > 0)
6415 { { "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 },
6416 { { "set", "ssl", "tls-keys", NULL }, NULL, cli_parse_set_tlskeys, NULL },
6417 { { "set", "ssl", "ocsp-response", NULL }, NULL, cli_parse_set_ocspresponse, NULL },
6418#endif
6419 { { NULL }, NULL, NULL, NULL }
6420}};
6421
6422
6423
Willy Tarreau7875d092012-09-10 08:20:03 +02006424/* Note: must not be declared <const> as its list will be overwritten.
6425 * Please take care of keeping this list alphabetically sorted.
6426 */
Willy Tarreaudc13c112013-06-21 23:16:39 +02006427static struct sample_fetch_kw_list sample_fetch_keywords = {ILH, {
Emeric Brun645ae792014-04-30 14:21:06 +02006428 { "ssl_bc", smp_fetch_ssl_fc, 0, NULL, SMP_T_BOOL, SMP_USE_L5SRV },
Thierry FOURNIER07ee64e2015-07-06 23:43:03 +02006429 { "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 +02006430 { "ssl_bc_cipher", smp_fetch_ssl_fc_cipher, 0, NULL, SMP_T_STR, SMP_USE_L5SRV },
6431 { "ssl_bc_protocol", smp_fetch_ssl_fc_protocol, 0, NULL, SMP_T_STR, SMP_USE_L5SRV },
Emeric Brunb73a9b02014-04-30 18:49:19 +02006432 { "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 +02006433 { "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 +02006434 { "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 +02006435 { "ssl_c_ca_err", smp_fetch_ssl_c_ca_err, 0, NULL, SMP_T_SINT, SMP_USE_L5CLI },
6436 { "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 +01006437 { "ssl_c_der", smp_fetch_ssl_x_der, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Thierry FOURNIER07ee64e2015-07-06 23:43:03 +02006438 { "ssl_c_err", smp_fetch_ssl_c_err, 0, NULL, SMP_T_SINT, SMP_USE_L5CLI },
Emeric Brunba841a12014-04-30 17:05:08 +02006439 { "ssl_c_i_dn", smp_fetch_ssl_x_i_dn, ARG2(0,STR,SINT), NULL, SMP_T_STR, SMP_USE_L5CLI },
6440 { "ssl_c_key_alg", smp_fetch_ssl_x_key_alg, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
6441 { "ssl_c_notafter", smp_fetch_ssl_x_notafter, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
6442 { "ssl_c_notbefore", smp_fetch_ssl_x_notbefore, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
6443 { "ssl_c_sig_alg", smp_fetch_ssl_x_sig_alg, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
6444 { "ssl_c_s_dn", smp_fetch_ssl_x_s_dn, ARG2(0,STR,SINT), NULL, SMP_T_STR, SMP_USE_L5CLI },
6445 { "ssl_c_serial", smp_fetch_ssl_x_serial, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
6446 { "ssl_c_sha1", smp_fetch_ssl_x_sha1, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Willy Tarreau80aca902013-01-07 15:42:20 +01006447 { "ssl_c_used", smp_fetch_ssl_c_used, 0, NULL, SMP_T_BOOL, SMP_USE_L5CLI },
Thierry FOURNIER07ee64e2015-07-06 23:43:03 +02006448 { "ssl_c_verify", smp_fetch_ssl_c_verify, 0, NULL, SMP_T_SINT, SMP_USE_L5CLI },
6449 { "ssl_c_version", smp_fetch_ssl_x_version, 0, NULL, SMP_T_SINT, SMP_USE_L5CLI },
Emeric Brun43e79582014-10-29 19:03:26 +01006450 { "ssl_f_der", smp_fetch_ssl_x_der, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Emeric Brunba841a12014-04-30 17:05:08 +02006451 { "ssl_f_i_dn", smp_fetch_ssl_x_i_dn, ARG2(0,STR,SINT), NULL, SMP_T_STR, SMP_USE_L5CLI },
6452 { "ssl_f_key_alg", smp_fetch_ssl_x_key_alg, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
6453 { "ssl_f_notafter", smp_fetch_ssl_x_notafter, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
6454 { "ssl_f_notbefore", smp_fetch_ssl_x_notbefore, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
6455 { "ssl_f_sig_alg", smp_fetch_ssl_x_sig_alg, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
6456 { "ssl_f_s_dn", smp_fetch_ssl_x_s_dn, ARG2(0,STR,SINT), NULL, SMP_T_STR, SMP_USE_L5CLI },
6457 { "ssl_f_serial", smp_fetch_ssl_x_serial, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Emeric Brun55f4fa82014-04-30 17:11:25 +02006458 { "ssl_f_sha1", smp_fetch_ssl_x_sha1, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Thierry FOURNIER07ee64e2015-07-06 23:43:03 +02006459 { "ssl_f_version", smp_fetch_ssl_x_version, 0, NULL, SMP_T_SINT, SMP_USE_L5CLI },
Willy Tarreau80aca902013-01-07 15:42:20 +01006460 { "ssl_fc", smp_fetch_ssl_fc, 0, NULL, SMP_T_BOOL, SMP_USE_L5CLI },
Thierry FOURNIER07ee64e2015-07-06 23:43:03 +02006461 { "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 +01006462 { "ssl_fc_cipher", smp_fetch_ssl_fc_cipher, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Willy Tarreau80aca902013-01-07 15:42:20 +01006463 { "ssl_fc_has_crt", smp_fetch_ssl_fc_has_crt, 0, NULL, SMP_T_BOOL, SMP_USE_L5CLI },
6464 { "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 +02006465 { "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 +02006466#ifdef OPENSSL_NPN_NEGOTIATED
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01006467 { "ssl_fc_npn", smp_fetch_ssl_fc_npn, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Willy Tarreaua33c6542012-10-15 13:19:06 +02006468#endif
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01006469#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01006470 { "ssl_fc_alpn", smp_fetch_ssl_fc_alpn, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Willy Tarreauab861d32013-04-02 02:30:41 +02006471#endif
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01006472 { "ssl_fc_protocol", smp_fetch_ssl_fc_protocol, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Emeric Brunb73a9b02014-04-30 18:49:19 +02006473 { "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 +02006474 { "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 +01006475 { "ssl_fc_session_id", smp_fetch_ssl_fc_session_id, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
6476 { "ssl_fc_sni", smp_fetch_ssl_fc_sni, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Willy Tarreau7875d092012-09-10 08:20:03 +02006477 { NULL, NULL, 0, 0, 0 },
6478}};
6479
6480/* Note: must not be declared <const> as its list will be overwritten.
6481 * Please take care of keeping this list alphabetically sorted.
6482 */
Willy Tarreaudc13c112013-06-21 23:16:39 +02006483static struct acl_kw_list acl_kws = {ILH, {
Thierry FOURNIERc5a4e982014-03-05 16:07:08 +01006484 { "ssl_fc_sni_end", "ssl_fc_sni", PAT_MATCH_END },
6485 { "ssl_fc_sni_reg", "ssl_fc_sni", PAT_MATCH_REG },
Willy Tarreau8ed669b2013-01-11 15:49:37 +01006486 { /* END */ },
Willy Tarreau7875d092012-09-10 08:20:03 +02006487}};
6488
Willy Tarreau79eeafa2012-09-14 07:53:05 +02006489/* Note: must not be declared <const> as its list will be overwritten.
6490 * Please take care of keeping this list alphabetically sorted, doing so helps
6491 * all code contributors.
6492 * Optional keywords are also declared with a NULL ->parse() function so that
6493 * the config parser can report an appropriate error when a known keyword was
6494 * not enabled.
6495 */
Willy Tarreau51fb7652012-09-18 18:24:39 +02006496static struct bind_kw_list bind_kws = { "SSL", { }, {
Nenad Merdanovic05552d42015-02-27 19:56:49 +01006497 { "alpn", bind_parse_alpn, 1 }, /* set ALPN supported protocols */
6498 { "ca-file", bind_parse_ca_file, 1 }, /* set CAfile to process verify on client cert */
6499 { "ca-ignore-err", bind_parse_ignore_err, 1 }, /* set error IDs to ignore on verify depth > 0 */
Christopher Faulet31af49d2015-06-09 17:29:50 +02006500 { "ca-sign-file", bind_parse_ca_sign_file, 1 }, /* set CAFile used to generate and sign server certs */
6501 { "ca-sign-pass", bind_parse_ca_sign_pass, 1 }, /* set CAKey passphrase */
Nenad Merdanovic05552d42015-02-27 19:56:49 +01006502 { "ciphers", bind_parse_ciphers, 1 }, /* set SSL cipher suite */
6503 { "crl-file", bind_parse_crl_file, 1 }, /* set certificat revocation list file use on client cert verify */
6504 { "crt", bind_parse_crt, 1 }, /* load SSL certificates from this location */
6505 { "crt-ignore-err", bind_parse_ignore_err, 1 }, /* set error IDs to ingore on verify depth == 0 */
6506 { "crt-list", bind_parse_crt_list, 1 }, /* load a list of crt from this location */
6507 { "ecdhe", bind_parse_ecdhe, 1 }, /* defines named curve for elliptic curve Diffie-Hellman */
6508 { "force-sslv3", bind_parse_force_sslv3, 0 }, /* force SSLv3 */
6509 { "force-tlsv10", bind_parse_force_tlsv10, 0 }, /* force TLSv10 */
6510 { "force-tlsv11", bind_parse_force_tlsv11, 0 }, /* force TLSv11 */
6511 { "force-tlsv12", bind_parse_force_tlsv12, 0 }, /* force TLSv12 */
Christopher Faulet31af49d2015-06-09 17:29:50 +02006512 { "generate-certificates", bind_parse_generate_certs, 0 }, /* enable the server certificates generation */
Nenad Merdanovic05552d42015-02-27 19:56:49 +01006513 { "no-sslv3", bind_parse_no_sslv3, 0 }, /* disable SSLv3 */
6514 { "no-tlsv10", bind_parse_no_tlsv10, 0 }, /* disable TLSv10 */
6515 { "no-tlsv11", bind_parse_no_tlsv11, 0 }, /* disable TLSv11 */
6516 { "no-tlsv12", bind_parse_no_tlsv12, 0 }, /* disable TLSv12 */
6517 { "no-tls-tickets", bind_parse_no_tls_tickets, 0 }, /* disable session resumption tickets */
6518 { "ssl", bind_parse_ssl, 0 }, /* enable SSL processing */
6519 { "strict-sni", bind_parse_strict_sni, 0 }, /* refuse negotiation if sni doesn't match a certificate */
6520 { "tls-ticket-keys", bind_parse_tls_ticket_keys, 1 }, /* set file to load TLS ticket keys from */
6521 { "verify", bind_parse_verify, 1 }, /* set SSL verify method */
6522 { "npn", bind_parse_npn, 1 }, /* set NPN supported protocols */
Willy Tarreau79eeafa2012-09-14 07:53:05 +02006523 { NULL, NULL, 0 },
6524}};
Emeric Brun46591952012-05-18 15:47:34 +02006525
Willy Tarreau92faadf2012-10-10 23:04:25 +02006526/* Note: must not be declared <const> as its list will be overwritten.
6527 * Please take care of keeping this list alphabetically sorted, doing so helps
6528 * all code contributors.
6529 * Optional keywords are also declared with a NULL ->parse() function so that
6530 * the config parser can report an appropriate error when a known keyword was
6531 * not enabled.
6532 */
6533static struct srv_kw_list srv_kws = { "SSL", { }, {
Emeric Brunef42d922012-10-11 16:11:36 +02006534 { "ca-file", srv_parse_ca_file, 1, 0 }, /* set CAfile to process verify server cert */
Emeric Brunecc91fe2012-10-11 15:05:10 +02006535 { "check-ssl", srv_parse_check_ssl, 0, 0 }, /* enable SSL for health checks */
6536 { "ciphers", srv_parse_ciphers, 1, 0 }, /* select the cipher suite */
Emeric Brunef42d922012-10-11 16:11:36 +02006537 { "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 +02006538 { "crt", srv_parse_crt, 1, 0 }, /* set client certificate */
Emeric Brunecc91fe2012-10-11 15:05:10 +02006539 { "force-sslv3", srv_parse_force_sslv3, 0, 0 }, /* force SSLv3 */
6540 { "force-tlsv10", srv_parse_force_tlsv10, 0, 0 }, /* force TLSv10 */
6541 { "force-tlsv11", srv_parse_force_tlsv11, 0, 0 }, /* force TLSv11 */
6542 { "force-tlsv12", srv_parse_force_tlsv12, 0, 0 }, /* force TLSv12 */
Willy Tarreau2a3fb1c2015-02-05 16:47:07 +01006543 { "no-ssl-reuse", srv_parse_no_ssl_reuse, 0, 0 }, /* disable session reuse */
Emeric Brunecc91fe2012-10-11 15:05:10 +02006544 { "no-sslv3", srv_parse_no_sslv3, 0, 0 }, /* disable SSLv3 */
6545 { "no-tlsv10", srv_parse_no_tlsv10, 0, 0 }, /* disable TLSv10 */
6546 { "no-tlsv11", srv_parse_no_tlsv11, 0, 0 }, /* disable TLSv11 */
6547 { "no-tlsv12", srv_parse_no_tlsv12, 0, 0 }, /* disable TLSv12 */
Emeric Brunf9c5c472012-10-11 15:28:34 +02006548 { "no-tls-tickets", srv_parse_no_tls_tickets, 0, 0 }, /* disable session resumption tickets */
David Safb76832014-05-08 23:42:08 -04006549 { "send-proxy-v2-ssl", srv_parse_send_proxy_ssl, 0, 0 }, /* send PROXY protocol header v2 with SSL info */
6550 { "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 +02006551 { "sni", srv_parse_sni, 1, 0 }, /* send SNI extension */
Emeric Brunecc91fe2012-10-11 15:05:10 +02006552 { "ssl", srv_parse_ssl, 0, 0 }, /* enable SSL processing */
Emeric Brunef42d922012-10-11 16:11:36 +02006553 { "verify", srv_parse_verify, 1, 0 }, /* set SSL verify method */
Evan Broderbe554312013-06-27 00:05:25 -07006554 { "verifyhost", srv_parse_verifyhost, 1, 0 }, /* require that SSL cert verifies for hostname */
Willy Tarreau92faadf2012-10-10 23:04:25 +02006555 { NULL, NULL, 0, 0 },
6556}};
6557
Emeric Brun2c86cbf2014-10-30 15:56:50 +01006558static struct cfg_kw_list cfg_kws = {ILH, {
Willy Tarreau8c3b0fd2016-12-21 22:44:46 +01006559 { CFG_GLOBAL, "ca-base", ssl_parse_global_ca_crt_base },
6560 { CFG_GLOBAL, "crt-base", ssl_parse_global_ca_crt_base },
Willy Tarreau0bea58d2016-12-21 23:17:25 +01006561 { CFG_GLOBAL, "maxsslconn", ssl_parse_global_int },
Emeric Brun2c86cbf2014-10-30 15:56:50 +01006562 { CFG_GLOBAL, "ssl-default-bind-options", ssl_parse_default_bind_options },
6563 { CFG_GLOBAL, "ssl-default-server-options", ssl_parse_default_server_options },
Willy Tarreau14e36a12016-12-21 23:28:13 +01006564#ifndef OPENSSL_NO_DH
6565 { CFG_GLOBAL, "ssl-dh-param-file", ssl_parse_global_dh_param_file },
6566#endif
Willy Tarreau9ceda382016-12-21 23:13:03 +01006567 { CFG_GLOBAL, "tune.ssl.cachesize", ssl_parse_global_int },
6568#ifndef OPENSSL_NO_DH
6569 { CFG_GLOBAL, "tune.ssl.default-dh-param", ssl_parse_global_default_dh },
6570#endif
6571 { CFG_GLOBAL, "tune.ssl.force-private-cache", ssl_parse_global_private_cache },
6572 { CFG_GLOBAL, "tune.ssl.lifetime", ssl_parse_global_lifetime },
6573 { CFG_GLOBAL, "tune.ssl.maxrecord", ssl_parse_global_int },
6574 { CFG_GLOBAL, "tune.ssl.ssl-ctx-cache-size", ssl_parse_global_int },
Willy Tarreauf22e9682016-12-21 23:23:19 +01006575 { CFG_GLOBAL, "ssl-default-bind-ciphers", ssl_parse_global_ciphers },
6576 { CFG_GLOBAL, "ssl-default-server-ciphers", ssl_parse_global_ciphers },
Emeric Brun2c86cbf2014-10-30 15:56:50 +01006577 { 0, NULL, NULL },
6578}};
6579
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02006580/* transport-layer operations for SSL sockets */
6581struct xprt_ops ssl_sock = {
Emeric Brun46591952012-05-18 15:47:34 +02006582 .snd_buf = ssl_sock_from_buf,
6583 .rcv_buf = ssl_sock_to_buf,
6584 .rcv_pipe = NULL,
6585 .snd_pipe = NULL,
6586 .shutr = NULL,
6587 .shutw = ssl_sock_shutw,
6588 .close = ssl_sock_close,
6589 .init = ssl_sock_init,
Willy Tarreau8e0bb0a2016-11-24 16:58:12 +01006590 .name = "SSL",
Emeric Brun46591952012-05-18 15:47:34 +02006591};
6592
Daniel Jakots54ffb912015-11-06 20:02:41 +01006593#if (OPENSSL_VERSION_NUMBER >= 0x1000200fL && !defined OPENSSL_NO_TLSEXT && !defined OPENSSL_IS_BORINGSSL && !defined LIBRESSL_VERSION_NUMBER)
Janusz Dziemidowicz2c701b52015-03-07 23:03:59 +01006594
6595static void ssl_sock_sctl_free_func(void *parent, void *ptr, CRYPTO_EX_DATA *ad, int idx, long argl, void *argp)
6596{
6597 if (ptr) {
6598 chunk_destroy(ptr);
6599 free(ptr);
6600 }
6601}
6602
6603#endif
6604
Emeric Brun46591952012-05-18 15:47:34 +02006605__attribute__((constructor))
Willy Tarreau92faadf2012-10-10 23:04:25 +02006606static void __ssl_sock_init(void)
6607{
Willy Tarreauc2c0b612016-12-21 19:23:20 +01006608 char *ptr;
6609
Emeric Brun46591952012-05-18 15:47:34 +02006610 STACK_OF(SSL_COMP)* cm;
6611
Willy Tarreau610f04b2014-02-13 11:36:41 +01006612#ifdef LISTEN_DEFAULT_CIPHERS
6613 global.listen_default_ciphers = LISTEN_DEFAULT_CIPHERS;
6614#endif
6615#ifdef CONNECT_DEFAULT_CIPHERS
6616 global.connect_default_ciphers = CONNECT_DEFAULT_CIPHERS;
6617#endif
6618 if (global.listen_default_ciphers)
6619 global.listen_default_ciphers = strdup(global.listen_default_ciphers);
6620 if (global.connect_default_ciphers)
6621 global.connect_default_ciphers = strdup(global.connect_default_ciphers);
Emeric Brun2c86cbf2014-10-30 15:56:50 +01006622 global.listen_default_ssloptions = BC_SSL_O_NONE;
6623 global.connect_default_ssloptions = SRV_SSL_O_NONE;
Willy Tarreau610f04b2014-02-13 11:36:41 +01006624
Emeric Brun46591952012-05-18 15:47:34 +02006625 SSL_library_init();
6626 cm = SSL_COMP_get_compression_methods();
6627 sk_SSL_COMP_zero(cm);
Daniel Jakots54ffb912015-11-06 20:02:41 +01006628#if (OPENSSL_VERSION_NUMBER >= 0x1000200fL && !defined OPENSSL_NO_TLSEXT && !defined OPENSSL_IS_BORINGSSL && !defined LIBRESSL_VERSION_NUMBER)
Janusz Dziemidowicz2c701b52015-03-07 23:03:59 +01006629 sctl_ex_index = SSL_CTX_get_ex_new_index(0, NULL, NULL, NULL, ssl_sock_sctl_free_func);
6630#endif
Willy Tarreau7875d092012-09-10 08:20:03 +02006631 sample_register_fetches(&sample_fetch_keywords);
6632 acl_register_keywords(&acl_kws);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02006633 bind_register_keywords(&bind_kws);
Willy Tarreau92faadf2012-10-10 23:04:25 +02006634 srv_register_keywords(&srv_kws);
Emeric Brun2c86cbf2014-10-30 15:56:50 +01006635 cfg_register_keywords(&cfg_kws);
William Lallemand32af2032016-10-29 18:09:35 +02006636 cli_register_kw(&cli_kws);
Willy Tarreaud92aa5c2015-01-15 21:34:39 +01006637
Willy Tarreauc2c0b612016-12-21 19:23:20 +01006638 ptr = NULL;
6639 memprintf(&ptr, "Built with OpenSSL version : "
6640#ifdef OPENSSL_IS_BORINGSSL
6641 "BoringSSL\n");
6642#else /* OPENSSL_IS_BORINGSSL */
6643 OPENSSL_VERSION_TEXT
6644 "\nRunning on OpenSSL version : %s%s",
6645 SSLeay_version(SSLEAY_VERSION),
6646 ((OPENSSL_VERSION_NUMBER ^ SSLeay()) >> 8) ? " (VERSIONS DIFFER!)" : "");
6647#endif
6648 memprintf(&ptr, "%s\nOpenSSL library supports TLS extensions : "
6649#if OPENSSL_VERSION_NUMBER < 0x00907000L
6650 "no (library version too old)"
6651#elif defined(OPENSSL_NO_TLSEXT)
6652 "no (disabled via OPENSSL_NO_TLSEXT)"
6653#else
6654 "yes"
6655#endif
6656 "", ptr);
6657
6658 memprintf(&ptr, "%s\nOpenSSL library supports SNI : "
6659#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
6660 "yes"
6661#else
6662#ifdef OPENSSL_NO_TLSEXT
6663 "no (because of OPENSSL_NO_TLSEXT)"
6664#else
6665 "no (version might be too old, 0.9.8f min needed)"
6666#endif
6667#endif
6668 "", ptr);
6669
6670 memprintf(&ptr, "%s\nOpenSSL library supports prefer-server-ciphers : "
6671#ifdef SSL_OP_CIPHER_SERVER_PREFERENCE
6672 "yes"
6673#else
6674 "no (0.9.7 or later needed)"
6675#endif
6676 "", ptr);
6677 hap_register_build_opts(ptr, 1);
6678
Willy Tarreaud92aa5c2015-01-15 21:34:39 +01006679 global.ssl_session_max_cost = SSL_SESSION_MAX_COST;
6680 global.ssl_handshake_max_cost = SSL_HANDSHAKE_MAX_COST;
Remi Gacogne4f902b82015-05-28 16:23:00 +02006681
6682#ifndef OPENSSL_NO_DH
6683 ssl_dh_ptr_index = SSL_CTX_get_ex_new_index(0, NULL, NULL, NULL, NULL);
6684#endif
Thierry FOURNIER / OZON.IO8b068c22016-10-10 11:59:50 +02006685
6686 /* Load SSL string for the verbose & debug mode. */
6687 ERR_load_SSL_strings();
Emeric Brun46591952012-05-18 15:47:34 +02006688}
6689
Remi Gacogned3a23c32015-05-28 16:39:47 +02006690__attribute__((destructor))
6691static void __ssl_sock_deinit(void)
6692{
Willy Tarreaua84c2672015-10-09 12:10:13 +02006693#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Christopher Faulet31af49d2015-06-09 17:29:50 +02006694 lru64_destroy(ssl_ctx_lru_tree);
Willy Tarreaua84c2672015-10-09 12:10:13 +02006695#endif
Christopher Faulet31af49d2015-06-09 17:29:50 +02006696
Remi Gacogned3a23c32015-05-28 16:39:47 +02006697#ifndef OPENSSL_NO_DH
6698 if (local_dh_1024) {
6699 DH_free(local_dh_1024);
6700 local_dh_1024 = NULL;
6701 }
6702
6703 if (local_dh_2048) {
6704 DH_free(local_dh_2048);
6705 local_dh_2048 = NULL;
6706 }
6707
6708 if (local_dh_4096) {
6709 DH_free(local_dh_4096);
6710 local_dh_4096 = NULL;
6711 }
6712
Remi Gacogne47783ef2015-05-29 15:53:22 +02006713 if (global_dh) {
6714 DH_free(global_dh);
6715 global_dh = NULL;
6716 }
Remi Gacogned3a23c32015-05-28 16:39:47 +02006717#endif
6718
6719 ERR_remove_state(0);
6720 ERR_free_strings();
6721
6722 EVP_cleanup();
6723
6724#if OPENSSL_VERSION_NUMBER >= 0x00907000L
6725 CRYPTO_cleanup_all_ex_data();
6726#endif
6727}
6728
6729
Emeric Brun46591952012-05-18 15:47:34 +02006730/*
6731 * Local variables:
6732 * c-indent-level: 8
6733 * c-basic-offset: 8
6734 * End:
6735 */