blob: 3eee173ae2fc3474347f1aeaa744189ff42711f7 [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
42#include <openssl/ssl.h>
Emeric Brunfc0421f2012-09-07 17:30:07 +020043#include <openssl/x509.h>
44#include <openssl/x509v3.h>
45#include <openssl/x509.h>
46#include <openssl/err.h>
Thierry Fournier383085f2013-01-24 14:15:43 +010047#include <openssl/rand.h>
Lukas Tribuse4e30f72014-12-09 16:32:51 +010048#if (defined SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB && !defined OPENSSL_NO_OCSP)
Emeric Brun4147b2e2014-06-16 18:36:30 +020049#include <openssl/ocsp.h>
50#endif
Remi Gacogne4f902b82015-05-28 16:23:00 +020051#ifndef OPENSSL_NO_DH
52#include <openssl/dh.h>
53#endif
Emeric Brun46591952012-05-18 15:47:34 +020054
Christopher Faulet31af49d2015-06-09 17:29:50 +020055#include <import/lru.h>
56#include <import/xxhash.h>
57
Emeric Brun46591952012-05-18 15:47:34 +020058#include <common/buffer.h>
59#include <common/compat.h>
60#include <common/config.h>
61#include <common/debug.h>
Willy Tarreau79eeafa2012-09-14 07:53:05 +020062#include <common/errors.h>
Emeric Brun46591952012-05-18 15:47:34 +020063#include <common/standard.h>
64#include <common/ticks.h>
65#include <common/time.h>
Emeric Brun2c86cbf2014-10-30 15:56:50 +010066#include <common/cfgparse.h>
Nenad Merdanovic05552d42015-02-27 19:56:49 +010067#include <common/base64.h>
Emeric Brun46591952012-05-18 15:47:34 +020068
Emeric Brunfc0421f2012-09-07 17:30:07 +020069#include <ebsttree.h>
70
71#include <types/global.h>
72#include <types/ssl_sock.h>
73
Willy Tarreau7875d092012-09-10 08:20:03 +020074#include <proto/acl.h>
75#include <proto/arg.h>
Emeric Brun46591952012-05-18 15:47:34 +020076#include <proto/connection.h>
77#include <proto/fd.h>
78#include <proto/freq_ctr.h>
79#include <proto/frontend.h>
Willy Tarreau79eeafa2012-09-14 07:53:05 +020080#include <proto/listener.h>
Thierry FOURNIERed66c292013-11-28 11:05:19 +010081#include <proto/pattern.h>
Christopher Faulet31af49d2015-06-09 17:29:50 +020082#include <proto/proto_tcp.h>
Willy Tarreau92faadf2012-10-10 23:04:25 +020083#include <proto/server.h>
Emeric Brun46591952012-05-18 15:47:34 +020084#include <proto/log.h>
Emeric Brun94324a42012-10-11 14:00:19 +020085#include <proto/proxy.h>
Emeric Brunfc0421f2012-09-07 17:30:07 +020086#include <proto/shctx.h>
Emeric Brun46591952012-05-18 15:47:34 +020087#include <proto/ssl_sock.h>
Willy Tarreau9ad7bd42015-04-03 19:19:59 +020088#include <proto/stream.h>
Emeric Brun46591952012-05-18 15:47:34 +020089#include <proto/task.h>
90
Willy Tarreau518cedd2014-02-17 15:43:01 +010091/* Warning, these are bits, not integers! */
Emeric Brune64aef12012-09-21 13:15:06 +020092#define SSL_SOCK_ST_FL_VERIFY_DONE 0x00000001
Emeric Brund8b2bb52014-01-28 15:43:53 +010093#define SSL_SOCK_ST_FL_16K_WBFSIZE 0x00000002
Willy Tarreau518cedd2014-02-17 15:43:01 +010094#define SSL_SOCK_SEND_UNLIMITED 0x00000004
Emeric Brun29f037d2014-04-25 19:05:36 +020095#define SSL_SOCK_RECV_HEARTBEAT 0x00000008
96
Emeric Brunf282a812012-09-21 15:27:54 +020097/* bits 0xFFFF0000 are reserved to store verify errors */
98
99/* Verify errors macros */
100#define SSL_SOCK_CA_ERROR_TO_ST(e) (((e > 63) ? 63 : e) << (16))
101#define SSL_SOCK_CAEDEPTH_TO_ST(d) (((d > 15) ? 15 : d) << (6+16))
102#define SSL_SOCK_CRTERROR_TO_ST(e) (((e > 63) ? 63 : e) << (4+6+16))
103
104#define SSL_SOCK_ST_TO_CA_ERROR(s) ((s >> (16)) & 63)
105#define SSL_SOCK_ST_TO_CAEDEPTH(s) ((s >> (6+16)) & 15)
106#define SSL_SOCK_ST_TO_CRTERROR(s) ((s >> (4+6+16)) & 63)
Emeric Brune64aef12012-09-21 13:15:06 +0200107
Nenad Merdanovic05552d42015-02-27 19:56:49 +0100108/* Supported hash function for TLS tickets */
109#ifdef OPENSSL_NO_SHA256
110#define HASH_FUNCT EVP_sha1
111#else
112#define HASH_FUNCT EVP_sha256
113#endif /* OPENSSL_NO_SHA256 */
114
Emeric Brun850efd52014-01-29 12:24:34 +0100115/* server and bind verify method, it uses a global value as default */
116enum {
117 SSL_SOCK_VERIFY_DEFAULT = 0,
118 SSL_SOCK_VERIFY_REQUIRED = 1,
119 SSL_SOCK_VERIFY_OPTIONAL = 2,
120 SSL_SOCK_VERIFY_NONE = 3,
121};
122
Willy Tarreau71b734c2014-01-28 15:19:44 +0100123int sslconns = 0;
124int totalsslconns = 0;
Emeric Brune1f38db2012-09-03 20:36:47 +0200125
Nenad Merdanovic200b0fa2015-05-09 08:46:01 +0200126#if (defined SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB && TLS_TICKETS_NO > 0)
127struct list tlskeys_reference = LIST_HEAD_INIT(tlskeys_reference);
128#endif
129
Remi Gacogne8de54152014-07-15 11:36:40 +0200130#ifndef OPENSSL_NO_DH
Remi Gacogne4f902b82015-05-28 16:23:00 +0200131static int ssl_dh_ptr_index = -1;
Remi Gacogne47783ef2015-05-29 15:53:22 +0200132static DH *global_dh = NULL;
Remi Gacogne8de54152014-07-15 11:36:40 +0200133static DH *local_dh_1024 = NULL;
134static DH *local_dh_2048 = NULL;
135static DH *local_dh_4096 = NULL;
Remi Gacogne8de54152014-07-15 11:36:40 +0200136#endif /* OPENSSL_NO_DH */
137
Willy Tarreauc8ad3be2015-06-17 15:48:26 +0200138#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Christopher Faulet31af49d2015-06-09 17:29:50 +0200139/* X509V3 Extensions that will be added on generated certificates */
140#define X509V3_EXT_SIZE 5
141static char *x509v3_ext_names[X509V3_EXT_SIZE] = {
142 "basicConstraints",
143 "nsComment",
144 "subjectKeyIdentifier",
145 "authorityKeyIdentifier",
146 "keyUsage",
147};
148static char *x509v3_ext_values[X509V3_EXT_SIZE] = {
149 "CA:FALSE",
150 "\"OpenSSL Generated Certificate\"",
151 "hash",
152 "keyid,issuer:always",
153 "nonRepudiation,digitalSignature,keyEncipherment"
154};
155
156/* LRU cache to store generated certificate */
157static struct lru64_head *ssl_ctx_lru_tree = NULL;
158static unsigned int ssl_ctx_lru_seed = 0;
Willy Tarreauc8ad3be2015-06-17 15:48:26 +0200159#endif // SSL_CTRL_SET_TLSEXT_HOSTNAME
160
yanbzhube2774d2015-12-10 15:07:30 -0500161#if OPENSSL_VERSION_NUMBER >= 0x1000200fL
162/* The order here matters for picking a default context,
163 * keep the most common keytype at the bottom of the list
164 */
165const char *SSL_SOCK_KEYTYPE_NAMES[] = {
166 "dsa",
167 "ecdsa",
168 "rsa"
169};
170#define SSL_SOCK_NUM_KEYTYPES 3
Willy Tarreau30da7ad2015-12-14 11:28:33 +0100171#else
172#define SSL_SOCK_NUM_KEYTYPES 1
yanbzhube2774d2015-12-10 15:07:30 -0500173#endif
174
Willy Tarreauc8ad3be2015-06-17 15:48:26 +0200175#if (defined SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB && !defined OPENSSL_NO_OCSP)
yanbzhube2774d2015-12-10 15:07:30 -0500176/*
177 * struct alignment works here such that the key.key is the same as key_data
178 * Do not change the placement of key_data
179 */
Willy Tarreauc8ad3be2015-06-17 15:48:26 +0200180struct certificate_ocsp {
181 struct ebmb_node key;
182 unsigned char key_data[OCSP_MAX_CERTID_ASN1_LENGTH];
183 struct chunk response;
184 long expire;
185};
Christopher Faulet31af49d2015-06-09 17:29:50 +0200186
yanbzhube2774d2015-12-10 15:07:30 -0500187struct ocsp_cbk_arg {
188 int is_single;
189 int single_kt;
190 union {
191 struct certificate_ocsp *s_ocsp;
192 /*
193 * m_ocsp will have multiple entries dependent on key type
194 * Entry 0 - DSA
195 * Entry 1 - ECDSA
196 * Entry 2 - RSA
197 */
198 struct certificate_ocsp *m_ocsp[SSL_SOCK_NUM_KEYTYPES];
199 };
200};
201
Emeric Brun4f3c87a2014-06-20 15:46:13 +0200202/*
Thierry FOURNIER / OZON.IO8b068c22016-10-10 11:59:50 +0200203 * This function gives the detail of the SSL error. It is used only
204 * if the debug mode and the verbose mode are activated. It dump all
205 * the SSL error until the stack was empty.
206 */
207static forceinline void ssl_sock_dump_errors(struct connection *conn)
208{
209 unsigned long ret;
210
211 if (unlikely(global.mode & MODE_DEBUG)) {
212 while(1) {
213 ret = ERR_get_error();
214 if (ret == 0)
215 return;
216 fprintf(stderr, "fd[%04x] OpenSSL error[0x%lx] %s: %s\n",
217 (unsigned short)conn->t.sock.fd, ret,
218 ERR_func_error_string(ret), ERR_reason_error_string(ret));
219 }
220 }
221}
222
223/*
Emeric Brun4f3c87a2014-06-20 15:46:13 +0200224 * This function returns the number of seconds elapsed
225 * since the Epoch, 1970-01-01 00:00:00 +0000 (UTC) and the
226 * date presented un ASN1_GENERALIZEDTIME.
227 *
228 * In parsing error case, it returns -1.
229 */
230static long asn1_generalizedtime_to_epoch(ASN1_GENERALIZEDTIME *d)
231{
232 long epoch;
233 char *p, *end;
234 const unsigned short month_offset[12] = {
235 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334
236 };
237 int year, month;
238
239 if (!d || (d->type != V_ASN1_GENERALIZEDTIME)) return -1;
240
241 p = (char *)d->data;
242 end = p + d->length;
243
244 if (end - p < 4) return -1;
245 year = 1000 * (p[0] - '0') + 100 * (p[1] - '0') + 10 * (p[2] - '0') + p[3] - '0';
246 p += 4;
247 if (end - p < 2) return -1;
248 month = 10 * (p[0] - '0') + p[1] - '0';
249 if (month < 1 || month > 12) return -1;
250 /* Compute the number of seconds since 1 jan 1970 and the beginning of current month
251 We consider leap years and the current month (<marsh or not) */
252 epoch = ( ((year - 1970) * 365)
253 + ((year - (month < 3)) / 4 - (year - (month < 3)) / 100 + (year - (month < 3)) / 400)
254 - ((1970 - 1) / 4 - (1970 - 1) / 100 + (1970 - 1) / 400)
255 + month_offset[month-1]
256 ) * 24 * 60 * 60;
257 p += 2;
258 if (end - p < 2) return -1;
259 /* Add the number of seconds of completed days of current month */
260 epoch += (10 * (p[0] - '0') + p[1] - '0' - 1) * 24 * 60 * 60;
261 p += 2;
262 if (end - p < 2) return -1;
263 /* Add the completed hours of the current day */
264 epoch += (10 * (p[0] - '0') + p[1] - '0') * 60 * 60;
265 p += 2;
266 if (end - p < 2) return -1;
267 /* Add the completed minutes of the current hour */
268 epoch += (10 * (p[0] - '0') + p[1] - '0') * 60;
269 p += 2;
270 if (p == end) return -1;
271 /* Test if there is available seconds */
272 if (p[0] < '0' || p[0] > '9')
273 goto nosec;
274 if (end - p < 2) return -1;
275 /* Add the seconds of the current minute */
276 epoch += 10 * (p[0] - '0') + p[1] - '0';
277 p += 2;
278 if (p == end) return -1;
279 /* Ignore seconds float part if present */
280 if (p[0] == '.') {
281 do {
282 if (++p == end) return -1;
283 } while (p[0] >= '0' && p[0] <= '9');
284 }
285
286nosec:
287 if (p[0] == 'Z') {
288 if (end - p != 1) return -1;
289 return epoch;
290 }
291 else if (p[0] == '+') {
292 if (end - p != 5) return -1;
293 /* Apply timezone offset */
294 return epoch - ((10 * (p[1] - '0') + p[2] - '0') * 60 + (10 * (p[3] - '0') + p[4] - '0')) * 60;
295 }
296 else if (p[0] == '-') {
297 if (end - p != 5) return -1;
298 /* Apply timezone offset */
299 return epoch + ((10 * (p[1] - '0') + p[2] - '0') * 60 + (10 * (p[3] - '0') + p[4] - '0')) * 60;
300 }
301
302 return -1;
303}
304
Emeric Brun1d3865b2014-06-20 15:37:32 +0200305static struct eb_root cert_ocsp_tree = EB_ROOT_UNIQUE;
Emeric Brun4147b2e2014-06-16 18:36:30 +0200306
307/* This function starts to check if the OCSP response (in DER format) contained
308 * in chunk 'ocsp_response' is valid (else exits on error).
309 * If 'cid' is not NULL, it will be compared to the OCSP certificate ID
310 * contained in the OCSP Response and exits on error if no match.
311 * If it's a valid OCSP Response:
312 * If 'ocsp' is not NULL, the chunk is copied in the OCSP response's container
313 * pointed by 'ocsp'.
314 * If 'ocsp' is NULL, the function looks up into the OCSP response's
315 * containers tree (using as index the ASN1 form of the OCSP Certificate ID extracted
316 * from the response) and exits on error if not found. Finally, If an OCSP response is
317 * already present in the container, it will be overwritten.
318 *
319 * Note: OCSP response containing more than one OCSP Single response is not
320 * considered valid.
321 *
322 * Returns 0 on success, 1 in error case.
323 */
324static int ssl_sock_load_ocsp_response(struct chunk *ocsp_response, struct certificate_ocsp *ocsp, OCSP_CERTID *cid, char **err)
325{
326 OCSP_RESPONSE *resp;
327 OCSP_BASICRESP *bs = NULL;
328 OCSP_SINGLERESP *sr;
329 unsigned char *p = (unsigned char *)ocsp_response->str;
330 int rc , count_sr;
Emeric Brun13a6b482014-06-20 15:44:34 +0200331 ASN1_GENERALIZEDTIME *revtime, *thisupd, *nextupd = NULL;
Emeric Brun4147b2e2014-06-16 18:36:30 +0200332 int reason;
333 int ret = 1;
334
335 resp = d2i_OCSP_RESPONSE(NULL, (const unsigned char **)&p, ocsp_response->len);
336 if (!resp) {
337 memprintf(err, "Unable to parse OCSP response");
338 goto out;
339 }
340
341 rc = OCSP_response_status(resp);
342 if (rc != OCSP_RESPONSE_STATUS_SUCCESSFUL) {
343 memprintf(err, "OCSP response status not successful");
344 goto out;
345 }
346
347 bs = OCSP_response_get1_basic(resp);
348 if (!bs) {
349 memprintf(err, "Failed to get basic response from OCSP Response");
350 goto out;
351 }
352
353 count_sr = OCSP_resp_count(bs);
354 if (count_sr > 1) {
355 memprintf(err, "OCSP response ignored because contains multiple single responses (%d)", count_sr);
356 goto out;
357 }
358
359 sr = OCSP_resp_get0(bs, 0);
360 if (!sr) {
361 memprintf(err, "Failed to get OCSP single response");
362 goto out;
363 }
364
365 rc = OCSP_single_get0_status(sr, &reason, &revtime, &thisupd, &nextupd);
366 if (rc != V_OCSP_CERTSTATUS_GOOD) {
367 memprintf(err, "OCSP single response: certificate status not good");
368 goto out;
369 }
370
Emeric Brun13a6b482014-06-20 15:44:34 +0200371 if (!nextupd) {
372 memprintf(err, "OCSP single response: missing nextupdate");
373 goto out;
374 }
375
Emeric Brunc8b27b62014-06-19 14:16:17 +0200376 rc = OCSP_check_validity(thisupd, nextupd, OCSP_MAX_RESPONSE_TIME_SKEW, -1);
Emeric Brun4147b2e2014-06-16 18:36:30 +0200377 if (!rc) {
378 memprintf(err, "OCSP single response: no longer valid.");
379 goto out;
380 }
381
382 if (cid) {
383 if (OCSP_id_cmp(sr->certId, cid)) {
384 memprintf(err, "OCSP single response: Certificate ID does not match certificate and issuer");
385 goto out;
386 }
387 }
388
389 if (!ocsp) {
390 unsigned char key[OCSP_MAX_CERTID_ASN1_LENGTH];
391 unsigned char *p;
392
393 rc = i2d_OCSP_CERTID(sr->certId, NULL);
394 if (!rc) {
395 memprintf(err, "OCSP single response: Unable to encode Certificate ID");
396 goto out;
397 }
398
399 if (rc > OCSP_MAX_CERTID_ASN1_LENGTH) {
400 memprintf(err, "OCSP single response: Certificate ID too long");
401 goto out;
402 }
403
404 p = key;
405 memset(key, 0, OCSP_MAX_CERTID_ASN1_LENGTH);
406 i2d_OCSP_CERTID(sr->certId, &p);
407 ocsp = (struct certificate_ocsp *)ebmb_lookup(&cert_ocsp_tree, key, OCSP_MAX_CERTID_ASN1_LENGTH);
408 if (!ocsp) {
409 memprintf(err, "OCSP single response: Certificate ID does not match any certificate or issuer");
410 goto out;
411 }
412 }
413
414 /* According to comments on "chunk_dup", the
415 previous chunk buffer will be freed */
416 if (!chunk_dup(&ocsp->response, ocsp_response)) {
417 memprintf(err, "OCSP response: Memory allocation error");
418 goto out;
419 }
420
Emeric Brun4f3c87a2014-06-20 15:46:13 +0200421 ocsp->expire = asn1_generalizedtime_to_epoch(nextupd) - OCSP_MAX_RESPONSE_TIME_SKEW;
422
Emeric Brun4147b2e2014-06-16 18:36:30 +0200423 ret = 0;
424out:
425 if (bs)
426 OCSP_BASICRESP_free(bs);
427
428 if (resp)
429 OCSP_RESPONSE_free(resp);
430
431 return ret;
432}
433/*
434 * External function use to update the OCSP response in the OCSP response's
435 * containers tree. The chunk 'ocsp_response' must contain the OCSP response
436 * to update in DER format.
437 *
438 * Returns 0 on success, 1 in error case.
439 */
440int ssl_sock_update_ocsp_response(struct chunk *ocsp_response, char **err)
441{
442 return ssl_sock_load_ocsp_response(ocsp_response, NULL, NULL, err);
443}
444
445/*
446 * This function load the OCSP Resonse in DER format contained in file at
447 * path 'ocsp_path' and call 'ssl_sock_load_ocsp_response'
448 *
449 * Returns 0 on success, 1 in error case.
450 */
451static int ssl_sock_load_ocsp_response_from_file(const char *ocsp_path, struct certificate_ocsp *ocsp, OCSP_CERTID *cid, char **err)
452{
453 int fd = -1;
454 int r = 0;
455 int ret = 1;
456
457 fd = open(ocsp_path, O_RDONLY);
458 if (fd == -1) {
459 memprintf(err, "Error opening OCSP response file");
460 goto end;
461 }
462
463 trash.len = 0;
464 while (trash.len < trash.size) {
465 r = read(fd, trash.str + trash.len, trash.size - trash.len);
466 if (r < 0) {
467 if (errno == EINTR)
468 continue;
469
470 memprintf(err, "Error reading OCSP response from file");
471 goto end;
472 }
473 else if (r == 0) {
474 break;
475 }
476 trash.len += r;
477 }
478
479 close(fd);
480 fd = -1;
481
482 ret = ssl_sock_load_ocsp_response(&trash, ocsp, cid, err);
483end:
484 if (fd != -1)
485 close(fd);
486
487 return ret;
488}
489
Nenad Merdanovic05552d42015-02-27 19:56:49 +0100490#if (defined SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB && TLS_TICKETS_NO > 0)
491static 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)
492{
493 struct tls_sess_key *keys;
494 struct connection *conn;
495 int head;
496 int i;
497
Vincent Bernat3c2f2f22016-04-03 13:48:42 +0200498 conn = SSL_get_app_data(s);
Nenad Merdanovic146defa2015-05-09 08:46:00 +0200499 keys = objt_listener(conn->target)->bind_conf->keys_ref->tlskeys;
500 head = objt_listener(conn->target)->bind_conf->keys_ref->tls_ticket_enc_index;
Nenad Merdanovic05552d42015-02-27 19:56:49 +0100501
502 if (enc) {
503 memcpy(key_name, keys[head].name, 16);
504
505 if(!RAND_pseudo_bytes(iv, EVP_MAX_IV_LENGTH))
506 return -1;
507
508 if(!EVP_EncryptInit_ex(ectx, EVP_aes_128_cbc(), NULL, keys[head].aes_key, iv))
509 return -1;
510
511 HMAC_Init_ex(hctx, keys[head].hmac_key, 16, HASH_FUNCT(), NULL);
512
513 return 1;
514 } else {
515 for (i = 0; i < TLS_TICKETS_NO; i++) {
516 if (!memcmp(key_name, keys[(head + i) % TLS_TICKETS_NO].name, 16))
517 goto found;
518 }
519 return 0;
520
521 found:
522 HMAC_Init_ex(hctx, keys[(head + i) % TLS_TICKETS_NO].hmac_key, 16, HASH_FUNCT(), NULL);
523 if(!EVP_DecryptInit_ex(ectx, EVP_aes_128_cbc(), NULL, keys[(head + i) % TLS_TICKETS_NO].aes_key, iv))
524 return -1;
525 /* 2 for key renewal, 1 if current key is still valid */
526 return i ? 2 : 1;
527 }
Nenad Merdanovic200b0fa2015-05-09 08:46:01 +0200528}
529
530struct tls_keys_ref *tlskeys_ref_lookup(const char *filename)
531{
532 struct tls_keys_ref *ref;
533
534 list_for_each_entry(ref, &tlskeys_reference, list)
535 if (ref->filename && strcmp(filename, ref->filename) == 0)
536 return ref;
537 return NULL;
538}
539
540struct tls_keys_ref *tlskeys_ref_lookupid(int unique_id)
541{
542 struct tls_keys_ref *ref;
543
544 list_for_each_entry(ref, &tlskeys_reference, list)
545 if (ref->unique_id == unique_id)
546 return ref;
547 return NULL;
548}
549
550int ssl_sock_update_tlskey(char *filename, struct chunk *tlskey, char **err) {
551 struct tls_keys_ref *ref = tlskeys_ref_lookup(filename);
552
553 if(!ref) {
554 memprintf(err, "Unable to locate the referenced filename: %s", filename);
555 return 1;
556 }
557
Pradeep Jindalcc79b002015-08-20 18:25:17 +0530558 memcpy((char *) (ref->tlskeys + ((ref->tls_ticket_enc_index + 2) % TLS_TICKETS_NO)), tlskey->str, tlskey->len);
559 ref->tls_ticket_enc_index = (ref->tls_ticket_enc_index + 1) % TLS_TICKETS_NO;
Nenad Merdanovic200b0fa2015-05-09 08:46:01 +0200560
561 return 0;
Nenad Merdanovic05552d42015-02-27 19:56:49 +0100562}
Nenad Merdanovic200b0fa2015-05-09 08:46:01 +0200563
564/* This function finalize the configuration parsing. Its set all the
565 * automatic ids
566 */
567void tlskeys_finalize_config(void)
568{
569 int i = 0;
570 struct tls_keys_ref *ref, *ref2, *ref3;
571 struct list tkr = LIST_HEAD_INIT(tkr);
572
573 list_for_each_entry(ref, &tlskeys_reference, list) {
574 if (ref->unique_id == -1) {
575 /* Look for the first free id. */
576 while (1) {
577 list_for_each_entry(ref2, &tlskeys_reference, list) {
578 if (ref2->unique_id == i) {
579 i++;
580 break;
581 }
582 }
583 if (&ref2->list == &tlskeys_reference)
584 break;
585 }
586
587 /* Uses the unique id and increment it for the next entry. */
588 ref->unique_id = i;
589 i++;
590 }
591 }
592
593 /* This sort the reference list by id. */
594 list_for_each_entry_safe(ref, ref2, &tlskeys_reference, list) {
595 LIST_DEL(&ref->list);
596 list_for_each_entry(ref3, &tkr, list) {
597 if (ref->unique_id < ref3->unique_id) {
598 LIST_ADDQ(&ref3->list, &ref->list);
599 break;
600 }
601 }
602 if (&ref3->list == &tkr)
603 LIST_ADDQ(&tkr, &ref->list);
604 }
605
606 /* swap root */
607 LIST_ADD(&tkr, &tlskeys_reference);
608 LIST_DEL(&tkr);
609}
610
Nenad Merdanovic05552d42015-02-27 19:56:49 +0100611#endif /* SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB */
612
yanbzhube2774d2015-12-10 15:07:30 -0500613int ssl_sock_get_ocsp_arg_kt_index(int evp_keytype)
614{
615 switch (evp_keytype) {
616 case EVP_PKEY_RSA:
617 return 2;
618 case EVP_PKEY_DSA:
619 return 0;
620 case EVP_PKEY_EC:
621 return 1;
622 }
623
624 return -1;
625}
626
Emeric Brun4147b2e2014-06-16 18:36:30 +0200627/*
628 * Callback used to set OCSP status extension content in server hello.
629 */
630int ssl_sock_ocsp_stapling_cbk(SSL *ssl, void *arg)
631{
yanbzhube2774d2015-12-10 15:07:30 -0500632 struct certificate_ocsp *ocsp;
633 struct ocsp_cbk_arg *ocsp_arg;
634 char *ssl_buf;
635 EVP_PKEY *ssl_pkey;
636 int key_type;
637 int index;
638
Vincent Bernat3c2f2f22016-04-03 13:48:42 +0200639 ocsp_arg = arg;
yanbzhube2774d2015-12-10 15:07:30 -0500640
641 ssl_pkey = SSL_get_privatekey(ssl);
642 if (!ssl_pkey)
643 return SSL_TLSEXT_ERR_NOACK;
644
645 key_type = EVP_PKEY_type(ssl_pkey->type);
646
647 if (ocsp_arg->is_single && ocsp_arg->single_kt == key_type)
648 ocsp = ocsp_arg->s_ocsp;
649 else {
650 /* For multiple certs per context, we have to find the correct OCSP response based on
651 * the certificate type
652 */
653 index = ssl_sock_get_ocsp_arg_kt_index(key_type);
654
655 if (index < 0)
656 return SSL_TLSEXT_ERR_NOACK;
657
658 ocsp = ocsp_arg->m_ocsp[index];
659
660 }
Emeric Brun4147b2e2014-06-16 18:36:30 +0200661
662 if (!ocsp ||
663 !ocsp->response.str ||
Emeric Brun4f3c87a2014-06-20 15:46:13 +0200664 !ocsp->response.len ||
665 (ocsp->expire < now.tv_sec))
Emeric Brun4147b2e2014-06-16 18:36:30 +0200666 return SSL_TLSEXT_ERR_NOACK;
667
668 ssl_buf = OPENSSL_malloc(ocsp->response.len);
669 if (!ssl_buf)
670 return SSL_TLSEXT_ERR_NOACK;
671
672 memcpy(ssl_buf, ocsp->response.str, ocsp->response.len);
673 SSL_set_tlsext_status_ocsp_resp(ssl, ssl_buf, ocsp->response.len);
674
675 return SSL_TLSEXT_ERR_OK;
676}
677
678/*
679 * This function enables the handling of OCSP status extension on 'ctx' if a
680 * file name 'cert_path' suffixed using ".ocsp" is present.
681 * To enable OCSP status extension, the issuer's certificate is mandatory.
682 * It should be present in the certificate's extra chain builded from file
683 * 'cert_path'. If not found, the issuer certificate is loaded from a file
684 * named 'cert_path' suffixed using '.issuer'.
685 *
686 * In addition, ".ocsp" file content is loaded as a DER format of an OCSP
687 * response. If file is empty or content is not a valid OCSP response,
688 * OCSP status extension is enabled but OCSP response is ignored (a warning
689 * is displayed).
690 *
691 * Returns 1 if no ".ocsp" file found, 0 if OCSP status extension is
692 * succesfully enabled, or -1 in other error case.
693 */
694static int ssl_sock_load_ocsp(SSL_CTX *ctx, const char *cert_path)
695{
696
697 BIO *in = NULL;
698 X509 *x, *xi = NULL, *issuer = NULL;
699 STACK_OF(X509) *chain = NULL;
700 OCSP_CERTID *cid = NULL;
701 SSL *ssl;
702 char ocsp_path[MAXPATHLEN+1];
703 int i, ret = -1;
704 struct stat st;
705 struct certificate_ocsp *ocsp = NULL, *iocsp;
706 char *warn = NULL;
707 unsigned char *p;
708
709 snprintf(ocsp_path, MAXPATHLEN+1, "%s.ocsp", cert_path);
710
711 if (stat(ocsp_path, &st))
712 return 1;
713
714 ssl = SSL_new(ctx);
715 if (!ssl)
716 goto out;
717
718 x = SSL_get_certificate(ssl);
719 if (!x)
720 goto out;
721
722 /* Try to lookup for issuer in certificate extra chain */
723#ifdef SSL_CTRL_GET_EXTRA_CHAIN_CERTS
724 SSL_CTX_get_extra_chain_certs(ctx, &chain);
725#else
726 chain = ctx->extra_certs;
727#endif
728 for (i = 0; i < sk_X509_num(chain); i++) {
729 issuer = sk_X509_value(chain, i);
730 if (X509_check_issued(issuer, x) == X509_V_OK)
731 break;
732 else
733 issuer = NULL;
734 }
735
736 /* If not found try to load issuer from a suffixed file */
737 if (!issuer) {
738 char issuer_path[MAXPATHLEN+1];
739
740 in = BIO_new(BIO_s_file());
741 if (!in)
742 goto out;
743
744 snprintf(issuer_path, MAXPATHLEN+1, "%s.issuer", cert_path);
745 if (BIO_read_filename(in, issuer_path) <= 0)
746 goto out;
747
748 xi = PEM_read_bio_X509_AUX(in, NULL, ctx->default_passwd_callback, ctx->default_passwd_callback_userdata);
749 if (!xi)
750 goto out;
751
752 if (X509_check_issued(xi, x) != X509_V_OK)
753 goto out;
754
755 issuer = xi;
756 }
757
758 cid = OCSP_cert_to_id(0, x, issuer);
759 if (!cid)
760 goto out;
761
762 i = i2d_OCSP_CERTID(cid, NULL);
763 if (!i || (i > OCSP_MAX_CERTID_ASN1_LENGTH))
764 goto out;
765
Vincent Bernat02779b62016-04-03 13:48:43 +0200766 ocsp = calloc(1, sizeof(*ocsp));
Emeric Brun4147b2e2014-06-16 18:36:30 +0200767 if (!ocsp)
768 goto out;
769
770 p = ocsp->key_data;
771 i2d_OCSP_CERTID(cid, &p);
772
773 iocsp = (struct certificate_ocsp *)ebmb_insert(&cert_ocsp_tree, &ocsp->key, OCSP_MAX_CERTID_ASN1_LENGTH);
774 if (iocsp == ocsp)
775 ocsp = NULL;
776
yanbzhube2774d2015-12-10 15:07:30 -0500777 if (!ctx->tlsext_status_cb) {
Vincent Bernat02779b62016-04-03 13:48:43 +0200778 struct ocsp_cbk_arg *cb_arg = calloc(1, sizeof(*cb_arg));
yanbzhube2774d2015-12-10 15:07:30 -0500779
780 cb_arg->is_single = 1;
781 cb_arg->s_ocsp = iocsp;
782 cb_arg->single_kt = EVP_PKEY_type(X509_get_pubkey(x)->type);
783
784 SSL_CTX_set_tlsext_status_cb(ctx, ssl_sock_ocsp_stapling_cbk);
785 SSL_CTX_set_tlsext_status_arg(ctx, cb_arg);
786 } else {
787 /*
788 * If the ctx has a status CB, then we have previously set an OCSP staple for this ctx
789 * Update that cb_arg with the new cert's staple
790 */
Vincent Bernat3c2f2f22016-04-03 13:48:42 +0200791 struct ocsp_cbk_arg *cb_arg = ctx->tlsext_status_arg;
yanbzhube2774d2015-12-10 15:07:30 -0500792 struct certificate_ocsp *tmp_ocsp;
793 int index;
794
795 /*
796 * The following few lines will convert cb_arg from a single ocsp to multi ocsp
797 * the order of operations below matter, take care when changing it
798 */
799 tmp_ocsp = cb_arg->s_ocsp;
800 index = ssl_sock_get_ocsp_arg_kt_index(cb_arg->single_kt);
801 cb_arg->s_ocsp = NULL;
802 cb_arg->m_ocsp[index] = tmp_ocsp;
803 cb_arg->is_single = 0;
804 cb_arg->single_kt = 0;
805
806 index = ssl_sock_get_ocsp_arg_kt_index(EVP_PKEY_type(X509_get_pubkey(x)->type));
807 if (index >= 0 && !cb_arg->m_ocsp[index])
808 cb_arg->m_ocsp[index] = iocsp;
809
810 }
Emeric Brun4147b2e2014-06-16 18:36:30 +0200811
812 ret = 0;
813
814 warn = NULL;
815 if (ssl_sock_load_ocsp_response_from_file(ocsp_path, iocsp, cid, &warn)) {
816 memprintf(&warn, "Loading '%s': %s. Content will be ignored", ocsp_path, warn ? warn : "failure");
817 Warning("%s.\n", warn);
818 }
819
820out:
821 if (ssl)
822 SSL_free(ssl);
823
824 if (in)
825 BIO_free(in);
826
827 if (xi)
828 X509_free(xi);
829
830 if (cid)
831 OCSP_CERTID_free(cid);
832
833 if (ocsp)
834 free(ocsp);
835
836 if (warn)
837 free(warn);
838
839
840 return ret;
841}
842
843#endif
844
Daniel Jakots54ffb912015-11-06 20:02:41 +0100845#if (OPENSSL_VERSION_NUMBER >= 0x1000200fL && !defined OPENSSL_NO_TLSEXT && !defined OPENSSL_IS_BORINGSSL && !defined LIBRESSL_VERSION_NUMBER)
Janusz Dziemidowicz2c701b52015-03-07 23:03:59 +0100846
847#define CT_EXTENSION_TYPE 18
848
849static int sctl_ex_index = -1;
850
851/*
852 * Try to parse Signed Certificate Timestamp List structure. This function
853 * makes only basic test if the data seems like SCTL. No signature validation
854 * is performed.
855 */
856static int ssl_sock_parse_sctl(struct chunk *sctl)
857{
858 int ret = 1;
859 int len, pos, sct_len;
860 unsigned char *data;
861
862 if (sctl->len < 2)
863 goto out;
864
865 data = (unsigned char *)sctl->str;
866 len = (data[0] << 8) | data[1];
867
868 if (len + 2 != sctl->len)
869 goto out;
870
871 data = data + 2;
872 pos = 0;
873 while (pos < len) {
874 if (len - pos < 2)
875 goto out;
876
877 sct_len = (data[pos] << 8) | data[pos + 1];
878 if (pos + sct_len + 2 > len)
879 goto out;
880
881 pos += sct_len + 2;
882 }
883
884 ret = 0;
885
886out:
887 return ret;
888}
889
890static int ssl_sock_load_sctl_from_file(const char *sctl_path, struct chunk **sctl)
891{
892 int fd = -1;
893 int r = 0;
894 int ret = 1;
895
896 *sctl = NULL;
897
898 fd = open(sctl_path, O_RDONLY);
899 if (fd == -1)
900 goto end;
901
902 trash.len = 0;
903 while (trash.len < trash.size) {
904 r = read(fd, trash.str + trash.len, trash.size - trash.len);
905 if (r < 0) {
906 if (errno == EINTR)
907 continue;
908
909 goto end;
910 }
911 else if (r == 0) {
912 break;
913 }
914 trash.len += r;
915 }
916
917 ret = ssl_sock_parse_sctl(&trash);
918 if (ret)
919 goto end;
920
Vincent Bernat02779b62016-04-03 13:48:43 +0200921 *sctl = calloc(1, sizeof(**sctl));
Janusz Dziemidowicz2c701b52015-03-07 23:03:59 +0100922 if (!chunk_dup(*sctl, &trash)) {
923 free(*sctl);
924 *sctl = NULL;
925 goto end;
926 }
927
928end:
929 if (fd != -1)
930 close(fd);
931
932 return ret;
933}
934
935int ssl_sock_sctl_add_cbk(SSL *ssl, unsigned ext_type, const unsigned char **out, size_t *outlen, int *al, void *add_arg)
936{
Vincent Bernat3c2f2f22016-04-03 13:48:42 +0200937 struct chunk *sctl = add_arg;
Janusz Dziemidowicz2c701b52015-03-07 23:03:59 +0100938
939 *out = (unsigned char *)sctl->str;
940 *outlen = sctl->len;
941
942 return 1;
943}
944
945int ssl_sock_sctl_parse_cbk(SSL *s, unsigned int ext_type, const unsigned char *in, size_t inlen, int *al, void *parse_arg)
946{
947 return 1;
948}
949
950static int ssl_sock_load_sctl(SSL_CTX *ctx, const char *cert_path)
951{
952 char sctl_path[MAXPATHLEN+1];
953 int ret = -1;
954 struct stat st;
955 struct chunk *sctl = NULL;
956
957 snprintf(sctl_path, MAXPATHLEN+1, "%s.sctl", cert_path);
958
959 if (stat(sctl_path, &st))
960 return 1;
961
962 if (ssl_sock_load_sctl_from_file(sctl_path, &sctl))
963 goto out;
964
965 if (!SSL_CTX_add_server_custom_ext(ctx, CT_EXTENSION_TYPE, ssl_sock_sctl_add_cbk, NULL, sctl, ssl_sock_sctl_parse_cbk, NULL)) {
966 free(sctl);
967 goto out;
968 }
969
970 SSL_CTX_set_ex_data(ctx, sctl_ex_index, sctl);
971
972 ret = 0;
973
974out:
975 return ret;
976}
977
978#endif
979
Emeric Brune1f38db2012-09-03 20:36:47 +0200980void ssl_sock_infocbk(const SSL *ssl, int where, int ret)
981{
Vincent Bernat3c2f2f22016-04-03 13:48:42 +0200982 struct connection *conn = SSL_get_app_data(ssl);
Emeric Brund8b2bb52014-01-28 15:43:53 +0100983 BIO *write_bio;
Willy Tarreau622317d2015-02-27 16:36:16 +0100984 (void)ret; /* shut gcc stupid warning */
Emeric Brune1f38db2012-09-03 20:36:47 +0200985
986 if (where & SSL_CB_HANDSHAKE_START) {
987 /* Disable renegotiation (CVE-2009-3555) */
Willy Tarreau20879a02012-12-03 16:32:10 +0100988 if (conn->flags & CO_FL_CONNECTED) {
Emeric Brune1f38db2012-09-03 20:36:47 +0200989 conn->flags |= CO_FL_ERROR;
Willy Tarreau20879a02012-12-03 16:32:10 +0100990 conn->err_code = CO_ER_SSL_RENEG;
991 }
Emeric Brune1f38db2012-09-03 20:36:47 +0200992 }
Emeric Brund8b2bb52014-01-28 15:43:53 +0100993
994 if ((where & SSL_CB_ACCEPT_LOOP) == SSL_CB_ACCEPT_LOOP) {
995 if (!(conn->xprt_st & SSL_SOCK_ST_FL_16K_WBFSIZE)) {
996 /* Long certificate chains optimz
997 If write and read bios are differents, we
998 consider that the buffering was activated,
999 so we rise the output buffer size from 4k
1000 to 16k */
1001 write_bio = SSL_get_wbio(ssl);
1002 if (write_bio != SSL_get_rbio(ssl)) {
1003 BIO_set_write_buffer_size(write_bio, 16384);
1004 conn->xprt_st |= SSL_SOCK_ST_FL_16K_WBFSIZE;
1005 }
1006 }
1007 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02001008}
1009
Emeric Brune64aef12012-09-21 13:15:06 +02001010/* Callback is called for each certificate of the chain during a verify
1011 ok is set to 1 if preverify detect no error on current certificate.
1012 Returns 0 to break the handshake, 1 otherwise. */
Evan Broderbe554312013-06-27 00:05:25 -07001013int ssl_sock_bind_verifycbk(int ok, X509_STORE_CTX *x_store)
Emeric Brune64aef12012-09-21 13:15:06 +02001014{
1015 SSL *ssl;
1016 struct connection *conn;
Emeric Brun81c00f02012-09-21 14:31:21 +02001017 int err, depth;
Emeric Brune64aef12012-09-21 13:15:06 +02001018
1019 ssl = X509_STORE_CTX_get_ex_data(x_store, SSL_get_ex_data_X509_STORE_CTX_idx());
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02001020 conn = SSL_get_app_data(ssl);
Emeric Brune64aef12012-09-21 13:15:06 +02001021
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02001022 conn->xprt_st |= SSL_SOCK_ST_FL_VERIFY_DONE;
Emeric Brune64aef12012-09-21 13:15:06 +02001023
Emeric Brun81c00f02012-09-21 14:31:21 +02001024 if (ok) /* no errors */
1025 return ok;
1026
1027 depth = X509_STORE_CTX_get_error_depth(x_store);
1028 err = X509_STORE_CTX_get_error(x_store);
1029
1030 /* check if CA error needs to be ignored */
1031 if (depth > 0) {
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02001032 if (!SSL_SOCK_ST_TO_CA_ERROR(conn->xprt_st)) {
1033 conn->xprt_st |= SSL_SOCK_CA_ERROR_TO_ST(err);
1034 conn->xprt_st |= SSL_SOCK_CAEDEPTH_TO_ST(depth);
Emeric Brunf282a812012-09-21 15:27:54 +02001035 }
1036
Emeric Brun1eb20ef2012-12-03 13:24:29 +01001037 if (objt_listener(conn->target)->bind_conf->ca_ignerr & (1ULL << err)) {
Thierry FOURNIER / OZON.IO8b068c22016-10-10 11:59:50 +02001038 ssl_sock_dump_errors(conn);
Emeric Brun1eb20ef2012-12-03 13:24:29 +01001039 ERR_clear_error();
Emeric Brun81c00f02012-09-21 14:31:21 +02001040 return 1;
Emeric Brun1eb20ef2012-12-03 13:24:29 +01001041 }
Emeric Brun81c00f02012-09-21 14:31:21 +02001042
Willy Tarreau20879a02012-12-03 16:32:10 +01001043 conn->err_code = CO_ER_SSL_CA_FAIL;
Emeric Brun81c00f02012-09-21 14:31:21 +02001044 return 0;
1045 }
1046
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02001047 if (!SSL_SOCK_ST_TO_CRTERROR(conn->xprt_st))
1048 conn->xprt_st |= SSL_SOCK_CRTERROR_TO_ST(err);
Emeric Brunf282a812012-09-21 15:27:54 +02001049
Emeric Brun81c00f02012-09-21 14:31:21 +02001050 /* check if certificate error needs to be ignored */
Emeric Brun1eb20ef2012-12-03 13:24:29 +01001051 if (objt_listener(conn->target)->bind_conf->crt_ignerr & (1ULL << err)) {
Thierry FOURNIER / OZON.IO8b068c22016-10-10 11:59:50 +02001052 ssl_sock_dump_errors(conn);
Emeric Brun1eb20ef2012-12-03 13:24:29 +01001053 ERR_clear_error();
Emeric Brun81c00f02012-09-21 14:31:21 +02001054 return 1;
Emeric Brun1eb20ef2012-12-03 13:24:29 +01001055 }
Emeric Brun81c00f02012-09-21 14:31:21 +02001056
Willy Tarreau20879a02012-12-03 16:32:10 +01001057 conn->err_code = CO_ER_SSL_CRT_FAIL;
Emeric Brun81c00f02012-09-21 14:31:21 +02001058 return 0;
Emeric Brune64aef12012-09-21 13:15:06 +02001059}
1060
Emeric Brun29f037d2014-04-25 19:05:36 +02001061/* Callback is called for ssl protocol analyse */
1062void ssl_sock_msgcbk(int write_p, int version, int content_type, const void *buf, size_t len, SSL *ssl, void *arg)
1063{
Emeric Brun29f037d2014-04-25 19:05:36 +02001064#ifdef TLS1_RT_HEARTBEAT
1065 /* test heartbeat received (write_p is set to 0
1066 for a received record) */
Willy Tarreauf51c6982014-04-25 20:02:39 +02001067 if ((content_type == TLS1_RT_HEARTBEAT) && (write_p == 0)) {
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02001068 struct connection *conn = SSL_get_app_data(ssl);
Willy Tarreauf51c6982014-04-25 20:02:39 +02001069 const unsigned char *p = buf;
1070 unsigned int payload;
1071
Emeric Brun29f037d2014-04-25 19:05:36 +02001072 conn->xprt_st |= SSL_SOCK_RECV_HEARTBEAT;
Willy Tarreauf51c6982014-04-25 20:02:39 +02001073
1074 /* Check if this is a CVE-2014-0160 exploitation attempt. */
1075 if (*p != TLS1_HB_REQUEST)
1076 return;
1077
Willy Tarreauaeed6722014-04-25 23:59:58 +02001078 if (len < 1 + 2 + 16) /* 1 type + 2 size + 0 payload + 16 padding */
Willy Tarreauf51c6982014-04-25 20:02:39 +02001079 goto kill_it;
1080
1081 payload = (p[1] * 256) + p[2];
Willy Tarreau3b2fdb62014-04-25 23:44:22 +02001082 if (3 + payload + 16 <= len)
Willy Tarreauf51c6982014-04-25 20:02:39 +02001083 return; /* OK no problem */
Willy Tarreauaeed6722014-04-25 23:59:58 +02001084 kill_it:
Willy Tarreau3b2fdb62014-04-25 23:44:22 +02001085 /* We have a clear heartbleed attack (CVE-2014-0160), the
1086 * advertised payload is larger than the advertised packet
1087 * length, so we have garbage in the buffer between the
1088 * payload and the end of the buffer (p+len). We can't know
1089 * if the SSL stack is patched, and we don't know if we can
1090 * safely wipe out the area between p+3+len and payload.
1091 * So instead, we prevent the response from being sent by
1092 * setting the max_send_fragment to 0 and we report an SSL
1093 * error, which will kill this connection. It will be reported
1094 * above as SSL_ERROR_SSL while an other handshake failure with
Willy Tarreauf51c6982014-04-25 20:02:39 +02001095 * a heartbeat message will be reported as SSL_ERROR_SYSCALL.
1096 */
Willy Tarreau3b2fdb62014-04-25 23:44:22 +02001097 ssl->max_send_fragment = 0;
Willy Tarreauf51c6982014-04-25 20:02:39 +02001098 SSLerr(SSL_F_TLS1_HEARTBEAT, SSL_R_SSL_HANDSHAKE_FAILURE);
1099 return;
1100 }
Emeric Brun29f037d2014-04-25 19:05:36 +02001101#endif
1102}
1103
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02001104#ifdef OPENSSL_NPN_NEGOTIATED
1105/* This callback is used so that the server advertises the list of
1106 * negociable protocols for NPN.
1107 */
1108static int ssl_sock_advertise_npn_protos(SSL *s, const unsigned char **data,
1109 unsigned int *len, void *arg)
1110{
1111 struct bind_conf *conf = arg;
1112
1113 *data = (const unsigned char *)conf->npn_str;
1114 *len = conf->npn_len;
1115 return SSL_TLSEXT_ERR_OK;
1116}
1117#endif
1118
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01001119#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Willy Tarreauab861d32013-04-02 02:30:41 +02001120/* This callback is used so that the server advertises the list of
1121 * negociable protocols for ALPN.
1122 */
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01001123static int ssl_sock_advertise_alpn_protos(SSL *s, const unsigned char **out,
1124 unsigned char *outlen,
1125 const unsigned char *server,
1126 unsigned int server_len, void *arg)
Willy Tarreauab861d32013-04-02 02:30:41 +02001127{
1128 struct bind_conf *conf = arg;
1129
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01001130 if (SSL_select_next_proto((unsigned char**) out, outlen, (const unsigned char *)conf->alpn_str,
1131 conf->alpn_len, server, server_len) != OPENSSL_NPN_NEGOTIATED) {
1132 return SSL_TLSEXT_ERR_NOACK;
1133 }
Willy Tarreauab861d32013-04-02 02:30:41 +02001134 return SSL_TLSEXT_ERR_OK;
1135}
1136#endif
1137
Willy Tarreauc8ad3be2015-06-17 15:48:26 +02001138#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Christopher Faulet85b5a1a2015-10-09 11:46:32 +02001139static DH *ssl_get_tmp_dh(SSL *ssl, int export, int keylen);
1140
Christopher Faulet30548802015-06-11 13:39:32 +02001141/* Create a X509 certificate with the specified servername and serial. This
1142 * function returns a SSL_CTX object or NULL if an error occurs. */
Christopher Faulet7969a332015-10-09 11:15:03 +02001143static SSL_CTX *
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001144ssl_sock_do_create_cert(const char *servername, struct bind_conf *bind_conf, SSL *ssl)
Christopher Faulet31af49d2015-06-09 17:29:50 +02001145{
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001146 static unsigned int serial = 0;
1147
Christopher Faulet7969a332015-10-09 11:15:03 +02001148 X509 *cacert = bind_conf->ca_sign_cert;
1149 EVP_PKEY *capkey = bind_conf->ca_sign_pkey;
Christopher Faulet31af49d2015-06-09 17:29:50 +02001150 SSL_CTX *ssl_ctx = NULL;
1151 X509 *newcrt = NULL;
1152 EVP_PKEY *pkey = NULL;
Christopher Faulet31af49d2015-06-09 17:29:50 +02001153 X509_NAME *name;
1154 const EVP_MD *digest;
1155 X509V3_CTX ctx;
1156 unsigned int i;
1157
Christopher Faulet7969a332015-10-09 11:15:03 +02001158 /* Get the private key of the defautl certificate and use it */
1159 if (!(pkey = SSL_get_privatekey(ssl)))
Christopher Faulet31af49d2015-06-09 17:29:50 +02001160 goto mkcert_error;
1161
1162 /* Create the certificate */
1163 if (!(newcrt = X509_new()))
1164 goto mkcert_error;
1165
1166 /* Set version number for the certificate (X509v3) and the serial
1167 * number */
1168 if (X509_set_version(newcrt, 2L) != 1)
1169 goto mkcert_error;
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001170 if (!serial)
1171 serial = now_ms;
1172 ASN1_INTEGER_set(X509_get_serialNumber(newcrt), serial++);
Christopher Faulet31af49d2015-06-09 17:29:50 +02001173
1174 /* Set duration for the certificate */
1175 if (!X509_gmtime_adj(X509_get_notBefore(newcrt), (long)-60*60*24) ||
1176 !X509_gmtime_adj(X509_get_notAfter(newcrt),(long)60*60*24*365))
1177 goto mkcert_error;
1178
1179 /* set public key in the certificate */
1180 if (X509_set_pubkey(newcrt, pkey) != 1)
1181 goto mkcert_error;
1182
1183 /* Set issuer name from the CA */
1184 if (!(name = X509_get_subject_name(cacert)))
1185 goto mkcert_error;
1186 if (X509_set_issuer_name(newcrt, name) != 1)
1187 goto mkcert_error;
1188
1189 /* Set the subject name using the same, but the CN */
1190 name = X509_NAME_dup(name);
1191 if (X509_NAME_add_entry_by_txt(name, "CN", MBSTRING_ASC,
1192 (const unsigned char *)servername,
1193 -1, -1, 0) != 1) {
1194 X509_NAME_free(name);
1195 goto mkcert_error;
1196 }
1197 if (X509_set_subject_name(newcrt, name) != 1) {
1198 X509_NAME_free(name);
1199 goto mkcert_error;
1200 }
1201 X509_NAME_free(name);
1202
1203 /* Add x509v3 extensions as specified */
1204 X509V3_set_ctx(&ctx, cacert, newcrt, NULL, NULL, 0);
1205 for (i = 0; i < X509V3_EXT_SIZE; i++) {
1206 X509_EXTENSION *ext;
1207
1208 if (!(ext = X509V3_EXT_conf(NULL, &ctx, x509v3_ext_names[i], x509v3_ext_values[i])))
1209 goto mkcert_error;
1210 if (!X509_add_ext(newcrt, ext, -1)) {
1211 X509_EXTENSION_free(ext);
1212 goto mkcert_error;
1213 }
1214 X509_EXTENSION_free(ext);
1215 }
1216
1217 /* Sign the certificate with the CA private key */
1218 if (EVP_PKEY_type(capkey->type) == EVP_PKEY_DSA)
1219 digest = EVP_dss1();
1220 else if (EVP_PKEY_type (capkey->type) == EVP_PKEY_RSA)
1221 digest = EVP_sha256();
Christopher Faulet7969a332015-10-09 11:15:03 +02001222 else if (EVP_PKEY_type (capkey->type) == EVP_PKEY_EC)
1223 digest = EVP_sha256();
1224 else {
Christopher Faulete7db2162015-10-19 13:59:24 +02001225#if (OPENSSL_VERSION_NUMBER >= 0x1000000fL)
Christopher Faulet7969a332015-10-09 11:15:03 +02001226 int nid;
1227
1228 if (EVP_PKEY_get_default_digest_nid(capkey, &nid) <= 0)
1229 goto mkcert_error;
1230 if (!(digest = EVP_get_digestbynid(nid)))
1231 goto mkcert_error;
Christopher Faulete7db2162015-10-19 13:59:24 +02001232#else
1233 goto mkcert_error;
1234#endif
Christopher Faulet7969a332015-10-09 11:15:03 +02001235 }
1236
Christopher Faulet31af49d2015-06-09 17:29:50 +02001237 if (!(X509_sign(newcrt, capkey, digest)))
1238 goto mkcert_error;
1239
1240 /* Create and set the new SSL_CTX */
1241 if (!(ssl_ctx = SSL_CTX_new(SSLv23_server_method())))
1242 goto mkcert_error;
1243 if (!SSL_CTX_use_PrivateKey(ssl_ctx, pkey))
1244 goto mkcert_error;
1245 if (!SSL_CTX_use_certificate(ssl_ctx, newcrt))
1246 goto mkcert_error;
1247 if (!SSL_CTX_check_private_key(ssl_ctx))
1248 goto mkcert_error;
1249
1250 if (newcrt) X509_free(newcrt);
Christopher Faulet7969a332015-10-09 11:15:03 +02001251
Christopher Faulet85b5a1a2015-10-09 11:46:32 +02001252 SSL_CTX_set_tmp_dh_callback(ssl_ctx, ssl_get_tmp_dh);
1253#if defined(SSL_CTX_set_tmp_ecdh) && !defined(OPENSSL_NO_ECDH)
1254 {
1255 const char *ecdhe = (bind_conf->ecdhe ? bind_conf->ecdhe : ECDHE_DEFAULT_CURVE);
1256 EC_KEY *ecc;
1257 int nid;
1258
1259 if ((nid = OBJ_sn2nid(ecdhe)) == NID_undef)
1260 goto end;
1261 if (!(ecc = EC_KEY_new_by_curve_name(nid)))
1262 goto end;
1263 SSL_CTX_set_tmp_ecdh(ssl_ctx, ecc);
1264 EC_KEY_free(ecc);
1265 }
1266#endif
1267 end:
Christopher Faulet31af49d2015-06-09 17:29:50 +02001268 return ssl_ctx;
1269
1270 mkcert_error:
1271 if (ssl_ctx) SSL_CTX_free(ssl_ctx);
1272 if (newcrt) X509_free(newcrt);
Christopher Faulet31af49d2015-06-09 17:29:50 +02001273 return NULL;
1274}
1275
Christopher Faulet7969a332015-10-09 11:15:03 +02001276SSL_CTX *
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001277ssl_sock_create_cert(struct connection *conn, const char *servername, unsigned int key)
Christopher Faulet7969a332015-10-09 11:15:03 +02001278{
1279 struct bind_conf *bind_conf = objt_listener(conn->target)->bind_conf;
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001280
1281 return ssl_sock_do_create_cert(servername, bind_conf, conn->xprt_ctx);
Christopher Faulet7969a332015-10-09 11:15:03 +02001282}
1283
Christopher Faulet30548802015-06-11 13:39:32 +02001284/* Do a lookup for a certificate in the LRU cache used to store generated
1285 * certificates. */
1286SSL_CTX *
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001287ssl_sock_get_generated_cert(unsigned int key, struct bind_conf *bind_conf)
Christopher Faulet30548802015-06-11 13:39:32 +02001288{
1289 struct lru64 *lru = NULL;
1290
1291 if (ssl_ctx_lru_tree) {
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001292 lru = lru64_lookup(key, ssl_ctx_lru_tree, bind_conf->ca_sign_cert, 0);
Christopher Faulet30548802015-06-11 13:39:32 +02001293 if (lru && lru->domain)
1294 return (SSL_CTX *)lru->data;
1295 }
1296 return NULL;
1297}
1298
Christopher Fauletd2cab922015-07-28 16:03:47 +02001299/* Set a certificate int the LRU cache used to store generated
1300 * certificate. Return 0 on success, otherwise -1 */
1301int
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001302ssl_sock_set_generated_cert(SSL_CTX *ssl_ctx, unsigned int key, struct bind_conf *bind_conf)
Christopher Faulet30548802015-06-11 13:39:32 +02001303{
1304 struct lru64 *lru = NULL;
1305
1306 if (ssl_ctx_lru_tree) {
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001307 lru = lru64_get(key, ssl_ctx_lru_tree, bind_conf->ca_sign_cert, 0);
Christopher Faulet30548802015-06-11 13:39:32 +02001308 if (!lru)
Christopher Fauletd2cab922015-07-28 16:03:47 +02001309 return -1;
Christopher Faulet30548802015-06-11 13:39:32 +02001310 if (lru->domain && lru->data)
1311 lru->free((SSL_CTX *)lru->data);
Christopher Faulet7969a332015-10-09 11:15:03 +02001312 lru64_commit(lru, ssl_ctx, bind_conf->ca_sign_cert, 0, (void (*)(void *))SSL_CTX_free);
Christopher Fauletd2cab922015-07-28 16:03:47 +02001313 return 0;
Christopher Faulet30548802015-06-11 13:39:32 +02001314 }
Christopher Fauletd2cab922015-07-28 16:03:47 +02001315 return -1;
Christopher Faulet30548802015-06-11 13:39:32 +02001316}
1317
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001318/* Compute the key of the certificate. */
Christopher Faulet30548802015-06-11 13:39:32 +02001319unsigned int
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001320ssl_sock_generated_cert_key(const void *data, size_t len)
Christopher Faulet30548802015-06-11 13:39:32 +02001321{
1322 return XXH32(data, len, ssl_ctx_lru_seed);
1323}
1324
Willy Tarreau2f63ef42015-10-20 15:16:01 +02001325/* Generate a cert and immediately assign it to the SSL session so that the cert's
1326 * refcount is maintained regardless of the cert's presence in the LRU cache.
1327 */
Christopher Faulet31af49d2015-06-09 17:29:50 +02001328static SSL_CTX *
Christopher Faulet7969a332015-10-09 11:15:03 +02001329ssl_sock_generate_certificate(const char *servername, struct bind_conf *bind_conf, SSL *ssl)
Christopher Faulet31af49d2015-06-09 17:29:50 +02001330{
1331 X509 *cacert = bind_conf->ca_sign_cert;
Christopher Faulet31af49d2015-06-09 17:29:50 +02001332 SSL_CTX *ssl_ctx = NULL;
1333 struct lru64 *lru = NULL;
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001334 unsigned int key;
Christopher Faulet31af49d2015-06-09 17:29:50 +02001335
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001336 key = ssl_sock_generated_cert_key(servername, strlen(servername));
Christopher Faulet31af49d2015-06-09 17:29:50 +02001337 if (ssl_ctx_lru_tree) {
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001338 lru = lru64_get(key, ssl_ctx_lru_tree, cacert, 0);
Christopher Faulet31af49d2015-06-09 17:29:50 +02001339 if (lru && lru->domain)
1340 ssl_ctx = (SSL_CTX *)lru->data;
Christopher Fauletd2cab922015-07-28 16:03:47 +02001341 if (!ssl_ctx && lru) {
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001342 ssl_ctx = ssl_sock_do_create_cert(servername, bind_conf, ssl);
Christopher Faulet31af49d2015-06-09 17:29:50 +02001343 lru64_commit(lru, ssl_ctx, cacert, 0, (void (*)(void *))SSL_CTX_free);
Christopher Fauletd2cab922015-07-28 16:03:47 +02001344 }
Willy Tarreau2f63ef42015-10-20 15:16:01 +02001345 SSL_set_SSL_CTX(ssl, ssl_ctx);
Christopher Faulet31af49d2015-06-09 17:29:50 +02001346 }
Willy Tarreau2f63ef42015-10-20 15:16:01 +02001347 else {
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001348 ssl_ctx = ssl_sock_do_create_cert(servername, bind_conf, ssl);
Willy Tarreau2f63ef42015-10-20 15:16:01 +02001349 SSL_set_SSL_CTX(ssl, ssl_ctx);
1350 /* No LRU cache, this CTX will be released as soon as the session dies */
1351 SSL_CTX_free(ssl_ctx);
1352 }
Christopher Faulet31af49d2015-06-09 17:29:50 +02001353 return ssl_ctx;
1354}
1355
Emeric Brunfc0421f2012-09-07 17:30:07 +02001356/* Sets the SSL ctx of <ssl> to match the advertised server name. Returns a
1357 * warning when no match is found, which implies the default (first) cert
1358 * will keep being used.
1359 */
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001360static int ssl_sock_switchctx_cbk(SSL *ssl, int *al, struct bind_conf *s)
Emeric Brunfc0421f2012-09-07 17:30:07 +02001361{
1362 const char *servername;
1363 const char *wildp = NULL;
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001364 struct ebmb_node *node, *n;
Emeric Brunfc0421f2012-09-07 17:30:07 +02001365 int i;
1366 (void)al; /* shut gcc stupid warning */
1367
1368 servername = SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name);
Emmanuel Hocdet65623372013-01-24 17:17:15 +01001369 if (!servername) {
Willy Tarreauf6721452015-07-07 18:04:38 +02001370 if (s->generate_certs) {
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02001371 struct connection *conn = SSL_get_app_data(ssl);
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001372 unsigned int key;
Willy Tarreauf6721452015-07-07 18:04:38 +02001373 SSL_CTX *ctx;
Christopher Faulet30548802015-06-11 13:39:32 +02001374
Willy Tarreauf6721452015-07-07 18:04:38 +02001375 conn_get_to_addr(conn);
1376 if (conn->flags & CO_FL_ADDR_TO_SET) {
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001377 key = ssl_sock_generated_cert_key(&conn->addr.to, get_addr_len(&conn->addr.to));
1378 ctx = ssl_sock_get_generated_cert(key, s);
Willy Tarreauf6721452015-07-07 18:04:38 +02001379 if (ctx) {
1380 /* switch ctx */
1381 SSL_set_SSL_CTX(ssl, ctx);
1382 return SSL_TLSEXT_ERR_OK;
1383 }
Christopher Faulet30548802015-06-11 13:39:32 +02001384 }
1385 }
1386
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001387 return (s->strict_sni ?
1388 SSL_TLSEXT_ERR_ALERT_FATAL :
Emmanuel Hocdet79274e22013-05-31 12:47:44 +02001389 SSL_TLSEXT_ERR_NOACK);
Emmanuel Hocdet65623372013-01-24 17:17:15 +01001390 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02001391
Willy Tarreau19d14ef2012-10-29 16:51:55 +01001392 for (i = 0; i < trash.size; i++) {
Emeric Brunfc0421f2012-09-07 17:30:07 +02001393 if (!servername[i])
1394 break;
Willy Tarreau19d14ef2012-10-29 16:51:55 +01001395 trash.str[i] = tolower(servername[i]);
1396 if (!wildp && (trash.str[i] == '.'))
1397 wildp = &trash.str[i];
Emeric Brunfc0421f2012-09-07 17:30:07 +02001398 }
Willy Tarreau19d14ef2012-10-29 16:51:55 +01001399 trash.str[i] = 0;
Emeric Brunfc0421f2012-09-07 17:30:07 +02001400
1401 /* lookup in full qualified names */
Willy Tarreau19d14ef2012-10-29 16:51:55 +01001402 node = ebst_lookup(&s->sni_ctx, trash.str);
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001403
1404 /* lookup a not neg filter */
1405 for (n = node; n; n = ebmb_next_dup(n)) {
1406 if (!container_of(n, struct sni_ctx, name)->neg) {
1407 node = n;
1408 break;
Emmanuel Hocdet65623372013-01-24 17:17:15 +01001409 }
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001410 }
1411 if (!node && wildp) {
1412 /* lookup in wildcards names */
Emeric Brunfc0421f2012-09-07 17:30:07 +02001413 node = ebst_lookup(&s->sni_w_ctx, wildp);
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001414 }
1415 if (!node || container_of(node, struct sni_ctx, name)->neg) {
Christopher Faulet31af49d2015-06-09 17:29:50 +02001416 SSL_CTX *ctx;
Christopher Faulet31af49d2015-06-09 17:29:50 +02001417 if (s->generate_certs &&
Christopher Faulet7969a332015-10-09 11:15:03 +02001418 (ctx = ssl_sock_generate_certificate(servername, s, ssl))) {
Christopher Faulet31af49d2015-06-09 17:29:50 +02001419 /* switch ctx */
Christopher Faulet31af49d2015-06-09 17:29:50 +02001420 return SSL_TLSEXT_ERR_OK;
1421 }
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001422 return (s->strict_sni ?
1423 SSL_TLSEXT_ERR_ALERT_FATAL :
1424 SSL_TLSEXT_ERR_ALERT_WARNING);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001425 }
1426
1427 /* switch ctx */
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001428 SSL_set_SSL_CTX(ssl, container_of(node, struct sni_ctx, name)->ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001429 return SSL_TLSEXT_ERR_OK;
1430}
1431#endif /* SSL_CTRL_SET_TLSEXT_HOSTNAME */
1432
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001433#ifndef OPENSSL_NO_DH
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001434
1435static DH * ssl_get_dh_1024(void)
1436{
Remi Gacogned3a341a2015-05-29 16:26:17 +02001437 static unsigned char dh1024_p[]={
1438 0xFA,0xF9,0x2A,0x22,0x2A,0xA7,0x7F,0xE1,0x67,0x4E,0x53,0xF7,
1439 0x56,0x13,0xC3,0xB1,0xE3,0x29,0x6B,0x66,0x31,0x6A,0x7F,0xB3,
1440 0xC2,0x68,0x6B,0xCB,0x1D,0x57,0x39,0x1D,0x1F,0xFF,0x1C,0xC9,
1441 0xA6,0xA4,0x98,0x82,0x31,0x5D,0x25,0xFF,0x8A,0xE0,0x73,0x96,
1442 0x81,0xC8,0x83,0x79,0xC1,0x5A,0x04,0xF8,0x37,0x0D,0xA8,0x3D,
1443 0xAE,0x74,0xBC,0xDB,0xB6,0xA4,0x75,0xD9,0x71,0x8A,0xA0,0x17,
1444 0x9E,0x2D,0xC8,0xA8,0xDF,0x2C,0x5F,0x82,0x95,0xF8,0x92,0x9B,
1445 0xA7,0x33,0x5F,0x89,0x71,0xC8,0x2D,0x6B,0x18,0x86,0xC4,0x94,
1446 0x22,0xA5,0x52,0x8D,0xF6,0xF6,0xD2,0x37,0x92,0x0F,0xA5,0xCC,
1447 0xDB,0x7B,0x1D,0x3D,0xA1,0x31,0xB7,0x80,0x8F,0x0B,0x67,0x5E,
1448 0x36,0xA5,0x60,0x0C,0xF1,0x95,0x33,0x8B,
1449 };
1450 static unsigned char dh1024_g[]={
1451 0x02,
1452 };
1453
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001454 DH *dh = DH_new();
1455 if (dh) {
Remi Gacogned3a341a2015-05-29 16:26:17 +02001456 dh->p = BN_bin2bn(dh1024_p, sizeof dh1024_p, NULL);
1457 dh->g = BN_bin2bn(dh1024_g, sizeof dh1024_g, NULL);
1458
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001459 if (!dh->p || !dh->g) {
1460 DH_free(dh);
1461 dh = NULL;
1462 }
1463 }
1464 return dh;
1465}
1466
1467static DH *ssl_get_dh_2048(void)
1468{
Remi Gacogned3a341a2015-05-29 16:26:17 +02001469 static unsigned char dh2048_p[]={
1470 0xEC,0x86,0xF8,0x70,0xA0,0x33,0x16,0xEC,0x05,0x1A,0x73,0x59,
1471 0xCD,0x1F,0x8B,0xF8,0x29,0xE4,0xD2,0xCF,0x52,0xDD,0xC2,0x24,
1472 0x8D,0xB5,0x38,0x9A,0xFB,0x5C,0xA4,0xE4,0xB2,0xDA,0xCE,0x66,
1473 0x50,0x74,0xA6,0x85,0x4D,0x4B,0x1D,0x30,0xB8,0x2B,0xF3,0x10,
1474 0xE9,0xA7,0x2D,0x05,0x71,0xE7,0x81,0xDF,0x8B,0x59,0x52,0x3B,
1475 0x5F,0x43,0x0B,0x68,0xF1,0xDB,0x07,0xBE,0x08,0x6B,0x1B,0x23,
1476 0xEE,0x4D,0xCC,0x9E,0x0E,0x43,0xA0,0x1E,0xDF,0x43,0x8C,0xEC,
1477 0xBE,0xBE,0x90,0xB4,0x51,0x54,0xB9,0x2F,0x7B,0x64,0x76,0x4E,
1478 0x5D,0xD4,0x2E,0xAE,0xC2,0x9E,0xAE,0x51,0x43,0x59,0xC7,0x77,
1479 0x9C,0x50,0x3C,0x0E,0xED,0x73,0x04,0x5F,0xF1,0x4C,0x76,0x2A,
1480 0xD8,0xF8,0xCF,0xFC,0x34,0x40,0xD1,0xB4,0x42,0x61,0x84,0x66,
1481 0x42,0x39,0x04,0xF8,0x68,0xB2,0x62,0xD7,0x55,0xED,0x1B,0x74,
1482 0x75,0x91,0xE0,0xC5,0x69,0xC1,0x31,0x5C,0xDB,0x7B,0x44,0x2E,
1483 0xCE,0x84,0x58,0x0D,0x1E,0x66,0x0C,0xC8,0x44,0x9E,0xFD,0x40,
1484 0x08,0x67,0x5D,0xFB,0xA7,0x76,0x8F,0x00,0x11,0x87,0xE9,0x93,
1485 0xF9,0x7D,0xC4,0xBC,0x74,0x55,0x20,0xD4,0x4A,0x41,0x2F,0x43,
1486 0x42,0x1A,0xC1,0xF2,0x97,0x17,0x49,0x27,0x37,0x6B,0x2F,0x88,
1487 0x7E,0x1C,0xA0,0xA1,0x89,0x92,0x27,0xD9,0x56,0x5A,0x71,0xC1,
1488 0x56,0x37,0x7E,0x3A,0x9D,0x05,0xE7,0xEE,0x5D,0x8F,0x82,0x17,
1489 0xBC,0xE9,0xC2,0x93,0x30,0x82,0xF9,0xF4,0xC9,0xAE,0x49,0xDB,
1490 0xD0,0x54,0xB4,0xD9,0x75,0x4D,0xFA,0x06,0xB8,0xD6,0x38,0x41,
1491 0xB7,0x1F,0x77,0xF3,
1492 };
1493 static unsigned char dh2048_g[]={
1494 0x02,
1495 };
1496
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001497 DH *dh = DH_new();
1498 if (dh) {
Remi Gacogned3a341a2015-05-29 16:26:17 +02001499 dh->p = BN_bin2bn(dh2048_p, sizeof dh2048_p, NULL);
1500 dh->g = BN_bin2bn(dh2048_g, sizeof dh2048_g, NULL);
1501
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001502 if (!dh->p || !dh->g) {
1503 DH_free(dh);
1504 dh = NULL;
1505 }
1506 }
1507 return dh;
1508}
1509
1510static DH *ssl_get_dh_4096(void)
1511{
Remi Gacogned3a341a2015-05-29 16:26:17 +02001512 static unsigned char dh4096_p[]={
1513 0xDE,0x16,0x94,0xCD,0x99,0x58,0x07,0xF1,0xF7,0x32,0x96,0x11,
1514 0x04,0x82,0xD4,0x84,0x72,0x80,0x99,0x06,0xCA,0xF0,0xA3,0x68,
1515 0x07,0xCE,0x64,0x50,0xE7,0x74,0x45,0x20,0x80,0x5E,0x4D,0xAD,
1516 0xA5,0xB6,0xED,0xFA,0x80,0x6C,0x3B,0x35,0xC4,0x9A,0x14,0x6B,
1517 0x32,0xBB,0xFD,0x1F,0x17,0x8E,0xB7,0x1F,0xD6,0xFA,0x3F,0x7B,
1518 0xEE,0x16,0xA5,0x62,0x33,0x0D,0xED,0xBC,0x4E,0x58,0xE5,0x47,
1519 0x4D,0xE9,0xAB,0x8E,0x38,0xD3,0x6E,0x90,0x57,0xE3,0x22,0x15,
1520 0x33,0xBD,0xF6,0x43,0x45,0xB5,0x10,0x0A,0xBE,0x2C,0xB4,0x35,
1521 0xB8,0x53,0x8D,0xAD,0xFB,0xA7,0x1F,0x85,0x58,0x41,0x7A,0x79,
1522 0x20,0x68,0xB3,0xE1,0x3D,0x08,0x76,0xBF,0x86,0x0D,0x49,0xE3,
1523 0x82,0x71,0x8C,0xB4,0x8D,0x81,0x84,0xD4,0xE7,0xBE,0x91,0xDC,
1524 0x26,0x39,0x48,0x0F,0x35,0xC4,0xCA,0x65,0xE3,0x40,0x93,0x52,
1525 0x76,0x58,0x7D,0xDD,0x51,0x75,0xDC,0x69,0x61,0xBF,0x47,0x2C,
1526 0x16,0x68,0x2D,0xC9,0x29,0xD3,0xE6,0xC0,0x99,0x48,0xA0,0x9A,
1527 0xC8,0x78,0xC0,0x6D,0x81,0x67,0x12,0x61,0x3F,0x71,0xBA,0x41,
1528 0x1F,0x6C,0x89,0x44,0x03,0xBA,0x3B,0x39,0x60,0xAA,0x28,0x55,
1529 0x59,0xAE,0xB8,0xFA,0xCB,0x6F,0xA5,0x1A,0xF7,0x2B,0xDD,0x52,
1530 0x8A,0x8B,0xE2,0x71,0xA6,0x5E,0x7E,0xD8,0x2E,0x18,0xE0,0x66,
1531 0xDF,0xDD,0x22,0x21,0x99,0x52,0x73,0xA6,0x33,0x20,0x65,0x0E,
1532 0x53,0xE7,0x6B,0x9B,0xC5,0xA3,0x2F,0x97,0x65,0x76,0xD3,0x47,
1533 0x23,0x77,0x12,0xB6,0x11,0x7B,0x24,0xED,0xF1,0xEF,0xC0,0xE2,
1534 0xA3,0x7E,0x67,0x05,0x3E,0x96,0x4D,0x45,0xC2,0x18,0xD1,0x73,
1535 0x9E,0x07,0xF3,0x81,0x6E,0x52,0x63,0xF6,0x20,0x76,0xB9,0x13,
1536 0xD2,0x65,0x30,0x18,0x16,0x09,0x16,0x9E,0x8F,0xF1,0xD2,0x10,
1537 0x5A,0xD3,0xD4,0xAF,0x16,0x61,0xDA,0x55,0x2E,0x18,0x5E,0x14,
1538 0x08,0x54,0x2E,0x2A,0x25,0xA2,0x1A,0x9B,0x8B,0x32,0xA9,0xFD,
1539 0xC2,0x48,0x96,0xE1,0x80,0xCA,0xE9,0x22,0x17,0xBB,0xCE,0x3E,
1540 0x9E,0xED,0xC7,0xF1,0x1F,0xEC,0x17,0x21,0xDC,0x7B,0x82,0x48,
1541 0x8E,0xBB,0x4B,0x9D,0x5B,0x04,0x04,0xDA,0xDB,0x39,0xDF,0x01,
1542 0x40,0xC3,0xAA,0x26,0x23,0x89,0x75,0xC6,0x0B,0xD0,0xA2,0x60,
1543 0x6A,0xF1,0xCC,0x65,0x18,0x98,0x1B,0x52,0xD2,0x74,0x61,0xCC,
1544 0xBD,0x60,0xAE,0xA3,0xA0,0x66,0x6A,0x16,0x34,0x92,0x3F,0x41,
1545 0x40,0x31,0x29,0xC0,0x2C,0x63,0xB2,0x07,0x8D,0xEB,0x94,0xB8,
1546 0xE8,0x47,0x92,0x52,0x93,0x6A,0x1B,0x7E,0x1A,0x61,0xB3,0x1B,
1547 0xF0,0xD6,0x72,0x9B,0xF1,0xB0,0xAF,0xBF,0x3E,0x65,0xEF,0x23,
1548 0x1D,0x6F,0xFF,0x70,0xCD,0x8A,0x4C,0x8A,0xA0,0x72,0x9D,0xBE,
1549 0xD4,0xBB,0x24,0x47,0x4A,0x68,0xB5,0xF5,0xC6,0xD5,0x7A,0xCD,
1550 0xCA,0x06,0x41,0x07,0xAD,0xC2,0x1E,0xE6,0x54,0xA7,0xAD,0x03,
1551 0xD9,0x12,0xC1,0x9C,0x13,0xB1,0xC9,0x0A,0x43,0x8E,0x1E,0x08,
1552 0xCE,0x50,0x82,0x73,0x5F,0xA7,0x55,0x1D,0xD9,0x59,0xAC,0xB5,
1553 0xEA,0x02,0x7F,0x6C,0x5B,0x74,0x96,0x98,0x67,0x24,0xA3,0x0F,
1554 0x15,0xFC,0xA9,0x7D,0x3E,0x67,0xD1,0x70,0xF8,0x97,0xF3,0x67,
1555 0xC5,0x8C,0x88,0x44,0x08,0x02,0xC7,0x2B,
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001556 };
Remi Gacogned3a341a2015-05-29 16:26:17 +02001557 static unsigned char dh4096_g[]={
1558 0x02,
1559 };
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001560
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001561 DH *dh = DH_new();
1562 if (dh) {
Remi Gacogned3a341a2015-05-29 16:26:17 +02001563 dh->p = BN_bin2bn(dh4096_p, sizeof dh4096_p, NULL);
1564 dh->g = BN_bin2bn(dh4096_g, sizeof dh4096_g, NULL);
1565
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001566 if (!dh->p || !dh->g) {
1567 DH_free(dh);
1568 dh = NULL;
1569 }
1570 }
1571 return dh;
1572}
1573
1574/* Returns Diffie-Hellman parameters matching the private key length
1575 but not exceeding global.tune.ssl_default_dh_param */
1576static DH *ssl_get_tmp_dh(SSL *ssl, int export, int keylen)
1577{
1578 DH *dh = NULL;
1579 EVP_PKEY *pkey = SSL_get_privatekey(ssl);
1580 int type = pkey ? EVP_PKEY_type(pkey->type) : EVP_PKEY_NONE;
1581
1582 /* The keylen supplied by OpenSSL can only be 512 or 1024.
1583 See ssl3_send_server_key_exchange() in ssl/s3_srvr.c
1584 */
1585 if (type == EVP_PKEY_RSA || type == EVP_PKEY_DSA) {
1586 keylen = EVP_PKEY_bits(pkey);
1587 }
1588
1589 if (keylen > global.tune.ssl_default_dh_param) {
1590 keylen = global.tune.ssl_default_dh_param;
1591 }
1592
Remi Gacogned3a341a2015-05-29 16:26:17 +02001593 if (keylen >= 4096) {
Remi Gacogne8de54152014-07-15 11:36:40 +02001594 dh = local_dh_4096;
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001595 }
1596 else if (keylen >= 2048) {
Remi Gacogne8de54152014-07-15 11:36:40 +02001597 dh = local_dh_2048;
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001598 }
1599 else {
Remi Gacogne8de54152014-07-15 11:36:40 +02001600 dh = local_dh_1024;
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001601 }
1602
1603 return dh;
1604}
1605
Remi Gacogne47783ef2015-05-29 15:53:22 +02001606static DH * ssl_sock_get_dh_from_file(const char *filename)
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001607{
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001608 DH *dh = NULL;
Remi Gacogne47783ef2015-05-29 15:53:22 +02001609 BIO *in = BIO_new(BIO_s_file());
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001610
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001611 if (in == NULL)
1612 goto end;
1613
Remi Gacogne47783ef2015-05-29 15:53:22 +02001614 if (BIO_read_filename(in, filename) <= 0)
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001615 goto end;
1616
Remi Gacogne47783ef2015-05-29 15:53:22 +02001617 dh = PEM_read_bio_DHparams(in, NULL, NULL, NULL);
1618
1619end:
1620 if (in)
1621 BIO_free(in);
1622
1623 return dh;
1624}
1625
1626int ssl_sock_load_global_dh_param_from_file(const char *filename)
1627{
1628 global_dh = ssl_sock_get_dh_from_file(filename);
1629
1630 if (global_dh) {
1631 return 0;
1632 }
1633
1634 return -1;
1635}
1636
1637/* Loads Diffie-Hellman parameter from a file. Returns 1 if loaded, else -1
1638 if an error occured, and 0 if parameter not found. */
1639int ssl_sock_load_dh_params(SSL_CTX *ctx, const char *file)
1640{
1641 int ret = -1;
1642 DH *dh = ssl_sock_get_dh_from_file(file);
1643
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001644 if (dh) {
1645 ret = 1;
1646 SSL_CTX_set_tmp_dh(ctx, dh);
Remi Gacogne4f902b82015-05-28 16:23:00 +02001647
1648 if (ssl_dh_ptr_index >= 0) {
1649 /* store a pointer to the DH params to avoid complaining about
1650 ssl-default-dh-param not being set for this SSL_CTX */
1651 SSL_CTX_set_ex_data(ctx, ssl_dh_ptr_index, dh);
1652 }
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001653 }
Remi Gacogne47783ef2015-05-29 15:53:22 +02001654 else if (global_dh) {
1655 SSL_CTX_set_tmp_dh(ctx, global_dh);
1656 ret = 0; /* DH params not found */
1657 }
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001658 else {
Emeric Brun41fdb3c2013-04-26 11:05:44 +02001659 /* Clear openssl global errors stack */
1660 ERR_clear_error();
1661
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001662 if (global.tune.ssl_default_dh_param <= 1024) {
1663 /* we are limited to DH parameter of 1024 bits anyway */
Remi Gacognec7e12632016-07-02 16:26:10 +02001664 if (local_dh_1024 == NULL)
1665 local_dh_1024 = ssl_get_dh_1024();
1666
Remi Gacogne8de54152014-07-15 11:36:40 +02001667 if (local_dh_1024 == NULL)
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001668 goto end;
Willy Tarreau6e774b42014-04-25 21:35:23 +02001669
Remi Gacogne8de54152014-07-15 11:36:40 +02001670 SSL_CTX_set_tmp_dh(ctx, local_dh_1024);
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001671 }
1672 else {
1673 SSL_CTX_set_tmp_dh_callback(ctx, ssl_get_tmp_dh);
1674 }
Willy Tarreau6e774b42014-04-25 21:35:23 +02001675
Emeric Brun41fdb3c2013-04-26 11:05:44 +02001676 ret = 0; /* DH params not found */
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001677 }
Emeric Brun644cde02012-12-14 11:21:13 +01001678
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001679end:
1680 if (dh)
1681 DH_free(dh);
1682
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001683 return ret;
1684}
1685#endif
1686
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001687static int ssl_sock_add_cert_sni(SSL_CTX *ctx, struct bind_conf *s, char *name, int order)
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001688{
1689 struct sni_ctx *sc;
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001690 int wild = 0, neg = 0;
Thierry FOURNIER / OZON.IO07c3d782016-10-06 10:56:48 +02001691 struct ebmb_node *node;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001692
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001693 if (*name == '!') {
1694 neg = 1;
1695 name++;
1696 }
1697 if (*name == '*') {
1698 wild = 1;
1699 name++;
1700 }
1701 /* !* filter is a nop */
1702 if (neg && wild)
1703 return order;
1704 if (*name) {
1705 int j, len;
1706 len = strlen(name);
Thierry FOURNIER / OZON.IO07c3d782016-10-06 10:56:48 +02001707 for (j = 0; j < len && j < trash.size; j++)
1708 trash.str[j] = tolower(name[j]);
1709 if (j >= trash.size)
1710 return order;
1711 trash.str[j] = 0;
1712
1713 /* Check for duplicates. */
1714 if (wild)
1715 node = ebst_lookup(&s->sni_w_ctx, trash.str);
1716 else
1717 node = ebst_lookup(&s->sni_ctx, trash.str);
1718 for (; node; node = ebmb_next_dup(node)) {
1719 sc = ebmb_entry(node, struct sni_ctx, name);
1720 if (sc->ctx == ctx && sc->neg == neg)
1721 return order;
1722 }
1723
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001724 sc = malloc(sizeof(struct sni_ctx) + len + 1);
Thierry FOURNIER / OZON.IO7a3bd3b2016-10-06 10:35:29 +02001725 if (!sc)
1726 return order;
Thierry FOURNIER / OZON.IO07c3d782016-10-06 10:56:48 +02001727 memcpy(sc->name.key, trash.str, len + 1);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001728 sc->ctx = ctx;
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001729 sc->order = order++;
1730 sc->neg = neg;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001731 if (wild)
1732 ebst_insert(&s->sni_w_ctx, &sc->name);
1733 else
1734 ebst_insert(&s->sni_ctx, &sc->name);
1735 }
1736 return order;
1737}
1738
yanbzhu488a4d22015-12-01 15:16:07 -05001739
1740/* The following code is used for loading multiple crt files into
1741 * SSL_CTX's based on CN/SAN
1742 */
1743#if OPENSSL_VERSION_NUMBER >= 0x1000200fL
1744/* This is used to preload the certifcate, private key
1745 * and Cert Chain of a file passed in via the crt
1746 * argument
1747 *
1748 * This way, we do not have to read the file multiple times
1749 */
1750struct cert_key_and_chain {
1751 X509 *cert;
1752 EVP_PKEY *key;
1753 unsigned int num_chain_certs;
1754 /* This is an array of X509 pointers */
1755 X509 **chain_certs;
1756};
1757
yanbzhu08ce6ab2015-12-02 13:01:29 -05001758#define SSL_SOCK_POSSIBLE_KT_COMBOS (1<<(SSL_SOCK_NUM_KEYTYPES))
1759
1760struct key_combo_ctx {
1761 SSL_CTX *ctx;
1762 int order;
1763};
1764
1765/* Map used for processing multiple keypairs for a single purpose
1766 *
1767 * This maps CN/SNI name to certificate type
1768 */
1769struct sni_keytype {
1770 int keytypes; /* BITMASK for keytypes */
1771 struct ebmb_node name; /* node holding the servername value */
1772};
1773
1774
yanbzhu488a4d22015-12-01 15:16:07 -05001775/* Frees the contents of a cert_key_and_chain
1776 */
1777static void ssl_sock_free_cert_key_and_chain_contents(struct cert_key_and_chain *ckch)
1778{
1779 int i;
1780
1781 if (!ckch)
1782 return;
1783
1784 /* Free the certificate and set pointer to NULL */
1785 if (ckch->cert)
1786 X509_free(ckch->cert);
1787 ckch->cert = NULL;
1788
1789 /* Free the key and set pointer to NULL */
1790 if (ckch->key)
1791 EVP_PKEY_free(ckch->key);
1792 ckch->key = NULL;
1793
1794 /* Free each certificate in the chain */
1795 for (i = 0; i < ckch->num_chain_certs; i++) {
1796 if (ckch->chain_certs[i])
1797 X509_free(ckch->chain_certs[i]);
1798 }
1799
1800 /* Free the chain obj itself and set to NULL */
1801 if (ckch->num_chain_certs > 0) {
1802 free(ckch->chain_certs);
1803 ckch->num_chain_certs = 0;
1804 ckch->chain_certs = NULL;
1805 }
1806
1807}
1808
1809/* checks if a key and cert exists in the ckch
1810 */
1811static int ssl_sock_is_ckch_valid(struct cert_key_and_chain *ckch)
1812{
1813 return (ckch->cert != NULL && ckch->key != NULL);
1814}
1815
1816
1817/* Loads the contents of a crt file (path) into a cert_key_and_chain
1818 * This allows us to carry the contents of the file without having to
1819 * read the file multiple times.
1820 *
1821 * returns:
1822 * 0 on Success
1823 * 1 on SSL Failure
1824 * 2 on file not found
1825 */
1826static int ssl_sock_load_crt_file_into_ckch(const char *path, struct cert_key_and_chain *ckch, char **err)
1827{
1828
1829 BIO *in;
1830 X509 *ca = NULL;
1831 int ret = 1;
1832
1833 ssl_sock_free_cert_key_and_chain_contents(ckch);
1834
1835 in = BIO_new(BIO_s_file());
1836 if (in == NULL)
1837 goto end;
1838
1839 if (BIO_read_filename(in, path) <= 0)
1840 goto end;
1841
yanbzhu488a4d22015-12-01 15:16:07 -05001842 /* Read Private Key */
1843 ckch->key = PEM_read_bio_PrivateKey(in, NULL, NULL, NULL);
1844 if (ckch->key == NULL) {
1845 memprintf(err, "%sunable to load private key from file '%s'.\n",
1846 err && *err ? *err : "", path);
1847 goto end;
1848 }
1849
Willy Tarreaubb137a82016-04-06 19:02:38 +02001850 /* Seek back to beginning of file */
Thierry FOURNIER / OZON.IOd44ea3f2016-10-14 00:49:21 +02001851 if (BIO_reset(in) == -1) {
1852 memprintf(err, "%san error occurred while reading the file '%s'.\n",
1853 err && *err ? *err : "", path);
1854 goto end;
1855 }
Willy Tarreaubb137a82016-04-06 19:02:38 +02001856
1857 /* Read Certificate */
1858 ckch->cert = PEM_read_bio_X509_AUX(in, NULL, NULL, NULL);
1859 if (ckch->cert == NULL) {
1860 memprintf(err, "%sunable to load certificate from file '%s'.\n",
1861 err && *err ? *err : "", path);
1862 goto end;
1863 }
1864
yanbzhu488a4d22015-12-01 15:16:07 -05001865 /* Read Certificate Chain */
1866 while ((ca = PEM_read_bio_X509(in, NULL, NULL, NULL))) {
1867 /* Grow the chain certs */
1868 ckch->num_chain_certs++;
1869 ckch->chain_certs = realloc(ckch->chain_certs, (ckch->num_chain_certs * sizeof(X509 *)));
1870
1871 /* use - 1 here since we just incremented it above */
1872 ckch->chain_certs[ckch->num_chain_certs - 1] = ca;
1873 }
1874 ret = ERR_get_error();
1875 if (ret && (ERR_GET_LIB(ret) != ERR_LIB_PEM && ERR_GET_REASON(ret) != PEM_R_NO_START_LINE)) {
1876 memprintf(err, "%sunable to load certificate chain from file '%s'.\n",
1877 err && *err ? *err : "", path);
1878 ret = 1;
1879 goto end;
1880 }
1881
1882 ret = 0;
1883
1884end:
1885
1886 ERR_clear_error();
1887 if (in)
1888 BIO_free(in);
1889
1890 /* Something went wrong in one of the reads */
1891 if (ret != 0)
1892 ssl_sock_free_cert_key_and_chain_contents(ckch);
1893
1894 return ret;
1895}
1896
1897/* Loads the info in ckch into ctx
1898 * Currently, this does not process any information about ocsp, dhparams or
1899 * sctl
1900 * Returns
1901 * 0 on success
1902 * 1 on failure
1903 */
1904static int ssl_sock_put_ckch_into_ctx(const char *path, const struct cert_key_and_chain *ckch, SSL_CTX *ctx, char **err)
1905{
1906 int i = 0;
1907
1908 if (SSL_CTX_use_PrivateKey(ctx, ckch->key) <= 0) {
1909 memprintf(err, "%sunable to load SSL private key into SSL Context '%s'.\n",
1910 err && *err ? *err : "", path);
1911 return 1;
1912 }
1913
1914 if (!SSL_CTX_use_certificate(ctx, ckch->cert)) {
1915 memprintf(err, "%sunable to load SSL certificate into SSL Context '%s'.\n",
1916 err && *err ? *err : "", path);
1917 return 1;
1918 }
1919
yanbzhu488a4d22015-12-01 15:16:07 -05001920 /* Load all certs in the ckch into the ctx_chain for the ssl_ctx */
1921 for (i = 0; i < ckch->num_chain_certs; i++) {
1922 if (!SSL_CTX_add1_chain_cert(ctx, ckch->chain_certs[i])) {
yanbzhu08ce6ab2015-12-02 13:01:29 -05001923 memprintf(err, "%sunable to load chain certificate #%d into SSL Context '%s'. Make sure you are linking against Openssl >= 1.0.2.\n",
1924 err && *err ? *err : "", (i+1), path);
yanbzhu488a4d22015-12-01 15:16:07 -05001925 return 1;
1926 }
1927 }
1928
1929 if (SSL_CTX_check_private_key(ctx) <= 0) {
1930 memprintf(err, "%sinconsistencies between private key and certificate loaded from PEM file '%s'.\n",
1931 err && *err ? *err : "", path);
1932 return 1;
1933 }
1934
1935 return 0;
1936}
1937
yanbzhu08ce6ab2015-12-02 13:01:29 -05001938
1939static void ssl_sock_populate_sni_keytypes_hplr(const char *str, struct eb_root *sni_keytypes, int key_index)
1940{
1941 struct sni_keytype *s_kt = NULL;
1942 struct ebmb_node *node;
1943 int i;
1944
1945 for (i = 0; i < trash.size; i++) {
1946 if (!str[i])
1947 break;
1948 trash.str[i] = tolower(str[i]);
1949 }
1950 trash.str[i] = 0;
1951 node = ebst_lookup(sni_keytypes, trash.str);
1952 if (!node) {
1953 /* CN not found in tree */
1954 s_kt = malloc(sizeof(struct sni_keytype) + i + 1);
1955 /* Using memcpy here instead of strncpy.
1956 * strncpy will cause sig_abrt errors under certain versions of gcc with -O2
1957 * See: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=60792
1958 */
1959 memcpy(s_kt->name.key, trash.str, i+1);
1960 s_kt->keytypes = 0;
1961 ebst_insert(sni_keytypes, &s_kt->name);
1962 } else {
1963 /* CN found in tree */
1964 s_kt = container_of(node, struct sni_keytype, name);
1965 }
1966
1967 /* Mark that this CN has the keytype of key_index via keytypes mask */
1968 s_kt->keytypes |= 1<<key_index;
1969
1970}
1971
1972
1973/* Given a path that does not exist, try to check for path.rsa, path.dsa and path.ecdsa files.
1974 * If any are found, group these files into a set of SSL_CTX*
1975 * based on shared and unique CN and SAN entries. Add these SSL_CTX* to the SNI tree.
1976 *
1977 * This will allow the user to explictly group multiple cert/keys for a single purpose
1978 *
1979 * Returns
1980 * 0 on success
1981 * 1 on failure
1982 */
Emmanuel Hocdetd294aea2016-05-13 11:14:06 +02001983static 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 -05001984{
1985 char fp[MAXPATHLEN+1] = {0};
1986 int n = 0;
1987 int i = 0;
1988 struct cert_key_and_chain certs_and_keys[SSL_SOCK_NUM_KEYTYPES] = { {0} };
1989 struct eb_root sni_keytypes_map = { {0} };
1990 struct ebmb_node *node;
1991 struct ebmb_node *next;
1992 /* Array of SSL_CTX pointers corresponding to each possible combo
1993 * of keytypes
1994 */
1995 struct key_combo_ctx key_combos[SSL_SOCK_POSSIBLE_KT_COMBOS] = { {0} };
1996 int rv = 0;
1997 X509_NAME *xname = NULL;
1998 char *str = NULL;
1999#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
2000 STACK_OF(GENERAL_NAME) *names = NULL;
2001#endif
2002
2003 /* Load all possible certs and keys */
2004 for (n = 0; n < SSL_SOCK_NUM_KEYTYPES; n++) {
2005 struct stat buf;
2006
2007 snprintf(fp, sizeof(fp), "%s.%s", path, SSL_SOCK_KEYTYPE_NAMES[n]);
2008 if (stat(fp, &buf) == 0) {
2009 if (ssl_sock_load_crt_file_into_ckch(fp, &certs_and_keys[n], err) == 1) {
2010 rv = 1;
2011 goto end;
2012 }
2013 }
2014 }
2015
2016 /* Process each ckch and update keytypes for each CN/SAN
2017 * for example, if CN/SAN www.a.com is associated with
2018 * certs with keytype 0 and 2, then at the end of the loop,
2019 * www.a.com will have:
2020 * keyindex = 0 | 1 | 4 = 5
2021 */
2022 for (n = 0; n < SSL_SOCK_NUM_KEYTYPES; n++) {
2023
2024 if (!ssl_sock_is_ckch_valid(&certs_and_keys[n]))
2025 continue;
2026
Emmanuel Hocdetd294aea2016-05-13 11:14:06 +02002027 if (fcount) {
Willy Tarreau24b892f2016-06-20 23:01:57 +02002028 for (i = 0; i < fcount; i++)
Emmanuel Hocdetd294aea2016-05-13 11:14:06 +02002029 ssl_sock_populate_sni_keytypes_hplr(sni_filter[i], &sni_keytypes_map, n);
2030 } else {
2031 /* A lot of the following code is OpenSSL boilerplate for processing CN's and SAN's,
2032 * so the line that contains logic is marked via comments
2033 */
2034 xname = X509_get_subject_name(certs_and_keys[n].cert);
2035 i = -1;
2036 while ((i = X509_NAME_get_index_by_NID(xname, NID_commonName, i)) != -1) {
2037 X509_NAME_ENTRY *entry = X509_NAME_get_entry(xname, i);
yanbzhu08ce6ab2015-12-02 13:01:29 -05002038
Emmanuel Hocdetd294aea2016-05-13 11:14:06 +02002039 if (ASN1_STRING_to_UTF8((unsigned char **)&str, entry->value) >= 0) {
2040 /* Important line is here */
2041 ssl_sock_populate_sni_keytypes_hplr(str, &sni_keytypes_map, n);
yanbzhu08ce6ab2015-12-02 13:01:29 -05002042
Emmanuel Hocdetd294aea2016-05-13 11:14:06 +02002043 OPENSSL_free(str);
2044 str = NULL;
2045 }
yanbzhu08ce6ab2015-12-02 13:01:29 -05002046 }
yanbzhu08ce6ab2015-12-02 13:01:29 -05002047
Emmanuel Hocdetd294aea2016-05-13 11:14:06 +02002048 /* Do the above logic for each SAN */
yanbzhu08ce6ab2015-12-02 13:01:29 -05002049#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Emmanuel Hocdetd294aea2016-05-13 11:14:06 +02002050 names = X509_get_ext_d2i(certs_and_keys[n].cert, NID_subject_alt_name, NULL, NULL);
2051 if (names) {
2052 for (i = 0; i < sk_GENERAL_NAME_num(names); i++) {
2053 GENERAL_NAME *name = sk_GENERAL_NAME_value(names, i);
yanbzhu08ce6ab2015-12-02 13:01:29 -05002054
Emmanuel Hocdetd294aea2016-05-13 11:14:06 +02002055 if (name->type == GEN_DNS) {
2056 if (ASN1_STRING_to_UTF8((unsigned char **)&str, name->d.dNSName) >= 0) {
2057 /* Important line is here */
2058 ssl_sock_populate_sni_keytypes_hplr(str, &sni_keytypes_map, n);
yanbzhu08ce6ab2015-12-02 13:01:29 -05002059
Emmanuel Hocdetd294aea2016-05-13 11:14:06 +02002060 OPENSSL_free(str);
2061 str = NULL;
2062 }
yanbzhu08ce6ab2015-12-02 13:01:29 -05002063 }
2064 }
2065 }
2066 }
2067#endif /* SSL_CTRL_SET_TLSEXT_HOSTNAME */
2068 }
2069
2070 /* If no files found, return error */
2071 if (eb_is_empty(&sni_keytypes_map)) {
2072 memprintf(err, "%sunable to load SSL certificate file '%s' file does not exist.\n",
2073 err && *err ? *err : "", path);
2074 rv = 1;
2075 goto end;
2076 }
2077
2078 /* We now have a map of CN/SAN to keytypes that are loaded in
2079 * Iterate through the map to create the SSL_CTX's (if needed)
2080 * and add each CTX to the SNI tree
2081 *
2082 * Some math here:
2083 * There are 2^n - 1 possibile combinations, each unique
2084 * combination is denoted by the key in the map. Each key
2085 * has a value between 1 and 2^n - 1. Conveniently, the array
2086 * of SSL_CTX* is sized 2^n. So, we can simply use the i'th
2087 * entry in the array to correspond to the unique combo (key)
2088 * associated with i. This unique key combo (i) will be associated
2089 * with combos[i-1]
2090 */
2091
2092 node = ebmb_first(&sni_keytypes_map);
2093 while (node) {
2094 SSL_CTX *cur_ctx;
2095
2096 str = (char *)container_of(node, struct sni_keytype, name)->name.key;
2097 i = container_of(node, struct sni_keytype, name)->keytypes;
2098 cur_ctx = key_combos[i-1].ctx;
2099
2100 if (cur_ctx == NULL) {
2101 /* need to create SSL_CTX */
2102 cur_ctx = SSL_CTX_new(SSLv23_server_method());
2103 if (cur_ctx == NULL) {
2104 memprintf(err, "%sunable to allocate SSL context.\n",
2105 err && *err ? *err : "");
2106 rv = 1;
2107 goto end;
2108 }
2109
yanbzhube2774d2015-12-10 15:07:30 -05002110 /* Load all required certs/keys/chains/OCSPs info into SSL_CTX */
yanbzhu08ce6ab2015-12-02 13:01:29 -05002111 for (n = 0; n < SSL_SOCK_NUM_KEYTYPES; n++) {
2112 if (i & (1<<n)) {
2113 /* Key combo contains ckch[n] */
2114 snprintf(trash.str, trash.size, "%s.%s", path, SSL_SOCK_KEYTYPE_NAMES[n]);
2115 if (ssl_sock_put_ckch_into_ctx(trash.str, &certs_and_keys[n], cur_ctx, err) != 0) {
2116 SSL_CTX_free(cur_ctx);
2117 rv = 1;
2118 goto end;
2119 }
yanbzhube2774d2015-12-10 15:07:30 -05002120
2121#if (defined SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB && !defined OPENSSL_NO_OCSP)
2122 /* Load OCSP Info into context */
2123 if (ssl_sock_load_ocsp(cur_ctx, trash.str) < 0) {
2124 if (err)
2125 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",
2126 *err ? *err : "", path);
2127 SSL_CTX_free(cur_ctx);
2128 rv = 1;
2129 goto end;
2130 }
2131#endif
yanbzhu08ce6ab2015-12-02 13:01:29 -05002132 }
2133 }
2134
2135 /* Load DH params into the ctx to support DHE keys */
2136#ifndef OPENSSL_NO_DH
2137 if (ssl_dh_ptr_index >= 0)
2138 SSL_CTX_set_ex_data(cur_ctx, ssl_dh_ptr_index, NULL);
2139
2140 rv = ssl_sock_load_dh_params(cur_ctx, NULL);
2141 if (rv < 0) {
2142 if (err)
2143 memprintf(err, "%sunable to load DH parameters from file '%s'.\n",
2144 *err ? *err : "", path);
2145 rv = 1;
2146 goto end;
2147 }
2148#endif
2149
2150 /* Update key_combos */
2151 key_combos[i-1].ctx = cur_ctx;
2152 }
2153
2154 /* Update SNI Tree */
Emmanuel Hocdetd294aea2016-05-13 11:14:06 +02002155 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 -05002156 node = ebmb_next(node);
2157 }
2158
2159
2160 /* Mark a default context if none exists, using the ctx that has the most shared keys */
2161 if (!bind_conf->default_ctx) {
2162 for (i = SSL_SOCK_POSSIBLE_KT_COMBOS - 1; i >= 0; i--) {
2163 if (key_combos[i].ctx) {
2164 bind_conf->default_ctx = key_combos[i].ctx;
2165 break;
2166 }
2167 }
2168 }
2169
2170end:
2171
2172 if (names)
2173 sk_GENERAL_NAME_pop_free(names, GENERAL_NAME_free);
2174
2175 for (n = 0; n < SSL_SOCK_NUM_KEYTYPES; n++)
2176 ssl_sock_free_cert_key_and_chain_contents(&certs_and_keys[n]);
2177
2178 node = ebmb_first(&sni_keytypes_map);
2179 while (node) {
2180 next = ebmb_next(node);
2181 ebmb_delete(node);
2182 node = next;
2183 }
2184
2185 return rv;
2186}
2187#else
2188/* This is a dummy, that just logs an error and returns error */
Emmanuel Hocdetd294aea2016-05-13 11:14:06 +02002189static 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 -05002190{
2191 memprintf(err, "%sunable to stat SSL certificate from file '%s' : %s.\n",
2192 err && *err ? *err : "", path, strerror(errno));
2193 return 1;
2194}
2195
yanbzhu488a4d22015-12-01 15:16:07 -05002196#endif /* #if OPENSSL_VERSION_NUMBER >= 0x1000200fL: Support for loading multiple certs into a single SSL_CTX */
2197
Emeric Brunfc0421f2012-09-07 17:30:07 +02002198/* Loads a certificate key and CA chain from a file. Returns 0 on error, -1 if
2199 * an early error happens and the caller must call SSL_CTX_free() by itelf.
2200 */
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02002201static 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 +02002202{
2203 BIO *in;
2204 X509 *x = NULL, *ca;
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02002205 int i, err;
Emeric Brunfc0421f2012-09-07 17:30:07 +02002206 int ret = -1;
2207 int order = 0;
2208 X509_NAME *xname;
2209 char *str;
Emeric Brunfc0421f2012-09-07 17:30:07 +02002210#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
2211 STACK_OF(GENERAL_NAME) *names;
2212#endif
2213
2214 in = BIO_new(BIO_s_file());
2215 if (in == NULL)
2216 goto end;
2217
2218 if (BIO_read_filename(in, file) <= 0)
2219 goto end;
2220
2221 x = PEM_read_bio_X509_AUX(in, NULL, ctx->default_passwd_callback, ctx->default_passwd_callback_userdata);
2222 if (x == NULL)
2223 goto end;
2224
Emeric Brun50bcecc2013-04-22 13:05:23 +02002225 if (fcount) {
2226 while (fcount--)
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02002227 order = ssl_sock_add_cert_sni(ctx, s, sni_filter[fcount], order);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002228 }
2229 else {
Emeric Brunfc0421f2012-09-07 17:30:07 +02002230#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002231 names = X509_get_ext_d2i(x, NID_subject_alt_name, NULL, NULL);
2232 if (names) {
2233 for (i = 0; i < sk_GENERAL_NAME_num(names); i++) {
2234 GENERAL_NAME *name = sk_GENERAL_NAME_value(names, i);
2235 if (name->type == GEN_DNS) {
2236 if (ASN1_STRING_to_UTF8((unsigned char **)&str, name->d.dNSName) >= 0) {
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02002237 order = ssl_sock_add_cert_sni(ctx, s, str, order);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002238 OPENSSL_free(str);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002239 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02002240 }
2241 }
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002242 sk_GENERAL_NAME_pop_free(names, GENERAL_NAME_free);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002243 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02002244#endif /* SSL_CTRL_SET_TLSEXT_HOSTNAME */
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002245 xname = X509_get_subject_name(x);
2246 i = -1;
2247 while ((i = X509_NAME_get_index_by_NID(xname, NID_commonName, i)) != -1) {
2248 X509_NAME_ENTRY *entry = X509_NAME_get_entry(xname, i);
2249 if (ASN1_STRING_to_UTF8((unsigned char **)&str, entry->value) >= 0) {
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02002250 order = ssl_sock_add_cert_sni(ctx, s, str, order);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002251 OPENSSL_free(str);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002252 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02002253 }
2254 }
2255
2256 ret = 0; /* the caller must not free the SSL_CTX argument anymore */
2257 if (!SSL_CTX_use_certificate(ctx, x))
2258 goto end;
2259
2260 if (ctx->extra_certs != NULL) {
2261 sk_X509_pop_free(ctx->extra_certs, X509_free);
2262 ctx->extra_certs = NULL;
2263 }
2264
2265 while ((ca = PEM_read_bio_X509(in, NULL, ctx->default_passwd_callback, ctx->default_passwd_callback_userdata))) {
2266 if (!SSL_CTX_add_extra_chain_cert(ctx, ca)) {
2267 X509_free(ca);
2268 goto end;
2269 }
2270 }
2271
2272 err = ERR_get_error();
2273 if (!err || (ERR_GET_LIB(err) == ERR_LIB_PEM && ERR_GET_REASON(err) == PEM_R_NO_START_LINE)) {
2274 /* we successfully reached the last cert in the file */
2275 ret = 1;
2276 }
2277 ERR_clear_error();
2278
2279end:
2280 if (x)
2281 X509_free(x);
2282
2283 if (in)
2284 BIO_free(in);
2285
2286 return ret;
2287}
2288
Emeric Brun50bcecc2013-04-22 13:05:23 +02002289static 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 +02002290{
2291 int ret;
2292 SSL_CTX *ctx;
2293
2294 ctx = SSL_CTX_new(SSLv23_server_method());
2295 if (!ctx) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02002296 memprintf(err, "%sunable to allocate SSL context for cert '%s'.\n",
2297 err && *err ? *err : "", path);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002298 return 1;
2299 }
2300
2301 if (SSL_CTX_use_PrivateKey_file(ctx, path, SSL_FILETYPE_PEM) <= 0) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02002302 memprintf(err, "%sunable to load SSL private key from PEM file '%s'.\n",
2303 err && *err ? *err : "", path);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002304 SSL_CTX_free(ctx);
2305 return 1;
2306 }
2307
Emeric Brun50bcecc2013-04-22 13:05:23 +02002308 ret = ssl_sock_load_cert_chain_file(ctx, path, bind_conf, sni_filter, fcount);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002309 if (ret <= 0) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02002310 memprintf(err, "%sunable to load SSL certificate from PEM file '%s'.\n",
2311 err && *err ? *err : "", path);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002312 if (ret < 0) /* serious error, must do that ourselves */
2313 SSL_CTX_free(ctx);
2314 return 1;
2315 }
Emeric Brun61694ab2012-10-26 13:35:33 +02002316
2317 if (SSL_CTX_check_private_key(ctx) <= 0) {
2318 memprintf(err, "%sinconsistencies between private key and certificate loaded from PEM file '%s'.\n",
2319 err && *err ? *err : "", path);
2320 return 1;
2321 }
2322
Emeric Brunfc0421f2012-09-07 17:30:07 +02002323 /* we must not free the SSL_CTX anymore below, since it's already in
2324 * the tree, so it will be discovered and cleaned in time.
2325 */
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02002326#ifndef OPENSSL_NO_DH
Remi Gacogne4f902b82015-05-28 16:23:00 +02002327 /* store a NULL pointer to indicate we have not yet loaded
2328 a custom DH param file */
2329 if (ssl_dh_ptr_index >= 0) {
2330 SSL_CTX_set_ex_data(ctx, ssl_dh_ptr_index, NULL);
2331 }
2332
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02002333 ret = ssl_sock_load_dh_params(ctx, path);
2334 if (ret < 0) {
2335 if (err)
2336 memprintf(err, "%sunable to load DH parameters from file '%s'.\n",
2337 *err ? *err : "", path);
2338 return 1;
2339 }
2340#endif
2341
Lukas Tribuse4e30f72014-12-09 16:32:51 +01002342#if (defined SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB && !defined OPENSSL_NO_OCSP)
Emeric Brun4147b2e2014-06-16 18:36:30 +02002343 ret = ssl_sock_load_ocsp(ctx, path);
2344 if (ret < 0) {
2345 if (err)
2346 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",
2347 *err ? *err : "", path);
2348 return 1;
2349 }
2350#endif
2351
Daniel Jakots54ffb912015-11-06 20:02:41 +01002352#if (OPENSSL_VERSION_NUMBER >= 0x1000200fL && !defined OPENSSL_NO_TLSEXT && !defined OPENSSL_IS_BORINGSSL && !defined LIBRESSL_VERSION_NUMBER)
Janusz Dziemidowicz2c701b52015-03-07 23:03:59 +01002353 if (sctl_ex_index >= 0) {
2354 ret = ssl_sock_load_sctl(ctx, path);
2355 if (ret < 0) {
2356 if (err)
2357 memprintf(err, "%s '%s.sctl' is present but cannot be read or parsed'.\n",
2358 *err ? *err : "", path);
2359 return 1;
2360 }
2361 }
2362#endif
2363
Emeric Brunfc0421f2012-09-07 17:30:07 +02002364#ifndef SSL_CTRL_SET_TLSEXT_HOSTNAME
Willy Tarreau2a65ff02012-09-13 17:54:29 +02002365 if (bind_conf->default_ctx) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02002366 memprintf(err, "%sthis version of openssl cannot load multiple SSL certificates.\n",
2367 err && *err ? *err : "");
Emeric Brunfc0421f2012-09-07 17:30:07 +02002368 return 1;
2369 }
2370#endif
Willy Tarreau2a65ff02012-09-13 17:54:29 +02002371 if (!bind_conf->default_ctx)
2372 bind_conf->default_ctx = ctx;
Emeric Brunfc0421f2012-09-07 17:30:07 +02002373
2374 return 0;
2375}
2376
Willy Tarreau79eeafa2012-09-14 07:53:05 +02002377int ssl_sock_load_cert(char *path, struct bind_conf *bind_conf, struct proxy *curproxy, char **err)
Emeric Brunfc0421f2012-09-07 17:30:07 +02002378{
Cyril Bonté3180f7b2015-01-25 00:16:08 +01002379 struct dirent **de_list;
2380 int i, n;
Emeric Brunfc0421f2012-09-07 17:30:07 +02002381 DIR *dir;
2382 struct stat buf;
Willy Tarreauee2663b2012-12-06 11:36:59 +01002383 char *end;
2384 char fp[MAXPATHLEN+1];
Emeric Brunfc0421f2012-09-07 17:30:07 +02002385 int cfgerr = 0;
yanbzhu63ea8462015-12-09 13:35:14 -05002386#if OPENSSL_VERSION_NUMBER >= 0x1000200fL
2387 int is_bundle;
2388 int j;
2389#endif
Emeric Brunfc0421f2012-09-07 17:30:07 +02002390
yanbzhu08ce6ab2015-12-02 13:01:29 -05002391 if (stat(path, &buf) == 0) {
2392 dir = opendir(path);
2393 if (!dir)
2394 return ssl_sock_load_cert_file(path, bind_conf, curproxy, NULL, 0, err);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002395
yanbzhu08ce6ab2015-12-02 13:01:29 -05002396 /* strip trailing slashes, including first one */
2397 for (end = path + strlen(path) - 1; end >= path && *end == '/'; end--)
2398 *end = 0;
Emeric Brunfc0421f2012-09-07 17:30:07 +02002399
yanbzhu08ce6ab2015-12-02 13:01:29 -05002400 n = scandir(path, &de_list, 0, alphasort);
2401 if (n < 0) {
2402 memprintf(err, "%sunable to scan directory '%s' : %s.\n",
2403 err && *err ? *err : "", path, strerror(errno));
2404 cfgerr++;
2405 }
2406 else {
2407 for (i = 0; i < n; i++) {
2408 struct dirent *de = de_list[i];
Emeric Brun2aab7222014-06-18 18:15:09 +02002409
yanbzhu08ce6ab2015-12-02 13:01:29 -05002410 end = strrchr(de->d_name, '.');
2411 if (end && (!strcmp(end, ".issuer") || !strcmp(end, ".ocsp") || !strcmp(end, ".sctl")))
2412 goto ignore_entry;
Cyril Bonté3180f7b2015-01-25 00:16:08 +01002413
yanbzhu08ce6ab2015-12-02 13:01:29 -05002414 snprintf(fp, sizeof(fp), "%s/%s", path, de->d_name);
2415 if (stat(fp, &buf) != 0) {
2416 memprintf(err, "%sunable to stat SSL certificate from file '%s' : %s.\n",
2417 err && *err ? *err : "", fp, strerror(errno));
2418 cfgerr++;
2419 goto ignore_entry;
2420 }
2421 if (!S_ISREG(buf.st_mode))
2422 goto ignore_entry;
yanbzhu63ea8462015-12-09 13:35:14 -05002423
2424#if OPENSSL_VERSION_NUMBER >= 0x1000200fL
2425 is_bundle = 0;
2426 /* Check if current entry in directory is part of a multi-cert bundle */
2427
2428 if (end) {
2429 for (j = 0; j < SSL_SOCK_NUM_KEYTYPES; j++) {
2430 if (!strcmp(end + 1, SSL_SOCK_KEYTYPE_NAMES[j])) {
2431 is_bundle = 1;
2432 break;
2433 }
2434 }
2435
2436 if (is_bundle) {
2437 char dp[MAXPATHLEN+1] = {0}; /* this will be the filename w/o the keytype */
2438 int dp_len;
2439
2440 dp_len = end - de->d_name;
2441 snprintf(dp, dp_len + 1, "%s", de->d_name);
2442
2443 /* increment i and free de until we get to a non-bundle cert
2444 * Note here that we look at de_list[i + 1] before freeing de
2445 * this is important since ignore_entry will free de
2446 */
2447 while (i + 1 < n && !strncmp(de_list[i + 1]->d_name, dp, dp_len)) {
2448 free(de);
2449 i++;
2450 de = de_list[i];
2451 }
2452
2453 snprintf(fp, sizeof(fp), "%s/%s", path, dp);
Emmanuel Hocdetd294aea2016-05-13 11:14:06 +02002454 ssl_sock_load_multi_cert(fp, bind_conf, curproxy, NULL, 0, err);
yanbzhu63ea8462015-12-09 13:35:14 -05002455
2456 /* Successfully processed the bundle */
2457 goto ignore_entry;
2458 }
2459 }
2460
2461#endif
yanbzhu08ce6ab2015-12-02 13:01:29 -05002462 cfgerr += ssl_sock_load_cert_file(fp, bind_conf, curproxy, NULL, 0, err);
2463ignore_entry:
2464 free(de);
Cyril Bonté3180f7b2015-01-25 00:16:08 +01002465 }
yanbzhu08ce6ab2015-12-02 13:01:29 -05002466 free(de_list);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002467 }
yanbzhu08ce6ab2015-12-02 13:01:29 -05002468 closedir(dir);
2469 return cfgerr;
Emeric Brunfc0421f2012-09-07 17:30:07 +02002470 }
yanbzhu08ce6ab2015-12-02 13:01:29 -05002471
Emmanuel Hocdetd294aea2016-05-13 11:14:06 +02002472 cfgerr = ssl_sock_load_multi_cert(path, bind_conf, curproxy, NULL, 0, err);
yanbzhu08ce6ab2015-12-02 13:01:29 -05002473
Emeric Brunfc0421f2012-09-07 17:30:07 +02002474 return cfgerr;
2475}
2476
Thierry Fournier383085f2013-01-24 14:15:43 +01002477/* Make sure openssl opens /dev/urandom before the chroot. The work is only
2478 * done once. Zero is returned if the operation fails. No error is returned
2479 * if the random is said as not implemented, because we expect that openssl
2480 * will use another method once needed.
2481 */
2482static int ssl_initialize_random()
2483{
2484 unsigned char random;
2485 static int random_initialized = 0;
2486
2487 if (!random_initialized && RAND_bytes(&random, 1) != 0)
2488 random_initialized = 1;
2489
2490 return random_initialized;
2491}
2492
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002493int ssl_sock_load_cert_list_file(char *file, struct bind_conf *bind_conf, struct proxy *curproxy, char **err)
2494{
Emmanuel Hocdet5e0e6e42016-05-13 11:18:50 +02002495 char thisline[LINESIZE*CRTLIST_FACTOR];
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002496 FILE *f;
yanbzhu1b04e5b2015-12-02 13:54:14 -05002497 struct stat buf;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002498 int linenum = 0;
2499 int cfgerr = 0;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002500
Willy Tarreauad1731d2013-04-02 17:35:58 +02002501 if ((f = fopen(file, "r")) == NULL) {
2502 memprintf(err, "cannot open file '%s' : %s", file, strerror(errno));
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002503 return 1;
Willy Tarreauad1731d2013-04-02 17:35:58 +02002504 }
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002505
2506 while (fgets(thisline, sizeof(thisline), f) != NULL) {
2507 int arg;
Emeric Brun50bcecc2013-04-22 13:05:23 +02002508 int newarg;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002509 char *end;
Emmanuel Hocdet5e0e6e42016-05-13 11:18:50 +02002510 char *args[MAX_LINE_ARGS*CRTLIST_FACTOR + 1];
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002511 char *line = thisline;
2512
2513 linenum++;
2514 end = line + strlen(line);
2515 if (end-line == sizeof(thisline)-1 && *(end-1) != '\n') {
2516 /* Check if we reached the limit and the last char is not \n.
2517 * Watch out for the last line without the terminating '\n'!
2518 */
Willy Tarreauad1731d2013-04-02 17:35:58 +02002519 memprintf(err, "line %d too long in file '%s', limit is %d characters",
2520 linenum, file, (int)sizeof(thisline)-1);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002521 cfgerr = 1;
Willy Tarreauad1731d2013-04-02 17:35:58 +02002522 break;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002523 }
2524
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002525 arg = 0;
Emeric Brun50bcecc2013-04-22 13:05:23 +02002526 newarg = 1;
2527 while (*line) {
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002528 if (*line == '#' || *line == '\n' || *line == '\r') {
2529 /* end of string, end of loop */
2530 *line = 0;
2531 break;
2532 }
2533 else if (isspace(*line)) {
Emeric Brun50bcecc2013-04-22 13:05:23 +02002534 newarg = 1;
2535 *line = 0;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002536 }
Emeric Brun50bcecc2013-04-22 13:05:23 +02002537 else if (newarg) {
Emmanuel Hocdet5e0e6e42016-05-13 11:18:50 +02002538 if (arg == MAX_LINE_ARGS*CRTLIST_FACTOR) {
Emeric Brun50bcecc2013-04-22 13:05:23 +02002539 memprintf(err, "too many args on line %d in file '%s'.",
2540 linenum, file);
2541 cfgerr = 1;
2542 break;
2543 }
2544 newarg = 0;
2545 args[arg++] = line;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002546 }
Emeric Brun50bcecc2013-04-22 13:05:23 +02002547 line++;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002548 }
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02002549 if (cfgerr)
2550 break;
Willy Tarreauad1731d2013-04-02 17:35:58 +02002551
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002552 /* empty line */
Emeric Brun50bcecc2013-04-22 13:05:23 +02002553 if (!arg)
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002554 continue;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002555
yanbzhu1b04e5b2015-12-02 13:54:14 -05002556 if (stat(args[0], &buf) == 0) {
2557 cfgerr = ssl_sock_load_cert_file(args[0], bind_conf, curproxy, &args[1], arg-1, err);
2558 } else {
Emmanuel Hocdetd294aea2016-05-13 11:14:06 +02002559 cfgerr = ssl_sock_load_multi_cert(args[0], bind_conf, curproxy, &args[1], arg-1, err);
yanbzhu1b04e5b2015-12-02 13:54:14 -05002560 }
2561
Willy Tarreauad1731d2013-04-02 17:35:58 +02002562 if (cfgerr) {
2563 memprintf(err, "error processing line %d in file '%s' : %s", linenum, file, *err);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002564 break;
Willy Tarreauad1731d2013-04-02 17:35:58 +02002565 }
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002566 }
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002567 fclose(f);
2568 return cfgerr;
2569}
2570
Emeric Brunfc0421f2012-09-07 17:30:07 +02002571#ifndef SSL_OP_CIPHER_SERVER_PREFERENCE /* needs OpenSSL >= 0.9.7 */
2572#define SSL_OP_CIPHER_SERVER_PREFERENCE 0
2573#endif
2574
2575#ifndef SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION /* needs OpenSSL >= 0.9.7 */
2576#define SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION 0
Willy Tarreau7d588ee2012-11-26 18:47:31 +01002577#define SSL_renegotiate_pending(arg) 0
Emeric Brunfc0421f2012-09-07 17:30:07 +02002578#endif
Emeric Brun2b58d042012-09-20 17:10:03 +02002579#ifndef SSL_OP_SINGLE_ECDH_USE /* needs OpenSSL >= 0.9.8 */
2580#define SSL_OP_SINGLE_ECDH_USE 0
2581#endif
Emeric Brun2d0c4822012-10-02 13:45:20 +02002582#ifndef SSL_OP_NO_TICKET /* needs OpenSSL >= 0.9.8 */
2583#define SSL_OP_NO_TICKET 0
2584#endif
Emeric Brunfc0421f2012-09-07 17:30:07 +02002585#ifndef SSL_OP_NO_COMPRESSION /* needs OpenSSL >= 0.9.9 */
2586#define SSL_OP_NO_COMPRESSION 0
2587#endif
Emeric Brunc0ff4922012-09-28 19:37:02 +02002588#ifndef SSL_OP_NO_TLSv1_1 /* needs OpenSSL >= 1.0.1 */
2589#define SSL_OP_NO_TLSv1_1 0
2590#endif
2591#ifndef SSL_OP_NO_TLSv1_2 /* needs OpenSSL >= 1.0.1 */
2592#define SSL_OP_NO_TLSv1_2 0
2593#endif
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02002594#ifndef SSL_OP_SINGLE_DH_USE /* needs OpenSSL >= 0.9.6 */
2595#define SSL_OP_SINGLE_DH_USE 0
2596#endif
Emeric Brun2b58d042012-09-20 17:10:03 +02002597#ifndef SSL_OP_SINGLE_ECDH_USE /* needs OpenSSL >= 1.0.0 */
2598#define SSL_OP_SINGLE_ECDH_USE 0
2599#endif
Emeric Brunfc0421f2012-09-07 17:30:07 +02002600#ifndef SSL_MODE_RELEASE_BUFFERS /* needs OpenSSL >= 1.0.0 */
2601#define SSL_MODE_RELEASE_BUFFERS 0
2602#endif
Willy Tarreau396a1862014-11-13 14:06:52 +01002603#ifndef SSL_MODE_SMALL_BUFFERS /* needs small_records.patch */
2604#define SSL_MODE_SMALL_BUFFERS 0
2605#endif
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002606
Willy Tarreau2a65ff02012-09-13 17:54:29 +02002607int ssl_sock_prepare_ctx(struct bind_conf *bind_conf, SSL_CTX *ctx, struct proxy *curproxy)
Emeric Brunfc0421f2012-09-07 17:30:07 +02002608{
2609 int cfgerr = 0;
Emeric Brun850efd52014-01-29 12:24:34 +01002610 int verify = SSL_VERIFY_NONE;
Remi Gacogneaf5c3da2014-05-19 10:29:58 +02002611 long ssloptions =
Emeric Brunfc0421f2012-09-07 17:30:07 +02002612 SSL_OP_ALL | /* all known workarounds for bugs */
2613 SSL_OP_NO_SSLv2 |
2614 SSL_OP_NO_COMPRESSION |
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02002615 SSL_OP_SINGLE_DH_USE |
Emeric Brun2b58d042012-09-20 17:10:03 +02002616 SSL_OP_SINGLE_ECDH_USE |
Emeric Brun3c4bc6e2012-10-04 18:44:19 +02002617 SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION |
2618 SSL_OP_CIPHER_SERVER_PREFERENCE;
Remi Gacogneaf5c3da2014-05-19 10:29:58 +02002619 long sslmode =
Emeric Brunfc0421f2012-09-07 17:30:07 +02002620 SSL_MODE_ENABLE_PARTIAL_WRITE |
2621 SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER |
Willy Tarreau396a1862014-11-13 14:06:52 +01002622 SSL_MODE_RELEASE_BUFFERS |
2623 SSL_MODE_SMALL_BUFFERS;
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002624 STACK_OF(SSL_CIPHER) * ciphers = NULL;
Willy Tarreaua616ba62014-10-26 06:49:19 +01002625 SSL_CIPHER * cipher = NULL;
Remi Gacognec1eab8c2014-06-12 18:20:11 +02002626 char cipher_description[128];
2627 /* The description of ciphers using an Ephemeral Diffie Hellman key exchange
2628 contains " Kx=DH " or " Kx=DH(". Beware of " Kx=DH/",
2629 which is not ephemeral DH. */
2630 const char dhe_description[] = " Kx=DH ";
2631 const char dhe_export_description[] = " Kx=DH(";
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002632 int idx = 0;
2633 int dhe_found = 0;
Remi Gacogne23d5d372014-10-10 17:04:26 +02002634 SSL *ssl = NULL;
Emeric Brunfc0421f2012-09-07 17:30:07 +02002635
Thierry Fournier383085f2013-01-24 14:15:43 +01002636 /* Make sure openssl opens /dev/urandom before the chroot */
2637 if (!ssl_initialize_random()) {
2638 Alert("OpenSSL random data generator initialization failed.\n");
2639 cfgerr++;
2640 }
2641
Emeric Brun89675492012-10-05 13:48:26 +02002642 if (bind_conf->ssl_options & BC_SSL_O_NO_SSLV3)
Emeric Brunfc0421f2012-09-07 17:30:07 +02002643 ssloptions |= SSL_OP_NO_SSLv3;
Emeric Brun89675492012-10-05 13:48:26 +02002644 if (bind_conf->ssl_options & BC_SSL_O_NO_TLSV10)
Emeric Brunfc0421f2012-09-07 17:30:07 +02002645 ssloptions |= SSL_OP_NO_TLSv1;
Emeric Brun89675492012-10-05 13:48:26 +02002646 if (bind_conf->ssl_options & BC_SSL_O_NO_TLSV11)
Emeric Brunc0ff4922012-09-28 19:37:02 +02002647 ssloptions |= SSL_OP_NO_TLSv1_1;
Emeric Brun89675492012-10-05 13:48:26 +02002648 if (bind_conf->ssl_options & BC_SSL_O_NO_TLSV12)
Emeric Brunc0ff4922012-09-28 19:37:02 +02002649 ssloptions |= SSL_OP_NO_TLSv1_2;
Emeric Brun89675492012-10-05 13:48:26 +02002650 if (bind_conf->ssl_options & BC_SSL_O_NO_TLS_TICKETS)
Emeric Brun2d0c4822012-10-02 13:45:20 +02002651 ssloptions |= SSL_OP_NO_TICKET;
Jérémie Courrèges-Anglas17c3f622015-07-25 16:50:52 -06002652 if (bind_conf->ssl_options & BC_SSL_O_USE_SSLV3) {
2653#ifndef OPENSSL_NO_SSL3
Emeric Brun2cb7ae52012-10-05 14:14:21 +02002654 SSL_CTX_set_ssl_version(ctx, SSLv3_server_method());
Jérémie Courrèges-Anglas17c3f622015-07-25 16:50:52 -06002655#else
2656 Alert("SSLv3 support requested but unavailable.\n");
2657 cfgerr++;
2658#endif
2659 }
Emeric Brun2cb7ae52012-10-05 14:14:21 +02002660 if (bind_conf->ssl_options & BC_SSL_O_USE_TLSV10)
2661 SSL_CTX_set_ssl_version(ctx, TLSv1_server_method());
2662#if SSL_OP_NO_TLSv1_1
2663 if (bind_conf->ssl_options & BC_SSL_O_USE_TLSV11)
2664 SSL_CTX_set_ssl_version(ctx, TLSv1_1_server_method());
2665#endif
2666#if SSL_OP_NO_TLSv1_2
2667 if (bind_conf->ssl_options & BC_SSL_O_USE_TLSV12)
2668 SSL_CTX_set_ssl_version(ctx, TLSv1_2_server_method());
2669#endif
Emeric Brunfc0421f2012-09-07 17:30:07 +02002670
2671 SSL_CTX_set_options(ctx, ssloptions);
2672 SSL_CTX_set_mode(ctx, sslmode);
Emeric Brun850efd52014-01-29 12:24:34 +01002673 switch (bind_conf->verify) {
2674 case SSL_SOCK_VERIFY_NONE:
2675 verify = SSL_VERIFY_NONE;
2676 break;
2677 case SSL_SOCK_VERIFY_OPTIONAL:
2678 verify = SSL_VERIFY_PEER;
2679 break;
2680 case SSL_SOCK_VERIFY_REQUIRED:
2681 verify = SSL_VERIFY_PEER|SSL_VERIFY_FAIL_IF_NO_PEER_CERT;
2682 break;
2683 }
2684 SSL_CTX_set_verify(ctx, verify, ssl_sock_bind_verifycbk);
2685 if (verify & SSL_VERIFY_PEER) {
Emeric Brunfb510ea2012-10-05 12:00:26 +02002686 if (bind_conf->ca_file) {
Emeric Brund94b3fe2012-09-20 18:23:56 +02002687 /* load CAfile to verify */
Emeric Brunfb510ea2012-10-05 12:00:26 +02002688 if (!SSL_CTX_load_verify_locations(ctx, bind_conf->ca_file, NULL)) {
Emeric Brund94b3fe2012-09-20 18:23:56 +02002689 Alert("Proxy '%s': unable to load CA file '%s' for bind '%s' at [%s:%d].\n",
Emeric Brunfb510ea2012-10-05 12:00:26 +02002690 curproxy->id, bind_conf->ca_file, bind_conf->arg, bind_conf->file, bind_conf->line);
Emeric Brund94b3fe2012-09-20 18:23:56 +02002691 cfgerr++;
2692 }
2693 /* set CA names fo client cert request, function returns void */
Emeric Brunfb510ea2012-10-05 12:00:26 +02002694 SSL_CTX_set_client_CA_list(ctx, SSL_load_client_CA_file(bind_conf->ca_file));
Emeric Brund94b3fe2012-09-20 18:23:56 +02002695 }
Emeric Brun850efd52014-01-29 12:24:34 +01002696 else {
2697 Alert("Proxy '%s': verify is enabled but no CA file specified for bind '%s' at [%s:%d].\n",
2698 curproxy->id, bind_conf->arg, bind_conf->file, bind_conf->line);
2699 cfgerr++;
2700 }
Emeric Brun051cdab2012-10-02 19:25:50 +02002701#ifdef X509_V_FLAG_CRL_CHECK
Emeric Brunfb510ea2012-10-05 12:00:26 +02002702 if (bind_conf->crl_file) {
Emeric Brund94b3fe2012-09-20 18:23:56 +02002703 X509_STORE *store = SSL_CTX_get_cert_store(ctx);
2704
Emeric Brunfb510ea2012-10-05 12:00:26 +02002705 if (!store || !X509_STORE_load_locations(store, bind_conf->crl_file, NULL)) {
Emeric Brund94b3fe2012-09-20 18:23:56 +02002706 Alert("Proxy '%s': unable to configure CRL file '%s' for bind '%s' at [%s:%d].\n",
Alexander Rigbofc65af02015-04-07 14:02:16 +02002707 curproxy->id, bind_conf->crl_file, bind_conf->arg, bind_conf->file, bind_conf->line);
Emeric Brund94b3fe2012-09-20 18:23:56 +02002708 cfgerr++;
2709 }
Emeric Brun561e5742012-10-02 15:20:55 +02002710 else {
2711 X509_STORE_set_flags(store, X509_V_FLAG_CRL_CHECK|X509_V_FLAG_CRL_CHECK_ALL);
2712 }
Emeric Brund94b3fe2012-09-20 18:23:56 +02002713 }
Emeric Brun051cdab2012-10-02 19:25:50 +02002714#endif
Emeric Brun644cde02012-12-14 11:21:13 +01002715 ERR_clear_error();
Emeric Brund94b3fe2012-09-20 18:23:56 +02002716 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02002717
Nenad Merdanovic05552d42015-02-27 19:56:49 +01002718#if (defined SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB && TLS_TICKETS_NO > 0)
Nenad Merdanovic146defa2015-05-09 08:46:00 +02002719 if(bind_conf->keys_ref) {
Nenad Merdanovic05552d42015-02-27 19:56:49 +01002720 if (!SSL_CTX_set_tlsext_ticket_key_cb(ctx, ssl_tlsext_ticket_key_cb)) {
2721 Alert("Proxy '%s': unable to set callback for TLS ticket validation for bind '%s' at [%s:%d].\n",
2722 curproxy->id, bind_conf->arg, bind_conf->file, bind_conf->line);
2723 cfgerr++;
2724 }
2725 }
2726#endif
2727
Emeric Brun4f65bff2012-11-16 15:11:00 +01002728 if (global.tune.ssllifetime)
2729 SSL_CTX_set_timeout(ctx, global.tune.ssllifetime);
2730
Emeric Brunfc0421f2012-09-07 17:30:07 +02002731 shared_context_set_cache(ctx);
Willy Tarreau2a65ff02012-09-13 17:54:29 +02002732 if (bind_conf->ciphers &&
2733 !SSL_CTX_set_cipher_list(ctx, bind_conf->ciphers)) {
Emeric Brunfc0421f2012-09-07 17:30:07 +02002734 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 +02002735 curproxy->id, bind_conf->ciphers, bind_conf->arg, bind_conf->file, bind_conf->line);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002736 cfgerr++;
2737 }
2738
Remi Gacogne47783ef2015-05-29 15:53:22 +02002739 /* If tune.ssl.default-dh-param has not been set,
2740 neither has ssl-default-dh-file and no static DH
2741 params were in the certificate file. */
Remi Gacogne4f902b82015-05-28 16:23:00 +02002742 if (global.tune.ssl_default_dh_param == 0 &&
Remi Gacogne47783ef2015-05-29 15:53:22 +02002743 global_dh == NULL &&
Remi Gacogne4f902b82015-05-28 16:23:00 +02002744 (ssl_dh_ptr_index == -1 ||
2745 SSL_CTX_get_ex_data(ctx, ssl_dh_ptr_index) == NULL)) {
Lukas Tribus90132722014-08-18 00:56:33 +02002746
Remi Gacogne23d5d372014-10-10 17:04:26 +02002747 ssl = SSL_new(ctx);
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002748
Remi Gacogne23d5d372014-10-10 17:04:26 +02002749 if (ssl) {
2750 ciphers = SSL_get_ciphers(ssl);
2751
2752 if (ciphers) {
2753 for (idx = 0; idx < sk_SSL_CIPHER_num(ciphers); idx++) {
2754 cipher = sk_SSL_CIPHER_value(ciphers, idx);
2755 if (SSL_CIPHER_description(cipher, cipher_description, sizeof (cipher_description)) == cipher_description) {
2756 if (strstr(cipher_description, dhe_description) != NULL ||
2757 strstr(cipher_description, dhe_export_description) != NULL) {
2758 dhe_found = 1;
2759 break;
2760 }
Remi Gacognec1eab8c2014-06-12 18:20:11 +02002761 }
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002762 }
2763 }
Remi Gacogne23d5d372014-10-10 17:04:26 +02002764 SSL_free(ssl);
2765 ssl = NULL;
Lukas Tribus90132722014-08-18 00:56:33 +02002766 }
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002767
Lukas Tribus90132722014-08-18 00:56:33 +02002768 if (dhe_found) {
2769 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 +02002770 }
2771
2772 global.tune.ssl_default_dh_param = 1024;
2773 }
Remi Gacogne8de54152014-07-15 11:36:40 +02002774
2775#ifndef OPENSSL_NO_DH
2776 if (global.tune.ssl_default_dh_param >= 1024) {
2777 if (local_dh_1024 == NULL) {
2778 local_dh_1024 = ssl_get_dh_1024();
2779 }
2780 if (global.tune.ssl_default_dh_param >= 2048) {
2781 if (local_dh_2048 == NULL) {
2782 local_dh_2048 = ssl_get_dh_2048();
2783 }
2784 if (global.tune.ssl_default_dh_param >= 4096) {
2785 if (local_dh_4096 == NULL) {
2786 local_dh_4096 = ssl_get_dh_4096();
2787 }
Remi Gacogne8de54152014-07-15 11:36:40 +02002788 }
2789 }
2790 }
2791#endif /* OPENSSL_NO_DH */
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002792
Emeric Brunfc0421f2012-09-07 17:30:07 +02002793 SSL_CTX_set_info_callback(ctx, ssl_sock_infocbk);
Willy Tarreau5cbe4ef2014-05-08 22:45:11 +02002794#if OPENSSL_VERSION_NUMBER >= 0x00907000L
Emeric Brun29f037d2014-04-25 19:05:36 +02002795 SSL_CTX_set_msg_callback(ctx, ssl_sock_msgcbk);
Willy Tarreau5cbe4ef2014-05-08 22:45:11 +02002796#endif
Emeric Brun29f037d2014-04-25 19:05:36 +02002797
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02002798#ifdef OPENSSL_NPN_NEGOTIATED
2799 if (bind_conf->npn_str)
2800 SSL_CTX_set_next_protos_advertised_cb(ctx, ssl_sock_advertise_npn_protos, bind_conf);
2801#endif
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01002802#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Willy Tarreauab861d32013-04-02 02:30:41 +02002803 if (bind_conf->alpn_str)
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01002804 SSL_CTX_set_alpn_select_cb(ctx, ssl_sock_advertise_alpn_protos, bind_conf);
Willy Tarreauab861d32013-04-02 02:30:41 +02002805#endif
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02002806
Emeric Brunfc0421f2012-09-07 17:30:07 +02002807#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
2808 SSL_CTX_set_tlsext_servername_callback(ctx, ssl_sock_switchctx_cbk);
Willy Tarreau2a65ff02012-09-13 17:54:29 +02002809 SSL_CTX_set_tlsext_servername_arg(ctx, bind_conf);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002810#endif
Emeric Brun2b58d042012-09-20 17:10:03 +02002811#if defined(SSL_CTX_set_tmp_ecdh) && !defined(OPENSSL_NO_ECDH)
Emeric Brun6924ef82013-03-06 14:08:53 +01002812 {
Emeric Brun2b58d042012-09-20 17:10:03 +02002813 int i;
2814 EC_KEY *ecdh;
2815
Emeric Brun6924ef82013-03-06 14:08:53 +01002816 i = OBJ_sn2nid(bind_conf->ecdhe ? bind_conf->ecdhe : ECDHE_DEFAULT_CURVE);
Emeric Brun2b58d042012-09-20 17:10:03 +02002817 if (!i || ((ecdh = EC_KEY_new_by_curve_name(i)) == NULL)) {
2818 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 +01002819 curproxy->id, bind_conf->ecdhe ? bind_conf->ecdhe : ECDHE_DEFAULT_CURVE,
2820 bind_conf->arg, bind_conf->file, bind_conf->line);
Emeric Brun2b58d042012-09-20 17:10:03 +02002821 cfgerr++;
2822 }
2823 else {
2824 SSL_CTX_set_tmp_ecdh(ctx, ecdh);
2825 EC_KEY_free(ecdh);
2826 }
2827 }
2828#endif
2829
Emeric Brunfc0421f2012-09-07 17:30:07 +02002830 return cfgerr;
2831}
2832
Evan Broderbe554312013-06-27 00:05:25 -07002833static int ssl_sock_srv_hostcheck(const char *pattern, const char *hostname)
2834{
2835 const char *pattern_wildcard, *pattern_left_label_end, *hostname_left_label_end;
2836 size_t prefixlen, suffixlen;
2837
2838 /* Trivial case */
2839 if (strcmp(pattern, hostname) == 0)
2840 return 1;
2841
Evan Broderbe554312013-06-27 00:05:25 -07002842 /* The rest of this logic is based on RFC 6125, section 6.4.3
2843 * (http://tools.ietf.org/html/rfc6125#section-6.4.3) */
2844
Emeric Bruna848dae2013-10-08 11:27:28 +02002845 pattern_wildcard = NULL;
2846 pattern_left_label_end = pattern;
2847 while (*pattern_left_label_end != '.') {
2848 switch (*pattern_left_label_end) {
2849 case 0:
2850 /* End of label not found */
2851 return 0;
2852 case '*':
2853 /* If there is more than one wildcards */
2854 if (pattern_wildcard)
2855 return 0;
2856 pattern_wildcard = pattern_left_label_end;
2857 break;
2858 }
2859 pattern_left_label_end++;
2860 }
2861
2862 /* If it's not trivial and there is no wildcard, it can't
2863 * match */
2864 if (!pattern_wildcard)
Evan Broderbe554312013-06-27 00:05:25 -07002865 return 0;
2866
2867 /* Make sure all labels match except the leftmost */
2868 hostname_left_label_end = strchr(hostname, '.');
2869 if (!hostname_left_label_end
2870 || strcmp(pattern_left_label_end, hostname_left_label_end) != 0)
2871 return 0;
2872
2873 /* Make sure the leftmost label of the hostname is long enough
2874 * that the wildcard can match */
Emeric Brun369da852013-10-08 11:39:35 +02002875 if (hostname_left_label_end - hostname < (pattern_left_label_end - pattern) - 1)
Evan Broderbe554312013-06-27 00:05:25 -07002876 return 0;
2877
2878 /* Finally compare the string on either side of the
2879 * wildcard */
2880 prefixlen = pattern_wildcard - pattern;
2881 suffixlen = pattern_left_label_end - (pattern_wildcard + 1);
Emeric Bruna848dae2013-10-08 11:27:28 +02002882 if ((prefixlen && (memcmp(pattern, hostname, prefixlen) != 0))
2883 || (suffixlen && (memcmp(pattern_wildcard + 1, hostname_left_label_end - suffixlen, suffixlen) != 0)))
Evan Broderbe554312013-06-27 00:05:25 -07002884 return 0;
2885
2886 return 1;
2887}
2888
2889static int ssl_sock_srv_verifycbk(int ok, X509_STORE_CTX *ctx)
2890{
2891 SSL *ssl;
2892 struct connection *conn;
2893 char *servername;
2894
2895 int depth;
2896 X509 *cert;
2897 STACK_OF(GENERAL_NAME) *alt_names;
2898 int i;
2899 X509_NAME *cert_subject;
2900 char *str;
2901
2902 if (ok == 0)
2903 return ok;
2904
2905 ssl = X509_STORE_CTX_get_ex_data(ctx, SSL_get_ex_data_X509_STORE_CTX_idx());
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02002906 conn = SSL_get_app_data(ssl);
Evan Broderbe554312013-06-27 00:05:25 -07002907
2908 servername = objt_server(conn->target)->ssl_ctx.verify_host;
2909
2910 /* We only need to verify the CN on the actual server cert,
2911 * not the indirect CAs */
2912 depth = X509_STORE_CTX_get_error_depth(ctx);
2913 if (depth != 0)
2914 return ok;
2915
2916 /* At this point, the cert is *not* OK unless we can find a
2917 * hostname match */
2918 ok = 0;
2919
2920 cert = X509_STORE_CTX_get_current_cert(ctx);
2921 /* It seems like this might happen if verify peer isn't set */
2922 if (!cert)
2923 return ok;
2924
2925 alt_names = X509_get_ext_d2i(cert, NID_subject_alt_name, NULL, NULL);
2926 if (alt_names) {
2927 for (i = 0; !ok && i < sk_GENERAL_NAME_num(alt_names); i++) {
2928 GENERAL_NAME *name = sk_GENERAL_NAME_value(alt_names, i);
2929 if (name->type == GEN_DNS) {
Emeric Bruna33410c2013-09-17 15:47:48 +02002930#if OPENSSL_VERSION_NUMBER < 0x00907000L
2931 if (ASN1_STRING_to_UTF8((unsigned char **)&str, name->d.ia5) >= 0) {
2932#else
Evan Broderbe554312013-06-27 00:05:25 -07002933 if (ASN1_STRING_to_UTF8((unsigned char **)&str, name->d.dNSName) >= 0) {
Emeric Bruna33410c2013-09-17 15:47:48 +02002934#endif
Evan Broderbe554312013-06-27 00:05:25 -07002935 ok = ssl_sock_srv_hostcheck(str, servername);
2936 OPENSSL_free(str);
2937 }
2938 }
2939 }
Emeric Brun4ad50a42013-09-17 15:19:54 +02002940 sk_GENERAL_NAME_pop_free(alt_names, GENERAL_NAME_free);
Evan Broderbe554312013-06-27 00:05:25 -07002941 }
2942
2943 cert_subject = X509_get_subject_name(cert);
2944 i = -1;
2945 while (!ok && (i = X509_NAME_get_index_by_NID(cert_subject, NID_commonName, i)) != -1) {
2946 X509_NAME_ENTRY *entry = X509_NAME_get_entry(cert_subject, i);
2947 if (ASN1_STRING_to_UTF8((unsigned char **)&str, entry->value) >= 0) {
2948 ok = ssl_sock_srv_hostcheck(str, servername);
2949 OPENSSL_free(str);
2950 }
2951 }
2952
2953 return ok;
2954}
2955
Emeric Brun94324a42012-10-11 14:00:19 +02002956/* prepare ssl context from servers options. Returns an error count */
2957int ssl_sock_prepare_srv_ctx(struct server *srv, struct proxy *curproxy)
2958{
2959 int cfgerr = 0;
Remi Gacogneaf5c3da2014-05-19 10:29:58 +02002960 long options =
Emeric Brun94324a42012-10-11 14:00:19 +02002961 SSL_OP_ALL | /* all known workarounds for bugs */
2962 SSL_OP_NO_SSLv2 |
2963 SSL_OP_NO_COMPRESSION;
Remi Gacogneaf5c3da2014-05-19 10:29:58 +02002964 long mode =
Emeric Brun94324a42012-10-11 14:00:19 +02002965 SSL_MODE_ENABLE_PARTIAL_WRITE |
2966 SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER |
Willy Tarreau396a1862014-11-13 14:06:52 +01002967 SSL_MODE_RELEASE_BUFFERS |
2968 SSL_MODE_SMALL_BUFFERS;
Emeric Brun850efd52014-01-29 12:24:34 +01002969 int verify = SSL_VERIFY_NONE;
Emeric Brun94324a42012-10-11 14:00:19 +02002970
Thierry Fournier383085f2013-01-24 14:15:43 +01002971 /* Make sure openssl opens /dev/urandom before the chroot */
2972 if (!ssl_initialize_random()) {
2973 Alert("OpenSSL random data generator initialization failed.\n");
2974 cfgerr++;
2975 }
2976
Willy Tarreaufce03112015-01-15 21:32:40 +01002977 /* Automatic memory computations need to know we use SSL there */
2978 global.ssl_used_backend = 1;
2979
2980 /* Initiate SSL context for current server */
Emeric Brun94324a42012-10-11 14:00:19 +02002981 srv->ssl_ctx.reused_sess = NULL;
2982 if (srv->use_ssl)
2983 srv->xprt = &ssl_sock;
2984 if (srv->check.use_ssl)
Cyril Bonté9ce13112014-11-15 22:41:27 +01002985 srv->check.xprt = &ssl_sock;
Emeric Brun94324a42012-10-11 14:00:19 +02002986
2987 srv->ssl_ctx.ctx = SSL_CTX_new(SSLv23_client_method());
2988 if (!srv->ssl_ctx.ctx) {
2989 Alert("config : %s '%s', server '%s': unable to allocate ssl context.\n",
2990 proxy_type_str(curproxy), curproxy->id,
2991 srv->id);
2992 cfgerr++;
2993 return cfgerr;
2994 }
Emeric Bruna7aa3092012-10-26 12:58:00 +02002995 if (srv->ssl_ctx.client_crt) {
2996 if (SSL_CTX_use_PrivateKey_file(srv->ssl_ctx.ctx, srv->ssl_ctx.client_crt, SSL_FILETYPE_PEM) <= 0) {
2997 Alert("config : %s '%s', server '%s': unable to load SSL private key from PEM file '%s'.\n",
2998 proxy_type_str(curproxy), curproxy->id,
2999 srv->id, srv->ssl_ctx.client_crt);
3000 cfgerr++;
3001 }
3002 else if (SSL_CTX_use_certificate_chain_file(srv->ssl_ctx.ctx, srv->ssl_ctx.client_crt) <= 0) {
3003 Alert("config : %s '%s', server '%s': unable to load ssl certificate from PEM file '%s'.\n",
3004 proxy_type_str(curproxy), curproxy->id,
3005 srv->id, srv->ssl_ctx.client_crt);
3006 cfgerr++;
3007 }
3008 else if (SSL_CTX_check_private_key(srv->ssl_ctx.ctx) <= 0) {
3009 Alert("config : %s '%s', server '%s': inconsistencies between private key and certificate loaded from PEM file '%s'.\n",
3010 proxy_type_str(curproxy), curproxy->id,
3011 srv->id, srv->ssl_ctx.client_crt);
3012 cfgerr++;
3013 }
3014 }
Emeric Brun94324a42012-10-11 14:00:19 +02003015
3016 if (srv->ssl_ctx.options & SRV_SSL_O_NO_SSLV3)
3017 options |= SSL_OP_NO_SSLv3;
3018 if (srv->ssl_ctx.options & SRV_SSL_O_NO_TLSV10)
3019 options |= SSL_OP_NO_TLSv1;
3020 if (srv->ssl_ctx.options & SRV_SSL_O_NO_TLSV11)
3021 options |= SSL_OP_NO_TLSv1_1;
3022 if (srv->ssl_ctx.options & SRV_SSL_O_NO_TLSV12)
3023 options |= SSL_OP_NO_TLSv1_2;
Emeric Brunf9c5c472012-10-11 15:28:34 +02003024 if (srv->ssl_ctx.options & SRV_SSL_O_NO_TLS_TICKETS)
3025 options |= SSL_OP_NO_TICKET;
Jérémie Courrèges-Anglas17c3f622015-07-25 16:50:52 -06003026 if (srv->ssl_ctx.options & SRV_SSL_O_USE_SSLV3) {
3027#ifndef OPENSSL_NO_SSL3
Emeric Brun94324a42012-10-11 14:00:19 +02003028 SSL_CTX_set_ssl_version(srv->ssl_ctx.ctx, SSLv3_client_method());
Jérémie Courrèges-Anglas17c3f622015-07-25 16:50:52 -06003029#else
Thierry FOURNIERbc965342015-08-26 08:21:26 +02003030 Alert("SSLv3 support requested but unavailable.\n");
Jérémie Courrèges-Anglas17c3f622015-07-25 16:50:52 -06003031 cfgerr++;
3032#endif
3033 }
Emeric Brun94324a42012-10-11 14:00:19 +02003034 if (srv->ssl_ctx.options & SRV_SSL_O_USE_TLSV10)
3035 SSL_CTX_set_ssl_version(srv->ssl_ctx.ctx, TLSv1_client_method());
3036#if SSL_OP_NO_TLSv1_1
3037 if (srv->ssl_ctx.options & SRV_SSL_O_USE_TLSV11)
3038 SSL_CTX_set_ssl_version(srv->ssl_ctx.ctx, TLSv1_1_client_method());
3039#endif
3040#if SSL_OP_NO_TLSv1_2
3041 if (srv->ssl_ctx.options & SRV_SSL_O_USE_TLSV12)
3042 SSL_CTX_set_ssl_version(srv->ssl_ctx.ctx, TLSv1_2_client_method());
3043#endif
3044
3045 SSL_CTX_set_options(srv->ssl_ctx.ctx, options);
3046 SSL_CTX_set_mode(srv->ssl_ctx.ctx, mode);
Emeric Brun850efd52014-01-29 12:24:34 +01003047
3048 if (global.ssl_server_verify == SSL_SERVER_VERIFY_REQUIRED)
3049 verify = SSL_VERIFY_PEER;
3050
3051 switch (srv->ssl_ctx.verify) {
3052 case SSL_SOCK_VERIFY_NONE:
3053 verify = SSL_VERIFY_NONE;
3054 break;
3055 case SSL_SOCK_VERIFY_REQUIRED:
3056 verify = SSL_VERIFY_PEER;
3057 break;
3058 }
Evan Broderbe554312013-06-27 00:05:25 -07003059 SSL_CTX_set_verify(srv->ssl_ctx.ctx,
Emeric Brun850efd52014-01-29 12:24:34 +01003060 verify,
Evan Broderbe554312013-06-27 00:05:25 -07003061 srv->ssl_ctx.verify_host ? ssl_sock_srv_verifycbk : NULL);
Emeric Brun850efd52014-01-29 12:24:34 +01003062 if (verify & SSL_VERIFY_PEER) {
Emeric Brunef42d922012-10-11 16:11:36 +02003063 if (srv->ssl_ctx.ca_file) {
3064 /* load CAfile to verify */
3065 if (!SSL_CTX_load_verify_locations(srv->ssl_ctx.ctx, srv->ssl_ctx.ca_file, NULL)) {
Willy Tarreau07ba08b2014-02-16 19:22:08 +01003066 Alert("Proxy '%s', server '%s' [%s:%d] unable to load CA file '%s'.\n",
Emeric Brunef42d922012-10-11 16:11:36 +02003067 curproxy->id, srv->id,
3068 srv->conf.file, srv->conf.line, srv->ssl_ctx.ca_file);
3069 cfgerr++;
3070 }
3071 }
Emeric Brun850efd52014-01-29 12:24:34 +01003072 else {
3073 if (global.ssl_server_verify == SSL_SERVER_VERIFY_REQUIRED)
Willy Tarreau07ba08b2014-02-16 19:22:08 +01003074 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 +01003075 curproxy->id, srv->id,
3076 srv->conf.file, srv->conf.line);
3077 else
Willy Tarreau07ba08b2014-02-16 19:22:08 +01003078 Alert("Proxy '%s', server '%s' [%s:%d] verify is enabled but no CA file specified.\n",
Emeric Brun850efd52014-01-29 12:24:34 +01003079 curproxy->id, srv->id,
3080 srv->conf.file, srv->conf.line);
3081 cfgerr++;
3082 }
Emeric Brunef42d922012-10-11 16:11:36 +02003083#ifdef X509_V_FLAG_CRL_CHECK
3084 if (srv->ssl_ctx.crl_file) {
3085 X509_STORE *store = SSL_CTX_get_cert_store(srv->ssl_ctx.ctx);
3086
3087 if (!store || !X509_STORE_load_locations(store, srv->ssl_ctx.crl_file, NULL)) {
Willy Tarreau07ba08b2014-02-16 19:22:08 +01003088 Alert("Proxy '%s', server '%s' [%s:%d] unable to configure CRL file '%s'.\n",
Emeric Brunef42d922012-10-11 16:11:36 +02003089 curproxy->id, srv->id,
3090 srv->conf.file, srv->conf.line, srv->ssl_ctx.crl_file);
3091 cfgerr++;
3092 }
3093 else {
3094 X509_STORE_set_flags(store, X509_V_FLAG_CRL_CHECK|X509_V_FLAG_CRL_CHECK_ALL);
3095 }
3096 }
3097#endif
3098 }
3099
Emeric Brun4f65bff2012-11-16 15:11:00 +01003100 if (global.tune.ssllifetime)
3101 SSL_CTX_set_timeout(srv->ssl_ctx.ctx, global.tune.ssllifetime);
3102
Emeric Brun94324a42012-10-11 14:00:19 +02003103 SSL_CTX_set_session_cache_mode(srv->ssl_ctx.ctx, SSL_SESS_CACHE_OFF);
3104 if (srv->ssl_ctx.ciphers &&
3105 !SSL_CTX_set_cipher_list(srv->ssl_ctx.ctx, srv->ssl_ctx.ciphers)) {
3106 Alert("Proxy '%s', server '%s' [%s:%d] : unable to set SSL cipher list to '%s'.\n",
3107 curproxy->id, srv->id,
3108 srv->conf.file, srv->conf.line, srv->ssl_ctx.ciphers);
3109 cfgerr++;
3110 }
3111
3112 return cfgerr;
3113}
3114
Willy Tarreau2a65ff02012-09-13 17:54:29 +02003115/* Walks down the two trees in bind_conf and prepares all certs. The pointer may
Emeric Brunfc0421f2012-09-07 17:30:07 +02003116 * be NULL, in which case nothing is done. Returns the number of errors
3117 * encountered.
3118 */
Willy Tarreau2a65ff02012-09-13 17:54:29 +02003119int ssl_sock_prepare_all_ctx(struct bind_conf *bind_conf, struct proxy *px)
Emeric Brunfc0421f2012-09-07 17:30:07 +02003120{
3121 struct ebmb_node *node;
3122 struct sni_ctx *sni;
3123 int err = 0;
3124
Willy Tarreau2a65ff02012-09-13 17:54:29 +02003125 if (!bind_conf || !bind_conf->is_ssl)
Emeric Brunfc0421f2012-09-07 17:30:07 +02003126 return 0;
3127
Willy Tarreaufce03112015-01-15 21:32:40 +01003128 /* Automatic memory computations need to know we use SSL there */
3129 global.ssl_used_frontend = 1;
3130
Emeric Brun0bed9942014-10-30 19:25:24 +01003131 if (bind_conf->default_ctx)
3132 err += ssl_sock_prepare_ctx(bind_conf, bind_conf->default_ctx, px);
3133
Willy Tarreau2a65ff02012-09-13 17:54:29 +02003134 node = ebmb_first(&bind_conf->sni_ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02003135 while (node) {
3136 sni = ebmb_entry(node, struct sni_ctx, name);
Emeric Brun0bed9942014-10-30 19:25:24 +01003137 if (!sni->order && sni->ctx != bind_conf->default_ctx)
3138 /* only initialize the CTX on its first occurrence and
3139 if it is not the default_ctx */
Willy Tarreau2a65ff02012-09-13 17:54:29 +02003140 err += ssl_sock_prepare_ctx(bind_conf, sni->ctx, px);
Emeric Brunfc0421f2012-09-07 17:30:07 +02003141 node = ebmb_next(node);
3142 }
3143
Willy Tarreau2a65ff02012-09-13 17:54:29 +02003144 node = ebmb_first(&bind_conf->sni_w_ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02003145 while (node) {
3146 sni = ebmb_entry(node, struct sni_ctx, name);
Emeric Brun0bed9942014-10-30 19:25:24 +01003147 if (!sni->order && sni->ctx != bind_conf->default_ctx)
3148 /* only initialize the CTX on its first occurrence and
3149 if it is not the default_ctx */
Willy Tarreau2a65ff02012-09-13 17:54:29 +02003150 err += ssl_sock_prepare_ctx(bind_conf, sni->ctx, px);
Emeric Brunfc0421f2012-09-07 17:30:07 +02003151 node = ebmb_next(node);
3152 }
3153 return err;
3154}
3155
Christopher Faulet77fe80c2015-07-29 13:02:40 +02003156
3157/* release ssl context allocated for servers. */
3158void ssl_sock_free_srv_ctx(struct server *srv)
3159{
3160 if (srv->ssl_ctx.ctx)
3161 SSL_CTX_free(srv->ssl_ctx.ctx);
3162}
3163
Willy Tarreau2a65ff02012-09-13 17:54:29 +02003164/* Walks down the two trees in bind_conf and frees all the certs. The pointer may
Emeric Brunfc0421f2012-09-07 17:30:07 +02003165 * be NULL, in which case nothing is done. The default_ctx is nullified too.
3166 */
Willy Tarreau2a65ff02012-09-13 17:54:29 +02003167void ssl_sock_free_all_ctx(struct bind_conf *bind_conf)
Emeric Brunfc0421f2012-09-07 17:30:07 +02003168{
3169 struct ebmb_node *node, *back;
3170 struct sni_ctx *sni;
3171
Willy Tarreau2a65ff02012-09-13 17:54:29 +02003172 if (!bind_conf || !bind_conf->is_ssl)
Emeric Brunfc0421f2012-09-07 17:30:07 +02003173 return;
3174
Willy Tarreau2a65ff02012-09-13 17:54:29 +02003175 node = ebmb_first(&bind_conf->sni_ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02003176 while (node) {
3177 sni = ebmb_entry(node, struct sni_ctx, name);
3178 back = ebmb_next(node);
3179 ebmb_delete(node);
3180 if (!sni->order) /* only free the CTX on its first occurrence */
3181 SSL_CTX_free(sni->ctx);
3182 free(sni);
3183 node = back;
3184 }
3185
Willy Tarreau2a65ff02012-09-13 17:54:29 +02003186 node = ebmb_first(&bind_conf->sni_w_ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02003187 while (node) {
3188 sni = ebmb_entry(node, struct sni_ctx, name);
3189 back = ebmb_next(node);
3190 ebmb_delete(node);
3191 if (!sni->order) /* only free the CTX on its first occurrence */
3192 SSL_CTX_free(sni->ctx);
3193 free(sni);
3194 node = back;
3195 }
3196
Willy Tarreau2a65ff02012-09-13 17:54:29 +02003197 bind_conf->default_ctx = NULL;
Emeric Brune1f38db2012-09-03 20:36:47 +02003198}
3199
Christopher Faulet31af49d2015-06-09 17:29:50 +02003200/* Load CA cert file and private key used to generate certificates */
3201int
3202ssl_sock_load_ca(struct bind_conf *bind_conf, struct proxy *px)
3203{
3204 FILE *fp;
3205 X509 *cacert = NULL;
3206 EVP_PKEY *capkey = NULL;
3207 int err = 0;
3208
3209 if (!bind_conf || !bind_conf->generate_certs)
3210 return err;
3211
Willy Tarreaua84c2672015-10-09 12:10:13 +02003212#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Christopher Fauletd2cab922015-07-28 16:03:47 +02003213 if (global.tune.ssl_ctx_cache)
3214 ssl_ctx_lru_tree = lru64_new(global.tune.ssl_ctx_cache);
3215 ssl_ctx_lru_seed = (unsigned int)time(NULL);
Willy Tarreaua84c2672015-10-09 12:10:13 +02003216#endif
Christopher Fauletd2cab922015-07-28 16:03:47 +02003217
Christopher Faulet31af49d2015-06-09 17:29:50 +02003218 if (!bind_conf->ca_sign_file) {
3219 Alert("Proxy '%s': cannot enable certificate generation, "
3220 "no CA certificate File configured at [%s:%d].\n",
3221 px->id, bind_conf->file, bind_conf->line);
Christopher Faulet31af49d2015-06-09 17:29:50 +02003222 goto load_error;
Christopher Fauletc6f02fb2015-10-09 10:53:31 +02003223 }
Christopher Faulet31af49d2015-06-09 17:29:50 +02003224
3225 /* read in the CA certificate */
3226 if (!(fp = fopen(bind_conf->ca_sign_file, "r"))) {
3227 Alert("Proxy '%s': Failed to read CA certificate file '%s' at [%s:%d].\n",
3228 px->id, bind_conf->ca_sign_file, bind_conf->file, bind_conf->line);
Christopher Faulet31af49d2015-06-09 17:29:50 +02003229 goto load_error;
3230 }
3231 if (!(cacert = PEM_read_X509(fp, NULL, NULL, NULL))) {
3232 Alert("Proxy '%s': Failed to read CA certificate file '%s' at [%s:%d].\n",
3233 px->id, bind_conf->ca_sign_file, bind_conf->file, bind_conf->line);
Christopher Fauletc6f02fb2015-10-09 10:53:31 +02003234 goto read_error;
Christopher Faulet31af49d2015-06-09 17:29:50 +02003235 }
Christopher Fauletc6f02fb2015-10-09 10:53:31 +02003236 rewind(fp);
Christopher Faulet31af49d2015-06-09 17:29:50 +02003237 if (!(capkey = PEM_read_PrivateKey(fp, NULL, NULL, bind_conf->ca_sign_pass))) {
3238 Alert("Proxy '%s': Failed to read CA private key file '%s' at [%s:%d].\n",
3239 px->id, bind_conf->ca_sign_file, bind_conf->file, bind_conf->line);
Christopher Fauletc6f02fb2015-10-09 10:53:31 +02003240 goto read_error;
Christopher Faulet31af49d2015-06-09 17:29:50 +02003241 }
Christopher Faulet31af49d2015-06-09 17:29:50 +02003242
Christopher Fauletc6f02fb2015-10-09 10:53:31 +02003243 fclose (fp);
Christopher Faulet31af49d2015-06-09 17:29:50 +02003244 bind_conf->ca_sign_cert = cacert;
3245 bind_conf->ca_sign_pkey = capkey;
3246 return err;
3247
Christopher Fauletc6f02fb2015-10-09 10:53:31 +02003248 read_error:
3249 fclose (fp);
Christopher Faulet31af49d2015-06-09 17:29:50 +02003250 if (capkey) EVP_PKEY_free(capkey);
3251 if (cacert) X509_free(cacert);
Christopher Fauletc6f02fb2015-10-09 10:53:31 +02003252 load_error:
3253 bind_conf->generate_certs = 0;
3254 err++;
Christopher Faulet31af49d2015-06-09 17:29:50 +02003255 return err;
3256}
3257
3258/* Release CA cert and private key used to generate certificated */
3259void
3260ssl_sock_free_ca(struct bind_conf *bind_conf)
3261{
3262 if (!bind_conf)
3263 return;
3264
3265 if (bind_conf->ca_sign_pkey)
3266 EVP_PKEY_free(bind_conf->ca_sign_pkey);
3267 if (bind_conf->ca_sign_cert)
3268 X509_free(bind_conf->ca_sign_cert);
3269}
3270
Emeric Brun46591952012-05-18 15:47:34 +02003271/*
3272 * This function is called if SSL * context is not yet allocated. The function
3273 * is designed to be called before any other data-layer operation and sets the
3274 * handshake flag on the connection. It is safe to call it multiple times.
3275 * It returns 0 on success and -1 in error case.
3276 */
3277static int ssl_sock_init(struct connection *conn)
3278{
3279 /* already initialized */
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02003280 if (conn->xprt_ctx)
Emeric Brun46591952012-05-18 15:47:34 +02003281 return 0;
3282
Willy Tarreau3c728722014-01-23 13:50:42 +01003283 if (!conn_ctrl_ready(conn))
Willy Tarreauf79c8172013-10-21 16:30:56 +02003284 return 0;
3285
Willy Tarreau20879a02012-12-03 16:32:10 +01003286 if (global.maxsslconn && sslconns >= global.maxsslconn) {
3287 conn->err_code = CO_ER_SSL_TOO_MANY;
Willy Tarreau403edff2012-09-06 11:58:37 +02003288 return -1;
Willy Tarreau20879a02012-12-03 16:32:10 +01003289 }
Willy Tarreau403edff2012-09-06 11:58:37 +02003290
Emeric Brun46591952012-05-18 15:47:34 +02003291 /* If it is in client mode initiate SSL session
3292 in connect state otherwise accept state */
Willy Tarreau3fdb3662012-11-12 00:42:33 +01003293 if (objt_server(conn->target)) {
Willy Tarreaufba03cd2014-11-13 13:48:58 +01003294 int may_retry = 1;
3295
3296 retry_connect:
Emeric Brun46591952012-05-18 15:47:34 +02003297 /* Alloc a new SSL session ctx */
Willy Tarreau3fdb3662012-11-12 00:42:33 +01003298 conn->xprt_ctx = SSL_new(objt_server(conn->target)->ssl_ctx.ctx);
Willy Tarreau20879a02012-12-03 16:32:10 +01003299 if (!conn->xprt_ctx) {
Willy Tarreaufba03cd2014-11-13 13:48:58 +01003300 if (may_retry--) {
3301 pool_gc2();
3302 goto retry_connect;
3303 }
Willy Tarreau20879a02012-12-03 16:32:10 +01003304 conn->err_code = CO_ER_SSL_NO_MEM;
Emeric Brun46591952012-05-18 15:47:34 +02003305 return -1;
Willy Tarreau20879a02012-12-03 16:32:10 +01003306 }
Emeric Brun46591952012-05-18 15:47:34 +02003307
Emeric Brun46591952012-05-18 15:47:34 +02003308 /* set fd on SSL session context */
Emeric Brun55476152014-11-12 17:35:37 +01003309 if (!SSL_set_fd(conn->xprt_ctx, conn->t.sock.fd)) {
3310 SSL_free(conn->xprt_ctx);
3311 conn->xprt_ctx = NULL;
Willy Tarreaufba03cd2014-11-13 13:48:58 +01003312 if (may_retry--) {
3313 pool_gc2();
3314 goto retry_connect;
3315 }
Emeric Brun55476152014-11-12 17:35:37 +01003316 conn->err_code = CO_ER_SSL_NO_MEM;
3317 return -1;
3318 }
Emeric Brun46591952012-05-18 15:47:34 +02003319
Evan Broderbe554312013-06-27 00:05:25 -07003320 /* set connection pointer */
Emeric Brun55476152014-11-12 17:35:37 +01003321 if (!SSL_set_app_data(conn->xprt_ctx, conn)) {
3322 SSL_free(conn->xprt_ctx);
3323 conn->xprt_ctx = NULL;
Willy Tarreaufba03cd2014-11-13 13:48:58 +01003324 if (may_retry--) {
3325 pool_gc2();
3326 goto retry_connect;
3327 }
Emeric Brun55476152014-11-12 17:35:37 +01003328 conn->err_code = CO_ER_SSL_NO_MEM;
3329 return -1;
3330 }
3331
3332 SSL_set_connect_state(conn->xprt_ctx);
3333 if (objt_server(conn->target)->ssl_ctx.reused_sess) {
3334 if(!SSL_set_session(conn->xprt_ctx, objt_server(conn->target)->ssl_ctx.reused_sess)) {
3335 SSL_SESSION_free(objt_server(conn->target)->ssl_ctx.reused_sess);
3336 objt_server(conn->target)->ssl_ctx.reused_sess = NULL;
3337 }
3338 }
Evan Broderbe554312013-06-27 00:05:25 -07003339
Emeric Brun46591952012-05-18 15:47:34 +02003340 /* leave init state and start handshake */
Willy Tarreau05737472012-09-04 08:03:39 +02003341 conn->flags |= CO_FL_SSL_WAIT_HS | CO_FL_WAIT_L6_CONN;
Willy Tarreau403edff2012-09-06 11:58:37 +02003342
3343 sslconns++;
Willy Tarreau71b734c2014-01-28 15:19:44 +01003344 totalsslconns++;
Emeric Brun46591952012-05-18 15:47:34 +02003345 return 0;
3346 }
Willy Tarreau3fdb3662012-11-12 00:42:33 +01003347 else if (objt_listener(conn->target)) {
Willy Tarreaufba03cd2014-11-13 13:48:58 +01003348 int may_retry = 1;
3349
3350 retry_accept:
Emeric Brun46591952012-05-18 15:47:34 +02003351 /* Alloc a new SSL session ctx */
Willy Tarreau3fdb3662012-11-12 00:42:33 +01003352 conn->xprt_ctx = SSL_new(objt_listener(conn->target)->bind_conf->default_ctx);
Willy Tarreau20879a02012-12-03 16:32:10 +01003353 if (!conn->xprt_ctx) {
Willy Tarreaufba03cd2014-11-13 13:48:58 +01003354 if (may_retry--) {
3355 pool_gc2();
3356 goto retry_accept;
3357 }
Willy Tarreau20879a02012-12-03 16:32:10 +01003358 conn->err_code = CO_ER_SSL_NO_MEM;
Emeric Brun46591952012-05-18 15:47:34 +02003359 return -1;
Willy Tarreau20879a02012-12-03 16:32:10 +01003360 }
Emeric Brun46591952012-05-18 15:47:34 +02003361
Emeric Brun46591952012-05-18 15:47:34 +02003362 /* set fd on SSL session context */
Emeric Brun55476152014-11-12 17:35:37 +01003363 if (!SSL_set_fd(conn->xprt_ctx, conn->t.sock.fd)) {
3364 SSL_free(conn->xprt_ctx);
3365 conn->xprt_ctx = NULL;
Willy Tarreaufba03cd2014-11-13 13:48:58 +01003366 if (may_retry--) {
3367 pool_gc2();
3368 goto retry_accept;
3369 }
Emeric Brun55476152014-11-12 17:35:37 +01003370 conn->err_code = CO_ER_SSL_NO_MEM;
3371 return -1;
3372 }
Emeric Brun46591952012-05-18 15:47:34 +02003373
Emeric Brune1f38db2012-09-03 20:36:47 +02003374 /* set connection pointer */
Emeric Brun55476152014-11-12 17:35:37 +01003375 if (!SSL_set_app_data(conn->xprt_ctx, conn)) {
3376 SSL_free(conn->xprt_ctx);
3377 conn->xprt_ctx = NULL;
Willy Tarreaufba03cd2014-11-13 13:48:58 +01003378 if (may_retry--) {
3379 pool_gc2();
3380 goto retry_accept;
3381 }
Emeric Brun55476152014-11-12 17:35:37 +01003382 conn->err_code = CO_ER_SSL_NO_MEM;
3383 return -1;
3384 }
3385
3386 SSL_set_accept_state(conn->xprt_ctx);
Emeric Brune1f38db2012-09-03 20:36:47 +02003387
Emeric Brun46591952012-05-18 15:47:34 +02003388 /* leave init state and start handshake */
Willy Tarreau05737472012-09-04 08:03:39 +02003389 conn->flags |= CO_FL_SSL_WAIT_HS | CO_FL_WAIT_L6_CONN;
Willy Tarreau403edff2012-09-06 11:58:37 +02003390
3391 sslconns++;
Willy Tarreau71b734c2014-01-28 15:19:44 +01003392 totalsslconns++;
Emeric Brun46591952012-05-18 15:47:34 +02003393 return 0;
3394 }
3395 /* don't know how to handle such a target */
Willy Tarreau20879a02012-12-03 16:32:10 +01003396 conn->err_code = CO_ER_SSL_NO_TARGET;
Emeric Brun46591952012-05-18 15:47:34 +02003397 return -1;
3398}
3399
3400
3401/* This is the callback which is used when an SSL handshake is pending. It
3402 * updates the FD status if it wants some polling before being called again.
3403 * It returns 0 if it fails in a fatal way or needs to poll to go further,
3404 * otherwise it returns non-zero and removes itself from the connection's
3405 * flags (the bit is provided in <flag> by the caller).
3406 */
3407int ssl_sock_handshake(struct connection *conn, unsigned int flag)
3408{
3409 int ret;
3410
Willy Tarreau3c728722014-01-23 13:50:42 +01003411 if (!conn_ctrl_ready(conn))
Willy Tarreauf79c8172013-10-21 16:30:56 +02003412 return 0;
3413
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02003414 if (!conn->xprt_ctx)
Emeric Brun46591952012-05-18 15:47:34 +02003415 goto out_error;
3416
Emeric Brun674b7432012-11-08 19:21:55 +01003417 /* If we use SSL_do_handshake to process a reneg initiated by
3418 * the remote peer, it sometimes returns SSL_ERROR_SSL.
3419 * Usually SSL_write and SSL_read are used and process implicitly
3420 * the reneg handshake.
3421 * Here we use SSL_peek as a workaround for reneg.
3422 */
3423 if ((conn->flags & CO_FL_CONNECTED) && SSL_renegotiate_pending(conn->xprt_ctx)) {
3424 char c;
3425
3426 ret = SSL_peek(conn->xprt_ctx, &c, 1);
3427 if (ret <= 0) {
3428 /* handshake may have not been completed, let's find why */
3429 ret = SSL_get_error(conn->xprt_ctx, ret);
3430 if (ret == SSL_ERROR_WANT_WRITE) {
3431 /* SSL handshake needs to write, L4 connection may not be ready */
3432 __conn_sock_stop_recv(conn);
Willy Tarreaue1f50c42014-01-22 20:02:06 +01003433 __conn_sock_want_send(conn);
3434 fd_cant_send(conn->t.sock.fd);
Emeric Brun674b7432012-11-08 19:21:55 +01003435 return 0;
3436 }
3437 else if (ret == SSL_ERROR_WANT_READ) {
3438 /* handshake may have been completed but we have
3439 * no more data to read.
3440 */
3441 if (!SSL_renegotiate_pending(conn->xprt_ctx)) {
3442 ret = 1;
3443 goto reneg_ok;
3444 }
3445 /* SSL handshake needs to read, L4 connection is ready */
3446 if (conn->flags & CO_FL_WAIT_L4_CONN)
3447 conn->flags &= ~CO_FL_WAIT_L4_CONN;
3448 __conn_sock_stop_send(conn);
Willy Tarreaue1f50c42014-01-22 20:02:06 +01003449 __conn_sock_want_recv(conn);
3450 fd_cant_recv(conn->t.sock.fd);
Emeric Brun674b7432012-11-08 19:21:55 +01003451 return 0;
3452 }
3453 else if (ret == SSL_ERROR_SYSCALL) {
3454 /* if errno is null, then connection was successfully established */
3455 if (!errno && conn->flags & CO_FL_WAIT_L4_CONN)
3456 conn->flags &= ~CO_FL_WAIT_L4_CONN;
Willy Tarreau20879a02012-12-03 16:32:10 +01003457 if (!conn->err_code) {
Emeric Brun29f037d2014-04-25 19:05:36 +02003458 if (!((SSL *)conn->xprt_ctx)->packet_length) {
3459 if (!errno) {
3460 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
3461 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
3462 else
3463 conn->err_code = CO_ER_SSL_EMPTY;
3464 }
3465 else {
3466 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
3467 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
3468 else
3469 conn->err_code = CO_ER_SSL_ABORT;
3470 }
3471 }
3472 else {
3473 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
3474 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
Willy Tarreau20879a02012-12-03 16:32:10 +01003475 else
Emeric Brun29f037d2014-04-25 19:05:36 +02003476 conn->err_code = CO_ER_SSL_HANDSHAKE;
3477 }
Willy Tarreau20879a02012-12-03 16:32:10 +01003478 }
Emeric Brun674b7432012-11-08 19:21:55 +01003479 goto out_error;
3480 }
3481 else {
3482 /* Fail on all other handshake errors */
3483 /* Note: OpenSSL may leave unread bytes in the socket's
3484 * buffer, causing an RST to be emitted upon close() on
3485 * TCP sockets. We first try to drain possibly pending
3486 * data to avoid this as much as possible.
3487 */
Willy Tarreaud85c4852015-03-13 00:40:28 +01003488 conn_sock_drain(conn);
Willy Tarreau20879a02012-12-03 16:32:10 +01003489 if (!conn->err_code)
Willy Tarreauf51c6982014-04-25 20:02:39 +02003490 conn->err_code = (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT) ?
3491 CO_ER_SSL_KILLED_HB : CO_ER_SSL_HANDSHAKE;
Emeric Brun674b7432012-11-08 19:21:55 +01003492 goto out_error;
3493 }
3494 }
3495 /* read some data: consider handshake completed */
3496 goto reneg_ok;
3497 }
3498
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02003499 ret = SSL_do_handshake(conn->xprt_ctx);
Emeric Brun46591952012-05-18 15:47:34 +02003500 if (ret != 1) {
3501 /* handshake did not complete, let's find why */
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02003502 ret = SSL_get_error(conn->xprt_ctx, ret);
Emeric Brun46591952012-05-18 15:47:34 +02003503
3504 if (ret == SSL_ERROR_WANT_WRITE) {
3505 /* SSL handshake needs to write, L4 connection may not be ready */
3506 __conn_sock_stop_recv(conn);
Willy Tarreaue1f50c42014-01-22 20:02:06 +01003507 __conn_sock_want_send(conn);
3508 fd_cant_send(conn->t.sock.fd);
Emeric Brun46591952012-05-18 15:47:34 +02003509 return 0;
3510 }
3511 else if (ret == SSL_ERROR_WANT_READ) {
3512 /* SSL handshake needs to read, L4 connection is ready */
3513 if (conn->flags & CO_FL_WAIT_L4_CONN)
3514 conn->flags &= ~CO_FL_WAIT_L4_CONN;
3515 __conn_sock_stop_send(conn);
Willy Tarreaue1f50c42014-01-22 20:02:06 +01003516 __conn_sock_want_recv(conn);
3517 fd_cant_recv(conn->t.sock.fd);
Emeric Brun46591952012-05-18 15:47:34 +02003518 return 0;
3519 }
Willy Tarreau89230192012-09-28 20:22:13 +02003520 else if (ret == SSL_ERROR_SYSCALL) {
3521 /* if errno is null, then connection was successfully established */
3522 if (!errno && conn->flags & CO_FL_WAIT_L4_CONN)
3523 conn->flags &= ~CO_FL_WAIT_L4_CONN;
Willy Tarreau20879a02012-12-03 16:32:10 +01003524
Emeric Brun29f037d2014-04-25 19:05:36 +02003525 if (!((SSL *)conn->xprt_ctx)->packet_length) {
3526 if (!errno) {
3527 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
3528 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
3529 else
3530 conn->err_code = CO_ER_SSL_EMPTY;
3531 }
3532 else {
3533 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
3534 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
3535 else
3536 conn->err_code = CO_ER_SSL_ABORT;
3537 }
3538 }
3539 else {
3540 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
3541 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
Willy Tarreau20879a02012-12-03 16:32:10 +01003542 else
Emeric Brun29f037d2014-04-25 19:05:36 +02003543 conn->err_code = CO_ER_SSL_HANDSHAKE;
3544 }
Willy Tarreau89230192012-09-28 20:22:13 +02003545 goto out_error;
3546 }
Emeric Brun46591952012-05-18 15:47:34 +02003547 else {
3548 /* Fail on all other handshake errors */
Willy Tarreau566dc552012-10-19 20:52:18 +02003549 /* Note: OpenSSL may leave unread bytes in the socket's
3550 * buffer, causing an RST to be emitted upon close() on
3551 * TCP sockets. We first try to drain possibly pending
3552 * data to avoid this as much as possible.
3553 */
Willy Tarreaud85c4852015-03-13 00:40:28 +01003554 conn_sock_drain(conn);
Willy Tarreau20879a02012-12-03 16:32:10 +01003555 if (!conn->err_code)
Willy Tarreauf51c6982014-04-25 20:02:39 +02003556 conn->err_code = (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT) ?
3557 CO_ER_SSL_KILLED_HB : CO_ER_SSL_HANDSHAKE;
Emeric Brun46591952012-05-18 15:47:34 +02003558 goto out_error;
3559 }
3560 }
3561
Emeric Brun674b7432012-11-08 19:21:55 +01003562reneg_ok:
Emeric Brun46591952012-05-18 15:47:34 +02003563 /* Handshake succeeded */
Willy Tarreau0c9c2722014-05-28 12:28:58 +02003564 if (!SSL_session_reused(conn->xprt_ctx)) {
3565 if (objt_server(conn->target)) {
3566 update_freq_ctr(&global.ssl_be_keys_per_sec, 1);
3567 if (global.ssl_be_keys_per_sec.curr_ctr > global.ssl_be_keys_max)
3568 global.ssl_be_keys_max = global.ssl_be_keys_per_sec.curr_ctr;
3569
Emeric Brun46591952012-05-18 15:47:34 +02003570 /* check if session was reused, if not store current session on server for reuse */
Willy Tarreau3fdb3662012-11-12 00:42:33 +01003571 if (objt_server(conn->target)->ssl_ctx.reused_sess)
3572 SSL_SESSION_free(objt_server(conn->target)->ssl_ctx.reused_sess);
Emeric Brun46591952012-05-18 15:47:34 +02003573
Willy Tarreau2a3fb1c2015-02-05 16:47:07 +01003574 if (!(objt_server(conn->target)->ssl_ctx.options & SRV_SSL_O_NO_REUSE))
3575 objt_server(conn->target)->ssl_ctx.reused_sess = SSL_get1_session(conn->xprt_ctx);
Emeric Brun46591952012-05-18 15:47:34 +02003576 }
Willy Tarreau0c9c2722014-05-28 12:28:58 +02003577 else {
3578 update_freq_ctr(&global.ssl_fe_keys_per_sec, 1);
3579 if (global.ssl_fe_keys_per_sec.curr_ctr > global.ssl_fe_keys_max)
3580 global.ssl_fe_keys_max = global.ssl_fe_keys_per_sec.curr_ctr;
3581 }
Emeric Brun46591952012-05-18 15:47:34 +02003582 }
3583
3584 /* The connection is now established at both layers, it's time to leave */
3585 conn->flags &= ~(flag | CO_FL_WAIT_L4_CONN | CO_FL_WAIT_L6_CONN);
3586 return 1;
3587
3588 out_error:
Emeric Brun644cde02012-12-14 11:21:13 +01003589 /* Clear openssl global errors stack */
Thierry FOURNIER / OZON.IO8b068c22016-10-10 11:59:50 +02003590 ssl_sock_dump_errors(conn);
Emeric Brun644cde02012-12-14 11:21:13 +01003591 ERR_clear_error();
3592
Emeric Brun9fa89732012-10-04 17:09:56 +02003593 /* free resumed session if exists */
Willy Tarreau3fdb3662012-11-12 00:42:33 +01003594 if (objt_server(conn->target) && objt_server(conn->target)->ssl_ctx.reused_sess) {
3595 SSL_SESSION_free(objt_server(conn->target)->ssl_ctx.reused_sess);
3596 objt_server(conn->target)->ssl_ctx.reused_sess = NULL;
Emeric Brun9fa89732012-10-04 17:09:56 +02003597 }
3598
Emeric Brun46591952012-05-18 15:47:34 +02003599 /* Fail on all other handshake errors */
3600 conn->flags |= CO_FL_ERROR;
Willy Tarreau20879a02012-12-03 16:32:10 +01003601 if (!conn->err_code)
3602 conn->err_code = CO_ER_SSL_HANDSHAKE;
Emeric Brun46591952012-05-18 15:47:34 +02003603 return 0;
3604}
3605
3606/* Receive up to <count> bytes from connection <conn>'s socket and store them
Willy Tarreauabf08d92014-01-14 11:31:27 +01003607 * into buffer <buf>. Only one call to recv() is performed, unless the
Emeric Brun46591952012-05-18 15:47:34 +02003608 * buffer wraps, in which case a second call may be performed. The connection's
3609 * flags are updated with whatever special event is detected (error, read0,
3610 * empty). The caller is responsible for taking care of those events and
3611 * avoiding the call if inappropriate. The function does not call the
3612 * connection's polling update function, so the caller is responsible for this.
3613 */
3614static int ssl_sock_to_buf(struct connection *conn, struct buffer *buf, int count)
3615{
3616 int ret, done = 0;
Willy Tarreauabf08d92014-01-14 11:31:27 +01003617 int try;
Emeric Brun46591952012-05-18 15:47:34 +02003618
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02003619 if (!conn->xprt_ctx)
Emeric Brun46591952012-05-18 15:47:34 +02003620 goto out_error;
3621
3622 if (conn->flags & CO_FL_HANDSHAKE)
3623 /* a handshake was requested */
3624 return 0;
3625
Willy Tarreauabf08d92014-01-14 11:31:27 +01003626 /* let's realign the buffer to optimize I/O */
3627 if (buffer_empty(buf))
Emeric Brun46591952012-05-18 15:47:34 +02003628 buf->p = buf->data;
Emeric Brun46591952012-05-18 15:47:34 +02003629
3630 /* read the largest possible block. For this, we perform only one call
3631 * to recv() unless the buffer wraps and we exactly fill the first hunk,
3632 * in which case we accept to do it once again. A new attempt is made on
3633 * EINTR too.
3634 */
Willy Tarreau00b0fb92014-01-17 11:09:40 +01003635 while (count > 0) {
Willy Tarreauabf08d92014-01-14 11:31:27 +01003636 /* first check if we have some room after p+i */
3637 try = buf->data + buf->size - (buf->p + buf->i);
3638 /* otherwise continue between data and p-o */
3639 if (try <= 0) {
3640 try = buf->p - (buf->data + buf->o);
3641 if (try <= 0)
3642 break;
3643 }
3644 if (try > count)
3645 try = count;
3646
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02003647 ret = SSL_read(conn->xprt_ctx, bi_end(buf), try);
Emeric Brune1f38db2012-09-03 20:36:47 +02003648 if (conn->flags & CO_FL_ERROR) {
3649 /* CO_FL_ERROR may be set by ssl_sock_infocbk */
Emeric Brun644cde02012-12-14 11:21:13 +01003650 goto out_error;
Emeric Brune1f38db2012-09-03 20:36:47 +02003651 }
Emeric Brun46591952012-05-18 15:47:34 +02003652 if (ret > 0) {
3653 buf->i += ret;
3654 done += ret;
3655 if (ret < try)
3656 break;
3657 count -= ret;
Emeric Brun46591952012-05-18 15:47:34 +02003658 }
3659 else if (ret == 0) {
Emeric Brun644cde02012-12-14 11:21:13 +01003660 ret = SSL_get_error(conn->xprt_ctx, ret);
3661 if (ret != SSL_ERROR_ZERO_RETURN) {
Emeric Brun1c646862012-12-14 12:33:41 +01003662 /* error on protocol or underlying transport */
3663 if ((ret != SSL_ERROR_SYSCALL)
3664 || (errno && (errno != EAGAIN)))
3665 conn->flags |= CO_FL_ERROR;
3666
Emeric Brun644cde02012-12-14 11:21:13 +01003667 /* Clear openssl global errors stack */
Thierry FOURNIER / OZON.IO8b068c22016-10-10 11:59:50 +02003668 ssl_sock_dump_errors(conn);
Emeric Brun644cde02012-12-14 11:21:13 +01003669 ERR_clear_error();
3670 }
Emeric Brun46591952012-05-18 15:47:34 +02003671 goto read0;
3672 }
3673 else {
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02003674 ret = SSL_get_error(conn->xprt_ctx, ret);
Emeric Brun46591952012-05-18 15:47:34 +02003675 if (ret == SSL_ERROR_WANT_WRITE) {
Emeric Brun8af8dd12012-11-08 17:56:20 +01003676 /* handshake is running, and it needs to enable write */
Emeric Brun46591952012-05-18 15:47:34 +02003677 conn->flags |= CO_FL_SSL_WAIT_HS;
Emeric Brun8af8dd12012-11-08 17:56:20 +01003678 __conn_sock_want_send(conn);
Emeric Brun46591952012-05-18 15:47:34 +02003679 break;
3680 }
3681 else if (ret == SSL_ERROR_WANT_READ) {
Emeric Brun282a76a2012-11-08 18:02:56 +01003682 if (SSL_renegotiate_pending(conn->xprt_ctx)) {
3683 /* handshake is running, and it may need to re-enable read */
3684 conn->flags |= CO_FL_SSL_WAIT_HS;
3685 __conn_sock_want_recv(conn);
3686 break;
3687 }
Emeric Brun46591952012-05-18 15:47:34 +02003688 /* we need to poll for retry a read later */
Willy Tarreaue1f50c42014-01-22 20:02:06 +01003689 fd_cant_recv(conn->t.sock.fd);
Emeric Brun46591952012-05-18 15:47:34 +02003690 break;
3691 }
3692 /* otherwise it's a real error */
3693 goto out_error;
3694 }
3695 }
3696 return done;
3697
3698 read0:
3699 conn_sock_read0(conn);
3700 return done;
3701 out_error:
Emeric Brun644cde02012-12-14 11:21:13 +01003702 /* Clear openssl global errors stack */
Thierry FOURNIER / OZON.IO8b068c22016-10-10 11:59:50 +02003703 ssl_sock_dump_errors(conn);
Emeric Brun644cde02012-12-14 11:21:13 +01003704 ERR_clear_error();
3705
Emeric Brun46591952012-05-18 15:47:34 +02003706 conn->flags |= CO_FL_ERROR;
3707 return done;
3708}
3709
3710
3711/* Send all pending bytes from buffer <buf> to connection <conn>'s socket.
Willy Tarreau1049b1f2014-02-02 01:51:17 +01003712 * <flags> may contain some CO_SFL_* flags to hint the system about other
3713 * pending data for example, but this flag is ignored at the moment.
Emeric Brun46591952012-05-18 15:47:34 +02003714 * Only one call to send() is performed, unless the buffer wraps, in which case
3715 * a second call may be performed. The connection's flags are updated with
3716 * whatever special event is detected (error, empty). The caller is responsible
3717 * for taking care of those events and avoiding the call if inappropriate. The
3718 * function does not call the connection's polling update function, so the caller
3719 * is responsible for this.
3720 */
3721static int ssl_sock_from_buf(struct connection *conn, struct buffer *buf, int flags)
3722{
3723 int ret, try, done;
3724
3725 done = 0;
3726
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02003727 if (!conn->xprt_ctx)
Emeric Brun46591952012-05-18 15:47:34 +02003728 goto out_error;
3729
3730 if (conn->flags & CO_FL_HANDSHAKE)
3731 /* a handshake was requested */
3732 return 0;
3733
3734 /* send the largest possible block. For this we perform only one call
3735 * to send() unless the buffer wraps and we exactly fill the first hunk,
3736 * in which case we accept to do it once again.
3737 */
3738 while (buf->o) {
Kevin Hestercad82342013-05-30 15:12:41 -07003739 try = bo_contig_data(buf);
Willy Tarreaubfd59462013-02-21 07:46:09 +01003740
Willy Tarreau7bed9452014-02-02 02:00:24 +01003741 if (!(flags & CO_SFL_STREAMER) &&
Willy Tarreau518cedd2014-02-17 15:43:01 +01003742 !(conn->xprt_st & SSL_SOCK_SEND_UNLIMITED) &&
3743 global.tune.ssl_max_record && try > global.tune.ssl_max_record) {
Willy Tarreaubfd59462013-02-21 07:46:09 +01003744 try = global.tune.ssl_max_record;
Willy Tarreau518cedd2014-02-17 15:43:01 +01003745 }
3746 else {
3747 /* we need to keep the information about the fact that
3748 * we're not limiting the upcoming send(), because if it
3749 * fails, we'll have to retry with at least as many data.
3750 */
3751 conn->xprt_st |= SSL_SOCK_SEND_UNLIMITED;
3752 }
Willy Tarreaubfd59462013-02-21 07:46:09 +01003753
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02003754 ret = SSL_write(conn->xprt_ctx, bo_ptr(buf), try);
Willy Tarreau518cedd2014-02-17 15:43:01 +01003755
Emeric Brune1f38db2012-09-03 20:36:47 +02003756 if (conn->flags & CO_FL_ERROR) {
3757 /* CO_FL_ERROR may be set by ssl_sock_infocbk */
Emeric Brun644cde02012-12-14 11:21:13 +01003758 goto out_error;
Emeric Brune1f38db2012-09-03 20:36:47 +02003759 }
Emeric Brun46591952012-05-18 15:47:34 +02003760 if (ret > 0) {
Willy Tarreau518cedd2014-02-17 15:43:01 +01003761 conn->xprt_st &= ~SSL_SOCK_SEND_UNLIMITED;
3762
Emeric Brun46591952012-05-18 15:47:34 +02003763 buf->o -= ret;
3764 done += ret;
3765
Willy Tarreau5fb38032012-12-16 19:39:09 +01003766 if (likely(buffer_empty(buf)))
Emeric Brun46591952012-05-18 15:47:34 +02003767 /* optimize data alignment in the buffer */
3768 buf->p = buf->data;
3769
3770 /* if the system buffer is full, don't insist */
3771 if (ret < try)
3772 break;
3773 }
3774 else {
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02003775 ret = SSL_get_error(conn->xprt_ctx, ret);
Emeric Brun46591952012-05-18 15:47:34 +02003776 if (ret == SSL_ERROR_WANT_WRITE) {
Emeric Brun282a76a2012-11-08 18:02:56 +01003777 if (SSL_renegotiate_pending(conn->xprt_ctx)) {
3778 /* handshake is running, and it may need to re-enable write */
3779 conn->flags |= CO_FL_SSL_WAIT_HS;
3780 __conn_sock_want_send(conn);
3781 break;
3782 }
Emeric Brun46591952012-05-18 15:47:34 +02003783 /* we need to poll to retry a write later */
Willy Tarreaue1f50c42014-01-22 20:02:06 +01003784 fd_cant_send(conn->t.sock.fd);
Emeric Brun46591952012-05-18 15:47:34 +02003785 break;
3786 }
3787 else if (ret == SSL_ERROR_WANT_READ) {
Emeric Brun8af8dd12012-11-08 17:56:20 +01003788 /* handshake is running, and it needs to enable read */
Emeric Brun46591952012-05-18 15:47:34 +02003789 conn->flags |= CO_FL_SSL_WAIT_HS;
Emeric Brun8af8dd12012-11-08 17:56:20 +01003790 __conn_sock_want_recv(conn);
Emeric Brun46591952012-05-18 15:47:34 +02003791 break;
3792 }
3793 goto out_error;
3794 }
3795 }
3796 return done;
3797
3798 out_error:
Emeric Brun644cde02012-12-14 11:21:13 +01003799 /* Clear openssl global errors stack */
Thierry FOURNIER / OZON.IO8b068c22016-10-10 11:59:50 +02003800 ssl_sock_dump_errors(conn);
Emeric Brun644cde02012-12-14 11:21:13 +01003801 ERR_clear_error();
3802
Emeric Brun46591952012-05-18 15:47:34 +02003803 conn->flags |= CO_FL_ERROR;
3804 return done;
3805}
3806
Emeric Brun46591952012-05-18 15:47:34 +02003807static void ssl_sock_close(struct connection *conn) {
3808
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02003809 if (conn->xprt_ctx) {
3810 SSL_free(conn->xprt_ctx);
3811 conn->xprt_ctx = NULL;
Willy Tarreau403edff2012-09-06 11:58:37 +02003812 sslconns--;
Emeric Brun46591952012-05-18 15:47:34 +02003813 }
Emeric Brun46591952012-05-18 15:47:34 +02003814}
3815
3816/* This function tries to perform a clean shutdown on an SSL connection, and in
3817 * any case, flags the connection as reusable if no handshake was in progress.
3818 */
3819static void ssl_sock_shutw(struct connection *conn, int clean)
3820{
3821 if (conn->flags & CO_FL_HANDSHAKE)
3822 return;
3823 /* no handshake was in progress, try a clean ssl shutdown */
Emeric Brun644cde02012-12-14 11:21:13 +01003824 if (clean && (SSL_shutdown(conn->xprt_ctx) <= 0)) {
3825 /* Clear openssl global errors stack */
Thierry FOURNIER / OZON.IO8b068c22016-10-10 11:59:50 +02003826 ssl_sock_dump_errors(conn);
Emeric Brun644cde02012-12-14 11:21:13 +01003827 ERR_clear_error();
3828 }
Emeric Brun46591952012-05-18 15:47:34 +02003829
3830 /* force flag on ssl to keep session in cache regardless shutdown result */
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02003831 SSL_set_shutdown(conn->xprt_ctx, SSL_SENT_SHUTDOWN);
Emeric Brun46591952012-05-18 15:47:34 +02003832}
3833
Willy Tarreauffc3fcd2012-10-12 20:17:54 +02003834/* used for logging, may be changed for a sample fetch later */
3835const char *ssl_sock_get_cipher_name(struct connection *conn)
3836{
3837 if (!conn->xprt && !conn->xprt_ctx)
3838 return NULL;
3839 return SSL_get_cipher_name(conn->xprt_ctx);
3840}
3841
3842/* used for logging, may be changed for a sample fetch later */
3843const char *ssl_sock_get_proto_version(struct connection *conn)
3844{
3845 if (!conn->xprt && !conn->xprt_ctx)
3846 return NULL;
3847 return SSL_get_version(conn->xprt_ctx);
3848}
3849
Willy Tarreau8d598402012-10-22 17:58:39 +02003850/* Extract a serial from a cert, and copy it to a chunk.
3851 * Returns 1 if serial is found and copied, 0 if no serial found and
3852 * -1 if output is not large enough.
3853 */
3854static int
3855ssl_sock_get_serial(X509 *crt, struct chunk *out)
3856{
3857 ASN1_INTEGER *serial;
3858
3859 serial = X509_get_serialNumber(crt);
3860 if (!serial)
3861 return 0;
3862
3863 if (out->size < serial->length)
3864 return -1;
3865
3866 memcpy(out->str, serial->data, serial->length);
3867 out->len = serial->length;
3868 return 1;
3869}
3870
Emeric Brun43e79582014-10-29 19:03:26 +01003871/* Extract a cert to der, and copy it to a chunk.
3872 * Returns 1 if cert is found and copied, 0 on der convertion failure and
3873 * -1 if output is not large enough.
3874 */
3875static int
3876ssl_sock_crt2der(X509 *crt, struct chunk *out)
3877{
3878 int len;
3879 unsigned char *p = (unsigned char *)out->str;;
3880
3881 len =i2d_X509(crt, NULL);
3882 if (len <= 0)
3883 return 1;
3884
3885 if (out->size < len)
3886 return -1;
3887
3888 i2d_X509(crt,&p);
3889 out->len = len;
3890 return 1;
3891}
3892
Emeric Brunce5ad802012-10-22 14:11:22 +02003893
3894/* Copy Date in ASN1_UTCTIME format in struct chunk out.
3895 * Returns 1 if serial is found and copied, 0 if no valid time found
3896 * and -1 if output is not large enough.
3897 */
3898static int
3899ssl_sock_get_time(ASN1_TIME *tm, struct chunk *out)
3900{
3901 if (tm->type == V_ASN1_GENERALIZEDTIME) {
3902 ASN1_GENERALIZEDTIME *gentm = (ASN1_GENERALIZEDTIME *)tm;
3903
3904 if (gentm->length < 12)
3905 return 0;
3906 if (gentm->data[0] != 0x32 || gentm->data[1] != 0x30)
3907 return 0;
3908 if (out->size < gentm->length-2)
3909 return -1;
3910
3911 memcpy(out->str, gentm->data+2, gentm->length-2);
3912 out->len = gentm->length-2;
3913 return 1;
3914 }
3915 else if (tm->type == V_ASN1_UTCTIME) {
3916 ASN1_UTCTIME *utctm = (ASN1_UTCTIME *)tm;
3917
3918 if (utctm->length < 10)
3919 return 0;
3920 if (utctm->data[0] >= 0x35)
3921 return 0;
3922 if (out->size < utctm->length)
3923 return -1;
3924
3925 memcpy(out->str, utctm->data, utctm->length);
3926 out->len = utctm->length;
3927 return 1;
3928 }
3929
3930 return 0;
3931}
3932
Emeric Brun87855892012-10-17 17:39:35 +02003933/* Extract an entry from a X509_NAME and copy its value to an output chunk.
3934 * Returns 1 if entry found, 0 if entry not found, or -1 if output not large enough.
3935 */
3936static int
3937ssl_sock_get_dn_entry(X509_NAME *a, const struct chunk *entry, int pos, struct chunk *out)
3938{
3939 X509_NAME_ENTRY *ne;
3940 int i, j, n;
3941 int cur = 0;
3942 const char *s;
3943 char tmp[128];
3944
3945 out->len = 0;
3946 for (i = 0; i < sk_X509_NAME_ENTRY_num(a->entries); i++) {
3947 if (pos < 0)
3948 j = (sk_X509_NAME_ENTRY_num(a->entries)-1) - i;
3949 else
3950 j = i;
3951
3952 ne = sk_X509_NAME_ENTRY_value(a->entries, j);
3953 n = OBJ_obj2nid(ne->object);
3954 if ((n == NID_undef) || ((s = OBJ_nid2sn(n)) == NULL)) {
3955 i2t_ASN1_OBJECT(tmp, sizeof(tmp), ne->object);
3956 s = tmp;
3957 }
3958
3959 if (chunk_strcasecmp(entry, s) != 0)
3960 continue;
3961
3962 if (pos < 0)
3963 cur--;
3964 else
3965 cur++;
3966
3967 if (cur != pos)
3968 continue;
3969
3970 if (ne->value->length > out->size)
3971 return -1;
3972
3973 memcpy(out->str, ne->value->data, ne->value->length);
3974 out->len = ne->value->length;
3975 return 1;
3976 }
3977
3978 return 0;
3979
3980}
3981
3982/* Extract and format full DN from a X509_NAME and copy result into a chunk
3983 * Returns 1 if dn entries exits, 0 if no dn entry found or -1 if output is not large enough.
3984 */
3985static int
3986ssl_sock_get_dn_oneline(X509_NAME *a, struct chunk *out)
3987{
3988 X509_NAME_ENTRY *ne;
3989 int i, n, ln;
3990 int l = 0;
3991 const char *s;
3992 char *p;
3993 char tmp[128];
3994
3995 out->len = 0;
3996 p = out->str;
3997 for (i = 0; i < sk_X509_NAME_ENTRY_num(a->entries); i++) {
3998 ne = sk_X509_NAME_ENTRY_value(a->entries, i);
3999 n = OBJ_obj2nid(ne->object);
4000 if ((n == NID_undef) || ((s = OBJ_nid2sn(n)) == NULL)) {
4001 i2t_ASN1_OBJECT(tmp, sizeof(tmp), ne->object);
4002 s = tmp;
4003 }
4004 ln = strlen(s);
4005
4006 l += 1 + ln + 1 + ne->value->length;
4007 if (l > out->size)
4008 return -1;
4009 out->len = l;
4010
4011 *(p++)='/';
4012 memcpy(p, s, ln);
4013 p += ln;
4014 *(p++)='=';
4015 memcpy(p, ne->value->data, ne->value->length);
4016 p += ne->value->length;
4017 }
4018
4019 if (!out->len)
4020 return 0;
4021
4022 return 1;
4023}
4024
David Safb76832014-05-08 23:42:08 -04004025char *ssl_sock_get_version(struct connection *conn)
4026{
4027 if (!ssl_sock_is_ssl(conn))
4028 return NULL;
4029
4030 return (char *)SSL_get_version(conn->xprt_ctx);
4031}
4032
Willy Tarreau63076412015-07-10 11:33:32 +02004033void ssl_sock_set_servername(struct connection *conn, const char *hostname)
4034{
4035#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
4036 if (!ssl_sock_is_ssl(conn))
4037 return;
4038
4039 SSL_set_tlsext_host_name(conn->xprt_ctx, hostname);
4040#endif
4041}
4042
Emeric Brun0abf8362014-06-24 18:26:41 +02004043/* Extract peer certificate's common name into the chunk dest
4044 * Returns
4045 * the len of the extracted common name
4046 * or 0 if no CN found in DN
4047 * or -1 on error case (i.e. no peer certificate)
4048 */
4049int ssl_sock_get_remote_common_name(struct connection *conn, struct chunk *dest)
David Safb76832014-05-08 23:42:08 -04004050{
4051 X509 *crt = NULL;
4052 X509_NAME *name;
David Safb76832014-05-08 23:42:08 -04004053 const char find_cn[] = "CN";
4054 const struct chunk find_cn_chunk = {
4055 .str = (char *)&find_cn,
4056 .len = sizeof(find_cn)-1
4057 };
Emeric Brun0abf8362014-06-24 18:26:41 +02004058 int result = -1;
David Safb76832014-05-08 23:42:08 -04004059
4060 if (!ssl_sock_is_ssl(conn))
Emeric Brun0abf8362014-06-24 18:26:41 +02004061 goto out;
David Safb76832014-05-08 23:42:08 -04004062
4063 /* SSL_get_peer_certificate, it increase X509 * ref count */
4064 crt = SSL_get_peer_certificate(conn->xprt_ctx);
4065 if (!crt)
4066 goto out;
4067
4068 name = X509_get_subject_name(crt);
4069 if (!name)
4070 goto out;
David Safb76832014-05-08 23:42:08 -04004071
Emeric Brun0abf8362014-06-24 18:26:41 +02004072 result = ssl_sock_get_dn_entry(name, &find_cn_chunk, 1, dest);
4073out:
David Safb76832014-05-08 23:42:08 -04004074 if (crt)
4075 X509_free(crt);
4076
4077 return result;
4078}
4079
Dave McCowan328fb582014-07-30 10:39:13 -04004080/* returns 1 if client passed a certificate for this session, 0 if not */
4081int ssl_sock_get_cert_used_sess(struct connection *conn)
4082{
4083 X509 *crt = NULL;
4084
4085 if (!ssl_sock_is_ssl(conn))
4086 return 0;
4087
4088 /* SSL_get_peer_certificate, it increase X509 * ref count */
4089 crt = SSL_get_peer_certificate(conn->xprt_ctx);
4090 if (!crt)
4091 return 0;
4092
4093 X509_free(crt);
4094 return 1;
4095}
4096
4097/* returns 1 if client passed a certificate for this connection, 0 if not */
4098int ssl_sock_get_cert_used_conn(struct connection *conn)
David Safb76832014-05-08 23:42:08 -04004099{
4100 if (!ssl_sock_is_ssl(conn))
4101 return 0;
4102
4103 return SSL_SOCK_ST_FL_VERIFY_DONE & conn->xprt_st ? 1 : 0;
4104}
4105
4106/* returns result from SSL verify */
4107unsigned int ssl_sock_get_verify_result(struct connection *conn)
4108{
4109 if (!ssl_sock_is_ssl(conn))
4110 return (unsigned int)X509_V_ERR_APPLICATION_VERIFICATION;
4111
4112 return (unsigned int)SSL_get_verify_result(conn->xprt_ctx);
4113}
4114
Willy Tarreau7875d092012-09-10 08:20:03 +02004115/***** Below are some sample fetching functions for ACL/patterns *****/
4116
Emeric Brune64aef12012-09-21 13:15:06 +02004117/* boolean, returns true if client cert was present */
4118static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004119smp_fetch_ssl_fc_has_crt(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brune64aef12012-09-21 13:15:06 +02004120{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004121 struct connection *conn;
4122
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004123 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004124 if (!conn || conn->xprt != &ssl_sock)
Emeric Brune64aef12012-09-21 13:15:06 +02004125 return 0;
4126
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004127 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brune64aef12012-09-21 13:15:06 +02004128 smp->flags |= SMP_F_MAY_CHANGE;
4129 return 0;
4130 }
4131
4132 smp->flags = 0;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004133 smp->data.type = SMP_T_BOOL;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004134 smp->data.u.sint = SSL_SOCK_ST_FL_VERIFY_DONE & conn->xprt_st ? 1 : 0;
Emeric Brune64aef12012-09-21 13:15:06 +02004135
4136 return 1;
4137}
4138
Emeric Brun43e79582014-10-29 19:03:26 +01004139/* binary, returns a certificate in a binary chunk (der/raw).
4140 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
4141 * should be use.
4142 */
4143static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004144smp_fetch_ssl_x_der(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun43e79582014-10-29 19:03:26 +01004145{
4146 int cert_peer = (kw[4] == 'c') ? 1 : 0;
4147 X509 *crt = NULL;
4148 int ret = 0;
4149 struct chunk *smp_trash;
4150 struct connection *conn;
4151
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004152 conn = objt_conn(smp->sess->origin);
Emeric Brun43e79582014-10-29 19:03:26 +01004153 if (!conn || conn->xprt != &ssl_sock)
4154 return 0;
4155
4156 if (!(conn->flags & CO_FL_CONNECTED)) {
4157 smp->flags |= SMP_F_MAY_CHANGE;
4158 return 0;
4159 }
4160
4161 if (cert_peer)
4162 crt = SSL_get_peer_certificate(conn->xprt_ctx);
4163 else
4164 crt = SSL_get_certificate(conn->xprt_ctx);
4165
4166 if (!crt)
4167 goto out;
4168
4169 smp_trash = get_trash_chunk();
4170 if (ssl_sock_crt2der(crt, smp_trash) <= 0)
4171 goto out;
4172
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004173 smp->data.u.str = *smp_trash;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004174 smp->data.type = SMP_T_BIN;
Emeric Brun43e79582014-10-29 19:03:26 +01004175 ret = 1;
4176out:
4177 /* SSL_get_peer_certificate, it increase X509 * ref count */
4178 if (cert_peer && crt)
4179 X509_free(crt);
4180 return ret;
4181}
4182
Emeric Brunba841a12014-04-30 17:05:08 +02004183/* binary, returns serial of certificate in a binary chunk.
4184 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
4185 * should be use.
4186 */
Willy Tarreau8d598402012-10-22 17:58:39 +02004187static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004188smp_fetch_ssl_x_serial(const struct arg *args, struct sample *smp, const char *kw, void *private)
Willy Tarreau8d598402012-10-22 17:58:39 +02004189{
Emeric Brunba841a12014-04-30 17:05:08 +02004190 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Willy Tarreau8d598402012-10-22 17:58:39 +02004191 X509 *crt = NULL;
4192 int ret = 0;
4193 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004194 struct connection *conn;
4195
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004196 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004197 if (!conn || conn->xprt != &ssl_sock)
Willy Tarreau8d598402012-10-22 17:58:39 +02004198 return 0;
4199
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004200 if (!(conn->flags & CO_FL_CONNECTED)) {
Willy Tarreau8d598402012-10-22 17:58:39 +02004201 smp->flags |= SMP_F_MAY_CHANGE;
4202 return 0;
4203 }
4204
Emeric Brunba841a12014-04-30 17:05:08 +02004205 if (cert_peer)
4206 crt = SSL_get_peer_certificate(conn->xprt_ctx);
4207 else
4208 crt = SSL_get_certificate(conn->xprt_ctx);
4209
Willy Tarreau8d598402012-10-22 17:58:39 +02004210 if (!crt)
4211 goto out;
4212
Willy Tarreau47ca5452012-12-23 20:22:19 +01004213 smp_trash = get_trash_chunk();
Willy Tarreau8d598402012-10-22 17:58:39 +02004214 if (ssl_sock_get_serial(crt, smp_trash) <= 0)
4215 goto out;
4216
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004217 smp->data.u.str = *smp_trash;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004218 smp->data.type = SMP_T_BIN;
Willy Tarreau8d598402012-10-22 17:58:39 +02004219 ret = 1;
4220out:
Emeric Brunba841a12014-04-30 17:05:08 +02004221 /* SSL_get_peer_certificate, it increase X509 * ref count */
4222 if (cert_peer && crt)
Willy Tarreau8d598402012-10-22 17:58:39 +02004223 X509_free(crt);
4224 return ret;
4225}
Emeric Brune64aef12012-09-21 13:15:06 +02004226
Emeric Brunba841a12014-04-30 17:05:08 +02004227/* binary, returns the client certificate's SHA-1 fingerprint (SHA-1 hash of DER-encoded certificate) in a binary chunk.
4228 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
4229 * should be use.
4230 */
James Votha051b4a2013-05-14 20:37:59 +02004231static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004232smp_fetch_ssl_x_sha1(const struct arg *args, struct sample *smp, const char *kw, void *private)
James Votha051b4a2013-05-14 20:37:59 +02004233{
Emeric Brunba841a12014-04-30 17:05:08 +02004234 int cert_peer = (kw[4] == 'c') ? 1 : 0;
James Votha051b4a2013-05-14 20:37:59 +02004235 X509 *crt = NULL;
4236 const EVP_MD *digest;
4237 int ret = 0;
4238 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004239 struct connection *conn;
James Votha051b4a2013-05-14 20:37:59 +02004240
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004241 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004242 if (!conn || conn->xprt != &ssl_sock)
4243 return 0;
4244
4245 if (!(conn->flags & CO_FL_CONNECTED)) {
James Votha051b4a2013-05-14 20:37:59 +02004246 smp->flags |= SMP_F_MAY_CHANGE;
4247 return 0;
4248 }
4249
Emeric Brunba841a12014-04-30 17:05:08 +02004250 if (cert_peer)
4251 crt = SSL_get_peer_certificate(conn->xprt_ctx);
4252 else
4253 crt = SSL_get_certificate(conn->xprt_ctx);
James Votha051b4a2013-05-14 20:37:59 +02004254 if (!crt)
4255 goto out;
4256
4257 smp_trash = get_trash_chunk();
4258 digest = EVP_sha1();
4259 X509_digest(crt, digest, (unsigned char *)smp_trash->str, (unsigned int *)&smp_trash->len);
4260
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004261 smp->data.u.str = *smp_trash;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004262 smp->data.type = SMP_T_BIN;
James Votha051b4a2013-05-14 20:37:59 +02004263 ret = 1;
4264out:
Emeric Brunba841a12014-04-30 17:05:08 +02004265 /* SSL_get_peer_certificate, it increase X509 * ref count */
4266 if (cert_peer && crt)
James Votha051b4a2013-05-14 20:37:59 +02004267 X509_free(crt);
4268 return ret;
4269}
4270
Emeric Brunba841a12014-04-30 17:05:08 +02004271/* string, returns certificate's notafter date in ASN1_UTCTIME format.
4272 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
4273 * should be use.
4274 */
Emeric Brunce5ad802012-10-22 14:11:22 +02004275static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004276smp_fetch_ssl_x_notafter(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brunce5ad802012-10-22 14:11:22 +02004277{
Emeric Brunba841a12014-04-30 17:05:08 +02004278 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brunce5ad802012-10-22 14:11:22 +02004279 X509 *crt = NULL;
4280 int ret = 0;
4281 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004282 struct connection *conn;
Emeric Brunce5ad802012-10-22 14:11:22 +02004283
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004284 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004285 if (!conn || conn->xprt != &ssl_sock)
4286 return 0;
4287
4288 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunce5ad802012-10-22 14:11:22 +02004289 smp->flags |= SMP_F_MAY_CHANGE;
4290 return 0;
4291 }
4292
Emeric Brunba841a12014-04-30 17:05:08 +02004293 if (cert_peer)
4294 crt = SSL_get_peer_certificate(conn->xprt_ctx);
4295 else
4296 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brunce5ad802012-10-22 14:11:22 +02004297 if (!crt)
4298 goto out;
4299
Willy Tarreau47ca5452012-12-23 20:22:19 +01004300 smp_trash = get_trash_chunk();
Emeric Brunce5ad802012-10-22 14:11:22 +02004301 if (ssl_sock_get_time(X509_get_notAfter(crt), smp_trash) <= 0)
4302 goto out;
4303
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004304 smp->data.u.str = *smp_trash;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004305 smp->data.type = SMP_T_STR;
Emeric Brunce5ad802012-10-22 14:11:22 +02004306 ret = 1;
4307out:
Emeric Brunba841a12014-04-30 17:05:08 +02004308 /* SSL_get_peer_certificate, it increase X509 * ref count */
4309 if (cert_peer && crt)
Emeric Brunce5ad802012-10-22 14:11:22 +02004310 X509_free(crt);
4311 return ret;
4312}
4313
Emeric Brunba841a12014-04-30 17:05:08 +02004314/* string, returns a string of a formatted full dn \C=..\O=..\OU=.. \CN=.. of certificate's issuer
4315 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
4316 * should be use.
4317 */
Emeric Brun87855892012-10-17 17:39:35 +02004318static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004319smp_fetch_ssl_x_i_dn(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun87855892012-10-17 17:39:35 +02004320{
Emeric Brunba841a12014-04-30 17:05:08 +02004321 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brun87855892012-10-17 17:39:35 +02004322 X509 *crt = NULL;
4323 X509_NAME *name;
4324 int ret = 0;
4325 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004326 struct connection *conn;
Emeric Brun87855892012-10-17 17:39:35 +02004327
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004328 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004329 if (!conn || conn->xprt != &ssl_sock)
4330 return 0;
4331
4332 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun87855892012-10-17 17:39:35 +02004333 smp->flags |= SMP_F_MAY_CHANGE;
4334 return 0;
4335 }
4336
Emeric Brunba841a12014-04-30 17:05:08 +02004337 if (cert_peer)
4338 crt = SSL_get_peer_certificate(conn->xprt_ctx);
4339 else
4340 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brun87855892012-10-17 17:39:35 +02004341 if (!crt)
4342 goto out;
4343
4344 name = X509_get_issuer_name(crt);
4345 if (!name)
4346 goto out;
4347
Willy Tarreau47ca5452012-12-23 20:22:19 +01004348 smp_trash = get_trash_chunk();
Emeric Brun87855892012-10-17 17:39:35 +02004349 if (args && args[0].type == ARGT_STR) {
4350 int pos = 1;
4351
4352 if (args[1].type == ARGT_SINT)
4353 pos = args[1].data.sint;
Emeric Brun87855892012-10-17 17:39:35 +02004354
4355 if (ssl_sock_get_dn_entry(name, &args[0].data.str, pos, smp_trash) <= 0)
4356 goto out;
4357 }
4358 else if (ssl_sock_get_dn_oneline(name, smp_trash) <= 0)
4359 goto out;
4360
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004361 smp->data.type = SMP_T_STR;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004362 smp->data.u.str = *smp_trash;
Emeric Brun87855892012-10-17 17:39:35 +02004363 ret = 1;
4364out:
Emeric Brunba841a12014-04-30 17:05:08 +02004365 /* SSL_get_peer_certificate, it increase X509 * ref count */
4366 if (cert_peer && crt)
Emeric Brun87855892012-10-17 17:39:35 +02004367 X509_free(crt);
4368 return ret;
4369}
4370
Emeric Brunba841a12014-04-30 17:05:08 +02004371/* string, returns notbefore date in ASN1_UTCTIME format.
4372 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
4373 * should be use.
4374 */
Emeric Brunce5ad802012-10-22 14:11:22 +02004375static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004376smp_fetch_ssl_x_notbefore(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brunce5ad802012-10-22 14:11:22 +02004377{
Emeric Brunba841a12014-04-30 17:05:08 +02004378 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brunce5ad802012-10-22 14:11:22 +02004379 X509 *crt = NULL;
4380 int ret = 0;
4381 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004382 struct connection *conn;
4383
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004384 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004385 if (!conn || conn->xprt != &ssl_sock)
Emeric Brunce5ad802012-10-22 14:11:22 +02004386 return 0;
4387
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004388 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunce5ad802012-10-22 14:11:22 +02004389 smp->flags |= SMP_F_MAY_CHANGE;
4390 return 0;
4391 }
4392
Emeric Brunba841a12014-04-30 17:05:08 +02004393 if (cert_peer)
4394 crt = SSL_get_peer_certificate(conn->xprt_ctx);
4395 else
4396 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brunce5ad802012-10-22 14:11:22 +02004397 if (!crt)
4398 goto out;
4399
Willy Tarreau47ca5452012-12-23 20:22:19 +01004400 smp_trash = get_trash_chunk();
Emeric Brunce5ad802012-10-22 14:11:22 +02004401 if (ssl_sock_get_time(X509_get_notBefore(crt), smp_trash) <= 0)
4402 goto out;
4403
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004404 smp->data.u.str = *smp_trash;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004405 smp->data.type = SMP_T_STR;
Emeric Brunce5ad802012-10-22 14:11:22 +02004406 ret = 1;
4407out:
Emeric Brunba841a12014-04-30 17:05:08 +02004408 /* SSL_get_peer_certificate, it increase X509 * ref count */
4409 if (cert_peer && crt)
Emeric Brunce5ad802012-10-22 14:11:22 +02004410 X509_free(crt);
4411 return ret;
4412}
4413
Emeric Brunba841a12014-04-30 17:05:08 +02004414/* string, returns a string of a formatted full dn \C=..\O=..\OU=.. \CN=.. of certificate's subject
4415 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
4416 * should be use.
4417 */
Emeric Brun87855892012-10-17 17:39:35 +02004418static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004419smp_fetch_ssl_x_s_dn(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun87855892012-10-17 17:39:35 +02004420{
Emeric Brunba841a12014-04-30 17:05:08 +02004421 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brun87855892012-10-17 17:39:35 +02004422 X509 *crt = NULL;
4423 X509_NAME *name;
4424 int ret = 0;
4425 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004426 struct connection *conn;
Emeric Brun87855892012-10-17 17:39:35 +02004427
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004428 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004429 if (!conn || conn->xprt != &ssl_sock)
4430 return 0;
4431
4432 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun87855892012-10-17 17:39:35 +02004433 smp->flags |= SMP_F_MAY_CHANGE;
4434 return 0;
4435 }
4436
Emeric Brunba841a12014-04-30 17:05:08 +02004437 if (cert_peer)
4438 crt = SSL_get_peer_certificate(conn->xprt_ctx);
4439 else
4440 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brun87855892012-10-17 17:39:35 +02004441 if (!crt)
4442 goto out;
4443
4444 name = X509_get_subject_name(crt);
4445 if (!name)
4446 goto out;
4447
Willy Tarreau47ca5452012-12-23 20:22:19 +01004448 smp_trash = get_trash_chunk();
Emeric Brun87855892012-10-17 17:39:35 +02004449 if (args && args[0].type == ARGT_STR) {
4450 int pos = 1;
4451
4452 if (args[1].type == ARGT_SINT)
4453 pos = args[1].data.sint;
Emeric Brun87855892012-10-17 17:39:35 +02004454
4455 if (ssl_sock_get_dn_entry(name, &args[0].data.str, pos, smp_trash) <= 0)
4456 goto out;
4457 }
4458 else if (ssl_sock_get_dn_oneline(name, smp_trash) <= 0)
4459 goto out;
4460
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004461 smp->data.type = SMP_T_STR;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004462 smp->data.u.str = *smp_trash;
Emeric Brun87855892012-10-17 17:39:35 +02004463 ret = 1;
4464out:
Emeric Brunba841a12014-04-30 17:05:08 +02004465 /* SSL_get_peer_certificate, it increase X509 * ref count */
4466 if (cert_peer && crt)
Emeric Brun87855892012-10-17 17:39:35 +02004467 X509_free(crt);
4468 return ret;
4469}
Emeric Brun9143d372012-12-20 15:44:16 +01004470
4471/* integer, returns true if current session use a client certificate */
4472static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004473smp_fetch_ssl_c_used(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun9143d372012-12-20 15:44:16 +01004474{
4475 X509 *crt;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004476 struct connection *conn;
Emeric Brun9143d372012-12-20 15:44:16 +01004477
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004478 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004479 if (!conn || conn->xprt != &ssl_sock)
4480 return 0;
4481
4482 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun9143d372012-12-20 15:44:16 +01004483 smp->flags |= SMP_F_MAY_CHANGE;
4484 return 0;
4485 }
4486
4487 /* SSL_get_peer_certificate returns a ptr on allocated X509 struct */
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004488 crt = SSL_get_peer_certificate(conn->xprt_ctx);
Emeric Brun9143d372012-12-20 15:44:16 +01004489 if (crt) {
4490 X509_free(crt);
4491 }
4492
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004493 smp->data.type = SMP_T_BOOL;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004494 smp->data.u.sint = (crt != NULL);
Emeric Brun9143d372012-12-20 15:44:16 +01004495 return 1;
4496}
4497
Emeric Brunba841a12014-04-30 17:05:08 +02004498/* integer, returns the certificate version
4499 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
4500 * should be use.
4501 */
Emeric Bruna7359fd2012-10-17 15:03:11 +02004502static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004503smp_fetch_ssl_x_version(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Bruna7359fd2012-10-17 15:03:11 +02004504{
Emeric Brunba841a12014-04-30 17:05:08 +02004505 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Bruna7359fd2012-10-17 15:03:11 +02004506 X509 *crt;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004507 struct connection *conn;
4508
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004509 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004510 if (!conn || conn->xprt != &ssl_sock)
Emeric Bruna7359fd2012-10-17 15:03:11 +02004511 return 0;
4512
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004513 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Bruna7359fd2012-10-17 15:03:11 +02004514 smp->flags |= SMP_F_MAY_CHANGE;
4515 return 0;
4516 }
4517
Emeric Brunba841a12014-04-30 17:05:08 +02004518 if (cert_peer)
4519 crt = SSL_get_peer_certificate(conn->xprt_ctx);
4520 else
4521 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Bruna7359fd2012-10-17 15:03:11 +02004522 if (!crt)
4523 return 0;
4524
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004525 smp->data.u.sint = (unsigned int)(1 + X509_get_version(crt));
Emeric Brunba841a12014-04-30 17:05:08 +02004526 /* SSL_get_peer_certificate increase X509 * ref count */
4527 if (cert_peer)
4528 X509_free(crt);
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004529 smp->data.type = SMP_T_SINT;
Emeric Bruna7359fd2012-10-17 15:03:11 +02004530
4531 return 1;
4532}
4533
Emeric Brunba841a12014-04-30 17:05:08 +02004534/* string, returns the certificate's signature algorithm.
4535 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
4536 * should be use.
4537 */
Emeric Brun7f56e742012-10-19 18:15:40 +02004538static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004539smp_fetch_ssl_x_sig_alg(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun7f56e742012-10-19 18:15:40 +02004540{
Emeric Brunba841a12014-04-30 17:05:08 +02004541 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brun7f56e742012-10-19 18:15:40 +02004542 X509 *crt;
4543 int nid;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004544 struct connection *conn;
Emeric Brun7f56e742012-10-19 18:15:40 +02004545
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004546 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004547 if (!conn || conn->xprt != &ssl_sock)
4548 return 0;
4549
4550 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun7f56e742012-10-19 18:15:40 +02004551 smp->flags |= SMP_F_MAY_CHANGE;
4552 return 0;
4553 }
4554
Emeric Brunba841a12014-04-30 17:05:08 +02004555 if (cert_peer)
4556 crt = SSL_get_peer_certificate(conn->xprt_ctx);
4557 else
4558 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brun7f56e742012-10-19 18:15:40 +02004559 if (!crt)
4560 return 0;
4561
4562 nid = OBJ_obj2nid((ASN1_OBJECT *)(crt->cert_info->signature->algorithm));
4563
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004564 smp->data.u.str.str = (char *)OBJ_nid2sn(nid);
4565 if (!smp->data.u.str.str) {
Emeric Brunba841a12014-04-30 17:05:08 +02004566 /* SSL_get_peer_certificate increase X509 * ref count */
4567 if (cert_peer)
4568 X509_free(crt);
Emeric Brun7f56e742012-10-19 18:15:40 +02004569 return 0;
Emeric Brun9bf3ba22013-10-07 14:31:44 +02004570 }
Emeric Brun7f56e742012-10-19 18:15:40 +02004571
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004572 smp->data.type = SMP_T_STR;
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01004573 smp->flags |= SMP_F_CONST;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004574 smp->data.u.str.len = strlen(smp->data.u.str.str);
Emeric Brunba841a12014-04-30 17:05:08 +02004575 /* SSL_get_peer_certificate increase X509 * ref count */
4576 if (cert_peer)
4577 X509_free(crt);
Emeric Brun7f56e742012-10-19 18:15:40 +02004578
4579 return 1;
4580}
4581
Emeric Brunba841a12014-04-30 17:05:08 +02004582/* string, returns the certificate's key algorithm.
4583 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
4584 * should be use.
4585 */
Emeric Brun521a0112012-10-22 12:22:55 +02004586static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004587smp_fetch_ssl_x_key_alg(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun521a0112012-10-22 12:22:55 +02004588{
Emeric Brunba841a12014-04-30 17:05:08 +02004589 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brun521a0112012-10-22 12:22:55 +02004590 X509 *crt;
4591 int nid;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004592 struct connection *conn;
Emeric Brun521a0112012-10-22 12:22:55 +02004593
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004594 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004595 if (!conn || conn->xprt != &ssl_sock)
4596 return 0;
4597
4598 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun521a0112012-10-22 12:22:55 +02004599 smp->flags |= SMP_F_MAY_CHANGE;
4600 return 0;
4601 }
4602
Emeric Brunba841a12014-04-30 17:05:08 +02004603 if (cert_peer)
4604 crt = SSL_get_peer_certificate(conn->xprt_ctx);
4605 else
4606 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brun521a0112012-10-22 12:22:55 +02004607 if (!crt)
4608 return 0;
4609
4610 nid = OBJ_obj2nid((ASN1_OBJECT *)(crt->cert_info->key->algor->algorithm));
4611
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004612 smp->data.u.str.str = (char *)OBJ_nid2sn(nid);
4613 if (!smp->data.u.str.str) {
Emeric Brunba841a12014-04-30 17:05:08 +02004614 /* SSL_get_peer_certificate increase X509 * ref count */
4615 if (cert_peer)
4616 X509_free(crt);
Emeric Brun521a0112012-10-22 12:22:55 +02004617 return 0;
Emeric Brun9bf3ba22013-10-07 14:31:44 +02004618 }
Emeric Brun521a0112012-10-22 12:22:55 +02004619
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004620 smp->data.type = SMP_T_STR;
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01004621 smp->flags |= SMP_F_CONST;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004622 smp->data.u.str.len = strlen(smp->data.u.str.str);
Emeric Brunba841a12014-04-30 17:05:08 +02004623 if (cert_peer)
4624 X509_free(crt);
Emeric Brun521a0112012-10-22 12:22:55 +02004625
4626 return 1;
4627}
4628
Emeric Brun645ae792014-04-30 14:21:06 +02004629/* boolean, returns true if front conn. transport layer is SSL.
4630 * This function is also usable on backend conn if the fetch keyword 5th
4631 * char is 'b'.
4632 */
Willy Tarreau7875d092012-09-10 08:20:03 +02004633static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004634smp_fetch_ssl_fc(const struct arg *args, struct sample *smp, const char *kw, void *private)
Willy Tarreau7875d092012-09-10 08:20:03 +02004635{
Willy Tarreaue237fe12016-03-10 17:05:28 +01004636 struct connection *conn = objt_conn((kw[4] != 'b') ? smp->sess->origin :
4637 smp->strm ? smp->strm->si[1].end : NULL);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004638
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004639 smp->data.type = SMP_T_BOOL;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004640 smp->data.u.sint = (conn && conn->xprt == &ssl_sock);
Willy Tarreau7875d092012-09-10 08:20:03 +02004641 return 1;
4642}
4643
Emeric Brun2525b6b2012-10-18 15:59:43 +02004644/* boolean, returns true if client present a SNI */
Willy Tarreau7875d092012-09-10 08:20:03 +02004645static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004646smp_fetch_ssl_fc_has_sni(const struct arg *args, struct sample *smp, const char *kw, void *private)
Willy Tarreau7875d092012-09-10 08:20:03 +02004647{
4648#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004649 struct connection *conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004650
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004651 smp->data.type = SMP_T_BOOL;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004652 smp->data.u.sint = (conn && conn->xprt == &ssl_sock) &&
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004653 conn->xprt_ctx &&
4654 SSL_get_servername(conn->xprt_ctx, TLSEXT_NAMETYPE_host_name) != NULL;
Willy Tarreau7875d092012-09-10 08:20:03 +02004655 return 1;
4656#else
4657 return 0;
4658#endif
4659}
4660
Nenad Merdanovic26ea8222015-05-18 02:28:57 +02004661/* boolean, returns true if client session has been resumed */
4662static int
4663smp_fetch_ssl_fc_is_resumed(const struct arg *args, struct sample *smp, const char *kw, void *private)
4664{
4665 struct connection *conn = objt_conn(smp->sess->origin);
4666
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004667 smp->data.type = SMP_T_BOOL;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004668 smp->data.u.sint = (conn && conn->xprt == &ssl_sock) &&
Nenad Merdanovic26ea8222015-05-18 02:28:57 +02004669 conn->xprt_ctx &&
4670 SSL_session_reused(conn->xprt_ctx);
4671 return 1;
4672}
4673
Emeric Brun645ae792014-04-30 14:21:06 +02004674/* string, returns the used cipher if front conn. transport layer is SSL.
4675 * This function is also usable on backend conn if the fetch keyword 5th
4676 * char is 'b'.
4677 */
Emeric Brun589fcad2012-10-16 14:13:26 +02004678static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004679smp_fetch_ssl_fc_cipher(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun589fcad2012-10-16 14:13:26 +02004680{
Willy Tarreaue237fe12016-03-10 17:05:28 +01004681 struct connection *conn = objt_conn((kw[4] != 'b') ? smp->sess->origin :
4682 smp->strm ? smp->strm->si[1].end : NULL);
Emeric Brun589fcad2012-10-16 14:13:26 +02004683
Willy Tarreaube508f12016-03-10 11:47:01 +01004684 smp->flags = 0;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004685 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
Emeric Brun589fcad2012-10-16 14:13:26 +02004686 return 0;
4687
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004688 smp->data.u.str.str = (char *)SSL_get_cipher_name(conn->xprt_ctx);
4689 if (!smp->data.u.str.str)
Emeric Brun589fcad2012-10-16 14:13:26 +02004690 return 0;
4691
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004692 smp->data.type = SMP_T_STR;
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01004693 smp->flags |= SMP_F_CONST;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004694 smp->data.u.str.len = strlen(smp->data.u.str.str);
Emeric Brun589fcad2012-10-16 14:13:26 +02004695
4696 return 1;
4697}
4698
Emeric Brun645ae792014-04-30 14:21:06 +02004699/* integer, returns the algoritm's keysize if front conn. transport layer
4700 * is SSL.
4701 * This function is also usable on backend conn if the fetch keyword 5th
4702 * char is 'b'.
4703 */
Emeric Brun589fcad2012-10-16 14:13:26 +02004704static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004705smp_fetch_ssl_fc_alg_keysize(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun589fcad2012-10-16 14:13:26 +02004706{
Willy Tarreaue237fe12016-03-10 17:05:28 +01004707 struct connection *conn = objt_conn((kw[4] != 'b') ? smp->sess->origin :
4708 smp->strm ? smp->strm->si[1].end : NULL);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004709
Willy Tarreaue237fe12016-03-10 17:05:28 +01004710 int sint;
Willy Tarreaube508f12016-03-10 11:47:01 +01004711
Emeric Brun589fcad2012-10-16 14:13:26 +02004712 smp->flags = 0;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004713 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
Emeric Brun589fcad2012-10-16 14:13:26 +02004714 return 0;
4715
Thierry FOURNIER07ee64e2015-07-06 23:43:03 +02004716 if (!SSL_get_cipher_bits(conn->xprt_ctx, &sint))
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004717 return 0;
4718
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004719 smp->data.u.sint = sint;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004720 smp->data.type = SMP_T_SINT;
Emeric Brun589fcad2012-10-16 14:13:26 +02004721
4722 return 1;
4723}
4724
Emeric Brun645ae792014-04-30 14:21:06 +02004725/* integer, returns the used keysize if front conn. transport layer is SSL.
4726 * This function is also usable on backend conn if the fetch keyword 5th
4727 * char is 'b'.
4728 */
Emeric Brun589fcad2012-10-16 14:13:26 +02004729static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004730smp_fetch_ssl_fc_use_keysize(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun589fcad2012-10-16 14:13:26 +02004731{
Willy Tarreaue237fe12016-03-10 17:05:28 +01004732 struct connection *conn = objt_conn((kw[4] != 'b') ? smp->sess->origin :
4733 smp->strm ? smp->strm->si[1].end : NULL);
Willy Tarreaube508f12016-03-10 11:47:01 +01004734
Emeric Brun589fcad2012-10-16 14:13:26 +02004735 smp->flags = 0;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004736 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
4737 return 0;
4738
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004739 smp->data.u.sint = (unsigned int)SSL_get_cipher_bits(conn->xprt_ctx, NULL);
4740 if (!smp->data.u.sint)
Emeric Brun589fcad2012-10-16 14:13:26 +02004741 return 0;
4742
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004743 smp->data.type = SMP_T_SINT;
Emeric Brun589fcad2012-10-16 14:13:26 +02004744
4745 return 1;
4746}
4747
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02004748#ifdef OPENSSL_NPN_NEGOTIATED
Willy Tarreau7875d092012-09-10 08:20:03 +02004749static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004750smp_fetch_ssl_fc_npn(const struct arg *args, struct sample *smp, const char *kw, void *private)
Willy Tarreaua33c6542012-10-15 13:19:06 +02004751{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004752 struct connection *conn;
4753
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01004754 smp->flags = SMP_F_CONST;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004755 smp->data.type = SMP_T_STR;
Willy Tarreaua33c6542012-10-15 13:19:06 +02004756
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004757 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004758 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
4759 return 0;
4760
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004761 smp->data.u.str.str = NULL;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004762 SSL_get0_next_proto_negotiated(conn->xprt_ctx,
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004763 (const unsigned char **)&smp->data.u.str.str, (unsigned *)&smp->data.u.str.len);
Willy Tarreaua33c6542012-10-15 13:19:06 +02004764
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004765 if (!smp->data.u.str.str)
Willy Tarreaua33c6542012-10-15 13:19:06 +02004766 return 0;
4767
4768 return 1;
Willy Tarreaua33c6542012-10-15 13:19:06 +02004769}
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02004770#endif
Willy Tarreaua33c6542012-10-15 13:19:06 +02004771
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01004772#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Willy Tarreauab861d32013-04-02 02:30:41 +02004773static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004774smp_fetch_ssl_fc_alpn(const struct arg *args, struct sample *smp, const char *kw, void *private)
Willy Tarreauab861d32013-04-02 02:30:41 +02004775{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004776 struct connection *conn;
4777
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01004778 smp->flags = SMP_F_CONST;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004779 smp->data.type = SMP_T_STR;
Willy Tarreauab861d32013-04-02 02:30:41 +02004780
Willy Tarreaue26bf052015-05-12 10:30:12 +02004781 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004782 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
Willy Tarreauab861d32013-04-02 02:30:41 +02004783 return 0;
4784
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004785 smp->data.u.str.str = NULL;
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01004786 SSL_get0_alpn_selected(conn->xprt_ctx,
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004787 (const unsigned char **)&smp->data.u.str.str, (unsigned *)&smp->data.u.str.len);
Willy Tarreauab861d32013-04-02 02:30:41 +02004788
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004789 if (!smp->data.u.str.str)
Willy Tarreauab861d32013-04-02 02:30:41 +02004790 return 0;
4791
4792 return 1;
4793}
4794#endif
4795
Emeric Brun645ae792014-04-30 14:21:06 +02004796/* string, returns the used protocol if front conn. transport layer is SSL.
4797 * This function is also usable on backend conn if the fetch keyword 5th
4798 * char is 'b'.
4799 */
Willy Tarreaua33c6542012-10-15 13:19:06 +02004800static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004801smp_fetch_ssl_fc_protocol(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun589fcad2012-10-16 14:13:26 +02004802{
Willy Tarreaue237fe12016-03-10 17:05:28 +01004803 struct connection *conn = objt_conn((kw[4] != 'b') ? smp->sess->origin :
4804 smp->strm ? smp->strm->si[1].end : NULL);
Willy Tarreaube508f12016-03-10 11:47:01 +01004805
Emeric Brun589fcad2012-10-16 14:13:26 +02004806 smp->flags = 0;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004807 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
4808 return 0;
4809
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004810 smp->data.u.str.str = (char *)SSL_get_version(conn->xprt_ctx);
4811 if (!smp->data.u.str.str)
Emeric Brun589fcad2012-10-16 14:13:26 +02004812 return 0;
4813
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004814 smp->data.type = SMP_T_STR;
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01004815 smp->flags = SMP_F_CONST;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004816 smp->data.u.str.len = strlen(smp->data.u.str.str);
Emeric Brun589fcad2012-10-16 14:13:26 +02004817
4818 return 1;
4819}
4820
Willy Tarreau87b09662015-04-03 00:22:06 +02004821/* binary, returns the SSL stream id if front conn. transport layer is SSL.
Emeric Brun645ae792014-04-30 14:21:06 +02004822 * This function is also usable on backend conn if the fetch keyword 5th
4823 * char is 'b'.
4824 */
Emeric Brun589fcad2012-10-16 14:13:26 +02004825static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004826smp_fetch_ssl_fc_session_id(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brunfe68f682012-10-16 14:59:28 +02004827{
4828#if OPENSSL_VERSION_NUMBER > 0x0090800fL
Willy Tarreaue237fe12016-03-10 17:05:28 +01004829 struct connection *conn = objt_conn((kw[4] != 'b') ? smp->sess->origin :
4830 smp->strm ? smp->strm->si[1].end : NULL);
Emeric Brunfe68f682012-10-16 14:59:28 +02004831
Willy Tarreaue237fe12016-03-10 17:05:28 +01004832 SSL_SESSION *ssl_sess;
Willy Tarreaube508f12016-03-10 11:47:01 +01004833
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01004834 smp->flags = SMP_F_CONST;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004835 smp->data.type = SMP_T_BIN;
Emeric Brunfe68f682012-10-16 14:59:28 +02004836
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004837 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
4838 return 0;
4839
Willy Tarreau192252e2015-04-04 01:47:55 +02004840 ssl_sess = SSL_get_session(conn->xprt_ctx);
4841 if (!ssl_sess)
Emeric Brunfe68f682012-10-16 14:59:28 +02004842 return 0;
4843
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004844 smp->data.u.str.str = (char *)SSL_SESSION_get_id(ssl_sess, (unsigned int *)&smp->data.u.str.len);
4845 if (!smp->data.u.str.str || !smp->data.u.str.len)
Emeric Brunfe68f682012-10-16 14:59:28 +02004846 return 0;
4847
4848 return 1;
4849#else
4850 return 0;
4851#endif
4852}
4853
4854static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004855smp_fetch_ssl_fc_sni(const struct arg *args, struct sample *smp, const char *kw, void *private)
Willy Tarreau7875d092012-09-10 08:20:03 +02004856{
4857#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004858 struct connection *conn;
4859
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01004860 smp->flags = SMP_F_CONST;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004861 smp->data.type = SMP_T_STR;
Willy Tarreau7875d092012-09-10 08:20:03 +02004862
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004863 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004864 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
4865 return 0;
4866
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004867 smp->data.u.str.str = (char *)SSL_get_servername(conn->xprt_ctx, TLSEXT_NAMETYPE_host_name);
4868 if (!smp->data.u.str.str)
Willy Tarreau3e394c92012-09-14 23:56:58 +02004869 return 0;
4870
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004871 smp->data.u.str.len = strlen(smp->data.u.str.str);
Willy Tarreau7875d092012-09-10 08:20:03 +02004872 return 1;
4873#else
4874 return 0;
4875#endif
4876}
4877
David Sc1ad52e2014-04-08 18:48:47 -04004878static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004879smp_fetch_ssl_fc_unique_id(const struct arg *args, struct sample *smp, const char *kw, void *private)
David Sc1ad52e2014-04-08 18:48:47 -04004880{
4881#if OPENSSL_VERSION_NUMBER > 0x0090800fL
Willy Tarreaue237fe12016-03-10 17:05:28 +01004882 struct connection *conn = objt_conn((kw[4] != 'b') ? smp->sess->origin :
4883 smp->strm ? smp->strm->si[1].end : NULL);
4884
David Sc1ad52e2014-04-08 18:48:47 -04004885 int finished_len;
David Sc1ad52e2014-04-08 18:48:47 -04004886 struct chunk *finished_trash;
David Sc1ad52e2014-04-08 18:48:47 -04004887
4888 smp->flags = 0;
David Sc1ad52e2014-04-08 18:48:47 -04004889 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
4890 return 0;
4891
4892 if (!(conn->flags & CO_FL_CONNECTED)) {
4893 smp->flags |= SMP_F_MAY_CHANGE;
4894 return 0;
4895 }
4896
4897 finished_trash = get_trash_chunk();
4898 if (!SSL_session_reused(conn->xprt_ctx))
4899 finished_len = SSL_get_peer_finished(conn->xprt_ctx, finished_trash->str, finished_trash->size);
4900 else
4901 finished_len = SSL_get_finished(conn->xprt_ctx, finished_trash->str, finished_trash->size);
4902
4903 if (!finished_len)
4904 return 0;
4905
Emeric Brunb73a9b02014-04-30 18:49:19 +02004906 finished_trash->len = finished_len;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004907 smp->data.u.str = *finished_trash;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004908 smp->data.type = SMP_T_BIN;
David Sc1ad52e2014-04-08 18:48:47 -04004909
4910 return 1;
4911#else
4912 return 0;
4913#endif
4914}
4915
Emeric Brun2525b6b2012-10-18 15:59:43 +02004916/* integer, returns the first verify error in CA chain of client certificate chain. */
Emeric Brunf282a812012-09-21 15:27:54 +02004917static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004918smp_fetch_ssl_c_ca_err(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brunf282a812012-09-21 15:27:54 +02004919{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004920 struct connection *conn;
4921
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004922 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004923 if (!conn || conn->xprt != &ssl_sock)
4924 return 0;
4925
4926 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunf282a812012-09-21 15:27:54 +02004927 smp->flags = SMP_F_MAY_CHANGE;
4928 return 0;
4929 }
4930
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004931 smp->data.type = SMP_T_SINT;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004932 smp->data.u.sint = (unsigned long long int)SSL_SOCK_ST_TO_CA_ERROR(conn->xprt_st);
Emeric Brunf282a812012-09-21 15:27:54 +02004933 smp->flags = 0;
4934
4935 return 1;
4936}
4937
Emeric Brun2525b6b2012-10-18 15:59:43 +02004938/* integer, returns the depth of the first verify error in CA chain of client certificate chain. */
Emeric Brunf282a812012-09-21 15:27:54 +02004939static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004940smp_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 +02004941{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004942 struct connection *conn;
4943
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004944 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004945 if (!conn || conn->xprt != &ssl_sock)
Emeric Brunf282a812012-09-21 15:27:54 +02004946 return 0;
4947
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004948 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunf282a812012-09-21 15:27:54 +02004949 smp->flags = SMP_F_MAY_CHANGE;
4950 return 0;
4951 }
4952
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004953 smp->data.type = SMP_T_SINT;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004954 smp->data.u.sint = (long long int)SSL_SOCK_ST_TO_CAEDEPTH(conn->xprt_st);
Emeric Brunf282a812012-09-21 15:27:54 +02004955 smp->flags = 0;
4956
4957 return 1;
4958}
4959
Emeric Brun2525b6b2012-10-18 15:59:43 +02004960/* integer, returns the first verify error on client certificate */
Emeric Brunf282a812012-09-21 15:27:54 +02004961static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004962smp_fetch_ssl_c_err(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brunf282a812012-09-21 15:27:54 +02004963{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004964 struct connection *conn;
4965
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004966 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004967 if (!conn || conn->xprt != &ssl_sock)
4968 return 0;
4969
4970 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunf282a812012-09-21 15:27:54 +02004971 smp->flags = SMP_F_MAY_CHANGE;
4972 return 0;
4973 }
4974
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004975 smp->data.type = SMP_T_SINT;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004976 smp->data.u.sint = (long long int)SSL_SOCK_ST_TO_CRTERROR(conn->xprt_st);
Emeric Brunf282a812012-09-21 15:27:54 +02004977 smp->flags = 0;
4978
4979 return 1;
4980}
4981
Emeric Brun2525b6b2012-10-18 15:59:43 +02004982/* integer, returns the verify result on client cert */
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02004983static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004984smp_fetch_ssl_c_verify(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02004985{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004986 struct connection *conn;
4987
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004988 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004989 if (!conn || conn->xprt != &ssl_sock)
4990 return 0;
4991
4992 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02004993 smp->flags = SMP_F_MAY_CHANGE;
4994 return 0;
4995 }
4996
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004997 if (!conn->xprt_ctx)
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02004998 return 0;
4999
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005000 smp->data.type = SMP_T_SINT;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005001 smp->data.u.sint = (long long int)SSL_get_verify_result(conn->xprt_ctx);
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02005002 smp->flags = 0;
5003
5004 return 1;
5005}
5006
Emeric Brunfb510ea2012-10-05 12:00:26 +02005007/* parse the "ca-file" bind keyword */
5008static 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 +02005009{
5010 if (!*args[cur_arg + 1]) {
5011 if (err)
5012 memprintf(err, "'%s' : missing CAfile path", args[cur_arg]);
5013 return ERR_ALERT | ERR_FATAL;
5014 }
5015
Emeric Brunef42d922012-10-11 16:11:36 +02005016 if ((*args[cur_arg + 1] != '/') && global.ca_base)
5017 memprintf(&conf->ca_file, "%s/%s", global.ca_base, args[cur_arg + 1]);
5018 else
5019 memprintf(&conf->ca_file, "%s", args[cur_arg + 1]);
Emeric Brunc8e8d122012-10-02 18:42:10 +02005020
Emeric Brund94b3fe2012-09-20 18:23:56 +02005021 return 0;
5022}
5023
Christopher Faulet31af49d2015-06-09 17:29:50 +02005024/* parse the "ca-sign-file" bind keyword */
5025static int bind_parse_ca_sign_file(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5026{
5027 if (!*args[cur_arg + 1]) {
5028 if (err)
5029 memprintf(err, "'%s' : missing CAfile path", args[cur_arg]);
5030 return ERR_ALERT | ERR_FATAL;
5031 }
5032
5033 if ((*args[cur_arg + 1] != '/') && global.ca_base)
5034 memprintf(&conf->ca_sign_file, "%s/%s", global.ca_base, args[cur_arg + 1]);
5035 else
5036 memprintf(&conf->ca_sign_file, "%s", args[cur_arg + 1]);
5037
5038 return 0;
5039}
5040
5041/* parse the ca-sign-pass bind keyword */
5042
5043static int bind_parse_ca_sign_pass(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5044{
5045 if (!*args[cur_arg + 1]) {
5046 if (err)
5047 memprintf(err, "'%s' : missing CAkey password", args[cur_arg]);
5048 return ERR_ALERT | ERR_FATAL;
5049 }
5050 memprintf(&conf->ca_sign_pass, "%s", args[cur_arg + 1]);
5051 return 0;
5052}
5053
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005054/* parse the "ciphers" bind keyword */
Willy Tarreau4348fad2012-09-20 16:48:07 +02005055static 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 +02005056{
5057 if (!*args[cur_arg + 1]) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02005058 memprintf(err, "'%s' : missing cipher suite", args[cur_arg]);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005059 return ERR_ALERT | ERR_FATAL;
5060 }
5061
Emeric Brun76d88952012-10-05 15:47:31 +02005062 free(conf->ciphers);
Willy Tarreau4348fad2012-09-20 16:48:07 +02005063 conf->ciphers = strdup(args[cur_arg + 1]);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005064 return 0;
5065}
5066
5067/* parse the "crt" bind keyword */
Willy Tarreau4348fad2012-09-20 16:48:07 +02005068static 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 +02005069{
Willy Tarreau38011032013-08-13 16:59:39 +02005070 char path[MAXPATHLEN];
Willy Tarreaub75d6922014-04-14 18:05:41 +02005071
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005072 if (!*args[cur_arg + 1]) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02005073 memprintf(err, "'%s' : missing certificate location", args[cur_arg]);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005074 return ERR_ALERT | ERR_FATAL;
5075 }
5076
Emeric Brunc8e8d122012-10-02 18:42:10 +02005077 if ((*args[cur_arg + 1] != '/' ) && global.crt_base) {
Willy Tarreau38011032013-08-13 16:59:39 +02005078 if ((strlen(global.crt_base) + 1 + strlen(args[cur_arg + 1]) + 1) > MAXPATHLEN) {
Emeric Brunc8e8d122012-10-02 18:42:10 +02005079 memprintf(err, "'%s' : path too long", args[cur_arg]);
5080 return ERR_ALERT | ERR_FATAL;
5081 }
Willy Tarreaub75d6922014-04-14 18:05:41 +02005082 snprintf(path, sizeof(path), "%s/%s", global.crt_base, args[cur_arg + 1]);
Emeric Brunc8e8d122012-10-02 18:42:10 +02005083 if (ssl_sock_load_cert(path, conf, px, err) > 0)
5084 return ERR_ALERT | ERR_FATAL;
5085
5086 return 0;
5087 }
5088
Willy Tarreau4348fad2012-09-20 16:48:07 +02005089 if (ssl_sock_load_cert(args[cur_arg + 1], conf, px, err) > 0)
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005090 return ERR_ALERT | ERR_FATAL;
Emeric Brund94b3fe2012-09-20 18:23:56 +02005091
5092 return 0;
5093}
5094
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01005095/* parse the "crt-list" bind keyword */
5096static int bind_parse_crt_list(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5097{
5098 if (!*args[cur_arg + 1]) {
5099 memprintf(err, "'%s' : missing certificate location", args[cur_arg]);
5100 return ERR_ALERT | ERR_FATAL;
5101 }
5102
Willy Tarreauad1731d2013-04-02 17:35:58 +02005103 if (ssl_sock_load_cert_list_file(args[cur_arg + 1], conf, px, err) > 0) {
5104 memprintf(err, "'%s' : %s", args[cur_arg], *err);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01005105 return ERR_ALERT | ERR_FATAL;
Willy Tarreauad1731d2013-04-02 17:35:58 +02005106 }
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01005107
5108 return 0;
5109}
5110
Emeric Brunfb510ea2012-10-05 12:00:26 +02005111/* parse the "crl-file" bind keyword */
5112static 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 +02005113{
Emeric Brun051cdab2012-10-02 19:25:50 +02005114#ifndef X509_V_FLAG_CRL_CHECK
5115 if (err)
5116 memprintf(err, "'%s' : library does not support CRL verify", args[cur_arg]);
5117 return ERR_ALERT | ERR_FATAL;
5118#else
Emeric Brund94b3fe2012-09-20 18:23:56 +02005119 if (!*args[cur_arg + 1]) {
5120 if (err)
5121 memprintf(err, "'%s' : missing CRLfile path", args[cur_arg]);
5122 return ERR_ALERT | ERR_FATAL;
5123 }
Emeric Brun2b58d042012-09-20 17:10:03 +02005124
Emeric Brunef42d922012-10-11 16:11:36 +02005125 if ((*args[cur_arg + 1] != '/') && global.ca_base)
5126 memprintf(&conf->crl_file, "%s/%s", global.ca_base, args[cur_arg + 1]);
5127 else
5128 memprintf(&conf->crl_file, "%s", args[cur_arg + 1]);
Emeric Brunc8e8d122012-10-02 18:42:10 +02005129
Emeric Brun2b58d042012-09-20 17:10:03 +02005130 return 0;
Emeric Brun051cdab2012-10-02 19:25:50 +02005131#endif
Emeric Brun2b58d042012-09-20 17:10:03 +02005132}
5133
5134/* parse the "ecdhe" bind keyword keywords */
5135static int bind_parse_ecdhe(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5136{
5137#if OPENSSL_VERSION_NUMBER < 0x0090800fL
5138 if (err)
5139 memprintf(err, "'%s' : library does not support elliptic curve Diffie-Hellman (too old)", args[cur_arg]);
5140 return ERR_ALERT | ERR_FATAL;
5141#elif defined(OPENSSL_NO_ECDH)
5142 if (err)
5143 memprintf(err, "'%s' : library does not support elliptic curve Diffie-Hellman (disabled via OPENSSL_NO_ECDH)", args[cur_arg]);
5144 return ERR_ALERT | ERR_FATAL;
5145#else
5146 if (!*args[cur_arg + 1]) {
5147 if (err)
5148 memprintf(err, "'%s' : missing named curve", args[cur_arg]);
5149 return ERR_ALERT | ERR_FATAL;
5150 }
5151
5152 conf->ecdhe = strdup(args[cur_arg + 1]);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005153
5154 return 0;
Emeric Brun2b58d042012-09-20 17:10:03 +02005155#endif
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005156}
5157
Emeric Brun81c00f02012-09-21 14:31:21 +02005158/* parse the "crt_ignerr" and "ca_ignerr" bind keywords */
5159static int bind_parse_ignore_err(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5160{
5161 int code;
5162 char *p = args[cur_arg + 1];
5163 unsigned long long *ignerr = &conf->crt_ignerr;
5164
5165 if (!*p) {
5166 if (err)
5167 memprintf(err, "'%s' : missing error IDs list", args[cur_arg]);
5168 return ERR_ALERT | ERR_FATAL;
5169 }
5170
5171 if (strcmp(args[cur_arg], "ca-ignore-err") == 0)
5172 ignerr = &conf->ca_ignerr;
5173
5174 if (strcmp(p, "all") == 0) {
5175 *ignerr = ~0ULL;
5176 return 0;
5177 }
5178
5179 while (p) {
5180 code = atoi(p);
5181 if ((code <= 0) || (code > 63)) {
5182 if (err)
5183 memprintf(err, "'%s' : ID '%d' out of range (1..63) in error IDs list '%s'",
5184 args[cur_arg], code, args[cur_arg + 1]);
5185 return ERR_ALERT | ERR_FATAL;
5186 }
5187 *ignerr |= 1ULL << code;
5188 p = strchr(p, ',');
5189 if (p)
5190 p++;
5191 }
5192
Emeric Brun2cb7ae52012-10-05 14:14:21 +02005193 return 0;
5194}
5195
5196/* parse the "force-sslv3" bind keyword */
5197static int bind_parse_force_sslv3(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5198{
5199 conf->ssl_options |= BC_SSL_O_USE_SSLV3;
5200 return 0;
5201}
5202
5203/* parse the "force-tlsv10" bind keyword */
5204static int bind_parse_force_tlsv10(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5205{
5206 conf->ssl_options |= BC_SSL_O_USE_TLSV10;
Emeric Brun2d0c4822012-10-02 13:45:20 +02005207 return 0;
5208}
5209
Emeric Brun2cb7ae52012-10-05 14:14:21 +02005210/* parse the "force-tlsv11" bind keyword */
5211static int bind_parse_force_tlsv11(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5212{
5213#if SSL_OP_NO_TLSv1_1
5214 conf->ssl_options |= BC_SSL_O_USE_TLSV11;
5215 return 0;
5216#else
5217 if (err)
5218 memprintf(err, "'%s' : library does not support protocol TLSv1.1", args[cur_arg]);
5219 return ERR_ALERT | ERR_FATAL;
5220#endif
5221}
5222
5223/* parse the "force-tlsv12" bind keyword */
5224static int bind_parse_force_tlsv12(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5225{
5226#if SSL_OP_NO_TLSv1_2
5227 conf->ssl_options |= BC_SSL_O_USE_TLSV12;
5228 return 0;
5229#else
5230 if (err)
5231 memprintf(err, "'%s' : library does not support protocol TLSv1.2", args[cur_arg]);
5232 return ERR_ALERT | ERR_FATAL;
5233#endif
5234}
5235
5236
Emeric Brun2d0c4822012-10-02 13:45:20 +02005237/* parse the "no-tls-tickets" bind keyword */
5238static int bind_parse_no_tls_tickets(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5239{
Emeric Brun89675492012-10-05 13:48:26 +02005240 conf->ssl_options |= BC_SSL_O_NO_TLS_TICKETS;
Emeric Brun81c00f02012-09-21 14:31:21 +02005241 return 0;
5242}
5243
Emeric Brun2d0c4822012-10-02 13:45:20 +02005244
Emeric Brun9b3009b2012-10-05 11:55:06 +02005245/* parse the "no-sslv3" bind keyword */
5246static 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 +02005247{
Emeric Brun89675492012-10-05 13:48:26 +02005248 conf->ssl_options |= BC_SSL_O_NO_SSLV3;
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005249 return 0;
5250}
5251
Emeric Brun9b3009b2012-10-05 11:55:06 +02005252/* parse the "no-tlsv10" bind keyword */
5253static 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 +02005254{
Emeric Brun89675492012-10-05 13:48:26 +02005255 conf->ssl_options |= BC_SSL_O_NO_TLSV10;
Emeric Brunc0ff4922012-09-28 19:37:02 +02005256 return 0;
5257}
5258
Emeric Brun9b3009b2012-10-05 11:55:06 +02005259/* parse the "no-tlsv11" bind keyword */
5260static 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 +02005261{
Emeric Brun89675492012-10-05 13:48:26 +02005262 conf->ssl_options |= BC_SSL_O_NO_TLSV11;
Emeric Brunc0ff4922012-09-28 19:37:02 +02005263 return 0;
5264}
5265
Emeric Brun9b3009b2012-10-05 11:55:06 +02005266/* parse the "no-tlsv12" bind keyword */
5267static 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 +02005268{
Emeric Brun89675492012-10-05 13:48:26 +02005269 conf->ssl_options |= BC_SSL_O_NO_TLSV12;
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005270 return 0;
5271}
5272
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02005273/* parse the "npn" bind keyword */
5274static int bind_parse_npn(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5275{
5276#ifdef OPENSSL_NPN_NEGOTIATED
5277 char *p1, *p2;
5278
5279 if (!*args[cur_arg + 1]) {
5280 memprintf(err, "'%s' : missing the comma-delimited NPN protocol suite", args[cur_arg]);
5281 return ERR_ALERT | ERR_FATAL;
5282 }
5283
5284 free(conf->npn_str);
5285
Willy Tarreau3724da12016-02-12 17:11:12 +01005286 /* the NPN string is built as a suite of (<len> <name>)*,
5287 * so we reuse each comma to store the next <len> and need
5288 * one more for the end of the string.
5289 */
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02005290 conf->npn_len = strlen(args[cur_arg + 1]) + 1;
Willy Tarreau3724da12016-02-12 17:11:12 +01005291 conf->npn_str = calloc(1, conf->npn_len + 1);
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02005292 memcpy(conf->npn_str + 1, args[cur_arg + 1], conf->npn_len);
5293
5294 /* replace commas with the name length */
5295 p1 = conf->npn_str;
5296 p2 = p1 + 1;
5297 while (1) {
5298 p2 = memchr(p1 + 1, ',', conf->npn_str + conf->npn_len - (p1 + 1));
5299 if (!p2)
5300 p2 = p1 + 1 + strlen(p1 + 1);
5301
5302 if (p2 - (p1 + 1) > 255) {
5303 *p2 = '\0';
5304 memprintf(err, "'%s' : NPN protocol name too long : '%s'", args[cur_arg], p1 + 1);
5305 return ERR_ALERT | ERR_FATAL;
5306 }
5307
5308 *p1 = p2 - (p1 + 1);
5309 p1 = p2;
5310
5311 if (!*p2)
5312 break;
5313
5314 *(p2++) = '\0';
5315 }
5316 return 0;
5317#else
5318 if (err)
5319 memprintf(err, "'%s' : library does not support TLS NPN extension", args[cur_arg]);
5320 return ERR_ALERT | ERR_FATAL;
5321#endif
5322}
5323
Willy Tarreauab861d32013-04-02 02:30:41 +02005324/* parse the "alpn" bind keyword */
5325static int bind_parse_alpn(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5326{
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01005327#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Willy Tarreauab861d32013-04-02 02:30:41 +02005328 char *p1, *p2;
5329
5330 if (!*args[cur_arg + 1]) {
5331 memprintf(err, "'%s' : missing the comma-delimited ALPN protocol suite", args[cur_arg]);
5332 return ERR_ALERT | ERR_FATAL;
5333 }
5334
5335 free(conf->alpn_str);
5336
Marcoen Hirschbergbef60912016-02-12 17:05:24 +01005337 /* the ALPN string is built as a suite of (<len> <name>)*,
5338 * so we reuse each comma to store the next <len> and need
5339 * one more for the end of the string.
5340 */
Willy Tarreauab861d32013-04-02 02:30:41 +02005341 conf->alpn_len = strlen(args[cur_arg + 1]) + 1;
Marcoen Hirschbergbef60912016-02-12 17:05:24 +01005342 conf->alpn_str = calloc(1, conf->alpn_len + 1);
Willy Tarreauab861d32013-04-02 02:30:41 +02005343 memcpy(conf->alpn_str + 1, args[cur_arg + 1], conf->alpn_len);
5344
5345 /* replace commas with the name length */
5346 p1 = conf->alpn_str;
5347 p2 = p1 + 1;
5348 while (1) {
5349 p2 = memchr(p1 + 1, ',', conf->alpn_str + conf->alpn_len - (p1 + 1));
5350 if (!p2)
5351 p2 = p1 + 1 + strlen(p1 + 1);
5352
5353 if (p2 - (p1 + 1) > 255) {
5354 *p2 = '\0';
5355 memprintf(err, "'%s' : ALPN protocol name too long : '%s'", args[cur_arg], p1 + 1);
5356 return ERR_ALERT | ERR_FATAL;
5357 }
5358
5359 *p1 = p2 - (p1 + 1);
5360 p1 = p2;
5361
5362 if (!*p2)
5363 break;
5364
5365 *(p2++) = '\0';
5366 }
5367 return 0;
5368#else
5369 if (err)
5370 memprintf(err, "'%s' : library does not support TLS ALPN extension", args[cur_arg]);
5371 return ERR_ALERT | ERR_FATAL;
5372#endif
5373}
5374
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005375/* parse the "ssl" bind keyword */
Willy Tarreau4348fad2012-09-20 16:48:07 +02005376static 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 +02005377{
Willy Tarreau81796be2012-09-22 19:11:47 +02005378 struct listener *l;
5379
Willy Tarreau4348fad2012-09-20 16:48:07 +02005380 conf->is_ssl = 1;
Emeric Brun76d88952012-10-05 15:47:31 +02005381
5382 if (global.listen_default_ciphers && !conf->ciphers)
5383 conf->ciphers = strdup(global.listen_default_ciphers);
Emeric Brun2c86cbf2014-10-30 15:56:50 +01005384 conf->ssl_options |= global.listen_default_ssloptions;
Emeric Brun76d88952012-10-05 15:47:31 +02005385
Willy Tarreau81796be2012-09-22 19:11:47 +02005386 list_for_each_entry(l, &conf->listeners, by_bind)
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02005387 l->xprt = &ssl_sock;
Willy Tarreau81796be2012-09-22 19:11:47 +02005388
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005389 return 0;
5390}
5391
Christopher Faulet31af49d2015-06-09 17:29:50 +02005392/* parse the "generate-certificates" bind keyword */
5393static int bind_parse_generate_certs(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5394{
5395#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
5396 conf->generate_certs = 1;
5397#else
5398 memprintf(err, "%sthis version of openssl cannot generate SSL certificates.\n",
5399 err && *err ? *err : "");
5400#endif
5401 return 0;
5402}
5403
Emmanuel Hocdet65623372013-01-24 17:17:15 +01005404/* parse the "strict-sni" bind keyword */
5405static int bind_parse_strict_sni(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5406{
5407 conf->strict_sni = 1;
5408 return 0;
Nenad Merdanovic05552d42015-02-27 19:56:49 +01005409}
5410
5411/* parse the "tls-ticket-keys" bind keyword */
5412static int bind_parse_tls_ticket_keys(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5413{
5414#if (defined SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB && TLS_TICKETS_NO > 0)
5415 FILE *f;
5416 int i = 0;
5417 char thisline[LINESIZE];
Nenad Merdanovic146defa2015-05-09 08:46:00 +02005418 struct tls_keys_ref *keys_ref;
Nenad Merdanovic05552d42015-02-27 19:56:49 +01005419
5420 if (!*args[cur_arg + 1]) {
5421 if (err)
5422 memprintf(err, "'%s' : missing TLS ticket keys file path", args[cur_arg]);
5423 return ERR_ALERT | ERR_FATAL;
5424 }
5425
Nenad Merdanovic200b0fa2015-05-09 08:46:01 +02005426 keys_ref = tlskeys_ref_lookup(args[cur_arg + 1]);
5427 if(keys_ref) {
5428 conf->keys_ref = keys_ref;
5429 return 0;
5430 }
5431
Vincent Bernat02779b62016-04-03 13:48:43 +02005432 keys_ref = malloc(sizeof(*keys_ref));
Nenad Merdanovic146defa2015-05-09 08:46:00 +02005433 keys_ref->tlskeys = malloc(TLS_TICKETS_NO * sizeof(struct tls_sess_key));
Nenad Merdanovic05552d42015-02-27 19:56:49 +01005434
5435 if ((f = fopen(args[cur_arg + 1], "r")) == NULL) {
5436 if (err)
5437 memprintf(err, "'%s' : unable to load ssl tickets keys file", args[cur_arg+1]);
5438 return ERR_ALERT | ERR_FATAL;
5439 }
5440
Nenad Merdanovic146defa2015-05-09 08:46:00 +02005441 keys_ref->filename = strdup(args[cur_arg + 1]);
5442
Nenad Merdanovic05552d42015-02-27 19:56:49 +01005443 while (fgets(thisline, sizeof(thisline), f) != NULL) {
5444 int len = strlen(thisline);
5445 /* Strip newline characters from the end */
5446 if(thisline[len - 1] == '\n')
5447 thisline[--len] = 0;
5448
5449 if(thisline[len - 1] == '\r')
5450 thisline[--len] = 0;
5451
Nenad Merdanovic146defa2015-05-09 08:46:00 +02005452 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 +01005453 if (err)
5454 memprintf(err, "'%s' : unable to decode base64 key on line %d", args[cur_arg+1], i + 1);
mildis16aa0152016-06-22 17:46:29 +02005455 fclose(f);
Nenad Merdanovic05552d42015-02-27 19:56:49 +01005456 return ERR_ALERT | ERR_FATAL;
5457 }
5458 i++;
5459 }
5460
5461 if (i < TLS_TICKETS_NO) {
5462 if (err)
5463 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 +02005464 fclose(f);
Nenad Merdanovic05552d42015-02-27 19:56:49 +01005465 return ERR_ALERT | ERR_FATAL;
5466 }
5467
5468 fclose(f);
5469
5470 /* Use penultimate key for encryption, handle when TLS_TICKETS_NO = 1 */
Nenad Merdanovic17891152016-03-25 22:16:57 +01005471 i -= 2;
5472 keys_ref->tls_ticket_enc_index = i < 0 ? 0 : i % TLS_TICKETS_NO;
Nenad Merdanovic200b0fa2015-05-09 08:46:01 +02005473 keys_ref->unique_id = -1;
Nenad Merdanovic146defa2015-05-09 08:46:00 +02005474 conf->keys_ref = keys_ref;
Nenad Merdanovic05552d42015-02-27 19:56:49 +01005475
Nenad Merdanovic200b0fa2015-05-09 08:46:01 +02005476 LIST_ADD(&tlskeys_reference, &keys_ref->list);
5477
Nenad Merdanovic05552d42015-02-27 19:56:49 +01005478 return 0;
5479#else
5480 if (err)
5481 memprintf(err, "'%s' : TLS ticket callback extension not supported", args[cur_arg]);
5482 return ERR_ALERT | ERR_FATAL;
5483#endif /* SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB */
Emmanuel Hocdet65623372013-01-24 17:17:15 +01005484}
5485
Emeric Brund94b3fe2012-09-20 18:23:56 +02005486/* parse the "verify" bind keyword */
5487static int bind_parse_verify(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5488{
5489 if (!*args[cur_arg + 1]) {
5490 if (err)
5491 memprintf(err, "'%s' : missing verify method", args[cur_arg]);
5492 return ERR_ALERT | ERR_FATAL;
5493 }
5494
5495 if (strcmp(args[cur_arg + 1], "none") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01005496 conf->verify = SSL_SOCK_VERIFY_NONE;
Emeric Brund94b3fe2012-09-20 18:23:56 +02005497 else if (strcmp(args[cur_arg + 1], "optional") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01005498 conf->verify = SSL_SOCK_VERIFY_OPTIONAL;
Emeric Brund94b3fe2012-09-20 18:23:56 +02005499 else if (strcmp(args[cur_arg + 1], "required") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01005500 conf->verify = SSL_SOCK_VERIFY_REQUIRED;
Emeric Brund94b3fe2012-09-20 18:23:56 +02005501 else {
5502 if (err)
5503 memprintf(err, "'%s' : unknown verify method '%s', only 'none', 'optional', and 'required' are supported\n",
5504 args[cur_arg], args[cur_arg + 1]);
5505 return ERR_ALERT | ERR_FATAL;
5506 }
5507
5508 return 0;
5509}
5510
Willy Tarreau92faadf2012-10-10 23:04:25 +02005511/************** "server" keywords ****************/
5512
Emeric Brunef42d922012-10-11 16:11:36 +02005513/* parse the "ca-file" server keyword */
5514static int srv_parse_ca_file(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5515{
5516 if (!*args[*cur_arg + 1]) {
5517 if (err)
5518 memprintf(err, "'%s' : missing CAfile path", args[*cur_arg]);
5519 return ERR_ALERT | ERR_FATAL;
5520 }
5521
5522 if ((*args[*cur_arg + 1] != '/') && global.ca_base)
5523 memprintf(&newsrv->ssl_ctx.ca_file, "%s/%s", global.ca_base, args[*cur_arg + 1]);
5524 else
5525 memprintf(&newsrv->ssl_ctx.ca_file, "%s", args[*cur_arg + 1]);
5526
5527 return 0;
5528}
5529
Willy Tarreau92faadf2012-10-10 23:04:25 +02005530/* parse the "check-ssl" server keyword */
5531static int srv_parse_check_ssl(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5532{
5533 newsrv->check.use_ssl = 1;
5534 if (global.connect_default_ciphers && !newsrv->ssl_ctx.ciphers)
5535 newsrv->ssl_ctx.ciphers = strdup(global.connect_default_ciphers);
Emeric Brun2c86cbf2014-10-30 15:56:50 +01005536 newsrv->ssl_ctx.options |= global.connect_default_ssloptions;
Willy Tarreau92faadf2012-10-10 23:04:25 +02005537 return 0;
5538}
5539
5540/* parse the "ciphers" server keyword */
5541static int srv_parse_ciphers(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5542{
5543 if (!*args[*cur_arg + 1]) {
5544 memprintf(err, "'%s' : missing cipher suite", args[*cur_arg]);
5545 return ERR_ALERT | ERR_FATAL;
5546 }
5547
5548 free(newsrv->ssl_ctx.ciphers);
5549 newsrv->ssl_ctx.ciphers = strdup(args[*cur_arg + 1]);
5550 return 0;
5551}
5552
Emeric Brunef42d922012-10-11 16:11:36 +02005553/* parse the "crl-file" server keyword */
5554static int srv_parse_crl_file(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5555{
5556#ifndef X509_V_FLAG_CRL_CHECK
5557 if (err)
5558 memprintf(err, "'%s' : library does not support CRL verify", args[*cur_arg]);
5559 return ERR_ALERT | ERR_FATAL;
5560#else
5561 if (!*args[*cur_arg + 1]) {
5562 if (err)
5563 memprintf(err, "'%s' : missing CRLfile path", args[*cur_arg]);
5564 return ERR_ALERT | ERR_FATAL;
5565 }
5566
5567 if ((*args[*cur_arg + 1] != '/') && global.ca_base)
5568 memprintf(&newsrv->ssl_ctx.crl_file, "%s/%s", global.ca_base, args[*cur_arg + 1]);
5569 else
5570 memprintf(&newsrv->ssl_ctx.crl_file, "%s", args[*cur_arg + 1]);
5571
5572 return 0;
5573#endif
5574}
5575
Emeric Bruna7aa3092012-10-26 12:58:00 +02005576/* parse the "crt" server keyword */
5577static int srv_parse_crt(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5578{
5579 if (!*args[*cur_arg + 1]) {
5580 if (err)
5581 memprintf(err, "'%s' : missing certificate file path", args[*cur_arg]);
5582 return ERR_ALERT | ERR_FATAL;
5583 }
5584
5585 if ((*args[*cur_arg + 1] != '/') && global.crt_base)
5586 memprintf(&newsrv->ssl_ctx.client_crt, "%s/%s", global.ca_base, args[*cur_arg + 1]);
5587 else
5588 memprintf(&newsrv->ssl_ctx.client_crt, "%s", args[*cur_arg + 1]);
5589
5590 return 0;
5591}
Emeric Brunef42d922012-10-11 16:11:36 +02005592
Willy Tarreau92faadf2012-10-10 23:04:25 +02005593/* parse the "force-sslv3" server keyword */
5594static int srv_parse_force_sslv3(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5595{
5596 newsrv->ssl_ctx.options |= SRV_SSL_O_USE_SSLV3;
5597 return 0;
5598}
5599
5600/* parse the "force-tlsv10" server keyword */
5601static int srv_parse_force_tlsv10(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5602{
5603 newsrv->ssl_ctx.options |= SRV_SSL_O_USE_TLSV10;
5604 return 0;
5605}
5606
5607/* parse the "force-tlsv11" server keyword */
5608static int srv_parse_force_tlsv11(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5609{
5610#if SSL_OP_NO_TLSv1_1
5611 newsrv->ssl_ctx.options |= SRV_SSL_O_USE_TLSV11;
5612 return 0;
5613#else
5614 if (err)
5615 memprintf(err, "'%s' : library does not support protocol TLSv1.1", args[*cur_arg]);
5616 return ERR_ALERT | ERR_FATAL;
5617#endif
5618}
5619
5620/* parse the "force-tlsv12" server keyword */
5621static int srv_parse_force_tlsv12(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5622{
5623#if SSL_OP_NO_TLSv1_2
5624 newsrv->ssl_ctx.options |= SRV_SSL_O_USE_TLSV12;
5625 return 0;
5626#else
5627 if (err)
5628 memprintf(err, "'%s' : library does not support protocol TLSv1.2", args[*cur_arg]);
5629 return ERR_ALERT | ERR_FATAL;
5630#endif
5631}
5632
Willy Tarreau2a3fb1c2015-02-05 16:47:07 +01005633/* parse the "no-ssl-reuse" server keyword */
5634static int srv_parse_no_ssl_reuse(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5635{
5636 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_REUSE;
5637 return 0;
5638}
5639
Willy Tarreau92faadf2012-10-10 23:04:25 +02005640/* parse the "no-sslv3" server keyword */
5641static int srv_parse_no_sslv3(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5642{
5643 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_SSLV3;
5644 return 0;
5645}
5646
5647/* parse the "no-tlsv10" server keyword */
5648static int srv_parse_no_tlsv10(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5649{
5650 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_TLSV10;
5651 return 0;
5652}
5653
5654/* parse the "no-tlsv11" server keyword */
5655static int srv_parse_no_tlsv11(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5656{
5657 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_TLSV11;
5658 return 0;
5659}
5660
5661/* parse the "no-tlsv12" server keyword */
5662static int srv_parse_no_tlsv12(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5663{
5664 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_TLSV12;
5665 return 0;
5666}
5667
Emeric Brunf9c5c472012-10-11 15:28:34 +02005668/* parse the "no-tls-tickets" server keyword */
5669static int srv_parse_no_tls_tickets(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5670{
5671 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_TLS_TICKETS;
5672 return 0;
5673}
David Safb76832014-05-08 23:42:08 -04005674/* parse the "send-proxy-v2-ssl" server keyword */
5675static int srv_parse_send_proxy_ssl(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5676{
5677 newsrv->pp_opts |= SRV_PP_V2;
5678 newsrv->pp_opts |= SRV_PP_V2_SSL;
5679 return 0;
5680}
5681
5682/* parse the "send-proxy-v2-ssl-cn" server keyword */
5683static int srv_parse_send_proxy_cn(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5684{
5685 newsrv->pp_opts |= SRV_PP_V2;
5686 newsrv->pp_opts |= SRV_PP_V2_SSL;
5687 newsrv->pp_opts |= SRV_PP_V2_SSL_CN;
5688 return 0;
5689}
Emeric Brunf9c5c472012-10-11 15:28:34 +02005690
Willy Tarreau732eac42015-07-09 11:40:25 +02005691/* parse the "sni" server keyword */
5692static int srv_parse_sni(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5693{
5694#ifndef SSL_CTRL_SET_TLSEXT_HOSTNAME
5695 memprintf(err, "'%s' : the current SSL library doesn't support the SNI TLS extension", args[*cur_arg]);
5696 return ERR_ALERT | ERR_FATAL;
5697#else
Cyril Bonté23d19d62016-03-07 22:13:22 +01005698 int idx;
Willy Tarreau732eac42015-07-09 11:40:25 +02005699 struct sample_expr *expr;
5700
5701 if (!*args[*cur_arg + 1]) {
5702 memprintf(err, "'%s' : missing sni expression", args[*cur_arg]);
5703 return ERR_ALERT | ERR_FATAL;
5704 }
5705
Cyril Bonté23d19d62016-03-07 22:13:22 +01005706 idx = (*cur_arg) + 1;
Willy Tarreau732eac42015-07-09 11:40:25 +02005707 proxy->conf.args.ctx = ARGC_SRV;
5708
Cyril Bonté23d19d62016-03-07 22:13:22 +01005709 expr = sample_parse_expr((char **)args, &idx, px->conf.file, px->conf.line, err, &proxy->conf.args);
Willy Tarreau732eac42015-07-09 11:40:25 +02005710 if (!expr) {
5711 memprintf(err, "error detected while parsing sni expression : %s", *err);
5712 return ERR_ALERT | ERR_FATAL;
5713 }
5714
5715 if (!(expr->fetch->val & SMP_VAL_BE_SRV_CON)) {
5716 memprintf(err, "error detected while parsing sni expression : "
5717 " fetch method '%s' extracts information from '%s', none of which is available here.\n",
Cyril Bonté23d19d62016-03-07 22:13:22 +01005718 args[idx-1], sample_src_names(expr->fetch->use));
Willy Tarreau732eac42015-07-09 11:40:25 +02005719 return ERR_ALERT | ERR_FATAL;
5720 }
5721
5722 px->http_needed |= !!(expr->fetch->use & SMP_USE_HTTP_ANY);
5723 newsrv->ssl_ctx.sni = expr;
5724 return 0;
5725#endif
5726}
5727
Willy Tarreau92faadf2012-10-10 23:04:25 +02005728/* parse the "ssl" server keyword */
5729static int srv_parse_ssl(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5730{
5731 newsrv->use_ssl = 1;
5732 if (global.connect_default_ciphers && !newsrv->ssl_ctx.ciphers)
5733 newsrv->ssl_ctx.ciphers = strdup(global.connect_default_ciphers);
5734 return 0;
5735}
5736
Emeric Brunef42d922012-10-11 16:11:36 +02005737/* parse the "verify" server keyword */
5738static int srv_parse_verify(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5739{
5740 if (!*args[*cur_arg + 1]) {
5741 if (err)
5742 memprintf(err, "'%s' : missing verify method", args[*cur_arg]);
5743 return ERR_ALERT | ERR_FATAL;
5744 }
5745
5746 if (strcmp(args[*cur_arg + 1], "none") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01005747 newsrv->ssl_ctx.verify = SSL_SOCK_VERIFY_NONE;
Emeric Brunef42d922012-10-11 16:11:36 +02005748 else if (strcmp(args[*cur_arg + 1], "required") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01005749 newsrv->ssl_ctx.verify = SSL_SOCK_VERIFY_REQUIRED;
Emeric Brunef42d922012-10-11 16:11:36 +02005750 else {
5751 if (err)
5752 memprintf(err, "'%s' : unknown verify method '%s', only 'none' and 'required' are supported\n",
5753 args[*cur_arg], args[*cur_arg + 1]);
5754 return ERR_ALERT | ERR_FATAL;
5755 }
5756
Evan Broderbe554312013-06-27 00:05:25 -07005757 return 0;
5758}
5759
5760/* parse the "verifyhost" server keyword */
5761static int srv_parse_verifyhost(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5762{
5763 if (!*args[*cur_arg + 1]) {
5764 if (err)
5765 memprintf(err, "'%s' : missing hostname to verify against", args[*cur_arg]);
5766 return ERR_ALERT | ERR_FATAL;
5767 }
5768
5769 newsrv->ssl_ctx.verify_host = strdup(args[*cur_arg + 1]);
5770
Emeric Brunef42d922012-10-11 16:11:36 +02005771 return 0;
5772}
5773
Emeric Brun2c86cbf2014-10-30 15:56:50 +01005774/* parse the "ssl-default-bind-options" keyword in global section */
5775static int ssl_parse_default_bind_options(char **args, int section_type, struct proxy *curpx,
5776 struct proxy *defpx, const char *file, int line,
5777 char **err) {
5778 int i = 1;
5779
5780 if (*(args[i]) == 0) {
5781 memprintf(err, "global statement '%s' expects an option as an argument.", args[0]);
5782 return -1;
5783 }
5784 while (*(args[i])) {
5785 if (!strcmp(args[i], "no-sslv3"))
5786 global.listen_default_ssloptions |= BC_SSL_O_NO_SSLV3;
5787 else if (!strcmp(args[i], "no-tlsv10"))
5788 global.listen_default_ssloptions |= BC_SSL_O_NO_TLSV10;
5789 else if (!strcmp(args[i], "no-tlsv11"))
5790 global.listen_default_ssloptions |= BC_SSL_O_NO_TLSV11;
5791 else if (!strcmp(args[i], "no-tlsv12"))
5792 global.listen_default_ssloptions |= BC_SSL_O_NO_TLSV12;
5793 else if (!strcmp(args[i], "force-sslv3"))
5794 global.listen_default_ssloptions |= BC_SSL_O_USE_SSLV3;
5795 else if (!strcmp(args[i], "force-tlsv10"))
5796 global.listen_default_ssloptions |= BC_SSL_O_USE_TLSV10;
5797 else if (!strcmp(args[i], "force-tlsv11")) {
5798#if SSL_OP_NO_TLSv1_1
5799 global.listen_default_ssloptions |= BC_SSL_O_USE_TLSV11;
5800#else
5801 memprintf(err, "'%s' '%s': library does not support protocol TLSv1.1", args[0], args[i]);
5802 return -1;
5803#endif
5804 }
5805 else if (!strcmp(args[i], "force-tlsv12")) {
5806#if SSL_OP_NO_TLSv1_2
5807 global.listen_default_ssloptions |= BC_SSL_O_USE_TLSV12;
5808#else
5809 memprintf(err, "'%s' '%s': library does not support protocol TLSv1.2", args[0], args[i]);
5810 return -1;
5811#endif
5812 }
5813 else if (!strcmp(args[i], "no-tls-tickets"))
5814 global.listen_default_ssloptions |= BC_SSL_O_NO_TLS_TICKETS;
5815 else {
5816 memprintf(err, "unknown option '%s' on global statement '%s'.", args[i], args[0]);
5817 return -1;
5818 }
5819 i++;
5820 }
5821 return 0;
5822}
5823
5824/* parse the "ssl-default-server-options" keyword in global section */
5825static int ssl_parse_default_server_options(char **args, int section_type, struct proxy *curpx,
5826 struct proxy *defpx, const char *file, int line,
5827 char **err) {
5828 int i = 1;
5829
5830 if (*(args[i]) == 0) {
5831 memprintf(err, "global statement '%s' expects an option as an argument.", args[0]);
5832 return -1;
5833 }
5834 while (*(args[i])) {
5835 if (!strcmp(args[i], "no-sslv3"))
5836 global.connect_default_ssloptions |= SRV_SSL_O_NO_SSLV3;
5837 else if (!strcmp(args[i], "no-tlsv10"))
5838 global.connect_default_ssloptions |= SRV_SSL_O_NO_TLSV10;
5839 else if (!strcmp(args[i], "no-tlsv11"))
5840 global.connect_default_ssloptions |= SRV_SSL_O_NO_TLSV11;
5841 else if (!strcmp(args[i], "no-tlsv12"))
5842 global.connect_default_ssloptions |= SRV_SSL_O_NO_TLSV12;
5843 else if (!strcmp(args[i], "force-sslv3"))
5844 global.connect_default_ssloptions |= SRV_SSL_O_USE_SSLV3;
5845 else if (!strcmp(args[i], "force-tlsv10"))
5846 global.connect_default_ssloptions |= SRV_SSL_O_USE_TLSV10;
5847 else if (!strcmp(args[i], "force-tlsv11")) {
5848#if SSL_OP_NO_TLSv1_1
5849 global.connect_default_ssloptions |= SRV_SSL_O_USE_TLSV11;
5850#else
5851 memprintf(err, "'%s' '%s': library does not support protocol TLSv1.1", args[0], args[i]);
5852 return -1;
5853#endif
5854 }
5855 else if (!strcmp(args[i], "force-tlsv12")) {
5856#if SSL_OP_NO_TLSv1_2
5857 global.connect_default_ssloptions |= SRV_SSL_O_USE_TLSV12;
5858#else
5859 memprintf(err, "'%s' '%s': library does not support protocol TLSv1.2", args[0], args[i]);
5860 return -1;
5861#endif
5862 }
5863 else if (!strcmp(args[i], "no-tls-tickets"))
5864 global.connect_default_ssloptions |= SRV_SSL_O_NO_TLS_TICKETS;
5865 else {
5866 memprintf(err, "unknown option '%s' on global statement '%s'.", args[i], args[0]);
5867 return -1;
5868 }
5869 i++;
5870 }
5871 return 0;
5872}
5873
Willy Tarreau7875d092012-09-10 08:20:03 +02005874/* Note: must not be declared <const> as its list will be overwritten.
5875 * Please take care of keeping this list alphabetically sorted.
5876 */
Willy Tarreaudc13c112013-06-21 23:16:39 +02005877static struct sample_fetch_kw_list sample_fetch_keywords = {ILH, {
Emeric Brun645ae792014-04-30 14:21:06 +02005878 { "ssl_bc", smp_fetch_ssl_fc, 0, NULL, SMP_T_BOOL, SMP_USE_L5SRV },
Thierry FOURNIER07ee64e2015-07-06 23:43:03 +02005879 { "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 +02005880 { "ssl_bc_cipher", smp_fetch_ssl_fc_cipher, 0, NULL, SMP_T_STR, SMP_USE_L5SRV },
5881 { "ssl_bc_protocol", smp_fetch_ssl_fc_protocol, 0, NULL, SMP_T_STR, SMP_USE_L5SRV },
Emeric Brunb73a9b02014-04-30 18:49:19 +02005882 { "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 +02005883 { "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 +02005884 { "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 +02005885 { "ssl_c_ca_err", smp_fetch_ssl_c_ca_err, 0, NULL, SMP_T_SINT, SMP_USE_L5CLI },
5886 { "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 +01005887 { "ssl_c_der", smp_fetch_ssl_x_der, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Thierry FOURNIER07ee64e2015-07-06 23:43:03 +02005888 { "ssl_c_err", smp_fetch_ssl_c_err, 0, NULL, SMP_T_SINT, SMP_USE_L5CLI },
Emeric Brunba841a12014-04-30 17:05:08 +02005889 { "ssl_c_i_dn", smp_fetch_ssl_x_i_dn, ARG2(0,STR,SINT), NULL, SMP_T_STR, SMP_USE_L5CLI },
5890 { "ssl_c_key_alg", smp_fetch_ssl_x_key_alg, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
5891 { "ssl_c_notafter", smp_fetch_ssl_x_notafter, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
5892 { "ssl_c_notbefore", smp_fetch_ssl_x_notbefore, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
5893 { "ssl_c_sig_alg", smp_fetch_ssl_x_sig_alg, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
5894 { "ssl_c_s_dn", smp_fetch_ssl_x_s_dn, ARG2(0,STR,SINT), NULL, SMP_T_STR, SMP_USE_L5CLI },
5895 { "ssl_c_serial", smp_fetch_ssl_x_serial, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
5896 { "ssl_c_sha1", smp_fetch_ssl_x_sha1, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Willy Tarreau80aca902013-01-07 15:42:20 +01005897 { "ssl_c_used", smp_fetch_ssl_c_used, 0, NULL, SMP_T_BOOL, SMP_USE_L5CLI },
Thierry FOURNIER07ee64e2015-07-06 23:43:03 +02005898 { "ssl_c_verify", smp_fetch_ssl_c_verify, 0, NULL, SMP_T_SINT, SMP_USE_L5CLI },
5899 { "ssl_c_version", smp_fetch_ssl_x_version, 0, NULL, SMP_T_SINT, SMP_USE_L5CLI },
Emeric Brun43e79582014-10-29 19:03:26 +01005900 { "ssl_f_der", smp_fetch_ssl_x_der, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Emeric Brunba841a12014-04-30 17:05:08 +02005901 { "ssl_f_i_dn", smp_fetch_ssl_x_i_dn, ARG2(0,STR,SINT), NULL, SMP_T_STR, SMP_USE_L5CLI },
5902 { "ssl_f_key_alg", smp_fetch_ssl_x_key_alg, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
5903 { "ssl_f_notafter", smp_fetch_ssl_x_notafter, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
5904 { "ssl_f_notbefore", smp_fetch_ssl_x_notbefore, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
5905 { "ssl_f_sig_alg", smp_fetch_ssl_x_sig_alg, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
5906 { "ssl_f_s_dn", smp_fetch_ssl_x_s_dn, ARG2(0,STR,SINT), NULL, SMP_T_STR, SMP_USE_L5CLI },
5907 { "ssl_f_serial", smp_fetch_ssl_x_serial, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Emeric Brun55f4fa82014-04-30 17:11:25 +02005908 { "ssl_f_sha1", smp_fetch_ssl_x_sha1, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Thierry FOURNIER07ee64e2015-07-06 23:43:03 +02005909 { "ssl_f_version", smp_fetch_ssl_x_version, 0, NULL, SMP_T_SINT, SMP_USE_L5CLI },
Willy Tarreau80aca902013-01-07 15:42:20 +01005910 { "ssl_fc", smp_fetch_ssl_fc, 0, NULL, SMP_T_BOOL, SMP_USE_L5CLI },
Thierry FOURNIER07ee64e2015-07-06 23:43:03 +02005911 { "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 +01005912 { "ssl_fc_cipher", smp_fetch_ssl_fc_cipher, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Willy Tarreau80aca902013-01-07 15:42:20 +01005913 { "ssl_fc_has_crt", smp_fetch_ssl_fc_has_crt, 0, NULL, SMP_T_BOOL, SMP_USE_L5CLI },
5914 { "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 +02005915 { "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 +02005916#ifdef OPENSSL_NPN_NEGOTIATED
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01005917 { "ssl_fc_npn", smp_fetch_ssl_fc_npn, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Willy Tarreaua33c6542012-10-15 13:19:06 +02005918#endif
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01005919#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01005920 { "ssl_fc_alpn", smp_fetch_ssl_fc_alpn, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Willy Tarreauab861d32013-04-02 02:30:41 +02005921#endif
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01005922 { "ssl_fc_protocol", smp_fetch_ssl_fc_protocol, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Emeric Brunb73a9b02014-04-30 18:49:19 +02005923 { "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 +02005924 { "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 +01005925 { "ssl_fc_session_id", smp_fetch_ssl_fc_session_id, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
5926 { "ssl_fc_sni", smp_fetch_ssl_fc_sni, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Willy Tarreau7875d092012-09-10 08:20:03 +02005927 { NULL, NULL, 0, 0, 0 },
5928}};
5929
5930/* Note: must not be declared <const> as its list will be overwritten.
5931 * Please take care of keeping this list alphabetically sorted.
5932 */
Willy Tarreaudc13c112013-06-21 23:16:39 +02005933static struct acl_kw_list acl_kws = {ILH, {
Thierry FOURNIERc5a4e982014-03-05 16:07:08 +01005934 { "ssl_fc_sni_end", "ssl_fc_sni", PAT_MATCH_END },
5935 { "ssl_fc_sni_reg", "ssl_fc_sni", PAT_MATCH_REG },
Willy Tarreau8ed669b2013-01-11 15:49:37 +01005936 { /* END */ },
Willy Tarreau7875d092012-09-10 08:20:03 +02005937}};
5938
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005939/* Note: must not be declared <const> as its list will be overwritten.
5940 * Please take care of keeping this list alphabetically sorted, doing so helps
5941 * all code contributors.
5942 * Optional keywords are also declared with a NULL ->parse() function so that
5943 * the config parser can report an appropriate error when a known keyword was
5944 * not enabled.
5945 */
Willy Tarreau51fb7652012-09-18 18:24:39 +02005946static struct bind_kw_list bind_kws = { "SSL", { }, {
Nenad Merdanovic05552d42015-02-27 19:56:49 +01005947 { "alpn", bind_parse_alpn, 1 }, /* set ALPN supported protocols */
5948 { "ca-file", bind_parse_ca_file, 1 }, /* set CAfile to process verify on client cert */
5949 { "ca-ignore-err", bind_parse_ignore_err, 1 }, /* set error IDs to ignore on verify depth > 0 */
Christopher Faulet31af49d2015-06-09 17:29:50 +02005950 { "ca-sign-file", bind_parse_ca_sign_file, 1 }, /* set CAFile used to generate and sign server certs */
5951 { "ca-sign-pass", bind_parse_ca_sign_pass, 1 }, /* set CAKey passphrase */
Nenad Merdanovic05552d42015-02-27 19:56:49 +01005952 { "ciphers", bind_parse_ciphers, 1 }, /* set SSL cipher suite */
5953 { "crl-file", bind_parse_crl_file, 1 }, /* set certificat revocation list file use on client cert verify */
5954 { "crt", bind_parse_crt, 1 }, /* load SSL certificates from this location */
5955 { "crt-ignore-err", bind_parse_ignore_err, 1 }, /* set error IDs to ingore on verify depth == 0 */
5956 { "crt-list", bind_parse_crt_list, 1 }, /* load a list of crt from this location */
5957 { "ecdhe", bind_parse_ecdhe, 1 }, /* defines named curve for elliptic curve Diffie-Hellman */
5958 { "force-sslv3", bind_parse_force_sslv3, 0 }, /* force SSLv3 */
5959 { "force-tlsv10", bind_parse_force_tlsv10, 0 }, /* force TLSv10 */
5960 { "force-tlsv11", bind_parse_force_tlsv11, 0 }, /* force TLSv11 */
5961 { "force-tlsv12", bind_parse_force_tlsv12, 0 }, /* force TLSv12 */
Christopher Faulet31af49d2015-06-09 17:29:50 +02005962 { "generate-certificates", bind_parse_generate_certs, 0 }, /* enable the server certificates generation */
Nenad Merdanovic05552d42015-02-27 19:56:49 +01005963 { "no-sslv3", bind_parse_no_sslv3, 0 }, /* disable SSLv3 */
5964 { "no-tlsv10", bind_parse_no_tlsv10, 0 }, /* disable TLSv10 */
5965 { "no-tlsv11", bind_parse_no_tlsv11, 0 }, /* disable TLSv11 */
5966 { "no-tlsv12", bind_parse_no_tlsv12, 0 }, /* disable TLSv12 */
5967 { "no-tls-tickets", bind_parse_no_tls_tickets, 0 }, /* disable session resumption tickets */
5968 { "ssl", bind_parse_ssl, 0 }, /* enable SSL processing */
5969 { "strict-sni", bind_parse_strict_sni, 0 }, /* refuse negotiation if sni doesn't match a certificate */
5970 { "tls-ticket-keys", bind_parse_tls_ticket_keys, 1 }, /* set file to load TLS ticket keys from */
5971 { "verify", bind_parse_verify, 1 }, /* set SSL verify method */
5972 { "npn", bind_parse_npn, 1 }, /* set NPN supported protocols */
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005973 { NULL, NULL, 0 },
5974}};
Emeric Brun46591952012-05-18 15:47:34 +02005975
Willy Tarreau92faadf2012-10-10 23:04:25 +02005976/* Note: must not be declared <const> as its list will be overwritten.
5977 * Please take care of keeping this list alphabetically sorted, doing so helps
5978 * all code contributors.
5979 * Optional keywords are also declared with a NULL ->parse() function so that
5980 * the config parser can report an appropriate error when a known keyword was
5981 * not enabled.
5982 */
5983static struct srv_kw_list srv_kws = { "SSL", { }, {
Emeric Brunef42d922012-10-11 16:11:36 +02005984 { "ca-file", srv_parse_ca_file, 1, 0 }, /* set CAfile to process verify server cert */
Emeric Brunecc91fe2012-10-11 15:05:10 +02005985 { "check-ssl", srv_parse_check_ssl, 0, 0 }, /* enable SSL for health checks */
5986 { "ciphers", srv_parse_ciphers, 1, 0 }, /* select the cipher suite */
Emeric Brunef42d922012-10-11 16:11:36 +02005987 { "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 +02005988 { "crt", srv_parse_crt, 1, 0 }, /* set client certificate */
Emeric Brunecc91fe2012-10-11 15:05:10 +02005989 { "force-sslv3", srv_parse_force_sslv3, 0, 0 }, /* force SSLv3 */
5990 { "force-tlsv10", srv_parse_force_tlsv10, 0, 0 }, /* force TLSv10 */
5991 { "force-tlsv11", srv_parse_force_tlsv11, 0, 0 }, /* force TLSv11 */
5992 { "force-tlsv12", srv_parse_force_tlsv12, 0, 0 }, /* force TLSv12 */
Willy Tarreau2a3fb1c2015-02-05 16:47:07 +01005993 { "no-ssl-reuse", srv_parse_no_ssl_reuse, 0, 0 }, /* disable session reuse */
Emeric Brunecc91fe2012-10-11 15:05:10 +02005994 { "no-sslv3", srv_parse_no_sslv3, 0, 0 }, /* disable SSLv3 */
5995 { "no-tlsv10", srv_parse_no_tlsv10, 0, 0 }, /* disable TLSv10 */
5996 { "no-tlsv11", srv_parse_no_tlsv11, 0, 0 }, /* disable TLSv11 */
5997 { "no-tlsv12", srv_parse_no_tlsv12, 0, 0 }, /* disable TLSv12 */
Emeric Brunf9c5c472012-10-11 15:28:34 +02005998 { "no-tls-tickets", srv_parse_no_tls_tickets, 0, 0 }, /* disable session resumption tickets */
David Safb76832014-05-08 23:42:08 -04005999 { "send-proxy-v2-ssl", srv_parse_send_proxy_ssl, 0, 0 }, /* send PROXY protocol header v2 with SSL info */
6000 { "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 +02006001 { "sni", srv_parse_sni, 1, 0 }, /* send SNI extension */
Emeric Brunecc91fe2012-10-11 15:05:10 +02006002 { "ssl", srv_parse_ssl, 0, 0 }, /* enable SSL processing */
Emeric Brunef42d922012-10-11 16:11:36 +02006003 { "verify", srv_parse_verify, 1, 0 }, /* set SSL verify method */
Evan Broderbe554312013-06-27 00:05:25 -07006004 { "verifyhost", srv_parse_verifyhost, 1, 0 }, /* require that SSL cert verifies for hostname */
Willy Tarreau92faadf2012-10-10 23:04:25 +02006005 { NULL, NULL, 0, 0 },
6006}};
6007
Emeric Brun2c86cbf2014-10-30 15:56:50 +01006008static struct cfg_kw_list cfg_kws = {ILH, {
6009 { CFG_GLOBAL, "ssl-default-bind-options", ssl_parse_default_bind_options },
6010 { CFG_GLOBAL, "ssl-default-server-options", ssl_parse_default_server_options },
6011 { 0, NULL, NULL },
6012}};
6013
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02006014/* transport-layer operations for SSL sockets */
6015struct xprt_ops ssl_sock = {
Emeric Brun46591952012-05-18 15:47:34 +02006016 .snd_buf = ssl_sock_from_buf,
6017 .rcv_buf = ssl_sock_to_buf,
6018 .rcv_pipe = NULL,
6019 .snd_pipe = NULL,
6020 .shutr = NULL,
6021 .shutw = ssl_sock_shutw,
6022 .close = ssl_sock_close,
6023 .init = ssl_sock_init,
6024};
6025
Daniel Jakots54ffb912015-11-06 20:02:41 +01006026#if (OPENSSL_VERSION_NUMBER >= 0x1000200fL && !defined OPENSSL_NO_TLSEXT && !defined OPENSSL_IS_BORINGSSL && !defined LIBRESSL_VERSION_NUMBER)
Janusz Dziemidowicz2c701b52015-03-07 23:03:59 +01006027
6028static void ssl_sock_sctl_free_func(void *parent, void *ptr, CRYPTO_EX_DATA *ad, int idx, long argl, void *argp)
6029{
6030 if (ptr) {
6031 chunk_destroy(ptr);
6032 free(ptr);
6033 }
6034}
6035
6036#endif
6037
Emeric Brun46591952012-05-18 15:47:34 +02006038__attribute__((constructor))
Willy Tarreau92faadf2012-10-10 23:04:25 +02006039static void __ssl_sock_init(void)
6040{
Emeric Brun46591952012-05-18 15:47:34 +02006041 STACK_OF(SSL_COMP)* cm;
6042
Willy Tarreau610f04b2014-02-13 11:36:41 +01006043#ifdef LISTEN_DEFAULT_CIPHERS
6044 global.listen_default_ciphers = LISTEN_DEFAULT_CIPHERS;
6045#endif
6046#ifdef CONNECT_DEFAULT_CIPHERS
6047 global.connect_default_ciphers = CONNECT_DEFAULT_CIPHERS;
6048#endif
6049 if (global.listen_default_ciphers)
6050 global.listen_default_ciphers = strdup(global.listen_default_ciphers);
6051 if (global.connect_default_ciphers)
6052 global.connect_default_ciphers = strdup(global.connect_default_ciphers);
Emeric Brun2c86cbf2014-10-30 15:56:50 +01006053 global.listen_default_ssloptions = BC_SSL_O_NONE;
6054 global.connect_default_ssloptions = SRV_SSL_O_NONE;
Willy Tarreau610f04b2014-02-13 11:36:41 +01006055
Emeric Brun46591952012-05-18 15:47:34 +02006056 SSL_library_init();
6057 cm = SSL_COMP_get_compression_methods();
6058 sk_SSL_COMP_zero(cm);
Daniel Jakots54ffb912015-11-06 20:02:41 +01006059#if (OPENSSL_VERSION_NUMBER >= 0x1000200fL && !defined OPENSSL_NO_TLSEXT && !defined OPENSSL_IS_BORINGSSL && !defined LIBRESSL_VERSION_NUMBER)
Janusz Dziemidowicz2c701b52015-03-07 23:03:59 +01006060 sctl_ex_index = SSL_CTX_get_ex_new_index(0, NULL, NULL, NULL, ssl_sock_sctl_free_func);
6061#endif
Willy Tarreau7875d092012-09-10 08:20:03 +02006062 sample_register_fetches(&sample_fetch_keywords);
6063 acl_register_keywords(&acl_kws);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02006064 bind_register_keywords(&bind_kws);
Willy Tarreau92faadf2012-10-10 23:04:25 +02006065 srv_register_keywords(&srv_kws);
Emeric Brun2c86cbf2014-10-30 15:56:50 +01006066 cfg_register_keywords(&cfg_kws);
Willy Tarreaud92aa5c2015-01-15 21:34:39 +01006067
6068 global.ssl_session_max_cost = SSL_SESSION_MAX_COST;
6069 global.ssl_handshake_max_cost = SSL_HANDSHAKE_MAX_COST;
Remi Gacogne4f902b82015-05-28 16:23:00 +02006070
6071#ifndef OPENSSL_NO_DH
6072 ssl_dh_ptr_index = SSL_CTX_get_ex_new_index(0, NULL, NULL, NULL, NULL);
6073#endif
Thierry FOURNIER / OZON.IO8b068c22016-10-10 11:59:50 +02006074
6075 /* Load SSL string for the verbose & debug mode. */
6076 ERR_load_SSL_strings();
Emeric Brun46591952012-05-18 15:47:34 +02006077}
6078
Remi Gacogned3a23c32015-05-28 16:39:47 +02006079__attribute__((destructor))
6080static void __ssl_sock_deinit(void)
6081{
Willy Tarreaua84c2672015-10-09 12:10:13 +02006082#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Christopher Faulet31af49d2015-06-09 17:29:50 +02006083 lru64_destroy(ssl_ctx_lru_tree);
Willy Tarreaua84c2672015-10-09 12:10:13 +02006084#endif
Christopher Faulet31af49d2015-06-09 17:29:50 +02006085
Remi Gacogned3a23c32015-05-28 16:39:47 +02006086#ifndef OPENSSL_NO_DH
6087 if (local_dh_1024) {
6088 DH_free(local_dh_1024);
6089 local_dh_1024 = NULL;
6090 }
6091
6092 if (local_dh_2048) {
6093 DH_free(local_dh_2048);
6094 local_dh_2048 = NULL;
6095 }
6096
6097 if (local_dh_4096) {
6098 DH_free(local_dh_4096);
6099 local_dh_4096 = NULL;
6100 }
6101
Remi Gacogne47783ef2015-05-29 15:53:22 +02006102 if (global_dh) {
6103 DH_free(global_dh);
6104 global_dh = NULL;
6105 }
Remi Gacogned3a23c32015-05-28 16:39:47 +02006106#endif
6107
6108 ERR_remove_state(0);
6109 ERR_free_strings();
6110
6111 EVP_cleanup();
6112
6113#if OPENSSL_VERSION_NUMBER >= 0x00907000L
6114 CRYPTO_cleanup_all_ex_data();
6115#endif
6116}
6117
6118
Emeric Brun46591952012-05-18 15:47:34 +02006119/*
6120 * Local variables:
6121 * c-indent-level: 8
6122 * c-basic-offset: 8
6123 * End:
6124 */