blob: 5319532583125a4ac7548bd432c9febdb8c141a1 [file] [log] [blame]
Emeric Brun46591952012-05-18 15:47:34 +02001/*
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02002 * SSL/TLS transport layer over SOCK_STREAM sockets
Emeric Brun46591952012-05-18 15:47:34 +02003 *
4 * Copyright (C) 2012 EXCELIANCE, Emeric Brun <ebrun@exceliance.fr>
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version
9 * 2 of the License, or (at your option) any later version.
10 *
Willy Tarreau69845df2012-09-10 09:43:09 +020011 * Acknowledgement:
12 * We'd like to specially thank the Stud project authors for a very clean
13 * and well documented code which helped us understand how the OpenSSL API
14 * ought to be used in non-blocking mode. This is one difficult part which
15 * is not easy to get from the OpenSSL doc, and reading the Stud code made
16 * it much more obvious than the examples in the OpenSSL package. Keep up
17 * the good works, guys !
18 *
19 * Stud is an extremely efficient and scalable SSL/TLS proxy which combines
20 * particularly well with haproxy. For more info about this project, visit :
21 * https://github.com/bumptech/stud
22 *
Emeric Brun46591952012-05-18 15:47:34 +020023 */
24
25#define _GNU_SOURCE
Emeric Brunfc0421f2012-09-07 17:30:07 +020026#include <ctype.h>
27#include <dirent.h>
Emeric Brun46591952012-05-18 15:47:34 +020028#include <errno.h>
29#include <fcntl.h>
30#include <stdio.h>
31#include <stdlib.h>
Emeric Brunfc0421f2012-09-07 17:30:07 +020032#include <string.h>
33#include <unistd.h>
Emeric Brun46591952012-05-18 15:47:34 +020034
35#include <sys/socket.h>
36#include <sys/stat.h>
37#include <sys/types.h>
Christopher Faulet31af49d2015-06-09 17:29:50 +020038#include <netdb.h>
Emeric Brun46591952012-05-18 15:47:34 +020039#include <netinet/tcp.h>
40
41#include <openssl/ssl.h>
Emeric Brunfc0421f2012-09-07 17:30:07 +020042#include <openssl/x509.h>
43#include <openssl/x509v3.h>
44#include <openssl/x509.h>
45#include <openssl/err.h>
Thierry Fournier383085f2013-01-24 14:15:43 +010046#include <openssl/rand.h>
Lukas Tribuse4e30f72014-12-09 16:32:51 +010047#if (defined SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB && !defined OPENSSL_NO_OCSP)
Emeric Brun4147b2e2014-06-16 18:36:30 +020048#include <openssl/ocsp.h>
49#endif
Remi Gacogne4f902b82015-05-28 16:23:00 +020050#ifndef OPENSSL_NO_DH
51#include <openssl/dh.h>
52#endif
Emeric Brun46591952012-05-18 15:47:34 +020053
Christopher Faulet31af49d2015-06-09 17:29:50 +020054#include <import/lru.h>
55#include <import/xxhash.h>
56
Emeric Brun46591952012-05-18 15:47:34 +020057#include <common/buffer.h>
58#include <common/compat.h>
59#include <common/config.h>
60#include <common/debug.h>
Willy Tarreau79eeafa2012-09-14 07:53:05 +020061#include <common/errors.h>
Emeric Brun46591952012-05-18 15:47:34 +020062#include <common/standard.h>
63#include <common/ticks.h>
64#include <common/time.h>
Emeric Brun2c86cbf2014-10-30 15:56:50 +010065#include <common/cfgparse.h>
Nenad Merdanovic05552d42015-02-27 19:56:49 +010066#include <common/base64.h>
Emeric Brun46591952012-05-18 15:47:34 +020067
Emeric Brunfc0421f2012-09-07 17:30:07 +020068#include <ebsttree.h>
69
70#include <types/global.h>
71#include <types/ssl_sock.h>
72
Willy Tarreau7875d092012-09-10 08:20:03 +020073#include <proto/acl.h>
74#include <proto/arg.h>
Emeric Brun46591952012-05-18 15:47:34 +020075#include <proto/connection.h>
76#include <proto/fd.h>
77#include <proto/freq_ctr.h>
78#include <proto/frontend.h>
Willy Tarreau79eeafa2012-09-14 07:53:05 +020079#include <proto/listener.h>
Thierry FOURNIERed66c292013-11-28 11:05:19 +010080#include <proto/pattern.h>
Christopher Faulet31af49d2015-06-09 17:29:50 +020081#include <proto/proto_tcp.h>
Willy Tarreau92faadf2012-10-10 23:04:25 +020082#include <proto/server.h>
Emeric Brun46591952012-05-18 15:47:34 +020083#include <proto/log.h>
Emeric Brun94324a42012-10-11 14:00:19 +020084#include <proto/proxy.h>
Emeric Brunfc0421f2012-09-07 17:30:07 +020085#include <proto/shctx.h>
Emeric Brun46591952012-05-18 15:47:34 +020086#include <proto/ssl_sock.h>
Willy Tarreau9ad7bd42015-04-03 19:19:59 +020087#include <proto/stream.h>
Emeric Brun46591952012-05-18 15:47:34 +020088#include <proto/task.h>
89
Willy Tarreau518cedd2014-02-17 15:43:01 +010090/* Warning, these are bits, not integers! */
Emeric Brune64aef12012-09-21 13:15:06 +020091#define SSL_SOCK_ST_FL_VERIFY_DONE 0x00000001
Emeric Brund8b2bb52014-01-28 15:43:53 +010092#define SSL_SOCK_ST_FL_16K_WBFSIZE 0x00000002
Willy Tarreau518cedd2014-02-17 15:43:01 +010093#define SSL_SOCK_SEND_UNLIMITED 0x00000004
Emeric Brun29f037d2014-04-25 19:05:36 +020094#define SSL_SOCK_RECV_HEARTBEAT 0x00000008
95
Emeric Brunf282a812012-09-21 15:27:54 +020096/* bits 0xFFFF0000 are reserved to store verify errors */
97
98/* Verify errors macros */
99#define SSL_SOCK_CA_ERROR_TO_ST(e) (((e > 63) ? 63 : e) << (16))
100#define SSL_SOCK_CAEDEPTH_TO_ST(d) (((d > 15) ? 15 : d) << (6+16))
101#define SSL_SOCK_CRTERROR_TO_ST(e) (((e > 63) ? 63 : e) << (4+6+16))
102
103#define SSL_SOCK_ST_TO_CA_ERROR(s) ((s >> (16)) & 63)
104#define SSL_SOCK_ST_TO_CAEDEPTH(s) ((s >> (6+16)) & 15)
105#define SSL_SOCK_ST_TO_CRTERROR(s) ((s >> (4+6+16)) & 63)
Emeric Brune64aef12012-09-21 13:15:06 +0200106
Nenad Merdanovic05552d42015-02-27 19:56:49 +0100107/* Supported hash function for TLS tickets */
108#ifdef OPENSSL_NO_SHA256
109#define HASH_FUNCT EVP_sha1
110#else
111#define HASH_FUNCT EVP_sha256
112#endif /* OPENSSL_NO_SHA256 */
113
Emeric Brun850efd52014-01-29 12:24:34 +0100114/* server and bind verify method, it uses a global value as default */
115enum {
116 SSL_SOCK_VERIFY_DEFAULT = 0,
117 SSL_SOCK_VERIFY_REQUIRED = 1,
118 SSL_SOCK_VERIFY_OPTIONAL = 2,
119 SSL_SOCK_VERIFY_NONE = 3,
120};
121
Willy Tarreau71b734c2014-01-28 15:19:44 +0100122int sslconns = 0;
123int totalsslconns = 0;
Emeric Brune1f38db2012-09-03 20:36:47 +0200124
Nenad Merdanovic200b0fa2015-05-09 08:46:01 +0200125#if (defined SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB && TLS_TICKETS_NO > 0)
126struct list tlskeys_reference = LIST_HEAD_INIT(tlskeys_reference);
127#endif
128
Remi Gacogne8de54152014-07-15 11:36:40 +0200129#ifndef OPENSSL_NO_DH
Remi Gacogne4f902b82015-05-28 16:23:00 +0200130static int ssl_dh_ptr_index = -1;
Remi Gacogne47783ef2015-05-29 15:53:22 +0200131static DH *global_dh = NULL;
Remi Gacogne8de54152014-07-15 11:36:40 +0200132static DH *local_dh_1024 = NULL;
133static DH *local_dh_2048 = NULL;
134static DH *local_dh_4096 = NULL;
Remi Gacogne8de54152014-07-15 11:36:40 +0200135#endif /* OPENSSL_NO_DH */
136
Willy Tarreauc8ad3be2015-06-17 15:48:26 +0200137#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Christopher Faulet31af49d2015-06-09 17:29:50 +0200138/* X509V3 Extensions that will be added on generated certificates */
139#define X509V3_EXT_SIZE 5
140static char *x509v3_ext_names[X509V3_EXT_SIZE] = {
141 "basicConstraints",
142 "nsComment",
143 "subjectKeyIdentifier",
144 "authorityKeyIdentifier",
145 "keyUsage",
146};
147static char *x509v3_ext_values[X509V3_EXT_SIZE] = {
148 "CA:FALSE",
149 "\"OpenSSL Generated Certificate\"",
150 "hash",
151 "keyid,issuer:always",
152 "nonRepudiation,digitalSignature,keyEncipherment"
153};
154
155/* LRU cache to store generated certificate */
156static struct lru64_head *ssl_ctx_lru_tree = NULL;
157static unsigned int ssl_ctx_lru_seed = 0;
Willy Tarreauc8ad3be2015-06-17 15:48:26 +0200158#endif // SSL_CTRL_SET_TLSEXT_HOSTNAME
159
160#if (defined SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB && !defined OPENSSL_NO_OCSP)
161struct certificate_ocsp {
162 struct ebmb_node key;
163 unsigned char key_data[OCSP_MAX_CERTID_ASN1_LENGTH];
164 struct chunk response;
165 long expire;
166};
Christopher Faulet31af49d2015-06-09 17:29:50 +0200167
Emeric Brun4f3c87a2014-06-20 15:46:13 +0200168/*
169 * This function returns the number of seconds elapsed
170 * since the Epoch, 1970-01-01 00:00:00 +0000 (UTC) and the
171 * date presented un ASN1_GENERALIZEDTIME.
172 *
173 * In parsing error case, it returns -1.
174 */
175static long asn1_generalizedtime_to_epoch(ASN1_GENERALIZEDTIME *d)
176{
177 long epoch;
178 char *p, *end;
179 const unsigned short month_offset[12] = {
180 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334
181 };
182 int year, month;
183
184 if (!d || (d->type != V_ASN1_GENERALIZEDTIME)) return -1;
185
186 p = (char *)d->data;
187 end = p + d->length;
188
189 if (end - p < 4) return -1;
190 year = 1000 * (p[0] - '0') + 100 * (p[1] - '0') + 10 * (p[2] - '0') + p[3] - '0';
191 p += 4;
192 if (end - p < 2) return -1;
193 month = 10 * (p[0] - '0') + p[1] - '0';
194 if (month < 1 || month > 12) return -1;
195 /* Compute the number of seconds since 1 jan 1970 and the beginning of current month
196 We consider leap years and the current month (<marsh or not) */
197 epoch = ( ((year - 1970) * 365)
198 + ((year - (month < 3)) / 4 - (year - (month < 3)) / 100 + (year - (month < 3)) / 400)
199 - ((1970 - 1) / 4 - (1970 - 1) / 100 + (1970 - 1) / 400)
200 + month_offset[month-1]
201 ) * 24 * 60 * 60;
202 p += 2;
203 if (end - p < 2) return -1;
204 /* Add the number of seconds of completed days of current month */
205 epoch += (10 * (p[0] - '0') + p[1] - '0' - 1) * 24 * 60 * 60;
206 p += 2;
207 if (end - p < 2) return -1;
208 /* Add the completed hours of the current day */
209 epoch += (10 * (p[0] - '0') + p[1] - '0') * 60 * 60;
210 p += 2;
211 if (end - p < 2) return -1;
212 /* Add the completed minutes of the current hour */
213 epoch += (10 * (p[0] - '0') + p[1] - '0') * 60;
214 p += 2;
215 if (p == end) return -1;
216 /* Test if there is available seconds */
217 if (p[0] < '0' || p[0] > '9')
218 goto nosec;
219 if (end - p < 2) return -1;
220 /* Add the seconds of the current minute */
221 epoch += 10 * (p[0] - '0') + p[1] - '0';
222 p += 2;
223 if (p == end) return -1;
224 /* Ignore seconds float part if present */
225 if (p[0] == '.') {
226 do {
227 if (++p == end) return -1;
228 } while (p[0] >= '0' && p[0] <= '9');
229 }
230
231nosec:
232 if (p[0] == 'Z') {
233 if (end - p != 1) return -1;
234 return epoch;
235 }
236 else if (p[0] == '+') {
237 if (end - p != 5) return -1;
238 /* Apply timezone offset */
239 return epoch - ((10 * (p[1] - '0') + p[2] - '0') * 60 + (10 * (p[3] - '0') + p[4] - '0')) * 60;
240 }
241 else if (p[0] == '-') {
242 if (end - p != 5) return -1;
243 /* Apply timezone offset */
244 return epoch + ((10 * (p[1] - '0') + p[2] - '0') * 60 + (10 * (p[3] - '0') + p[4] - '0')) * 60;
245 }
246
247 return -1;
248}
249
Emeric Brun1d3865b2014-06-20 15:37:32 +0200250static struct eb_root cert_ocsp_tree = EB_ROOT_UNIQUE;
Emeric Brun4147b2e2014-06-16 18:36:30 +0200251
252/* This function starts to check if the OCSP response (in DER format) contained
253 * in chunk 'ocsp_response' is valid (else exits on error).
254 * If 'cid' is not NULL, it will be compared to the OCSP certificate ID
255 * contained in the OCSP Response and exits on error if no match.
256 * If it's a valid OCSP Response:
257 * If 'ocsp' is not NULL, the chunk is copied in the OCSP response's container
258 * pointed by 'ocsp'.
259 * If 'ocsp' is NULL, the function looks up into the OCSP response's
260 * containers tree (using as index the ASN1 form of the OCSP Certificate ID extracted
261 * from the response) and exits on error if not found. Finally, If an OCSP response is
262 * already present in the container, it will be overwritten.
263 *
264 * Note: OCSP response containing more than one OCSP Single response is not
265 * considered valid.
266 *
267 * Returns 0 on success, 1 in error case.
268 */
269static int ssl_sock_load_ocsp_response(struct chunk *ocsp_response, struct certificate_ocsp *ocsp, OCSP_CERTID *cid, char **err)
270{
271 OCSP_RESPONSE *resp;
272 OCSP_BASICRESP *bs = NULL;
273 OCSP_SINGLERESP *sr;
274 unsigned char *p = (unsigned char *)ocsp_response->str;
275 int rc , count_sr;
Emeric Brun13a6b482014-06-20 15:44:34 +0200276 ASN1_GENERALIZEDTIME *revtime, *thisupd, *nextupd = NULL;
Emeric Brun4147b2e2014-06-16 18:36:30 +0200277 int reason;
278 int ret = 1;
279
280 resp = d2i_OCSP_RESPONSE(NULL, (const unsigned char **)&p, ocsp_response->len);
281 if (!resp) {
282 memprintf(err, "Unable to parse OCSP response");
283 goto out;
284 }
285
286 rc = OCSP_response_status(resp);
287 if (rc != OCSP_RESPONSE_STATUS_SUCCESSFUL) {
288 memprintf(err, "OCSP response status not successful");
289 goto out;
290 }
291
292 bs = OCSP_response_get1_basic(resp);
293 if (!bs) {
294 memprintf(err, "Failed to get basic response from OCSP Response");
295 goto out;
296 }
297
298 count_sr = OCSP_resp_count(bs);
299 if (count_sr > 1) {
300 memprintf(err, "OCSP response ignored because contains multiple single responses (%d)", count_sr);
301 goto out;
302 }
303
304 sr = OCSP_resp_get0(bs, 0);
305 if (!sr) {
306 memprintf(err, "Failed to get OCSP single response");
307 goto out;
308 }
309
310 rc = OCSP_single_get0_status(sr, &reason, &revtime, &thisupd, &nextupd);
311 if (rc != V_OCSP_CERTSTATUS_GOOD) {
312 memprintf(err, "OCSP single response: certificate status not good");
313 goto out;
314 }
315
Emeric Brun13a6b482014-06-20 15:44:34 +0200316 if (!nextupd) {
317 memprintf(err, "OCSP single response: missing nextupdate");
318 goto out;
319 }
320
Emeric Brunc8b27b62014-06-19 14:16:17 +0200321 rc = OCSP_check_validity(thisupd, nextupd, OCSP_MAX_RESPONSE_TIME_SKEW, -1);
Emeric Brun4147b2e2014-06-16 18:36:30 +0200322 if (!rc) {
323 memprintf(err, "OCSP single response: no longer valid.");
324 goto out;
325 }
326
327 if (cid) {
328 if (OCSP_id_cmp(sr->certId, cid)) {
329 memprintf(err, "OCSP single response: Certificate ID does not match certificate and issuer");
330 goto out;
331 }
332 }
333
334 if (!ocsp) {
335 unsigned char key[OCSP_MAX_CERTID_ASN1_LENGTH];
336 unsigned char *p;
337
338 rc = i2d_OCSP_CERTID(sr->certId, NULL);
339 if (!rc) {
340 memprintf(err, "OCSP single response: Unable to encode Certificate ID");
341 goto out;
342 }
343
344 if (rc > OCSP_MAX_CERTID_ASN1_LENGTH) {
345 memprintf(err, "OCSP single response: Certificate ID too long");
346 goto out;
347 }
348
349 p = key;
350 memset(key, 0, OCSP_MAX_CERTID_ASN1_LENGTH);
351 i2d_OCSP_CERTID(sr->certId, &p);
352 ocsp = (struct certificate_ocsp *)ebmb_lookup(&cert_ocsp_tree, key, OCSP_MAX_CERTID_ASN1_LENGTH);
353 if (!ocsp) {
354 memprintf(err, "OCSP single response: Certificate ID does not match any certificate or issuer");
355 goto out;
356 }
357 }
358
359 /* According to comments on "chunk_dup", the
360 previous chunk buffer will be freed */
361 if (!chunk_dup(&ocsp->response, ocsp_response)) {
362 memprintf(err, "OCSP response: Memory allocation error");
363 goto out;
364 }
365
Emeric Brun4f3c87a2014-06-20 15:46:13 +0200366 ocsp->expire = asn1_generalizedtime_to_epoch(nextupd) - OCSP_MAX_RESPONSE_TIME_SKEW;
367
Emeric Brun4147b2e2014-06-16 18:36:30 +0200368 ret = 0;
369out:
370 if (bs)
371 OCSP_BASICRESP_free(bs);
372
373 if (resp)
374 OCSP_RESPONSE_free(resp);
375
376 return ret;
377}
378/*
379 * External function use to update the OCSP response in the OCSP response's
380 * containers tree. The chunk 'ocsp_response' must contain the OCSP response
381 * to update in DER format.
382 *
383 * Returns 0 on success, 1 in error case.
384 */
385int ssl_sock_update_ocsp_response(struct chunk *ocsp_response, char **err)
386{
387 return ssl_sock_load_ocsp_response(ocsp_response, NULL, NULL, err);
388}
389
390/*
391 * This function load the OCSP Resonse in DER format contained in file at
392 * path 'ocsp_path' and call 'ssl_sock_load_ocsp_response'
393 *
394 * Returns 0 on success, 1 in error case.
395 */
396static int ssl_sock_load_ocsp_response_from_file(const char *ocsp_path, struct certificate_ocsp *ocsp, OCSP_CERTID *cid, char **err)
397{
398 int fd = -1;
399 int r = 0;
400 int ret = 1;
401
402 fd = open(ocsp_path, O_RDONLY);
403 if (fd == -1) {
404 memprintf(err, "Error opening OCSP response file");
405 goto end;
406 }
407
408 trash.len = 0;
409 while (trash.len < trash.size) {
410 r = read(fd, trash.str + trash.len, trash.size - trash.len);
411 if (r < 0) {
412 if (errno == EINTR)
413 continue;
414
415 memprintf(err, "Error reading OCSP response from file");
416 goto end;
417 }
418 else if (r == 0) {
419 break;
420 }
421 trash.len += r;
422 }
423
424 close(fd);
425 fd = -1;
426
427 ret = ssl_sock_load_ocsp_response(&trash, ocsp, cid, err);
428end:
429 if (fd != -1)
430 close(fd);
431
432 return ret;
433}
434
Nenad Merdanovic05552d42015-02-27 19:56:49 +0100435#if (defined SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB && TLS_TICKETS_NO > 0)
436static 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)
437{
438 struct tls_sess_key *keys;
439 struct connection *conn;
440 int head;
441 int i;
442
443 conn = (struct connection *)SSL_get_app_data(s);
Nenad Merdanovic146defa2015-05-09 08:46:00 +0200444 keys = objt_listener(conn->target)->bind_conf->keys_ref->tlskeys;
445 head = objt_listener(conn->target)->bind_conf->keys_ref->tls_ticket_enc_index;
Nenad Merdanovic05552d42015-02-27 19:56:49 +0100446
447 if (enc) {
448 memcpy(key_name, keys[head].name, 16);
449
450 if(!RAND_pseudo_bytes(iv, EVP_MAX_IV_LENGTH))
451 return -1;
452
453 if(!EVP_EncryptInit_ex(ectx, EVP_aes_128_cbc(), NULL, keys[head].aes_key, iv))
454 return -1;
455
456 HMAC_Init_ex(hctx, keys[head].hmac_key, 16, HASH_FUNCT(), NULL);
457
458 return 1;
459 } else {
460 for (i = 0; i < TLS_TICKETS_NO; i++) {
461 if (!memcmp(key_name, keys[(head + i) % TLS_TICKETS_NO].name, 16))
462 goto found;
463 }
464 return 0;
465
466 found:
467 HMAC_Init_ex(hctx, keys[(head + i) % TLS_TICKETS_NO].hmac_key, 16, HASH_FUNCT(), NULL);
468 if(!EVP_DecryptInit_ex(ectx, EVP_aes_128_cbc(), NULL, keys[(head + i) % TLS_TICKETS_NO].aes_key, iv))
469 return -1;
470 /* 2 for key renewal, 1 if current key is still valid */
471 return i ? 2 : 1;
472 }
Nenad Merdanovic200b0fa2015-05-09 08:46:01 +0200473}
474
475struct tls_keys_ref *tlskeys_ref_lookup(const char *filename)
476{
477 struct tls_keys_ref *ref;
478
479 list_for_each_entry(ref, &tlskeys_reference, list)
480 if (ref->filename && strcmp(filename, ref->filename) == 0)
481 return ref;
482 return NULL;
483}
484
485struct tls_keys_ref *tlskeys_ref_lookupid(int unique_id)
486{
487 struct tls_keys_ref *ref;
488
489 list_for_each_entry(ref, &tlskeys_reference, list)
490 if (ref->unique_id == unique_id)
491 return ref;
492 return NULL;
493}
494
495int ssl_sock_update_tlskey(char *filename, struct chunk *tlskey, char **err) {
496 struct tls_keys_ref *ref = tlskeys_ref_lookup(filename);
497
498 if(!ref) {
499 memprintf(err, "Unable to locate the referenced filename: %s", filename);
500 return 1;
501 }
502
Pradeep Jindalcc79b002015-08-20 18:25:17 +0530503 memcpy((char *) (ref->tlskeys + ((ref->tls_ticket_enc_index + 2) % TLS_TICKETS_NO)), tlskey->str, tlskey->len);
504 ref->tls_ticket_enc_index = (ref->tls_ticket_enc_index + 1) % TLS_TICKETS_NO;
Nenad Merdanovic200b0fa2015-05-09 08:46:01 +0200505
506 return 0;
Nenad Merdanovic05552d42015-02-27 19:56:49 +0100507}
Nenad Merdanovic200b0fa2015-05-09 08:46:01 +0200508
509/* This function finalize the configuration parsing. Its set all the
510 * automatic ids
511 */
512void tlskeys_finalize_config(void)
513{
514 int i = 0;
515 struct tls_keys_ref *ref, *ref2, *ref3;
516 struct list tkr = LIST_HEAD_INIT(tkr);
517
518 list_for_each_entry(ref, &tlskeys_reference, list) {
519 if (ref->unique_id == -1) {
520 /* Look for the first free id. */
521 while (1) {
522 list_for_each_entry(ref2, &tlskeys_reference, list) {
523 if (ref2->unique_id == i) {
524 i++;
525 break;
526 }
527 }
528 if (&ref2->list == &tlskeys_reference)
529 break;
530 }
531
532 /* Uses the unique id and increment it for the next entry. */
533 ref->unique_id = i;
534 i++;
535 }
536 }
537
538 /* This sort the reference list by id. */
539 list_for_each_entry_safe(ref, ref2, &tlskeys_reference, list) {
540 LIST_DEL(&ref->list);
541 list_for_each_entry(ref3, &tkr, list) {
542 if (ref->unique_id < ref3->unique_id) {
543 LIST_ADDQ(&ref3->list, &ref->list);
544 break;
545 }
546 }
547 if (&ref3->list == &tkr)
548 LIST_ADDQ(&tkr, &ref->list);
549 }
550
551 /* swap root */
552 LIST_ADD(&tkr, &tlskeys_reference);
553 LIST_DEL(&tkr);
554}
555
Nenad Merdanovic05552d42015-02-27 19:56:49 +0100556#endif /* SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB */
557
Emeric Brun4147b2e2014-06-16 18:36:30 +0200558/*
559 * Callback used to set OCSP status extension content in server hello.
560 */
561int ssl_sock_ocsp_stapling_cbk(SSL *ssl, void *arg)
562{
563 struct certificate_ocsp *ocsp = (struct certificate_ocsp *)arg;
564 char* ssl_buf;
565
566 if (!ocsp ||
567 !ocsp->response.str ||
Emeric Brun4f3c87a2014-06-20 15:46:13 +0200568 !ocsp->response.len ||
569 (ocsp->expire < now.tv_sec))
Emeric Brun4147b2e2014-06-16 18:36:30 +0200570 return SSL_TLSEXT_ERR_NOACK;
571
572 ssl_buf = OPENSSL_malloc(ocsp->response.len);
573 if (!ssl_buf)
574 return SSL_TLSEXT_ERR_NOACK;
575
576 memcpy(ssl_buf, ocsp->response.str, ocsp->response.len);
577 SSL_set_tlsext_status_ocsp_resp(ssl, ssl_buf, ocsp->response.len);
578
579 return SSL_TLSEXT_ERR_OK;
580}
581
582/*
583 * This function enables the handling of OCSP status extension on 'ctx' if a
584 * file name 'cert_path' suffixed using ".ocsp" is present.
585 * To enable OCSP status extension, the issuer's certificate is mandatory.
586 * It should be present in the certificate's extra chain builded from file
587 * 'cert_path'. If not found, the issuer certificate is loaded from a file
588 * named 'cert_path' suffixed using '.issuer'.
589 *
590 * In addition, ".ocsp" file content is loaded as a DER format of an OCSP
591 * response. If file is empty or content is not a valid OCSP response,
592 * OCSP status extension is enabled but OCSP response is ignored (a warning
593 * is displayed).
594 *
595 * Returns 1 if no ".ocsp" file found, 0 if OCSP status extension is
596 * succesfully enabled, or -1 in other error case.
597 */
598static int ssl_sock_load_ocsp(SSL_CTX *ctx, const char *cert_path)
599{
600
601 BIO *in = NULL;
602 X509 *x, *xi = NULL, *issuer = NULL;
603 STACK_OF(X509) *chain = NULL;
604 OCSP_CERTID *cid = NULL;
605 SSL *ssl;
606 char ocsp_path[MAXPATHLEN+1];
607 int i, ret = -1;
608 struct stat st;
609 struct certificate_ocsp *ocsp = NULL, *iocsp;
610 char *warn = NULL;
611 unsigned char *p;
612
613 snprintf(ocsp_path, MAXPATHLEN+1, "%s.ocsp", cert_path);
614
615 if (stat(ocsp_path, &st))
616 return 1;
617
618 ssl = SSL_new(ctx);
619 if (!ssl)
620 goto out;
621
622 x = SSL_get_certificate(ssl);
623 if (!x)
624 goto out;
625
626 /* Try to lookup for issuer in certificate extra chain */
627#ifdef SSL_CTRL_GET_EXTRA_CHAIN_CERTS
628 SSL_CTX_get_extra_chain_certs(ctx, &chain);
629#else
630 chain = ctx->extra_certs;
631#endif
632 for (i = 0; i < sk_X509_num(chain); i++) {
633 issuer = sk_X509_value(chain, i);
634 if (X509_check_issued(issuer, x) == X509_V_OK)
635 break;
636 else
637 issuer = NULL;
638 }
639
640 /* If not found try to load issuer from a suffixed file */
641 if (!issuer) {
642 char issuer_path[MAXPATHLEN+1];
643
644 in = BIO_new(BIO_s_file());
645 if (!in)
646 goto out;
647
648 snprintf(issuer_path, MAXPATHLEN+1, "%s.issuer", cert_path);
649 if (BIO_read_filename(in, issuer_path) <= 0)
650 goto out;
651
652 xi = PEM_read_bio_X509_AUX(in, NULL, ctx->default_passwd_callback, ctx->default_passwd_callback_userdata);
653 if (!xi)
654 goto out;
655
656 if (X509_check_issued(xi, x) != X509_V_OK)
657 goto out;
658
659 issuer = xi;
660 }
661
662 cid = OCSP_cert_to_id(0, x, issuer);
663 if (!cid)
664 goto out;
665
666 i = i2d_OCSP_CERTID(cid, NULL);
667 if (!i || (i > OCSP_MAX_CERTID_ASN1_LENGTH))
668 goto out;
669
670 ocsp = calloc(1, sizeof(struct certificate_ocsp));
671 if (!ocsp)
672 goto out;
673
674 p = ocsp->key_data;
675 i2d_OCSP_CERTID(cid, &p);
676
677 iocsp = (struct certificate_ocsp *)ebmb_insert(&cert_ocsp_tree, &ocsp->key, OCSP_MAX_CERTID_ASN1_LENGTH);
678 if (iocsp == ocsp)
679 ocsp = NULL;
680
681 SSL_CTX_set_tlsext_status_cb(ctx, ssl_sock_ocsp_stapling_cbk);
682 SSL_CTX_set_tlsext_status_arg(ctx, iocsp);
683
684 ret = 0;
685
686 warn = NULL;
687 if (ssl_sock_load_ocsp_response_from_file(ocsp_path, iocsp, cid, &warn)) {
688 memprintf(&warn, "Loading '%s': %s. Content will be ignored", ocsp_path, warn ? warn : "failure");
689 Warning("%s.\n", warn);
690 }
691
692out:
693 if (ssl)
694 SSL_free(ssl);
695
696 if (in)
697 BIO_free(in);
698
699 if (xi)
700 X509_free(xi);
701
702 if (cid)
703 OCSP_CERTID_free(cid);
704
705 if (ocsp)
706 free(ocsp);
707
708 if (warn)
709 free(warn);
710
711
712 return ret;
713}
714
715#endif
716
Janusz Dziemidowicz2c701b52015-03-07 23:03:59 +0100717#if (OPENSSL_VERSION_NUMBER >= 0x1000200fL && !defined OPENSSL_NO_TLSEXT && !defined OPENSSL_IS_BORINGSSL)
718
719#define CT_EXTENSION_TYPE 18
720
721static int sctl_ex_index = -1;
722
723/*
724 * Try to parse Signed Certificate Timestamp List structure. This function
725 * makes only basic test if the data seems like SCTL. No signature validation
726 * is performed.
727 */
728static int ssl_sock_parse_sctl(struct chunk *sctl)
729{
730 int ret = 1;
731 int len, pos, sct_len;
732 unsigned char *data;
733
734 if (sctl->len < 2)
735 goto out;
736
737 data = (unsigned char *)sctl->str;
738 len = (data[0] << 8) | data[1];
739
740 if (len + 2 != sctl->len)
741 goto out;
742
743 data = data + 2;
744 pos = 0;
745 while (pos < len) {
746 if (len - pos < 2)
747 goto out;
748
749 sct_len = (data[pos] << 8) | data[pos + 1];
750 if (pos + sct_len + 2 > len)
751 goto out;
752
753 pos += sct_len + 2;
754 }
755
756 ret = 0;
757
758out:
759 return ret;
760}
761
762static int ssl_sock_load_sctl_from_file(const char *sctl_path, struct chunk **sctl)
763{
764 int fd = -1;
765 int r = 0;
766 int ret = 1;
767
768 *sctl = NULL;
769
770 fd = open(sctl_path, O_RDONLY);
771 if (fd == -1)
772 goto end;
773
774 trash.len = 0;
775 while (trash.len < trash.size) {
776 r = read(fd, trash.str + trash.len, trash.size - trash.len);
777 if (r < 0) {
778 if (errno == EINTR)
779 continue;
780
781 goto end;
782 }
783 else if (r == 0) {
784 break;
785 }
786 trash.len += r;
787 }
788
789 ret = ssl_sock_parse_sctl(&trash);
790 if (ret)
791 goto end;
792
793 *sctl = calloc(1, sizeof(struct chunk));
794 if (!chunk_dup(*sctl, &trash)) {
795 free(*sctl);
796 *sctl = NULL;
797 goto end;
798 }
799
800end:
801 if (fd != -1)
802 close(fd);
803
804 return ret;
805}
806
807int ssl_sock_sctl_add_cbk(SSL *ssl, unsigned ext_type, const unsigned char **out, size_t *outlen, int *al, void *add_arg)
808{
809 struct chunk *sctl = (struct chunk *)add_arg;
810
811 *out = (unsigned char *)sctl->str;
812 *outlen = sctl->len;
813
814 return 1;
815}
816
817int ssl_sock_sctl_parse_cbk(SSL *s, unsigned int ext_type, const unsigned char *in, size_t inlen, int *al, void *parse_arg)
818{
819 return 1;
820}
821
822static int ssl_sock_load_sctl(SSL_CTX *ctx, const char *cert_path)
823{
824 char sctl_path[MAXPATHLEN+1];
825 int ret = -1;
826 struct stat st;
827 struct chunk *sctl = NULL;
828
829 snprintf(sctl_path, MAXPATHLEN+1, "%s.sctl", cert_path);
830
831 if (stat(sctl_path, &st))
832 return 1;
833
834 if (ssl_sock_load_sctl_from_file(sctl_path, &sctl))
835 goto out;
836
837 if (!SSL_CTX_add_server_custom_ext(ctx, CT_EXTENSION_TYPE, ssl_sock_sctl_add_cbk, NULL, sctl, ssl_sock_sctl_parse_cbk, NULL)) {
838 free(sctl);
839 goto out;
840 }
841
842 SSL_CTX_set_ex_data(ctx, sctl_ex_index, sctl);
843
844 ret = 0;
845
846out:
847 return ret;
848}
849
850#endif
851
Emeric Brune1f38db2012-09-03 20:36:47 +0200852void ssl_sock_infocbk(const SSL *ssl, int where, int ret)
853{
854 struct connection *conn = (struct connection *)SSL_get_app_data(ssl);
Emeric Brund8b2bb52014-01-28 15:43:53 +0100855 BIO *write_bio;
Willy Tarreau622317d2015-02-27 16:36:16 +0100856 (void)ret; /* shut gcc stupid warning */
Emeric Brune1f38db2012-09-03 20:36:47 +0200857
858 if (where & SSL_CB_HANDSHAKE_START) {
859 /* Disable renegotiation (CVE-2009-3555) */
Willy Tarreau20879a02012-12-03 16:32:10 +0100860 if (conn->flags & CO_FL_CONNECTED) {
Emeric Brune1f38db2012-09-03 20:36:47 +0200861 conn->flags |= CO_FL_ERROR;
Willy Tarreau20879a02012-12-03 16:32:10 +0100862 conn->err_code = CO_ER_SSL_RENEG;
863 }
Emeric Brune1f38db2012-09-03 20:36:47 +0200864 }
Emeric Brund8b2bb52014-01-28 15:43:53 +0100865
866 if ((where & SSL_CB_ACCEPT_LOOP) == SSL_CB_ACCEPT_LOOP) {
867 if (!(conn->xprt_st & SSL_SOCK_ST_FL_16K_WBFSIZE)) {
868 /* Long certificate chains optimz
869 If write and read bios are differents, we
870 consider that the buffering was activated,
871 so we rise the output buffer size from 4k
872 to 16k */
873 write_bio = SSL_get_wbio(ssl);
874 if (write_bio != SSL_get_rbio(ssl)) {
875 BIO_set_write_buffer_size(write_bio, 16384);
876 conn->xprt_st |= SSL_SOCK_ST_FL_16K_WBFSIZE;
877 }
878 }
879 }
Emeric Brunfc0421f2012-09-07 17:30:07 +0200880}
881
Emeric Brune64aef12012-09-21 13:15:06 +0200882/* Callback is called for each certificate of the chain during a verify
883 ok is set to 1 if preverify detect no error on current certificate.
884 Returns 0 to break the handshake, 1 otherwise. */
Evan Broderbe554312013-06-27 00:05:25 -0700885int ssl_sock_bind_verifycbk(int ok, X509_STORE_CTX *x_store)
Emeric Brune64aef12012-09-21 13:15:06 +0200886{
887 SSL *ssl;
888 struct connection *conn;
Emeric Brun81c00f02012-09-21 14:31:21 +0200889 int err, depth;
Emeric Brune64aef12012-09-21 13:15:06 +0200890
891 ssl = X509_STORE_CTX_get_ex_data(x_store, SSL_get_ex_data_X509_STORE_CTX_idx());
892 conn = (struct connection *)SSL_get_app_data(ssl);
893
Willy Tarreauf7bc57c2012-10-03 00:19:48 +0200894 conn->xprt_st |= SSL_SOCK_ST_FL_VERIFY_DONE;
Emeric Brune64aef12012-09-21 13:15:06 +0200895
Emeric Brun81c00f02012-09-21 14:31:21 +0200896 if (ok) /* no errors */
897 return ok;
898
899 depth = X509_STORE_CTX_get_error_depth(x_store);
900 err = X509_STORE_CTX_get_error(x_store);
901
902 /* check if CA error needs to be ignored */
903 if (depth > 0) {
Willy Tarreauf7bc57c2012-10-03 00:19:48 +0200904 if (!SSL_SOCK_ST_TO_CA_ERROR(conn->xprt_st)) {
905 conn->xprt_st |= SSL_SOCK_CA_ERROR_TO_ST(err);
906 conn->xprt_st |= SSL_SOCK_CAEDEPTH_TO_ST(depth);
Emeric Brunf282a812012-09-21 15:27:54 +0200907 }
908
Emeric Brun1eb20ef2012-12-03 13:24:29 +0100909 if (objt_listener(conn->target)->bind_conf->ca_ignerr & (1ULL << err)) {
910 ERR_clear_error();
Emeric Brun81c00f02012-09-21 14:31:21 +0200911 return 1;
Emeric Brun1eb20ef2012-12-03 13:24:29 +0100912 }
Emeric Brun81c00f02012-09-21 14:31:21 +0200913
Willy Tarreau20879a02012-12-03 16:32:10 +0100914 conn->err_code = CO_ER_SSL_CA_FAIL;
Emeric Brun81c00f02012-09-21 14:31:21 +0200915 return 0;
916 }
917
Willy Tarreauf7bc57c2012-10-03 00:19:48 +0200918 if (!SSL_SOCK_ST_TO_CRTERROR(conn->xprt_st))
919 conn->xprt_st |= SSL_SOCK_CRTERROR_TO_ST(err);
Emeric Brunf282a812012-09-21 15:27:54 +0200920
Emeric Brun81c00f02012-09-21 14:31:21 +0200921 /* check if certificate error needs to be ignored */
Emeric Brun1eb20ef2012-12-03 13:24:29 +0100922 if (objt_listener(conn->target)->bind_conf->crt_ignerr & (1ULL << err)) {
923 ERR_clear_error();
Emeric Brun81c00f02012-09-21 14:31:21 +0200924 return 1;
Emeric Brun1eb20ef2012-12-03 13:24:29 +0100925 }
Emeric Brun81c00f02012-09-21 14:31:21 +0200926
Willy Tarreau20879a02012-12-03 16:32:10 +0100927 conn->err_code = CO_ER_SSL_CRT_FAIL;
Emeric Brun81c00f02012-09-21 14:31:21 +0200928 return 0;
Emeric Brune64aef12012-09-21 13:15:06 +0200929}
930
Emeric Brun29f037d2014-04-25 19:05:36 +0200931/* Callback is called for ssl protocol analyse */
932void ssl_sock_msgcbk(int write_p, int version, int content_type, const void *buf, size_t len, SSL *ssl, void *arg)
933{
Emeric Brun29f037d2014-04-25 19:05:36 +0200934#ifdef TLS1_RT_HEARTBEAT
935 /* test heartbeat received (write_p is set to 0
936 for a received record) */
Willy Tarreauf51c6982014-04-25 20:02:39 +0200937 if ((content_type == TLS1_RT_HEARTBEAT) && (write_p == 0)) {
Willy Tarreau84815002014-04-25 21:40:27 +0200938 struct connection *conn = (struct connection *)SSL_get_app_data(ssl);
Willy Tarreauf51c6982014-04-25 20:02:39 +0200939 const unsigned char *p = buf;
940 unsigned int payload;
941
Emeric Brun29f037d2014-04-25 19:05:36 +0200942 conn->xprt_st |= SSL_SOCK_RECV_HEARTBEAT;
Willy Tarreauf51c6982014-04-25 20:02:39 +0200943
944 /* Check if this is a CVE-2014-0160 exploitation attempt. */
945 if (*p != TLS1_HB_REQUEST)
946 return;
947
Willy Tarreauaeed6722014-04-25 23:59:58 +0200948 if (len < 1 + 2 + 16) /* 1 type + 2 size + 0 payload + 16 padding */
Willy Tarreauf51c6982014-04-25 20:02:39 +0200949 goto kill_it;
950
951 payload = (p[1] * 256) + p[2];
Willy Tarreau3b2fdb62014-04-25 23:44:22 +0200952 if (3 + payload + 16 <= len)
Willy Tarreauf51c6982014-04-25 20:02:39 +0200953 return; /* OK no problem */
Willy Tarreauaeed6722014-04-25 23:59:58 +0200954 kill_it:
Willy Tarreau3b2fdb62014-04-25 23:44:22 +0200955 /* We have a clear heartbleed attack (CVE-2014-0160), the
956 * advertised payload is larger than the advertised packet
957 * length, so we have garbage in the buffer between the
958 * payload and the end of the buffer (p+len). We can't know
959 * if the SSL stack is patched, and we don't know if we can
960 * safely wipe out the area between p+3+len and payload.
961 * So instead, we prevent the response from being sent by
962 * setting the max_send_fragment to 0 and we report an SSL
963 * error, which will kill this connection. It will be reported
964 * above as SSL_ERROR_SSL while an other handshake failure with
Willy Tarreauf51c6982014-04-25 20:02:39 +0200965 * a heartbeat message will be reported as SSL_ERROR_SYSCALL.
966 */
Willy Tarreau3b2fdb62014-04-25 23:44:22 +0200967 ssl->max_send_fragment = 0;
Willy Tarreauf51c6982014-04-25 20:02:39 +0200968 SSLerr(SSL_F_TLS1_HEARTBEAT, SSL_R_SSL_HANDSHAKE_FAILURE);
969 return;
970 }
Emeric Brun29f037d2014-04-25 19:05:36 +0200971#endif
972}
973
Willy Tarreau6c9a3d52012-10-18 18:57:14 +0200974#ifdef OPENSSL_NPN_NEGOTIATED
975/* This callback is used so that the server advertises the list of
976 * negociable protocols for NPN.
977 */
978static int ssl_sock_advertise_npn_protos(SSL *s, const unsigned char **data,
979 unsigned int *len, void *arg)
980{
981 struct bind_conf *conf = arg;
982
983 *data = (const unsigned char *)conf->npn_str;
984 *len = conf->npn_len;
985 return SSL_TLSEXT_ERR_OK;
986}
987#endif
988
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +0100989#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Willy Tarreauab861d32013-04-02 02:30:41 +0200990/* This callback is used so that the server advertises the list of
991 * negociable protocols for ALPN.
992 */
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +0100993static int ssl_sock_advertise_alpn_protos(SSL *s, const unsigned char **out,
994 unsigned char *outlen,
995 const unsigned char *server,
996 unsigned int server_len, void *arg)
Willy Tarreauab861d32013-04-02 02:30:41 +0200997{
998 struct bind_conf *conf = arg;
999
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01001000 if (SSL_select_next_proto((unsigned char**) out, outlen, (const unsigned char *)conf->alpn_str,
1001 conf->alpn_len, server, server_len) != OPENSSL_NPN_NEGOTIATED) {
1002 return SSL_TLSEXT_ERR_NOACK;
1003 }
Willy Tarreauab861d32013-04-02 02:30:41 +02001004 return SSL_TLSEXT_ERR_OK;
1005}
1006#endif
1007
Willy Tarreauc8ad3be2015-06-17 15:48:26 +02001008#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Christopher Faulet85b5a1a2015-10-09 11:46:32 +02001009static DH *ssl_get_tmp_dh(SSL *ssl, int export, int keylen);
1010
Christopher Faulet30548802015-06-11 13:39:32 +02001011/* Create a X509 certificate with the specified servername and serial. This
1012 * function returns a SSL_CTX object or NULL if an error occurs. */
Christopher Faulet7969a332015-10-09 11:15:03 +02001013static SSL_CTX *
1014ssl_sock_do_create_cert(const char *servername, unsigned int serial,
1015 struct bind_conf *bind_conf, SSL *ssl)
Christopher Faulet31af49d2015-06-09 17:29:50 +02001016{
Christopher Faulet7969a332015-10-09 11:15:03 +02001017 X509 *cacert = bind_conf->ca_sign_cert;
1018 EVP_PKEY *capkey = bind_conf->ca_sign_pkey;
Christopher Faulet31af49d2015-06-09 17:29:50 +02001019 SSL_CTX *ssl_ctx = NULL;
1020 X509 *newcrt = NULL;
1021 EVP_PKEY *pkey = NULL;
Christopher Faulet31af49d2015-06-09 17:29:50 +02001022 X509_NAME *name;
1023 const EVP_MD *digest;
1024 X509V3_CTX ctx;
1025 unsigned int i;
1026
Christopher Faulet7969a332015-10-09 11:15:03 +02001027 /* Get the private key of the defautl certificate and use it */
1028 if (!(pkey = SSL_get_privatekey(ssl)))
Christopher Faulet31af49d2015-06-09 17:29:50 +02001029 goto mkcert_error;
1030
1031 /* Create the certificate */
1032 if (!(newcrt = X509_new()))
1033 goto mkcert_error;
1034
1035 /* Set version number for the certificate (X509v3) and the serial
1036 * number */
1037 if (X509_set_version(newcrt, 2L) != 1)
1038 goto mkcert_error;
1039 ASN1_INTEGER_set(X509_get_serialNumber(newcrt), serial);
1040
1041 /* Set duration for the certificate */
1042 if (!X509_gmtime_adj(X509_get_notBefore(newcrt), (long)-60*60*24) ||
1043 !X509_gmtime_adj(X509_get_notAfter(newcrt),(long)60*60*24*365))
1044 goto mkcert_error;
1045
1046 /* set public key in the certificate */
1047 if (X509_set_pubkey(newcrt, pkey) != 1)
1048 goto mkcert_error;
1049
1050 /* Set issuer name from the CA */
1051 if (!(name = X509_get_subject_name(cacert)))
1052 goto mkcert_error;
1053 if (X509_set_issuer_name(newcrt, name) != 1)
1054 goto mkcert_error;
1055
1056 /* Set the subject name using the same, but the CN */
1057 name = X509_NAME_dup(name);
1058 if (X509_NAME_add_entry_by_txt(name, "CN", MBSTRING_ASC,
1059 (const unsigned char *)servername,
1060 -1, -1, 0) != 1) {
1061 X509_NAME_free(name);
1062 goto mkcert_error;
1063 }
1064 if (X509_set_subject_name(newcrt, name) != 1) {
1065 X509_NAME_free(name);
1066 goto mkcert_error;
1067 }
1068 X509_NAME_free(name);
1069
1070 /* Add x509v3 extensions as specified */
1071 X509V3_set_ctx(&ctx, cacert, newcrt, NULL, NULL, 0);
1072 for (i = 0; i < X509V3_EXT_SIZE; i++) {
1073 X509_EXTENSION *ext;
1074
1075 if (!(ext = X509V3_EXT_conf(NULL, &ctx, x509v3_ext_names[i], x509v3_ext_values[i])))
1076 goto mkcert_error;
1077 if (!X509_add_ext(newcrt, ext, -1)) {
1078 X509_EXTENSION_free(ext);
1079 goto mkcert_error;
1080 }
1081 X509_EXTENSION_free(ext);
1082 }
1083
1084 /* Sign the certificate with the CA private key */
1085 if (EVP_PKEY_type(capkey->type) == EVP_PKEY_DSA)
1086 digest = EVP_dss1();
1087 else if (EVP_PKEY_type (capkey->type) == EVP_PKEY_RSA)
1088 digest = EVP_sha256();
Christopher Faulet7969a332015-10-09 11:15:03 +02001089 else if (EVP_PKEY_type (capkey->type) == EVP_PKEY_EC)
1090 digest = EVP_sha256();
1091 else {
1092 int nid;
1093
1094 if (EVP_PKEY_get_default_digest_nid(capkey, &nid) <= 0)
1095 goto mkcert_error;
1096 if (!(digest = EVP_get_digestbynid(nid)))
1097 goto mkcert_error;
1098 }
1099
Christopher Faulet31af49d2015-06-09 17:29:50 +02001100 if (!(X509_sign(newcrt, capkey, digest)))
1101 goto mkcert_error;
1102
1103 /* Create and set the new SSL_CTX */
1104 if (!(ssl_ctx = SSL_CTX_new(SSLv23_server_method())))
1105 goto mkcert_error;
1106 if (!SSL_CTX_use_PrivateKey(ssl_ctx, pkey))
1107 goto mkcert_error;
1108 if (!SSL_CTX_use_certificate(ssl_ctx, newcrt))
1109 goto mkcert_error;
1110 if (!SSL_CTX_check_private_key(ssl_ctx))
1111 goto mkcert_error;
1112
1113 if (newcrt) X509_free(newcrt);
Christopher Faulet7969a332015-10-09 11:15:03 +02001114
Christopher Faulet85b5a1a2015-10-09 11:46:32 +02001115 SSL_CTX_set_tmp_dh_callback(ssl_ctx, ssl_get_tmp_dh);
1116#if defined(SSL_CTX_set_tmp_ecdh) && !defined(OPENSSL_NO_ECDH)
1117 {
1118 const char *ecdhe = (bind_conf->ecdhe ? bind_conf->ecdhe : ECDHE_DEFAULT_CURVE);
1119 EC_KEY *ecc;
1120 int nid;
1121
1122 if ((nid = OBJ_sn2nid(ecdhe)) == NID_undef)
1123 goto end;
1124 if (!(ecc = EC_KEY_new_by_curve_name(nid)))
1125 goto end;
1126 SSL_CTX_set_tmp_ecdh(ssl_ctx, ecc);
1127 EC_KEY_free(ecc);
1128 }
1129#endif
1130 end:
Christopher Faulet31af49d2015-06-09 17:29:50 +02001131 return ssl_ctx;
1132
1133 mkcert_error:
1134 if (ssl_ctx) SSL_CTX_free(ssl_ctx);
1135 if (newcrt) X509_free(newcrt);
Christopher Faulet31af49d2015-06-09 17:29:50 +02001136 return NULL;
1137}
1138
Christopher Faulet7969a332015-10-09 11:15:03 +02001139SSL_CTX *
1140ssl_sock_create_cert(struct connection *conn, const char *servername, unsigned int serial)
1141{
1142 struct bind_conf *bind_conf = objt_listener(conn->target)->bind_conf;
1143 return ssl_sock_do_create_cert(servername, serial, bind_conf, conn->xprt_ctx);
1144}
1145
Christopher Faulet30548802015-06-11 13:39:32 +02001146/* Do a lookup for a certificate in the LRU cache used to store generated
1147 * certificates. */
1148SSL_CTX *
Christopher Faulet7969a332015-10-09 11:15:03 +02001149ssl_sock_get_generated_cert(unsigned int serial, struct bind_conf *bind_conf)
Christopher Faulet30548802015-06-11 13:39:32 +02001150{
1151 struct lru64 *lru = NULL;
1152
1153 if (ssl_ctx_lru_tree) {
Christopher Faulet7969a332015-10-09 11:15:03 +02001154 lru = lru64_lookup(serial, ssl_ctx_lru_tree, bind_conf->ca_sign_cert, 0);
Christopher Faulet30548802015-06-11 13:39:32 +02001155 if (lru && lru->domain)
1156 return (SSL_CTX *)lru->data;
1157 }
1158 return NULL;
1159}
1160
Christopher Fauletd2cab922015-07-28 16:03:47 +02001161/* Set a certificate int the LRU cache used to store generated
1162 * certificate. Return 0 on success, otherwise -1 */
1163int
Christopher Faulet7969a332015-10-09 11:15:03 +02001164ssl_sock_set_generated_cert(SSL_CTX *ssl_ctx, unsigned int serial, struct bind_conf *bind_conf)
Christopher Faulet30548802015-06-11 13:39:32 +02001165{
1166 struct lru64 *lru = NULL;
1167
1168 if (ssl_ctx_lru_tree) {
Christopher Faulet7969a332015-10-09 11:15:03 +02001169 lru = lru64_get(serial, ssl_ctx_lru_tree, bind_conf->ca_sign_cert, 0);
Christopher Faulet30548802015-06-11 13:39:32 +02001170 if (!lru)
Christopher Fauletd2cab922015-07-28 16:03:47 +02001171 return -1;
Christopher Faulet30548802015-06-11 13:39:32 +02001172 if (lru->domain && lru->data)
1173 lru->free((SSL_CTX *)lru->data);
Christopher Faulet7969a332015-10-09 11:15:03 +02001174 lru64_commit(lru, ssl_ctx, bind_conf->ca_sign_cert, 0, (void (*)(void *))SSL_CTX_free);
Christopher Fauletd2cab922015-07-28 16:03:47 +02001175 return 0;
Christopher Faulet30548802015-06-11 13:39:32 +02001176 }
Christopher Fauletd2cab922015-07-28 16:03:47 +02001177 return -1;
Christopher Faulet30548802015-06-11 13:39:32 +02001178}
1179
1180/* Compute the serial that will be used to create/set/get a certificate. */
1181unsigned int
Willy Tarreau646b8642015-07-07 18:09:15 +02001182ssl_sock_generated_cert_serial(const void *data, size_t len)
Christopher Faulet30548802015-06-11 13:39:32 +02001183{
1184 return XXH32(data, len, ssl_ctx_lru_seed);
1185}
1186
Christopher Faulet31af49d2015-06-09 17:29:50 +02001187static SSL_CTX *
Christopher Faulet7969a332015-10-09 11:15:03 +02001188ssl_sock_generate_certificate(const char *servername, struct bind_conf *bind_conf, SSL *ssl)
Christopher Faulet31af49d2015-06-09 17:29:50 +02001189{
1190 X509 *cacert = bind_conf->ca_sign_cert;
Christopher Faulet31af49d2015-06-09 17:29:50 +02001191 SSL_CTX *ssl_ctx = NULL;
1192 struct lru64 *lru = NULL;
1193 unsigned int serial;
1194
Willy Tarreaufc017fe2015-07-07 18:09:34 +02001195 serial = ssl_sock_generated_cert_serial(servername, strlen(servername));
Christopher Faulet31af49d2015-06-09 17:29:50 +02001196 if (ssl_ctx_lru_tree) {
1197 lru = lru64_get(serial, ssl_ctx_lru_tree, cacert, 0);
1198 if (lru && lru->domain)
1199 ssl_ctx = (SSL_CTX *)lru->data;
Christopher Fauletd2cab922015-07-28 16:03:47 +02001200 if (!ssl_ctx && lru) {
Christopher Faulet7969a332015-10-09 11:15:03 +02001201 ssl_ctx = ssl_sock_do_create_cert(servername, serial, bind_conf, ssl);
Christopher Faulet31af49d2015-06-09 17:29:50 +02001202 lru64_commit(lru, ssl_ctx, cacert, 0, (void (*)(void *))SSL_CTX_free);
Christopher Fauletd2cab922015-07-28 16:03:47 +02001203 }
Christopher Faulet31af49d2015-06-09 17:29:50 +02001204 }
Christopher Fauletd2cab922015-07-28 16:03:47 +02001205 else
Christopher Faulet7969a332015-10-09 11:15:03 +02001206 ssl_ctx = ssl_sock_do_create_cert(servername, serial, bind_conf, ssl);
Christopher Faulet31af49d2015-06-09 17:29:50 +02001207 return ssl_ctx;
1208}
1209
Emeric Brunfc0421f2012-09-07 17:30:07 +02001210/* Sets the SSL ctx of <ssl> to match the advertised server name. Returns a
1211 * warning when no match is found, which implies the default (first) cert
1212 * will keep being used.
1213 */
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001214static int ssl_sock_switchctx_cbk(SSL *ssl, int *al, struct bind_conf *s)
Emeric Brunfc0421f2012-09-07 17:30:07 +02001215{
1216 const char *servername;
1217 const char *wildp = NULL;
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001218 struct ebmb_node *node, *n;
Emeric Brunfc0421f2012-09-07 17:30:07 +02001219 int i;
1220 (void)al; /* shut gcc stupid warning */
1221
1222 servername = SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name);
Emmanuel Hocdet65623372013-01-24 17:17:15 +01001223 if (!servername) {
Willy Tarreauf6721452015-07-07 18:04:38 +02001224 if (s->generate_certs) {
1225 struct connection *conn = (struct connection *)SSL_get_app_data(ssl);
1226 unsigned int serial;
1227 SSL_CTX *ctx;
Christopher Faulet30548802015-06-11 13:39:32 +02001228
Willy Tarreauf6721452015-07-07 18:04:38 +02001229 conn_get_to_addr(conn);
1230 if (conn->flags & CO_FL_ADDR_TO_SET) {
1231 serial = ssl_sock_generated_cert_serial(&conn->addr.to, get_addr_len(&conn->addr.to));
Christopher Faulet7969a332015-10-09 11:15:03 +02001232 ctx = ssl_sock_get_generated_cert(serial, s);
Willy Tarreauf6721452015-07-07 18:04:38 +02001233 if (ctx) {
1234 /* switch ctx */
1235 SSL_set_SSL_CTX(ssl, ctx);
1236 return SSL_TLSEXT_ERR_OK;
1237 }
Christopher Faulet30548802015-06-11 13:39:32 +02001238 }
1239 }
1240
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001241 return (s->strict_sni ?
1242 SSL_TLSEXT_ERR_ALERT_FATAL :
Emmanuel Hocdet79274e22013-05-31 12:47:44 +02001243 SSL_TLSEXT_ERR_NOACK);
Emmanuel Hocdet65623372013-01-24 17:17:15 +01001244 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02001245
Willy Tarreau19d14ef2012-10-29 16:51:55 +01001246 for (i = 0; i < trash.size; i++) {
Emeric Brunfc0421f2012-09-07 17:30:07 +02001247 if (!servername[i])
1248 break;
Willy Tarreau19d14ef2012-10-29 16:51:55 +01001249 trash.str[i] = tolower(servername[i]);
1250 if (!wildp && (trash.str[i] == '.'))
1251 wildp = &trash.str[i];
Emeric Brunfc0421f2012-09-07 17:30:07 +02001252 }
Willy Tarreau19d14ef2012-10-29 16:51:55 +01001253 trash.str[i] = 0;
Emeric Brunfc0421f2012-09-07 17:30:07 +02001254
1255 /* lookup in full qualified names */
Willy Tarreau19d14ef2012-10-29 16:51:55 +01001256 node = ebst_lookup(&s->sni_ctx, trash.str);
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001257
1258 /* lookup a not neg filter */
1259 for (n = node; n; n = ebmb_next_dup(n)) {
1260 if (!container_of(n, struct sni_ctx, name)->neg) {
1261 node = n;
1262 break;
Emmanuel Hocdet65623372013-01-24 17:17:15 +01001263 }
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001264 }
1265 if (!node && wildp) {
1266 /* lookup in wildcards names */
Emeric Brunfc0421f2012-09-07 17:30:07 +02001267 node = ebst_lookup(&s->sni_w_ctx, wildp);
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001268 }
1269 if (!node || container_of(node, struct sni_ctx, name)->neg) {
Christopher Faulet31af49d2015-06-09 17:29:50 +02001270 SSL_CTX *ctx;
Christopher Faulet31af49d2015-06-09 17:29:50 +02001271 if (s->generate_certs &&
Christopher Faulet7969a332015-10-09 11:15:03 +02001272 (ctx = ssl_sock_generate_certificate(servername, s, ssl))) {
Christopher Faulet31af49d2015-06-09 17:29:50 +02001273 /* switch ctx */
1274 SSL_set_SSL_CTX(ssl, ctx);
1275 return SSL_TLSEXT_ERR_OK;
1276 }
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001277 return (s->strict_sni ?
1278 SSL_TLSEXT_ERR_ALERT_FATAL :
1279 SSL_TLSEXT_ERR_ALERT_WARNING);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001280 }
1281
1282 /* switch ctx */
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001283 SSL_set_SSL_CTX(ssl, container_of(node, struct sni_ctx, name)->ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001284 return SSL_TLSEXT_ERR_OK;
1285}
1286#endif /* SSL_CTRL_SET_TLSEXT_HOSTNAME */
1287
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001288#ifndef OPENSSL_NO_DH
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001289
1290static DH * ssl_get_dh_1024(void)
1291{
Remi Gacogned3a341a2015-05-29 16:26:17 +02001292 static unsigned char dh1024_p[]={
1293 0xFA,0xF9,0x2A,0x22,0x2A,0xA7,0x7F,0xE1,0x67,0x4E,0x53,0xF7,
1294 0x56,0x13,0xC3,0xB1,0xE3,0x29,0x6B,0x66,0x31,0x6A,0x7F,0xB3,
1295 0xC2,0x68,0x6B,0xCB,0x1D,0x57,0x39,0x1D,0x1F,0xFF,0x1C,0xC9,
1296 0xA6,0xA4,0x98,0x82,0x31,0x5D,0x25,0xFF,0x8A,0xE0,0x73,0x96,
1297 0x81,0xC8,0x83,0x79,0xC1,0x5A,0x04,0xF8,0x37,0x0D,0xA8,0x3D,
1298 0xAE,0x74,0xBC,0xDB,0xB6,0xA4,0x75,0xD9,0x71,0x8A,0xA0,0x17,
1299 0x9E,0x2D,0xC8,0xA8,0xDF,0x2C,0x5F,0x82,0x95,0xF8,0x92,0x9B,
1300 0xA7,0x33,0x5F,0x89,0x71,0xC8,0x2D,0x6B,0x18,0x86,0xC4,0x94,
1301 0x22,0xA5,0x52,0x8D,0xF6,0xF6,0xD2,0x37,0x92,0x0F,0xA5,0xCC,
1302 0xDB,0x7B,0x1D,0x3D,0xA1,0x31,0xB7,0x80,0x8F,0x0B,0x67,0x5E,
1303 0x36,0xA5,0x60,0x0C,0xF1,0x95,0x33,0x8B,
1304 };
1305 static unsigned char dh1024_g[]={
1306 0x02,
1307 };
1308
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001309 DH *dh = DH_new();
1310 if (dh) {
Remi Gacogned3a341a2015-05-29 16:26:17 +02001311 dh->p = BN_bin2bn(dh1024_p, sizeof dh1024_p, NULL);
1312 dh->g = BN_bin2bn(dh1024_g, sizeof dh1024_g, NULL);
1313
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001314 if (!dh->p || !dh->g) {
1315 DH_free(dh);
1316 dh = NULL;
1317 }
1318 }
1319 return dh;
1320}
1321
1322static DH *ssl_get_dh_2048(void)
1323{
Remi Gacogned3a341a2015-05-29 16:26:17 +02001324 static unsigned char dh2048_p[]={
1325 0xEC,0x86,0xF8,0x70,0xA0,0x33,0x16,0xEC,0x05,0x1A,0x73,0x59,
1326 0xCD,0x1F,0x8B,0xF8,0x29,0xE4,0xD2,0xCF,0x52,0xDD,0xC2,0x24,
1327 0x8D,0xB5,0x38,0x9A,0xFB,0x5C,0xA4,0xE4,0xB2,0xDA,0xCE,0x66,
1328 0x50,0x74,0xA6,0x85,0x4D,0x4B,0x1D,0x30,0xB8,0x2B,0xF3,0x10,
1329 0xE9,0xA7,0x2D,0x05,0x71,0xE7,0x81,0xDF,0x8B,0x59,0x52,0x3B,
1330 0x5F,0x43,0x0B,0x68,0xF1,0xDB,0x07,0xBE,0x08,0x6B,0x1B,0x23,
1331 0xEE,0x4D,0xCC,0x9E,0x0E,0x43,0xA0,0x1E,0xDF,0x43,0x8C,0xEC,
1332 0xBE,0xBE,0x90,0xB4,0x51,0x54,0xB9,0x2F,0x7B,0x64,0x76,0x4E,
1333 0x5D,0xD4,0x2E,0xAE,0xC2,0x9E,0xAE,0x51,0x43,0x59,0xC7,0x77,
1334 0x9C,0x50,0x3C,0x0E,0xED,0x73,0x04,0x5F,0xF1,0x4C,0x76,0x2A,
1335 0xD8,0xF8,0xCF,0xFC,0x34,0x40,0xD1,0xB4,0x42,0x61,0x84,0x66,
1336 0x42,0x39,0x04,0xF8,0x68,0xB2,0x62,0xD7,0x55,0xED,0x1B,0x74,
1337 0x75,0x91,0xE0,0xC5,0x69,0xC1,0x31,0x5C,0xDB,0x7B,0x44,0x2E,
1338 0xCE,0x84,0x58,0x0D,0x1E,0x66,0x0C,0xC8,0x44,0x9E,0xFD,0x40,
1339 0x08,0x67,0x5D,0xFB,0xA7,0x76,0x8F,0x00,0x11,0x87,0xE9,0x93,
1340 0xF9,0x7D,0xC4,0xBC,0x74,0x55,0x20,0xD4,0x4A,0x41,0x2F,0x43,
1341 0x42,0x1A,0xC1,0xF2,0x97,0x17,0x49,0x27,0x37,0x6B,0x2F,0x88,
1342 0x7E,0x1C,0xA0,0xA1,0x89,0x92,0x27,0xD9,0x56,0x5A,0x71,0xC1,
1343 0x56,0x37,0x7E,0x3A,0x9D,0x05,0xE7,0xEE,0x5D,0x8F,0x82,0x17,
1344 0xBC,0xE9,0xC2,0x93,0x30,0x82,0xF9,0xF4,0xC9,0xAE,0x49,0xDB,
1345 0xD0,0x54,0xB4,0xD9,0x75,0x4D,0xFA,0x06,0xB8,0xD6,0x38,0x41,
1346 0xB7,0x1F,0x77,0xF3,
1347 };
1348 static unsigned char dh2048_g[]={
1349 0x02,
1350 };
1351
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001352 DH *dh = DH_new();
1353 if (dh) {
Remi Gacogned3a341a2015-05-29 16:26:17 +02001354 dh->p = BN_bin2bn(dh2048_p, sizeof dh2048_p, NULL);
1355 dh->g = BN_bin2bn(dh2048_g, sizeof dh2048_g, NULL);
1356
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001357 if (!dh->p || !dh->g) {
1358 DH_free(dh);
1359 dh = NULL;
1360 }
1361 }
1362 return dh;
1363}
1364
1365static DH *ssl_get_dh_4096(void)
1366{
Remi Gacogned3a341a2015-05-29 16:26:17 +02001367 static unsigned char dh4096_p[]={
1368 0xDE,0x16,0x94,0xCD,0x99,0x58,0x07,0xF1,0xF7,0x32,0x96,0x11,
1369 0x04,0x82,0xD4,0x84,0x72,0x80,0x99,0x06,0xCA,0xF0,0xA3,0x68,
1370 0x07,0xCE,0x64,0x50,0xE7,0x74,0x45,0x20,0x80,0x5E,0x4D,0xAD,
1371 0xA5,0xB6,0xED,0xFA,0x80,0x6C,0x3B,0x35,0xC4,0x9A,0x14,0x6B,
1372 0x32,0xBB,0xFD,0x1F,0x17,0x8E,0xB7,0x1F,0xD6,0xFA,0x3F,0x7B,
1373 0xEE,0x16,0xA5,0x62,0x33,0x0D,0xED,0xBC,0x4E,0x58,0xE5,0x47,
1374 0x4D,0xE9,0xAB,0x8E,0x38,0xD3,0x6E,0x90,0x57,0xE3,0x22,0x15,
1375 0x33,0xBD,0xF6,0x43,0x45,0xB5,0x10,0x0A,0xBE,0x2C,0xB4,0x35,
1376 0xB8,0x53,0x8D,0xAD,0xFB,0xA7,0x1F,0x85,0x58,0x41,0x7A,0x79,
1377 0x20,0x68,0xB3,0xE1,0x3D,0x08,0x76,0xBF,0x86,0x0D,0x49,0xE3,
1378 0x82,0x71,0x8C,0xB4,0x8D,0x81,0x84,0xD4,0xE7,0xBE,0x91,0xDC,
1379 0x26,0x39,0x48,0x0F,0x35,0xC4,0xCA,0x65,0xE3,0x40,0x93,0x52,
1380 0x76,0x58,0x7D,0xDD,0x51,0x75,0xDC,0x69,0x61,0xBF,0x47,0x2C,
1381 0x16,0x68,0x2D,0xC9,0x29,0xD3,0xE6,0xC0,0x99,0x48,0xA0,0x9A,
1382 0xC8,0x78,0xC0,0x6D,0x81,0x67,0x12,0x61,0x3F,0x71,0xBA,0x41,
1383 0x1F,0x6C,0x89,0x44,0x03,0xBA,0x3B,0x39,0x60,0xAA,0x28,0x55,
1384 0x59,0xAE,0xB8,0xFA,0xCB,0x6F,0xA5,0x1A,0xF7,0x2B,0xDD,0x52,
1385 0x8A,0x8B,0xE2,0x71,0xA6,0x5E,0x7E,0xD8,0x2E,0x18,0xE0,0x66,
1386 0xDF,0xDD,0x22,0x21,0x99,0x52,0x73,0xA6,0x33,0x20,0x65,0x0E,
1387 0x53,0xE7,0x6B,0x9B,0xC5,0xA3,0x2F,0x97,0x65,0x76,0xD3,0x47,
1388 0x23,0x77,0x12,0xB6,0x11,0x7B,0x24,0xED,0xF1,0xEF,0xC0,0xE2,
1389 0xA3,0x7E,0x67,0x05,0x3E,0x96,0x4D,0x45,0xC2,0x18,0xD1,0x73,
1390 0x9E,0x07,0xF3,0x81,0x6E,0x52,0x63,0xF6,0x20,0x76,0xB9,0x13,
1391 0xD2,0x65,0x30,0x18,0x16,0x09,0x16,0x9E,0x8F,0xF1,0xD2,0x10,
1392 0x5A,0xD3,0xD4,0xAF,0x16,0x61,0xDA,0x55,0x2E,0x18,0x5E,0x14,
1393 0x08,0x54,0x2E,0x2A,0x25,0xA2,0x1A,0x9B,0x8B,0x32,0xA9,0xFD,
1394 0xC2,0x48,0x96,0xE1,0x80,0xCA,0xE9,0x22,0x17,0xBB,0xCE,0x3E,
1395 0x9E,0xED,0xC7,0xF1,0x1F,0xEC,0x17,0x21,0xDC,0x7B,0x82,0x48,
1396 0x8E,0xBB,0x4B,0x9D,0x5B,0x04,0x04,0xDA,0xDB,0x39,0xDF,0x01,
1397 0x40,0xC3,0xAA,0x26,0x23,0x89,0x75,0xC6,0x0B,0xD0,0xA2,0x60,
1398 0x6A,0xF1,0xCC,0x65,0x18,0x98,0x1B,0x52,0xD2,0x74,0x61,0xCC,
1399 0xBD,0x60,0xAE,0xA3,0xA0,0x66,0x6A,0x16,0x34,0x92,0x3F,0x41,
1400 0x40,0x31,0x29,0xC0,0x2C,0x63,0xB2,0x07,0x8D,0xEB,0x94,0xB8,
1401 0xE8,0x47,0x92,0x52,0x93,0x6A,0x1B,0x7E,0x1A,0x61,0xB3,0x1B,
1402 0xF0,0xD6,0x72,0x9B,0xF1,0xB0,0xAF,0xBF,0x3E,0x65,0xEF,0x23,
1403 0x1D,0x6F,0xFF,0x70,0xCD,0x8A,0x4C,0x8A,0xA0,0x72,0x9D,0xBE,
1404 0xD4,0xBB,0x24,0x47,0x4A,0x68,0xB5,0xF5,0xC6,0xD5,0x7A,0xCD,
1405 0xCA,0x06,0x41,0x07,0xAD,0xC2,0x1E,0xE6,0x54,0xA7,0xAD,0x03,
1406 0xD9,0x12,0xC1,0x9C,0x13,0xB1,0xC9,0x0A,0x43,0x8E,0x1E,0x08,
1407 0xCE,0x50,0x82,0x73,0x5F,0xA7,0x55,0x1D,0xD9,0x59,0xAC,0xB5,
1408 0xEA,0x02,0x7F,0x6C,0x5B,0x74,0x96,0x98,0x67,0x24,0xA3,0x0F,
1409 0x15,0xFC,0xA9,0x7D,0x3E,0x67,0xD1,0x70,0xF8,0x97,0xF3,0x67,
1410 0xC5,0x8C,0x88,0x44,0x08,0x02,0xC7,0x2B,
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001411 };
Remi Gacogned3a341a2015-05-29 16:26:17 +02001412 static unsigned char dh4096_g[]={
1413 0x02,
1414 };
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001415
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001416 DH *dh = DH_new();
1417 if (dh) {
Remi Gacogned3a341a2015-05-29 16:26:17 +02001418 dh->p = BN_bin2bn(dh4096_p, sizeof dh4096_p, NULL);
1419 dh->g = BN_bin2bn(dh4096_g, sizeof dh4096_g, NULL);
1420
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001421 if (!dh->p || !dh->g) {
1422 DH_free(dh);
1423 dh = NULL;
1424 }
1425 }
1426 return dh;
1427}
1428
1429/* Returns Diffie-Hellman parameters matching the private key length
1430 but not exceeding global.tune.ssl_default_dh_param */
1431static DH *ssl_get_tmp_dh(SSL *ssl, int export, int keylen)
1432{
1433 DH *dh = NULL;
1434 EVP_PKEY *pkey = SSL_get_privatekey(ssl);
1435 int type = pkey ? EVP_PKEY_type(pkey->type) : EVP_PKEY_NONE;
1436
1437 /* The keylen supplied by OpenSSL can only be 512 or 1024.
1438 See ssl3_send_server_key_exchange() in ssl/s3_srvr.c
1439 */
1440 if (type == EVP_PKEY_RSA || type == EVP_PKEY_DSA) {
1441 keylen = EVP_PKEY_bits(pkey);
1442 }
1443
1444 if (keylen > global.tune.ssl_default_dh_param) {
1445 keylen = global.tune.ssl_default_dh_param;
1446 }
1447
Remi Gacogned3a341a2015-05-29 16:26:17 +02001448 if (keylen >= 4096) {
Remi Gacogne8de54152014-07-15 11:36:40 +02001449 dh = local_dh_4096;
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001450 }
1451 else if (keylen >= 2048) {
Remi Gacogne8de54152014-07-15 11:36:40 +02001452 dh = local_dh_2048;
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001453 }
1454 else {
Remi Gacogne8de54152014-07-15 11:36:40 +02001455 dh = local_dh_1024;
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001456 }
1457
1458 return dh;
1459}
1460
Remi Gacogne47783ef2015-05-29 15:53:22 +02001461static DH * ssl_sock_get_dh_from_file(const char *filename)
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001462{
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001463 DH *dh = NULL;
Remi Gacogne47783ef2015-05-29 15:53:22 +02001464 BIO *in = BIO_new(BIO_s_file());
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001465
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001466 if (in == NULL)
1467 goto end;
1468
Remi Gacogne47783ef2015-05-29 15:53:22 +02001469 if (BIO_read_filename(in, filename) <= 0)
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001470 goto end;
1471
Remi Gacogne47783ef2015-05-29 15:53:22 +02001472 dh = PEM_read_bio_DHparams(in, NULL, NULL, NULL);
1473
1474end:
1475 if (in)
1476 BIO_free(in);
1477
1478 return dh;
1479}
1480
1481int ssl_sock_load_global_dh_param_from_file(const char *filename)
1482{
1483 global_dh = ssl_sock_get_dh_from_file(filename);
1484
1485 if (global_dh) {
1486 return 0;
1487 }
1488
1489 return -1;
1490}
1491
1492/* Loads Diffie-Hellman parameter from a file. Returns 1 if loaded, else -1
1493 if an error occured, and 0 if parameter not found. */
1494int ssl_sock_load_dh_params(SSL_CTX *ctx, const char *file)
1495{
1496 int ret = -1;
1497 DH *dh = ssl_sock_get_dh_from_file(file);
1498
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001499 if (dh) {
1500 ret = 1;
1501 SSL_CTX_set_tmp_dh(ctx, dh);
Remi Gacogne4f902b82015-05-28 16:23:00 +02001502
1503 if (ssl_dh_ptr_index >= 0) {
1504 /* store a pointer to the DH params to avoid complaining about
1505 ssl-default-dh-param not being set for this SSL_CTX */
1506 SSL_CTX_set_ex_data(ctx, ssl_dh_ptr_index, dh);
1507 }
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001508 }
Remi Gacogne47783ef2015-05-29 15:53:22 +02001509 else if (global_dh) {
1510 SSL_CTX_set_tmp_dh(ctx, global_dh);
1511 ret = 0; /* DH params not found */
1512 }
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001513 else {
Emeric Brun41fdb3c2013-04-26 11:05:44 +02001514 /* Clear openssl global errors stack */
1515 ERR_clear_error();
1516
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001517 if (global.tune.ssl_default_dh_param <= 1024) {
1518 /* we are limited to DH parameter of 1024 bits anyway */
Remi Gacogne8de54152014-07-15 11:36:40 +02001519 local_dh_1024 = ssl_get_dh_1024();
1520 if (local_dh_1024 == NULL)
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001521 goto end;
Willy Tarreau6e774b42014-04-25 21:35:23 +02001522
Remi Gacogne8de54152014-07-15 11:36:40 +02001523 SSL_CTX_set_tmp_dh(ctx, local_dh_1024);
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001524 }
1525 else {
1526 SSL_CTX_set_tmp_dh_callback(ctx, ssl_get_tmp_dh);
1527 }
Willy Tarreau6e774b42014-04-25 21:35:23 +02001528
Emeric Brun41fdb3c2013-04-26 11:05:44 +02001529 ret = 0; /* DH params not found */
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001530 }
Emeric Brun644cde02012-12-14 11:21:13 +01001531
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001532end:
1533 if (dh)
1534 DH_free(dh);
1535
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001536 return ret;
1537}
1538#endif
1539
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001540static int ssl_sock_add_cert_sni(SSL_CTX *ctx, struct bind_conf *s, char *name, int order)
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001541{
1542 struct sni_ctx *sc;
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001543 int wild = 0, neg = 0;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001544
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001545 if (*name == '!') {
1546 neg = 1;
1547 name++;
1548 }
1549 if (*name == '*') {
1550 wild = 1;
1551 name++;
1552 }
1553 /* !* filter is a nop */
1554 if (neg && wild)
1555 return order;
1556 if (*name) {
1557 int j, len;
1558 len = strlen(name);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001559 sc = malloc(sizeof(struct sni_ctx) + len + 1);
1560 for (j = 0; j < len; j++)
1561 sc->name.key[j] = tolower(name[j]);
1562 sc->name.key[len] = 0;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001563 sc->ctx = ctx;
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001564 sc->order = order++;
1565 sc->neg = neg;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001566 if (wild)
1567 ebst_insert(&s->sni_w_ctx, &sc->name);
1568 else
1569 ebst_insert(&s->sni_ctx, &sc->name);
1570 }
1571 return order;
1572}
1573
Emeric Brunfc0421f2012-09-07 17:30:07 +02001574/* Loads a certificate key and CA chain from a file. Returns 0 on error, -1 if
1575 * an early error happens and the caller must call SSL_CTX_free() by itelf.
1576 */
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001577static 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 +02001578{
1579 BIO *in;
1580 X509 *x = NULL, *ca;
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001581 int i, err;
Emeric Brunfc0421f2012-09-07 17:30:07 +02001582 int ret = -1;
1583 int order = 0;
1584 X509_NAME *xname;
1585 char *str;
Emeric Brunfc0421f2012-09-07 17:30:07 +02001586#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
1587 STACK_OF(GENERAL_NAME) *names;
1588#endif
1589
1590 in = BIO_new(BIO_s_file());
1591 if (in == NULL)
1592 goto end;
1593
1594 if (BIO_read_filename(in, file) <= 0)
1595 goto end;
1596
1597 x = PEM_read_bio_X509_AUX(in, NULL, ctx->default_passwd_callback, ctx->default_passwd_callback_userdata);
1598 if (x == NULL)
1599 goto end;
1600
Emeric Brun50bcecc2013-04-22 13:05:23 +02001601 if (fcount) {
1602 while (fcount--)
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001603 order = ssl_sock_add_cert_sni(ctx, s, sni_filter[fcount], order);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001604 }
1605 else {
Emeric Brunfc0421f2012-09-07 17:30:07 +02001606#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001607 names = X509_get_ext_d2i(x, NID_subject_alt_name, NULL, NULL);
1608 if (names) {
1609 for (i = 0; i < sk_GENERAL_NAME_num(names); i++) {
1610 GENERAL_NAME *name = sk_GENERAL_NAME_value(names, i);
1611 if (name->type == GEN_DNS) {
1612 if (ASN1_STRING_to_UTF8((unsigned char **)&str, name->d.dNSName) >= 0) {
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001613 order = ssl_sock_add_cert_sni(ctx, s, str, order);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001614 OPENSSL_free(str);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001615 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02001616 }
1617 }
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001618 sk_GENERAL_NAME_pop_free(names, GENERAL_NAME_free);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001619 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02001620#endif /* SSL_CTRL_SET_TLSEXT_HOSTNAME */
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001621 xname = X509_get_subject_name(x);
1622 i = -1;
1623 while ((i = X509_NAME_get_index_by_NID(xname, NID_commonName, i)) != -1) {
1624 X509_NAME_ENTRY *entry = X509_NAME_get_entry(xname, i);
1625 if (ASN1_STRING_to_UTF8((unsigned char **)&str, entry->value) >= 0) {
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001626 order = ssl_sock_add_cert_sni(ctx, s, str, order);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001627 OPENSSL_free(str);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001628 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02001629 }
1630 }
1631
1632 ret = 0; /* the caller must not free the SSL_CTX argument anymore */
1633 if (!SSL_CTX_use_certificate(ctx, x))
1634 goto end;
1635
1636 if (ctx->extra_certs != NULL) {
1637 sk_X509_pop_free(ctx->extra_certs, X509_free);
1638 ctx->extra_certs = NULL;
1639 }
1640
1641 while ((ca = PEM_read_bio_X509(in, NULL, ctx->default_passwd_callback, ctx->default_passwd_callback_userdata))) {
1642 if (!SSL_CTX_add_extra_chain_cert(ctx, ca)) {
1643 X509_free(ca);
1644 goto end;
1645 }
1646 }
1647
1648 err = ERR_get_error();
1649 if (!err || (ERR_GET_LIB(err) == ERR_LIB_PEM && ERR_GET_REASON(err) == PEM_R_NO_START_LINE)) {
1650 /* we successfully reached the last cert in the file */
1651 ret = 1;
1652 }
1653 ERR_clear_error();
1654
1655end:
1656 if (x)
1657 X509_free(x);
1658
1659 if (in)
1660 BIO_free(in);
1661
1662 return ret;
1663}
1664
Emeric Brun50bcecc2013-04-22 13:05:23 +02001665static 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 +02001666{
1667 int ret;
1668 SSL_CTX *ctx;
1669
1670 ctx = SSL_CTX_new(SSLv23_server_method());
1671 if (!ctx) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02001672 memprintf(err, "%sunable to allocate SSL context for cert '%s'.\n",
1673 err && *err ? *err : "", path);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001674 return 1;
1675 }
1676
1677 if (SSL_CTX_use_PrivateKey_file(ctx, path, SSL_FILETYPE_PEM) <= 0) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02001678 memprintf(err, "%sunable to load SSL private key from PEM file '%s'.\n",
1679 err && *err ? *err : "", path);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001680 SSL_CTX_free(ctx);
1681 return 1;
1682 }
1683
Emeric Brun50bcecc2013-04-22 13:05:23 +02001684 ret = ssl_sock_load_cert_chain_file(ctx, path, bind_conf, sni_filter, fcount);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001685 if (ret <= 0) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02001686 memprintf(err, "%sunable to load SSL certificate from PEM file '%s'.\n",
1687 err && *err ? *err : "", path);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001688 if (ret < 0) /* serious error, must do that ourselves */
1689 SSL_CTX_free(ctx);
1690 return 1;
1691 }
Emeric Brun61694ab2012-10-26 13:35:33 +02001692
1693 if (SSL_CTX_check_private_key(ctx) <= 0) {
1694 memprintf(err, "%sinconsistencies between private key and certificate loaded from PEM file '%s'.\n",
1695 err && *err ? *err : "", path);
1696 return 1;
1697 }
1698
Emeric Brunfc0421f2012-09-07 17:30:07 +02001699 /* we must not free the SSL_CTX anymore below, since it's already in
1700 * the tree, so it will be discovered and cleaned in time.
1701 */
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001702#ifndef OPENSSL_NO_DH
Remi Gacogne4f902b82015-05-28 16:23:00 +02001703 /* store a NULL pointer to indicate we have not yet loaded
1704 a custom DH param file */
1705 if (ssl_dh_ptr_index >= 0) {
1706 SSL_CTX_set_ex_data(ctx, ssl_dh_ptr_index, NULL);
1707 }
1708
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001709 ret = ssl_sock_load_dh_params(ctx, path);
1710 if (ret < 0) {
1711 if (err)
1712 memprintf(err, "%sunable to load DH parameters from file '%s'.\n",
1713 *err ? *err : "", path);
1714 return 1;
1715 }
1716#endif
1717
Lukas Tribuse4e30f72014-12-09 16:32:51 +01001718#if (defined SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB && !defined OPENSSL_NO_OCSP)
Emeric Brun4147b2e2014-06-16 18:36:30 +02001719 ret = ssl_sock_load_ocsp(ctx, path);
1720 if (ret < 0) {
1721 if (err)
1722 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",
1723 *err ? *err : "", path);
1724 return 1;
1725 }
1726#endif
1727
Janusz Dziemidowicz2c701b52015-03-07 23:03:59 +01001728#if (OPENSSL_VERSION_NUMBER >= 0x1000200fL && !defined OPENSSL_NO_TLSEXT && !defined OPENSSL_IS_BORINGSSL)
1729 if (sctl_ex_index >= 0) {
1730 ret = ssl_sock_load_sctl(ctx, path);
1731 if (ret < 0) {
1732 if (err)
1733 memprintf(err, "%s '%s.sctl' is present but cannot be read or parsed'.\n",
1734 *err ? *err : "", path);
1735 return 1;
1736 }
1737 }
1738#endif
1739
Emeric Brunfc0421f2012-09-07 17:30:07 +02001740#ifndef SSL_CTRL_SET_TLSEXT_HOSTNAME
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001741 if (bind_conf->default_ctx) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02001742 memprintf(err, "%sthis version of openssl cannot load multiple SSL certificates.\n",
1743 err && *err ? *err : "");
Emeric Brunfc0421f2012-09-07 17:30:07 +02001744 return 1;
1745 }
1746#endif
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001747 if (!bind_conf->default_ctx)
1748 bind_conf->default_ctx = ctx;
Emeric Brunfc0421f2012-09-07 17:30:07 +02001749
1750 return 0;
1751}
1752
Willy Tarreau79eeafa2012-09-14 07:53:05 +02001753int ssl_sock_load_cert(char *path, struct bind_conf *bind_conf, struct proxy *curproxy, char **err)
Emeric Brunfc0421f2012-09-07 17:30:07 +02001754{
Cyril Bonté3180f7b2015-01-25 00:16:08 +01001755 struct dirent **de_list;
1756 int i, n;
Emeric Brunfc0421f2012-09-07 17:30:07 +02001757 DIR *dir;
1758 struct stat buf;
Willy Tarreauee2663b2012-12-06 11:36:59 +01001759 char *end;
1760 char fp[MAXPATHLEN+1];
Emeric Brunfc0421f2012-09-07 17:30:07 +02001761 int cfgerr = 0;
1762
1763 if (!(dir = opendir(path)))
Emeric Brun50bcecc2013-04-22 13:05:23 +02001764 return ssl_sock_load_cert_file(path, bind_conf, curproxy, NULL, 0, err);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001765
1766 /* strip trailing slashes, including first one */
1767 for (end = path + strlen(path) - 1; end >= path && *end == '/'; end--)
1768 *end = 0;
1769
Cyril Bonté3180f7b2015-01-25 00:16:08 +01001770 n = scandir(path, &de_list, 0, alphasort);
1771 if (n < 0) {
1772 memprintf(err, "%sunable to scan directory '%s' : %s.\n",
1773 err && *err ? *err : "", path, strerror(errno));
1774 cfgerr++;
1775 }
1776 else {
1777 for (i = 0; i < n; i++) {
1778 struct dirent *de = de_list[i];
Emeric Brun2aab7222014-06-18 18:15:09 +02001779
Cyril Bonté3180f7b2015-01-25 00:16:08 +01001780 end = strrchr(de->d_name, '.');
Janusz Dziemidowicz2c701b52015-03-07 23:03:59 +01001781 if (end && (!strcmp(end, ".issuer") || !strcmp(end, ".ocsp") || !strcmp(end, ".sctl")))
Cyril Bonté3180f7b2015-01-25 00:16:08 +01001782 goto ignore_entry;
1783
1784 snprintf(fp, sizeof(fp), "%s/%s", path, de->d_name);
1785 if (stat(fp, &buf) != 0) {
1786 memprintf(err, "%sunable to stat SSL certificate from file '%s' : %s.\n",
1787 err && *err ? *err : "", fp, strerror(errno));
1788 cfgerr++;
1789 goto ignore_entry;
1790 }
1791 if (!S_ISREG(buf.st_mode))
1792 goto ignore_entry;
1793 cfgerr += ssl_sock_load_cert_file(fp, bind_conf, curproxy, NULL, 0, err);
1794 ignore_entry:
1795 free(de);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001796 }
Cyril Bonté3180f7b2015-01-25 00:16:08 +01001797 free(de_list);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001798 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02001799 closedir(dir);
1800 return cfgerr;
1801}
1802
Thierry Fournier383085f2013-01-24 14:15:43 +01001803/* Make sure openssl opens /dev/urandom before the chroot. The work is only
1804 * done once. Zero is returned if the operation fails. No error is returned
1805 * if the random is said as not implemented, because we expect that openssl
1806 * will use another method once needed.
1807 */
1808static int ssl_initialize_random()
1809{
1810 unsigned char random;
1811 static int random_initialized = 0;
1812
1813 if (!random_initialized && RAND_bytes(&random, 1) != 0)
1814 random_initialized = 1;
1815
1816 return random_initialized;
1817}
1818
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001819int ssl_sock_load_cert_list_file(char *file, struct bind_conf *bind_conf, struct proxy *curproxy, char **err)
1820{
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001821 char thisline[LINESIZE];
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001822 FILE *f;
1823 int linenum = 0;
1824 int cfgerr = 0;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001825
Willy Tarreauad1731d2013-04-02 17:35:58 +02001826 if ((f = fopen(file, "r")) == NULL) {
1827 memprintf(err, "cannot open file '%s' : %s", file, strerror(errno));
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001828 return 1;
Willy Tarreauad1731d2013-04-02 17:35:58 +02001829 }
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001830
1831 while (fgets(thisline, sizeof(thisline), f) != NULL) {
1832 int arg;
Emeric Brun50bcecc2013-04-22 13:05:23 +02001833 int newarg;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001834 char *end;
1835 char *args[MAX_LINE_ARGS + 1];
1836 char *line = thisline;
1837
1838 linenum++;
1839 end = line + strlen(line);
1840 if (end-line == sizeof(thisline)-1 && *(end-1) != '\n') {
1841 /* Check if we reached the limit and the last char is not \n.
1842 * Watch out for the last line without the terminating '\n'!
1843 */
Willy Tarreauad1731d2013-04-02 17:35:58 +02001844 memprintf(err, "line %d too long in file '%s', limit is %d characters",
1845 linenum, file, (int)sizeof(thisline)-1);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001846 cfgerr = 1;
Willy Tarreauad1731d2013-04-02 17:35:58 +02001847 break;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001848 }
1849
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001850 arg = 0;
Emeric Brun50bcecc2013-04-22 13:05:23 +02001851 newarg = 1;
1852 while (*line) {
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001853 if (*line == '#' || *line == '\n' || *line == '\r') {
1854 /* end of string, end of loop */
1855 *line = 0;
1856 break;
1857 }
1858 else if (isspace(*line)) {
Emeric Brun50bcecc2013-04-22 13:05:23 +02001859 newarg = 1;
1860 *line = 0;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001861 }
Emeric Brun50bcecc2013-04-22 13:05:23 +02001862 else if (newarg) {
1863 if (arg == MAX_LINE_ARGS) {
1864 memprintf(err, "too many args on line %d in file '%s'.",
1865 linenum, file);
1866 cfgerr = 1;
1867 break;
1868 }
1869 newarg = 0;
1870 args[arg++] = line;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001871 }
Emeric Brun50bcecc2013-04-22 13:05:23 +02001872 line++;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001873 }
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001874 if (cfgerr)
1875 break;
Willy Tarreauad1731d2013-04-02 17:35:58 +02001876
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001877 /* empty line */
Emeric Brun50bcecc2013-04-22 13:05:23 +02001878 if (!arg)
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001879 continue;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001880
Emeric Brun50bcecc2013-04-22 13:05:23 +02001881 cfgerr = ssl_sock_load_cert_file(args[0], bind_conf, curproxy, &args[1], arg-1, err);
Willy Tarreauad1731d2013-04-02 17:35:58 +02001882 if (cfgerr) {
1883 memprintf(err, "error processing line %d in file '%s' : %s", linenum, file, *err);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001884 break;
Willy Tarreauad1731d2013-04-02 17:35:58 +02001885 }
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001886 }
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001887 fclose(f);
1888 return cfgerr;
1889}
1890
Emeric Brunfc0421f2012-09-07 17:30:07 +02001891#ifndef SSL_OP_CIPHER_SERVER_PREFERENCE /* needs OpenSSL >= 0.9.7 */
1892#define SSL_OP_CIPHER_SERVER_PREFERENCE 0
1893#endif
1894
1895#ifndef SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION /* needs OpenSSL >= 0.9.7 */
1896#define SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION 0
Willy Tarreau7d588ee2012-11-26 18:47:31 +01001897#define SSL_renegotiate_pending(arg) 0
Emeric Brunfc0421f2012-09-07 17:30:07 +02001898#endif
Emeric Brun2b58d042012-09-20 17:10:03 +02001899#ifndef SSL_OP_SINGLE_ECDH_USE /* needs OpenSSL >= 0.9.8 */
1900#define SSL_OP_SINGLE_ECDH_USE 0
1901#endif
Emeric Brun2d0c4822012-10-02 13:45:20 +02001902#ifndef SSL_OP_NO_TICKET /* needs OpenSSL >= 0.9.8 */
1903#define SSL_OP_NO_TICKET 0
1904#endif
Emeric Brunfc0421f2012-09-07 17:30:07 +02001905#ifndef SSL_OP_NO_COMPRESSION /* needs OpenSSL >= 0.9.9 */
1906#define SSL_OP_NO_COMPRESSION 0
1907#endif
Emeric Brunc0ff4922012-09-28 19:37:02 +02001908#ifndef SSL_OP_NO_TLSv1_1 /* needs OpenSSL >= 1.0.1 */
1909#define SSL_OP_NO_TLSv1_1 0
1910#endif
1911#ifndef SSL_OP_NO_TLSv1_2 /* needs OpenSSL >= 1.0.1 */
1912#define SSL_OP_NO_TLSv1_2 0
1913#endif
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001914#ifndef SSL_OP_SINGLE_DH_USE /* needs OpenSSL >= 0.9.6 */
1915#define SSL_OP_SINGLE_DH_USE 0
1916#endif
Emeric Brun2b58d042012-09-20 17:10:03 +02001917#ifndef SSL_OP_SINGLE_ECDH_USE /* needs OpenSSL >= 1.0.0 */
1918#define SSL_OP_SINGLE_ECDH_USE 0
1919#endif
Emeric Brunfc0421f2012-09-07 17:30:07 +02001920#ifndef SSL_MODE_RELEASE_BUFFERS /* needs OpenSSL >= 1.0.0 */
1921#define SSL_MODE_RELEASE_BUFFERS 0
1922#endif
Willy Tarreau396a1862014-11-13 14:06:52 +01001923#ifndef SSL_MODE_SMALL_BUFFERS /* needs small_records.patch */
1924#define SSL_MODE_SMALL_BUFFERS 0
1925#endif
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001926
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001927int ssl_sock_prepare_ctx(struct bind_conf *bind_conf, SSL_CTX *ctx, struct proxy *curproxy)
Emeric Brunfc0421f2012-09-07 17:30:07 +02001928{
1929 int cfgerr = 0;
Emeric Brun850efd52014-01-29 12:24:34 +01001930 int verify = SSL_VERIFY_NONE;
Remi Gacogneaf5c3da2014-05-19 10:29:58 +02001931 long ssloptions =
Emeric Brunfc0421f2012-09-07 17:30:07 +02001932 SSL_OP_ALL | /* all known workarounds for bugs */
1933 SSL_OP_NO_SSLv2 |
1934 SSL_OP_NO_COMPRESSION |
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001935 SSL_OP_SINGLE_DH_USE |
Emeric Brun2b58d042012-09-20 17:10:03 +02001936 SSL_OP_SINGLE_ECDH_USE |
Emeric Brun3c4bc6e2012-10-04 18:44:19 +02001937 SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION |
1938 SSL_OP_CIPHER_SERVER_PREFERENCE;
Remi Gacogneaf5c3da2014-05-19 10:29:58 +02001939 long sslmode =
Emeric Brunfc0421f2012-09-07 17:30:07 +02001940 SSL_MODE_ENABLE_PARTIAL_WRITE |
1941 SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER |
Willy Tarreau396a1862014-11-13 14:06:52 +01001942 SSL_MODE_RELEASE_BUFFERS |
1943 SSL_MODE_SMALL_BUFFERS;
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001944 STACK_OF(SSL_CIPHER) * ciphers = NULL;
Willy Tarreaua616ba62014-10-26 06:49:19 +01001945 SSL_CIPHER * cipher = NULL;
Remi Gacognec1eab8c2014-06-12 18:20:11 +02001946 char cipher_description[128];
1947 /* The description of ciphers using an Ephemeral Diffie Hellman key exchange
1948 contains " Kx=DH " or " Kx=DH(". Beware of " Kx=DH/",
1949 which is not ephemeral DH. */
1950 const char dhe_description[] = " Kx=DH ";
1951 const char dhe_export_description[] = " Kx=DH(";
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001952 int idx = 0;
1953 int dhe_found = 0;
Remi Gacogne23d5d372014-10-10 17:04:26 +02001954 SSL *ssl = NULL;
Emeric Brunfc0421f2012-09-07 17:30:07 +02001955
Thierry Fournier383085f2013-01-24 14:15:43 +01001956 /* Make sure openssl opens /dev/urandom before the chroot */
1957 if (!ssl_initialize_random()) {
1958 Alert("OpenSSL random data generator initialization failed.\n");
1959 cfgerr++;
1960 }
1961
Emeric Brun89675492012-10-05 13:48:26 +02001962 if (bind_conf->ssl_options & BC_SSL_O_NO_SSLV3)
Emeric Brunfc0421f2012-09-07 17:30:07 +02001963 ssloptions |= SSL_OP_NO_SSLv3;
Emeric Brun89675492012-10-05 13:48:26 +02001964 if (bind_conf->ssl_options & BC_SSL_O_NO_TLSV10)
Emeric Brunfc0421f2012-09-07 17:30:07 +02001965 ssloptions |= SSL_OP_NO_TLSv1;
Emeric Brun89675492012-10-05 13:48:26 +02001966 if (bind_conf->ssl_options & BC_SSL_O_NO_TLSV11)
Emeric Brunc0ff4922012-09-28 19:37:02 +02001967 ssloptions |= SSL_OP_NO_TLSv1_1;
Emeric Brun89675492012-10-05 13:48:26 +02001968 if (bind_conf->ssl_options & BC_SSL_O_NO_TLSV12)
Emeric Brunc0ff4922012-09-28 19:37:02 +02001969 ssloptions |= SSL_OP_NO_TLSv1_2;
Emeric Brun89675492012-10-05 13:48:26 +02001970 if (bind_conf->ssl_options & BC_SSL_O_NO_TLS_TICKETS)
Emeric Brun2d0c4822012-10-02 13:45:20 +02001971 ssloptions |= SSL_OP_NO_TICKET;
Jérémie Courrèges-Anglas17c3f622015-07-25 16:50:52 -06001972 if (bind_conf->ssl_options & BC_SSL_O_USE_SSLV3) {
1973#ifndef OPENSSL_NO_SSL3
Emeric Brun2cb7ae52012-10-05 14:14:21 +02001974 SSL_CTX_set_ssl_version(ctx, SSLv3_server_method());
Jérémie Courrèges-Anglas17c3f622015-07-25 16:50:52 -06001975#else
1976 Alert("SSLv3 support requested but unavailable.\n");
1977 cfgerr++;
1978#endif
1979 }
Emeric Brun2cb7ae52012-10-05 14:14:21 +02001980 if (bind_conf->ssl_options & BC_SSL_O_USE_TLSV10)
1981 SSL_CTX_set_ssl_version(ctx, TLSv1_server_method());
1982#if SSL_OP_NO_TLSv1_1
1983 if (bind_conf->ssl_options & BC_SSL_O_USE_TLSV11)
1984 SSL_CTX_set_ssl_version(ctx, TLSv1_1_server_method());
1985#endif
1986#if SSL_OP_NO_TLSv1_2
1987 if (bind_conf->ssl_options & BC_SSL_O_USE_TLSV12)
1988 SSL_CTX_set_ssl_version(ctx, TLSv1_2_server_method());
1989#endif
Emeric Brunfc0421f2012-09-07 17:30:07 +02001990
1991 SSL_CTX_set_options(ctx, ssloptions);
1992 SSL_CTX_set_mode(ctx, sslmode);
Emeric Brun850efd52014-01-29 12:24:34 +01001993 switch (bind_conf->verify) {
1994 case SSL_SOCK_VERIFY_NONE:
1995 verify = SSL_VERIFY_NONE;
1996 break;
1997 case SSL_SOCK_VERIFY_OPTIONAL:
1998 verify = SSL_VERIFY_PEER;
1999 break;
2000 case SSL_SOCK_VERIFY_REQUIRED:
2001 verify = SSL_VERIFY_PEER|SSL_VERIFY_FAIL_IF_NO_PEER_CERT;
2002 break;
2003 }
2004 SSL_CTX_set_verify(ctx, verify, ssl_sock_bind_verifycbk);
2005 if (verify & SSL_VERIFY_PEER) {
Emeric Brunfb510ea2012-10-05 12:00:26 +02002006 if (bind_conf->ca_file) {
Emeric Brund94b3fe2012-09-20 18:23:56 +02002007 /* load CAfile to verify */
Emeric Brunfb510ea2012-10-05 12:00:26 +02002008 if (!SSL_CTX_load_verify_locations(ctx, bind_conf->ca_file, NULL)) {
Emeric Brund94b3fe2012-09-20 18:23:56 +02002009 Alert("Proxy '%s': unable to load CA file '%s' for bind '%s' at [%s:%d].\n",
Emeric Brunfb510ea2012-10-05 12:00:26 +02002010 curproxy->id, bind_conf->ca_file, bind_conf->arg, bind_conf->file, bind_conf->line);
Emeric Brund94b3fe2012-09-20 18:23:56 +02002011 cfgerr++;
2012 }
2013 /* set CA names fo client cert request, function returns void */
Emeric Brunfb510ea2012-10-05 12:00:26 +02002014 SSL_CTX_set_client_CA_list(ctx, SSL_load_client_CA_file(bind_conf->ca_file));
Emeric Brund94b3fe2012-09-20 18:23:56 +02002015 }
Emeric Brun850efd52014-01-29 12:24:34 +01002016 else {
2017 Alert("Proxy '%s': verify is enabled but no CA file specified for bind '%s' at [%s:%d].\n",
2018 curproxy->id, bind_conf->arg, bind_conf->file, bind_conf->line);
2019 cfgerr++;
2020 }
Emeric Brun051cdab2012-10-02 19:25:50 +02002021#ifdef X509_V_FLAG_CRL_CHECK
Emeric Brunfb510ea2012-10-05 12:00:26 +02002022 if (bind_conf->crl_file) {
Emeric Brund94b3fe2012-09-20 18:23:56 +02002023 X509_STORE *store = SSL_CTX_get_cert_store(ctx);
2024
Emeric Brunfb510ea2012-10-05 12:00:26 +02002025 if (!store || !X509_STORE_load_locations(store, bind_conf->crl_file, NULL)) {
Emeric Brund94b3fe2012-09-20 18:23:56 +02002026 Alert("Proxy '%s': unable to configure CRL file '%s' for bind '%s' at [%s:%d].\n",
Alexander Rigbofc65af02015-04-07 14:02:16 +02002027 curproxy->id, bind_conf->crl_file, bind_conf->arg, bind_conf->file, bind_conf->line);
Emeric Brund94b3fe2012-09-20 18:23:56 +02002028 cfgerr++;
2029 }
Emeric Brun561e5742012-10-02 15:20:55 +02002030 else {
2031 X509_STORE_set_flags(store, X509_V_FLAG_CRL_CHECK|X509_V_FLAG_CRL_CHECK_ALL);
2032 }
Emeric Brund94b3fe2012-09-20 18:23:56 +02002033 }
Emeric Brun051cdab2012-10-02 19:25:50 +02002034#endif
Emeric Brun644cde02012-12-14 11:21:13 +01002035 ERR_clear_error();
Emeric Brund94b3fe2012-09-20 18:23:56 +02002036 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02002037
Nenad Merdanovic05552d42015-02-27 19:56:49 +01002038#if (defined SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB && TLS_TICKETS_NO > 0)
Nenad Merdanovic146defa2015-05-09 08:46:00 +02002039 if(bind_conf->keys_ref) {
Nenad Merdanovic05552d42015-02-27 19:56:49 +01002040 if (!SSL_CTX_set_tlsext_ticket_key_cb(ctx, ssl_tlsext_ticket_key_cb)) {
2041 Alert("Proxy '%s': unable to set callback for TLS ticket validation for bind '%s' at [%s:%d].\n",
2042 curproxy->id, bind_conf->arg, bind_conf->file, bind_conf->line);
2043 cfgerr++;
2044 }
2045 }
2046#endif
2047
Emeric Brun4f65bff2012-11-16 15:11:00 +01002048 if (global.tune.ssllifetime)
2049 SSL_CTX_set_timeout(ctx, global.tune.ssllifetime);
2050
Emeric Brunfc0421f2012-09-07 17:30:07 +02002051 shared_context_set_cache(ctx);
Willy Tarreau2a65ff02012-09-13 17:54:29 +02002052 if (bind_conf->ciphers &&
2053 !SSL_CTX_set_cipher_list(ctx, bind_conf->ciphers)) {
Emeric Brunfc0421f2012-09-07 17:30:07 +02002054 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 +02002055 curproxy->id, bind_conf->ciphers, bind_conf->arg, bind_conf->file, bind_conf->line);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002056 cfgerr++;
2057 }
2058
Remi Gacogne47783ef2015-05-29 15:53:22 +02002059 /* If tune.ssl.default-dh-param has not been set,
2060 neither has ssl-default-dh-file and no static DH
2061 params were in the certificate file. */
Remi Gacogne4f902b82015-05-28 16:23:00 +02002062 if (global.tune.ssl_default_dh_param == 0 &&
Remi Gacogne47783ef2015-05-29 15:53:22 +02002063 global_dh == NULL &&
Remi Gacogne4f902b82015-05-28 16:23:00 +02002064 (ssl_dh_ptr_index == -1 ||
2065 SSL_CTX_get_ex_data(ctx, ssl_dh_ptr_index) == NULL)) {
Lukas Tribus90132722014-08-18 00:56:33 +02002066
Remi Gacogne23d5d372014-10-10 17:04:26 +02002067 ssl = SSL_new(ctx);
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002068
Remi Gacogne23d5d372014-10-10 17:04:26 +02002069 if (ssl) {
2070 ciphers = SSL_get_ciphers(ssl);
2071
2072 if (ciphers) {
2073 for (idx = 0; idx < sk_SSL_CIPHER_num(ciphers); idx++) {
2074 cipher = sk_SSL_CIPHER_value(ciphers, idx);
2075 if (SSL_CIPHER_description(cipher, cipher_description, sizeof (cipher_description)) == cipher_description) {
2076 if (strstr(cipher_description, dhe_description) != NULL ||
2077 strstr(cipher_description, dhe_export_description) != NULL) {
2078 dhe_found = 1;
2079 break;
2080 }
Remi Gacognec1eab8c2014-06-12 18:20:11 +02002081 }
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002082 }
2083 }
Remi Gacogne23d5d372014-10-10 17:04:26 +02002084 SSL_free(ssl);
2085 ssl = NULL;
Lukas Tribus90132722014-08-18 00:56:33 +02002086 }
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002087
Lukas Tribus90132722014-08-18 00:56:33 +02002088 if (dhe_found) {
2089 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 +02002090 }
2091
2092 global.tune.ssl_default_dh_param = 1024;
2093 }
Remi Gacogne8de54152014-07-15 11:36:40 +02002094
2095#ifndef OPENSSL_NO_DH
2096 if (global.tune.ssl_default_dh_param >= 1024) {
2097 if (local_dh_1024 == NULL) {
2098 local_dh_1024 = ssl_get_dh_1024();
2099 }
2100 if (global.tune.ssl_default_dh_param >= 2048) {
2101 if (local_dh_2048 == NULL) {
2102 local_dh_2048 = ssl_get_dh_2048();
2103 }
2104 if (global.tune.ssl_default_dh_param >= 4096) {
2105 if (local_dh_4096 == NULL) {
2106 local_dh_4096 = ssl_get_dh_4096();
2107 }
Remi Gacogne8de54152014-07-15 11:36:40 +02002108 }
2109 }
2110 }
2111#endif /* OPENSSL_NO_DH */
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002112
Emeric Brunfc0421f2012-09-07 17:30:07 +02002113 SSL_CTX_set_info_callback(ctx, ssl_sock_infocbk);
Willy Tarreau5cbe4ef2014-05-08 22:45:11 +02002114#if OPENSSL_VERSION_NUMBER >= 0x00907000L
Emeric Brun29f037d2014-04-25 19:05:36 +02002115 SSL_CTX_set_msg_callback(ctx, ssl_sock_msgcbk);
Willy Tarreau5cbe4ef2014-05-08 22:45:11 +02002116#endif
Emeric Brun29f037d2014-04-25 19:05:36 +02002117
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02002118#ifdef OPENSSL_NPN_NEGOTIATED
2119 if (bind_conf->npn_str)
2120 SSL_CTX_set_next_protos_advertised_cb(ctx, ssl_sock_advertise_npn_protos, bind_conf);
2121#endif
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01002122#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Willy Tarreauab861d32013-04-02 02:30:41 +02002123 if (bind_conf->alpn_str)
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01002124 SSL_CTX_set_alpn_select_cb(ctx, ssl_sock_advertise_alpn_protos, bind_conf);
Willy Tarreauab861d32013-04-02 02:30:41 +02002125#endif
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02002126
Emeric Brunfc0421f2012-09-07 17:30:07 +02002127#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
2128 SSL_CTX_set_tlsext_servername_callback(ctx, ssl_sock_switchctx_cbk);
Willy Tarreau2a65ff02012-09-13 17:54:29 +02002129 SSL_CTX_set_tlsext_servername_arg(ctx, bind_conf);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002130#endif
Emeric Brun2b58d042012-09-20 17:10:03 +02002131#if defined(SSL_CTX_set_tmp_ecdh) && !defined(OPENSSL_NO_ECDH)
Emeric Brun6924ef82013-03-06 14:08:53 +01002132 {
Emeric Brun2b58d042012-09-20 17:10:03 +02002133 int i;
2134 EC_KEY *ecdh;
2135
Emeric Brun6924ef82013-03-06 14:08:53 +01002136 i = OBJ_sn2nid(bind_conf->ecdhe ? bind_conf->ecdhe : ECDHE_DEFAULT_CURVE);
Emeric Brun2b58d042012-09-20 17:10:03 +02002137 if (!i || ((ecdh = EC_KEY_new_by_curve_name(i)) == NULL)) {
2138 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 +01002139 curproxy->id, bind_conf->ecdhe ? bind_conf->ecdhe : ECDHE_DEFAULT_CURVE,
2140 bind_conf->arg, bind_conf->file, bind_conf->line);
Emeric Brun2b58d042012-09-20 17:10:03 +02002141 cfgerr++;
2142 }
2143 else {
2144 SSL_CTX_set_tmp_ecdh(ctx, ecdh);
2145 EC_KEY_free(ecdh);
2146 }
2147 }
2148#endif
2149
Emeric Brunfc0421f2012-09-07 17:30:07 +02002150 return cfgerr;
2151}
2152
Evan Broderbe554312013-06-27 00:05:25 -07002153static int ssl_sock_srv_hostcheck(const char *pattern, const char *hostname)
2154{
2155 const char *pattern_wildcard, *pattern_left_label_end, *hostname_left_label_end;
2156 size_t prefixlen, suffixlen;
2157
2158 /* Trivial case */
2159 if (strcmp(pattern, hostname) == 0)
2160 return 1;
2161
Evan Broderbe554312013-06-27 00:05:25 -07002162 /* The rest of this logic is based on RFC 6125, section 6.4.3
2163 * (http://tools.ietf.org/html/rfc6125#section-6.4.3) */
2164
Emeric Bruna848dae2013-10-08 11:27:28 +02002165 pattern_wildcard = NULL;
2166 pattern_left_label_end = pattern;
2167 while (*pattern_left_label_end != '.') {
2168 switch (*pattern_left_label_end) {
2169 case 0:
2170 /* End of label not found */
2171 return 0;
2172 case '*':
2173 /* If there is more than one wildcards */
2174 if (pattern_wildcard)
2175 return 0;
2176 pattern_wildcard = pattern_left_label_end;
2177 break;
2178 }
2179 pattern_left_label_end++;
2180 }
2181
2182 /* If it's not trivial and there is no wildcard, it can't
2183 * match */
2184 if (!pattern_wildcard)
Evan Broderbe554312013-06-27 00:05:25 -07002185 return 0;
2186
2187 /* Make sure all labels match except the leftmost */
2188 hostname_left_label_end = strchr(hostname, '.');
2189 if (!hostname_left_label_end
2190 || strcmp(pattern_left_label_end, hostname_left_label_end) != 0)
2191 return 0;
2192
2193 /* Make sure the leftmost label of the hostname is long enough
2194 * that the wildcard can match */
Emeric Brun369da852013-10-08 11:39:35 +02002195 if (hostname_left_label_end - hostname < (pattern_left_label_end - pattern) - 1)
Evan Broderbe554312013-06-27 00:05:25 -07002196 return 0;
2197
2198 /* Finally compare the string on either side of the
2199 * wildcard */
2200 prefixlen = pattern_wildcard - pattern;
2201 suffixlen = pattern_left_label_end - (pattern_wildcard + 1);
Emeric Bruna848dae2013-10-08 11:27:28 +02002202 if ((prefixlen && (memcmp(pattern, hostname, prefixlen) != 0))
2203 || (suffixlen && (memcmp(pattern_wildcard + 1, hostname_left_label_end - suffixlen, suffixlen) != 0)))
Evan Broderbe554312013-06-27 00:05:25 -07002204 return 0;
2205
2206 return 1;
2207}
2208
2209static int ssl_sock_srv_verifycbk(int ok, X509_STORE_CTX *ctx)
2210{
2211 SSL *ssl;
2212 struct connection *conn;
2213 char *servername;
2214
2215 int depth;
2216 X509 *cert;
2217 STACK_OF(GENERAL_NAME) *alt_names;
2218 int i;
2219 X509_NAME *cert_subject;
2220 char *str;
2221
2222 if (ok == 0)
2223 return ok;
2224
2225 ssl = X509_STORE_CTX_get_ex_data(ctx, SSL_get_ex_data_X509_STORE_CTX_idx());
2226 conn = (struct connection *)SSL_get_app_data(ssl);
2227
2228 servername = objt_server(conn->target)->ssl_ctx.verify_host;
2229
2230 /* We only need to verify the CN on the actual server cert,
2231 * not the indirect CAs */
2232 depth = X509_STORE_CTX_get_error_depth(ctx);
2233 if (depth != 0)
2234 return ok;
2235
2236 /* At this point, the cert is *not* OK unless we can find a
2237 * hostname match */
2238 ok = 0;
2239
2240 cert = X509_STORE_CTX_get_current_cert(ctx);
2241 /* It seems like this might happen if verify peer isn't set */
2242 if (!cert)
2243 return ok;
2244
2245 alt_names = X509_get_ext_d2i(cert, NID_subject_alt_name, NULL, NULL);
2246 if (alt_names) {
2247 for (i = 0; !ok && i < sk_GENERAL_NAME_num(alt_names); i++) {
2248 GENERAL_NAME *name = sk_GENERAL_NAME_value(alt_names, i);
2249 if (name->type == GEN_DNS) {
Emeric Bruna33410c2013-09-17 15:47:48 +02002250#if OPENSSL_VERSION_NUMBER < 0x00907000L
2251 if (ASN1_STRING_to_UTF8((unsigned char **)&str, name->d.ia5) >= 0) {
2252#else
Evan Broderbe554312013-06-27 00:05:25 -07002253 if (ASN1_STRING_to_UTF8((unsigned char **)&str, name->d.dNSName) >= 0) {
Emeric Bruna33410c2013-09-17 15:47:48 +02002254#endif
Evan Broderbe554312013-06-27 00:05:25 -07002255 ok = ssl_sock_srv_hostcheck(str, servername);
2256 OPENSSL_free(str);
2257 }
2258 }
2259 }
Emeric Brun4ad50a42013-09-17 15:19:54 +02002260 sk_GENERAL_NAME_pop_free(alt_names, GENERAL_NAME_free);
Evan Broderbe554312013-06-27 00:05:25 -07002261 }
2262
2263 cert_subject = X509_get_subject_name(cert);
2264 i = -1;
2265 while (!ok && (i = X509_NAME_get_index_by_NID(cert_subject, NID_commonName, i)) != -1) {
2266 X509_NAME_ENTRY *entry = X509_NAME_get_entry(cert_subject, i);
2267 if (ASN1_STRING_to_UTF8((unsigned char **)&str, entry->value) >= 0) {
2268 ok = ssl_sock_srv_hostcheck(str, servername);
2269 OPENSSL_free(str);
2270 }
2271 }
2272
2273 return ok;
2274}
2275
Emeric Brun94324a42012-10-11 14:00:19 +02002276/* prepare ssl context from servers options. Returns an error count */
2277int ssl_sock_prepare_srv_ctx(struct server *srv, struct proxy *curproxy)
2278{
2279 int cfgerr = 0;
Remi Gacogneaf5c3da2014-05-19 10:29:58 +02002280 long options =
Emeric Brun94324a42012-10-11 14:00:19 +02002281 SSL_OP_ALL | /* all known workarounds for bugs */
2282 SSL_OP_NO_SSLv2 |
2283 SSL_OP_NO_COMPRESSION;
Remi Gacogneaf5c3da2014-05-19 10:29:58 +02002284 long mode =
Emeric Brun94324a42012-10-11 14:00:19 +02002285 SSL_MODE_ENABLE_PARTIAL_WRITE |
2286 SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER |
Willy Tarreau396a1862014-11-13 14:06:52 +01002287 SSL_MODE_RELEASE_BUFFERS |
2288 SSL_MODE_SMALL_BUFFERS;
Emeric Brun850efd52014-01-29 12:24:34 +01002289 int verify = SSL_VERIFY_NONE;
Emeric Brun94324a42012-10-11 14:00:19 +02002290
Thierry Fournier383085f2013-01-24 14:15:43 +01002291 /* Make sure openssl opens /dev/urandom before the chroot */
2292 if (!ssl_initialize_random()) {
2293 Alert("OpenSSL random data generator initialization failed.\n");
2294 cfgerr++;
2295 }
2296
Willy Tarreaufce03112015-01-15 21:32:40 +01002297 /* Automatic memory computations need to know we use SSL there */
2298 global.ssl_used_backend = 1;
2299
2300 /* Initiate SSL context for current server */
Emeric Brun94324a42012-10-11 14:00:19 +02002301 srv->ssl_ctx.reused_sess = NULL;
2302 if (srv->use_ssl)
2303 srv->xprt = &ssl_sock;
2304 if (srv->check.use_ssl)
Cyril Bonté9ce13112014-11-15 22:41:27 +01002305 srv->check.xprt = &ssl_sock;
Emeric Brun94324a42012-10-11 14:00:19 +02002306
2307 srv->ssl_ctx.ctx = SSL_CTX_new(SSLv23_client_method());
2308 if (!srv->ssl_ctx.ctx) {
2309 Alert("config : %s '%s', server '%s': unable to allocate ssl context.\n",
2310 proxy_type_str(curproxy), curproxy->id,
2311 srv->id);
2312 cfgerr++;
2313 return cfgerr;
2314 }
Emeric Bruna7aa3092012-10-26 12:58:00 +02002315 if (srv->ssl_ctx.client_crt) {
2316 if (SSL_CTX_use_PrivateKey_file(srv->ssl_ctx.ctx, srv->ssl_ctx.client_crt, SSL_FILETYPE_PEM) <= 0) {
2317 Alert("config : %s '%s', server '%s': unable to load SSL private key from PEM file '%s'.\n",
2318 proxy_type_str(curproxy), curproxy->id,
2319 srv->id, srv->ssl_ctx.client_crt);
2320 cfgerr++;
2321 }
2322 else if (SSL_CTX_use_certificate_chain_file(srv->ssl_ctx.ctx, srv->ssl_ctx.client_crt) <= 0) {
2323 Alert("config : %s '%s', server '%s': unable to load ssl certificate from PEM file '%s'.\n",
2324 proxy_type_str(curproxy), curproxy->id,
2325 srv->id, srv->ssl_ctx.client_crt);
2326 cfgerr++;
2327 }
2328 else if (SSL_CTX_check_private_key(srv->ssl_ctx.ctx) <= 0) {
2329 Alert("config : %s '%s', server '%s': inconsistencies between private key and certificate loaded from PEM file '%s'.\n",
2330 proxy_type_str(curproxy), curproxy->id,
2331 srv->id, srv->ssl_ctx.client_crt);
2332 cfgerr++;
2333 }
2334 }
Emeric Brun94324a42012-10-11 14:00:19 +02002335
2336 if (srv->ssl_ctx.options & SRV_SSL_O_NO_SSLV3)
2337 options |= SSL_OP_NO_SSLv3;
2338 if (srv->ssl_ctx.options & SRV_SSL_O_NO_TLSV10)
2339 options |= SSL_OP_NO_TLSv1;
2340 if (srv->ssl_ctx.options & SRV_SSL_O_NO_TLSV11)
2341 options |= SSL_OP_NO_TLSv1_1;
2342 if (srv->ssl_ctx.options & SRV_SSL_O_NO_TLSV12)
2343 options |= SSL_OP_NO_TLSv1_2;
Emeric Brunf9c5c472012-10-11 15:28:34 +02002344 if (srv->ssl_ctx.options & SRV_SSL_O_NO_TLS_TICKETS)
2345 options |= SSL_OP_NO_TICKET;
Jérémie Courrèges-Anglas17c3f622015-07-25 16:50:52 -06002346 if (srv->ssl_ctx.options & SRV_SSL_O_USE_SSLV3) {
2347#ifndef OPENSSL_NO_SSL3
Emeric Brun94324a42012-10-11 14:00:19 +02002348 SSL_CTX_set_ssl_version(srv->ssl_ctx.ctx, SSLv3_client_method());
Jérémie Courrèges-Anglas17c3f622015-07-25 16:50:52 -06002349#else
Thierry FOURNIERbc965342015-08-26 08:21:26 +02002350 Alert("SSLv3 support requested but unavailable.\n");
Jérémie Courrèges-Anglas17c3f622015-07-25 16:50:52 -06002351 cfgerr++;
2352#endif
2353 }
Emeric Brun94324a42012-10-11 14:00:19 +02002354 if (srv->ssl_ctx.options & SRV_SSL_O_USE_TLSV10)
2355 SSL_CTX_set_ssl_version(srv->ssl_ctx.ctx, TLSv1_client_method());
2356#if SSL_OP_NO_TLSv1_1
2357 if (srv->ssl_ctx.options & SRV_SSL_O_USE_TLSV11)
2358 SSL_CTX_set_ssl_version(srv->ssl_ctx.ctx, TLSv1_1_client_method());
2359#endif
2360#if SSL_OP_NO_TLSv1_2
2361 if (srv->ssl_ctx.options & SRV_SSL_O_USE_TLSV12)
2362 SSL_CTX_set_ssl_version(srv->ssl_ctx.ctx, TLSv1_2_client_method());
2363#endif
2364
2365 SSL_CTX_set_options(srv->ssl_ctx.ctx, options);
2366 SSL_CTX_set_mode(srv->ssl_ctx.ctx, mode);
Emeric Brun850efd52014-01-29 12:24:34 +01002367
2368 if (global.ssl_server_verify == SSL_SERVER_VERIFY_REQUIRED)
2369 verify = SSL_VERIFY_PEER;
2370
2371 switch (srv->ssl_ctx.verify) {
2372 case SSL_SOCK_VERIFY_NONE:
2373 verify = SSL_VERIFY_NONE;
2374 break;
2375 case SSL_SOCK_VERIFY_REQUIRED:
2376 verify = SSL_VERIFY_PEER;
2377 break;
2378 }
Evan Broderbe554312013-06-27 00:05:25 -07002379 SSL_CTX_set_verify(srv->ssl_ctx.ctx,
Emeric Brun850efd52014-01-29 12:24:34 +01002380 verify,
Evan Broderbe554312013-06-27 00:05:25 -07002381 srv->ssl_ctx.verify_host ? ssl_sock_srv_verifycbk : NULL);
Emeric Brun850efd52014-01-29 12:24:34 +01002382 if (verify & SSL_VERIFY_PEER) {
Emeric Brunef42d922012-10-11 16:11:36 +02002383 if (srv->ssl_ctx.ca_file) {
2384 /* load CAfile to verify */
2385 if (!SSL_CTX_load_verify_locations(srv->ssl_ctx.ctx, srv->ssl_ctx.ca_file, NULL)) {
Willy Tarreau07ba08b2014-02-16 19:22:08 +01002386 Alert("Proxy '%s', server '%s' [%s:%d] unable to load CA file '%s'.\n",
Emeric Brunef42d922012-10-11 16:11:36 +02002387 curproxy->id, srv->id,
2388 srv->conf.file, srv->conf.line, srv->ssl_ctx.ca_file);
2389 cfgerr++;
2390 }
2391 }
Emeric Brun850efd52014-01-29 12:24:34 +01002392 else {
2393 if (global.ssl_server_verify == SSL_SERVER_VERIFY_REQUIRED)
Willy Tarreau07ba08b2014-02-16 19:22:08 +01002394 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 +01002395 curproxy->id, srv->id,
2396 srv->conf.file, srv->conf.line);
2397 else
Willy Tarreau07ba08b2014-02-16 19:22:08 +01002398 Alert("Proxy '%s', server '%s' [%s:%d] verify is enabled but no CA file specified.\n",
Emeric Brun850efd52014-01-29 12:24:34 +01002399 curproxy->id, srv->id,
2400 srv->conf.file, srv->conf.line);
2401 cfgerr++;
2402 }
Emeric Brunef42d922012-10-11 16:11:36 +02002403#ifdef X509_V_FLAG_CRL_CHECK
2404 if (srv->ssl_ctx.crl_file) {
2405 X509_STORE *store = SSL_CTX_get_cert_store(srv->ssl_ctx.ctx);
2406
2407 if (!store || !X509_STORE_load_locations(store, srv->ssl_ctx.crl_file, NULL)) {
Willy Tarreau07ba08b2014-02-16 19:22:08 +01002408 Alert("Proxy '%s', server '%s' [%s:%d] unable to configure CRL file '%s'.\n",
Emeric Brunef42d922012-10-11 16:11:36 +02002409 curproxy->id, srv->id,
2410 srv->conf.file, srv->conf.line, srv->ssl_ctx.crl_file);
2411 cfgerr++;
2412 }
2413 else {
2414 X509_STORE_set_flags(store, X509_V_FLAG_CRL_CHECK|X509_V_FLAG_CRL_CHECK_ALL);
2415 }
2416 }
2417#endif
2418 }
2419
Emeric Brun4f65bff2012-11-16 15:11:00 +01002420 if (global.tune.ssllifetime)
2421 SSL_CTX_set_timeout(srv->ssl_ctx.ctx, global.tune.ssllifetime);
2422
Emeric Brun94324a42012-10-11 14:00:19 +02002423 SSL_CTX_set_session_cache_mode(srv->ssl_ctx.ctx, SSL_SESS_CACHE_OFF);
2424 if (srv->ssl_ctx.ciphers &&
2425 !SSL_CTX_set_cipher_list(srv->ssl_ctx.ctx, srv->ssl_ctx.ciphers)) {
2426 Alert("Proxy '%s', server '%s' [%s:%d] : unable to set SSL cipher list to '%s'.\n",
2427 curproxy->id, srv->id,
2428 srv->conf.file, srv->conf.line, srv->ssl_ctx.ciphers);
2429 cfgerr++;
2430 }
2431
2432 return cfgerr;
2433}
2434
Willy Tarreau2a65ff02012-09-13 17:54:29 +02002435/* Walks down the two trees in bind_conf and prepares all certs. The pointer may
Emeric Brunfc0421f2012-09-07 17:30:07 +02002436 * be NULL, in which case nothing is done. Returns the number of errors
2437 * encountered.
2438 */
Willy Tarreau2a65ff02012-09-13 17:54:29 +02002439int ssl_sock_prepare_all_ctx(struct bind_conf *bind_conf, struct proxy *px)
Emeric Brunfc0421f2012-09-07 17:30:07 +02002440{
2441 struct ebmb_node *node;
2442 struct sni_ctx *sni;
2443 int err = 0;
2444
Willy Tarreau2a65ff02012-09-13 17:54:29 +02002445 if (!bind_conf || !bind_conf->is_ssl)
Emeric Brunfc0421f2012-09-07 17:30:07 +02002446 return 0;
2447
Willy Tarreaufce03112015-01-15 21:32:40 +01002448 /* Automatic memory computations need to know we use SSL there */
2449 global.ssl_used_frontend = 1;
2450
Emeric Brun0bed9942014-10-30 19:25:24 +01002451 if (bind_conf->default_ctx)
2452 err += ssl_sock_prepare_ctx(bind_conf, bind_conf->default_ctx, px);
2453
Willy Tarreau2a65ff02012-09-13 17:54:29 +02002454 node = ebmb_first(&bind_conf->sni_ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002455 while (node) {
2456 sni = ebmb_entry(node, struct sni_ctx, name);
Emeric Brun0bed9942014-10-30 19:25:24 +01002457 if (!sni->order && sni->ctx != bind_conf->default_ctx)
2458 /* only initialize the CTX on its first occurrence and
2459 if it is not the default_ctx */
Willy Tarreau2a65ff02012-09-13 17:54:29 +02002460 err += ssl_sock_prepare_ctx(bind_conf, sni->ctx, px);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002461 node = ebmb_next(node);
2462 }
2463
Willy Tarreau2a65ff02012-09-13 17:54:29 +02002464 node = ebmb_first(&bind_conf->sni_w_ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002465 while (node) {
2466 sni = ebmb_entry(node, struct sni_ctx, name);
Emeric Brun0bed9942014-10-30 19:25:24 +01002467 if (!sni->order && sni->ctx != bind_conf->default_ctx)
2468 /* only initialize the CTX on its first occurrence and
2469 if it is not the default_ctx */
Willy Tarreau2a65ff02012-09-13 17:54:29 +02002470 err += ssl_sock_prepare_ctx(bind_conf, sni->ctx, px);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002471 node = ebmb_next(node);
2472 }
2473 return err;
2474}
2475
Christopher Faulet77fe80c2015-07-29 13:02:40 +02002476
2477/* release ssl context allocated for servers. */
2478void ssl_sock_free_srv_ctx(struct server *srv)
2479{
2480 if (srv->ssl_ctx.ctx)
2481 SSL_CTX_free(srv->ssl_ctx.ctx);
2482}
2483
Willy Tarreau2a65ff02012-09-13 17:54:29 +02002484/* Walks down the two trees in bind_conf and frees all the certs. The pointer may
Emeric Brunfc0421f2012-09-07 17:30:07 +02002485 * be NULL, in which case nothing is done. The default_ctx is nullified too.
2486 */
Willy Tarreau2a65ff02012-09-13 17:54:29 +02002487void ssl_sock_free_all_ctx(struct bind_conf *bind_conf)
Emeric Brunfc0421f2012-09-07 17:30:07 +02002488{
2489 struct ebmb_node *node, *back;
2490 struct sni_ctx *sni;
2491
Willy Tarreau2a65ff02012-09-13 17:54:29 +02002492 if (!bind_conf || !bind_conf->is_ssl)
Emeric Brunfc0421f2012-09-07 17:30:07 +02002493 return;
2494
Willy Tarreau2a65ff02012-09-13 17:54:29 +02002495 node = ebmb_first(&bind_conf->sni_ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002496 while (node) {
2497 sni = ebmb_entry(node, struct sni_ctx, name);
2498 back = ebmb_next(node);
2499 ebmb_delete(node);
2500 if (!sni->order) /* only free the CTX on its first occurrence */
2501 SSL_CTX_free(sni->ctx);
2502 free(sni);
2503 node = back;
2504 }
2505
Willy Tarreau2a65ff02012-09-13 17:54:29 +02002506 node = ebmb_first(&bind_conf->sni_w_ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002507 while (node) {
2508 sni = ebmb_entry(node, struct sni_ctx, name);
2509 back = ebmb_next(node);
2510 ebmb_delete(node);
2511 if (!sni->order) /* only free the CTX on its first occurrence */
2512 SSL_CTX_free(sni->ctx);
2513 free(sni);
2514 node = back;
2515 }
2516
Willy Tarreau2a65ff02012-09-13 17:54:29 +02002517 bind_conf->default_ctx = NULL;
Emeric Brune1f38db2012-09-03 20:36:47 +02002518}
2519
Christopher Faulet31af49d2015-06-09 17:29:50 +02002520/* Load CA cert file and private key used to generate certificates */
2521int
2522ssl_sock_load_ca(struct bind_conf *bind_conf, struct proxy *px)
2523{
2524 FILE *fp;
2525 X509 *cacert = NULL;
2526 EVP_PKEY *capkey = NULL;
2527 int err = 0;
2528
2529 if (!bind_conf || !bind_conf->generate_certs)
2530 return err;
2531
Willy Tarreaua84c2672015-10-09 12:10:13 +02002532#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Christopher Fauletd2cab922015-07-28 16:03:47 +02002533 if (global.tune.ssl_ctx_cache)
2534 ssl_ctx_lru_tree = lru64_new(global.tune.ssl_ctx_cache);
2535 ssl_ctx_lru_seed = (unsigned int)time(NULL);
Willy Tarreaua84c2672015-10-09 12:10:13 +02002536#endif
Christopher Fauletd2cab922015-07-28 16:03:47 +02002537
Christopher Faulet31af49d2015-06-09 17:29:50 +02002538 if (!bind_conf->ca_sign_file) {
2539 Alert("Proxy '%s': cannot enable certificate generation, "
2540 "no CA certificate File configured at [%s:%d].\n",
2541 px->id, bind_conf->file, bind_conf->line);
Christopher Faulet31af49d2015-06-09 17:29:50 +02002542 goto load_error;
Christopher Fauletc6f02fb2015-10-09 10:53:31 +02002543 }
Christopher Faulet31af49d2015-06-09 17:29:50 +02002544
2545 /* read in the CA certificate */
2546 if (!(fp = fopen(bind_conf->ca_sign_file, "r"))) {
2547 Alert("Proxy '%s': Failed to read CA certificate file '%s' at [%s:%d].\n",
2548 px->id, bind_conf->ca_sign_file, bind_conf->file, bind_conf->line);
Christopher Faulet31af49d2015-06-09 17:29:50 +02002549 goto load_error;
2550 }
2551 if (!(cacert = PEM_read_X509(fp, NULL, NULL, NULL))) {
2552 Alert("Proxy '%s': Failed to read CA certificate file '%s' at [%s:%d].\n",
2553 px->id, bind_conf->ca_sign_file, bind_conf->file, bind_conf->line);
Christopher Fauletc6f02fb2015-10-09 10:53:31 +02002554 goto read_error;
Christopher Faulet31af49d2015-06-09 17:29:50 +02002555 }
Christopher Fauletc6f02fb2015-10-09 10:53:31 +02002556 rewind(fp);
Christopher Faulet31af49d2015-06-09 17:29:50 +02002557 if (!(capkey = PEM_read_PrivateKey(fp, NULL, NULL, bind_conf->ca_sign_pass))) {
2558 Alert("Proxy '%s': Failed to read CA private key file '%s' at [%s:%d].\n",
2559 px->id, bind_conf->ca_sign_file, bind_conf->file, bind_conf->line);
Christopher Fauletc6f02fb2015-10-09 10:53:31 +02002560 goto read_error;
Christopher Faulet31af49d2015-06-09 17:29:50 +02002561 }
Christopher Faulet31af49d2015-06-09 17:29:50 +02002562
Christopher Fauletc6f02fb2015-10-09 10:53:31 +02002563 fclose (fp);
Christopher Faulet31af49d2015-06-09 17:29:50 +02002564 bind_conf->ca_sign_cert = cacert;
2565 bind_conf->ca_sign_pkey = capkey;
2566 return err;
2567
Christopher Fauletc6f02fb2015-10-09 10:53:31 +02002568 read_error:
2569 fclose (fp);
Christopher Faulet31af49d2015-06-09 17:29:50 +02002570 if (capkey) EVP_PKEY_free(capkey);
2571 if (cacert) X509_free(cacert);
Christopher Fauletc6f02fb2015-10-09 10:53:31 +02002572 load_error:
2573 bind_conf->generate_certs = 0;
2574 err++;
Christopher Faulet31af49d2015-06-09 17:29:50 +02002575 return err;
2576}
2577
2578/* Release CA cert and private key used to generate certificated */
2579void
2580ssl_sock_free_ca(struct bind_conf *bind_conf)
2581{
2582 if (!bind_conf)
2583 return;
2584
2585 if (bind_conf->ca_sign_pkey)
2586 EVP_PKEY_free(bind_conf->ca_sign_pkey);
2587 if (bind_conf->ca_sign_cert)
2588 X509_free(bind_conf->ca_sign_cert);
2589}
2590
Emeric Brun46591952012-05-18 15:47:34 +02002591/*
2592 * This function is called if SSL * context is not yet allocated. The function
2593 * is designed to be called before any other data-layer operation and sets the
2594 * handshake flag on the connection. It is safe to call it multiple times.
2595 * It returns 0 on success and -1 in error case.
2596 */
2597static int ssl_sock_init(struct connection *conn)
2598{
2599 /* already initialized */
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02002600 if (conn->xprt_ctx)
Emeric Brun46591952012-05-18 15:47:34 +02002601 return 0;
2602
Willy Tarreau3c728722014-01-23 13:50:42 +01002603 if (!conn_ctrl_ready(conn))
Willy Tarreauf79c8172013-10-21 16:30:56 +02002604 return 0;
2605
Willy Tarreau20879a02012-12-03 16:32:10 +01002606 if (global.maxsslconn && sslconns >= global.maxsslconn) {
2607 conn->err_code = CO_ER_SSL_TOO_MANY;
Willy Tarreau403edff2012-09-06 11:58:37 +02002608 return -1;
Willy Tarreau20879a02012-12-03 16:32:10 +01002609 }
Willy Tarreau403edff2012-09-06 11:58:37 +02002610
Emeric Brun46591952012-05-18 15:47:34 +02002611 /* If it is in client mode initiate SSL session
2612 in connect state otherwise accept state */
Willy Tarreau3fdb3662012-11-12 00:42:33 +01002613 if (objt_server(conn->target)) {
Willy Tarreaufba03cd2014-11-13 13:48:58 +01002614 int may_retry = 1;
2615
2616 retry_connect:
Emeric Brun46591952012-05-18 15:47:34 +02002617 /* Alloc a new SSL session ctx */
Willy Tarreau3fdb3662012-11-12 00:42:33 +01002618 conn->xprt_ctx = SSL_new(objt_server(conn->target)->ssl_ctx.ctx);
Willy Tarreau20879a02012-12-03 16:32:10 +01002619 if (!conn->xprt_ctx) {
Willy Tarreaufba03cd2014-11-13 13:48:58 +01002620 if (may_retry--) {
2621 pool_gc2();
2622 goto retry_connect;
2623 }
Willy Tarreau20879a02012-12-03 16:32:10 +01002624 conn->err_code = CO_ER_SSL_NO_MEM;
Emeric Brun46591952012-05-18 15:47:34 +02002625 return -1;
Willy Tarreau20879a02012-12-03 16:32:10 +01002626 }
Emeric Brun46591952012-05-18 15:47:34 +02002627
Emeric Brun46591952012-05-18 15:47:34 +02002628 /* set fd on SSL session context */
Emeric Brun55476152014-11-12 17:35:37 +01002629 if (!SSL_set_fd(conn->xprt_ctx, conn->t.sock.fd)) {
2630 SSL_free(conn->xprt_ctx);
2631 conn->xprt_ctx = NULL;
Willy Tarreaufba03cd2014-11-13 13:48:58 +01002632 if (may_retry--) {
2633 pool_gc2();
2634 goto retry_connect;
2635 }
Emeric Brun55476152014-11-12 17:35:37 +01002636 conn->err_code = CO_ER_SSL_NO_MEM;
2637 return -1;
2638 }
Emeric Brun46591952012-05-18 15:47:34 +02002639
Evan Broderbe554312013-06-27 00:05:25 -07002640 /* set connection pointer */
Emeric Brun55476152014-11-12 17:35:37 +01002641 if (!SSL_set_app_data(conn->xprt_ctx, conn)) {
2642 SSL_free(conn->xprt_ctx);
2643 conn->xprt_ctx = NULL;
Willy Tarreaufba03cd2014-11-13 13:48:58 +01002644 if (may_retry--) {
2645 pool_gc2();
2646 goto retry_connect;
2647 }
Emeric Brun55476152014-11-12 17:35:37 +01002648 conn->err_code = CO_ER_SSL_NO_MEM;
2649 return -1;
2650 }
2651
2652 SSL_set_connect_state(conn->xprt_ctx);
2653 if (objt_server(conn->target)->ssl_ctx.reused_sess) {
2654 if(!SSL_set_session(conn->xprt_ctx, objt_server(conn->target)->ssl_ctx.reused_sess)) {
2655 SSL_SESSION_free(objt_server(conn->target)->ssl_ctx.reused_sess);
2656 objt_server(conn->target)->ssl_ctx.reused_sess = NULL;
2657 }
2658 }
Evan Broderbe554312013-06-27 00:05:25 -07002659
Emeric Brun46591952012-05-18 15:47:34 +02002660 /* leave init state and start handshake */
Willy Tarreau05737472012-09-04 08:03:39 +02002661 conn->flags |= CO_FL_SSL_WAIT_HS | CO_FL_WAIT_L6_CONN;
Willy Tarreau403edff2012-09-06 11:58:37 +02002662
2663 sslconns++;
Willy Tarreau71b734c2014-01-28 15:19:44 +01002664 totalsslconns++;
Emeric Brun46591952012-05-18 15:47:34 +02002665 return 0;
2666 }
Willy Tarreau3fdb3662012-11-12 00:42:33 +01002667 else if (objt_listener(conn->target)) {
Willy Tarreaufba03cd2014-11-13 13:48:58 +01002668 int may_retry = 1;
2669
2670 retry_accept:
Emeric Brun46591952012-05-18 15:47:34 +02002671 /* Alloc a new SSL session ctx */
Willy Tarreau3fdb3662012-11-12 00:42:33 +01002672 conn->xprt_ctx = SSL_new(objt_listener(conn->target)->bind_conf->default_ctx);
Willy Tarreau20879a02012-12-03 16:32:10 +01002673 if (!conn->xprt_ctx) {
Willy Tarreaufba03cd2014-11-13 13:48:58 +01002674 if (may_retry--) {
2675 pool_gc2();
2676 goto retry_accept;
2677 }
Willy Tarreau20879a02012-12-03 16:32:10 +01002678 conn->err_code = CO_ER_SSL_NO_MEM;
Emeric Brun46591952012-05-18 15:47:34 +02002679 return -1;
Willy Tarreau20879a02012-12-03 16:32:10 +01002680 }
Emeric Brun46591952012-05-18 15:47:34 +02002681
Emeric Brun46591952012-05-18 15:47:34 +02002682 /* set fd on SSL session context */
Emeric Brun55476152014-11-12 17:35:37 +01002683 if (!SSL_set_fd(conn->xprt_ctx, conn->t.sock.fd)) {
2684 SSL_free(conn->xprt_ctx);
2685 conn->xprt_ctx = NULL;
Willy Tarreaufba03cd2014-11-13 13:48:58 +01002686 if (may_retry--) {
2687 pool_gc2();
2688 goto retry_accept;
2689 }
Emeric Brun55476152014-11-12 17:35:37 +01002690 conn->err_code = CO_ER_SSL_NO_MEM;
2691 return -1;
2692 }
Emeric Brun46591952012-05-18 15:47:34 +02002693
Emeric Brune1f38db2012-09-03 20:36:47 +02002694 /* set connection pointer */
Emeric Brun55476152014-11-12 17:35:37 +01002695 if (!SSL_set_app_data(conn->xprt_ctx, conn)) {
2696 SSL_free(conn->xprt_ctx);
2697 conn->xprt_ctx = NULL;
Willy Tarreaufba03cd2014-11-13 13:48:58 +01002698 if (may_retry--) {
2699 pool_gc2();
2700 goto retry_accept;
2701 }
Emeric Brun55476152014-11-12 17:35:37 +01002702 conn->err_code = CO_ER_SSL_NO_MEM;
2703 return -1;
2704 }
2705
2706 SSL_set_accept_state(conn->xprt_ctx);
Emeric Brune1f38db2012-09-03 20:36:47 +02002707
Emeric Brun46591952012-05-18 15:47:34 +02002708 /* leave init state and start handshake */
Willy Tarreau05737472012-09-04 08:03:39 +02002709 conn->flags |= CO_FL_SSL_WAIT_HS | CO_FL_WAIT_L6_CONN;
Willy Tarreau403edff2012-09-06 11:58:37 +02002710
2711 sslconns++;
Willy Tarreau71b734c2014-01-28 15:19:44 +01002712 totalsslconns++;
Emeric Brun46591952012-05-18 15:47:34 +02002713 return 0;
2714 }
2715 /* don't know how to handle such a target */
Willy Tarreau20879a02012-12-03 16:32:10 +01002716 conn->err_code = CO_ER_SSL_NO_TARGET;
Emeric Brun46591952012-05-18 15:47:34 +02002717 return -1;
2718}
2719
2720
2721/* This is the callback which is used when an SSL handshake is pending. It
2722 * updates the FD status if it wants some polling before being called again.
2723 * It returns 0 if it fails in a fatal way or needs to poll to go further,
2724 * otherwise it returns non-zero and removes itself from the connection's
2725 * flags (the bit is provided in <flag> by the caller).
2726 */
2727int ssl_sock_handshake(struct connection *conn, unsigned int flag)
2728{
2729 int ret;
2730
Willy Tarreau3c728722014-01-23 13:50:42 +01002731 if (!conn_ctrl_ready(conn))
Willy Tarreauf79c8172013-10-21 16:30:56 +02002732 return 0;
2733
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02002734 if (!conn->xprt_ctx)
Emeric Brun46591952012-05-18 15:47:34 +02002735 goto out_error;
2736
Emeric Brun674b7432012-11-08 19:21:55 +01002737 /* If we use SSL_do_handshake to process a reneg initiated by
2738 * the remote peer, it sometimes returns SSL_ERROR_SSL.
2739 * Usually SSL_write and SSL_read are used and process implicitly
2740 * the reneg handshake.
2741 * Here we use SSL_peek as a workaround for reneg.
2742 */
2743 if ((conn->flags & CO_FL_CONNECTED) && SSL_renegotiate_pending(conn->xprt_ctx)) {
2744 char c;
2745
2746 ret = SSL_peek(conn->xprt_ctx, &c, 1);
2747 if (ret <= 0) {
2748 /* handshake may have not been completed, let's find why */
2749 ret = SSL_get_error(conn->xprt_ctx, ret);
2750 if (ret == SSL_ERROR_WANT_WRITE) {
2751 /* SSL handshake needs to write, L4 connection may not be ready */
2752 __conn_sock_stop_recv(conn);
Willy Tarreaue1f50c42014-01-22 20:02:06 +01002753 __conn_sock_want_send(conn);
2754 fd_cant_send(conn->t.sock.fd);
Emeric Brun674b7432012-11-08 19:21:55 +01002755 return 0;
2756 }
2757 else if (ret == SSL_ERROR_WANT_READ) {
2758 /* handshake may have been completed but we have
2759 * no more data to read.
2760 */
2761 if (!SSL_renegotiate_pending(conn->xprt_ctx)) {
2762 ret = 1;
2763 goto reneg_ok;
2764 }
2765 /* SSL handshake needs to read, L4 connection is ready */
2766 if (conn->flags & CO_FL_WAIT_L4_CONN)
2767 conn->flags &= ~CO_FL_WAIT_L4_CONN;
2768 __conn_sock_stop_send(conn);
Willy Tarreaue1f50c42014-01-22 20:02:06 +01002769 __conn_sock_want_recv(conn);
2770 fd_cant_recv(conn->t.sock.fd);
Emeric Brun674b7432012-11-08 19:21:55 +01002771 return 0;
2772 }
2773 else if (ret == SSL_ERROR_SYSCALL) {
2774 /* if errno is null, then connection was successfully established */
2775 if (!errno && conn->flags & CO_FL_WAIT_L4_CONN)
2776 conn->flags &= ~CO_FL_WAIT_L4_CONN;
Willy Tarreau20879a02012-12-03 16:32:10 +01002777 if (!conn->err_code) {
Emeric Brun29f037d2014-04-25 19:05:36 +02002778 if (!((SSL *)conn->xprt_ctx)->packet_length) {
2779 if (!errno) {
2780 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
2781 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
2782 else
2783 conn->err_code = CO_ER_SSL_EMPTY;
2784 }
2785 else {
2786 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
2787 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
2788 else
2789 conn->err_code = CO_ER_SSL_ABORT;
2790 }
2791 }
2792 else {
2793 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
2794 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
Willy Tarreau20879a02012-12-03 16:32:10 +01002795 else
Emeric Brun29f037d2014-04-25 19:05:36 +02002796 conn->err_code = CO_ER_SSL_HANDSHAKE;
2797 }
Willy Tarreau20879a02012-12-03 16:32:10 +01002798 }
Emeric Brun674b7432012-11-08 19:21:55 +01002799 goto out_error;
2800 }
2801 else {
2802 /* Fail on all other handshake errors */
2803 /* Note: OpenSSL may leave unread bytes in the socket's
2804 * buffer, causing an RST to be emitted upon close() on
2805 * TCP sockets. We first try to drain possibly pending
2806 * data to avoid this as much as possible.
2807 */
Willy Tarreaud85c4852015-03-13 00:40:28 +01002808 conn_sock_drain(conn);
Willy Tarreau20879a02012-12-03 16:32:10 +01002809 if (!conn->err_code)
Willy Tarreauf51c6982014-04-25 20:02:39 +02002810 conn->err_code = (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT) ?
2811 CO_ER_SSL_KILLED_HB : CO_ER_SSL_HANDSHAKE;
Emeric Brun674b7432012-11-08 19:21:55 +01002812 goto out_error;
2813 }
2814 }
2815 /* read some data: consider handshake completed */
2816 goto reneg_ok;
2817 }
2818
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02002819 ret = SSL_do_handshake(conn->xprt_ctx);
Emeric Brun46591952012-05-18 15:47:34 +02002820 if (ret != 1) {
2821 /* handshake did not complete, let's find why */
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02002822 ret = SSL_get_error(conn->xprt_ctx, ret);
Emeric Brun46591952012-05-18 15:47:34 +02002823
2824 if (ret == SSL_ERROR_WANT_WRITE) {
2825 /* SSL handshake needs to write, L4 connection may not be ready */
2826 __conn_sock_stop_recv(conn);
Willy Tarreaue1f50c42014-01-22 20:02:06 +01002827 __conn_sock_want_send(conn);
2828 fd_cant_send(conn->t.sock.fd);
Emeric Brun46591952012-05-18 15:47:34 +02002829 return 0;
2830 }
2831 else if (ret == SSL_ERROR_WANT_READ) {
2832 /* SSL handshake needs to read, L4 connection is ready */
2833 if (conn->flags & CO_FL_WAIT_L4_CONN)
2834 conn->flags &= ~CO_FL_WAIT_L4_CONN;
2835 __conn_sock_stop_send(conn);
Willy Tarreaue1f50c42014-01-22 20:02:06 +01002836 __conn_sock_want_recv(conn);
2837 fd_cant_recv(conn->t.sock.fd);
Emeric Brun46591952012-05-18 15:47:34 +02002838 return 0;
2839 }
Willy Tarreau89230192012-09-28 20:22:13 +02002840 else if (ret == SSL_ERROR_SYSCALL) {
2841 /* if errno is null, then connection was successfully established */
2842 if (!errno && conn->flags & CO_FL_WAIT_L4_CONN)
2843 conn->flags &= ~CO_FL_WAIT_L4_CONN;
Willy Tarreau20879a02012-12-03 16:32:10 +01002844
Emeric Brun29f037d2014-04-25 19:05:36 +02002845 if (!((SSL *)conn->xprt_ctx)->packet_length) {
2846 if (!errno) {
2847 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
2848 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
2849 else
2850 conn->err_code = CO_ER_SSL_EMPTY;
2851 }
2852 else {
2853 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
2854 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
2855 else
2856 conn->err_code = CO_ER_SSL_ABORT;
2857 }
2858 }
2859 else {
2860 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
2861 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
Willy Tarreau20879a02012-12-03 16:32:10 +01002862 else
Emeric Brun29f037d2014-04-25 19:05:36 +02002863 conn->err_code = CO_ER_SSL_HANDSHAKE;
2864 }
Willy Tarreau89230192012-09-28 20:22:13 +02002865 goto out_error;
2866 }
Emeric Brun46591952012-05-18 15:47:34 +02002867 else {
2868 /* Fail on all other handshake errors */
Willy Tarreau566dc552012-10-19 20:52:18 +02002869 /* Note: OpenSSL may leave unread bytes in the socket's
2870 * buffer, causing an RST to be emitted upon close() on
2871 * TCP sockets. We first try to drain possibly pending
2872 * data to avoid this as much as possible.
2873 */
Willy Tarreaud85c4852015-03-13 00:40:28 +01002874 conn_sock_drain(conn);
Willy Tarreau20879a02012-12-03 16:32:10 +01002875 if (!conn->err_code)
Willy Tarreauf51c6982014-04-25 20:02:39 +02002876 conn->err_code = (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT) ?
2877 CO_ER_SSL_KILLED_HB : CO_ER_SSL_HANDSHAKE;
Emeric Brun46591952012-05-18 15:47:34 +02002878 goto out_error;
2879 }
2880 }
2881
Emeric Brun674b7432012-11-08 19:21:55 +01002882reneg_ok:
Emeric Brun46591952012-05-18 15:47:34 +02002883 /* Handshake succeeded */
Willy Tarreau0c9c2722014-05-28 12:28:58 +02002884 if (!SSL_session_reused(conn->xprt_ctx)) {
2885 if (objt_server(conn->target)) {
2886 update_freq_ctr(&global.ssl_be_keys_per_sec, 1);
2887 if (global.ssl_be_keys_per_sec.curr_ctr > global.ssl_be_keys_max)
2888 global.ssl_be_keys_max = global.ssl_be_keys_per_sec.curr_ctr;
2889
Emeric Brun46591952012-05-18 15:47:34 +02002890 /* check if session was reused, if not store current session on server for reuse */
Willy Tarreau3fdb3662012-11-12 00:42:33 +01002891 if (objt_server(conn->target)->ssl_ctx.reused_sess)
2892 SSL_SESSION_free(objt_server(conn->target)->ssl_ctx.reused_sess);
Emeric Brun46591952012-05-18 15:47:34 +02002893
Willy Tarreau2a3fb1c2015-02-05 16:47:07 +01002894 if (!(objt_server(conn->target)->ssl_ctx.options & SRV_SSL_O_NO_REUSE))
2895 objt_server(conn->target)->ssl_ctx.reused_sess = SSL_get1_session(conn->xprt_ctx);
Emeric Brun46591952012-05-18 15:47:34 +02002896 }
Willy Tarreau0c9c2722014-05-28 12:28:58 +02002897 else {
2898 update_freq_ctr(&global.ssl_fe_keys_per_sec, 1);
2899 if (global.ssl_fe_keys_per_sec.curr_ctr > global.ssl_fe_keys_max)
2900 global.ssl_fe_keys_max = global.ssl_fe_keys_per_sec.curr_ctr;
2901 }
Emeric Brun46591952012-05-18 15:47:34 +02002902 }
2903
2904 /* The connection is now established at both layers, it's time to leave */
2905 conn->flags &= ~(flag | CO_FL_WAIT_L4_CONN | CO_FL_WAIT_L6_CONN);
2906 return 1;
2907
2908 out_error:
Emeric Brun644cde02012-12-14 11:21:13 +01002909 /* Clear openssl global errors stack */
2910 ERR_clear_error();
2911
Emeric Brun9fa89732012-10-04 17:09:56 +02002912 /* free resumed session if exists */
Willy Tarreau3fdb3662012-11-12 00:42:33 +01002913 if (objt_server(conn->target) && objt_server(conn->target)->ssl_ctx.reused_sess) {
2914 SSL_SESSION_free(objt_server(conn->target)->ssl_ctx.reused_sess);
2915 objt_server(conn->target)->ssl_ctx.reused_sess = NULL;
Emeric Brun9fa89732012-10-04 17:09:56 +02002916 }
2917
Emeric Brun46591952012-05-18 15:47:34 +02002918 /* Fail on all other handshake errors */
2919 conn->flags |= CO_FL_ERROR;
Willy Tarreau20879a02012-12-03 16:32:10 +01002920 if (!conn->err_code)
2921 conn->err_code = CO_ER_SSL_HANDSHAKE;
Emeric Brun46591952012-05-18 15:47:34 +02002922 return 0;
2923}
2924
2925/* Receive up to <count> bytes from connection <conn>'s socket and store them
Willy Tarreauabf08d92014-01-14 11:31:27 +01002926 * into buffer <buf>. Only one call to recv() is performed, unless the
Emeric Brun46591952012-05-18 15:47:34 +02002927 * buffer wraps, in which case a second call may be performed. The connection's
2928 * flags are updated with whatever special event is detected (error, read0,
2929 * empty). The caller is responsible for taking care of those events and
2930 * avoiding the call if inappropriate. The function does not call the
2931 * connection's polling update function, so the caller is responsible for this.
2932 */
2933static int ssl_sock_to_buf(struct connection *conn, struct buffer *buf, int count)
2934{
2935 int ret, done = 0;
Willy Tarreauabf08d92014-01-14 11:31:27 +01002936 int try;
Emeric Brun46591952012-05-18 15:47:34 +02002937
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02002938 if (!conn->xprt_ctx)
Emeric Brun46591952012-05-18 15:47:34 +02002939 goto out_error;
2940
2941 if (conn->flags & CO_FL_HANDSHAKE)
2942 /* a handshake was requested */
2943 return 0;
2944
Willy Tarreauabf08d92014-01-14 11:31:27 +01002945 /* let's realign the buffer to optimize I/O */
2946 if (buffer_empty(buf))
Emeric Brun46591952012-05-18 15:47:34 +02002947 buf->p = buf->data;
Emeric Brun46591952012-05-18 15:47:34 +02002948
2949 /* read the largest possible block. For this, we perform only one call
2950 * to recv() unless the buffer wraps and we exactly fill the first hunk,
2951 * in which case we accept to do it once again. A new attempt is made on
2952 * EINTR too.
2953 */
Willy Tarreau00b0fb92014-01-17 11:09:40 +01002954 while (count > 0) {
Willy Tarreauabf08d92014-01-14 11:31:27 +01002955 /* first check if we have some room after p+i */
2956 try = buf->data + buf->size - (buf->p + buf->i);
2957 /* otherwise continue between data and p-o */
2958 if (try <= 0) {
2959 try = buf->p - (buf->data + buf->o);
2960 if (try <= 0)
2961 break;
2962 }
2963 if (try > count)
2964 try = count;
2965
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02002966 ret = SSL_read(conn->xprt_ctx, bi_end(buf), try);
Emeric Brune1f38db2012-09-03 20:36:47 +02002967 if (conn->flags & CO_FL_ERROR) {
2968 /* CO_FL_ERROR may be set by ssl_sock_infocbk */
Emeric Brun644cde02012-12-14 11:21:13 +01002969 goto out_error;
Emeric Brune1f38db2012-09-03 20:36:47 +02002970 }
Emeric Brun46591952012-05-18 15:47:34 +02002971 if (ret > 0) {
2972 buf->i += ret;
2973 done += ret;
2974 if (ret < try)
2975 break;
2976 count -= ret;
Emeric Brun46591952012-05-18 15:47:34 +02002977 }
2978 else if (ret == 0) {
Emeric Brun644cde02012-12-14 11:21:13 +01002979 ret = SSL_get_error(conn->xprt_ctx, ret);
2980 if (ret != SSL_ERROR_ZERO_RETURN) {
Emeric Brun1c646862012-12-14 12:33:41 +01002981 /* error on protocol or underlying transport */
2982 if ((ret != SSL_ERROR_SYSCALL)
2983 || (errno && (errno != EAGAIN)))
2984 conn->flags |= CO_FL_ERROR;
2985
Emeric Brun644cde02012-12-14 11:21:13 +01002986 /* Clear openssl global errors stack */
2987 ERR_clear_error();
2988 }
Emeric Brun46591952012-05-18 15:47:34 +02002989 goto read0;
2990 }
2991 else {
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02002992 ret = SSL_get_error(conn->xprt_ctx, ret);
Emeric Brun46591952012-05-18 15:47:34 +02002993 if (ret == SSL_ERROR_WANT_WRITE) {
Emeric Brun8af8dd12012-11-08 17:56:20 +01002994 /* handshake is running, and it needs to enable write */
Emeric Brun46591952012-05-18 15:47:34 +02002995 conn->flags |= CO_FL_SSL_WAIT_HS;
Emeric Brun8af8dd12012-11-08 17:56:20 +01002996 __conn_sock_want_send(conn);
Emeric Brun46591952012-05-18 15:47:34 +02002997 break;
2998 }
2999 else if (ret == SSL_ERROR_WANT_READ) {
Emeric Brun282a76a2012-11-08 18:02:56 +01003000 if (SSL_renegotiate_pending(conn->xprt_ctx)) {
3001 /* handshake is running, and it may need to re-enable read */
3002 conn->flags |= CO_FL_SSL_WAIT_HS;
3003 __conn_sock_want_recv(conn);
3004 break;
3005 }
Emeric Brun46591952012-05-18 15:47:34 +02003006 /* we need to poll for retry a read later */
Willy Tarreaue1f50c42014-01-22 20:02:06 +01003007 fd_cant_recv(conn->t.sock.fd);
Emeric Brun46591952012-05-18 15:47:34 +02003008 break;
3009 }
3010 /* otherwise it's a real error */
3011 goto out_error;
3012 }
3013 }
3014 return done;
3015
3016 read0:
3017 conn_sock_read0(conn);
3018 return done;
3019 out_error:
Emeric Brun644cde02012-12-14 11:21:13 +01003020 /* Clear openssl global errors stack */
3021 ERR_clear_error();
3022
Emeric Brun46591952012-05-18 15:47:34 +02003023 conn->flags |= CO_FL_ERROR;
3024 return done;
3025}
3026
3027
3028/* Send all pending bytes from buffer <buf> to connection <conn>'s socket.
Willy Tarreau1049b1f2014-02-02 01:51:17 +01003029 * <flags> may contain some CO_SFL_* flags to hint the system about other
3030 * pending data for example, but this flag is ignored at the moment.
Emeric Brun46591952012-05-18 15:47:34 +02003031 * Only one call to send() is performed, unless the buffer wraps, in which case
3032 * a second call may be performed. The connection's flags are updated with
3033 * whatever special event is detected (error, empty). The caller is responsible
3034 * for taking care of those events and avoiding the call if inappropriate. The
3035 * function does not call the connection's polling update function, so the caller
3036 * is responsible for this.
3037 */
3038static int ssl_sock_from_buf(struct connection *conn, struct buffer *buf, int flags)
3039{
3040 int ret, try, done;
3041
3042 done = 0;
3043
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02003044 if (!conn->xprt_ctx)
Emeric Brun46591952012-05-18 15:47:34 +02003045 goto out_error;
3046
3047 if (conn->flags & CO_FL_HANDSHAKE)
3048 /* a handshake was requested */
3049 return 0;
3050
3051 /* send the largest possible block. For this we perform only one call
3052 * to send() unless the buffer wraps and we exactly fill the first hunk,
3053 * in which case we accept to do it once again.
3054 */
3055 while (buf->o) {
Kevin Hestercad82342013-05-30 15:12:41 -07003056 try = bo_contig_data(buf);
Willy Tarreaubfd59462013-02-21 07:46:09 +01003057
Willy Tarreau7bed9452014-02-02 02:00:24 +01003058 if (!(flags & CO_SFL_STREAMER) &&
Willy Tarreau518cedd2014-02-17 15:43:01 +01003059 !(conn->xprt_st & SSL_SOCK_SEND_UNLIMITED) &&
3060 global.tune.ssl_max_record && try > global.tune.ssl_max_record) {
Willy Tarreaubfd59462013-02-21 07:46:09 +01003061 try = global.tune.ssl_max_record;
Willy Tarreau518cedd2014-02-17 15:43:01 +01003062 }
3063 else {
3064 /* we need to keep the information about the fact that
3065 * we're not limiting the upcoming send(), because if it
3066 * fails, we'll have to retry with at least as many data.
3067 */
3068 conn->xprt_st |= SSL_SOCK_SEND_UNLIMITED;
3069 }
Willy Tarreaubfd59462013-02-21 07:46:09 +01003070
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02003071 ret = SSL_write(conn->xprt_ctx, bo_ptr(buf), try);
Willy Tarreau518cedd2014-02-17 15:43:01 +01003072
Emeric Brune1f38db2012-09-03 20:36:47 +02003073 if (conn->flags & CO_FL_ERROR) {
3074 /* CO_FL_ERROR may be set by ssl_sock_infocbk */
Emeric Brun644cde02012-12-14 11:21:13 +01003075 goto out_error;
Emeric Brune1f38db2012-09-03 20:36:47 +02003076 }
Emeric Brun46591952012-05-18 15:47:34 +02003077 if (ret > 0) {
Willy Tarreau518cedd2014-02-17 15:43:01 +01003078 conn->xprt_st &= ~SSL_SOCK_SEND_UNLIMITED;
3079
Emeric Brun46591952012-05-18 15:47:34 +02003080 buf->o -= ret;
3081 done += ret;
3082
Willy Tarreau5fb38032012-12-16 19:39:09 +01003083 if (likely(buffer_empty(buf)))
Emeric Brun46591952012-05-18 15:47:34 +02003084 /* optimize data alignment in the buffer */
3085 buf->p = buf->data;
3086
3087 /* if the system buffer is full, don't insist */
3088 if (ret < try)
3089 break;
3090 }
3091 else {
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02003092 ret = SSL_get_error(conn->xprt_ctx, ret);
Emeric Brun46591952012-05-18 15:47:34 +02003093 if (ret == SSL_ERROR_WANT_WRITE) {
Emeric Brun282a76a2012-11-08 18:02:56 +01003094 if (SSL_renegotiate_pending(conn->xprt_ctx)) {
3095 /* handshake is running, and it may need to re-enable write */
3096 conn->flags |= CO_FL_SSL_WAIT_HS;
3097 __conn_sock_want_send(conn);
3098 break;
3099 }
Emeric Brun46591952012-05-18 15:47:34 +02003100 /* we need to poll to retry a write later */
Willy Tarreaue1f50c42014-01-22 20:02:06 +01003101 fd_cant_send(conn->t.sock.fd);
Emeric Brun46591952012-05-18 15:47:34 +02003102 break;
3103 }
3104 else if (ret == SSL_ERROR_WANT_READ) {
Emeric Brun8af8dd12012-11-08 17:56:20 +01003105 /* handshake is running, and it needs to enable read */
Emeric Brun46591952012-05-18 15:47:34 +02003106 conn->flags |= CO_FL_SSL_WAIT_HS;
Emeric Brun8af8dd12012-11-08 17:56:20 +01003107 __conn_sock_want_recv(conn);
Emeric Brun46591952012-05-18 15:47:34 +02003108 break;
3109 }
3110 goto out_error;
3111 }
3112 }
3113 return done;
3114
3115 out_error:
Emeric Brun644cde02012-12-14 11:21:13 +01003116 /* Clear openssl global errors stack */
3117 ERR_clear_error();
3118
Emeric Brun46591952012-05-18 15:47:34 +02003119 conn->flags |= CO_FL_ERROR;
3120 return done;
3121}
3122
Emeric Brun46591952012-05-18 15:47:34 +02003123static void ssl_sock_close(struct connection *conn) {
3124
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02003125 if (conn->xprt_ctx) {
Willy Tarreaua84c2672015-10-09 12:10:13 +02003126#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Christopher Fauletd2cab922015-07-28 16:03:47 +02003127 if (!ssl_ctx_lru_tree && objt_listener(conn->target)) {
3128 SSL_CTX *ctx = SSL_get_SSL_CTX(conn->xprt_ctx);
3129 if (ctx != objt_listener(conn->target)->bind_conf->default_ctx)
3130 SSL_CTX_free(ctx);
3131 }
Willy Tarreaua84c2672015-10-09 12:10:13 +02003132#endif
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02003133 SSL_free(conn->xprt_ctx);
3134 conn->xprt_ctx = NULL;
Willy Tarreau403edff2012-09-06 11:58:37 +02003135 sslconns--;
Emeric Brun46591952012-05-18 15:47:34 +02003136 }
Emeric Brun46591952012-05-18 15:47:34 +02003137}
3138
3139/* This function tries to perform a clean shutdown on an SSL connection, and in
3140 * any case, flags the connection as reusable if no handshake was in progress.
3141 */
3142static void ssl_sock_shutw(struct connection *conn, int clean)
3143{
3144 if (conn->flags & CO_FL_HANDSHAKE)
3145 return;
3146 /* no handshake was in progress, try a clean ssl shutdown */
Emeric Brun644cde02012-12-14 11:21:13 +01003147 if (clean && (SSL_shutdown(conn->xprt_ctx) <= 0)) {
3148 /* Clear openssl global errors stack */
3149 ERR_clear_error();
3150 }
Emeric Brun46591952012-05-18 15:47:34 +02003151
3152 /* force flag on ssl to keep session in cache regardless shutdown result */
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02003153 SSL_set_shutdown(conn->xprt_ctx, SSL_SENT_SHUTDOWN);
Emeric Brun46591952012-05-18 15:47:34 +02003154}
3155
Willy Tarreauffc3fcd2012-10-12 20:17:54 +02003156/* used for logging, may be changed for a sample fetch later */
3157const char *ssl_sock_get_cipher_name(struct connection *conn)
3158{
3159 if (!conn->xprt && !conn->xprt_ctx)
3160 return NULL;
3161 return SSL_get_cipher_name(conn->xprt_ctx);
3162}
3163
3164/* used for logging, may be changed for a sample fetch later */
3165const char *ssl_sock_get_proto_version(struct connection *conn)
3166{
3167 if (!conn->xprt && !conn->xprt_ctx)
3168 return NULL;
3169 return SSL_get_version(conn->xprt_ctx);
3170}
3171
Willy Tarreau8d598402012-10-22 17:58:39 +02003172/* Extract a serial from a cert, and copy it to a chunk.
3173 * Returns 1 if serial is found and copied, 0 if no serial found and
3174 * -1 if output is not large enough.
3175 */
3176static int
3177ssl_sock_get_serial(X509 *crt, struct chunk *out)
3178{
3179 ASN1_INTEGER *serial;
3180
3181 serial = X509_get_serialNumber(crt);
3182 if (!serial)
3183 return 0;
3184
3185 if (out->size < serial->length)
3186 return -1;
3187
3188 memcpy(out->str, serial->data, serial->length);
3189 out->len = serial->length;
3190 return 1;
3191}
3192
Emeric Brun43e79582014-10-29 19:03:26 +01003193/* Extract a cert to der, and copy it to a chunk.
3194 * Returns 1 if cert is found and copied, 0 on der convertion failure and
3195 * -1 if output is not large enough.
3196 */
3197static int
3198ssl_sock_crt2der(X509 *crt, struct chunk *out)
3199{
3200 int len;
3201 unsigned char *p = (unsigned char *)out->str;;
3202
3203 len =i2d_X509(crt, NULL);
3204 if (len <= 0)
3205 return 1;
3206
3207 if (out->size < len)
3208 return -1;
3209
3210 i2d_X509(crt,&p);
3211 out->len = len;
3212 return 1;
3213}
3214
Emeric Brunce5ad802012-10-22 14:11:22 +02003215
3216/* Copy Date in ASN1_UTCTIME format in struct chunk out.
3217 * Returns 1 if serial is found and copied, 0 if no valid time found
3218 * and -1 if output is not large enough.
3219 */
3220static int
3221ssl_sock_get_time(ASN1_TIME *tm, struct chunk *out)
3222{
3223 if (tm->type == V_ASN1_GENERALIZEDTIME) {
3224 ASN1_GENERALIZEDTIME *gentm = (ASN1_GENERALIZEDTIME *)tm;
3225
3226 if (gentm->length < 12)
3227 return 0;
3228 if (gentm->data[0] != 0x32 || gentm->data[1] != 0x30)
3229 return 0;
3230 if (out->size < gentm->length-2)
3231 return -1;
3232
3233 memcpy(out->str, gentm->data+2, gentm->length-2);
3234 out->len = gentm->length-2;
3235 return 1;
3236 }
3237 else if (tm->type == V_ASN1_UTCTIME) {
3238 ASN1_UTCTIME *utctm = (ASN1_UTCTIME *)tm;
3239
3240 if (utctm->length < 10)
3241 return 0;
3242 if (utctm->data[0] >= 0x35)
3243 return 0;
3244 if (out->size < utctm->length)
3245 return -1;
3246
3247 memcpy(out->str, utctm->data, utctm->length);
3248 out->len = utctm->length;
3249 return 1;
3250 }
3251
3252 return 0;
3253}
3254
Emeric Brun87855892012-10-17 17:39:35 +02003255/* Extract an entry from a X509_NAME and copy its value to an output chunk.
3256 * Returns 1 if entry found, 0 if entry not found, or -1 if output not large enough.
3257 */
3258static int
3259ssl_sock_get_dn_entry(X509_NAME *a, const struct chunk *entry, int pos, struct chunk *out)
3260{
3261 X509_NAME_ENTRY *ne;
3262 int i, j, n;
3263 int cur = 0;
3264 const char *s;
3265 char tmp[128];
3266
3267 out->len = 0;
3268 for (i = 0; i < sk_X509_NAME_ENTRY_num(a->entries); i++) {
3269 if (pos < 0)
3270 j = (sk_X509_NAME_ENTRY_num(a->entries)-1) - i;
3271 else
3272 j = i;
3273
3274 ne = sk_X509_NAME_ENTRY_value(a->entries, j);
3275 n = OBJ_obj2nid(ne->object);
3276 if ((n == NID_undef) || ((s = OBJ_nid2sn(n)) == NULL)) {
3277 i2t_ASN1_OBJECT(tmp, sizeof(tmp), ne->object);
3278 s = tmp;
3279 }
3280
3281 if (chunk_strcasecmp(entry, s) != 0)
3282 continue;
3283
3284 if (pos < 0)
3285 cur--;
3286 else
3287 cur++;
3288
3289 if (cur != pos)
3290 continue;
3291
3292 if (ne->value->length > out->size)
3293 return -1;
3294
3295 memcpy(out->str, ne->value->data, ne->value->length);
3296 out->len = ne->value->length;
3297 return 1;
3298 }
3299
3300 return 0;
3301
3302}
3303
3304/* Extract and format full DN from a X509_NAME and copy result into a chunk
3305 * Returns 1 if dn entries exits, 0 if no dn entry found or -1 if output is not large enough.
3306 */
3307static int
3308ssl_sock_get_dn_oneline(X509_NAME *a, struct chunk *out)
3309{
3310 X509_NAME_ENTRY *ne;
3311 int i, n, ln;
3312 int l = 0;
3313 const char *s;
3314 char *p;
3315 char tmp[128];
3316
3317 out->len = 0;
3318 p = out->str;
3319 for (i = 0; i < sk_X509_NAME_ENTRY_num(a->entries); i++) {
3320 ne = sk_X509_NAME_ENTRY_value(a->entries, i);
3321 n = OBJ_obj2nid(ne->object);
3322 if ((n == NID_undef) || ((s = OBJ_nid2sn(n)) == NULL)) {
3323 i2t_ASN1_OBJECT(tmp, sizeof(tmp), ne->object);
3324 s = tmp;
3325 }
3326 ln = strlen(s);
3327
3328 l += 1 + ln + 1 + ne->value->length;
3329 if (l > out->size)
3330 return -1;
3331 out->len = l;
3332
3333 *(p++)='/';
3334 memcpy(p, s, ln);
3335 p += ln;
3336 *(p++)='=';
3337 memcpy(p, ne->value->data, ne->value->length);
3338 p += ne->value->length;
3339 }
3340
3341 if (!out->len)
3342 return 0;
3343
3344 return 1;
3345}
3346
David Safb76832014-05-08 23:42:08 -04003347char *ssl_sock_get_version(struct connection *conn)
3348{
3349 if (!ssl_sock_is_ssl(conn))
3350 return NULL;
3351
3352 return (char *)SSL_get_version(conn->xprt_ctx);
3353}
3354
Willy Tarreau63076412015-07-10 11:33:32 +02003355void ssl_sock_set_servername(struct connection *conn, const char *hostname)
3356{
3357#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
3358 if (!ssl_sock_is_ssl(conn))
3359 return;
3360
3361 SSL_set_tlsext_host_name(conn->xprt_ctx, hostname);
3362#endif
3363}
3364
Emeric Brun0abf8362014-06-24 18:26:41 +02003365/* Extract peer certificate's common name into the chunk dest
3366 * Returns
3367 * the len of the extracted common name
3368 * or 0 if no CN found in DN
3369 * or -1 on error case (i.e. no peer certificate)
3370 */
3371int ssl_sock_get_remote_common_name(struct connection *conn, struct chunk *dest)
David Safb76832014-05-08 23:42:08 -04003372{
3373 X509 *crt = NULL;
3374 X509_NAME *name;
David Safb76832014-05-08 23:42:08 -04003375 const char find_cn[] = "CN";
3376 const struct chunk find_cn_chunk = {
3377 .str = (char *)&find_cn,
3378 .len = sizeof(find_cn)-1
3379 };
Emeric Brun0abf8362014-06-24 18:26:41 +02003380 int result = -1;
David Safb76832014-05-08 23:42:08 -04003381
3382 if (!ssl_sock_is_ssl(conn))
Emeric Brun0abf8362014-06-24 18:26:41 +02003383 goto out;
David Safb76832014-05-08 23:42:08 -04003384
3385 /* SSL_get_peer_certificate, it increase X509 * ref count */
3386 crt = SSL_get_peer_certificate(conn->xprt_ctx);
3387 if (!crt)
3388 goto out;
3389
3390 name = X509_get_subject_name(crt);
3391 if (!name)
3392 goto out;
David Safb76832014-05-08 23:42:08 -04003393
Emeric Brun0abf8362014-06-24 18:26:41 +02003394 result = ssl_sock_get_dn_entry(name, &find_cn_chunk, 1, dest);
3395out:
David Safb76832014-05-08 23:42:08 -04003396 if (crt)
3397 X509_free(crt);
3398
3399 return result;
3400}
3401
Dave McCowan328fb582014-07-30 10:39:13 -04003402/* returns 1 if client passed a certificate for this session, 0 if not */
3403int ssl_sock_get_cert_used_sess(struct connection *conn)
3404{
3405 X509 *crt = NULL;
3406
3407 if (!ssl_sock_is_ssl(conn))
3408 return 0;
3409
3410 /* SSL_get_peer_certificate, it increase X509 * ref count */
3411 crt = SSL_get_peer_certificate(conn->xprt_ctx);
3412 if (!crt)
3413 return 0;
3414
3415 X509_free(crt);
3416 return 1;
3417}
3418
3419/* returns 1 if client passed a certificate for this connection, 0 if not */
3420int ssl_sock_get_cert_used_conn(struct connection *conn)
David Safb76832014-05-08 23:42:08 -04003421{
3422 if (!ssl_sock_is_ssl(conn))
3423 return 0;
3424
3425 return SSL_SOCK_ST_FL_VERIFY_DONE & conn->xprt_st ? 1 : 0;
3426}
3427
3428/* returns result from SSL verify */
3429unsigned int ssl_sock_get_verify_result(struct connection *conn)
3430{
3431 if (!ssl_sock_is_ssl(conn))
3432 return (unsigned int)X509_V_ERR_APPLICATION_VERIFICATION;
3433
3434 return (unsigned int)SSL_get_verify_result(conn->xprt_ctx);
3435}
3436
Willy Tarreau7875d092012-09-10 08:20:03 +02003437/***** Below are some sample fetching functions for ACL/patterns *****/
3438
Emeric Brune64aef12012-09-21 13:15:06 +02003439/* boolean, returns true if client cert was present */
3440static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02003441smp_fetch_ssl_fc_has_crt(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brune64aef12012-09-21 13:15:06 +02003442{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003443 struct connection *conn;
3444
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02003445 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003446 if (!conn || conn->xprt != &ssl_sock)
Emeric Brune64aef12012-09-21 13:15:06 +02003447 return 0;
3448
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003449 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brune64aef12012-09-21 13:15:06 +02003450 smp->flags |= SMP_F_MAY_CHANGE;
3451 return 0;
3452 }
3453
3454 smp->flags = 0;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02003455 smp->data.type = SMP_T_BOOL;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02003456 smp->data.u.sint = SSL_SOCK_ST_FL_VERIFY_DONE & conn->xprt_st ? 1 : 0;
Emeric Brune64aef12012-09-21 13:15:06 +02003457
3458 return 1;
3459}
3460
Emeric Brun43e79582014-10-29 19:03:26 +01003461/* binary, returns a certificate in a binary chunk (der/raw).
3462 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
3463 * should be use.
3464 */
3465static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02003466smp_fetch_ssl_x_der(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun43e79582014-10-29 19:03:26 +01003467{
3468 int cert_peer = (kw[4] == 'c') ? 1 : 0;
3469 X509 *crt = NULL;
3470 int ret = 0;
3471 struct chunk *smp_trash;
3472 struct connection *conn;
3473
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02003474 conn = objt_conn(smp->sess->origin);
Emeric Brun43e79582014-10-29 19:03:26 +01003475 if (!conn || conn->xprt != &ssl_sock)
3476 return 0;
3477
3478 if (!(conn->flags & CO_FL_CONNECTED)) {
3479 smp->flags |= SMP_F_MAY_CHANGE;
3480 return 0;
3481 }
3482
3483 if (cert_peer)
3484 crt = SSL_get_peer_certificate(conn->xprt_ctx);
3485 else
3486 crt = SSL_get_certificate(conn->xprt_ctx);
3487
3488 if (!crt)
3489 goto out;
3490
3491 smp_trash = get_trash_chunk();
3492 if (ssl_sock_crt2der(crt, smp_trash) <= 0)
3493 goto out;
3494
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02003495 smp->data.u.str = *smp_trash;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02003496 smp->data.type = SMP_T_BIN;
Emeric Brun43e79582014-10-29 19:03:26 +01003497 ret = 1;
3498out:
3499 /* SSL_get_peer_certificate, it increase X509 * ref count */
3500 if (cert_peer && crt)
3501 X509_free(crt);
3502 return ret;
3503}
3504
Emeric Brunba841a12014-04-30 17:05:08 +02003505/* binary, returns serial of certificate in a binary chunk.
3506 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
3507 * should be use.
3508 */
Willy Tarreau8d598402012-10-22 17:58:39 +02003509static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02003510smp_fetch_ssl_x_serial(const struct arg *args, struct sample *smp, const char *kw, void *private)
Willy Tarreau8d598402012-10-22 17:58:39 +02003511{
Emeric Brunba841a12014-04-30 17:05:08 +02003512 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Willy Tarreau8d598402012-10-22 17:58:39 +02003513 X509 *crt = NULL;
3514 int ret = 0;
3515 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003516 struct connection *conn;
3517
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02003518 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003519 if (!conn || conn->xprt != &ssl_sock)
Willy Tarreau8d598402012-10-22 17:58:39 +02003520 return 0;
3521
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003522 if (!(conn->flags & CO_FL_CONNECTED)) {
Willy Tarreau8d598402012-10-22 17:58:39 +02003523 smp->flags |= SMP_F_MAY_CHANGE;
3524 return 0;
3525 }
3526
Emeric Brunba841a12014-04-30 17:05:08 +02003527 if (cert_peer)
3528 crt = SSL_get_peer_certificate(conn->xprt_ctx);
3529 else
3530 crt = SSL_get_certificate(conn->xprt_ctx);
3531
Willy Tarreau8d598402012-10-22 17:58:39 +02003532 if (!crt)
3533 goto out;
3534
Willy Tarreau47ca5452012-12-23 20:22:19 +01003535 smp_trash = get_trash_chunk();
Willy Tarreau8d598402012-10-22 17:58:39 +02003536 if (ssl_sock_get_serial(crt, smp_trash) <= 0)
3537 goto out;
3538
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02003539 smp->data.u.str = *smp_trash;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02003540 smp->data.type = SMP_T_BIN;
Willy Tarreau8d598402012-10-22 17:58:39 +02003541 ret = 1;
3542out:
Emeric Brunba841a12014-04-30 17:05:08 +02003543 /* SSL_get_peer_certificate, it increase X509 * ref count */
3544 if (cert_peer && crt)
Willy Tarreau8d598402012-10-22 17:58:39 +02003545 X509_free(crt);
3546 return ret;
3547}
Emeric Brune64aef12012-09-21 13:15:06 +02003548
Emeric Brunba841a12014-04-30 17:05:08 +02003549/* binary, returns the client certificate's SHA-1 fingerprint (SHA-1 hash of DER-encoded certificate) in a binary chunk.
3550 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
3551 * should be use.
3552 */
James Votha051b4a2013-05-14 20:37:59 +02003553static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02003554smp_fetch_ssl_x_sha1(const struct arg *args, struct sample *smp, const char *kw, void *private)
James Votha051b4a2013-05-14 20:37:59 +02003555{
Emeric Brunba841a12014-04-30 17:05:08 +02003556 int cert_peer = (kw[4] == 'c') ? 1 : 0;
James Votha051b4a2013-05-14 20:37:59 +02003557 X509 *crt = NULL;
3558 const EVP_MD *digest;
3559 int ret = 0;
3560 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003561 struct connection *conn;
James Votha051b4a2013-05-14 20:37:59 +02003562
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02003563 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003564 if (!conn || conn->xprt != &ssl_sock)
3565 return 0;
3566
3567 if (!(conn->flags & CO_FL_CONNECTED)) {
James Votha051b4a2013-05-14 20:37:59 +02003568 smp->flags |= SMP_F_MAY_CHANGE;
3569 return 0;
3570 }
3571
Emeric Brunba841a12014-04-30 17:05:08 +02003572 if (cert_peer)
3573 crt = SSL_get_peer_certificate(conn->xprt_ctx);
3574 else
3575 crt = SSL_get_certificate(conn->xprt_ctx);
James Votha051b4a2013-05-14 20:37:59 +02003576 if (!crt)
3577 goto out;
3578
3579 smp_trash = get_trash_chunk();
3580 digest = EVP_sha1();
3581 X509_digest(crt, digest, (unsigned char *)smp_trash->str, (unsigned int *)&smp_trash->len);
3582
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02003583 smp->data.u.str = *smp_trash;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02003584 smp->data.type = SMP_T_BIN;
James Votha051b4a2013-05-14 20:37:59 +02003585 ret = 1;
3586out:
Emeric Brunba841a12014-04-30 17:05:08 +02003587 /* SSL_get_peer_certificate, it increase X509 * ref count */
3588 if (cert_peer && crt)
James Votha051b4a2013-05-14 20:37:59 +02003589 X509_free(crt);
3590 return ret;
3591}
3592
Emeric Brunba841a12014-04-30 17:05:08 +02003593/* string, returns certificate's notafter date in ASN1_UTCTIME format.
3594 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
3595 * should be use.
3596 */
Emeric Brunce5ad802012-10-22 14:11:22 +02003597static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02003598smp_fetch_ssl_x_notafter(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brunce5ad802012-10-22 14:11:22 +02003599{
Emeric Brunba841a12014-04-30 17:05:08 +02003600 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brunce5ad802012-10-22 14:11:22 +02003601 X509 *crt = NULL;
3602 int ret = 0;
3603 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003604 struct connection *conn;
Emeric Brunce5ad802012-10-22 14:11:22 +02003605
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02003606 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003607 if (!conn || conn->xprt != &ssl_sock)
3608 return 0;
3609
3610 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunce5ad802012-10-22 14:11:22 +02003611 smp->flags |= SMP_F_MAY_CHANGE;
3612 return 0;
3613 }
3614
Emeric Brunba841a12014-04-30 17:05:08 +02003615 if (cert_peer)
3616 crt = SSL_get_peer_certificate(conn->xprt_ctx);
3617 else
3618 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brunce5ad802012-10-22 14:11:22 +02003619 if (!crt)
3620 goto out;
3621
Willy Tarreau47ca5452012-12-23 20:22:19 +01003622 smp_trash = get_trash_chunk();
Emeric Brunce5ad802012-10-22 14:11:22 +02003623 if (ssl_sock_get_time(X509_get_notAfter(crt), smp_trash) <= 0)
3624 goto out;
3625
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02003626 smp->data.u.str = *smp_trash;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02003627 smp->data.type = SMP_T_STR;
Emeric Brunce5ad802012-10-22 14:11:22 +02003628 ret = 1;
3629out:
Emeric Brunba841a12014-04-30 17:05:08 +02003630 /* SSL_get_peer_certificate, it increase X509 * ref count */
3631 if (cert_peer && crt)
Emeric Brunce5ad802012-10-22 14:11:22 +02003632 X509_free(crt);
3633 return ret;
3634}
3635
Emeric Brunba841a12014-04-30 17:05:08 +02003636/* string, returns a string of a formatted full dn \C=..\O=..\OU=.. \CN=.. of certificate's issuer
3637 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
3638 * should be use.
3639 */
Emeric Brun87855892012-10-17 17:39:35 +02003640static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02003641smp_fetch_ssl_x_i_dn(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun87855892012-10-17 17:39:35 +02003642{
Emeric Brunba841a12014-04-30 17:05:08 +02003643 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brun87855892012-10-17 17:39:35 +02003644 X509 *crt = NULL;
3645 X509_NAME *name;
3646 int ret = 0;
3647 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003648 struct connection *conn;
Emeric Brun87855892012-10-17 17:39:35 +02003649
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02003650 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003651 if (!conn || conn->xprt != &ssl_sock)
3652 return 0;
3653
3654 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun87855892012-10-17 17:39:35 +02003655 smp->flags |= SMP_F_MAY_CHANGE;
3656 return 0;
3657 }
3658
Emeric Brunba841a12014-04-30 17:05:08 +02003659 if (cert_peer)
3660 crt = SSL_get_peer_certificate(conn->xprt_ctx);
3661 else
3662 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brun87855892012-10-17 17:39:35 +02003663 if (!crt)
3664 goto out;
3665
3666 name = X509_get_issuer_name(crt);
3667 if (!name)
3668 goto out;
3669
Willy Tarreau47ca5452012-12-23 20:22:19 +01003670 smp_trash = get_trash_chunk();
Emeric Brun87855892012-10-17 17:39:35 +02003671 if (args && args[0].type == ARGT_STR) {
3672 int pos = 1;
3673
3674 if (args[1].type == ARGT_SINT)
3675 pos = args[1].data.sint;
Emeric Brun87855892012-10-17 17:39:35 +02003676
3677 if (ssl_sock_get_dn_entry(name, &args[0].data.str, pos, smp_trash) <= 0)
3678 goto out;
3679 }
3680 else if (ssl_sock_get_dn_oneline(name, smp_trash) <= 0)
3681 goto out;
3682
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02003683 smp->data.type = SMP_T_STR;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02003684 smp->data.u.str = *smp_trash;
Emeric Brun87855892012-10-17 17:39:35 +02003685 ret = 1;
3686out:
Emeric Brunba841a12014-04-30 17:05:08 +02003687 /* SSL_get_peer_certificate, it increase X509 * ref count */
3688 if (cert_peer && crt)
Emeric Brun87855892012-10-17 17:39:35 +02003689 X509_free(crt);
3690 return ret;
3691}
3692
Emeric Brunba841a12014-04-30 17:05:08 +02003693/* string, returns notbefore date in ASN1_UTCTIME format.
3694 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
3695 * should be use.
3696 */
Emeric Brunce5ad802012-10-22 14:11:22 +02003697static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02003698smp_fetch_ssl_x_notbefore(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brunce5ad802012-10-22 14:11:22 +02003699{
Emeric Brunba841a12014-04-30 17:05:08 +02003700 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brunce5ad802012-10-22 14:11:22 +02003701 X509 *crt = NULL;
3702 int ret = 0;
3703 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003704 struct connection *conn;
3705
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02003706 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003707 if (!conn || conn->xprt != &ssl_sock)
Emeric Brunce5ad802012-10-22 14:11:22 +02003708 return 0;
3709
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003710 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunce5ad802012-10-22 14:11:22 +02003711 smp->flags |= SMP_F_MAY_CHANGE;
3712 return 0;
3713 }
3714
Emeric Brunba841a12014-04-30 17:05:08 +02003715 if (cert_peer)
3716 crt = SSL_get_peer_certificate(conn->xprt_ctx);
3717 else
3718 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brunce5ad802012-10-22 14:11:22 +02003719 if (!crt)
3720 goto out;
3721
Willy Tarreau47ca5452012-12-23 20:22:19 +01003722 smp_trash = get_trash_chunk();
Emeric Brunce5ad802012-10-22 14:11:22 +02003723 if (ssl_sock_get_time(X509_get_notBefore(crt), smp_trash) <= 0)
3724 goto out;
3725
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02003726 smp->data.u.str = *smp_trash;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02003727 smp->data.type = SMP_T_STR;
Emeric Brunce5ad802012-10-22 14:11:22 +02003728 ret = 1;
3729out:
Emeric Brunba841a12014-04-30 17:05:08 +02003730 /* SSL_get_peer_certificate, it increase X509 * ref count */
3731 if (cert_peer && crt)
Emeric Brunce5ad802012-10-22 14:11:22 +02003732 X509_free(crt);
3733 return ret;
3734}
3735
Emeric Brunba841a12014-04-30 17:05:08 +02003736/* string, returns a string of a formatted full dn \C=..\O=..\OU=.. \CN=.. of certificate's subject
3737 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
3738 * should be use.
3739 */
Emeric Brun87855892012-10-17 17:39:35 +02003740static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02003741smp_fetch_ssl_x_s_dn(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun87855892012-10-17 17:39:35 +02003742{
Emeric Brunba841a12014-04-30 17:05:08 +02003743 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brun87855892012-10-17 17:39:35 +02003744 X509 *crt = NULL;
3745 X509_NAME *name;
3746 int ret = 0;
3747 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003748 struct connection *conn;
Emeric Brun87855892012-10-17 17:39:35 +02003749
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02003750 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003751 if (!conn || conn->xprt != &ssl_sock)
3752 return 0;
3753
3754 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun87855892012-10-17 17:39:35 +02003755 smp->flags |= SMP_F_MAY_CHANGE;
3756 return 0;
3757 }
3758
Emeric Brunba841a12014-04-30 17:05:08 +02003759 if (cert_peer)
3760 crt = SSL_get_peer_certificate(conn->xprt_ctx);
3761 else
3762 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brun87855892012-10-17 17:39:35 +02003763 if (!crt)
3764 goto out;
3765
3766 name = X509_get_subject_name(crt);
3767 if (!name)
3768 goto out;
3769
Willy Tarreau47ca5452012-12-23 20:22:19 +01003770 smp_trash = get_trash_chunk();
Emeric Brun87855892012-10-17 17:39:35 +02003771 if (args && args[0].type == ARGT_STR) {
3772 int pos = 1;
3773
3774 if (args[1].type == ARGT_SINT)
3775 pos = args[1].data.sint;
Emeric Brun87855892012-10-17 17:39:35 +02003776
3777 if (ssl_sock_get_dn_entry(name, &args[0].data.str, pos, smp_trash) <= 0)
3778 goto out;
3779 }
3780 else if (ssl_sock_get_dn_oneline(name, smp_trash) <= 0)
3781 goto out;
3782
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02003783 smp->data.type = SMP_T_STR;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02003784 smp->data.u.str = *smp_trash;
Emeric Brun87855892012-10-17 17:39:35 +02003785 ret = 1;
3786out:
Emeric Brunba841a12014-04-30 17:05:08 +02003787 /* SSL_get_peer_certificate, it increase X509 * ref count */
3788 if (cert_peer && crt)
Emeric Brun87855892012-10-17 17:39:35 +02003789 X509_free(crt);
3790 return ret;
3791}
Emeric Brun9143d372012-12-20 15:44:16 +01003792
3793/* integer, returns true if current session use a client certificate */
3794static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02003795smp_fetch_ssl_c_used(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun9143d372012-12-20 15:44:16 +01003796{
3797 X509 *crt;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003798 struct connection *conn;
Emeric Brun9143d372012-12-20 15:44:16 +01003799
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02003800 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003801 if (!conn || conn->xprt != &ssl_sock)
3802 return 0;
3803
3804 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun9143d372012-12-20 15:44:16 +01003805 smp->flags |= SMP_F_MAY_CHANGE;
3806 return 0;
3807 }
3808
3809 /* SSL_get_peer_certificate returns a ptr on allocated X509 struct */
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003810 crt = SSL_get_peer_certificate(conn->xprt_ctx);
Emeric Brun9143d372012-12-20 15:44:16 +01003811 if (crt) {
3812 X509_free(crt);
3813 }
3814
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02003815 smp->data.type = SMP_T_BOOL;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02003816 smp->data.u.sint = (crt != NULL);
Emeric Brun9143d372012-12-20 15:44:16 +01003817 return 1;
3818}
3819
Emeric Brunba841a12014-04-30 17:05:08 +02003820/* integer, returns the certificate version
3821 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
3822 * should be use.
3823 */
Emeric Bruna7359fd2012-10-17 15:03:11 +02003824static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02003825smp_fetch_ssl_x_version(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Bruna7359fd2012-10-17 15:03:11 +02003826{
Emeric Brunba841a12014-04-30 17:05:08 +02003827 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Bruna7359fd2012-10-17 15:03:11 +02003828 X509 *crt;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003829 struct connection *conn;
3830
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02003831 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003832 if (!conn || conn->xprt != &ssl_sock)
Emeric Bruna7359fd2012-10-17 15:03:11 +02003833 return 0;
3834
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003835 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Bruna7359fd2012-10-17 15:03:11 +02003836 smp->flags |= SMP_F_MAY_CHANGE;
3837 return 0;
3838 }
3839
Emeric Brunba841a12014-04-30 17:05:08 +02003840 if (cert_peer)
3841 crt = SSL_get_peer_certificate(conn->xprt_ctx);
3842 else
3843 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Bruna7359fd2012-10-17 15:03:11 +02003844 if (!crt)
3845 return 0;
3846
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02003847 smp->data.u.sint = (unsigned int)(1 + X509_get_version(crt));
Emeric Brunba841a12014-04-30 17:05:08 +02003848 /* SSL_get_peer_certificate increase X509 * ref count */
3849 if (cert_peer)
3850 X509_free(crt);
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02003851 smp->data.type = SMP_T_SINT;
Emeric Bruna7359fd2012-10-17 15:03:11 +02003852
3853 return 1;
3854}
3855
Emeric Brunba841a12014-04-30 17:05:08 +02003856/* string, returns the certificate's signature algorithm.
3857 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
3858 * should be use.
3859 */
Emeric Brun7f56e742012-10-19 18:15:40 +02003860static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02003861smp_fetch_ssl_x_sig_alg(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun7f56e742012-10-19 18:15:40 +02003862{
Emeric Brunba841a12014-04-30 17:05:08 +02003863 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brun7f56e742012-10-19 18:15:40 +02003864 X509 *crt;
3865 int nid;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003866 struct connection *conn;
Emeric Brun7f56e742012-10-19 18:15:40 +02003867
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02003868 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003869 if (!conn || conn->xprt != &ssl_sock)
3870 return 0;
3871
3872 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun7f56e742012-10-19 18:15:40 +02003873 smp->flags |= SMP_F_MAY_CHANGE;
3874 return 0;
3875 }
3876
Emeric Brunba841a12014-04-30 17:05:08 +02003877 if (cert_peer)
3878 crt = SSL_get_peer_certificate(conn->xprt_ctx);
3879 else
3880 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brun7f56e742012-10-19 18:15:40 +02003881 if (!crt)
3882 return 0;
3883
3884 nid = OBJ_obj2nid((ASN1_OBJECT *)(crt->cert_info->signature->algorithm));
3885
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02003886 smp->data.u.str.str = (char *)OBJ_nid2sn(nid);
3887 if (!smp->data.u.str.str) {
Emeric Brunba841a12014-04-30 17:05:08 +02003888 /* SSL_get_peer_certificate increase X509 * ref count */
3889 if (cert_peer)
3890 X509_free(crt);
Emeric Brun7f56e742012-10-19 18:15:40 +02003891 return 0;
Emeric Brun9bf3ba22013-10-07 14:31:44 +02003892 }
Emeric Brun7f56e742012-10-19 18:15:40 +02003893
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02003894 smp->data.type = SMP_T_STR;
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01003895 smp->flags |= SMP_F_CONST;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02003896 smp->data.u.str.len = strlen(smp->data.u.str.str);
Emeric Brunba841a12014-04-30 17:05:08 +02003897 /* SSL_get_peer_certificate increase X509 * ref count */
3898 if (cert_peer)
3899 X509_free(crt);
Emeric Brun7f56e742012-10-19 18:15:40 +02003900
3901 return 1;
3902}
3903
Emeric Brunba841a12014-04-30 17:05:08 +02003904/* string, returns the certificate's key algorithm.
3905 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
3906 * should be use.
3907 */
Emeric Brun521a0112012-10-22 12:22:55 +02003908static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02003909smp_fetch_ssl_x_key_alg(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun521a0112012-10-22 12:22:55 +02003910{
Emeric Brunba841a12014-04-30 17:05:08 +02003911 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brun521a0112012-10-22 12:22:55 +02003912 X509 *crt;
3913 int nid;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003914 struct connection *conn;
Emeric Brun521a0112012-10-22 12:22:55 +02003915
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02003916 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003917 if (!conn || conn->xprt != &ssl_sock)
3918 return 0;
3919
3920 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun521a0112012-10-22 12:22:55 +02003921 smp->flags |= SMP_F_MAY_CHANGE;
3922 return 0;
3923 }
3924
Emeric Brunba841a12014-04-30 17:05:08 +02003925 if (cert_peer)
3926 crt = SSL_get_peer_certificate(conn->xprt_ctx);
3927 else
3928 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brun521a0112012-10-22 12:22:55 +02003929 if (!crt)
3930 return 0;
3931
3932 nid = OBJ_obj2nid((ASN1_OBJECT *)(crt->cert_info->key->algor->algorithm));
3933
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02003934 smp->data.u.str.str = (char *)OBJ_nid2sn(nid);
3935 if (!smp->data.u.str.str) {
Emeric Brunba841a12014-04-30 17:05:08 +02003936 /* SSL_get_peer_certificate increase X509 * ref count */
3937 if (cert_peer)
3938 X509_free(crt);
Emeric Brun521a0112012-10-22 12:22:55 +02003939 return 0;
Emeric Brun9bf3ba22013-10-07 14:31:44 +02003940 }
Emeric Brun521a0112012-10-22 12:22:55 +02003941
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02003942 smp->data.type = SMP_T_STR;
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01003943 smp->flags |= SMP_F_CONST;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02003944 smp->data.u.str.len = strlen(smp->data.u.str.str);
Emeric Brunba841a12014-04-30 17:05:08 +02003945 if (cert_peer)
3946 X509_free(crt);
Emeric Brun521a0112012-10-22 12:22:55 +02003947
3948 return 1;
3949}
3950
Emeric Brun645ae792014-04-30 14:21:06 +02003951/* boolean, returns true if front conn. transport layer is SSL.
3952 * This function is also usable on backend conn if the fetch keyword 5th
3953 * char is 'b'.
3954 */
Willy Tarreau7875d092012-09-10 08:20:03 +02003955static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02003956smp_fetch_ssl_fc(const struct arg *args, struct sample *smp, const char *kw, void *private)
Willy Tarreau7875d092012-09-10 08:20:03 +02003957{
Emeric Brun645ae792014-04-30 14:21:06 +02003958 int back_conn = (kw[4] == 'b') ? 1 : 0;
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02003959 struct connection *conn = objt_conn(smp->strm->si[back_conn].end);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003960
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02003961 smp->data.type = SMP_T_BOOL;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02003962 smp->data.u.sint = (conn && conn->xprt == &ssl_sock);
Willy Tarreau7875d092012-09-10 08:20:03 +02003963 return 1;
3964}
3965
Emeric Brun2525b6b2012-10-18 15:59:43 +02003966/* boolean, returns true if client present a SNI */
Willy Tarreau7875d092012-09-10 08:20:03 +02003967static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02003968smp_fetch_ssl_fc_has_sni(const struct arg *args, struct sample *smp, const char *kw, void *private)
Willy Tarreau7875d092012-09-10 08:20:03 +02003969{
3970#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02003971 struct connection *conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003972
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02003973 smp->data.type = SMP_T_BOOL;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02003974 smp->data.u.sint = (conn && conn->xprt == &ssl_sock) &&
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003975 conn->xprt_ctx &&
3976 SSL_get_servername(conn->xprt_ctx, TLSEXT_NAMETYPE_host_name) != NULL;
Willy Tarreau7875d092012-09-10 08:20:03 +02003977 return 1;
3978#else
3979 return 0;
3980#endif
3981}
3982
Nenad Merdanovic26ea8222015-05-18 02:28:57 +02003983/* boolean, returns true if client session has been resumed */
3984static int
3985smp_fetch_ssl_fc_is_resumed(const struct arg *args, struct sample *smp, const char *kw, void *private)
3986{
3987 struct connection *conn = objt_conn(smp->sess->origin);
3988
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02003989 smp->data.type = SMP_T_BOOL;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02003990 smp->data.u.sint = (conn && conn->xprt == &ssl_sock) &&
Nenad Merdanovic26ea8222015-05-18 02:28:57 +02003991 conn->xprt_ctx &&
3992 SSL_session_reused(conn->xprt_ctx);
3993 return 1;
3994}
3995
Emeric Brun645ae792014-04-30 14:21:06 +02003996/* string, returns the used cipher if front conn. transport layer is SSL.
3997 * This function is also usable on backend conn if the fetch keyword 5th
3998 * char is 'b'.
3999 */
Emeric Brun589fcad2012-10-16 14:13:26 +02004000static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004001smp_fetch_ssl_fc_cipher(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun589fcad2012-10-16 14:13:26 +02004002{
Emeric Brun645ae792014-04-30 14:21:06 +02004003 int back_conn = (kw[4] == 'b') ? 1 : 0;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004004 struct connection *conn;
4005
Emeric Brun589fcad2012-10-16 14:13:26 +02004006 smp->flags = 0;
4007
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004008 conn = objt_conn(smp->strm->si[back_conn].end);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004009 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
Emeric Brun589fcad2012-10-16 14:13:26 +02004010 return 0;
4011
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004012 smp->data.u.str.str = (char *)SSL_get_cipher_name(conn->xprt_ctx);
4013 if (!smp->data.u.str.str)
Emeric Brun589fcad2012-10-16 14:13:26 +02004014 return 0;
4015
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004016 smp->data.type = SMP_T_STR;
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01004017 smp->flags |= SMP_F_CONST;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004018 smp->data.u.str.len = strlen(smp->data.u.str.str);
Emeric Brun589fcad2012-10-16 14:13:26 +02004019
4020 return 1;
4021}
4022
Emeric Brun645ae792014-04-30 14:21:06 +02004023/* integer, returns the algoritm's keysize if front conn. transport layer
4024 * is SSL.
4025 * This function is also usable on backend conn if the fetch keyword 5th
4026 * char is 'b'.
4027 */
Emeric Brun589fcad2012-10-16 14:13:26 +02004028static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004029smp_fetch_ssl_fc_alg_keysize(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun589fcad2012-10-16 14:13:26 +02004030{
Emeric Brun645ae792014-04-30 14:21:06 +02004031 int back_conn = (kw[4] == 'b') ? 1 : 0;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004032 struct connection *conn;
Thierry FOURNIER07ee64e2015-07-06 23:43:03 +02004033 int sint;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004034
Emeric Brun589fcad2012-10-16 14:13:26 +02004035 smp->flags = 0;
4036
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004037 conn = objt_conn(smp->strm->si[back_conn].end);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004038 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
Emeric Brun589fcad2012-10-16 14:13:26 +02004039 return 0;
4040
Thierry FOURNIER07ee64e2015-07-06 23:43:03 +02004041 if (!SSL_get_cipher_bits(conn->xprt_ctx, &sint))
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004042 return 0;
4043
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004044 smp->data.u.sint = sint;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004045 smp->data.type = SMP_T_SINT;
Emeric Brun589fcad2012-10-16 14:13:26 +02004046
4047 return 1;
4048}
4049
Emeric Brun645ae792014-04-30 14:21:06 +02004050/* integer, returns the used keysize if front conn. transport layer is SSL.
4051 * This function is also usable on backend conn if the fetch keyword 5th
4052 * char is 'b'.
4053 */
Emeric Brun589fcad2012-10-16 14:13:26 +02004054static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004055smp_fetch_ssl_fc_use_keysize(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun589fcad2012-10-16 14:13:26 +02004056{
Emeric Brun645ae792014-04-30 14:21:06 +02004057 int back_conn = (kw[4] == 'b') ? 1 : 0;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004058 struct connection *conn;
4059
Emeric Brun589fcad2012-10-16 14:13:26 +02004060 smp->flags = 0;
4061
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004062 conn = objt_conn(smp->strm->si[back_conn].end);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004063 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
4064 return 0;
4065
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004066 smp->data.u.sint = (unsigned int)SSL_get_cipher_bits(conn->xprt_ctx, NULL);
4067 if (!smp->data.u.sint)
Emeric Brun589fcad2012-10-16 14:13:26 +02004068 return 0;
4069
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004070 smp->data.type = SMP_T_SINT;
Emeric Brun589fcad2012-10-16 14:13:26 +02004071
4072 return 1;
4073}
4074
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02004075#ifdef OPENSSL_NPN_NEGOTIATED
Willy Tarreau7875d092012-09-10 08:20:03 +02004076static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004077smp_fetch_ssl_fc_npn(const struct arg *args, struct sample *smp, const char *kw, void *private)
Willy Tarreaua33c6542012-10-15 13:19:06 +02004078{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004079 struct connection *conn;
4080
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01004081 smp->flags = SMP_F_CONST;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004082 smp->data.type = SMP_T_STR;
Willy Tarreaua33c6542012-10-15 13:19:06 +02004083
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004084 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004085 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
4086 return 0;
4087
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004088 smp->data.u.str.str = NULL;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004089 SSL_get0_next_proto_negotiated(conn->xprt_ctx,
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004090 (const unsigned char **)&smp->data.u.str.str, (unsigned *)&smp->data.u.str.len);
Willy Tarreaua33c6542012-10-15 13:19:06 +02004091
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004092 if (!smp->data.u.str.str)
Willy Tarreaua33c6542012-10-15 13:19:06 +02004093 return 0;
4094
4095 return 1;
Willy Tarreaua33c6542012-10-15 13:19:06 +02004096}
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02004097#endif
Willy Tarreaua33c6542012-10-15 13:19:06 +02004098
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01004099#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Willy Tarreauab861d32013-04-02 02:30:41 +02004100static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004101smp_fetch_ssl_fc_alpn(const struct arg *args, struct sample *smp, const char *kw, void *private)
Willy Tarreauab861d32013-04-02 02:30:41 +02004102{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004103 struct connection *conn;
4104
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01004105 smp->flags = SMP_F_CONST;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004106 smp->data.type = SMP_T_STR;
Willy Tarreauab861d32013-04-02 02:30:41 +02004107
Willy Tarreaue26bf052015-05-12 10:30:12 +02004108 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004109 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
Willy Tarreauab861d32013-04-02 02:30:41 +02004110 return 0;
4111
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004112 smp->data.u.str.str = NULL;
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01004113 SSL_get0_alpn_selected(conn->xprt_ctx,
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004114 (const unsigned char **)&smp->data.u.str.str, (unsigned *)&smp->data.u.str.len);
Willy Tarreauab861d32013-04-02 02:30:41 +02004115
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004116 if (!smp->data.u.str.str)
Willy Tarreauab861d32013-04-02 02:30:41 +02004117 return 0;
4118
4119 return 1;
4120}
4121#endif
4122
Emeric Brun645ae792014-04-30 14:21:06 +02004123/* string, returns the used protocol if front conn. transport layer is SSL.
4124 * This function is also usable on backend conn if the fetch keyword 5th
4125 * char is 'b'.
4126 */
Willy Tarreaua33c6542012-10-15 13:19:06 +02004127static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004128smp_fetch_ssl_fc_protocol(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun589fcad2012-10-16 14:13:26 +02004129{
Emeric Brun645ae792014-04-30 14:21:06 +02004130 int back_conn = (kw[4] == 'b') ? 1 : 0;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004131 struct connection *conn;
4132
Emeric Brun589fcad2012-10-16 14:13:26 +02004133 smp->flags = 0;
4134
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004135 conn = objt_conn(smp->strm->si[back_conn].end);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004136 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
4137 return 0;
4138
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004139 smp->data.u.str.str = (char *)SSL_get_version(conn->xprt_ctx);
4140 if (!smp->data.u.str.str)
Emeric Brun589fcad2012-10-16 14:13:26 +02004141 return 0;
4142
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004143 smp->data.type = SMP_T_STR;
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01004144 smp->flags = SMP_F_CONST;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004145 smp->data.u.str.len = strlen(smp->data.u.str.str);
Emeric Brun589fcad2012-10-16 14:13:26 +02004146
4147 return 1;
4148}
4149
Willy Tarreau87b09662015-04-03 00:22:06 +02004150/* binary, returns the SSL stream id if front conn. transport layer is SSL.
Emeric Brun645ae792014-04-30 14:21:06 +02004151 * This function is also usable on backend conn if the fetch keyword 5th
4152 * char is 'b'.
4153 */
Emeric Brun589fcad2012-10-16 14:13:26 +02004154static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004155smp_fetch_ssl_fc_session_id(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brunfe68f682012-10-16 14:59:28 +02004156{
4157#if OPENSSL_VERSION_NUMBER > 0x0090800fL
Emeric Brun645ae792014-04-30 14:21:06 +02004158 int back_conn = (kw[4] == 'b') ? 1 : 0;
Willy Tarreau192252e2015-04-04 01:47:55 +02004159 SSL_SESSION *ssl_sess;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004160 struct connection *conn;
Emeric Brunfe68f682012-10-16 14:59:28 +02004161
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01004162 smp->flags = SMP_F_CONST;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004163 smp->data.type = SMP_T_BIN;
Emeric Brunfe68f682012-10-16 14:59:28 +02004164
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004165 conn = objt_conn(smp->strm->si[back_conn].end);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004166 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
4167 return 0;
4168
Willy Tarreau192252e2015-04-04 01:47:55 +02004169 ssl_sess = SSL_get_session(conn->xprt_ctx);
4170 if (!ssl_sess)
Emeric Brunfe68f682012-10-16 14:59:28 +02004171 return 0;
4172
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004173 smp->data.u.str.str = (char *)SSL_SESSION_get_id(ssl_sess, (unsigned int *)&smp->data.u.str.len);
4174 if (!smp->data.u.str.str || !smp->data.u.str.len)
Emeric Brunfe68f682012-10-16 14:59:28 +02004175 return 0;
4176
4177 return 1;
4178#else
4179 return 0;
4180#endif
4181}
4182
4183static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004184smp_fetch_ssl_fc_sni(const struct arg *args, struct sample *smp, const char *kw, void *private)
Willy Tarreau7875d092012-09-10 08:20:03 +02004185{
4186#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004187 struct connection *conn;
4188
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01004189 smp->flags = SMP_F_CONST;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004190 smp->data.type = SMP_T_STR;
Willy Tarreau7875d092012-09-10 08:20:03 +02004191
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004192 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004193 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
4194 return 0;
4195
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004196 smp->data.u.str.str = (char *)SSL_get_servername(conn->xprt_ctx, TLSEXT_NAMETYPE_host_name);
4197 if (!smp->data.u.str.str)
Willy Tarreau3e394c92012-09-14 23:56:58 +02004198 return 0;
4199
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004200 smp->data.u.str.len = strlen(smp->data.u.str.str);
Willy Tarreau7875d092012-09-10 08:20:03 +02004201 return 1;
4202#else
4203 return 0;
4204#endif
4205}
4206
David Sc1ad52e2014-04-08 18:48:47 -04004207static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004208smp_fetch_ssl_fc_unique_id(const struct arg *args, struct sample *smp, const char *kw, void *private)
David Sc1ad52e2014-04-08 18:48:47 -04004209{
4210#if OPENSSL_VERSION_NUMBER > 0x0090800fL
Emeric Brun645ae792014-04-30 14:21:06 +02004211 int back_conn = (kw[4] == 'b') ? 1 : 0;
David Sc1ad52e2014-04-08 18:48:47 -04004212 struct connection *conn;
4213 int finished_len;
David Sc1ad52e2014-04-08 18:48:47 -04004214 struct chunk *finished_trash;
David Sc1ad52e2014-04-08 18:48:47 -04004215
4216 smp->flags = 0;
4217
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004218 conn = objt_conn(smp->strm->si[back_conn].end);
David Sc1ad52e2014-04-08 18:48:47 -04004219 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
4220 return 0;
4221
4222 if (!(conn->flags & CO_FL_CONNECTED)) {
4223 smp->flags |= SMP_F_MAY_CHANGE;
4224 return 0;
4225 }
4226
4227 finished_trash = get_trash_chunk();
4228 if (!SSL_session_reused(conn->xprt_ctx))
4229 finished_len = SSL_get_peer_finished(conn->xprt_ctx, finished_trash->str, finished_trash->size);
4230 else
4231 finished_len = SSL_get_finished(conn->xprt_ctx, finished_trash->str, finished_trash->size);
4232
4233 if (!finished_len)
4234 return 0;
4235
Emeric Brunb73a9b02014-04-30 18:49:19 +02004236 finished_trash->len = finished_len;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004237 smp->data.u.str = *finished_trash;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004238 smp->data.type = SMP_T_BIN;
David Sc1ad52e2014-04-08 18:48:47 -04004239
4240 return 1;
4241#else
4242 return 0;
4243#endif
4244}
4245
Emeric Brun2525b6b2012-10-18 15:59:43 +02004246/* integer, returns the first verify error in CA chain of client certificate chain. */
Emeric Brunf282a812012-09-21 15:27:54 +02004247static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004248smp_fetch_ssl_c_ca_err(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brunf282a812012-09-21 15:27:54 +02004249{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004250 struct connection *conn;
4251
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004252 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004253 if (!conn || conn->xprt != &ssl_sock)
4254 return 0;
4255
4256 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunf282a812012-09-21 15:27:54 +02004257 smp->flags = SMP_F_MAY_CHANGE;
4258 return 0;
4259 }
4260
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004261 smp->data.type = SMP_T_SINT;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004262 smp->data.u.sint = (unsigned long long int)SSL_SOCK_ST_TO_CA_ERROR(conn->xprt_st);
Emeric Brunf282a812012-09-21 15:27:54 +02004263 smp->flags = 0;
4264
4265 return 1;
4266}
4267
Emeric Brun2525b6b2012-10-18 15:59:43 +02004268/* integer, returns the depth of the first verify error in CA chain of client certificate chain. */
Emeric Brunf282a812012-09-21 15:27:54 +02004269static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004270smp_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 +02004271{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004272 struct connection *conn;
4273
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004274 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004275 if (!conn || conn->xprt != &ssl_sock)
Emeric Brunf282a812012-09-21 15:27:54 +02004276 return 0;
4277
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004278 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunf282a812012-09-21 15:27:54 +02004279 smp->flags = SMP_F_MAY_CHANGE;
4280 return 0;
4281 }
4282
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004283 smp->data.type = SMP_T_SINT;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004284 smp->data.u.sint = (long long int)SSL_SOCK_ST_TO_CAEDEPTH(conn->xprt_st);
Emeric Brunf282a812012-09-21 15:27:54 +02004285 smp->flags = 0;
4286
4287 return 1;
4288}
4289
Emeric Brun2525b6b2012-10-18 15:59:43 +02004290/* integer, returns the first verify error on client certificate */
Emeric Brunf282a812012-09-21 15:27:54 +02004291static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004292smp_fetch_ssl_c_err(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brunf282a812012-09-21 15:27:54 +02004293{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004294 struct connection *conn;
4295
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004296 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004297 if (!conn || conn->xprt != &ssl_sock)
4298 return 0;
4299
4300 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunf282a812012-09-21 15:27:54 +02004301 smp->flags = SMP_F_MAY_CHANGE;
4302 return 0;
4303 }
4304
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004305 smp->data.type = SMP_T_SINT;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004306 smp->data.u.sint = (long long int)SSL_SOCK_ST_TO_CRTERROR(conn->xprt_st);
Emeric Brunf282a812012-09-21 15:27:54 +02004307 smp->flags = 0;
4308
4309 return 1;
4310}
4311
Emeric Brun2525b6b2012-10-18 15:59:43 +02004312/* integer, returns the verify result on client cert */
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02004313static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004314smp_fetch_ssl_c_verify(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02004315{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004316 struct connection *conn;
4317
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004318 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004319 if (!conn || conn->xprt != &ssl_sock)
4320 return 0;
4321
4322 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02004323 smp->flags = SMP_F_MAY_CHANGE;
4324 return 0;
4325 }
4326
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004327 if (!conn->xprt_ctx)
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02004328 return 0;
4329
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004330 smp->data.type = SMP_T_SINT;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004331 smp->data.u.sint = (long long int)SSL_get_verify_result(conn->xprt_ctx);
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02004332 smp->flags = 0;
4333
4334 return 1;
4335}
4336
Emeric Brunfb510ea2012-10-05 12:00:26 +02004337/* parse the "ca-file" bind keyword */
4338static 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 +02004339{
4340 if (!*args[cur_arg + 1]) {
4341 if (err)
4342 memprintf(err, "'%s' : missing CAfile path", args[cur_arg]);
4343 return ERR_ALERT | ERR_FATAL;
4344 }
4345
Emeric Brunef42d922012-10-11 16:11:36 +02004346 if ((*args[cur_arg + 1] != '/') && global.ca_base)
4347 memprintf(&conf->ca_file, "%s/%s", global.ca_base, args[cur_arg + 1]);
4348 else
4349 memprintf(&conf->ca_file, "%s", args[cur_arg + 1]);
Emeric Brunc8e8d122012-10-02 18:42:10 +02004350
Emeric Brund94b3fe2012-09-20 18:23:56 +02004351 return 0;
4352}
4353
Christopher Faulet31af49d2015-06-09 17:29:50 +02004354/* parse the "ca-sign-file" bind keyword */
4355static int bind_parse_ca_sign_file(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
4356{
4357 if (!*args[cur_arg + 1]) {
4358 if (err)
4359 memprintf(err, "'%s' : missing CAfile path", args[cur_arg]);
4360 return ERR_ALERT | ERR_FATAL;
4361 }
4362
4363 if ((*args[cur_arg + 1] != '/') && global.ca_base)
4364 memprintf(&conf->ca_sign_file, "%s/%s", global.ca_base, args[cur_arg + 1]);
4365 else
4366 memprintf(&conf->ca_sign_file, "%s", args[cur_arg + 1]);
4367
4368 return 0;
4369}
4370
4371/* parse the ca-sign-pass bind keyword */
4372
4373static int bind_parse_ca_sign_pass(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
4374{
4375 if (!*args[cur_arg + 1]) {
4376 if (err)
4377 memprintf(err, "'%s' : missing CAkey password", args[cur_arg]);
4378 return ERR_ALERT | ERR_FATAL;
4379 }
4380 memprintf(&conf->ca_sign_pass, "%s", args[cur_arg + 1]);
4381 return 0;
4382}
4383
Willy Tarreau79eeafa2012-09-14 07:53:05 +02004384/* parse the "ciphers" bind keyword */
Willy Tarreau4348fad2012-09-20 16:48:07 +02004385static 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 +02004386{
4387 if (!*args[cur_arg + 1]) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02004388 memprintf(err, "'%s' : missing cipher suite", args[cur_arg]);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02004389 return ERR_ALERT | ERR_FATAL;
4390 }
4391
Emeric Brun76d88952012-10-05 15:47:31 +02004392 free(conf->ciphers);
Willy Tarreau4348fad2012-09-20 16:48:07 +02004393 conf->ciphers = strdup(args[cur_arg + 1]);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02004394 return 0;
4395}
4396
4397/* parse the "crt" bind keyword */
Willy Tarreau4348fad2012-09-20 16:48:07 +02004398static 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 +02004399{
Willy Tarreau38011032013-08-13 16:59:39 +02004400 char path[MAXPATHLEN];
Willy Tarreaub75d6922014-04-14 18:05:41 +02004401
Willy Tarreau79eeafa2012-09-14 07:53:05 +02004402 if (!*args[cur_arg + 1]) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02004403 memprintf(err, "'%s' : missing certificate location", args[cur_arg]);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02004404 return ERR_ALERT | ERR_FATAL;
4405 }
4406
Emeric Brunc8e8d122012-10-02 18:42:10 +02004407 if ((*args[cur_arg + 1] != '/' ) && global.crt_base) {
Willy Tarreau38011032013-08-13 16:59:39 +02004408 if ((strlen(global.crt_base) + 1 + strlen(args[cur_arg + 1]) + 1) > MAXPATHLEN) {
Emeric Brunc8e8d122012-10-02 18:42:10 +02004409 memprintf(err, "'%s' : path too long", args[cur_arg]);
4410 return ERR_ALERT | ERR_FATAL;
4411 }
Willy Tarreaub75d6922014-04-14 18:05:41 +02004412 snprintf(path, sizeof(path), "%s/%s", global.crt_base, args[cur_arg + 1]);
Emeric Brunc8e8d122012-10-02 18:42:10 +02004413 if (ssl_sock_load_cert(path, conf, px, err) > 0)
4414 return ERR_ALERT | ERR_FATAL;
4415
4416 return 0;
4417 }
4418
Willy Tarreau4348fad2012-09-20 16:48:07 +02004419 if (ssl_sock_load_cert(args[cur_arg + 1], conf, px, err) > 0)
Willy Tarreau79eeafa2012-09-14 07:53:05 +02004420 return ERR_ALERT | ERR_FATAL;
Emeric Brund94b3fe2012-09-20 18:23:56 +02004421
4422 return 0;
4423}
4424
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01004425/* parse the "crt-list" bind keyword */
4426static int bind_parse_crt_list(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
4427{
4428 if (!*args[cur_arg + 1]) {
4429 memprintf(err, "'%s' : missing certificate location", args[cur_arg]);
4430 return ERR_ALERT | ERR_FATAL;
4431 }
4432
Willy Tarreauad1731d2013-04-02 17:35:58 +02004433 if (ssl_sock_load_cert_list_file(args[cur_arg + 1], conf, px, err) > 0) {
4434 memprintf(err, "'%s' : %s", args[cur_arg], *err);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01004435 return ERR_ALERT | ERR_FATAL;
Willy Tarreauad1731d2013-04-02 17:35:58 +02004436 }
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01004437
4438 return 0;
4439}
4440
Emeric Brunfb510ea2012-10-05 12:00:26 +02004441/* parse the "crl-file" bind keyword */
4442static 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 +02004443{
Emeric Brun051cdab2012-10-02 19:25:50 +02004444#ifndef X509_V_FLAG_CRL_CHECK
4445 if (err)
4446 memprintf(err, "'%s' : library does not support CRL verify", args[cur_arg]);
4447 return ERR_ALERT | ERR_FATAL;
4448#else
Emeric Brund94b3fe2012-09-20 18:23:56 +02004449 if (!*args[cur_arg + 1]) {
4450 if (err)
4451 memprintf(err, "'%s' : missing CRLfile path", args[cur_arg]);
4452 return ERR_ALERT | ERR_FATAL;
4453 }
Emeric Brun2b58d042012-09-20 17:10:03 +02004454
Emeric Brunef42d922012-10-11 16:11:36 +02004455 if ((*args[cur_arg + 1] != '/') && global.ca_base)
4456 memprintf(&conf->crl_file, "%s/%s", global.ca_base, args[cur_arg + 1]);
4457 else
4458 memprintf(&conf->crl_file, "%s", args[cur_arg + 1]);
Emeric Brunc8e8d122012-10-02 18:42:10 +02004459
Emeric Brun2b58d042012-09-20 17:10:03 +02004460 return 0;
Emeric Brun051cdab2012-10-02 19:25:50 +02004461#endif
Emeric Brun2b58d042012-09-20 17:10:03 +02004462}
4463
4464/* parse the "ecdhe" bind keyword keywords */
4465static int bind_parse_ecdhe(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
4466{
4467#if OPENSSL_VERSION_NUMBER < 0x0090800fL
4468 if (err)
4469 memprintf(err, "'%s' : library does not support elliptic curve Diffie-Hellman (too old)", args[cur_arg]);
4470 return ERR_ALERT | ERR_FATAL;
4471#elif defined(OPENSSL_NO_ECDH)
4472 if (err)
4473 memprintf(err, "'%s' : library does not support elliptic curve Diffie-Hellman (disabled via OPENSSL_NO_ECDH)", args[cur_arg]);
4474 return ERR_ALERT | ERR_FATAL;
4475#else
4476 if (!*args[cur_arg + 1]) {
4477 if (err)
4478 memprintf(err, "'%s' : missing named curve", args[cur_arg]);
4479 return ERR_ALERT | ERR_FATAL;
4480 }
4481
4482 conf->ecdhe = strdup(args[cur_arg + 1]);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02004483
4484 return 0;
Emeric Brun2b58d042012-09-20 17:10:03 +02004485#endif
Willy Tarreau79eeafa2012-09-14 07:53:05 +02004486}
4487
Emeric Brun81c00f02012-09-21 14:31:21 +02004488/* parse the "crt_ignerr" and "ca_ignerr" bind keywords */
4489static int bind_parse_ignore_err(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
4490{
4491 int code;
4492 char *p = args[cur_arg + 1];
4493 unsigned long long *ignerr = &conf->crt_ignerr;
4494
4495 if (!*p) {
4496 if (err)
4497 memprintf(err, "'%s' : missing error IDs list", args[cur_arg]);
4498 return ERR_ALERT | ERR_FATAL;
4499 }
4500
4501 if (strcmp(args[cur_arg], "ca-ignore-err") == 0)
4502 ignerr = &conf->ca_ignerr;
4503
4504 if (strcmp(p, "all") == 0) {
4505 *ignerr = ~0ULL;
4506 return 0;
4507 }
4508
4509 while (p) {
4510 code = atoi(p);
4511 if ((code <= 0) || (code > 63)) {
4512 if (err)
4513 memprintf(err, "'%s' : ID '%d' out of range (1..63) in error IDs list '%s'",
4514 args[cur_arg], code, args[cur_arg + 1]);
4515 return ERR_ALERT | ERR_FATAL;
4516 }
4517 *ignerr |= 1ULL << code;
4518 p = strchr(p, ',');
4519 if (p)
4520 p++;
4521 }
4522
Emeric Brun2cb7ae52012-10-05 14:14:21 +02004523 return 0;
4524}
4525
4526/* parse the "force-sslv3" bind keyword */
4527static int bind_parse_force_sslv3(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
4528{
4529 conf->ssl_options |= BC_SSL_O_USE_SSLV3;
4530 return 0;
4531}
4532
4533/* parse the "force-tlsv10" bind keyword */
4534static int bind_parse_force_tlsv10(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
4535{
4536 conf->ssl_options |= BC_SSL_O_USE_TLSV10;
Emeric Brun2d0c4822012-10-02 13:45:20 +02004537 return 0;
4538}
4539
Emeric Brun2cb7ae52012-10-05 14:14:21 +02004540/* parse the "force-tlsv11" bind keyword */
4541static int bind_parse_force_tlsv11(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
4542{
4543#if SSL_OP_NO_TLSv1_1
4544 conf->ssl_options |= BC_SSL_O_USE_TLSV11;
4545 return 0;
4546#else
4547 if (err)
4548 memprintf(err, "'%s' : library does not support protocol TLSv1.1", args[cur_arg]);
4549 return ERR_ALERT | ERR_FATAL;
4550#endif
4551}
4552
4553/* parse the "force-tlsv12" bind keyword */
4554static int bind_parse_force_tlsv12(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
4555{
4556#if SSL_OP_NO_TLSv1_2
4557 conf->ssl_options |= BC_SSL_O_USE_TLSV12;
4558 return 0;
4559#else
4560 if (err)
4561 memprintf(err, "'%s' : library does not support protocol TLSv1.2", args[cur_arg]);
4562 return ERR_ALERT | ERR_FATAL;
4563#endif
4564}
4565
4566
Emeric Brun2d0c4822012-10-02 13:45:20 +02004567/* parse the "no-tls-tickets" bind keyword */
4568static int bind_parse_no_tls_tickets(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
4569{
Emeric Brun89675492012-10-05 13:48:26 +02004570 conf->ssl_options |= BC_SSL_O_NO_TLS_TICKETS;
Emeric Brun81c00f02012-09-21 14:31:21 +02004571 return 0;
4572}
4573
Emeric Brun2d0c4822012-10-02 13:45:20 +02004574
Emeric Brun9b3009b2012-10-05 11:55:06 +02004575/* parse the "no-sslv3" bind keyword */
4576static 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 +02004577{
Emeric Brun89675492012-10-05 13:48:26 +02004578 conf->ssl_options |= BC_SSL_O_NO_SSLV3;
Willy Tarreau79eeafa2012-09-14 07:53:05 +02004579 return 0;
4580}
4581
Emeric Brun9b3009b2012-10-05 11:55:06 +02004582/* parse the "no-tlsv10" bind keyword */
4583static 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 +02004584{
Emeric Brun89675492012-10-05 13:48:26 +02004585 conf->ssl_options |= BC_SSL_O_NO_TLSV10;
Emeric Brunc0ff4922012-09-28 19:37:02 +02004586 return 0;
4587}
4588
Emeric Brun9b3009b2012-10-05 11:55:06 +02004589/* parse the "no-tlsv11" bind keyword */
4590static 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 +02004591{
Emeric Brun89675492012-10-05 13:48:26 +02004592 conf->ssl_options |= BC_SSL_O_NO_TLSV11;
Emeric Brunc0ff4922012-09-28 19:37:02 +02004593 return 0;
4594}
4595
Emeric Brun9b3009b2012-10-05 11:55:06 +02004596/* parse the "no-tlsv12" bind keyword */
4597static 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 +02004598{
Emeric Brun89675492012-10-05 13:48:26 +02004599 conf->ssl_options |= BC_SSL_O_NO_TLSV12;
Willy Tarreau79eeafa2012-09-14 07:53:05 +02004600 return 0;
4601}
4602
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02004603/* parse the "npn" bind keyword */
4604static int bind_parse_npn(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
4605{
4606#ifdef OPENSSL_NPN_NEGOTIATED
4607 char *p1, *p2;
4608
4609 if (!*args[cur_arg + 1]) {
4610 memprintf(err, "'%s' : missing the comma-delimited NPN protocol suite", args[cur_arg]);
4611 return ERR_ALERT | ERR_FATAL;
4612 }
4613
4614 free(conf->npn_str);
4615
4616 /* the NPN string is built as a suite of (<len> <name>)* */
4617 conf->npn_len = strlen(args[cur_arg + 1]) + 1;
4618 conf->npn_str = calloc(1, conf->npn_len);
4619 memcpy(conf->npn_str + 1, args[cur_arg + 1], conf->npn_len);
4620
4621 /* replace commas with the name length */
4622 p1 = conf->npn_str;
4623 p2 = p1 + 1;
4624 while (1) {
4625 p2 = memchr(p1 + 1, ',', conf->npn_str + conf->npn_len - (p1 + 1));
4626 if (!p2)
4627 p2 = p1 + 1 + strlen(p1 + 1);
4628
4629 if (p2 - (p1 + 1) > 255) {
4630 *p2 = '\0';
4631 memprintf(err, "'%s' : NPN protocol name too long : '%s'", args[cur_arg], p1 + 1);
4632 return ERR_ALERT | ERR_FATAL;
4633 }
4634
4635 *p1 = p2 - (p1 + 1);
4636 p1 = p2;
4637
4638 if (!*p2)
4639 break;
4640
4641 *(p2++) = '\0';
4642 }
4643 return 0;
4644#else
4645 if (err)
4646 memprintf(err, "'%s' : library does not support TLS NPN extension", args[cur_arg]);
4647 return ERR_ALERT | ERR_FATAL;
4648#endif
4649}
4650
Willy Tarreauab861d32013-04-02 02:30:41 +02004651/* parse the "alpn" bind keyword */
4652static int bind_parse_alpn(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
4653{
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01004654#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Willy Tarreauab861d32013-04-02 02:30:41 +02004655 char *p1, *p2;
4656
4657 if (!*args[cur_arg + 1]) {
4658 memprintf(err, "'%s' : missing the comma-delimited ALPN protocol suite", args[cur_arg]);
4659 return ERR_ALERT | ERR_FATAL;
4660 }
4661
4662 free(conf->alpn_str);
4663
4664 /* the ALPN string is built as a suite of (<len> <name>)* */
4665 conf->alpn_len = strlen(args[cur_arg + 1]) + 1;
4666 conf->alpn_str = calloc(1, conf->alpn_len);
4667 memcpy(conf->alpn_str + 1, args[cur_arg + 1], conf->alpn_len);
4668
4669 /* replace commas with the name length */
4670 p1 = conf->alpn_str;
4671 p2 = p1 + 1;
4672 while (1) {
4673 p2 = memchr(p1 + 1, ',', conf->alpn_str + conf->alpn_len - (p1 + 1));
4674 if (!p2)
4675 p2 = p1 + 1 + strlen(p1 + 1);
4676
4677 if (p2 - (p1 + 1) > 255) {
4678 *p2 = '\0';
4679 memprintf(err, "'%s' : ALPN protocol name too long : '%s'", args[cur_arg], p1 + 1);
4680 return ERR_ALERT | ERR_FATAL;
4681 }
4682
4683 *p1 = p2 - (p1 + 1);
4684 p1 = p2;
4685
4686 if (!*p2)
4687 break;
4688
4689 *(p2++) = '\0';
4690 }
4691 return 0;
4692#else
4693 if (err)
4694 memprintf(err, "'%s' : library does not support TLS ALPN extension", args[cur_arg]);
4695 return ERR_ALERT | ERR_FATAL;
4696#endif
4697}
4698
Willy Tarreau79eeafa2012-09-14 07:53:05 +02004699/* parse the "ssl" bind keyword */
Willy Tarreau4348fad2012-09-20 16:48:07 +02004700static 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 +02004701{
Willy Tarreau81796be2012-09-22 19:11:47 +02004702 struct listener *l;
4703
Willy Tarreau4348fad2012-09-20 16:48:07 +02004704 conf->is_ssl = 1;
Emeric Brun76d88952012-10-05 15:47:31 +02004705
4706 if (global.listen_default_ciphers && !conf->ciphers)
4707 conf->ciphers = strdup(global.listen_default_ciphers);
Emeric Brun2c86cbf2014-10-30 15:56:50 +01004708 conf->ssl_options |= global.listen_default_ssloptions;
Emeric Brun76d88952012-10-05 15:47:31 +02004709
Willy Tarreau81796be2012-09-22 19:11:47 +02004710 list_for_each_entry(l, &conf->listeners, by_bind)
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02004711 l->xprt = &ssl_sock;
Willy Tarreau81796be2012-09-22 19:11:47 +02004712
Willy Tarreau79eeafa2012-09-14 07:53:05 +02004713 return 0;
4714}
4715
Christopher Faulet31af49d2015-06-09 17:29:50 +02004716/* parse the "generate-certificates" bind keyword */
4717static int bind_parse_generate_certs(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
4718{
4719#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
4720 conf->generate_certs = 1;
4721#else
4722 memprintf(err, "%sthis version of openssl cannot generate SSL certificates.\n",
4723 err && *err ? *err : "");
4724#endif
4725 return 0;
4726}
4727
Emmanuel Hocdet65623372013-01-24 17:17:15 +01004728/* parse the "strict-sni" bind keyword */
4729static int bind_parse_strict_sni(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
4730{
4731 conf->strict_sni = 1;
4732 return 0;
Nenad Merdanovic05552d42015-02-27 19:56:49 +01004733}
4734
4735/* parse the "tls-ticket-keys" bind keyword */
4736static int bind_parse_tls_ticket_keys(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
4737{
4738#if (defined SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB && TLS_TICKETS_NO > 0)
4739 FILE *f;
4740 int i = 0;
4741 char thisline[LINESIZE];
Nenad Merdanovic146defa2015-05-09 08:46:00 +02004742 struct tls_keys_ref *keys_ref;
Nenad Merdanovic05552d42015-02-27 19:56:49 +01004743
4744 if (!*args[cur_arg + 1]) {
4745 if (err)
4746 memprintf(err, "'%s' : missing TLS ticket keys file path", args[cur_arg]);
4747 return ERR_ALERT | ERR_FATAL;
4748 }
4749
Nenad Merdanovic200b0fa2015-05-09 08:46:01 +02004750 keys_ref = tlskeys_ref_lookup(args[cur_arg + 1]);
4751 if(keys_ref) {
4752 conf->keys_ref = keys_ref;
4753 return 0;
4754 }
4755
Nenad Merdanovic146defa2015-05-09 08:46:00 +02004756 keys_ref = malloc(sizeof(struct tls_keys_ref));
4757 keys_ref->tlskeys = malloc(TLS_TICKETS_NO * sizeof(struct tls_sess_key));
Nenad Merdanovic05552d42015-02-27 19:56:49 +01004758
4759 if ((f = fopen(args[cur_arg + 1], "r")) == NULL) {
4760 if (err)
4761 memprintf(err, "'%s' : unable to load ssl tickets keys file", args[cur_arg+1]);
4762 return ERR_ALERT | ERR_FATAL;
4763 }
4764
Nenad Merdanovic146defa2015-05-09 08:46:00 +02004765 keys_ref->filename = strdup(args[cur_arg + 1]);
4766
Nenad Merdanovic05552d42015-02-27 19:56:49 +01004767 while (fgets(thisline, sizeof(thisline), f) != NULL) {
4768 int len = strlen(thisline);
4769 /* Strip newline characters from the end */
4770 if(thisline[len - 1] == '\n')
4771 thisline[--len] = 0;
4772
4773 if(thisline[len - 1] == '\r')
4774 thisline[--len] = 0;
4775
Nenad Merdanovic146defa2015-05-09 08:46:00 +02004776 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 +01004777 if (err)
4778 memprintf(err, "'%s' : unable to decode base64 key on line %d", args[cur_arg+1], i + 1);
4779 return ERR_ALERT | ERR_FATAL;
4780 }
4781 i++;
4782 }
4783
4784 if (i < TLS_TICKETS_NO) {
4785 if (err)
4786 memprintf(err, "'%s' : please supply at least %d keys in the tls-tickets-file", args[cur_arg+1], TLS_TICKETS_NO);
4787 return ERR_ALERT | ERR_FATAL;
4788 }
4789
4790 fclose(f);
4791
4792 /* Use penultimate key for encryption, handle when TLS_TICKETS_NO = 1 */
4793 i-=2;
Nenad Merdanovic146defa2015-05-09 08:46:00 +02004794 keys_ref->tls_ticket_enc_index = i < 0 ? 0 : i;
Nenad Merdanovic200b0fa2015-05-09 08:46:01 +02004795 keys_ref->unique_id = -1;
Nenad Merdanovic146defa2015-05-09 08:46:00 +02004796 conf->keys_ref = keys_ref;
Nenad Merdanovic05552d42015-02-27 19:56:49 +01004797
Nenad Merdanovic200b0fa2015-05-09 08:46:01 +02004798 LIST_ADD(&tlskeys_reference, &keys_ref->list);
4799
Nenad Merdanovic05552d42015-02-27 19:56:49 +01004800 return 0;
4801#else
4802 if (err)
4803 memprintf(err, "'%s' : TLS ticket callback extension not supported", args[cur_arg]);
4804 return ERR_ALERT | ERR_FATAL;
4805#endif /* SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB */
Emmanuel Hocdet65623372013-01-24 17:17:15 +01004806}
4807
Emeric Brund94b3fe2012-09-20 18:23:56 +02004808/* parse the "verify" bind keyword */
4809static int bind_parse_verify(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
4810{
4811 if (!*args[cur_arg + 1]) {
4812 if (err)
4813 memprintf(err, "'%s' : missing verify method", args[cur_arg]);
4814 return ERR_ALERT | ERR_FATAL;
4815 }
4816
4817 if (strcmp(args[cur_arg + 1], "none") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01004818 conf->verify = SSL_SOCK_VERIFY_NONE;
Emeric Brund94b3fe2012-09-20 18:23:56 +02004819 else if (strcmp(args[cur_arg + 1], "optional") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01004820 conf->verify = SSL_SOCK_VERIFY_OPTIONAL;
Emeric Brund94b3fe2012-09-20 18:23:56 +02004821 else if (strcmp(args[cur_arg + 1], "required") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01004822 conf->verify = SSL_SOCK_VERIFY_REQUIRED;
Emeric Brund94b3fe2012-09-20 18:23:56 +02004823 else {
4824 if (err)
4825 memprintf(err, "'%s' : unknown verify method '%s', only 'none', 'optional', and 'required' are supported\n",
4826 args[cur_arg], args[cur_arg + 1]);
4827 return ERR_ALERT | ERR_FATAL;
4828 }
4829
4830 return 0;
4831}
4832
Willy Tarreau92faadf2012-10-10 23:04:25 +02004833/************** "server" keywords ****************/
4834
Emeric Brunef42d922012-10-11 16:11:36 +02004835/* parse the "ca-file" server keyword */
4836static int srv_parse_ca_file(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4837{
4838 if (!*args[*cur_arg + 1]) {
4839 if (err)
4840 memprintf(err, "'%s' : missing CAfile path", args[*cur_arg]);
4841 return ERR_ALERT | ERR_FATAL;
4842 }
4843
4844 if ((*args[*cur_arg + 1] != '/') && global.ca_base)
4845 memprintf(&newsrv->ssl_ctx.ca_file, "%s/%s", global.ca_base, args[*cur_arg + 1]);
4846 else
4847 memprintf(&newsrv->ssl_ctx.ca_file, "%s", args[*cur_arg + 1]);
4848
4849 return 0;
4850}
4851
Willy Tarreau92faadf2012-10-10 23:04:25 +02004852/* parse the "check-ssl" server keyword */
4853static int srv_parse_check_ssl(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4854{
4855 newsrv->check.use_ssl = 1;
4856 if (global.connect_default_ciphers && !newsrv->ssl_ctx.ciphers)
4857 newsrv->ssl_ctx.ciphers = strdup(global.connect_default_ciphers);
Emeric Brun2c86cbf2014-10-30 15:56:50 +01004858 newsrv->ssl_ctx.options |= global.connect_default_ssloptions;
Willy Tarreau92faadf2012-10-10 23:04:25 +02004859 return 0;
4860}
4861
4862/* parse the "ciphers" server keyword */
4863static int srv_parse_ciphers(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4864{
4865 if (!*args[*cur_arg + 1]) {
4866 memprintf(err, "'%s' : missing cipher suite", args[*cur_arg]);
4867 return ERR_ALERT | ERR_FATAL;
4868 }
4869
4870 free(newsrv->ssl_ctx.ciphers);
4871 newsrv->ssl_ctx.ciphers = strdup(args[*cur_arg + 1]);
4872 return 0;
4873}
4874
Emeric Brunef42d922012-10-11 16:11:36 +02004875/* parse the "crl-file" server keyword */
4876static int srv_parse_crl_file(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4877{
4878#ifndef X509_V_FLAG_CRL_CHECK
4879 if (err)
4880 memprintf(err, "'%s' : library does not support CRL verify", args[*cur_arg]);
4881 return ERR_ALERT | ERR_FATAL;
4882#else
4883 if (!*args[*cur_arg + 1]) {
4884 if (err)
4885 memprintf(err, "'%s' : missing CRLfile path", args[*cur_arg]);
4886 return ERR_ALERT | ERR_FATAL;
4887 }
4888
4889 if ((*args[*cur_arg + 1] != '/') && global.ca_base)
4890 memprintf(&newsrv->ssl_ctx.crl_file, "%s/%s", global.ca_base, args[*cur_arg + 1]);
4891 else
4892 memprintf(&newsrv->ssl_ctx.crl_file, "%s", args[*cur_arg + 1]);
4893
4894 return 0;
4895#endif
4896}
4897
Emeric Bruna7aa3092012-10-26 12:58:00 +02004898/* parse the "crt" server keyword */
4899static int srv_parse_crt(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4900{
4901 if (!*args[*cur_arg + 1]) {
4902 if (err)
4903 memprintf(err, "'%s' : missing certificate file path", args[*cur_arg]);
4904 return ERR_ALERT | ERR_FATAL;
4905 }
4906
4907 if ((*args[*cur_arg + 1] != '/') && global.crt_base)
4908 memprintf(&newsrv->ssl_ctx.client_crt, "%s/%s", global.ca_base, args[*cur_arg + 1]);
4909 else
4910 memprintf(&newsrv->ssl_ctx.client_crt, "%s", args[*cur_arg + 1]);
4911
4912 return 0;
4913}
Emeric Brunef42d922012-10-11 16:11:36 +02004914
Willy Tarreau92faadf2012-10-10 23:04:25 +02004915/* parse the "force-sslv3" server keyword */
4916static int srv_parse_force_sslv3(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4917{
4918 newsrv->ssl_ctx.options |= SRV_SSL_O_USE_SSLV3;
4919 return 0;
4920}
4921
4922/* parse the "force-tlsv10" server keyword */
4923static int srv_parse_force_tlsv10(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4924{
4925 newsrv->ssl_ctx.options |= SRV_SSL_O_USE_TLSV10;
4926 return 0;
4927}
4928
4929/* parse the "force-tlsv11" server keyword */
4930static int srv_parse_force_tlsv11(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4931{
4932#if SSL_OP_NO_TLSv1_1
4933 newsrv->ssl_ctx.options |= SRV_SSL_O_USE_TLSV11;
4934 return 0;
4935#else
4936 if (err)
4937 memprintf(err, "'%s' : library does not support protocol TLSv1.1", args[*cur_arg]);
4938 return ERR_ALERT | ERR_FATAL;
4939#endif
4940}
4941
4942/* parse the "force-tlsv12" server keyword */
4943static int srv_parse_force_tlsv12(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4944{
4945#if SSL_OP_NO_TLSv1_2
4946 newsrv->ssl_ctx.options |= SRV_SSL_O_USE_TLSV12;
4947 return 0;
4948#else
4949 if (err)
4950 memprintf(err, "'%s' : library does not support protocol TLSv1.2", args[*cur_arg]);
4951 return ERR_ALERT | ERR_FATAL;
4952#endif
4953}
4954
Willy Tarreau2a3fb1c2015-02-05 16:47:07 +01004955/* parse the "no-ssl-reuse" server keyword */
4956static int srv_parse_no_ssl_reuse(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4957{
4958 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_REUSE;
4959 return 0;
4960}
4961
Willy Tarreau92faadf2012-10-10 23:04:25 +02004962/* parse the "no-sslv3" server keyword */
4963static int srv_parse_no_sslv3(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4964{
4965 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_SSLV3;
4966 return 0;
4967}
4968
4969/* parse the "no-tlsv10" server keyword */
4970static int srv_parse_no_tlsv10(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4971{
4972 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_TLSV10;
4973 return 0;
4974}
4975
4976/* parse the "no-tlsv11" server keyword */
4977static int srv_parse_no_tlsv11(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4978{
4979 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_TLSV11;
4980 return 0;
4981}
4982
4983/* parse the "no-tlsv12" server keyword */
4984static int srv_parse_no_tlsv12(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4985{
4986 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_TLSV12;
4987 return 0;
4988}
4989
Emeric Brunf9c5c472012-10-11 15:28:34 +02004990/* parse the "no-tls-tickets" server keyword */
4991static int srv_parse_no_tls_tickets(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4992{
4993 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_TLS_TICKETS;
4994 return 0;
4995}
David Safb76832014-05-08 23:42:08 -04004996/* parse the "send-proxy-v2-ssl" server keyword */
4997static int srv_parse_send_proxy_ssl(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4998{
4999 newsrv->pp_opts |= SRV_PP_V2;
5000 newsrv->pp_opts |= SRV_PP_V2_SSL;
5001 return 0;
5002}
5003
5004/* parse the "send-proxy-v2-ssl-cn" server keyword */
5005static int srv_parse_send_proxy_cn(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5006{
5007 newsrv->pp_opts |= SRV_PP_V2;
5008 newsrv->pp_opts |= SRV_PP_V2_SSL;
5009 newsrv->pp_opts |= SRV_PP_V2_SSL_CN;
5010 return 0;
5011}
Emeric Brunf9c5c472012-10-11 15:28:34 +02005012
Willy Tarreau732eac42015-07-09 11:40:25 +02005013/* parse the "sni" server keyword */
5014static int srv_parse_sni(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5015{
5016#ifndef SSL_CTRL_SET_TLSEXT_HOSTNAME
5017 memprintf(err, "'%s' : the current SSL library doesn't support the SNI TLS extension", args[*cur_arg]);
5018 return ERR_ALERT | ERR_FATAL;
5019#else
5020 struct sample_expr *expr;
5021
5022 if (!*args[*cur_arg + 1]) {
5023 memprintf(err, "'%s' : missing sni expression", args[*cur_arg]);
5024 return ERR_ALERT | ERR_FATAL;
5025 }
5026
5027 (*cur_arg)++;
5028 proxy->conf.args.ctx = ARGC_SRV;
5029
5030 expr = sample_parse_expr((char **)args, cur_arg, px->conf.file, px->conf.line, err, &proxy->conf.args);
5031 if (!expr) {
5032 memprintf(err, "error detected while parsing sni expression : %s", *err);
5033 return ERR_ALERT | ERR_FATAL;
5034 }
5035
5036 if (!(expr->fetch->val & SMP_VAL_BE_SRV_CON)) {
5037 memprintf(err, "error detected while parsing sni expression : "
5038 " fetch method '%s' extracts information from '%s', none of which is available here.\n",
5039 args[*cur_arg-1], sample_src_names(expr->fetch->use));
5040 return ERR_ALERT | ERR_FATAL;
5041 }
5042
5043 px->http_needed |= !!(expr->fetch->use & SMP_USE_HTTP_ANY);
5044 newsrv->ssl_ctx.sni = expr;
5045 return 0;
5046#endif
5047}
5048
Willy Tarreau92faadf2012-10-10 23:04:25 +02005049/* parse the "ssl" server keyword */
5050static int srv_parse_ssl(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5051{
5052 newsrv->use_ssl = 1;
5053 if (global.connect_default_ciphers && !newsrv->ssl_ctx.ciphers)
5054 newsrv->ssl_ctx.ciphers = strdup(global.connect_default_ciphers);
5055 return 0;
5056}
5057
Emeric Brunef42d922012-10-11 16:11:36 +02005058/* parse the "verify" server keyword */
5059static int srv_parse_verify(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5060{
5061 if (!*args[*cur_arg + 1]) {
5062 if (err)
5063 memprintf(err, "'%s' : missing verify method", args[*cur_arg]);
5064 return ERR_ALERT | ERR_FATAL;
5065 }
5066
5067 if (strcmp(args[*cur_arg + 1], "none") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01005068 newsrv->ssl_ctx.verify = SSL_SOCK_VERIFY_NONE;
Emeric Brunef42d922012-10-11 16:11:36 +02005069 else if (strcmp(args[*cur_arg + 1], "required") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01005070 newsrv->ssl_ctx.verify = SSL_SOCK_VERIFY_REQUIRED;
Emeric Brunef42d922012-10-11 16:11:36 +02005071 else {
5072 if (err)
5073 memprintf(err, "'%s' : unknown verify method '%s', only 'none' and 'required' are supported\n",
5074 args[*cur_arg], args[*cur_arg + 1]);
5075 return ERR_ALERT | ERR_FATAL;
5076 }
5077
Evan Broderbe554312013-06-27 00:05:25 -07005078 return 0;
5079}
5080
5081/* parse the "verifyhost" server keyword */
5082static int srv_parse_verifyhost(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5083{
5084 if (!*args[*cur_arg + 1]) {
5085 if (err)
5086 memprintf(err, "'%s' : missing hostname to verify against", args[*cur_arg]);
5087 return ERR_ALERT | ERR_FATAL;
5088 }
5089
5090 newsrv->ssl_ctx.verify_host = strdup(args[*cur_arg + 1]);
5091
Emeric Brunef42d922012-10-11 16:11:36 +02005092 return 0;
5093}
5094
Emeric Brun2c86cbf2014-10-30 15:56:50 +01005095/* parse the "ssl-default-bind-options" keyword in global section */
5096static int ssl_parse_default_bind_options(char **args, int section_type, struct proxy *curpx,
5097 struct proxy *defpx, const char *file, int line,
5098 char **err) {
5099 int i = 1;
5100
5101 if (*(args[i]) == 0) {
5102 memprintf(err, "global statement '%s' expects an option as an argument.", args[0]);
5103 return -1;
5104 }
5105 while (*(args[i])) {
5106 if (!strcmp(args[i], "no-sslv3"))
5107 global.listen_default_ssloptions |= BC_SSL_O_NO_SSLV3;
5108 else if (!strcmp(args[i], "no-tlsv10"))
5109 global.listen_default_ssloptions |= BC_SSL_O_NO_TLSV10;
5110 else if (!strcmp(args[i], "no-tlsv11"))
5111 global.listen_default_ssloptions |= BC_SSL_O_NO_TLSV11;
5112 else if (!strcmp(args[i], "no-tlsv12"))
5113 global.listen_default_ssloptions |= BC_SSL_O_NO_TLSV12;
5114 else if (!strcmp(args[i], "force-sslv3"))
5115 global.listen_default_ssloptions |= BC_SSL_O_USE_SSLV3;
5116 else if (!strcmp(args[i], "force-tlsv10"))
5117 global.listen_default_ssloptions |= BC_SSL_O_USE_TLSV10;
5118 else if (!strcmp(args[i], "force-tlsv11")) {
5119#if SSL_OP_NO_TLSv1_1
5120 global.listen_default_ssloptions |= BC_SSL_O_USE_TLSV11;
5121#else
5122 memprintf(err, "'%s' '%s': library does not support protocol TLSv1.1", args[0], args[i]);
5123 return -1;
5124#endif
5125 }
5126 else if (!strcmp(args[i], "force-tlsv12")) {
5127#if SSL_OP_NO_TLSv1_2
5128 global.listen_default_ssloptions |= BC_SSL_O_USE_TLSV12;
5129#else
5130 memprintf(err, "'%s' '%s': library does not support protocol TLSv1.2", args[0], args[i]);
5131 return -1;
5132#endif
5133 }
5134 else if (!strcmp(args[i], "no-tls-tickets"))
5135 global.listen_default_ssloptions |= BC_SSL_O_NO_TLS_TICKETS;
5136 else {
5137 memprintf(err, "unknown option '%s' on global statement '%s'.", args[i], args[0]);
5138 return -1;
5139 }
5140 i++;
5141 }
5142 return 0;
5143}
5144
5145/* parse the "ssl-default-server-options" keyword in global section */
5146static int ssl_parse_default_server_options(char **args, int section_type, struct proxy *curpx,
5147 struct proxy *defpx, const char *file, int line,
5148 char **err) {
5149 int i = 1;
5150
5151 if (*(args[i]) == 0) {
5152 memprintf(err, "global statement '%s' expects an option as an argument.", args[0]);
5153 return -1;
5154 }
5155 while (*(args[i])) {
5156 if (!strcmp(args[i], "no-sslv3"))
5157 global.connect_default_ssloptions |= SRV_SSL_O_NO_SSLV3;
5158 else if (!strcmp(args[i], "no-tlsv10"))
5159 global.connect_default_ssloptions |= SRV_SSL_O_NO_TLSV10;
5160 else if (!strcmp(args[i], "no-tlsv11"))
5161 global.connect_default_ssloptions |= SRV_SSL_O_NO_TLSV11;
5162 else if (!strcmp(args[i], "no-tlsv12"))
5163 global.connect_default_ssloptions |= SRV_SSL_O_NO_TLSV12;
5164 else if (!strcmp(args[i], "force-sslv3"))
5165 global.connect_default_ssloptions |= SRV_SSL_O_USE_SSLV3;
5166 else if (!strcmp(args[i], "force-tlsv10"))
5167 global.connect_default_ssloptions |= SRV_SSL_O_USE_TLSV10;
5168 else if (!strcmp(args[i], "force-tlsv11")) {
5169#if SSL_OP_NO_TLSv1_1
5170 global.connect_default_ssloptions |= SRV_SSL_O_USE_TLSV11;
5171#else
5172 memprintf(err, "'%s' '%s': library does not support protocol TLSv1.1", args[0], args[i]);
5173 return -1;
5174#endif
5175 }
5176 else if (!strcmp(args[i], "force-tlsv12")) {
5177#if SSL_OP_NO_TLSv1_2
5178 global.connect_default_ssloptions |= SRV_SSL_O_USE_TLSV12;
5179#else
5180 memprintf(err, "'%s' '%s': library does not support protocol TLSv1.2", args[0], args[i]);
5181 return -1;
5182#endif
5183 }
5184 else if (!strcmp(args[i], "no-tls-tickets"))
5185 global.connect_default_ssloptions |= SRV_SSL_O_NO_TLS_TICKETS;
5186 else {
5187 memprintf(err, "unknown option '%s' on global statement '%s'.", args[i], args[0]);
5188 return -1;
5189 }
5190 i++;
5191 }
5192 return 0;
5193}
5194
Willy Tarreau7875d092012-09-10 08:20:03 +02005195/* Note: must not be declared <const> as its list will be overwritten.
5196 * Please take care of keeping this list alphabetically sorted.
5197 */
Willy Tarreaudc13c112013-06-21 23:16:39 +02005198static struct sample_fetch_kw_list sample_fetch_keywords = {ILH, {
Emeric Brun645ae792014-04-30 14:21:06 +02005199 { "ssl_bc", smp_fetch_ssl_fc, 0, NULL, SMP_T_BOOL, SMP_USE_L5SRV },
Thierry FOURNIER07ee64e2015-07-06 23:43:03 +02005200 { "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 +02005201 { "ssl_bc_cipher", smp_fetch_ssl_fc_cipher, 0, NULL, SMP_T_STR, SMP_USE_L5SRV },
5202 { "ssl_bc_protocol", smp_fetch_ssl_fc_protocol, 0, NULL, SMP_T_STR, SMP_USE_L5SRV },
Emeric Brunb73a9b02014-04-30 18:49:19 +02005203 { "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 +02005204 { "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 +02005205 { "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 +02005206 { "ssl_c_ca_err", smp_fetch_ssl_c_ca_err, 0, NULL, SMP_T_SINT, SMP_USE_L5CLI },
5207 { "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 +01005208 { "ssl_c_der", smp_fetch_ssl_x_der, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Thierry FOURNIER07ee64e2015-07-06 23:43:03 +02005209 { "ssl_c_err", smp_fetch_ssl_c_err, 0, NULL, SMP_T_SINT, SMP_USE_L5CLI },
Emeric Brunba841a12014-04-30 17:05:08 +02005210 { "ssl_c_i_dn", smp_fetch_ssl_x_i_dn, ARG2(0,STR,SINT), NULL, SMP_T_STR, SMP_USE_L5CLI },
5211 { "ssl_c_key_alg", smp_fetch_ssl_x_key_alg, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
5212 { "ssl_c_notafter", smp_fetch_ssl_x_notafter, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
5213 { "ssl_c_notbefore", smp_fetch_ssl_x_notbefore, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
5214 { "ssl_c_sig_alg", smp_fetch_ssl_x_sig_alg, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
5215 { "ssl_c_s_dn", smp_fetch_ssl_x_s_dn, ARG2(0,STR,SINT), NULL, SMP_T_STR, SMP_USE_L5CLI },
5216 { "ssl_c_serial", smp_fetch_ssl_x_serial, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
5217 { "ssl_c_sha1", smp_fetch_ssl_x_sha1, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Willy Tarreau80aca902013-01-07 15:42:20 +01005218 { "ssl_c_used", smp_fetch_ssl_c_used, 0, NULL, SMP_T_BOOL, SMP_USE_L5CLI },
Thierry FOURNIER07ee64e2015-07-06 23:43:03 +02005219 { "ssl_c_verify", smp_fetch_ssl_c_verify, 0, NULL, SMP_T_SINT, SMP_USE_L5CLI },
5220 { "ssl_c_version", smp_fetch_ssl_x_version, 0, NULL, SMP_T_SINT, SMP_USE_L5CLI },
Emeric Brun43e79582014-10-29 19:03:26 +01005221 { "ssl_f_der", smp_fetch_ssl_x_der, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Emeric Brunba841a12014-04-30 17:05:08 +02005222 { "ssl_f_i_dn", smp_fetch_ssl_x_i_dn, ARG2(0,STR,SINT), NULL, SMP_T_STR, SMP_USE_L5CLI },
5223 { "ssl_f_key_alg", smp_fetch_ssl_x_key_alg, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
5224 { "ssl_f_notafter", smp_fetch_ssl_x_notafter, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
5225 { "ssl_f_notbefore", smp_fetch_ssl_x_notbefore, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
5226 { "ssl_f_sig_alg", smp_fetch_ssl_x_sig_alg, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
5227 { "ssl_f_s_dn", smp_fetch_ssl_x_s_dn, ARG2(0,STR,SINT), NULL, SMP_T_STR, SMP_USE_L5CLI },
5228 { "ssl_f_serial", smp_fetch_ssl_x_serial, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Emeric Brun55f4fa82014-04-30 17:11:25 +02005229 { "ssl_f_sha1", smp_fetch_ssl_x_sha1, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Thierry FOURNIER07ee64e2015-07-06 23:43:03 +02005230 { "ssl_f_version", smp_fetch_ssl_x_version, 0, NULL, SMP_T_SINT, SMP_USE_L5CLI },
Willy Tarreau80aca902013-01-07 15:42:20 +01005231 { "ssl_fc", smp_fetch_ssl_fc, 0, NULL, SMP_T_BOOL, SMP_USE_L5CLI },
Thierry FOURNIER07ee64e2015-07-06 23:43:03 +02005232 { "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 +01005233 { "ssl_fc_cipher", smp_fetch_ssl_fc_cipher, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Willy Tarreau80aca902013-01-07 15:42:20 +01005234 { "ssl_fc_has_crt", smp_fetch_ssl_fc_has_crt, 0, NULL, SMP_T_BOOL, SMP_USE_L5CLI },
5235 { "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 +02005236 { "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 +02005237#ifdef OPENSSL_NPN_NEGOTIATED
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01005238 { "ssl_fc_npn", smp_fetch_ssl_fc_npn, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Willy Tarreaua33c6542012-10-15 13:19:06 +02005239#endif
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01005240#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01005241 { "ssl_fc_alpn", smp_fetch_ssl_fc_alpn, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Willy Tarreauab861d32013-04-02 02:30:41 +02005242#endif
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01005243 { "ssl_fc_protocol", smp_fetch_ssl_fc_protocol, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Emeric Brunb73a9b02014-04-30 18:49:19 +02005244 { "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 +02005245 { "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 +01005246 { "ssl_fc_session_id", smp_fetch_ssl_fc_session_id, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
5247 { "ssl_fc_sni", smp_fetch_ssl_fc_sni, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Willy Tarreau7875d092012-09-10 08:20:03 +02005248 { NULL, NULL, 0, 0, 0 },
5249}};
5250
5251/* Note: must not be declared <const> as its list will be overwritten.
5252 * Please take care of keeping this list alphabetically sorted.
5253 */
Willy Tarreaudc13c112013-06-21 23:16:39 +02005254static struct acl_kw_list acl_kws = {ILH, {
Thierry FOURNIERc5a4e982014-03-05 16:07:08 +01005255 { "ssl_fc_sni_end", "ssl_fc_sni", PAT_MATCH_END },
5256 { "ssl_fc_sni_reg", "ssl_fc_sni", PAT_MATCH_REG },
Willy Tarreau8ed669b2013-01-11 15:49:37 +01005257 { /* END */ },
Willy Tarreau7875d092012-09-10 08:20:03 +02005258}};
5259
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005260/* Note: must not be declared <const> as its list will be overwritten.
5261 * Please take care of keeping this list alphabetically sorted, doing so helps
5262 * all code contributors.
5263 * Optional keywords are also declared with a NULL ->parse() function so that
5264 * the config parser can report an appropriate error when a known keyword was
5265 * not enabled.
5266 */
Willy Tarreau51fb7652012-09-18 18:24:39 +02005267static struct bind_kw_list bind_kws = { "SSL", { }, {
Nenad Merdanovic05552d42015-02-27 19:56:49 +01005268 { "alpn", bind_parse_alpn, 1 }, /* set ALPN supported protocols */
5269 { "ca-file", bind_parse_ca_file, 1 }, /* set CAfile to process verify on client cert */
5270 { "ca-ignore-err", bind_parse_ignore_err, 1 }, /* set error IDs to ignore on verify depth > 0 */
Christopher Faulet31af49d2015-06-09 17:29:50 +02005271 { "ca-sign-file", bind_parse_ca_sign_file, 1 }, /* set CAFile used to generate and sign server certs */
5272 { "ca-sign-pass", bind_parse_ca_sign_pass, 1 }, /* set CAKey passphrase */
Nenad Merdanovic05552d42015-02-27 19:56:49 +01005273 { "ciphers", bind_parse_ciphers, 1 }, /* set SSL cipher suite */
5274 { "crl-file", bind_parse_crl_file, 1 }, /* set certificat revocation list file use on client cert verify */
5275 { "crt", bind_parse_crt, 1 }, /* load SSL certificates from this location */
5276 { "crt-ignore-err", bind_parse_ignore_err, 1 }, /* set error IDs to ingore on verify depth == 0 */
5277 { "crt-list", bind_parse_crt_list, 1 }, /* load a list of crt from this location */
5278 { "ecdhe", bind_parse_ecdhe, 1 }, /* defines named curve for elliptic curve Diffie-Hellman */
5279 { "force-sslv3", bind_parse_force_sslv3, 0 }, /* force SSLv3 */
5280 { "force-tlsv10", bind_parse_force_tlsv10, 0 }, /* force TLSv10 */
5281 { "force-tlsv11", bind_parse_force_tlsv11, 0 }, /* force TLSv11 */
5282 { "force-tlsv12", bind_parse_force_tlsv12, 0 }, /* force TLSv12 */
Christopher Faulet31af49d2015-06-09 17:29:50 +02005283 { "generate-certificates", bind_parse_generate_certs, 0 }, /* enable the server certificates generation */
Nenad Merdanovic05552d42015-02-27 19:56:49 +01005284 { "no-sslv3", bind_parse_no_sslv3, 0 }, /* disable SSLv3 */
5285 { "no-tlsv10", bind_parse_no_tlsv10, 0 }, /* disable TLSv10 */
5286 { "no-tlsv11", bind_parse_no_tlsv11, 0 }, /* disable TLSv11 */
5287 { "no-tlsv12", bind_parse_no_tlsv12, 0 }, /* disable TLSv12 */
5288 { "no-tls-tickets", bind_parse_no_tls_tickets, 0 }, /* disable session resumption tickets */
5289 { "ssl", bind_parse_ssl, 0 }, /* enable SSL processing */
5290 { "strict-sni", bind_parse_strict_sni, 0 }, /* refuse negotiation if sni doesn't match a certificate */
5291 { "tls-ticket-keys", bind_parse_tls_ticket_keys, 1 }, /* set file to load TLS ticket keys from */
5292 { "verify", bind_parse_verify, 1 }, /* set SSL verify method */
5293 { "npn", bind_parse_npn, 1 }, /* set NPN supported protocols */
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005294 { NULL, NULL, 0 },
5295}};
Emeric Brun46591952012-05-18 15:47:34 +02005296
Willy Tarreau92faadf2012-10-10 23:04:25 +02005297/* Note: must not be declared <const> as its list will be overwritten.
5298 * Please take care of keeping this list alphabetically sorted, doing so helps
5299 * all code contributors.
5300 * Optional keywords are also declared with a NULL ->parse() function so that
5301 * the config parser can report an appropriate error when a known keyword was
5302 * not enabled.
5303 */
5304static struct srv_kw_list srv_kws = { "SSL", { }, {
Emeric Brunef42d922012-10-11 16:11:36 +02005305 { "ca-file", srv_parse_ca_file, 1, 0 }, /* set CAfile to process verify server cert */
Emeric Brunecc91fe2012-10-11 15:05:10 +02005306 { "check-ssl", srv_parse_check_ssl, 0, 0 }, /* enable SSL for health checks */
5307 { "ciphers", srv_parse_ciphers, 1, 0 }, /* select the cipher suite */
Emeric Brunef42d922012-10-11 16:11:36 +02005308 { "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 +02005309 { "crt", srv_parse_crt, 1, 0 }, /* set client certificate */
Emeric Brunecc91fe2012-10-11 15:05:10 +02005310 { "force-sslv3", srv_parse_force_sslv3, 0, 0 }, /* force SSLv3 */
5311 { "force-tlsv10", srv_parse_force_tlsv10, 0, 0 }, /* force TLSv10 */
5312 { "force-tlsv11", srv_parse_force_tlsv11, 0, 0 }, /* force TLSv11 */
5313 { "force-tlsv12", srv_parse_force_tlsv12, 0, 0 }, /* force TLSv12 */
Willy Tarreau2a3fb1c2015-02-05 16:47:07 +01005314 { "no-ssl-reuse", srv_parse_no_ssl_reuse, 0, 0 }, /* disable session reuse */
Emeric Brunecc91fe2012-10-11 15:05:10 +02005315 { "no-sslv3", srv_parse_no_sslv3, 0, 0 }, /* disable SSLv3 */
5316 { "no-tlsv10", srv_parse_no_tlsv10, 0, 0 }, /* disable TLSv10 */
5317 { "no-tlsv11", srv_parse_no_tlsv11, 0, 0 }, /* disable TLSv11 */
5318 { "no-tlsv12", srv_parse_no_tlsv12, 0, 0 }, /* disable TLSv12 */
Emeric Brunf9c5c472012-10-11 15:28:34 +02005319 { "no-tls-tickets", srv_parse_no_tls_tickets, 0, 0 }, /* disable session resumption tickets */
David Safb76832014-05-08 23:42:08 -04005320 { "send-proxy-v2-ssl", srv_parse_send_proxy_ssl, 0, 0 }, /* send PROXY protocol header v2 with SSL info */
5321 { "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 +02005322 { "sni", srv_parse_sni, 1, 0 }, /* send SNI extension */
Emeric Brunecc91fe2012-10-11 15:05:10 +02005323 { "ssl", srv_parse_ssl, 0, 0 }, /* enable SSL processing */
Emeric Brunef42d922012-10-11 16:11:36 +02005324 { "verify", srv_parse_verify, 1, 0 }, /* set SSL verify method */
Evan Broderbe554312013-06-27 00:05:25 -07005325 { "verifyhost", srv_parse_verifyhost, 1, 0 }, /* require that SSL cert verifies for hostname */
Willy Tarreau92faadf2012-10-10 23:04:25 +02005326 { NULL, NULL, 0, 0 },
5327}};
5328
Emeric Brun2c86cbf2014-10-30 15:56:50 +01005329static struct cfg_kw_list cfg_kws = {ILH, {
5330 { CFG_GLOBAL, "ssl-default-bind-options", ssl_parse_default_bind_options },
5331 { CFG_GLOBAL, "ssl-default-server-options", ssl_parse_default_server_options },
5332 { 0, NULL, NULL },
5333}};
5334
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02005335/* transport-layer operations for SSL sockets */
5336struct xprt_ops ssl_sock = {
Emeric Brun46591952012-05-18 15:47:34 +02005337 .snd_buf = ssl_sock_from_buf,
5338 .rcv_buf = ssl_sock_to_buf,
5339 .rcv_pipe = NULL,
5340 .snd_pipe = NULL,
5341 .shutr = NULL,
5342 .shutw = ssl_sock_shutw,
5343 .close = ssl_sock_close,
5344 .init = ssl_sock_init,
5345};
5346
Janusz Dziemidowicz2c701b52015-03-07 23:03:59 +01005347#if (OPENSSL_VERSION_NUMBER >= 0x1000200fL && !defined OPENSSL_NO_TLSEXT && !defined OPENSSL_IS_BORINGSSL)
5348
5349static void ssl_sock_sctl_free_func(void *parent, void *ptr, CRYPTO_EX_DATA *ad, int idx, long argl, void *argp)
5350{
5351 if (ptr) {
5352 chunk_destroy(ptr);
5353 free(ptr);
5354 }
5355}
5356
5357#endif
5358
Emeric Brun46591952012-05-18 15:47:34 +02005359__attribute__((constructor))
Willy Tarreau92faadf2012-10-10 23:04:25 +02005360static void __ssl_sock_init(void)
5361{
Emeric Brun46591952012-05-18 15:47:34 +02005362 STACK_OF(SSL_COMP)* cm;
5363
Willy Tarreau610f04b2014-02-13 11:36:41 +01005364#ifdef LISTEN_DEFAULT_CIPHERS
5365 global.listen_default_ciphers = LISTEN_DEFAULT_CIPHERS;
5366#endif
5367#ifdef CONNECT_DEFAULT_CIPHERS
5368 global.connect_default_ciphers = CONNECT_DEFAULT_CIPHERS;
5369#endif
5370 if (global.listen_default_ciphers)
5371 global.listen_default_ciphers = strdup(global.listen_default_ciphers);
5372 if (global.connect_default_ciphers)
5373 global.connect_default_ciphers = strdup(global.connect_default_ciphers);
Emeric Brun2c86cbf2014-10-30 15:56:50 +01005374 global.listen_default_ssloptions = BC_SSL_O_NONE;
5375 global.connect_default_ssloptions = SRV_SSL_O_NONE;
Willy Tarreau610f04b2014-02-13 11:36:41 +01005376
Emeric Brun46591952012-05-18 15:47:34 +02005377 SSL_library_init();
5378 cm = SSL_COMP_get_compression_methods();
5379 sk_SSL_COMP_zero(cm);
Janusz Dziemidowicz2c701b52015-03-07 23:03:59 +01005380#if (OPENSSL_VERSION_NUMBER >= 0x1000200fL && !defined OPENSSL_NO_TLSEXT && !defined OPENSSL_IS_BORINGSSL)
5381 sctl_ex_index = SSL_CTX_get_ex_new_index(0, NULL, NULL, NULL, ssl_sock_sctl_free_func);
5382#endif
Willy Tarreau7875d092012-09-10 08:20:03 +02005383 sample_register_fetches(&sample_fetch_keywords);
5384 acl_register_keywords(&acl_kws);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005385 bind_register_keywords(&bind_kws);
Willy Tarreau92faadf2012-10-10 23:04:25 +02005386 srv_register_keywords(&srv_kws);
Emeric Brun2c86cbf2014-10-30 15:56:50 +01005387 cfg_register_keywords(&cfg_kws);
Willy Tarreaud92aa5c2015-01-15 21:34:39 +01005388
5389 global.ssl_session_max_cost = SSL_SESSION_MAX_COST;
5390 global.ssl_handshake_max_cost = SSL_HANDSHAKE_MAX_COST;
Remi Gacogne4f902b82015-05-28 16:23:00 +02005391
5392#ifndef OPENSSL_NO_DH
5393 ssl_dh_ptr_index = SSL_CTX_get_ex_new_index(0, NULL, NULL, NULL, NULL);
5394#endif
Emeric Brun46591952012-05-18 15:47:34 +02005395}
5396
Remi Gacogned3a23c32015-05-28 16:39:47 +02005397__attribute__((destructor))
5398static void __ssl_sock_deinit(void)
5399{
Willy Tarreaua84c2672015-10-09 12:10:13 +02005400#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Christopher Faulet31af49d2015-06-09 17:29:50 +02005401 lru64_destroy(ssl_ctx_lru_tree);
Willy Tarreaua84c2672015-10-09 12:10:13 +02005402#endif
Christopher Faulet31af49d2015-06-09 17:29:50 +02005403
Remi Gacogned3a23c32015-05-28 16:39:47 +02005404#ifndef OPENSSL_NO_DH
5405 if (local_dh_1024) {
5406 DH_free(local_dh_1024);
5407 local_dh_1024 = NULL;
5408 }
5409
5410 if (local_dh_2048) {
5411 DH_free(local_dh_2048);
5412 local_dh_2048 = NULL;
5413 }
5414
5415 if (local_dh_4096) {
5416 DH_free(local_dh_4096);
5417 local_dh_4096 = NULL;
5418 }
5419
Remi Gacogne47783ef2015-05-29 15:53:22 +02005420 if (global_dh) {
5421 DH_free(global_dh);
5422 global_dh = NULL;
5423 }
Remi Gacogned3a23c32015-05-28 16:39:47 +02005424#endif
5425
5426 ERR_remove_state(0);
5427 ERR_free_strings();
5428
5429 EVP_cleanup();
5430
5431#if OPENSSL_VERSION_NUMBER >= 0x00907000L
5432 CRYPTO_cleanup_all_ex_data();
5433#endif
5434}
5435
5436
Emeric Brun46591952012-05-18 15:47:34 +02005437/*
5438 * Local variables:
5439 * c-indent-level: 8
5440 * c-basic-offset: 8
5441 * End:
5442 */