blob: b7187fa826d56ccb3c71da34158e3c102cb1cd8c [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 Tarreau3fdb3662012-11-12 00:42:33 +01002241 if (objt_server(conn->target)->ssl_ctx.reused_sess)
2242 SSL_SESSION_free(objt_server(conn->target)->ssl_ctx.reused_sess);
Emeric Brun46591952012-05-18 15:47:34 +02002243
Willy Tarreau3fdb3662012-11-12 00:42:33 +01002244 objt_server(conn->target)->ssl_ctx.reused_sess = SSL_get1_session(conn->xprt_ctx);
Emeric Brun46591952012-05-18 15:47:34 +02002245 }
Willy Tarreau0c9c2722014-05-28 12:28:58 +02002246 else {
2247 update_freq_ctr(&global.ssl_fe_keys_per_sec, 1);
2248 if (global.ssl_fe_keys_per_sec.curr_ctr > global.ssl_fe_keys_max)
2249 global.ssl_fe_keys_max = global.ssl_fe_keys_per_sec.curr_ctr;
2250 }
Emeric Brun46591952012-05-18 15:47:34 +02002251 }
2252
2253 /* The connection is now established at both layers, it's time to leave */
2254 conn->flags &= ~(flag | CO_FL_WAIT_L4_CONN | CO_FL_WAIT_L6_CONN);
2255 return 1;
2256
2257 out_error:
Emeric Brun644cde02012-12-14 11:21:13 +01002258 /* Clear openssl global errors stack */
2259 ERR_clear_error();
2260
Emeric Brun9fa89732012-10-04 17:09:56 +02002261 /* free resumed session if exists */
Willy Tarreau3fdb3662012-11-12 00:42:33 +01002262 if (objt_server(conn->target) && objt_server(conn->target)->ssl_ctx.reused_sess) {
2263 SSL_SESSION_free(objt_server(conn->target)->ssl_ctx.reused_sess);
2264 objt_server(conn->target)->ssl_ctx.reused_sess = NULL;
Emeric Brun9fa89732012-10-04 17:09:56 +02002265 }
2266
Emeric Brun46591952012-05-18 15:47:34 +02002267 /* Fail on all other handshake errors */
2268 conn->flags |= CO_FL_ERROR;
Willy Tarreau20879a02012-12-03 16:32:10 +01002269 if (!conn->err_code)
2270 conn->err_code = CO_ER_SSL_HANDSHAKE;
Emeric Brun46591952012-05-18 15:47:34 +02002271 return 0;
2272}
2273
2274/* Receive up to <count> bytes from connection <conn>'s socket and store them
Willy Tarreauabf08d92014-01-14 11:31:27 +01002275 * into buffer <buf>. Only one call to recv() is performed, unless the
Emeric Brun46591952012-05-18 15:47:34 +02002276 * buffer wraps, in which case a second call may be performed. The connection's
2277 * flags are updated with whatever special event is detected (error, read0,
2278 * empty). The caller is responsible for taking care of those events and
2279 * avoiding the call if inappropriate. The function does not call the
2280 * connection's polling update function, so the caller is responsible for this.
2281 */
2282static int ssl_sock_to_buf(struct connection *conn, struct buffer *buf, int count)
2283{
2284 int ret, done = 0;
Willy Tarreauabf08d92014-01-14 11:31:27 +01002285 int try;
Emeric Brun46591952012-05-18 15:47:34 +02002286
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02002287 if (!conn->xprt_ctx)
Emeric Brun46591952012-05-18 15:47:34 +02002288 goto out_error;
2289
2290 if (conn->flags & CO_FL_HANDSHAKE)
2291 /* a handshake was requested */
2292 return 0;
2293
Willy Tarreauabf08d92014-01-14 11:31:27 +01002294 /* let's realign the buffer to optimize I/O */
2295 if (buffer_empty(buf))
Emeric Brun46591952012-05-18 15:47:34 +02002296 buf->p = buf->data;
Emeric Brun46591952012-05-18 15:47:34 +02002297
2298 /* read the largest possible block. For this, we perform only one call
2299 * to recv() unless the buffer wraps and we exactly fill the first hunk,
2300 * in which case we accept to do it once again. A new attempt is made on
2301 * EINTR too.
2302 */
Willy Tarreau00b0fb92014-01-17 11:09:40 +01002303 while (count > 0) {
Willy Tarreauabf08d92014-01-14 11:31:27 +01002304 /* first check if we have some room after p+i */
2305 try = buf->data + buf->size - (buf->p + buf->i);
2306 /* otherwise continue between data and p-o */
2307 if (try <= 0) {
2308 try = buf->p - (buf->data + buf->o);
2309 if (try <= 0)
2310 break;
2311 }
2312 if (try > count)
2313 try = count;
2314
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02002315 ret = SSL_read(conn->xprt_ctx, bi_end(buf), try);
Emeric Brune1f38db2012-09-03 20:36:47 +02002316 if (conn->flags & CO_FL_ERROR) {
2317 /* CO_FL_ERROR may be set by ssl_sock_infocbk */
Emeric Brun644cde02012-12-14 11:21:13 +01002318 goto out_error;
Emeric Brune1f38db2012-09-03 20:36:47 +02002319 }
Emeric Brun46591952012-05-18 15:47:34 +02002320 if (ret > 0) {
2321 buf->i += ret;
2322 done += ret;
2323 if (ret < try)
2324 break;
2325 count -= ret;
Emeric Brun46591952012-05-18 15:47:34 +02002326 }
2327 else if (ret == 0) {
Emeric Brun644cde02012-12-14 11:21:13 +01002328 ret = SSL_get_error(conn->xprt_ctx, ret);
2329 if (ret != SSL_ERROR_ZERO_RETURN) {
Emeric Brun1c646862012-12-14 12:33:41 +01002330 /* error on protocol or underlying transport */
2331 if ((ret != SSL_ERROR_SYSCALL)
2332 || (errno && (errno != EAGAIN)))
2333 conn->flags |= CO_FL_ERROR;
2334
Emeric Brun644cde02012-12-14 11:21:13 +01002335 /* Clear openssl global errors stack */
2336 ERR_clear_error();
2337 }
Emeric Brun46591952012-05-18 15:47:34 +02002338 goto read0;
2339 }
2340 else {
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02002341 ret = SSL_get_error(conn->xprt_ctx, ret);
Emeric Brun46591952012-05-18 15:47:34 +02002342 if (ret == SSL_ERROR_WANT_WRITE) {
Emeric Brun8af8dd12012-11-08 17:56:20 +01002343 /* handshake is running, and it needs to enable write */
Emeric Brun46591952012-05-18 15:47:34 +02002344 conn->flags |= CO_FL_SSL_WAIT_HS;
Emeric Brun8af8dd12012-11-08 17:56:20 +01002345 __conn_sock_want_send(conn);
Emeric Brun46591952012-05-18 15:47:34 +02002346 break;
2347 }
2348 else if (ret == SSL_ERROR_WANT_READ) {
Emeric Brun282a76a2012-11-08 18:02:56 +01002349 if (SSL_renegotiate_pending(conn->xprt_ctx)) {
2350 /* handshake is running, and it may need to re-enable read */
2351 conn->flags |= CO_FL_SSL_WAIT_HS;
2352 __conn_sock_want_recv(conn);
2353 break;
2354 }
Emeric Brun46591952012-05-18 15:47:34 +02002355 /* we need to poll for retry a read later */
Willy Tarreaue1f50c42014-01-22 20:02:06 +01002356 fd_cant_recv(conn->t.sock.fd);
Emeric Brun46591952012-05-18 15:47:34 +02002357 break;
2358 }
2359 /* otherwise it's a real error */
2360 goto out_error;
2361 }
2362 }
2363 return done;
2364
2365 read0:
2366 conn_sock_read0(conn);
2367 return done;
2368 out_error:
Emeric Brun644cde02012-12-14 11:21:13 +01002369 /* Clear openssl global errors stack */
2370 ERR_clear_error();
2371
Emeric Brun46591952012-05-18 15:47:34 +02002372 conn->flags |= CO_FL_ERROR;
2373 return done;
2374}
2375
2376
2377/* Send all pending bytes from buffer <buf> to connection <conn>'s socket.
Willy Tarreau1049b1f2014-02-02 01:51:17 +01002378 * <flags> may contain some CO_SFL_* flags to hint the system about other
2379 * pending data for example, but this flag is ignored at the moment.
Emeric Brun46591952012-05-18 15:47:34 +02002380 * Only one call to send() is performed, unless the buffer wraps, in which case
2381 * a second call may be performed. The connection's flags are updated with
2382 * whatever special event is detected (error, empty). The caller is responsible
2383 * for taking care of those events and avoiding the call if inappropriate. The
2384 * function does not call the connection's polling update function, so the caller
2385 * is responsible for this.
2386 */
2387static int ssl_sock_from_buf(struct connection *conn, struct buffer *buf, int flags)
2388{
2389 int ret, try, done;
2390
2391 done = 0;
2392
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02002393 if (!conn->xprt_ctx)
Emeric Brun46591952012-05-18 15:47:34 +02002394 goto out_error;
2395
2396 if (conn->flags & CO_FL_HANDSHAKE)
2397 /* a handshake was requested */
2398 return 0;
2399
2400 /* send the largest possible block. For this we perform only one call
2401 * to send() unless the buffer wraps and we exactly fill the first hunk,
2402 * in which case we accept to do it once again.
2403 */
2404 while (buf->o) {
Kevin Hestercad82342013-05-30 15:12:41 -07002405 try = bo_contig_data(buf);
Willy Tarreaubfd59462013-02-21 07:46:09 +01002406
Willy Tarreau7bed9452014-02-02 02:00:24 +01002407 if (!(flags & CO_SFL_STREAMER) &&
Willy Tarreau518cedd2014-02-17 15:43:01 +01002408 !(conn->xprt_st & SSL_SOCK_SEND_UNLIMITED) &&
2409 global.tune.ssl_max_record && try > global.tune.ssl_max_record) {
Willy Tarreaubfd59462013-02-21 07:46:09 +01002410 try = global.tune.ssl_max_record;
Willy Tarreau518cedd2014-02-17 15:43:01 +01002411 }
2412 else {
2413 /* we need to keep the information about the fact that
2414 * we're not limiting the upcoming send(), because if it
2415 * fails, we'll have to retry with at least as many data.
2416 */
2417 conn->xprt_st |= SSL_SOCK_SEND_UNLIMITED;
2418 }
Willy Tarreaubfd59462013-02-21 07:46:09 +01002419
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02002420 ret = SSL_write(conn->xprt_ctx, bo_ptr(buf), try);
Willy Tarreau518cedd2014-02-17 15:43:01 +01002421
Emeric Brune1f38db2012-09-03 20:36:47 +02002422 if (conn->flags & CO_FL_ERROR) {
2423 /* CO_FL_ERROR may be set by ssl_sock_infocbk */
Emeric Brun644cde02012-12-14 11:21:13 +01002424 goto out_error;
Emeric Brune1f38db2012-09-03 20:36:47 +02002425 }
Emeric Brun46591952012-05-18 15:47:34 +02002426 if (ret > 0) {
Willy Tarreau518cedd2014-02-17 15:43:01 +01002427 conn->xprt_st &= ~SSL_SOCK_SEND_UNLIMITED;
2428
Emeric Brun46591952012-05-18 15:47:34 +02002429 buf->o -= ret;
2430 done += ret;
2431
Willy Tarreau5fb38032012-12-16 19:39:09 +01002432 if (likely(buffer_empty(buf)))
Emeric Brun46591952012-05-18 15:47:34 +02002433 /* optimize data alignment in the buffer */
2434 buf->p = buf->data;
2435
2436 /* if the system buffer is full, don't insist */
2437 if (ret < try)
2438 break;
2439 }
2440 else {
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02002441 ret = SSL_get_error(conn->xprt_ctx, ret);
Emeric Brun46591952012-05-18 15:47:34 +02002442 if (ret == SSL_ERROR_WANT_WRITE) {
Emeric Brun282a76a2012-11-08 18:02:56 +01002443 if (SSL_renegotiate_pending(conn->xprt_ctx)) {
2444 /* handshake is running, and it may need to re-enable write */
2445 conn->flags |= CO_FL_SSL_WAIT_HS;
2446 __conn_sock_want_send(conn);
2447 break;
2448 }
Emeric Brun46591952012-05-18 15:47:34 +02002449 /* we need to poll to retry a write later */
Willy Tarreaue1f50c42014-01-22 20:02:06 +01002450 fd_cant_send(conn->t.sock.fd);
Emeric Brun46591952012-05-18 15:47:34 +02002451 break;
2452 }
2453 else if (ret == SSL_ERROR_WANT_READ) {
Emeric Brun8af8dd12012-11-08 17:56:20 +01002454 /* handshake is running, and it needs to enable read */
Emeric Brun46591952012-05-18 15:47:34 +02002455 conn->flags |= CO_FL_SSL_WAIT_HS;
Emeric Brun8af8dd12012-11-08 17:56:20 +01002456 __conn_sock_want_recv(conn);
Emeric Brun46591952012-05-18 15:47:34 +02002457 break;
2458 }
2459 goto out_error;
2460 }
2461 }
2462 return done;
2463
2464 out_error:
Emeric Brun644cde02012-12-14 11:21:13 +01002465 /* Clear openssl global errors stack */
2466 ERR_clear_error();
2467
Emeric Brun46591952012-05-18 15:47:34 +02002468 conn->flags |= CO_FL_ERROR;
2469 return done;
2470}
2471
Emeric Brun46591952012-05-18 15:47:34 +02002472static void ssl_sock_close(struct connection *conn) {
2473
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02002474 if (conn->xprt_ctx) {
2475 SSL_free(conn->xprt_ctx);
2476 conn->xprt_ctx = NULL;
Willy Tarreau403edff2012-09-06 11:58:37 +02002477 sslconns--;
Emeric Brun46591952012-05-18 15:47:34 +02002478 }
Emeric Brun46591952012-05-18 15:47:34 +02002479}
2480
2481/* This function tries to perform a clean shutdown on an SSL connection, and in
2482 * any case, flags the connection as reusable if no handshake was in progress.
2483 */
2484static void ssl_sock_shutw(struct connection *conn, int clean)
2485{
2486 if (conn->flags & CO_FL_HANDSHAKE)
2487 return;
2488 /* no handshake was in progress, try a clean ssl shutdown */
Emeric Brun644cde02012-12-14 11:21:13 +01002489 if (clean && (SSL_shutdown(conn->xprt_ctx) <= 0)) {
2490 /* Clear openssl global errors stack */
2491 ERR_clear_error();
2492 }
Emeric Brun46591952012-05-18 15:47:34 +02002493
2494 /* force flag on ssl to keep session in cache regardless shutdown result */
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02002495 SSL_set_shutdown(conn->xprt_ctx, SSL_SENT_SHUTDOWN);
Emeric Brun46591952012-05-18 15:47:34 +02002496}
2497
Willy Tarreauffc3fcd2012-10-12 20:17:54 +02002498/* used for logging, may be changed for a sample fetch later */
2499const char *ssl_sock_get_cipher_name(struct connection *conn)
2500{
2501 if (!conn->xprt && !conn->xprt_ctx)
2502 return NULL;
2503 return SSL_get_cipher_name(conn->xprt_ctx);
2504}
2505
2506/* used for logging, may be changed for a sample fetch later */
2507const char *ssl_sock_get_proto_version(struct connection *conn)
2508{
2509 if (!conn->xprt && !conn->xprt_ctx)
2510 return NULL;
2511 return SSL_get_version(conn->xprt_ctx);
2512}
2513
Willy Tarreau8d598402012-10-22 17:58:39 +02002514/* Extract a serial from a cert, and copy it to a chunk.
2515 * Returns 1 if serial is found and copied, 0 if no serial found and
2516 * -1 if output is not large enough.
2517 */
2518static int
2519ssl_sock_get_serial(X509 *crt, struct chunk *out)
2520{
2521 ASN1_INTEGER *serial;
2522
2523 serial = X509_get_serialNumber(crt);
2524 if (!serial)
2525 return 0;
2526
2527 if (out->size < serial->length)
2528 return -1;
2529
2530 memcpy(out->str, serial->data, serial->length);
2531 out->len = serial->length;
2532 return 1;
2533}
2534
Emeric Brunb3cc4252014-10-29 19:03:26 +01002535/* Extract a cert to der, and copy it to a chunk.
2536 * Returns 1 if cert is found and copied, 0 on der convertion failure and
2537 * -1 if output is not large enough.
2538 */
2539static int
2540ssl_sock_crt2der(X509 *crt, struct chunk *out)
2541{
2542 int len;
2543 unsigned char *p = (unsigned char *)out->str;;
2544
2545 len =i2d_X509(crt, NULL);
2546 if (len <= 0)
2547 return 1;
2548
2549 if (out->size < len)
2550 return -1;
2551
2552 i2d_X509(crt,&p);
2553 out->len = len;
2554 return 1;
2555}
2556
Emeric Brunce5ad802012-10-22 14:11:22 +02002557
2558/* Copy Date in ASN1_UTCTIME format in struct chunk out.
2559 * Returns 1 if serial is found and copied, 0 if no valid time found
2560 * and -1 if output is not large enough.
2561 */
2562static int
2563ssl_sock_get_time(ASN1_TIME *tm, struct chunk *out)
2564{
2565 if (tm->type == V_ASN1_GENERALIZEDTIME) {
2566 ASN1_GENERALIZEDTIME *gentm = (ASN1_GENERALIZEDTIME *)tm;
2567
2568 if (gentm->length < 12)
2569 return 0;
2570 if (gentm->data[0] != 0x32 || gentm->data[1] != 0x30)
2571 return 0;
2572 if (out->size < gentm->length-2)
2573 return -1;
2574
2575 memcpy(out->str, gentm->data+2, gentm->length-2);
2576 out->len = gentm->length-2;
2577 return 1;
2578 }
2579 else if (tm->type == V_ASN1_UTCTIME) {
2580 ASN1_UTCTIME *utctm = (ASN1_UTCTIME *)tm;
2581
2582 if (utctm->length < 10)
2583 return 0;
2584 if (utctm->data[0] >= 0x35)
2585 return 0;
2586 if (out->size < utctm->length)
2587 return -1;
2588
2589 memcpy(out->str, utctm->data, utctm->length);
2590 out->len = utctm->length;
2591 return 1;
2592 }
2593
2594 return 0;
2595}
2596
Emeric Brun87855892012-10-17 17:39:35 +02002597/* Extract an entry from a X509_NAME and copy its value to an output chunk.
2598 * Returns 1 if entry found, 0 if entry not found, or -1 if output not large enough.
2599 */
2600static int
2601ssl_sock_get_dn_entry(X509_NAME *a, const struct chunk *entry, int pos, struct chunk *out)
2602{
2603 X509_NAME_ENTRY *ne;
2604 int i, j, n;
2605 int cur = 0;
2606 const char *s;
2607 char tmp[128];
2608
2609 out->len = 0;
2610 for (i = 0; i < sk_X509_NAME_ENTRY_num(a->entries); i++) {
2611 if (pos < 0)
2612 j = (sk_X509_NAME_ENTRY_num(a->entries)-1) - i;
2613 else
2614 j = i;
2615
2616 ne = sk_X509_NAME_ENTRY_value(a->entries, j);
2617 n = OBJ_obj2nid(ne->object);
2618 if ((n == NID_undef) || ((s = OBJ_nid2sn(n)) == NULL)) {
2619 i2t_ASN1_OBJECT(tmp, sizeof(tmp), ne->object);
2620 s = tmp;
2621 }
2622
2623 if (chunk_strcasecmp(entry, s) != 0)
2624 continue;
2625
2626 if (pos < 0)
2627 cur--;
2628 else
2629 cur++;
2630
2631 if (cur != pos)
2632 continue;
2633
2634 if (ne->value->length > out->size)
2635 return -1;
2636
2637 memcpy(out->str, ne->value->data, ne->value->length);
2638 out->len = ne->value->length;
2639 return 1;
2640 }
2641
2642 return 0;
2643
2644}
2645
2646/* Extract and format full DN from a X509_NAME and copy result into a chunk
2647 * Returns 1 if dn entries exits, 0 if no dn entry found or -1 if output is not large enough.
2648 */
2649static int
2650ssl_sock_get_dn_oneline(X509_NAME *a, struct chunk *out)
2651{
2652 X509_NAME_ENTRY *ne;
2653 int i, n, ln;
2654 int l = 0;
2655 const char *s;
2656 char *p;
2657 char tmp[128];
2658
2659 out->len = 0;
2660 p = out->str;
2661 for (i = 0; i < sk_X509_NAME_ENTRY_num(a->entries); i++) {
2662 ne = sk_X509_NAME_ENTRY_value(a->entries, i);
2663 n = OBJ_obj2nid(ne->object);
2664 if ((n == NID_undef) || ((s = OBJ_nid2sn(n)) == NULL)) {
2665 i2t_ASN1_OBJECT(tmp, sizeof(tmp), ne->object);
2666 s = tmp;
2667 }
2668 ln = strlen(s);
2669
2670 l += 1 + ln + 1 + ne->value->length;
2671 if (l > out->size)
2672 return -1;
2673 out->len = l;
2674
2675 *(p++)='/';
2676 memcpy(p, s, ln);
2677 p += ln;
2678 *(p++)='=';
2679 memcpy(p, ne->value->data, ne->value->length);
2680 p += ne->value->length;
2681 }
2682
2683 if (!out->len)
2684 return 0;
2685
2686 return 1;
2687}
2688
David Safb76832014-05-08 23:42:08 -04002689char *ssl_sock_get_version(struct connection *conn)
2690{
2691 if (!ssl_sock_is_ssl(conn))
2692 return NULL;
2693
2694 return (char *)SSL_get_version(conn->xprt_ctx);
2695}
2696
Emeric Brun49100982014-06-24 18:26:41 +02002697/* Extract peer certificate's common name into the chunk dest
2698 * Returns
2699 * the len of the extracted common name
2700 * or 0 if no CN found in DN
2701 * or -1 on error case (i.e. no peer certificate)
2702 */
2703int ssl_sock_get_remote_common_name(struct connection *conn, struct chunk *dest)
David Safb76832014-05-08 23:42:08 -04002704{
2705 X509 *crt = NULL;
2706 X509_NAME *name;
David Safb76832014-05-08 23:42:08 -04002707 const char find_cn[] = "CN";
2708 const struct chunk find_cn_chunk = {
2709 .str = (char *)&find_cn,
2710 .len = sizeof(find_cn)-1
2711 };
Emeric Brun49100982014-06-24 18:26:41 +02002712 int result = -1;
David Safb76832014-05-08 23:42:08 -04002713
2714 if (!ssl_sock_is_ssl(conn))
Emeric Brun49100982014-06-24 18:26:41 +02002715 goto out;
David Safb76832014-05-08 23:42:08 -04002716
2717 /* SSL_get_peer_certificate, it increase X509 * ref count */
2718 crt = SSL_get_peer_certificate(conn->xprt_ctx);
2719 if (!crt)
2720 goto out;
2721
2722 name = X509_get_subject_name(crt);
2723 if (!name)
2724 goto out;
David Safb76832014-05-08 23:42:08 -04002725
Emeric Brun49100982014-06-24 18:26:41 +02002726 result = ssl_sock_get_dn_entry(name, &find_cn_chunk, 1, dest);
2727out:
David Safb76832014-05-08 23:42:08 -04002728 if (crt)
2729 X509_free(crt);
2730
2731 return result;
2732}
2733
Dave McCowand6ec6052014-07-30 10:39:13 -04002734/* returns 1 if client passed a certificate for this session, 0 if not */
2735int ssl_sock_get_cert_used_sess(struct connection *conn)
2736{
2737 X509 *crt = NULL;
2738
2739 if (!ssl_sock_is_ssl(conn))
2740 return 0;
2741
2742 /* SSL_get_peer_certificate, it increase X509 * ref count */
2743 crt = SSL_get_peer_certificate(conn->xprt_ctx);
2744 if (!crt)
2745 return 0;
2746
2747 X509_free(crt);
2748 return 1;
2749}
2750
2751/* returns 1 if client passed a certificate for this connection, 0 if not */
2752int ssl_sock_get_cert_used_conn(struct connection *conn)
David Safb76832014-05-08 23:42:08 -04002753{
2754 if (!ssl_sock_is_ssl(conn))
2755 return 0;
2756
2757 return SSL_SOCK_ST_FL_VERIFY_DONE & conn->xprt_st ? 1 : 0;
2758}
2759
2760/* returns result from SSL verify */
2761unsigned int ssl_sock_get_verify_result(struct connection *conn)
2762{
2763 if (!ssl_sock_is_ssl(conn))
2764 return (unsigned int)X509_V_ERR_APPLICATION_VERIFICATION;
2765
2766 return (unsigned int)SSL_get_verify_result(conn->xprt_ctx);
2767}
2768
Willy Tarreau7875d092012-09-10 08:20:03 +02002769/***** Below are some sample fetching functions for ACL/patterns *****/
2770
Emeric Brune64aef12012-09-21 13:15:06 +02002771/* boolean, returns true if client cert was present */
2772static int
Emeric Brun2525b6b2012-10-18 15:59:43 +02002773smp_fetch_ssl_fc_has_crt(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002774 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brune64aef12012-09-21 13:15:06 +02002775{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002776 struct connection *conn;
2777
2778 if (!l4)
2779 return 0;
2780
2781 conn = objt_conn(l4->si[0].end);
2782 if (!conn || conn->xprt != &ssl_sock)
Emeric Brune64aef12012-09-21 13:15:06 +02002783 return 0;
2784
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002785 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brune64aef12012-09-21 13:15:06 +02002786 smp->flags |= SMP_F_MAY_CHANGE;
2787 return 0;
2788 }
2789
2790 smp->flags = 0;
2791 smp->type = SMP_T_BOOL;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002792 smp->data.uint = SSL_SOCK_ST_FL_VERIFY_DONE & conn->xprt_st ? 1 : 0;
Emeric Brune64aef12012-09-21 13:15:06 +02002793
2794 return 1;
2795}
2796
Emeric Brunb3cc4252014-10-29 19:03:26 +01002797/* binary, returns a certificate in a binary chunk (der/raw).
2798 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
2799 * should be use.
2800 */
2801static int
2802smp_fetch_ssl_x_der(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
2803 const struct arg *args, struct sample *smp, const char *kw)
2804{
2805 int cert_peer = (kw[4] == 'c') ? 1 : 0;
2806 X509 *crt = NULL;
2807 int ret = 0;
2808 struct chunk *smp_trash;
2809 struct connection *conn;
2810
2811 if (!l4)
2812 return 0;
2813
2814 conn = objt_conn(l4->si[0].end);
2815 if (!conn || conn->xprt != &ssl_sock)
2816 return 0;
2817
2818 if (!(conn->flags & CO_FL_CONNECTED)) {
2819 smp->flags |= SMP_F_MAY_CHANGE;
2820 return 0;
2821 }
2822
2823 if (cert_peer)
2824 crt = SSL_get_peer_certificate(conn->xprt_ctx);
2825 else
2826 crt = SSL_get_certificate(conn->xprt_ctx);
2827
2828 if (!crt)
2829 goto out;
2830
2831 smp_trash = get_trash_chunk();
2832 if (ssl_sock_crt2der(crt, smp_trash) <= 0)
2833 goto out;
2834
2835 smp->data.str = *smp_trash;
2836 smp->type = SMP_T_BIN;
2837 ret = 1;
2838out:
2839 /* SSL_get_peer_certificate, it increase X509 * ref count */
2840 if (cert_peer && crt)
2841 X509_free(crt);
2842 return ret;
2843}
2844
Emeric Brunba841a12014-04-30 17:05:08 +02002845/* binary, returns serial of certificate in a binary chunk.
2846 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
2847 * should be use.
2848 */
Willy Tarreau8d598402012-10-22 17:58:39 +02002849static int
Emeric Brunba841a12014-04-30 17:05:08 +02002850smp_fetch_ssl_x_serial(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002851 const struct arg *args, struct sample *smp, const char *kw)
Willy Tarreau8d598402012-10-22 17:58:39 +02002852{
Emeric Brunba841a12014-04-30 17:05:08 +02002853 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Willy Tarreau8d598402012-10-22 17:58:39 +02002854 X509 *crt = NULL;
2855 int ret = 0;
2856 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002857 struct connection *conn;
2858
2859 if (!l4)
2860 return 0;
Willy Tarreau8d598402012-10-22 17:58:39 +02002861
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002862 conn = objt_conn(l4->si[0].end);
2863 if (!conn || conn->xprt != &ssl_sock)
Willy Tarreau8d598402012-10-22 17:58:39 +02002864 return 0;
2865
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002866 if (!(conn->flags & CO_FL_CONNECTED)) {
Willy Tarreau8d598402012-10-22 17:58:39 +02002867 smp->flags |= SMP_F_MAY_CHANGE;
2868 return 0;
2869 }
2870
Emeric Brunba841a12014-04-30 17:05:08 +02002871 if (cert_peer)
2872 crt = SSL_get_peer_certificate(conn->xprt_ctx);
2873 else
2874 crt = SSL_get_certificate(conn->xprt_ctx);
2875
Willy Tarreau8d598402012-10-22 17:58:39 +02002876 if (!crt)
2877 goto out;
2878
Willy Tarreau47ca5452012-12-23 20:22:19 +01002879 smp_trash = get_trash_chunk();
Willy Tarreau8d598402012-10-22 17:58:39 +02002880 if (ssl_sock_get_serial(crt, smp_trash) <= 0)
2881 goto out;
2882
2883 smp->data.str = *smp_trash;
2884 smp->type = SMP_T_BIN;
2885 ret = 1;
2886out:
Emeric Brunba841a12014-04-30 17:05:08 +02002887 /* SSL_get_peer_certificate, it increase X509 * ref count */
2888 if (cert_peer && crt)
Willy Tarreau8d598402012-10-22 17:58:39 +02002889 X509_free(crt);
2890 return ret;
2891}
Emeric Brune64aef12012-09-21 13:15:06 +02002892
Emeric Brunba841a12014-04-30 17:05:08 +02002893/* binary, returns the client certificate's SHA-1 fingerprint (SHA-1 hash of DER-encoded certificate) in a binary chunk.
2894 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
2895 * should be use.
2896 */
James Votha051b4a2013-05-14 20:37:59 +02002897static int
Emeric Brunba841a12014-04-30 17:05:08 +02002898smp_fetch_ssl_x_sha1(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002899 const struct arg *args, struct sample *smp, const char *kw)
James Votha051b4a2013-05-14 20:37:59 +02002900{
Emeric Brunba841a12014-04-30 17:05:08 +02002901 int cert_peer = (kw[4] == 'c') ? 1 : 0;
James Votha051b4a2013-05-14 20:37:59 +02002902 X509 *crt = NULL;
2903 const EVP_MD *digest;
2904 int ret = 0;
2905 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002906 struct connection *conn;
James Votha051b4a2013-05-14 20:37:59 +02002907
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002908 if (!l4)
James Votha051b4a2013-05-14 20:37:59 +02002909 return 0;
2910
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002911 conn = objt_conn(l4->si[0].end);
2912 if (!conn || conn->xprt != &ssl_sock)
2913 return 0;
2914
2915 if (!(conn->flags & CO_FL_CONNECTED)) {
James Votha051b4a2013-05-14 20:37:59 +02002916 smp->flags |= SMP_F_MAY_CHANGE;
2917 return 0;
2918 }
2919
Emeric Brunba841a12014-04-30 17:05:08 +02002920 if (cert_peer)
2921 crt = SSL_get_peer_certificate(conn->xprt_ctx);
2922 else
2923 crt = SSL_get_certificate(conn->xprt_ctx);
James Votha051b4a2013-05-14 20:37:59 +02002924 if (!crt)
2925 goto out;
2926
2927 smp_trash = get_trash_chunk();
2928 digest = EVP_sha1();
2929 X509_digest(crt, digest, (unsigned char *)smp_trash->str, (unsigned int *)&smp_trash->len);
2930
2931 smp->data.str = *smp_trash;
2932 smp->type = SMP_T_BIN;
2933 ret = 1;
2934out:
Emeric Brunba841a12014-04-30 17:05:08 +02002935 /* SSL_get_peer_certificate, it increase X509 * ref count */
2936 if (cert_peer && crt)
James Votha051b4a2013-05-14 20:37:59 +02002937 X509_free(crt);
2938 return ret;
2939}
2940
Emeric Brunba841a12014-04-30 17:05:08 +02002941/* string, returns certificate's notafter date in ASN1_UTCTIME format.
2942 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
2943 * should be use.
2944 */
Emeric Brunce5ad802012-10-22 14:11:22 +02002945static int
Emeric Brunba841a12014-04-30 17:05:08 +02002946smp_fetch_ssl_x_notafter(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002947 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brunce5ad802012-10-22 14:11:22 +02002948{
Emeric Brunba841a12014-04-30 17:05:08 +02002949 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brunce5ad802012-10-22 14:11:22 +02002950 X509 *crt = NULL;
2951 int ret = 0;
2952 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002953 struct connection *conn;
Emeric Brunce5ad802012-10-22 14:11:22 +02002954
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002955 if (!l4)
Emeric Brunce5ad802012-10-22 14:11:22 +02002956 return 0;
2957
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002958 conn = objt_conn(l4->si[0].end);
2959 if (!conn || conn->xprt != &ssl_sock)
2960 return 0;
2961
2962 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunce5ad802012-10-22 14:11:22 +02002963 smp->flags |= SMP_F_MAY_CHANGE;
2964 return 0;
2965 }
2966
Emeric Brunba841a12014-04-30 17:05:08 +02002967 if (cert_peer)
2968 crt = SSL_get_peer_certificate(conn->xprt_ctx);
2969 else
2970 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brunce5ad802012-10-22 14:11:22 +02002971 if (!crt)
2972 goto out;
2973
Willy Tarreau47ca5452012-12-23 20:22:19 +01002974 smp_trash = get_trash_chunk();
Emeric Brunce5ad802012-10-22 14:11:22 +02002975 if (ssl_sock_get_time(X509_get_notAfter(crt), smp_trash) <= 0)
2976 goto out;
2977
2978 smp->data.str = *smp_trash;
2979 smp->type = SMP_T_STR;
2980 ret = 1;
2981out:
Emeric Brunba841a12014-04-30 17:05:08 +02002982 /* SSL_get_peer_certificate, it increase X509 * ref count */
2983 if (cert_peer && crt)
Emeric Brunce5ad802012-10-22 14:11:22 +02002984 X509_free(crt);
2985 return ret;
2986}
2987
Emeric Brunba841a12014-04-30 17:05:08 +02002988/* string, returns a string of a formatted full dn \C=..\O=..\OU=.. \CN=.. of certificate's issuer
2989 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
2990 * should be use.
2991 */
Emeric Brun87855892012-10-17 17:39:35 +02002992static int
Emeric Brunba841a12014-04-30 17:05:08 +02002993smp_fetch_ssl_x_i_dn(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002994 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brun87855892012-10-17 17:39:35 +02002995{
Emeric Brunba841a12014-04-30 17:05:08 +02002996 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brun87855892012-10-17 17:39:35 +02002997 X509 *crt = NULL;
2998 X509_NAME *name;
2999 int ret = 0;
3000 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003001 struct connection *conn;
Emeric Brun87855892012-10-17 17:39:35 +02003002
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003003 if (!l4)
Emeric Brun87855892012-10-17 17:39:35 +02003004 return 0;
3005
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003006 conn = objt_conn(l4->si[0].end);
3007 if (!conn || conn->xprt != &ssl_sock)
3008 return 0;
3009
3010 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun87855892012-10-17 17:39:35 +02003011 smp->flags |= SMP_F_MAY_CHANGE;
3012 return 0;
3013 }
3014
Emeric Brunba841a12014-04-30 17:05:08 +02003015 if (cert_peer)
3016 crt = SSL_get_peer_certificate(conn->xprt_ctx);
3017 else
3018 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brun87855892012-10-17 17:39:35 +02003019 if (!crt)
3020 goto out;
3021
3022 name = X509_get_issuer_name(crt);
3023 if (!name)
3024 goto out;
3025
Willy Tarreau47ca5452012-12-23 20:22:19 +01003026 smp_trash = get_trash_chunk();
Emeric Brun87855892012-10-17 17:39:35 +02003027 if (args && args[0].type == ARGT_STR) {
3028 int pos = 1;
3029
3030 if (args[1].type == ARGT_SINT)
3031 pos = args[1].data.sint;
3032 else if (args[1].type == ARGT_UINT)
3033 pos =(int)args[1].data.uint;
3034
3035 if (ssl_sock_get_dn_entry(name, &args[0].data.str, pos, smp_trash) <= 0)
3036 goto out;
3037 }
3038 else if (ssl_sock_get_dn_oneline(name, smp_trash) <= 0)
3039 goto out;
3040
3041 smp->type = SMP_T_STR;
3042 smp->data.str = *smp_trash;
3043 ret = 1;
3044out:
Emeric Brunba841a12014-04-30 17:05:08 +02003045 /* SSL_get_peer_certificate, it increase X509 * ref count */
3046 if (cert_peer && crt)
Emeric Brun87855892012-10-17 17:39:35 +02003047 X509_free(crt);
3048 return ret;
3049}
3050
Emeric Brunba841a12014-04-30 17:05:08 +02003051/* string, returns notbefore date in ASN1_UTCTIME format.
3052 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
3053 * should be use.
3054 */
Emeric Brunce5ad802012-10-22 14:11:22 +02003055static int
Emeric Brunba841a12014-04-30 17:05:08 +02003056smp_fetch_ssl_x_notbefore(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003057 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brunce5ad802012-10-22 14:11:22 +02003058{
Emeric Brunba841a12014-04-30 17:05:08 +02003059 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brunce5ad802012-10-22 14:11:22 +02003060 X509 *crt = NULL;
3061 int ret = 0;
3062 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003063 struct connection *conn;
3064
3065 if (!l4)
3066 return 0;
Emeric Brunce5ad802012-10-22 14:11:22 +02003067
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003068 conn = objt_conn(l4->si[0].end);
3069 if (!conn || conn->xprt != &ssl_sock)
Emeric Brunce5ad802012-10-22 14:11:22 +02003070 return 0;
3071
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003072 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunce5ad802012-10-22 14:11:22 +02003073 smp->flags |= SMP_F_MAY_CHANGE;
3074 return 0;
3075 }
3076
Emeric Brunba841a12014-04-30 17:05:08 +02003077 if (cert_peer)
3078 crt = SSL_get_peer_certificate(conn->xprt_ctx);
3079 else
3080 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brunce5ad802012-10-22 14:11:22 +02003081 if (!crt)
3082 goto out;
3083
Willy Tarreau47ca5452012-12-23 20:22:19 +01003084 smp_trash = get_trash_chunk();
Emeric Brunce5ad802012-10-22 14:11:22 +02003085 if (ssl_sock_get_time(X509_get_notBefore(crt), smp_trash) <= 0)
3086 goto out;
3087
3088 smp->data.str = *smp_trash;
3089 smp->type = SMP_T_STR;
3090 ret = 1;
3091out:
Emeric Brunba841a12014-04-30 17:05:08 +02003092 /* SSL_get_peer_certificate, it increase X509 * ref count */
3093 if (cert_peer && crt)
Emeric Brunce5ad802012-10-22 14:11:22 +02003094 X509_free(crt);
3095 return ret;
3096}
3097
Emeric Brunba841a12014-04-30 17:05:08 +02003098/* string, returns a string of a formatted full dn \C=..\O=..\OU=.. \CN=.. of certificate's subject
3099 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
3100 * should be use.
3101 */
Emeric Brun87855892012-10-17 17:39:35 +02003102static int
Emeric Brunba841a12014-04-30 17:05:08 +02003103smp_fetch_ssl_x_s_dn(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003104 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brun87855892012-10-17 17:39:35 +02003105{
Emeric Brunba841a12014-04-30 17:05:08 +02003106 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brun87855892012-10-17 17:39:35 +02003107 X509 *crt = NULL;
3108 X509_NAME *name;
3109 int ret = 0;
3110 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003111 struct connection *conn;
Emeric Brun87855892012-10-17 17:39:35 +02003112
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003113 if (!l4)
Emeric Brun87855892012-10-17 17:39:35 +02003114 return 0;
3115
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003116 conn = objt_conn(l4->si[0].end);
3117 if (!conn || conn->xprt != &ssl_sock)
3118 return 0;
3119
3120 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun87855892012-10-17 17:39:35 +02003121 smp->flags |= SMP_F_MAY_CHANGE;
3122 return 0;
3123 }
3124
Emeric Brunba841a12014-04-30 17:05:08 +02003125 if (cert_peer)
3126 crt = SSL_get_peer_certificate(conn->xprt_ctx);
3127 else
3128 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brun87855892012-10-17 17:39:35 +02003129 if (!crt)
3130 goto out;
3131
3132 name = X509_get_subject_name(crt);
3133 if (!name)
3134 goto out;
3135
Willy Tarreau47ca5452012-12-23 20:22:19 +01003136 smp_trash = get_trash_chunk();
Emeric Brun87855892012-10-17 17:39:35 +02003137 if (args && args[0].type == ARGT_STR) {
3138 int pos = 1;
3139
3140 if (args[1].type == ARGT_SINT)
3141 pos = args[1].data.sint;
3142 else if (args[1].type == ARGT_UINT)
3143 pos =(int)args[1].data.uint;
3144
3145 if (ssl_sock_get_dn_entry(name, &args[0].data.str, pos, smp_trash) <= 0)
3146 goto out;
3147 }
3148 else if (ssl_sock_get_dn_oneline(name, smp_trash) <= 0)
3149 goto out;
3150
3151 smp->type = SMP_T_STR;
3152 smp->data.str = *smp_trash;
3153 ret = 1;
3154out:
Emeric Brunba841a12014-04-30 17:05:08 +02003155 /* SSL_get_peer_certificate, it increase X509 * ref count */
3156 if (cert_peer && crt)
Emeric Brun87855892012-10-17 17:39:35 +02003157 X509_free(crt);
3158 return ret;
3159}
Emeric Brun9143d372012-12-20 15:44:16 +01003160
3161/* integer, returns true if current session use a client certificate */
3162static int
3163smp_fetch_ssl_c_used(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003164 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brun9143d372012-12-20 15:44:16 +01003165{
3166 X509 *crt;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003167 struct connection *conn;
Emeric Brun9143d372012-12-20 15:44:16 +01003168
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003169 if (!l4)
Emeric Brun9143d372012-12-20 15:44:16 +01003170 return 0;
3171
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003172 conn = objt_conn(l4->si[0].end);
3173 if (!conn || conn->xprt != &ssl_sock)
3174 return 0;
3175
3176 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun9143d372012-12-20 15:44:16 +01003177 smp->flags |= SMP_F_MAY_CHANGE;
3178 return 0;
3179 }
3180
3181 /* SSL_get_peer_certificate returns a ptr on allocated X509 struct */
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003182 crt = SSL_get_peer_certificate(conn->xprt_ctx);
Emeric Brun9143d372012-12-20 15:44:16 +01003183 if (crt) {
3184 X509_free(crt);
3185 }
3186
3187 smp->type = SMP_T_BOOL;
3188 smp->data.uint = (crt != NULL);
3189 return 1;
3190}
3191
Emeric Brunba841a12014-04-30 17:05:08 +02003192/* integer, returns the certificate version
3193 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
3194 * should be use.
3195 */
Emeric Bruna7359fd2012-10-17 15:03:11 +02003196static int
Emeric Brunba841a12014-04-30 17:05:08 +02003197smp_fetch_ssl_x_version(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003198 const struct arg *args, struct sample *smp, const char *kw)
Emeric Bruna7359fd2012-10-17 15:03:11 +02003199{
Emeric Brunba841a12014-04-30 17:05:08 +02003200 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Bruna7359fd2012-10-17 15:03:11 +02003201 X509 *crt;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003202 struct connection *conn;
3203
3204 if (!l4)
3205 return 0;
Emeric Bruna7359fd2012-10-17 15:03:11 +02003206
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003207 conn = objt_conn(l4->si[0].end);
3208 if (!conn || conn->xprt != &ssl_sock)
Emeric Bruna7359fd2012-10-17 15:03:11 +02003209 return 0;
3210
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003211 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Bruna7359fd2012-10-17 15:03:11 +02003212 smp->flags |= SMP_F_MAY_CHANGE;
3213 return 0;
3214 }
3215
Emeric Brunba841a12014-04-30 17:05:08 +02003216 if (cert_peer)
3217 crt = SSL_get_peer_certificate(conn->xprt_ctx);
3218 else
3219 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Bruna7359fd2012-10-17 15:03:11 +02003220 if (!crt)
3221 return 0;
3222
3223 smp->data.uint = (unsigned int)(1 + X509_get_version(crt));
Emeric Brunba841a12014-04-30 17:05:08 +02003224 /* SSL_get_peer_certificate increase X509 * ref count */
3225 if (cert_peer)
3226 X509_free(crt);
Emeric Bruna7359fd2012-10-17 15:03:11 +02003227 smp->type = SMP_T_UINT;
3228
3229 return 1;
3230}
3231
Emeric Brunba841a12014-04-30 17:05:08 +02003232/* string, returns the certificate's signature algorithm.
3233 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
3234 * should be use.
3235 */
Emeric Brun7f56e742012-10-19 18:15:40 +02003236static int
Emeric Brunba841a12014-04-30 17:05:08 +02003237smp_fetch_ssl_x_sig_alg(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003238 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brun7f56e742012-10-19 18:15:40 +02003239{
Emeric Brunba841a12014-04-30 17:05:08 +02003240 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brun7f56e742012-10-19 18:15:40 +02003241 X509 *crt;
3242 int nid;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003243 struct connection *conn;
Emeric Brun7f56e742012-10-19 18:15:40 +02003244
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003245 if (!l4)
Emeric Brun7f56e742012-10-19 18:15:40 +02003246 return 0;
3247
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003248 conn = objt_conn(l4->si[0].end);
3249 if (!conn || conn->xprt != &ssl_sock)
3250 return 0;
3251
3252 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun7f56e742012-10-19 18:15:40 +02003253 smp->flags |= SMP_F_MAY_CHANGE;
3254 return 0;
3255 }
3256
Emeric Brunba841a12014-04-30 17:05:08 +02003257 if (cert_peer)
3258 crt = SSL_get_peer_certificate(conn->xprt_ctx);
3259 else
3260 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brun7f56e742012-10-19 18:15:40 +02003261 if (!crt)
3262 return 0;
3263
3264 nid = OBJ_obj2nid((ASN1_OBJECT *)(crt->cert_info->signature->algorithm));
3265
3266 smp->data.str.str = (char *)OBJ_nid2sn(nid);
Emeric Brun9bf3ba22013-10-07 14:31:44 +02003267 if (!smp->data.str.str) {
Emeric Brunba841a12014-04-30 17:05:08 +02003268 /* SSL_get_peer_certificate increase X509 * ref count */
3269 if (cert_peer)
3270 X509_free(crt);
Emeric Brun7f56e742012-10-19 18:15:40 +02003271 return 0;
Emeric Brun9bf3ba22013-10-07 14:31:44 +02003272 }
Emeric Brun7f56e742012-10-19 18:15:40 +02003273
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01003274 smp->type = SMP_T_STR;
3275 smp->flags |= SMP_F_CONST;
Emeric Brun7f56e742012-10-19 18:15:40 +02003276 smp->data.str.len = strlen(smp->data.str.str);
Emeric Brunba841a12014-04-30 17:05:08 +02003277 /* SSL_get_peer_certificate increase X509 * ref count */
3278 if (cert_peer)
3279 X509_free(crt);
Emeric Brun7f56e742012-10-19 18:15:40 +02003280
3281 return 1;
3282}
3283
Emeric Brunba841a12014-04-30 17:05:08 +02003284/* string, returns the certificate's key algorithm.
3285 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
3286 * should be use.
3287 */
Emeric Brun521a0112012-10-22 12:22:55 +02003288static int
Emeric Brunba841a12014-04-30 17:05:08 +02003289smp_fetch_ssl_x_key_alg(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003290 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brun521a0112012-10-22 12:22:55 +02003291{
Emeric Brunba841a12014-04-30 17:05:08 +02003292 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brun521a0112012-10-22 12:22:55 +02003293 X509 *crt;
3294 int nid;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003295 struct connection *conn;
Emeric Brun521a0112012-10-22 12:22:55 +02003296
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003297 if (!l4)
Emeric Brun521a0112012-10-22 12:22:55 +02003298 return 0;
3299
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003300 conn = objt_conn(l4->si[0].end);
3301 if (!conn || conn->xprt != &ssl_sock)
3302 return 0;
3303
3304 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun521a0112012-10-22 12:22:55 +02003305 smp->flags |= SMP_F_MAY_CHANGE;
3306 return 0;
3307 }
3308
Emeric Brunba841a12014-04-30 17:05:08 +02003309 if (cert_peer)
3310 crt = SSL_get_peer_certificate(conn->xprt_ctx);
3311 else
3312 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brun521a0112012-10-22 12:22:55 +02003313 if (!crt)
3314 return 0;
3315
3316 nid = OBJ_obj2nid((ASN1_OBJECT *)(crt->cert_info->key->algor->algorithm));
3317
3318 smp->data.str.str = (char *)OBJ_nid2sn(nid);
Emeric Brun9bf3ba22013-10-07 14:31:44 +02003319 if (!smp->data.str.str) {
Emeric Brunba841a12014-04-30 17:05:08 +02003320 /* SSL_get_peer_certificate increase X509 * ref count */
3321 if (cert_peer)
3322 X509_free(crt);
Emeric Brun521a0112012-10-22 12:22:55 +02003323 return 0;
Emeric Brun9bf3ba22013-10-07 14:31:44 +02003324 }
Emeric Brun521a0112012-10-22 12:22:55 +02003325
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01003326 smp->type = SMP_T_STR;
3327 smp->flags |= SMP_F_CONST;
Emeric Brun521a0112012-10-22 12:22:55 +02003328 smp->data.str.len = strlen(smp->data.str.str);
Emeric Brunba841a12014-04-30 17:05:08 +02003329 if (cert_peer)
3330 X509_free(crt);
Emeric Brun521a0112012-10-22 12:22:55 +02003331
3332 return 1;
3333}
3334
Emeric Brun645ae792014-04-30 14:21:06 +02003335/* boolean, returns true if front conn. transport layer is SSL.
3336 * This function is also usable on backend conn if the fetch keyword 5th
3337 * char is 'b'.
3338 */
Willy Tarreau7875d092012-09-10 08:20:03 +02003339static int
Emeric Brun2525b6b2012-10-18 15:59:43 +02003340smp_fetch_ssl_fc(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003341 const struct arg *args, struct sample *smp, const char *kw)
Willy Tarreau7875d092012-09-10 08:20:03 +02003342{
Emeric Brun645ae792014-04-30 14:21:06 +02003343 int back_conn = (kw[4] == 'b') ? 1 : 0;
3344 struct connection *conn = objt_conn(l4->si[back_conn].end);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003345
Willy Tarreau7875d092012-09-10 08:20:03 +02003346 smp->type = SMP_T_BOOL;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003347 smp->data.uint = (conn && conn->xprt == &ssl_sock);
Willy Tarreau7875d092012-09-10 08:20:03 +02003348 return 1;
3349}
3350
Emeric Brun2525b6b2012-10-18 15:59:43 +02003351/* boolean, returns true if client present a SNI */
Willy Tarreau7875d092012-09-10 08:20:03 +02003352static int
Emeric Brun2525b6b2012-10-18 15:59:43 +02003353smp_fetch_ssl_fc_has_sni(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003354 const struct arg *args, struct sample *smp, const char *kw)
Willy Tarreau7875d092012-09-10 08:20:03 +02003355{
3356#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003357 struct connection *conn = objt_conn(l4->si[0].end);
3358
Willy Tarreau7875d092012-09-10 08:20:03 +02003359 smp->type = SMP_T_BOOL;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003360 smp->data.uint = (conn && conn->xprt == &ssl_sock) &&
3361 conn->xprt_ctx &&
3362 SSL_get_servername(conn->xprt_ctx, TLSEXT_NAMETYPE_host_name) != NULL;
Willy Tarreau7875d092012-09-10 08:20:03 +02003363 return 1;
3364#else
3365 return 0;
3366#endif
3367}
3368
Emeric Brun645ae792014-04-30 14:21:06 +02003369/* string, returns the used cipher if front conn. transport layer is SSL.
3370 * This function is also usable on backend conn if the fetch keyword 5th
3371 * char is 'b'.
3372 */
Emeric Brun589fcad2012-10-16 14:13:26 +02003373static int
3374smp_fetch_ssl_fc_cipher(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003375 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brun589fcad2012-10-16 14:13:26 +02003376{
Emeric Brun645ae792014-04-30 14:21:06 +02003377 int back_conn = (kw[4] == 'b') ? 1 : 0;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003378 struct connection *conn;
3379
Emeric Brun589fcad2012-10-16 14:13:26 +02003380 smp->flags = 0;
3381
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003382 if (!l4)
3383 return 0;
3384
Emeric Brun645ae792014-04-30 14:21:06 +02003385 conn = objt_conn(l4->si[back_conn].end);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003386 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
Emeric Brun589fcad2012-10-16 14:13:26 +02003387 return 0;
3388
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003389 smp->data.str.str = (char *)SSL_get_cipher_name(conn->xprt_ctx);
Emeric Brun589fcad2012-10-16 14:13:26 +02003390 if (!smp->data.str.str)
3391 return 0;
3392
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01003393 smp->type = SMP_T_STR;
3394 smp->flags |= SMP_F_CONST;
Emeric Brun589fcad2012-10-16 14:13:26 +02003395 smp->data.str.len = strlen(smp->data.str.str);
3396
3397 return 1;
3398}
3399
Emeric Brun645ae792014-04-30 14:21:06 +02003400/* integer, returns the algoritm's keysize if front conn. transport layer
3401 * is SSL.
3402 * This function is also usable on backend conn if the fetch keyword 5th
3403 * char is 'b'.
3404 */
Emeric Brun589fcad2012-10-16 14:13:26 +02003405static int
3406smp_fetch_ssl_fc_alg_keysize(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003407 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brun589fcad2012-10-16 14:13:26 +02003408{
Emeric Brun645ae792014-04-30 14:21:06 +02003409 int back_conn = (kw[4] == 'b') ? 1 : 0;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003410 struct connection *conn;
3411
Emeric Brun589fcad2012-10-16 14:13:26 +02003412 smp->flags = 0;
3413
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003414 if (!l4)
Emeric Brun589fcad2012-10-16 14:13:26 +02003415 return 0;
3416
Emeric Brun645ae792014-04-30 14:21:06 +02003417 conn = objt_conn(l4->si[back_conn].end);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003418 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
Emeric Brun589fcad2012-10-16 14:13:26 +02003419 return 0;
3420
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003421 if (!SSL_get_cipher_bits(conn->xprt_ctx, (int *)&smp->data.uint))
3422 return 0;
3423
Emeric Brun589fcad2012-10-16 14:13:26 +02003424 smp->type = SMP_T_UINT;
3425
3426 return 1;
3427}
3428
Emeric Brun645ae792014-04-30 14:21:06 +02003429/* integer, returns the used keysize if front conn. transport layer is SSL.
3430 * This function is also usable on backend conn if the fetch keyword 5th
3431 * char is 'b'.
3432 */
Emeric Brun589fcad2012-10-16 14:13:26 +02003433static int
3434smp_fetch_ssl_fc_use_keysize(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003435 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brun589fcad2012-10-16 14:13:26 +02003436{
Emeric Brun645ae792014-04-30 14:21:06 +02003437 int back_conn = (kw[4] == 'b') ? 1 : 0;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003438 struct connection *conn;
3439
Emeric Brun589fcad2012-10-16 14:13:26 +02003440 smp->flags = 0;
3441
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003442 if (!l4)
Emeric Brun589fcad2012-10-16 14:13:26 +02003443 return 0;
3444
Emeric Brun645ae792014-04-30 14:21:06 +02003445 conn = objt_conn(l4->si[back_conn].end);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003446 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
3447 return 0;
3448
3449 smp->data.uint = (unsigned int)SSL_get_cipher_bits(conn->xprt_ctx, NULL);
Emeric Brun589fcad2012-10-16 14:13:26 +02003450 if (!smp->data.uint)
3451 return 0;
3452
3453 smp->type = SMP_T_UINT;
3454
3455 return 1;
3456}
3457
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02003458#ifdef OPENSSL_NPN_NEGOTIATED
Willy Tarreau7875d092012-09-10 08:20:03 +02003459static int
Emeric Brun2525b6b2012-10-18 15:59:43 +02003460smp_fetch_ssl_fc_npn(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003461 const struct arg *args, struct sample *smp, const char *kw)
Willy Tarreaua33c6542012-10-15 13:19:06 +02003462{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003463 struct connection *conn;
3464
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01003465 smp->flags = SMP_F_CONST;
3466 smp->type = SMP_T_STR;
Willy Tarreaua33c6542012-10-15 13:19:06 +02003467
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003468 if (!l4)
Willy Tarreaua33c6542012-10-15 13:19:06 +02003469 return 0;
3470
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003471 conn = objt_conn(l4->si[0].end);
3472 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
3473 return 0;
3474
Willy Tarreaua33c6542012-10-15 13:19:06 +02003475 smp->data.str.str = NULL;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003476 SSL_get0_next_proto_negotiated(conn->xprt_ctx,
Willy Tarreaua33c6542012-10-15 13:19:06 +02003477 (const unsigned char **)&smp->data.str.str, (unsigned *)&smp->data.str.len);
3478
3479 if (!smp->data.str.str)
3480 return 0;
3481
3482 return 1;
Willy Tarreaua33c6542012-10-15 13:19:06 +02003483}
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02003484#endif
Willy Tarreaua33c6542012-10-15 13:19:06 +02003485
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01003486#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Willy Tarreauab861d32013-04-02 02:30:41 +02003487static int
3488smp_fetch_ssl_fc_alpn(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003489 const struct arg *args, struct sample *smp, const char *kw)
Willy Tarreauab861d32013-04-02 02:30:41 +02003490{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003491 struct connection *conn;
3492
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01003493 smp->flags = SMP_F_CONST;
3494 smp->type = SMP_T_STR;
Willy Tarreauab861d32013-04-02 02:30:41 +02003495
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003496 if (!l4)
3497 return 0;
3498
3499 conn = objt_conn(l4->si[0].end);
3500 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
Willy Tarreauab861d32013-04-02 02:30:41 +02003501 return 0;
3502
3503 smp->data.str.str = NULL;
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01003504 SSL_get0_alpn_selected(conn->xprt_ctx,
Willy Tarreauab861d32013-04-02 02:30:41 +02003505 (const unsigned char **)&smp->data.str.str, (unsigned *)&smp->data.str.len);
3506
3507 if (!smp->data.str.str)
3508 return 0;
3509
3510 return 1;
3511}
3512#endif
3513
Emeric Brun645ae792014-04-30 14:21:06 +02003514/* string, returns the used protocol if front conn. transport layer is SSL.
3515 * This function is also usable on backend conn if the fetch keyword 5th
3516 * char is 'b'.
3517 */
Willy Tarreaua33c6542012-10-15 13:19:06 +02003518static int
Emeric Brun589fcad2012-10-16 14:13:26 +02003519smp_fetch_ssl_fc_protocol(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003520 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brun589fcad2012-10-16 14:13:26 +02003521{
Emeric Brun645ae792014-04-30 14:21:06 +02003522 int back_conn = (kw[4] == 'b') ? 1 : 0;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003523 struct connection *conn;
3524
Emeric Brun589fcad2012-10-16 14:13:26 +02003525 smp->flags = 0;
3526
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003527 if (!l4)
Emeric Brun589fcad2012-10-16 14:13:26 +02003528 return 0;
3529
Emeric Brun645ae792014-04-30 14:21:06 +02003530 conn = objt_conn(l4->si[back_conn].end);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003531 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
3532 return 0;
3533
3534 smp->data.str.str = (char *)SSL_get_version(conn->xprt_ctx);
Emeric Brun589fcad2012-10-16 14:13:26 +02003535 if (!smp->data.str.str)
3536 return 0;
3537
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01003538 smp->type = SMP_T_STR;
3539 smp->flags = SMP_F_CONST;
Emeric Brun589fcad2012-10-16 14:13:26 +02003540 smp->data.str.len = strlen(smp->data.str.str);
3541
3542 return 1;
3543}
3544
Emeric Brun645ae792014-04-30 14:21:06 +02003545/* binary, returns the SSL session id if front conn. transport layer is SSL.
3546 * This function is also usable on backend conn if the fetch keyword 5th
3547 * char is 'b'.
3548 */
Emeric Brun589fcad2012-10-16 14:13:26 +02003549static int
Emeric Brunfe68f682012-10-16 14:59:28 +02003550smp_fetch_ssl_fc_session_id(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003551 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brunfe68f682012-10-16 14:59:28 +02003552{
3553#if OPENSSL_VERSION_NUMBER > 0x0090800fL
Emeric Brun645ae792014-04-30 14:21:06 +02003554 int back_conn = (kw[4] == 'b') ? 1 : 0;
Emeric Brunfe68f682012-10-16 14:59:28 +02003555 SSL_SESSION *sess;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003556 struct connection *conn;
Emeric Brunfe68f682012-10-16 14:59:28 +02003557
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01003558 smp->flags = SMP_F_CONST;
3559 smp->type = SMP_T_BIN;
Emeric Brunfe68f682012-10-16 14:59:28 +02003560
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003561 if (!l4)
Emeric Brunfe68f682012-10-16 14:59:28 +02003562 return 0;
3563
Emeric Brun645ae792014-04-30 14:21:06 +02003564 conn = objt_conn(l4->si[back_conn].end);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003565 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
3566 return 0;
3567
3568 sess = SSL_get_session(conn->xprt_ctx);
Emeric Brunfe68f682012-10-16 14:59:28 +02003569 if (!sess)
3570 return 0;
3571
3572 smp->data.str.str = (char *)SSL_SESSION_get_id(sess, (unsigned int *)&smp->data.str.len);
Willy Tarreau69760db2015-06-17 18:34:14 +02003573 if (!smp->data.str.str || !smp->data.str.len)
Emeric Brunfe68f682012-10-16 14:59:28 +02003574 return 0;
3575
3576 return 1;
3577#else
3578 return 0;
3579#endif
3580}
3581
3582static int
Emeric Brun2525b6b2012-10-18 15:59:43 +02003583smp_fetch_ssl_fc_sni(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003584 const struct arg *args, struct sample *smp, const char *kw)
Willy Tarreau7875d092012-09-10 08:20:03 +02003585{
3586#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003587 struct connection *conn;
3588
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01003589 smp->flags = SMP_F_CONST;
3590 smp->type = SMP_T_STR;
Willy Tarreau7875d092012-09-10 08:20:03 +02003591
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003592 if (!l4)
Willy Tarreau7875d092012-09-10 08:20:03 +02003593 return 0;
3594
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003595 conn = objt_conn(l4->si[0].end);
3596 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
3597 return 0;
3598
3599 smp->data.str.str = (char *)SSL_get_servername(conn->xprt_ctx, TLSEXT_NAMETYPE_host_name);
Willy Tarreau3e394c92012-09-14 23:56:58 +02003600 if (!smp->data.str.str)
3601 return 0;
3602
Willy Tarreau7875d092012-09-10 08:20:03 +02003603 smp->data.str.len = strlen(smp->data.str.str);
3604 return 1;
3605#else
3606 return 0;
3607#endif
3608}
3609
David Sc1ad52e2014-04-08 18:48:47 -04003610static int
3611smp_fetch_ssl_fc_unique_id(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
3612 const struct arg *args, struct sample *smp, const char *kw)
3613{
3614#if OPENSSL_VERSION_NUMBER > 0x0090800fL
Emeric Brun645ae792014-04-30 14:21:06 +02003615 int back_conn = (kw[4] == 'b') ? 1 : 0;
David Sc1ad52e2014-04-08 18:48:47 -04003616 struct connection *conn;
3617 int finished_len;
David Sc1ad52e2014-04-08 18:48:47 -04003618 struct chunk *finished_trash;
David Sc1ad52e2014-04-08 18:48:47 -04003619
3620 smp->flags = 0;
3621
3622 if (!l4)
3623 return 0;
3624
Emeric Brun645ae792014-04-30 14:21:06 +02003625 conn = objt_conn(l4->si[back_conn].end);
David Sc1ad52e2014-04-08 18:48:47 -04003626 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
3627 return 0;
3628
3629 if (!(conn->flags & CO_FL_CONNECTED)) {
3630 smp->flags |= SMP_F_MAY_CHANGE;
3631 return 0;
3632 }
3633
3634 finished_trash = get_trash_chunk();
3635 if (!SSL_session_reused(conn->xprt_ctx))
3636 finished_len = SSL_get_peer_finished(conn->xprt_ctx, finished_trash->str, finished_trash->size);
3637 else
3638 finished_len = SSL_get_finished(conn->xprt_ctx, finished_trash->str, finished_trash->size);
3639
3640 if (!finished_len)
3641 return 0;
3642
Emeric Brunb73a9b02014-04-30 18:49:19 +02003643 finished_trash->len = finished_len;
3644 smp->data.str = *finished_trash;
3645 smp->type = SMP_T_BIN;
David Sc1ad52e2014-04-08 18:48:47 -04003646
3647 return 1;
3648#else
3649 return 0;
3650#endif
3651}
3652
Emeric Brun2525b6b2012-10-18 15:59:43 +02003653/* integer, returns the first verify error in CA chain of client certificate chain. */
Emeric Brunf282a812012-09-21 15:27:54 +02003654static int
Emeric Brun2525b6b2012-10-18 15:59:43 +02003655smp_fetch_ssl_c_ca_err(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003656 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brunf282a812012-09-21 15:27:54 +02003657{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003658 struct connection *conn;
3659
3660 if (!l4)
Emeric Brunf282a812012-09-21 15:27:54 +02003661 return 0;
3662
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003663 conn = objt_conn(l4->si[0].end);
3664 if (!conn || conn->xprt != &ssl_sock)
3665 return 0;
3666
3667 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunf282a812012-09-21 15:27:54 +02003668 smp->flags = SMP_F_MAY_CHANGE;
3669 return 0;
3670 }
3671
3672 smp->type = SMP_T_UINT;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003673 smp->data.uint = (unsigned int)SSL_SOCK_ST_TO_CA_ERROR(conn->xprt_st);
Emeric Brunf282a812012-09-21 15:27:54 +02003674 smp->flags = 0;
3675
3676 return 1;
3677}
3678
Emeric Brun2525b6b2012-10-18 15:59:43 +02003679/* integer, returns the depth of the first verify error in CA chain of client certificate chain. */
Emeric Brunf282a812012-09-21 15:27:54 +02003680static int
Emeric Brun2525b6b2012-10-18 15:59:43 +02003681smp_fetch_ssl_c_ca_err_depth(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003682 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brunf282a812012-09-21 15:27:54 +02003683{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003684 struct connection *conn;
3685
3686 if (!l4)
3687 return 0;
3688
3689 conn = objt_conn(l4->si[0].end);
3690 if (!conn || conn->xprt != &ssl_sock)
Emeric Brunf282a812012-09-21 15:27:54 +02003691 return 0;
3692
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003693 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunf282a812012-09-21 15:27:54 +02003694 smp->flags = SMP_F_MAY_CHANGE;
3695 return 0;
3696 }
3697
3698 smp->type = SMP_T_UINT;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003699 smp->data.uint = (unsigned int)SSL_SOCK_ST_TO_CAEDEPTH(conn->xprt_st);
Emeric Brunf282a812012-09-21 15:27:54 +02003700 smp->flags = 0;
3701
3702 return 1;
3703}
3704
Emeric Brun2525b6b2012-10-18 15:59:43 +02003705/* integer, returns the first verify error on client certificate */
Emeric Brunf282a812012-09-21 15:27:54 +02003706static int
Emeric Brun2525b6b2012-10-18 15:59:43 +02003707smp_fetch_ssl_c_err(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003708 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brunf282a812012-09-21 15:27:54 +02003709{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003710 struct connection *conn;
3711
3712 if (!l4)
Emeric Brunf282a812012-09-21 15:27:54 +02003713 return 0;
3714
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003715 conn = objt_conn(l4->si[0].end);
3716 if (!conn || conn->xprt != &ssl_sock)
3717 return 0;
3718
3719 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunf282a812012-09-21 15:27:54 +02003720 smp->flags = SMP_F_MAY_CHANGE;
3721 return 0;
3722 }
3723
3724 smp->type = SMP_T_UINT;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003725 smp->data.uint = (unsigned int)SSL_SOCK_ST_TO_CRTERROR(conn->xprt_st);
Emeric Brunf282a812012-09-21 15:27:54 +02003726 smp->flags = 0;
3727
3728 return 1;
3729}
3730
Emeric Brun2525b6b2012-10-18 15:59:43 +02003731/* integer, returns the verify result on client cert */
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02003732static int
Emeric Brun2525b6b2012-10-18 15:59:43 +02003733smp_fetch_ssl_c_verify(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003734 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02003735{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003736 struct connection *conn;
3737
3738 if (!l4)
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02003739 return 0;
3740
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003741 conn = objt_conn(l4->si[0].end);
3742 if (!conn || conn->xprt != &ssl_sock)
3743 return 0;
3744
3745 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02003746 smp->flags = SMP_F_MAY_CHANGE;
3747 return 0;
3748 }
3749
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003750 if (!conn->xprt_ctx)
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02003751 return 0;
3752
3753 smp->type = SMP_T_UINT;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003754 smp->data.uint = (unsigned int)SSL_get_verify_result(conn->xprt_ctx);
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02003755 smp->flags = 0;
3756
3757 return 1;
3758}
3759
Emeric Brunfb510ea2012-10-05 12:00:26 +02003760/* parse the "ca-file" bind keyword */
3761static 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 +02003762{
3763 if (!*args[cur_arg + 1]) {
3764 if (err)
3765 memprintf(err, "'%s' : missing CAfile path", args[cur_arg]);
3766 return ERR_ALERT | ERR_FATAL;
3767 }
3768
Emeric Brunef42d922012-10-11 16:11:36 +02003769 if ((*args[cur_arg + 1] != '/') && global.ca_base)
3770 memprintf(&conf->ca_file, "%s/%s", global.ca_base, args[cur_arg + 1]);
3771 else
3772 memprintf(&conf->ca_file, "%s", args[cur_arg + 1]);
Emeric Brunc8e8d122012-10-02 18:42:10 +02003773
Emeric Brund94b3fe2012-09-20 18:23:56 +02003774 return 0;
3775}
3776
Willy Tarreau79eeafa2012-09-14 07:53:05 +02003777/* parse the "ciphers" bind keyword */
Willy Tarreau4348fad2012-09-20 16:48:07 +02003778static 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 +02003779{
3780 if (!*args[cur_arg + 1]) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02003781 memprintf(err, "'%s' : missing cipher suite", args[cur_arg]);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02003782 return ERR_ALERT | ERR_FATAL;
3783 }
3784
Emeric Brun76d88952012-10-05 15:47:31 +02003785 free(conf->ciphers);
Willy Tarreau4348fad2012-09-20 16:48:07 +02003786 conf->ciphers = strdup(args[cur_arg + 1]);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02003787 return 0;
3788}
3789
3790/* parse the "crt" bind keyword */
Willy Tarreau4348fad2012-09-20 16:48:07 +02003791static 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 +02003792{
Willy Tarreau38011032013-08-13 16:59:39 +02003793 char path[MAXPATHLEN];
Willy Tarreaub75d6922014-04-14 18:05:41 +02003794
Willy Tarreau79eeafa2012-09-14 07:53:05 +02003795 if (!*args[cur_arg + 1]) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02003796 memprintf(err, "'%s' : missing certificate location", args[cur_arg]);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02003797 return ERR_ALERT | ERR_FATAL;
3798 }
3799
Emeric Brunc8e8d122012-10-02 18:42:10 +02003800 if ((*args[cur_arg + 1] != '/' ) && global.crt_base) {
Willy Tarreau38011032013-08-13 16:59:39 +02003801 if ((strlen(global.crt_base) + 1 + strlen(args[cur_arg + 1]) + 1) > MAXPATHLEN) {
Emeric Brunc8e8d122012-10-02 18:42:10 +02003802 memprintf(err, "'%s' : path too long", args[cur_arg]);
3803 return ERR_ALERT | ERR_FATAL;
3804 }
Willy Tarreaub75d6922014-04-14 18:05:41 +02003805 snprintf(path, sizeof(path), "%s/%s", global.crt_base, args[cur_arg + 1]);
Emeric Brunc8e8d122012-10-02 18:42:10 +02003806 if (ssl_sock_load_cert(path, conf, px, err) > 0)
3807 return ERR_ALERT | ERR_FATAL;
3808
3809 return 0;
3810 }
3811
Willy Tarreau4348fad2012-09-20 16:48:07 +02003812 if (ssl_sock_load_cert(args[cur_arg + 1], conf, px, err) > 0)
Willy Tarreau79eeafa2012-09-14 07:53:05 +02003813 return ERR_ALERT | ERR_FATAL;
Emeric Brund94b3fe2012-09-20 18:23:56 +02003814
3815 return 0;
3816}
3817
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01003818/* parse the "crt-list" bind keyword */
3819static int bind_parse_crt_list(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
3820{
3821 if (!*args[cur_arg + 1]) {
3822 memprintf(err, "'%s' : missing certificate location", args[cur_arg]);
3823 return ERR_ALERT | ERR_FATAL;
3824 }
3825
Willy Tarreauad1731d2013-04-02 17:35:58 +02003826 if (ssl_sock_load_cert_list_file(args[cur_arg + 1], conf, px, err) > 0) {
3827 memprintf(err, "'%s' : %s", args[cur_arg], *err);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01003828 return ERR_ALERT | ERR_FATAL;
Willy Tarreauad1731d2013-04-02 17:35:58 +02003829 }
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01003830
3831 return 0;
3832}
3833
Emeric Brunfb510ea2012-10-05 12:00:26 +02003834/* parse the "crl-file" bind keyword */
3835static 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 +02003836{
Emeric Brun051cdab2012-10-02 19:25:50 +02003837#ifndef X509_V_FLAG_CRL_CHECK
3838 if (err)
3839 memprintf(err, "'%s' : library does not support CRL verify", args[cur_arg]);
3840 return ERR_ALERT | ERR_FATAL;
3841#else
Emeric Brund94b3fe2012-09-20 18:23:56 +02003842 if (!*args[cur_arg + 1]) {
3843 if (err)
3844 memprintf(err, "'%s' : missing CRLfile path", args[cur_arg]);
3845 return ERR_ALERT | ERR_FATAL;
3846 }
Emeric Brun2b58d042012-09-20 17:10:03 +02003847
Emeric Brunef42d922012-10-11 16:11:36 +02003848 if ((*args[cur_arg + 1] != '/') && global.ca_base)
3849 memprintf(&conf->crl_file, "%s/%s", global.ca_base, args[cur_arg + 1]);
3850 else
3851 memprintf(&conf->crl_file, "%s", args[cur_arg + 1]);
Emeric Brunc8e8d122012-10-02 18:42:10 +02003852
Emeric Brun2b58d042012-09-20 17:10:03 +02003853 return 0;
Emeric Brun051cdab2012-10-02 19:25:50 +02003854#endif
Emeric Brun2b58d042012-09-20 17:10:03 +02003855}
3856
3857/* parse the "ecdhe" bind keyword keywords */
3858static int bind_parse_ecdhe(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
3859{
3860#if OPENSSL_VERSION_NUMBER < 0x0090800fL
3861 if (err)
3862 memprintf(err, "'%s' : library does not support elliptic curve Diffie-Hellman (too old)", args[cur_arg]);
3863 return ERR_ALERT | ERR_FATAL;
3864#elif defined(OPENSSL_NO_ECDH)
3865 if (err)
3866 memprintf(err, "'%s' : library does not support elliptic curve Diffie-Hellman (disabled via OPENSSL_NO_ECDH)", args[cur_arg]);
3867 return ERR_ALERT | ERR_FATAL;
3868#else
3869 if (!*args[cur_arg + 1]) {
3870 if (err)
3871 memprintf(err, "'%s' : missing named curve", args[cur_arg]);
3872 return ERR_ALERT | ERR_FATAL;
3873 }
3874
3875 conf->ecdhe = strdup(args[cur_arg + 1]);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02003876
3877 return 0;
Emeric Brun2b58d042012-09-20 17:10:03 +02003878#endif
Willy Tarreau79eeafa2012-09-14 07:53:05 +02003879}
3880
Emeric Brun81c00f02012-09-21 14:31:21 +02003881/* parse the "crt_ignerr" and "ca_ignerr" bind keywords */
3882static int bind_parse_ignore_err(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
3883{
3884 int code;
3885 char *p = args[cur_arg + 1];
3886 unsigned long long *ignerr = &conf->crt_ignerr;
3887
3888 if (!*p) {
3889 if (err)
3890 memprintf(err, "'%s' : missing error IDs list", args[cur_arg]);
3891 return ERR_ALERT | ERR_FATAL;
3892 }
3893
3894 if (strcmp(args[cur_arg], "ca-ignore-err") == 0)
3895 ignerr = &conf->ca_ignerr;
3896
3897 if (strcmp(p, "all") == 0) {
3898 *ignerr = ~0ULL;
3899 return 0;
3900 }
3901
3902 while (p) {
3903 code = atoi(p);
3904 if ((code <= 0) || (code > 63)) {
3905 if (err)
3906 memprintf(err, "'%s' : ID '%d' out of range (1..63) in error IDs list '%s'",
3907 args[cur_arg], code, args[cur_arg + 1]);
3908 return ERR_ALERT | ERR_FATAL;
3909 }
3910 *ignerr |= 1ULL << code;
3911 p = strchr(p, ',');
3912 if (p)
3913 p++;
3914 }
3915
Emeric Brun2cb7ae52012-10-05 14:14:21 +02003916 return 0;
3917}
3918
3919/* parse the "force-sslv3" bind keyword */
3920static int bind_parse_force_sslv3(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
3921{
3922 conf->ssl_options |= BC_SSL_O_USE_SSLV3;
3923 return 0;
3924}
3925
3926/* parse the "force-tlsv10" bind keyword */
3927static int bind_parse_force_tlsv10(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
3928{
3929 conf->ssl_options |= BC_SSL_O_USE_TLSV10;
Emeric Brun2d0c4822012-10-02 13:45:20 +02003930 return 0;
3931}
3932
Emeric Brun2cb7ae52012-10-05 14:14:21 +02003933/* parse the "force-tlsv11" bind keyword */
3934static int bind_parse_force_tlsv11(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
3935{
3936#if SSL_OP_NO_TLSv1_1
3937 conf->ssl_options |= BC_SSL_O_USE_TLSV11;
3938 return 0;
3939#else
3940 if (err)
3941 memprintf(err, "'%s' : library does not support protocol TLSv1.1", args[cur_arg]);
3942 return ERR_ALERT | ERR_FATAL;
3943#endif
3944}
3945
3946/* parse the "force-tlsv12" bind keyword */
3947static int bind_parse_force_tlsv12(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
3948{
3949#if SSL_OP_NO_TLSv1_2
3950 conf->ssl_options |= BC_SSL_O_USE_TLSV12;
3951 return 0;
3952#else
3953 if (err)
3954 memprintf(err, "'%s' : library does not support protocol TLSv1.2", args[cur_arg]);
3955 return ERR_ALERT | ERR_FATAL;
3956#endif
3957}
3958
3959
Emeric Brun2d0c4822012-10-02 13:45:20 +02003960/* parse the "no-tls-tickets" bind keyword */
3961static int bind_parse_no_tls_tickets(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
3962{
Emeric Brun89675492012-10-05 13:48:26 +02003963 conf->ssl_options |= BC_SSL_O_NO_TLS_TICKETS;
Emeric Brun81c00f02012-09-21 14:31:21 +02003964 return 0;
3965}
3966
Emeric Brun2d0c4822012-10-02 13:45:20 +02003967
Emeric Brun9b3009b2012-10-05 11:55:06 +02003968/* parse the "no-sslv3" bind keyword */
3969static 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 +02003970{
Emeric Brun89675492012-10-05 13:48:26 +02003971 conf->ssl_options |= BC_SSL_O_NO_SSLV3;
Willy Tarreau79eeafa2012-09-14 07:53:05 +02003972 return 0;
3973}
3974
Emeric Brun9b3009b2012-10-05 11:55:06 +02003975/* parse the "no-tlsv10" bind keyword */
3976static 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 +02003977{
Emeric Brun89675492012-10-05 13:48:26 +02003978 conf->ssl_options |= BC_SSL_O_NO_TLSV10;
Emeric Brunc0ff4922012-09-28 19:37:02 +02003979 return 0;
3980}
3981
Emeric Brun9b3009b2012-10-05 11:55:06 +02003982/* parse the "no-tlsv11" bind keyword */
3983static 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 +02003984{
Emeric Brun89675492012-10-05 13:48:26 +02003985 conf->ssl_options |= BC_SSL_O_NO_TLSV11;
Emeric Brunc0ff4922012-09-28 19:37:02 +02003986 return 0;
3987}
3988
Emeric Brun9b3009b2012-10-05 11:55:06 +02003989/* parse the "no-tlsv12" bind keyword */
3990static 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 +02003991{
Emeric Brun89675492012-10-05 13:48:26 +02003992 conf->ssl_options |= BC_SSL_O_NO_TLSV12;
Willy Tarreau79eeafa2012-09-14 07:53:05 +02003993 return 0;
3994}
3995
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02003996/* parse the "npn" bind keyword */
3997static int bind_parse_npn(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
3998{
3999#ifdef OPENSSL_NPN_NEGOTIATED
4000 char *p1, *p2;
4001
4002 if (!*args[cur_arg + 1]) {
4003 memprintf(err, "'%s' : missing the comma-delimited NPN protocol suite", args[cur_arg]);
4004 return ERR_ALERT | ERR_FATAL;
4005 }
4006
4007 free(conf->npn_str);
4008
Willy Tarreau8760ef02016-02-12 17:11:12 +01004009 /* the NPN string is built as a suite of (<len> <name>)*,
4010 * so we reuse each comma to store the next <len> and need
4011 * one more for the end of the string.
4012 */
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02004013 conf->npn_len = strlen(args[cur_arg + 1]) + 1;
Willy Tarreau8760ef02016-02-12 17:11:12 +01004014 conf->npn_str = calloc(1, conf->npn_len + 1);
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02004015 memcpy(conf->npn_str + 1, args[cur_arg + 1], conf->npn_len);
4016
4017 /* replace commas with the name length */
4018 p1 = conf->npn_str;
4019 p2 = p1 + 1;
4020 while (1) {
4021 p2 = memchr(p1 + 1, ',', conf->npn_str + conf->npn_len - (p1 + 1));
4022 if (!p2)
4023 p2 = p1 + 1 + strlen(p1 + 1);
4024
4025 if (p2 - (p1 + 1) > 255) {
4026 *p2 = '\0';
4027 memprintf(err, "'%s' : NPN protocol name too long : '%s'", args[cur_arg], p1 + 1);
4028 return ERR_ALERT | ERR_FATAL;
4029 }
4030
4031 *p1 = p2 - (p1 + 1);
4032 p1 = p2;
4033
4034 if (!*p2)
4035 break;
4036
4037 *(p2++) = '\0';
4038 }
4039 return 0;
4040#else
4041 if (err)
4042 memprintf(err, "'%s' : library does not support TLS NPN extension", args[cur_arg]);
4043 return ERR_ALERT | ERR_FATAL;
4044#endif
4045}
4046
Willy Tarreauab861d32013-04-02 02:30:41 +02004047/* parse the "alpn" bind keyword */
4048static int bind_parse_alpn(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
4049{
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01004050#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Willy Tarreauab861d32013-04-02 02:30:41 +02004051 char *p1, *p2;
4052
4053 if (!*args[cur_arg + 1]) {
4054 memprintf(err, "'%s' : missing the comma-delimited ALPN protocol suite", args[cur_arg]);
4055 return ERR_ALERT | ERR_FATAL;
4056 }
4057
4058 free(conf->alpn_str);
4059
Marcoen Hirschberg9344dd02016-02-12 17:05:24 +01004060 /* the ALPN string is built as a suite of (<len> <name>)*,
4061 * so we reuse each comma to store the next <len> and need
4062 * one more for the end of the string.
4063 */
Willy Tarreauab861d32013-04-02 02:30:41 +02004064 conf->alpn_len = strlen(args[cur_arg + 1]) + 1;
Marcoen Hirschberg9344dd02016-02-12 17:05:24 +01004065 conf->alpn_str = calloc(1, conf->alpn_len + 1);
Willy Tarreauab861d32013-04-02 02:30:41 +02004066 memcpy(conf->alpn_str + 1, args[cur_arg + 1], conf->alpn_len);
4067
4068 /* replace commas with the name length */
4069 p1 = conf->alpn_str;
4070 p2 = p1 + 1;
4071 while (1) {
4072 p2 = memchr(p1 + 1, ',', conf->alpn_str + conf->alpn_len - (p1 + 1));
4073 if (!p2)
4074 p2 = p1 + 1 + strlen(p1 + 1);
4075
4076 if (p2 - (p1 + 1) > 255) {
4077 *p2 = '\0';
4078 memprintf(err, "'%s' : ALPN protocol name too long : '%s'", args[cur_arg], p1 + 1);
4079 return ERR_ALERT | ERR_FATAL;
4080 }
4081
4082 *p1 = p2 - (p1 + 1);
4083 p1 = p2;
4084
4085 if (!*p2)
4086 break;
4087
4088 *(p2++) = '\0';
4089 }
4090 return 0;
4091#else
4092 if (err)
4093 memprintf(err, "'%s' : library does not support TLS ALPN extension", args[cur_arg]);
4094 return ERR_ALERT | ERR_FATAL;
4095#endif
4096}
4097
Willy Tarreau79eeafa2012-09-14 07:53:05 +02004098/* parse the "ssl" bind keyword */
Willy Tarreau4348fad2012-09-20 16:48:07 +02004099static 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 +02004100{
Willy Tarreau81796be2012-09-22 19:11:47 +02004101 struct listener *l;
4102
Willy Tarreau4348fad2012-09-20 16:48:07 +02004103 conf->is_ssl = 1;
Emeric Brun76d88952012-10-05 15:47:31 +02004104
4105 if (global.listen_default_ciphers && !conf->ciphers)
4106 conf->ciphers = strdup(global.listen_default_ciphers);
Emeric Brun42a3e202014-10-30 15:56:50 +01004107 conf->ssl_options |= global.listen_default_ssloptions;
Emeric Brun76d88952012-10-05 15:47:31 +02004108
Willy Tarreau81796be2012-09-22 19:11:47 +02004109 list_for_each_entry(l, &conf->listeners, by_bind)
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02004110 l->xprt = &ssl_sock;
Willy Tarreau81796be2012-09-22 19:11:47 +02004111
Willy Tarreau79eeafa2012-09-14 07:53:05 +02004112 return 0;
4113}
4114
Emmanuel Hocdet65623372013-01-24 17:17:15 +01004115/* parse the "strict-sni" bind keyword */
4116static int bind_parse_strict_sni(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
4117{
4118 conf->strict_sni = 1;
4119 return 0;
4120}
4121
Emeric Brund94b3fe2012-09-20 18:23:56 +02004122/* parse the "verify" bind keyword */
4123static int bind_parse_verify(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
4124{
4125 if (!*args[cur_arg + 1]) {
4126 if (err)
4127 memprintf(err, "'%s' : missing verify method", args[cur_arg]);
4128 return ERR_ALERT | ERR_FATAL;
4129 }
4130
4131 if (strcmp(args[cur_arg + 1], "none") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01004132 conf->verify = SSL_SOCK_VERIFY_NONE;
Emeric Brund94b3fe2012-09-20 18:23:56 +02004133 else if (strcmp(args[cur_arg + 1], "optional") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01004134 conf->verify = SSL_SOCK_VERIFY_OPTIONAL;
Emeric Brund94b3fe2012-09-20 18:23:56 +02004135 else if (strcmp(args[cur_arg + 1], "required") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01004136 conf->verify = SSL_SOCK_VERIFY_REQUIRED;
Emeric Brund94b3fe2012-09-20 18:23:56 +02004137 else {
4138 if (err)
4139 memprintf(err, "'%s' : unknown verify method '%s', only 'none', 'optional', and 'required' are supported\n",
4140 args[cur_arg], args[cur_arg + 1]);
4141 return ERR_ALERT | ERR_FATAL;
4142 }
4143
4144 return 0;
4145}
4146
Willy Tarreau92faadf2012-10-10 23:04:25 +02004147/************** "server" keywords ****************/
4148
Emeric Brunef42d922012-10-11 16:11:36 +02004149/* parse the "ca-file" server keyword */
4150static int srv_parse_ca_file(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4151{
4152 if (!*args[*cur_arg + 1]) {
4153 if (err)
4154 memprintf(err, "'%s' : missing CAfile path", args[*cur_arg]);
4155 return ERR_ALERT | ERR_FATAL;
4156 }
4157
4158 if ((*args[*cur_arg + 1] != '/') && global.ca_base)
4159 memprintf(&newsrv->ssl_ctx.ca_file, "%s/%s", global.ca_base, args[*cur_arg + 1]);
4160 else
4161 memprintf(&newsrv->ssl_ctx.ca_file, "%s", args[*cur_arg + 1]);
4162
4163 return 0;
4164}
4165
Willy Tarreau92faadf2012-10-10 23:04:25 +02004166/* parse the "check-ssl" server keyword */
4167static int srv_parse_check_ssl(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4168{
4169 newsrv->check.use_ssl = 1;
4170 if (global.connect_default_ciphers && !newsrv->ssl_ctx.ciphers)
4171 newsrv->ssl_ctx.ciphers = strdup(global.connect_default_ciphers);
Emeric Brun42a3e202014-10-30 15:56:50 +01004172 newsrv->ssl_ctx.options |= global.connect_default_ssloptions;
Willy Tarreau92faadf2012-10-10 23:04:25 +02004173 return 0;
4174}
4175
4176/* parse the "ciphers" server keyword */
4177static int srv_parse_ciphers(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4178{
4179 if (!*args[*cur_arg + 1]) {
4180 memprintf(err, "'%s' : missing cipher suite", args[*cur_arg]);
4181 return ERR_ALERT | ERR_FATAL;
4182 }
4183
4184 free(newsrv->ssl_ctx.ciphers);
4185 newsrv->ssl_ctx.ciphers = strdup(args[*cur_arg + 1]);
4186 return 0;
4187}
4188
Emeric Brunef42d922012-10-11 16:11:36 +02004189/* parse the "crl-file" server keyword */
4190static int srv_parse_crl_file(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4191{
4192#ifndef X509_V_FLAG_CRL_CHECK
4193 if (err)
4194 memprintf(err, "'%s' : library does not support CRL verify", args[*cur_arg]);
4195 return ERR_ALERT | ERR_FATAL;
4196#else
4197 if (!*args[*cur_arg + 1]) {
4198 if (err)
4199 memprintf(err, "'%s' : missing CRLfile path", args[*cur_arg]);
4200 return ERR_ALERT | ERR_FATAL;
4201 }
4202
4203 if ((*args[*cur_arg + 1] != '/') && global.ca_base)
4204 memprintf(&newsrv->ssl_ctx.crl_file, "%s/%s", global.ca_base, args[*cur_arg + 1]);
4205 else
4206 memprintf(&newsrv->ssl_ctx.crl_file, "%s", args[*cur_arg + 1]);
4207
4208 return 0;
4209#endif
4210}
4211
Emeric Bruna7aa3092012-10-26 12:58:00 +02004212/* parse the "crt" server keyword */
4213static int srv_parse_crt(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4214{
4215 if (!*args[*cur_arg + 1]) {
4216 if (err)
4217 memprintf(err, "'%s' : missing certificate file path", args[*cur_arg]);
4218 return ERR_ALERT | ERR_FATAL;
4219 }
4220
4221 if ((*args[*cur_arg + 1] != '/') && global.crt_base)
4222 memprintf(&newsrv->ssl_ctx.client_crt, "%s/%s", global.ca_base, args[*cur_arg + 1]);
4223 else
4224 memprintf(&newsrv->ssl_ctx.client_crt, "%s", args[*cur_arg + 1]);
4225
4226 return 0;
4227}
Emeric Brunef42d922012-10-11 16:11:36 +02004228
Willy Tarreau92faadf2012-10-10 23:04:25 +02004229/* parse the "force-sslv3" server keyword */
4230static int srv_parse_force_sslv3(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4231{
4232 newsrv->ssl_ctx.options |= SRV_SSL_O_USE_SSLV3;
4233 return 0;
4234}
4235
4236/* parse the "force-tlsv10" server keyword */
4237static int srv_parse_force_tlsv10(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4238{
4239 newsrv->ssl_ctx.options |= SRV_SSL_O_USE_TLSV10;
4240 return 0;
4241}
4242
4243/* parse the "force-tlsv11" server keyword */
4244static int srv_parse_force_tlsv11(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4245{
4246#if SSL_OP_NO_TLSv1_1
4247 newsrv->ssl_ctx.options |= SRV_SSL_O_USE_TLSV11;
4248 return 0;
4249#else
4250 if (err)
4251 memprintf(err, "'%s' : library does not support protocol TLSv1.1", args[*cur_arg]);
4252 return ERR_ALERT | ERR_FATAL;
4253#endif
4254}
4255
4256/* parse the "force-tlsv12" server keyword */
4257static int srv_parse_force_tlsv12(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4258{
4259#if SSL_OP_NO_TLSv1_2
4260 newsrv->ssl_ctx.options |= SRV_SSL_O_USE_TLSV12;
4261 return 0;
4262#else
4263 if (err)
4264 memprintf(err, "'%s' : library does not support protocol TLSv1.2", args[*cur_arg]);
4265 return ERR_ALERT | ERR_FATAL;
4266#endif
4267}
4268
4269/* parse the "no-sslv3" server keyword */
4270static int srv_parse_no_sslv3(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4271{
4272 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_SSLV3;
4273 return 0;
4274}
4275
4276/* parse the "no-tlsv10" server keyword */
4277static int srv_parse_no_tlsv10(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4278{
4279 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_TLSV10;
4280 return 0;
4281}
4282
4283/* parse the "no-tlsv11" server keyword */
4284static int srv_parse_no_tlsv11(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4285{
4286 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_TLSV11;
4287 return 0;
4288}
4289
4290/* parse the "no-tlsv12" server keyword */
4291static int srv_parse_no_tlsv12(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4292{
4293 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_TLSV12;
4294 return 0;
4295}
4296
Emeric Brunf9c5c472012-10-11 15:28:34 +02004297/* parse the "no-tls-tickets" server keyword */
4298static int srv_parse_no_tls_tickets(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4299{
4300 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_TLS_TICKETS;
4301 return 0;
4302}
David Safb76832014-05-08 23:42:08 -04004303/* parse the "send-proxy-v2-ssl" server keyword */
4304static int srv_parse_send_proxy_ssl(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4305{
4306 newsrv->pp_opts |= SRV_PP_V2;
4307 newsrv->pp_opts |= SRV_PP_V2_SSL;
4308 return 0;
4309}
4310
4311/* parse the "send-proxy-v2-ssl-cn" server keyword */
4312static int srv_parse_send_proxy_cn(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4313{
4314 newsrv->pp_opts |= SRV_PP_V2;
4315 newsrv->pp_opts |= SRV_PP_V2_SSL;
4316 newsrv->pp_opts |= SRV_PP_V2_SSL_CN;
4317 return 0;
4318}
Emeric Brunf9c5c472012-10-11 15:28:34 +02004319
Willy Tarreau92faadf2012-10-10 23:04:25 +02004320/* parse the "ssl" server keyword */
4321static int srv_parse_ssl(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4322{
4323 newsrv->use_ssl = 1;
4324 if (global.connect_default_ciphers && !newsrv->ssl_ctx.ciphers)
4325 newsrv->ssl_ctx.ciphers = strdup(global.connect_default_ciphers);
4326 return 0;
4327}
4328
Emeric Brunef42d922012-10-11 16:11:36 +02004329/* parse the "verify" server keyword */
4330static int srv_parse_verify(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4331{
4332 if (!*args[*cur_arg + 1]) {
4333 if (err)
4334 memprintf(err, "'%s' : missing verify method", args[*cur_arg]);
4335 return ERR_ALERT | ERR_FATAL;
4336 }
4337
4338 if (strcmp(args[*cur_arg + 1], "none") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01004339 newsrv->ssl_ctx.verify = SSL_SOCK_VERIFY_NONE;
Emeric Brunef42d922012-10-11 16:11:36 +02004340 else if (strcmp(args[*cur_arg + 1], "required") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01004341 newsrv->ssl_ctx.verify = SSL_SOCK_VERIFY_REQUIRED;
Emeric Brunef42d922012-10-11 16:11:36 +02004342 else {
4343 if (err)
4344 memprintf(err, "'%s' : unknown verify method '%s', only 'none' and 'required' are supported\n",
4345 args[*cur_arg], args[*cur_arg + 1]);
4346 return ERR_ALERT | ERR_FATAL;
4347 }
4348
Evan Broderbe554312013-06-27 00:05:25 -07004349 return 0;
4350}
4351
4352/* parse the "verifyhost" server keyword */
4353static int srv_parse_verifyhost(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4354{
4355 if (!*args[*cur_arg + 1]) {
4356 if (err)
4357 memprintf(err, "'%s' : missing hostname to verify against", args[*cur_arg]);
4358 return ERR_ALERT | ERR_FATAL;
4359 }
4360
4361 newsrv->ssl_ctx.verify_host = strdup(args[*cur_arg + 1]);
4362
Emeric Brunef42d922012-10-11 16:11:36 +02004363 return 0;
4364}
4365
Emeric Brun42a3e202014-10-30 15:56:50 +01004366/* parse the "ssl-default-bind-options" keyword in global section */
4367static int ssl_parse_default_bind_options(char **args, int section_type, struct proxy *curpx,
4368 struct proxy *defpx, const char *file, int line,
4369 char **err) {
4370 int i = 1;
4371
4372 if (*(args[i]) == 0) {
4373 memprintf(err, "global statement '%s' expects an option as an argument.", args[0]);
4374 return -1;
4375 }
4376 while (*(args[i])) {
4377 if (!strcmp(args[i], "no-sslv3"))
4378 global.listen_default_ssloptions |= BC_SSL_O_NO_SSLV3;
4379 else if (!strcmp(args[i], "no-tlsv10"))
4380 global.listen_default_ssloptions |= BC_SSL_O_NO_TLSV10;
4381 else if (!strcmp(args[i], "no-tlsv11"))
4382 global.listen_default_ssloptions |= BC_SSL_O_NO_TLSV11;
4383 else if (!strcmp(args[i], "no-tlsv12"))
4384 global.listen_default_ssloptions |= BC_SSL_O_NO_TLSV12;
4385 else if (!strcmp(args[i], "force-sslv3"))
4386 global.listen_default_ssloptions |= BC_SSL_O_USE_SSLV3;
4387 else if (!strcmp(args[i], "force-tlsv10"))
4388 global.listen_default_ssloptions |= BC_SSL_O_USE_TLSV10;
4389 else if (!strcmp(args[i], "force-tlsv11")) {
4390#if SSL_OP_NO_TLSv1_1
4391 global.listen_default_ssloptions |= BC_SSL_O_USE_TLSV11;
4392#else
4393 memprintf(err, "'%s' '%s': library does not support protocol TLSv1.1", args[0], args[i]);
4394 return -1;
4395#endif
4396 }
4397 else if (!strcmp(args[i], "force-tlsv12")) {
4398#if SSL_OP_NO_TLSv1_2
4399 global.listen_default_ssloptions |= BC_SSL_O_USE_TLSV12;
4400#else
4401 memprintf(err, "'%s' '%s': library does not support protocol TLSv1.2", args[0], args[i]);
4402 return -1;
4403#endif
4404 }
4405 else if (!strcmp(args[i], "no-tls-tickets"))
4406 global.listen_default_ssloptions |= BC_SSL_O_NO_TLS_TICKETS;
4407 else {
4408 memprintf(err, "unknown option '%s' on global statement '%s'.", args[i], args[0]);
4409 return -1;
4410 }
4411 i++;
4412 }
4413 return 0;
4414}
4415
4416/* parse the "ssl-default-server-options" keyword in global section */
4417static int ssl_parse_default_server_options(char **args, int section_type, struct proxy *curpx,
4418 struct proxy *defpx, const char *file, int line,
4419 char **err) {
4420 int i = 1;
4421
4422 if (*(args[i]) == 0) {
4423 memprintf(err, "global statement '%s' expects an option as an argument.", args[0]);
4424 return -1;
4425 }
4426 while (*(args[i])) {
4427 if (!strcmp(args[i], "no-sslv3"))
4428 global.connect_default_ssloptions |= SRV_SSL_O_NO_SSLV3;
4429 else if (!strcmp(args[i], "no-tlsv10"))
4430 global.connect_default_ssloptions |= SRV_SSL_O_NO_TLSV10;
4431 else if (!strcmp(args[i], "no-tlsv11"))
4432 global.connect_default_ssloptions |= SRV_SSL_O_NO_TLSV11;
4433 else if (!strcmp(args[i], "no-tlsv12"))
4434 global.connect_default_ssloptions |= SRV_SSL_O_NO_TLSV12;
4435 else if (!strcmp(args[i], "force-sslv3"))
4436 global.connect_default_ssloptions |= SRV_SSL_O_USE_SSLV3;
4437 else if (!strcmp(args[i], "force-tlsv10"))
4438 global.connect_default_ssloptions |= SRV_SSL_O_USE_TLSV10;
4439 else if (!strcmp(args[i], "force-tlsv11")) {
4440#if SSL_OP_NO_TLSv1_1
4441 global.connect_default_ssloptions |= SRV_SSL_O_USE_TLSV11;
4442#else
4443 memprintf(err, "'%s' '%s': library does not support protocol TLSv1.1", args[0], args[i]);
4444 return -1;
4445#endif
4446 }
4447 else if (!strcmp(args[i], "force-tlsv12")) {
4448#if SSL_OP_NO_TLSv1_2
4449 global.connect_default_ssloptions |= SRV_SSL_O_USE_TLSV12;
4450#else
4451 memprintf(err, "'%s' '%s': library does not support protocol TLSv1.2", args[0], args[i]);
4452 return -1;
4453#endif
4454 }
4455 else if (!strcmp(args[i], "no-tls-tickets"))
4456 global.connect_default_ssloptions |= SRV_SSL_O_NO_TLS_TICKETS;
4457 else {
4458 memprintf(err, "unknown option '%s' on global statement '%s'.", args[i], args[0]);
4459 return -1;
4460 }
4461 i++;
4462 }
4463 return 0;
4464}
4465
Willy Tarreau7875d092012-09-10 08:20:03 +02004466/* Note: must not be declared <const> as its list will be overwritten.
4467 * Please take care of keeping this list alphabetically sorted.
4468 */
Willy Tarreaudc13c112013-06-21 23:16:39 +02004469static struct sample_fetch_kw_list sample_fetch_keywords = {ILH, {
Emeric Brun645ae792014-04-30 14:21:06 +02004470 { "ssl_bc", smp_fetch_ssl_fc, 0, NULL, SMP_T_BOOL, SMP_USE_L5SRV },
4471 { "ssl_bc_alg_keysize", smp_fetch_ssl_fc_alg_keysize, 0, NULL, SMP_T_UINT, SMP_USE_L5SRV },
4472 { "ssl_bc_cipher", smp_fetch_ssl_fc_cipher, 0, NULL, SMP_T_STR, SMP_USE_L5SRV },
4473 { "ssl_bc_protocol", smp_fetch_ssl_fc_protocol, 0, NULL, SMP_T_STR, SMP_USE_L5SRV },
Emeric Brunb73a9b02014-04-30 18:49:19 +02004474 { "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 +02004475 { "ssl_bc_use_keysize", smp_fetch_ssl_fc_use_keysize, 0, NULL, SMP_T_UINT, SMP_USE_L5SRV },
4476 { "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 +01004477 { "ssl_c_ca_err", smp_fetch_ssl_c_ca_err, 0, NULL, SMP_T_UINT, SMP_USE_L5CLI },
4478 { "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 +01004479 { "ssl_c_der", smp_fetch_ssl_x_der, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Willy Tarreau80aca902013-01-07 15:42:20 +01004480 { "ssl_c_err", smp_fetch_ssl_c_err, 0, NULL, SMP_T_UINT, SMP_USE_L5CLI },
Emeric Brunba841a12014-04-30 17:05:08 +02004481 { "ssl_c_i_dn", smp_fetch_ssl_x_i_dn, ARG2(0,STR,SINT), NULL, SMP_T_STR, SMP_USE_L5CLI },
4482 { "ssl_c_key_alg", smp_fetch_ssl_x_key_alg, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
4483 { "ssl_c_notafter", smp_fetch_ssl_x_notafter, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
4484 { "ssl_c_notbefore", smp_fetch_ssl_x_notbefore, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
4485 { "ssl_c_sig_alg", smp_fetch_ssl_x_sig_alg, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
4486 { "ssl_c_s_dn", smp_fetch_ssl_x_s_dn, ARG2(0,STR,SINT), NULL, SMP_T_STR, SMP_USE_L5CLI },
4487 { "ssl_c_serial", smp_fetch_ssl_x_serial, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
4488 { "ssl_c_sha1", smp_fetch_ssl_x_sha1, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Willy Tarreau80aca902013-01-07 15:42:20 +01004489 { "ssl_c_used", smp_fetch_ssl_c_used, 0, NULL, SMP_T_BOOL, SMP_USE_L5CLI },
4490 { "ssl_c_verify", smp_fetch_ssl_c_verify, 0, NULL, SMP_T_UINT, SMP_USE_L5CLI },
Emeric Brunba841a12014-04-30 17:05:08 +02004491 { "ssl_c_version", smp_fetch_ssl_x_version, 0, NULL, SMP_T_UINT, SMP_USE_L5CLI },
Emeric Brunb3cc4252014-10-29 19:03:26 +01004492 { "ssl_f_der", smp_fetch_ssl_x_der, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Emeric Brunba841a12014-04-30 17:05:08 +02004493 { "ssl_f_i_dn", smp_fetch_ssl_x_i_dn, ARG2(0,STR,SINT), NULL, SMP_T_STR, SMP_USE_L5CLI },
4494 { "ssl_f_key_alg", smp_fetch_ssl_x_key_alg, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
4495 { "ssl_f_notafter", smp_fetch_ssl_x_notafter, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
4496 { "ssl_f_notbefore", smp_fetch_ssl_x_notbefore, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
4497 { "ssl_f_sig_alg", smp_fetch_ssl_x_sig_alg, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
4498 { "ssl_f_s_dn", smp_fetch_ssl_x_s_dn, ARG2(0,STR,SINT), NULL, SMP_T_STR, SMP_USE_L5CLI },
4499 { "ssl_f_serial", smp_fetch_ssl_x_serial, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Emeric Brun55f4fa82014-04-30 17:11:25 +02004500 { "ssl_f_sha1", smp_fetch_ssl_x_sha1, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Emeric Brunba841a12014-04-30 17:05:08 +02004501 { "ssl_f_version", smp_fetch_ssl_x_version, 0, NULL, SMP_T_UINT, SMP_USE_L5CLI },
Willy Tarreau80aca902013-01-07 15:42:20 +01004502 { "ssl_fc", smp_fetch_ssl_fc, 0, NULL, SMP_T_BOOL, SMP_USE_L5CLI },
4503 { "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 +01004504 { "ssl_fc_cipher", smp_fetch_ssl_fc_cipher, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Willy Tarreau80aca902013-01-07 15:42:20 +01004505 { "ssl_fc_has_crt", smp_fetch_ssl_fc_has_crt, 0, NULL, SMP_T_BOOL, SMP_USE_L5CLI },
4506 { "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 +02004507#ifdef OPENSSL_NPN_NEGOTIATED
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01004508 { "ssl_fc_npn", smp_fetch_ssl_fc_npn, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Willy Tarreaua33c6542012-10-15 13:19:06 +02004509#endif
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01004510#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01004511 { "ssl_fc_alpn", smp_fetch_ssl_fc_alpn, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Willy Tarreauab861d32013-04-02 02:30:41 +02004512#endif
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01004513 { "ssl_fc_protocol", smp_fetch_ssl_fc_protocol, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Emeric Brunb73a9b02014-04-30 18:49:19 +02004514 { "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 +01004515 { "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 +01004516 { "ssl_fc_session_id", smp_fetch_ssl_fc_session_id, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
4517 { "ssl_fc_sni", smp_fetch_ssl_fc_sni, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Willy Tarreau7875d092012-09-10 08:20:03 +02004518 { NULL, NULL, 0, 0, 0 },
4519}};
4520
4521/* Note: must not be declared <const> as its list will be overwritten.
4522 * Please take care of keeping this list alphabetically sorted.
4523 */
Willy Tarreaudc13c112013-06-21 23:16:39 +02004524static struct acl_kw_list acl_kws = {ILH, {
Thierry FOURNIERc5a4e982014-03-05 16:07:08 +01004525 { "ssl_fc_sni_end", "ssl_fc_sni", PAT_MATCH_END },
4526 { "ssl_fc_sni_reg", "ssl_fc_sni", PAT_MATCH_REG },
Willy Tarreau8ed669b2013-01-11 15:49:37 +01004527 { /* END */ },
Willy Tarreau7875d092012-09-10 08:20:03 +02004528}};
4529
Willy Tarreau79eeafa2012-09-14 07:53:05 +02004530/* Note: must not be declared <const> as its list will be overwritten.
4531 * Please take care of keeping this list alphabetically sorted, doing so helps
4532 * all code contributors.
4533 * Optional keywords are also declared with a NULL ->parse() function so that
4534 * the config parser can report an appropriate error when a known keyword was
4535 * not enabled.
4536 */
Willy Tarreau51fb7652012-09-18 18:24:39 +02004537static struct bind_kw_list bind_kws = { "SSL", { }, {
Willy Tarreauab861d32013-04-02 02:30:41 +02004538 { "alpn", bind_parse_alpn, 1 }, /* set ALPN supported protocols */
Emeric Brunfb510ea2012-10-05 12:00:26 +02004539 { "ca-file", bind_parse_ca_file, 1 }, /* set CAfile to process verify on client cert */
Emeric Brun2d0c4822012-10-02 13:45:20 +02004540 { "ca-ignore-err", bind_parse_ignore_err, 1 }, /* set error IDs to ignore on verify depth > 0 */
4541 { "ciphers", bind_parse_ciphers, 1 }, /* set SSL cipher suite */
Emeric Brunfb510ea2012-10-05 12:00:26 +02004542 { "crl-file", bind_parse_crl_file, 1 }, /* set certificat revocation list file use on client cert verify */
Emeric Brun2d0c4822012-10-02 13:45:20 +02004543 { "crt", bind_parse_crt, 1 }, /* load SSL certificates from this location */
4544 { "crt-ignore-err", bind_parse_ignore_err, 1 }, /* set error IDs to ingore on verify depth == 0 */
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01004545 { "crt-list", bind_parse_crt_list, 1 }, /* load a list of crt from this location */
Emeric Brun2d0c4822012-10-02 13:45:20 +02004546 { "ecdhe", bind_parse_ecdhe, 1 }, /* defines named curve for elliptic curve Diffie-Hellman */
Emeric Brun2cb7ae52012-10-05 14:14:21 +02004547 { "force-sslv3", bind_parse_force_sslv3, 0 }, /* force SSLv3 */
4548 { "force-tlsv10", bind_parse_force_tlsv10, 0 }, /* force TLSv10 */
4549 { "force-tlsv11", bind_parse_force_tlsv11, 0 }, /* force TLSv11 */
4550 { "force-tlsv12", bind_parse_force_tlsv12, 0 }, /* force TLSv12 */
Emeric Brun9b3009b2012-10-05 11:55:06 +02004551 { "no-sslv3", bind_parse_no_sslv3, 0 }, /* disable SSLv3 */
4552 { "no-tlsv10", bind_parse_no_tlsv10, 0 }, /* disable TLSv10 */
4553 { "no-tlsv11", bind_parse_no_tlsv11, 0 }, /* disable TLSv11 */
4554 { "no-tlsv12", bind_parse_no_tlsv12, 0 }, /* disable TLSv12 */
Emeric Brun2d0c4822012-10-02 13:45:20 +02004555 { "no-tls-tickets", bind_parse_no_tls_tickets, 0 }, /* disable session resumption tickets */
Emeric Brun2d0c4822012-10-02 13:45:20 +02004556 { "ssl", bind_parse_ssl, 0 }, /* enable SSL processing */
Emmanuel Hocdet65623372013-01-24 17:17:15 +01004557 { "strict-sni", bind_parse_strict_sni, 0 }, /* refuse negotiation if sni doesn't match a certificate */
Emeric Brun2d0c4822012-10-02 13:45:20 +02004558 { "verify", bind_parse_verify, 1 }, /* set SSL verify method */
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02004559 { "npn", bind_parse_npn, 1 }, /* set NPN supported protocols */
Willy Tarreau79eeafa2012-09-14 07:53:05 +02004560 { NULL, NULL, 0 },
4561}};
Emeric Brun46591952012-05-18 15:47:34 +02004562
Willy Tarreau92faadf2012-10-10 23:04:25 +02004563/* Note: must not be declared <const> as its list will be overwritten.
4564 * Please take care of keeping this list alphabetically sorted, doing so helps
4565 * all code contributors.
4566 * Optional keywords are also declared with a NULL ->parse() function so that
4567 * the config parser can report an appropriate error when a known keyword was
4568 * not enabled.
4569 */
4570static struct srv_kw_list srv_kws = { "SSL", { }, {
Emeric Brunef42d922012-10-11 16:11:36 +02004571 { "ca-file", srv_parse_ca_file, 1, 0 }, /* set CAfile to process verify server cert */
Emeric Brunecc91fe2012-10-11 15:05:10 +02004572 { "check-ssl", srv_parse_check_ssl, 0, 0 }, /* enable SSL for health checks */
4573 { "ciphers", srv_parse_ciphers, 1, 0 }, /* select the cipher suite */
Emeric Brunef42d922012-10-11 16:11:36 +02004574 { "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 +02004575 { "crt", srv_parse_crt, 1, 0 }, /* set client certificate */
Emeric Brunecc91fe2012-10-11 15:05:10 +02004576 { "force-sslv3", srv_parse_force_sslv3, 0, 0 }, /* force SSLv3 */
4577 { "force-tlsv10", srv_parse_force_tlsv10, 0, 0 }, /* force TLSv10 */
4578 { "force-tlsv11", srv_parse_force_tlsv11, 0, 0 }, /* force TLSv11 */
4579 { "force-tlsv12", srv_parse_force_tlsv12, 0, 0 }, /* force TLSv12 */
4580 { "no-sslv3", srv_parse_no_sslv3, 0, 0 }, /* disable SSLv3 */
4581 { "no-tlsv10", srv_parse_no_tlsv10, 0, 0 }, /* disable TLSv10 */
4582 { "no-tlsv11", srv_parse_no_tlsv11, 0, 0 }, /* disable TLSv11 */
4583 { "no-tlsv12", srv_parse_no_tlsv12, 0, 0 }, /* disable TLSv12 */
Emeric Brunf9c5c472012-10-11 15:28:34 +02004584 { "no-tls-tickets", srv_parse_no_tls_tickets, 0, 0 }, /* disable session resumption tickets */
David Safb76832014-05-08 23:42:08 -04004585 { "send-proxy-v2-ssl", srv_parse_send_proxy_ssl, 0, 0 }, /* send PROXY protocol header v2 with SSL info */
4586 { "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 +02004587 { "ssl", srv_parse_ssl, 0, 0 }, /* enable SSL processing */
Emeric Brunef42d922012-10-11 16:11:36 +02004588 { "verify", srv_parse_verify, 1, 0 }, /* set SSL verify method */
Evan Broderbe554312013-06-27 00:05:25 -07004589 { "verifyhost", srv_parse_verifyhost, 1, 0 }, /* require that SSL cert verifies for hostname */
Willy Tarreau92faadf2012-10-10 23:04:25 +02004590 { NULL, NULL, 0, 0 },
4591}};
4592
Emeric Brun42a3e202014-10-30 15:56:50 +01004593static struct cfg_kw_list cfg_kws = {ILH, {
4594 { CFG_GLOBAL, "ssl-default-bind-options", ssl_parse_default_bind_options },
4595 { CFG_GLOBAL, "ssl-default-server-options", ssl_parse_default_server_options },
4596 { 0, NULL, NULL },
4597}};
4598
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02004599/* transport-layer operations for SSL sockets */
4600struct xprt_ops ssl_sock = {
Emeric Brun46591952012-05-18 15:47:34 +02004601 .snd_buf = ssl_sock_from_buf,
4602 .rcv_buf = ssl_sock_to_buf,
4603 .rcv_pipe = NULL,
4604 .snd_pipe = NULL,
4605 .shutr = NULL,
4606 .shutw = ssl_sock_shutw,
4607 .close = ssl_sock_close,
4608 .init = ssl_sock_init,
4609};
4610
4611__attribute__((constructor))
Willy Tarreau92faadf2012-10-10 23:04:25 +02004612static void __ssl_sock_init(void)
4613{
Emeric Brun46591952012-05-18 15:47:34 +02004614 STACK_OF(SSL_COMP)* cm;
4615
Willy Tarreau610f04b2014-02-13 11:36:41 +01004616#ifdef LISTEN_DEFAULT_CIPHERS
4617 global.listen_default_ciphers = LISTEN_DEFAULT_CIPHERS;
4618#endif
4619#ifdef CONNECT_DEFAULT_CIPHERS
4620 global.connect_default_ciphers = CONNECT_DEFAULT_CIPHERS;
4621#endif
4622 if (global.listen_default_ciphers)
4623 global.listen_default_ciphers = strdup(global.listen_default_ciphers);
4624 if (global.connect_default_ciphers)
4625 global.connect_default_ciphers = strdup(global.connect_default_ciphers);
Emeric Brun42a3e202014-10-30 15:56:50 +01004626 global.listen_default_ssloptions = BC_SSL_O_NONE;
4627 global.connect_default_ssloptions = SRV_SSL_O_NONE;
Willy Tarreau610f04b2014-02-13 11:36:41 +01004628
Emeric Brun46591952012-05-18 15:47:34 +02004629 SSL_library_init();
4630 cm = SSL_COMP_get_compression_methods();
4631 sk_SSL_COMP_zero(cm);
Willy Tarreau7875d092012-09-10 08:20:03 +02004632 sample_register_fetches(&sample_fetch_keywords);
4633 acl_register_keywords(&acl_kws);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02004634 bind_register_keywords(&bind_kws);
Willy Tarreau92faadf2012-10-10 23:04:25 +02004635 srv_register_keywords(&srv_kws);
Emeric Brun42a3e202014-10-30 15:56:50 +01004636 cfg_register_keywords(&cfg_kws);
Remi Gacogne5d769ca2015-05-28 16:23:00 +02004637
4638#ifndef OPENSSL_NO_DH
4639 ssl_dh_ptr_index = SSL_CTX_get_ex_new_index(0, NULL, NULL, NULL, NULL);
4640#endif
Emeric Brun46591952012-05-18 15:47:34 +02004641}
4642
Remi Gacogne269a02f2015-05-28 16:39:47 +02004643__attribute__((destructor))
4644static void __ssl_sock_deinit(void)
4645{
4646#ifndef OPENSSL_NO_DH
4647 if (local_dh_1024) {
4648 DH_free(local_dh_1024);
4649 local_dh_1024 = NULL;
4650 }
4651
4652 if (local_dh_2048) {
4653 DH_free(local_dh_2048);
4654 local_dh_2048 = NULL;
4655 }
4656
4657 if (local_dh_4096) {
4658 DH_free(local_dh_4096);
4659 local_dh_4096 = NULL;
4660 }
Remi Gacogne269a02f2015-05-28 16:39:47 +02004661#endif
4662
4663 ERR_remove_state(0);
4664 ERR_free_strings();
4665
4666 EVP_cleanup();
4667
4668#if OPENSSL_VERSION_NUMBER >= 0x00907000L
4669 CRYPTO_cleanup_all_ex_data();
4670#endif
4671}
4672
4673
Emeric Brun46591952012-05-18 15:47:34 +02004674/*
4675 * Local variables:
4676 * c-indent-level: 8
4677 * c-basic-offset: 8
4678 * End:
4679 */