blob: f24761822fdae81a232628705bab8fd1fdf2c918 [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/*
203 * This function returns the number of seconds elapsed
204 * since the Epoch, 1970-01-01 00:00:00 +0000 (UTC) and the
205 * date presented un ASN1_GENERALIZEDTIME.
206 *
207 * In parsing error case, it returns -1.
208 */
209static long asn1_generalizedtime_to_epoch(ASN1_GENERALIZEDTIME *d)
210{
211 long epoch;
212 char *p, *end;
213 const unsigned short month_offset[12] = {
214 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334
215 };
216 int year, month;
217
218 if (!d || (d->type != V_ASN1_GENERALIZEDTIME)) return -1;
219
220 p = (char *)d->data;
221 end = p + d->length;
222
223 if (end - p < 4) return -1;
224 year = 1000 * (p[0] - '0') + 100 * (p[1] - '0') + 10 * (p[2] - '0') + p[3] - '0';
225 p += 4;
226 if (end - p < 2) return -1;
227 month = 10 * (p[0] - '0') + p[1] - '0';
228 if (month < 1 || month > 12) return -1;
229 /* Compute the number of seconds since 1 jan 1970 and the beginning of current month
230 We consider leap years and the current month (<marsh or not) */
231 epoch = ( ((year - 1970) * 365)
232 + ((year - (month < 3)) / 4 - (year - (month < 3)) / 100 + (year - (month < 3)) / 400)
233 - ((1970 - 1) / 4 - (1970 - 1) / 100 + (1970 - 1) / 400)
234 + month_offset[month-1]
235 ) * 24 * 60 * 60;
236 p += 2;
237 if (end - p < 2) return -1;
238 /* Add the number of seconds of completed days of current month */
239 epoch += (10 * (p[0] - '0') + p[1] - '0' - 1) * 24 * 60 * 60;
240 p += 2;
241 if (end - p < 2) return -1;
242 /* Add the completed hours of the current day */
243 epoch += (10 * (p[0] - '0') + p[1] - '0') * 60 * 60;
244 p += 2;
245 if (end - p < 2) return -1;
246 /* Add the completed minutes of the current hour */
247 epoch += (10 * (p[0] - '0') + p[1] - '0') * 60;
248 p += 2;
249 if (p == end) return -1;
250 /* Test if there is available seconds */
251 if (p[0] < '0' || p[0] > '9')
252 goto nosec;
253 if (end - p < 2) return -1;
254 /* Add the seconds of the current minute */
255 epoch += 10 * (p[0] - '0') + p[1] - '0';
256 p += 2;
257 if (p == end) return -1;
258 /* Ignore seconds float part if present */
259 if (p[0] == '.') {
260 do {
261 if (++p == end) return -1;
262 } while (p[0] >= '0' && p[0] <= '9');
263 }
264
265nosec:
266 if (p[0] == 'Z') {
267 if (end - p != 1) return -1;
268 return epoch;
269 }
270 else if (p[0] == '+') {
271 if (end - p != 5) return -1;
272 /* Apply timezone offset */
273 return epoch - ((10 * (p[1] - '0') + p[2] - '0') * 60 + (10 * (p[3] - '0') + p[4] - '0')) * 60;
274 }
275 else if (p[0] == '-') {
276 if (end - p != 5) return -1;
277 /* Apply timezone offset */
278 return epoch + ((10 * (p[1] - '0') + p[2] - '0') * 60 + (10 * (p[3] - '0') + p[4] - '0')) * 60;
279 }
280
281 return -1;
282}
283
Emeric Brun1d3865b2014-06-20 15:37:32 +0200284static struct eb_root cert_ocsp_tree = EB_ROOT_UNIQUE;
Emeric Brun4147b2e2014-06-16 18:36:30 +0200285
286/* This function starts to check if the OCSP response (in DER format) contained
287 * in chunk 'ocsp_response' is valid (else exits on error).
288 * If 'cid' is not NULL, it will be compared to the OCSP certificate ID
289 * contained in the OCSP Response and exits on error if no match.
290 * If it's a valid OCSP Response:
291 * If 'ocsp' is not NULL, the chunk is copied in the OCSP response's container
292 * pointed by 'ocsp'.
293 * If 'ocsp' is NULL, the function looks up into the OCSP response's
294 * containers tree (using as index the ASN1 form of the OCSP Certificate ID extracted
295 * from the response) and exits on error if not found. Finally, If an OCSP response is
296 * already present in the container, it will be overwritten.
297 *
298 * Note: OCSP response containing more than one OCSP Single response is not
299 * considered valid.
300 *
301 * Returns 0 on success, 1 in error case.
302 */
303static int ssl_sock_load_ocsp_response(struct chunk *ocsp_response, struct certificate_ocsp *ocsp, OCSP_CERTID *cid, char **err)
304{
305 OCSP_RESPONSE *resp;
306 OCSP_BASICRESP *bs = NULL;
307 OCSP_SINGLERESP *sr;
308 unsigned char *p = (unsigned char *)ocsp_response->str;
309 int rc , count_sr;
Emeric Brun13a6b482014-06-20 15:44:34 +0200310 ASN1_GENERALIZEDTIME *revtime, *thisupd, *nextupd = NULL;
Emeric Brun4147b2e2014-06-16 18:36:30 +0200311 int reason;
312 int ret = 1;
313
314 resp = d2i_OCSP_RESPONSE(NULL, (const unsigned char **)&p, ocsp_response->len);
315 if (!resp) {
316 memprintf(err, "Unable to parse OCSP response");
317 goto out;
318 }
319
320 rc = OCSP_response_status(resp);
321 if (rc != OCSP_RESPONSE_STATUS_SUCCESSFUL) {
322 memprintf(err, "OCSP response status not successful");
323 goto out;
324 }
325
326 bs = OCSP_response_get1_basic(resp);
327 if (!bs) {
328 memprintf(err, "Failed to get basic response from OCSP Response");
329 goto out;
330 }
331
332 count_sr = OCSP_resp_count(bs);
333 if (count_sr > 1) {
334 memprintf(err, "OCSP response ignored because contains multiple single responses (%d)", count_sr);
335 goto out;
336 }
337
338 sr = OCSP_resp_get0(bs, 0);
339 if (!sr) {
340 memprintf(err, "Failed to get OCSP single response");
341 goto out;
342 }
343
344 rc = OCSP_single_get0_status(sr, &reason, &revtime, &thisupd, &nextupd);
345 if (rc != V_OCSP_CERTSTATUS_GOOD) {
346 memprintf(err, "OCSP single response: certificate status not good");
347 goto out;
348 }
349
Emeric Brun13a6b482014-06-20 15:44:34 +0200350 if (!nextupd) {
351 memprintf(err, "OCSP single response: missing nextupdate");
352 goto out;
353 }
354
Emeric Brunc8b27b62014-06-19 14:16:17 +0200355 rc = OCSP_check_validity(thisupd, nextupd, OCSP_MAX_RESPONSE_TIME_SKEW, -1);
Emeric Brun4147b2e2014-06-16 18:36:30 +0200356 if (!rc) {
357 memprintf(err, "OCSP single response: no longer valid.");
358 goto out;
359 }
360
361 if (cid) {
362 if (OCSP_id_cmp(sr->certId, cid)) {
363 memprintf(err, "OCSP single response: Certificate ID does not match certificate and issuer");
364 goto out;
365 }
366 }
367
368 if (!ocsp) {
369 unsigned char key[OCSP_MAX_CERTID_ASN1_LENGTH];
370 unsigned char *p;
371
372 rc = i2d_OCSP_CERTID(sr->certId, NULL);
373 if (!rc) {
374 memprintf(err, "OCSP single response: Unable to encode Certificate ID");
375 goto out;
376 }
377
378 if (rc > OCSP_MAX_CERTID_ASN1_LENGTH) {
379 memprintf(err, "OCSP single response: Certificate ID too long");
380 goto out;
381 }
382
383 p = key;
384 memset(key, 0, OCSP_MAX_CERTID_ASN1_LENGTH);
385 i2d_OCSP_CERTID(sr->certId, &p);
386 ocsp = (struct certificate_ocsp *)ebmb_lookup(&cert_ocsp_tree, key, OCSP_MAX_CERTID_ASN1_LENGTH);
387 if (!ocsp) {
388 memprintf(err, "OCSP single response: Certificate ID does not match any certificate or issuer");
389 goto out;
390 }
391 }
392
393 /* According to comments on "chunk_dup", the
394 previous chunk buffer will be freed */
395 if (!chunk_dup(&ocsp->response, ocsp_response)) {
396 memprintf(err, "OCSP response: Memory allocation error");
397 goto out;
398 }
399
Emeric Brun4f3c87a2014-06-20 15:46:13 +0200400 ocsp->expire = asn1_generalizedtime_to_epoch(nextupd) - OCSP_MAX_RESPONSE_TIME_SKEW;
401
Emeric Brun4147b2e2014-06-16 18:36:30 +0200402 ret = 0;
403out:
404 if (bs)
405 OCSP_BASICRESP_free(bs);
406
407 if (resp)
408 OCSP_RESPONSE_free(resp);
409
410 return ret;
411}
412/*
413 * External function use to update the OCSP response in the OCSP response's
414 * containers tree. The chunk 'ocsp_response' must contain the OCSP response
415 * to update in DER format.
416 *
417 * Returns 0 on success, 1 in error case.
418 */
419int ssl_sock_update_ocsp_response(struct chunk *ocsp_response, char **err)
420{
421 return ssl_sock_load_ocsp_response(ocsp_response, NULL, NULL, err);
422}
423
424/*
425 * This function load the OCSP Resonse in DER format contained in file at
426 * path 'ocsp_path' and call 'ssl_sock_load_ocsp_response'
427 *
428 * Returns 0 on success, 1 in error case.
429 */
430static int ssl_sock_load_ocsp_response_from_file(const char *ocsp_path, struct certificate_ocsp *ocsp, OCSP_CERTID *cid, char **err)
431{
432 int fd = -1;
433 int r = 0;
434 int ret = 1;
435
436 fd = open(ocsp_path, O_RDONLY);
437 if (fd == -1) {
438 memprintf(err, "Error opening OCSP response file");
439 goto end;
440 }
441
442 trash.len = 0;
443 while (trash.len < trash.size) {
444 r = read(fd, trash.str + trash.len, trash.size - trash.len);
445 if (r < 0) {
446 if (errno == EINTR)
447 continue;
448
449 memprintf(err, "Error reading OCSP response from file");
450 goto end;
451 }
452 else if (r == 0) {
453 break;
454 }
455 trash.len += r;
456 }
457
458 close(fd);
459 fd = -1;
460
461 ret = ssl_sock_load_ocsp_response(&trash, ocsp, cid, err);
462end:
463 if (fd != -1)
464 close(fd);
465
466 return ret;
467}
468
Nenad Merdanovic05552d42015-02-27 19:56:49 +0100469#if (defined SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB && TLS_TICKETS_NO > 0)
470static 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)
471{
472 struct tls_sess_key *keys;
473 struct connection *conn;
474 int head;
475 int i;
476
Vincent Bernat3c2f2f22016-04-03 13:48:42 +0200477 conn = SSL_get_app_data(s);
Nenad Merdanovic146defa2015-05-09 08:46:00 +0200478 keys = objt_listener(conn->target)->bind_conf->keys_ref->tlskeys;
479 head = objt_listener(conn->target)->bind_conf->keys_ref->tls_ticket_enc_index;
Nenad Merdanovic05552d42015-02-27 19:56:49 +0100480
481 if (enc) {
482 memcpy(key_name, keys[head].name, 16);
483
484 if(!RAND_pseudo_bytes(iv, EVP_MAX_IV_LENGTH))
485 return -1;
486
487 if(!EVP_EncryptInit_ex(ectx, EVP_aes_128_cbc(), NULL, keys[head].aes_key, iv))
488 return -1;
489
490 HMAC_Init_ex(hctx, keys[head].hmac_key, 16, HASH_FUNCT(), NULL);
491
492 return 1;
493 } else {
494 for (i = 0; i < TLS_TICKETS_NO; i++) {
495 if (!memcmp(key_name, keys[(head + i) % TLS_TICKETS_NO].name, 16))
496 goto found;
497 }
498 return 0;
499
500 found:
501 HMAC_Init_ex(hctx, keys[(head + i) % TLS_TICKETS_NO].hmac_key, 16, HASH_FUNCT(), NULL);
502 if(!EVP_DecryptInit_ex(ectx, EVP_aes_128_cbc(), NULL, keys[(head + i) % TLS_TICKETS_NO].aes_key, iv))
503 return -1;
504 /* 2 for key renewal, 1 if current key is still valid */
505 return i ? 2 : 1;
506 }
Nenad Merdanovic200b0fa2015-05-09 08:46:01 +0200507}
508
509struct tls_keys_ref *tlskeys_ref_lookup(const char *filename)
510{
511 struct tls_keys_ref *ref;
512
513 list_for_each_entry(ref, &tlskeys_reference, list)
514 if (ref->filename && strcmp(filename, ref->filename) == 0)
515 return ref;
516 return NULL;
517}
518
519struct tls_keys_ref *tlskeys_ref_lookupid(int unique_id)
520{
521 struct tls_keys_ref *ref;
522
523 list_for_each_entry(ref, &tlskeys_reference, list)
524 if (ref->unique_id == unique_id)
525 return ref;
526 return NULL;
527}
528
529int ssl_sock_update_tlskey(char *filename, struct chunk *tlskey, char **err) {
530 struct tls_keys_ref *ref = tlskeys_ref_lookup(filename);
531
532 if(!ref) {
533 memprintf(err, "Unable to locate the referenced filename: %s", filename);
534 return 1;
535 }
536
Pradeep Jindalcc79b002015-08-20 18:25:17 +0530537 memcpy((char *) (ref->tlskeys + ((ref->tls_ticket_enc_index + 2) % TLS_TICKETS_NO)), tlskey->str, tlskey->len);
538 ref->tls_ticket_enc_index = (ref->tls_ticket_enc_index + 1) % TLS_TICKETS_NO;
Nenad Merdanovic200b0fa2015-05-09 08:46:01 +0200539
540 return 0;
Nenad Merdanovic05552d42015-02-27 19:56:49 +0100541}
Nenad Merdanovic200b0fa2015-05-09 08:46:01 +0200542
543/* This function finalize the configuration parsing. Its set all the
544 * automatic ids
545 */
546void tlskeys_finalize_config(void)
547{
548 int i = 0;
549 struct tls_keys_ref *ref, *ref2, *ref3;
550 struct list tkr = LIST_HEAD_INIT(tkr);
551
552 list_for_each_entry(ref, &tlskeys_reference, list) {
553 if (ref->unique_id == -1) {
554 /* Look for the first free id. */
555 while (1) {
556 list_for_each_entry(ref2, &tlskeys_reference, list) {
557 if (ref2->unique_id == i) {
558 i++;
559 break;
560 }
561 }
562 if (&ref2->list == &tlskeys_reference)
563 break;
564 }
565
566 /* Uses the unique id and increment it for the next entry. */
567 ref->unique_id = i;
568 i++;
569 }
570 }
571
572 /* This sort the reference list by id. */
573 list_for_each_entry_safe(ref, ref2, &tlskeys_reference, list) {
574 LIST_DEL(&ref->list);
575 list_for_each_entry(ref3, &tkr, list) {
576 if (ref->unique_id < ref3->unique_id) {
577 LIST_ADDQ(&ref3->list, &ref->list);
578 break;
579 }
580 }
581 if (&ref3->list == &tkr)
582 LIST_ADDQ(&tkr, &ref->list);
583 }
584
585 /* swap root */
586 LIST_ADD(&tkr, &tlskeys_reference);
587 LIST_DEL(&tkr);
588}
589
Nenad Merdanovic05552d42015-02-27 19:56:49 +0100590#endif /* SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB */
591
yanbzhube2774d2015-12-10 15:07:30 -0500592int ssl_sock_get_ocsp_arg_kt_index(int evp_keytype)
593{
594 switch (evp_keytype) {
595 case EVP_PKEY_RSA:
596 return 2;
597 case EVP_PKEY_DSA:
598 return 0;
599 case EVP_PKEY_EC:
600 return 1;
601 }
602
603 return -1;
604}
605
Emeric Brun4147b2e2014-06-16 18:36:30 +0200606/*
607 * Callback used to set OCSP status extension content in server hello.
608 */
609int ssl_sock_ocsp_stapling_cbk(SSL *ssl, void *arg)
610{
yanbzhube2774d2015-12-10 15:07:30 -0500611 struct certificate_ocsp *ocsp;
612 struct ocsp_cbk_arg *ocsp_arg;
613 char *ssl_buf;
614 EVP_PKEY *ssl_pkey;
615 int key_type;
616 int index;
617
Vincent Bernat3c2f2f22016-04-03 13:48:42 +0200618 ocsp_arg = arg;
yanbzhube2774d2015-12-10 15:07:30 -0500619
620 ssl_pkey = SSL_get_privatekey(ssl);
621 if (!ssl_pkey)
622 return SSL_TLSEXT_ERR_NOACK;
623
624 key_type = EVP_PKEY_type(ssl_pkey->type);
625
626 if (ocsp_arg->is_single && ocsp_arg->single_kt == key_type)
627 ocsp = ocsp_arg->s_ocsp;
628 else {
629 /* For multiple certs per context, we have to find the correct OCSP response based on
630 * the certificate type
631 */
632 index = ssl_sock_get_ocsp_arg_kt_index(key_type);
633
634 if (index < 0)
635 return SSL_TLSEXT_ERR_NOACK;
636
637 ocsp = ocsp_arg->m_ocsp[index];
638
639 }
Emeric Brun4147b2e2014-06-16 18:36:30 +0200640
641 if (!ocsp ||
642 !ocsp->response.str ||
Emeric Brun4f3c87a2014-06-20 15:46:13 +0200643 !ocsp->response.len ||
644 (ocsp->expire < now.tv_sec))
Emeric Brun4147b2e2014-06-16 18:36:30 +0200645 return SSL_TLSEXT_ERR_NOACK;
646
647 ssl_buf = OPENSSL_malloc(ocsp->response.len);
648 if (!ssl_buf)
649 return SSL_TLSEXT_ERR_NOACK;
650
651 memcpy(ssl_buf, ocsp->response.str, ocsp->response.len);
652 SSL_set_tlsext_status_ocsp_resp(ssl, ssl_buf, ocsp->response.len);
653
654 return SSL_TLSEXT_ERR_OK;
655}
656
657/*
658 * This function enables the handling of OCSP status extension on 'ctx' if a
659 * file name 'cert_path' suffixed using ".ocsp" is present.
660 * To enable OCSP status extension, the issuer's certificate is mandatory.
661 * It should be present in the certificate's extra chain builded from file
662 * 'cert_path'. If not found, the issuer certificate is loaded from a file
663 * named 'cert_path' suffixed using '.issuer'.
664 *
665 * In addition, ".ocsp" file content is loaded as a DER format of an OCSP
666 * response. If file is empty or content is not a valid OCSP response,
667 * OCSP status extension is enabled but OCSP response is ignored (a warning
668 * is displayed).
669 *
670 * Returns 1 if no ".ocsp" file found, 0 if OCSP status extension is
671 * succesfully enabled, or -1 in other error case.
672 */
673static int ssl_sock_load_ocsp(SSL_CTX *ctx, const char *cert_path)
674{
675
676 BIO *in = NULL;
677 X509 *x, *xi = NULL, *issuer = NULL;
678 STACK_OF(X509) *chain = NULL;
679 OCSP_CERTID *cid = NULL;
680 SSL *ssl;
681 char ocsp_path[MAXPATHLEN+1];
682 int i, ret = -1;
683 struct stat st;
684 struct certificate_ocsp *ocsp = NULL, *iocsp;
685 char *warn = NULL;
686 unsigned char *p;
687
688 snprintf(ocsp_path, MAXPATHLEN+1, "%s.ocsp", cert_path);
689
690 if (stat(ocsp_path, &st))
691 return 1;
692
693 ssl = SSL_new(ctx);
694 if (!ssl)
695 goto out;
696
697 x = SSL_get_certificate(ssl);
698 if (!x)
699 goto out;
700
701 /* Try to lookup for issuer in certificate extra chain */
702#ifdef SSL_CTRL_GET_EXTRA_CHAIN_CERTS
703 SSL_CTX_get_extra_chain_certs(ctx, &chain);
704#else
705 chain = ctx->extra_certs;
706#endif
707 for (i = 0; i < sk_X509_num(chain); i++) {
708 issuer = sk_X509_value(chain, i);
709 if (X509_check_issued(issuer, x) == X509_V_OK)
710 break;
711 else
712 issuer = NULL;
713 }
714
715 /* If not found try to load issuer from a suffixed file */
716 if (!issuer) {
717 char issuer_path[MAXPATHLEN+1];
718
719 in = BIO_new(BIO_s_file());
720 if (!in)
721 goto out;
722
723 snprintf(issuer_path, MAXPATHLEN+1, "%s.issuer", cert_path);
724 if (BIO_read_filename(in, issuer_path) <= 0)
725 goto out;
726
727 xi = PEM_read_bio_X509_AUX(in, NULL, ctx->default_passwd_callback, ctx->default_passwd_callback_userdata);
728 if (!xi)
729 goto out;
730
731 if (X509_check_issued(xi, x) != X509_V_OK)
732 goto out;
733
734 issuer = xi;
735 }
736
737 cid = OCSP_cert_to_id(0, x, issuer);
738 if (!cid)
739 goto out;
740
741 i = i2d_OCSP_CERTID(cid, NULL);
742 if (!i || (i > OCSP_MAX_CERTID_ASN1_LENGTH))
743 goto out;
744
Vincent Bernat02779b62016-04-03 13:48:43 +0200745 ocsp = calloc(1, sizeof(*ocsp));
Emeric Brun4147b2e2014-06-16 18:36:30 +0200746 if (!ocsp)
747 goto out;
748
749 p = ocsp->key_data;
750 i2d_OCSP_CERTID(cid, &p);
751
752 iocsp = (struct certificate_ocsp *)ebmb_insert(&cert_ocsp_tree, &ocsp->key, OCSP_MAX_CERTID_ASN1_LENGTH);
753 if (iocsp == ocsp)
754 ocsp = NULL;
755
yanbzhube2774d2015-12-10 15:07:30 -0500756 if (!ctx->tlsext_status_cb) {
Vincent Bernat02779b62016-04-03 13:48:43 +0200757 struct ocsp_cbk_arg *cb_arg = calloc(1, sizeof(*cb_arg));
yanbzhube2774d2015-12-10 15:07:30 -0500758
759 cb_arg->is_single = 1;
760 cb_arg->s_ocsp = iocsp;
761 cb_arg->single_kt = EVP_PKEY_type(X509_get_pubkey(x)->type);
762
763 SSL_CTX_set_tlsext_status_cb(ctx, ssl_sock_ocsp_stapling_cbk);
764 SSL_CTX_set_tlsext_status_arg(ctx, cb_arg);
765 } else {
766 /*
767 * If the ctx has a status CB, then we have previously set an OCSP staple for this ctx
768 * Update that cb_arg with the new cert's staple
769 */
Vincent Bernat3c2f2f22016-04-03 13:48:42 +0200770 struct ocsp_cbk_arg *cb_arg = ctx->tlsext_status_arg;
yanbzhube2774d2015-12-10 15:07:30 -0500771 struct certificate_ocsp *tmp_ocsp;
772 int index;
773
774 /*
775 * The following few lines will convert cb_arg from a single ocsp to multi ocsp
776 * the order of operations below matter, take care when changing it
777 */
778 tmp_ocsp = cb_arg->s_ocsp;
779 index = ssl_sock_get_ocsp_arg_kt_index(cb_arg->single_kt);
780 cb_arg->s_ocsp = NULL;
781 cb_arg->m_ocsp[index] = tmp_ocsp;
782 cb_arg->is_single = 0;
783 cb_arg->single_kt = 0;
784
785 index = ssl_sock_get_ocsp_arg_kt_index(EVP_PKEY_type(X509_get_pubkey(x)->type));
786 if (index >= 0 && !cb_arg->m_ocsp[index])
787 cb_arg->m_ocsp[index] = iocsp;
788
789 }
Emeric Brun4147b2e2014-06-16 18:36:30 +0200790
791 ret = 0;
792
793 warn = NULL;
794 if (ssl_sock_load_ocsp_response_from_file(ocsp_path, iocsp, cid, &warn)) {
795 memprintf(&warn, "Loading '%s': %s. Content will be ignored", ocsp_path, warn ? warn : "failure");
796 Warning("%s.\n", warn);
797 }
798
799out:
800 if (ssl)
801 SSL_free(ssl);
802
803 if (in)
804 BIO_free(in);
805
806 if (xi)
807 X509_free(xi);
808
809 if (cid)
810 OCSP_CERTID_free(cid);
811
812 if (ocsp)
813 free(ocsp);
814
815 if (warn)
816 free(warn);
817
818
819 return ret;
820}
821
822#endif
823
Daniel Jakots54ffb912015-11-06 20:02:41 +0100824#if (OPENSSL_VERSION_NUMBER >= 0x1000200fL && !defined OPENSSL_NO_TLSEXT && !defined OPENSSL_IS_BORINGSSL && !defined LIBRESSL_VERSION_NUMBER)
Janusz Dziemidowicz2c701b52015-03-07 23:03:59 +0100825
826#define CT_EXTENSION_TYPE 18
827
828static int sctl_ex_index = -1;
829
830/*
831 * Try to parse Signed Certificate Timestamp List structure. This function
832 * makes only basic test if the data seems like SCTL. No signature validation
833 * is performed.
834 */
835static int ssl_sock_parse_sctl(struct chunk *sctl)
836{
837 int ret = 1;
838 int len, pos, sct_len;
839 unsigned char *data;
840
841 if (sctl->len < 2)
842 goto out;
843
844 data = (unsigned char *)sctl->str;
845 len = (data[0] << 8) | data[1];
846
847 if (len + 2 != sctl->len)
848 goto out;
849
850 data = data + 2;
851 pos = 0;
852 while (pos < len) {
853 if (len - pos < 2)
854 goto out;
855
856 sct_len = (data[pos] << 8) | data[pos + 1];
857 if (pos + sct_len + 2 > len)
858 goto out;
859
860 pos += sct_len + 2;
861 }
862
863 ret = 0;
864
865out:
866 return ret;
867}
868
869static int ssl_sock_load_sctl_from_file(const char *sctl_path, struct chunk **sctl)
870{
871 int fd = -1;
872 int r = 0;
873 int ret = 1;
874
875 *sctl = NULL;
876
877 fd = open(sctl_path, O_RDONLY);
878 if (fd == -1)
879 goto end;
880
881 trash.len = 0;
882 while (trash.len < trash.size) {
883 r = read(fd, trash.str + trash.len, trash.size - trash.len);
884 if (r < 0) {
885 if (errno == EINTR)
886 continue;
887
888 goto end;
889 }
890 else if (r == 0) {
891 break;
892 }
893 trash.len += r;
894 }
895
896 ret = ssl_sock_parse_sctl(&trash);
897 if (ret)
898 goto end;
899
Vincent Bernat02779b62016-04-03 13:48:43 +0200900 *sctl = calloc(1, sizeof(**sctl));
Janusz Dziemidowicz2c701b52015-03-07 23:03:59 +0100901 if (!chunk_dup(*sctl, &trash)) {
902 free(*sctl);
903 *sctl = NULL;
904 goto end;
905 }
906
907end:
908 if (fd != -1)
909 close(fd);
910
911 return ret;
912}
913
914int ssl_sock_sctl_add_cbk(SSL *ssl, unsigned ext_type, const unsigned char **out, size_t *outlen, int *al, void *add_arg)
915{
Vincent Bernat3c2f2f22016-04-03 13:48:42 +0200916 struct chunk *sctl = add_arg;
Janusz Dziemidowicz2c701b52015-03-07 23:03:59 +0100917
918 *out = (unsigned char *)sctl->str;
919 *outlen = sctl->len;
920
921 return 1;
922}
923
924int ssl_sock_sctl_parse_cbk(SSL *s, unsigned int ext_type, const unsigned char *in, size_t inlen, int *al, void *parse_arg)
925{
926 return 1;
927}
928
929static int ssl_sock_load_sctl(SSL_CTX *ctx, const char *cert_path)
930{
931 char sctl_path[MAXPATHLEN+1];
932 int ret = -1;
933 struct stat st;
934 struct chunk *sctl = NULL;
935
936 snprintf(sctl_path, MAXPATHLEN+1, "%s.sctl", cert_path);
937
938 if (stat(sctl_path, &st))
939 return 1;
940
941 if (ssl_sock_load_sctl_from_file(sctl_path, &sctl))
942 goto out;
943
944 if (!SSL_CTX_add_server_custom_ext(ctx, CT_EXTENSION_TYPE, ssl_sock_sctl_add_cbk, NULL, sctl, ssl_sock_sctl_parse_cbk, NULL)) {
945 free(sctl);
946 goto out;
947 }
948
949 SSL_CTX_set_ex_data(ctx, sctl_ex_index, sctl);
950
951 ret = 0;
952
953out:
954 return ret;
955}
956
957#endif
958
Emeric Brune1f38db2012-09-03 20:36:47 +0200959void ssl_sock_infocbk(const SSL *ssl, int where, int ret)
960{
Vincent Bernat3c2f2f22016-04-03 13:48:42 +0200961 struct connection *conn = SSL_get_app_data(ssl);
Emeric Brund8b2bb52014-01-28 15:43:53 +0100962 BIO *write_bio;
Willy Tarreau622317d2015-02-27 16:36:16 +0100963 (void)ret; /* shut gcc stupid warning */
Emeric Brune1f38db2012-09-03 20:36:47 +0200964
965 if (where & SSL_CB_HANDSHAKE_START) {
966 /* Disable renegotiation (CVE-2009-3555) */
Willy Tarreau20879a02012-12-03 16:32:10 +0100967 if (conn->flags & CO_FL_CONNECTED) {
Emeric Brune1f38db2012-09-03 20:36:47 +0200968 conn->flags |= CO_FL_ERROR;
Willy Tarreau20879a02012-12-03 16:32:10 +0100969 conn->err_code = CO_ER_SSL_RENEG;
970 }
Emeric Brune1f38db2012-09-03 20:36:47 +0200971 }
Emeric Brund8b2bb52014-01-28 15:43:53 +0100972
973 if ((where & SSL_CB_ACCEPT_LOOP) == SSL_CB_ACCEPT_LOOP) {
974 if (!(conn->xprt_st & SSL_SOCK_ST_FL_16K_WBFSIZE)) {
975 /* Long certificate chains optimz
976 If write and read bios are differents, we
977 consider that the buffering was activated,
978 so we rise the output buffer size from 4k
979 to 16k */
980 write_bio = SSL_get_wbio(ssl);
981 if (write_bio != SSL_get_rbio(ssl)) {
982 BIO_set_write_buffer_size(write_bio, 16384);
983 conn->xprt_st |= SSL_SOCK_ST_FL_16K_WBFSIZE;
984 }
985 }
986 }
Emeric Brunfc0421f2012-09-07 17:30:07 +0200987}
988
Emeric Brune64aef12012-09-21 13:15:06 +0200989/* Callback is called for each certificate of the chain during a verify
990 ok is set to 1 if preverify detect no error on current certificate.
991 Returns 0 to break the handshake, 1 otherwise. */
Evan Broderbe554312013-06-27 00:05:25 -0700992int ssl_sock_bind_verifycbk(int ok, X509_STORE_CTX *x_store)
Emeric Brune64aef12012-09-21 13:15:06 +0200993{
994 SSL *ssl;
995 struct connection *conn;
Emeric Brun81c00f02012-09-21 14:31:21 +0200996 int err, depth;
Emeric Brune64aef12012-09-21 13:15:06 +0200997
998 ssl = X509_STORE_CTX_get_ex_data(x_store, SSL_get_ex_data_X509_STORE_CTX_idx());
Vincent Bernat3c2f2f22016-04-03 13:48:42 +0200999 conn = SSL_get_app_data(ssl);
Emeric Brune64aef12012-09-21 13:15:06 +02001000
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02001001 conn->xprt_st |= SSL_SOCK_ST_FL_VERIFY_DONE;
Emeric Brune64aef12012-09-21 13:15:06 +02001002
Emeric Brun81c00f02012-09-21 14:31:21 +02001003 if (ok) /* no errors */
1004 return ok;
1005
1006 depth = X509_STORE_CTX_get_error_depth(x_store);
1007 err = X509_STORE_CTX_get_error(x_store);
1008
1009 /* check if CA error needs to be ignored */
1010 if (depth > 0) {
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02001011 if (!SSL_SOCK_ST_TO_CA_ERROR(conn->xprt_st)) {
1012 conn->xprt_st |= SSL_SOCK_CA_ERROR_TO_ST(err);
1013 conn->xprt_st |= SSL_SOCK_CAEDEPTH_TO_ST(depth);
Emeric Brunf282a812012-09-21 15:27:54 +02001014 }
1015
Emeric Brun1eb20ef2012-12-03 13:24:29 +01001016 if (objt_listener(conn->target)->bind_conf->ca_ignerr & (1ULL << err)) {
1017 ERR_clear_error();
Emeric Brun81c00f02012-09-21 14:31:21 +02001018 return 1;
Emeric Brun1eb20ef2012-12-03 13:24:29 +01001019 }
Emeric Brun81c00f02012-09-21 14:31:21 +02001020
Willy Tarreau20879a02012-12-03 16:32:10 +01001021 conn->err_code = CO_ER_SSL_CA_FAIL;
Emeric Brun81c00f02012-09-21 14:31:21 +02001022 return 0;
1023 }
1024
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02001025 if (!SSL_SOCK_ST_TO_CRTERROR(conn->xprt_st))
1026 conn->xprt_st |= SSL_SOCK_CRTERROR_TO_ST(err);
Emeric Brunf282a812012-09-21 15:27:54 +02001027
Emeric Brun81c00f02012-09-21 14:31:21 +02001028 /* check if certificate error needs to be ignored */
Emeric Brun1eb20ef2012-12-03 13:24:29 +01001029 if (objt_listener(conn->target)->bind_conf->crt_ignerr & (1ULL << err)) {
1030 ERR_clear_error();
Emeric Brun81c00f02012-09-21 14:31:21 +02001031 return 1;
Emeric Brun1eb20ef2012-12-03 13:24:29 +01001032 }
Emeric Brun81c00f02012-09-21 14:31:21 +02001033
Willy Tarreau20879a02012-12-03 16:32:10 +01001034 conn->err_code = CO_ER_SSL_CRT_FAIL;
Emeric Brun81c00f02012-09-21 14:31:21 +02001035 return 0;
Emeric Brune64aef12012-09-21 13:15:06 +02001036}
1037
Emeric Brun29f037d2014-04-25 19:05:36 +02001038/* Callback is called for ssl protocol analyse */
1039void ssl_sock_msgcbk(int write_p, int version, int content_type, const void *buf, size_t len, SSL *ssl, void *arg)
1040{
Emeric Brun29f037d2014-04-25 19:05:36 +02001041#ifdef TLS1_RT_HEARTBEAT
1042 /* test heartbeat received (write_p is set to 0
1043 for a received record) */
Willy Tarreauf51c6982014-04-25 20:02:39 +02001044 if ((content_type == TLS1_RT_HEARTBEAT) && (write_p == 0)) {
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02001045 struct connection *conn = SSL_get_app_data(ssl);
Willy Tarreauf51c6982014-04-25 20:02:39 +02001046 const unsigned char *p = buf;
1047 unsigned int payload;
1048
Emeric Brun29f037d2014-04-25 19:05:36 +02001049 conn->xprt_st |= SSL_SOCK_RECV_HEARTBEAT;
Willy Tarreauf51c6982014-04-25 20:02:39 +02001050
1051 /* Check if this is a CVE-2014-0160 exploitation attempt. */
1052 if (*p != TLS1_HB_REQUEST)
1053 return;
1054
Willy Tarreauaeed6722014-04-25 23:59:58 +02001055 if (len < 1 + 2 + 16) /* 1 type + 2 size + 0 payload + 16 padding */
Willy Tarreauf51c6982014-04-25 20:02:39 +02001056 goto kill_it;
1057
1058 payload = (p[1] * 256) + p[2];
Willy Tarreau3b2fdb62014-04-25 23:44:22 +02001059 if (3 + payload + 16 <= len)
Willy Tarreauf51c6982014-04-25 20:02:39 +02001060 return; /* OK no problem */
Willy Tarreauaeed6722014-04-25 23:59:58 +02001061 kill_it:
Willy Tarreau3b2fdb62014-04-25 23:44:22 +02001062 /* We have a clear heartbleed attack (CVE-2014-0160), the
1063 * advertised payload is larger than the advertised packet
1064 * length, so we have garbage in the buffer between the
1065 * payload and the end of the buffer (p+len). We can't know
1066 * if the SSL stack is patched, and we don't know if we can
1067 * safely wipe out the area between p+3+len and payload.
1068 * So instead, we prevent the response from being sent by
1069 * setting the max_send_fragment to 0 and we report an SSL
1070 * error, which will kill this connection. It will be reported
1071 * above as SSL_ERROR_SSL while an other handshake failure with
Willy Tarreauf51c6982014-04-25 20:02:39 +02001072 * a heartbeat message will be reported as SSL_ERROR_SYSCALL.
1073 */
Willy Tarreau3b2fdb62014-04-25 23:44:22 +02001074 ssl->max_send_fragment = 0;
Willy Tarreauf51c6982014-04-25 20:02:39 +02001075 SSLerr(SSL_F_TLS1_HEARTBEAT, SSL_R_SSL_HANDSHAKE_FAILURE);
1076 return;
1077 }
Emeric Brun29f037d2014-04-25 19:05:36 +02001078#endif
1079}
1080
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02001081#ifdef OPENSSL_NPN_NEGOTIATED
1082/* This callback is used so that the server advertises the list of
1083 * negociable protocols for NPN.
1084 */
1085static int ssl_sock_advertise_npn_protos(SSL *s, const unsigned char **data,
1086 unsigned int *len, void *arg)
1087{
1088 struct bind_conf *conf = arg;
1089
1090 *data = (const unsigned char *)conf->npn_str;
1091 *len = conf->npn_len;
1092 return SSL_TLSEXT_ERR_OK;
1093}
1094#endif
1095
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01001096#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Willy Tarreauab861d32013-04-02 02:30:41 +02001097/* This callback is used so that the server advertises the list of
1098 * negociable protocols for ALPN.
1099 */
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01001100static int ssl_sock_advertise_alpn_protos(SSL *s, const unsigned char **out,
1101 unsigned char *outlen,
1102 const unsigned char *server,
1103 unsigned int server_len, void *arg)
Willy Tarreauab861d32013-04-02 02:30:41 +02001104{
1105 struct bind_conf *conf = arg;
1106
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01001107 if (SSL_select_next_proto((unsigned char**) out, outlen, (const unsigned char *)conf->alpn_str,
1108 conf->alpn_len, server, server_len) != OPENSSL_NPN_NEGOTIATED) {
1109 return SSL_TLSEXT_ERR_NOACK;
1110 }
Willy Tarreauab861d32013-04-02 02:30:41 +02001111 return SSL_TLSEXT_ERR_OK;
1112}
1113#endif
1114
Willy Tarreauc8ad3be2015-06-17 15:48:26 +02001115#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Christopher Faulet85b5a1a2015-10-09 11:46:32 +02001116static DH *ssl_get_tmp_dh(SSL *ssl, int export, int keylen);
1117
Christopher Faulet30548802015-06-11 13:39:32 +02001118/* Create a X509 certificate with the specified servername and serial. This
1119 * function returns a SSL_CTX object or NULL if an error occurs. */
Christopher Faulet7969a332015-10-09 11:15:03 +02001120static SSL_CTX *
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001121ssl_sock_do_create_cert(const char *servername, struct bind_conf *bind_conf, SSL *ssl)
Christopher Faulet31af49d2015-06-09 17:29:50 +02001122{
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001123 static unsigned int serial = 0;
1124
Christopher Faulet7969a332015-10-09 11:15:03 +02001125 X509 *cacert = bind_conf->ca_sign_cert;
1126 EVP_PKEY *capkey = bind_conf->ca_sign_pkey;
Christopher Faulet31af49d2015-06-09 17:29:50 +02001127 SSL_CTX *ssl_ctx = NULL;
1128 X509 *newcrt = NULL;
1129 EVP_PKEY *pkey = NULL;
Christopher Faulet31af49d2015-06-09 17:29:50 +02001130 X509_NAME *name;
1131 const EVP_MD *digest;
1132 X509V3_CTX ctx;
1133 unsigned int i;
1134
Christopher Faulet7969a332015-10-09 11:15:03 +02001135 /* Get the private key of the defautl certificate and use it */
1136 if (!(pkey = SSL_get_privatekey(ssl)))
Christopher Faulet31af49d2015-06-09 17:29:50 +02001137 goto mkcert_error;
1138
1139 /* Create the certificate */
1140 if (!(newcrt = X509_new()))
1141 goto mkcert_error;
1142
1143 /* Set version number for the certificate (X509v3) and the serial
1144 * number */
1145 if (X509_set_version(newcrt, 2L) != 1)
1146 goto mkcert_error;
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001147 if (!serial)
1148 serial = now_ms;
1149 ASN1_INTEGER_set(X509_get_serialNumber(newcrt), serial++);
Christopher Faulet31af49d2015-06-09 17:29:50 +02001150
1151 /* Set duration for the certificate */
1152 if (!X509_gmtime_adj(X509_get_notBefore(newcrt), (long)-60*60*24) ||
1153 !X509_gmtime_adj(X509_get_notAfter(newcrt),(long)60*60*24*365))
1154 goto mkcert_error;
1155
1156 /* set public key in the certificate */
1157 if (X509_set_pubkey(newcrt, pkey) != 1)
1158 goto mkcert_error;
1159
1160 /* Set issuer name from the CA */
1161 if (!(name = X509_get_subject_name(cacert)))
1162 goto mkcert_error;
1163 if (X509_set_issuer_name(newcrt, name) != 1)
1164 goto mkcert_error;
1165
1166 /* Set the subject name using the same, but the CN */
1167 name = X509_NAME_dup(name);
1168 if (X509_NAME_add_entry_by_txt(name, "CN", MBSTRING_ASC,
1169 (const unsigned char *)servername,
1170 -1, -1, 0) != 1) {
1171 X509_NAME_free(name);
1172 goto mkcert_error;
1173 }
1174 if (X509_set_subject_name(newcrt, name) != 1) {
1175 X509_NAME_free(name);
1176 goto mkcert_error;
1177 }
1178 X509_NAME_free(name);
1179
1180 /* Add x509v3 extensions as specified */
1181 X509V3_set_ctx(&ctx, cacert, newcrt, NULL, NULL, 0);
1182 for (i = 0; i < X509V3_EXT_SIZE; i++) {
1183 X509_EXTENSION *ext;
1184
1185 if (!(ext = X509V3_EXT_conf(NULL, &ctx, x509v3_ext_names[i], x509v3_ext_values[i])))
1186 goto mkcert_error;
1187 if (!X509_add_ext(newcrt, ext, -1)) {
1188 X509_EXTENSION_free(ext);
1189 goto mkcert_error;
1190 }
1191 X509_EXTENSION_free(ext);
1192 }
1193
1194 /* Sign the certificate with the CA private key */
1195 if (EVP_PKEY_type(capkey->type) == EVP_PKEY_DSA)
1196 digest = EVP_dss1();
1197 else if (EVP_PKEY_type (capkey->type) == EVP_PKEY_RSA)
1198 digest = EVP_sha256();
Christopher Faulet7969a332015-10-09 11:15:03 +02001199 else if (EVP_PKEY_type (capkey->type) == EVP_PKEY_EC)
1200 digest = EVP_sha256();
1201 else {
Christopher Faulete7db2162015-10-19 13:59:24 +02001202#if (OPENSSL_VERSION_NUMBER >= 0x1000000fL)
Christopher Faulet7969a332015-10-09 11:15:03 +02001203 int nid;
1204
1205 if (EVP_PKEY_get_default_digest_nid(capkey, &nid) <= 0)
1206 goto mkcert_error;
1207 if (!(digest = EVP_get_digestbynid(nid)))
1208 goto mkcert_error;
Christopher Faulete7db2162015-10-19 13:59:24 +02001209#else
1210 goto mkcert_error;
1211#endif
Christopher Faulet7969a332015-10-09 11:15:03 +02001212 }
1213
Christopher Faulet31af49d2015-06-09 17:29:50 +02001214 if (!(X509_sign(newcrt, capkey, digest)))
1215 goto mkcert_error;
1216
1217 /* Create and set the new SSL_CTX */
1218 if (!(ssl_ctx = SSL_CTX_new(SSLv23_server_method())))
1219 goto mkcert_error;
1220 if (!SSL_CTX_use_PrivateKey(ssl_ctx, pkey))
1221 goto mkcert_error;
1222 if (!SSL_CTX_use_certificate(ssl_ctx, newcrt))
1223 goto mkcert_error;
1224 if (!SSL_CTX_check_private_key(ssl_ctx))
1225 goto mkcert_error;
1226
1227 if (newcrt) X509_free(newcrt);
Christopher Faulet7969a332015-10-09 11:15:03 +02001228
Christopher Faulet85b5a1a2015-10-09 11:46:32 +02001229 SSL_CTX_set_tmp_dh_callback(ssl_ctx, ssl_get_tmp_dh);
1230#if defined(SSL_CTX_set_tmp_ecdh) && !defined(OPENSSL_NO_ECDH)
1231 {
1232 const char *ecdhe = (bind_conf->ecdhe ? bind_conf->ecdhe : ECDHE_DEFAULT_CURVE);
1233 EC_KEY *ecc;
1234 int nid;
1235
1236 if ((nid = OBJ_sn2nid(ecdhe)) == NID_undef)
1237 goto end;
1238 if (!(ecc = EC_KEY_new_by_curve_name(nid)))
1239 goto end;
1240 SSL_CTX_set_tmp_ecdh(ssl_ctx, ecc);
1241 EC_KEY_free(ecc);
1242 }
1243#endif
1244 end:
Christopher Faulet31af49d2015-06-09 17:29:50 +02001245 return ssl_ctx;
1246
1247 mkcert_error:
1248 if (ssl_ctx) SSL_CTX_free(ssl_ctx);
1249 if (newcrt) X509_free(newcrt);
Christopher Faulet31af49d2015-06-09 17:29:50 +02001250 return NULL;
1251}
1252
Christopher Faulet7969a332015-10-09 11:15:03 +02001253SSL_CTX *
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001254ssl_sock_create_cert(struct connection *conn, const char *servername, unsigned int key)
Christopher Faulet7969a332015-10-09 11:15:03 +02001255{
1256 struct bind_conf *bind_conf = objt_listener(conn->target)->bind_conf;
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001257
1258 return ssl_sock_do_create_cert(servername, bind_conf, conn->xprt_ctx);
Christopher Faulet7969a332015-10-09 11:15:03 +02001259}
1260
Christopher Faulet30548802015-06-11 13:39:32 +02001261/* Do a lookup for a certificate in the LRU cache used to store generated
1262 * certificates. */
1263SSL_CTX *
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001264ssl_sock_get_generated_cert(unsigned int key, struct bind_conf *bind_conf)
Christopher Faulet30548802015-06-11 13:39:32 +02001265{
1266 struct lru64 *lru = NULL;
1267
1268 if (ssl_ctx_lru_tree) {
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001269 lru = lru64_lookup(key, ssl_ctx_lru_tree, bind_conf->ca_sign_cert, 0);
Christopher Faulet30548802015-06-11 13:39:32 +02001270 if (lru && lru->domain)
1271 return (SSL_CTX *)lru->data;
1272 }
1273 return NULL;
1274}
1275
Christopher Fauletd2cab922015-07-28 16:03:47 +02001276/* Set a certificate int the LRU cache used to store generated
1277 * certificate. Return 0 on success, otherwise -1 */
1278int
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001279ssl_sock_set_generated_cert(SSL_CTX *ssl_ctx, unsigned int key, struct bind_conf *bind_conf)
Christopher Faulet30548802015-06-11 13:39:32 +02001280{
1281 struct lru64 *lru = NULL;
1282
1283 if (ssl_ctx_lru_tree) {
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001284 lru = lru64_get(key, ssl_ctx_lru_tree, bind_conf->ca_sign_cert, 0);
Christopher Faulet30548802015-06-11 13:39:32 +02001285 if (!lru)
Christopher Fauletd2cab922015-07-28 16:03:47 +02001286 return -1;
Christopher Faulet30548802015-06-11 13:39:32 +02001287 if (lru->domain && lru->data)
1288 lru->free((SSL_CTX *)lru->data);
Christopher Faulet7969a332015-10-09 11:15:03 +02001289 lru64_commit(lru, ssl_ctx, bind_conf->ca_sign_cert, 0, (void (*)(void *))SSL_CTX_free);
Christopher Fauletd2cab922015-07-28 16:03:47 +02001290 return 0;
Christopher Faulet30548802015-06-11 13:39:32 +02001291 }
Christopher Fauletd2cab922015-07-28 16:03:47 +02001292 return -1;
Christopher Faulet30548802015-06-11 13:39:32 +02001293}
1294
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001295/* Compute the key of the certificate. */
Christopher Faulet30548802015-06-11 13:39:32 +02001296unsigned int
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001297ssl_sock_generated_cert_key(const void *data, size_t len)
Christopher Faulet30548802015-06-11 13:39:32 +02001298{
1299 return XXH32(data, len, ssl_ctx_lru_seed);
1300}
1301
Willy Tarreau2f63ef42015-10-20 15:16:01 +02001302/* Generate a cert and immediately assign it to the SSL session so that the cert's
1303 * refcount is maintained regardless of the cert's presence in the LRU cache.
1304 */
Christopher Faulet31af49d2015-06-09 17:29:50 +02001305static SSL_CTX *
Christopher Faulet7969a332015-10-09 11:15:03 +02001306ssl_sock_generate_certificate(const char *servername, struct bind_conf *bind_conf, SSL *ssl)
Christopher Faulet31af49d2015-06-09 17:29:50 +02001307{
1308 X509 *cacert = bind_conf->ca_sign_cert;
Christopher Faulet31af49d2015-06-09 17:29:50 +02001309 SSL_CTX *ssl_ctx = NULL;
1310 struct lru64 *lru = NULL;
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001311 unsigned int key;
Christopher Faulet31af49d2015-06-09 17:29:50 +02001312
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001313 key = ssl_sock_generated_cert_key(servername, strlen(servername));
Christopher Faulet31af49d2015-06-09 17:29:50 +02001314 if (ssl_ctx_lru_tree) {
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001315 lru = lru64_get(key, ssl_ctx_lru_tree, cacert, 0);
Christopher Faulet31af49d2015-06-09 17:29:50 +02001316 if (lru && lru->domain)
1317 ssl_ctx = (SSL_CTX *)lru->data;
Christopher Fauletd2cab922015-07-28 16:03:47 +02001318 if (!ssl_ctx && lru) {
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001319 ssl_ctx = ssl_sock_do_create_cert(servername, bind_conf, ssl);
Christopher Faulet31af49d2015-06-09 17:29:50 +02001320 lru64_commit(lru, ssl_ctx, cacert, 0, (void (*)(void *))SSL_CTX_free);
Christopher Fauletd2cab922015-07-28 16:03:47 +02001321 }
Willy Tarreau2f63ef42015-10-20 15:16:01 +02001322 SSL_set_SSL_CTX(ssl, ssl_ctx);
Christopher Faulet31af49d2015-06-09 17:29:50 +02001323 }
Willy Tarreau2f63ef42015-10-20 15:16:01 +02001324 else {
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001325 ssl_ctx = ssl_sock_do_create_cert(servername, bind_conf, ssl);
Willy Tarreau2f63ef42015-10-20 15:16:01 +02001326 SSL_set_SSL_CTX(ssl, ssl_ctx);
1327 /* No LRU cache, this CTX will be released as soon as the session dies */
1328 SSL_CTX_free(ssl_ctx);
1329 }
Christopher Faulet31af49d2015-06-09 17:29:50 +02001330 return ssl_ctx;
1331}
1332
Emeric Brunfc0421f2012-09-07 17:30:07 +02001333/* Sets the SSL ctx of <ssl> to match the advertised server name. Returns a
1334 * warning when no match is found, which implies the default (first) cert
1335 * will keep being used.
1336 */
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001337static int ssl_sock_switchctx_cbk(SSL *ssl, int *al, struct bind_conf *s)
Emeric Brunfc0421f2012-09-07 17:30:07 +02001338{
1339 const char *servername;
1340 const char *wildp = NULL;
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001341 struct ebmb_node *node, *n;
Emeric Brunfc0421f2012-09-07 17:30:07 +02001342 int i;
1343 (void)al; /* shut gcc stupid warning */
1344
1345 servername = SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name);
Emmanuel Hocdet65623372013-01-24 17:17:15 +01001346 if (!servername) {
Willy Tarreauf6721452015-07-07 18:04:38 +02001347 if (s->generate_certs) {
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02001348 struct connection *conn = SSL_get_app_data(ssl);
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001349 unsigned int key;
Willy Tarreauf6721452015-07-07 18:04:38 +02001350 SSL_CTX *ctx;
Christopher Faulet30548802015-06-11 13:39:32 +02001351
Willy Tarreauf6721452015-07-07 18:04:38 +02001352 conn_get_to_addr(conn);
1353 if (conn->flags & CO_FL_ADDR_TO_SET) {
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001354 key = ssl_sock_generated_cert_key(&conn->addr.to, get_addr_len(&conn->addr.to));
1355 ctx = ssl_sock_get_generated_cert(key, s);
Willy Tarreauf6721452015-07-07 18:04:38 +02001356 if (ctx) {
1357 /* switch ctx */
1358 SSL_set_SSL_CTX(ssl, ctx);
1359 return SSL_TLSEXT_ERR_OK;
1360 }
Christopher Faulet30548802015-06-11 13:39:32 +02001361 }
1362 }
1363
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001364 return (s->strict_sni ?
1365 SSL_TLSEXT_ERR_ALERT_FATAL :
Emmanuel Hocdet79274e22013-05-31 12:47:44 +02001366 SSL_TLSEXT_ERR_NOACK);
Emmanuel Hocdet65623372013-01-24 17:17:15 +01001367 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02001368
Willy Tarreau19d14ef2012-10-29 16:51:55 +01001369 for (i = 0; i < trash.size; i++) {
Emeric Brunfc0421f2012-09-07 17:30:07 +02001370 if (!servername[i])
1371 break;
Willy Tarreau19d14ef2012-10-29 16:51:55 +01001372 trash.str[i] = tolower(servername[i]);
1373 if (!wildp && (trash.str[i] == '.'))
1374 wildp = &trash.str[i];
Emeric Brunfc0421f2012-09-07 17:30:07 +02001375 }
Willy Tarreau19d14ef2012-10-29 16:51:55 +01001376 trash.str[i] = 0;
Emeric Brunfc0421f2012-09-07 17:30:07 +02001377
1378 /* lookup in full qualified names */
Willy Tarreau19d14ef2012-10-29 16:51:55 +01001379 node = ebst_lookup(&s->sni_ctx, trash.str);
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001380
1381 /* lookup a not neg filter */
1382 for (n = node; n; n = ebmb_next_dup(n)) {
1383 if (!container_of(n, struct sni_ctx, name)->neg) {
1384 node = n;
1385 break;
Emmanuel Hocdet65623372013-01-24 17:17:15 +01001386 }
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001387 }
1388 if (!node && wildp) {
1389 /* lookup in wildcards names */
Emeric Brunfc0421f2012-09-07 17:30:07 +02001390 node = ebst_lookup(&s->sni_w_ctx, wildp);
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001391 }
1392 if (!node || container_of(node, struct sni_ctx, name)->neg) {
Christopher Faulet31af49d2015-06-09 17:29:50 +02001393 SSL_CTX *ctx;
Christopher Faulet31af49d2015-06-09 17:29:50 +02001394 if (s->generate_certs &&
Christopher Faulet7969a332015-10-09 11:15:03 +02001395 (ctx = ssl_sock_generate_certificate(servername, s, ssl))) {
Christopher Faulet31af49d2015-06-09 17:29:50 +02001396 /* switch ctx */
Christopher Faulet31af49d2015-06-09 17:29:50 +02001397 return SSL_TLSEXT_ERR_OK;
1398 }
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001399 return (s->strict_sni ?
1400 SSL_TLSEXT_ERR_ALERT_FATAL :
1401 SSL_TLSEXT_ERR_ALERT_WARNING);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001402 }
1403
1404 /* switch ctx */
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001405 SSL_set_SSL_CTX(ssl, container_of(node, struct sni_ctx, name)->ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001406 return SSL_TLSEXT_ERR_OK;
1407}
1408#endif /* SSL_CTRL_SET_TLSEXT_HOSTNAME */
1409
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001410#ifndef OPENSSL_NO_DH
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001411
1412static DH * ssl_get_dh_1024(void)
1413{
Remi Gacogned3a341a2015-05-29 16:26:17 +02001414 static unsigned char dh1024_p[]={
1415 0xFA,0xF9,0x2A,0x22,0x2A,0xA7,0x7F,0xE1,0x67,0x4E,0x53,0xF7,
1416 0x56,0x13,0xC3,0xB1,0xE3,0x29,0x6B,0x66,0x31,0x6A,0x7F,0xB3,
1417 0xC2,0x68,0x6B,0xCB,0x1D,0x57,0x39,0x1D,0x1F,0xFF,0x1C,0xC9,
1418 0xA6,0xA4,0x98,0x82,0x31,0x5D,0x25,0xFF,0x8A,0xE0,0x73,0x96,
1419 0x81,0xC8,0x83,0x79,0xC1,0x5A,0x04,0xF8,0x37,0x0D,0xA8,0x3D,
1420 0xAE,0x74,0xBC,0xDB,0xB6,0xA4,0x75,0xD9,0x71,0x8A,0xA0,0x17,
1421 0x9E,0x2D,0xC8,0xA8,0xDF,0x2C,0x5F,0x82,0x95,0xF8,0x92,0x9B,
1422 0xA7,0x33,0x5F,0x89,0x71,0xC8,0x2D,0x6B,0x18,0x86,0xC4,0x94,
1423 0x22,0xA5,0x52,0x8D,0xF6,0xF6,0xD2,0x37,0x92,0x0F,0xA5,0xCC,
1424 0xDB,0x7B,0x1D,0x3D,0xA1,0x31,0xB7,0x80,0x8F,0x0B,0x67,0x5E,
1425 0x36,0xA5,0x60,0x0C,0xF1,0x95,0x33,0x8B,
1426 };
1427 static unsigned char dh1024_g[]={
1428 0x02,
1429 };
1430
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001431 DH *dh = DH_new();
1432 if (dh) {
Remi Gacogned3a341a2015-05-29 16:26:17 +02001433 dh->p = BN_bin2bn(dh1024_p, sizeof dh1024_p, NULL);
1434 dh->g = BN_bin2bn(dh1024_g, sizeof dh1024_g, NULL);
1435
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001436 if (!dh->p || !dh->g) {
1437 DH_free(dh);
1438 dh = NULL;
1439 }
1440 }
1441 return dh;
1442}
1443
1444static DH *ssl_get_dh_2048(void)
1445{
Remi Gacogned3a341a2015-05-29 16:26:17 +02001446 static unsigned char dh2048_p[]={
1447 0xEC,0x86,0xF8,0x70,0xA0,0x33,0x16,0xEC,0x05,0x1A,0x73,0x59,
1448 0xCD,0x1F,0x8B,0xF8,0x29,0xE4,0xD2,0xCF,0x52,0xDD,0xC2,0x24,
1449 0x8D,0xB5,0x38,0x9A,0xFB,0x5C,0xA4,0xE4,0xB2,0xDA,0xCE,0x66,
1450 0x50,0x74,0xA6,0x85,0x4D,0x4B,0x1D,0x30,0xB8,0x2B,0xF3,0x10,
1451 0xE9,0xA7,0x2D,0x05,0x71,0xE7,0x81,0xDF,0x8B,0x59,0x52,0x3B,
1452 0x5F,0x43,0x0B,0x68,0xF1,0xDB,0x07,0xBE,0x08,0x6B,0x1B,0x23,
1453 0xEE,0x4D,0xCC,0x9E,0x0E,0x43,0xA0,0x1E,0xDF,0x43,0x8C,0xEC,
1454 0xBE,0xBE,0x90,0xB4,0x51,0x54,0xB9,0x2F,0x7B,0x64,0x76,0x4E,
1455 0x5D,0xD4,0x2E,0xAE,0xC2,0x9E,0xAE,0x51,0x43,0x59,0xC7,0x77,
1456 0x9C,0x50,0x3C,0x0E,0xED,0x73,0x04,0x5F,0xF1,0x4C,0x76,0x2A,
1457 0xD8,0xF8,0xCF,0xFC,0x34,0x40,0xD1,0xB4,0x42,0x61,0x84,0x66,
1458 0x42,0x39,0x04,0xF8,0x68,0xB2,0x62,0xD7,0x55,0xED,0x1B,0x74,
1459 0x75,0x91,0xE0,0xC5,0x69,0xC1,0x31,0x5C,0xDB,0x7B,0x44,0x2E,
1460 0xCE,0x84,0x58,0x0D,0x1E,0x66,0x0C,0xC8,0x44,0x9E,0xFD,0x40,
1461 0x08,0x67,0x5D,0xFB,0xA7,0x76,0x8F,0x00,0x11,0x87,0xE9,0x93,
1462 0xF9,0x7D,0xC4,0xBC,0x74,0x55,0x20,0xD4,0x4A,0x41,0x2F,0x43,
1463 0x42,0x1A,0xC1,0xF2,0x97,0x17,0x49,0x27,0x37,0x6B,0x2F,0x88,
1464 0x7E,0x1C,0xA0,0xA1,0x89,0x92,0x27,0xD9,0x56,0x5A,0x71,0xC1,
1465 0x56,0x37,0x7E,0x3A,0x9D,0x05,0xE7,0xEE,0x5D,0x8F,0x82,0x17,
1466 0xBC,0xE9,0xC2,0x93,0x30,0x82,0xF9,0xF4,0xC9,0xAE,0x49,0xDB,
1467 0xD0,0x54,0xB4,0xD9,0x75,0x4D,0xFA,0x06,0xB8,0xD6,0x38,0x41,
1468 0xB7,0x1F,0x77,0xF3,
1469 };
1470 static unsigned char dh2048_g[]={
1471 0x02,
1472 };
1473
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001474 DH *dh = DH_new();
1475 if (dh) {
Remi Gacogned3a341a2015-05-29 16:26:17 +02001476 dh->p = BN_bin2bn(dh2048_p, sizeof dh2048_p, NULL);
1477 dh->g = BN_bin2bn(dh2048_g, sizeof dh2048_g, NULL);
1478
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001479 if (!dh->p || !dh->g) {
1480 DH_free(dh);
1481 dh = NULL;
1482 }
1483 }
1484 return dh;
1485}
1486
1487static DH *ssl_get_dh_4096(void)
1488{
Remi Gacogned3a341a2015-05-29 16:26:17 +02001489 static unsigned char dh4096_p[]={
1490 0xDE,0x16,0x94,0xCD,0x99,0x58,0x07,0xF1,0xF7,0x32,0x96,0x11,
1491 0x04,0x82,0xD4,0x84,0x72,0x80,0x99,0x06,0xCA,0xF0,0xA3,0x68,
1492 0x07,0xCE,0x64,0x50,0xE7,0x74,0x45,0x20,0x80,0x5E,0x4D,0xAD,
1493 0xA5,0xB6,0xED,0xFA,0x80,0x6C,0x3B,0x35,0xC4,0x9A,0x14,0x6B,
1494 0x32,0xBB,0xFD,0x1F,0x17,0x8E,0xB7,0x1F,0xD6,0xFA,0x3F,0x7B,
1495 0xEE,0x16,0xA5,0x62,0x33,0x0D,0xED,0xBC,0x4E,0x58,0xE5,0x47,
1496 0x4D,0xE9,0xAB,0x8E,0x38,0xD3,0x6E,0x90,0x57,0xE3,0x22,0x15,
1497 0x33,0xBD,0xF6,0x43,0x45,0xB5,0x10,0x0A,0xBE,0x2C,0xB4,0x35,
1498 0xB8,0x53,0x8D,0xAD,0xFB,0xA7,0x1F,0x85,0x58,0x41,0x7A,0x79,
1499 0x20,0x68,0xB3,0xE1,0x3D,0x08,0x76,0xBF,0x86,0x0D,0x49,0xE3,
1500 0x82,0x71,0x8C,0xB4,0x8D,0x81,0x84,0xD4,0xE7,0xBE,0x91,0xDC,
1501 0x26,0x39,0x48,0x0F,0x35,0xC4,0xCA,0x65,0xE3,0x40,0x93,0x52,
1502 0x76,0x58,0x7D,0xDD,0x51,0x75,0xDC,0x69,0x61,0xBF,0x47,0x2C,
1503 0x16,0x68,0x2D,0xC9,0x29,0xD3,0xE6,0xC0,0x99,0x48,0xA0,0x9A,
1504 0xC8,0x78,0xC0,0x6D,0x81,0x67,0x12,0x61,0x3F,0x71,0xBA,0x41,
1505 0x1F,0x6C,0x89,0x44,0x03,0xBA,0x3B,0x39,0x60,0xAA,0x28,0x55,
1506 0x59,0xAE,0xB8,0xFA,0xCB,0x6F,0xA5,0x1A,0xF7,0x2B,0xDD,0x52,
1507 0x8A,0x8B,0xE2,0x71,0xA6,0x5E,0x7E,0xD8,0x2E,0x18,0xE0,0x66,
1508 0xDF,0xDD,0x22,0x21,0x99,0x52,0x73,0xA6,0x33,0x20,0x65,0x0E,
1509 0x53,0xE7,0x6B,0x9B,0xC5,0xA3,0x2F,0x97,0x65,0x76,0xD3,0x47,
1510 0x23,0x77,0x12,0xB6,0x11,0x7B,0x24,0xED,0xF1,0xEF,0xC0,0xE2,
1511 0xA3,0x7E,0x67,0x05,0x3E,0x96,0x4D,0x45,0xC2,0x18,0xD1,0x73,
1512 0x9E,0x07,0xF3,0x81,0x6E,0x52,0x63,0xF6,0x20,0x76,0xB9,0x13,
1513 0xD2,0x65,0x30,0x18,0x16,0x09,0x16,0x9E,0x8F,0xF1,0xD2,0x10,
1514 0x5A,0xD3,0xD4,0xAF,0x16,0x61,0xDA,0x55,0x2E,0x18,0x5E,0x14,
1515 0x08,0x54,0x2E,0x2A,0x25,0xA2,0x1A,0x9B,0x8B,0x32,0xA9,0xFD,
1516 0xC2,0x48,0x96,0xE1,0x80,0xCA,0xE9,0x22,0x17,0xBB,0xCE,0x3E,
1517 0x9E,0xED,0xC7,0xF1,0x1F,0xEC,0x17,0x21,0xDC,0x7B,0x82,0x48,
1518 0x8E,0xBB,0x4B,0x9D,0x5B,0x04,0x04,0xDA,0xDB,0x39,0xDF,0x01,
1519 0x40,0xC3,0xAA,0x26,0x23,0x89,0x75,0xC6,0x0B,0xD0,0xA2,0x60,
1520 0x6A,0xF1,0xCC,0x65,0x18,0x98,0x1B,0x52,0xD2,0x74,0x61,0xCC,
1521 0xBD,0x60,0xAE,0xA3,0xA0,0x66,0x6A,0x16,0x34,0x92,0x3F,0x41,
1522 0x40,0x31,0x29,0xC0,0x2C,0x63,0xB2,0x07,0x8D,0xEB,0x94,0xB8,
1523 0xE8,0x47,0x92,0x52,0x93,0x6A,0x1B,0x7E,0x1A,0x61,0xB3,0x1B,
1524 0xF0,0xD6,0x72,0x9B,0xF1,0xB0,0xAF,0xBF,0x3E,0x65,0xEF,0x23,
1525 0x1D,0x6F,0xFF,0x70,0xCD,0x8A,0x4C,0x8A,0xA0,0x72,0x9D,0xBE,
1526 0xD4,0xBB,0x24,0x47,0x4A,0x68,0xB5,0xF5,0xC6,0xD5,0x7A,0xCD,
1527 0xCA,0x06,0x41,0x07,0xAD,0xC2,0x1E,0xE6,0x54,0xA7,0xAD,0x03,
1528 0xD9,0x12,0xC1,0x9C,0x13,0xB1,0xC9,0x0A,0x43,0x8E,0x1E,0x08,
1529 0xCE,0x50,0x82,0x73,0x5F,0xA7,0x55,0x1D,0xD9,0x59,0xAC,0xB5,
1530 0xEA,0x02,0x7F,0x6C,0x5B,0x74,0x96,0x98,0x67,0x24,0xA3,0x0F,
1531 0x15,0xFC,0xA9,0x7D,0x3E,0x67,0xD1,0x70,0xF8,0x97,0xF3,0x67,
1532 0xC5,0x8C,0x88,0x44,0x08,0x02,0xC7,0x2B,
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001533 };
Remi Gacogned3a341a2015-05-29 16:26:17 +02001534 static unsigned char dh4096_g[]={
1535 0x02,
1536 };
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001537
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001538 DH *dh = DH_new();
1539 if (dh) {
Remi Gacogned3a341a2015-05-29 16:26:17 +02001540 dh->p = BN_bin2bn(dh4096_p, sizeof dh4096_p, NULL);
1541 dh->g = BN_bin2bn(dh4096_g, sizeof dh4096_g, NULL);
1542
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001543 if (!dh->p || !dh->g) {
1544 DH_free(dh);
1545 dh = NULL;
1546 }
1547 }
1548 return dh;
1549}
1550
1551/* Returns Diffie-Hellman parameters matching the private key length
1552 but not exceeding global.tune.ssl_default_dh_param */
1553static DH *ssl_get_tmp_dh(SSL *ssl, int export, int keylen)
1554{
1555 DH *dh = NULL;
1556 EVP_PKEY *pkey = SSL_get_privatekey(ssl);
1557 int type = pkey ? EVP_PKEY_type(pkey->type) : EVP_PKEY_NONE;
1558
1559 /* The keylen supplied by OpenSSL can only be 512 or 1024.
1560 See ssl3_send_server_key_exchange() in ssl/s3_srvr.c
1561 */
1562 if (type == EVP_PKEY_RSA || type == EVP_PKEY_DSA) {
1563 keylen = EVP_PKEY_bits(pkey);
1564 }
1565
1566 if (keylen > global.tune.ssl_default_dh_param) {
1567 keylen = global.tune.ssl_default_dh_param;
1568 }
1569
Remi Gacogned3a341a2015-05-29 16:26:17 +02001570 if (keylen >= 4096) {
Remi Gacogne8de54152014-07-15 11:36:40 +02001571 dh = local_dh_4096;
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001572 }
1573 else if (keylen >= 2048) {
Remi Gacogne8de54152014-07-15 11:36:40 +02001574 dh = local_dh_2048;
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001575 }
1576 else {
Remi Gacogne8de54152014-07-15 11:36:40 +02001577 dh = local_dh_1024;
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001578 }
1579
1580 return dh;
1581}
1582
Remi Gacogne47783ef2015-05-29 15:53:22 +02001583static DH * ssl_sock_get_dh_from_file(const char *filename)
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001584{
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001585 DH *dh = NULL;
Remi Gacogne47783ef2015-05-29 15:53:22 +02001586 BIO *in = BIO_new(BIO_s_file());
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001587
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001588 if (in == NULL)
1589 goto end;
1590
Remi Gacogne47783ef2015-05-29 15:53:22 +02001591 if (BIO_read_filename(in, filename) <= 0)
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001592 goto end;
1593
Remi Gacogne47783ef2015-05-29 15:53:22 +02001594 dh = PEM_read_bio_DHparams(in, NULL, NULL, NULL);
1595
1596end:
1597 if (in)
1598 BIO_free(in);
1599
1600 return dh;
1601}
1602
1603int ssl_sock_load_global_dh_param_from_file(const char *filename)
1604{
1605 global_dh = ssl_sock_get_dh_from_file(filename);
1606
1607 if (global_dh) {
1608 return 0;
1609 }
1610
1611 return -1;
1612}
1613
1614/* Loads Diffie-Hellman parameter from a file. Returns 1 if loaded, else -1
1615 if an error occured, and 0 if parameter not found. */
1616int ssl_sock_load_dh_params(SSL_CTX *ctx, const char *file)
1617{
1618 int ret = -1;
1619 DH *dh = ssl_sock_get_dh_from_file(file);
1620
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001621 if (dh) {
1622 ret = 1;
1623 SSL_CTX_set_tmp_dh(ctx, dh);
Remi Gacogne4f902b82015-05-28 16:23:00 +02001624
1625 if (ssl_dh_ptr_index >= 0) {
1626 /* store a pointer to the DH params to avoid complaining about
1627 ssl-default-dh-param not being set for this SSL_CTX */
1628 SSL_CTX_set_ex_data(ctx, ssl_dh_ptr_index, dh);
1629 }
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001630 }
Remi Gacogne47783ef2015-05-29 15:53:22 +02001631 else if (global_dh) {
1632 SSL_CTX_set_tmp_dh(ctx, global_dh);
1633 ret = 0; /* DH params not found */
1634 }
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001635 else {
Emeric Brun41fdb3c2013-04-26 11:05:44 +02001636 /* Clear openssl global errors stack */
1637 ERR_clear_error();
1638
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001639 if (global.tune.ssl_default_dh_param <= 1024) {
1640 /* we are limited to DH parameter of 1024 bits anyway */
Remi Gacogne8de54152014-07-15 11:36:40 +02001641 local_dh_1024 = ssl_get_dh_1024();
1642 if (local_dh_1024 == NULL)
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001643 goto end;
Willy Tarreau6e774b42014-04-25 21:35:23 +02001644
Remi Gacogne8de54152014-07-15 11:36:40 +02001645 SSL_CTX_set_tmp_dh(ctx, local_dh_1024);
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001646 }
1647 else {
1648 SSL_CTX_set_tmp_dh_callback(ctx, ssl_get_tmp_dh);
1649 }
Willy Tarreau6e774b42014-04-25 21:35:23 +02001650
Emeric Brun41fdb3c2013-04-26 11:05:44 +02001651 ret = 0; /* DH params not found */
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001652 }
Emeric Brun644cde02012-12-14 11:21:13 +01001653
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001654end:
1655 if (dh)
1656 DH_free(dh);
1657
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001658 return ret;
1659}
1660#endif
1661
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001662static int ssl_sock_add_cert_sni(SSL_CTX *ctx, struct bind_conf *s, char *name, int order)
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001663{
1664 struct sni_ctx *sc;
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001665 int wild = 0, neg = 0;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001666
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001667 if (*name == '!') {
1668 neg = 1;
1669 name++;
1670 }
1671 if (*name == '*') {
1672 wild = 1;
1673 name++;
1674 }
1675 /* !* filter is a nop */
1676 if (neg && wild)
1677 return order;
1678 if (*name) {
1679 int j, len;
1680 len = strlen(name);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001681 sc = malloc(sizeof(struct sni_ctx) + len + 1);
1682 for (j = 0; j < len; j++)
1683 sc->name.key[j] = tolower(name[j]);
1684 sc->name.key[len] = 0;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001685 sc->ctx = ctx;
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001686 sc->order = order++;
1687 sc->neg = neg;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001688 if (wild)
1689 ebst_insert(&s->sni_w_ctx, &sc->name);
1690 else
1691 ebst_insert(&s->sni_ctx, &sc->name);
1692 }
1693 return order;
1694}
1695
yanbzhu488a4d22015-12-01 15:16:07 -05001696
1697/* The following code is used for loading multiple crt files into
1698 * SSL_CTX's based on CN/SAN
1699 */
1700#if OPENSSL_VERSION_NUMBER >= 0x1000200fL
1701/* This is used to preload the certifcate, private key
1702 * and Cert Chain of a file passed in via the crt
1703 * argument
1704 *
1705 * This way, we do not have to read the file multiple times
1706 */
1707struct cert_key_and_chain {
1708 X509 *cert;
1709 EVP_PKEY *key;
1710 unsigned int num_chain_certs;
1711 /* This is an array of X509 pointers */
1712 X509 **chain_certs;
1713};
1714
yanbzhu08ce6ab2015-12-02 13:01:29 -05001715#define SSL_SOCK_POSSIBLE_KT_COMBOS (1<<(SSL_SOCK_NUM_KEYTYPES))
1716
1717struct key_combo_ctx {
1718 SSL_CTX *ctx;
1719 int order;
1720};
1721
1722/* Map used for processing multiple keypairs for a single purpose
1723 *
1724 * This maps CN/SNI name to certificate type
1725 */
1726struct sni_keytype {
1727 int keytypes; /* BITMASK for keytypes */
1728 struct ebmb_node name; /* node holding the servername value */
1729};
1730
1731
yanbzhu488a4d22015-12-01 15:16:07 -05001732/* Frees the contents of a cert_key_and_chain
1733 */
1734static void ssl_sock_free_cert_key_and_chain_contents(struct cert_key_and_chain *ckch)
1735{
1736 int i;
1737
1738 if (!ckch)
1739 return;
1740
1741 /* Free the certificate and set pointer to NULL */
1742 if (ckch->cert)
1743 X509_free(ckch->cert);
1744 ckch->cert = NULL;
1745
1746 /* Free the key and set pointer to NULL */
1747 if (ckch->key)
1748 EVP_PKEY_free(ckch->key);
1749 ckch->key = NULL;
1750
1751 /* Free each certificate in the chain */
1752 for (i = 0; i < ckch->num_chain_certs; i++) {
1753 if (ckch->chain_certs[i])
1754 X509_free(ckch->chain_certs[i]);
1755 }
1756
1757 /* Free the chain obj itself and set to NULL */
1758 if (ckch->num_chain_certs > 0) {
1759 free(ckch->chain_certs);
1760 ckch->num_chain_certs = 0;
1761 ckch->chain_certs = NULL;
1762 }
1763
1764}
1765
1766/* checks if a key and cert exists in the ckch
1767 */
1768static int ssl_sock_is_ckch_valid(struct cert_key_and_chain *ckch)
1769{
1770 return (ckch->cert != NULL && ckch->key != NULL);
1771}
1772
1773
1774/* Loads the contents of a crt file (path) into a cert_key_and_chain
1775 * This allows us to carry the contents of the file without having to
1776 * read the file multiple times.
1777 *
1778 * returns:
1779 * 0 on Success
1780 * 1 on SSL Failure
1781 * 2 on file not found
1782 */
1783static int ssl_sock_load_crt_file_into_ckch(const char *path, struct cert_key_and_chain *ckch, char **err)
1784{
1785
1786 BIO *in;
1787 X509 *ca = NULL;
1788 int ret = 1;
1789
1790 ssl_sock_free_cert_key_and_chain_contents(ckch);
1791
1792 in = BIO_new(BIO_s_file());
1793 if (in == NULL)
1794 goto end;
1795
1796 if (BIO_read_filename(in, path) <= 0)
1797 goto end;
1798
yanbzhu488a4d22015-12-01 15:16:07 -05001799 /* Read Private Key */
1800 ckch->key = PEM_read_bio_PrivateKey(in, NULL, NULL, NULL);
1801 if (ckch->key == NULL) {
1802 memprintf(err, "%sunable to load private key from file '%s'.\n",
1803 err && *err ? *err : "", path);
1804 goto end;
1805 }
1806
Willy Tarreaubb137a82016-04-06 19:02:38 +02001807 /* Seek back to beginning of file */
1808 BIO_reset(in);
1809
1810 /* Read Certificate */
1811 ckch->cert = PEM_read_bio_X509_AUX(in, NULL, NULL, NULL);
1812 if (ckch->cert == NULL) {
1813 memprintf(err, "%sunable to load certificate from file '%s'.\n",
1814 err && *err ? *err : "", path);
1815 goto end;
1816 }
1817
yanbzhu488a4d22015-12-01 15:16:07 -05001818 /* Read Certificate Chain */
1819 while ((ca = PEM_read_bio_X509(in, NULL, NULL, NULL))) {
1820 /* Grow the chain certs */
1821 ckch->num_chain_certs++;
1822 ckch->chain_certs = realloc(ckch->chain_certs, (ckch->num_chain_certs * sizeof(X509 *)));
1823
1824 /* use - 1 here since we just incremented it above */
1825 ckch->chain_certs[ckch->num_chain_certs - 1] = ca;
1826 }
1827 ret = ERR_get_error();
1828 if (ret && (ERR_GET_LIB(ret) != ERR_LIB_PEM && ERR_GET_REASON(ret) != PEM_R_NO_START_LINE)) {
1829 memprintf(err, "%sunable to load certificate chain from file '%s'.\n",
1830 err && *err ? *err : "", path);
1831 ret = 1;
1832 goto end;
1833 }
1834
1835 ret = 0;
1836
1837end:
1838
1839 ERR_clear_error();
1840 if (in)
1841 BIO_free(in);
1842
1843 /* Something went wrong in one of the reads */
1844 if (ret != 0)
1845 ssl_sock_free_cert_key_and_chain_contents(ckch);
1846
1847 return ret;
1848}
1849
1850/* Loads the info in ckch into ctx
1851 * Currently, this does not process any information about ocsp, dhparams or
1852 * sctl
1853 * Returns
1854 * 0 on success
1855 * 1 on failure
1856 */
1857static int ssl_sock_put_ckch_into_ctx(const char *path, const struct cert_key_and_chain *ckch, SSL_CTX *ctx, char **err)
1858{
1859 int i = 0;
1860
1861 if (SSL_CTX_use_PrivateKey(ctx, ckch->key) <= 0) {
1862 memprintf(err, "%sunable to load SSL private key into SSL Context '%s'.\n",
1863 err && *err ? *err : "", path);
1864 return 1;
1865 }
1866
1867 if (!SSL_CTX_use_certificate(ctx, ckch->cert)) {
1868 memprintf(err, "%sunable to load SSL certificate into SSL Context '%s'.\n",
1869 err && *err ? *err : "", path);
1870 return 1;
1871 }
1872
yanbzhu488a4d22015-12-01 15:16:07 -05001873 /* Load all certs in the ckch into the ctx_chain for the ssl_ctx */
1874 for (i = 0; i < ckch->num_chain_certs; i++) {
1875 if (!SSL_CTX_add1_chain_cert(ctx, ckch->chain_certs[i])) {
yanbzhu08ce6ab2015-12-02 13:01:29 -05001876 memprintf(err, "%sunable to load chain certificate #%d into SSL Context '%s'. Make sure you are linking against Openssl >= 1.0.2.\n",
1877 err && *err ? *err : "", (i+1), path);
yanbzhu488a4d22015-12-01 15:16:07 -05001878 return 1;
1879 }
1880 }
1881
1882 if (SSL_CTX_check_private_key(ctx) <= 0) {
1883 memprintf(err, "%sinconsistencies between private key and certificate loaded from PEM file '%s'.\n",
1884 err && *err ? *err : "", path);
1885 return 1;
1886 }
1887
1888 return 0;
1889}
1890
yanbzhu08ce6ab2015-12-02 13:01:29 -05001891
1892static void ssl_sock_populate_sni_keytypes_hplr(const char *str, struct eb_root *sni_keytypes, int key_index)
1893{
1894 struct sni_keytype *s_kt = NULL;
1895 struct ebmb_node *node;
1896 int i;
1897
1898 for (i = 0; i < trash.size; i++) {
1899 if (!str[i])
1900 break;
1901 trash.str[i] = tolower(str[i]);
1902 }
1903 trash.str[i] = 0;
1904 node = ebst_lookup(sni_keytypes, trash.str);
1905 if (!node) {
1906 /* CN not found in tree */
1907 s_kt = malloc(sizeof(struct sni_keytype) + i + 1);
1908 /* Using memcpy here instead of strncpy.
1909 * strncpy will cause sig_abrt errors under certain versions of gcc with -O2
1910 * See: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=60792
1911 */
1912 memcpy(s_kt->name.key, trash.str, i+1);
1913 s_kt->keytypes = 0;
1914 ebst_insert(sni_keytypes, &s_kt->name);
1915 } else {
1916 /* CN found in tree */
1917 s_kt = container_of(node, struct sni_keytype, name);
1918 }
1919
1920 /* Mark that this CN has the keytype of key_index via keytypes mask */
1921 s_kt->keytypes |= 1<<key_index;
1922
1923}
1924
1925
1926/* Given a path that does not exist, try to check for path.rsa, path.dsa and path.ecdsa files.
1927 * If any are found, group these files into a set of SSL_CTX*
1928 * based on shared and unique CN and SAN entries. Add these SSL_CTX* to the SNI tree.
1929 *
1930 * This will allow the user to explictly group multiple cert/keys for a single purpose
1931 *
1932 * Returns
1933 * 0 on success
1934 * 1 on failure
1935 */
Emmanuel Hocdetd294aea2016-05-13 11:14:06 +02001936static 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 -05001937{
1938 char fp[MAXPATHLEN+1] = {0};
1939 int n = 0;
1940 int i = 0;
1941 struct cert_key_and_chain certs_and_keys[SSL_SOCK_NUM_KEYTYPES] = { {0} };
1942 struct eb_root sni_keytypes_map = { {0} };
1943 struct ebmb_node *node;
1944 struct ebmb_node *next;
1945 /* Array of SSL_CTX pointers corresponding to each possible combo
1946 * of keytypes
1947 */
1948 struct key_combo_ctx key_combos[SSL_SOCK_POSSIBLE_KT_COMBOS] = { {0} };
1949 int rv = 0;
1950 X509_NAME *xname = NULL;
1951 char *str = NULL;
1952#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
1953 STACK_OF(GENERAL_NAME) *names = NULL;
1954#endif
1955
1956 /* Load all possible certs and keys */
1957 for (n = 0; n < SSL_SOCK_NUM_KEYTYPES; n++) {
1958 struct stat buf;
1959
1960 snprintf(fp, sizeof(fp), "%s.%s", path, SSL_SOCK_KEYTYPE_NAMES[n]);
1961 if (stat(fp, &buf) == 0) {
1962 if (ssl_sock_load_crt_file_into_ckch(fp, &certs_and_keys[n], err) == 1) {
1963 rv = 1;
1964 goto end;
1965 }
1966 }
1967 }
1968
1969 /* Process each ckch and update keytypes for each CN/SAN
1970 * for example, if CN/SAN www.a.com is associated with
1971 * certs with keytype 0 and 2, then at the end of the loop,
1972 * www.a.com will have:
1973 * keyindex = 0 | 1 | 4 = 5
1974 */
1975 for (n = 0; n < SSL_SOCK_NUM_KEYTYPES; n++) {
1976
1977 if (!ssl_sock_is_ckch_valid(&certs_and_keys[n]))
1978 continue;
1979
Emmanuel Hocdetd294aea2016-05-13 11:14:06 +02001980 if (fcount) {
Willy Tarreau24b892f2016-06-20 23:01:57 +02001981 for (i = 0; i < fcount; i++)
Emmanuel Hocdetd294aea2016-05-13 11:14:06 +02001982 ssl_sock_populate_sni_keytypes_hplr(sni_filter[i], &sni_keytypes_map, n);
1983 } else {
1984 /* A lot of the following code is OpenSSL boilerplate for processing CN's and SAN's,
1985 * so the line that contains logic is marked via comments
1986 */
1987 xname = X509_get_subject_name(certs_and_keys[n].cert);
1988 i = -1;
1989 while ((i = X509_NAME_get_index_by_NID(xname, NID_commonName, i)) != -1) {
1990 X509_NAME_ENTRY *entry = X509_NAME_get_entry(xname, i);
yanbzhu08ce6ab2015-12-02 13:01:29 -05001991
Emmanuel Hocdetd294aea2016-05-13 11:14:06 +02001992 if (ASN1_STRING_to_UTF8((unsigned char **)&str, entry->value) >= 0) {
1993 /* Important line is here */
1994 ssl_sock_populate_sni_keytypes_hplr(str, &sni_keytypes_map, n);
yanbzhu08ce6ab2015-12-02 13:01:29 -05001995
Emmanuel Hocdetd294aea2016-05-13 11:14:06 +02001996 OPENSSL_free(str);
1997 str = NULL;
1998 }
yanbzhu08ce6ab2015-12-02 13:01:29 -05001999 }
yanbzhu08ce6ab2015-12-02 13:01:29 -05002000
Emmanuel Hocdetd294aea2016-05-13 11:14:06 +02002001 /* Do the above logic for each SAN */
yanbzhu08ce6ab2015-12-02 13:01:29 -05002002#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Emmanuel Hocdetd294aea2016-05-13 11:14:06 +02002003 names = X509_get_ext_d2i(certs_and_keys[n].cert, NID_subject_alt_name, NULL, NULL);
2004 if (names) {
2005 for (i = 0; i < sk_GENERAL_NAME_num(names); i++) {
2006 GENERAL_NAME *name = sk_GENERAL_NAME_value(names, i);
yanbzhu08ce6ab2015-12-02 13:01:29 -05002007
Emmanuel Hocdetd294aea2016-05-13 11:14:06 +02002008 if (name->type == GEN_DNS) {
2009 if (ASN1_STRING_to_UTF8((unsigned char **)&str, name->d.dNSName) >= 0) {
2010 /* Important line is here */
2011 ssl_sock_populate_sni_keytypes_hplr(str, &sni_keytypes_map, n);
yanbzhu08ce6ab2015-12-02 13:01:29 -05002012
Emmanuel Hocdetd294aea2016-05-13 11:14:06 +02002013 OPENSSL_free(str);
2014 str = NULL;
2015 }
yanbzhu08ce6ab2015-12-02 13:01:29 -05002016 }
2017 }
2018 }
2019 }
2020#endif /* SSL_CTRL_SET_TLSEXT_HOSTNAME */
2021 }
2022
2023 /* If no files found, return error */
2024 if (eb_is_empty(&sni_keytypes_map)) {
2025 memprintf(err, "%sunable to load SSL certificate file '%s' file does not exist.\n",
2026 err && *err ? *err : "", path);
2027 rv = 1;
2028 goto end;
2029 }
2030
2031 /* We now have a map of CN/SAN to keytypes that are loaded in
2032 * Iterate through the map to create the SSL_CTX's (if needed)
2033 * and add each CTX to the SNI tree
2034 *
2035 * Some math here:
2036 * There are 2^n - 1 possibile combinations, each unique
2037 * combination is denoted by the key in the map. Each key
2038 * has a value between 1 and 2^n - 1. Conveniently, the array
2039 * of SSL_CTX* is sized 2^n. So, we can simply use the i'th
2040 * entry in the array to correspond to the unique combo (key)
2041 * associated with i. This unique key combo (i) will be associated
2042 * with combos[i-1]
2043 */
2044
2045 node = ebmb_first(&sni_keytypes_map);
2046 while (node) {
2047 SSL_CTX *cur_ctx;
2048
2049 str = (char *)container_of(node, struct sni_keytype, name)->name.key;
2050 i = container_of(node, struct sni_keytype, name)->keytypes;
2051 cur_ctx = key_combos[i-1].ctx;
2052
2053 if (cur_ctx == NULL) {
2054 /* need to create SSL_CTX */
2055 cur_ctx = SSL_CTX_new(SSLv23_server_method());
2056 if (cur_ctx == NULL) {
2057 memprintf(err, "%sunable to allocate SSL context.\n",
2058 err && *err ? *err : "");
2059 rv = 1;
2060 goto end;
2061 }
2062
yanbzhube2774d2015-12-10 15:07:30 -05002063 /* Load all required certs/keys/chains/OCSPs info into SSL_CTX */
yanbzhu08ce6ab2015-12-02 13:01:29 -05002064 for (n = 0; n < SSL_SOCK_NUM_KEYTYPES; n++) {
2065 if (i & (1<<n)) {
2066 /* Key combo contains ckch[n] */
2067 snprintf(trash.str, trash.size, "%s.%s", path, SSL_SOCK_KEYTYPE_NAMES[n]);
2068 if (ssl_sock_put_ckch_into_ctx(trash.str, &certs_and_keys[n], cur_ctx, err) != 0) {
2069 SSL_CTX_free(cur_ctx);
2070 rv = 1;
2071 goto end;
2072 }
yanbzhube2774d2015-12-10 15:07:30 -05002073
2074#if (defined SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB && !defined OPENSSL_NO_OCSP)
2075 /* Load OCSP Info into context */
2076 if (ssl_sock_load_ocsp(cur_ctx, trash.str) < 0) {
2077 if (err)
2078 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",
2079 *err ? *err : "", path);
2080 SSL_CTX_free(cur_ctx);
2081 rv = 1;
2082 goto end;
2083 }
2084#endif
yanbzhu08ce6ab2015-12-02 13:01:29 -05002085 }
2086 }
2087
2088 /* Load DH params into the ctx to support DHE keys */
2089#ifndef OPENSSL_NO_DH
2090 if (ssl_dh_ptr_index >= 0)
2091 SSL_CTX_set_ex_data(cur_ctx, ssl_dh_ptr_index, NULL);
2092
2093 rv = ssl_sock_load_dh_params(cur_ctx, NULL);
2094 if (rv < 0) {
2095 if (err)
2096 memprintf(err, "%sunable to load DH parameters from file '%s'.\n",
2097 *err ? *err : "", path);
2098 rv = 1;
2099 goto end;
2100 }
2101#endif
2102
2103 /* Update key_combos */
2104 key_combos[i-1].ctx = cur_ctx;
2105 }
2106
2107 /* Update SNI Tree */
Emmanuel Hocdetd294aea2016-05-13 11:14:06 +02002108 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 -05002109 node = ebmb_next(node);
2110 }
2111
2112
2113 /* Mark a default context if none exists, using the ctx that has the most shared keys */
2114 if (!bind_conf->default_ctx) {
2115 for (i = SSL_SOCK_POSSIBLE_KT_COMBOS - 1; i >= 0; i--) {
2116 if (key_combos[i].ctx) {
2117 bind_conf->default_ctx = key_combos[i].ctx;
2118 break;
2119 }
2120 }
2121 }
2122
2123end:
2124
2125 if (names)
2126 sk_GENERAL_NAME_pop_free(names, GENERAL_NAME_free);
2127
2128 for (n = 0; n < SSL_SOCK_NUM_KEYTYPES; n++)
2129 ssl_sock_free_cert_key_and_chain_contents(&certs_and_keys[n]);
2130
2131 node = ebmb_first(&sni_keytypes_map);
2132 while (node) {
2133 next = ebmb_next(node);
2134 ebmb_delete(node);
2135 node = next;
2136 }
2137
2138 return rv;
2139}
2140#else
2141/* This is a dummy, that just logs an error and returns error */
Emmanuel Hocdetd294aea2016-05-13 11:14:06 +02002142static 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 -05002143{
2144 memprintf(err, "%sunable to stat SSL certificate from file '%s' : %s.\n",
2145 err && *err ? *err : "", path, strerror(errno));
2146 return 1;
2147}
2148
yanbzhu488a4d22015-12-01 15:16:07 -05002149#endif /* #if OPENSSL_VERSION_NUMBER >= 0x1000200fL: Support for loading multiple certs into a single SSL_CTX */
2150
Emeric Brunfc0421f2012-09-07 17:30:07 +02002151/* Loads a certificate key and CA chain from a file. Returns 0 on error, -1 if
2152 * an early error happens and the caller must call SSL_CTX_free() by itelf.
2153 */
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02002154static 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 +02002155{
2156 BIO *in;
2157 X509 *x = NULL, *ca;
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02002158 int i, err;
Emeric Brunfc0421f2012-09-07 17:30:07 +02002159 int ret = -1;
2160 int order = 0;
2161 X509_NAME *xname;
2162 char *str;
Emeric Brunfc0421f2012-09-07 17:30:07 +02002163#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
2164 STACK_OF(GENERAL_NAME) *names;
2165#endif
2166
2167 in = BIO_new(BIO_s_file());
2168 if (in == NULL)
2169 goto end;
2170
2171 if (BIO_read_filename(in, file) <= 0)
2172 goto end;
2173
2174 x = PEM_read_bio_X509_AUX(in, NULL, ctx->default_passwd_callback, ctx->default_passwd_callback_userdata);
2175 if (x == NULL)
2176 goto end;
2177
Emeric Brun50bcecc2013-04-22 13:05:23 +02002178 if (fcount) {
2179 while (fcount--)
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02002180 order = ssl_sock_add_cert_sni(ctx, s, sni_filter[fcount], order);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002181 }
2182 else {
Emeric Brunfc0421f2012-09-07 17:30:07 +02002183#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002184 names = X509_get_ext_d2i(x, NID_subject_alt_name, NULL, NULL);
2185 if (names) {
2186 for (i = 0; i < sk_GENERAL_NAME_num(names); i++) {
2187 GENERAL_NAME *name = sk_GENERAL_NAME_value(names, i);
2188 if (name->type == GEN_DNS) {
2189 if (ASN1_STRING_to_UTF8((unsigned char **)&str, name->d.dNSName) >= 0) {
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02002190 order = ssl_sock_add_cert_sni(ctx, s, str, order);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002191 OPENSSL_free(str);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002192 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02002193 }
2194 }
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002195 sk_GENERAL_NAME_pop_free(names, GENERAL_NAME_free);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002196 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02002197#endif /* SSL_CTRL_SET_TLSEXT_HOSTNAME */
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002198 xname = X509_get_subject_name(x);
2199 i = -1;
2200 while ((i = X509_NAME_get_index_by_NID(xname, NID_commonName, i)) != -1) {
2201 X509_NAME_ENTRY *entry = X509_NAME_get_entry(xname, i);
2202 if (ASN1_STRING_to_UTF8((unsigned char **)&str, entry->value) >= 0) {
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02002203 order = ssl_sock_add_cert_sni(ctx, s, str, order);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002204 OPENSSL_free(str);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002205 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02002206 }
2207 }
2208
2209 ret = 0; /* the caller must not free the SSL_CTX argument anymore */
2210 if (!SSL_CTX_use_certificate(ctx, x))
2211 goto end;
2212
2213 if (ctx->extra_certs != NULL) {
2214 sk_X509_pop_free(ctx->extra_certs, X509_free);
2215 ctx->extra_certs = NULL;
2216 }
2217
2218 while ((ca = PEM_read_bio_X509(in, NULL, ctx->default_passwd_callback, ctx->default_passwd_callback_userdata))) {
2219 if (!SSL_CTX_add_extra_chain_cert(ctx, ca)) {
2220 X509_free(ca);
2221 goto end;
2222 }
2223 }
2224
2225 err = ERR_get_error();
2226 if (!err || (ERR_GET_LIB(err) == ERR_LIB_PEM && ERR_GET_REASON(err) == PEM_R_NO_START_LINE)) {
2227 /* we successfully reached the last cert in the file */
2228 ret = 1;
2229 }
2230 ERR_clear_error();
2231
2232end:
2233 if (x)
2234 X509_free(x);
2235
2236 if (in)
2237 BIO_free(in);
2238
2239 return ret;
2240}
2241
Emeric Brun50bcecc2013-04-22 13:05:23 +02002242static 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 +02002243{
2244 int ret;
2245 SSL_CTX *ctx;
2246
2247 ctx = SSL_CTX_new(SSLv23_server_method());
2248 if (!ctx) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02002249 memprintf(err, "%sunable to allocate SSL context for cert '%s'.\n",
2250 err && *err ? *err : "", path);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002251 return 1;
2252 }
2253
2254 if (SSL_CTX_use_PrivateKey_file(ctx, path, SSL_FILETYPE_PEM) <= 0) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02002255 memprintf(err, "%sunable to load SSL private key from PEM file '%s'.\n",
2256 err && *err ? *err : "", path);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002257 SSL_CTX_free(ctx);
2258 return 1;
2259 }
2260
Emeric Brun50bcecc2013-04-22 13:05:23 +02002261 ret = ssl_sock_load_cert_chain_file(ctx, path, bind_conf, sni_filter, fcount);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002262 if (ret <= 0) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02002263 memprintf(err, "%sunable to load SSL certificate from PEM file '%s'.\n",
2264 err && *err ? *err : "", path);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002265 if (ret < 0) /* serious error, must do that ourselves */
2266 SSL_CTX_free(ctx);
2267 return 1;
2268 }
Emeric Brun61694ab2012-10-26 13:35:33 +02002269
2270 if (SSL_CTX_check_private_key(ctx) <= 0) {
2271 memprintf(err, "%sinconsistencies between private key and certificate loaded from PEM file '%s'.\n",
2272 err && *err ? *err : "", path);
2273 return 1;
2274 }
2275
Emeric Brunfc0421f2012-09-07 17:30:07 +02002276 /* we must not free the SSL_CTX anymore below, since it's already in
2277 * the tree, so it will be discovered and cleaned in time.
2278 */
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02002279#ifndef OPENSSL_NO_DH
Remi Gacogne4f902b82015-05-28 16:23:00 +02002280 /* store a NULL pointer to indicate we have not yet loaded
2281 a custom DH param file */
2282 if (ssl_dh_ptr_index >= 0) {
2283 SSL_CTX_set_ex_data(ctx, ssl_dh_ptr_index, NULL);
2284 }
2285
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02002286 ret = ssl_sock_load_dh_params(ctx, path);
2287 if (ret < 0) {
2288 if (err)
2289 memprintf(err, "%sunable to load DH parameters from file '%s'.\n",
2290 *err ? *err : "", path);
2291 return 1;
2292 }
2293#endif
2294
Lukas Tribuse4e30f72014-12-09 16:32:51 +01002295#if (defined SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB && !defined OPENSSL_NO_OCSP)
Emeric Brun4147b2e2014-06-16 18:36:30 +02002296 ret = ssl_sock_load_ocsp(ctx, path);
2297 if (ret < 0) {
2298 if (err)
2299 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",
2300 *err ? *err : "", path);
2301 return 1;
2302 }
2303#endif
2304
Daniel Jakots54ffb912015-11-06 20:02:41 +01002305#if (OPENSSL_VERSION_NUMBER >= 0x1000200fL && !defined OPENSSL_NO_TLSEXT && !defined OPENSSL_IS_BORINGSSL && !defined LIBRESSL_VERSION_NUMBER)
Janusz Dziemidowicz2c701b52015-03-07 23:03:59 +01002306 if (sctl_ex_index >= 0) {
2307 ret = ssl_sock_load_sctl(ctx, path);
2308 if (ret < 0) {
2309 if (err)
2310 memprintf(err, "%s '%s.sctl' is present but cannot be read or parsed'.\n",
2311 *err ? *err : "", path);
2312 return 1;
2313 }
2314 }
2315#endif
2316
Emeric Brunfc0421f2012-09-07 17:30:07 +02002317#ifndef SSL_CTRL_SET_TLSEXT_HOSTNAME
Willy Tarreau2a65ff02012-09-13 17:54:29 +02002318 if (bind_conf->default_ctx) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02002319 memprintf(err, "%sthis version of openssl cannot load multiple SSL certificates.\n",
2320 err && *err ? *err : "");
Emeric Brunfc0421f2012-09-07 17:30:07 +02002321 return 1;
2322 }
2323#endif
Willy Tarreau2a65ff02012-09-13 17:54:29 +02002324 if (!bind_conf->default_ctx)
2325 bind_conf->default_ctx = ctx;
Emeric Brunfc0421f2012-09-07 17:30:07 +02002326
2327 return 0;
2328}
2329
Willy Tarreau79eeafa2012-09-14 07:53:05 +02002330int ssl_sock_load_cert(char *path, struct bind_conf *bind_conf, struct proxy *curproxy, char **err)
Emeric Brunfc0421f2012-09-07 17:30:07 +02002331{
Cyril Bonté3180f7b2015-01-25 00:16:08 +01002332 struct dirent **de_list;
2333 int i, n;
Emeric Brunfc0421f2012-09-07 17:30:07 +02002334 DIR *dir;
2335 struct stat buf;
Willy Tarreauee2663b2012-12-06 11:36:59 +01002336 char *end;
2337 char fp[MAXPATHLEN+1];
Emeric Brunfc0421f2012-09-07 17:30:07 +02002338 int cfgerr = 0;
yanbzhu63ea8462015-12-09 13:35:14 -05002339#if OPENSSL_VERSION_NUMBER >= 0x1000200fL
2340 int is_bundle;
2341 int j;
2342#endif
Emeric Brunfc0421f2012-09-07 17:30:07 +02002343
yanbzhu08ce6ab2015-12-02 13:01:29 -05002344 if (stat(path, &buf) == 0) {
2345 dir = opendir(path);
2346 if (!dir)
2347 return ssl_sock_load_cert_file(path, bind_conf, curproxy, NULL, 0, err);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002348
yanbzhu08ce6ab2015-12-02 13:01:29 -05002349 /* strip trailing slashes, including first one */
2350 for (end = path + strlen(path) - 1; end >= path && *end == '/'; end--)
2351 *end = 0;
Emeric Brunfc0421f2012-09-07 17:30:07 +02002352
yanbzhu08ce6ab2015-12-02 13:01:29 -05002353 n = scandir(path, &de_list, 0, alphasort);
2354 if (n < 0) {
2355 memprintf(err, "%sunable to scan directory '%s' : %s.\n",
2356 err && *err ? *err : "", path, strerror(errno));
2357 cfgerr++;
2358 }
2359 else {
2360 for (i = 0; i < n; i++) {
2361 struct dirent *de = de_list[i];
Emeric Brun2aab7222014-06-18 18:15:09 +02002362
yanbzhu08ce6ab2015-12-02 13:01:29 -05002363 end = strrchr(de->d_name, '.');
2364 if (end && (!strcmp(end, ".issuer") || !strcmp(end, ".ocsp") || !strcmp(end, ".sctl")))
2365 goto ignore_entry;
Cyril Bonté3180f7b2015-01-25 00:16:08 +01002366
yanbzhu08ce6ab2015-12-02 13:01:29 -05002367 snprintf(fp, sizeof(fp), "%s/%s", path, de->d_name);
2368 if (stat(fp, &buf) != 0) {
2369 memprintf(err, "%sunable to stat SSL certificate from file '%s' : %s.\n",
2370 err && *err ? *err : "", fp, strerror(errno));
2371 cfgerr++;
2372 goto ignore_entry;
2373 }
2374 if (!S_ISREG(buf.st_mode))
2375 goto ignore_entry;
yanbzhu63ea8462015-12-09 13:35:14 -05002376
2377#if OPENSSL_VERSION_NUMBER >= 0x1000200fL
2378 is_bundle = 0;
2379 /* Check if current entry in directory is part of a multi-cert bundle */
2380
2381 if (end) {
2382 for (j = 0; j < SSL_SOCK_NUM_KEYTYPES; j++) {
2383 if (!strcmp(end + 1, SSL_SOCK_KEYTYPE_NAMES[j])) {
2384 is_bundle = 1;
2385 break;
2386 }
2387 }
2388
2389 if (is_bundle) {
2390 char dp[MAXPATHLEN+1] = {0}; /* this will be the filename w/o the keytype */
2391 int dp_len;
2392
2393 dp_len = end - de->d_name;
2394 snprintf(dp, dp_len + 1, "%s", de->d_name);
2395
2396 /* increment i and free de until we get to a non-bundle cert
2397 * Note here that we look at de_list[i + 1] before freeing de
2398 * this is important since ignore_entry will free de
2399 */
2400 while (i + 1 < n && !strncmp(de_list[i + 1]->d_name, dp, dp_len)) {
2401 free(de);
2402 i++;
2403 de = de_list[i];
2404 }
2405
2406 snprintf(fp, sizeof(fp), "%s/%s", path, dp);
Emmanuel Hocdetd294aea2016-05-13 11:14:06 +02002407 ssl_sock_load_multi_cert(fp, bind_conf, curproxy, NULL, 0, err);
yanbzhu63ea8462015-12-09 13:35:14 -05002408
2409 /* Successfully processed the bundle */
2410 goto ignore_entry;
2411 }
2412 }
2413
2414#endif
yanbzhu08ce6ab2015-12-02 13:01:29 -05002415 cfgerr += ssl_sock_load_cert_file(fp, bind_conf, curproxy, NULL, 0, err);
2416ignore_entry:
2417 free(de);
Cyril Bonté3180f7b2015-01-25 00:16:08 +01002418 }
yanbzhu08ce6ab2015-12-02 13:01:29 -05002419 free(de_list);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002420 }
yanbzhu08ce6ab2015-12-02 13:01:29 -05002421 closedir(dir);
2422 return cfgerr;
Emeric Brunfc0421f2012-09-07 17:30:07 +02002423 }
yanbzhu08ce6ab2015-12-02 13:01:29 -05002424
Emmanuel Hocdetd294aea2016-05-13 11:14:06 +02002425 cfgerr = ssl_sock_load_multi_cert(path, bind_conf, curproxy, NULL, 0, err);
yanbzhu08ce6ab2015-12-02 13:01:29 -05002426
Emeric Brunfc0421f2012-09-07 17:30:07 +02002427 return cfgerr;
2428}
2429
Thierry Fournier383085f2013-01-24 14:15:43 +01002430/* Make sure openssl opens /dev/urandom before the chroot. The work is only
2431 * done once. Zero is returned if the operation fails. No error is returned
2432 * if the random is said as not implemented, because we expect that openssl
2433 * will use another method once needed.
2434 */
2435static int ssl_initialize_random()
2436{
2437 unsigned char random;
2438 static int random_initialized = 0;
2439
2440 if (!random_initialized && RAND_bytes(&random, 1) != 0)
2441 random_initialized = 1;
2442
2443 return random_initialized;
2444}
2445
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002446int ssl_sock_load_cert_list_file(char *file, struct bind_conf *bind_conf, struct proxy *curproxy, char **err)
2447{
Emmanuel Hocdet5e0e6e42016-05-13 11:18:50 +02002448 char thisline[LINESIZE*CRTLIST_FACTOR];
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002449 FILE *f;
yanbzhu1b04e5b2015-12-02 13:54:14 -05002450 struct stat buf;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002451 int linenum = 0;
2452 int cfgerr = 0;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002453
Willy Tarreauad1731d2013-04-02 17:35:58 +02002454 if ((f = fopen(file, "r")) == NULL) {
2455 memprintf(err, "cannot open file '%s' : %s", file, strerror(errno));
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002456 return 1;
Willy Tarreauad1731d2013-04-02 17:35:58 +02002457 }
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002458
2459 while (fgets(thisline, sizeof(thisline), f) != NULL) {
2460 int arg;
Emeric Brun50bcecc2013-04-22 13:05:23 +02002461 int newarg;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002462 char *end;
Emmanuel Hocdet5e0e6e42016-05-13 11:18:50 +02002463 char *args[MAX_LINE_ARGS*CRTLIST_FACTOR + 1];
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002464 char *line = thisline;
2465
2466 linenum++;
2467 end = line + strlen(line);
2468 if (end-line == sizeof(thisline)-1 && *(end-1) != '\n') {
2469 /* Check if we reached the limit and the last char is not \n.
2470 * Watch out for the last line without the terminating '\n'!
2471 */
Willy Tarreauad1731d2013-04-02 17:35:58 +02002472 memprintf(err, "line %d too long in file '%s', limit is %d characters",
2473 linenum, file, (int)sizeof(thisline)-1);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002474 cfgerr = 1;
Willy Tarreauad1731d2013-04-02 17:35:58 +02002475 break;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002476 }
2477
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002478 arg = 0;
Emeric Brun50bcecc2013-04-22 13:05:23 +02002479 newarg = 1;
2480 while (*line) {
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002481 if (*line == '#' || *line == '\n' || *line == '\r') {
2482 /* end of string, end of loop */
2483 *line = 0;
2484 break;
2485 }
2486 else if (isspace(*line)) {
Emeric Brun50bcecc2013-04-22 13:05:23 +02002487 newarg = 1;
2488 *line = 0;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002489 }
Emeric Brun50bcecc2013-04-22 13:05:23 +02002490 else if (newarg) {
Emmanuel Hocdet5e0e6e42016-05-13 11:18:50 +02002491 if (arg == MAX_LINE_ARGS*CRTLIST_FACTOR) {
Emeric Brun50bcecc2013-04-22 13:05:23 +02002492 memprintf(err, "too many args on line %d in file '%s'.",
2493 linenum, file);
2494 cfgerr = 1;
2495 break;
2496 }
2497 newarg = 0;
2498 args[arg++] = line;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002499 }
Emeric Brun50bcecc2013-04-22 13:05:23 +02002500 line++;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002501 }
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02002502 if (cfgerr)
2503 break;
Willy Tarreauad1731d2013-04-02 17:35:58 +02002504
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002505 /* empty line */
Emeric Brun50bcecc2013-04-22 13:05:23 +02002506 if (!arg)
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002507 continue;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002508
yanbzhu1b04e5b2015-12-02 13:54:14 -05002509 if (stat(args[0], &buf) == 0) {
2510 cfgerr = ssl_sock_load_cert_file(args[0], bind_conf, curproxy, &args[1], arg-1, err);
2511 } else {
Emmanuel Hocdetd294aea2016-05-13 11:14:06 +02002512 cfgerr = ssl_sock_load_multi_cert(args[0], bind_conf, curproxy, &args[1], arg-1, err);
yanbzhu1b04e5b2015-12-02 13:54:14 -05002513 }
2514
Willy Tarreauad1731d2013-04-02 17:35:58 +02002515 if (cfgerr) {
2516 memprintf(err, "error processing line %d in file '%s' : %s", linenum, file, *err);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002517 break;
Willy Tarreauad1731d2013-04-02 17:35:58 +02002518 }
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002519 }
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002520 fclose(f);
2521 return cfgerr;
2522}
2523
Emeric Brunfc0421f2012-09-07 17:30:07 +02002524#ifndef SSL_OP_CIPHER_SERVER_PREFERENCE /* needs OpenSSL >= 0.9.7 */
2525#define SSL_OP_CIPHER_SERVER_PREFERENCE 0
2526#endif
2527
2528#ifndef SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION /* needs OpenSSL >= 0.9.7 */
2529#define SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION 0
Willy Tarreau7d588ee2012-11-26 18:47:31 +01002530#define SSL_renegotiate_pending(arg) 0
Emeric Brunfc0421f2012-09-07 17:30:07 +02002531#endif
Emeric Brun2b58d042012-09-20 17:10:03 +02002532#ifndef SSL_OP_SINGLE_ECDH_USE /* needs OpenSSL >= 0.9.8 */
2533#define SSL_OP_SINGLE_ECDH_USE 0
2534#endif
Emeric Brun2d0c4822012-10-02 13:45:20 +02002535#ifndef SSL_OP_NO_TICKET /* needs OpenSSL >= 0.9.8 */
2536#define SSL_OP_NO_TICKET 0
2537#endif
Emeric Brunfc0421f2012-09-07 17:30:07 +02002538#ifndef SSL_OP_NO_COMPRESSION /* needs OpenSSL >= 0.9.9 */
2539#define SSL_OP_NO_COMPRESSION 0
2540#endif
Emeric Brunc0ff4922012-09-28 19:37:02 +02002541#ifndef SSL_OP_NO_TLSv1_1 /* needs OpenSSL >= 1.0.1 */
2542#define SSL_OP_NO_TLSv1_1 0
2543#endif
2544#ifndef SSL_OP_NO_TLSv1_2 /* needs OpenSSL >= 1.0.1 */
2545#define SSL_OP_NO_TLSv1_2 0
2546#endif
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02002547#ifndef SSL_OP_SINGLE_DH_USE /* needs OpenSSL >= 0.9.6 */
2548#define SSL_OP_SINGLE_DH_USE 0
2549#endif
Emeric Brun2b58d042012-09-20 17:10:03 +02002550#ifndef SSL_OP_SINGLE_ECDH_USE /* needs OpenSSL >= 1.0.0 */
2551#define SSL_OP_SINGLE_ECDH_USE 0
2552#endif
Emeric Brunfc0421f2012-09-07 17:30:07 +02002553#ifndef SSL_MODE_RELEASE_BUFFERS /* needs OpenSSL >= 1.0.0 */
2554#define SSL_MODE_RELEASE_BUFFERS 0
2555#endif
Willy Tarreau396a1862014-11-13 14:06:52 +01002556#ifndef SSL_MODE_SMALL_BUFFERS /* needs small_records.patch */
2557#define SSL_MODE_SMALL_BUFFERS 0
2558#endif
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002559
Willy Tarreau2a65ff02012-09-13 17:54:29 +02002560int ssl_sock_prepare_ctx(struct bind_conf *bind_conf, SSL_CTX *ctx, struct proxy *curproxy)
Emeric Brunfc0421f2012-09-07 17:30:07 +02002561{
2562 int cfgerr = 0;
Emeric Brun850efd52014-01-29 12:24:34 +01002563 int verify = SSL_VERIFY_NONE;
Remi Gacogneaf5c3da2014-05-19 10:29:58 +02002564 long ssloptions =
Emeric Brunfc0421f2012-09-07 17:30:07 +02002565 SSL_OP_ALL | /* all known workarounds for bugs */
2566 SSL_OP_NO_SSLv2 |
2567 SSL_OP_NO_COMPRESSION |
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02002568 SSL_OP_SINGLE_DH_USE |
Emeric Brun2b58d042012-09-20 17:10:03 +02002569 SSL_OP_SINGLE_ECDH_USE |
Emeric Brun3c4bc6e2012-10-04 18:44:19 +02002570 SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION |
2571 SSL_OP_CIPHER_SERVER_PREFERENCE;
Remi Gacogneaf5c3da2014-05-19 10:29:58 +02002572 long sslmode =
Emeric Brunfc0421f2012-09-07 17:30:07 +02002573 SSL_MODE_ENABLE_PARTIAL_WRITE |
2574 SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER |
Willy Tarreau396a1862014-11-13 14:06:52 +01002575 SSL_MODE_RELEASE_BUFFERS |
2576 SSL_MODE_SMALL_BUFFERS;
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002577 STACK_OF(SSL_CIPHER) * ciphers = NULL;
Willy Tarreaua616ba62014-10-26 06:49:19 +01002578 SSL_CIPHER * cipher = NULL;
Remi Gacognec1eab8c2014-06-12 18:20:11 +02002579 char cipher_description[128];
2580 /* The description of ciphers using an Ephemeral Diffie Hellman key exchange
2581 contains " Kx=DH " or " Kx=DH(". Beware of " Kx=DH/",
2582 which is not ephemeral DH. */
2583 const char dhe_description[] = " Kx=DH ";
2584 const char dhe_export_description[] = " Kx=DH(";
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002585 int idx = 0;
2586 int dhe_found = 0;
Remi Gacogne23d5d372014-10-10 17:04:26 +02002587 SSL *ssl = NULL;
Emeric Brunfc0421f2012-09-07 17:30:07 +02002588
Thierry Fournier383085f2013-01-24 14:15:43 +01002589 /* Make sure openssl opens /dev/urandom before the chroot */
2590 if (!ssl_initialize_random()) {
2591 Alert("OpenSSL random data generator initialization failed.\n");
2592 cfgerr++;
2593 }
2594
Emeric Brun89675492012-10-05 13:48:26 +02002595 if (bind_conf->ssl_options & BC_SSL_O_NO_SSLV3)
Emeric Brunfc0421f2012-09-07 17:30:07 +02002596 ssloptions |= SSL_OP_NO_SSLv3;
Emeric Brun89675492012-10-05 13:48:26 +02002597 if (bind_conf->ssl_options & BC_SSL_O_NO_TLSV10)
Emeric Brunfc0421f2012-09-07 17:30:07 +02002598 ssloptions |= SSL_OP_NO_TLSv1;
Emeric Brun89675492012-10-05 13:48:26 +02002599 if (bind_conf->ssl_options & BC_SSL_O_NO_TLSV11)
Emeric Brunc0ff4922012-09-28 19:37:02 +02002600 ssloptions |= SSL_OP_NO_TLSv1_1;
Emeric Brun89675492012-10-05 13:48:26 +02002601 if (bind_conf->ssl_options & BC_SSL_O_NO_TLSV12)
Emeric Brunc0ff4922012-09-28 19:37:02 +02002602 ssloptions |= SSL_OP_NO_TLSv1_2;
Emeric Brun89675492012-10-05 13:48:26 +02002603 if (bind_conf->ssl_options & BC_SSL_O_NO_TLS_TICKETS)
Emeric Brun2d0c4822012-10-02 13:45:20 +02002604 ssloptions |= SSL_OP_NO_TICKET;
Jérémie Courrèges-Anglas17c3f622015-07-25 16:50:52 -06002605 if (bind_conf->ssl_options & BC_SSL_O_USE_SSLV3) {
2606#ifndef OPENSSL_NO_SSL3
Emeric Brun2cb7ae52012-10-05 14:14:21 +02002607 SSL_CTX_set_ssl_version(ctx, SSLv3_server_method());
Jérémie Courrèges-Anglas17c3f622015-07-25 16:50:52 -06002608#else
2609 Alert("SSLv3 support requested but unavailable.\n");
2610 cfgerr++;
2611#endif
2612 }
Emeric Brun2cb7ae52012-10-05 14:14:21 +02002613 if (bind_conf->ssl_options & BC_SSL_O_USE_TLSV10)
2614 SSL_CTX_set_ssl_version(ctx, TLSv1_server_method());
2615#if SSL_OP_NO_TLSv1_1
2616 if (bind_conf->ssl_options & BC_SSL_O_USE_TLSV11)
2617 SSL_CTX_set_ssl_version(ctx, TLSv1_1_server_method());
2618#endif
2619#if SSL_OP_NO_TLSv1_2
2620 if (bind_conf->ssl_options & BC_SSL_O_USE_TLSV12)
2621 SSL_CTX_set_ssl_version(ctx, TLSv1_2_server_method());
2622#endif
Emeric Brunfc0421f2012-09-07 17:30:07 +02002623
2624 SSL_CTX_set_options(ctx, ssloptions);
2625 SSL_CTX_set_mode(ctx, sslmode);
Emeric Brun850efd52014-01-29 12:24:34 +01002626 switch (bind_conf->verify) {
2627 case SSL_SOCK_VERIFY_NONE:
2628 verify = SSL_VERIFY_NONE;
2629 break;
2630 case SSL_SOCK_VERIFY_OPTIONAL:
2631 verify = SSL_VERIFY_PEER;
2632 break;
2633 case SSL_SOCK_VERIFY_REQUIRED:
2634 verify = SSL_VERIFY_PEER|SSL_VERIFY_FAIL_IF_NO_PEER_CERT;
2635 break;
2636 }
2637 SSL_CTX_set_verify(ctx, verify, ssl_sock_bind_verifycbk);
2638 if (verify & SSL_VERIFY_PEER) {
Emeric Brunfb510ea2012-10-05 12:00:26 +02002639 if (bind_conf->ca_file) {
Emeric Brund94b3fe2012-09-20 18:23:56 +02002640 /* load CAfile to verify */
Emeric Brunfb510ea2012-10-05 12:00:26 +02002641 if (!SSL_CTX_load_verify_locations(ctx, bind_conf->ca_file, NULL)) {
Emeric Brund94b3fe2012-09-20 18:23:56 +02002642 Alert("Proxy '%s': unable to load CA file '%s' for bind '%s' at [%s:%d].\n",
Emeric Brunfb510ea2012-10-05 12:00:26 +02002643 curproxy->id, bind_conf->ca_file, bind_conf->arg, bind_conf->file, bind_conf->line);
Emeric Brund94b3fe2012-09-20 18:23:56 +02002644 cfgerr++;
2645 }
2646 /* set CA names fo client cert request, function returns void */
Emeric Brunfb510ea2012-10-05 12:00:26 +02002647 SSL_CTX_set_client_CA_list(ctx, SSL_load_client_CA_file(bind_conf->ca_file));
Emeric Brund94b3fe2012-09-20 18:23:56 +02002648 }
Emeric Brun850efd52014-01-29 12:24:34 +01002649 else {
2650 Alert("Proxy '%s': verify is enabled but no CA file specified for bind '%s' at [%s:%d].\n",
2651 curproxy->id, bind_conf->arg, bind_conf->file, bind_conf->line);
2652 cfgerr++;
2653 }
Emeric Brun051cdab2012-10-02 19:25:50 +02002654#ifdef X509_V_FLAG_CRL_CHECK
Emeric Brunfb510ea2012-10-05 12:00:26 +02002655 if (bind_conf->crl_file) {
Emeric Brund94b3fe2012-09-20 18:23:56 +02002656 X509_STORE *store = SSL_CTX_get_cert_store(ctx);
2657
Emeric Brunfb510ea2012-10-05 12:00:26 +02002658 if (!store || !X509_STORE_load_locations(store, bind_conf->crl_file, NULL)) {
Emeric Brund94b3fe2012-09-20 18:23:56 +02002659 Alert("Proxy '%s': unable to configure CRL file '%s' for bind '%s' at [%s:%d].\n",
Alexander Rigbofc65af02015-04-07 14:02:16 +02002660 curproxy->id, bind_conf->crl_file, bind_conf->arg, bind_conf->file, bind_conf->line);
Emeric Brund94b3fe2012-09-20 18:23:56 +02002661 cfgerr++;
2662 }
Emeric Brun561e5742012-10-02 15:20:55 +02002663 else {
2664 X509_STORE_set_flags(store, X509_V_FLAG_CRL_CHECK|X509_V_FLAG_CRL_CHECK_ALL);
2665 }
Emeric Brund94b3fe2012-09-20 18:23:56 +02002666 }
Emeric Brun051cdab2012-10-02 19:25:50 +02002667#endif
Emeric Brun644cde02012-12-14 11:21:13 +01002668 ERR_clear_error();
Emeric Brund94b3fe2012-09-20 18:23:56 +02002669 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02002670
Nenad Merdanovic05552d42015-02-27 19:56:49 +01002671#if (defined SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB && TLS_TICKETS_NO > 0)
Nenad Merdanovic146defa2015-05-09 08:46:00 +02002672 if(bind_conf->keys_ref) {
Nenad Merdanovic05552d42015-02-27 19:56:49 +01002673 if (!SSL_CTX_set_tlsext_ticket_key_cb(ctx, ssl_tlsext_ticket_key_cb)) {
2674 Alert("Proxy '%s': unable to set callback for TLS ticket validation for bind '%s' at [%s:%d].\n",
2675 curproxy->id, bind_conf->arg, bind_conf->file, bind_conf->line);
2676 cfgerr++;
2677 }
2678 }
2679#endif
2680
Emeric Brun4f65bff2012-11-16 15:11:00 +01002681 if (global.tune.ssllifetime)
2682 SSL_CTX_set_timeout(ctx, global.tune.ssllifetime);
2683
Emeric Brunfc0421f2012-09-07 17:30:07 +02002684 shared_context_set_cache(ctx);
Willy Tarreau2a65ff02012-09-13 17:54:29 +02002685 if (bind_conf->ciphers &&
2686 !SSL_CTX_set_cipher_list(ctx, bind_conf->ciphers)) {
Emeric Brunfc0421f2012-09-07 17:30:07 +02002687 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 +02002688 curproxy->id, bind_conf->ciphers, bind_conf->arg, bind_conf->file, bind_conf->line);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002689 cfgerr++;
2690 }
2691
Remi Gacogne47783ef2015-05-29 15:53:22 +02002692 /* If tune.ssl.default-dh-param has not been set,
2693 neither has ssl-default-dh-file and no static DH
2694 params were in the certificate file. */
Remi Gacogne4f902b82015-05-28 16:23:00 +02002695 if (global.tune.ssl_default_dh_param == 0 &&
Remi Gacogne47783ef2015-05-29 15:53:22 +02002696 global_dh == NULL &&
Remi Gacogne4f902b82015-05-28 16:23:00 +02002697 (ssl_dh_ptr_index == -1 ||
2698 SSL_CTX_get_ex_data(ctx, ssl_dh_ptr_index) == NULL)) {
Lukas Tribus90132722014-08-18 00:56:33 +02002699
Remi Gacogne23d5d372014-10-10 17:04:26 +02002700 ssl = SSL_new(ctx);
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002701
Remi Gacogne23d5d372014-10-10 17:04:26 +02002702 if (ssl) {
2703 ciphers = SSL_get_ciphers(ssl);
2704
2705 if (ciphers) {
2706 for (idx = 0; idx < sk_SSL_CIPHER_num(ciphers); idx++) {
2707 cipher = sk_SSL_CIPHER_value(ciphers, idx);
2708 if (SSL_CIPHER_description(cipher, cipher_description, sizeof (cipher_description)) == cipher_description) {
2709 if (strstr(cipher_description, dhe_description) != NULL ||
2710 strstr(cipher_description, dhe_export_description) != NULL) {
2711 dhe_found = 1;
2712 break;
2713 }
Remi Gacognec1eab8c2014-06-12 18:20:11 +02002714 }
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002715 }
2716 }
Remi Gacogne23d5d372014-10-10 17:04:26 +02002717 SSL_free(ssl);
2718 ssl = NULL;
Lukas Tribus90132722014-08-18 00:56:33 +02002719 }
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002720
Lukas Tribus90132722014-08-18 00:56:33 +02002721 if (dhe_found) {
2722 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 +02002723 }
2724
2725 global.tune.ssl_default_dh_param = 1024;
2726 }
Remi Gacogne8de54152014-07-15 11:36:40 +02002727
2728#ifndef OPENSSL_NO_DH
2729 if (global.tune.ssl_default_dh_param >= 1024) {
2730 if (local_dh_1024 == NULL) {
2731 local_dh_1024 = ssl_get_dh_1024();
2732 }
2733 if (global.tune.ssl_default_dh_param >= 2048) {
2734 if (local_dh_2048 == NULL) {
2735 local_dh_2048 = ssl_get_dh_2048();
2736 }
2737 if (global.tune.ssl_default_dh_param >= 4096) {
2738 if (local_dh_4096 == NULL) {
2739 local_dh_4096 = ssl_get_dh_4096();
2740 }
Remi Gacogne8de54152014-07-15 11:36:40 +02002741 }
2742 }
2743 }
2744#endif /* OPENSSL_NO_DH */
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002745
Emeric Brunfc0421f2012-09-07 17:30:07 +02002746 SSL_CTX_set_info_callback(ctx, ssl_sock_infocbk);
Willy Tarreau5cbe4ef2014-05-08 22:45:11 +02002747#if OPENSSL_VERSION_NUMBER >= 0x00907000L
Emeric Brun29f037d2014-04-25 19:05:36 +02002748 SSL_CTX_set_msg_callback(ctx, ssl_sock_msgcbk);
Willy Tarreau5cbe4ef2014-05-08 22:45:11 +02002749#endif
Emeric Brun29f037d2014-04-25 19:05:36 +02002750
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02002751#ifdef OPENSSL_NPN_NEGOTIATED
2752 if (bind_conf->npn_str)
2753 SSL_CTX_set_next_protos_advertised_cb(ctx, ssl_sock_advertise_npn_protos, bind_conf);
2754#endif
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01002755#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Willy Tarreauab861d32013-04-02 02:30:41 +02002756 if (bind_conf->alpn_str)
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01002757 SSL_CTX_set_alpn_select_cb(ctx, ssl_sock_advertise_alpn_protos, bind_conf);
Willy Tarreauab861d32013-04-02 02:30:41 +02002758#endif
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02002759
Emeric Brunfc0421f2012-09-07 17:30:07 +02002760#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
2761 SSL_CTX_set_tlsext_servername_callback(ctx, ssl_sock_switchctx_cbk);
Willy Tarreau2a65ff02012-09-13 17:54:29 +02002762 SSL_CTX_set_tlsext_servername_arg(ctx, bind_conf);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002763#endif
Emeric Brun2b58d042012-09-20 17:10:03 +02002764#if defined(SSL_CTX_set_tmp_ecdh) && !defined(OPENSSL_NO_ECDH)
Emeric Brun6924ef82013-03-06 14:08:53 +01002765 {
Emeric Brun2b58d042012-09-20 17:10:03 +02002766 int i;
2767 EC_KEY *ecdh;
2768
Emeric Brun6924ef82013-03-06 14:08:53 +01002769 i = OBJ_sn2nid(bind_conf->ecdhe ? bind_conf->ecdhe : ECDHE_DEFAULT_CURVE);
Emeric Brun2b58d042012-09-20 17:10:03 +02002770 if (!i || ((ecdh = EC_KEY_new_by_curve_name(i)) == NULL)) {
2771 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 +01002772 curproxy->id, bind_conf->ecdhe ? bind_conf->ecdhe : ECDHE_DEFAULT_CURVE,
2773 bind_conf->arg, bind_conf->file, bind_conf->line);
Emeric Brun2b58d042012-09-20 17:10:03 +02002774 cfgerr++;
2775 }
2776 else {
2777 SSL_CTX_set_tmp_ecdh(ctx, ecdh);
2778 EC_KEY_free(ecdh);
2779 }
2780 }
2781#endif
2782
Emeric Brunfc0421f2012-09-07 17:30:07 +02002783 return cfgerr;
2784}
2785
Evan Broderbe554312013-06-27 00:05:25 -07002786static int ssl_sock_srv_hostcheck(const char *pattern, const char *hostname)
2787{
2788 const char *pattern_wildcard, *pattern_left_label_end, *hostname_left_label_end;
2789 size_t prefixlen, suffixlen;
2790
2791 /* Trivial case */
2792 if (strcmp(pattern, hostname) == 0)
2793 return 1;
2794
Evan Broderbe554312013-06-27 00:05:25 -07002795 /* The rest of this logic is based on RFC 6125, section 6.4.3
2796 * (http://tools.ietf.org/html/rfc6125#section-6.4.3) */
2797
Emeric Bruna848dae2013-10-08 11:27:28 +02002798 pattern_wildcard = NULL;
2799 pattern_left_label_end = pattern;
2800 while (*pattern_left_label_end != '.') {
2801 switch (*pattern_left_label_end) {
2802 case 0:
2803 /* End of label not found */
2804 return 0;
2805 case '*':
2806 /* If there is more than one wildcards */
2807 if (pattern_wildcard)
2808 return 0;
2809 pattern_wildcard = pattern_left_label_end;
2810 break;
2811 }
2812 pattern_left_label_end++;
2813 }
2814
2815 /* If it's not trivial and there is no wildcard, it can't
2816 * match */
2817 if (!pattern_wildcard)
Evan Broderbe554312013-06-27 00:05:25 -07002818 return 0;
2819
2820 /* Make sure all labels match except the leftmost */
2821 hostname_left_label_end = strchr(hostname, '.');
2822 if (!hostname_left_label_end
2823 || strcmp(pattern_left_label_end, hostname_left_label_end) != 0)
2824 return 0;
2825
2826 /* Make sure the leftmost label of the hostname is long enough
2827 * that the wildcard can match */
Emeric Brun369da852013-10-08 11:39:35 +02002828 if (hostname_left_label_end - hostname < (pattern_left_label_end - pattern) - 1)
Evan Broderbe554312013-06-27 00:05:25 -07002829 return 0;
2830
2831 /* Finally compare the string on either side of the
2832 * wildcard */
2833 prefixlen = pattern_wildcard - pattern;
2834 suffixlen = pattern_left_label_end - (pattern_wildcard + 1);
Emeric Bruna848dae2013-10-08 11:27:28 +02002835 if ((prefixlen && (memcmp(pattern, hostname, prefixlen) != 0))
2836 || (suffixlen && (memcmp(pattern_wildcard + 1, hostname_left_label_end - suffixlen, suffixlen) != 0)))
Evan Broderbe554312013-06-27 00:05:25 -07002837 return 0;
2838
2839 return 1;
2840}
2841
2842static int ssl_sock_srv_verifycbk(int ok, X509_STORE_CTX *ctx)
2843{
2844 SSL *ssl;
2845 struct connection *conn;
2846 char *servername;
2847
2848 int depth;
2849 X509 *cert;
2850 STACK_OF(GENERAL_NAME) *alt_names;
2851 int i;
2852 X509_NAME *cert_subject;
2853 char *str;
2854
2855 if (ok == 0)
2856 return ok;
2857
2858 ssl = X509_STORE_CTX_get_ex_data(ctx, SSL_get_ex_data_X509_STORE_CTX_idx());
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02002859 conn = SSL_get_app_data(ssl);
Evan Broderbe554312013-06-27 00:05:25 -07002860
2861 servername = objt_server(conn->target)->ssl_ctx.verify_host;
2862
2863 /* We only need to verify the CN on the actual server cert,
2864 * not the indirect CAs */
2865 depth = X509_STORE_CTX_get_error_depth(ctx);
2866 if (depth != 0)
2867 return ok;
2868
2869 /* At this point, the cert is *not* OK unless we can find a
2870 * hostname match */
2871 ok = 0;
2872
2873 cert = X509_STORE_CTX_get_current_cert(ctx);
2874 /* It seems like this might happen if verify peer isn't set */
2875 if (!cert)
2876 return ok;
2877
2878 alt_names = X509_get_ext_d2i(cert, NID_subject_alt_name, NULL, NULL);
2879 if (alt_names) {
2880 for (i = 0; !ok && i < sk_GENERAL_NAME_num(alt_names); i++) {
2881 GENERAL_NAME *name = sk_GENERAL_NAME_value(alt_names, i);
2882 if (name->type == GEN_DNS) {
Emeric Bruna33410c2013-09-17 15:47:48 +02002883#if OPENSSL_VERSION_NUMBER < 0x00907000L
2884 if (ASN1_STRING_to_UTF8((unsigned char **)&str, name->d.ia5) >= 0) {
2885#else
Evan Broderbe554312013-06-27 00:05:25 -07002886 if (ASN1_STRING_to_UTF8((unsigned char **)&str, name->d.dNSName) >= 0) {
Emeric Bruna33410c2013-09-17 15:47:48 +02002887#endif
Evan Broderbe554312013-06-27 00:05:25 -07002888 ok = ssl_sock_srv_hostcheck(str, servername);
2889 OPENSSL_free(str);
2890 }
2891 }
2892 }
Emeric Brun4ad50a42013-09-17 15:19:54 +02002893 sk_GENERAL_NAME_pop_free(alt_names, GENERAL_NAME_free);
Evan Broderbe554312013-06-27 00:05:25 -07002894 }
2895
2896 cert_subject = X509_get_subject_name(cert);
2897 i = -1;
2898 while (!ok && (i = X509_NAME_get_index_by_NID(cert_subject, NID_commonName, i)) != -1) {
2899 X509_NAME_ENTRY *entry = X509_NAME_get_entry(cert_subject, i);
2900 if (ASN1_STRING_to_UTF8((unsigned char **)&str, entry->value) >= 0) {
2901 ok = ssl_sock_srv_hostcheck(str, servername);
2902 OPENSSL_free(str);
2903 }
2904 }
2905
2906 return ok;
2907}
2908
Emeric Brun94324a42012-10-11 14:00:19 +02002909/* prepare ssl context from servers options. Returns an error count */
2910int ssl_sock_prepare_srv_ctx(struct server *srv, struct proxy *curproxy)
2911{
2912 int cfgerr = 0;
Remi Gacogneaf5c3da2014-05-19 10:29:58 +02002913 long options =
Emeric Brun94324a42012-10-11 14:00:19 +02002914 SSL_OP_ALL | /* all known workarounds for bugs */
2915 SSL_OP_NO_SSLv2 |
2916 SSL_OP_NO_COMPRESSION;
Remi Gacogneaf5c3da2014-05-19 10:29:58 +02002917 long mode =
Emeric Brun94324a42012-10-11 14:00:19 +02002918 SSL_MODE_ENABLE_PARTIAL_WRITE |
2919 SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER |
Willy Tarreau396a1862014-11-13 14:06:52 +01002920 SSL_MODE_RELEASE_BUFFERS |
2921 SSL_MODE_SMALL_BUFFERS;
Emeric Brun850efd52014-01-29 12:24:34 +01002922 int verify = SSL_VERIFY_NONE;
Emeric Brun94324a42012-10-11 14:00:19 +02002923
Thierry Fournier383085f2013-01-24 14:15:43 +01002924 /* Make sure openssl opens /dev/urandom before the chroot */
2925 if (!ssl_initialize_random()) {
2926 Alert("OpenSSL random data generator initialization failed.\n");
2927 cfgerr++;
2928 }
2929
Willy Tarreaufce03112015-01-15 21:32:40 +01002930 /* Automatic memory computations need to know we use SSL there */
2931 global.ssl_used_backend = 1;
2932
2933 /* Initiate SSL context for current server */
Emeric Brun94324a42012-10-11 14:00:19 +02002934 srv->ssl_ctx.reused_sess = NULL;
2935 if (srv->use_ssl)
2936 srv->xprt = &ssl_sock;
2937 if (srv->check.use_ssl)
Cyril Bonté9ce13112014-11-15 22:41:27 +01002938 srv->check.xprt = &ssl_sock;
Emeric Brun94324a42012-10-11 14:00:19 +02002939
2940 srv->ssl_ctx.ctx = SSL_CTX_new(SSLv23_client_method());
2941 if (!srv->ssl_ctx.ctx) {
2942 Alert("config : %s '%s', server '%s': unable to allocate ssl context.\n",
2943 proxy_type_str(curproxy), curproxy->id,
2944 srv->id);
2945 cfgerr++;
2946 return cfgerr;
2947 }
Emeric Bruna7aa3092012-10-26 12:58:00 +02002948 if (srv->ssl_ctx.client_crt) {
2949 if (SSL_CTX_use_PrivateKey_file(srv->ssl_ctx.ctx, srv->ssl_ctx.client_crt, SSL_FILETYPE_PEM) <= 0) {
2950 Alert("config : %s '%s', server '%s': unable to load SSL private key from PEM file '%s'.\n",
2951 proxy_type_str(curproxy), curproxy->id,
2952 srv->id, srv->ssl_ctx.client_crt);
2953 cfgerr++;
2954 }
2955 else if (SSL_CTX_use_certificate_chain_file(srv->ssl_ctx.ctx, srv->ssl_ctx.client_crt) <= 0) {
2956 Alert("config : %s '%s', server '%s': unable to load ssl certificate from PEM file '%s'.\n",
2957 proxy_type_str(curproxy), curproxy->id,
2958 srv->id, srv->ssl_ctx.client_crt);
2959 cfgerr++;
2960 }
2961 else if (SSL_CTX_check_private_key(srv->ssl_ctx.ctx) <= 0) {
2962 Alert("config : %s '%s', server '%s': inconsistencies between private key and certificate loaded from PEM file '%s'.\n",
2963 proxy_type_str(curproxy), curproxy->id,
2964 srv->id, srv->ssl_ctx.client_crt);
2965 cfgerr++;
2966 }
2967 }
Emeric Brun94324a42012-10-11 14:00:19 +02002968
2969 if (srv->ssl_ctx.options & SRV_SSL_O_NO_SSLV3)
2970 options |= SSL_OP_NO_SSLv3;
2971 if (srv->ssl_ctx.options & SRV_SSL_O_NO_TLSV10)
2972 options |= SSL_OP_NO_TLSv1;
2973 if (srv->ssl_ctx.options & SRV_SSL_O_NO_TLSV11)
2974 options |= SSL_OP_NO_TLSv1_1;
2975 if (srv->ssl_ctx.options & SRV_SSL_O_NO_TLSV12)
2976 options |= SSL_OP_NO_TLSv1_2;
Emeric Brunf9c5c472012-10-11 15:28:34 +02002977 if (srv->ssl_ctx.options & SRV_SSL_O_NO_TLS_TICKETS)
2978 options |= SSL_OP_NO_TICKET;
Jérémie Courrèges-Anglas17c3f622015-07-25 16:50:52 -06002979 if (srv->ssl_ctx.options & SRV_SSL_O_USE_SSLV3) {
2980#ifndef OPENSSL_NO_SSL3
Emeric Brun94324a42012-10-11 14:00:19 +02002981 SSL_CTX_set_ssl_version(srv->ssl_ctx.ctx, SSLv3_client_method());
Jérémie Courrèges-Anglas17c3f622015-07-25 16:50:52 -06002982#else
Thierry FOURNIERbc965342015-08-26 08:21:26 +02002983 Alert("SSLv3 support requested but unavailable.\n");
Jérémie Courrèges-Anglas17c3f622015-07-25 16:50:52 -06002984 cfgerr++;
2985#endif
2986 }
Emeric Brun94324a42012-10-11 14:00:19 +02002987 if (srv->ssl_ctx.options & SRV_SSL_O_USE_TLSV10)
2988 SSL_CTX_set_ssl_version(srv->ssl_ctx.ctx, TLSv1_client_method());
2989#if SSL_OP_NO_TLSv1_1
2990 if (srv->ssl_ctx.options & SRV_SSL_O_USE_TLSV11)
2991 SSL_CTX_set_ssl_version(srv->ssl_ctx.ctx, TLSv1_1_client_method());
2992#endif
2993#if SSL_OP_NO_TLSv1_2
2994 if (srv->ssl_ctx.options & SRV_SSL_O_USE_TLSV12)
2995 SSL_CTX_set_ssl_version(srv->ssl_ctx.ctx, TLSv1_2_client_method());
2996#endif
2997
2998 SSL_CTX_set_options(srv->ssl_ctx.ctx, options);
2999 SSL_CTX_set_mode(srv->ssl_ctx.ctx, mode);
Emeric Brun850efd52014-01-29 12:24:34 +01003000
3001 if (global.ssl_server_verify == SSL_SERVER_VERIFY_REQUIRED)
3002 verify = SSL_VERIFY_PEER;
3003
3004 switch (srv->ssl_ctx.verify) {
3005 case SSL_SOCK_VERIFY_NONE:
3006 verify = SSL_VERIFY_NONE;
3007 break;
3008 case SSL_SOCK_VERIFY_REQUIRED:
3009 verify = SSL_VERIFY_PEER;
3010 break;
3011 }
Evan Broderbe554312013-06-27 00:05:25 -07003012 SSL_CTX_set_verify(srv->ssl_ctx.ctx,
Emeric Brun850efd52014-01-29 12:24:34 +01003013 verify,
Evan Broderbe554312013-06-27 00:05:25 -07003014 srv->ssl_ctx.verify_host ? ssl_sock_srv_verifycbk : NULL);
Emeric Brun850efd52014-01-29 12:24:34 +01003015 if (verify & SSL_VERIFY_PEER) {
Emeric Brunef42d922012-10-11 16:11:36 +02003016 if (srv->ssl_ctx.ca_file) {
3017 /* load CAfile to verify */
3018 if (!SSL_CTX_load_verify_locations(srv->ssl_ctx.ctx, srv->ssl_ctx.ca_file, NULL)) {
Willy Tarreau07ba08b2014-02-16 19:22:08 +01003019 Alert("Proxy '%s', server '%s' [%s:%d] unable to load CA file '%s'.\n",
Emeric Brunef42d922012-10-11 16:11:36 +02003020 curproxy->id, srv->id,
3021 srv->conf.file, srv->conf.line, srv->ssl_ctx.ca_file);
3022 cfgerr++;
3023 }
3024 }
Emeric Brun850efd52014-01-29 12:24:34 +01003025 else {
3026 if (global.ssl_server_verify == SSL_SERVER_VERIFY_REQUIRED)
Willy Tarreau07ba08b2014-02-16 19:22:08 +01003027 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 +01003028 curproxy->id, srv->id,
3029 srv->conf.file, srv->conf.line);
3030 else
Willy Tarreau07ba08b2014-02-16 19:22:08 +01003031 Alert("Proxy '%s', server '%s' [%s:%d] verify is enabled but no CA file specified.\n",
Emeric Brun850efd52014-01-29 12:24:34 +01003032 curproxy->id, srv->id,
3033 srv->conf.file, srv->conf.line);
3034 cfgerr++;
3035 }
Emeric Brunef42d922012-10-11 16:11:36 +02003036#ifdef X509_V_FLAG_CRL_CHECK
3037 if (srv->ssl_ctx.crl_file) {
3038 X509_STORE *store = SSL_CTX_get_cert_store(srv->ssl_ctx.ctx);
3039
3040 if (!store || !X509_STORE_load_locations(store, srv->ssl_ctx.crl_file, NULL)) {
Willy Tarreau07ba08b2014-02-16 19:22:08 +01003041 Alert("Proxy '%s', server '%s' [%s:%d] unable to configure CRL file '%s'.\n",
Emeric Brunef42d922012-10-11 16:11:36 +02003042 curproxy->id, srv->id,
3043 srv->conf.file, srv->conf.line, srv->ssl_ctx.crl_file);
3044 cfgerr++;
3045 }
3046 else {
3047 X509_STORE_set_flags(store, X509_V_FLAG_CRL_CHECK|X509_V_FLAG_CRL_CHECK_ALL);
3048 }
3049 }
3050#endif
3051 }
3052
Emeric Brun4f65bff2012-11-16 15:11:00 +01003053 if (global.tune.ssllifetime)
3054 SSL_CTX_set_timeout(srv->ssl_ctx.ctx, global.tune.ssllifetime);
3055
Emeric Brun94324a42012-10-11 14:00:19 +02003056 SSL_CTX_set_session_cache_mode(srv->ssl_ctx.ctx, SSL_SESS_CACHE_OFF);
3057 if (srv->ssl_ctx.ciphers &&
3058 !SSL_CTX_set_cipher_list(srv->ssl_ctx.ctx, srv->ssl_ctx.ciphers)) {
3059 Alert("Proxy '%s', server '%s' [%s:%d] : unable to set SSL cipher list to '%s'.\n",
3060 curproxy->id, srv->id,
3061 srv->conf.file, srv->conf.line, srv->ssl_ctx.ciphers);
3062 cfgerr++;
3063 }
3064
3065 return cfgerr;
3066}
3067
Willy Tarreau2a65ff02012-09-13 17:54:29 +02003068/* Walks down the two trees in bind_conf and prepares all certs. The pointer may
Emeric Brunfc0421f2012-09-07 17:30:07 +02003069 * be NULL, in which case nothing is done. Returns the number of errors
3070 * encountered.
3071 */
Willy Tarreau2a65ff02012-09-13 17:54:29 +02003072int ssl_sock_prepare_all_ctx(struct bind_conf *bind_conf, struct proxy *px)
Emeric Brunfc0421f2012-09-07 17:30:07 +02003073{
3074 struct ebmb_node *node;
3075 struct sni_ctx *sni;
3076 int err = 0;
3077
Willy Tarreau2a65ff02012-09-13 17:54:29 +02003078 if (!bind_conf || !bind_conf->is_ssl)
Emeric Brunfc0421f2012-09-07 17:30:07 +02003079 return 0;
3080
Willy Tarreaufce03112015-01-15 21:32:40 +01003081 /* Automatic memory computations need to know we use SSL there */
3082 global.ssl_used_frontend = 1;
3083
Emeric Brun0bed9942014-10-30 19:25:24 +01003084 if (bind_conf->default_ctx)
3085 err += ssl_sock_prepare_ctx(bind_conf, bind_conf->default_ctx, px);
3086
Willy Tarreau2a65ff02012-09-13 17:54:29 +02003087 node = ebmb_first(&bind_conf->sni_ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02003088 while (node) {
3089 sni = ebmb_entry(node, struct sni_ctx, name);
Emeric Brun0bed9942014-10-30 19:25:24 +01003090 if (!sni->order && sni->ctx != bind_conf->default_ctx)
3091 /* only initialize the CTX on its first occurrence and
3092 if it is not the default_ctx */
Willy Tarreau2a65ff02012-09-13 17:54:29 +02003093 err += ssl_sock_prepare_ctx(bind_conf, sni->ctx, px);
Emeric Brunfc0421f2012-09-07 17:30:07 +02003094 node = ebmb_next(node);
3095 }
3096
Willy Tarreau2a65ff02012-09-13 17:54:29 +02003097 node = ebmb_first(&bind_conf->sni_w_ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02003098 while (node) {
3099 sni = ebmb_entry(node, struct sni_ctx, name);
Emeric Brun0bed9942014-10-30 19:25:24 +01003100 if (!sni->order && sni->ctx != bind_conf->default_ctx)
3101 /* only initialize the CTX on its first occurrence and
3102 if it is not the default_ctx */
Willy Tarreau2a65ff02012-09-13 17:54:29 +02003103 err += ssl_sock_prepare_ctx(bind_conf, sni->ctx, px);
Emeric Brunfc0421f2012-09-07 17:30:07 +02003104 node = ebmb_next(node);
3105 }
3106 return err;
3107}
3108
Christopher Faulet77fe80c2015-07-29 13:02:40 +02003109
3110/* release ssl context allocated for servers. */
3111void ssl_sock_free_srv_ctx(struct server *srv)
3112{
3113 if (srv->ssl_ctx.ctx)
3114 SSL_CTX_free(srv->ssl_ctx.ctx);
3115}
3116
Willy Tarreau2a65ff02012-09-13 17:54:29 +02003117/* Walks down the two trees in bind_conf and frees all the certs. The pointer may
Emeric Brunfc0421f2012-09-07 17:30:07 +02003118 * be NULL, in which case nothing is done. The default_ctx is nullified too.
3119 */
Willy Tarreau2a65ff02012-09-13 17:54:29 +02003120void ssl_sock_free_all_ctx(struct bind_conf *bind_conf)
Emeric Brunfc0421f2012-09-07 17:30:07 +02003121{
3122 struct ebmb_node *node, *back;
3123 struct sni_ctx *sni;
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;
3127
Willy Tarreau2a65ff02012-09-13 17:54:29 +02003128 node = ebmb_first(&bind_conf->sni_ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02003129 while (node) {
3130 sni = ebmb_entry(node, struct sni_ctx, name);
3131 back = ebmb_next(node);
3132 ebmb_delete(node);
3133 if (!sni->order) /* only free the CTX on its first occurrence */
3134 SSL_CTX_free(sni->ctx);
3135 free(sni);
3136 node = back;
3137 }
3138
Willy Tarreau2a65ff02012-09-13 17:54:29 +02003139 node = ebmb_first(&bind_conf->sni_w_ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02003140 while (node) {
3141 sni = ebmb_entry(node, struct sni_ctx, name);
3142 back = ebmb_next(node);
3143 ebmb_delete(node);
3144 if (!sni->order) /* only free the CTX on its first occurrence */
3145 SSL_CTX_free(sni->ctx);
3146 free(sni);
3147 node = back;
3148 }
3149
Willy Tarreau2a65ff02012-09-13 17:54:29 +02003150 bind_conf->default_ctx = NULL;
Emeric Brune1f38db2012-09-03 20:36:47 +02003151}
3152
Christopher Faulet31af49d2015-06-09 17:29:50 +02003153/* Load CA cert file and private key used to generate certificates */
3154int
3155ssl_sock_load_ca(struct bind_conf *bind_conf, struct proxy *px)
3156{
3157 FILE *fp;
3158 X509 *cacert = NULL;
3159 EVP_PKEY *capkey = NULL;
3160 int err = 0;
3161
3162 if (!bind_conf || !bind_conf->generate_certs)
3163 return err;
3164
Willy Tarreaua84c2672015-10-09 12:10:13 +02003165#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Christopher Fauletd2cab922015-07-28 16:03:47 +02003166 if (global.tune.ssl_ctx_cache)
3167 ssl_ctx_lru_tree = lru64_new(global.tune.ssl_ctx_cache);
3168 ssl_ctx_lru_seed = (unsigned int)time(NULL);
Willy Tarreaua84c2672015-10-09 12:10:13 +02003169#endif
Christopher Fauletd2cab922015-07-28 16:03:47 +02003170
Christopher Faulet31af49d2015-06-09 17:29:50 +02003171 if (!bind_conf->ca_sign_file) {
3172 Alert("Proxy '%s': cannot enable certificate generation, "
3173 "no CA certificate File configured at [%s:%d].\n",
3174 px->id, bind_conf->file, bind_conf->line);
Christopher Faulet31af49d2015-06-09 17:29:50 +02003175 goto load_error;
Christopher Fauletc6f02fb2015-10-09 10:53:31 +02003176 }
Christopher Faulet31af49d2015-06-09 17:29:50 +02003177
3178 /* read in the CA certificate */
3179 if (!(fp = fopen(bind_conf->ca_sign_file, "r"))) {
3180 Alert("Proxy '%s': Failed to read CA certificate file '%s' at [%s:%d].\n",
3181 px->id, bind_conf->ca_sign_file, bind_conf->file, bind_conf->line);
Christopher Faulet31af49d2015-06-09 17:29:50 +02003182 goto load_error;
3183 }
3184 if (!(cacert = PEM_read_X509(fp, NULL, NULL, NULL))) {
3185 Alert("Proxy '%s': Failed to read CA certificate file '%s' at [%s:%d].\n",
3186 px->id, bind_conf->ca_sign_file, bind_conf->file, bind_conf->line);
Christopher Fauletc6f02fb2015-10-09 10:53:31 +02003187 goto read_error;
Christopher Faulet31af49d2015-06-09 17:29:50 +02003188 }
Christopher Fauletc6f02fb2015-10-09 10:53:31 +02003189 rewind(fp);
Christopher Faulet31af49d2015-06-09 17:29:50 +02003190 if (!(capkey = PEM_read_PrivateKey(fp, NULL, NULL, bind_conf->ca_sign_pass))) {
3191 Alert("Proxy '%s': Failed to read CA private key file '%s' at [%s:%d].\n",
3192 px->id, bind_conf->ca_sign_file, bind_conf->file, bind_conf->line);
Christopher Fauletc6f02fb2015-10-09 10:53:31 +02003193 goto read_error;
Christopher Faulet31af49d2015-06-09 17:29:50 +02003194 }
Christopher Faulet31af49d2015-06-09 17:29:50 +02003195
Christopher Fauletc6f02fb2015-10-09 10:53:31 +02003196 fclose (fp);
Christopher Faulet31af49d2015-06-09 17:29:50 +02003197 bind_conf->ca_sign_cert = cacert;
3198 bind_conf->ca_sign_pkey = capkey;
3199 return err;
3200
Christopher Fauletc6f02fb2015-10-09 10:53:31 +02003201 read_error:
3202 fclose (fp);
Christopher Faulet31af49d2015-06-09 17:29:50 +02003203 if (capkey) EVP_PKEY_free(capkey);
3204 if (cacert) X509_free(cacert);
Christopher Fauletc6f02fb2015-10-09 10:53:31 +02003205 load_error:
3206 bind_conf->generate_certs = 0;
3207 err++;
Christopher Faulet31af49d2015-06-09 17:29:50 +02003208 return err;
3209}
3210
3211/* Release CA cert and private key used to generate certificated */
3212void
3213ssl_sock_free_ca(struct bind_conf *bind_conf)
3214{
3215 if (!bind_conf)
3216 return;
3217
3218 if (bind_conf->ca_sign_pkey)
3219 EVP_PKEY_free(bind_conf->ca_sign_pkey);
3220 if (bind_conf->ca_sign_cert)
3221 X509_free(bind_conf->ca_sign_cert);
3222}
3223
Emeric Brun46591952012-05-18 15:47:34 +02003224/*
3225 * This function is called if SSL * context is not yet allocated. The function
3226 * is designed to be called before any other data-layer operation and sets the
3227 * handshake flag on the connection. It is safe to call it multiple times.
3228 * It returns 0 on success and -1 in error case.
3229 */
3230static int ssl_sock_init(struct connection *conn)
3231{
3232 /* already initialized */
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02003233 if (conn->xprt_ctx)
Emeric Brun46591952012-05-18 15:47:34 +02003234 return 0;
3235
Willy Tarreau3c728722014-01-23 13:50:42 +01003236 if (!conn_ctrl_ready(conn))
Willy Tarreauf79c8172013-10-21 16:30:56 +02003237 return 0;
3238
Willy Tarreau20879a02012-12-03 16:32:10 +01003239 if (global.maxsslconn && sslconns >= global.maxsslconn) {
3240 conn->err_code = CO_ER_SSL_TOO_MANY;
Willy Tarreau403edff2012-09-06 11:58:37 +02003241 return -1;
Willy Tarreau20879a02012-12-03 16:32:10 +01003242 }
Willy Tarreau403edff2012-09-06 11:58:37 +02003243
Emeric Brun46591952012-05-18 15:47:34 +02003244 /* If it is in client mode initiate SSL session
3245 in connect state otherwise accept state */
Willy Tarreau3fdb3662012-11-12 00:42:33 +01003246 if (objt_server(conn->target)) {
Willy Tarreaufba03cd2014-11-13 13:48:58 +01003247 int may_retry = 1;
3248
3249 retry_connect:
Emeric Brun46591952012-05-18 15:47:34 +02003250 /* Alloc a new SSL session ctx */
Willy Tarreau3fdb3662012-11-12 00:42:33 +01003251 conn->xprt_ctx = SSL_new(objt_server(conn->target)->ssl_ctx.ctx);
Willy Tarreau20879a02012-12-03 16:32:10 +01003252 if (!conn->xprt_ctx) {
Willy Tarreaufba03cd2014-11-13 13:48:58 +01003253 if (may_retry--) {
3254 pool_gc2();
3255 goto retry_connect;
3256 }
Willy Tarreau20879a02012-12-03 16:32:10 +01003257 conn->err_code = CO_ER_SSL_NO_MEM;
Emeric Brun46591952012-05-18 15:47:34 +02003258 return -1;
Willy Tarreau20879a02012-12-03 16:32:10 +01003259 }
Emeric Brun46591952012-05-18 15:47:34 +02003260
Emeric Brun46591952012-05-18 15:47:34 +02003261 /* set fd on SSL session context */
Emeric Brun55476152014-11-12 17:35:37 +01003262 if (!SSL_set_fd(conn->xprt_ctx, conn->t.sock.fd)) {
3263 SSL_free(conn->xprt_ctx);
3264 conn->xprt_ctx = NULL;
Willy Tarreaufba03cd2014-11-13 13:48:58 +01003265 if (may_retry--) {
3266 pool_gc2();
3267 goto retry_connect;
3268 }
Emeric Brun55476152014-11-12 17:35:37 +01003269 conn->err_code = CO_ER_SSL_NO_MEM;
3270 return -1;
3271 }
Emeric Brun46591952012-05-18 15:47:34 +02003272
Evan Broderbe554312013-06-27 00:05:25 -07003273 /* set connection pointer */
Emeric Brun55476152014-11-12 17:35:37 +01003274 if (!SSL_set_app_data(conn->xprt_ctx, conn)) {
3275 SSL_free(conn->xprt_ctx);
3276 conn->xprt_ctx = NULL;
Willy Tarreaufba03cd2014-11-13 13:48:58 +01003277 if (may_retry--) {
3278 pool_gc2();
3279 goto retry_connect;
3280 }
Emeric Brun55476152014-11-12 17:35:37 +01003281 conn->err_code = CO_ER_SSL_NO_MEM;
3282 return -1;
3283 }
3284
3285 SSL_set_connect_state(conn->xprt_ctx);
3286 if (objt_server(conn->target)->ssl_ctx.reused_sess) {
3287 if(!SSL_set_session(conn->xprt_ctx, objt_server(conn->target)->ssl_ctx.reused_sess)) {
3288 SSL_SESSION_free(objt_server(conn->target)->ssl_ctx.reused_sess);
3289 objt_server(conn->target)->ssl_ctx.reused_sess = NULL;
3290 }
3291 }
Evan Broderbe554312013-06-27 00:05:25 -07003292
Emeric Brun46591952012-05-18 15:47:34 +02003293 /* leave init state and start handshake */
Willy Tarreau05737472012-09-04 08:03:39 +02003294 conn->flags |= CO_FL_SSL_WAIT_HS | CO_FL_WAIT_L6_CONN;
Willy Tarreau403edff2012-09-06 11:58:37 +02003295
3296 sslconns++;
Willy Tarreau71b734c2014-01-28 15:19:44 +01003297 totalsslconns++;
Emeric Brun46591952012-05-18 15:47:34 +02003298 return 0;
3299 }
Willy Tarreau3fdb3662012-11-12 00:42:33 +01003300 else if (objt_listener(conn->target)) {
Willy Tarreaufba03cd2014-11-13 13:48:58 +01003301 int may_retry = 1;
3302
3303 retry_accept:
Emeric Brun46591952012-05-18 15:47:34 +02003304 /* Alloc a new SSL session ctx */
Willy Tarreau3fdb3662012-11-12 00:42:33 +01003305 conn->xprt_ctx = SSL_new(objt_listener(conn->target)->bind_conf->default_ctx);
Willy Tarreau20879a02012-12-03 16:32:10 +01003306 if (!conn->xprt_ctx) {
Willy Tarreaufba03cd2014-11-13 13:48:58 +01003307 if (may_retry--) {
3308 pool_gc2();
3309 goto retry_accept;
3310 }
Willy Tarreau20879a02012-12-03 16:32:10 +01003311 conn->err_code = CO_ER_SSL_NO_MEM;
Emeric Brun46591952012-05-18 15:47:34 +02003312 return -1;
Willy Tarreau20879a02012-12-03 16:32:10 +01003313 }
Emeric Brun46591952012-05-18 15:47:34 +02003314
Emeric Brun46591952012-05-18 15:47:34 +02003315 /* set fd on SSL session context */
Emeric Brun55476152014-11-12 17:35:37 +01003316 if (!SSL_set_fd(conn->xprt_ctx, conn->t.sock.fd)) {
3317 SSL_free(conn->xprt_ctx);
3318 conn->xprt_ctx = NULL;
Willy Tarreaufba03cd2014-11-13 13:48:58 +01003319 if (may_retry--) {
3320 pool_gc2();
3321 goto retry_accept;
3322 }
Emeric Brun55476152014-11-12 17:35:37 +01003323 conn->err_code = CO_ER_SSL_NO_MEM;
3324 return -1;
3325 }
Emeric Brun46591952012-05-18 15:47:34 +02003326
Emeric Brune1f38db2012-09-03 20:36:47 +02003327 /* set connection pointer */
Emeric Brun55476152014-11-12 17:35:37 +01003328 if (!SSL_set_app_data(conn->xprt_ctx, conn)) {
3329 SSL_free(conn->xprt_ctx);
3330 conn->xprt_ctx = NULL;
Willy Tarreaufba03cd2014-11-13 13:48:58 +01003331 if (may_retry--) {
3332 pool_gc2();
3333 goto retry_accept;
3334 }
Emeric Brun55476152014-11-12 17:35:37 +01003335 conn->err_code = CO_ER_SSL_NO_MEM;
3336 return -1;
3337 }
3338
3339 SSL_set_accept_state(conn->xprt_ctx);
Emeric Brune1f38db2012-09-03 20:36:47 +02003340
Emeric Brun46591952012-05-18 15:47:34 +02003341 /* leave init state and start handshake */
Willy Tarreau05737472012-09-04 08:03:39 +02003342 conn->flags |= CO_FL_SSL_WAIT_HS | CO_FL_WAIT_L6_CONN;
Willy Tarreau403edff2012-09-06 11:58:37 +02003343
3344 sslconns++;
Willy Tarreau71b734c2014-01-28 15:19:44 +01003345 totalsslconns++;
Emeric Brun46591952012-05-18 15:47:34 +02003346 return 0;
3347 }
3348 /* don't know how to handle such a target */
Willy Tarreau20879a02012-12-03 16:32:10 +01003349 conn->err_code = CO_ER_SSL_NO_TARGET;
Emeric Brun46591952012-05-18 15:47:34 +02003350 return -1;
3351}
3352
3353
3354/* This is the callback which is used when an SSL handshake is pending. It
3355 * updates the FD status if it wants some polling before being called again.
3356 * It returns 0 if it fails in a fatal way or needs to poll to go further,
3357 * otherwise it returns non-zero and removes itself from the connection's
3358 * flags (the bit is provided in <flag> by the caller).
3359 */
3360int ssl_sock_handshake(struct connection *conn, unsigned int flag)
3361{
3362 int ret;
3363
Willy Tarreau3c728722014-01-23 13:50:42 +01003364 if (!conn_ctrl_ready(conn))
Willy Tarreauf79c8172013-10-21 16:30:56 +02003365 return 0;
3366
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02003367 if (!conn->xprt_ctx)
Emeric Brun46591952012-05-18 15:47:34 +02003368 goto out_error;
3369
Emeric Brun674b7432012-11-08 19:21:55 +01003370 /* If we use SSL_do_handshake to process a reneg initiated by
3371 * the remote peer, it sometimes returns SSL_ERROR_SSL.
3372 * Usually SSL_write and SSL_read are used and process implicitly
3373 * the reneg handshake.
3374 * Here we use SSL_peek as a workaround for reneg.
3375 */
3376 if ((conn->flags & CO_FL_CONNECTED) && SSL_renegotiate_pending(conn->xprt_ctx)) {
3377 char c;
3378
3379 ret = SSL_peek(conn->xprt_ctx, &c, 1);
3380 if (ret <= 0) {
3381 /* handshake may have not been completed, let's find why */
3382 ret = SSL_get_error(conn->xprt_ctx, ret);
3383 if (ret == SSL_ERROR_WANT_WRITE) {
3384 /* SSL handshake needs to write, L4 connection may not be ready */
3385 __conn_sock_stop_recv(conn);
Willy Tarreaue1f50c42014-01-22 20:02:06 +01003386 __conn_sock_want_send(conn);
3387 fd_cant_send(conn->t.sock.fd);
Emeric Brun674b7432012-11-08 19:21:55 +01003388 return 0;
3389 }
3390 else if (ret == SSL_ERROR_WANT_READ) {
3391 /* handshake may have been completed but we have
3392 * no more data to read.
3393 */
3394 if (!SSL_renegotiate_pending(conn->xprt_ctx)) {
3395 ret = 1;
3396 goto reneg_ok;
3397 }
3398 /* SSL handshake needs to read, L4 connection is ready */
3399 if (conn->flags & CO_FL_WAIT_L4_CONN)
3400 conn->flags &= ~CO_FL_WAIT_L4_CONN;
3401 __conn_sock_stop_send(conn);
Willy Tarreaue1f50c42014-01-22 20:02:06 +01003402 __conn_sock_want_recv(conn);
3403 fd_cant_recv(conn->t.sock.fd);
Emeric Brun674b7432012-11-08 19:21:55 +01003404 return 0;
3405 }
3406 else if (ret == SSL_ERROR_SYSCALL) {
3407 /* if errno is null, then connection was successfully established */
3408 if (!errno && conn->flags & CO_FL_WAIT_L4_CONN)
3409 conn->flags &= ~CO_FL_WAIT_L4_CONN;
Willy Tarreau20879a02012-12-03 16:32:10 +01003410 if (!conn->err_code) {
Emeric Brun29f037d2014-04-25 19:05:36 +02003411 if (!((SSL *)conn->xprt_ctx)->packet_length) {
3412 if (!errno) {
3413 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
3414 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
3415 else
3416 conn->err_code = CO_ER_SSL_EMPTY;
3417 }
3418 else {
3419 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
3420 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
3421 else
3422 conn->err_code = CO_ER_SSL_ABORT;
3423 }
3424 }
3425 else {
3426 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
3427 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
Willy Tarreau20879a02012-12-03 16:32:10 +01003428 else
Emeric Brun29f037d2014-04-25 19:05:36 +02003429 conn->err_code = CO_ER_SSL_HANDSHAKE;
3430 }
Willy Tarreau20879a02012-12-03 16:32:10 +01003431 }
Emeric Brun674b7432012-11-08 19:21:55 +01003432 goto out_error;
3433 }
3434 else {
3435 /* Fail on all other handshake errors */
3436 /* Note: OpenSSL may leave unread bytes in the socket's
3437 * buffer, causing an RST to be emitted upon close() on
3438 * TCP sockets. We first try to drain possibly pending
3439 * data to avoid this as much as possible.
3440 */
Willy Tarreaud85c4852015-03-13 00:40:28 +01003441 conn_sock_drain(conn);
Willy Tarreau20879a02012-12-03 16:32:10 +01003442 if (!conn->err_code)
Willy Tarreauf51c6982014-04-25 20:02:39 +02003443 conn->err_code = (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT) ?
3444 CO_ER_SSL_KILLED_HB : CO_ER_SSL_HANDSHAKE;
Emeric Brun674b7432012-11-08 19:21:55 +01003445 goto out_error;
3446 }
3447 }
3448 /* read some data: consider handshake completed */
3449 goto reneg_ok;
3450 }
3451
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02003452 ret = SSL_do_handshake(conn->xprt_ctx);
Emeric Brun46591952012-05-18 15:47:34 +02003453 if (ret != 1) {
3454 /* handshake did not complete, let's find why */
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02003455 ret = SSL_get_error(conn->xprt_ctx, ret);
Emeric Brun46591952012-05-18 15:47:34 +02003456
3457 if (ret == SSL_ERROR_WANT_WRITE) {
3458 /* SSL handshake needs to write, L4 connection may not be ready */
3459 __conn_sock_stop_recv(conn);
Willy Tarreaue1f50c42014-01-22 20:02:06 +01003460 __conn_sock_want_send(conn);
3461 fd_cant_send(conn->t.sock.fd);
Emeric Brun46591952012-05-18 15:47:34 +02003462 return 0;
3463 }
3464 else if (ret == SSL_ERROR_WANT_READ) {
3465 /* SSL handshake needs to read, L4 connection is ready */
3466 if (conn->flags & CO_FL_WAIT_L4_CONN)
3467 conn->flags &= ~CO_FL_WAIT_L4_CONN;
3468 __conn_sock_stop_send(conn);
Willy Tarreaue1f50c42014-01-22 20:02:06 +01003469 __conn_sock_want_recv(conn);
3470 fd_cant_recv(conn->t.sock.fd);
Emeric Brun46591952012-05-18 15:47:34 +02003471 return 0;
3472 }
Willy Tarreau89230192012-09-28 20:22:13 +02003473 else if (ret == SSL_ERROR_SYSCALL) {
3474 /* if errno is null, then connection was successfully established */
3475 if (!errno && conn->flags & CO_FL_WAIT_L4_CONN)
3476 conn->flags &= ~CO_FL_WAIT_L4_CONN;
Willy Tarreau20879a02012-12-03 16:32:10 +01003477
Emeric Brun29f037d2014-04-25 19:05:36 +02003478 if (!((SSL *)conn->xprt_ctx)->packet_length) {
3479 if (!errno) {
3480 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
3481 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
3482 else
3483 conn->err_code = CO_ER_SSL_EMPTY;
3484 }
3485 else {
3486 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
3487 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
3488 else
3489 conn->err_code = CO_ER_SSL_ABORT;
3490 }
3491 }
3492 else {
3493 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
3494 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
Willy Tarreau20879a02012-12-03 16:32:10 +01003495 else
Emeric Brun29f037d2014-04-25 19:05:36 +02003496 conn->err_code = CO_ER_SSL_HANDSHAKE;
3497 }
Willy Tarreau89230192012-09-28 20:22:13 +02003498 goto out_error;
3499 }
Emeric Brun46591952012-05-18 15:47:34 +02003500 else {
3501 /* Fail on all other handshake errors */
Willy Tarreau566dc552012-10-19 20:52:18 +02003502 /* Note: OpenSSL may leave unread bytes in the socket's
3503 * buffer, causing an RST to be emitted upon close() on
3504 * TCP sockets. We first try to drain possibly pending
3505 * data to avoid this as much as possible.
3506 */
Willy Tarreaud85c4852015-03-13 00:40:28 +01003507 conn_sock_drain(conn);
Willy Tarreau20879a02012-12-03 16:32:10 +01003508 if (!conn->err_code)
Willy Tarreauf51c6982014-04-25 20:02:39 +02003509 conn->err_code = (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT) ?
3510 CO_ER_SSL_KILLED_HB : CO_ER_SSL_HANDSHAKE;
Emeric Brun46591952012-05-18 15:47:34 +02003511 goto out_error;
3512 }
3513 }
3514
Emeric Brun674b7432012-11-08 19:21:55 +01003515reneg_ok:
Emeric Brun46591952012-05-18 15:47:34 +02003516 /* Handshake succeeded */
Willy Tarreau0c9c2722014-05-28 12:28:58 +02003517 if (!SSL_session_reused(conn->xprt_ctx)) {
3518 if (objt_server(conn->target)) {
3519 update_freq_ctr(&global.ssl_be_keys_per_sec, 1);
3520 if (global.ssl_be_keys_per_sec.curr_ctr > global.ssl_be_keys_max)
3521 global.ssl_be_keys_max = global.ssl_be_keys_per_sec.curr_ctr;
3522
Emeric Brun46591952012-05-18 15:47:34 +02003523 /* check if session was reused, if not store current session on server for reuse */
Willy Tarreau3fdb3662012-11-12 00:42:33 +01003524 if (objt_server(conn->target)->ssl_ctx.reused_sess)
3525 SSL_SESSION_free(objt_server(conn->target)->ssl_ctx.reused_sess);
Emeric Brun46591952012-05-18 15:47:34 +02003526
Willy Tarreau2a3fb1c2015-02-05 16:47:07 +01003527 if (!(objt_server(conn->target)->ssl_ctx.options & SRV_SSL_O_NO_REUSE))
3528 objt_server(conn->target)->ssl_ctx.reused_sess = SSL_get1_session(conn->xprt_ctx);
Emeric Brun46591952012-05-18 15:47:34 +02003529 }
Willy Tarreau0c9c2722014-05-28 12:28:58 +02003530 else {
3531 update_freq_ctr(&global.ssl_fe_keys_per_sec, 1);
3532 if (global.ssl_fe_keys_per_sec.curr_ctr > global.ssl_fe_keys_max)
3533 global.ssl_fe_keys_max = global.ssl_fe_keys_per_sec.curr_ctr;
3534 }
Emeric Brun46591952012-05-18 15:47:34 +02003535 }
3536
3537 /* The connection is now established at both layers, it's time to leave */
3538 conn->flags &= ~(flag | CO_FL_WAIT_L4_CONN | CO_FL_WAIT_L6_CONN);
3539 return 1;
3540
3541 out_error:
Emeric Brun644cde02012-12-14 11:21:13 +01003542 /* Clear openssl global errors stack */
3543 ERR_clear_error();
3544
Emeric Brun9fa89732012-10-04 17:09:56 +02003545 /* free resumed session if exists */
Willy Tarreau3fdb3662012-11-12 00:42:33 +01003546 if (objt_server(conn->target) && objt_server(conn->target)->ssl_ctx.reused_sess) {
3547 SSL_SESSION_free(objt_server(conn->target)->ssl_ctx.reused_sess);
3548 objt_server(conn->target)->ssl_ctx.reused_sess = NULL;
Emeric Brun9fa89732012-10-04 17:09:56 +02003549 }
3550
Emeric Brun46591952012-05-18 15:47:34 +02003551 /* Fail on all other handshake errors */
3552 conn->flags |= CO_FL_ERROR;
Willy Tarreau20879a02012-12-03 16:32:10 +01003553 if (!conn->err_code)
3554 conn->err_code = CO_ER_SSL_HANDSHAKE;
Emeric Brun46591952012-05-18 15:47:34 +02003555 return 0;
3556}
3557
3558/* Receive up to <count> bytes from connection <conn>'s socket and store them
Willy Tarreauabf08d92014-01-14 11:31:27 +01003559 * into buffer <buf>. Only one call to recv() is performed, unless the
Emeric Brun46591952012-05-18 15:47:34 +02003560 * buffer wraps, in which case a second call may be performed. The connection's
3561 * flags are updated with whatever special event is detected (error, read0,
3562 * empty). The caller is responsible for taking care of those events and
3563 * avoiding the call if inappropriate. The function does not call the
3564 * connection's polling update function, so the caller is responsible for this.
3565 */
3566static int ssl_sock_to_buf(struct connection *conn, struct buffer *buf, int count)
3567{
3568 int ret, done = 0;
Willy Tarreauabf08d92014-01-14 11:31:27 +01003569 int try;
Emeric Brun46591952012-05-18 15:47:34 +02003570
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02003571 if (!conn->xprt_ctx)
Emeric Brun46591952012-05-18 15:47:34 +02003572 goto out_error;
3573
3574 if (conn->flags & CO_FL_HANDSHAKE)
3575 /* a handshake was requested */
3576 return 0;
3577
Willy Tarreauabf08d92014-01-14 11:31:27 +01003578 /* let's realign the buffer to optimize I/O */
3579 if (buffer_empty(buf))
Emeric Brun46591952012-05-18 15:47:34 +02003580 buf->p = buf->data;
Emeric Brun46591952012-05-18 15:47:34 +02003581
3582 /* read the largest possible block. For this, we perform only one call
3583 * to recv() unless the buffer wraps and we exactly fill the first hunk,
3584 * in which case we accept to do it once again. A new attempt is made on
3585 * EINTR too.
3586 */
Willy Tarreau00b0fb92014-01-17 11:09:40 +01003587 while (count > 0) {
Willy Tarreauabf08d92014-01-14 11:31:27 +01003588 /* first check if we have some room after p+i */
3589 try = buf->data + buf->size - (buf->p + buf->i);
3590 /* otherwise continue between data and p-o */
3591 if (try <= 0) {
3592 try = buf->p - (buf->data + buf->o);
3593 if (try <= 0)
3594 break;
3595 }
3596 if (try > count)
3597 try = count;
3598
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02003599 ret = SSL_read(conn->xprt_ctx, bi_end(buf), try);
Emeric Brune1f38db2012-09-03 20:36:47 +02003600 if (conn->flags & CO_FL_ERROR) {
3601 /* CO_FL_ERROR may be set by ssl_sock_infocbk */
Emeric Brun644cde02012-12-14 11:21:13 +01003602 goto out_error;
Emeric Brune1f38db2012-09-03 20:36:47 +02003603 }
Emeric Brun46591952012-05-18 15:47:34 +02003604 if (ret > 0) {
3605 buf->i += ret;
3606 done += ret;
3607 if (ret < try)
3608 break;
3609 count -= ret;
Emeric Brun46591952012-05-18 15:47:34 +02003610 }
3611 else if (ret == 0) {
Emeric Brun644cde02012-12-14 11:21:13 +01003612 ret = SSL_get_error(conn->xprt_ctx, ret);
3613 if (ret != SSL_ERROR_ZERO_RETURN) {
Emeric Brun1c646862012-12-14 12:33:41 +01003614 /* error on protocol or underlying transport */
3615 if ((ret != SSL_ERROR_SYSCALL)
3616 || (errno && (errno != EAGAIN)))
3617 conn->flags |= CO_FL_ERROR;
3618
Emeric Brun644cde02012-12-14 11:21:13 +01003619 /* Clear openssl global errors stack */
3620 ERR_clear_error();
3621 }
Emeric Brun46591952012-05-18 15:47:34 +02003622 goto read0;
3623 }
3624 else {
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02003625 ret = SSL_get_error(conn->xprt_ctx, ret);
Emeric Brun46591952012-05-18 15:47:34 +02003626 if (ret == SSL_ERROR_WANT_WRITE) {
Emeric Brun8af8dd12012-11-08 17:56:20 +01003627 /* handshake is running, and it needs to enable write */
Emeric Brun46591952012-05-18 15:47:34 +02003628 conn->flags |= CO_FL_SSL_WAIT_HS;
Emeric Brun8af8dd12012-11-08 17:56:20 +01003629 __conn_sock_want_send(conn);
Emeric Brun46591952012-05-18 15:47:34 +02003630 break;
3631 }
3632 else if (ret == SSL_ERROR_WANT_READ) {
Emeric Brun282a76a2012-11-08 18:02:56 +01003633 if (SSL_renegotiate_pending(conn->xprt_ctx)) {
3634 /* handshake is running, and it may need to re-enable read */
3635 conn->flags |= CO_FL_SSL_WAIT_HS;
3636 __conn_sock_want_recv(conn);
3637 break;
3638 }
Emeric Brun46591952012-05-18 15:47:34 +02003639 /* we need to poll for retry a read later */
Willy Tarreaue1f50c42014-01-22 20:02:06 +01003640 fd_cant_recv(conn->t.sock.fd);
Emeric Brun46591952012-05-18 15:47:34 +02003641 break;
3642 }
3643 /* otherwise it's a real error */
3644 goto out_error;
3645 }
3646 }
3647 return done;
3648
3649 read0:
3650 conn_sock_read0(conn);
3651 return done;
3652 out_error:
Emeric Brun644cde02012-12-14 11:21:13 +01003653 /* Clear openssl global errors stack */
3654 ERR_clear_error();
3655
Emeric Brun46591952012-05-18 15:47:34 +02003656 conn->flags |= CO_FL_ERROR;
3657 return done;
3658}
3659
3660
3661/* Send all pending bytes from buffer <buf> to connection <conn>'s socket.
Willy Tarreau1049b1f2014-02-02 01:51:17 +01003662 * <flags> may contain some CO_SFL_* flags to hint the system about other
3663 * pending data for example, but this flag is ignored at the moment.
Emeric Brun46591952012-05-18 15:47:34 +02003664 * Only one call to send() is performed, unless the buffer wraps, in which case
3665 * a second call may be performed. The connection's flags are updated with
3666 * whatever special event is detected (error, empty). The caller is responsible
3667 * for taking care of those events and avoiding the call if inappropriate. The
3668 * function does not call the connection's polling update function, so the caller
3669 * is responsible for this.
3670 */
3671static int ssl_sock_from_buf(struct connection *conn, struct buffer *buf, int flags)
3672{
3673 int ret, try, done;
3674
3675 done = 0;
3676
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02003677 if (!conn->xprt_ctx)
Emeric Brun46591952012-05-18 15:47:34 +02003678 goto out_error;
3679
3680 if (conn->flags & CO_FL_HANDSHAKE)
3681 /* a handshake was requested */
3682 return 0;
3683
3684 /* send the largest possible block. For this we perform only one call
3685 * to send() unless the buffer wraps and we exactly fill the first hunk,
3686 * in which case we accept to do it once again.
3687 */
3688 while (buf->o) {
Kevin Hestercad82342013-05-30 15:12:41 -07003689 try = bo_contig_data(buf);
Willy Tarreaubfd59462013-02-21 07:46:09 +01003690
Willy Tarreau7bed9452014-02-02 02:00:24 +01003691 if (!(flags & CO_SFL_STREAMER) &&
Willy Tarreau518cedd2014-02-17 15:43:01 +01003692 !(conn->xprt_st & SSL_SOCK_SEND_UNLIMITED) &&
3693 global.tune.ssl_max_record && try > global.tune.ssl_max_record) {
Willy Tarreaubfd59462013-02-21 07:46:09 +01003694 try = global.tune.ssl_max_record;
Willy Tarreau518cedd2014-02-17 15:43:01 +01003695 }
3696 else {
3697 /* we need to keep the information about the fact that
3698 * we're not limiting the upcoming send(), because if it
3699 * fails, we'll have to retry with at least as many data.
3700 */
3701 conn->xprt_st |= SSL_SOCK_SEND_UNLIMITED;
3702 }
Willy Tarreaubfd59462013-02-21 07:46:09 +01003703
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02003704 ret = SSL_write(conn->xprt_ctx, bo_ptr(buf), try);
Willy Tarreau518cedd2014-02-17 15:43:01 +01003705
Emeric Brune1f38db2012-09-03 20:36:47 +02003706 if (conn->flags & CO_FL_ERROR) {
3707 /* CO_FL_ERROR may be set by ssl_sock_infocbk */
Emeric Brun644cde02012-12-14 11:21:13 +01003708 goto out_error;
Emeric Brune1f38db2012-09-03 20:36:47 +02003709 }
Emeric Brun46591952012-05-18 15:47:34 +02003710 if (ret > 0) {
Willy Tarreau518cedd2014-02-17 15:43:01 +01003711 conn->xprt_st &= ~SSL_SOCK_SEND_UNLIMITED;
3712
Emeric Brun46591952012-05-18 15:47:34 +02003713 buf->o -= ret;
3714 done += ret;
3715
Willy Tarreau5fb38032012-12-16 19:39:09 +01003716 if (likely(buffer_empty(buf)))
Emeric Brun46591952012-05-18 15:47:34 +02003717 /* optimize data alignment in the buffer */
3718 buf->p = buf->data;
3719
3720 /* if the system buffer is full, don't insist */
3721 if (ret < try)
3722 break;
3723 }
3724 else {
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02003725 ret = SSL_get_error(conn->xprt_ctx, ret);
Emeric Brun46591952012-05-18 15:47:34 +02003726 if (ret == SSL_ERROR_WANT_WRITE) {
Emeric Brun282a76a2012-11-08 18:02:56 +01003727 if (SSL_renegotiate_pending(conn->xprt_ctx)) {
3728 /* handshake is running, and it may need to re-enable write */
3729 conn->flags |= CO_FL_SSL_WAIT_HS;
3730 __conn_sock_want_send(conn);
3731 break;
3732 }
Emeric Brun46591952012-05-18 15:47:34 +02003733 /* we need to poll to retry a write later */
Willy Tarreaue1f50c42014-01-22 20:02:06 +01003734 fd_cant_send(conn->t.sock.fd);
Emeric Brun46591952012-05-18 15:47:34 +02003735 break;
3736 }
3737 else if (ret == SSL_ERROR_WANT_READ) {
Emeric Brun8af8dd12012-11-08 17:56:20 +01003738 /* handshake is running, and it needs to enable read */
Emeric Brun46591952012-05-18 15:47:34 +02003739 conn->flags |= CO_FL_SSL_WAIT_HS;
Emeric Brun8af8dd12012-11-08 17:56:20 +01003740 __conn_sock_want_recv(conn);
Emeric Brun46591952012-05-18 15:47:34 +02003741 break;
3742 }
3743 goto out_error;
3744 }
3745 }
3746 return done;
3747
3748 out_error:
Emeric Brun644cde02012-12-14 11:21:13 +01003749 /* Clear openssl global errors stack */
3750 ERR_clear_error();
3751
Emeric Brun46591952012-05-18 15:47:34 +02003752 conn->flags |= CO_FL_ERROR;
3753 return done;
3754}
3755
Emeric Brun46591952012-05-18 15:47:34 +02003756static void ssl_sock_close(struct connection *conn) {
3757
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02003758 if (conn->xprt_ctx) {
3759 SSL_free(conn->xprt_ctx);
3760 conn->xprt_ctx = NULL;
Willy Tarreau403edff2012-09-06 11:58:37 +02003761 sslconns--;
Emeric Brun46591952012-05-18 15:47:34 +02003762 }
Emeric Brun46591952012-05-18 15:47:34 +02003763}
3764
3765/* This function tries to perform a clean shutdown on an SSL connection, and in
3766 * any case, flags the connection as reusable if no handshake was in progress.
3767 */
3768static void ssl_sock_shutw(struct connection *conn, int clean)
3769{
3770 if (conn->flags & CO_FL_HANDSHAKE)
3771 return;
3772 /* no handshake was in progress, try a clean ssl shutdown */
Emeric Brun644cde02012-12-14 11:21:13 +01003773 if (clean && (SSL_shutdown(conn->xprt_ctx) <= 0)) {
3774 /* Clear openssl global errors stack */
3775 ERR_clear_error();
3776 }
Emeric Brun46591952012-05-18 15:47:34 +02003777
3778 /* force flag on ssl to keep session in cache regardless shutdown result */
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02003779 SSL_set_shutdown(conn->xprt_ctx, SSL_SENT_SHUTDOWN);
Emeric Brun46591952012-05-18 15:47:34 +02003780}
3781
Willy Tarreauffc3fcd2012-10-12 20:17:54 +02003782/* used for logging, may be changed for a sample fetch later */
3783const char *ssl_sock_get_cipher_name(struct connection *conn)
3784{
3785 if (!conn->xprt && !conn->xprt_ctx)
3786 return NULL;
3787 return SSL_get_cipher_name(conn->xprt_ctx);
3788}
3789
3790/* used for logging, may be changed for a sample fetch later */
3791const char *ssl_sock_get_proto_version(struct connection *conn)
3792{
3793 if (!conn->xprt && !conn->xprt_ctx)
3794 return NULL;
3795 return SSL_get_version(conn->xprt_ctx);
3796}
3797
Willy Tarreau8d598402012-10-22 17:58:39 +02003798/* Extract a serial from a cert, and copy it to a chunk.
3799 * Returns 1 if serial is found and copied, 0 if no serial found and
3800 * -1 if output is not large enough.
3801 */
3802static int
3803ssl_sock_get_serial(X509 *crt, struct chunk *out)
3804{
3805 ASN1_INTEGER *serial;
3806
3807 serial = X509_get_serialNumber(crt);
3808 if (!serial)
3809 return 0;
3810
3811 if (out->size < serial->length)
3812 return -1;
3813
3814 memcpy(out->str, serial->data, serial->length);
3815 out->len = serial->length;
3816 return 1;
3817}
3818
Emeric Brun43e79582014-10-29 19:03:26 +01003819/* Extract a cert to der, and copy it to a chunk.
3820 * Returns 1 if cert is found and copied, 0 on der convertion failure and
3821 * -1 if output is not large enough.
3822 */
3823static int
3824ssl_sock_crt2der(X509 *crt, struct chunk *out)
3825{
3826 int len;
3827 unsigned char *p = (unsigned char *)out->str;;
3828
3829 len =i2d_X509(crt, NULL);
3830 if (len <= 0)
3831 return 1;
3832
3833 if (out->size < len)
3834 return -1;
3835
3836 i2d_X509(crt,&p);
3837 out->len = len;
3838 return 1;
3839}
3840
Emeric Brunce5ad802012-10-22 14:11:22 +02003841
3842/* Copy Date in ASN1_UTCTIME format in struct chunk out.
3843 * Returns 1 if serial is found and copied, 0 if no valid time found
3844 * and -1 if output is not large enough.
3845 */
3846static int
3847ssl_sock_get_time(ASN1_TIME *tm, struct chunk *out)
3848{
3849 if (tm->type == V_ASN1_GENERALIZEDTIME) {
3850 ASN1_GENERALIZEDTIME *gentm = (ASN1_GENERALIZEDTIME *)tm;
3851
3852 if (gentm->length < 12)
3853 return 0;
3854 if (gentm->data[0] != 0x32 || gentm->data[1] != 0x30)
3855 return 0;
3856 if (out->size < gentm->length-2)
3857 return -1;
3858
3859 memcpy(out->str, gentm->data+2, gentm->length-2);
3860 out->len = gentm->length-2;
3861 return 1;
3862 }
3863 else if (tm->type == V_ASN1_UTCTIME) {
3864 ASN1_UTCTIME *utctm = (ASN1_UTCTIME *)tm;
3865
3866 if (utctm->length < 10)
3867 return 0;
3868 if (utctm->data[0] >= 0x35)
3869 return 0;
3870 if (out->size < utctm->length)
3871 return -1;
3872
3873 memcpy(out->str, utctm->data, utctm->length);
3874 out->len = utctm->length;
3875 return 1;
3876 }
3877
3878 return 0;
3879}
3880
Emeric Brun87855892012-10-17 17:39:35 +02003881/* Extract an entry from a X509_NAME and copy its value to an output chunk.
3882 * Returns 1 if entry found, 0 if entry not found, or -1 if output not large enough.
3883 */
3884static int
3885ssl_sock_get_dn_entry(X509_NAME *a, const struct chunk *entry, int pos, struct chunk *out)
3886{
3887 X509_NAME_ENTRY *ne;
3888 int i, j, n;
3889 int cur = 0;
3890 const char *s;
3891 char tmp[128];
3892
3893 out->len = 0;
3894 for (i = 0; i < sk_X509_NAME_ENTRY_num(a->entries); i++) {
3895 if (pos < 0)
3896 j = (sk_X509_NAME_ENTRY_num(a->entries)-1) - i;
3897 else
3898 j = i;
3899
3900 ne = sk_X509_NAME_ENTRY_value(a->entries, j);
3901 n = OBJ_obj2nid(ne->object);
3902 if ((n == NID_undef) || ((s = OBJ_nid2sn(n)) == NULL)) {
3903 i2t_ASN1_OBJECT(tmp, sizeof(tmp), ne->object);
3904 s = tmp;
3905 }
3906
3907 if (chunk_strcasecmp(entry, s) != 0)
3908 continue;
3909
3910 if (pos < 0)
3911 cur--;
3912 else
3913 cur++;
3914
3915 if (cur != pos)
3916 continue;
3917
3918 if (ne->value->length > out->size)
3919 return -1;
3920
3921 memcpy(out->str, ne->value->data, ne->value->length);
3922 out->len = ne->value->length;
3923 return 1;
3924 }
3925
3926 return 0;
3927
3928}
3929
3930/* Extract and format full DN from a X509_NAME and copy result into a chunk
3931 * Returns 1 if dn entries exits, 0 if no dn entry found or -1 if output is not large enough.
3932 */
3933static int
3934ssl_sock_get_dn_oneline(X509_NAME *a, struct chunk *out)
3935{
3936 X509_NAME_ENTRY *ne;
3937 int i, n, ln;
3938 int l = 0;
3939 const char *s;
3940 char *p;
3941 char tmp[128];
3942
3943 out->len = 0;
3944 p = out->str;
3945 for (i = 0; i < sk_X509_NAME_ENTRY_num(a->entries); i++) {
3946 ne = sk_X509_NAME_ENTRY_value(a->entries, i);
3947 n = OBJ_obj2nid(ne->object);
3948 if ((n == NID_undef) || ((s = OBJ_nid2sn(n)) == NULL)) {
3949 i2t_ASN1_OBJECT(tmp, sizeof(tmp), ne->object);
3950 s = tmp;
3951 }
3952 ln = strlen(s);
3953
3954 l += 1 + ln + 1 + ne->value->length;
3955 if (l > out->size)
3956 return -1;
3957 out->len = l;
3958
3959 *(p++)='/';
3960 memcpy(p, s, ln);
3961 p += ln;
3962 *(p++)='=';
3963 memcpy(p, ne->value->data, ne->value->length);
3964 p += ne->value->length;
3965 }
3966
3967 if (!out->len)
3968 return 0;
3969
3970 return 1;
3971}
3972
David Safb76832014-05-08 23:42:08 -04003973char *ssl_sock_get_version(struct connection *conn)
3974{
3975 if (!ssl_sock_is_ssl(conn))
3976 return NULL;
3977
3978 return (char *)SSL_get_version(conn->xprt_ctx);
3979}
3980
Willy Tarreau63076412015-07-10 11:33:32 +02003981void ssl_sock_set_servername(struct connection *conn, const char *hostname)
3982{
3983#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
3984 if (!ssl_sock_is_ssl(conn))
3985 return;
3986
3987 SSL_set_tlsext_host_name(conn->xprt_ctx, hostname);
3988#endif
3989}
3990
Emeric Brun0abf8362014-06-24 18:26:41 +02003991/* Extract peer certificate's common name into the chunk dest
3992 * Returns
3993 * the len of the extracted common name
3994 * or 0 if no CN found in DN
3995 * or -1 on error case (i.e. no peer certificate)
3996 */
3997int ssl_sock_get_remote_common_name(struct connection *conn, struct chunk *dest)
David Safb76832014-05-08 23:42:08 -04003998{
3999 X509 *crt = NULL;
4000 X509_NAME *name;
David Safb76832014-05-08 23:42:08 -04004001 const char find_cn[] = "CN";
4002 const struct chunk find_cn_chunk = {
4003 .str = (char *)&find_cn,
4004 .len = sizeof(find_cn)-1
4005 };
Emeric Brun0abf8362014-06-24 18:26:41 +02004006 int result = -1;
David Safb76832014-05-08 23:42:08 -04004007
4008 if (!ssl_sock_is_ssl(conn))
Emeric Brun0abf8362014-06-24 18:26:41 +02004009 goto out;
David Safb76832014-05-08 23:42:08 -04004010
4011 /* SSL_get_peer_certificate, it increase X509 * ref count */
4012 crt = SSL_get_peer_certificate(conn->xprt_ctx);
4013 if (!crt)
4014 goto out;
4015
4016 name = X509_get_subject_name(crt);
4017 if (!name)
4018 goto out;
David Safb76832014-05-08 23:42:08 -04004019
Emeric Brun0abf8362014-06-24 18:26:41 +02004020 result = ssl_sock_get_dn_entry(name, &find_cn_chunk, 1, dest);
4021out:
David Safb76832014-05-08 23:42:08 -04004022 if (crt)
4023 X509_free(crt);
4024
4025 return result;
4026}
4027
Dave McCowan328fb582014-07-30 10:39:13 -04004028/* returns 1 if client passed a certificate for this session, 0 if not */
4029int ssl_sock_get_cert_used_sess(struct connection *conn)
4030{
4031 X509 *crt = NULL;
4032
4033 if (!ssl_sock_is_ssl(conn))
4034 return 0;
4035
4036 /* SSL_get_peer_certificate, it increase X509 * ref count */
4037 crt = SSL_get_peer_certificate(conn->xprt_ctx);
4038 if (!crt)
4039 return 0;
4040
4041 X509_free(crt);
4042 return 1;
4043}
4044
4045/* returns 1 if client passed a certificate for this connection, 0 if not */
4046int ssl_sock_get_cert_used_conn(struct connection *conn)
David Safb76832014-05-08 23:42:08 -04004047{
4048 if (!ssl_sock_is_ssl(conn))
4049 return 0;
4050
4051 return SSL_SOCK_ST_FL_VERIFY_DONE & conn->xprt_st ? 1 : 0;
4052}
4053
4054/* returns result from SSL verify */
4055unsigned int ssl_sock_get_verify_result(struct connection *conn)
4056{
4057 if (!ssl_sock_is_ssl(conn))
4058 return (unsigned int)X509_V_ERR_APPLICATION_VERIFICATION;
4059
4060 return (unsigned int)SSL_get_verify_result(conn->xprt_ctx);
4061}
4062
Willy Tarreau7875d092012-09-10 08:20:03 +02004063/***** Below are some sample fetching functions for ACL/patterns *****/
4064
Emeric Brune64aef12012-09-21 13:15:06 +02004065/* boolean, returns true if client cert was present */
4066static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004067smp_fetch_ssl_fc_has_crt(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brune64aef12012-09-21 13:15:06 +02004068{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004069 struct connection *conn;
4070
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004071 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004072 if (!conn || conn->xprt != &ssl_sock)
Emeric Brune64aef12012-09-21 13:15:06 +02004073 return 0;
4074
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004075 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brune64aef12012-09-21 13:15:06 +02004076 smp->flags |= SMP_F_MAY_CHANGE;
4077 return 0;
4078 }
4079
4080 smp->flags = 0;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004081 smp->data.type = SMP_T_BOOL;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004082 smp->data.u.sint = SSL_SOCK_ST_FL_VERIFY_DONE & conn->xprt_st ? 1 : 0;
Emeric Brune64aef12012-09-21 13:15:06 +02004083
4084 return 1;
4085}
4086
Emeric Brun43e79582014-10-29 19:03:26 +01004087/* binary, returns a certificate in a binary chunk (der/raw).
4088 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
4089 * should be use.
4090 */
4091static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004092smp_fetch_ssl_x_der(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun43e79582014-10-29 19:03:26 +01004093{
4094 int cert_peer = (kw[4] == 'c') ? 1 : 0;
4095 X509 *crt = NULL;
4096 int ret = 0;
4097 struct chunk *smp_trash;
4098 struct connection *conn;
4099
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004100 conn = objt_conn(smp->sess->origin);
Emeric Brun43e79582014-10-29 19:03:26 +01004101 if (!conn || conn->xprt != &ssl_sock)
4102 return 0;
4103
4104 if (!(conn->flags & CO_FL_CONNECTED)) {
4105 smp->flags |= SMP_F_MAY_CHANGE;
4106 return 0;
4107 }
4108
4109 if (cert_peer)
4110 crt = SSL_get_peer_certificate(conn->xprt_ctx);
4111 else
4112 crt = SSL_get_certificate(conn->xprt_ctx);
4113
4114 if (!crt)
4115 goto out;
4116
4117 smp_trash = get_trash_chunk();
4118 if (ssl_sock_crt2der(crt, smp_trash) <= 0)
4119 goto out;
4120
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004121 smp->data.u.str = *smp_trash;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004122 smp->data.type = SMP_T_BIN;
Emeric Brun43e79582014-10-29 19:03:26 +01004123 ret = 1;
4124out:
4125 /* SSL_get_peer_certificate, it increase X509 * ref count */
4126 if (cert_peer && crt)
4127 X509_free(crt);
4128 return ret;
4129}
4130
Emeric Brunba841a12014-04-30 17:05:08 +02004131/* binary, returns serial of certificate in a binary chunk.
4132 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
4133 * should be use.
4134 */
Willy Tarreau8d598402012-10-22 17:58:39 +02004135static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004136smp_fetch_ssl_x_serial(const struct arg *args, struct sample *smp, const char *kw, void *private)
Willy Tarreau8d598402012-10-22 17:58:39 +02004137{
Emeric Brunba841a12014-04-30 17:05:08 +02004138 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Willy Tarreau8d598402012-10-22 17:58:39 +02004139 X509 *crt = NULL;
4140 int ret = 0;
4141 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004142 struct connection *conn;
4143
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004144 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004145 if (!conn || conn->xprt != &ssl_sock)
Willy Tarreau8d598402012-10-22 17:58:39 +02004146 return 0;
4147
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004148 if (!(conn->flags & CO_FL_CONNECTED)) {
Willy Tarreau8d598402012-10-22 17:58:39 +02004149 smp->flags |= SMP_F_MAY_CHANGE;
4150 return 0;
4151 }
4152
Emeric Brunba841a12014-04-30 17:05:08 +02004153 if (cert_peer)
4154 crt = SSL_get_peer_certificate(conn->xprt_ctx);
4155 else
4156 crt = SSL_get_certificate(conn->xprt_ctx);
4157
Willy Tarreau8d598402012-10-22 17:58:39 +02004158 if (!crt)
4159 goto out;
4160
Willy Tarreau47ca5452012-12-23 20:22:19 +01004161 smp_trash = get_trash_chunk();
Willy Tarreau8d598402012-10-22 17:58:39 +02004162 if (ssl_sock_get_serial(crt, smp_trash) <= 0)
4163 goto out;
4164
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004165 smp->data.u.str = *smp_trash;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004166 smp->data.type = SMP_T_BIN;
Willy Tarreau8d598402012-10-22 17:58:39 +02004167 ret = 1;
4168out:
Emeric Brunba841a12014-04-30 17:05:08 +02004169 /* SSL_get_peer_certificate, it increase X509 * ref count */
4170 if (cert_peer && crt)
Willy Tarreau8d598402012-10-22 17:58:39 +02004171 X509_free(crt);
4172 return ret;
4173}
Emeric Brune64aef12012-09-21 13:15:06 +02004174
Emeric Brunba841a12014-04-30 17:05:08 +02004175/* binary, returns the client certificate's SHA-1 fingerprint (SHA-1 hash of DER-encoded certificate) in a binary chunk.
4176 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
4177 * should be use.
4178 */
James Votha051b4a2013-05-14 20:37:59 +02004179static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004180smp_fetch_ssl_x_sha1(const struct arg *args, struct sample *smp, const char *kw, void *private)
James Votha051b4a2013-05-14 20:37:59 +02004181{
Emeric Brunba841a12014-04-30 17:05:08 +02004182 int cert_peer = (kw[4] == 'c') ? 1 : 0;
James Votha051b4a2013-05-14 20:37:59 +02004183 X509 *crt = NULL;
4184 const EVP_MD *digest;
4185 int ret = 0;
4186 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004187 struct connection *conn;
James Votha051b4a2013-05-14 20:37:59 +02004188
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004189 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004190 if (!conn || conn->xprt != &ssl_sock)
4191 return 0;
4192
4193 if (!(conn->flags & CO_FL_CONNECTED)) {
James Votha051b4a2013-05-14 20:37:59 +02004194 smp->flags |= SMP_F_MAY_CHANGE;
4195 return 0;
4196 }
4197
Emeric Brunba841a12014-04-30 17:05:08 +02004198 if (cert_peer)
4199 crt = SSL_get_peer_certificate(conn->xprt_ctx);
4200 else
4201 crt = SSL_get_certificate(conn->xprt_ctx);
James Votha051b4a2013-05-14 20:37:59 +02004202 if (!crt)
4203 goto out;
4204
4205 smp_trash = get_trash_chunk();
4206 digest = EVP_sha1();
4207 X509_digest(crt, digest, (unsigned char *)smp_trash->str, (unsigned int *)&smp_trash->len);
4208
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004209 smp->data.u.str = *smp_trash;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004210 smp->data.type = SMP_T_BIN;
James Votha051b4a2013-05-14 20:37:59 +02004211 ret = 1;
4212out:
Emeric Brunba841a12014-04-30 17:05:08 +02004213 /* SSL_get_peer_certificate, it increase X509 * ref count */
4214 if (cert_peer && crt)
James Votha051b4a2013-05-14 20:37:59 +02004215 X509_free(crt);
4216 return ret;
4217}
4218
Emeric Brunba841a12014-04-30 17:05:08 +02004219/* string, returns certificate's notafter date in ASN1_UTCTIME format.
4220 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
4221 * should be use.
4222 */
Emeric Brunce5ad802012-10-22 14:11:22 +02004223static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004224smp_fetch_ssl_x_notafter(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brunce5ad802012-10-22 14:11:22 +02004225{
Emeric Brunba841a12014-04-30 17:05:08 +02004226 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brunce5ad802012-10-22 14:11:22 +02004227 X509 *crt = NULL;
4228 int ret = 0;
4229 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004230 struct connection *conn;
Emeric Brunce5ad802012-10-22 14:11:22 +02004231
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004232 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004233 if (!conn || conn->xprt != &ssl_sock)
4234 return 0;
4235
4236 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunce5ad802012-10-22 14:11:22 +02004237 smp->flags |= SMP_F_MAY_CHANGE;
4238 return 0;
4239 }
4240
Emeric Brunba841a12014-04-30 17:05:08 +02004241 if (cert_peer)
4242 crt = SSL_get_peer_certificate(conn->xprt_ctx);
4243 else
4244 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brunce5ad802012-10-22 14:11:22 +02004245 if (!crt)
4246 goto out;
4247
Willy Tarreau47ca5452012-12-23 20:22:19 +01004248 smp_trash = get_trash_chunk();
Emeric Brunce5ad802012-10-22 14:11:22 +02004249 if (ssl_sock_get_time(X509_get_notAfter(crt), smp_trash) <= 0)
4250 goto out;
4251
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004252 smp->data.u.str = *smp_trash;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004253 smp->data.type = SMP_T_STR;
Emeric Brunce5ad802012-10-22 14:11:22 +02004254 ret = 1;
4255out:
Emeric Brunba841a12014-04-30 17:05:08 +02004256 /* SSL_get_peer_certificate, it increase X509 * ref count */
4257 if (cert_peer && crt)
Emeric Brunce5ad802012-10-22 14:11:22 +02004258 X509_free(crt);
4259 return ret;
4260}
4261
Emeric Brunba841a12014-04-30 17:05:08 +02004262/* string, returns a string of a formatted full dn \C=..\O=..\OU=.. \CN=.. of certificate's issuer
4263 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
4264 * should be use.
4265 */
Emeric Brun87855892012-10-17 17:39:35 +02004266static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004267smp_fetch_ssl_x_i_dn(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun87855892012-10-17 17:39:35 +02004268{
Emeric Brunba841a12014-04-30 17:05:08 +02004269 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brun87855892012-10-17 17:39:35 +02004270 X509 *crt = NULL;
4271 X509_NAME *name;
4272 int ret = 0;
4273 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004274 struct connection *conn;
Emeric Brun87855892012-10-17 17:39:35 +02004275
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004276 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004277 if (!conn || conn->xprt != &ssl_sock)
4278 return 0;
4279
4280 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun87855892012-10-17 17:39:35 +02004281 smp->flags |= SMP_F_MAY_CHANGE;
4282 return 0;
4283 }
4284
Emeric Brunba841a12014-04-30 17:05:08 +02004285 if (cert_peer)
4286 crt = SSL_get_peer_certificate(conn->xprt_ctx);
4287 else
4288 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brun87855892012-10-17 17:39:35 +02004289 if (!crt)
4290 goto out;
4291
4292 name = X509_get_issuer_name(crt);
4293 if (!name)
4294 goto out;
4295
Willy Tarreau47ca5452012-12-23 20:22:19 +01004296 smp_trash = get_trash_chunk();
Emeric Brun87855892012-10-17 17:39:35 +02004297 if (args && args[0].type == ARGT_STR) {
4298 int pos = 1;
4299
4300 if (args[1].type == ARGT_SINT)
4301 pos = args[1].data.sint;
Emeric Brun87855892012-10-17 17:39:35 +02004302
4303 if (ssl_sock_get_dn_entry(name, &args[0].data.str, pos, smp_trash) <= 0)
4304 goto out;
4305 }
4306 else if (ssl_sock_get_dn_oneline(name, smp_trash) <= 0)
4307 goto out;
4308
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004309 smp->data.type = SMP_T_STR;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004310 smp->data.u.str = *smp_trash;
Emeric Brun87855892012-10-17 17:39:35 +02004311 ret = 1;
4312out:
Emeric Brunba841a12014-04-30 17:05:08 +02004313 /* SSL_get_peer_certificate, it increase X509 * ref count */
4314 if (cert_peer && crt)
Emeric Brun87855892012-10-17 17:39:35 +02004315 X509_free(crt);
4316 return ret;
4317}
4318
Emeric Brunba841a12014-04-30 17:05:08 +02004319/* string, returns notbefore date in ASN1_UTCTIME format.
4320 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
4321 * should be use.
4322 */
Emeric Brunce5ad802012-10-22 14:11:22 +02004323static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004324smp_fetch_ssl_x_notbefore(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brunce5ad802012-10-22 14:11:22 +02004325{
Emeric Brunba841a12014-04-30 17:05:08 +02004326 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brunce5ad802012-10-22 14:11:22 +02004327 X509 *crt = NULL;
4328 int ret = 0;
4329 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004330 struct connection *conn;
4331
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004332 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004333 if (!conn || conn->xprt != &ssl_sock)
Emeric Brunce5ad802012-10-22 14:11:22 +02004334 return 0;
4335
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004336 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunce5ad802012-10-22 14:11:22 +02004337 smp->flags |= SMP_F_MAY_CHANGE;
4338 return 0;
4339 }
4340
Emeric Brunba841a12014-04-30 17:05:08 +02004341 if (cert_peer)
4342 crt = SSL_get_peer_certificate(conn->xprt_ctx);
4343 else
4344 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brunce5ad802012-10-22 14:11:22 +02004345 if (!crt)
4346 goto out;
4347
Willy Tarreau47ca5452012-12-23 20:22:19 +01004348 smp_trash = get_trash_chunk();
Emeric Brunce5ad802012-10-22 14:11:22 +02004349 if (ssl_sock_get_time(X509_get_notBefore(crt), smp_trash) <= 0)
4350 goto out;
4351
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004352 smp->data.u.str = *smp_trash;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004353 smp->data.type = SMP_T_STR;
Emeric Brunce5ad802012-10-22 14:11:22 +02004354 ret = 1;
4355out:
Emeric Brunba841a12014-04-30 17:05:08 +02004356 /* SSL_get_peer_certificate, it increase X509 * ref count */
4357 if (cert_peer && crt)
Emeric Brunce5ad802012-10-22 14:11:22 +02004358 X509_free(crt);
4359 return ret;
4360}
4361
Emeric Brunba841a12014-04-30 17:05:08 +02004362/* string, returns a string of a formatted full dn \C=..\O=..\OU=.. \CN=.. of certificate's subject
4363 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
4364 * should be use.
4365 */
Emeric Brun87855892012-10-17 17:39:35 +02004366static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004367smp_fetch_ssl_x_s_dn(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun87855892012-10-17 17:39:35 +02004368{
Emeric Brunba841a12014-04-30 17:05:08 +02004369 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brun87855892012-10-17 17:39:35 +02004370 X509 *crt = NULL;
4371 X509_NAME *name;
4372 int ret = 0;
4373 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004374 struct connection *conn;
Emeric Brun87855892012-10-17 17:39:35 +02004375
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004376 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004377 if (!conn || conn->xprt != &ssl_sock)
4378 return 0;
4379
4380 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun87855892012-10-17 17:39:35 +02004381 smp->flags |= SMP_F_MAY_CHANGE;
4382 return 0;
4383 }
4384
Emeric Brunba841a12014-04-30 17:05:08 +02004385 if (cert_peer)
4386 crt = SSL_get_peer_certificate(conn->xprt_ctx);
4387 else
4388 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brun87855892012-10-17 17:39:35 +02004389 if (!crt)
4390 goto out;
4391
4392 name = X509_get_subject_name(crt);
4393 if (!name)
4394 goto out;
4395
Willy Tarreau47ca5452012-12-23 20:22:19 +01004396 smp_trash = get_trash_chunk();
Emeric Brun87855892012-10-17 17:39:35 +02004397 if (args && args[0].type == ARGT_STR) {
4398 int pos = 1;
4399
4400 if (args[1].type == ARGT_SINT)
4401 pos = args[1].data.sint;
Emeric Brun87855892012-10-17 17:39:35 +02004402
4403 if (ssl_sock_get_dn_entry(name, &args[0].data.str, pos, smp_trash) <= 0)
4404 goto out;
4405 }
4406 else if (ssl_sock_get_dn_oneline(name, smp_trash) <= 0)
4407 goto out;
4408
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004409 smp->data.type = SMP_T_STR;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004410 smp->data.u.str = *smp_trash;
Emeric Brun87855892012-10-17 17:39:35 +02004411 ret = 1;
4412out:
Emeric Brunba841a12014-04-30 17:05:08 +02004413 /* SSL_get_peer_certificate, it increase X509 * ref count */
4414 if (cert_peer && crt)
Emeric Brun87855892012-10-17 17:39:35 +02004415 X509_free(crt);
4416 return ret;
4417}
Emeric Brun9143d372012-12-20 15:44:16 +01004418
4419/* integer, returns true if current session use a client certificate */
4420static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004421smp_fetch_ssl_c_used(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun9143d372012-12-20 15:44:16 +01004422{
4423 X509 *crt;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004424 struct connection *conn;
Emeric Brun9143d372012-12-20 15:44:16 +01004425
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004426 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004427 if (!conn || conn->xprt != &ssl_sock)
4428 return 0;
4429
4430 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun9143d372012-12-20 15:44:16 +01004431 smp->flags |= SMP_F_MAY_CHANGE;
4432 return 0;
4433 }
4434
4435 /* SSL_get_peer_certificate returns a ptr on allocated X509 struct */
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004436 crt = SSL_get_peer_certificate(conn->xprt_ctx);
Emeric Brun9143d372012-12-20 15:44:16 +01004437 if (crt) {
4438 X509_free(crt);
4439 }
4440
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004441 smp->data.type = SMP_T_BOOL;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004442 smp->data.u.sint = (crt != NULL);
Emeric Brun9143d372012-12-20 15:44:16 +01004443 return 1;
4444}
4445
Emeric Brunba841a12014-04-30 17:05:08 +02004446/* integer, returns the certificate version
4447 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
4448 * should be use.
4449 */
Emeric Bruna7359fd2012-10-17 15:03:11 +02004450static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004451smp_fetch_ssl_x_version(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Bruna7359fd2012-10-17 15:03:11 +02004452{
Emeric Brunba841a12014-04-30 17:05:08 +02004453 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Bruna7359fd2012-10-17 15:03:11 +02004454 X509 *crt;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004455 struct connection *conn;
4456
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004457 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004458 if (!conn || conn->xprt != &ssl_sock)
Emeric Bruna7359fd2012-10-17 15:03:11 +02004459 return 0;
4460
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004461 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Bruna7359fd2012-10-17 15:03:11 +02004462 smp->flags |= SMP_F_MAY_CHANGE;
4463 return 0;
4464 }
4465
Emeric Brunba841a12014-04-30 17:05:08 +02004466 if (cert_peer)
4467 crt = SSL_get_peer_certificate(conn->xprt_ctx);
4468 else
4469 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Bruna7359fd2012-10-17 15:03:11 +02004470 if (!crt)
4471 return 0;
4472
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004473 smp->data.u.sint = (unsigned int)(1 + X509_get_version(crt));
Emeric Brunba841a12014-04-30 17:05:08 +02004474 /* SSL_get_peer_certificate increase X509 * ref count */
4475 if (cert_peer)
4476 X509_free(crt);
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004477 smp->data.type = SMP_T_SINT;
Emeric Bruna7359fd2012-10-17 15:03:11 +02004478
4479 return 1;
4480}
4481
Emeric Brunba841a12014-04-30 17:05:08 +02004482/* string, returns the certificate's signature algorithm.
4483 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
4484 * should be use.
4485 */
Emeric Brun7f56e742012-10-19 18:15:40 +02004486static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004487smp_fetch_ssl_x_sig_alg(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun7f56e742012-10-19 18:15:40 +02004488{
Emeric Brunba841a12014-04-30 17:05:08 +02004489 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brun7f56e742012-10-19 18:15:40 +02004490 X509 *crt;
4491 int nid;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004492 struct connection *conn;
Emeric Brun7f56e742012-10-19 18:15:40 +02004493
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004494 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004495 if (!conn || conn->xprt != &ssl_sock)
4496 return 0;
4497
4498 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun7f56e742012-10-19 18:15:40 +02004499 smp->flags |= SMP_F_MAY_CHANGE;
4500 return 0;
4501 }
4502
Emeric Brunba841a12014-04-30 17:05:08 +02004503 if (cert_peer)
4504 crt = SSL_get_peer_certificate(conn->xprt_ctx);
4505 else
4506 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brun7f56e742012-10-19 18:15:40 +02004507 if (!crt)
4508 return 0;
4509
4510 nid = OBJ_obj2nid((ASN1_OBJECT *)(crt->cert_info->signature->algorithm));
4511
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004512 smp->data.u.str.str = (char *)OBJ_nid2sn(nid);
4513 if (!smp->data.u.str.str) {
Emeric Brunba841a12014-04-30 17:05:08 +02004514 /* SSL_get_peer_certificate increase X509 * ref count */
4515 if (cert_peer)
4516 X509_free(crt);
Emeric Brun7f56e742012-10-19 18:15:40 +02004517 return 0;
Emeric Brun9bf3ba22013-10-07 14:31:44 +02004518 }
Emeric Brun7f56e742012-10-19 18:15:40 +02004519
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004520 smp->data.type = SMP_T_STR;
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01004521 smp->flags |= SMP_F_CONST;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004522 smp->data.u.str.len = strlen(smp->data.u.str.str);
Emeric Brunba841a12014-04-30 17:05:08 +02004523 /* SSL_get_peer_certificate increase X509 * ref count */
4524 if (cert_peer)
4525 X509_free(crt);
Emeric Brun7f56e742012-10-19 18:15:40 +02004526
4527 return 1;
4528}
4529
Emeric Brunba841a12014-04-30 17:05:08 +02004530/* string, returns the certificate's key algorithm.
4531 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
4532 * should be use.
4533 */
Emeric Brun521a0112012-10-22 12:22:55 +02004534static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004535smp_fetch_ssl_x_key_alg(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun521a0112012-10-22 12:22:55 +02004536{
Emeric Brunba841a12014-04-30 17:05:08 +02004537 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brun521a0112012-10-22 12:22:55 +02004538 X509 *crt;
4539 int nid;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004540 struct connection *conn;
Emeric Brun521a0112012-10-22 12:22:55 +02004541
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004542 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004543 if (!conn || conn->xprt != &ssl_sock)
4544 return 0;
4545
4546 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun521a0112012-10-22 12:22:55 +02004547 smp->flags |= SMP_F_MAY_CHANGE;
4548 return 0;
4549 }
4550
Emeric Brunba841a12014-04-30 17:05:08 +02004551 if (cert_peer)
4552 crt = SSL_get_peer_certificate(conn->xprt_ctx);
4553 else
4554 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brun521a0112012-10-22 12:22:55 +02004555 if (!crt)
4556 return 0;
4557
4558 nid = OBJ_obj2nid((ASN1_OBJECT *)(crt->cert_info->key->algor->algorithm));
4559
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004560 smp->data.u.str.str = (char *)OBJ_nid2sn(nid);
4561 if (!smp->data.u.str.str) {
Emeric Brunba841a12014-04-30 17:05:08 +02004562 /* SSL_get_peer_certificate increase X509 * ref count */
4563 if (cert_peer)
4564 X509_free(crt);
Emeric Brun521a0112012-10-22 12:22:55 +02004565 return 0;
Emeric Brun9bf3ba22013-10-07 14:31:44 +02004566 }
Emeric Brun521a0112012-10-22 12:22:55 +02004567
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004568 smp->data.type = SMP_T_STR;
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01004569 smp->flags |= SMP_F_CONST;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004570 smp->data.u.str.len = strlen(smp->data.u.str.str);
Emeric Brunba841a12014-04-30 17:05:08 +02004571 if (cert_peer)
4572 X509_free(crt);
Emeric Brun521a0112012-10-22 12:22:55 +02004573
4574 return 1;
4575}
4576
Emeric Brun645ae792014-04-30 14:21:06 +02004577/* boolean, returns true if front conn. transport layer is SSL.
4578 * This function is also usable on backend conn if the fetch keyword 5th
4579 * char is 'b'.
4580 */
Willy Tarreau7875d092012-09-10 08:20:03 +02004581static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004582smp_fetch_ssl_fc(const struct arg *args, struct sample *smp, const char *kw, void *private)
Willy Tarreau7875d092012-09-10 08:20:03 +02004583{
Willy Tarreaue237fe12016-03-10 17:05:28 +01004584 struct connection *conn = objt_conn((kw[4] != 'b') ? smp->sess->origin :
4585 smp->strm ? smp->strm->si[1].end : NULL);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004586
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004587 smp->data.type = SMP_T_BOOL;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004588 smp->data.u.sint = (conn && conn->xprt == &ssl_sock);
Willy Tarreau7875d092012-09-10 08:20:03 +02004589 return 1;
4590}
4591
Emeric Brun2525b6b2012-10-18 15:59:43 +02004592/* boolean, returns true if client present a SNI */
Willy Tarreau7875d092012-09-10 08:20:03 +02004593static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004594smp_fetch_ssl_fc_has_sni(const struct arg *args, struct sample *smp, const char *kw, void *private)
Willy Tarreau7875d092012-09-10 08:20:03 +02004595{
4596#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004597 struct connection *conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004598
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004599 smp->data.type = SMP_T_BOOL;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004600 smp->data.u.sint = (conn && conn->xprt == &ssl_sock) &&
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004601 conn->xprt_ctx &&
4602 SSL_get_servername(conn->xprt_ctx, TLSEXT_NAMETYPE_host_name) != NULL;
Willy Tarreau7875d092012-09-10 08:20:03 +02004603 return 1;
4604#else
4605 return 0;
4606#endif
4607}
4608
Nenad Merdanovic26ea8222015-05-18 02:28:57 +02004609/* boolean, returns true if client session has been resumed */
4610static int
4611smp_fetch_ssl_fc_is_resumed(const struct arg *args, struct sample *smp, const char *kw, void *private)
4612{
4613 struct connection *conn = objt_conn(smp->sess->origin);
4614
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004615 smp->data.type = SMP_T_BOOL;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004616 smp->data.u.sint = (conn && conn->xprt == &ssl_sock) &&
Nenad Merdanovic26ea8222015-05-18 02:28:57 +02004617 conn->xprt_ctx &&
4618 SSL_session_reused(conn->xprt_ctx);
4619 return 1;
4620}
4621
Emeric Brun645ae792014-04-30 14:21:06 +02004622/* string, returns the used cipher if front conn. transport layer is SSL.
4623 * This function is also usable on backend conn if the fetch keyword 5th
4624 * char is 'b'.
4625 */
Emeric Brun589fcad2012-10-16 14:13:26 +02004626static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004627smp_fetch_ssl_fc_cipher(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun589fcad2012-10-16 14:13:26 +02004628{
Willy Tarreaue237fe12016-03-10 17:05:28 +01004629 struct connection *conn = objt_conn((kw[4] != 'b') ? smp->sess->origin :
4630 smp->strm ? smp->strm->si[1].end : NULL);
Emeric Brun589fcad2012-10-16 14:13:26 +02004631
Willy Tarreaube508f12016-03-10 11:47:01 +01004632 smp->flags = 0;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004633 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
Emeric Brun589fcad2012-10-16 14:13:26 +02004634 return 0;
4635
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004636 smp->data.u.str.str = (char *)SSL_get_cipher_name(conn->xprt_ctx);
4637 if (!smp->data.u.str.str)
Emeric Brun589fcad2012-10-16 14:13:26 +02004638 return 0;
4639
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004640 smp->data.type = SMP_T_STR;
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01004641 smp->flags |= SMP_F_CONST;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004642 smp->data.u.str.len = strlen(smp->data.u.str.str);
Emeric Brun589fcad2012-10-16 14:13:26 +02004643
4644 return 1;
4645}
4646
Emeric Brun645ae792014-04-30 14:21:06 +02004647/* integer, returns the algoritm's keysize if front conn. transport layer
4648 * is SSL.
4649 * This function is also usable on backend conn if the fetch keyword 5th
4650 * char is 'b'.
4651 */
Emeric Brun589fcad2012-10-16 14:13:26 +02004652static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004653smp_fetch_ssl_fc_alg_keysize(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun589fcad2012-10-16 14:13:26 +02004654{
Willy Tarreaue237fe12016-03-10 17:05:28 +01004655 struct connection *conn = objt_conn((kw[4] != 'b') ? smp->sess->origin :
4656 smp->strm ? smp->strm->si[1].end : NULL);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004657
Willy Tarreaue237fe12016-03-10 17:05:28 +01004658 int sint;
Willy Tarreaube508f12016-03-10 11:47:01 +01004659
Emeric Brun589fcad2012-10-16 14:13:26 +02004660 smp->flags = 0;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004661 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
Emeric Brun589fcad2012-10-16 14:13:26 +02004662 return 0;
4663
Thierry FOURNIER07ee64e2015-07-06 23:43:03 +02004664 if (!SSL_get_cipher_bits(conn->xprt_ctx, &sint))
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004665 return 0;
4666
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004667 smp->data.u.sint = sint;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004668 smp->data.type = SMP_T_SINT;
Emeric Brun589fcad2012-10-16 14:13:26 +02004669
4670 return 1;
4671}
4672
Emeric Brun645ae792014-04-30 14:21:06 +02004673/* integer, returns the used keysize if front conn. transport layer is SSL.
4674 * This function is also usable on backend conn if the fetch keyword 5th
4675 * char is 'b'.
4676 */
Emeric Brun589fcad2012-10-16 14:13:26 +02004677static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004678smp_fetch_ssl_fc_use_keysize(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun589fcad2012-10-16 14:13:26 +02004679{
Willy Tarreaue237fe12016-03-10 17:05:28 +01004680 struct connection *conn = objt_conn((kw[4] != 'b') ? smp->sess->origin :
4681 smp->strm ? smp->strm->si[1].end : NULL);
Willy Tarreaube508f12016-03-10 11:47:01 +01004682
Emeric Brun589fcad2012-10-16 14:13:26 +02004683 smp->flags = 0;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004684 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
4685 return 0;
4686
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004687 smp->data.u.sint = (unsigned int)SSL_get_cipher_bits(conn->xprt_ctx, NULL);
4688 if (!smp->data.u.sint)
Emeric Brun589fcad2012-10-16 14:13:26 +02004689 return 0;
4690
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004691 smp->data.type = SMP_T_SINT;
Emeric Brun589fcad2012-10-16 14:13:26 +02004692
4693 return 1;
4694}
4695
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02004696#ifdef OPENSSL_NPN_NEGOTIATED
Willy Tarreau7875d092012-09-10 08:20:03 +02004697static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004698smp_fetch_ssl_fc_npn(const struct arg *args, struct sample *smp, const char *kw, void *private)
Willy Tarreaua33c6542012-10-15 13:19:06 +02004699{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004700 struct connection *conn;
4701
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01004702 smp->flags = SMP_F_CONST;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004703 smp->data.type = SMP_T_STR;
Willy Tarreaua33c6542012-10-15 13:19:06 +02004704
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004705 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004706 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
4707 return 0;
4708
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004709 smp->data.u.str.str = NULL;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004710 SSL_get0_next_proto_negotiated(conn->xprt_ctx,
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004711 (const unsigned char **)&smp->data.u.str.str, (unsigned *)&smp->data.u.str.len);
Willy Tarreaua33c6542012-10-15 13:19:06 +02004712
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004713 if (!smp->data.u.str.str)
Willy Tarreaua33c6542012-10-15 13:19:06 +02004714 return 0;
4715
4716 return 1;
Willy Tarreaua33c6542012-10-15 13:19:06 +02004717}
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02004718#endif
Willy Tarreaua33c6542012-10-15 13:19:06 +02004719
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01004720#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Willy Tarreauab861d32013-04-02 02:30:41 +02004721static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004722smp_fetch_ssl_fc_alpn(const struct arg *args, struct sample *smp, const char *kw, void *private)
Willy Tarreauab861d32013-04-02 02:30:41 +02004723{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004724 struct connection *conn;
4725
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01004726 smp->flags = SMP_F_CONST;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004727 smp->data.type = SMP_T_STR;
Willy Tarreauab861d32013-04-02 02:30:41 +02004728
Willy Tarreaue26bf052015-05-12 10:30:12 +02004729 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004730 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
Willy Tarreauab861d32013-04-02 02:30:41 +02004731 return 0;
4732
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004733 smp->data.u.str.str = NULL;
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01004734 SSL_get0_alpn_selected(conn->xprt_ctx,
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004735 (const unsigned char **)&smp->data.u.str.str, (unsigned *)&smp->data.u.str.len);
Willy Tarreauab861d32013-04-02 02:30:41 +02004736
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004737 if (!smp->data.u.str.str)
Willy Tarreauab861d32013-04-02 02:30:41 +02004738 return 0;
4739
4740 return 1;
4741}
4742#endif
4743
Emeric Brun645ae792014-04-30 14:21:06 +02004744/* string, returns the used protocol if front conn. transport layer is SSL.
4745 * This function is also usable on backend conn if the fetch keyword 5th
4746 * char is 'b'.
4747 */
Willy Tarreaua33c6542012-10-15 13:19:06 +02004748static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004749smp_fetch_ssl_fc_protocol(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun589fcad2012-10-16 14:13:26 +02004750{
Willy Tarreaue237fe12016-03-10 17:05:28 +01004751 struct connection *conn = objt_conn((kw[4] != 'b') ? smp->sess->origin :
4752 smp->strm ? smp->strm->si[1].end : NULL);
Willy Tarreaube508f12016-03-10 11:47:01 +01004753
Emeric Brun589fcad2012-10-16 14:13:26 +02004754 smp->flags = 0;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004755 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
4756 return 0;
4757
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004758 smp->data.u.str.str = (char *)SSL_get_version(conn->xprt_ctx);
4759 if (!smp->data.u.str.str)
Emeric Brun589fcad2012-10-16 14:13:26 +02004760 return 0;
4761
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004762 smp->data.type = SMP_T_STR;
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01004763 smp->flags = SMP_F_CONST;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004764 smp->data.u.str.len = strlen(smp->data.u.str.str);
Emeric Brun589fcad2012-10-16 14:13:26 +02004765
4766 return 1;
4767}
4768
Willy Tarreau87b09662015-04-03 00:22:06 +02004769/* binary, returns the SSL stream id if front conn. transport layer is SSL.
Emeric Brun645ae792014-04-30 14:21:06 +02004770 * This function is also usable on backend conn if the fetch keyword 5th
4771 * char is 'b'.
4772 */
Emeric Brun589fcad2012-10-16 14:13:26 +02004773static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004774smp_fetch_ssl_fc_session_id(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brunfe68f682012-10-16 14:59:28 +02004775{
4776#if OPENSSL_VERSION_NUMBER > 0x0090800fL
Willy Tarreaue237fe12016-03-10 17:05:28 +01004777 struct connection *conn = objt_conn((kw[4] != 'b') ? smp->sess->origin :
4778 smp->strm ? smp->strm->si[1].end : NULL);
Emeric Brunfe68f682012-10-16 14:59:28 +02004779
Willy Tarreaue237fe12016-03-10 17:05:28 +01004780 SSL_SESSION *ssl_sess;
Willy Tarreaube508f12016-03-10 11:47:01 +01004781
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01004782 smp->flags = SMP_F_CONST;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004783 smp->data.type = SMP_T_BIN;
Emeric Brunfe68f682012-10-16 14:59:28 +02004784
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004785 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
4786 return 0;
4787
Willy Tarreau192252e2015-04-04 01:47:55 +02004788 ssl_sess = SSL_get_session(conn->xprt_ctx);
4789 if (!ssl_sess)
Emeric Brunfe68f682012-10-16 14:59:28 +02004790 return 0;
4791
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004792 smp->data.u.str.str = (char *)SSL_SESSION_get_id(ssl_sess, (unsigned int *)&smp->data.u.str.len);
4793 if (!smp->data.u.str.str || !smp->data.u.str.len)
Emeric Brunfe68f682012-10-16 14:59:28 +02004794 return 0;
4795
4796 return 1;
4797#else
4798 return 0;
4799#endif
4800}
4801
4802static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004803smp_fetch_ssl_fc_sni(const struct arg *args, struct sample *smp, const char *kw, void *private)
Willy Tarreau7875d092012-09-10 08:20:03 +02004804{
4805#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004806 struct connection *conn;
4807
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01004808 smp->flags = SMP_F_CONST;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004809 smp->data.type = SMP_T_STR;
Willy Tarreau7875d092012-09-10 08:20:03 +02004810
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004811 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004812 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
4813 return 0;
4814
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004815 smp->data.u.str.str = (char *)SSL_get_servername(conn->xprt_ctx, TLSEXT_NAMETYPE_host_name);
4816 if (!smp->data.u.str.str)
Willy Tarreau3e394c92012-09-14 23:56:58 +02004817 return 0;
4818
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004819 smp->data.u.str.len = strlen(smp->data.u.str.str);
Willy Tarreau7875d092012-09-10 08:20:03 +02004820 return 1;
4821#else
4822 return 0;
4823#endif
4824}
4825
David Sc1ad52e2014-04-08 18:48:47 -04004826static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004827smp_fetch_ssl_fc_unique_id(const struct arg *args, struct sample *smp, const char *kw, void *private)
David Sc1ad52e2014-04-08 18:48:47 -04004828{
4829#if OPENSSL_VERSION_NUMBER > 0x0090800fL
Willy Tarreaue237fe12016-03-10 17:05:28 +01004830 struct connection *conn = objt_conn((kw[4] != 'b') ? smp->sess->origin :
4831 smp->strm ? smp->strm->si[1].end : NULL);
4832
David Sc1ad52e2014-04-08 18:48:47 -04004833 int finished_len;
David Sc1ad52e2014-04-08 18:48:47 -04004834 struct chunk *finished_trash;
David Sc1ad52e2014-04-08 18:48:47 -04004835
4836 smp->flags = 0;
David Sc1ad52e2014-04-08 18:48:47 -04004837 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
4838 return 0;
4839
4840 if (!(conn->flags & CO_FL_CONNECTED)) {
4841 smp->flags |= SMP_F_MAY_CHANGE;
4842 return 0;
4843 }
4844
4845 finished_trash = get_trash_chunk();
4846 if (!SSL_session_reused(conn->xprt_ctx))
4847 finished_len = SSL_get_peer_finished(conn->xprt_ctx, finished_trash->str, finished_trash->size);
4848 else
4849 finished_len = SSL_get_finished(conn->xprt_ctx, finished_trash->str, finished_trash->size);
4850
4851 if (!finished_len)
4852 return 0;
4853
Emeric Brunb73a9b02014-04-30 18:49:19 +02004854 finished_trash->len = finished_len;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004855 smp->data.u.str = *finished_trash;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004856 smp->data.type = SMP_T_BIN;
David Sc1ad52e2014-04-08 18:48:47 -04004857
4858 return 1;
4859#else
4860 return 0;
4861#endif
4862}
4863
Emeric Brun2525b6b2012-10-18 15:59:43 +02004864/* integer, returns the first verify error in CA chain of client certificate chain. */
Emeric Brunf282a812012-09-21 15:27:54 +02004865static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004866smp_fetch_ssl_c_ca_err(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brunf282a812012-09-21 15:27:54 +02004867{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004868 struct connection *conn;
4869
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004870 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004871 if (!conn || conn->xprt != &ssl_sock)
4872 return 0;
4873
4874 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunf282a812012-09-21 15:27:54 +02004875 smp->flags = SMP_F_MAY_CHANGE;
4876 return 0;
4877 }
4878
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004879 smp->data.type = SMP_T_SINT;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004880 smp->data.u.sint = (unsigned long long int)SSL_SOCK_ST_TO_CA_ERROR(conn->xprt_st);
Emeric Brunf282a812012-09-21 15:27:54 +02004881 smp->flags = 0;
4882
4883 return 1;
4884}
4885
Emeric Brun2525b6b2012-10-18 15:59:43 +02004886/* integer, returns the depth of the first verify error in CA chain of client certificate chain. */
Emeric Brunf282a812012-09-21 15:27:54 +02004887static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004888smp_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 +02004889{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004890 struct connection *conn;
4891
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004892 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004893 if (!conn || conn->xprt != &ssl_sock)
Emeric Brunf282a812012-09-21 15:27:54 +02004894 return 0;
4895
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004896 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunf282a812012-09-21 15:27:54 +02004897 smp->flags = SMP_F_MAY_CHANGE;
4898 return 0;
4899 }
4900
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004901 smp->data.type = SMP_T_SINT;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004902 smp->data.u.sint = (long long int)SSL_SOCK_ST_TO_CAEDEPTH(conn->xprt_st);
Emeric Brunf282a812012-09-21 15:27:54 +02004903 smp->flags = 0;
4904
4905 return 1;
4906}
4907
Emeric Brun2525b6b2012-10-18 15:59:43 +02004908/* integer, returns the first verify error on client certificate */
Emeric Brunf282a812012-09-21 15:27:54 +02004909static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004910smp_fetch_ssl_c_err(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brunf282a812012-09-21 15:27:54 +02004911{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004912 struct connection *conn;
4913
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004914 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004915 if (!conn || conn->xprt != &ssl_sock)
4916 return 0;
4917
4918 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunf282a812012-09-21 15:27:54 +02004919 smp->flags = SMP_F_MAY_CHANGE;
4920 return 0;
4921 }
4922
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004923 smp->data.type = SMP_T_SINT;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004924 smp->data.u.sint = (long long int)SSL_SOCK_ST_TO_CRTERROR(conn->xprt_st);
Emeric Brunf282a812012-09-21 15:27:54 +02004925 smp->flags = 0;
4926
4927 return 1;
4928}
4929
Emeric Brun2525b6b2012-10-18 15:59:43 +02004930/* integer, returns the verify result on client cert */
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02004931static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004932smp_fetch_ssl_c_verify(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02004933{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004934 struct connection *conn;
4935
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004936 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004937 if (!conn || conn->xprt != &ssl_sock)
4938 return 0;
4939
4940 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02004941 smp->flags = SMP_F_MAY_CHANGE;
4942 return 0;
4943 }
4944
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004945 if (!conn->xprt_ctx)
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02004946 return 0;
4947
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004948 smp->data.type = SMP_T_SINT;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004949 smp->data.u.sint = (long long int)SSL_get_verify_result(conn->xprt_ctx);
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02004950 smp->flags = 0;
4951
4952 return 1;
4953}
4954
Emeric Brunfb510ea2012-10-05 12:00:26 +02004955/* parse the "ca-file" bind keyword */
4956static 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 +02004957{
4958 if (!*args[cur_arg + 1]) {
4959 if (err)
4960 memprintf(err, "'%s' : missing CAfile path", args[cur_arg]);
4961 return ERR_ALERT | ERR_FATAL;
4962 }
4963
Emeric Brunef42d922012-10-11 16:11:36 +02004964 if ((*args[cur_arg + 1] != '/') && global.ca_base)
4965 memprintf(&conf->ca_file, "%s/%s", global.ca_base, args[cur_arg + 1]);
4966 else
4967 memprintf(&conf->ca_file, "%s", args[cur_arg + 1]);
Emeric Brunc8e8d122012-10-02 18:42:10 +02004968
Emeric Brund94b3fe2012-09-20 18:23:56 +02004969 return 0;
4970}
4971
Christopher Faulet31af49d2015-06-09 17:29:50 +02004972/* parse the "ca-sign-file" bind keyword */
4973static int bind_parse_ca_sign_file(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
4974{
4975 if (!*args[cur_arg + 1]) {
4976 if (err)
4977 memprintf(err, "'%s' : missing CAfile path", args[cur_arg]);
4978 return ERR_ALERT | ERR_FATAL;
4979 }
4980
4981 if ((*args[cur_arg + 1] != '/') && global.ca_base)
4982 memprintf(&conf->ca_sign_file, "%s/%s", global.ca_base, args[cur_arg + 1]);
4983 else
4984 memprintf(&conf->ca_sign_file, "%s", args[cur_arg + 1]);
4985
4986 return 0;
4987}
4988
4989/* parse the ca-sign-pass bind keyword */
4990
4991static int bind_parse_ca_sign_pass(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
4992{
4993 if (!*args[cur_arg + 1]) {
4994 if (err)
4995 memprintf(err, "'%s' : missing CAkey password", args[cur_arg]);
4996 return ERR_ALERT | ERR_FATAL;
4997 }
4998 memprintf(&conf->ca_sign_pass, "%s", args[cur_arg + 1]);
4999 return 0;
5000}
5001
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005002/* parse the "ciphers" bind keyword */
Willy Tarreau4348fad2012-09-20 16:48:07 +02005003static 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 +02005004{
5005 if (!*args[cur_arg + 1]) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02005006 memprintf(err, "'%s' : missing cipher suite", args[cur_arg]);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005007 return ERR_ALERT | ERR_FATAL;
5008 }
5009
Emeric Brun76d88952012-10-05 15:47:31 +02005010 free(conf->ciphers);
Willy Tarreau4348fad2012-09-20 16:48:07 +02005011 conf->ciphers = strdup(args[cur_arg + 1]);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005012 return 0;
5013}
5014
5015/* parse the "crt" bind keyword */
Willy Tarreau4348fad2012-09-20 16:48:07 +02005016static 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 +02005017{
Willy Tarreau38011032013-08-13 16:59:39 +02005018 char path[MAXPATHLEN];
Willy Tarreaub75d6922014-04-14 18:05:41 +02005019
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005020 if (!*args[cur_arg + 1]) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02005021 memprintf(err, "'%s' : missing certificate location", args[cur_arg]);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005022 return ERR_ALERT | ERR_FATAL;
5023 }
5024
Emeric Brunc8e8d122012-10-02 18:42:10 +02005025 if ((*args[cur_arg + 1] != '/' ) && global.crt_base) {
Willy Tarreau38011032013-08-13 16:59:39 +02005026 if ((strlen(global.crt_base) + 1 + strlen(args[cur_arg + 1]) + 1) > MAXPATHLEN) {
Emeric Brunc8e8d122012-10-02 18:42:10 +02005027 memprintf(err, "'%s' : path too long", args[cur_arg]);
5028 return ERR_ALERT | ERR_FATAL;
5029 }
Willy Tarreaub75d6922014-04-14 18:05:41 +02005030 snprintf(path, sizeof(path), "%s/%s", global.crt_base, args[cur_arg + 1]);
Emeric Brunc8e8d122012-10-02 18:42:10 +02005031 if (ssl_sock_load_cert(path, conf, px, err) > 0)
5032 return ERR_ALERT | ERR_FATAL;
5033
5034 return 0;
5035 }
5036
Willy Tarreau4348fad2012-09-20 16:48:07 +02005037 if (ssl_sock_load_cert(args[cur_arg + 1], conf, px, err) > 0)
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005038 return ERR_ALERT | ERR_FATAL;
Emeric Brund94b3fe2012-09-20 18:23:56 +02005039
5040 return 0;
5041}
5042
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01005043/* parse the "crt-list" bind keyword */
5044static int bind_parse_crt_list(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5045{
5046 if (!*args[cur_arg + 1]) {
5047 memprintf(err, "'%s' : missing certificate location", args[cur_arg]);
5048 return ERR_ALERT | ERR_FATAL;
5049 }
5050
Willy Tarreauad1731d2013-04-02 17:35:58 +02005051 if (ssl_sock_load_cert_list_file(args[cur_arg + 1], conf, px, err) > 0) {
5052 memprintf(err, "'%s' : %s", args[cur_arg], *err);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01005053 return ERR_ALERT | ERR_FATAL;
Willy Tarreauad1731d2013-04-02 17:35:58 +02005054 }
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01005055
5056 return 0;
5057}
5058
Emeric Brunfb510ea2012-10-05 12:00:26 +02005059/* parse the "crl-file" bind keyword */
5060static 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 +02005061{
Emeric Brun051cdab2012-10-02 19:25:50 +02005062#ifndef X509_V_FLAG_CRL_CHECK
5063 if (err)
5064 memprintf(err, "'%s' : library does not support CRL verify", args[cur_arg]);
5065 return ERR_ALERT | ERR_FATAL;
5066#else
Emeric Brund94b3fe2012-09-20 18:23:56 +02005067 if (!*args[cur_arg + 1]) {
5068 if (err)
5069 memprintf(err, "'%s' : missing CRLfile path", args[cur_arg]);
5070 return ERR_ALERT | ERR_FATAL;
5071 }
Emeric Brun2b58d042012-09-20 17:10:03 +02005072
Emeric Brunef42d922012-10-11 16:11:36 +02005073 if ((*args[cur_arg + 1] != '/') && global.ca_base)
5074 memprintf(&conf->crl_file, "%s/%s", global.ca_base, args[cur_arg + 1]);
5075 else
5076 memprintf(&conf->crl_file, "%s", args[cur_arg + 1]);
Emeric Brunc8e8d122012-10-02 18:42:10 +02005077
Emeric Brun2b58d042012-09-20 17:10:03 +02005078 return 0;
Emeric Brun051cdab2012-10-02 19:25:50 +02005079#endif
Emeric Brun2b58d042012-09-20 17:10:03 +02005080}
5081
5082/* parse the "ecdhe" bind keyword keywords */
5083static int bind_parse_ecdhe(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5084{
5085#if OPENSSL_VERSION_NUMBER < 0x0090800fL
5086 if (err)
5087 memprintf(err, "'%s' : library does not support elliptic curve Diffie-Hellman (too old)", args[cur_arg]);
5088 return ERR_ALERT | ERR_FATAL;
5089#elif defined(OPENSSL_NO_ECDH)
5090 if (err)
5091 memprintf(err, "'%s' : library does not support elliptic curve Diffie-Hellman (disabled via OPENSSL_NO_ECDH)", args[cur_arg]);
5092 return ERR_ALERT | ERR_FATAL;
5093#else
5094 if (!*args[cur_arg + 1]) {
5095 if (err)
5096 memprintf(err, "'%s' : missing named curve", args[cur_arg]);
5097 return ERR_ALERT | ERR_FATAL;
5098 }
5099
5100 conf->ecdhe = strdup(args[cur_arg + 1]);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005101
5102 return 0;
Emeric Brun2b58d042012-09-20 17:10:03 +02005103#endif
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005104}
5105
Emeric Brun81c00f02012-09-21 14:31:21 +02005106/* parse the "crt_ignerr" and "ca_ignerr" bind keywords */
5107static int bind_parse_ignore_err(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5108{
5109 int code;
5110 char *p = args[cur_arg + 1];
5111 unsigned long long *ignerr = &conf->crt_ignerr;
5112
5113 if (!*p) {
5114 if (err)
5115 memprintf(err, "'%s' : missing error IDs list", args[cur_arg]);
5116 return ERR_ALERT | ERR_FATAL;
5117 }
5118
5119 if (strcmp(args[cur_arg], "ca-ignore-err") == 0)
5120 ignerr = &conf->ca_ignerr;
5121
5122 if (strcmp(p, "all") == 0) {
5123 *ignerr = ~0ULL;
5124 return 0;
5125 }
5126
5127 while (p) {
5128 code = atoi(p);
5129 if ((code <= 0) || (code > 63)) {
5130 if (err)
5131 memprintf(err, "'%s' : ID '%d' out of range (1..63) in error IDs list '%s'",
5132 args[cur_arg], code, args[cur_arg + 1]);
5133 return ERR_ALERT | ERR_FATAL;
5134 }
5135 *ignerr |= 1ULL << code;
5136 p = strchr(p, ',');
5137 if (p)
5138 p++;
5139 }
5140
Emeric Brun2cb7ae52012-10-05 14:14:21 +02005141 return 0;
5142}
5143
5144/* parse the "force-sslv3" bind keyword */
5145static int bind_parse_force_sslv3(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5146{
5147 conf->ssl_options |= BC_SSL_O_USE_SSLV3;
5148 return 0;
5149}
5150
5151/* parse the "force-tlsv10" bind keyword */
5152static int bind_parse_force_tlsv10(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5153{
5154 conf->ssl_options |= BC_SSL_O_USE_TLSV10;
Emeric Brun2d0c4822012-10-02 13:45:20 +02005155 return 0;
5156}
5157
Emeric Brun2cb7ae52012-10-05 14:14:21 +02005158/* parse the "force-tlsv11" bind keyword */
5159static int bind_parse_force_tlsv11(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5160{
5161#if SSL_OP_NO_TLSv1_1
5162 conf->ssl_options |= BC_SSL_O_USE_TLSV11;
5163 return 0;
5164#else
5165 if (err)
5166 memprintf(err, "'%s' : library does not support protocol TLSv1.1", args[cur_arg]);
5167 return ERR_ALERT | ERR_FATAL;
5168#endif
5169}
5170
5171/* parse the "force-tlsv12" bind keyword */
5172static int bind_parse_force_tlsv12(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5173{
5174#if SSL_OP_NO_TLSv1_2
5175 conf->ssl_options |= BC_SSL_O_USE_TLSV12;
5176 return 0;
5177#else
5178 if (err)
5179 memprintf(err, "'%s' : library does not support protocol TLSv1.2", args[cur_arg]);
5180 return ERR_ALERT | ERR_FATAL;
5181#endif
5182}
5183
5184
Emeric Brun2d0c4822012-10-02 13:45:20 +02005185/* parse the "no-tls-tickets" bind keyword */
5186static int bind_parse_no_tls_tickets(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5187{
Emeric Brun89675492012-10-05 13:48:26 +02005188 conf->ssl_options |= BC_SSL_O_NO_TLS_TICKETS;
Emeric Brun81c00f02012-09-21 14:31:21 +02005189 return 0;
5190}
5191
Emeric Brun2d0c4822012-10-02 13:45:20 +02005192
Emeric Brun9b3009b2012-10-05 11:55:06 +02005193/* parse the "no-sslv3" bind keyword */
5194static 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 +02005195{
Emeric Brun89675492012-10-05 13:48:26 +02005196 conf->ssl_options |= BC_SSL_O_NO_SSLV3;
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005197 return 0;
5198}
5199
Emeric Brun9b3009b2012-10-05 11:55:06 +02005200/* parse the "no-tlsv10" bind keyword */
5201static 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 +02005202{
Emeric Brun89675492012-10-05 13:48:26 +02005203 conf->ssl_options |= BC_SSL_O_NO_TLSV10;
Emeric Brunc0ff4922012-09-28 19:37:02 +02005204 return 0;
5205}
5206
Emeric Brun9b3009b2012-10-05 11:55:06 +02005207/* parse the "no-tlsv11" bind keyword */
5208static 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 +02005209{
Emeric Brun89675492012-10-05 13:48:26 +02005210 conf->ssl_options |= BC_SSL_O_NO_TLSV11;
Emeric Brunc0ff4922012-09-28 19:37:02 +02005211 return 0;
5212}
5213
Emeric Brun9b3009b2012-10-05 11:55:06 +02005214/* parse the "no-tlsv12" bind keyword */
5215static 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 +02005216{
Emeric Brun89675492012-10-05 13:48:26 +02005217 conf->ssl_options |= BC_SSL_O_NO_TLSV12;
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005218 return 0;
5219}
5220
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02005221/* parse the "npn" bind keyword */
5222static int bind_parse_npn(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5223{
5224#ifdef OPENSSL_NPN_NEGOTIATED
5225 char *p1, *p2;
5226
5227 if (!*args[cur_arg + 1]) {
5228 memprintf(err, "'%s' : missing the comma-delimited NPN protocol suite", args[cur_arg]);
5229 return ERR_ALERT | ERR_FATAL;
5230 }
5231
5232 free(conf->npn_str);
5233
Willy Tarreau3724da12016-02-12 17:11:12 +01005234 /* the NPN string is built as a suite of (<len> <name>)*,
5235 * so we reuse each comma to store the next <len> and need
5236 * one more for the end of the string.
5237 */
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02005238 conf->npn_len = strlen(args[cur_arg + 1]) + 1;
Willy Tarreau3724da12016-02-12 17:11:12 +01005239 conf->npn_str = calloc(1, conf->npn_len + 1);
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02005240 memcpy(conf->npn_str + 1, args[cur_arg + 1], conf->npn_len);
5241
5242 /* replace commas with the name length */
5243 p1 = conf->npn_str;
5244 p2 = p1 + 1;
5245 while (1) {
5246 p2 = memchr(p1 + 1, ',', conf->npn_str + conf->npn_len - (p1 + 1));
5247 if (!p2)
5248 p2 = p1 + 1 + strlen(p1 + 1);
5249
5250 if (p2 - (p1 + 1) > 255) {
5251 *p2 = '\0';
5252 memprintf(err, "'%s' : NPN protocol name too long : '%s'", args[cur_arg], p1 + 1);
5253 return ERR_ALERT | ERR_FATAL;
5254 }
5255
5256 *p1 = p2 - (p1 + 1);
5257 p1 = p2;
5258
5259 if (!*p2)
5260 break;
5261
5262 *(p2++) = '\0';
5263 }
5264 return 0;
5265#else
5266 if (err)
5267 memprintf(err, "'%s' : library does not support TLS NPN extension", args[cur_arg]);
5268 return ERR_ALERT | ERR_FATAL;
5269#endif
5270}
5271
Willy Tarreauab861d32013-04-02 02:30:41 +02005272/* parse the "alpn" bind keyword */
5273static int bind_parse_alpn(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5274{
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01005275#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Willy Tarreauab861d32013-04-02 02:30:41 +02005276 char *p1, *p2;
5277
5278 if (!*args[cur_arg + 1]) {
5279 memprintf(err, "'%s' : missing the comma-delimited ALPN protocol suite", args[cur_arg]);
5280 return ERR_ALERT | ERR_FATAL;
5281 }
5282
5283 free(conf->alpn_str);
5284
Marcoen Hirschbergbef60912016-02-12 17:05:24 +01005285 /* the ALPN string is built as a suite of (<len> <name>)*,
5286 * so we reuse each comma to store the next <len> and need
5287 * one more for the end of the string.
5288 */
Willy Tarreauab861d32013-04-02 02:30:41 +02005289 conf->alpn_len = strlen(args[cur_arg + 1]) + 1;
Marcoen Hirschbergbef60912016-02-12 17:05:24 +01005290 conf->alpn_str = calloc(1, conf->alpn_len + 1);
Willy Tarreauab861d32013-04-02 02:30:41 +02005291 memcpy(conf->alpn_str + 1, args[cur_arg + 1], conf->alpn_len);
5292
5293 /* replace commas with the name length */
5294 p1 = conf->alpn_str;
5295 p2 = p1 + 1;
5296 while (1) {
5297 p2 = memchr(p1 + 1, ',', conf->alpn_str + conf->alpn_len - (p1 + 1));
5298 if (!p2)
5299 p2 = p1 + 1 + strlen(p1 + 1);
5300
5301 if (p2 - (p1 + 1) > 255) {
5302 *p2 = '\0';
5303 memprintf(err, "'%s' : ALPN protocol name too long : '%s'", args[cur_arg], p1 + 1);
5304 return ERR_ALERT | ERR_FATAL;
5305 }
5306
5307 *p1 = p2 - (p1 + 1);
5308 p1 = p2;
5309
5310 if (!*p2)
5311 break;
5312
5313 *(p2++) = '\0';
5314 }
5315 return 0;
5316#else
5317 if (err)
5318 memprintf(err, "'%s' : library does not support TLS ALPN extension", args[cur_arg]);
5319 return ERR_ALERT | ERR_FATAL;
5320#endif
5321}
5322
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005323/* parse the "ssl" bind keyword */
Willy Tarreau4348fad2012-09-20 16:48:07 +02005324static 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 +02005325{
Willy Tarreau81796be2012-09-22 19:11:47 +02005326 struct listener *l;
5327
Willy Tarreau4348fad2012-09-20 16:48:07 +02005328 conf->is_ssl = 1;
Emeric Brun76d88952012-10-05 15:47:31 +02005329
5330 if (global.listen_default_ciphers && !conf->ciphers)
5331 conf->ciphers = strdup(global.listen_default_ciphers);
Emeric Brun2c86cbf2014-10-30 15:56:50 +01005332 conf->ssl_options |= global.listen_default_ssloptions;
Emeric Brun76d88952012-10-05 15:47:31 +02005333
Willy Tarreau81796be2012-09-22 19:11:47 +02005334 list_for_each_entry(l, &conf->listeners, by_bind)
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02005335 l->xprt = &ssl_sock;
Willy Tarreau81796be2012-09-22 19:11:47 +02005336
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005337 return 0;
5338}
5339
Christopher Faulet31af49d2015-06-09 17:29:50 +02005340/* parse the "generate-certificates" bind keyword */
5341static int bind_parse_generate_certs(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5342{
5343#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
5344 conf->generate_certs = 1;
5345#else
5346 memprintf(err, "%sthis version of openssl cannot generate SSL certificates.\n",
5347 err && *err ? *err : "");
5348#endif
5349 return 0;
5350}
5351
Emmanuel Hocdet65623372013-01-24 17:17:15 +01005352/* parse the "strict-sni" bind keyword */
5353static int bind_parse_strict_sni(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5354{
5355 conf->strict_sni = 1;
5356 return 0;
Nenad Merdanovic05552d42015-02-27 19:56:49 +01005357}
5358
5359/* parse the "tls-ticket-keys" bind keyword */
5360static int bind_parse_tls_ticket_keys(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5361{
5362#if (defined SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB && TLS_TICKETS_NO > 0)
5363 FILE *f;
5364 int i = 0;
5365 char thisline[LINESIZE];
Nenad Merdanovic146defa2015-05-09 08:46:00 +02005366 struct tls_keys_ref *keys_ref;
Nenad Merdanovic05552d42015-02-27 19:56:49 +01005367
5368 if (!*args[cur_arg + 1]) {
5369 if (err)
5370 memprintf(err, "'%s' : missing TLS ticket keys file path", args[cur_arg]);
5371 return ERR_ALERT | ERR_FATAL;
5372 }
5373
Nenad Merdanovic200b0fa2015-05-09 08:46:01 +02005374 keys_ref = tlskeys_ref_lookup(args[cur_arg + 1]);
5375 if(keys_ref) {
5376 conf->keys_ref = keys_ref;
5377 return 0;
5378 }
5379
Vincent Bernat02779b62016-04-03 13:48:43 +02005380 keys_ref = malloc(sizeof(*keys_ref));
Nenad Merdanovic146defa2015-05-09 08:46:00 +02005381 keys_ref->tlskeys = malloc(TLS_TICKETS_NO * sizeof(struct tls_sess_key));
Nenad Merdanovic05552d42015-02-27 19:56:49 +01005382
5383 if ((f = fopen(args[cur_arg + 1], "r")) == NULL) {
5384 if (err)
5385 memprintf(err, "'%s' : unable to load ssl tickets keys file", args[cur_arg+1]);
5386 return ERR_ALERT | ERR_FATAL;
5387 }
5388
Nenad Merdanovic146defa2015-05-09 08:46:00 +02005389 keys_ref->filename = strdup(args[cur_arg + 1]);
5390
Nenad Merdanovic05552d42015-02-27 19:56:49 +01005391 while (fgets(thisline, sizeof(thisline), f) != NULL) {
5392 int len = strlen(thisline);
5393 /* Strip newline characters from the end */
5394 if(thisline[len - 1] == '\n')
5395 thisline[--len] = 0;
5396
5397 if(thisline[len - 1] == '\r')
5398 thisline[--len] = 0;
5399
Nenad Merdanovic146defa2015-05-09 08:46:00 +02005400 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 +01005401 if (err)
5402 memprintf(err, "'%s' : unable to decode base64 key on line %d", args[cur_arg+1], i + 1);
mildis16aa0152016-06-22 17:46:29 +02005403 fclose(f);
Nenad Merdanovic05552d42015-02-27 19:56:49 +01005404 return ERR_ALERT | ERR_FATAL;
5405 }
5406 i++;
5407 }
5408
5409 if (i < TLS_TICKETS_NO) {
5410 if (err)
5411 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 +02005412 fclose(f);
Nenad Merdanovic05552d42015-02-27 19:56:49 +01005413 return ERR_ALERT | ERR_FATAL;
5414 }
5415
5416 fclose(f);
5417
5418 /* Use penultimate key for encryption, handle when TLS_TICKETS_NO = 1 */
Nenad Merdanovic17891152016-03-25 22:16:57 +01005419 i -= 2;
5420 keys_ref->tls_ticket_enc_index = i < 0 ? 0 : i % TLS_TICKETS_NO;
Nenad Merdanovic200b0fa2015-05-09 08:46:01 +02005421 keys_ref->unique_id = -1;
Nenad Merdanovic146defa2015-05-09 08:46:00 +02005422 conf->keys_ref = keys_ref;
Nenad Merdanovic05552d42015-02-27 19:56:49 +01005423
Nenad Merdanovic200b0fa2015-05-09 08:46:01 +02005424 LIST_ADD(&tlskeys_reference, &keys_ref->list);
5425
Nenad Merdanovic05552d42015-02-27 19:56:49 +01005426 return 0;
5427#else
5428 if (err)
5429 memprintf(err, "'%s' : TLS ticket callback extension not supported", args[cur_arg]);
5430 return ERR_ALERT | ERR_FATAL;
5431#endif /* SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB */
Emmanuel Hocdet65623372013-01-24 17:17:15 +01005432}
5433
Emeric Brund94b3fe2012-09-20 18:23:56 +02005434/* parse the "verify" bind keyword */
5435static int bind_parse_verify(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5436{
5437 if (!*args[cur_arg + 1]) {
5438 if (err)
5439 memprintf(err, "'%s' : missing verify method", args[cur_arg]);
5440 return ERR_ALERT | ERR_FATAL;
5441 }
5442
5443 if (strcmp(args[cur_arg + 1], "none") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01005444 conf->verify = SSL_SOCK_VERIFY_NONE;
Emeric Brund94b3fe2012-09-20 18:23:56 +02005445 else if (strcmp(args[cur_arg + 1], "optional") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01005446 conf->verify = SSL_SOCK_VERIFY_OPTIONAL;
Emeric Brund94b3fe2012-09-20 18:23:56 +02005447 else if (strcmp(args[cur_arg + 1], "required") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01005448 conf->verify = SSL_SOCK_VERIFY_REQUIRED;
Emeric Brund94b3fe2012-09-20 18:23:56 +02005449 else {
5450 if (err)
5451 memprintf(err, "'%s' : unknown verify method '%s', only 'none', 'optional', and 'required' are supported\n",
5452 args[cur_arg], args[cur_arg + 1]);
5453 return ERR_ALERT | ERR_FATAL;
5454 }
5455
5456 return 0;
5457}
5458
Willy Tarreau92faadf2012-10-10 23:04:25 +02005459/************** "server" keywords ****************/
5460
Emeric Brunef42d922012-10-11 16:11:36 +02005461/* parse the "ca-file" server keyword */
5462static int srv_parse_ca_file(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5463{
5464 if (!*args[*cur_arg + 1]) {
5465 if (err)
5466 memprintf(err, "'%s' : missing CAfile path", args[*cur_arg]);
5467 return ERR_ALERT | ERR_FATAL;
5468 }
5469
5470 if ((*args[*cur_arg + 1] != '/') && global.ca_base)
5471 memprintf(&newsrv->ssl_ctx.ca_file, "%s/%s", global.ca_base, args[*cur_arg + 1]);
5472 else
5473 memprintf(&newsrv->ssl_ctx.ca_file, "%s", args[*cur_arg + 1]);
5474
5475 return 0;
5476}
5477
Willy Tarreau92faadf2012-10-10 23:04:25 +02005478/* parse the "check-ssl" server keyword */
5479static int srv_parse_check_ssl(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5480{
5481 newsrv->check.use_ssl = 1;
5482 if (global.connect_default_ciphers && !newsrv->ssl_ctx.ciphers)
5483 newsrv->ssl_ctx.ciphers = strdup(global.connect_default_ciphers);
Emeric Brun2c86cbf2014-10-30 15:56:50 +01005484 newsrv->ssl_ctx.options |= global.connect_default_ssloptions;
Willy Tarreau92faadf2012-10-10 23:04:25 +02005485 return 0;
5486}
5487
5488/* parse the "ciphers" server keyword */
5489static int srv_parse_ciphers(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5490{
5491 if (!*args[*cur_arg + 1]) {
5492 memprintf(err, "'%s' : missing cipher suite", args[*cur_arg]);
5493 return ERR_ALERT | ERR_FATAL;
5494 }
5495
5496 free(newsrv->ssl_ctx.ciphers);
5497 newsrv->ssl_ctx.ciphers = strdup(args[*cur_arg + 1]);
5498 return 0;
5499}
5500
Emeric Brunef42d922012-10-11 16:11:36 +02005501/* parse the "crl-file" server keyword */
5502static int srv_parse_crl_file(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5503{
5504#ifndef X509_V_FLAG_CRL_CHECK
5505 if (err)
5506 memprintf(err, "'%s' : library does not support CRL verify", args[*cur_arg]);
5507 return ERR_ALERT | ERR_FATAL;
5508#else
5509 if (!*args[*cur_arg + 1]) {
5510 if (err)
5511 memprintf(err, "'%s' : missing CRLfile path", args[*cur_arg]);
5512 return ERR_ALERT | ERR_FATAL;
5513 }
5514
5515 if ((*args[*cur_arg + 1] != '/') && global.ca_base)
5516 memprintf(&newsrv->ssl_ctx.crl_file, "%s/%s", global.ca_base, args[*cur_arg + 1]);
5517 else
5518 memprintf(&newsrv->ssl_ctx.crl_file, "%s", args[*cur_arg + 1]);
5519
5520 return 0;
5521#endif
5522}
5523
Emeric Bruna7aa3092012-10-26 12:58:00 +02005524/* parse the "crt" server keyword */
5525static int srv_parse_crt(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5526{
5527 if (!*args[*cur_arg + 1]) {
5528 if (err)
5529 memprintf(err, "'%s' : missing certificate file path", args[*cur_arg]);
5530 return ERR_ALERT | ERR_FATAL;
5531 }
5532
5533 if ((*args[*cur_arg + 1] != '/') && global.crt_base)
5534 memprintf(&newsrv->ssl_ctx.client_crt, "%s/%s", global.ca_base, args[*cur_arg + 1]);
5535 else
5536 memprintf(&newsrv->ssl_ctx.client_crt, "%s", args[*cur_arg + 1]);
5537
5538 return 0;
5539}
Emeric Brunef42d922012-10-11 16:11:36 +02005540
Willy Tarreau92faadf2012-10-10 23:04:25 +02005541/* parse the "force-sslv3" server keyword */
5542static int srv_parse_force_sslv3(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5543{
5544 newsrv->ssl_ctx.options |= SRV_SSL_O_USE_SSLV3;
5545 return 0;
5546}
5547
5548/* parse the "force-tlsv10" server keyword */
5549static int srv_parse_force_tlsv10(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5550{
5551 newsrv->ssl_ctx.options |= SRV_SSL_O_USE_TLSV10;
5552 return 0;
5553}
5554
5555/* parse the "force-tlsv11" server keyword */
5556static int srv_parse_force_tlsv11(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5557{
5558#if SSL_OP_NO_TLSv1_1
5559 newsrv->ssl_ctx.options |= SRV_SSL_O_USE_TLSV11;
5560 return 0;
5561#else
5562 if (err)
5563 memprintf(err, "'%s' : library does not support protocol TLSv1.1", args[*cur_arg]);
5564 return ERR_ALERT | ERR_FATAL;
5565#endif
5566}
5567
5568/* parse the "force-tlsv12" server keyword */
5569static int srv_parse_force_tlsv12(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5570{
5571#if SSL_OP_NO_TLSv1_2
5572 newsrv->ssl_ctx.options |= SRV_SSL_O_USE_TLSV12;
5573 return 0;
5574#else
5575 if (err)
5576 memprintf(err, "'%s' : library does not support protocol TLSv1.2", args[*cur_arg]);
5577 return ERR_ALERT | ERR_FATAL;
5578#endif
5579}
5580
Willy Tarreau2a3fb1c2015-02-05 16:47:07 +01005581/* parse the "no-ssl-reuse" server keyword */
5582static int srv_parse_no_ssl_reuse(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5583{
5584 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_REUSE;
5585 return 0;
5586}
5587
Willy Tarreau92faadf2012-10-10 23:04:25 +02005588/* parse the "no-sslv3" server keyword */
5589static int srv_parse_no_sslv3(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5590{
5591 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_SSLV3;
5592 return 0;
5593}
5594
5595/* parse the "no-tlsv10" server keyword */
5596static int srv_parse_no_tlsv10(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5597{
5598 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_TLSV10;
5599 return 0;
5600}
5601
5602/* parse the "no-tlsv11" server keyword */
5603static int srv_parse_no_tlsv11(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5604{
5605 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_TLSV11;
5606 return 0;
5607}
5608
5609/* parse the "no-tlsv12" server keyword */
5610static int srv_parse_no_tlsv12(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5611{
5612 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_TLSV12;
5613 return 0;
5614}
5615
Emeric Brunf9c5c472012-10-11 15:28:34 +02005616/* parse the "no-tls-tickets" server keyword */
5617static int srv_parse_no_tls_tickets(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5618{
5619 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_TLS_TICKETS;
5620 return 0;
5621}
David Safb76832014-05-08 23:42:08 -04005622/* parse the "send-proxy-v2-ssl" server keyword */
5623static int srv_parse_send_proxy_ssl(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5624{
5625 newsrv->pp_opts |= SRV_PP_V2;
5626 newsrv->pp_opts |= SRV_PP_V2_SSL;
5627 return 0;
5628}
5629
5630/* parse the "send-proxy-v2-ssl-cn" server keyword */
5631static int srv_parse_send_proxy_cn(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5632{
5633 newsrv->pp_opts |= SRV_PP_V2;
5634 newsrv->pp_opts |= SRV_PP_V2_SSL;
5635 newsrv->pp_opts |= SRV_PP_V2_SSL_CN;
5636 return 0;
5637}
Emeric Brunf9c5c472012-10-11 15:28:34 +02005638
Willy Tarreau732eac42015-07-09 11:40:25 +02005639/* parse the "sni" server keyword */
5640static int srv_parse_sni(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5641{
5642#ifndef SSL_CTRL_SET_TLSEXT_HOSTNAME
5643 memprintf(err, "'%s' : the current SSL library doesn't support the SNI TLS extension", args[*cur_arg]);
5644 return ERR_ALERT | ERR_FATAL;
5645#else
Cyril Bonté23d19d62016-03-07 22:13:22 +01005646 int idx;
Willy Tarreau732eac42015-07-09 11:40:25 +02005647 struct sample_expr *expr;
5648
5649 if (!*args[*cur_arg + 1]) {
5650 memprintf(err, "'%s' : missing sni expression", args[*cur_arg]);
5651 return ERR_ALERT | ERR_FATAL;
5652 }
5653
Cyril Bonté23d19d62016-03-07 22:13:22 +01005654 idx = (*cur_arg) + 1;
Willy Tarreau732eac42015-07-09 11:40:25 +02005655 proxy->conf.args.ctx = ARGC_SRV;
5656
Cyril Bonté23d19d62016-03-07 22:13:22 +01005657 expr = sample_parse_expr((char **)args, &idx, px->conf.file, px->conf.line, err, &proxy->conf.args);
Willy Tarreau732eac42015-07-09 11:40:25 +02005658 if (!expr) {
5659 memprintf(err, "error detected while parsing sni expression : %s", *err);
5660 return ERR_ALERT | ERR_FATAL;
5661 }
5662
5663 if (!(expr->fetch->val & SMP_VAL_BE_SRV_CON)) {
5664 memprintf(err, "error detected while parsing sni expression : "
5665 " fetch method '%s' extracts information from '%s', none of which is available here.\n",
Cyril Bonté23d19d62016-03-07 22:13:22 +01005666 args[idx-1], sample_src_names(expr->fetch->use));
Willy Tarreau732eac42015-07-09 11:40:25 +02005667 return ERR_ALERT | ERR_FATAL;
5668 }
5669
5670 px->http_needed |= !!(expr->fetch->use & SMP_USE_HTTP_ANY);
5671 newsrv->ssl_ctx.sni = expr;
5672 return 0;
5673#endif
5674}
5675
Willy Tarreau92faadf2012-10-10 23:04:25 +02005676/* parse the "ssl" server keyword */
5677static int srv_parse_ssl(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5678{
5679 newsrv->use_ssl = 1;
5680 if (global.connect_default_ciphers && !newsrv->ssl_ctx.ciphers)
5681 newsrv->ssl_ctx.ciphers = strdup(global.connect_default_ciphers);
5682 return 0;
5683}
5684
Emeric Brunef42d922012-10-11 16:11:36 +02005685/* parse the "verify" server keyword */
5686static int srv_parse_verify(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5687{
5688 if (!*args[*cur_arg + 1]) {
5689 if (err)
5690 memprintf(err, "'%s' : missing verify method", args[*cur_arg]);
5691 return ERR_ALERT | ERR_FATAL;
5692 }
5693
5694 if (strcmp(args[*cur_arg + 1], "none") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01005695 newsrv->ssl_ctx.verify = SSL_SOCK_VERIFY_NONE;
Emeric Brunef42d922012-10-11 16:11:36 +02005696 else if (strcmp(args[*cur_arg + 1], "required") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01005697 newsrv->ssl_ctx.verify = SSL_SOCK_VERIFY_REQUIRED;
Emeric Brunef42d922012-10-11 16:11:36 +02005698 else {
5699 if (err)
5700 memprintf(err, "'%s' : unknown verify method '%s', only 'none' and 'required' are supported\n",
5701 args[*cur_arg], args[*cur_arg + 1]);
5702 return ERR_ALERT | ERR_FATAL;
5703 }
5704
Evan Broderbe554312013-06-27 00:05:25 -07005705 return 0;
5706}
5707
5708/* parse the "verifyhost" server keyword */
5709static int srv_parse_verifyhost(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5710{
5711 if (!*args[*cur_arg + 1]) {
5712 if (err)
5713 memprintf(err, "'%s' : missing hostname to verify against", args[*cur_arg]);
5714 return ERR_ALERT | ERR_FATAL;
5715 }
5716
5717 newsrv->ssl_ctx.verify_host = strdup(args[*cur_arg + 1]);
5718
Emeric Brunef42d922012-10-11 16:11:36 +02005719 return 0;
5720}
5721
Emeric Brun2c86cbf2014-10-30 15:56:50 +01005722/* parse the "ssl-default-bind-options" keyword in global section */
5723static int ssl_parse_default_bind_options(char **args, int section_type, struct proxy *curpx,
5724 struct proxy *defpx, const char *file, int line,
5725 char **err) {
5726 int i = 1;
5727
5728 if (*(args[i]) == 0) {
5729 memprintf(err, "global statement '%s' expects an option as an argument.", args[0]);
5730 return -1;
5731 }
5732 while (*(args[i])) {
5733 if (!strcmp(args[i], "no-sslv3"))
5734 global.listen_default_ssloptions |= BC_SSL_O_NO_SSLV3;
5735 else if (!strcmp(args[i], "no-tlsv10"))
5736 global.listen_default_ssloptions |= BC_SSL_O_NO_TLSV10;
5737 else if (!strcmp(args[i], "no-tlsv11"))
5738 global.listen_default_ssloptions |= BC_SSL_O_NO_TLSV11;
5739 else if (!strcmp(args[i], "no-tlsv12"))
5740 global.listen_default_ssloptions |= BC_SSL_O_NO_TLSV12;
5741 else if (!strcmp(args[i], "force-sslv3"))
5742 global.listen_default_ssloptions |= BC_SSL_O_USE_SSLV3;
5743 else if (!strcmp(args[i], "force-tlsv10"))
5744 global.listen_default_ssloptions |= BC_SSL_O_USE_TLSV10;
5745 else if (!strcmp(args[i], "force-tlsv11")) {
5746#if SSL_OP_NO_TLSv1_1
5747 global.listen_default_ssloptions |= BC_SSL_O_USE_TLSV11;
5748#else
5749 memprintf(err, "'%s' '%s': library does not support protocol TLSv1.1", args[0], args[i]);
5750 return -1;
5751#endif
5752 }
5753 else if (!strcmp(args[i], "force-tlsv12")) {
5754#if SSL_OP_NO_TLSv1_2
5755 global.listen_default_ssloptions |= BC_SSL_O_USE_TLSV12;
5756#else
5757 memprintf(err, "'%s' '%s': library does not support protocol TLSv1.2", args[0], args[i]);
5758 return -1;
5759#endif
5760 }
5761 else if (!strcmp(args[i], "no-tls-tickets"))
5762 global.listen_default_ssloptions |= BC_SSL_O_NO_TLS_TICKETS;
5763 else {
5764 memprintf(err, "unknown option '%s' on global statement '%s'.", args[i], args[0]);
5765 return -1;
5766 }
5767 i++;
5768 }
5769 return 0;
5770}
5771
5772/* parse the "ssl-default-server-options" keyword in global section */
5773static int ssl_parse_default_server_options(char **args, int section_type, struct proxy *curpx,
5774 struct proxy *defpx, const char *file, int line,
5775 char **err) {
5776 int i = 1;
5777
5778 if (*(args[i]) == 0) {
5779 memprintf(err, "global statement '%s' expects an option as an argument.", args[0]);
5780 return -1;
5781 }
5782 while (*(args[i])) {
5783 if (!strcmp(args[i], "no-sslv3"))
5784 global.connect_default_ssloptions |= SRV_SSL_O_NO_SSLV3;
5785 else if (!strcmp(args[i], "no-tlsv10"))
5786 global.connect_default_ssloptions |= SRV_SSL_O_NO_TLSV10;
5787 else if (!strcmp(args[i], "no-tlsv11"))
5788 global.connect_default_ssloptions |= SRV_SSL_O_NO_TLSV11;
5789 else if (!strcmp(args[i], "no-tlsv12"))
5790 global.connect_default_ssloptions |= SRV_SSL_O_NO_TLSV12;
5791 else if (!strcmp(args[i], "force-sslv3"))
5792 global.connect_default_ssloptions |= SRV_SSL_O_USE_SSLV3;
5793 else if (!strcmp(args[i], "force-tlsv10"))
5794 global.connect_default_ssloptions |= SRV_SSL_O_USE_TLSV10;
5795 else if (!strcmp(args[i], "force-tlsv11")) {
5796#if SSL_OP_NO_TLSv1_1
5797 global.connect_default_ssloptions |= SRV_SSL_O_USE_TLSV11;
5798#else
5799 memprintf(err, "'%s' '%s': library does not support protocol TLSv1.1", args[0], args[i]);
5800 return -1;
5801#endif
5802 }
5803 else if (!strcmp(args[i], "force-tlsv12")) {
5804#if SSL_OP_NO_TLSv1_2
5805 global.connect_default_ssloptions |= SRV_SSL_O_USE_TLSV12;
5806#else
5807 memprintf(err, "'%s' '%s': library does not support protocol TLSv1.2", args[0], args[i]);
5808 return -1;
5809#endif
5810 }
5811 else if (!strcmp(args[i], "no-tls-tickets"))
5812 global.connect_default_ssloptions |= SRV_SSL_O_NO_TLS_TICKETS;
5813 else {
5814 memprintf(err, "unknown option '%s' on global statement '%s'.", args[i], args[0]);
5815 return -1;
5816 }
5817 i++;
5818 }
5819 return 0;
5820}
5821
Willy Tarreau7875d092012-09-10 08:20:03 +02005822/* Note: must not be declared <const> as its list will be overwritten.
5823 * Please take care of keeping this list alphabetically sorted.
5824 */
Willy Tarreaudc13c112013-06-21 23:16:39 +02005825static struct sample_fetch_kw_list sample_fetch_keywords = {ILH, {
Emeric Brun645ae792014-04-30 14:21:06 +02005826 { "ssl_bc", smp_fetch_ssl_fc, 0, NULL, SMP_T_BOOL, SMP_USE_L5SRV },
Thierry FOURNIER07ee64e2015-07-06 23:43:03 +02005827 { "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 +02005828 { "ssl_bc_cipher", smp_fetch_ssl_fc_cipher, 0, NULL, SMP_T_STR, SMP_USE_L5SRV },
5829 { "ssl_bc_protocol", smp_fetch_ssl_fc_protocol, 0, NULL, SMP_T_STR, SMP_USE_L5SRV },
Emeric Brunb73a9b02014-04-30 18:49:19 +02005830 { "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 +02005831 { "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 +02005832 { "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 +02005833 { "ssl_c_ca_err", smp_fetch_ssl_c_ca_err, 0, NULL, SMP_T_SINT, SMP_USE_L5CLI },
5834 { "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 +01005835 { "ssl_c_der", smp_fetch_ssl_x_der, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Thierry FOURNIER07ee64e2015-07-06 23:43:03 +02005836 { "ssl_c_err", smp_fetch_ssl_c_err, 0, NULL, SMP_T_SINT, SMP_USE_L5CLI },
Emeric Brunba841a12014-04-30 17:05:08 +02005837 { "ssl_c_i_dn", smp_fetch_ssl_x_i_dn, ARG2(0,STR,SINT), NULL, SMP_T_STR, SMP_USE_L5CLI },
5838 { "ssl_c_key_alg", smp_fetch_ssl_x_key_alg, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
5839 { "ssl_c_notafter", smp_fetch_ssl_x_notafter, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
5840 { "ssl_c_notbefore", smp_fetch_ssl_x_notbefore, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
5841 { "ssl_c_sig_alg", smp_fetch_ssl_x_sig_alg, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
5842 { "ssl_c_s_dn", smp_fetch_ssl_x_s_dn, ARG2(0,STR,SINT), NULL, SMP_T_STR, SMP_USE_L5CLI },
5843 { "ssl_c_serial", smp_fetch_ssl_x_serial, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
5844 { "ssl_c_sha1", smp_fetch_ssl_x_sha1, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Willy Tarreau80aca902013-01-07 15:42:20 +01005845 { "ssl_c_used", smp_fetch_ssl_c_used, 0, NULL, SMP_T_BOOL, SMP_USE_L5CLI },
Thierry FOURNIER07ee64e2015-07-06 23:43:03 +02005846 { "ssl_c_verify", smp_fetch_ssl_c_verify, 0, NULL, SMP_T_SINT, SMP_USE_L5CLI },
5847 { "ssl_c_version", smp_fetch_ssl_x_version, 0, NULL, SMP_T_SINT, SMP_USE_L5CLI },
Emeric Brun43e79582014-10-29 19:03:26 +01005848 { "ssl_f_der", smp_fetch_ssl_x_der, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Emeric Brunba841a12014-04-30 17:05:08 +02005849 { "ssl_f_i_dn", smp_fetch_ssl_x_i_dn, ARG2(0,STR,SINT), NULL, SMP_T_STR, SMP_USE_L5CLI },
5850 { "ssl_f_key_alg", smp_fetch_ssl_x_key_alg, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
5851 { "ssl_f_notafter", smp_fetch_ssl_x_notafter, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
5852 { "ssl_f_notbefore", smp_fetch_ssl_x_notbefore, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
5853 { "ssl_f_sig_alg", smp_fetch_ssl_x_sig_alg, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
5854 { "ssl_f_s_dn", smp_fetch_ssl_x_s_dn, ARG2(0,STR,SINT), NULL, SMP_T_STR, SMP_USE_L5CLI },
5855 { "ssl_f_serial", smp_fetch_ssl_x_serial, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Emeric Brun55f4fa82014-04-30 17:11:25 +02005856 { "ssl_f_sha1", smp_fetch_ssl_x_sha1, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Thierry FOURNIER07ee64e2015-07-06 23:43:03 +02005857 { "ssl_f_version", smp_fetch_ssl_x_version, 0, NULL, SMP_T_SINT, SMP_USE_L5CLI },
Willy Tarreau80aca902013-01-07 15:42:20 +01005858 { "ssl_fc", smp_fetch_ssl_fc, 0, NULL, SMP_T_BOOL, SMP_USE_L5CLI },
Thierry FOURNIER07ee64e2015-07-06 23:43:03 +02005859 { "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 +01005860 { "ssl_fc_cipher", smp_fetch_ssl_fc_cipher, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Willy Tarreau80aca902013-01-07 15:42:20 +01005861 { "ssl_fc_has_crt", smp_fetch_ssl_fc_has_crt, 0, NULL, SMP_T_BOOL, SMP_USE_L5CLI },
5862 { "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 +02005863 { "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 +02005864#ifdef OPENSSL_NPN_NEGOTIATED
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01005865 { "ssl_fc_npn", smp_fetch_ssl_fc_npn, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Willy Tarreaua33c6542012-10-15 13:19:06 +02005866#endif
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01005867#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01005868 { "ssl_fc_alpn", smp_fetch_ssl_fc_alpn, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Willy Tarreauab861d32013-04-02 02:30:41 +02005869#endif
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01005870 { "ssl_fc_protocol", smp_fetch_ssl_fc_protocol, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Emeric Brunb73a9b02014-04-30 18:49:19 +02005871 { "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 +02005872 { "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 +01005873 { "ssl_fc_session_id", smp_fetch_ssl_fc_session_id, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
5874 { "ssl_fc_sni", smp_fetch_ssl_fc_sni, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Willy Tarreau7875d092012-09-10 08:20:03 +02005875 { NULL, NULL, 0, 0, 0 },
5876}};
5877
5878/* Note: must not be declared <const> as its list will be overwritten.
5879 * Please take care of keeping this list alphabetically sorted.
5880 */
Willy Tarreaudc13c112013-06-21 23:16:39 +02005881static struct acl_kw_list acl_kws = {ILH, {
Thierry FOURNIERc5a4e982014-03-05 16:07:08 +01005882 { "ssl_fc_sni_end", "ssl_fc_sni", PAT_MATCH_END },
5883 { "ssl_fc_sni_reg", "ssl_fc_sni", PAT_MATCH_REG },
Willy Tarreau8ed669b2013-01-11 15:49:37 +01005884 { /* END */ },
Willy Tarreau7875d092012-09-10 08:20:03 +02005885}};
5886
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005887/* Note: must not be declared <const> as its list will be overwritten.
5888 * Please take care of keeping this list alphabetically sorted, doing so helps
5889 * all code contributors.
5890 * Optional keywords are also declared with a NULL ->parse() function so that
5891 * the config parser can report an appropriate error when a known keyword was
5892 * not enabled.
5893 */
Willy Tarreau51fb7652012-09-18 18:24:39 +02005894static struct bind_kw_list bind_kws = { "SSL", { }, {
Nenad Merdanovic05552d42015-02-27 19:56:49 +01005895 { "alpn", bind_parse_alpn, 1 }, /* set ALPN supported protocols */
5896 { "ca-file", bind_parse_ca_file, 1 }, /* set CAfile to process verify on client cert */
5897 { "ca-ignore-err", bind_parse_ignore_err, 1 }, /* set error IDs to ignore on verify depth > 0 */
Christopher Faulet31af49d2015-06-09 17:29:50 +02005898 { "ca-sign-file", bind_parse_ca_sign_file, 1 }, /* set CAFile used to generate and sign server certs */
5899 { "ca-sign-pass", bind_parse_ca_sign_pass, 1 }, /* set CAKey passphrase */
Nenad Merdanovic05552d42015-02-27 19:56:49 +01005900 { "ciphers", bind_parse_ciphers, 1 }, /* set SSL cipher suite */
5901 { "crl-file", bind_parse_crl_file, 1 }, /* set certificat revocation list file use on client cert verify */
5902 { "crt", bind_parse_crt, 1 }, /* load SSL certificates from this location */
5903 { "crt-ignore-err", bind_parse_ignore_err, 1 }, /* set error IDs to ingore on verify depth == 0 */
5904 { "crt-list", bind_parse_crt_list, 1 }, /* load a list of crt from this location */
5905 { "ecdhe", bind_parse_ecdhe, 1 }, /* defines named curve for elliptic curve Diffie-Hellman */
5906 { "force-sslv3", bind_parse_force_sslv3, 0 }, /* force SSLv3 */
5907 { "force-tlsv10", bind_parse_force_tlsv10, 0 }, /* force TLSv10 */
5908 { "force-tlsv11", bind_parse_force_tlsv11, 0 }, /* force TLSv11 */
5909 { "force-tlsv12", bind_parse_force_tlsv12, 0 }, /* force TLSv12 */
Christopher Faulet31af49d2015-06-09 17:29:50 +02005910 { "generate-certificates", bind_parse_generate_certs, 0 }, /* enable the server certificates generation */
Nenad Merdanovic05552d42015-02-27 19:56:49 +01005911 { "no-sslv3", bind_parse_no_sslv3, 0 }, /* disable SSLv3 */
5912 { "no-tlsv10", bind_parse_no_tlsv10, 0 }, /* disable TLSv10 */
5913 { "no-tlsv11", bind_parse_no_tlsv11, 0 }, /* disable TLSv11 */
5914 { "no-tlsv12", bind_parse_no_tlsv12, 0 }, /* disable TLSv12 */
5915 { "no-tls-tickets", bind_parse_no_tls_tickets, 0 }, /* disable session resumption tickets */
5916 { "ssl", bind_parse_ssl, 0 }, /* enable SSL processing */
5917 { "strict-sni", bind_parse_strict_sni, 0 }, /* refuse negotiation if sni doesn't match a certificate */
5918 { "tls-ticket-keys", bind_parse_tls_ticket_keys, 1 }, /* set file to load TLS ticket keys from */
5919 { "verify", bind_parse_verify, 1 }, /* set SSL verify method */
5920 { "npn", bind_parse_npn, 1 }, /* set NPN supported protocols */
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005921 { NULL, NULL, 0 },
5922}};
Emeric Brun46591952012-05-18 15:47:34 +02005923
Willy Tarreau92faadf2012-10-10 23:04:25 +02005924/* Note: must not be declared <const> as its list will be overwritten.
5925 * Please take care of keeping this list alphabetically sorted, doing so helps
5926 * all code contributors.
5927 * Optional keywords are also declared with a NULL ->parse() function so that
5928 * the config parser can report an appropriate error when a known keyword was
5929 * not enabled.
5930 */
5931static struct srv_kw_list srv_kws = { "SSL", { }, {
Emeric Brunef42d922012-10-11 16:11:36 +02005932 { "ca-file", srv_parse_ca_file, 1, 0 }, /* set CAfile to process verify server cert */
Emeric Brunecc91fe2012-10-11 15:05:10 +02005933 { "check-ssl", srv_parse_check_ssl, 0, 0 }, /* enable SSL for health checks */
5934 { "ciphers", srv_parse_ciphers, 1, 0 }, /* select the cipher suite */
Emeric Brunef42d922012-10-11 16:11:36 +02005935 { "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 +02005936 { "crt", srv_parse_crt, 1, 0 }, /* set client certificate */
Emeric Brunecc91fe2012-10-11 15:05:10 +02005937 { "force-sslv3", srv_parse_force_sslv3, 0, 0 }, /* force SSLv3 */
5938 { "force-tlsv10", srv_parse_force_tlsv10, 0, 0 }, /* force TLSv10 */
5939 { "force-tlsv11", srv_parse_force_tlsv11, 0, 0 }, /* force TLSv11 */
5940 { "force-tlsv12", srv_parse_force_tlsv12, 0, 0 }, /* force TLSv12 */
Willy Tarreau2a3fb1c2015-02-05 16:47:07 +01005941 { "no-ssl-reuse", srv_parse_no_ssl_reuse, 0, 0 }, /* disable session reuse */
Emeric Brunecc91fe2012-10-11 15:05:10 +02005942 { "no-sslv3", srv_parse_no_sslv3, 0, 0 }, /* disable SSLv3 */
5943 { "no-tlsv10", srv_parse_no_tlsv10, 0, 0 }, /* disable TLSv10 */
5944 { "no-tlsv11", srv_parse_no_tlsv11, 0, 0 }, /* disable TLSv11 */
5945 { "no-tlsv12", srv_parse_no_tlsv12, 0, 0 }, /* disable TLSv12 */
Emeric Brunf9c5c472012-10-11 15:28:34 +02005946 { "no-tls-tickets", srv_parse_no_tls_tickets, 0, 0 }, /* disable session resumption tickets */
David Safb76832014-05-08 23:42:08 -04005947 { "send-proxy-v2-ssl", srv_parse_send_proxy_ssl, 0, 0 }, /* send PROXY protocol header v2 with SSL info */
5948 { "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 +02005949 { "sni", srv_parse_sni, 1, 0 }, /* send SNI extension */
Emeric Brunecc91fe2012-10-11 15:05:10 +02005950 { "ssl", srv_parse_ssl, 0, 0 }, /* enable SSL processing */
Emeric Brunef42d922012-10-11 16:11:36 +02005951 { "verify", srv_parse_verify, 1, 0 }, /* set SSL verify method */
Evan Broderbe554312013-06-27 00:05:25 -07005952 { "verifyhost", srv_parse_verifyhost, 1, 0 }, /* require that SSL cert verifies for hostname */
Willy Tarreau92faadf2012-10-10 23:04:25 +02005953 { NULL, NULL, 0, 0 },
5954}};
5955
Emeric Brun2c86cbf2014-10-30 15:56:50 +01005956static struct cfg_kw_list cfg_kws = {ILH, {
5957 { CFG_GLOBAL, "ssl-default-bind-options", ssl_parse_default_bind_options },
5958 { CFG_GLOBAL, "ssl-default-server-options", ssl_parse_default_server_options },
5959 { 0, NULL, NULL },
5960}};
5961
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02005962/* transport-layer operations for SSL sockets */
5963struct xprt_ops ssl_sock = {
Emeric Brun46591952012-05-18 15:47:34 +02005964 .snd_buf = ssl_sock_from_buf,
5965 .rcv_buf = ssl_sock_to_buf,
5966 .rcv_pipe = NULL,
5967 .snd_pipe = NULL,
5968 .shutr = NULL,
5969 .shutw = ssl_sock_shutw,
5970 .close = ssl_sock_close,
5971 .init = ssl_sock_init,
5972};
5973
Daniel Jakots54ffb912015-11-06 20:02:41 +01005974#if (OPENSSL_VERSION_NUMBER >= 0x1000200fL && !defined OPENSSL_NO_TLSEXT && !defined OPENSSL_IS_BORINGSSL && !defined LIBRESSL_VERSION_NUMBER)
Janusz Dziemidowicz2c701b52015-03-07 23:03:59 +01005975
5976static void ssl_sock_sctl_free_func(void *parent, void *ptr, CRYPTO_EX_DATA *ad, int idx, long argl, void *argp)
5977{
5978 if (ptr) {
5979 chunk_destroy(ptr);
5980 free(ptr);
5981 }
5982}
5983
5984#endif
5985
Emeric Brun46591952012-05-18 15:47:34 +02005986__attribute__((constructor))
Willy Tarreau92faadf2012-10-10 23:04:25 +02005987static void __ssl_sock_init(void)
5988{
Emeric Brun46591952012-05-18 15:47:34 +02005989 STACK_OF(SSL_COMP)* cm;
5990
Willy Tarreau610f04b2014-02-13 11:36:41 +01005991#ifdef LISTEN_DEFAULT_CIPHERS
5992 global.listen_default_ciphers = LISTEN_DEFAULT_CIPHERS;
5993#endif
5994#ifdef CONNECT_DEFAULT_CIPHERS
5995 global.connect_default_ciphers = CONNECT_DEFAULT_CIPHERS;
5996#endif
5997 if (global.listen_default_ciphers)
5998 global.listen_default_ciphers = strdup(global.listen_default_ciphers);
5999 if (global.connect_default_ciphers)
6000 global.connect_default_ciphers = strdup(global.connect_default_ciphers);
Emeric Brun2c86cbf2014-10-30 15:56:50 +01006001 global.listen_default_ssloptions = BC_SSL_O_NONE;
6002 global.connect_default_ssloptions = SRV_SSL_O_NONE;
Willy Tarreau610f04b2014-02-13 11:36:41 +01006003
Emeric Brun46591952012-05-18 15:47:34 +02006004 SSL_library_init();
6005 cm = SSL_COMP_get_compression_methods();
6006 sk_SSL_COMP_zero(cm);
Daniel Jakots54ffb912015-11-06 20:02:41 +01006007#if (OPENSSL_VERSION_NUMBER >= 0x1000200fL && !defined OPENSSL_NO_TLSEXT && !defined OPENSSL_IS_BORINGSSL && !defined LIBRESSL_VERSION_NUMBER)
Janusz Dziemidowicz2c701b52015-03-07 23:03:59 +01006008 sctl_ex_index = SSL_CTX_get_ex_new_index(0, NULL, NULL, NULL, ssl_sock_sctl_free_func);
6009#endif
Willy Tarreau7875d092012-09-10 08:20:03 +02006010 sample_register_fetches(&sample_fetch_keywords);
6011 acl_register_keywords(&acl_kws);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02006012 bind_register_keywords(&bind_kws);
Willy Tarreau92faadf2012-10-10 23:04:25 +02006013 srv_register_keywords(&srv_kws);
Emeric Brun2c86cbf2014-10-30 15:56:50 +01006014 cfg_register_keywords(&cfg_kws);
Willy Tarreaud92aa5c2015-01-15 21:34:39 +01006015
6016 global.ssl_session_max_cost = SSL_SESSION_MAX_COST;
6017 global.ssl_handshake_max_cost = SSL_HANDSHAKE_MAX_COST;
Remi Gacogne4f902b82015-05-28 16:23:00 +02006018
6019#ifndef OPENSSL_NO_DH
6020 ssl_dh_ptr_index = SSL_CTX_get_ex_new_index(0, NULL, NULL, NULL, NULL);
6021#endif
Emeric Brun46591952012-05-18 15:47:34 +02006022}
6023
Remi Gacogned3a23c32015-05-28 16:39:47 +02006024__attribute__((destructor))
6025static void __ssl_sock_deinit(void)
6026{
Willy Tarreaua84c2672015-10-09 12:10:13 +02006027#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Christopher Faulet31af49d2015-06-09 17:29:50 +02006028 lru64_destroy(ssl_ctx_lru_tree);
Willy Tarreaua84c2672015-10-09 12:10:13 +02006029#endif
Christopher Faulet31af49d2015-06-09 17:29:50 +02006030
Remi Gacogned3a23c32015-05-28 16:39:47 +02006031#ifndef OPENSSL_NO_DH
6032 if (local_dh_1024) {
6033 DH_free(local_dh_1024);
6034 local_dh_1024 = NULL;
6035 }
6036
6037 if (local_dh_2048) {
6038 DH_free(local_dh_2048);
6039 local_dh_2048 = NULL;
6040 }
6041
6042 if (local_dh_4096) {
6043 DH_free(local_dh_4096);
6044 local_dh_4096 = NULL;
6045 }
6046
Remi Gacogne47783ef2015-05-29 15:53:22 +02006047 if (global_dh) {
6048 DH_free(global_dh);
6049 global_dh = NULL;
6050 }
Remi Gacogned3a23c32015-05-28 16:39:47 +02006051#endif
6052
6053 ERR_remove_state(0);
6054 ERR_free_strings();
6055
6056 EVP_cleanup();
6057
6058#if OPENSSL_VERSION_NUMBER >= 0x00907000L
6059 CRYPTO_cleanup_all_ex_data();
6060#endif
6061}
6062
6063
Emeric Brun46591952012-05-18 15:47:34 +02006064/*
6065 * Local variables:
6066 * c-indent-level: 8
6067 * c-basic-offset: 8
6068 * End:
6069 */