blob: f5d4920a9d003d31b011630217ec85b0cab6b8d4 [file] [log] [blame]
yanbzhu08ce6ab2015-12-02 13:01:29 -05001
Emeric Brun46591952012-05-18 15:47:34 +02002/*
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02003 * SSL/TLS transport layer over SOCK_STREAM sockets
Emeric Brun46591952012-05-18 15:47:34 +02004 *
5 * Copyright (C) 2012 EXCELIANCE, Emeric Brun <ebrun@exceliance.fr>
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation; either version
10 * 2 of the License, or (at your option) any later version.
11 *
Willy Tarreau69845df2012-09-10 09:43:09 +020012 * Acknowledgement:
13 * We'd like to specially thank the Stud project authors for a very clean
14 * and well documented code which helped us understand how the OpenSSL API
15 * ought to be used in non-blocking mode. This is one difficult part which
16 * is not easy to get from the OpenSSL doc, and reading the Stud code made
17 * it much more obvious than the examples in the OpenSSL package. Keep up
18 * the good works, guys !
19 *
20 * Stud is an extremely efficient and scalable SSL/TLS proxy which combines
21 * particularly well with haproxy. For more info about this project, visit :
22 * https://github.com/bumptech/stud
23 *
Emeric Brun46591952012-05-18 15:47:34 +020024 */
25
26#define _GNU_SOURCE
Emeric Brunfc0421f2012-09-07 17:30:07 +020027#include <ctype.h>
28#include <dirent.h>
Emeric Brun46591952012-05-18 15:47:34 +020029#include <errno.h>
30#include <fcntl.h>
31#include <stdio.h>
32#include <stdlib.h>
Emeric Brunfc0421f2012-09-07 17:30:07 +020033#include <string.h>
34#include <unistd.h>
Emeric Brun46591952012-05-18 15:47:34 +020035
36#include <sys/socket.h>
37#include <sys/stat.h>
38#include <sys/types.h>
Christopher Faulet31af49d2015-06-09 17:29:50 +020039#include <netdb.h>
Emeric Brun46591952012-05-18 15:47:34 +020040#include <netinet/tcp.h>
41
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +020042#include <openssl/crypto.h>
Emeric Brun46591952012-05-18 15:47:34 +020043#include <openssl/ssl.h>
Emeric Brunfc0421f2012-09-07 17:30:07 +020044#include <openssl/x509.h>
45#include <openssl/x509v3.h>
46#include <openssl/x509.h>
47#include <openssl/err.h>
Thierry Fournier383085f2013-01-24 14:15:43 +010048#include <openssl/rand.h>
Lukas Tribuse4e30f72014-12-09 16:32:51 +010049#if (defined SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB && !defined OPENSSL_NO_OCSP)
Emeric Brun4147b2e2014-06-16 18:36:30 +020050#include <openssl/ocsp.h>
51#endif
Remi Gacogne4f902b82015-05-28 16:23:00 +020052#ifndef OPENSSL_NO_DH
53#include <openssl/dh.h>
54#endif
Emeric Brun46591952012-05-18 15:47:34 +020055
Christopher Faulet31af49d2015-06-09 17:29:50 +020056#include <import/lru.h>
57#include <import/xxhash.h>
58
Emeric Brun46591952012-05-18 15:47:34 +020059#include <common/buffer.h>
60#include <common/compat.h>
61#include <common/config.h>
62#include <common/debug.h>
Willy Tarreau79eeafa2012-09-14 07:53:05 +020063#include <common/errors.h>
Emeric Brun46591952012-05-18 15:47:34 +020064#include <common/standard.h>
65#include <common/ticks.h>
66#include <common/time.h>
Emeric Brun2c86cbf2014-10-30 15:56:50 +010067#include <common/cfgparse.h>
Nenad Merdanovic05552d42015-02-27 19:56:49 +010068#include <common/base64.h>
Emeric Brun46591952012-05-18 15:47:34 +020069
Emeric Brunfc0421f2012-09-07 17:30:07 +020070#include <ebsttree.h>
71
William Lallemand32af2032016-10-29 18:09:35 +020072#include <types/applet.h>
73#include <types/cli.h>
Emeric Brunfc0421f2012-09-07 17:30:07 +020074#include <types/global.h>
75#include <types/ssl_sock.h>
William Lallemand32af2032016-10-29 18:09:35 +020076#include <types/stats.h>
Emeric Brunfc0421f2012-09-07 17:30:07 +020077
Willy Tarreau7875d092012-09-10 08:20:03 +020078#include <proto/acl.h>
79#include <proto/arg.h>
William Lallemand32af2032016-10-29 18:09:35 +020080#include <proto/channel.h>
Emeric Brun46591952012-05-18 15:47:34 +020081#include <proto/connection.h>
William Lallemand32af2032016-10-29 18:09:35 +020082#include <proto/cli.h>
Emeric Brun46591952012-05-18 15:47:34 +020083#include <proto/fd.h>
84#include <proto/freq_ctr.h>
85#include <proto/frontend.h>
Willy Tarreau79eeafa2012-09-14 07:53:05 +020086#include <proto/listener.h>
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +020087#include <proto/openssl-compat.h>
Thierry FOURNIERed66c292013-11-28 11:05:19 +010088#include <proto/pattern.h>
Christopher Faulet31af49d2015-06-09 17:29:50 +020089#include <proto/proto_tcp.h>
Willy Tarreau92faadf2012-10-10 23:04:25 +020090#include <proto/server.h>
William Lallemand32af2032016-10-29 18:09:35 +020091#include <proto/stream_interface.h>
Emeric Brun46591952012-05-18 15:47:34 +020092#include <proto/log.h>
Emeric Brun94324a42012-10-11 14:00:19 +020093#include <proto/proxy.h>
Emeric Brunfc0421f2012-09-07 17:30:07 +020094#include <proto/shctx.h>
Emeric Brun46591952012-05-18 15:47:34 +020095#include <proto/ssl_sock.h>
Willy Tarreau9ad7bd42015-04-03 19:19:59 +020096#include <proto/stream.h>
Emeric Brun46591952012-05-18 15:47:34 +020097#include <proto/task.h>
98
Willy Tarreau518cedd2014-02-17 15:43:01 +010099/* Warning, these are bits, not integers! */
Emeric Brune64aef12012-09-21 13:15:06 +0200100#define SSL_SOCK_ST_FL_VERIFY_DONE 0x00000001
Emeric Brund8b2bb52014-01-28 15:43:53 +0100101#define SSL_SOCK_ST_FL_16K_WBFSIZE 0x00000002
Willy Tarreau518cedd2014-02-17 15:43:01 +0100102#define SSL_SOCK_SEND_UNLIMITED 0x00000004
Emeric Brun29f037d2014-04-25 19:05:36 +0200103#define SSL_SOCK_RECV_HEARTBEAT 0x00000008
104
Emeric Brunf282a812012-09-21 15:27:54 +0200105/* bits 0xFFFF0000 are reserved to store verify errors */
106
107/* Verify errors macros */
108#define SSL_SOCK_CA_ERROR_TO_ST(e) (((e > 63) ? 63 : e) << (16))
109#define SSL_SOCK_CAEDEPTH_TO_ST(d) (((d > 15) ? 15 : d) << (6+16))
110#define SSL_SOCK_CRTERROR_TO_ST(e) (((e > 63) ? 63 : e) << (4+6+16))
111
112#define SSL_SOCK_ST_TO_CA_ERROR(s) ((s >> (16)) & 63)
113#define SSL_SOCK_ST_TO_CAEDEPTH(s) ((s >> (6+16)) & 15)
114#define SSL_SOCK_ST_TO_CRTERROR(s) ((s >> (4+6+16)) & 63)
Emeric Brune64aef12012-09-21 13:15:06 +0200115
Nenad Merdanovic05552d42015-02-27 19:56:49 +0100116/* Supported hash function for TLS tickets */
117#ifdef OPENSSL_NO_SHA256
118#define HASH_FUNCT EVP_sha1
119#else
120#define HASH_FUNCT EVP_sha256
121#endif /* OPENSSL_NO_SHA256 */
122
Emeric Brun850efd52014-01-29 12:24:34 +0100123/* server and bind verify method, it uses a global value as default */
124enum {
125 SSL_SOCK_VERIFY_DEFAULT = 0,
126 SSL_SOCK_VERIFY_REQUIRED = 1,
127 SSL_SOCK_VERIFY_OPTIONAL = 2,
128 SSL_SOCK_VERIFY_NONE = 3,
129};
130
Willy Tarreau71b734c2014-01-28 15:19:44 +0100131int sslconns = 0;
132int totalsslconns = 0;
Willy Tarreaud9f5cca2016-12-22 21:08:52 +0100133static struct xprt_ops ssl_sock;
Emeric Brune1f38db2012-09-03 20:36:47 +0200134
Nenad Merdanovic200b0fa2015-05-09 08:46:01 +0200135#if (defined SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB && TLS_TICKETS_NO > 0)
136struct list tlskeys_reference = LIST_HEAD_INIT(tlskeys_reference);
137#endif
138
Remi Gacogne8de54152014-07-15 11:36:40 +0200139#ifndef OPENSSL_NO_DH
Remi Gacogne4f902b82015-05-28 16:23:00 +0200140static int ssl_dh_ptr_index = -1;
Remi Gacogne47783ef2015-05-29 15:53:22 +0200141static DH *global_dh = NULL;
Remi Gacogne8de54152014-07-15 11:36:40 +0200142static DH *local_dh_1024 = NULL;
143static DH *local_dh_2048 = NULL;
144static DH *local_dh_4096 = NULL;
Remi Gacogne8de54152014-07-15 11:36:40 +0200145#endif /* OPENSSL_NO_DH */
146
Willy Tarreauc8ad3be2015-06-17 15:48:26 +0200147#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Christopher Faulet31af49d2015-06-09 17:29:50 +0200148/* X509V3 Extensions that will be added on generated certificates */
149#define X509V3_EXT_SIZE 5
150static char *x509v3_ext_names[X509V3_EXT_SIZE] = {
151 "basicConstraints",
152 "nsComment",
153 "subjectKeyIdentifier",
154 "authorityKeyIdentifier",
155 "keyUsage",
156};
157static char *x509v3_ext_values[X509V3_EXT_SIZE] = {
158 "CA:FALSE",
159 "\"OpenSSL Generated Certificate\"",
160 "hash",
161 "keyid,issuer:always",
162 "nonRepudiation,digitalSignature,keyEncipherment"
163};
164
165/* LRU cache to store generated certificate */
166static struct lru64_head *ssl_ctx_lru_tree = NULL;
167static unsigned int ssl_ctx_lru_seed = 0;
Willy Tarreauc8ad3be2015-06-17 15:48:26 +0200168#endif // SSL_CTRL_SET_TLSEXT_HOSTNAME
169
yanbzhube2774d2015-12-10 15:07:30 -0500170#if OPENSSL_VERSION_NUMBER >= 0x1000200fL
171/* The order here matters for picking a default context,
172 * keep the most common keytype at the bottom of the list
173 */
174const char *SSL_SOCK_KEYTYPE_NAMES[] = {
175 "dsa",
176 "ecdsa",
177 "rsa"
178};
179#define SSL_SOCK_NUM_KEYTYPES 3
Willy Tarreau30da7ad2015-12-14 11:28:33 +0100180#else
181#define SSL_SOCK_NUM_KEYTYPES 1
yanbzhube2774d2015-12-10 15:07:30 -0500182#endif
183
Willy Tarreauc8ad3be2015-06-17 15:48:26 +0200184#if (defined SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB && !defined OPENSSL_NO_OCSP)
yanbzhube2774d2015-12-10 15:07:30 -0500185/*
186 * struct alignment works here such that the key.key is the same as key_data
187 * Do not change the placement of key_data
188 */
Willy Tarreauc8ad3be2015-06-17 15:48:26 +0200189struct certificate_ocsp {
190 struct ebmb_node key;
191 unsigned char key_data[OCSP_MAX_CERTID_ASN1_LENGTH];
192 struct chunk response;
193 long expire;
194};
Christopher Faulet31af49d2015-06-09 17:29:50 +0200195
yanbzhube2774d2015-12-10 15:07:30 -0500196struct ocsp_cbk_arg {
197 int is_single;
198 int single_kt;
199 union {
200 struct certificate_ocsp *s_ocsp;
201 /*
202 * m_ocsp will have multiple entries dependent on key type
203 * Entry 0 - DSA
204 * Entry 1 - ECDSA
205 * Entry 2 - RSA
206 */
207 struct certificate_ocsp *m_ocsp[SSL_SOCK_NUM_KEYTYPES];
208 };
209};
210
Emeric Brun4f3c87a2014-06-20 15:46:13 +0200211/*
Thierry FOURNIER / OZON.IO8b068c22016-10-10 11:59:50 +0200212 * This function gives the detail of the SSL error. It is used only
213 * if the debug mode and the verbose mode are activated. It dump all
214 * the SSL error until the stack was empty.
215 */
216static forceinline void ssl_sock_dump_errors(struct connection *conn)
217{
218 unsigned long ret;
219
220 if (unlikely(global.mode & MODE_DEBUG)) {
221 while(1) {
222 ret = ERR_get_error();
223 if (ret == 0)
224 return;
225 fprintf(stderr, "fd[%04x] OpenSSL error[0x%lx] %s: %s\n",
226 (unsigned short)conn->t.sock.fd, ret,
227 ERR_func_error_string(ret), ERR_reason_error_string(ret));
228 }
229 }
230}
231
232/*
Emeric Brun4f3c87a2014-06-20 15:46:13 +0200233 * This function returns the number of seconds elapsed
234 * since the Epoch, 1970-01-01 00:00:00 +0000 (UTC) and the
235 * date presented un ASN1_GENERALIZEDTIME.
236 *
237 * In parsing error case, it returns -1.
238 */
239static long asn1_generalizedtime_to_epoch(ASN1_GENERALIZEDTIME *d)
240{
241 long epoch;
242 char *p, *end;
243 const unsigned short month_offset[12] = {
244 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334
245 };
246 int year, month;
247
248 if (!d || (d->type != V_ASN1_GENERALIZEDTIME)) return -1;
249
250 p = (char *)d->data;
251 end = p + d->length;
252
253 if (end - p < 4) return -1;
254 year = 1000 * (p[0] - '0') + 100 * (p[1] - '0') + 10 * (p[2] - '0') + p[3] - '0';
255 p += 4;
256 if (end - p < 2) return -1;
257 month = 10 * (p[0] - '0') + p[1] - '0';
258 if (month < 1 || month > 12) return -1;
259 /* Compute the number of seconds since 1 jan 1970 and the beginning of current month
260 We consider leap years and the current month (<marsh or not) */
261 epoch = ( ((year - 1970) * 365)
262 + ((year - (month < 3)) / 4 - (year - (month < 3)) / 100 + (year - (month < 3)) / 400)
263 - ((1970 - 1) / 4 - (1970 - 1) / 100 + (1970 - 1) / 400)
264 + month_offset[month-1]
265 ) * 24 * 60 * 60;
266 p += 2;
267 if (end - p < 2) return -1;
268 /* Add the number of seconds of completed days of current month */
269 epoch += (10 * (p[0] - '0') + p[1] - '0' - 1) * 24 * 60 * 60;
270 p += 2;
271 if (end - p < 2) return -1;
272 /* Add the completed hours of the current day */
273 epoch += (10 * (p[0] - '0') + p[1] - '0') * 60 * 60;
274 p += 2;
275 if (end - p < 2) return -1;
276 /* Add the completed minutes of the current hour */
277 epoch += (10 * (p[0] - '0') + p[1] - '0') * 60;
278 p += 2;
279 if (p == end) return -1;
280 /* Test if there is available seconds */
281 if (p[0] < '0' || p[0] > '9')
282 goto nosec;
283 if (end - p < 2) return -1;
284 /* Add the seconds of the current minute */
285 epoch += 10 * (p[0] - '0') + p[1] - '0';
286 p += 2;
287 if (p == end) return -1;
288 /* Ignore seconds float part if present */
289 if (p[0] == '.') {
290 do {
291 if (++p == end) return -1;
292 } while (p[0] >= '0' && p[0] <= '9');
293 }
294
295nosec:
296 if (p[0] == 'Z') {
297 if (end - p != 1) return -1;
298 return epoch;
299 }
300 else if (p[0] == '+') {
301 if (end - p != 5) return -1;
302 /* Apply timezone offset */
303 return epoch - ((10 * (p[1] - '0') + p[2] - '0') * 60 + (10 * (p[3] - '0') + p[4] - '0')) * 60;
304 }
305 else if (p[0] == '-') {
306 if (end - p != 5) return -1;
307 /* Apply timezone offset */
308 return epoch + ((10 * (p[1] - '0') + p[2] - '0') * 60 + (10 * (p[3] - '0') + p[4] - '0')) * 60;
309 }
310
311 return -1;
312}
313
Emeric Brun1d3865b2014-06-20 15:37:32 +0200314static struct eb_root cert_ocsp_tree = EB_ROOT_UNIQUE;
Emeric Brun4147b2e2014-06-16 18:36:30 +0200315
316/* This function starts to check if the OCSP response (in DER format) contained
317 * in chunk 'ocsp_response' is valid (else exits on error).
318 * If 'cid' is not NULL, it will be compared to the OCSP certificate ID
319 * contained in the OCSP Response and exits on error if no match.
320 * If it's a valid OCSP Response:
321 * If 'ocsp' is not NULL, the chunk is copied in the OCSP response's container
322 * pointed by 'ocsp'.
323 * If 'ocsp' is NULL, the function looks up into the OCSP response's
324 * containers tree (using as index the ASN1 form of the OCSP Certificate ID extracted
325 * from the response) and exits on error if not found. Finally, If an OCSP response is
326 * already present in the container, it will be overwritten.
327 *
328 * Note: OCSP response containing more than one OCSP Single response is not
329 * considered valid.
330 *
331 * Returns 0 on success, 1 in error case.
332 */
333static int ssl_sock_load_ocsp_response(struct chunk *ocsp_response, struct certificate_ocsp *ocsp, OCSP_CERTID *cid, char **err)
334{
335 OCSP_RESPONSE *resp;
336 OCSP_BASICRESP *bs = NULL;
337 OCSP_SINGLERESP *sr;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +0200338 OCSP_CERTID *id;
Emeric Brun4147b2e2014-06-16 18:36:30 +0200339 unsigned char *p = (unsigned char *)ocsp_response->str;
340 int rc , count_sr;
Emeric Brun13a6b482014-06-20 15:44:34 +0200341 ASN1_GENERALIZEDTIME *revtime, *thisupd, *nextupd = NULL;
Emeric Brun4147b2e2014-06-16 18:36:30 +0200342 int reason;
343 int ret = 1;
344
345 resp = d2i_OCSP_RESPONSE(NULL, (const unsigned char **)&p, ocsp_response->len);
346 if (!resp) {
347 memprintf(err, "Unable to parse OCSP response");
348 goto out;
349 }
350
351 rc = OCSP_response_status(resp);
352 if (rc != OCSP_RESPONSE_STATUS_SUCCESSFUL) {
353 memprintf(err, "OCSP response status not successful");
354 goto out;
355 }
356
357 bs = OCSP_response_get1_basic(resp);
358 if (!bs) {
359 memprintf(err, "Failed to get basic response from OCSP Response");
360 goto out;
361 }
362
363 count_sr = OCSP_resp_count(bs);
364 if (count_sr > 1) {
365 memprintf(err, "OCSP response ignored because contains multiple single responses (%d)", count_sr);
366 goto out;
367 }
368
369 sr = OCSP_resp_get0(bs, 0);
370 if (!sr) {
371 memprintf(err, "Failed to get OCSP single response");
372 goto out;
373 }
374
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +0200375 id = (OCSP_CERTID*)OCSP_SINGLERESP_get0_id(sr);
376
Emeric Brun4147b2e2014-06-16 18:36:30 +0200377 rc = OCSP_single_get0_status(sr, &reason, &revtime, &thisupd, &nextupd);
378 if (rc != V_OCSP_CERTSTATUS_GOOD) {
379 memprintf(err, "OCSP single response: certificate status not good");
380 goto out;
381 }
382
Emeric Brun13a6b482014-06-20 15:44:34 +0200383 if (!nextupd) {
384 memprintf(err, "OCSP single response: missing nextupdate");
385 goto out;
386 }
387
Emeric Brunc8b27b62014-06-19 14:16:17 +0200388 rc = OCSP_check_validity(thisupd, nextupd, OCSP_MAX_RESPONSE_TIME_SKEW, -1);
Emeric Brun4147b2e2014-06-16 18:36:30 +0200389 if (!rc) {
390 memprintf(err, "OCSP single response: no longer valid.");
391 goto out;
392 }
393
394 if (cid) {
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +0200395 if (OCSP_id_cmp(id, cid)) {
Emeric Brun4147b2e2014-06-16 18:36:30 +0200396 memprintf(err, "OCSP single response: Certificate ID does not match certificate and issuer");
397 goto out;
398 }
399 }
400
401 if (!ocsp) {
402 unsigned char key[OCSP_MAX_CERTID_ASN1_LENGTH];
403 unsigned char *p;
404
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +0200405 rc = i2d_OCSP_CERTID(id, NULL);
Emeric Brun4147b2e2014-06-16 18:36:30 +0200406 if (!rc) {
407 memprintf(err, "OCSP single response: Unable to encode Certificate ID");
408 goto out;
409 }
410
411 if (rc > OCSP_MAX_CERTID_ASN1_LENGTH) {
412 memprintf(err, "OCSP single response: Certificate ID too long");
413 goto out;
414 }
415
416 p = key;
417 memset(key, 0, OCSP_MAX_CERTID_ASN1_LENGTH);
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +0200418 i2d_OCSP_CERTID(id, &p);
Emeric Brun4147b2e2014-06-16 18:36:30 +0200419 ocsp = (struct certificate_ocsp *)ebmb_lookup(&cert_ocsp_tree, key, OCSP_MAX_CERTID_ASN1_LENGTH);
420 if (!ocsp) {
421 memprintf(err, "OCSP single response: Certificate ID does not match any certificate or issuer");
422 goto out;
423 }
424 }
425
426 /* According to comments on "chunk_dup", the
427 previous chunk buffer will be freed */
428 if (!chunk_dup(&ocsp->response, ocsp_response)) {
429 memprintf(err, "OCSP response: Memory allocation error");
430 goto out;
431 }
432
Emeric Brun4f3c87a2014-06-20 15:46:13 +0200433 ocsp->expire = asn1_generalizedtime_to_epoch(nextupd) - OCSP_MAX_RESPONSE_TIME_SKEW;
434
Emeric Brun4147b2e2014-06-16 18:36:30 +0200435 ret = 0;
436out:
437 if (bs)
438 OCSP_BASICRESP_free(bs);
439
440 if (resp)
441 OCSP_RESPONSE_free(resp);
442
443 return ret;
444}
445/*
446 * External function use to update the OCSP response in the OCSP response's
447 * containers tree. The chunk 'ocsp_response' must contain the OCSP response
448 * to update in DER format.
449 *
450 * Returns 0 on success, 1 in error case.
451 */
452int ssl_sock_update_ocsp_response(struct chunk *ocsp_response, char **err)
453{
454 return ssl_sock_load_ocsp_response(ocsp_response, NULL, NULL, err);
455}
456
457/*
458 * This function load the OCSP Resonse in DER format contained in file at
459 * path 'ocsp_path' and call 'ssl_sock_load_ocsp_response'
460 *
461 * Returns 0 on success, 1 in error case.
462 */
463static int ssl_sock_load_ocsp_response_from_file(const char *ocsp_path, struct certificate_ocsp *ocsp, OCSP_CERTID *cid, char **err)
464{
465 int fd = -1;
466 int r = 0;
467 int ret = 1;
468
469 fd = open(ocsp_path, O_RDONLY);
470 if (fd == -1) {
471 memprintf(err, "Error opening OCSP response file");
472 goto end;
473 }
474
475 trash.len = 0;
476 while (trash.len < trash.size) {
477 r = read(fd, trash.str + trash.len, trash.size - trash.len);
478 if (r < 0) {
479 if (errno == EINTR)
480 continue;
481
482 memprintf(err, "Error reading OCSP response from file");
483 goto end;
484 }
485 else if (r == 0) {
486 break;
487 }
488 trash.len += r;
489 }
490
491 close(fd);
492 fd = -1;
493
494 ret = ssl_sock_load_ocsp_response(&trash, ocsp, cid, err);
495end:
496 if (fd != -1)
497 close(fd);
498
499 return ret;
500}
501
Nenad Merdanovic05552d42015-02-27 19:56:49 +0100502#if (defined SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB && TLS_TICKETS_NO > 0)
503static 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)
504{
505 struct tls_sess_key *keys;
506 struct connection *conn;
507 int head;
508 int i;
509
Vincent Bernat3c2f2f22016-04-03 13:48:42 +0200510 conn = SSL_get_app_data(s);
Nenad Merdanovic146defa2015-05-09 08:46:00 +0200511 keys = objt_listener(conn->target)->bind_conf->keys_ref->tlskeys;
512 head = objt_listener(conn->target)->bind_conf->keys_ref->tls_ticket_enc_index;
Nenad Merdanovic05552d42015-02-27 19:56:49 +0100513
514 if (enc) {
515 memcpy(key_name, keys[head].name, 16);
516
517 if(!RAND_pseudo_bytes(iv, EVP_MAX_IV_LENGTH))
518 return -1;
519
520 if(!EVP_EncryptInit_ex(ectx, EVP_aes_128_cbc(), NULL, keys[head].aes_key, iv))
521 return -1;
522
523 HMAC_Init_ex(hctx, keys[head].hmac_key, 16, HASH_FUNCT(), NULL);
524
525 return 1;
526 } else {
527 for (i = 0; i < TLS_TICKETS_NO; i++) {
528 if (!memcmp(key_name, keys[(head + i) % TLS_TICKETS_NO].name, 16))
529 goto found;
530 }
531 return 0;
532
533 found:
534 HMAC_Init_ex(hctx, keys[(head + i) % TLS_TICKETS_NO].hmac_key, 16, HASH_FUNCT(), NULL);
535 if(!EVP_DecryptInit_ex(ectx, EVP_aes_128_cbc(), NULL, keys[(head + i) % TLS_TICKETS_NO].aes_key, iv))
536 return -1;
537 /* 2 for key renewal, 1 if current key is still valid */
538 return i ? 2 : 1;
539 }
Nenad Merdanovic200b0fa2015-05-09 08:46:01 +0200540}
541
542struct tls_keys_ref *tlskeys_ref_lookup(const char *filename)
543{
544 struct tls_keys_ref *ref;
545
546 list_for_each_entry(ref, &tlskeys_reference, list)
547 if (ref->filename && strcmp(filename, ref->filename) == 0)
548 return ref;
549 return NULL;
550}
551
552struct tls_keys_ref *tlskeys_ref_lookupid(int unique_id)
553{
554 struct tls_keys_ref *ref;
555
556 list_for_each_entry(ref, &tlskeys_reference, list)
557 if (ref->unique_id == unique_id)
558 return ref;
559 return NULL;
560}
561
562int ssl_sock_update_tlskey(char *filename, struct chunk *tlskey, char **err) {
563 struct tls_keys_ref *ref = tlskeys_ref_lookup(filename);
564
565 if(!ref) {
566 memprintf(err, "Unable to locate the referenced filename: %s", filename);
567 return 1;
568 }
569
Pradeep Jindalcc79b002015-08-20 18:25:17 +0530570 memcpy((char *) (ref->tlskeys + ((ref->tls_ticket_enc_index + 2) % TLS_TICKETS_NO)), tlskey->str, tlskey->len);
571 ref->tls_ticket_enc_index = (ref->tls_ticket_enc_index + 1) % TLS_TICKETS_NO;
Nenad Merdanovic200b0fa2015-05-09 08:46:01 +0200572
573 return 0;
Nenad Merdanovic05552d42015-02-27 19:56:49 +0100574}
Nenad Merdanovic200b0fa2015-05-09 08:46:01 +0200575
576/* This function finalize the configuration parsing. Its set all the
577 * automatic ids
578 */
579void tlskeys_finalize_config(void)
580{
581 int i = 0;
582 struct tls_keys_ref *ref, *ref2, *ref3;
583 struct list tkr = LIST_HEAD_INIT(tkr);
584
585 list_for_each_entry(ref, &tlskeys_reference, list) {
586 if (ref->unique_id == -1) {
587 /* Look for the first free id. */
588 while (1) {
589 list_for_each_entry(ref2, &tlskeys_reference, list) {
590 if (ref2->unique_id == i) {
591 i++;
592 break;
593 }
594 }
595 if (&ref2->list == &tlskeys_reference)
596 break;
597 }
598
599 /* Uses the unique id and increment it for the next entry. */
600 ref->unique_id = i;
601 i++;
602 }
603 }
604
605 /* This sort the reference list by id. */
606 list_for_each_entry_safe(ref, ref2, &tlskeys_reference, list) {
607 LIST_DEL(&ref->list);
608 list_for_each_entry(ref3, &tkr, list) {
609 if (ref->unique_id < ref3->unique_id) {
610 LIST_ADDQ(&ref3->list, &ref->list);
611 break;
612 }
613 }
614 if (&ref3->list == &tkr)
615 LIST_ADDQ(&tkr, &ref->list);
616 }
617
618 /* swap root */
619 LIST_ADD(&tkr, &tlskeys_reference);
620 LIST_DEL(&tkr);
621}
622
Nenad Merdanovic05552d42015-02-27 19:56:49 +0100623#endif /* SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB */
624
yanbzhube2774d2015-12-10 15:07:30 -0500625int ssl_sock_get_ocsp_arg_kt_index(int evp_keytype)
626{
627 switch (evp_keytype) {
628 case EVP_PKEY_RSA:
629 return 2;
630 case EVP_PKEY_DSA:
631 return 0;
632 case EVP_PKEY_EC:
633 return 1;
634 }
635
636 return -1;
637}
638
Emeric Brun4147b2e2014-06-16 18:36:30 +0200639/*
640 * Callback used to set OCSP status extension content in server hello.
641 */
642int ssl_sock_ocsp_stapling_cbk(SSL *ssl, void *arg)
643{
yanbzhube2774d2015-12-10 15:07:30 -0500644 struct certificate_ocsp *ocsp;
645 struct ocsp_cbk_arg *ocsp_arg;
646 char *ssl_buf;
647 EVP_PKEY *ssl_pkey;
648 int key_type;
649 int index;
650
Vincent Bernat3c2f2f22016-04-03 13:48:42 +0200651 ocsp_arg = arg;
yanbzhube2774d2015-12-10 15:07:30 -0500652
653 ssl_pkey = SSL_get_privatekey(ssl);
654 if (!ssl_pkey)
655 return SSL_TLSEXT_ERR_NOACK;
656
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +0200657 key_type = EVP_PKEY_base_id(ssl_pkey);
yanbzhube2774d2015-12-10 15:07:30 -0500658
659 if (ocsp_arg->is_single && ocsp_arg->single_kt == key_type)
660 ocsp = ocsp_arg->s_ocsp;
661 else {
662 /* For multiple certs per context, we have to find the correct OCSP response based on
663 * the certificate type
664 */
665 index = ssl_sock_get_ocsp_arg_kt_index(key_type);
666
667 if (index < 0)
668 return SSL_TLSEXT_ERR_NOACK;
669
670 ocsp = ocsp_arg->m_ocsp[index];
671
672 }
Emeric Brun4147b2e2014-06-16 18:36:30 +0200673
674 if (!ocsp ||
675 !ocsp->response.str ||
Emeric Brun4f3c87a2014-06-20 15:46:13 +0200676 !ocsp->response.len ||
677 (ocsp->expire < now.tv_sec))
Emeric Brun4147b2e2014-06-16 18:36:30 +0200678 return SSL_TLSEXT_ERR_NOACK;
679
680 ssl_buf = OPENSSL_malloc(ocsp->response.len);
681 if (!ssl_buf)
682 return SSL_TLSEXT_ERR_NOACK;
683
684 memcpy(ssl_buf, ocsp->response.str, ocsp->response.len);
685 SSL_set_tlsext_status_ocsp_resp(ssl, ssl_buf, ocsp->response.len);
686
687 return SSL_TLSEXT_ERR_OK;
688}
689
690/*
691 * This function enables the handling of OCSP status extension on 'ctx' if a
692 * file name 'cert_path' suffixed using ".ocsp" is present.
693 * To enable OCSP status extension, the issuer's certificate is mandatory.
694 * It should be present in the certificate's extra chain builded from file
695 * 'cert_path'. If not found, the issuer certificate is loaded from a file
696 * named 'cert_path' suffixed using '.issuer'.
697 *
698 * In addition, ".ocsp" file content is loaded as a DER format of an OCSP
699 * response. If file is empty or content is not a valid OCSP response,
700 * OCSP status extension is enabled but OCSP response is ignored (a warning
701 * is displayed).
702 *
703 * Returns 1 if no ".ocsp" file found, 0 if OCSP status extension is
704 * succesfully enabled, or -1 in other error case.
705 */
706static int ssl_sock_load_ocsp(SSL_CTX *ctx, const char *cert_path)
707{
708
709 BIO *in = NULL;
710 X509 *x, *xi = NULL, *issuer = NULL;
711 STACK_OF(X509) *chain = NULL;
712 OCSP_CERTID *cid = NULL;
713 SSL *ssl;
714 char ocsp_path[MAXPATHLEN+1];
715 int i, ret = -1;
716 struct stat st;
717 struct certificate_ocsp *ocsp = NULL, *iocsp;
718 char *warn = NULL;
719 unsigned char *p;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +0200720 pem_password_cb *passwd_cb;
721 void *passwd_cb_userdata;
722 void (*callback) (void);
Emeric Brun4147b2e2014-06-16 18:36:30 +0200723
724 snprintf(ocsp_path, MAXPATHLEN+1, "%s.ocsp", cert_path);
725
726 if (stat(ocsp_path, &st))
727 return 1;
728
729 ssl = SSL_new(ctx);
730 if (!ssl)
731 goto out;
732
733 x = SSL_get_certificate(ssl);
734 if (!x)
735 goto out;
736
737 /* Try to lookup for issuer in certificate extra chain */
738#ifdef SSL_CTRL_GET_EXTRA_CHAIN_CERTS
739 SSL_CTX_get_extra_chain_certs(ctx, &chain);
740#else
741 chain = ctx->extra_certs;
742#endif
743 for (i = 0; i < sk_X509_num(chain); i++) {
744 issuer = sk_X509_value(chain, i);
745 if (X509_check_issued(issuer, x) == X509_V_OK)
746 break;
747 else
748 issuer = NULL;
749 }
750
751 /* If not found try to load issuer from a suffixed file */
752 if (!issuer) {
753 char issuer_path[MAXPATHLEN+1];
754
755 in = BIO_new(BIO_s_file());
756 if (!in)
757 goto out;
758
759 snprintf(issuer_path, MAXPATHLEN+1, "%s.issuer", cert_path);
760 if (BIO_read_filename(in, issuer_path) <= 0)
761 goto out;
762
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +0200763 passwd_cb = SSL_CTX_get_default_passwd_cb(ctx);
764 passwd_cb_userdata = SSL_CTX_get_default_passwd_cb_userdata(ctx);
765
766 xi = PEM_read_bio_X509_AUX(in, NULL, passwd_cb, passwd_cb_userdata);
Emeric Brun4147b2e2014-06-16 18:36:30 +0200767 if (!xi)
768 goto out;
769
770 if (X509_check_issued(xi, x) != X509_V_OK)
771 goto out;
772
773 issuer = xi;
774 }
775
776 cid = OCSP_cert_to_id(0, x, issuer);
777 if (!cid)
778 goto out;
779
780 i = i2d_OCSP_CERTID(cid, NULL);
781 if (!i || (i > OCSP_MAX_CERTID_ASN1_LENGTH))
782 goto out;
783
Vincent Bernat02779b62016-04-03 13:48:43 +0200784 ocsp = calloc(1, sizeof(*ocsp));
Emeric Brun4147b2e2014-06-16 18:36:30 +0200785 if (!ocsp)
786 goto out;
787
788 p = ocsp->key_data;
789 i2d_OCSP_CERTID(cid, &p);
790
791 iocsp = (struct certificate_ocsp *)ebmb_insert(&cert_ocsp_tree, &ocsp->key, OCSP_MAX_CERTID_ASN1_LENGTH);
792 if (iocsp == ocsp)
793 ocsp = NULL;
794
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +0200795#ifndef SSL_CTX_get_tlsext_status_cb
796# define SSL_CTX_get_tlsext_status_cb(ctx, cb) \
797 *cb = (void (*) (void))ctx->tlsext_status_cb;
798#endif
799 SSL_CTX_get_tlsext_status_cb(ctx, &callback);
800
801 if (!callback) {
Vincent Bernat02779b62016-04-03 13:48:43 +0200802 struct ocsp_cbk_arg *cb_arg = calloc(1, sizeof(*cb_arg));
yanbzhube2774d2015-12-10 15:07:30 -0500803
804 cb_arg->is_single = 1;
805 cb_arg->s_ocsp = iocsp;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +0200806
807 cb_arg->single_kt = EVP_PKEY_base_id(X509_get_pubkey(x));
yanbzhube2774d2015-12-10 15:07:30 -0500808
809 SSL_CTX_set_tlsext_status_cb(ctx, ssl_sock_ocsp_stapling_cbk);
810 SSL_CTX_set_tlsext_status_arg(ctx, cb_arg);
811 } else {
812 /*
813 * If the ctx has a status CB, then we have previously set an OCSP staple for this ctx
814 * Update that cb_arg with the new cert's staple
815 */
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +0200816 struct ocsp_cbk_arg *cb_arg;
yanbzhube2774d2015-12-10 15:07:30 -0500817 struct certificate_ocsp *tmp_ocsp;
818 int index;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +0200819 int key_type;
820
821#ifdef SSL_CTX_get_tlsext_status_arg
822 SSL_CTX_ctrl(ctx, SSL_CTRL_GET_TLSEXT_STATUS_REQ_CB_ARG, 0, &cb_arg);
823#else
824 cb_arg = ctx->tlsext_status_arg;
825#endif
yanbzhube2774d2015-12-10 15:07:30 -0500826
827 /*
828 * The following few lines will convert cb_arg from a single ocsp to multi ocsp
829 * the order of operations below matter, take care when changing it
830 */
831 tmp_ocsp = cb_arg->s_ocsp;
832 index = ssl_sock_get_ocsp_arg_kt_index(cb_arg->single_kt);
833 cb_arg->s_ocsp = NULL;
834 cb_arg->m_ocsp[index] = tmp_ocsp;
835 cb_arg->is_single = 0;
836 cb_arg->single_kt = 0;
837
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +0200838 key_type = EVP_PKEY_base_id(X509_get_pubkey(x));
839 index = ssl_sock_get_ocsp_arg_kt_index(key_type);
yanbzhube2774d2015-12-10 15:07:30 -0500840 if (index >= 0 && !cb_arg->m_ocsp[index])
841 cb_arg->m_ocsp[index] = iocsp;
842
843 }
Emeric Brun4147b2e2014-06-16 18:36:30 +0200844
845 ret = 0;
846
847 warn = NULL;
848 if (ssl_sock_load_ocsp_response_from_file(ocsp_path, iocsp, cid, &warn)) {
849 memprintf(&warn, "Loading '%s': %s. Content will be ignored", ocsp_path, warn ? warn : "failure");
850 Warning("%s.\n", warn);
851 }
852
853out:
854 if (ssl)
855 SSL_free(ssl);
856
857 if (in)
858 BIO_free(in);
859
860 if (xi)
861 X509_free(xi);
862
863 if (cid)
864 OCSP_CERTID_free(cid);
865
866 if (ocsp)
867 free(ocsp);
868
869 if (warn)
870 free(warn);
871
872
873 return ret;
874}
875
876#endif
877
Daniel Jakots54ffb912015-11-06 20:02:41 +0100878#if (OPENSSL_VERSION_NUMBER >= 0x1000200fL && !defined OPENSSL_NO_TLSEXT && !defined OPENSSL_IS_BORINGSSL && !defined LIBRESSL_VERSION_NUMBER)
Janusz Dziemidowicz2c701b52015-03-07 23:03:59 +0100879
880#define CT_EXTENSION_TYPE 18
881
882static int sctl_ex_index = -1;
883
884/*
885 * Try to parse Signed Certificate Timestamp List structure. This function
886 * makes only basic test if the data seems like SCTL. No signature validation
887 * is performed.
888 */
889static int ssl_sock_parse_sctl(struct chunk *sctl)
890{
891 int ret = 1;
892 int len, pos, sct_len;
893 unsigned char *data;
894
895 if (sctl->len < 2)
896 goto out;
897
898 data = (unsigned char *)sctl->str;
899 len = (data[0] << 8) | data[1];
900
901 if (len + 2 != sctl->len)
902 goto out;
903
904 data = data + 2;
905 pos = 0;
906 while (pos < len) {
907 if (len - pos < 2)
908 goto out;
909
910 sct_len = (data[pos] << 8) | data[pos + 1];
911 if (pos + sct_len + 2 > len)
912 goto out;
913
914 pos += sct_len + 2;
915 }
916
917 ret = 0;
918
919out:
920 return ret;
921}
922
923static int ssl_sock_load_sctl_from_file(const char *sctl_path, struct chunk **sctl)
924{
925 int fd = -1;
926 int r = 0;
927 int ret = 1;
928
929 *sctl = NULL;
930
931 fd = open(sctl_path, O_RDONLY);
932 if (fd == -1)
933 goto end;
934
935 trash.len = 0;
936 while (trash.len < trash.size) {
937 r = read(fd, trash.str + trash.len, trash.size - trash.len);
938 if (r < 0) {
939 if (errno == EINTR)
940 continue;
941
942 goto end;
943 }
944 else if (r == 0) {
945 break;
946 }
947 trash.len += r;
948 }
949
950 ret = ssl_sock_parse_sctl(&trash);
951 if (ret)
952 goto end;
953
Vincent Bernat02779b62016-04-03 13:48:43 +0200954 *sctl = calloc(1, sizeof(**sctl));
Janusz Dziemidowicz2c701b52015-03-07 23:03:59 +0100955 if (!chunk_dup(*sctl, &trash)) {
956 free(*sctl);
957 *sctl = NULL;
958 goto end;
959 }
960
961end:
962 if (fd != -1)
963 close(fd);
964
965 return ret;
966}
967
968int ssl_sock_sctl_add_cbk(SSL *ssl, unsigned ext_type, const unsigned char **out, size_t *outlen, int *al, void *add_arg)
969{
Vincent Bernat3c2f2f22016-04-03 13:48:42 +0200970 struct chunk *sctl = add_arg;
Janusz Dziemidowicz2c701b52015-03-07 23:03:59 +0100971
972 *out = (unsigned char *)sctl->str;
973 *outlen = sctl->len;
974
975 return 1;
976}
977
978int ssl_sock_sctl_parse_cbk(SSL *s, unsigned int ext_type, const unsigned char *in, size_t inlen, int *al, void *parse_arg)
979{
980 return 1;
981}
982
983static int ssl_sock_load_sctl(SSL_CTX *ctx, const char *cert_path)
984{
985 char sctl_path[MAXPATHLEN+1];
986 int ret = -1;
987 struct stat st;
988 struct chunk *sctl = NULL;
989
990 snprintf(sctl_path, MAXPATHLEN+1, "%s.sctl", cert_path);
991
992 if (stat(sctl_path, &st))
993 return 1;
994
995 if (ssl_sock_load_sctl_from_file(sctl_path, &sctl))
996 goto out;
997
998 if (!SSL_CTX_add_server_custom_ext(ctx, CT_EXTENSION_TYPE, ssl_sock_sctl_add_cbk, NULL, sctl, ssl_sock_sctl_parse_cbk, NULL)) {
999 free(sctl);
1000 goto out;
1001 }
1002
1003 SSL_CTX_set_ex_data(ctx, sctl_ex_index, sctl);
1004
1005 ret = 0;
1006
1007out:
1008 return ret;
1009}
1010
1011#endif
1012
Emeric Brune1f38db2012-09-03 20:36:47 +02001013void ssl_sock_infocbk(const SSL *ssl, int where, int ret)
1014{
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02001015 struct connection *conn = SSL_get_app_data(ssl);
Emeric Brund8b2bb52014-01-28 15:43:53 +01001016 BIO *write_bio;
Willy Tarreau622317d2015-02-27 16:36:16 +01001017 (void)ret; /* shut gcc stupid warning */
Emeric Brune1f38db2012-09-03 20:36:47 +02001018
1019 if (where & SSL_CB_HANDSHAKE_START) {
1020 /* Disable renegotiation (CVE-2009-3555) */
Willy Tarreau20879a02012-12-03 16:32:10 +01001021 if (conn->flags & CO_FL_CONNECTED) {
Emeric Brune1f38db2012-09-03 20:36:47 +02001022 conn->flags |= CO_FL_ERROR;
Willy Tarreau20879a02012-12-03 16:32:10 +01001023 conn->err_code = CO_ER_SSL_RENEG;
1024 }
Emeric Brune1f38db2012-09-03 20:36:47 +02001025 }
Emeric Brund8b2bb52014-01-28 15:43:53 +01001026
1027 if ((where & SSL_CB_ACCEPT_LOOP) == SSL_CB_ACCEPT_LOOP) {
1028 if (!(conn->xprt_st & SSL_SOCK_ST_FL_16K_WBFSIZE)) {
1029 /* Long certificate chains optimz
1030 If write and read bios are differents, we
1031 consider that the buffering was activated,
1032 so we rise the output buffer size from 4k
1033 to 16k */
1034 write_bio = SSL_get_wbio(ssl);
1035 if (write_bio != SSL_get_rbio(ssl)) {
1036 BIO_set_write_buffer_size(write_bio, 16384);
1037 conn->xprt_st |= SSL_SOCK_ST_FL_16K_WBFSIZE;
1038 }
1039 }
1040 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02001041}
1042
Emeric Brune64aef12012-09-21 13:15:06 +02001043/* Callback is called for each certificate of the chain during a verify
1044 ok is set to 1 if preverify detect no error on current certificate.
1045 Returns 0 to break the handshake, 1 otherwise. */
Evan Broderbe554312013-06-27 00:05:25 -07001046int ssl_sock_bind_verifycbk(int ok, X509_STORE_CTX *x_store)
Emeric Brune64aef12012-09-21 13:15:06 +02001047{
1048 SSL *ssl;
1049 struct connection *conn;
Emeric Brun81c00f02012-09-21 14:31:21 +02001050 int err, depth;
Emeric Brune64aef12012-09-21 13:15:06 +02001051
1052 ssl = X509_STORE_CTX_get_ex_data(x_store, SSL_get_ex_data_X509_STORE_CTX_idx());
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02001053 conn = SSL_get_app_data(ssl);
Emeric Brune64aef12012-09-21 13:15:06 +02001054
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02001055 conn->xprt_st |= SSL_SOCK_ST_FL_VERIFY_DONE;
Emeric Brune64aef12012-09-21 13:15:06 +02001056
Emeric Brun81c00f02012-09-21 14:31:21 +02001057 if (ok) /* no errors */
1058 return ok;
1059
1060 depth = X509_STORE_CTX_get_error_depth(x_store);
1061 err = X509_STORE_CTX_get_error(x_store);
1062
1063 /* check if CA error needs to be ignored */
1064 if (depth > 0) {
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02001065 if (!SSL_SOCK_ST_TO_CA_ERROR(conn->xprt_st)) {
1066 conn->xprt_st |= SSL_SOCK_CA_ERROR_TO_ST(err);
1067 conn->xprt_st |= SSL_SOCK_CAEDEPTH_TO_ST(depth);
Emeric Brunf282a812012-09-21 15:27:54 +02001068 }
1069
Emeric Brun1eb20ef2012-12-03 13:24:29 +01001070 if (objt_listener(conn->target)->bind_conf->ca_ignerr & (1ULL << err)) {
Thierry FOURNIER / OZON.IO8b068c22016-10-10 11:59:50 +02001071 ssl_sock_dump_errors(conn);
Emeric Brun1eb20ef2012-12-03 13:24:29 +01001072 ERR_clear_error();
Emeric Brun81c00f02012-09-21 14:31:21 +02001073 return 1;
Emeric Brun1eb20ef2012-12-03 13:24:29 +01001074 }
Emeric Brun81c00f02012-09-21 14:31:21 +02001075
Willy Tarreau20879a02012-12-03 16:32:10 +01001076 conn->err_code = CO_ER_SSL_CA_FAIL;
Emeric Brun81c00f02012-09-21 14:31:21 +02001077 return 0;
1078 }
1079
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02001080 if (!SSL_SOCK_ST_TO_CRTERROR(conn->xprt_st))
1081 conn->xprt_st |= SSL_SOCK_CRTERROR_TO_ST(err);
Emeric Brunf282a812012-09-21 15:27:54 +02001082
Emeric Brun81c00f02012-09-21 14:31:21 +02001083 /* check if certificate error needs to be ignored */
Emeric Brun1eb20ef2012-12-03 13:24:29 +01001084 if (objt_listener(conn->target)->bind_conf->crt_ignerr & (1ULL << err)) {
Thierry FOURNIER / OZON.IO8b068c22016-10-10 11:59:50 +02001085 ssl_sock_dump_errors(conn);
Emeric Brun1eb20ef2012-12-03 13:24:29 +01001086 ERR_clear_error();
Emeric Brun81c00f02012-09-21 14:31:21 +02001087 return 1;
Emeric Brun1eb20ef2012-12-03 13:24:29 +01001088 }
Emeric Brun81c00f02012-09-21 14:31:21 +02001089
Willy Tarreau20879a02012-12-03 16:32:10 +01001090 conn->err_code = CO_ER_SSL_CRT_FAIL;
Emeric Brun81c00f02012-09-21 14:31:21 +02001091 return 0;
Emeric Brune64aef12012-09-21 13:15:06 +02001092}
1093
Emeric Brun29f037d2014-04-25 19:05:36 +02001094/* Callback is called for ssl protocol analyse */
1095void ssl_sock_msgcbk(int write_p, int version, int content_type, const void *buf, size_t len, SSL *ssl, void *arg)
1096{
Emeric Brun29f037d2014-04-25 19:05:36 +02001097#ifdef TLS1_RT_HEARTBEAT
1098 /* test heartbeat received (write_p is set to 0
1099 for a received record) */
Willy Tarreauf51c6982014-04-25 20:02:39 +02001100 if ((content_type == TLS1_RT_HEARTBEAT) && (write_p == 0)) {
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02001101 struct connection *conn = SSL_get_app_data(ssl);
Willy Tarreauf51c6982014-04-25 20:02:39 +02001102 const unsigned char *p = buf;
1103 unsigned int payload;
1104
Emeric Brun29f037d2014-04-25 19:05:36 +02001105 conn->xprt_st |= SSL_SOCK_RECV_HEARTBEAT;
Willy Tarreauf51c6982014-04-25 20:02:39 +02001106
1107 /* Check if this is a CVE-2014-0160 exploitation attempt. */
1108 if (*p != TLS1_HB_REQUEST)
1109 return;
1110
Willy Tarreauaeed6722014-04-25 23:59:58 +02001111 if (len < 1 + 2 + 16) /* 1 type + 2 size + 0 payload + 16 padding */
Willy Tarreauf51c6982014-04-25 20:02:39 +02001112 goto kill_it;
1113
1114 payload = (p[1] * 256) + p[2];
Willy Tarreau3b2fdb62014-04-25 23:44:22 +02001115 if (3 + payload + 16 <= len)
Willy Tarreauf51c6982014-04-25 20:02:39 +02001116 return; /* OK no problem */
Willy Tarreauaeed6722014-04-25 23:59:58 +02001117 kill_it:
Willy Tarreau3b2fdb62014-04-25 23:44:22 +02001118 /* We have a clear heartbleed attack (CVE-2014-0160), the
1119 * advertised payload is larger than the advertised packet
1120 * length, so we have garbage in the buffer between the
1121 * payload and the end of the buffer (p+len). We can't know
1122 * if the SSL stack is patched, and we don't know if we can
1123 * safely wipe out the area between p+3+len and payload.
1124 * So instead, we prevent the response from being sent by
1125 * setting the max_send_fragment to 0 and we report an SSL
1126 * error, which will kill this connection. It will be reported
1127 * above as SSL_ERROR_SSL while an other handshake failure with
Willy Tarreauf51c6982014-04-25 20:02:39 +02001128 * a heartbeat message will be reported as SSL_ERROR_SYSCALL.
1129 */
Willy Tarreau3b2fdb62014-04-25 23:44:22 +02001130 ssl->max_send_fragment = 0;
Willy Tarreauf51c6982014-04-25 20:02:39 +02001131 SSLerr(SSL_F_TLS1_HEARTBEAT, SSL_R_SSL_HANDSHAKE_FAILURE);
1132 return;
1133 }
Emeric Brun29f037d2014-04-25 19:05:36 +02001134#endif
1135}
1136
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02001137#ifdef OPENSSL_NPN_NEGOTIATED
1138/* This callback is used so that the server advertises the list of
1139 * negociable protocols for NPN.
1140 */
1141static int ssl_sock_advertise_npn_protos(SSL *s, const unsigned char **data,
1142 unsigned int *len, void *arg)
1143{
1144 struct bind_conf *conf = arg;
1145
1146 *data = (const unsigned char *)conf->npn_str;
1147 *len = conf->npn_len;
1148 return SSL_TLSEXT_ERR_OK;
1149}
1150#endif
1151
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01001152#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Willy Tarreauab861d32013-04-02 02:30:41 +02001153/* This callback is used so that the server advertises the list of
1154 * negociable protocols for ALPN.
1155 */
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01001156static int ssl_sock_advertise_alpn_protos(SSL *s, const unsigned char **out,
1157 unsigned char *outlen,
1158 const unsigned char *server,
1159 unsigned int server_len, void *arg)
Willy Tarreauab861d32013-04-02 02:30:41 +02001160{
1161 struct bind_conf *conf = arg;
1162
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01001163 if (SSL_select_next_proto((unsigned char**) out, outlen, (const unsigned char *)conf->alpn_str,
1164 conf->alpn_len, server, server_len) != OPENSSL_NPN_NEGOTIATED) {
1165 return SSL_TLSEXT_ERR_NOACK;
1166 }
Willy Tarreauab861d32013-04-02 02:30:41 +02001167 return SSL_TLSEXT_ERR_OK;
1168}
1169#endif
1170
Willy Tarreauc8ad3be2015-06-17 15:48:26 +02001171#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Christopher Faulet85b5a1a2015-10-09 11:46:32 +02001172static DH *ssl_get_tmp_dh(SSL *ssl, int export, int keylen);
1173
Christopher Faulet30548802015-06-11 13:39:32 +02001174/* Create a X509 certificate with the specified servername and serial. This
1175 * function returns a SSL_CTX object or NULL if an error occurs. */
Christopher Faulet7969a332015-10-09 11:15:03 +02001176static SSL_CTX *
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001177ssl_sock_do_create_cert(const char *servername, struct bind_conf *bind_conf, SSL *ssl)
Christopher Faulet31af49d2015-06-09 17:29:50 +02001178{
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001179 static unsigned int serial = 0;
1180
Christopher Faulet7969a332015-10-09 11:15:03 +02001181 X509 *cacert = bind_conf->ca_sign_cert;
1182 EVP_PKEY *capkey = bind_conf->ca_sign_pkey;
Christopher Faulet31af49d2015-06-09 17:29:50 +02001183 SSL_CTX *ssl_ctx = NULL;
1184 X509 *newcrt = NULL;
1185 EVP_PKEY *pkey = NULL;
Christopher Faulet31af49d2015-06-09 17:29:50 +02001186 X509_NAME *name;
1187 const EVP_MD *digest;
1188 X509V3_CTX ctx;
1189 unsigned int i;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02001190 int key_type;
Christopher Faulet31af49d2015-06-09 17:29:50 +02001191
Christopher Faulet7969a332015-10-09 11:15:03 +02001192 /* Get the private key of the defautl certificate and use it */
1193 if (!(pkey = SSL_get_privatekey(ssl)))
Christopher Faulet31af49d2015-06-09 17:29:50 +02001194 goto mkcert_error;
1195
1196 /* Create the certificate */
1197 if (!(newcrt = X509_new()))
1198 goto mkcert_error;
1199
1200 /* Set version number for the certificate (X509v3) and the serial
1201 * number */
1202 if (X509_set_version(newcrt, 2L) != 1)
1203 goto mkcert_error;
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001204 if (!serial)
1205 serial = now_ms;
1206 ASN1_INTEGER_set(X509_get_serialNumber(newcrt), serial++);
Christopher Faulet31af49d2015-06-09 17:29:50 +02001207
1208 /* Set duration for the certificate */
1209 if (!X509_gmtime_adj(X509_get_notBefore(newcrt), (long)-60*60*24) ||
1210 !X509_gmtime_adj(X509_get_notAfter(newcrt),(long)60*60*24*365))
1211 goto mkcert_error;
1212
1213 /* set public key in the certificate */
1214 if (X509_set_pubkey(newcrt, pkey) != 1)
1215 goto mkcert_error;
1216
1217 /* Set issuer name from the CA */
1218 if (!(name = X509_get_subject_name(cacert)))
1219 goto mkcert_error;
1220 if (X509_set_issuer_name(newcrt, name) != 1)
1221 goto mkcert_error;
1222
1223 /* Set the subject name using the same, but the CN */
1224 name = X509_NAME_dup(name);
1225 if (X509_NAME_add_entry_by_txt(name, "CN", MBSTRING_ASC,
1226 (const unsigned char *)servername,
1227 -1, -1, 0) != 1) {
1228 X509_NAME_free(name);
1229 goto mkcert_error;
1230 }
1231 if (X509_set_subject_name(newcrt, name) != 1) {
1232 X509_NAME_free(name);
1233 goto mkcert_error;
1234 }
1235 X509_NAME_free(name);
1236
1237 /* Add x509v3 extensions as specified */
1238 X509V3_set_ctx(&ctx, cacert, newcrt, NULL, NULL, 0);
1239 for (i = 0; i < X509V3_EXT_SIZE; i++) {
1240 X509_EXTENSION *ext;
1241
1242 if (!(ext = X509V3_EXT_conf(NULL, &ctx, x509v3_ext_names[i], x509v3_ext_values[i])))
1243 goto mkcert_error;
1244 if (!X509_add_ext(newcrt, ext, -1)) {
1245 X509_EXTENSION_free(ext);
1246 goto mkcert_error;
1247 }
1248 X509_EXTENSION_free(ext);
1249 }
1250
1251 /* Sign the certificate with the CA private key */
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02001252
1253 key_type = EVP_PKEY_base_id(capkey);
1254
1255 if (key_type == EVP_PKEY_DSA)
1256 digest = EVP_sha1();
1257 else if (key_type == EVP_PKEY_RSA)
Christopher Faulet31af49d2015-06-09 17:29:50 +02001258 digest = EVP_sha256();
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02001259 else if (key_type == EVP_PKEY_EC)
Christopher Faulet7969a332015-10-09 11:15:03 +02001260 digest = EVP_sha256();
1261 else {
Christopher Faulete7db2162015-10-19 13:59:24 +02001262#if (OPENSSL_VERSION_NUMBER >= 0x1000000fL)
Christopher Faulet7969a332015-10-09 11:15:03 +02001263 int nid;
1264
1265 if (EVP_PKEY_get_default_digest_nid(capkey, &nid) <= 0)
1266 goto mkcert_error;
1267 if (!(digest = EVP_get_digestbynid(nid)))
1268 goto mkcert_error;
Christopher Faulete7db2162015-10-19 13:59:24 +02001269#else
1270 goto mkcert_error;
1271#endif
Christopher Faulet7969a332015-10-09 11:15:03 +02001272 }
1273
Christopher Faulet31af49d2015-06-09 17:29:50 +02001274 if (!(X509_sign(newcrt, capkey, digest)))
1275 goto mkcert_error;
1276
1277 /* Create and set the new SSL_CTX */
1278 if (!(ssl_ctx = SSL_CTX_new(SSLv23_server_method())))
1279 goto mkcert_error;
1280 if (!SSL_CTX_use_PrivateKey(ssl_ctx, pkey))
1281 goto mkcert_error;
1282 if (!SSL_CTX_use_certificate(ssl_ctx, newcrt))
1283 goto mkcert_error;
1284 if (!SSL_CTX_check_private_key(ssl_ctx))
1285 goto mkcert_error;
1286
1287 if (newcrt) X509_free(newcrt);
Christopher Faulet7969a332015-10-09 11:15:03 +02001288
Christopher Faulet85b5a1a2015-10-09 11:46:32 +02001289 SSL_CTX_set_tmp_dh_callback(ssl_ctx, ssl_get_tmp_dh);
1290#if defined(SSL_CTX_set_tmp_ecdh) && !defined(OPENSSL_NO_ECDH)
1291 {
1292 const char *ecdhe = (bind_conf->ecdhe ? bind_conf->ecdhe : ECDHE_DEFAULT_CURVE);
1293 EC_KEY *ecc;
1294 int nid;
1295
1296 if ((nid = OBJ_sn2nid(ecdhe)) == NID_undef)
1297 goto end;
1298 if (!(ecc = EC_KEY_new_by_curve_name(nid)))
1299 goto end;
1300 SSL_CTX_set_tmp_ecdh(ssl_ctx, ecc);
1301 EC_KEY_free(ecc);
1302 }
1303#endif
1304 end:
Christopher Faulet31af49d2015-06-09 17:29:50 +02001305 return ssl_ctx;
1306
1307 mkcert_error:
1308 if (ssl_ctx) SSL_CTX_free(ssl_ctx);
1309 if (newcrt) X509_free(newcrt);
Christopher Faulet31af49d2015-06-09 17:29:50 +02001310 return NULL;
1311}
1312
Christopher Faulet7969a332015-10-09 11:15:03 +02001313SSL_CTX *
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001314ssl_sock_create_cert(struct connection *conn, const char *servername, unsigned int key)
Christopher Faulet7969a332015-10-09 11:15:03 +02001315{
1316 struct bind_conf *bind_conf = objt_listener(conn->target)->bind_conf;
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001317
1318 return ssl_sock_do_create_cert(servername, bind_conf, conn->xprt_ctx);
Christopher Faulet7969a332015-10-09 11:15:03 +02001319}
1320
Christopher Faulet30548802015-06-11 13:39:32 +02001321/* Do a lookup for a certificate in the LRU cache used to store generated
1322 * certificates. */
1323SSL_CTX *
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001324ssl_sock_get_generated_cert(unsigned int key, struct bind_conf *bind_conf)
Christopher Faulet30548802015-06-11 13:39:32 +02001325{
1326 struct lru64 *lru = NULL;
1327
1328 if (ssl_ctx_lru_tree) {
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001329 lru = lru64_lookup(key, ssl_ctx_lru_tree, bind_conf->ca_sign_cert, 0);
Christopher Faulet30548802015-06-11 13:39:32 +02001330 if (lru && lru->domain)
1331 return (SSL_CTX *)lru->data;
1332 }
1333 return NULL;
1334}
1335
Christopher Fauletd2cab922015-07-28 16:03:47 +02001336/* Set a certificate int the LRU cache used to store generated
1337 * certificate. Return 0 on success, otherwise -1 */
1338int
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001339ssl_sock_set_generated_cert(SSL_CTX *ssl_ctx, unsigned int key, struct bind_conf *bind_conf)
Christopher Faulet30548802015-06-11 13:39:32 +02001340{
1341 struct lru64 *lru = NULL;
1342
1343 if (ssl_ctx_lru_tree) {
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001344 lru = lru64_get(key, ssl_ctx_lru_tree, bind_conf->ca_sign_cert, 0);
Christopher Faulet30548802015-06-11 13:39:32 +02001345 if (!lru)
Christopher Fauletd2cab922015-07-28 16:03:47 +02001346 return -1;
Christopher Faulet30548802015-06-11 13:39:32 +02001347 if (lru->domain && lru->data)
1348 lru->free((SSL_CTX *)lru->data);
Christopher Faulet7969a332015-10-09 11:15:03 +02001349 lru64_commit(lru, ssl_ctx, bind_conf->ca_sign_cert, 0, (void (*)(void *))SSL_CTX_free);
Christopher Fauletd2cab922015-07-28 16:03:47 +02001350 return 0;
Christopher Faulet30548802015-06-11 13:39:32 +02001351 }
Christopher Fauletd2cab922015-07-28 16:03:47 +02001352 return -1;
Christopher Faulet30548802015-06-11 13:39:32 +02001353}
1354
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001355/* Compute the key of the certificate. */
Christopher Faulet30548802015-06-11 13:39:32 +02001356unsigned int
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001357ssl_sock_generated_cert_key(const void *data, size_t len)
Christopher Faulet30548802015-06-11 13:39:32 +02001358{
1359 return XXH32(data, len, ssl_ctx_lru_seed);
1360}
1361
Willy Tarreau2f63ef42015-10-20 15:16:01 +02001362/* Generate a cert and immediately assign it to the SSL session so that the cert's
1363 * refcount is maintained regardless of the cert's presence in the LRU cache.
1364 */
Christopher Faulet31af49d2015-06-09 17:29:50 +02001365static SSL_CTX *
Christopher Faulet7969a332015-10-09 11:15:03 +02001366ssl_sock_generate_certificate(const char *servername, struct bind_conf *bind_conf, SSL *ssl)
Christopher Faulet31af49d2015-06-09 17:29:50 +02001367{
1368 X509 *cacert = bind_conf->ca_sign_cert;
Christopher Faulet31af49d2015-06-09 17:29:50 +02001369 SSL_CTX *ssl_ctx = NULL;
1370 struct lru64 *lru = NULL;
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001371 unsigned int key;
Christopher Faulet31af49d2015-06-09 17:29:50 +02001372
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001373 key = ssl_sock_generated_cert_key(servername, strlen(servername));
Christopher Faulet31af49d2015-06-09 17:29:50 +02001374 if (ssl_ctx_lru_tree) {
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001375 lru = lru64_get(key, ssl_ctx_lru_tree, cacert, 0);
Christopher Faulet31af49d2015-06-09 17:29:50 +02001376 if (lru && lru->domain)
1377 ssl_ctx = (SSL_CTX *)lru->data;
Christopher Fauletd2cab922015-07-28 16:03:47 +02001378 if (!ssl_ctx && lru) {
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001379 ssl_ctx = ssl_sock_do_create_cert(servername, bind_conf, ssl);
Christopher Faulet31af49d2015-06-09 17:29:50 +02001380 lru64_commit(lru, ssl_ctx, cacert, 0, (void (*)(void *))SSL_CTX_free);
Christopher Fauletd2cab922015-07-28 16:03:47 +02001381 }
Willy Tarreau2f63ef42015-10-20 15:16:01 +02001382 SSL_set_SSL_CTX(ssl, ssl_ctx);
Christopher Faulet31af49d2015-06-09 17:29:50 +02001383 }
Willy Tarreau2f63ef42015-10-20 15:16:01 +02001384 else {
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001385 ssl_ctx = ssl_sock_do_create_cert(servername, bind_conf, ssl);
Willy Tarreau2f63ef42015-10-20 15:16:01 +02001386 SSL_set_SSL_CTX(ssl, ssl_ctx);
1387 /* No LRU cache, this CTX will be released as soon as the session dies */
1388 SSL_CTX_free(ssl_ctx);
1389 }
Christopher Faulet31af49d2015-06-09 17:29:50 +02001390 return ssl_ctx;
1391}
1392
Emeric Brunfc0421f2012-09-07 17:30:07 +02001393/* Sets the SSL ctx of <ssl> to match the advertised server name. Returns a
1394 * warning when no match is found, which implies the default (first) cert
1395 * will keep being used.
1396 */
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001397static int ssl_sock_switchctx_cbk(SSL *ssl, int *al, struct bind_conf *s)
Emeric Brunfc0421f2012-09-07 17:30:07 +02001398{
1399 const char *servername;
1400 const char *wildp = NULL;
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001401 struct ebmb_node *node, *n;
Emeric Brunfc0421f2012-09-07 17:30:07 +02001402 int i;
1403 (void)al; /* shut gcc stupid warning */
1404
1405 servername = SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name);
Emmanuel Hocdet65623372013-01-24 17:17:15 +01001406 if (!servername) {
Willy Tarreauf6721452015-07-07 18:04:38 +02001407 if (s->generate_certs) {
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02001408 struct connection *conn = SSL_get_app_data(ssl);
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001409 unsigned int key;
Willy Tarreauf6721452015-07-07 18:04:38 +02001410 SSL_CTX *ctx;
Christopher Faulet30548802015-06-11 13:39:32 +02001411
Willy Tarreauf6721452015-07-07 18:04:38 +02001412 conn_get_to_addr(conn);
1413 if (conn->flags & CO_FL_ADDR_TO_SET) {
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001414 key = ssl_sock_generated_cert_key(&conn->addr.to, get_addr_len(&conn->addr.to));
1415 ctx = ssl_sock_get_generated_cert(key, s);
Willy Tarreauf6721452015-07-07 18:04:38 +02001416 if (ctx) {
1417 /* switch ctx */
1418 SSL_set_SSL_CTX(ssl, ctx);
1419 return SSL_TLSEXT_ERR_OK;
1420 }
Christopher Faulet30548802015-06-11 13:39:32 +02001421 }
1422 }
1423
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001424 return (s->strict_sni ?
1425 SSL_TLSEXT_ERR_ALERT_FATAL :
Emmanuel Hocdet79274e22013-05-31 12:47:44 +02001426 SSL_TLSEXT_ERR_NOACK);
Emmanuel Hocdet65623372013-01-24 17:17:15 +01001427 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02001428
Willy Tarreau19d14ef2012-10-29 16:51:55 +01001429 for (i = 0; i < trash.size; i++) {
Emeric Brunfc0421f2012-09-07 17:30:07 +02001430 if (!servername[i])
1431 break;
Willy Tarreau19d14ef2012-10-29 16:51:55 +01001432 trash.str[i] = tolower(servername[i]);
1433 if (!wildp && (trash.str[i] == '.'))
1434 wildp = &trash.str[i];
Emeric Brunfc0421f2012-09-07 17:30:07 +02001435 }
Willy Tarreau19d14ef2012-10-29 16:51:55 +01001436 trash.str[i] = 0;
Emeric Brunfc0421f2012-09-07 17:30:07 +02001437
1438 /* lookup in full qualified names */
Willy Tarreau19d14ef2012-10-29 16:51:55 +01001439 node = ebst_lookup(&s->sni_ctx, trash.str);
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001440
1441 /* lookup a not neg filter */
1442 for (n = node; n; n = ebmb_next_dup(n)) {
1443 if (!container_of(n, struct sni_ctx, name)->neg) {
1444 node = n;
1445 break;
Emmanuel Hocdet65623372013-01-24 17:17:15 +01001446 }
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001447 }
1448 if (!node && wildp) {
1449 /* lookup in wildcards names */
Emeric Brunfc0421f2012-09-07 17:30:07 +02001450 node = ebst_lookup(&s->sni_w_ctx, wildp);
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001451 }
1452 if (!node || container_of(node, struct sni_ctx, name)->neg) {
Christopher Faulet31af49d2015-06-09 17:29:50 +02001453 SSL_CTX *ctx;
Christopher Faulet31af49d2015-06-09 17:29:50 +02001454 if (s->generate_certs &&
Christopher Faulet7969a332015-10-09 11:15:03 +02001455 (ctx = ssl_sock_generate_certificate(servername, s, ssl))) {
Christopher Faulet31af49d2015-06-09 17:29:50 +02001456 /* switch ctx */
Christopher Faulet31af49d2015-06-09 17:29:50 +02001457 return SSL_TLSEXT_ERR_OK;
1458 }
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001459 return (s->strict_sni ?
1460 SSL_TLSEXT_ERR_ALERT_FATAL :
1461 SSL_TLSEXT_ERR_ALERT_WARNING);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001462 }
1463
1464 /* switch ctx */
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001465 SSL_set_SSL_CTX(ssl, container_of(node, struct sni_ctx, name)->ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001466 return SSL_TLSEXT_ERR_OK;
1467}
1468#endif /* SSL_CTRL_SET_TLSEXT_HOSTNAME */
1469
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001470#ifndef OPENSSL_NO_DH
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001471
1472static DH * ssl_get_dh_1024(void)
1473{
Remi Gacogned3a341a2015-05-29 16:26:17 +02001474 static unsigned char dh1024_p[]={
1475 0xFA,0xF9,0x2A,0x22,0x2A,0xA7,0x7F,0xE1,0x67,0x4E,0x53,0xF7,
1476 0x56,0x13,0xC3,0xB1,0xE3,0x29,0x6B,0x66,0x31,0x6A,0x7F,0xB3,
1477 0xC2,0x68,0x6B,0xCB,0x1D,0x57,0x39,0x1D,0x1F,0xFF,0x1C,0xC9,
1478 0xA6,0xA4,0x98,0x82,0x31,0x5D,0x25,0xFF,0x8A,0xE0,0x73,0x96,
1479 0x81,0xC8,0x83,0x79,0xC1,0x5A,0x04,0xF8,0x37,0x0D,0xA8,0x3D,
1480 0xAE,0x74,0xBC,0xDB,0xB6,0xA4,0x75,0xD9,0x71,0x8A,0xA0,0x17,
1481 0x9E,0x2D,0xC8,0xA8,0xDF,0x2C,0x5F,0x82,0x95,0xF8,0x92,0x9B,
1482 0xA7,0x33,0x5F,0x89,0x71,0xC8,0x2D,0x6B,0x18,0x86,0xC4,0x94,
1483 0x22,0xA5,0x52,0x8D,0xF6,0xF6,0xD2,0x37,0x92,0x0F,0xA5,0xCC,
1484 0xDB,0x7B,0x1D,0x3D,0xA1,0x31,0xB7,0x80,0x8F,0x0B,0x67,0x5E,
1485 0x36,0xA5,0x60,0x0C,0xF1,0x95,0x33,0x8B,
1486 };
1487 static unsigned char dh1024_g[]={
1488 0x02,
1489 };
1490
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02001491 BIGNUM *p;
1492 BIGNUM *g;
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001493 DH *dh = DH_new();
1494 if (dh) {
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02001495 p = BN_bin2bn(dh1024_p, sizeof dh1024_p, NULL);
1496 g = BN_bin2bn(dh1024_g, sizeof dh1024_g, NULL);
Remi Gacogned3a341a2015-05-29 16:26:17 +02001497
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02001498 if (!p || !g) {
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001499 DH_free(dh);
1500 dh = NULL;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02001501 } else {
1502 DH_set0_pqg(dh, p, NULL, g);
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001503 }
1504 }
1505 return dh;
1506}
1507
1508static DH *ssl_get_dh_2048(void)
1509{
Remi Gacogned3a341a2015-05-29 16:26:17 +02001510 static unsigned char dh2048_p[]={
1511 0xEC,0x86,0xF8,0x70,0xA0,0x33,0x16,0xEC,0x05,0x1A,0x73,0x59,
1512 0xCD,0x1F,0x8B,0xF8,0x29,0xE4,0xD2,0xCF,0x52,0xDD,0xC2,0x24,
1513 0x8D,0xB5,0x38,0x9A,0xFB,0x5C,0xA4,0xE4,0xB2,0xDA,0xCE,0x66,
1514 0x50,0x74,0xA6,0x85,0x4D,0x4B,0x1D,0x30,0xB8,0x2B,0xF3,0x10,
1515 0xE9,0xA7,0x2D,0x05,0x71,0xE7,0x81,0xDF,0x8B,0x59,0x52,0x3B,
1516 0x5F,0x43,0x0B,0x68,0xF1,0xDB,0x07,0xBE,0x08,0x6B,0x1B,0x23,
1517 0xEE,0x4D,0xCC,0x9E,0x0E,0x43,0xA0,0x1E,0xDF,0x43,0x8C,0xEC,
1518 0xBE,0xBE,0x90,0xB4,0x51,0x54,0xB9,0x2F,0x7B,0x64,0x76,0x4E,
1519 0x5D,0xD4,0x2E,0xAE,0xC2,0x9E,0xAE,0x51,0x43,0x59,0xC7,0x77,
1520 0x9C,0x50,0x3C,0x0E,0xED,0x73,0x04,0x5F,0xF1,0x4C,0x76,0x2A,
1521 0xD8,0xF8,0xCF,0xFC,0x34,0x40,0xD1,0xB4,0x42,0x61,0x84,0x66,
1522 0x42,0x39,0x04,0xF8,0x68,0xB2,0x62,0xD7,0x55,0xED,0x1B,0x74,
1523 0x75,0x91,0xE0,0xC5,0x69,0xC1,0x31,0x5C,0xDB,0x7B,0x44,0x2E,
1524 0xCE,0x84,0x58,0x0D,0x1E,0x66,0x0C,0xC8,0x44,0x9E,0xFD,0x40,
1525 0x08,0x67,0x5D,0xFB,0xA7,0x76,0x8F,0x00,0x11,0x87,0xE9,0x93,
1526 0xF9,0x7D,0xC4,0xBC,0x74,0x55,0x20,0xD4,0x4A,0x41,0x2F,0x43,
1527 0x42,0x1A,0xC1,0xF2,0x97,0x17,0x49,0x27,0x37,0x6B,0x2F,0x88,
1528 0x7E,0x1C,0xA0,0xA1,0x89,0x92,0x27,0xD9,0x56,0x5A,0x71,0xC1,
1529 0x56,0x37,0x7E,0x3A,0x9D,0x05,0xE7,0xEE,0x5D,0x8F,0x82,0x17,
1530 0xBC,0xE9,0xC2,0x93,0x30,0x82,0xF9,0xF4,0xC9,0xAE,0x49,0xDB,
1531 0xD0,0x54,0xB4,0xD9,0x75,0x4D,0xFA,0x06,0xB8,0xD6,0x38,0x41,
1532 0xB7,0x1F,0x77,0xF3,
1533 };
1534 static unsigned char dh2048_g[]={
1535 0x02,
1536 };
1537
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02001538 BIGNUM *p;
1539 BIGNUM *g;
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001540 DH *dh = DH_new();
1541 if (dh) {
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02001542 p = BN_bin2bn(dh2048_p, sizeof dh2048_p, NULL);
1543 g = BN_bin2bn(dh2048_g, sizeof dh2048_g, NULL);
Remi Gacogned3a341a2015-05-29 16:26:17 +02001544
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02001545 if (!p || !g) {
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001546 DH_free(dh);
1547 dh = NULL;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02001548 } else {
1549 DH_set0_pqg(dh, p, NULL, g);
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001550 }
1551 }
1552 return dh;
1553}
1554
1555static DH *ssl_get_dh_4096(void)
1556{
Remi Gacogned3a341a2015-05-29 16:26:17 +02001557 static unsigned char dh4096_p[]={
1558 0xDE,0x16,0x94,0xCD,0x99,0x58,0x07,0xF1,0xF7,0x32,0x96,0x11,
1559 0x04,0x82,0xD4,0x84,0x72,0x80,0x99,0x06,0xCA,0xF0,0xA3,0x68,
1560 0x07,0xCE,0x64,0x50,0xE7,0x74,0x45,0x20,0x80,0x5E,0x4D,0xAD,
1561 0xA5,0xB6,0xED,0xFA,0x80,0x6C,0x3B,0x35,0xC4,0x9A,0x14,0x6B,
1562 0x32,0xBB,0xFD,0x1F,0x17,0x8E,0xB7,0x1F,0xD6,0xFA,0x3F,0x7B,
1563 0xEE,0x16,0xA5,0x62,0x33,0x0D,0xED,0xBC,0x4E,0x58,0xE5,0x47,
1564 0x4D,0xE9,0xAB,0x8E,0x38,0xD3,0x6E,0x90,0x57,0xE3,0x22,0x15,
1565 0x33,0xBD,0xF6,0x43,0x45,0xB5,0x10,0x0A,0xBE,0x2C,0xB4,0x35,
1566 0xB8,0x53,0x8D,0xAD,0xFB,0xA7,0x1F,0x85,0x58,0x41,0x7A,0x79,
1567 0x20,0x68,0xB3,0xE1,0x3D,0x08,0x76,0xBF,0x86,0x0D,0x49,0xE3,
1568 0x82,0x71,0x8C,0xB4,0x8D,0x81,0x84,0xD4,0xE7,0xBE,0x91,0xDC,
1569 0x26,0x39,0x48,0x0F,0x35,0xC4,0xCA,0x65,0xE3,0x40,0x93,0x52,
1570 0x76,0x58,0x7D,0xDD,0x51,0x75,0xDC,0x69,0x61,0xBF,0x47,0x2C,
1571 0x16,0x68,0x2D,0xC9,0x29,0xD3,0xE6,0xC0,0x99,0x48,0xA0,0x9A,
1572 0xC8,0x78,0xC0,0x6D,0x81,0x67,0x12,0x61,0x3F,0x71,0xBA,0x41,
1573 0x1F,0x6C,0x89,0x44,0x03,0xBA,0x3B,0x39,0x60,0xAA,0x28,0x55,
1574 0x59,0xAE,0xB8,0xFA,0xCB,0x6F,0xA5,0x1A,0xF7,0x2B,0xDD,0x52,
1575 0x8A,0x8B,0xE2,0x71,0xA6,0x5E,0x7E,0xD8,0x2E,0x18,0xE0,0x66,
1576 0xDF,0xDD,0x22,0x21,0x99,0x52,0x73,0xA6,0x33,0x20,0x65,0x0E,
1577 0x53,0xE7,0x6B,0x9B,0xC5,0xA3,0x2F,0x97,0x65,0x76,0xD3,0x47,
1578 0x23,0x77,0x12,0xB6,0x11,0x7B,0x24,0xED,0xF1,0xEF,0xC0,0xE2,
1579 0xA3,0x7E,0x67,0x05,0x3E,0x96,0x4D,0x45,0xC2,0x18,0xD1,0x73,
1580 0x9E,0x07,0xF3,0x81,0x6E,0x52,0x63,0xF6,0x20,0x76,0xB9,0x13,
1581 0xD2,0x65,0x30,0x18,0x16,0x09,0x16,0x9E,0x8F,0xF1,0xD2,0x10,
1582 0x5A,0xD3,0xD4,0xAF,0x16,0x61,0xDA,0x55,0x2E,0x18,0x5E,0x14,
1583 0x08,0x54,0x2E,0x2A,0x25,0xA2,0x1A,0x9B,0x8B,0x32,0xA9,0xFD,
1584 0xC2,0x48,0x96,0xE1,0x80,0xCA,0xE9,0x22,0x17,0xBB,0xCE,0x3E,
1585 0x9E,0xED,0xC7,0xF1,0x1F,0xEC,0x17,0x21,0xDC,0x7B,0x82,0x48,
1586 0x8E,0xBB,0x4B,0x9D,0x5B,0x04,0x04,0xDA,0xDB,0x39,0xDF,0x01,
1587 0x40,0xC3,0xAA,0x26,0x23,0x89,0x75,0xC6,0x0B,0xD0,0xA2,0x60,
1588 0x6A,0xF1,0xCC,0x65,0x18,0x98,0x1B,0x52,0xD2,0x74,0x61,0xCC,
1589 0xBD,0x60,0xAE,0xA3,0xA0,0x66,0x6A,0x16,0x34,0x92,0x3F,0x41,
1590 0x40,0x31,0x29,0xC0,0x2C,0x63,0xB2,0x07,0x8D,0xEB,0x94,0xB8,
1591 0xE8,0x47,0x92,0x52,0x93,0x6A,0x1B,0x7E,0x1A,0x61,0xB3,0x1B,
1592 0xF0,0xD6,0x72,0x9B,0xF1,0xB0,0xAF,0xBF,0x3E,0x65,0xEF,0x23,
1593 0x1D,0x6F,0xFF,0x70,0xCD,0x8A,0x4C,0x8A,0xA0,0x72,0x9D,0xBE,
1594 0xD4,0xBB,0x24,0x47,0x4A,0x68,0xB5,0xF5,0xC6,0xD5,0x7A,0xCD,
1595 0xCA,0x06,0x41,0x07,0xAD,0xC2,0x1E,0xE6,0x54,0xA7,0xAD,0x03,
1596 0xD9,0x12,0xC1,0x9C,0x13,0xB1,0xC9,0x0A,0x43,0x8E,0x1E,0x08,
1597 0xCE,0x50,0x82,0x73,0x5F,0xA7,0x55,0x1D,0xD9,0x59,0xAC,0xB5,
1598 0xEA,0x02,0x7F,0x6C,0x5B,0x74,0x96,0x98,0x67,0x24,0xA3,0x0F,
1599 0x15,0xFC,0xA9,0x7D,0x3E,0x67,0xD1,0x70,0xF8,0x97,0xF3,0x67,
1600 0xC5,0x8C,0x88,0x44,0x08,0x02,0xC7,0x2B,
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001601 };
Remi Gacogned3a341a2015-05-29 16:26:17 +02001602 static unsigned char dh4096_g[]={
1603 0x02,
1604 };
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001605
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02001606 BIGNUM *p;
1607 BIGNUM *g;
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001608 DH *dh = DH_new();
1609 if (dh) {
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02001610 p = BN_bin2bn(dh4096_p, sizeof dh4096_p, NULL);
1611 g = BN_bin2bn(dh4096_g, sizeof dh4096_g, NULL);
Remi Gacogned3a341a2015-05-29 16:26:17 +02001612
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02001613 if (!p || !g) {
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001614 DH_free(dh);
1615 dh = NULL;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02001616 } else {
1617 DH_set0_pqg(dh, p, NULL, g);
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001618 }
1619 }
1620 return dh;
1621}
1622
1623/* Returns Diffie-Hellman parameters matching the private key length
1624 but not exceeding global.tune.ssl_default_dh_param */
1625static DH *ssl_get_tmp_dh(SSL *ssl, int export, int keylen)
1626{
1627 DH *dh = NULL;
1628 EVP_PKEY *pkey = SSL_get_privatekey(ssl);
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02001629 int type;
1630
1631 type = pkey ? EVP_PKEY_base_id(pkey) : EVP_PKEY_NONE;
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001632
1633 /* The keylen supplied by OpenSSL can only be 512 or 1024.
1634 See ssl3_send_server_key_exchange() in ssl/s3_srvr.c
1635 */
1636 if (type == EVP_PKEY_RSA || type == EVP_PKEY_DSA) {
1637 keylen = EVP_PKEY_bits(pkey);
1638 }
1639
1640 if (keylen > global.tune.ssl_default_dh_param) {
1641 keylen = global.tune.ssl_default_dh_param;
1642 }
1643
Remi Gacogned3a341a2015-05-29 16:26:17 +02001644 if (keylen >= 4096) {
Remi Gacogne8de54152014-07-15 11:36:40 +02001645 dh = local_dh_4096;
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001646 }
1647 else if (keylen >= 2048) {
Remi Gacogne8de54152014-07-15 11:36:40 +02001648 dh = local_dh_2048;
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001649 }
1650 else {
Remi Gacogne8de54152014-07-15 11:36:40 +02001651 dh = local_dh_1024;
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001652 }
1653
1654 return dh;
1655}
1656
Remi Gacogne47783ef2015-05-29 15:53:22 +02001657static DH * ssl_sock_get_dh_from_file(const char *filename)
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001658{
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001659 DH *dh = NULL;
Remi Gacogne47783ef2015-05-29 15:53:22 +02001660 BIO *in = BIO_new(BIO_s_file());
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001661
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001662 if (in == NULL)
1663 goto end;
1664
Remi Gacogne47783ef2015-05-29 15:53:22 +02001665 if (BIO_read_filename(in, filename) <= 0)
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001666 goto end;
1667
Remi Gacogne47783ef2015-05-29 15:53:22 +02001668 dh = PEM_read_bio_DHparams(in, NULL, NULL, NULL);
1669
1670end:
1671 if (in)
1672 BIO_free(in);
1673
1674 return dh;
1675}
1676
1677int ssl_sock_load_global_dh_param_from_file(const char *filename)
1678{
1679 global_dh = ssl_sock_get_dh_from_file(filename);
1680
1681 if (global_dh) {
1682 return 0;
1683 }
1684
1685 return -1;
1686}
1687
1688/* Loads Diffie-Hellman parameter from a file. Returns 1 if loaded, else -1
1689 if an error occured, and 0 if parameter not found. */
1690int ssl_sock_load_dh_params(SSL_CTX *ctx, const char *file)
1691{
1692 int ret = -1;
1693 DH *dh = ssl_sock_get_dh_from_file(file);
1694
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001695 if (dh) {
1696 ret = 1;
1697 SSL_CTX_set_tmp_dh(ctx, dh);
Remi Gacogne4f902b82015-05-28 16:23:00 +02001698
1699 if (ssl_dh_ptr_index >= 0) {
1700 /* store a pointer to the DH params to avoid complaining about
1701 ssl-default-dh-param not being set for this SSL_CTX */
1702 SSL_CTX_set_ex_data(ctx, ssl_dh_ptr_index, dh);
1703 }
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001704 }
Remi Gacogne47783ef2015-05-29 15:53:22 +02001705 else if (global_dh) {
1706 SSL_CTX_set_tmp_dh(ctx, global_dh);
1707 ret = 0; /* DH params not found */
1708 }
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001709 else {
Emeric Brun41fdb3c2013-04-26 11:05:44 +02001710 /* Clear openssl global errors stack */
1711 ERR_clear_error();
1712
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001713 if (global.tune.ssl_default_dh_param <= 1024) {
1714 /* we are limited to DH parameter of 1024 bits anyway */
Remi Gacognec7e12632016-07-02 16:26:10 +02001715 if (local_dh_1024 == NULL)
1716 local_dh_1024 = ssl_get_dh_1024();
1717
Remi Gacogne8de54152014-07-15 11:36:40 +02001718 if (local_dh_1024 == NULL)
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001719 goto end;
Willy Tarreau6e774b42014-04-25 21:35:23 +02001720
Remi Gacogne8de54152014-07-15 11:36:40 +02001721 SSL_CTX_set_tmp_dh(ctx, local_dh_1024);
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001722 }
1723 else {
1724 SSL_CTX_set_tmp_dh_callback(ctx, ssl_get_tmp_dh);
1725 }
Willy Tarreau6e774b42014-04-25 21:35:23 +02001726
Emeric Brun41fdb3c2013-04-26 11:05:44 +02001727 ret = 0; /* DH params not found */
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001728 }
Emeric Brun644cde02012-12-14 11:21:13 +01001729
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001730end:
1731 if (dh)
1732 DH_free(dh);
1733
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001734 return ret;
1735}
1736#endif
1737
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001738static int ssl_sock_add_cert_sni(SSL_CTX *ctx, struct bind_conf *s, char *name, int order)
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001739{
1740 struct sni_ctx *sc;
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001741 int wild = 0, neg = 0;
Thierry FOURNIER / OZON.IO07c3d782016-10-06 10:56:48 +02001742 struct ebmb_node *node;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001743
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001744 if (*name == '!') {
1745 neg = 1;
1746 name++;
1747 }
1748 if (*name == '*') {
1749 wild = 1;
1750 name++;
1751 }
1752 /* !* filter is a nop */
1753 if (neg && wild)
1754 return order;
1755 if (*name) {
1756 int j, len;
1757 len = strlen(name);
Thierry FOURNIER / OZON.IO07c3d782016-10-06 10:56:48 +02001758 for (j = 0; j < len && j < trash.size; j++)
1759 trash.str[j] = tolower(name[j]);
1760 if (j >= trash.size)
1761 return order;
1762 trash.str[j] = 0;
1763
1764 /* Check for duplicates. */
1765 if (wild)
1766 node = ebst_lookup(&s->sni_w_ctx, trash.str);
1767 else
1768 node = ebst_lookup(&s->sni_ctx, trash.str);
1769 for (; node; node = ebmb_next_dup(node)) {
1770 sc = ebmb_entry(node, struct sni_ctx, name);
1771 if (sc->ctx == ctx && sc->neg == neg)
1772 return order;
1773 }
1774
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001775 sc = malloc(sizeof(struct sni_ctx) + len + 1);
Thierry FOURNIER / OZON.IO7a3bd3b2016-10-06 10:35:29 +02001776 if (!sc)
1777 return order;
Thierry FOURNIER / OZON.IO07c3d782016-10-06 10:56:48 +02001778 memcpy(sc->name.key, trash.str, len + 1);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001779 sc->ctx = ctx;
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001780 sc->order = order++;
1781 sc->neg = neg;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001782 if (wild)
1783 ebst_insert(&s->sni_w_ctx, &sc->name);
1784 else
1785 ebst_insert(&s->sni_ctx, &sc->name);
1786 }
1787 return order;
1788}
1789
yanbzhu488a4d22015-12-01 15:16:07 -05001790
1791/* The following code is used for loading multiple crt files into
1792 * SSL_CTX's based on CN/SAN
1793 */
Luca Pizzamiglio578b1692016-12-12 10:56:56 +01001794#if OPENSSL_VERSION_NUMBER >= 0x1000200fL && !defined(LIBRESSL_VERSION_NUMBER)
yanbzhu488a4d22015-12-01 15:16:07 -05001795/* This is used to preload the certifcate, private key
1796 * and Cert Chain of a file passed in via the crt
1797 * argument
1798 *
1799 * This way, we do not have to read the file multiple times
1800 */
1801struct cert_key_and_chain {
1802 X509 *cert;
1803 EVP_PKEY *key;
1804 unsigned int num_chain_certs;
1805 /* This is an array of X509 pointers */
1806 X509 **chain_certs;
1807};
1808
yanbzhu08ce6ab2015-12-02 13:01:29 -05001809#define SSL_SOCK_POSSIBLE_KT_COMBOS (1<<(SSL_SOCK_NUM_KEYTYPES))
1810
1811struct key_combo_ctx {
1812 SSL_CTX *ctx;
1813 int order;
1814};
1815
1816/* Map used for processing multiple keypairs for a single purpose
1817 *
1818 * This maps CN/SNI name to certificate type
1819 */
1820struct sni_keytype {
1821 int keytypes; /* BITMASK for keytypes */
1822 struct ebmb_node name; /* node holding the servername value */
1823};
1824
1825
yanbzhu488a4d22015-12-01 15:16:07 -05001826/* Frees the contents of a cert_key_and_chain
1827 */
1828static void ssl_sock_free_cert_key_and_chain_contents(struct cert_key_and_chain *ckch)
1829{
1830 int i;
1831
1832 if (!ckch)
1833 return;
1834
1835 /* Free the certificate and set pointer to NULL */
1836 if (ckch->cert)
1837 X509_free(ckch->cert);
1838 ckch->cert = NULL;
1839
1840 /* Free the key and set pointer to NULL */
1841 if (ckch->key)
1842 EVP_PKEY_free(ckch->key);
1843 ckch->key = NULL;
1844
1845 /* Free each certificate in the chain */
1846 for (i = 0; i < ckch->num_chain_certs; i++) {
1847 if (ckch->chain_certs[i])
1848 X509_free(ckch->chain_certs[i]);
1849 }
1850
1851 /* Free the chain obj itself and set to NULL */
1852 if (ckch->num_chain_certs > 0) {
1853 free(ckch->chain_certs);
1854 ckch->num_chain_certs = 0;
1855 ckch->chain_certs = NULL;
1856 }
1857
1858}
1859
1860/* checks if a key and cert exists in the ckch
1861 */
1862static int ssl_sock_is_ckch_valid(struct cert_key_and_chain *ckch)
1863{
1864 return (ckch->cert != NULL && ckch->key != NULL);
1865}
1866
1867
1868/* Loads the contents of a crt file (path) into a cert_key_and_chain
1869 * This allows us to carry the contents of the file without having to
1870 * read the file multiple times.
1871 *
1872 * returns:
1873 * 0 on Success
1874 * 1 on SSL Failure
1875 * 2 on file not found
1876 */
1877static int ssl_sock_load_crt_file_into_ckch(const char *path, struct cert_key_and_chain *ckch, char **err)
1878{
1879
1880 BIO *in;
1881 X509 *ca = NULL;
1882 int ret = 1;
1883
1884 ssl_sock_free_cert_key_and_chain_contents(ckch);
1885
1886 in = BIO_new(BIO_s_file());
1887 if (in == NULL)
1888 goto end;
1889
1890 if (BIO_read_filename(in, path) <= 0)
1891 goto end;
1892
yanbzhu488a4d22015-12-01 15:16:07 -05001893 /* Read Private Key */
1894 ckch->key = PEM_read_bio_PrivateKey(in, NULL, NULL, NULL);
1895 if (ckch->key == NULL) {
1896 memprintf(err, "%sunable to load private key from file '%s'.\n",
1897 err && *err ? *err : "", path);
1898 goto end;
1899 }
1900
Willy Tarreaubb137a82016-04-06 19:02:38 +02001901 /* Seek back to beginning of file */
Thierry FOURNIER / OZON.IOd44ea3f2016-10-14 00:49:21 +02001902 if (BIO_reset(in) == -1) {
1903 memprintf(err, "%san error occurred while reading the file '%s'.\n",
1904 err && *err ? *err : "", path);
1905 goto end;
1906 }
Willy Tarreaubb137a82016-04-06 19:02:38 +02001907
1908 /* Read Certificate */
1909 ckch->cert = PEM_read_bio_X509_AUX(in, NULL, NULL, NULL);
1910 if (ckch->cert == NULL) {
1911 memprintf(err, "%sunable to load certificate from file '%s'.\n",
1912 err && *err ? *err : "", path);
1913 goto end;
1914 }
1915
yanbzhu488a4d22015-12-01 15:16:07 -05001916 /* Read Certificate Chain */
1917 while ((ca = PEM_read_bio_X509(in, NULL, NULL, NULL))) {
1918 /* Grow the chain certs */
1919 ckch->num_chain_certs++;
1920 ckch->chain_certs = realloc(ckch->chain_certs, (ckch->num_chain_certs * sizeof(X509 *)));
1921
1922 /* use - 1 here since we just incremented it above */
1923 ckch->chain_certs[ckch->num_chain_certs - 1] = ca;
1924 }
1925 ret = ERR_get_error();
1926 if (ret && (ERR_GET_LIB(ret) != ERR_LIB_PEM && ERR_GET_REASON(ret) != PEM_R_NO_START_LINE)) {
1927 memprintf(err, "%sunable to load certificate chain from file '%s'.\n",
1928 err && *err ? *err : "", path);
1929 ret = 1;
1930 goto end;
1931 }
1932
1933 ret = 0;
1934
1935end:
1936
1937 ERR_clear_error();
1938 if (in)
1939 BIO_free(in);
1940
1941 /* Something went wrong in one of the reads */
1942 if (ret != 0)
1943 ssl_sock_free_cert_key_and_chain_contents(ckch);
1944
1945 return ret;
1946}
1947
1948/* Loads the info in ckch into ctx
1949 * Currently, this does not process any information about ocsp, dhparams or
1950 * sctl
1951 * Returns
1952 * 0 on success
1953 * 1 on failure
1954 */
1955static int ssl_sock_put_ckch_into_ctx(const char *path, const struct cert_key_and_chain *ckch, SSL_CTX *ctx, char **err)
1956{
1957 int i = 0;
1958
1959 if (SSL_CTX_use_PrivateKey(ctx, ckch->key) <= 0) {
1960 memprintf(err, "%sunable to load SSL private key into SSL Context '%s'.\n",
1961 err && *err ? *err : "", path);
1962 return 1;
1963 }
1964
1965 if (!SSL_CTX_use_certificate(ctx, ckch->cert)) {
1966 memprintf(err, "%sunable to load SSL certificate into SSL Context '%s'.\n",
1967 err && *err ? *err : "", path);
1968 return 1;
1969 }
1970
yanbzhu488a4d22015-12-01 15:16:07 -05001971 /* Load all certs in the ckch into the ctx_chain for the ssl_ctx */
1972 for (i = 0; i < ckch->num_chain_certs; i++) {
1973 if (!SSL_CTX_add1_chain_cert(ctx, ckch->chain_certs[i])) {
yanbzhu08ce6ab2015-12-02 13:01:29 -05001974 memprintf(err, "%sunable to load chain certificate #%d into SSL Context '%s'. Make sure you are linking against Openssl >= 1.0.2.\n",
1975 err && *err ? *err : "", (i+1), path);
yanbzhu488a4d22015-12-01 15:16:07 -05001976 return 1;
1977 }
1978 }
1979
1980 if (SSL_CTX_check_private_key(ctx) <= 0) {
1981 memprintf(err, "%sinconsistencies between private key and certificate loaded from PEM file '%s'.\n",
1982 err && *err ? *err : "", path);
1983 return 1;
1984 }
1985
1986 return 0;
1987}
1988
yanbzhu08ce6ab2015-12-02 13:01:29 -05001989
1990static void ssl_sock_populate_sni_keytypes_hplr(const char *str, struct eb_root *sni_keytypes, int key_index)
1991{
1992 struct sni_keytype *s_kt = NULL;
1993 struct ebmb_node *node;
1994 int i;
1995
1996 for (i = 0; i < trash.size; i++) {
1997 if (!str[i])
1998 break;
1999 trash.str[i] = tolower(str[i]);
2000 }
2001 trash.str[i] = 0;
2002 node = ebst_lookup(sni_keytypes, trash.str);
2003 if (!node) {
2004 /* CN not found in tree */
2005 s_kt = malloc(sizeof(struct sni_keytype) + i + 1);
2006 /* Using memcpy here instead of strncpy.
2007 * strncpy will cause sig_abrt errors under certain versions of gcc with -O2
2008 * See: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=60792
2009 */
2010 memcpy(s_kt->name.key, trash.str, i+1);
2011 s_kt->keytypes = 0;
2012 ebst_insert(sni_keytypes, &s_kt->name);
2013 } else {
2014 /* CN found in tree */
2015 s_kt = container_of(node, struct sni_keytype, name);
2016 }
2017
2018 /* Mark that this CN has the keytype of key_index via keytypes mask */
2019 s_kt->keytypes |= 1<<key_index;
2020
2021}
2022
2023
2024/* Given a path that does not exist, try to check for path.rsa, path.dsa and path.ecdsa files.
2025 * If any are found, group these files into a set of SSL_CTX*
2026 * based on shared and unique CN and SAN entries. Add these SSL_CTX* to the SNI tree.
2027 *
2028 * This will allow the user to explictly group multiple cert/keys for a single purpose
2029 *
2030 * Returns
2031 * 0 on success
2032 * 1 on failure
2033 */
Willy Tarreau03209342016-12-22 17:08:28 +01002034static int ssl_sock_load_multi_cert(const char *path, struct bind_conf *bind_conf, char **sni_filter, int fcount, char **err)
yanbzhu08ce6ab2015-12-02 13:01:29 -05002035{
2036 char fp[MAXPATHLEN+1] = {0};
2037 int n = 0;
2038 int i = 0;
2039 struct cert_key_and_chain certs_and_keys[SSL_SOCK_NUM_KEYTYPES] = { {0} };
2040 struct eb_root sni_keytypes_map = { {0} };
2041 struct ebmb_node *node;
2042 struct ebmb_node *next;
2043 /* Array of SSL_CTX pointers corresponding to each possible combo
2044 * of keytypes
2045 */
2046 struct key_combo_ctx key_combos[SSL_SOCK_POSSIBLE_KT_COMBOS] = { {0} };
2047 int rv = 0;
2048 X509_NAME *xname = NULL;
2049 char *str = NULL;
2050#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
2051 STACK_OF(GENERAL_NAME) *names = NULL;
2052#endif
2053
2054 /* Load all possible certs and keys */
2055 for (n = 0; n < SSL_SOCK_NUM_KEYTYPES; n++) {
2056 struct stat buf;
2057
2058 snprintf(fp, sizeof(fp), "%s.%s", path, SSL_SOCK_KEYTYPE_NAMES[n]);
2059 if (stat(fp, &buf) == 0) {
2060 if (ssl_sock_load_crt_file_into_ckch(fp, &certs_and_keys[n], err) == 1) {
2061 rv = 1;
2062 goto end;
2063 }
2064 }
2065 }
2066
2067 /* Process each ckch and update keytypes for each CN/SAN
2068 * for example, if CN/SAN www.a.com is associated with
2069 * certs with keytype 0 and 2, then at the end of the loop,
2070 * www.a.com will have:
2071 * keyindex = 0 | 1 | 4 = 5
2072 */
2073 for (n = 0; n < SSL_SOCK_NUM_KEYTYPES; n++) {
2074
2075 if (!ssl_sock_is_ckch_valid(&certs_and_keys[n]))
2076 continue;
2077
Emmanuel Hocdetd294aea2016-05-13 11:14:06 +02002078 if (fcount) {
Willy Tarreau24b892f2016-06-20 23:01:57 +02002079 for (i = 0; i < fcount; i++)
Emmanuel Hocdetd294aea2016-05-13 11:14:06 +02002080 ssl_sock_populate_sni_keytypes_hplr(sni_filter[i], &sni_keytypes_map, n);
2081 } else {
2082 /* A lot of the following code is OpenSSL boilerplate for processing CN's and SAN's,
2083 * so the line that contains logic is marked via comments
2084 */
2085 xname = X509_get_subject_name(certs_and_keys[n].cert);
2086 i = -1;
2087 while ((i = X509_NAME_get_index_by_NID(xname, NID_commonName, i)) != -1) {
2088 X509_NAME_ENTRY *entry = X509_NAME_get_entry(xname, i);
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02002089 ASN1_STRING *value;
2090 value = X509_NAME_ENTRY_get_data(entry);
2091 if (ASN1_STRING_to_UTF8((unsigned char **)&str, value) >= 0) {
Emmanuel Hocdetd294aea2016-05-13 11:14:06 +02002092 /* Important line is here */
2093 ssl_sock_populate_sni_keytypes_hplr(str, &sni_keytypes_map, n);
yanbzhu08ce6ab2015-12-02 13:01:29 -05002094
Emmanuel Hocdetd294aea2016-05-13 11:14:06 +02002095 OPENSSL_free(str);
2096 str = NULL;
2097 }
yanbzhu08ce6ab2015-12-02 13:01:29 -05002098 }
yanbzhu08ce6ab2015-12-02 13:01:29 -05002099
Emmanuel Hocdetd294aea2016-05-13 11:14:06 +02002100 /* Do the above logic for each SAN */
yanbzhu08ce6ab2015-12-02 13:01:29 -05002101#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Emmanuel Hocdetd294aea2016-05-13 11:14:06 +02002102 names = X509_get_ext_d2i(certs_and_keys[n].cert, NID_subject_alt_name, NULL, NULL);
2103 if (names) {
2104 for (i = 0; i < sk_GENERAL_NAME_num(names); i++) {
2105 GENERAL_NAME *name = sk_GENERAL_NAME_value(names, i);
yanbzhu08ce6ab2015-12-02 13:01:29 -05002106
Emmanuel Hocdetd294aea2016-05-13 11:14:06 +02002107 if (name->type == GEN_DNS) {
2108 if (ASN1_STRING_to_UTF8((unsigned char **)&str, name->d.dNSName) >= 0) {
2109 /* Important line is here */
2110 ssl_sock_populate_sni_keytypes_hplr(str, &sni_keytypes_map, n);
yanbzhu08ce6ab2015-12-02 13:01:29 -05002111
Emmanuel Hocdetd294aea2016-05-13 11:14:06 +02002112 OPENSSL_free(str);
2113 str = NULL;
2114 }
yanbzhu08ce6ab2015-12-02 13:01:29 -05002115 }
2116 }
2117 }
2118 }
2119#endif /* SSL_CTRL_SET_TLSEXT_HOSTNAME */
2120 }
2121
2122 /* If no files found, return error */
2123 if (eb_is_empty(&sni_keytypes_map)) {
2124 memprintf(err, "%sunable to load SSL certificate file '%s' file does not exist.\n",
2125 err && *err ? *err : "", path);
2126 rv = 1;
2127 goto end;
2128 }
2129
2130 /* We now have a map of CN/SAN to keytypes that are loaded in
2131 * Iterate through the map to create the SSL_CTX's (if needed)
2132 * and add each CTX to the SNI tree
2133 *
2134 * Some math here:
2135 * There are 2^n - 1 possibile combinations, each unique
2136 * combination is denoted by the key in the map. Each key
2137 * has a value between 1 and 2^n - 1. Conveniently, the array
2138 * of SSL_CTX* is sized 2^n. So, we can simply use the i'th
2139 * entry in the array to correspond to the unique combo (key)
2140 * associated with i. This unique key combo (i) will be associated
2141 * with combos[i-1]
2142 */
2143
2144 node = ebmb_first(&sni_keytypes_map);
2145 while (node) {
2146 SSL_CTX *cur_ctx;
Bertrand Jacquin33423092016-11-13 16:37:13 +00002147 char cur_file[MAXPATHLEN+1];
yanbzhu08ce6ab2015-12-02 13:01:29 -05002148
2149 str = (char *)container_of(node, struct sni_keytype, name)->name.key;
2150 i = container_of(node, struct sni_keytype, name)->keytypes;
2151 cur_ctx = key_combos[i-1].ctx;
2152
2153 if (cur_ctx == NULL) {
2154 /* need to create SSL_CTX */
2155 cur_ctx = SSL_CTX_new(SSLv23_server_method());
2156 if (cur_ctx == NULL) {
2157 memprintf(err, "%sunable to allocate SSL context.\n",
2158 err && *err ? *err : "");
2159 rv = 1;
2160 goto end;
2161 }
2162
yanbzhube2774d2015-12-10 15:07:30 -05002163 /* Load all required certs/keys/chains/OCSPs info into SSL_CTX */
yanbzhu08ce6ab2015-12-02 13:01:29 -05002164 for (n = 0; n < SSL_SOCK_NUM_KEYTYPES; n++) {
2165 if (i & (1<<n)) {
2166 /* Key combo contains ckch[n] */
Bertrand Jacquin33423092016-11-13 16:37:13 +00002167 snprintf(cur_file, MAXPATHLEN+1, "%s.%s", path, SSL_SOCK_KEYTYPE_NAMES[n]);
2168 if (ssl_sock_put_ckch_into_ctx(cur_file, &certs_and_keys[n], cur_ctx, err) != 0) {
yanbzhu08ce6ab2015-12-02 13:01:29 -05002169 SSL_CTX_free(cur_ctx);
2170 rv = 1;
2171 goto end;
2172 }
yanbzhube2774d2015-12-10 15:07:30 -05002173
2174#if (defined SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB && !defined OPENSSL_NO_OCSP)
2175 /* Load OCSP Info into context */
Bertrand Jacquin33423092016-11-13 16:37:13 +00002176 if (ssl_sock_load_ocsp(cur_ctx, cur_file) < 0) {
yanbzhube2774d2015-12-10 15:07:30 -05002177 if (err)
2178 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 +00002179 *err ? *err : "", cur_file);
yanbzhube2774d2015-12-10 15:07:30 -05002180 SSL_CTX_free(cur_ctx);
2181 rv = 1;
2182 goto end;
2183 }
2184#endif
yanbzhu08ce6ab2015-12-02 13:01:29 -05002185 }
2186 }
2187
2188 /* Load DH params into the ctx to support DHE keys */
2189#ifndef OPENSSL_NO_DH
2190 if (ssl_dh_ptr_index >= 0)
2191 SSL_CTX_set_ex_data(cur_ctx, ssl_dh_ptr_index, NULL);
2192
2193 rv = ssl_sock_load_dh_params(cur_ctx, NULL);
2194 if (rv < 0) {
2195 if (err)
2196 memprintf(err, "%sunable to load DH parameters from file '%s'.\n",
2197 *err ? *err : "", path);
2198 rv = 1;
2199 goto end;
2200 }
2201#endif
2202
2203 /* Update key_combos */
2204 key_combos[i-1].ctx = cur_ctx;
2205 }
2206
2207 /* Update SNI Tree */
Emmanuel Hocdetd294aea2016-05-13 11:14:06 +02002208 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 -05002209 node = ebmb_next(node);
2210 }
2211
2212
2213 /* Mark a default context if none exists, using the ctx that has the most shared keys */
2214 if (!bind_conf->default_ctx) {
2215 for (i = SSL_SOCK_POSSIBLE_KT_COMBOS - 1; i >= 0; i--) {
2216 if (key_combos[i].ctx) {
2217 bind_conf->default_ctx = key_combos[i].ctx;
2218 break;
2219 }
2220 }
2221 }
2222
2223end:
2224
2225 if (names)
2226 sk_GENERAL_NAME_pop_free(names, GENERAL_NAME_free);
2227
2228 for (n = 0; n < SSL_SOCK_NUM_KEYTYPES; n++)
2229 ssl_sock_free_cert_key_and_chain_contents(&certs_and_keys[n]);
2230
2231 node = ebmb_first(&sni_keytypes_map);
2232 while (node) {
2233 next = ebmb_next(node);
2234 ebmb_delete(node);
2235 node = next;
2236 }
2237
2238 return rv;
2239}
2240#else
2241/* This is a dummy, that just logs an error and returns error */
Willy Tarreau03209342016-12-22 17:08:28 +01002242static int ssl_sock_load_multi_cert(const char *path, struct bind_conf *bind_conf, char **sni_filter, int fcount, char **err)
yanbzhu08ce6ab2015-12-02 13:01:29 -05002243{
2244 memprintf(err, "%sunable to stat SSL certificate from file '%s' : %s.\n",
2245 err && *err ? *err : "", path, strerror(errno));
2246 return 1;
2247}
2248
yanbzhu488a4d22015-12-01 15:16:07 -05002249#endif /* #if OPENSSL_VERSION_NUMBER >= 0x1000200fL: Support for loading multiple certs into a single SSL_CTX */
2250
Emeric Brunfc0421f2012-09-07 17:30:07 +02002251/* Loads a certificate key and CA chain from a file. Returns 0 on error, -1 if
2252 * an early error happens and the caller must call SSL_CTX_free() by itelf.
2253 */
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02002254static 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 +02002255{
2256 BIO *in;
2257 X509 *x = NULL, *ca;
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02002258 int i, err;
Emeric Brunfc0421f2012-09-07 17:30:07 +02002259 int ret = -1;
2260 int order = 0;
2261 X509_NAME *xname;
2262 char *str;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02002263 pem_password_cb *passwd_cb;
2264 void *passwd_cb_userdata;
2265
Emeric Brunfc0421f2012-09-07 17:30:07 +02002266#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
2267 STACK_OF(GENERAL_NAME) *names;
2268#endif
2269
2270 in = BIO_new(BIO_s_file());
2271 if (in == NULL)
2272 goto end;
2273
2274 if (BIO_read_filename(in, file) <= 0)
2275 goto end;
2276
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02002277
2278 passwd_cb = SSL_CTX_get_default_passwd_cb(ctx);
2279 passwd_cb_userdata = SSL_CTX_get_default_passwd_cb_userdata(ctx);
2280
2281 x = PEM_read_bio_X509_AUX(in, NULL, passwd_cb, passwd_cb_userdata);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002282 if (x == NULL)
2283 goto end;
2284
Emeric Brun50bcecc2013-04-22 13:05:23 +02002285 if (fcount) {
2286 while (fcount--)
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02002287 order = ssl_sock_add_cert_sni(ctx, s, sni_filter[fcount], order);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002288 }
2289 else {
Emeric Brunfc0421f2012-09-07 17:30:07 +02002290#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002291 names = X509_get_ext_d2i(x, NID_subject_alt_name, NULL, NULL);
2292 if (names) {
2293 for (i = 0; i < sk_GENERAL_NAME_num(names); i++) {
2294 GENERAL_NAME *name = sk_GENERAL_NAME_value(names, i);
2295 if (name->type == GEN_DNS) {
2296 if (ASN1_STRING_to_UTF8((unsigned char **)&str, name->d.dNSName) >= 0) {
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02002297 order = ssl_sock_add_cert_sni(ctx, s, str, order);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002298 OPENSSL_free(str);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002299 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02002300 }
2301 }
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002302 sk_GENERAL_NAME_pop_free(names, GENERAL_NAME_free);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002303 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02002304#endif /* SSL_CTRL_SET_TLSEXT_HOSTNAME */
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002305 xname = X509_get_subject_name(x);
2306 i = -1;
2307 while ((i = X509_NAME_get_index_by_NID(xname, NID_commonName, i)) != -1) {
2308 X509_NAME_ENTRY *entry = X509_NAME_get_entry(xname, i);
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02002309 ASN1_STRING *value;
2310
2311 value = X509_NAME_ENTRY_get_data(entry);
2312 if (ASN1_STRING_to_UTF8((unsigned char **)&str, value) >= 0) {
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02002313 order = ssl_sock_add_cert_sni(ctx, s, str, order);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002314 OPENSSL_free(str);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002315 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02002316 }
2317 }
2318
2319 ret = 0; /* the caller must not free the SSL_CTX argument anymore */
2320 if (!SSL_CTX_use_certificate(ctx, x))
2321 goto end;
2322
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02002323#ifdef SSL_CTX_clear_extra_chain_certs
2324 SSL_CTX_clear_extra_chain_certs(ctx);
2325#else
Emeric Brunfc0421f2012-09-07 17:30:07 +02002326 if (ctx->extra_certs != NULL) {
2327 sk_X509_pop_free(ctx->extra_certs, X509_free);
2328 ctx->extra_certs = NULL;
2329 }
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02002330#endif
Emeric Brunfc0421f2012-09-07 17:30:07 +02002331
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02002332 while ((ca = PEM_read_bio_X509(in, NULL, passwd_cb, passwd_cb_userdata))) {
Emeric Brunfc0421f2012-09-07 17:30:07 +02002333 if (!SSL_CTX_add_extra_chain_cert(ctx, ca)) {
2334 X509_free(ca);
2335 goto end;
2336 }
2337 }
2338
2339 err = ERR_get_error();
2340 if (!err || (ERR_GET_LIB(err) == ERR_LIB_PEM && ERR_GET_REASON(err) == PEM_R_NO_START_LINE)) {
2341 /* we successfully reached the last cert in the file */
2342 ret = 1;
2343 }
2344 ERR_clear_error();
2345
2346end:
2347 if (x)
2348 X509_free(x);
2349
2350 if (in)
2351 BIO_free(in);
2352
2353 return ret;
2354}
2355
Willy Tarreau03209342016-12-22 17:08:28 +01002356static int ssl_sock_load_cert_file(const char *path, struct bind_conf *bind_conf, char **sni_filter, int fcount, char **err)
Emeric Brunfc0421f2012-09-07 17:30:07 +02002357{
2358 int ret;
2359 SSL_CTX *ctx;
2360
2361 ctx = SSL_CTX_new(SSLv23_server_method());
2362 if (!ctx) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02002363 memprintf(err, "%sunable to allocate SSL context for cert '%s'.\n",
2364 err && *err ? *err : "", path);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002365 return 1;
2366 }
2367
2368 if (SSL_CTX_use_PrivateKey_file(ctx, path, SSL_FILETYPE_PEM) <= 0) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02002369 memprintf(err, "%sunable to load SSL private key from PEM file '%s'.\n",
2370 err && *err ? *err : "", path);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002371 SSL_CTX_free(ctx);
2372 return 1;
2373 }
2374
Emeric Brun50bcecc2013-04-22 13:05:23 +02002375 ret = ssl_sock_load_cert_chain_file(ctx, path, bind_conf, sni_filter, fcount);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002376 if (ret <= 0) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02002377 memprintf(err, "%sunable to load SSL certificate from PEM file '%s'.\n",
2378 err && *err ? *err : "", path);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002379 if (ret < 0) /* serious error, must do that ourselves */
2380 SSL_CTX_free(ctx);
2381 return 1;
2382 }
Emeric Brun61694ab2012-10-26 13:35:33 +02002383
2384 if (SSL_CTX_check_private_key(ctx) <= 0) {
2385 memprintf(err, "%sinconsistencies between private key and certificate loaded from PEM file '%s'.\n",
2386 err && *err ? *err : "", path);
2387 return 1;
2388 }
2389
Emeric Brunfc0421f2012-09-07 17:30:07 +02002390 /* we must not free the SSL_CTX anymore below, since it's already in
2391 * the tree, so it will be discovered and cleaned in time.
2392 */
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02002393#ifndef OPENSSL_NO_DH
Remi Gacogne4f902b82015-05-28 16:23:00 +02002394 /* store a NULL pointer to indicate we have not yet loaded
2395 a custom DH param file */
2396 if (ssl_dh_ptr_index >= 0) {
2397 SSL_CTX_set_ex_data(ctx, ssl_dh_ptr_index, NULL);
2398 }
2399
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02002400 ret = ssl_sock_load_dh_params(ctx, path);
2401 if (ret < 0) {
2402 if (err)
2403 memprintf(err, "%sunable to load DH parameters from file '%s'.\n",
2404 *err ? *err : "", path);
2405 return 1;
2406 }
2407#endif
2408
Lukas Tribuse4e30f72014-12-09 16:32:51 +01002409#if (defined SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB && !defined OPENSSL_NO_OCSP)
Emeric Brun4147b2e2014-06-16 18:36:30 +02002410 ret = ssl_sock_load_ocsp(ctx, path);
2411 if (ret < 0) {
2412 if (err)
2413 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",
2414 *err ? *err : "", path);
2415 return 1;
2416 }
2417#endif
2418
Daniel Jakots54ffb912015-11-06 20:02:41 +01002419#if (OPENSSL_VERSION_NUMBER >= 0x1000200fL && !defined OPENSSL_NO_TLSEXT && !defined OPENSSL_IS_BORINGSSL && !defined LIBRESSL_VERSION_NUMBER)
Janusz Dziemidowicz2c701b52015-03-07 23:03:59 +01002420 if (sctl_ex_index >= 0) {
2421 ret = ssl_sock_load_sctl(ctx, path);
2422 if (ret < 0) {
2423 if (err)
2424 memprintf(err, "%s '%s.sctl' is present but cannot be read or parsed'.\n",
2425 *err ? *err : "", path);
2426 return 1;
2427 }
2428 }
2429#endif
2430
Emeric Brunfc0421f2012-09-07 17:30:07 +02002431#ifndef SSL_CTRL_SET_TLSEXT_HOSTNAME
Willy Tarreau2a65ff02012-09-13 17:54:29 +02002432 if (bind_conf->default_ctx) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02002433 memprintf(err, "%sthis version of openssl cannot load multiple SSL certificates.\n",
2434 err && *err ? *err : "");
Emeric Brunfc0421f2012-09-07 17:30:07 +02002435 return 1;
2436 }
2437#endif
Willy Tarreau2a65ff02012-09-13 17:54:29 +02002438 if (!bind_conf->default_ctx)
2439 bind_conf->default_ctx = ctx;
Emeric Brunfc0421f2012-09-07 17:30:07 +02002440
2441 return 0;
2442}
2443
Willy Tarreau03209342016-12-22 17:08:28 +01002444int ssl_sock_load_cert(char *path, struct bind_conf *bind_conf, char **err)
Emeric Brunfc0421f2012-09-07 17:30:07 +02002445{
Cyril Bonté3180f7b2015-01-25 00:16:08 +01002446 struct dirent **de_list;
2447 int i, n;
Emeric Brunfc0421f2012-09-07 17:30:07 +02002448 DIR *dir;
2449 struct stat buf;
Willy Tarreauee2663b2012-12-06 11:36:59 +01002450 char *end;
2451 char fp[MAXPATHLEN+1];
Emeric Brunfc0421f2012-09-07 17:30:07 +02002452 int cfgerr = 0;
yanbzhu63ea8462015-12-09 13:35:14 -05002453#if OPENSSL_VERSION_NUMBER >= 0x1000200fL
2454 int is_bundle;
2455 int j;
2456#endif
Emeric Brunfc0421f2012-09-07 17:30:07 +02002457
yanbzhu08ce6ab2015-12-02 13:01:29 -05002458 if (stat(path, &buf) == 0) {
2459 dir = opendir(path);
2460 if (!dir)
Willy Tarreau03209342016-12-22 17:08:28 +01002461 return ssl_sock_load_cert_file(path, bind_conf, NULL, 0, err);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002462
yanbzhu08ce6ab2015-12-02 13:01:29 -05002463 /* strip trailing slashes, including first one */
2464 for (end = path + strlen(path) - 1; end >= path && *end == '/'; end--)
2465 *end = 0;
Emeric Brunfc0421f2012-09-07 17:30:07 +02002466
yanbzhu08ce6ab2015-12-02 13:01:29 -05002467 n = scandir(path, &de_list, 0, alphasort);
2468 if (n < 0) {
2469 memprintf(err, "%sunable to scan directory '%s' : %s.\n",
2470 err && *err ? *err : "", path, strerror(errno));
2471 cfgerr++;
2472 }
2473 else {
2474 for (i = 0; i < n; i++) {
2475 struct dirent *de = de_list[i];
Emeric Brun2aab7222014-06-18 18:15:09 +02002476
yanbzhu08ce6ab2015-12-02 13:01:29 -05002477 end = strrchr(de->d_name, '.');
2478 if (end && (!strcmp(end, ".issuer") || !strcmp(end, ".ocsp") || !strcmp(end, ".sctl")))
2479 goto ignore_entry;
Cyril Bonté3180f7b2015-01-25 00:16:08 +01002480
yanbzhu08ce6ab2015-12-02 13:01:29 -05002481 snprintf(fp, sizeof(fp), "%s/%s", path, de->d_name);
2482 if (stat(fp, &buf) != 0) {
2483 memprintf(err, "%sunable to stat SSL certificate from file '%s' : %s.\n",
2484 err && *err ? *err : "", fp, strerror(errno));
2485 cfgerr++;
2486 goto ignore_entry;
2487 }
2488 if (!S_ISREG(buf.st_mode))
2489 goto ignore_entry;
yanbzhu63ea8462015-12-09 13:35:14 -05002490
2491#if OPENSSL_VERSION_NUMBER >= 0x1000200fL
2492 is_bundle = 0;
2493 /* Check if current entry in directory is part of a multi-cert bundle */
2494
2495 if (end) {
2496 for (j = 0; j < SSL_SOCK_NUM_KEYTYPES; j++) {
2497 if (!strcmp(end + 1, SSL_SOCK_KEYTYPE_NAMES[j])) {
2498 is_bundle = 1;
2499 break;
2500 }
2501 }
2502
2503 if (is_bundle) {
2504 char dp[MAXPATHLEN+1] = {0}; /* this will be the filename w/o the keytype */
2505 int dp_len;
2506
2507 dp_len = end - de->d_name;
2508 snprintf(dp, dp_len + 1, "%s", de->d_name);
2509
2510 /* increment i and free de until we get to a non-bundle cert
2511 * Note here that we look at de_list[i + 1] before freeing de
2512 * this is important since ignore_entry will free de
2513 */
2514 while (i + 1 < n && !strncmp(de_list[i + 1]->d_name, dp, dp_len)) {
2515 free(de);
2516 i++;
2517 de = de_list[i];
2518 }
2519
2520 snprintf(fp, sizeof(fp), "%s/%s", path, dp);
Willy Tarreau03209342016-12-22 17:08:28 +01002521 ssl_sock_load_multi_cert(fp, bind_conf, NULL, 0, err);
yanbzhu63ea8462015-12-09 13:35:14 -05002522
2523 /* Successfully processed the bundle */
2524 goto ignore_entry;
2525 }
2526 }
2527
2528#endif
Willy Tarreau03209342016-12-22 17:08:28 +01002529 cfgerr += ssl_sock_load_cert_file(fp, bind_conf, NULL, 0, err);
yanbzhu08ce6ab2015-12-02 13:01:29 -05002530ignore_entry:
2531 free(de);
Cyril Bonté3180f7b2015-01-25 00:16:08 +01002532 }
yanbzhu08ce6ab2015-12-02 13:01:29 -05002533 free(de_list);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002534 }
yanbzhu08ce6ab2015-12-02 13:01:29 -05002535 closedir(dir);
2536 return cfgerr;
Emeric Brunfc0421f2012-09-07 17:30:07 +02002537 }
yanbzhu08ce6ab2015-12-02 13:01:29 -05002538
Willy Tarreau03209342016-12-22 17:08:28 +01002539 cfgerr = ssl_sock_load_multi_cert(path, bind_conf, NULL, 0, err);
yanbzhu08ce6ab2015-12-02 13:01:29 -05002540
Emeric Brunfc0421f2012-09-07 17:30:07 +02002541 return cfgerr;
2542}
2543
Thierry Fournier383085f2013-01-24 14:15:43 +01002544/* Make sure openssl opens /dev/urandom before the chroot. The work is only
2545 * done once. Zero is returned if the operation fails. No error is returned
2546 * if the random is said as not implemented, because we expect that openssl
2547 * will use another method once needed.
2548 */
2549static int ssl_initialize_random()
2550{
2551 unsigned char random;
2552 static int random_initialized = 0;
2553
2554 if (!random_initialized && RAND_bytes(&random, 1) != 0)
2555 random_initialized = 1;
2556
2557 return random_initialized;
2558}
2559
Willy Tarreau03209342016-12-22 17:08:28 +01002560int ssl_sock_load_cert_list_file(char *file, struct bind_conf *bind_conf, char **err)
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002561{
Emmanuel Hocdet5e0e6e42016-05-13 11:18:50 +02002562 char thisline[LINESIZE*CRTLIST_FACTOR];
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002563 FILE *f;
yanbzhu1b04e5b2015-12-02 13:54:14 -05002564 struct stat buf;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002565 int linenum = 0;
2566 int cfgerr = 0;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002567
Willy Tarreauad1731d2013-04-02 17:35:58 +02002568 if ((f = fopen(file, "r")) == NULL) {
2569 memprintf(err, "cannot open file '%s' : %s", file, strerror(errno));
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002570 return 1;
Willy Tarreauad1731d2013-04-02 17:35:58 +02002571 }
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002572
2573 while (fgets(thisline, sizeof(thisline), f) != NULL) {
2574 int arg;
Emeric Brun50bcecc2013-04-22 13:05:23 +02002575 int newarg;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002576 char *end;
Emmanuel Hocdet5e0e6e42016-05-13 11:18:50 +02002577 char *args[MAX_LINE_ARGS*CRTLIST_FACTOR + 1];
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002578 char *line = thisline;
2579
2580 linenum++;
2581 end = line + strlen(line);
2582 if (end-line == sizeof(thisline)-1 && *(end-1) != '\n') {
2583 /* Check if we reached the limit and the last char is not \n.
2584 * Watch out for the last line without the terminating '\n'!
2585 */
Willy Tarreauad1731d2013-04-02 17:35:58 +02002586 memprintf(err, "line %d too long in file '%s', limit is %d characters",
2587 linenum, file, (int)sizeof(thisline)-1);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002588 cfgerr = 1;
Willy Tarreauad1731d2013-04-02 17:35:58 +02002589 break;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002590 }
2591
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002592 arg = 0;
Emeric Brun50bcecc2013-04-22 13:05:23 +02002593 newarg = 1;
2594 while (*line) {
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002595 if (*line == '#' || *line == '\n' || *line == '\r') {
2596 /* end of string, end of loop */
2597 *line = 0;
2598 break;
2599 }
2600 else if (isspace(*line)) {
Emeric Brun50bcecc2013-04-22 13:05:23 +02002601 newarg = 1;
2602 *line = 0;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002603 }
Emeric Brun50bcecc2013-04-22 13:05:23 +02002604 else if (newarg) {
Emmanuel Hocdet5e0e6e42016-05-13 11:18:50 +02002605 if (arg == MAX_LINE_ARGS*CRTLIST_FACTOR) {
Emeric Brun50bcecc2013-04-22 13:05:23 +02002606 memprintf(err, "too many args on line %d in file '%s'.",
2607 linenum, file);
2608 cfgerr = 1;
2609 break;
2610 }
2611 newarg = 0;
2612 args[arg++] = line;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002613 }
Emeric Brun50bcecc2013-04-22 13:05:23 +02002614 line++;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002615 }
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02002616 if (cfgerr)
2617 break;
Willy Tarreauad1731d2013-04-02 17:35:58 +02002618
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002619 /* empty line */
Emeric Brun50bcecc2013-04-22 13:05:23 +02002620 if (!arg)
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002621 continue;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002622
yanbzhu1b04e5b2015-12-02 13:54:14 -05002623 if (stat(args[0], &buf) == 0) {
Willy Tarreau03209342016-12-22 17:08:28 +01002624 cfgerr = ssl_sock_load_cert_file(args[0], bind_conf, &args[1], arg-1, err);
yanbzhu1b04e5b2015-12-02 13:54:14 -05002625 } else {
Willy Tarreau03209342016-12-22 17:08:28 +01002626 cfgerr = ssl_sock_load_multi_cert(args[0], bind_conf, &args[1], arg-1, err);
yanbzhu1b04e5b2015-12-02 13:54:14 -05002627 }
2628
Willy Tarreauad1731d2013-04-02 17:35:58 +02002629 if (cfgerr) {
2630 memprintf(err, "error processing line %d in file '%s' : %s", linenum, file, *err);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002631 break;
Willy Tarreauad1731d2013-04-02 17:35:58 +02002632 }
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002633 }
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002634 fclose(f);
2635 return cfgerr;
2636}
2637
Emeric Brunfc0421f2012-09-07 17:30:07 +02002638#ifndef SSL_OP_CIPHER_SERVER_PREFERENCE /* needs OpenSSL >= 0.9.7 */
2639#define SSL_OP_CIPHER_SERVER_PREFERENCE 0
2640#endif
2641
2642#ifndef SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION /* needs OpenSSL >= 0.9.7 */
2643#define SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION 0
Willy Tarreau7d588ee2012-11-26 18:47:31 +01002644#define SSL_renegotiate_pending(arg) 0
Emeric Brunfc0421f2012-09-07 17:30:07 +02002645#endif
Emeric Brun2b58d042012-09-20 17:10:03 +02002646#ifndef SSL_OP_SINGLE_ECDH_USE /* needs OpenSSL >= 0.9.8 */
2647#define SSL_OP_SINGLE_ECDH_USE 0
2648#endif
Emeric Brun2d0c4822012-10-02 13:45:20 +02002649#ifndef SSL_OP_NO_TICKET /* needs OpenSSL >= 0.9.8 */
2650#define SSL_OP_NO_TICKET 0
2651#endif
Emeric Brunfc0421f2012-09-07 17:30:07 +02002652#ifndef SSL_OP_NO_COMPRESSION /* needs OpenSSL >= 0.9.9 */
2653#define SSL_OP_NO_COMPRESSION 0
2654#endif
Emeric Brunc0ff4922012-09-28 19:37:02 +02002655#ifndef SSL_OP_NO_TLSv1_1 /* needs OpenSSL >= 1.0.1 */
2656#define SSL_OP_NO_TLSv1_1 0
2657#endif
2658#ifndef SSL_OP_NO_TLSv1_2 /* needs OpenSSL >= 1.0.1 */
2659#define SSL_OP_NO_TLSv1_2 0
2660#endif
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02002661#ifndef SSL_OP_SINGLE_DH_USE /* needs OpenSSL >= 0.9.6 */
2662#define SSL_OP_SINGLE_DH_USE 0
2663#endif
Emeric Brun2b58d042012-09-20 17:10:03 +02002664#ifndef SSL_OP_SINGLE_ECDH_USE /* needs OpenSSL >= 1.0.0 */
2665#define SSL_OP_SINGLE_ECDH_USE 0
2666#endif
Emeric Brunfc0421f2012-09-07 17:30:07 +02002667#ifndef SSL_MODE_RELEASE_BUFFERS /* needs OpenSSL >= 1.0.0 */
2668#define SSL_MODE_RELEASE_BUFFERS 0
2669#endif
Willy Tarreau396a1862014-11-13 14:06:52 +01002670#ifndef SSL_MODE_SMALL_BUFFERS /* needs small_records.patch */
2671#define SSL_MODE_SMALL_BUFFERS 0
2672#endif
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002673
Willy Tarreau03209342016-12-22 17:08:28 +01002674int ssl_sock_prepare_ctx(struct bind_conf *bind_conf, SSL_CTX *ctx)
Emeric Brunfc0421f2012-09-07 17:30:07 +02002675{
Willy Tarreau03209342016-12-22 17:08:28 +01002676 struct proxy *curproxy = bind_conf->frontend;
Emeric Brunfc0421f2012-09-07 17:30:07 +02002677 int cfgerr = 0;
Emeric Brun850efd52014-01-29 12:24:34 +01002678 int verify = SSL_VERIFY_NONE;
Remi Gacogneaf5c3da2014-05-19 10:29:58 +02002679 long ssloptions =
Emeric Brunfc0421f2012-09-07 17:30:07 +02002680 SSL_OP_ALL | /* all known workarounds for bugs */
2681 SSL_OP_NO_SSLv2 |
2682 SSL_OP_NO_COMPRESSION |
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02002683 SSL_OP_SINGLE_DH_USE |
Emeric Brun2b58d042012-09-20 17:10:03 +02002684 SSL_OP_SINGLE_ECDH_USE |
Emeric Brun3c4bc6e2012-10-04 18:44:19 +02002685 SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION |
2686 SSL_OP_CIPHER_SERVER_PREFERENCE;
Remi Gacogneaf5c3da2014-05-19 10:29:58 +02002687 long sslmode =
Emeric Brunfc0421f2012-09-07 17:30:07 +02002688 SSL_MODE_ENABLE_PARTIAL_WRITE |
2689 SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER |
Willy Tarreau396a1862014-11-13 14:06:52 +01002690 SSL_MODE_RELEASE_BUFFERS |
2691 SSL_MODE_SMALL_BUFFERS;
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002692 STACK_OF(SSL_CIPHER) * ciphers = NULL;
Willy Tarreaua616ba62014-10-26 06:49:19 +01002693 SSL_CIPHER * cipher = NULL;
Remi Gacognec1eab8c2014-06-12 18:20:11 +02002694 char cipher_description[128];
2695 /* The description of ciphers using an Ephemeral Diffie Hellman key exchange
2696 contains " Kx=DH " or " Kx=DH(". Beware of " Kx=DH/",
2697 which is not ephemeral DH. */
2698 const char dhe_description[] = " Kx=DH ";
2699 const char dhe_export_description[] = " Kx=DH(";
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002700 int idx = 0;
2701 int dhe_found = 0;
Remi Gacogne23d5d372014-10-10 17:04:26 +02002702 SSL *ssl = NULL;
Emeric Brunfc0421f2012-09-07 17:30:07 +02002703
Thierry Fournier383085f2013-01-24 14:15:43 +01002704 /* Make sure openssl opens /dev/urandom before the chroot */
2705 if (!ssl_initialize_random()) {
2706 Alert("OpenSSL random data generator initialization failed.\n");
2707 cfgerr++;
2708 }
2709
Emeric Brun89675492012-10-05 13:48:26 +02002710 if (bind_conf->ssl_options & BC_SSL_O_NO_SSLV3)
Emeric Brunfc0421f2012-09-07 17:30:07 +02002711 ssloptions |= SSL_OP_NO_SSLv3;
Emeric Brun89675492012-10-05 13:48:26 +02002712 if (bind_conf->ssl_options & BC_SSL_O_NO_TLSV10)
Emeric Brunfc0421f2012-09-07 17:30:07 +02002713 ssloptions |= SSL_OP_NO_TLSv1;
Emeric Brun89675492012-10-05 13:48:26 +02002714 if (bind_conf->ssl_options & BC_SSL_O_NO_TLSV11)
Emeric Brunc0ff4922012-09-28 19:37:02 +02002715 ssloptions |= SSL_OP_NO_TLSv1_1;
Emeric Brun89675492012-10-05 13:48:26 +02002716 if (bind_conf->ssl_options & BC_SSL_O_NO_TLSV12)
Emeric Brunc0ff4922012-09-28 19:37:02 +02002717 ssloptions |= SSL_OP_NO_TLSv1_2;
Emeric Brun89675492012-10-05 13:48:26 +02002718 if (bind_conf->ssl_options & BC_SSL_O_NO_TLS_TICKETS)
Emeric Brun2d0c4822012-10-02 13:45:20 +02002719 ssloptions |= SSL_OP_NO_TICKET;
Jérémie Courrèges-Anglas17c3f622015-07-25 16:50:52 -06002720 if (bind_conf->ssl_options & BC_SSL_O_USE_SSLV3) {
2721#ifndef OPENSSL_NO_SSL3
Emeric Brun2cb7ae52012-10-05 14:14:21 +02002722 SSL_CTX_set_ssl_version(ctx, SSLv3_server_method());
Jérémie Courrèges-Anglas17c3f622015-07-25 16:50:52 -06002723#else
2724 Alert("SSLv3 support requested but unavailable.\n");
2725 cfgerr++;
2726#endif
2727 }
Emeric Brun2cb7ae52012-10-05 14:14:21 +02002728 if (bind_conf->ssl_options & BC_SSL_O_USE_TLSV10)
2729 SSL_CTX_set_ssl_version(ctx, TLSv1_server_method());
2730#if SSL_OP_NO_TLSv1_1
2731 if (bind_conf->ssl_options & BC_SSL_O_USE_TLSV11)
2732 SSL_CTX_set_ssl_version(ctx, TLSv1_1_server_method());
2733#endif
2734#if SSL_OP_NO_TLSv1_2
2735 if (bind_conf->ssl_options & BC_SSL_O_USE_TLSV12)
2736 SSL_CTX_set_ssl_version(ctx, TLSv1_2_server_method());
2737#endif
Emeric Brunfc0421f2012-09-07 17:30:07 +02002738
2739 SSL_CTX_set_options(ctx, ssloptions);
2740 SSL_CTX_set_mode(ctx, sslmode);
Emeric Brun850efd52014-01-29 12:24:34 +01002741 switch (bind_conf->verify) {
2742 case SSL_SOCK_VERIFY_NONE:
2743 verify = SSL_VERIFY_NONE;
2744 break;
2745 case SSL_SOCK_VERIFY_OPTIONAL:
2746 verify = SSL_VERIFY_PEER;
2747 break;
2748 case SSL_SOCK_VERIFY_REQUIRED:
2749 verify = SSL_VERIFY_PEER|SSL_VERIFY_FAIL_IF_NO_PEER_CERT;
2750 break;
2751 }
2752 SSL_CTX_set_verify(ctx, verify, ssl_sock_bind_verifycbk);
2753 if (verify & SSL_VERIFY_PEER) {
Emeric Brunfb510ea2012-10-05 12:00:26 +02002754 if (bind_conf->ca_file) {
Emeric Brund94b3fe2012-09-20 18:23:56 +02002755 /* load CAfile to verify */
Emeric Brunfb510ea2012-10-05 12:00:26 +02002756 if (!SSL_CTX_load_verify_locations(ctx, bind_conf->ca_file, NULL)) {
Emeric Brund94b3fe2012-09-20 18:23:56 +02002757 Alert("Proxy '%s': unable to load CA file '%s' for bind '%s' at [%s:%d].\n",
Emeric Brunfb510ea2012-10-05 12:00:26 +02002758 curproxy->id, bind_conf->ca_file, bind_conf->arg, bind_conf->file, bind_conf->line);
Emeric Brund94b3fe2012-09-20 18:23:56 +02002759 cfgerr++;
2760 }
2761 /* set CA names fo client cert request, function returns void */
Emeric Brunfb510ea2012-10-05 12:00:26 +02002762 SSL_CTX_set_client_CA_list(ctx, SSL_load_client_CA_file(bind_conf->ca_file));
Emeric Brund94b3fe2012-09-20 18:23:56 +02002763 }
Emeric Brun850efd52014-01-29 12:24:34 +01002764 else {
2765 Alert("Proxy '%s': verify is enabled but no CA file specified for bind '%s' at [%s:%d].\n",
2766 curproxy->id, bind_conf->arg, bind_conf->file, bind_conf->line);
2767 cfgerr++;
2768 }
Emeric Brun051cdab2012-10-02 19:25:50 +02002769#ifdef X509_V_FLAG_CRL_CHECK
Emeric Brunfb510ea2012-10-05 12:00:26 +02002770 if (bind_conf->crl_file) {
Emeric Brund94b3fe2012-09-20 18:23:56 +02002771 X509_STORE *store = SSL_CTX_get_cert_store(ctx);
2772
Emeric Brunfb510ea2012-10-05 12:00:26 +02002773 if (!store || !X509_STORE_load_locations(store, bind_conf->crl_file, NULL)) {
Emeric Brund94b3fe2012-09-20 18:23:56 +02002774 Alert("Proxy '%s': unable to configure CRL file '%s' for bind '%s' at [%s:%d].\n",
Alexander Rigbofc65af02015-04-07 14:02:16 +02002775 curproxy->id, bind_conf->crl_file, bind_conf->arg, bind_conf->file, bind_conf->line);
Emeric Brund94b3fe2012-09-20 18:23:56 +02002776 cfgerr++;
2777 }
Emeric Brun561e5742012-10-02 15:20:55 +02002778 else {
2779 X509_STORE_set_flags(store, X509_V_FLAG_CRL_CHECK|X509_V_FLAG_CRL_CHECK_ALL);
2780 }
Emeric Brund94b3fe2012-09-20 18:23:56 +02002781 }
Emeric Brun051cdab2012-10-02 19:25:50 +02002782#endif
Emeric Brun644cde02012-12-14 11:21:13 +01002783 ERR_clear_error();
Emeric Brund94b3fe2012-09-20 18:23:56 +02002784 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02002785
Nenad Merdanovic05552d42015-02-27 19:56:49 +01002786#if (defined SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB && TLS_TICKETS_NO > 0)
Nenad Merdanovic146defa2015-05-09 08:46:00 +02002787 if(bind_conf->keys_ref) {
Nenad Merdanovic05552d42015-02-27 19:56:49 +01002788 if (!SSL_CTX_set_tlsext_ticket_key_cb(ctx, ssl_tlsext_ticket_key_cb)) {
2789 Alert("Proxy '%s': unable to set callback for TLS ticket validation for bind '%s' at [%s:%d].\n",
2790 curproxy->id, bind_conf->arg, bind_conf->file, bind_conf->line);
2791 cfgerr++;
2792 }
2793 }
2794#endif
2795
Emeric Brun4f65bff2012-11-16 15:11:00 +01002796 if (global.tune.ssllifetime)
2797 SSL_CTX_set_timeout(ctx, global.tune.ssllifetime);
2798
Emeric Brunfc0421f2012-09-07 17:30:07 +02002799 shared_context_set_cache(ctx);
Willy Tarreau2a65ff02012-09-13 17:54:29 +02002800 if (bind_conf->ciphers &&
2801 !SSL_CTX_set_cipher_list(ctx, bind_conf->ciphers)) {
Emeric Brunfc0421f2012-09-07 17:30:07 +02002802 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 +02002803 curproxy->id, bind_conf->ciphers, bind_conf->arg, bind_conf->file, bind_conf->line);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002804 cfgerr++;
2805 }
2806
Remi Gacogne47783ef2015-05-29 15:53:22 +02002807 /* If tune.ssl.default-dh-param has not been set,
2808 neither has ssl-default-dh-file and no static DH
2809 params were in the certificate file. */
Remi Gacogne4f902b82015-05-28 16:23:00 +02002810 if (global.tune.ssl_default_dh_param == 0 &&
Remi Gacogne47783ef2015-05-29 15:53:22 +02002811 global_dh == NULL &&
Remi Gacogne4f902b82015-05-28 16:23:00 +02002812 (ssl_dh_ptr_index == -1 ||
2813 SSL_CTX_get_ex_data(ctx, ssl_dh_ptr_index) == NULL)) {
Lukas Tribus90132722014-08-18 00:56:33 +02002814
Remi Gacogne23d5d372014-10-10 17:04:26 +02002815 ssl = SSL_new(ctx);
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002816
Remi Gacogne23d5d372014-10-10 17:04:26 +02002817 if (ssl) {
2818 ciphers = SSL_get_ciphers(ssl);
2819
2820 if (ciphers) {
2821 for (idx = 0; idx < sk_SSL_CIPHER_num(ciphers); idx++) {
2822 cipher = sk_SSL_CIPHER_value(ciphers, idx);
2823 if (SSL_CIPHER_description(cipher, cipher_description, sizeof (cipher_description)) == cipher_description) {
2824 if (strstr(cipher_description, dhe_description) != NULL ||
2825 strstr(cipher_description, dhe_export_description) != NULL) {
2826 dhe_found = 1;
2827 break;
2828 }
Remi Gacognec1eab8c2014-06-12 18:20:11 +02002829 }
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002830 }
2831 }
Remi Gacogne23d5d372014-10-10 17:04:26 +02002832 SSL_free(ssl);
2833 ssl = NULL;
Lukas Tribus90132722014-08-18 00:56:33 +02002834 }
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002835
Lukas Tribus90132722014-08-18 00:56:33 +02002836 if (dhe_found) {
2837 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 +02002838 }
2839
2840 global.tune.ssl_default_dh_param = 1024;
2841 }
Remi Gacogne8de54152014-07-15 11:36:40 +02002842
2843#ifndef OPENSSL_NO_DH
2844 if (global.tune.ssl_default_dh_param >= 1024) {
2845 if (local_dh_1024 == NULL) {
2846 local_dh_1024 = ssl_get_dh_1024();
2847 }
2848 if (global.tune.ssl_default_dh_param >= 2048) {
2849 if (local_dh_2048 == NULL) {
2850 local_dh_2048 = ssl_get_dh_2048();
2851 }
2852 if (global.tune.ssl_default_dh_param >= 4096) {
2853 if (local_dh_4096 == NULL) {
2854 local_dh_4096 = ssl_get_dh_4096();
2855 }
Remi Gacogne8de54152014-07-15 11:36:40 +02002856 }
2857 }
2858 }
2859#endif /* OPENSSL_NO_DH */
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002860
Emeric Brunfc0421f2012-09-07 17:30:07 +02002861 SSL_CTX_set_info_callback(ctx, ssl_sock_infocbk);
Willy Tarreau5cbe4ef2014-05-08 22:45:11 +02002862#if OPENSSL_VERSION_NUMBER >= 0x00907000L
Emeric Brun29f037d2014-04-25 19:05:36 +02002863 SSL_CTX_set_msg_callback(ctx, ssl_sock_msgcbk);
Willy Tarreau5cbe4ef2014-05-08 22:45:11 +02002864#endif
Emeric Brun29f037d2014-04-25 19:05:36 +02002865
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02002866#ifdef OPENSSL_NPN_NEGOTIATED
2867 if (bind_conf->npn_str)
2868 SSL_CTX_set_next_protos_advertised_cb(ctx, ssl_sock_advertise_npn_protos, bind_conf);
2869#endif
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01002870#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Willy Tarreauab861d32013-04-02 02:30:41 +02002871 if (bind_conf->alpn_str)
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01002872 SSL_CTX_set_alpn_select_cb(ctx, ssl_sock_advertise_alpn_protos, bind_conf);
Willy Tarreauab861d32013-04-02 02:30:41 +02002873#endif
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02002874
Emeric Brunfc0421f2012-09-07 17:30:07 +02002875#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
2876 SSL_CTX_set_tlsext_servername_callback(ctx, ssl_sock_switchctx_cbk);
Willy Tarreau2a65ff02012-09-13 17:54:29 +02002877 SSL_CTX_set_tlsext_servername_arg(ctx, bind_conf);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002878#endif
Emeric Brun2b58d042012-09-20 17:10:03 +02002879#if defined(SSL_CTX_set_tmp_ecdh) && !defined(OPENSSL_NO_ECDH)
Emeric Brun6924ef82013-03-06 14:08:53 +01002880 {
Emeric Brun2b58d042012-09-20 17:10:03 +02002881 int i;
2882 EC_KEY *ecdh;
2883
Emeric Brun6924ef82013-03-06 14:08:53 +01002884 i = OBJ_sn2nid(bind_conf->ecdhe ? bind_conf->ecdhe : ECDHE_DEFAULT_CURVE);
Emeric Brun2b58d042012-09-20 17:10:03 +02002885 if (!i || ((ecdh = EC_KEY_new_by_curve_name(i)) == NULL)) {
2886 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 +01002887 curproxy->id, bind_conf->ecdhe ? bind_conf->ecdhe : ECDHE_DEFAULT_CURVE,
2888 bind_conf->arg, bind_conf->file, bind_conf->line);
Emeric Brun2b58d042012-09-20 17:10:03 +02002889 cfgerr++;
2890 }
2891 else {
2892 SSL_CTX_set_tmp_ecdh(ctx, ecdh);
2893 EC_KEY_free(ecdh);
2894 }
2895 }
2896#endif
2897
Emeric Brunfc0421f2012-09-07 17:30:07 +02002898 return cfgerr;
2899}
2900
Evan Broderbe554312013-06-27 00:05:25 -07002901static int ssl_sock_srv_hostcheck(const char *pattern, const char *hostname)
2902{
2903 const char *pattern_wildcard, *pattern_left_label_end, *hostname_left_label_end;
2904 size_t prefixlen, suffixlen;
2905
2906 /* Trivial case */
2907 if (strcmp(pattern, hostname) == 0)
2908 return 1;
2909
Evan Broderbe554312013-06-27 00:05:25 -07002910 /* The rest of this logic is based on RFC 6125, section 6.4.3
2911 * (http://tools.ietf.org/html/rfc6125#section-6.4.3) */
2912
Emeric Bruna848dae2013-10-08 11:27:28 +02002913 pattern_wildcard = NULL;
2914 pattern_left_label_end = pattern;
2915 while (*pattern_left_label_end != '.') {
2916 switch (*pattern_left_label_end) {
2917 case 0:
2918 /* End of label not found */
2919 return 0;
2920 case '*':
2921 /* If there is more than one wildcards */
2922 if (pattern_wildcard)
2923 return 0;
2924 pattern_wildcard = pattern_left_label_end;
2925 break;
2926 }
2927 pattern_left_label_end++;
2928 }
2929
2930 /* If it's not trivial and there is no wildcard, it can't
2931 * match */
2932 if (!pattern_wildcard)
Evan Broderbe554312013-06-27 00:05:25 -07002933 return 0;
2934
2935 /* Make sure all labels match except the leftmost */
2936 hostname_left_label_end = strchr(hostname, '.');
2937 if (!hostname_left_label_end
2938 || strcmp(pattern_left_label_end, hostname_left_label_end) != 0)
2939 return 0;
2940
2941 /* Make sure the leftmost label of the hostname is long enough
2942 * that the wildcard can match */
Emeric Brun369da852013-10-08 11:39:35 +02002943 if (hostname_left_label_end - hostname < (pattern_left_label_end - pattern) - 1)
Evan Broderbe554312013-06-27 00:05:25 -07002944 return 0;
2945
2946 /* Finally compare the string on either side of the
2947 * wildcard */
2948 prefixlen = pattern_wildcard - pattern;
2949 suffixlen = pattern_left_label_end - (pattern_wildcard + 1);
Emeric Bruna848dae2013-10-08 11:27:28 +02002950 if ((prefixlen && (memcmp(pattern, hostname, prefixlen) != 0))
2951 || (suffixlen && (memcmp(pattern_wildcard + 1, hostname_left_label_end - suffixlen, suffixlen) != 0)))
Evan Broderbe554312013-06-27 00:05:25 -07002952 return 0;
2953
2954 return 1;
2955}
2956
2957static int ssl_sock_srv_verifycbk(int ok, X509_STORE_CTX *ctx)
2958{
2959 SSL *ssl;
2960 struct connection *conn;
2961 char *servername;
2962
2963 int depth;
2964 X509 *cert;
2965 STACK_OF(GENERAL_NAME) *alt_names;
2966 int i;
2967 X509_NAME *cert_subject;
2968 char *str;
2969
2970 if (ok == 0)
2971 return ok;
2972
2973 ssl = X509_STORE_CTX_get_ex_data(ctx, SSL_get_ex_data_X509_STORE_CTX_idx());
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02002974 conn = SSL_get_app_data(ssl);
Evan Broderbe554312013-06-27 00:05:25 -07002975
2976 servername = objt_server(conn->target)->ssl_ctx.verify_host;
2977
2978 /* We only need to verify the CN on the actual server cert,
2979 * not the indirect CAs */
2980 depth = X509_STORE_CTX_get_error_depth(ctx);
2981 if (depth != 0)
2982 return ok;
2983
2984 /* At this point, the cert is *not* OK unless we can find a
2985 * hostname match */
2986 ok = 0;
2987
2988 cert = X509_STORE_CTX_get_current_cert(ctx);
2989 /* It seems like this might happen if verify peer isn't set */
2990 if (!cert)
2991 return ok;
2992
2993 alt_names = X509_get_ext_d2i(cert, NID_subject_alt_name, NULL, NULL);
2994 if (alt_names) {
2995 for (i = 0; !ok && i < sk_GENERAL_NAME_num(alt_names); i++) {
2996 GENERAL_NAME *name = sk_GENERAL_NAME_value(alt_names, i);
2997 if (name->type == GEN_DNS) {
Emeric Bruna33410c2013-09-17 15:47:48 +02002998#if OPENSSL_VERSION_NUMBER < 0x00907000L
2999 if (ASN1_STRING_to_UTF8((unsigned char **)&str, name->d.ia5) >= 0) {
3000#else
Evan Broderbe554312013-06-27 00:05:25 -07003001 if (ASN1_STRING_to_UTF8((unsigned char **)&str, name->d.dNSName) >= 0) {
Emeric Bruna33410c2013-09-17 15:47:48 +02003002#endif
Evan Broderbe554312013-06-27 00:05:25 -07003003 ok = ssl_sock_srv_hostcheck(str, servername);
3004 OPENSSL_free(str);
3005 }
3006 }
3007 }
Emeric Brun4ad50a42013-09-17 15:19:54 +02003008 sk_GENERAL_NAME_pop_free(alt_names, GENERAL_NAME_free);
Evan Broderbe554312013-06-27 00:05:25 -07003009 }
3010
3011 cert_subject = X509_get_subject_name(cert);
3012 i = -1;
3013 while (!ok && (i = X509_NAME_get_index_by_NID(cert_subject, NID_commonName, i)) != -1) {
3014 X509_NAME_ENTRY *entry = X509_NAME_get_entry(cert_subject, i);
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02003015 ASN1_STRING *value;
3016 value = X509_NAME_ENTRY_get_data(entry);
3017 if (ASN1_STRING_to_UTF8((unsigned char **)&str, value) >= 0) {
Evan Broderbe554312013-06-27 00:05:25 -07003018 ok = ssl_sock_srv_hostcheck(str, servername);
3019 OPENSSL_free(str);
3020 }
3021 }
3022
3023 return ok;
3024}
3025
Emeric Brun94324a42012-10-11 14:00:19 +02003026/* prepare ssl context from servers options. Returns an error count */
Willy Tarreau03209342016-12-22 17:08:28 +01003027int ssl_sock_prepare_srv_ctx(struct server *srv)
Emeric Brun94324a42012-10-11 14:00:19 +02003028{
Willy Tarreau03209342016-12-22 17:08:28 +01003029 struct proxy *curproxy = srv->proxy;
Emeric Brun94324a42012-10-11 14:00:19 +02003030 int cfgerr = 0;
Remi Gacogneaf5c3da2014-05-19 10:29:58 +02003031 long options =
Emeric Brun94324a42012-10-11 14:00:19 +02003032 SSL_OP_ALL | /* all known workarounds for bugs */
3033 SSL_OP_NO_SSLv2 |
3034 SSL_OP_NO_COMPRESSION;
Remi Gacogneaf5c3da2014-05-19 10:29:58 +02003035 long mode =
Emeric Brun94324a42012-10-11 14:00:19 +02003036 SSL_MODE_ENABLE_PARTIAL_WRITE |
3037 SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER |
Willy Tarreau396a1862014-11-13 14:06:52 +01003038 SSL_MODE_RELEASE_BUFFERS |
3039 SSL_MODE_SMALL_BUFFERS;
Emeric Brun850efd52014-01-29 12:24:34 +01003040 int verify = SSL_VERIFY_NONE;
Emeric Brun94324a42012-10-11 14:00:19 +02003041
Thierry Fournier383085f2013-01-24 14:15:43 +01003042 /* Make sure openssl opens /dev/urandom before the chroot */
3043 if (!ssl_initialize_random()) {
3044 Alert("OpenSSL random data generator initialization failed.\n");
3045 cfgerr++;
3046 }
3047
Willy Tarreaufce03112015-01-15 21:32:40 +01003048 /* Automatic memory computations need to know we use SSL there */
3049 global.ssl_used_backend = 1;
3050
3051 /* Initiate SSL context for current server */
Emeric Brun94324a42012-10-11 14:00:19 +02003052 srv->ssl_ctx.reused_sess = NULL;
3053 if (srv->use_ssl)
3054 srv->xprt = &ssl_sock;
3055 if (srv->check.use_ssl)
Cyril Bonté9ce13112014-11-15 22:41:27 +01003056 srv->check.xprt = &ssl_sock;
Emeric Brun94324a42012-10-11 14:00:19 +02003057
3058 srv->ssl_ctx.ctx = SSL_CTX_new(SSLv23_client_method());
3059 if (!srv->ssl_ctx.ctx) {
3060 Alert("config : %s '%s', server '%s': unable to allocate ssl context.\n",
3061 proxy_type_str(curproxy), curproxy->id,
3062 srv->id);
3063 cfgerr++;
3064 return cfgerr;
3065 }
Emeric Bruna7aa3092012-10-26 12:58:00 +02003066 if (srv->ssl_ctx.client_crt) {
3067 if (SSL_CTX_use_PrivateKey_file(srv->ssl_ctx.ctx, srv->ssl_ctx.client_crt, SSL_FILETYPE_PEM) <= 0) {
3068 Alert("config : %s '%s', server '%s': unable to load SSL private key from PEM file '%s'.\n",
3069 proxy_type_str(curproxy), curproxy->id,
3070 srv->id, srv->ssl_ctx.client_crt);
3071 cfgerr++;
3072 }
3073 else if (SSL_CTX_use_certificate_chain_file(srv->ssl_ctx.ctx, srv->ssl_ctx.client_crt) <= 0) {
3074 Alert("config : %s '%s', server '%s': unable to load ssl certificate from PEM file '%s'.\n",
3075 proxy_type_str(curproxy), curproxy->id,
3076 srv->id, srv->ssl_ctx.client_crt);
3077 cfgerr++;
3078 }
3079 else if (SSL_CTX_check_private_key(srv->ssl_ctx.ctx) <= 0) {
3080 Alert("config : %s '%s', server '%s': inconsistencies between private key and certificate loaded from PEM file '%s'.\n",
3081 proxy_type_str(curproxy), curproxy->id,
3082 srv->id, srv->ssl_ctx.client_crt);
3083 cfgerr++;
3084 }
3085 }
Emeric Brun94324a42012-10-11 14:00:19 +02003086
3087 if (srv->ssl_ctx.options & SRV_SSL_O_NO_SSLV3)
3088 options |= SSL_OP_NO_SSLv3;
3089 if (srv->ssl_ctx.options & SRV_SSL_O_NO_TLSV10)
3090 options |= SSL_OP_NO_TLSv1;
3091 if (srv->ssl_ctx.options & SRV_SSL_O_NO_TLSV11)
3092 options |= SSL_OP_NO_TLSv1_1;
3093 if (srv->ssl_ctx.options & SRV_SSL_O_NO_TLSV12)
3094 options |= SSL_OP_NO_TLSv1_2;
Emeric Brunf9c5c472012-10-11 15:28:34 +02003095 if (srv->ssl_ctx.options & SRV_SSL_O_NO_TLS_TICKETS)
3096 options |= SSL_OP_NO_TICKET;
Jérémie Courrèges-Anglas17c3f622015-07-25 16:50:52 -06003097 if (srv->ssl_ctx.options & SRV_SSL_O_USE_SSLV3) {
3098#ifndef OPENSSL_NO_SSL3
Emeric Brun94324a42012-10-11 14:00:19 +02003099 SSL_CTX_set_ssl_version(srv->ssl_ctx.ctx, SSLv3_client_method());
Jérémie Courrèges-Anglas17c3f622015-07-25 16:50:52 -06003100#else
Thierry FOURNIERbc965342015-08-26 08:21:26 +02003101 Alert("SSLv3 support requested but unavailable.\n");
Jérémie Courrèges-Anglas17c3f622015-07-25 16:50:52 -06003102 cfgerr++;
3103#endif
3104 }
Emeric Brun94324a42012-10-11 14:00:19 +02003105 if (srv->ssl_ctx.options & SRV_SSL_O_USE_TLSV10)
3106 SSL_CTX_set_ssl_version(srv->ssl_ctx.ctx, TLSv1_client_method());
3107#if SSL_OP_NO_TLSv1_1
3108 if (srv->ssl_ctx.options & SRV_SSL_O_USE_TLSV11)
3109 SSL_CTX_set_ssl_version(srv->ssl_ctx.ctx, TLSv1_1_client_method());
3110#endif
3111#if SSL_OP_NO_TLSv1_2
3112 if (srv->ssl_ctx.options & SRV_SSL_O_USE_TLSV12)
3113 SSL_CTX_set_ssl_version(srv->ssl_ctx.ctx, TLSv1_2_client_method());
3114#endif
3115
3116 SSL_CTX_set_options(srv->ssl_ctx.ctx, options);
3117 SSL_CTX_set_mode(srv->ssl_ctx.ctx, mode);
Emeric Brun850efd52014-01-29 12:24:34 +01003118
3119 if (global.ssl_server_verify == SSL_SERVER_VERIFY_REQUIRED)
3120 verify = SSL_VERIFY_PEER;
3121
3122 switch (srv->ssl_ctx.verify) {
3123 case SSL_SOCK_VERIFY_NONE:
3124 verify = SSL_VERIFY_NONE;
3125 break;
3126 case SSL_SOCK_VERIFY_REQUIRED:
3127 verify = SSL_VERIFY_PEER;
3128 break;
3129 }
Evan Broderbe554312013-06-27 00:05:25 -07003130 SSL_CTX_set_verify(srv->ssl_ctx.ctx,
Emeric Brun850efd52014-01-29 12:24:34 +01003131 verify,
Evan Broderbe554312013-06-27 00:05:25 -07003132 srv->ssl_ctx.verify_host ? ssl_sock_srv_verifycbk : NULL);
Emeric Brun850efd52014-01-29 12:24:34 +01003133 if (verify & SSL_VERIFY_PEER) {
Emeric Brunef42d922012-10-11 16:11:36 +02003134 if (srv->ssl_ctx.ca_file) {
3135 /* load CAfile to verify */
3136 if (!SSL_CTX_load_verify_locations(srv->ssl_ctx.ctx, srv->ssl_ctx.ca_file, NULL)) {
Willy Tarreau07ba08b2014-02-16 19:22:08 +01003137 Alert("Proxy '%s', server '%s' [%s:%d] unable to load CA file '%s'.\n",
Emeric Brunef42d922012-10-11 16:11:36 +02003138 curproxy->id, srv->id,
3139 srv->conf.file, srv->conf.line, srv->ssl_ctx.ca_file);
3140 cfgerr++;
3141 }
3142 }
Emeric Brun850efd52014-01-29 12:24:34 +01003143 else {
3144 if (global.ssl_server_verify == SSL_SERVER_VERIFY_REQUIRED)
Willy Tarreau07ba08b2014-02-16 19:22:08 +01003145 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 +01003146 curproxy->id, srv->id,
3147 srv->conf.file, srv->conf.line);
3148 else
Willy Tarreau07ba08b2014-02-16 19:22:08 +01003149 Alert("Proxy '%s', server '%s' [%s:%d] verify is enabled but no CA file specified.\n",
Emeric Brun850efd52014-01-29 12:24:34 +01003150 curproxy->id, srv->id,
3151 srv->conf.file, srv->conf.line);
3152 cfgerr++;
3153 }
Emeric Brunef42d922012-10-11 16:11:36 +02003154#ifdef X509_V_FLAG_CRL_CHECK
3155 if (srv->ssl_ctx.crl_file) {
3156 X509_STORE *store = SSL_CTX_get_cert_store(srv->ssl_ctx.ctx);
3157
3158 if (!store || !X509_STORE_load_locations(store, srv->ssl_ctx.crl_file, NULL)) {
Willy Tarreau07ba08b2014-02-16 19:22:08 +01003159 Alert("Proxy '%s', server '%s' [%s:%d] unable to configure CRL file '%s'.\n",
Emeric Brunef42d922012-10-11 16:11:36 +02003160 curproxy->id, srv->id,
3161 srv->conf.file, srv->conf.line, srv->ssl_ctx.crl_file);
3162 cfgerr++;
3163 }
3164 else {
3165 X509_STORE_set_flags(store, X509_V_FLAG_CRL_CHECK|X509_V_FLAG_CRL_CHECK_ALL);
3166 }
3167 }
3168#endif
3169 }
3170
Emeric Brun4f65bff2012-11-16 15:11:00 +01003171 if (global.tune.ssllifetime)
3172 SSL_CTX_set_timeout(srv->ssl_ctx.ctx, global.tune.ssllifetime);
3173
Emeric Brun94324a42012-10-11 14:00:19 +02003174 SSL_CTX_set_session_cache_mode(srv->ssl_ctx.ctx, SSL_SESS_CACHE_OFF);
3175 if (srv->ssl_ctx.ciphers &&
3176 !SSL_CTX_set_cipher_list(srv->ssl_ctx.ctx, srv->ssl_ctx.ciphers)) {
3177 Alert("Proxy '%s', server '%s' [%s:%d] : unable to set SSL cipher list to '%s'.\n",
3178 curproxy->id, srv->id,
3179 srv->conf.file, srv->conf.line, srv->ssl_ctx.ciphers);
3180 cfgerr++;
3181 }
3182
3183 return cfgerr;
3184}
3185
Willy Tarreau2a65ff02012-09-13 17:54:29 +02003186/* Walks down the two trees in bind_conf and prepares all certs. The pointer may
Emeric Brunfc0421f2012-09-07 17:30:07 +02003187 * be NULL, in which case nothing is done. Returns the number of errors
3188 * encountered.
3189 */
Willy Tarreau03209342016-12-22 17:08:28 +01003190int ssl_sock_prepare_all_ctx(struct bind_conf *bind_conf)
Emeric Brunfc0421f2012-09-07 17:30:07 +02003191{
3192 struct ebmb_node *node;
3193 struct sni_ctx *sni;
3194 int err = 0;
3195
Willy Tarreau2a65ff02012-09-13 17:54:29 +02003196 if (!bind_conf || !bind_conf->is_ssl)
Emeric Brunfc0421f2012-09-07 17:30:07 +02003197 return 0;
3198
Willy Tarreaufce03112015-01-15 21:32:40 +01003199 /* Automatic memory computations need to know we use SSL there */
3200 global.ssl_used_frontend = 1;
3201
Emeric Brun0bed9942014-10-30 19:25:24 +01003202 if (bind_conf->default_ctx)
Willy Tarreau03209342016-12-22 17:08:28 +01003203 err += ssl_sock_prepare_ctx(bind_conf, bind_conf->default_ctx);
Emeric Brun0bed9942014-10-30 19:25:24 +01003204
Willy Tarreau2a65ff02012-09-13 17:54:29 +02003205 node = ebmb_first(&bind_conf->sni_ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02003206 while (node) {
3207 sni = ebmb_entry(node, struct sni_ctx, name);
Emeric Brun0bed9942014-10-30 19:25:24 +01003208 if (!sni->order && sni->ctx != bind_conf->default_ctx)
3209 /* only initialize the CTX on its first occurrence and
3210 if it is not the default_ctx */
Willy Tarreau03209342016-12-22 17:08:28 +01003211 err += ssl_sock_prepare_ctx(bind_conf, sni->ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02003212 node = ebmb_next(node);
3213 }
3214
Willy Tarreau2a65ff02012-09-13 17:54:29 +02003215 node = ebmb_first(&bind_conf->sni_w_ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02003216 while (node) {
3217 sni = ebmb_entry(node, struct sni_ctx, name);
Emeric Brun0bed9942014-10-30 19:25:24 +01003218 if (!sni->order && sni->ctx != bind_conf->default_ctx)
3219 /* only initialize the CTX on its first occurrence and
3220 if it is not the default_ctx */
Willy Tarreau03209342016-12-22 17:08:28 +01003221 err += ssl_sock_prepare_ctx(bind_conf, sni->ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02003222 node = ebmb_next(node);
3223 }
3224 return err;
3225}
3226
Willy Tarreau55d37912016-12-21 23:38:39 +01003227/* Prepares all the contexts for a bind_conf and allocates the shared SSL
3228 * context if needed. Returns < 0 on error, 0 on success. The warnings and
3229 * alerts are directly emitted since the rest of the stack does it below.
3230 */
3231int ssl_sock_prepare_bind_conf(struct bind_conf *bind_conf)
3232{
3233 struct proxy *px = bind_conf->frontend;
3234 int alloc_ctx;
3235 int err;
3236
3237 if (!bind_conf->is_ssl) {
3238 if (bind_conf->default_ctx) {
3239 Warning("Proxy '%s': A certificate was specified but SSL was not enabled on bind '%s' at [%s:%d] (use 'ssl').\n",
3240 px->id, bind_conf->arg, bind_conf->file, bind_conf->line);
3241 }
3242 return 0;
3243 }
3244 if (!bind_conf->default_ctx) {
3245 Alert("Proxy '%s': no SSL certificate specified for bind '%s' at [%s:%d] (use 'crt').\n",
3246 px->id, bind_conf->arg, bind_conf->file, bind_conf->line);
3247 return -1;
3248 }
3249
3250 alloc_ctx = shared_context_init(global.tune.sslcachesize, (!global.tune.sslprivatecache && (global.nbproc > 1)) ? 1 : 0);
3251 if (alloc_ctx < 0) {
3252 if (alloc_ctx == SHCTX_E_INIT_LOCK)
3253 Alert("Unable to initialize the lock for the shared SSL session cache. You can retry using the global statement 'tune.ssl.force-private-cache' but it could increase CPU usage due to renegotiations if nbproc > 1.\n");
3254 else
3255 Alert("Unable to allocate SSL session cache.\n");
3256 return -1;
3257 }
3258
3259 err = 0;
3260 /* initialize all certificate contexts */
3261 err += ssl_sock_prepare_all_ctx(bind_conf);
3262
3263 /* initialize CA variables if the certificates generation is enabled */
3264 err += ssl_sock_load_ca(bind_conf);
3265
3266 return -err;
3267}
Christopher Faulet77fe80c2015-07-29 13:02:40 +02003268
3269/* release ssl context allocated for servers. */
3270void ssl_sock_free_srv_ctx(struct server *srv)
3271{
3272 if (srv->ssl_ctx.ctx)
3273 SSL_CTX_free(srv->ssl_ctx.ctx);
3274}
3275
Willy Tarreau2a65ff02012-09-13 17:54:29 +02003276/* Walks down the two trees in bind_conf and frees all the certs. The pointer may
Emeric Brunfc0421f2012-09-07 17:30:07 +02003277 * be NULL, in which case nothing is done. The default_ctx is nullified too.
3278 */
Willy Tarreau2a65ff02012-09-13 17:54:29 +02003279void ssl_sock_free_all_ctx(struct bind_conf *bind_conf)
Emeric Brunfc0421f2012-09-07 17:30:07 +02003280{
3281 struct ebmb_node *node, *back;
3282 struct sni_ctx *sni;
3283
Willy Tarreau2a65ff02012-09-13 17:54:29 +02003284 if (!bind_conf || !bind_conf->is_ssl)
Emeric Brunfc0421f2012-09-07 17:30:07 +02003285 return;
3286
Willy Tarreau2a65ff02012-09-13 17:54:29 +02003287 node = ebmb_first(&bind_conf->sni_ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02003288 while (node) {
3289 sni = ebmb_entry(node, struct sni_ctx, name);
3290 back = ebmb_next(node);
3291 ebmb_delete(node);
3292 if (!sni->order) /* only free the CTX on its first occurrence */
3293 SSL_CTX_free(sni->ctx);
3294 free(sni);
3295 node = back;
3296 }
3297
Willy Tarreau2a65ff02012-09-13 17:54:29 +02003298 node = ebmb_first(&bind_conf->sni_w_ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02003299 while (node) {
3300 sni = ebmb_entry(node, struct sni_ctx, name);
3301 back = ebmb_next(node);
3302 ebmb_delete(node);
3303 if (!sni->order) /* only free the CTX on its first occurrence */
3304 SSL_CTX_free(sni->ctx);
3305 free(sni);
3306 node = back;
3307 }
3308
Willy Tarreau2a65ff02012-09-13 17:54:29 +02003309 bind_conf->default_ctx = NULL;
Emeric Brune1f38db2012-09-03 20:36:47 +02003310}
3311
Willy Tarreau795cdab2016-12-22 17:30:54 +01003312/* Destroys all the contexts for a bind_conf. This is used during deinit(). */
3313void ssl_sock_destroy_bind_conf(struct bind_conf *bind_conf)
3314{
3315 ssl_sock_free_ca(bind_conf);
3316 ssl_sock_free_all_ctx(bind_conf);
3317 free(bind_conf->ca_file);
3318 free(bind_conf->ca_sign_file);
3319 free(bind_conf->ca_sign_pass);
3320 free(bind_conf->ciphers);
3321 free(bind_conf->ecdhe);
3322 free(bind_conf->crl_file);
3323 if (bind_conf->keys_ref) {
3324 free(bind_conf->keys_ref->filename);
3325 free(bind_conf->keys_ref->tlskeys);
3326 LIST_DEL(&bind_conf->keys_ref->list);
3327 free(bind_conf->keys_ref);
3328 }
3329 bind_conf->keys_ref = NULL;
3330 bind_conf->crl_file = NULL;
3331 bind_conf->ecdhe = NULL;
3332 bind_conf->ciphers = NULL;
3333 bind_conf->ca_sign_pass = NULL;
3334 bind_conf->ca_sign_file = NULL;
3335 bind_conf->ca_file = NULL;
3336}
3337
Christopher Faulet31af49d2015-06-09 17:29:50 +02003338/* Load CA cert file and private key used to generate certificates */
3339int
Willy Tarreau03209342016-12-22 17:08:28 +01003340ssl_sock_load_ca(struct bind_conf *bind_conf)
Christopher Faulet31af49d2015-06-09 17:29:50 +02003341{
Willy Tarreau03209342016-12-22 17:08:28 +01003342 struct proxy *px = bind_conf->frontend;
Christopher Faulet31af49d2015-06-09 17:29:50 +02003343 FILE *fp;
3344 X509 *cacert = NULL;
3345 EVP_PKEY *capkey = NULL;
3346 int err = 0;
3347
3348 if (!bind_conf || !bind_conf->generate_certs)
3349 return err;
3350
Willy Tarreaua84c2672015-10-09 12:10:13 +02003351#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Christopher Fauletd2cab922015-07-28 16:03:47 +02003352 if (global.tune.ssl_ctx_cache)
3353 ssl_ctx_lru_tree = lru64_new(global.tune.ssl_ctx_cache);
3354 ssl_ctx_lru_seed = (unsigned int)time(NULL);
Willy Tarreaua84c2672015-10-09 12:10:13 +02003355#endif
Christopher Fauletd2cab922015-07-28 16:03:47 +02003356
Christopher Faulet31af49d2015-06-09 17:29:50 +02003357 if (!bind_conf->ca_sign_file) {
3358 Alert("Proxy '%s': cannot enable certificate generation, "
3359 "no CA certificate File configured at [%s:%d].\n",
3360 px->id, bind_conf->file, bind_conf->line);
Christopher Faulet31af49d2015-06-09 17:29:50 +02003361 goto load_error;
Christopher Fauletc6f02fb2015-10-09 10:53:31 +02003362 }
Christopher Faulet31af49d2015-06-09 17:29:50 +02003363
3364 /* read in the CA certificate */
3365 if (!(fp = fopen(bind_conf->ca_sign_file, "r"))) {
3366 Alert("Proxy '%s': Failed to read CA certificate file '%s' at [%s:%d].\n",
3367 px->id, bind_conf->ca_sign_file, bind_conf->file, bind_conf->line);
Christopher Faulet31af49d2015-06-09 17:29:50 +02003368 goto load_error;
3369 }
3370 if (!(cacert = PEM_read_X509(fp, NULL, NULL, NULL))) {
3371 Alert("Proxy '%s': Failed to read CA certificate file '%s' at [%s:%d].\n",
3372 px->id, bind_conf->ca_sign_file, bind_conf->file, bind_conf->line);
Christopher Fauletc6f02fb2015-10-09 10:53:31 +02003373 goto read_error;
Christopher Faulet31af49d2015-06-09 17:29:50 +02003374 }
Christopher Fauletc6f02fb2015-10-09 10:53:31 +02003375 rewind(fp);
Christopher Faulet31af49d2015-06-09 17:29:50 +02003376 if (!(capkey = PEM_read_PrivateKey(fp, NULL, NULL, bind_conf->ca_sign_pass))) {
3377 Alert("Proxy '%s': Failed to read CA private key file '%s' at [%s:%d].\n",
3378 px->id, bind_conf->ca_sign_file, bind_conf->file, bind_conf->line);
Christopher Fauletc6f02fb2015-10-09 10:53:31 +02003379 goto read_error;
Christopher Faulet31af49d2015-06-09 17:29:50 +02003380 }
Christopher Faulet31af49d2015-06-09 17:29:50 +02003381
Christopher Fauletc6f02fb2015-10-09 10:53:31 +02003382 fclose (fp);
Christopher Faulet31af49d2015-06-09 17:29:50 +02003383 bind_conf->ca_sign_cert = cacert;
3384 bind_conf->ca_sign_pkey = capkey;
3385 return err;
3386
Christopher Fauletc6f02fb2015-10-09 10:53:31 +02003387 read_error:
3388 fclose (fp);
Christopher Faulet31af49d2015-06-09 17:29:50 +02003389 if (capkey) EVP_PKEY_free(capkey);
3390 if (cacert) X509_free(cacert);
Christopher Fauletc6f02fb2015-10-09 10:53:31 +02003391 load_error:
3392 bind_conf->generate_certs = 0;
3393 err++;
Christopher Faulet31af49d2015-06-09 17:29:50 +02003394 return err;
3395}
3396
3397/* Release CA cert and private key used to generate certificated */
3398void
3399ssl_sock_free_ca(struct bind_conf *bind_conf)
3400{
3401 if (!bind_conf)
3402 return;
3403
3404 if (bind_conf->ca_sign_pkey)
3405 EVP_PKEY_free(bind_conf->ca_sign_pkey);
3406 if (bind_conf->ca_sign_cert)
3407 X509_free(bind_conf->ca_sign_cert);
Willy Tarreau94ff03a2016-12-22 17:57:46 +01003408 bind_conf->ca_sign_pkey = NULL;
3409 bind_conf->ca_sign_cert = NULL;
Christopher Faulet31af49d2015-06-09 17:29:50 +02003410}
3411
Emeric Brun46591952012-05-18 15:47:34 +02003412/*
3413 * This function is called if SSL * context is not yet allocated. The function
3414 * is designed to be called before any other data-layer operation and sets the
3415 * handshake flag on the connection. It is safe to call it multiple times.
3416 * It returns 0 on success and -1 in error case.
3417 */
3418static int ssl_sock_init(struct connection *conn)
3419{
3420 /* already initialized */
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02003421 if (conn->xprt_ctx)
Emeric Brun46591952012-05-18 15:47:34 +02003422 return 0;
3423
Willy Tarreau3c728722014-01-23 13:50:42 +01003424 if (!conn_ctrl_ready(conn))
Willy Tarreauf79c8172013-10-21 16:30:56 +02003425 return 0;
3426
Willy Tarreau20879a02012-12-03 16:32:10 +01003427 if (global.maxsslconn && sslconns >= global.maxsslconn) {
3428 conn->err_code = CO_ER_SSL_TOO_MANY;
Willy Tarreau403edff2012-09-06 11:58:37 +02003429 return -1;
Willy Tarreau20879a02012-12-03 16:32:10 +01003430 }
Willy Tarreau403edff2012-09-06 11:58:37 +02003431
Emeric Brun46591952012-05-18 15:47:34 +02003432 /* If it is in client mode initiate SSL session
3433 in connect state otherwise accept state */
Willy Tarreau3fdb3662012-11-12 00:42:33 +01003434 if (objt_server(conn->target)) {
Willy Tarreaufba03cd2014-11-13 13:48:58 +01003435 int may_retry = 1;
3436
3437 retry_connect:
Emeric Brun46591952012-05-18 15:47:34 +02003438 /* Alloc a new SSL session ctx */
Willy Tarreau3fdb3662012-11-12 00:42:33 +01003439 conn->xprt_ctx = SSL_new(objt_server(conn->target)->ssl_ctx.ctx);
Willy Tarreau20879a02012-12-03 16:32:10 +01003440 if (!conn->xprt_ctx) {
Willy Tarreaufba03cd2014-11-13 13:48:58 +01003441 if (may_retry--) {
3442 pool_gc2();
3443 goto retry_connect;
3444 }
Willy Tarreau20879a02012-12-03 16:32:10 +01003445 conn->err_code = CO_ER_SSL_NO_MEM;
Emeric Brun46591952012-05-18 15:47:34 +02003446 return -1;
Willy Tarreau20879a02012-12-03 16:32:10 +01003447 }
Emeric Brun46591952012-05-18 15:47:34 +02003448
Emeric Brun46591952012-05-18 15:47:34 +02003449 /* set fd on SSL session context */
Emeric Brun55476152014-11-12 17:35:37 +01003450 if (!SSL_set_fd(conn->xprt_ctx, conn->t.sock.fd)) {
3451 SSL_free(conn->xprt_ctx);
3452 conn->xprt_ctx = NULL;
Willy Tarreaufba03cd2014-11-13 13:48:58 +01003453 if (may_retry--) {
3454 pool_gc2();
3455 goto retry_connect;
3456 }
Emeric Brun55476152014-11-12 17:35:37 +01003457 conn->err_code = CO_ER_SSL_NO_MEM;
3458 return -1;
3459 }
Emeric Brun46591952012-05-18 15:47:34 +02003460
Evan Broderbe554312013-06-27 00:05:25 -07003461 /* set connection pointer */
Emeric Brun55476152014-11-12 17:35:37 +01003462 if (!SSL_set_app_data(conn->xprt_ctx, conn)) {
3463 SSL_free(conn->xprt_ctx);
3464 conn->xprt_ctx = NULL;
Willy Tarreaufba03cd2014-11-13 13:48:58 +01003465 if (may_retry--) {
3466 pool_gc2();
3467 goto retry_connect;
3468 }
Emeric Brun55476152014-11-12 17:35:37 +01003469 conn->err_code = CO_ER_SSL_NO_MEM;
3470 return -1;
3471 }
3472
3473 SSL_set_connect_state(conn->xprt_ctx);
3474 if (objt_server(conn->target)->ssl_ctx.reused_sess) {
3475 if(!SSL_set_session(conn->xprt_ctx, objt_server(conn->target)->ssl_ctx.reused_sess)) {
3476 SSL_SESSION_free(objt_server(conn->target)->ssl_ctx.reused_sess);
3477 objt_server(conn->target)->ssl_ctx.reused_sess = NULL;
3478 }
3479 }
Evan Broderbe554312013-06-27 00:05:25 -07003480
Emeric Brun46591952012-05-18 15:47:34 +02003481 /* leave init state and start handshake */
Willy Tarreau05737472012-09-04 08:03:39 +02003482 conn->flags |= CO_FL_SSL_WAIT_HS | CO_FL_WAIT_L6_CONN;
Willy Tarreau403edff2012-09-06 11:58:37 +02003483
3484 sslconns++;
Willy Tarreau71b734c2014-01-28 15:19:44 +01003485 totalsslconns++;
Emeric Brun46591952012-05-18 15:47:34 +02003486 return 0;
3487 }
Willy Tarreau3fdb3662012-11-12 00:42:33 +01003488 else if (objt_listener(conn->target)) {
Willy Tarreaufba03cd2014-11-13 13:48:58 +01003489 int may_retry = 1;
3490
3491 retry_accept:
Emeric Brun46591952012-05-18 15:47:34 +02003492 /* Alloc a new SSL session ctx */
Willy Tarreau3fdb3662012-11-12 00:42:33 +01003493 conn->xprt_ctx = SSL_new(objt_listener(conn->target)->bind_conf->default_ctx);
Willy Tarreau20879a02012-12-03 16:32:10 +01003494 if (!conn->xprt_ctx) {
Willy Tarreaufba03cd2014-11-13 13:48:58 +01003495 if (may_retry--) {
3496 pool_gc2();
3497 goto retry_accept;
3498 }
Willy Tarreau20879a02012-12-03 16:32:10 +01003499 conn->err_code = CO_ER_SSL_NO_MEM;
Emeric Brun46591952012-05-18 15:47:34 +02003500 return -1;
Willy Tarreau20879a02012-12-03 16:32:10 +01003501 }
Emeric Brun46591952012-05-18 15:47:34 +02003502
Emeric Brun46591952012-05-18 15:47:34 +02003503 /* set fd on SSL session context */
Emeric Brun55476152014-11-12 17:35:37 +01003504 if (!SSL_set_fd(conn->xprt_ctx, conn->t.sock.fd)) {
3505 SSL_free(conn->xprt_ctx);
3506 conn->xprt_ctx = NULL;
Willy Tarreaufba03cd2014-11-13 13:48:58 +01003507 if (may_retry--) {
3508 pool_gc2();
3509 goto retry_accept;
3510 }
Emeric Brun55476152014-11-12 17:35:37 +01003511 conn->err_code = CO_ER_SSL_NO_MEM;
3512 return -1;
3513 }
Emeric Brun46591952012-05-18 15:47:34 +02003514
Emeric Brune1f38db2012-09-03 20:36:47 +02003515 /* set connection pointer */
Emeric Brun55476152014-11-12 17:35:37 +01003516 if (!SSL_set_app_data(conn->xprt_ctx, conn)) {
3517 SSL_free(conn->xprt_ctx);
3518 conn->xprt_ctx = NULL;
Willy Tarreaufba03cd2014-11-13 13:48:58 +01003519 if (may_retry--) {
3520 pool_gc2();
3521 goto retry_accept;
3522 }
Emeric Brun55476152014-11-12 17:35:37 +01003523 conn->err_code = CO_ER_SSL_NO_MEM;
3524 return -1;
3525 }
3526
3527 SSL_set_accept_state(conn->xprt_ctx);
Emeric Brune1f38db2012-09-03 20:36:47 +02003528
Emeric Brun46591952012-05-18 15:47:34 +02003529 /* leave init state and start handshake */
Willy Tarreau05737472012-09-04 08:03:39 +02003530 conn->flags |= CO_FL_SSL_WAIT_HS | CO_FL_WAIT_L6_CONN;
Willy Tarreau403edff2012-09-06 11:58:37 +02003531
3532 sslconns++;
Willy Tarreau71b734c2014-01-28 15:19:44 +01003533 totalsslconns++;
Emeric Brun46591952012-05-18 15:47:34 +02003534 return 0;
3535 }
3536 /* don't know how to handle such a target */
Willy Tarreau20879a02012-12-03 16:32:10 +01003537 conn->err_code = CO_ER_SSL_NO_TARGET;
Emeric Brun46591952012-05-18 15:47:34 +02003538 return -1;
3539}
3540
3541
3542/* This is the callback which is used when an SSL handshake is pending. It
3543 * updates the FD status if it wants some polling before being called again.
3544 * It returns 0 if it fails in a fatal way or needs to poll to go further,
3545 * otherwise it returns non-zero and removes itself from the connection's
3546 * flags (the bit is provided in <flag> by the caller).
3547 */
3548int ssl_sock_handshake(struct connection *conn, unsigned int flag)
3549{
3550 int ret;
3551
Willy Tarreau3c728722014-01-23 13:50:42 +01003552 if (!conn_ctrl_ready(conn))
Willy Tarreauf79c8172013-10-21 16:30:56 +02003553 return 0;
3554
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02003555 if (!conn->xprt_ctx)
Emeric Brun46591952012-05-18 15:47:34 +02003556 goto out_error;
3557
Emeric Brun674b7432012-11-08 19:21:55 +01003558 /* If we use SSL_do_handshake to process a reneg initiated by
3559 * the remote peer, it sometimes returns SSL_ERROR_SSL.
3560 * Usually SSL_write and SSL_read are used and process implicitly
3561 * the reneg handshake.
3562 * Here we use SSL_peek as a workaround for reneg.
3563 */
3564 if ((conn->flags & CO_FL_CONNECTED) && SSL_renegotiate_pending(conn->xprt_ctx)) {
3565 char c;
3566
3567 ret = SSL_peek(conn->xprt_ctx, &c, 1);
3568 if (ret <= 0) {
3569 /* handshake may have not been completed, let's find why */
3570 ret = SSL_get_error(conn->xprt_ctx, ret);
3571 if (ret == SSL_ERROR_WANT_WRITE) {
3572 /* SSL handshake needs to write, L4 connection may not be ready */
3573 __conn_sock_stop_recv(conn);
Willy Tarreaue1f50c42014-01-22 20:02:06 +01003574 __conn_sock_want_send(conn);
3575 fd_cant_send(conn->t.sock.fd);
Emeric Brun674b7432012-11-08 19:21:55 +01003576 return 0;
3577 }
3578 else if (ret == SSL_ERROR_WANT_READ) {
3579 /* handshake may have been completed but we have
3580 * no more data to read.
3581 */
3582 if (!SSL_renegotiate_pending(conn->xprt_ctx)) {
3583 ret = 1;
3584 goto reneg_ok;
3585 }
3586 /* SSL handshake needs to read, L4 connection is ready */
3587 if (conn->flags & CO_FL_WAIT_L4_CONN)
3588 conn->flags &= ~CO_FL_WAIT_L4_CONN;
3589 __conn_sock_stop_send(conn);
Willy Tarreaue1f50c42014-01-22 20:02:06 +01003590 __conn_sock_want_recv(conn);
3591 fd_cant_recv(conn->t.sock.fd);
Emeric Brun674b7432012-11-08 19:21:55 +01003592 return 0;
3593 }
3594 else if (ret == SSL_ERROR_SYSCALL) {
3595 /* if errno is null, then connection was successfully established */
3596 if (!errno && conn->flags & CO_FL_WAIT_L4_CONN)
3597 conn->flags &= ~CO_FL_WAIT_L4_CONN;
Willy Tarreau20879a02012-12-03 16:32:10 +01003598 if (!conn->err_code) {
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02003599 int empty_handshake;
Luca Pizzamiglio578b1692016-12-12 10:56:56 +01003600#if (OPENSSL_VERSION_NUMBER >= 0x1010000fL) && !defined(LIBRESSL_VERSION_NUMBER)
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02003601 OSSL_HANDSHAKE_STATE state = SSL_get_state((SSL *)conn->xprt_ctx);
3602 empty_handshake = state == TLS_ST_BEFORE;
3603#else
3604 empty_handshake = !((SSL *)conn->xprt_ctx)->packet_length;
3605#endif
3606
3607 if (empty_handshake) {
Emeric Brun29f037d2014-04-25 19:05:36 +02003608 if (!errno) {
3609 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
3610 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
3611 else
3612 conn->err_code = CO_ER_SSL_EMPTY;
3613 }
3614 else {
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_ABORT;
3619 }
3620 }
3621 else {
3622 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
3623 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
Willy Tarreau20879a02012-12-03 16:32:10 +01003624 else
Emeric Brun29f037d2014-04-25 19:05:36 +02003625 conn->err_code = CO_ER_SSL_HANDSHAKE;
3626 }
Willy Tarreau20879a02012-12-03 16:32:10 +01003627 }
Emeric Brun674b7432012-11-08 19:21:55 +01003628 goto out_error;
3629 }
3630 else {
3631 /* Fail on all other handshake errors */
3632 /* Note: OpenSSL may leave unread bytes in the socket's
3633 * buffer, causing an RST to be emitted upon close() on
3634 * TCP sockets. We first try to drain possibly pending
3635 * data to avoid this as much as possible.
3636 */
Willy Tarreaud85c4852015-03-13 00:40:28 +01003637 conn_sock_drain(conn);
Willy Tarreau20879a02012-12-03 16:32:10 +01003638 if (!conn->err_code)
Willy Tarreauf51c6982014-04-25 20:02:39 +02003639 conn->err_code = (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT) ?
3640 CO_ER_SSL_KILLED_HB : CO_ER_SSL_HANDSHAKE;
Emeric Brun674b7432012-11-08 19:21:55 +01003641 goto out_error;
3642 }
3643 }
3644 /* read some data: consider handshake completed */
3645 goto reneg_ok;
3646 }
3647
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02003648 ret = SSL_do_handshake(conn->xprt_ctx);
Emeric Brun46591952012-05-18 15:47:34 +02003649 if (ret != 1) {
3650 /* handshake did not complete, let's find why */
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02003651 ret = SSL_get_error(conn->xprt_ctx, ret);
Emeric Brun46591952012-05-18 15:47:34 +02003652
3653 if (ret == SSL_ERROR_WANT_WRITE) {
3654 /* SSL handshake needs to write, L4 connection may not be ready */
3655 __conn_sock_stop_recv(conn);
Willy Tarreaue1f50c42014-01-22 20:02:06 +01003656 __conn_sock_want_send(conn);
3657 fd_cant_send(conn->t.sock.fd);
Emeric Brun46591952012-05-18 15:47:34 +02003658 return 0;
3659 }
3660 else if (ret == SSL_ERROR_WANT_READ) {
3661 /* SSL handshake needs to read, L4 connection is ready */
3662 if (conn->flags & CO_FL_WAIT_L4_CONN)
3663 conn->flags &= ~CO_FL_WAIT_L4_CONN;
3664 __conn_sock_stop_send(conn);
Willy Tarreaue1f50c42014-01-22 20:02:06 +01003665 __conn_sock_want_recv(conn);
3666 fd_cant_recv(conn->t.sock.fd);
Emeric Brun46591952012-05-18 15:47:34 +02003667 return 0;
3668 }
Willy Tarreau89230192012-09-28 20:22:13 +02003669 else if (ret == SSL_ERROR_SYSCALL) {
Luca Pizzamiglio578b1692016-12-12 10:56:56 +01003670#if (OPENSSL_VERSION_NUMBER >= 0x1010000fL) && !defined(LIBRESSL_VERSION_NUMBER)
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02003671 OSSL_HANDSHAKE_STATE state;
3672#endif
3673 int empty_handshake;
Willy Tarreau89230192012-09-28 20:22:13 +02003674 /* if errno is null, then connection was successfully established */
3675 if (!errno && conn->flags & CO_FL_WAIT_L4_CONN)
3676 conn->flags &= ~CO_FL_WAIT_L4_CONN;
Willy Tarreau20879a02012-12-03 16:32:10 +01003677
Luca Pizzamiglio578b1692016-12-12 10:56:56 +01003678#if (OPENSSL_VERSION_NUMBER >= 0x1010000fL) && !defined(LIBRESSL_VERSION_NUMBER)
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02003679 state = SSL_get_state((SSL *)conn->xprt_ctx);
3680 empty_handshake = state == TLS_ST_BEFORE;
3681#else
3682 empty_handshake = !((SSL *)conn->xprt_ctx)->packet_length;
3683#endif
3684 if (empty_handshake) {
Emeric Brun29f037d2014-04-25 19:05:36 +02003685 if (!errno) {
3686 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
3687 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
3688 else
3689 conn->err_code = CO_ER_SSL_EMPTY;
3690 }
3691 else {
3692 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
3693 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
3694 else
3695 conn->err_code = CO_ER_SSL_ABORT;
3696 }
3697 }
3698 else {
3699 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
3700 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
Willy Tarreau20879a02012-12-03 16:32:10 +01003701 else
Emeric Brun29f037d2014-04-25 19:05:36 +02003702 conn->err_code = CO_ER_SSL_HANDSHAKE;
3703 }
Willy Tarreau89230192012-09-28 20:22:13 +02003704 goto out_error;
3705 }
Emeric Brun46591952012-05-18 15:47:34 +02003706 else {
3707 /* Fail on all other handshake errors */
Willy Tarreau566dc552012-10-19 20:52:18 +02003708 /* Note: OpenSSL may leave unread bytes in the socket's
3709 * buffer, causing an RST to be emitted upon close() on
3710 * TCP sockets. We first try to drain possibly pending
3711 * data to avoid this as much as possible.
3712 */
Willy Tarreaud85c4852015-03-13 00:40:28 +01003713 conn_sock_drain(conn);
Willy Tarreau20879a02012-12-03 16:32:10 +01003714 if (!conn->err_code)
Willy Tarreauf51c6982014-04-25 20:02:39 +02003715 conn->err_code = (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT) ?
3716 CO_ER_SSL_KILLED_HB : CO_ER_SSL_HANDSHAKE;
Emeric Brun46591952012-05-18 15:47:34 +02003717 goto out_error;
3718 }
3719 }
3720
Emeric Brun674b7432012-11-08 19:21:55 +01003721reneg_ok:
Emeric Brun46591952012-05-18 15:47:34 +02003722 /* Handshake succeeded */
Willy Tarreau0c9c2722014-05-28 12:28:58 +02003723 if (!SSL_session_reused(conn->xprt_ctx)) {
3724 if (objt_server(conn->target)) {
3725 update_freq_ctr(&global.ssl_be_keys_per_sec, 1);
3726 if (global.ssl_be_keys_per_sec.curr_ctr > global.ssl_be_keys_max)
3727 global.ssl_be_keys_max = global.ssl_be_keys_per_sec.curr_ctr;
3728
Emeric Brun46591952012-05-18 15:47:34 +02003729 /* check if session was reused, if not store current session on server for reuse */
Willy Tarreau30fd4bd2016-12-22 21:54:21 +01003730 if (objt_server(conn->target)->ssl_ctx.reused_sess) {
Willy Tarreau3fdb3662012-11-12 00:42:33 +01003731 SSL_SESSION_free(objt_server(conn->target)->ssl_ctx.reused_sess);
Willy Tarreau30fd4bd2016-12-22 21:54:21 +01003732 objt_server(conn->target)->ssl_ctx.reused_sess = NULL;
3733 }
Emeric Brun46591952012-05-18 15:47:34 +02003734
Willy Tarreau2a3fb1c2015-02-05 16:47:07 +01003735 if (!(objt_server(conn->target)->ssl_ctx.options & SRV_SSL_O_NO_REUSE))
3736 objt_server(conn->target)->ssl_ctx.reused_sess = SSL_get1_session(conn->xprt_ctx);
Emeric Brun46591952012-05-18 15:47:34 +02003737 }
Willy Tarreau0c9c2722014-05-28 12:28:58 +02003738 else {
3739 update_freq_ctr(&global.ssl_fe_keys_per_sec, 1);
3740 if (global.ssl_fe_keys_per_sec.curr_ctr > global.ssl_fe_keys_max)
3741 global.ssl_fe_keys_max = global.ssl_fe_keys_per_sec.curr_ctr;
3742 }
Emeric Brun46591952012-05-18 15:47:34 +02003743 }
3744
3745 /* The connection is now established at both layers, it's time to leave */
3746 conn->flags &= ~(flag | CO_FL_WAIT_L4_CONN | CO_FL_WAIT_L6_CONN);
3747 return 1;
3748
3749 out_error:
Emeric Brun644cde02012-12-14 11:21:13 +01003750 /* Clear openssl global errors stack */
Thierry FOURNIER / OZON.IO8b068c22016-10-10 11:59:50 +02003751 ssl_sock_dump_errors(conn);
Emeric Brun644cde02012-12-14 11:21:13 +01003752 ERR_clear_error();
3753
Emeric Brun9fa89732012-10-04 17:09:56 +02003754 /* free resumed session if exists */
Willy Tarreau3fdb3662012-11-12 00:42:33 +01003755 if (objt_server(conn->target) && objt_server(conn->target)->ssl_ctx.reused_sess) {
3756 SSL_SESSION_free(objt_server(conn->target)->ssl_ctx.reused_sess);
3757 objt_server(conn->target)->ssl_ctx.reused_sess = NULL;
Emeric Brun9fa89732012-10-04 17:09:56 +02003758 }
3759
Emeric Brun46591952012-05-18 15:47:34 +02003760 /* Fail on all other handshake errors */
3761 conn->flags |= CO_FL_ERROR;
Willy Tarreau20879a02012-12-03 16:32:10 +01003762 if (!conn->err_code)
3763 conn->err_code = CO_ER_SSL_HANDSHAKE;
Emeric Brun46591952012-05-18 15:47:34 +02003764 return 0;
3765}
3766
3767/* Receive up to <count> bytes from connection <conn>'s socket and store them
Willy Tarreauabf08d92014-01-14 11:31:27 +01003768 * into buffer <buf>. Only one call to recv() is performed, unless the
Emeric Brun46591952012-05-18 15:47:34 +02003769 * buffer wraps, in which case a second call may be performed. The connection's
3770 * flags are updated with whatever special event is detected (error, read0,
3771 * empty). The caller is responsible for taking care of those events and
3772 * avoiding the call if inappropriate. The function does not call the
3773 * connection's polling update function, so the caller is responsible for this.
3774 */
3775static int ssl_sock_to_buf(struct connection *conn, struct buffer *buf, int count)
3776{
3777 int ret, done = 0;
Willy Tarreauabf08d92014-01-14 11:31:27 +01003778 int try;
Emeric Brun46591952012-05-18 15:47:34 +02003779
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02003780 if (!conn->xprt_ctx)
Emeric Brun46591952012-05-18 15:47:34 +02003781 goto out_error;
3782
3783 if (conn->flags & CO_FL_HANDSHAKE)
3784 /* a handshake was requested */
3785 return 0;
3786
Willy Tarreauabf08d92014-01-14 11:31:27 +01003787 /* let's realign the buffer to optimize I/O */
3788 if (buffer_empty(buf))
Emeric Brun46591952012-05-18 15:47:34 +02003789 buf->p = buf->data;
Emeric Brun46591952012-05-18 15:47:34 +02003790
3791 /* read the largest possible block. For this, we perform only one call
3792 * to recv() unless the buffer wraps and we exactly fill the first hunk,
3793 * in which case we accept to do it once again. A new attempt is made on
3794 * EINTR too.
3795 */
Willy Tarreau00b0fb92014-01-17 11:09:40 +01003796 while (count > 0) {
Willy Tarreauabf08d92014-01-14 11:31:27 +01003797 /* first check if we have some room after p+i */
3798 try = buf->data + buf->size - (buf->p + buf->i);
3799 /* otherwise continue between data and p-o */
3800 if (try <= 0) {
3801 try = buf->p - (buf->data + buf->o);
3802 if (try <= 0)
3803 break;
3804 }
3805 if (try > count)
3806 try = count;
3807
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02003808 ret = SSL_read(conn->xprt_ctx, bi_end(buf), try);
Emeric Brune1f38db2012-09-03 20:36:47 +02003809 if (conn->flags & CO_FL_ERROR) {
3810 /* CO_FL_ERROR may be set by ssl_sock_infocbk */
Emeric Brun644cde02012-12-14 11:21:13 +01003811 goto out_error;
Emeric Brune1f38db2012-09-03 20:36:47 +02003812 }
Emeric Brun46591952012-05-18 15:47:34 +02003813 if (ret > 0) {
3814 buf->i += ret;
3815 done += ret;
3816 if (ret < try)
3817 break;
3818 count -= ret;
Emeric Brun46591952012-05-18 15:47:34 +02003819 }
3820 else if (ret == 0) {
Emeric Brun644cde02012-12-14 11:21:13 +01003821 ret = SSL_get_error(conn->xprt_ctx, ret);
3822 if (ret != SSL_ERROR_ZERO_RETURN) {
Emeric Brun1c646862012-12-14 12:33:41 +01003823 /* error on protocol or underlying transport */
3824 if ((ret != SSL_ERROR_SYSCALL)
3825 || (errno && (errno != EAGAIN)))
3826 conn->flags |= CO_FL_ERROR;
3827
Emeric Brun644cde02012-12-14 11:21:13 +01003828 /* Clear openssl global errors stack */
Thierry FOURNIER / OZON.IO8b068c22016-10-10 11:59:50 +02003829 ssl_sock_dump_errors(conn);
Emeric Brun644cde02012-12-14 11:21:13 +01003830 ERR_clear_error();
3831 }
Emeric Brun46591952012-05-18 15:47:34 +02003832 goto read0;
3833 }
3834 else {
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02003835 ret = SSL_get_error(conn->xprt_ctx, ret);
Emeric Brun46591952012-05-18 15:47:34 +02003836 if (ret == SSL_ERROR_WANT_WRITE) {
Emeric Brun8af8dd12012-11-08 17:56:20 +01003837 /* handshake is running, and it needs to enable write */
Emeric Brun46591952012-05-18 15:47:34 +02003838 conn->flags |= CO_FL_SSL_WAIT_HS;
Emeric Brun8af8dd12012-11-08 17:56:20 +01003839 __conn_sock_want_send(conn);
Emeric Brun46591952012-05-18 15:47:34 +02003840 break;
3841 }
3842 else if (ret == SSL_ERROR_WANT_READ) {
Emeric Brun282a76a2012-11-08 18:02:56 +01003843 if (SSL_renegotiate_pending(conn->xprt_ctx)) {
3844 /* handshake is running, and it may need to re-enable read */
3845 conn->flags |= CO_FL_SSL_WAIT_HS;
3846 __conn_sock_want_recv(conn);
3847 break;
3848 }
Emeric Brun46591952012-05-18 15:47:34 +02003849 /* we need to poll for retry a read later */
Willy Tarreaue1f50c42014-01-22 20:02:06 +01003850 fd_cant_recv(conn->t.sock.fd);
Emeric Brun46591952012-05-18 15:47:34 +02003851 break;
3852 }
3853 /* otherwise it's a real error */
3854 goto out_error;
3855 }
3856 }
3857 return done;
3858
3859 read0:
3860 conn_sock_read0(conn);
3861 return done;
3862 out_error:
Emeric Brun644cde02012-12-14 11:21:13 +01003863 /* Clear openssl global errors stack */
Thierry FOURNIER / OZON.IO8b068c22016-10-10 11:59:50 +02003864 ssl_sock_dump_errors(conn);
Emeric Brun644cde02012-12-14 11:21:13 +01003865 ERR_clear_error();
3866
Emeric Brun46591952012-05-18 15:47:34 +02003867 conn->flags |= CO_FL_ERROR;
3868 return done;
3869}
3870
3871
3872/* Send all pending bytes from buffer <buf> to connection <conn>'s socket.
Willy Tarreau1049b1f2014-02-02 01:51:17 +01003873 * <flags> may contain some CO_SFL_* flags to hint the system about other
3874 * pending data for example, but this flag is ignored at the moment.
Emeric Brun46591952012-05-18 15:47:34 +02003875 * Only one call to send() is performed, unless the buffer wraps, in which case
3876 * a second call may be performed. The connection's flags are updated with
3877 * whatever special event is detected (error, empty). The caller is responsible
3878 * for taking care of those events and avoiding the call if inappropriate. The
3879 * function does not call the connection's polling update function, so the caller
3880 * is responsible for this.
3881 */
3882static int ssl_sock_from_buf(struct connection *conn, struct buffer *buf, int flags)
3883{
3884 int ret, try, done;
3885
3886 done = 0;
3887
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02003888 if (!conn->xprt_ctx)
Emeric Brun46591952012-05-18 15:47:34 +02003889 goto out_error;
3890
3891 if (conn->flags & CO_FL_HANDSHAKE)
3892 /* a handshake was requested */
3893 return 0;
3894
3895 /* send the largest possible block. For this we perform only one call
3896 * to send() unless the buffer wraps and we exactly fill the first hunk,
3897 * in which case we accept to do it once again.
3898 */
3899 while (buf->o) {
Kevin Hestercad82342013-05-30 15:12:41 -07003900 try = bo_contig_data(buf);
Willy Tarreaubfd59462013-02-21 07:46:09 +01003901
Willy Tarreau7bed9452014-02-02 02:00:24 +01003902 if (!(flags & CO_SFL_STREAMER) &&
Willy Tarreau518cedd2014-02-17 15:43:01 +01003903 !(conn->xprt_st & SSL_SOCK_SEND_UNLIMITED) &&
3904 global.tune.ssl_max_record && try > global.tune.ssl_max_record) {
Willy Tarreaubfd59462013-02-21 07:46:09 +01003905 try = global.tune.ssl_max_record;
Willy Tarreau518cedd2014-02-17 15:43:01 +01003906 }
3907 else {
3908 /* we need to keep the information about the fact that
3909 * we're not limiting the upcoming send(), because if it
3910 * fails, we'll have to retry with at least as many data.
3911 */
3912 conn->xprt_st |= SSL_SOCK_SEND_UNLIMITED;
3913 }
Willy Tarreaubfd59462013-02-21 07:46:09 +01003914
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02003915 ret = SSL_write(conn->xprt_ctx, bo_ptr(buf), try);
Willy Tarreau518cedd2014-02-17 15:43:01 +01003916
Emeric Brune1f38db2012-09-03 20:36:47 +02003917 if (conn->flags & CO_FL_ERROR) {
3918 /* CO_FL_ERROR may be set by ssl_sock_infocbk */
Emeric Brun644cde02012-12-14 11:21:13 +01003919 goto out_error;
Emeric Brune1f38db2012-09-03 20:36:47 +02003920 }
Emeric Brun46591952012-05-18 15:47:34 +02003921 if (ret > 0) {
Willy Tarreau518cedd2014-02-17 15:43:01 +01003922 conn->xprt_st &= ~SSL_SOCK_SEND_UNLIMITED;
3923
Emeric Brun46591952012-05-18 15:47:34 +02003924 buf->o -= ret;
3925 done += ret;
3926
Willy Tarreau5fb38032012-12-16 19:39:09 +01003927 if (likely(buffer_empty(buf)))
Emeric Brun46591952012-05-18 15:47:34 +02003928 /* optimize data alignment in the buffer */
3929 buf->p = buf->data;
3930
3931 /* if the system buffer is full, don't insist */
3932 if (ret < try)
3933 break;
3934 }
3935 else {
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02003936 ret = SSL_get_error(conn->xprt_ctx, ret);
Emeric Brun46591952012-05-18 15:47:34 +02003937 if (ret == SSL_ERROR_WANT_WRITE) {
Emeric Brun282a76a2012-11-08 18:02:56 +01003938 if (SSL_renegotiate_pending(conn->xprt_ctx)) {
3939 /* handshake is running, and it may need to re-enable write */
3940 conn->flags |= CO_FL_SSL_WAIT_HS;
3941 __conn_sock_want_send(conn);
3942 break;
3943 }
Emeric Brun46591952012-05-18 15:47:34 +02003944 /* we need to poll to retry a write later */
Willy Tarreaue1f50c42014-01-22 20:02:06 +01003945 fd_cant_send(conn->t.sock.fd);
Emeric Brun46591952012-05-18 15:47:34 +02003946 break;
3947 }
3948 else if (ret == SSL_ERROR_WANT_READ) {
Emeric Brun8af8dd12012-11-08 17:56:20 +01003949 /* handshake is running, and it needs to enable read */
Emeric Brun46591952012-05-18 15:47:34 +02003950 conn->flags |= CO_FL_SSL_WAIT_HS;
Emeric Brun8af8dd12012-11-08 17:56:20 +01003951 __conn_sock_want_recv(conn);
Emeric Brun46591952012-05-18 15:47:34 +02003952 break;
3953 }
3954 goto out_error;
3955 }
3956 }
3957 return done;
3958
3959 out_error:
Emeric Brun644cde02012-12-14 11:21:13 +01003960 /* Clear openssl global errors stack */
Thierry FOURNIER / OZON.IO8b068c22016-10-10 11:59:50 +02003961 ssl_sock_dump_errors(conn);
Emeric Brun644cde02012-12-14 11:21:13 +01003962 ERR_clear_error();
3963
Emeric Brun46591952012-05-18 15:47:34 +02003964 conn->flags |= CO_FL_ERROR;
3965 return done;
3966}
3967
Emeric Brun46591952012-05-18 15:47:34 +02003968static void ssl_sock_close(struct connection *conn) {
3969
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02003970 if (conn->xprt_ctx) {
3971 SSL_free(conn->xprt_ctx);
3972 conn->xprt_ctx = NULL;
Willy Tarreau403edff2012-09-06 11:58:37 +02003973 sslconns--;
Emeric Brun46591952012-05-18 15:47:34 +02003974 }
Emeric Brun46591952012-05-18 15:47:34 +02003975}
3976
3977/* This function tries to perform a clean shutdown on an SSL connection, and in
3978 * any case, flags the connection as reusable if no handshake was in progress.
3979 */
3980static void ssl_sock_shutw(struct connection *conn, int clean)
3981{
3982 if (conn->flags & CO_FL_HANDSHAKE)
3983 return;
3984 /* no handshake was in progress, try a clean ssl shutdown */
Emeric Brun644cde02012-12-14 11:21:13 +01003985 if (clean && (SSL_shutdown(conn->xprt_ctx) <= 0)) {
3986 /* Clear openssl global errors stack */
Thierry FOURNIER / OZON.IO8b068c22016-10-10 11:59:50 +02003987 ssl_sock_dump_errors(conn);
Emeric Brun644cde02012-12-14 11:21:13 +01003988 ERR_clear_error();
3989 }
Emeric Brun46591952012-05-18 15:47:34 +02003990
3991 /* force flag on ssl to keep session in cache regardless shutdown result */
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02003992 SSL_set_shutdown(conn->xprt_ctx, SSL_SENT_SHUTDOWN);
Emeric Brun46591952012-05-18 15:47:34 +02003993}
3994
Willy Tarreauffc3fcd2012-10-12 20:17:54 +02003995/* used for logging, may be changed for a sample fetch later */
3996const char *ssl_sock_get_cipher_name(struct connection *conn)
3997{
3998 if (!conn->xprt && !conn->xprt_ctx)
3999 return NULL;
4000 return SSL_get_cipher_name(conn->xprt_ctx);
4001}
4002
4003/* used for logging, may be changed for a sample fetch later */
4004const char *ssl_sock_get_proto_version(struct connection *conn)
4005{
4006 if (!conn->xprt && !conn->xprt_ctx)
4007 return NULL;
4008 return SSL_get_version(conn->xprt_ctx);
4009}
4010
Willy Tarreau8d598402012-10-22 17:58:39 +02004011/* Extract a serial from a cert, and copy it to a chunk.
4012 * Returns 1 if serial is found and copied, 0 if no serial found and
4013 * -1 if output is not large enough.
4014 */
4015static int
4016ssl_sock_get_serial(X509 *crt, struct chunk *out)
4017{
4018 ASN1_INTEGER *serial;
4019
4020 serial = X509_get_serialNumber(crt);
4021 if (!serial)
4022 return 0;
4023
4024 if (out->size < serial->length)
4025 return -1;
4026
4027 memcpy(out->str, serial->data, serial->length);
4028 out->len = serial->length;
4029 return 1;
4030}
4031
Emeric Brun43e79582014-10-29 19:03:26 +01004032/* Extract a cert to der, and copy it to a chunk.
4033 * Returns 1 if cert is found and copied, 0 on der convertion failure and
4034 * -1 if output is not large enough.
4035 */
4036static int
4037ssl_sock_crt2der(X509 *crt, struct chunk *out)
4038{
4039 int len;
4040 unsigned char *p = (unsigned char *)out->str;;
4041
4042 len =i2d_X509(crt, NULL);
4043 if (len <= 0)
4044 return 1;
4045
4046 if (out->size < len)
4047 return -1;
4048
4049 i2d_X509(crt,&p);
4050 out->len = len;
4051 return 1;
4052}
4053
Emeric Brunce5ad802012-10-22 14:11:22 +02004054
4055/* Copy Date in ASN1_UTCTIME format in struct chunk out.
4056 * Returns 1 if serial is found and copied, 0 if no valid time found
4057 * and -1 if output is not large enough.
4058 */
4059static int
4060ssl_sock_get_time(ASN1_TIME *tm, struct chunk *out)
4061{
4062 if (tm->type == V_ASN1_GENERALIZEDTIME) {
4063 ASN1_GENERALIZEDTIME *gentm = (ASN1_GENERALIZEDTIME *)tm;
4064
4065 if (gentm->length < 12)
4066 return 0;
4067 if (gentm->data[0] != 0x32 || gentm->data[1] != 0x30)
4068 return 0;
4069 if (out->size < gentm->length-2)
4070 return -1;
4071
4072 memcpy(out->str, gentm->data+2, gentm->length-2);
4073 out->len = gentm->length-2;
4074 return 1;
4075 }
4076 else if (tm->type == V_ASN1_UTCTIME) {
4077 ASN1_UTCTIME *utctm = (ASN1_UTCTIME *)tm;
4078
4079 if (utctm->length < 10)
4080 return 0;
4081 if (utctm->data[0] >= 0x35)
4082 return 0;
4083 if (out->size < utctm->length)
4084 return -1;
4085
4086 memcpy(out->str, utctm->data, utctm->length);
4087 out->len = utctm->length;
4088 return 1;
4089 }
4090
4091 return 0;
4092}
4093
Emeric Brun87855892012-10-17 17:39:35 +02004094/* Extract an entry from a X509_NAME and copy its value to an output chunk.
4095 * Returns 1 if entry found, 0 if entry not found, or -1 if output not large enough.
4096 */
4097static int
4098ssl_sock_get_dn_entry(X509_NAME *a, const struct chunk *entry, int pos, struct chunk *out)
4099{
4100 X509_NAME_ENTRY *ne;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004101 ASN1_OBJECT *obj;
4102 ASN1_STRING *data;
4103 const unsigned char *data_ptr;
4104 int data_len;
Emeric Brun87855892012-10-17 17:39:35 +02004105 int i, j, n;
4106 int cur = 0;
4107 const char *s;
4108 char tmp[128];
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004109 int name_count;
4110
4111 name_count = X509_NAME_entry_count(a);
Emeric Brun87855892012-10-17 17:39:35 +02004112
4113 out->len = 0;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004114 for (i = 0; i < name_count; i++) {
Emeric Brun87855892012-10-17 17:39:35 +02004115 if (pos < 0)
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004116 j = (name_count-1) - i;
Emeric Brun87855892012-10-17 17:39:35 +02004117 else
4118 j = i;
4119
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004120 ne = X509_NAME_get_entry(a, j);
4121 obj = X509_NAME_ENTRY_get_object(ne);
4122 data = X509_NAME_ENTRY_get_data(ne);
4123 data_ptr = ASN1_STRING_get0_data(data);
4124 data_len = ASN1_STRING_length(data);
4125 n = OBJ_obj2nid(obj);
Emeric Brun87855892012-10-17 17:39:35 +02004126 if ((n == NID_undef) || ((s = OBJ_nid2sn(n)) == NULL)) {
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004127 i2t_ASN1_OBJECT(tmp, sizeof(tmp), obj);
Emeric Brun87855892012-10-17 17:39:35 +02004128 s = tmp;
4129 }
4130
4131 if (chunk_strcasecmp(entry, s) != 0)
4132 continue;
4133
4134 if (pos < 0)
4135 cur--;
4136 else
4137 cur++;
4138
4139 if (cur != pos)
4140 continue;
4141
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004142 if (data_len > out->size)
Emeric Brun87855892012-10-17 17:39:35 +02004143 return -1;
4144
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004145 memcpy(out->str, data_ptr, data_len);
4146 out->len = data_len;
Emeric Brun87855892012-10-17 17:39:35 +02004147 return 1;
4148 }
4149
4150 return 0;
4151
4152}
4153
4154/* Extract and format full DN from a X509_NAME and copy result into a chunk
4155 * Returns 1 if dn entries exits, 0 if no dn entry found or -1 if output is not large enough.
4156 */
4157static int
4158ssl_sock_get_dn_oneline(X509_NAME *a, struct chunk *out)
4159{
4160 X509_NAME_ENTRY *ne;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004161 ASN1_OBJECT *obj;
4162 ASN1_STRING *data;
4163 const unsigned char *data_ptr;
4164 int data_len;
Emeric Brun87855892012-10-17 17:39:35 +02004165 int i, n, ln;
4166 int l = 0;
4167 const char *s;
4168 char *p;
4169 char tmp[128];
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004170 int name_count;
4171
4172
4173 name_count = X509_NAME_entry_count(a);
Emeric Brun87855892012-10-17 17:39:35 +02004174
4175 out->len = 0;
4176 p = out->str;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004177 for (i = 0; i < name_count; i++) {
4178 ne = X509_NAME_get_entry(a, i);
4179 obj = X509_NAME_ENTRY_get_object(ne);
4180 data = X509_NAME_ENTRY_get_data(ne);
4181 data_ptr = ASN1_STRING_get0_data(data);
4182 data_len = ASN1_STRING_length(data);
4183 n = OBJ_obj2nid(obj);
Emeric Brun87855892012-10-17 17:39:35 +02004184 if ((n == NID_undef) || ((s = OBJ_nid2sn(n)) == NULL)) {
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004185 i2t_ASN1_OBJECT(tmp, sizeof(tmp), obj);
Emeric Brun87855892012-10-17 17:39:35 +02004186 s = tmp;
4187 }
4188 ln = strlen(s);
4189
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004190 l += 1 + ln + 1 + data_len;
Emeric Brun87855892012-10-17 17:39:35 +02004191 if (l > out->size)
4192 return -1;
4193 out->len = l;
4194
4195 *(p++)='/';
4196 memcpy(p, s, ln);
4197 p += ln;
4198 *(p++)='=';
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004199 memcpy(p, data_ptr, data_len);
4200 p += data_len;
Emeric Brun87855892012-10-17 17:39:35 +02004201 }
4202
4203 if (!out->len)
4204 return 0;
4205
4206 return 1;
4207}
4208
David Safb76832014-05-08 23:42:08 -04004209char *ssl_sock_get_version(struct connection *conn)
4210{
4211 if (!ssl_sock_is_ssl(conn))
4212 return NULL;
4213
4214 return (char *)SSL_get_version(conn->xprt_ctx);
4215}
4216
Willy Tarreau63076412015-07-10 11:33:32 +02004217void ssl_sock_set_servername(struct connection *conn, const char *hostname)
4218{
4219#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
4220 if (!ssl_sock_is_ssl(conn))
4221 return;
4222
4223 SSL_set_tlsext_host_name(conn->xprt_ctx, hostname);
4224#endif
4225}
4226
Emeric Brun0abf8362014-06-24 18:26:41 +02004227/* Extract peer certificate's common name into the chunk dest
4228 * Returns
4229 * the len of the extracted common name
4230 * or 0 if no CN found in DN
4231 * or -1 on error case (i.e. no peer certificate)
4232 */
4233int ssl_sock_get_remote_common_name(struct connection *conn, struct chunk *dest)
David Safb76832014-05-08 23:42:08 -04004234{
4235 X509 *crt = NULL;
4236 X509_NAME *name;
David Safb76832014-05-08 23:42:08 -04004237 const char find_cn[] = "CN";
4238 const struct chunk find_cn_chunk = {
4239 .str = (char *)&find_cn,
4240 .len = sizeof(find_cn)-1
4241 };
Emeric Brun0abf8362014-06-24 18:26:41 +02004242 int result = -1;
David Safb76832014-05-08 23:42:08 -04004243
4244 if (!ssl_sock_is_ssl(conn))
Emeric Brun0abf8362014-06-24 18:26:41 +02004245 goto out;
David Safb76832014-05-08 23:42:08 -04004246
4247 /* SSL_get_peer_certificate, it increase X509 * ref count */
4248 crt = SSL_get_peer_certificate(conn->xprt_ctx);
4249 if (!crt)
4250 goto out;
4251
4252 name = X509_get_subject_name(crt);
4253 if (!name)
4254 goto out;
David Safb76832014-05-08 23:42:08 -04004255
Emeric Brun0abf8362014-06-24 18:26:41 +02004256 result = ssl_sock_get_dn_entry(name, &find_cn_chunk, 1, dest);
4257out:
David Safb76832014-05-08 23:42:08 -04004258 if (crt)
4259 X509_free(crt);
4260
4261 return result;
4262}
4263
Dave McCowan328fb582014-07-30 10:39:13 -04004264/* returns 1 if client passed a certificate for this session, 0 if not */
4265int ssl_sock_get_cert_used_sess(struct connection *conn)
4266{
4267 X509 *crt = NULL;
4268
4269 if (!ssl_sock_is_ssl(conn))
4270 return 0;
4271
4272 /* SSL_get_peer_certificate, it increase X509 * ref count */
4273 crt = SSL_get_peer_certificate(conn->xprt_ctx);
4274 if (!crt)
4275 return 0;
4276
4277 X509_free(crt);
4278 return 1;
4279}
4280
4281/* returns 1 if client passed a certificate for this connection, 0 if not */
4282int ssl_sock_get_cert_used_conn(struct connection *conn)
David Safb76832014-05-08 23:42:08 -04004283{
4284 if (!ssl_sock_is_ssl(conn))
4285 return 0;
4286
4287 return SSL_SOCK_ST_FL_VERIFY_DONE & conn->xprt_st ? 1 : 0;
4288}
4289
4290/* returns result from SSL verify */
4291unsigned int ssl_sock_get_verify_result(struct connection *conn)
4292{
4293 if (!ssl_sock_is_ssl(conn))
4294 return (unsigned int)X509_V_ERR_APPLICATION_VERIFICATION;
4295
4296 return (unsigned int)SSL_get_verify_result(conn->xprt_ctx);
4297}
4298
Willy Tarreau7875d092012-09-10 08:20:03 +02004299/***** Below are some sample fetching functions for ACL/patterns *****/
4300
Emeric Brune64aef12012-09-21 13:15:06 +02004301/* boolean, returns true if client cert was present */
4302static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004303smp_fetch_ssl_fc_has_crt(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brune64aef12012-09-21 13:15:06 +02004304{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004305 struct connection *conn;
4306
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004307 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004308 if (!conn || conn->xprt != &ssl_sock)
Emeric Brune64aef12012-09-21 13:15:06 +02004309 return 0;
4310
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004311 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brune64aef12012-09-21 13:15:06 +02004312 smp->flags |= SMP_F_MAY_CHANGE;
4313 return 0;
4314 }
4315
4316 smp->flags = 0;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004317 smp->data.type = SMP_T_BOOL;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004318 smp->data.u.sint = SSL_SOCK_ST_FL_VERIFY_DONE & conn->xprt_st ? 1 : 0;
Emeric Brune64aef12012-09-21 13:15:06 +02004319
4320 return 1;
4321}
4322
Emeric Brun43e79582014-10-29 19:03:26 +01004323/* binary, returns a certificate in a binary chunk (der/raw).
4324 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
4325 * should be use.
4326 */
4327static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004328smp_fetch_ssl_x_der(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun43e79582014-10-29 19:03:26 +01004329{
4330 int cert_peer = (kw[4] == 'c') ? 1 : 0;
4331 X509 *crt = NULL;
4332 int ret = 0;
4333 struct chunk *smp_trash;
4334 struct connection *conn;
4335
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004336 conn = objt_conn(smp->sess->origin);
Emeric Brun43e79582014-10-29 19:03:26 +01004337 if (!conn || conn->xprt != &ssl_sock)
4338 return 0;
4339
4340 if (!(conn->flags & CO_FL_CONNECTED)) {
4341 smp->flags |= SMP_F_MAY_CHANGE;
4342 return 0;
4343 }
4344
4345 if (cert_peer)
4346 crt = SSL_get_peer_certificate(conn->xprt_ctx);
4347 else
4348 crt = SSL_get_certificate(conn->xprt_ctx);
4349
4350 if (!crt)
4351 goto out;
4352
4353 smp_trash = get_trash_chunk();
4354 if (ssl_sock_crt2der(crt, smp_trash) <= 0)
4355 goto out;
4356
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004357 smp->data.u.str = *smp_trash;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004358 smp->data.type = SMP_T_BIN;
Emeric Brun43e79582014-10-29 19:03:26 +01004359 ret = 1;
4360out:
4361 /* SSL_get_peer_certificate, it increase X509 * ref count */
4362 if (cert_peer && crt)
4363 X509_free(crt);
4364 return ret;
4365}
4366
Emeric Brunba841a12014-04-30 17:05:08 +02004367/* binary, returns serial of certificate in a binary chunk.
4368 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
4369 * should be use.
4370 */
Willy Tarreau8d598402012-10-22 17:58:39 +02004371static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004372smp_fetch_ssl_x_serial(const struct arg *args, struct sample *smp, const char *kw, void *private)
Willy Tarreau8d598402012-10-22 17:58:39 +02004373{
Emeric Brunba841a12014-04-30 17:05:08 +02004374 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Willy Tarreau8d598402012-10-22 17:58:39 +02004375 X509 *crt = NULL;
4376 int ret = 0;
4377 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004378 struct connection *conn;
4379
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004380 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004381 if (!conn || conn->xprt != &ssl_sock)
Willy Tarreau8d598402012-10-22 17:58:39 +02004382 return 0;
4383
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004384 if (!(conn->flags & CO_FL_CONNECTED)) {
Willy Tarreau8d598402012-10-22 17:58:39 +02004385 smp->flags |= SMP_F_MAY_CHANGE;
4386 return 0;
4387 }
4388
Emeric Brunba841a12014-04-30 17:05:08 +02004389 if (cert_peer)
4390 crt = SSL_get_peer_certificate(conn->xprt_ctx);
4391 else
4392 crt = SSL_get_certificate(conn->xprt_ctx);
4393
Willy Tarreau8d598402012-10-22 17:58:39 +02004394 if (!crt)
4395 goto out;
4396
Willy Tarreau47ca5452012-12-23 20:22:19 +01004397 smp_trash = get_trash_chunk();
Willy Tarreau8d598402012-10-22 17:58:39 +02004398 if (ssl_sock_get_serial(crt, smp_trash) <= 0)
4399 goto out;
4400
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004401 smp->data.u.str = *smp_trash;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004402 smp->data.type = SMP_T_BIN;
Willy Tarreau8d598402012-10-22 17:58:39 +02004403 ret = 1;
4404out:
Emeric Brunba841a12014-04-30 17:05:08 +02004405 /* SSL_get_peer_certificate, it increase X509 * ref count */
4406 if (cert_peer && crt)
Willy Tarreau8d598402012-10-22 17:58:39 +02004407 X509_free(crt);
4408 return ret;
4409}
Emeric Brune64aef12012-09-21 13:15:06 +02004410
Emeric Brunba841a12014-04-30 17:05:08 +02004411/* binary, returns the client certificate's SHA-1 fingerprint (SHA-1 hash of DER-encoded certificate) in a binary chunk.
4412 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
4413 * should be use.
4414 */
James Votha051b4a2013-05-14 20:37:59 +02004415static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004416smp_fetch_ssl_x_sha1(const struct arg *args, struct sample *smp, const char *kw, void *private)
James Votha051b4a2013-05-14 20:37:59 +02004417{
Emeric Brunba841a12014-04-30 17:05:08 +02004418 int cert_peer = (kw[4] == 'c') ? 1 : 0;
James Votha051b4a2013-05-14 20:37:59 +02004419 X509 *crt = NULL;
4420 const EVP_MD *digest;
4421 int ret = 0;
4422 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004423 struct connection *conn;
James Votha051b4a2013-05-14 20:37:59 +02004424
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004425 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004426 if (!conn || conn->xprt != &ssl_sock)
4427 return 0;
4428
4429 if (!(conn->flags & CO_FL_CONNECTED)) {
James Votha051b4a2013-05-14 20:37:59 +02004430 smp->flags |= SMP_F_MAY_CHANGE;
4431 return 0;
4432 }
4433
Emeric Brunba841a12014-04-30 17:05:08 +02004434 if (cert_peer)
4435 crt = SSL_get_peer_certificate(conn->xprt_ctx);
4436 else
4437 crt = SSL_get_certificate(conn->xprt_ctx);
James Votha051b4a2013-05-14 20:37:59 +02004438 if (!crt)
4439 goto out;
4440
4441 smp_trash = get_trash_chunk();
4442 digest = EVP_sha1();
4443 X509_digest(crt, digest, (unsigned char *)smp_trash->str, (unsigned int *)&smp_trash->len);
4444
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004445 smp->data.u.str = *smp_trash;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004446 smp->data.type = SMP_T_BIN;
James Votha051b4a2013-05-14 20:37:59 +02004447 ret = 1;
4448out:
Emeric Brunba841a12014-04-30 17:05:08 +02004449 /* SSL_get_peer_certificate, it increase X509 * ref count */
4450 if (cert_peer && crt)
James Votha051b4a2013-05-14 20:37:59 +02004451 X509_free(crt);
4452 return ret;
4453}
4454
Emeric Brunba841a12014-04-30 17:05:08 +02004455/* string, returns certificate's notafter date in ASN1_UTCTIME format.
4456 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
4457 * should be use.
4458 */
Emeric Brunce5ad802012-10-22 14:11:22 +02004459static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004460smp_fetch_ssl_x_notafter(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brunce5ad802012-10-22 14:11:22 +02004461{
Emeric Brunba841a12014-04-30 17:05:08 +02004462 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brunce5ad802012-10-22 14:11:22 +02004463 X509 *crt = NULL;
4464 int ret = 0;
4465 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004466 struct connection *conn;
Emeric Brunce5ad802012-10-22 14:11:22 +02004467
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004468 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004469 if (!conn || conn->xprt != &ssl_sock)
4470 return 0;
4471
4472 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunce5ad802012-10-22 14:11:22 +02004473 smp->flags |= SMP_F_MAY_CHANGE;
4474 return 0;
4475 }
4476
Emeric Brunba841a12014-04-30 17:05:08 +02004477 if (cert_peer)
4478 crt = SSL_get_peer_certificate(conn->xprt_ctx);
4479 else
4480 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brunce5ad802012-10-22 14:11:22 +02004481 if (!crt)
4482 goto out;
4483
Willy Tarreau47ca5452012-12-23 20:22:19 +01004484 smp_trash = get_trash_chunk();
Emeric Brunce5ad802012-10-22 14:11:22 +02004485 if (ssl_sock_get_time(X509_get_notAfter(crt), smp_trash) <= 0)
4486 goto out;
4487
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004488 smp->data.u.str = *smp_trash;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004489 smp->data.type = SMP_T_STR;
Emeric Brunce5ad802012-10-22 14:11:22 +02004490 ret = 1;
4491out:
Emeric Brunba841a12014-04-30 17:05:08 +02004492 /* SSL_get_peer_certificate, it increase X509 * ref count */
4493 if (cert_peer && crt)
Emeric Brunce5ad802012-10-22 14:11:22 +02004494 X509_free(crt);
4495 return ret;
4496}
4497
Emeric Brunba841a12014-04-30 17:05:08 +02004498/* string, returns a string of a formatted full dn \C=..\O=..\OU=.. \CN=.. of certificate's issuer
4499 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
4500 * should be use.
4501 */
Emeric Brun87855892012-10-17 17:39:35 +02004502static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004503smp_fetch_ssl_x_i_dn(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun87855892012-10-17 17:39:35 +02004504{
Emeric Brunba841a12014-04-30 17:05:08 +02004505 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brun87855892012-10-17 17:39:35 +02004506 X509 *crt = NULL;
4507 X509_NAME *name;
4508 int ret = 0;
4509 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004510 struct connection *conn;
Emeric Brun87855892012-10-17 17:39:35 +02004511
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004512 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004513 if (!conn || conn->xprt != &ssl_sock)
4514 return 0;
4515
4516 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun87855892012-10-17 17:39:35 +02004517 smp->flags |= SMP_F_MAY_CHANGE;
4518 return 0;
4519 }
4520
Emeric Brunba841a12014-04-30 17:05:08 +02004521 if (cert_peer)
4522 crt = SSL_get_peer_certificate(conn->xprt_ctx);
4523 else
4524 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brun87855892012-10-17 17:39:35 +02004525 if (!crt)
4526 goto out;
4527
4528 name = X509_get_issuer_name(crt);
4529 if (!name)
4530 goto out;
4531
Willy Tarreau47ca5452012-12-23 20:22:19 +01004532 smp_trash = get_trash_chunk();
Emeric Brun87855892012-10-17 17:39:35 +02004533 if (args && args[0].type == ARGT_STR) {
4534 int pos = 1;
4535
4536 if (args[1].type == ARGT_SINT)
4537 pos = args[1].data.sint;
Emeric Brun87855892012-10-17 17:39:35 +02004538
4539 if (ssl_sock_get_dn_entry(name, &args[0].data.str, pos, smp_trash) <= 0)
4540 goto out;
4541 }
4542 else if (ssl_sock_get_dn_oneline(name, smp_trash) <= 0)
4543 goto out;
4544
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004545 smp->data.type = SMP_T_STR;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004546 smp->data.u.str = *smp_trash;
Emeric Brun87855892012-10-17 17:39:35 +02004547 ret = 1;
4548out:
Emeric Brunba841a12014-04-30 17:05:08 +02004549 /* SSL_get_peer_certificate, it increase X509 * ref count */
4550 if (cert_peer && crt)
Emeric Brun87855892012-10-17 17:39:35 +02004551 X509_free(crt);
4552 return ret;
4553}
4554
Emeric Brunba841a12014-04-30 17:05:08 +02004555/* string, returns notbefore date in ASN1_UTCTIME format.
4556 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
4557 * should be use.
4558 */
Emeric Brunce5ad802012-10-22 14:11:22 +02004559static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004560smp_fetch_ssl_x_notbefore(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brunce5ad802012-10-22 14:11:22 +02004561{
Emeric Brunba841a12014-04-30 17:05:08 +02004562 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brunce5ad802012-10-22 14:11:22 +02004563 X509 *crt = NULL;
4564 int ret = 0;
4565 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004566 struct connection *conn;
4567
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004568 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004569 if (!conn || conn->xprt != &ssl_sock)
Emeric Brunce5ad802012-10-22 14:11:22 +02004570 return 0;
4571
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004572 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunce5ad802012-10-22 14:11:22 +02004573 smp->flags |= SMP_F_MAY_CHANGE;
4574 return 0;
4575 }
4576
Emeric Brunba841a12014-04-30 17:05:08 +02004577 if (cert_peer)
4578 crt = SSL_get_peer_certificate(conn->xprt_ctx);
4579 else
4580 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brunce5ad802012-10-22 14:11:22 +02004581 if (!crt)
4582 goto out;
4583
Willy Tarreau47ca5452012-12-23 20:22:19 +01004584 smp_trash = get_trash_chunk();
Emeric Brunce5ad802012-10-22 14:11:22 +02004585 if (ssl_sock_get_time(X509_get_notBefore(crt), smp_trash) <= 0)
4586 goto out;
4587
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004588 smp->data.u.str = *smp_trash;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004589 smp->data.type = SMP_T_STR;
Emeric Brunce5ad802012-10-22 14:11:22 +02004590 ret = 1;
4591out:
Emeric Brunba841a12014-04-30 17:05:08 +02004592 /* SSL_get_peer_certificate, it increase X509 * ref count */
4593 if (cert_peer && crt)
Emeric Brunce5ad802012-10-22 14:11:22 +02004594 X509_free(crt);
4595 return ret;
4596}
4597
Emeric Brunba841a12014-04-30 17:05:08 +02004598/* string, returns a string of a formatted full dn \C=..\O=..\OU=.. \CN=.. of certificate's subject
4599 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
4600 * should be use.
4601 */
Emeric Brun87855892012-10-17 17:39:35 +02004602static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004603smp_fetch_ssl_x_s_dn(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun87855892012-10-17 17:39:35 +02004604{
Emeric Brunba841a12014-04-30 17:05:08 +02004605 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brun87855892012-10-17 17:39:35 +02004606 X509 *crt = NULL;
4607 X509_NAME *name;
4608 int ret = 0;
4609 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004610 struct connection *conn;
Emeric Brun87855892012-10-17 17:39:35 +02004611
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004612 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004613 if (!conn || conn->xprt != &ssl_sock)
4614 return 0;
4615
4616 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun87855892012-10-17 17:39:35 +02004617 smp->flags |= SMP_F_MAY_CHANGE;
4618 return 0;
4619 }
4620
Emeric Brunba841a12014-04-30 17:05:08 +02004621 if (cert_peer)
4622 crt = SSL_get_peer_certificate(conn->xprt_ctx);
4623 else
4624 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brun87855892012-10-17 17:39:35 +02004625 if (!crt)
4626 goto out;
4627
4628 name = X509_get_subject_name(crt);
4629 if (!name)
4630 goto out;
4631
Willy Tarreau47ca5452012-12-23 20:22:19 +01004632 smp_trash = get_trash_chunk();
Emeric Brun87855892012-10-17 17:39:35 +02004633 if (args && args[0].type == ARGT_STR) {
4634 int pos = 1;
4635
4636 if (args[1].type == ARGT_SINT)
4637 pos = args[1].data.sint;
Emeric Brun87855892012-10-17 17:39:35 +02004638
4639 if (ssl_sock_get_dn_entry(name, &args[0].data.str, pos, smp_trash) <= 0)
4640 goto out;
4641 }
4642 else if (ssl_sock_get_dn_oneline(name, smp_trash) <= 0)
4643 goto out;
4644
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004645 smp->data.type = SMP_T_STR;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004646 smp->data.u.str = *smp_trash;
Emeric Brun87855892012-10-17 17:39:35 +02004647 ret = 1;
4648out:
Emeric Brunba841a12014-04-30 17:05:08 +02004649 /* SSL_get_peer_certificate, it increase X509 * ref count */
4650 if (cert_peer && crt)
Emeric Brun87855892012-10-17 17:39:35 +02004651 X509_free(crt);
4652 return ret;
4653}
Emeric Brun9143d372012-12-20 15:44:16 +01004654
4655/* integer, returns true if current session use a client certificate */
4656static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004657smp_fetch_ssl_c_used(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun9143d372012-12-20 15:44:16 +01004658{
4659 X509 *crt;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004660 struct connection *conn;
Emeric Brun9143d372012-12-20 15:44:16 +01004661
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004662 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004663 if (!conn || conn->xprt != &ssl_sock)
4664 return 0;
4665
4666 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun9143d372012-12-20 15:44:16 +01004667 smp->flags |= SMP_F_MAY_CHANGE;
4668 return 0;
4669 }
4670
4671 /* SSL_get_peer_certificate returns a ptr on allocated X509 struct */
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004672 crt = SSL_get_peer_certificate(conn->xprt_ctx);
Emeric Brun9143d372012-12-20 15:44:16 +01004673 if (crt) {
4674 X509_free(crt);
4675 }
4676
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004677 smp->data.type = SMP_T_BOOL;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004678 smp->data.u.sint = (crt != NULL);
Emeric Brun9143d372012-12-20 15:44:16 +01004679 return 1;
4680}
4681
Emeric Brunba841a12014-04-30 17:05:08 +02004682/* integer, returns the certificate version
4683 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
4684 * should be use.
4685 */
Emeric Bruna7359fd2012-10-17 15:03:11 +02004686static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004687smp_fetch_ssl_x_version(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Bruna7359fd2012-10-17 15:03:11 +02004688{
Emeric Brunba841a12014-04-30 17:05:08 +02004689 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Bruna7359fd2012-10-17 15:03:11 +02004690 X509 *crt;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004691 struct connection *conn;
4692
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004693 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004694 if (!conn || conn->xprt != &ssl_sock)
Emeric Bruna7359fd2012-10-17 15:03:11 +02004695 return 0;
4696
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004697 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Bruna7359fd2012-10-17 15:03:11 +02004698 smp->flags |= SMP_F_MAY_CHANGE;
4699 return 0;
4700 }
4701
Emeric Brunba841a12014-04-30 17:05:08 +02004702 if (cert_peer)
4703 crt = SSL_get_peer_certificate(conn->xprt_ctx);
4704 else
4705 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Bruna7359fd2012-10-17 15:03:11 +02004706 if (!crt)
4707 return 0;
4708
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004709 smp->data.u.sint = (unsigned int)(1 + X509_get_version(crt));
Emeric Brunba841a12014-04-30 17:05:08 +02004710 /* SSL_get_peer_certificate increase X509 * ref count */
4711 if (cert_peer)
4712 X509_free(crt);
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004713 smp->data.type = SMP_T_SINT;
Emeric Bruna7359fd2012-10-17 15:03:11 +02004714
4715 return 1;
4716}
4717
Emeric Brunba841a12014-04-30 17:05:08 +02004718/* string, returns the certificate's signature algorithm.
4719 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
4720 * should be use.
4721 */
Emeric Brun7f56e742012-10-19 18:15:40 +02004722static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004723smp_fetch_ssl_x_sig_alg(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun7f56e742012-10-19 18:15:40 +02004724{
Emeric Brunba841a12014-04-30 17:05:08 +02004725 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brun7f56e742012-10-19 18:15:40 +02004726 X509 *crt;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004727 __OPENSSL_110_CONST__ ASN1_OBJECT *algorithm;
Emeric Brun7f56e742012-10-19 18:15:40 +02004728 int nid;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004729 struct connection *conn;
Emeric Brun7f56e742012-10-19 18:15:40 +02004730
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004731 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004732 if (!conn || conn->xprt != &ssl_sock)
4733 return 0;
4734
4735 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun7f56e742012-10-19 18:15:40 +02004736 smp->flags |= SMP_F_MAY_CHANGE;
4737 return 0;
4738 }
4739
Emeric Brunba841a12014-04-30 17:05:08 +02004740 if (cert_peer)
4741 crt = SSL_get_peer_certificate(conn->xprt_ctx);
4742 else
4743 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brun7f56e742012-10-19 18:15:40 +02004744 if (!crt)
4745 return 0;
4746
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004747 X509_ALGOR_get0(&algorithm, NULL, NULL, X509_get0_tbs_sigalg(crt));
4748 nid = OBJ_obj2nid(algorithm);
Emeric Brun7f56e742012-10-19 18:15:40 +02004749
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004750 smp->data.u.str.str = (char *)OBJ_nid2sn(nid);
4751 if (!smp->data.u.str.str) {
Emeric Brunba841a12014-04-30 17:05:08 +02004752 /* SSL_get_peer_certificate increase X509 * ref count */
4753 if (cert_peer)
4754 X509_free(crt);
Emeric Brun7f56e742012-10-19 18:15:40 +02004755 return 0;
Emeric Brun9bf3ba22013-10-07 14:31:44 +02004756 }
Emeric Brun7f56e742012-10-19 18:15:40 +02004757
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004758 smp->data.type = SMP_T_STR;
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01004759 smp->flags |= SMP_F_CONST;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004760 smp->data.u.str.len = strlen(smp->data.u.str.str);
Emeric Brunba841a12014-04-30 17:05:08 +02004761 /* SSL_get_peer_certificate increase X509 * ref count */
4762 if (cert_peer)
4763 X509_free(crt);
Emeric Brun7f56e742012-10-19 18:15:40 +02004764
4765 return 1;
4766}
4767
Emeric Brunba841a12014-04-30 17:05:08 +02004768/* string, returns the certificate's key algorithm.
4769 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
4770 * should be use.
4771 */
Emeric Brun521a0112012-10-22 12:22:55 +02004772static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004773smp_fetch_ssl_x_key_alg(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun521a0112012-10-22 12:22:55 +02004774{
Emeric Brunba841a12014-04-30 17:05:08 +02004775 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brun521a0112012-10-22 12:22:55 +02004776 X509 *crt;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004777 ASN1_OBJECT *algorithm;
Emeric Brun521a0112012-10-22 12:22:55 +02004778 int nid;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004779 struct connection *conn;
Emeric Brun521a0112012-10-22 12:22:55 +02004780
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004781 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004782 if (!conn || conn->xprt != &ssl_sock)
4783 return 0;
4784
4785 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun521a0112012-10-22 12:22:55 +02004786 smp->flags |= SMP_F_MAY_CHANGE;
4787 return 0;
4788 }
4789
Emeric Brunba841a12014-04-30 17:05:08 +02004790 if (cert_peer)
4791 crt = SSL_get_peer_certificate(conn->xprt_ctx);
4792 else
4793 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brun521a0112012-10-22 12:22:55 +02004794 if (!crt)
4795 return 0;
4796
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004797 X509_PUBKEY_get0_param(&algorithm, NULL, NULL, NULL, X509_get_X509_PUBKEY(crt));
4798 nid = OBJ_obj2nid(algorithm);
Emeric Brun521a0112012-10-22 12:22:55 +02004799
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004800 smp->data.u.str.str = (char *)OBJ_nid2sn(nid);
4801 if (!smp->data.u.str.str) {
Emeric Brunba841a12014-04-30 17:05:08 +02004802 /* SSL_get_peer_certificate increase X509 * ref count */
4803 if (cert_peer)
4804 X509_free(crt);
Emeric Brun521a0112012-10-22 12:22:55 +02004805 return 0;
Emeric Brun9bf3ba22013-10-07 14:31:44 +02004806 }
Emeric Brun521a0112012-10-22 12:22:55 +02004807
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004808 smp->data.type = SMP_T_STR;
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01004809 smp->flags |= SMP_F_CONST;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004810 smp->data.u.str.len = strlen(smp->data.u.str.str);
Emeric Brunba841a12014-04-30 17:05:08 +02004811 if (cert_peer)
4812 X509_free(crt);
Emeric Brun521a0112012-10-22 12:22:55 +02004813
4814 return 1;
4815}
4816
Emeric Brun645ae792014-04-30 14:21:06 +02004817/* boolean, returns true if front conn. transport layer is SSL.
4818 * This function is also usable on backend conn if the fetch keyword 5th
4819 * char is 'b'.
4820 */
Willy Tarreau7875d092012-09-10 08:20:03 +02004821static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004822smp_fetch_ssl_fc(const struct arg *args, struct sample *smp, const char *kw, void *private)
Willy Tarreau7875d092012-09-10 08:20:03 +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
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004827 smp->data.type = SMP_T_BOOL;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004828 smp->data.u.sint = (conn && conn->xprt == &ssl_sock);
Willy Tarreau7875d092012-09-10 08:20:03 +02004829 return 1;
4830}
4831
Emeric Brun2525b6b2012-10-18 15:59:43 +02004832/* boolean, returns true if client present a SNI */
Willy Tarreau7875d092012-09-10 08:20:03 +02004833static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004834smp_fetch_ssl_fc_has_sni(const struct arg *args, struct sample *smp, const char *kw, void *private)
Willy Tarreau7875d092012-09-10 08:20:03 +02004835{
4836#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004837 struct connection *conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004838
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004839 smp->data.type = SMP_T_BOOL;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004840 smp->data.u.sint = (conn && conn->xprt == &ssl_sock) &&
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004841 conn->xprt_ctx &&
4842 SSL_get_servername(conn->xprt_ctx, TLSEXT_NAMETYPE_host_name) != NULL;
Willy Tarreau7875d092012-09-10 08:20:03 +02004843 return 1;
4844#else
4845 return 0;
4846#endif
4847}
4848
Nenad Merdanovic26ea8222015-05-18 02:28:57 +02004849/* boolean, returns true if client session has been resumed */
4850static int
4851smp_fetch_ssl_fc_is_resumed(const struct arg *args, struct sample *smp, const char *kw, void *private)
4852{
4853 struct connection *conn = objt_conn(smp->sess->origin);
4854
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004855 smp->data.type = SMP_T_BOOL;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004856 smp->data.u.sint = (conn && conn->xprt == &ssl_sock) &&
Nenad Merdanovic26ea8222015-05-18 02:28:57 +02004857 conn->xprt_ctx &&
4858 SSL_session_reused(conn->xprt_ctx);
4859 return 1;
4860}
4861
Emeric Brun645ae792014-04-30 14:21:06 +02004862/* string, returns the used cipher if front conn. transport layer is SSL.
4863 * This function is also usable on backend conn if the fetch keyword 5th
4864 * char is 'b'.
4865 */
Emeric Brun589fcad2012-10-16 14:13:26 +02004866static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004867smp_fetch_ssl_fc_cipher(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun589fcad2012-10-16 14:13:26 +02004868{
Willy Tarreaue237fe12016-03-10 17:05:28 +01004869 struct connection *conn = objt_conn((kw[4] != 'b') ? smp->sess->origin :
4870 smp->strm ? smp->strm->si[1].end : NULL);
Emeric Brun589fcad2012-10-16 14:13:26 +02004871
Willy Tarreaube508f12016-03-10 11:47:01 +01004872 smp->flags = 0;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004873 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
Emeric Brun589fcad2012-10-16 14:13:26 +02004874 return 0;
4875
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004876 smp->data.u.str.str = (char *)SSL_get_cipher_name(conn->xprt_ctx);
4877 if (!smp->data.u.str.str)
Emeric Brun589fcad2012-10-16 14:13:26 +02004878 return 0;
4879
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004880 smp->data.type = SMP_T_STR;
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01004881 smp->flags |= SMP_F_CONST;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004882 smp->data.u.str.len = strlen(smp->data.u.str.str);
Emeric Brun589fcad2012-10-16 14:13:26 +02004883
4884 return 1;
4885}
4886
Emeric Brun645ae792014-04-30 14:21:06 +02004887/* integer, returns the algoritm's keysize if front conn. transport layer
4888 * is SSL.
4889 * This function is also usable on backend conn if the fetch keyword 5th
4890 * char is 'b'.
4891 */
Emeric Brun589fcad2012-10-16 14:13:26 +02004892static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004893smp_fetch_ssl_fc_alg_keysize(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun589fcad2012-10-16 14:13:26 +02004894{
Willy Tarreaue237fe12016-03-10 17:05:28 +01004895 struct connection *conn = objt_conn((kw[4] != 'b') ? smp->sess->origin :
4896 smp->strm ? smp->strm->si[1].end : NULL);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004897
Willy Tarreaue237fe12016-03-10 17:05:28 +01004898 int sint;
Willy Tarreaube508f12016-03-10 11:47:01 +01004899
Emeric Brun589fcad2012-10-16 14:13:26 +02004900 smp->flags = 0;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004901 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
Emeric Brun589fcad2012-10-16 14:13:26 +02004902 return 0;
4903
Thierry FOURNIER07ee64e2015-07-06 23:43:03 +02004904 if (!SSL_get_cipher_bits(conn->xprt_ctx, &sint))
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004905 return 0;
4906
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004907 smp->data.u.sint = sint;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004908 smp->data.type = SMP_T_SINT;
Emeric Brun589fcad2012-10-16 14:13:26 +02004909
4910 return 1;
4911}
4912
Emeric Brun645ae792014-04-30 14:21:06 +02004913/* integer, returns the used keysize 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 */
Emeric Brun589fcad2012-10-16 14:13:26 +02004917static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004918smp_fetch_ssl_fc_use_keysize(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.sint = (unsigned int)SSL_get_cipher_bits(conn->xprt_ctx, NULL);
4928 if (!smp->data.u.sint)
Emeric Brun589fcad2012-10-16 14:13:26 +02004929 return 0;
4930
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004931 smp->data.type = SMP_T_SINT;
Emeric Brun589fcad2012-10-16 14:13:26 +02004932
4933 return 1;
4934}
4935
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02004936#ifdef OPENSSL_NPN_NEGOTIATED
Willy Tarreau7875d092012-09-10 08:20:03 +02004937static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004938smp_fetch_ssl_fc_npn(const struct arg *args, struct sample *smp, const char *kw, void *private)
Willy Tarreaua33c6542012-10-15 13:19:06 +02004939{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004940 struct connection *conn;
4941
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01004942 smp->flags = SMP_F_CONST;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004943 smp->data.type = SMP_T_STR;
Willy Tarreaua33c6542012-10-15 13:19:06 +02004944
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004945 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004946 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
4947 return 0;
4948
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004949 smp->data.u.str.str = NULL;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004950 SSL_get0_next_proto_negotiated(conn->xprt_ctx,
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004951 (const unsigned char **)&smp->data.u.str.str, (unsigned *)&smp->data.u.str.len);
Willy Tarreaua33c6542012-10-15 13:19:06 +02004952
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004953 if (!smp->data.u.str.str)
Willy Tarreaua33c6542012-10-15 13:19:06 +02004954 return 0;
4955
4956 return 1;
Willy Tarreaua33c6542012-10-15 13:19:06 +02004957}
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02004958#endif
Willy Tarreaua33c6542012-10-15 13:19:06 +02004959
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01004960#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Willy Tarreauab861d32013-04-02 02:30:41 +02004961static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004962smp_fetch_ssl_fc_alpn(const struct arg *args, struct sample *smp, const char *kw, void *private)
Willy Tarreauab861d32013-04-02 02:30:41 +02004963{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004964 struct connection *conn;
4965
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01004966 smp->flags = SMP_F_CONST;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004967 smp->data.type = SMP_T_STR;
Willy Tarreauab861d32013-04-02 02:30:41 +02004968
Willy Tarreaue26bf052015-05-12 10:30:12 +02004969 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004970 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
Willy Tarreauab861d32013-04-02 02:30:41 +02004971 return 0;
4972
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004973 smp->data.u.str.str = NULL;
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01004974 SSL_get0_alpn_selected(conn->xprt_ctx,
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004975 (const unsigned char **)&smp->data.u.str.str, (unsigned *)&smp->data.u.str.len);
Willy Tarreauab861d32013-04-02 02:30:41 +02004976
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004977 if (!smp->data.u.str.str)
Willy Tarreauab861d32013-04-02 02:30:41 +02004978 return 0;
4979
4980 return 1;
4981}
4982#endif
4983
Emeric Brun645ae792014-04-30 14:21:06 +02004984/* string, returns the used protocol if front conn. transport layer is SSL.
4985 * This function is also usable on backend conn if the fetch keyword 5th
4986 * char is 'b'.
4987 */
Willy Tarreaua33c6542012-10-15 13:19:06 +02004988static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004989smp_fetch_ssl_fc_protocol(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun589fcad2012-10-16 14:13:26 +02004990{
Willy Tarreaue237fe12016-03-10 17:05:28 +01004991 struct connection *conn = objt_conn((kw[4] != 'b') ? smp->sess->origin :
4992 smp->strm ? smp->strm->si[1].end : NULL);
Willy Tarreaube508f12016-03-10 11:47:01 +01004993
Emeric Brun589fcad2012-10-16 14:13:26 +02004994 smp->flags = 0;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004995 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
4996 return 0;
4997
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004998 smp->data.u.str.str = (char *)SSL_get_version(conn->xprt_ctx);
4999 if (!smp->data.u.str.str)
Emeric Brun589fcad2012-10-16 14:13:26 +02005000 return 0;
5001
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005002 smp->data.type = SMP_T_STR;
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01005003 smp->flags = SMP_F_CONST;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005004 smp->data.u.str.len = strlen(smp->data.u.str.str);
Emeric Brun589fcad2012-10-16 14:13:26 +02005005
5006 return 1;
5007}
5008
Willy Tarreau87b09662015-04-03 00:22:06 +02005009/* binary, returns the SSL stream id if front conn. transport layer is SSL.
Emeric Brun645ae792014-04-30 14:21:06 +02005010 * This function is also usable on backend conn if the fetch keyword 5th
5011 * char is 'b'.
5012 */
Emeric Brun589fcad2012-10-16 14:13:26 +02005013static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005014smp_fetch_ssl_fc_session_id(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brunfe68f682012-10-16 14:59:28 +02005015{
5016#if OPENSSL_VERSION_NUMBER > 0x0090800fL
Willy Tarreaue237fe12016-03-10 17:05:28 +01005017 struct connection *conn = objt_conn((kw[4] != 'b') ? smp->sess->origin :
5018 smp->strm ? smp->strm->si[1].end : NULL);
Emeric Brunfe68f682012-10-16 14:59:28 +02005019
Willy Tarreaue237fe12016-03-10 17:05:28 +01005020 SSL_SESSION *ssl_sess;
Willy Tarreaube508f12016-03-10 11:47:01 +01005021
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01005022 smp->flags = SMP_F_CONST;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005023 smp->data.type = SMP_T_BIN;
Emeric Brunfe68f682012-10-16 14:59:28 +02005024
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005025 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
5026 return 0;
5027
Willy Tarreau192252e2015-04-04 01:47:55 +02005028 ssl_sess = SSL_get_session(conn->xprt_ctx);
5029 if (!ssl_sess)
Emeric Brunfe68f682012-10-16 14:59:28 +02005030 return 0;
5031
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005032 smp->data.u.str.str = (char *)SSL_SESSION_get_id(ssl_sess, (unsigned int *)&smp->data.u.str.len);
5033 if (!smp->data.u.str.str || !smp->data.u.str.len)
Emeric Brunfe68f682012-10-16 14:59:28 +02005034 return 0;
5035
5036 return 1;
5037#else
5038 return 0;
5039#endif
5040}
5041
5042static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005043smp_fetch_ssl_fc_sni(const struct arg *args, struct sample *smp, const char *kw, void *private)
Willy Tarreau7875d092012-09-10 08:20:03 +02005044{
5045#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005046 struct connection *conn;
5047
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01005048 smp->flags = SMP_F_CONST;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005049 smp->data.type = SMP_T_STR;
Willy Tarreau7875d092012-09-10 08:20:03 +02005050
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02005051 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005052 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
5053 return 0;
5054
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005055 smp->data.u.str.str = (char *)SSL_get_servername(conn->xprt_ctx, TLSEXT_NAMETYPE_host_name);
5056 if (!smp->data.u.str.str)
Willy Tarreau3e394c92012-09-14 23:56:58 +02005057 return 0;
5058
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005059 smp->data.u.str.len = strlen(smp->data.u.str.str);
Willy Tarreau7875d092012-09-10 08:20:03 +02005060 return 1;
5061#else
5062 return 0;
5063#endif
5064}
5065
David Sc1ad52e2014-04-08 18:48:47 -04005066static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005067smp_fetch_ssl_fc_unique_id(const struct arg *args, struct sample *smp, const char *kw, void *private)
David Sc1ad52e2014-04-08 18:48:47 -04005068{
5069#if OPENSSL_VERSION_NUMBER > 0x0090800fL
Willy Tarreaue237fe12016-03-10 17:05:28 +01005070 struct connection *conn = objt_conn((kw[4] != 'b') ? smp->sess->origin :
5071 smp->strm ? smp->strm->si[1].end : NULL);
5072
David Sc1ad52e2014-04-08 18:48:47 -04005073 int finished_len;
David Sc1ad52e2014-04-08 18:48:47 -04005074 struct chunk *finished_trash;
David Sc1ad52e2014-04-08 18:48:47 -04005075
5076 smp->flags = 0;
David Sc1ad52e2014-04-08 18:48:47 -04005077 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
5078 return 0;
5079
5080 if (!(conn->flags & CO_FL_CONNECTED)) {
5081 smp->flags |= SMP_F_MAY_CHANGE;
5082 return 0;
5083 }
5084
5085 finished_trash = get_trash_chunk();
5086 if (!SSL_session_reused(conn->xprt_ctx))
5087 finished_len = SSL_get_peer_finished(conn->xprt_ctx, finished_trash->str, finished_trash->size);
5088 else
5089 finished_len = SSL_get_finished(conn->xprt_ctx, finished_trash->str, finished_trash->size);
5090
5091 if (!finished_len)
5092 return 0;
5093
Emeric Brunb73a9b02014-04-30 18:49:19 +02005094 finished_trash->len = finished_len;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005095 smp->data.u.str = *finished_trash;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005096 smp->data.type = SMP_T_BIN;
David Sc1ad52e2014-04-08 18:48:47 -04005097
5098 return 1;
5099#else
5100 return 0;
5101#endif
5102}
5103
Emeric Brun2525b6b2012-10-18 15:59:43 +02005104/* integer, returns the first verify error in CA chain of client certificate chain. */
Emeric Brunf282a812012-09-21 15:27:54 +02005105static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005106smp_fetch_ssl_c_ca_err(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brunf282a812012-09-21 15:27:54 +02005107{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005108 struct connection *conn;
5109
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02005110 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005111 if (!conn || conn->xprt != &ssl_sock)
5112 return 0;
5113
5114 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunf282a812012-09-21 15:27:54 +02005115 smp->flags = SMP_F_MAY_CHANGE;
5116 return 0;
5117 }
5118
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005119 smp->data.type = SMP_T_SINT;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005120 smp->data.u.sint = (unsigned long long int)SSL_SOCK_ST_TO_CA_ERROR(conn->xprt_st);
Emeric Brunf282a812012-09-21 15:27:54 +02005121 smp->flags = 0;
5122
5123 return 1;
5124}
5125
Emeric Brun2525b6b2012-10-18 15:59:43 +02005126/* integer, returns the depth of the first verify error in CA chain of client certificate chain. */
Emeric Brunf282a812012-09-21 15:27:54 +02005127static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005128smp_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 +02005129{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005130 struct connection *conn;
5131
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02005132 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005133 if (!conn || conn->xprt != &ssl_sock)
Emeric Brunf282a812012-09-21 15:27:54 +02005134 return 0;
5135
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005136 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunf282a812012-09-21 15:27:54 +02005137 smp->flags = SMP_F_MAY_CHANGE;
5138 return 0;
5139 }
5140
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005141 smp->data.type = SMP_T_SINT;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005142 smp->data.u.sint = (long long int)SSL_SOCK_ST_TO_CAEDEPTH(conn->xprt_st);
Emeric Brunf282a812012-09-21 15:27:54 +02005143 smp->flags = 0;
5144
5145 return 1;
5146}
5147
Emeric Brun2525b6b2012-10-18 15:59:43 +02005148/* integer, returns the first verify error on client certificate */
Emeric Brunf282a812012-09-21 15:27:54 +02005149static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005150smp_fetch_ssl_c_err(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brunf282a812012-09-21 15:27:54 +02005151{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005152 struct connection *conn;
5153
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02005154 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005155 if (!conn || conn->xprt != &ssl_sock)
5156 return 0;
5157
5158 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunf282a812012-09-21 15:27:54 +02005159 smp->flags = SMP_F_MAY_CHANGE;
5160 return 0;
5161 }
5162
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005163 smp->data.type = SMP_T_SINT;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005164 smp->data.u.sint = (long long int)SSL_SOCK_ST_TO_CRTERROR(conn->xprt_st);
Emeric Brunf282a812012-09-21 15:27:54 +02005165 smp->flags = 0;
5166
5167 return 1;
5168}
5169
Emeric Brun2525b6b2012-10-18 15:59:43 +02005170/* integer, returns the verify result on client cert */
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02005171static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005172smp_fetch_ssl_c_verify(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02005173{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005174 struct connection *conn;
5175
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02005176 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005177 if (!conn || conn->xprt != &ssl_sock)
5178 return 0;
5179
5180 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02005181 smp->flags = SMP_F_MAY_CHANGE;
5182 return 0;
5183 }
5184
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005185 if (!conn->xprt_ctx)
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02005186 return 0;
5187
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005188 smp->data.type = SMP_T_SINT;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005189 smp->data.u.sint = (long long int)SSL_get_verify_result(conn->xprt_ctx);
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02005190 smp->flags = 0;
5191
5192 return 1;
5193}
5194
Emeric Brunfb510ea2012-10-05 12:00:26 +02005195/* parse the "ca-file" bind keyword */
5196static 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 +02005197{
5198 if (!*args[cur_arg + 1]) {
5199 if (err)
5200 memprintf(err, "'%s' : missing CAfile path", args[cur_arg]);
5201 return ERR_ALERT | ERR_FATAL;
5202 }
5203
Emeric Brunef42d922012-10-11 16:11:36 +02005204 if ((*args[cur_arg + 1] != '/') && global.ca_base)
5205 memprintf(&conf->ca_file, "%s/%s", global.ca_base, args[cur_arg + 1]);
5206 else
5207 memprintf(&conf->ca_file, "%s", args[cur_arg + 1]);
Emeric Brunc8e8d122012-10-02 18:42:10 +02005208
Emeric Brund94b3fe2012-09-20 18:23:56 +02005209 return 0;
5210}
5211
Christopher Faulet31af49d2015-06-09 17:29:50 +02005212/* parse the "ca-sign-file" bind keyword */
5213static int bind_parse_ca_sign_file(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5214{
5215 if (!*args[cur_arg + 1]) {
5216 if (err)
5217 memprintf(err, "'%s' : missing CAfile path", args[cur_arg]);
5218 return ERR_ALERT | ERR_FATAL;
5219 }
5220
5221 if ((*args[cur_arg + 1] != '/') && global.ca_base)
5222 memprintf(&conf->ca_sign_file, "%s/%s", global.ca_base, args[cur_arg + 1]);
5223 else
5224 memprintf(&conf->ca_sign_file, "%s", args[cur_arg + 1]);
5225
5226 return 0;
5227}
5228
Bertrand Jacquinff13c062016-11-13 16:37:11 +00005229/* parse the "ca-sign-pass" bind keyword */
Christopher Faulet31af49d2015-06-09 17:29:50 +02005230static int bind_parse_ca_sign_pass(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5231{
5232 if (!*args[cur_arg + 1]) {
5233 if (err)
5234 memprintf(err, "'%s' : missing CAkey password", args[cur_arg]);
5235 return ERR_ALERT | ERR_FATAL;
5236 }
5237 memprintf(&conf->ca_sign_pass, "%s", args[cur_arg + 1]);
5238 return 0;
5239}
5240
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005241/* parse the "ciphers" bind keyword */
Willy Tarreau4348fad2012-09-20 16:48:07 +02005242static 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 +02005243{
5244 if (!*args[cur_arg + 1]) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02005245 memprintf(err, "'%s' : missing cipher suite", args[cur_arg]);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005246 return ERR_ALERT | ERR_FATAL;
5247 }
5248
Emeric Brun76d88952012-10-05 15:47:31 +02005249 free(conf->ciphers);
Willy Tarreau4348fad2012-09-20 16:48:07 +02005250 conf->ciphers = strdup(args[cur_arg + 1]);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005251 return 0;
5252}
5253
5254/* parse the "crt" bind keyword */
Willy Tarreau4348fad2012-09-20 16:48:07 +02005255static 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 +02005256{
Willy Tarreau38011032013-08-13 16:59:39 +02005257 char path[MAXPATHLEN];
Willy Tarreaub75d6922014-04-14 18:05:41 +02005258
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005259 if (!*args[cur_arg + 1]) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02005260 memprintf(err, "'%s' : missing certificate location", args[cur_arg]);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005261 return ERR_ALERT | ERR_FATAL;
5262 }
5263
Emeric Brunc8e8d122012-10-02 18:42:10 +02005264 if ((*args[cur_arg + 1] != '/' ) && global.crt_base) {
Willy Tarreau38011032013-08-13 16:59:39 +02005265 if ((strlen(global.crt_base) + 1 + strlen(args[cur_arg + 1]) + 1) > MAXPATHLEN) {
Emeric Brunc8e8d122012-10-02 18:42:10 +02005266 memprintf(err, "'%s' : path too long", args[cur_arg]);
5267 return ERR_ALERT | ERR_FATAL;
5268 }
Willy Tarreaub75d6922014-04-14 18:05:41 +02005269 snprintf(path, sizeof(path), "%s/%s", global.crt_base, args[cur_arg + 1]);
Willy Tarreau03209342016-12-22 17:08:28 +01005270 if (ssl_sock_load_cert(path, conf, err) > 0)
Emeric Brunc8e8d122012-10-02 18:42:10 +02005271 return ERR_ALERT | ERR_FATAL;
5272
5273 return 0;
5274 }
5275
Willy Tarreau03209342016-12-22 17:08:28 +01005276 if (ssl_sock_load_cert(args[cur_arg + 1], conf, err) > 0)
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005277 return ERR_ALERT | ERR_FATAL;
Emeric Brund94b3fe2012-09-20 18:23:56 +02005278
5279 return 0;
5280}
5281
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01005282/* parse the "crt-list" bind keyword */
5283static int bind_parse_crt_list(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5284{
5285 if (!*args[cur_arg + 1]) {
5286 memprintf(err, "'%s' : missing certificate location", args[cur_arg]);
5287 return ERR_ALERT | ERR_FATAL;
5288 }
5289
Willy Tarreau03209342016-12-22 17:08:28 +01005290 if (ssl_sock_load_cert_list_file(args[cur_arg + 1], conf, err) > 0) {
Willy Tarreauad1731d2013-04-02 17:35:58 +02005291 memprintf(err, "'%s' : %s", args[cur_arg], *err);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01005292 return ERR_ALERT | ERR_FATAL;
Willy Tarreauad1731d2013-04-02 17:35:58 +02005293 }
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01005294
5295 return 0;
5296}
5297
Emeric Brunfb510ea2012-10-05 12:00:26 +02005298/* parse the "crl-file" bind keyword */
5299static 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 +02005300{
Emeric Brun051cdab2012-10-02 19:25:50 +02005301#ifndef X509_V_FLAG_CRL_CHECK
5302 if (err)
5303 memprintf(err, "'%s' : library does not support CRL verify", args[cur_arg]);
5304 return ERR_ALERT | ERR_FATAL;
5305#else
Emeric Brund94b3fe2012-09-20 18:23:56 +02005306 if (!*args[cur_arg + 1]) {
5307 if (err)
5308 memprintf(err, "'%s' : missing CRLfile path", args[cur_arg]);
5309 return ERR_ALERT | ERR_FATAL;
5310 }
Emeric Brun2b58d042012-09-20 17:10:03 +02005311
Emeric Brunef42d922012-10-11 16:11:36 +02005312 if ((*args[cur_arg + 1] != '/') && global.ca_base)
5313 memprintf(&conf->crl_file, "%s/%s", global.ca_base, args[cur_arg + 1]);
5314 else
5315 memprintf(&conf->crl_file, "%s", args[cur_arg + 1]);
Emeric Brunc8e8d122012-10-02 18:42:10 +02005316
Emeric Brun2b58d042012-09-20 17:10:03 +02005317 return 0;
Emeric Brun051cdab2012-10-02 19:25:50 +02005318#endif
Emeric Brun2b58d042012-09-20 17:10:03 +02005319}
5320
Bertrand Jacquinff13c062016-11-13 16:37:11 +00005321/* parse the "ecdhe" bind keyword keyword */
Emeric Brun2b58d042012-09-20 17:10:03 +02005322static int bind_parse_ecdhe(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5323{
5324#if OPENSSL_VERSION_NUMBER < 0x0090800fL
5325 if (err)
5326 memprintf(err, "'%s' : library does not support elliptic curve Diffie-Hellman (too old)", args[cur_arg]);
5327 return ERR_ALERT | ERR_FATAL;
5328#elif defined(OPENSSL_NO_ECDH)
5329 if (err)
5330 memprintf(err, "'%s' : library does not support elliptic curve Diffie-Hellman (disabled via OPENSSL_NO_ECDH)", args[cur_arg]);
5331 return ERR_ALERT | ERR_FATAL;
5332#else
5333 if (!*args[cur_arg + 1]) {
5334 if (err)
5335 memprintf(err, "'%s' : missing named curve", args[cur_arg]);
5336 return ERR_ALERT | ERR_FATAL;
5337 }
5338
5339 conf->ecdhe = strdup(args[cur_arg + 1]);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005340
5341 return 0;
Emeric Brun2b58d042012-09-20 17:10:03 +02005342#endif
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005343}
5344
Bertrand Jacquinff13c062016-11-13 16:37:11 +00005345/* parse the "crt-ignore-err" and "ca-ignore-err" bind keywords */
Emeric Brun81c00f02012-09-21 14:31:21 +02005346static int bind_parse_ignore_err(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5347{
5348 int code;
5349 char *p = args[cur_arg + 1];
5350 unsigned long long *ignerr = &conf->crt_ignerr;
5351
5352 if (!*p) {
5353 if (err)
5354 memprintf(err, "'%s' : missing error IDs list", args[cur_arg]);
5355 return ERR_ALERT | ERR_FATAL;
5356 }
5357
5358 if (strcmp(args[cur_arg], "ca-ignore-err") == 0)
5359 ignerr = &conf->ca_ignerr;
5360
5361 if (strcmp(p, "all") == 0) {
5362 *ignerr = ~0ULL;
5363 return 0;
5364 }
5365
5366 while (p) {
5367 code = atoi(p);
5368 if ((code <= 0) || (code > 63)) {
5369 if (err)
5370 memprintf(err, "'%s' : ID '%d' out of range (1..63) in error IDs list '%s'",
5371 args[cur_arg], code, args[cur_arg + 1]);
5372 return ERR_ALERT | ERR_FATAL;
5373 }
5374 *ignerr |= 1ULL << code;
5375 p = strchr(p, ',');
5376 if (p)
5377 p++;
5378 }
5379
Emeric Brun2cb7ae52012-10-05 14:14:21 +02005380 return 0;
5381}
5382
5383/* parse the "force-sslv3" bind keyword */
5384static int bind_parse_force_sslv3(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5385{
5386 conf->ssl_options |= BC_SSL_O_USE_SSLV3;
5387 return 0;
5388}
5389
5390/* parse the "force-tlsv10" bind keyword */
5391static int bind_parse_force_tlsv10(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5392{
5393 conf->ssl_options |= BC_SSL_O_USE_TLSV10;
Emeric Brun2d0c4822012-10-02 13:45:20 +02005394 return 0;
5395}
5396
Emeric Brun2cb7ae52012-10-05 14:14:21 +02005397/* parse the "force-tlsv11" bind keyword */
5398static int bind_parse_force_tlsv11(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5399{
5400#if SSL_OP_NO_TLSv1_1
5401 conf->ssl_options |= BC_SSL_O_USE_TLSV11;
5402 return 0;
5403#else
5404 if (err)
5405 memprintf(err, "'%s' : library does not support protocol TLSv1.1", args[cur_arg]);
5406 return ERR_ALERT | ERR_FATAL;
5407#endif
5408}
5409
5410/* parse the "force-tlsv12" bind keyword */
5411static int bind_parse_force_tlsv12(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5412{
5413#if SSL_OP_NO_TLSv1_2
5414 conf->ssl_options |= BC_SSL_O_USE_TLSV12;
5415 return 0;
5416#else
5417 if (err)
5418 memprintf(err, "'%s' : library does not support protocol TLSv1.2", args[cur_arg]);
5419 return ERR_ALERT | ERR_FATAL;
5420#endif
5421}
5422
5423
Emeric Brun2d0c4822012-10-02 13:45:20 +02005424/* parse the "no-tls-tickets" bind keyword */
5425static int bind_parse_no_tls_tickets(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5426{
Emeric Brun89675492012-10-05 13:48:26 +02005427 conf->ssl_options |= BC_SSL_O_NO_TLS_TICKETS;
Emeric Brun81c00f02012-09-21 14:31:21 +02005428 return 0;
5429}
5430
Emeric Brun2d0c4822012-10-02 13:45:20 +02005431
Emeric Brun9b3009b2012-10-05 11:55:06 +02005432/* parse the "no-sslv3" bind keyword */
5433static 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 +02005434{
Emeric Brun89675492012-10-05 13:48:26 +02005435 conf->ssl_options |= BC_SSL_O_NO_SSLV3;
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005436 return 0;
5437}
5438
Emeric Brun9b3009b2012-10-05 11:55:06 +02005439/* parse the "no-tlsv10" bind keyword */
5440static 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 +02005441{
Emeric Brun89675492012-10-05 13:48:26 +02005442 conf->ssl_options |= BC_SSL_O_NO_TLSV10;
Emeric Brunc0ff4922012-09-28 19:37:02 +02005443 return 0;
5444}
5445
Emeric Brun9b3009b2012-10-05 11:55:06 +02005446/* parse the "no-tlsv11" bind keyword */
5447static 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 +02005448{
Emeric Brun89675492012-10-05 13:48:26 +02005449 conf->ssl_options |= BC_SSL_O_NO_TLSV11;
Emeric Brunc0ff4922012-09-28 19:37:02 +02005450 return 0;
5451}
5452
Emeric Brun9b3009b2012-10-05 11:55:06 +02005453/* parse the "no-tlsv12" bind keyword */
5454static 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 +02005455{
Emeric Brun89675492012-10-05 13:48:26 +02005456 conf->ssl_options |= BC_SSL_O_NO_TLSV12;
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005457 return 0;
5458}
5459
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02005460/* parse the "npn" bind keyword */
5461static int bind_parse_npn(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5462{
5463#ifdef OPENSSL_NPN_NEGOTIATED
5464 char *p1, *p2;
5465
5466 if (!*args[cur_arg + 1]) {
5467 memprintf(err, "'%s' : missing the comma-delimited NPN protocol suite", args[cur_arg]);
5468 return ERR_ALERT | ERR_FATAL;
5469 }
5470
5471 free(conf->npn_str);
5472
Willy Tarreau3724da12016-02-12 17:11:12 +01005473 /* the NPN string is built as a suite of (<len> <name>)*,
5474 * so we reuse each comma to store the next <len> and need
5475 * one more for the end of the string.
5476 */
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02005477 conf->npn_len = strlen(args[cur_arg + 1]) + 1;
Willy Tarreau3724da12016-02-12 17:11:12 +01005478 conf->npn_str = calloc(1, conf->npn_len + 1);
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02005479 memcpy(conf->npn_str + 1, args[cur_arg + 1], conf->npn_len);
5480
5481 /* replace commas with the name length */
5482 p1 = conf->npn_str;
5483 p2 = p1 + 1;
5484 while (1) {
5485 p2 = memchr(p1 + 1, ',', conf->npn_str + conf->npn_len - (p1 + 1));
5486 if (!p2)
5487 p2 = p1 + 1 + strlen(p1 + 1);
5488
5489 if (p2 - (p1 + 1) > 255) {
5490 *p2 = '\0';
5491 memprintf(err, "'%s' : NPN protocol name too long : '%s'", args[cur_arg], p1 + 1);
5492 return ERR_ALERT | ERR_FATAL;
5493 }
5494
5495 *p1 = p2 - (p1 + 1);
5496 p1 = p2;
5497
5498 if (!*p2)
5499 break;
5500
5501 *(p2++) = '\0';
5502 }
5503 return 0;
5504#else
5505 if (err)
5506 memprintf(err, "'%s' : library does not support TLS NPN extension", args[cur_arg]);
5507 return ERR_ALERT | ERR_FATAL;
5508#endif
5509}
5510
Willy Tarreauab861d32013-04-02 02:30:41 +02005511/* parse the "alpn" bind keyword */
5512static int bind_parse_alpn(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5513{
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01005514#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Willy Tarreauab861d32013-04-02 02:30:41 +02005515 char *p1, *p2;
5516
5517 if (!*args[cur_arg + 1]) {
5518 memprintf(err, "'%s' : missing the comma-delimited ALPN protocol suite", args[cur_arg]);
5519 return ERR_ALERT | ERR_FATAL;
5520 }
5521
5522 free(conf->alpn_str);
5523
Marcoen Hirschbergbef60912016-02-12 17:05:24 +01005524 /* the ALPN string is built as a suite of (<len> <name>)*,
5525 * so we reuse each comma to store the next <len> and need
5526 * one more for the end of the string.
5527 */
Willy Tarreauab861d32013-04-02 02:30:41 +02005528 conf->alpn_len = strlen(args[cur_arg + 1]) + 1;
Marcoen Hirschbergbef60912016-02-12 17:05:24 +01005529 conf->alpn_str = calloc(1, conf->alpn_len + 1);
Willy Tarreauab861d32013-04-02 02:30:41 +02005530 memcpy(conf->alpn_str + 1, args[cur_arg + 1], conf->alpn_len);
5531
5532 /* replace commas with the name length */
5533 p1 = conf->alpn_str;
5534 p2 = p1 + 1;
5535 while (1) {
5536 p2 = memchr(p1 + 1, ',', conf->alpn_str + conf->alpn_len - (p1 + 1));
5537 if (!p2)
5538 p2 = p1 + 1 + strlen(p1 + 1);
5539
5540 if (p2 - (p1 + 1) > 255) {
5541 *p2 = '\0';
5542 memprintf(err, "'%s' : ALPN protocol name too long : '%s'", args[cur_arg], p1 + 1);
5543 return ERR_ALERT | ERR_FATAL;
5544 }
5545
5546 *p1 = p2 - (p1 + 1);
5547 p1 = p2;
5548
5549 if (!*p2)
5550 break;
5551
5552 *(p2++) = '\0';
5553 }
5554 return 0;
5555#else
5556 if (err)
5557 memprintf(err, "'%s' : library does not support TLS ALPN extension", args[cur_arg]);
5558 return ERR_ALERT | ERR_FATAL;
5559#endif
5560}
5561
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005562/* parse the "ssl" bind keyword */
Willy Tarreau4348fad2012-09-20 16:48:07 +02005563static 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 +02005564{
Willy Tarreau71a8c7c2016-12-21 22:04:54 +01005565 conf->xprt = &ssl_sock;
Willy Tarreau4348fad2012-09-20 16:48:07 +02005566 conf->is_ssl = 1;
Emeric Brun76d88952012-10-05 15:47:31 +02005567
5568 if (global.listen_default_ciphers && !conf->ciphers)
5569 conf->ciphers = strdup(global.listen_default_ciphers);
Emeric Brun2c86cbf2014-10-30 15:56:50 +01005570 conf->ssl_options |= global.listen_default_ssloptions;
Emeric Brun76d88952012-10-05 15:47:31 +02005571
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005572 return 0;
5573}
5574
Christopher Faulet31af49d2015-06-09 17:29:50 +02005575/* parse the "generate-certificates" bind keyword */
5576static int bind_parse_generate_certs(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5577{
5578#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
5579 conf->generate_certs = 1;
5580#else
5581 memprintf(err, "%sthis version of openssl cannot generate SSL certificates.\n",
5582 err && *err ? *err : "");
5583#endif
5584 return 0;
5585}
5586
Emmanuel Hocdet65623372013-01-24 17:17:15 +01005587/* parse the "strict-sni" bind keyword */
5588static int bind_parse_strict_sni(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5589{
5590 conf->strict_sni = 1;
5591 return 0;
Nenad Merdanovic05552d42015-02-27 19:56:49 +01005592}
5593
5594/* parse the "tls-ticket-keys" bind keyword */
5595static int bind_parse_tls_ticket_keys(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5596{
5597#if (defined SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB && TLS_TICKETS_NO > 0)
5598 FILE *f;
5599 int i = 0;
5600 char thisline[LINESIZE];
Nenad Merdanovic146defa2015-05-09 08:46:00 +02005601 struct tls_keys_ref *keys_ref;
Nenad Merdanovic05552d42015-02-27 19:56:49 +01005602
5603 if (!*args[cur_arg + 1]) {
5604 if (err)
5605 memprintf(err, "'%s' : missing TLS ticket keys file path", args[cur_arg]);
5606 return ERR_ALERT | ERR_FATAL;
5607 }
5608
Nenad Merdanovic200b0fa2015-05-09 08:46:01 +02005609 keys_ref = tlskeys_ref_lookup(args[cur_arg + 1]);
5610 if(keys_ref) {
5611 conf->keys_ref = keys_ref;
5612 return 0;
5613 }
5614
Vincent Bernat02779b62016-04-03 13:48:43 +02005615 keys_ref = malloc(sizeof(*keys_ref));
Nenad Merdanovic146defa2015-05-09 08:46:00 +02005616 keys_ref->tlskeys = malloc(TLS_TICKETS_NO * sizeof(struct tls_sess_key));
Nenad Merdanovic05552d42015-02-27 19:56:49 +01005617
5618 if ((f = fopen(args[cur_arg + 1], "r")) == NULL) {
5619 if (err)
5620 memprintf(err, "'%s' : unable to load ssl tickets keys file", args[cur_arg+1]);
5621 return ERR_ALERT | ERR_FATAL;
5622 }
5623
Nenad Merdanovic146defa2015-05-09 08:46:00 +02005624 keys_ref->filename = strdup(args[cur_arg + 1]);
5625
Nenad Merdanovic05552d42015-02-27 19:56:49 +01005626 while (fgets(thisline, sizeof(thisline), f) != NULL) {
5627 int len = strlen(thisline);
5628 /* Strip newline characters from the end */
5629 if(thisline[len - 1] == '\n')
5630 thisline[--len] = 0;
5631
5632 if(thisline[len - 1] == '\r')
5633 thisline[--len] = 0;
5634
Nenad Merdanovic146defa2015-05-09 08:46:00 +02005635 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 +01005636 if (err)
5637 memprintf(err, "'%s' : unable to decode base64 key on line %d", args[cur_arg+1], i + 1);
mildis16aa0152016-06-22 17:46:29 +02005638 fclose(f);
Nenad Merdanovic05552d42015-02-27 19:56:49 +01005639 return ERR_ALERT | ERR_FATAL;
5640 }
5641 i++;
5642 }
5643
5644 if (i < TLS_TICKETS_NO) {
5645 if (err)
5646 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 +02005647 fclose(f);
Nenad Merdanovic05552d42015-02-27 19:56:49 +01005648 return ERR_ALERT | ERR_FATAL;
5649 }
5650
5651 fclose(f);
5652
5653 /* Use penultimate key for encryption, handle when TLS_TICKETS_NO = 1 */
Nenad Merdanovic17891152016-03-25 22:16:57 +01005654 i -= 2;
5655 keys_ref->tls_ticket_enc_index = i < 0 ? 0 : i % TLS_TICKETS_NO;
Nenad Merdanovic200b0fa2015-05-09 08:46:01 +02005656 keys_ref->unique_id = -1;
Nenad Merdanovic146defa2015-05-09 08:46:00 +02005657 conf->keys_ref = keys_ref;
Nenad Merdanovic05552d42015-02-27 19:56:49 +01005658
Nenad Merdanovic200b0fa2015-05-09 08:46:01 +02005659 LIST_ADD(&tlskeys_reference, &keys_ref->list);
5660
Nenad Merdanovic05552d42015-02-27 19:56:49 +01005661 return 0;
5662#else
5663 if (err)
5664 memprintf(err, "'%s' : TLS ticket callback extension not supported", args[cur_arg]);
5665 return ERR_ALERT | ERR_FATAL;
5666#endif /* SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB */
Emmanuel Hocdet65623372013-01-24 17:17:15 +01005667}
5668
Emeric Brund94b3fe2012-09-20 18:23:56 +02005669/* parse the "verify" bind keyword */
5670static int bind_parse_verify(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5671{
5672 if (!*args[cur_arg + 1]) {
5673 if (err)
5674 memprintf(err, "'%s' : missing verify method", args[cur_arg]);
5675 return ERR_ALERT | ERR_FATAL;
5676 }
5677
5678 if (strcmp(args[cur_arg + 1], "none") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01005679 conf->verify = SSL_SOCK_VERIFY_NONE;
Emeric Brund94b3fe2012-09-20 18:23:56 +02005680 else if (strcmp(args[cur_arg + 1], "optional") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01005681 conf->verify = SSL_SOCK_VERIFY_OPTIONAL;
Emeric Brund94b3fe2012-09-20 18:23:56 +02005682 else if (strcmp(args[cur_arg + 1], "required") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01005683 conf->verify = SSL_SOCK_VERIFY_REQUIRED;
Emeric Brund94b3fe2012-09-20 18:23:56 +02005684 else {
5685 if (err)
5686 memprintf(err, "'%s' : unknown verify method '%s', only 'none', 'optional', and 'required' are supported\n",
5687 args[cur_arg], args[cur_arg + 1]);
5688 return ERR_ALERT | ERR_FATAL;
5689 }
5690
5691 return 0;
5692}
5693
Willy Tarreau92faadf2012-10-10 23:04:25 +02005694/************** "server" keywords ****************/
5695
Emeric Brunef42d922012-10-11 16:11:36 +02005696/* parse the "ca-file" server keyword */
5697static int srv_parse_ca_file(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5698{
5699 if (!*args[*cur_arg + 1]) {
5700 if (err)
5701 memprintf(err, "'%s' : missing CAfile path", args[*cur_arg]);
5702 return ERR_ALERT | ERR_FATAL;
5703 }
5704
5705 if ((*args[*cur_arg + 1] != '/') && global.ca_base)
5706 memprintf(&newsrv->ssl_ctx.ca_file, "%s/%s", global.ca_base, args[*cur_arg + 1]);
5707 else
5708 memprintf(&newsrv->ssl_ctx.ca_file, "%s", args[*cur_arg + 1]);
5709
5710 return 0;
5711}
5712
Willy Tarreau92faadf2012-10-10 23:04:25 +02005713/* parse the "check-ssl" server keyword */
5714static int srv_parse_check_ssl(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5715{
5716 newsrv->check.use_ssl = 1;
5717 if (global.connect_default_ciphers && !newsrv->ssl_ctx.ciphers)
5718 newsrv->ssl_ctx.ciphers = strdup(global.connect_default_ciphers);
Emeric Brun2c86cbf2014-10-30 15:56:50 +01005719 newsrv->ssl_ctx.options |= global.connect_default_ssloptions;
Willy Tarreau92faadf2012-10-10 23:04:25 +02005720 return 0;
5721}
5722
5723/* parse the "ciphers" server keyword */
5724static int srv_parse_ciphers(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5725{
5726 if (!*args[*cur_arg + 1]) {
5727 memprintf(err, "'%s' : missing cipher suite", args[*cur_arg]);
5728 return ERR_ALERT | ERR_FATAL;
5729 }
5730
5731 free(newsrv->ssl_ctx.ciphers);
5732 newsrv->ssl_ctx.ciphers = strdup(args[*cur_arg + 1]);
5733 return 0;
5734}
5735
Emeric Brunef42d922012-10-11 16:11:36 +02005736/* parse the "crl-file" server keyword */
5737static int srv_parse_crl_file(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5738{
5739#ifndef X509_V_FLAG_CRL_CHECK
5740 if (err)
5741 memprintf(err, "'%s' : library does not support CRL verify", args[*cur_arg]);
5742 return ERR_ALERT | ERR_FATAL;
5743#else
5744 if (!*args[*cur_arg + 1]) {
5745 if (err)
5746 memprintf(err, "'%s' : missing CRLfile path", args[*cur_arg]);
5747 return ERR_ALERT | ERR_FATAL;
5748 }
5749
5750 if ((*args[*cur_arg + 1] != '/') && global.ca_base)
5751 memprintf(&newsrv->ssl_ctx.crl_file, "%s/%s", global.ca_base, args[*cur_arg + 1]);
5752 else
5753 memprintf(&newsrv->ssl_ctx.crl_file, "%s", args[*cur_arg + 1]);
5754
5755 return 0;
5756#endif
5757}
5758
Emeric Bruna7aa3092012-10-26 12:58:00 +02005759/* parse the "crt" server keyword */
5760static int srv_parse_crt(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5761{
5762 if (!*args[*cur_arg + 1]) {
5763 if (err)
5764 memprintf(err, "'%s' : missing certificate file path", args[*cur_arg]);
5765 return ERR_ALERT | ERR_FATAL;
5766 }
5767
5768 if ((*args[*cur_arg + 1] != '/') && global.crt_base)
5769 memprintf(&newsrv->ssl_ctx.client_crt, "%s/%s", global.ca_base, args[*cur_arg + 1]);
5770 else
5771 memprintf(&newsrv->ssl_ctx.client_crt, "%s", args[*cur_arg + 1]);
5772
5773 return 0;
5774}
Emeric Brunef42d922012-10-11 16:11:36 +02005775
Willy Tarreau92faadf2012-10-10 23:04:25 +02005776/* parse the "force-sslv3" server keyword */
5777static int srv_parse_force_sslv3(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5778{
5779 newsrv->ssl_ctx.options |= SRV_SSL_O_USE_SSLV3;
5780 return 0;
5781}
5782
5783/* parse the "force-tlsv10" server keyword */
5784static int srv_parse_force_tlsv10(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5785{
5786 newsrv->ssl_ctx.options |= SRV_SSL_O_USE_TLSV10;
5787 return 0;
5788}
5789
5790/* parse the "force-tlsv11" server keyword */
5791static int srv_parse_force_tlsv11(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5792{
5793#if SSL_OP_NO_TLSv1_1
5794 newsrv->ssl_ctx.options |= SRV_SSL_O_USE_TLSV11;
5795 return 0;
5796#else
5797 if (err)
5798 memprintf(err, "'%s' : library does not support protocol TLSv1.1", args[*cur_arg]);
5799 return ERR_ALERT | ERR_FATAL;
5800#endif
5801}
5802
5803/* parse the "force-tlsv12" server keyword */
5804static int srv_parse_force_tlsv12(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5805{
5806#if SSL_OP_NO_TLSv1_2
5807 newsrv->ssl_ctx.options |= SRV_SSL_O_USE_TLSV12;
5808 return 0;
5809#else
5810 if (err)
5811 memprintf(err, "'%s' : library does not support protocol TLSv1.2", args[*cur_arg]);
5812 return ERR_ALERT | ERR_FATAL;
5813#endif
5814}
5815
Willy Tarreau2a3fb1c2015-02-05 16:47:07 +01005816/* parse the "no-ssl-reuse" server keyword */
5817static int srv_parse_no_ssl_reuse(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5818{
5819 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_REUSE;
5820 return 0;
5821}
5822
Willy Tarreau92faadf2012-10-10 23:04:25 +02005823/* parse the "no-sslv3" server keyword */
5824static int srv_parse_no_sslv3(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5825{
5826 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_SSLV3;
5827 return 0;
5828}
5829
5830/* parse the "no-tlsv10" server keyword */
5831static int srv_parse_no_tlsv10(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5832{
5833 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_TLSV10;
5834 return 0;
5835}
5836
5837/* parse the "no-tlsv11" server keyword */
5838static int srv_parse_no_tlsv11(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5839{
5840 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_TLSV11;
5841 return 0;
5842}
5843
5844/* parse the "no-tlsv12" server keyword */
5845static int srv_parse_no_tlsv12(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5846{
5847 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_TLSV12;
5848 return 0;
5849}
5850
Emeric Brunf9c5c472012-10-11 15:28:34 +02005851/* parse the "no-tls-tickets" server keyword */
5852static int srv_parse_no_tls_tickets(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5853{
5854 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_TLS_TICKETS;
5855 return 0;
5856}
David Safb76832014-05-08 23:42:08 -04005857/* parse the "send-proxy-v2-ssl" server keyword */
5858static int srv_parse_send_proxy_ssl(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5859{
5860 newsrv->pp_opts |= SRV_PP_V2;
5861 newsrv->pp_opts |= SRV_PP_V2_SSL;
5862 return 0;
5863}
5864
5865/* parse the "send-proxy-v2-ssl-cn" server keyword */
5866static int srv_parse_send_proxy_cn(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5867{
5868 newsrv->pp_opts |= SRV_PP_V2;
5869 newsrv->pp_opts |= SRV_PP_V2_SSL;
5870 newsrv->pp_opts |= SRV_PP_V2_SSL_CN;
5871 return 0;
5872}
Emeric Brunf9c5c472012-10-11 15:28:34 +02005873
Willy Tarreau732eac42015-07-09 11:40:25 +02005874/* parse the "sni" server keyword */
5875static int srv_parse_sni(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5876{
5877#ifndef SSL_CTRL_SET_TLSEXT_HOSTNAME
5878 memprintf(err, "'%s' : the current SSL library doesn't support the SNI TLS extension", args[*cur_arg]);
5879 return ERR_ALERT | ERR_FATAL;
5880#else
Cyril Bonté23d19d62016-03-07 22:13:22 +01005881 int idx;
Willy Tarreau732eac42015-07-09 11:40:25 +02005882 struct sample_expr *expr;
5883
5884 if (!*args[*cur_arg + 1]) {
5885 memprintf(err, "'%s' : missing sni expression", args[*cur_arg]);
5886 return ERR_ALERT | ERR_FATAL;
5887 }
5888
Cyril Bonté23d19d62016-03-07 22:13:22 +01005889 idx = (*cur_arg) + 1;
Willy Tarreau732eac42015-07-09 11:40:25 +02005890 proxy->conf.args.ctx = ARGC_SRV;
5891
Cyril Bonté23d19d62016-03-07 22:13:22 +01005892 expr = sample_parse_expr((char **)args, &idx, px->conf.file, px->conf.line, err, &proxy->conf.args);
Willy Tarreau732eac42015-07-09 11:40:25 +02005893 if (!expr) {
5894 memprintf(err, "error detected while parsing sni expression : %s", *err);
5895 return ERR_ALERT | ERR_FATAL;
5896 }
5897
5898 if (!(expr->fetch->val & SMP_VAL_BE_SRV_CON)) {
5899 memprintf(err, "error detected while parsing sni expression : "
5900 " fetch method '%s' extracts information from '%s', none of which is available here.\n",
Cyril Bonté23d19d62016-03-07 22:13:22 +01005901 args[idx-1], sample_src_names(expr->fetch->use));
Willy Tarreau732eac42015-07-09 11:40:25 +02005902 return ERR_ALERT | ERR_FATAL;
5903 }
5904
5905 px->http_needed |= !!(expr->fetch->use & SMP_USE_HTTP_ANY);
5906 newsrv->ssl_ctx.sni = expr;
5907 return 0;
5908#endif
5909}
5910
Willy Tarreau92faadf2012-10-10 23:04:25 +02005911/* parse the "ssl" server keyword */
5912static int srv_parse_ssl(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5913{
5914 newsrv->use_ssl = 1;
5915 if (global.connect_default_ciphers && !newsrv->ssl_ctx.ciphers)
5916 newsrv->ssl_ctx.ciphers = strdup(global.connect_default_ciphers);
5917 return 0;
5918}
5919
Emeric Brunef42d922012-10-11 16:11:36 +02005920/* parse the "verify" server keyword */
5921static int srv_parse_verify(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5922{
5923 if (!*args[*cur_arg + 1]) {
5924 if (err)
5925 memprintf(err, "'%s' : missing verify method", args[*cur_arg]);
5926 return ERR_ALERT | ERR_FATAL;
5927 }
5928
5929 if (strcmp(args[*cur_arg + 1], "none") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01005930 newsrv->ssl_ctx.verify = SSL_SOCK_VERIFY_NONE;
Emeric Brunef42d922012-10-11 16:11:36 +02005931 else if (strcmp(args[*cur_arg + 1], "required") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01005932 newsrv->ssl_ctx.verify = SSL_SOCK_VERIFY_REQUIRED;
Emeric Brunef42d922012-10-11 16:11:36 +02005933 else {
5934 if (err)
5935 memprintf(err, "'%s' : unknown verify method '%s', only 'none' and 'required' are supported\n",
5936 args[*cur_arg], args[*cur_arg + 1]);
5937 return ERR_ALERT | ERR_FATAL;
5938 }
5939
Evan Broderbe554312013-06-27 00:05:25 -07005940 return 0;
5941}
5942
5943/* parse the "verifyhost" server keyword */
5944static int srv_parse_verifyhost(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5945{
5946 if (!*args[*cur_arg + 1]) {
5947 if (err)
5948 memprintf(err, "'%s' : missing hostname to verify against", args[*cur_arg]);
5949 return ERR_ALERT | ERR_FATAL;
5950 }
5951
5952 newsrv->ssl_ctx.verify_host = strdup(args[*cur_arg + 1]);
5953
Emeric Brunef42d922012-10-11 16:11:36 +02005954 return 0;
5955}
5956
Emeric Brun2c86cbf2014-10-30 15:56:50 +01005957/* parse the "ssl-default-bind-options" keyword in global section */
5958static int ssl_parse_default_bind_options(char **args, int section_type, struct proxy *curpx,
5959 struct proxy *defpx, const char *file, int line,
5960 char **err) {
5961 int i = 1;
5962
5963 if (*(args[i]) == 0) {
5964 memprintf(err, "global statement '%s' expects an option as an argument.", args[0]);
5965 return -1;
5966 }
5967 while (*(args[i])) {
5968 if (!strcmp(args[i], "no-sslv3"))
5969 global.listen_default_ssloptions |= BC_SSL_O_NO_SSLV3;
5970 else if (!strcmp(args[i], "no-tlsv10"))
5971 global.listen_default_ssloptions |= BC_SSL_O_NO_TLSV10;
5972 else if (!strcmp(args[i], "no-tlsv11"))
5973 global.listen_default_ssloptions |= BC_SSL_O_NO_TLSV11;
5974 else if (!strcmp(args[i], "no-tlsv12"))
5975 global.listen_default_ssloptions |= BC_SSL_O_NO_TLSV12;
5976 else if (!strcmp(args[i], "force-sslv3"))
5977 global.listen_default_ssloptions |= BC_SSL_O_USE_SSLV3;
5978 else if (!strcmp(args[i], "force-tlsv10"))
5979 global.listen_default_ssloptions |= BC_SSL_O_USE_TLSV10;
5980 else if (!strcmp(args[i], "force-tlsv11")) {
5981#if SSL_OP_NO_TLSv1_1
5982 global.listen_default_ssloptions |= BC_SSL_O_USE_TLSV11;
5983#else
5984 memprintf(err, "'%s' '%s': library does not support protocol TLSv1.1", args[0], args[i]);
5985 return -1;
5986#endif
5987 }
5988 else if (!strcmp(args[i], "force-tlsv12")) {
5989#if SSL_OP_NO_TLSv1_2
5990 global.listen_default_ssloptions |= BC_SSL_O_USE_TLSV12;
5991#else
5992 memprintf(err, "'%s' '%s': library does not support protocol TLSv1.2", args[0], args[i]);
5993 return -1;
5994#endif
5995 }
5996 else if (!strcmp(args[i], "no-tls-tickets"))
5997 global.listen_default_ssloptions |= BC_SSL_O_NO_TLS_TICKETS;
5998 else {
5999 memprintf(err, "unknown option '%s' on global statement '%s'.", args[i], args[0]);
6000 return -1;
6001 }
6002 i++;
6003 }
6004 return 0;
6005}
6006
6007/* parse the "ssl-default-server-options" keyword in global section */
6008static int ssl_parse_default_server_options(char **args, int section_type, struct proxy *curpx,
6009 struct proxy *defpx, const char *file, int line,
6010 char **err) {
6011 int i = 1;
6012
6013 if (*(args[i]) == 0) {
6014 memprintf(err, "global statement '%s' expects an option as an argument.", args[0]);
6015 return -1;
6016 }
6017 while (*(args[i])) {
6018 if (!strcmp(args[i], "no-sslv3"))
6019 global.connect_default_ssloptions |= SRV_SSL_O_NO_SSLV3;
6020 else if (!strcmp(args[i], "no-tlsv10"))
6021 global.connect_default_ssloptions |= SRV_SSL_O_NO_TLSV10;
6022 else if (!strcmp(args[i], "no-tlsv11"))
6023 global.connect_default_ssloptions |= SRV_SSL_O_NO_TLSV11;
6024 else if (!strcmp(args[i], "no-tlsv12"))
6025 global.connect_default_ssloptions |= SRV_SSL_O_NO_TLSV12;
6026 else if (!strcmp(args[i], "force-sslv3"))
6027 global.connect_default_ssloptions |= SRV_SSL_O_USE_SSLV3;
6028 else if (!strcmp(args[i], "force-tlsv10"))
6029 global.connect_default_ssloptions |= SRV_SSL_O_USE_TLSV10;
6030 else if (!strcmp(args[i], "force-tlsv11")) {
6031#if SSL_OP_NO_TLSv1_1
6032 global.connect_default_ssloptions |= SRV_SSL_O_USE_TLSV11;
6033#else
6034 memprintf(err, "'%s' '%s': library does not support protocol TLSv1.1", args[0], args[i]);
6035 return -1;
6036#endif
6037 }
6038 else if (!strcmp(args[i], "force-tlsv12")) {
6039#if SSL_OP_NO_TLSv1_2
6040 global.connect_default_ssloptions |= SRV_SSL_O_USE_TLSV12;
6041#else
6042 memprintf(err, "'%s' '%s': library does not support protocol TLSv1.2", args[0], args[i]);
6043 return -1;
6044#endif
6045 }
6046 else if (!strcmp(args[i], "no-tls-tickets"))
6047 global.connect_default_ssloptions |= SRV_SSL_O_NO_TLS_TICKETS;
6048 else {
6049 memprintf(err, "unknown option '%s' on global statement '%s'.", args[i], args[0]);
6050 return -1;
6051 }
6052 i++;
6053 }
6054 return 0;
6055}
6056
Willy Tarreau8c3b0fd2016-12-21 22:44:46 +01006057/* parse the "ca-base" / "crt-base" keywords in global section.
6058 * Returns <0 on alert, >0 on warning, 0 on success.
6059 */
6060static int ssl_parse_global_ca_crt_base(char **args, int section_type, struct proxy *curpx,
6061 struct proxy *defpx, const char *file, int line,
6062 char **err)
6063{
6064 char **target;
6065
6066 target = (args[0][1] == 'a') ? &global.ca_base : &global.crt_base;
6067
6068 if (too_many_args(1, args, err, NULL))
6069 return -1;
6070
6071 if (*target) {
6072 memprintf(err, "'%s' already specified.", args[0]);
6073 return -1;
6074 }
6075
6076 if (*(args[1]) == 0) {
6077 memprintf(err, "global statement '%s' expects a directory path as an argument.", args[0]);
6078 return -1;
6079 }
6080 *target = strdup(args[1]);
6081 return 0;
6082}
6083
Willy Tarreauf22e9682016-12-21 23:23:19 +01006084/* parse the "ssl-default-bind-ciphers" / "ssl-default-server-ciphers" keywords
6085 * in global section. Returns <0 on alert, >0 on warning, 0 on success.
6086 */
6087static int ssl_parse_global_ciphers(char **args, int section_type, struct proxy *curpx,
6088 struct proxy *defpx, const char *file, int line,
6089 char **err)
6090{
6091 char **target;
6092
6093 target = (args[0][12] == 'b') ? &global.listen_default_ciphers : &global.connect_default_ciphers;
6094
6095 if (too_many_args(1, args, err, NULL))
6096 return -1;
6097
6098 if (*(args[1]) == 0) {
6099 memprintf(err, "global statement '%s' expects a cipher suite as an argument.", args[0]);
6100 return -1;
6101 }
6102
6103 free(*target);
6104 *target = strdup(args[1]);
6105 return 0;
6106}
6107
Willy Tarreau9ceda382016-12-21 23:13:03 +01006108/* parse various global tune.ssl settings consisting in positive integers.
6109 * Returns <0 on alert, >0 on warning, 0 on success.
6110 */
6111static int ssl_parse_global_int(char **args, int section_type, struct proxy *curpx,
6112 struct proxy *defpx, const char *file, int line,
6113 char **err)
6114{
6115 int *target;
6116
6117 if (strcmp(args[0], "tune.ssl.cachesize") == 0)
6118 target = &global.tune.sslcachesize;
6119 else if (strcmp(args[0], "tune.ssl.maxrecord") == 0)
6120 target = (int *)&global.tune.ssl_max_record;
6121 else if (strcmp(args[0], "tune.ssl.ssl-ctx-cache-size") == 0)
6122 target = &global.tune.ssl_ctx_cache;
Willy Tarreau0bea58d2016-12-21 23:17:25 +01006123 else if (strcmp(args[0], "maxsslconn") == 0)
6124 target = &global.maxsslconn;
Willy Tarreau9ceda382016-12-21 23:13:03 +01006125 else {
6126 memprintf(err, "'%s' keyword not unhandled (please report this bug).", args[0]);
6127 return -1;
6128 }
6129
6130 if (too_many_args(1, args, err, NULL))
6131 return -1;
6132
6133 if (*(args[1]) == 0) {
6134 memprintf(err, "'%s' expects an integer argument.", args[0]);
6135 return -1;
6136 }
6137
6138 *target = atoi(args[1]);
6139 if (*target < 0) {
6140 memprintf(err, "'%s' expects a positive numeric value.", args[0]);
6141 return -1;
6142 }
6143 return 0;
6144}
6145
6146/* parse "ssl.force-private-cache".
6147 * Returns <0 on alert, >0 on warning, 0 on success.
6148 */
6149static int ssl_parse_global_private_cache(char **args, int section_type, struct proxy *curpx,
6150 struct proxy *defpx, const char *file, int line,
6151 char **err)
6152{
6153 if (too_many_args(0, args, err, NULL))
6154 return -1;
6155
6156 global.tune.sslprivatecache = 1;
6157 return 0;
6158}
6159
6160/* parse "ssl.lifetime".
6161 * Returns <0 on alert, >0 on warning, 0 on success.
6162 */
6163static int ssl_parse_global_lifetime(char **args, int section_type, struct proxy *curpx,
6164 struct proxy *defpx, const char *file, int line,
6165 char **err)
6166{
6167 const char *res;
6168
6169 if (too_many_args(1, args, err, NULL))
6170 return -1;
6171
6172 if (*(args[1]) == 0) {
6173 memprintf(err, "'%s' expects ssl sessions <lifetime> in seconds as argument.", args[0]);
6174 return -1;
6175 }
6176
6177 res = parse_time_err(args[1], &global.tune.ssllifetime, TIME_UNIT_S);
6178 if (res) {
6179 memprintf(err, "unexpected character '%c' in argument to <%s>.", *res, args[0]);
6180 return -1;
6181 }
6182 return 0;
6183}
6184
6185#ifndef OPENSSL_NO_DH
Willy Tarreau14e36a12016-12-21 23:28:13 +01006186/* parse "ssl-dh-param-file".
6187 * Returns <0 on alert, >0 on warning, 0 on success.
6188 */
6189static int ssl_parse_global_dh_param_file(char **args, int section_type, struct proxy *curpx,
6190 struct proxy *defpx, const char *file, int line,
6191 char **err)
6192{
6193 if (too_many_args(1, args, err, NULL))
6194 return -1;
6195
6196 if (*(args[1]) == 0) {
6197 memprintf(err, "'%s' expects a file path as an argument.", args[0]);
6198 return -1;
6199 }
6200
6201 if (ssl_sock_load_global_dh_param_from_file(args[1])) {
6202 memprintf(err, "'%s': unable to load DH parameters from file <%s>.", args[0], args[1]);
6203 return -1;
6204 }
6205 return 0;
6206}
6207
Willy Tarreau9ceda382016-12-21 23:13:03 +01006208/* parse "ssl.default-dh-param".
6209 * Returns <0 on alert, >0 on warning, 0 on success.
6210 */
6211static int ssl_parse_global_default_dh(char **args, int section_type, struct proxy *curpx,
6212 struct proxy *defpx, const char *file, int line,
6213 char **err)
6214{
6215 if (too_many_args(1, args, err, NULL))
6216 return -1;
6217
6218 if (*(args[1]) == 0) {
6219 memprintf(err, "'%s' expects an integer argument.", args[0]);
6220 return -1;
6221 }
6222
6223 global.tune.ssl_default_dh_param = atoi(args[1]);
6224 if (global.tune.ssl_default_dh_param < 1024) {
6225 memprintf(err, "'%s' expects a value >= 1024.", args[0]);
6226 return -1;
6227 }
6228 return 0;
6229}
6230#endif
6231
6232
William Lallemand32af2032016-10-29 18:09:35 +02006233/* This function is used with TLS ticket keys management. It permits to browse
6234 * each reference. The variable <getnext> must contain the current node,
6235 * <end> point to the root node.
6236 */
6237#if (defined SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB && TLS_TICKETS_NO > 0)
6238static inline
6239struct tls_keys_ref *tlskeys_list_get_next(struct tls_keys_ref *getnext, struct list *end)
6240{
6241 struct tls_keys_ref *ref = getnext;
6242
6243 while (1) {
6244
6245 /* Get next list entry. */
6246 ref = LIST_NEXT(&ref->list, struct tls_keys_ref *, list);
6247
6248 /* If the entry is the last of the list, return NULL. */
6249 if (&ref->list == end)
6250 return NULL;
6251
6252 return ref;
6253 }
6254}
6255
6256static inline
6257struct tls_keys_ref *tlskeys_ref_lookup_ref(const char *reference)
6258{
6259 int id;
6260 char *error;
6261
6262 /* If the reference starts by a '#', this is numeric id. */
6263 if (reference[0] == '#') {
6264 /* Try to convert the numeric id. If the conversion fails, the lookup fails. */
6265 id = strtol(reference + 1, &error, 10);
6266 if (*error != '\0')
6267 return NULL;
6268
6269 /* Perform the unique id lookup. */
6270 return tlskeys_ref_lookupid(id);
6271 }
6272
6273 /* Perform the string lookup. */
6274 return tlskeys_ref_lookup(reference);
6275}
6276#endif
6277
6278
6279#if (defined SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB && TLS_TICKETS_NO > 0)
6280
6281static int cli_io_handler_tlskeys_files(struct appctx *appctx);
6282
6283static inline int cli_io_handler_tlskeys_entries(struct appctx *appctx) {
6284 return cli_io_handler_tlskeys_files(appctx);
6285}
6286
Willy Tarreauf5f26e82016-12-16 18:47:27 +01006287/* dumps all tls keys. Relies on cli.i0 (non-null = only list file names), cli.i1
6288 * (next index to be dumped), and cli.p0 (next key reference).
6289 */
William Lallemand32af2032016-10-29 18:09:35 +02006290static int cli_io_handler_tlskeys_files(struct appctx *appctx) {
6291
6292 struct stream_interface *si = appctx->owner;
6293
6294 switch (appctx->st2) {
6295 case STAT_ST_INIT:
6296 /* Display the column headers. If the message cannot be sent,
6297 * quit the fucntion with returning 0. The function is called
6298 * later and restart at the state "STAT_ST_INIT".
6299 */
6300 chunk_reset(&trash);
6301
6302 if (appctx->io_handler == cli_io_handler_tlskeys_entries)
6303 chunk_appendf(&trash, "# id secret\n");
6304 else
6305 chunk_appendf(&trash, "# id (file)\n");
6306
6307 if (bi_putchk(si_ic(si), &trash) == -1) {
6308 si_applet_cant_put(si);
6309 return 0;
6310 }
6311
William Lallemand32af2032016-10-29 18:09:35 +02006312 /* Now, we start the browsing of the references lists.
6313 * Note that the following call to LIST_ELEM return bad pointer. The only
6314 * available field of this pointer is <list>. It is used with the function
6315 * tlskeys_list_get_next() for retruning the first available entry
6316 */
Willy Tarreauf5f26e82016-12-16 18:47:27 +01006317 if (appctx->ctx.cli.p0 == NULL) {
6318 appctx->ctx.cli.p0 = LIST_ELEM(&tlskeys_reference, struct tls_keys_ref *, list);
6319 appctx->ctx.cli.p0 = tlskeys_list_get_next(appctx->ctx.cli.p0, &tlskeys_reference);
William Lallemand32af2032016-10-29 18:09:35 +02006320 }
6321
6322 appctx->st2 = STAT_ST_LIST;
6323 /* fall through */
6324
6325 case STAT_ST_LIST:
Willy Tarreauf5f26e82016-12-16 18:47:27 +01006326 while (appctx->ctx.cli.p0) {
6327 struct tls_keys_ref *ref = appctx->ctx.cli.p0;
6328 int head = ref->tls_ticket_enc_index;
William Lallemand32af2032016-10-29 18:09:35 +02006329
6330 chunk_reset(&trash);
Willy Tarreauf5f26e82016-12-16 18:47:27 +01006331 if (appctx->io_handler == cli_io_handler_tlskeys_entries && appctx->ctx.cli.i1 == 0)
William Lallemand32af2032016-10-29 18:09:35 +02006332 chunk_appendf(&trash, "# ");
Willy Tarreauf5f26e82016-12-16 18:47:27 +01006333
6334 if (appctx->ctx.cli.i1 == 0)
6335 chunk_appendf(&trash, "%d (%s)\n", ref->unique_id, ref->filename);
6336
William Lallemand32af2032016-10-29 18:09:35 +02006337 if (appctx->io_handler == cli_io_handler_tlskeys_entries) {
Willy Tarreauf5f26e82016-12-16 18:47:27 +01006338 while (appctx->ctx.cli.i1 < TLS_TICKETS_NO) {
William Lallemand32af2032016-10-29 18:09:35 +02006339 struct chunk *t2 = get_trash_chunk();
6340
6341 chunk_reset(t2);
6342 /* should never fail here because we dump only a key in the t2 buffer */
Willy Tarreauf5f26e82016-12-16 18:47:27 +01006343 t2->len = a2base64((char *)(ref->tlskeys + (head + 2 + appctx->ctx.cli.i1) % TLS_TICKETS_NO),
William Lallemand32af2032016-10-29 18:09:35 +02006344 sizeof(struct tls_sess_key), t2->str, t2->size);
Willy Tarreauf5f26e82016-12-16 18:47:27 +01006345 chunk_appendf(&trash, "%d.%d %s\n", ref->unique_id, appctx->ctx.cli.i1, t2->str);
William Lallemand32af2032016-10-29 18:09:35 +02006346
6347 if (bi_putchk(si_ic(si), &trash) == -1) {
6348 /* let's try again later from this stream. We add ourselves into
6349 * this stream's users so that it can remove us upon termination.
6350 */
6351 si_applet_cant_put(si);
6352 return 0;
6353 }
Willy Tarreauf5f26e82016-12-16 18:47:27 +01006354 appctx->ctx.cli.i1++;
William Lallemand32af2032016-10-29 18:09:35 +02006355 }
Willy Tarreauf5f26e82016-12-16 18:47:27 +01006356 appctx->ctx.cli.i1 = 0;
William Lallemand32af2032016-10-29 18:09:35 +02006357 }
6358 if (bi_putchk(si_ic(si), &trash) == -1) {
6359 /* let's try again later from this stream. We add ourselves into
6360 * this stream's users so that it can remove us upon termination.
6361 */
6362 si_applet_cant_put(si);
6363 return 0;
6364 }
6365
Willy Tarreauf5f26e82016-12-16 18:47:27 +01006366 if (appctx->ctx.cli.i0 == 0) /* don't display everything if not necessary */
William Lallemand32af2032016-10-29 18:09:35 +02006367 break;
6368
6369 /* get next list entry and check the end of the list */
Willy Tarreauf5f26e82016-12-16 18:47:27 +01006370 appctx->ctx.cli.p0 = tlskeys_list_get_next(appctx->ctx.cli.p0, &tlskeys_reference);
William Lallemand32af2032016-10-29 18:09:35 +02006371 }
6372
6373 appctx->st2 = STAT_ST_FIN;
6374 /* fall through */
6375
6376 default:
6377 appctx->st2 = STAT_ST_FIN;
6378 return 1;
6379 }
6380 return 0;
6381}
6382
6383#endif
6384
Willy Tarreauf5f26e82016-12-16 18:47:27 +01006385/* sets cli.i0 to non-zero if only file lists should be dumped */
William Lallemand32af2032016-10-29 18:09:35 +02006386static int cli_parse_show_tlskeys(char **args, struct appctx *appctx, void *private)
6387{
William Lallemand32af2032016-10-29 18:09:35 +02006388 /* no parameter, shows only file list */
6389 if (!*args[2]) {
Willy Tarreauf5f26e82016-12-16 18:47:27 +01006390 appctx->ctx.cli.i0 = 1;
William Lallemand32af2032016-10-29 18:09:35 +02006391 appctx->io_handler = cli_io_handler_tlskeys_files;
Willy Tarreau3067bfa2016-12-05 14:50:15 +01006392 return 0;
William Lallemand32af2032016-10-29 18:09:35 +02006393 }
6394
6395 if (args[2][0] == '*') {
6396 /* list every TLS ticket keys */
Willy Tarreauf5f26e82016-12-16 18:47:27 +01006397 appctx->ctx.cli.i0 = 1;
William Lallemand32af2032016-10-29 18:09:35 +02006398 } else {
Willy Tarreauf5f26e82016-12-16 18:47:27 +01006399 appctx->ctx.cli.p0 = tlskeys_ref_lookup_ref(args[2]);
6400 if (!appctx->ctx.cli.p0) {
William Lallemand32af2032016-10-29 18:09:35 +02006401 appctx->ctx.cli.msg = "'show tls-keys' unable to locate referenced filename\n";
Willy Tarreau3b6e5472016-11-24 15:53:53 +01006402 appctx->st0 = CLI_ST_PRINT;
William Lallemand32af2032016-10-29 18:09:35 +02006403 return 1;
6404 }
6405 }
William Lallemand32af2032016-10-29 18:09:35 +02006406 appctx->io_handler = cli_io_handler_tlskeys_entries;
Willy Tarreau3067bfa2016-12-05 14:50:15 +01006407 return 0;
William Lallemand32af2032016-10-29 18:09:35 +02006408}
6409
6410
6411static int cli_parse_set_tlskeys(char **args, struct appctx *appctx, void *private)
6412{
Willy Tarreauf5f26e82016-12-16 18:47:27 +01006413 struct tls_keys_ref *ref;
6414
William Lallemand32af2032016-10-29 18:09:35 +02006415 /* Expect two parameters: the filename and the new new TLS key in encoding */
6416 if (!*args[3] || !*args[4]) {
6417 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 +01006418 appctx->st0 = CLI_ST_PRINT;
William Lallemand32af2032016-10-29 18:09:35 +02006419 return 1;
6420 }
6421
Willy Tarreauf5f26e82016-12-16 18:47:27 +01006422 ref = tlskeys_ref_lookup_ref(args[3]);
6423 if (!ref) {
William Lallemand32af2032016-10-29 18:09:35 +02006424 appctx->ctx.cli.msg = "'set ssl tls-key' unable to locate referenced filename\n";
Willy Tarreau3b6e5472016-11-24 15:53:53 +01006425 appctx->st0 = CLI_ST_PRINT;
William Lallemand32af2032016-10-29 18:09:35 +02006426 return 1;
6427 }
6428
6429 trash.len = base64dec(args[4], strlen(args[4]), trash.str, trash.size);
6430 if (trash.len != sizeof(struct tls_sess_key)) {
6431 appctx->ctx.cli.msg = "'set ssl tls-key' received invalid base64 encoded TLS key.\n";
Willy Tarreau3b6e5472016-11-24 15:53:53 +01006432 appctx->st0 = CLI_ST_PRINT;
William Lallemand32af2032016-10-29 18:09:35 +02006433 return 1;
6434 }
6435
Willy Tarreauf5f26e82016-12-16 18:47:27 +01006436 memcpy(ref->tlskeys + ((ref->tls_ticket_enc_index + 2) % TLS_TICKETS_NO), trash.str, trash.len);
6437 ref->tls_ticket_enc_index = (ref->tls_ticket_enc_index + 1) % TLS_TICKETS_NO;
William Lallemand32af2032016-10-29 18:09:35 +02006438
6439 appctx->ctx.cli.msg = "TLS ticket key updated!";
Willy Tarreau3b6e5472016-11-24 15:53:53 +01006440 appctx->st0 = CLI_ST_PRINT;
William Lallemand32af2032016-10-29 18:09:35 +02006441 return 1;
6442
6443}
6444
6445static int cli_parse_set_ocspresponse(char **args, struct appctx *appctx, void *private)
6446{
6447#if (defined SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB && !defined OPENSSL_NO_OCSP)
6448 char *err = NULL;
6449
6450 /* Expect one parameter: the new response in base64 encoding */
6451 if (!*args[3]) {
6452 appctx->ctx.cli.msg = "'set ssl ocsp-response' expects response in base64 encoding.\n";
Willy Tarreau3b6e5472016-11-24 15:53:53 +01006453 appctx->st0 = CLI_ST_PRINT;
William Lallemand32af2032016-10-29 18:09:35 +02006454 return 1;
6455 }
6456
6457 trash.len = base64dec(args[3], strlen(args[3]), trash.str, trash.size);
6458 if (trash.len < 0) {
6459 appctx->ctx.cli.msg = "'set ssl ocsp-response' received invalid base64 encoded response.\n";
Willy Tarreau3b6e5472016-11-24 15:53:53 +01006460 appctx->st0 = CLI_ST_PRINT;
William Lallemand32af2032016-10-29 18:09:35 +02006461 return 1;
6462 }
6463
6464 if (ssl_sock_update_ocsp_response(&trash, &err)) {
6465 if (err) {
6466 memprintf(&err, "%s.\n", err);
6467 appctx->ctx.cli.err = err;
Willy Tarreau3b6e5472016-11-24 15:53:53 +01006468 appctx->st0 = CLI_ST_PRINT_FREE;
William Lallemand32af2032016-10-29 18:09:35 +02006469 }
6470 return 1;
6471 }
6472 appctx->ctx.cli.msg = "OCSP Response updated!";
Willy Tarreau3b6e5472016-11-24 15:53:53 +01006473 appctx->st0 = CLI_ST_PRINT;
William Lallemand32af2032016-10-29 18:09:35 +02006474 return 1;
6475#else
6476 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 +01006477 appctx->st0 = CLI_ST_PRINT;
William Lallemand32af2032016-10-29 18:09:35 +02006478 return 1;
6479#endif
6480
6481}
6482
6483/* register cli keywords */
6484static struct cli_kw_list cli_kws = {{ },{
6485#if (defined SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB && TLS_TICKETS_NO > 0)
6486 { { "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 },
6487 { { "set", "ssl", "tls-keys", NULL }, NULL, cli_parse_set_tlskeys, NULL },
6488 { { "set", "ssl", "ocsp-response", NULL }, NULL, cli_parse_set_ocspresponse, NULL },
6489#endif
6490 { { NULL }, NULL, NULL, NULL }
6491}};
6492
6493
6494
Willy Tarreau7875d092012-09-10 08:20:03 +02006495/* Note: must not be declared <const> as its list will be overwritten.
6496 * Please take care of keeping this list alphabetically sorted.
6497 */
Willy Tarreaudc13c112013-06-21 23:16:39 +02006498static struct sample_fetch_kw_list sample_fetch_keywords = {ILH, {
Emeric Brun645ae792014-04-30 14:21:06 +02006499 { "ssl_bc", smp_fetch_ssl_fc, 0, NULL, SMP_T_BOOL, SMP_USE_L5SRV },
Thierry FOURNIER07ee64e2015-07-06 23:43:03 +02006500 { "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 +02006501 { "ssl_bc_cipher", smp_fetch_ssl_fc_cipher, 0, NULL, SMP_T_STR, SMP_USE_L5SRV },
6502 { "ssl_bc_protocol", smp_fetch_ssl_fc_protocol, 0, NULL, SMP_T_STR, SMP_USE_L5SRV },
Emeric Brunb73a9b02014-04-30 18:49:19 +02006503 { "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 +02006504 { "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 +02006505 { "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 +02006506 { "ssl_c_ca_err", smp_fetch_ssl_c_ca_err, 0, NULL, SMP_T_SINT, SMP_USE_L5CLI },
6507 { "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 +01006508 { "ssl_c_der", smp_fetch_ssl_x_der, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Thierry FOURNIER07ee64e2015-07-06 23:43:03 +02006509 { "ssl_c_err", smp_fetch_ssl_c_err, 0, NULL, SMP_T_SINT, SMP_USE_L5CLI },
Emeric Brunba841a12014-04-30 17:05:08 +02006510 { "ssl_c_i_dn", smp_fetch_ssl_x_i_dn, ARG2(0,STR,SINT), NULL, SMP_T_STR, SMP_USE_L5CLI },
6511 { "ssl_c_key_alg", smp_fetch_ssl_x_key_alg, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
6512 { "ssl_c_notafter", smp_fetch_ssl_x_notafter, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
6513 { "ssl_c_notbefore", smp_fetch_ssl_x_notbefore, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
6514 { "ssl_c_sig_alg", smp_fetch_ssl_x_sig_alg, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
6515 { "ssl_c_s_dn", smp_fetch_ssl_x_s_dn, ARG2(0,STR,SINT), NULL, SMP_T_STR, SMP_USE_L5CLI },
6516 { "ssl_c_serial", smp_fetch_ssl_x_serial, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
6517 { "ssl_c_sha1", smp_fetch_ssl_x_sha1, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Willy Tarreau80aca902013-01-07 15:42:20 +01006518 { "ssl_c_used", smp_fetch_ssl_c_used, 0, NULL, SMP_T_BOOL, SMP_USE_L5CLI },
Thierry FOURNIER07ee64e2015-07-06 23:43:03 +02006519 { "ssl_c_verify", smp_fetch_ssl_c_verify, 0, NULL, SMP_T_SINT, SMP_USE_L5CLI },
6520 { "ssl_c_version", smp_fetch_ssl_x_version, 0, NULL, SMP_T_SINT, SMP_USE_L5CLI },
Emeric Brun43e79582014-10-29 19:03:26 +01006521 { "ssl_f_der", smp_fetch_ssl_x_der, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Emeric Brunba841a12014-04-30 17:05:08 +02006522 { "ssl_f_i_dn", smp_fetch_ssl_x_i_dn, ARG2(0,STR,SINT), NULL, SMP_T_STR, SMP_USE_L5CLI },
6523 { "ssl_f_key_alg", smp_fetch_ssl_x_key_alg, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
6524 { "ssl_f_notafter", smp_fetch_ssl_x_notafter, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
6525 { "ssl_f_notbefore", smp_fetch_ssl_x_notbefore, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
6526 { "ssl_f_sig_alg", smp_fetch_ssl_x_sig_alg, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
6527 { "ssl_f_s_dn", smp_fetch_ssl_x_s_dn, ARG2(0,STR,SINT), NULL, SMP_T_STR, SMP_USE_L5CLI },
6528 { "ssl_f_serial", smp_fetch_ssl_x_serial, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Emeric Brun55f4fa82014-04-30 17:11:25 +02006529 { "ssl_f_sha1", smp_fetch_ssl_x_sha1, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Thierry FOURNIER07ee64e2015-07-06 23:43:03 +02006530 { "ssl_f_version", smp_fetch_ssl_x_version, 0, NULL, SMP_T_SINT, SMP_USE_L5CLI },
Willy Tarreau80aca902013-01-07 15:42:20 +01006531 { "ssl_fc", smp_fetch_ssl_fc, 0, NULL, SMP_T_BOOL, SMP_USE_L5CLI },
Thierry FOURNIER07ee64e2015-07-06 23:43:03 +02006532 { "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 +01006533 { "ssl_fc_cipher", smp_fetch_ssl_fc_cipher, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Willy Tarreau80aca902013-01-07 15:42:20 +01006534 { "ssl_fc_has_crt", smp_fetch_ssl_fc_has_crt, 0, NULL, SMP_T_BOOL, SMP_USE_L5CLI },
6535 { "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 +02006536 { "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 +02006537#ifdef OPENSSL_NPN_NEGOTIATED
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01006538 { "ssl_fc_npn", smp_fetch_ssl_fc_npn, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Willy Tarreaua33c6542012-10-15 13:19:06 +02006539#endif
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01006540#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01006541 { "ssl_fc_alpn", smp_fetch_ssl_fc_alpn, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Willy Tarreauab861d32013-04-02 02:30:41 +02006542#endif
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01006543 { "ssl_fc_protocol", smp_fetch_ssl_fc_protocol, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Emeric Brunb73a9b02014-04-30 18:49:19 +02006544 { "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 +02006545 { "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 +01006546 { "ssl_fc_session_id", smp_fetch_ssl_fc_session_id, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
6547 { "ssl_fc_sni", smp_fetch_ssl_fc_sni, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Willy Tarreau7875d092012-09-10 08:20:03 +02006548 { NULL, NULL, 0, 0, 0 },
6549}};
6550
6551/* Note: must not be declared <const> as its list will be overwritten.
6552 * Please take care of keeping this list alphabetically sorted.
6553 */
Willy Tarreaudc13c112013-06-21 23:16:39 +02006554static struct acl_kw_list acl_kws = {ILH, {
Thierry FOURNIERc5a4e982014-03-05 16:07:08 +01006555 { "ssl_fc_sni_end", "ssl_fc_sni", PAT_MATCH_END },
6556 { "ssl_fc_sni_reg", "ssl_fc_sni", PAT_MATCH_REG },
Willy Tarreau8ed669b2013-01-11 15:49:37 +01006557 { /* END */ },
Willy Tarreau7875d092012-09-10 08:20:03 +02006558}};
6559
Willy Tarreau79eeafa2012-09-14 07:53:05 +02006560/* Note: must not be declared <const> as its list will be overwritten.
6561 * Please take care of keeping this list alphabetically sorted, doing so helps
6562 * all code contributors.
6563 * Optional keywords are also declared with a NULL ->parse() function so that
6564 * the config parser can report an appropriate error when a known keyword was
6565 * not enabled.
6566 */
Willy Tarreau51fb7652012-09-18 18:24:39 +02006567static struct bind_kw_list bind_kws = { "SSL", { }, {
Nenad Merdanovic05552d42015-02-27 19:56:49 +01006568 { "alpn", bind_parse_alpn, 1 }, /* set ALPN supported protocols */
6569 { "ca-file", bind_parse_ca_file, 1 }, /* set CAfile to process verify on client cert */
6570 { "ca-ignore-err", bind_parse_ignore_err, 1 }, /* set error IDs to ignore on verify depth > 0 */
Christopher Faulet31af49d2015-06-09 17:29:50 +02006571 { "ca-sign-file", bind_parse_ca_sign_file, 1 }, /* set CAFile used to generate and sign server certs */
6572 { "ca-sign-pass", bind_parse_ca_sign_pass, 1 }, /* set CAKey passphrase */
Nenad Merdanovic05552d42015-02-27 19:56:49 +01006573 { "ciphers", bind_parse_ciphers, 1 }, /* set SSL cipher suite */
6574 { "crl-file", bind_parse_crl_file, 1 }, /* set certificat revocation list file use on client cert verify */
6575 { "crt", bind_parse_crt, 1 }, /* load SSL certificates from this location */
6576 { "crt-ignore-err", bind_parse_ignore_err, 1 }, /* set error IDs to ingore on verify depth == 0 */
6577 { "crt-list", bind_parse_crt_list, 1 }, /* load a list of crt from this location */
6578 { "ecdhe", bind_parse_ecdhe, 1 }, /* defines named curve for elliptic curve Diffie-Hellman */
6579 { "force-sslv3", bind_parse_force_sslv3, 0 }, /* force SSLv3 */
6580 { "force-tlsv10", bind_parse_force_tlsv10, 0 }, /* force TLSv10 */
6581 { "force-tlsv11", bind_parse_force_tlsv11, 0 }, /* force TLSv11 */
6582 { "force-tlsv12", bind_parse_force_tlsv12, 0 }, /* force TLSv12 */
Christopher Faulet31af49d2015-06-09 17:29:50 +02006583 { "generate-certificates", bind_parse_generate_certs, 0 }, /* enable the server certificates generation */
Nenad Merdanovic05552d42015-02-27 19:56:49 +01006584 { "no-sslv3", bind_parse_no_sslv3, 0 }, /* disable SSLv3 */
6585 { "no-tlsv10", bind_parse_no_tlsv10, 0 }, /* disable TLSv10 */
6586 { "no-tlsv11", bind_parse_no_tlsv11, 0 }, /* disable TLSv11 */
6587 { "no-tlsv12", bind_parse_no_tlsv12, 0 }, /* disable TLSv12 */
6588 { "no-tls-tickets", bind_parse_no_tls_tickets, 0 }, /* disable session resumption tickets */
6589 { "ssl", bind_parse_ssl, 0 }, /* enable SSL processing */
6590 { "strict-sni", bind_parse_strict_sni, 0 }, /* refuse negotiation if sni doesn't match a certificate */
6591 { "tls-ticket-keys", bind_parse_tls_ticket_keys, 1 }, /* set file to load TLS ticket keys from */
6592 { "verify", bind_parse_verify, 1 }, /* set SSL verify method */
6593 { "npn", bind_parse_npn, 1 }, /* set NPN supported protocols */
Willy Tarreau79eeafa2012-09-14 07:53:05 +02006594 { NULL, NULL, 0 },
6595}};
Emeric Brun46591952012-05-18 15:47:34 +02006596
Willy Tarreau92faadf2012-10-10 23:04:25 +02006597/* Note: must not be declared <const> as its list will be overwritten.
6598 * Please take care of keeping this list alphabetically sorted, doing so helps
6599 * all code contributors.
6600 * Optional keywords are also declared with a NULL ->parse() function so that
6601 * the config parser can report an appropriate error when a known keyword was
6602 * not enabled.
6603 */
6604static struct srv_kw_list srv_kws = { "SSL", { }, {
Emeric Brunef42d922012-10-11 16:11:36 +02006605 { "ca-file", srv_parse_ca_file, 1, 0 }, /* set CAfile to process verify server cert */
Emeric Brunecc91fe2012-10-11 15:05:10 +02006606 { "check-ssl", srv_parse_check_ssl, 0, 0 }, /* enable SSL for health checks */
6607 { "ciphers", srv_parse_ciphers, 1, 0 }, /* select the cipher suite */
Emeric Brunef42d922012-10-11 16:11:36 +02006608 { "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 +02006609 { "crt", srv_parse_crt, 1, 0 }, /* set client certificate */
Emeric Brunecc91fe2012-10-11 15:05:10 +02006610 { "force-sslv3", srv_parse_force_sslv3, 0, 0 }, /* force SSLv3 */
6611 { "force-tlsv10", srv_parse_force_tlsv10, 0, 0 }, /* force TLSv10 */
6612 { "force-tlsv11", srv_parse_force_tlsv11, 0, 0 }, /* force TLSv11 */
6613 { "force-tlsv12", srv_parse_force_tlsv12, 0, 0 }, /* force TLSv12 */
Willy Tarreau2a3fb1c2015-02-05 16:47:07 +01006614 { "no-ssl-reuse", srv_parse_no_ssl_reuse, 0, 0 }, /* disable session reuse */
Emeric Brunecc91fe2012-10-11 15:05:10 +02006615 { "no-sslv3", srv_parse_no_sslv3, 0, 0 }, /* disable SSLv3 */
6616 { "no-tlsv10", srv_parse_no_tlsv10, 0, 0 }, /* disable TLSv10 */
6617 { "no-tlsv11", srv_parse_no_tlsv11, 0, 0 }, /* disable TLSv11 */
6618 { "no-tlsv12", srv_parse_no_tlsv12, 0, 0 }, /* disable TLSv12 */
Emeric Brunf9c5c472012-10-11 15:28:34 +02006619 { "no-tls-tickets", srv_parse_no_tls_tickets, 0, 0 }, /* disable session resumption tickets */
David Safb76832014-05-08 23:42:08 -04006620 { "send-proxy-v2-ssl", srv_parse_send_proxy_ssl, 0, 0 }, /* send PROXY protocol header v2 with SSL info */
6621 { "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 +02006622 { "sni", srv_parse_sni, 1, 0 }, /* send SNI extension */
Emeric Brunecc91fe2012-10-11 15:05:10 +02006623 { "ssl", srv_parse_ssl, 0, 0 }, /* enable SSL processing */
Emeric Brunef42d922012-10-11 16:11:36 +02006624 { "verify", srv_parse_verify, 1, 0 }, /* set SSL verify method */
Evan Broderbe554312013-06-27 00:05:25 -07006625 { "verifyhost", srv_parse_verifyhost, 1, 0 }, /* require that SSL cert verifies for hostname */
Willy Tarreau92faadf2012-10-10 23:04:25 +02006626 { NULL, NULL, 0, 0 },
6627}};
6628
Emeric Brun2c86cbf2014-10-30 15:56:50 +01006629static struct cfg_kw_list cfg_kws = {ILH, {
Willy Tarreau8c3b0fd2016-12-21 22:44:46 +01006630 { CFG_GLOBAL, "ca-base", ssl_parse_global_ca_crt_base },
6631 { CFG_GLOBAL, "crt-base", ssl_parse_global_ca_crt_base },
Willy Tarreau0bea58d2016-12-21 23:17:25 +01006632 { CFG_GLOBAL, "maxsslconn", ssl_parse_global_int },
Emeric Brun2c86cbf2014-10-30 15:56:50 +01006633 { CFG_GLOBAL, "ssl-default-bind-options", ssl_parse_default_bind_options },
6634 { CFG_GLOBAL, "ssl-default-server-options", ssl_parse_default_server_options },
Willy Tarreau14e36a12016-12-21 23:28:13 +01006635#ifndef OPENSSL_NO_DH
6636 { CFG_GLOBAL, "ssl-dh-param-file", ssl_parse_global_dh_param_file },
6637#endif
Willy Tarreau9ceda382016-12-21 23:13:03 +01006638 { CFG_GLOBAL, "tune.ssl.cachesize", ssl_parse_global_int },
6639#ifndef OPENSSL_NO_DH
6640 { CFG_GLOBAL, "tune.ssl.default-dh-param", ssl_parse_global_default_dh },
6641#endif
6642 { CFG_GLOBAL, "tune.ssl.force-private-cache", ssl_parse_global_private_cache },
6643 { CFG_GLOBAL, "tune.ssl.lifetime", ssl_parse_global_lifetime },
6644 { CFG_GLOBAL, "tune.ssl.maxrecord", ssl_parse_global_int },
6645 { CFG_GLOBAL, "tune.ssl.ssl-ctx-cache-size", ssl_parse_global_int },
Willy Tarreauf22e9682016-12-21 23:23:19 +01006646 { CFG_GLOBAL, "ssl-default-bind-ciphers", ssl_parse_global_ciphers },
6647 { CFG_GLOBAL, "ssl-default-server-ciphers", ssl_parse_global_ciphers },
Emeric Brun2c86cbf2014-10-30 15:56:50 +01006648 { 0, NULL, NULL },
6649}};
6650
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02006651/* transport-layer operations for SSL sockets */
Willy Tarreaud9f5cca2016-12-22 21:08:52 +01006652static struct xprt_ops ssl_sock = {
Emeric Brun46591952012-05-18 15:47:34 +02006653 .snd_buf = ssl_sock_from_buf,
6654 .rcv_buf = ssl_sock_to_buf,
6655 .rcv_pipe = NULL,
6656 .snd_pipe = NULL,
6657 .shutr = NULL,
6658 .shutw = ssl_sock_shutw,
6659 .close = ssl_sock_close,
6660 .init = ssl_sock_init,
Willy Tarreau55d37912016-12-21 23:38:39 +01006661 .prepare_bind_conf = ssl_sock_prepare_bind_conf,
Willy Tarreau795cdab2016-12-22 17:30:54 +01006662 .destroy_bind_conf = ssl_sock_destroy_bind_conf,
Willy Tarreau8e0bb0a2016-11-24 16:58:12 +01006663 .name = "SSL",
Emeric Brun46591952012-05-18 15:47:34 +02006664};
6665
Daniel Jakots54ffb912015-11-06 20:02:41 +01006666#if (OPENSSL_VERSION_NUMBER >= 0x1000200fL && !defined OPENSSL_NO_TLSEXT && !defined OPENSSL_IS_BORINGSSL && !defined LIBRESSL_VERSION_NUMBER)
Janusz Dziemidowicz2c701b52015-03-07 23:03:59 +01006667
6668static void ssl_sock_sctl_free_func(void *parent, void *ptr, CRYPTO_EX_DATA *ad, int idx, long argl, void *argp)
6669{
6670 if (ptr) {
6671 chunk_destroy(ptr);
6672 free(ptr);
6673 }
6674}
6675
6676#endif
6677
Emeric Brun46591952012-05-18 15:47:34 +02006678__attribute__((constructor))
Willy Tarreau92faadf2012-10-10 23:04:25 +02006679static void __ssl_sock_init(void)
6680{
Willy Tarreauc2c0b612016-12-21 19:23:20 +01006681 char *ptr;
6682
Emeric Brun46591952012-05-18 15:47:34 +02006683 STACK_OF(SSL_COMP)* cm;
6684
Willy Tarreau610f04b2014-02-13 11:36:41 +01006685#ifdef LISTEN_DEFAULT_CIPHERS
6686 global.listen_default_ciphers = LISTEN_DEFAULT_CIPHERS;
6687#endif
6688#ifdef CONNECT_DEFAULT_CIPHERS
6689 global.connect_default_ciphers = CONNECT_DEFAULT_CIPHERS;
6690#endif
6691 if (global.listen_default_ciphers)
6692 global.listen_default_ciphers = strdup(global.listen_default_ciphers);
6693 if (global.connect_default_ciphers)
6694 global.connect_default_ciphers = strdup(global.connect_default_ciphers);
Emeric Brun2c86cbf2014-10-30 15:56:50 +01006695 global.listen_default_ssloptions = BC_SSL_O_NONE;
6696 global.connect_default_ssloptions = SRV_SSL_O_NONE;
Willy Tarreau610f04b2014-02-13 11:36:41 +01006697
Willy Tarreau13e14102016-12-22 20:25:26 +01006698 xprt_register(XPRT_SSL, &ssl_sock);
Emeric Brun46591952012-05-18 15:47:34 +02006699 SSL_library_init();
6700 cm = SSL_COMP_get_compression_methods();
6701 sk_SSL_COMP_zero(cm);
Daniel Jakots54ffb912015-11-06 20:02:41 +01006702#if (OPENSSL_VERSION_NUMBER >= 0x1000200fL && !defined OPENSSL_NO_TLSEXT && !defined OPENSSL_IS_BORINGSSL && !defined LIBRESSL_VERSION_NUMBER)
Janusz Dziemidowicz2c701b52015-03-07 23:03:59 +01006703 sctl_ex_index = SSL_CTX_get_ex_new_index(0, NULL, NULL, NULL, ssl_sock_sctl_free_func);
6704#endif
Willy Tarreau7875d092012-09-10 08:20:03 +02006705 sample_register_fetches(&sample_fetch_keywords);
6706 acl_register_keywords(&acl_kws);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02006707 bind_register_keywords(&bind_kws);
Willy Tarreau92faadf2012-10-10 23:04:25 +02006708 srv_register_keywords(&srv_kws);
Emeric Brun2c86cbf2014-10-30 15:56:50 +01006709 cfg_register_keywords(&cfg_kws);
William Lallemand32af2032016-10-29 18:09:35 +02006710 cli_register_kw(&cli_kws);
Willy Tarreaud92aa5c2015-01-15 21:34:39 +01006711
Willy Tarreauc2c0b612016-12-21 19:23:20 +01006712 ptr = NULL;
6713 memprintf(&ptr, "Built with OpenSSL version : "
6714#ifdef OPENSSL_IS_BORINGSSL
6715 "BoringSSL\n");
6716#else /* OPENSSL_IS_BORINGSSL */
6717 OPENSSL_VERSION_TEXT
6718 "\nRunning on OpenSSL version : %s%s",
6719 SSLeay_version(SSLEAY_VERSION),
6720 ((OPENSSL_VERSION_NUMBER ^ SSLeay()) >> 8) ? " (VERSIONS DIFFER!)" : "");
6721#endif
6722 memprintf(&ptr, "%s\nOpenSSL library supports TLS extensions : "
6723#if OPENSSL_VERSION_NUMBER < 0x00907000L
6724 "no (library version too old)"
6725#elif defined(OPENSSL_NO_TLSEXT)
6726 "no (disabled via OPENSSL_NO_TLSEXT)"
6727#else
6728 "yes"
6729#endif
6730 "", ptr);
6731
6732 memprintf(&ptr, "%s\nOpenSSL library supports SNI : "
6733#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
6734 "yes"
6735#else
6736#ifdef OPENSSL_NO_TLSEXT
6737 "no (because of OPENSSL_NO_TLSEXT)"
6738#else
6739 "no (version might be too old, 0.9.8f min needed)"
6740#endif
6741#endif
6742 "", ptr);
6743
6744 memprintf(&ptr, "%s\nOpenSSL library supports prefer-server-ciphers : "
6745#ifdef SSL_OP_CIPHER_SERVER_PREFERENCE
6746 "yes"
6747#else
6748 "no (0.9.7 or later needed)"
6749#endif
6750 "", ptr);
6751 hap_register_build_opts(ptr, 1);
6752
Willy Tarreaud92aa5c2015-01-15 21:34:39 +01006753 global.ssl_session_max_cost = SSL_SESSION_MAX_COST;
6754 global.ssl_handshake_max_cost = SSL_HANDSHAKE_MAX_COST;
Remi Gacogne4f902b82015-05-28 16:23:00 +02006755
6756#ifndef OPENSSL_NO_DH
6757 ssl_dh_ptr_index = SSL_CTX_get_ex_new_index(0, NULL, NULL, NULL, NULL);
6758#endif
Thierry FOURNIER / OZON.IO8b068c22016-10-10 11:59:50 +02006759
6760 /* Load SSL string for the verbose & debug mode. */
6761 ERR_load_SSL_strings();
Emeric Brun46591952012-05-18 15:47:34 +02006762}
6763
Remi Gacogned3a23c32015-05-28 16:39:47 +02006764__attribute__((destructor))
6765static void __ssl_sock_deinit(void)
6766{
Willy Tarreaua84c2672015-10-09 12:10:13 +02006767#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Christopher Faulet31af49d2015-06-09 17:29:50 +02006768 lru64_destroy(ssl_ctx_lru_tree);
Willy Tarreaua84c2672015-10-09 12:10:13 +02006769#endif
Christopher Faulet31af49d2015-06-09 17:29:50 +02006770
Remi Gacogned3a23c32015-05-28 16:39:47 +02006771#ifndef OPENSSL_NO_DH
6772 if (local_dh_1024) {
6773 DH_free(local_dh_1024);
6774 local_dh_1024 = NULL;
6775 }
6776
6777 if (local_dh_2048) {
6778 DH_free(local_dh_2048);
6779 local_dh_2048 = NULL;
6780 }
6781
6782 if (local_dh_4096) {
6783 DH_free(local_dh_4096);
6784 local_dh_4096 = NULL;
6785 }
6786
Remi Gacogne47783ef2015-05-29 15:53:22 +02006787 if (global_dh) {
6788 DH_free(global_dh);
6789 global_dh = NULL;
6790 }
Remi Gacogned3a23c32015-05-28 16:39:47 +02006791#endif
6792
6793 ERR_remove_state(0);
6794 ERR_free_strings();
6795
6796 EVP_cleanup();
6797
6798#if OPENSSL_VERSION_NUMBER >= 0x00907000L
6799 CRYPTO_cleanup_all_ex_data();
6800#endif
6801}
6802
6803
Emeric Brun46591952012-05-18 15:47:34 +02006804/*
6805 * Local variables:
6806 * c-indent-level: 8
6807 * c-basic-offset: 8
6808 * End:
6809 */