blob: e3c21a431eaf89ea66ae7ca44860114e945f86c4 [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>
38
39#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>
Emeric Brun4147b2e2014-06-16 18:36:30 +020047#ifdef SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB
48#include <openssl/ocsp.h>
49#endif
Remi Gacogne5d769ca2015-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
54#include <common/buffer.h>
55#include <common/compat.h>
56#include <common/config.h>
57#include <common/debug.h>
Willy Tarreau79eeafa2012-09-14 07:53:05 +020058#include <common/errors.h>
Emeric Brun46591952012-05-18 15:47:34 +020059#include <common/standard.h>
60#include <common/ticks.h>
61#include <common/time.h>
Emeric Brun42a3e202014-10-30 15:56:50 +010062#include <common/cfgparse.h>
Emeric Brun46591952012-05-18 15:47:34 +020063
Emeric Brunfc0421f2012-09-07 17:30:07 +020064#include <ebsttree.h>
65
66#include <types/global.h>
67#include <types/ssl_sock.h>
68
Willy Tarreau7875d092012-09-10 08:20:03 +020069#include <proto/acl.h>
70#include <proto/arg.h>
Emeric Brun46591952012-05-18 15:47:34 +020071#include <proto/connection.h>
72#include <proto/fd.h>
73#include <proto/freq_ctr.h>
74#include <proto/frontend.h>
Willy Tarreau79eeafa2012-09-14 07:53:05 +020075#include <proto/listener.h>
Thierry FOURNIERed66c292013-11-28 11:05:19 +010076#include <proto/pattern.h>
Willy Tarreau92faadf2012-10-10 23:04:25 +020077#include <proto/server.h>
Emeric Brun46591952012-05-18 15:47:34 +020078#include <proto/log.h>
Emeric Brun94324a42012-10-11 14:00:19 +020079#include <proto/proxy.h>
Emeric Brunfc0421f2012-09-07 17:30:07 +020080#include <proto/shctx.h>
Emeric Brun46591952012-05-18 15:47:34 +020081#include <proto/ssl_sock.h>
82#include <proto/task.h>
83
Willy Tarreau518cedd2014-02-17 15:43:01 +010084/* Warning, these are bits, not integers! */
Emeric Brune64aef12012-09-21 13:15:06 +020085#define SSL_SOCK_ST_FL_VERIFY_DONE 0x00000001
Emeric Brund8b2bb52014-01-28 15:43:53 +010086#define SSL_SOCK_ST_FL_16K_WBFSIZE 0x00000002
Willy Tarreau518cedd2014-02-17 15:43:01 +010087#define SSL_SOCK_SEND_UNLIMITED 0x00000004
Emeric Brun29f037d2014-04-25 19:05:36 +020088#define SSL_SOCK_RECV_HEARTBEAT 0x00000008
89
Emeric Brunf282a812012-09-21 15:27:54 +020090/* bits 0xFFFF0000 are reserved to store verify errors */
91
92/* Verify errors macros */
93#define SSL_SOCK_CA_ERROR_TO_ST(e) (((e > 63) ? 63 : e) << (16))
94#define SSL_SOCK_CAEDEPTH_TO_ST(d) (((d > 15) ? 15 : d) << (6+16))
95#define SSL_SOCK_CRTERROR_TO_ST(e) (((e > 63) ? 63 : e) << (4+6+16))
96
97#define SSL_SOCK_ST_TO_CA_ERROR(s) ((s >> (16)) & 63)
98#define SSL_SOCK_ST_TO_CAEDEPTH(s) ((s >> (6+16)) & 15)
99#define SSL_SOCK_ST_TO_CRTERROR(s) ((s >> (4+6+16)) & 63)
Emeric Brune64aef12012-09-21 13:15:06 +0200100
Emeric Brun850efd52014-01-29 12:24:34 +0100101/* server and bind verify method, it uses a global value as default */
102enum {
103 SSL_SOCK_VERIFY_DEFAULT = 0,
104 SSL_SOCK_VERIFY_REQUIRED = 1,
105 SSL_SOCK_VERIFY_OPTIONAL = 2,
106 SSL_SOCK_VERIFY_NONE = 3,
107};
108
Willy Tarreau71b734c2014-01-28 15:19:44 +0100109int sslconns = 0;
110int totalsslconns = 0;
Emeric Brune1f38db2012-09-03 20:36:47 +0200111
Remi Gacogne60d7aeb2014-07-15 11:36:40 +0200112#ifndef OPENSSL_NO_DH
Remi Gacogne5d769ca2015-05-28 16:23:00 +0200113static int ssl_dh_ptr_index = -1;
Remi Gacogne60d7aeb2014-07-15 11:36:40 +0200114static DH *local_dh_1024 = NULL;
115static DH *local_dh_2048 = NULL;
116static DH *local_dh_4096 = NULL;
Remi Gacogne60d7aeb2014-07-15 11:36:40 +0200117#endif /* OPENSSL_NO_DH */
118
Emeric Brun4147b2e2014-06-16 18:36:30 +0200119#ifdef SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB
120struct certificate_ocsp {
121 struct ebmb_node key;
122 unsigned char key_data[OCSP_MAX_CERTID_ASN1_LENGTH];
123 struct chunk response;
Emeric Brun58484372014-06-20 15:46:13 +0200124 long expire;
Emeric Brun4147b2e2014-06-16 18:36:30 +0200125};
126
Emeric Brun58484372014-06-20 15:46:13 +0200127/*
128 * This function returns the number of seconds elapsed
129 * since the Epoch, 1970-01-01 00:00:00 +0000 (UTC) and the
130 * date presented un ASN1_GENERALIZEDTIME.
131 *
132 * In parsing error case, it returns -1.
133 */
134static long asn1_generalizedtime_to_epoch(ASN1_GENERALIZEDTIME *d)
135{
136 long epoch;
137 char *p, *end;
138 const unsigned short month_offset[12] = {
139 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334
140 };
141 int year, month;
142
143 if (!d || (d->type != V_ASN1_GENERALIZEDTIME)) return -1;
144
145 p = (char *)d->data;
146 end = p + d->length;
147
148 if (end - p < 4) return -1;
149 year = 1000 * (p[0] - '0') + 100 * (p[1] - '0') + 10 * (p[2] - '0') + p[3] - '0';
150 p += 4;
151 if (end - p < 2) return -1;
152 month = 10 * (p[0] - '0') + p[1] - '0';
153 if (month < 1 || month > 12) return -1;
154 /* Compute the number of seconds since 1 jan 1970 and the beginning of current month
155 We consider leap years and the current month (<marsh or not) */
156 epoch = ( ((year - 1970) * 365)
157 + ((year - (month < 3)) / 4 - (year - (month < 3)) / 100 + (year - (month < 3)) / 400)
158 - ((1970 - 1) / 4 - (1970 - 1) / 100 + (1970 - 1) / 400)
159 + month_offset[month-1]
160 ) * 24 * 60 * 60;
161 p += 2;
162 if (end - p < 2) return -1;
163 /* Add the number of seconds of completed days of current month */
164 epoch += (10 * (p[0] - '0') + p[1] - '0' - 1) * 24 * 60 * 60;
165 p += 2;
166 if (end - p < 2) return -1;
167 /* Add the completed hours of the current day */
168 epoch += (10 * (p[0] - '0') + p[1] - '0') * 60 * 60;
169 p += 2;
170 if (end - p < 2) return -1;
171 /* Add the completed minutes of the current hour */
172 epoch += (10 * (p[0] - '0') + p[1] - '0') * 60;
173 p += 2;
174 if (p == end) return -1;
175 /* Test if there is available seconds */
176 if (p[0] < '0' || p[0] > '9')
177 goto nosec;
178 if (end - p < 2) return -1;
179 /* Add the seconds of the current minute */
180 epoch += 10 * (p[0] - '0') + p[1] - '0';
181 p += 2;
182 if (p == end) return -1;
183 /* Ignore seconds float part if present */
184 if (p[0] == '.') {
185 do {
186 if (++p == end) return -1;
187 } while (p[0] >= '0' && p[0] <= '9');
188 }
189
190nosec:
191 if (p[0] == 'Z') {
192 if (end - p != 1) return -1;
193 return epoch;
194 }
195 else if (p[0] == '+') {
196 if (end - p != 5) return -1;
197 /* Apply timezone offset */
198 return epoch - ((10 * (p[1] - '0') + p[2] - '0') * 60 + (10 * (p[3] - '0') + p[4] - '0')) * 60;
199 }
200 else if (p[0] == '-') {
201 if (end - p != 5) return -1;
202 /* Apply timezone offset */
203 return epoch + ((10 * (p[1] - '0') + p[2] - '0') * 60 + (10 * (p[3] - '0') + p[4] - '0')) * 60;
204 }
205
206 return -1;
207}
208
Emeric Brun8d914d12014-06-20 15:37:32 +0200209static struct eb_root cert_ocsp_tree = EB_ROOT_UNIQUE;
Emeric Brun4147b2e2014-06-16 18:36:30 +0200210
211/* This function starts to check if the OCSP response (in DER format) contained
212 * in chunk 'ocsp_response' is valid (else exits on error).
213 * If 'cid' is not NULL, it will be compared to the OCSP certificate ID
214 * contained in the OCSP Response and exits on error if no match.
215 * If it's a valid OCSP Response:
216 * If 'ocsp' is not NULL, the chunk is copied in the OCSP response's container
217 * pointed by 'ocsp'.
218 * If 'ocsp' is NULL, the function looks up into the OCSP response's
219 * containers tree (using as index the ASN1 form of the OCSP Certificate ID extracted
220 * from the response) and exits on error if not found. Finally, If an OCSP response is
221 * already present in the container, it will be overwritten.
222 *
223 * Note: OCSP response containing more than one OCSP Single response is not
224 * considered valid.
225 *
226 * Returns 0 on success, 1 in error case.
227 */
228static int ssl_sock_load_ocsp_response(struct chunk *ocsp_response, struct certificate_ocsp *ocsp, OCSP_CERTID *cid, char **err)
229{
230 OCSP_RESPONSE *resp;
231 OCSP_BASICRESP *bs = NULL;
232 OCSP_SINGLERESP *sr;
233 unsigned char *p = (unsigned char *)ocsp_response->str;
234 int rc , count_sr;
Emeric Brun1135ea42014-06-20 15:44:34 +0200235 ASN1_GENERALIZEDTIME *revtime, *thisupd, *nextupd = NULL;
Emeric Brun4147b2e2014-06-16 18:36:30 +0200236 int reason;
237 int ret = 1;
238
239 resp = d2i_OCSP_RESPONSE(NULL, (const unsigned char **)&p, ocsp_response->len);
240 if (!resp) {
241 memprintf(err, "Unable to parse OCSP response");
242 goto out;
243 }
244
245 rc = OCSP_response_status(resp);
246 if (rc != OCSP_RESPONSE_STATUS_SUCCESSFUL) {
247 memprintf(err, "OCSP response status not successful");
248 goto out;
249 }
250
251 bs = OCSP_response_get1_basic(resp);
252 if (!bs) {
253 memprintf(err, "Failed to get basic response from OCSP Response");
254 goto out;
255 }
256
257 count_sr = OCSP_resp_count(bs);
258 if (count_sr > 1) {
259 memprintf(err, "OCSP response ignored because contains multiple single responses (%d)", count_sr);
260 goto out;
261 }
262
263 sr = OCSP_resp_get0(bs, 0);
264 if (!sr) {
265 memprintf(err, "Failed to get OCSP single response");
266 goto out;
267 }
268
269 rc = OCSP_single_get0_status(sr, &reason, &revtime, &thisupd, &nextupd);
270 if (rc != V_OCSP_CERTSTATUS_GOOD) {
271 memprintf(err, "OCSP single response: certificate status not good");
272 goto out;
273 }
274
Emeric Brun1135ea42014-06-20 15:44:34 +0200275 if (!nextupd) {
276 memprintf(err, "OCSP single response: missing nextupdate");
277 goto out;
278 }
279
Emeric Brunc8b27b62014-06-19 14:16:17 +0200280 rc = OCSP_check_validity(thisupd, nextupd, OCSP_MAX_RESPONSE_TIME_SKEW, -1);
Emeric Brun4147b2e2014-06-16 18:36:30 +0200281 if (!rc) {
282 memprintf(err, "OCSP single response: no longer valid.");
283 goto out;
284 }
285
286 if (cid) {
287 if (OCSP_id_cmp(sr->certId, cid)) {
288 memprintf(err, "OCSP single response: Certificate ID does not match certificate and issuer");
289 goto out;
290 }
291 }
292
293 if (!ocsp) {
294 unsigned char key[OCSP_MAX_CERTID_ASN1_LENGTH];
295 unsigned char *p;
296
297 rc = i2d_OCSP_CERTID(sr->certId, NULL);
298 if (!rc) {
299 memprintf(err, "OCSP single response: Unable to encode Certificate ID");
300 goto out;
301 }
302
303 if (rc > OCSP_MAX_CERTID_ASN1_LENGTH) {
304 memprintf(err, "OCSP single response: Certificate ID too long");
305 goto out;
306 }
307
308 p = key;
309 memset(key, 0, OCSP_MAX_CERTID_ASN1_LENGTH);
310 i2d_OCSP_CERTID(sr->certId, &p);
311 ocsp = (struct certificate_ocsp *)ebmb_lookup(&cert_ocsp_tree, key, OCSP_MAX_CERTID_ASN1_LENGTH);
312 if (!ocsp) {
313 memprintf(err, "OCSP single response: Certificate ID does not match any certificate or issuer");
314 goto out;
315 }
316 }
317
318 /* According to comments on "chunk_dup", the
319 previous chunk buffer will be freed */
320 if (!chunk_dup(&ocsp->response, ocsp_response)) {
321 memprintf(err, "OCSP response: Memory allocation error");
322 goto out;
323 }
324
Emeric Brun58484372014-06-20 15:46:13 +0200325 ocsp->expire = asn1_generalizedtime_to_epoch(nextupd) - OCSP_MAX_RESPONSE_TIME_SKEW;
326
Emeric Brun4147b2e2014-06-16 18:36:30 +0200327 ret = 0;
328out:
329 if (bs)
330 OCSP_BASICRESP_free(bs);
331
332 if (resp)
333 OCSP_RESPONSE_free(resp);
334
335 return ret;
336}
337/*
338 * External function use to update the OCSP response in the OCSP response's
339 * containers tree. The chunk 'ocsp_response' must contain the OCSP response
340 * to update in DER format.
341 *
342 * Returns 0 on success, 1 in error case.
343 */
344int ssl_sock_update_ocsp_response(struct chunk *ocsp_response, char **err)
345{
346 return ssl_sock_load_ocsp_response(ocsp_response, NULL, NULL, err);
347}
348
349/*
350 * This function load the OCSP Resonse in DER format contained in file at
351 * path 'ocsp_path' and call 'ssl_sock_load_ocsp_response'
352 *
353 * Returns 0 on success, 1 in error case.
354 */
355static int ssl_sock_load_ocsp_response_from_file(const char *ocsp_path, struct certificate_ocsp *ocsp, OCSP_CERTID *cid, char **err)
356{
357 int fd = -1;
358 int r = 0;
359 int ret = 1;
360
361 fd = open(ocsp_path, O_RDONLY);
362 if (fd == -1) {
363 memprintf(err, "Error opening OCSP response file");
364 goto end;
365 }
366
367 trash.len = 0;
368 while (trash.len < trash.size) {
369 r = read(fd, trash.str + trash.len, trash.size - trash.len);
370 if (r < 0) {
371 if (errno == EINTR)
372 continue;
373
374 memprintf(err, "Error reading OCSP response from file");
375 goto end;
376 }
377 else if (r == 0) {
378 break;
379 }
380 trash.len += r;
381 }
382
383 close(fd);
384 fd = -1;
385
386 ret = ssl_sock_load_ocsp_response(&trash, ocsp, cid, err);
387end:
388 if (fd != -1)
389 close(fd);
390
391 return ret;
392}
393
394/*
395 * Callback used to set OCSP status extension content in server hello.
396 */
397int ssl_sock_ocsp_stapling_cbk(SSL *ssl, void *arg)
398{
399 struct certificate_ocsp *ocsp = (struct certificate_ocsp *)arg;
400 char* ssl_buf;
401
402 if (!ocsp ||
403 !ocsp->response.str ||
Emeric Brun58484372014-06-20 15:46:13 +0200404 !ocsp->response.len ||
405 (ocsp->expire < now.tv_sec))
Emeric Brun4147b2e2014-06-16 18:36:30 +0200406 return SSL_TLSEXT_ERR_NOACK;
407
408 ssl_buf = OPENSSL_malloc(ocsp->response.len);
409 if (!ssl_buf)
410 return SSL_TLSEXT_ERR_NOACK;
411
412 memcpy(ssl_buf, ocsp->response.str, ocsp->response.len);
413 SSL_set_tlsext_status_ocsp_resp(ssl, ssl_buf, ocsp->response.len);
414
415 return SSL_TLSEXT_ERR_OK;
416}
417
418/*
419 * This function enables the handling of OCSP status extension on 'ctx' if a
420 * file name 'cert_path' suffixed using ".ocsp" is present.
421 * To enable OCSP status extension, the issuer's certificate is mandatory.
422 * It should be present in the certificate's extra chain builded from file
423 * 'cert_path'. If not found, the issuer certificate is loaded from a file
424 * named 'cert_path' suffixed using '.issuer'.
425 *
426 * In addition, ".ocsp" file content is loaded as a DER format of an OCSP
427 * response. If file is empty or content is not a valid OCSP response,
428 * OCSP status extension is enabled but OCSP response is ignored (a warning
429 * is displayed).
430 *
431 * Returns 1 if no ".ocsp" file found, 0 if OCSP status extension is
432 * succesfully enabled, or -1 in other error case.
433 */
434static int ssl_sock_load_ocsp(SSL_CTX *ctx, const char *cert_path)
435{
436
437 BIO *in = NULL;
438 X509 *x, *xi = NULL, *issuer = NULL;
439 STACK_OF(X509) *chain = NULL;
440 OCSP_CERTID *cid = NULL;
441 SSL *ssl;
442 char ocsp_path[MAXPATHLEN+1];
443 int i, ret = -1;
444 struct stat st;
445 struct certificate_ocsp *ocsp = NULL, *iocsp;
446 char *warn = NULL;
447 unsigned char *p;
448
449 snprintf(ocsp_path, MAXPATHLEN+1, "%s.ocsp", cert_path);
450
451 if (stat(ocsp_path, &st))
452 return 1;
453
454 ssl = SSL_new(ctx);
455 if (!ssl)
456 goto out;
457
458 x = SSL_get_certificate(ssl);
459 if (!x)
460 goto out;
461
462 /* Try to lookup for issuer in certificate extra chain */
463#ifdef SSL_CTRL_GET_EXTRA_CHAIN_CERTS
464 SSL_CTX_get_extra_chain_certs(ctx, &chain);
465#else
466 chain = ctx->extra_certs;
467#endif
468 for (i = 0; i < sk_X509_num(chain); i++) {
469 issuer = sk_X509_value(chain, i);
470 if (X509_check_issued(issuer, x) == X509_V_OK)
471 break;
472 else
473 issuer = NULL;
474 }
475
476 /* If not found try to load issuer from a suffixed file */
477 if (!issuer) {
478 char issuer_path[MAXPATHLEN+1];
479
480 in = BIO_new(BIO_s_file());
481 if (!in)
482 goto out;
483
484 snprintf(issuer_path, MAXPATHLEN+1, "%s.issuer", cert_path);
485 if (BIO_read_filename(in, issuer_path) <= 0)
486 goto out;
487
488 xi = PEM_read_bio_X509_AUX(in, NULL, ctx->default_passwd_callback, ctx->default_passwd_callback_userdata);
489 if (!xi)
490 goto out;
491
492 if (X509_check_issued(xi, x) != X509_V_OK)
493 goto out;
494
495 issuer = xi;
496 }
497
498 cid = OCSP_cert_to_id(0, x, issuer);
499 if (!cid)
500 goto out;
501
502 i = i2d_OCSP_CERTID(cid, NULL);
503 if (!i || (i > OCSP_MAX_CERTID_ASN1_LENGTH))
504 goto out;
505
506 ocsp = calloc(1, sizeof(struct certificate_ocsp));
507 if (!ocsp)
508 goto out;
509
510 p = ocsp->key_data;
511 i2d_OCSP_CERTID(cid, &p);
512
513 iocsp = (struct certificate_ocsp *)ebmb_insert(&cert_ocsp_tree, &ocsp->key, OCSP_MAX_CERTID_ASN1_LENGTH);
514 if (iocsp == ocsp)
515 ocsp = NULL;
516
517 SSL_CTX_set_tlsext_status_cb(ctx, ssl_sock_ocsp_stapling_cbk);
518 SSL_CTX_set_tlsext_status_arg(ctx, iocsp);
519
520 ret = 0;
521
522 warn = NULL;
523 if (ssl_sock_load_ocsp_response_from_file(ocsp_path, iocsp, cid, &warn)) {
524 memprintf(&warn, "Loading '%s': %s. Content will be ignored", ocsp_path, warn ? warn : "failure");
525 Warning("%s.\n", warn);
526 }
527
528out:
529 if (ssl)
530 SSL_free(ssl);
531
532 if (in)
533 BIO_free(in);
534
535 if (xi)
536 X509_free(xi);
537
538 if (cid)
539 OCSP_CERTID_free(cid);
540
541 if (ocsp)
542 free(ocsp);
543
544 if (warn)
545 free(warn);
546
547
548 return ret;
549}
550
551#endif
552
Emeric Brune1f38db2012-09-03 20:36:47 +0200553void ssl_sock_infocbk(const SSL *ssl, int where, int ret)
554{
555 struct connection *conn = (struct connection *)SSL_get_app_data(ssl);
556 (void)ret; /* shut gcc stupid warning */
Emeric Brund8b2bb52014-01-28 15:43:53 +0100557 BIO *write_bio;
Emeric Brune1f38db2012-09-03 20:36:47 +0200558
559 if (where & SSL_CB_HANDSHAKE_START) {
560 /* Disable renegotiation (CVE-2009-3555) */
Willy Tarreau20879a02012-12-03 16:32:10 +0100561 if (conn->flags & CO_FL_CONNECTED) {
Emeric Brune1f38db2012-09-03 20:36:47 +0200562 conn->flags |= CO_FL_ERROR;
Willy Tarreau20879a02012-12-03 16:32:10 +0100563 conn->err_code = CO_ER_SSL_RENEG;
564 }
Emeric Brune1f38db2012-09-03 20:36:47 +0200565 }
Emeric Brund8b2bb52014-01-28 15:43:53 +0100566
567 if ((where & SSL_CB_ACCEPT_LOOP) == SSL_CB_ACCEPT_LOOP) {
568 if (!(conn->xprt_st & SSL_SOCK_ST_FL_16K_WBFSIZE)) {
569 /* Long certificate chains optimz
570 If write and read bios are differents, we
571 consider that the buffering was activated,
572 so we rise the output buffer size from 4k
573 to 16k */
574 write_bio = SSL_get_wbio(ssl);
575 if (write_bio != SSL_get_rbio(ssl)) {
576 BIO_set_write_buffer_size(write_bio, 16384);
577 conn->xprt_st |= SSL_SOCK_ST_FL_16K_WBFSIZE;
578 }
579 }
580 }
Emeric Brunfc0421f2012-09-07 17:30:07 +0200581}
582
Emeric Brune64aef12012-09-21 13:15:06 +0200583/* Callback is called for each certificate of the chain during a verify
584 ok is set to 1 if preverify detect no error on current certificate.
585 Returns 0 to break the handshake, 1 otherwise. */
Evan Broderbe554312013-06-27 00:05:25 -0700586int ssl_sock_bind_verifycbk(int ok, X509_STORE_CTX *x_store)
Emeric Brune64aef12012-09-21 13:15:06 +0200587{
588 SSL *ssl;
589 struct connection *conn;
Emeric Brun81c00f02012-09-21 14:31:21 +0200590 int err, depth;
Emeric Brune64aef12012-09-21 13:15:06 +0200591
592 ssl = X509_STORE_CTX_get_ex_data(x_store, SSL_get_ex_data_X509_STORE_CTX_idx());
593 conn = (struct connection *)SSL_get_app_data(ssl);
594
Willy Tarreauf7bc57c2012-10-03 00:19:48 +0200595 conn->xprt_st |= SSL_SOCK_ST_FL_VERIFY_DONE;
Emeric Brune64aef12012-09-21 13:15:06 +0200596
Emeric Brun81c00f02012-09-21 14:31:21 +0200597 if (ok) /* no errors */
598 return ok;
599
600 depth = X509_STORE_CTX_get_error_depth(x_store);
601 err = X509_STORE_CTX_get_error(x_store);
602
603 /* check if CA error needs to be ignored */
604 if (depth > 0) {
Willy Tarreauf7bc57c2012-10-03 00:19:48 +0200605 if (!SSL_SOCK_ST_TO_CA_ERROR(conn->xprt_st)) {
606 conn->xprt_st |= SSL_SOCK_CA_ERROR_TO_ST(err);
607 conn->xprt_st |= SSL_SOCK_CAEDEPTH_TO_ST(depth);
Emeric Brunf282a812012-09-21 15:27:54 +0200608 }
609
Emeric Brun1eb20ef2012-12-03 13:24:29 +0100610 if (objt_listener(conn->target)->bind_conf->ca_ignerr & (1ULL << err)) {
611 ERR_clear_error();
Emeric Brun81c00f02012-09-21 14:31:21 +0200612 return 1;
Emeric Brun1eb20ef2012-12-03 13:24:29 +0100613 }
Emeric Brun81c00f02012-09-21 14:31:21 +0200614
Willy Tarreau20879a02012-12-03 16:32:10 +0100615 conn->err_code = CO_ER_SSL_CA_FAIL;
Emeric Brun81c00f02012-09-21 14:31:21 +0200616 return 0;
617 }
618
Willy Tarreauf7bc57c2012-10-03 00:19:48 +0200619 if (!SSL_SOCK_ST_TO_CRTERROR(conn->xprt_st))
620 conn->xprt_st |= SSL_SOCK_CRTERROR_TO_ST(err);
Emeric Brunf282a812012-09-21 15:27:54 +0200621
Emeric Brun81c00f02012-09-21 14:31:21 +0200622 /* check if certificate error needs to be ignored */
Emeric Brun1eb20ef2012-12-03 13:24:29 +0100623 if (objt_listener(conn->target)->bind_conf->crt_ignerr & (1ULL << err)) {
624 ERR_clear_error();
Emeric Brun81c00f02012-09-21 14:31:21 +0200625 return 1;
Emeric Brun1eb20ef2012-12-03 13:24:29 +0100626 }
Emeric Brun81c00f02012-09-21 14:31:21 +0200627
Willy Tarreau20879a02012-12-03 16:32:10 +0100628 conn->err_code = CO_ER_SSL_CRT_FAIL;
Emeric Brun81c00f02012-09-21 14:31:21 +0200629 return 0;
Emeric Brune64aef12012-09-21 13:15:06 +0200630}
631
Emeric Brun29f037d2014-04-25 19:05:36 +0200632/* Callback is called for ssl protocol analyse */
633void ssl_sock_msgcbk(int write_p, int version, int content_type, const void *buf, size_t len, SSL *ssl, void *arg)
634{
Emeric Brun29f037d2014-04-25 19:05:36 +0200635#ifdef TLS1_RT_HEARTBEAT
636 /* test heartbeat received (write_p is set to 0
637 for a received record) */
Willy Tarreauf51c6982014-04-25 20:02:39 +0200638 if ((content_type == TLS1_RT_HEARTBEAT) && (write_p == 0)) {
Willy Tarreau84815002014-04-25 21:40:27 +0200639 struct connection *conn = (struct connection *)SSL_get_app_data(ssl);
Willy Tarreauf51c6982014-04-25 20:02:39 +0200640 const unsigned char *p = buf;
641 unsigned int payload;
642
Emeric Brun29f037d2014-04-25 19:05:36 +0200643 conn->xprt_st |= SSL_SOCK_RECV_HEARTBEAT;
Willy Tarreauf51c6982014-04-25 20:02:39 +0200644
645 /* Check if this is a CVE-2014-0160 exploitation attempt. */
646 if (*p != TLS1_HB_REQUEST)
647 return;
648
Willy Tarreauaeed6722014-04-25 23:59:58 +0200649 if (len < 1 + 2 + 16) /* 1 type + 2 size + 0 payload + 16 padding */
Willy Tarreauf51c6982014-04-25 20:02:39 +0200650 goto kill_it;
651
652 payload = (p[1] * 256) + p[2];
Willy Tarreau3b2fdb62014-04-25 23:44:22 +0200653 if (3 + payload + 16 <= len)
Willy Tarreauf51c6982014-04-25 20:02:39 +0200654 return; /* OK no problem */
Willy Tarreauaeed6722014-04-25 23:59:58 +0200655 kill_it:
Willy Tarreau3b2fdb62014-04-25 23:44:22 +0200656 /* We have a clear heartbleed attack (CVE-2014-0160), the
657 * advertised payload is larger than the advertised packet
658 * length, so we have garbage in the buffer between the
659 * payload and the end of the buffer (p+len). We can't know
660 * if the SSL stack is patched, and we don't know if we can
661 * safely wipe out the area between p+3+len and payload.
662 * So instead, we prevent the response from being sent by
663 * setting the max_send_fragment to 0 and we report an SSL
664 * error, which will kill this connection. It will be reported
665 * above as SSL_ERROR_SSL while an other handshake failure with
Willy Tarreauf51c6982014-04-25 20:02:39 +0200666 * a heartbeat message will be reported as SSL_ERROR_SYSCALL.
667 */
Willy Tarreau3b2fdb62014-04-25 23:44:22 +0200668 ssl->max_send_fragment = 0;
Willy Tarreauf51c6982014-04-25 20:02:39 +0200669 SSLerr(SSL_F_TLS1_HEARTBEAT, SSL_R_SSL_HANDSHAKE_FAILURE);
670 return;
671 }
Emeric Brun29f037d2014-04-25 19:05:36 +0200672#endif
673}
674
Willy Tarreau6c9a3d52012-10-18 18:57:14 +0200675#ifdef OPENSSL_NPN_NEGOTIATED
676/* This callback is used so that the server advertises the list of
677 * negociable protocols for NPN.
678 */
679static int ssl_sock_advertise_npn_protos(SSL *s, const unsigned char **data,
680 unsigned int *len, void *arg)
681{
682 struct bind_conf *conf = arg;
683
684 *data = (const unsigned char *)conf->npn_str;
685 *len = conf->npn_len;
686 return SSL_TLSEXT_ERR_OK;
687}
688#endif
689
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +0100690#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Willy Tarreauab861d32013-04-02 02:30:41 +0200691/* This callback is used so that the server advertises the list of
692 * negociable protocols for ALPN.
693 */
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +0100694static int ssl_sock_advertise_alpn_protos(SSL *s, const unsigned char **out,
695 unsigned char *outlen,
696 const unsigned char *server,
697 unsigned int server_len, void *arg)
Willy Tarreauab861d32013-04-02 02:30:41 +0200698{
699 struct bind_conf *conf = arg;
700
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +0100701 if (SSL_select_next_proto((unsigned char**) out, outlen, (const unsigned char *)conf->alpn_str,
702 conf->alpn_len, server, server_len) != OPENSSL_NPN_NEGOTIATED) {
703 return SSL_TLSEXT_ERR_NOACK;
704 }
Willy Tarreauab861d32013-04-02 02:30:41 +0200705 return SSL_TLSEXT_ERR_OK;
706}
707#endif
708
Emeric Brunfc0421f2012-09-07 17:30:07 +0200709#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
710/* Sets the SSL ctx of <ssl> to match the advertised server name. Returns a
711 * warning when no match is found, which implies the default (first) cert
712 * will keep being used.
713 */
Willy Tarreau2a65ff02012-09-13 17:54:29 +0200714static int ssl_sock_switchctx_cbk(SSL *ssl, int *al, struct bind_conf *s)
Emeric Brunfc0421f2012-09-07 17:30:07 +0200715{
716 const char *servername;
717 const char *wildp = NULL;
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +0200718 struct ebmb_node *node, *n;
Emeric Brunfc0421f2012-09-07 17:30:07 +0200719 int i;
720 (void)al; /* shut gcc stupid warning */
721
722 servername = SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name);
Emmanuel Hocdet65623372013-01-24 17:17:15 +0100723 if (!servername) {
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +0200724 return (s->strict_sni ?
725 SSL_TLSEXT_ERR_ALERT_FATAL :
Emmanuel Hocdet79274e22013-05-31 12:47:44 +0200726 SSL_TLSEXT_ERR_NOACK);
Emmanuel Hocdet65623372013-01-24 17:17:15 +0100727 }
Emeric Brunfc0421f2012-09-07 17:30:07 +0200728
Willy Tarreau19d14ef2012-10-29 16:51:55 +0100729 for (i = 0; i < trash.size; i++) {
Emeric Brunfc0421f2012-09-07 17:30:07 +0200730 if (!servername[i])
731 break;
Willy Tarreau19d14ef2012-10-29 16:51:55 +0100732 trash.str[i] = tolower(servername[i]);
733 if (!wildp && (trash.str[i] == '.'))
734 wildp = &trash.str[i];
Emeric Brunfc0421f2012-09-07 17:30:07 +0200735 }
Willy Tarreau19d14ef2012-10-29 16:51:55 +0100736 trash.str[i] = 0;
Emeric Brunfc0421f2012-09-07 17:30:07 +0200737
738 /* lookup in full qualified names */
Willy Tarreau19d14ef2012-10-29 16:51:55 +0100739 node = ebst_lookup(&s->sni_ctx, trash.str);
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +0200740
741 /* lookup a not neg filter */
742 for (n = node; n; n = ebmb_next_dup(n)) {
743 if (!container_of(n, struct sni_ctx, name)->neg) {
744 node = n;
745 break;
Emmanuel Hocdet65623372013-01-24 17:17:15 +0100746 }
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +0200747 }
748 if (!node && wildp) {
749 /* lookup in wildcards names */
Emeric Brunfc0421f2012-09-07 17:30:07 +0200750 node = ebst_lookup(&s->sni_w_ctx, wildp);
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +0200751 }
752 if (!node || container_of(node, struct sni_ctx, name)->neg) {
753 return (s->strict_sni ?
754 SSL_TLSEXT_ERR_ALERT_FATAL :
755 SSL_TLSEXT_ERR_ALERT_WARNING);
Emeric Brunfc0421f2012-09-07 17:30:07 +0200756 }
757
758 /* switch ctx */
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +0200759 SSL_set_SSL_CTX(ssl, container_of(node, struct sni_ctx, name)->ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +0200760 return SSL_TLSEXT_ERR_OK;
761}
762#endif /* SSL_CTRL_SET_TLSEXT_HOSTNAME */
763
Emeric Bruna4bcd9a2012-09-20 16:19:02 +0200764#ifndef OPENSSL_NO_DH
Remi Gacognef46cd6e2014-06-12 14:58:40 +0200765
766static DH * ssl_get_dh_1024(void)
767{
Remi Gacogne2ad3ec12015-05-29 16:26:17 +0200768 static unsigned char dh1024_p[]={
769 0xFA,0xF9,0x2A,0x22,0x2A,0xA7,0x7F,0xE1,0x67,0x4E,0x53,0xF7,
770 0x56,0x13,0xC3,0xB1,0xE3,0x29,0x6B,0x66,0x31,0x6A,0x7F,0xB3,
771 0xC2,0x68,0x6B,0xCB,0x1D,0x57,0x39,0x1D,0x1F,0xFF,0x1C,0xC9,
772 0xA6,0xA4,0x98,0x82,0x31,0x5D,0x25,0xFF,0x8A,0xE0,0x73,0x96,
773 0x81,0xC8,0x83,0x79,0xC1,0x5A,0x04,0xF8,0x37,0x0D,0xA8,0x3D,
774 0xAE,0x74,0xBC,0xDB,0xB6,0xA4,0x75,0xD9,0x71,0x8A,0xA0,0x17,
775 0x9E,0x2D,0xC8,0xA8,0xDF,0x2C,0x5F,0x82,0x95,0xF8,0x92,0x9B,
776 0xA7,0x33,0x5F,0x89,0x71,0xC8,0x2D,0x6B,0x18,0x86,0xC4,0x94,
777 0x22,0xA5,0x52,0x8D,0xF6,0xF6,0xD2,0x37,0x92,0x0F,0xA5,0xCC,
778 0xDB,0x7B,0x1D,0x3D,0xA1,0x31,0xB7,0x80,0x8F,0x0B,0x67,0x5E,
779 0x36,0xA5,0x60,0x0C,0xF1,0x95,0x33,0x8B,
780 };
781 static unsigned char dh1024_g[]={
782 0x02,
783 };
784
Remi Gacognef46cd6e2014-06-12 14:58:40 +0200785 DH *dh = DH_new();
786 if (dh) {
Remi Gacogne2ad3ec12015-05-29 16:26:17 +0200787 dh->p = BN_bin2bn(dh1024_p, sizeof dh1024_p, NULL);
788 dh->g = BN_bin2bn(dh1024_g, sizeof dh1024_g, NULL);
789
Remi Gacognef46cd6e2014-06-12 14:58:40 +0200790 if (!dh->p || !dh->g) {
791 DH_free(dh);
792 dh = NULL;
793 }
794 }
795 return dh;
796}
797
798static DH *ssl_get_dh_2048(void)
799{
Remi Gacogne2ad3ec12015-05-29 16:26:17 +0200800 static unsigned char dh2048_p[]={
801 0xEC,0x86,0xF8,0x70,0xA0,0x33,0x16,0xEC,0x05,0x1A,0x73,0x59,
802 0xCD,0x1F,0x8B,0xF8,0x29,0xE4,0xD2,0xCF,0x52,0xDD,0xC2,0x24,
803 0x8D,0xB5,0x38,0x9A,0xFB,0x5C,0xA4,0xE4,0xB2,0xDA,0xCE,0x66,
804 0x50,0x74,0xA6,0x85,0x4D,0x4B,0x1D,0x30,0xB8,0x2B,0xF3,0x10,
805 0xE9,0xA7,0x2D,0x05,0x71,0xE7,0x81,0xDF,0x8B,0x59,0x52,0x3B,
806 0x5F,0x43,0x0B,0x68,0xF1,0xDB,0x07,0xBE,0x08,0x6B,0x1B,0x23,
807 0xEE,0x4D,0xCC,0x9E,0x0E,0x43,0xA0,0x1E,0xDF,0x43,0x8C,0xEC,
808 0xBE,0xBE,0x90,0xB4,0x51,0x54,0xB9,0x2F,0x7B,0x64,0x76,0x4E,
809 0x5D,0xD4,0x2E,0xAE,0xC2,0x9E,0xAE,0x51,0x43,0x59,0xC7,0x77,
810 0x9C,0x50,0x3C,0x0E,0xED,0x73,0x04,0x5F,0xF1,0x4C,0x76,0x2A,
811 0xD8,0xF8,0xCF,0xFC,0x34,0x40,0xD1,0xB4,0x42,0x61,0x84,0x66,
812 0x42,0x39,0x04,0xF8,0x68,0xB2,0x62,0xD7,0x55,0xED,0x1B,0x74,
813 0x75,0x91,0xE0,0xC5,0x69,0xC1,0x31,0x5C,0xDB,0x7B,0x44,0x2E,
814 0xCE,0x84,0x58,0x0D,0x1E,0x66,0x0C,0xC8,0x44,0x9E,0xFD,0x40,
815 0x08,0x67,0x5D,0xFB,0xA7,0x76,0x8F,0x00,0x11,0x87,0xE9,0x93,
816 0xF9,0x7D,0xC4,0xBC,0x74,0x55,0x20,0xD4,0x4A,0x41,0x2F,0x43,
817 0x42,0x1A,0xC1,0xF2,0x97,0x17,0x49,0x27,0x37,0x6B,0x2F,0x88,
818 0x7E,0x1C,0xA0,0xA1,0x89,0x92,0x27,0xD9,0x56,0x5A,0x71,0xC1,
819 0x56,0x37,0x7E,0x3A,0x9D,0x05,0xE7,0xEE,0x5D,0x8F,0x82,0x17,
820 0xBC,0xE9,0xC2,0x93,0x30,0x82,0xF9,0xF4,0xC9,0xAE,0x49,0xDB,
821 0xD0,0x54,0xB4,0xD9,0x75,0x4D,0xFA,0x06,0xB8,0xD6,0x38,0x41,
822 0xB7,0x1F,0x77,0xF3,
823 };
824 static unsigned char dh2048_g[]={
825 0x02,
826 };
827
Remi Gacognef46cd6e2014-06-12 14:58:40 +0200828 DH *dh = DH_new();
829 if (dh) {
Remi Gacogne2ad3ec12015-05-29 16:26:17 +0200830 dh->p = BN_bin2bn(dh2048_p, sizeof dh2048_p, NULL);
831 dh->g = BN_bin2bn(dh2048_g, sizeof dh2048_g, NULL);
832
Remi Gacognef46cd6e2014-06-12 14:58:40 +0200833 if (!dh->p || !dh->g) {
834 DH_free(dh);
835 dh = NULL;
836 }
837 }
838 return dh;
839}
840
841static DH *ssl_get_dh_4096(void)
842{
Remi Gacogne2ad3ec12015-05-29 16:26:17 +0200843 static unsigned char dh4096_p[]={
844 0xDE,0x16,0x94,0xCD,0x99,0x58,0x07,0xF1,0xF7,0x32,0x96,0x11,
845 0x04,0x82,0xD4,0x84,0x72,0x80,0x99,0x06,0xCA,0xF0,0xA3,0x68,
846 0x07,0xCE,0x64,0x50,0xE7,0x74,0x45,0x20,0x80,0x5E,0x4D,0xAD,
847 0xA5,0xB6,0xED,0xFA,0x80,0x6C,0x3B,0x35,0xC4,0x9A,0x14,0x6B,
848 0x32,0xBB,0xFD,0x1F,0x17,0x8E,0xB7,0x1F,0xD6,0xFA,0x3F,0x7B,
849 0xEE,0x16,0xA5,0x62,0x33,0x0D,0xED,0xBC,0x4E,0x58,0xE5,0x47,
850 0x4D,0xE9,0xAB,0x8E,0x38,0xD3,0x6E,0x90,0x57,0xE3,0x22,0x15,
851 0x33,0xBD,0xF6,0x43,0x45,0xB5,0x10,0x0A,0xBE,0x2C,0xB4,0x35,
852 0xB8,0x53,0x8D,0xAD,0xFB,0xA7,0x1F,0x85,0x58,0x41,0x7A,0x79,
853 0x20,0x68,0xB3,0xE1,0x3D,0x08,0x76,0xBF,0x86,0x0D,0x49,0xE3,
854 0x82,0x71,0x8C,0xB4,0x8D,0x81,0x84,0xD4,0xE7,0xBE,0x91,0xDC,
855 0x26,0x39,0x48,0x0F,0x35,0xC4,0xCA,0x65,0xE3,0x40,0x93,0x52,
856 0x76,0x58,0x7D,0xDD,0x51,0x75,0xDC,0x69,0x61,0xBF,0x47,0x2C,
857 0x16,0x68,0x2D,0xC9,0x29,0xD3,0xE6,0xC0,0x99,0x48,0xA0,0x9A,
858 0xC8,0x78,0xC0,0x6D,0x81,0x67,0x12,0x61,0x3F,0x71,0xBA,0x41,
859 0x1F,0x6C,0x89,0x44,0x03,0xBA,0x3B,0x39,0x60,0xAA,0x28,0x55,
860 0x59,0xAE,0xB8,0xFA,0xCB,0x6F,0xA5,0x1A,0xF7,0x2B,0xDD,0x52,
861 0x8A,0x8B,0xE2,0x71,0xA6,0x5E,0x7E,0xD8,0x2E,0x18,0xE0,0x66,
862 0xDF,0xDD,0x22,0x21,0x99,0x52,0x73,0xA6,0x33,0x20,0x65,0x0E,
863 0x53,0xE7,0x6B,0x9B,0xC5,0xA3,0x2F,0x97,0x65,0x76,0xD3,0x47,
864 0x23,0x77,0x12,0xB6,0x11,0x7B,0x24,0xED,0xF1,0xEF,0xC0,0xE2,
865 0xA3,0x7E,0x67,0x05,0x3E,0x96,0x4D,0x45,0xC2,0x18,0xD1,0x73,
866 0x9E,0x07,0xF3,0x81,0x6E,0x52,0x63,0xF6,0x20,0x76,0xB9,0x13,
867 0xD2,0x65,0x30,0x18,0x16,0x09,0x16,0x9E,0x8F,0xF1,0xD2,0x10,
868 0x5A,0xD3,0xD4,0xAF,0x16,0x61,0xDA,0x55,0x2E,0x18,0x5E,0x14,
869 0x08,0x54,0x2E,0x2A,0x25,0xA2,0x1A,0x9B,0x8B,0x32,0xA9,0xFD,
870 0xC2,0x48,0x96,0xE1,0x80,0xCA,0xE9,0x22,0x17,0xBB,0xCE,0x3E,
871 0x9E,0xED,0xC7,0xF1,0x1F,0xEC,0x17,0x21,0xDC,0x7B,0x82,0x48,
872 0x8E,0xBB,0x4B,0x9D,0x5B,0x04,0x04,0xDA,0xDB,0x39,0xDF,0x01,
873 0x40,0xC3,0xAA,0x26,0x23,0x89,0x75,0xC6,0x0B,0xD0,0xA2,0x60,
874 0x6A,0xF1,0xCC,0x65,0x18,0x98,0x1B,0x52,0xD2,0x74,0x61,0xCC,
875 0xBD,0x60,0xAE,0xA3,0xA0,0x66,0x6A,0x16,0x34,0x92,0x3F,0x41,
876 0x40,0x31,0x29,0xC0,0x2C,0x63,0xB2,0x07,0x8D,0xEB,0x94,0xB8,
877 0xE8,0x47,0x92,0x52,0x93,0x6A,0x1B,0x7E,0x1A,0x61,0xB3,0x1B,
878 0xF0,0xD6,0x72,0x9B,0xF1,0xB0,0xAF,0xBF,0x3E,0x65,0xEF,0x23,
879 0x1D,0x6F,0xFF,0x70,0xCD,0x8A,0x4C,0x8A,0xA0,0x72,0x9D,0xBE,
880 0xD4,0xBB,0x24,0x47,0x4A,0x68,0xB5,0xF5,0xC6,0xD5,0x7A,0xCD,
881 0xCA,0x06,0x41,0x07,0xAD,0xC2,0x1E,0xE6,0x54,0xA7,0xAD,0x03,
882 0xD9,0x12,0xC1,0x9C,0x13,0xB1,0xC9,0x0A,0x43,0x8E,0x1E,0x08,
883 0xCE,0x50,0x82,0x73,0x5F,0xA7,0x55,0x1D,0xD9,0x59,0xAC,0xB5,
884 0xEA,0x02,0x7F,0x6C,0x5B,0x74,0x96,0x98,0x67,0x24,0xA3,0x0F,
885 0x15,0xFC,0xA9,0x7D,0x3E,0x67,0xD1,0x70,0xF8,0x97,0xF3,0x67,
886 0xC5,0x8C,0x88,0x44,0x08,0x02,0xC7,0x2B,
Remi Gacognef46cd6e2014-06-12 14:58:40 +0200887 };
Remi Gacogne2ad3ec12015-05-29 16:26:17 +0200888 static unsigned char dh4096_g[]={
889 0x02,
890 };
Remi Gacognef46cd6e2014-06-12 14:58:40 +0200891
Remi Gacognef46cd6e2014-06-12 14:58:40 +0200892 DH *dh = DH_new();
893 if (dh) {
Remi Gacogne2ad3ec12015-05-29 16:26:17 +0200894 dh->p = BN_bin2bn(dh4096_p, sizeof dh4096_p, NULL);
895 dh->g = BN_bin2bn(dh4096_g, sizeof dh4096_g, NULL);
896
Remi Gacognef46cd6e2014-06-12 14:58:40 +0200897 if (!dh->p || !dh->g) {
898 DH_free(dh);
899 dh = NULL;
900 }
901 }
902 return dh;
903}
904
905/* Returns Diffie-Hellman parameters matching the private key length
906 but not exceeding global.tune.ssl_default_dh_param */
907static DH *ssl_get_tmp_dh(SSL *ssl, int export, int keylen)
908{
909 DH *dh = NULL;
910 EVP_PKEY *pkey = SSL_get_privatekey(ssl);
911 int type = pkey ? EVP_PKEY_type(pkey->type) : EVP_PKEY_NONE;
912
913 /* The keylen supplied by OpenSSL can only be 512 or 1024.
914 See ssl3_send_server_key_exchange() in ssl/s3_srvr.c
915 */
916 if (type == EVP_PKEY_RSA || type == EVP_PKEY_DSA) {
917 keylen = EVP_PKEY_bits(pkey);
918 }
919
920 if (keylen > global.tune.ssl_default_dh_param) {
921 keylen = global.tune.ssl_default_dh_param;
922 }
923
Remi Gacogne2ad3ec12015-05-29 16:26:17 +0200924 if (keylen >= 4096) {
Remi Gacogne60d7aeb2014-07-15 11:36:40 +0200925 dh = local_dh_4096;
Remi Gacognef46cd6e2014-06-12 14:58:40 +0200926 }
927 else if (keylen >= 2048) {
Remi Gacogne60d7aeb2014-07-15 11:36:40 +0200928 dh = local_dh_2048;
Remi Gacognef46cd6e2014-06-12 14:58:40 +0200929 }
930 else {
Remi Gacogne60d7aeb2014-07-15 11:36:40 +0200931 dh = local_dh_1024;
Remi Gacognef46cd6e2014-06-12 14:58:40 +0200932 }
933
934 return dh;
935}
936
Emeric Bruna4bcd9a2012-09-20 16:19:02 +0200937/* Loads Diffie-Hellman parameter from a file. Returns 1 if loaded, else -1
938 if an error occured, and 0 if parameter not found. */
Willy Tarreau6e774b42014-04-25 21:35:23 +0200939int ssl_sock_load_dh_params(SSL_CTX *ctx, const char *file)
Emeric Bruna4bcd9a2012-09-20 16:19:02 +0200940{
941 int ret = -1;
942 BIO *in;
943 DH *dh = NULL;
944
945 in = BIO_new(BIO_s_file());
946 if (in == NULL)
947 goto end;
948
949 if (BIO_read_filename(in, file) <= 0)
950 goto end;
951
952 dh = PEM_read_bio_DHparams(in, NULL, ctx->default_passwd_callback, ctx->default_passwd_callback_userdata);
Remi Gacognef46cd6e2014-06-12 14:58:40 +0200953 if (dh) {
954 ret = 1;
955 SSL_CTX_set_tmp_dh(ctx, dh);
Remi Gacogne5d769ca2015-05-28 16:23:00 +0200956
957 if (ssl_dh_ptr_index >= 0) {
958 /* store a pointer to the DH params to avoid complaining about
959 ssl-default-dh-param not being set for this SSL_CTX */
960 SSL_CTX_set_ex_data(ctx, ssl_dh_ptr_index, dh);
961 }
Remi Gacognef46cd6e2014-06-12 14:58:40 +0200962 }
963 else {
Emeric Brun41fdb3c2013-04-26 11:05:44 +0200964 /* Clear openssl global errors stack */
965 ERR_clear_error();
966
Remi Gacognef46cd6e2014-06-12 14:58:40 +0200967 if (global.tune.ssl_default_dh_param <= 1024) {
968 /* we are limited to DH parameter of 1024 bits anyway */
Remi Gacogne60d7aeb2014-07-15 11:36:40 +0200969 local_dh_1024 = ssl_get_dh_1024();
970 if (local_dh_1024 == NULL)
Remi Gacognef46cd6e2014-06-12 14:58:40 +0200971 goto end;
Willy Tarreau6e774b42014-04-25 21:35:23 +0200972
Remi Gacogne60d7aeb2014-07-15 11:36:40 +0200973 SSL_CTX_set_tmp_dh(ctx, local_dh_1024);
Remi Gacognef46cd6e2014-06-12 14:58:40 +0200974 }
975 else {
976 SSL_CTX_set_tmp_dh_callback(ctx, ssl_get_tmp_dh);
977 }
Willy Tarreau6e774b42014-04-25 21:35:23 +0200978
Emeric Brun41fdb3c2013-04-26 11:05:44 +0200979 ret = 0; /* DH params not found */
Emeric Bruna4bcd9a2012-09-20 16:19:02 +0200980 }
Emeric Brun644cde02012-12-14 11:21:13 +0100981
Emeric Bruna4bcd9a2012-09-20 16:19:02 +0200982end:
983 if (dh)
984 DH_free(dh);
985
986 if (in)
Emeric Brun41fdb3c2013-04-26 11:05:44 +0200987 BIO_free(in);
Emeric Bruna4bcd9a2012-09-20 16:19:02 +0200988
989 return ret;
990}
991#endif
992
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +0200993static int ssl_sock_add_cert_sni(SSL_CTX *ctx, struct bind_conf *s, char *name, int order)
Emmanuel Hocdetfe616562013-01-22 15:31:15 +0100994{
995 struct sni_ctx *sc;
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +0200996 int wild = 0, neg = 0;
Thierry FOURNIER / OZON.IOe72f43d2016-10-06 10:56:48 +0200997 struct ebmb_node *node;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +0100998
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +0200999 if (*name == '!') {
1000 neg = 1;
1001 name++;
1002 }
1003 if (*name == '*') {
1004 wild = 1;
1005 name++;
1006 }
1007 /* !* filter is a nop */
1008 if (neg && wild)
1009 return order;
1010 if (*name) {
1011 int j, len;
1012 len = strlen(name);
Thierry FOURNIER / OZON.IOe72f43d2016-10-06 10:56:48 +02001013 for (j = 0; j < len && j < trash.size; j++)
1014 trash.str[j] = tolower(name[j]);
1015 if (j >= trash.size)
1016 return order;
1017 trash.str[j] = 0;
1018
1019 /* Check for duplicates. */
1020 if (wild)
1021 node = ebst_lookup(&s->sni_w_ctx, trash.str);
1022 else
1023 node = ebst_lookup(&s->sni_ctx, trash.str);
1024 for (; node; node = ebmb_next_dup(node)) {
1025 sc = ebmb_entry(node, struct sni_ctx, name);
1026 if (sc->ctx == ctx && sc->neg == neg)
1027 return order;
1028 }
1029
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001030 sc = malloc(sizeof(struct sni_ctx) + len + 1);
Thierry FOURNIER / OZON.IO5a00bf72016-10-06 10:35:29 +02001031 if (!sc)
1032 return order;
Thierry FOURNIER / OZON.IOe72f43d2016-10-06 10:56:48 +02001033 memcpy(sc->name.key, trash.str, len + 1);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001034 sc->ctx = ctx;
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001035 sc->order = order++;
1036 sc->neg = neg;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001037 if (wild)
1038 ebst_insert(&s->sni_w_ctx, &sc->name);
1039 else
1040 ebst_insert(&s->sni_ctx, &sc->name);
1041 }
1042 return order;
1043}
1044
Emeric Brunfc0421f2012-09-07 17:30:07 +02001045/* Loads a certificate key and CA chain from a file. Returns 0 on error, -1 if
1046 * an early error happens and the caller must call SSL_CTX_free() by itelf.
1047 */
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001048static 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 +02001049{
1050 BIO *in;
1051 X509 *x = NULL, *ca;
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001052 int i, err;
Emeric Brunfc0421f2012-09-07 17:30:07 +02001053 int ret = -1;
1054 int order = 0;
1055 X509_NAME *xname;
1056 char *str;
Emeric Brunfc0421f2012-09-07 17:30:07 +02001057#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
1058 STACK_OF(GENERAL_NAME) *names;
1059#endif
1060
1061 in = BIO_new(BIO_s_file());
1062 if (in == NULL)
1063 goto end;
1064
1065 if (BIO_read_filename(in, file) <= 0)
1066 goto end;
1067
1068 x = PEM_read_bio_X509_AUX(in, NULL, ctx->default_passwd_callback, ctx->default_passwd_callback_userdata);
1069 if (x == NULL)
1070 goto end;
1071
Emeric Brun50bcecc2013-04-22 13:05:23 +02001072 if (fcount) {
1073 while (fcount--)
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001074 order = ssl_sock_add_cert_sni(ctx, s, sni_filter[fcount], order);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001075 }
1076 else {
Emeric Brunfc0421f2012-09-07 17:30:07 +02001077#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001078 names = X509_get_ext_d2i(x, NID_subject_alt_name, NULL, NULL);
1079 if (names) {
1080 for (i = 0; i < sk_GENERAL_NAME_num(names); i++) {
1081 GENERAL_NAME *name = sk_GENERAL_NAME_value(names, i);
1082 if (name->type == GEN_DNS) {
1083 if (ASN1_STRING_to_UTF8((unsigned char **)&str, name->d.dNSName) >= 0) {
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001084 order = ssl_sock_add_cert_sni(ctx, s, str, order);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001085 OPENSSL_free(str);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001086 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02001087 }
1088 }
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001089 sk_GENERAL_NAME_pop_free(names, GENERAL_NAME_free);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001090 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02001091#endif /* SSL_CTRL_SET_TLSEXT_HOSTNAME */
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001092 xname = X509_get_subject_name(x);
1093 i = -1;
1094 while ((i = X509_NAME_get_index_by_NID(xname, NID_commonName, i)) != -1) {
1095 X509_NAME_ENTRY *entry = X509_NAME_get_entry(xname, i);
1096 if (ASN1_STRING_to_UTF8((unsigned char **)&str, entry->value) >= 0) {
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001097 order = ssl_sock_add_cert_sni(ctx, s, str, order);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001098 OPENSSL_free(str);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001099 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02001100 }
1101 }
1102
1103 ret = 0; /* the caller must not free the SSL_CTX argument anymore */
1104 if (!SSL_CTX_use_certificate(ctx, x))
1105 goto end;
1106
1107 if (ctx->extra_certs != NULL) {
1108 sk_X509_pop_free(ctx->extra_certs, X509_free);
1109 ctx->extra_certs = NULL;
1110 }
1111
1112 while ((ca = PEM_read_bio_X509(in, NULL, ctx->default_passwd_callback, ctx->default_passwd_callback_userdata))) {
1113 if (!SSL_CTX_add_extra_chain_cert(ctx, ca)) {
1114 X509_free(ca);
1115 goto end;
1116 }
1117 }
1118
1119 err = ERR_get_error();
1120 if (!err || (ERR_GET_LIB(err) == ERR_LIB_PEM && ERR_GET_REASON(err) == PEM_R_NO_START_LINE)) {
1121 /* we successfully reached the last cert in the file */
1122 ret = 1;
1123 }
1124 ERR_clear_error();
1125
1126end:
1127 if (x)
1128 X509_free(x);
1129
1130 if (in)
1131 BIO_free(in);
1132
1133 return ret;
1134}
1135
Emeric Brun50bcecc2013-04-22 13:05:23 +02001136static 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 +02001137{
1138 int ret;
1139 SSL_CTX *ctx;
1140
1141 ctx = SSL_CTX_new(SSLv23_server_method());
1142 if (!ctx) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02001143 memprintf(err, "%sunable to allocate SSL context for cert '%s'.\n",
1144 err && *err ? *err : "", path);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001145 return 1;
1146 }
1147
1148 if (SSL_CTX_use_PrivateKey_file(ctx, path, SSL_FILETYPE_PEM) <= 0) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02001149 memprintf(err, "%sunable to load SSL private key from PEM file '%s'.\n",
1150 err && *err ? *err : "", path);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001151 SSL_CTX_free(ctx);
1152 return 1;
1153 }
1154
Emeric Brun50bcecc2013-04-22 13:05:23 +02001155 ret = ssl_sock_load_cert_chain_file(ctx, path, bind_conf, sni_filter, fcount);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001156 if (ret <= 0) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02001157 memprintf(err, "%sunable to load SSL certificate from PEM file '%s'.\n",
1158 err && *err ? *err : "", path);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001159 if (ret < 0) /* serious error, must do that ourselves */
1160 SSL_CTX_free(ctx);
1161 return 1;
1162 }
Emeric Brun61694ab2012-10-26 13:35:33 +02001163
1164 if (SSL_CTX_check_private_key(ctx) <= 0) {
1165 memprintf(err, "%sinconsistencies between private key and certificate loaded from PEM file '%s'.\n",
1166 err && *err ? *err : "", path);
1167 return 1;
1168 }
1169
Emeric Brunfc0421f2012-09-07 17:30:07 +02001170 /* we must not free the SSL_CTX anymore below, since it's already in
1171 * the tree, so it will be discovered and cleaned in time.
1172 */
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001173#ifndef OPENSSL_NO_DH
Remi Gacogne5d769ca2015-05-28 16:23:00 +02001174 /* store a NULL pointer to indicate we have not yet loaded
1175 a custom DH param file */
1176 if (ssl_dh_ptr_index >= 0) {
1177 SSL_CTX_set_ex_data(ctx, ssl_dh_ptr_index, NULL);
1178 }
1179
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001180 ret = ssl_sock_load_dh_params(ctx, path);
1181 if (ret < 0) {
1182 if (err)
1183 memprintf(err, "%sunable to load DH parameters from file '%s'.\n",
1184 *err ? *err : "", path);
1185 return 1;
1186 }
1187#endif
1188
Emeric Brun4147b2e2014-06-16 18:36:30 +02001189#ifdef SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB
1190 ret = ssl_sock_load_ocsp(ctx, path);
1191 if (ret < 0) {
1192 if (err)
1193 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",
1194 *err ? *err : "", path);
1195 return 1;
1196 }
1197#endif
1198
Emeric Brunfc0421f2012-09-07 17:30:07 +02001199#ifndef SSL_CTRL_SET_TLSEXT_HOSTNAME
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001200 if (bind_conf->default_ctx) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02001201 memprintf(err, "%sthis version of openssl cannot load multiple SSL certificates.\n",
1202 err && *err ? *err : "");
Emeric Brunfc0421f2012-09-07 17:30:07 +02001203 return 1;
1204 }
1205#endif
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001206 if (!bind_conf->default_ctx)
1207 bind_conf->default_ctx = ctx;
Emeric Brunfc0421f2012-09-07 17:30:07 +02001208
1209 return 0;
1210}
1211
Willy Tarreau79eeafa2012-09-14 07:53:05 +02001212int ssl_sock_load_cert(char *path, struct bind_conf *bind_conf, struct proxy *curproxy, char **err)
Emeric Brunfc0421f2012-09-07 17:30:07 +02001213{
Cyril Bonté62043c92015-01-25 00:16:08 +01001214 struct dirent **de_list;
1215 int i, n;
Emeric Brunfc0421f2012-09-07 17:30:07 +02001216 DIR *dir;
1217 struct stat buf;
Willy Tarreauee2663b2012-12-06 11:36:59 +01001218 char *end;
1219 char fp[MAXPATHLEN+1];
Emeric Brunfc0421f2012-09-07 17:30:07 +02001220 int cfgerr = 0;
1221
1222 if (!(dir = opendir(path)))
Emeric Brun50bcecc2013-04-22 13:05:23 +02001223 return ssl_sock_load_cert_file(path, bind_conf, curproxy, NULL, 0, err);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001224
1225 /* strip trailing slashes, including first one */
1226 for (end = path + strlen(path) - 1; end >= path && *end == '/'; end--)
1227 *end = 0;
1228
Cyril Bonté62043c92015-01-25 00:16:08 +01001229 n = scandir(path, &de_list, 0, alphasort);
1230 if (n < 0) {
1231 memprintf(err, "%sunable to scan directory '%s' : %s.\n",
1232 err && *err ? *err : "", path, strerror(errno));
1233 cfgerr++;
1234 }
1235 else {
1236 for (i = 0; i < n; i++) {
1237 struct dirent *de = de_list[i];
Emeric Brun2aab7222014-06-18 18:15:09 +02001238
Cyril Bonté62043c92015-01-25 00:16:08 +01001239 end = strrchr(de->d_name, '.');
1240 if (end && (!strcmp(end, ".issuer") || !strcmp(end, ".ocsp")))
1241 goto ignore_entry;
1242
1243 snprintf(fp, sizeof(fp), "%s/%s", path, de->d_name);
1244 if (stat(fp, &buf) != 0) {
1245 memprintf(err, "%sunable to stat SSL certificate from file '%s' : %s.\n",
1246 err && *err ? *err : "", fp, strerror(errno));
1247 cfgerr++;
1248 goto ignore_entry;
1249 }
1250 if (!S_ISREG(buf.st_mode))
1251 goto ignore_entry;
1252 cfgerr += ssl_sock_load_cert_file(fp, bind_conf, curproxy, NULL, 0, err);
1253 ignore_entry:
1254 free(de);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001255 }
Cyril Bonté62043c92015-01-25 00:16:08 +01001256 free(de_list);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001257 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02001258 closedir(dir);
1259 return cfgerr;
1260}
1261
Thierry Fournier383085f2013-01-24 14:15:43 +01001262/* Make sure openssl opens /dev/urandom before the chroot. The work is only
1263 * done once. Zero is returned if the operation fails. No error is returned
1264 * if the random is said as not implemented, because we expect that openssl
1265 * will use another method once needed.
1266 */
1267static int ssl_initialize_random()
1268{
1269 unsigned char random;
1270 static int random_initialized = 0;
1271
1272 if (!random_initialized && RAND_bytes(&random, 1) != 0)
1273 random_initialized = 1;
1274
1275 return random_initialized;
1276}
1277
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001278int ssl_sock_load_cert_list_file(char *file, struct bind_conf *bind_conf, struct proxy *curproxy, char **err)
1279{
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001280 char thisline[LINESIZE];
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001281 FILE *f;
1282 int linenum = 0;
1283 int cfgerr = 0;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001284
Willy Tarreauad1731d2013-04-02 17:35:58 +02001285 if ((f = fopen(file, "r")) == NULL) {
1286 memprintf(err, "cannot open file '%s' : %s", file, strerror(errno));
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001287 return 1;
Willy Tarreauad1731d2013-04-02 17:35:58 +02001288 }
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001289
1290 while (fgets(thisline, sizeof(thisline), f) != NULL) {
1291 int arg;
Emeric Brun50bcecc2013-04-22 13:05:23 +02001292 int newarg;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001293 char *end;
1294 char *args[MAX_LINE_ARGS + 1];
1295 char *line = thisline;
1296
1297 linenum++;
1298 end = line + strlen(line);
1299 if (end-line == sizeof(thisline)-1 && *(end-1) != '\n') {
1300 /* Check if we reached the limit and the last char is not \n.
1301 * Watch out for the last line without the terminating '\n'!
1302 */
Willy Tarreauad1731d2013-04-02 17:35:58 +02001303 memprintf(err, "line %d too long in file '%s', limit is %d characters",
1304 linenum, file, (int)sizeof(thisline)-1);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001305 cfgerr = 1;
Willy Tarreauad1731d2013-04-02 17:35:58 +02001306 break;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001307 }
1308
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001309 arg = 0;
Emeric Brun50bcecc2013-04-22 13:05:23 +02001310 newarg = 1;
1311 while (*line) {
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001312 if (*line == '#' || *line == '\n' || *line == '\r') {
1313 /* end of string, end of loop */
1314 *line = 0;
1315 break;
1316 }
1317 else if (isspace(*line)) {
Emeric Brun50bcecc2013-04-22 13:05:23 +02001318 newarg = 1;
1319 *line = 0;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001320 }
Emeric Brun50bcecc2013-04-22 13:05:23 +02001321 else if (newarg) {
1322 if (arg == MAX_LINE_ARGS) {
1323 memprintf(err, "too many args on line %d in file '%s'.",
1324 linenum, file);
1325 cfgerr = 1;
1326 break;
1327 }
1328 newarg = 0;
1329 args[arg++] = line;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001330 }
Emeric Brun50bcecc2013-04-22 13:05:23 +02001331 line++;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001332 }
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001333 if (cfgerr)
1334 break;
Willy Tarreauad1731d2013-04-02 17:35:58 +02001335
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001336 /* empty line */
Emeric Brun50bcecc2013-04-22 13:05:23 +02001337 if (!arg)
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001338 continue;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001339
Emeric Brun50bcecc2013-04-22 13:05:23 +02001340 cfgerr = ssl_sock_load_cert_file(args[0], bind_conf, curproxy, &args[1], arg-1, err);
Willy Tarreauad1731d2013-04-02 17:35:58 +02001341 if (cfgerr) {
1342 memprintf(err, "error processing line %d in file '%s' : %s", linenum, file, *err);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001343 break;
Willy Tarreauad1731d2013-04-02 17:35:58 +02001344 }
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001345 }
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001346 fclose(f);
1347 return cfgerr;
1348}
1349
Emeric Brunfc0421f2012-09-07 17:30:07 +02001350#ifndef SSL_OP_CIPHER_SERVER_PREFERENCE /* needs OpenSSL >= 0.9.7 */
1351#define SSL_OP_CIPHER_SERVER_PREFERENCE 0
1352#endif
1353
1354#ifndef SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION /* needs OpenSSL >= 0.9.7 */
1355#define SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION 0
Willy Tarreau7d588ee2012-11-26 18:47:31 +01001356#define SSL_renegotiate_pending(arg) 0
Emeric Brunfc0421f2012-09-07 17:30:07 +02001357#endif
Emeric Brun2b58d042012-09-20 17:10:03 +02001358#ifndef SSL_OP_SINGLE_ECDH_USE /* needs OpenSSL >= 0.9.8 */
1359#define SSL_OP_SINGLE_ECDH_USE 0
1360#endif
Emeric Brun2d0c4822012-10-02 13:45:20 +02001361#ifndef SSL_OP_NO_TICKET /* needs OpenSSL >= 0.9.8 */
1362#define SSL_OP_NO_TICKET 0
1363#endif
Emeric Brunfc0421f2012-09-07 17:30:07 +02001364#ifndef SSL_OP_NO_COMPRESSION /* needs OpenSSL >= 0.9.9 */
1365#define SSL_OP_NO_COMPRESSION 0
1366#endif
Emeric Brunc0ff4922012-09-28 19:37:02 +02001367#ifndef SSL_OP_NO_TLSv1_1 /* needs OpenSSL >= 1.0.1 */
1368#define SSL_OP_NO_TLSv1_1 0
1369#endif
1370#ifndef SSL_OP_NO_TLSv1_2 /* needs OpenSSL >= 1.0.1 */
1371#define SSL_OP_NO_TLSv1_2 0
1372#endif
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001373#ifndef SSL_OP_SINGLE_DH_USE /* needs OpenSSL >= 0.9.6 */
1374#define SSL_OP_SINGLE_DH_USE 0
1375#endif
Emeric Brun2b58d042012-09-20 17:10:03 +02001376#ifndef SSL_OP_SINGLE_ECDH_USE /* needs OpenSSL >= 1.0.0 */
1377#define SSL_OP_SINGLE_ECDH_USE 0
1378#endif
Emeric Brunfc0421f2012-09-07 17:30:07 +02001379#ifndef SSL_MODE_RELEASE_BUFFERS /* needs OpenSSL >= 1.0.0 */
1380#define SSL_MODE_RELEASE_BUFFERS 0
1381#endif
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001382
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001383int ssl_sock_prepare_ctx(struct bind_conf *bind_conf, SSL_CTX *ctx, struct proxy *curproxy)
Emeric Brunfc0421f2012-09-07 17:30:07 +02001384{
1385 int cfgerr = 0;
Emeric Brun850efd52014-01-29 12:24:34 +01001386 int verify = SSL_VERIFY_NONE;
Remi Gacogneaf5c3da2014-05-19 10:29:58 +02001387 long ssloptions =
Emeric Brunfc0421f2012-09-07 17:30:07 +02001388 SSL_OP_ALL | /* all known workarounds for bugs */
1389 SSL_OP_NO_SSLv2 |
1390 SSL_OP_NO_COMPRESSION |
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001391 SSL_OP_SINGLE_DH_USE |
Emeric Brun2b58d042012-09-20 17:10:03 +02001392 SSL_OP_SINGLE_ECDH_USE |
Emeric Brun3c4bc6e2012-10-04 18:44:19 +02001393 SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION |
1394 SSL_OP_CIPHER_SERVER_PREFERENCE;
Remi Gacogneaf5c3da2014-05-19 10:29:58 +02001395 long sslmode =
Emeric Brunfc0421f2012-09-07 17:30:07 +02001396 SSL_MODE_ENABLE_PARTIAL_WRITE |
1397 SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER |
1398 SSL_MODE_RELEASE_BUFFERS;
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001399 STACK_OF(SSL_CIPHER) * ciphers = NULL;
1400 SSL_CIPHER * cipher = NULL;
Remi Gacognec1eab8c2014-06-12 18:20:11 +02001401 char cipher_description[128];
1402 /* The description of ciphers using an Ephemeral Diffie Hellman key exchange
1403 contains " Kx=DH " or " Kx=DH(". Beware of " Kx=DH/",
1404 which is not ephemeral DH. */
1405 const char dhe_description[] = " Kx=DH ";
1406 const char dhe_export_description[] = " Kx=DH(";
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001407 int idx = 0;
1408 int dhe_found = 0;
Emeric Brunfc0421f2012-09-07 17:30:07 +02001409
Thierry Fournier383085f2013-01-24 14:15:43 +01001410 /* Make sure openssl opens /dev/urandom before the chroot */
1411 if (!ssl_initialize_random()) {
1412 Alert("OpenSSL random data generator initialization failed.\n");
1413 cfgerr++;
1414 }
1415
Emeric Brun89675492012-10-05 13:48:26 +02001416 if (bind_conf->ssl_options & BC_SSL_O_NO_SSLV3)
Emeric Brunfc0421f2012-09-07 17:30:07 +02001417 ssloptions |= SSL_OP_NO_SSLv3;
Emeric Brun89675492012-10-05 13:48:26 +02001418 if (bind_conf->ssl_options & BC_SSL_O_NO_TLSV10)
Emeric Brunfc0421f2012-09-07 17:30:07 +02001419 ssloptions |= SSL_OP_NO_TLSv1;
Emeric Brun89675492012-10-05 13:48:26 +02001420 if (bind_conf->ssl_options & BC_SSL_O_NO_TLSV11)
Emeric Brunc0ff4922012-09-28 19:37:02 +02001421 ssloptions |= SSL_OP_NO_TLSv1_1;
Emeric Brun89675492012-10-05 13:48:26 +02001422 if (bind_conf->ssl_options & BC_SSL_O_NO_TLSV12)
Emeric Brunc0ff4922012-09-28 19:37:02 +02001423 ssloptions |= SSL_OP_NO_TLSv1_2;
Emeric Brun89675492012-10-05 13:48:26 +02001424 if (bind_conf->ssl_options & BC_SSL_O_NO_TLS_TICKETS)
Emeric Brun2d0c4822012-10-02 13:45:20 +02001425 ssloptions |= SSL_OP_NO_TICKET;
Jérémie Courrèges-Anglaseee374c2015-07-25 16:50:52 -06001426 if (bind_conf->ssl_options & BC_SSL_O_USE_SSLV3) {
1427#ifndef OPENSSL_NO_SSL3
Emeric Brun2cb7ae52012-10-05 14:14:21 +02001428 SSL_CTX_set_ssl_version(ctx, SSLv3_server_method());
Jérémie Courrèges-Anglaseee374c2015-07-25 16:50:52 -06001429#else
1430 Alert("SSLv3 support requested but unavailable.\n");
1431 cfgerr++;
1432#endif
1433 }
Emeric Brun2cb7ae52012-10-05 14:14:21 +02001434 if (bind_conf->ssl_options & BC_SSL_O_USE_TLSV10)
1435 SSL_CTX_set_ssl_version(ctx, TLSv1_server_method());
1436#if SSL_OP_NO_TLSv1_1
1437 if (bind_conf->ssl_options & BC_SSL_O_USE_TLSV11)
1438 SSL_CTX_set_ssl_version(ctx, TLSv1_1_server_method());
1439#endif
1440#if SSL_OP_NO_TLSv1_2
1441 if (bind_conf->ssl_options & BC_SSL_O_USE_TLSV12)
1442 SSL_CTX_set_ssl_version(ctx, TLSv1_2_server_method());
1443#endif
Emeric Brunfc0421f2012-09-07 17:30:07 +02001444
1445 SSL_CTX_set_options(ctx, ssloptions);
1446 SSL_CTX_set_mode(ctx, sslmode);
Emeric Brun850efd52014-01-29 12:24:34 +01001447 switch (bind_conf->verify) {
1448 case SSL_SOCK_VERIFY_NONE:
1449 verify = SSL_VERIFY_NONE;
1450 break;
1451 case SSL_SOCK_VERIFY_OPTIONAL:
1452 verify = SSL_VERIFY_PEER;
1453 break;
1454 case SSL_SOCK_VERIFY_REQUIRED:
1455 verify = SSL_VERIFY_PEER|SSL_VERIFY_FAIL_IF_NO_PEER_CERT;
1456 break;
1457 }
1458 SSL_CTX_set_verify(ctx, verify, ssl_sock_bind_verifycbk);
1459 if (verify & SSL_VERIFY_PEER) {
Emeric Brunfb510ea2012-10-05 12:00:26 +02001460 if (bind_conf->ca_file) {
Emeric Brund94b3fe2012-09-20 18:23:56 +02001461 /* load CAfile to verify */
Emeric Brunfb510ea2012-10-05 12:00:26 +02001462 if (!SSL_CTX_load_verify_locations(ctx, bind_conf->ca_file, NULL)) {
Emeric Brund94b3fe2012-09-20 18:23:56 +02001463 Alert("Proxy '%s': unable to load CA file '%s' for bind '%s' at [%s:%d].\n",
Emeric Brunfb510ea2012-10-05 12:00:26 +02001464 curproxy->id, bind_conf->ca_file, bind_conf->arg, bind_conf->file, bind_conf->line);
Emeric Brund94b3fe2012-09-20 18:23:56 +02001465 cfgerr++;
1466 }
1467 /* set CA names fo client cert request, function returns void */
Emeric Brunfb510ea2012-10-05 12:00:26 +02001468 SSL_CTX_set_client_CA_list(ctx, SSL_load_client_CA_file(bind_conf->ca_file));
Emeric Brund94b3fe2012-09-20 18:23:56 +02001469 }
Emeric Brun850efd52014-01-29 12:24:34 +01001470 else {
1471 Alert("Proxy '%s': verify is enabled but no CA file specified for bind '%s' at [%s:%d].\n",
1472 curproxy->id, bind_conf->arg, bind_conf->file, bind_conf->line);
1473 cfgerr++;
1474 }
Emeric Brun051cdab2012-10-02 19:25:50 +02001475#ifdef X509_V_FLAG_CRL_CHECK
Emeric Brunfb510ea2012-10-05 12:00:26 +02001476 if (bind_conf->crl_file) {
Emeric Brund94b3fe2012-09-20 18:23:56 +02001477 X509_STORE *store = SSL_CTX_get_cert_store(ctx);
1478
Emeric Brunfb510ea2012-10-05 12:00:26 +02001479 if (!store || !X509_STORE_load_locations(store, bind_conf->crl_file, NULL)) {
Emeric Brund94b3fe2012-09-20 18:23:56 +02001480 Alert("Proxy '%s': unable to configure CRL file '%s' for bind '%s' at [%s:%d].\n",
Alexander Rigbo37dc94c2015-04-07 14:02:16 +02001481 curproxy->id, bind_conf->crl_file, bind_conf->arg, bind_conf->file, bind_conf->line);
Emeric Brund94b3fe2012-09-20 18:23:56 +02001482 cfgerr++;
1483 }
Emeric Brun561e5742012-10-02 15:20:55 +02001484 else {
1485 X509_STORE_set_flags(store, X509_V_FLAG_CRL_CHECK|X509_V_FLAG_CRL_CHECK_ALL);
1486 }
Emeric Brund94b3fe2012-09-20 18:23:56 +02001487 }
Emeric Brun051cdab2012-10-02 19:25:50 +02001488#endif
Emeric Brun644cde02012-12-14 11:21:13 +01001489 ERR_clear_error();
Emeric Brund94b3fe2012-09-20 18:23:56 +02001490 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02001491
Emeric Brun4f65bff2012-11-16 15:11:00 +01001492 if (global.tune.ssllifetime)
1493 SSL_CTX_set_timeout(ctx, global.tune.ssllifetime);
1494
Emeric Brunfc0421f2012-09-07 17:30:07 +02001495 shared_context_set_cache(ctx);
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001496 if (bind_conf->ciphers &&
1497 !SSL_CTX_set_cipher_list(ctx, bind_conf->ciphers)) {
Emeric Brunfc0421f2012-09-07 17:30:07 +02001498 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 +02001499 curproxy->id, bind_conf->ciphers, bind_conf->arg, bind_conf->file, bind_conf->line);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001500 cfgerr++;
1501 }
1502
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001503 /* If tune.ssl.default-dh-param has not been set and
1504 no static DH params were in the certificate file. */
Remi Gacogne5d769ca2015-05-28 16:23:00 +02001505 if (global.tune.ssl_default_dh_param == 0 &&
1506 (ssl_dh_ptr_index == -1 ||
1507 SSL_CTX_get_ex_data(ctx, ssl_dh_ptr_index) == NULL)) {
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001508 ciphers = ctx->cipher_list;
1509
1510 if (ciphers) {
1511 for (idx = 0; idx < sk_SSL_CIPHER_num(ciphers); idx++) {
1512 cipher = sk_SSL_CIPHER_value(ciphers, idx);
Remi Gacognec1eab8c2014-06-12 18:20:11 +02001513 if (SSL_CIPHER_description(cipher, cipher_description, sizeof (cipher_description)) == cipher_description) {
1514 if (strstr(cipher_description, dhe_description) != NULL ||
1515 strstr(cipher_description, dhe_export_description) != NULL) {
1516 dhe_found = 1;
1517 break;
1518 }
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001519 }
1520 }
1521
1522 if (dhe_found) {
1523 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");
1524 }
1525 }
1526
1527 global.tune.ssl_default_dh_param = 1024;
1528 }
Remi Gacogne60d7aeb2014-07-15 11:36:40 +02001529
1530#ifndef OPENSSL_NO_DH
1531 if (global.tune.ssl_default_dh_param >= 1024) {
1532 if (local_dh_1024 == NULL) {
1533 local_dh_1024 = ssl_get_dh_1024();
1534 }
1535 if (global.tune.ssl_default_dh_param >= 2048) {
1536 if (local_dh_2048 == NULL) {
1537 local_dh_2048 = ssl_get_dh_2048();
1538 }
1539 if (global.tune.ssl_default_dh_param >= 4096) {
1540 if (local_dh_4096 == NULL) {
1541 local_dh_4096 = ssl_get_dh_4096();
1542 }
Remi Gacogne60d7aeb2014-07-15 11:36:40 +02001543 }
1544 }
1545 }
1546#endif /* OPENSSL_NO_DH */
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001547
Emeric Brunfc0421f2012-09-07 17:30:07 +02001548 SSL_CTX_set_info_callback(ctx, ssl_sock_infocbk);
Willy Tarreau5cbe4ef2014-05-08 22:45:11 +02001549#if OPENSSL_VERSION_NUMBER >= 0x00907000L
Emeric Brun29f037d2014-04-25 19:05:36 +02001550 SSL_CTX_set_msg_callback(ctx, ssl_sock_msgcbk);
Willy Tarreau5cbe4ef2014-05-08 22:45:11 +02001551#endif
Emeric Brun29f037d2014-04-25 19:05:36 +02001552
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02001553#ifdef OPENSSL_NPN_NEGOTIATED
1554 if (bind_conf->npn_str)
1555 SSL_CTX_set_next_protos_advertised_cb(ctx, ssl_sock_advertise_npn_protos, bind_conf);
1556#endif
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01001557#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Willy Tarreauab861d32013-04-02 02:30:41 +02001558 if (bind_conf->alpn_str)
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01001559 SSL_CTX_set_alpn_select_cb(ctx, ssl_sock_advertise_alpn_protos, bind_conf);
Willy Tarreauab861d32013-04-02 02:30:41 +02001560#endif
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02001561
Emeric Brunfc0421f2012-09-07 17:30:07 +02001562#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
1563 SSL_CTX_set_tlsext_servername_callback(ctx, ssl_sock_switchctx_cbk);
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001564 SSL_CTX_set_tlsext_servername_arg(ctx, bind_conf);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001565#endif
Emeric Brun2b58d042012-09-20 17:10:03 +02001566#if defined(SSL_CTX_set_tmp_ecdh) && !defined(OPENSSL_NO_ECDH)
Emeric Brun6924ef82013-03-06 14:08:53 +01001567 {
Emeric Brun2b58d042012-09-20 17:10:03 +02001568 int i;
1569 EC_KEY *ecdh;
1570
Emeric Brun6924ef82013-03-06 14:08:53 +01001571 i = OBJ_sn2nid(bind_conf->ecdhe ? bind_conf->ecdhe : ECDHE_DEFAULT_CURVE);
Emeric Brun2b58d042012-09-20 17:10:03 +02001572 if (!i || ((ecdh = EC_KEY_new_by_curve_name(i)) == NULL)) {
1573 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 +01001574 curproxy->id, bind_conf->ecdhe ? bind_conf->ecdhe : ECDHE_DEFAULT_CURVE,
1575 bind_conf->arg, bind_conf->file, bind_conf->line);
Emeric Brun2b58d042012-09-20 17:10:03 +02001576 cfgerr++;
1577 }
1578 else {
1579 SSL_CTX_set_tmp_ecdh(ctx, ecdh);
1580 EC_KEY_free(ecdh);
1581 }
1582 }
1583#endif
1584
Emeric Brunfc0421f2012-09-07 17:30:07 +02001585 return cfgerr;
1586}
1587
Evan Broderbe554312013-06-27 00:05:25 -07001588static int ssl_sock_srv_hostcheck(const char *pattern, const char *hostname)
1589{
1590 const char *pattern_wildcard, *pattern_left_label_end, *hostname_left_label_end;
1591 size_t prefixlen, suffixlen;
1592
1593 /* Trivial case */
1594 if (strcmp(pattern, hostname) == 0)
1595 return 1;
1596
Evan Broderbe554312013-06-27 00:05:25 -07001597 /* The rest of this logic is based on RFC 6125, section 6.4.3
1598 * (http://tools.ietf.org/html/rfc6125#section-6.4.3) */
1599
Emeric Bruna848dae2013-10-08 11:27:28 +02001600 pattern_wildcard = NULL;
1601 pattern_left_label_end = pattern;
1602 while (*pattern_left_label_end != '.') {
1603 switch (*pattern_left_label_end) {
1604 case 0:
1605 /* End of label not found */
1606 return 0;
1607 case '*':
1608 /* If there is more than one wildcards */
1609 if (pattern_wildcard)
1610 return 0;
1611 pattern_wildcard = pattern_left_label_end;
1612 break;
1613 }
1614 pattern_left_label_end++;
1615 }
1616
1617 /* If it's not trivial and there is no wildcard, it can't
1618 * match */
1619 if (!pattern_wildcard)
Evan Broderbe554312013-06-27 00:05:25 -07001620 return 0;
1621
1622 /* Make sure all labels match except the leftmost */
1623 hostname_left_label_end = strchr(hostname, '.');
1624 if (!hostname_left_label_end
1625 || strcmp(pattern_left_label_end, hostname_left_label_end) != 0)
1626 return 0;
1627
1628 /* Make sure the leftmost label of the hostname is long enough
1629 * that the wildcard can match */
Emeric Brun369da852013-10-08 11:39:35 +02001630 if (hostname_left_label_end - hostname < (pattern_left_label_end - pattern) - 1)
Evan Broderbe554312013-06-27 00:05:25 -07001631 return 0;
1632
1633 /* Finally compare the string on either side of the
1634 * wildcard */
1635 prefixlen = pattern_wildcard - pattern;
1636 suffixlen = pattern_left_label_end - (pattern_wildcard + 1);
Emeric Bruna848dae2013-10-08 11:27:28 +02001637 if ((prefixlen && (memcmp(pattern, hostname, prefixlen) != 0))
1638 || (suffixlen && (memcmp(pattern_wildcard + 1, hostname_left_label_end - suffixlen, suffixlen) != 0)))
Evan Broderbe554312013-06-27 00:05:25 -07001639 return 0;
1640
1641 return 1;
1642}
1643
1644static int ssl_sock_srv_verifycbk(int ok, X509_STORE_CTX *ctx)
1645{
1646 SSL *ssl;
1647 struct connection *conn;
1648 char *servername;
1649
1650 int depth;
1651 X509 *cert;
1652 STACK_OF(GENERAL_NAME) *alt_names;
1653 int i;
1654 X509_NAME *cert_subject;
1655 char *str;
1656
1657 if (ok == 0)
1658 return ok;
1659
1660 ssl = X509_STORE_CTX_get_ex_data(ctx, SSL_get_ex_data_X509_STORE_CTX_idx());
1661 conn = (struct connection *)SSL_get_app_data(ssl);
1662
1663 servername = objt_server(conn->target)->ssl_ctx.verify_host;
1664
1665 /* We only need to verify the CN on the actual server cert,
1666 * not the indirect CAs */
1667 depth = X509_STORE_CTX_get_error_depth(ctx);
1668 if (depth != 0)
1669 return ok;
1670
1671 /* At this point, the cert is *not* OK unless we can find a
1672 * hostname match */
1673 ok = 0;
1674
1675 cert = X509_STORE_CTX_get_current_cert(ctx);
1676 /* It seems like this might happen if verify peer isn't set */
1677 if (!cert)
1678 return ok;
1679
1680 alt_names = X509_get_ext_d2i(cert, NID_subject_alt_name, NULL, NULL);
1681 if (alt_names) {
1682 for (i = 0; !ok && i < sk_GENERAL_NAME_num(alt_names); i++) {
1683 GENERAL_NAME *name = sk_GENERAL_NAME_value(alt_names, i);
1684 if (name->type == GEN_DNS) {
Emeric Bruna33410c2013-09-17 15:47:48 +02001685#if OPENSSL_VERSION_NUMBER < 0x00907000L
1686 if (ASN1_STRING_to_UTF8((unsigned char **)&str, name->d.ia5) >= 0) {
1687#else
Evan Broderbe554312013-06-27 00:05:25 -07001688 if (ASN1_STRING_to_UTF8((unsigned char **)&str, name->d.dNSName) >= 0) {
Emeric Bruna33410c2013-09-17 15:47:48 +02001689#endif
Evan Broderbe554312013-06-27 00:05:25 -07001690 ok = ssl_sock_srv_hostcheck(str, servername);
1691 OPENSSL_free(str);
1692 }
1693 }
1694 }
Emeric Brun4ad50a42013-09-17 15:19:54 +02001695 sk_GENERAL_NAME_pop_free(alt_names, GENERAL_NAME_free);
Evan Broderbe554312013-06-27 00:05:25 -07001696 }
1697
1698 cert_subject = X509_get_subject_name(cert);
1699 i = -1;
1700 while (!ok && (i = X509_NAME_get_index_by_NID(cert_subject, NID_commonName, i)) != -1) {
1701 X509_NAME_ENTRY *entry = X509_NAME_get_entry(cert_subject, i);
1702 if (ASN1_STRING_to_UTF8((unsigned char **)&str, entry->value) >= 0) {
1703 ok = ssl_sock_srv_hostcheck(str, servername);
1704 OPENSSL_free(str);
1705 }
1706 }
1707
1708 return ok;
1709}
1710
Emeric Brun94324a42012-10-11 14:00:19 +02001711/* prepare ssl context from servers options. Returns an error count */
1712int ssl_sock_prepare_srv_ctx(struct server *srv, struct proxy *curproxy)
1713{
1714 int cfgerr = 0;
Remi Gacogneaf5c3da2014-05-19 10:29:58 +02001715 long options =
Emeric Brun94324a42012-10-11 14:00:19 +02001716 SSL_OP_ALL | /* all known workarounds for bugs */
1717 SSL_OP_NO_SSLv2 |
1718 SSL_OP_NO_COMPRESSION;
Remi Gacogneaf5c3da2014-05-19 10:29:58 +02001719 long mode =
Emeric Brun94324a42012-10-11 14:00:19 +02001720 SSL_MODE_ENABLE_PARTIAL_WRITE |
1721 SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER |
1722 SSL_MODE_RELEASE_BUFFERS;
Emeric Brun850efd52014-01-29 12:24:34 +01001723 int verify = SSL_VERIFY_NONE;
Emeric Brun94324a42012-10-11 14:00:19 +02001724
Thierry Fournier383085f2013-01-24 14:15:43 +01001725 /* Make sure openssl opens /dev/urandom before the chroot */
1726 if (!ssl_initialize_random()) {
1727 Alert("OpenSSL random data generator initialization failed.\n");
1728 cfgerr++;
1729 }
1730
Emeric Brun94324a42012-10-11 14:00:19 +02001731 /* Initiate SSL context for current server */
1732 srv->ssl_ctx.reused_sess = NULL;
1733 if (srv->use_ssl)
1734 srv->xprt = &ssl_sock;
1735 if (srv->check.use_ssl)
Cyril Bonté1f96a872014-11-15 22:41:27 +01001736 srv->check.xprt = &ssl_sock;
Emeric Brun94324a42012-10-11 14:00:19 +02001737
1738 srv->ssl_ctx.ctx = SSL_CTX_new(SSLv23_client_method());
1739 if (!srv->ssl_ctx.ctx) {
1740 Alert("config : %s '%s', server '%s': unable to allocate ssl context.\n",
1741 proxy_type_str(curproxy), curproxy->id,
1742 srv->id);
1743 cfgerr++;
1744 return cfgerr;
1745 }
Emeric Bruna7aa3092012-10-26 12:58:00 +02001746 if (srv->ssl_ctx.client_crt) {
1747 if (SSL_CTX_use_PrivateKey_file(srv->ssl_ctx.ctx, srv->ssl_ctx.client_crt, SSL_FILETYPE_PEM) <= 0) {
1748 Alert("config : %s '%s', server '%s': unable to load SSL private key from PEM file '%s'.\n",
1749 proxy_type_str(curproxy), curproxy->id,
1750 srv->id, srv->ssl_ctx.client_crt);
1751 cfgerr++;
1752 }
1753 else if (SSL_CTX_use_certificate_chain_file(srv->ssl_ctx.ctx, srv->ssl_ctx.client_crt) <= 0) {
1754 Alert("config : %s '%s', server '%s': unable to load ssl certificate from PEM file '%s'.\n",
1755 proxy_type_str(curproxy), curproxy->id,
1756 srv->id, srv->ssl_ctx.client_crt);
1757 cfgerr++;
1758 }
1759 else if (SSL_CTX_check_private_key(srv->ssl_ctx.ctx) <= 0) {
1760 Alert("config : %s '%s', server '%s': inconsistencies between private key and certificate loaded from PEM file '%s'.\n",
1761 proxy_type_str(curproxy), curproxy->id,
1762 srv->id, srv->ssl_ctx.client_crt);
1763 cfgerr++;
1764 }
1765 }
Emeric Brun94324a42012-10-11 14:00:19 +02001766
1767 if (srv->ssl_ctx.options & SRV_SSL_O_NO_SSLV3)
1768 options |= SSL_OP_NO_SSLv3;
1769 if (srv->ssl_ctx.options & SRV_SSL_O_NO_TLSV10)
1770 options |= SSL_OP_NO_TLSv1;
1771 if (srv->ssl_ctx.options & SRV_SSL_O_NO_TLSV11)
1772 options |= SSL_OP_NO_TLSv1_1;
1773 if (srv->ssl_ctx.options & SRV_SSL_O_NO_TLSV12)
1774 options |= SSL_OP_NO_TLSv1_2;
Emeric Brunf9c5c472012-10-11 15:28:34 +02001775 if (srv->ssl_ctx.options & SRV_SSL_O_NO_TLS_TICKETS)
1776 options |= SSL_OP_NO_TICKET;
Jérémie Courrèges-Anglaseee374c2015-07-25 16:50:52 -06001777 if (srv->ssl_ctx.options & SRV_SSL_O_USE_SSLV3) {
1778#ifndef OPENSSL_NO_SSL3
Emeric Brun94324a42012-10-11 14:00:19 +02001779 SSL_CTX_set_ssl_version(srv->ssl_ctx.ctx, SSLv3_client_method());
Jérémie Courrèges-Anglaseee374c2015-07-25 16:50:52 -06001780#else
Thierry FOURNIER2272b4f2015-08-26 08:21:26 +02001781 Alert("SSLv3 support requested but unavailable.\n");
Jérémie Courrèges-Anglaseee374c2015-07-25 16:50:52 -06001782 cfgerr++;
1783#endif
1784 }
Emeric Brun94324a42012-10-11 14:00:19 +02001785 if (srv->ssl_ctx.options & SRV_SSL_O_USE_TLSV10)
1786 SSL_CTX_set_ssl_version(srv->ssl_ctx.ctx, TLSv1_client_method());
1787#if SSL_OP_NO_TLSv1_1
1788 if (srv->ssl_ctx.options & SRV_SSL_O_USE_TLSV11)
1789 SSL_CTX_set_ssl_version(srv->ssl_ctx.ctx, TLSv1_1_client_method());
1790#endif
1791#if SSL_OP_NO_TLSv1_2
1792 if (srv->ssl_ctx.options & SRV_SSL_O_USE_TLSV12)
1793 SSL_CTX_set_ssl_version(srv->ssl_ctx.ctx, TLSv1_2_client_method());
1794#endif
1795
1796 SSL_CTX_set_options(srv->ssl_ctx.ctx, options);
1797 SSL_CTX_set_mode(srv->ssl_ctx.ctx, mode);
Emeric Brun850efd52014-01-29 12:24:34 +01001798
1799 if (global.ssl_server_verify == SSL_SERVER_VERIFY_REQUIRED)
1800 verify = SSL_VERIFY_PEER;
1801
1802 switch (srv->ssl_ctx.verify) {
1803 case SSL_SOCK_VERIFY_NONE:
1804 verify = SSL_VERIFY_NONE;
1805 break;
1806 case SSL_SOCK_VERIFY_REQUIRED:
1807 verify = SSL_VERIFY_PEER;
1808 break;
1809 }
Evan Broderbe554312013-06-27 00:05:25 -07001810 SSL_CTX_set_verify(srv->ssl_ctx.ctx,
Emeric Brun850efd52014-01-29 12:24:34 +01001811 verify,
Evan Broderbe554312013-06-27 00:05:25 -07001812 srv->ssl_ctx.verify_host ? ssl_sock_srv_verifycbk : NULL);
Emeric Brun850efd52014-01-29 12:24:34 +01001813 if (verify & SSL_VERIFY_PEER) {
Emeric Brunef42d922012-10-11 16:11:36 +02001814 if (srv->ssl_ctx.ca_file) {
1815 /* load CAfile to verify */
1816 if (!SSL_CTX_load_verify_locations(srv->ssl_ctx.ctx, srv->ssl_ctx.ca_file, NULL)) {
Willy Tarreau07ba08b2014-02-16 19:22:08 +01001817 Alert("Proxy '%s', server '%s' [%s:%d] unable to load CA file '%s'.\n",
Emeric Brunef42d922012-10-11 16:11:36 +02001818 curproxy->id, srv->id,
1819 srv->conf.file, srv->conf.line, srv->ssl_ctx.ca_file);
1820 cfgerr++;
1821 }
1822 }
Emeric Brun850efd52014-01-29 12:24:34 +01001823 else {
1824 if (global.ssl_server_verify == SSL_SERVER_VERIFY_REQUIRED)
Willy Tarreau07ba08b2014-02-16 19:22:08 +01001825 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 +01001826 curproxy->id, srv->id,
1827 srv->conf.file, srv->conf.line);
1828 else
Willy Tarreau07ba08b2014-02-16 19:22:08 +01001829 Alert("Proxy '%s', server '%s' [%s:%d] verify is enabled but no CA file specified.\n",
Emeric Brun850efd52014-01-29 12:24:34 +01001830 curproxy->id, srv->id,
1831 srv->conf.file, srv->conf.line);
1832 cfgerr++;
1833 }
Emeric Brunef42d922012-10-11 16:11:36 +02001834#ifdef X509_V_FLAG_CRL_CHECK
1835 if (srv->ssl_ctx.crl_file) {
1836 X509_STORE *store = SSL_CTX_get_cert_store(srv->ssl_ctx.ctx);
1837
1838 if (!store || !X509_STORE_load_locations(store, srv->ssl_ctx.crl_file, NULL)) {
Willy Tarreau07ba08b2014-02-16 19:22:08 +01001839 Alert("Proxy '%s', server '%s' [%s:%d] unable to configure CRL file '%s'.\n",
Emeric Brunef42d922012-10-11 16:11:36 +02001840 curproxy->id, srv->id,
1841 srv->conf.file, srv->conf.line, srv->ssl_ctx.crl_file);
1842 cfgerr++;
1843 }
1844 else {
1845 X509_STORE_set_flags(store, X509_V_FLAG_CRL_CHECK|X509_V_FLAG_CRL_CHECK_ALL);
1846 }
1847 }
1848#endif
1849 }
1850
Emeric Brun4f65bff2012-11-16 15:11:00 +01001851 if (global.tune.ssllifetime)
1852 SSL_CTX_set_timeout(srv->ssl_ctx.ctx, global.tune.ssllifetime);
1853
Emeric Brun94324a42012-10-11 14:00:19 +02001854 SSL_CTX_set_session_cache_mode(srv->ssl_ctx.ctx, SSL_SESS_CACHE_OFF);
1855 if (srv->ssl_ctx.ciphers &&
1856 !SSL_CTX_set_cipher_list(srv->ssl_ctx.ctx, srv->ssl_ctx.ciphers)) {
1857 Alert("Proxy '%s', server '%s' [%s:%d] : unable to set SSL cipher list to '%s'.\n",
1858 curproxy->id, srv->id,
1859 srv->conf.file, srv->conf.line, srv->ssl_ctx.ciphers);
1860 cfgerr++;
1861 }
1862
1863 return cfgerr;
1864}
1865
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001866/* Walks down the two trees in bind_conf and prepares all certs. The pointer may
Emeric Brunfc0421f2012-09-07 17:30:07 +02001867 * be NULL, in which case nothing is done. Returns the number of errors
1868 * encountered.
1869 */
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001870int ssl_sock_prepare_all_ctx(struct bind_conf *bind_conf, struct proxy *px)
Emeric Brunfc0421f2012-09-07 17:30:07 +02001871{
1872 struct ebmb_node *node;
1873 struct sni_ctx *sni;
1874 int err = 0;
1875
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001876 if (!bind_conf || !bind_conf->is_ssl)
Emeric Brunfc0421f2012-09-07 17:30:07 +02001877 return 0;
1878
Emeric Brun8068b032014-10-30 19:25:24 +01001879 if (bind_conf->default_ctx)
1880 err += ssl_sock_prepare_ctx(bind_conf, bind_conf->default_ctx, px);
1881
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001882 node = ebmb_first(&bind_conf->sni_ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001883 while (node) {
1884 sni = ebmb_entry(node, struct sni_ctx, name);
Emeric Brun8068b032014-10-30 19:25:24 +01001885 if (!sni->order && sni->ctx != bind_conf->default_ctx)
1886 /* only initialize the CTX on its first occurrence and
1887 if it is not the default_ctx */
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001888 err += ssl_sock_prepare_ctx(bind_conf, sni->ctx, px);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001889 node = ebmb_next(node);
1890 }
1891
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001892 node = ebmb_first(&bind_conf->sni_w_ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001893 while (node) {
1894 sni = ebmb_entry(node, struct sni_ctx, name);
Emeric Brun8068b032014-10-30 19:25:24 +01001895 if (!sni->order && sni->ctx != bind_conf->default_ctx)
1896 /* only initialize the CTX on its first occurrence and
1897 if it is not the default_ctx */
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001898 err += ssl_sock_prepare_ctx(bind_conf, sni->ctx, px);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001899 node = ebmb_next(node);
1900 }
1901 return err;
1902}
1903
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001904/* Walks down the two trees in bind_conf and frees all the certs. The pointer may
Emeric Brunfc0421f2012-09-07 17:30:07 +02001905 * be NULL, in which case nothing is done. The default_ctx is nullified too.
1906 */
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001907void ssl_sock_free_all_ctx(struct bind_conf *bind_conf)
Emeric Brunfc0421f2012-09-07 17:30:07 +02001908{
1909 struct ebmb_node *node, *back;
1910 struct sni_ctx *sni;
1911
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001912 if (!bind_conf || !bind_conf->is_ssl)
Emeric Brunfc0421f2012-09-07 17:30:07 +02001913 return;
1914
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001915 node = ebmb_first(&bind_conf->sni_ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001916 while (node) {
1917 sni = ebmb_entry(node, struct sni_ctx, name);
1918 back = ebmb_next(node);
1919 ebmb_delete(node);
1920 if (!sni->order) /* only free the CTX on its first occurrence */
1921 SSL_CTX_free(sni->ctx);
1922 free(sni);
1923 node = back;
1924 }
1925
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001926 node = ebmb_first(&bind_conf->sni_w_ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001927 while (node) {
1928 sni = ebmb_entry(node, struct sni_ctx, name);
1929 back = ebmb_next(node);
1930 ebmb_delete(node);
1931 if (!sni->order) /* only free the CTX on its first occurrence */
1932 SSL_CTX_free(sni->ctx);
1933 free(sni);
1934 node = back;
1935 }
1936
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001937 bind_conf->default_ctx = NULL;
Emeric Brune1f38db2012-09-03 20:36:47 +02001938}
1939
Emeric Brun46591952012-05-18 15:47:34 +02001940/*
1941 * This function is called if SSL * context is not yet allocated. The function
1942 * is designed to be called before any other data-layer operation and sets the
1943 * handshake flag on the connection. It is safe to call it multiple times.
1944 * It returns 0 on success and -1 in error case.
1945 */
1946static int ssl_sock_init(struct connection *conn)
1947{
1948 /* already initialized */
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02001949 if (conn->xprt_ctx)
Emeric Brun46591952012-05-18 15:47:34 +02001950 return 0;
1951
Willy Tarreau3c728722014-01-23 13:50:42 +01001952 if (!conn_ctrl_ready(conn))
Willy Tarreauf79c8172013-10-21 16:30:56 +02001953 return 0;
1954
Willy Tarreau20879a02012-12-03 16:32:10 +01001955 if (global.maxsslconn && sslconns >= global.maxsslconn) {
1956 conn->err_code = CO_ER_SSL_TOO_MANY;
Willy Tarreau403edff2012-09-06 11:58:37 +02001957 return -1;
Willy Tarreau20879a02012-12-03 16:32:10 +01001958 }
Willy Tarreau403edff2012-09-06 11:58:37 +02001959
Emeric Brun46591952012-05-18 15:47:34 +02001960 /* If it is in client mode initiate SSL session
1961 in connect state otherwise accept state */
Willy Tarreau3fdb3662012-11-12 00:42:33 +01001962 if (objt_server(conn->target)) {
Willy Tarreau9bcc01a2014-11-13 13:48:58 +01001963 int may_retry = 1;
1964
1965 retry_connect:
Emeric Brun46591952012-05-18 15:47:34 +02001966 /* Alloc a new SSL session ctx */
Willy Tarreau3fdb3662012-11-12 00:42:33 +01001967 conn->xprt_ctx = SSL_new(objt_server(conn->target)->ssl_ctx.ctx);
Willy Tarreau20879a02012-12-03 16:32:10 +01001968 if (!conn->xprt_ctx) {
Willy Tarreau9bcc01a2014-11-13 13:48:58 +01001969 if (may_retry--) {
1970 pool_gc2();
1971 goto retry_connect;
1972 }
Willy Tarreau20879a02012-12-03 16:32:10 +01001973 conn->err_code = CO_ER_SSL_NO_MEM;
Emeric Brun46591952012-05-18 15:47:34 +02001974 return -1;
Willy Tarreau20879a02012-12-03 16:32:10 +01001975 }
Emeric Brun46591952012-05-18 15:47:34 +02001976
Emeric Brun46591952012-05-18 15:47:34 +02001977 /* set fd on SSL session context */
Emeric Brun90951492014-11-12 17:35:37 +01001978 if (!SSL_set_fd(conn->xprt_ctx, conn->t.sock.fd)) {
1979 SSL_free(conn->xprt_ctx);
1980 conn->xprt_ctx = NULL;
Willy Tarreau9bcc01a2014-11-13 13:48:58 +01001981 if (may_retry--) {
1982 pool_gc2();
1983 goto retry_connect;
1984 }
Emeric Brun90951492014-11-12 17:35:37 +01001985 conn->err_code = CO_ER_SSL_NO_MEM;
1986 return -1;
1987 }
Emeric Brun46591952012-05-18 15:47:34 +02001988
Evan Broderbe554312013-06-27 00:05:25 -07001989 /* set connection pointer */
Emeric Brun90951492014-11-12 17:35:37 +01001990 if (!SSL_set_app_data(conn->xprt_ctx, conn)) {
1991 SSL_free(conn->xprt_ctx);
1992 conn->xprt_ctx = NULL;
Willy Tarreau9bcc01a2014-11-13 13:48:58 +01001993 if (may_retry--) {
1994 pool_gc2();
1995 goto retry_connect;
1996 }
Emeric Brun90951492014-11-12 17:35:37 +01001997 conn->err_code = CO_ER_SSL_NO_MEM;
1998 return -1;
1999 }
2000
2001 SSL_set_connect_state(conn->xprt_ctx);
2002 if (objt_server(conn->target)->ssl_ctx.reused_sess) {
2003 if(!SSL_set_session(conn->xprt_ctx, objt_server(conn->target)->ssl_ctx.reused_sess)) {
2004 SSL_SESSION_free(objt_server(conn->target)->ssl_ctx.reused_sess);
2005 objt_server(conn->target)->ssl_ctx.reused_sess = NULL;
2006 }
2007 }
Evan Broderbe554312013-06-27 00:05:25 -07002008
Emeric Brun46591952012-05-18 15:47:34 +02002009 /* leave init state and start handshake */
Willy Tarreau05737472012-09-04 08:03:39 +02002010 conn->flags |= CO_FL_SSL_WAIT_HS | CO_FL_WAIT_L6_CONN;
Willy Tarreau403edff2012-09-06 11:58:37 +02002011
2012 sslconns++;
Willy Tarreau71b734c2014-01-28 15:19:44 +01002013 totalsslconns++;
Emeric Brun46591952012-05-18 15:47:34 +02002014 return 0;
2015 }
Willy Tarreau3fdb3662012-11-12 00:42:33 +01002016 else if (objt_listener(conn->target)) {
Willy Tarreau9bcc01a2014-11-13 13:48:58 +01002017 int may_retry = 1;
2018
2019 retry_accept:
Emeric Brun46591952012-05-18 15:47:34 +02002020 /* Alloc a new SSL session ctx */
Willy Tarreau3fdb3662012-11-12 00:42:33 +01002021 conn->xprt_ctx = SSL_new(objt_listener(conn->target)->bind_conf->default_ctx);
Willy Tarreau20879a02012-12-03 16:32:10 +01002022 if (!conn->xprt_ctx) {
Willy Tarreau9bcc01a2014-11-13 13:48:58 +01002023 if (may_retry--) {
2024 pool_gc2();
2025 goto retry_accept;
2026 }
Willy Tarreau20879a02012-12-03 16:32:10 +01002027 conn->err_code = CO_ER_SSL_NO_MEM;
Emeric Brun46591952012-05-18 15:47:34 +02002028 return -1;
Willy Tarreau20879a02012-12-03 16:32:10 +01002029 }
Emeric Brun46591952012-05-18 15:47:34 +02002030
Emeric Brun46591952012-05-18 15:47:34 +02002031 /* set fd on SSL session context */
Emeric Brun90951492014-11-12 17:35:37 +01002032 if (!SSL_set_fd(conn->xprt_ctx, conn->t.sock.fd)) {
2033 SSL_free(conn->xprt_ctx);
2034 conn->xprt_ctx = NULL;
Willy Tarreau9bcc01a2014-11-13 13:48:58 +01002035 if (may_retry--) {
2036 pool_gc2();
2037 goto retry_accept;
2038 }
Emeric Brun90951492014-11-12 17:35:37 +01002039 conn->err_code = CO_ER_SSL_NO_MEM;
2040 return -1;
2041 }
Emeric Brun46591952012-05-18 15:47:34 +02002042
Emeric Brune1f38db2012-09-03 20:36:47 +02002043 /* set connection pointer */
Emeric Brun90951492014-11-12 17:35:37 +01002044 if (!SSL_set_app_data(conn->xprt_ctx, conn)) {
2045 SSL_free(conn->xprt_ctx);
2046 conn->xprt_ctx = NULL;
Willy Tarreau9bcc01a2014-11-13 13:48:58 +01002047 if (may_retry--) {
2048 pool_gc2();
2049 goto retry_accept;
2050 }
Emeric Brun90951492014-11-12 17:35:37 +01002051 conn->err_code = CO_ER_SSL_NO_MEM;
2052 return -1;
2053 }
2054
2055 SSL_set_accept_state(conn->xprt_ctx);
Emeric Brune1f38db2012-09-03 20:36:47 +02002056
Emeric Brun46591952012-05-18 15:47:34 +02002057 /* leave init state and start handshake */
Willy Tarreau05737472012-09-04 08:03:39 +02002058 conn->flags |= CO_FL_SSL_WAIT_HS | CO_FL_WAIT_L6_CONN;
Willy Tarreau403edff2012-09-06 11:58:37 +02002059
2060 sslconns++;
Willy Tarreau71b734c2014-01-28 15:19:44 +01002061 totalsslconns++;
Emeric Brun46591952012-05-18 15:47:34 +02002062 return 0;
2063 }
2064 /* don't know how to handle such a target */
Willy Tarreau20879a02012-12-03 16:32:10 +01002065 conn->err_code = CO_ER_SSL_NO_TARGET;
Emeric Brun46591952012-05-18 15:47:34 +02002066 return -1;
2067}
2068
2069
2070/* This is the callback which is used when an SSL handshake is pending. It
2071 * updates the FD status if it wants some polling before being called again.
2072 * It returns 0 if it fails in a fatal way or needs to poll to go further,
2073 * otherwise it returns non-zero and removes itself from the connection's
2074 * flags (the bit is provided in <flag> by the caller).
2075 */
2076int ssl_sock_handshake(struct connection *conn, unsigned int flag)
2077{
2078 int ret;
2079
Willy Tarreau3c728722014-01-23 13:50:42 +01002080 if (!conn_ctrl_ready(conn))
Willy Tarreauf79c8172013-10-21 16:30:56 +02002081 return 0;
2082
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02002083 if (!conn->xprt_ctx)
Emeric Brun46591952012-05-18 15:47:34 +02002084 goto out_error;
2085
Emeric Brun674b7432012-11-08 19:21:55 +01002086 /* If we use SSL_do_handshake to process a reneg initiated by
2087 * the remote peer, it sometimes returns SSL_ERROR_SSL.
2088 * Usually SSL_write and SSL_read are used and process implicitly
2089 * the reneg handshake.
2090 * Here we use SSL_peek as a workaround for reneg.
2091 */
2092 if ((conn->flags & CO_FL_CONNECTED) && SSL_renegotiate_pending(conn->xprt_ctx)) {
2093 char c;
2094
2095 ret = SSL_peek(conn->xprt_ctx, &c, 1);
2096 if (ret <= 0) {
2097 /* handshake may have not been completed, let's find why */
2098 ret = SSL_get_error(conn->xprt_ctx, ret);
2099 if (ret == SSL_ERROR_WANT_WRITE) {
2100 /* SSL handshake needs to write, L4 connection may not be ready */
2101 __conn_sock_stop_recv(conn);
Willy Tarreaue1f50c42014-01-22 20:02:06 +01002102 __conn_sock_want_send(conn);
2103 fd_cant_send(conn->t.sock.fd);
Emeric Brun674b7432012-11-08 19:21:55 +01002104 return 0;
2105 }
2106 else if (ret == SSL_ERROR_WANT_READ) {
2107 /* handshake may have been completed but we have
2108 * no more data to read.
2109 */
2110 if (!SSL_renegotiate_pending(conn->xprt_ctx)) {
2111 ret = 1;
2112 goto reneg_ok;
2113 }
2114 /* SSL handshake needs to read, L4 connection is ready */
2115 if (conn->flags & CO_FL_WAIT_L4_CONN)
2116 conn->flags &= ~CO_FL_WAIT_L4_CONN;
2117 __conn_sock_stop_send(conn);
Willy Tarreaue1f50c42014-01-22 20:02:06 +01002118 __conn_sock_want_recv(conn);
2119 fd_cant_recv(conn->t.sock.fd);
Emeric Brun674b7432012-11-08 19:21:55 +01002120 return 0;
2121 }
2122 else if (ret == SSL_ERROR_SYSCALL) {
2123 /* if errno is null, then connection was successfully established */
2124 if (!errno && conn->flags & CO_FL_WAIT_L4_CONN)
2125 conn->flags &= ~CO_FL_WAIT_L4_CONN;
Willy Tarreau20879a02012-12-03 16:32:10 +01002126 if (!conn->err_code) {
Emeric Brun29f037d2014-04-25 19:05:36 +02002127 if (!((SSL *)conn->xprt_ctx)->packet_length) {
2128 if (!errno) {
2129 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
2130 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
2131 else
2132 conn->err_code = CO_ER_SSL_EMPTY;
2133 }
2134 else {
2135 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
2136 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
2137 else
2138 conn->err_code = CO_ER_SSL_ABORT;
2139 }
2140 }
2141 else {
2142 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
2143 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
Willy Tarreau20879a02012-12-03 16:32:10 +01002144 else
Emeric Brun29f037d2014-04-25 19:05:36 +02002145 conn->err_code = CO_ER_SSL_HANDSHAKE;
2146 }
Willy Tarreau20879a02012-12-03 16:32:10 +01002147 }
Emeric Brun674b7432012-11-08 19:21:55 +01002148 goto out_error;
2149 }
2150 else {
2151 /* Fail on all other handshake errors */
2152 /* Note: OpenSSL may leave unread bytes in the socket's
2153 * buffer, causing an RST to be emitted upon close() on
2154 * TCP sockets. We first try to drain possibly pending
2155 * data to avoid this as much as possible.
2156 */
Willy Tarreau46be2e52014-01-20 12:10:52 +01002157 conn_drain(conn);
Willy Tarreau20879a02012-12-03 16:32:10 +01002158 if (!conn->err_code)
Willy Tarreauf51c6982014-04-25 20:02:39 +02002159 conn->err_code = (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT) ?
2160 CO_ER_SSL_KILLED_HB : CO_ER_SSL_HANDSHAKE;
Emeric Brun674b7432012-11-08 19:21:55 +01002161 goto out_error;
2162 }
2163 }
2164 /* read some data: consider handshake completed */
2165 goto reneg_ok;
2166 }
2167
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02002168 ret = SSL_do_handshake(conn->xprt_ctx);
Emeric Brun46591952012-05-18 15:47:34 +02002169 if (ret != 1) {
2170 /* handshake did not complete, let's find why */
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02002171 ret = SSL_get_error(conn->xprt_ctx, ret);
Emeric Brun46591952012-05-18 15:47:34 +02002172
2173 if (ret == SSL_ERROR_WANT_WRITE) {
2174 /* SSL handshake needs to write, L4 connection may not be ready */
2175 __conn_sock_stop_recv(conn);
Willy Tarreaue1f50c42014-01-22 20:02:06 +01002176 __conn_sock_want_send(conn);
2177 fd_cant_send(conn->t.sock.fd);
Emeric Brun46591952012-05-18 15:47:34 +02002178 return 0;
2179 }
2180 else if (ret == SSL_ERROR_WANT_READ) {
2181 /* SSL handshake needs to read, L4 connection is ready */
2182 if (conn->flags & CO_FL_WAIT_L4_CONN)
2183 conn->flags &= ~CO_FL_WAIT_L4_CONN;
2184 __conn_sock_stop_send(conn);
Willy Tarreaue1f50c42014-01-22 20:02:06 +01002185 __conn_sock_want_recv(conn);
2186 fd_cant_recv(conn->t.sock.fd);
Emeric Brun46591952012-05-18 15:47:34 +02002187 return 0;
2188 }
Willy Tarreau89230192012-09-28 20:22:13 +02002189 else if (ret == SSL_ERROR_SYSCALL) {
2190 /* if errno is null, then connection was successfully established */
2191 if (!errno && conn->flags & CO_FL_WAIT_L4_CONN)
2192 conn->flags &= ~CO_FL_WAIT_L4_CONN;
Willy Tarreau20879a02012-12-03 16:32:10 +01002193
Emeric Brun29f037d2014-04-25 19:05:36 +02002194 if (!((SSL *)conn->xprt_ctx)->packet_length) {
2195 if (!errno) {
2196 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
2197 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
2198 else
2199 conn->err_code = CO_ER_SSL_EMPTY;
2200 }
2201 else {
2202 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
2203 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
2204 else
2205 conn->err_code = CO_ER_SSL_ABORT;
2206 }
2207 }
2208 else {
2209 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
2210 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
Willy Tarreau20879a02012-12-03 16:32:10 +01002211 else
Emeric Brun29f037d2014-04-25 19:05:36 +02002212 conn->err_code = CO_ER_SSL_HANDSHAKE;
2213 }
Willy Tarreau89230192012-09-28 20:22:13 +02002214 goto out_error;
2215 }
Emeric Brun46591952012-05-18 15:47:34 +02002216 else {
2217 /* Fail on all other handshake errors */
Willy Tarreau566dc552012-10-19 20:52:18 +02002218 /* Note: OpenSSL may leave unread bytes in the socket's
2219 * buffer, causing an RST to be emitted upon close() on
2220 * TCP sockets. We first try to drain possibly pending
2221 * data to avoid this as much as possible.
2222 */
Willy Tarreau46be2e52014-01-20 12:10:52 +01002223 conn_drain(conn);
Willy Tarreau20879a02012-12-03 16:32:10 +01002224 if (!conn->err_code)
Willy Tarreauf51c6982014-04-25 20:02:39 +02002225 conn->err_code = (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT) ?
2226 CO_ER_SSL_KILLED_HB : CO_ER_SSL_HANDSHAKE;
Emeric Brun46591952012-05-18 15:47:34 +02002227 goto out_error;
2228 }
2229 }
2230
Emeric Brun674b7432012-11-08 19:21:55 +01002231reneg_ok:
2232
Emeric Brun46591952012-05-18 15:47:34 +02002233 /* Handshake succeeded */
Willy Tarreau0c9c2722014-05-28 12:28:58 +02002234 if (!SSL_session_reused(conn->xprt_ctx)) {
2235 if (objt_server(conn->target)) {
2236 update_freq_ctr(&global.ssl_be_keys_per_sec, 1);
2237 if (global.ssl_be_keys_per_sec.curr_ctr > global.ssl_be_keys_max)
2238 global.ssl_be_keys_max = global.ssl_be_keys_per_sec.curr_ctr;
2239
Emeric Brun46591952012-05-18 15:47:34 +02002240 /* check if session was reused, if not store current session on server for reuse */
Willy Tarreaua491c652016-12-22 21:54:21 +01002241 if (objt_server(conn->target)->ssl_ctx.reused_sess) {
Willy Tarreau3fdb3662012-11-12 00:42:33 +01002242 SSL_SESSION_free(objt_server(conn->target)->ssl_ctx.reused_sess);
Willy Tarreaua491c652016-12-22 21:54:21 +01002243 objt_server(conn->target)->ssl_ctx.reused_sess = NULL;
2244 }
Emeric Brun46591952012-05-18 15:47:34 +02002245
Willy Tarreau3fdb3662012-11-12 00:42:33 +01002246 objt_server(conn->target)->ssl_ctx.reused_sess = SSL_get1_session(conn->xprt_ctx);
Emeric Brun46591952012-05-18 15:47:34 +02002247 }
Willy Tarreau0c9c2722014-05-28 12:28:58 +02002248 else {
2249 update_freq_ctr(&global.ssl_fe_keys_per_sec, 1);
2250 if (global.ssl_fe_keys_per_sec.curr_ctr > global.ssl_fe_keys_max)
2251 global.ssl_fe_keys_max = global.ssl_fe_keys_per_sec.curr_ctr;
2252 }
Emeric Brun46591952012-05-18 15:47:34 +02002253 }
2254
2255 /* The connection is now established at both layers, it's time to leave */
2256 conn->flags &= ~(flag | CO_FL_WAIT_L4_CONN | CO_FL_WAIT_L6_CONN);
2257 return 1;
2258
2259 out_error:
Emeric Brun644cde02012-12-14 11:21:13 +01002260 /* Clear openssl global errors stack */
2261 ERR_clear_error();
2262
Emeric Brun9fa89732012-10-04 17:09:56 +02002263 /* free resumed session if exists */
Willy Tarreau3fdb3662012-11-12 00:42:33 +01002264 if (objt_server(conn->target) && objt_server(conn->target)->ssl_ctx.reused_sess) {
2265 SSL_SESSION_free(objt_server(conn->target)->ssl_ctx.reused_sess);
2266 objt_server(conn->target)->ssl_ctx.reused_sess = NULL;
Emeric Brun9fa89732012-10-04 17:09:56 +02002267 }
2268
Emeric Brun46591952012-05-18 15:47:34 +02002269 /* Fail on all other handshake errors */
2270 conn->flags |= CO_FL_ERROR;
Willy Tarreau20879a02012-12-03 16:32:10 +01002271 if (!conn->err_code)
2272 conn->err_code = CO_ER_SSL_HANDSHAKE;
Emeric Brun46591952012-05-18 15:47:34 +02002273 return 0;
2274}
2275
2276/* Receive up to <count> bytes from connection <conn>'s socket and store them
Willy Tarreauabf08d92014-01-14 11:31:27 +01002277 * into buffer <buf>. Only one call to recv() is performed, unless the
Emeric Brun46591952012-05-18 15:47:34 +02002278 * buffer wraps, in which case a second call may be performed. The connection's
2279 * flags are updated with whatever special event is detected (error, read0,
2280 * empty). The caller is responsible for taking care of those events and
2281 * avoiding the call if inappropriate. The function does not call the
2282 * connection's polling update function, so the caller is responsible for this.
2283 */
2284static int ssl_sock_to_buf(struct connection *conn, struct buffer *buf, int count)
2285{
2286 int ret, done = 0;
Willy Tarreauabf08d92014-01-14 11:31:27 +01002287 int try;
Emeric Brun46591952012-05-18 15:47:34 +02002288
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02002289 if (!conn->xprt_ctx)
Emeric Brun46591952012-05-18 15:47:34 +02002290 goto out_error;
2291
2292 if (conn->flags & CO_FL_HANDSHAKE)
2293 /* a handshake was requested */
2294 return 0;
2295
Willy Tarreauabf08d92014-01-14 11:31:27 +01002296 /* let's realign the buffer to optimize I/O */
2297 if (buffer_empty(buf))
Emeric Brun46591952012-05-18 15:47:34 +02002298 buf->p = buf->data;
Emeric Brun46591952012-05-18 15:47:34 +02002299
2300 /* read the largest possible block. For this, we perform only one call
2301 * to recv() unless the buffer wraps and we exactly fill the first hunk,
2302 * in which case we accept to do it once again. A new attempt is made on
2303 * EINTR too.
2304 */
Willy Tarreau00b0fb92014-01-17 11:09:40 +01002305 while (count > 0) {
Willy Tarreauabf08d92014-01-14 11:31:27 +01002306 /* first check if we have some room after p+i */
2307 try = buf->data + buf->size - (buf->p + buf->i);
2308 /* otherwise continue between data and p-o */
2309 if (try <= 0) {
2310 try = buf->p - (buf->data + buf->o);
2311 if (try <= 0)
2312 break;
2313 }
2314 if (try > count)
2315 try = count;
2316
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02002317 ret = SSL_read(conn->xprt_ctx, bi_end(buf), try);
Emeric Brune1f38db2012-09-03 20:36:47 +02002318 if (conn->flags & CO_FL_ERROR) {
2319 /* CO_FL_ERROR may be set by ssl_sock_infocbk */
Emeric Brun644cde02012-12-14 11:21:13 +01002320 goto out_error;
Emeric Brune1f38db2012-09-03 20:36:47 +02002321 }
Emeric Brun46591952012-05-18 15:47:34 +02002322 if (ret > 0) {
2323 buf->i += ret;
2324 done += ret;
2325 if (ret < try)
2326 break;
2327 count -= ret;
Emeric Brun46591952012-05-18 15:47:34 +02002328 }
2329 else if (ret == 0) {
Emeric Brun644cde02012-12-14 11:21:13 +01002330 ret = SSL_get_error(conn->xprt_ctx, ret);
2331 if (ret != SSL_ERROR_ZERO_RETURN) {
Emeric Brun1c646862012-12-14 12:33:41 +01002332 /* error on protocol or underlying transport */
2333 if ((ret != SSL_ERROR_SYSCALL)
2334 || (errno && (errno != EAGAIN)))
2335 conn->flags |= CO_FL_ERROR;
2336
Emeric Brun644cde02012-12-14 11:21:13 +01002337 /* Clear openssl global errors stack */
2338 ERR_clear_error();
2339 }
Emeric Brun46591952012-05-18 15:47:34 +02002340 goto read0;
2341 }
2342 else {
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02002343 ret = SSL_get_error(conn->xprt_ctx, ret);
Emeric Brun46591952012-05-18 15:47:34 +02002344 if (ret == SSL_ERROR_WANT_WRITE) {
Emeric Brun8af8dd12012-11-08 17:56:20 +01002345 /* handshake is running, and it needs to enable write */
Emeric Brun46591952012-05-18 15:47:34 +02002346 conn->flags |= CO_FL_SSL_WAIT_HS;
Emeric Brun8af8dd12012-11-08 17:56:20 +01002347 __conn_sock_want_send(conn);
Emeric Brun46591952012-05-18 15:47:34 +02002348 break;
2349 }
2350 else if (ret == SSL_ERROR_WANT_READ) {
Emeric Brun282a76a2012-11-08 18:02:56 +01002351 if (SSL_renegotiate_pending(conn->xprt_ctx)) {
2352 /* handshake is running, and it may need to re-enable read */
2353 conn->flags |= CO_FL_SSL_WAIT_HS;
2354 __conn_sock_want_recv(conn);
2355 break;
2356 }
Emeric Brun46591952012-05-18 15:47:34 +02002357 /* we need to poll for retry a read later */
Willy Tarreaue1f50c42014-01-22 20:02:06 +01002358 fd_cant_recv(conn->t.sock.fd);
Emeric Brun46591952012-05-18 15:47:34 +02002359 break;
2360 }
2361 /* otherwise it's a real error */
2362 goto out_error;
2363 }
2364 }
2365 return done;
2366
2367 read0:
2368 conn_sock_read0(conn);
2369 return done;
2370 out_error:
Emeric Brun644cde02012-12-14 11:21:13 +01002371 /* Clear openssl global errors stack */
2372 ERR_clear_error();
2373
Emeric Brun46591952012-05-18 15:47:34 +02002374 conn->flags |= CO_FL_ERROR;
2375 return done;
2376}
2377
2378
2379/* Send all pending bytes from buffer <buf> to connection <conn>'s socket.
Willy Tarreau1049b1f2014-02-02 01:51:17 +01002380 * <flags> may contain some CO_SFL_* flags to hint the system about other
2381 * pending data for example, but this flag is ignored at the moment.
Emeric Brun46591952012-05-18 15:47:34 +02002382 * Only one call to send() is performed, unless the buffer wraps, in which case
2383 * a second call may be performed. The connection's flags are updated with
2384 * whatever special event is detected (error, empty). The caller is responsible
2385 * for taking care of those events and avoiding the call if inappropriate. The
2386 * function does not call the connection's polling update function, so the caller
2387 * is responsible for this.
2388 */
2389static int ssl_sock_from_buf(struct connection *conn, struct buffer *buf, int flags)
2390{
2391 int ret, try, done;
2392
2393 done = 0;
2394
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02002395 if (!conn->xprt_ctx)
Emeric Brun46591952012-05-18 15:47:34 +02002396 goto out_error;
2397
2398 if (conn->flags & CO_FL_HANDSHAKE)
2399 /* a handshake was requested */
2400 return 0;
2401
2402 /* send the largest possible block. For this we perform only one call
2403 * to send() unless the buffer wraps and we exactly fill the first hunk,
2404 * in which case we accept to do it once again.
2405 */
2406 while (buf->o) {
Kevin Hestercad82342013-05-30 15:12:41 -07002407 try = bo_contig_data(buf);
Willy Tarreaubfd59462013-02-21 07:46:09 +01002408
Willy Tarreau7bed9452014-02-02 02:00:24 +01002409 if (!(flags & CO_SFL_STREAMER) &&
Willy Tarreau518cedd2014-02-17 15:43:01 +01002410 !(conn->xprt_st & SSL_SOCK_SEND_UNLIMITED) &&
2411 global.tune.ssl_max_record && try > global.tune.ssl_max_record) {
Willy Tarreaubfd59462013-02-21 07:46:09 +01002412 try = global.tune.ssl_max_record;
Willy Tarreau518cedd2014-02-17 15:43:01 +01002413 }
2414 else {
2415 /* we need to keep the information about the fact that
2416 * we're not limiting the upcoming send(), because if it
2417 * fails, we'll have to retry with at least as many data.
2418 */
2419 conn->xprt_st |= SSL_SOCK_SEND_UNLIMITED;
2420 }
Willy Tarreaubfd59462013-02-21 07:46:09 +01002421
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02002422 ret = SSL_write(conn->xprt_ctx, bo_ptr(buf), try);
Willy Tarreau518cedd2014-02-17 15:43:01 +01002423
Emeric Brune1f38db2012-09-03 20:36:47 +02002424 if (conn->flags & CO_FL_ERROR) {
2425 /* CO_FL_ERROR may be set by ssl_sock_infocbk */
Emeric Brun644cde02012-12-14 11:21:13 +01002426 goto out_error;
Emeric Brune1f38db2012-09-03 20:36:47 +02002427 }
Emeric Brun46591952012-05-18 15:47:34 +02002428 if (ret > 0) {
Willy Tarreau518cedd2014-02-17 15:43:01 +01002429 conn->xprt_st &= ~SSL_SOCK_SEND_UNLIMITED;
2430
Emeric Brun46591952012-05-18 15:47:34 +02002431 buf->o -= ret;
2432 done += ret;
2433
Willy Tarreau5fb38032012-12-16 19:39:09 +01002434 if (likely(buffer_empty(buf)))
Emeric Brun46591952012-05-18 15:47:34 +02002435 /* optimize data alignment in the buffer */
2436 buf->p = buf->data;
2437
2438 /* if the system buffer is full, don't insist */
2439 if (ret < try)
2440 break;
2441 }
2442 else {
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02002443 ret = SSL_get_error(conn->xprt_ctx, ret);
Emeric Brun46591952012-05-18 15:47:34 +02002444 if (ret == SSL_ERROR_WANT_WRITE) {
Emeric Brun282a76a2012-11-08 18:02:56 +01002445 if (SSL_renegotiate_pending(conn->xprt_ctx)) {
2446 /* handshake is running, and it may need to re-enable write */
2447 conn->flags |= CO_FL_SSL_WAIT_HS;
2448 __conn_sock_want_send(conn);
2449 break;
2450 }
Emeric Brun46591952012-05-18 15:47:34 +02002451 /* we need to poll to retry a write later */
Willy Tarreaue1f50c42014-01-22 20:02:06 +01002452 fd_cant_send(conn->t.sock.fd);
Emeric Brun46591952012-05-18 15:47:34 +02002453 break;
2454 }
2455 else if (ret == SSL_ERROR_WANT_READ) {
Emeric Brun8af8dd12012-11-08 17:56:20 +01002456 /* handshake is running, and it needs to enable read */
Emeric Brun46591952012-05-18 15:47:34 +02002457 conn->flags |= CO_FL_SSL_WAIT_HS;
Emeric Brun8af8dd12012-11-08 17:56:20 +01002458 __conn_sock_want_recv(conn);
Emeric Brun46591952012-05-18 15:47:34 +02002459 break;
2460 }
2461 goto out_error;
2462 }
2463 }
2464 return done;
2465
2466 out_error:
Emeric Brun644cde02012-12-14 11:21:13 +01002467 /* Clear openssl global errors stack */
2468 ERR_clear_error();
2469
Emeric Brun46591952012-05-18 15:47:34 +02002470 conn->flags |= CO_FL_ERROR;
2471 return done;
2472}
2473
Emeric Brun46591952012-05-18 15:47:34 +02002474static void ssl_sock_close(struct connection *conn) {
2475
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02002476 if (conn->xprt_ctx) {
2477 SSL_free(conn->xprt_ctx);
2478 conn->xprt_ctx = NULL;
Willy Tarreau403edff2012-09-06 11:58:37 +02002479 sslconns--;
Emeric Brun46591952012-05-18 15:47:34 +02002480 }
Emeric Brun46591952012-05-18 15:47:34 +02002481}
2482
2483/* This function tries to perform a clean shutdown on an SSL connection, and in
2484 * any case, flags the connection as reusable if no handshake was in progress.
2485 */
2486static void ssl_sock_shutw(struct connection *conn, int clean)
2487{
2488 if (conn->flags & CO_FL_HANDSHAKE)
2489 return;
2490 /* no handshake was in progress, try a clean ssl shutdown */
Emeric Brun644cde02012-12-14 11:21:13 +01002491 if (clean && (SSL_shutdown(conn->xprt_ctx) <= 0)) {
2492 /* Clear openssl global errors stack */
2493 ERR_clear_error();
2494 }
Emeric Brun46591952012-05-18 15:47:34 +02002495
2496 /* force flag on ssl to keep session in cache regardless shutdown result */
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02002497 SSL_set_shutdown(conn->xprt_ctx, SSL_SENT_SHUTDOWN);
Emeric Brun46591952012-05-18 15:47:34 +02002498}
2499
Willy Tarreauffc3fcd2012-10-12 20:17:54 +02002500/* used for logging, may be changed for a sample fetch later */
2501const char *ssl_sock_get_cipher_name(struct connection *conn)
2502{
2503 if (!conn->xprt && !conn->xprt_ctx)
2504 return NULL;
2505 return SSL_get_cipher_name(conn->xprt_ctx);
2506}
2507
2508/* used for logging, may be changed for a sample fetch later */
2509const char *ssl_sock_get_proto_version(struct connection *conn)
2510{
2511 if (!conn->xprt && !conn->xprt_ctx)
2512 return NULL;
2513 return SSL_get_version(conn->xprt_ctx);
2514}
2515
Willy Tarreau8d598402012-10-22 17:58:39 +02002516/* Extract a serial from a cert, and copy it to a chunk.
2517 * Returns 1 if serial is found and copied, 0 if no serial found and
2518 * -1 if output is not large enough.
2519 */
2520static int
2521ssl_sock_get_serial(X509 *crt, struct chunk *out)
2522{
2523 ASN1_INTEGER *serial;
2524
2525 serial = X509_get_serialNumber(crt);
2526 if (!serial)
2527 return 0;
2528
2529 if (out->size < serial->length)
2530 return -1;
2531
2532 memcpy(out->str, serial->data, serial->length);
2533 out->len = serial->length;
2534 return 1;
2535}
2536
Emeric Brunb3cc4252014-10-29 19:03:26 +01002537/* Extract a cert to der, and copy it to a chunk.
2538 * Returns 1 if cert is found and copied, 0 on der convertion failure and
2539 * -1 if output is not large enough.
2540 */
2541static int
2542ssl_sock_crt2der(X509 *crt, struct chunk *out)
2543{
2544 int len;
2545 unsigned char *p = (unsigned char *)out->str;;
2546
2547 len =i2d_X509(crt, NULL);
2548 if (len <= 0)
2549 return 1;
2550
2551 if (out->size < len)
2552 return -1;
2553
2554 i2d_X509(crt,&p);
2555 out->len = len;
2556 return 1;
2557}
2558
Emeric Brunce5ad802012-10-22 14:11:22 +02002559
2560/* Copy Date in ASN1_UTCTIME format in struct chunk out.
2561 * Returns 1 if serial is found and copied, 0 if no valid time found
2562 * and -1 if output is not large enough.
2563 */
2564static int
2565ssl_sock_get_time(ASN1_TIME *tm, struct chunk *out)
2566{
2567 if (tm->type == V_ASN1_GENERALIZEDTIME) {
2568 ASN1_GENERALIZEDTIME *gentm = (ASN1_GENERALIZEDTIME *)tm;
2569
2570 if (gentm->length < 12)
2571 return 0;
2572 if (gentm->data[0] != 0x32 || gentm->data[1] != 0x30)
2573 return 0;
2574 if (out->size < gentm->length-2)
2575 return -1;
2576
2577 memcpy(out->str, gentm->data+2, gentm->length-2);
2578 out->len = gentm->length-2;
2579 return 1;
2580 }
2581 else if (tm->type == V_ASN1_UTCTIME) {
2582 ASN1_UTCTIME *utctm = (ASN1_UTCTIME *)tm;
2583
2584 if (utctm->length < 10)
2585 return 0;
2586 if (utctm->data[0] >= 0x35)
2587 return 0;
2588 if (out->size < utctm->length)
2589 return -1;
2590
2591 memcpy(out->str, utctm->data, utctm->length);
2592 out->len = utctm->length;
2593 return 1;
2594 }
2595
2596 return 0;
2597}
2598
Emeric Brun87855892012-10-17 17:39:35 +02002599/* Extract an entry from a X509_NAME and copy its value to an output chunk.
2600 * Returns 1 if entry found, 0 if entry not found, or -1 if output not large enough.
2601 */
2602static int
2603ssl_sock_get_dn_entry(X509_NAME *a, const struct chunk *entry, int pos, struct chunk *out)
2604{
2605 X509_NAME_ENTRY *ne;
2606 int i, j, n;
2607 int cur = 0;
2608 const char *s;
2609 char tmp[128];
2610
2611 out->len = 0;
2612 for (i = 0; i < sk_X509_NAME_ENTRY_num(a->entries); i++) {
2613 if (pos < 0)
2614 j = (sk_X509_NAME_ENTRY_num(a->entries)-1) - i;
2615 else
2616 j = i;
2617
2618 ne = sk_X509_NAME_ENTRY_value(a->entries, j);
2619 n = OBJ_obj2nid(ne->object);
2620 if ((n == NID_undef) || ((s = OBJ_nid2sn(n)) == NULL)) {
2621 i2t_ASN1_OBJECT(tmp, sizeof(tmp), ne->object);
2622 s = tmp;
2623 }
2624
2625 if (chunk_strcasecmp(entry, s) != 0)
2626 continue;
2627
2628 if (pos < 0)
2629 cur--;
2630 else
2631 cur++;
2632
2633 if (cur != pos)
2634 continue;
2635
2636 if (ne->value->length > out->size)
2637 return -1;
2638
2639 memcpy(out->str, ne->value->data, ne->value->length);
2640 out->len = ne->value->length;
2641 return 1;
2642 }
2643
2644 return 0;
2645
2646}
2647
2648/* Extract and format full DN from a X509_NAME and copy result into a chunk
2649 * Returns 1 if dn entries exits, 0 if no dn entry found or -1 if output is not large enough.
2650 */
2651static int
2652ssl_sock_get_dn_oneline(X509_NAME *a, struct chunk *out)
2653{
2654 X509_NAME_ENTRY *ne;
2655 int i, n, ln;
2656 int l = 0;
2657 const char *s;
2658 char *p;
2659 char tmp[128];
2660
2661 out->len = 0;
2662 p = out->str;
2663 for (i = 0; i < sk_X509_NAME_ENTRY_num(a->entries); i++) {
2664 ne = sk_X509_NAME_ENTRY_value(a->entries, i);
2665 n = OBJ_obj2nid(ne->object);
2666 if ((n == NID_undef) || ((s = OBJ_nid2sn(n)) == NULL)) {
2667 i2t_ASN1_OBJECT(tmp, sizeof(tmp), ne->object);
2668 s = tmp;
2669 }
2670 ln = strlen(s);
2671
2672 l += 1 + ln + 1 + ne->value->length;
2673 if (l > out->size)
2674 return -1;
2675 out->len = l;
2676
2677 *(p++)='/';
2678 memcpy(p, s, ln);
2679 p += ln;
2680 *(p++)='=';
2681 memcpy(p, ne->value->data, ne->value->length);
2682 p += ne->value->length;
2683 }
2684
2685 if (!out->len)
2686 return 0;
2687
2688 return 1;
2689}
2690
David Safb76832014-05-08 23:42:08 -04002691char *ssl_sock_get_version(struct connection *conn)
2692{
2693 if (!ssl_sock_is_ssl(conn))
2694 return NULL;
2695
2696 return (char *)SSL_get_version(conn->xprt_ctx);
2697}
2698
Emeric Brun49100982014-06-24 18:26:41 +02002699/* Extract peer certificate's common name into the chunk dest
2700 * Returns
2701 * the len of the extracted common name
2702 * or 0 if no CN found in DN
2703 * or -1 on error case (i.e. no peer certificate)
2704 */
2705int ssl_sock_get_remote_common_name(struct connection *conn, struct chunk *dest)
David Safb76832014-05-08 23:42:08 -04002706{
2707 X509 *crt = NULL;
2708 X509_NAME *name;
David Safb76832014-05-08 23:42:08 -04002709 const char find_cn[] = "CN";
2710 const struct chunk find_cn_chunk = {
2711 .str = (char *)&find_cn,
2712 .len = sizeof(find_cn)-1
2713 };
Emeric Brun49100982014-06-24 18:26:41 +02002714 int result = -1;
David Safb76832014-05-08 23:42:08 -04002715
2716 if (!ssl_sock_is_ssl(conn))
Emeric Brun49100982014-06-24 18:26:41 +02002717 goto out;
David Safb76832014-05-08 23:42:08 -04002718
2719 /* SSL_get_peer_certificate, it increase X509 * ref count */
2720 crt = SSL_get_peer_certificate(conn->xprt_ctx);
2721 if (!crt)
2722 goto out;
2723
2724 name = X509_get_subject_name(crt);
2725 if (!name)
2726 goto out;
David Safb76832014-05-08 23:42:08 -04002727
Emeric Brun49100982014-06-24 18:26:41 +02002728 result = ssl_sock_get_dn_entry(name, &find_cn_chunk, 1, dest);
2729out:
David Safb76832014-05-08 23:42:08 -04002730 if (crt)
2731 X509_free(crt);
2732
2733 return result;
2734}
2735
Dave McCowand6ec6052014-07-30 10:39:13 -04002736/* returns 1 if client passed a certificate for this session, 0 if not */
2737int ssl_sock_get_cert_used_sess(struct connection *conn)
2738{
2739 X509 *crt = NULL;
2740
2741 if (!ssl_sock_is_ssl(conn))
2742 return 0;
2743
2744 /* SSL_get_peer_certificate, it increase X509 * ref count */
2745 crt = SSL_get_peer_certificate(conn->xprt_ctx);
2746 if (!crt)
2747 return 0;
2748
2749 X509_free(crt);
2750 return 1;
2751}
2752
2753/* returns 1 if client passed a certificate for this connection, 0 if not */
2754int ssl_sock_get_cert_used_conn(struct connection *conn)
David Safb76832014-05-08 23:42:08 -04002755{
2756 if (!ssl_sock_is_ssl(conn))
2757 return 0;
2758
2759 return SSL_SOCK_ST_FL_VERIFY_DONE & conn->xprt_st ? 1 : 0;
2760}
2761
2762/* returns result from SSL verify */
2763unsigned int ssl_sock_get_verify_result(struct connection *conn)
2764{
2765 if (!ssl_sock_is_ssl(conn))
2766 return (unsigned int)X509_V_ERR_APPLICATION_VERIFICATION;
2767
2768 return (unsigned int)SSL_get_verify_result(conn->xprt_ctx);
2769}
2770
Willy Tarreau7875d092012-09-10 08:20:03 +02002771/***** Below are some sample fetching functions for ACL/patterns *****/
2772
Emeric Brune64aef12012-09-21 13:15:06 +02002773/* boolean, returns true if client cert was present */
2774static int
Emeric Brun2525b6b2012-10-18 15:59:43 +02002775smp_fetch_ssl_fc_has_crt(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002776 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brune64aef12012-09-21 13:15:06 +02002777{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002778 struct connection *conn;
2779
2780 if (!l4)
2781 return 0;
2782
2783 conn = objt_conn(l4->si[0].end);
2784 if (!conn || conn->xprt != &ssl_sock)
Emeric Brune64aef12012-09-21 13:15:06 +02002785 return 0;
2786
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002787 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brune64aef12012-09-21 13:15:06 +02002788 smp->flags |= SMP_F_MAY_CHANGE;
2789 return 0;
2790 }
2791
2792 smp->flags = 0;
2793 smp->type = SMP_T_BOOL;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002794 smp->data.uint = SSL_SOCK_ST_FL_VERIFY_DONE & conn->xprt_st ? 1 : 0;
Emeric Brune64aef12012-09-21 13:15:06 +02002795
2796 return 1;
2797}
2798
Emeric Brunb3cc4252014-10-29 19:03:26 +01002799/* binary, returns a certificate in a binary chunk (der/raw).
2800 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
2801 * should be use.
2802 */
2803static int
2804smp_fetch_ssl_x_der(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
2805 const struct arg *args, struct sample *smp, const char *kw)
2806{
2807 int cert_peer = (kw[4] == 'c') ? 1 : 0;
2808 X509 *crt = NULL;
2809 int ret = 0;
2810 struct chunk *smp_trash;
2811 struct connection *conn;
2812
2813 if (!l4)
2814 return 0;
2815
2816 conn = objt_conn(l4->si[0].end);
2817 if (!conn || conn->xprt != &ssl_sock)
2818 return 0;
2819
2820 if (!(conn->flags & CO_FL_CONNECTED)) {
2821 smp->flags |= SMP_F_MAY_CHANGE;
2822 return 0;
2823 }
2824
2825 if (cert_peer)
2826 crt = SSL_get_peer_certificate(conn->xprt_ctx);
2827 else
2828 crt = SSL_get_certificate(conn->xprt_ctx);
2829
2830 if (!crt)
2831 goto out;
2832
2833 smp_trash = get_trash_chunk();
2834 if (ssl_sock_crt2der(crt, smp_trash) <= 0)
2835 goto out;
2836
2837 smp->data.str = *smp_trash;
2838 smp->type = SMP_T_BIN;
2839 ret = 1;
2840out:
2841 /* SSL_get_peer_certificate, it increase X509 * ref count */
2842 if (cert_peer && crt)
2843 X509_free(crt);
2844 return ret;
2845}
2846
Emeric Brunba841a12014-04-30 17:05:08 +02002847/* binary, returns serial of certificate in a binary chunk.
2848 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
2849 * should be use.
2850 */
Willy Tarreau8d598402012-10-22 17:58:39 +02002851static int
Emeric Brunba841a12014-04-30 17:05:08 +02002852smp_fetch_ssl_x_serial(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002853 const struct arg *args, struct sample *smp, const char *kw)
Willy Tarreau8d598402012-10-22 17:58:39 +02002854{
Emeric Brunba841a12014-04-30 17:05:08 +02002855 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Willy Tarreau8d598402012-10-22 17:58:39 +02002856 X509 *crt = NULL;
2857 int ret = 0;
2858 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002859 struct connection *conn;
2860
2861 if (!l4)
2862 return 0;
Willy Tarreau8d598402012-10-22 17:58:39 +02002863
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002864 conn = objt_conn(l4->si[0].end);
2865 if (!conn || conn->xprt != &ssl_sock)
Willy Tarreau8d598402012-10-22 17:58:39 +02002866 return 0;
2867
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002868 if (!(conn->flags & CO_FL_CONNECTED)) {
Willy Tarreau8d598402012-10-22 17:58:39 +02002869 smp->flags |= SMP_F_MAY_CHANGE;
2870 return 0;
2871 }
2872
Emeric Brunba841a12014-04-30 17:05:08 +02002873 if (cert_peer)
2874 crt = SSL_get_peer_certificate(conn->xprt_ctx);
2875 else
2876 crt = SSL_get_certificate(conn->xprt_ctx);
2877
Willy Tarreau8d598402012-10-22 17:58:39 +02002878 if (!crt)
2879 goto out;
2880
Willy Tarreau47ca5452012-12-23 20:22:19 +01002881 smp_trash = get_trash_chunk();
Willy Tarreau8d598402012-10-22 17:58:39 +02002882 if (ssl_sock_get_serial(crt, smp_trash) <= 0)
2883 goto out;
2884
2885 smp->data.str = *smp_trash;
2886 smp->type = SMP_T_BIN;
2887 ret = 1;
2888out:
Emeric Brunba841a12014-04-30 17:05:08 +02002889 /* SSL_get_peer_certificate, it increase X509 * ref count */
2890 if (cert_peer && crt)
Willy Tarreau8d598402012-10-22 17:58:39 +02002891 X509_free(crt);
2892 return ret;
2893}
Emeric Brune64aef12012-09-21 13:15:06 +02002894
Emeric Brunba841a12014-04-30 17:05:08 +02002895/* binary, returns the client certificate's SHA-1 fingerprint (SHA-1 hash of DER-encoded certificate) in a binary chunk.
2896 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
2897 * should be use.
2898 */
James Votha051b4a2013-05-14 20:37:59 +02002899static int
Emeric Brunba841a12014-04-30 17:05:08 +02002900smp_fetch_ssl_x_sha1(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002901 const struct arg *args, struct sample *smp, const char *kw)
James Votha051b4a2013-05-14 20:37:59 +02002902{
Emeric Brunba841a12014-04-30 17:05:08 +02002903 int cert_peer = (kw[4] == 'c') ? 1 : 0;
James Votha051b4a2013-05-14 20:37:59 +02002904 X509 *crt = NULL;
2905 const EVP_MD *digest;
2906 int ret = 0;
2907 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002908 struct connection *conn;
James Votha051b4a2013-05-14 20:37:59 +02002909
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002910 if (!l4)
James Votha051b4a2013-05-14 20:37:59 +02002911 return 0;
2912
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002913 conn = objt_conn(l4->si[0].end);
2914 if (!conn || conn->xprt != &ssl_sock)
2915 return 0;
2916
2917 if (!(conn->flags & CO_FL_CONNECTED)) {
James Votha051b4a2013-05-14 20:37:59 +02002918 smp->flags |= SMP_F_MAY_CHANGE;
2919 return 0;
2920 }
2921
Emeric Brunba841a12014-04-30 17:05:08 +02002922 if (cert_peer)
2923 crt = SSL_get_peer_certificate(conn->xprt_ctx);
2924 else
2925 crt = SSL_get_certificate(conn->xprt_ctx);
James Votha051b4a2013-05-14 20:37:59 +02002926 if (!crt)
2927 goto out;
2928
2929 smp_trash = get_trash_chunk();
2930 digest = EVP_sha1();
2931 X509_digest(crt, digest, (unsigned char *)smp_trash->str, (unsigned int *)&smp_trash->len);
2932
2933 smp->data.str = *smp_trash;
2934 smp->type = SMP_T_BIN;
2935 ret = 1;
2936out:
Emeric Brunba841a12014-04-30 17:05:08 +02002937 /* SSL_get_peer_certificate, it increase X509 * ref count */
2938 if (cert_peer && crt)
James Votha051b4a2013-05-14 20:37:59 +02002939 X509_free(crt);
2940 return ret;
2941}
2942
Emeric Brunba841a12014-04-30 17:05:08 +02002943/* string, returns certificate's notafter date in ASN1_UTCTIME format.
2944 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
2945 * should be use.
2946 */
Emeric Brunce5ad802012-10-22 14:11:22 +02002947static int
Emeric Brunba841a12014-04-30 17:05:08 +02002948smp_fetch_ssl_x_notafter(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002949 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brunce5ad802012-10-22 14:11:22 +02002950{
Emeric Brunba841a12014-04-30 17:05:08 +02002951 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brunce5ad802012-10-22 14:11:22 +02002952 X509 *crt = NULL;
2953 int ret = 0;
2954 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002955 struct connection *conn;
Emeric Brunce5ad802012-10-22 14:11:22 +02002956
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002957 if (!l4)
Emeric Brunce5ad802012-10-22 14:11:22 +02002958 return 0;
2959
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002960 conn = objt_conn(l4->si[0].end);
2961 if (!conn || conn->xprt != &ssl_sock)
2962 return 0;
2963
2964 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunce5ad802012-10-22 14:11:22 +02002965 smp->flags |= SMP_F_MAY_CHANGE;
2966 return 0;
2967 }
2968
Emeric Brunba841a12014-04-30 17:05:08 +02002969 if (cert_peer)
2970 crt = SSL_get_peer_certificate(conn->xprt_ctx);
2971 else
2972 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brunce5ad802012-10-22 14:11:22 +02002973 if (!crt)
2974 goto out;
2975
Willy Tarreau47ca5452012-12-23 20:22:19 +01002976 smp_trash = get_trash_chunk();
Emeric Brunce5ad802012-10-22 14:11:22 +02002977 if (ssl_sock_get_time(X509_get_notAfter(crt), smp_trash) <= 0)
2978 goto out;
2979
2980 smp->data.str = *smp_trash;
2981 smp->type = SMP_T_STR;
2982 ret = 1;
2983out:
Emeric Brunba841a12014-04-30 17:05:08 +02002984 /* SSL_get_peer_certificate, it increase X509 * ref count */
2985 if (cert_peer && crt)
Emeric Brunce5ad802012-10-22 14:11:22 +02002986 X509_free(crt);
2987 return ret;
2988}
2989
Emeric Brunba841a12014-04-30 17:05:08 +02002990/* string, returns a string of a formatted full dn \C=..\O=..\OU=.. \CN=.. of certificate's issuer
2991 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
2992 * should be use.
2993 */
Emeric Brun87855892012-10-17 17:39:35 +02002994static int
Emeric Brunba841a12014-04-30 17:05:08 +02002995smp_fetch_ssl_x_i_dn(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002996 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brun87855892012-10-17 17:39:35 +02002997{
Emeric Brunba841a12014-04-30 17:05:08 +02002998 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brun87855892012-10-17 17:39:35 +02002999 X509 *crt = NULL;
3000 X509_NAME *name;
3001 int ret = 0;
3002 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003003 struct connection *conn;
Emeric Brun87855892012-10-17 17:39:35 +02003004
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003005 if (!l4)
Emeric Brun87855892012-10-17 17:39:35 +02003006 return 0;
3007
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003008 conn = objt_conn(l4->si[0].end);
3009 if (!conn || conn->xprt != &ssl_sock)
3010 return 0;
3011
3012 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun87855892012-10-17 17:39:35 +02003013 smp->flags |= SMP_F_MAY_CHANGE;
3014 return 0;
3015 }
3016
Emeric Brunba841a12014-04-30 17:05:08 +02003017 if (cert_peer)
3018 crt = SSL_get_peer_certificate(conn->xprt_ctx);
3019 else
3020 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brun87855892012-10-17 17:39:35 +02003021 if (!crt)
3022 goto out;
3023
3024 name = X509_get_issuer_name(crt);
3025 if (!name)
3026 goto out;
3027
Willy Tarreau47ca5452012-12-23 20:22:19 +01003028 smp_trash = get_trash_chunk();
Emeric Brun87855892012-10-17 17:39:35 +02003029 if (args && args[0].type == ARGT_STR) {
3030 int pos = 1;
3031
3032 if (args[1].type == ARGT_SINT)
3033 pos = args[1].data.sint;
3034 else if (args[1].type == ARGT_UINT)
3035 pos =(int)args[1].data.uint;
3036
3037 if (ssl_sock_get_dn_entry(name, &args[0].data.str, pos, smp_trash) <= 0)
3038 goto out;
3039 }
3040 else if (ssl_sock_get_dn_oneline(name, smp_trash) <= 0)
3041 goto out;
3042
3043 smp->type = SMP_T_STR;
3044 smp->data.str = *smp_trash;
3045 ret = 1;
3046out:
Emeric Brunba841a12014-04-30 17:05:08 +02003047 /* SSL_get_peer_certificate, it increase X509 * ref count */
3048 if (cert_peer && crt)
Emeric Brun87855892012-10-17 17:39:35 +02003049 X509_free(crt);
3050 return ret;
3051}
3052
Emeric Brunba841a12014-04-30 17:05:08 +02003053/* string, returns notbefore date in ASN1_UTCTIME format.
3054 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
3055 * should be use.
3056 */
Emeric Brunce5ad802012-10-22 14:11:22 +02003057static int
Emeric Brunba841a12014-04-30 17:05:08 +02003058smp_fetch_ssl_x_notbefore(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003059 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brunce5ad802012-10-22 14:11:22 +02003060{
Emeric Brunba841a12014-04-30 17:05:08 +02003061 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brunce5ad802012-10-22 14:11:22 +02003062 X509 *crt = NULL;
3063 int ret = 0;
3064 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003065 struct connection *conn;
3066
3067 if (!l4)
3068 return 0;
Emeric Brunce5ad802012-10-22 14:11:22 +02003069
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003070 conn = objt_conn(l4->si[0].end);
3071 if (!conn || conn->xprt != &ssl_sock)
Emeric Brunce5ad802012-10-22 14:11:22 +02003072 return 0;
3073
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003074 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunce5ad802012-10-22 14:11:22 +02003075 smp->flags |= SMP_F_MAY_CHANGE;
3076 return 0;
3077 }
3078
Emeric Brunba841a12014-04-30 17:05:08 +02003079 if (cert_peer)
3080 crt = SSL_get_peer_certificate(conn->xprt_ctx);
3081 else
3082 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brunce5ad802012-10-22 14:11:22 +02003083 if (!crt)
3084 goto out;
3085
Willy Tarreau47ca5452012-12-23 20:22:19 +01003086 smp_trash = get_trash_chunk();
Emeric Brunce5ad802012-10-22 14:11:22 +02003087 if (ssl_sock_get_time(X509_get_notBefore(crt), smp_trash) <= 0)
3088 goto out;
3089
3090 smp->data.str = *smp_trash;
3091 smp->type = SMP_T_STR;
3092 ret = 1;
3093out:
Emeric Brunba841a12014-04-30 17:05:08 +02003094 /* SSL_get_peer_certificate, it increase X509 * ref count */
3095 if (cert_peer && crt)
Emeric Brunce5ad802012-10-22 14:11:22 +02003096 X509_free(crt);
3097 return ret;
3098}
3099
Emeric Brunba841a12014-04-30 17:05:08 +02003100/* string, returns a string of a formatted full dn \C=..\O=..\OU=.. \CN=.. of certificate's subject
3101 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
3102 * should be use.
3103 */
Emeric Brun87855892012-10-17 17:39:35 +02003104static int
Emeric Brunba841a12014-04-30 17:05:08 +02003105smp_fetch_ssl_x_s_dn(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003106 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brun87855892012-10-17 17:39:35 +02003107{
Emeric Brunba841a12014-04-30 17:05:08 +02003108 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brun87855892012-10-17 17:39:35 +02003109 X509 *crt = NULL;
3110 X509_NAME *name;
3111 int ret = 0;
3112 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003113 struct connection *conn;
Emeric Brun87855892012-10-17 17:39:35 +02003114
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003115 if (!l4)
Emeric Brun87855892012-10-17 17:39:35 +02003116 return 0;
3117
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003118 conn = objt_conn(l4->si[0].end);
3119 if (!conn || conn->xprt != &ssl_sock)
3120 return 0;
3121
3122 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun87855892012-10-17 17:39:35 +02003123 smp->flags |= SMP_F_MAY_CHANGE;
3124 return 0;
3125 }
3126
Emeric Brunba841a12014-04-30 17:05:08 +02003127 if (cert_peer)
3128 crt = SSL_get_peer_certificate(conn->xprt_ctx);
3129 else
3130 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brun87855892012-10-17 17:39:35 +02003131 if (!crt)
3132 goto out;
3133
3134 name = X509_get_subject_name(crt);
3135 if (!name)
3136 goto out;
3137
Willy Tarreau47ca5452012-12-23 20:22:19 +01003138 smp_trash = get_trash_chunk();
Emeric Brun87855892012-10-17 17:39:35 +02003139 if (args && args[0].type == ARGT_STR) {
3140 int pos = 1;
3141
3142 if (args[1].type == ARGT_SINT)
3143 pos = args[1].data.sint;
3144 else if (args[1].type == ARGT_UINT)
3145 pos =(int)args[1].data.uint;
3146
3147 if (ssl_sock_get_dn_entry(name, &args[0].data.str, pos, smp_trash) <= 0)
3148 goto out;
3149 }
3150 else if (ssl_sock_get_dn_oneline(name, smp_trash) <= 0)
3151 goto out;
3152
3153 smp->type = SMP_T_STR;
3154 smp->data.str = *smp_trash;
3155 ret = 1;
3156out:
Emeric Brunba841a12014-04-30 17:05:08 +02003157 /* SSL_get_peer_certificate, it increase X509 * ref count */
3158 if (cert_peer && crt)
Emeric Brun87855892012-10-17 17:39:35 +02003159 X509_free(crt);
3160 return ret;
3161}
Emeric Brun9143d372012-12-20 15:44:16 +01003162
3163/* integer, returns true if current session use a client certificate */
3164static int
3165smp_fetch_ssl_c_used(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003166 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brun9143d372012-12-20 15:44:16 +01003167{
3168 X509 *crt;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003169 struct connection *conn;
Emeric Brun9143d372012-12-20 15:44:16 +01003170
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003171 if (!l4)
Emeric Brun9143d372012-12-20 15:44:16 +01003172 return 0;
3173
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003174 conn = objt_conn(l4->si[0].end);
3175 if (!conn || conn->xprt != &ssl_sock)
3176 return 0;
3177
3178 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun9143d372012-12-20 15:44:16 +01003179 smp->flags |= SMP_F_MAY_CHANGE;
3180 return 0;
3181 }
3182
3183 /* SSL_get_peer_certificate returns a ptr on allocated X509 struct */
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003184 crt = SSL_get_peer_certificate(conn->xprt_ctx);
Emeric Brun9143d372012-12-20 15:44:16 +01003185 if (crt) {
3186 X509_free(crt);
3187 }
3188
3189 smp->type = SMP_T_BOOL;
3190 smp->data.uint = (crt != NULL);
3191 return 1;
3192}
3193
Emeric Brunba841a12014-04-30 17:05:08 +02003194/* integer, returns the certificate version
3195 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
3196 * should be use.
3197 */
Emeric Bruna7359fd2012-10-17 15:03:11 +02003198static int
Emeric Brunba841a12014-04-30 17:05:08 +02003199smp_fetch_ssl_x_version(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003200 const struct arg *args, struct sample *smp, const char *kw)
Emeric Bruna7359fd2012-10-17 15:03:11 +02003201{
Emeric Brunba841a12014-04-30 17:05:08 +02003202 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Bruna7359fd2012-10-17 15:03:11 +02003203 X509 *crt;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003204 struct connection *conn;
3205
3206 if (!l4)
3207 return 0;
Emeric Bruna7359fd2012-10-17 15:03:11 +02003208
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003209 conn = objt_conn(l4->si[0].end);
3210 if (!conn || conn->xprt != &ssl_sock)
Emeric Bruna7359fd2012-10-17 15:03:11 +02003211 return 0;
3212
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003213 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Bruna7359fd2012-10-17 15:03:11 +02003214 smp->flags |= SMP_F_MAY_CHANGE;
3215 return 0;
3216 }
3217
Emeric Brunba841a12014-04-30 17:05:08 +02003218 if (cert_peer)
3219 crt = SSL_get_peer_certificate(conn->xprt_ctx);
3220 else
3221 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Bruna7359fd2012-10-17 15:03:11 +02003222 if (!crt)
3223 return 0;
3224
3225 smp->data.uint = (unsigned int)(1 + X509_get_version(crt));
Emeric Brunba841a12014-04-30 17:05:08 +02003226 /* SSL_get_peer_certificate increase X509 * ref count */
3227 if (cert_peer)
3228 X509_free(crt);
Emeric Bruna7359fd2012-10-17 15:03:11 +02003229 smp->type = SMP_T_UINT;
3230
3231 return 1;
3232}
3233
Emeric Brunba841a12014-04-30 17:05:08 +02003234/* string, returns the certificate's signature algorithm.
3235 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
3236 * should be use.
3237 */
Emeric Brun7f56e742012-10-19 18:15:40 +02003238static int
Emeric Brunba841a12014-04-30 17:05:08 +02003239smp_fetch_ssl_x_sig_alg(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003240 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brun7f56e742012-10-19 18:15:40 +02003241{
Emeric Brunba841a12014-04-30 17:05:08 +02003242 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brun7f56e742012-10-19 18:15:40 +02003243 X509 *crt;
3244 int nid;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003245 struct connection *conn;
Emeric Brun7f56e742012-10-19 18:15:40 +02003246
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003247 if (!l4)
Emeric Brun7f56e742012-10-19 18:15:40 +02003248 return 0;
3249
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003250 conn = objt_conn(l4->si[0].end);
3251 if (!conn || conn->xprt != &ssl_sock)
3252 return 0;
3253
3254 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun7f56e742012-10-19 18:15:40 +02003255 smp->flags |= SMP_F_MAY_CHANGE;
3256 return 0;
3257 }
3258
Emeric Brunba841a12014-04-30 17:05:08 +02003259 if (cert_peer)
3260 crt = SSL_get_peer_certificate(conn->xprt_ctx);
3261 else
3262 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brun7f56e742012-10-19 18:15:40 +02003263 if (!crt)
3264 return 0;
3265
3266 nid = OBJ_obj2nid((ASN1_OBJECT *)(crt->cert_info->signature->algorithm));
3267
3268 smp->data.str.str = (char *)OBJ_nid2sn(nid);
Emeric Brun9bf3ba22013-10-07 14:31:44 +02003269 if (!smp->data.str.str) {
Emeric Brunba841a12014-04-30 17:05:08 +02003270 /* SSL_get_peer_certificate increase X509 * ref count */
3271 if (cert_peer)
3272 X509_free(crt);
Emeric Brun7f56e742012-10-19 18:15:40 +02003273 return 0;
Emeric Brun9bf3ba22013-10-07 14:31:44 +02003274 }
Emeric Brun7f56e742012-10-19 18:15:40 +02003275
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01003276 smp->type = SMP_T_STR;
3277 smp->flags |= SMP_F_CONST;
Emeric Brun7f56e742012-10-19 18:15:40 +02003278 smp->data.str.len = strlen(smp->data.str.str);
Emeric Brunba841a12014-04-30 17:05:08 +02003279 /* SSL_get_peer_certificate increase X509 * ref count */
3280 if (cert_peer)
3281 X509_free(crt);
Emeric Brun7f56e742012-10-19 18:15:40 +02003282
3283 return 1;
3284}
3285
Emeric Brunba841a12014-04-30 17:05:08 +02003286/* string, returns the certificate's key algorithm.
3287 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
3288 * should be use.
3289 */
Emeric Brun521a0112012-10-22 12:22:55 +02003290static int
Emeric Brunba841a12014-04-30 17:05:08 +02003291smp_fetch_ssl_x_key_alg(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003292 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brun521a0112012-10-22 12:22:55 +02003293{
Emeric Brunba841a12014-04-30 17:05:08 +02003294 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brun521a0112012-10-22 12:22:55 +02003295 X509 *crt;
3296 int nid;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003297 struct connection *conn;
Emeric Brun521a0112012-10-22 12:22:55 +02003298
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003299 if (!l4)
Emeric Brun521a0112012-10-22 12:22:55 +02003300 return 0;
3301
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003302 conn = objt_conn(l4->si[0].end);
3303 if (!conn || conn->xprt != &ssl_sock)
3304 return 0;
3305
3306 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun521a0112012-10-22 12:22:55 +02003307 smp->flags |= SMP_F_MAY_CHANGE;
3308 return 0;
3309 }
3310
Emeric Brunba841a12014-04-30 17:05:08 +02003311 if (cert_peer)
3312 crt = SSL_get_peer_certificate(conn->xprt_ctx);
3313 else
3314 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brun521a0112012-10-22 12:22:55 +02003315 if (!crt)
3316 return 0;
3317
3318 nid = OBJ_obj2nid((ASN1_OBJECT *)(crt->cert_info->key->algor->algorithm));
3319
3320 smp->data.str.str = (char *)OBJ_nid2sn(nid);
Emeric Brun9bf3ba22013-10-07 14:31:44 +02003321 if (!smp->data.str.str) {
Emeric Brunba841a12014-04-30 17:05:08 +02003322 /* SSL_get_peer_certificate increase X509 * ref count */
3323 if (cert_peer)
3324 X509_free(crt);
Emeric Brun521a0112012-10-22 12:22:55 +02003325 return 0;
Emeric Brun9bf3ba22013-10-07 14:31:44 +02003326 }
Emeric Brun521a0112012-10-22 12:22:55 +02003327
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01003328 smp->type = SMP_T_STR;
3329 smp->flags |= SMP_F_CONST;
Emeric Brun521a0112012-10-22 12:22:55 +02003330 smp->data.str.len = strlen(smp->data.str.str);
Emeric Brunba841a12014-04-30 17:05:08 +02003331 if (cert_peer)
3332 X509_free(crt);
Emeric Brun521a0112012-10-22 12:22:55 +02003333
3334 return 1;
3335}
3336
Emeric Brun645ae792014-04-30 14:21:06 +02003337/* boolean, returns true if front conn. transport layer is SSL.
3338 * This function is also usable on backend conn if the fetch keyword 5th
3339 * char is 'b'.
3340 */
Willy Tarreau7875d092012-09-10 08:20:03 +02003341static int
Emeric Brun2525b6b2012-10-18 15:59:43 +02003342smp_fetch_ssl_fc(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003343 const struct arg *args, struct sample *smp, const char *kw)
Willy Tarreau7875d092012-09-10 08:20:03 +02003344{
Emeric Brun645ae792014-04-30 14:21:06 +02003345 int back_conn = (kw[4] == 'b') ? 1 : 0;
3346 struct connection *conn = objt_conn(l4->si[back_conn].end);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003347
Willy Tarreau7875d092012-09-10 08:20:03 +02003348 smp->type = SMP_T_BOOL;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003349 smp->data.uint = (conn && conn->xprt == &ssl_sock);
Willy Tarreau7875d092012-09-10 08:20:03 +02003350 return 1;
3351}
3352
Emeric Brun2525b6b2012-10-18 15:59:43 +02003353/* boolean, returns true if client present a SNI */
Willy Tarreau7875d092012-09-10 08:20:03 +02003354static int
Emeric Brun2525b6b2012-10-18 15:59:43 +02003355smp_fetch_ssl_fc_has_sni(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003356 const struct arg *args, struct sample *smp, const char *kw)
Willy Tarreau7875d092012-09-10 08:20:03 +02003357{
3358#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003359 struct connection *conn = objt_conn(l4->si[0].end);
3360
Willy Tarreau7875d092012-09-10 08:20:03 +02003361 smp->type = SMP_T_BOOL;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003362 smp->data.uint = (conn && conn->xprt == &ssl_sock) &&
3363 conn->xprt_ctx &&
3364 SSL_get_servername(conn->xprt_ctx, TLSEXT_NAMETYPE_host_name) != NULL;
Willy Tarreau7875d092012-09-10 08:20:03 +02003365 return 1;
3366#else
3367 return 0;
3368#endif
3369}
3370
Emeric Brun645ae792014-04-30 14:21:06 +02003371/* string, returns the used cipher if front conn. transport layer is SSL.
3372 * This function is also usable on backend conn if the fetch keyword 5th
3373 * char is 'b'.
3374 */
Emeric Brun589fcad2012-10-16 14:13:26 +02003375static int
3376smp_fetch_ssl_fc_cipher(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003377 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brun589fcad2012-10-16 14:13:26 +02003378{
Emeric Brun645ae792014-04-30 14:21:06 +02003379 int back_conn = (kw[4] == 'b') ? 1 : 0;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003380 struct connection *conn;
3381
Emeric Brun589fcad2012-10-16 14:13:26 +02003382 smp->flags = 0;
3383
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003384 if (!l4)
3385 return 0;
3386
Emeric Brun645ae792014-04-30 14:21:06 +02003387 conn = objt_conn(l4->si[back_conn].end);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003388 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
Emeric Brun589fcad2012-10-16 14:13:26 +02003389 return 0;
3390
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003391 smp->data.str.str = (char *)SSL_get_cipher_name(conn->xprt_ctx);
Emeric Brun589fcad2012-10-16 14:13:26 +02003392 if (!smp->data.str.str)
3393 return 0;
3394
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01003395 smp->type = SMP_T_STR;
3396 smp->flags |= SMP_F_CONST;
Emeric Brun589fcad2012-10-16 14:13:26 +02003397 smp->data.str.len = strlen(smp->data.str.str);
3398
3399 return 1;
3400}
3401
Emeric Brun645ae792014-04-30 14:21:06 +02003402/* integer, returns the algoritm's keysize if front conn. transport layer
3403 * is SSL.
3404 * This function is also usable on backend conn if the fetch keyword 5th
3405 * char is 'b'.
3406 */
Emeric Brun589fcad2012-10-16 14:13:26 +02003407static int
3408smp_fetch_ssl_fc_alg_keysize(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003409 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brun589fcad2012-10-16 14:13:26 +02003410{
Emeric Brun645ae792014-04-30 14:21:06 +02003411 int back_conn = (kw[4] == 'b') ? 1 : 0;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003412 struct connection *conn;
3413
Emeric Brun589fcad2012-10-16 14:13:26 +02003414 smp->flags = 0;
3415
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003416 if (!l4)
Emeric Brun589fcad2012-10-16 14:13:26 +02003417 return 0;
3418
Emeric Brun645ae792014-04-30 14:21:06 +02003419 conn = objt_conn(l4->si[back_conn].end);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003420 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
Emeric Brun589fcad2012-10-16 14:13:26 +02003421 return 0;
3422
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003423 if (!SSL_get_cipher_bits(conn->xprt_ctx, (int *)&smp->data.uint))
3424 return 0;
3425
Emeric Brun589fcad2012-10-16 14:13:26 +02003426 smp->type = SMP_T_UINT;
3427
3428 return 1;
3429}
3430
Emeric Brun645ae792014-04-30 14:21:06 +02003431/* integer, returns the used keysize if front conn. transport layer is SSL.
3432 * This function is also usable on backend conn if the fetch keyword 5th
3433 * char is 'b'.
3434 */
Emeric Brun589fcad2012-10-16 14:13:26 +02003435static int
3436smp_fetch_ssl_fc_use_keysize(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003437 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brun589fcad2012-10-16 14:13:26 +02003438{
Emeric Brun645ae792014-04-30 14:21:06 +02003439 int back_conn = (kw[4] == 'b') ? 1 : 0;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003440 struct connection *conn;
3441
Emeric Brun589fcad2012-10-16 14:13:26 +02003442 smp->flags = 0;
3443
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003444 if (!l4)
Emeric Brun589fcad2012-10-16 14:13:26 +02003445 return 0;
3446
Emeric Brun645ae792014-04-30 14:21:06 +02003447 conn = objt_conn(l4->si[back_conn].end);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003448 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
3449 return 0;
3450
3451 smp->data.uint = (unsigned int)SSL_get_cipher_bits(conn->xprt_ctx, NULL);
Emeric Brun589fcad2012-10-16 14:13:26 +02003452 if (!smp->data.uint)
3453 return 0;
3454
3455 smp->type = SMP_T_UINT;
3456
3457 return 1;
3458}
3459
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02003460#ifdef OPENSSL_NPN_NEGOTIATED
Willy Tarreau7875d092012-09-10 08:20:03 +02003461static int
Emeric Brun2525b6b2012-10-18 15:59:43 +02003462smp_fetch_ssl_fc_npn(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003463 const struct arg *args, struct sample *smp, const char *kw)
Willy Tarreaua33c6542012-10-15 13:19:06 +02003464{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003465 struct connection *conn;
3466
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01003467 smp->flags = SMP_F_CONST;
3468 smp->type = SMP_T_STR;
Willy Tarreaua33c6542012-10-15 13:19:06 +02003469
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003470 if (!l4)
Willy Tarreaua33c6542012-10-15 13:19:06 +02003471 return 0;
3472
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003473 conn = objt_conn(l4->si[0].end);
3474 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
3475 return 0;
3476
Willy Tarreaua33c6542012-10-15 13:19:06 +02003477 smp->data.str.str = NULL;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003478 SSL_get0_next_proto_negotiated(conn->xprt_ctx,
Willy Tarreaua33c6542012-10-15 13:19:06 +02003479 (const unsigned char **)&smp->data.str.str, (unsigned *)&smp->data.str.len);
3480
3481 if (!smp->data.str.str)
3482 return 0;
3483
3484 return 1;
Willy Tarreaua33c6542012-10-15 13:19:06 +02003485}
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02003486#endif
Willy Tarreaua33c6542012-10-15 13:19:06 +02003487
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01003488#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Willy Tarreauab861d32013-04-02 02:30:41 +02003489static int
3490smp_fetch_ssl_fc_alpn(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003491 const struct arg *args, struct sample *smp, const char *kw)
Willy Tarreauab861d32013-04-02 02:30:41 +02003492{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003493 struct connection *conn;
3494
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01003495 smp->flags = SMP_F_CONST;
3496 smp->type = SMP_T_STR;
Willy Tarreauab861d32013-04-02 02:30:41 +02003497
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003498 if (!l4)
3499 return 0;
3500
3501 conn = objt_conn(l4->si[0].end);
3502 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
Willy Tarreauab861d32013-04-02 02:30:41 +02003503 return 0;
3504
3505 smp->data.str.str = NULL;
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01003506 SSL_get0_alpn_selected(conn->xprt_ctx,
Willy Tarreauab861d32013-04-02 02:30:41 +02003507 (const unsigned char **)&smp->data.str.str, (unsigned *)&smp->data.str.len);
3508
3509 if (!smp->data.str.str)
3510 return 0;
3511
3512 return 1;
3513}
3514#endif
3515
Emeric Brun645ae792014-04-30 14:21:06 +02003516/* string, returns the used protocol if front conn. transport layer is SSL.
3517 * This function is also usable on backend conn if the fetch keyword 5th
3518 * char is 'b'.
3519 */
Willy Tarreaua33c6542012-10-15 13:19:06 +02003520static int
Emeric Brun589fcad2012-10-16 14:13:26 +02003521smp_fetch_ssl_fc_protocol(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003522 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brun589fcad2012-10-16 14:13:26 +02003523{
Emeric Brun645ae792014-04-30 14:21:06 +02003524 int back_conn = (kw[4] == 'b') ? 1 : 0;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003525 struct connection *conn;
3526
Emeric Brun589fcad2012-10-16 14:13:26 +02003527 smp->flags = 0;
3528
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003529 if (!l4)
Emeric Brun589fcad2012-10-16 14:13:26 +02003530 return 0;
3531
Emeric Brun645ae792014-04-30 14:21:06 +02003532 conn = objt_conn(l4->si[back_conn].end);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003533 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
3534 return 0;
3535
3536 smp->data.str.str = (char *)SSL_get_version(conn->xprt_ctx);
Emeric Brun589fcad2012-10-16 14:13:26 +02003537 if (!smp->data.str.str)
3538 return 0;
3539
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01003540 smp->type = SMP_T_STR;
3541 smp->flags = SMP_F_CONST;
Emeric Brun589fcad2012-10-16 14:13:26 +02003542 smp->data.str.len = strlen(smp->data.str.str);
3543
3544 return 1;
3545}
3546
Emeric Brun645ae792014-04-30 14:21:06 +02003547/* binary, returns the SSL session id if front conn. transport layer is SSL.
3548 * This function is also usable on backend conn if the fetch keyword 5th
3549 * char is 'b'.
3550 */
Emeric Brun589fcad2012-10-16 14:13:26 +02003551static int
Emeric Brunfe68f682012-10-16 14:59:28 +02003552smp_fetch_ssl_fc_session_id(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003553 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brunfe68f682012-10-16 14:59:28 +02003554{
3555#if OPENSSL_VERSION_NUMBER > 0x0090800fL
Emeric Brun645ae792014-04-30 14:21:06 +02003556 int back_conn = (kw[4] == 'b') ? 1 : 0;
Emeric Brunfe68f682012-10-16 14:59:28 +02003557 SSL_SESSION *sess;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003558 struct connection *conn;
Emeric Brunfe68f682012-10-16 14:59:28 +02003559
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01003560 smp->flags = SMP_F_CONST;
3561 smp->type = SMP_T_BIN;
Emeric Brunfe68f682012-10-16 14:59:28 +02003562
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003563 if (!l4)
Emeric Brunfe68f682012-10-16 14:59:28 +02003564 return 0;
3565
Emeric Brun645ae792014-04-30 14:21:06 +02003566 conn = objt_conn(l4->si[back_conn].end);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003567 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
3568 return 0;
3569
3570 sess = SSL_get_session(conn->xprt_ctx);
Emeric Brunfe68f682012-10-16 14:59:28 +02003571 if (!sess)
3572 return 0;
3573
3574 smp->data.str.str = (char *)SSL_SESSION_get_id(sess, (unsigned int *)&smp->data.str.len);
Willy Tarreau69760db2015-06-17 18:34:14 +02003575 if (!smp->data.str.str || !smp->data.str.len)
Emeric Brunfe68f682012-10-16 14:59:28 +02003576 return 0;
3577
3578 return 1;
3579#else
3580 return 0;
3581#endif
3582}
3583
3584static int
Emeric Brun2525b6b2012-10-18 15:59:43 +02003585smp_fetch_ssl_fc_sni(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003586 const struct arg *args, struct sample *smp, const char *kw)
Willy Tarreau7875d092012-09-10 08:20:03 +02003587{
3588#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003589 struct connection *conn;
3590
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01003591 smp->flags = SMP_F_CONST;
3592 smp->type = SMP_T_STR;
Willy Tarreau7875d092012-09-10 08:20:03 +02003593
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003594 if (!l4)
Willy Tarreau7875d092012-09-10 08:20:03 +02003595 return 0;
3596
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003597 conn = objt_conn(l4->si[0].end);
3598 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
3599 return 0;
3600
3601 smp->data.str.str = (char *)SSL_get_servername(conn->xprt_ctx, TLSEXT_NAMETYPE_host_name);
Willy Tarreau3e394c92012-09-14 23:56:58 +02003602 if (!smp->data.str.str)
3603 return 0;
3604
Willy Tarreau7875d092012-09-10 08:20:03 +02003605 smp->data.str.len = strlen(smp->data.str.str);
3606 return 1;
3607#else
3608 return 0;
3609#endif
3610}
3611
David Sc1ad52e2014-04-08 18:48:47 -04003612static int
3613smp_fetch_ssl_fc_unique_id(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
3614 const struct arg *args, struct sample *smp, const char *kw)
3615{
3616#if OPENSSL_VERSION_NUMBER > 0x0090800fL
Emeric Brun645ae792014-04-30 14:21:06 +02003617 int back_conn = (kw[4] == 'b') ? 1 : 0;
David Sc1ad52e2014-04-08 18:48:47 -04003618 struct connection *conn;
3619 int finished_len;
David Sc1ad52e2014-04-08 18:48:47 -04003620 struct chunk *finished_trash;
David Sc1ad52e2014-04-08 18:48:47 -04003621
3622 smp->flags = 0;
3623
3624 if (!l4)
3625 return 0;
3626
Emeric Brun645ae792014-04-30 14:21:06 +02003627 conn = objt_conn(l4->si[back_conn].end);
David Sc1ad52e2014-04-08 18:48:47 -04003628 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
3629 return 0;
3630
3631 if (!(conn->flags & CO_FL_CONNECTED)) {
3632 smp->flags |= SMP_F_MAY_CHANGE;
3633 return 0;
3634 }
3635
3636 finished_trash = get_trash_chunk();
3637 if (!SSL_session_reused(conn->xprt_ctx))
3638 finished_len = SSL_get_peer_finished(conn->xprt_ctx, finished_trash->str, finished_trash->size);
3639 else
3640 finished_len = SSL_get_finished(conn->xprt_ctx, finished_trash->str, finished_trash->size);
3641
3642 if (!finished_len)
3643 return 0;
3644
Emeric Brunb73a9b02014-04-30 18:49:19 +02003645 finished_trash->len = finished_len;
3646 smp->data.str = *finished_trash;
3647 smp->type = SMP_T_BIN;
David Sc1ad52e2014-04-08 18:48:47 -04003648
3649 return 1;
3650#else
3651 return 0;
3652#endif
3653}
3654
Emeric Brun2525b6b2012-10-18 15:59:43 +02003655/* integer, returns the first verify error in CA chain of client certificate chain. */
Emeric Brunf282a812012-09-21 15:27:54 +02003656static int
Emeric Brun2525b6b2012-10-18 15:59:43 +02003657smp_fetch_ssl_c_ca_err(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003658 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brunf282a812012-09-21 15:27:54 +02003659{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003660 struct connection *conn;
3661
3662 if (!l4)
Emeric Brunf282a812012-09-21 15:27:54 +02003663 return 0;
3664
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003665 conn = objt_conn(l4->si[0].end);
3666 if (!conn || conn->xprt != &ssl_sock)
3667 return 0;
3668
3669 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunf282a812012-09-21 15:27:54 +02003670 smp->flags = SMP_F_MAY_CHANGE;
3671 return 0;
3672 }
3673
3674 smp->type = SMP_T_UINT;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003675 smp->data.uint = (unsigned int)SSL_SOCK_ST_TO_CA_ERROR(conn->xprt_st);
Emeric Brunf282a812012-09-21 15:27:54 +02003676 smp->flags = 0;
3677
3678 return 1;
3679}
3680
Emeric Brun2525b6b2012-10-18 15:59:43 +02003681/* integer, returns the depth of the first verify error in CA chain of client certificate chain. */
Emeric Brunf282a812012-09-21 15:27:54 +02003682static int
Emeric Brun2525b6b2012-10-18 15:59:43 +02003683smp_fetch_ssl_c_ca_err_depth(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003684 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brunf282a812012-09-21 15:27:54 +02003685{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003686 struct connection *conn;
3687
3688 if (!l4)
3689 return 0;
3690
3691 conn = objt_conn(l4->si[0].end);
3692 if (!conn || conn->xprt != &ssl_sock)
Emeric Brunf282a812012-09-21 15:27:54 +02003693 return 0;
3694
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003695 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunf282a812012-09-21 15:27:54 +02003696 smp->flags = SMP_F_MAY_CHANGE;
3697 return 0;
3698 }
3699
3700 smp->type = SMP_T_UINT;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003701 smp->data.uint = (unsigned int)SSL_SOCK_ST_TO_CAEDEPTH(conn->xprt_st);
Emeric Brunf282a812012-09-21 15:27:54 +02003702 smp->flags = 0;
3703
3704 return 1;
3705}
3706
Emeric Brun2525b6b2012-10-18 15:59:43 +02003707/* integer, returns the first verify error on client certificate */
Emeric Brunf282a812012-09-21 15:27:54 +02003708static int
Emeric Brun2525b6b2012-10-18 15:59:43 +02003709smp_fetch_ssl_c_err(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003710 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brunf282a812012-09-21 15:27:54 +02003711{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003712 struct connection *conn;
3713
3714 if (!l4)
Emeric Brunf282a812012-09-21 15:27:54 +02003715 return 0;
3716
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003717 conn = objt_conn(l4->si[0].end);
3718 if (!conn || conn->xprt != &ssl_sock)
3719 return 0;
3720
3721 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunf282a812012-09-21 15:27:54 +02003722 smp->flags = SMP_F_MAY_CHANGE;
3723 return 0;
3724 }
3725
3726 smp->type = SMP_T_UINT;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003727 smp->data.uint = (unsigned int)SSL_SOCK_ST_TO_CRTERROR(conn->xprt_st);
Emeric Brunf282a812012-09-21 15:27:54 +02003728 smp->flags = 0;
3729
3730 return 1;
3731}
3732
Emeric Brun2525b6b2012-10-18 15:59:43 +02003733/* integer, returns the verify result on client cert */
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02003734static int
Emeric Brun2525b6b2012-10-18 15:59:43 +02003735smp_fetch_ssl_c_verify(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003736 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02003737{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003738 struct connection *conn;
3739
3740 if (!l4)
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02003741 return 0;
3742
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003743 conn = objt_conn(l4->si[0].end);
3744 if (!conn || conn->xprt != &ssl_sock)
3745 return 0;
3746
3747 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02003748 smp->flags = SMP_F_MAY_CHANGE;
3749 return 0;
3750 }
3751
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003752 if (!conn->xprt_ctx)
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02003753 return 0;
3754
3755 smp->type = SMP_T_UINT;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003756 smp->data.uint = (unsigned int)SSL_get_verify_result(conn->xprt_ctx);
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02003757 smp->flags = 0;
3758
3759 return 1;
3760}
3761
Emeric Brunfb510ea2012-10-05 12:00:26 +02003762/* parse the "ca-file" bind keyword */
3763static 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 +02003764{
3765 if (!*args[cur_arg + 1]) {
3766 if (err)
3767 memprintf(err, "'%s' : missing CAfile path", args[cur_arg]);
3768 return ERR_ALERT | ERR_FATAL;
3769 }
3770
Emeric Brunef42d922012-10-11 16:11:36 +02003771 if ((*args[cur_arg + 1] != '/') && global.ca_base)
3772 memprintf(&conf->ca_file, "%s/%s", global.ca_base, args[cur_arg + 1]);
3773 else
3774 memprintf(&conf->ca_file, "%s", args[cur_arg + 1]);
Emeric Brunc8e8d122012-10-02 18:42:10 +02003775
Emeric Brund94b3fe2012-09-20 18:23:56 +02003776 return 0;
3777}
3778
Willy Tarreau79eeafa2012-09-14 07:53:05 +02003779/* parse the "ciphers" bind keyword */
Willy Tarreau4348fad2012-09-20 16:48:07 +02003780static 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 +02003781{
3782 if (!*args[cur_arg + 1]) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02003783 memprintf(err, "'%s' : missing cipher suite", args[cur_arg]);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02003784 return ERR_ALERT | ERR_FATAL;
3785 }
3786
Emeric Brun76d88952012-10-05 15:47:31 +02003787 free(conf->ciphers);
Willy Tarreau4348fad2012-09-20 16:48:07 +02003788 conf->ciphers = strdup(args[cur_arg + 1]);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02003789 return 0;
3790}
3791
3792/* parse the "crt" bind keyword */
Willy Tarreau4348fad2012-09-20 16:48:07 +02003793static 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 +02003794{
Willy Tarreau38011032013-08-13 16:59:39 +02003795 char path[MAXPATHLEN];
Willy Tarreaub75d6922014-04-14 18:05:41 +02003796
Willy Tarreau79eeafa2012-09-14 07:53:05 +02003797 if (!*args[cur_arg + 1]) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02003798 memprintf(err, "'%s' : missing certificate location", args[cur_arg]);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02003799 return ERR_ALERT | ERR_FATAL;
3800 }
3801
Emeric Brunc8e8d122012-10-02 18:42:10 +02003802 if ((*args[cur_arg + 1] != '/' ) && global.crt_base) {
Willy Tarreau38011032013-08-13 16:59:39 +02003803 if ((strlen(global.crt_base) + 1 + strlen(args[cur_arg + 1]) + 1) > MAXPATHLEN) {
Emeric Brunc8e8d122012-10-02 18:42:10 +02003804 memprintf(err, "'%s' : path too long", args[cur_arg]);
3805 return ERR_ALERT | ERR_FATAL;
3806 }
Willy Tarreaub75d6922014-04-14 18:05:41 +02003807 snprintf(path, sizeof(path), "%s/%s", global.crt_base, args[cur_arg + 1]);
Emeric Brunc8e8d122012-10-02 18:42:10 +02003808 if (ssl_sock_load_cert(path, conf, px, err) > 0)
3809 return ERR_ALERT | ERR_FATAL;
3810
3811 return 0;
3812 }
3813
Willy Tarreau4348fad2012-09-20 16:48:07 +02003814 if (ssl_sock_load_cert(args[cur_arg + 1], conf, px, err) > 0)
Willy Tarreau79eeafa2012-09-14 07:53:05 +02003815 return ERR_ALERT | ERR_FATAL;
Emeric Brund94b3fe2012-09-20 18:23:56 +02003816
3817 return 0;
3818}
3819
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01003820/* parse the "crt-list" bind keyword */
3821static int bind_parse_crt_list(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
3822{
3823 if (!*args[cur_arg + 1]) {
3824 memprintf(err, "'%s' : missing certificate location", args[cur_arg]);
3825 return ERR_ALERT | ERR_FATAL;
3826 }
3827
Willy Tarreauad1731d2013-04-02 17:35:58 +02003828 if (ssl_sock_load_cert_list_file(args[cur_arg + 1], conf, px, err) > 0) {
3829 memprintf(err, "'%s' : %s", args[cur_arg], *err);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01003830 return ERR_ALERT | ERR_FATAL;
Willy Tarreauad1731d2013-04-02 17:35:58 +02003831 }
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01003832
3833 return 0;
3834}
3835
Emeric Brunfb510ea2012-10-05 12:00:26 +02003836/* parse the "crl-file" bind keyword */
3837static 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 +02003838{
Emeric Brun051cdab2012-10-02 19:25:50 +02003839#ifndef X509_V_FLAG_CRL_CHECK
3840 if (err)
3841 memprintf(err, "'%s' : library does not support CRL verify", args[cur_arg]);
3842 return ERR_ALERT | ERR_FATAL;
3843#else
Emeric Brund94b3fe2012-09-20 18:23:56 +02003844 if (!*args[cur_arg + 1]) {
3845 if (err)
3846 memprintf(err, "'%s' : missing CRLfile path", args[cur_arg]);
3847 return ERR_ALERT | ERR_FATAL;
3848 }
Emeric Brun2b58d042012-09-20 17:10:03 +02003849
Emeric Brunef42d922012-10-11 16:11:36 +02003850 if ((*args[cur_arg + 1] != '/') && global.ca_base)
3851 memprintf(&conf->crl_file, "%s/%s", global.ca_base, args[cur_arg + 1]);
3852 else
3853 memprintf(&conf->crl_file, "%s", args[cur_arg + 1]);
Emeric Brunc8e8d122012-10-02 18:42:10 +02003854
Emeric Brun2b58d042012-09-20 17:10:03 +02003855 return 0;
Emeric Brun051cdab2012-10-02 19:25:50 +02003856#endif
Emeric Brun2b58d042012-09-20 17:10:03 +02003857}
3858
3859/* parse the "ecdhe" bind keyword keywords */
3860static int bind_parse_ecdhe(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
3861{
3862#if OPENSSL_VERSION_NUMBER < 0x0090800fL
3863 if (err)
3864 memprintf(err, "'%s' : library does not support elliptic curve Diffie-Hellman (too old)", args[cur_arg]);
3865 return ERR_ALERT | ERR_FATAL;
3866#elif defined(OPENSSL_NO_ECDH)
3867 if (err)
3868 memprintf(err, "'%s' : library does not support elliptic curve Diffie-Hellman (disabled via OPENSSL_NO_ECDH)", args[cur_arg]);
3869 return ERR_ALERT | ERR_FATAL;
3870#else
3871 if (!*args[cur_arg + 1]) {
3872 if (err)
3873 memprintf(err, "'%s' : missing named curve", args[cur_arg]);
3874 return ERR_ALERT | ERR_FATAL;
3875 }
3876
3877 conf->ecdhe = strdup(args[cur_arg + 1]);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02003878
3879 return 0;
Emeric Brun2b58d042012-09-20 17:10:03 +02003880#endif
Willy Tarreau79eeafa2012-09-14 07:53:05 +02003881}
3882
Emeric Brun81c00f02012-09-21 14:31:21 +02003883/* parse the "crt_ignerr" and "ca_ignerr" bind keywords */
3884static int bind_parse_ignore_err(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
3885{
3886 int code;
3887 char *p = args[cur_arg + 1];
3888 unsigned long long *ignerr = &conf->crt_ignerr;
3889
3890 if (!*p) {
3891 if (err)
3892 memprintf(err, "'%s' : missing error IDs list", args[cur_arg]);
3893 return ERR_ALERT | ERR_FATAL;
3894 }
3895
3896 if (strcmp(args[cur_arg], "ca-ignore-err") == 0)
3897 ignerr = &conf->ca_ignerr;
3898
3899 if (strcmp(p, "all") == 0) {
3900 *ignerr = ~0ULL;
3901 return 0;
3902 }
3903
3904 while (p) {
3905 code = atoi(p);
3906 if ((code <= 0) || (code > 63)) {
3907 if (err)
3908 memprintf(err, "'%s' : ID '%d' out of range (1..63) in error IDs list '%s'",
3909 args[cur_arg], code, args[cur_arg + 1]);
3910 return ERR_ALERT | ERR_FATAL;
3911 }
3912 *ignerr |= 1ULL << code;
3913 p = strchr(p, ',');
3914 if (p)
3915 p++;
3916 }
3917
Emeric Brun2cb7ae52012-10-05 14:14:21 +02003918 return 0;
3919}
3920
3921/* parse the "force-sslv3" bind keyword */
3922static int bind_parse_force_sslv3(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
3923{
3924 conf->ssl_options |= BC_SSL_O_USE_SSLV3;
3925 return 0;
3926}
3927
3928/* parse the "force-tlsv10" bind keyword */
3929static int bind_parse_force_tlsv10(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
3930{
3931 conf->ssl_options |= BC_SSL_O_USE_TLSV10;
Emeric Brun2d0c4822012-10-02 13:45:20 +02003932 return 0;
3933}
3934
Emeric Brun2cb7ae52012-10-05 14:14:21 +02003935/* parse the "force-tlsv11" bind keyword */
3936static int bind_parse_force_tlsv11(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
3937{
3938#if SSL_OP_NO_TLSv1_1
3939 conf->ssl_options |= BC_SSL_O_USE_TLSV11;
3940 return 0;
3941#else
3942 if (err)
3943 memprintf(err, "'%s' : library does not support protocol TLSv1.1", args[cur_arg]);
3944 return ERR_ALERT | ERR_FATAL;
3945#endif
3946}
3947
3948/* parse the "force-tlsv12" bind keyword */
3949static int bind_parse_force_tlsv12(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
3950{
3951#if SSL_OP_NO_TLSv1_2
3952 conf->ssl_options |= BC_SSL_O_USE_TLSV12;
3953 return 0;
3954#else
3955 if (err)
3956 memprintf(err, "'%s' : library does not support protocol TLSv1.2", args[cur_arg]);
3957 return ERR_ALERT | ERR_FATAL;
3958#endif
3959}
3960
3961
Emeric Brun2d0c4822012-10-02 13:45:20 +02003962/* parse the "no-tls-tickets" bind keyword */
3963static int bind_parse_no_tls_tickets(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
3964{
Emeric Brun89675492012-10-05 13:48:26 +02003965 conf->ssl_options |= BC_SSL_O_NO_TLS_TICKETS;
Emeric Brun81c00f02012-09-21 14:31:21 +02003966 return 0;
3967}
3968
Emeric Brun2d0c4822012-10-02 13:45:20 +02003969
Emeric Brun9b3009b2012-10-05 11:55:06 +02003970/* parse the "no-sslv3" bind keyword */
3971static 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 +02003972{
Emeric Brun89675492012-10-05 13:48:26 +02003973 conf->ssl_options |= BC_SSL_O_NO_SSLV3;
Willy Tarreau79eeafa2012-09-14 07:53:05 +02003974 return 0;
3975}
3976
Emeric Brun9b3009b2012-10-05 11:55:06 +02003977/* parse the "no-tlsv10" bind keyword */
3978static 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 +02003979{
Emeric Brun89675492012-10-05 13:48:26 +02003980 conf->ssl_options |= BC_SSL_O_NO_TLSV10;
Emeric Brunc0ff4922012-09-28 19:37:02 +02003981 return 0;
3982}
3983
Emeric Brun9b3009b2012-10-05 11:55:06 +02003984/* parse the "no-tlsv11" bind keyword */
3985static 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 +02003986{
Emeric Brun89675492012-10-05 13:48:26 +02003987 conf->ssl_options |= BC_SSL_O_NO_TLSV11;
Emeric Brunc0ff4922012-09-28 19:37:02 +02003988 return 0;
3989}
3990
Emeric Brun9b3009b2012-10-05 11:55:06 +02003991/* parse the "no-tlsv12" bind keyword */
3992static 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 +02003993{
Emeric Brun89675492012-10-05 13:48:26 +02003994 conf->ssl_options |= BC_SSL_O_NO_TLSV12;
Willy Tarreau79eeafa2012-09-14 07:53:05 +02003995 return 0;
3996}
3997
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02003998/* parse the "npn" bind keyword */
3999static int bind_parse_npn(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
4000{
4001#ifdef OPENSSL_NPN_NEGOTIATED
4002 char *p1, *p2;
4003
4004 if (!*args[cur_arg + 1]) {
4005 memprintf(err, "'%s' : missing the comma-delimited NPN protocol suite", args[cur_arg]);
4006 return ERR_ALERT | ERR_FATAL;
4007 }
4008
4009 free(conf->npn_str);
4010
Willy Tarreau8760ef02016-02-12 17:11:12 +01004011 /* the NPN string is built as a suite of (<len> <name>)*,
4012 * so we reuse each comma to store the next <len> and need
4013 * one more for the end of the string.
4014 */
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02004015 conf->npn_len = strlen(args[cur_arg + 1]) + 1;
Willy Tarreau8760ef02016-02-12 17:11:12 +01004016 conf->npn_str = calloc(1, conf->npn_len + 1);
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02004017 memcpy(conf->npn_str + 1, args[cur_arg + 1], conf->npn_len);
4018
4019 /* replace commas with the name length */
4020 p1 = conf->npn_str;
4021 p2 = p1 + 1;
4022 while (1) {
4023 p2 = memchr(p1 + 1, ',', conf->npn_str + conf->npn_len - (p1 + 1));
4024 if (!p2)
4025 p2 = p1 + 1 + strlen(p1 + 1);
4026
4027 if (p2 - (p1 + 1) > 255) {
4028 *p2 = '\0';
4029 memprintf(err, "'%s' : NPN protocol name too long : '%s'", args[cur_arg], p1 + 1);
4030 return ERR_ALERT | ERR_FATAL;
4031 }
4032
4033 *p1 = p2 - (p1 + 1);
4034 p1 = p2;
4035
4036 if (!*p2)
4037 break;
4038
4039 *(p2++) = '\0';
4040 }
4041 return 0;
4042#else
4043 if (err)
4044 memprintf(err, "'%s' : library does not support TLS NPN extension", args[cur_arg]);
4045 return ERR_ALERT | ERR_FATAL;
4046#endif
4047}
4048
Willy Tarreauab861d32013-04-02 02:30:41 +02004049/* parse the "alpn" bind keyword */
4050static int bind_parse_alpn(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
4051{
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01004052#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Willy Tarreauab861d32013-04-02 02:30:41 +02004053 char *p1, *p2;
4054
4055 if (!*args[cur_arg + 1]) {
4056 memprintf(err, "'%s' : missing the comma-delimited ALPN protocol suite", args[cur_arg]);
4057 return ERR_ALERT | ERR_FATAL;
4058 }
4059
4060 free(conf->alpn_str);
4061
Marcoen Hirschberg9344dd02016-02-12 17:05:24 +01004062 /* the ALPN string is built as a suite of (<len> <name>)*,
4063 * so we reuse each comma to store the next <len> and need
4064 * one more for the end of the string.
4065 */
Willy Tarreauab861d32013-04-02 02:30:41 +02004066 conf->alpn_len = strlen(args[cur_arg + 1]) + 1;
Marcoen Hirschberg9344dd02016-02-12 17:05:24 +01004067 conf->alpn_str = calloc(1, conf->alpn_len + 1);
Willy Tarreauab861d32013-04-02 02:30:41 +02004068 memcpy(conf->alpn_str + 1, args[cur_arg + 1], conf->alpn_len);
4069
4070 /* replace commas with the name length */
4071 p1 = conf->alpn_str;
4072 p2 = p1 + 1;
4073 while (1) {
4074 p2 = memchr(p1 + 1, ',', conf->alpn_str + conf->alpn_len - (p1 + 1));
4075 if (!p2)
4076 p2 = p1 + 1 + strlen(p1 + 1);
4077
4078 if (p2 - (p1 + 1) > 255) {
4079 *p2 = '\0';
4080 memprintf(err, "'%s' : ALPN protocol name too long : '%s'", args[cur_arg], p1 + 1);
4081 return ERR_ALERT | ERR_FATAL;
4082 }
4083
4084 *p1 = p2 - (p1 + 1);
4085 p1 = p2;
4086
4087 if (!*p2)
4088 break;
4089
4090 *(p2++) = '\0';
4091 }
4092 return 0;
4093#else
4094 if (err)
4095 memprintf(err, "'%s' : library does not support TLS ALPN extension", args[cur_arg]);
4096 return ERR_ALERT | ERR_FATAL;
4097#endif
4098}
4099
Willy Tarreau79eeafa2012-09-14 07:53:05 +02004100/* parse the "ssl" bind keyword */
Willy Tarreau4348fad2012-09-20 16:48:07 +02004101static 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 +02004102{
Willy Tarreau81796be2012-09-22 19:11:47 +02004103 struct listener *l;
4104
Willy Tarreau4348fad2012-09-20 16:48:07 +02004105 conf->is_ssl = 1;
Emeric Brun76d88952012-10-05 15:47:31 +02004106
4107 if (global.listen_default_ciphers && !conf->ciphers)
4108 conf->ciphers = strdup(global.listen_default_ciphers);
Emeric Brun42a3e202014-10-30 15:56:50 +01004109 conf->ssl_options |= global.listen_default_ssloptions;
Emeric Brun76d88952012-10-05 15:47:31 +02004110
Willy Tarreau81796be2012-09-22 19:11:47 +02004111 list_for_each_entry(l, &conf->listeners, by_bind)
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02004112 l->xprt = &ssl_sock;
Willy Tarreau81796be2012-09-22 19:11:47 +02004113
Willy Tarreau79eeafa2012-09-14 07:53:05 +02004114 return 0;
4115}
4116
Emmanuel Hocdet65623372013-01-24 17:17:15 +01004117/* parse the "strict-sni" bind keyword */
4118static int bind_parse_strict_sni(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
4119{
4120 conf->strict_sni = 1;
4121 return 0;
4122}
4123
Emeric Brund94b3fe2012-09-20 18:23:56 +02004124/* parse the "verify" bind keyword */
4125static int bind_parse_verify(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
4126{
4127 if (!*args[cur_arg + 1]) {
4128 if (err)
4129 memprintf(err, "'%s' : missing verify method", args[cur_arg]);
4130 return ERR_ALERT | ERR_FATAL;
4131 }
4132
4133 if (strcmp(args[cur_arg + 1], "none") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01004134 conf->verify = SSL_SOCK_VERIFY_NONE;
Emeric Brund94b3fe2012-09-20 18:23:56 +02004135 else if (strcmp(args[cur_arg + 1], "optional") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01004136 conf->verify = SSL_SOCK_VERIFY_OPTIONAL;
Emeric Brund94b3fe2012-09-20 18:23:56 +02004137 else if (strcmp(args[cur_arg + 1], "required") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01004138 conf->verify = SSL_SOCK_VERIFY_REQUIRED;
Emeric Brund94b3fe2012-09-20 18:23:56 +02004139 else {
4140 if (err)
4141 memprintf(err, "'%s' : unknown verify method '%s', only 'none', 'optional', and 'required' are supported\n",
4142 args[cur_arg], args[cur_arg + 1]);
4143 return ERR_ALERT | ERR_FATAL;
4144 }
4145
4146 return 0;
4147}
4148
Willy Tarreau92faadf2012-10-10 23:04:25 +02004149/************** "server" keywords ****************/
4150
Emeric Brunef42d922012-10-11 16:11:36 +02004151/* parse the "ca-file" server keyword */
4152static int srv_parse_ca_file(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4153{
4154 if (!*args[*cur_arg + 1]) {
4155 if (err)
4156 memprintf(err, "'%s' : missing CAfile path", args[*cur_arg]);
4157 return ERR_ALERT | ERR_FATAL;
4158 }
4159
4160 if ((*args[*cur_arg + 1] != '/') && global.ca_base)
4161 memprintf(&newsrv->ssl_ctx.ca_file, "%s/%s", global.ca_base, args[*cur_arg + 1]);
4162 else
4163 memprintf(&newsrv->ssl_ctx.ca_file, "%s", args[*cur_arg + 1]);
4164
4165 return 0;
4166}
4167
Willy Tarreau92faadf2012-10-10 23:04:25 +02004168/* parse the "check-ssl" server keyword */
4169static int srv_parse_check_ssl(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4170{
4171 newsrv->check.use_ssl = 1;
4172 if (global.connect_default_ciphers && !newsrv->ssl_ctx.ciphers)
4173 newsrv->ssl_ctx.ciphers = strdup(global.connect_default_ciphers);
Emeric Brun42a3e202014-10-30 15:56:50 +01004174 newsrv->ssl_ctx.options |= global.connect_default_ssloptions;
Willy Tarreau92faadf2012-10-10 23:04:25 +02004175 return 0;
4176}
4177
4178/* parse the "ciphers" server keyword */
4179static int srv_parse_ciphers(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4180{
4181 if (!*args[*cur_arg + 1]) {
4182 memprintf(err, "'%s' : missing cipher suite", args[*cur_arg]);
4183 return ERR_ALERT | ERR_FATAL;
4184 }
4185
4186 free(newsrv->ssl_ctx.ciphers);
4187 newsrv->ssl_ctx.ciphers = strdup(args[*cur_arg + 1]);
4188 return 0;
4189}
4190
Emeric Brunef42d922012-10-11 16:11:36 +02004191/* parse the "crl-file" server keyword */
4192static int srv_parse_crl_file(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4193{
4194#ifndef X509_V_FLAG_CRL_CHECK
4195 if (err)
4196 memprintf(err, "'%s' : library does not support CRL verify", args[*cur_arg]);
4197 return ERR_ALERT | ERR_FATAL;
4198#else
4199 if (!*args[*cur_arg + 1]) {
4200 if (err)
4201 memprintf(err, "'%s' : missing CRLfile path", args[*cur_arg]);
4202 return ERR_ALERT | ERR_FATAL;
4203 }
4204
4205 if ((*args[*cur_arg + 1] != '/') && global.ca_base)
4206 memprintf(&newsrv->ssl_ctx.crl_file, "%s/%s", global.ca_base, args[*cur_arg + 1]);
4207 else
4208 memprintf(&newsrv->ssl_ctx.crl_file, "%s", args[*cur_arg + 1]);
4209
4210 return 0;
4211#endif
4212}
4213
Emeric Bruna7aa3092012-10-26 12:58:00 +02004214/* parse the "crt" server keyword */
4215static int srv_parse_crt(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4216{
4217 if (!*args[*cur_arg + 1]) {
4218 if (err)
4219 memprintf(err, "'%s' : missing certificate file path", args[*cur_arg]);
4220 return ERR_ALERT | ERR_FATAL;
4221 }
4222
4223 if ((*args[*cur_arg + 1] != '/') && global.crt_base)
4224 memprintf(&newsrv->ssl_ctx.client_crt, "%s/%s", global.ca_base, args[*cur_arg + 1]);
4225 else
4226 memprintf(&newsrv->ssl_ctx.client_crt, "%s", args[*cur_arg + 1]);
4227
4228 return 0;
4229}
Emeric Brunef42d922012-10-11 16:11:36 +02004230
Willy Tarreau92faadf2012-10-10 23:04:25 +02004231/* parse the "force-sslv3" server keyword */
4232static int srv_parse_force_sslv3(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4233{
4234 newsrv->ssl_ctx.options |= SRV_SSL_O_USE_SSLV3;
4235 return 0;
4236}
4237
4238/* parse the "force-tlsv10" server keyword */
4239static int srv_parse_force_tlsv10(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4240{
4241 newsrv->ssl_ctx.options |= SRV_SSL_O_USE_TLSV10;
4242 return 0;
4243}
4244
4245/* parse the "force-tlsv11" server keyword */
4246static int srv_parse_force_tlsv11(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4247{
4248#if SSL_OP_NO_TLSv1_1
4249 newsrv->ssl_ctx.options |= SRV_SSL_O_USE_TLSV11;
4250 return 0;
4251#else
4252 if (err)
4253 memprintf(err, "'%s' : library does not support protocol TLSv1.1", args[*cur_arg]);
4254 return ERR_ALERT | ERR_FATAL;
4255#endif
4256}
4257
4258/* parse the "force-tlsv12" server keyword */
4259static int srv_parse_force_tlsv12(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4260{
4261#if SSL_OP_NO_TLSv1_2
4262 newsrv->ssl_ctx.options |= SRV_SSL_O_USE_TLSV12;
4263 return 0;
4264#else
4265 if (err)
4266 memprintf(err, "'%s' : library does not support protocol TLSv1.2", args[*cur_arg]);
4267 return ERR_ALERT | ERR_FATAL;
4268#endif
4269}
4270
4271/* parse the "no-sslv3" server keyword */
4272static int srv_parse_no_sslv3(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4273{
4274 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_SSLV3;
4275 return 0;
4276}
4277
4278/* parse the "no-tlsv10" server keyword */
4279static int srv_parse_no_tlsv10(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4280{
4281 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_TLSV10;
4282 return 0;
4283}
4284
4285/* parse the "no-tlsv11" server keyword */
4286static int srv_parse_no_tlsv11(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4287{
4288 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_TLSV11;
4289 return 0;
4290}
4291
4292/* parse the "no-tlsv12" server keyword */
4293static int srv_parse_no_tlsv12(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4294{
4295 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_TLSV12;
4296 return 0;
4297}
4298
Emeric Brunf9c5c472012-10-11 15:28:34 +02004299/* parse the "no-tls-tickets" server keyword */
4300static int srv_parse_no_tls_tickets(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4301{
4302 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_TLS_TICKETS;
4303 return 0;
4304}
David Safb76832014-05-08 23:42:08 -04004305/* parse the "send-proxy-v2-ssl" server keyword */
4306static int srv_parse_send_proxy_ssl(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4307{
4308 newsrv->pp_opts |= SRV_PP_V2;
4309 newsrv->pp_opts |= SRV_PP_V2_SSL;
4310 return 0;
4311}
4312
4313/* parse the "send-proxy-v2-ssl-cn" server keyword */
4314static int srv_parse_send_proxy_cn(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4315{
4316 newsrv->pp_opts |= SRV_PP_V2;
4317 newsrv->pp_opts |= SRV_PP_V2_SSL;
4318 newsrv->pp_opts |= SRV_PP_V2_SSL_CN;
4319 return 0;
4320}
Emeric Brunf9c5c472012-10-11 15:28:34 +02004321
Willy Tarreau92faadf2012-10-10 23:04:25 +02004322/* parse the "ssl" server keyword */
4323static int srv_parse_ssl(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4324{
4325 newsrv->use_ssl = 1;
4326 if (global.connect_default_ciphers && !newsrv->ssl_ctx.ciphers)
4327 newsrv->ssl_ctx.ciphers = strdup(global.connect_default_ciphers);
4328 return 0;
4329}
4330
Emeric Brunef42d922012-10-11 16:11:36 +02004331/* parse the "verify" server keyword */
4332static int srv_parse_verify(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4333{
4334 if (!*args[*cur_arg + 1]) {
4335 if (err)
4336 memprintf(err, "'%s' : missing verify method", args[*cur_arg]);
4337 return ERR_ALERT | ERR_FATAL;
4338 }
4339
4340 if (strcmp(args[*cur_arg + 1], "none") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01004341 newsrv->ssl_ctx.verify = SSL_SOCK_VERIFY_NONE;
Emeric Brunef42d922012-10-11 16:11:36 +02004342 else if (strcmp(args[*cur_arg + 1], "required") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01004343 newsrv->ssl_ctx.verify = SSL_SOCK_VERIFY_REQUIRED;
Emeric Brunef42d922012-10-11 16:11:36 +02004344 else {
4345 if (err)
4346 memprintf(err, "'%s' : unknown verify method '%s', only 'none' and 'required' are supported\n",
4347 args[*cur_arg], args[*cur_arg + 1]);
4348 return ERR_ALERT | ERR_FATAL;
4349 }
4350
Evan Broderbe554312013-06-27 00:05:25 -07004351 return 0;
4352}
4353
4354/* parse the "verifyhost" server keyword */
4355static int srv_parse_verifyhost(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4356{
4357 if (!*args[*cur_arg + 1]) {
4358 if (err)
4359 memprintf(err, "'%s' : missing hostname to verify against", args[*cur_arg]);
4360 return ERR_ALERT | ERR_FATAL;
4361 }
4362
4363 newsrv->ssl_ctx.verify_host = strdup(args[*cur_arg + 1]);
4364
Emeric Brunef42d922012-10-11 16:11:36 +02004365 return 0;
4366}
4367
Emeric Brun42a3e202014-10-30 15:56:50 +01004368/* parse the "ssl-default-bind-options" keyword in global section */
4369static int ssl_parse_default_bind_options(char **args, int section_type, struct proxy *curpx,
4370 struct proxy *defpx, const char *file, int line,
4371 char **err) {
4372 int i = 1;
4373
4374 if (*(args[i]) == 0) {
4375 memprintf(err, "global statement '%s' expects an option as an argument.", args[0]);
4376 return -1;
4377 }
4378 while (*(args[i])) {
4379 if (!strcmp(args[i], "no-sslv3"))
4380 global.listen_default_ssloptions |= BC_SSL_O_NO_SSLV3;
4381 else if (!strcmp(args[i], "no-tlsv10"))
4382 global.listen_default_ssloptions |= BC_SSL_O_NO_TLSV10;
4383 else if (!strcmp(args[i], "no-tlsv11"))
4384 global.listen_default_ssloptions |= BC_SSL_O_NO_TLSV11;
4385 else if (!strcmp(args[i], "no-tlsv12"))
4386 global.listen_default_ssloptions |= BC_SSL_O_NO_TLSV12;
4387 else if (!strcmp(args[i], "force-sslv3"))
4388 global.listen_default_ssloptions |= BC_SSL_O_USE_SSLV3;
4389 else if (!strcmp(args[i], "force-tlsv10"))
4390 global.listen_default_ssloptions |= BC_SSL_O_USE_TLSV10;
4391 else if (!strcmp(args[i], "force-tlsv11")) {
4392#if SSL_OP_NO_TLSv1_1
4393 global.listen_default_ssloptions |= BC_SSL_O_USE_TLSV11;
4394#else
4395 memprintf(err, "'%s' '%s': library does not support protocol TLSv1.1", args[0], args[i]);
4396 return -1;
4397#endif
4398 }
4399 else if (!strcmp(args[i], "force-tlsv12")) {
4400#if SSL_OP_NO_TLSv1_2
4401 global.listen_default_ssloptions |= BC_SSL_O_USE_TLSV12;
4402#else
4403 memprintf(err, "'%s' '%s': library does not support protocol TLSv1.2", args[0], args[i]);
4404 return -1;
4405#endif
4406 }
4407 else if (!strcmp(args[i], "no-tls-tickets"))
4408 global.listen_default_ssloptions |= BC_SSL_O_NO_TLS_TICKETS;
4409 else {
4410 memprintf(err, "unknown option '%s' on global statement '%s'.", args[i], args[0]);
4411 return -1;
4412 }
4413 i++;
4414 }
4415 return 0;
4416}
4417
4418/* parse the "ssl-default-server-options" keyword in global section */
4419static int ssl_parse_default_server_options(char **args, int section_type, struct proxy *curpx,
4420 struct proxy *defpx, const char *file, int line,
4421 char **err) {
4422 int i = 1;
4423
4424 if (*(args[i]) == 0) {
4425 memprintf(err, "global statement '%s' expects an option as an argument.", args[0]);
4426 return -1;
4427 }
4428 while (*(args[i])) {
4429 if (!strcmp(args[i], "no-sslv3"))
4430 global.connect_default_ssloptions |= SRV_SSL_O_NO_SSLV3;
4431 else if (!strcmp(args[i], "no-tlsv10"))
4432 global.connect_default_ssloptions |= SRV_SSL_O_NO_TLSV10;
4433 else if (!strcmp(args[i], "no-tlsv11"))
4434 global.connect_default_ssloptions |= SRV_SSL_O_NO_TLSV11;
4435 else if (!strcmp(args[i], "no-tlsv12"))
4436 global.connect_default_ssloptions |= SRV_SSL_O_NO_TLSV12;
4437 else if (!strcmp(args[i], "force-sslv3"))
4438 global.connect_default_ssloptions |= SRV_SSL_O_USE_SSLV3;
4439 else if (!strcmp(args[i], "force-tlsv10"))
4440 global.connect_default_ssloptions |= SRV_SSL_O_USE_TLSV10;
4441 else if (!strcmp(args[i], "force-tlsv11")) {
4442#if SSL_OP_NO_TLSv1_1
4443 global.connect_default_ssloptions |= SRV_SSL_O_USE_TLSV11;
4444#else
4445 memprintf(err, "'%s' '%s': library does not support protocol TLSv1.1", args[0], args[i]);
4446 return -1;
4447#endif
4448 }
4449 else if (!strcmp(args[i], "force-tlsv12")) {
4450#if SSL_OP_NO_TLSv1_2
4451 global.connect_default_ssloptions |= SRV_SSL_O_USE_TLSV12;
4452#else
4453 memprintf(err, "'%s' '%s': library does not support protocol TLSv1.2", args[0], args[i]);
4454 return -1;
4455#endif
4456 }
4457 else if (!strcmp(args[i], "no-tls-tickets"))
4458 global.connect_default_ssloptions |= SRV_SSL_O_NO_TLS_TICKETS;
4459 else {
4460 memprintf(err, "unknown option '%s' on global statement '%s'.", args[i], args[0]);
4461 return -1;
4462 }
4463 i++;
4464 }
4465 return 0;
4466}
4467
Willy Tarreau7875d092012-09-10 08:20:03 +02004468/* Note: must not be declared <const> as its list will be overwritten.
4469 * Please take care of keeping this list alphabetically sorted.
4470 */
Willy Tarreaudc13c112013-06-21 23:16:39 +02004471static struct sample_fetch_kw_list sample_fetch_keywords = {ILH, {
Emeric Brun645ae792014-04-30 14:21:06 +02004472 { "ssl_bc", smp_fetch_ssl_fc, 0, NULL, SMP_T_BOOL, SMP_USE_L5SRV },
4473 { "ssl_bc_alg_keysize", smp_fetch_ssl_fc_alg_keysize, 0, NULL, SMP_T_UINT, SMP_USE_L5SRV },
4474 { "ssl_bc_cipher", smp_fetch_ssl_fc_cipher, 0, NULL, SMP_T_STR, SMP_USE_L5SRV },
4475 { "ssl_bc_protocol", smp_fetch_ssl_fc_protocol, 0, NULL, SMP_T_STR, SMP_USE_L5SRV },
Emeric Brunb73a9b02014-04-30 18:49:19 +02004476 { "ssl_bc_unique_id", smp_fetch_ssl_fc_unique_id, 0, NULL, SMP_T_BIN, SMP_USE_L5SRV },
Emeric Brun645ae792014-04-30 14:21:06 +02004477 { "ssl_bc_use_keysize", smp_fetch_ssl_fc_use_keysize, 0, NULL, SMP_T_UINT, SMP_USE_L5SRV },
4478 { "ssl_bc_session_id", smp_fetch_ssl_fc_session_id, 0, NULL, SMP_T_BIN, SMP_USE_L5SRV },
Willy Tarreau80aca902013-01-07 15:42:20 +01004479 { "ssl_c_ca_err", smp_fetch_ssl_c_ca_err, 0, NULL, SMP_T_UINT, SMP_USE_L5CLI },
4480 { "ssl_c_ca_err_depth", smp_fetch_ssl_c_ca_err_depth, 0, NULL, SMP_T_UINT, SMP_USE_L5CLI },
Emeric Brunb3cc4252014-10-29 19:03:26 +01004481 { "ssl_c_der", smp_fetch_ssl_x_der, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Willy Tarreau80aca902013-01-07 15:42:20 +01004482 { "ssl_c_err", smp_fetch_ssl_c_err, 0, NULL, SMP_T_UINT, SMP_USE_L5CLI },
Emeric Brunba841a12014-04-30 17:05:08 +02004483 { "ssl_c_i_dn", smp_fetch_ssl_x_i_dn, ARG2(0,STR,SINT), NULL, SMP_T_STR, SMP_USE_L5CLI },
4484 { "ssl_c_key_alg", smp_fetch_ssl_x_key_alg, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
4485 { "ssl_c_notafter", smp_fetch_ssl_x_notafter, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
4486 { "ssl_c_notbefore", smp_fetch_ssl_x_notbefore, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
4487 { "ssl_c_sig_alg", smp_fetch_ssl_x_sig_alg, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
4488 { "ssl_c_s_dn", smp_fetch_ssl_x_s_dn, ARG2(0,STR,SINT), NULL, SMP_T_STR, SMP_USE_L5CLI },
4489 { "ssl_c_serial", smp_fetch_ssl_x_serial, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
4490 { "ssl_c_sha1", smp_fetch_ssl_x_sha1, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Willy Tarreau80aca902013-01-07 15:42:20 +01004491 { "ssl_c_used", smp_fetch_ssl_c_used, 0, NULL, SMP_T_BOOL, SMP_USE_L5CLI },
4492 { "ssl_c_verify", smp_fetch_ssl_c_verify, 0, NULL, SMP_T_UINT, SMP_USE_L5CLI },
Emeric Brunba841a12014-04-30 17:05:08 +02004493 { "ssl_c_version", smp_fetch_ssl_x_version, 0, NULL, SMP_T_UINT, SMP_USE_L5CLI },
Emeric Brunb3cc4252014-10-29 19:03:26 +01004494 { "ssl_f_der", smp_fetch_ssl_x_der, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Emeric Brunba841a12014-04-30 17:05:08 +02004495 { "ssl_f_i_dn", smp_fetch_ssl_x_i_dn, ARG2(0,STR,SINT), NULL, SMP_T_STR, SMP_USE_L5CLI },
4496 { "ssl_f_key_alg", smp_fetch_ssl_x_key_alg, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
4497 { "ssl_f_notafter", smp_fetch_ssl_x_notafter, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
4498 { "ssl_f_notbefore", smp_fetch_ssl_x_notbefore, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
4499 { "ssl_f_sig_alg", smp_fetch_ssl_x_sig_alg, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
4500 { "ssl_f_s_dn", smp_fetch_ssl_x_s_dn, ARG2(0,STR,SINT), NULL, SMP_T_STR, SMP_USE_L5CLI },
4501 { "ssl_f_serial", smp_fetch_ssl_x_serial, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Emeric Brun55f4fa82014-04-30 17:11:25 +02004502 { "ssl_f_sha1", smp_fetch_ssl_x_sha1, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Emeric Brunba841a12014-04-30 17:05:08 +02004503 { "ssl_f_version", smp_fetch_ssl_x_version, 0, NULL, SMP_T_UINT, SMP_USE_L5CLI },
Willy Tarreau80aca902013-01-07 15:42:20 +01004504 { "ssl_fc", smp_fetch_ssl_fc, 0, NULL, SMP_T_BOOL, SMP_USE_L5CLI },
4505 { "ssl_fc_alg_keysize", smp_fetch_ssl_fc_alg_keysize, 0, NULL, SMP_T_UINT, SMP_USE_L5CLI },
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01004506 { "ssl_fc_cipher", smp_fetch_ssl_fc_cipher, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Willy Tarreau80aca902013-01-07 15:42:20 +01004507 { "ssl_fc_has_crt", smp_fetch_ssl_fc_has_crt, 0, NULL, SMP_T_BOOL, SMP_USE_L5CLI },
4508 { "ssl_fc_has_sni", smp_fetch_ssl_fc_has_sni, 0, NULL, SMP_T_BOOL, SMP_USE_L5CLI },
Willy Tarreaua33c6542012-10-15 13:19:06 +02004509#ifdef OPENSSL_NPN_NEGOTIATED
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01004510 { "ssl_fc_npn", smp_fetch_ssl_fc_npn, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Willy Tarreaua33c6542012-10-15 13:19:06 +02004511#endif
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01004512#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01004513 { "ssl_fc_alpn", smp_fetch_ssl_fc_alpn, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Willy Tarreauab861d32013-04-02 02:30:41 +02004514#endif
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01004515 { "ssl_fc_protocol", smp_fetch_ssl_fc_protocol, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Emeric Brunb73a9b02014-04-30 18:49:19 +02004516 { "ssl_fc_unique_id", smp_fetch_ssl_fc_unique_id, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Willy Tarreau80aca902013-01-07 15:42:20 +01004517 { "ssl_fc_use_keysize", smp_fetch_ssl_fc_use_keysize, 0, NULL, SMP_T_UINT, SMP_USE_L5CLI },
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01004518 { "ssl_fc_session_id", smp_fetch_ssl_fc_session_id, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
4519 { "ssl_fc_sni", smp_fetch_ssl_fc_sni, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Willy Tarreau7875d092012-09-10 08:20:03 +02004520 { NULL, NULL, 0, 0, 0 },
4521}};
4522
4523/* Note: must not be declared <const> as its list will be overwritten.
4524 * Please take care of keeping this list alphabetically sorted.
4525 */
Willy Tarreaudc13c112013-06-21 23:16:39 +02004526static struct acl_kw_list acl_kws = {ILH, {
Thierry FOURNIERc5a4e982014-03-05 16:07:08 +01004527 { "ssl_fc_sni_end", "ssl_fc_sni", PAT_MATCH_END },
4528 { "ssl_fc_sni_reg", "ssl_fc_sni", PAT_MATCH_REG },
Willy Tarreau8ed669b2013-01-11 15:49:37 +01004529 { /* END */ },
Willy Tarreau7875d092012-09-10 08:20:03 +02004530}};
4531
Willy Tarreau79eeafa2012-09-14 07:53:05 +02004532/* Note: must not be declared <const> as its list will be overwritten.
4533 * Please take care of keeping this list alphabetically sorted, doing so helps
4534 * all code contributors.
4535 * Optional keywords are also declared with a NULL ->parse() function so that
4536 * the config parser can report an appropriate error when a known keyword was
4537 * not enabled.
4538 */
Willy Tarreau51fb7652012-09-18 18:24:39 +02004539static struct bind_kw_list bind_kws = { "SSL", { }, {
Willy Tarreauab861d32013-04-02 02:30:41 +02004540 { "alpn", bind_parse_alpn, 1 }, /* set ALPN supported protocols */
Emeric Brunfb510ea2012-10-05 12:00:26 +02004541 { "ca-file", bind_parse_ca_file, 1 }, /* set CAfile to process verify on client cert */
Emeric Brun2d0c4822012-10-02 13:45:20 +02004542 { "ca-ignore-err", bind_parse_ignore_err, 1 }, /* set error IDs to ignore on verify depth > 0 */
4543 { "ciphers", bind_parse_ciphers, 1 }, /* set SSL cipher suite */
Emeric Brunfb510ea2012-10-05 12:00:26 +02004544 { "crl-file", bind_parse_crl_file, 1 }, /* set certificat revocation list file use on client cert verify */
Emeric Brun2d0c4822012-10-02 13:45:20 +02004545 { "crt", bind_parse_crt, 1 }, /* load SSL certificates from this location */
4546 { "crt-ignore-err", bind_parse_ignore_err, 1 }, /* set error IDs to ingore on verify depth == 0 */
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01004547 { "crt-list", bind_parse_crt_list, 1 }, /* load a list of crt from this location */
Emeric Brun2d0c4822012-10-02 13:45:20 +02004548 { "ecdhe", bind_parse_ecdhe, 1 }, /* defines named curve for elliptic curve Diffie-Hellman */
Emeric Brun2cb7ae52012-10-05 14:14:21 +02004549 { "force-sslv3", bind_parse_force_sslv3, 0 }, /* force SSLv3 */
4550 { "force-tlsv10", bind_parse_force_tlsv10, 0 }, /* force TLSv10 */
4551 { "force-tlsv11", bind_parse_force_tlsv11, 0 }, /* force TLSv11 */
4552 { "force-tlsv12", bind_parse_force_tlsv12, 0 }, /* force TLSv12 */
Emeric Brun9b3009b2012-10-05 11:55:06 +02004553 { "no-sslv3", bind_parse_no_sslv3, 0 }, /* disable SSLv3 */
4554 { "no-tlsv10", bind_parse_no_tlsv10, 0 }, /* disable TLSv10 */
4555 { "no-tlsv11", bind_parse_no_tlsv11, 0 }, /* disable TLSv11 */
4556 { "no-tlsv12", bind_parse_no_tlsv12, 0 }, /* disable TLSv12 */
Emeric Brun2d0c4822012-10-02 13:45:20 +02004557 { "no-tls-tickets", bind_parse_no_tls_tickets, 0 }, /* disable session resumption tickets */
Emeric Brun2d0c4822012-10-02 13:45:20 +02004558 { "ssl", bind_parse_ssl, 0 }, /* enable SSL processing */
Emmanuel Hocdet65623372013-01-24 17:17:15 +01004559 { "strict-sni", bind_parse_strict_sni, 0 }, /* refuse negotiation if sni doesn't match a certificate */
Emeric Brun2d0c4822012-10-02 13:45:20 +02004560 { "verify", bind_parse_verify, 1 }, /* set SSL verify method */
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02004561 { "npn", bind_parse_npn, 1 }, /* set NPN supported protocols */
Willy Tarreau79eeafa2012-09-14 07:53:05 +02004562 { NULL, NULL, 0 },
4563}};
Emeric Brun46591952012-05-18 15:47:34 +02004564
Willy Tarreau92faadf2012-10-10 23:04:25 +02004565/* Note: must not be declared <const> as its list will be overwritten.
4566 * Please take care of keeping this list alphabetically sorted, doing so helps
4567 * all code contributors.
4568 * Optional keywords are also declared with a NULL ->parse() function so that
4569 * the config parser can report an appropriate error when a known keyword was
4570 * not enabled.
4571 */
4572static struct srv_kw_list srv_kws = { "SSL", { }, {
Emeric Brunef42d922012-10-11 16:11:36 +02004573 { "ca-file", srv_parse_ca_file, 1, 0 }, /* set CAfile to process verify server cert */
Emeric Brunecc91fe2012-10-11 15:05:10 +02004574 { "check-ssl", srv_parse_check_ssl, 0, 0 }, /* enable SSL for health checks */
4575 { "ciphers", srv_parse_ciphers, 1, 0 }, /* select the cipher suite */
Emeric Brunef42d922012-10-11 16:11:36 +02004576 { "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 +02004577 { "crt", srv_parse_crt, 1, 0 }, /* set client certificate */
Emeric Brunecc91fe2012-10-11 15:05:10 +02004578 { "force-sslv3", srv_parse_force_sslv3, 0, 0 }, /* force SSLv3 */
4579 { "force-tlsv10", srv_parse_force_tlsv10, 0, 0 }, /* force TLSv10 */
4580 { "force-tlsv11", srv_parse_force_tlsv11, 0, 0 }, /* force TLSv11 */
4581 { "force-tlsv12", srv_parse_force_tlsv12, 0, 0 }, /* force TLSv12 */
4582 { "no-sslv3", srv_parse_no_sslv3, 0, 0 }, /* disable SSLv3 */
4583 { "no-tlsv10", srv_parse_no_tlsv10, 0, 0 }, /* disable TLSv10 */
4584 { "no-tlsv11", srv_parse_no_tlsv11, 0, 0 }, /* disable TLSv11 */
4585 { "no-tlsv12", srv_parse_no_tlsv12, 0, 0 }, /* disable TLSv12 */
Emeric Brunf9c5c472012-10-11 15:28:34 +02004586 { "no-tls-tickets", srv_parse_no_tls_tickets, 0, 0 }, /* disable session resumption tickets */
David Safb76832014-05-08 23:42:08 -04004587 { "send-proxy-v2-ssl", srv_parse_send_proxy_ssl, 0, 0 }, /* send PROXY protocol header v2 with SSL info */
4588 { "send-proxy-v2-ssl-cn", srv_parse_send_proxy_cn, 0, 0 }, /* send PROXY protocol header v2 with CN */
Emeric Brunecc91fe2012-10-11 15:05:10 +02004589 { "ssl", srv_parse_ssl, 0, 0 }, /* enable SSL processing */
Emeric Brunef42d922012-10-11 16:11:36 +02004590 { "verify", srv_parse_verify, 1, 0 }, /* set SSL verify method */
Evan Broderbe554312013-06-27 00:05:25 -07004591 { "verifyhost", srv_parse_verifyhost, 1, 0 }, /* require that SSL cert verifies for hostname */
Willy Tarreau92faadf2012-10-10 23:04:25 +02004592 { NULL, NULL, 0, 0 },
4593}};
4594
Emeric Brun42a3e202014-10-30 15:56:50 +01004595static struct cfg_kw_list cfg_kws = {ILH, {
4596 { CFG_GLOBAL, "ssl-default-bind-options", ssl_parse_default_bind_options },
4597 { CFG_GLOBAL, "ssl-default-server-options", ssl_parse_default_server_options },
4598 { 0, NULL, NULL },
4599}};
4600
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02004601/* transport-layer operations for SSL sockets */
4602struct xprt_ops ssl_sock = {
Emeric Brun46591952012-05-18 15:47:34 +02004603 .snd_buf = ssl_sock_from_buf,
4604 .rcv_buf = ssl_sock_to_buf,
4605 .rcv_pipe = NULL,
4606 .snd_pipe = NULL,
4607 .shutr = NULL,
4608 .shutw = ssl_sock_shutw,
4609 .close = ssl_sock_close,
4610 .init = ssl_sock_init,
4611};
4612
4613__attribute__((constructor))
Willy Tarreau92faadf2012-10-10 23:04:25 +02004614static void __ssl_sock_init(void)
4615{
Emeric Brun46591952012-05-18 15:47:34 +02004616 STACK_OF(SSL_COMP)* cm;
4617
Willy Tarreau610f04b2014-02-13 11:36:41 +01004618#ifdef LISTEN_DEFAULT_CIPHERS
4619 global.listen_default_ciphers = LISTEN_DEFAULT_CIPHERS;
4620#endif
4621#ifdef CONNECT_DEFAULT_CIPHERS
4622 global.connect_default_ciphers = CONNECT_DEFAULT_CIPHERS;
4623#endif
4624 if (global.listen_default_ciphers)
4625 global.listen_default_ciphers = strdup(global.listen_default_ciphers);
4626 if (global.connect_default_ciphers)
4627 global.connect_default_ciphers = strdup(global.connect_default_ciphers);
Emeric Brun42a3e202014-10-30 15:56:50 +01004628 global.listen_default_ssloptions = BC_SSL_O_NONE;
4629 global.connect_default_ssloptions = SRV_SSL_O_NONE;
Willy Tarreau610f04b2014-02-13 11:36:41 +01004630
Emeric Brun46591952012-05-18 15:47:34 +02004631 SSL_library_init();
4632 cm = SSL_COMP_get_compression_methods();
4633 sk_SSL_COMP_zero(cm);
Willy Tarreau7875d092012-09-10 08:20:03 +02004634 sample_register_fetches(&sample_fetch_keywords);
4635 acl_register_keywords(&acl_kws);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02004636 bind_register_keywords(&bind_kws);
Willy Tarreau92faadf2012-10-10 23:04:25 +02004637 srv_register_keywords(&srv_kws);
Emeric Brun42a3e202014-10-30 15:56:50 +01004638 cfg_register_keywords(&cfg_kws);
Remi Gacogne5d769ca2015-05-28 16:23:00 +02004639
4640#ifndef OPENSSL_NO_DH
4641 ssl_dh_ptr_index = SSL_CTX_get_ex_new_index(0, NULL, NULL, NULL, NULL);
4642#endif
Emeric Brun46591952012-05-18 15:47:34 +02004643}
4644
Remi Gacogne269a02f2015-05-28 16:39:47 +02004645__attribute__((destructor))
4646static void __ssl_sock_deinit(void)
4647{
4648#ifndef OPENSSL_NO_DH
4649 if (local_dh_1024) {
4650 DH_free(local_dh_1024);
4651 local_dh_1024 = NULL;
4652 }
4653
4654 if (local_dh_2048) {
4655 DH_free(local_dh_2048);
4656 local_dh_2048 = NULL;
4657 }
4658
4659 if (local_dh_4096) {
4660 DH_free(local_dh_4096);
4661 local_dh_4096 = NULL;
4662 }
Remi Gacogne269a02f2015-05-28 16:39:47 +02004663#endif
4664
4665 ERR_remove_state(0);
4666 ERR_free_strings();
4667
4668 EVP_cleanup();
4669
4670#if OPENSSL_VERSION_NUMBER >= 0x00907000L
4671 CRYPTO_cleanup_all_ex_data();
4672#endif
4673}
4674
4675
Emeric Brun46591952012-05-18 15:47:34 +02004676/*
4677 * Local variables:
4678 * c-indent-level: 8
4679 * c-basic-offset: 8
4680 * End:
4681 */