blob: 8f698c0b2012420ce0529e981896442b9112ffe3 [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;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +0100997
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +0200998 if (*name == '!') {
999 neg = 1;
1000 name++;
1001 }
1002 if (*name == '*') {
1003 wild = 1;
1004 name++;
1005 }
1006 /* !* filter is a nop */
1007 if (neg && wild)
1008 return order;
1009 if (*name) {
1010 int j, len;
1011 len = strlen(name);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001012 sc = malloc(sizeof(struct sni_ctx) + len + 1);
1013 for (j = 0; j < len; j++)
1014 sc->name.key[j] = tolower(name[j]);
1015 sc->name.key[len] = 0;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001016 sc->ctx = ctx;
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001017 sc->order = order++;
1018 sc->neg = neg;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001019 if (wild)
1020 ebst_insert(&s->sni_w_ctx, &sc->name);
1021 else
1022 ebst_insert(&s->sni_ctx, &sc->name);
1023 }
1024 return order;
1025}
1026
Emeric Brunfc0421f2012-09-07 17:30:07 +02001027/* Loads a certificate key and CA chain from a file. Returns 0 on error, -1 if
1028 * an early error happens and the caller must call SSL_CTX_free() by itelf.
1029 */
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001030static 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 +02001031{
1032 BIO *in;
1033 X509 *x = NULL, *ca;
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001034 int i, err;
Emeric Brunfc0421f2012-09-07 17:30:07 +02001035 int ret = -1;
1036 int order = 0;
1037 X509_NAME *xname;
1038 char *str;
Emeric Brunfc0421f2012-09-07 17:30:07 +02001039#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
1040 STACK_OF(GENERAL_NAME) *names;
1041#endif
1042
1043 in = BIO_new(BIO_s_file());
1044 if (in == NULL)
1045 goto end;
1046
1047 if (BIO_read_filename(in, file) <= 0)
1048 goto end;
1049
1050 x = PEM_read_bio_X509_AUX(in, NULL, ctx->default_passwd_callback, ctx->default_passwd_callback_userdata);
1051 if (x == NULL)
1052 goto end;
1053
Emeric Brun50bcecc2013-04-22 13:05:23 +02001054 if (fcount) {
1055 while (fcount--)
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001056 order = ssl_sock_add_cert_sni(ctx, s, sni_filter[fcount], order);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001057 }
1058 else {
Emeric Brunfc0421f2012-09-07 17:30:07 +02001059#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001060 names = X509_get_ext_d2i(x, NID_subject_alt_name, NULL, NULL);
1061 if (names) {
1062 for (i = 0; i < sk_GENERAL_NAME_num(names); i++) {
1063 GENERAL_NAME *name = sk_GENERAL_NAME_value(names, i);
1064 if (name->type == GEN_DNS) {
1065 if (ASN1_STRING_to_UTF8((unsigned char **)&str, name->d.dNSName) >= 0) {
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001066 order = ssl_sock_add_cert_sni(ctx, s, str, order);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001067 OPENSSL_free(str);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001068 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02001069 }
1070 }
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001071 sk_GENERAL_NAME_pop_free(names, GENERAL_NAME_free);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001072 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02001073#endif /* SSL_CTRL_SET_TLSEXT_HOSTNAME */
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001074 xname = X509_get_subject_name(x);
1075 i = -1;
1076 while ((i = X509_NAME_get_index_by_NID(xname, NID_commonName, i)) != -1) {
1077 X509_NAME_ENTRY *entry = X509_NAME_get_entry(xname, i);
1078 if (ASN1_STRING_to_UTF8((unsigned char **)&str, entry->value) >= 0) {
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001079 order = ssl_sock_add_cert_sni(ctx, s, str, order);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001080 OPENSSL_free(str);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001081 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02001082 }
1083 }
1084
1085 ret = 0; /* the caller must not free the SSL_CTX argument anymore */
1086 if (!SSL_CTX_use_certificate(ctx, x))
1087 goto end;
1088
1089 if (ctx->extra_certs != NULL) {
1090 sk_X509_pop_free(ctx->extra_certs, X509_free);
1091 ctx->extra_certs = NULL;
1092 }
1093
1094 while ((ca = PEM_read_bio_X509(in, NULL, ctx->default_passwd_callback, ctx->default_passwd_callback_userdata))) {
1095 if (!SSL_CTX_add_extra_chain_cert(ctx, ca)) {
1096 X509_free(ca);
1097 goto end;
1098 }
1099 }
1100
1101 err = ERR_get_error();
1102 if (!err || (ERR_GET_LIB(err) == ERR_LIB_PEM && ERR_GET_REASON(err) == PEM_R_NO_START_LINE)) {
1103 /* we successfully reached the last cert in the file */
1104 ret = 1;
1105 }
1106 ERR_clear_error();
1107
1108end:
1109 if (x)
1110 X509_free(x);
1111
1112 if (in)
1113 BIO_free(in);
1114
1115 return ret;
1116}
1117
Emeric Brun50bcecc2013-04-22 13:05:23 +02001118static 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 +02001119{
1120 int ret;
1121 SSL_CTX *ctx;
1122
1123 ctx = SSL_CTX_new(SSLv23_server_method());
1124 if (!ctx) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02001125 memprintf(err, "%sunable to allocate SSL context for cert '%s'.\n",
1126 err && *err ? *err : "", path);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001127 return 1;
1128 }
1129
1130 if (SSL_CTX_use_PrivateKey_file(ctx, path, SSL_FILETYPE_PEM) <= 0) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02001131 memprintf(err, "%sunable to load SSL private key from PEM file '%s'.\n",
1132 err && *err ? *err : "", path);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001133 SSL_CTX_free(ctx);
1134 return 1;
1135 }
1136
Emeric Brun50bcecc2013-04-22 13:05:23 +02001137 ret = ssl_sock_load_cert_chain_file(ctx, path, bind_conf, sni_filter, fcount);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001138 if (ret <= 0) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02001139 memprintf(err, "%sunable to load SSL certificate from PEM file '%s'.\n",
1140 err && *err ? *err : "", path);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001141 if (ret < 0) /* serious error, must do that ourselves */
1142 SSL_CTX_free(ctx);
1143 return 1;
1144 }
Emeric Brun61694ab2012-10-26 13:35:33 +02001145
1146 if (SSL_CTX_check_private_key(ctx) <= 0) {
1147 memprintf(err, "%sinconsistencies between private key and certificate loaded from PEM file '%s'.\n",
1148 err && *err ? *err : "", path);
1149 return 1;
1150 }
1151
Emeric Brunfc0421f2012-09-07 17:30:07 +02001152 /* we must not free the SSL_CTX anymore below, since it's already in
1153 * the tree, so it will be discovered and cleaned in time.
1154 */
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001155#ifndef OPENSSL_NO_DH
Remi Gacogne5d769ca2015-05-28 16:23:00 +02001156 /* store a NULL pointer to indicate we have not yet loaded
1157 a custom DH param file */
1158 if (ssl_dh_ptr_index >= 0) {
1159 SSL_CTX_set_ex_data(ctx, ssl_dh_ptr_index, NULL);
1160 }
1161
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001162 ret = ssl_sock_load_dh_params(ctx, path);
1163 if (ret < 0) {
1164 if (err)
1165 memprintf(err, "%sunable to load DH parameters from file '%s'.\n",
1166 *err ? *err : "", path);
1167 return 1;
1168 }
1169#endif
1170
Emeric Brun4147b2e2014-06-16 18:36:30 +02001171#ifdef SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB
1172 ret = ssl_sock_load_ocsp(ctx, path);
1173 if (ret < 0) {
1174 if (err)
1175 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",
1176 *err ? *err : "", path);
1177 return 1;
1178 }
1179#endif
1180
Emeric Brunfc0421f2012-09-07 17:30:07 +02001181#ifndef SSL_CTRL_SET_TLSEXT_HOSTNAME
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001182 if (bind_conf->default_ctx) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02001183 memprintf(err, "%sthis version of openssl cannot load multiple SSL certificates.\n",
1184 err && *err ? *err : "");
Emeric Brunfc0421f2012-09-07 17:30:07 +02001185 return 1;
1186 }
1187#endif
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001188 if (!bind_conf->default_ctx)
1189 bind_conf->default_ctx = ctx;
Emeric Brunfc0421f2012-09-07 17:30:07 +02001190
1191 return 0;
1192}
1193
Willy Tarreau79eeafa2012-09-14 07:53:05 +02001194int ssl_sock_load_cert(char *path, struct bind_conf *bind_conf, struct proxy *curproxy, char **err)
Emeric Brunfc0421f2012-09-07 17:30:07 +02001195{
Cyril Bonté62043c92015-01-25 00:16:08 +01001196 struct dirent **de_list;
1197 int i, n;
Emeric Brunfc0421f2012-09-07 17:30:07 +02001198 DIR *dir;
1199 struct stat buf;
Willy Tarreauee2663b2012-12-06 11:36:59 +01001200 char *end;
1201 char fp[MAXPATHLEN+1];
Emeric Brunfc0421f2012-09-07 17:30:07 +02001202 int cfgerr = 0;
1203
1204 if (!(dir = opendir(path)))
Emeric Brun50bcecc2013-04-22 13:05:23 +02001205 return ssl_sock_load_cert_file(path, bind_conf, curproxy, NULL, 0, err);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001206
1207 /* strip trailing slashes, including first one */
1208 for (end = path + strlen(path) - 1; end >= path && *end == '/'; end--)
1209 *end = 0;
1210
Cyril Bonté62043c92015-01-25 00:16:08 +01001211 n = scandir(path, &de_list, 0, alphasort);
1212 if (n < 0) {
1213 memprintf(err, "%sunable to scan directory '%s' : %s.\n",
1214 err && *err ? *err : "", path, strerror(errno));
1215 cfgerr++;
1216 }
1217 else {
1218 for (i = 0; i < n; i++) {
1219 struct dirent *de = de_list[i];
Emeric Brun2aab7222014-06-18 18:15:09 +02001220
Cyril Bonté62043c92015-01-25 00:16:08 +01001221 end = strrchr(de->d_name, '.');
1222 if (end && (!strcmp(end, ".issuer") || !strcmp(end, ".ocsp")))
1223 goto ignore_entry;
1224
1225 snprintf(fp, sizeof(fp), "%s/%s", path, de->d_name);
1226 if (stat(fp, &buf) != 0) {
1227 memprintf(err, "%sunable to stat SSL certificate from file '%s' : %s.\n",
1228 err && *err ? *err : "", fp, strerror(errno));
1229 cfgerr++;
1230 goto ignore_entry;
1231 }
1232 if (!S_ISREG(buf.st_mode))
1233 goto ignore_entry;
1234 cfgerr += ssl_sock_load_cert_file(fp, bind_conf, curproxy, NULL, 0, err);
1235 ignore_entry:
1236 free(de);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001237 }
Cyril Bonté62043c92015-01-25 00:16:08 +01001238 free(de_list);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001239 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02001240 closedir(dir);
1241 return cfgerr;
1242}
1243
Thierry Fournier383085f2013-01-24 14:15:43 +01001244/* Make sure openssl opens /dev/urandom before the chroot. The work is only
1245 * done once. Zero is returned if the operation fails. No error is returned
1246 * if the random is said as not implemented, because we expect that openssl
1247 * will use another method once needed.
1248 */
1249static int ssl_initialize_random()
1250{
1251 unsigned char random;
1252 static int random_initialized = 0;
1253
1254 if (!random_initialized && RAND_bytes(&random, 1) != 0)
1255 random_initialized = 1;
1256
1257 return random_initialized;
1258}
1259
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001260int ssl_sock_load_cert_list_file(char *file, struct bind_conf *bind_conf, struct proxy *curproxy, char **err)
1261{
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001262 char thisline[LINESIZE];
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001263 FILE *f;
1264 int linenum = 0;
1265 int cfgerr = 0;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001266
Willy Tarreauad1731d2013-04-02 17:35:58 +02001267 if ((f = fopen(file, "r")) == NULL) {
1268 memprintf(err, "cannot open file '%s' : %s", file, strerror(errno));
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001269 return 1;
Willy Tarreauad1731d2013-04-02 17:35:58 +02001270 }
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001271
1272 while (fgets(thisline, sizeof(thisline), f) != NULL) {
1273 int arg;
Emeric Brun50bcecc2013-04-22 13:05:23 +02001274 int newarg;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001275 char *end;
1276 char *args[MAX_LINE_ARGS + 1];
1277 char *line = thisline;
1278
1279 linenum++;
1280 end = line + strlen(line);
1281 if (end-line == sizeof(thisline)-1 && *(end-1) != '\n') {
1282 /* Check if we reached the limit and the last char is not \n.
1283 * Watch out for the last line without the terminating '\n'!
1284 */
Willy Tarreauad1731d2013-04-02 17:35:58 +02001285 memprintf(err, "line %d too long in file '%s', limit is %d characters",
1286 linenum, file, (int)sizeof(thisline)-1);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001287 cfgerr = 1;
Willy Tarreauad1731d2013-04-02 17:35:58 +02001288 break;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001289 }
1290
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001291 arg = 0;
Emeric Brun50bcecc2013-04-22 13:05:23 +02001292 newarg = 1;
1293 while (*line) {
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001294 if (*line == '#' || *line == '\n' || *line == '\r') {
1295 /* end of string, end of loop */
1296 *line = 0;
1297 break;
1298 }
1299 else if (isspace(*line)) {
Emeric Brun50bcecc2013-04-22 13:05:23 +02001300 newarg = 1;
1301 *line = 0;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001302 }
Emeric Brun50bcecc2013-04-22 13:05:23 +02001303 else if (newarg) {
1304 if (arg == MAX_LINE_ARGS) {
1305 memprintf(err, "too many args on line %d in file '%s'.",
1306 linenum, file);
1307 cfgerr = 1;
1308 break;
1309 }
1310 newarg = 0;
1311 args[arg++] = line;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001312 }
Emeric Brun50bcecc2013-04-22 13:05:23 +02001313 line++;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001314 }
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001315 if (cfgerr)
1316 break;
Willy Tarreauad1731d2013-04-02 17:35:58 +02001317
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001318 /* empty line */
Emeric Brun50bcecc2013-04-22 13:05:23 +02001319 if (!arg)
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001320 continue;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001321
Emeric Brun50bcecc2013-04-22 13:05:23 +02001322 cfgerr = ssl_sock_load_cert_file(args[0], bind_conf, curproxy, &args[1], arg-1, err);
Willy Tarreauad1731d2013-04-02 17:35:58 +02001323 if (cfgerr) {
1324 memprintf(err, "error processing line %d in file '%s' : %s", linenum, file, *err);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001325 break;
Willy Tarreauad1731d2013-04-02 17:35:58 +02001326 }
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001327 }
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001328 fclose(f);
1329 return cfgerr;
1330}
1331
Emeric Brunfc0421f2012-09-07 17:30:07 +02001332#ifndef SSL_OP_CIPHER_SERVER_PREFERENCE /* needs OpenSSL >= 0.9.7 */
1333#define SSL_OP_CIPHER_SERVER_PREFERENCE 0
1334#endif
1335
1336#ifndef SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION /* needs OpenSSL >= 0.9.7 */
1337#define SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION 0
Willy Tarreau7d588ee2012-11-26 18:47:31 +01001338#define SSL_renegotiate_pending(arg) 0
Emeric Brunfc0421f2012-09-07 17:30:07 +02001339#endif
Emeric Brun2b58d042012-09-20 17:10:03 +02001340#ifndef SSL_OP_SINGLE_ECDH_USE /* needs OpenSSL >= 0.9.8 */
1341#define SSL_OP_SINGLE_ECDH_USE 0
1342#endif
Emeric Brun2d0c4822012-10-02 13:45:20 +02001343#ifndef SSL_OP_NO_TICKET /* needs OpenSSL >= 0.9.8 */
1344#define SSL_OP_NO_TICKET 0
1345#endif
Emeric Brunfc0421f2012-09-07 17:30:07 +02001346#ifndef SSL_OP_NO_COMPRESSION /* needs OpenSSL >= 0.9.9 */
1347#define SSL_OP_NO_COMPRESSION 0
1348#endif
Emeric Brunc0ff4922012-09-28 19:37:02 +02001349#ifndef SSL_OP_NO_TLSv1_1 /* needs OpenSSL >= 1.0.1 */
1350#define SSL_OP_NO_TLSv1_1 0
1351#endif
1352#ifndef SSL_OP_NO_TLSv1_2 /* needs OpenSSL >= 1.0.1 */
1353#define SSL_OP_NO_TLSv1_2 0
1354#endif
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001355#ifndef SSL_OP_SINGLE_DH_USE /* needs OpenSSL >= 0.9.6 */
1356#define SSL_OP_SINGLE_DH_USE 0
1357#endif
Emeric Brun2b58d042012-09-20 17:10:03 +02001358#ifndef SSL_OP_SINGLE_ECDH_USE /* needs OpenSSL >= 1.0.0 */
1359#define SSL_OP_SINGLE_ECDH_USE 0
1360#endif
Emeric Brunfc0421f2012-09-07 17:30:07 +02001361#ifndef SSL_MODE_RELEASE_BUFFERS /* needs OpenSSL >= 1.0.0 */
1362#define SSL_MODE_RELEASE_BUFFERS 0
1363#endif
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001364
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001365int ssl_sock_prepare_ctx(struct bind_conf *bind_conf, SSL_CTX *ctx, struct proxy *curproxy)
Emeric Brunfc0421f2012-09-07 17:30:07 +02001366{
1367 int cfgerr = 0;
Emeric Brun850efd52014-01-29 12:24:34 +01001368 int verify = SSL_VERIFY_NONE;
Remi Gacogneaf5c3da2014-05-19 10:29:58 +02001369 long ssloptions =
Emeric Brunfc0421f2012-09-07 17:30:07 +02001370 SSL_OP_ALL | /* all known workarounds for bugs */
1371 SSL_OP_NO_SSLv2 |
1372 SSL_OP_NO_COMPRESSION |
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001373 SSL_OP_SINGLE_DH_USE |
Emeric Brun2b58d042012-09-20 17:10:03 +02001374 SSL_OP_SINGLE_ECDH_USE |
Emeric Brun3c4bc6e2012-10-04 18:44:19 +02001375 SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION |
1376 SSL_OP_CIPHER_SERVER_PREFERENCE;
Remi Gacogneaf5c3da2014-05-19 10:29:58 +02001377 long sslmode =
Emeric Brunfc0421f2012-09-07 17:30:07 +02001378 SSL_MODE_ENABLE_PARTIAL_WRITE |
1379 SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER |
1380 SSL_MODE_RELEASE_BUFFERS;
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001381 STACK_OF(SSL_CIPHER) * ciphers = NULL;
1382 SSL_CIPHER * cipher = NULL;
Remi Gacognec1eab8c2014-06-12 18:20:11 +02001383 char cipher_description[128];
1384 /* The description of ciphers using an Ephemeral Diffie Hellman key exchange
1385 contains " Kx=DH " or " Kx=DH(". Beware of " Kx=DH/",
1386 which is not ephemeral DH. */
1387 const char dhe_description[] = " Kx=DH ";
1388 const char dhe_export_description[] = " Kx=DH(";
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001389 int idx = 0;
1390 int dhe_found = 0;
Emeric Brunfc0421f2012-09-07 17:30:07 +02001391
Thierry Fournier383085f2013-01-24 14:15:43 +01001392 /* Make sure openssl opens /dev/urandom before the chroot */
1393 if (!ssl_initialize_random()) {
1394 Alert("OpenSSL random data generator initialization failed.\n");
1395 cfgerr++;
1396 }
1397
Emeric Brun89675492012-10-05 13:48:26 +02001398 if (bind_conf->ssl_options & BC_SSL_O_NO_SSLV3)
Emeric Brunfc0421f2012-09-07 17:30:07 +02001399 ssloptions |= SSL_OP_NO_SSLv3;
Emeric Brun89675492012-10-05 13:48:26 +02001400 if (bind_conf->ssl_options & BC_SSL_O_NO_TLSV10)
Emeric Brunfc0421f2012-09-07 17:30:07 +02001401 ssloptions |= SSL_OP_NO_TLSv1;
Emeric Brun89675492012-10-05 13:48:26 +02001402 if (bind_conf->ssl_options & BC_SSL_O_NO_TLSV11)
Emeric Brunc0ff4922012-09-28 19:37:02 +02001403 ssloptions |= SSL_OP_NO_TLSv1_1;
Emeric Brun89675492012-10-05 13:48:26 +02001404 if (bind_conf->ssl_options & BC_SSL_O_NO_TLSV12)
Emeric Brunc0ff4922012-09-28 19:37:02 +02001405 ssloptions |= SSL_OP_NO_TLSv1_2;
Emeric Brun89675492012-10-05 13:48:26 +02001406 if (bind_conf->ssl_options & BC_SSL_O_NO_TLS_TICKETS)
Emeric Brun2d0c4822012-10-02 13:45:20 +02001407 ssloptions |= SSL_OP_NO_TICKET;
Jérémie Courrèges-Anglaseee374c2015-07-25 16:50:52 -06001408 if (bind_conf->ssl_options & BC_SSL_O_USE_SSLV3) {
1409#ifndef OPENSSL_NO_SSL3
Emeric Brun2cb7ae52012-10-05 14:14:21 +02001410 SSL_CTX_set_ssl_version(ctx, SSLv3_server_method());
Jérémie Courrèges-Anglaseee374c2015-07-25 16:50:52 -06001411#else
1412 Alert("SSLv3 support requested but unavailable.\n");
1413 cfgerr++;
1414#endif
1415 }
Emeric Brun2cb7ae52012-10-05 14:14:21 +02001416 if (bind_conf->ssl_options & BC_SSL_O_USE_TLSV10)
1417 SSL_CTX_set_ssl_version(ctx, TLSv1_server_method());
1418#if SSL_OP_NO_TLSv1_1
1419 if (bind_conf->ssl_options & BC_SSL_O_USE_TLSV11)
1420 SSL_CTX_set_ssl_version(ctx, TLSv1_1_server_method());
1421#endif
1422#if SSL_OP_NO_TLSv1_2
1423 if (bind_conf->ssl_options & BC_SSL_O_USE_TLSV12)
1424 SSL_CTX_set_ssl_version(ctx, TLSv1_2_server_method());
1425#endif
Emeric Brunfc0421f2012-09-07 17:30:07 +02001426
1427 SSL_CTX_set_options(ctx, ssloptions);
1428 SSL_CTX_set_mode(ctx, sslmode);
Emeric Brun850efd52014-01-29 12:24:34 +01001429 switch (bind_conf->verify) {
1430 case SSL_SOCK_VERIFY_NONE:
1431 verify = SSL_VERIFY_NONE;
1432 break;
1433 case SSL_SOCK_VERIFY_OPTIONAL:
1434 verify = SSL_VERIFY_PEER;
1435 break;
1436 case SSL_SOCK_VERIFY_REQUIRED:
1437 verify = SSL_VERIFY_PEER|SSL_VERIFY_FAIL_IF_NO_PEER_CERT;
1438 break;
1439 }
1440 SSL_CTX_set_verify(ctx, verify, ssl_sock_bind_verifycbk);
1441 if (verify & SSL_VERIFY_PEER) {
Emeric Brunfb510ea2012-10-05 12:00:26 +02001442 if (bind_conf->ca_file) {
Emeric Brund94b3fe2012-09-20 18:23:56 +02001443 /* load CAfile to verify */
Emeric Brunfb510ea2012-10-05 12:00:26 +02001444 if (!SSL_CTX_load_verify_locations(ctx, bind_conf->ca_file, NULL)) {
Emeric Brund94b3fe2012-09-20 18:23:56 +02001445 Alert("Proxy '%s': unable to load CA file '%s' for bind '%s' at [%s:%d].\n",
Emeric Brunfb510ea2012-10-05 12:00:26 +02001446 curproxy->id, bind_conf->ca_file, bind_conf->arg, bind_conf->file, bind_conf->line);
Emeric Brund94b3fe2012-09-20 18:23:56 +02001447 cfgerr++;
1448 }
1449 /* set CA names fo client cert request, function returns void */
Emeric Brunfb510ea2012-10-05 12:00:26 +02001450 SSL_CTX_set_client_CA_list(ctx, SSL_load_client_CA_file(bind_conf->ca_file));
Emeric Brund94b3fe2012-09-20 18:23:56 +02001451 }
Emeric Brun850efd52014-01-29 12:24:34 +01001452 else {
1453 Alert("Proxy '%s': verify is enabled but no CA file specified for bind '%s' at [%s:%d].\n",
1454 curproxy->id, bind_conf->arg, bind_conf->file, bind_conf->line);
1455 cfgerr++;
1456 }
Emeric Brun051cdab2012-10-02 19:25:50 +02001457#ifdef X509_V_FLAG_CRL_CHECK
Emeric Brunfb510ea2012-10-05 12:00:26 +02001458 if (bind_conf->crl_file) {
Emeric Brund94b3fe2012-09-20 18:23:56 +02001459 X509_STORE *store = SSL_CTX_get_cert_store(ctx);
1460
Emeric Brunfb510ea2012-10-05 12:00:26 +02001461 if (!store || !X509_STORE_load_locations(store, bind_conf->crl_file, NULL)) {
Emeric Brund94b3fe2012-09-20 18:23:56 +02001462 Alert("Proxy '%s': unable to configure CRL file '%s' for bind '%s' at [%s:%d].\n",
Alexander Rigbo37dc94c2015-04-07 14:02:16 +02001463 curproxy->id, bind_conf->crl_file, bind_conf->arg, bind_conf->file, bind_conf->line);
Emeric Brund94b3fe2012-09-20 18:23:56 +02001464 cfgerr++;
1465 }
Emeric Brun561e5742012-10-02 15:20:55 +02001466 else {
1467 X509_STORE_set_flags(store, X509_V_FLAG_CRL_CHECK|X509_V_FLAG_CRL_CHECK_ALL);
1468 }
Emeric Brund94b3fe2012-09-20 18:23:56 +02001469 }
Emeric Brun051cdab2012-10-02 19:25:50 +02001470#endif
Emeric Brun644cde02012-12-14 11:21:13 +01001471 ERR_clear_error();
Emeric Brund94b3fe2012-09-20 18:23:56 +02001472 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02001473
Emeric Brun4f65bff2012-11-16 15:11:00 +01001474 if (global.tune.ssllifetime)
1475 SSL_CTX_set_timeout(ctx, global.tune.ssllifetime);
1476
Emeric Brunfc0421f2012-09-07 17:30:07 +02001477 shared_context_set_cache(ctx);
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001478 if (bind_conf->ciphers &&
1479 !SSL_CTX_set_cipher_list(ctx, bind_conf->ciphers)) {
Emeric Brunfc0421f2012-09-07 17:30:07 +02001480 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 +02001481 curproxy->id, bind_conf->ciphers, bind_conf->arg, bind_conf->file, bind_conf->line);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001482 cfgerr++;
1483 }
1484
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001485 /* If tune.ssl.default-dh-param has not been set and
1486 no static DH params were in the certificate file. */
Remi Gacogne5d769ca2015-05-28 16:23:00 +02001487 if (global.tune.ssl_default_dh_param == 0 &&
1488 (ssl_dh_ptr_index == -1 ||
1489 SSL_CTX_get_ex_data(ctx, ssl_dh_ptr_index) == NULL)) {
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001490 ciphers = ctx->cipher_list;
1491
1492 if (ciphers) {
1493 for (idx = 0; idx < sk_SSL_CIPHER_num(ciphers); idx++) {
1494 cipher = sk_SSL_CIPHER_value(ciphers, idx);
Remi Gacognec1eab8c2014-06-12 18:20:11 +02001495 if (SSL_CIPHER_description(cipher, cipher_description, sizeof (cipher_description)) == cipher_description) {
1496 if (strstr(cipher_description, dhe_description) != NULL ||
1497 strstr(cipher_description, dhe_export_description) != NULL) {
1498 dhe_found = 1;
1499 break;
1500 }
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001501 }
1502 }
1503
1504 if (dhe_found) {
1505 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");
1506 }
1507 }
1508
1509 global.tune.ssl_default_dh_param = 1024;
1510 }
Remi Gacogne60d7aeb2014-07-15 11:36:40 +02001511
1512#ifndef OPENSSL_NO_DH
1513 if (global.tune.ssl_default_dh_param >= 1024) {
1514 if (local_dh_1024 == NULL) {
1515 local_dh_1024 = ssl_get_dh_1024();
1516 }
1517 if (global.tune.ssl_default_dh_param >= 2048) {
1518 if (local_dh_2048 == NULL) {
1519 local_dh_2048 = ssl_get_dh_2048();
1520 }
1521 if (global.tune.ssl_default_dh_param >= 4096) {
1522 if (local_dh_4096 == NULL) {
1523 local_dh_4096 = ssl_get_dh_4096();
1524 }
Remi Gacogne60d7aeb2014-07-15 11:36:40 +02001525 }
1526 }
1527 }
1528#endif /* OPENSSL_NO_DH */
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001529
Emeric Brunfc0421f2012-09-07 17:30:07 +02001530 SSL_CTX_set_info_callback(ctx, ssl_sock_infocbk);
Willy Tarreau5cbe4ef2014-05-08 22:45:11 +02001531#if OPENSSL_VERSION_NUMBER >= 0x00907000L
Emeric Brun29f037d2014-04-25 19:05:36 +02001532 SSL_CTX_set_msg_callback(ctx, ssl_sock_msgcbk);
Willy Tarreau5cbe4ef2014-05-08 22:45:11 +02001533#endif
Emeric Brun29f037d2014-04-25 19:05:36 +02001534
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02001535#ifdef OPENSSL_NPN_NEGOTIATED
1536 if (bind_conf->npn_str)
1537 SSL_CTX_set_next_protos_advertised_cb(ctx, ssl_sock_advertise_npn_protos, bind_conf);
1538#endif
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01001539#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Willy Tarreauab861d32013-04-02 02:30:41 +02001540 if (bind_conf->alpn_str)
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01001541 SSL_CTX_set_alpn_select_cb(ctx, ssl_sock_advertise_alpn_protos, bind_conf);
Willy Tarreauab861d32013-04-02 02:30:41 +02001542#endif
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02001543
Emeric Brunfc0421f2012-09-07 17:30:07 +02001544#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
1545 SSL_CTX_set_tlsext_servername_callback(ctx, ssl_sock_switchctx_cbk);
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001546 SSL_CTX_set_tlsext_servername_arg(ctx, bind_conf);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001547#endif
Emeric Brun2b58d042012-09-20 17:10:03 +02001548#if defined(SSL_CTX_set_tmp_ecdh) && !defined(OPENSSL_NO_ECDH)
Emeric Brun6924ef82013-03-06 14:08:53 +01001549 {
Emeric Brun2b58d042012-09-20 17:10:03 +02001550 int i;
1551 EC_KEY *ecdh;
1552
Emeric Brun6924ef82013-03-06 14:08:53 +01001553 i = OBJ_sn2nid(bind_conf->ecdhe ? bind_conf->ecdhe : ECDHE_DEFAULT_CURVE);
Emeric Brun2b58d042012-09-20 17:10:03 +02001554 if (!i || ((ecdh = EC_KEY_new_by_curve_name(i)) == NULL)) {
1555 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 +01001556 curproxy->id, bind_conf->ecdhe ? bind_conf->ecdhe : ECDHE_DEFAULT_CURVE,
1557 bind_conf->arg, bind_conf->file, bind_conf->line);
Emeric Brun2b58d042012-09-20 17:10:03 +02001558 cfgerr++;
1559 }
1560 else {
1561 SSL_CTX_set_tmp_ecdh(ctx, ecdh);
1562 EC_KEY_free(ecdh);
1563 }
1564 }
1565#endif
1566
Emeric Brunfc0421f2012-09-07 17:30:07 +02001567 return cfgerr;
1568}
1569
Evan Broderbe554312013-06-27 00:05:25 -07001570static int ssl_sock_srv_hostcheck(const char *pattern, const char *hostname)
1571{
1572 const char *pattern_wildcard, *pattern_left_label_end, *hostname_left_label_end;
1573 size_t prefixlen, suffixlen;
1574
1575 /* Trivial case */
1576 if (strcmp(pattern, hostname) == 0)
1577 return 1;
1578
Evan Broderbe554312013-06-27 00:05:25 -07001579 /* The rest of this logic is based on RFC 6125, section 6.4.3
1580 * (http://tools.ietf.org/html/rfc6125#section-6.4.3) */
1581
Emeric Bruna848dae2013-10-08 11:27:28 +02001582 pattern_wildcard = NULL;
1583 pattern_left_label_end = pattern;
1584 while (*pattern_left_label_end != '.') {
1585 switch (*pattern_left_label_end) {
1586 case 0:
1587 /* End of label not found */
1588 return 0;
1589 case '*':
1590 /* If there is more than one wildcards */
1591 if (pattern_wildcard)
1592 return 0;
1593 pattern_wildcard = pattern_left_label_end;
1594 break;
1595 }
1596 pattern_left_label_end++;
1597 }
1598
1599 /* If it's not trivial and there is no wildcard, it can't
1600 * match */
1601 if (!pattern_wildcard)
Evan Broderbe554312013-06-27 00:05:25 -07001602 return 0;
1603
1604 /* Make sure all labels match except the leftmost */
1605 hostname_left_label_end = strchr(hostname, '.');
1606 if (!hostname_left_label_end
1607 || strcmp(pattern_left_label_end, hostname_left_label_end) != 0)
1608 return 0;
1609
1610 /* Make sure the leftmost label of the hostname is long enough
1611 * that the wildcard can match */
Emeric Brun369da852013-10-08 11:39:35 +02001612 if (hostname_left_label_end - hostname < (pattern_left_label_end - pattern) - 1)
Evan Broderbe554312013-06-27 00:05:25 -07001613 return 0;
1614
1615 /* Finally compare the string on either side of the
1616 * wildcard */
1617 prefixlen = pattern_wildcard - pattern;
1618 suffixlen = pattern_left_label_end - (pattern_wildcard + 1);
Emeric Bruna848dae2013-10-08 11:27:28 +02001619 if ((prefixlen && (memcmp(pattern, hostname, prefixlen) != 0))
1620 || (suffixlen && (memcmp(pattern_wildcard + 1, hostname_left_label_end - suffixlen, suffixlen) != 0)))
Evan Broderbe554312013-06-27 00:05:25 -07001621 return 0;
1622
1623 return 1;
1624}
1625
1626static int ssl_sock_srv_verifycbk(int ok, X509_STORE_CTX *ctx)
1627{
1628 SSL *ssl;
1629 struct connection *conn;
1630 char *servername;
1631
1632 int depth;
1633 X509 *cert;
1634 STACK_OF(GENERAL_NAME) *alt_names;
1635 int i;
1636 X509_NAME *cert_subject;
1637 char *str;
1638
1639 if (ok == 0)
1640 return ok;
1641
1642 ssl = X509_STORE_CTX_get_ex_data(ctx, SSL_get_ex_data_X509_STORE_CTX_idx());
1643 conn = (struct connection *)SSL_get_app_data(ssl);
1644
1645 servername = objt_server(conn->target)->ssl_ctx.verify_host;
1646
1647 /* We only need to verify the CN on the actual server cert,
1648 * not the indirect CAs */
1649 depth = X509_STORE_CTX_get_error_depth(ctx);
1650 if (depth != 0)
1651 return ok;
1652
1653 /* At this point, the cert is *not* OK unless we can find a
1654 * hostname match */
1655 ok = 0;
1656
1657 cert = X509_STORE_CTX_get_current_cert(ctx);
1658 /* It seems like this might happen if verify peer isn't set */
1659 if (!cert)
1660 return ok;
1661
1662 alt_names = X509_get_ext_d2i(cert, NID_subject_alt_name, NULL, NULL);
1663 if (alt_names) {
1664 for (i = 0; !ok && i < sk_GENERAL_NAME_num(alt_names); i++) {
1665 GENERAL_NAME *name = sk_GENERAL_NAME_value(alt_names, i);
1666 if (name->type == GEN_DNS) {
Emeric Bruna33410c2013-09-17 15:47:48 +02001667#if OPENSSL_VERSION_NUMBER < 0x00907000L
1668 if (ASN1_STRING_to_UTF8((unsigned char **)&str, name->d.ia5) >= 0) {
1669#else
Evan Broderbe554312013-06-27 00:05:25 -07001670 if (ASN1_STRING_to_UTF8((unsigned char **)&str, name->d.dNSName) >= 0) {
Emeric Bruna33410c2013-09-17 15:47:48 +02001671#endif
Evan Broderbe554312013-06-27 00:05:25 -07001672 ok = ssl_sock_srv_hostcheck(str, servername);
1673 OPENSSL_free(str);
1674 }
1675 }
1676 }
Emeric Brun4ad50a42013-09-17 15:19:54 +02001677 sk_GENERAL_NAME_pop_free(alt_names, GENERAL_NAME_free);
Evan Broderbe554312013-06-27 00:05:25 -07001678 }
1679
1680 cert_subject = X509_get_subject_name(cert);
1681 i = -1;
1682 while (!ok && (i = X509_NAME_get_index_by_NID(cert_subject, NID_commonName, i)) != -1) {
1683 X509_NAME_ENTRY *entry = X509_NAME_get_entry(cert_subject, i);
1684 if (ASN1_STRING_to_UTF8((unsigned char **)&str, entry->value) >= 0) {
1685 ok = ssl_sock_srv_hostcheck(str, servername);
1686 OPENSSL_free(str);
1687 }
1688 }
1689
1690 return ok;
1691}
1692
Emeric Brun94324a42012-10-11 14:00:19 +02001693/* prepare ssl context from servers options. Returns an error count */
1694int ssl_sock_prepare_srv_ctx(struct server *srv, struct proxy *curproxy)
1695{
1696 int cfgerr = 0;
Remi Gacogneaf5c3da2014-05-19 10:29:58 +02001697 long options =
Emeric Brun94324a42012-10-11 14:00:19 +02001698 SSL_OP_ALL | /* all known workarounds for bugs */
1699 SSL_OP_NO_SSLv2 |
1700 SSL_OP_NO_COMPRESSION;
Remi Gacogneaf5c3da2014-05-19 10:29:58 +02001701 long mode =
Emeric Brun94324a42012-10-11 14:00:19 +02001702 SSL_MODE_ENABLE_PARTIAL_WRITE |
1703 SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER |
1704 SSL_MODE_RELEASE_BUFFERS;
Emeric Brun850efd52014-01-29 12:24:34 +01001705 int verify = SSL_VERIFY_NONE;
Emeric Brun94324a42012-10-11 14:00:19 +02001706
Thierry Fournier383085f2013-01-24 14:15:43 +01001707 /* Make sure openssl opens /dev/urandom before the chroot */
1708 if (!ssl_initialize_random()) {
1709 Alert("OpenSSL random data generator initialization failed.\n");
1710 cfgerr++;
1711 }
1712
Emeric Brun94324a42012-10-11 14:00:19 +02001713 /* Initiate SSL context for current server */
1714 srv->ssl_ctx.reused_sess = NULL;
1715 if (srv->use_ssl)
1716 srv->xprt = &ssl_sock;
1717 if (srv->check.use_ssl)
Cyril Bonté1f96a872014-11-15 22:41:27 +01001718 srv->check.xprt = &ssl_sock;
Emeric Brun94324a42012-10-11 14:00:19 +02001719
1720 srv->ssl_ctx.ctx = SSL_CTX_new(SSLv23_client_method());
1721 if (!srv->ssl_ctx.ctx) {
1722 Alert("config : %s '%s', server '%s': unable to allocate ssl context.\n",
1723 proxy_type_str(curproxy), curproxy->id,
1724 srv->id);
1725 cfgerr++;
1726 return cfgerr;
1727 }
Emeric Bruna7aa3092012-10-26 12:58:00 +02001728 if (srv->ssl_ctx.client_crt) {
1729 if (SSL_CTX_use_PrivateKey_file(srv->ssl_ctx.ctx, srv->ssl_ctx.client_crt, SSL_FILETYPE_PEM) <= 0) {
1730 Alert("config : %s '%s', server '%s': unable to load SSL private key from PEM file '%s'.\n",
1731 proxy_type_str(curproxy), curproxy->id,
1732 srv->id, srv->ssl_ctx.client_crt);
1733 cfgerr++;
1734 }
1735 else if (SSL_CTX_use_certificate_chain_file(srv->ssl_ctx.ctx, srv->ssl_ctx.client_crt) <= 0) {
1736 Alert("config : %s '%s', server '%s': unable to load ssl certificate from PEM file '%s'.\n",
1737 proxy_type_str(curproxy), curproxy->id,
1738 srv->id, srv->ssl_ctx.client_crt);
1739 cfgerr++;
1740 }
1741 else if (SSL_CTX_check_private_key(srv->ssl_ctx.ctx) <= 0) {
1742 Alert("config : %s '%s', server '%s': inconsistencies between private key and certificate loaded from PEM file '%s'.\n",
1743 proxy_type_str(curproxy), curproxy->id,
1744 srv->id, srv->ssl_ctx.client_crt);
1745 cfgerr++;
1746 }
1747 }
Emeric Brun94324a42012-10-11 14:00:19 +02001748
1749 if (srv->ssl_ctx.options & SRV_SSL_O_NO_SSLV3)
1750 options |= SSL_OP_NO_SSLv3;
1751 if (srv->ssl_ctx.options & SRV_SSL_O_NO_TLSV10)
1752 options |= SSL_OP_NO_TLSv1;
1753 if (srv->ssl_ctx.options & SRV_SSL_O_NO_TLSV11)
1754 options |= SSL_OP_NO_TLSv1_1;
1755 if (srv->ssl_ctx.options & SRV_SSL_O_NO_TLSV12)
1756 options |= SSL_OP_NO_TLSv1_2;
Emeric Brunf9c5c472012-10-11 15:28:34 +02001757 if (srv->ssl_ctx.options & SRV_SSL_O_NO_TLS_TICKETS)
1758 options |= SSL_OP_NO_TICKET;
Jérémie Courrèges-Anglaseee374c2015-07-25 16:50:52 -06001759 if (srv->ssl_ctx.options & SRV_SSL_O_USE_SSLV3) {
1760#ifndef OPENSSL_NO_SSL3
Emeric Brun94324a42012-10-11 14:00:19 +02001761 SSL_CTX_set_ssl_version(srv->ssl_ctx.ctx, SSLv3_client_method());
Jérémie Courrèges-Anglaseee374c2015-07-25 16:50:52 -06001762#else
Thierry FOURNIER2272b4f2015-08-26 08:21:26 +02001763 Alert("SSLv3 support requested but unavailable.\n");
Jérémie Courrèges-Anglaseee374c2015-07-25 16:50:52 -06001764 cfgerr++;
1765#endif
1766 }
Emeric Brun94324a42012-10-11 14:00:19 +02001767 if (srv->ssl_ctx.options & SRV_SSL_O_USE_TLSV10)
1768 SSL_CTX_set_ssl_version(srv->ssl_ctx.ctx, TLSv1_client_method());
1769#if SSL_OP_NO_TLSv1_1
1770 if (srv->ssl_ctx.options & SRV_SSL_O_USE_TLSV11)
1771 SSL_CTX_set_ssl_version(srv->ssl_ctx.ctx, TLSv1_1_client_method());
1772#endif
1773#if SSL_OP_NO_TLSv1_2
1774 if (srv->ssl_ctx.options & SRV_SSL_O_USE_TLSV12)
1775 SSL_CTX_set_ssl_version(srv->ssl_ctx.ctx, TLSv1_2_client_method());
1776#endif
1777
1778 SSL_CTX_set_options(srv->ssl_ctx.ctx, options);
1779 SSL_CTX_set_mode(srv->ssl_ctx.ctx, mode);
Emeric Brun850efd52014-01-29 12:24:34 +01001780
1781 if (global.ssl_server_verify == SSL_SERVER_VERIFY_REQUIRED)
1782 verify = SSL_VERIFY_PEER;
1783
1784 switch (srv->ssl_ctx.verify) {
1785 case SSL_SOCK_VERIFY_NONE:
1786 verify = SSL_VERIFY_NONE;
1787 break;
1788 case SSL_SOCK_VERIFY_REQUIRED:
1789 verify = SSL_VERIFY_PEER;
1790 break;
1791 }
Evan Broderbe554312013-06-27 00:05:25 -07001792 SSL_CTX_set_verify(srv->ssl_ctx.ctx,
Emeric Brun850efd52014-01-29 12:24:34 +01001793 verify,
Evan Broderbe554312013-06-27 00:05:25 -07001794 srv->ssl_ctx.verify_host ? ssl_sock_srv_verifycbk : NULL);
Emeric Brun850efd52014-01-29 12:24:34 +01001795 if (verify & SSL_VERIFY_PEER) {
Emeric Brunef42d922012-10-11 16:11:36 +02001796 if (srv->ssl_ctx.ca_file) {
1797 /* load CAfile to verify */
1798 if (!SSL_CTX_load_verify_locations(srv->ssl_ctx.ctx, srv->ssl_ctx.ca_file, NULL)) {
Willy Tarreau07ba08b2014-02-16 19:22:08 +01001799 Alert("Proxy '%s', server '%s' [%s:%d] unable to load CA file '%s'.\n",
Emeric Brunef42d922012-10-11 16:11:36 +02001800 curproxy->id, srv->id,
1801 srv->conf.file, srv->conf.line, srv->ssl_ctx.ca_file);
1802 cfgerr++;
1803 }
1804 }
Emeric Brun850efd52014-01-29 12:24:34 +01001805 else {
1806 if (global.ssl_server_verify == SSL_SERVER_VERIFY_REQUIRED)
Willy Tarreau07ba08b2014-02-16 19:22:08 +01001807 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 +01001808 curproxy->id, srv->id,
1809 srv->conf.file, srv->conf.line);
1810 else
Willy Tarreau07ba08b2014-02-16 19:22:08 +01001811 Alert("Proxy '%s', server '%s' [%s:%d] verify is enabled but no CA file specified.\n",
Emeric Brun850efd52014-01-29 12:24:34 +01001812 curproxy->id, srv->id,
1813 srv->conf.file, srv->conf.line);
1814 cfgerr++;
1815 }
Emeric Brunef42d922012-10-11 16:11:36 +02001816#ifdef X509_V_FLAG_CRL_CHECK
1817 if (srv->ssl_ctx.crl_file) {
1818 X509_STORE *store = SSL_CTX_get_cert_store(srv->ssl_ctx.ctx);
1819
1820 if (!store || !X509_STORE_load_locations(store, srv->ssl_ctx.crl_file, NULL)) {
Willy Tarreau07ba08b2014-02-16 19:22:08 +01001821 Alert("Proxy '%s', server '%s' [%s:%d] unable to configure CRL file '%s'.\n",
Emeric Brunef42d922012-10-11 16:11:36 +02001822 curproxy->id, srv->id,
1823 srv->conf.file, srv->conf.line, srv->ssl_ctx.crl_file);
1824 cfgerr++;
1825 }
1826 else {
1827 X509_STORE_set_flags(store, X509_V_FLAG_CRL_CHECK|X509_V_FLAG_CRL_CHECK_ALL);
1828 }
1829 }
1830#endif
1831 }
1832
Emeric Brun4f65bff2012-11-16 15:11:00 +01001833 if (global.tune.ssllifetime)
1834 SSL_CTX_set_timeout(srv->ssl_ctx.ctx, global.tune.ssllifetime);
1835
Emeric Brun94324a42012-10-11 14:00:19 +02001836 SSL_CTX_set_session_cache_mode(srv->ssl_ctx.ctx, SSL_SESS_CACHE_OFF);
1837 if (srv->ssl_ctx.ciphers &&
1838 !SSL_CTX_set_cipher_list(srv->ssl_ctx.ctx, srv->ssl_ctx.ciphers)) {
1839 Alert("Proxy '%s', server '%s' [%s:%d] : unable to set SSL cipher list to '%s'.\n",
1840 curproxy->id, srv->id,
1841 srv->conf.file, srv->conf.line, srv->ssl_ctx.ciphers);
1842 cfgerr++;
1843 }
1844
1845 return cfgerr;
1846}
1847
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001848/* Walks down the two trees in bind_conf and prepares all certs. The pointer may
Emeric Brunfc0421f2012-09-07 17:30:07 +02001849 * be NULL, in which case nothing is done. Returns the number of errors
1850 * encountered.
1851 */
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001852int ssl_sock_prepare_all_ctx(struct bind_conf *bind_conf, struct proxy *px)
Emeric Brunfc0421f2012-09-07 17:30:07 +02001853{
1854 struct ebmb_node *node;
1855 struct sni_ctx *sni;
1856 int err = 0;
1857
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001858 if (!bind_conf || !bind_conf->is_ssl)
Emeric Brunfc0421f2012-09-07 17:30:07 +02001859 return 0;
1860
Emeric Brun8068b032014-10-30 19:25:24 +01001861 if (bind_conf->default_ctx)
1862 err += ssl_sock_prepare_ctx(bind_conf, bind_conf->default_ctx, px);
1863
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001864 node = ebmb_first(&bind_conf->sni_ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001865 while (node) {
1866 sni = ebmb_entry(node, struct sni_ctx, name);
Emeric Brun8068b032014-10-30 19:25:24 +01001867 if (!sni->order && sni->ctx != bind_conf->default_ctx)
1868 /* only initialize the CTX on its first occurrence and
1869 if it is not the default_ctx */
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001870 err += ssl_sock_prepare_ctx(bind_conf, sni->ctx, px);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001871 node = ebmb_next(node);
1872 }
1873
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001874 node = ebmb_first(&bind_conf->sni_w_ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001875 while (node) {
1876 sni = ebmb_entry(node, struct sni_ctx, name);
Emeric Brun8068b032014-10-30 19:25:24 +01001877 if (!sni->order && sni->ctx != bind_conf->default_ctx)
1878 /* only initialize the CTX on its first occurrence and
1879 if it is not the default_ctx */
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001880 err += ssl_sock_prepare_ctx(bind_conf, sni->ctx, px);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001881 node = ebmb_next(node);
1882 }
1883 return err;
1884}
1885
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001886/* Walks down the two trees in bind_conf and frees all the certs. The pointer may
Emeric Brunfc0421f2012-09-07 17:30:07 +02001887 * be NULL, in which case nothing is done. The default_ctx is nullified too.
1888 */
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001889void ssl_sock_free_all_ctx(struct bind_conf *bind_conf)
Emeric Brunfc0421f2012-09-07 17:30:07 +02001890{
1891 struct ebmb_node *node, *back;
1892 struct sni_ctx *sni;
1893
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001894 if (!bind_conf || !bind_conf->is_ssl)
Emeric Brunfc0421f2012-09-07 17:30:07 +02001895 return;
1896
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001897 node = ebmb_first(&bind_conf->sni_ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001898 while (node) {
1899 sni = ebmb_entry(node, struct sni_ctx, name);
1900 back = ebmb_next(node);
1901 ebmb_delete(node);
1902 if (!sni->order) /* only free the CTX on its first occurrence */
1903 SSL_CTX_free(sni->ctx);
1904 free(sni);
1905 node = back;
1906 }
1907
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001908 node = ebmb_first(&bind_conf->sni_w_ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001909 while (node) {
1910 sni = ebmb_entry(node, struct sni_ctx, name);
1911 back = ebmb_next(node);
1912 ebmb_delete(node);
1913 if (!sni->order) /* only free the CTX on its first occurrence */
1914 SSL_CTX_free(sni->ctx);
1915 free(sni);
1916 node = back;
1917 }
1918
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001919 bind_conf->default_ctx = NULL;
Emeric Brune1f38db2012-09-03 20:36:47 +02001920}
1921
Emeric Brun46591952012-05-18 15:47:34 +02001922/*
1923 * This function is called if SSL * context is not yet allocated. The function
1924 * is designed to be called before any other data-layer operation and sets the
1925 * handshake flag on the connection. It is safe to call it multiple times.
1926 * It returns 0 on success and -1 in error case.
1927 */
1928static int ssl_sock_init(struct connection *conn)
1929{
1930 /* already initialized */
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02001931 if (conn->xprt_ctx)
Emeric Brun46591952012-05-18 15:47:34 +02001932 return 0;
1933
Willy Tarreau3c728722014-01-23 13:50:42 +01001934 if (!conn_ctrl_ready(conn))
Willy Tarreauf79c8172013-10-21 16:30:56 +02001935 return 0;
1936
Willy Tarreau20879a02012-12-03 16:32:10 +01001937 if (global.maxsslconn && sslconns >= global.maxsslconn) {
1938 conn->err_code = CO_ER_SSL_TOO_MANY;
Willy Tarreau403edff2012-09-06 11:58:37 +02001939 return -1;
Willy Tarreau20879a02012-12-03 16:32:10 +01001940 }
Willy Tarreau403edff2012-09-06 11:58:37 +02001941
Emeric Brun46591952012-05-18 15:47:34 +02001942 /* If it is in client mode initiate SSL session
1943 in connect state otherwise accept state */
Willy Tarreau3fdb3662012-11-12 00:42:33 +01001944 if (objt_server(conn->target)) {
Willy Tarreau9bcc01a2014-11-13 13:48:58 +01001945 int may_retry = 1;
1946
1947 retry_connect:
Emeric Brun46591952012-05-18 15:47:34 +02001948 /* Alloc a new SSL session ctx */
Willy Tarreau3fdb3662012-11-12 00:42:33 +01001949 conn->xprt_ctx = SSL_new(objt_server(conn->target)->ssl_ctx.ctx);
Willy Tarreau20879a02012-12-03 16:32:10 +01001950 if (!conn->xprt_ctx) {
Willy Tarreau9bcc01a2014-11-13 13:48:58 +01001951 if (may_retry--) {
1952 pool_gc2();
1953 goto retry_connect;
1954 }
Willy Tarreau20879a02012-12-03 16:32:10 +01001955 conn->err_code = CO_ER_SSL_NO_MEM;
Emeric Brun46591952012-05-18 15:47:34 +02001956 return -1;
Willy Tarreau20879a02012-12-03 16:32:10 +01001957 }
Emeric Brun46591952012-05-18 15:47:34 +02001958
Emeric Brun46591952012-05-18 15:47:34 +02001959 /* set fd on SSL session context */
Emeric Brun90951492014-11-12 17:35:37 +01001960 if (!SSL_set_fd(conn->xprt_ctx, conn->t.sock.fd)) {
1961 SSL_free(conn->xprt_ctx);
1962 conn->xprt_ctx = NULL;
Willy Tarreau9bcc01a2014-11-13 13:48:58 +01001963 if (may_retry--) {
1964 pool_gc2();
1965 goto retry_connect;
1966 }
Emeric Brun90951492014-11-12 17:35:37 +01001967 conn->err_code = CO_ER_SSL_NO_MEM;
1968 return -1;
1969 }
Emeric Brun46591952012-05-18 15:47:34 +02001970
Evan Broderbe554312013-06-27 00:05:25 -07001971 /* set connection pointer */
Emeric Brun90951492014-11-12 17:35:37 +01001972 if (!SSL_set_app_data(conn->xprt_ctx, conn)) {
1973 SSL_free(conn->xprt_ctx);
1974 conn->xprt_ctx = NULL;
Willy Tarreau9bcc01a2014-11-13 13:48:58 +01001975 if (may_retry--) {
1976 pool_gc2();
1977 goto retry_connect;
1978 }
Emeric Brun90951492014-11-12 17:35:37 +01001979 conn->err_code = CO_ER_SSL_NO_MEM;
1980 return -1;
1981 }
1982
1983 SSL_set_connect_state(conn->xprt_ctx);
1984 if (objt_server(conn->target)->ssl_ctx.reused_sess) {
1985 if(!SSL_set_session(conn->xprt_ctx, objt_server(conn->target)->ssl_ctx.reused_sess)) {
1986 SSL_SESSION_free(objt_server(conn->target)->ssl_ctx.reused_sess);
1987 objt_server(conn->target)->ssl_ctx.reused_sess = NULL;
1988 }
1989 }
Evan Broderbe554312013-06-27 00:05:25 -07001990
Emeric Brun46591952012-05-18 15:47:34 +02001991 /* leave init state and start handshake */
Willy Tarreau05737472012-09-04 08:03:39 +02001992 conn->flags |= CO_FL_SSL_WAIT_HS | CO_FL_WAIT_L6_CONN;
Willy Tarreau403edff2012-09-06 11:58:37 +02001993
1994 sslconns++;
Willy Tarreau71b734c2014-01-28 15:19:44 +01001995 totalsslconns++;
Emeric Brun46591952012-05-18 15:47:34 +02001996 return 0;
1997 }
Willy Tarreau3fdb3662012-11-12 00:42:33 +01001998 else if (objt_listener(conn->target)) {
Willy Tarreau9bcc01a2014-11-13 13:48:58 +01001999 int may_retry = 1;
2000
2001 retry_accept:
Emeric Brun46591952012-05-18 15:47:34 +02002002 /* Alloc a new SSL session ctx */
Willy Tarreau3fdb3662012-11-12 00:42:33 +01002003 conn->xprt_ctx = SSL_new(objt_listener(conn->target)->bind_conf->default_ctx);
Willy Tarreau20879a02012-12-03 16:32:10 +01002004 if (!conn->xprt_ctx) {
Willy Tarreau9bcc01a2014-11-13 13:48:58 +01002005 if (may_retry--) {
2006 pool_gc2();
2007 goto retry_accept;
2008 }
Willy Tarreau20879a02012-12-03 16:32:10 +01002009 conn->err_code = CO_ER_SSL_NO_MEM;
Emeric Brun46591952012-05-18 15:47:34 +02002010 return -1;
Willy Tarreau20879a02012-12-03 16:32:10 +01002011 }
Emeric Brun46591952012-05-18 15:47:34 +02002012
Emeric Brun46591952012-05-18 15:47:34 +02002013 /* set fd on SSL session context */
Emeric Brun90951492014-11-12 17:35:37 +01002014 if (!SSL_set_fd(conn->xprt_ctx, conn->t.sock.fd)) {
2015 SSL_free(conn->xprt_ctx);
2016 conn->xprt_ctx = NULL;
Willy Tarreau9bcc01a2014-11-13 13:48:58 +01002017 if (may_retry--) {
2018 pool_gc2();
2019 goto retry_accept;
2020 }
Emeric Brun90951492014-11-12 17:35:37 +01002021 conn->err_code = CO_ER_SSL_NO_MEM;
2022 return -1;
2023 }
Emeric Brun46591952012-05-18 15:47:34 +02002024
Emeric Brune1f38db2012-09-03 20:36:47 +02002025 /* set connection pointer */
Emeric Brun90951492014-11-12 17:35:37 +01002026 if (!SSL_set_app_data(conn->xprt_ctx, conn)) {
2027 SSL_free(conn->xprt_ctx);
2028 conn->xprt_ctx = NULL;
Willy Tarreau9bcc01a2014-11-13 13:48:58 +01002029 if (may_retry--) {
2030 pool_gc2();
2031 goto retry_accept;
2032 }
Emeric Brun90951492014-11-12 17:35:37 +01002033 conn->err_code = CO_ER_SSL_NO_MEM;
2034 return -1;
2035 }
2036
2037 SSL_set_accept_state(conn->xprt_ctx);
Emeric Brune1f38db2012-09-03 20:36:47 +02002038
Emeric Brun46591952012-05-18 15:47:34 +02002039 /* leave init state and start handshake */
Willy Tarreau05737472012-09-04 08:03:39 +02002040 conn->flags |= CO_FL_SSL_WAIT_HS | CO_FL_WAIT_L6_CONN;
Willy Tarreau403edff2012-09-06 11:58:37 +02002041
2042 sslconns++;
Willy Tarreau71b734c2014-01-28 15:19:44 +01002043 totalsslconns++;
Emeric Brun46591952012-05-18 15:47:34 +02002044 return 0;
2045 }
2046 /* don't know how to handle such a target */
Willy Tarreau20879a02012-12-03 16:32:10 +01002047 conn->err_code = CO_ER_SSL_NO_TARGET;
Emeric Brun46591952012-05-18 15:47:34 +02002048 return -1;
2049}
2050
2051
2052/* This is the callback which is used when an SSL handshake is pending. It
2053 * updates the FD status if it wants some polling before being called again.
2054 * It returns 0 if it fails in a fatal way or needs to poll to go further,
2055 * otherwise it returns non-zero and removes itself from the connection's
2056 * flags (the bit is provided in <flag> by the caller).
2057 */
2058int ssl_sock_handshake(struct connection *conn, unsigned int flag)
2059{
2060 int ret;
2061
Willy Tarreau3c728722014-01-23 13:50:42 +01002062 if (!conn_ctrl_ready(conn))
Willy Tarreauf79c8172013-10-21 16:30:56 +02002063 return 0;
2064
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02002065 if (!conn->xprt_ctx)
Emeric Brun46591952012-05-18 15:47:34 +02002066 goto out_error;
2067
Emeric Brun674b7432012-11-08 19:21:55 +01002068 /* If we use SSL_do_handshake to process a reneg initiated by
2069 * the remote peer, it sometimes returns SSL_ERROR_SSL.
2070 * Usually SSL_write and SSL_read are used and process implicitly
2071 * the reneg handshake.
2072 * Here we use SSL_peek as a workaround for reneg.
2073 */
2074 if ((conn->flags & CO_FL_CONNECTED) && SSL_renegotiate_pending(conn->xprt_ctx)) {
2075 char c;
2076
2077 ret = SSL_peek(conn->xprt_ctx, &c, 1);
2078 if (ret <= 0) {
2079 /* handshake may have not been completed, let's find why */
2080 ret = SSL_get_error(conn->xprt_ctx, ret);
2081 if (ret == SSL_ERROR_WANT_WRITE) {
2082 /* SSL handshake needs to write, L4 connection may not be ready */
2083 __conn_sock_stop_recv(conn);
Willy Tarreaue1f50c42014-01-22 20:02:06 +01002084 __conn_sock_want_send(conn);
2085 fd_cant_send(conn->t.sock.fd);
Emeric Brun674b7432012-11-08 19:21:55 +01002086 return 0;
2087 }
2088 else if (ret == SSL_ERROR_WANT_READ) {
2089 /* handshake may have been completed but we have
2090 * no more data to read.
2091 */
2092 if (!SSL_renegotiate_pending(conn->xprt_ctx)) {
2093 ret = 1;
2094 goto reneg_ok;
2095 }
2096 /* SSL handshake needs to read, L4 connection is ready */
2097 if (conn->flags & CO_FL_WAIT_L4_CONN)
2098 conn->flags &= ~CO_FL_WAIT_L4_CONN;
2099 __conn_sock_stop_send(conn);
Willy Tarreaue1f50c42014-01-22 20:02:06 +01002100 __conn_sock_want_recv(conn);
2101 fd_cant_recv(conn->t.sock.fd);
Emeric Brun674b7432012-11-08 19:21:55 +01002102 return 0;
2103 }
2104 else if (ret == SSL_ERROR_SYSCALL) {
2105 /* if errno is null, then connection was successfully established */
2106 if (!errno && conn->flags & CO_FL_WAIT_L4_CONN)
2107 conn->flags &= ~CO_FL_WAIT_L4_CONN;
Willy Tarreau20879a02012-12-03 16:32:10 +01002108 if (!conn->err_code) {
Emeric Brun29f037d2014-04-25 19:05:36 +02002109 if (!((SSL *)conn->xprt_ctx)->packet_length) {
2110 if (!errno) {
2111 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
2112 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
2113 else
2114 conn->err_code = CO_ER_SSL_EMPTY;
2115 }
2116 else {
2117 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
2118 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
2119 else
2120 conn->err_code = CO_ER_SSL_ABORT;
2121 }
2122 }
2123 else {
2124 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
2125 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
Willy Tarreau20879a02012-12-03 16:32:10 +01002126 else
Emeric Brun29f037d2014-04-25 19:05:36 +02002127 conn->err_code = CO_ER_SSL_HANDSHAKE;
2128 }
Willy Tarreau20879a02012-12-03 16:32:10 +01002129 }
Emeric Brun674b7432012-11-08 19:21:55 +01002130 goto out_error;
2131 }
2132 else {
2133 /* Fail on all other handshake errors */
2134 /* Note: OpenSSL may leave unread bytes in the socket's
2135 * buffer, causing an RST to be emitted upon close() on
2136 * TCP sockets. We first try to drain possibly pending
2137 * data to avoid this as much as possible.
2138 */
Willy Tarreau46be2e52014-01-20 12:10:52 +01002139 conn_drain(conn);
Willy Tarreau20879a02012-12-03 16:32:10 +01002140 if (!conn->err_code)
Willy Tarreauf51c6982014-04-25 20:02:39 +02002141 conn->err_code = (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT) ?
2142 CO_ER_SSL_KILLED_HB : CO_ER_SSL_HANDSHAKE;
Emeric Brun674b7432012-11-08 19:21:55 +01002143 goto out_error;
2144 }
2145 }
2146 /* read some data: consider handshake completed */
2147 goto reneg_ok;
2148 }
2149
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02002150 ret = SSL_do_handshake(conn->xprt_ctx);
Emeric Brun46591952012-05-18 15:47:34 +02002151 if (ret != 1) {
2152 /* handshake did not complete, let's find why */
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02002153 ret = SSL_get_error(conn->xprt_ctx, ret);
Emeric Brun46591952012-05-18 15:47:34 +02002154
2155 if (ret == SSL_ERROR_WANT_WRITE) {
2156 /* SSL handshake needs to write, L4 connection may not be ready */
2157 __conn_sock_stop_recv(conn);
Willy Tarreaue1f50c42014-01-22 20:02:06 +01002158 __conn_sock_want_send(conn);
2159 fd_cant_send(conn->t.sock.fd);
Emeric Brun46591952012-05-18 15:47:34 +02002160 return 0;
2161 }
2162 else if (ret == SSL_ERROR_WANT_READ) {
2163 /* SSL handshake needs to read, L4 connection is ready */
2164 if (conn->flags & CO_FL_WAIT_L4_CONN)
2165 conn->flags &= ~CO_FL_WAIT_L4_CONN;
2166 __conn_sock_stop_send(conn);
Willy Tarreaue1f50c42014-01-22 20:02:06 +01002167 __conn_sock_want_recv(conn);
2168 fd_cant_recv(conn->t.sock.fd);
Emeric Brun46591952012-05-18 15:47:34 +02002169 return 0;
2170 }
Willy Tarreau89230192012-09-28 20:22:13 +02002171 else if (ret == SSL_ERROR_SYSCALL) {
2172 /* if errno is null, then connection was successfully established */
2173 if (!errno && conn->flags & CO_FL_WAIT_L4_CONN)
2174 conn->flags &= ~CO_FL_WAIT_L4_CONN;
Willy Tarreau20879a02012-12-03 16:32:10 +01002175
Emeric Brun29f037d2014-04-25 19:05:36 +02002176 if (!((SSL *)conn->xprt_ctx)->packet_length) {
2177 if (!errno) {
2178 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
2179 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
2180 else
2181 conn->err_code = CO_ER_SSL_EMPTY;
2182 }
2183 else {
2184 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
2185 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
2186 else
2187 conn->err_code = CO_ER_SSL_ABORT;
2188 }
2189 }
2190 else {
2191 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
2192 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
Willy Tarreau20879a02012-12-03 16:32:10 +01002193 else
Emeric Brun29f037d2014-04-25 19:05:36 +02002194 conn->err_code = CO_ER_SSL_HANDSHAKE;
2195 }
Willy Tarreau89230192012-09-28 20:22:13 +02002196 goto out_error;
2197 }
Emeric Brun46591952012-05-18 15:47:34 +02002198 else {
2199 /* Fail on all other handshake errors */
Willy Tarreau566dc552012-10-19 20:52:18 +02002200 /* Note: OpenSSL may leave unread bytes in the socket's
2201 * buffer, causing an RST to be emitted upon close() on
2202 * TCP sockets. We first try to drain possibly pending
2203 * data to avoid this as much as possible.
2204 */
Willy Tarreau46be2e52014-01-20 12:10:52 +01002205 conn_drain(conn);
Willy Tarreau20879a02012-12-03 16:32:10 +01002206 if (!conn->err_code)
Willy Tarreauf51c6982014-04-25 20:02:39 +02002207 conn->err_code = (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT) ?
2208 CO_ER_SSL_KILLED_HB : CO_ER_SSL_HANDSHAKE;
Emeric Brun46591952012-05-18 15:47:34 +02002209 goto out_error;
2210 }
2211 }
2212
Emeric Brun674b7432012-11-08 19:21:55 +01002213reneg_ok:
2214
Emeric Brun46591952012-05-18 15:47:34 +02002215 /* Handshake succeeded */
Willy Tarreau0c9c2722014-05-28 12:28:58 +02002216 if (!SSL_session_reused(conn->xprt_ctx)) {
2217 if (objt_server(conn->target)) {
2218 update_freq_ctr(&global.ssl_be_keys_per_sec, 1);
2219 if (global.ssl_be_keys_per_sec.curr_ctr > global.ssl_be_keys_max)
2220 global.ssl_be_keys_max = global.ssl_be_keys_per_sec.curr_ctr;
2221
Emeric Brun46591952012-05-18 15:47:34 +02002222 /* check if session was reused, if not store current session on server for reuse */
Willy Tarreau3fdb3662012-11-12 00:42:33 +01002223 if (objt_server(conn->target)->ssl_ctx.reused_sess)
2224 SSL_SESSION_free(objt_server(conn->target)->ssl_ctx.reused_sess);
Emeric Brun46591952012-05-18 15:47:34 +02002225
Willy Tarreau3fdb3662012-11-12 00:42:33 +01002226 objt_server(conn->target)->ssl_ctx.reused_sess = SSL_get1_session(conn->xprt_ctx);
Emeric Brun46591952012-05-18 15:47:34 +02002227 }
Willy Tarreau0c9c2722014-05-28 12:28:58 +02002228 else {
2229 update_freq_ctr(&global.ssl_fe_keys_per_sec, 1);
2230 if (global.ssl_fe_keys_per_sec.curr_ctr > global.ssl_fe_keys_max)
2231 global.ssl_fe_keys_max = global.ssl_fe_keys_per_sec.curr_ctr;
2232 }
Emeric Brun46591952012-05-18 15:47:34 +02002233 }
2234
2235 /* The connection is now established at both layers, it's time to leave */
2236 conn->flags &= ~(flag | CO_FL_WAIT_L4_CONN | CO_FL_WAIT_L6_CONN);
2237 return 1;
2238
2239 out_error:
Emeric Brun644cde02012-12-14 11:21:13 +01002240 /* Clear openssl global errors stack */
2241 ERR_clear_error();
2242
Emeric Brun9fa89732012-10-04 17:09:56 +02002243 /* free resumed session if exists */
Willy Tarreau3fdb3662012-11-12 00:42:33 +01002244 if (objt_server(conn->target) && objt_server(conn->target)->ssl_ctx.reused_sess) {
2245 SSL_SESSION_free(objt_server(conn->target)->ssl_ctx.reused_sess);
2246 objt_server(conn->target)->ssl_ctx.reused_sess = NULL;
Emeric Brun9fa89732012-10-04 17:09:56 +02002247 }
2248
Emeric Brun46591952012-05-18 15:47:34 +02002249 /* Fail on all other handshake errors */
2250 conn->flags |= CO_FL_ERROR;
Willy Tarreau20879a02012-12-03 16:32:10 +01002251 if (!conn->err_code)
2252 conn->err_code = CO_ER_SSL_HANDSHAKE;
Emeric Brun46591952012-05-18 15:47:34 +02002253 return 0;
2254}
2255
2256/* Receive up to <count> bytes from connection <conn>'s socket and store them
Willy Tarreauabf08d92014-01-14 11:31:27 +01002257 * into buffer <buf>. Only one call to recv() is performed, unless the
Emeric Brun46591952012-05-18 15:47:34 +02002258 * buffer wraps, in which case a second call may be performed. The connection's
2259 * flags are updated with whatever special event is detected (error, read0,
2260 * empty). The caller is responsible for taking care of those events and
2261 * avoiding the call if inappropriate. The function does not call the
2262 * connection's polling update function, so the caller is responsible for this.
2263 */
2264static int ssl_sock_to_buf(struct connection *conn, struct buffer *buf, int count)
2265{
2266 int ret, done = 0;
Willy Tarreauabf08d92014-01-14 11:31:27 +01002267 int try;
Emeric Brun46591952012-05-18 15:47:34 +02002268
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02002269 if (!conn->xprt_ctx)
Emeric Brun46591952012-05-18 15:47:34 +02002270 goto out_error;
2271
2272 if (conn->flags & CO_FL_HANDSHAKE)
2273 /* a handshake was requested */
2274 return 0;
2275
Willy Tarreauabf08d92014-01-14 11:31:27 +01002276 /* let's realign the buffer to optimize I/O */
2277 if (buffer_empty(buf))
Emeric Brun46591952012-05-18 15:47:34 +02002278 buf->p = buf->data;
Emeric Brun46591952012-05-18 15:47:34 +02002279
2280 /* read the largest possible block. For this, we perform only one call
2281 * to recv() unless the buffer wraps and we exactly fill the first hunk,
2282 * in which case we accept to do it once again. A new attempt is made on
2283 * EINTR too.
2284 */
Willy Tarreau00b0fb92014-01-17 11:09:40 +01002285 while (count > 0) {
Willy Tarreauabf08d92014-01-14 11:31:27 +01002286 /* first check if we have some room after p+i */
2287 try = buf->data + buf->size - (buf->p + buf->i);
2288 /* otherwise continue between data and p-o */
2289 if (try <= 0) {
2290 try = buf->p - (buf->data + buf->o);
2291 if (try <= 0)
2292 break;
2293 }
2294 if (try > count)
2295 try = count;
2296
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02002297 ret = SSL_read(conn->xprt_ctx, bi_end(buf), try);
Emeric Brune1f38db2012-09-03 20:36:47 +02002298 if (conn->flags & CO_FL_ERROR) {
2299 /* CO_FL_ERROR may be set by ssl_sock_infocbk */
Emeric Brun644cde02012-12-14 11:21:13 +01002300 goto out_error;
Emeric Brune1f38db2012-09-03 20:36:47 +02002301 }
Emeric Brun46591952012-05-18 15:47:34 +02002302 if (ret > 0) {
2303 buf->i += ret;
2304 done += ret;
2305 if (ret < try)
2306 break;
2307 count -= ret;
Emeric Brun46591952012-05-18 15:47:34 +02002308 }
2309 else if (ret == 0) {
Emeric Brun644cde02012-12-14 11:21:13 +01002310 ret = SSL_get_error(conn->xprt_ctx, ret);
2311 if (ret != SSL_ERROR_ZERO_RETURN) {
Emeric Brun1c646862012-12-14 12:33:41 +01002312 /* error on protocol or underlying transport */
2313 if ((ret != SSL_ERROR_SYSCALL)
2314 || (errno && (errno != EAGAIN)))
2315 conn->flags |= CO_FL_ERROR;
2316
Emeric Brun644cde02012-12-14 11:21:13 +01002317 /* Clear openssl global errors stack */
2318 ERR_clear_error();
2319 }
Emeric Brun46591952012-05-18 15:47:34 +02002320 goto read0;
2321 }
2322 else {
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02002323 ret = SSL_get_error(conn->xprt_ctx, ret);
Emeric Brun46591952012-05-18 15:47:34 +02002324 if (ret == SSL_ERROR_WANT_WRITE) {
Emeric Brun8af8dd12012-11-08 17:56:20 +01002325 /* handshake is running, and it needs to enable write */
Emeric Brun46591952012-05-18 15:47:34 +02002326 conn->flags |= CO_FL_SSL_WAIT_HS;
Emeric Brun8af8dd12012-11-08 17:56:20 +01002327 __conn_sock_want_send(conn);
Emeric Brun46591952012-05-18 15:47:34 +02002328 break;
2329 }
2330 else if (ret == SSL_ERROR_WANT_READ) {
Emeric Brun282a76a2012-11-08 18:02:56 +01002331 if (SSL_renegotiate_pending(conn->xprt_ctx)) {
2332 /* handshake is running, and it may need to re-enable read */
2333 conn->flags |= CO_FL_SSL_WAIT_HS;
2334 __conn_sock_want_recv(conn);
2335 break;
2336 }
Emeric Brun46591952012-05-18 15:47:34 +02002337 /* we need to poll for retry a read later */
Willy Tarreaue1f50c42014-01-22 20:02:06 +01002338 fd_cant_recv(conn->t.sock.fd);
Emeric Brun46591952012-05-18 15:47:34 +02002339 break;
2340 }
2341 /* otherwise it's a real error */
2342 goto out_error;
2343 }
2344 }
2345 return done;
2346
2347 read0:
2348 conn_sock_read0(conn);
2349 return done;
2350 out_error:
Emeric Brun644cde02012-12-14 11:21:13 +01002351 /* Clear openssl global errors stack */
2352 ERR_clear_error();
2353
Emeric Brun46591952012-05-18 15:47:34 +02002354 conn->flags |= CO_FL_ERROR;
2355 return done;
2356}
2357
2358
2359/* Send all pending bytes from buffer <buf> to connection <conn>'s socket.
Willy Tarreau1049b1f2014-02-02 01:51:17 +01002360 * <flags> may contain some CO_SFL_* flags to hint the system about other
2361 * pending data for example, but this flag is ignored at the moment.
Emeric Brun46591952012-05-18 15:47:34 +02002362 * Only one call to send() is performed, unless the buffer wraps, in which case
2363 * a second call may be performed. The connection's flags are updated with
2364 * whatever special event is detected (error, empty). The caller is responsible
2365 * for taking care of those events and avoiding the call if inappropriate. The
2366 * function does not call the connection's polling update function, so the caller
2367 * is responsible for this.
2368 */
2369static int ssl_sock_from_buf(struct connection *conn, struct buffer *buf, int flags)
2370{
2371 int ret, try, done;
2372
2373 done = 0;
2374
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02002375 if (!conn->xprt_ctx)
Emeric Brun46591952012-05-18 15:47:34 +02002376 goto out_error;
2377
2378 if (conn->flags & CO_FL_HANDSHAKE)
2379 /* a handshake was requested */
2380 return 0;
2381
2382 /* send the largest possible block. For this we perform only one call
2383 * to send() unless the buffer wraps and we exactly fill the first hunk,
2384 * in which case we accept to do it once again.
2385 */
2386 while (buf->o) {
Kevin Hestercad82342013-05-30 15:12:41 -07002387 try = bo_contig_data(buf);
Willy Tarreaubfd59462013-02-21 07:46:09 +01002388
Willy Tarreau7bed9452014-02-02 02:00:24 +01002389 if (!(flags & CO_SFL_STREAMER) &&
Willy Tarreau518cedd2014-02-17 15:43:01 +01002390 !(conn->xprt_st & SSL_SOCK_SEND_UNLIMITED) &&
2391 global.tune.ssl_max_record && try > global.tune.ssl_max_record) {
Willy Tarreaubfd59462013-02-21 07:46:09 +01002392 try = global.tune.ssl_max_record;
Willy Tarreau518cedd2014-02-17 15:43:01 +01002393 }
2394 else {
2395 /* we need to keep the information about the fact that
2396 * we're not limiting the upcoming send(), because if it
2397 * fails, we'll have to retry with at least as many data.
2398 */
2399 conn->xprt_st |= SSL_SOCK_SEND_UNLIMITED;
2400 }
Willy Tarreaubfd59462013-02-21 07:46:09 +01002401
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02002402 ret = SSL_write(conn->xprt_ctx, bo_ptr(buf), try);
Willy Tarreau518cedd2014-02-17 15:43:01 +01002403
Emeric Brune1f38db2012-09-03 20:36:47 +02002404 if (conn->flags & CO_FL_ERROR) {
2405 /* CO_FL_ERROR may be set by ssl_sock_infocbk */
Emeric Brun644cde02012-12-14 11:21:13 +01002406 goto out_error;
Emeric Brune1f38db2012-09-03 20:36:47 +02002407 }
Emeric Brun46591952012-05-18 15:47:34 +02002408 if (ret > 0) {
Willy Tarreau518cedd2014-02-17 15:43:01 +01002409 conn->xprt_st &= ~SSL_SOCK_SEND_UNLIMITED;
2410
Emeric Brun46591952012-05-18 15:47:34 +02002411 buf->o -= ret;
2412 done += ret;
2413
Willy Tarreau5fb38032012-12-16 19:39:09 +01002414 if (likely(buffer_empty(buf)))
Emeric Brun46591952012-05-18 15:47:34 +02002415 /* optimize data alignment in the buffer */
2416 buf->p = buf->data;
2417
2418 /* if the system buffer is full, don't insist */
2419 if (ret < try)
2420 break;
2421 }
2422 else {
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02002423 ret = SSL_get_error(conn->xprt_ctx, ret);
Emeric Brun46591952012-05-18 15:47:34 +02002424 if (ret == SSL_ERROR_WANT_WRITE) {
Emeric Brun282a76a2012-11-08 18:02:56 +01002425 if (SSL_renegotiate_pending(conn->xprt_ctx)) {
2426 /* handshake is running, and it may need to re-enable write */
2427 conn->flags |= CO_FL_SSL_WAIT_HS;
2428 __conn_sock_want_send(conn);
2429 break;
2430 }
Emeric Brun46591952012-05-18 15:47:34 +02002431 /* we need to poll to retry a write later */
Willy Tarreaue1f50c42014-01-22 20:02:06 +01002432 fd_cant_send(conn->t.sock.fd);
Emeric Brun46591952012-05-18 15:47:34 +02002433 break;
2434 }
2435 else if (ret == SSL_ERROR_WANT_READ) {
Emeric Brun8af8dd12012-11-08 17:56:20 +01002436 /* handshake is running, and it needs to enable read */
Emeric Brun46591952012-05-18 15:47:34 +02002437 conn->flags |= CO_FL_SSL_WAIT_HS;
Emeric Brun8af8dd12012-11-08 17:56:20 +01002438 __conn_sock_want_recv(conn);
Emeric Brun46591952012-05-18 15:47:34 +02002439 break;
2440 }
2441 goto out_error;
2442 }
2443 }
2444 return done;
2445
2446 out_error:
Emeric Brun644cde02012-12-14 11:21:13 +01002447 /* Clear openssl global errors stack */
2448 ERR_clear_error();
2449
Emeric Brun46591952012-05-18 15:47:34 +02002450 conn->flags |= CO_FL_ERROR;
2451 return done;
2452}
2453
Emeric Brun46591952012-05-18 15:47:34 +02002454static void ssl_sock_close(struct connection *conn) {
2455
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02002456 if (conn->xprt_ctx) {
2457 SSL_free(conn->xprt_ctx);
2458 conn->xprt_ctx = NULL;
Willy Tarreau403edff2012-09-06 11:58:37 +02002459 sslconns--;
Emeric Brun46591952012-05-18 15:47:34 +02002460 }
Emeric Brun46591952012-05-18 15:47:34 +02002461}
2462
2463/* This function tries to perform a clean shutdown on an SSL connection, and in
2464 * any case, flags the connection as reusable if no handshake was in progress.
2465 */
2466static void ssl_sock_shutw(struct connection *conn, int clean)
2467{
2468 if (conn->flags & CO_FL_HANDSHAKE)
2469 return;
2470 /* no handshake was in progress, try a clean ssl shutdown */
Emeric Brun644cde02012-12-14 11:21:13 +01002471 if (clean && (SSL_shutdown(conn->xprt_ctx) <= 0)) {
2472 /* Clear openssl global errors stack */
2473 ERR_clear_error();
2474 }
Emeric Brun46591952012-05-18 15:47:34 +02002475
2476 /* force flag on ssl to keep session in cache regardless shutdown result */
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02002477 SSL_set_shutdown(conn->xprt_ctx, SSL_SENT_SHUTDOWN);
Emeric Brun46591952012-05-18 15:47:34 +02002478}
2479
Willy Tarreauffc3fcd2012-10-12 20:17:54 +02002480/* used for logging, may be changed for a sample fetch later */
2481const char *ssl_sock_get_cipher_name(struct connection *conn)
2482{
2483 if (!conn->xprt && !conn->xprt_ctx)
2484 return NULL;
2485 return SSL_get_cipher_name(conn->xprt_ctx);
2486}
2487
2488/* used for logging, may be changed for a sample fetch later */
2489const char *ssl_sock_get_proto_version(struct connection *conn)
2490{
2491 if (!conn->xprt && !conn->xprt_ctx)
2492 return NULL;
2493 return SSL_get_version(conn->xprt_ctx);
2494}
2495
Willy Tarreau8d598402012-10-22 17:58:39 +02002496/* Extract a serial from a cert, and copy it to a chunk.
2497 * Returns 1 if serial is found and copied, 0 if no serial found and
2498 * -1 if output is not large enough.
2499 */
2500static int
2501ssl_sock_get_serial(X509 *crt, struct chunk *out)
2502{
2503 ASN1_INTEGER *serial;
2504
2505 serial = X509_get_serialNumber(crt);
2506 if (!serial)
2507 return 0;
2508
2509 if (out->size < serial->length)
2510 return -1;
2511
2512 memcpy(out->str, serial->data, serial->length);
2513 out->len = serial->length;
2514 return 1;
2515}
2516
Emeric Brunb3cc4252014-10-29 19:03:26 +01002517/* Extract a cert to der, and copy it to a chunk.
2518 * Returns 1 if cert is found and copied, 0 on der convertion failure and
2519 * -1 if output is not large enough.
2520 */
2521static int
2522ssl_sock_crt2der(X509 *crt, struct chunk *out)
2523{
2524 int len;
2525 unsigned char *p = (unsigned char *)out->str;;
2526
2527 len =i2d_X509(crt, NULL);
2528 if (len <= 0)
2529 return 1;
2530
2531 if (out->size < len)
2532 return -1;
2533
2534 i2d_X509(crt,&p);
2535 out->len = len;
2536 return 1;
2537}
2538
Emeric Brunce5ad802012-10-22 14:11:22 +02002539
2540/* Copy Date in ASN1_UTCTIME format in struct chunk out.
2541 * Returns 1 if serial is found and copied, 0 if no valid time found
2542 * and -1 if output is not large enough.
2543 */
2544static int
2545ssl_sock_get_time(ASN1_TIME *tm, struct chunk *out)
2546{
2547 if (tm->type == V_ASN1_GENERALIZEDTIME) {
2548 ASN1_GENERALIZEDTIME *gentm = (ASN1_GENERALIZEDTIME *)tm;
2549
2550 if (gentm->length < 12)
2551 return 0;
2552 if (gentm->data[0] != 0x32 || gentm->data[1] != 0x30)
2553 return 0;
2554 if (out->size < gentm->length-2)
2555 return -1;
2556
2557 memcpy(out->str, gentm->data+2, gentm->length-2);
2558 out->len = gentm->length-2;
2559 return 1;
2560 }
2561 else if (tm->type == V_ASN1_UTCTIME) {
2562 ASN1_UTCTIME *utctm = (ASN1_UTCTIME *)tm;
2563
2564 if (utctm->length < 10)
2565 return 0;
2566 if (utctm->data[0] >= 0x35)
2567 return 0;
2568 if (out->size < utctm->length)
2569 return -1;
2570
2571 memcpy(out->str, utctm->data, utctm->length);
2572 out->len = utctm->length;
2573 return 1;
2574 }
2575
2576 return 0;
2577}
2578
Emeric Brun87855892012-10-17 17:39:35 +02002579/* Extract an entry from a X509_NAME and copy its value to an output chunk.
2580 * Returns 1 if entry found, 0 if entry not found, or -1 if output not large enough.
2581 */
2582static int
2583ssl_sock_get_dn_entry(X509_NAME *a, const struct chunk *entry, int pos, struct chunk *out)
2584{
2585 X509_NAME_ENTRY *ne;
2586 int i, j, n;
2587 int cur = 0;
2588 const char *s;
2589 char tmp[128];
2590
2591 out->len = 0;
2592 for (i = 0; i < sk_X509_NAME_ENTRY_num(a->entries); i++) {
2593 if (pos < 0)
2594 j = (sk_X509_NAME_ENTRY_num(a->entries)-1) - i;
2595 else
2596 j = i;
2597
2598 ne = sk_X509_NAME_ENTRY_value(a->entries, j);
2599 n = OBJ_obj2nid(ne->object);
2600 if ((n == NID_undef) || ((s = OBJ_nid2sn(n)) == NULL)) {
2601 i2t_ASN1_OBJECT(tmp, sizeof(tmp), ne->object);
2602 s = tmp;
2603 }
2604
2605 if (chunk_strcasecmp(entry, s) != 0)
2606 continue;
2607
2608 if (pos < 0)
2609 cur--;
2610 else
2611 cur++;
2612
2613 if (cur != pos)
2614 continue;
2615
2616 if (ne->value->length > out->size)
2617 return -1;
2618
2619 memcpy(out->str, ne->value->data, ne->value->length);
2620 out->len = ne->value->length;
2621 return 1;
2622 }
2623
2624 return 0;
2625
2626}
2627
2628/* Extract and format full DN from a X509_NAME and copy result into a chunk
2629 * Returns 1 if dn entries exits, 0 if no dn entry found or -1 if output is not large enough.
2630 */
2631static int
2632ssl_sock_get_dn_oneline(X509_NAME *a, struct chunk *out)
2633{
2634 X509_NAME_ENTRY *ne;
2635 int i, n, ln;
2636 int l = 0;
2637 const char *s;
2638 char *p;
2639 char tmp[128];
2640
2641 out->len = 0;
2642 p = out->str;
2643 for (i = 0; i < sk_X509_NAME_ENTRY_num(a->entries); i++) {
2644 ne = sk_X509_NAME_ENTRY_value(a->entries, i);
2645 n = OBJ_obj2nid(ne->object);
2646 if ((n == NID_undef) || ((s = OBJ_nid2sn(n)) == NULL)) {
2647 i2t_ASN1_OBJECT(tmp, sizeof(tmp), ne->object);
2648 s = tmp;
2649 }
2650 ln = strlen(s);
2651
2652 l += 1 + ln + 1 + ne->value->length;
2653 if (l > out->size)
2654 return -1;
2655 out->len = l;
2656
2657 *(p++)='/';
2658 memcpy(p, s, ln);
2659 p += ln;
2660 *(p++)='=';
2661 memcpy(p, ne->value->data, ne->value->length);
2662 p += ne->value->length;
2663 }
2664
2665 if (!out->len)
2666 return 0;
2667
2668 return 1;
2669}
2670
David Safb76832014-05-08 23:42:08 -04002671char *ssl_sock_get_version(struct connection *conn)
2672{
2673 if (!ssl_sock_is_ssl(conn))
2674 return NULL;
2675
2676 return (char *)SSL_get_version(conn->xprt_ctx);
2677}
2678
Emeric Brun49100982014-06-24 18:26:41 +02002679/* Extract peer certificate's common name into the chunk dest
2680 * Returns
2681 * the len of the extracted common name
2682 * or 0 if no CN found in DN
2683 * or -1 on error case (i.e. no peer certificate)
2684 */
2685int ssl_sock_get_remote_common_name(struct connection *conn, struct chunk *dest)
David Safb76832014-05-08 23:42:08 -04002686{
2687 X509 *crt = NULL;
2688 X509_NAME *name;
David Safb76832014-05-08 23:42:08 -04002689 const char find_cn[] = "CN";
2690 const struct chunk find_cn_chunk = {
2691 .str = (char *)&find_cn,
2692 .len = sizeof(find_cn)-1
2693 };
Emeric Brun49100982014-06-24 18:26:41 +02002694 int result = -1;
David Safb76832014-05-08 23:42:08 -04002695
2696 if (!ssl_sock_is_ssl(conn))
Emeric Brun49100982014-06-24 18:26:41 +02002697 goto out;
David Safb76832014-05-08 23:42:08 -04002698
2699 /* SSL_get_peer_certificate, it increase X509 * ref count */
2700 crt = SSL_get_peer_certificate(conn->xprt_ctx);
2701 if (!crt)
2702 goto out;
2703
2704 name = X509_get_subject_name(crt);
2705 if (!name)
2706 goto out;
David Safb76832014-05-08 23:42:08 -04002707
Emeric Brun49100982014-06-24 18:26:41 +02002708 result = ssl_sock_get_dn_entry(name, &find_cn_chunk, 1, dest);
2709out:
David Safb76832014-05-08 23:42:08 -04002710 if (crt)
2711 X509_free(crt);
2712
2713 return result;
2714}
2715
Dave McCowand6ec6052014-07-30 10:39:13 -04002716/* returns 1 if client passed a certificate for this session, 0 if not */
2717int ssl_sock_get_cert_used_sess(struct connection *conn)
2718{
2719 X509 *crt = NULL;
2720
2721 if (!ssl_sock_is_ssl(conn))
2722 return 0;
2723
2724 /* SSL_get_peer_certificate, it increase X509 * ref count */
2725 crt = SSL_get_peer_certificate(conn->xprt_ctx);
2726 if (!crt)
2727 return 0;
2728
2729 X509_free(crt);
2730 return 1;
2731}
2732
2733/* returns 1 if client passed a certificate for this connection, 0 if not */
2734int ssl_sock_get_cert_used_conn(struct connection *conn)
David Safb76832014-05-08 23:42:08 -04002735{
2736 if (!ssl_sock_is_ssl(conn))
2737 return 0;
2738
2739 return SSL_SOCK_ST_FL_VERIFY_DONE & conn->xprt_st ? 1 : 0;
2740}
2741
2742/* returns result from SSL verify */
2743unsigned int ssl_sock_get_verify_result(struct connection *conn)
2744{
2745 if (!ssl_sock_is_ssl(conn))
2746 return (unsigned int)X509_V_ERR_APPLICATION_VERIFICATION;
2747
2748 return (unsigned int)SSL_get_verify_result(conn->xprt_ctx);
2749}
2750
Willy Tarreau7875d092012-09-10 08:20:03 +02002751/***** Below are some sample fetching functions for ACL/patterns *****/
2752
Emeric Brune64aef12012-09-21 13:15:06 +02002753/* boolean, returns true if client cert was present */
2754static int
Emeric Brun2525b6b2012-10-18 15:59:43 +02002755smp_fetch_ssl_fc_has_crt(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002756 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brune64aef12012-09-21 13:15:06 +02002757{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002758 struct connection *conn;
2759
2760 if (!l4)
2761 return 0;
2762
2763 conn = objt_conn(l4->si[0].end);
2764 if (!conn || conn->xprt != &ssl_sock)
Emeric Brune64aef12012-09-21 13:15:06 +02002765 return 0;
2766
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002767 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brune64aef12012-09-21 13:15:06 +02002768 smp->flags |= SMP_F_MAY_CHANGE;
2769 return 0;
2770 }
2771
2772 smp->flags = 0;
2773 smp->type = SMP_T_BOOL;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002774 smp->data.uint = SSL_SOCK_ST_FL_VERIFY_DONE & conn->xprt_st ? 1 : 0;
Emeric Brune64aef12012-09-21 13:15:06 +02002775
2776 return 1;
2777}
2778
Emeric Brunb3cc4252014-10-29 19:03:26 +01002779/* binary, returns a certificate in a binary chunk (der/raw).
2780 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
2781 * should be use.
2782 */
2783static int
2784smp_fetch_ssl_x_der(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
2785 const struct arg *args, struct sample *smp, const char *kw)
2786{
2787 int cert_peer = (kw[4] == 'c') ? 1 : 0;
2788 X509 *crt = NULL;
2789 int ret = 0;
2790 struct chunk *smp_trash;
2791 struct connection *conn;
2792
2793 if (!l4)
2794 return 0;
2795
2796 conn = objt_conn(l4->si[0].end);
2797 if (!conn || conn->xprt != &ssl_sock)
2798 return 0;
2799
2800 if (!(conn->flags & CO_FL_CONNECTED)) {
2801 smp->flags |= SMP_F_MAY_CHANGE;
2802 return 0;
2803 }
2804
2805 if (cert_peer)
2806 crt = SSL_get_peer_certificate(conn->xprt_ctx);
2807 else
2808 crt = SSL_get_certificate(conn->xprt_ctx);
2809
2810 if (!crt)
2811 goto out;
2812
2813 smp_trash = get_trash_chunk();
2814 if (ssl_sock_crt2der(crt, smp_trash) <= 0)
2815 goto out;
2816
2817 smp->data.str = *smp_trash;
2818 smp->type = SMP_T_BIN;
2819 ret = 1;
2820out:
2821 /* SSL_get_peer_certificate, it increase X509 * ref count */
2822 if (cert_peer && crt)
2823 X509_free(crt);
2824 return ret;
2825}
2826
Emeric Brunba841a12014-04-30 17:05:08 +02002827/* binary, returns serial of certificate in a binary chunk.
2828 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
2829 * should be use.
2830 */
Willy Tarreau8d598402012-10-22 17:58:39 +02002831static int
Emeric Brunba841a12014-04-30 17:05:08 +02002832smp_fetch_ssl_x_serial(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002833 const struct arg *args, struct sample *smp, const char *kw)
Willy Tarreau8d598402012-10-22 17:58:39 +02002834{
Emeric Brunba841a12014-04-30 17:05:08 +02002835 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Willy Tarreau8d598402012-10-22 17:58:39 +02002836 X509 *crt = NULL;
2837 int ret = 0;
2838 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002839 struct connection *conn;
2840
2841 if (!l4)
2842 return 0;
Willy Tarreau8d598402012-10-22 17:58:39 +02002843
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002844 conn = objt_conn(l4->si[0].end);
2845 if (!conn || conn->xprt != &ssl_sock)
Willy Tarreau8d598402012-10-22 17:58:39 +02002846 return 0;
2847
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002848 if (!(conn->flags & CO_FL_CONNECTED)) {
Willy Tarreau8d598402012-10-22 17:58:39 +02002849 smp->flags |= SMP_F_MAY_CHANGE;
2850 return 0;
2851 }
2852
Emeric Brunba841a12014-04-30 17:05:08 +02002853 if (cert_peer)
2854 crt = SSL_get_peer_certificate(conn->xprt_ctx);
2855 else
2856 crt = SSL_get_certificate(conn->xprt_ctx);
2857
Willy Tarreau8d598402012-10-22 17:58:39 +02002858 if (!crt)
2859 goto out;
2860
Willy Tarreau47ca5452012-12-23 20:22:19 +01002861 smp_trash = get_trash_chunk();
Willy Tarreau8d598402012-10-22 17:58:39 +02002862 if (ssl_sock_get_serial(crt, smp_trash) <= 0)
2863 goto out;
2864
2865 smp->data.str = *smp_trash;
2866 smp->type = SMP_T_BIN;
2867 ret = 1;
2868out:
Emeric Brunba841a12014-04-30 17:05:08 +02002869 /* SSL_get_peer_certificate, it increase X509 * ref count */
2870 if (cert_peer && crt)
Willy Tarreau8d598402012-10-22 17:58:39 +02002871 X509_free(crt);
2872 return ret;
2873}
Emeric Brune64aef12012-09-21 13:15:06 +02002874
Emeric Brunba841a12014-04-30 17:05:08 +02002875/* binary, returns the client certificate's SHA-1 fingerprint (SHA-1 hash of DER-encoded certificate) in a binary chunk.
2876 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
2877 * should be use.
2878 */
James Votha051b4a2013-05-14 20:37:59 +02002879static int
Emeric Brunba841a12014-04-30 17:05:08 +02002880smp_fetch_ssl_x_sha1(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002881 const struct arg *args, struct sample *smp, const char *kw)
James Votha051b4a2013-05-14 20:37:59 +02002882{
Emeric Brunba841a12014-04-30 17:05:08 +02002883 int cert_peer = (kw[4] == 'c') ? 1 : 0;
James Votha051b4a2013-05-14 20:37:59 +02002884 X509 *crt = NULL;
2885 const EVP_MD *digest;
2886 int ret = 0;
2887 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002888 struct connection *conn;
James Votha051b4a2013-05-14 20:37:59 +02002889
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002890 if (!l4)
James Votha051b4a2013-05-14 20:37:59 +02002891 return 0;
2892
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002893 conn = objt_conn(l4->si[0].end);
2894 if (!conn || conn->xprt != &ssl_sock)
2895 return 0;
2896
2897 if (!(conn->flags & CO_FL_CONNECTED)) {
James Votha051b4a2013-05-14 20:37:59 +02002898 smp->flags |= SMP_F_MAY_CHANGE;
2899 return 0;
2900 }
2901
Emeric Brunba841a12014-04-30 17:05:08 +02002902 if (cert_peer)
2903 crt = SSL_get_peer_certificate(conn->xprt_ctx);
2904 else
2905 crt = SSL_get_certificate(conn->xprt_ctx);
James Votha051b4a2013-05-14 20:37:59 +02002906 if (!crt)
2907 goto out;
2908
2909 smp_trash = get_trash_chunk();
2910 digest = EVP_sha1();
2911 X509_digest(crt, digest, (unsigned char *)smp_trash->str, (unsigned int *)&smp_trash->len);
2912
2913 smp->data.str = *smp_trash;
2914 smp->type = SMP_T_BIN;
2915 ret = 1;
2916out:
Emeric Brunba841a12014-04-30 17:05:08 +02002917 /* SSL_get_peer_certificate, it increase X509 * ref count */
2918 if (cert_peer && crt)
James Votha051b4a2013-05-14 20:37:59 +02002919 X509_free(crt);
2920 return ret;
2921}
2922
Emeric Brunba841a12014-04-30 17:05:08 +02002923/* string, returns certificate's notafter date in ASN1_UTCTIME format.
2924 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
2925 * should be use.
2926 */
Emeric Brunce5ad802012-10-22 14:11:22 +02002927static int
Emeric Brunba841a12014-04-30 17:05:08 +02002928smp_fetch_ssl_x_notafter(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002929 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brunce5ad802012-10-22 14:11:22 +02002930{
Emeric Brunba841a12014-04-30 17:05:08 +02002931 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brunce5ad802012-10-22 14:11:22 +02002932 X509 *crt = NULL;
2933 int ret = 0;
2934 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002935 struct connection *conn;
Emeric Brunce5ad802012-10-22 14:11:22 +02002936
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002937 if (!l4)
Emeric Brunce5ad802012-10-22 14:11:22 +02002938 return 0;
2939
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002940 conn = objt_conn(l4->si[0].end);
2941 if (!conn || conn->xprt != &ssl_sock)
2942 return 0;
2943
2944 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunce5ad802012-10-22 14:11:22 +02002945 smp->flags |= SMP_F_MAY_CHANGE;
2946 return 0;
2947 }
2948
Emeric Brunba841a12014-04-30 17:05:08 +02002949 if (cert_peer)
2950 crt = SSL_get_peer_certificate(conn->xprt_ctx);
2951 else
2952 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brunce5ad802012-10-22 14:11:22 +02002953 if (!crt)
2954 goto out;
2955
Willy Tarreau47ca5452012-12-23 20:22:19 +01002956 smp_trash = get_trash_chunk();
Emeric Brunce5ad802012-10-22 14:11:22 +02002957 if (ssl_sock_get_time(X509_get_notAfter(crt), smp_trash) <= 0)
2958 goto out;
2959
2960 smp->data.str = *smp_trash;
2961 smp->type = SMP_T_STR;
2962 ret = 1;
2963out:
Emeric Brunba841a12014-04-30 17:05:08 +02002964 /* SSL_get_peer_certificate, it increase X509 * ref count */
2965 if (cert_peer && crt)
Emeric Brunce5ad802012-10-22 14:11:22 +02002966 X509_free(crt);
2967 return ret;
2968}
2969
Emeric Brunba841a12014-04-30 17:05:08 +02002970/* string, returns a string of a formatted full dn \C=..\O=..\OU=.. \CN=.. of certificate's issuer
2971 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
2972 * should be use.
2973 */
Emeric Brun87855892012-10-17 17:39:35 +02002974static int
Emeric Brunba841a12014-04-30 17:05:08 +02002975smp_fetch_ssl_x_i_dn(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002976 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brun87855892012-10-17 17:39:35 +02002977{
Emeric Brunba841a12014-04-30 17:05:08 +02002978 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brun87855892012-10-17 17:39:35 +02002979 X509 *crt = NULL;
2980 X509_NAME *name;
2981 int ret = 0;
2982 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002983 struct connection *conn;
Emeric Brun87855892012-10-17 17:39:35 +02002984
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002985 if (!l4)
Emeric Brun87855892012-10-17 17:39:35 +02002986 return 0;
2987
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002988 conn = objt_conn(l4->si[0].end);
2989 if (!conn || conn->xprt != &ssl_sock)
2990 return 0;
2991
2992 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun87855892012-10-17 17:39:35 +02002993 smp->flags |= SMP_F_MAY_CHANGE;
2994 return 0;
2995 }
2996
Emeric Brunba841a12014-04-30 17:05:08 +02002997 if (cert_peer)
2998 crt = SSL_get_peer_certificate(conn->xprt_ctx);
2999 else
3000 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brun87855892012-10-17 17:39:35 +02003001 if (!crt)
3002 goto out;
3003
3004 name = X509_get_issuer_name(crt);
3005 if (!name)
3006 goto out;
3007
Willy Tarreau47ca5452012-12-23 20:22:19 +01003008 smp_trash = get_trash_chunk();
Emeric Brun87855892012-10-17 17:39:35 +02003009 if (args && args[0].type == ARGT_STR) {
3010 int pos = 1;
3011
3012 if (args[1].type == ARGT_SINT)
3013 pos = args[1].data.sint;
3014 else if (args[1].type == ARGT_UINT)
3015 pos =(int)args[1].data.uint;
3016
3017 if (ssl_sock_get_dn_entry(name, &args[0].data.str, pos, smp_trash) <= 0)
3018 goto out;
3019 }
3020 else if (ssl_sock_get_dn_oneline(name, smp_trash) <= 0)
3021 goto out;
3022
3023 smp->type = SMP_T_STR;
3024 smp->data.str = *smp_trash;
3025 ret = 1;
3026out:
Emeric Brunba841a12014-04-30 17:05:08 +02003027 /* SSL_get_peer_certificate, it increase X509 * ref count */
3028 if (cert_peer && crt)
Emeric Brun87855892012-10-17 17:39:35 +02003029 X509_free(crt);
3030 return ret;
3031}
3032
Emeric Brunba841a12014-04-30 17:05:08 +02003033/* string, returns notbefore date in ASN1_UTCTIME format.
3034 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
3035 * should be use.
3036 */
Emeric Brunce5ad802012-10-22 14:11:22 +02003037static int
Emeric Brunba841a12014-04-30 17:05:08 +02003038smp_fetch_ssl_x_notbefore(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003039 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brunce5ad802012-10-22 14:11:22 +02003040{
Emeric Brunba841a12014-04-30 17:05:08 +02003041 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brunce5ad802012-10-22 14:11:22 +02003042 X509 *crt = NULL;
3043 int ret = 0;
3044 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003045 struct connection *conn;
3046
3047 if (!l4)
3048 return 0;
Emeric Brunce5ad802012-10-22 14:11:22 +02003049
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003050 conn = objt_conn(l4->si[0].end);
3051 if (!conn || conn->xprt != &ssl_sock)
Emeric Brunce5ad802012-10-22 14:11:22 +02003052 return 0;
3053
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003054 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunce5ad802012-10-22 14:11:22 +02003055 smp->flags |= SMP_F_MAY_CHANGE;
3056 return 0;
3057 }
3058
Emeric Brunba841a12014-04-30 17:05:08 +02003059 if (cert_peer)
3060 crt = SSL_get_peer_certificate(conn->xprt_ctx);
3061 else
3062 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brunce5ad802012-10-22 14:11:22 +02003063 if (!crt)
3064 goto out;
3065
Willy Tarreau47ca5452012-12-23 20:22:19 +01003066 smp_trash = get_trash_chunk();
Emeric Brunce5ad802012-10-22 14:11:22 +02003067 if (ssl_sock_get_time(X509_get_notBefore(crt), smp_trash) <= 0)
3068 goto out;
3069
3070 smp->data.str = *smp_trash;
3071 smp->type = SMP_T_STR;
3072 ret = 1;
3073out:
Emeric Brunba841a12014-04-30 17:05:08 +02003074 /* SSL_get_peer_certificate, it increase X509 * ref count */
3075 if (cert_peer && crt)
Emeric Brunce5ad802012-10-22 14:11:22 +02003076 X509_free(crt);
3077 return ret;
3078}
3079
Emeric Brunba841a12014-04-30 17:05:08 +02003080/* string, returns a string of a formatted full dn \C=..\O=..\OU=.. \CN=.. of certificate's subject
3081 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
3082 * should be use.
3083 */
Emeric Brun87855892012-10-17 17:39:35 +02003084static int
Emeric Brunba841a12014-04-30 17:05:08 +02003085smp_fetch_ssl_x_s_dn(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003086 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brun87855892012-10-17 17:39:35 +02003087{
Emeric Brunba841a12014-04-30 17:05:08 +02003088 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brun87855892012-10-17 17:39:35 +02003089 X509 *crt = NULL;
3090 X509_NAME *name;
3091 int ret = 0;
3092 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003093 struct connection *conn;
Emeric Brun87855892012-10-17 17:39:35 +02003094
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003095 if (!l4)
Emeric Brun87855892012-10-17 17:39:35 +02003096 return 0;
3097
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003098 conn = objt_conn(l4->si[0].end);
3099 if (!conn || conn->xprt != &ssl_sock)
3100 return 0;
3101
3102 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun87855892012-10-17 17:39:35 +02003103 smp->flags |= SMP_F_MAY_CHANGE;
3104 return 0;
3105 }
3106
Emeric Brunba841a12014-04-30 17:05:08 +02003107 if (cert_peer)
3108 crt = SSL_get_peer_certificate(conn->xprt_ctx);
3109 else
3110 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brun87855892012-10-17 17:39:35 +02003111 if (!crt)
3112 goto out;
3113
3114 name = X509_get_subject_name(crt);
3115 if (!name)
3116 goto out;
3117
Willy Tarreau47ca5452012-12-23 20:22:19 +01003118 smp_trash = get_trash_chunk();
Emeric Brun87855892012-10-17 17:39:35 +02003119 if (args && args[0].type == ARGT_STR) {
3120 int pos = 1;
3121
3122 if (args[1].type == ARGT_SINT)
3123 pos = args[1].data.sint;
3124 else if (args[1].type == ARGT_UINT)
3125 pos =(int)args[1].data.uint;
3126
3127 if (ssl_sock_get_dn_entry(name, &args[0].data.str, pos, smp_trash) <= 0)
3128 goto out;
3129 }
3130 else if (ssl_sock_get_dn_oneline(name, smp_trash) <= 0)
3131 goto out;
3132
3133 smp->type = SMP_T_STR;
3134 smp->data.str = *smp_trash;
3135 ret = 1;
3136out:
Emeric Brunba841a12014-04-30 17:05:08 +02003137 /* SSL_get_peer_certificate, it increase X509 * ref count */
3138 if (cert_peer && crt)
Emeric Brun87855892012-10-17 17:39:35 +02003139 X509_free(crt);
3140 return ret;
3141}
Emeric Brun9143d372012-12-20 15:44:16 +01003142
3143/* integer, returns true if current session use a client certificate */
3144static int
3145smp_fetch_ssl_c_used(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003146 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brun9143d372012-12-20 15:44:16 +01003147{
3148 X509 *crt;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003149 struct connection *conn;
Emeric Brun9143d372012-12-20 15:44:16 +01003150
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003151 if (!l4)
Emeric Brun9143d372012-12-20 15:44:16 +01003152 return 0;
3153
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003154 conn = objt_conn(l4->si[0].end);
3155 if (!conn || conn->xprt != &ssl_sock)
3156 return 0;
3157
3158 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun9143d372012-12-20 15:44:16 +01003159 smp->flags |= SMP_F_MAY_CHANGE;
3160 return 0;
3161 }
3162
3163 /* SSL_get_peer_certificate returns a ptr on allocated X509 struct */
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003164 crt = SSL_get_peer_certificate(conn->xprt_ctx);
Emeric Brun9143d372012-12-20 15:44:16 +01003165 if (crt) {
3166 X509_free(crt);
3167 }
3168
3169 smp->type = SMP_T_BOOL;
3170 smp->data.uint = (crt != NULL);
3171 return 1;
3172}
3173
Emeric Brunba841a12014-04-30 17:05:08 +02003174/* integer, returns the certificate version
3175 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
3176 * should be use.
3177 */
Emeric Bruna7359fd2012-10-17 15:03:11 +02003178static int
Emeric Brunba841a12014-04-30 17:05:08 +02003179smp_fetch_ssl_x_version(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003180 const struct arg *args, struct sample *smp, const char *kw)
Emeric Bruna7359fd2012-10-17 15:03:11 +02003181{
Emeric Brunba841a12014-04-30 17:05:08 +02003182 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Bruna7359fd2012-10-17 15:03:11 +02003183 X509 *crt;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003184 struct connection *conn;
3185
3186 if (!l4)
3187 return 0;
Emeric Bruna7359fd2012-10-17 15:03:11 +02003188
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003189 conn = objt_conn(l4->si[0].end);
3190 if (!conn || conn->xprt != &ssl_sock)
Emeric Bruna7359fd2012-10-17 15:03:11 +02003191 return 0;
3192
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003193 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Bruna7359fd2012-10-17 15:03:11 +02003194 smp->flags |= SMP_F_MAY_CHANGE;
3195 return 0;
3196 }
3197
Emeric Brunba841a12014-04-30 17:05:08 +02003198 if (cert_peer)
3199 crt = SSL_get_peer_certificate(conn->xprt_ctx);
3200 else
3201 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Bruna7359fd2012-10-17 15:03:11 +02003202 if (!crt)
3203 return 0;
3204
3205 smp->data.uint = (unsigned int)(1 + X509_get_version(crt));
Emeric Brunba841a12014-04-30 17:05:08 +02003206 /* SSL_get_peer_certificate increase X509 * ref count */
3207 if (cert_peer)
3208 X509_free(crt);
Emeric Bruna7359fd2012-10-17 15:03:11 +02003209 smp->type = SMP_T_UINT;
3210
3211 return 1;
3212}
3213
Emeric Brunba841a12014-04-30 17:05:08 +02003214/* string, returns the certificate's signature algorithm.
3215 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
3216 * should be use.
3217 */
Emeric Brun7f56e742012-10-19 18:15:40 +02003218static int
Emeric Brunba841a12014-04-30 17:05:08 +02003219smp_fetch_ssl_x_sig_alg(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003220 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brun7f56e742012-10-19 18:15:40 +02003221{
Emeric Brunba841a12014-04-30 17:05:08 +02003222 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brun7f56e742012-10-19 18:15:40 +02003223 X509 *crt;
3224 int nid;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003225 struct connection *conn;
Emeric Brun7f56e742012-10-19 18:15:40 +02003226
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003227 if (!l4)
Emeric Brun7f56e742012-10-19 18:15:40 +02003228 return 0;
3229
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003230 conn = objt_conn(l4->si[0].end);
3231 if (!conn || conn->xprt != &ssl_sock)
3232 return 0;
3233
3234 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun7f56e742012-10-19 18:15:40 +02003235 smp->flags |= SMP_F_MAY_CHANGE;
3236 return 0;
3237 }
3238
Emeric Brunba841a12014-04-30 17:05:08 +02003239 if (cert_peer)
3240 crt = SSL_get_peer_certificate(conn->xprt_ctx);
3241 else
3242 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brun7f56e742012-10-19 18:15:40 +02003243 if (!crt)
3244 return 0;
3245
3246 nid = OBJ_obj2nid((ASN1_OBJECT *)(crt->cert_info->signature->algorithm));
3247
3248 smp->data.str.str = (char *)OBJ_nid2sn(nid);
Emeric Brun9bf3ba22013-10-07 14:31:44 +02003249 if (!smp->data.str.str) {
Emeric Brunba841a12014-04-30 17:05:08 +02003250 /* SSL_get_peer_certificate increase X509 * ref count */
3251 if (cert_peer)
3252 X509_free(crt);
Emeric Brun7f56e742012-10-19 18:15:40 +02003253 return 0;
Emeric Brun9bf3ba22013-10-07 14:31:44 +02003254 }
Emeric Brun7f56e742012-10-19 18:15:40 +02003255
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01003256 smp->type = SMP_T_STR;
3257 smp->flags |= SMP_F_CONST;
Emeric Brun7f56e742012-10-19 18:15:40 +02003258 smp->data.str.len = strlen(smp->data.str.str);
Emeric Brunba841a12014-04-30 17:05:08 +02003259 /* SSL_get_peer_certificate increase X509 * ref count */
3260 if (cert_peer)
3261 X509_free(crt);
Emeric Brun7f56e742012-10-19 18:15:40 +02003262
3263 return 1;
3264}
3265
Emeric Brunba841a12014-04-30 17:05:08 +02003266/* string, returns the certificate's key algorithm.
3267 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
3268 * should be use.
3269 */
Emeric Brun521a0112012-10-22 12:22:55 +02003270static int
Emeric Brunba841a12014-04-30 17:05:08 +02003271smp_fetch_ssl_x_key_alg(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003272 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brun521a0112012-10-22 12:22:55 +02003273{
Emeric Brunba841a12014-04-30 17:05:08 +02003274 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brun521a0112012-10-22 12:22:55 +02003275 X509 *crt;
3276 int nid;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003277 struct connection *conn;
Emeric Brun521a0112012-10-22 12:22:55 +02003278
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003279 if (!l4)
Emeric Brun521a0112012-10-22 12:22:55 +02003280 return 0;
3281
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003282 conn = objt_conn(l4->si[0].end);
3283 if (!conn || conn->xprt != &ssl_sock)
3284 return 0;
3285
3286 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun521a0112012-10-22 12:22:55 +02003287 smp->flags |= SMP_F_MAY_CHANGE;
3288 return 0;
3289 }
3290
Emeric Brunba841a12014-04-30 17:05:08 +02003291 if (cert_peer)
3292 crt = SSL_get_peer_certificate(conn->xprt_ctx);
3293 else
3294 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brun521a0112012-10-22 12:22:55 +02003295 if (!crt)
3296 return 0;
3297
3298 nid = OBJ_obj2nid((ASN1_OBJECT *)(crt->cert_info->key->algor->algorithm));
3299
3300 smp->data.str.str = (char *)OBJ_nid2sn(nid);
Emeric Brun9bf3ba22013-10-07 14:31:44 +02003301 if (!smp->data.str.str) {
Emeric Brunba841a12014-04-30 17:05:08 +02003302 /* SSL_get_peer_certificate increase X509 * ref count */
3303 if (cert_peer)
3304 X509_free(crt);
Emeric Brun521a0112012-10-22 12:22:55 +02003305 return 0;
Emeric Brun9bf3ba22013-10-07 14:31:44 +02003306 }
Emeric Brun521a0112012-10-22 12:22:55 +02003307
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01003308 smp->type = SMP_T_STR;
3309 smp->flags |= SMP_F_CONST;
Emeric Brun521a0112012-10-22 12:22:55 +02003310 smp->data.str.len = strlen(smp->data.str.str);
Emeric Brunba841a12014-04-30 17:05:08 +02003311 if (cert_peer)
3312 X509_free(crt);
Emeric Brun521a0112012-10-22 12:22:55 +02003313
3314 return 1;
3315}
3316
Emeric Brun645ae792014-04-30 14:21:06 +02003317/* boolean, returns true if front conn. transport layer is SSL.
3318 * This function is also usable on backend conn if the fetch keyword 5th
3319 * char is 'b'.
3320 */
Willy Tarreau7875d092012-09-10 08:20:03 +02003321static int
Emeric Brun2525b6b2012-10-18 15:59:43 +02003322smp_fetch_ssl_fc(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003323 const struct arg *args, struct sample *smp, const char *kw)
Willy Tarreau7875d092012-09-10 08:20:03 +02003324{
Emeric Brun645ae792014-04-30 14:21:06 +02003325 int back_conn = (kw[4] == 'b') ? 1 : 0;
3326 struct connection *conn = objt_conn(l4->si[back_conn].end);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003327
Willy Tarreau7875d092012-09-10 08:20:03 +02003328 smp->type = SMP_T_BOOL;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003329 smp->data.uint = (conn && conn->xprt == &ssl_sock);
Willy Tarreau7875d092012-09-10 08:20:03 +02003330 return 1;
3331}
3332
Emeric Brun2525b6b2012-10-18 15:59:43 +02003333/* boolean, returns true if client present a SNI */
Willy Tarreau7875d092012-09-10 08:20:03 +02003334static int
Emeric Brun2525b6b2012-10-18 15:59:43 +02003335smp_fetch_ssl_fc_has_sni(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003336 const struct arg *args, struct sample *smp, const char *kw)
Willy Tarreau7875d092012-09-10 08:20:03 +02003337{
3338#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003339 struct connection *conn = objt_conn(l4->si[0].end);
3340
Willy Tarreau7875d092012-09-10 08:20:03 +02003341 smp->type = SMP_T_BOOL;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003342 smp->data.uint = (conn && conn->xprt == &ssl_sock) &&
3343 conn->xprt_ctx &&
3344 SSL_get_servername(conn->xprt_ctx, TLSEXT_NAMETYPE_host_name) != NULL;
Willy Tarreau7875d092012-09-10 08:20:03 +02003345 return 1;
3346#else
3347 return 0;
3348#endif
3349}
3350
Emeric Brun645ae792014-04-30 14:21:06 +02003351/* string, returns the used cipher if front conn. transport layer is SSL.
3352 * This function is also usable on backend conn if the fetch keyword 5th
3353 * char is 'b'.
3354 */
Emeric Brun589fcad2012-10-16 14:13:26 +02003355static int
3356smp_fetch_ssl_fc_cipher(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003357 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brun589fcad2012-10-16 14:13:26 +02003358{
Emeric Brun645ae792014-04-30 14:21:06 +02003359 int back_conn = (kw[4] == 'b') ? 1 : 0;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003360 struct connection *conn;
3361
Emeric Brun589fcad2012-10-16 14:13:26 +02003362 smp->flags = 0;
3363
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003364 if (!l4)
3365 return 0;
3366
Emeric Brun645ae792014-04-30 14:21:06 +02003367 conn = objt_conn(l4->si[back_conn].end);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003368 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
Emeric Brun589fcad2012-10-16 14:13:26 +02003369 return 0;
3370
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003371 smp->data.str.str = (char *)SSL_get_cipher_name(conn->xprt_ctx);
Emeric Brun589fcad2012-10-16 14:13:26 +02003372 if (!smp->data.str.str)
3373 return 0;
3374
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01003375 smp->type = SMP_T_STR;
3376 smp->flags |= SMP_F_CONST;
Emeric Brun589fcad2012-10-16 14:13:26 +02003377 smp->data.str.len = strlen(smp->data.str.str);
3378
3379 return 1;
3380}
3381
Emeric Brun645ae792014-04-30 14:21:06 +02003382/* integer, returns the algoritm's keysize if front conn. transport layer
3383 * is SSL.
3384 * This function is also usable on backend conn if the fetch keyword 5th
3385 * char is 'b'.
3386 */
Emeric Brun589fcad2012-10-16 14:13:26 +02003387static int
3388smp_fetch_ssl_fc_alg_keysize(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003389 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brun589fcad2012-10-16 14:13:26 +02003390{
Emeric Brun645ae792014-04-30 14:21:06 +02003391 int back_conn = (kw[4] == 'b') ? 1 : 0;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003392 struct connection *conn;
3393
Emeric Brun589fcad2012-10-16 14:13:26 +02003394 smp->flags = 0;
3395
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003396 if (!l4)
Emeric Brun589fcad2012-10-16 14:13:26 +02003397 return 0;
3398
Emeric Brun645ae792014-04-30 14:21:06 +02003399 conn = objt_conn(l4->si[back_conn].end);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003400 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
Emeric Brun589fcad2012-10-16 14:13:26 +02003401 return 0;
3402
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003403 if (!SSL_get_cipher_bits(conn->xprt_ctx, (int *)&smp->data.uint))
3404 return 0;
3405
Emeric Brun589fcad2012-10-16 14:13:26 +02003406 smp->type = SMP_T_UINT;
3407
3408 return 1;
3409}
3410
Emeric Brun645ae792014-04-30 14:21:06 +02003411/* integer, returns the used keysize if front conn. transport layer is SSL.
3412 * This function is also usable on backend conn if the fetch keyword 5th
3413 * char is 'b'.
3414 */
Emeric Brun589fcad2012-10-16 14:13:26 +02003415static int
3416smp_fetch_ssl_fc_use_keysize(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003417 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brun589fcad2012-10-16 14:13:26 +02003418{
Emeric Brun645ae792014-04-30 14:21:06 +02003419 int back_conn = (kw[4] == 'b') ? 1 : 0;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003420 struct connection *conn;
3421
Emeric Brun589fcad2012-10-16 14:13:26 +02003422 smp->flags = 0;
3423
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003424 if (!l4)
Emeric Brun589fcad2012-10-16 14:13:26 +02003425 return 0;
3426
Emeric Brun645ae792014-04-30 14:21:06 +02003427 conn = objt_conn(l4->si[back_conn].end);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003428 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
3429 return 0;
3430
3431 smp->data.uint = (unsigned int)SSL_get_cipher_bits(conn->xprt_ctx, NULL);
Emeric Brun589fcad2012-10-16 14:13:26 +02003432 if (!smp->data.uint)
3433 return 0;
3434
3435 smp->type = SMP_T_UINT;
3436
3437 return 1;
3438}
3439
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02003440#ifdef OPENSSL_NPN_NEGOTIATED
Willy Tarreau7875d092012-09-10 08:20:03 +02003441static int
Emeric Brun2525b6b2012-10-18 15:59:43 +02003442smp_fetch_ssl_fc_npn(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003443 const struct arg *args, struct sample *smp, const char *kw)
Willy Tarreaua33c6542012-10-15 13:19:06 +02003444{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003445 struct connection *conn;
3446
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01003447 smp->flags = SMP_F_CONST;
3448 smp->type = SMP_T_STR;
Willy Tarreaua33c6542012-10-15 13:19:06 +02003449
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003450 if (!l4)
Willy Tarreaua33c6542012-10-15 13:19:06 +02003451 return 0;
3452
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003453 conn = objt_conn(l4->si[0].end);
3454 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
3455 return 0;
3456
Willy Tarreaua33c6542012-10-15 13:19:06 +02003457 smp->data.str.str = NULL;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003458 SSL_get0_next_proto_negotiated(conn->xprt_ctx,
Willy Tarreaua33c6542012-10-15 13:19:06 +02003459 (const unsigned char **)&smp->data.str.str, (unsigned *)&smp->data.str.len);
3460
3461 if (!smp->data.str.str)
3462 return 0;
3463
3464 return 1;
Willy Tarreaua33c6542012-10-15 13:19:06 +02003465}
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02003466#endif
Willy Tarreaua33c6542012-10-15 13:19:06 +02003467
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01003468#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Willy Tarreauab861d32013-04-02 02:30:41 +02003469static int
3470smp_fetch_ssl_fc_alpn(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003471 const struct arg *args, struct sample *smp, const char *kw)
Willy Tarreauab861d32013-04-02 02:30:41 +02003472{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003473 struct connection *conn;
3474
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01003475 smp->flags = SMP_F_CONST;
3476 smp->type = SMP_T_STR;
Willy Tarreauab861d32013-04-02 02:30:41 +02003477
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003478 if (!l4)
3479 return 0;
3480
3481 conn = objt_conn(l4->si[0].end);
3482 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
Willy Tarreauab861d32013-04-02 02:30:41 +02003483 return 0;
3484
3485 smp->data.str.str = NULL;
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01003486 SSL_get0_alpn_selected(conn->xprt_ctx,
Willy Tarreauab861d32013-04-02 02:30:41 +02003487 (const unsigned char **)&smp->data.str.str, (unsigned *)&smp->data.str.len);
3488
3489 if (!smp->data.str.str)
3490 return 0;
3491
3492 return 1;
3493}
3494#endif
3495
Emeric Brun645ae792014-04-30 14:21:06 +02003496/* string, returns the used protocol if front conn. transport layer is SSL.
3497 * This function is also usable on backend conn if the fetch keyword 5th
3498 * char is 'b'.
3499 */
Willy Tarreaua33c6542012-10-15 13:19:06 +02003500static int
Emeric Brun589fcad2012-10-16 14:13:26 +02003501smp_fetch_ssl_fc_protocol(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003502 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brun589fcad2012-10-16 14:13:26 +02003503{
Emeric Brun645ae792014-04-30 14:21:06 +02003504 int back_conn = (kw[4] == 'b') ? 1 : 0;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003505 struct connection *conn;
3506
Emeric Brun589fcad2012-10-16 14:13:26 +02003507 smp->flags = 0;
3508
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003509 if (!l4)
Emeric Brun589fcad2012-10-16 14:13:26 +02003510 return 0;
3511
Emeric Brun645ae792014-04-30 14:21:06 +02003512 conn = objt_conn(l4->si[back_conn].end);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003513 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
3514 return 0;
3515
3516 smp->data.str.str = (char *)SSL_get_version(conn->xprt_ctx);
Emeric Brun589fcad2012-10-16 14:13:26 +02003517 if (!smp->data.str.str)
3518 return 0;
3519
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01003520 smp->type = SMP_T_STR;
3521 smp->flags = SMP_F_CONST;
Emeric Brun589fcad2012-10-16 14:13:26 +02003522 smp->data.str.len = strlen(smp->data.str.str);
3523
3524 return 1;
3525}
3526
Emeric Brun645ae792014-04-30 14:21:06 +02003527/* binary, returns the SSL session id if front conn. transport layer is SSL.
3528 * This function is also usable on backend conn if the fetch keyword 5th
3529 * char is 'b'.
3530 */
Emeric Brun589fcad2012-10-16 14:13:26 +02003531static int
Emeric Brunfe68f682012-10-16 14:59:28 +02003532smp_fetch_ssl_fc_session_id(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003533 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brunfe68f682012-10-16 14:59:28 +02003534{
3535#if OPENSSL_VERSION_NUMBER > 0x0090800fL
Emeric Brun645ae792014-04-30 14:21:06 +02003536 int back_conn = (kw[4] == 'b') ? 1 : 0;
Emeric Brunfe68f682012-10-16 14:59:28 +02003537 SSL_SESSION *sess;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003538 struct connection *conn;
Emeric Brunfe68f682012-10-16 14:59:28 +02003539
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01003540 smp->flags = SMP_F_CONST;
3541 smp->type = SMP_T_BIN;
Emeric Brunfe68f682012-10-16 14:59:28 +02003542
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003543 if (!l4)
Emeric Brunfe68f682012-10-16 14:59:28 +02003544 return 0;
3545
Emeric Brun645ae792014-04-30 14:21:06 +02003546 conn = objt_conn(l4->si[back_conn].end);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003547 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
3548 return 0;
3549
3550 sess = SSL_get_session(conn->xprt_ctx);
Emeric Brunfe68f682012-10-16 14:59:28 +02003551 if (!sess)
3552 return 0;
3553
3554 smp->data.str.str = (char *)SSL_SESSION_get_id(sess, (unsigned int *)&smp->data.str.len);
Willy Tarreau69760db2015-06-17 18:34:14 +02003555 if (!smp->data.str.str || !smp->data.str.len)
Emeric Brunfe68f682012-10-16 14:59:28 +02003556 return 0;
3557
3558 return 1;
3559#else
3560 return 0;
3561#endif
3562}
3563
3564static int
Emeric Brun2525b6b2012-10-18 15:59:43 +02003565smp_fetch_ssl_fc_sni(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003566 const struct arg *args, struct sample *smp, const char *kw)
Willy Tarreau7875d092012-09-10 08:20:03 +02003567{
3568#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003569 struct connection *conn;
3570
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01003571 smp->flags = SMP_F_CONST;
3572 smp->type = SMP_T_STR;
Willy Tarreau7875d092012-09-10 08:20:03 +02003573
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003574 if (!l4)
Willy Tarreau7875d092012-09-10 08:20:03 +02003575 return 0;
3576
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003577 conn = objt_conn(l4->si[0].end);
3578 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
3579 return 0;
3580
3581 smp->data.str.str = (char *)SSL_get_servername(conn->xprt_ctx, TLSEXT_NAMETYPE_host_name);
Willy Tarreau3e394c92012-09-14 23:56:58 +02003582 if (!smp->data.str.str)
3583 return 0;
3584
Willy Tarreau7875d092012-09-10 08:20:03 +02003585 smp->data.str.len = strlen(smp->data.str.str);
3586 return 1;
3587#else
3588 return 0;
3589#endif
3590}
3591
David Sc1ad52e2014-04-08 18:48:47 -04003592static int
3593smp_fetch_ssl_fc_unique_id(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
3594 const struct arg *args, struct sample *smp, const char *kw)
3595{
3596#if OPENSSL_VERSION_NUMBER > 0x0090800fL
Emeric Brun645ae792014-04-30 14:21:06 +02003597 int back_conn = (kw[4] == 'b') ? 1 : 0;
David Sc1ad52e2014-04-08 18:48:47 -04003598 struct connection *conn;
3599 int finished_len;
David Sc1ad52e2014-04-08 18:48:47 -04003600 struct chunk *finished_trash;
David Sc1ad52e2014-04-08 18:48:47 -04003601
3602 smp->flags = 0;
3603
3604 if (!l4)
3605 return 0;
3606
Emeric Brun645ae792014-04-30 14:21:06 +02003607 conn = objt_conn(l4->si[back_conn].end);
David Sc1ad52e2014-04-08 18:48:47 -04003608 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
3609 return 0;
3610
3611 if (!(conn->flags & CO_FL_CONNECTED)) {
3612 smp->flags |= SMP_F_MAY_CHANGE;
3613 return 0;
3614 }
3615
3616 finished_trash = get_trash_chunk();
3617 if (!SSL_session_reused(conn->xprt_ctx))
3618 finished_len = SSL_get_peer_finished(conn->xprt_ctx, finished_trash->str, finished_trash->size);
3619 else
3620 finished_len = SSL_get_finished(conn->xprt_ctx, finished_trash->str, finished_trash->size);
3621
3622 if (!finished_len)
3623 return 0;
3624
Emeric Brunb73a9b02014-04-30 18:49:19 +02003625 finished_trash->len = finished_len;
3626 smp->data.str = *finished_trash;
3627 smp->type = SMP_T_BIN;
David Sc1ad52e2014-04-08 18:48:47 -04003628
3629 return 1;
3630#else
3631 return 0;
3632#endif
3633}
3634
Emeric Brun2525b6b2012-10-18 15:59:43 +02003635/* integer, returns the first verify error in CA chain of client certificate chain. */
Emeric Brunf282a812012-09-21 15:27:54 +02003636static int
Emeric Brun2525b6b2012-10-18 15:59:43 +02003637smp_fetch_ssl_c_ca_err(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003638 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brunf282a812012-09-21 15:27:54 +02003639{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003640 struct connection *conn;
3641
3642 if (!l4)
Emeric Brunf282a812012-09-21 15:27:54 +02003643 return 0;
3644
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003645 conn = objt_conn(l4->si[0].end);
3646 if (!conn || conn->xprt != &ssl_sock)
3647 return 0;
3648
3649 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunf282a812012-09-21 15:27:54 +02003650 smp->flags = SMP_F_MAY_CHANGE;
3651 return 0;
3652 }
3653
3654 smp->type = SMP_T_UINT;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003655 smp->data.uint = (unsigned int)SSL_SOCK_ST_TO_CA_ERROR(conn->xprt_st);
Emeric Brunf282a812012-09-21 15:27:54 +02003656 smp->flags = 0;
3657
3658 return 1;
3659}
3660
Emeric Brun2525b6b2012-10-18 15:59:43 +02003661/* integer, returns the depth of the first verify error in CA chain of client certificate chain. */
Emeric Brunf282a812012-09-21 15:27:54 +02003662static int
Emeric Brun2525b6b2012-10-18 15:59:43 +02003663smp_fetch_ssl_c_ca_err_depth(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003664 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brunf282a812012-09-21 15:27:54 +02003665{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003666 struct connection *conn;
3667
3668 if (!l4)
3669 return 0;
3670
3671 conn = objt_conn(l4->si[0].end);
3672 if (!conn || conn->xprt != &ssl_sock)
Emeric Brunf282a812012-09-21 15:27:54 +02003673 return 0;
3674
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003675 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunf282a812012-09-21 15:27:54 +02003676 smp->flags = SMP_F_MAY_CHANGE;
3677 return 0;
3678 }
3679
3680 smp->type = SMP_T_UINT;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003681 smp->data.uint = (unsigned int)SSL_SOCK_ST_TO_CAEDEPTH(conn->xprt_st);
Emeric Brunf282a812012-09-21 15:27:54 +02003682 smp->flags = 0;
3683
3684 return 1;
3685}
3686
Emeric Brun2525b6b2012-10-18 15:59:43 +02003687/* integer, returns the first verify error on client certificate */
Emeric Brunf282a812012-09-21 15:27:54 +02003688static int
Emeric Brun2525b6b2012-10-18 15:59:43 +02003689smp_fetch_ssl_c_err(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003690 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brunf282a812012-09-21 15:27:54 +02003691{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003692 struct connection *conn;
3693
3694 if (!l4)
Emeric Brunf282a812012-09-21 15:27:54 +02003695 return 0;
3696
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003697 conn = objt_conn(l4->si[0].end);
3698 if (!conn || conn->xprt != &ssl_sock)
3699 return 0;
3700
3701 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunf282a812012-09-21 15:27:54 +02003702 smp->flags = SMP_F_MAY_CHANGE;
3703 return 0;
3704 }
3705
3706 smp->type = SMP_T_UINT;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003707 smp->data.uint = (unsigned int)SSL_SOCK_ST_TO_CRTERROR(conn->xprt_st);
Emeric Brunf282a812012-09-21 15:27:54 +02003708 smp->flags = 0;
3709
3710 return 1;
3711}
3712
Emeric Brun2525b6b2012-10-18 15:59:43 +02003713/* integer, returns the verify result on client cert */
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02003714static int
Emeric Brun2525b6b2012-10-18 15:59:43 +02003715smp_fetch_ssl_c_verify(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003716 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02003717{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003718 struct connection *conn;
3719
3720 if (!l4)
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02003721 return 0;
3722
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003723 conn = objt_conn(l4->si[0].end);
3724 if (!conn || conn->xprt != &ssl_sock)
3725 return 0;
3726
3727 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02003728 smp->flags = SMP_F_MAY_CHANGE;
3729 return 0;
3730 }
3731
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003732 if (!conn->xprt_ctx)
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02003733 return 0;
3734
3735 smp->type = SMP_T_UINT;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003736 smp->data.uint = (unsigned int)SSL_get_verify_result(conn->xprt_ctx);
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02003737 smp->flags = 0;
3738
3739 return 1;
3740}
3741
Emeric Brunfb510ea2012-10-05 12:00:26 +02003742/* parse the "ca-file" bind keyword */
3743static 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 +02003744{
3745 if (!*args[cur_arg + 1]) {
3746 if (err)
3747 memprintf(err, "'%s' : missing CAfile path", args[cur_arg]);
3748 return ERR_ALERT | ERR_FATAL;
3749 }
3750
Emeric Brunef42d922012-10-11 16:11:36 +02003751 if ((*args[cur_arg + 1] != '/') && global.ca_base)
3752 memprintf(&conf->ca_file, "%s/%s", global.ca_base, args[cur_arg + 1]);
3753 else
3754 memprintf(&conf->ca_file, "%s", args[cur_arg + 1]);
Emeric Brunc8e8d122012-10-02 18:42:10 +02003755
Emeric Brund94b3fe2012-09-20 18:23:56 +02003756 return 0;
3757}
3758
Willy Tarreau79eeafa2012-09-14 07:53:05 +02003759/* parse the "ciphers" bind keyword */
Willy Tarreau4348fad2012-09-20 16:48:07 +02003760static 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 +02003761{
3762 if (!*args[cur_arg + 1]) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02003763 memprintf(err, "'%s' : missing cipher suite", args[cur_arg]);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02003764 return ERR_ALERT | ERR_FATAL;
3765 }
3766
Emeric Brun76d88952012-10-05 15:47:31 +02003767 free(conf->ciphers);
Willy Tarreau4348fad2012-09-20 16:48:07 +02003768 conf->ciphers = strdup(args[cur_arg + 1]);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02003769 return 0;
3770}
3771
3772/* parse the "crt" bind keyword */
Willy Tarreau4348fad2012-09-20 16:48:07 +02003773static 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 +02003774{
Willy Tarreau38011032013-08-13 16:59:39 +02003775 char path[MAXPATHLEN];
Willy Tarreaub75d6922014-04-14 18:05:41 +02003776
Willy Tarreau79eeafa2012-09-14 07:53:05 +02003777 if (!*args[cur_arg + 1]) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02003778 memprintf(err, "'%s' : missing certificate location", args[cur_arg]);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02003779 return ERR_ALERT | ERR_FATAL;
3780 }
3781
Emeric Brunc8e8d122012-10-02 18:42:10 +02003782 if ((*args[cur_arg + 1] != '/' ) && global.crt_base) {
Willy Tarreau38011032013-08-13 16:59:39 +02003783 if ((strlen(global.crt_base) + 1 + strlen(args[cur_arg + 1]) + 1) > MAXPATHLEN) {
Emeric Brunc8e8d122012-10-02 18:42:10 +02003784 memprintf(err, "'%s' : path too long", args[cur_arg]);
3785 return ERR_ALERT | ERR_FATAL;
3786 }
Willy Tarreaub75d6922014-04-14 18:05:41 +02003787 snprintf(path, sizeof(path), "%s/%s", global.crt_base, args[cur_arg + 1]);
Emeric Brunc8e8d122012-10-02 18:42:10 +02003788 if (ssl_sock_load_cert(path, conf, px, err) > 0)
3789 return ERR_ALERT | ERR_FATAL;
3790
3791 return 0;
3792 }
3793
Willy Tarreau4348fad2012-09-20 16:48:07 +02003794 if (ssl_sock_load_cert(args[cur_arg + 1], conf, px, err) > 0)
Willy Tarreau79eeafa2012-09-14 07:53:05 +02003795 return ERR_ALERT | ERR_FATAL;
Emeric Brund94b3fe2012-09-20 18:23:56 +02003796
3797 return 0;
3798}
3799
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01003800/* parse the "crt-list" bind keyword */
3801static int bind_parse_crt_list(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
3802{
3803 if (!*args[cur_arg + 1]) {
3804 memprintf(err, "'%s' : missing certificate location", args[cur_arg]);
3805 return ERR_ALERT | ERR_FATAL;
3806 }
3807
Willy Tarreauad1731d2013-04-02 17:35:58 +02003808 if (ssl_sock_load_cert_list_file(args[cur_arg + 1], conf, px, err) > 0) {
3809 memprintf(err, "'%s' : %s", args[cur_arg], *err);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01003810 return ERR_ALERT | ERR_FATAL;
Willy Tarreauad1731d2013-04-02 17:35:58 +02003811 }
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01003812
3813 return 0;
3814}
3815
Emeric Brunfb510ea2012-10-05 12:00:26 +02003816/* parse the "crl-file" bind keyword */
3817static 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 +02003818{
Emeric Brun051cdab2012-10-02 19:25:50 +02003819#ifndef X509_V_FLAG_CRL_CHECK
3820 if (err)
3821 memprintf(err, "'%s' : library does not support CRL verify", args[cur_arg]);
3822 return ERR_ALERT | ERR_FATAL;
3823#else
Emeric Brund94b3fe2012-09-20 18:23:56 +02003824 if (!*args[cur_arg + 1]) {
3825 if (err)
3826 memprintf(err, "'%s' : missing CRLfile path", args[cur_arg]);
3827 return ERR_ALERT | ERR_FATAL;
3828 }
Emeric Brun2b58d042012-09-20 17:10:03 +02003829
Emeric Brunef42d922012-10-11 16:11:36 +02003830 if ((*args[cur_arg + 1] != '/') && global.ca_base)
3831 memprintf(&conf->crl_file, "%s/%s", global.ca_base, args[cur_arg + 1]);
3832 else
3833 memprintf(&conf->crl_file, "%s", args[cur_arg + 1]);
Emeric Brunc8e8d122012-10-02 18:42:10 +02003834
Emeric Brun2b58d042012-09-20 17:10:03 +02003835 return 0;
Emeric Brun051cdab2012-10-02 19:25:50 +02003836#endif
Emeric Brun2b58d042012-09-20 17:10:03 +02003837}
3838
3839/* parse the "ecdhe" bind keyword keywords */
3840static int bind_parse_ecdhe(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
3841{
3842#if OPENSSL_VERSION_NUMBER < 0x0090800fL
3843 if (err)
3844 memprintf(err, "'%s' : library does not support elliptic curve Diffie-Hellman (too old)", args[cur_arg]);
3845 return ERR_ALERT | ERR_FATAL;
3846#elif defined(OPENSSL_NO_ECDH)
3847 if (err)
3848 memprintf(err, "'%s' : library does not support elliptic curve Diffie-Hellman (disabled via OPENSSL_NO_ECDH)", args[cur_arg]);
3849 return ERR_ALERT | ERR_FATAL;
3850#else
3851 if (!*args[cur_arg + 1]) {
3852 if (err)
3853 memprintf(err, "'%s' : missing named curve", args[cur_arg]);
3854 return ERR_ALERT | ERR_FATAL;
3855 }
3856
3857 conf->ecdhe = strdup(args[cur_arg + 1]);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02003858
3859 return 0;
Emeric Brun2b58d042012-09-20 17:10:03 +02003860#endif
Willy Tarreau79eeafa2012-09-14 07:53:05 +02003861}
3862
Emeric Brun81c00f02012-09-21 14:31:21 +02003863/* parse the "crt_ignerr" and "ca_ignerr" bind keywords */
3864static int bind_parse_ignore_err(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
3865{
3866 int code;
3867 char *p = args[cur_arg + 1];
3868 unsigned long long *ignerr = &conf->crt_ignerr;
3869
3870 if (!*p) {
3871 if (err)
3872 memprintf(err, "'%s' : missing error IDs list", args[cur_arg]);
3873 return ERR_ALERT | ERR_FATAL;
3874 }
3875
3876 if (strcmp(args[cur_arg], "ca-ignore-err") == 0)
3877 ignerr = &conf->ca_ignerr;
3878
3879 if (strcmp(p, "all") == 0) {
3880 *ignerr = ~0ULL;
3881 return 0;
3882 }
3883
3884 while (p) {
3885 code = atoi(p);
3886 if ((code <= 0) || (code > 63)) {
3887 if (err)
3888 memprintf(err, "'%s' : ID '%d' out of range (1..63) in error IDs list '%s'",
3889 args[cur_arg], code, args[cur_arg + 1]);
3890 return ERR_ALERT | ERR_FATAL;
3891 }
3892 *ignerr |= 1ULL << code;
3893 p = strchr(p, ',');
3894 if (p)
3895 p++;
3896 }
3897
Emeric Brun2cb7ae52012-10-05 14:14:21 +02003898 return 0;
3899}
3900
3901/* parse the "force-sslv3" bind keyword */
3902static int bind_parse_force_sslv3(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
3903{
3904 conf->ssl_options |= BC_SSL_O_USE_SSLV3;
3905 return 0;
3906}
3907
3908/* parse the "force-tlsv10" bind keyword */
3909static int bind_parse_force_tlsv10(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
3910{
3911 conf->ssl_options |= BC_SSL_O_USE_TLSV10;
Emeric Brun2d0c4822012-10-02 13:45:20 +02003912 return 0;
3913}
3914
Emeric Brun2cb7ae52012-10-05 14:14:21 +02003915/* parse the "force-tlsv11" bind keyword */
3916static int bind_parse_force_tlsv11(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
3917{
3918#if SSL_OP_NO_TLSv1_1
3919 conf->ssl_options |= BC_SSL_O_USE_TLSV11;
3920 return 0;
3921#else
3922 if (err)
3923 memprintf(err, "'%s' : library does not support protocol TLSv1.1", args[cur_arg]);
3924 return ERR_ALERT | ERR_FATAL;
3925#endif
3926}
3927
3928/* parse the "force-tlsv12" bind keyword */
3929static int bind_parse_force_tlsv12(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
3930{
3931#if SSL_OP_NO_TLSv1_2
3932 conf->ssl_options |= BC_SSL_O_USE_TLSV12;
3933 return 0;
3934#else
3935 if (err)
3936 memprintf(err, "'%s' : library does not support protocol TLSv1.2", args[cur_arg]);
3937 return ERR_ALERT | ERR_FATAL;
3938#endif
3939}
3940
3941
Emeric Brun2d0c4822012-10-02 13:45:20 +02003942/* parse the "no-tls-tickets" bind keyword */
3943static int bind_parse_no_tls_tickets(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
3944{
Emeric Brun89675492012-10-05 13:48:26 +02003945 conf->ssl_options |= BC_SSL_O_NO_TLS_TICKETS;
Emeric Brun81c00f02012-09-21 14:31:21 +02003946 return 0;
3947}
3948
Emeric Brun2d0c4822012-10-02 13:45:20 +02003949
Emeric Brun9b3009b2012-10-05 11:55:06 +02003950/* parse the "no-sslv3" bind keyword */
3951static 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 +02003952{
Emeric Brun89675492012-10-05 13:48:26 +02003953 conf->ssl_options |= BC_SSL_O_NO_SSLV3;
Willy Tarreau79eeafa2012-09-14 07:53:05 +02003954 return 0;
3955}
3956
Emeric Brun9b3009b2012-10-05 11:55:06 +02003957/* parse the "no-tlsv10" bind keyword */
3958static 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 +02003959{
Emeric Brun89675492012-10-05 13:48:26 +02003960 conf->ssl_options |= BC_SSL_O_NO_TLSV10;
Emeric Brunc0ff4922012-09-28 19:37:02 +02003961 return 0;
3962}
3963
Emeric Brun9b3009b2012-10-05 11:55:06 +02003964/* parse the "no-tlsv11" bind keyword */
3965static 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 +02003966{
Emeric Brun89675492012-10-05 13:48:26 +02003967 conf->ssl_options |= BC_SSL_O_NO_TLSV11;
Emeric Brunc0ff4922012-09-28 19:37:02 +02003968 return 0;
3969}
3970
Emeric Brun9b3009b2012-10-05 11:55:06 +02003971/* parse the "no-tlsv12" bind keyword */
3972static 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 +02003973{
Emeric Brun89675492012-10-05 13:48:26 +02003974 conf->ssl_options |= BC_SSL_O_NO_TLSV12;
Willy Tarreau79eeafa2012-09-14 07:53:05 +02003975 return 0;
3976}
3977
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02003978/* parse the "npn" bind keyword */
3979static int bind_parse_npn(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
3980{
3981#ifdef OPENSSL_NPN_NEGOTIATED
3982 char *p1, *p2;
3983
3984 if (!*args[cur_arg + 1]) {
3985 memprintf(err, "'%s' : missing the comma-delimited NPN protocol suite", args[cur_arg]);
3986 return ERR_ALERT | ERR_FATAL;
3987 }
3988
3989 free(conf->npn_str);
3990
3991 /* the NPN string is built as a suite of (<len> <name>)* */
3992 conf->npn_len = strlen(args[cur_arg + 1]) + 1;
3993 conf->npn_str = calloc(1, conf->npn_len);
3994 memcpy(conf->npn_str + 1, args[cur_arg + 1], conf->npn_len);
3995
3996 /* replace commas with the name length */
3997 p1 = conf->npn_str;
3998 p2 = p1 + 1;
3999 while (1) {
4000 p2 = memchr(p1 + 1, ',', conf->npn_str + conf->npn_len - (p1 + 1));
4001 if (!p2)
4002 p2 = p1 + 1 + strlen(p1 + 1);
4003
4004 if (p2 - (p1 + 1) > 255) {
4005 *p2 = '\0';
4006 memprintf(err, "'%s' : NPN protocol name too long : '%s'", args[cur_arg], p1 + 1);
4007 return ERR_ALERT | ERR_FATAL;
4008 }
4009
4010 *p1 = p2 - (p1 + 1);
4011 p1 = p2;
4012
4013 if (!*p2)
4014 break;
4015
4016 *(p2++) = '\0';
4017 }
4018 return 0;
4019#else
4020 if (err)
4021 memprintf(err, "'%s' : library does not support TLS NPN extension", args[cur_arg]);
4022 return ERR_ALERT | ERR_FATAL;
4023#endif
4024}
4025
Willy Tarreauab861d32013-04-02 02:30:41 +02004026/* parse the "alpn" bind keyword */
4027static int bind_parse_alpn(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
4028{
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01004029#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Willy Tarreauab861d32013-04-02 02:30:41 +02004030 char *p1, *p2;
4031
4032 if (!*args[cur_arg + 1]) {
4033 memprintf(err, "'%s' : missing the comma-delimited ALPN protocol suite", args[cur_arg]);
4034 return ERR_ALERT | ERR_FATAL;
4035 }
4036
4037 free(conf->alpn_str);
4038
4039 /* the ALPN string is built as a suite of (<len> <name>)* */
4040 conf->alpn_len = strlen(args[cur_arg + 1]) + 1;
4041 conf->alpn_str = calloc(1, conf->alpn_len);
4042 memcpy(conf->alpn_str + 1, args[cur_arg + 1], conf->alpn_len);
4043
4044 /* replace commas with the name length */
4045 p1 = conf->alpn_str;
4046 p2 = p1 + 1;
4047 while (1) {
4048 p2 = memchr(p1 + 1, ',', conf->alpn_str + conf->alpn_len - (p1 + 1));
4049 if (!p2)
4050 p2 = p1 + 1 + strlen(p1 + 1);
4051
4052 if (p2 - (p1 + 1) > 255) {
4053 *p2 = '\0';
4054 memprintf(err, "'%s' : ALPN protocol name too long : '%s'", args[cur_arg], p1 + 1);
4055 return ERR_ALERT | ERR_FATAL;
4056 }
4057
4058 *p1 = p2 - (p1 + 1);
4059 p1 = p2;
4060
4061 if (!*p2)
4062 break;
4063
4064 *(p2++) = '\0';
4065 }
4066 return 0;
4067#else
4068 if (err)
4069 memprintf(err, "'%s' : library does not support TLS ALPN extension", args[cur_arg]);
4070 return ERR_ALERT | ERR_FATAL;
4071#endif
4072}
4073
Willy Tarreau79eeafa2012-09-14 07:53:05 +02004074/* parse the "ssl" bind keyword */
Willy Tarreau4348fad2012-09-20 16:48:07 +02004075static 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 +02004076{
Willy Tarreau81796be2012-09-22 19:11:47 +02004077 struct listener *l;
4078
Willy Tarreau4348fad2012-09-20 16:48:07 +02004079 conf->is_ssl = 1;
Emeric Brun76d88952012-10-05 15:47:31 +02004080
4081 if (global.listen_default_ciphers && !conf->ciphers)
4082 conf->ciphers = strdup(global.listen_default_ciphers);
Emeric Brun42a3e202014-10-30 15:56:50 +01004083 conf->ssl_options |= global.listen_default_ssloptions;
Emeric Brun76d88952012-10-05 15:47:31 +02004084
Willy Tarreau81796be2012-09-22 19:11:47 +02004085 list_for_each_entry(l, &conf->listeners, by_bind)
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02004086 l->xprt = &ssl_sock;
Willy Tarreau81796be2012-09-22 19:11:47 +02004087
Willy Tarreau79eeafa2012-09-14 07:53:05 +02004088 return 0;
4089}
4090
Emmanuel Hocdet65623372013-01-24 17:17:15 +01004091/* parse the "strict-sni" bind keyword */
4092static int bind_parse_strict_sni(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
4093{
4094 conf->strict_sni = 1;
4095 return 0;
4096}
4097
Emeric Brund94b3fe2012-09-20 18:23:56 +02004098/* parse the "verify" bind keyword */
4099static int bind_parse_verify(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
4100{
4101 if (!*args[cur_arg + 1]) {
4102 if (err)
4103 memprintf(err, "'%s' : missing verify method", args[cur_arg]);
4104 return ERR_ALERT | ERR_FATAL;
4105 }
4106
4107 if (strcmp(args[cur_arg + 1], "none") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01004108 conf->verify = SSL_SOCK_VERIFY_NONE;
Emeric Brund94b3fe2012-09-20 18:23:56 +02004109 else if (strcmp(args[cur_arg + 1], "optional") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01004110 conf->verify = SSL_SOCK_VERIFY_OPTIONAL;
Emeric Brund94b3fe2012-09-20 18:23:56 +02004111 else if (strcmp(args[cur_arg + 1], "required") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01004112 conf->verify = SSL_SOCK_VERIFY_REQUIRED;
Emeric Brund94b3fe2012-09-20 18:23:56 +02004113 else {
4114 if (err)
4115 memprintf(err, "'%s' : unknown verify method '%s', only 'none', 'optional', and 'required' are supported\n",
4116 args[cur_arg], args[cur_arg + 1]);
4117 return ERR_ALERT | ERR_FATAL;
4118 }
4119
4120 return 0;
4121}
4122
Willy Tarreau92faadf2012-10-10 23:04:25 +02004123/************** "server" keywords ****************/
4124
Emeric Brunef42d922012-10-11 16:11:36 +02004125/* parse the "ca-file" server keyword */
4126static int srv_parse_ca_file(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4127{
4128 if (!*args[*cur_arg + 1]) {
4129 if (err)
4130 memprintf(err, "'%s' : missing CAfile path", args[*cur_arg]);
4131 return ERR_ALERT | ERR_FATAL;
4132 }
4133
4134 if ((*args[*cur_arg + 1] != '/') && global.ca_base)
4135 memprintf(&newsrv->ssl_ctx.ca_file, "%s/%s", global.ca_base, args[*cur_arg + 1]);
4136 else
4137 memprintf(&newsrv->ssl_ctx.ca_file, "%s", args[*cur_arg + 1]);
4138
4139 return 0;
4140}
4141
Willy Tarreau92faadf2012-10-10 23:04:25 +02004142/* parse the "check-ssl" server keyword */
4143static int srv_parse_check_ssl(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4144{
4145 newsrv->check.use_ssl = 1;
4146 if (global.connect_default_ciphers && !newsrv->ssl_ctx.ciphers)
4147 newsrv->ssl_ctx.ciphers = strdup(global.connect_default_ciphers);
Emeric Brun42a3e202014-10-30 15:56:50 +01004148 newsrv->ssl_ctx.options |= global.connect_default_ssloptions;
Willy Tarreau92faadf2012-10-10 23:04:25 +02004149 return 0;
4150}
4151
4152/* parse the "ciphers" server keyword */
4153static int srv_parse_ciphers(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4154{
4155 if (!*args[*cur_arg + 1]) {
4156 memprintf(err, "'%s' : missing cipher suite", args[*cur_arg]);
4157 return ERR_ALERT | ERR_FATAL;
4158 }
4159
4160 free(newsrv->ssl_ctx.ciphers);
4161 newsrv->ssl_ctx.ciphers = strdup(args[*cur_arg + 1]);
4162 return 0;
4163}
4164
Emeric Brunef42d922012-10-11 16:11:36 +02004165/* parse the "crl-file" server keyword */
4166static int srv_parse_crl_file(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4167{
4168#ifndef X509_V_FLAG_CRL_CHECK
4169 if (err)
4170 memprintf(err, "'%s' : library does not support CRL verify", args[*cur_arg]);
4171 return ERR_ALERT | ERR_FATAL;
4172#else
4173 if (!*args[*cur_arg + 1]) {
4174 if (err)
4175 memprintf(err, "'%s' : missing CRLfile path", args[*cur_arg]);
4176 return ERR_ALERT | ERR_FATAL;
4177 }
4178
4179 if ((*args[*cur_arg + 1] != '/') && global.ca_base)
4180 memprintf(&newsrv->ssl_ctx.crl_file, "%s/%s", global.ca_base, args[*cur_arg + 1]);
4181 else
4182 memprintf(&newsrv->ssl_ctx.crl_file, "%s", args[*cur_arg + 1]);
4183
4184 return 0;
4185#endif
4186}
4187
Emeric Bruna7aa3092012-10-26 12:58:00 +02004188/* parse the "crt" server keyword */
4189static int srv_parse_crt(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4190{
4191 if (!*args[*cur_arg + 1]) {
4192 if (err)
4193 memprintf(err, "'%s' : missing certificate file path", args[*cur_arg]);
4194 return ERR_ALERT | ERR_FATAL;
4195 }
4196
4197 if ((*args[*cur_arg + 1] != '/') && global.crt_base)
4198 memprintf(&newsrv->ssl_ctx.client_crt, "%s/%s", global.ca_base, args[*cur_arg + 1]);
4199 else
4200 memprintf(&newsrv->ssl_ctx.client_crt, "%s", args[*cur_arg + 1]);
4201
4202 return 0;
4203}
Emeric Brunef42d922012-10-11 16:11:36 +02004204
Willy Tarreau92faadf2012-10-10 23:04:25 +02004205/* parse the "force-sslv3" server keyword */
4206static int srv_parse_force_sslv3(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4207{
4208 newsrv->ssl_ctx.options |= SRV_SSL_O_USE_SSLV3;
4209 return 0;
4210}
4211
4212/* parse the "force-tlsv10" server keyword */
4213static int srv_parse_force_tlsv10(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4214{
4215 newsrv->ssl_ctx.options |= SRV_SSL_O_USE_TLSV10;
4216 return 0;
4217}
4218
4219/* parse the "force-tlsv11" server keyword */
4220static int srv_parse_force_tlsv11(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4221{
4222#if SSL_OP_NO_TLSv1_1
4223 newsrv->ssl_ctx.options |= SRV_SSL_O_USE_TLSV11;
4224 return 0;
4225#else
4226 if (err)
4227 memprintf(err, "'%s' : library does not support protocol TLSv1.1", args[*cur_arg]);
4228 return ERR_ALERT | ERR_FATAL;
4229#endif
4230}
4231
4232/* parse the "force-tlsv12" server keyword */
4233static int srv_parse_force_tlsv12(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4234{
4235#if SSL_OP_NO_TLSv1_2
4236 newsrv->ssl_ctx.options |= SRV_SSL_O_USE_TLSV12;
4237 return 0;
4238#else
4239 if (err)
4240 memprintf(err, "'%s' : library does not support protocol TLSv1.2", args[*cur_arg]);
4241 return ERR_ALERT | ERR_FATAL;
4242#endif
4243}
4244
4245/* parse the "no-sslv3" server keyword */
4246static int srv_parse_no_sslv3(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4247{
4248 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_SSLV3;
4249 return 0;
4250}
4251
4252/* parse the "no-tlsv10" server keyword */
4253static int srv_parse_no_tlsv10(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4254{
4255 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_TLSV10;
4256 return 0;
4257}
4258
4259/* parse the "no-tlsv11" server keyword */
4260static int srv_parse_no_tlsv11(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4261{
4262 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_TLSV11;
4263 return 0;
4264}
4265
4266/* parse the "no-tlsv12" server keyword */
4267static int srv_parse_no_tlsv12(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4268{
4269 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_TLSV12;
4270 return 0;
4271}
4272
Emeric Brunf9c5c472012-10-11 15:28:34 +02004273/* parse the "no-tls-tickets" server keyword */
4274static int srv_parse_no_tls_tickets(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4275{
4276 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_TLS_TICKETS;
4277 return 0;
4278}
David Safb76832014-05-08 23:42:08 -04004279/* parse the "send-proxy-v2-ssl" server keyword */
4280static int srv_parse_send_proxy_ssl(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4281{
4282 newsrv->pp_opts |= SRV_PP_V2;
4283 newsrv->pp_opts |= SRV_PP_V2_SSL;
4284 return 0;
4285}
4286
4287/* parse the "send-proxy-v2-ssl-cn" server keyword */
4288static int srv_parse_send_proxy_cn(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4289{
4290 newsrv->pp_opts |= SRV_PP_V2;
4291 newsrv->pp_opts |= SRV_PP_V2_SSL;
4292 newsrv->pp_opts |= SRV_PP_V2_SSL_CN;
4293 return 0;
4294}
Emeric Brunf9c5c472012-10-11 15:28:34 +02004295
Willy Tarreau92faadf2012-10-10 23:04:25 +02004296/* parse the "ssl" server keyword */
4297static int srv_parse_ssl(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4298{
4299 newsrv->use_ssl = 1;
4300 if (global.connect_default_ciphers && !newsrv->ssl_ctx.ciphers)
4301 newsrv->ssl_ctx.ciphers = strdup(global.connect_default_ciphers);
4302 return 0;
4303}
4304
Emeric Brunef42d922012-10-11 16:11:36 +02004305/* parse the "verify" server keyword */
4306static int srv_parse_verify(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4307{
4308 if (!*args[*cur_arg + 1]) {
4309 if (err)
4310 memprintf(err, "'%s' : missing verify method", args[*cur_arg]);
4311 return ERR_ALERT | ERR_FATAL;
4312 }
4313
4314 if (strcmp(args[*cur_arg + 1], "none") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01004315 newsrv->ssl_ctx.verify = SSL_SOCK_VERIFY_NONE;
Emeric Brunef42d922012-10-11 16:11:36 +02004316 else if (strcmp(args[*cur_arg + 1], "required") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01004317 newsrv->ssl_ctx.verify = SSL_SOCK_VERIFY_REQUIRED;
Emeric Brunef42d922012-10-11 16:11:36 +02004318 else {
4319 if (err)
4320 memprintf(err, "'%s' : unknown verify method '%s', only 'none' and 'required' are supported\n",
4321 args[*cur_arg], args[*cur_arg + 1]);
4322 return ERR_ALERT | ERR_FATAL;
4323 }
4324
Evan Broderbe554312013-06-27 00:05:25 -07004325 return 0;
4326}
4327
4328/* parse the "verifyhost" server keyword */
4329static int srv_parse_verifyhost(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4330{
4331 if (!*args[*cur_arg + 1]) {
4332 if (err)
4333 memprintf(err, "'%s' : missing hostname to verify against", args[*cur_arg]);
4334 return ERR_ALERT | ERR_FATAL;
4335 }
4336
4337 newsrv->ssl_ctx.verify_host = strdup(args[*cur_arg + 1]);
4338
Emeric Brunef42d922012-10-11 16:11:36 +02004339 return 0;
4340}
4341
Emeric Brun42a3e202014-10-30 15:56:50 +01004342/* parse the "ssl-default-bind-options" keyword in global section */
4343static int ssl_parse_default_bind_options(char **args, int section_type, struct proxy *curpx,
4344 struct proxy *defpx, const char *file, int line,
4345 char **err) {
4346 int i = 1;
4347
4348 if (*(args[i]) == 0) {
4349 memprintf(err, "global statement '%s' expects an option as an argument.", args[0]);
4350 return -1;
4351 }
4352 while (*(args[i])) {
4353 if (!strcmp(args[i], "no-sslv3"))
4354 global.listen_default_ssloptions |= BC_SSL_O_NO_SSLV3;
4355 else if (!strcmp(args[i], "no-tlsv10"))
4356 global.listen_default_ssloptions |= BC_SSL_O_NO_TLSV10;
4357 else if (!strcmp(args[i], "no-tlsv11"))
4358 global.listen_default_ssloptions |= BC_SSL_O_NO_TLSV11;
4359 else if (!strcmp(args[i], "no-tlsv12"))
4360 global.listen_default_ssloptions |= BC_SSL_O_NO_TLSV12;
4361 else if (!strcmp(args[i], "force-sslv3"))
4362 global.listen_default_ssloptions |= BC_SSL_O_USE_SSLV3;
4363 else if (!strcmp(args[i], "force-tlsv10"))
4364 global.listen_default_ssloptions |= BC_SSL_O_USE_TLSV10;
4365 else if (!strcmp(args[i], "force-tlsv11")) {
4366#if SSL_OP_NO_TLSv1_1
4367 global.listen_default_ssloptions |= BC_SSL_O_USE_TLSV11;
4368#else
4369 memprintf(err, "'%s' '%s': library does not support protocol TLSv1.1", args[0], args[i]);
4370 return -1;
4371#endif
4372 }
4373 else if (!strcmp(args[i], "force-tlsv12")) {
4374#if SSL_OP_NO_TLSv1_2
4375 global.listen_default_ssloptions |= BC_SSL_O_USE_TLSV12;
4376#else
4377 memprintf(err, "'%s' '%s': library does not support protocol TLSv1.2", args[0], args[i]);
4378 return -1;
4379#endif
4380 }
4381 else if (!strcmp(args[i], "no-tls-tickets"))
4382 global.listen_default_ssloptions |= BC_SSL_O_NO_TLS_TICKETS;
4383 else {
4384 memprintf(err, "unknown option '%s' on global statement '%s'.", args[i], args[0]);
4385 return -1;
4386 }
4387 i++;
4388 }
4389 return 0;
4390}
4391
4392/* parse the "ssl-default-server-options" keyword in global section */
4393static int ssl_parse_default_server_options(char **args, int section_type, struct proxy *curpx,
4394 struct proxy *defpx, const char *file, int line,
4395 char **err) {
4396 int i = 1;
4397
4398 if (*(args[i]) == 0) {
4399 memprintf(err, "global statement '%s' expects an option as an argument.", args[0]);
4400 return -1;
4401 }
4402 while (*(args[i])) {
4403 if (!strcmp(args[i], "no-sslv3"))
4404 global.connect_default_ssloptions |= SRV_SSL_O_NO_SSLV3;
4405 else if (!strcmp(args[i], "no-tlsv10"))
4406 global.connect_default_ssloptions |= SRV_SSL_O_NO_TLSV10;
4407 else if (!strcmp(args[i], "no-tlsv11"))
4408 global.connect_default_ssloptions |= SRV_SSL_O_NO_TLSV11;
4409 else if (!strcmp(args[i], "no-tlsv12"))
4410 global.connect_default_ssloptions |= SRV_SSL_O_NO_TLSV12;
4411 else if (!strcmp(args[i], "force-sslv3"))
4412 global.connect_default_ssloptions |= SRV_SSL_O_USE_SSLV3;
4413 else if (!strcmp(args[i], "force-tlsv10"))
4414 global.connect_default_ssloptions |= SRV_SSL_O_USE_TLSV10;
4415 else if (!strcmp(args[i], "force-tlsv11")) {
4416#if SSL_OP_NO_TLSv1_1
4417 global.connect_default_ssloptions |= SRV_SSL_O_USE_TLSV11;
4418#else
4419 memprintf(err, "'%s' '%s': library does not support protocol TLSv1.1", args[0], args[i]);
4420 return -1;
4421#endif
4422 }
4423 else if (!strcmp(args[i], "force-tlsv12")) {
4424#if SSL_OP_NO_TLSv1_2
4425 global.connect_default_ssloptions |= SRV_SSL_O_USE_TLSV12;
4426#else
4427 memprintf(err, "'%s' '%s': library does not support protocol TLSv1.2", args[0], args[i]);
4428 return -1;
4429#endif
4430 }
4431 else if (!strcmp(args[i], "no-tls-tickets"))
4432 global.connect_default_ssloptions |= SRV_SSL_O_NO_TLS_TICKETS;
4433 else {
4434 memprintf(err, "unknown option '%s' on global statement '%s'.", args[i], args[0]);
4435 return -1;
4436 }
4437 i++;
4438 }
4439 return 0;
4440}
4441
Willy Tarreau7875d092012-09-10 08:20:03 +02004442/* Note: must not be declared <const> as its list will be overwritten.
4443 * Please take care of keeping this list alphabetically sorted.
4444 */
Willy Tarreaudc13c112013-06-21 23:16:39 +02004445static struct sample_fetch_kw_list sample_fetch_keywords = {ILH, {
Emeric Brun645ae792014-04-30 14:21:06 +02004446 { "ssl_bc", smp_fetch_ssl_fc, 0, NULL, SMP_T_BOOL, SMP_USE_L5SRV },
4447 { "ssl_bc_alg_keysize", smp_fetch_ssl_fc_alg_keysize, 0, NULL, SMP_T_UINT, SMP_USE_L5SRV },
4448 { "ssl_bc_cipher", smp_fetch_ssl_fc_cipher, 0, NULL, SMP_T_STR, SMP_USE_L5SRV },
4449 { "ssl_bc_protocol", smp_fetch_ssl_fc_protocol, 0, NULL, SMP_T_STR, SMP_USE_L5SRV },
Emeric Brunb73a9b02014-04-30 18:49:19 +02004450 { "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 +02004451 { "ssl_bc_use_keysize", smp_fetch_ssl_fc_use_keysize, 0, NULL, SMP_T_UINT, SMP_USE_L5SRV },
4452 { "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 +01004453 { "ssl_c_ca_err", smp_fetch_ssl_c_ca_err, 0, NULL, SMP_T_UINT, SMP_USE_L5CLI },
4454 { "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 +01004455 { "ssl_c_der", smp_fetch_ssl_x_der, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Willy Tarreau80aca902013-01-07 15:42:20 +01004456 { "ssl_c_err", smp_fetch_ssl_c_err, 0, NULL, SMP_T_UINT, SMP_USE_L5CLI },
Emeric Brunba841a12014-04-30 17:05:08 +02004457 { "ssl_c_i_dn", smp_fetch_ssl_x_i_dn, ARG2(0,STR,SINT), NULL, SMP_T_STR, SMP_USE_L5CLI },
4458 { "ssl_c_key_alg", smp_fetch_ssl_x_key_alg, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
4459 { "ssl_c_notafter", smp_fetch_ssl_x_notafter, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
4460 { "ssl_c_notbefore", smp_fetch_ssl_x_notbefore, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
4461 { "ssl_c_sig_alg", smp_fetch_ssl_x_sig_alg, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
4462 { "ssl_c_s_dn", smp_fetch_ssl_x_s_dn, ARG2(0,STR,SINT), NULL, SMP_T_STR, SMP_USE_L5CLI },
4463 { "ssl_c_serial", smp_fetch_ssl_x_serial, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
4464 { "ssl_c_sha1", smp_fetch_ssl_x_sha1, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Willy Tarreau80aca902013-01-07 15:42:20 +01004465 { "ssl_c_used", smp_fetch_ssl_c_used, 0, NULL, SMP_T_BOOL, SMP_USE_L5CLI },
4466 { "ssl_c_verify", smp_fetch_ssl_c_verify, 0, NULL, SMP_T_UINT, SMP_USE_L5CLI },
Emeric Brunba841a12014-04-30 17:05:08 +02004467 { "ssl_c_version", smp_fetch_ssl_x_version, 0, NULL, SMP_T_UINT, SMP_USE_L5CLI },
Emeric Brunb3cc4252014-10-29 19:03:26 +01004468 { "ssl_f_der", smp_fetch_ssl_x_der, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Emeric Brunba841a12014-04-30 17:05:08 +02004469 { "ssl_f_i_dn", smp_fetch_ssl_x_i_dn, ARG2(0,STR,SINT), NULL, SMP_T_STR, SMP_USE_L5CLI },
4470 { "ssl_f_key_alg", smp_fetch_ssl_x_key_alg, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
4471 { "ssl_f_notafter", smp_fetch_ssl_x_notafter, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
4472 { "ssl_f_notbefore", smp_fetch_ssl_x_notbefore, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
4473 { "ssl_f_sig_alg", smp_fetch_ssl_x_sig_alg, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
4474 { "ssl_f_s_dn", smp_fetch_ssl_x_s_dn, ARG2(0,STR,SINT), NULL, SMP_T_STR, SMP_USE_L5CLI },
4475 { "ssl_f_serial", smp_fetch_ssl_x_serial, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Emeric Brun55f4fa82014-04-30 17:11:25 +02004476 { "ssl_f_sha1", smp_fetch_ssl_x_sha1, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Emeric Brunba841a12014-04-30 17:05:08 +02004477 { "ssl_f_version", smp_fetch_ssl_x_version, 0, NULL, SMP_T_UINT, SMP_USE_L5CLI },
Willy Tarreau80aca902013-01-07 15:42:20 +01004478 { "ssl_fc", smp_fetch_ssl_fc, 0, NULL, SMP_T_BOOL, SMP_USE_L5CLI },
4479 { "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 +01004480 { "ssl_fc_cipher", smp_fetch_ssl_fc_cipher, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Willy Tarreau80aca902013-01-07 15:42:20 +01004481 { "ssl_fc_has_crt", smp_fetch_ssl_fc_has_crt, 0, NULL, SMP_T_BOOL, SMP_USE_L5CLI },
4482 { "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 +02004483#ifdef OPENSSL_NPN_NEGOTIATED
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01004484 { "ssl_fc_npn", smp_fetch_ssl_fc_npn, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Willy Tarreaua33c6542012-10-15 13:19:06 +02004485#endif
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01004486#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01004487 { "ssl_fc_alpn", smp_fetch_ssl_fc_alpn, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Willy Tarreauab861d32013-04-02 02:30:41 +02004488#endif
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01004489 { "ssl_fc_protocol", smp_fetch_ssl_fc_protocol, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Emeric Brunb73a9b02014-04-30 18:49:19 +02004490 { "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 +01004491 { "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 +01004492 { "ssl_fc_session_id", smp_fetch_ssl_fc_session_id, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
4493 { "ssl_fc_sni", smp_fetch_ssl_fc_sni, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Willy Tarreau7875d092012-09-10 08:20:03 +02004494 { NULL, NULL, 0, 0, 0 },
4495}};
4496
4497/* Note: must not be declared <const> as its list will be overwritten.
4498 * Please take care of keeping this list alphabetically sorted.
4499 */
Willy Tarreaudc13c112013-06-21 23:16:39 +02004500static struct acl_kw_list acl_kws = {ILH, {
Thierry FOURNIERc5a4e982014-03-05 16:07:08 +01004501 { "ssl_fc_sni_end", "ssl_fc_sni", PAT_MATCH_END },
4502 { "ssl_fc_sni_reg", "ssl_fc_sni", PAT_MATCH_REG },
Willy Tarreau8ed669b2013-01-11 15:49:37 +01004503 { /* END */ },
Willy Tarreau7875d092012-09-10 08:20:03 +02004504}};
4505
Willy Tarreau79eeafa2012-09-14 07:53:05 +02004506/* Note: must not be declared <const> as its list will be overwritten.
4507 * Please take care of keeping this list alphabetically sorted, doing so helps
4508 * all code contributors.
4509 * Optional keywords are also declared with a NULL ->parse() function so that
4510 * the config parser can report an appropriate error when a known keyword was
4511 * not enabled.
4512 */
Willy Tarreau51fb7652012-09-18 18:24:39 +02004513static struct bind_kw_list bind_kws = { "SSL", { }, {
Willy Tarreauab861d32013-04-02 02:30:41 +02004514 { "alpn", bind_parse_alpn, 1 }, /* set ALPN supported protocols */
Emeric Brunfb510ea2012-10-05 12:00:26 +02004515 { "ca-file", bind_parse_ca_file, 1 }, /* set CAfile to process verify on client cert */
Emeric Brun2d0c4822012-10-02 13:45:20 +02004516 { "ca-ignore-err", bind_parse_ignore_err, 1 }, /* set error IDs to ignore on verify depth > 0 */
4517 { "ciphers", bind_parse_ciphers, 1 }, /* set SSL cipher suite */
Emeric Brunfb510ea2012-10-05 12:00:26 +02004518 { "crl-file", bind_parse_crl_file, 1 }, /* set certificat revocation list file use on client cert verify */
Emeric Brun2d0c4822012-10-02 13:45:20 +02004519 { "crt", bind_parse_crt, 1 }, /* load SSL certificates from this location */
4520 { "crt-ignore-err", bind_parse_ignore_err, 1 }, /* set error IDs to ingore on verify depth == 0 */
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01004521 { "crt-list", bind_parse_crt_list, 1 }, /* load a list of crt from this location */
Emeric Brun2d0c4822012-10-02 13:45:20 +02004522 { "ecdhe", bind_parse_ecdhe, 1 }, /* defines named curve for elliptic curve Diffie-Hellman */
Emeric Brun2cb7ae52012-10-05 14:14:21 +02004523 { "force-sslv3", bind_parse_force_sslv3, 0 }, /* force SSLv3 */
4524 { "force-tlsv10", bind_parse_force_tlsv10, 0 }, /* force TLSv10 */
4525 { "force-tlsv11", bind_parse_force_tlsv11, 0 }, /* force TLSv11 */
4526 { "force-tlsv12", bind_parse_force_tlsv12, 0 }, /* force TLSv12 */
Emeric Brun9b3009b2012-10-05 11:55:06 +02004527 { "no-sslv3", bind_parse_no_sslv3, 0 }, /* disable SSLv3 */
4528 { "no-tlsv10", bind_parse_no_tlsv10, 0 }, /* disable TLSv10 */
4529 { "no-tlsv11", bind_parse_no_tlsv11, 0 }, /* disable TLSv11 */
4530 { "no-tlsv12", bind_parse_no_tlsv12, 0 }, /* disable TLSv12 */
Emeric Brun2d0c4822012-10-02 13:45:20 +02004531 { "no-tls-tickets", bind_parse_no_tls_tickets, 0 }, /* disable session resumption tickets */
Emeric Brun2d0c4822012-10-02 13:45:20 +02004532 { "ssl", bind_parse_ssl, 0 }, /* enable SSL processing */
Emmanuel Hocdet65623372013-01-24 17:17:15 +01004533 { "strict-sni", bind_parse_strict_sni, 0 }, /* refuse negotiation if sni doesn't match a certificate */
Emeric Brun2d0c4822012-10-02 13:45:20 +02004534 { "verify", bind_parse_verify, 1 }, /* set SSL verify method */
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02004535 { "npn", bind_parse_npn, 1 }, /* set NPN supported protocols */
Willy Tarreau79eeafa2012-09-14 07:53:05 +02004536 { NULL, NULL, 0 },
4537}};
Emeric Brun46591952012-05-18 15:47:34 +02004538
Willy Tarreau92faadf2012-10-10 23:04:25 +02004539/* Note: must not be declared <const> as its list will be overwritten.
4540 * Please take care of keeping this list alphabetically sorted, doing so helps
4541 * all code contributors.
4542 * Optional keywords are also declared with a NULL ->parse() function so that
4543 * the config parser can report an appropriate error when a known keyword was
4544 * not enabled.
4545 */
4546static struct srv_kw_list srv_kws = { "SSL", { }, {
Emeric Brunef42d922012-10-11 16:11:36 +02004547 { "ca-file", srv_parse_ca_file, 1, 0 }, /* set CAfile to process verify server cert */
Emeric Brunecc91fe2012-10-11 15:05:10 +02004548 { "check-ssl", srv_parse_check_ssl, 0, 0 }, /* enable SSL for health checks */
4549 { "ciphers", srv_parse_ciphers, 1, 0 }, /* select the cipher suite */
Emeric Brunef42d922012-10-11 16:11:36 +02004550 { "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 +02004551 { "crt", srv_parse_crt, 1, 0 }, /* set client certificate */
Emeric Brunecc91fe2012-10-11 15:05:10 +02004552 { "force-sslv3", srv_parse_force_sslv3, 0, 0 }, /* force SSLv3 */
4553 { "force-tlsv10", srv_parse_force_tlsv10, 0, 0 }, /* force TLSv10 */
4554 { "force-tlsv11", srv_parse_force_tlsv11, 0, 0 }, /* force TLSv11 */
4555 { "force-tlsv12", srv_parse_force_tlsv12, 0, 0 }, /* force TLSv12 */
4556 { "no-sslv3", srv_parse_no_sslv3, 0, 0 }, /* disable SSLv3 */
4557 { "no-tlsv10", srv_parse_no_tlsv10, 0, 0 }, /* disable TLSv10 */
4558 { "no-tlsv11", srv_parse_no_tlsv11, 0, 0 }, /* disable TLSv11 */
4559 { "no-tlsv12", srv_parse_no_tlsv12, 0, 0 }, /* disable TLSv12 */
Emeric Brunf9c5c472012-10-11 15:28:34 +02004560 { "no-tls-tickets", srv_parse_no_tls_tickets, 0, 0 }, /* disable session resumption tickets */
David Safb76832014-05-08 23:42:08 -04004561 { "send-proxy-v2-ssl", srv_parse_send_proxy_ssl, 0, 0 }, /* send PROXY protocol header v2 with SSL info */
4562 { "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 +02004563 { "ssl", srv_parse_ssl, 0, 0 }, /* enable SSL processing */
Emeric Brunef42d922012-10-11 16:11:36 +02004564 { "verify", srv_parse_verify, 1, 0 }, /* set SSL verify method */
Evan Broderbe554312013-06-27 00:05:25 -07004565 { "verifyhost", srv_parse_verifyhost, 1, 0 }, /* require that SSL cert verifies for hostname */
Willy Tarreau92faadf2012-10-10 23:04:25 +02004566 { NULL, NULL, 0, 0 },
4567}};
4568
Emeric Brun42a3e202014-10-30 15:56:50 +01004569static struct cfg_kw_list cfg_kws = {ILH, {
4570 { CFG_GLOBAL, "ssl-default-bind-options", ssl_parse_default_bind_options },
4571 { CFG_GLOBAL, "ssl-default-server-options", ssl_parse_default_server_options },
4572 { 0, NULL, NULL },
4573}};
4574
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02004575/* transport-layer operations for SSL sockets */
4576struct xprt_ops ssl_sock = {
Emeric Brun46591952012-05-18 15:47:34 +02004577 .snd_buf = ssl_sock_from_buf,
4578 .rcv_buf = ssl_sock_to_buf,
4579 .rcv_pipe = NULL,
4580 .snd_pipe = NULL,
4581 .shutr = NULL,
4582 .shutw = ssl_sock_shutw,
4583 .close = ssl_sock_close,
4584 .init = ssl_sock_init,
4585};
4586
4587__attribute__((constructor))
Willy Tarreau92faadf2012-10-10 23:04:25 +02004588static void __ssl_sock_init(void)
4589{
Emeric Brun46591952012-05-18 15:47:34 +02004590 STACK_OF(SSL_COMP)* cm;
4591
Willy Tarreau610f04b2014-02-13 11:36:41 +01004592#ifdef LISTEN_DEFAULT_CIPHERS
4593 global.listen_default_ciphers = LISTEN_DEFAULT_CIPHERS;
4594#endif
4595#ifdef CONNECT_DEFAULT_CIPHERS
4596 global.connect_default_ciphers = CONNECT_DEFAULT_CIPHERS;
4597#endif
4598 if (global.listen_default_ciphers)
4599 global.listen_default_ciphers = strdup(global.listen_default_ciphers);
4600 if (global.connect_default_ciphers)
4601 global.connect_default_ciphers = strdup(global.connect_default_ciphers);
Emeric Brun42a3e202014-10-30 15:56:50 +01004602 global.listen_default_ssloptions = BC_SSL_O_NONE;
4603 global.connect_default_ssloptions = SRV_SSL_O_NONE;
Willy Tarreau610f04b2014-02-13 11:36:41 +01004604
Emeric Brun46591952012-05-18 15:47:34 +02004605 SSL_library_init();
4606 cm = SSL_COMP_get_compression_methods();
4607 sk_SSL_COMP_zero(cm);
Willy Tarreau7875d092012-09-10 08:20:03 +02004608 sample_register_fetches(&sample_fetch_keywords);
4609 acl_register_keywords(&acl_kws);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02004610 bind_register_keywords(&bind_kws);
Willy Tarreau92faadf2012-10-10 23:04:25 +02004611 srv_register_keywords(&srv_kws);
Emeric Brun42a3e202014-10-30 15:56:50 +01004612 cfg_register_keywords(&cfg_kws);
Remi Gacogne5d769ca2015-05-28 16:23:00 +02004613
4614#ifndef OPENSSL_NO_DH
4615 ssl_dh_ptr_index = SSL_CTX_get_ex_new_index(0, NULL, NULL, NULL, NULL);
4616#endif
Emeric Brun46591952012-05-18 15:47:34 +02004617}
4618
Remi Gacogne269a02f2015-05-28 16:39:47 +02004619__attribute__((destructor))
4620static void __ssl_sock_deinit(void)
4621{
4622#ifndef OPENSSL_NO_DH
4623 if (local_dh_1024) {
4624 DH_free(local_dh_1024);
4625 local_dh_1024 = NULL;
4626 }
4627
4628 if (local_dh_2048) {
4629 DH_free(local_dh_2048);
4630 local_dh_2048 = NULL;
4631 }
4632
4633 if (local_dh_4096) {
4634 DH_free(local_dh_4096);
4635 local_dh_4096 = NULL;
4636 }
Remi Gacogne269a02f2015-05-28 16:39:47 +02004637#endif
4638
4639 ERR_remove_state(0);
4640 ERR_free_strings();
4641
4642 EVP_cleanup();
4643
4644#if OPENSSL_VERSION_NUMBER >= 0x00907000L
4645 CRYPTO_cleanup_all_ex_data();
4646#endif
4647}
4648
4649
Emeric Brun46591952012-05-18 15:47:34 +02004650/*
4651 * Local variables:
4652 * c-indent-level: 8
4653 * c-basic-offset: 8
4654 * End:
4655 */