blob: 0f7819b78830f7994913bfdada4236ec06b5192f [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;
117static DH *local_dh_8192 = NULL;
118#endif /* OPENSSL_NO_DH */
119
Emeric Brun4147b2e2014-06-16 18:36:30 +0200120#ifdef SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB
121struct certificate_ocsp {
122 struct ebmb_node key;
123 unsigned char key_data[OCSP_MAX_CERTID_ASN1_LENGTH];
124 struct chunk response;
Emeric Brun58484372014-06-20 15:46:13 +0200125 long expire;
Emeric Brun4147b2e2014-06-16 18:36:30 +0200126};
127
Emeric Brun58484372014-06-20 15:46:13 +0200128/*
129 * This function returns the number of seconds elapsed
130 * since the Epoch, 1970-01-01 00:00:00 +0000 (UTC) and the
131 * date presented un ASN1_GENERALIZEDTIME.
132 *
133 * In parsing error case, it returns -1.
134 */
135static long asn1_generalizedtime_to_epoch(ASN1_GENERALIZEDTIME *d)
136{
137 long epoch;
138 char *p, *end;
139 const unsigned short month_offset[12] = {
140 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334
141 };
142 int year, month;
143
144 if (!d || (d->type != V_ASN1_GENERALIZEDTIME)) return -1;
145
146 p = (char *)d->data;
147 end = p + d->length;
148
149 if (end - p < 4) return -1;
150 year = 1000 * (p[0] - '0') + 100 * (p[1] - '0') + 10 * (p[2] - '0') + p[3] - '0';
151 p += 4;
152 if (end - p < 2) return -1;
153 month = 10 * (p[0] - '0') + p[1] - '0';
154 if (month < 1 || month > 12) return -1;
155 /* Compute the number of seconds since 1 jan 1970 and the beginning of current month
156 We consider leap years and the current month (<marsh or not) */
157 epoch = ( ((year - 1970) * 365)
158 + ((year - (month < 3)) / 4 - (year - (month < 3)) / 100 + (year - (month < 3)) / 400)
159 - ((1970 - 1) / 4 - (1970 - 1) / 100 + (1970 - 1) / 400)
160 + month_offset[month-1]
161 ) * 24 * 60 * 60;
162 p += 2;
163 if (end - p < 2) return -1;
164 /* Add the number of seconds of completed days of current month */
165 epoch += (10 * (p[0] - '0') + p[1] - '0' - 1) * 24 * 60 * 60;
166 p += 2;
167 if (end - p < 2) return -1;
168 /* Add the completed hours of the current day */
169 epoch += (10 * (p[0] - '0') + p[1] - '0') * 60 * 60;
170 p += 2;
171 if (end - p < 2) return -1;
172 /* Add the completed minutes of the current hour */
173 epoch += (10 * (p[0] - '0') + p[1] - '0') * 60;
174 p += 2;
175 if (p == end) return -1;
176 /* Test if there is available seconds */
177 if (p[0] < '0' || p[0] > '9')
178 goto nosec;
179 if (end - p < 2) return -1;
180 /* Add the seconds of the current minute */
181 epoch += 10 * (p[0] - '0') + p[1] - '0';
182 p += 2;
183 if (p == end) return -1;
184 /* Ignore seconds float part if present */
185 if (p[0] == '.') {
186 do {
187 if (++p == end) return -1;
188 } while (p[0] >= '0' && p[0] <= '9');
189 }
190
191nosec:
192 if (p[0] == 'Z') {
193 if (end - p != 1) return -1;
194 return epoch;
195 }
196 else if (p[0] == '+') {
197 if (end - p != 5) return -1;
198 /* Apply timezone offset */
199 return epoch - ((10 * (p[1] - '0') + p[2] - '0') * 60 + (10 * (p[3] - '0') + p[4] - '0')) * 60;
200 }
201 else if (p[0] == '-') {
202 if (end - p != 5) return -1;
203 /* Apply timezone offset */
204 return epoch + ((10 * (p[1] - '0') + p[2] - '0') * 60 + (10 * (p[3] - '0') + p[4] - '0')) * 60;
205 }
206
207 return -1;
208}
209
Emeric Brun8d914d12014-06-20 15:37:32 +0200210static struct eb_root cert_ocsp_tree = EB_ROOT_UNIQUE;
Emeric Brun4147b2e2014-06-16 18:36:30 +0200211
212/* This function starts to check if the OCSP response (in DER format) contained
213 * in chunk 'ocsp_response' is valid (else exits on error).
214 * If 'cid' is not NULL, it will be compared to the OCSP certificate ID
215 * contained in the OCSP Response and exits on error if no match.
216 * If it's a valid OCSP Response:
217 * If 'ocsp' is not NULL, the chunk is copied in the OCSP response's container
218 * pointed by 'ocsp'.
219 * If 'ocsp' is NULL, the function looks up into the OCSP response's
220 * containers tree (using as index the ASN1 form of the OCSP Certificate ID extracted
221 * from the response) and exits on error if not found. Finally, If an OCSP response is
222 * already present in the container, it will be overwritten.
223 *
224 * Note: OCSP response containing more than one OCSP Single response is not
225 * considered valid.
226 *
227 * Returns 0 on success, 1 in error case.
228 */
229static int ssl_sock_load_ocsp_response(struct chunk *ocsp_response, struct certificate_ocsp *ocsp, OCSP_CERTID *cid, char **err)
230{
231 OCSP_RESPONSE *resp;
232 OCSP_BASICRESP *bs = NULL;
233 OCSP_SINGLERESP *sr;
234 unsigned char *p = (unsigned char *)ocsp_response->str;
235 int rc , count_sr;
Emeric Brun1135ea42014-06-20 15:44:34 +0200236 ASN1_GENERALIZEDTIME *revtime, *thisupd, *nextupd = NULL;
Emeric Brun4147b2e2014-06-16 18:36:30 +0200237 int reason;
238 int ret = 1;
239
240 resp = d2i_OCSP_RESPONSE(NULL, (const unsigned char **)&p, ocsp_response->len);
241 if (!resp) {
242 memprintf(err, "Unable to parse OCSP response");
243 goto out;
244 }
245
246 rc = OCSP_response_status(resp);
247 if (rc != OCSP_RESPONSE_STATUS_SUCCESSFUL) {
248 memprintf(err, "OCSP response status not successful");
249 goto out;
250 }
251
252 bs = OCSP_response_get1_basic(resp);
253 if (!bs) {
254 memprintf(err, "Failed to get basic response from OCSP Response");
255 goto out;
256 }
257
258 count_sr = OCSP_resp_count(bs);
259 if (count_sr > 1) {
260 memprintf(err, "OCSP response ignored because contains multiple single responses (%d)", count_sr);
261 goto out;
262 }
263
264 sr = OCSP_resp_get0(bs, 0);
265 if (!sr) {
266 memprintf(err, "Failed to get OCSP single response");
267 goto out;
268 }
269
270 rc = OCSP_single_get0_status(sr, &reason, &revtime, &thisupd, &nextupd);
271 if (rc != V_OCSP_CERTSTATUS_GOOD) {
272 memprintf(err, "OCSP single response: certificate status not good");
273 goto out;
274 }
275
Emeric Brun1135ea42014-06-20 15:44:34 +0200276 if (!nextupd) {
277 memprintf(err, "OCSP single response: missing nextupdate");
278 goto out;
279 }
280
Emeric Brunc8b27b62014-06-19 14:16:17 +0200281 rc = OCSP_check_validity(thisupd, nextupd, OCSP_MAX_RESPONSE_TIME_SKEW, -1);
Emeric Brun4147b2e2014-06-16 18:36:30 +0200282 if (!rc) {
283 memprintf(err, "OCSP single response: no longer valid.");
284 goto out;
285 }
286
287 if (cid) {
288 if (OCSP_id_cmp(sr->certId, cid)) {
289 memprintf(err, "OCSP single response: Certificate ID does not match certificate and issuer");
290 goto out;
291 }
292 }
293
294 if (!ocsp) {
295 unsigned char key[OCSP_MAX_CERTID_ASN1_LENGTH];
296 unsigned char *p;
297
298 rc = i2d_OCSP_CERTID(sr->certId, NULL);
299 if (!rc) {
300 memprintf(err, "OCSP single response: Unable to encode Certificate ID");
301 goto out;
302 }
303
304 if (rc > OCSP_MAX_CERTID_ASN1_LENGTH) {
305 memprintf(err, "OCSP single response: Certificate ID too long");
306 goto out;
307 }
308
309 p = key;
310 memset(key, 0, OCSP_MAX_CERTID_ASN1_LENGTH);
311 i2d_OCSP_CERTID(sr->certId, &p);
312 ocsp = (struct certificate_ocsp *)ebmb_lookup(&cert_ocsp_tree, key, OCSP_MAX_CERTID_ASN1_LENGTH);
313 if (!ocsp) {
314 memprintf(err, "OCSP single response: Certificate ID does not match any certificate or issuer");
315 goto out;
316 }
317 }
318
319 /* According to comments on "chunk_dup", the
320 previous chunk buffer will be freed */
321 if (!chunk_dup(&ocsp->response, ocsp_response)) {
322 memprintf(err, "OCSP response: Memory allocation error");
323 goto out;
324 }
325
Emeric Brun58484372014-06-20 15:46:13 +0200326 ocsp->expire = asn1_generalizedtime_to_epoch(nextupd) - OCSP_MAX_RESPONSE_TIME_SKEW;
327
Emeric Brun4147b2e2014-06-16 18:36:30 +0200328 ret = 0;
329out:
330 if (bs)
331 OCSP_BASICRESP_free(bs);
332
333 if (resp)
334 OCSP_RESPONSE_free(resp);
335
336 return ret;
337}
338/*
339 * External function use to update the OCSP response in the OCSP response's
340 * containers tree. The chunk 'ocsp_response' must contain the OCSP response
341 * to update in DER format.
342 *
343 * Returns 0 on success, 1 in error case.
344 */
345int ssl_sock_update_ocsp_response(struct chunk *ocsp_response, char **err)
346{
347 return ssl_sock_load_ocsp_response(ocsp_response, NULL, NULL, err);
348}
349
350/*
351 * This function load the OCSP Resonse in DER format contained in file at
352 * path 'ocsp_path' and call 'ssl_sock_load_ocsp_response'
353 *
354 * Returns 0 on success, 1 in error case.
355 */
356static int ssl_sock_load_ocsp_response_from_file(const char *ocsp_path, struct certificate_ocsp *ocsp, OCSP_CERTID *cid, char **err)
357{
358 int fd = -1;
359 int r = 0;
360 int ret = 1;
361
362 fd = open(ocsp_path, O_RDONLY);
363 if (fd == -1) {
364 memprintf(err, "Error opening OCSP response file");
365 goto end;
366 }
367
368 trash.len = 0;
369 while (trash.len < trash.size) {
370 r = read(fd, trash.str + trash.len, trash.size - trash.len);
371 if (r < 0) {
372 if (errno == EINTR)
373 continue;
374
375 memprintf(err, "Error reading OCSP response from file");
376 goto end;
377 }
378 else if (r == 0) {
379 break;
380 }
381 trash.len += r;
382 }
383
384 close(fd);
385 fd = -1;
386
387 ret = ssl_sock_load_ocsp_response(&trash, ocsp, cid, err);
388end:
389 if (fd != -1)
390 close(fd);
391
392 return ret;
393}
394
395/*
396 * Callback used to set OCSP status extension content in server hello.
397 */
398int ssl_sock_ocsp_stapling_cbk(SSL *ssl, void *arg)
399{
400 struct certificate_ocsp *ocsp = (struct certificate_ocsp *)arg;
401 char* ssl_buf;
402
403 if (!ocsp ||
404 !ocsp->response.str ||
Emeric Brun58484372014-06-20 15:46:13 +0200405 !ocsp->response.len ||
406 (ocsp->expire < now.tv_sec))
Emeric Brun4147b2e2014-06-16 18:36:30 +0200407 return SSL_TLSEXT_ERR_NOACK;
408
409 ssl_buf = OPENSSL_malloc(ocsp->response.len);
410 if (!ssl_buf)
411 return SSL_TLSEXT_ERR_NOACK;
412
413 memcpy(ssl_buf, ocsp->response.str, ocsp->response.len);
414 SSL_set_tlsext_status_ocsp_resp(ssl, ssl_buf, ocsp->response.len);
415
416 return SSL_TLSEXT_ERR_OK;
417}
418
419/*
420 * This function enables the handling of OCSP status extension on 'ctx' if a
421 * file name 'cert_path' suffixed using ".ocsp" is present.
422 * To enable OCSP status extension, the issuer's certificate is mandatory.
423 * It should be present in the certificate's extra chain builded from file
424 * 'cert_path'. If not found, the issuer certificate is loaded from a file
425 * named 'cert_path' suffixed using '.issuer'.
426 *
427 * In addition, ".ocsp" file content is loaded as a DER format of an OCSP
428 * response. If file is empty or content is not a valid OCSP response,
429 * OCSP status extension is enabled but OCSP response is ignored (a warning
430 * is displayed).
431 *
432 * Returns 1 if no ".ocsp" file found, 0 if OCSP status extension is
433 * succesfully enabled, or -1 in other error case.
434 */
435static int ssl_sock_load_ocsp(SSL_CTX *ctx, const char *cert_path)
436{
437
438 BIO *in = NULL;
439 X509 *x, *xi = NULL, *issuer = NULL;
440 STACK_OF(X509) *chain = NULL;
441 OCSP_CERTID *cid = NULL;
442 SSL *ssl;
443 char ocsp_path[MAXPATHLEN+1];
444 int i, ret = -1;
445 struct stat st;
446 struct certificate_ocsp *ocsp = NULL, *iocsp;
447 char *warn = NULL;
448 unsigned char *p;
449
450 snprintf(ocsp_path, MAXPATHLEN+1, "%s.ocsp", cert_path);
451
452 if (stat(ocsp_path, &st))
453 return 1;
454
455 ssl = SSL_new(ctx);
456 if (!ssl)
457 goto out;
458
459 x = SSL_get_certificate(ssl);
460 if (!x)
461 goto out;
462
463 /* Try to lookup for issuer in certificate extra chain */
464#ifdef SSL_CTRL_GET_EXTRA_CHAIN_CERTS
465 SSL_CTX_get_extra_chain_certs(ctx, &chain);
466#else
467 chain = ctx->extra_certs;
468#endif
469 for (i = 0; i < sk_X509_num(chain); i++) {
470 issuer = sk_X509_value(chain, i);
471 if (X509_check_issued(issuer, x) == X509_V_OK)
472 break;
473 else
474 issuer = NULL;
475 }
476
477 /* If not found try to load issuer from a suffixed file */
478 if (!issuer) {
479 char issuer_path[MAXPATHLEN+1];
480
481 in = BIO_new(BIO_s_file());
482 if (!in)
483 goto out;
484
485 snprintf(issuer_path, MAXPATHLEN+1, "%s.issuer", cert_path);
486 if (BIO_read_filename(in, issuer_path) <= 0)
487 goto out;
488
489 xi = PEM_read_bio_X509_AUX(in, NULL, ctx->default_passwd_callback, ctx->default_passwd_callback_userdata);
490 if (!xi)
491 goto out;
492
493 if (X509_check_issued(xi, x) != X509_V_OK)
494 goto out;
495
496 issuer = xi;
497 }
498
499 cid = OCSP_cert_to_id(0, x, issuer);
500 if (!cid)
501 goto out;
502
503 i = i2d_OCSP_CERTID(cid, NULL);
504 if (!i || (i > OCSP_MAX_CERTID_ASN1_LENGTH))
505 goto out;
506
507 ocsp = calloc(1, sizeof(struct certificate_ocsp));
508 if (!ocsp)
509 goto out;
510
511 p = ocsp->key_data;
512 i2d_OCSP_CERTID(cid, &p);
513
514 iocsp = (struct certificate_ocsp *)ebmb_insert(&cert_ocsp_tree, &ocsp->key, OCSP_MAX_CERTID_ASN1_LENGTH);
515 if (iocsp == ocsp)
516 ocsp = NULL;
517
518 SSL_CTX_set_tlsext_status_cb(ctx, ssl_sock_ocsp_stapling_cbk);
519 SSL_CTX_set_tlsext_status_arg(ctx, iocsp);
520
521 ret = 0;
522
523 warn = NULL;
524 if (ssl_sock_load_ocsp_response_from_file(ocsp_path, iocsp, cid, &warn)) {
525 memprintf(&warn, "Loading '%s': %s. Content will be ignored", ocsp_path, warn ? warn : "failure");
526 Warning("%s.\n", warn);
527 }
528
529out:
530 if (ssl)
531 SSL_free(ssl);
532
533 if (in)
534 BIO_free(in);
535
536 if (xi)
537 X509_free(xi);
538
539 if (cid)
540 OCSP_CERTID_free(cid);
541
542 if (ocsp)
543 free(ocsp);
544
545 if (warn)
546 free(warn);
547
548
549 return ret;
550}
551
552#endif
553
Emeric Brune1f38db2012-09-03 20:36:47 +0200554void ssl_sock_infocbk(const SSL *ssl, int where, int ret)
555{
556 struct connection *conn = (struct connection *)SSL_get_app_data(ssl);
557 (void)ret; /* shut gcc stupid warning */
Emeric Brund8b2bb52014-01-28 15:43:53 +0100558 BIO *write_bio;
Emeric Brune1f38db2012-09-03 20:36:47 +0200559
560 if (where & SSL_CB_HANDSHAKE_START) {
561 /* Disable renegotiation (CVE-2009-3555) */
Willy Tarreau20879a02012-12-03 16:32:10 +0100562 if (conn->flags & CO_FL_CONNECTED) {
Emeric Brune1f38db2012-09-03 20:36:47 +0200563 conn->flags |= CO_FL_ERROR;
Willy Tarreau20879a02012-12-03 16:32:10 +0100564 conn->err_code = CO_ER_SSL_RENEG;
565 }
Emeric Brune1f38db2012-09-03 20:36:47 +0200566 }
Emeric Brund8b2bb52014-01-28 15:43:53 +0100567
568 if ((where & SSL_CB_ACCEPT_LOOP) == SSL_CB_ACCEPT_LOOP) {
569 if (!(conn->xprt_st & SSL_SOCK_ST_FL_16K_WBFSIZE)) {
570 /* Long certificate chains optimz
571 If write and read bios are differents, we
572 consider that the buffering was activated,
573 so we rise the output buffer size from 4k
574 to 16k */
575 write_bio = SSL_get_wbio(ssl);
576 if (write_bio != SSL_get_rbio(ssl)) {
577 BIO_set_write_buffer_size(write_bio, 16384);
578 conn->xprt_st |= SSL_SOCK_ST_FL_16K_WBFSIZE;
579 }
580 }
581 }
Emeric Brunfc0421f2012-09-07 17:30:07 +0200582}
583
Emeric Brune64aef12012-09-21 13:15:06 +0200584/* Callback is called for each certificate of the chain during a verify
585 ok is set to 1 if preverify detect no error on current certificate.
586 Returns 0 to break the handshake, 1 otherwise. */
Evan Broderbe554312013-06-27 00:05:25 -0700587int ssl_sock_bind_verifycbk(int ok, X509_STORE_CTX *x_store)
Emeric Brune64aef12012-09-21 13:15:06 +0200588{
589 SSL *ssl;
590 struct connection *conn;
Emeric Brun81c00f02012-09-21 14:31:21 +0200591 int err, depth;
Emeric Brune64aef12012-09-21 13:15:06 +0200592
593 ssl = X509_STORE_CTX_get_ex_data(x_store, SSL_get_ex_data_X509_STORE_CTX_idx());
594 conn = (struct connection *)SSL_get_app_data(ssl);
595
Willy Tarreauf7bc57c2012-10-03 00:19:48 +0200596 conn->xprt_st |= SSL_SOCK_ST_FL_VERIFY_DONE;
Emeric Brune64aef12012-09-21 13:15:06 +0200597
Emeric Brun81c00f02012-09-21 14:31:21 +0200598 if (ok) /* no errors */
599 return ok;
600
601 depth = X509_STORE_CTX_get_error_depth(x_store);
602 err = X509_STORE_CTX_get_error(x_store);
603
604 /* check if CA error needs to be ignored */
605 if (depth > 0) {
Willy Tarreauf7bc57c2012-10-03 00:19:48 +0200606 if (!SSL_SOCK_ST_TO_CA_ERROR(conn->xprt_st)) {
607 conn->xprt_st |= SSL_SOCK_CA_ERROR_TO_ST(err);
608 conn->xprt_st |= SSL_SOCK_CAEDEPTH_TO_ST(depth);
Emeric Brunf282a812012-09-21 15:27:54 +0200609 }
610
Emeric Brun1eb20ef2012-12-03 13:24:29 +0100611 if (objt_listener(conn->target)->bind_conf->ca_ignerr & (1ULL << err)) {
612 ERR_clear_error();
Emeric Brun81c00f02012-09-21 14:31:21 +0200613 return 1;
Emeric Brun1eb20ef2012-12-03 13:24:29 +0100614 }
Emeric Brun81c00f02012-09-21 14:31:21 +0200615
Willy Tarreau20879a02012-12-03 16:32:10 +0100616 conn->err_code = CO_ER_SSL_CA_FAIL;
Emeric Brun81c00f02012-09-21 14:31:21 +0200617 return 0;
618 }
619
Willy Tarreauf7bc57c2012-10-03 00:19:48 +0200620 if (!SSL_SOCK_ST_TO_CRTERROR(conn->xprt_st))
621 conn->xprt_st |= SSL_SOCK_CRTERROR_TO_ST(err);
Emeric Brunf282a812012-09-21 15:27:54 +0200622
Emeric Brun81c00f02012-09-21 14:31:21 +0200623 /* check if certificate error needs to be ignored */
Emeric Brun1eb20ef2012-12-03 13:24:29 +0100624 if (objt_listener(conn->target)->bind_conf->crt_ignerr & (1ULL << err)) {
625 ERR_clear_error();
Emeric Brun81c00f02012-09-21 14:31:21 +0200626 return 1;
Emeric Brun1eb20ef2012-12-03 13:24:29 +0100627 }
Emeric Brun81c00f02012-09-21 14:31:21 +0200628
Willy Tarreau20879a02012-12-03 16:32:10 +0100629 conn->err_code = CO_ER_SSL_CRT_FAIL;
Emeric Brun81c00f02012-09-21 14:31:21 +0200630 return 0;
Emeric Brune64aef12012-09-21 13:15:06 +0200631}
632
Emeric Brun29f037d2014-04-25 19:05:36 +0200633/* Callback is called for ssl protocol analyse */
634void ssl_sock_msgcbk(int write_p, int version, int content_type, const void *buf, size_t len, SSL *ssl, void *arg)
635{
Emeric Brun29f037d2014-04-25 19:05:36 +0200636#ifdef TLS1_RT_HEARTBEAT
637 /* test heartbeat received (write_p is set to 0
638 for a received record) */
Willy Tarreauf51c6982014-04-25 20:02:39 +0200639 if ((content_type == TLS1_RT_HEARTBEAT) && (write_p == 0)) {
Willy Tarreau84815002014-04-25 21:40:27 +0200640 struct connection *conn = (struct connection *)SSL_get_app_data(ssl);
Willy Tarreauf51c6982014-04-25 20:02:39 +0200641 const unsigned char *p = buf;
642 unsigned int payload;
643
Emeric Brun29f037d2014-04-25 19:05:36 +0200644 conn->xprt_st |= SSL_SOCK_RECV_HEARTBEAT;
Willy Tarreauf51c6982014-04-25 20:02:39 +0200645
646 /* Check if this is a CVE-2014-0160 exploitation attempt. */
647 if (*p != TLS1_HB_REQUEST)
648 return;
649
Willy Tarreauaeed6722014-04-25 23:59:58 +0200650 if (len < 1 + 2 + 16) /* 1 type + 2 size + 0 payload + 16 padding */
Willy Tarreauf51c6982014-04-25 20:02:39 +0200651 goto kill_it;
652
653 payload = (p[1] * 256) + p[2];
Willy Tarreau3b2fdb62014-04-25 23:44:22 +0200654 if (3 + payload + 16 <= len)
Willy Tarreauf51c6982014-04-25 20:02:39 +0200655 return; /* OK no problem */
Willy Tarreauaeed6722014-04-25 23:59:58 +0200656 kill_it:
Willy Tarreau3b2fdb62014-04-25 23:44:22 +0200657 /* We have a clear heartbleed attack (CVE-2014-0160), the
658 * advertised payload is larger than the advertised packet
659 * length, so we have garbage in the buffer between the
660 * payload and the end of the buffer (p+len). We can't know
661 * if the SSL stack is patched, and we don't know if we can
662 * safely wipe out the area between p+3+len and payload.
663 * So instead, we prevent the response from being sent by
664 * setting the max_send_fragment to 0 and we report an SSL
665 * error, which will kill this connection. It will be reported
666 * above as SSL_ERROR_SSL while an other handshake failure with
Willy Tarreauf51c6982014-04-25 20:02:39 +0200667 * a heartbeat message will be reported as SSL_ERROR_SYSCALL.
668 */
Willy Tarreau3b2fdb62014-04-25 23:44:22 +0200669 ssl->max_send_fragment = 0;
Willy Tarreauf51c6982014-04-25 20:02:39 +0200670 SSLerr(SSL_F_TLS1_HEARTBEAT, SSL_R_SSL_HANDSHAKE_FAILURE);
671 return;
672 }
Emeric Brun29f037d2014-04-25 19:05:36 +0200673#endif
674}
675
Willy Tarreau6c9a3d52012-10-18 18:57:14 +0200676#ifdef OPENSSL_NPN_NEGOTIATED
677/* This callback is used so that the server advertises the list of
678 * negociable protocols for NPN.
679 */
680static int ssl_sock_advertise_npn_protos(SSL *s, const unsigned char **data,
681 unsigned int *len, void *arg)
682{
683 struct bind_conf *conf = arg;
684
685 *data = (const unsigned char *)conf->npn_str;
686 *len = conf->npn_len;
687 return SSL_TLSEXT_ERR_OK;
688}
689#endif
690
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +0100691#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Willy Tarreauab861d32013-04-02 02:30:41 +0200692/* This callback is used so that the server advertises the list of
693 * negociable protocols for ALPN.
694 */
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +0100695static int ssl_sock_advertise_alpn_protos(SSL *s, const unsigned char **out,
696 unsigned char *outlen,
697 const unsigned char *server,
698 unsigned int server_len, void *arg)
Willy Tarreauab861d32013-04-02 02:30:41 +0200699{
700 struct bind_conf *conf = arg;
701
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +0100702 if (SSL_select_next_proto((unsigned char**) out, outlen, (const unsigned char *)conf->alpn_str,
703 conf->alpn_len, server, server_len) != OPENSSL_NPN_NEGOTIATED) {
704 return SSL_TLSEXT_ERR_NOACK;
705 }
Willy Tarreauab861d32013-04-02 02:30:41 +0200706 return SSL_TLSEXT_ERR_OK;
707}
708#endif
709
Emeric Brunfc0421f2012-09-07 17:30:07 +0200710#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
711/* Sets the SSL ctx of <ssl> to match the advertised server name. Returns a
712 * warning when no match is found, which implies the default (first) cert
713 * will keep being used.
714 */
Willy Tarreau2a65ff02012-09-13 17:54:29 +0200715static int ssl_sock_switchctx_cbk(SSL *ssl, int *al, struct bind_conf *s)
Emeric Brunfc0421f2012-09-07 17:30:07 +0200716{
717 const char *servername;
718 const char *wildp = NULL;
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +0200719 struct ebmb_node *node, *n;
Emeric Brunfc0421f2012-09-07 17:30:07 +0200720 int i;
721 (void)al; /* shut gcc stupid warning */
722
723 servername = SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name);
Emmanuel Hocdet65623372013-01-24 17:17:15 +0100724 if (!servername) {
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +0200725 return (s->strict_sni ?
726 SSL_TLSEXT_ERR_ALERT_FATAL :
Emmanuel Hocdet79274e22013-05-31 12:47:44 +0200727 SSL_TLSEXT_ERR_NOACK);
Emmanuel Hocdet65623372013-01-24 17:17:15 +0100728 }
Emeric Brunfc0421f2012-09-07 17:30:07 +0200729
Willy Tarreau19d14ef2012-10-29 16:51:55 +0100730 for (i = 0; i < trash.size; i++) {
Emeric Brunfc0421f2012-09-07 17:30:07 +0200731 if (!servername[i])
732 break;
Willy Tarreau19d14ef2012-10-29 16:51:55 +0100733 trash.str[i] = tolower(servername[i]);
734 if (!wildp && (trash.str[i] == '.'))
735 wildp = &trash.str[i];
Emeric Brunfc0421f2012-09-07 17:30:07 +0200736 }
Willy Tarreau19d14ef2012-10-29 16:51:55 +0100737 trash.str[i] = 0;
Emeric Brunfc0421f2012-09-07 17:30:07 +0200738
739 /* lookup in full qualified names */
Willy Tarreau19d14ef2012-10-29 16:51:55 +0100740 node = ebst_lookup(&s->sni_ctx, trash.str);
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +0200741
742 /* lookup a not neg filter */
743 for (n = node; n; n = ebmb_next_dup(n)) {
744 if (!container_of(n, struct sni_ctx, name)->neg) {
745 node = n;
746 break;
Emmanuel Hocdet65623372013-01-24 17:17:15 +0100747 }
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +0200748 }
749 if (!node && wildp) {
750 /* lookup in wildcards names */
Emeric Brunfc0421f2012-09-07 17:30:07 +0200751 node = ebst_lookup(&s->sni_w_ctx, wildp);
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +0200752 }
753 if (!node || container_of(node, struct sni_ctx, name)->neg) {
754 return (s->strict_sni ?
755 SSL_TLSEXT_ERR_ALERT_FATAL :
756 SSL_TLSEXT_ERR_ALERT_WARNING);
Emeric Brunfc0421f2012-09-07 17:30:07 +0200757 }
758
759 /* switch ctx */
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +0200760 SSL_set_SSL_CTX(ssl, container_of(node, struct sni_ctx, name)->ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +0200761 return SSL_TLSEXT_ERR_OK;
762}
763#endif /* SSL_CTRL_SET_TLSEXT_HOSTNAME */
764
Emeric Bruna4bcd9a2012-09-20 16:19:02 +0200765#ifndef OPENSSL_NO_DH
Remi Gacognef46cd6e2014-06-12 14:58:40 +0200766
767static DH * ssl_get_dh_1024(void)
768{
769#if OPENSSL_VERSION_NUMBER < 0x0090801fL
770 static const unsigned char rfc_2409_prime_1024[] = {
771 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xC9,0x0F,0xDA,0xA2,
772 0x21,0x68,0xC2,0x34,0xC4,0xC6,0x62,0x8B,0x80,0xDC,0x1C,0xD1,
773 0x29,0x02,0x4E,0x08,0x8A,0x67,0xCC,0x74,0x02,0x0B,0xBE,0xA6,
774 0x3B,0x13,0x9B,0x22,0x51,0x4A,0x08,0x79,0x8E,0x34,0x04,0xDD,
775 0xEF,0x95,0x19,0xB3,0xCD,0x3A,0x43,0x1B,0x30,0x2B,0x0A,0x6D,
776 0xF2,0x5F,0x14,0x37,0x4F,0xE1,0x35,0x6D,0x6D,0x51,0xC2,0x45,
777 0xE4,0x85,0xB5,0x76,0x62,0x5E,0x7E,0xC6,0xF4,0x4C,0x42,0xE9,
778 0xA6,0x37,0xED,0x6B,0x0B,0xFF,0x5C,0xB6,0xF4,0x06,0xB7,0xED,
779 0xEE,0x38,0x6B,0xFB,0x5A,0x89,0x9F,0xA5,0xAE,0x9F,0x24,0x11,
780 0x7C,0x4B,0x1F,0xE6,0x49,0x28,0x66,0x51,0xEC,0xE6,0x53,0x81,
781 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
782 };
783#endif
784 DH *dh = DH_new();
785 if (dh) {
786#if OPENSSL_VERSION_NUMBER >= 0x0090801fL
787 dh->p = get_rfc2409_prime_1024(NULL);
788#else
789 dh->p = BN_bin2bn(rfc_2409_prime_1024, sizeof rfc_2409_prime_1024, NULL);
790#endif
791 /* See RFC 2409, Section 6 "Oakley Groups"
792 for the reason why 2 is used as generator.
793 */
794 BN_dec2bn(&dh->g, "2");
795 if (!dh->p || !dh->g) {
796 DH_free(dh);
797 dh = NULL;
798 }
799 }
800 return dh;
801}
802
803static DH *ssl_get_dh_2048(void)
804{
805#if OPENSSL_VERSION_NUMBER < 0x0090801fL
806 static const unsigned char rfc_3526_prime_2048[] = {
807 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xC9,0x0F,0xDA,0xA2,
808 0x21,0x68,0xC2,0x34,0xC4,0xC6,0x62,0x8B,0x80,0xDC,0x1C,0xD1,
809 0x29,0x02,0x4E,0x08,0x8A,0x67,0xCC,0x74,0x02,0x0B,0xBE,0xA6,
810 0x3B,0x13,0x9B,0x22,0x51,0x4A,0x08,0x79,0x8E,0x34,0x04,0xDD,
811 0xEF,0x95,0x19,0xB3,0xCD,0x3A,0x43,0x1B,0x30,0x2B,0x0A,0x6D,
812 0xF2,0x5F,0x14,0x37,0x4F,0xE1,0x35,0x6D,0x6D,0x51,0xC2,0x45,
813 0xE4,0x85,0xB5,0x76,0x62,0x5E,0x7E,0xC6,0xF4,0x4C,0x42,0xE9,
814 0xA6,0x37,0xED,0x6B,0x0B,0xFF,0x5C,0xB6,0xF4,0x06,0xB7,0xED,
815 0xEE,0x38,0x6B,0xFB,0x5A,0x89,0x9F,0xA5,0xAE,0x9F,0x24,0x11,
816 0x7C,0x4B,0x1F,0xE6,0x49,0x28,0x66,0x51,0xEC,0xE4,0x5B,0x3D,
817 0xC2,0x00,0x7C,0xB8,0xA1,0x63,0xBF,0x05,0x98,0xDA,0x48,0x36,
818 0x1C,0x55,0xD3,0x9A,0x69,0x16,0x3F,0xA8,0xFD,0x24,0xCF,0x5F,
819 0x83,0x65,0x5D,0x23,0xDC,0xA3,0xAD,0x96,0x1C,0x62,0xF3,0x56,
820 0x20,0x85,0x52,0xBB,0x9E,0xD5,0x29,0x07,0x70,0x96,0x96,0x6D,
821 0x67,0x0C,0x35,0x4E,0x4A,0xBC,0x98,0x04,0xF1,0x74,0x6C,0x08,
822 0xCA,0x18,0x21,0x7C,0x32,0x90,0x5E,0x46,0x2E,0x36,0xCE,0x3B,
823 0xE3,0x9E,0x77,0x2C,0x18,0x0E,0x86,0x03,0x9B,0x27,0x83,0xA2,
824 0xEC,0x07,0xA2,0x8F,0xB5,0xC5,0x5D,0xF0,0x6F,0x4C,0x52,0xC9,
825 0xDE,0x2B,0xCB,0xF6,0x95,0x58,0x17,0x18,0x39,0x95,0x49,0x7C,
826 0xEA,0x95,0x6A,0xE5,0x15,0xD2,0x26,0x18,0x98,0xFA,0x05,0x10,
827 0x15,0x72,0x8E,0x5A,0x8A,0xAC,0xAA,0x68,0xFF,0xFF,0xFF,0xFF,
828 0xFF,0xFF,0xFF,0xFF,
829 };
830#endif
831 DH *dh = DH_new();
832 if (dh) {
833#if OPENSSL_VERSION_NUMBER >= 0x0090801fL
834 dh->p = get_rfc3526_prime_2048(NULL);
835#else
836 dh->p = BN_bin2bn(rfc_3526_prime_2048, sizeof rfc_3526_prime_2048, NULL);
837#endif
838 /* See RFC 3526, Section 3 "2048-bit MODP Group"
839 for the reason why 2 is used as generator.
840 */
841 BN_dec2bn(&dh->g, "2");
842 if (!dh->p || !dh->g) {
843 DH_free(dh);
844 dh = NULL;
845 }
846 }
847 return dh;
848}
849
850static DH *ssl_get_dh_4096(void)
851{
852#if OPENSSL_VERSION_NUMBER < 0x0090801fL
853 static const unsigned char rfc_3526_prime_4096[] = {
854 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xC9,0x0F,0xDA,0xA2,
855 0x21,0x68,0xC2,0x34,0xC4,0xC6,0x62,0x8B,0x80,0xDC,0x1C,0xD1,
856 0x29,0x02,0x4E,0x08,0x8A,0x67,0xCC,0x74,0x02,0x0B,0xBE,0xA6,
857 0x3B,0x13,0x9B,0x22,0x51,0x4A,0x08,0x79,0x8E,0x34,0x04,0xDD,
858 0xEF,0x95,0x19,0xB3,0xCD,0x3A,0x43,0x1B,0x30,0x2B,0x0A,0x6D,
859 0xF2,0x5F,0x14,0x37,0x4F,0xE1,0x35,0x6D,0x6D,0x51,0xC2,0x45,
860 0xE4,0x85,0xB5,0x76,0x62,0x5E,0x7E,0xC6,0xF4,0x4C,0x42,0xE9,
861 0xA6,0x37,0xED,0x6B,0x0B,0xFF,0x5C,0xB6,0xF4,0x06,0xB7,0xED,
862 0xEE,0x38,0x6B,0xFB,0x5A,0x89,0x9F,0xA5,0xAE,0x9F,0x24,0x11,
863 0x7C,0x4B,0x1F,0xE6,0x49,0x28,0x66,0x51,0xEC,0xE4,0x5B,0x3D,
864 0xC2,0x00,0x7C,0xB8,0xA1,0x63,0xBF,0x05,0x98,0xDA,0x48,0x36,
865 0x1C,0x55,0xD3,0x9A,0x69,0x16,0x3F,0xA8,0xFD,0x24,0xCF,0x5F,
866 0x83,0x65,0x5D,0x23,0xDC,0xA3,0xAD,0x96,0x1C,0x62,0xF3,0x56,
867 0x20,0x85,0x52,0xBB,0x9E,0xD5,0x29,0x07,0x70,0x96,0x96,0x6D,
868 0x67,0x0C,0x35,0x4E,0x4A,0xBC,0x98,0x04,0xF1,0x74,0x6C,0x08,
869 0xCA,0x18,0x21,0x7C,0x32,0x90,0x5E,0x46,0x2E,0x36,0xCE,0x3B,
870 0xE3,0x9E,0x77,0x2C,0x18,0x0E,0x86,0x03,0x9B,0x27,0x83,0xA2,
871 0xEC,0x07,0xA2,0x8F,0xB5,0xC5,0x5D,0xF0,0x6F,0x4C,0x52,0xC9,
872 0xDE,0x2B,0xCB,0xF6,0x95,0x58,0x17,0x18,0x39,0x95,0x49,0x7C,
873 0xEA,0x95,0x6A,0xE5,0x15,0xD2,0x26,0x18,0x98,0xFA,0x05,0x10,
874 0x15,0x72,0x8E,0x5A,0x8A,0xAA,0xC4,0x2D,0xAD,0x33,0x17,0x0D,
875 0x04,0x50,0x7A,0x33,0xA8,0x55,0x21,0xAB,0xDF,0x1C,0xBA,0x64,
876 0xEC,0xFB,0x85,0x04,0x58,0xDB,0xEF,0x0A,0x8A,0xEA,0x71,0x57,
877 0x5D,0x06,0x0C,0x7D,0xB3,0x97,0x0F,0x85,0xA6,0xE1,0xE4,0xC7,
878 0xAB,0xF5,0xAE,0x8C,0xDB,0x09,0x33,0xD7,0x1E,0x8C,0x94,0xE0,
879 0x4A,0x25,0x61,0x9D,0xCE,0xE3,0xD2,0x26,0x1A,0xD2,0xEE,0x6B,
880 0xF1,0x2F,0xFA,0x06,0xD9,0x8A,0x08,0x64,0xD8,0x76,0x02,0x73,
881 0x3E,0xC8,0x6A,0x64,0x52,0x1F,0x2B,0x18,0x17,0x7B,0x20,0x0C,
882 0xBB,0xE1,0x17,0x57,0x7A,0x61,0x5D,0x6C,0x77,0x09,0x88,0xC0,
883 0xBA,0xD9,0x46,0xE2,0x08,0xE2,0x4F,0xA0,0x74,0xE5,0xAB,0x31,
884 0x43,0xDB,0x5B,0xFC,0xE0,0xFD,0x10,0x8E,0x4B,0x82,0xD1,0x20,
885 0xA9,0x21,0x08,0x01,0x1A,0x72,0x3C,0x12,0xA7,0x87,0xE6,0xD7,
886 0x88,0x71,0x9A,0x10,0xBD,0xBA,0x5B,0x26,0x99,0xC3,0x27,0x18,
887 0x6A,0xF4,0xE2,0x3C,0x1A,0x94,0x68,0x34,0xB6,0x15,0x0B,0xDA,
888 0x25,0x83,0xE9,0xCA,0x2A,0xD4,0x4C,0xE8,0xDB,0xBB,0xC2,0xDB,
889 0x04,0xDE,0x8E,0xF9,0x2E,0x8E,0xFC,0x14,0x1F,0xBE,0xCA,0xA6,
890 0x28,0x7C,0x59,0x47,0x4E,0x6B,0xC0,0x5D,0x99,0xB2,0x96,0x4F,
891 0xA0,0x90,0xC3,0xA2,0x23,0x3B,0xA1,0x86,0x51,0x5B,0xE7,0xED,
892 0x1F,0x61,0x29,0x70,0xCE,0xE2,0xD7,0xAF,0xB8,0x1B,0xDD,0x76,
893 0x21,0x70,0x48,0x1C,0xD0,0x06,0x91,0x27,0xD5,0xB0,0x5A,0xA9,
894 0x93,0xB4,0xEA,0x98,0x8D,0x8F,0xDD,0xC1,0x86,0xFF,0xB7,0xDC,
895 0x90,0xA6,0xC0,0x8F,0x4D,0xF4,0x35,0xC9,0x34,0x06,0x31,0x99,
896 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
897 };
898#endif
899 DH *dh = DH_new();
900 if (dh) {
901#if OPENSSL_VERSION_NUMBER >= 0x0090801fL
902 dh->p = get_rfc3526_prime_4096(NULL);
903#else
904 dh->p = BN_bin2bn(rfc_3526_prime_4096, sizeof rfc_3526_prime_4096, NULL);
905#endif
906 /* See RFC 3526, Section 5 "4096-bit MODP Group"
907 for the reason why 2 is used as generator.
908 */
909 BN_dec2bn(&dh->g, "2");
910 if (!dh->p || !dh->g) {
911 DH_free(dh);
912 dh = NULL;
913 }
914 }
915 return dh;
916}
917
918static DH *ssl_get_dh_8192(void)
919{
920#if OPENSSL_VERSION_NUMBER < 0x0090801fL
921 static const unsigned char rfc_3526_prime_8192[] = {
922 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xC9,0x0F,0xDA,0xA2,
923 0x21,0x68,0xC2,0x34,0xC4,0xC6,0x62,0x8B,0x80,0xDC,0x1C,0xD1,
924 0x29,0x02,0x4E,0x08,0x8A,0x67,0xCC,0x74,0x02,0x0B,0xBE,0xA6,
925 0x3B,0x13,0x9B,0x22,0x51,0x4A,0x08,0x79,0x8E,0x34,0x04,0xDD,
926 0xEF,0x95,0x19,0xB3,0xCD,0x3A,0x43,0x1B,0x30,0x2B,0x0A,0x6D,
927 0xF2,0x5F,0x14,0x37,0x4F,0xE1,0x35,0x6D,0x6D,0x51,0xC2,0x45,
928 0xE4,0x85,0xB5,0x76,0x62,0x5E,0x7E,0xC6,0xF4,0x4C,0x42,0xE9,
929 0xA6,0x37,0xED,0x6B,0x0B,0xFF,0x5C,0xB6,0xF4,0x06,0xB7,0xED,
930 0xEE,0x38,0x6B,0xFB,0x5A,0x89,0x9F,0xA5,0xAE,0x9F,0x24,0x11,
931 0x7C,0x4B,0x1F,0xE6,0x49,0x28,0x66,0x51,0xEC,0xE4,0x5B,0x3D,
932 0xC2,0x00,0x7C,0xB8,0xA1,0x63,0xBF,0x05,0x98,0xDA,0x48,0x36,
933 0x1C,0x55,0xD3,0x9A,0x69,0x16,0x3F,0xA8,0xFD,0x24,0xCF,0x5F,
934 0x83,0x65,0x5D,0x23,0xDC,0xA3,0xAD,0x96,0x1C,0x62,0xF3,0x56,
935 0x20,0x85,0x52,0xBB,0x9E,0xD5,0x29,0x07,0x70,0x96,0x96,0x6D,
936 0x67,0x0C,0x35,0x4E,0x4A,0xBC,0x98,0x04,0xF1,0x74,0x6C,0x08,
937 0xCA,0x18,0x21,0x7C,0x32,0x90,0x5E,0x46,0x2E,0x36,0xCE,0x3B,
938 0xE3,0x9E,0x77,0x2C,0x18,0x0E,0x86,0x03,0x9B,0x27,0x83,0xA2,
939 0xEC,0x07,0xA2,0x8F,0xB5,0xC5,0x5D,0xF0,0x6F,0x4C,0x52,0xC9,
940 0xDE,0x2B,0xCB,0xF6,0x95,0x58,0x17,0x18,0x39,0x95,0x49,0x7C,
941 0xEA,0x95,0x6A,0xE5,0x15,0xD2,0x26,0x18,0x98,0xFA,0x05,0x10,
942 0x15,0x72,0x8E,0x5A,0x8A,0xAA,0xC4,0x2D,0xAD,0x33,0x17,0x0D,
943 0x04,0x50,0x7A,0x33,0xA8,0x55,0x21,0xAB,0xDF,0x1C,0xBA,0x64,
944 0xEC,0xFB,0x85,0x04,0x58,0xDB,0xEF,0x0A,0x8A,0xEA,0x71,0x57,
945 0x5D,0x06,0x0C,0x7D,0xB3,0x97,0x0F,0x85,0xA6,0xE1,0xE4,0xC7,
946 0xAB,0xF5,0xAE,0x8C,0xDB,0x09,0x33,0xD7,0x1E,0x8C,0x94,0xE0,
947 0x4A,0x25,0x61,0x9D,0xCE,0xE3,0xD2,0x26,0x1A,0xD2,0xEE,0x6B,
948 0xF1,0x2F,0xFA,0x06,0xD9,0x8A,0x08,0x64,0xD8,0x76,0x02,0x73,
949 0x3E,0xC8,0x6A,0x64,0x52,0x1F,0x2B,0x18,0x17,0x7B,0x20,0x0C,
950 0xBB,0xE1,0x17,0x57,0x7A,0x61,0x5D,0x6C,0x77,0x09,0x88,0xC0,
951 0xBA,0xD9,0x46,0xE2,0x08,0xE2,0x4F,0xA0,0x74,0xE5,0xAB,0x31,
952 0x43,0xDB,0x5B,0xFC,0xE0,0xFD,0x10,0x8E,0x4B,0x82,0xD1,0x20,
953 0xA9,0x21,0x08,0x01,0x1A,0x72,0x3C,0x12,0xA7,0x87,0xE6,0xD7,
954 0x88,0x71,0x9A,0x10,0xBD,0xBA,0x5B,0x26,0x99,0xC3,0x27,0x18,
955 0x6A,0xF4,0xE2,0x3C,0x1A,0x94,0x68,0x34,0xB6,0x15,0x0B,0xDA,
956 0x25,0x83,0xE9,0xCA,0x2A,0xD4,0x4C,0xE8,0xDB,0xBB,0xC2,0xDB,
957 0x04,0xDE,0x8E,0xF9,0x2E,0x8E,0xFC,0x14,0x1F,0xBE,0xCA,0xA6,
958 0x28,0x7C,0x59,0x47,0x4E,0x6B,0xC0,0x5D,0x99,0xB2,0x96,0x4F,
959 0xA0,0x90,0xC3,0xA2,0x23,0x3B,0xA1,0x86,0x51,0x5B,0xE7,0xED,
960 0x1F,0x61,0x29,0x70,0xCE,0xE2,0xD7,0xAF,0xB8,0x1B,0xDD,0x76,
961 0x21,0x70,0x48,0x1C,0xD0,0x06,0x91,0x27,0xD5,0xB0,0x5A,0xA9,
962 0x93,0xB4,0xEA,0x98,0x8D,0x8F,0xDD,0xC1,0x86,0xFF,0xB7,0xDC,
963 0x90,0xA6,0xC0,0x8F,0x4D,0xF4,0x35,0xC9,0x34,0x02,0x84,0x92,
964 0x36,0xC3,0xFA,0xB4,0xD2,0x7C,0x70,0x26,0xC1,0xD4,0xDC,0xB2,
965 0x60,0x26,0x46,0xDE,0xC9,0x75,0x1E,0x76,0x3D,0xBA,0x37,0xBD,
966 0xF8,0xFF,0x94,0x06,0xAD,0x9E,0x53,0x0E,0xE5,0xDB,0x38,0x2F,
967 0x41,0x30,0x01,0xAE,0xB0,0x6A,0x53,0xED,0x90,0x27,0xD8,0x31,
968 0x17,0x97,0x27,0xB0,0x86,0x5A,0x89,0x18,0xDA,0x3E,0xDB,0xEB,
969 0xCF,0x9B,0x14,0xED,0x44,0xCE,0x6C,0xBA,0xCE,0xD4,0xBB,0x1B,
970 0xDB,0x7F,0x14,0x47,0xE6,0xCC,0x25,0x4B,0x33,0x20,0x51,0x51,
971 0x2B,0xD7,0xAF,0x42,0x6F,0xB8,0xF4,0x01,0x37,0x8C,0xD2,0xBF,
972 0x59,0x83,0xCA,0x01,0xC6,0x4B,0x92,0xEC,0xF0,0x32,0xEA,0x15,
973 0xD1,0x72,0x1D,0x03,0xF4,0x82,0xD7,0xCE,0x6E,0x74,0xFE,0xF6,
974 0xD5,0x5E,0x70,0x2F,0x46,0x98,0x0C,0x82,0xB5,0xA8,0x40,0x31,
975 0x90,0x0B,0x1C,0x9E,0x59,0xE7,0xC9,0x7F,0xBE,0xC7,0xE8,0xF3,
976 0x23,0xA9,0x7A,0x7E,0x36,0xCC,0x88,0xBE,0x0F,0x1D,0x45,0xB7,
977 0xFF,0x58,0x5A,0xC5,0x4B,0xD4,0x07,0xB2,0x2B,0x41,0x54,0xAA,
978 0xCC,0x8F,0x6D,0x7E,0xBF,0x48,0xE1,0xD8,0x14,0xCC,0x5E,0xD2,
979 0x0F,0x80,0x37,0xE0,0xA7,0x97,0x15,0xEE,0xF2,0x9B,0xE3,0x28,
980 0x06,0xA1,0xD5,0x8B,0xB7,0xC5,0xDA,0x76,0xF5,0x50,0xAA,0x3D,
981 0x8A,0x1F,0xBF,0xF0,0xEB,0x19,0xCC,0xB1,0xA3,0x13,0xD5,0x5C,
982 0xDA,0x56,0xC9,0xEC,0x2E,0xF2,0x96,0x32,0x38,0x7F,0xE8,0xD7,
983 0x6E,0x3C,0x04,0x68,0x04,0x3E,0x8F,0x66,0x3F,0x48,0x60,0xEE,
984 0x12,0xBF,0x2D,0x5B,0x0B,0x74,0x74,0xD6,0xE6,0x94,0xF9,0x1E,
985 0x6D,0xBE,0x11,0x59,0x74,0xA3,0x92,0x6F,0x12,0xFE,0xE5,0xE4,
986 0x38,0x77,0x7C,0xB6,0xA9,0x32,0xDF,0x8C,0xD8,0xBE,0xC4,0xD0,
987 0x73,0xB9,0x31,0xBA,0x3B,0xC8,0x32,0xB6,0x8D,0x9D,0xD3,0x00,
988 0x74,0x1F,0xA7,0xBF,0x8A,0xFC,0x47,0xED,0x25,0x76,0xF6,0x93,
989 0x6B,0xA4,0x24,0x66,0x3A,0xAB,0x63,0x9C,0x5A,0xE4,0xF5,0x68,
990 0x34,0x23,0xB4,0x74,0x2B,0xF1,0xC9,0x78,0x23,0x8F,0x16,0xCB,
991 0xE3,0x9D,0x65,0x2D,0xE3,0xFD,0xB8,0xBE,0xFC,0x84,0x8A,0xD9,
992 0x22,0x22,0x2E,0x04,0xA4,0x03,0x7C,0x07,0x13,0xEB,0x57,0xA8,
993 0x1A,0x23,0xF0,0xC7,0x34,0x73,0xFC,0x64,0x6C,0xEA,0x30,0x6B,
994 0x4B,0xCB,0xC8,0x86,0x2F,0x83,0x85,0xDD,0xFA,0x9D,0x4B,0x7F,
995 0xA2,0xC0,0x87,0xE8,0x79,0x68,0x33,0x03,0xED,0x5B,0xDD,0x3A,
996 0x06,0x2B,0x3C,0xF5,0xB3,0xA2,0x78,0xA6,0x6D,0x2A,0x13,0xF8,
997 0x3F,0x44,0xF8,0x2D,0xDF,0x31,0x0E,0xE0,0x74,0xAB,0x6A,0x36,
998 0x45,0x97,0xE8,0x99,0xA0,0x25,0x5D,0xC1,0x64,0xF3,0x1C,0xC5,
999 0x08,0x46,0x85,0x1D,0xF9,0xAB,0x48,0x19,0x5D,0xED,0x7E,0xA1,
1000 0xB1,0xD5,0x10,0xBD,0x7E,0xE7,0x4D,0x73,0xFA,0xF3,0x6B,0xC3,
1001 0x1E,0xCF,0xA2,0x68,0x35,0x90,0x46,0xF4,0xEB,0x87,0x9F,0x92,
1002 0x40,0x09,0x43,0x8B,0x48,0x1C,0x6C,0xD7,0x88,0x9A,0x00,0x2E,
1003 0xD5,0xEE,0x38,0x2B,0xC9,0x19,0x0D,0xA6,0xFC,0x02,0x6E,0x47,
1004 0x95,0x58,0xE4,0x47,0x56,0x77,0xE9,0xAA,0x9E,0x30,0x50,0xE2,
1005 0x76,0x56,0x94,0xDF,0xC8,0x1F,0x56,0xE8,0x80,0xB9,0x6E,0x71,
1006 0x60,0xC9,0x80,0xDD,0x98,0xED,0xD3,0xDF,0xFF,0xFF,0xFF,0xFF,
1007 0xFF,0xFF,0xFF,0xFF,
1008 };
1009#endif
1010 DH *dh = DH_new();
1011 if (dh) {
1012#if OPENSSL_VERSION_NUMBER >= 0x0090801fL
1013 dh->p = get_rfc3526_prime_8192(NULL);
1014#else
1015 dh->p = BN_bin2bn(rfc_3526_prime_8192, sizeof rfc_3526_prime_8192, NULL);
1016#endif
1017 /* See RFC 3526, Section 7 "8192-bit MODP Group"
1018 for the reason why 2 is used as generator.
1019 */
1020 BN_dec2bn(&dh->g, "2");
1021 if (!dh->p || !dh->g) {
1022 DH_free(dh);
1023 dh = NULL;
1024 }
1025 }
1026 return dh;
1027}
1028
1029/* Returns Diffie-Hellman parameters matching the private key length
1030 but not exceeding global.tune.ssl_default_dh_param */
1031static DH *ssl_get_tmp_dh(SSL *ssl, int export, int keylen)
1032{
1033 DH *dh = NULL;
1034 EVP_PKEY *pkey = SSL_get_privatekey(ssl);
1035 int type = pkey ? EVP_PKEY_type(pkey->type) : EVP_PKEY_NONE;
1036
1037 /* The keylen supplied by OpenSSL can only be 512 or 1024.
1038 See ssl3_send_server_key_exchange() in ssl/s3_srvr.c
1039 */
1040 if (type == EVP_PKEY_RSA || type == EVP_PKEY_DSA) {
1041 keylen = EVP_PKEY_bits(pkey);
1042 }
1043
1044 if (keylen > global.tune.ssl_default_dh_param) {
1045 keylen = global.tune.ssl_default_dh_param;
1046 }
1047
1048 if (keylen >= 8192) {
Remi Gacogne60d7aeb2014-07-15 11:36:40 +02001049 dh = local_dh_8192;
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001050 }
1051 else if (keylen >= 4096) {
Remi Gacogne60d7aeb2014-07-15 11:36:40 +02001052 dh = local_dh_4096;
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001053 }
1054 else if (keylen >= 2048) {
Remi Gacogne60d7aeb2014-07-15 11:36:40 +02001055 dh = local_dh_2048;
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001056 }
1057 else {
Remi Gacogne60d7aeb2014-07-15 11:36:40 +02001058 dh = local_dh_1024;
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001059 }
1060
1061 return dh;
1062}
1063
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001064/* Loads Diffie-Hellman parameter from a file. Returns 1 if loaded, else -1
1065 if an error occured, and 0 if parameter not found. */
Willy Tarreau6e774b42014-04-25 21:35:23 +02001066int ssl_sock_load_dh_params(SSL_CTX *ctx, const char *file)
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001067{
1068 int ret = -1;
1069 BIO *in;
1070 DH *dh = NULL;
1071
1072 in = BIO_new(BIO_s_file());
1073 if (in == NULL)
1074 goto end;
1075
1076 if (BIO_read_filename(in, file) <= 0)
1077 goto end;
1078
1079 dh = PEM_read_bio_DHparams(in, NULL, ctx->default_passwd_callback, ctx->default_passwd_callback_userdata);
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001080 if (dh) {
1081 ret = 1;
1082 SSL_CTX_set_tmp_dh(ctx, dh);
Remi Gacogne5d769ca2015-05-28 16:23:00 +02001083
1084 if (ssl_dh_ptr_index >= 0) {
1085 /* store a pointer to the DH params to avoid complaining about
1086 ssl-default-dh-param not being set for this SSL_CTX */
1087 SSL_CTX_set_ex_data(ctx, ssl_dh_ptr_index, dh);
1088 }
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001089 }
1090 else {
Emeric Brun41fdb3c2013-04-26 11:05:44 +02001091 /* Clear openssl global errors stack */
1092 ERR_clear_error();
1093
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001094 if (global.tune.ssl_default_dh_param <= 1024) {
1095 /* we are limited to DH parameter of 1024 bits anyway */
Remi Gacogne60d7aeb2014-07-15 11:36:40 +02001096 local_dh_1024 = ssl_get_dh_1024();
1097 if (local_dh_1024 == NULL)
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001098 goto end;
Willy Tarreau6e774b42014-04-25 21:35:23 +02001099
Remi Gacogne60d7aeb2014-07-15 11:36:40 +02001100 SSL_CTX_set_tmp_dh(ctx, local_dh_1024);
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001101 }
1102 else {
1103 SSL_CTX_set_tmp_dh_callback(ctx, ssl_get_tmp_dh);
1104 }
Willy Tarreau6e774b42014-04-25 21:35:23 +02001105
Emeric Brun41fdb3c2013-04-26 11:05:44 +02001106 ret = 0; /* DH params not found */
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001107 }
Emeric Brun644cde02012-12-14 11:21:13 +01001108
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001109end:
1110 if (dh)
1111 DH_free(dh);
1112
1113 if (in)
Emeric Brun41fdb3c2013-04-26 11:05:44 +02001114 BIO_free(in);
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001115
1116 return ret;
1117}
1118#endif
1119
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001120static int ssl_sock_add_cert_sni(SSL_CTX *ctx, struct bind_conf *s, char *name, int order)
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001121{
1122 struct sni_ctx *sc;
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001123 int wild = 0, neg = 0;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001124
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001125 if (*name == '!') {
1126 neg = 1;
1127 name++;
1128 }
1129 if (*name == '*') {
1130 wild = 1;
1131 name++;
1132 }
1133 /* !* filter is a nop */
1134 if (neg && wild)
1135 return order;
1136 if (*name) {
1137 int j, len;
1138 len = strlen(name);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001139 sc = malloc(sizeof(struct sni_ctx) + len + 1);
1140 for (j = 0; j < len; j++)
1141 sc->name.key[j] = tolower(name[j]);
1142 sc->name.key[len] = 0;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001143 sc->ctx = ctx;
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001144 sc->order = order++;
1145 sc->neg = neg;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001146 if (wild)
1147 ebst_insert(&s->sni_w_ctx, &sc->name);
1148 else
1149 ebst_insert(&s->sni_ctx, &sc->name);
1150 }
1151 return order;
1152}
1153
Emeric Brunfc0421f2012-09-07 17:30:07 +02001154/* Loads a certificate key and CA chain from a file. Returns 0 on error, -1 if
1155 * an early error happens and the caller must call SSL_CTX_free() by itelf.
1156 */
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001157static 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 +02001158{
1159 BIO *in;
1160 X509 *x = NULL, *ca;
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001161 int i, err;
Emeric Brunfc0421f2012-09-07 17:30:07 +02001162 int ret = -1;
1163 int order = 0;
1164 X509_NAME *xname;
1165 char *str;
Emeric Brunfc0421f2012-09-07 17:30:07 +02001166#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
1167 STACK_OF(GENERAL_NAME) *names;
1168#endif
1169
1170 in = BIO_new(BIO_s_file());
1171 if (in == NULL)
1172 goto end;
1173
1174 if (BIO_read_filename(in, file) <= 0)
1175 goto end;
1176
1177 x = PEM_read_bio_X509_AUX(in, NULL, ctx->default_passwd_callback, ctx->default_passwd_callback_userdata);
1178 if (x == NULL)
1179 goto end;
1180
Emeric Brun50bcecc2013-04-22 13:05:23 +02001181 if (fcount) {
1182 while (fcount--)
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001183 order = ssl_sock_add_cert_sni(ctx, s, sni_filter[fcount], order);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001184 }
1185 else {
Emeric Brunfc0421f2012-09-07 17:30:07 +02001186#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001187 names = X509_get_ext_d2i(x, NID_subject_alt_name, NULL, NULL);
1188 if (names) {
1189 for (i = 0; i < sk_GENERAL_NAME_num(names); i++) {
1190 GENERAL_NAME *name = sk_GENERAL_NAME_value(names, i);
1191 if (name->type == GEN_DNS) {
1192 if (ASN1_STRING_to_UTF8((unsigned char **)&str, name->d.dNSName) >= 0) {
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001193 order = ssl_sock_add_cert_sni(ctx, s, str, order);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001194 OPENSSL_free(str);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001195 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02001196 }
1197 }
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001198 sk_GENERAL_NAME_pop_free(names, GENERAL_NAME_free);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001199 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02001200#endif /* SSL_CTRL_SET_TLSEXT_HOSTNAME */
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001201 xname = X509_get_subject_name(x);
1202 i = -1;
1203 while ((i = X509_NAME_get_index_by_NID(xname, NID_commonName, i)) != -1) {
1204 X509_NAME_ENTRY *entry = X509_NAME_get_entry(xname, i);
1205 if (ASN1_STRING_to_UTF8((unsigned char **)&str, entry->value) >= 0) {
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001206 order = ssl_sock_add_cert_sni(ctx, s, str, order);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001207 OPENSSL_free(str);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001208 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02001209 }
1210 }
1211
1212 ret = 0; /* the caller must not free the SSL_CTX argument anymore */
1213 if (!SSL_CTX_use_certificate(ctx, x))
1214 goto end;
1215
1216 if (ctx->extra_certs != NULL) {
1217 sk_X509_pop_free(ctx->extra_certs, X509_free);
1218 ctx->extra_certs = NULL;
1219 }
1220
1221 while ((ca = PEM_read_bio_X509(in, NULL, ctx->default_passwd_callback, ctx->default_passwd_callback_userdata))) {
1222 if (!SSL_CTX_add_extra_chain_cert(ctx, ca)) {
1223 X509_free(ca);
1224 goto end;
1225 }
1226 }
1227
1228 err = ERR_get_error();
1229 if (!err || (ERR_GET_LIB(err) == ERR_LIB_PEM && ERR_GET_REASON(err) == PEM_R_NO_START_LINE)) {
1230 /* we successfully reached the last cert in the file */
1231 ret = 1;
1232 }
1233 ERR_clear_error();
1234
1235end:
1236 if (x)
1237 X509_free(x);
1238
1239 if (in)
1240 BIO_free(in);
1241
1242 return ret;
1243}
1244
Emeric Brun50bcecc2013-04-22 13:05:23 +02001245static 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 +02001246{
1247 int ret;
1248 SSL_CTX *ctx;
1249
1250 ctx = SSL_CTX_new(SSLv23_server_method());
1251 if (!ctx) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02001252 memprintf(err, "%sunable to allocate SSL context for cert '%s'.\n",
1253 err && *err ? *err : "", path);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001254 return 1;
1255 }
1256
1257 if (SSL_CTX_use_PrivateKey_file(ctx, path, SSL_FILETYPE_PEM) <= 0) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02001258 memprintf(err, "%sunable to load SSL private key from PEM file '%s'.\n",
1259 err && *err ? *err : "", path);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001260 SSL_CTX_free(ctx);
1261 return 1;
1262 }
1263
Emeric Brun50bcecc2013-04-22 13:05:23 +02001264 ret = ssl_sock_load_cert_chain_file(ctx, path, bind_conf, sni_filter, fcount);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001265 if (ret <= 0) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02001266 memprintf(err, "%sunable to load SSL certificate from PEM file '%s'.\n",
1267 err && *err ? *err : "", path);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001268 if (ret < 0) /* serious error, must do that ourselves */
1269 SSL_CTX_free(ctx);
1270 return 1;
1271 }
Emeric Brun61694ab2012-10-26 13:35:33 +02001272
1273 if (SSL_CTX_check_private_key(ctx) <= 0) {
1274 memprintf(err, "%sinconsistencies between private key and certificate loaded from PEM file '%s'.\n",
1275 err && *err ? *err : "", path);
1276 return 1;
1277 }
1278
Emeric Brunfc0421f2012-09-07 17:30:07 +02001279 /* we must not free the SSL_CTX anymore below, since it's already in
1280 * the tree, so it will be discovered and cleaned in time.
1281 */
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001282#ifndef OPENSSL_NO_DH
Remi Gacogne5d769ca2015-05-28 16:23:00 +02001283 /* store a NULL pointer to indicate we have not yet loaded
1284 a custom DH param file */
1285 if (ssl_dh_ptr_index >= 0) {
1286 SSL_CTX_set_ex_data(ctx, ssl_dh_ptr_index, NULL);
1287 }
1288
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001289 ret = ssl_sock_load_dh_params(ctx, path);
1290 if (ret < 0) {
1291 if (err)
1292 memprintf(err, "%sunable to load DH parameters from file '%s'.\n",
1293 *err ? *err : "", path);
1294 return 1;
1295 }
1296#endif
1297
Emeric Brun4147b2e2014-06-16 18:36:30 +02001298#ifdef SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB
1299 ret = ssl_sock_load_ocsp(ctx, path);
1300 if (ret < 0) {
1301 if (err)
1302 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",
1303 *err ? *err : "", path);
1304 return 1;
1305 }
1306#endif
1307
Emeric Brunfc0421f2012-09-07 17:30:07 +02001308#ifndef SSL_CTRL_SET_TLSEXT_HOSTNAME
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001309 if (bind_conf->default_ctx) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02001310 memprintf(err, "%sthis version of openssl cannot load multiple SSL certificates.\n",
1311 err && *err ? *err : "");
Emeric Brunfc0421f2012-09-07 17:30:07 +02001312 return 1;
1313 }
1314#endif
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001315 if (!bind_conf->default_ctx)
1316 bind_conf->default_ctx = ctx;
Emeric Brunfc0421f2012-09-07 17:30:07 +02001317
1318 return 0;
1319}
1320
Willy Tarreau79eeafa2012-09-14 07:53:05 +02001321int ssl_sock_load_cert(char *path, struct bind_conf *bind_conf, struct proxy *curproxy, char **err)
Emeric Brunfc0421f2012-09-07 17:30:07 +02001322{
Cyril Bonté62043c92015-01-25 00:16:08 +01001323 struct dirent **de_list;
1324 int i, n;
Emeric Brunfc0421f2012-09-07 17:30:07 +02001325 DIR *dir;
1326 struct stat buf;
Willy Tarreauee2663b2012-12-06 11:36:59 +01001327 char *end;
1328 char fp[MAXPATHLEN+1];
Emeric Brunfc0421f2012-09-07 17:30:07 +02001329 int cfgerr = 0;
1330
1331 if (!(dir = opendir(path)))
Emeric Brun50bcecc2013-04-22 13:05:23 +02001332 return ssl_sock_load_cert_file(path, bind_conf, curproxy, NULL, 0, err);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001333
1334 /* strip trailing slashes, including first one */
1335 for (end = path + strlen(path) - 1; end >= path && *end == '/'; end--)
1336 *end = 0;
1337
Cyril Bonté62043c92015-01-25 00:16:08 +01001338 n = scandir(path, &de_list, 0, alphasort);
1339 if (n < 0) {
1340 memprintf(err, "%sunable to scan directory '%s' : %s.\n",
1341 err && *err ? *err : "", path, strerror(errno));
1342 cfgerr++;
1343 }
1344 else {
1345 for (i = 0; i < n; i++) {
1346 struct dirent *de = de_list[i];
Emeric Brun2aab7222014-06-18 18:15:09 +02001347
Cyril Bonté62043c92015-01-25 00:16:08 +01001348 end = strrchr(de->d_name, '.');
1349 if (end && (!strcmp(end, ".issuer") || !strcmp(end, ".ocsp")))
1350 goto ignore_entry;
1351
1352 snprintf(fp, sizeof(fp), "%s/%s", path, de->d_name);
1353 if (stat(fp, &buf) != 0) {
1354 memprintf(err, "%sunable to stat SSL certificate from file '%s' : %s.\n",
1355 err && *err ? *err : "", fp, strerror(errno));
1356 cfgerr++;
1357 goto ignore_entry;
1358 }
1359 if (!S_ISREG(buf.st_mode))
1360 goto ignore_entry;
1361 cfgerr += ssl_sock_load_cert_file(fp, bind_conf, curproxy, NULL, 0, err);
1362 ignore_entry:
1363 free(de);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001364 }
Cyril Bonté62043c92015-01-25 00:16:08 +01001365 free(de_list);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001366 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02001367 closedir(dir);
1368 return cfgerr;
1369}
1370
Thierry Fournier383085f2013-01-24 14:15:43 +01001371/* Make sure openssl opens /dev/urandom before the chroot. The work is only
1372 * done once. Zero is returned if the operation fails. No error is returned
1373 * if the random is said as not implemented, because we expect that openssl
1374 * will use another method once needed.
1375 */
1376static int ssl_initialize_random()
1377{
1378 unsigned char random;
1379 static int random_initialized = 0;
1380
1381 if (!random_initialized && RAND_bytes(&random, 1) != 0)
1382 random_initialized = 1;
1383
1384 return random_initialized;
1385}
1386
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001387int ssl_sock_load_cert_list_file(char *file, struct bind_conf *bind_conf, struct proxy *curproxy, char **err)
1388{
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001389 char thisline[LINESIZE];
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001390 FILE *f;
1391 int linenum = 0;
1392 int cfgerr = 0;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001393
Willy Tarreauad1731d2013-04-02 17:35:58 +02001394 if ((f = fopen(file, "r")) == NULL) {
1395 memprintf(err, "cannot open file '%s' : %s", file, strerror(errno));
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001396 return 1;
Willy Tarreauad1731d2013-04-02 17:35:58 +02001397 }
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001398
1399 while (fgets(thisline, sizeof(thisline), f) != NULL) {
1400 int arg;
Emeric Brun50bcecc2013-04-22 13:05:23 +02001401 int newarg;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001402 char *end;
1403 char *args[MAX_LINE_ARGS + 1];
1404 char *line = thisline;
1405
1406 linenum++;
1407 end = line + strlen(line);
1408 if (end-line == sizeof(thisline)-1 && *(end-1) != '\n') {
1409 /* Check if we reached the limit and the last char is not \n.
1410 * Watch out for the last line without the terminating '\n'!
1411 */
Willy Tarreauad1731d2013-04-02 17:35:58 +02001412 memprintf(err, "line %d too long in file '%s', limit is %d characters",
1413 linenum, file, (int)sizeof(thisline)-1);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001414 cfgerr = 1;
Willy Tarreauad1731d2013-04-02 17:35:58 +02001415 break;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001416 }
1417
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001418 arg = 0;
Emeric Brun50bcecc2013-04-22 13:05:23 +02001419 newarg = 1;
1420 while (*line) {
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001421 if (*line == '#' || *line == '\n' || *line == '\r') {
1422 /* end of string, end of loop */
1423 *line = 0;
1424 break;
1425 }
1426 else if (isspace(*line)) {
Emeric Brun50bcecc2013-04-22 13:05:23 +02001427 newarg = 1;
1428 *line = 0;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001429 }
Emeric Brun50bcecc2013-04-22 13:05:23 +02001430 else if (newarg) {
1431 if (arg == MAX_LINE_ARGS) {
1432 memprintf(err, "too many args on line %d in file '%s'.",
1433 linenum, file);
1434 cfgerr = 1;
1435 break;
1436 }
1437 newarg = 0;
1438 args[arg++] = line;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001439 }
Emeric Brun50bcecc2013-04-22 13:05:23 +02001440 line++;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001441 }
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001442 if (cfgerr)
1443 break;
Willy Tarreauad1731d2013-04-02 17:35:58 +02001444
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001445 /* empty line */
Emeric Brun50bcecc2013-04-22 13:05:23 +02001446 if (!arg)
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001447 continue;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001448
Emeric Brun50bcecc2013-04-22 13:05:23 +02001449 cfgerr = ssl_sock_load_cert_file(args[0], bind_conf, curproxy, &args[1], arg-1, err);
Willy Tarreauad1731d2013-04-02 17:35:58 +02001450 if (cfgerr) {
1451 memprintf(err, "error processing line %d in file '%s' : %s", linenum, file, *err);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001452 break;
Willy Tarreauad1731d2013-04-02 17:35:58 +02001453 }
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001454 }
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001455 fclose(f);
1456 return cfgerr;
1457}
1458
Emeric Brunfc0421f2012-09-07 17:30:07 +02001459#ifndef SSL_OP_CIPHER_SERVER_PREFERENCE /* needs OpenSSL >= 0.9.7 */
1460#define SSL_OP_CIPHER_SERVER_PREFERENCE 0
1461#endif
1462
1463#ifndef SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION /* needs OpenSSL >= 0.9.7 */
1464#define SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION 0
Willy Tarreau7d588ee2012-11-26 18:47:31 +01001465#define SSL_renegotiate_pending(arg) 0
Emeric Brunfc0421f2012-09-07 17:30:07 +02001466#endif
Emeric Brun2b58d042012-09-20 17:10:03 +02001467#ifndef SSL_OP_SINGLE_ECDH_USE /* needs OpenSSL >= 0.9.8 */
1468#define SSL_OP_SINGLE_ECDH_USE 0
1469#endif
Emeric Brun2d0c4822012-10-02 13:45:20 +02001470#ifndef SSL_OP_NO_TICKET /* needs OpenSSL >= 0.9.8 */
1471#define SSL_OP_NO_TICKET 0
1472#endif
Emeric Brunfc0421f2012-09-07 17:30:07 +02001473#ifndef SSL_OP_NO_COMPRESSION /* needs OpenSSL >= 0.9.9 */
1474#define SSL_OP_NO_COMPRESSION 0
1475#endif
Emeric Brunc0ff4922012-09-28 19:37:02 +02001476#ifndef SSL_OP_NO_TLSv1_1 /* needs OpenSSL >= 1.0.1 */
1477#define SSL_OP_NO_TLSv1_1 0
1478#endif
1479#ifndef SSL_OP_NO_TLSv1_2 /* needs OpenSSL >= 1.0.1 */
1480#define SSL_OP_NO_TLSv1_2 0
1481#endif
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001482#ifndef SSL_OP_SINGLE_DH_USE /* needs OpenSSL >= 0.9.6 */
1483#define SSL_OP_SINGLE_DH_USE 0
1484#endif
Emeric Brun2b58d042012-09-20 17:10:03 +02001485#ifndef SSL_OP_SINGLE_ECDH_USE /* needs OpenSSL >= 1.0.0 */
1486#define SSL_OP_SINGLE_ECDH_USE 0
1487#endif
Emeric Brunfc0421f2012-09-07 17:30:07 +02001488#ifndef SSL_MODE_RELEASE_BUFFERS /* needs OpenSSL >= 1.0.0 */
1489#define SSL_MODE_RELEASE_BUFFERS 0
1490#endif
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001491
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001492int ssl_sock_prepare_ctx(struct bind_conf *bind_conf, SSL_CTX *ctx, struct proxy *curproxy)
Emeric Brunfc0421f2012-09-07 17:30:07 +02001493{
1494 int cfgerr = 0;
Emeric Brun850efd52014-01-29 12:24:34 +01001495 int verify = SSL_VERIFY_NONE;
Remi Gacogneaf5c3da2014-05-19 10:29:58 +02001496 long ssloptions =
Emeric Brunfc0421f2012-09-07 17:30:07 +02001497 SSL_OP_ALL | /* all known workarounds for bugs */
1498 SSL_OP_NO_SSLv2 |
1499 SSL_OP_NO_COMPRESSION |
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001500 SSL_OP_SINGLE_DH_USE |
Emeric Brun2b58d042012-09-20 17:10:03 +02001501 SSL_OP_SINGLE_ECDH_USE |
Emeric Brun3c4bc6e2012-10-04 18:44:19 +02001502 SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION |
1503 SSL_OP_CIPHER_SERVER_PREFERENCE;
Remi Gacogneaf5c3da2014-05-19 10:29:58 +02001504 long sslmode =
Emeric Brunfc0421f2012-09-07 17:30:07 +02001505 SSL_MODE_ENABLE_PARTIAL_WRITE |
1506 SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER |
1507 SSL_MODE_RELEASE_BUFFERS;
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001508 STACK_OF(SSL_CIPHER) * ciphers = NULL;
1509 SSL_CIPHER * cipher = NULL;
Remi Gacognec1eab8c2014-06-12 18:20:11 +02001510 char cipher_description[128];
1511 /* The description of ciphers using an Ephemeral Diffie Hellman key exchange
1512 contains " Kx=DH " or " Kx=DH(". Beware of " Kx=DH/",
1513 which is not ephemeral DH. */
1514 const char dhe_description[] = " Kx=DH ";
1515 const char dhe_export_description[] = " Kx=DH(";
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001516 int idx = 0;
1517 int dhe_found = 0;
Emeric Brunfc0421f2012-09-07 17:30:07 +02001518
Thierry Fournier383085f2013-01-24 14:15:43 +01001519 /* Make sure openssl opens /dev/urandom before the chroot */
1520 if (!ssl_initialize_random()) {
1521 Alert("OpenSSL random data generator initialization failed.\n");
1522 cfgerr++;
1523 }
1524
Emeric Brun89675492012-10-05 13:48:26 +02001525 if (bind_conf->ssl_options & BC_SSL_O_NO_SSLV3)
Emeric Brunfc0421f2012-09-07 17:30:07 +02001526 ssloptions |= SSL_OP_NO_SSLv3;
Emeric Brun89675492012-10-05 13:48:26 +02001527 if (bind_conf->ssl_options & BC_SSL_O_NO_TLSV10)
Emeric Brunfc0421f2012-09-07 17:30:07 +02001528 ssloptions |= SSL_OP_NO_TLSv1;
Emeric Brun89675492012-10-05 13:48:26 +02001529 if (bind_conf->ssl_options & BC_SSL_O_NO_TLSV11)
Emeric Brunc0ff4922012-09-28 19:37:02 +02001530 ssloptions |= SSL_OP_NO_TLSv1_1;
Emeric Brun89675492012-10-05 13:48:26 +02001531 if (bind_conf->ssl_options & BC_SSL_O_NO_TLSV12)
Emeric Brunc0ff4922012-09-28 19:37:02 +02001532 ssloptions |= SSL_OP_NO_TLSv1_2;
Emeric Brun89675492012-10-05 13:48:26 +02001533 if (bind_conf->ssl_options & BC_SSL_O_NO_TLS_TICKETS)
Emeric Brun2d0c4822012-10-02 13:45:20 +02001534 ssloptions |= SSL_OP_NO_TICKET;
Emeric Brun2cb7ae52012-10-05 14:14:21 +02001535 if (bind_conf->ssl_options & BC_SSL_O_USE_SSLV3)
1536 SSL_CTX_set_ssl_version(ctx, SSLv3_server_method());
1537 if (bind_conf->ssl_options & BC_SSL_O_USE_TLSV10)
1538 SSL_CTX_set_ssl_version(ctx, TLSv1_server_method());
1539#if SSL_OP_NO_TLSv1_1
1540 if (bind_conf->ssl_options & BC_SSL_O_USE_TLSV11)
1541 SSL_CTX_set_ssl_version(ctx, TLSv1_1_server_method());
1542#endif
1543#if SSL_OP_NO_TLSv1_2
1544 if (bind_conf->ssl_options & BC_SSL_O_USE_TLSV12)
1545 SSL_CTX_set_ssl_version(ctx, TLSv1_2_server_method());
1546#endif
Emeric Brunfc0421f2012-09-07 17:30:07 +02001547
1548 SSL_CTX_set_options(ctx, ssloptions);
1549 SSL_CTX_set_mode(ctx, sslmode);
Emeric Brun850efd52014-01-29 12:24:34 +01001550 switch (bind_conf->verify) {
1551 case SSL_SOCK_VERIFY_NONE:
1552 verify = SSL_VERIFY_NONE;
1553 break;
1554 case SSL_SOCK_VERIFY_OPTIONAL:
1555 verify = SSL_VERIFY_PEER;
1556 break;
1557 case SSL_SOCK_VERIFY_REQUIRED:
1558 verify = SSL_VERIFY_PEER|SSL_VERIFY_FAIL_IF_NO_PEER_CERT;
1559 break;
1560 }
1561 SSL_CTX_set_verify(ctx, verify, ssl_sock_bind_verifycbk);
1562 if (verify & SSL_VERIFY_PEER) {
Emeric Brunfb510ea2012-10-05 12:00:26 +02001563 if (bind_conf->ca_file) {
Emeric Brund94b3fe2012-09-20 18:23:56 +02001564 /* load CAfile to verify */
Emeric Brunfb510ea2012-10-05 12:00:26 +02001565 if (!SSL_CTX_load_verify_locations(ctx, bind_conf->ca_file, NULL)) {
Emeric Brund94b3fe2012-09-20 18:23:56 +02001566 Alert("Proxy '%s': unable to load CA file '%s' for bind '%s' at [%s:%d].\n",
Emeric Brunfb510ea2012-10-05 12:00:26 +02001567 curproxy->id, bind_conf->ca_file, bind_conf->arg, bind_conf->file, bind_conf->line);
Emeric Brund94b3fe2012-09-20 18:23:56 +02001568 cfgerr++;
1569 }
1570 /* set CA names fo client cert request, function returns void */
Emeric Brunfb510ea2012-10-05 12:00:26 +02001571 SSL_CTX_set_client_CA_list(ctx, SSL_load_client_CA_file(bind_conf->ca_file));
Emeric Brund94b3fe2012-09-20 18:23:56 +02001572 }
Emeric Brun850efd52014-01-29 12:24:34 +01001573 else {
1574 Alert("Proxy '%s': verify is enabled but no CA file specified for bind '%s' at [%s:%d].\n",
1575 curproxy->id, bind_conf->arg, bind_conf->file, bind_conf->line);
1576 cfgerr++;
1577 }
Emeric Brun051cdab2012-10-02 19:25:50 +02001578#ifdef X509_V_FLAG_CRL_CHECK
Emeric Brunfb510ea2012-10-05 12:00:26 +02001579 if (bind_conf->crl_file) {
Emeric Brund94b3fe2012-09-20 18:23:56 +02001580 X509_STORE *store = SSL_CTX_get_cert_store(ctx);
1581
Emeric Brunfb510ea2012-10-05 12:00:26 +02001582 if (!store || !X509_STORE_load_locations(store, bind_conf->crl_file, NULL)) {
Emeric Brund94b3fe2012-09-20 18:23:56 +02001583 Alert("Proxy '%s': unable to configure CRL file '%s' for bind '%s' at [%s:%d].\n",
Alexander Rigbo37dc94c2015-04-07 14:02:16 +02001584 curproxy->id, bind_conf->crl_file, bind_conf->arg, bind_conf->file, bind_conf->line);
Emeric Brund94b3fe2012-09-20 18:23:56 +02001585 cfgerr++;
1586 }
Emeric Brun561e5742012-10-02 15:20:55 +02001587 else {
1588 X509_STORE_set_flags(store, X509_V_FLAG_CRL_CHECK|X509_V_FLAG_CRL_CHECK_ALL);
1589 }
Emeric Brund94b3fe2012-09-20 18:23:56 +02001590 }
Emeric Brun051cdab2012-10-02 19:25:50 +02001591#endif
Emeric Brun644cde02012-12-14 11:21:13 +01001592 ERR_clear_error();
Emeric Brund94b3fe2012-09-20 18:23:56 +02001593 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02001594
Emeric Brun4f65bff2012-11-16 15:11:00 +01001595 if (global.tune.ssllifetime)
1596 SSL_CTX_set_timeout(ctx, global.tune.ssllifetime);
1597
Emeric Brunfc0421f2012-09-07 17:30:07 +02001598 shared_context_set_cache(ctx);
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001599 if (bind_conf->ciphers &&
1600 !SSL_CTX_set_cipher_list(ctx, bind_conf->ciphers)) {
Emeric Brunfc0421f2012-09-07 17:30:07 +02001601 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 +02001602 curproxy->id, bind_conf->ciphers, bind_conf->arg, bind_conf->file, bind_conf->line);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001603 cfgerr++;
1604 }
1605
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001606 /* If tune.ssl.default-dh-param has not been set and
1607 no static DH params were in the certificate file. */
Remi Gacogne5d769ca2015-05-28 16:23:00 +02001608 if (global.tune.ssl_default_dh_param == 0 &&
1609 (ssl_dh_ptr_index == -1 ||
1610 SSL_CTX_get_ex_data(ctx, ssl_dh_ptr_index) == NULL)) {
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001611 ciphers = ctx->cipher_list;
1612
1613 if (ciphers) {
1614 for (idx = 0; idx < sk_SSL_CIPHER_num(ciphers); idx++) {
1615 cipher = sk_SSL_CIPHER_value(ciphers, idx);
Remi Gacognec1eab8c2014-06-12 18:20:11 +02001616 if (SSL_CIPHER_description(cipher, cipher_description, sizeof (cipher_description)) == cipher_description) {
1617 if (strstr(cipher_description, dhe_description) != NULL ||
1618 strstr(cipher_description, dhe_export_description) != NULL) {
1619 dhe_found = 1;
1620 break;
1621 }
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001622 }
1623 }
1624
1625 if (dhe_found) {
1626 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");
1627 }
1628 }
1629
1630 global.tune.ssl_default_dh_param = 1024;
1631 }
Remi Gacogne60d7aeb2014-07-15 11:36:40 +02001632
1633#ifndef OPENSSL_NO_DH
1634 if (global.tune.ssl_default_dh_param >= 1024) {
1635 if (local_dh_1024 == NULL) {
1636 local_dh_1024 = ssl_get_dh_1024();
1637 }
1638 if (global.tune.ssl_default_dh_param >= 2048) {
1639 if (local_dh_2048 == NULL) {
1640 local_dh_2048 = ssl_get_dh_2048();
1641 }
1642 if (global.tune.ssl_default_dh_param >= 4096) {
1643 if (local_dh_4096 == NULL) {
1644 local_dh_4096 = ssl_get_dh_4096();
1645 }
1646 if (global.tune.ssl_default_dh_param >= 8192 &&
1647 local_dh_8192 == NULL) {
1648 local_dh_8192 = ssl_get_dh_8192();
1649 }
1650 }
1651 }
1652 }
1653#endif /* OPENSSL_NO_DH */
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001654
Emeric Brunfc0421f2012-09-07 17:30:07 +02001655 SSL_CTX_set_info_callback(ctx, ssl_sock_infocbk);
Willy Tarreau5cbe4ef2014-05-08 22:45:11 +02001656#if OPENSSL_VERSION_NUMBER >= 0x00907000L
Emeric Brun29f037d2014-04-25 19:05:36 +02001657 SSL_CTX_set_msg_callback(ctx, ssl_sock_msgcbk);
Willy Tarreau5cbe4ef2014-05-08 22:45:11 +02001658#endif
Emeric Brun29f037d2014-04-25 19:05:36 +02001659
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02001660#ifdef OPENSSL_NPN_NEGOTIATED
1661 if (bind_conf->npn_str)
1662 SSL_CTX_set_next_protos_advertised_cb(ctx, ssl_sock_advertise_npn_protos, bind_conf);
1663#endif
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01001664#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Willy Tarreauab861d32013-04-02 02:30:41 +02001665 if (bind_conf->alpn_str)
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01001666 SSL_CTX_set_alpn_select_cb(ctx, ssl_sock_advertise_alpn_protos, bind_conf);
Willy Tarreauab861d32013-04-02 02:30:41 +02001667#endif
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02001668
Emeric Brunfc0421f2012-09-07 17:30:07 +02001669#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
1670 SSL_CTX_set_tlsext_servername_callback(ctx, ssl_sock_switchctx_cbk);
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001671 SSL_CTX_set_tlsext_servername_arg(ctx, bind_conf);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001672#endif
Emeric Brun2b58d042012-09-20 17:10:03 +02001673#if defined(SSL_CTX_set_tmp_ecdh) && !defined(OPENSSL_NO_ECDH)
Emeric Brun6924ef82013-03-06 14:08:53 +01001674 {
Emeric Brun2b58d042012-09-20 17:10:03 +02001675 int i;
1676 EC_KEY *ecdh;
1677
Emeric Brun6924ef82013-03-06 14:08:53 +01001678 i = OBJ_sn2nid(bind_conf->ecdhe ? bind_conf->ecdhe : ECDHE_DEFAULT_CURVE);
Emeric Brun2b58d042012-09-20 17:10:03 +02001679 if (!i || ((ecdh = EC_KEY_new_by_curve_name(i)) == NULL)) {
1680 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 +01001681 curproxy->id, bind_conf->ecdhe ? bind_conf->ecdhe : ECDHE_DEFAULT_CURVE,
1682 bind_conf->arg, bind_conf->file, bind_conf->line);
Emeric Brun2b58d042012-09-20 17:10:03 +02001683 cfgerr++;
1684 }
1685 else {
1686 SSL_CTX_set_tmp_ecdh(ctx, ecdh);
1687 EC_KEY_free(ecdh);
1688 }
1689 }
1690#endif
1691
Emeric Brunfc0421f2012-09-07 17:30:07 +02001692 return cfgerr;
1693}
1694
Evan Broderbe554312013-06-27 00:05:25 -07001695static int ssl_sock_srv_hostcheck(const char *pattern, const char *hostname)
1696{
1697 const char *pattern_wildcard, *pattern_left_label_end, *hostname_left_label_end;
1698 size_t prefixlen, suffixlen;
1699
1700 /* Trivial case */
1701 if (strcmp(pattern, hostname) == 0)
1702 return 1;
1703
Evan Broderbe554312013-06-27 00:05:25 -07001704 /* The rest of this logic is based on RFC 6125, section 6.4.3
1705 * (http://tools.ietf.org/html/rfc6125#section-6.4.3) */
1706
Emeric Bruna848dae2013-10-08 11:27:28 +02001707 pattern_wildcard = NULL;
1708 pattern_left_label_end = pattern;
1709 while (*pattern_left_label_end != '.') {
1710 switch (*pattern_left_label_end) {
1711 case 0:
1712 /* End of label not found */
1713 return 0;
1714 case '*':
1715 /* If there is more than one wildcards */
1716 if (pattern_wildcard)
1717 return 0;
1718 pattern_wildcard = pattern_left_label_end;
1719 break;
1720 }
1721 pattern_left_label_end++;
1722 }
1723
1724 /* If it's not trivial and there is no wildcard, it can't
1725 * match */
1726 if (!pattern_wildcard)
Evan Broderbe554312013-06-27 00:05:25 -07001727 return 0;
1728
1729 /* Make sure all labels match except the leftmost */
1730 hostname_left_label_end = strchr(hostname, '.');
1731 if (!hostname_left_label_end
1732 || strcmp(pattern_left_label_end, hostname_left_label_end) != 0)
1733 return 0;
1734
1735 /* Make sure the leftmost label of the hostname is long enough
1736 * that the wildcard can match */
Emeric Brun369da852013-10-08 11:39:35 +02001737 if (hostname_left_label_end - hostname < (pattern_left_label_end - pattern) - 1)
Evan Broderbe554312013-06-27 00:05:25 -07001738 return 0;
1739
1740 /* Finally compare the string on either side of the
1741 * wildcard */
1742 prefixlen = pattern_wildcard - pattern;
1743 suffixlen = pattern_left_label_end - (pattern_wildcard + 1);
Emeric Bruna848dae2013-10-08 11:27:28 +02001744 if ((prefixlen && (memcmp(pattern, hostname, prefixlen) != 0))
1745 || (suffixlen && (memcmp(pattern_wildcard + 1, hostname_left_label_end - suffixlen, suffixlen) != 0)))
Evan Broderbe554312013-06-27 00:05:25 -07001746 return 0;
1747
1748 return 1;
1749}
1750
1751static int ssl_sock_srv_verifycbk(int ok, X509_STORE_CTX *ctx)
1752{
1753 SSL *ssl;
1754 struct connection *conn;
1755 char *servername;
1756
1757 int depth;
1758 X509 *cert;
1759 STACK_OF(GENERAL_NAME) *alt_names;
1760 int i;
1761 X509_NAME *cert_subject;
1762 char *str;
1763
1764 if (ok == 0)
1765 return ok;
1766
1767 ssl = X509_STORE_CTX_get_ex_data(ctx, SSL_get_ex_data_X509_STORE_CTX_idx());
1768 conn = (struct connection *)SSL_get_app_data(ssl);
1769
1770 servername = objt_server(conn->target)->ssl_ctx.verify_host;
1771
1772 /* We only need to verify the CN on the actual server cert,
1773 * not the indirect CAs */
1774 depth = X509_STORE_CTX_get_error_depth(ctx);
1775 if (depth != 0)
1776 return ok;
1777
1778 /* At this point, the cert is *not* OK unless we can find a
1779 * hostname match */
1780 ok = 0;
1781
1782 cert = X509_STORE_CTX_get_current_cert(ctx);
1783 /* It seems like this might happen if verify peer isn't set */
1784 if (!cert)
1785 return ok;
1786
1787 alt_names = X509_get_ext_d2i(cert, NID_subject_alt_name, NULL, NULL);
1788 if (alt_names) {
1789 for (i = 0; !ok && i < sk_GENERAL_NAME_num(alt_names); i++) {
1790 GENERAL_NAME *name = sk_GENERAL_NAME_value(alt_names, i);
1791 if (name->type == GEN_DNS) {
Emeric Bruna33410c2013-09-17 15:47:48 +02001792#if OPENSSL_VERSION_NUMBER < 0x00907000L
1793 if (ASN1_STRING_to_UTF8((unsigned char **)&str, name->d.ia5) >= 0) {
1794#else
Evan Broderbe554312013-06-27 00:05:25 -07001795 if (ASN1_STRING_to_UTF8((unsigned char **)&str, name->d.dNSName) >= 0) {
Emeric Bruna33410c2013-09-17 15:47:48 +02001796#endif
Evan Broderbe554312013-06-27 00:05:25 -07001797 ok = ssl_sock_srv_hostcheck(str, servername);
1798 OPENSSL_free(str);
1799 }
1800 }
1801 }
Emeric Brun4ad50a42013-09-17 15:19:54 +02001802 sk_GENERAL_NAME_pop_free(alt_names, GENERAL_NAME_free);
Evan Broderbe554312013-06-27 00:05:25 -07001803 }
1804
1805 cert_subject = X509_get_subject_name(cert);
1806 i = -1;
1807 while (!ok && (i = X509_NAME_get_index_by_NID(cert_subject, NID_commonName, i)) != -1) {
1808 X509_NAME_ENTRY *entry = X509_NAME_get_entry(cert_subject, i);
1809 if (ASN1_STRING_to_UTF8((unsigned char **)&str, entry->value) >= 0) {
1810 ok = ssl_sock_srv_hostcheck(str, servername);
1811 OPENSSL_free(str);
1812 }
1813 }
1814
1815 return ok;
1816}
1817
Emeric Brun94324a42012-10-11 14:00:19 +02001818/* prepare ssl context from servers options. Returns an error count */
1819int ssl_sock_prepare_srv_ctx(struct server *srv, struct proxy *curproxy)
1820{
1821 int cfgerr = 0;
Remi Gacogneaf5c3da2014-05-19 10:29:58 +02001822 long options =
Emeric Brun94324a42012-10-11 14:00:19 +02001823 SSL_OP_ALL | /* all known workarounds for bugs */
1824 SSL_OP_NO_SSLv2 |
1825 SSL_OP_NO_COMPRESSION;
Remi Gacogneaf5c3da2014-05-19 10:29:58 +02001826 long mode =
Emeric Brun94324a42012-10-11 14:00:19 +02001827 SSL_MODE_ENABLE_PARTIAL_WRITE |
1828 SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER |
1829 SSL_MODE_RELEASE_BUFFERS;
Emeric Brun850efd52014-01-29 12:24:34 +01001830 int verify = SSL_VERIFY_NONE;
Emeric Brun94324a42012-10-11 14:00:19 +02001831
Thierry Fournier383085f2013-01-24 14:15:43 +01001832 /* Make sure openssl opens /dev/urandom before the chroot */
1833 if (!ssl_initialize_random()) {
1834 Alert("OpenSSL random data generator initialization failed.\n");
1835 cfgerr++;
1836 }
1837
Emeric Brun94324a42012-10-11 14:00:19 +02001838 /* Initiate SSL context for current server */
1839 srv->ssl_ctx.reused_sess = NULL;
1840 if (srv->use_ssl)
1841 srv->xprt = &ssl_sock;
1842 if (srv->check.use_ssl)
Cyril Bonté1f96a872014-11-15 22:41:27 +01001843 srv->check.xprt = &ssl_sock;
Emeric Brun94324a42012-10-11 14:00:19 +02001844
1845 srv->ssl_ctx.ctx = SSL_CTX_new(SSLv23_client_method());
1846 if (!srv->ssl_ctx.ctx) {
1847 Alert("config : %s '%s', server '%s': unable to allocate ssl context.\n",
1848 proxy_type_str(curproxy), curproxy->id,
1849 srv->id);
1850 cfgerr++;
1851 return cfgerr;
1852 }
Emeric Bruna7aa3092012-10-26 12:58:00 +02001853 if (srv->ssl_ctx.client_crt) {
1854 if (SSL_CTX_use_PrivateKey_file(srv->ssl_ctx.ctx, srv->ssl_ctx.client_crt, SSL_FILETYPE_PEM) <= 0) {
1855 Alert("config : %s '%s', server '%s': unable to load SSL private key from PEM file '%s'.\n",
1856 proxy_type_str(curproxy), curproxy->id,
1857 srv->id, srv->ssl_ctx.client_crt);
1858 cfgerr++;
1859 }
1860 else if (SSL_CTX_use_certificate_chain_file(srv->ssl_ctx.ctx, srv->ssl_ctx.client_crt) <= 0) {
1861 Alert("config : %s '%s', server '%s': unable to load ssl certificate from PEM file '%s'.\n",
1862 proxy_type_str(curproxy), curproxy->id,
1863 srv->id, srv->ssl_ctx.client_crt);
1864 cfgerr++;
1865 }
1866 else if (SSL_CTX_check_private_key(srv->ssl_ctx.ctx) <= 0) {
1867 Alert("config : %s '%s', server '%s': inconsistencies between private key and certificate loaded from PEM file '%s'.\n",
1868 proxy_type_str(curproxy), curproxy->id,
1869 srv->id, srv->ssl_ctx.client_crt);
1870 cfgerr++;
1871 }
1872 }
Emeric Brun94324a42012-10-11 14:00:19 +02001873
1874 if (srv->ssl_ctx.options & SRV_SSL_O_NO_SSLV3)
1875 options |= SSL_OP_NO_SSLv3;
1876 if (srv->ssl_ctx.options & SRV_SSL_O_NO_TLSV10)
1877 options |= SSL_OP_NO_TLSv1;
1878 if (srv->ssl_ctx.options & SRV_SSL_O_NO_TLSV11)
1879 options |= SSL_OP_NO_TLSv1_1;
1880 if (srv->ssl_ctx.options & SRV_SSL_O_NO_TLSV12)
1881 options |= SSL_OP_NO_TLSv1_2;
Emeric Brunf9c5c472012-10-11 15:28:34 +02001882 if (srv->ssl_ctx.options & SRV_SSL_O_NO_TLS_TICKETS)
1883 options |= SSL_OP_NO_TICKET;
Emeric Brun94324a42012-10-11 14:00:19 +02001884 if (srv->ssl_ctx.options & SRV_SSL_O_USE_SSLV3)
1885 SSL_CTX_set_ssl_version(srv->ssl_ctx.ctx, SSLv3_client_method());
1886 if (srv->ssl_ctx.options & SRV_SSL_O_USE_TLSV10)
1887 SSL_CTX_set_ssl_version(srv->ssl_ctx.ctx, TLSv1_client_method());
1888#if SSL_OP_NO_TLSv1_1
1889 if (srv->ssl_ctx.options & SRV_SSL_O_USE_TLSV11)
1890 SSL_CTX_set_ssl_version(srv->ssl_ctx.ctx, TLSv1_1_client_method());
1891#endif
1892#if SSL_OP_NO_TLSv1_2
1893 if (srv->ssl_ctx.options & SRV_SSL_O_USE_TLSV12)
1894 SSL_CTX_set_ssl_version(srv->ssl_ctx.ctx, TLSv1_2_client_method());
1895#endif
1896
1897 SSL_CTX_set_options(srv->ssl_ctx.ctx, options);
1898 SSL_CTX_set_mode(srv->ssl_ctx.ctx, mode);
Emeric Brun850efd52014-01-29 12:24:34 +01001899
1900 if (global.ssl_server_verify == SSL_SERVER_VERIFY_REQUIRED)
1901 verify = SSL_VERIFY_PEER;
1902
1903 switch (srv->ssl_ctx.verify) {
1904 case SSL_SOCK_VERIFY_NONE:
1905 verify = SSL_VERIFY_NONE;
1906 break;
1907 case SSL_SOCK_VERIFY_REQUIRED:
1908 verify = SSL_VERIFY_PEER;
1909 break;
1910 }
Evan Broderbe554312013-06-27 00:05:25 -07001911 SSL_CTX_set_verify(srv->ssl_ctx.ctx,
Emeric Brun850efd52014-01-29 12:24:34 +01001912 verify,
Evan Broderbe554312013-06-27 00:05:25 -07001913 srv->ssl_ctx.verify_host ? ssl_sock_srv_verifycbk : NULL);
Emeric Brun850efd52014-01-29 12:24:34 +01001914 if (verify & SSL_VERIFY_PEER) {
Emeric Brunef42d922012-10-11 16:11:36 +02001915 if (srv->ssl_ctx.ca_file) {
1916 /* load CAfile to verify */
1917 if (!SSL_CTX_load_verify_locations(srv->ssl_ctx.ctx, srv->ssl_ctx.ca_file, NULL)) {
Willy Tarreau07ba08b2014-02-16 19:22:08 +01001918 Alert("Proxy '%s', server '%s' [%s:%d] unable to load CA file '%s'.\n",
Emeric Brunef42d922012-10-11 16:11:36 +02001919 curproxy->id, srv->id,
1920 srv->conf.file, srv->conf.line, srv->ssl_ctx.ca_file);
1921 cfgerr++;
1922 }
1923 }
Emeric Brun850efd52014-01-29 12:24:34 +01001924 else {
1925 if (global.ssl_server_verify == SSL_SERVER_VERIFY_REQUIRED)
Willy Tarreau07ba08b2014-02-16 19:22:08 +01001926 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 +01001927 curproxy->id, srv->id,
1928 srv->conf.file, srv->conf.line);
1929 else
Willy Tarreau07ba08b2014-02-16 19:22:08 +01001930 Alert("Proxy '%s', server '%s' [%s:%d] verify is enabled but no CA file specified.\n",
Emeric Brun850efd52014-01-29 12:24:34 +01001931 curproxy->id, srv->id,
1932 srv->conf.file, srv->conf.line);
1933 cfgerr++;
1934 }
Emeric Brunef42d922012-10-11 16:11:36 +02001935#ifdef X509_V_FLAG_CRL_CHECK
1936 if (srv->ssl_ctx.crl_file) {
1937 X509_STORE *store = SSL_CTX_get_cert_store(srv->ssl_ctx.ctx);
1938
1939 if (!store || !X509_STORE_load_locations(store, srv->ssl_ctx.crl_file, NULL)) {
Willy Tarreau07ba08b2014-02-16 19:22:08 +01001940 Alert("Proxy '%s', server '%s' [%s:%d] unable to configure CRL file '%s'.\n",
Emeric Brunef42d922012-10-11 16:11:36 +02001941 curproxy->id, srv->id,
1942 srv->conf.file, srv->conf.line, srv->ssl_ctx.crl_file);
1943 cfgerr++;
1944 }
1945 else {
1946 X509_STORE_set_flags(store, X509_V_FLAG_CRL_CHECK|X509_V_FLAG_CRL_CHECK_ALL);
1947 }
1948 }
1949#endif
1950 }
1951
Emeric Brun4f65bff2012-11-16 15:11:00 +01001952 if (global.tune.ssllifetime)
1953 SSL_CTX_set_timeout(srv->ssl_ctx.ctx, global.tune.ssllifetime);
1954
Emeric Brun94324a42012-10-11 14:00:19 +02001955 SSL_CTX_set_session_cache_mode(srv->ssl_ctx.ctx, SSL_SESS_CACHE_OFF);
1956 if (srv->ssl_ctx.ciphers &&
1957 !SSL_CTX_set_cipher_list(srv->ssl_ctx.ctx, srv->ssl_ctx.ciphers)) {
1958 Alert("Proxy '%s', server '%s' [%s:%d] : unable to set SSL cipher list to '%s'.\n",
1959 curproxy->id, srv->id,
1960 srv->conf.file, srv->conf.line, srv->ssl_ctx.ciphers);
1961 cfgerr++;
1962 }
1963
1964 return cfgerr;
1965}
1966
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001967/* Walks down the two trees in bind_conf and prepares all certs. The pointer may
Emeric Brunfc0421f2012-09-07 17:30:07 +02001968 * be NULL, in which case nothing is done. Returns the number of errors
1969 * encountered.
1970 */
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001971int ssl_sock_prepare_all_ctx(struct bind_conf *bind_conf, struct proxy *px)
Emeric Brunfc0421f2012-09-07 17:30:07 +02001972{
1973 struct ebmb_node *node;
1974 struct sni_ctx *sni;
1975 int err = 0;
1976
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001977 if (!bind_conf || !bind_conf->is_ssl)
Emeric Brunfc0421f2012-09-07 17:30:07 +02001978 return 0;
1979
Emeric Brun8068b032014-10-30 19:25:24 +01001980 if (bind_conf->default_ctx)
1981 err += ssl_sock_prepare_ctx(bind_conf, bind_conf->default_ctx, px);
1982
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001983 node = ebmb_first(&bind_conf->sni_ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001984 while (node) {
1985 sni = ebmb_entry(node, struct sni_ctx, name);
Emeric Brun8068b032014-10-30 19:25:24 +01001986 if (!sni->order && sni->ctx != bind_conf->default_ctx)
1987 /* only initialize the CTX on its first occurrence and
1988 if it is not the default_ctx */
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001989 err += ssl_sock_prepare_ctx(bind_conf, sni->ctx, px);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001990 node = ebmb_next(node);
1991 }
1992
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001993 node = ebmb_first(&bind_conf->sni_w_ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001994 while (node) {
1995 sni = ebmb_entry(node, struct sni_ctx, name);
Emeric Brun8068b032014-10-30 19:25:24 +01001996 if (!sni->order && sni->ctx != bind_conf->default_ctx)
1997 /* only initialize the CTX on its first occurrence and
1998 if it is not the default_ctx */
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001999 err += ssl_sock_prepare_ctx(bind_conf, sni->ctx, px);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002000 node = ebmb_next(node);
2001 }
2002 return err;
2003}
2004
Willy Tarreau2a65ff02012-09-13 17:54:29 +02002005/* Walks down the two trees in bind_conf and frees all the certs. The pointer may
Emeric Brunfc0421f2012-09-07 17:30:07 +02002006 * be NULL, in which case nothing is done. The default_ctx is nullified too.
2007 */
Willy Tarreau2a65ff02012-09-13 17:54:29 +02002008void ssl_sock_free_all_ctx(struct bind_conf *bind_conf)
Emeric Brunfc0421f2012-09-07 17:30:07 +02002009{
2010 struct ebmb_node *node, *back;
2011 struct sni_ctx *sni;
2012
Willy Tarreau2a65ff02012-09-13 17:54:29 +02002013 if (!bind_conf || !bind_conf->is_ssl)
Emeric Brunfc0421f2012-09-07 17:30:07 +02002014 return;
2015
Willy Tarreau2a65ff02012-09-13 17:54:29 +02002016 node = ebmb_first(&bind_conf->sni_ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002017 while (node) {
2018 sni = ebmb_entry(node, struct sni_ctx, name);
2019 back = ebmb_next(node);
2020 ebmb_delete(node);
2021 if (!sni->order) /* only free the CTX on its first occurrence */
2022 SSL_CTX_free(sni->ctx);
2023 free(sni);
2024 node = back;
2025 }
2026
Willy Tarreau2a65ff02012-09-13 17:54:29 +02002027 node = ebmb_first(&bind_conf->sni_w_ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002028 while (node) {
2029 sni = ebmb_entry(node, struct sni_ctx, name);
2030 back = ebmb_next(node);
2031 ebmb_delete(node);
2032 if (!sni->order) /* only free the CTX on its first occurrence */
2033 SSL_CTX_free(sni->ctx);
2034 free(sni);
2035 node = back;
2036 }
2037
Willy Tarreau2a65ff02012-09-13 17:54:29 +02002038 bind_conf->default_ctx = NULL;
Emeric Brune1f38db2012-09-03 20:36:47 +02002039}
2040
Emeric Brun46591952012-05-18 15:47:34 +02002041/*
2042 * This function is called if SSL * context is not yet allocated. The function
2043 * is designed to be called before any other data-layer operation and sets the
2044 * handshake flag on the connection. It is safe to call it multiple times.
2045 * It returns 0 on success and -1 in error case.
2046 */
2047static int ssl_sock_init(struct connection *conn)
2048{
2049 /* already initialized */
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02002050 if (conn->xprt_ctx)
Emeric Brun46591952012-05-18 15:47:34 +02002051 return 0;
2052
Willy Tarreau3c728722014-01-23 13:50:42 +01002053 if (!conn_ctrl_ready(conn))
Willy Tarreauf79c8172013-10-21 16:30:56 +02002054 return 0;
2055
Willy Tarreau20879a02012-12-03 16:32:10 +01002056 if (global.maxsslconn && sslconns >= global.maxsslconn) {
2057 conn->err_code = CO_ER_SSL_TOO_MANY;
Willy Tarreau403edff2012-09-06 11:58:37 +02002058 return -1;
Willy Tarreau20879a02012-12-03 16:32:10 +01002059 }
Willy Tarreau403edff2012-09-06 11:58:37 +02002060
Emeric Brun46591952012-05-18 15:47:34 +02002061 /* If it is in client mode initiate SSL session
2062 in connect state otherwise accept state */
Willy Tarreau3fdb3662012-11-12 00:42:33 +01002063 if (objt_server(conn->target)) {
Willy Tarreau9bcc01a2014-11-13 13:48:58 +01002064 int may_retry = 1;
2065
2066 retry_connect:
Emeric Brun46591952012-05-18 15:47:34 +02002067 /* Alloc a new SSL session ctx */
Willy Tarreau3fdb3662012-11-12 00:42:33 +01002068 conn->xprt_ctx = SSL_new(objt_server(conn->target)->ssl_ctx.ctx);
Willy Tarreau20879a02012-12-03 16:32:10 +01002069 if (!conn->xprt_ctx) {
Willy Tarreau9bcc01a2014-11-13 13:48:58 +01002070 if (may_retry--) {
2071 pool_gc2();
2072 goto retry_connect;
2073 }
Willy Tarreau20879a02012-12-03 16:32:10 +01002074 conn->err_code = CO_ER_SSL_NO_MEM;
Emeric Brun46591952012-05-18 15:47:34 +02002075 return -1;
Willy Tarreau20879a02012-12-03 16:32:10 +01002076 }
Emeric Brun46591952012-05-18 15:47:34 +02002077
Emeric Brun46591952012-05-18 15:47:34 +02002078 /* set fd on SSL session context */
Emeric Brun90951492014-11-12 17:35:37 +01002079 if (!SSL_set_fd(conn->xprt_ctx, conn->t.sock.fd)) {
2080 SSL_free(conn->xprt_ctx);
2081 conn->xprt_ctx = NULL;
Willy Tarreau9bcc01a2014-11-13 13:48:58 +01002082 if (may_retry--) {
2083 pool_gc2();
2084 goto retry_connect;
2085 }
Emeric Brun90951492014-11-12 17:35:37 +01002086 conn->err_code = CO_ER_SSL_NO_MEM;
2087 return -1;
2088 }
Emeric Brun46591952012-05-18 15:47:34 +02002089
Evan Broderbe554312013-06-27 00:05:25 -07002090 /* set connection pointer */
Emeric Brun90951492014-11-12 17:35:37 +01002091 if (!SSL_set_app_data(conn->xprt_ctx, conn)) {
2092 SSL_free(conn->xprt_ctx);
2093 conn->xprt_ctx = NULL;
Willy Tarreau9bcc01a2014-11-13 13:48:58 +01002094 if (may_retry--) {
2095 pool_gc2();
2096 goto retry_connect;
2097 }
Emeric Brun90951492014-11-12 17:35:37 +01002098 conn->err_code = CO_ER_SSL_NO_MEM;
2099 return -1;
2100 }
2101
2102 SSL_set_connect_state(conn->xprt_ctx);
2103 if (objt_server(conn->target)->ssl_ctx.reused_sess) {
2104 if(!SSL_set_session(conn->xprt_ctx, objt_server(conn->target)->ssl_ctx.reused_sess)) {
2105 SSL_SESSION_free(objt_server(conn->target)->ssl_ctx.reused_sess);
2106 objt_server(conn->target)->ssl_ctx.reused_sess = NULL;
2107 }
2108 }
Evan Broderbe554312013-06-27 00:05:25 -07002109
Emeric Brun46591952012-05-18 15:47:34 +02002110 /* leave init state and start handshake */
Willy Tarreau05737472012-09-04 08:03:39 +02002111 conn->flags |= CO_FL_SSL_WAIT_HS | CO_FL_WAIT_L6_CONN;
Willy Tarreau403edff2012-09-06 11:58:37 +02002112
2113 sslconns++;
Willy Tarreau71b734c2014-01-28 15:19:44 +01002114 totalsslconns++;
Emeric Brun46591952012-05-18 15:47:34 +02002115 return 0;
2116 }
Willy Tarreau3fdb3662012-11-12 00:42:33 +01002117 else if (objt_listener(conn->target)) {
Willy Tarreau9bcc01a2014-11-13 13:48:58 +01002118 int may_retry = 1;
2119
2120 retry_accept:
Emeric Brun46591952012-05-18 15:47:34 +02002121 /* Alloc a new SSL session ctx */
Willy Tarreau3fdb3662012-11-12 00:42:33 +01002122 conn->xprt_ctx = SSL_new(objt_listener(conn->target)->bind_conf->default_ctx);
Willy Tarreau20879a02012-12-03 16:32:10 +01002123 if (!conn->xprt_ctx) {
Willy Tarreau9bcc01a2014-11-13 13:48:58 +01002124 if (may_retry--) {
2125 pool_gc2();
2126 goto retry_accept;
2127 }
Willy Tarreau20879a02012-12-03 16:32:10 +01002128 conn->err_code = CO_ER_SSL_NO_MEM;
Emeric Brun46591952012-05-18 15:47:34 +02002129 return -1;
Willy Tarreau20879a02012-12-03 16:32:10 +01002130 }
Emeric Brun46591952012-05-18 15:47:34 +02002131
Emeric Brun46591952012-05-18 15:47:34 +02002132 /* set fd on SSL session context */
Emeric Brun90951492014-11-12 17:35:37 +01002133 if (!SSL_set_fd(conn->xprt_ctx, conn->t.sock.fd)) {
2134 SSL_free(conn->xprt_ctx);
2135 conn->xprt_ctx = NULL;
Willy Tarreau9bcc01a2014-11-13 13:48:58 +01002136 if (may_retry--) {
2137 pool_gc2();
2138 goto retry_accept;
2139 }
Emeric Brun90951492014-11-12 17:35:37 +01002140 conn->err_code = CO_ER_SSL_NO_MEM;
2141 return -1;
2142 }
Emeric Brun46591952012-05-18 15:47:34 +02002143
Emeric Brune1f38db2012-09-03 20:36:47 +02002144 /* set connection pointer */
Emeric Brun90951492014-11-12 17:35:37 +01002145 if (!SSL_set_app_data(conn->xprt_ctx, conn)) {
2146 SSL_free(conn->xprt_ctx);
2147 conn->xprt_ctx = NULL;
Willy Tarreau9bcc01a2014-11-13 13:48:58 +01002148 if (may_retry--) {
2149 pool_gc2();
2150 goto retry_accept;
2151 }
Emeric Brun90951492014-11-12 17:35:37 +01002152 conn->err_code = CO_ER_SSL_NO_MEM;
2153 return -1;
2154 }
2155
2156 SSL_set_accept_state(conn->xprt_ctx);
Emeric Brune1f38db2012-09-03 20:36:47 +02002157
Emeric Brun46591952012-05-18 15:47:34 +02002158 /* leave init state and start handshake */
Willy Tarreau05737472012-09-04 08:03:39 +02002159 conn->flags |= CO_FL_SSL_WAIT_HS | CO_FL_WAIT_L6_CONN;
Willy Tarreau403edff2012-09-06 11:58:37 +02002160
2161 sslconns++;
Willy Tarreau71b734c2014-01-28 15:19:44 +01002162 totalsslconns++;
Emeric Brun46591952012-05-18 15:47:34 +02002163 return 0;
2164 }
2165 /* don't know how to handle such a target */
Willy Tarreau20879a02012-12-03 16:32:10 +01002166 conn->err_code = CO_ER_SSL_NO_TARGET;
Emeric Brun46591952012-05-18 15:47:34 +02002167 return -1;
2168}
2169
2170
2171/* This is the callback which is used when an SSL handshake is pending. It
2172 * updates the FD status if it wants some polling before being called again.
2173 * It returns 0 if it fails in a fatal way or needs to poll to go further,
2174 * otherwise it returns non-zero and removes itself from the connection's
2175 * flags (the bit is provided in <flag> by the caller).
2176 */
2177int ssl_sock_handshake(struct connection *conn, unsigned int flag)
2178{
2179 int ret;
2180
Willy Tarreau3c728722014-01-23 13:50:42 +01002181 if (!conn_ctrl_ready(conn))
Willy Tarreauf79c8172013-10-21 16:30:56 +02002182 return 0;
2183
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02002184 if (!conn->xprt_ctx)
Emeric Brun46591952012-05-18 15:47:34 +02002185 goto out_error;
2186
Emeric Brun674b7432012-11-08 19:21:55 +01002187 /* If we use SSL_do_handshake to process a reneg initiated by
2188 * the remote peer, it sometimes returns SSL_ERROR_SSL.
2189 * Usually SSL_write and SSL_read are used and process implicitly
2190 * the reneg handshake.
2191 * Here we use SSL_peek as a workaround for reneg.
2192 */
2193 if ((conn->flags & CO_FL_CONNECTED) && SSL_renegotiate_pending(conn->xprt_ctx)) {
2194 char c;
2195
2196 ret = SSL_peek(conn->xprt_ctx, &c, 1);
2197 if (ret <= 0) {
2198 /* handshake may have not been completed, let's find why */
2199 ret = SSL_get_error(conn->xprt_ctx, ret);
2200 if (ret == SSL_ERROR_WANT_WRITE) {
2201 /* SSL handshake needs to write, L4 connection may not be ready */
2202 __conn_sock_stop_recv(conn);
Willy Tarreaue1f50c42014-01-22 20:02:06 +01002203 __conn_sock_want_send(conn);
2204 fd_cant_send(conn->t.sock.fd);
Emeric Brun674b7432012-11-08 19:21:55 +01002205 return 0;
2206 }
2207 else if (ret == SSL_ERROR_WANT_READ) {
2208 /* handshake may have been completed but we have
2209 * no more data to read.
2210 */
2211 if (!SSL_renegotiate_pending(conn->xprt_ctx)) {
2212 ret = 1;
2213 goto reneg_ok;
2214 }
2215 /* SSL handshake needs to read, L4 connection is ready */
2216 if (conn->flags & CO_FL_WAIT_L4_CONN)
2217 conn->flags &= ~CO_FL_WAIT_L4_CONN;
2218 __conn_sock_stop_send(conn);
Willy Tarreaue1f50c42014-01-22 20:02:06 +01002219 __conn_sock_want_recv(conn);
2220 fd_cant_recv(conn->t.sock.fd);
Emeric Brun674b7432012-11-08 19:21:55 +01002221 return 0;
2222 }
2223 else if (ret == SSL_ERROR_SYSCALL) {
2224 /* if errno is null, then connection was successfully established */
2225 if (!errno && conn->flags & CO_FL_WAIT_L4_CONN)
2226 conn->flags &= ~CO_FL_WAIT_L4_CONN;
Willy Tarreau20879a02012-12-03 16:32:10 +01002227 if (!conn->err_code) {
Emeric Brun29f037d2014-04-25 19:05:36 +02002228 if (!((SSL *)conn->xprt_ctx)->packet_length) {
2229 if (!errno) {
2230 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
2231 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
2232 else
2233 conn->err_code = CO_ER_SSL_EMPTY;
2234 }
2235 else {
2236 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
2237 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
2238 else
2239 conn->err_code = CO_ER_SSL_ABORT;
2240 }
2241 }
2242 else {
2243 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
2244 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
Willy Tarreau20879a02012-12-03 16:32:10 +01002245 else
Emeric Brun29f037d2014-04-25 19:05:36 +02002246 conn->err_code = CO_ER_SSL_HANDSHAKE;
2247 }
Willy Tarreau20879a02012-12-03 16:32:10 +01002248 }
Emeric Brun674b7432012-11-08 19:21:55 +01002249 goto out_error;
2250 }
2251 else {
2252 /* Fail on all other handshake errors */
2253 /* Note: OpenSSL may leave unread bytes in the socket's
2254 * buffer, causing an RST to be emitted upon close() on
2255 * TCP sockets. We first try to drain possibly pending
2256 * data to avoid this as much as possible.
2257 */
Willy Tarreau46be2e52014-01-20 12:10:52 +01002258 conn_drain(conn);
Willy Tarreau20879a02012-12-03 16:32:10 +01002259 if (!conn->err_code)
Willy Tarreauf51c6982014-04-25 20:02:39 +02002260 conn->err_code = (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT) ?
2261 CO_ER_SSL_KILLED_HB : CO_ER_SSL_HANDSHAKE;
Emeric Brun674b7432012-11-08 19:21:55 +01002262 goto out_error;
2263 }
2264 }
2265 /* read some data: consider handshake completed */
2266 goto reneg_ok;
2267 }
2268
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02002269 ret = SSL_do_handshake(conn->xprt_ctx);
Emeric Brun46591952012-05-18 15:47:34 +02002270 if (ret != 1) {
2271 /* handshake did not complete, let's find why */
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02002272 ret = SSL_get_error(conn->xprt_ctx, ret);
Emeric Brun46591952012-05-18 15:47:34 +02002273
2274 if (ret == SSL_ERROR_WANT_WRITE) {
2275 /* SSL handshake needs to write, L4 connection may not be ready */
2276 __conn_sock_stop_recv(conn);
Willy Tarreaue1f50c42014-01-22 20:02:06 +01002277 __conn_sock_want_send(conn);
2278 fd_cant_send(conn->t.sock.fd);
Emeric Brun46591952012-05-18 15:47:34 +02002279 return 0;
2280 }
2281 else if (ret == SSL_ERROR_WANT_READ) {
2282 /* SSL handshake needs to read, L4 connection is ready */
2283 if (conn->flags & CO_FL_WAIT_L4_CONN)
2284 conn->flags &= ~CO_FL_WAIT_L4_CONN;
2285 __conn_sock_stop_send(conn);
Willy Tarreaue1f50c42014-01-22 20:02:06 +01002286 __conn_sock_want_recv(conn);
2287 fd_cant_recv(conn->t.sock.fd);
Emeric Brun46591952012-05-18 15:47:34 +02002288 return 0;
2289 }
Willy Tarreau89230192012-09-28 20:22:13 +02002290 else if (ret == SSL_ERROR_SYSCALL) {
2291 /* if errno is null, then connection was successfully established */
2292 if (!errno && conn->flags & CO_FL_WAIT_L4_CONN)
2293 conn->flags &= ~CO_FL_WAIT_L4_CONN;
Willy Tarreau20879a02012-12-03 16:32:10 +01002294
Emeric Brun29f037d2014-04-25 19:05:36 +02002295 if (!((SSL *)conn->xprt_ctx)->packet_length) {
2296 if (!errno) {
2297 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
2298 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
2299 else
2300 conn->err_code = CO_ER_SSL_EMPTY;
2301 }
2302 else {
2303 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
2304 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
2305 else
2306 conn->err_code = CO_ER_SSL_ABORT;
2307 }
2308 }
2309 else {
2310 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
2311 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
Willy Tarreau20879a02012-12-03 16:32:10 +01002312 else
Emeric Brun29f037d2014-04-25 19:05:36 +02002313 conn->err_code = CO_ER_SSL_HANDSHAKE;
2314 }
Willy Tarreau89230192012-09-28 20:22:13 +02002315 goto out_error;
2316 }
Emeric Brun46591952012-05-18 15:47:34 +02002317 else {
2318 /* Fail on all other handshake errors */
Willy Tarreau566dc552012-10-19 20:52:18 +02002319 /* Note: OpenSSL may leave unread bytes in the socket's
2320 * buffer, causing an RST to be emitted upon close() on
2321 * TCP sockets. We first try to drain possibly pending
2322 * data to avoid this as much as possible.
2323 */
Willy Tarreau46be2e52014-01-20 12:10:52 +01002324 conn_drain(conn);
Willy Tarreau20879a02012-12-03 16:32:10 +01002325 if (!conn->err_code)
Willy Tarreauf51c6982014-04-25 20:02:39 +02002326 conn->err_code = (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT) ?
2327 CO_ER_SSL_KILLED_HB : CO_ER_SSL_HANDSHAKE;
Emeric Brun46591952012-05-18 15:47:34 +02002328 goto out_error;
2329 }
2330 }
2331
Emeric Brun674b7432012-11-08 19:21:55 +01002332reneg_ok:
2333
Emeric Brun46591952012-05-18 15:47:34 +02002334 /* Handshake succeeded */
Willy Tarreau0c9c2722014-05-28 12:28:58 +02002335 if (!SSL_session_reused(conn->xprt_ctx)) {
2336 if (objt_server(conn->target)) {
2337 update_freq_ctr(&global.ssl_be_keys_per_sec, 1);
2338 if (global.ssl_be_keys_per_sec.curr_ctr > global.ssl_be_keys_max)
2339 global.ssl_be_keys_max = global.ssl_be_keys_per_sec.curr_ctr;
2340
Emeric Brun46591952012-05-18 15:47:34 +02002341 /* check if session was reused, if not store current session on server for reuse */
Willy Tarreau3fdb3662012-11-12 00:42:33 +01002342 if (objt_server(conn->target)->ssl_ctx.reused_sess)
2343 SSL_SESSION_free(objt_server(conn->target)->ssl_ctx.reused_sess);
Emeric Brun46591952012-05-18 15:47:34 +02002344
Willy Tarreau3fdb3662012-11-12 00:42:33 +01002345 objt_server(conn->target)->ssl_ctx.reused_sess = SSL_get1_session(conn->xprt_ctx);
Emeric Brun46591952012-05-18 15:47:34 +02002346 }
Willy Tarreau0c9c2722014-05-28 12:28:58 +02002347 else {
2348 update_freq_ctr(&global.ssl_fe_keys_per_sec, 1);
2349 if (global.ssl_fe_keys_per_sec.curr_ctr > global.ssl_fe_keys_max)
2350 global.ssl_fe_keys_max = global.ssl_fe_keys_per_sec.curr_ctr;
2351 }
Emeric Brun46591952012-05-18 15:47:34 +02002352 }
2353
2354 /* The connection is now established at both layers, it's time to leave */
2355 conn->flags &= ~(flag | CO_FL_WAIT_L4_CONN | CO_FL_WAIT_L6_CONN);
2356 return 1;
2357
2358 out_error:
Emeric Brun644cde02012-12-14 11:21:13 +01002359 /* Clear openssl global errors stack */
2360 ERR_clear_error();
2361
Emeric Brun9fa89732012-10-04 17:09:56 +02002362 /* free resumed session if exists */
Willy Tarreau3fdb3662012-11-12 00:42:33 +01002363 if (objt_server(conn->target) && objt_server(conn->target)->ssl_ctx.reused_sess) {
2364 SSL_SESSION_free(objt_server(conn->target)->ssl_ctx.reused_sess);
2365 objt_server(conn->target)->ssl_ctx.reused_sess = NULL;
Emeric Brun9fa89732012-10-04 17:09:56 +02002366 }
2367
Emeric Brun46591952012-05-18 15:47:34 +02002368 /* Fail on all other handshake errors */
2369 conn->flags |= CO_FL_ERROR;
Willy Tarreau20879a02012-12-03 16:32:10 +01002370 if (!conn->err_code)
2371 conn->err_code = CO_ER_SSL_HANDSHAKE;
Emeric Brun46591952012-05-18 15:47:34 +02002372 return 0;
2373}
2374
2375/* Receive up to <count> bytes from connection <conn>'s socket and store them
Willy Tarreauabf08d92014-01-14 11:31:27 +01002376 * into buffer <buf>. Only one call to recv() is performed, unless the
Emeric Brun46591952012-05-18 15:47:34 +02002377 * buffer wraps, in which case a second call may be performed. The connection's
2378 * flags are updated with whatever special event is detected (error, read0,
2379 * empty). The caller is responsible for taking care of those events and
2380 * avoiding the call if inappropriate. The function does not call the
2381 * connection's polling update function, so the caller is responsible for this.
2382 */
2383static int ssl_sock_to_buf(struct connection *conn, struct buffer *buf, int count)
2384{
2385 int ret, done = 0;
Willy Tarreauabf08d92014-01-14 11:31:27 +01002386 int try;
Emeric Brun46591952012-05-18 15:47:34 +02002387
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02002388 if (!conn->xprt_ctx)
Emeric Brun46591952012-05-18 15:47:34 +02002389 goto out_error;
2390
2391 if (conn->flags & CO_FL_HANDSHAKE)
2392 /* a handshake was requested */
2393 return 0;
2394
Willy Tarreauabf08d92014-01-14 11:31:27 +01002395 /* let's realign the buffer to optimize I/O */
2396 if (buffer_empty(buf))
Emeric Brun46591952012-05-18 15:47:34 +02002397 buf->p = buf->data;
Emeric Brun46591952012-05-18 15:47:34 +02002398
2399 /* read the largest possible block. For this, we perform only one call
2400 * to recv() unless the buffer wraps and we exactly fill the first hunk,
2401 * in which case we accept to do it once again. A new attempt is made on
2402 * EINTR too.
2403 */
Willy Tarreau00b0fb92014-01-17 11:09:40 +01002404 while (count > 0) {
Willy Tarreauabf08d92014-01-14 11:31:27 +01002405 /* first check if we have some room after p+i */
2406 try = buf->data + buf->size - (buf->p + buf->i);
2407 /* otherwise continue between data and p-o */
2408 if (try <= 0) {
2409 try = buf->p - (buf->data + buf->o);
2410 if (try <= 0)
2411 break;
2412 }
2413 if (try > count)
2414 try = count;
2415
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02002416 ret = SSL_read(conn->xprt_ctx, bi_end(buf), try);
Emeric Brune1f38db2012-09-03 20:36:47 +02002417 if (conn->flags & CO_FL_ERROR) {
2418 /* CO_FL_ERROR may be set by ssl_sock_infocbk */
Emeric Brun644cde02012-12-14 11:21:13 +01002419 goto out_error;
Emeric Brune1f38db2012-09-03 20:36:47 +02002420 }
Emeric Brun46591952012-05-18 15:47:34 +02002421 if (ret > 0) {
2422 buf->i += ret;
2423 done += ret;
2424 if (ret < try)
2425 break;
2426 count -= ret;
Emeric Brun46591952012-05-18 15:47:34 +02002427 }
2428 else if (ret == 0) {
Emeric Brun644cde02012-12-14 11:21:13 +01002429 ret = SSL_get_error(conn->xprt_ctx, ret);
2430 if (ret != SSL_ERROR_ZERO_RETURN) {
Emeric Brun1c646862012-12-14 12:33:41 +01002431 /* error on protocol or underlying transport */
2432 if ((ret != SSL_ERROR_SYSCALL)
2433 || (errno && (errno != EAGAIN)))
2434 conn->flags |= CO_FL_ERROR;
2435
Emeric Brun644cde02012-12-14 11:21:13 +01002436 /* Clear openssl global errors stack */
2437 ERR_clear_error();
2438 }
Emeric Brun46591952012-05-18 15:47:34 +02002439 goto read0;
2440 }
2441 else {
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02002442 ret = SSL_get_error(conn->xprt_ctx, ret);
Emeric Brun46591952012-05-18 15:47:34 +02002443 if (ret == SSL_ERROR_WANT_WRITE) {
Emeric Brun8af8dd12012-11-08 17:56:20 +01002444 /* handshake is running, and it needs to enable write */
Emeric Brun46591952012-05-18 15:47:34 +02002445 conn->flags |= CO_FL_SSL_WAIT_HS;
Emeric Brun8af8dd12012-11-08 17:56:20 +01002446 __conn_sock_want_send(conn);
Emeric Brun46591952012-05-18 15:47:34 +02002447 break;
2448 }
2449 else if (ret == SSL_ERROR_WANT_READ) {
Emeric Brun282a76a2012-11-08 18:02:56 +01002450 if (SSL_renegotiate_pending(conn->xprt_ctx)) {
2451 /* handshake is running, and it may need to re-enable read */
2452 conn->flags |= CO_FL_SSL_WAIT_HS;
2453 __conn_sock_want_recv(conn);
2454 break;
2455 }
Emeric Brun46591952012-05-18 15:47:34 +02002456 /* we need to poll for retry a read later */
Willy Tarreaue1f50c42014-01-22 20:02:06 +01002457 fd_cant_recv(conn->t.sock.fd);
Emeric Brun46591952012-05-18 15:47:34 +02002458 break;
2459 }
2460 /* otherwise it's a real error */
2461 goto out_error;
2462 }
2463 }
2464 return done;
2465
2466 read0:
2467 conn_sock_read0(conn);
2468 return done;
2469 out_error:
Emeric Brun644cde02012-12-14 11:21:13 +01002470 /* Clear openssl global errors stack */
2471 ERR_clear_error();
2472
Emeric Brun46591952012-05-18 15:47:34 +02002473 conn->flags |= CO_FL_ERROR;
2474 return done;
2475}
2476
2477
2478/* Send all pending bytes from buffer <buf> to connection <conn>'s socket.
Willy Tarreau1049b1f2014-02-02 01:51:17 +01002479 * <flags> may contain some CO_SFL_* flags to hint the system about other
2480 * pending data for example, but this flag is ignored at the moment.
Emeric Brun46591952012-05-18 15:47:34 +02002481 * Only one call to send() is performed, unless the buffer wraps, in which case
2482 * a second call may be performed. The connection's flags are updated with
2483 * whatever special event is detected (error, empty). The caller is responsible
2484 * for taking care of those events and avoiding the call if inappropriate. The
2485 * function does not call the connection's polling update function, so the caller
2486 * is responsible for this.
2487 */
2488static int ssl_sock_from_buf(struct connection *conn, struct buffer *buf, int flags)
2489{
2490 int ret, try, done;
2491
2492 done = 0;
2493
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02002494 if (!conn->xprt_ctx)
Emeric Brun46591952012-05-18 15:47:34 +02002495 goto out_error;
2496
2497 if (conn->flags & CO_FL_HANDSHAKE)
2498 /* a handshake was requested */
2499 return 0;
2500
2501 /* send the largest possible block. For this we perform only one call
2502 * to send() unless the buffer wraps and we exactly fill the first hunk,
2503 * in which case we accept to do it once again.
2504 */
2505 while (buf->o) {
Kevin Hestercad82342013-05-30 15:12:41 -07002506 try = bo_contig_data(buf);
Willy Tarreaubfd59462013-02-21 07:46:09 +01002507
Willy Tarreau7bed9452014-02-02 02:00:24 +01002508 if (!(flags & CO_SFL_STREAMER) &&
Willy Tarreau518cedd2014-02-17 15:43:01 +01002509 !(conn->xprt_st & SSL_SOCK_SEND_UNLIMITED) &&
2510 global.tune.ssl_max_record && try > global.tune.ssl_max_record) {
Willy Tarreaubfd59462013-02-21 07:46:09 +01002511 try = global.tune.ssl_max_record;
Willy Tarreau518cedd2014-02-17 15:43:01 +01002512 }
2513 else {
2514 /* we need to keep the information about the fact that
2515 * we're not limiting the upcoming send(), because if it
2516 * fails, we'll have to retry with at least as many data.
2517 */
2518 conn->xprt_st |= SSL_SOCK_SEND_UNLIMITED;
2519 }
Willy Tarreaubfd59462013-02-21 07:46:09 +01002520
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02002521 ret = SSL_write(conn->xprt_ctx, bo_ptr(buf), try);
Willy Tarreau518cedd2014-02-17 15:43:01 +01002522
Emeric Brune1f38db2012-09-03 20:36:47 +02002523 if (conn->flags & CO_FL_ERROR) {
2524 /* CO_FL_ERROR may be set by ssl_sock_infocbk */
Emeric Brun644cde02012-12-14 11:21:13 +01002525 goto out_error;
Emeric Brune1f38db2012-09-03 20:36:47 +02002526 }
Emeric Brun46591952012-05-18 15:47:34 +02002527 if (ret > 0) {
Willy Tarreau518cedd2014-02-17 15:43:01 +01002528 conn->xprt_st &= ~SSL_SOCK_SEND_UNLIMITED;
2529
Emeric Brun46591952012-05-18 15:47:34 +02002530 buf->o -= ret;
2531 done += ret;
2532
Willy Tarreau5fb38032012-12-16 19:39:09 +01002533 if (likely(buffer_empty(buf)))
Emeric Brun46591952012-05-18 15:47:34 +02002534 /* optimize data alignment in the buffer */
2535 buf->p = buf->data;
2536
2537 /* if the system buffer is full, don't insist */
2538 if (ret < try)
2539 break;
2540 }
2541 else {
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02002542 ret = SSL_get_error(conn->xprt_ctx, ret);
Emeric Brun46591952012-05-18 15:47:34 +02002543 if (ret == SSL_ERROR_WANT_WRITE) {
Emeric Brun282a76a2012-11-08 18:02:56 +01002544 if (SSL_renegotiate_pending(conn->xprt_ctx)) {
2545 /* handshake is running, and it may need to re-enable write */
2546 conn->flags |= CO_FL_SSL_WAIT_HS;
2547 __conn_sock_want_send(conn);
2548 break;
2549 }
Emeric Brun46591952012-05-18 15:47:34 +02002550 /* we need to poll to retry a write later */
Willy Tarreaue1f50c42014-01-22 20:02:06 +01002551 fd_cant_send(conn->t.sock.fd);
Emeric Brun46591952012-05-18 15:47:34 +02002552 break;
2553 }
2554 else if (ret == SSL_ERROR_WANT_READ) {
Emeric Brun8af8dd12012-11-08 17:56:20 +01002555 /* handshake is running, and it needs to enable read */
Emeric Brun46591952012-05-18 15:47:34 +02002556 conn->flags |= CO_FL_SSL_WAIT_HS;
Emeric Brun8af8dd12012-11-08 17:56:20 +01002557 __conn_sock_want_recv(conn);
Emeric Brun46591952012-05-18 15:47:34 +02002558 break;
2559 }
2560 goto out_error;
2561 }
2562 }
2563 return done;
2564
2565 out_error:
Emeric Brun644cde02012-12-14 11:21:13 +01002566 /* Clear openssl global errors stack */
2567 ERR_clear_error();
2568
Emeric Brun46591952012-05-18 15:47:34 +02002569 conn->flags |= CO_FL_ERROR;
2570 return done;
2571}
2572
Emeric Brun46591952012-05-18 15:47:34 +02002573static void ssl_sock_close(struct connection *conn) {
2574
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02002575 if (conn->xprt_ctx) {
2576 SSL_free(conn->xprt_ctx);
2577 conn->xprt_ctx = NULL;
Willy Tarreau403edff2012-09-06 11:58:37 +02002578 sslconns--;
Emeric Brun46591952012-05-18 15:47:34 +02002579 }
Emeric Brun46591952012-05-18 15:47:34 +02002580}
2581
2582/* This function tries to perform a clean shutdown on an SSL connection, and in
2583 * any case, flags the connection as reusable if no handshake was in progress.
2584 */
2585static void ssl_sock_shutw(struct connection *conn, int clean)
2586{
2587 if (conn->flags & CO_FL_HANDSHAKE)
2588 return;
2589 /* no handshake was in progress, try a clean ssl shutdown */
Emeric Brun644cde02012-12-14 11:21:13 +01002590 if (clean && (SSL_shutdown(conn->xprt_ctx) <= 0)) {
2591 /* Clear openssl global errors stack */
2592 ERR_clear_error();
2593 }
Emeric Brun46591952012-05-18 15:47:34 +02002594
2595 /* force flag on ssl to keep session in cache regardless shutdown result */
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02002596 SSL_set_shutdown(conn->xprt_ctx, SSL_SENT_SHUTDOWN);
Emeric Brun46591952012-05-18 15:47:34 +02002597}
2598
Willy Tarreauffc3fcd2012-10-12 20:17:54 +02002599/* used for logging, may be changed for a sample fetch later */
2600const char *ssl_sock_get_cipher_name(struct connection *conn)
2601{
2602 if (!conn->xprt && !conn->xprt_ctx)
2603 return NULL;
2604 return SSL_get_cipher_name(conn->xprt_ctx);
2605}
2606
2607/* used for logging, may be changed for a sample fetch later */
2608const char *ssl_sock_get_proto_version(struct connection *conn)
2609{
2610 if (!conn->xprt && !conn->xprt_ctx)
2611 return NULL;
2612 return SSL_get_version(conn->xprt_ctx);
2613}
2614
Willy Tarreau8d598402012-10-22 17:58:39 +02002615/* Extract a serial from a cert, and copy it to a chunk.
2616 * Returns 1 if serial is found and copied, 0 if no serial found and
2617 * -1 if output is not large enough.
2618 */
2619static int
2620ssl_sock_get_serial(X509 *crt, struct chunk *out)
2621{
2622 ASN1_INTEGER *serial;
2623
2624 serial = X509_get_serialNumber(crt);
2625 if (!serial)
2626 return 0;
2627
2628 if (out->size < serial->length)
2629 return -1;
2630
2631 memcpy(out->str, serial->data, serial->length);
2632 out->len = serial->length;
2633 return 1;
2634}
2635
Emeric Brunb3cc4252014-10-29 19:03:26 +01002636/* Extract a cert to der, and copy it to a chunk.
2637 * Returns 1 if cert is found and copied, 0 on der convertion failure and
2638 * -1 if output is not large enough.
2639 */
2640static int
2641ssl_sock_crt2der(X509 *crt, struct chunk *out)
2642{
2643 int len;
2644 unsigned char *p = (unsigned char *)out->str;;
2645
2646 len =i2d_X509(crt, NULL);
2647 if (len <= 0)
2648 return 1;
2649
2650 if (out->size < len)
2651 return -1;
2652
2653 i2d_X509(crt,&p);
2654 out->len = len;
2655 return 1;
2656}
2657
Emeric Brunce5ad802012-10-22 14:11:22 +02002658
2659/* Copy Date in ASN1_UTCTIME format in struct chunk out.
2660 * Returns 1 if serial is found and copied, 0 if no valid time found
2661 * and -1 if output is not large enough.
2662 */
2663static int
2664ssl_sock_get_time(ASN1_TIME *tm, struct chunk *out)
2665{
2666 if (tm->type == V_ASN1_GENERALIZEDTIME) {
2667 ASN1_GENERALIZEDTIME *gentm = (ASN1_GENERALIZEDTIME *)tm;
2668
2669 if (gentm->length < 12)
2670 return 0;
2671 if (gentm->data[0] != 0x32 || gentm->data[1] != 0x30)
2672 return 0;
2673 if (out->size < gentm->length-2)
2674 return -1;
2675
2676 memcpy(out->str, gentm->data+2, gentm->length-2);
2677 out->len = gentm->length-2;
2678 return 1;
2679 }
2680 else if (tm->type == V_ASN1_UTCTIME) {
2681 ASN1_UTCTIME *utctm = (ASN1_UTCTIME *)tm;
2682
2683 if (utctm->length < 10)
2684 return 0;
2685 if (utctm->data[0] >= 0x35)
2686 return 0;
2687 if (out->size < utctm->length)
2688 return -1;
2689
2690 memcpy(out->str, utctm->data, utctm->length);
2691 out->len = utctm->length;
2692 return 1;
2693 }
2694
2695 return 0;
2696}
2697
Emeric Brun87855892012-10-17 17:39:35 +02002698/* Extract an entry from a X509_NAME and copy its value to an output chunk.
2699 * Returns 1 if entry found, 0 if entry not found, or -1 if output not large enough.
2700 */
2701static int
2702ssl_sock_get_dn_entry(X509_NAME *a, const struct chunk *entry, int pos, struct chunk *out)
2703{
2704 X509_NAME_ENTRY *ne;
2705 int i, j, n;
2706 int cur = 0;
2707 const char *s;
2708 char tmp[128];
2709
2710 out->len = 0;
2711 for (i = 0; i < sk_X509_NAME_ENTRY_num(a->entries); i++) {
2712 if (pos < 0)
2713 j = (sk_X509_NAME_ENTRY_num(a->entries)-1) - i;
2714 else
2715 j = i;
2716
2717 ne = sk_X509_NAME_ENTRY_value(a->entries, j);
2718 n = OBJ_obj2nid(ne->object);
2719 if ((n == NID_undef) || ((s = OBJ_nid2sn(n)) == NULL)) {
2720 i2t_ASN1_OBJECT(tmp, sizeof(tmp), ne->object);
2721 s = tmp;
2722 }
2723
2724 if (chunk_strcasecmp(entry, s) != 0)
2725 continue;
2726
2727 if (pos < 0)
2728 cur--;
2729 else
2730 cur++;
2731
2732 if (cur != pos)
2733 continue;
2734
2735 if (ne->value->length > out->size)
2736 return -1;
2737
2738 memcpy(out->str, ne->value->data, ne->value->length);
2739 out->len = ne->value->length;
2740 return 1;
2741 }
2742
2743 return 0;
2744
2745}
2746
2747/* Extract and format full DN from a X509_NAME and copy result into a chunk
2748 * Returns 1 if dn entries exits, 0 if no dn entry found or -1 if output is not large enough.
2749 */
2750static int
2751ssl_sock_get_dn_oneline(X509_NAME *a, struct chunk *out)
2752{
2753 X509_NAME_ENTRY *ne;
2754 int i, n, ln;
2755 int l = 0;
2756 const char *s;
2757 char *p;
2758 char tmp[128];
2759
2760 out->len = 0;
2761 p = out->str;
2762 for (i = 0; i < sk_X509_NAME_ENTRY_num(a->entries); i++) {
2763 ne = sk_X509_NAME_ENTRY_value(a->entries, i);
2764 n = OBJ_obj2nid(ne->object);
2765 if ((n == NID_undef) || ((s = OBJ_nid2sn(n)) == NULL)) {
2766 i2t_ASN1_OBJECT(tmp, sizeof(tmp), ne->object);
2767 s = tmp;
2768 }
2769 ln = strlen(s);
2770
2771 l += 1 + ln + 1 + ne->value->length;
2772 if (l > out->size)
2773 return -1;
2774 out->len = l;
2775
2776 *(p++)='/';
2777 memcpy(p, s, ln);
2778 p += ln;
2779 *(p++)='=';
2780 memcpy(p, ne->value->data, ne->value->length);
2781 p += ne->value->length;
2782 }
2783
2784 if (!out->len)
2785 return 0;
2786
2787 return 1;
2788}
2789
David Safb76832014-05-08 23:42:08 -04002790char *ssl_sock_get_version(struct connection *conn)
2791{
2792 if (!ssl_sock_is_ssl(conn))
2793 return NULL;
2794
2795 return (char *)SSL_get_version(conn->xprt_ctx);
2796}
2797
Emeric Brun49100982014-06-24 18:26:41 +02002798/* Extract peer certificate's common name into the chunk dest
2799 * Returns
2800 * the len of the extracted common name
2801 * or 0 if no CN found in DN
2802 * or -1 on error case (i.e. no peer certificate)
2803 */
2804int ssl_sock_get_remote_common_name(struct connection *conn, struct chunk *dest)
David Safb76832014-05-08 23:42:08 -04002805{
2806 X509 *crt = NULL;
2807 X509_NAME *name;
David Safb76832014-05-08 23:42:08 -04002808 const char find_cn[] = "CN";
2809 const struct chunk find_cn_chunk = {
2810 .str = (char *)&find_cn,
2811 .len = sizeof(find_cn)-1
2812 };
Emeric Brun49100982014-06-24 18:26:41 +02002813 int result = -1;
David Safb76832014-05-08 23:42:08 -04002814
2815 if (!ssl_sock_is_ssl(conn))
Emeric Brun49100982014-06-24 18:26:41 +02002816 goto out;
David Safb76832014-05-08 23:42:08 -04002817
2818 /* SSL_get_peer_certificate, it increase X509 * ref count */
2819 crt = SSL_get_peer_certificate(conn->xprt_ctx);
2820 if (!crt)
2821 goto out;
2822
2823 name = X509_get_subject_name(crt);
2824 if (!name)
2825 goto out;
David Safb76832014-05-08 23:42:08 -04002826
Emeric Brun49100982014-06-24 18:26:41 +02002827 result = ssl_sock_get_dn_entry(name, &find_cn_chunk, 1, dest);
2828out:
David Safb76832014-05-08 23:42:08 -04002829 if (crt)
2830 X509_free(crt);
2831
2832 return result;
2833}
2834
Dave McCowand6ec6052014-07-30 10:39:13 -04002835/* returns 1 if client passed a certificate for this session, 0 if not */
2836int ssl_sock_get_cert_used_sess(struct connection *conn)
2837{
2838 X509 *crt = NULL;
2839
2840 if (!ssl_sock_is_ssl(conn))
2841 return 0;
2842
2843 /* SSL_get_peer_certificate, it increase X509 * ref count */
2844 crt = SSL_get_peer_certificate(conn->xprt_ctx);
2845 if (!crt)
2846 return 0;
2847
2848 X509_free(crt);
2849 return 1;
2850}
2851
2852/* returns 1 if client passed a certificate for this connection, 0 if not */
2853int ssl_sock_get_cert_used_conn(struct connection *conn)
David Safb76832014-05-08 23:42:08 -04002854{
2855 if (!ssl_sock_is_ssl(conn))
2856 return 0;
2857
2858 return SSL_SOCK_ST_FL_VERIFY_DONE & conn->xprt_st ? 1 : 0;
2859}
2860
2861/* returns result from SSL verify */
2862unsigned int ssl_sock_get_verify_result(struct connection *conn)
2863{
2864 if (!ssl_sock_is_ssl(conn))
2865 return (unsigned int)X509_V_ERR_APPLICATION_VERIFICATION;
2866
2867 return (unsigned int)SSL_get_verify_result(conn->xprt_ctx);
2868}
2869
Willy Tarreau7875d092012-09-10 08:20:03 +02002870/***** Below are some sample fetching functions for ACL/patterns *****/
2871
Emeric Brune64aef12012-09-21 13:15:06 +02002872/* boolean, returns true if client cert was present */
2873static int
Emeric Brun2525b6b2012-10-18 15:59:43 +02002874smp_fetch_ssl_fc_has_crt(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002875 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brune64aef12012-09-21 13:15:06 +02002876{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002877 struct connection *conn;
2878
2879 if (!l4)
2880 return 0;
2881
2882 conn = objt_conn(l4->si[0].end);
2883 if (!conn || conn->xprt != &ssl_sock)
Emeric Brune64aef12012-09-21 13:15:06 +02002884 return 0;
2885
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002886 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brune64aef12012-09-21 13:15:06 +02002887 smp->flags |= SMP_F_MAY_CHANGE;
2888 return 0;
2889 }
2890
2891 smp->flags = 0;
2892 smp->type = SMP_T_BOOL;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002893 smp->data.uint = SSL_SOCK_ST_FL_VERIFY_DONE & conn->xprt_st ? 1 : 0;
Emeric Brune64aef12012-09-21 13:15:06 +02002894
2895 return 1;
2896}
2897
Emeric Brunb3cc4252014-10-29 19:03:26 +01002898/* binary, returns a certificate in a binary chunk (der/raw).
2899 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
2900 * should be use.
2901 */
2902static int
2903smp_fetch_ssl_x_der(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
2904 const struct arg *args, struct sample *smp, const char *kw)
2905{
2906 int cert_peer = (kw[4] == 'c') ? 1 : 0;
2907 X509 *crt = NULL;
2908 int ret = 0;
2909 struct chunk *smp_trash;
2910 struct connection *conn;
2911
2912 if (!l4)
2913 return 0;
2914
2915 conn = objt_conn(l4->si[0].end);
2916 if (!conn || conn->xprt != &ssl_sock)
2917 return 0;
2918
2919 if (!(conn->flags & CO_FL_CONNECTED)) {
2920 smp->flags |= SMP_F_MAY_CHANGE;
2921 return 0;
2922 }
2923
2924 if (cert_peer)
2925 crt = SSL_get_peer_certificate(conn->xprt_ctx);
2926 else
2927 crt = SSL_get_certificate(conn->xprt_ctx);
2928
2929 if (!crt)
2930 goto out;
2931
2932 smp_trash = get_trash_chunk();
2933 if (ssl_sock_crt2der(crt, smp_trash) <= 0)
2934 goto out;
2935
2936 smp->data.str = *smp_trash;
2937 smp->type = SMP_T_BIN;
2938 ret = 1;
2939out:
2940 /* SSL_get_peer_certificate, it increase X509 * ref count */
2941 if (cert_peer && crt)
2942 X509_free(crt);
2943 return ret;
2944}
2945
Emeric Brunba841a12014-04-30 17:05:08 +02002946/* binary, returns serial of certificate in a binary chunk.
2947 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
2948 * should be use.
2949 */
Willy Tarreau8d598402012-10-22 17:58:39 +02002950static int
Emeric Brunba841a12014-04-30 17:05:08 +02002951smp_fetch_ssl_x_serial(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002952 const struct arg *args, struct sample *smp, const char *kw)
Willy Tarreau8d598402012-10-22 17:58:39 +02002953{
Emeric Brunba841a12014-04-30 17:05:08 +02002954 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Willy Tarreau8d598402012-10-22 17:58:39 +02002955 X509 *crt = NULL;
2956 int ret = 0;
2957 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002958 struct connection *conn;
2959
2960 if (!l4)
2961 return 0;
Willy Tarreau8d598402012-10-22 17:58:39 +02002962
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002963 conn = objt_conn(l4->si[0].end);
2964 if (!conn || conn->xprt != &ssl_sock)
Willy Tarreau8d598402012-10-22 17:58:39 +02002965 return 0;
2966
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002967 if (!(conn->flags & CO_FL_CONNECTED)) {
Willy Tarreau8d598402012-10-22 17:58:39 +02002968 smp->flags |= SMP_F_MAY_CHANGE;
2969 return 0;
2970 }
2971
Emeric Brunba841a12014-04-30 17:05:08 +02002972 if (cert_peer)
2973 crt = SSL_get_peer_certificate(conn->xprt_ctx);
2974 else
2975 crt = SSL_get_certificate(conn->xprt_ctx);
2976
Willy Tarreau8d598402012-10-22 17:58:39 +02002977 if (!crt)
2978 goto out;
2979
Willy Tarreau47ca5452012-12-23 20:22:19 +01002980 smp_trash = get_trash_chunk();
Willy Tarreau8d598402012-10-22 17:58:39 +02002981 if (ssl_sock_get_serial(crt, smp_trash) <= 0)
2982 goto out;
2983
2984 smp->data.str = *smp_trash;
2985 smp->type = SMP_T_BIN;
2986 ret = 1;
2987out:
Emeric Brunba841a12014-04-30 17:05:08 +02002988 /* SSL_get_peer_certificate, it increase X509 * ref count */
2989 if (cert_peer && crt)
Willy Tarreau8d598402012-10-22 17:58:39 +02002990 X509_free(crt);
2991 return ret;
2992}
Emeric Brune64aef12012-09-21 13:15:06 +02002993
Emeric Brunba841a12014-04-30 17:05:08 +02002994/* binary, returns the client certificate's SHA-1 fingerprint (SHA-1 hash of DER-encoded certificate) in a binary chunk.
2995 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
2996 * should be use.
2997 */
James Votha051b4a2013-05-14 20:37:59 +02002998static int
Emeric Brunba841a12014-04-30 17:05:08 +02002999smp_fetch_ssl_x_sha1(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003000 const struct arg *args, struct sample *smp, const char *kw)
James Votha051b4a2013-05-14 20:37:59 +02003001{
Emeric Brunba841a12014-04-30 17:05:08 +02003002 int cert_peer = (kw[4] == 'c') ? 1 : 0;
James Votha051b4a2013-05-14 20:37:59 +02003003 X509 *crt = NULL;
3004 const EVP_MD *digest;
3005 int ret = 0;
3006 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003007 struct connection *conn;
James Votha051b4a2013-05-14 20:37:59 +02003008
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003009 if (!l4)
James Votha051b4a2013-05-14 20:37:59 +02003010 return 0;
3011
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003012 conn = objt_conn(l4->si[0].end);
3013 if (!conn || conn->xprt != &ssl_sock)
3014 return 0;
3015
3016 if (!(conn->flags & CO_FL_CONNECTED)) {
James Votha051b4a2013-05-14 20:37:59 +02003017 smp->flags |= SMP_F_MAY_CHANGE;
3018 return 0;
3019 }
3020
Emeric Brunba841a12014-04-30 17:05:08 +02003021 if (cert_peer)
3022 crt = SSL_get_peer_certificate(conn->xprt_ctx);
3023 else
3024 crt = SSL_get_certificate(conn->xprt_ctx);
James Votha051b4a2013-05-14 20:37:59 +02003025 if (!crt)
3026 goto out;
3027
3028 smp_trash = get_trash_chunk();
3029 digest = EVP_sha1();
3030 X509_digest(crt, digest, (unsigned char *)smp_trash->str, (unsigned int *)&smp_trash->len);
3031
3032 smp->data.str = *smp_trash;
3033 smp->type = SMP_T_BIN;
3034 ret = 1;
3035out:
Emeric Brunba841a12014-04-30 17:05:08 +02003036 /* SSL_get_peer_certificate, it increase X509 * ref count */
3037 if (cert_peer && crt)
James Votha051b4a2013-05-14 20:37:59 +02003038 X509_free(crt);
3039 return ret;
3040}
3041
Emeric Brunba841a12014-04-30 17:05:08 +02003042/* string, returns certificate's notafter date in ASN1_UTCTIME format.
3043 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
3044 * should be use.
3045 */
Emeric Brunce5ad802012-10-22 14:11:22 +02003046static int
Emeric Brunba841a12014-04-30 17:05:08 +02003047smp_fetch_ssl_x_notafter(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003048 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brunce5ad802012-10-22 14:11:22 +02003049{
Emeric Brunba841a12014-04-30 17:05:08 +02003050 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brunce5ad802012-10-22 14:11:22 +02003051 X509 *crt = NULL;
3052 int ret = 0;
3053 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003054 struct connection *conn;
Emeric Brunce5ad802012-10-22 14:11:22 +02003055
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003056 if (!l4)
Emeric Brunce5ad802012-10-22 14:11:22 +02003057 return 0;
3058
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003059 conn = objt_conn(l4->si[0].end);
3060 if (!conn || conn->xprt != &ssl_sock)
3061 return 0;
3062
3063 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunce5ad802012-10-22 14:11:22 +02003064 smp->flags |= SMP_F_MAY_CHANGE;
3065 return 0;
3066 }
3067
Emeric Brunba841a12014-04-30 17:05:08 +02003068 if (cert_peer)
3069 crt = SSL_get_peer_certificate(conn->xprt_ctx);
3070 else
3071 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brunce5ad802012-10-22 14:11:22 +02003072 if (!crt)
3073 goto out;
3074
Willy Tarreau47ca5452012-12-23 20:22:19 +01003075 smp_trash = get_trash_chunk();
Emeric Brunce5ad802012-10-22 14:11:22 +02003076 if (ssl_sock_get_time(X509_get_notAfter(crt), smp_trash) <= 0)
3077 goto out;
3078
3079 smp->data.str = *smp_trash;
3080 smp->type = SMP_T_STR;
3081 ret = 1;
3082out:
Emeric Brunba841a12014-04-30 17:05:08 +02003083 /* SSL_get_peer_certificate, it increase X509 * ref count */
3084 if (cert_peer && crt)
Emeric Brunce5ad802012-10-22 14:11:22 +02003085 X509_free(crt);
3086 return ret;
3087}
3088
Emeric Brunba841a12014-04-30 17:05:08 +02003089/* string, returns a string of a formatted full dn \C=..\O=..\OU=.. \CN=.. of certificate's issuer
3090 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
3091 * should be use.
3092 */
Emeric Brun87855892012-10-17 17:39:35 +02003093static int
Emeric Brunba841a12014-04-30 17:05:08 +02003094smp_fetch_ssl_x_i_dn(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003095 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brun87855892012-10-17 17:39:35 +02003096{
Emeric Brunba841a12014-04-30 17:05:08 +02003097 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brun87855892012-10-17 17:39:35 +02003098 X509 *crt = NULL;
3099 X509_NAME *name;
3100 int ret = 0;
3101 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003102 struct connection *conn;
Emeric Brun87855892012-10-17 17:39:35 +02003103
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003104 if (!l4)
Emeric Brun87855892012-10-17 17:39:35 +02003105 return 0;
3106
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003107 conn = objt_conn(l4->si[0].end);
3108 if (!conn || conn->xprt != &ssl_sock)
3109 return 0;
3110
3111 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun87855892012-10-17 17:39:35 +02003112 smp->flags |= SMP_F_MAY_CHANGE;
3113 return 0;
3114 }
3115
Emeric Brunba841a12014-04-30 17:05:08 +02003116 if (cert_peer)
3117 crt = SSL_get_peer_certificate(conn->xprt_ctx);
3118 else
3119 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brun87855892012-10-17 17:39:35 +02003120 if (!crt)
3121 goto out;
3122
3123 name = X509_get_issuer_name(crt);
3124 if (!name)
3125 goto out;
3126
Willy Tarreau47ca5452012-12-23 20:22:19 +01003127 smp_trash = get_trash_chunk();
Emeric Brun87855892012-10-17 17:39:35 +02003128 if (args && args[0].type == ARGT_STR) {
3129 int pos = 1;
3130
3131 if (args[1].type == ARGT_SINT)
3132 pos = args[1].data.sint;
3133 else if (args[1].type == ARGT_UINT)
3134 pos =(int)args[1].data.uint;
3135
3136 if (ssl_sock_get_dn_entry(name, &args[0].data.str, pos, smp_trash) <= 0)
3137 goto out;
3138 }
3139 else if (ssl_sock_get_dn_oneline(name, smp_trash) <= 0)
3140 goto out;
3141
3142 smp->type = SMP_T_STR;
3143 smp->data.str = *smp_trash;
3144 ret = 1;
3145out:
Emeric Brunba841a12014-04-30 17:05:08 +02003146 /* SSL_get_peer_certificate, it increase X509 * ref count */
3147 if (cert_peer && crt)
Emeric Brun87855892012-10-17 17:39:35 +02003148 X509_free(crt);
3149 return ret;
3150}
3151
Emeric Brunba841a12014-04-30 17:05:08 +02003152/* string, returns notbefore date in ASN1_UTCTIME format.
3153 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
3154 * should be use.
3155 */
Emeric Brunce5ad802012-10-22 14:11:22 +02003156static int
Emeric Brunba841a12014-04-30 17:05:08 +02003157smp_fetch_ssl_x_notbefore(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003158 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brunce5ad802012-10-22 14:11:22 +02003159{
Emeric Brunba841a12014-04-30 17:05:08 +02003160 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brunce5ad802012-10-22 14:11:22 +02003161 X509 *crt = NULL;
3162 int ret = 0;
3163 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003164 struct connection *conn;
3165
3166 if (!l4)
3167 return 0;
Emeric Brunce5ad802012-10-22 14:11:22 +02003168
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003169 conn = objt_conn(l4->si[0].end);
3170 if (!conn || conn->xprt != &ssl_sock)
Emeric Brunce5ad802012-10-22 14:11:22 +02003171 return 0;
3172
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003173 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunce5ad802012-10-22 14:11:22 +02003174 smp->flags |= SMP_F_MAY_CHANGE;
3175 return 0;
3176 }
3177
Emeric Brunba841a12014-04-30 17:05:08 +02003178 if (cert_peer)
3179 crt = SSL_get_peer_certificate(conn->xprt_ctx);
3180 else
3181 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brunce5ad802012-10-22 14:11:22 +02003182 if (!crt)
3183 goto out;
3184
Willy Tarreau47ca5452012-12-23 20:22:19 +01003185 smp_trash = get_trash_chunk();
Emeric Brunce5ad802012-10-22 14:11:22 +02003186 if (ssl_sock_get_time(X509_get_notBefore(crt), smp_trash) <= 0)
3187 goto out;
3188
3189 smp->data.str = *smp_trash;
3190 smp->type = SMP_T_STR;
3191 ret = 1;
3192out:
Emeric Brunba841a12014-04-30 17:05:08 +02003193 /* SSL_get_peer_certificate, it increase X509 * ref count */
3194 if (cert_peer && crt)
Emeric Brunce5ad802012-10-22 14:11:22 +02003195 X509_free(crt);
3196 return ret;
3197}
3198
Emeric Brunba841a12014-04-30 17:05:08 +02003199/* string, returns a string of a formatted full dn \C=..\O=..\OU=.. \CN=.. of certificate's subject
3200 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
3201 * should be use.
3202 */
Emeric Brun87855892012-10-17 17:39:35 +02003203static int
Emeric Brunba841a12014-04-30 17:05:08 +02003204smp_fetch_ssl_x_s_dn(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003205 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brun87855892012-10-17 17:39:35 +02003206{
Emeric Brunba841a12014-04-30 17:05:08 +02003207 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brun87855892012-10-17 17:39:35 +02003208 X509 *crt = NULL;
3209 X509_NAME *name;
3210 int ret = 0;
3211 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003212 struct connection *conn;
Emeric Brun87855892012-10-17 17:39:35 +02003213
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003214 if (!l4)
Emeric Brun87855892012-10-17 17:39:35 +02003215 return 0;
3216
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003217 conn = objt_conn(l4->si[0].end);
3218 if (!conn || conn->xprt != &ssl_sock)
3219 return 0;
3220
3221 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun87855892012-10-17 17:39:35 +02003222 smp->flags |= SMP_F_MAY_CHANGE;
3223 return 0;
3224 }
3225
Emeric Brunba841a12014-04-30 17:05:08 +02003226 if (cert_peer)
3227 crt = SSL_get_peer_certificate(conn->xprt_ctx);
3228 else
3229 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brun87855892012-10-17 17:39:35 +02003230 if (!crt)
3231 goto out;
3232
3233 name = X509_get_subject_name(crt);
3234 if (!name)
3235 goto out;
3236
Willy Tarreau47ca5452012-12-23 20:22:19 +01003237 smp_trash = get_trash_chunk();
Emeric Brun87855892012-10-17 17:39:35 +02003238 if (args && args[0].type == ARGT_STR) {
3239 int pos = 1;
3240
3241 if (args[1].type == ARGT_SINT)
3242 pos = args[1].data.sint;
3243 else if (args[1].type == ARGT_UINT)
3244 pos =(int)args[1].data.uint;
3245
3246 if (ssl_sock_get_dn_entry(name, &args[0].data.str, pos, smp_trash) <= 0)
3247 goto out;
3248 }
3249 else if (ssl_sock_get_dn_oneline(name, smp_trash) <= 0)
3250 goto out;
3251
3252 smp->type = SMP_T_STR;
3253 smp->data.str = *smp_trash;
3254 ret = 1;
3255out:
Emeric Brunba841a12014-04-30 17:05:08 +02003256 /* SSL_get_peer_certificate, it increase X509 * ref count */
3257 if (cert_peer && crt)
Emeric Brun87855892012-10-17 17:39:35 +02003258 X509_free(crt);
3259 return ret;
3260}
Emeric Brun9143d372012-12-20 15:44:16 +01003261
3262/* integer, returns true if current session use a client certificate */
3263static int
3264smp_fetch_ssl_c_used(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003265 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brun9143d372012-12-20 15:44:16 +01003266{
3267 X509 *crt;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003268 struct connection *conn;
Emeric Brun9143d372012-12-20 15:44:16 +01003269
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003270 if (!l4)
Emeric Brun9143d372012-12-20 15:44:16 +01003271 return 0;
3272
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003273 conn = objt_conn(l4->si[0].end);
3274 if (!conn || conn->xprt != &ssl_sock)
3275 return 0;
3276
3277 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun9143d372012-12-20 15:44:16 +01003278 smp->flags |= SMP_F_MAY_CHANGE;
3279 return 0;
3280 }
3281
3282 /* SSL_get_peer_certificate returns a ptr on allocated X509 struct */
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003283 crt = SSL_get_peer_certificate(conn->xprt_ctx);
Emeric Brun9143d372012-12-20 15:44:16 +01003284 if (crt) {
3285 X509_free(crt);
3286 }
3287
3288 smp->type = SMP_T_BOOL;
3289 smp->data.uint = (crt != NULL);
3290 return 1;
3291}
3292
Emeric Brunba841a12014-04-30 17:05:08 +02003293/* integer, returns the certificate version
3294 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
3295 * should be use.
3296 */
Emeric Bruna7359fd2012-10-17 15:03:11 +02003297static int
Emeric Brunba841a12014-04-30 17:05:08 +02003298smp_fetch_ssl_x_version(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003299 const struct arg *args, struct sample *smp, const char *kw)
Emeric Bruna7359fd2012-10-17 15:03:11 +02003300{
Emeric Brunba841a12014-04-30 17:05:08 +02003301 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Bruna7359fd2012-10-17 15:03:11 +02003302 X509 *crt;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003303 struct connection *conn;
3304
3305 if (!l4)
3306 return 0;
Emeric Bruna7359fd2012-10-17 15:03:11 +02003307
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003308 conn = objt_conn(l4->si[0].end);
3309 if (!conn || conn->xprt != &ssl_sock)
Emeric Bruna7359fd2012-10-17 15:03:11 +02003310 return 0;
3311
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003312 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Bruna7359fd2012-10-17 15:03:11 +02003313 smp->flags |= SMP_F_MAY_CHANGE;
3314 return 0;
3315 }
3316
Emeric Brunba841a12014-04-30 17:05:08 +02003317 if (cert_peer)
3318 crt = SSL_get_peer_certificate(conn->xprt_ctx);
3319 else
3320 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Bruna7359fd2012-10-17 15:03:11 +02003321 if (!crt)
3322 return 0;
3323
3324 smp->data.uint = (unsigned int)(1 + X509_get_version(crt));
Emeric Brunba841a12014-04-30 17:05:08 +02003325 /* SSL_get_peer_certificate increase X509 * ref count */
3326 if (cert_peer)
3327 X509_free(crt);
Emeric Bruna7359fd2012-10-17 15:03:11 +02003328 smp->type = SMP_T_UINT;
3329
3330 return 1;
3331}
3332
Emeric Brunba841a12014-04-30 17:05:08 +02003333/* string, returns the certificate's signature algorithm.
3334 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
3335 * should be use.
3336 */
Emeric Brun7f56e742012-10-19 18:15:40 +02003337static int
Emeric Brunba841a12014-04-30 17:05:08 +02003338smp_fetch_ssl_x_sig_alg(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003339 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brun7f56e742012-10-19 18:15:40 +02003340{
Emeric Brunba841a12014-04-30 17:05:08 +02003341 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brun7f56e742012-10-19 18:15:40 +02003342 X509 *crt;
3343 int nid;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003344 struct connection *conn;
Emeric Brun7f56e742012-10-19 18:15:40 +02003345
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003346 if (!l4)
Emeric Brun7f56e742012-10-19 18:15:40 +02003347 return 0;
3348
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003349 conn = objt_conn(l4->si[0].end);
3350 if (!conn || conn->xprt != &ssl_sock)
3351 return 0;
3352
3353 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun7f56e742012-10-19 18:15:40 +02003354 smp->flags |= SMP_F_MAY_CHANGE;
3355 return 0;
3356 }
3357
Emeric Brunba841a12014-04-30 17:05:08 +02003358 if (cert_peer)
3359 crt = SSL_get_peer_certificate(conn->xprt_ctx);
3360 else
3361 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brun7f56e742012-10-19 18:15:40 +02003362 if (!crt)
3363 return 0;
3364
3365 nid = OBJ_obj2nid((ASN1_OBJECT *)(crt->cert_info->signature->algorithm));
3366
3367 smp->data.str.str = (char *)OBJ_nid2sn(nid);
Emeric Brun9bf3ba22013-10-07 14:31:44 +02003368 if (!smp->data.str.str) {
Emeric Brunba841a12014-04-30 17:05:08 +02003369 /* SSL_get_peer_certificate increase X509 * ref count */
3370 if (cert_peer)
3371 X509_free(crt);
Emeric Brun7f56e742012-10-19 18:15:40 +02003372 return 0;
Emeric Brun9bf3ba22013-10-07 14:31:44 +02003373 }
Emeric Brun7f56e742012-10-19 18:15:40 +02003374
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01003375 smp->type = SMP_T_STR;
3376 smp->flags |= SMP_F_CONST;
Emeric Brun7f56e742012-10-19 18:15:40 +02003377 smp->data.str.len = strlen(smp->data.str.str);
Emeric Brunba841a12014-04-30 17:05:08 +02003378 /* SSL_get_peer_certificate increase X509 * ref count */
3379 if (cert_peer)
3380 X509_free(crt);
Emeric Brun7f56e742012-10-19 18:15:40 +02003381
3382 return 1;
3383}
3384
Emeric Brunba841a12014-04-30 17:05:08 +02003385/* string, returns the certificate's key algorithm.
3386 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
3387 * should be use.
3388 */
Emeric Brun521a0112012-10-22 12:22:55 +02003389static int
Emeric Brunba841a12014-04-30 17:05:08 +02003390smp_fetch_ssl_x_key_alg(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003391 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brun521a0112012-10-22 12:22:55 +02003392{
Emeric Brunba841a12014-04-30 17:05:08 +02003393 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brun521a0112012-10-22 12:22:55 +02003394 X509 *crt;
3395 int nid;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003396 struct connection *conn;
Emeric Brun521a0112012-10-22 12:22:55 +02003397
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003398 if (!l4)
Emeric Brun521a0112012-10-22 12:22:55 +02003399 return 0;
3400
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003401 conn = objt_conn(l4->si[0].end);
3402 if (!conn || conn->xprt != &ssl_sock)
3403 return 0;
3404
3405 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun521a0112012-10-22 12:22:55 +02003406 smp->flags |= SMP_F_MAY_CHANGE;
3407 return 0;
3408 }
3409
Emeric Brunba841a12014-04-30 17:05:08 +02003410 if (cert_peer)
3411 crt = SSL_get_peer_certificate(conn->xprt_ctx);
3412 else
3413 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brun521a0112012-10-22 12:22:55 +02003414 if (!crt)
3415 return 0;
3416
3417 nid = OBJ_obj2nid((ASN1_OBJECT *)(crt->cert_info->key->algor->algorithm));
3418
3419 smp->data.str.str = (char *)OBJ_nid2sn(nid);
Emeric Brun9bf3ba22013-10-07 14:31:44 +02003420 if (!smp->data.str.str) {
Emeric Brunba841a12014-04-30 17:05:08 +02003421 /* SSL_get_peer_certificate increase X509 * ref count */
3422 if (cert_peer)
3423 X509_free(crt);
Emeric Brun521a0112012-10-22 12:22:55 +02003424 return 0;
Emeric Brun9bf3ba22013-10-07 14:31:44 +02003425 }
Emeric Brun521a0112012-10-22 12:22:55 +02003426
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01003427 smp->type = SMP_T_STR;
3428 smp->flags |= SMP_F_CONST;
Emeric Brun521a0112012-10-22 12:22:55 +02003429 smp->data.str.len = strlen(smp->data.str.str);
Emeric Brunba841a12014-04-30 17:05:08 +02003430 if (cert_peer)
3431 X509_free(crt);
Emeric Brun521a0112012-10-22 12:22:55 +02003432
3433 return 1;
3434}
3435
Emeric Brun645ae792014-04-30 14:21:06 +02003436/* boolean, returns true if front conn. transport layer is SSL.
3437 * This function is also usable on backend conn if the fetch keyword 5th
3438 * char is 'b'.
3439 */
Willy Tarreau7875d092012-09-10 08:20:03 +02003440static int
Emeric Brun2525b6b2012-10-18 15:59:43 +02003441smp_fetch_ssl_fc(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003442 const struct arg *args, struct sample *smp, const char *kw)
Willy Tarreau7875d092012-09-10 08:20:03 +02003443{
Emeric Brun645ae792014-04-30 14:21:06 +02003444 int back_conn = (kw[4] == 'b') ? 1 : 0;
3445 struct connection *conn = objt_conn(l4->si[back_conn].end);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003446
Willy Tarreau7875d092012-09-10 08:20:03 +02003447 smp->type = SMP_T_BOOL;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003448 smp->data.uint = (conn && conn->xprt == &ssl_sock);
Willy Tarreau7875d092012-09-10 08:20:03 +02003449 return 1;
3450}
3451
Emeric Brun2525b6b2012-10-18 15:59:43 +02003452/* boolean, returns true if client present a SNI */
Willy Tarreau7875d092012-09-10 08:20:03 +02003453static int
Emeric Brun2525b6b2012-10-18 15:59:43 +02003454smp_fetch_ssl_fc_has_sni(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003455 const struct arg *args, struct sample *smp, const char *kw)
Willy Tarreau7875d092012-09-10 08:20:03 +02003456{
3457#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003458 struct connection *conn = objt_conn(l4->si[0].end);
3459
Willy Tarreau7875d092012-09-10 08:20:03 +02003460 smp->type = SMP_T_BOOL;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003461 smp->data.uint = (conn && conn->xprt == &ssl_sock) &&
3462 conn->xprt_ctx &&
3463 SSL_get_servername(conn->xprt_ctx, TLSEXT_NAMETYPE_host_name) != NULL;
Willy Tarreau7875d092012-09-10 08:20:03 +02003464 return 1;
3465#else
3466 return 0;
3467#endif
3468}
3469
Emeric Brun645ae792014-04-30 14:21:06 +02003470/* string, returns the used cipher if front conn. transport layer is SSL.
3471 * This function is also usable on backend conn if the fetch keyword 5th
3472 * char is 'b'.
3473 */
Emeric Brun589fcad2012-10-16 14:13:26 +02003474static int
3475smp_fetch_ssl_fc_cipher(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003476 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brun589fcad2012-10-16 14:13:26 +02003477{
Emeric Brun645ae792014-04-30 14:21:06 +02003478 int back_conn = (kw[4] == 'b') ? 1 : 0;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003479 struct connection *conn;
3480
Emeric Brun589fcad2012-10-16 14:13:26 +02003481 smp->flags = 0;
3482
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003483 if (!l4)
3484 return 0;
3485
Emeric Brun645ae792014-04-30 14:21:06 +02003486 conn = objt_conn(l4->si[back_conn].end);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003487 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
Emeric Brun589fcad2012-10-16 14:13:26 +02003488 return 0;
3489
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003490 smp->data.str.str = (char *)SSL_get_cipher_name(conn->xprt_ctx);
Emeric Brun589fcad2012-10-16 14:13:26 +02003491 if (!smp->data.str.str)
3492 return 0;
3493
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01003494 smp->type = SMP_T_STR;
3495 smp->flags |= SMP_F_CONST;
Emeric Brun589fcad2012-10-16 14:13:26 +02003496 smp->data.str.len = strlen(smp->data.str.str);
3497
3498 return 1;
3499}
3500
Emeric Brun645ae792014-04-30 14:21:06 +02003501/* integer, returns the algoritm's keysize if front conn. transport layer
3502 * is SSL.
3503 * This function is also usable on backend conn if the fetch keyword 5th
3504 * char is 'b'.
3505 */
Emeric Brun589fcad2012-10-16 14:13:26 +02003506static int
3507smp_fetch_ssl_fc_alg_keysize(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003508 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brun589fcad2012-10-16 14:13:26 +02003509{
Emeric Brun645ae792014-04-30 14:21:06 +02003510 int back_conn = (kw[4] == 'b') ? 1 : 0;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003511 struct connection *conn;
3512
Emeric Brun589fcad2012-10-16 14:13:26 +02003513 smp->flags = 0;
3514
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003515 if (!l4)
Emeric Brun589fcad2012-10-16 14:13:26 +02003516 return 0;
3517
Emeric Brun645ae792014-04-30 14:21:06 +02003518 conn = objt_conn(l4->si[back_conn].end);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003519 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
Emeric Brun589fcad2012-10-16 14:13:26 +02003520 return 0;
3521
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003522 if (!SSL_get_cipher_bits(conn->xprt_ctx, (int *)&smp->data.uint))
3523 return 0;
3524
Emeric Brun589fcad2012-10-16 14:13:26 +02003525 smp->type = SMP_T_UINT;
3526
3527 return 1;
3528}
3529
Emeric Brun645ae792014-04-30 14:21:06 +02003530/* integer, returns the used keysize if front conn. transport layer is SSL.
3531 * This function is also usable on backend conn if the fetch keyword 5th
3532 * char is 'b'.
3533 */
Emeric Brun589fcad2012-10-16 14:13:26 +02003534static int
3535smp_fetch_ssl_fc_use_keysize(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003536 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brun589fcad2012-10-16 14:13:26 +02003537{
Emeric Brun645ae792014-04-30 14:21:06 +02003538 int back_conn = (kw[4] == 'b') ? 1 : 0;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003539 struct connection *conn;
3540
Emeric Brun589fcad2012-10-16 14:13:26 +02003541 smp->flags = 0;
3542
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003543 if (!l4)
Emeric Brun589fcad2012-10-16 14:13:26 +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 smp->data.uint = (unsigned int)SSL_get_cipher_bits(conn->xprt_ctx, NULL);
Emeric Brun589fcad2012-10-16 14:13:26 +02003551 if (!smp->data.uint)
3552 return 0;
3553
3554 smp->type = SMP_T_UINT;
3555
3556 return 1;
3557}
3558
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02003559#ifdef OPENSSL_NPN_NEGOTIATED
Willy Tarreau7875d092012-09-10 08:20:03 +02003560static int
Emeric Brun2525b6b2012-10-18 15:59:43 +02003561smp_fetch_ssl_fc_npn(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003562 const struct arg *args, struct sample *smp, const char *kw)
Willy Tarreaua33c6542012-10-15 13:19:06 +02003563{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003564 struct connection *conn;
3565
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01003566 smp->flags = SMP_F_CONST;
3567 smp->type = SMP_T_STR;
Willy Tarreaua33c6542012-10-15 13:19:06 +02003568
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003569 if (!l4)
Willy Tarreaua33c6542012-10-15 13:19:06 +02003570 return 0;
3571
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003572 conn = objt_conn(l4->si[0].end);
3573 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
3574 return 0;
3575
Willy Tarreaua33c6542012-10-15 13:19:06 +02003576 smp->data.str.str = NULL;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003577 SSL_get0_next_proto_negotiated(conn->xprt_ctx,
Willy Tarreaua33c6542012-10-15 13:19:06 +02003578 (const unsigned char **)&smp->data.str.str, (unsigned *)&smp->data.str.len);
3579
3580 if (!smp->data.str.str)
3581 return 0;
3582
3583 return 1;
Willy Tarreaua33c6542012-10-15 13:19:06 +02003584}
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02003585#endif
Willy Tarreaua33c6542012-10-15 13:19:06 +02003586
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01003587#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Willy Tarreauab861d32013-04-02 02:30:41 +02003588static int
3589smp_fetch_ssl_fc_alpn(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003590 const struct arg *args, struct sample *smp, const char *kw)
Willy Tarreauab861d32013-04-02 02:30:41 +02003591{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003592 struct connection *conn;
3593
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01003594 smp->flags = SMP_F_CONST;
3595 smp->type = SMP_T_STR;
Willy Tarreauab861d32013-04-02 02:30:41 +02003596
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003597 if (!l4)
3598 return 0;
3599
3600 conn = objt_conn(l4->si[0].end);
3601 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
Willy Tarreauab861d32013-04-02 02:30:41 +02003602 return 0;
3603
3604 smp->data.str.str = NULL;
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01003605 SSL_get0_alpn_selected(conn->xprt_ctx,
Willy Tarreauab861d32013-04-02 02:30:41 +02003606 (const unsigned char **)&smp->data.str.str, (unsigned *)&smp->data.str.len);
3607
3608 if (!smp->data.str.str)
3609 return 0;
3610
3611 return 1;
3612}
3613#endif
3614
Emeric Brun645ae792014-04-30 14:21:06 +02003615/* string, returns the used protocol if front conn. transport layer is SSL.
3616 * This function is also usable on backend conn if the fetch keyword 5th
3617 * char is 'b'.
3618 */
Willy Tarreaua33c6542012-10-15 13:19:06 +02003619static int
Emeric Brun589fcad2012-10-16 14:13:26 +02003620smp_fetch_ssl_fc_protocol(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003621 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brun589fcad2012-10-16 14:13:26 +02003622{
Emeric Brun645ae792014-04-30 14:21:06 +02003623 int back_conn = (kw[4] == 'b') ? 1 : 0;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003624 struct connection *conn;
3625
Emeric Brun589fcad2012-10-16 14:13:26 +02003626 smp->flags = 0;
3627
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003628 if (!l4)
Emeric Brun589fcad2012-10-16 14:13:26 +02003629 return 0;
3630
Emeric Brun645ae792014-04-30 14:21:06 +02003631 conn = objt_conn(l4->si[back_conn].end);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003632 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
3633 return 0;
3634
3635 smp->data.str.str = (char *)SSL_get_version(conn->xprt_ctx);
Emeric Brun589fcad2012-10-16 14:13:26 +02003636 if (!smp->data.str.str)
3637 return 0;
3638
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01003639 smp->type = SMP_T_STR;
3640 smp->flags = SMP_F_CONST;
Emeric Brun589fcad2012-10-16 14:13:26 +02003641 smp->data.str.len = strlen(smp->data.str.str);
3642
3643 return 1;
3644}
3645
Emeric Brun645ae792014-04-30 14:21:06 +02003646/* binary, returns the SSL session id if front conn. transport layer is SSL.
3647 * This function is also usable on backend conn if the fetch keyword 5th
3648 * char is 'b'.
3649 */
Emeric Brun589fcad2012-10-16 14:13:26 +02003650static int
Emeric Brunfe68f682012-10-16 14:59:28 +02003651smp_fetch_ssl_fc_session_id(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003652 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brunfe68f682012-10-16 14:59:28 +02003653{
3654#if OPENSSL_VERSION_NUMBER > 0x0090800fL
Emeric Brun645ae792014-04-30 14:21:06 +02003655 int back_conn = (kw[4] == 'b') ? 1 : 0;
Emeric Brunfe68f682012-10-16 14:59:28 +02003656 SSL_SESSION *sess;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003657 struct connection *conn;
Emeric Brunfe68f682012-10-16 14:59:28 +02003658
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01003659 smp->flags = SMP_F_CONST;
3660 smp->type = SMP_T_BIN;
Emeric Brunfe68f682012-10-16 14:59:28 +02003661
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003662 if (!l4)
Emeric Brunfe68f682012-10-16 14:59:28 +02003663 return 0;
3664
Emeric Brun645ae792014-04-30 14:21:06 +02003665 conn = objt_conn(l4->si[back_conn].end);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003666 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
3667 return 0;
3668
3669 sess = SSL_get_session(conn->xprt_ctx);
Emeric Brunfe68f682012-10-16 14:59:28 +02003670 if (!sess)
3671 return 0;
3672
3673 smp->data.str.str = (char *)SSL_SESSION_get_id(sess, (unsigned int *)&smp->data.str.len);
3674 if (!smp->data.str.str || !&smp->data.str.len)
3675 return 0;
3676
3677 return 1;
3678#else
3679 return 0;
3680#endif
3681}
3682
3683static int
Emeric Brun2525b6b2012-10-18 15:59:43 +02003684smp_fetch_ssl_fc_sni(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003685 const struct arg *args, struct sample *smp, const char *kw)
Willy Tarreau7875d092012-09-10 08:20:03 +02003686{
3687#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003688 struct connection *conn;
3689
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01003690 smp->flags = SMP_F_CONST;
3691 smp->type = SMP_T_STR;
Willy Tarreau7875d092012-09-10 08:20:03 +02003692
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003693 if (!l4)
Willy Tarreau7875d092012-09-10 08:20:03 +02003694 return 0;
3695
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003696 conn = objt_conn(l4->si[0].end);
3697 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
3698 return 0;
3699
3700 smp->data.str.str = (char *)SSL_get_servername(conn->xprt_ctx, TLSEXT_NAMETYPE_host_name);
Willy Tarreau3e394c92012-09-14 23:56:58 +02003701 if (!smp->data.str.str)
3702 return 0;
3703
Willy Tarreau7875d092012-09-10 08:20:03 +02003704 smp->data.str.len = strlen(smp->data.str.str);
3705 return 1;
3706#else
3707 return 0;
3708#endif
3709}
3710
David Sc1ad52e2014-04-08 18:48:47 -04003711static int
3712smp_fetch_ssl_fc_unique_id(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
3713 const struct arg *args, struct sample *smp, const char *kw)
3714{
3715#if OPENSSL_VERSION_NUMBER > 0x0090800fL
Emeric Brun645ae792014-04-30 14:21:06 +02003716 int back_conn = (kw[4] == 'b') ? 1 : 0;
David Sc1ad52e2014-04-08 18:48:47 -04003717 struct connection *conn;
3718 int finished_len;
David Sc1ad52e2014-04-08 18:48:47 -04003719 struct chunk *finished_trash;
David Sc1ad52e2014-04-08 18:48:47 -04003720
3721 smp->flags = 0;
3722
3723 if (!l4)
3724 return 0;
3725
Emeric Brun645ae792014-04-30 14:21:06 +02003726 conn = objt_conn(l4->si[back_conn].end);
David Sc1ad52e2014-04-08 18:48:47 -04003727 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
3728 return 0;
3729
3730 if (!(conn->flags & CO_FL_CONNECTED)) {
3731 smp->flags |= SMP_F_MAY_CHANGE;
3732 return 0;
3733 }
3734
3735 finished_trash = get_trash_chunk();
3736 if (!SSL_session_reused(conn->xprt_ctx))
3737 finished_len = SSL_get_peer_finished(conn->xprt_ctx, finished_trash->str, finished_trash->size);
3738 else
3739 finished_len = SSL_get_finished(conn->xprt_ctx, finished_trash->str, finished_trash->size);
3740
3741 if (!finished_len)
3742 return 0;
3743
Emeric Brunb73a9b02014-04-30 18:49:19 +02003744 finished_trash->len = finished_len;
3745 smp->data.str = *finished_trash;
3746 smp->type = SMP_T_BIN;
David Sc1ad52e2014-04-08 18:48:47 -04003747
3748 return 1;
3749#else
3750 return 0;
3751#endif
3752}
3753
Emeric Brun2525b6b2012-10-18 15:59:43 +02003754/* integer, returns the first verify error in CA chain of client certificate chain. */
Emeric Brunf282a812012-09-21 15:27:54 +02003755static int
Emeric Brun2525b6b2012-10-18 15:59:43 +02003756smp_fetch_ssl_c_ca_err(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003757 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brunf282a812012-09-21 15:27:54 +02003758{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003759 struct connection *conn;
3760
3761 if (!l4)
Emeric Brunf282a812012-09-21 15:27:54 +02003762 return 0;
3763
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003764 conn = objt_conn(l4->si[0].end);
3765 if (!conn || conn->xprt != &ssl_sock)
3766 return 0;
3767
3768 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunf282a812012-09-21 15:27:54 +02003769 smp->flags = SMP_F_MAY_CHANGE;
3770 return 0;
3771 }
3772
3773 smp->type = SMP_T_UINT;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003774 smp->data.uint = (unsigned int)SSL_SOCK_ST_TO_CA_ERROR(conn->xprt_st);
Emeric Brunf282a812012-09-21 15:27:54 +02003775 smp->flags = 0;
3776
3777 return 1;
3778}
3779
Emeric Brun2525b6b2012-10-18 15:59:43 +02003780/* integer, returns the depth of the first verify error in CA chain of client certificate chain. */
Emeric Brunf282a812012-09-21 15:27:54 +02003781static int
Emeric Brun2525b6b2012-10-18 15:59:43 +02003782smp_fetch_ssl_c_ca_err_depth(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003783 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brunf282a812012-09-21 15:27:54 +02003784{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003785 struct connection *conn;
3786
3787 if (!l4)
3788 return 0;
3789
3790 conn = objt_conn(l4->si[0].end);
3791 if (!conn || conn->xprt != &ssl_sock)
Emeric Brunf282a812012-09-21 15:27:54 +02003792 return 0;
3793
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003794 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunf282a812012-09-21 15:27:54 +02003795 smp->flags = SMP_F_MAY_CHANGE;
3796 return 0;
3797 }
3798
3799 smp->type = SMP_T_UINT;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003800 smp->data.uint = (unsigned int)SSL_SOCK_ST_TO_CAEDEPTH(conn->xprt_st);
Emeric Brunf282a812012-09-21 15:27:54 +02003801 smp->flags = 0;
3802
3803 return 1;
3804}
3805
Emeric Brun2525b6b2012-10-18 15:59:43 +02003806/* integer, returns the first verify error on client certificate */
Emeric Brunf282a812012-09-21 15:27:54 +02003807static int
Emeric Brun2525b6b2012-10-18 15:59:43 +02003808smp_fetch_ssl_c_err(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003809 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brunf282a812012-09-21 15:27:54 +02003810{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003811 struct connection *conn;
3812
3813 if (!l4)
Emeric Brunf282a812012-09-21 15:27:54 +02003814 return 0;
3815
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003816 conn = objt_conn(l4->si[0].end);
3817 if (!conn || conn->xprt != &ssl_sock)
3818 return 0;
3819
3820 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunf282a812012-09-21 15:27:54 +02003821 smp->flags = SMP_F_MAY_CHANGE;
3822 return 0;
3823 }
3824
3825 smp->type = SMP_T_UINT;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003826 smp->data.uint = (unsigned int)SSL_SOCK_ST_TO_CRTERROR(conn->xprt_st);
Emeric Brunf282a812012-09-21 15:27:54 +02003827 smp->flags = 0;
3828
3829 return 1;
3830}
3831
Emeric Brun2525b6b2012-10-18 15:59:43 +02003832/* integer, returns the verify result on client cert */
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02003833static int
Emeric Brun2525b6b2012-10-18 15:59:43 +02003834smp_fetch_ssl_c_verify(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003835 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02003836{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003837 struct connection *conn;
3838
3839 if (!l4)
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02003840 return 0;
3841
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003842 conn = objt_conn(l4->si[0].end);
3843 if (!conn || conn->xprt != &ssl_sock)
3844 return 0;
3845
3846 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02003847 smp->flags = SMP_F_MAY_CHANGE;
3848 return 0;
3849 }
3850
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003851 if (!conn->xprt_ctx)
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02003852 return 0;
3853
3854 smp->type = SMP_T_UINT;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003855 smp->data.uint = (unsigned int)SSL_get_verify_result(conn->xprt_ctx);
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02003856 smp->flags = 0;
3857
3858 return 1;
3859}
3860
Emeric Brunfb510ea2012-10-05 12:00:26 +02003861/* parse the "ca-file" bind keyword */
3862static 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 +02003863{
3864 if (!*args[cur_arg + 1]) {
3865 if (err)
3866 memprintf(err, "'%s' : missing CAfile path", args[cur_arg]);
3867 return ERR_ALERT | ERR_FATAL;
3868 }
3869
Emeric Brunef42d922012-10-11 16:11:36 +02003870 if ((*args[cur_arg + 1] != '/') && global.ca_base)
3871 memprintf(&conf->ca_file, "%s/%s", global.ca_base, args[cur_arg + 1]);
3872 else
3873 memprintf(&conf->ca_file, "%s", args[cur_arg + 1]);
Emeric Brunc8e8d122012-10-02 18:42:10 +02003874
Emeric Brund94b3fe2012-09-20 18:23:56 +02003875 return 0;
3876}
3877
Willy Tarreau79eeafa2012-09-14 07:53:05 +02003878/* parse the "ciphers" bind keyword */
Willy Tarreau4348fad2012-09-20 16:48:07 +02003879static 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 +02003880{
3881 if (!*args[cur_arg + 1]) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02003882 memprintf(err, "'%s' : missing cipher suite", args[cur_arg]);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02003883 return ERR_ALERT | ERR_FATAL;
3884 }
3885
Emeric Brun76d88952012-10-05 15:47:31 +02003886 free(conf->ciphers);
Willy Tarreau4348fad2012-09-20 16:48:07 +02003887 conf->ciphers = strdup(args[cur_arg + 1]);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02003888 return 0;
3889}
3890
3891/* parse the "crt" bind keyword */
Willy Tarreau4348fad2012-09-20 16:48:07 +02003892static 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 +02003893{
Willy Tarreau38011032013-08-13 16:59:39 +02003894 char path[MAXPATHLEN];
Willy Tarreaub75d6922014-04-14 18:05:41 +02003895
Willy Tarreau79eeafa2012-09-14 07:53:05 +02003896 if (!*args[cur_arg + 1]) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02003897 memprintf(err, "'%s' : missing certificate location", args[cur_arg]);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02003898 return ERR_ALERT | ERR_FATAL;
3899 }
3900
Emeric Brunc8e8d122012-10-02 18:42:10 +02003901 if ((*args[cur_arg + 1] != '/' ) && global.crt_base) {
Willy Tarreau38011032013-08-13 16:59:39 +02003902 if ((strlen(global.crt_base) + 1 + strlen(args[cur_arg + 1]) + 1) > MAXPATHLEN) {
Emeric Brunc8e8d122012-10-02 18:42:10 +02003903 memprintf(err, "'%s' : path too long", args[cur_arg]);
3904 return ERR_ALERT | ERR_FATAL;
3905 }
Willy Tarreaub75d6922014-04-14 18:05:41 +02003906 snprintf(path, sizeof(path), "%s/%s", global.crt_base, args[cur_arg + 1]);
Emeric Brunc8e8d122012-10-02 18:42:10 +02003907 if (ssl_sock_load_cert(path, conf, px, err) > 0)
3908 return ERR_ALERT | ERR_FATAL;
3909
3910 return 0;
3911 }
3912
Willy Tarreau4348fad2012-09-20 16:48:07 +02003913 if (ssl_sock_load_cert(args[cur_arg + 1], conf, px, err) > 0)
Willy Tarreau79eeafa2012-09-14 07:53:05 +02003914 return ERR_ALERT | ERR_FATAL;
Emeric Brund94b3fe2012-09-20 18:23:56 +02003915
3916 return 0;
3917}
3918
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01003919/* parse the "crt-list" bind keyword */
3920static int bind_parse_crt_list(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
3921{
3922 if (!*args[cur_arg + 1]) {
3923 memprintf(err, "'%s' : missing certificate location", args[cur_arg]);
3924 return ERR_ALERT | ERR_FATAL;
3925 }
3926
Willy Tarreauad1731d2013-04-02 17:35:58 +02003927 if (ssl_sock_load_cert_list_file(args[cur_arg + 1], conf, px, err) > 0) {
3928 memprintf(err, "'%s' : %s", args[cur_arg], *err);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01003929 return ERR_ALERT | ERR_FATAL;
Willy Tarreauad1731d2013-04-02 17:35:58 +02003930 }
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01003931
3932 return 0;
3933}
3934
Emeric Brunfb510ea2012-10-05 12:00:26 +02003935/* parse the "crl-file" bind keyword */
3936static 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 +02003937{
Emeric Brun051cdab2012-10-02 19:25:50 +02003938#ifndef X509_V_FLAG_CRL_CHECK
3939 if (err)
3940 memprintf(err, "'%s' : library does not support CRL verify", args[cur_arg]);
3941 return ERR_ALERT | ERR_FATAL;
3942#else
Emeric Brund94b3fe2012-09-20 18:23:56 +02003943 if (!*args[cur_arg + 1]) {
3944 if (err)
3945 memprintf(err, "'%s' : missing CRLfile path", args[cur_arg]);
3946 return ERR_ALERT | ERR_FATAL;
3947 }
Emeric Brun2b58d042012-09-20 17:10:03 +02003948
Emeric Brunef42d922012-10-11 16:11:36 +02003949 if ((*args[cur_arg + 1] != '/') && global.ca_base)
3950 memprintf(&conf->crl_file, "%s/%s", global.ca_base, args[cur_arg + 1]);
3951 else
3952 memprintf(&conf->crl_file, "%s", args[cur_arg + 1]);
Emeric Brunc8e8d122012-10-02 18:42:10 +02003953
Emeric Brun2b58d042012-09-20 17:10:03 +02003954 return 0;
Emeric Brun051cdab2012-10-02 19:25:50 +02003955#endif
Emeric Brun2b58d042012-09-20 17:10:03 +02003956}
3957
3958/* parse the "ecdhe" bind keyword keywords */
3959static int bind_parse_ecdhe(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
3960{
3961#if OPENSSL_VERSION_NUMBER < 0x0090800fL
3962 if (err)
3963 memprintf(err, "'%s' : library does not support elliptic curve Diffie-Hellman (too old)", args[cur_arg]);
3964 return ERR_ALERT | ERR_FATAL;
3965#elif defined(OPENSSL_NO_ECDH)
3966 if (err)
3967 memprintf(err, "'%s' : library does not support elliptic curve Diffie-Hellman (disabled via OPENSSL_NO_ECDH)", args[cur_arg]);
3968 return ERR_ALERT | ERR_FATAL;
3969#else
3970 if (!*args[cur_arg + 1]) {
3971 if (err)
3972 memprintf(err, "'%s' : missing named curve", args[cur_arg]);
3973 return ERR_ALERT | ERR_FATAL;
3974 }
3975
3976 conf->ecdhe = strdup(args[cur_arg + 1]);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02003977
3978 return 0;
Emeric Brun2b58d042012-09-20 17:10:03 +02003979#endif
Willy Tarreau79eeafa2012-09-14 07:53:05 +02003980}
3981
Emeric Brun81c00f02012-09-21 14:31:21 +02003982/* parse the "crt_ignerr" and "ca_ignerr" bind keywords */
3983static int bind_parse_ignore_err(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
3984{
3985 int code;
3986 char *p = args[cur_arg + 1];
3987 unsigned long long *ignerr = &conf->crt_ignerr;
3988
3989 if (!*p) {
3990 if (err)
3991 memprintf(err, "'%s' : missing error IDs list", args[cur_arg]);
3992 return ERR_ALERT | ERR_FATAL;
3993 }
3994
3995 if (strcmp(args[cur_arg], "ca-ignore-err") == 0)
3996 ignerr = &conf->ca_ignerr;
3997
3998 if (strcmp(p, "all") == 0) {
3999 *ignerr = ~0ULL;
4000 return 0;
4001 }
4002
4003 while (p) {
4004 code = atoi(p);
4005 if ((code <= 0) || (code > 63)) {
4006 if (err)
4007 memprintf(err, "'%s' : ID '%d' out of range (1..63) in error IDs list '%s'",
4008 args[cur_arg], code, args[cur_arg + 1]);
4009 return ERR_ALERT | ERR_FATAL;
4010 }
4011 *ignerr |= 1ULL << code;
4012 p = strchr(p, ',');
4013 if (p)
4014 p++;
4015 }
4016
Emeric Brun2cb7ae52012-10-05 14:14:21 +02004017 return 0;
4018}
4019
4020/* parse the "force-sslv3" bind keyword */
4021static int bind_parse_force_sslv3(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
4022{
4023 conf->ssl_options |= BC_SSL_O_USE_SSLV3;
4024 return 0;
4025}
4026
4027/* parse the "force-tlsv10" bind keyword */
4028static int bind_parse_force_tlsv10(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
4029{
4030 conf->ssl_options |= BC_SSL_O_USE_TLSV10;
Emeric Brun2d0c4822012-10-02 13:45:20 +02004031 return 0;
4032}
4033
Emeric Brun2cb7ae52012-10-05 14:14:21 +02004034/* parse the "force-tlsv11" bind keyword */
4035static int bind_parse_force_tlsv11(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
4036{
4037#if SSL_OP_NO_TLSv1_1
4038 conf->ssl_options |= BC_SSL_O_USE_TLSV11;
4039 return 0;
4040#else
4041 if (err)
4042 memprintf(err, "'%s' : library does not support protocol TLSv1.1", args[cur_arg]);
4043 return ERR_ALERT | ERR_FATAL;
4044#endif
4045}
4046
4047/* parse the "force-tlsv12" bind keyword */
4048static int bind_parse_force_tlsv12(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
4049{
4050#if SSL_OP_NO_TLSv1_2
4051 conf->ssl_options |= BC_SSL_O_USE_TLSV12;
4052 return 0;
4053#else
4054 if (err)
4055 memprintf(err, "'%s' : library does not support protocol TLSv1.2", args[cur_arg]);
4056 return ERR_ALERT | ERR_FATAL;
4057#endif
4058}
4059
4060
Emeric Brun2d0c4822012-10-02 13:45:20 +02004061/* parse the "no-tls-tickets" bind keyword */
4062static int bind_parse_no_tls_tickets(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
4063{
Emeric Brun89675492012-10-05 13:48:26 +02004064 conf->ssl_options |= BC_SSL_O_NO_TLS_TICKETS;
Emeric Brun81c00f02012-09-21 14:31:21 +02004065 return 0;
4066}
4067
Emeric Brun2d0c4822012-10-02 13:45:20 +02004068
Emeric Brun9b3009b2012-10-05 11:55:06 +02004069/* parse the "no-sslv3" bind keyword */
4070static 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 +02004071{
Emeric Brun89675492012-10-05 13:48:26 +02004072 conf->ssl_options |= BC_SSL_O_NO_SSLV3;
Willy Tarreau79eeafa2012-09-14 07:53:05 +02004073 return 0;
4074}
4075
Emeric Brun9b3009b2012-10-05 11:55:06 +02004076/* parse the "no-tlsv10" bind keyword */
4077static 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 +02004078{
Emeric Brun89675492012-10-05 13:48:26 +02004079 conf->ssl_options |= BC_SSL_O_NO_TLSV10;
Emeric Brunc0ff4922012-09-28 19:37:02 +02004080 return 0;
4081}
4082
Emeric Brun9b3009b2012-10-05 11:55:06 +02004083/* parse the "no-tlsv11" bind keyword */
4084static 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 +02004085{
Emeric Brun89675492012-10-05 13:48:26 +02004086 conf->ssl_options |= BC_SSL_O_NO_TLSV11;
Emeric Brunc0ff4922012-09-28 19:37:02 +02004087 return 0;
4088}
4089
Emeric Brun9b3009b2012-10-05 11:55:06 +02004090/* parse the "no-tlsv12" bind keyword */
4091static 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 +02004092{
Emeric Brun89675492012-10-05 13:48:26 +02004093 conf->ssl_options |= BC_SSL_O_NO_TLSV12;
Willy Tarreau79eeafa2012-09-14 07:53:05 +02004094 return 0;
4095}
4096
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02004097/* parse the "npn" bind keyword */
4098static int bind_parse_npn(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
4099{
4100#ifdef OPENSSL_NPN_NEGOTIATED
4101 char *p1, *p2;
4102
4103 if (!*args[cur_arg + 1]) {
4104 memprintf(err, "'%s' : missing the comma-delimited NPN protocol suite", args[cur_arg]);
4105 return ERR_ALERT | ERR_FATAL;
4106 }
4107
4108 free(conf->npn_str);
4109
4110 /* the NPN string is built as a suite of (<len> <name>)* */
4111 conf->npn_len = strlen(args[cur_arg + 1]) + 1;
4112 conf->npn_str = calloc(1, conf->npn_len);
4113 memcpy(conf->npn_str + 1, args[cur_arg + 1], conf->npn_len);
4114
4115 /* replace commas with the name length */
4116 p1 = conf->npn_str;
4117 p2 = p1 + 1;
4118 while (1) {
4119 p2 = memchr(p1 + 1, ',', conf->npn_str + conf->npn_len - (p1 + 1));
4120 if (!p2)
4121 p2 = p1 + 1 + strlen(p1 + 1);
4122
4123 if (p2 - (p1 + 1) > 255) {
4124 *p2 = '\0';
4125 memprintf(err, "'%s' : NPN protocol name too long : '%s'", args[cur_arg], p1 + 1);
4126 return ERR_ALERT | ERR_FATAL;
4127 }
4128
4129 *p1 = p2 - (p1 + 1);
4130 p1 = p2;
4131
4132 if (!*p2)
4133 break;
4134
4135 *(p2++) = '\0';
4136 }
4137 return 0;
4138#else
4139 if (err)
4140 memprintf(err, "'%s' : library does not support TLS NPN extension", args[cur_arg]);
4141 return ERR_ALERT | ERR_FATAL;
4142#endif
4143}
4144
Willy Tarreauab861d32013-04-02 02:30:41 +02004145/* parse the "alpn" bind keyword */
4146static int bind_parse_alpn(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
4147{
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01004148#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Willy Tarreauab861d32013-04-02 02:30:41 +02004149 char *p1, *p2;
4150
4151 if (!*args[cur_arg + 1]) {
4152 memprintf(err, "'%s' : missing the comma-delimited ALPN protocol suite", args[cur_arg]);
4153 return ERR_ALERT | ERR_FATAL;
4154 }
4155
4156 free(conf->alpn_str);
4157
4158 /* the ALPN string is built as a suite of (<len> <name>)* */
4159 conf->alpn_len = strlen(args[cur_arg + 1]) + 1;
4160 conf->alpn_str = calloc(1, conf->alpn_len);
4161 memcpy(conf->alpn_str + 1, args[cur_arg + 1], conf->alpn_len);
4162
4163 /* replace commas with the name length */
4164 p1 = conf->alpn_str;
4165 p2 = p1 + 1;
4166 while (1) {
4167 p2 = memchr(p1 + 1, ',', conf->alpn_str + conf->alpn_len - (p1 + 1));
4168 if (!p2)
4169 p2 = p1 + 1 + strlen(p1 + 1);
4170
4171 if (p2 - (p1 + 1) > 255) {
4172 *p2 = '\0';
4173 memprintf(err, "'%s' : ALPN protocol name too long : '%s'", args[cur_arg], p1 + 1);
4174 return ERR_ALERT | ERR_FATAL;
4175 }
4176
4177 *p1 = p2 - (p1 + 1);
4178 p1 = p2;
4179
4180 if (!*p2)
4181 break;
4182
4183 *(p2++) = '\0';
4184 }
4185 return 0;
4186#else
4187 if (err)
4188 memprintf(err, "'%s' : library does not support TLS ALPN extension", args[cur_arg]);
4189 return ERR_ALERT | ERR_FATAL;
4190#endif
4191}
4192
Willy Tarreau79eeafa2012-09-14 07:53:05 +02004193/* parse the "ssl" bind keyword */
Willy Tarreau4348fad2012-09-20 16:48:07 +02004194static 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 +02004195{
Willy Tarreau81796be2012-09-22 19:11:47 +02004196 struct listener *l;
4197
Willy Tarreau4348fad2012-09-20 16:48:07 +02004198 conf->is_ssl = 1;
Emeric Brun76d88952012-10-05 15:47:31 +02004199
4200 if (global.listen_default_ciphers && !conf->ciphers)
4201 conf->ciphers = strdup(global.listen_default_ciphers);
Emeric Brun42a3e202014-10-30 15:56:50 +01004202 conf->ssl_options |= global.listen_default_ssloptions;
Emeric Brun76d88952012-10-05 15:47:31 +02004203
Willy Tarreau81796be2012-09-22 19:11:47 +02004204 list_for_each_entry(l, &conf->listeners, by_bind)
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02004205 l->xprt = &ssl_sock;
Willy Tarreau81796be2012-09-22 19:11:47 +02004206
Willy Tarreau79eeafa2012-09-14 07:53:05 +02004207 return 0;
4208}
4209
Emmanuel Hocdet65623372013-01-24 17:17:15 +01004210/* parse the "strict-sni" bind keyword */
4211static int bind_parse_strict_sni(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
4212{
4213 conf->strict_sni = 1;
4214 return 0;
4215}
4216
Emeric Brund94b3fe2012-09-20 18:23:56 +02004217/* parse the "verify" bind keyword */
4218static int bind_parse_verify(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
4219{
4220 if (!*args[cur_arg + 1]) {
4221 if (err)
4222 memprintf(err, "'%s' : missing verify method", args[cur_arg]);
4223 return ERR_ALERT | ERR_FATAL;
4224 }
4225
4226 if (strcmp(args[cur_arg + 1], "none") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01004227 conf->verify = SSL_SOCK_VERIFY_NONE;
Emeric Brund94b3fe2012-09-20 18:23:56 +02004228 else if (strcmp(args[cur_arg + 1], "optional") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01004229 conf->verify = SSL_SOCK_VERIFY_OPTIONAL;
Emeric Brund94b3fe2012-09-20 18:23:56 +02004230 else if (strcmp(args[cur_arg + 1], "required") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01004231 conf->verify = SSL_SOCK_VERIFY_REQUIRED;
Emeric Brund94b3fe2012-09-20 18:23:56 +02004232 else {
4233 if (err)
4234 memprintf(err, "'%s' : unknown verify method '%s', only 'none', 'optional', and 'required' are supported\n",
4235 args[cur_arg], args[cur_arg + 1]);
4236 return ERR_ALERT | ERR_FATAL;
4237 }
4238
4239 return 0;
4240}
4241
Willy Tarreau92faadf2012-10-10 23:04:25 +02004242/************** "server" keywords ****************/
4243
Emeric Brunef42d922012-10-11 16:11:36 +02004244/* parse the "ca-file" server keyword */
4245static int srv_parse_ca_file(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4246{
4247 if (!*args[*cur_arg + 1]) {
4248 if (err)
4249 memprintf(err, "'%s' : missing CAfile path", args[*cur_arg]);
4250 return ERR_ALERT | ERR_FATAL;
4251 }
4252
4253 if ((*args[*cur_arg + 1] != '/') && global.ca_base)
4254 memprintf(&newsrv->ssl_ctx.ca_file, "%s/%s", global.ca_base, args[*cur_arg + 1]);
4255 else
4256 memprintf(&newsrv->ssl_ctx.ca_file, "%s", args[*cur_arg + 1]);
4257
4258 return 0;
4259}
4260
Willy Tarreau92faadf2012-10-10 23:04:25 +02004261/* parse the "check-ssl" server keyword */
4262static int srv_parse_check_ssl(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4263{
4264 newsrv->check.use_ssl = 1;
4265 if (global.connect_default_ciphers && !newsrv->ssl_ctx.ciphers)
4266 newsrv->ssl_ctx.ciphers = strdup(global.connect_default_ciphers);
Emeric Brun42a3e202014-10-30 15:56:50 +01004267 newsrv->ssl_ctx.options |= global.connect_default_ssloptions;
Willy Tarreau92faadf2012-10-10 23:04:25 +02004268 return 0;
4269}
4270
4271/* parse the "ciphers" server keyword */
4272static int srv_parse_ciphers(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4273{
4274 if (!*args[*cur_arg + 1]) {
4275 memprintf(err, "'%s' : missing cipher suite", args[*cur_arg]);
4276 return ERR_ALERT | ERR_FATAL;
4277 }
4278
4279 free(newsrv->ssl_ctx.ciphers);
4280 newsrv->ssl_ctx.ciphers = strdup(args[*cur_arg + 1]);
4281 return 0;
4282}
4283
Emeric Brunef42d922012-10-11 16:11:36 +02004284/* parse the "crl-file" server keyword */
4285static int srv_parse_crl_file(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4286{
4287#ifndef X509_V_FLAG_CRL_CHECK
4288 if (err)
4289 memprintf(err, "'%s' : library does not support CRL verify", args[*cur_arg]);
4290 return ERR_ALERT | ERR_FATAL;
4291#else
4292 if (!*args[*cur_arg + 1]) {
4293 if (err)
4294 memprintf(err, "'%s' : missing CRLfile path", args[*cur_arg]);
4295 return ERR_ALERT | ERR_FATAL;
4296 }
4297
4298 if ((*args[*cur_arg + 1] != '/') && global.ca_base)
4299 memprintf(&newsrv->ssl_ctx.crl_file, "%s/%s", global.ca_base, args[*cur_arg + 1]);
4300 else
4301 memprintf(&newsrv->ssl_ctx.crl_file, "%s", args[*cur_arg + 1]);
4302
4303 return 0;
4304#endif
4305}
4306
Emeric Bruna7aa3092012-10-26 12:58:00 +02004307/* parse the "crt" server keyword */
4308static int srv_parse_crt(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4309{
4310 if (!*args[*cur_arg + 1]) {
4311 if (err)
4312 memprintf(err, "'%s' : missing certificate file path", args[*cur_arg]);
4313 return ERR_ALERT | ERR_FATAL;
4314 }
4315
4316 if ((*args[*cur_arg + 1] != '/') && global.crt_base)
4317 memprintf(&newsrv->ssl_ctx.client_crt, "%s/%s", global.ca_base, args[*cur_arg + 1]);
4318 else
4319 memprintf(&newsrv->ssl_ctx.client_crt, "%s", args[*cur_arg + 1]);
4320
4321 return 0;
4322}
Emeric Brunef42d922012-10-11 16:11:36 +02004323
Willy Tarreau92faadf2012-10-10 23:04:25 +02004324/* parse the "force-sslv3" server keyword */
4325static int srv_parse_force_sslv3(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4326{
4327 newsrv->ssl_ctx.options |= SRV_SSL_O_USE_SSLV3;
4328 return 0;
4329}
4330
4331/* parse the "force-tlsv10" server keyword */
4332static int srv_parse_force_tlsv10(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4333{
4334 newsrv->ssl_ctx.options |= SRV_SSL_O_USE_TLSV10;
4335 return 0;
4336}
4337
4338/* parse the "force-tlsv11" server keyword */
4339static int srv_parse_force_tlsv11(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4340{
4341#if SSL_OP_NO_TLSv1_1
4342 newsrv->ssl_ctx.options |= SRV_SSL_O_USE_TLSV11;
4343 return 0;
4344#else
4345 if (err)
4346 memprintf(err, "'%s' : library does not support protocol TLSv1.1", args[*cur_arg]);
4347 return ERR_ALERT | ERR_FATAL;
4348#endif
4349}
4350
4351/* parse the "force-tlsv12" server keyword */
4352static int srv_parse_force_tlsv12(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4353{
4354#if SSL_OP_NO_TLSv1_2
4355 newsrv->ssl_ctx.options |= SRV_SSL_O_USE_TLSV12;
4356 return 0;
4357#else
4358 if (err)
4359 memprintf(err, "'%s' : library does not support protocol TLSv1.2", args[*cur_arg]);
4360 return ERR_ALERT | ERR_FATAL;
4361#endif
4362}
4363
4364/* parse the "no-sslv3" server keyword */
4365static int srv_parse_no_sslv3(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4366{
4367 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_SSLV3;
4368 return 0;
4369}
4370
4371/* parse the "no-tlsv10" server keyword */
4372static int srv_parse_no_tlsv10(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4373{
4374 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_TLSV10;
4375 return 0;
4376}
4377
4378/* parse the "no-tlsv11" server keyword */
4379static int srv_parse_no_tlsv11(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4380{
4381 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_TLSV11;
4382 return 0;
4383}
4384
4385/* parse the "no-tlsv12" server keyword */
4386static int srv_parse_no_tlsv12(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4387{
4388 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_TLSV12;
4389 return 0;
4390}
4391
Emeric Brunf9c5c472012-10-11 15:28:34 +02004392/* parse the "no-tls-tickets" server keyword */
4393static int srv_parse_no_tls_tickets(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4394{
4395 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_TLS_TICKETS;
4396 return 0;
4397}
David Safb76832014-05-08 23:42:08 -04004398/* parse the "send-proxy-v2-ssl" server keyword */
4399static int srv_parse_send_proxy_ssl(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4400{
4401 newsrv->pp_opts |= SRV_PP_V2;
4402 newsrv->pp_opts |= SRV_PP_V2_SSL;
4403 return 0;
4404}
4405
4406/* parse the "send-proxy-v2-ssl-cn" server keyword */
4407static int srv_parse_send_proxy_cn(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4408{
4409 newsrv->pp_opts |= SRV_PP_V2;
4410 newsrv->pp_opts |= SRV_PP_V2_SSL;
4411 newsrv->pp_opts |= SRV_PP_V2_SSL_CN;
4412 return 0;
4413}
Emeric Brunf9c5c472012-10-11 15:28:34 +02004414
Willy Tarreau92faadf2012-10-10 23:04:25 +02004415/* parse the "ssl" server keyword */
4416static int srv_parse_ssl(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4417{
4418 newsrv->use_ssl = 1;
4419 if (global.connect_default_ciphers && !newsrv->ssl_ctx.ciphers)
4420 newsrv->ssl_ctx.ciphers = strdup(global.connect_default_ciphers);
4421 return 0;
4422}
4423
Emeric Brunef42d922012-10-11 16:11:36 +02004424/* parse the "verify" server keyword */
4425static int srv_parse_verify(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4426{
4427 if (!*args[*cur_arg + 1]) {
4428 if (err)
4429 memprintf(err, "'%s' : missing verify method", args[*cur_arg]);
4430 return ERR_ALERT | ERR_FATAL;
4431 }
4432
4433 if (strcmp(args[*cur_arg + 1], "none") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01004434 newsrv->ssl_ctx.verify = SSL_SOCK_VERIFY_NONE;
Emeric Brunef42d922012-10-11 16:11:36 +02004435 else if (strcmp(args[*cur_arg + 1], "required") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01004436 newsrv->ssl_ctx.verify = SSL_SOCK_VERIFY_REQUIRED;
Emeric Brunef42d922012-10-11 16:11:36 +02004437 else {
4438 if (err)
4439 memprintf(err, "'%s' : unknown verify method '%s', only 'none' and 'required' are supported\n",
4440 args[*cur_arg], args[*cur_arg + 1]);
4441 return ERR_ALERT | ERR_FATAL;
4442 }
4443
Evan Broderbe554312013-06-27 00:05:25 -07004444 return 0;
4445}
4446
4447/* parse the "verifyhost" server keyword */
4448static int srv_parse_verifyhost(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4449{
4450 if (!*args[*cur_arg + 1]) {
4451 if (err)
4452 memprintf(err, "'%s' : missing hostname to verify against", args[*cur_arg]);
4453 return ERR_ALERT | ERR_FATAL;
4454 }
4455
4456 newsrv->ssl_ctx.verify_host = strdup(args[*cur_arg + 1]);
4457
Emeric Brunef42d922012-10-11 16:11:36 +02004458 return 0;
4459}
4460
Emeric Brun42a3e202014-10-30 15:56:50 +01004461/* parse the "ssl-default-bind-options" keyword in global section */
4462static int ssl_parse_default_bind_options(char **args, int section_type, struct proxy *curpx,
4463 struct proxy *defpx, const char *file, int line,
4464 char **err) {
4465 int i = 1;
4466
4467 if (*(args[i]) == 0) {
4468 memprintf(err, "global statement '%s' expects an option as an argument.", args[0]);
4469 return -1;
4470 }
4471 while (*(args[i])) {
4472 if (!strcmp(args[i], "no-sslv3"))
4473 global.listen_default_ssloptions |= BC_SSL_O_NO_SSLV3;
4474 else if (!strcmp(args[i], "no-tlsv10"))
4475 global.listen_default_ssloptions |= BC_SSL_O_NO_TLSV10;
4476 else if (!strcmp(args[i], "no-tlsv11"))
4477 global.listen_default_ssloptions |= BC_SSL_O_NO_TLSV11;
4478 else if (!strcmp(args[i], "no-tlsv12"))
4479 global.listen_default_ssloptions |= BC_SSL_O_NO_TLSV12;
4480 else if (!strcmp(args[i], "force-sslv3"))
4481 global.listen_default_ssloptions |= BC_SSL_O_USE_SSLV3;
4482 else if (!strcmp(args[i], "force-tlsv10"))
4483 global.listen_default_ssloptions |= BC_SSL_O_USE_TLSV10;
4484 else if (!strcmp(args[i], "force-tlsv11")) {
4485#if SSL_OP_NO_TLSv1_1
4486 global.listen_default_ssloptions |= BC_SSL_O_USE_TLSV11;
4487#else
4488 memprintf(err, "'%s' '%s': library does not support protocol TLSv1.1", args[0], args[i]);
4489 return -1;
4490#endif
4491 }
4492 else if (!strcmp(args[i], "force-tlsv12")) {
4493#if SSL_OP_NO_TLSv1_2
4494 global.listen_default_ssloptions |= BC_SSL_O_USE_TLSV12;
4495#else
4496 memprintf(err, "'%s' '%s': library does not support protocol TLSv1.2", args[0], args[i]);
4497 return -1;
4498#endif
4499 }
4500 else if (!strcmp(args[i], "no-tls-tickets"))
4501 global.listen_default_ssloptions |= BC_SSL_O_NO_TLS_TICKETS;
4502 else {
4503 memprintf(err, "unknown option '%s' on global statement '%s'.", args[i], args[0]);
4504 return -1;
4505 }
4506 i++;
4507 }
4508 return 0;
4509}
4510
4511/* parse the "ssl-default-server-options" keyword in global section */
4512static int ssl_parse_default_server_options(char **args, int section_type, struct proxy *curpx,
4513 struct proxy *defpx, const char *file, int line,
4514 char **err) {
4515 int i = 1;
4516
4517 if (*(args[i]) == 0) {
4518 memprintf(err, "global statement '%s' expects an option as an argument.", args[0]);
4519 return -1;
4520 }
4521 while (*(args[i])) {
4522 if (!strcmp(args[i], "no-sslv3"))
4523 global.connect_default_ssloptions |= SRV_SSL_O_NO_SSLV3;
4524 else if (!strcmp(args[i], "no-tlsv10"))
4525 global.connect_default_ssloptions |= SRV_SSL_O_NO_TLSV10;
4526 else if (!strcmp(args[i], "no-tlsv11"))
4527 global.connect_default_ssloptions |= SRV_SSL_O_NO_TLSV11;
4528 else if (!strcmp(args[i], "no-tlsv12"))
4529 global.connect_default_ssloptions |= SRV_SSL_O_NO_TLSV12;
4530 else if (!strcmp(args[i], "force-sslv3"))
4531 global.connect_default_ssloptions |= SRV_SSL_O_USE_SSLV3;
4532 else if (!strcmp(args[i], "force-tlsv10"))
4533 global.connect_default_ssloptions |= SRV_SSL_O_USE_TLSV10;
4534 else if (!strcmp(args[i], "force-tlsv11")) {
4535#if SSL_OP_NO_TLSv1_1
4536 global.connect_default_ssloptions |= SRV_SSL_O_USE_TLSV11;
4537#else
4538 memprintf(err, "'%s' '%s': library does not support protocol TLSv1.1", args[0], args[i]);
4539 return -1;
4540#endif
4541 }
4542 else if (!strcmp(args[i], "force-tlsv12")) {
4543#if SSL_OP_NO_TLSv1_2
4544 global.connect_default_ssloptions |= SRV_SSL_O_USE_TLSV12;
4545#else
4546 memprintf(err, "'%s' '%s': library does not support protocol TLSv1.2", args[0], args[i]);
4547 return -1;
4548#endif
4549 }
4550 else if (!strcmp(args[i], "no-tls-tickets"))
4551 global.connect_default_ssloptions |= SRV_SSL_O_NO_TLS_TICKETS;
4552 else {
4553 memprintf(err, "unknown option '%s' on global statement '%s'.", args[i], args[0]);
4554 return -1;
4555 }
4556 i++;
4557 }
4558 return 0;
4559}
4560
Willy Tarreau7875d092012-09-10 08:20:03 +02004561/* Note: must not be declared <const> as its list will be overwritten.
4562 * Please take care of keeping this list alphabetically sorted.
4563 */
Willy Tarreaudc13c112013-06-21 23:16:39 +02004564static struct sample_fetch_kw_list sample_fetch_keywords = {ILH, {
Emeric Brun645ae792014-04-30 14:21:06 +02004565 { "ssl_bc", smp_fetch_ssl_fc, 0, NULL, SMP_T_BOOL, SMP_USE_L5SRV },
4566 { "ssl_bc_alg_keysize", smp_fetch_ssl_fc_alg_keysize, 0, NULL, SMP_T_UINT, SMP_USE_L5SRV },
4567 { "ssl_bc_cipher", smp_fetch_ssl_fc_cipher, 0, NULL, SMP_T_STR, SMP_USE_L5SRV },
4568 { "ssl_bc_protocol", smp_fetch_ssl_fc_protocol, 0, NULL, SMP_T_STR, SMP_USE_L5SRV },
Emeric Brunb73a9b02014-04-30 18:49:19 +02004569 { "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 +02004570 { "ssl_bc_use_keysize", smp_fetch_ssl_fc_use_keysize, 0, NULL, SMP_T_UINT, SMP_USE_L5SRV },
4571 { "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 +01004572 { "ssl_c_ca_err", smp_fetch_ssl_c_ca_err, 0, NULL, SMP_T_UINT, SMP_USE_L5CLI },
4573 { "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 +01004574 { "ssl_c_der", smp_fetch_ssl_x_der, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Willy Tarreau80aca902013-01-07 15:42:20 +01004575 { "ssl_c_err", smp_fetch_ssl_c_err, 0, NULL, SMP_T_UINT, SMP_USE_L5CLI },
Emeric Brunba841a12014-04-30 17:05:08 +02004576 { "ssl_c_i_dn", smp_fetch_ssl_x_i_dn, ARG2(0,STR,SINT), NULL, SMP_T_STR, SMP_USE_L5CLI },
4577 { "ssl_c_key_alg", smp_fetch_ssl_x_key_alg, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
4578 { "ssl_c_notafter", smp_fetch_ssl_x_notafter, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
4579 { "ssl_c_notbefore", smp_fetch_ssl_x_notbefore, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
4580 { "ssl_c_sig_alg", smp_fetch_ssl_x_sig_alg, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
4581 { "ssl_c_s_dn", smp_fetch_ssl_x_s_dn, ARG2(0,STR,SINT), NULL, SMP_T_STR, SMP_USE_L5CLI },
4582 { "ssl_c_serial", smp_fetch_ssl_x_serial, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
4583 { "ssl_c_sha1", smp_fetch_ssl_x_sha1, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Willy Tarreau80aca902013-01-07 15:42:20 +01004584 { "ssl_c_used", smp_fetch_ssl_c_used, 0, NULL, SMP_T_BOOL, SMP_USE_L5CLI },
4585 { "ssl_c_verify", smp_fetch_ssl_c_verify, 0, NULL, SMP_T_UINT, SMP_USE_L5CLI },
Emeric Brunba841a12014-04-30 17:05:08 +02004586 { "ssl_c_version", smp_fetch_ssl_x_version, 0, NULL, SMP_T_UINT, SMP_USE_L5CLI },
Emeric Brunb3cc4252014-10-29 19:03:26 +01004587 { "ssl_f_der", smp_fetch_ssl_x_der, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Emeric Brunba841a12014-04-30 17:05:08 +02004588 { "ssl_f_i_dn", smp_fetch_ssl_x_i_dn, ARG2(0,STR,SINT), NULL, SMP_T_STR, SMP_USE_L5CLI },
4589 { "ssl_f_key_alg", smp_fetch_ssl_x_key_alg, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
4590 { "ssl_f_notafter", smp_fetch_ssl_x_notafter, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
4591 { "ssl_f_notbefore", smp_fetch_ssl_x_notbefore, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
4592 { "ssl_f_sig_alg", smp_fetch_ssl_x_sig_alg, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
4593 { "ssl_f_s_dn", smp_fetch_ssl_x_s_dn, ARG2(0,STR,SINT), NULL, SMP_T_STR, SMP_USE_L5CLI },
4594 { "ssl_f_serial", smp_fetch_ssl_x_serial, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Emeric Brun55f4fa82014-04-30 17:11:25 +02004595 { "ssl_f_sha1", smp_fetch_ssl_x_sha1, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Emeric Brunba841a12014-04-30 17:05:08 +02004596 { "ssl_f_version", smp_fetch_ssl_x_version, 0, NULL, SMP_T_UINT, SMP_USE_L5CLI },
Willy Tarreau80aca902013-01-07 15:42:20 +01004597 { "ssl_fc", smp_fetch_ssl_fc, 0, NULL, SMP_T_BOOL, SMP_USE_L5CLI },
4598 { "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 +01004599 { "ssl_fc_cipher", smp_fetch_ssl_fc_cipher, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Willy Tarreau80aca902013-01-07 15:42:20 +01004600 { "ssl_fc_has_crt", smp_fetch_ssl_fc_has_crt, 0, NULL, SMP_T_BOOL, SMP_USE_L5CLI },
4601 { "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 +02004602#ifdef OPENSSL_NPN_NEGOTIATED
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01004603 { "ssl_fc_npn", smp_fetch_ssl_fc_npn, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Willy Tarreaua33c6542012-10-15 13:19:06 +02004604#endif
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01004605#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01004606 { "ssl_fc_alpn", smp_fetch_ssl_fc_alpn, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Willy Tarreauab861d32013-04-02 02:30:41 +02004607#endif
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01004608 { "ssl_fc_protocol", smp_fetch_ssl_fc_protocol, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Emeric Brunb73a9b02014-04-30 18:49:19 +02004609 { "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 +01004610 { "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 +01004611 { "ssl_fc_session_id", smp_fetch_ssl_fc_session_id, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
4612 { "ssl_fc_sni", smp_fetch_ssl_fc_sni, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Willy Tarreau7875d092012-09-10 08:20:03 +02004613 { NULL, NULL, 0, 0, 0 },
4614}};
4615
4616/* Note: must not be declared <const> as its list will be overwritten.
4617 * Please take care of keeping this list alphabetically sorted.
4618 */
Willy Tarreaudc13c112013-06-21 23:16:39 +02004619static struct acl_kw_list acl_kws = {ILH, {
Thierry FOURNIERc5a4e982014-03-05 16:07:08 +01004620 { "ssl_fc_sni_end", "ssl_fc_sni", PAT_MATCH_END },
4621 { "ssl_fc_sni_reg", "ssl_fc_sni", PAT_MATCH_REG },
Willy Tarreau8ed669b2013-01-11 15:49:37 +01004622 { /* END */ },
Willy Tarreau7875d092012-09-10 08:20:03 +02004623}};
4624
Willy Tarreau79eeafa2012-09-14 07:53:05 +02004625/* Note: must not be declared <const> as its list will be overwritten.
4626 * Please take care of keeping this list alphabetically sorted, doing so helps
4627 * all code contributors.
4628 * Optional keywords are also declared with a NULL ->parse() function so that
4629 * the config parser can report an appropriate error when a known keyword was
4630 * not enabled.
4631 */
Willy Tarreau51fb7652012-09-18 18:24:39 +02004632static struct bind_kw_list bind_kws = { "SSL", { }, {
Willy Tarreauab861d32013-04-02 02:30:41 +02004633 { "alpn", bind_parse_alpn, 1 }, /* set ALPN supported protocols */
Emeric Brunfb510ea2012-10-05 12:00:26 +02004634 { "ca-file", bind_parse_ca_file, 1 }, /* set CAfile to process verify on client cert */
Emeric Brun2d0c4822012-10-02 13:45:20 +02004635 { "ca-ignore-err", bind_parse_ignore_err, 1 }, /* set error IDs to ignore on verify depth > 0 */
4636 { "ciphers", bind_parse_ciphers, 1 }, /* set SSL cipher suite */
Emeric Brunfb510ea2012-10-05 12:00:26 +02004637 { "crl-file", bind_parse_crl_file, 1 }, /* set certificat revocation list file use on client cert verify */
Emeric Brun2d0c4822012-10-02 13:45:20 +02004638 { "crt", bind_parse_crt, 1 }, /* load SSL certificates from this location */
4639 { "crt-ignore-err", bind_parse_ignore_err, 1 }, /* set error IDs to ingore on verify depth == 0 */
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01004640 { "crt-list", bind_parse_crt_list, 1 }, /* load a list of crt from this location */
Emeric Brun2d0c4822012-10-02 13:45:20 +02004641 { "ecdhe", bind_parse_ecdhe, 1 }, /* defines named curve for elliptic curve Diffie-Hellman */
Emeric Brun2cb7ae52012-10-05 14:14:21 +02004642 { "force-sslv3", bind_parse_force_sslv3, 0 }, /* force SSLv3 */
4643 { "force-tlsv10", bind_parse_force_tlsv10, 0 }, /* force TLSv10 */
4644 { "force-tlsv11", bind_parse_force_tlsv11, 0 }, /* force TLSv11 */
4645 { "force-tlsv12", bind_parse_force_tlsv12, 0 }, /* force TLSv12 */
Emeric Brun9b3009b2012-10-05 11:55:06 +02004646 { "no-sslv3", bind_parse_no_sslv3, 0 }, /* disable SSLv3 */
4647 { "no-tlsv10", bind_parse_no_tlsv10, 0 }, /* disable TLSv10 */
4648 { "no-tlsv11", bind_parse_no_tlsv11, 0 }, /* disable TLSv11 */
4649 { "no-tlsv12", bind_parse_no_tlsv12, 0 }, /* disable TLSv12 */
Emeric Brun2d0c4822012-10-02 13:45:20 +02004650 { "no-tls-tickets", bind_parse_no_tls_tickets, 0 }, /* disable session resumption tickets */
Emeric Brun2d0c4822012-10-02 13:45:20 +02004651 { "ssl", bind_parse_ssl, 0 }, /* enable SSL processing */
Emmanuel Hocdet65623372013-01-24 17:17:15 +01004652 { "strict-sni", bind_parse_strict_sni, 0 }, /* refuse negotiation if sni doesn't match a certificate */
Emeric Brun2d0c4822012-10-02 13:45:20 +02004653 { "verify", bind_parse_verify, 1 }, /* set SSL verify method */
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02004654 { "npn", bind_parse_npn, 1 }, /* set NPN supported protocols */
Willy Tarreau79eeafa2012-09-14 07:53:05 +02004655 { NULL, NULL, 0 },
4656}};
Emeric Brun46591952012-05-18 15:47:34 +02004657
Willy Tarreau92faadf2012-10-10 23:04:25 +02004658/* Note: must not be declared <const> as its list will be overwritten.
4659 * Please take care of keeping this list alphabetically sorted, doing so helps
4660 * all code contributors.
4661 * Optional keywords are also declared with a NULL ->parse() function so that
4662 * the config parser can report an appropriate error when a known keyword was
4663 * not enabled.
4664 */
4665static struct srv_kw_list srv_kws = { "SSL", { }, {
Emeric Brunef42d922012-10-11 16:11:36 +02004666 { "ca-file", srv_parse_ca_file, 1, 0 }, /* set CAfile to process verify server cert */
Emeric Brunecc91fe2012-10-11 15:05:10 +02004667 { "check-ssl", srv_parse_check_ssl, 0, 0 }, /* enable SSL for health checks */
4668 { "ciphers", srv_parse_ciphers, 1, 0 }, /* select the cipher suite */
Emeric Brunef42d922012-10-11 16:11:36 +02004669 { "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 +02004670 { "crt", srv_parse_crt, 1, 0 }, /* set client certificate */
Emeric Brunecc91fe2012-10-11 15:05:10 +02004671 { "force-sslv3", srv_parse_force_sslv3, 0, 0 }, /* force SSLv3 */
4672 { "force-tlsv10", srv_parse_force_tlsv10, 0, 0 }, /* force TLSv10 */
4673 { "force-tlsv11", srv_parse_force_tlsv11, 0, 0 }, /* force TLSv11 */
4674 { "force-tlsv12", srv_parse_force_tlsv12, 0, 0 }, /* force TLSv12 */
4675 { "no-sslv3", srv_parse_no_sslv3, 0, 0 }, /* disable SSLv3 */
4676 { "no-tlsv10", srv_parse_no_tlsv10, 0, 0 }, /* disable TLSv10 */
4677 { "no-tlsv11", srv_parse_no_tlsv11, 0, 0 }, /* disable TLSv11 */
4678 { "no-tlsv12", srv_parse_no_tlsv12, 0, 0 }, /* disable TLSv12 */
Emeric Brunf9c5c472012-10-11 15:28:34 +02004679 { "no-tls-tickets", srv_parse_no_tls_tickets, 0, 0 }, /* disable session resumption tickets */
David Safb76832014-05-08 23:42:08 -04004680 { "send-proxy-v2-ssl", srv_parse_send_proxy_ssl, 0, 0 }, /* send PROXY protocol header v2 with SSL info */
4681 { "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 +02004682 { "ssl", srv_parse_ssl, 0, 0 }, /* enable SSL processing */
Emeric Brunef42d922012-10-11 16:11:36 +02004683 { "verify", srv_parse_verify, 1, 0 }, /* set SSL verify method */
Evan Broderbe554312013-06-27 00:05:25 -07004684 { "verifyhost", srv_parse_verifyhost, 1, 0 }, /* require that SSL cert verifies for hostname */
Willy Tarreau92faadf2012-10-10 23:04:25 +02004685 { NULL, NULL, 0, 0 },
4686}};
4687
Emeric Brun42a3e202014-10-30 15:56:50 +01004688static struct cfg_kw_list cfg_kws = {ILH, {
4689 { CFG_GLOBAL, "ssl-default-bind-options", ssl_parse_default_bind_options },
4690 { CFG_GLOBAL, "ssl-default-server-options", ssl_parse_default_server_options },
4691 { 0, NULL, NULL },
4692}};
4693
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02004694/* transport-layer operations for SSL sockets */
4695struct xprt_ops ssl_sock = {
Emeric Brun46591952012-05-18 15:47:34 +02004696 .snd_buf = ssl_sock_from_buf,
4697 .rcv_buf = ssl_sock_to_buf,
4698 .rcv_pipe = NULL,
4699 .snd_pipe = NULL,
4700 .shutr = NULL,
4701 .shutw = ssl_sock_shutw,
4702 .close = ssl_sock_close,
4703 .init = ssl_sock_init,
4704};
4705
4706__attribute__((constructor))
Willy Tarreau92faadf2012-10-10 23:04:25 +02004707static void __ssl_sock_init(void)
4708{
Emeric Brun46591952012-05-18 15:47:34 +02004709 STACK_OF(SSL_COMP)* cm;
4710
Willy Tarreau610f04b2014-02-13 11:36:41 +01004711#ifdef LISTEN_DEFAULT_CIPHERS
4712 global.listen_default_ciphers = LISTEN_DEFAULT_CIPHERS;
4713#endif
4714#ifdef CONNECT_DEFAULT_CIPHERS
4715 global.connect_default_ciphers = CONNECT_DEFAULT_CIPHERS;
4716#endif
4717 if (global.listen_default_ciphers)
4718 global.listen_default_ciphers = strdup(global.listen_default_ciphers);
4719 if (global.connect_default_ciphers)
4720 global.connect_default_ciphers = strdup(global.connect_default_ciphers);
Emeric Brun42a3e202014-10-30 15:56:50 +01004721 global.listen_default_ssloptions = BC_SSL_O_NONE;
4722 global.connect_default_ssloptions = SRV_SSL_O_NONE;
Willy Tarreau610f04b2014-02-13 11:36:41 +01004723
Emeric Brun46591952012-05-18 15:47:34 +02004724 SSL_library_init();
4725 cm = SSL_COMP_get_compression_methods();
4726 sk_SSL_COMP_zero(cm);
Willy Tarreau7875d092012-09-10 08:20:03 +02004727 sample_register_fetches(&sample_fetch_keywords);
4728 acl_register_keywords(&acl_kws);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02004729 bind_register_keywords(&bind_kws);
Willy Tarreau92faadf2012-10-10 23:04:25 +02004730 srv_register_keywords(&srv_kws);
Emeric Brun42a3e202014-10-30 15:56:50 +01004731 cfg_register_keywords(&cfg_kws);
Remi Gacogne5d769ca2015-05-28 16:23:00 +02004732
4733#ifndef OPENSSL_NO_DH
4734 ssl_dh_ptr_index = SSL_CTX_get_ex_new_index(0, NULL, NULL, NULL, NULL);
4735#endif
Emeric Brun46591952012-05-18 15:47:34 +02004736}
4737
Remi Gacogne269a02f2015-05-28 16:39:47 +02004738__attribute__((destructor))
4739static void __ssl_sock_deinit(void)
4740{
4741#ifndef OPENSSL_NO_DH
4742 if (local_dh_1024) {
4743 DH_free(local_dh_1024);
4744 local_dh_1024 = NULL;
4745 }
4746
4747 if (local_dh_2048) {
4748 DH_free(local_dh_2048);
4749 local_dh_2048 = NULL;
4750 }
4751
4752 if (local_dh_4096) {
4753 DH_free(local_dh_4096);
4754 local_dh_4096 = NULL;
4755 }
4756
4757 if (local_dh_8192) {
4758 DH_free(local_dh_8192);
4759 local_dh_8192 = NULL;
4760 }
4761#endif
4762
4763 ERR_remove_state(0);
4764 ERR_free_strings();
4765
4766 EVP_cleanup();
4767
4768#if OPENSSL_VERSION_NUMBER >= 0x00907000L
4769 CRYPTO_cleanup_all_ex_data();
4770#endif
4771}
4772
4773
Emeric Brun46591952012-05-18 15:47:34 +02004774/*
4775 * Local variables:
4776 * c-indent-level: 8
4777 * c-basic-offset: 8
4778 * End:
4779 */