blob: ef03525fc51432f6eeed6c9af24cbc65ce300e11 [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
72#include <types/global.h>
73#include <types/ssl_sock.h>
74
Willy Tarreau7875d092012-09-10 08:20:03 +020075#include <proto/acl.h>
76#include <proto/arg.h>
Emeric Brun46591952012-05-18 15:47:34 +020077#include <proto/connection.h>
78#include <proto/fd.h>
79#include <proto/freq_ctr.h>
80#include <proto/frontend.h>
Willy Tarreau79eeafa2012-09-14 07:53:05 +020081#include <proto/listener.h>
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +020082#include <proto/openssl-compat.h>
Thierry FOURNIERed66c292013-11-28 11:05:19 +010083#include <proto/pattern.h>
Christopher Faulet31af49d2015-06-09 17:29:50 +020084#include <proto/proto_tcp.h>
Willy Tarreau92faadf2012-10-10 23:04:25 +020085#include <proto/server.h>
Emeric Brun46591952012-05-18 15:47:34 +020086#include <proto/log.h>
Emeric Brun94324a42012-10-11 14:00:19 +020087#include <proto/proxy.h>
Emeric Brunfc0421f2012-09-07 17:30:07 +020088#include <proto/shctx.h>
Emeric Brun46591952012-05-18 15:47:34 +020089#include <proto/ssl_sock.h>
Willy Tarreau9ad7bd42015-04-03 19:19:59 +020090#include <proto/stream.h>
Emeric Brun46591952012-05-18 15:47:34 +020091#include <proto/task.h>
92
Willy Tarreau518cedd2014-02-17 15:43:01 +010093/* Warning, these are bits, not integers! */
Emeric Brune64aef12012-09-21 13:15:06 +020094#define SSL_SOCK_ST_FL_VERIFY_DONE 0x00000001
Emeric Brund8b2bb52014-01-28 15:43:53 +010095#define SSL_SOCK_ST_FL_16K_WBFSIZE 0x00000002
Willy Tarreau518cedd2014-02-17 15:43:01 +010096#define SSL_SOCK_SEND_UNLIMITED 0x00000004
Emeric Brun29f037d2014-04-25 19:05:36 +020097#define SSL_SOCK_RECV_HEARTBEAT 0x00000008
98
Emeric Brunf282a812012-09-21 15:27:54 +020099/* bits 0xFFFF0000 are reserved to store verify errors */
100
101/* Verify errors macros */
102#define SSL_SOCK_CA_ERROR_TO_ST(e) (((e > 63) ? 63 : e) << (16))
103#define SSL_SOCK_CAEDEPTH_TO_ST(d) (((d > 15) ? 15 : d) << (6+16))
104#define SSL_SOCK_CRTERROR_TO_ST(e) (((e > 63) ? 63 : e) << (4+6+16))
105
106#define SSL_SOCK_ST_TO_CA_ERROR(s) ((s >> (16)) & 63)
107#define SSL_SOCK_ST_TO_CAEDEPTH(s) ((s >> (6+16)) & 15)
108#define SSL_SOCK_ST_TO_CRTERROR(s) ((s >> (4+6+16)) & 63)
Emeric Brune64aef12012-09-21 13:15:06 +0200109
Nenad Merdanovic05552d42015-02-27 19:56:49 +0100110/* Supported hash function for TLS tickets */
111#ifdef OPENSSL_NO_SHA256
112#define HASH_FUNCT EVP_sha1
113#else
114#define HASH_FUNCT EVP_sha256
115#endif /* OPENSSL_NO_SHA256 */
116
Emeric Brun850efd52014-01-29 12:24:34 +0100117/* server and bind verify method, it uses a global value as default */
118enum {
119 SSL_SOCK_VERIFY_DEFAULT = 0,
120 SSL_SOCK_VERIFY_REQUIRED = 1,
121 SSL_SOCK_VERIFY_OPTIONAL = 2,
122 SSL_SOCK_VERIFY_NONE = 3,
123};
124
Willy Tarreau71b734c2014-01-28 15:19:44 +0100125int sslconns = 0;
126int totalsslconns = 0;
Emeric Brune1f38db2012-09-03 20:36:47 +0200127
Nenad Merdanovic200b0fa2015-05-09 08:46:01 +0200128#if (defined SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB && TLS_TICKETS_NO > 0)
129struct list tlskeys_reference = LIST_HEAD_INIT(tlskeys_reference);
130#endif
131
Remi Gacogne8de54152014-07-15 11:36:40 +0200132#ifndef OPENSSL_NO_DH
Remi Gacogne4f902b82015-05-28 16:23:00 +0200133static int ssl_dh_ptr_index = -1;
Remi Gacogne47783ef2015-05-29 15:53:22 +0200134static DH *global_dh = NULL;
Remi Gacogne8de54152014-07-15 11:36:40 +0200135static DH *local_dh_1024 = NULL;
136static DH *local_dh_2048 = NULL;
137static DH *local_dh_4096 = NULL;
Remi Gacogne8de54152014-07-15 11:36:40 +0200138#endif /* OPENSSL_NO_DH */
139
Willy Tarreauc8ad3be2015-06-17 15:48:26 +0200140#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Christopher Faulet31af49d2015-06-09 17:29:50 +0200141/* X509V3 Extensions that will be added on generated certificates */
142#define X509V3_EXT_SIZE 5
143static char *x509v3_ext_names[X509V3_EXT_SIZE] = {
144 "basicConstraints",
145 "nsComment",
146 "subjectKeyIdentifier",
147 "authorityKeyIdentifier",
148 "keyUsage",
149};
150static char *x509v3_ext_values[X509V3_EXT_SIZE] = {
151 "CA:FALSE",
152 "\"OpenSSL Generated Certificate\"",
153 "hash",
154 "keyid,issuer:always",
155 "nonRepudiation,digitalSignature,keyEncipherment"
156};
157
158/* LRU cache to store generated certificate */
159static struct lru64_head *ssl_ctx_lru_tree = NULL;
160static unsigned int ssl_ctx_lru_seed = 0;
Willy Tarreauc8ad3be2015-06-17 15:48:26 +0200161#endif // SSL_CTRL_SET_TLSEXT_HOSTNAME
162
yanbzhube2774d2015-12-10 15:07:30 -0500163#if OPENSSL_VERSION_NUMBER >= 0x1000200fL
164/* The order here matters for picking a default context,
165 * keep the most common keytype at the bottom of the list
166 */
167const char *SSL_SOCK_KEYTYPE_NAMES[] = {
168 "dsa",
169 "ecdsa",
170 "rsa"
171};
172#define SSL_SOCK_NUM_KEYTYPES 3
Willy Tarreau30da7ad2015-12-14 11:28:33 +0100173#else
174#define SSL_SOCK_NUM_KEYTYPES 1
yanbzhube2774d2015-12-10 15:07:30 -0500175#endif
176
Willy Tarreauc8ad3be2015-06-17 15:48:26 +0200177#if (defined SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB && !defined OPENSSL_NO_OCSP)
yanbzhube2774d2015-12-10 15:07:30 -0500178/*
179 * struct alignment works here such that the key.key is the same as key_data
180 * Do not change the placement of key_data
181 */
Willy Tarreauc8ad3be2015-06-17 15:48:26 +0200182struct certificate_ocsp {
183 struct ebmb_node key;
184 unsigned char key_data[OCSP_MAX_CERTID_ASN1_LENGTH];
185 struct chunk response;
186 long expire;
187};
Christopher Faulet31af49d2015-06-09 17:29:50 +0200188
yanbzhube2774d2015-12-10 15:07:30 -0500189struct ocsp_cbk_arg {
190 int is_single;
191 int single_kt;
192 union {
193 struct certificate_ocsp *s_ocsp;
194 /*
195 * m_ocsp will have multiple entries dependent on key type
196 * Entry 0 - DSA
197 * Entry 1 - ECDSA
198 * Entry 2 - RSA
199 */
200 struct certificate_ocsp *m_ocsp[SSL_SOCK_NUM_KEYTYPES];
201 };
202};
203
Emeric Brun4f3c87a2014-06-20 15:46:13 +0200204/*
Thierry FOURNIER / OZON.IO8b068c22016-10-10 11:59:50 +0200205 * This function gives the detail of the SSL error. It is used only
206 * if the debug mode and the verbose mode are activated. It dump all
207 * the SSL error until the stack was empty.
208 */
209static forceinline void ssl_sock_dump_errors(struct connection *conn)
210{
211 unsigned long ret;
212
213 if (unlikely(global.mode & MODE_DEBUG)) {
214 while(1) {
215 ret = ERR_get_error();
216 if (ret == 0)
217 return;
218 fprintf(stderr, "fd[%04x] OpenSSL error[0x%lx] %s: %s\n",
219 (unsigned short)conn->t.sock.fd, ret,
220 ERR_func_error_string(ret), ERR_reason_error_string(ret));
221 }
222 }
223}
224
225/*
Emeric Brun4f3c87a2014-06-20 15:46:13 +0200226 * This function returns the number of seconds elapsed
227 * since the Epoch, 1970-01-01 00:00:00 +0000 (UTC) and the
228 * date presented un ASN1_GENERALIZEDTIME.
229 *
230 * In parsing error case, it returns -1.
231 */
232static long asn1_generalizedtime_to_epoch(ASN1_GENERALIZEDTIME *d)
233{
234 long epoch;
235 char *p, *end;
236 const unsigned short month_offset[12] = {
237 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334
238 };
239 int year, month;
240
241 if (!d || (d->type != V_ASN1_GENERALIZEDTIME)) return -1;
242
243 p = (char *)d->data;
244 end = p + d->length;
245
246 if (end - p < 4) return -1;
247 year = 1000 * (p[0] - '0') + 100 * (p[1] - '0') + 10 * (p[2] - '0') + p[3] - '0';
248 p += 4;
249 if (end - p < 2) return -1;
250 month = 10 * (p[0] - '0') + p[1] - '0';
251 if (month < 1 || month > 12) return -1;
252 /* Compute the number of seconds since 1 jan 1970 and the beginning of current month
253 We consider leap years and the current month (<marsh or not) */
254 epoch = ( ((year - 1970) * 365)
255 + ((year - (month < 3)) / 4 - (year - (month < 3)) / 100 + (year - (month < 3)) / 400)
256 - ((1970 - 1) / 4 - (1970 - 1) / 100 + (1970 - 1) / 400)
257 + month_offset[month-1]
258 ) * 24 * 60 * 60;
259 p += 2;
260 if (end - p < 2) return -1;
261 /* Add the number of seconds of completed days of current month */
262 epoch += (10 * (p[0] - '0') + p[1] - '0' - 1) * 24 * 60 * 60;
263 p += 2;
264 if (end - p < 2) return -1;
265 /* Add the completed hours of the current day */
266 epoch += (10 * (p[0] - '0') + p[1] - '0') * 60 * 60;
267 p += 2;
268 if (end - p < 2) return -1;
269 /* Add the completed minutes of the current hour */
270 epoch += (10 * (p[0] - '0') + p[1] - '0') * 60;
271 p += 2;
272 if (p == end) return -1;
273 /* Test if there is available seconds */
274 if (p[0] < '0' || p[0] > '9')
275 goto nosec;
276 if (end - p < 2) return -1;
277 /* Add the seconds of the current minute */
278 epoch += 10 * (p[0] - '0') + p[1] - '0';
279 p += 2;
280 if (p == end) return -1;
281 /* Ignore seconds float part if present */
282 if (p[0] == '.') {
283 do {
284 if (++p == end) return -1;
285 } while (p[0] >= '0' && p[0] <= '9');
286 }
287
288nosec:
289 if (p[0] == 'Z') {
290 if (end - p != 1) return -1;
291 return epoch;
292 }
293 else if (p[0] == '+') {
294 if (end - p != 5) return -1;
295 /* Apply timezone offset */
296 return epoch - ((10 * (p[1] - '0') + p[2] - '0') * 60 + (10 * (p[3] - '0') + p[4] - '0')) * 60;
297 }
298 else if (p[0] == '-') {
299 if (end - p != 5) return -1;
300 /* Apply timezone offset */
301 return epoch + ((10 * (p[1] - '0') + p[2] - '0') * 60 + (10 * (p[3] - '0') + p[4] - '0')) * 60;
302 }
303
304 return -1;
305}
306
Emeric Brun1d3865b2014-06-20 15:37:32 +0200307static struct eb_root cert_ocsp_tree = EB_ROOT_UNIQUE;
Emeric Brun4147b2e2014-06-16 18:36:30 +0200308
309/* This function starts to check if the OCSP response (in DER format) contained
310 * in chunk 'ocsp_response' is valid (else exits on error).
311 * If 'cid' is not NULL, it will be compared to the OCSP certificate ID
312 * contained in the OCSP Response and exits on error if no match.
313 * If it's a valid OCSP Response:
314 * If 'ocsp' is not NULL, the chunk is copied in the OCSP response's container
315 * pointed by 'ocsp'.
316 * If 'ocsp' is NULL, the function looks up into the OCSP response's
317 * containers tree (using as index the ASN1 form of the OCSP Certificate ID extracted
318 * from the response) and exits on error if not found. Finally, If an OCSP response is
319 * already present in the container, it will be overwritten.
320 *
321 * Note: OCSP response containing more than one OCSP Single response is not
322 * considered valid.
323 *
324 * Returns 0 on success, 1 in error case.
325 */
326static int ssl_sock_load_ocsp_response(struct chunk *ocsp_response, struct certificate_ocsp *ocsp, OCSP_CERTID *cid, char **err)
327{
328 OCSP_RESPONSE *resp;
329 OCSP_BASICRESP *bs = NULL;
330 OCSP_SINGLERESP *sr;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +0200331 OCSP_CERTID *id;
Emeric Brun4147b2e2014-06-16 18:36:30 +0200332 unsigned char *p = (unsigned char *)ocsp_response->str;
333 int rc , count_sr;
Emeric Brun13a6b482014-06-20 15:44:34 +0200334 ASN1_GENERALIZEDTIME *revtime, *thisupd, *nextupd = NULL;
Emeric Brun4147b2e2014-06-16 18:36:30 +0200335 int reason;
336 int ret = 1;
337
338 resp = d2i_OCSP_RESPONSE(NULL, (const unsigned char **)&p, ocsp_response->len);
339 if (!resp) {
340 memprintf(err, "Unable to parse OCSP response");
341 goto out;
342 }
343
344 rc = OCSP_response_status(resp);
345 if (rc != OCSP_RESPONSE_STATUS_SUCCESSFUL) {
346 memprintf(err, "OCSP response status not successful");
347 goto out;
348 }
349
350 bs = OCSP_response_get1_basic(resp);
351 if (!bs) {
352 memprintf(err, "Failed to get basic response from OCSP Response");
353 goto out;
354 }
355
356 count_sr = OCSP_resp_count(bs);
357 if (count_sr > 1) {
358 memprintf(err, "OCSP response ignored because contains multiple single responses (%d)", count_sr);
359 goto out;
360 }
361
362 sr = OCSP_resp_get0(bs, 0);
363 if (!sr) {
364 memprintf(err, "Failed to get OCSP single response");
365 goto out;
366 }
367
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +0200368 id = (OCSP_CERTID*)OCSP_SINGLERESP_get0_id(sr);
369
Emeric Brun4147b2e2014-06-16 18:36:30 +0200370 rc = OCSP_single_get0_status(sr, &reason, &revtime, &thisupd, &nextupd);
371 if (rc != V_OCSP_CERTSTATUS_GOOD) {
372 memprintf(err, "OCSP single response: certificate status not good");
373 goto out;
374 }
375
Emeric Brun13a6b482014-06-20 15:44:34 +0200376 if (!nextupd) {
377 memprintf(err, "OCSP single response: missing nextupdate");
378 goto out;
379 }
380
Emeric Brunc8b27b62014-06-19 14:16:17 +0200381 rc = OCSP_check_validity(thisupd, nextupd, OCSP_MAX_RESPONSE_TIME_SKEW, -1);
Emeric Brun4147b2e2014-06-16 18:36:30 +0200382 if (!rc) {
383 memprintf(err, "OCSP single response: no longer valid.");
384 goto out;
385 }
386
387 if (cid) {
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +0200388 if (OCSP_id_cmp(id, cid)) {
Emeric Brun4147b2e2014-06-16 18:36:30 +0200389 memprintf(err, "OCSP single response: Certificate ID does not match certificate and issuer");
390 goto out;
391 }
392 }
393
394 if (!ocsp) {
395 unsigned char key[OCSP_MAX_CERTID_ASN1_LENGTH];
396 unsigned char *p;
397
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +0200398 rc = i2d_OCSP_CERTID(id, NULL);
Emeric Brun4147b2e2014-06-16 18:36:30 +0200399 if (!rc) {
400 memprintf(err, "OCSP single response: Unable to encode Certificate ID");
401 goto out;
402 }
403
404 if (rc > OCSP_MAX_CERTID_ASN1_LENGTH) {
405 memprintf(err, "OCSP single response: Certificate ID too long");
406 goto out;
407 }
408
409 p = key;
410 memset(key, 0, OCSP_MAX_CERTID_ASN1_LENGTH);
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +0200411 i2d_OCSP_CERTID(id, &p);
Emeric Brun4147b2e2014-06-16 18:36:30 +0200412 ocsp = (struct certificate_ocsp *)ebmb_lookup(&cert_ocsp_tree, key, OCSP_MAX_CERTID_ASN1_LENGTH);
413 if (!ocsp) {
414 memprintf(err, "OCSP single response: Certificate ID does not match any certificate or issuer");
415 goto out;
416 }
417 }
418
419 /* According to comments on "chunk_dup", the
420 previous chunk buffer will be freed */
421 if (!chunk_dup(&ocsp->response, ocsp_response)) {
422 memprintf(err, "OCSP response: Memory allocation error");
423 goto out;
424 }
425
Emeric Brun4f3c87a2014-06-20 15:46:13 +0200426 ocsp->expire = asn1_generalizedtime_to_epoch(nextupd) - OCSP_MAX_RESPONSE_TIME_SKEW;
427
Emeric Brun4147b2e2014-06-16 18:36:30 +0200428 ret = 0;
429out:
430 if (bs)
431 OCSP_BASICRESP_free(bs);
432
433 if (resp)
434 OCSP_RESPONSE_free(resp);
435
436 return ret;
437}
438/*
439 * External function use to update the OCSP response in the OCSP response's
440 * containers tree. The chunk 'ocsp_response' must contain the OCSP response
441 * to update in DER format.
442 *
443 * Returns 0 on success, 1 in error case.
444 */
445int ssl_sock_update_ocsp_response(struct chunk *ocsp_response, char **err)
446{
447 return ssl_sock_load_ocsp_response(ocsp_response, NULL, NULL, err);
448}
449
450/*
451 * This function load the OCSP Resonse in DER format contained in file at
452 * path 'ocsp_path' and call 'ssl_sock_load_ocsp_response'
453 *
454 * Returns 0 on success, 1 in error case.
455 */
456static int ssl_sock_load_ocsp_response_from_file(const char *ocsp_path, struct certificate_ocsp *ocsp, OCSP_CERTID *cid, char **err)
457{
458 int fd = -1;
459 int r = 0;
460 int ret = 1;
461
462 fd = open(ocsp_path, O_RDONLY);
463 if (fd == -1) {
464 memprintf(err, "Error opening OCSP response file");
465 goto end;
466 }
467
468 trash.len = 0;
469 while (trash.len < trash.size) {
470 r = read(fd, trash.str + trash.len, trash.size - trash.len);
471 if (r < 0) {
472 if (errno == EINTR)
473 continue;
474
475 memprintf(err, "Error reading OCSP response from file");
476 goto end;
477 }
478 else if (r == 0) {
479 break;
480 }
481 trash.len += r;
482 }
483
484 close(fd);
485 fd = -1;
486
487 ret = ssl_sock_load_ocsp_response(&trash, ocsp, cid, err);
488end:
489 if (fd != -1)
490 close(fd);
491
492 return ret;
493}
494
Nenad Merdanovic05552d42015-02-27 19:56:49 +0100495#if (defined SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB && TLS_TICKETS_NO > 0)
496static 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)
497{
498 struct tls_sess_key *keys;
499 struct connection *conn;
500 int head;
501 int i;
502
Vincent Bernat3c2f2f22016-04-03 13:48:42 +0200503 conn = SSL_get_app_data(s);
Nenad Merdanovic146defa2015-05-09 08:46:00 +0200504 keys = objt_listener(conn->target)->bind_conf->keys_ref->tlskeys;
505 head = objt_listener(conn->target)->bind_conf->keys_ref->tls_ticket_enc_index;
Nenad Merdanovic05552d42015-02-27 19:56:49 +0100506
507 if (enc) {
508 memcpy(key_name, keys[head].name, 16);
509
510 if(!RAND_pseudo_bytes(iv, EVP_MAX_IV_LENGTH))
511 return -1;
512
513 if(!EVP_EncryptInit_ex(ectx, EVP_aes_128_cbc(), NULL, keys[head].aes_key, iv))
514 return -1;
515
516 HMAC_Init_ex(hctx, keys[head].hmac_key, 16, HASH_FUNCT(), NULL);
517
518 return 1;
519 } else {
520 for (i = 0; i < TLS_TICKETS_NO; i++) {
521 if (!memcmp(key_name, keys[(head + i) % TLS_TICKETS_NO].name, 16))
522 goto found;
523 }
524 return 0;
525
526 found:
527 HMAC_Init_ex(hctx, keys[(head + i) % TLS_TICKETS_NO].hmac_key, 16, HASH_FUNCT(), NULL);
528 if(!EVP_DecryptInit_ex(ectx, EVP_aes_128_cbc(), NULL, keys[(head + i) % TLS_TICKETS_NO].aes_key, iv))
529 return -1;
530 /* 2 for key renewal, 1 if current key is still valid */
531 return i ? 2 : 1;
532 }
Nenad Merdanovic200b0fa2015-05-09 08:46:01 +0200533}
534
535struct tls_keys_ref *tlskeys_ref_lookup(const char *filename)
536{
537 struct tls_keys_ref *ref;
538
539 list_for_each_entry(ref, &tlskeys_reference, list)
540 if (ref->filename && strcmp(filename, ref->filename) == 0)
541 return ref;
542 return NULL;
543}
544
545struct tls_keys_ref *tlskeys_ref_lookupid(int unique_id)
546{
547 struct tls_keys_ref *ref;
548
549 list_for_each_entry(ref, &tlskeys_reference, list)
550 if (ref->unique_id == unique_id)
551 return ref;
552 return NULL;
553}
554
555int ssl_sock_update_tlskey(char *filename, struct chunk *tlskey, char **err) {
556 struct tls_keys_ref *ref = tlskeys_ref_lookup(filename);
557
558 if(!ref) {
559 memprintf(err, "Unable to locate the referenced filename: %s", filename);
560 return 1;
561 }
562
Pradeep Jindalcc79b002015-08-20 18:25:17 +0530563 memcpy((char *) (ref->tlskeys + ((ref->tls_ticket_enc_index + 2) % TLS_TICKETS_NO)), tlskey->str, tlskey->len);
564 ref->tls_ticket_enc_index = (ref->tls_ticket_enc_index + 1) % TLS_TICKETS_NO;
Nenad Merdanovic200b0fa2015-05-09 08:46:01 +0200565
566 return 0;
Nenad Merdanovic05552d42015-02-27 19:56:49 +0100567}
Nenad Merdanovic200b0fa2015-05-09 08:46:01 +0200568
569/* This function finalize the configuration parsing. Its set all the
570 * automatic ids
571 */
572void tlskeys_finalize_config(void)
573{
574 int i = 0;
575 struct tls_keys_ref *ref, *ref2, *ref3;
576 struct list tkr = LIST_HEAD_INIT(tkr);
577
578 list_for_each_entry(ref, &tlskeys_reference, list) {
579 if (ref->unique_id == -1) {
580 /* Look for the first free id. */
581 while (1) {
582 list_for_each_entry(ref2, &tlskeys_reference, list) {
583 if (ref2->unique_id == i) {
584 i++;
585 break;
586 }
587 }
588 if (&ref2->list == &tlskeys_reference)
589 break;
590 }
591
592 /* Uses the unique id and increment it for the next entry. */
593 ref->unique_id = i;
594 i++;
595 }
596 }
597
598 /* This sort the reference list by id. */
599 list_for_each_entry_safe(ref, ref2, &tlskeys_reference, list) {
600 LIST_DEL(&ref->list);
601 list_for_each_entry(ref3, &tkr, list) {
602 if (ref->unique_id < ref3->unique_id) {
603 LIST_ADDQ(&ref3->list, &ref->list);
604 break;
605 }
606 }
607 if (&ref3->list == &tkr)
608 LIST_ADDQ(&tkr, &ref->list);
609 }
610
611 /* swap root */
612 LIST_ADD(&tkr, &tlskeys_reference);
613 LIST_DEL(&tkr);
614}
615
Nenad Merdanovic05552d42015-02-27 19:56:49 +0100616#endif /* SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB */
617
yanbzhube2774d2015-12-10 15:07:30 -0500618int ssl_sock_get_ocsp_arg_kt_index(int evp_keytype)
619{
620 switch (evp_keytype) {
621 case EVP_PKEY_RSA:
622 return 2;
623 case EVP_PKEY_DSA:
624 return 0;
625 case EVP_PKEY_EC:
626 return 1;
627 }
628
629 return -1;
630}
631
Emeric Brun4147b2e2014-06-16 18:36:30 +0200632/*
633 * Callback used to set OCSP status extension content in server hello.
634 */
635int ssl_sock_ocsp_stapling_cbk(SSL *ssl, void *arg)
636{
yanbzhube2774d2015-12-10 15:07:30 -0500637 struct certificate_ocsp *ocsp;
638 struct ocsp_cbk_arg *ocsp_arg;
639 char *ssl_buf;
640 EVP_PKEY *ssl_pkey;
641 int key_type;
642 int index;
643
Vincent Bernat3c2f2f22016-04-03 13:48:42 +0200644 ocsp_arg = arg;
yanbzhube2774d2015-12-10 15:07:30 -0500645
646 ssl_pkey = SSL_get_privatekey(ssl);
647 if (!ssl_pkey)
648 return SSL_TLSEXT_ERR_NOACK;
649
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +0200650 key_type = EVP_PKEY_base_id(ssl_pkey);
yanbzhube2774d2015-12-10 15:07:30 -0500651
652 if (ocsp_arg->is_single && ocsp_arg->single_kt == key_type)
653 ocsp = ocsp_arg->s_ocsp;
654 else {
655 /* For multiple certs per context, we have to find the correct OCSP response based on
656 * the certificate type
657 */
658 index = ssl_sock_get_ocsp_arg_kt_index(key_type);
659
660 if (index < 0)
661 return SSL_TLSEXT_ERR_NOACK;
662
663 ocsp = ocsp_arg->m_ocsp[index];
664
665 }
Emeric Brun4147b2e2014-06-16 18:36:30 +0200666
667 if (!ocsp ||
668 !ocsp->response.str ||
Emeric Brun4f3c87a2014-06-20 15:46:13 +0200669 !ocsp->response.len ||
670 (ocsp->expire < now.tv_sec))
Emeric Brun4147b2e2014-06-16 18:36:30 +0200671 return SSL_TLSEXT_ERR_NOACK;
672
673 ssl_buf = OPENSSL_malloc(ocsp->response.len);
674 if (!ssl_buf)
675 return SSL_TLSEXT_ERR_NOACK;
676
677 memcpy(ssl_buf, ocsp->response.str, ocsp->response.len);
678 SSL_set_tlsext_status_ocsp_resp(ssl, ssl_buf, ocsp->response.len);
679
680 return SSL_TLSEXT_ERR_OK;
681}
682
683/*
684 * This function enables the handling of OCSP status extension on 'ctx' if a
685 * file name 'cert_path' suffixed using ".ocsp" is present.
686 * To enable OCSP status extension, the issuer's certificate is mandatory.
687 * It should be present in the certificate's extra chain builded from file
688 * 'cert_path'. If not found, the issuer certificate is loaded from a file
689 * named 'cert_path' suffixed using '.issuer'.
690 *
691 * In addition, ".ocsp" file content is loaded as a DER format of an OCSP
692 * response. If file is empty or content is not a valid OCSP response,
693 * OCSP status extension is enabled but OCSP response is ignored (a warning
694 * is displayed).
695 *
696 * Returns 1 if no ".ocsp" file found, 0 if OCSP status extension is
697 * succesfully enabled, or -1 in other error case.
698 */
699static int ssl_sock_load_ocsp(SSL_CTX *ctx, const char *cert_path)
700{
701
702 BIO *in = NULL;
703 X509 *x, *xi = NULL, *issuer = NULL;
704 STACK_OF(X509) *chain = NULL;
705 OCSP_CERTID *cid = NULL;
706 SSL *ssl;
707 char ocsp_path[MAXPATHLEN+1];
708 int i, ret = -1;
709 struct stat st;
710 struct certificate_ocsp *ocsp = NULL, *iocsp;
711 char *warn = NULL;
712 unsigned char *p;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +0200713 pem_password_cb *passwd_cb;
714 void *passwd_cb_userdata;
715 void (*callback) (void);
Emeric Brun4147b2e2014-06-16 18:36:30 +0200716
717 snprintf(ocsp_path, MAXPATHLEN+1, "%s.ocsp", cert_path);
718
719 if (stat(ocsp_path, &st))
720 return 1;
721
722 ssl = SSL_new(ctx);
723 if (!ssl)
724 goto out;
725
726 x = SSL_get_certificate(ssl);
727 if (!x)
728 goto out;
729
730 /* Try to lookup for issuer in certificate extra chain */
731#ifdef SSL_CTRL_GET_EXTRA_CHAIN_CERTS
732 SSL_CTX_get_extra_chain_certs(ctx, &chain);
733#else
734 chain = ctx->extra_certs;
735#endif
736 for (i = 0; i < sk_X509_num(chain); i++) {
737 issuer = sk_X509_value(chain, i);
738 if (X509_check_issued(issuer, x) == X509_V_OK)
739 break;
740 else
741 issuer = NULL;
742 }
743
744 /* If not found try to load issuer from a suffixed file */
745 if (!issuer) {
746 char issuer_path[MAXPATHLEN+1];
747
748 in = BIO_new(BIO_s_file());
749 if (!in)
750 goto out;
751
752 snprintf(issuer_path, MAXPATHLEN+1, "%s.issuer", cert_path);
753 if (BIO_read_filename(in, issuer_path) <= 0)
754 goto out;
755
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +0200756 passwd_cb = SSL_CTX_get_default_passwd_cb(ctx);
757 passwd_cb_userdata = SSL_CTX_get_default_passwd_cb_userdata(ctx);
758
759 xi = PEM_read_bio_X509_AUX(in, NULL, passwd_cb, passwd_cb_userdata);
Emeric Brun4147b2e2014-06-16 18:36:30 +0200760 if (!xi)
761 goto out;
762
763 if (X509_check_issued(xi, x) != X509_V_OK)
764 goto out;
765
766 issuer = xi;
767 }
768
769 cid = OCSP_cert_to_id(0, x, issuer);
770 if (!cid)
771 goto out;
772
773 i = i2d_OCSP_CERTID(cid, NULL);
774 if (!i || (i > OCSP_MAX_CERTID_ASN1_LENGTH))
775 goto out;
776
Vincent Bernat02779b62016-04-03 13:48:43 +0200777 ocsp = calloc(1, sizeof(*ocsp));
Emeric Brun4147b2e2014-06-16 18:36:30 +0200778 if (!ocsp)
779 goto out;
780
781 p = ocsp->key_data;
782 i2d_OCSP_CERTID(cid, &p);
783
784 iocsp = (struct certificate_ocsp *)ebmb_insert(&cert_ocsp_tree, &ocsp->key, OCSP_MAX_CERTID_ASN1_LENGTH);
785 if (iocsp == ocsp)
786 ocsp = NULL;
787
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +0200788#ifndef SSL_CTX_get_tlsext_status_cb
789# define SSL_CTX_get_tlsext_status_cb(ctx, cb) \
790 *cb = (void (*) (void))ctx->tlsext_status_cb;
791#endif
792 SSL_CTX_get_tlsext_status_cb(ctx, &callback);
793
794 if (!callback) {
Vincent Bernat02779b62016-04-03 13:48:43 +0200795 struct ocsp_cbk_arg *cb_arg = calloc(1, sizeof(*cb_arg));
yanbzhube2774d2015-12-10 15:07:30 -0500796
797 cb_arg->is_single = 1;
798 cb_arg->s_ocsp = iocsp;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +0200799
800 cb_arg->single_kt = EVP_PKEY_base_id(X509_get_pubkey(x));
yanbzhube2774d2015-12-10 15:07:30 -0500801
802 SSL_CTX_set_tlsext_status_cb(ctx, ssl_sock_ocsp_stapling_cbk);
803 SSL_CTX_set_tlsext_status_arg(ctx, cb_arg);
804 } else {
805 /*
806 * If the ctx has a status CB, then we have previously set an OCSP staple for this ctx
807 * Update that cb_arg with the new cert's staple
808 */
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +0200809 struct ocsp_cbk_arg *cb_arg;
yanbzhube2774d2015-12-10 15:07:30 -0500810 struct certificate_ocsp *tmp_ocsp;
811 int index;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +0200812 int key_type;
813
814#ifdef SSL_CTX_get_tlsext_status_arg
815 SSL_CTX_ctrl(ctx, SSL_CTRL_GET_TLSEXT_STATUS_REQ_CB_ARG, 0, &cb_arg);
816#else
817 cb_arg = ctx->tlsext_status_arg;
818#endif
yanbzhube2774d2015-12-10 15:07:30 -0500819
820 /*
821 * The following few lines will convert cb_arg from a single ocsp to multi ocsp
822 * the order of operations below matter, take care when changing it
823 */
824 tmp_ocsp = cb_arg->s_ocsp;
825 index = ssl_sock_get_ocsp_arg_kt_index(cb_arg->single_kt);
826 cb_arg->s_ocsp = NULL;
827 cb_arg->m_ocsp[index] = tmp_ocsp;
828 cb_arg->is_single = 0;
829 cb_arg->single_kt = 0;
830
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +0200831 key_type = EVP_PKEY_base_id(X509_get_pubkey(x));
832 index = ssl_sock_get_ocsp_arg_kt_index(key_type);
yanbzhube2774d2015-12-10 15:07:30 -0500833 if (index >= 0 && !cb_arg->m_ocsp[index])
834 cb_arg->m_ocsp[index] = iocsp;
835
836 }
Emeric Brun4147b2e2014-06-16 18:36:30 +0200837
838 ret = 0;
839
840 warn = NULL;
841 if (ssl_sock_load_ocsp_response_from_file(ocsp_path, iocsp, cid, &warn)) {
842 memprintf(&warn, "Loading '%s': %s. Content will be ignored", ocsp_path, warn ? warn : "failure");
843 Warning("%s.\n", warn);
844 }
845
846out:
847 if (ssl)
848 SSL_free(ssl);
849
850 if (in)
851 BIO_free(in);
852
853 if (xi)
854 X509_free(xi);
855
856 if (cid)
857 OCSP_CERTID_free(cid);
858
859 if (ocsp)
860 free(ocsp);
861
862 if (warn)
863 free(warn);
864
865
866 return ret;
867}
868
869#endif
870
Daniel Jakots54ffb912015-11-06 20:02:41 +0100871#if (OPENSSL_VERSION_NUMBER >= 0x1000200fL && !defined OPENSSL_NO_TLSEXT && !defined OPENSSL_IS_BORINGSSL && !defined LIBRESSL_VERSION_NUMBER)
Janusz Dziemidowicz2c701b52015-03-07 23:03:59 +0100872
873#define CT_EXTENSION_TYPE 18
874
875static int sctl_ex_index = -1;
876
877/*
878 * Try to parse Signed Certificate Timestamp List structure. This function
879 * makes only basic test if the data seems like SCTL. No signature validation
880 * is performed.
881 */
882static int ssl_sock_parse_sctl(struct chunk *sctl)
883{
884 int ret = 1;
885 int len, pos, sct_len;
886 unsigned char *data;
887
888 if (sctl->len < 2)
889 goto out;
890
891 data = (unsigned char *)sctl->str;
892 len = (data[0] << 8) | data[1];
893
894 if (len + 2 != sctl->len)
895 goto out;
896
897 data = data + 2;
898 pos = 0;
899 while (pos < len) {
900 if (len - pos < 2)
901 goto out;
902
903 sct_len = (data[pos] << 8) | data[pos + 1];
904 if (pos + sct_len + 2 > len)
905 goto out;
906
907 pos += sct_len + 2;
908 }
909
910 ret = 0;
911
912out:
913 return ret;
914}
915
916static int ssl_sock_load_sctl_from_file(const char *sctl_path, struct chunk **sctl)
917{
918 int fd = -1;
919 int r = 0;
920 int ret = 1;
921
922 *sctl = NULL;
923
924 fd = open(sctl_path, O_RDONLY);
925 if (fd == -1)
926 goto end;
927
928 trash.len = 0;
929 while (trash.len < trash.size) {
930 r = read(fd, trash.str + trash.len, trash.size - trash.len);
931 if (r < 0) {
932 if (errno == EINTR)
933 continue;
934
935 goto end;
936 }
937 else if (r == 0) {
938 break;
939 }
940 trash.len += r;
941 }
942
943 ret = ssl_sock_parse_sctl(&trash);
944 if (ret)
945 goto end;
946
Vincent Bernat02779b62016-04-03 13:48:43 +0200947 *sctl = calloc(1, sizeof(**sctl));
Janusz Dziemidowicz2c701b52015-03-07 23:03:59 +0100948 if (!chunk_dup(*sctl, &trash)) {
949 free(*sctl);
950 *sctl = NULL;
951 goto end;
952 }
953
954end:
955 if (fd != -1)
956 close(fd);
957
958 return ret;
959}
960
961int ssl_sock_sctl_add_cbk(SSL *ssl, unsigned ext_type, const unsigned char **out, size_t *outlen, int *al, void *add_arg)
962{
Vincent Bernat3c2f2f22016-04-03 13:48:42 +0200963 struct chunk *sctl = add_arg;
Janusz Dziemidowicz2c701b52015-03-07 23:03:59 +0100964
965 *out = (unsigned char *)sctl->str;
966 *outlen = sctl->len;
967
968 return 1;
969}
970
971int ssl_sock_sctl_parse_cbk(SSL *s, unsigned int ext_type, const unsigned char *in, size_t inlen, int *al, void *parse_arg)
972{
973 return 1;
974}
975
976static int ssl_sock_load_sctl(SSL_CTX *ctx, const char *cert_path)
977{
978 char sctl_path[MAXPATHLEN+1];
979 int ret = -1;
980 struct stat st;
981 struct chunk *sctl = NULL;
982
983 snprintf(sctl_path, MAXPATHLEN+1, "%s.sctl", cert_path);
984
985 if (stat(sctl_path, &st))
986 return 1;
987
988 if (ssl_sock_load_sctl_from_file(sctl_path, &sctl))
989 goto out;
990
991 if (!SSL_CTX_add_server_custom_ext(ctx, CT_EXTENSION_TYPE, ssl_sock_sctl_add_cbk, NULL, sctl, ssl_sock_sctl_parse_cbk, NULL)) {
992 free(sctl);
993 goto out;
994 }
995
996 SSL_CTX_set_ex_data(ctx, sctl_ex_index, sctl);
997
998 ret = 0;
999
1000out:
1001 return ret;
1002}
1003
1004#endif
1005
Emeric Brune1f38db2012-09-03 20:36:47 +02001006void ssl_sock_infocbk(const SSL *ssl, int where, int ret)
1007{
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02001008 struct connection *conn = SSL_get_app_data(ssl);
Emeric Brund8b2bb52014-01-28 15:43:53 +01001009 BIO *write_bio;
Willy Tarreau622317d2015-02-27 16:36:16 +01001010 (void)ret; /* shut gcc stupid warning */
Emeric Brune1f38db2012-09-03 20:36:47 +02001011
1012 if (where & SSL_CB_HANDSHAKE_START) {
1013 /* Disable renegotiation (CVE-2009-3555) */
Willy Tarreau20879a02012-12-03 16:32:10 +01001014 if (conn->flags & CO_FL_CONNECTED) {
Emeric Brune1f38db2012-09-03 20:36:47 +02001015 conn->flags |= CO_FL_ERROR;
Willy Tarreau20879a02012-12-03 16:32:10 +01001016 conn->err_code = CO_ER_SSL_RENEG;
1017 }
Emeric Brune1f38db2012-09-03 20:36:47 +02001018 }
Emeric Brund8b2bb52014-01-28 15:43:53 +01001019
1020 if ((where & SSL_CB_ACCEPT_LOOP) == SSL_CB_ACCEPT_LOOP) {
1021 if (!(conn->xprt_st & SSL_SOCK_ST_FL_16K_WBFSIZE)) {
1022 /* Long certificate chains optimz
1023 If write and read bios are differents, we
1024 consider that the buffering was activated,
1025 so we rise the output buffer size from 4k
1026 to 16k */
1027 write_bio = SSL_get_wbio(ssl);
1028 if (write_bio != SSL_get_rbio(ssl)) {
1029 BIO_set_write_buffer_size(write_bio, 16384);
1030 conn->xprt_st |= SSL_SOCK_ST_FL_16K_WBFSIZE;
1031 }
1032 }
1033 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02001034}
1035
Emeric Brune64aef12012-09-21 13:15:06 +02001036/* Callback is called for each certificate of the chain during a verify
1037 ok is set to 1 if preverify detect no error on current certificate.
1038 Returns 0 to break the handshake, 1 otherwise. */
Evan Broderbe554312013-06-27 00:05:25 -07001039int ssl_sock_bind_verifycbk(int ok, X509_STORE_CTX *x_store)
Emeric Brune64aef12012-09-21 13:15:06 +02001040{
1041 SSL *ssl;
1042 struct connection *conn;
Emeric Brun81c00f02012-09-21 14:31:21 +02001043 int err, depth;
Emeric Brune64aef12012-09-21 13:15:06 +02001044
1045 ssl = X509_STORE_CTX_get_ex_data(x_store, SSL_get_ex_data_X509_STORE_CTX_idx());
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02001046 conn = SSL_get_app_data(ssl);
Emeric Brune64aef12012-09-21 13:15:06 +02001047
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02001048 conn->xprt_st |= SSL_SOCK_ST_FL_VERIFY_DONE;
Emeric Brune64aef12012-09-21 13:15:06 +02001049
Emeric Brun81c00f02012-09-21 14:31:21 +02001050 if (ok) /* no errors */
1051 return ok;
1052
1053 depth = X509_STORE_CTX_get_error_depth(x_store);
1054 err = X509_STORE_CTX_get_error(x_store);
1055
1056 /* check if CA error needs to be ignored */
1057 if (depth > 0) {
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02001058 if (!SSL_SOCK_ST_TO_CA_ERROR(conn->xprt_st)) {
1059 conn->xprt_st |= SSL_SOCK_CA_ERROR_TO_ST(err);
1060 conn->xprt_st |= SSL_SOCK_CAEDEPTH_TO_ST(depth);
Emeric Brunf282a812012-09-21 15:27:54 +02001061 }
1062
Emeric Brun1eb20ef2012-12-03 13:24:29 +01001063 if (objt_listener(conn->target)->bind_conf->ca_ignerr & (1ULL << err)) {
Thierry FOURNIER / OZON.IO8b068c22016-10-10 11:59:50 +02001064 ssl_sock_dump_errors(conn);
Emeric Brun1eb20ef2012-12-03 13:24:29 +01001065 ERR_clear_error();
Emeric Brun81c00f02012-09-21 14:31:21 +02001066 return 1;
Emeric Brun1eb20ef2012-12-03 13:24:29 +01001067 }
Emeric Brun81c00f02012-09-21 14:31:21 +02001068
Willy Tarreau20879a02012-12-03 16:32:10 +01001069 conn->err_code = CO_ER_SSL_CA_FAIL;
Emeric Brun81c00f02012-09-21 14:31:21 +02001070 return 0;
1071 }
1072
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02001073 if (!SSL_SOCK_ST_TO_CRTERROR(conn->xprt_st))
1074 conn->xprt_st |= SSL_SOCK_CRTERROR_TO_ST(err);
Emeric Brunf282a812012-09-21 15:27:54 +02001075
Emeric Brun81c00f02012-09-21 14:31:21 +02001076 /* check if certificate error needs to be ignored */
Emeric Brun1eb20ef2012-12-03 13:24:29 +01001077 if (objt_listener(conn->target)->bind_conf->crt_ignerr & (1ULL << err)) {
Thierry FOURNIER / OZON.IO8b068c22016-10-10 11:59:50 +02001078 ssl_sock_dump_errors(conn);
Emeric Brun1eb20ef2012-12-03 13:24:29 +01001079 ERR_clear_error();
Emeric Brun81c00f02012-09-21 14:31:21 +02001080 return 1;
Emeric Brun1eb20ef2012-12-03 13:24:29 +01001081 }
Emeric Brun81c00f02012-09-21 14:31:21 +02001082
Willy Tarreau20879a02012-12-03 16:32:10 +01001083 conn->err_code = CO_ER_SSL_CRT_FAIL;
Emeric Brun81c00f02012-09-21 14:31:21 +02001084 return 0;
Emeric Brune64aef12012-09-21 13:15:06 +02001085}
1086
Emeric Brun29f037d2014-04-25 19:05:36 +02001087/* Callback is called for ssl protocol analyse */
1088void ssl_sock_msgcbk(int write_p, int version, int content_type, const void *buf, size_t len, SSL *ssl, void *arg)
1089{
Emeric Brun29f037d2014-04-25 19:05:36 +02001090#ifdef TLS1_RT_HEARTBEAT
1091 /* test heartbeat received (write_p is set to 0
1092 for a received record) */
Willy Tarreauf51c6982014-04-25 20:02:39 +02001093 if ((content_type == TLS1_RT_HEARTBEAT) && (write_p == 0)) {
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02001094 struct connection *conn = SSL_get_app_data(ssl);
Willy Tarreauf51c6982014-04-25 20:02:39 +02001095 const unsigned char *p = buf;
1096 unsigned int payload;
1097
Emeric Brun29f037d2014-04-25 19:05:36 +02001098 conn->xprt_st |= SSL_SOCK_RECV_HEARTBEAT;
Willy Tarreauf51c6982014-04-25 20:02:39 +02001099
1100 /* Check if this is a CVE-2014-0160 exploitation attempt. */
1101 if (*p != TLS1_HB_REQUEST)
1102 return;
1103
Willy Tarreauaeed6722014-04-25 23:59:58 +02001104 if (len < 1 + 2 + 16) /* 1 type + 2 size + 0 payload + 16 padding */
Willy Tarreauf51c6982014-04-25 20:02:39 +02001105 goto kill_it;
1106
1107 payload = (p[1] * 256) + p[2];
Willy Tarreau3b2fdb62014-04-25 23:44:22 +02001108 if (3 + payload + 16 <= len)
Willy Tarreauf51c6982014-04-25 20:02:39 +02001109 return; /* OK no problem */
Willy Tarreauaeed6722014-04-25 23:59:58 +02001110 kill_it:
Willy Tarreau3b2fdb62014-04-25 23:44:22 +02001111 /* We have a clear heartbleed attack (CVE-2014-0160), the
1112 * advertised payload is larger than the advertised packet
1113 * length, so we have garbage in the buffer between the
1114 * payload and the end of the buffer (p+len). We can't know
1115 * if the SSL stack is patched, and we don't know if we can
1116 * safely wipe out the area between p+3+len and payload.
1117 * So instead, we prevent the response from being sent by
1118 * setting the max_send_fragment to 0 and we report an SSL
1119 * error, which will kill this connection. It will be reported
1120 * above as SSL_ERROR_SSL while an other handshake failure with
Willy Tarreauf51c6982014-04-25 20:02:39 +02001121 * a heartbeat message will be reported as SSL_ERROR_SYSCALL.
1122 */
Willy Tarreau3b2fdb62014-04-25 23:44:22 +02001123 ssl->max_send_fragment = 0;
Willy Tarreauf51c6982014-04-25 20:02:39 +02001124 SSLerr(SSL_F_TLS1_HEARTBEAT, SSL_R_SSL_HANDSHAKE_FAILURE);
1125 return;
1126 }
Emeric Brun29f037d2014-04-25 19:05:36 +02001127#endif
1128}
1129
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02001130#ifdef OPENSSL_NPN_NEGOTIATED
1131/* This callback is used so that the server advertises the list of
1132 * negociable protocols for NPN.
1133 */
1134static int ssl_sock_advertise_npn_protos(SSL *s, const unsigned char **data,
1135 unsigned int *len, void *arg)
1136{
1137 struct bind_conf *conf = arg;
1138
1139 *data = (const unsigned char *)conf->npn_str;
1140 *len = conf->npn_len;
1141 return SSL_TLSEXT_ERR_OK;
1142}
1143#endif
1144
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01001145#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Willy Tarreauab861d32013-04-02 02:30:41 +02001146/* This callback is used so that the server advertises the list of
1147 * negociable protocols for ALPN.
1148 */
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01001149static int ssl_sock_advertise_alpn_protos(SSL *s, const unsigned char **out,
1150 unsigned char *outlen,
1151 const unsigned char *server,
1152 unsigned int server_len, void *arg)
Willy Tarreauab861d32013-04-02 02:30:41 +02001153{
1154 struct bind_conf *conf = arg;
1155
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01001156 if (SSL_select_next_proto((unsigned char**) out, outlen, (const unsigned char *)conf->alpn_str,
1157 conf->alpn_len, server, server_len) != OPENSSL_NPN_NEGOTIATED) {
1158 return SSL_TLSEXT_ERR_NOACK;
1159 }
Willy Tarreauab861d32013-04-02 02:30:41 +02001160 return SSL_TLSEXT_ERR_OK;
1161}
1162#endif
1163
Willy Tarreauc8ad3be2015-06-17 15:48:26 +02001164#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Christopher Faulet85b5a1a2015-10-09 11:46:32 +02001165static DH *ssl_get_tmp_dh(SSL *ssl, int export, int keylen);
1166
Christopher Faulet30548802015-06-11 13:39:32 +02001167/* Create a X509 certificate with the specified servername and serial. This
1168 * function returns a SSL_CTX object or NULL if an error occurs. */
Christopher Faulet7969a332015-10-09 11:15:03 +02001169static SSL_CTX *
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001170ssl_sock_do_create_cert(const char *servername, struct bind_conf *bind_conf, SSL *ssl)
Christopher Faulet31af49d2015-06-09 17:29:50 +02001171{
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001172 static unsigned int serial = 0;
1173
Christopher Faulet7969a332015-10-09 11:15:03 +02001174 X509 *cacert = bind_conf->ca_sign_cert;
1175 EVP_PKEY *capkey = bind_conf->ca_sign_pkey;
Christopher Faulet31af49d2015-06-09 17:29:50 +02001176 SSL_CTX *ssl_ctx = NULL;
1177 X509 *newcrt = NULL;
1178 EVP_PKEY *pkey = NULL;
Christopher Faulet31af49d2015-06-09 17:29:50 +02001179 X509_NAME *name;
1180 const EVP_MD *digest;
1181 X509V3_CTX ctx;
1182 unsigned int i;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02001183 int key_type;
Christopher Faulet31af49d2015-06-09 17:29:50 +02001184
Christopher Faulet7969a332015-10-09 11:15:03 +02001185 /* Get the private key of the defautl certificate and use it */
1186 if (!(pkey = SSL_get_privatekey(ssl)))
Christopher Faulet31af49d2015-06-09 17:29:50 +02001187 goto mkcert_error;
1188
1189 /* Create the certificate */
1190 if (!(newcrt = X509_new()))
1191 goto mkcert_error;
1192
1193 /* Set version number for the certificate (X509v3) and the serial
1194 * number */
1195 if (X509_set_version(newcrt, 2L) != 1)
1196 goto mkcert_error;
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001197 if (!serial)
1198 serial = now_ms;
1199 ASN1_INTEGER_set(X509_get_serialNumber(newcrt), serial++);
Christopher Faulet31af49d2015-06-09 17:29:50 +02001200
1201 /* Set duration for the certificate */
1202 if (!X509_gmtime_adj(X509_get_notBefore(newcrt), (long)-60*60*24) ||
1203 !X509_gmtime_adj(X509_get_notAfter(newcrt),(long)60*60*24*365))
1204 goto mkcert_error;
1205
1206 /* set public key in the certificate */
1207 if (X509_set_pubkey(newcrt, pkey) != 1)
1208 goto mkcert_error;
1209
1210 /* Set issuer name from the CA */
1211 if (!(name = X509_get_subject_name(cacert)))
1212 goto mkcert_error;
1213 if (X509_set_issuer_name(newcrt, name) != 1)
1214 goto mkcert_error;
1215
1216 /* Set the subject name using the same, but the CN */
1217 name = X509_NAME_dup(name);
1218 if (X509_NAME_add_entry_by_txt(name, "CN", MBSTRING_ASC,
1219 (const unsigned char *)servername,
1220 -1, -1, 0) != 1) {
1221 X509_NAME_free(name);
1222 goto mkcert_error;
1223 }
1224 if (X509_set_subject_name(newcrt, name) != 1) {
1225 X509_NAME_free(name);
1226 goto mkcert_error;
1227 }
1228 X509_NAME_free(name);
1229
1230 /* Add x509v3 extensions as specified */
1231 X509V3_set_ctx(&ctx, cacert, newcrt, NULL, NULL, 0);
1232 for (i = 0; i < X509V3_EXT_SIZE; i++) {
1233 X509_EXTENSION *ext;
1234
1235 if (!(ext = X509V3_EXT_conf(NULL, &ctx, x509v3_ext_names[i], x509v3_ext_values[i])))
1236 goto mkcert_error;
1237 if (!X509_add_ext(newcrt, ext, -1)) {
1238 X509_EXTENSION_free(ext);
1239 goto mkcert_error;
1240 }
1241 X509_EXTENSION_free(ext);
1242 }
1243
1244 /* Sign the certificate with the CA private key */
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02001245
1246 key_type = EVP_PKEY_base_id(capkey);
1247
1248 if (key_type == EVP_PKEY_DSA)
1249 digest = EVP_sha1();
1250 else if (key_type == EVP_PKEY_RSA)
Christopher Faulet31af49d2015-06-09 17:29:50 +02001251 digest = EVP_sha256();
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02001252 else if (key_type == EVP_PKEY_EC)
Christopher Faulet7969a332015-10-09 11:15:03 +02001253 digest = EVP_sha256();
1254 else {
Christopher Faulete7db2162015-10-19 13:59:24 +02001255#if (OPENSSL_VERSION_NUMBER >= 0x1000000fL)
Christopher Faulet7969a332015-10-09 11:15:03 +02001256 int nid;
1257
1258 if (EVP_PKEY_get_default_digest_nid(capkey, &nid) <= 0)
1259 goto mkcert_error;
1260 if (!(digest = EVP_get_digestbynid(nid)))
1261 goto mkcert_error;
Christopher Faulete7db2162015-10-19 13:59:24 +02001262#else
1263 goto mkcert_error;
1264#endif
Christopher Faulet7969a332015-10-09 11:15:03 +02001265 }
1266
Christopher Faulet31af49d2015-06-09 17:29:50 +02001267 if (!(X509_sign(newcrt, capkey, digest)))
1268 goto mkcert_error;
1269
1270 /* Create and set the new SSL_CTX */
1271 if (!(ssl_ctx = SSL_CTX_new(SSLv23_server_method())))
1272 goto mkcert_error;
1273 if (!SSL_CTX_use_PrivateKey(ssl_ctx, pkey))
1274 goto mkcert_error;
1275 if (!SSL_CTX_use_certificate(ssl_ctx, newcrt))
1276 goto mkcert_error;
1277 if (!SSL_CTX_check_private_key(ssl_ctx))
1278 goto mkcert_error;
1279
1280 if (newcrt) X509_free(newcrt);
Christopher Faulet7969a332015-10-09 11:15:03 +02001281
Christopher Faulet85b5a1a2015-10-09 11:46:32 +02001282 SSL_CTX_set_tmp_dh_callback(ssl_ctx, ssl_get_tmp_dh);
1283#if defined(SSL_CTX_set_tmp_ecdh) && !defined(OPENSSL_NO_ECDH)
1284 {
1285 const char *ecdhe = (bind_conf->ecdhe ? bind_conf->ecdhe : ECDHE_DEFAULT_CURVE);
1286 EC_KEY *ecc;
1287 int nid;
1288
1289 if ((nid = OBJ_sn2nid(ecdhe)) == NID_undef)
1290 goto end;
1291 if (!(ecc = EC_KEY_new_by_curve_name(nid)))
1292 goto end;
1293 SSL_CTX_set_tmp_ecdh(ssl_ctx, ecc);
1294 EC_KEY_free(ecc);
1295 }
1296#endif
1297 end:
Christopher Faulet31af49d2015-06-09 17:29:50 +02001298 return ssl_ctx;
1299
1300 mkcert_error:
1301 if (ssl_ctx) SSL_CTX_free(ssl_ctx);
1302 if (newcrt) X509_free(newcrt);
Christopher Faulet31af49d2015-06-09 17:29:50 +02001303 return NULL;
1304}
1305
Christopher Faulet7969a332015-10-09 11:15:03 +02001306SSL_CTX *
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001307ssl_sock_create_cert(struct connection *conn, const char *servername, unsigned int key)
Christopher Faulet7969a332015-10-09 11:15:03 +02001308{
1309 struct bind_conf *bind_conf = objt_listener(conn->target)->bind_conf;
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001310
1311 return ssl_sock_do_create_cert(servername, bind_conf, conn->xprt_ctx);
Christopher Faulet7969a332015-10-09 11:15:03 +02001312}
1313
Christopher Faulet30548802015-06-11 13:39:32 +02001314/* Do a lookup for a certificate in the LRU cache used to store generated
1315 * certificates. */
1316SSL_CTX *
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001317ssl_sock_get_generated_cert(unsigned int key, struct bind_conf *bind_conf)
Christopher Faulet30548802015-06-11 13:39:32 +02001318{
1319 struct lru64 *lru = NULL;
1320
1321 if (ssl_ctx_lru_tree) {
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001322 lru = lru64_lookup(key, ssl_ctx_lru_tree, bind_conf->ca_sign_cert, 0);
Christopher Faulet30548802015-06-11 13:39:32 +02001323 if (lru && lru->domain)
1324 return (SSL_CTX *)lru->data;
1325 }
1326 return NULL;
1327}
1328
Christopher Fauletd2cab922015-07-28 16:03:47 +02001329/* Set a certificate int the LRU cache used to store generated
1330 * certificate. Return 0 on success, otherwise -1 */
1331int
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001332ssl_sock_set_generated_cert(SSL_CTX *ssl_ctx, unsigned int key, struct bind_conf *bind_conf)
Christopher Faulet30548802015-06-11 13:39:32 +02001333{
1334 struct lru64 *lru = NULL;
1335
1336 if (ssl_ctx_lru_tree) {
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001337 lru = lru64_get(key, ssl_ctx_lru_tree, bind_conf->ca_sign_cert, 0);
Christopher Faulet30548802015-06-11 13:39:32 +02001338 if (!lru)
Christopher Fauletd2cab922015-07-28 16:03:47 +02001339 return -1;
Christopher Faulet30548802015-06-11 13:39:32 +02001340 if (lru->domain && lru->data)
1341 lru->free((SSL_CTX *)lru->data);
Christopher Faulet7969a332015-10-09 11:15:03 +02001342 lru64_commit(lru, ssl_ctx, bind_conf->ca_sign_cert, 0, (void (*)(void *))SSL_CTX_free);
Christopher Fauletd2cab922015-07-28 16:03:47 +02001343 return 0;
Christopher Faulet30548802015-06-11 13:39:32 +02001344 }
Christopher Fauletd2cab922015-07-28 16:03:47 +02001345 return -1;
Christopher Faulet30548802015-06-11 13:39:32 +02001346}
1347
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001348/* Compute the key of the certificate. */
Christopher Faulet30548802015-06-11 13:39:32 +02001349unsigned int
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001350ssl_sock_generated_cert_key(const void *data, size_t len)
Christopher Faulet30548802015-06-11 13:39:32 +02001351{
1352 return XXH32(data, len, ssl_ctx_lru_seed);
1353}
1354
Willy Tarreau2f63ef42015-10-20 15:16:01 +02001355/* Generate a cert and immediately assign it to the SSL session so that the cert's
1356 * refcount is maintained regardless of the cert's presence in the LRU cache.
1357 */
Christopher Faulet31af49d2015-06-09 17:29:50 +02001358static SSL_CTX *
Christopher Faulet7969a332015-10-09 11:15:03 +02001359ssl_sock_generate_certificate(const char *servername, struct bind_conf *bind_conf, SSL *ssl)
Christopher Faulet31af49d2015-06-09 17:29:50 +02001360{
1361 X509 *cacert = bind_conf->ca_sign_cert;
Christopher Faulet31af49d2015-06-09 17:29:50 +02001362 SSL_CTX *ssl_ctx = NULL;
1363 struct lru64 *lru = NULL;
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001364 unsigned int key;
Christopher Faulet31af49d2015-06-09 17:29:50 +02001365
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001366 key = ssl_sock_generated_cert_key(servername, strlen(servername));
Christopher Faulet31af49d2015-06-09 17:29:50 +02001367 if (ssl_ctx_lru_tree) {
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001368 lru = lru64_get(key, ssl_ctx_lru_tree, cacert, 0);
Christopher Faulet31af49d2015-06-09 17:29:50 +02001369 if (lru && lru->domain)
1370 ssl_ctx = (SSL_CTX *)lru->data;
Christopher Fauletd2cab922015-07-28 16:03:47 +02001371 if (!ssl_ctx && lru) {
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001372 ssl_ctx = ssl_sock_do_create_cert(servername, bind_conf, ssl);
Christopher Faulet31af49d2015-06-09 17:29:50 +02001373 lru64_commit(lru, ssl_ctx, cacert, 0, (void (*)(void *))SSL_CTX_free);
Christopher Fauletd2cab922015-07-28 16:03:47 +02001374 }
Willy Tarreau2f63ef42015-10-20 15:16:01 +02001375 SSL_set_SSL_CTX(ssl, ssl_ctx);
Christopher Faulet31af49d2015-06-09 17:29:50 +02001376 }
Willy Tarreau2f63ef42015-10-20 15:16:01 +02001377 else {
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001378 ssl_ctx = ssl_sock_do_create_cert(servername, bind_conf, ssl);
Willy Tarreau2f63ef42015-10-20 15:16:01 +02001379 SSL_set_SSL_CTX(ssl, ssl_ctx);
1380 /* No LRU cache, this CTX will be released as soon as the session dies */
1381 SSL_CTX_free(ssl_ctx);
1382 }
Christopher Faulet31af49d2015-06-09 17:29:50 +02001383 return ssl_ctx;
1384}
1385
Emeric Brunfc0421f2012-09-07 17:30:07 +02001386/* Sets the SSL ctx of <ssl> to match the advertised server name. Returns a
1387 * warning when no match is found, which implies the default (first) cert
1388 * will keep being used.
1389 */
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001390static int ssl_sock_switchctx_cbk(SSL *ssl, int *al, struct bind_conf *s)
Emeric Brunfc0421f2012-09-07 17:30:07 +02001391{
1392 const char *servername;
1393 const char *wildp = NULL;
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001394 struct ebmb_node *node, *n;
Emeric Brunfc0421f2012-09-07 17:30:07 +02001395 int i;
1396 (void)al; /* shut gcc stupid warning */
1397
1398 servername = SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name);
Emmanuel Hocdet65623372013-01-24 17:17:15 +01001399 if (!servername) {
Willy Tarreauf6721452015-07-07 18:04:38 +02001400 if (s->generate_certs) {
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02001401 struct connection *conn = SSL_get_app_data(ssl);
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001402 unsigned int key;
Willy Tarreauf6721452015-07-07 18:04:38 +02001403 SSL_CTX *ctx;
Christopher Faulet30548802015-06-11 13:39:32 +02001404
Willy Tarreauf6721452015-07-07 18:04:38 +02001405 conn_get_to_addr(conn);
1406 if (conn->flags & CO_FL_ADDR_TO_SET) {
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001407 key = ssl_sock_generated_cert_key(&conn->addr.to, get_addr_len(&conn->addr.to));
1408 ctx = ssl_sock_get_generated_cert(key, s);
Willy Tarreauf6721452015-07-07 18:04:38 +02001409 if (ctx) {
1410 /* switch ctx */
1411 SSL_set_SSL_CTX(ssl, ctx);
1412 return SSL_TLSEXT_ERR_OK;
1413 }
Christopher Faulet30548802015-06-11 13:39:32 +02001414 }
1415 }
1416
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001417 return (s->strict_sni ?
1418 SSL_TLSEXT_ERR_ALERT_FATAL :
Emmanuel Hocdet79274e22013-05-31 12:47:44 +02001419 SSL_TLSEXT_ERR_NOACK);
Emmanuel Hocdet65623372013-01-24 17:17:15 +01001420 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02001421
Willy Tarreau19d14ef2012-10-29 16:51:55 +01001422 for (i = 0; i < trash.size; i++) {
Emeric Brunfc0421f2012-09-07 17:30:07 +02001423 if (!servername[i])
1424 break;
Willy Tarreau19d14ef2012-10-29 16:51:55 +01001425 trash.str[i] = tolower(servername[i]);
1426 if (!wildp && (trash.str[i] == '.'))
1427 wildp = &trash.str[i];
Emeric Brunfc0421f2012-09-07 17:30:07 +02001428 }
Willy Tarreau19d14ef2012-10-29 16:51:55 +01001429 trash.str[i] = 0;
Emeric Brunfc0421f2012-09-07 17:30:07 +02001430
1431 /* lookup in full qualified names */
Willy Tarreau19d14ef2012-10-29 16:51:55 +01001432 node = ebst_lookup(&s->sni_ctx, trash.str);
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001433
1434 /* lookup a not neg filter */
1435 for (n = node; n; n = ebmb_next_dup(n)) {
1436 if (!container_of(n, struct sni_ctx, name)->neg) {
1437 node = n;
1438 break;
Emmanuel Hocdet65623372013-01-24 17:17:15 +01001439 }
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001440 }
1441 if (!node && wildp) {
1442 /* lookup in wildcards names */
Emeric Brunfc0421f2012-09-07 17:30:07 +02001443 node = ebst_lookup(&s->sni_w_ctx, wildp);
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001444 }
1445 if (!node || container_of(node, struct sni_ctx, name)->neg) {
Christopher Faulet31af49d2015-06-09 17:29:50 +02001446 SSL_CTX *ctx;
Christopher Faulet31af49d2015-06-09 17:29:50 +02001447 if (s->generate_certs &&
Christopher Faulet7969a332015-10-09 11:15:03 +02001448 (ctx = ssl_sock_generate_certificate(servername, s, ssl))) {
Christopher Faulet31af49d2015-06-09 17:29:50 +02001449 /* switch ctx */
Christopher Faulet31af49d2015-06-09 17:29:50 +02001450 return SSL_TLSEXT_ERR_OK;
1451 }
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001452 return (s->strict_sni ?
1453 SSL_TLSEXT_ERR_ALERT_FATAL :
1454 SSL_TLSEXT_ERR_ALERT_WARNING);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001455 }
1456
1457 /* switch ctx */
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001458 SSL_set_SSL_CTX(ssl, container_of(node, struct sni_ctx, name)->ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001459 return SSL_TLSEXT_ERR_OK;
1460}
1461#endif /* SSL_CTRL_SET_TLSEXT_HOSTNAME */
1462
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001463#ifndef OPENSSL_NO_DH
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001464
1465static DH * ssl_get_dh_1024(void)
1466{
Remi Gacogned3a341a2015-05-29 16:26:17 +02001467 static unsigned char dh1024_p[]={
1468 0xFA,0xF9,0x2A,0x22,0x2A,0xA7,0x7F,0xE1,0x67,0x4E,0x53,0xF7,
1469 0x56,0x13,0xC3,0xB1,0xE3,0x29,0x6B,0x66,0x31,0x6A,0x7F,0xB3,
1470 0xC2,0x68,0x6B,0xCB,0x1D,0x57,0x39,0x1D,0x1F,0xFF,0x1C,0xC9,
1471 0xA6,0xA4,0x98,0x82,0x31,0x5D,0x25,0xFF,0x8A,0xE0,0x73,0x96,
1472 0x81,0xC8,0x83,0x79,0xC1,0x5A,0x04,0xF8,0x37,0x0D,0xA8,0x3D,
1473 0xAE,0x74,0xBC,0xDB,0xB6,0xA4,0x75,0xD9,0x71,0x8A,0xA0,0x17,
1474 0x9E,0x2D,0xC8,0xA8,0xDF,0x2C,0x5F,0x82,0x95,0xF8,0x92,0x9B,
1475 0xA7,0x33,0x5F,0x89,0x71,0xC8,0x2D,0x6B,0x18,0x86,0xC4,0x94,
1476 0x22,0xA5,0x52,0x8D,0xF6,0xF6,0xD2,0x37,0x92,0x0F,0xA5,0xCC,
1477 0xDB,0x7B,0x1D,0x3D,0xA1,0x31,0xB7,0x80,0x8F,0x0B,0x67,0x5E,
1478 0x36,0xA5,0x60,0x0C,0xF1,0x95,0x33,0x8B,
1479 };
1480 static unsigned char dh1024_g[]={
1481 0x02,
1482 };
1483
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02001484 BIGNUM *p;
1485 BIGNUM *g;
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001486 DH *dh = DH_new();
1487 if (dh) {
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02001488 p = BN_bin2bn(dh1024_p, sizeof dh1024_p, NULL);
1489 g = BN_bin2bn(dh1024_g, sizeof dh1024_g, NULL);
Remi Gacogned3a341a2015-05-29 16:26:17 +02001490
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02001491 if (!p || !g) {
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001492 DH_free(dh);
1493 dh = NULL;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02001494 } else {
1495 DH_set0_pqg(dh, p, NULL, g);
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001496 }
1497 }
1498 return dh;
1499}
1500
1501static DH *ssl_get_dh_2048(void)
1502{
Remi Gacogned3a341a2015-05-29 16:26:17 +02001503 static unsigned char dh2048_p[]={
1504 0xEC,0x86,0xF8,0x70,0xA0,0x33,0x16,0xEC,0x05,0x1A,0x73,0x59,
1505 0xCD,0x1F,0x8B,0xF8,0x29,0xE4,0xD2,0xCF,0x52,0xDD,0xC2,0x24,
1506 0x8D,0xB5,0x38,0x9A,0xFB,0x5C,0xA4,0xE4,0xB2,0xDA,0xCE,0x66,
1507 0x50,0x74,0xA6,0x85,0x4D,0x4B,0x1D,0x30,0xB8,0x2B,0xF3,0x10,
1508 0xE9,0xA7,0x2D,0x05,0x71,0xE7,0x81,0xDF,0x8B,0x59,0x52,0x3B,
1509 0x5F,0x43,0x0B,0x68,0xF1,0xDB,0x07,0xBE,0x08,0x6B,0x1B,0x23,
1510 0xEE,0x4D,0xCC,0x9E,0x0E,0x43,0xA0,0x1E,0xDF,0x43,0x8C,0xEC,
1511 0xBE,0xBE,0x90,0xB4,0x51,0x54,0xB9,0x2F,0x7B,0x64,0x76,0x4E,
1512 0x5D,0xD4,0x2E,0xAE,0xC2,0x9E,0xAE,0x51,0x43,0x59,0xC7,0x77,
1513 0x9C,0x50,0x3C,0x0E,0xED,0x73,0x04,0x5F,0xF1,0x4C,0x76,0x2A,
1514 0xD8,0xF8,0xCF,0xFC,0x34,0x40,0xD1,0xB4,0x42,0x61,0x84,0x66,
1515 0x42,0x39,0x04,0xF8,0x68,0xB2,0x62,0xD7,0x55,0xED,0x1B,0x74,
1516 0x75,0x91,0xE0,0xC5,0x69,0xC1,0x31,0x5C,0xDB,0x7B,0x44,0x2E,
1517 0xCE,0x84,0x58,0x0D,0x1E,0x66,0x0C,0xC8,0x44,0x9E,0xFD,0x40,
1518 0x08,0x67,0x5D,0xFB,0xA7,0x76,0x8F,0x00,0x11,0x87,0xE9,0x93,
1519 0xF9,0x7D,0xC4,0xBC,0x74,0x55,0x20,0xD4,0x4A,0x41,0x2F,0x43,
1520 0x42,0x1A,0xC1,0xF2,0x97,0x17,0x49,0x27,0x37,0x6B,0x2F,0x88,
1521 0x7E,0x1C,0xA0,0xA1,0x89,0x92,0x27,0xD9,0x56,0x5A,0x71,0xC1,
1522 0x56,0x37,0x7E,0x3A,0x9D,0x05,0xE7,0xEE,0x5D,0x8F,0x82,0x17,
1523 0xBC,0xE9,0xC2,0x93,0x30,0x82,0xF9,0xF4,0xC9,0xAE,0x49,0xDB,
1524 0xD0,0x54,0xB4,0xD9,0x75,0x4D,0xFA,0x06,0xB8,0xD6,0x38,0x41,
1525 0xB7,0x1F,0x77,0xF3,
1526 };
1527 static unsigned char dh2048_g[]={
1528 0x02,
1529 };
1530
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02001531 BIGNUM *p;
1532 BIGNUM *g;
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001533 DH *dh = DH_new();
1534 if (dh) {
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02001535 p = BN_bin2bn(dh2048_p, sizeof dh2048_p, NULL);
1536 g = BN_bin2bn(dh2048_g, sizeof dh2048_g, NULL);
Remi Gacogned3a341a2015-05-29 16:26:17 +02001537
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02001538 if (!p || !g) {
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001539 DH_free(dh);
1540 dh = NULL;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02001541 } else {
1542 DH_set0_pqg(dh, p, NULL, g);
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001543 }
1544 }
1545 return dh;
1546}
1547
1548static DH *ssl_get_dh_4096(void)
1549{
Remi Gacogned3a341a2015-05-29 16:26:17 +02001550 static unsigned char dh4096_p[]={
1551 0xDE,0x16,0x94,0xCD,0x99,0x58,0x07,0xF1,0xF7,0x32,0x96,0x11,
1552 0x04,0x82,0xD4,0x84,0x72,0x80,0x99,0x06,0xCA,0xF0,0xA3,0x68,
1553 0x07,0xCE,0x64,0x50,0xE7,0x74,0x45,0x20,0x80,0x5E,0x4D,0xAD,
1554 0xA5,0xB6,0xED,0xFA,0x80,0x6C,0x3B,0x35,0xC4,0x9A,0x14,0x6B,
1555 0x32,0xBB,0xFD,0x1F,0x17,0x8E,0xB7,0x1F,0xD6,0xFA,0x3F,0x7B,
1556 0xEE,0x16,0xA5,0x62,0x33,0x0D,0xED,0xBC,0x4E,0x58,0xE5,0x47,
1557 0x4D,0xE9,0xAB,0x8E,0x38,0xD3,0x6E,0x90,0x57,0xE3,0x22,0x15,
1558 0x33,0xBD,0xF6,0x43,0x45,0xB5,0x10,0x0A,0xBE,0x2C,0xB4,0x35,
1559 0xB8,0x53,0x8D,0xAD,0xFB,0xA7,0x1F,0x85,0x58,0x41,0x7A,0x79,
1560 0x20,0x68,0xB3,0xE1,0x3D,0x08,0x76,0xBF,0x86,0x0D,0x49,0xE3,
1561 0x82,0x71,0x8C,0xB4,0x8D,0x81,0x84,0xD4,0xE7,0xBE,0x91,0xDC,
1562 0x26,0x39,0x48,0x0F,0x35,0xC4,0xCA,0x65,0xE3,0x40,0x93,0x52,
1563 0x76,0x58,0x7D,0xDD,0x51,0x75,0xDC,0x69,0x61,0xBF,0x47,0x2C,
1564 0x16,0x68,0x2D,0xC9,0x29,0xD3,0xE6,0xC0,0x99,0x48,0xA0,0x9A,
1565 0xC8,0x78,0xC0,0x6D,0x81,0x67,0x12,0x61,0x3F,0x71,0xBA,0x41,
1566 0x1F,0x6C,0x89,0x44,0x03,0xBA,0x3B,0x39,0x60,0xAA,0x28,0x55,
1567 0x59,0xAE,0xB8,0xFA,0xCB,0x6F,0xA5,0x1A,0xF7,0x2B,0xDD,0x52,
1568 0x8A,0x8B,0xE2,0x71,0xA6,0x5E,0x7E,0xD8,0x2E,0x18,0xE0,0x66,
1569 0xDF,0xDD,0x22,0x21,0x99,0x52,0x73,0xA6,0x33,0x20,0x65,0x0E,
1570 0x53,0xE7,0x6B,0x9B,0xC5,0xA3,0x2F,0x97,0x65,0x76,0xD3,0x47,
1571 0x23,0x77,0x12,0xB6,0x11,0x7B,0x24,0xED,0xF1,0xEF,0xC0,0xE2,
1572 0xA3,0x7E,0x67,0x05,0x3E,0x96,0x4D,0x45,0xC2,0x18,0xD1,0x73,
1573 0x9E,0x07,0xF3,0x81,0x6E,0x52,0x63,0xF6,0x20,0x76,0xB9,0x13,
1574 0xD2,0x65,0x30,0x18,0x16,0x09,0x16,0x9E,0x8F,0xF1,0xD2,0x10,
1575 0x5A,0xD3,0xD4,0xAF,0x16,0x61,0xDA,0x55,0x2E,0x18,0x5E,0x14,
1576 0x08,0x54,0x2E,0x2A,0x25,0xA2,0x1A,0x9B,0x8B,0x32,0xA9,0xFD,
1577 0xC2,0x48,0x96,0xE1,0x80,0xCA,0xE9,0x22,0x17,0xBB,0xCE,0x3E,
1578 0x9E,0xED,0xC7,0xF1,0x1F,0xEC,0x17,0x21,0xDC,0x7B,0x82,0x48,
1579 0x8E,0xBB,0x4B,0x9D,0x5B,0x04,0x04,0xDA,0xDB,0x39,0xDF,0x01,
1580 0x40,0xC3,0xAA,0x26,0x23,0x89,0x75,0xC6,0x0B,0xD0,0xA2,0x60,
1581 0x6A,0xF1,0xCC,0x65,0x18,0x98,0x1B,0x52,0xD2,0x74,0x61,0xCC,
1582 0xBD,0x60,0xAE,0xA3,0xA0,0x66,0x6A,0x16,0x34,0x92,0x3F,0x41,
1583 0x40,0x31,0x29,0xC0,0x2C,0x63,0xB2,0x07,0x8D,0xEB,0x94,0xB8,
1584 0xE8,0x47,0x92,0x52,0x93,0x6A,0x1B,0x7E,0x1A,0x61,0xB3,0x1B,
1585 0xF0,0xD6,0x72,0x9B,0xF1,0xB0,0xAF,0xBF,0x3E,0x65,0xEF,0x23,
1586 0x1D,0x6F,0xFF,0x70,0xCD,0x8A,0x4C,0x8A,0xA0,0x72,0x9D,0xBE,
1587 0xD4,0xBB,0x24,0x47,0x4A,0x68,0xB5,0xF5,0xC6,0xD5,0x7A,0xCD,
1588 0xCA,0x06,0x41,0x07,0xAD,0xC2,0x1E,0xE6,0x54,0xA7,0xAD,0x03,
1589 0xD9,0x12,0xC1,0x9C,0x13,0xB1,0xC9,0x0A,0x43,0x8E,0x1E,0x08,
1590 0xCE,0x50,0x82,0x73,0x5F,0xA7,0x55,0x1D,0xD9,0x59,0xAC,0xB5,
1591 0xEA,0x02,0x7F,0x6C,0x5B,0x74,0x96,0x98,0x67,0x24,0xA3,0x0F,
1592 0x15,0xFC,0xA9,0x7D,0x3E,0x67,0xD1,0x70,0xF8,0x97,0xF3,0x67,
1593 0xC5,0x8C,0x88,0x44,0x08,0x02,0xC7,0x2B,
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001594 };
Remi Gacogned3a341a2015-05-29 16:26:17 +02001595 static unsigned char dh4096_g[]={
1596 0x02,
1597 };
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001598
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02001599 BIGNUM *p;
1600 BIGNUM *g;
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001601 DH *dh = DH_new();
1602 if (dh) {
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02001603 p = BN_bin2bn(dh4096_p, sizeof dh4096_p, NULL);
1604 g = BN_bin2bn(dh4096_g, sizeof dh4096_g, NULL);
Remi Gacogned3a341a2015-05-29 16:26:17 +02001605
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02001606 if (!p || !g) {
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001607 DH_free(dh);
1608 dh = NULL;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02001609 } else {
1610 DH_set0_pqg(dh, p, NULL, g);
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001611 }
1612 }
1613 return dh;
1614}
1615
1616/* Returns Diffie-Hellman parameters matching the private key length
1617 but not exceeding global.tune.ssl_default_dh_param */
1618static DH *ssl_get_tmp_dh(SSL *ssl, int export, int keylen)
1619{
1620 DH *dh = NULL;
1621 EVP_PKEY *pkey = SSL_get_privatekey(ssl);
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02001622 int type;
1623
1624 type = pkey ? EVP_PKEY_base_id(pkey) : EVP_PKEY_NONE;
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001625
1626 /* The keylen supplied by OpenSSL can only be 512 or 1024.
1627 See ssl3_send_server_key_exchange() in ssl/s3_srvr.c
1628 */
1629 if (type == EVP_PKEY_RSA || type == EVP_PKEY_DSA) {
1630 keylen = EVP_PKEY_bits(pkey);
1631 }
1632
1633 if (keylen > global.tune.ssl_default_dh_param) {
1634 keylen = global.tune.ssl_default_dh_param;
1635 }
1636
Remi Gacogned3a341a2015-05-29 16:26:17 +02001637 if (keylen >= 4096) {
Remi Gacogne8de54152014-07-15 11:36:40 +02001638 dh = local_dh_4096;
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001639 }
1640 else if (keylen >= 2048) {
Remi Gacogne8de54152014-07-15 11:36:40 +02001641 dh = local_dh_2048;
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001642 }
1643 else {
Remi Gacogne8de54152014-07-15 11:36:40 +02001644 dh = local_dh_1024;
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001645 }
1646
1647 return dh;
1648}
1649
Remi Gacogne47783ef2015-05-29 15:53:22 +02001650static DH * ssl_sock_get_dh_from_file(const char *filename)
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001651{
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001652 DH *dh = NULL;
Remi Gacogne47783ef2015-05-29 15:53:22 +02001653 BIO *in = BIO_new(BIO_s_file());
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001654
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001655 if (in == NULL)
1656 goto end;
1657
Remi Gacogne47783ef2015-05-29 15:53:22 +02001658 if (BIO_read_filename(in, filename) <= 0)
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001659 goto end;
1660
Remi Gacogne47783ef2015-05-29 15:53:22 +02001661 dh = PEM_read_bio_DHparams(in, NULL, NULL, NULL);
1662
1663end:
1664 if (in)
1665 BIO_free(in);
1666
1667 return dh;
1668}
1669
1670int ssl_sock_load_global_dh_param_from_file(const char *filename)
1671{
1672 global_dh = ssl_sock_get_dh_from_file(filename);
1673
1674 if (global_dh) {
1675 return 0;
1676 }
1677
1678 return -1;
1679}
1680
1681/* Loads Diffie-Hellman parameter from a file. Returns 1 if loaded, else -1
1682 if an error occured, and 0 if parameter not found. */
1683int ssl_sock_load_dh_params(SSL_CTX *ctx, const char *file)
1684{
1685 int ret = -1;
1686 DH *dh = ssl_sock_get_dh_from_file(file);
1687
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001688 if (dh) {
1689 ret = 1;
1690 SSL_CTX_set_tmp_dh(ctx, dh);
Remi Gacogne4f902b82015-05-28 16:23:00 +02001691
1692 if (ssl_dh_ptr_index >= 0) {
1693 /* store a pointer to the DH params to avoid complaining about
1694 ssl-default-dh-param not being set for this SSL_CTX */
1695 SSL_CTX_set_ex_data(ctx, ssl_dh_ptr_index, dh);
1696 }
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001697 }
Remi Gacogne47783ef2015-05-29 15:53:22 +02001698 else if (global_dh) {
1699 SSL_CTX_set_tmp_dh(ctx, global_dh);
1700 ret = 0; /* DH params not found */
1701 }
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001702 else {
Emeric Brun41fdb3c2013-04-26 11:05:44 +02001703 /* Clear openssl global errors stack */
1704 ERR_clear_error();
1705
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001706 if (global.tune.ssl_default_dh_param <= 1024) {
1707 /* we are limited to DH parameter of 1024 bits anyway */
Remi Gacognec7e12632016-07-02 16:26:10 +02001708 if (local_dh_1024 == NULL)
1709 local_dh_1024 = ssl_get_dh_1024();
1710
Remi Gacogne8de54152014-07-15 11:36:40 +02001711 if (local_dh_1024 == NULL)
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001712 goto end;
Willy Tarreau6e774b42014-04-25 21:35:23 +02001713
Remi Gacogne8de54152014-07-15 11:36:40 +02001714 SSL_CTX_set_tmp_dh(ctx, local_dh_1024);
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001715 }
1716 else {
1717 SSL_CTX_set_tmp_dh_callback(ctx, ssl_get_tmp_dh);
1718 }
Willy Tarreau6e774b42014-04-25 21:35:23 +02001719
Emeric Brun41fdb3c2013-04-26 11:05:44 +02001720 ret = 0; /* DH params not found */
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001721 }
Emeric Brun644cde02012-12-14 11:21:13 +01001722
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001723end:
1724 if (dh)
1725 DH_free(dh);
1726
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001727 return ret;
1728}
1729#endif
1730
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001731static int ssl_sock_add_cert_sni(SSL_CTX *ctx, struct bind_conf *s, char *name, int order)
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001732{
1733 struct sni_ctx *sc;
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001734 int wild = 0, neg = 0;
Thierry FOURNIER / OZON.IO07c3d782016-10-06 10:56:48 +02001735 struct ebmb_node *node;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001736
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001737 if (*name == '!') {
1738 neg = 1;
1739 name++;
1740 }
1741 if (*name == '*') {
1742 wild = 1;
1743 name++;
1744 }
1745 /* !* filter is a nop */
1746 if (neg && wild)
1747 return order;
1748 if (*name) {
1749 int j, len;
1750 len = strlen(name);
Thierry FOURNIER / OZON.IO07c3d782016-10-06 10:56:48 +02001751 for (j = 0; j < len && j < trash.size; j++)
1752 trash.str[j] = tolower(name[j]);
1753 if (j >= trash.size)
1754 return order;
1755 trash.str[j] = 0;
1756
1757 /* Check for duplicates. */
1758 if (wild)
1759 node = ebst_lookup(&s->sni_w_ctx, trash.str);
1760 else
1761 node = ebst_lookup(&s->sni_ctx, trash.str);
1762 for (; node; node = ebmb_next_dup(node)) {
1763 sc = ebmb_entry(node, struct sni_ctx, name);
1764 if (sc->ctx == ctx && sc->neg == neg)
1765 return order;
1766 }
1767
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001768 sc = malloc(sizeof(struct sni_ctx) + len + 1);
Thierry FOURNIER / OZON.IO7a3bd3b2016-10-06 10:35:29 +02001769 if (!sc)
1770 return order;
Thierry FOURNIER / OZON.IO07c3d782016-10-06 10:56:48 +02001771 memcpy(sc->name.key, trash.str, len + 1);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001772 sc->ctx = ctx;
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001773 sc->order = order++;
1774 sc->neg = neg;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001775 if (wild)
1776 ebst_insert(&s->sni_w_ctx, &sc->name);
1777 else
1778 ebst_insert(&s->sni_ctx, &sc->name);
1779 }
1780 return order;
1781}
1782
yanbzhu488a4d22015-12-01 15:16:07 -05001783
1784/* The following code is used for loading multiple crt files into
1785 * SSL_CTX's based on CN/SAN
1786 */
1787#if OPENSSL_VERSION_NUMBER >= 0x1000200fL
1788/* This is used to preload the certifcate, private key
1789 * and Cert Chain of a file passed in via the crt
1790 * argument
1791 *
1792 * This way, we do not have to read the file multiple times
1793 */
1794struct cert_key_and_chain {
1795 X509 *cert;
1796 EVP_PKEY *key;
1797 unsigned int num_chain_certs;
1798 /* This is an array of X509 pointers */
1799 X509 **chain_certs;
1800};
1801
yanbzhu08ce6ab2015-12-02 13:01:29 -05001802#define SSL_SOCK_POSSIBLE_KT_COMBOS (1<<(SSL_SOCK_NUM_KEYTYPES))
1803
1804struct key_combo_ctx {
1805 SSL_CTX *ctx;
1806 int order;
1807};
1808
1809/* Map used for processing multiple keypairs for a single purpose
1810 *
1811 * This maps CN/SNI name to certificate type
1812 */
1813struct sni_keytype {
1814 int keytypes; /* BITMASK for keytypes */
1815 struct ebmb_node name; /* node holding the servername value */
1816};
1817
1818
yanbzhu488a4d22015-12-01 15:16:07 -05001819/* Frees the contents of a cert_key_and_chain
1820 */
1821static void ssl_sock_free_cert_key_and_chain_contents(struct cert_key_and_chain *ckch)
1822{
1823 int i;
1824
1825 if (!ckch)
1826 return;
1827
1828 /* Free the certificate and set pointer to NULL */
1829 if (ckch->cert)
1830 X509_free(ckch->cert);
1831 ckch->cert = NULL;
1832
1833 /* Free the key and set pointer to NULL */
1834 if (ckch->key)
1835 EVP_PKEY_free(ckch->key);
1836 ckch->key = NULL;
1837
1838 /* Free each certificate in the chain */
1839 for (i = 0; i < ckch->num_chain_certs; i++) {
1840 if (ckch->chain_certs[i])
1841 X509_free(ckch->chain_certs[i]);
1842 }
1843
1844 /* Free the chain obj itself and set to NULL */
1845 if (ckch->num_chain_certs > 0) {
1846 free(ckch->chain_certs);
1847 ckch->num_chain_certs = 0;
1848 ckch->chain_certs = NULL;
1849 }
1850
1851}
1852
1853/* checks if a key and cert exists in the ckch
1854 */
1855static int ssl_sock_is_ckch_valid(struct cert_key_and_chain *ckch)
1856{
1857 return (ckch->cert != NULL && ckch->key != NULL);
1858}
1859
1860
1861/* Loads the contents of a crt file (path) into a cert_key_and_chain
1862 * This allows us to carry the contents of the file without having to
1863 * read the file multiple times.
1864 *
1865 * returns:
1866 * 0 on Success
1867 * 1 on SSL Failure
1868 * 2 on file not found
1869 */
1870static int ssl_sock_load_crt_file_into_ckch(const char *path, struct cert_key_and_chain *ckch, char **err)
1871{
1872
1873 BIO *in;
1874 X509 *ca = NULL;
1875 int ret = 1;
1876
1877 ssl_sock_free_cert_key_and_chain_contents(ckch);
1878
1879 in = BIO_new(BIO_s_file());
1880 if (in == NULL)
1881 goto end;
1882
1883 if (BIO_read_filename(in, path) <= 0)
1884 goto end;
1885
yanbzhu488a4d22015-12-01 15:16:07 -05001886 /* Read Private Key */
1887 ckch->key = PEM_read_bio_PrivateKey(in, NULL, NULL, NULL);
1888 if (ckch->key == NULL) {
1889 memprintf(err, "%sunable to load private key from file '%s'.\n",
1890 err && *err ? *err : "", path);
1891 goto end;
1892 }
1893
Willy Tarreaubb137a82016-04-06 19:02:38 +02001894 /* Seek back to beginning of file */
Thierry FOURNIER / OZON.IOd44ea3f2016-10-14 00:49:21 +02001895 if (BIO_reset(in) == -1) {
1896 memprintf(err, "%san error occurred while reading the file '%s'.\n",
1897 err && *err ? *err : "", path);
1898 goto end;
1899 }
Willy Tarreaubb137a82016-04-06 19:02:38 +02001900
1901 /* Read Certificate */
1902 ckch->cert = PEM_read_bio_X509_AUX(in, NULL, NULL, NULL);
1903 if (ckch->cert == NULL) {
1904 memprintf(err, "%sunable to load certificate from file '%s'.\n",
1905 err && *err ? *err : "", path);
1906 goto end;
1907 }
1908
yanbzhu488a4d22015-12-01 15:16:07 -05001909 /* Read Certificate Chain */
1910 while ((ca = PEM_read_bio_X509(in, NULL, NULL, NULL))) {
1911 /* Grow the chain certs */
1912 ckch->num_chain_certs++;
1913 ckch->chain_certs = realloc(ckch->chain_certs, (ckch->num_chain_certs * sizeof(X509 *)));
1914
1915 /* use - 1 here since we just incremented it above */
1916 ckch->chain_certs[ckch->num_chain_certs - 1] = ca;
1917 }
1918 ret = ERR_get_error();
1919 if (ret && (ERR_GET_LIB(ret) != ERR_LIB_PEM && ERR_GET_REASON(ret) != PEM_R_NO_START_LINE)) {
1920 memprintf(err, "%sunable to load certificate chain from file '%s'.\n",
1921 err && *err ? *err : "", path);
1922 ret = 1;
1923 goto end;
1924 }
1925
1926 ret = 0;
1927
1928end:
1929
1930 ERR_clear_error();
1931 if (in)
1932 BIO_free(in);
1933
1934 /* Something went wrong in one of the reads */
1935 if (ret != 0)
1936 ssl_sock_free_cert_key_and_chain_contents(ckch);
1937
1938 return ret;
1939}
1940
1941/* Loads the info in ckch into ctx
1942 * Currently, this does not process any information about ocsp, dhparams or
1943 * sctl
1944 * Returns
1945 * 0 on success
1946 * 1 on failure
1947 */
1948static int ssl_sock_put_ckch_into_ctx(const char *path, const struct cert_key_and_chain *ckch, SSL_CTX *ctx, char **err)
1949{
1950 int i = 0;
1951
1952 if (SSL_CTX_use_PrivateKey(ctx, ckch->key) <= 0) {
1953 memprintf(err, "%sunable to load SSL private key into SSL Context '%s'.\n",
1954 err && *err ? *err : "", path);
1955 return 1;
1956 }
1957
1958 if (!SSL_CTX_use_certificate(ctx, ckch->cert)) {
1959 memprintf(err, "%sunable to load SSL certificate into SSL Context '%s'.\n",
1960 err && *err ? *err : "", path);
1961 return 1;
1962 }
1963
yanbzhu488a4d22015-12-01 15:16:07 -05001964 /* Load all certs in the ckch into the ctx_chain for the ssl_ctx */
1965 for (i = 0; i < ckch->num_chain_certs; i++) {
1966 if (!SSL_CTX_add1_chain_cert(ctx, ckch->chain_certs[i])) {
yanbzhu08ce6ab2015-12-02 13:01:29 -05001967 memprintf(err, "%sunable to load chain certificate #%d into SSL Context '%s'. Make sure you are linking against Openssl >= 1.0.2.\n",
1968 err && *err ? *err : "", (i+1), path);
yanbzhu488a4d22015-12-01 15:16:07 -05001969 return 1;
1970 }
1971 }
1972
1973 if (SSL_CTX_check_private_key(ctx) <= 0) {
1974 memprintf(err, "%sinconsistencies between private key and certificate loaded from PEM file '%s'.\n",
1975 err && *err ? *err : "", path);
1976 return 1;
1977 }
1978
1979 return 0;
1980}
1981
yanbzhu08ce6ab2015-12-02 13:01:29 -05001982
1983static void ssl_sock_populate_sni_keytypes_hplr(const char *str, struct eb_root *sni_keytypes, int key_index)
1984{
1985 struct sni_keytype *s_kt = NULL;
1986 struct ebmb_node *node;
1987 int i;
1988
1989 for (i = 0; i < trash.size; i++) {
1990 if (!str[i])
1991 break;
1992 trash.str[i] = tolower(str[i]);
1993 }
1994 trash.str[i] = 0;
1995 node = ebst_lookup(sni_keytypes, trash.str);
1996 if (!node) {
1997 /* CN not found in tree */
1998 s_kt = malloc(sizeof(struct sni_keytype) + i + 1);
1999 /* Using memcpy here instead of strncpy.
2000 * strncpy will cause sig_abrt errors under certain versions of gcc with -O2
2001 * See: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=60792
2002 */
2003 memcpy(s_kt->name.key, trash.str, i+1);
2004 s_kt->keytypes = 0;
2005 ebst_insert(sni_keytypes, &s_kt->name);
2006 } else {
2007 /* CN found in tree */
2008 s_kt = container_of(node, struct sni_keytype, name);
2009 }
2010
2011 /* Mark that this CN has the keytype of key_index via keytypes mask */
2012 s_kt->keytypes |= 1<<key_index;
2013
2014}
2015
2016
2017/* Given a path that does not exist, try to check for path.rsa, path.dsa and path.ecdsa files.
2018 * If any are found, group these files into a set of SSL_CTX*
2019 * based on shared and unique CN and SAN entries. Add these SSL_CTX* to the SNI tree.
2020 *
2021 * This will allow the user to explictly group multiple cert/keys for a single purpose
2022 *
2023 * Returns
2024 * 0 on success
2025 * 1 on failure
2026 */
Emmanuel Hocdetd294aea2016-05-13 11:14:06 +02002027static int ssl_sock_load_multi_cert(const char *path, struct bind_conf *bind_conf, struct proxy *curproxy, char **sni_filter, int fcount, char **err)
yanbzhu08ce6ab2015-12-02 13:01:29 -05002028{
2029 char fp[MAXPATHLEN+1] = {0};
2030 int n = 0;
2031 int i = 0;
2032 struct cert_key_and_chain certs_and_keys[SSL_SOCK_NUM_KEYTYPES] = { {0} };
2033 struct eb_root sni_keytypes_map = { {0} };
2034 struct ebmb_node *node;
2035 struct ebmb_node *next;
2036 /* Array of SSL_CTX pointers corresponding to each possible combo
2037 * of keytypes
2038 */
2039 struct key_combo_ctx key_combos[SSL_SOCK_POSSIBLE_KT_COMBOS] = { {0} };
2040 int rv = 0;
2041 X509_NAME *xname = NULL;
2042 char *str = NULL;
2043#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
2044 STACK_OF(GENERAL_NAME) *names = NULL;
2045#endif
2046
2047 /* Load all possible certs and keys */
2048 for (n = 0; n < SSL_SOCK_NUM_KEYTYPES; n++) {
2049 struct stat buf;
2050
2051 snprintf(fp, sizeof(fp), "%s.%s", path, SSL_SOCK_KEYTYPE_NAMES[n]);
2052 if (stat(fp, &buf) == 0) {
2053 if (ssl_sock_load_crt_file_into_ckch(fp, &certs_and_keys[n], err) == 1) {
2054 rv = 1;
2055 goto end;
2056 }
2057 }
2058 }
2059
2060 /* Process each ckch and update keytypes for each CN/SAN
2061 * for example, if CN/SAN www.a.com is associated with
2062 * certs with keytype 0 and 2, then at the end of the loop,
2063 * www.a.com will have:
2064 * keyindex = 0 | 1 | 4 = 5
2065 */
2066 for (n = 0; n < SSL_SOCK_NUM_KEYTYPES; n++) {
2067
2068 if (!ssl_sock_is_ckch_valid(&certs_and_keys[n]))
2069 continue;
2070
Emmanuel Hocdetd294aea2016-05-13 11:14:06 +02002071 if (fcount) {
Willy Tarreau24b892f2016-06-20 23:01:57 +02002072 for (i = 0; i < fcount; i++)
Emmanuel Hocdetd294aea2016-05-13 11:14:06 +02002073 ssl_sock_populate_sni_keytypes_hplr(sni_filter[i], &sni_keytypes_map, n);
2074 } else {
2075 /* A lot of the following code is OpenSSL boilerplate for processing CN's and SAN's,
2076 * so the line that contains logic is marked via comments
2077 */
2078 xname = X509_get_subject_name(certs_and_keys[n].cert);
2079 i = -1;
2080 while ((i = X509_NAME_get_index_by_NID(xname, NID_commonName, i)) != -1) {
2081 X509_NAME_ENTRY *entry = X509_NAME_get_entry(xname, i);
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02002082 ASN1_STRING *value;
2083 value = X509_NAME_ENTRY_get_data(entry);
2084 if (ASN1_STRING_to_UTF8((unsigned char **)&str, value) >= 0) {
Emmanuel Hocdetd294aea2016-05-13 11:14:06 +02002085 /* Important line is here */
2086 ssl_sock_populate_sni_keytypes_hplr(str, &sni_keytypes_map, n);
yanbzhu08ce6ab2015-12-02 13:01:29 -05002087
Emmanuel Hocdetd294aea2016-05-13 11:14:06 +02002088 OPENSSL_free(str);
2089 str = NULL;
2090 }
yanbzhu08ce6ab2015-12-02 13:01:29 -05002091 }
yanbzhu08ce6ab2015-12-02 13:01:29 -05002092
Emmanuel Hocdetd294aea2016-05-13 11:14:06 +02002093 /* Do the above logic for each SAN */
yanbzhu08ce6ab2015-12-02 13:01:29 -05002094#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Emmanuel Hocdetd294aea2016-05-13 11:14:06 +02002095 names = X509_get_ext_d2i(certs_and_keys[n].cert, NID_subject_alt_name, NULL, NULL);
2096 if (names) {
2097 for (i = 0; i < sk_GENERAL_NAME_num(names); i++) {
2098 GENERAL_NAME *name = sk_GENERAL_NAME_value(names, i);
yanbzhu08ce6ab2015-12-02 13:01:29 -05002099
Emmanuel Hocdetd294aea2016-05-13 11:14:06 +02002100 if (name->type == GEN_DNS) {
2101 if (ASN1_STRING_to_UTF8((unsigned char **)&str, name->d.dNSName) >= 0) {
2102 /* Important line is here */
2103 ssl_sock_populate_sni_keytypes_hplr(str, &sni_keytypes_map, n);
yanbzhu08ce6ab2015-12-02 13:01:29 -05002104
Emmanuel Hocdetd294aea2016-05-13 11:14:06 +02002105 OPENSSL_free(str);
2106 str = NULL;
2107 }
yanbzhu08ce6ab2015-12-02 13:01:29 -05002108 }
2109 }
2110 }
2111 }
2112#endif /* SSL_CTRL_SET_TLSEXT_HOSTNAME */
2113 }
2114
2115 /* If no files found, return error */
2116 if (eb_is_empty(&sni_keytypes_map)) {
2117 memprintf(err, "%sunable to load SSL certificate file '%s' file does not exist.\n",
2118 err && *err ? *err : "", path);
2119 rv = 1;
2120 goto end;
2121 }
2122
2123 /* We now have a map of CN/SAN to keytypes that are loaded in
2124 * Iterate through the map to create the SSL_CTX's (if needed)
2125 * and add each CTX to the SNI tree
2126 *
2127 * Some math here:
2128 * There are 2^n - 1 possibile combinations, each unique
2129 * combination is denoted by the key in the map. Each key
2130 * has a value between 1 and 2^n - 1. Conveniently, the array
2131 * of SSL_CTX* is sized 2^n. So, we can simply use the i'th
2132 * entry in the array to correspond to the unique combo (key)
2133 * associated with i. This unique key combo (i) will be associated
2134 * with combos[i-1]
2135 */
2136
2137 node = ebmb_first(&sni_keytypes_map);
2138 while (node) {
2139 SSL_CTX *cur_ctx;
Bertrand Jacquin33423092016-11-13 16:37:13 +00002140 char cur_file[MAXPATHLEN+1];
yanbzhu08ce6ab2015-12-02 13:01:29 -05002141
2142 str = (char *)container_of(node, struct sni_keytype, name)->name.key;
2143 i = container_of(node, struct sni_keytype, name)->keytypes;
2144 cur_ctx = key_combos[i-1].ctx;
2145
2146 if (cur_ctx == NULL) {
2147 /* need to create SSL_CTX */
2148 cur_ctx = SSL_CTX_new(SSLv23_server_method());
2149 if (cur_ctx == NULL) {
2150 memprintf(err, "%sunable to allocate SSL context.\n",
2151 err && *err ? *err : "");
2152 rv = 1;
2153 goto end;
2154 }
2155
yanbzhube2774d2015-12-10 15:07:30 -05002156 /* Load all required certs/keys/chains/OCSPs info into SSL_CTX */
yanbzhu08ce6ab2015-12-02 13:01:29 -05002157 for (n = 0; n < SSL_SOCK_NUM_KEYTYPES; n++) {
2158 if (i & (1<<n)) {
2159 /* Key combo contains ckch[n] */
Bertrand Jacquin33423092016-11-13 16:37:13 +00002160 snprintf(cur_file, MAXPATHLEN+1, "%s.%s", path, SSL_SOCK_KEYTYPE_NAMES[n]);
2161 if (ssl_sock_put_ckch_into_ctx(cur_file, &certs_and_keys[n], cur_ctx, err) != 0) {
yanbzhu08ce6ab2015-12-02 13:01:29 -05002162 SSL_CTX_free(cur_ctx);
2163 rv = 1;
2164 goto end;
2165 }
yanbzhube2774d2015-12-10 15:07:30 -05002166
2167#if (defined SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB && !defined OPENSSL_NO_OCSP)
2168 /* Load OCSP Info into context */
Bertrand Jacquin33423092016-11-13 16:37:13 +00002169 if (ssl_sock_load_ocsp(cur_ctx, cur_file) < 0) {
yanbzhube2774d2015-12-10 15:07:30 -05002170 if (err)
2171 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 +00002172 *err ? *err : "", cur_file);
yanbzhube2774d2015-12-10 15:07:30 -05002173 SSL_CTX_free(cur_ctx);
2174 rv = 1;
2175 goto end;
2176 }
2177#endif
yanbzhu08ce6ab2015-12-02 13:01:29 -05002178 }
2179 }
2180
2181 /* Load DH params into the ctx to support DHE keys */
2182#ifndef OPENSSL_NO_DH
2183 if (ssl_dh_ptr_index >= 0)
2184 SSL_CTX_set_ex_data(cur_ctx, ssl_dh_ptr_index, NULL);
2185
2186 rv = ssl_sock_load_dh_params(cur_ctx, NULL);
2187 if (rv < 0) {
2188 if (err)
2189 memprintf(err, "%sunable to load DH parameters from file '%s'.\n",
2190 *err ? *err : "", path);
2191 rv = 1;
2192 goto end;
2193 }
2194#endif
2195
2196 /* Update key_combos */
2197 key_combos[i-1].ctx = cur_ctx;
2198 }
2199
2200 /* Update SNI Tree */
Emmanuel Hocdetd294aea2016-05-13 11:14:06 +02002201 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 -05002202 node = ebmb_next(node);
2203 }
2204
2205
2206 /* Mark a default context if none exists, using the ctx that has the most shared keys */
2207 if (!bind_conf->default_ctx) {
2208 for (i = SSL_SOCK_POSSIBLE_KT_COMBOS - 1; i >= 0; i--) {
2209 if (key_combos[i].ctx) {
2210 bind_conf->default_ctx = key_combos[i].ctx;
2211 break;
2212 }
2213 }
2214 }
2215
2216end:
2217
2218 if (names)
2219 sk_GENERAL_NAME_pop_free(names, GENERAL_NAME_free);
2220
2221 for (n = 0; n < SSL_SOCK_NUM_KEYTYPES; n++)
2222 ssl_sock_free_cert_key_and_chain_contents(&certs_and_keys[n]);
2223
2224 node = ebmb_first(&sni_keytypes_map);
2225 while (node) {
2226 next = ebmb_next(node);
2227 ebmb_delete(node);
2228 node = next;
2229 }
2230
2231 return rv;
2232}
2233#else
2234/* This is a dummy, that just logs an error and returns error */
Emmanuel Hocdetd294aea2016-05-13 11:14:06 +02002235static int ssl_sock_load_multi_cert(const char *path, struct bind_conf *bind_conf, struct proxy *curproxy, char **sni_filter, int fcount, char **err)
yanbzhu08ce6ab2015-12-02 13:01:29 -05002236{
2237 memprintf(err, "%sunable to stat SSL certificate from file '%s' : %s.\n",
2238 err && *err ? *err : "", path, strerror(errno));
2239 return 1;
2240}
2241
yanbzhu488a4d22015-12-01 15:16:07 -05002242#endif /* #if OPENSSL_VERSION_NUMBER >= 0x1000200fL: Support for loading multiple certs into a single SSL_CTX */
2243
Emeric Brunfc0421f2012-09-07 17:30:07 +02002244/* Loads a certificate key and CA chain from a file. Returns 0 on error, -1 if
2245 * an early error happens and the caller must call SSL_CTX_free() by itelf.
2246 */
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02002247static 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 +02002248{
2249 BIO *in;
2250 X509 *x = NULL, *ca;
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02002251 int i, err;
Emeric Brunfc0421f2012-09-07 17:30:07 +02002252 int ret = -1;
2253 int order = 0;
2254 X509_NAME *xname;
2255 char *str;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02002256 pem_password_cb *passwd_cb;
2257 void *passwd_cb_userdata;
2258
Emeric Brunfc0421f2012-09-07 17:30:07 +02002259#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
2260 STACK_OF(GENERAL_NAME) *names;
2261#endif
2262
2263 in = BIO_new(BIO_s_file());
2264 if (in == NULL)
2265 goto end;
2266
2267 if (BIO_read_filename(in, file) <= 0)
2268 goto end;
2269
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02002270
2271 passwd_cb = SSL_CTX_get_default_passwd_cb(ctx);
2272 passwd_cb_userdata = SSL_CTX_get_default_passwd_cb_userdata(ctx);
2273
2274 x = PEM_read_bio_X509_AUX(in, NULL, passwd_cb, passwd_cb_userdata);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002275 if (x == NULL)
2276 goto end;
2277
Emeric Brun50bcecc2013-04-22 13:05:23 +02002278 if (fcount) {
2279 while (fcount--)
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02002280 order = ssl_sock_add_cert_sni(ctx, s, sni_filter[fcount], order);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002281 }
2282 else {
Emeric Brunfc0421f2012-09-07 17:30:07 +02002283#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002284 names = X509_get_ext_d2i(x, NID_subject_alt_name, NULL, NULL);
2285 if (names) {
2286 for (i = 0; i < sk_GENERAL_NAME_num(names); i++) {
2287 GENERAL_NAME *name = sk_GENERAL_NAME_value(names, i);
2288 if (name->type == GEN_DNS) {
2289 if (ASN1_STRING_to_UTF8((unsigned char **)&str, name->d.dNSName) >= 0) {
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02002290 order = ssl_sock_add_cert_sni(ctx, s, str, order);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002291 OPENSSL_free(str);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002292 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02002293 }
2294 }
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002295 sk_GENERAL_NAME_pop_free(names, GENERAL_NAME_free);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002296 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02002297#endif /* SSL_CTRL_SET_TLSEXT_HOSTNAME */
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002298 xname = X509_get_subject_name(x);
2299 i = -1;
2300 while ((i = X509_NAME_get_index_by_NID(xname, NID_commonName, i)) != -1) {
2301 X509_NAME_ENTRY *entry = X509_NAME_get_entry(xname, i);
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02002302 ASN1_STRING *value;
2303
2304 value = X509_NAME_ENTRY_get_data(entry);
2305 if (ASN1_STRING_to_UTF8((unsigned char **)&str, value) >= 0) {
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02002306 order = ssl_sock_add_cert_sni(ctx, s, str, order);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002307 OPENSSL_free(str);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002308 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02002309 }
2310 }
2311
2312 ret = 0; /* the caller must not free the SSL_CTX argument anymore */
2313 if (!SSL_CTX_use_certificate(ctx, x))
2314 goto end;
2315
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02002316#ifdef SSL_CTX_clear_extra_chain_certs
2317 SSL_CTX_clear_extra_chain_certs(ctx);
2318#else
Emeric Brunfc0421f2012-09-07 17:30:07 +02002319 if (ctx->extra_certs != NULL) {
2320 sk_X509_pop_free(ctx->extra_certs, X509_free);
2321 ctx->extra_certs = NULL;
2322 }
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02002323#endif
Emeric Brunfc0421f2012-09-07 17:30:07 +02002324
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02002325 while ((ca = PEM_read_bio_X509(in, NULL, passwd_cb, passwd_cb_userdata))) {
Emeric Brunfc0421f2012-09-07 17:30:07 +02002326 if (!SSL_CTX_add_extra_chain_cert(ctx, ca)) {
2327 X509_free(ca);
2328 goto end;
2329 }
2330 }
2331
2332 err = ERR_get_error();
2333 if (!err || (ERR_GET_LIB(err) == ERR_LIB_PEM && ERR_GET_REASON(err) == PEM_R_NO_START_LINE)) {
2334 /* we successfully reached the last cert in the file */
2335 ret = 1;
2336 }
2337 ERR_clear_error();
2338
2339end:
2340 if (x)
2341 X509_free(x);
2342
2343 if (in)
2344 BIO_free(in);
2345
2346 return ret;
2347}
2348
Emeric Brun50bcecc2013-04-22 13:05:23 +02002349static int ssl_sock_load_cert_file(const char *path, struct bind_conf *bind_conf, struct proxy *curproxy, char **sni_filter, int fcount, char **err)
Emeric Brunfc0421f2012-09-07 17:30:07 +02002350{
2351 int ret;
2352 SSL_CTX *ctx;
2353
2354 ctx = SSL_CTX_new(SSLv23_server_method());
2355 if (!ctx) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02002356 memprintf(err, "%sunable to allocate SSL context for cert '%s'.\n",
2357 err && *err ? *err : "", path);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002358 return 1;
2359 }
2360
2361 if (SSL_CTX_use_PrivateKey_file(ctx, path, SSL_FILETYPE_PEM) <= 0) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02002362 memprintf(err, "%sunable to load SSL private key from PEM file '%s'.\n",
2363 err && *err ? *err : "", path);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002364 SSL_CTX_free(ctx);
2365 return 1;
2366 }
2367
Emeric Brun50bcecc2013-04-22 13:05:23 +02002368 ret = ssl_sock_load_cert_chain_file(ctx, path, bind_conf, sni_filter, fcount);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002369 if (ret <= 0) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02002370 memprintf(err, "%sunable to load SSL certificate from PEM file '%s'.\n",
2371 err && *err ? *err : "", path);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002372 if (ret < 0) /* serious error, must do that ourselves */
2373 SSL_CTX_free(ctx);
2374 return 1;
2375 }
Emeric Brun61694ab2012-10-26 13:35:33 +02002376
2377 if (SSL_CTX_check_private_key(ctx) <= 0) {
2378 memprintf(err, "%sinconsistencies between private key and certificate loaded from PEM file '%s'.\n",
2379 err && *err ? *err : "", path);
2380 return 1;
2381 }
2382
Emeric Brunfc0421f2012-09-07 17:30:07 +02002383 /* we must not free the SSL_CTX anymore below, since it's already in
2384 * the tree, so it will be discovered and cleaned in time.
2385 */
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02002386#ifndef OPENSSL_NO_DH
Remi Gacogne4f902b82015-05-28 16:23:00 +02002387 /* store a NULL pointer to indicate we have not yet loaded
2388 a custom DH param file */
2389 if (ssl_dh_ptr_index >= 0) {
2390 SSL_CTX_set_ex_data(ctx, ssl_dh_ptr_index, NULL);
2391 }
2392
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02002393 ret = ssl_sock_load_dh_params(ctx, path);
2394 if (ret < 0) {
2395 if (err)
2396 memprintf(err, "%sunable to load DH parameters from file '%s'.\n",
2397 *err ? *err : "", path);
2398 return 1;
2399 }
2400#endif
2401
Lukas Tribuse4e30f72014-12-09 16:32:51 +01002402#if (defined SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB && !defined OPENSSL_NO_OCSP)
Emeric Brun4147b2e2014-06-16 18:36:30 +02002403 ret = ssl_sock_load_ocsp(ctx, path);
2404 if (ret < 0) {
2405 if (err)
2406 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",
2407 *err ? *err : "", path);
2408 return 1;
2409 }
2410#endif
2411
Daniel Jakots54ffb912015-11-06 20:02:41 +01002412#if (OPENSSL_VERSION_NUMBER >= 0x1000200fL && !defined OPENSSL_NO_TLSEXT && !defined OPENSSL_IS_BORINGSSL && !defined LIBRESSL_VERSION_NUMBER)
Janusz Dziemidowicz2c701b52015-03-07 23:03:59 +01002413 if (sctl_ex_index >= 0) {
2414 ret = ssl_sock_load_sctl(ctx, path);
2415 if (ret < 0) {
2416 if (err)
2417 memprintf(err, "%s '%s.sctl' is present but cannot be read or parsed'.\n",
2418 *err ? *err : "", path);
2419 return 1;
2420 }
2421 }
2422#endif
2423
Emeric Brunfc0421f2012-09-07 17:30:07 +02002424#ifndef SSL_CTRL_SET_TLSEXT_HOSTNAME
Willy Tarreau2a65ff02012-09-13 17:54:29 +02002425 if (bind_conf->default_ctx) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02002426 memprintf(err, "%sthis version of openssl cannot load multiple SSL certificates.\n",
2427 err && *err ? *err : "");
Emeric Brunfc0421f2012-09-07 17:30:07 +02002428 return 1;
2429 }
2430#endif
Willy Tarreau2a65ff02012-09-13 17:54:29 +02002431 if (!bind_conf->default_ctx)
2432 bind_conf->default_ctx = ctx;
Emeric Brunfc0421f2012-09-07 17:30:07 +02002433
2434 return 0;
2435}
2436
Willy Tarreau79eeafa2012-09-14 07:53:05 +02002437int ssl_sock_load_cert(char *path, struct bind_conf *bind_conf, struct proxy *curproxy, char **err)
Emeric Brunfc0421f2012-09-07 17:30:07 +02002438{
Cyril Bonté3180f7b2015-01-25 00:16:08 +01002439 struct dirent **de_list;
2440 int i, n;
Emeric Brunfc0421f2012-09-07 17:30:07 +02002441 DIR *dir;
2442 struct stat buf;
Willy Tarreauee2663b2012-12-06 11:36:59 +01002443 char *end;
2444 char fp[MAXPATHLEN+1];
Emeric Brunfc0421f2012-09-07 17:30:07 +02002445 int cfgerr = 0;
yanbzhu63ea8462015-12-09 13:35:14 -05002446#if OPENSSL_VERSION_NUMBER >= 0x1000200fL
2447 int is_bundle;
2448 int j;
2449#endif
Emeric Brunfc0421f2012-09-07 17:30:07 +02002450
yanbzhu08ce6ab2015-12-02 13:01:29 -05002451 if (stat(path, &buf) == 0) {
2452 dir = opendir(path);
2453 if (!dir)
2454 return ssl_sock_load_cert_file(path, bind_conf, curproxy, NULL, 0, err);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002455
yanbzhu08ce6ab2015-12-02 13:01:29 -05002456 /* strip trailing slashes, including first one */
2457 for (end = path + strlen(path) - 1; end >= path && *end == '/'; end--)
2458 *end = 0;
Emeric Brunfc0421f2012-09-07 17:30:07 +02002459
yanbzhu08ce6ab2015-12-02 13:01:29 -05002460 n = scandir(path, &de_list, 0, alphasort);
2461 if (n < 0) {
2462 memprintf(err, "%sunable to scan directory '%s' : %s.\n",
2463 err && *err ? *err : "", path, strerror(errno));
2464 cfgerr++;
2465 }
2466 else {
2467 for (i = 0; i < n; i++) {
2468 struct dirent *de = de_list[i];
Emeric Brun2aab7222014-06-18 18:15:09 +02002469
yanbzhu08ce6ab2015-12-02 13:01:29 -05002470 end = strrchr(de->d_name, '.');
2471 if (end && (!strcmp(end, ".issuer") || !strcmp(end, ".ocsp") || !strcmp(end, ".sctl")))
2472 goto ignore_entry;
Cyril Bonté3180f7b2015-01-25 00:16:08 +01002473
yanbzhu08ce6ab2015-12-02 13:01:29 -05002474 snprintf(fp, sizeof(fp), "%s/%s", path, de->d_name);
2475 if (stat(fp, &buf) != 0) {
2476 memprintf(err, "%sunable to stat SSL certificate from file '%s' : %s.\n",
2477 err && *err ? *err : "", fp, strerror(errno));
2478 cfgerr++;
2479 goto ignore_entry;
2480 }
2481 if (!S_ISREG(buf.st_mode))
2482 goto ignore_entry;
yanbzhu63ea8462015-12-09 13:35:14 -05002483
2484#if OPENSSL_VERSION_NUMBER >= 0x1000200fL
2485 is_bundle = 0;
2486 /* Check if current entry in directory is part of a multi-cert bundle */
2487
2488 if (end) {
2489 for (j = 0; j < SSL_SOCK_NUM_KEYTYPES; j++) {
2490 if (!strcmp(end + 1, SSL_SOCK_KEYTYPE_NAMES[j])) {
2491 is_bundle = 1;
2492 break;
2493 }
2494 }
2495
2496 if (is_bundle) {
2497 char dp[MAXPATHLEN+1] = {0}; /* this will be the filename w/o the keytype */
2498 int dp_len;
2499
2500 dp_len = end - de->d_name;
2501 snprintf(dp, dp_len + 1, "%s", de->d_name);
2502
2503 /* increment i and free de until we get to a non-bundle cert
2504 * Note here that we look at de_list[i + 1] before freeing de
2505 * this is important since ignore_entry will free de
2506 */
2507 while (i + 1 < n && !strncmp(de_list[i + 1]->d_name, dp, dp_len)) {
2508 free(de);
2509 i++;
2510 de = de_list[i];
2511 }
2512
2513 snprintf(fp, sizeof(fp), "%s/%s", path, dp);
Emmanuel Hocdetd294aea2016-05-13 11:14:06 +02002514 ssl_sock_load_multi_cert(fp, bind_conf, curproxy, NULL, 0, err);
yanbzhu63ea8462015-12-09 13:35:14 -05002515
2516 /* Successfully processed the bundle */
2517 goto ignore_entry;
2518 }
2519 }
2520
2521#endif
yanbzhu08ce6ab2015-12-02 13:01:29 -05002522 cfgerr += ssl_sock_load_cert_file(fp, bind_conf, curproxy, NULL, 0, err);
2523ignore_entry:
2524 free(de);
Cyril Bonté3180f7b2015-01-25 00:16:08 +01002525 }
yanbzhu08ce6ab2015-12-02 13:01:29 -05002526 free(de_list);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002527 }
yanbzhu08ce6ab2015-12-02 13:01:29 -05002528 closedir(dir);
2529 return cfgerr;
Emeric Brunfc0421f2012-09-07 17:30:07 +02002530 }
yanbzhu08ce6ab2015-12-02 13:01:29 -05002531
Emmanuel Hocdetd294aea2016-05-13 11:14:06 +02002532 cfgerr = ssl_sock_load_multi_cert(path, bind_conf, curproxy, NULL, 0, err);
yanbzhu08ce6ab2015-12-02 13:01:29 -05002533
Emeric Brunfc0421f2012-09-07 17:30:07 +02002534 return cfgerr;
2535}
2536
Thierry Fournier383085f2013-01-24 14:15:43 +01002537/* Make sure openssl opens /dev/urandom before the chroot. The work is only
2538 * done once. Zero is returned if the operation fails. No error is returned
2539 * if the random is said as not implemented, because we expect that openssl
2540 * will use another method once needed.
2541 */
2542static int ssl_initialize_random()
2543{
2544 unsigned char random;
2545 static int random_initialized = 0;
2546
2547 if (!random_initialized && RAND_bytes(&random, 1) != 0)
2548 random_initialized = 1;
2549
2550 return random_initialized;
2551}
2552
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002553int ssl_sock_load_cert_list_file(char *file, struct bind_conf *bind_conf, struct proxy *curproxy, char **err)
2554{
Emmanuel Hocdet5e0e6e42016-05-13 11:18:50 +02002555 char thisline[LINESIZE*CRTLIST_FACTOR];
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002556 FILE *f;
yanbzhu1b04e5b2015-12-02 13:54:14 -05002557 struct stat buf;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002558 int linenum = 0;
2559 int cfgerr = 0;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002560
Willy Tarreauad1731d2013-04-02 17:35:58 +02002561 if ((f = fopen(file, "r")) == NULL) {
2562 memprintf(err, "cannot open file '%s' : %s", file, strerror(errno));
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002563 return 1;
Willy Tarreauad1731d2013-04-02 17:35:58 +02002564 }
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002565
2566 while (fgets(thisline, sizeof(thisline), f) != NULL) {
2567 int arg;
Emeric Brun50bcecc2013-04-22 13:05:23 +02002568 int newarg;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002569 char *end;
Emmanuel Hocdet5e0e6e42016-05-13 11:18:50 +02002570 char *args[MAX_LINE_ARGS*CRTLIST_FACTOR + 1];
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002571 char *line = thisline;
2572
2573 linenum++;
2574 end = line + strlen(line);
2575 if (end-line == sizeof(thisline)-1 && *(end-1) != '\n') {
2576 /* Check if we reached the limit and the last char is not \n.
2577 * Watch out for the last line without the terminating '\n'!
2578 */
Willy Tarreauad1731d2013-04-02 17:35:58 +02002579 memprintf(err, "line %d too long in file '%s', limit is %d characters",
2580 linenum, file, (int)sizeof(thisline)-1);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002581 cfgerr = 1;
Willy Tarreauad1731d2013-04-02 17:35:58 +02002582 break;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002583 }
2584
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002585 arg = 0;
Emeric Brun50bcecc2013-04-22 13:05:23 +02002586 newarg = 1;
2587 while (*line) {
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002588 if (*line == '#' || *line == '\n' || *line == '\r') {
2589 /* end of string, end of loop */
2590 *line = 0;
2591 break;
2592 }
2593 else if (isspace(*line)) {
Emeric Brun50bcecc2013-04-22 13:05:23 +02002594 newarg = 1;
2595 *line = 0;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002596 }
Emeric Brun50bcecc2013-04-22 13:05:23 +02002597 else if (newarg) {
Emmanuel Hocdet5e0e6e42016-05-13 11:18:50 +02002598 if (arg == MAX_LINE_ARGS*CRTLIST_FACTOR) {
Emeric Brun50bcecc2013-04-22 13:05:23 +02002599 memprintf(err, "too many args on line %d in file '%s'.",
2600 linenum, file);
2601 cfgerr = 1;
2602 break;
2603 }
2604 newarg = 0;
2605 args[arg++] = line;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002606 }
Emeric Brun50bcecc2013-04-22 13:05:23 +02002607 line++;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002608 }
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02002609 if (cfgerr)
2610 break;
Willy Tarreauad1731d2013-04-02 17:35:58 +02002611
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002612 /* empty line */
Emeric Brun50bcecc2013-04-22 13:05:23 +02002613 if (!arg)
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002614 continue;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002615
yanbzhu1b04e5b2015-12-02 13:54:14 -05002616 if (stat(args[0], &buf) == 0) {
2617 cfgerr = ssl_sock_load_cert_file(args[0], bind_conf, curproxy, &args[1], arg-1, err);
2618 } else {
Emmanuel Hocdetd294aea2016-05-13 11:14:06 +02002619 cfgerr = ssl_sock_load_multi_cert(args[0], bind_conf, curproxy, &args[1], arg-1, err);
yanbzhu1b04e5b2015-12-02 13:54:14 -05002620 }
2621
Willy Tarreauad1731d2013-04-02 17:35:58 +02002622 if (cfgerr) {
2623 memprintf(err, "error processing line %d in file '%s' : %s", linenum, file, *err);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002624 break;
Willy Tarreauad1731d2013-04-02 17:35:58 +02002625 }
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002626 }
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002627 fclose(f);
2628 return cfgerr;
2629}
2630
Emeric Brunfc0421f2012-09-07 17:30:07 +02002631#ifndef SSL_OP_CIPHER_SERVER_PREFERENCE /* needs OpenSSL >= 0.9.7 */
2632#define SSL_OP_CIPHER_SERVER_PREFERENCE 0
2633#endif
2634
2635#ifndef SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION /* needs OpenSSL >= 0.9.7 */
2636#define SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION 0
Willy Tarreau7d588ee2012-11-26 18:47:31 +01002637#define SSL_renegotiate_pending(arg) 0
Emeric Brunfc0421f2012-09-07 17:30:07 +02002638#endif
Emeric Brun2b58d042012-09-20 17:10:03 +02002639#ifndef SSL_OP_SINGLE_ECDH_USE /* needs OpenSSL >= 0.9.8 */
2640#define SSL_OP_SINGLE_ECDH_USE 0
2641#endif
Emeric Brun2d0c4822012-10-02 13:45:20 +02002642#ifndef SSL_OP_NO_TICKET /* needs OpenSSL >= 0.9.8 */
2643#define SSL_OP_NO_TICKET 0
2644#endif
Emeric Brunfc0421f2012-09-07 17:30:07 +02002645#ifndef SSL_OP_NO_COMPRESSION /* needs OpenSSL >= 0.9.9 */
2646#define SSL_OP_NO_COMPRESSION 0
2647#endif
Emeric Brunc0ff4922012-09-28 19:37:02 +02002648#ifndef SSL_OP_NO_TLSv1_1 /* needs OpenSSL >= 1.0.1 */
2649#define SSL_OP_NO_TLSv1_1 0
2650#endif
2651#ifndef SSL_OP_NO_TLSv1_2 /* needs OpenSSL >= 1.0.1 */
2652#define SSL_OP_NO_TLSv1_2 0
2653#endif
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02002654#ifndef SSL_OP_SINGLE_DH_USE /* needs OpenSSL >= 0.9.6 */
2655#define SSL_OP_SINGLE_DH_USE 0
2656#endif
Emeric Brun2b58d042012-09-20 17:10:03 +02002657#ifndef SSL_OP_SINGLE_ECDH_USE /* needs OpenSSL >= 1.0.0 */
2658#define SSL_OP_SINGLE_ECDH_USE 0
2659#endif
Emeric Brunfc0421f2012-09-07 17:30:07 +02002660#ifndef SSL_MODE_RELEASE_BUFFERS /* needs OpenSSL >= 1.0.0 */
2661#define SSL_MODE_RELEASE_BUFFERS 0
2662#endif
Willy Tarreau396a1862014-11-13 14:06:52 +01002663#ifndef SSL_MODE_SMALL_BUFFERS /* needs small_records.patch */
2664#define SSL_MODE_SMALL_BUFFERS 0
2665#endif
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002666
Willy Tarreau2a65ff02012-09-13 17:54:29 +02002667int ssl_sock_prepare_ctx(struct bind_conf *bind_conf, SSL_CTX *ctx, struct proxy *curproxy)
Emeric Brunfc0421f2012-09-07 17:30:07 +02002668{
2669 int cfgerr = 0;
Emeric Brun850efd52014-01-29 12:24:34 +01002670 int verify = SSL_VERIFY_NONE;
Remi Gacogneaf5c3da2014-05-19 10:29:58 +02002671 long ssloptions =
Emeric Brunfc0421f2012-09-07 17:30:07 +02002672 SSL_OP_ALL | /* all known workarounds for bugs */
2673 SSL_OP_NO_SSLv2 |
2674 SSL_OP_NO_COMPRESSION |
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02002675 SSL_OP_SINGLE_DH_USE |
Emeric Brun2b58d042012-09-20 17:10:03 +02002676 SSL_OP_SINGLE_ECDH_USE |
Emeric Brun3c4bc6e2012-10-04 18:44:19 +02002677 SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION |
2678 SSL_OP_CIPHER_SERVER_PREFERENCE;
Remi Gacogneaf5c3da2014-05-19 10:29:58 +02002679 long sslmode =
Emeric Brunfc0421f2012-09-07 17:30:07 +02002680 SSL_MODE_ENABLE_PARTIAL_WRITE |
2681 SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER |
Willy Tarreau396a1862014-11-13 14:06:52 +01002682 SSL_MODE_RELEASE_BUFFERS |
2683 SSL_MODE_SMALL_BUFFERS;
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002684 STACK_OF(SSL_CIPHER) * ciphers = NULL;
Willy Tarreaua616ba62014-10-26 06:49:19 +01002685 SSL_CIPHER * cipher = NULL;
Remi Gacognec1eab8c2014-06-12 18:20:11 +02002686 char cipher_description[128];
2687 /* The description of ciphers using an Ephemeral Diffie Hellman key exchange
2688 contains " Kx=DH " or " Kx=DH(". Beware of " Kx=DH/",
2689 which is not ephemeral DH. */
2690 const char dhe_description[] = " Kx=DH ";
2691 const char dhe_export_description[] = " Kx=DH(";
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002692 int idx = 0;
2693 int dhe_found = 0;
Remi Gacogne23d5d372014-10-10 17:04:26 +02002694 SSL *ssl = NULL;
Emeric Brunfc0421f2012-09-07 17:30:07 +02002695
Thierry Fournier383085f2013-01-24 14:15:43 +01002696 /* Make sure openssl opens /dev/urandom before the chroot */
2697 if (!ssl_initialize_random()) {
2698 Alert("OpenSSL random data generator initialization failed.\n");
2699 cfgerr++;
2700 }
2701
Emeric Brun89675492012-10-05 13:48:26 +02002702 if (bind_conf->ssl_options & BC_SSL_O_NO_SSLV3)
Emeric Brunfc0421f2012-09-07 17:30:07 +02002703 ssloptions |= SSL_OP_NO_SSLv3;
Emeric Brun89675492012-10-05 13:48:26 +02002704 if (bind_conf->ssl_options & BC_SSL_O_NO_TLSV10)
Emeric Brunfc0421f2012-09-07 17:30:07 +02002705 ssloptions |= SSL_OP_NO_TLSv1;
Emeric Brun89675492012-10-05 13:48:26 +02002706 if (bind_conf->ssl_options & BC_SSL_O_NO_TLSV11)
Emeric Brunc0ff4922012-09-28 19:37:02 +02002707 ssloptions |= SSL_OP_NO_TLSv1_1;
Emeric Brun89675492012-10-05 13:48:26 +02002708 if (bind_conf->ssl_options & BC_SSL_O_NO_TLSV12)
Emeric Brunc0ff4922012-09-28 19:37:02 +02002709 ssloptions |= SSL_OP_NO_TLSv1_2;
Emeric Brun89675492012-10-05 13:48:26 +02002710 if (bind_conf->ssl_options & BC_SSL_O_NO_TLS_TICKETS)
Emeric Brun2d0c4822012-10-02 13:45:20 +02002711 ssloptions |= SSL_OP_NO_TICKET;
Jérémie Courrèges-Anglas17c3f622015-07-25 16:50:52 -06002712 if (bind_conf->ssl_options & BC_SSL_O_USE_SSLV3) {
2713#ifndef OPENSSL_NO_SSL3
Emeric Brun2cb7ae52012-10-05 14:14:21 +02002714 SSL_CTX_set_ssl_version(ctx, SSLv3_server_method());
Jérémie Courrèges-Anglas17c3f622015-07-25 16:50:52 -06002715#else
2716 Alert("SSLv3 support requested but unavailable.\n");
2717 cfgerr++;
2718#endif
2719 }
Emeric Brun2cb7ae52012-10-05 14:14:21 +02002720 if (bind_conf->ssl_options & BC_SSL_O_USE_TLSV10)
2721 SSL_CTX_set_ssl_version(ctx, TLSv1_server_method());
2722#if SSL_OP_NO_TLSv1_1
2723 if (bind_conf->ssl_options & BC_SSL_O_USE_TLSV11)
2724 SSL_CTX_set_ssl_version(ctx, TLSv1_1_server_method());
2725#endif
2726#if SSL_OP_NO_TLSv1_2
2727 if (bind_conf->ssl_options & BC_SSL_O_USE_TLSV12)
2728 SSL_CTX_set_ssl_version(ctx, TLSv1_2_server_method());
2729#endif
Emeric Brunfc0421f2012-09-07 17:30:07 +02002730
2731 SSL_CTX_set_options(ctx, ssloptions);
2732 SSL_CTX_set_mode(ctx, sslmode);
Emeric Brun850efd52014-01-29 12:24:34 +01002733 switch (bind_conf->verify) {
2734 case SSL_SOCK_VERIFY_NONE:
2735 verify = SSL_VERIFY_NONE;
2736 break;
2737 case SSL_SOCK_VERIFY_OPTIONAL:
2738 verify = SSL_VERIFY_PEER;
2739 break;
2740 case SSL_SOCK_VERIFY_REQUIRED:
2741 verify = SSL_VERIFY_PEER|SSL_VERIFY_FAIL_IF_NO_PEER_CERT;
2742 break;
2743 }
2744 SSL_CTX_set_verify(ctx, verify, ssl_sock_bind_verifycbk);
2745 if (verify & SSL_VERIFY_PEER) {
Emeric Brunfb510ea2012-10-05 12:00:26 +02002746 if (bind_conf->ca_file) {
Emeric Brund94b3fe2012-09-20 18:23:56 +02002747 /* load CAfile to verify */
Emeric Brunfb510ea2012-10-05 12:00:26 +02002748 if (!SSL_CTX_load_verify_locations(ctx, bind_conf->ca_file, NULL)) {
Emeric Brund94b3fe2012-09-20 18:23:56 +02002749 Alert("Proxy '%s': unable to load CA file '%s' for bind '%s' at [%s:%d].\n",
Emeric Brunfb510ea2012-10-05 12:00:26 +02002750 curproxy->id, bind_conf->ca_file, bind_conf->arg, bind_conf->file, bind_conf->line);
Emeric Brund94b3fe2012-09-20 18:23:56 +02002751 cfgerr++;
2752 }
2753 /* set CA names fo client cert request, function returns void */
Emeric Brunfb510ea2012-10-05 12:00:26 +02002754 SSL_CTX_set_client_CA_list(ctx, SSL_load_client_CA_file(bind_conf->ca_file));
Emeric Brund94b3fe2012-09-20 18:23:56 +02002755 }
Emeric Brun850efd52014-01-29 12:24:34 +01002756 else {
2757 Alert("Proxy '%s': verify is enabled but no CA file specified for bind '%s' at [%s:%d].\n",
2758 curproxy->id, bind_conf->arg, bind_conf->file, bind_conf->line);
2759 cfgerr++;
2760 }
Emeric Brun051cdab2012-10-02 19:25:50 +02002761#ifdef X509_V_FLAG_CRL_CHECK
Emeric Brunfb510ea2012-10-05 12:00:26 +02002762 if (bind_conf->crl_file) {
Emeric Brund94b3fe2012-09-20 18:23:56 +02002763 X509_STORE *store = SSL_CTX_get_cert_store(ctx);
2764
Emeric Brunfb510ea2012-10-05 12:00:26 +02002765 if (!store || !X509_STORE_load_locations(store, bind_conf->crl_file, NULL)) {
Emeric Brund94b3fe2012-09-20 18:23:56 +02002766 Alert("Proxy '%s': unable to configure CRL file '%s' for bind '%s' at [%s:%d].\n",
Alexander Rigbofc65af02015-04-07 14:02:16 +02002767 curproxy->id, bind_conf->crl_file, bind_conf->arg, bind_conf->file, bind_conf->line);
Emeric Brund94b3fe2012-09-20 18:23:56 +02002768 cfgerr++;
2769 }
Emeric Brun561e5742012-10-02 15:20:55 +02002770 else {
2771 X509_STORE_set_flags(store, X509_V_FLAG_CRL_CHECK|X509_V_FLAG_CRL_CHECK_ALL);
2772 }
Emeric Brund94b3fe2012-09-20 18:23:56 +02002773 }
Emeric Brun051cdab2012-10-02 19:25:50 +02002774#endif
Emeric Brun644cde02012-12-14 11:21:13 +01002775 ERR_clear_error();
Emeric Brund94b3fe2012-09-20 18:23:56 +02002776 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02002777
Nenad Merdanovic05552d42015-02-27 19:56:49 +01002778#if (defined SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB && TLS_TICKETS_NO > 0)
Nenad Merdanovic146defa2015-05-09 08:46:00 +02002779 if(bind_conf->keys_ref) {
Nenad Merdanovic05552d42015-02-27 19:56:49 +01002780 if (!SSL_CTX_set_tlsext_ticket_key_cb(ctx, ssl_tlsext_ticket_key_cb)) {
2781 Alert("Proxy '%s': unable to set callback for TLS ticket validation for bind '%s' at [%s:%d].\n",
2782 curproxy->id, bind_conf->arg, bind_conf->file, bind_conf->line);
2783 cfgerr++;
2784 }
2785 }
2786#endif
2787
Emeric Brun4f65bff2012-11-16 15:11:00 +01002788 if (global.tune.ssllifetime)
2789 SSL_CTX_set_timeout(ctx, global.tune.ssllifetime);
2790
Emeric Brunfc0421f2012-09-07 17:30:07 +02002791 shared_context_set_cache(ctx);
Willy Tarreau2a65ff02012-09-13 17:54:29 +02002792 if (bind_conf->ciphers &&
2793 !SSL_CTX_set_cipher_list(ctx, bind_conf->ciphers)) {
Emeric Brunfc0421f2012-09-07 17:30:07 +02002794 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 +02002795 curproxy->id, bind_conf->ciphers, bind_conf->arg, bind_conf->file, bind_conf->line);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002796 cfgerr++;
2797 }
2798
Remi Gacogne47783ef2015-05-29 15:53:22 +02002799 /* If tune.ssl.default-dh-param has not been set,
2800 neither has ssl-default-dh-file and no static DH
2801 params were in the certificate file. */
Remi Gacogne4f902b82015-05-28 16:23:00 +02002802 if (global.tune.ssl_default_dh_param == 0 &&
Remi Gacogne47783ef2015-05-29 15:53:22 +02002803 global_dh == NULL &&
Remi Gacogne4f902b82015-05-28 16:23:00 +02002804 (ssl_dh_ptr_index == -1 ||
2805 SSL_CTX_get_ex_data(ctx, ssl_dh_ptr_index) == NULL)) {
Lukas Tribus90132722014-08-18 00:56:33 +02002806
Remi Gacogne23d5d372014-10-10 17:04:26 +02002807 ssl = SSL_new(ctx);
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002808
Remi Gacogne23d5d372014-10-10 17:04:26 +02002809 if (ssl) {
2810 ciphers = SSL_get_ciphers(ssl);
2811
2812 if (ciphers) {
2813 for (idx = 0; idx < sk_SSL_CIPHER_num(ciphers); idx++) {
2814 cipher = sk_SSL_CIPHER_value(ciphers, idx);
2815 if (SSL_CIPHER_description(cipher, cipher_description, sizeof (cipher_description)) == cipher_description) {
2816 if (strstr(cipher_description, dhe_description) != NULL ||
2817 strstr(cipher_description, dhe_export_description) != NULL) {
2818 dhe_found = 1;
2819 break;
2820 }
Remi Gacognec1eab8c2014-06-12 18:20:11 +02002821 }
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002822 }
2823 }
Remi Gacogne23d5d372014-10-10 17:04:26 +02002824 SSL_free(ssl);
2825 ssl = NULL;
Lukas Tribus90132722014-08-18 00:56:33 +02002826 }
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002827
Lukas Tribus90132722014-08-18 00:56:33 +02002828 if (dhe_found) {
2829 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 +02002830 }
2831
2832 global.tune.ssl_default_dh_param = 1024;
2833 }
Remi Gacogne8de54152014-07-15 11:36:40 +02002834
2835#ifndef OPENSSL_NO_DH
2836 if (global.tune.ssl_default_dh_param >= 1024) {
2837 if (local_dh_1024 == NULL) {
2838 local_dh_1024 = ssl_get_dh_1024();
2839 }
2840 if (global.tune.ssl_default_dh_param >= 2048) {
2841 if (local_dh_2048 == NULL) {
2842 local_dh_2048 = ssl_get_dh_2048();
2843 }
2844 if (global.tune.ssl_default_dh_param >= 4096) {
2845 if (local_dh_4096 == NULL) {
2846 local_dh_4096 = ssl_get_dh_4096();
2847 }
Remi Gacogne8de54152014-07-15 11:36:40 +02002848 }
2849 }
2850 }
2851#endif /* OPENSSL_NO_DH */
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002852
Emeric Brunfc0421f2012-09-07 17:30:07 +02002853 SSL_CTX_set_info_callback(ctx, ssl_sock_infocbk);
Willy Tarreau5cbe4ef2014-05-08 22:45:11 +02002854#if OPENSSL_VERSION_NUMBER >= 0x00907000L
Emeric Brun29f037d2014-04-25 19:05:36 +02002855 SSL_CTX_set_msg_callback(ctx, ssl_sock_msgcbk);
Willy Tarreau5cbe4ef2014-05-08 22:45:11 +02002856#endif
Emeric Brun29f037d2014-04-25 19:05:36 +02002857
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02002858#ifdef OPENSSL_NPN_NEGOTIATED
2859 if (bind_conf->npn_str)
2860 SSL_CTX_set_next_protos_advertised_cb(ctx, ssl_sock_advertise_npn_protos, bind_conf);
2861#endif
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01002862#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Willy Tarreauab861d32013-04-02 02:30:41 +02002863 if (bind_conf->alpn_str)
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01002864 SSL_CTX_set_alpn_select_cb(ctx, ssl_sock_advertise_alpn_protos, bind_conf);
Willy Tarreauab861d32013-04-02 02:30:41 +02002865#endif
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02002866
Emeric Brunfc0421f2012-09-07 17:30:07 +02002867#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
2868 SSL_CTX_set_tlsext_servername_callback(ctx, ssl_sock_switchctx_cbk);
Willy Tarreau2a65ff02012-09-13 17:54:29 +02002869 SSL_CTX_set_tlsext_servername_arg(ctx, bind_conf);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002870#endif
Emeric Brun2b58d042012-09-20 17:10:03 +02002871#if defined(SSL_CTX_set_tmp_ecdh) && !defined(OPENSSL_NO_ECDH)
Emeric Brun6924ef82013-03-06 14:08:53 +01002872 {
Emeric Brun2b58d042012-09-20 17:10:03 +02002873 int i;
2874 EC_KEY *ecdh;
2875
Emeric Brun6924ef82013-03-06 14:08:53 +01002876 i = OBJ_sn2nid(bind_conf->ecdhe ? bind_conf->ecdhe : ECDHE_DEFAULT_CURVE);
Emeric Brun2b58d042012-09-20 17:10:03 +02002877 if (!i || ((ecdh = EC_KEY_new_by_curve_name(i)) == NULL)) {
2878 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 +01002879 curproxy->id, bind_conf->ecdhe ? bind_conf->ecdhe : ECDHE_DEFAULT_CURVE,
2880 bind_conf->arg, bind_conf->file, bind_conf->line);
Emeric Brun2b58d042012-09-20 17:10:03 +02002881 cfgerr++;
2882 }
2883 else {
2884 SSL_CTX_set_tmp_ecdh(ctx, ecdh);
2885 EC_KEY_free(ecdh);
2886 }
2887 }
2888#endif
2889
Emeric Brunfc0421f2012-09-07 17:30:07 +02002890 return cfgerr;
2891}
2892
Evan Broderbe554312013-06-27 00:05:25 -07002893static int ssl_sock_srv_hostcheck(const char *pattern, const char *hostname)
2894{
2895 const char *pattern_wildcard, *pattern_left_label_end, *hostname_left_label_end;
2896 size_t prefixlen, suffixlen;
2897
2898 /* Trivial case */
2899 if (strcmp(pattern, hostname) == 0)
2900 return 1;
2901
Evan Broderbe554312013-06-27 00:05:25 -07002902 /* The rest of this logic is based on RFC 6125, section 6.4.3
2903 * (http://tools.ietf.org/html/rfc6125#section-6.4.3) */
2904
Emeric Bruna848dae2013-10-08 11:27:28 +02002905 pattern_wildcard = NULL;
2906 pattern_left_label_end = pattern;
2907 while (*pattern_left_label_end != '.') {
2908 switch (*pattern_left_label_end) {
2909 case 0:
2910 /* End of label not found */
2911 return 0;
2912 case '*':
2913 /* If there is more than one wildcards */
2914 if (pattern_wildcard)
2915 return 0;
2916 pattern_wildcard = pattern_left_label_end;
2917 break;
2918 }
2919 pattern_left_label_end++;
2920 }
2921
2922 /* If it's not trivial and there is no wildcard, it can't
2923 * match */
2924 if (!pattern_wildcard)
Evan Broderbe554312013-06-27 00:05:25 -07002925 return 0;
2926
2927 /* Make sure all labels match except the leftmost */
2928 hostname_left_label_end = strchr(hostname, '.');
2929 if (!hostname_left_label_end
2930 || strcmp(pattern_left_label_end, hostname_left_label_end) != 0)
2931 return 0;
2932
2933 /* Make sure the leftmost label of the hostname is long enough
2934 * that the wildcard can match */
Emeric Brun369da852013-10-08 11:39:35 +02002935 if (hostname_left_label_end - hostname < (pattern_left_label_end - pattern) - 1)
Evan Broderbe554312013-06-27 00:05:25 -07002936 return 0;
2937
2938 /* Finally compare the string on either side of the
2939 * wildcard */
2940 prefixlen = pattern_wildcard - pattern;
2941 suffixlen = pattern_left_label_end - (pattern_wildcard + 1);
Emeric Bruna848dae2013-10-08 11:27:28 +02002942 if ((prefixlen && (memcmp(pattern, hostname, prefixlen) != 0))
2943 || (suffixlen && (memcmp(pattern_wildcard + 1, hostname_left_label_end - suffixlen, suffixlen) != 0)))
Evan Broderbe554312013-06-27 00:05:25 -07002944 return 0;
2945
2946 return 1;
2947}
2948
2949static int ssl_sock_srv_verifycbk(int ok, X509_STORE_CTX *ctx)
2950{
2951 SSL *ssl;
2952 struct connection *conn;
2953 char *servername;
2954
2955 int depth;
2956 X509 *cert;
2957 STACK_OF(GENERAL_NAME) *alt_names;
2958 int i;
2959 X509_NAME *cert_subject;
2960 char *str;
2961
2962 if (ok == 0)
2963 return ok;
2964
2965 ssl = X509_STORE_CTX_get_ex_data(ctx, SSL_get_ex_data_X509_STORE_CTX_idx());
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02002966 conn = SSL_get_app_data(ssl);
Evan Broderbe554312013-06-27 00:05:25 -07002967
2968 servername = objt_server(conn->target)->ssl_ctx.verify_host;
2969
2970 /* We only need to verify the CN on the actual server cert,
2971 * not the indirect CAs */
2972 depth = X509_STORE_CTX_get_error_depth(ctx);
2973 if (depth != 0)
2974 return ok;
2975
2976 /* At this point, the cert is *not* OK unless we can find a
2977 * hostname match */
2978 ok = 0;
2979
2980 cert = X509_STORE_CTX_get_current_cert(ctx);
2981 /* It seems like this might happen if verify peer isn't set */
2982 if (!cert)
2983 return ok;
2984
2985 alt_names = X509_get_ext_d2i(cert, NID_subject_alt_name, NULL, NULL);
2986 if (alt_names) {
2987 for (i = 0; !ok && i < sk_GENERAL_NAME_num(alt_names); i++) {
2988 GENERAL_NAME *name = sk_GENERAL_NAME_value(alt_names, i);
2989 if (name->type == GEN_DNS) {
Emeric Bruna33410c2013-09-17 15:47:48 +02002990#if OPENSSL_VERSION_NUMBER < 0x00907000L
2991 if (ASN1_STRING_to_UTF8((unsigned char **)&str, name->d.ia5) >= 0) {
2992#else
Evan Broderbe554312013-06-27 00:05:25 -07002993 if (ASN1_STRING_to_UTF8((unsigned char **)&str, name->d.dNSName) >= 0) {
Emeric Bruna33410c2013-09-17 15:47:48 +02002994#endif
Evan Broderbe554312013-06-27 00:05:25 -07002995 ok = ssl_sock_srv_hostcheck(str, servername);
2996 OPENSSL_free(str);
2997 }
2998 }
2999 }
Emeric Brun4ad50a42013-09-17 15:19:54 +02003000 sk_GENERAL_NAME_pop_free(alt_names, GENERAL_NAME_free);
Evan Broderbe554312013-06-27 00:05:25 -07003001 }
3002
3003 cert_subject = X509_get_subject_name(cert);
3004 i = -1;
3005 while (!ok && (i = X509_NAME_get_index_by_NID(cert_subject, NID_commonName, i)) != -1) {
3006 X509_NAME_ENTRY *entry = X509_NAME_get_entry(cert_subject, i);
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02003007 ASN1_STRING *value;
3008 value = X509_NAME_ENTRY_get_data(entry);
3009 if (ASN1_STRING_to_UTF8((unsigned char **)&str, value) >= 0) {
Evan Broderbe554312013-06-27 00:05:25 -07003010 ok = ssl_sock_srv_hostcheck(str, servername);
3011 OPENSSL_free(str);
3012 }
3013 }
3014
3015 return ok;
3016}
3017
Emeric Brun94324a42012-10-11 14:00:19 +02003018/* prepare ssl context from servers options. Returns an error count */
3019int ssl_sock_prepare_srv_ctx(struct server *srv, struct proxy *curproxy)
3020{
3021 int cfgerr = 0;
Remi Gacogneaf5c3da2014-05-19 10:29:58 +02003022 long options =
Emeric Brun94324a42012-10-11 14:00:19 +02003023 SSL_OP_ALL | /* all known workarounds for bugs */
3024 SSL_OP_NO_SSLv2 |
3025 SSL_OP_NO_COMPRESSION;
Remi Gacogneaf5c3da2014-05-19 10:29:58 +02003026 long mode =
Emeric Brun94324a42012-10-11 14:00:19 +02003027 SSL_MODE_ENABLE_PARTIAL_WRITE |
3028 SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER |
Willy Tarreau396a1862014-11-13 14:06:52 +01003029 SSL_MODE_RELEASE_BUFFERS |
3030 SSL_MODE_SMALL_BUFFERS;
Emeric Brun850efd52014-01-29 12:24:34 +01003031 int verify = SSL_VERIFY_NONE;
Emeric Brun94324a42012-10-11 14:00:19 +02003032
Thierry Fournier383085f2013-01-24 14:15:43 +01003033 /* Make sure openssl opens /dev/urandom before the chroot */
3034 if (!ssl_initialize_random()) {
3035 Alert("OpenSSL random data generator initialization failed.\n");
3036 cfgerr++;
3037 }
3038
Willy Tarreaufce03112015-01-15 21:32:40 +01003039 /* Automatic memory computations need to know we use SSL there */
3040 global.ssl_used_backend = 1;
3041
3042 /* Initiate SSL context for current server */
Emeric Brun94324a42012-10-11 14:00:19 +02003043 srv->ssl_ctx.reused_sess = NULL;
3044 if (srv->use_ssl)
3045 srv->xprt = &ssl_sock;
3046 if (srv->check.use_ssl)
Cyril Bonté9ce13112014-11-15 22:41:27 +01003047 srv->check.xprt = &ssl_sock;
Emeric Brun94324a42012-10-11 14:00:19 +02003048
3049 srv->ssl_ctx.ctx = SSL_CTX_new(SSLv23_client_method());
3050 if (!srv->ssl_ctx.ctx) {
3051 Alert("config : %s '%s', server '%s': unable to allocate ssl context.\n",
3052 proxy_type_str(curproxy), curproxy->id,
3053 srv->id);
3054 cfgerr++;
3055 return cfgerr;
3056 }
Emeric Bruna7aa3092012-10-26 12:58:00 +02003057 if (srv->ssl_ctx.client_crt) {
3058 if (SSL_CTX_use_PrivateKey_file(srv->ssl_ctx.ctx, srv->ssl_ctx.client_crt, SSL_FILETYPE_PEM) <= 0) {
3059 Alert("config : %s '%s', server '%s': unable to load SSL private key from PEM file '%s'.\n",
3060 proxy_type_str(curproxy), curproxy->id,
3061 srv->id, srv->ssl_ctx.client_crt);
3062 cfgerr++;
3063 }
3064 else if (SSL_CTX_use_certificate_chain_file(srv->ssl_ctx.ctx, srv->ssl_ctx.client_crt) <= 0) {
3065 Alert("config : %s '%s', server '%s': unable to load ssl certificate from PEM file '%s'.\n",
3066 proxy_type_str(curproxy), curproxy->id,
3067 srv->id, srv->ssl_ctx.client_crt);
3068 cfgerr++;
3069 }
3070 else if (SSL_CTX_check_private_key(srv->ssl_ctx.ctx) <= 0) {
3071 Alert("config : %s '%s', server '%s': inconsistencies between private key and certificate loaded from PEM file '%s'.\n",
3072 proxy_type_str(curproxy), curproxy->id,
3073 srv->id, srv->ssl_ctx.client_crt);
3074 cfgerr++;
3075 }
3076 }
Emeric Brun94324a42012-10-11 14:00:19 +02003077
3078 if (srv->ssl_ctx.options & SRV_SSL_O_NO_SSLV3)
3079 options |= SSL_OP_NO_SSLv3;
3080 if (srv->ssl_ctx.options & SRV_SSL_O_NO_TLSV10)
3081 options |= SSL_OP_NO_TLSv1;
3082 if (srv->ssl_ctx.options & SRV_SSL_O_NO_TLSV11)
3083 options |= SSL_OP_NO_TLSv1_1;
3084 if (srv->ssl_ctx.options & SRV_SSL_O_NO_TLSV12)
3085 options |= SSL_OP_NO_TLSv1_2;
Emeric Brunf9c5c472012-10-11 15:28:34 +02003086 if (srv->ssl_ctx.options & SRV_SSL_O_NO_TLS_TICKETS)
3087 options |= SSL_OP_NO_TICKET;
Jérémie Courrèges-Anglas17c3f622015-07-25 16:50:52 -06003088 if (srv->ssl_ctx.options & SRV_SSL_O_USE_SSLV3) {
3089#ifndef OPENSSL_NO_SSL3
Emeric Brun94324a42012-10-11 14:00:19 +02003090 SSL_CTX_set_ssl_version(srv->ssl_ctx.ctx, SSLv3_client_method());
Jérémie Courrèges-Anglas17c3f622015-07-25 16:50:52 -06003091#else
Thierry FOURNIERbc965342015-08-26 08:21:26 +02003092 Alert("SSLv3 support requested but unavailable.\n");
Jérémie Courrèges-Anglas17c3f622015-07-25 16:50:52 -06003093 cfgerr++;
3094#endif
3095 }
Emeric Brun94324a42012-10-11 14:00:19 +02003096 if (srv->ssl_ctx.options & SRV_SSL_O_USE_TLSV10)
3097 SSL_CTX_set_ssl_version(srv->ssl_ctx.ctx, TLSv1_client_method());
3098#if SSL_OP_NO_TLSv1_1
3099 if (srv->ssl_ctx.options & SRV_SSL_O_USE_TLSV11)
3100 SSL_CTX_set_ssl_version(srv->ssl_ctx.ctx, TLSv1_1_client_method());
3101#endif
3102#if SSL_OP_NO_TLSv1_2
3103 if (srv->ssl_ctx.options & SRV_SSL_O_USE_TLSV12)
3104 SSL_CTX_set_ssl_version(srv->ssl_ctx.ctx, TLSv1_2_client_method());
3105#endif
3106
3107 SSL_CTX_set_options(srv->ssl_ctx.ctx, options);
3108 SSL_CTX_set_mode(srv->ssl_ctx.ctx, mode);
Emeric Brun850efd52014-01-29 12:24:34 +01003109
3110 if (global.ssl_server_verify == SSL_SERVER_VERIFY_REQUIRED)
3111 verify = SSL_VERIFY_PEER;
3112
3113 switch (srv->ssl_ctx.verify) {
3114 case SSL_SOCK_VERIFY_NONE:
3115 verify = SSL_VERIFY_NONE;
3116 break;
3117 case SSL_SOCK_VERIFY_REQUIRED:
3118 verify = SSL_VERIFY_PEER;
3119 break;
3120 }
Evan Broderbe554312013-06-27 00:05:25 -07003121 SSL_CTX_set_verify(srv->ssl_ctx.ctx,
Emeric Brun850efd52014-01-29 12:24:34 +01003122 verify,
Evan Broderbe554312013-06-27 00:05:25 -07003123 srv->ssl_ctx.verify_host ? ssl_sock_srv_verifycbk : NULL);
Emeric Brun850efd52014-01-29 12:24:34 +01003124 if (verify & SSL_VERIFY_PEER) {
Emeric Brunef42d922012-10-11 16:11:36 +02003125 if (srv->ssl_ctx.ca_file) {
3126 /* load CAfile to verify */
3127 if (!SSL_CTX_load_verify_locations(srv->ssl_ctx.ctx, srv->ssl_ctx.ca_file, NULL)) {
Willy Tarreau07ba08b2014-02-16 19:22:08 +01003128 Alert("Proxy '%s', server '%s' [%s:%d] unable to load CA file '%s'.\n",
Emeric Brunef42d922012-10-11 16:11:36 +02003129 curproxy->id, srv->id,
3130 srv->conf.file, srv->conf.line, srv->ssl_ctx.ca_file);
3131 cfgerr++;
3132 }
3133 }
Emeric Brun850efd52014-01-29 12:24:34 +01003134 else {
3135 if (global.ssl_server_verify == SSL_SERVER_VERIFY_REQUIRED)
Willy Tarreau07ba08b2014-02-16 19:22:08 +01003136 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 +01003137 curproxy->id, srv->id,
3138 srv->conf.file, srv->conf.line);
3139 else
Willy Tarreau07ba08b2014-02-16 19:22:08 +01003140 Alert("Proxy '%s', server '%s' [%s:%d] verify is enabled but no CA file specified.\n",
Emeric Brun850efd52014-01-29 12:24:34 +01003141 curproxy->id, srv->id,
3142 srv->conf.file, srv->conf.line);
3143 cfgerr++;
3144 }
Emeric Brunef42d922012-10-11 16:11:36 +02003145#ifdef X509_V_FLAG_CRL_CHECK
3146 if (srv->ssl_ctx.crl_file) {
3147 X509_STORE *store = SSL_CTX_get_cert_store(srv->ssl_ctx.ctx);
3148
3149 if (!store || !X509_STORE_load_locations(store, srv->ssl_ctx.crl_file, NULL)) {
Willy Tarreau07ba08b2014-02-16 19:22:08 +01003150 Alert("Proxy '%s', server '%s' [%s:%d] unable to configure CRL file '%s'.\n",
Emeric Brunef42d922012-10-11 16:11:36 +02003151 curproxy->id, srv->id,
3152 srv->conf.file, srv->conf.line, srv->ssl_ctx.crl_file);
3153 cfgerr++;
3154 }
3155 else {
3156 X509_STORE_set_flags(store, X509_V_FLAG_CRL_CHECK|X509_V_FLAG_CRL_CHECK_ALL);
3157 }
3158 }
3159#endif
3160 }
3161
Emeric Brun4f65bff2012-11-16 15:11:00 +01003162 if (global.tune.ssllifetime)
3163 SSL_CTX_set_timeout(srv->ssl_ctx.ctx, global.tune.ssllifetime);
3164
Emeric Brun94324a42012-10-11 14:00:19 +02003165 SSL_CTX_set_session_cache_mode(srv->ssl_ctx.ctx, SSL_SESS_CACHE_OFF);
3166 if (srv->ssl_ctx.ciphers &&
3167 !SSL_CTX_set_cipher_list(srv->ssl_ctx.ctx, srv->ssl_ctx.ciphers)) {
3168 Alert("Proxy '%s', server '%s' [%s:%d] : unable to set SSL cipher list to '%s'.\n",
3169 curproxy->id, srv->id,
3170 srv->conf.file, srv->conf.line, srv->ssl_ctx.ciphers);
3171 cfgerr++;
3172 }
3173
3174 return cfgerr;
3175}
3176
Willy Tarreau2a65ff02012-09-13 17:54:29 +02003177/* Walks down the two trees in bind_conf and prepares all certs. The pointer may
Emeric Brunfc0421f2012-09-07 17:30:07 +02003178 * be NULL, in which case nothing is done. Returns the number of errors
3179 * encountered.
3180 */
Willy Tarreau2a65ff02012-09-13 17:54:29 +02003181int ssl_sock_prepare_all_ctx(struct bind_conf *bind_conf, struct proxy *px)
Emeric Brunfc0421f2012-09-07 17:30:07 +02003182{
3183 struct ebmb_node *node;
3184 struct sni_ctx *sni;
3185 int err = 0;
3186
Willy Tarreau2a65ff02012-09-13 17:54:29 +02003187 if (!bind_conf || !bind_conf->is_ssl)
Emeric Brunfc0421f2012-09-07 17:30:07 +02003188 return 0;
3189
Willy Tarreaufce03112015-01-15 21:32:40 +01003190 /* Automatic memory computations need to know we use SSL there */
3191 global.ssl_used_frontend = 1;
3192
Emeric Brun0bed9942014-10-30 19:25:24 +01003193 if (bind_conf->default_ctx)
3194 err += ssl_sock_prepare_ctx(bind_conf, bind_conf->default_ctx, px);
3195
Willy Tarreau2a65ff02012-09-13 17:54:29 +02003196 node = ebmb_first(&bind_conf->sni_ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02003197 while (node) {
3198 sni = ebmb_entry(node, struct sni_ctx, name);
Emeric Brun0bed9942014-10-30 19:25:24 +01003199 if (!sni->order && sni->ctx != bind_conf->default_ctx)
3200 /* only initialize the CTX on its first occurrence and
3201 if it is not the default_ctx */
Willy Tarreau2a65ff02012-09-13 17:54:29 +02003202 err += ssl_sock_prepare_ctx(bind_conf, sni->ctx, px);
Emeric Brunfc0421f2012-09-07 17:30:07 +02003203 node = ebmb_next(node);
3204 }
3205
Willy Tarreau2a65ff02012-09-13 17:54:29 +02003206 node = ebmb_first(&bind_conf->sni_w_ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02003207 while (node) {
3208 sni = ebmb_entry(node, struct sni_ctx, name);
Emeric Brun0bed9942014-10-30 19:25:24 +01003209 if (!sni->order && sni->ctx != bind_conf->default_ctx)
3210 /* only initialize the CTX on its first occurrence and
3211 if it is not the default_ctx */
Willy Tarreau2a65ff02012-09-13 17:54:29 +02003212 err += ssl_sock_prepare_ctx(bind_conf, sni->ctx, px);
Emeric Brunfc0421f2012-09-07 17:30:07 +02003213 node = ebmb_next(node);
3214 }
3215 return err;
3216}
3217
Christopher Faulet77fe80c2015-07-29 13:02:40 +02003218
3219/* release ssl context allocated for servers. */
3220void ssl_sock_free_srv_ctx(struct server *srv)
3221{
3222 if (srv->ssl_ctx.ctx)
3223 SSL_CTX_free(srv->ssl_ctx.ctx);
3224}
3225
Willy Tarreau2a65ff02012-09-13 17:54:29 +02003226/* Walks down the two trees in bind_conf and frees all the certs. The pointer may
Emeric Brunfc0421f2012-09-07 17:30:07 +02003227 * be NULL, in which case nothing is done. The default_ctx is nullified too.
3228 */
Willy Tarreau2a65ff02012-09-13 17:54:29 +02003229void ssl_sock_free_all_ctx(struct bind_conf *bind_conf)
Emeric Brunfc0421f2012-09-07 17:30:07 +02003230{
3231 struct ebmb_node *node, *back;
3232 struct sni_ctx *sni;
3233
Willy Tarreau2a65ff02012-09-13 17:54:29 +02003234 if (!bind_conf || !bind_conf->is_ssl)
Emeric Brunfc0421f2012-09-07 17:30:07 +02003235 return;
3236
Willy Tarreau2a65ff02012-09-13 17:54:29 +02003237 node = ebmb_first(&bind_conf->sni_ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02003238 while (node) {
3239 sni = ebmb_entry(node, struct sni_ctx, name);
3240 back = ebmb_next(node);
3241 ebmb_delete(node);
3242 if (!sni->order) /* only free the CTX on its first occurrence */
3243 SSL_CTX_free(sni->ctx);
3244 free(sni);
3245 node = back;
3246 }
3247
Willy Tarreau2a65ff02012-09-13 17:54:29 +02003248 node = ebmb_first(&bind_conf->sni_w_ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02003249 while (node) {
3250 sni = ebmb_entry(node, struct sni_ctx, name);
3251 back = ebmb_next(node);
3252 ebmb_delete(node);
3253 if (!sni->order) /* only free the CTX on its first occurrence */
3254 SSL_CTX_free(sni->ctx);
3255 free(sni);
3256 node = back;
3257 }
3258
Willy Tarreau2a65ff02012-09-13 17:54:29 +02003259 bind_conf->default_ctx = NULL;
Emeric Brune1f38db2012-09-03 20:36:47 +02003260}
3261
Christopher Faulet31af49d2015-06-09 17:29:50 +02003262/* Load CA cert file and private key used to generate certificates */
3263int
3264ssl_sock_load_ca(struct bind_conf *bind_conf, struct proxy *px)
3265{
3266 FILE *fp;
3267 X509 *cacert = NULL;
3268 EVP_PKEY *capkey = NULL;
3269 int err = 0;
3270
3271 if (!bind_conf || !bind_conf->generate_certs)
3272 return err;
3273
Willy Tarreaua84c2672015-10-09 12:10:13 +02003274#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Christopher Fauletd2cab922015-07-28 16:03:47 +02003275 if (global.tune.ssl_ctx_cache)
3276 ssl_ctx_lru_tree = lru64_new(global.tune.ssl_ctx_cache);
3277 ssl_ctx_lru_seed = (unsigned int)time(NULL);
Willy Tarreaua84c2672015-10-09 12:10:13 +02003278#endif
Christopher Fauletd2cab922015-07-28 16:03:47 +02003279
Christopher Faulet31af49d2015-06-09 17:29:50 +02003280 if (!bind_conf->ca_sign_file) {
3281 Alert("Proxy '%s': cannot enable certificate generation, "
3282 "no CA certificate File configured at [%s:%d].\n",
3283 px->id, bind_conf->file, bind_conf->line);
Christopher Faulet31af49d2015-06-09 17:29:50 +02003284 goto load_error;
Christopher Fauletc6f02fb2015-10-09 10:53:31 +02003285 }
Christopher Faulet31af49d2015-06-09 17:29:50 +02003286
3287 /* read in the CA certificate */
3288 if (!(fp = fopen(bind_conf->ca_sign_file, "r"))) {
3289 Alert("Proxy '%s': Failed to read CA certificate file '%s' at [%s:%d].\n",
3290 px->id, bind_conf->ca_sign_file, bind_conf->file, bind_conf->line);
Christopher Faulet31af49d2015-06-09 17:29:50 +02003291 goto load_error;
3292 }
3293 if (!(cacert = PEM_read_X509(fp, NULL, NULL, NULL))) {
3294 Alert("Proxy '%s': Failed to read CA certificate file '%s' at [%s:%d].\n",
3295 px->id, bind_conf->ca_sign_file, bind_conf->file, bind_conf->line);
Christopher Fauletc6f02fb2015-10-09 10:53:31 +02003296 goto read_error;
Christopher Faulet31af49d2015-06-09 17:29:50 +02003297 }
Christopher Fauletc6f02fb2015-10-09 10:53:31 +02003298 rewind(fp);
Christopher Faulet31af49d2015-06-09 17:29:50 +02003299 if (!(capkey = PEM_read_PrivateKey(fp, NULL, NULL, bind_conf->ca_sign_pass))) {
3300 Alert("Proxy '%s': Failed to read CA private key file '%s' at [%s:%d].\n",
3301 px->id, bind_conf->ca_sign_file, bind_conf->file, bind_conf->line);
Christopher Fauletc6f02fb2015-10-09 10:53:31 +02003302 goto read_error;
Christopher Faulet31af49d2015-06-09 17:29:50 +02003303 }
Christopher Faulet31af49d2015-06-09 17:29:50 +02003304
Christopher Fauletc6f02fb2015-10-09 10:53:31 +02003305 fclose (fp);
Christopher Faulet31af49d2015-06-09 17:29:50 +02003306 bind_conf->ca_sign_cert = cacert;
3307 bind_conf->ca_sign_pkey = capkey;
3308 return err;
3309
Christopher Fauletc6f02fb2015-10-09 10:53:31 +02003310 read_error:
3311 fclose (fp);
Christopher Faulet31af49d2015-06-09 17:29:50 +02003312 if (capkey) EVP_PKEY_free(capkey);
3313 if (cacert) X509_free(cacert);
Christopher Fauletc6f02fb2015-10-09 10:53:31 +02003314 load_error:
3315 bind_conf->generate_certs = 0;
3316 err++;
Christopher Faulet31af49d2015-06-09 17:29:50 +02003317 return err;
3318}
3319
3320/* Release CA cert and private key used to generate certificated */
3321void
3322ssl_sock_free_ca(struct bind_conf *bind_conf)
3323{
3324 if (!bind_conf)
3325 return;
3326
3327 if (bind_conf->ca_sign_pkey)
3328 EVP_PKEY_free(bind_conf->ca_sign_pkey);
3329 if (bind_conf->ca_sign_cert)
3330 X509_free(bind_conf->ca_sign_cert);
3331}
3332
Emeric Brun46591952012-05-18 15:47:34 +02003333/*
3334 * This function is called if SSL * context is not yet allocated. The function
3335 * is designed to be called before any other data-layer operation and sets the
3336 * handshake flag on the connection. It is safe to call it multiple times.
3337 * It returns 0 on success and -1 in error case.
3338 */
3339static int ssl_sock_init(struct connection *conn)
3340{
3341 /* already initialized */
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02003342 if (conn->xprt_ctx)
Emeric Brun46591952012-05-18 15:47:34 +02003343 return 0;
3344
Willy Tarreau3c728722014-01-23 13:50:42 +01003345 if (!conn_ctrl_ready(conn))
Willy Tarreauf79c8172013-10-21 16:30:56 +02003346 return 0;
3347
Willy Tarreau20879a02012-12-03 16:32:10 +01003348 if (global.maxsslconn && sslconns >= global.maxsslconn) {
3349 conn->err_code = CO_ER_SSL_TOO_MANY;
Willy Tarreau403edff2012-09-06 11:58:37 +02003350 return -1;
Willy Tarreau20879a02012-12-03 16:32:10 +01003351 }
Willy Tarreau403edff2012-09-06 11:58:37 +02003352
Emeric Brun46591952012-05-18 15:47:34 +02003353 /* If it is in client mode initiate SSL session
3354 in connect state otherwise accept state */
Willy Tarreau3fdb3662012-11-12 00:42:33 +01003355 if (objt_server(conn->target)) {
Willy Tarreaufba03cd2014-11-13 13:48:58 +01003356 int may_retry = 1;
3357
3358 retry_connect:
Emeric Brun46591952012-05-18 15:47:34 +02003359 /* Alloc a new SSL session ctx */
Willy Tarreau3fdb3662012-11-12 00:42:33 +01003360 conn->xprt_ctx = SSL_new(objt_server(conn->target)->ssl_ctx.ctx);
Willy Tarreau20879a02012-12-03 16:32:10 +01003361 if (!conn->xprt_ctx) {
Willy Tarreaufba03cd2014-11-13 13:48:58 +01003362 if (may_retry--) {
3363 pool_gc2();
3364 goto retry_connect;
3365 }
Willy Tarreau20879a02012-12-03 16:32:10 +01003366 conn->err_code = CO_ER_SSL_NO_MEM;
Emeric Brun46591952012-05-18 15:47:34 +02003367 return -1;
Willy Tarreau20879a02012-12-03 16:32:10 +01003368 }
Emeric Brun46591952012-05-18 15:47:34 +02003369
Emeric Brun46591952012-05-18 15:47:34 +02003370 /* set fd on SSL session context */
Emeric Brun55476152014-11-12 17:35:37 +01003371 if (!SSL_set_fd(conn->xprt_ctx, conn->t.sock.fd)) {
3372 SSL_free(conn->xprt_ctx);
3373 conn->xprt_ctx = NULL;
Willy Tarreaufba03cd2014-11-13 13:48:58 +01003374 if (may_retry--) {
3375 pool_gc2();
3376 goto retry_connect;
3377 }
Emeric Brun55476152014-11-12 17:35:37 +01003378 conn->err_code = CO_ER_SSL_NO_MEM;
3379 return -1;
3380 }
Emeric Brun46591952012-05-18 15:47:34 +02003381
Evan Broderbe554312013-06-27 00:05:25 -07003382 /* set connection pointer */
Emeric Brun55476152014-11-12 17:35:37 +01003383 if (!SSL_set_app_data(conn->xprt_ctx, conn)) {
3384 SSL_free(conn->xprt_ctx);
3385 conn->xprt_ctx = NULL;
Willy Tarreaufba03cd2014-11-13 13:48:58 +01003386 if (may_retry--) {
3387 pool_gc2();
3388 goto retry_connect;
3389 }
Emeric Brun55476152014-11-12 17:35:37 +01003390 conn->err_code = CO_ER_SSL_NO_MEM;
3391 return -1;
3392 }
3393
3394 SSL_set_connect_state(conn->xprt_ctx);
3395 if (objt_server(conn->target)->ssl_ctx.reused_sess) {
3396 if(!SSL_set_session(conn->xprt_ctx, objt_server(conn->target)->ssl_ctx.reused_sess)) {
3397 SSL_SESSION_free(objt_server(conn->target)->ssl_ctx.reused_sess);
3398 objt_server(conn->target)->ssl_ctx.reused_sess = NULL;
3399 }
3400 }
Evan Broderbe554312013-06-27 00:05:25 -07003401
Emeric Brun46591952012-05-18 15:47:34 +02003402 /* leave init state and start handshake */
Willy Tarreau05737472012-09-04 08:03:39 +02003403 conn->flags |= CO_FL_SSL_WAIT_HS | CO_FL_WAIT_L6_CONN;
Willy Tarreau403edff2012-09-06 11:58:37 +02003404
3405 sslconns++;
Willy Tarreau71b734c2014-01-28 15:19:44 +01003406 totalsslconns++;
Emeric Brun46591952012-05-18 15:47:34 +02003407 return 0;
3408 }
Willy Tarreau3fdb3662012-11-12 00:42:33 +01003409 else if (objt_listener(conn->target)) {
Willy Tarreaufba03cd2014-11-13 13:48:58 +01003410 int may_retry = 1;
3411
3412 retry_accept:
Emeric Brun46591952012-05-18 15:47:34 +02003413 /* Alloc a new SSL session ctx */
Willy Tarreau3fdb3662012-11-12 00:42:33 +01003414 conn->xprt_ctx = SSL_new(objt_listener(conn->target)->bind_conf->default_ctx);
Willy Tarreau20879a02012-12-03 16:32:10 +01003415 if (!conn->xprt_ctx) {
Willy Tarreaufba03cd2014-11-13 13:48:58 +01003416 if (may_retry--) {
3417 pool_gc2();
3418 goto retry_accept;
3419 }
Willy Tarreau20879a02012-12-03 16:32:10 +01003420 conn->err_code = CO_ER_SSL_NO_MEM;
Emeric Brun46591952012-05-18 15:47:34 +02003421 return -1;
Willy Tarreau20879a02012-12-03 16:32:10 +01003422 }
Emeric Brun46591952012-05-18 15:47:34 +02003423
Emeric Brun46591952012-05-18 15:47:34 +02003424 /* set fd on SSL session context */
Emeric Brun55476152014-11-12 17:35:37 +01003425 if (!SSL_set_fd(conn->xprt_ctx, conn->t.sock.fd)) {
3426 SSL_free(conn->xprt_ctx);
3427 conn->xprt_ctx = NULL;
Willy Tarreaufba03cd2014-11-13 13:48:58 +01003428 if (may_retry--) {
3429 pool_gc2();
3430 goto retry_accept;
3431 }
Emeric Brun55476152014-11-12 17:35:37 +01003432 conn->err_code = CO_ER_SSL_NO_MEM;
3433 return -1;
3434 }
Emeric Brun46591952012-05-18 15:47:34 +02003435
Emeric Brune1f38db2012-09-03 20:36:47 +02003436 /* set connection pointer */
Emeric Brun55476152014-11-12 17:35:37 +01003437 if (!SSL_set_app_data(conn->xprt_ctx, conn)) {
3438 SSL_free(conn->xprt_ctx);
3439 conn->xprt_ctx = NULL;
Willy Tarreaufba03cd2014-11-13 13:48:58 +01003440 if (may_retry--) {
3441 pool_gc2();
3442 goto retry_accept;
3443 }
Emeric Brun55476152014-11-12 17:35:37 +01003444 conn->err_code = CO_ER_SSL_NO_MEM;
3445 return -1;
3446 }
3447
3448 SSL_set_accept_state(conn->xprt_ctx);
Emeric Brune1f38db2012-09-03 20:36:47 +02003449
Emeric Brun46591952012-05-18 15:47:34 +02003450 /* leave init state and start handshake */
Willy Tarreau05737472012-09-04 08:03:39 +02003451 conn->flags |= CO_FL_SSL_WAIT_HS | CO_FL_WAIT_L6_CONN;
Willy Tarreau403edff2012-09-06 11:58:37 +02003452
3453 sslconns++;
Willy Tarreau71b734c2014-01-28 15:19:44 +01003454 totalsslconns++;
Emeric Brun46591952012-05-18 15:47:34 +02003455 return 0;
3456 }
3457 /* don't know how to handle such a target */
Willy Tarreau20879a02012-12-03 16:32:10 +01003458 conn->err_code = CO_ER_SSL_NO_TARGET;
Emeric Brun46591952012-05-18 15:47:34 +02003459 return -1;
3460}
3461
3462
3463/* This is the callback which is used when an SSL handshake is pending. It
3464 * updates the FD status if it wants some polling before being called again.
3465 * It returns 0 if it fails in a fatal way or needs to poll to go further,
3466 * otherwise it returns non-zero and removes itself from the connection's
3467 * flags (the bit is provided in <flag> by the caller).
3468 */
3469int ssl_sock_handshake(struct connection *conn, unsigned int flag)
3470{
3471 int ret;
3472
Willy Tarreau3c728722014-01-23 13:50:42 +01003473 if (!conn_ctrl_ready(conn))
Willy Tarreauf79c8172013-10-21 16:30:56 +02003474 return 0;
3475
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02003476 if (!conn->xprt_ctx)
Emeric Brun46591952012-05-18 15:47:34 +02003477 goto out_error;
3478
Emeric Brun674b7432012-11-08 19:21:55 +01003479 /* If we use SSL_do_handshake to process a reneg initiated by
3480 * the remote peer, it sometimes returns SSL_ERROR_SSL.
3481 * Usually SSL_write and SSL_read are used and process implicitly
3482 * the reneg handshake.
3483 * Here we use SSL_peek as a workaround for reneg.
3484 */
3485 if ((conn->flags & CO_FL_CONNECTED) && SSL_renegotiate_pending(conn->xprt_ctx)) {
3486 char c;
3487
3488 ret = SSL_peek(conn->xprt_ctx, &c, 1);
3489 if (ret <= 0) {
3490 /* handshake may have not been completed, let's find why */
3491 ret = SSL_get_error(conn->xprt_ctx, ret);
3492 if (ret == SSL_ERROR_WANT_WRITE) {
3493 /* SSL handshake needs to write, L4 connection may not be ready */
3494 __conn_sock_stop_recv(conn);
Willy Tarreaue1f50c42014-01-22 20:02:06 +01003495 __conn_sock_want_send(conn);
3496 fd_cant_send(conn->t.sock.fd);
Emeric Brun674b7432012-11-08 19:21:55 +01003497 return 0;
3498 }
3499 else if (ret == SSL_ERROR_WANT_READ) {
3500 /* handshake may have been completed but we have
3501 * no more data to read.
3502 */
3503 if (!SSL_renegotiate_pending(conn->xprt_ctx)) {
3504 ret = 1;
3505 goto reneg_ok;
3506 }
3507 /* SSL handshake needs to read, L4 connection is ready */
3508 if (conn->flags & CO_FL_WAIT_L4_CONN)
3509 conn->flags &= ~CO_FL_WAIT_L4_CONN;
3510 __conn_sock_stop_send(conn);
Willy Tarreaue1f50c42014-01-22 20:02:06 +01003511 __conn_sock_want_recv(conn);
3512 fd_cant_recv(conn->t.sock.fd);
Emeric Brun674b7432012-11-08 19:21:55 +01003513 return 0;
3514 }
3515 else if (ret == SSL_ERROR_SYSCALL) {
3516 /* if errno is null, then connection was successfully established */
3517 if (!errno && conn->flags & CO_FL_WAIT_L4_CONN)
3518 conn->flags &= ~CO_FL_WAIT_L4_CONN;
Willy Tarreau20879a02012-12-03 16:32:10 +01003519 if (!conn->err_code) {
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02003520 int empty_handshake;
3521#if (OPENSSL_VERSION_NUMBER >= 0x1010000fL)
3522 OSSL_HANDSHAKE_STATE state = SSL_get_state((SSL *)conn->xprt_ctx);
3523 empty_handshake = state == TLS_ST_BEFORE;
3524#else
3525 empty_handshake = !((SSL *)conn->xprt_ctx)->packet_length;
3526#endif
3527
3528 if (empty_handshake) {
Emeric Brun29f037d2014-04-25 19:05:36 +02003529 if (!errno) {
3530 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
3531 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
3532 else
3533 conn->err_code = CO_ER_SSL_EMPTY;
3534 }
3535 else {
3536 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
3537 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
3538 else
3539 conn->err_code = CO_ER_SSL_ABORT;
3540 }
3541 }
3542 else {
3543 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
3544 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
Willy Tarreau20879a02012-12-03 16:32:10 +01003545 else
Emeric Brun29f037d2014-04-25 19:05:36 +02003546 conn->err_code = CO_ER_SSL_HANDSHAKE;
3547 }
Willy Tarreau20879a02012-12-03 16:32:10 +01003548 }
Emeric Brun674b7432012-11-08 19:21:55 +01003549 goto out_error;
3550 }
3551 else {
3552 /* Fail on all other handshake errors */
3553 /* Note: OpenSSL may leave unread bytes in the socket's
3554 * buffer, causing an RST to be emitted upon close() on
3555 * TCP sockets. We first try to drain possibly pending
3556 * data to avoid this as much as possible.
3557 */
Willy Tarreaud85c4852015-03-13 00:40:28 +01003558 conn_sock_drain(conn);
Willy Tarreau20879a02012-12-03 16:32:10 +01003559 if (!conn->err_code)
Willy Tarreauf51c6982014-04-25 20:02:39 +02003560 conn->err_code = (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT) ?
3561 CO_ER_SSL_KILLED_HB : CO_ER_SSL_HANDSHAKE;
Emeric Brun674b7432012-11-08 19:21:55 +01003562 goto out_error;
3563 }
3564 }
3565 /* read some data: consider handshake completed */
3566 goto reneg_ok;
3567 }
3568
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02003569 ret = SSL_do_handshake(conn->xprt_ctx);
Emeric Brun46591952012-05-18 15:47:34 +02003570 if (ret != 1) {
3571 /* handshake did not complete, let's find why */
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02003572 ret = SSL_get_error(conn->xprt_ctx, ret);
Emeric Brun46591952012-05-18 15:47:34 +02003573
3574 if (ret == SSL_ERROR_WANT_WRITE) {
3575 /* SSL handshake needs to write, L4 connection may not be ready */
3576 __conn_sock_stop_recv(conn);
Willy Tarreaue1f50c42014-01-22 20:02:06 +01003577 __conn_sock_want_send(conn);
3578 fd_cant_send(conn->t.sock.fd);
Emeric Brun46591952012-05-18 15:47:34 +02003579 return 0;
3580 }
3581 else if (ret == SSL_ERROR_WANT_READ) {
3582 /* SSL handshake needs to read, L4 connection is ready */
3583 if (conn->flags & CO_FL_WAIT_L4_CONN)
3584 conn->flags &= ~CO_FL_WAIT_L4_CONN;
3585 __conn_sock_stop_send(conn);
Willy Tarreaue1f50c42014-01-22 20:02:06 +01003586 __conn_sock_want_recv(conn);
3587 fd_cant_recv(conn->t.sock.fd);
Emeric Brun46591952012-05-18 15:47:34 +02003588 return 0;
3589 }
Willy Tarreau89230192012-09-28 20:22:13 +02003590 else if (ret == SSL_ERROR_SYSCALL) {
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02003591#if (OPENSSL_VERSION_NUMBER >= 0x1010000fL)
3592 OSSL_HANDSHAKE_STATE state;
3593#endif
3594 int empty_handshake;
Willy Tarreau89230192012-09-28 20:22:13 +02003595 /* 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
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02003599#if (OPENSSL_VERSION_NUMBER >= 0x1010000fL)
3600 state = SSL_get_state((SSL *)conn->xprt_ctx);
3601 empty_handshake = state == TLS_ST_BEFORE;
3602#else
3603 empty_handshake = !((SSL *)conn->xprt_ctx)->packet_length;
3604#endif
3605 if (empty_handshake) {
Emeric Brun29f037d2014-04-25 19:05:36 +02003606 if (!errno) {
3607 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
3608 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
3609 else
3610 conn->err_code = CO_ER_SSL_EMPTY;
3611 }
3612 else {
3613 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
3614 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
3615 else
3616 conn->err_code = CO_ER_SSL_ABORT;
3617 }
3618 }
3619 else {
3620 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
3621 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
Willy Tarreau20879a02012-12-03 16:32:10 +01003622 else
Emeric Brun29f037d2014-04-25 19:05:36 +02003623 conn->err_code = CO_ER_SSL_HANDSHAKE;
3624 }
Willy Tarreau89230192012-09-28 20:22:13 +02003625 goto out_error;
3626 }
Emeric Brun46591952012-05-18 15:47:34 +02003627 else {
3628 /* Fail on all other handshake errors */
Willy Tarreau566dc552012-10-19 20:52:18 +02003629 /* Note: OpenSSL may leave unread bytes in the socket's
3630 * buffer, causing an RST to be emitted upon close() on
3631 * TCP sockets. We first try to drain possibly pending
3632 * data to avoid this as much as possible.
3633 */
Willy Tarreaud85c4852015-03-13 00:40:28 +01003634 conn_sock_drain(conn);
Willy Tarreau20879a02012-12-03 16:32:10 +01003635 if (!conn->err_code)
Willy Tarreauf51c6982014-04-25 20:02:39 +02003636 conn->err_code = (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT) ?
3637 CO_ER_SSL_KILLED_HB : CO_ER_SSL_HANDSHAKE;
Emeric Brun46591952012-05-18 15:47:34 +02003638 goto out_error;
3639 }
3640 }
3641
Emeric Brun674b7432012-11-08 19:21:55 +01003642reneg_ok:
Emeric Brun46591952012-05-18 15:47:34 +02003643 /* Handshake succeeded */
Willy Tarreau0c9c2722014-05-28 12:28:58 +02003644 if (!SSL_session_reused(conn->xprt_ctx)) {
3645 if (objt_server(conn->target)) {
3646 update_freq_ctr(&global.ssl_be_keys_per_sec, 1);
3647 if (global.ssl_be_keys_per_sec.curr_ctr > global.ssl_be_keys_max)
3648 global.ssl_be_keys_max = global.ssl_be_keys_per_sec.curr_ctr;
3649
Emeric Brun46591952012-05-18 15:47:34 +02003650 /* check if session was reused, if not store current session on server for reuse */
Willy Tarreau3fdb3662012-11-12 00:42:33 +01003651 if (objt_server(conn->target)->ssl_ctx.reused_sess)
3652 SSL_SESSION_free(objt_server(conn->target)->ssl_ctx.reused_sess);
Emeric Brun46591952012-05-18 15:47:34 +02003653
Willy Tarreau2a3fb1c2015-02-05 16:47:07 +01003654 if (!(objt_server(conn->target)->ssl_ctx.options & SRV_SSL_O_NO_REUSE))
3655 objt_server(conn->target)->ssl_ctx.reused_sess = SSL_get1_session(conn->xprt_ctx);
Emeric Brun46591952012-05-18 15:47:34 +02003656 }
Willy Tarreau0c9c2722014-05-28 12:28:58 +02003657 else {
3658 update_freq_ctr(&global.ssl_fe_keys_per_sec, 1);
3659 if (global.ssl_fe_keys_per_sec.curr_ctr > global.ssl_fe_keys_max)
3660 global.ssl_fe_keys_max = global.ssl_fe_keys_per_sec.curr_ctr;
3661 }
Emeric Brun46591952012-05-18 15:47:34 +02003662 }
3663
3664 /* The connection is now established at both layers, it's time to leave */
3665 conn->flags &= ~(flag | CO_FL_WAIT_L4_CONN | CO_FL_WAIT_L6_CONN);
3666 return 1;
3667
3668 out_error:
Emeric Brun644cde02012-12-14 11:21:13 +01003669 /* Clear openssl global errors stack */
Thierry FOURNIER / OZON.IO8b068c22016-10-10 11:59:50 +02003670 ssl_sock_dump_errors(conn);
Emeric Brun644cde02012-12-14 11:21:13 +01003671 ERR_clear_error();
3672
Emeric Brun9fa89732012-10-04 17:09:56 +02003673 /* free resumed session if exists */
Willy Tarreau3fdb3662012-11-12 00:42:33 +01003674 if (objt_server(conn->target) && objt_server(conn->target)->ssl_ctx.reused_sess) {
3675 SSL_SESSION_free(objt_server(conn->target)->ssl_ctx.reused_sess);
3676 objt_server(conn->target)->ssl_ctx.reused_sess = NULL;
Emeric Brun9fa89732012-10-04 17:09:56 +02003677 }
3678
Emeric Brun46591952012-05-18 15:47:34 +02003679 /* Fail on all other handshake errors */
3680 conn->flags |= CO_FL_ERROR;
Willy Tarreau20879a02012-12-03 16:32:10 +01003681 if (!conn->err_code)
3682 conn->err_code = CO_ER_SSL_HANDSHAKE;
Emeric Brun46591952012-05-18 15:47:34 +02003683 return 0;
3684}
3685
3686/* Receive up to <count> bytes from connection <conn>'s socket and store them
Willy Tarreauabf08d92014-01-14 11:31:27 +01003687 * into buffer <buf>. Only one call to recv() is performed, unless the
Emeric Brun46591952012-05-18 15:47:34 +02003688 * buffer wraps, in which case a second call may be performed. The connection's
3689 * flags are updated with whatever special event is detected (error, read0,
3690 * empty). The caller is responsible for taking care of those events and
3691 * avoiding the call if inappropriate. The function does not call the
3692 * connection's polling update function, so the caller is responsible for this.
3693 */
3694static int ssl_sock_to_buf(struct connection *conn, struct buffer *buf, int count)
3695{
3696 int ret, done = 0;
Willy Tarreauabf08d92014-01-14 11:31:27 +01003697 int try;
Emeric Brun46591952012-05-18 15:47:34 +02003698
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02003699 if (!conn->xprt_ctx)
Emeric Brun46591952012-05-18 15:47:34 +02003700 goto out_error;
3701
3702 if (conn->flags & CO_FL_HANDSHAKE)
3703 /* a handshake was requested */
3704 return 0;
3705
Willy Tarreauabf08d92014-01-14 11:31:27 +01003706 /* let's realign the buffer to optimize I/O */
3707 if (buffer_empty(buf))
Emeric Brun46591952012-05-18 15:47:34 +02003708 buf->p = buf->data;
Emeric Brun46591952012-05-18 15:47:34 +02003709
3710 /* read the largest possible block. For this, we perform only one call
3711 * to recv() unless the buffer wraps and we exactly fill the first hunk,
3712 * in which case we accept to do it once again. A new attempt is made on
3713 * EINTR too.
3714 */
Willy Tarreau00b0fb92014-01-17 11:09:40 +01003715 while (count > 0) {
Willy Tarreauabf08d92014-01-14 11:31:27 +01003716 /* first check if we have some room after p+i */
3717 try = buf->data + buf->size - (buf->p + buf->i);
3718 /* otherwise continue between data and p-o */
3719 if (try <= 0) {
3720 try = buf->p - (buf->data + buf->o);
3721 if (try <= 0)
3722 break;
3723 }
3724 if (try > count)
3725 try = count;
3726
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02003727 ret = SSL_read(conn->xprt_ctx, bi_end(buf), try);
Emeric Brune1f38db2012-09-03 20:36:47 +02003728 if (conn->flags & CO_FL_ERROR) {
3729 /* CO_FL_ERROR may be set by ssl_sock_infocbk */
Emeric Brun644cde02012-12-14 11:21:13 +01003730 goto out_error;
Emeric Brune1f38db2012-09-03 20:36:47 +02003731 }
Emeric Brun46591952012-05-18 15:47:34 +02003732 if (ret > 0) {
3733 buf->i += ret;
3734 done += ret;
3735 if (ret < try)
3736 break;
3737 count -= ret;
Emeric Brun46591952012-05-18 15:47:34 +02003738 }
3739 else if (ret == 0) {
Emeric Brun644cde02012-12-14 11:21:13 +01003740 ret = SSL_get_error(conn->xprt_ctx, ret);
3741 if (ret != SSL_ERROR_ZERO_RETURN) {
Emeric Brun1c646862012-12-14 12:33:41 +01003742 /* error on protocol or underlying transport */
3743 if ((ret != SSL_ERROR_SYSCALL)
3744 || (errno && (errno != EAGAIN)))
3745 conn->flags |= CO_FL_ERROR;
3746
Emeric Brun644cde02012-12-14 11:21:13 +01003747 /* Clear openssl global errors stack */
Thierry FOURNIER / OZON.IO8b068c22016-10-10 11:59:50 +02003748 ssl_sock_dump_errors(conn);
Emeric Brun644cde02012-12-14 11:21:13 +01003749 ERR_clear_error();
3750 }
Emeric Brun46591952012-05-18 15:47:34 +02003751 goto read0;
3752 }
3753 else {
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02003754 ret = SSL_get_error(conn->xprt_ctx, ret);
Emeric Brun46591952012-05-18 15:47:34 +02003755 if (ret == SSL_ERROR_WANT_WRITE) {
Emeric Brun8af8dd12012-11-08 17:56:20 +01003756 /* handshake is running, and it needs to enable write */
Emeric Brun46591952012-05-18 15:47:34 +02003757 conn->flags |= CO_FL_SSL_WAIT_HS;
Emeric Brun8af8dd12012-11-08 17:56:20 +01003758 __conn_sock_want_send(conn);
Emeric Brun46591952012-05-18 15:47:34 +02003759 break;
3760 }
3761 else if (ret == SSL_ERROR_WANT_READ) {
Emeric Brun282a76a2012-11-08 18:02:56 +01003762 if (SSL_renegotiate_pending(conn->xprt_ctx)) {
3763 /* handshake is running, and it may need to re-enable read */
3764 conn->flags |= CO_FL_SSL_WAIT_HS;
3765 __conn_sock_want_recv(conn);
3766 break;
3767 }
Emeric Brun46591952012-05-18 15:47:34 +02003768 /* we need to poll for retry a read later */
Willy Tarreaue1f50c42014-01-22 20:02:06 +01003769 fd_cant_recv(conn->t.sock.fd);
Emeric Brun46591952012-05-18 15:47:34 +02003770 break;
3771 }
3772 /* otherwise it's a real error */
3773 goto out_error;
3774 }
3775 }
3776 return done;
3777
3778 read0:
3779 conn_sock_read0(conn);
3780 return done;
3781 out_error:
Emeric Brun644cde02012-12-14 11:21:13 +01003782 /* Clear openssl global errors stack */
Thierry FOURNIER / OZON.IO8b068c22016-10-10 11:59:50 +02003783 ssl_sock_dump_errors(conn);
Emeric Brun644cde02012-12-14 11:21:13 +01003784 ERR_clear_error();
3785
Emeric Brun46591952012-05-18 15:47:34 +02003786 conn->flags |= CO_FL_ERROR;
3787 return done;
3788}
3789
3790
3791/* Send all pending bytes from buffer <buf> to connection <conn>'s socket.
Willy Tarreau1049b1f2014-02-02 01:51:17 +01003792 * <flags> may contain some CO_SFL_* flags to hint the system about other
3793 * pending data for example, but this flag is ignored at the moment.
Emeric Brun46591952012-05-18 15:47:34 +02003794 * Only one call to send() is performed, unless the buffer wraps, in which case
3795 * a second call may be performed. The connection's flags are updated with
3796 * whatever special event is detected (error, empty). The caller is responsible
3797 * for taking care of those events and avoiding the call if inappropriate. The
3798 * function does not call the connection's polling update function, so the caller
3799 * is responsible for this.
3800 */
3801static int ssl_sock_from_buf(struct connection *conn, struct buffer *buf, int flags)
3802{
3803 int ret, try, done;
3804
3805 done = 0;
3806
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02003807 if (!conn->xprt_ctx)
Emeric Brun46591952012-05-18 15:47:34 +02003808 goto out_error;
3809
3810 if (conn->flags & CO_FL_HANDSHAKE)
3811 /* a handshake was requested */
3812 return 0;
3813
3814 /* send the largest possible block. For this we perform only one call
3815 * to send() unless the buffer wraps and we exactly fill the first hunk,
3816 * in which case we accept to do it once again.
3817 */
3818 while (buf->o) {
Kevin Hestercad82342013-05-30 15:12:41 -07003819 try = bo_contig_data(buf);
Willy Tarreaubfd59462013-02-21 07:46:09 +01003820
Willy Tarreau7bed9452014-02-02 02:00:24 +01003821 if (!(flags & CO_SFL_STREAMER) &&
Willy Tarreau518cedd2014-02-17 15:43:01 +01003822 !(conn->xprt_st & SSL_SOCK_SEND_UNLIMITED) &&
3823 global.tune.ssl_max_record && try > global.tune.ssl_max_record) {
Willy Tarreaubfd59462013-02-21 07:46:09 +01003824 try = global.tune.ssl_max_record;
Willy Tarreau518cedd2014-02-17 15:43:01 +01003825 }
3826 else {
3827 /* we need to keep the information about the fact that
3828 * we're not limiting the upcoming send(), because if it
3829 * fails, we'll have to retry with at least as many data.
3830 */
3831 conn->xprt_st |= SSL_SOCK_SEND_UNLIMITED;
3832 }
Willy Tarreaubfd59462013-02-21 07:46:09 +01003833
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02003834 ret = SSL_write(conn->xprt_ctx, bo_ptr(buf), try);
Willy Tarreau518cedd2014-02-17 15:43:01 +01003835
Emeric Brune1f38db2012-09-03 20:36:47 +02003836 if (conn->flags & CO_FL_ERROR) {
3837 /* CO_FL_ERROR may be set by ssl_sock_infocbk */
Emeric Brun644cde02012-12-14 11:21:13 +01003838 goto out_error;
Emeric Brune1f38db2012-09-03 20:36:47 +02003839 }
Emeric Brun46591952012-05-18 15:47:34 +02003840 if (ret > 0) {
Willy Tarreau518cedd2014-02-17 15:43:01 +01003841 conn->xprt_st &= ~SSL_SOCK_SEND_UNLIMITED;
3842
Emeric Brun46591952012-05-18 15:47:34 +02003843 buf->o -= ret;
3844 done += ret;
3845
Willy Tarreau5fb38032012-12-16 19:39:09 +01003846 if (likely(buffer_empty(buf)))
Emeric Brun46591952012-05-18 15:47:34 +02003847 /* optimize data alignment in the buffer */
3848 buf->p = buf->data;
3849
3850 /* if the system buffer is full, don't insist */
3851 if (ret < try)
3852 break;
3853 }
3854 else {
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02003855 ret = SSL_get_error(conn->xprt_ctx, ret);
Emeric Brun46591952012-05-18 15:47:34 +02003856 if (ret == SSL_ERROR_WANT_WRITE) {
Emeric Brun282a76a2012-11-08 18:02:56 +01003857 if (SSL_renegotiate_pending(conn->xprt_ctx)) {
3858 /* handshake is running, and it may need to re-enable write */
3859 conn->flags |= CO_FL_SSL_WAIT_HS;
3860 __conn_sock_want_send(conn);
3861 break;
3862 }
Emeric Brun46591952012-05-18 15:47:34 +02003863 /* we need to poll to retry a write later */
Willy Tarreaue1f50c42014-01-22 20:02:06 +01003864 fd_cant_send(conn->t.sock.fd);
Emeric Brun46591952012-05-18 15:47:34 +02003865 break;
3866 }
3867 else if (ret == SSL_ERROR_WANT_READ) {
Emeric Brun8af8dd12012-11-08 17:56:20 +01003868 /* handshake is running, and it needs to enable read */
Emeric Brun46591952012-05-18 15:47:34 +02003869 conn->flags |= CO_FL_SSL_WAIT_HS;
Emeric Brun8af8dd12012-11-08 17:56:20 +01003870 __conn_sock_want_recv(conn);
Emeric Brun46591952012-05-18 15:47:34 +02003871 break;
3872 }
3873 goto out_error;
3874 }
3875 }
3876 return done;
3877
3878 out_error:
Emeric Brun644cde02012-12-14 11:21:13 +01003879 /* Clear openssl global errors stack */
Thierry FOURNIER / OZON.IO8b068c22016-10-10 11:59:50 +02003880 ssl_sock_dump_errors(conn);
Emeric Brun644cde02012-12-14 11:21:13 +01003881 ERR_clear_error();
3882
Emeric Brun46591952012-05-18 15:47:34 +02003883 conn->flags |= CO_FL_ERROR;
3884 return done;
3885}
3886
Emeric Brun46591952012-05-18 15:47:34 +02003887static void ssl_sock_close(struct connection *conn) {
3888
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02003889 if (conn->xprt_ctx) {
3890 SSL_free(conn->xprt_ctx);
3891 conn->xprt_ctx = NULL;
Willy Tarreau403edff2012-09-06 11:58:37 +02003892 sslconns--;
Emeric Brun46591952012-05-18 15:47:34 +02003893 }
Emeric Brun46591952012-05-18 15:47:34 +02003894}
3895
3896/* This function tries to perform a clean shutdown on an SSL connection, and in
3897 * any case, flags the connection as reusable if no handshake was in progress.
3898 */
3899static void ssl_sock_shutw(struct connection *conn, int clean)
3900{
3901 if (conn->flags & CO_FL_HANDSHAKE)
3902 return;
3903 /* no handshake was in progress, try a clean ssl shutdown */
Emeric Brun644cde02012-12-14 11:21:13 +01003904 if (clean && (SSL_shutdown(conn->xprt_ctx) <= 0)) {
3905 /* Clear openssl global errors stack */
Thierry FOURNIER / OZON.IO8b068c22016-10-10 11:59:50 +02003906 ssl_sock_dump_errors(conn);
Emeric Brun644cde02012-12-14 11:21:13 +01003907 ERR_clear_error();
3908 }
Emeric Brun46591952012-05-18 15:47:34 +02003909
3910 /* force flag on ssl to keep session in cache regardless shutdown result */
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02003911 SSL_set_shutdown(conn->xprt_ctx, SSL_SENT_SHUTDOWN);
Emeric Brun46591952012-05-18 15:47:34 +02003912}
3913
Willy Tarreauffc3fcd2012-10-12 20:17:54 +02003914/* used for logging, may be changed for a sample fetch later */
3915const char *ssl_sock_get_cipher_name(struct connection *conn)
3916{
3917 if (!conn->xprt && !conn->xprt_ctx)
3918 return NULL;
3919 return SSL_get_cipher_name(conn->xprt_ctx);
3920}
3921
3922/* used for logging, may be changed for a sample fetch later */
3923const char *ssl_sock_get_proto_version(struct connection *conn)
3924{
3925 if (!conn->xprt && !conn->xprt_ctx)
3926 return NULL;
3927 return SSL_get_version(conn->xprt_ctx);
3928}
3929
Willy Tarreau8d598402012-10-22 17:58:39 +02003930/* Extract a serial from a cert, and copy it to a chunk.
3931 * Returns 1 if serial is found and copied, 0 if no serial found and
3932 * -1 if output is not large enough.
3933 */
3934static int
3935ssl_sock_get_serial(X509 *crt, struct chunk *out)
3936{
3937 ASN1_INTEGER *serial;
3938
3939 serial = X509_get_serialNumber(crt);
3940 if (!serial)
3941 return 0;
3942
3943 if (out->size < serial->length)
3944 return -1;
3945
3946 memcpy(out->str, serial->data, serial->length);
3947 out->len = serial->length;
3948 return 1;
3949}
3950
Emeric Brun43e79582014-10-29 19:03:26 +01003951/* Extract a cert to der, and copy it to a chunk.
3952 * Returns 1 if cert is found and copied, 0 on der convertion failure and
3953 * -1 if output is not large enough.
3954 */
3955static int
3956ssl_sock_crt2der(X509 *crt, struct chunk *out)
3957{
3958 int len;
3959 unsigned char *p = (unsigned char *)out->str;;
3960
3961 len =i2d_X509(crt, NULL);
3962 if (len <= 0)
3963 return 1;
3964
3965 if (out->size < len)
3966 return -1;
3967
3968 i2d_X509(crt,&p);
3969 out->len = len;
3970 return 1;
3971}
3972
Emeric Brunce5ad802012-10-22 14:11:22 +02003973
3974/* Copy Date in ASN1_UTCTIME format in struct chunk out.
3975 * Returns 1 if serial is found and copied, 0 if no valid time found
3976 * and -1 if output is not large enough.
3977 */
3978static int
3979ssl_sock_get_time(ASN1_TIME *tm, struct chunk *out)
3980{
3981 if (tm->type == V_ASN1_GENERALIZEDTIME) {
3982 ASN1_GENERALIZEDTIME *gentm = (ASN1_GENERALIZEDTIME *)tm;
3983
3984 if (gentm->length < 12)
3985 return 0;
3986 if (gentm->data[0] != 0x32 || gentm->data[1] != 0x30)
3987 return 0;
3988 if (out->size < gentm->length-2)
3989 return -1;
3990
3991 memcpy(out->str, gentm->data+2, gentm->length-2);
3992 out->len = gentm->length-2;
3993 return 1;
3994 }
3995 else if (tm->type == V_ASN1_UTCTIME) {
3996 ASN1_UTCTIME *utctm = (ASN1_UTCTIME *)tm;
3997
3998 if (utctm->length < 10)
3999 return 0;
4000 if (utctm->data[0] >= 0x35)
4001 return 0;
4002 if (out->size < utctm->length)
4003 return -1;
4004
4005 memcpy(out->str, utctm->data, utctm->length);
4006 out->len = utctm->length;
4007 return 1;
4008 }
4009
4010 return 0;
4011}
4012
Emeric Brun87855892012-10-17 17:39:35 +02004013/* Extract an entry from a X509_NAME and copy its value to an output chunk.
4014 * Returns 1 if entry found, 0 if entry not found, or -1 if output not large enough.
4015 */
4016static int
4017ssl_sock_get_dn_entry(X509_NAME *a, const struct chunk *entry, int pos, struct chunk *out)
4018{
4019 X509_NAME_ENTRY *ne;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004020 ASN1_OBJECT *obj;
4021 ASN1_STRING *data;
4022 const unsigned char *data_ptr;
4023 int data_len;
Emeric Brun87855892012-10-17 17:39:35 +02004024 int i, j, n;
4025 int cur = 0;
4026 const char *s;
4027 char tmp[128];
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004028 int name_count;
4029
4030 name_count = X509_NAME_entry_count(a);
Emeric Brun87855892012-10-17 17:39:35 +02004031
4032 out->len = 0;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004033 for (i = 0; i < name_count; i++) {
Emeric Brun87855892012-10-17 17:39:35 +02004034 if (pos < 0)
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004035 j = (name_count-1) - i;
Emeric Brun87855892012-10-17 17:39:35 +02004036 else
4037 j = i;
4038
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004039 ne = X509_NAME_get_entry(a, j);
4040 obj = X509_NAME_ENTRY_get_object(ne);
4041 data = X509_NAME_ENTRY_get_data(ne);
4042 data_ptr = ASN1_STRING_get0_data(data);
4043 data_len = ASN1_STRING_length(data);
4044 n = OBJ_obj2nid(obj);
Emeric Brun87855892012-10-17 17:39:35 +02004045 if ((n == NID_undef) || ((s = OBJ_nid2sn(n)) == NULL)) {
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004046 i2t_ASN1_OBJECT(tmp, sizeof(tmp), obj);
Emeric Brun87855892012-10-17 17:39:35 +02004047 s = tmp;
4048 }
4049
4050 if (chunk_strcasecmp(entry, s) != 0)
4051 continue;
4052
4053 if (pos < 0)
4054 cur--;
4055 else
4056 cur++;
4057
4058 if (cur != pos)
4059 continue;
4060
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004061 if (data_len > out->size)
Emeric Brun87855892012-10-17 17:39:35 +02004062 return -1;
4063
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004064 memcpy(out->str, data_ptr, data_len);
4065 out->len = data_len;
Emeric Brun87855892012-10-17 17:39:35 +02004066 return 1;
4067 }
4068
4069 return 0;
4070
4071}
4072
4073/* Extract and format full DN from a X509_NAME and copy result into a chunk
4074 * Returns 1 if dn entries exits, 0 if no dn entry found or -1 if output is not large enough.
4075 */
4076static int
4077ssl_sock_get_dn_oneline(X509_NAME *a, struct chunk *out)
4078{
4079 X509_NAME_ENTRY *ne;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004080 ASN1_OBJECT *obj;
4081 ASN1_STRING *data;
4082 const unsigned char *data_ptr;
4083 int data_len;
Emeric Brun87855892012-10-17 17:39:35 +02004084 int i, n, ln;
4085 int l = 0;
4086 const char *s;
4087 char *p;
4088 char tmp[128];
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004089 int name_count;
4090
4091
4092 name_count = X509_NAME_entry_count(a);
Emeric Brun87855892012-10-17 17:39:35 +02004093
4094 out->len = 0;
4095 p = out->str;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004096 for (i = 0; i < name_count; i++) {
4097 ne = X509_NAME_get_entry(a, i);
4098 obj = X509_NAME_ENTRY_get_object(ne);
4099 data = X509_NAME_ENTRY_get_data(ne);
4100 data_ptr = ASN1_STRING_get0_data(data);
4101 data_len = ASN1_STRING_length(data);
4102 n = OBJ_obj2nid(obj);
Emeric Brun87855892012-10-17 17:39:35 +02004103 if ((n == NID_undef) || ((s = OBJ_nid2sn(n)) == NULL)) {
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004104 i2t_ASN1_OBJECT(tmp, sizeof(tmp), obj);
Emeric Brun87855892012-10-17 17:39:35 +02004105 s = tmp;
4106 }
4107 ln = strlen(s);
4108
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004109 l += 1 + ln + 1 + data_len;
Emeric Brun87855892012-10-17 17:39:35 +02004110 if (l > out->size)
4111 return -1;
4112 out->len = l;
4113
4114 *(p++)='/';
4115 memcpy(p, s, ln);
4116 p += ln;
4117 *(p++)='=';
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004118 memcpy(p, data_ptr, data_len);
4119 p += data_len;
Emeric Brun87855892012-10-17 17:39:35 +02004120 }
4121
4122 if (!out->len)
4123 return 0;
4124
4125 return 1;
4126}
4127
David Safb76832014-05-08 23:42:08 -04004128char *ssl_sock_get_version(struct connection *conn)
4129{
4130 if (!ssl_sock_is_ssl(conn))
4131 return NULL;
4132
4133 return (char *)SSL_get_version(conn->xprt_ctx);
4134}
4135
Willy Tarreau63076412015-07-10 11:33:32 +02004136void ssl_sock_set_servername(struct connection *conn, const char *hostname)
4137{
4138#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
4139 if (!ssl_sock_is_ssl(conn))
4140 return;
4141
4142 SSL_set_tlsext_host_name(conn->xprt_ctx, hostname);
4143#endif
4144}
4145
Emeric Brun0abf8362014-06-24 18:26:41 +02004146/* Extract peer certificate's common name into the chunk dest
4147 * Returns
4148 * the len of the extracted common name
4149 * or 0 if no CN found in DN
4150 * or -1 on error case (i.e. no peer certificate)
4151 */
4152int ssl_sock_get_remote_common_name(struct connection *conn, struct chunk *dest)
David Safb76832014-05-08 23:42:08 -04004153{
4154 X509 *crt = NULL;
4155 X509_NAME *name;
David Safb76832014-05-08 23:42:08 -04004156 const char find_cn[] = "CN";
4157 const struct chunk find_cn_chunk = {
4158 .str = (char *)&find_cn,
4159 .len = sizeof(find_cn)-1
4160 };
Emeric Brun0abf8362014-06-24 18:26:41 +02004161 int result = -1;
David Safb76832014-05-08 23:42:08 -04004162
4163 if (!ssl_sock_is_ssl(conn))
Emeric Brun0abf8362014-06-24 18:26:41 +02004164 goto out;
David Safb76832014-05-08 23:42:08 -04004165
4166 /* SSL_get_peer_certificate, it increase X509 * ref count */
4167 crt = SSL_get_peer_certificate(conn->xprt_ctx);
4168 if (!crt)
4169 goto out;
4170
4171 name = X509_get_subject_name(crt);
4172 if (!name)
4173 goto out;
David Safb76832014-05-08 23:42:08 -04004174
Emeric Brun0abf8362014-06-24 18:26:41 +02004175 result = ssl_sock_get_dn_entry(name, &find_cn_chunk, 1, dest);
4176out:
David Safb76832014-05-08 23:42:08 -04004177 if (crt)
4178 X509_free(crt);
4179
4180 return result;
4181}
4182
Dave McCowan328fb582014-07-30 10:39:13 -04004183/* returns 1 if client passed a certificate for this session, 0 if not */
4184int ssl_sock_get_cert_used_sess(struct connection *conn)
4185{
4186 X509 *crt = NULL;
4187
4188 if (!ssl_sock_is_ssl(conn))
4189 return 0;
4190
4191 /* SSL_get_peer_certificate, it increase X509 * ref count */
4192 crt = SSL_get_peer_certificate(conn->xprt_ctx);
4193 if (!crt)
4194 return 0;
4195
4196 X509_free(crt);
4197 return 1;
4198}
4199
4200/* returns 1 if client passed a certificate for this connection, 0 if not */
4201int ssl_sock_get_cert_used_conn(struct connection *conn)
David Safb76832014-05-08 23:42:08 -04004202{
4203 if (!ssl_sock_is_ssl(conn))
4204 return 0;
4205
4206 return SSL_SOCK_ST_FL_VERIFY_DONE & conn->xprt_st ? 1 : 0;
4207}
4208
4209/* returns result from SSL verify */
4210unsigned int ssl_sock_get_verify_result(struct connection *conn)
4211{
4212 if (!ssl_sock_is_ssl(conn))
4213 return (unsigned int)X509_V_ERR_APPLICATION_VERIFICATION;
4214
4215 return (unsigned int)SSL_get_verify_result(conn->xprt_ctx);
4216}
4217
Willy Tarreau7875d092012-09-10 08:20:03 +02004218/***** Below are some sample fetching functions for ACL/patterns *****/
4219
Emeric Brune64aef12012-09-21 13:15:06 +02004220/* boolean, returns true if client cert was present */
4221static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004222smp_fetch_ssl_fc_has_crt(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brune64aef12012-09-21 13:15:06 +02004223{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004224 struct connection *conn;
4225
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004226 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004227 if (!conn || conn->xprt != &ssl_sock)
Emeric Brune64aef12012-09-21 13:15:06 +02004228 return 0;
4229
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004230 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brune64aef12012-09-21 13:15:06 +02004231 smp->flags |= SMP_F_MAY_CHANGE;
4232 return 0;
4233 }
4234
4235 smp->flags = 0;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004236 smp->data.type = SMP_T_BOOL;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004237 smp->data.u.sint = SSL_SOCK_ST_FL_VERIFY_DONE & conn->xprt_st ? 1 : 0;
Emeric Brune64aef12012-09-21 13:15:06 +02004238
4239 return 1;
4240}
4241
Emeric Brun43e79582014-10-29 19:03:26 +01004242/* binary, returns a certificate in a binary chunk (der/raw).
4243 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
4244 * should be use.
4245 */
4246static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004247smp_fetch_ssl_x_der(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun43e79582014-10-29 19:03:26 +01004248{
4249 int cert_peer = (kw[4] == 'c') ? 1 : 0;
4250 X509 *crt = NULL;
4251 int ret = 0;
4252 struct chunk *smp_trash;
4253 struct connection *conn;
4254
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004255 conn = objt_conn(smp->sess->origin);
Emeric Brun43e79582014-10-29 19:03:26 +01004256 if (!conn || conn->xprt != &ssl_sock)
4257 return 0;
4258
4259 if (!(conn->flags & CO_FL_CONNECTED)) {
4260 smp->flags |= SMP_F_MAY_CHANGE;
4261 return 0;
4262 }
4263
4264 if (cert_peer)
4265 crt = SSL_get_peer_certificate(conn->xprt_ctx);
4266 else
4267 crt = SSL_get_certificate(conn->xprt_ctx);
4268
4269 if (!crt)
4270 goto out;
4271
4272 smp_trash = get_trash_chunk();
4273 if (ssl_sock_crt2der(crt, smp_trash) <= 0)
4274 goto out;
4275
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004276 smp->data.u.str = *smp_trash;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004277 smp->data.type = SMP_T_BIN;
Emeric Brun43e79582014-10-29 19:03:26 +01004278 ret = 1;
4279out:
4280 /* SSL_get_peer_certificate, it increase X509 * ref count */
4281 if (cert_peer && crt)
4282 X509_free(crt);
4283 return ret;
4284}
4285
Emeric Brunba841a12014-04-30 17:05:08 +02004286/* binary, returns serial of certificate in a binary chunk.
4287 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
4288 * should be use.
4289 */
Willy Tarreau8d598402012-10-22 17:58:39 +02004290static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004291smp_fetch_ssl_x_serial(const struct arg *args, struct sample *smp, const char *kw, void *private)
Willy Tarreau8d598402012-10-22 17:58:39 +02004292{
Emeric Brunba841a12014-04-30 17:05:08 +02004293 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Willy Tarreau8d598402012-10-22 17:58:39 +02004294 X509 *crt = NULL;
4295 int ret = 0;
4296 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004297 struct connection *conn;
4298
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004299 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004300 if (!conn || conn->xprt != &ssl_sock)
Willy Tarreau8d598402012-10-22 17:58:39 +02004301 return 0;
4302
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004303 if (!(conn->flags & CO_FL_CONNECTED)) {
Willy Tarreau8d598402012-10-22 17:58:39 +02004304 smp->flags |= SMP_F_MAY_CHANGE;
4305 return 0;
4306 }
4307
Emeric Brunba841a12014-04-30 17:05:08 +02004308 if (cert_peer)
4309 crt = SSL_get_peer_certificate(conn->xprt_ctx);
4310 else
4311 crt = SSL_get_certificate(conn->xprt_ctx);
4312
Willy Tarreau8d598402012-10-22 17:58:39 +02004313 if (!crt)
4314 goto out;
4315
Willy Tarreau47ca5452012-12-23 20:22:19 +01004316 smp_trash = get_trash_chunk();
Willy Tarreau8d598402012-10-22 17:58:39 +02004317 if (ssl_sock_get_serial(crt, smp_trash) <= 0)
4318 goto out;
4319
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004320 smp->data.u.str = *smp_trash;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004321 smp->data.type = SMP_T_BIN;
Willy Tarreau8d598402012-10-22 17:58:39 +02004322 ret = 1;
4323out:
Emeric Brunba841a12014-04-30 17:05:08 +02004324 /* SSL_get_peer_certificate, it increase X509 * ref count */
4325 if (cert_peer && crt)
Willy Tarreau8d598402012-10-22 17:58:39 +02004326 X509_free(crt);
4327 return ret;
4328}
Emeric Brune64aef12012-09-21 13:15:06 +02004329
Emeric Brunba841a12014-04-30 17:05:08 +02004330/* binary, returns the client certificate's SHA-1 fingerprint (SHA-1 hash of DER-encoded certificate) in a binary chunk.
4331 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
4332 * should be use.
4333 */
James Votha051b4a2013-05-14 20:37:59 +02004334static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004335smp_fetch_ssl_x_sha1(const struct arg *args, struct sample *smp, const char *kw, void *private)
James Votha051b4a2013-05-14 20:37:59 +02004336{
Emeric Brunba841a12014-04-30 17:05:08 +02004337 int cert_peer = (kw[4] == 'c') ? 1 : 0;
James Votha051b4a2013-05-14 20:37:59 +02004338 X509 *crt = NULL;
4339 const EVP_MD *digest;
4340 int ret = 0;
4341 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004342 struct connection *conn;
James Votha051b4a2013-05-14 20:37:59 +02004343
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004344 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004345 if (!conn || conn->xprt != &ssl_sock)
4346 return 0;
4347
4348 if (!(conn->flags & CO_FL_CONNECTED)) {
James Votha051b4a2013-05-14 20:37:59 +02004349 smp->flags |= SMP_F_MAY_CHANGE;
4350 return 0;
4351 }
4352
Emeric Brunba841a12014-04-30 17:05:08 +02004353 if (cert_peer)
4354 crt = SSL_get_peer_certificate(conn->xprt_ctx);
4355 else
4356 crt = SSL_get_certificate(conn->xprt_ctx);
James Votha051b4a2013-05-14 20:37:59 +02004357 if (!crt)
4358 goto out;
4359
4360 smp_trash = get_trash_chunk();
4361 digest = EVP_sha1();
4362 X509_digest(crt, digest, (unsigned char *)smp_trash->str, (unsigned int *)&smp_trash->len);
4363
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004364 smp->data.u.str = *smp_trash;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004365 smp->data.type = SMP_T_BIN;
James Votha051b4a2013-05-14 20:37:59 +02004366 ret = 1;
4367out:
Emeric Brunba841a12014-04-30 17:05:08 +02004368 /* SSL_get_peer_certificate, it increase X509 * ref count */
4369 if (cert_peer && crt)
James Votha051b4a2013-05-14 20:37:59 +02004370 X509_free(crt);
4371 return ret;
4372}
4373
Emeric Brunba841a12014-04-30 17:05:08 +02004374/* string, returns certificate's notafter date in ASN1_UTCTIME format.
4375 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
4376 * should be use.
4377 */
Emeric Brunce5ad802012-10-22 14:11:22 +02004378static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004379smp_fetch_ssl_x_notafter(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brunce5ad802012-10-22 14:11:22 +02004380{
Emeric Brunba841a12014-04-30 17:05:08 +02004381 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brunce5ad802012-10-22 14:11:22 +02004382 X509 *crt = NULL;
4383 int ret = 0;
4384 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004385 struct connection *conn;
Emeric Brunce5ad802012-10-22 14:11:22 +02004386
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004387 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004388 if (!conn || conn->xprt != &ssl_sock)
4389 return 0;
4390
4391 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunce5ad802012-10-22 14:11:22 +02004392 smp->flags |= SMP_F_MAY_CHANGE;
4393 return 0;
4394 }
4395
Emeric Brunba841a12014-04-30 17:05:08 +02004396 if (cert_peer)
4397 crt = SSL_get_peer_certificate(conn->xprt_ctx);
4398 else
4399 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brunce5ad802012-10-22 14:11:22 +02004400 if (!crt)
4401 goto out;
4402
Willy Tarreau47ca5452012-12-23 20:22:19 +01004403 smp_trash = get_trash_chunk();
Emeric Brunce5ad802012-10-22 14:11:22 +02004404 if (ssl_sock_get_time(X509_get_notAfter(crt), smp_trash) <= 0)
4405 goto out;
4406
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004407 smp->data.u.str = *smp_trash;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004408 smp->data.type = SMP_T_STR;
Emeric Brunce5ad802012-10-22 14:11:22 +02004409 ret = 1;
4410out:
Emeric Brunba841a12014-04-30 17:05:08 +02004411 /* SSL_get_peer_certificate, it increase X509 * ref count */
4412 if (cert_peer && crt)
Emeric Brunce5ad802012-10-22 14:11:22 +02004413 X509_free(crt);
4414 return ret;
4415}
4416
Emeric Brunba841a12014-04-30 17:05:08 +02004417/* string, returns a string of a formatted full dn \C=..\O=..\OU=.. \CN=.. of certificate's issuer
4418 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
4419 * should be use.
4420 */
Emeric Brun87855892012-10-17 17:39:35 +02004421static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004422smp_fetch_ssl_x_i_dn(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun87855892012-10-17 17:39:35 +02004423{
Emeric Brunba841a12014-04-30 17:05:08 +02004424 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brun87855892012-10-17 17:39:35 +02004425 X509 *crt = NULL;
4426 X509_NAME *name;
4427 int ret = 0;
4428 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004429 struct connection *conn;
Emeric Brun87855892012-10-17 17:39:35 +02004430
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004431 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004432 if (!conn || conn->xprt != &ssl_sock)
4433 return 0;
4434
4435 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun87855892012-10-17 17:39:35 +02004436 smp->flags |= SMP_F_MAY_CHANGE;
4437 return 0;
4438 }
4439
Emeric Brunba841a12014-04-30 17:05:08 +02004440 if (cert_peer)
4441 crt = SSL_get_peer_certificate(conn->xprt_ctx);
4442 else
4443 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brun87855892012-10-17 17:39:35 +02004444 if (!crt)
4445 goto out;
4446
4447 name = X509_get_issuer_name(crt);
4448 if (!name)
4449 goto out;
4450
Willy Tarreau47ca5452012-12-23 20:22:19 +01004451 smp_trash = get_trash_chunk();
Emeric Brun87855892012-10-17 17:39:35 +02004452 if (args && args[0].type == ARGT_STR) {
4453 int pos = 1;
4454
4455 if (args[1].type == ARGT_SINT)
4456 pos = args[1].data.sint;
Emeric Brun87855892012-10-17 17:39:35 +02004457
4458 if (ssl_sock_get_dn_entry(name, &args[0].data.str, pos, smp_trash) <= 0)
4459 goto out;
4460 }
4461 else if (ssl_sock_get_dn_oneline(name, smp_trash) <= 0)
4462 goto out;
4463
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004464 smp->data.type = SMP_T_STR;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004465 smp->data.u.str = *smp_trash;
Emeric Brun87855892012-10-17 17:39:35 +02004466 ret = 1;
4467out:
Emeric Brunba841a12014-04-30 17:05:08 +02004468 /* SSL_get_peer_certificate, it increase X509 * ref count */
4469 if (cert_peer && crt)
Emeric Brun87855892012-10-17 17:39:35 +02004470 X509_free(crt);
4471 return ret;
4472}
4473
Emeric Brunba841a12014-04-30 17:05:08 +02004474/* string, returns notbefore date in ASN1_UTCTIME format.
4475 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
4476 * should be use.
4477 */
Emeric Brunce5ad802012-10-22 14:11:22 +02004478static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004479smp_fetch_ssl_x_notbefore(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brunce5ad802012-10-22 14:11:22 +02004480{
Emeric Brunba841a12014-04-30 17:05:08 +02004481 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brunce5ad802012-10-22 14:11:22 +02004482 X509 *crt = NULL;
4483 int ret = 0;
4484 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004485 struct connection *conn;
4486
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004487 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004488 if (!conn || conn->xprt != &ssl_sock)
Emeric Brunce5ad802012-10-22 14:11:22 +02004489 return 0;
4490
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004491 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunce5ad802012-10-22 14:11:22 +02004492 smp->flags |= SMP_F_MAY_CHANGE;
4493 return 0;
4494 }
4495
Emeric Brunba841a12014-04-30 17:05:08 +02004496 if (cert_peer)
4497 crt = SSL_get_peer_certificate(conn->xprt_ctx);
4498 else
4499 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brunce5ad802012-10-22 14:11:22 +02004500 if (!crt)
4501 goto out;
4502
Willy Tarreau47ca5452012-12-23 20:22:19 +01004503 smp_trash = get_trash_chunk();
Emeric Brunce5ad802012-10-22 14:11:22 +02004504 if (ssl_sock_get_time(X509_get_notBefore(crt), smp_trash) <= 0)
4505 goto out;
4506
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004507 smp->data.u.str = *smp_trash;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004508 smp->data.type = SMP_T_STR;
Emeric Brunce5ad802012-10-22 14:11:22 +02004509 ret = 1;
4510out:
Emeric Brunba841a12014-04-30 17:05:08 +02004511 /* SSL_get_peer_certificate, it increase X509 * ref count */
4512 if (cert_peer && crt)
Emeric Brunce5ad802012-10-22 14:11:22 +02004513 X509_free(crt);
4514 return ret;
4515}
4516
Emeric Brunba841a12014-04-30 17:05:08 +02004517/* string, returns a string of a formatted full dn \C=..\O=..\OU=.. \CN=.. of certificate's subject
4518 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
4519 * should be use.
4520 */
Emeric Brun87855892012-10-17 17:39:35 +02004521static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004522smp_fetch_ssl_x_s_dn(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun87855892012-10-17 17:39:35 +02004523{
Emeric Brunba841a12014-04-30 17:05:08 +02004524 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brun87855892012-10-17 17:39:35 +02004525 X509 *crt = NULL;
4526 X509_NAME *name;
4527 int ret = 0;
4528 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004529 struct connection *conn;
Emeric Brun87855892012-10-17 17:39:35 +02004530
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004531 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004532 if (!conn || conn->xprt != &ssl_sock)
4533 return 0;
4534
4535 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun87855892012-10-17 17:39:35 +02004536 smp->flags |= SMP_F_MAY_CHANGE;
4537 return 0;
4538 }
4539
Emeric Brunba841a12014-04-30 17:05:08 +02004540 if (cert_peer)
4541 crt = SSL_get_peer_certificate(conn->xprt_ctx);
4542 else
4543 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brun87855892012-10-17 17:39:35 +02004544 if (!crt)
4545 goto out;
4546
4547 name = X509_get_subject_name(crt);
4548 if (!name)
4549 goto out;
4550
Willy Tarreau47ca5452012-12-23 20:22:19 +01004551 smp_trash = get_trash_chunk();
Emeric Brun87855892012-10-17 17:39:35 +02004552 if (args && args[0].type == ARGT_STR) {
4553 int pos = 1;
4554
4555 if (args[1].type == ARGT_SINT)
4556 pos = args[1].data.sint;
Emeric Brun87855892012-10-17 17:39:35 +02004557
4558 if (ssl_sock_get_dn_entry(name, &args[0].data.str, pos, smp_trash) <= 0)
4559 goto out;
4560 }
4561 else if (ssl_sock_get_dn_oneline(name, smp_trash) <= 0)
4562 goto out;
4563
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004564 smp->data.type = SMP_T_STR;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004565 smp->data.u.str = *smp_trash;
Emeric Brun87855892012-10-17 17:39:35 +02004566 ret = 1;
4567out:
Emeric Brunba841a12014-04-30 17:05:08 +02004568 /* SSL_get_peer_certificate, it increase X509 * ref count */
4569 if (cert_peer && crt)
Emeric Brun87855892012-10-17 17:39:35 +02004570 X509_free(crt);
4571 return ret;
4572}
Emeric Brun9143d372012-12-20 15:44:16 +01004573
4574/* integer, returns true if current session use a client certificate */
4575static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004576smp_fetch_ssl_c_used(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun9143d372012-12-20 15:44:16 +01004577{
4578 X509 *crt;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004579 struct connection *conn;
Emeric Brun9143d372012-12-20 15:44:16 +01004580
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004581 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004582 if (!conn || conn->xprt != &ssl_sock)
4583 return 0;
4584
4585 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun9143d372012-12-20 15:44:16 +01004586 smp->flags |= SMP_F_MAY_CHANGE;
4587 return 0;
4588 }
4589
4590 /* SSL_get_peer_certificate returns a ptr on allocated X509 struct */
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004591 crt = SSL_get_peer_certificate(conn->xprt_ctx);
Emeric Brun9143d372012-12-20 15:44:16 +01004592 if (crt) {
4593 X509_free(crt);
4594 }
4595
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004596 smp->data.type = SMP_T_BOOL;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004597 smp->data.u.sint = (crt != NULL);
Emeric Brun9143d372012-12-20 15:44:16 +01004598 return 1;
4599}
4600
Emeric Brunba841a12014-04-30 17:05:08 +02004601/* integer, returns the certificate version
4602 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
4603 * should be use.
4604 */
Emeric Bruna7359fd2012-10-17 15:03:11 +02004605static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004606smp_fetch_ssl_x_version(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Bruna7359fd2012-10-17 15:03:11 +02004607{
Emeric Brunba841a12014-04-30 17:05:08 +02004608 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Bruna7359fd2012-10-17 15:03:11 +02004609 X509 *crt;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004610 struct connection *conn;
4611
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)
Emeric Bruna7359fd2012-10-17 15:03:11 +02004614 return 0;
4615
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004616 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Bruna7359fd2012-10-17 15:03:11 +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 Bruna7359fd2012-10-17 15:03:11 +02004625 if (!crt)
4626 return 0;
4627
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004628 smp->data.u.sint = (unsigned int)(1 + X509_get_version(crt));
Emeric Brunba841a12014-04-30 17:05:08 +02004629 /* SSL_get_peer_certificate increase X509 * ref count */
4630 if (cert_peer)
4631 X509_free(crt);
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004632 smp->data.type = SMP_T_SINT;
Emeric Bruna7359fd2012-10-17 15:03:11 +02004633
4634 return 1;
4635}
4636
Emeric Brunba841a12014-04-30 17:05:08 +02004637/* string, returns the certificate's signature algorithm.
4638 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
4639 * should be use.
4640 */
Emeric Brun7f56e742012-10-19 18:15:40 +02004641static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004642smp_fetch_ssl_x_sig_alg(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun7f56e742012-10-19 18:15:40 +02004643{
Emeric Brunba841a12014-04-30 17:05:08 +02004644 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brun7f56e742012-10-19 18:15:40 +02004645 X509 *crt;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004646 __OPENSSL_110_CONST__ ASN1_OBJECT *algorithm;
Emeric Brun7f56e742012-10-19 18:15:40 +02004647 int nid;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004648 struct connection *conn;
Emeric Brun7f56e742012-10-19 18:15:40 +02004649
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004650 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004651 if (!conn || conn->xprt != &ssl_sock)
4652 return 0;
4653
4654 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun7f56e742012-10-19 18:15:40 +02004655 smp->flags |= SMP_F_MAY_CHANGE;
4656 return 0;
4657 }
4658
Emeric Brunba841a12014-04-30 17:05:08 +02004659 if (cert_peer)
4660 crt = SSL_get_peer_certificate(conn->xprt_ctx);
4661 else
4662 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brun7f56e742012-10-19 18:15:40 +02004663 if (!crt)
4664 return 0;
4665
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004666 X509_ALGOR_get0(&algorithm, NULL, NULL, X509_get0_tbs_sigalg(crt));
4667 nid = OBJ_obj2nid(algorithm);
Emeric Brun7f56e742012-10-19 18:15:40 +02004668
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004669 smp->data.u.str.str = (char *)OBJ_nid2sn(nid);
4670 if (!smp->data.u.str.str) {
Emeric Brunba841a12014-04-30 17:05:08 +02004671 /* SSL_get_peer_certificate increase X509 * ref count */
4672 if (cert_peer)
4673 X509_free(crt);
Emeric Brun7f56e742012-10-19 18:15:40 +02004674 return 0;
Emeric Brun9bf3ba22013-10-07 14:31:44 +02004675 }
Emeric Brun7f56e742012-10-19 18:15:40 +02004676
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004677 smp->data.type = SMP_T_STR;
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01004678 smp->flags |= SMP_F_CONST;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004679 smp->data.u.str.len = strlen(smp->data.u.str.str);
Emeric Brunba841a12014-04-30 17:05:08 +02004680 /* SSL_get_peer_certificate increase X509 * ref count */
4681 if (cert_peer)
4682 X509_free(crt);
Emeric Brun7f56e742012-10-19 18:15:40 +02004683
4684 return 1;
4685}
4686
Emeric Brunba841a12014-04-30 17:05:08 +02004687/* string, returns the certificate's key algorithm.
4688 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
4689 * should be use.
4690 */
Emeric Brun521a0112012-10-22 12:22:55 +02004691static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004692smp_fetch_ssl_x_key_alg(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun521a0112012-10-22 12:22:55 +02004693{
Emeric Brunba841a12014-04-30 17:05:08 +02004694 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brun521a0112012-10-22 12:22:55 +02004695 X509 *crt;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004696 ASN1_OBJECT *algorithm;
Emeric Brun521a0112012-10-22 12:22:55 +02004697 int nid;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004698 struct connection *conn;
Emeric Brun521a0112012-10-22 12:22:55 +02004699
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004700 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004701 if (!conn || conn->xprt != &ssl_sock)
4702 return 0;
4703
4704 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun521a0112012-10-22 12:22:55 +02004705 smp->flags |= SMP_F_MAY_CHANGE;
4706 return 0;
4707 }
4708
Emeric Brunba841a12014-04-30 17:05:08 +02004709 if (cert_peer)
4710 crt = SSL_get_peer_certificate(conn->xprt_ctx);
4711 else
4712 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brun521a0112012-10-22 12:22:55 +02004713 if (!crt)
4714 return 0;
4715
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004716 X509_PUBKEY_get0_param(&algorithm, NULL, NULL, NULL, X509_get_X509_PUBKEY(crt));
4717 nid = OBJ_obj2nid(algorithm);
Emeric Brun521a0112012-10-22 12:22:55 +02004718
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004719 smp->data.u.str.str = (char *)OBJ_nid2sn(nid);
4720 if (!smp->data.u.str.str) {
Emeric Brunba841a12014-04-30 17:05:08 +02004721 /* SSL_get_peer_certificate increase X509 * ref count */
4722 if (cert_peer)
4723 X509_free(crt);
Emeric Brun521a0112012-10-22 12:22:55 +02004724 return 0;
Emeric Brun9bf3ba22013-10-07 14:31:44 +02004725 }
Emeric Brun521a0112012-10-22 12:22:55 +02004726
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004727 smp->data.type = SMP_T_STR;
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01004728 smp->flags |= SMP_F_CONST;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004729 smp->data.u.str.len = strlen(smp->data.u.str.str);
Emeric Brunba841a12014-04-30 17:05:08 +02004730 if (cert_peer)
4731 X509_free(crt);
Emeric Brun521a0112012-10-22 12:22:55 +02004732
4733 return 1;
4734}
4735
Emeric Brun645ae792014-04-30 14:21:06 +02004736/* boolean, returns true if front conn. transport layer is SSL.
4737 * This function is also usable on backend conn if the fetch keyword 5th
4738 * char is 'b'.
4739 */
Willy Tarreau7875d092012-09-10 08:20:03 +02004740static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004741smp_fetch_ssl_fc(const struct arg *args, struct sample *smp, const char *kw, void *private)
Willy Tarreau7875d092012-09-10 08:20:03 +02004742{
Willy Tarreaue237fe12016-03-10 17:05:28 +01004743 struct connection *conn = objt_conn((kw[4] != 'b') ? smp->sess->origin :
4744 smp->strm ? smp->strm->si[1].end : NULL);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004745
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004746 smp->data.type = SMP_T_BOOL;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004747 smp->data.u.sint = (conn && conn->xprt == &ssl_sock);
Willy Tarreau7875d092012-09-10 08:20:03 +02004748 return 1;
4749}
4750
Emeric Brun2525b6b2012-10-18 15:59:43 +02004751/* boolean, returns true if client present a SNI */
Willy Tarreau7875d092012-09-10 08:20:03 +02004752static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004753smp_fetch_ssl_fc_has_sni(const struct arg *args, struct sample *smp, const char *kw, void *private)
Willy Tarreau7875d092012-09-10 08:20:03 +02004754{
4755#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004756 struct connection *conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004757
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004758 smp->data.type = SMP_T_BOOL;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004759 smp->data.u.sint = (conn && conn->xprt == &ssl_sock) &&
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004760 conn->xprt_ctx &&
4761 SSL_get_servername(conn->xprt_ctx, TLSEXT_NAMETYPE_host_name) != NULL;
Willy Tarreau7875d092012-09-10 08:20:03 +02004762 return 1;
4763#else
4764 return 0;
4765#endif
4766}
4767
Nenad Merdanovic26ea8222015-05-18 02:28:57 +02004768/* boolean, returns true if client session has been resumed */
4769static int
4770smp_fetch_ssl_fc_is_resumed(const struct arg *args, struct sample *smp, const char *kw, void *private)
4771{
4772 struct connection *conn = objt_conn(smp->sess->origin);
4773
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004774 smp->data.type = SMP_T_BOOL;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004775 smp->data.u.sint = (conn && conn->xprt == &ssl_sock) &&
Nenad Merdanovic26ea8222015-05-18 02:28:57 +02004776 conn->xprt_ctx &&
4777 SSL_session_reused(conn->xprt_ctx);
4778 return 1;
4779}
4780
Emeric Brun645ae792014-04-30 14:21:06 +02004781/* string, returns the used cipher if front conn. transport layer is SSL.
4782 * This function is also usable on backend conn if the fetch keyword 5th
4783 * char is 'b'.
4784 */
Emeric Brun589fcad2012-10-16 14:13:26 +02004785static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004786smp_fetch_ssl_fc_cipher(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun589fcad2012-10-16 14:13:26 +02004787{
Willy Tarreaue237fe12016-03-10 17:05:28 +01004788 struct connection *conn = objt_conn((kw[4] != 'b') ? smp->sess->origin :
4789 smp->strm ? smp->strm->si[1].end : NULL);
Emeric Brun589fcad2012-10-16 14:13:26 +02004790
Willy Tarreaube508f12016-03-10 11:47:01 +01004791 smp->flags = 0;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004792 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
Emeric Brun589fcad2012-10-16 14:13:26 +02004793 return 0;
4794
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004795 smp->data.u.str.str = (char *)SSL_get_cipher_name(conn->xprt_ctx);
4796 if (!smp->data.u.str.str)
Emeric Brun589fcad2012-10-16 14:13:26 +02004797 return 0;
4798
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004799 smp->data.type = SMP_T_STR;
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01004800 smp->flags |= SMP_F_CONST;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004801 smp->data.u.str.len = strlen(smp->data.u.str.str);
Emeric Brun589fcad2012-10-16 14:13:26 +02004802
4803 return 1;
4804}
4805
Emeric Brun645ae792014-04-30 14:21:06 +02004806/* integer, returns the algoritm's keysize if front conn. transport layer
4807 * is SSL.
4808 * This function is also usable on backend conn if the fetch keyword 5th
4809 * char is 'b'.
4810 */
Emeric Brun589fcad2012-10-16 14:13:26 +02004811static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004812smp_fetch_ssl_fc_alg_keysize(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun589fcad2012-10-16 14:13:26 +02004813{
Willy Tarreaue237fe12016-03-10 17:05:28 +01004814 struct connection *conn = objt_conn((kw[4] != 'b') ? smp->sess->origin :
4815 smp->strm ? smp->strm->si[1].end : NULL);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004816
Willy Tarreaue237fe12016-03-10 17:05:28 +01004817 int sint;
Willy Tarreaube508f12016-03-10 11:47:01 +01004818
Emeric Brun589fcad2012-10-16 14:13:26 +02004819 smp->flags = 0;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004820 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
Emeric Brun589fcad2012-10-16 14:13:26 +02004821 return 0;
4822
Thierry FOURNIER07ee64e2015-07-06 23:43:03 +02004823 if (!SSL_get_cipher_bits(conn->xprt_ctx, &sint))
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004824 return 0;
4825
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004826 smp->data.u.sint = sint;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004827 smp->data.type = SMP_T_SINT;
Emeric Brun589fcad2012-10-16 14:13:26 +02004828
4829 return 1;
4830}
4831
Emeric Brun645ae792014-04-30 14:21:06 +02004832/* integer, returns the used keysize if front conn. transport layer is SSL.
4833 * This function is also usable on backend conn if the fetch keyword 5th
4834 * char is 'b'.
4835 */
Emeric Brun589fcad2012-10-16 14:13:26 +02004836static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004837smp_fetch_ssl_fc_use_keysize(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun589fcad2012-10-16 14:13:26 +02004838{
Willy Tarreaue237fe12016-03-10 17:05:28 +01004839 struct connection *conn = objt_conn((kw[4] != 'b') ? smp->sess->origin :
4840 smp->strm ? smp->strm->si[1].end : NULL);
Willy Tarreaube508f12016-03-10 11:47:01 +01004841
Emeric Brun589fcad2012-10-16 14:13:26 +02004842 smp->flags = 0;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004843 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
4844 return 0;
4845
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004846 smp->data.u.sint = (unsigned int)SSL_get_cipher_bits(conn->xprt_ctx, NULL);
4847 if (!smp->data.u.sint)
Emeric Brun589fcad2012-10-16 14:13:26 +02004848 return 0;
4849
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004850 smp->data.type = SMP_T_SINT;
Emeric Brun589fcad2012-10-16 14:13:26 +02004851
4852 return 1;
4853}
4854
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02004855#ifdef OPENSSL_NPN_NEGOTIATED
Willy Tarreau7875d092012-09-10 08:20:03 +02004856static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004857smp_fetch_ssl_fc_npn(const struct arg *args, struct sample *smp, const char *kw, void *private)
Willy Tarreaua33c6542012-10-15 13:19:06 +02004858{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004859 struct connection *conn;
4860
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01004861 smp->flags = SMP_F_CONST;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004862 smp->data.type = SMP_T_STR;
Willy Tarreaua33c6542012-10-15 13:19:06 +02004863
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004864 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004865 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
4866 return 0;
4867
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004868 smp->data.u.str.str = NULL;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004869 SSL_get0_next_proto_negotiated(conn->xprt_ctx,
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004870 (const unsigned char **)&smp->data.u.str.str, (unsigned *)&smp->data.u.str.len);
Willy Tarreaua33c6542012-10-15 13:19:06 +02004871
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004872 if (!smp->data.u.str.str)
Willy Tarreaua33c6542012-10-15 13:19:06 +02004873 return 0;
4874
4875 return 1;
Willy Tarreaua33c6542012-10-15 13:19:06 +02004876}
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02004877#endif
Willy Tarreaua33c6542012-10-15 13:19:06 +02004878
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01004879#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Willy Tarreauab861d32013-04-02 02:30:41 +02004880static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004881smp_fetch_ssl_fc_alpn(const struct arg *args, struct sample *smp, const char *kw, void *private)
Willy Tarreauab861d32013-04-02 02:30:41 +02004882{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004883 struct connection *conn;
4884
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01004885 smp->flags = SMP_F_CONST;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004886 smp->data.type = SMP_T_STR;
Willy Tarreauab861d32013-04-02 02:30:41 +02004887
Willy Tarreaue26bf052015-05-12 10:30:12 +02004888 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004889 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
Willy Tarreauab861d32013-04-02 02:30:41 +02004890 return 0;
4891
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004892 smp->data.u.str.str = NULL;
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01004893 SSL_get0_alpn_selected(conn->xprt_ctx,
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004894 (const unsigned char **)&smp->data.u.str.str, (unsigned *)&smp->data.u.str.len);
Willy Tarreauab861d32013-04-02 02:30:41 +02004895
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004896 if (!smp->data.u.str.str)
Willy Tarreauab861d32013-04-02 02:30:41 +02004897 return 0;
4898
4899 return 1;
4900}
4901#endif
4902
Emeric Brun645ae792014-04-30 14:21:06 +02004903/* string, returns the used protocol if front conn. transport layer is SSL.
4904 * This function is also usable on backend conn if the fetch keyword 5th
4905 * char is 'b'.
4906 */
Willy Tarreaua33c6542012-10-15 13:19:06 +02004907static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004908smp_fetch_ssl_fc_protocol(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun589fcad2012-10-16 14:13:26 +02004909{
Willy Tarreaue237fe12016-03-10 17:05:28 +01004910 struct connection *conn = objt_conn((kw[4] != 'b') ? smp->sess->origin :
4911 smp->strm ? smp->strm->si[1].end : NULL);
Willy Tarreaube508f12016-03-10 11:47:01 +01004912
Emeric Brun589fcad2012-10-16 14:13:26 +02004913 smp->flags = 0;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004914 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
4915 return 0;
4916
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004917 smp->data.u.str.str = (char *)SSL_get_version(conn->xprt_ctx);
4918 if (!smp->data.u.str.str)
Emeric Brun589fcad2012-10-16 14:13:26 +02004919 return 0;
4920
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004921 smp->data.type = SMP_T_STR;
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01004922 smp->flags = SMP_F_CONST;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004923 smp->data.u.str.len = strlen(smp->data.u.str.str);
Emeric Brun589fcad2012-10-16 14:13:26 +02004924
4925 return 1;
4926}
4927
Willy Tarreau87b09662015-04-03 00:22:06 +02004928/* binary, returns the SSL stream id if front conn. transport layer is SSL.
Emeric Brun645ae792014-04-30 14:21:06 +02004929 * This function is also usable on backend conn if the fetch keyword 5th
4930 * char is 'b'.
4931 */
Emeric Brun589fcad2012-10-16 14:13:26 +02004932static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004933smp_fetch_ssl_fc_session_id(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brunfe68f682012-10-16 14:59:28 +02004934{
4935#if OPENSSL_VERSION_NUMBER > 0x0090800fL
Willy Tarreaue237fe12016-03-10 17:05:28 +01004936 struct connection *conn = objt_conn((kw[4] != 'b') ? smp->sess->origin :
4937 smp->strm ? smp->strm->si[1].end : NULL);
Emeric Brunfe68f682012-10-16 14:59:28 +02004938
Willy Tarreaue237fe12016-03-10 17:05:28 +01004939 SSL_SESSION *ssl_sess;
Willy Tarreaube508f12016-03-10 11:47:01 +01004940
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01004941 smp->flags = SMP_F_CONST;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004942 smp->data.type = SMP_T_BIN;
Emeric Brunfe68f682012-10-16 14:59:28 +02004943
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004944 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
4945 return 0;
4946
Willy Tarreau192252e2015-04-04 01:47:55 +02004947 ssl_sess = SSL_get_session(conn->xprt_ctx);
4948 if (!ssl_sess)
Emeric Brunfe68f682012-10-16 14:59:28 +02004949 return 0;
4950
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004951 smp->data.u.str.str = (char *)SSL_SESSION_get_id(ssl_sess, (unsigned int *)&smp->data.u.str.len);
4952 if (!smp->data.u.str.str || !smp->data.u.str.len)
Emeric Brunfe68f682012-10-16 14:59:28 +02004953 return 0;
4954
4955 return 1;
4956#else
4957 return 0;
4958#endif
4959}
4960
4961static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004962smp_fetch_ssl_fc_sni(const struct arg *args, struct sample *smp, const char *kw, void *private)
Willy Tarreau7875d092012-09-10 08:20:03 +02004963{
4964#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004965 struct connection *conn;
4966
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01004967 smp->flags = SMP_F_CONST;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004968 smp->data.type = SMP_T_STR;
Willy Tarreau7875d092012-09-10 08:20:03 +02004969
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004970 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004971 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
4972 return 0;
4973
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004974 smp->data.u.str.str = (char *)SSL_get_servername(conn->xprt_ctx, TLSEXT_NAMETYPE_host_name);
4975 if (!smp->data.u.str.str)
Willy Tarreau3e394c92012-09-14 23:56:58 +02004976 return 0;
4977
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004978 smp->data.u.str.len = strlen(smp->data.u.str.str);
Willy Tarreau7875d092012-09-10 08:20:03 +02004979 return 1;
4980#else
4981 return 0;
4982#endif
4983}
4984
David Sc1ad52e2014-04-08 18:48:47 -04004985static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004986smp_fetch_ssl_fc_unique_id(const struct arg *args, struct sample *smp, const char *kw, void *private)
David Sc1ad52e2014-04-08 18:48:47 -04004987{
4988#if OPENSSL_VERSION_NUMBER > 0x0090800fL
Willy Tarreaue237fe12016-03-10 17:05:28 +01004989 struct connection *conn = objt_conn((kw[4] != 'b') ? smp->sess->origin :
4990 smp->strm ? smp->strm->si[1].end : NULL);
4991
David Sc1ad52e2014-04-08 18:48:47 -04004992 int finished_len;
David Sc1ad52e2014-04-08 18:48:47 -04004993 struct chunk *finished_trash;
David Sc1ad52e2014-04-08 18:48:47 -04004994
4995 smp->flags = 0;
David Sc1ad52e2014-04-08 18:48:47 -04004996 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
4997 return 0;
4998
4999 if (!(conn->flags & CO_FL_CONNECTED)) {
5000 smp->flags |= SMP_F_MAY_CHANGE;
5001 return 0;
5002 }
5003
5004 finished_trash = get_trash_chunk();
5005 if (!SSL_session_reused(conn->xprt_ctx))
5006 finished_len = SSL_get_peer_finished(conn->xprt_ctx, finished_trash->str, finished_trash->size);
5007 else
5008 finished_len = SSL_get_finished(conn->xprt_ctx, finished_trash->str, finished_trash->size);
5009
5010 if (!finished_len)
5011 return 0;
5012
Emeric Brunb73a9b02014-04-30 18:49:19 +02005013 finished_trash->len = finished_len;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005014 smp->data.u.str = *finished_trash;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005015 smp->data.type = SMP_T_BIN;
David Sc1ad52e2014-04-08 18:48:47 -04005016
5017 return 1;
5018#else
5019 return 0;
5020#endif
5021}
5022
Emeric Brun2525b6b2012-10-18 15:59:43 +02005023/* integer, returns the first verify error in CA chain of client certificate chain. */
Emeric Brunf282a812012-09-21 15:27:54 +02005024static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005025smp_fetch_ssl_c_ca_err(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brunf282a812012-09-21 15:27:54 +02005026{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005027 struct connection *conn;
5028
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02005029 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005030 if (!conn || conn->xprt != &ssl_sock)
5031 return 0;
5032
5033 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunf282a812012-09-21 15:27:54 +02005034 smp->flags = SMP_F_MAY_CHANGE;
5035 return 0;
5036 }
5037
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005038 smp->data.type = SMP_T_SINT;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005039 smp->data.u.sint = (unsigned long long int)SSL_SOCK_ST_TO_CA_ERROR(conn->xprt_st);
Emeric Brunf282a812012-09-21 15:27:54 +02005040 smp->flags = 0;
5041
5042 return 1;
5043}
5044
Emeric Brun2525b6b2012-10-18 15:59:43 +02005045/* integer, returns the depth of the first verify error in CA chain of client certificate chain. */
Emeric Brunf282a812012-09-21 15:27:54 +02005046static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005047smp_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 +02005048{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005049 struct connection *conn;
5050
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 != &ssl_sock)
Emeric Brunf282a812012-09-21 15:27:54 +02005053 return 0;
5054
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005055 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunf282a812012-09-21 15:27:54 +02005056 smp->flags = SMP_F_MAY_CHANGE;
5057 return 0;
5058 }
5059
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005060 smp->data.type = SMP_T_SINT;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005061 smp->data.u.sint = (long long int)SSL_SOCK_ST_TO_CAEDEPTH(conn->xprt_st);
Emeric Brunf282a812012-09-21 15:27:54 +02005062 smp->flags = 0;
5063
5064 return 1;
5065}
5066
Emeric Brun2525b6b2012-10-18 15:59:43 +02005067/* integer, returns the first verify error on client certificate */
Emeric Brunf282a812012-09-21 15:27:54 +02005068static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005069smp_fetch_ssl_c_err(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brunf282a812012-09-21 15:27:54 +02005070{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005071 struct connection *conn;
5072
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02005073 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005074 if (!conn || conn->xprt != &ssl_sock)
5075 return 0;
5076
5077 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunf282a812012-09-21 15:27:54 +02005078 smp->flags = SMP_F_MAY_CHANGE;
5079 return 0;
5080 }
5081
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005082 smp->data.type = SMP_T_SINT;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005083 smp->data.u.sint = (long long int)SSL_SOCK_ST_TO_CRTERROR(conn->xprt_st);
Emeric Brunf282a812012-09-21 15:27:54 +02005084 smp->flags = 0;
5085
5086 return 1;
5087}
5088
Emeric Brun2525b6b2012-10-18 15:59:43 +02005089/* integer, returns the verify result on client cert */
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02005090static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005091smp_fetch_ssl_c_verify(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02005092{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005093 struct connection *conn;
5094
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02005095 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005096 if (!conn || conn->xprt != &ssl_sock)
5097 return 0;
5098
5099 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02005100 smp->flags = SMP_F_MAY_CHANGE;
5101 return 0;
5102 }
5103
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005104 if (!conn->xprt_ctx)
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02005105 return 0;
5106
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005107 smp->data.type = SMP_T_SINT;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005108 smp->data.u.sint = (long long int)SSL_get_verify_result(conn->xprt_ctx);
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02005109 smp->flags = 0;
5110
5111 return 1;
5112}
5113
Emeric Brunfb510ea2012-10-05 12:00:26 +02005114/* parse the "ca-file" bind keyword */
5115static 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 +02005116{
5117 if (!*args[cur_arg + 1]) {
5118 if (err)
5119 memprintf(err, "'%s' : missing CAfile path", args[cur_arg]);
5120 return ERR_ALERT | ERR_FATAL;
5121 }
5122
Emeric Brunef42d922012-10-11 16:11:36 +02005123 if ((*args[cur_arg + 1] != '/') && global.ca_base)
5124 memprintf(&conf->ca_file, "%s/%s", global.ca_base, args[cur_arg + 1]);
5125 else
5126 memprintf(&conf->ca_file, "%s", args[cur_arg + 1]);
Emeric Brunc8e8d122012-10-02 18:42:10 +02005127
Emeric Brund94b3fe2012-09-20 18:23:56 +02005128 return 0;
5129}
5130
Christopher Faulet31af49d2015-06-09 17:29:50 +02005131/* parse the "ca-sign-file" bind keyword */
5132static int bind_parse_ca_sign_file(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5133{
5134 if (!*args[cur_arg + 1]) {
5135 if (err)
5136 memprintf(err, "'%s' : missing CAfile path", args[cur_arg]);
5137 return ERR_ALERT | ERR_FATAL;
5138 }
5139
5140 if ((*args[cur_arg + 1] != '/') && global.ca_base)
5141 memprintf(&conf->ca_sign_file, "%s/%s", global.ca_base, args[cur_arg + 1]);
5142 else
5143 memprintf(&conf->ca_sign_file, "%s", args[cur_arg + 1]);
5144
5145 return 0;
5146}
5147
Bertrand Jacquinff13c062016-11-13 16:37:11 +00005148/* parse the "ca-sign-pass" bind keyword */
Christopher Faulet31af49d2015-06-09 17:29:50 +02005149static int bind_parse_ca_sign_pass(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5150{
5151 if (!*args[cur_arg + 1]) {
5152 if (err)
5153 memprintf(err, "'%s' : missing CAkey password", args[cur_arg]);
5154 return ERR_ALERT | ERR_FATAL;
5155 }
5156 memprintf(&conf->ca_sign_pass, "%s", args[cur_arg + 1]);
5157 return 0;
5158}
5159
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005160/* parse the "ciphers" bind keyword */
Willy Tarreau4348fad2012-09-20 16:48:07 +02005161static 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 +02005162{
5163 if (!*args[cur_arg + 1]) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02005164 memprintf(err, "'%s' : missing cipher suite", args[cur_arg]);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005165 return ERR_ALERT | ERR_FATAL;
5166 }
5167
Emeric Brun76d88952012-10-05 15:47:31 +02005168 free(conf->ciphers);
Willy Tarreau4348fad2012-09-20 16:48:07 +02005169 conf->ciphers = strdup(args[cur_arg + 1]);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005170 return 0;
5171}
5172
5173/* parse the "crt" bind keyword */
Willy Tarreau4348fad2012-09-20 16:48:07 +02005174static 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 +02005175{
Willy Tarreau38011032013-08-13 16:59:39 +02005176 char path[MAXPATHLEN];
Willy Tarreaub75d6922014-04-14 18:05:41 +02005177
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005178 if (!*args[cur_arg + 1]) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02005179 memprintf(err, "'%s' : missing certificate location", args[cur_arg]);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005180 return ERR_ALERT | ERR_FATAL;
5181 }
5182
Emeric Brunc8e8d122012-10-02 18:42:10 +02005183 if ((*args[cur_arg + 1] != '/' ) && global.crt_base) {
Willy Tarreau38011032013-08-13 16:59:39 +02005184 if ((strlen(global.crt_base) + 1 + strlen(args[cur_arg + 1]) + 1) > MAXPATHLEN) {
Emeric Brunc8e8d122012-10-02 18:42:10 +02005185 memprintf(err, "'%s' : path too long", args[cur_arg]);
5186 return ERR_ALERT | ERR_FATAL;
5187 }
Willy Tarreaub75d6922014-04-14 18:05:41 +02005188 snprintf(path, sizeof(path), "%s/%s", global.crt_base, args[cur_arg + 1]);
Emeric Brunc8e8d122012-10-02 18:42:10 +02005189 if (ssl_sock_load_cert(path, conf, px, err) > 0)
5190 return ERR_ALERT | ERR_FATAL;
5191
5192 return 0;
5193 }
5194
Willy Tarreau4348fad2012-09-20 16:48:07 +02005195 if (ssl_sock_load_cert(args[cur_arg + 1], conf, px, err) > 0)
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005196 return ERR_ALERT | ERR_FATAL;
Emeric Brund94b3fe2012-09-20 18:23:56 +02005197
5198 return 0;
5199}
5200
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01005201/* parse the "crt-list" bind keyword */
5202static int bind_parse_crt_list(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5203{
5204 if (!*args[cur_arg + 1]) {
5205 memprintf(err, "'%s' : missing certificate location", args[cur_arg]);
5206 return ERR_ALERT | ERR_FATAL;
5207 }
5208
Willy Tarreauad1731d2013-04-02 17:35:58 +02005209 if (ssl_sock_load_cert_list_file(args[cur_arg + 1], conf, px, err) > 0) {
5210 memprintf(err, "'%s' : %s", args[cur_arg], *err);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01005211 return ERR_ALERT | ERR_FATAL;
Willy Tarreauad1731d2013-04-02 17:35:58 +02005212 }
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01005213
5214 return 0;
5215}
5216
Emeric Brunfb510ea2012-10-05 12:00:26 +02005217/* parse the "crl-file" bind keyword */
5218static 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 +02005219{
Emeric Brun051cdab2012-10-02 19:25:50 +02005220#ifndef X509_V_FLAG_CRL_CHECK
5221 if (err)
5222 memprintf(err, "'%s' : library does not support CRL verify", args[cur_arg]);
5223 return ERR_ALERT | ERR_FATAL;
5224#else
Emeric Brund94b3fe2012-09-20 18:23:56 +02005225 if (!*args[cur_arg + 1]) {
5226 if (err)
5227 memprintf(err, "'%s' : missing CRLfile path", args[cur_arg]);
5228 return ERR_ALERT | ERR_FATAL;
5229 }
Emeric Brun2b58d042012-09-20 17:10:03 +02005230
Emeric Brunef42d922012-10-11 16:11:36 +02005231 if ((*args[cur_arg + 1] != '/') && global.ca_base)
5232 memprintf(&conf->crl_file, "%s/%s", global.ca_base, args[cur_arg + 1]);
5233 else
5234 memprintf(&conf->crl_file, "%s", args[cur_arg + 1]);
Emeric Brunc8e8d122012-10-02 18:42:10 +02005235
Emeric Brun2b58d042012-09-20 17:10:03 +02005236 return 0;
Emeric Brun051cdab2012-10-02 19:25:50 +02005237#endif
Emeric Brun2b58d042012-09-20 17:10:03 +02005238}
5239
Bertrand Jacquinff13c062016-11-13 16:37:11 +00005240/* parse the "ecdhe" bind keyword keyword */
Emeric Brun2b58d042012-09-20 17:10:03 +02005241static int bind_parse_ecdhe(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5242{
5243#if OPENSSL_VERSION_NUMBER < 0x0090800fL
5244 if (err)
5245 memprintf(err, "'%s' : library does not support elliptic curve Diffie-Hellman (too old)", args[cur_arg]);
5246 return ERR_ALERT | ERR_FATAL;
5247#elif defined(OPENSSL_NO_ECDH)
5248 if (err)
5249 memprintf(err, "'%s' : library does not support elliptic curve Diffie-Hellman (disabled via OPENSSL_NO_ECDH)", args[cur_arg]);
5250 return ERR_ALERT | ERR_FATAL;
5251#else
5252 if (!*args[cur_arg + 1]) {
5253 if (err)
5254 memprintf(err, "'%s' : missing named curve", args[cur_arg]);
5255 return ERR_ALERT | ERR_FATAL;
5256 }
5257
5258 conf->ecdhe = strdup(args[cur_arg + 1]);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005259
5260 return 0;
Emeric Brun2b58d042012-09-20 17:10:03 +02005261#endif
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005262}
5263
Bertrand Jacquinff13c062016-11-13 16:37:11 +00005264/* parse the "crt-ignore-err" and "ca-ignore-err" bind keywords */
Emeric Brun81c00f02012-09-21 14:31:21 +02005265static int bind_parse_ignore_err(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5266{
5267 int code;
5268 char *p = args[cur_arg + 1];
5269 unsigned long long *ignerr = &conf->crt_ignerr;
5270
5271 if (!*p) {
5272 if (err)
5273 memprintf(err, "'%s' : missing error IDs list", args[cur_arg]);
5274 return ERR_ALERT | ERR_FATAL;
5275 }
5276
5277 if (strcmp(args[cur_arg], "ca-ignore-err") == 0)
5278 ignerr = &conf->ca_ignerr;
5279
5280 if (strcmp(p, "all") == 0) {
5281 *ignerr = ~0ULL;
5282 return 0;
5283 }
5284
5285 while (p) {
5286 code = atoi(p);
5287 if ((code <= 0) || (code > 63)) {
5288 if (err)
5289 memprintf(err, "'%s' : ID '%d' out of range (1..63) in error IDs list '%s'",
5290 args[cur_arg], code, args[cur_arg + 1]);
5291 return ERR_ALERT | ERR_FATAL;
5292 }
5293 *ignerr |= 1ULL << code;
5294 p = strchr(p, ',');
5295 if (p)
5296 p++;
5297 }
5298
Emeric Brun2cb7ae52012-10-05 14:14:21 +02005299 return 0;
5300}
5301
5302/* parse the "force-sslv3" bind keyword */
5303static int bind_parse_force_sslv3(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5304{
5305 conf->ssl_options |= BC_SSL_O_USE_SSLV3;
5306 return 0;
5307}
5308
5309/* parse the "force-tlsv10" bind keyword */
5310static int bind_parse_force_tlsv10(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5311{
5312 conf->ssl_options |= BC_SSL_O_USE_TLSV10;
Emeric Brun2d0c4822012-10-02 13:45:20 +02005313 return 0;
5314}
5315
Emeric Brun2cb7ae52012-10-05 14:14:21 +02005316/* parse the "force-tlsv11" bind keyword */
5317static int bind_parse_force_tlsv11(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5318{
5319#if SSL_OP_NO_TLSv1_1
5320 conf->ssl_options |= BC_SSL_O_USE_TLSV11;
5321 return 0;
5322#else
5323 if (err)
5324 memprintf(err, "'%s' : library does not support protocol TLSv1.1", args[cur_arg]);
5325 return ERR_ALERT | ERR_FATAL;
5326#endif
5327}
5328
5329/* parse the "force-tlsv12" bind keyword */
5330static int bind_parse_force_tlsv12(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5331{
5332#if SSL_OP_NO_TLSv1_2
5333 conf->ssl_options |= BC_SSL_O_USE_TLSV12;
5334 return 0;
5335#else
5336 if (err)
5337 memprintf(err, "'%s' : library does not support protocol TLSv1.2", args[cur_arg]);
5338 return ERR_ALERT | ERR_FATAL;
5339#endif
5340}
5341
5342
Emeric Brun2d0c4822012-10-02 13:45:20 +02005343/* parse the "no-tls-tickets" bind keyword */
5344static int bind_parse_no_tls_tickets(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5345{
Emeric Brun89675492012-10-05 13:48:26 +02005346 conf->ssl_options |= BC_SSL_O_NO_TLS_TICKETS;
Emeric Brun81c00f02012-09-21 14:31:21 +02005347 return 0;
5348}
5349
Emeric Brun2d0c4822012-10-02 13:45:20 +02005350
Emeric Brun9b3009b2012-10-05 11:55:06 +02005351/* parse the "no-sslv3" bind keyword */
5352static 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 +02005353{
Emeric Brun89675492012-10-05 13:48:26 +02005354 conf->ssl_options |= BC_SSL_O_NO_SSLV3;
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005355 return 0;
5356}
5357
Emeric Brun9b3009b2012-10-05 11:55:06 +02005358/* parse the "no-tlsv10" bind keyword */
5359static 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 +02005360{
Emeric Brun89675492012-10-05 13:48:26 +02005361 conf->ssl_options |= BC_SSL_O_NO_TLSV10;
Emeric Brunc0ff4922012-09-28 19:37:02 +02005362 return 0;
5363}
5364
Emeric Brun9b3009b2012-10-05 11:55:06 +02005365/* parse the "no-tlsv11" bind keyword */
5366static 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 +02005367{
Emeric Brun89675492012-10-05 13:48:26 +02005368 conf->ssl_options |= BC_SSL_O_NO_TLSV11;
Emeric Brunc0ff4922012-09-28 19:37:02 +02005369 return 0;
5370}
5371
Emeric Brun9b3009b2012-10-05 11:55:06 +02005372/* parse the "no-tlsv12" bind keyword */
5373static 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 +02005374{
Emeric Brun89675492012-10-05 13:48:26 +02005375 conf->ssl_options |= BC_SSL_O_NO_TLSV12;
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005376 return 0;
5377}
5378
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02005379/* parse the "npn" bind keyword */
5380static int bind_parse_npn(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5381{
5382#ifdef OPENSSL_NPN_NEGOTIATED
5383 char *p1, *p2;
5384
5385 if (!*args[cur_arg + 1]) {
5386 memprintf(err, "'%s' : missing the comma-delimited NPN protocol suite", args[cur_arg]);
5387 return ERR_ALERT | ERR_FATAL;
5388 }
5389
5390 free(conf->npn_str);
5391
Willy Tarreau3724da12016-02-12 17:11:12 +01005392 /* the NPN string is built as a suite of (<len> <name>)*,
5393 * so we reuse each comma to store the next <len> and need
5394 * one more for the end of the string.
5395 */
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02005396 conf->npn_len = strlen(args[cur_arg + 1]) + 1;
Willy Tarreau3724da12016-02-12 17:11:12 +01005397 conf->npn_str = calloc(1, conf->npn_len + 1);
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02005398 memcpy(conf->npn_str + 1, args[cur_arg + 1], conf->npn_len);
5399
5400 /* replace commas with the name length */
5401 p1 = conf->npn_str;
5402 p2 = p1 + 1;
5403 while (1) {
5404 p2 = memchr(p1 + 1, ',', conf->npn_str + conf->npn_len - (p1 + 1));
5405 if (!p2)
5406 p2 = p1 + 1 + strlen(p1 + 1);
5407
5408 if (p2 - (p1 + 1) > 255) {
5409 *p2 = '\0';
5410 memprintf(err, "'%s' : NPN protocol name too long : '%s'", args[cur_arg], p1 + 1);
5411 return ERR_ALERT | ERR_FATAL;
5412 }
5413
5414 *p1 = p2 - (p1 + 1);
5415 p1 = p2;
5416
5417 if (!*p2)
5418 break;
5419
5420 *(p2++) = '\0';
5421 }
5422 return 0;
5423#else
5424 if (err)
5425 memprintf(err, "'%s' : library does not support TLS NPN extension", args[cur_arg]);
5426 return ERR_ALERT | ERR_FATAL;
5427#endif
5428}
5429
Willy Tarreauab861d32013-04-02 02:30:41 +02005430/* parse the "alpn" bind keyword */
5431static int bind_parse_alpn(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5432{
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01005433#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Willy Tarreauab861d32013-04-02 02:30:41 +02005434 char *p1, *p2;
5435
5436 if (!*args[cur_arg + 1]) {
5437 memprintf(err, "'%s' : missing the comma-delimited ALPN protocol suite", args[cur_arg]);
5438 return ERR_ALERT | ERR_FATAL;
5439 }
5440
5441 free(conf->alpn_str);
5442
Marcoen Hirschbergbef60912016-02-12 17:05:24 +01005443 /* the ALPN string is built as a suite of (<len> <name>)*,
5444 * so we reuse each comma to store the next <len> and need
5445 * one more for the end of the string.
5446 */
Willy Tarreauab861d32013-04-02 02:30:41 +02005447 conf->alpn_len = strlen(args[cur_arg + 1]) + 1;
Marcoen Hirschbergbef60912016-02-12 17:05:24 +01005448 conf->alpn_str = calloc(1, conf->alpn_len + 1);
Willy Tarreauab861d32013-04-02 02:30:41 +02005449 memcpy(conf->alpn_str + 1, args[cur_arg + 1], conf->alpn_len);
5450
5451 /* replace commas with the name length */
5452 p1 = conf->alpn_str;
5453 p2 = p1 + 1;
5454 while (1) {
5455 p2 = memchr(p1 + 1, ',', conf->alpn_str + conf->alpn_len - (p1 + 1));
5456 if (!p2)
5457 p2 = p1 + 1 + strlen(p1 + 1);
5458
5459 if (p2 - (p1 + 1) > 255) {
5460 *p2 = '\0';
5461 memprintf(err, "'%s' : ALPN protocol name too long : '%s'", args[cur_arg], p1 + 1);
5462 return ERR_ALERT | ERR_FATAL;
5463 }
5464
5465 *p1 = p2 - (p1 + 1);
5466 p1 = p2;
5467
5468 if (!*p2)
5469 break;
5470
5471 *(p2++) = '\0';
5472 }
5473 return 0;
5474#else
5475 if (err)
5476 memprintf(err, "'%s' : library does not support TLS ALPN extension", args[cur_arg]);
5477 return ERR_ALERT | ERR_FATAL;
5478#endif
5479}
5480
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005481/* parse the "ssl" bind keyword */
Willy Tarreau4348fad2012-09-20 16:48:07 +02005482static 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 +02005483{
Willy Tarreau81796be2012-09-22 19:11:47 +02005484 struct listener *l;
5485
Willy Tarreau4348fad2012-09-20 16:48:07 +02005486 conf->is_ssl = 1;
Emeric Brun76d88952012-10-05 15:47:31 +02005487
5488 if (global.listen_default_ciphers && !conf->ciphers)
5489 conf->ciphers = strdup(global.listen_default_ciphers);
Emeric Brun2c86cbf2014-10-30 15:56:50 +01005490 conf->ssl_options |= global.listen_default_ssloptions;
Emeric Brun76d88952012-10-05 15:47:31 +02005491
Willy Tarreau81796be2012-09-22 19:11:47 +02005492 list_for_each_entry(l, &conf->listeners, by_bind)
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02005493 l->xprt = &ssl_sock;
Willy Tarreau81796be2012-09-22 19:11:47 +02005494
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005495 return 0;
5496}
5497
Christopher Faulet31af49d2015-06-09 17:29:50 +02005498/* parse the "generate-certificates" bind keyword */
5499static int bind_parse_generate_certs(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5500{
5501#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
5502 conf->generate_certs = 1;
5503#else
5504 memprintf(err, "%sthis version of openssl cannot generate SSL certificates.\n",
5505 err && *err ? *err : "");
5506#endif
5507 return 0;
5508}
5509
Emmanuel Hocdet65623372013-01-24 17:17:15 +01005510/* parse the "strict-sni" bind keyword */
5511static int bind_parse_strict_sni(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5512{
5513 conf->strict_sni = 1;
5514 return 0;
Nenad Merdanovic05552d42015-02-27 19:56:49 +01005515}
5516
5517/* parse the "tls-ticket-keys" bind keyword */
5518static int bind_parse_tls_ticket_keys(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5519{
5520#if (defined SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB && TLS_TICKETS_NO > 0)
5521 FILE *f;
5522 int i = 0;
5523 char thisline[LINESIZE];
Nenad Merdanovic146defa2015-05-09 08:46:00 +02005524 struct tls_keys_ref *keys_ref;
Nenad Merdanovic05552d42015-02-27 19:56:49 +01005525
5526 if (!*args[cur_arg + 1]) {
5527 if (err)
5528 memprintf(err, "'%s' : missing TLS ticket keys file path", args[cur_arg]);
5529 return ERR_ALERT | ERR_FATAL;
5530 }
5531
Nenad Merdanovic200b0fa2015-05-09 08:46:01 +02005532 keys_ref = tlskeys_ref_lookup(args[cur_arg + 1]);
5533 if(keys_ref) {
5534 conf->keys_ref = keys_ref;
5535 return 0;
5536 }
5537
Vincent Bernat02779b62016-04-03 13:48:43 +02005538 keys_ref = malloc(sizeof(*keys_ref));
Nenad Merdanovic146defa2015-05-09 08:46:00 +02005539 keys_ref->tlskeys = malloc(TLS_TICKETS_NO * sizeof(struct tls_sess_key));
Nenad Merdanovic05552d42015-02-27 19:56:49 +01005540
5541 if ((f = fopen(args[cur_arg + 1], "r")) == NULL) {
5542 if (err)
5543 memprintf(err, "'%s' : unable to load ssl tickets keys file", args[cur_arg+1]);
5544 return ERR_ALERT | ERR_FATAL;
5545 }
5546
Nenad Merdanovic146defa2015-05-09 08:46:00 +02005547 keys_ref->filename = strdup(args[cur_arg + 1]);
5548
Nenad Merdanovic05552d42015-02-27 19:56:49 +01005549 while (fgets(thisline, sizeof(thisline), f) != NULL) {
5550 int len = strlen(thisline);
5551 /* Strip newline characters from the end */
5552 if(thisline[len - 1] == '\n')
5553 thisline[--len] = 0;
5554
5555 if(thisline[len - 1] == '\r')
5556 thisline[--len] = 0;
5557
Nenad Merdanovic146defa2015-05-09 08:46:00 +02005558 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 +01005559 if (err)
5560 memprintf(err, "'%s' : unable to decode base64 key on line %d", args[cur_arg+1], i + 1);
mildis16aa0152016-06-22 17:46:29 +02005561 fclose(f);
Nenad Merdanovic05552d42015-02-27 19:56:49 +01005562 return ERR_ALERT | ERR_FATAL;
5563 }
5564 i++;
5565 }
5566
5567 if (i < TLS_TICKETS_NO) {
5568 if (err)
5569 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 +02005570 fclose(f);
Nenad Merdanovic05552d42015-02-27 19:56:49 +01005571 return ERR_ALERT | ERR_FATAL;
5572 }
5573
5574 fclose(f);
5575
5576 /* Use penultimate key for encryption, handle when TLS_TICKETS_NO = 1 */
Nenad Merdanovic17891152016-03-25 22:16:57 +01005577 i -= 2;
5578 keys_ref->tls_ticket_enc_index = i < 0 ? 0 : i % TLS_TICKETS_NO;
Nenad Merdanovic200b0fa2015-05-09 08:46:01 +02005579 keys_ref->unique_id = -1;
Nenad Merdanovic146defa2015-05-09 08:46:00 +02005580 conf->keys_ref = keys_ref;
Nenad Merdanovic05552d42015-02-27 19:56:49 +01005581
Nenad Merdanovic200b0fa2015-05-09 08:46:01 +02005582 LIST_ADD(&tlskeys_reference, &keys_ref->list);
5583
Nenad Merdanovic05552d42015-02-27 19:56:49 +01005584 return 0;
5585#else
5586 if (err)
5587 memprintf(err, "'%s' : TLS ticket callback extension not supported", args[cur_arg]);
5588 return ERR_ALERT | ERR_FATAL;
5589#endif /* SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB */
Emmanuel Hocdet65623372013-01-24 17:17:15 +01005590}
5591
Emeric Brund94b3fe2012-09-20 18:23:56 +02005592/* parse the "verify" bind keyword */
5593static int bind_parse_verify(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5594{
5595 if (!*args[cur_arg + 1]) {
5596 if (err)
5597 memprintf(err, "'%s' : missing verify method", args[cur_arg]);
5598 return ERR_ALERT | ERR_FATAL;
5599 }
5600
5601 if (strcmp(args[cur_arg + 1], "none") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01005602 conf->verify = SSL_SOCK_VERIFY_NONE;
Emeric Brund94b3fe2012-09-20 18:23:56 +02005603 else if (strcmp(args[cur_arg + 1], "optional") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01005604 conf->verify = SSL_SOCK_VERIFY_OPTIONAL;
Emeric Brund94b3fe2012-09-20 18:23:56 +02005605 else if (strcmp(args[cur_arg + 1], "required") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01005606 conf->verify = SSL_SOCK_VERIFY_REQUIRED;
Emeric Brund94b3fe2012-09-20 18:23:56 +02005607 else {
5608 if (err)
5609 memprintf(err, "'%s' : unknown verify method '%s', only 'none', 'optional', and 'required' are supported\n",
5610 args[cur_arg], args[cur_arg + 1]);
5611 return ERR_ALERT | ERR_FATAL;
5612 }
5613
5614 return 0;
5615}
5616
Willy Tarreau92faadf2012-10-10 23:04:25 +02005617/************** "server" keywords ****************/
5618
Emeric Brunef42d922012-10-11 16:11:36 +02005619/* parse the "ca-file" server keyword */
5620static int srv_parse_ca_file(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5621{
5622 if (!*args[*cur_arg + 1]) {
5623 if (err)
5624 memprintf(err, "'%s' : missing CAfile path", args[*cur_arg]);
5625 return ERR_ALERT | ERR_FATAL;
5626 }
5627
5628 if ((*args[*cur_arg + 1] != '/') && global.ca_base)
5629 memprintf(&newsrv->ssl_ctx.ca_file, "%s/%s", global.ca_base, args[*cur_arg + 1]);
5630 else
5631 memprintf(&newsrv->ssl_ctx.ca_file, "%s", args[*cur_arg + 1]);
5632
5633 return 0;
5634}
5635
Willy Tarreau92faadf2012-10-10 23:04:25 +02005636/* parse the "check-ssl" server keyword */
5637static int srv_parse_check_ssl(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5638{
5639 newsrv->check.use_ssl = 1;
5640 if (global.connect_default_ciphers && !newsrv->ssl_ctx.ciphers)
5641 newsrv->ssl_ctx.ciphers = strdup(global.connect_default_ciphers);
Emeric Brun2c86cbf2014-10-30 15:56:50 +01005642 newsrv->ssl_ctx.options |= global.connect_default_ssloptions;
Willy Tarreau92faadf2012-10-10 23:04:25 +02005643 return 0;
5644}
5645
5646/* parse the "ciphers" server keyword */
5647static int srv_parse_ciphers(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5648{
5649 if (!*args[*cur_arg + 1]) {
5650 memprintf(err, "'%s' : missing cipher suite", args[*cur_arg]);
5651 return ERR_ALERT | ERR_FATAL;
5652 }
5653
5654 free(newsrv->ssl_ctx.ciphers);
5655 newsrv->ssl_ctx.ciphers = strdup(args[*cur_arg + 1]);
5656 return 0;
5657}
5658
Emeric Brunef42d922012-10-11 16:11:36 +02005659/* parse the "crl-file" server keyword */
5660static int srv_parse_crl_file(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5661{
5662#ifndef X509_V_FLAG_CRL_CHECK
5663 if (err)
5664 memprintf(err, "'%s' : library does not support CRL verify", args[*cur_arg]);
5665 return ERR_ALERT | ERR_FATAL;
5666#else
5667 if (!*args[*cur_arg + 1]) {
5668 if (err)
5669 memprintf(err, "'%s' : missing CRLfile path", args[*cur_arg]);
5670 return ERR_ALERT | ERR_FATAL;
5671 }
5672
5673 if ((*args[*cur_arg + 1] != '/') && global.ca_base)
5674 memprintf(&newsrv->ssl_ctx.crl_file, "%s/%s", global.ca_base, args[*cur_arg + 1]);
5675 else
5676 memprintf(&newsrv->ssl_ctx.crl_file, "%s", args[*cur_arg + 1]);
5677
5678 return 0;
5679#endif
5680}
5681
Emeric Bruna7aa3092012-10-26 12:58:00 +02005682/* parse the "crt" server keyword */
5683static int srv_parse_crt(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5684{
5685 if (!*args[*cur_arg + 1]) {
5686 if (err)
5687 memprintf(err, "'%s' : missing certificate file path", args[*cur_arg]);
5688 return ERR_ALERT | ERR_FATAL;
5689 }
5690
5691 if ((*args[*cur_arg + 1] != '/') && global.crt_base)
5692 memprintf(&newsrv->ssl_ctx.client_crt, "%s/%s", global.ca_base, args[*cur_arg + 1]);
5693 else
5694 memprintf(&newsrv->ssl_ctx.client_crt, "%s", args[*cur_arg + 1]);
5695
5696 return 0;
5697}
Emeric Brunef42d922012-10-11 16:11:36 +02005698
Willy Tarreau92faadf2012-10-10 23:04:25 +02005699/* parse the "force-sslv3" server keyword */
5700static int srv_parse_force_sslv3(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5701{
5702 newsrv->ssl_ctx.options |= SRV_SSL_O_USE_SSLV3;
5703 return 0;
5704}
5705
5706/* parse the "force-tlsv10" server keyword */
5707static int srv_parse_force_tlsv10(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5708{
5709 newsrv->ssl_ctx.options |= SRV_SSL_O_USE_TLSV10;
5710 return 0;
5711}
5712
5713/* parse the "force-tlsv11" server keyword */
5714static int srv_parse_force_tlsv11(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5715{
5716#if SSL_OP_NO_TLSv1_1
5717 newsrv->ssl_ctx.options |= SRV_SSL_O_USE_TLSV11;
5718 return 0;
5719#else
5720 if (err)
5721 memprintf(err, "'%s' : library does not support protocol TLSv1.1", args[*cur_arg]);
5722 return ERR_ALERT | ERR_FATAL;
5723#endif
5724}
5725
5726/* parse the "force-tlsv12" server keyword */
5727static int srv_parse_force_tlsv12(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5728{
5729#if SSL_OP_NO_TLSv1_2
5730 newsrv->ssl_ctx.options |= SRV_SSL_O_USE_TLSV12;
5731 return 0;
5732#else
5733 if (err)
5734 memprintf(err, "'%s' : library does not support protocol TLSv1.2", args[*cur_arg]);
5735 return ERR_ALERT | ERR_FATAL;
5736#endif
5737}
5738
Willy Tarreau2a3fb1c2015-02-05 16:47:07 +01005739/* parse the "no-ssl-reuse" server keyword */
5740static int srv_parse_no_ssl_reuse(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5741{
5742 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_REUSE;
5743 return 0;
5744}
5745
Willy Tarreau92faadf2012-10-10 23:04:25 +02005746/* parse the "no-sslv3" server keyword */
5747static int srv_parse_no_sslv3(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5748{
5749 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_SSLV3;
5750 return 0;
5751}
5752
5753/* parse the "no-tlsv10" server keyword */
5754static int srv_parse_no_tlsv10(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5755{
5756 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_TLSV10;
5757 return 0;
5758}
5759
5760/* parse the "no-tlsv11" server keyword */
5761static int srv_parse_no_tlsv11(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5762{
5763 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_TLSV11;
5764 return 0;
5765}
5766
5767/* parse the "no-tlsv12" server keyword */
5768static int srv_parse_no_tlsv12(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5769{
5770 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_TLSV12;
5771 return 0;
5772}
5773
Emeric Brunf9c5c472012-10-11 15:28:34 +02005774/* parse the "no-tls-tickets" server keyword */
5775static int srv_parse_no_tls_tickets(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5776{
5777 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_TLS_TICKETS;
5778 return 0;
5779}
David Safb76832014-05-08 23:42:08 -04005780/* parse the "send-proxy-v2-ssl" server keyword */
5781static int srv_parse_send_proxy_ssl(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5782{
5783 newsrv->pp_opts |= SRV_PP_V2;
5784 newsrv->pp_opts |= SRV_PP_V2_SSL;
5785 return 0;
5786}
5787
5788/* parse the "send-proxy-v2-ssl-cn" server keyword */
5789static int srv_parse_send_proxy_cn(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5790{
5791 newsrv->pp_opts |= SRV_PP_V2;
5792 newsrv->pp_opts |= SRV_PP_V2_SSL;
5793 newsrv->pp_opts |= SRV_PP_V2_SSL_CN;
5794 return 0;
5795}
Emeric Brunf9c5c472012-10-11 15:28:34 +02005796
Willy Tarreau732eac42015-07-09 11:40:25 +02005797/* parse the "sni" server keyword */
5798static int srv_parse_sni(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5799{
5800#ifndef SSL_CTRL_SET_TLSEXT_HOSTNAME
5801 memprintf(err, "'%s' : the current SSL library doesn't support the SNI TLS extension", args[*cur_arg]);
5802 return ERR_ALERT | ERR_FATAL;
5803#else
Cyril Bonté23d19d62016-03-07 22:13:22 +01005804 int idx;
Willy Tarreau732eac42015-07-09 11:40:25 +02005805 struct sample_expr *expr;
5806
5807 if (!*args[*cur_arg + 1]) {
5808 memprintf(err, "'%s' : missing sni expression", args[*cur_arg]);
5809 return ERR_ALERT | ERR_FATAL;
5810 }
5811
Cyril Bonté23d19d62016-03-07 22:13:22 +01005812 idx = (*cur_arg) + 1;
Willy Tarreau732eac42015-07-09 11:40:25 +02005813 proxy->conf.args.ctx = ARGC_SRV;
5814
Cyril Bonté23d19d62016-03-07 22:13:22 +01005815 expr = sample_parse_expr((char **)args, &idx, px->conf.file, px->conf.line, err, &proxy->conf.args);
Willy Tarreau732eac42015-07-09 11:40:25 +02005816 if (!expr) {
5817 memprintf(err, "error detected while parsing sni expression : %s", *err);
5818 return ERR_ALERT | ERR_FATAL;
5819 }
5820
5821 if (!(expr->fetch->val & SMP_VAL_BE_SRV_CON)) {
5822 memprintf(err, "error detected while parsing sni expression : "
5823 " fetch method '%s' extracts information from '%s', none of which is available here.\n",
Cyril Bonté23d19d62016-03-07 22:13:22 +01005824 args[idx-1], sample_src_names(expr->fetch->use));
Willy Tarreau732eac42015-07-09 11:40:25 +02005825 return ERR_ALERT | ERR_FATAL;
5826 }
5827
5828 px->http_needed |= !!(expr->fetch->use & SMP_USE_HTTP_ANY);
5829 newsrv->ssl_ctx.sni = expr;
5830 return 0;
5831#endif
5832}
5833
Willy Tarreau92faadf2012-10-10 23:04:25 +02005834/* parse the "ssl" server keyword */
5835static int srv_parse_ssl(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5836{
5837 newsrv->use_ssl = 1;
5838 if (global.connect_default_ciphers && !newsrv->ssl_ctx.ciphers)
5839 newsrv->ssl_ctx.ciphers = strdup(global.connect_default_ciphers);
5840 return 0;
5841}
5842
Emeric Brunef42d922012-10-11 16:11:36 +02005843/* parse the "verify" server keyword */
5844static int srv_parse_verify(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5845{
5846 if (!*args[*cur_arg + 1]) {
5847 if (err)
5848 memprintf(err, "'%s' : missing verify method", args[*cur_arg]);
5849 return ERR_ALERT | ERR_FATAL;
5850 }
5851
5852 if (strcmp(args[*cur_arg + 1], "none") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01005853 newsrv->ssl_ctx.verify = SSL_SOCK_VERIFY_NONE;
Emeric Brunef42d922012-10-11 16:11:36 +02005854 else if (strcmp(args[*cur_arg + 1], "required") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01005855 newsrv->ssl_ctx.verify = SSL_SOCK_VERIFY_REQUIRED;
Emeric Brunef42d922012-10-11 16:11:36 +02005856 else {
5857 if (err)
5858 memprintf(err, "'%s' : unknown verify method '%s', only 'none' and 'required' are supported\n",
5859 args[*cur_arg], args[*cur_arg + 1]);
5860 return ERR_ALERT | ERR_FATAL;
5861 }
5862
Evan Broderbe554312013-06-27 00:05:25 -07005863 return 0;
5864}
5865
5866/* parse the "verifyhost" server keyword */
5867static int srv_parse_verifyhost(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5868{
5869 if (!*args[*cur_arg + 1]) {
5870 if (err)
5871 memprintf(err, "'%s' : missing hostname to verify against", args[*cur_arg]);
5872 return ERR_ALERT | ERR_FATAL;
5873 }
5874
5875 newsrv->ssl_ctx.verify_host = strdup(args[*cur_arg + 1]);
5876
Emeric Brunef42d922012-10-11 16:11:36 +02005877 return 0;
5878}
5879
Emeric Brun2c86cbf2014-10-30 15:56:50 +01005880/* parse the "ssl-default-bind-options" keyword in global section */
5881static int ssl_parse_default_bind_options(char **args, int section_type, struct proxy *curpx,
5882 struct proxy *defpx, const char *file, int line,
5883 char **err) {
5884 int i = 1;
5885
5886 if (*(args[i]) == 0) {
5887 memprintf(err, "global statement '%s' expects an option as an argument.", args[0]);
5888 return -1;
5889 }
5890 while (*(args[i])) {
5891 if (!strcmp(args[i], "no-sslv3"))
5892 global.listen_default_ssloptions |= BC_SSL_O_NO_SSLV3;
5893 else if (!strcmp(args[i], "no-tlsv10"))
5894 global.listen_default_ssloptions |= BC_SSL_O_NO_TLSV10;
5895 else if (!strcmp(args[i], "no-tlsv11"))
5896 global.listen_default_ssloptions |= BC_SSL_O_NO_TLSV11;
5897 else if (!strcmp(args[i], "no-tlsv12"))
5898 global.listen_default_ssloptions |= BC_SSL_O_NO_TLSV12;
5899 else if (!strcmp(args[i], "force-sslv3"))
5900 global.listen_default_ssloptions |= BC_SSL_O_USE_SSLV3;
5901 else if (!strcmp(args[i], "force-tlsv10"))
5902 global.listen_default_ssloptions |= BC_SSL_O_USE_TLSV10;
5903 else if (!strcmp(args[i], "force-tlsv11")) {
5904#if SSL_OP_NO_TLSv1_1
5905 global.listen_default_ssloptions |= BC_SSL_O_USE_TLSV11;
5906#else
5907 memprintf(err, "'%s' '%s': library does not support protocol TLSv1.1", args[0], args[i]);
5908 return -1;
5909#endif
5910 }
5911 else if (!strcmp(args[i], "force-tlsv12")) {
5912#if SSL_OP_NO_TLSv1_2
5913 global.listen_default_ssloptions |= BC_SSL_O_USE_TLSV12;
5914#else
5915 memprintf(err, "'%s' '%s': library does not support protocol TLSv1.2", args[0], args[i]);
5916 return -1;
5917#endif
5918 }
5919 else if (!strcmp(args[i], "no-tls-tickets"))
5920 global.listen_default_ssloptions |= BC_SSL_O_NO_TLS_TICKETS;
5921 else {
5922 memprintf(err, "unknown option '%s' on global statement '%s'.", args[i], args[0]);
5923 return -1;
5924 }
5925 i++;
5926 }
5927 return 0;
5928}
5929
5930/* parse the "ssl-default-server-options" keyword in global section */
5931static int ssl_parse_default_server_options(char **args, int section_type, struct proxy *curpx,
5932 struct proxy *defpx, const char *file, int line,
5933 char **err) {
5934 int i = 1;
5935
5936 if (*(args[i]) == 0) {
5937 memprintf(err, "global statement '%s' expects an option as an argument.", args[0]);
5938 return -1;
5939 }
5940 while (*(args[i])) {
5941 if (!strcmp(args[i], "no-sslv3"))
5942 global.connect_default_ssloptions |= SRV_SSL_O_NO_SSLV3;
5943 else if (!strcmp(args[i], "no-tlsv10"))
5944 global.connect_default_ssloptions |= SRV_SSL_O_NO_TLSV10;
5945 else if (!strcmp(args[i], "no-tlsv11"))
5946 global.connect_default_ssloptions |= SRV_SSL_O_NO_TLSV11;
5947 else if (!strcmp(args[i], "no-tlsv12"))
5948 global.connect_default_ssloptions |= SRV_SSL_O_NO_TLSV12;
5949 else if (!strcmp(args[i], "force-sslv3"))
5950 global.connect_default_ssloptions |= SRV_SSL_O_USE_SSLV3;
5951 else if (!strcmp(args[i], "force-tlsv10"))
5952 global.connect_default_ssloptions |= SRV_SSL_O_USE_TLSV10;
5953 else if (!strcmp(args[i], "force-tlsv11")) {
5954#if SSL_OP_NO_TLSv1_1
5955 global.connect_default_ssloptions |= SRV_SSL_O_USE_TLSV11;
5956#else
5957 memprintf(err, "'%s' '%s': library does not support protocol TLSv1.1", args[0], args[i]);
5958 return -1;
5959#endif
5960 }
5961 else if (!strcmp(args[i], "force-tlsv12")) {
5962#if SSL_OP_NO_TLSv1_2
5963 global.connect_default_ssloptions |= SRV_SSL_O_USE_TLSV12;
5964#else
5965 memprintf(err, "'%s' '%s': library does not support protocol TLSv1.2", args[0], args[i]);
5966 return -1;
5967#endif
5968 }
5969 else if (!strcmp(args[i], "no-tls-tickets"))
5970 global.connect_default_ssloptions |= SRV_SSL_O_NO_TLS_TICKETS;
5971 else {
5972 memprintf(err, "unknown option '%s' on global statement '%s'.", args[i], args[0]);
5973 return -1;
5974 }
5975 i++;
5976 }
5977 return 0;
5978}
5979
Willy Tarreau7875d092012-09-10 08:20:03 +02005980/* Note: must not be declared <const> as its list will be overwritten.
5981 * Please take care of keeping this list alphabetically sorted.
5982 */
Willy Tarreaudc13c112013-06-21 23:16:39 +02005983static struct sample_fetch_kw_list sample_fetch_keywords = {ILH, {
Emeric Brun645ae792014-04-30 14:21:06 +02005984 { "ssl_bc", smp_fetch_ssl_fc, 0, NULL, SMP_T_BOOL, SMP_USE_L5SRV },
Thierry FOURNIER07ee64e2015-07-06 23:43:03 +02005985 { "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 +02005986 { "ssl_bc_cipher", smp_fetch_ssl_fc_cipher, 0, NULL, SMP_T_STR, SMP_USE_L5SRV },
5987 { "ssl_bc_protocol", smp_fetch_ssl_fc_protocol, 0, NULL, SMP_T_STR, SMP_USE_L5SRV },
Emeric Brunb73a9b02014-04-30 18:49:19 +02005988 { "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 +02005989 { "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 +02005990 { "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 +02005991 { "ssl_c_ca_err", smp_fetch_ssl_c_ca_err, 0, NULL, SMP_T_SINT, SMP_USE_L5CLI },
5992 { "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 +01005993 { "ssl_c_der", smp_fetch_ssl_x_der, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Thierry FOURNIER07ee64e2015-07-06 23:43:03 +02005994 { "ssl_c_err", smp_fetch_ssl_c_err, 0, NULL, SMP_T_SINT, SMP_USE_L5CLI },
Emeric Brunba841a12014-04-30 17:05:08 +02005995 { "ssl_c_i_dn", smp_fetch_ssl_x_i_dn, ARG2(0,STR,SINT), NULL, SMP_T_STR, SMP_USE_L5CLI },
5996 { "ssl_c_key_alg", smp_fetch_ssl_x_key_alg, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
5997 { "ssl_c_notafter", smp_fetch_ssl_x_notafter, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
5998 { "ssl_c_notbefore", smp_fetch_ssl_x_notbefore, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
5999 { "ssl_c_sig_alg", smp_fetch_ssl_x_sig_alg, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
6000 { "ssl_c_s_dn", smp_fetch_ssl_x_s_dn, ARG2(0,STR,SINT), NULL, SMP_T_STR, SMP_USE_L5CLI },
6001 { "ssl_c_serial", smp_fetch_ssl_x_serial, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
6002 { "ssl_c_sha1", smp_fetch_ssl_x_sha1, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Willy Tarreau80aca902013-01-07 15:42:20 +01006003 { "ssl_c_used", smp_fetch_ssl_c_used, 0, NULL, SMP_T_BOOL, SMP_USE_L5CLI },
Thierry FOURNIER07ee64e2015-07-06 23:43:03 +02006004 { "ssl_c_verify", smp_fetch_ssl_c_verify, 0, NULL, SMP_T_SINT, SMP_USE_L5CLI },
6005 { "ssl_c_version", smp_fetch_ssl_x_version, 0, NULL, SMP_T_SINT, SMP_USE_L5CLI },
Emeric Brun43e79582014-10-29 19:03:26 +01006006 { "ssl_f_der", smp_fetch_ssl_x_der, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Emeric Brunba841a12014-04-30 17:05:08 +02006007 { "ssl_f_i_dn", smp_fetch_ssl_x_i_dn, ARG2(0,STR,SINT), NULL, SMP_T_STR, SMP_USE_L5CLI },
6008 { "ssl_f_key_alg", smp_fetch_ssl_x_key_alg, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
6009 { "ssl_f_notafter", smp_fetch_ssl_x_notafter, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
6010 { "ssl_f_notbefore", smp_fetch_ssl_x_notbefore, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
6011 { "ssl_f_sig_alg", smp_fetch_ssl_x_sig_alg, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
6012 { "ssl_f_s_dn", smp_fetch_ssl_x_s_dn, ARG2(0,STR,SINT), NULL, SMP_T_STR, SMP_USE_L5CLI },
6013 { "ssl_f_serial", smp_fetch_ssl_x_serial, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Emeric Brun55f4fa82014-04-30 17:11:25 +02006014 { "ssl_f_sha1", smp_fetch_ssl_x_sha1, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Thierry FOURNIER07ee64e2015-07-06 23:43:03 +02006015 { "ssl_f_version", smp_fetch_ssl_x_version, 0, NULL, SMP_T_SINT, SMP_USE_L5CLI },
Willy Tarreau80aca902013-01-07 15:42:20 +01006016 { "ssl_fc", smp_fetch_ssl_fc, 0, NULL, SMP_T_BOOL, SMP_USE_L5CLI },
Thierry FOURNIER07ee64e2015-07-06 23:43:03 +02006017 { "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 +01006018 { "ssl_fc_cipher", smp_fetch_ssl_fc_cipher, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Willy Tarreau80aca902013-01-07 15:42:20 +01006019 { "ssl_fc_has_crt", smp_fetch_ssl_fc_has_crt, 0, NULL, SMP_T_BOOL, SMP_USE_L5CLI },
6020 { "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 +02006021 { "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 +02006022#ifdef OPENSSL_NPN_NEGOTIATED
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01006023 { "ssl_fc_npn", smp_fetch_ssl_fc_npn, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Willy Tarreaua33c6542012-10-15 13:19:06 +02006024#endif
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01006025#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01006026 { "ssl_fc_alpn", smp_fetch_ssl_fc_alpn, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Willy Tarreauab861d32013-04-02 02:30:41 +02006027#endif
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01006028 { "ssl_fc_protocol", smp_fetch_ssl_fc_protocol, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Emeric Brunb73a9b02014-04-30 18:49:19 +02006029 { "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 +02006030 { "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 +01006031 { "ssl_fc_session_id", smp_fetch_ssl_fc_session_id, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
6032 { "ssl_fc_sni", smp_fetch_ssl_fc_sni, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Willy Tarreau7875d092012-09-10 08:20:03 +02006033 { NULL, NULL, 0, 0, 0 },
6034}};
6035
6036/* Note: must not be declared <const> as its list will be overwritten.
6037 * Please take care of keeping this list alphabetically sorted.
6038 */
Willy Tarreaudc13c112013-06-21 23:16:39 +02006039static struct acl_kw_list acl_kws = {ILH, {
Thierry FOURNIERc5a4e982014-03-05 16:07:08 +01006040 { "ssl_fc_sni_end", "ssl_fc_sni", PAT_MATCH_END },
6041 { "ssl_fc_sni_reg", "ssl_fc_sni", PAT_MATCH_REG },
Willy Tarreau8ed669b2013-01-11 15:49:37 +01006042 { /* END */ },
Willy Tarreau7875d092012-09-10 08:20:03 +02006043}};
6044
Willy Tarreau79eeafa2012-09-14 07:53:05 +02006045/* Note: must not be declared <const> as its list will be overwritten.
6046 * Please take care of keeping this list alphabetically sorted, doing so helps
6047 * all code contributors.
6048 * Optional keywords are also declared with a NULL ->parse() function so that
6049 * the config parser can report an appropriate error when a known keyword was
6050 * not enabled.
6051 */
Willy Tarreau51fb7652012-09-18 18:24:39 +02006052static struct bind_kw_list bind_kws = { "SSL", { }, {
Nenad Merdanovic05552d42015-02-27 19:56:49 +01006053 { "alpn", bind_parse_alpn, 1 }, /* set ALPN supported protocols */
6054 { "ca-file", bind_parse_ca_file, 1 }, /* set CAfile to process verify on client cert */
6055 { "ca-ignore-err", bind_parse_ignore_err, 1 }, /* set error IDs to ignore on verify depth > 0 */
Christopher Faulet31af49d2015-06-09 17:29:50 +02006056 { "ca-sign-file", bind_parse_ca_sign_file, 1 }, /* set CAFile used to generate and sign server certs */
6057 { "ca-sign-pass", bind_parse_ca_sign_pass, 1 }, /* set CAKey passphrase */
Nenad Merdanovic05552d42015-02-27 19:56:49 +01006058 { "ciphers", bind_parse_ciphers, 1 }, /* set SSL cipher suite */
6059 { "crl-file", bind_parse_crl_file, 1 }, /* set certificat revocation list file use on client cert verify */
6060 { "crt", bind_parse_crt, 1 }, /* load SSL certificates from this location */
6061 { "crt-ignore-err", bind_parse_ignore_err, 1 }, /* set error IDs to ingore on verify depth == 0 */
6062 { "crt-list", bind_parse_crt_list, 1 }, /* load a list of crt from this location */
6063 { "ecdhe", bind_parse_ecdhe, 1 }, /* defines named curve for elliptic curve Diffie-Hellman */
6064 { "force-sslv3", bind_parse_force_sslv3, 0 }, /* force SSLv3 */
6065 { "force-tlsv10", bind_parse_force_tlsv10, 0 }, /* force TLSv10 */
6066 { "force-tlsv11", bind_parse_force_tlsv11, 0 }, /* force TLSv11 */
6067 { "force-tlsv12", bind_parse_force_tlsv12, 0 }, /* force TLSv12 */
Christopher Faulet31af49d2015-06-09 17:29:50 +02006068 { "generate-certificates", bind_parse_generate_certs, 0 }, /* enable the server certificates generation */
Nenad Merdanovic05552d42015-02-27 19:56:49 +01006069 { "no-sslv3", bind_parse_no_sslv3, 0 }, /* disable SSLv3 */
6070 { "no-tlsv10", bind_parse_no_tlsv10, 0 }, /* disable TLSv10 */
6071 { "no-tlsv11", bind_parse_no_tlsv11, 0 }, /* disable TLSv11 */
6072 { "no-tlsv12", bind_parse_no_tlsv12, 0 }, /* disable TLSv12 */
6073 { "no-tls-tickets", bind_parse_no_tls_tickets, 0 }, /* disable session resumption tickets */
6074 { "ssl", bind_parse_ssl, 0 }, /* enable SSL processing */
6075 { "strict-sni", bind_parse_strict_sni, 0 }, /* refuse negotiation if sni doesn't match a certificate */
6076 { "tls-ticket-keys", bind_parse_tls_ticket_keys, 1 }, /* set file to load TLS ticket keys from */
6077 { "verify", bind_parse_verify, 1 }, /* set SSL verify method */
6078 { "npn", bind_parse_npn, 1 }, /* set NPN supported protocols */
Willy Tarreau79eeafa2012-09-14 07:53:05 +02006079 { NULL, NULL, 0 },
6080}};
Emeric Brun46591952012-05-18 15:47:34 +02006081
Willy Tarreau92faadf2012-10-10 23:04:25 +02006082/* Note: must not be declared <const> as its list will be overwritten.
6083 * Please take care of keeping this list alphabetically sorted, doing so helps
6084 * all code contributors.
6085 * Optional keywords are also declared with a NULL ->parse() function so that
6086 * the config parser can report an appropriate error when a known keyword was
6087 * not enabled.
6088 */
6089static struct srv_kw_list srv_kws = { "SSL", { }, {
Emeric Brunef42d922012-10-11 16:11:36 +02006090 { "ca-file", srv_parse_ca_file, 1, 0 }, /* set CAfile to process verify server cert */
Emeric Brunecc91fe2012-10-11 15:05:10 +02006091 { "check-ssl", srv_parse_check_ssl, 0, 0 }, /* enable SSL for health checks */
6092 { "ciphers", srv_parse_ciphers, 1, 0 }, /* select the cipher suite */
Emeric Brunef42d922012-10-11 16:11:36 +02006093 { "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 +02006094 { "crt", srv_parse_crt, 1, 0 }, /* set client certificate */
Emeric Brunecc91fe2012-10-11 15:05:10 +02006095 { "force-sslv3", srv_parse_force_sslv3, 0, 0 }, /* force SSLv3 */
6096 { "force-tlsv10", srv_parse_force_tlsv10, 0, 0 }, /* force TLSv10 */
6097 { "force-tlsv11", srv_parse_force_tlsv11, 0, 0 }, /* force TLSv11 */
6098 { "force-tlsv12", srv_parse_force_tlsv12, 0, 0 }, /* force TLSv12 */
Willy Tarreau2a3fb1c2015-02-05 16:47:07 +01006099 { "no-ssl-reuse", srv_parse_no_ssl_reuse, 0, 0 }, /* disable session reuse */
Emeric Brunecc91fe2012-10-11 15:05:10 +02006100 { "no-sslv3", srv_parse_no_sslv3, 0, 0 }, /* disable SSLv3 */
6101 { "no-tlsv10", srv_parse_no_tlsv10, 0, 0 }, /* disable TLSv10 */
6102 { "no-tlsv11", srv_parse_no_tlsv11, 0, 0 }, /* disable TLSv11 */
6103 { "no-tlsv12", srv_parse_no_tlsv12, 0, 0 }, /* disable TLSv12 */
Emeric Brunf9c5c472012-10-11 15:28:34 +02006104 { "no-tls-tickets", srv_parse_no_tls_tickets, 0, 0 }, /* disable session resumption tickets */
David Safb76832014-05-08 23:42:08 -04006105 { "send-proxy-v2-ssl", srv_parse_send_proxy_ssl, 0, 0 }, /* send PROXY protocol header v2 with SSL info */
6106 { "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 +02006107 { "sni", srv_parse_sni, 1, 0 }, /* send SNI extension */
Emeric Brunecc91fe2012-10-11 15:05:10 +02006108 { "ssl", srv_parse_ssl, 0, 0 }, /* enable SSL processing */
Emeric Brunef42d922012-10-11 16:11:36 +02006109 { "verify", srv_parse_verify, 1, 0 }, /* set SSL verify method */
Evan Broderbe554312013-06-27 00:05:25 -07006110 { "verifyhost", srv_parse_verifyhost, 1, 0 }, /* require that SSL cert verifies for hostname */
Willy Tarreau92faadf2012-10-10 23:04:25 +02006111 { NULL, NULL, 0, 0 },
6112}};
6113
Emeric Brun2c86cbf2014-10-30 15:56:50 +01006114static struct cfg_kw_list cfg_kws = {ILH, {
6115 { CFG_GLOBAL, "ssl-default-bind-options", ssl_parse_default_bind_options },
6116 { CFG_GLOBAL, "ssl-default-server-options", ssl_parse_default_server_options },
6117 { 0, NULL, NULL },
6118}};
6119
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02006120/* transport-layer operations for SSL sockets */
6121struct xprt_ops ssl_sock = {
Emeric Brun46591952012-05-18 15:47:34 +02006122 .snd_buf = ssl_sock_from_buf,
6123 .rcv_buf = ssl_sock_to_buf,
6124 .rcv_pipe = NULL,
6125 .snd_pipe = NULL,
6126 .shutr = NULL,
6127 .shutw = ssl_sock_shutw,
6128 .close = ssl_sock_close,
6129 .init = ssl_sock_init,
6130};
6131
Daniel Jakots54ffb912015-11-06 20:02:41 +01006132#if (OPENSSL_VERSION_NUMBER >= 0x1000200fL && !defined OPENSSL_NO_TLSEXT && !defined OPENSSL_IS_BORINGSSL && !defined LIBRESSL_VERSION_NUMBER)
Janusz Dziemidowicz2c701b52015-03-07 23:03:59 +01006133
6134static void ssl_sock_sctl_free_func(void *parent, void *ptr, CRYPTO_EX_DATA *ad, int idx, long argl, void *argp)
6135{
6136 if (ptr) {
6137 chunk_destroy(ptr);
6138 free(ptr);
6139 }
6140}
6141
6142#endif
6143
Emeric Brun46591952012-05-18 15:47:34 +02006144__attribute__((constructor))
Willy Tarreau92faadf2012-10-10 23:04:25 +02006145static void __ssl_sock_init(void)
6146{
Emeric Brun46591952012-05-18 15:47:34 +02006147 STACK_OF(SSL_COMP)* cm;
6148
Willy Tarreau610f04b2014-02-13 11:36:41 +01006149#ifdef LISTEN_DEFAULT_CIPHERS
6150 global.listen_default_ciphers = LISTEN_DEFAULT_CIPHERS;
6151#endif
6152#ifdef CONNECT_DEFAULT_CIPHERS
6153 global.connect_default_ciphers = CONNECT_DEFAULT_CIPHERS;
6154#endif
6155 if (global.listen_default_ciphers)
6156 global.listen_default_ciphers = strdup(global.listen_default_ciphers);
6157 if (global.connect_default_ciphers)
6158 global.connect_default_ciphers = strdup(global.connect_default_ciphers);
Emeric Brun2c86cbf2014-10-30 15:56:50 +01006159 global.listen_default_ssloptions = BC_SSL_O_NONE;
6160 global.connect_default_ssloptions = SRV_SSL_O_NONE;
Willy Tarreau610f04b2014-02-13 11:36:41 +01006161
Emeric Brun46591952012-05-18 15:47:34 +02006162 SSL_library_init();
6163 cm = SSL_COMP_get_compression_methods();
6164 sk_SSL_COMP_zero(cm);
Daniel Jakots54ffb912015-11-06 20:02:41 +01006165#if (OPENSSL_VERSION_NUMBER >= 0x1000200fL && !defined OPENSSL_NO_TLSEXT && !defined OPENSSL_IS_BORINGSSL && !defined LIBRESSL_VERSION_NUMBER)
Janusz Dziemidowicz2c701b52015-03-07 23:03:59 +01006166 sctl_ex_index = SSL_CTX_get_ex_new_index(0, NULL, NULL, NULL, ssl_sock_sctl_free_func);
6167#endif
Willy Tarreau7875d092012-09-10 08:20:03 +02006168 sample_register_fetches(&sample_fetch_keywords);
6169 acl_register_keywords(&acl_kws);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02006170 bind_register_keywords(&bind_kws);
Willy Tarreau92faadf2012-10-10 23:04:25 +02006171 srv_register_keywords(&srv_kws);
Emeric Brun2c86cbf2014-10-30 15:56:50 +01006172 cfg_register_keywords(&cfg_kws);
Willy Tarreaud92aa5c2015-01-15 21:34:39 +01006173
6174 global.ssl_session_max_cost = SSL_SESSION_MAX_COST;
6175 global.ssl_handshake_max_cost = SSL_HANDSHAKE_MAX_COST;
Remi Gacogne4f902b82015-05-28 16:23:00 +02006176
6177#ifndef OPENSSL_NO_DH
6178 ssl_dh_ptr_index = SSL_CTX_get_ex_new_index(0, NULL, NULL, NULL, NULL);
6179#endif
Thierry FOURNIER / OZON.IO8b068c22016-10-10 11:59:50 +02006180
6181 /* Load SSL string for the verbose & debug mode. */
6182 ERR_load_SSL_strings();
Emeric Brun46591952012-05-18 15:47:34 +02006183}
6184
Remi Gacogned3a23c32015-05-28 16:39:47 +02006185__attribute__((destructor))
6186static void __ssl_sock_deinit(void)
6187{
Willy Tarreaua84c2672015-10-09 12:10:13 +02006188#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Christopher Faulet31af49d2015-06-09 17:29:50 +02006189 lru64_destroy(ssl_ctx_lru_tree);
Willy Tarreaua84c2672015-10-09 12:10:13 +02006190#endif
Christopher Faulet31af49d2015-06-09 17:29:50 +02006191
Remi Gacogned3a23c32015-05-28 16:39:47 +02006192#ifndef OPENSSL_NO_DH
6193 if (local_dh_1024) {
6194 DH_free(local_dh_1024);
6195 local_dh_1024 = NULL;
6196 }
6197
6198 if (local_dh_2048) {
6199 DH_free(local_dh_2048);
6200 local_dh_2048 = NULL;
6201 }
6202
6203 if (local_dh_4096) {
6204 DH_free(local_dh_4096);
6205 local_dh_4096 = NULL;
6206 }
6207
Remi Gacogne47783ef2015-05-29 15:53:22 +02006208 if (global_dh) {
6209 DH_free(global_dh);
6210 global_dh = NULL;
6211 }
Remi Gacogned3a23c32015-05-28 16:39:47 +02006212#endif
6213
6214 ERR_remove_state(0);
6215 ERR_free_strings();
6216
6217 EVP_cleanup();
6218
6219#if OPENSSL_VERSION_NUMBER >= 0x00907000L
6220 CRYPTO_cleanup_all_ex_data();
6221#endif
6222}
6223
6224
Emeric Brun46591952012-05-18 15:47:34 +02006225/*
6226 * Local variables:
6227 * c-indent-level: 8
6228 * c-basic-offset: 8
6229 * End:
6230 */