blob: 5200069f10a716923602cebd186c19e7690980c5 [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
477 conn = (struct connection *)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
618 ocsp_arg = (struct ocsp_cbk_arg *)arg;
619
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
745 ocsp = calloc(1, sizeof(struct certificate_ocsp));
746 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) {
757 struct ocsp_cbk_arg *cb_arg = calloc(1, sizeof(struct ocsp_cbk_arg));
758
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 */
770 struct ocsp_cbk_arg *cb_arg = (struct ocsp_cbk_arg *) ctx->tlsext_status_arg;
771 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
900 *sctl = calloc(1, sizeof(struct chunk));
901 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{
916 struct chunk *sctl = (struct chunk *)add_arg;
917
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{
961 struct connection *conn = (struct connection *)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());
999 conn = (struct connection *)SSL_get_app_data(ssl);
1000
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)) {
Willy Tarreau84815002014-04-25 21:40:27 +02001045 struct connection *conn = (struct connection *)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 *
1121ssl_sock_do_create_cert(const char *servername, unsigned int serial,
1122 struct bind_conf *bind_conf, SSL *ssl)
Christopher Faulet31af49d2015-06-09 17:29:50 +02001123{
Christopher Faulet7969a332015-10-09 11:15:03 +02001124 X509 *cacert = bind_conf->ca_sign_cert;
1125 EVP_PKEY *capkey = bind_conf->ca_sign_pkey;
Christopher Faulet31af49d2015-06-09 17:29:50 +02001126 SSL_CTX *ssl_ctx = NULL;
1127 X509 *newcrt = NULL;
1128 EVP_PKEY *pkey = NULL;
Christopher Faulet31af49d2015-06-09 17:29:50 +02001129 X509_NAME *name;
1130 const EVP_MD *digest;
1131 X509V3_CTX ctx;
1132 unsigned int i;
1133
Christopher Faulet7969a332015-10-09 11:15:03 +02001134 /* Get the private key of the defautl certificate and use it */
1135 if (!(pkey = SSL_get_privatekey(ssl)))
Christopher Faulet31af49d2015-06-09 17:29:50 +02001136 goto mkcert_error;
1137
1138 /* Create the certificate */
1139 if (!(newcrt = X509_new()))
1140 goto mkcert_error;
1141
1142 /* Set version number for the certificate (X509v3) and the serial
1143 * number */
1144 if (X509_set_version(newcrt, 2L) != 1)
1145 goto mkcert_error;
1146 ASN1_INTEGER_set(X509_get_serialNumber(newcrt), serial);
1147
1148 /* Set duration for the certificate */
1149 if (!X509_gmtime_adj(X509_get_notBefore(newcrt), (long)-60*60*24) ||
1150 !X509_gmtime_adj(X509_get_notAfter(newcrt),(long)60*60*24*365))
1151 goto mkcert_error;
1152
1153 /* set public key in the certificate */
1154 if (X509_set_pubkey(newcrt, pkey) != 1)
1155 goto mkcert_error;
1156
1157 /* Set issuer name from the CA */
1158 if (!(name = X509_get_subject_name(cacert)))
1159 goto mkcert_error;
1160 if (X509_set_issuer_name(newcrt, name) != 1)
1161 goto mkcert_error;
1162
1163 /* Set the subject name using the same, but the CN */
1164 name = X509_NAME_dup(name);
1165 if (X509_NAME_add_entry_by_txt(name, "CN", MBSTRING_ASC,
1166 (const unsigned char *)servername,
1167 -1, -1, 0) != 1) {
1168 X509_NAME_free(name);
1169 goto mkcert_error;
1170 }
1171 if (X509_set_subject_name(newcrt, name) != 1) {
1172 X509_NAME_free(name);
1173 goto mkcert_error;
1174 }
1175 X509_NAME_free(name);
1176
1177 /* Add x509v3 extensions as specified */
1178 X509V3_set_ctx(&ctx, cacert, newcrt, NULL, NULL, 0);
1179 for (i = 0; i < X509V3_EXT_SIZE; i++) {
1180 X509_EXTENSION *ext;
1181
1182 if (!(ext = X509V3_EXT_conf(NULL, &ctx, x509v3_ext_names[i], x509v3_ext_values[i])))
1183 goto mkcert_error;
1184 if (!X509_add_ext(newcrt, ext, -1)) {
1185 X509_EXTENSION_free(ext);
1186 goto mkcert_error;
1187 }
1188 X509_EXTENSION_free(ext);
1189 }
1190
1191 /* Sign the certificate with the CA private key */
1192 if (EVP_PKEY_type(capkey->type) == EVP_PKEY_DSA)
1193 digest = EVP_dss1();
1194 else if (EVP_PKEY_type (capkey->type) == EVP_PKEY_RSA)
1195 digest = EVP_sha256();
Christopher Faulet7969a332015-10-09 11:15:03 +02001196 else if (EVP_PKEY_type (capkey->type) == EVP_PKEY_EC)
1197 digest = EVP_sha256();
1198 else {
Christopher Faulete7db2162015-10-19 13:59:24 +02001199#if (OPENSSL_VERSION_NUMBER >= 0x1000000fL)
Christopher Faulet7969a332015-10-09 11:15:03 +02001200 int nid;
1201
1202 if (EVP_PKEY_get_default_digest_nid(capkey, &nid) <= 0)
1203 goto mkcert_error;
1204 if (!(digest = EVP_get_digestbynid(nid)))
1205 goto mkcert_error;
Christopher Faulete7db2162015-10-19 13:59:24 +02001206#else
1207 goto mkcert_error;
1208#endif
Christopher Faulet7969a332015-10-09 11:15:03 +02001209 }
1210
Christopher Faulet31af49d2015-06-09 17:29:50 +02001211 if (!(X509_sign(newcrt, capkey, digest)))
1212 goto mkcert_error;
1213
1214 /* Create and set the new SSL_CTX */
1215 if (!(ssl_ctx = SSL_CTX_new(SSLv23_server_method())))
1216 goto mkcert_error;
1217 if (!SSL_CTX_use_PrivateKey(ssl_ctx, pkey))
1218 goto mkcert_error;
1219 if (!SSL_CTX_use_certificate(ssl_ctx, newcrt))
1220 goto mkcert_error;
1221 if (!SSL_CTX_check_private_key(ssl_ctx))
1222 goto mkcert_error;
1223
1224 if (newcrt) X509_free(newcrt);
Christopher Faulet7969a332015-10-09 11:15:03 +02001225
Christopher Faulet85b5a1a2015-10-09 11:46:32 +02001226 SSL_CTX_set_tmp_dh_callback(ssl_ctx, ssl_get_tmp_dh);
1227#if defined(SSL_CTX_set_tmp_ecdh) && !defined(OPENSSL_NO_ECDH)
1228 {
1229 const char *ecdhe = (bind_conf->ecdhe ? bind_conf->ecdhe : ECDHE_DEFAULT_CURVE);
1230 EC_KEY *ecc;
1231 int nid;
1232
1233 if ((nid = OBJ_sn2nid(ecdhe)) == NID_undef)
1234 goto end;
1235 if (!(ecc = EC_KEY_new_by_curve_name(nid)))
1236 goto end;
1237 SSL_CTX_set_tmp_ecdh(ssl_ctx, ecc);
1238 EC_KEY_free(ecc);
1239 }
1240#endif
1241 end:
Christopher Faulet31af49d2015-06-09 17:29:50 +02001242 return ssl_ctx;
1243
1244 mkcert_error:
1245 if (ssl_ctx) SSL_CTX_free(ssl_ctx);
1246 if (newcrt) X509_free(newcrt);
Christopher Faulet31af49d2015-06-09 17:29:50 +02001247 return NULL;
1248}
1249
Christopher Faulet7969a332015-10-09 11:15:03 +02001250SSL_CTX *
1251ssl_sock_create_cert(struct connection *conn, const char *servername, unsigned int serial)
1252{
1253 struct bind_conf *bind_conf = objt_listener(conn->target)->bind_conf;
1254 return ssl_sock_do_create_cert(servername, serial, bind_conf, conn->xprt_ctx);
1255}
1256
Christopher Faulet30548802015-06-11 13:39:32 +02001257/* Do a lookup for a certificate in the LRU cache used to store generated
1258 * certificates. */
1259SSL_CTX *
Christopher Faulet7969a332015-10-09 11:15:03 +02001260ssl_sock_get_generated_cert(unsigned int serial, struct bind_conf *bind_conf)
Christopher Faulet30548802015-06-11 13:39:32 +02001261{
1262 struct lru64 *lru = NULL;
1263
1264 if (ssl_ctx_lru_tree) {
Christopher Faulet7969a332015-10-09 11:15:03 +02001265 lru = lru64_lookup(serial, ssl_ctx_lru_tree, bind_conf->ca_sign_cert, 0);
Christopher Faulet30548802015-06-11 13:39:32 +02001266 if (lru && lru->domain)
1267 return (SSL_CTX *)lru->data;
1268 }
1269 return NULL;
1270}
1271
Christopher Fauletd2cab922015-07-28 16:03:47 +02001272/* Set a certificate int the LRU cache used to store generated
1273 * certificate. Return 0 on success, otherwise -1 */
1274int
Christopher Faulet7969a332015-10-09 11:15:03 +02001275ssl_sock_set_generated_cert(SSL_CTX *ssl_ctx, unsigned int serial, struct bind_conf *bind_conf)
Christopher Faulet30548802015-06-11 13:39:32 +02001276{
1277 struct lru64 *lru = NULL;
1278
1279 if (ssl_ctx_lru_tree) {
Christopher Faulet7969a332015-10-09 11:15:03 +02001280 lru = lru64_get(serial, ssl_ctx_lru_tree, bind_conf->ca_sign_cert, 0);
Christopher Faulet30548802015-06-11 13:39:32 +02001281 if (!lru)
Christopher Fauletd2cab922015-07-28 16:03:47 +02001282 return -1;
Christopher Faulet30548802015-06-11 13:39:32 +02001283 if (lru->domain && lru->data)
1284 lru->free((SSL_CTX *)lru->data);
Christopher Faulet7969a332015-10-09 11:15:03 +02001285 lru64_commit(lru, ssl_ctx, bind_conf->ca_sign_cert, 0, (void (*)(void *))SSL_CTX_free);
Christopher Fauletd2cab922015-07-28 16:03:47 +02001286 return 0;
Christopher Faulet30548802015-06-11 13:39:32 +02001287 }
Christopher Fauletd2cab922015-07-28 16:03:47 +02001288 return -1;
Christopher Faulet30548802015-06-11 13:39:32 +02001289}
1290
1291/* Compute the serial that will be used to create/set/get a certificate. */
1292unsigned int
Willy Tarreau646b8642015-07-07 18:09:15 +02001293ssl_sock_generated_cert_serial(const void *data, size_t len)
Christopher Faulet30548802015-06-11 13:39:32 +02001294{
1295 return XXH32(data, len, ssl_ctx_lru_seed);
1296}
1297
Willy Tarreau2f63ef42015-10-20 15:16:01 +02001298/* Generate a cert and immediately assign it to the SSL session so that the cert's
1299 * refcount is maintained regardless of the cert's presence in the LRU cache.
1300 */
Christopher Faulet31af49d2015-06-09 17:29:50 +02001301static SSL_CTX *
Christopher Faulet7969a332015-10-09 11:15:03 +02001302ssl_sock_generate_certificate(const char *servername, struct bind_conf *bind_conf, SSL *ssl)
Christopher Faulet31af49d2015-06-09 17:29:50 +02001303{
1304 X509 *cacert = bind_conf->ca_sign_cert;
Christopher Faulet31af49d2015-06-09 17:29:50 +02001305 SSL_CTX *ssl_ctx = NULL;
1306 struct lru64 *lru = NULL;
1307 unsigned int serial;
1308
Willy Tarreaufc017fe2015-07-07 18:09:34 +02001309 serial = ssl_sock_generated_cert_serial(servername, strlen(servername));
Christopher Faulet31af49d2015-06-09 17:29:50 +02001310 if (ssl_ctx_lru_tree) {
1311 lru = lru64_get(serial, ssl_ctx_lru_tree, cacert, 0);
1312 if (lru && lru->domain)
1313 ssl_ctx = (SSL_CTX *)lru->data;
Christopher Fauletd2cab922015-07-28 16:03:47 +02001314 if (!ssl_ctx && lru) {
Christopher Faulet7969a332015-10-09 11:15:03 +02001315 ssl_ctx = ssl_sock_do_create_cert(servername, serial, bind_conf, ssl);
Christopher Faulet31af49d2015-06-09 17:29:50 +02001316 lru64_commit(lru, ssl_ctx, cacert, 0, (void (*)(void *))SSL_CTX_free);
Christopher Fauletd2cab922015-07-28 16:03:47 +02001317 }
Willy Tarreau2f63ef42015-10-20 15:16:01 +02001318 SSL_set_SSL_CTX(ssl, ssl_ctx);
Christopher Faulet31af49d2015-06-09 17:29:50 +02001319 }
Willy Tarreau2f63ef42015-10-20 15:16:01 +02001320 else {
Christopher Faulet7969a332015-10-09 11:15:03 +02001321 ssl_ctx = ssl_sock_do_create_cert(servername, serial, bind_conf, ssl);
Willy Tarreau2f63ef42015-10-20 15:16:01 +02001322 SSL_set_SSL_CTX(ssl, ssl_ctx);
1323 /* No LRU cache, this CTX will be released as soon as the session dies */
1324 SSL_CTX_free(ssl_ctx);
1325 }
Christopher Faulet31af49d2015-06-09 17:29:50 +02001326 return ssl_ctx;
1327}
1328
Emeric Brunfc0421f2012-09-07 17:30:07 +02001329/* Sets the SSL ctx of <ssl> to match the advertised server name. Returns a
1330 * warning when no match is found, which implies the default (first) cert
1331 * will keep being used.
1332 */
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001333static int ssl_sock_switchctx_cbk(SSL *ssl, int *al, struct bind_conf *s)
Emeric Brunfc0421f2012-09-07 17:30:07 +02001334{
1335 const char *servername;
1336 const char *wildp = NULL;
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001337 struct ebmb_node *node, *n;
Emeric Brunfc0421f2012-09-07 17:30:07 +02001338 int i;
1339 (void)al; /* shut gcc stupid warning */
1340
1341 servername = SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name);
Emmanuel Hocdet65623372013-01-24 17:17:15 +01001342 if (!servername) {
Willy Tarreauf6721452015-07-07 18:04:38 +02001343 if (s->generate_certs) {
1344 struct connection *conn = (struct connection *)SSL_get_app_data(ssl);
1345 unsigned int serial;
1346 SSL_CTX *ctx;
Christopher Faulet30548802015-06-11 13:39:32 +02001347
Willy Tarreauf6721452015-07-07 18:04:38 +02001348 conn_get_to_addr(conn);
1349 if (conn->flags & CO_FL_ADDR_TO_SET) {
1350 serial = ssl_sock_generated_cert_serial(&conn->addr.to, get_addr_len(&conn->addr.to));
Christopher Faulet7969a332015-10-09 11:15:03 +02001351 ctx = ssl_sock_get_generated_cert(serial, s);
Willy Tarreauf6721452015-07-07 18:04:38 +02001352 if (ctx) {
1353 /* switch ctx */
1354 SSL_set_SSL_CTX(ssl, ctx);
1355 return SSL_TLSEXT_ERR_OK;
1356 }
Christopher Faulet30548802015-06-11 13:39:32 +02001357 }
1358 }
1359
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001360 return (s->strict_sni ?
1361 SSL_TLSEXT_ERR_ALERT_FATAL :
Emmanuel Hocdet79274e22013-05-31 12:47:44 +02001362 SSL_TLSEXT_ERR_NOACK);
Emmanuel Hocdet65623372013-01-24 17:17:15 +01001363 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02001364
Willy Tarreau19d14ef2012-10-29 16:51:55 +01001365 for (i = 0; i < trash.size; i++) {
Emeric Brunfc0421f2012-09-07 17:30:07 +02001366 if (!servername[i])
1367 break;
Willy Tarreau19d14ef2012-10-29 16:51:55 +01001368 trash.str[i] = tolower(servername[i]);
1369 if (!wildp && (trash.str[i] == '.'))
1370 wildp = &trash.str[i];
Emeric Brunfc0421f2012-09-07 17:30:07 +02001371 }
Willy Tarreau19d14ef2012-10-29 16:51:55 +01001372 trash.str[i] = 0;
Emeric Brunfc0421f2012-09-07 17:30:07 +02001373
1374 /* lookup in full qualified names */
Willy Tarreau19d14ef2012-10-29 16:51:55 +01001375 node = ebst_lookup(&s->sni_ctx, trash.str);
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001376
1377 /* lookup a not neg filter */
1378 for (n = node; n; n = ebmb_next_dup(n)) {
1379 if (!container_of(n, struct sni_ctx, name)->neg) {
1380 node = n;
1381 break;
Emmanuel Hocdet65623372013-01-24 17:17:15 +01001382 }
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001383 }
1384 if (!node && wildp) {
1385 /* lookup in wildcards names */
Emeric Brunfc0421f2012-09-07 17:30:07 +02001386 node = ebst_lookup(&s->sni_w_ctx, wildp);
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001387 }
1388 if (!node || container_of(node, struct sni_ctx, name)->neg) {
Christopher Faulet31af49d2015-06-09 17:29:50 +02001389 SSL_CTX *ctx;
Christopher Faulet31af49d2015-06-09 17:29:50 +02001390 if (s->generate_certs &&
Christopher Faulet7969a332015-10-09 11:15:03 +02001391 (ctx = ssl_sock_generate_certificate(servername, s, ssl))) {
Christopher Faulet31af49d2015-06-09 17:29:50 +02001392 /* switch ctx */
Christopher Faulet31af49d2015-06-09 17:29:50 +02001393 return SSL_TLSEXT_ERR_OK;
1394 }
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001395 return (s->strict_sni ?
1396 SSL_TLSEXT_ERR_ALERT_FATAL :
1397 SSL_TLSEXT_ERR_ALERT_WARNING);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001398 }
1399
1400 /* switch ctx */
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001401 SSL_set_SSL_CTX(ssl, container_of(node, struct sni_ctx, name)->ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001402 return SSL_TLSEXT_ERR_OK;
1403}
1404#endif /* SSL_CTRL_SET_TLSEXT_HOSTNAME */
1405
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001406#ifndef OPENSSL_NO_DH
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001407
1408static DH * ssl_get_dh_1024(void)
1409{
Remi Gacogned3a341a2015-05-29 16:26:17 +02001410 static unsigned char dh1024_p[]={
1411 0xFA,0xF9,0x2A,0x22,0x2A,0xA7,0x7F,0xE1,0x67,0x4E,0x53,0xF7,
1412 0x56,0x13,0xC3,0xB1,0xE3,0x29,0x6B,0x66,0x31,0x6A,0x7F,0xB3,
1413 0xC2,0x68,0x6B,0xCB,0x1D,0x57,0x39,0x1D,0x1F,0xFF,0x1C,0xC9,
1414 0xA6,0xA4,0x98,0x82,0x31,0x5D,0x25,0xFF,0x8A,0xE0,0x73,0x96,
1415 0x81,0xC8,0x83,0x79,0xC1,0x5A,0x04,0xF8,0x37,0x0D,0xA8,0x3D,
1416 0xAE,0x74,0xBC,0xDB,0xB6,0xA4,0x75,0xD9,0x71,0x8A,0xA0,0x17,
1417 0x9E,0x2D,0xC8,0xA8,0xDF,0x2C,0x5F,0x82,0x95,0xF8,0x92,0x9B,
1418 0xA7,0x33,0x5F,0x89,0x71,0xC8,0x2D,0x6B,0x18,0x86,0xC4,0x94,
1419 0x22,0xA5,0x52,0x8D,0xF6,0xF6,0xD2,0x37,0x92,0x0F,0xA5,0xCC,
1420 0xDB,0x7B,0x1D,0x3D,0xA1,0x31,0xB7,0x80,0x8F,0x0B,0x67,0x5E,
1421 0x36,0xA5,0x60,0x0C,0xF1,0x95,0x33,0x8B,
1422 };
1423 static unsigned char dh1024_g[]={
1424 0x02,
1425 };
1426
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001427 DH *dh = DH_new();
1428 if (dh) {
Remi Gacogned3a341a2015-05-29 16:26:17 +02001429 dh->p = BN_bin2bn(dh1024_p, sizeof dh1024_p, NULL);
1430 dh->g = BN_bin2bn(dh1024_g, sizeof dh1024_g, NULL);
1431
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001432 if (!dh->p || !dh->g) {
1433 DH_free(dh);
1434 dh = NULL;
1435 }
1436 }
1437 return dh;
1438}
1439
1440static DH *ssl_get_dh_2048(void)
1441{
Remi Gacogned3a341a2015-05-29 16:26:17 +02001442 static unsigned char dh2048_p[]={
1443 0xEC,0x86,0xF8,0x70,0xA0,0x33,0x16,0xEC,0x05,0x1A,0x73,0x59,
1444 0xCD,0x1F,0x8B,0xF8,0x29,0xE4,0xD2,0xCF,0x52,0xDD,0xC2,0x24,
1445 0x8D,0xB5,0x38,0x9A,0xFB,0x5C,0xA4,0xE4,0xB2,0xDA,0xCE,0x66,
1446 0x50,0x74,0xA6,0x85,0x4D,0x4B,0x1D,0x30,0xB8,0x2B,0xF3,0x10,
1447 0xE9,0xA7,0x2D,0x05,0x71,0xE7,0x81,0xDF,0x8B,0x59,0x52,0x3B,
1448 0x5F,0x43,0x0B,0x68,0xF1,0xDB,0x07,0xBE,0x08,0x6B,0x1B,0x23,
1449 0xEE,0x4D,0xCC,0x9E,0x0E,0x43,0xA0,0x1E,0xDF,0x43,0x8C,0xEC,
1450 0xBE,0xBE,0x90,0xB4,0x51,0x54,0xB9,0x2F,0x7B,0x64,0x76,0x4E,
1451 0x5D,0xD4,0x2E,0xAE,0xC2,0x9E,0xAE,0x51,0x43,0x59,0xC7,0x77,
1452 0x9C,0x50,0x3C,0x0E,0xED,0x73,0x04,0x5F,0xF1,0x4C,0x76,0x2A,
1453 0xD8,0xF8,0xCF,0xFC,0x34,0x40,0xD1,0xB4,0x42,0x61,0x84,0x66,
1454 0x42,0x39,0x04,0xF8,0x68,0xB2,0x62,0xD7,0x55,0xED,0x1B,0x74,
1455 0x75,0x91,0xE0,0xC5,0x69,0xC1,0x31,0x5C,0xDB,0x7B,0x44,0x2E,
1456 0xCE,0x84,0x58,0x0D,0x1E,0x66,0x0C,0xC8,0x44,0x9E,0xFD,0x40,
1457 0x08,0x67,0x5D,0xFB,0xA7,0x76,0x8F,0x00,0x11,0x87,0xE9,0x93,
1458 0xF9,0x7D,0xC4,0xBC,0x74,0x55,0x20,0xD4,0x4A,0x41,0x2F,0x43,
1459 0x42,0x1A,0xC1,0xF2,0x97,0x17,0x49,0x27,0x37,0x6B,0x2F,0x88,
1460 0x7E,0x1C,0xA0,0xA1,0x89,0x92,0x27,0xD9,0x56,0x5A,0x71,0xC1,
1461 0x56,0x37,0x7E,0x3A,0x9D,0x05,0xE7,0xEE,0x5D,0x8F,0x82,0x17,
1462 0xBC,0xE9,0xC2,0x93,0x30,0x82,0xF9,0xF4,0xC9,0xAE,0x49,0xDB,
1463 0xD0,0x54,0xB4,0xD9,0x75,0x4D,0xFA,0x06,0xB8,0xD6,0x38,0x41,
1464 0xB7,0x1F,0x77,0xF3,
1465 };
1466 static unsigned char dh2048_g[]={
1467 0x02,
1468 };
1469
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001470 DH *dh = DH_new();
1471 if (dh) {
Remi Gacogned3a341a2015-05-29 16:26:17 +02001472 dh->p = BN_bin2bn(dh2048_p, sizeof dh2048_p, NULL);
1473 dh->g = BN_bin2bn(dh2048_g, sizeof dh2048_g, NULL);
1474
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001475 if (!dh->p || !dh->g) {
1476 DH_free(dh);
1477 dh = NULL;
1478 }
1479 }
1480 return dh;
1481}
1482
1483static DH *ssl_get_dh_4096(void)
1484{
Remi Gacogned3a341a2015-05-29 16:26:17 +02001485 static unsigned char dh4096_p[]={
1486 0xDE,0x16,0x94,0xCD,0x99,0x58,0x07,0xF1,0xF7,0x32,0x96,0x11,
1487 0x04,0x82,0xD4,0x84,0x72,0x80,0x99,0x06,0xCA,0xF0,0xA3,0x68,
1488 0x07,0xCE,0x64,0x50,0xE7,0x74,0x45,0x20,0x80,0x5E,0x4D,0xAD,
1489 0xA5,0xB6,0xED,0xFA,0x80,0x6C,0x3B,0x35,0xC4,0x9A,0x14,0x6B,
1490 0x32,0xBB,0xFD,0x1F,0x17,0x8E,0xB7,0x1F,0xD6,0xFA,0x3F,0x7B,
1491 0xEE,0x16,0xA5,0x62,0x33,0x0D,0xED,0xBC,0x4E,0x58,0xE5,0x47,
1492 0x4D,0xE9,0xAB,0x8E,0x38,0xD3,0x6E,0x90,0x57,0xE3,0x22,0x15,
1493 0x33,0xBD,0xF6,0x43,0x45,0xB5,0x10,0x0A,0xBE,0x2C,0xB4,0x35,
1494 0xB8,0x53,0x8D,0xAD,0xFB,0xA7,0x1F,0x85,0x58,0x41,0x7A,0x79,
1495 0x20,0x68,0xB3,0xE1,0x3D,0x08,0x76,0xBF,0x86,0x0D,0x49,0xE3,
1496 0x82,0x71,0x8C,0xB4,0x8D,0x81,0x84,0xD4,0xE7,0xBE,0x91,0xDC,
1497 0x26,0x39,0x48,0x0F,0x35,0xC4,0xCA,0x65,0xE3,0x40,0x93,0x52,
1498 0x76,0x58,0x7D,0xDD,0x51,0x75,0xDC,0x69,0x61,0xBF,0x47,0x2C,
1499 0x16,0x68,0x2D,0xC9,0x29,0xD3,0xE6,0xC0,0x99,0x48,0xA0,0x9A,
1500 0xC8,0x78,0xC0,0x6D,0x81,0x67,0x12,0x61,0x3F,0x71,0xBA,0x41,
1501 0x1F,0x6C,0x89,0x44,0x03,0xBA,0x3B,0x39,0x60,0xAA,0x28,0x55,
1502 0x59,0xAE,0xB8,0xFA,0xCB,0x6F,0xA5,0x1A,0xF7,0x2B,0xDD,0x52,
1503 0x8A,0x8B,0xE2,0x71,0xA6,0x5E,0x7E,0xD8,0x2E,0x18,0xE0,0x66,
1504 0xDF,0xDD,0x22,0x21,0x99,0x52,0x73,0xA6,0x33,0x20,0x65,0x0E,
1505 0x53,0xE7,0x6B,0x9B,0xC5,0xA3,0x2F,0x97,0x65,0x76,0xD3,0x47,
1506 0x23,0x77,0x12,0xB6,0x11,0x7B,0x24,0xED,0xF1,0xEF,0xC0,0xE2,
1507 0xA3,0x7E,0x67,0x05,0x3E,0x96,0x4D,0x45,0xC2,0x18,0xD1,0x73,
1508 0x9E,0x07,0xF3,0x81,0x6E,0x52,0x63,0xF6,0x20,0x76,0xB9,0x13,
1509 0xD2,0x65,0x30,0x18,0x16,0x09,0x16,0x9E,0x8F,0xF1,0xD2,0x10,
1510 0x5A,0xD3,0xD4,0xAF,0x16,0x61,0xDA,0x55,0x2E,0x18,0x5E,0x14,
1511 0x08,0x54,0x2E,0x2A,0x25,0xA2,0x1A,0x9B,0x8B,0x32,0xA9,0xFD,
1512 0xC2,0x48,0x96,0xE1,0x80,0xCA,0xE9,0x22,0x17,0xBB,0xCE,0x3E,
1513 0x9E,0xED,0xC7,0xF1,0x1F,0xEC,0x17,0x21,0xDC,0x7B,0x82,0x48,
1514 0x8E,0xBB,0x4B,0x9D,0x5B,0x04,0x04,0xDA,0xDB,0x39,0xDF,0x01,
1515 0x40,0xC3,0xAA,0x26,0x23,0x89,0x75,0xC6,0x0B,0xD0,0xA2,0x60,
1516 0x6A,0xF1,0xCC,0x65,0x18,0x98,0x1B,0x52,0xD2,0x74,0x61,0xCC,
1517 0xBD,0x60,0xAE,0xA3,0xA0,0x66,0x6A,0x16,0x34,0x92,0x3F,0x41,
1518 0x40,0x31,0x29,0xC0,0x2C,0x63,0xB2,0x07,0x8D,0xEB,0x94,0xB8,
1519 0xE8,0x47,0x92,0x52,0x93,0x6A,0x1B,0x7E,0x1A,0x61,0xB3,0x1B,
1520 0xF0,0xD6,0x72,0x9B,0xF1,0xB0,0xAF,0xBF,0x3E,0x65,0xEF,0x23,
1521 0x1D,0x6F,0xFF,0x70,0xCD,0x8A,0x4C,0x8A,0xA0,0x72,0x9D,0xBE,
1522 0xD4,0xBB,0x24,0x47,0x4A,0x68,0xB5,0xF5,0xC6,0xD5,0x7A,0xCD,
1523 0xCA,0x06,0x41,0x07,0xAD,0xC2,0x1E,0xE6,0x54,0xA7,0xAD,0x03,
1524 0xD9,0x12,0xC1,0x9C,0x13,0xB1,0xC9,0x0A,0x43,0x8E,0x1E,0x08,
1525 0xCE,0x50,0x82,0x73,0x5F,0xA7,0x55,0x1D,0xD9,0x59,0xAC,0xB5,
1526 0xEA,0x02,0x7F,0x6C,0x5B,0x74,0x96,0x98,0x67,0x24,0xA3,0x0F,
1527 0x15,0xFC,0xA9,0x7D,0x3E,0x67,0xD1,0x70,0xF8,0x97,0xF3,0x67,
1528 0xC5,0x8C,0x88,0x44,0x08,0x02,0xC7,0x2B,
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001529 };
Remi Gacogned3a341a2015-05-29 16:26:17 +02001530 static unsigned char dh4096_g[]={
1531 0x02,
1532 };
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001533
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001534 DH *dh = DH_new();
1535 if (dh) {
Remi Gacogned3a341a2015-05-29 16:26:17 +02001536 dh->p = BN_bin2bn(dh4096_p, sizeof dh4096_p, NULL);
1537 dh->g = BN_bin2bn(dh4096_g, sizeof dh4096_g, NULL);
1538
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001539 if (!dh->p || !dh->g) {
1540 DH_free(dh);
1541 dh = NULL;
1542 }
1543 }
1544 return dh;
1545}
1546
1547/* Returns Diffie-Hellman parameters matching the private key length
1548 but not exceeding global.tune.ssl_default_dh_param */
1549static DH *ssl_get_tmp_dh(SSL *ssl, int export, int keylen)
1550{
1551 DH *dh = NULL;
1552 EVP_PKEY *pkey = SSL_get_privatekey(ssl);
1553 int type = pkey ? EVP_PKEY_type(pkey->type) : EVP_PKEY_NONE;
1554
1555 /* The keylen supplied by OpenSSL can only be 512 or 1024.
1556 See ssl3_send_server_key_exchange() in ssl/s3_srvr.c
1557 */
1558 if (type == EVP_PKEY_RSA || type == EVP_PKEY_DSA) {
1559 keylen = EVP_PKEY_bits(pkey);
1560 }
1561
1562 if (keylen > global.tune.ssl_default_dh_param) {
1563 keylen = global.tune.ssl_default_dh_param;
1564 }
1565
Remi Gacogned3a341a2015-05-29 16:26:17 +02001566 if (keylen >= 4096) {
Remi Gacogne8de54152014-07-15 11:36:40 +02001567 dh = local_dh_4096;
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001568 }
1569 else if (keylen >= 2048) {
Remi Gacogne8de54152014-07-15 11:36:40 +02001570 dh = local_dh_2048;
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001571 }
1572 else {
Remi Gacogne8de54152014-07-15 11:36:40 +02001573 dh = local_dh_1024;
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001574 }
1575
1576 return dh;
1577}
1578
Remi Gacogne47783ef2015-05-29 15:53:22 +02001579static DH * ssl_sock_get_dh_from_file(const char *filename)
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001580{
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001581 DH *dh = NULL;
Remi Gacogne47783ef2015-05-29 15:53:22 +02001582 BIO *in = BIO_new(BIO_s_file());
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001583
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001584 if (in == NULL)
1585 goto end;
1586
Remi Gacogne47783ef2015-05-29 15:53:22 +02001587 if (BIO_read_filename(in, filename) <= 0)
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001588 goto end;
1589
Remi Gacogne47783ef2015-05-29 15:53:22 +02001590 dh = PEM_read_bio_DHparams(in, NULL, NULL, NULL);
1591
1592end:
1593 if (in)
1594 BIO_free(in);
1595
1596 return dh;
1597}
1598
1599int ssl_sock_load_global_dh_param_from_file(const char *filename)
1600{
1601 global_dh = ssl_sock_get_dh_from_file(filename);
1602
1603 if (global_dh) {
1604 return 0;
1605 }
1606
1607 return -1;
1608}
1609
1610/* Loads Diffie-Hellman parameter from a file. Returns 1 if loaded, else -1
1611 if an error occured, and 0 if parameter not found. */
1612int ssl_sock_load_dh_params(SSL_CTX *ctx, const char *file)
1613{
1614 int ret = -1;
1615 DH *dh = ssl_sock_get_dh_from_file(file);
1616
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001617 if (dh) {
1618 ret = 1;
1619 SSL_CTX_set_tmp_dh(ctx, dh);
Remi Gacogne4f902b82015-05-28 16:23:00 +02001620
1621 if (ssl_dh_ptr_index >= 0) {
1622 /* store a pointer to the DH params to avoid complaining about
1623 ssl-default-dh-param not being set for this SSL_CTX */
1624 SSL_CTX_set_ex_data(ctx, ssl_dh_ptr_index, dh);
1625 }
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001626 }
Remi Gacogne47783ef2015-05-29 15:53:22 +02001627 else if (global_dh) {
1628 SSL_CTX_set_tmp_dh(ctx, global_dh);
1629 ret = 0; /* DH params not found */
1630 }
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001631 else {
Emeric Brun41fdb3c2013-04-26 11:05:44 +02001632 /* Clear openssl global errors stack */
1633 ERR_clear_error();
1634
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001635 if (global.tune.ssl_default_dh_param <= 1024) {
1636 /* we are limited to DH parameter of 1024 bits anyway */
Remi Gacogne8de54152014-07-15 11:36:40 +02001637 local_dh_1024 = ssl_get_dh_1024();
1638 if (local_dh_1024 == NULL)
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001639 goto end;
Willy Tarreau6e774b42014-04-25 21:35:23 +02001640
Remi Gacogne8de54152014-07-15 11:36:40 +02001641 SSL_CTX_set_tmp_dh(ctx, local_dh_1024);
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001642 }
1643 else {
1644 SSL_CTX_set_tmp_dh_callback(ctx, ssl_get_tmp_dh);
1645 }
Willy Tarreau6e774b42014-04-25 21:35:23 +02001646
Emeric Brun41fdb3c2013-04-26 11:05:44 +02001647 ret = 0; /* DH params not found */
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001648 }
Emeric Brun644cde02012-12-14 11:21:13 +01001649
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001650end:
1651 if (dh)
1652 DH_free(dh);
1653
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001654 return ret;
1655}
1656#endif
1657
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001658static int ssl_sock_add_cert_sni(SSL_CTX *ctx, struct bind_conf *s, char *name, int order)
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001659{
1660 struct sni_ctx *sc;
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001661 int wild = 0, neg = 0;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001662
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001663 if (*name == '!') {
1664 neg = 1;
1665 name++;
1666 }
1667 if (*name == '*') {
1668 wild = 1;
1669 name++;
1670 }
1671 /* !* filter is a nop */
1672 if (neg && wild)
1673 return order;
1674 if (*name) {
1675 int j, len;
1676 len = strlen(name);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001677 sc = malloc(sizeof(struct sni_ctx) + len + 1);
1678 for (j = 0; j < len; j++)
1679 sc->name.key[j] = tolower(name[j]);
1680 sc->name.key[len] = 0;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001681 sc->ctx = ctx;
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001682 sc->order = order++;
1683 sc->neg = neg;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001684 if (wild)
1685 ebst_insert(&s->sni_w_ctx, &sc->name);
1686 else
1687 ebst_insert(&s->sni_ctx, &sc->name);
1688 }
1689 return order;
1690}
1691
yanbzhu488a4d22015-12-01 15:16:07 -05001692
1693/* The following code is used for loading multiple crt files into
1694 * SSL_CTX's based on CN/SAN
1695 */
1696#if OPENSSL_VERSION_NUMBER >= 0x1000200fL
1697/* This is used to preload the certifcate, private key
1698 * and Cert Chain of a file passed in via the crt
1699 * argument
1700 *
1701 * This way, we do not have to read the file multiple times
1702 */
1703struct cert_key_and_chain {
1704 X509 *cert;
1705 EVP_PKEY *key;
1706 unsigned int num_chain_certs;
1707 /* This is an array of X509 pointers */
1708 X509 **chain_certs;
1709};
1710
yanbzhu08ce6ab2015-12-02 13:01:29 -05001711#define SSL_SOCK_POSSIBLE_KT_COMBOS (1<<(SSL_SOCK_NUM_KEYTYPES))
1712
1713struct key_combo_ctx {
1714 SSL_CTX *ctx;
1715 int order;
1716};
1717
1718/* Map used for processing multiple keypairs for a single purpose
1719 *
1720 * This maps CN/SNI name to certificate type
1721 */
1722struct sni_keytype {
1723 int keytypes; /* BITMASK for keytypes */
1724 struct ebmb_node name; /* node holding the servername value */
1725};
1726
1727
yanbzhu488a4d22015-12-01 15:16:07 -05001728/* Frees the contents of a cert_key_and_chain
1729 */
1730static void ssl_sock_free_cert_key_and_chain_contents(struct cert_key_and_chain *ckch)
1731{
1732 int i;
1733
1734 if (!ckch)
1735 return;
1736
1737 /* Free the certificate and set pointer to NULL */
1738 if (ckch->cert)
1739 X509_free(ckch->cert);
1740 ckch->cert = NULL;
1741
1742 /* Free the key and set pointer to NULL */
1743 if (ckch->key)
1744 EVP_PKEY_free(ckch->key);
1745 ckch->key = NULL;
1746
1747 /* Free each certificate in the chain */
1748 for (i = 0; i < ckch->num_chain_certs; i++) {
1749 if (ckch->chain_certs[i])
1750 X509_free(ckch->chain_certs[i]);
1751 }
1752
1753 /* Free the chain obj itself and set to NULL */
1754 if (ckch->num_chain_certs > 0) {
1755 free(ckch->chain_certs);
1756 ckch->num_chain_certs = 0;
1757 ckch->chain_certs = NULL;
1758 }
1759
1760}
1761
1762/* checks if a key and cert exists in the ckch
1763 */
1764static int ssl_sock_is_ckch_valid(struct cert_key_and_chain *ckch)
1765{
1766 return (ckch->cert != NULL && ckch->key != NULL);
1767}
1768
1769
1770/* Loads the contents of a crt file (path) into a cert_key_and_chain
1771 * This allows us to carry the contents of the file without having to
1772 * read the file multiple times.
1773 *
1774 * returns:
1775 * 0 on Success
1776 * 1 on SSL Failure
1777 * 2 on file not found
1778 */
1779static int ssl_sock_load_crt_file_into_ckch(const char *path, struct cert_key_and_chain *ckch, char **err)
1780{
1781
1782 BIO *in;
1783 X509 *ca = NULL;
1784 int ret = 1;
1785
1786 ssl_sock_free_cert_key_and_chain_contents(ckch);
1787
1788 in = BIO_new(BIO_s_file());
1789 if (in == NULL)
1790 goto end;
1791
1792 if (BIO_read_filename(in, path) <= 0)
1793 goto end;
1794
1795 /* Read Certificate */
1796 ckch->cert = PEM_read_bio_X509_AUX(in, NULL, NULL, NULL);
1797 if (ckch->cert == NULL) {
1798 memprintf(err, "%sunable to load certificate from file '%s'.\n",
1799 err && *err ? *err : "", path);
1800 goto end;
1801 }
1802
1803 /* Read Private Key */
1804 ckch->key = PEM_read_bio_PrivateKey(in, NULL, NULL, NULL);
1805 if (ckch->key == NULL) {
1806 memprintf(err, "%sunable to load private key from file '%s'.\n",
1807 err && *err ? *err : "", path);
1808 goto end;
1809 }
1810
1811 /* Read Certificate Chain */
1812 while ((ca = PEM_read_bio_X509(in, NULL, NULL, NULL))) {
1813 /* Grow the chain certs */
1814 ckch->num_chain_certs++;
1815 ckch->chain_certs = realloc(ckch->chain_certs, (ckch->num_chain_certs * sizeof(X509 *)));
1816
1817 /* use - 1 here since we just incremented it above */
1818 ckch->chain_certs[ckch->num_chain_certs - 1] = ca;
1819 }
1820 ret = ERR_get_error();
1821 if (ret && (ERR_GET_LIB(ret) != ERR_LIB_PEM && ERR_GET_REASON(ret) != PEM_R_NO_START_LINE)) {
1822 memprintf(err, "%sunable to load certificate chain from file '%s'.\n",
1823 err && *err ? *err : "", path);
1824 ret = 1;
1825 goto end;
1826 }
1827
1828 ret = 0;
1829
1830end:
1831
1832 ERR_clear_error();
1833 if (in)
1834 BIO_free(in);
1835
1836 /* Something went wrong in one of the reads */
1837 if (ret != 0)
1838 ssl_sock_free_cert_key_and_chain_contents(ckch);
1839
1840 return ret;
1841}
1842
1843/* Loads the info in ckch into ctx
1844 * Currently, this does not process any information about ocsp, dhparams or
1845 * sctl
1846 * Returns
1847 * 0 on success
1848 * 1 on failure
1849 */
1850static int ssl_sock_put_ckch_into_ctx(const char *path, const struct cert_key_and_chain *ckch, SSL_CTX *ctx, char **err)
1851{
1852 int i = 0;
1853
1854 if (SSL_CTX_use_PrivateKey(ctx, ckch->key) <= 0) {
1855 memprintf(err, "%sunable to load SSL private key into SSL Context '%s'.\n",
1856 err && *err ? *err : "", path);
1857 return 1;
1858 }
1859
1860 if (!SSL_CTX_use_certificate(ctx, ckch->cert)) {
1861 memprintf(err, "%sunable to load SSL certificate into SSL Context '%s'.\n",
1862 err && *err ? *err : "", path);
1863 return 1;
1864 }
1865
yanbzhu488a4d22015-12-01 15:16:07 -05001866 /* Load all certs in the ckch into the ctx_chain for the ssl_ctx */
1867 for (i = 0; i < ckch->num_chain_certs; i++) {
1868 if (!SSL_CTX_add1_chain_cert(ctx, ckch->chain_certs[i])) {
yanbzhu08ce6ab2015-12-02 13:01:29 -05001869 memprintf(err, "%sunable to load chain certificate #%d into SSL Context '%s'. Make sure you are linking against Openssl >= 1.0.2.\n",
1870 err && *err ? *err : "", (i+1), path);
yanbzhu488a4d22015-12-01 15:16:07 -05001871 return 1;
1872 }
1873 }
1874
1875 if (SSL_CTX_check_private_key(ctx) <= 0) {
1876 memprintf(err, "%sinconsistencies between private key and certificate loaded from PEM file '%s'.\n",
1877 err && *err ? *err : "", path);
1878 return 1;
1879 }
1880
1881 return 0;
1882}
1883
yanbzhu08ce6ab2015-12-02 13:01:29 -05001884
1885static void ssl_sock_populate_sni_keytypes_hplr(const char *str, struct eb_root *sni_keytypes, int key_index)
1886{
1887 struct sni_keytype *s_kt = NULL;
1888 struct ebmb_node *node;
1889 int i;
1890
1891 for (i = 0; i < trash.size; i++) {
1892 if (!str[i])
1893 break;
1894 trash.str[i] = tolower(str[i]);
1895 }
1896 trash.str[i] = 0;
1897 node = ebst_lookup(sni_keytypes, trash.str);
1898 if (!node) {
1899 /* CN not found in tree */
1900 s_kt = malloc(sizeof(struct sni_keytype) + i + 1);
1901 /* Using memcpy here instead of strncpy.
1902 * strncpy will cause sig_abrt errors under certain versions of gcc with -O2
1903 * See: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=60792
1904 */
1905 memcpy(s_kt->name.key, trash.str, i+1);
1906 s_kt->keytypes = 0;
1907 ebst_insert(sni_keytypes, &s_kt->name);
1908 } else {
1909 /* CN found in tree */
1910 s_kt = container_of(node, struct sni_keytype, name);
1911 }
1912
1913 /* Mark that this CN has the keytype of key_index via keytypes mask */
1914 s_kt->keytypes |= 1<<key_index;
1915
1916}
1917
1918
1919/* Given a path that does not exist, try to check for path.rsa, path.dsa and path.ecdsa files.
1920 * If any are found, group these files into a set of SSL_CTX*
1921 * based on shared and unique CN and SAN entries. Add these SSL_CTX* to the SNI tree.
1922 *
1923 * This will allow the user to explictly group multiple cert/keys for a single purpose
1924 *
1925 * Returns
1926 * 0 on success
1927 * 1 on failure
1928 */
1929static int ssl_sock_load_multi_cert(const char *path, struct bind_conf *bind_conf, struct proxy *curproxy, char **sni_filter, char **err)
1930{
1931 char fp[MAXPATHLEN+1] = {0};
1932 int n = 0;
1933 int i = 0;
1934 struct cert_key_and_chain certs_and_keys[SSL_SOCK_NUM_KEYTYPES] = { {0} };
1935 struct eb_root sni_keytypes_map = { {0} };
1936 struct ebmb_node *node;
1937 struct ebmb_node *next;
1938 /* Array of SSL_CTX pointers corresponding to each possible combo
1939 * of keytypes
1940 */
1941 struct key_combo_ctx key_combos[SSL_SOCK_POSSIBLE_KT_COMBOS] = { {0} };
1942 int rv = 0;
1943 X509_NAME *xname = NULL;
1944 char *str = NULL;
1945#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
1946 STACK_OF(GENERAL_NAME) *names = NULL;
1947#endif
1948
1949 /* Load all possible certs and keys */
1950 for (n = 0; n < SSL_SOCK_NUM_KEYTYPES; n++) {
1951 struct stat buf;
1952
1953 snprintf(fp, sizeof(fp), "%s.%s", path, SSL_SOCK_KEYTYPE_NAMES[n]);
1954 if (stat(fp, &buf) == 0) {
1955 if (ssl_sock_load_crt_file_into_ckch(fp, &certs_and_keys[n], err) == 1) {
1956 rv = 1;
1957 goto end;
1958 }
1959 }
1960 }
1961
1962 /* Process each ckch and update keytypes for each CN/SAN
1963 * for example, if CN/SAN www.a.com is associated with
1964 * certs with keytype 0 and 2, then at the end of the loop,
1965 * www.a.com will have:
1966 * keyindex = 0 | 1 | 4 = 5
1967 */
1968 for (n = 0; n < SSL_SOCK_NUM_KEYTYPES; n++) {
1969
1970 if (!ssl_sock_is_ckch_valid(&certs_and_keys[n]))
1971 continue;
1972
1973 /* A lot of the following code is OpenSSL boilerplate for processing CN's and SAN's,
1974 * so the line that contains logic is marked via comments
1975 */
1976 xname = X509_get_subject_name(certs_and_keys[n].cert);
1977 i = -1;
1978 while ((i = X509_NAME_get_index_by_NID(xname, NID_commonName, i)) != -1) {
1979 X509_NAME_ENTRY *entry = X509_NAME_get_entry(xname, i);
1980
1981 if (ASN1_STRING_to_UTF8((unsigned char **)&str, entry->value) >= 0) {
1982 /* Important line is here */
1983 ssl_sock_populate_sni_keytypes_hplr(str, &sni_keytypes_map, n);
1984
1985 OPENSSL_free(str);
1986 str = NULL;
1987 }
1988 }
1989
1990 /* Do the above logic for each SAN */
1991#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
1992 names = X509_get_ext_d2i(certs_and_keys[n].cert, NID_subject_alt_name, NULL, NULL);
1993 if (names) {
1994 for (i = 0; i < sk_GENERAL_NAME_num(names); i++) {
1995 GENERAL_NAME *name = sk_GENERAL_NAME_value(names, i);
1996
1997 if (name->type == GEN_DNS) {
1998 if (ASN1_STRING_to_UTF8((unsigned char **)&str, name->d.dNSName) >= 0) {
1999 /* Important line is here */
2000 ssl_sock_populate_sni_keytypes_hplr(str, &sni_keytypes_map, n);
2001
2002 OPENSSL_free(str);
2003 str = NULL;
2004 }
2005 }
2006 }
2007 }
2008#endif /* SSL_CTRL_SET_TLSEXT_HOSTNAME */
2009 }
2010
2011 /* If no files found, return error */
2012 if (eb_is_empty(&sni_keytypes_map)) {
2013 memprintf(err, "%sunable to load SSL certificate file '%s' file does not exist.\n",
2014 err && *err ? *err : "", path);
2015 rv = 1;
2016 goto end;
2017 }
2018
2019 /* We now have a map of CN/SAN to keytypes that are loaded in
2020 * Iterate through the map to create the SSL_CTX's (if needed)
2021 * and add each CTX to the SNI tree
2022 *
2023 * Some math here:
2024 * There are 2^n - 1 possibile combinations, each unique
2025 * combination is denoted by the key in the map. Each key
2026 * has a value between 1 and 2^n - 1. Conveniently, the array
2027 * of SSL_CTX* is sized 2^n. So, we can simply use the i'th
2028 * entry in the array to correspond to the unique combo (key)
2029 * associated with i. This unique key combo (i) will be associated
2030 * with combos[i-1]
2031 */
2032
2033 node = ebmb_first(&sni_keytypes_map);
2034 while (node) {
2035 SSL_CTX *cur_ctx;
2036
2037 str = (char *)container_of(node, struct sni_keytype, name)->name.key;
2038 i = container_of(node, struct sni_keytype, name)->keytypes;
2039 cur_ctx = key_combos[i-1].ctx;
2040
2041 if (cur_ctx == NULL) {
2042 /* need to create SSL_CTX */
2043 cur_ctx = SSL_CTX_new(SSLv23_server_method());
2044 if (cur_ctx == NULL) {
2045 memprintf(err, "%sunable to allocate SSL context.\n",
2046 err && *err ? *err : "");
2047 rv = 1;
2048 goto end;
2049 }
2050
yanbzhube2774d2015-12-10 15:07:30 -05002051 /* Load all required certs/keys/chains/OCSPs info into SSL_CTX */
yanbzhu08ce6ab2015-12-02 13:01:29 -05002052 for (n = 0; n < SSL_SOCK_NUM_KEYTYPES; n++) {
2053 if (i & (1<<n)) {
2054 /* Key combo contains ckch[n] */
2055 snprintf(trash.str, trash.size, "%s.%s", path, SSL_SOCK_KEYTYPE_NAMES[n]);
2056 if (ssl_sock_put_ckch_into_ctx(trash.str, &certs_and_keys[n], cur_ctx, err) != 0) {
2057 SSL_CTX_free(cur_ctx);
2058 rv = 1;
2059 goto end;
2060 }
yanbzhube2774d2015-12-10 15:07:30 -05002061
2062#if (defined SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB && !defined OPENSSL_NO_OCSP)
2063 /* Load OCSP Info into context */
2064 if (ssl_sock_load_ocsp(cur_ctx, trash.str) < 0) {
2065 if (err)
2066 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",
2067 *err ? *err : "", path);
2068 SSL_CTX_free(cur_ctx);
2069 rv = 1;
2070 goto end;
2071 }
2072#endif
yanbzhu08ce6ab2015-12-02 13:01:29 -05002073 }
2074 }
2075
2076 /* Load DH params into the ctx to support DHE keys */
2077#ifndef OPENSSL_NO_DH
2078 if (ssl_dh_ptr_index >= 0)
2079 SSL_CTX_set_ex_data(cur_ctx, ssl_dh_ptr_index, NULL);
2080
2081 rv = ssl_sock_load_dh_params(cur_ctx, NULL);
2082 if (rv < 0) {
2083 if (err)
2084 memprintf(err, "%sunable to load DH parameters from file '%s'.\n",
2085 *err ? *err : "", path);
2086 rv = 1;
2087 goto end;
2088 }
2089#endif
2090
2091 /* Update key_combos */
2092 key_combos[i-1].ctx = cur_ctx;
2093 }
2094
2095 /* Update SNI Tree */
2096 ssl_sock_add_cert_sni(cur_ctx, bind_conf, str, key_combos[i-1].order++);
2097 node = ebmb_next(node);
2098 }
2099
2100
2101 /* Mark a default context if none exists, using the ctx that has the most shared keys */
2102 if (!bind_conf->default_ctx) {
2103 for (i = SSL_SOCK_POSSIBLE_KT_COMBOS - 1; i >= 0; i--) {
2104 if (key_combos[i].ctx) {
2105 bind_conf->default_ctx = key_combos[i].ctx;
2106 break;
2107 }
2108 }
2109 }
2110
2111end:
2112
2113 if (names)
2114 sk_GENERAL_NAME_pop_free(names, GENERAL_NAME_free);
2115
2116 for (n = 0; n < SSL_SOCK_NUM_KEYTYPES; n++)
2117 ssl_sock_free_cert_key_and_chain_contents(&certs_and_keys[n]);
2118
2119 node = ebmb_first(&sni_keytypes_map);
2120 while (node) {
2121 next = ebmb_next(node);
2122 ebmb_delete(node);
2123 node = next;
2124 }
2125
2126 return rv;
2127}
2128#else
2129/* This is a dummy, that just logs an error and returns error */
2130static int ssl_sock_load_multi_cert(const char *path, struct bind_conf *bind_conf, struct proxy *curproxy, char **sni_filter, char **err)
2131{
2132 memprintf(err, "%sunable to stat SSL certificate from file '%s' : %s.\n",
2133 err && *err ? *err : "", path, strerror(errno));
2134 return 1;
2135}
2136
yanbzhu488a4d22015-12-01 15:16:07 -05002137#endif /* #if OPENSSL_VERSION_NUMBER >= 0x1000200fL: Support for loading multiple certs into a single SSL_CTX */
2138
Emeric Brunfc0421f2012-09-07 17:30:07 +02002139/* Loads a certificate key and CA chain from a file. Returns 0 on error, -1 if
2140 * an early error happens and the caller must call SSL_CTX_free() by itelf.
2141 */
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02002142static 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 +02002143{
2144 BIO *in;
2145 X509 *x = NULL, *ca;
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02002146 int i, err;
Emeric Brunfc0421f2012-09-07 17:30:07 +02002147 int ret = -1;
2148 int order = 0;
2149 X509_NAME *xname;
2150 char *str;
Emeric Brunfc0421f2012-09-07 17:30:07 +02002151#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
2152 STACK_OF(GENERAL_NAME) *names;
2153#endif
2154
2155 in = BIO_new(BIO_s_file());
2156 if (in == NULL)
2157 goto end;
2158
2159 if (BIO_read_filename(in, file) <= 0)
2160 goto end;
2161
2162 x = PEM_read_bio_X509_AUX(in, NULL, ctx->default_passwd_callback, ctx->default_passwd_callback_userdata);
2163 if (x == NULL)
2164 goto end;
2165
Emeric Brun50bcecc2013-04-22 13:05:23 +02002166 if (fcount) {
2167 while (fcount--)
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02002168 order = ssl_sock_add_cert_sni(ctx, s, sni_filter[fcount], order);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002169 }
2170 else {
Emeric Brunfc0421f2012-09-07 17:30:07 +02002171#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002172 names = X509_get_ext_d2i(x, NID_subject_alt_name, NULL, NULL);
2173 if (names) {
2174 for (i = 0; i < sk_GENERAL_NAME_num(names); i++) {
2175 GENERAL_NAME *name = sk_GENERAL_NAME_value(names, i);
2176 if (name->type == GEN_DNS) {
2177 if (ASN1_STRING_to_UTF8((unsigned char **)&str, name->d.dNSName) >= 0) {
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02002178 order = ssl_sock_add_cert_sni(ctx, s, str, order);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002179 OPENSSL_free(str);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002180 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02002181 }
2182 }
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002183 sk_GENERAL_NAME_pop_free(names, GENERAL_NAME_free);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002184 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02002185#endif /* SSL_CTRL_SET_TLSEXT_HOSTNAME */
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002186 xname = X509_get_subject_name(x);
2187 i = -1;
2188 while ((i = X509_NAME_get_index_by_NID(xname, NID_commonName, i)) != -1) {
2189 X509_NAME_ENTRY *entry = X509_NAME_get_entry(xname, i);
2190 if (ASN1_STRING_to_UTF8((unsigned char **)&str, entry->value) >= 0) {
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02002191 order = ssl_sock_add_cert_sni(ctx, s, str, order);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002192 OPENSSL_free(str);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002193 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02002194 }
2195 }
2196
2197 ret = 0; /* the caller must not free the SSL_CTX argument anymore */
2198 if (!SSL_CTX_use_certificate(ctx, x))
2199 goto end;
2200
2201 if (ctx->extra_certs != NULL) {
2202 sk_X509_pop_free(ctx->extra_certs, X509_free);
2203 ctx->extra_certs = NULL;
2204 }
2205
2206 while ((ca = PEM_read_bio_X509(in, NULL, ctx->default_passwd_callback, ctx->default_passwd_callback_userdata))) {
2207 if (!SSL_CTX_add_extra_chain_cert(ctx, ca)) {
2208 X509_free(ca);
2209 goto end;
2210 }
2211 }
2212
2213 err = ERR_get_error();
2214 if (!err || (ERR_GET_LIB(err) == ERR_LIB_PEM && ERR_GET_REASON(err) == PEM_R_NO_START_LINE)) {
2215 /* we successfully reached the last cert in the file */
2216 ret = 1;
2217 }
2218 ERR_clear_error();
2219
2220end:
2221 if (x)
2222 X509_free(x);
2223
2224 if (in)
2225 BIO_free(in);
2226
2227 return ret;
2228}
2229
Emeric Brun50bcecc2013-04-22 13:05:23 +02002230static 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 +02002231{
2232 int ret;
2233 SSL_CTX *ctx;
2234
2235 ctx = SSL_CTX_new(SSLv23_server_method());
2236 if (!ctx) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02002237 memprintf(err, "%sunable to allocate SSL context for cert '%s'.\n",
2238 err && *err ? *err : "", path);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002239 return 1;
2240 }
2241
2242 if (SSL_CTX_use_PrivateKey_file(ctx, path, SSL_FILETYPE_PEM) <= 0) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02002243 memprintf(err, "%sunable to load SSL private key from PEM file '%s'.\n",
2244 err && *err ? *err : "", path);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002245 SSL_CTX_free(ctx);
2246 return 1;
2247 }
2248
Emeric Brun50bcecc2013-04-22 13:05:23 +02002249 ret = ssl_sock_load_cert_chain_file(ctx, path, bind_conf, sni_filter, fcount);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002250 if (ret <= 0) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02002251 memprintf(err, "%sunable to load SSL certificate from PEM file '%s'.\n",
2252 err && *err ? *err : "", path);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002253 if (ret < 0) /* serious error, must do that ourselves */
2254 SSL_CTX_free(ctx);
2255 return 1;
2256 }
Emeric Brun61694ab2012-10-26 13:35:33 +02002257
2258 if (SSL_CTX_check_private_key(ctx) <= 0) {
2259 memprintf(err, "%sinconsistencies between private key and certificate loaded from PEM file '%s'.\n",
2260 err && *err ? *err : "", path);
2261 return 1;
2262 }
2263
Emeric Brunfc0421f2012-09-07 17:30:07 +02002264 /* we must not free the SSL_CTX anymore below, since it's already in
2265 * the tree, so it will be discovered and cleaned in time.
2266 */
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02002267#ifndef OPENSSL_NO_DH
Remi Gacogne4f902b82015-05-28 16:23:00 +02002268 /* store a NULL pointer to indicate we have not yet loaded
2269 a custom DH param file */
2270 if (ssl_dh_ptr_index >= 0) {
2271 SSL_CTX_set_ex_data(ctx, ssl_dh_ptr_index, NULL);
2272 }
2273
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02002274 ret = ssl_sock_load_dh_params(ctx, path);
2275 if (ret < 0) {
2276 if (err)
2277 memprintf(err, "%sunable to load DH parameters from file '%s'.\n",
2278 *err ? *err : "", path);
2279 return 1;
2280 }
2281#endif
2282
Lukas Tribuse4e30f72014-12-09 16:32:51 +01002283#if (defined SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB && !defined OPENSSL_NO_OCSP)
Emeric Brun4147b2e2014-06-16 18:36:30 +02002284 ret = ssl_sock_load_ocsp(ctx, path);
2285 if (ret < 0) {
2286 if (err)
2287 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",
2288 *err ? *err : "", path);
2289 return 1;
2290 }
2291#endif
2292
Daniel Jakots54ffb912015-11-06 20:02:41 +01002293#if (OPENSSL_VERSION_NUMBER >= 0x1000200fL && !defined OPENSSL_NO_TLSEXT && !defined OPENSSL_IS_BORINGSSL && !defined LIBRESSL_VERSION_NUMBER)
Janusz Dziemidowicz2c701b52015-03-07 23:03:59 +01002294 if (sctl_ex_index >= 0) {
2295 ret = ssl_sock_load_sctl(ctx, path);
2296 if (ret < 0) {
2297 if (err)
2298 memprintf(err, "%s '%s.sctl' is present but cannot be read or parsed'.\n",
2299 *err ? *err : "", path);
2300 return 1;
2301 }
2302 }
2303#endif
2304
Emeric Brunfc0421f2012-09-07 17:30:07 +02002305#ifndef SSL_CTRL_SET_TLSEXT_HOSTNAME
Willy Tarreau2a65ff02012-09-13 17:54:29 +02002306 if (bind_conf->default_ctx) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02002307 memprintf(err, "%sthis version of openssl cannot load multiple SSL certificates.\n",
2308 err && *err ? *err : "");
Emeric Brunfc0421f2012-09-07 17:30:07 +02002309 return 1;
2310 }
2311#endif
Willy Tarreau2a65ff02012-09-13 17:54:29 +02002312 if (!bind_conf->default_ctx)
2313 bind_conf->default_ctx = ctx;
Emeric Brunfc0421f2012-09-07 17:30:07 +02002314
2315 return 0;
2316}
2317
Willy Tarreau79eeafa2012-09-14 07:53:05 +02002318int ssl_sock_load_cert(char *path, struct bind_conf *bind_conf, struct proxy *curproxy, char **err)
Emeric Brunfc0421f2012-09-07 17:30:07 +02002319{
Cyril Bonté3180f7b2015-01-25 00:16:08 +01002320 struct dirent **de_list;
2321 int i, n;
Emeric Brunfc0421f2012-09-07 17:30:07 +02002322 DIR *dir;
2323 struct stat buf;
Willy Tarreauee2663b2012-12-06 11:36:59 +01002324 char *end;
2325 char fp[MAXPATHLEN+1];
Emeric Brunfc0421f2012-09-07 17:30:07 +02002326 int cfgerr = 0;
yanbzhu63ea8462015-12-09 13:35:14 -05002327#if OPENSSL_VERSION_NUMBER >= 0x1000200fL
2328 int is_bundle;
2329 int j;
2330#endif
Emeric Brunfc0421f2012-09-07 17:30:07 +02002331
yanbzhu08ce6ab2015-12-02 13:01:29 -05002332 if (stat(path, &buf) == 0) {
2333 dir = opendir(path);
2334 if (!dir)
2335 return ssl_sock_load_cert_file(path, bind_conf, curproxy, NULL, 0, err);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002336
yanbzhu08ce6ab2015-12-02 13:01:29 -05002337 /* strip trailing slashes, including first one */
2338 for (end = path + strlen(path) - 1; end >= path && *end == '/'; end--)
2339 *end = 0;
Emeric Brunfc0421f2012-09-07 17:30:07 +02002340
yanbzhu08ce6ab2015-12-02 13:01:29 -05002341 n = scandir(path, &de_list, 0, alphasort);
2342 if (n < 0) {
2343 memprintf(err, "%sunable to scan directory '%s' : %s.\n",
2344 err && *err ? *err : "", path, strerror(errno));
2345 cfgerr++;
2346 }
2347 else {
2348 for (i = 0; i < n; i++) {
2349 struct dirent *de = de_list[i];
Emeric Brun2aab7222014-06-18 18:15:09 +02002350
yanbzhu08ce6ab2015-12-02 13:01:29 -05002351 end = strrchr(de->d_name, '.');
2352 if (end && (!strcmp(end, ".issuer") || !strcmp(end, ".ocsp") || !strcmp(end, ".sctl")))
2353 goto ignore_entry;
Cyril Bonté3180f7b2015-01-25 00:16:08 +01002354
yanbzhu08ce6ab2015-12-02 13:01:29 -05002355 snprintf(fp, sizeof(fp), "%s/%s", path, de->d_name);
2356 if (stat(fp, &buf) != 0) {
2357 memprintf(err, "%sunable to stat SSL certificate from file '%s' : %s.\n",
2358 err && *err ? *err : "", fp, strerror(errno));
2359 cfgerr++;
2360 goto ignore_entry;
2361 }
2362 if (!S_ISREG(buf.st_mode))
2363 goto ignore_entry;
yanbzhu63ea8462015-12-09 13:35:14 -05002364
2365#if OPENSSL_VERSION_NUMBER >= 0x1000200fL
2366 is_bundle = 0;
2367 /* Check if current entry in directory is part of a multi-cert bundle */
2368
2369 if (end) {
2370 for (j = 0; j < SSL_SOCK_NUM_KEYTYPES; j++) {
2371 if (!strcmp(end + 1, SSL_SOCK_KEYTYPE_NAMES[j])) {
2372 is_bundle = 1;
2373 break;
2374 }
2375 }
2376
2377 if (is_bundle) {
2378 char dp[MAXPATHLEN+1] = {0}; /* this will be the filename w/o the keytype */
2379 int dp_len;
2380
2381 dp_len = end - de->d_name;
2382 snprintf(dp, dp_len + 1, "%s", de->d_name);
2383
2384 /* increment i and free de until we get to a non-bundle cert
2385 * Note here that we look at de_list[i + 1] before freeing de
2386 * this is important since ignore_entry will free de
2387 */
2388 while (i + 1 < n && !strncmp(de_list[i + 1]->d_name, dp, dp_len)) {
2389 free(de);
2390 i++;
2391 de = de_list[i];
2392 }
2393
2394 snprintf(fp, sizeof(fp), "%s/%s", path, dp);
2395 ssl_sock_load_multi_cert(fp, bind_conf, curproxy, NULL, err);
2396
2397 /* Successfully processed the bundle */
2398 goto ignore_entry;
2399 }
2400 }
2401
2402#endif
yanbzhu08ce6ab2015-12-02 13:01:29 -05002403 cfgerr += ssl_sock_load_cert_file(fp, bind_conf, curproxy, NULL, 0, err);
2404ignore_entry:
2405 free(de);
Cyril Bonté3180f7b2015-01-25 00:16:08 +01002406 }
yanbzhu08ce6ab2015-12-02 13:01:29 -05002407 free(de_list);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002408 }
yanbzhu08ce6ab2015-12-02 13:01:29 -05002409 closedir(dir);
2410 return cfgerr;
Emeric Brunfc0421f2012-09-07 17:30:07 +02002411 }
yanbzhu08ce6ab2015-12-02 13:01:29 -05002412
2413 cfgerr = ssl_sock_load_multi_cert(path, bind_conf, curproxy, NULL, err);
2414
Emeric Brunfc0421f2012-09-07 17:30:07 +02002415 return cfgerr;
2416}
2417
Thierry Fournier383085f2013-01-24 14:15:43 +01002418/* Make sure openssl opens /dev/urandom before the chroot. The work is only
2419 * done once. Zero is returned if the operation fails. No error is returned
2420 * if the random is said as not implemented, because we expect that openssl
2421 * will use another method once needed.
2422 */
2423static int ssl_initialize_random()
2424{
2425 unsigned char random;
2426 static int random_initialized = 0;
2427
2428 if (!random_initialized && RAND_bytes(&random, 1) != 0)
2429 random_initialized = 1;
2430
2431 return random_initialized;
2432}
2433
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002434int ssl_sock_load_cert_list_file(char *file, struct bind_conf *bind_conf, struct proxy *curproxy, char **err)
2435{
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02002436 char thisline[LINESIZE];
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002437 FILE *f;
yanbzhu1b04e5b2015-12-02 13:54:14 -05002438 struct stat buf;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002439 int linenum = 0;
2440 int cfgerr = 0;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002441
Willy Tarreauad1731d2013-04-02 17:35:58 +02002442 if ((f = fopen(file, "r")) == NULL) {
2443 memprintf(err, "cannot open file '%s' : %s", file, strerror(errno));
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002444 return 1;
Willy Tarreauad1731d2013-04-02 17:35:58 +02002445 }
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002446
2447 while (fgets(thisline, sizeof(thisline), f) != NULL) {
2448 int arg;
Emeric Brun50bcecc2013-04-22 13:05:23 +02002449 int newarg;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002450 char *end;
2451 char *args[MAX_LINE_ARGS + 1];
2452 char *line = thisline;
2453
2454 linenum++;
2455 end = line + strlen(line);
2456 if (end-line == sizeof(thisline)-1 && *(end-1) != '\n') {
2457 /* Check if we reached the limit and the last char is not \n.
2458 * Watch out for the last line without the terminating '\n'!
2459 */
Willy Tarreauad1731d2013-04-02 17:35:58 +02002460 memprintf(err, "line %d too long in file '%s', limit is %d characters",
2461 linenum, file, (int)sizeof(thisline)-1);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002462 cfgerr = 1;
Willy Tarreauad1731d2013-04-02 17:35:58 +02002463 break;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002464 }
2465
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002466 arg = 0;
Emeric Brun50bcecc2013-04-22 13:05:23 +02002467 newarg = 1;
2468 while (*line) {
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002469 if (*line == '#' || *line == '\n' || *line == '\r') {
2470 /* end of string, end of loop */
2471 *line = 0;
2472 break;
2473 }
2474 else if (isspace(*line)) {
Emeric Brun50bcecc2013-04-22 13:05:23 +02002475 newarg = 1;
2476 *line = 0;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002477 }
Emeric Brun50bcecc2013-04-22 13:05:23 +02002478 else if (newarg) {
2479 if (arg == MAX_LINE_ARGS) {
2480 memprintf(err, "too many args on line %d in file '%s'.",
2481 linenum, file);
2482 cfgerr = 1;
2483 break;
2484 }
2485 newarg = 0;
2486 args[arg++] = line;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002487 }
Emeric Brun50bcecc2013-04-22 13:05:23 +02002488 line++;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002489 }
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02002490 if (cfgerr)
2491 break;
Willy Tarreauad1731d2013-04-02 17:35:58 +02002492
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002493 /* empty line */
Emeric Brun50bcecc2013-04-22 13:05:23 +02002494 if (!arg)
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002495 continue;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002496
yanbzhu1b04e5b2015-12-02 13:54:14 -05002497 if (stat(args[0], &buf) == 0) {
2498 cfgerr = ssl_sock_load_cert_file(args[0], bind_conf, curproxy, &args[1], arg-1, err);
2499 } else {
2500 cfgerr = ssl_sock_load_multi_cert(args[0], bind_conf, curproxy, NULL, err);
2501 }
2502
Willy Tarreauad1731d2013-04-02 17:35:58 +02002503 if (cfgerr) {
2504 memprintf(err, "error processing line %d in file '%s' : %s", linenum, file, *err);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002505 break;
Willy Tarreauad1731d2013-04-02 17:35:58 +02002506 }
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002507 }
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002508 fclose(f);
2509 return cfgerr;
2510}
2511
Emeric Brunfc0421f2012-09-07 17:30:07 +02002512#ifndef SSL_OP_CIPHER_SERVER_PREFERENCE /* needs OpenSSL >= 0.9.7 */
2513#define SSL_OP_CIPHER_SERVER_PREFERENCE 0
2514#endif
2515
2516#ifndef SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION /* needs OpenSSL >= 0.9.7 */
2517#define SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION 0
Willy Tarreau7d588ee2012-11-26 18:47:31 +01002518#define SSL_renegotiate_pending(arg) 0
Emeric Brunfc0421f2012-09-07 17:30:07 +02002519#endif
Emeric Brun2b58d042012-09-20 17:10:03 +02002520#ifndef SSL_OP_SINGLE_ECDH_USE /* needs OpenSSL >= 0.9.8 */
2521#define SSL_OP_SINGLE_ECDH_USE 0
2522#endif
Emeric Brun2d0c4822012-10-02 13:45:20 +02002523#ifndef SSL_OP_NO_TICKET /* needs OpenSSL >= 0.9.8 */
2524#define SSL_OP_NO_TICKET 0
2525#endif
Emeric Brunfc0421f2012-09-07 17:30:07 +02002526#ifndef SSL_OP_NO_COMPRESSION /* needs OpenSSL >= 0.9.9 */
2527#define SSL_OP_NO_COMPRESSION 0
2528#endif
Emeric Brunc0ff4922012-09-28 19:37:02 +02002529#ifndef SSL_OP_NO_TLSv1_1 /* needs OpenSSL >= 1.0.1 */
2530#define SSL_OP_NO_TLSv1_1 0
2531#endif
2532#ifndef SSL_OP_NO_TLSv1_2 /* needs OpenSSL >= 1.0.1 */
2533#define SSL_OP_NO_TLSv1_2 0
2534#endif
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02002535#ifndef SSL_OP_SINGLE_DH_USE /* needs OpenSSL >= 0.9.6 */
2536#define SSL_OP_SINGLE_DH_USE 0
2537#endif
Emeric Brun2b58d042012-09-20 17:10:03 +02002538#ifndef SSL_OP_SINGLE_ECDH_USE /* needs OpenSSL >= 1.0.0 */
2539#define SSL_OP_SINGLE_ECDH_USE 0
2540#endif
Emeric Brunfc0421f2012-09-07 17:30:07 +02002541#ifndef SSL_MODE_RELEASE_BUFFERS /* needs OpenSSL >= 1.0.0 */
2542#define SSL_MODE_RELEASE_BUFFERS 0
2543#endif
Willy Tarreau396a1862014-11-13 14:06:52 +01002544#ifndef SSL_MODE_SMALL_BUFFERS /* needs small_records.patch */
2545#define SSL_MODE_SMALL_BUFFERS 0
2546#endif
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002547
Willy Tarreau2a65ff02012-09-13 17:54:29 +02002548int ssl_sock_prepare_ctx(struct bind_conf *bind_conf, SSL_CTX *ctx, struct proxy *curproxy)
Emeric Brunfc0421f2012-09-07 17:30:07 +02002549{
2550 int cfgerr = 0;
Emeric Brun850efd52014-01-29 12:24:34 +01002551 int verify = SSL_VERIFY_NONE;
Remi Gacogneaf5c3da2014-05-19 10:29:58 +02002552 long ssloptions =
Emeric Brunfc0421f2012-09-07 17:30:07 +02002553 SSL_OP_ALL | /* all known workarounds for bugs */
2554 SSL_OP_NO_SSLv2 |
2555 SSL_OP_NO_COMPRESSION |
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02002556 SSL_OP_SINGLE_DH_USE |
Emeric Brun2b58d042012-09-20 17:10:03 +02002557 SSL_OP_SINGLE_ECDH_USE |
Emeric Brun3c4bc6e2012-10-04 18:44:19 +02002558 SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION |
2559 SSL_OP_CIPHER_SERVER_PREFERENCE;
Remi Gacogneaf5c3da2014-05-19 10:29:58 +02002560 long sslmode =
Emeric Brunfc0421f2012-09-07 17:30:07 +02002561 SSL_MODE_ENABLE_PARTIAL_WRITE |
2562 SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER |
Willy Tarreau396a1862014-11-13 14:06:52 +01002563 SSL_MODE_RELEASE_BUFFERS |
2564 SSL_MODE_SMALL_BUFFERS;
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002565 STACK_OF(SSL_CIPHER) * ciphers = NULL;
Willy Tarreaua616ba62014-10-26 06:49:19 +01002566 SSL_CIPHER * cipher = NULL;
Remi Gacognec1eab8c2014-06-12 18:20:11 +02002567 char cipher_description[128];
2568 /* The description of ciphers using an Ephemeral Diffie Hellman key exchange
2569 contains " Kx=DH " or " Kx=DH(". Beware of " Kx=DH/",
2570 which is not ephemeral DH. */
2571 const char dhe_description[] = " Kx=DH ";
2572 const char dhe_export_description[] = " Kx=DH(";
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002573 int idx = 0;
2574 int dhe_found = 0;
Remi Gacogne23d5d372014-10-10 17:04:26 +02002575 SSL *ssl = NULL;
Emeric Brunfc0421f2012-09-07 17:30:07 +02002576
Thierry Fournier383085f2013-01-24 14:15:43 +01002577 /* Make sure openssl opens /dev/urandom before the chroot */
2578 if (!ssl_initialize_random()) {
2579 Alert("OpenSSL random data generator initialization failed.\n");
2580 cfgerr++;
2581 }
2582
Emeric Brun89675492012-10-05 13:48:26 +02002583 if (bind_conf->ssl_options & BC_SSL_O_NO_SSLV3)
Emeric Brunfc0421f2012-09-07 17:30:07 +02002584 ssloptions |= SSL_OP_NO_SSLv3;
Emeric Brun89675492012-10-05 13:48:26 +02002585 if (bind_conf->ssl_options & BC_SSL_O_NO_TLSV10)
Emeric Brunfc0421f2012-09-07 17:30:07 +02002586 ssloptions |= SSL_OP_NO_TLSv1;
Emeric Brun89675492012-10-05 13:48:26 +02002587 if (bind_conf->ssl_options & BC_SSL_O_NO_TLSV11)
Emeric Brunc0ff4922012-09-28 19:37:02 +02002588 ssloptions |= SSL_OP_NO_TLSv1_1;
Emeric Brun89675492012-10-05 13:48:26 +02002589 if (bind_conf->ssl_options & BC_SSL_O_NO_TLSV12)
Emeric Brunc0ff4922012-09-28 19:37:02 +02002590 ssloptions |= SSL_OP_NO_TLSv1_2;
Emeric Brun89675492012-10-05 13:48:26 +02002591 if (bind_conf->ssl_options & BC_SSL_O_NO_TLS_TICKETS)
Emeric Brun2d0c4822012-10-02 13:45:20 +02002592 ssloptions |= SSL_OP_NO_TICKET;
Jérémie Courrèges-Anglas17c3f622015-07-25 16:50:52 -06002593 if (bind_conf->ssl_options & BC_SSL_O_USE_SSLV3) {
2594#ifndef OPENSSL_NO_SSL3
Emeric Brun2cb7ae52012-10-05 14:14:21 +02002595 SSL_CTX_set_ssl_version(ctx, SSLv3_server_method());
Jérémie Courrèges-Anglas17c3f622015-07-25 16:50:52 -06002596#else
2597 Alert("SSLv3 support requested but unavailable.\n");
2598 cfgerr++;
2599#endif
2600 }
Emeric Brun2cb7ae52012-10-05 14:14:21 +02002601 if (bind_conf->ssl_options & BC_SSL_O_USE_TLSV10)
2602 SSL_CTX_set_ssl_version(ctx, TLSv1_server_method());
2603#if SSL_OP_NO_TLSv1_1
2604 if (bind_conf->ssl_options & BC_SSL_O_USE_TLSV11)
2605 SSL_CTX_set_ssl_version(ctx, TLSv1_1_server_method());
2606#endif
2607#if SSL_OP_NO_TLSv1_2
2608 if (bind_conf->ssl_options & BC_SSL_O_USE_TLSV12)
2609 SSL_CTX_set_ssl_version(ctx, TLSv1_2_server_method());
2610#endif
Emeric Brunfc0421f2012-09-07 17:30:07 +02002611
2612 SSL_CTX_set_options(ctx, ssloptions);
2613 SSL_CTX_set_mode(ctx, sslmode);
Emeric Brun850efd52014-01-29 12:24:34 +01002614 switch (bind_conf->verify) {
2615 case SSL_SOCK_VERIFY_NONE:
2616 verify = SSL_VERIFY_NONE;
2617 break;
2618 case SSL_SOCK_VERIFY_OPTIONAL:
2619 verify = SSL_VERIFY_PEER;
2620 break;
2621 case SSL_SOCK_VERIFY_REQUIRED:
2622 verify = SSL_VERIFY_PEER|SSL_VERIFY_FAIL_IF_NO_PEER_CERT;
2623 break;
2624 }
2625 SSL_CTX_set_verify(ctx, verify, ssl_sock_bind_verifycbk);
2626 if (verify & SSL_VERIFY_PEER) {
Emeric Brunfb510ea2012-10-05 12:00:26 +02002627 if (bind_conf->ca_file) {
Emeric Brund94b3fe2012-09-20 18:23:56 +02002628 /* load CAfile to verify */
Emeric Brunfb510ea2012-10-05 12:00:26 +02002629 if (!SSL_CTX_load_verify_locations(ctx, bind_conf->ca_file, NULL)) {
Emeric Brund94b3fe2012-09-20 18:23:56 +02002630 Alert("Proxy '%s': unable to load CA file '%s' for bind '%s' at [%s:%d].\n",
Emeric Brunfb510ea2012-10-05 12:00:26 +02002631 curproxy->id, bind_conf->ca_file, bind_conf->arg, bind_conf->file, bind_conf->line);
Emeric Brund94b3fe2012-09-20 18:23:56 +02002632 cfgerr++;
2633 }
2634 /* set CA names fo client cert request, function returns void */
Emeric Brunfb510ea2012-10-05 12:00:26 +02002635 SSL_CTX_set_client_CA_list(ctx, SSL_load_client_CA_file(bind_conf->ca_file));
Emeric Brund94b3fe2012-09-20 18:23:56 +02002636 }
Emeric Brun850efd52014-01-29 12:24:34 +01002637 else {
2638 Alert("Proxy '%s': verify is enabled but no CA file specified for bind '%s' at [%s:%d].\n",
2639 curproxy->id, bind_conf->arg, bind_conf->file, bind_conf->line);
2640 cfgerr++;
2641 }
Emeric Brun051cdab2012-10-02 19:25:50 +02002642#ifdef X509_V_FLAG_CRL_CHECK
Emeric Brunfb510ea2012-10-05 12:00:26 +02002643 if (bind_conf->crl_file) {
Emeric Brund94b3fe2012-09-20 18:23:56 +02002644 X509_STORE *store = SSL_CTX_get_cert_store(ctx);
2645
Emeric Brunfb510ea2012-10-05 12:00:26 +02002646 if (!store || !X509_STORE_load_locations(store, bind_conf->crl_file, NULL)) {
Emeric Brund94b3fe2012-09-20 18:23:56 +02002647 Alert("Proxy '%s': unable to configure CRL file '%s' for bind '%s' at [%s:%d].\n",
Alexander Rigbofc65af02015-04-07 14:02:16 +02002648 curproxy->id, bind_conf->crl_file, bind_conf->arg, bind_conf->file, bind_conf->line);
Emeric Brund94b3fe2012-09-20 18:23:56 +02002649 cfgerr++;
2650 }
Emeric Brun561e5742012-10-02 15:20:55 +02002651 else {
2652 X509_STORE_set_flags(store, X509_V_FLAG_CRL_CHECK|X509_V_FLAG_CRL_CHECK_ALL);
2653 }
Emeric Brund94b3fe2012-09-20 18:23:56 +02002654 }
Emeric Brun051cdab2012-10-02 19:25:50 +02002655#endif
Emeric Brun644cde02012-12-14 11:21:13 +01002656 ERR_clear_error();
Emeric Brund94b3fe2012-09-20 18:23:56 +02002657 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02002658
Nenad Merdanovic05552d42015-02-27 19:56:49 +01002659#if (defined SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB && TLS_TICKETS_NO > 0)
Nenad Merdanovic146defa2015-05-09 08:46:00 +02002660 if(bind_conf->keys_ref) {
Nenad Merdanovic05552d42015-02-27 19:56:49 +01002661 if (!SSL_CTX_set_tlsext_ticket_key_cb(ctx, ssl_tlsext_ticket_key_cb)) {
2662 Alert("Proxy '%s': unable to set callback for TLS ticket validation for bind '%s' at [%s:%d].\n",
2663 curproxy->id, bind_conf->arg, bind_conf->file, bind_conf->line);
2664 cfgerr++;
2665 }
2666 }
2667#endif
2668
Emeric Brun4f65bff2012-11-16 15:11:00 +01002669 if (global.tune.ssllifetime)
2670 SSL_CTX_set_timeout(ctx, global.tune.ssllifetime);
2671
Emeric Brunfc0421f2012-09-07 17:30:07 +02002672 shared_context_set_cache(ctx);
Willy Tarreau2a65ff02012-09-13 17:54:29 +02002673 if (bind_conf->ciphers &&
2674 !SSL_CTX_set_cipher_list(ctx, bind_conf->ciphers)) {
Emeric Brunfc0421f2012-09-07 17:30:07 +02002675 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 +02002676 curproxy->id, bind_conf->ciphers, bind_conf->arg, bind_conf->file, bind_conf->line);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002677 cfgerr++;
2678 }
2679
Remi Gacogne47783ef2015-05-29 15:53:22 +02002680 /* If tune.ssl.default-dh-param has not been set,
2681 neither has ssl-default-dh-file and no static DH
2682 params were in the certificate file. */
Remi Gacogne4f902b82015-05-28 16:23:00 +02002683 if (global.tune.ssl_default_dh_param == 0 &&
Remi Gacogne47783ef2015-05-29 15:53:22 +02002684 global_dh == NULL &&
Remi Gacogne4f902b82015-05-28 16:23:00 +02002685 (ssl_dh_ptr_index == -1 ||
2686 SSL_CTX_get_ex_data(ctx, ssl_dh_ptr_index) == NULL)) {
Lukas Tribus90132722014-08-18 00:56:33 +02002687
Remi Gacogne23d5d372014-10-10 17:04:26 +02002688 ssl = SSL_new(ctx);
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002689
Remi Gacogne23d5d372014-10-10 17:04:26 +02002690 if (ssl) {
2691 ciphers = SSL_get_ciphers(ssl);
2692
2693 if (ciphers) {
2694 for (idx = 0; idx < sk_SSL_CIPHER_num(ciphers); idx++) {
2695 cipher = sk_SSL_CIPHER_value(ciphers, idx);
2696 if (SSL_CIPHER_description(cipher, cipher_description, sizeof (cipher_description)) == cipher_description) {
2697 if (strstr(cipher_description, dhe_description) != NULL ||
2698 strstr(cipher_description, dhe_export_description) != NULL) {
2699 dhe_found = 1;
2700 break;
2701 }
Remi Gacognec1eab8c2014-06-12 18:20:11 +02002702 }
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002703 }
2704 }
Remi Gacogne23d5d372014-10-10 17:04:26 +02002705 SSL_free(ssl);
2706 ssl = NULL;
Lukas Tribus90132722014-08-18 00:56:33 +02002707 }
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002708
Lukas Tribus90132722014-08-18 00:56:33 +02002709 if (dhe_found) {
2710 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 +02002711 }
2712
2713 global.tune.ssl_default_dh_param = 1024;
2714 }
Remi Gacogne8de54152014-07-15 11:36:40 +02002715
2716#ifndef OPENSSL_NO_DH
2717 if (global.tune.ssl_default_dh_param >= 1024) {
2718 if (local_dh_1024 == NULL) {
2719 local_dh_1024 = ssl_get_dh_1024();
2720 }
2721 if (global.tune.ssl_default_dh_param >= 2048) {
2722 if (local_dh_2048 == NULL) {
2723 local_dh_2048 = ssl_get_dh_2048();
2724 }
2725 if (global.tune.ssl_default_dh_param >= 4096) {
2726 if (local_dh_4096 == NULL) {
2727 local_dh_4096 = ssl_get_dh_4096();
2728 }
Remi Gacogne8de54152014-07-15 11:36:40 +02002729 }
2730 }
2731 }
2732#endif /* OPENSSL_NO_DH */
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002733
Emeric Brunfc0421f2012-09-07 17:30:07 +02002734 SSL_CTX_set_info_callback(ctx, ssl_sock_infocbk);
Willy Tarreau5cbe4ef2014-05-08 22:45:11 +02002735#if OPENSSL_VERSION_NUMBER >= 0x00907000L
Emeric Brun29f037d2014-04-25 19:05:36 +02002736 SSL_CTX_set_msg_callback(ctx, ssl_sock_msgcbk);
Willy Tarreau5cbe4ef2014-05-08 22:45:11 +02002737#endif
Emeric Brun29f037d2014-04-25 19:05:36 +02002738
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02002739#ifdef OPENSSL_NPN_NEGOTIATED
2740 if (bind_conf->npn_str)
2741 SSL_CTX_set_next_protos_advertised_cb(ctx, ssl_sock_advertise_npn_protos, bind_conf);
2742#endif
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01002743#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Willy Tarreauab861d32013-04-02 02:30:41 +02002744 if (bind_conf->alpn_str)
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01002745 SSL_CTX_set_alpn_select_cb(ctx, ssl_sock_advertise_alpn_protos, bind_conf);
Willy Tarreauab861d32013-04-02 02:30:41 +02002746#endif
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02002747
Emeric Brunfc0421f2012-09-07 17:30:07 +02002748#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
2749 SSL_CTX_set_tlsext_servername_callback(ctx, ssl_sock_switchctx_cbk);
Willy Tarreau2a65ff02012-09-13 17:54:29 +02002750 SSL_CTX_set_tlsext_servername_arg(ctx, bind_conf);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002751#endif
Emeric Brun2b58d042012-09-20 17:10:03 +02002752#if defined(SSL_CTX_set_tmp_ecdh) && !defined(OPENSSL_NO_ECDH)
Emeric Brun6924ef82013-03-06 14:08:53 +01002753 {
Emeric Brun2b58d042012-09-20 17:10:03 +02002754 int i;
2755 EC_KEY *ecdh;
2756
Emeric Brun6924ef82013-03-06 14:08:53 +01002757 i = OBJ_sn2nid(bind_conf->ecdhe ? bind_conf->ecdhe : ECDHE_DEFAULT_CURVE);
Emeric Brun2b58d042012-09-20 17:10:03 +02002758 if (!i || ((ecdh = EC_KEY_new_by_curve_name(i)) == NULL)) {
2759 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 +01002760 curproxy->id, bind_conf->ecdhe ? bind_conf->ecdhe : ECDHE_DEFAULT_CURVE,
2761 bind_conf->arg, bind_conf->file, bind_conf->line);
Emeric Brun2b58d042012-09-20 17:10:03 +02002762 cfgerr++;
2763 }
2764 else {
2765 SSL_CTX_set_tmp_ecdh(ctx, ecdh);
2766 EC_KEY_free(ecdh);
2767 }
2768 }
2769#endif
2770
Emeric Brunfc0421f2012-09-07 17:30:07 +02002771 return cfgerr;
2772}
2773
Evan Broderbe554312013-06-27 00:05:25 -07002774static int ssl_sock_srv_hostcheck(const char *pattern, const char *hostname)
2775{
2776 const char *pattern_wildcard, *pattern_left_label_end, *hostname_left_label_end;
2777 size_t prefixlen, suffixlen;
2778
2779 /* Trivial case */
2780 if (strcmp(pattern, hostname) == 0)
2781 return 1;
2782
Evan Broderbe554312013-06-27 00:05:25 -07002783 /* The rest of this logic is based on RFC 6125, section 6.4.3
2784 * (http://tools.ietf.org/html/rfc6125#section-6.4.3) */
2785
Emeric Bruna848dae2013-10-08 11:27:28 +02002786 pattern_wildcard = NULL;
2787 pattern_left_label_end = pattern;
2788 while (*pattern_left_label_end != '.') {
2789 switch (*pattern_left_label_end) {
2790 case 0:
2791 /* End of label not found */
2792 return 0;
2793 case '*':
2794 /* If there is more than one wildcards */
2795 if (pattern_wildcard)
2796 return 0;
2797 pattern_wildcard = pattern_left_label_end;
2798 break;
2799 }
2800 pattern_left_label_end++;
2801 }
2802
2803 /* If it's not trivial and there is no wildcard, it can't
2804 * match */
2805 if (!pattern_wildcard)
Evan Broderbe554312013-06-27 00:05:25 -07002806 return 0;
2807
2808 /* Make sure all labels match except the leftmost */
2809 hostname_left_label_end = strchr(hostname, '.');
2810 if (!hostname_left_label_end
2811 || strcmp(pattern_left_label_end, hostname_left_label_end) != 0)
2812 return 0;
2813
2814 /* Make sure the leftmost label of the hostname is long enough
2815 * that the wildcard can match */
Emeric Brun369da852013-10-08 11:39:35 +02002816 if (hostname_left_label_end - hostname < (pattern_left_label_end - pattern) - 1)
Evan Broderbe554312013-06-27 00:05:25 -07002817 return 0;
2818
2819 /* Finally compare the string on either side of the
2820 * wildcard */
2821 prefixlen = pattern_wildcard - pattern;
2822 suffixlen = pattern_left_label_end - (pattern_wildcard + 1);
Emeric Bruna848dae2013-10-08 11:27:28 +02002823 if ((prefixlen && (memcmp(pattern, hostname, prefixlen) != 0))
2824 || (suffixlen && (memcmp(pattern_wildcard + 1, hostname_left_label_end - suffixlen, suffixlen) != 0)))
Evan Broderbe554312013-06-27 00:05:25 -07002825 return 0;
2826
2827 return 1;
2828}
2829
2830static int ssl_sock_srv_verifycbk(int ok, X509_STORE_CTX *ctx)
2831{
2832 SSL *ssl;
2833 struct connection *conn;
2834 char *servername;
2835
2836 int depth;
2837 X509 *cert;
2838 STACK_OF(GENERAL_NAME) *alt_names;
2839 int i;
2840 X509_NAME *cert_subject;
2841 char *str;
2842
2843 if (ok == 0)
2844 return ok;
2845
2846 ssl = X509_STORE_CTX_get_ex_data(ctx, SSL_get_ex_data_X509_STORE_CTX_idx());
2847 conn = (struct connection *)SSL_get_app_data(ssl);
2848
2849 servername = objt_server(conn->target)->ssl_ctx.verify_host;
2850
2851 /* We only need to verify the CN on the actual server cert,
2852 * not the indirect CAs */
2853 depth = X509_STORE_CTX_get_error_depth(ctx);
2854 if (depth != 0)
2855 return ok;
2856
2857 /* At this point, the cert is *not* OK unless we can find a
2858 * hostname match */
2859 ok = 0;
2860
2861 cert = X509_STORE_CTX_get_current_cert(ctx);
2862 /* It seems like this might happen if verify peer isn't set */
2863 if (!cert)
2864 return ok;
2865
2866 alt_names = X509_get_ext_d2i(cert, NID_subject_alt_name, NULL, NULL);
2867 if (alt_names) {
2868 for (i = 0; !ok && i < sk_GENERAL_NAME_num(alt_names); i++) {
2869 GENERAL_NAME *name = sk_GENERAL_NAME_value(alt_names, i);
2870 if (name->type == GEN_DNS) {
Emeric Bruna33410c2013-09-17 15:47:48 +02002871#if OPENSSL_VERSION_NUMBER < 0x00907000L
2872 if (ASN1_STRING_to_UTF8((unsigned char **)&str, name->d.ia5) >= 0) {
2873#else
Evan Broderbe554312013-06-27 00:05:25 -07002874 if (ASN1_STRING_to_UTF8((unsigned char **)&str, name->d.dNSName) >= 0) {
Emeric Bruna33410c2013-09-17 15:47:48 +02002875#endif
Evan Broderbe554312013-06-27 00:05:25 -07002876 ok = ssl_sock_srv_hostcheck(str, servername);
2877 OPENSSL_free(str);
2878 }
2879 }
2880 }
Emeric Brun4ad50a42013-09-17 15:19:54 +02002881 sk_GENERAL_NAME_pop_free(alt_names, GENERAL_NAME_free);
Evan Broderbe554312013-06-27 00:05:25 -07002882 }
2883
2884 cert_subject = X509_get_subject_name(cert);
2885 i = -1;
2886 while (!ok && (i = X509_NAME_get_index_by_NID(cert_subject, NID_commonName, i)) != -1) {
2887 X509_NAME_ENTRY *entry = X509_NAME_get_entry(cert_subject, i);
2888 if (ASN1_STRING_to_UTF8((unsigned char **)&str, entry->value) >= 0) {
2889 ok = ssl_sock_srv_hostcheck(str, servername);
2890 OPENSSL_free(str);
2891 }
2892 }
2893
2894 return ok;
2895}
2896
Emeric Brun94324a42012-10-11 14:00:19 +02002897/* prepare ssl context from servers options. Returns an error count */
2898int ssl_sock_prepare_srv_ctx(struct server *srv, struct proxy *curproxy)
2899{
2900 int cfgerr = 0;
Remi Gacogneaf5c3da2014-05-19 10:29:58 +02002901 long options =
Emeric Brun94324a42012-10-11 14:00:19 +02002902 SSL_OP_ALL | /* all known workarounds for bugs */
2903 SSL_OP_NO_SSLv2 |
2904 SSL_OP_NO_COMPRESSION;
Remi Gacogneaf5c3da2014-05-19 10:29:58 +02002905 long mode =
Emeric Brun94324a42012-10-11 14:00:19 +02002906 SSL_MODE_ENABLE_PARTIAL_WRITE |
2907 SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER |
Willy Tarreau396a1862014-11-13 14:06:52 +01002908 SSL_MODE_RELEASE_BUFFERS |
2909 SSL_MODE_SMALL_BUFFERS;
Emeric Brun850efd52014-01-29 12:24:34 +01002910 int verify = SSL_VERIFY_NONE;
Emeric Brun94324a42012-10-11 14:00:19 +02002911
Thierry Fournier383085f2013-01-24 14:15:43 +01002912 /* Make sure openssl opens /dev/urandom before the chroot */
2913 if (!ssl_initialize_random()) {
2914 Alert("OpenSSL random data generator initialization failed.\n");
2915 cfgerr++;
2916 }
2917
Willy Tarreaufce03112015-01-15 21:32:40 +01002918 /* Automatic memory computations need to know we use SSL there */
2919 global.ssl_used_backend = 1;
2920
2921 /* Initiate SSL context for current server */
Emeric Brun94324a42012-10-11 14:00:19 +02002922 srv->ssl_ctx.reused_sess = NULL;
2923 if (srv->use_ssl)
2924 srv->xprt = &ssl_sock;
2925 if (srv->check.use_ssl)
Cyril Bonté9ce13112014-11-15 22:41:27 +01002926 srv->check.xprt = &ssl_sock;
Emeric Brun94324a42012-10-11 14:00:19 +02002927
2928 srv->ssl_ctx.ctx = SSL_CTX_new(SSLv23_client_method());
2929 if (!srv->ssl_ctx.ctx) {
2930 Alert("config : %s '%s', server '%s': unable to allocate ssl context.\n",
2931 proxy_type_str(curproxy), curproxy->id,
2932 srv->id);
2933 cfgerr++;
2934 return cfgerr;
2935 }
Emeric Bruna7aa3092012-10-26 12:58:00 +02002936 if (srv->ssl_ctx.client_crt) {
2937 if (SSL_CTX_use_PrivateKey_file(srv->ssl_ctx.ctx, srv->ssl_ctx.client_crt, SSL_FILETYPE_PEM) <= 0) {
2938 Alert("config : %s '%s', server '%s': unable to load SSL private key from PEM file '%s'.\n",
2939 proxy_type_str(curproxy), curproxy->id,
2940 srv->id, srv->ssl_ctx.client_crt);
2941 cfgerr++;
2942 }
2943 else if (SSL_CTX_use_certificate_chain_file(srv->ssl_ctx.ctx, srv->ssl_ctx.client_crt) <= 0) {
2944 Alert("config : %s '%s', server '%s': unable to load ssl certificate from PEM file '%s'.\n",
2945 proxy_type_str(curproxy), curproxy->id,
2946 srv->id, srv->ssl_ctx.client_crt);
2947 cfgerr++;
2948 }
2949 else if (SSL_CTX_check_private_key(srv->ssl_ctx.ctx) <= 0) {
2950 Alert("config : %s '%s', server '%s': inconsistencies between private key and certificate loaded from PEM file '%s'.\n",
2951 proxy_type_str(curproxy), curproxy->id,
2952 srv->id, srv->ssl_ctx.client_crt);
2953 cfgerr++;
2954 }
2955 }
Emeric Brun94324a42012-10-11 14:00:19 +02002956
2957 if (srv->ssl_ctx.options & SRV_SSL_O_NO_SSLV3)
2958 options |= SSL_OP_NO_SSLv3;
2959 if (srv->ssl_ctx.options & SRV_SSL_O_NO_TLSV10)
2960 options |= SSL_OP_NO_TLSv1;
2961 if (srv->ssl_ctx.options & SRV_SSL_O_NO_TLSV11)
2962 options |= SSL_OP_NO_TLSv1_1;
2963 if (srv->ssl_ctx.options & SRV_SSL_O_NO_TLSV12)
2964 options |= SSL_OP_NO_TLSv1_2;
Emeric Brunf9c5c472012-10-11 15:28:34 +02002965 if (srv->ssl_ctx.options & SRV_SSL_O_NO_TLS_TICKETS)
2966 options |= SSL_OP_NO_TICKET;
Jérémie Courrèges-Anglas17c3f622015-07-25 16:50:52 -06002967 if (srv->ssl_ctx.options & SRV_SSL_O_USE_SSLV3) {
2968#ifndef OPENSSL_NO_SSL3
Emeric Brun94324a42012-10-11 14:00:19 +02002969 SSL_CTX_set_ssl_version(srv->ssl_ctx.ctx, SSLv3_client_method());
Jérémie Courrèges-Anglas17c3f622015-07-25 16:50:52 -06002970#else
Thierry FOURNIERbc965342015-08-26 08:21:26 +02002971 Alert("SSLv3 support requested but unavailable.\n");
Jérémie Courrèges-Anglas17c3f622015-07-25 16:50:52 -06002972 cfgerr++;
2973#endif
2974 }
Emeric Brun94324a42012-10-11 14:00:19 +02002975 if (srv->ssl_ctx.options & SRV_SSL_O_USE_TLSV10)
2976 SSL_CTX_set_ssl_version(srv->ssl_ctx.ctx, TLSv1_client_method());
2977#if SSL_OP_NO_TLSv1_1
2978 if (srv->ssl_ctx.options & SRV_SSL_O_USE_TLSV11)
2979 SSL_CTX_set_ssl_version(srv->ssl_ctx.ctx, TLSv1_1_client_method());
2980#endif
2981#if SSL_OP_NO_TLSv1_2
2982 if (srv->ssl_ctx.options & SRV_SSL_O_USE_TLSV12)
2983 SSL_CTX_set_ssl_version(srv->ssl_ctx.ctx, TLSv1_2_client_method());
2984#endif
2985
2986 SSL_CTX_set_options(srv->ssl_ctx.ctx, options);
2987 SSL_CTX_set_mode(srv->ssl_ctx.ctx, mode);
Emeric Brun850efd52014-01-29 12:24:34 +01002988
2989 if (global.ssl_server_verify == SSL_SERVER_VERIFY_REQUIRED)
2990 verify = SSL_VERIFY_PEER;
2991
2992 switch (srv->ssl_ctx.verify) {
2993 case SSL_SOCK_VERIFY_NONE:
2994 verify = SSL_VERIFY_NONE;
2995 break;
2996 case SSL_SOCK_VERIFY_REQUIRED:
2997 verify = SSL_VERIFY_PEER;
2998 break;
2999 }
Evan Broderbe554312013-06-27 00:05:25 -07003000 SSL_CTX_set_verify(srv->ssl_ctx.ctx,
Emeric Brun850efd52014-01-29 12:24:34 +01003001 verify,
Evan Broderbe554312013-06-27 00:05:25 -07003002 srv->ssl_ctx.verify_host ? ssl_sock_srv_verifycbk : NULL);
Emeric Brun850efd52014-01-29 12:24:34 +01003003 if (verify & SSL_VERIFY_PEER) {
Emeric Brunef42d922012-10-11 16:11:36 +02003004 if (srv->ssl_ctx.ca_file) {
3005 /* load CAfile to verify */
3006 if (!SSL_CTX_load_verify_locations(srv->ssl_ctx.ctx, srv->ssl_ctx.ca_file, NULL)) {
Willy Tarreau07ba08b2014-02-16 19:22:08 +01003007 Alert("Proxy '%s', server '%s' [%s:%d] unable to load CA file '%s'.\n",
Emeric Brunef42d922012-10-11 16:11:36 +02003008 curproxy->id, srv->id,
3009 srv->conf.file, srv->conf.line, srv->ssl_ctx.ca_file);
3010 cfgerr++;
3011 }
3012 }
Emeric Brun850efd52014-01-29 12:24:34 +01003013 else {
3014 if (global.ssl_server_verify == SSL_SERVER_VERIFY_REQUIRED)
Willy Tarreau07ba08b2014-02-16 19:22:08 +01003015 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 +01003016 curproxy->id, srv->id,
3017 srv->conf.file, srv->conf.line);
3018 else
Willy Tarreau07ba08b2014-02-16 19:22:08 +01003019 Alert("Proxy '%s', server '%s' [%s:%d] verify is enabled but no CA file specified.\n",
Emeric Brun850efd52014-01-29 12:24:34 +01003020 curproxy->id, srv->id,
3021 srv->conf.file, srv->conf.line);
3022 cfgerr++;
3023 }
Emeric Brunef42d922012-10-11 16:11:36 +02003024#ifdef X509_V_FLAG_CRL_CHECK
3025 if (srv->ssl_ctx.crl_file) {
3026 X509_STORE *store = SSL_CTX_get_cert_store(srv->ssl_ctx.ctx);
3027
3028 if (!store || !X509_STORE_load_locations(store, srv->ssl_ctx.crl_file, NULL)) {
Willy Tarreau07ba08b2014-02-16 19:22:08 +01003029 Alert("Proxy '%s', server '%s' [%s:%d] unable to configure CRL file '%s'.\n",
Emeric Brunef42d922012-10-11 16:11:36 +02003030 curproxy->id, srv->id,
3031 srv->conf.file, srv->conf.line, srv->ssl_ctx.crl_file);
3032 cfgerr++;
3033 }
3034 else {
3035 X509_STORE_set_flags(store, X509_V_FLAG_CRL_CHECK|X509_V_FLAG_CRL_CHECK_ALL);
3036 }
3037 }
3038#endif
3039 }
3040
Emeric Brun4f65bff2012-11-16 15:11:00 +01003041 if (global.tune.ssllifetime)
3042 SSL_CTX_set_timeout(srv->ssl_ctx.ctx, global.tune.ssllifetime);
3043
Emeric Brun94324a42012-10-11 14:00:19 +02003044 SSL_CTX_set_session_cache_mode(srv->ssl_ctx.ctx, SSL_SESS_CACHE_OFF);
3045 if (srv->ssl_ctx.ciphers &&
3046 !SSL_CTX_set_cipher_list(srv->ssl_ctx.ctx, srv->ssl_ctx.ciphers)) {
3047 Alert("Proxy '%s', server '%s' [%s:%d] : unable to set SSL cipher list to '%s'.\n",
3048 curproxy->id, srv->id,
3049 srv->conf.file, srv->conf.line, srv->ssl_ctx.ciphers);
3050 cfgerr++;
3051 }
3052
3053 return cfgerr;
3054}
3055
Willy Tarreau2a65ff02012-09-13 17:54:29 +02003056/* Walks down the two trees in bind_conf and prepares all certs. The pointer may
Emeric Brunfc0421f2012-09-07 17:30:07 +02003057 * be NULL, in which case nothing is done. Returns the number of errors
3058 * encountered.
3059 */
Willy Tarreau2a65ff02012-09-13 17:54:29 +02003060int ssl_sock_prepare_all_ctx(struct bind_conf *bind_conf, struct proxy *px)
Emeric Brunfc0421f2012-09-07 17:30:07 +02003061{
3062 struct ebmb_node *node;
3063 struct sni_ctx *sni;
3064 int err = 0;
3065
Willy Tarreau2a65ff02012-09-13 17:54:29 +02003066 if (!bind_conf || !bind_conf->is_ssl)
Emeric Brunfc0421f2012-09-07 17:30:07 +02003067 return 0;
3068
Willy Tarreaufce03112015-01-15 21:32:40 +01003069 /* Automatic memory computations need to know we use SSL there */
3070 global.ssl_used_frontend = 1;
3071
Emeric Brun0bed9942014-10-30 19:25:24 +01003072 if (bind_conf->default_ctx)
3073 err += ssl_sock_prepare_ctx(bind_conf, bind_conf->default_ctx, px);
3074
Willy Tarreau2a65ff02012-09-13 17:54:29 +02003075 node = ebmb_first(&bind_conf->sni_ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02003076 while (node) {
3077 sni = ebmb_entry(node, struct sni_ctx, name);
Emeric Brun0bed9942014-10-30 19:25:24 +01003078 if (!sni->order && sni->ctx != bind_conf->default_ctx)
3079 /* only initialize the CTX on its first occurrence and
3080 if it is not the default_ctx */
Willy Tarreau2a65ff02012-09-13 17:54:29 +02003081 err += ssl_sock_prepare_ctx(bind_conf, sni->ctx, px);
Emeric Brunfc0421f2012-09-07 17:30:07 +02003082 node = ebmb_next(node);
3083 }
3084
Willy Tarreau2a65ff02012-09-13 17:54:29 +02003085 node = ebmb_first(&bind_conf->sni_w_ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02003086 while (node) {
3087 sni = ebmb_entry(node, struct sni_ctx, name);
Emeric Brun0bed9942014-10-30 19:25:24 +01003088 if (!sni->order && sni->ctx != bind_conf->default_ctx)
3089 /* only initialize the CTX on its first occurrence and
3090 if it is not the default_ctx */
Willy Tarreau2a65ff02012-09-13 17:54:29 +02003091 err += ssl_sock_prepare_ctx(bind_conf, sni->ctx, px);
Emeric Brunfc0421f2012-09-07 17:30:07 +02003092 node = ebmb_next(node);
3093 }
3094 return err;
3095}
3096
Christopher Faulet77fe80c2015-07-29 13:02:40 +02003097
3098/* release ssl context allocated for servers. */
3099void ssl_sock_free_srv_ctx(struct server *srv)
3100{
3101 if (srv->ssl_ctx.ctx)
3102 SSL_CTX_free(srv->ssl_ctx.ctx);
3103}
3104
Willy Tarreau2a65ff02012-09-13 17:54:29 +02003105/* Walks down the two trees in bind_conf and frees all the certs. The pointer may
Emeric Brunfc0421f2012-09-07 17:30:07 +02003106 * be NULL, in which case nothing is done. The default_ctx is nullified too.
3107 */
Willy Tarreau2a65ff02012-09-13 17:54:29 +02003108void ssl_sock_free_all_ctx(struct bind_conf *bind_conf)
Emeric Brunfc0421f2012-09-07 17:30:07 +02003109{
3110 struct ebmb_node *node, *back;
3111 struct sni_ctx *sni;
3112
Willy Tarreau2a65ff02012-09-13 17:54:29 +02003113 if (!bind_conf || !bind_conf->is_ssl)
Emeric Brunfc0421f2012-09-07 17:30:07 +02003114 return;
3115
Willy Tarreau2a65ff02012-09-13 17:54:29 +02003116 node = ebmb_first(&bind_conf->sni_ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02003117 while (node) {
3118 sni = ebmb_entry(node, struct sni_ctx, name);
3119 back = ebmb_next(node);
3120 ebmb_delete(node);
3121 if (!sni->order) /* only free the CTX on its first occurrence */
3122 SSL_CTX_free(sni->ctx);
3123 free(sni);
3124 node = back;
3125 }
3126
Willy Tarreau2a65ff02012-09-13 17:54:29 +02003127 node = ebmb_first(&bind_conf->sni_w_ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02003128 while (node) {
3129 sni = ebmb_entry(node, struct sni_ctx, name);
3130 back = ebmb_next(node);
3131 ebmb_delete(node);
3132 if (!sni->order) /* only free the CTX on its first occurrence */
3133 SSL_CTX_free(sni->ctx);
3134 free(sni);
3135 node = back;
3136 }
3137
Willy Tarreau2a65ff02012-09-13 17:54:29 +02003138 bind_conf->default_ctx = NULL;
Emeric Brune1f38db2012-09-03 20:36:47 +02003139}
3140
Christopher Faulet31af49d2015-06-09 17:29:50 +02003141/* Load CA cert file and private key used to generate certificates */
3142int
3143ssl_sock_load_ca(struct bind_conf *bind_conf, struct proxy *px)
3144{
3145 FILE *fp;
3146 X509 *cacert = NULL;
3147 EVP_PKEY *capkey = NULL;
3148 int err = 0;
3149
3150 if (!bind_conf || !bind_conf->generate_certs)
3151 return err;
3152
Willy Tarreaua84c2672015-10-09 12:10:13 +02003153#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Christopher Fauletd2cab922015-07-28 16:03:47 +02003154 if (global.tune.ssl_ctx_cache)
3155 ssl_ctx_lru_tree = lru64_new(global.tune.ssl_ctx_cache);
3156 ssl_ctx_lru_seed = (unsigned int)time(NULL);
Willy Tarreaua84c2672015-10-09 12:10:13 +02003157#endif
Christopher Fauletd2cab922015-07-28 16:03:47 +02003158
Christopher Faulet31af49d2015-06-09 17:29:50 +02003159 if (!bind_conf->ca_sign_file) {
3160 Alert("Proxy '%s': cannot enable certificate generation, "
3161 "no CA certificate File configured at [%s:%d].\n",
3162 px->id, bind_conf->file, bind_conf->line);
Christopher Faulet31af49d2015-06-09 17:29:50 +02003163 goto load_error;
Christopher Fauletc6f02fb2015-10-09 10:53:31 +02003164 }
Christopher Faulet31af49d2015-06-09 17:29:50 +02003165
3166 /* read in the CA certificate */
3167 if (!(fp = fopen(bind_conf->ca_sign_file, "r"))) {
3168 Alert("Proxy '%s': Failed to read CA certificate file '%s' at [%s:%d].\n",
3169 px->id, bind_conf->ca_sign_file, bind_conf->file, bind_conf->line);
Christopher Faulet31af49d2015-06-09 17:29:50 +02003170 goto load_error;
3171 }
3172 if (!(cacert = PEM_read_X509(fp, NULL, NULL, NULL))) {
3173 Alert("Proxy '%s': Failed to read CA certificate file '%s' at [%s:%d].\n",
3174 px->id, bind_conf->ca_sign_file, bind_conf->file, bind_conf->line);
Christopher Fauletc6f02fb2015-10-09 10:53:31 +02003175 goto read_error;
Christopher Faulet31af49d2015-06-09 17:29:50 +02003176 }
Christopher Fauletc6f02fb2015-10-09 10:53:31 +02003177 rewind(fp);
Christopher Faulet31af49d2015-06-09 17:29:50 +02003178 if (!(capkey = PEM_read_PrivateKey(fp, NULL, NULL, bind_conf->ca_sign_pass))) {
3179 Alert("Proxy '%s': Failed to read CA private key file '%s' at [%s:%d].\n",
3180 px->id, bind_conf->ca_sign_file, bind_conf->file, bind_conf->line);
Christopher Fauletc6f02fb2015-10-09 10:53:31 +02003181 goto read_error;
Christopher Faulet31af49d2015-06-09 17:29:50 +02003182 }
Christopher Faulet31af49d2015-06-09 17:29:50 +02003183
Christopher Fauletc6f02fb2015-10-09 10:53:31 +02003184 fclose (fp);
Christopher Faulet31af49d2015-06-09 17:29:50 +02003185 bind_conf->ca_sign_cert = cacert;
3186 bind_conf->ca_sign_pkey = capkey;
3187 return err;
3188
Christopher Fauletc6f02fb2015-10-09 10:53:31 +02003189 read_error:
3190 fclose (fp);
Christopher Faulet31af49d2015-06-09 17:29:50 +02003191 if (capkey) EVP_PKEY_free(capkey);
3192 if (cacert) X509_free(cacert);
Christopher Fauletc6f02fb2015-10-09 10:53:31 +02003193 load_error:
3194 bind_conf->generate_certs = 0;
3195 err++;
Christopher Faulet31af49d2015-06-09 17:29:50 +02003196 return err;
3197}
3198
3199/* Release CA cert and private key used to generate certificated */
3200void
3201ssl_sock_free_ca(struct bind_conf *bind_conf)
3202{
3203 if (!bind_conf)
3204 return;
3205
3206 if (bind_conf->ca_sign_pkey)
3207 EVP_PKEY_free(bind_conf->ca_sign_pkey);
3208 if (bind_conf->ca_sign_cert)
3209 X509_free(bind_conf->ca_sign_cert);
3210}
3211
Emeric Brun46591952012-05-18 15:47:34 +02003212/*
3213 * This function is called if SSL * context is not yet allocated. The function
3214 * is designed to be called before any other data-layer operation and sets the
3215 * handshake flag on the connection. It is safe to call it multiple times.
3216 * It returns 0 on success and -1 in error case.
3217 */
3218static int ssl_sock_init(struct connection *conn)
3219{
3220 /* already initialized */
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02003221 if (conn->xprt_ctx)
Emeric Brun46591952012-05-18 15:47:34 +02003222 return 0;
3223
Willy Tarreau3c728722014-01-23 13:50:42 +01003224 if (!conn_ctrl_ready(conn))
Willy Tarreauf79c8172013-10-21 16:30:56 +02003225 return 0;
3226
Willy Tarreau20879a02012-12-03 16:32:10 +01003227 if (global.maxsslconn && sslconns >= global.maxsslconn) {
3228 conn->err_code = CO_ER_SSL_TOO_MANY;
Willy Tarreau403edff2012-09-06 11:58:37 +02003229 return -1;
Willy Tarreau20879a02012-12-03 16:32:10 +01003230 }
Willy Tarreau403edff2012-09-06 11:58:37 +02003231
Emeric Brun46591952012-05-18 15:47:34 +02003232 /* If it is in client mode initiate SSL session
3233 in connect state otherwise accept state */
Willy Tarreau3fdb3662012-11-12 00:42:33 +01003234 if (objt_server(conn->target)) {
Willy Tarreaufba03cd2014-11-13 13:48:58 +01003235 int may_retry = 1;
3236
3237 retry_connect:
Emeric Brun46591952012-05-18 15:47:34 +02003238 /* Alloc a new SSL session ctx */
Willy Tarreau3fdb3662012-11-12 00:42:33 +01003239 conn->xprt_ctx = SSL_new(objt_server(conn->target)->ssl_ctx.ctx);
Willy Tarreau20879a02012-12-03 16:32:10 +01003240 if (!conn->xprt_ctx) {
Willy Tarreaufba03cd2014-11-13 13:48:58 +01003241 if (may_retry--) {
3242 pool_gc2();
3243 goto retry_connect;
3244 }
Willy Tarreau20879a02012-12-03 16:32:10 +01003245 conn->err_code = CO_ER_SSL_NO_MEM;
Emeric Brun46591952012-05-18 15:47:34 +02003246 return -1;
Willy Tarreau20879a02012-12-03 16:32:10 +01003247 }
Emeric Brun46591952012-05-18 15:47:34 +02003248
Emeric Brun46591952012-05-18 15:47:34 +02003249 /* set fd on SSL session context */
Emeric Brun55476152014-11-12 17:35:37 +01003250 if (!SSL_set_fd(conn->xprt_ctx, conn->t.sock.fd)) {
3251 SSL_free(conn->xprt_ctx);
3252 conn->xprt_ctx = NULL;
Willy Tarreaufba03cd2014-11-13 13:48:58 +01003253 if (may_retry--) {
3254 pool_gc2();
3255 goto retry_connect;
3256 }
Emeric Brun55476152014-11-12 17:35:37 +01003257 conn->err_code = CO_ER_SSL_NO_MEM;
3258 return -1;
3259 }
Emeric Brun46591952012-05-18 15:47:34 +02003260
Evan Broderbe554312013-06-27 00:05:25 -07003261 /* set connection pointer */
Emeric Brun55476152014-11-12 17:35:37 +01003262 if (!SSL_set_app_data(conn->xprt_ctx, conn)) {
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 }
3272
3273 SSL_set_connect_state(conn->xprt_ctx);
3274 if (objt_server(conn->target)->ssl_ctx.reused_sess) {
3275 if(!SSL_set_session(conn->xprt_ctx, objt_server(conn->target)->ssl_ctx.reused_sess)) {
3276 SSL_SESSION_free(objt_server(conn->target)->ssl_ctx.reused_sess);
3277 objt_server(conn->target)->ssl_ctx.reused_sess = NULL;
3278 }
3279 }
Evan Broderbe554312013-06-27 00:05:25 -07003280
Emeric Brun46591952012-05-18 15:47:34 +02003281 /* leave init state and start handshake */
Willy Tarreau05737472012-09-04 08:03:39 +02003282 conn->flags |= CO_FL_SSL_WAIT_HS | CO_FL_WAIT_L6_CONN;
Willy Tarreau403edff2012-09-06 11:58:37 +02003283
3284 sslconns++;
Willy Tarreau71b734c2014-01-28 15:19:44 +01003285 totalsslconns++;
Emeric Brun46591952012-05-18 15:47:34 +02003286 return 0;
3287 }
Willy Tarreau3fdb3662012-11-12 00:42:33 +01003288 else if (objt_listener(conn->target)) {
Willy Tarreaufba03cd2014-11-13 13:48:58 +01003289 int may_retry = 1;
3290
3291 retry_accept:
Emeric Brun46591952012-05-18 15:47:34 +02003292 /* Alloc a new SSL session ctx */
Willy Tarreau3fdb3662012-11-12 00:42:33 +01003293 conn->xprt_ctx = SSL_new(objt_listener(conn->target)->bind_conf->default_ctx);
Willy Tarreau20879a02012-12-03 16:32:10 +01003294 if (!conn->xprt_ctx) {
Willy Tarreaufba03cd2014-11-13 13:48:58 +01003295 if (may_retry--) {
3296 pool_gc2();
3297 goto retry_accept;
3298 }
Willy Tarreau20879a02012-12-03 16:32:10 +01003299 conn->err_code = CO_ER_SSL_NO_MEM;
Emeric Brun46591952012-05-18 15:47:34 +02003300 return -1;
Willy Tarreau20879a02012-12-03 16:32:10 +01003301 }
Emeric Brun46591952012-05-18 15:47:34 +02003302
Emeric Brun46591952012-05-18 15:47:34 +02003303 /* set fd on SSL session context */
Emeric Brun55476152014-11-12 17:35:37 +01003304 if (!SSL_set_fd(conn->xprt_ctx, conn->t.sock.fd)) {
3305 SSL_free(conn->xprt_ctx);
3306 conn->xprt_ctx = NULL;
Willy Tarreaufba03cd2014-11-13 13:48:58 +01003307 if (may_retry--) {
3308 pool_gc2();
3309 goto retry_accept;
3310 }
Emeric Brun55476152014-11-12 17:35:37 +01003311 conn->err_code = CO_ER_SSL_NO_MEM;
3312 return -1;
3313 }
Emeric Brun46591952012-05-18 15:47:34 +02003314
Emeric Brune1f38db2012-09-03 20:36:47 +02003315 /* set connection pointer */
Emeric Brun55476152014-11-12 17:35:37 +01003316 if (!SSL_set_app_data(conn->xprt_ctx, conn)) {
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 }
3326
3327 SSL_set_accept_state(conn->xprt_ctx);
Emeric Brune1f38db2012-09-03 20:36:47 +02003328
Emeric Brun46591952012-05-18 15:47:34 +02003329 /* leave init state and start handshake */
Willy Tarreau05737472012-09-04 08:03:39 +02003330 conn->flags |= CO_FL_SSL_WAIT_HS | CO_FL_WAIT_L6_CONN;
Willy Tarreau403edff2012-09-06 11:58:37 +02003331
3332 sslconns++;
Willy Tarreau71b734c2014-01-28 15:19:44 +01003333 totalsslconns++;
Emeric Brun46591952012-05-18 15:47:34 +02003334 return 0;
3335 }
3336 /* don't know how to handle such a target */
Willy Tarreau20879a02012-12-03 16:32:10 +01003337 conn->err_code = CO_ER_SSL_NO_TARGET;
Emeric Brun46591952012-05-18 15:47:34 +02003338 return -1;
3339}
3340
3341
3342/* This is the callback which is used when an SSL handshake is pending. It
3343 * updates the FD status if it wants some polling before being called again.
3344 * It returns 0 if it fails in a fatal way or needs to poll to go further,
3345 * otherwise it returns non-zero and removes itself from the connection's
3346 * flags (the bit is provided in <flag> by the caller).
3347 */
3348int ssl_sock_handshake(struct connection *conn, unsigned int flag)
3349{
3350 int ret;
3351
Willy Tarreau3c728722014-01-23 13:50:42 +01003352 if (!conn_ctrl_ready(conn))
Willy Tarreauf79c8172013-10-21 16:30:56 +02003353 return 0;
3354
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02003355 if (!conn->xprt_ctx)
Emeric Brun46591952012-05-18 15:47:34 +02003356 goto out_error;
3357
Emeric Brun674b7432012-11-08 19:21:55 +01003358 /* If we use SSL_do_handshake to process a reneg initiated by
3359 * the remote peer, it sometimes returns SSL_ERROR_SSL.
3360 * Usually SSL_write and SSL_read are used and process implicitly
3361 * the reneg handshake.
3362 * Here we use SSL_peek as a workaround for reneg.
3363 */
3364 if ((conn->flags & CO_FL_CONNECTED) && SSL_renegotiate_pending(conn->xprt_ctx)) {
3365 char c;
3366
3367 ret = SSL_peek(conn->xprt_ctx, &c, 1);
3368 if (ret <= 0) {
3369 /* handshake may have not been completed, let's find why */
3370 ret = SSL_get_error(conn->xprt_ctx, ret);
3371 if (ret == SSL_ERROR_WANT_WRITE) {
3372 /* SSL handshake needs to write, L4 connection may not be ready */
3373 __conn_sock_stop_recv(conn);
Willy Tarreaue1f50c42014-01-22 20:02:06 +01003374 __conn_sock_want_send(conn);
3375 fd_cant_send(conn->t.sock.fd);
Emeric Brun674b7432012-11-08 19:21:55 +01003376 return 0;
3377 }
3378 else if (ret == SSL_ERROR_WANT_READ) {
3379 /* handshake may have been completed but we have
3380 * no more data to read.
3381 */
3382 if (!SSL_renegotiate_pending(conn->xprt_ctx)) {
3383 ret = 1;
3384 goto reneg_ok;
3385 }
3386 /* SSL handshake needs to read, L4 connection is ready */
3387 if (conn->flags & CO_FL_WAIT_L4_CONN)
3388 conn->flags &= ~CO_FL_WAIT_L4_CONN;
3389 __conn_sock_stop_send(conn);
Willy Tarreaue1f50c42014-01-22 20:02:06 +01003390 __conn_sock_want_recv(conn);
3391 fd_cant_recv(conn->t.sock.fd);
Emeric Brun674b7432012-11-08 19:21:55 +01003392 return 0;
3393 }
3394 else if (ret == SSL_ERROR_SYSCALL) {
3395 /* if errno is null, then connection was successfully established */
3396 if (!errno && conn->flags & CO_FL_WAIT_L4_CONN)
3397 conn->flags &= ~CO_FL_WAIT_L4_CONN;
Willy Tarreau20879a02012-12-03 16:32:10 +01003398 if (!conn->err_code) {
Emeric Brun29f037d2014-04-25 19:05:36 +02003399 if (!((SSL *)conn->xprt_ctx)->packet_length) {
3400 if (!errno) {
3401 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
3402 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
3403 else
3404 conn->err_code = CO_ER_SSL_EMPTY;
3405 }
3406 else {
3407 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
3408 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
3409 else
3410 conn->err_code = CO_ER_SSL_ABORT;
3411 }
3412 }
3413 else {
3414 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
3415 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
Willy Tarreau20879a02012-12-03 16:32:10 +01003416 else
Emeric Brun29f037d2014-04-25 19:05:36 +02003417 conn->err_code = CO_ER_SSL_HANDSHAKE;
3418 }
Willy Tarreau20879a02012-12-03 16:32:10 +01003419 }
Emeric Brun674b7432012-11-08 19:21:55 +01003420 goto out_error;
3421 }
3422 else {
3423 /* Fail on all other handshake errors */
3424 /* Note: OpenSSL may leave unread bytes in the socket's
3425 * buffer, causing an RST to be emitted upon close() on
3426 * TCP sockets. We first try to drain possibly pending
3427 * data to avoid this as much as possible.
3428 */
Willy Tarreaud85c4852015-03-13 00:40:28 +01003429 conn_sock_drain(conn);
Willy Tarreau20879a02012-12-03 16:32:10 +01003430 if (!conn->err_code)
Willy Tarreauf51c6982014-04-25 20:02:39 +02003431 conn->err_code = (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT) ?
3432 CO_ER_SSL_KILLED_HB : CO_ER_SSL_HANDSHAKE;
Emeric Brun674b7432012-11-08 19:21:55 +01003433 goto out_error;
3434 }
3435 }
3436 /* read some data: consider handshake completed */
3437 goto reneg_ok;
3438 }
3439
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02003440 ret = SSL_do_handshake(conn->xprt_ctx);
Emeric Brun46591952012-05-18 15:47:34 +02003441 if (ret != 1) {
3442 /* handshake did not complete, let's find why */
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02003443 ret = SSL_get_error(conn->xprt_ctx, ret);
Emeric Brun46591952012-05-18 15:47:34 +02003444
3445 if (ret == SSL_ERROR_WANT_WRITE) {
3446 /* SSL handshake needs to write, L4 connection may not be ready */
3447 __conn_sock_stop_recv(conn);
Willy Tarreaue1f50c42014-01-22 20:02:06 +01003448 __conn_sock_want_send(conn);
3449 fd_cant_send(conn->t.sock.fd);
Emeric Brun46591952012-05-18 15:47:34 +02003450 return 0;
3451 }
3452 else if (ret == SSL_ERROR_WANT_READ) {
3453 /* SSL handshake needs to read, L4 connection is ready */
3454 if (conn->flags & CO_FL_WAIT_L4_CONN)
3455 conn->flags &= ~CO_FL_WAIT_L4_CONN;
3456 __conn_sock_stop_send(conn);
Willy Tarreaue1f50c42014-01-22 20:02:06 +01003457 __conn_sock_want_recv(conn);
3458 fd_cant_recv(conn->t.sock.fd);
Emeric Brun46591952012-05-18 15:47:34 +02003459 return 0;
3460 }
Willy Tarreau89230192012-09-28 20:22:13 +02003461 else if (ret == SSL_ERROR_SYSCALL) {
3462 /* if errno is null, then connection was successfully established */
3463 if (!errno && conn->flags & CO_FL_WAIT_L4_CONN)
3464 conn->flags &= ~CO_FL_WAIT_L4_CONN;
Willy Tarreau20879a02012-12-03 16:32:10 +01003465
Emeric Brun29f037d2014-04-25 19:05:36 +02003466 if (!((SSL *)conn->xprt_ctx)->packet_length) {
3467 if (!errno) {
3468 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
3469 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
3470 else
3471 conn->err_code = CO_ER_SSL_EMPTY;
3472 }
3473 else {
3474 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
3475 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
3476 else
3477 conn->err_code = CO_ER_SSL_ABORT;
3478 }
3479 }
3480 else {
3481 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
3482 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
Willy Tarreau20879a02012-12-03 16:32:10 +01003483 else
Emeric Brun29f037d2014-04-25 19:05:36 +02003484 conn->err_code = CO_ER_SSL_HANDSHAKE;
3485 }
Willy Tarreau89230192012-09-28 20:22:13 +02003486 goto out_error;
3487 }
Emeric Brun46591952012-05-18 15:47:34 +02003488 else {
3489 /* Fail on all other handshake errors */
Willy Tarreau566dc552012-10-19 20:52:18 +02003490 /* Note: OpenSSL may leave unread bytes in the socket's
3491 * buffer, causing an RST to be emitted upon close() on
3492 * TCP sockets. We first try to drain possibly pending
3493 * data to avoid this as much as possible.
3494 */
Willy Tarreaud85c4852015-03-13 00:40:28 +01003495 conn_sock_drain(conn);
Willy Tarreau20879a02012-12-03 16:32:10 +01003496 if (!conn->err_code)
Willy Tarreauf51c6982014-04-25 20:02:39 +02003497 conn->err_code = (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT) ?
3498 CO_ER_SSL_KILLED_HB : CO_ER_SSL_HANDSHAKE;
Emeric Brun46591952012-05-18 15:47:34 +02003499 goto out_error;
3500 }
3501 }
3502
Emeric Brun674b7432012-11-08 19:21:55 +01003503reneg_ok:
Emeric Brun46591952012-05-18 15:47:34 +02003504 /* Handshake succeeded */
Willy Tarreau0c9c2722014-05-28 12:28:58 +02003505 if (!SSL_session_reused(conn->xprt_ctx)) {
3506 if (objt_server(conn->target)) {
3507 update_freq_ctr(&global.ssl_be_keys_per_sec, 1);
3508 if (global.ssl_be_keys_per_sec.curr_ctr > global.ssl_be_keys_max)
3509 global.ssl_be_keys_max = global.ssl_be_keys_per_sec.curr_ctr;
3510
Emeric Brun46591952012-05-18 15:47:34 +02003511 /* check if session was reused, if not store current session on server for reuse */
Willy Tarreau3fdb3662012-11-12 00:42:33 +01003512 if (objt_server(conn->target)->ssl_ctx.reused_sess)
3513 SSL_SESSION_free(objt_server(conn->target)->ssl_ctx.reused_sess);
Emeric Brun46591952012-05-18 15:47:34 +02003514
Willy Tarreau2a3fb1c2015-02-05 16:47:07 +01003515 if (!(objt_server(conn->target)->ssl_ctx.options & SRV_SSL_O_NO_REUSE))
3516 objt_server(conn->target)->ssl_ctx.reused_sess = SSL_get1_session(conn->xprt_ctx);
Emeric Brun46591952012-05-18 15:47:34 +02003517 }
Willy Tarreau0c9c2722014-05-28 12:28:58 +02003518 else {
3519 update_freq_ctr(&global.ssl_fe_keys_per_sec, 1);
3520 if (global.ssl_fe_keys_per_sec.curr_ctr > global.ssl_fe_keys_max)
3521 global.ssl_fe_keys_max = global.ssl_fe_keys_per_sec.curr_ctr;
3522 }
Emeric Brun46591952012-05-18 15:47:34 +02003523 }
3524
3525 /* The connection is now established at both layers, it's time to leave */
3526 conn->flags &= ~(flag | CO_FL_WAIT_L4_CONN | CO_FL_WAIT_L6_CONN);
3527 return 1;
3528
3529 out_error:
Emeric Brun644cde02012-12-14 11:21:13 +01003530 /* Clear openssl global errors stack */
3531 ERR_clear_error();
3532
Emeric Brun9fa89732012-10-04 17:09:56 +02003533 /* free resumed session if exists */
Willy Tarreau3fdb3662012-11-12 00:42:33 +01003534 if (objt_server(conn->target) && objt_server(conn->target)->ssl_ctx.reused_sess) {
3535 SSL_SESSION_free(objt_server(conn->target)->ssl_ctx.reused_sess);
3536 objt_server(conn->target)->ssl_ctx.reused_sess = NULL;
Emeric Brun9fa89732012-10-04 17:09:56 +02003537 }
3538
Emeric Brun46591952012-05-18 15:47:34 +02003539 /* Fail on all other handshake errors */
3540 conn->flags |= CO_FL_ERROR;
Willy Tarreau20879a02012-12-03 16:32:10 +01003541 if (!conn->err_code)
3542 conn->err_code = CO_ER_SSL_HANDSHAKE;
Emeric Brun46591952012-05-18 15:47:34 +02003543 return 0;
3544}
3545
3546/* Receive up to <count> bytes from connection <conn>'s socket and store them
Willy Tarreauabf08d92014-01-14 11:31:27 +01003547 * into buffer <buf>. Only one call to recv() is performed, unless the
Emeric Brun46591952012-05-18 15:47:34 +02003548 * buffer wraps, in which case a second call may be performed. The connection's
3549 * flags are updated with whatever special event is detected (error, read0,
3550 * empty). The caller is responsible for taking care of those events and
3551 * avoiding the call if inappropriate. The function does not call the
3552 * connection's polling update function, so the caller is responsible for this.
3553 */
3554static int ssl_sock_to_buf(struct connection *conn, struct buffer *buf, int count)
3555{
3556 int ret, done = 0;
Willy Tarreauabf08d92014-01-14 11:31:27 +01003557 int try;
Emeric Brun46591952012-05-18 15:47:34 +02003558
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02003559 if (!conn->xprt_ctx)
Emeric Brun46591952012-05-18 15:47:34 +02003560 goto out_error;
3561
3562 if (conn->flags & CO_FL_HANDSHAKE)
3563 /* a handshake was requested */
3564 return 0;
3565
Willy Tarreauabf08d92014-01-14 11:31:27 +01003566 /* let's realign the buffer to optimize I/O */
3567 if (buffer_empty(buf))
Emeric Brun46591952012-05-18 15:47:34 +02003568 buf->p = buf->data;
Emeric Brun46591952012-05-18 15:47:34 +02003569
3570 /* read the largest possible block. For this, we perform only one call
3571 * to recv() unless the buffer wraps and we exactly fill the first hunk,
3572 * in which case we accept to do it once again. A new attempt is made on
3573 * EINTR too.
3574 */
Willy Tarreau00b0fb92014-01-17 11:09:40 +01003575 while (count > 0) {
Willy Tarreauabf08d92014-01-14 11:31:27 +01003576 /* first check if we have some room after p+i */
3577 try = buf->data + buf->size - (buf->p + buf->i);
3578 /* otherwise continue between data and p-o */
3579 if (try <= 0) {
3580 try = buf->p - (buf->data + buf->o);
3581 if (try <= 0)
3582 break;
3583 }
3584 if (try > count)
3585 try = count;
3586
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02003587 ret = SSL_read(conn->xprt_ctx, bi_end(buf), try);
Emeric Brune1f38db2012-09-03 20:36:47 +02003588 if (conn->flags & CO_FL_ERROR) {
3589 /* CO_FL_ERROR may be set by ssl_sock_infocbk */
Emeric Brun644cde02012-12-14 11:21:13 +01003590 goto out_error;
Emeric Brune1f38db2012-09-03 20:36:47 +02003591 }
Emeric Brun46591952012-05-18 15:47:34 +02003592 if (ret > 0) {
3593 buf->i += ret;
3594 done += ret;
3595 if (ret < try)
3596 break;
3597 count -= ret;
Emeric Brun46591952012-05-18 15:47:34 +02003598 }
3599 else if (ret == 0) {
Emeric Brun644cde02012-12-14 11:21:13 +01003600 ret = SSL_get_error(conn->xprt_ctx, ret);
3601 if (ret != SSL_ERROR_ZERO_RETURN) {
Emeric Brun1c646862012-12-14 12:33:41 +01003602 /* error on protocol or underlying transport */
3603 if ((ret != SSL_ERROR_SYSCALL)
3604 || (errno && (errno != EAGAIN)))
3605 conn->flags |= CO_FL_ERROR;
3606
Emeric Brun644cde02012-12-14 11:21:13 +01003607 /* Clear openssl global errors stack */
3608 ERR_clear_error();
3609 }
Emeric Brun46591952012-05-18 15:47:34 +02003610 goto read0;
3611 }
3612 else {
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02003613 ret = SSL_get_error(conn->xprt_ctx, ret);
Emeric Brun46591952012-05-18 15:47:34 +02003614 if (ret == SSL_ERROR_WANT_WRITE) {
Emeric Brun8af8dd12012-11-08 17:56:20 +01003615 /* handshake is running, and it needs to enable write */
Emeric Brun46591952012-05-18 15:47:34 +02003616 conn->flags |= CO_FL_SSL_WAIT_HS;
Emeric Brun8af8dd12012-11-08 17:56:20 +01003617 __conn_sock_want_send(conn);
Emeric Brun46591952012-05-18 15:47:34 +02003618 break;
3619 }
3620 else if (ret == SSL_ERROR_WANT_READ) {
Emeric Brun282a76a2012-11-08 18:02:56 +01003621 if (SSL_renegotiate_pending(conn->xprt_ctx)) {
3622 /* handshake is running, and it may need to re-enable read */
3623 conn->flags |= CO_FL_SSL_WAIT_HS;
3624 __conn_sock_want_recv(conn);
3625 break;
3626 }
Emeric Brun46591952012-05-18 15:47:34 +02003627 /* we need to poll for retry a read later */
Willy Tarreaue1f50c42014-01-22 20:02:06 +01003628 fd_cant_recv(conn->t.sock.fd);
Emeric Brun46591952012-05-18 15:47:34 +02003629 break;
3630 }
3631 /* otherwise it's a real error */
3632 goto out_error;
3633 }
3634 }
3635 return done;
3636
3637 read0:
3638 conn_sock_read0(conn);
3639 return done;
3640 out_error:
Emeric Brun644cde02012-12-14 11:21:13 +01003641 /* Clear openssl global errors stack */
3642 ERR_clear_error();
3643
Emeric Brun46591952012-05-18 15:47:34 +02003644 conn->flags |= CO_FL_ERROR;
3645 return done;
3646}
3647
3648
3649/* Send all pending bytes from buffer <buf> to connection <conn>'s socket.
Willy Tarreau1049b1f2014-02-02 01:51:17 +01003650 * <flags> may contain some CO_SFL_* flags to hint the system about other
3651 * pending data for example, but this flag is ignored at the moment.
Emeric Brun46591952012-05-18 15:47:34 +02003652 * Only one call to send() is performed, unless the buffer wraps, in which case
3653 * a second call may be performed. The connection's flags are updated with
3654 * whatever special event is detected (error, empty). The caller is responsible
3655 * for taking care of those events and avoiding the call if inappropriate. The
3656 * function does not call the connection's polling update function, so the caller
3657 * is responsible for this.
3658 */
3659static int ssl_sock_from_buf(struct connection *conn, struct buffer *buf, int flags)
3660{
3661 int ret, try, done;
3662
3663 done = 0;
3664
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02003665 if (!conn->xprt_ctx)
Emeric Brun46591952012-05-18 15:47:34 +02003666 goto out_error;
3667
3668 if (conn->flags & CO_FL_HANDSHAKE)
3669 /* a handshake was requested */
3670 return 0;
3671
3672 /* send the largest possible block. For this we perform only one call
3673 * to send() unless the buffer wraps and we exactly fill the first hunk,
3674 * in which case we accept to do it once again.
3675 */
3676 while (buf->o) {
Kevin Hestercad82342013-05-30 15:12:41 -07003677 try = bo_contig_data(buf);
Willy Tarreaubfd59462013-02-21 07:46:09 +01003678
Willy Tarreau7bed9452014-02-02 02:00:24 +01003679 if (!(flags & CO_SFL_STREAMER) &&
Willy Tarreau518cedd2014-02-17 15:43:01 +01003680 !(conn->xprt_st & SSL_SOCK_SEND_UNLIMITED) &&
3681 global.tune.ssl_max_record && try > global.tune.ssl_max_record) {
Willy Tarreaubfd59462013-02-21 07:46:09 +01003682 try = global.tune.ssl_max_record;
Willy Tarreau518cedd2014-02-17 15:43:01 +01003683 }
3684 else {
3685 /* we need to keep the information about the fact that
3686 * we're not limiting the upcoming send(), because if it
3687 * fails, we'll have to retry with at least as many data.
3688 */
3689 conn->xprt_st |= SSL_SOCK_SEND_UNLIMITED;
3690 }
Willy Tarreaubfd59462013-02-21 07:46:09 +01003691
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02003692 ret = SSL_write(conn->xprt_ctx, bo_ptr(buf), try);
Willy Tarreau518cedd2014-02-17 15:43:01 +01003693
Emeric Brune1f38db2012-09-03 20:36:47 +02003694 if (conn->flags & CO_FL_ERROR) {
3695 /* CO_FL_ERROR may be set by ssl_sock_infocbk */
Emeric Brun644cde02012-12-14 11:21:13 +01003696 goto out_error;
Emeric Brune1f38db2012-09-03 20:36:47 +02003697 }
Emeric Brun46591952012-05-18 15:47:34 +02003698 if (ret > 0) {
Willy Tarreau518cedd2014-02-17 15:43:01 +01003699 conn->xprt_st &= ~SSL_SOCK_SEND_UNLIMITED;
3700
Emeric Brun46591952012-05-18 15:47:34 +02003701 buf->o -= ret;
3702 done += ret;
3703
Willy Tarreau5fb38032012-12-16 19:39:09 +01003704 if (likely(buffer_empty(buf)))
Emeric Brun46591952012-05-18 15:47:34 +02003705 /* optimize data alignment in the buffer */
3706 buf->p = buf->data;
3707
3708 /* if the system buffer is full, don't insist */
3709 if (ret < try)
3710 break;
3711 }
3712 else {
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02003713 ret = SSL_get_error(conn->xprt_ctx, ret);
Emeric Brun46591952012-05-18 15:47:34 +02003714 if (ret == SSL_ERROR_WANT_WRITE) {
Emeric Brun282a76a2012-11-08 18:02:56 +01003715 if (SSL_renegotiate_pending(conn->xprt_ctx)) {
3716 /* handshake is running, and it may need to re-enable write */
3717 conn->flags |= CO_FL_SSL_WAIT_HS;
3718 __conn_sock_want_send(conn);
3719 break;
3720 }
Emeric Brun46591952012-05-18 15:47:34 +02003721 /* we need to poll to retry a write later */
Willy Tarreaue1f50c42014-01-22 20:02:06 +01003722 fd_cant_send(conn->t.sock.fd);
Emeric Brun46591952012-05-18 15:47:34 +02003723 break;
3724 }
3725 else if (ret == SSL_ERROR_WANT_READ) {
Emeric Brun8af8dd12012-11-08 17:56:20 +01003726 /* handshake is running, and it needs to enable read */
Emeric Brun46591952012-05-18 15:47:34 +02003727 conn->flags |= CO_FL_SSL_WAIT_HS;
Emeric Brun8af8dd12012-11-08 17:56:20 +01003728 __conn_sock_want_recv(conn);
Emeric Brun46591952012-05-18 15:47:34 +02003729 break;
3730 }
3731 goto out_error;
3732 }
3733 }
3734 return done;
3735
3736 out_error:
Emeric Brun644cde02012-12-14 11:21:13 +01003737 /* Clear openssl global errors stack */
3738 ERR_clear_error();
3739
Emeric Brun46591952012-05-18 15:47:34 +02003740 conn->flags |= CO_FL_ERROR;
3741 return done;
3742}
3743
Emeric Brun46591952012-05-18 15:47:34 +02003744static void ssl_sock_close(struct connection *conn) {
3745
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02003746 if (conn->xprt_ctx) {
3747 SSL_free(conn->xprt_ctx);
3748 conn->xprt_ctx = NULL;
Willy Tarreau403edff2012-09-06 11:58:37 +02003749 sslconns--;
Emeric Brun46591952012-05-18 15:47:34 +02003750 }
Emeric Brun46591952012-05-18 15:47:34 +02003751}
3752
3753/* This function tries to perform a clean shutdown on an SSL connection, and in
3754 * any case, flags the connection as reusable if no handshake was in progress.
3755 */
3756static void ssl_sock_shutw(struct connection *conn, int clean)
3757{
3758 if (conn->flags & CO_FL_HANDSHAKE)
3759 return;
3760 /* no handshake was in progress, try a clean ssl shutdown */
Emeric Brun644cde02012-12-14 11:21:13 +01003761 if (clean && (SSL_shutdown(conn->xprt_ctx) <= 0)) {
3762 /* Clear openssl global errors stack */
3763 ERR_clear_error();
3764 }
Emeric Brun46591952012-05-18 15:47:34 +02003765
3766 /* force flag on ssl to keep session in cache regardless shutdown result */
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02003767 SSL_set_shutdown(conn->xprt_ctx, SSL_SENT_SHUTDOWN);
Emeric Brun46591952012-05-18 15:47:34 +02003768}
3769
Willy Tarreauffc3fcd2012-10-12 20:17:54 +02003770/* used for logging, may be changed for a sample fetch later */
3771const char *ssl_sock_get_cipher_name(struct connection *conn)
3772{
3773 if (!conn->xprt && !conn->xprt_ctx)
3774 return NULL;
3775 return SSL_get_cipher_name(conn->xprt_ctx);
3776}
3777
3778/* used for logging, may be changed for a sample fetch later */
3779const char *ssl_sock_get_proto_version(struct connection *conn)
3780{
3781 if (!conn->xprt && !conn->xprt_ctx)
3782 return NULL;
3783 return SSL_get_version(conn->xprt_ctx);
3784}
3785
Willy Tarreau8d598402012-10-22 17:58:39 +02003786/* Extract a serial from a cert, and copy it to a chunk.
3787 * Returns 1 if serial is found and copied, 0 if no serial found and
3788 * -1 if output is not large enough.
3789 */
3790static int
3791ssl_sock_get_serial(X509 *crt, struct chunk *out)
3792{
3793 ASN1_INTEGER *serial;
3794
3795 serial = X509_get_serialNumber(crt);
3796 if (!serial)
3797 return 0;
3798
3799 if (out->size < serial->length)
3800 return -1;
3801
3802 memcpy(out->str, serial->data, serial->length);
3803 out->len = serial->length;
3804 return 1;
3805}
3806
Emeric Brun43e79582014-10-29 19:03:26 +01003807/* Extract a cert to der, and copy it to a chunk.
3808 * Returns 1 if cert is found and copied, 0 on der convertion failure and
3809 * -1 if output is not large enough.
3810 */
3811static int
3812ssl_sock_crt2der(X509 *crt, struct chunk *out)
3813{
3814 int len;
3815 unsigned char *p = (unsigned char *)out->str;;
3816
3817 len =i2d_X509(crt, NULL);
3818 if (len <= 0)
3819 return 1;
3820
3821 if (out->size < len)
3822 return -1;
3823
3824 i2d_X509(crt,&p);
3825 out->len = len;
3826 return 1;
3827}
3828
Emeric Brunce5ad802012-10-22 14:11:22 +02003829
3830/* Copy Date in ASN1_UTCTIME format in struct chunk out.
3831 * Returns 1 if serial is found and copied, 0 if no valid time found
3832 * and -1 if output is not large enough.
3833 */
3834static int
3835ssl_sock_get_time(ASN1_TIME *tm, struct chunk *out)
3836{
3837 if (tm->type == V_ASN1_GENERALIZEDTIME) {
3838 ASN1_GENERALIZEDTIME *gentm = (ASN1_GENERALIZEDTIME *)tm;
3839
3840 if (gentm->length < 12)
3841 return 0;
3842 if (gentm->data[0] != 0x32 || gentm->data[1] != 0x30)
3843 return 0;
3844 if (out->size < gentm->length-2)
3845 return -1;
3846
3847 memcpy(out->str, gentm->data+2, gentm->length-2);
3848 out->len = gentm->length-2;
3849 return 1;
3850 }
3851 else if (tm->type == V_ASN1_UTCTIME) {
3852 ASN1_UTCTIME *utctm = (ASN1_UTCTIME *)tm;
3853
3854 if (utctm->length < 10)
3855 return 0;
3856 if (utctm->data[0] >= 0x35)
3857 return 0;
3858 if (out->size < utctm->length)
3859 return -1;
3860
3861 memcpy(out->str, utctm->data, utctm->length);
3862 out->len = utctm->length;
3863 return 1;
3864 }
3865
3866 return 0;
3867}
3868
Emeric Brun87855892012-10-17 17:39:35 +02003869/* Extract an entry from a X509_NAME and copy its value to an output chunk.
3870 * Returns 1 if entry found, 0 if entry not found, or -1 if output not large enough.
3871 */
3872static int
3873ssl_sock_get_dn_entry(X509_NAME *a, const struct chunk *entry, int pos, struct chunk *out)
3874{
3875 X509_NAME_ENTRY *ne;
3876 int i, j, n;
3877 int cur = 0;
3878 const char *s;
3879 char tmp[128];
3880
3881 out->len = 0;
3882 for (i = 0; i < sk_X509_NAME_ENTRY_num(a->entries); i++) {
3883 if (pos < 0)
3884 j = (sk_X509_NAME_ENTRY_num(a->entries)-1) - i;
3885 else
3886 j = i;
3887
3888 ne = sk_X509_NAME_ENTRY_value(a->entries, j);
3889 n = OBJ_obj2nid(ne->object);
3890 if ((n == NID_undef) || ((s = OBJ_nid2sn(n)) == NULL)) {
3891 i2t_ASN1_OBJECT(tmp, sizeof(tmp), ne->object);
3892 s = tmp;
3893 }
3894
3895 if (chunk_strcasecmp(entry, s) != 0)
3896 continue;
3897
3898 if (pos < 0)
3899 cur--;
3900 else
3901 cur++;
3902
3903 if (cur != pos)
3904 continue;
3905
3906 if (ne->value->length > out->size)
3907 return -1;
3908
3909 memcpy(out->str, ne->value->data, ne->value->length);
3910 out->len = ne->value->length;
3911 return 1;
3912 }
3913
3914 return 0;
3915
3916}
3917
3918/* Extract and format full DN from a X509_NAME and copy result into a chunk
3919 * Returns 1 if dn entries exits, 0 if no dn entry found or -1 if output is not large enough.
3920 */
3921static int
3922ssl_sock_get_dn_oneline(X509_NAME *a, struct chunk *out)
3923{
3924 X509_NAME_ENTRY *ne;
3925 int i, n, ln;
3926 int l = 0;
3927 const char *s;
3928 char *p;
3929 char tmp[128];
3930
3931 out->len = 0;
3932 p = out->str;
3933 for (i = 0; i < sk_X509_NAME_ENTRY_num(a->entries); i++) {
3934 ne = sk_X509_NAME_ENTRY_value(a->entries, i);
3935 n = OBJ_obj2nid(ne->object);
3936 if ((n == NID_undef) || ((s = OBJ_nid2sn(n)) == NULL)) {
3937 i2t_ASN1_OBJECT(tmp, sizeof(tmp), ne->object);
3938 s = tmp;
3939 }
3940 ln = strlen(s);
3941
3942 l += 1 + ln + 1 + ne->value->length;
3943 if (l > out->size)
3944 return -1;
3945 out->len = l;
3946
3947 *(p++)='/';
3948 memcpy(p, s, ln);
3949 p += ln;
3950 *(p++)='=';
3951 memcpy(p, ne->value->data, ne->value->length);
3952 p += ne->value->length;
3953 }
3954
3955 if (!out->len)
3956 return 0;
3957
3958 return 1;
3959}
3960
David Safb76832014-05-08 23:42:08 -04003961char *ssl_sock_get_version(struct connection *conn)
3962{
3963 if (!ssl_sock_is_ssl(conn))
3964 return NULL;
3965
3966 return (char *)SSL_get_version(conn->xprt_ctx);
3967}
3968
Willy Tarreau63076412015-07-10 11:33:32 +02003969void ssl_sock_set_servername(struct connection *conn, const char *hostname)
3970{
3971#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
3972 if (!ssl_sock_is_ssl(conn))
3973 return;
3974
3975 SSL_set_tlsext_host_name(conn->xprt_ctx, hostname);
3976#endif
3977}
3978
Emeric Brun0abf8362014-06-24 18:26:41 +02003979/* Extract peer certificate's common name into the chunk dest
3980 * Returns
3981 * the len of the extracted common name
3982 * or 0 if no CN found in DN
3983 * or -1 on error case (i.e. no peer certificate)
3984 */
3985int ssl_sock_get_remote_common_name(struct connection *conn, struct chunk *dest)
David Safb76832014-05-08 23:42:08 -04003986{
3987 X509 *crt = NULL;
3988 X509_NAME *name;
David Safb76832014-05-08 23:42:08 -04003989 const char find_cn[] = "CN";
3990 const struct chunk find_cn_chunk = {
3991 .str = (char *)&find_cn,
3992 .len = sizeof(find_cn)-1
3993 };
Emeric Brun0abf8362014-06-24 18:26:41 +02003994 int result = -1;
David Safb76832014-05-08 23:42:08 -04003995
3996 if (!ssl_sock_is_ssl(conn))
Emeric Brun0abf8362014-06-24 18:26:41 +02003997 goto out;
David Safb76832014-05-08 23:42:08 -04003998
3999 /* SSL_get_peer_certificate, it increase X509 * ref count */
4000 crt = SSL_get_peer_certificate(conn->xprt_ctx);
4001 if (!crt)
4002 goto out;
4003
4004 name = X509_get_subject_name(crt);
4005 if (!name)
4006 goto out;
David Safb76832014-05-08 23:42:08 -04004007
Emeric Brun0abf8362014-06-24 18:26:41 +02004008 result = ssl_sock_get_dn_entry(name, &find_cn_chunk, 1, dest);
4009out:
David Safb76832014-05-08 23:42:08 -04004010 if (crt)
4011 X509_free(crt);
4012
4013 return result;
4014}
4015
Dave McCowan328fb582014-07-30 10:39:13 -04004016/* returns 1 if client passed a certificate for this session, 0 if not */
4017int ssl_sock_get_cert_used_sess(struct connection *conn)
4018{
4019 X509 *crt = NULL;
4020
4021 if (!ssl_sock_is_ssl(conn))
4022 return 0;
4023
4024 /* SSL_get_peer_certificate, it increase X509 * ref count */
4025 crt = SSL_get_peer_certificate(conn->xprt_ctx);
4026 if (!crt)
4027 return 0;
4028
4029 X509_free(crt);
4030 return 1;
4031}
4032
4033/* returns 1 if client passed a certificate for this connection, 0 if not */
4034int ssl_sock_get_cert_used_conn(struct connection *conn)
David Safb76832014-05-08 23:42:08 -04004035{
4036 if (!ssl_sock_is_ssl(conn))
4037 return 0;
4038
4039 return SSL_SOCK_ST_FL_VERIFY_DONE & conn->xprt_st ? 1 : 0;
4040}
4041
4042/* returns result from SSL verify */
4043unsigned int ssl_sock_get_verify_result(struct connection *conn)
4044{
4045 if (!ssl_sock_is_ssl(conn))
4046 return (unsigned int)X509_V_ERR_APPLICATION_VERIFICATION;
4047
4048 return (unsigned int)SSL_get_verify_result(conn->xprt_ctx);
4049}
4050
Willy Tarreau7875d092012-09-10 08:20:03 +02004051/***** Below are some sample fetching functions for ACL/patterns *****/
4052
Emeric Brune64aef12012-09-21 13:15:06 +02004053/* boolean, returns true if client cert was present */
4054static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004055smp_fetch_ssl_fc_has_crt(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brune64aef12012-09-21 13:15:06 +02004056{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004057 struct connection *conn;
4058
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004059 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004060 if (!conn || conn->xprt != &ssl_sock)
Emeric Brune64aef12012-09-21 13:15:06 +02004061 return 0;
4062
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004063 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brune64aef12012-09-21 13:15:06 +02004064 smp->flags |= SMP_F_MAY_CHANGE;
4065 return 0;
4066 }
4067
4068 smp->flags = 0;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004069 smp->data.type = SMP_T_BOOL;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004070 smp->data.u.sint = SSL_SOCK_ST_FL_VERIFY_DONE & conn->xprt_st ? 1 : 0;
Emeric Brune64aef12012-09-21 13:15:06 +02004071
4072 return 1;
4073}
4074
Emeric Brun43e79582014-10-29 19:03:26 +01004075/* binary, returns a certificate in a binary chunk (der/raw).
4076 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
4077 * should be use.
4078 */
4079static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004080smp_fetch_ssl_x_der(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun43e79582014-10-29 19:03:26 +01004081{
4082 int cert_peer = (kw[4] == 'c') ? 1 : 0;
4083 X509 *crt = NULL;
4084 int ret = 0;
4085 struct chunk *smp_trash;
4086 struct connection *conn;
4087
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004088 conn = objt_conn(smp->sess->origin);
Emeric Brun43e79582014-10-29 19:03:26 +01004089 if (!conn || conn->xprt != &ssl_sock)
4090 return 0;
4091
4092 if (!(conn->flags & CO_FL_CONNECTED)) {
4093 smp->flags |= SMP_F_MAY_CHANGE;
4094 return 0;
4095 }
4096
4097 if (cert_peer)
4098 crt = SSL_get_peer_certificate(conn->xprt_ctx);
4099 else
4100 crt = SSL_get_certificate(conn->xprt_ctx);
4101
4102 if (!crt)
4103 goto out;
4104
4105 smp_trash = get_trash_chunk();
4106 if (ssl_sock_crt2der(crt, smp_trash) <= 0)
4107 goto out;
4108
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004109 smp->data.u.str = *smp_trash;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004110 smp->data.type = SMP_T_BIN;
Emeric Brun43e79582014-10-29 19:03:26 +01004111 ret = 1;
4112out:
4113 /* SSL_get_peer_certificate, it increase X509 * ref count */
4114 if (cert_peer && crt)
4115 X509_free(crt);
4116 return ret;
4117}
4118
Emeric Brunba841a12014-04-30 17:05:08 +02004119/* binary, returns serial of certificate in a binary chunk.
4120 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
4121 * should be use.
4122 */
Willy Tarreau8d598402012-10-22 17:58:39 +02004123static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004124smp_fetch_ssl_x_serial(const struct arg *args, struct sample *smp, const char *kw, void *private)
Willy Tarreau8d598402012-10-22 17:58:39 +02004125{
Emeric Brunba841a12014-04-30 17:05:08 +02004126 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Willy Tarreau8d598402012-10-22 17:58:39 +02004127 X509 *crt = NULL;
4128 int ret = 0;
4129 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004130 struct connection *conn;
4131
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004132 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004133 if (!conn || conn->xprt != &ssl_sock)
Willy Tarreau8d598402012-10-22 17:58:39 +02004134 return 0;
4135
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004136 if (!(conn->flags & CO_FL_CONNECTED)) {
Willy Tarreau8d598402012-10-22 17:58:39 +02004137 smp->flags |= SMP_F_MAY_CHANGE;
4138 return 0;
4139 }
4140
Emeric Brunba841a12014-04-30 17:05:08 +02004141 if (cert_peer)
4142 crt = SSL_get_peer_certificate(conn->xprt_ctx);
4143 else
4144 crt = SSL_get_certificate(conn->xprt_ctx);
4145
Willy Tarreau8d598402012-10-22 17:58:39 +02004146 if (!crt)
4147 goto out;
4148
Willy Tarreau47ca5452012-12-23 20:22:19 +01004149 smp_trash = get_trash_chunk();
Willy Tarreau8d598402012-10-22 17:58:39 +02004150 if (ssl_sock_get_serial(crt, smp_trash) <= 0)
4151 goto out;
4152
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004153 smp->data.u.str = *smp_trash;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004154 smp->data.type = SMP_T_BIN;
Willy Tarreau8d598402012-10-22 17:58:39 +02004155 ret = 1;
4156out:
Emeric Brunba841a12014-04-30 17:05:08 +02004157 /* SSL_get_peer_certificate, it increase X509 * ref count */
4158 if (cert_peer && crt)
Willy Tarreau8d598402012-10-22 17:58:39 +02004159 X509_free(crt);
4160 return ret;
4161}
Emeric Brune64aef12012-09-21 13:15:06 +02004162
Emeric Brunba841a12014-04-30 17:05:08 +02004163/* binary, returns the client certificate's SHA-1 fingerprint (SHA-1 hash of DER-encoded certificate) in a binary chunk.
4164 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
4165 * should be use.
4166 */
James Votha051b4a2013-05-14 20:37:59 +02004167static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004168smp_fetch_ssl_x_sha1(const struct arg *args, struct sample *smp, const char *kw, void *private)
James Votha051b4a2013-05-14 20:37:59 +02004169{
Emeric Brunba841a12014-04-30 17:05:08 +02004170 int cert_peer = (kw[4] == 'c') ? 1 : 0;
James Votha051b4a2013-05-14 20:37:59 +02004171 X509 *crt = NULL;
4172 const EVP_MD *digest;
4173 int ret = 0;
4174 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004175 struct connection *conn;
James Votha051b4a2013-05-14 20:37:59 +02004176
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004177 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004178 if (!conn || conn->xprt != &ssl_sock)
4179 return 0;
4180
4181 if (!(conn->flags & CO_FL_CONNECTED)) {
James Votha051b4a2013-05-14 20:37:59 +02004182 smp->flags |= SMP_F_MAY_CHANGE;
4183 return 0;
4184 }
4185
Emeric Brunba841a12014-04-30 17:05:08 +02004186 if (cert_peer)
4187 crt = SSL_get_peer_certificate(conn->xprt_ctx);
4188 else
4189 crt = SSL_get_certificate(conn->xprt_ctx);
James Votha051b4a2013-05-14 20:37:59 +02004190 if (!crt)
4191 goto out;
4192
4193 smp_trash = get_trash_chunk();
4194 digest = EVP_sha1();
4195 X509_digest(crt, digest, (unsigned char *)smp_trash->str, (unsigned int *)&smp_trash->len);
4196
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004197 smp->data.u.str = *smp_trash;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004198 smp->data.type = SMP_T_BIN;
James Votha051b4a2013-05-14 20:37:59 +02004199 ret = 1;
4200out:
Emeric Brunba841a12014-04-30 17:05:08 +02004201 /* SSL_get_peer_certificate, it increase X509 * ref count */
4202 if (cert_peer && crt)
James Votha051b4a2013-05-14 20:37:59 +02004203 X509_free(crt);
4204 return ret;
4205}
4206
Emeric Brunba841a12014-04-30 17:05:08 +02004207/* string, returns certificate's notafter date in ASN1_UTCTIME format.
4208 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
4209 * should be use.
4210 */
Emeric Brunce5ad802012-10-22 14:11:22 +02004211static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004212smp_fetch_ssl_x_notafter(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brunce5ad802012-10-22 14:11:22 +02004213{
Emeric Brunba841a12014-04-30 17:05:08 +02004214 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brunce5ad802012-10-22 14:11:22 +02004215 X509 *crt = NULL;
4216 int ret = 0;
4217 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004218 struct connection *conn;
Emeric Brunce5ad802012-10-22 14:11:22 +02004219
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004220 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004221 if (!conn || conn->xprt != &ssl_sock)
4222 return 0;
4223
4224 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunce5ad802012-10-22 14:11:22 +02004225 smp->flags |= SMP_F_MAY_CHANGE;
4226 return 0;
4227 }
4228
Emeric Brunba841a12014-04-30 17:05:08 +02004229 if (cert_peer)
4230 crt = SSL_get_peer_certificate(conn->xprt_ctx);
4231 else
4232 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brunce5ad802012-10-22 14:11:22 +02004233 if (!crt)
4234 goto out;
4235
Willy Tarreau47ca5452012-12-23 20:22:19 +01004236 smp_trash = get_trash_chunk();
Emeric Brunce5ad802012-10-22 14:11:22 +02004237 if (ssl_sock_get_time(X509_get_notAfter(crt), smp_trash) <= 0)
4238 goto out;
4239
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004240 smp->data.u.str = *smp_trash;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004241 smp->data.type = SMP_T_STR;
Emeric Brunce5ad802012-10-22 14:11:22 +02004242 ret = 1;
4243out:
Emeric Brunba841a12014-04-30 17:05:08 +02004244 /* SSL_get_peer_certificate, it increase X509 * ref count */
4245 if (cert_peer && crt)
Emeric Brunce5ad802012-10-22 14:11:22 +02004246 X509_free(crt);
4247 return ret;
4248}
4249
Emeric Brunba841a12014-04-30 17:05:08 +02004250/* string, returns a string of a formatted full dn \C=..\O=..\OU=.. \CN=.. of certificate's issuer
4251 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
4252 * should be use.
4253 */
Emeric Brun87855892012-10-17 17:39:35 +02004254static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004255smp_fetch_ssl_x_i_dn(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun87855892012-10-17 17:39:35 +02004256{
Emeric Brunba841a12014-04-30 17:05:08 +02004257 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brun87855892012-10-17 17:39:35 +02004258 X509 *crt = NULL;
4259 X509_NAME *name;
4260 int ret = 0;
4261 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004262 struct connection *conn;
Emeric Brun87855892012-10-17 17:39:35 +02004263
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004264 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004265 if (!conn || conn->xprt != &ssl_sock)
4266 return 0;
4267
4268 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun87855892012-10-17 17:39:35 +02004269 smp->flags |= SMP_F_MAY_CHANGE;
4270 return 0;
4271 }
4272
Emeric Brunba841a12014-04-30 17:05:08 +02004273 if (cert_peer)
4274 crt = SSL_get_peer_certificate(conn->xprt_ctx);
4275 else
4276 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brun87855892012-10-17 17:39:35 +02004277 if (!crt)
4278 goto out;
4279
4280 name = X509_get_issuer_name(crt);
4281 if (!name)
4282 goto out;
4283
Willy Tarreau47ca5452012-12-23 20:22:19 +01004284 smp_trash = get_trash_chunk();
Emeric Brun87855892012-10-17 17:39:35 +02004285 if (args && args[0].type == ARGT_STR) {
4286 int pos = 1;
4287
4288 if (args[1].type == ARGT_SINT)
4289 pos = args[1].data.sint;
Emeric Brun87855892012-10-17 17:39:35 +02004290
4291 if (ssl_sock_get_dn_entry(name, &args[0].data.str, pos, smp_trash) <= 0)
4292 goto out;
4293 }
4294 else if (ssl_sock_get_dn_oneline(name, smp_trash) <= 0)
4295 goto out;
4296
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004297 smp->data.type = SMP_T_STR;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004298 smp->data.u.str = *smp_trash;
Emeric Brun87855892012-10-17 17:39:35 +02004299 ret = 1;
4300out:
Emeric Brunba841a12014-04-30 17:05:08 +02004301 /* SSL_get_peer_certificate, it increase X509 * ref count */
4302 if (cert_peer && crt)
Emeric Brun87855892012-10-17 17:39:35 +02004303 X509_free(crt);
4304 return ret;
4305}
4306
Emeric Brunba841a12014-04-30 17:05:08 +02004307/* string, returns notbefore date in ASN1_UTCTIME format.
4308 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
4309 * should be use.
4310 */
Emeric Brunce5ad802012-10-22 14:11:22 +02004311static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004312smp_fetch_ssl_x_notbefore(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brunce5ad802012-10-22 14:11:22 +02004313{
Emeric Brunba841a12014-04-30 17:05:08 +02004314 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brunce5ad802012-10-22 14:11:22 +02004315 X509 *crt = NULL;
4316 int ret = 0;
4317 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004318 struct connection *conn;
4319
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004320 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004321 if (!conn || conn->xprt != &ssl_sock)
Emeric Brunce5ad802012-10-22 14:11:22 +02004322 return 0;
4323
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004324 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunce5ad802012-10-22 14:11:22 +02004325 smp->flags |= SMP_F_MAY_CHANGE;
4326 return 0;
4327 }
4328
Emeric Brunba841a12014-04-30 17:05:08 +02004329 if (cert_peer)
4330 crt = SSL_get_peer_certificate(conn->xprt_ctx);
4331 else
4332 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brunce5ad802012-10-22 14:11:22 +02004333 if (!crt)
4334 goto out;
4335
Willy Tarreau47ca5452012-12-23 20:22:19 +01004336 smp_trash = get_trash_chunk();
Emeric Brunce5ad802012-10-22 14:11:22 +02004337 if (ssl_sock_get_time(X509_get_notBefore(crt), smp_trash) <= 0)
4338 goto out;
4339
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004340 smp->data.u.str = *smp_trash;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004341 smp->data.type = SMP_T_STR;
Emeric Brunce5ad802012-10-22 14:11:22 +02004342 ret = 1;
4343out:
Emeric Brunba841a12014-04-30 17:05:08 +02004344 /* SSL_get_peer_certificate, it increase X509 * ref count */
4345 if (cert_peer && crt)
Emeric Brunce5ad802012-10-22 14:11:22 +02004346 X509_free(crt);
4347 return ret;
4348}
4349
Emeric Brunba841a12014-04-30 17:05:08 +02004350/* string, returns a string of a formatted full dn \C=..\O=..\OU=.. \CN=.. of certificate's subject
4351 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
4352 * should be use.
4353 */
Emeric Brun87855892012-10-17 17:39:35 +02004354static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004355smp_fetch_ssl_x_s_dn(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun87855892012-10-17 17:39:35 +02004356{
Emeric Brunba841a12014-04-30 17:05:08 +02004357 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brun87855892012-10-17 17:39:35 +02004358 X509 *crt = NULL;
4359 X509_NAME *name;
4360 int ret = 0;
4361 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004362 struct connection *conn;
Emeric Brun87855892012-10-17 17:39:35 +02004363
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004364 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004365 if (!conn || conn->xprt != &ssl_sock)
4366 return 0;
4367
4368 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun87855892012-10-17 17:39:35 +02004369 smp->flags |= SMP_F_MAY_CHANGE;
4370 return 0;
4371 }
4372
Emeric Brunba841a12014-04-30 17:05:08 +02004373 if (cert_peer)
4374 crt = SSL_get_peer_certificate(conn->xprt_ctx);
4375 else
4376 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brun87855892012-10-17 17:39:35 +02004377 if (!crt)
4378 goto out;
4379
4380 name = X509_get_subject_name(crt);
4381 if (!name)
4382 goto out;
4383
Willy Tarreau47ca5452012-12-23 20:22:19 +01004384 smp_trash = get_trash_chunk();
Emeric Brun87855892012-10-17 17:39:35 +02004385 if (args && args[0].type == ARGT_STR) {
4386 int pos = 1;
4387
4388 if (args[1].type == ARGT_SINT)
4389 pos = args[1].data.sint;
Emeric Brun87855892012-10-17 17:39:35 +02004390
4391 if (ssl_sock_get_dn_entry(name, &args[0].data.str, pos, smp_trash) <= 0)
4392 goto out;
4393 }
4394 else if (ssl_sock_get_dn_oneline(name, smp_trash) <= 0)
4395 goto out;
4396
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004397 smp->data.type = SMP_T_STR;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004398 smp->data.u.str = *smp_trash;
Emeric Brun87855892012-10-17 17:39:35 +02004399 ret = 1;
4400out:
Emeric Brunba841a12014-04-30 17:05:08 +02004401 /* SSL_get_peer_certificate, it increase X509 * ref count */
4402 if (cert_peer && crt)
Emeric Brun87855892012-10-17 17:39:35 +02004403 X509_free(crt);
4404 return ret;
4405}
Emeric Brun9143d372012-12-20 15:44:16 +01004406
4407/* integer, returns true if current session use a client certificate */
4408static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004409smp_fetch_ssl_c_used(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun9143d372012-12-20 15:44:16 +01004410{
4411 X509 *crt;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004412 struct connection *conn;
Emeric Brun9143d372012-12-20 15:44:16 +01004413
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004414 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004415 if (!conn || conn->xprt != &ssl_sock)
4416 return 0;
4417
4418 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun9143d372012-12-20 15:44:16 +01004419 smp->flags |= SMP_F_MAY_CHANGE;
4420 return 0;
4421 }
4422
4423 /* SSL_get_peer_certificate returns a ptr on allocated X509 struct */
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004424 crt = SSL_get_peer_certificate(conn->xprt_ctx);
Emeric Brun9143d372012-12-20 15:44:16 +01004425 if (crt) {
4426 X509_free(crt);
4427 }
4428
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004429 smp->data.type = SMP_T_BOOL;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004430 smp->data.u.sint = (crt != NULL);
Emeric Brun9143d372012-12-20 15:44:16 +01004431 return 1;
4432}
4433
Emeric Brunba841a12014-04-30 17:05:08 +02004434/* integer, returns the certificate version
4435 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
4436 * should be use.
4437 */
Emeric Bruna7359fd2012-10-17 15:03:11 +02004438static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004439smp_fetch_ssl_x_version(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Bruna7359fd2012-10-17 15:03:11 +02004440{
Emeric Brunba841a12014-04-30 17:05:08 +02004441 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Bruna7359fd2012-10-17 15:03:11 +02004442 X509 *crt;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004443 struct connection *conn;
4444
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004445 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004446 if (!conn || conn->xprt != &ssl_sock)
Emeric Bruna7359fd2012-10-17 15:03:11 +02004447 return 0;
4448
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004449 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Bruna7359fd2012-10-17 15:03:11 +02004450 smp->flags |= SMP_F_MAY_CHANGE;
4451 return 0;
4452 }
4453
Emeric Brunba841a12014-04-30 17:05:08 +02004454 if (cert_peer)
4455 crt = SSL_get_peer_certificate(conn->xprt_ctx);
4456 else
4457 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Bruna7359fd2012-10-17 15:03:11 +02004458 if (!crt)
4459 return 0;
4460
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004461 smp->data.u.sint = (unsigned int)(1 + X509_get_version(crt));
Emeric Brunba841a12014-04-30 17:05:08 +02004462 /* SSL_get_peer_certificate increase X509 * ref count */
4463 if (cert_peer)
4464 X509_free(crt);
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004465 smp->data.type = SMP_T_SINT;
Emeric Bruna7359fd2012-10-17 15:03:11 +02004466
4467 return 1;
4468}
4469
Emeric Brunba841a12014-04-30 17:05:08 +02004470/* string, returns the certificate's signature algorithm.
4471 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
4472 * should be use.
4473 */
Emeric Brun7f56e742012-10-19 18:15:40 +02004474static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004475smp_fetch_ssl_x_sig_alg(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun7f56e742012-10-19 18:15:40 +02004476{
Emeric Brunba841a12014-04-30 17:05:08 +02004477 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brun7f56e742012-10-19 18:15:40 +02004478 X509 *crt;
4479 int nid;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004480 struct connection *conn;
Emeric Brun7f56e742012-10-19 18:15:40 +02004481
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004482 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004483 if (!conn || conn->xprt != &ssl_sock)
4484 return 0;
4485
4486 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun7f56e742012-10-19 18:15:40 +02004487 smp->flags |= SMP_F_MAY_CHANGE;
4488 return 0;
4489 }
4490
Emeric Brunba841a12014-04-30 17:05:08 +02004491 if (cert_peer)
4492 crt = SSL_get_peer_certificate(conn->xprt_ctx);
4493 else
4494 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brun7f56e742012-10-19 18:15:40 +02004495 if (!crt)
4496 return 0;
4497
4498 nid = OBJ_obj2nid((ASN1_OBJECT *)(crt->cert_info->signature->algorithm));
4499
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004500 smp->data.u.str.str = (char *)OBJ_nid2sn(nid);
4501 if (!smp->data.u.str.str) {
Emeric Brunba841a12014-04-30 17:05:08 +02004502 /* SSL_get_peer_certificate increase X509 * ref count */
4503 if (cert_peer)
4504 X509_free(crt);
Emeric Brun7f56e742012-10-19 18:15:40 +02004505 return 0;
Emeric Brun9bf3ba22013-10-07 14:31:44 +02004506 }
Emeric Brun7f56e742012-10-19 18:15:40 +02004507
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004508 smp->data.type = SMP_T_STR;
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01004509 smp->flags |= SMP_F_CONST;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004510 smp->data.u.str.len = strlen(smp->data.u.str.str);
Emeric Brunba841a12014-04-30 17:05:08 +02004511 /* SSL_get_peer_certificate increase X509 * ref count */
4512 if (cert_peer)
4513 X509_free(crt);
Emeric Brun7f56e742012-10-19 18:15:40 +02004514
4515 return 1;
4516}
4517
Emeric Brunba841a12014-04-30 17:05:08 +02004518/* string, returns the certificate's key algorithm.
4519 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
4520 * should be use.
4521 */
Emeric Brun521a0112012-10-22 12:22:55 +02004522static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004523smp_fetch_ssl_x_key_alg(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun521a0112012-10-22 12:22:55 +02004524{
Emeric Brunba841a12014-04-30 17:05:08 +02004525 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brun521a0112012-10-22 12:22:55 +02004526 X509 *crt;
4527 int nid;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004528 struct connection *conn;
Emeric Brun521a0112012-10-22 12:22:55 +02004529
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004530 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004531 if (!conn || conn->xprt != &ssl_sock)
4532 return 0;
4533
4534 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun521a0112012-10-22 12:22:55 +02004535 smp->flags |= SMP_F_MAY_CHANGE;
4536 return 0;
4537 }
4538
Emeric Brunba841a12014-04-30 17:05:08 +02004539 if (cert_peer)
4540 crt = SSL_get_peer_certificate(conn->xprt_ctx);
4541 else
4542 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brun521a0112012-10-22 12:22:55 +02004543 if (!crt)
4544 return 0;
4545
4546 nid = OBJ_obj2nid((ASN1_OBJECT *)(crt->cert_info->key->algor->algorithm));
4547
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004548 smp->data.u.str.str = (char *)OBJ_nid2sn(nid);
4549 if (!smp->data.u.str.str) {
Emeric Brunba841a12014-04-30 17:05:08 +02004550 /* SSL_get_peer_certificate increase X509 * ref count */
4551 if (cert_peer)
4552 X509_free(crt);
Emeric Brun521a0112012-10-22 12:22:55 +02004553 return 0;
Emeric Brun9bf3ba22013-10-07 14:31:44 +02004554 }
Emeric Brun521a0112012-10-22 12:22:55 +02004555
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004556 smp->data.type = SMP_T_STR;
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01004557 smp->flags |= SMP_F_CONST;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004558 smp->data.u.str.len = strlen(smp->data.u.str.str);
Emeric Brunba841a12014-04-30 17:05:08 +02004559 if (cert_peer)
4560 X509_free(crt);
Emeric Brun521a0112012-10-22 12:22:55 +02004561
4562 return 1;
4563}
4564
Emeric Brun645ae792014-04-30 14:21:06 +02004565/* boolean, returns true if front conn. transport layer is SSL.
4566 * This function is also usable on backend conn if the fetch keyword 5th
4567 * char is 'b'.
4568 */
Willy Tarreau7875d092012-09-10 08:20:03 +02004569static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004570smp_fetch_ssl_fc(const struct arg *args, struct sample *smp, const char *kw, void *private)
Willy Tarreau7875d092012-09-10 08:20:03 +02004571{
Emeric Brun645ae792014-04-30 14:21:06 +02004572 int back_conn = (kw[4] == 'b') ? 1 : 0;
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004573 struct connection *conn = objt_conn(smp->strm->si[back_conn].end);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004574
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004575 smp->data.type = SMP_T_BOOL;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004576 smp->data.u.sint = (conn && conn->xprt == &ssl_sock);
Willy Tarreau7875d092012-09-10 08:20:03 +02004577 return 1;
4578}
4579
Emeric Brun2525b6b2012-10-18 15:59:43 +02004580/* boolean, returns true if client present a SNI */
Willy Tarreau7875d092012-09-10 08:20:03 +02004581static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004582smp_fetch_ssl_fc_has_sni(const struct arg *args, struct sample *smp, const char *kw, void *private)
Willy Tarreau7875d092012-09-10 08:20:03 +02004583{
4584#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004585 struct connection *conn = objt_conn(smp->sess->origin);
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 Tarreaub363a1f2013-10-01 10:45:07 +02004589 conn->xprt_ctx &&
4590 SSL_get_servername(conn->xprt_ctx, TLSEXT_NAMETYPE_host_name) != NULL;
Willy Tarreau7875d092012-09-10 08:20:03 +02004591 return 1;
4592#else
4593 return 0;
4594#endif
4595}
4596
Nenad Merdanovic26ea8222015-05-18 02:28:57 +02004597/* boolean, returns true if client session has been resumed */
4598static int
4599smp_fetch_ssl_fc_is_resumed(const struct arg *args, struct sample *smp, const char *kw, void *private)
4600{
4601 struct connection *conn = objt_conn(smp->sess->origin);
4602
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004603 smp->data.type = SMP_T_BOOL;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004604 smp->data.u.sint = (conn && conn->xprt == &ssl_sock) &&
Nenad Merdanovic26ea8222015-05-18 02:28:57 +02004605 conn->xprt_ctx &&
4606 SSL_session_reused(conn->xprt_ctx);
4607 return 1;
4608}
4609
Emeric Brun645ae792014-04-30 14:21:06 +02004610/* string, returns the used cipher if front conn. transport layer is SSL.
4611 * This function is also usable on backend conn if the fetch keyword 5th
4612 * char is 'b'.
4613 */
Emeric Brun589fcad2012-10-16 14:13:26 +02004614static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004615smp_fetch_ssl_fc_cipher(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun589fcad2012-10-16 14:13:26 +02004616{
Emeric Brun645ae792014-04-30 14:21:06 +02004617 int back_conn = (kw[4] == 'b') ? 1 : 0;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004618 struct connection *conn;
4619
Emeric Brun589fcad2012-10-16 14:13:26 +02004620 smp->flags = 0;
4621
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004622 conn = objt_conn(smp->strm->si[back_conn].end);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004623 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
Emeric Brun589fcad2012-10-16 14:13:26 +02004624 return 0;
4625
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004626 smp->data.u.str.str = (char *)SSL_get_cipher_name(conn->xprt_ctx);
4627 if (!smp->data.u.str.str)
Emeric Brun589fcad2012-10-16 14:13:26 +02004628 return 0;
4629
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004630 smp->data.type = SMP_T_STR;
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01004631 smp->flags |= SMP_F_CONST;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004632 smp->data.u.str.len = strlen(smp->data.u.str.str);
Emeric Brun589fcad2012-10-16 14:13:26 +02004633
4634 return 1;
4635}
4636
Emeric Brun645ae792014-04-30 14:21:06 +02004637/* integer, returns the algoritm's keysize if front conn. transport layer
4638 * is SSL.
4639 * This function is also usable on backend conn if the fetch keyword 5th
4640 * char is 'b'.
4641 */
Emeric Brun589fcad2012-10-16 14:13:26 +02004642static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004643smp_fetch_ssl_fc_alg_keysize(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun589fcad2012-10-16 14:13:26 +02004644{
Emeric Brun645ae792014-04-30 14:21:06 +02004645 int back_conn = (kw[4] == 'b') ? 1 : 0;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004646 struct connection *conn;
Thierry FOURNIER07ee64e2015-07-06 23:43:03 +02004647 int sint;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004648
Emeric Brun589fcad2012-10-16 14:13:26 +02004649 smp->flags = 0;
4650
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004651 conn = objt_conn(smp->strm->si[back_conn].end);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004652 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
Emeric Brun589fcad2012-10-16 14:13:26 +02004653 return 0;
4654
Thierry FOURNIER07ee64e2015-07-06 23:43:03 +02004655 if (!SSL_get_cipher_bits(conn->xprt_ctx, &sint))
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004656 return 0;
4657
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004658 smp->data.u.sint = sint;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004659 smp->data.type = SMP_T_SINT;
Emeric Brun589fcad2012-10-16 14:13:26 +02004660
4661 return 1;
4662}
4663
Emeric Brun645ae792014-04-30 14:21:06 +02004664/* integer, returns the used keysize if front conn. transport layer is SSL.
4665 * This function is also usable on backend conn if the fetch keyword 5th
4666 * char is 'b'.
4667 */
Emeric Brun589fcad2012-10-16 14:13:26 +02004668static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004669smp_fetch_ssl_fc_use_keysize(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun589fcad2012-10-16 14:13:26 +02004670{
Emeric Brun645ae792014-04-30 14:21:06 +02004671 int back_conn = (kw[4] == 'b') ? 1 : 0;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004672 struct connection *conn;
4673
Emeric Brun589fcad2012-10-16 14:13:26 +02004674 smp->flags = 0;
4675
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004676 conn = objt_conn(smp->strm->si[back_conn].end);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004677 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
4678 return 0;
4679
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004680 smp->data.u.sint = (unsigned int)SSL_get_cipher_bits(conn->xprt_ctx, NULL);
4681 if (!smp->data.u.sint)
Emeric Brun589fcad2012-10-16 14:13:26 +02004682 return 0;
4683
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004684 smp->data.type = SMP_T_SINT;
Emeric Brun589fcad2012-10-16 14:13:26 +02004685
4686 return 1;
4687}
4688
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02004689#ifdef OPENSSL_NPN_NEGOTIATED
Willy Tarreau7875d092012-09-10 08:20:03 +02004690static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004691smp_fetch_ssl_fc_npn(const struct arg *args, struct sample *smp, const char *kw, void *private)
Willy Tarreaua33c6542012-10-15 13:19:06 +02004692{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004693 struct connection *conn;
4694
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01004695 smp->flags = SMP_F_CONST;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004696 smp->data.type = SMP_T_STR;
Willy Tarreaua33c6542012-10-15 13:19:06 +02004697
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004698 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004699 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
4700 return 0;
4701
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004702 smp->data.u.str.str = NULL;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004703 SSL_get0_next_proto_negotiated(conn->xprt_ctx,
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004704 (const unsigned char **)&smp->data.u.str.str, (unsigned *)&smp->data.u.str.len);
Willy Tarreaua33c6542012-10-15 13:19:06 +02004705
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004706 if (!smp->data.u.str.str)
Willy Tarreaua33c6542012-10-15 13:19:06 +02004707 return 0;
4708
4709 return 1;
Willy Tarreaua33c6542012-10-15 13:19:06 +02004710}
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02004711#endif
Willy Tarreaua33c6542012-10-15 13:19:06 +02004712
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01004713#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Willy Tarreauab861d32013-04-02 02:30:41 +02004714static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004715smp_fetch_ssl_fc_alpn(const struct arg *args, struct sample *smp, const char *kw, void *private)
Willy Tarreauab861d32013-04-02 02:30:41 +02004716{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004717 struct connection *conn;
4718
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01004719 smp->flags = SMP_F_CONST;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004720 smp->data.type = SMP_T_STR;
Willy Tarreauab861d32013-04-02 02:30:41 +02004721
Willy Tarreaue26bf052015-05-12 10:30:12 +02004722 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004723 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
Willy Tarreauab861d32013-04-02 02:30:41 +02004724 return 0;
4725
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004726 smp->data.u.str.str = NULL;
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01004727 SSL_get0_alpn_selected(conn->xprt_ctx,
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004728 (const unsigned char **)&smp->data.u.str.str, (unsigned *)&smp->data.u.str.len);
Willy Tarreauab861d32013-04-02 02:30:41 +02004729
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004730 if (!smp->data.u.str.str)
Willy Tarreauab861d32013-04-02 02:30:41 +02004731 return 0;
4732
4733 return 1;
4734}
4735#endif
4736
Emeric Brun645ae792014-04-30 14:21:06 +02004737/* string, returns the used protocol if front conn. transport layer is SSL.
4738 * This function is also usable on backend conn if the fetch keyword 5th
4739 * char is 'b'.
4740 */
Willy Tarreaua33c6542012-10-15 13:19:06 +02004741static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004742smp_fetch_ssl_fc_protocol(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun589fcad2012-10-16 14:13:26 +02004743{
Emeric Brun645ae792014-04-30 14:21:06 +02004744 int back_conn = (kw[4] == 'b') ? 1 : 0;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004745 struct connection *conn;
4746
Emeric Brun589fcad2012-10-16 14:13:26 +02004747 smp->flags = 0;
4748
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004749 conn = objt_conn(smp->strm->si[back_conn].end);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004750 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
4751 return 0;
4752
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004753 smp->data.u.str.str = (char *)SSL_get_version(conn->xprt_ctx);
4754 if (!smp->data.u.str.str)
Emeric Brun589fcad2012-10-16 14:13:26 +02004755 return 0;
4756
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004757 smp->data.type = SMP_T_STR;
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01004758 smp->flags = SMP_F_CONST;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004759 smp->data.u.str.len = strlen(smp->data.u.str.str);
Emeric Brun589fcad2012-10-16 14:13:26 +02004760
4761 return 1;
4762}
4763
Willy Tarreau87b09662015-04-03 00:22:06 +02004764/* binary, returns the SSL stream id if front conn. transport layer is SSL.
Emeric Brun645ae792014-04-30 14:21:06 +02004765 * This function is also usable on backend conn if the fetch keyword 5th
4766 * char is 'b'.
4767 */
Emeric Brun589fcad2012-10-16 14:13:26 +02004768static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004769smp_fetch_ssl_fc_session_id(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brunfe68f682012-10-16 14:59:28 +02004770{
4771#if OPENSSL_VERSION_NUMBER > 0x0090800fL
Emeric Brun645ae792014-04-30 14:21:06 +02004772 int back_conn = (kw[4] == 'b') ? 1 : 0;
Willy Tarreau192252e2015-04-04 01:47:55 +02004773 SSL_SESSION *ssl_sess;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004774 struct connection *conn;
Emeric Brunfe68f682012-10-16 14:59:28 +02004775
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01004776 smp->flags = SMP_F_CONST;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004777 smp->data.type = SMP_T_BIN;
Emeric Brunfe68f682012-10-16 14:59:28 +02004778
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004779 conn = objt_conn(smp->strm->si[back_conn].end);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004780 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
4781 return 0;
4782
Willy Tarreau192252e2015-04-04 01:47:55 +02004783 ssl_sess = SSL_get_session(conn->xprt_ctx);
4784 if (!ssl_sess)
Emeric Brunfe68f682012-10-16 14:59:28 +02004785 return 0;
4786
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004787 smp->data.u.str.str = (char *)SSL_SESSION_get_id(ssl_sess, (unsigned int *)&smp->data.u.str.len);
4788 if (!smp->data.u.str.str || !smp->data.u.str.len)
Emeric Brunfe68f682012-10-16 14:59:28 +02004789 return 0;
4790
4791 return 1;
4792#else
4793 return 0;
4794#endif
4795}
4796
4797static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004798smp_fetch_ssl_fc_sni(const struct arg *args, struct sample *smp, const char *kw, void *private)
Willy Tarreau7875d092012-09-10 08:20:03 +02004799{
4800#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004801 struct connection *conn;
4802
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01004803 smp->flags = SMP_F_CONST;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004804 smp->data.type = SMP_T_STR;
Willy Tarreau7875d092012-09-10 08:20:03 +02004805
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004806 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004807 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
4808 return 0;
4809
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004810 smp->data.u.str.str = (char *)SSL_get_servername(conn->xprt_ctx, TLSEXT_NAMETYPE_host_name);
4811 if (!smp->data.u.str.str)
Willy Tarreau3e394c92012-09-14 23:56:58 +02004812 return 0;
4813
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004814 smp->data.u.str.len = strlen(smp->data.u.str.str);
Willy Tarreau7875d092012-09-10 08:20:03 +02004815 return 1;
4816#else
4817 return 0;
4818#endif
4819}
4820
David Sc1ad52e2014-04-08 18:48:47 -04004821static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004822smp_fetch_ssl_fc_unique_id(const struct arg *args, struct sample *smp, const char *kw, void *private)
David Sc1ad52e2014-04-08 18:48:47 -04004823{
4824#if OPENSSL_VERSION_NUMBER > 0x0090800fL
Emeric Brun645ae792014-04-30 14:21:06 +02004825 int back_conn = (kw[4] == 'b') ? 1 : 0;
David Sc1ad52e2014-04-08 18:48:47 -04004826 struct connection *conn;
4827 int finished_len;
David Sc1ad52e2014-04-08 18:48:47 -04004828 struct chunk *finished_trash;
David Sc1ad52e2014-04-08 18:48:47 -04004829
4830 smp->flags = 0;
4831
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004832 conn = objt_conn(smp->strm->si[back_conn].end);
David Sc1ad52e2014-04-08 18:48:47 -04004833 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
4834 return 0;
4835
4836 if (!(conn->flags & CO_FL_CONNECTED)) {
4837 smp->flags |= SMP_F_MAY_CHANGE;
4838 return 0;
4839 }
4840
4841 finished_trash = get_trash_chunk();
4842 if (!SSL_session_reused(conn->xprt_ctx))
4843 finished_len = SSL_get_peer_finished(conn->xprt_ctx, finished_trash->str, finished_trash->size);
4844 else
4845 finished_len = SSL_get_finished(conn->xprt_ctx, finished_trash->str, finished_trash->size);
4846
4847 if (!finished_len)
4848 return 0;
4849
Emeric Brunb73a9b02014-04-30 18:49:19 +02004850 finished_trash->len = finished_len;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004851 smp->data.u.str = *finished_trash;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004852 smp->data.type = SMP_T_BIN;
David Sc1ad52e2014-04-08 18:48:47 -04004853
4854 return 1;
4855#else
4856 return 0;
4857#endif
4858}
4859
Emeric Brun2525b6b2012-10-18 15:59:43 +02004860/* integer, returns the first verify error in CA chain of client certificate chain. */
Emeric Brunf282a812012-09-21 15:27:54 +02004861static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004862smp_fetch_ssl_c_ca_err(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brunf282a812012-09-21 15:27:54 +02004863{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004864 struct connection *conn;
4865
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004866 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004867 if (!conn || conn->xprt != &ssl_sock)
4868 return 0;
4869
4870 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunf282a812012-09-21 15:27:54 +02004871 smp->flags = SMP_F_MAY_CHANGE;
4872 return 0;
4873 }
4874
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004875 smp->data.type = SMP_T_SINT;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004876 smp->data.u.sint = (unsigned long long int)SSL_SOCK_ST_TO_CA_ERROR(conn->xprt_st);
Emeric Brunf282a812012-09-21 15:27:54 +02004877 smp->flags = 0;
4878
4879 return 1;
4880}
4881
Emeric Brun2525b6b2012-10-18 15:59:43 +02004882/* integer, returns the depth of the first verify error in CA chain of client certificate chain. */
Emeric Brunf282a812012-09-21 15:27:54 +02004883static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004884smp_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 +02004885{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004886 struct connection *conn;
4887
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004888 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004889 if (!conn || conn->xprt != &ssl_sock)
Emeric Brunf282a812012-09-21 15:27:54 +02004890 return 0;
4891
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004892 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunf282a812012-09-21 15:27:54 +02004893 smp->flags = SMP_F_MAY_CHANGE;
4894 return 0;
4895 }
4896
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004897 smp->data.type = SMP_T_SINT;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004898 smp->data.u.sint = (long long int)SSL_SOCK_ST_TO_CAEDEPTH(conn->xprt_st);
Emeric Brunf282a812012-09-21 15:27:54 +02004899 smp->flags = 0;
4900
4901 return 1;
4902}
4903
Emeric Brun2525b6b2012-10-18 15:59:43 +02004904/* integer, returns the first verify error on client certificate */
Emeric Brunf282a812012-09-21 15:27:54 +02004905static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004906smp_fetch_ssl_c_err(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brunf282a812012-09-21 15:27:54 +02004907{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004908 struct connection *conn;
4909
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004910 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004911 if (!conn || conn->xprt != &ssl_sock)
4912 return 0;
4913
4914 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunf282a812012-09-21 15:27:54 +02004915 smp->flags = SMP_F_MAY_CHANGE;
4916 return 0;
4917 }
4918
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004919 smp->data.type = SMP_T_SINT;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004920 smp->data.u.sint = (long long int)SSL_SOCK_ST_TO_CRTERROR(conn->xprt_st);
Emeric Brunf282a812012-09-21 15:27:54 +02004921 smp->flags = 0;
4922
4923 return 1;
4924}
4925
Emeric Brun2525b6b2012-10-18 15:59:43 +02004926/* integer, returns the verify result on client cert */
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02004927static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004928smp_fetch_ssl_c_verify(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02004929{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004930 struct connection *conn;
4931
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004932 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004933 if (!conn || conn->xprt != &ssl_sock)
4934 return 0;
4935
4936 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02004937 smp->flags = SMP_F_MAY_CHANGE;
4938 return 0;
4939 }
4940
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004941 if (!conn->xprt_ctx)
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02004942 return 0;
4943
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004944 smp->data.type = SMP_T_SINT;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004945 smp->data.u.sint = (long long int)SSL_get_verify_result(conn->xprt_ctx);
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02004946 smp->flags = 0;
4947
4948 return 1;
4949}
4950
Emeric Brunfb510ea2012-10-05 12:00:26 +02004951/* parse the "ca-file" bind keyword */
4952static 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 +02004953{
4954 if (!*args[cur_arg + 1]) {
4955 if (err)
4956 memprintf(err, "'%s' : missing CAfile path", args[cur_arg]);
4957 return ERR_ALERT | ERR_FATAL;
4958 }
4959
Emeric Brunef42d922012-10-11 16:11:36 +02004960 if ((*args[cur_arg + 1] != '/') && global.ca_base)
4961 memprintf(&conf->ca_file, "%s/%s", global.ca_base, args[cur_arg + 1]);
4962 else
4963 memprintf(&conf->ca_file, "%s", args[cur_arg + 1]);
Emeric Brunc8e8d122012-10-02 18:42:10 +02004964
Emeric Brund94b3fe2012-09-20 18:23:56 +02004965 return 0;
4966}
4967
Christopher Faulet31af49d2015-06-09 17:29:50 +02004968/* parse the "ca-sign-file" bind keyword */
4969static int bind_parse_ca_sign_file(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
4970{
4971 if (!*args[cur_arg + 1]) {
4972 if (err)
4973 memprintf(err, "'%s' : missing CAfile path", args[cur_arg]);
4974 return ERR_ALERT | ERR_FATAL;
4975 }
4976
4977 if ((*args[cur_arg + 1] != '/') && global.ca_base)
4978 memprintf(&conf->ca_sign_file, "%s/%s", global.ca_base, args[cur_arg + 1]);
4979 else
4980 memprintf(&conf->ca_sign_file, "%s", args[cur_arg + 1]);
4981
4982 return 0;
4983}
4984
4985/* parse the ca-sign-pass bind keyword */
4986
4987static int bind_parse_ca_sign_pass(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
4988{
4989 if (!*args[cur_arg + 1]) {
4990 if (err)
4991 memprintf(err, "'%s' : missing CAkey password", args[cur_arg]);
4992 return ERR_ALERT | ERR_FATAL;
4993 }
4994 memprintf(&conf->ca_sign_pass, "%s", args[cur_arg + 1]);
4995 return 0;
4996}
4997
Willy Tarreau79eeafa2012-09-14 07:53:05 +02004998/* parse the "ciphers" bind keyword */
Willy Tarreau4348fad2012-09-20 16:48:07 +02004999static 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 +02005000{
5001 if (!*args[cur_arg + 1]) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02005002 memprintf(err, "'%s' : missing cipher suite", args[cur_arg]);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005003 return ERR_ALERT | ERR_FATAL;
5004 }
5005
Emeric Brun76d88952012-10-05 15:47:31 +02005006 free(conf->ciphers);
Willy Tarreau4348fad2012-09-20 16:48:07 +02005007 conf->ciphers = strdup(args[cur_arg + 1]);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005008 return 0;
5009}
5010
5011/* parse the "crt" bind keyword */
Willy Tarreau4348fad2012-09-20 16:48:07 +02005012static 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 +02005013{
Willy Tarreau38011032013-08-13 16:59:39 +02005014 char path[MAXPATHLEN];
Willy Tarreaub75d6922014-04-14 18:05:41 +02005015
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005016 if (!*args[cur_arg + 1]) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02005017 memprintf(err, "'%s' : missing certificate location", args[cur_arg]);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005018 return ERR_ALERT | ERR_FATAL;
5019 }
5020
Emeric Brunc8e8d122012-10-02 18:42:10 +02005021 if ((*args[cur_arg + 1] != '/' ) && global.crt_base) {
Willy Tarreau38011032013-08-13 16:59:39 +02005022 if ((strlen(global.crt_base) + 1 + strlen(args[cur_arg + 1]) + 1) > MAXPATHLEN) {
Emeric Brunc8e8d122012-10-02 18:42:10 +02005023 memprintf(err, "'%s' : path too long", args[cur_arg]);
5024 return ERR_ALERT | ERR_FATAL;
5025 }
Willy Tarreaub75d6922014-04-14 18:05:41 +02005026 snprintf(path, sizeof(path), "%s/%s", global.crt_base, args[cur_arg + 1]);
Emeric Brunc8e8d122012-10-02 18:42:10 +02005027 if (ssl_sock_load_cert(path, conf, px, err) > 0)
5028 return ERR_ALERT | ERR_FATAL;
5029
5030 return 0;
5031 }
5032
Willy Tarreau4348fad2012-09-20 16:48:07 +02005033 if (ssl_sock_load_cert(args[cur_arg + 1], conf, px, err) > 0)
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005034 return ERR_ALERT | ERR_FATAL;
Emeric Brund94b3fe2012-09-20 18:23:56 +02005035
5036 return 0;
5037}
5038
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01005039/* parse the "crt-list" bind keyword */
5040static int bind_parse_crt_list(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5041{
5042 if (!*args[cur_arg + 1]) {
5043 memprintf(err, "'%s' : missing certificate location", args[cur_arg]);
5044 return ERR_ALERT | ERR_FATAL;
5045 }
5046
Willy Tarreauad1731d2013-04-02 17:35:58 +02005047 if (ssl_sock_load_cert_list_file(args[cur_arg + 1], conf, px, err) > 0) {
5048 memprintf(err, "'%s' : %s", args[cur_arg], *err);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01005049 return ERR_ALERT | ERR_FATAL;
Willy Tarreauad1731d2013-04-02 17:35:58 +02005050 }
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01005051
5052 return 0;
5053}
5054
Emeric Brunfb510ea2012-10-05 12:00:26 +02005055/* parse the "crl-file" bind keyword */
5056static 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 +02005057{
Emeric Brun051cdab2012-10-02 19:25:50 +02005058#ifndef X509_V_FLAG_CRL_CHECK
5059 if (err)
5060 memprintf(err, "'%s' : library does not support CRL verify", args[cur_arg]);
5061 return ERR_ALERT | ERR_FATAL;
5062#else
Emeric Brund94b3fe2012-09-20 18:23:56 +02005063 if (!*args[cur_arg + 1]) {
5064 if (err)
5065 memprintf(err, "'%s' : missing CRLfile path", args[cur_arg]);
5066 return ERR_ALERT | ERR_FATAL;
5067 }
Emeric Brun2b58d042012-09-20 17:10:03 +02005068
Emeric Brunef42d922012-10-11 16:11:36 +02005069 if ((*args[cur_arg + 1] != '/') && global.ca_base)
5070 memprintf(&conf->crl_file, "%s/%s", global.ca_base, args[cur_arg + 1]);
5071 else
5072 memprintf(&conf->crl_file, "%s", args[cur_arg + 1]);
Emeric Brunc8e8d122012-10-02 18:42:10 +02005073
Emeric Brun2b58d042012-09-20 17:10:03 +02005074 return 0;
Emeric Brun051cdab2012-10-02 19:25:50 +02005075#endif
Emeric Brun2b58d042012-09-20 17:10:03 +02005076}
5077
5078/* parse the "ecdhe" bind keyword keywords */
5079static int bind_parse_ecdhe(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5080{
5081#if OPENSSL_VERSION_NUMBER < 0x0090800fL
5082 if (err)
5083 memprintf(err, "'%s' : library does not support elliptic curve Diffie-Hellman (too old)", args[cur_arg]);
5084 return ERR_ALERT | ERR_FATAL;
5085#elif defined(OPENSSL_NO_ECDH)
5086 if (err)
5087 memprintf(err, "'%s' : library does not support elliptic curve Diffie-Hellman (disabled via OPENSSL_NO_ECDH)", args[cur_arg]);
5088 return ERR_ALERT | ERR_FATAL;
5089#else
5090 if (!*args[cur_arg + 1]) {
5091 if (err)
5092 memprintf(err, "'%s' : missing named curve", args[cur_arg]);
5093 return ERR_ALERT | ERR_FATAL;
5094 }
5095
5096 conf->ecdhe = strdup(args[cur_arg + 1]);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005097
5098 return 0;
Emeric Brun2b58d042012-09-20 17:10:03 +02005099#endif
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005100}
5101
Emeric Brun81c00f02012-09-21 14:31:21 +02005102/* parse the "crt_ignerr" and "ca_ignerr" bind keywords */
5103static int bind_parse_ignore_err(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5104{
5105 int code;
5106 char *p = args[cur_arg + 1];
5107 unsigned long long *ignerr = &conf->crt_ignerr;
5108
5109 if (!*p) {
5110 if (err)
5111 memprintf(err, "'%s' : missing error IDs list", args[cur_arg]);
5112 return ERR_ALERT | ERR_FATAL;
5113 }
5114
5115 if (strcmp(args[cur_arg], "ca-ignore-err") == 0)
5116 ignerr = &conf->ca_ignerr;
5117
5118 if (strcmp(p, "all") == 0) {
5119 *ignerr = ~0ULL;
5120 return 0;
5121 }
5122
5123 while (p) {
5124 code = atoi(p);
5125 if ((code <= 0) || (code > 63)) {
5126 if (err)
5127 memprintf(err, "'%s' : ID '%d' out of range (1..63) in error IDs list '%s'",
5128 args[cur_arg], code, args[cur_arg + 1]);
5129 return ERR_ALERT | ERR_FATAL;
5130 }
5131 *ignerr |= 1ULL << code;
5132 p = strchr(p, ',');
5133 if (p)
5134 p++;
5135 }
5136
Emeric Brun2cb7ae52012-10-05 14:14:21 +02005137 return 0;
5138}
5139
5140/* parse the "force-sslv3" bind keyword */
5141static int bind_parse_force_sslv3(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5142{
5143 conf->ssl_options |= BC_SSL_O_USE_SSLV3;
5144 return 0;
5145}
5146
5147/* parse the "force-tlsv10" bind keyword */
5148static int bind_parse_force_tlsv10(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5149{
5150 conf->ssl_options |= BC_SSL_O_USE_TLSV10;
Emeric Brun2d0c4822012-10-02 13:45:20 +02005151 return 0;
5152}
5153
Emeric Brun2cb7ae52012-10-05 14:14:21 +02005154/* parse the "force-tlsv11" bind keyword */
5155static int bind_parse_force_tlsv11(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5156{
5157#if SSL_OP_NO_TLSv1_1
5158 conf->ssl_options |= BC_SSL_O_USE_TLSV11;
5159 return 0;
5160#else
5161 if (err)
5162 memprintf(err, "'%s' : library does not support protocol TLSv1.1", args[cur_arg]);
5163 return ERR_ALERT | ERR_FATAL;
5164#endif
5165}
5166
5167/* parse the "force-tlsv12" bind keyword */
5168static int bind_parse_force_tlsv12(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5169{
5170#if SSL_OP_NO_TLSv1_2
5171 conf->ssl_options |= BC_SSL_O_USE_TLSV12;
5172 return 0;
5173#else
5174 if (err)
5175 memprintf(err, "'%s' : library does not support protocol TLSv1.2", args[cur_arg]);
5176 return ERR_ALERT | ERR_FATAL;
5177#endif
5178}
5179
5180
Emeric Brun2d0c4822012-10-02 13:45:20 +02005181/* parse the "no-tls-tickets" bind keyword */
5182static int bind_parse_no_tls_tickets(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5183{
Emeric Brun89675492012-10-05 13:48:26 +02005184 conf->ssl_options |= BC_SSL_O_NO_TLS_TICKETS;
Emeric Brun81c00f02012-09-21 14:31:21 +02005185 return 0;
5186}
5187
Emeric Brun2d0c4822012-10-02 13:45:20 +02005188
Emeric Brun9b3009b2012-10-05 11:55:06 +02005189/* parse the "no-sslv3" bind keyword */
5190static 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 +02005191{
Emeric Brun89675492012-10-05 13:48:26 +02005192 conf->ssl_options |= BC_SSL_O_NO_SSLV3;
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005193 return 0;
5194}
5195
Emeric Brun9b3009b2012-10-05 11:55:06 +02005196/* parse the "no-tlsv10" bind keyword */
5197static 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 +02005198{
Emeric Brun89675492012-10-05 13:48:26 +02005199 conf->ssl_options |= BC_SSL_O_NO_TLSV10;
Emeric Brunc0ff4922012-09-28 19:37:02 +02005200 return 0;
5201}
5202
Emeric Brun9b3009b2012-10-05 11:55:06 +02005203/* parse the "no-tlsv11" bind keyword */
5204static 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 +02005205{
Emeric Brun89675492012-10-05 13:48:26 +02005206 conf->ssl_options |= BC_SSL_O_NO_TLSV11;
Emeric Brunc0ff4922012-09-28 19:37:02 +02005207 return 0;
5208}
5209
Emeric Brun9b3009b2012-10-05 11:55:06 +02005210/* parse the "no-tlsv12" bind keyword */
5211static 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 +02005212{
Emeric Brun89675492012-10-05 13:48:26 +02005213 conf->ssl_options |= BC_SSL_O_NO_TLSV12;
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005214 return 0;
5215}
5216
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02005217/* parse the "npn" bind keyword */
5218static int bind_parse_npn(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5219{
5220#ifdef OPENSSL_NPN_NEGOTIATED
5221 char *p1, *p2;
5222
5223 if (!*args[cur_arg + 1]) {
5224 memprintf(err, "'%s' : missing the comma-delimited NPN protocol suite", args[cur_arg]);
5225 return ERR_ALERT | ERR_FATAL;
5226 }
5227
5228 free(conf->npn_str);
5229
5230 /* the NPN string is built as a suite of (<len> <name>)* */
5231 conf->npn_len = strlen(args[cur_arg + 1]) + 1;
5232 conf->npn_str = calloc(1, conf->npn_len);
5233 memcpy(conf->npn_str + 1, args[cur_arg + 1], conf->npn_len);
5234
5235 /* replace commas with the name length */
5236 p1 = conf->npn_str;
5237 p2 = p1 + 1;
5238 while (1) {
5239 p2 = memchr(p1 + 1, ',', conf->npn_str + conf->npn_len - (p1 + 1));
5240 if (!p2)
5241 p2 = p1 + 1 + strlen(p1 + 1);
5242
5243 if (p2 - (p1 + 1) > 255) {
5244 *p2 = '\0';
5245 memprintf(err, "'%s' : NPN protocol name too long : '%s'", args[cur_arg], p1 + 1);
5246 return ERR_ALERT | ERR_FATAL;
5247 }
5248
5249 *p1 = p2 - (p1 + 1);
5250 p1 = p2;
5251
5252 if (!*p2)
5253 break;
5254
5255 *(p2++) = '\0';
5256 }
5257 return 0;
5258#else
5259 if (err)
5260 memprintf(err, "'%s' : library does not support TLS NPN extension", args[cur_arg]);
5261 return ERR_ALERT | ERR_FATAL;
5262#endif
5263}
5264
Willy Tarreauab861d32013-04-02 02:30:41 +02005265/* parse the "alpn" bind keyword */
5266static int bind_parse_alpn(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5267{
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01005268#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Willy Tarreauab861d32013-04-02 02:30:41 +02005269 char *p1, *p2;
5270
5271 if (!*args[cur_arg + 1]) {
5272 memprintf(err, "'%s' : missing the comma-delimited ALPN protocol suite", args[cur_arg]);
5273 return ERR_ALERT | ERR_FATAL;
5274 }
5275
5276 free(conf->alpn_str);
5277
5278 /* the ALPN string is built as a suite of (<len> <name>)* */
5279 conf->alpn_len = strlen(args[cur_arg + 1]) + 1;
5280 conf->alpn_str = calloc(1, conf->alpn_len);
5281 memcpy(conf->alpn_str + 1, args[cur_arg + 1], conf->alpn_len);
5282
5283 /* replace commas with the name length */
5284 p1 = conf->alpn_str;
5285 p2 = p1 + 1;
5286 while (1) {
5287 p2 = memchr(p1 + 1, ',', conf->alpn_str + conf->alpn_len - (p1 + 1));
5288 if (!p2)
5289 p2 = p1 + 1 + strlen(p1 + 1);
5290
5291 if (p2 - (p1 + 1) > 255) {
5292 *p2 = '\0';
5293 memprintf(err, "'%s' : ALPN protocol name too long : '%s'", args[cur_arg], p1 + 1);
5294 return ERR_ALERT | ERR_FATAL;
5295 }
5296
5297 *p1 = p2 - (p1 + 1);
5298 p1 = p2;
5299
5300 if (!*p2)
5301 break;
5302
5303 *(p2++) = '\0';
5304 }
5305 return 0;
5306#else
5307 if (err)
5308 memprintf(err, "'%s' : library does not support TLS ALPN extension", args[cur_arg]);
5309 return ERR_ALERT | ERR_FATAL;
5310#endif
5311}
5312
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005313/* parse the "ssl" bind keyword */
Willy Tarreau4348fad2012-09-20 16:48:07 +02005314static 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 +02005315{
Willy Tarreau81796be2012-09-22 19:11:47 +02005316 struct listener *l;
5317
Willy Tarreau4348fad2012-09-20 16:48:07 +02005318 conf->is_ssl = 1;
Emeric Brun76d88952012-10-05 15:47:31 +02005319
5320 if (global.listen_default_ciphers && !conf->ciphers)
5321 conf->ciphers = strdup(global.listen_default_ciphers);
Emeric Brun2c86cbf2014-10-30 15:56:50 +01005322 conf->ssl_options |= global.listen_default_ssloptions;
Emeric Brun76d88952012-10-05 15:47:31 +02005323
Willy Tarreau81796be2012-09-22 19:11:47 +02005324 list_for_each_entry(l, &conf->listeners, by_bind)
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02005325 l->xprt = &ssl_sock;
Willy Tarreau81796be2012-09-22 19:11:47 +02005326
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005327 return 0;
5328}
5329
Christopher Faulet31af49d2015-06-09 17:29:50 +02005330/* parse the "generate-certificates" bind keyword */
5331static int bind_parse_generate_certs(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5332{
5333#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
5334 conf->generate_certs = 1;
5335#else
5336 memprintf(err, "%sthis version of openssl cannot generate SSL certificates.\n",
5337 err && *err ? *err : "");
5338#endif
5339 return 0;
5340}
5341
Emmanuel Hocdet65623372013-01-24 17:17:15 +01005342/* parse the "strict-sni" bind keyword */
5343static int bind_parse_strict_sni(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5344{
5345 conf->strict_sni = 1;
5346 return 0;
Nenad Merdanovic05552d42015-02-27 19:56:49 +01005347}
5348
5349/* parse the "tls-ticket-keys" bind keyword */
5350static int bind_parse_tls_ticket_keys(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5351{
5352#if (defined SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB && TLS_TICKETS_NO > 0)
5353 FILE *f;
5354 int i = 0;
5355 char thisline[LINESIZE];
Nenad Merdanovic146defa2015-05-09 08:46:00 +02005356 struct tls_keys_ref *keys_ref;
Nenad Merdanovic05552d42015-02-27 19:56:49 +01005357
5358 if (!*args[cur_arg + 1]) {
5359 if (err)
5360 memprintf(err, "'%s' : missing TLS ticket keys file path", args[cur_arg]);
5361 return ERR_ALERT | ERR_FATAL;
5362 }
5363
Nenad Merdanovic200b0fa2015-05-09 08:46:01 +02005364 keys_ref = tlskeys_ref_lookup(args[cur_arg + 1]);
5365 if(keys_ref) {
5366 conf->keys_ref = keys_ref;
5367 return 0;
5368 }
5369
Nenad Merdanovic146defa2015-05-09 08:46:00 +02005370 keys_ref = malloc(sizeof(struct tls_keys_ref));
5371 keys_ref->tlskeys = malloc(TLS_TICKETS_NO * sizeof(struct tls_sess_key));
Nenad Merdanovic05552d42015-02-27 19:56:49 +01005372
5373 if ((f = fopen(args[cur_arg + 1], "r")) == NULL) {
5374 if (err)
5375 memprintf(err, "'%s' : unable to load ssl tickets keys file", args[cur_arg+1]);
5376 return ERR_ALERT | ERR_FATAL;
5377 }
5378
Nenad Merdanovic146defa2015-05-09 08:46:00 +02005379 keys_ref->filename = strdup(args[cur_arg + 1]);
5380
Nenad Merdanovic05552d42015-02-27 19:56:49 +01005381 while (fgets(thisline, sizeof(thisline), f) != NULL) {
5382 int len = strlen(thisline);
5383 /* Strip newline characters from the end */
5384 if(thisline[len - 1] == '\n')
5385 thisline[--len] = 0;
5386
5387 if(thisline[len - 1] == '\r')
5388 thisline[--len] = 0;
5389
Nenad Merdanovic146defa2015-05-09 08:46:00 +02005390 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 +01005391 if (err)
5392 memprintf(err, "'%s' : unable to decode base64 key on line %d", args[cur_arg+1], i + 1);
5393 return ERR_ALERT | ERR_FATAL;
5394 }
5395 i++;
5396 }
5397
5398 if (i < TLS_TICKETS_NO) {
5399 if (err)
5400 memprintf(err, "'%s' : please supply at least %d keys in the tls-tickets-file", args[cur_arg+1], TLS_TICKETS_NO);
5401 return ERR_ALERT | ERR_FATAL;
5402 }
5403
5404 fclose(f);
5405
5406 /* Use penultimate key for encryption, handle when TLS_TICKETS_NO = 1 */
5407 i-=2;
Nenad Merdanovic146defa2015-05-09 08:46:00 +02005408 keys_ref->tls_ticket_enc_index = i < 0 ? 0 : i;
Nenad Merdanovic200b0fa2015-05-09 08:46:01 +02005409 keys_ref->unique_id = -1;
Nenad Merdanovic146defa2015-05-09 08:46:00 +02005410 conf->keys_ref = keys_ref;
Nenad Merdanovic05552d42015-02-27 19:56:49 +01005411
Nenad Merdanovic200b0fa2015-05-09 08:46:01 +02005412 LIST_ADD(&tlskeys_reference, &keys_ref->list);
5413
Nenad Merdanovic05552d42015-02-27 19:56:49 +01005414 return 0;
5415#else
5416 if (err)
5417 memprintf(err, "'%s' : TLS ticket callback extension not supported", args[cur_arg]);
5418 return ERR_ALERT | ERR_FATAL;
5419#endif /* SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB */
Emmanuel Hocdet65623372013-01-24 17:17:15 +01005420}
5421
Emeric Brund94b3fe2012-09-20 18:23:56 +02005422/* parse the "verify" bind keyword */
5423static int bind_parse_verify(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5424{
5425 if (!*args[cur_arg + 1]) {
5426 if (err)
5427 memprintf(err, "'%s' : missing verify method", args[cur_arg]);
5428 return ERR_ALERT | ERR_FATAL;
5429 }
5430
5431 if (strcmp(args[cur_arg + 1], "none") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01005432 conf->verify = SSL_SOCK_VERIFY_NONE;
Emeric Brund94b3fe2012-09-20 18:23:56 +02005433 else if (strcmp(args[cur_arg + 1], "optional") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01005434 conf->verify = SSL_SOCK_VERIFY_OPTIONAL;
Emeric Brund94b3fe2012-09-20 18:23:56 +02005435 else if (strcmp(args[cur_arg + 1], "required") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01005436 conf->verify = SSL_SOCK_VERIFY_REQUIRED;
Emeric Brund94b3fe2012-09-20 18:23:56 +02005437 else {
5438 if (err)
5439 memprintf(err, "'%s' : unknown verify method '%s', only 'none', 'optional', and 'required' are supported\n",
5440 args[cur_arg], args[cur_arg + 1]);
5441 return ERR_ALERT | ERR_FATAL;
5442 }
5443
5444 return 0;
5445}
5446
Willy Tarreau92faadf2012-10-10 23:04:25 +02005447/************** "server" keywords ****************/
5448
Emeric Brunef42d922012-10-11 16:11:36 +02005449/* parse the "ca-file" server keyword */
5450static int srv_parse_ca_file(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5451{
5452 if (!*args[*cur_arg + 1]) {
5453 if (err)
5454 memprintf(err, "'%s' : missing CAfile path", args[*cur_arg]);
5455 return ERR_ALERT | ERR_FATAL;
5456 }
5457
5458 if ((*args[*cur_arg + 1] != '/') && global.ca_base)
5459 memprintf(&newsrv->ssl_ctx.ca_file, "%s/%s", global.ca_base, args[*cur_arg + 1]);
5460 else
5461 memprintf(&newsrv->ssl_ctx.ca_file, "%s", args[*cur_arg + 1]);
5462
5463 return 0;
5464}
5465
Willy Tarreau92faadf2012-10-10 23:04:25 +02005466/* parse the "check-ssl" server keyword */
5467static int srv_parse_check_ssl(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5468{
5469 newsrv->check.use_ssl = 1;
5470 if (global.connect_default_ciphers && !newsrv->ssl_ctx.ciphers)
5471 newsrv->ssl_ctx.ciphers = strdup(global.connect_default_ciphers);
Emeric Brun2c86cbf2014-10-30 15:56:50 +01005472 newsrv->ssl_ctx.options |= global.connect_default_ssloptions;
Willy Tarreau92faadf2012-10-10 23:04:25 +02005473 return 0;
5474}
5475
5476/* parse the "ciphers" server keyword */
5477static int srv_parse_ciphers(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5478{
5479 if (!*args[*cur_arg + 1]) {
5480 memprintf(err, "'%s' : missing cipher suite", args[*cur_arg]);
5481 return ERR_ALERT | ERR_FATAL;
5482 }
5483
5484 free(newsrv->ssl_ctx.ciphers);
5485 newsrv->ssl_ctx.ciphers = strdup(args[*cur_arg + 1]);
5486 return 0;
5487}
5488
Emeric Brunef42d922012-10-11 16:11:36 +02005489/* parse the "crl-file" server keyword */
5490static int srv_parse_crl_file(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5491{
5492#ifndef X509_V_FLAG_CRL_CHECK
5493 if (err)
5494 memprintf(err, "'%s' : library does not support CRL verify", args[*cur_arg]);
5495 return ERR_ALERT | ERR_FATAL;
5496#else
5497 if (!*args[*cur_arg + 1]) {
5498 if (err)
5499 memprintf(err, "'%s' : missing CRLfile path", args[*cur_arg]);
5500 return ERR_ALERT | ERR_FATAL;
5501 }
5502
5503 if ((*args[*cur_arg + 1] != '/') && global.ca_base)
5504 memprintf(&newsrv->ssl_ctx.crl_file, "%s/%s", global.ca_base, args[*cur_arg + 1]);
5505 else
5506 memprintf(&newsrv->ssl_ctx.crl_file, "%s", args[*cur_arg + 1]);
5507
5508 return 0;
5509#endif
5510}
5511
Emeric Bruna7aa3092012-10-26 12:58:00 +02005512/* parse the "crt" server keyword */
5513static int srv_parse_crt(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5514{
5515 if (!*args[*cur_arg + 1]) {
5516 if (err)
5517 memprintf(err, "'%s' : missing certificate file path", args[*cur_arg]);
5518 return ERR_ALERT | ERR_FATAL;
5519 }
5520
5521 if ((*args[*cur_arg + 1] != '/') && global.crt_base)
5522 memprintf(&newsrv->ssl_ctx.client_crt, "%s/%s", global.ca_base, args[*cur_arg + 1]);
5523 else
5524 memprintf(&newsrv->ssl_ctx.client_crt, "%s", args[*cur_arg + 1]);
5525
5526 return 0;
5527}
Emeric Brunef42d922012-10-11 16:11:36 +02005528
Willy Tarreau92faadf2012-10-10 23:04:25 +02005529/* parse the "force-sslv3" server keyword */
5530static int srv_parse_force_sslv3(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5531{
5532 newsrv->ssl_ctx.options |= SRV_SSL_O_USE_SSLV3;
5533 return 0;
5534}
5535
5536/* parse the "force-tlsv10" server keyword */
5537static int srv_parse_force_tlsv10(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5538{
5539 newsrv->ssl_ctx.options |= SRV_SSL_O_USE_TLSV10;
5540 return 0;
5541}
5542
5543/* parse the "force-tlsv11" server keyword */
5544static int srv_parse_force_tlsv11(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5545{
5546#if SSL_OP_NO_TLSv1_1
5547 newsrv->ssl_ctx.options |= SRV_SSL_O_USE_TLSV11;
5548 return 0;
5549#else
5550 if (err)
5551 memprintf(err, "'%s' : library does not support protocol TLSv1.1", args[*cur_arg]);
5552 return ERR_ALERT | ERR_FATAL;
5553#endif
5554}
5555
5556/* parse the "force-tlsv12" server keyword */
5557static int srv_parse_force_tlsv12(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5558{
5559#if SSL_OP_NO_TLSv1_2
5560 newsrv->ssl_ctx.options |= SRV_SSL_O_USE_TLSV12;
5561 return 0;
5562#else
5563 if (err)
5564 memprintf(err, "'%s' : library does not support protocol TLSv1.2", args[*cur_arg]);
5565 return ERR_ALERT | ERR_FATAL;
5566#endif
5567}
5568
Willy Tarreau2a3fb1c2015-02-05 16:47:07 +01005569/* parse the "no-ssl-reuse" server keyword */
5570static int srv_parse_no_ssl_reuse(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5571{
5572 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_REUSE;
5573 return 0;
5574}
5575
Willy Tarreau92faadf2012-10-10 23:04:25 +02005576/* parse the "no-sslv3" server keyword */
5577static int srv_parse_no_sslv3(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5578{
5579 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_SSLV3;
5580 return 0;
5581}
5582
5583/* parse the "no-tlsv10" server keyword */
5584static int srv_parse_no_tlsv10(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5585{
5586 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_TLSV10;
5587 return 0;
5588}
5589
5590/* parse the "no-tlsv11" server keyword */
5591static int srv_parse_no_tlsv11(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5592{
5593 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_TLSV11;
5594 return 0;
5595}
5596
5597/* parse the "no-tlsv12" server keyword */
5598static int srv_parse_no_tlsv12(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5599{
5600 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_TLSV12;
5601 return 0;
5602}
5603
Emeric Brunf9c5c472012-10-11 15:28:34 +02005604/* parse the "no-tls-tickets" server keyword */
5605static int srv_parse_no_tls_tickets(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5606{
5607 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_TLS_TICKETS;
5608 return 0;
5609}
David Safb76832014-05-08 23:42:08 -04005610/* parse the "send-proxy-v2-ssl" server keyword */
5611static int srv_parse_send_proxy_ssl(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5612{
5613 newsrv->pp_opts |= SRV_PP_V2;
5614 newsrv->pp_opts |= SRV_PP_V2_SSL;
5615 return 0;
5616}
5617
5618/* parse the "send-proxy-v2-ssl-cn" server keyword */
5619static int srv_parse_send_proxy_cn(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5620{
5621 newsrv->pp_opts |= SRV_PP_V2;
5622 newsrv->pp_opts |= SRV_PP_V2_SSL;
5623 newsrv->pp_opts |= SRV_PP_V2_SSL_CN;
5624 return 0;
5625}
Emeric Brunf9c5c472012-10-11 15:28:34 +02005626
Willy Tarreau732eac42015-07-09 11:40:25 +02005627/* parse the "sni" server keyword */
5628static int srv_parse_sni(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5629{
5630#ifndef SSL_CTRL_SET_TLSEXT_HOSTNAME
5631 memprintf(err, "'%s' : the current SSL library doesn't support the SNI TLS extension", args[*cur_arg]);
5632 return ERR_ALERT | ERR_FATAL;
5633#else
5634 struct sample_expr *expr;
5635
5636 if (!*args[*cur_arg + 1]) {
5637 memprintf(err, "'%s' : missing sni expression", args[*cur_arg]);
5638 return ERR_ALERT | ERR_FATAL;
5639 }
5640
5641 (*cur_arg)++;
5642 proxy->conf.args.ctx = ARGC_SRV;
5643
5644 expr = sample_parse_expr((char **)args, cur_arg, px->conf.file, px->conf.line, err, &proxy->conf.args);
5645 if (!expr) {
5646 memprintf(err, "error detected while parsing sni expression : %s", *err);
5647 return ERR_ALERT | ERR_FATAL;
5648 }
5649
5650 if (!(expr->fetch->val & SMP_VAL_BE_SRV_CON)) {
5651 memprintf(err, "error detected while parsing sni expression : "
5652 " fetch method '%s' extracts information from '%s', none of which is available here.\n",
5653 args[*cur_arg-1], sample_src_names(expr->fetch->use));
5654 return ERR_ALERT | ERR_FATAL;
5655 }
5656
5657 px->http_needed |= !!(expr->fetch->use & SMP_USE_HTTP_ANY);
5658 newsrv->ssl_ctx.sni = expr;
5659 return 0;
5660#endif
5661}
5662
Willy Tarreau92faadf2012-10-10 23:04:25 +02005663/* parse the "ssl" server keyword */
5664static int srv_parse_ssl(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5665{
5666 newsrv->use_ssl = 1;
5667 if (global.connect_default_ciphers && !newsrv->ssl_ctx.ciphers)
5668 newsrv->ssl_ctx.ciphers = strdup(global.connect_default_ciphers);
5669 return 0;
5670}
5671
Emeric Brunef42d922012-10-11 16:11:36 +02005672/* parse the "verify" server keyword */
5673static int srv_parse_verify(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5674{
5675 if (!*args[*cur_arg + 1]) {
5676 if (err)
5677 memprintf(err, "'%s' : missing verify method", args[*cur_arg]);
5678 return ERR_ALERT | ERR_FATAL;
5679 }
5680
5681 if (strcmp(args[*cur_arg + 1], "none") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01005682 newsrv->ssl_ctx.verify = SSL_SOCK_VERIFY_NONE;
Emeric Brunef42d922012-10-11 16:11:36 +02005683 else if (strcmp(args[*cur_arg + 1], "required") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01005684 newsrv->ssl_ctx.verify = SSL_SOCK_VERIFY_REQUIRED;
Emeric Brunef42d922012-10-11 16:11:36 +02005685 else {
5686 if (err)
5687 memprintf(err, "'%s' : unknown verify method '%s', only 'none' and 'required' are supported\n",
5688 args[*cur_arg], args[*cur_arg + 1]);
5689 return ERR_ALERT | ERR_FATAL;
5690 }
5691
Evan Broderbe554312013-06-27 00:05:25 -07005692 return 0;
5693}
5694
5695/* parse the "verifyhost" server keyword */
5696static int srv_parse_verifyhost(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5697{
5698 if (!*args[*cur_arg + 1]) {
5699 if (err)
5700 memprintf(err, "'%s' : missing hostname to verify against", args[*cur_arg]);
5701 return ERR_ALERT | ERR_FATAL;
5702 }
5703
5704 newsrv->ssl_ctx.verify_host = strdup(args[*cur_arg + 1]);
5705
Emeric Brunef42d922012-10-11 16:11:36 +02005706 return 0;
5707}
5708
Emeric Brun2c86cbf2014-10-30 15:56:50 +01005709/* parse the "ssl-default-bind-options" keyword in global section */
5710static int ssl_parse_default_bind_options(char **args, int section_type, struct proxy *curpx,
5711 struct proxy *defpx, const char *file, int line,
5712 char **err) {
5713 int i = 1;
5714
5715 if (*(args[i]) == 0) {
5716 memprintf(err, "global statement '%s' expects an option as an argument.", args[0]);
5717 return -1;
5718 }
5719 while (*(args[i])) {
5720 if (!strcmp(args[i], "no-sslv3"))
5721 global.listen_default_ssloptions |= BC_SSL_O_NO_SSLV3;
5722 else if (!strcmp(args[i], "no-tlsv10"))
5723 global.listen_default_ssloptions |= BC_SSL_O_NO_TLSV10;
5724 else if (!strcmp(args[i], "no-tlsv11"))
5725 global.listen_default_ssloptions |= BC_SSL_O_NO_TLSV11;
5726 else if (!strcmp(args[i], "no-tlsv12"))
5727 global.listen_default_ssloptions |= BC_SSL_O_NO_TLSV12;
5728 else if (!strcmp(args[i], "force-sslv3"))
5729 global.listen_default_ssloptions |= BC_SSL_O_USE_SSLV3;
5730 else if (!strcmp(args[i], "force-tlsv10"))
5731 global.listen_default_ssloptions |= BC_SSL_O_USE_TLSV10;
5732 else if (!strcmp(args[i], "force-tlsv11")) {
5733#if SSL_OP_NO_TLSv1_1
5734 global.listen_default_ssloptions |= BC_SSL_O_USE_TLSV11;
5735#else
5736 memprintf(err, "'%s' '%s': library does not support protocol TLSv1.1", args[0], args[i]);
5737 return -1;
5738#endif
5739 }
5740 else if (!strcmp(args[i], "force-tlsv12")) {
5741#if SSL_OP_NO_TLSv1_2
5742 global.listen_default_ssloptions |= BC_SSL_O_USE_TLSV12;
5743#else
5744 memprintf(err, "'%s' '%s': library does not support protocol TLSv1.2", args[0], args[i]);
5745 return -1;
5746#endif
5747 }
5748 else if (!strcmp(args[i], "no-tls-tickets"))
5749 global.listen_default_ssloptions |= BC_SSL_O_NO_TLS_TICKETS;
5750 else {
5751 memprintf(err, "unknown option '%s' on global statement '%s'.", args[i], args[0]);
5752 return -1;
5753 }
5754 i++;
5755 }
5756 return 0;
5757}
5758
5759/* parse the "ssl-default-server-options" keyword in global section */
5760static int ssl_parse_default_server_options(char **args, int section_type, struct proxy *curpx,
5761 struct proxy *defpx, const char *file, int line,
5762 char **err) {
5763 int i = 1;
5764
5765 if (*(args[i]) == 0) {
5766 memprintf(err, "global statement '%s' expects an option as an argument.", args[0]);
5767 return -1;
5768 }
5769 while (*(args[i])) {
5770 if (!strcmp(args[i], "no-sslv3"))
5771 global.connect_default_ssloptions |= SRV_SSL_O_NO_SSLV3;
5772 else if (!strcmp(args[i], "no-tlsv10"))
5773 global.connect_default_ssloptions |= SRV_SSL_O_NO_TLSV10;
5774 else if (!strcmp(args[i], "no-tlsv11"))
5775 global.connect_default_ssloptions |= SRV_SSL_O_NO_TLSV11;
5776 else if (!strcmp(args[i], "no-tlsv12"))
5777 global.connect_default_ssloptions |= SRV_SSL_O_NO_TLSV12;
5778 else if (!strcmp(args[i], "force-sslv3"))
5779 global.connect_default_ssloptions |= SRV_SSL_O_USE_SSLV3;
5780 else if (!strcmp(args[i], "force-tlsv10"))
5781 global.connect_default_ssloptions |= SRV_SSL_O_USE_TLSV10;
5782 else if (!strcmp(args[i], "force-tlsv11")) {
5783#if SSL_OP_NO_TLSv1_1
5784 global.connect_default_ssloptions |= SRV_SSL_O_USE_TLSV11;
5785#else
5786 memprintf(err, "'%s' '%s': library does not support protocol TLSv1.1", args[0], args[i]);
5787 return -1;
5788#endif
5789 }
5790 else if (!strcmp(args[i], "force-tlsv12")) {
5791#if SSL_OP_NO_TLSv1_2
5792 global.connect_default_ssloptions |= SRV_SSL_O_USE_TLSV12;
5793#else
5794 memprintf(err, "'%s' '%s': library does not support protocol TLSv1.2", args[0], args[i]);
5795 return -1;
5796#endif
5797 }
5798 else if (!strcmp(args[i], "no-tls-tickets"))
5799 global.connect_default_ssloptions |= SRV_SSL_O_NO_TLS_TICKETS;
5800 else {
5801 memprintf(err, "unknown option '%s' on global statement '%s'.", args[i], args[0]);
5802 return -1;
5803 }
5804 i++;
5805 }
5806 return 0;
5807}
5808
Willy Tarreau7875d092012-09-10 08:20:03 +02005809/* Note: must not be declared <const> as its list will be overwritten.
5810 * Please take care of keeping this list alphabetically sorted.
5811 */
Willy Tarreaudc13c112013-06-21 23:16:39 +02005812static struct sample_fetch_kw_list sample_fetch_keywords = {ILH, {
Emeric Brun645ae792014-04-30 14:21:06 +02005813 { "ssl_bc", smp_fetch_ssl_fc, 0, NULL, SMP_T_BOOL, SMP_USE_L5SRV },
Thierry FOURNIER07ee64e2015-07-06 23:43:03 +02005814 { "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 +02005815 { "ssl_bc_cipher", smp_fetch_ssl_fc_cipher, 0, NULL, SMP_T_STR, SMP_USE_L5SRV },
5816 { "ssl_bc_protocol", smp_fetch_ssl_fc_protocol, 0, NULL, SMP_T_STR, SMP_USE_L5SRV },
Emeric Brunb73a9b02014-04-30 18:49:19 +02005817 { "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 +02005818 { "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 +02005819 { "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 +02005820 { "ssl_c_ca_err", smp_fetch_ssl_c_ca_err, 0, NULL, SMP_T_SINT, SMP_USE_L5CLI },
5821 { "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 +01005822 { "ssl_c_der", smp_fetch_ssl_x_der, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Thierry FOURNIER07ee64e2015-07-06 23:43:03 +02005823 { "ssl_c_err", smp_fetch_ssl_c_err, 0, NULL, SMP_T_SINT, SMP_USE_L5CLI },
Emeric Brunba841a12014-04-30 17:05:08 +02005824 { "ssl_c_i_dn", smp_fetch_ssl_x_i_dn, ARG2(0,STR,SINT), NULL, SMP_T_STR, SMP_USE_L5CLI },
5825 { "ssl_c_key_alg", smp_fetch_ssl_x_key_alg, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
5826 { "ssl_c_notafter", smp_fetch_ssl_x_notafter, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
5827 { "ssl_c_notbefore", smp_fetch_ssl_x_notbefore, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
5828 { "ssl_c_sig_alg", smp_fetch_ssl_x_sig_alg, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
5829 { "ssl_c_s_dn", smp_fetch_ssl_x_s_dn, ARG2(0,STR,SINT), NULL, SMP_T_STR, SMP_USE_L5CLI },
5830 { "ssl_c_serial", smp_fetch_ssl_x_serial, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
5831 { "ssl_c_sha1", smp_fetch_ssl_x_sha1, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Willy Tarreau80aca902013-01-07 15:42:20 +01005832 { "ssl_c_used", smp_fetch_ssl_c_used, 0, NULL, SMP_T_BOOL, SMP_USE_L5CLI },
Thierry FOURNIER07ee64e2015-07-06 23:43:03 +02005833 { "ssl_c_verify", smp_fetch_ssl_c_verify, 0, NULL, SMP_T_SINT, SMP_USE_L5CLI },
5834 { "ssl_c_version", smp_fetch_ssl_x_version, 0, NULL, SMP_T_SINT, SMP_USE_L5CLI },
Emeric Brun43e79582014-10-29 19:03:26 +01005835 { "ssl_f_der", smp_fetch_ssl_x_der, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Emeric Brunba841a12014-04-30 17:05:08 +02005836 { "ssl_f_i_dn", smp_fetch_ssl_x_i_dn, ARG2(0,STR,SINT), NULL, SMP_T_STR, SMP_USE_L5CLI },
5837 { "ssl_f_key_alg", smp_fetch_ssl_x_key_alg, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
5838 { "ssl_f_notafter", smp_fetch_ssl_x_notafter, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
5839 { "ssl_f_notbefore", smp_fetch_ssl_x_notbefore, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
5840 { "ssl_f_sig_alg", smp_fetch_ssl_x_sig_alg, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
5841 { "ssl_f_s_dn", smp_fetch_ssl_x_s_dn, ARG2(0,STR,SINT), NULL, SMP_T_STR, SMP_USE_L5CLI },
5842 { "ssl_f_serial", smp_fetch_ssl_x_serial, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Emeric Brun55f4fa82014-04-30 17:11:25 +02005843 { "ssl_f_sha1", smp_fetch_ssl_x_sha1, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Thierry FOURNIER07ee64e2015-07-06 23:43:03 +02005844 { "ssl_f_version", smp_fetch_ssl_x_version, 0, NULL, SMP_T_SINT, SMP_USE_L5CLI },
Willy Tarreau80aca902013-01-07 15:42:20 +01005845 { "ssl_fc", smp_fetch_ssl_fc, 0, NULL, SMP_T_BOOL, SMP_USE_L5CLI },
Thierry FOURNIER07ee64e2015-07-06 23:43:03 +02005846 { "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 +01005847 { "ssl_fc_cipher", smp_fetch_ssl_fc_cipher, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Willy Tarreau80aca902013-01-07 15:42:20 +01005848 { "ssl_fc_has_crt", smp_fetch_ssl_fc_has_crt, 0, NULL, SMP_T_BOOL, SMP_USE_L5CLI },
5849 { "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 +02005850 { "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 +02005851#ifdef OPENSSL_NPN_NEGOTIATED
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01005852 { "ssl_fc_npn", smp_fetch_ssl_fc_npn, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Willy Tarreaua33c6542012-10-15 13:19:06 +02005853#endif
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01005854#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01005855 { "ssl_fc_alpn", smp_fetch_ssl_fc_alpn, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Willy Tarreauab861d32013-04-02 02:30:41 +02005856#endif
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01005857 { "ssl_fc_protocol", smp_fetch_ssl_fc_protocol, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Emeric Brunb73a9b02014-04-30 18:49:19 +02005858 { "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 +02005859 { "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 +01005860 { "ssl_fc_session_id", smp_fetch_ssl_fc_session_id, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
5861 { "ssl_fc_sni", smp_fetch_ssl_fc_sni, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Willy Tarreau7875d092012-09-10 08:20:03 +02005862 { NULL, NULL, 0, 0, 0 },
5863}};
5864
5865/* Note: must not be declared <const> as its list will be overwritten.
5866 * Please take care of keeping this list alphabetically sorted.
5867 */
Willy Tarreaudc13c112013-06-21 23:16:39 +02005868static struct acl_kw_list acl_kws = {ILH, {
Thierry FOURNIERc5a4e982014-03-05 16:07:08 +01005869 { "ssl_fc_sni_end", "ssl_fc_sni", PAT_MATCH_END },
5870 { "ssl_fc_sni_reg", "ssl_fc_sni", PAT_MATCH_REG },
Willy Tarreau8ed669b2013-01-11 15:49:37 +01005871 { /* END */ },
Willy Tarreau7875d092012-09-10 08:20:03 +02005872}};
5873
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005874/* Note: must not be declared <const> as its list will be overwritten.
5875 * Please take care of keeping this list alphabetically sorted, doing so helps
5876 * all code contributors.
5877 * Optional keywords are also declared with a NULL ->parse() function so that
5878 * the config parser can report an appropriate error when a known keyword was
5879 * not enabled.
5880 */
Willy Tarreau51fb7652012-09-18 18:24:39 +02005881static struct bind_kw_list bind_kws = { "SSL", { }, {
Nenad Merdanovic05552d42015-02-27 19:56:49 +01005882 { "alpn", bind_parse_alpn, 1 }, /* set ALPN supported protocols */
5883 { "ca-file", bind_parse_ca_file, 1 }, /* set CAfile to process verify on client cert */
5884 { "ca-ignore-err", bind_parse_ignore_err, 1 }, /* set error IDs to ignore on verify depth > 0 */
Christopher Faulet31af49d2015-06-09 17:29:50 +02005885 { "ca-sign-file", bind_parse_ca_sign_file, 1 }, /* set CAFile used to generate and sign server certs */
5886 { "ca-sign-pass", bind_parse_ca_sign_pass, 1 }, /* set CAKey passphrase */
Nenad Merdanovic05552d42015-02-27 19:56:49 +01005887 { "ciphers", bind_parse_ciphers, 1 }, /* set SSL cipher suite */
5888 { "crl-file", bind_parse_crl_file, 1 }, /* set certificat revocation list file use on client cert verify */
5889 { "crt", bind_parse_crt, 1 }, /* load SSL certificates from this location */
5890 { "crt-ignore-err", bind_parse_ignore_err, 1 }, /* set error IDs to ingore on verify depth == 0 */
5891 { "crt-list", bind_parse_crt_list, 1 }, /* load a list of crt from this location */
5892 { "ecdhe", bind_parse_ecdhe, 1 }, /* defines named curve for elliptic curve Diffie-Hellman */
5893 { "force-sslv3", bind_parse_force_sslv3, 0 }, /* force SSLv3 */
5894 { "force-tlsv10", bind_parse_force_tlsv10, 0 }, /* force TLSv10 */
5895 { "force-tlsv11", bind_parse_force_tlsv11, 0 }, /* force TLSv11 */
5896 { "force-tlsv12", bind_parse_force_tlsv12, 0 }, /* force TLSv12 */
Christopher Faulet31af49d2015-06-09 17:29:50 +02005897 { "generate-certificates", bind_parse_generate_certs, 0 }, /* enable the server certificates generation */
Nenad Merdanovic05552d42015-02-27 19:56:49 +01005898 { "no-sslv3", bind_parse_no_sslv3, 0 }, /* disable SSLv3 */
5899 { "no-tlsv10", bind_parse_no_tlsv10, 0 }, /* disable TLSv10 */
5900 { "no-tlsv11", bind_parse_no_tlsv11, 0 }, /* disable TLSv11 */
5901 { "no-tlsv12", bind_parse_no_tlsv12, 0 }, /* disable TLSv12 */
5902 { "no-tls-tickets", bind_parse_no_tls_tickets, 0 }, /* disable session resumption tickets */
5903 { "ssl", bind_parse_ssl, 0 }, /* enable SSL processing */
5904 { "strict-sni", bind_parse_strict_sni, 0 }, /* refuse negotiation if sni doesn't match a certificate */
5905 { "tls-ticket-keys", bind_parse_tls_ticket_keys, 1 }, /* set file to load TLS ticket keys from */
5906 { "verify", bind_parse_verify, 1 }, /* set SSL verify method */
5907 { "npn", bind_parse_npn, 1 }, /* set NPN supported protocols */
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005908 { NULL, NULL, 0 },
5909}};
Emeric Brun46591952012-05-18 15:47:34 +02005910
Willy Tarreau92faadf2012-10-10 23:04:25 +02005911/* Note: must not be declared <const> as its list will be overwritten.
5912 * Please take care of keeping this list alphabetically sorted, doing so helps
5913 * all code contributors.
5914 * Optional keywords are also declared with a NULL ->parse() function so that
5915 * the config parser can report an appropriate error when a known keyword was
5916 * not enabled.
5917 */
5918static struct srv_kw_list srv_kws = { "SSL", { }, {
Emeric Brunef42d922012-10-11 16:11:36 +02005919 { "ca-file", srv_parse_ca_file, 1, 0 }, /* set CAfile to process verify server cert */
Emeric Brunecc91fe2012-10-11 15:05:10 +02005920 { "check-ssl", srv_parse_check_ssl, 0, 0 }, /* enable SSL for health checks */
5921 { "ciphers", srv_parse_ciphers, 1, 0 }, /* select the cipher suite */
Emeric Brunef42d922012-10-11 16:11:36 +02005922 { "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 +02005923 { "crt", srv_parse_crt, 1, 0 }, /* set client certificate */
Emeric Brunecc91fe2012-10-11 15:05:10 +02005924 { "force-sslv3", srv_parse_force_sslv3, 0, 0 }, /* force SSLv3 */
5925 { "force-tlsv10", srv_parse_force_tlsv10, 0, 0 }, /* force TLSv10 */
5926 { "force-tlsv11", srv_parse_force_tlsv11, 0, 0 }, /* force TLSv11 */
5927 { "force-tlsv12", srv_parse_force_tlsv12, 0, 0 }, /* force TLSv12 */
Willy Tarreau2a3fb1c2015-02-05 16:47:07 +01005928 { "no-ssl-reuse", srv_parse_no_ssl_reuse, 0, 0 }, /* disable session reuse */
Emeric Brunecc91fe2012-10-11 15:05:10 +02005929 { "no-sslv3", srv_parse_no_sslv3, 0, 0 }, /* disable SSLv3 */
5930 { "no-tlsv10", srv_parse_no_tlsv10, 0, 0 }, /* disable TLSv10 */
5931 { "no-tlsv11", srv_parse_no_tlsv11, 0, 0 }, /* disable TLSv11 */
5932 { "no-tlsv12", srv_parse_no_tlsv12, 0, 0 }, /* disable TLSv12 */
Emeric Brunf9c5c472012-10-11 15:28:34 +02005933 { "no-tls-tickets", srv_parse_no_tls_tickets, 0, 0 }, /* disable session resumption tickets */
David Safb76832014-05-08 23:42:08 -04005934 { "send-proxy-v2-ssl", srv_parse_send_proxy_ssl, 0, 0 }, /* send PROXY protocol header v2 with SSL info */
5935 { "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 +02005936 { "sni", srv_parse_sni, 1, 0 }, /* send SNI extension */
Emeric Brunecc91fe2012-10-11 15:05:10 +02005937 { "ssl", srv_parse_ssl, 0, 0 }, /* enable SSL processing */
Emeric Brunef42d922012-10-11 16:11:36 +02005938 { "verify", srv_parse_verify, 1, 0 }, /* set SSL verify method */
Evan Broderbe554312013-06-27 00:05:25 -07005939 { "verifyhost", srv_parse_verifyhost, 1, 0 }, /* require that SSL cert verifies for hostname */
Willy Tarreau92faadf2012-10-10 23:04:25 +02005940 { NULL, NULL, 0, 0 },
5941}};
5942
Emeric Brun2c86cbf2014-10-30 15:56:50 +01005943static struct cfg_kw_list cfg_kws = {ILH, {
5944 { CFG_GLOBAL, "ssl-default-bind-options", ssl_parse_default_bind_options },
5945 { CFG_GLOBAL, "ssl-default-server-options", ssl_parse_default_server_options },
5946 { 0, NULL, NULL },
5947}};
5948
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02005949/* transport-layer operations for SSL sockets */
5950struct xprt_ops ssl_sock = {
Emeric Brun46591952012-05-18 15:47:34 +02005951 .snd_buf = ssl_sock_from_buf,
5952 .rcv_buf = ssl_sock_to_buf,
5953 .rcv_pipe = NULL,
5954 .snd_pipe = NULL,
5955 .shutr = NULL,
5956 .shutw = ssl_sock_shutw,
5957 .close = ssl_sock_close,
5958 .init = ssl_sock_init,
5959};
5960
Daniel Jakots54ffb912015-11-06 20:02:41 +01005961#if (OPENSSL_VERSION_NUMBER >= 0x1000200fL && !defined OPENSSL_NO_TLSEXT && !defined OPENSSL_IS_BORINGSSL && !defined LIBRESSL_VERSION_NUMBER)
Janusz Dziemidowicz2c701b52015-03-07 23:03:59 +01005962
5963static void ssl_sock_sctl_free_func(void *parent, void *ptr, CRYPTO_EX_DATA *ad, int idx, long argl, void *argp)
5964{
5965 if (ptr) {
5966 chunk_destroy(ptr);
5967 free(ptr);
5968 }
5969}
5970
5971#endif
5972
Emeric Brun46591952012-05-18 15:47:34 +02005973__attribute__((constructor))
Willy Tarreau92faadf2012-10-10 23:04:25 +02005974static void __ssl_sock_init(void)
5975{
Emeric Brun46591952012-05-18 15:47:34 +02005976 STACK_OF(SSL_COMP)* cm;
5977
Willy Tarreau610f04b2014-02-13 11:36:41 +01005978#ifdef LISTEN_DEFAULT_CIPHERS
5979 global.listen_default_ciphers = LISTEN_DEFAULT_CIPHERS;
5980#endif
5981#ifdef CONNECT_DEFAULT_CIPHERS
5982 global.connect_default_ciphers = CONNECT_DEFAULT_CIPHERS;
5983#endif
5984 if (global.listen_default_ciphers)
5985 global.listen_default_ciphers = strdup(global.listen_default_ciphers);
5986 if (global.connect_default_ciphers)
5987 global.connect_default_ciphers = strdup(global.connect_default_ciphers);
Emeric Brun2c86cbf2014-10-30 15:56:50 +01005988 global.listen_default_ssloptions = BC_SSL_O_NONE;
5989 global.connect_default_ssloptions = SRV_SSL_O_NONE;
Willy Tarreau610f04b2014-02-13 11:36:41 +01005990
Emeric Brun46591952012-05-18 15:47:34 +02005991 SSL_library_init();
5992 cm = SSL_COMP_get_compression_methods();
5993 sk_SSL_COMP_zero(cm);
Daniel Jakots54ffb912015-11-06 20:02:41 +01005994#if (OPENSSL_VERSION_NUMBER >= 0x1000200fL && !defined OPENSSL_NO_TLSEXT && !defined OPENSSL_IS_BORINGSSL && !defined LIBRESSL_VERSION_NUMBER)
Janusz Dziemidowicz2c701b52015-03-07 23:03:59 +01005995 sctl_ex_index = SSL_CTX_get_ex_new_index(0, NULL, NULL, NULL, ssl_sock_sctl_free_func);
5996#endif
Willy Tarreau7875d092012-09-10 08:20:03 +02005997 sample_register_fetches(&sample_fetch_keywords);
5998 acl_register_keywords(&acl_kws);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005999 bind_register_keywords(&bind_kws);
Willy Tarreau92faadf2012-10-10 23:04:25 +02006000 srv_register_keywords(&srv_kws);
Emeric Brun2c86cbf2014-10-30 15:56:50 +01006001 cfg_register_keywords(&cfg_kws);
Willy Tarreaud92aa5c2015-01-15 21:34:39 +01006002
6003 global.ssl_session_max_cost = SSL_SESSION_MAX_COST;
6004 global.ssl_handshake_max_cost = SSL_HANDSHAKE_MAX_COST;
Remi Gacogne4f902b82015-05-28 16:23:00 +02006005
6006#ifndef OPENSSL_NO_DH
6007 ssl_dh_ptr_index = SSL_CTX_get_ex_new_index(0, NULL, NULL, NULL, NULL);
6008#endif
Emeric Brun46591952012-05-18 15:47:34 +02006009}
6010
Remi Gacogned3a23c32015-05-28 16:39:47 +02006011__attribute__((destructor))
6012static void __ssl_sock_deinit(void)
6013{
Willy Tarreaua84c2672015-10-09 12:10:13 +02006014#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Christopher Faulet31af49d2015-06-09 17:29:50 +02006015 lru64_destroy(ssl_ctx_lru_tree);
Willy Tarreaua84c2672015-10-09 12:10:13 +02006016#endif
Christopher Faulet31af49d2015-06-09 17:29:50 +02006017
Remi Gacogned3a23c32015-05-28 16:39:47 +02006018#ifndef OPENSSL_NO_DH
6019 if (local_dh_1024) {
6020 DH_free(local_dh_1024);
6021 local_dh_1024 = NULL;
6022 }
6023
6024 if (local_dh_2048) {
6025 DH_free(local_dh_2048);
6026 local_dh_2048 = NULL;
6027 }
6028
6029 if (local_dh_4096) {
6030 DH_free(local_dh_4096);
6031 local_dh_4096 = NULL;
6032 }
6033
Remi Gacogne47783ef2015-05-29 15:53:22 +02006034 if (global_dh) {
6035 DH_free(global_dh);
6036 global_dh = NULL;
6037 }
Remi Gacogned3a23c32015-05-28 16:39:47 +02006038#endif
6039
6040 ERR_remove_state(0);
6041 ERR_free_strings();
6042
6043 EVP_cleanup();
6044
6045#if OPENSSL_VERSION_NUMBER >= 0x00907000L
6046 CRYPTO_cleanup_all_ex_data();
6047#endif
6048}
6049
6050
Emeric Brun46591952012-05-18 15:47:34 +02006051/*
6052 * Local variables:
6053 * c-indent-level: 8
6054 * c-basic-offset: 8
6055 * End:
6056 */