blob: 67422dc75d37e2f6706a465a56bac6a8deb9edcd [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>
Lukas Tribuse4e30f72014-12-09 16:32:51 +010047#if (defined SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB && !defined OPENSSL_NO_OCSP)
Emeric Brun4147b2e2014-06-16 18:36:30 +020048#include <openssl/ocsp.h>
49#endif
Emeric Brun46591952012-05-18 15:47:34 +020050
51#include <common/buffer.h>
52#include <common/compat.h>
53#include <common/config.h>
54#include <common/debug.h>
Willy Tarreau79eeafa2012-09-14 07:53:05 +020055#include <common/errors.h>
Emeric Brun46591952012-05-18 15:47:34 +020056#include <common/standard.h>
57#include <common/ticks.h>
58#include <common/time.h>
Emeric Brun2c86cbf2014-10-30 15:56:50 +010059#include <common/cfgparse.h>
Emeric Brun46591952012-05-18 15:47:34 +020060
Emeric Brunfc0421f2012-09-07 17:30:07 +020061#include <ebsttree.h>
62
63#include <types/global.h>
64#include <types/ssl_sock.h>
65
Willy Tarreau7875d092012-09-10 08:20:03 +020066#include <proto/acl.h>
67#include <proto/arg.h>
Emeric Brun46591952012-05-18 15:47:34 +020068#include <proto/connection.h>
69#include <proto/fd.h>
70#include <proto/freq_ctr.h>
71#include <proto/frontend.h>
Willy Tarreau79eeafa2012-09-14 07:53:05 +020072#include <proto/listener.h>
Thierry FOURNIERed66c292013-11-28 11:05:19 +010073#include <proto/pattern.h>
Willy Tarreau92faadf2012-10-10 23:04:25 +020074#include <proto/server.h>
Emeric Brun46591952012-05-18 15:47:34 +020075#include <proto/log.h>
Emeric Brun94324a42012-10-11 14:00:19 +020076#include <proto/proxy.h>
Emeric Brunfc0421f2012-09-07 17:30:07 +020077#include <proto/shctx.h>
Emeric Brun46591952012-05-18 15:47:34 +020078#include <proto/ssl_sock.h>
79#include <proto/task.h>
80
Willy Tarreau518cedd2014-02-17 15:43:01 +010081/* Warning, these are bits, not integers! */
Emeric Brune64aef12012-09-21 13:15:06 +020082#define SSL_SOCK_ST_FL_VERIFY_DONE 0x00000001
Emeric Brund8b2bb52014-01-28 15:43:53 +010083#define SSL_SOCK_ST_FL_16K_WBFSIZE 0x00000002
Willy Tarreau518cedd2014-02-17 15:43:01 +010084#define SSL_SOCK_SEND_UNLIMITED 0x00000004
Emeric Brun29f037d2014-04-25 19:05:36 +020085#define SSL_SOCK_RECV_HEARTBEAT 0x00000008
86
Emeric Brunf282a812012-09-21 15:27:54 +020087/* bits 0xFFFF0000 are reserved to store verify errors */
88
89/* Verify errors macros */
90#define SSL_SOCK_CA_ERROR_TO_ST(e) (((e > 63) ? 63 : e) << (16))
91#define SSL_SOCK_CAEDEPTH_TO_ST(d) (((d > 15) ? 15 : d) << (6+16))
92#define SSL_SOCK_CRTERROR_TO_ST(e) (((e > 63) ? 63 : e) << (4+6+16))
93
94#define SSL_SOCK_ST_TO_CA_ERROR(s) ((s >> (16)) & 63)
95#define SSL_SOCK_ST_TO_CAEDEPTH(s) ((s >> (6+16)) & 15)
96#define SSL_SOCK_ST_TO_CRTERROR(s) ((s >> (4+6+16)) & 63)
Emeric Brune64aef12012-09-21 13:15:06 +020097
Emeric Brun850efd52014-01-29 12:24:34 +010098/* server and bind verify method, it uses a global value as default */
99enum {
100 SSL_SOCK_VERIFY_DEFAULT = 0,
101 SSL_SOCK_VERIFY_REQUIRED = 1,
102 SSL_SOCK_VERIFY_OPTIONAL = 2,
103 SSL_SOCK_VERIFY_NONE = 3,
104};
105
Willy Tarreau71b734c2014-01-28 15:19:44 +0100106int sslconns = 0;
107int totalsslconns = 0;
Emeric Brune1f38db2012-09-03 20:36:47 +0200108
Remi Gacogne8de54152014-07-15 11:36:40 +0200109#ifndef OPENSSL_NO_DH
110static DH *local_dh_1024 = NULL;
111static DH *local_dh_2048 = NULL;
112static DH *local_dh_4096 = NULL;
113static DH *local_dh_8192 = NULL;
114#endif /* OPENSSL_NO_DH */
115
Lukas Tribuse4e30f72014-12-09 16:32:51 +0100116#if (defined SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB && !defined OPENSSL_NO_OCSP)
Emeric Brun4147b2e2014-06-16 18:36:30 +0200117struct certificate_ocsp {
118 struct ebmb_node key;
119 unsigned char key_data[OCSP_MAX_CERTID_ASN1_LENGTH];
120 struct chunk response;
Emeric Brun4f3c87a2014-06-20 15:46:13 +0200121 long expire;
Emeric Brun4147b2e2014-06-16 18:36:30 +0200122};
123
Emeric Brun4f3c87a2014-06-20 15:46:13 +0200124/*
125 * This function returns the number of seconds elapsed
126 * since the Epoch, 1970-01-01 00:00:00 +0000 (UTC) and the
127 * date presented un ASN1_GENERALIZEDTIME.
128 *
129 * In parsing error case, it returns -1.
130 */
131static long asn1_generalizedtime_to_epoch(ASN1_GENERALIZEDTIME *d)
132{
133 long epoch;
134 char *p, *end;
135 const unsigned short month_offset[12] = {
136 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334
137 };
138 int year, month;
139
140 if (!d || (d->type != V_ASN1_GENERALIZEDTIME)) return -1;
141
142 p = (char *)d->data;
143 end = p + d->length;
144
145 if (end - p < 4) return -1;
146 year = 1000 * (p[0] - '0') + 100 * (p[1] - '0') + 10 * (p[2] - '0') + p[3] - '0';
147 p += 4;
148 if (end - p < 2) return -1;
149 month = 10 * (p[0] - '0') + p[1] - '0';
150 if (month < 1 || month > 12) return -1;
151 /* Compute the number of seconds since 1 jan 1970 and the beginning of current month
152 We consider leap years and the current month (<marsh or not) */
153 epoch = ( ((year - 1970) * 365)
154 + ((year - (month < 3)) / 4 - (year - (month < 3)) / 100 + (year - (month < 3)) / 400)
155 - ((1970 - 1) / 4 - (1970 - 1) / 100 + (1970 - 1) / 400)
156 + month_offset[month-1]
157 ) * 24 * 60 * 60;
158 p += 2;
159 if (end - p < 2) return -1;
160 /* Add the number of seconds of completed days of current month */
161 epoch += (10 * (p[0] - '0') + p[1] - '0' - 1) * 24 * 60 * 60;
162 p += 2;
163 if (end - p < 2) return -1;
164 /* Add the completed hours of the current day */
165 epoch += (10 * (p[0] - '0') + p[1] - '0') * 60 * 60;
166 p += 2;
167 if (end - p < 2) return -1;
168 /* Add the completed minutes of the current hour */
169 epoch += (10 * (p[0] - '0') + p[1] - '0') * 60;
170 p += 2;
171 if (p == end) return -1;
172 /* Test if there is available seconds */
173 if (p[0] < '0' || p[0] > '9')
174 goto nosec;
175 if (end - p < 2) return -1;
176 /* Add the seconds of the current minute */
177 epoch += 10 * (p[0] - '0') + p[1] - '0';
178 p += 2;
179 if (p == end) return -1;
180 /* Ignore seconds float part if present */
181 if (p[0] == '.') {
182 do {
183 if (++p == end) return -1;
184 } while (p[0] >= '0' && p[0] <= '9');
185 }
186
187nosec:
188 if (p[0] == 'Z') {
189 if (end - p != 1) return -1;
190 return epoch;
191 }
192 else if (p[0] == '+') {
193 if (end - p != 5) return -1;
194 /* Apply timezone offset */
195 return epoch - ((10 * (p[1] - '0') + p[2] - '0') * 60 + (10 * (p[3] - '0') + p[4] - '0')) * 60;
196 }
197 else if (p[0] == '-') {
198 if (end - p != 5) return -1;
199 /* Apply timezone offset */
200 return epoch + ((10 * (p[1] - '0') + p[2] - '0') * 60 + (10 * (p[3] - '0') + p[4] - '0')) * 60;
201 }
202
203 return -1;
204}
205
Emeric Brun1d3865b2014-06-20 15:37:32 +0200206static struct eb_root cert_ocsp_tree = EB_ROOT_UNIQUE;
Emeric Brun4147b2e2014-06-16 18:36:30 +0200207
208/* This function starts to check if the OCSP response (in DER format) contained
209 * in chunk 'ocsp_response' is valid (else exits on error).
210 * If 'cid' is not NULL, it will be compared to the OCSP certificate ID
211 * contained in the OCSP Response and exits on error if no match.
212 * If it's a valid OCSP Response:
213 * If 'ocsp' is not NULL, the chunk is copied in the OCSP response's container
214 * pointed by 'ocsp'.
215 * If 'ocsp' is NULL, the function looks up into the OCSP response's
216 * containers tree (using as index the ASN1 form of the OCSP Certificate ID extracted
217 * from the response) and exits on error if not found. Finally, If an OCSP response is
218 * already present in the container, it will be overwritten.
219 *
220 * Note: OCSP response containing more than one OCSP Single response is not
221 * considered valid.
222 *
223 * Returns 0 on success, 1 in error case.
224 */
225static int ssl_sock_load_ocsp_response(struct chunk *ocsp_response, struct certificate_ocsp *ocsp, OCSP_CERTID *cid, char **err)
226{
227 OCSP_RESPONSE *resp;
228 OCSP_BASICRESP *bs = NULL;
229 OCSP_SINGLERESP *sr;
230 unsigned char *p = (unsigned char *)ocsp_response->str;
231 int rc , count_sr;
Emeric Brun13a6b482014-06-20 15:44:34 +0200232 ASN1_GENERALIZEDTIME *revtime, *thisupd, *nextupd = NULL;
Emeric Brun4147b2e2014-06-16 18:36:30 +0200233 int reason;
234 int ret = 1;
235
236 resp = d2i_OCSP_RESPONSE(NULL, (const unsigned char **)&p, ocsp_response->len);
237 if (!resp) {
238 memprintf(err, "Unable to parse OCSP response");
239 goto out;
240 }
241
242 rc = OCSP_response_status(resp);
243 if (rc != OCSP_RESPONSE_STATUS_SUCCESSFUL) {
244 memprintf(err, "OCSP response status not successful");
245 goto out;
246 }
247
248 bs = OCSP_response_get1_basic(resp);
249 if (!bs) {
250 memprintf(err, "Failed to get basic response from OCSP Response");
251 goto out;
252 }
253
254 count_sr = OCSP_resp_count(bs);
255 if (count_sr > 1) {
256 memprintf(err, "OCSP response ignored because contains multiple single responses (%d)", count_sr);
257 goto out;
258 }
259
260 sr = OCSP_resp_get0(bs, 0);
261 if (!sr) {
262 memprintf(err, "Failed to get OCSP single response");
263 goto out;
264 }
265
266 rc = OCSP_single_get0_status(sr, &reason, &revtime, &thisupd, &nextupd);
267 if (rc != V_OCSP_CERTSTATUS_GOOD) {
268 memprintf(err, "OCSP single response: certificate status not good");
269 goto out;
270 }
271
Emeric Brun13a6b482014-06-20 15:44:34 +0200272 if (!nextupd) {
273 memprintf(err, "OCSP single response: missing nextupdate");
274 goto out;
275 }
276
Emeric Brunc8b27b62014-06-19 14:16:17 +0200277 rc = OCSP_check_validity(thisupd, nextupd, OCSP_MAX_RESPONSE_TIME_SKEW, -1);
Emeric Brun4147b2e2014-06-16 18:36:30 +0200278 if (!rc) {
279 memprintf(err, "OCSP single response: no longer valid.");
280 goto out;
281 }
282
283 if (cid) {
284 if (OCSP_id_cmp(sr->certId, cid)) {
285 memprintf(err, "OCSP single response: Certificate ID does not match certificate and issuer");
286 goto out;
287 }
288 }
289
290 if (!ocsp) {
291 unsigned char key[OCSP_MAX_CERTID_ASN1_LENGTH];
292 unsigned char *p;
293
294 rc = i2d_OCSP_CERTID(sr->certId, NULL);
295 if (!rc) {
296 memprintf(err, "OCSP single response: Unable to encode Certificate ID");
297 goto out;
298 }
299
300 if (rc > OCSP_MAX_CERTID_ASN1_LENGTH) {
301 memprintf(err, "OCSP single response: Certificate ID too long");
302 goto out;
303 }
304
305 p = key;
306 memset(key, 0, OCSP_MAX_CERTID_ASN1_LENGTH);
307 i2d_OCSP_CERTID(sr->certId, &p);
308 ocsp = (struct certificate_ocsp *)ebmb_lookup(&cert_ocsp_tree, key, OCSP_MAX_CERTID_ASN1_LENGTH);
309 if (!ocsp) {
310 memprintf(err, "OCSP single response: Certificate ID does not match any certificate or issuer");
311 goto out;
312 }
313 }
314
315 /* According to comments on "chunk_dup", the
316 previous chunk buffer will be freed */
317 if (!chunk_dup(&ocsp->response, ocsp_response)) {
318 memprintf(err, "OCSP response: Memory allocation error");
319 goto out;
320 }
321
Emeric Brun4f3c87a2014-06-20 15:46:13 +0200322 ocsp->expire = asn1_generalizedtime_to_epoch(nextupd) - OCSP_MAX_RESPONSE_TIME_SKEW;
323
Emeric Brun4147b2e2014-06-16 18:36:30 +0200324 ret = 0;
325out:
326 if (bs)
327 OCSP_BASICRESP_free(bs);
328
329 if (resp)
330 OCSP_RESPONSE_free(resp);
331
332 return ret;
333}
334/*
335 * External function use to update the OCSP response in the OCSP response's
336 * containers tree. The chunk 'ocsp_response' must contain the OCSP response
337 * to update in DER format.
338 *
339 * Returns 0 on success, 1 in error case.
340 */
341int ssl_sock_update_ocsp_response(struct chunk *ocsp_response, char **err)
342{
343 return ssl_sock_load_ocsp_response(ocsp_response, NULL, NULL, err);
344}
345
346/*
347 * This function load the OCSP Resonse in DER format contained in file at
348 * path 'ocsp_path' and call 'ssl_sock_load_ocsp_response'
349 *
350 * Returns 0 on success, 1 in error case.
351 */
352static int ssl_sock_load_ocsp_response_from_file(const char *ocsp_path, struct certificate_ocsp *ocsp, OCSP_CERTID *cid, char **err)
353{
354 int fd = -1;
355 int r = 0;
356 int ret = 1;
357
358 fd = open(ocsp_path, O_RDONLY);
359 if (fd == -1) {
360 memprintf(err, "Error opening OCSP response file");
361 goto end;
362 }
363
364 trash.len = 0;
365 while (trash.len < trash.size) {
366 r = read(fd, trash.str + trash.len, trash.size - trash.len);
367 if (r < 0) {
368 if (errno == EINTR)
369 continue;
370
371 memprintf(err, "Error reading OCSP response from file");
372 goto end;
373 }
374 else if (r == 0) {
375 break;
376 }
377 trash.len += r;
378 }
379
380 close(fd);
381 fd = -1;
382
383 ret = ssl_sock_load_ocsp_response(&trash, ocsp, cid, err);
384end:
385 if (fd != -1)
386 close(fd);
387
388 return ret;
389}
390
391/*
392 * Callback used to set OCSP status extension content in server hello.
393 */
394int ssl_sock_ocsp_stapling_cbk(SSL *ssl, void *arg)
395{
396 struct certificate_ocsp *ocsp = (struct certificate_ocsp *)arg;
397 char* ssl_buf;
398
399 if (!ocsp ||
400 !ocsp->response.str ||
Emeric Brun4f3c87a2014-06-20 15:46:13 +0200401 !ocsp->response.len ||
402 (ocsp->expire < now.tv_sec))
Emeric Brun4147b2e2014-06-16 18:36:30 +0200403 return SSL_TLSEXT_ERR_NOACK;
404
405 ssl_buf = OPENSSL_malloc(ocsp->response.len);
406 if (!ssl_buf)
407 return SSL_TLSEXT_ERR_NOACK;
408
409 memcpy(ssl_buf, ocsp->response.str, ocsp->response.len);
410 SSL_set_tlsext_status_ocsp_resp(ssl, ssl_buf, ocsp->response.len);
411
412 return SSL_TLSEXT_ERR_OK;
413}
414
415/*
416 * This function enables the handling of OCSP status extension on 'ctx' if a
417 * file name 'cert_path' suffixed using ".ocsp" is present.
418 * To enable OCSP status extension, the issuer's certificate is mandatory.
419 * It should be present in the certificate's extra chain builded from file
420 * 'cert_path'. If not found, the issuer certificate is loaded from a file
421 * named 'cert_path' suffixed using '.issuer'.
422 *
423 * In addition, ".ocsp" file content is loaded as a DER format of an OCSP
424 * response. If file is empty or content is not a valid OCSP response,
425 * OCSP status extension is enabled but OCSP response is ignored (a warning
426 * is displayed).
427 *
428 * Returns 1 if no ".ocsp" file found, 0 if OCSP status extension is
429 * succesfully enabled, or -1 in other error case.
430 */
431static int ssl_sock_load_ocsp(SSL_CTX *ctx, const char *cert_path)
432{
433
434 BIO *in = NULL;
435 X509 *x, *xi = NULL, *issuer = NULL;
436 STACK_OF(X509) *chain = NULL;
437 OCSP_CERTID *cid = NULL;
438 SSL *ssl;
439 char ocsp_path[MAXPATHLEN+1];
440 int i, ret = -1;
441 struct stat st;
442 struct certificate_ocsp *ocsp = NULL, *iocsp;
443 char *warn = NULL;
444 unsigned char *p;
445
446 snprintf(ocsp_path, MAXPATHLEN+1, "%s.ocsp", cert_path);
447
448 if (stat(ocsp_path, &st))
449 return 1;
450
451 ssl = SSL_new(ctx);
452 if (!ssl)
453 goto out;
454
455 x = SSL_get_certificate(ssl);
456 if (!x)
457 goto out;
458
459 /* Try to lookup for issuer in certificate extra chain */
460#ifdef SSL_CTRL_GET_EXTRA_CHAIN_CERTS
461 SSL_CTX_get_extra_chain_certs(ctx, &chain);
462#else
463 chain = ctx->extra_certs;
464#endif
465 for (i = 0; i < sk_X509_num(chain); i++) {
466 issuer = sk_X509_value(chain, i);
467 if (X509_check_issued(issuer, x) == X509_V_OK)
468 break;
469 else
470 issuer = NULL;
471 }
472
473 /* If not found try to load issuer from a suffixed file */
474 if (!issuer) {
475 char issuer_path[MAXPATHLEN+1];
476
477 in = BIO_new(BIO_s_file());
478 if (!in)
479 goto out;
480
481 snprintf(issuer_path, MAXPATHLEN+1, "%s.issuer", cert_path);
482 if (BIO_read_filename(in, issuer_path) <= 0)
483 goto out;
484
485 xi = PEM_read_bio_X509_AUX(in, NULL, ctx->default_passwd_callback, ctx->default_passwd_callback_userdata);
486 if (!xi)
487 goto out;
488
489 if (X509_check_issued(xi, x) != X509_V_OK)
490 goto out;
491
492 issuer = xi;
493 }
494
495 cid = OCSP_cert_to_id(0, x, issuer);
496 if (!cid)
497 goto out;
498
499 i = i2d_OCSP_CERTID(cid, NULL);
500 if (!i || (i > OCSP_MAX_CERTID_ASN1_LENGTH))
501 goto out;
502
503 ocsp = calloc(1, sizeof(struct certificate_ocsp));
504 if (!ocsp)
505 goto out;
506
507 p = ocsp->key_data;
508 i2d_OCSP_CERTID(cid, &p);
509
510 iocsp = (struct certificate_ocsp *)ebmb_insert(&cert_ocsp_tree, &ocsp->key, OCSP_MAX_CERTID_ASN1_LENGTH);
511 if (iocsp == ocsp)
512 ocsp = NULL;
513
514 SSL_CTX_set_tlsext_status_cb(ctx, ssl_sock_ocsp_stapling_cbk);
515 SSL_CTX_set_tlsext_status_arg(ctx, iocsp);
516
517 ret = 0;
518
519 warn = NULL;
520 if (ssl_sock_load_ocsp_response_from_file(ocsp_path, iocsp, cid, &warn)) {
521 memprintf(&warn, "Loading '%s': %s. Content will be ignored", ocsp_path, warn ? warn : "failure");
522 Warning("%s.\n", warn);
523 }
524
525out:
526 if (ssl)
527 SSL_free(ssl);
528
529 if (in)
530 BIO_free(in);
531
532 if (xi)
533 X509_free(xi);
534
535 if (cid)
536 OCSP_CERTID_free(cid);
537
538 if (ocsp)
539 free(ocsp);
540
541 if (warn)
542 free(warn);
543
544
545 return ret;
546}
547
548#endif
549
Emeric Brune1f38db2012-09-03 20:36:47 +0200550void ssl_sock_infocbk(const SSL *ssl, int where, int ret)
551{
552 struct connection *conn = (struct connection *)SSL_get_app_data(ssl);
553 (void)ret; /* shut gcc stupid warning */
Emeric Brund8b2bb52014-01-28 15:43:53 +0100554 BIO *write_bio;
Emeric Brune1f38db2012-09-03 20:36:47 +0200555
556 if (where & SSL_CB_HANDSHAKE_START) {
557 /* Disable renegotiation (CVE-2009-3555) */
Willy Tarreau20879a02012-12-03 16:32:10 +0100558 if (conn->flags & CO_FL_CONNECTED) {
Emeric Brune1f38db2012-09-03 20:36:47 +0200559 conn->flags |= CO_FL_ERROR;
Willy Tarreau20879a02012-12-03 16:32:10 +0100560 conn->err_code = CO_ER_SSL_RENEG;
561 }
Emeric Brune1f38db2012-09-03 20:36:47 +0200562 }
Emeric Brund8b2bb52014-01-28 15:43:53 +0100563
564 if ((where & SSL_CB_ACCEPT_LOOP) == SSL_CB_ACCEPT_LOOP) {
565 if (!(conn->xprt_st & SSL_SOCK_ST_FL_16K_WBFSIZE)) {
566 /* Long certificate chains optimz
567 If write and read bios are differents, we
568 consider that the buffering was activated,
569 so we rise the output buffer size from 4k
570 to 16k */
571 write_bio = SSL_get_wbio(ssl);
572 if (write_bio != SSL_get_rbio(ssl)) {
573 BIO_set_write_buffer_size(write_bio, 16384);
574 conn->xprt_st |= SSL_SOCK_ST_FL_16K_WBFSIZE;
575 }
576 }
577 }
Emeric Brunfc0421f2012-09-07 17:30:07 +0200578}
579
Emeric Brune64aef12012-09-21 13:15:06 +0200580/* Callback is called for each certificate of the chain during a verify
581 ok is set to 1 if preverify detect no error on current certificate.
582 Returns 0 to break the handshake, 1 otherwise. */
Evan Broderbe554312013-06-27 00:05:25 -0700583int ssl_sock_bind_verifycbk(int ok, X509_STORE_CTX *x_store)
Emeric Brune64aef12012-09-21 13:15:06 +0200584{
585 SSL *ssl;
586 struct connection *conn;
Emeric Brun81c00f02012-09-21 14:31:21 +0200587 int err, depth;
Emeric Brune64aef12012-09-21 13:15:06 +0200588
589 ssl = X509_STORE_CTX_get_ex_data(x_store, SSL_get_ex_data_X509_STORE_CTX_idx());
590 conn = (struct connection *)SSL_get_app_data(ssl);
591
Willy Tarreauf7bc57c2012-10-03 00:19:48 +0200592 conn->xprt_st |= SSL_SOCK_ST_FL_VERIFY_DONE;
Emeric Brune64aef12012-09-21 13:15:06 +0200593
Emeric Brun81c00f02012-09-21 14:31:21 +0200594 if (ok) /* no errors */
595 return ok;
596
597 depth = X509_STORE_CTX_get_error_depth(x_store);
598 err = X509_STORE_CTX_get_error(x_store);
599
600 /* check if CA error needs to be ignored */
601 if (depth > 0) {
Willy Tarreauf7bc57c2012-10-03 00:19:48 +0200602 if (!SSL_SOCK_ST_TO_CA_ERROR(conn->xprt_st)) {
603 conn->xprt_st |= SSL_SOCK_CA_ERROR_TO_ST(err);
604 conn->xprt_st |= SSL_SOCK_CAEDEPTH_TO_ST(depth);
Emeric Brunf282a812012-09-21 15:27:54 +0200605 }
606
Emeric Brun1eb20ef2012-12-03 13:24:29 +0100607 if (objt_listener(conn->target)->bind_conf->ca_ignerr & (1ULL << err)) {
608 ERR_clear_error();
Emeric Brun81c00f02012-09-21 14:31:21 +0200609 return 1;
Emeric Brun1eb20ef2012-12-03 13:24:29 +0100610 }
Emeric Brun81c00f02012-09-21 14:31:21 +0200611
Willy Tarreau20879a02012-12-03 16:32:10 +0100612 conn->err_code = CO_ER_SSL_CA_FAIL;
Emeric Brun81c00f02012-09-21 14:31:21 +0200613 return 0;
614 }
615
Willy Tarreauf7bc57c2012-10-03 00:19:48 +0200616 if (!SSL_SOCK_ST_TO_CRTERROR(conn->xprt_st))
617 conn->xprt_st |= SSL_SOCK_CRTERROR_TO_ST(err);
Emeric Brunf282a812012-09-21 15:27:54 +0200618
Emeric Brun81c00f02012-09-21 14:31:21 +0200619 /* check if certificate error needs to be ignored */
Emeric Brun1eb20ef2012-12-03 13:24:29 +0100620 if (objt_listener(conn->target)->bind_conf->crt_ignerr & (1ULL << err)) {
621 ERR_clear_error();
Emeric Brun81c00f02012-09-21 14:31:21 +0200622 return 1;
Emeric Brun1eb20ef2012-12-03 13:24:29 +0100623 }
Emeric Brun81c00f02012-09-21 14:31:21 +0200624
Willy Tarreau20879a02012-12-03 16:32:10 +0100625 conn->err_code = CO_ER_SSL_CRT_FAIL;
Emeric Brun81c00f02012-09-21 14:31:21 +0200626 return 0;
Emeric Brune64aef12012-09-21 13:15:06 +0200627}
628
Emeric Brun29f037d2014-04-25 19:05:36 +0200629/* Callback is called for ssl protocol analyse */
630void ssl_sock_msgcbk(int write_p, int version, int content_type, const void *buf, size_t len, SSL *ssl, void *arg)
631{
Emeric Brun29f037d2014-04-25 19:05:36 +0200632#ifdef TLS1_RT_HEARTBEAT
633 /* test heartbeat received (write_p is set to 0
634 for a received record) */
Willy Tarreauf51c6982014-04-25 20:02:39 +0200635 if ((content_type == TLS1_RT_HEARTBEAT) && (write_p == 0)) {
Willy Tarreau84815002014-04-25 21:40:27 +0200636 struct connection *conn = (struct connection *)SSL_get_app_data(ssl);
Willy Tarreauf51c6982014-04-25 20:02:39 +0200637 const unsigned char *p = buf;
638 unsigned int payload;
639
Emeric Brun29f037d2014-04-25 19:05:36 +0200640 conn->xprt_st |= SSL_SOCK_RECV_HEARTBEAT;
Willy Tarreauf51c6982014-04-25 20:02:39 +0200641
642 /* Check if this is a CVE-2014-0160 exploitation attempt. */
643 if (*p != TLS1_HB_REQUEST)
644 return;
645
Willy Tarreauaeed6722014-04-25 23:59:58 +0200646 if (len < 1 + 2 + 16) /* 1 type + 2 size + 0 payload + 16 padding */
Willy Tarreauf51c6982014-04-25 20:02:39 +0200647 goto kill_it;
648
649 payload = (p[1] * 256) + p[2];
Willy Tarreau3b2fdb62014-04-25 23:44:22 +0200650 if (3 + payload + 16 <= len)
Willy Tarreauf51c6982014-04-25 20:02:39 +0200651 return; /* OK no problem */
Willy Tarreauaeed6722014-04-25 23:59:58 +0200652 kill_it:
Willy Tarreau3b2fdb62014-04-25 23:44:22 +0200653 /* We have a clear heartbleed attack (CVE-2014-0160), the
654 * advertised payload is larger than the advertised packet
655 * length, so we have garbage in the buffer between the
656 * payload and the end of the buffer (p+len). We can't know
657 * if the SSL stack is patched, and we don't know if we can
658 * safely wipe out the area between p+3+len and payload.
659 * So instead, we prevent the response from being sent by
660 * setting the max_send_fragment to 0 and we report an SSL
661 * error, which will kill this connection. It will be reported
662 * above as SSL_ERROR_SSL while an other handshake failure with
Willy Tarreauf51c6982014-04-25 20:02:39 +0200663 * a heartbeat message will be reported as SSL_ERROR_SYSCALL.
664 */
Willy Tarreau3b2fdb62014-04-25 23:44:22 +0200665 ssl->max_send_fragment = 0;
Willy Tarreauf51c6982014-04-25 20:02:39 +0200666 SSLerr(SSL_F_TLS1_HEARTBEAT, SSL_R_SSL_HANDSHAKE_FAILURE);
667 return;
668 }
Emeric Brun29f037d2014-04-25 19:05:36 +0200669#endif
670}
671
Willy Tarreau6c9a3d52012-10-18 18:57:14 +0200672#ifdef OPENSSL_NPN_NEGOTIATED
673/* This callback is used so that the server advertises the list of
674 * negociable protocols for NPN.
675 */
676static int ssl_sock_advertise_npn_protos(SSL *s, const unsigned char **data,
677 unsigned int *len, void *arg)
678{
679 struct bind_conf *conf = arg;
680
681 *data = (const unsigned char *)conf->npn_str;
682 *len = conf->npn_len;
683 return SSL_TLSEXT_ERR_OK;
684}
685#endif
686
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +0100687#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Willy Tarreauab861d32013-04-02 02:30:41 +0200688/* This callback is used so that the server advertises the list of
689 * negociable protocols for ALPN.
690 */
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +0100691static int ssl_sock_advertise_alpn_protos(SSL *s, const unsigned char **out,
692 unsigned char *outlen,
693 const unsigned char *server,
694 unsigned int server_len, void *arg)
Willy Tarreauab861d32013-04-02 02:30:41 +0200695{
696 struct bind_conf *conf = arg;
697
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +0100698 if (SSL_select_next_proto((unsigned char**) out, outlen, (const unsigned char *)conf->alpn_str,
699 conf->alpn_len, server, server_len) != OPENSSL_NPN_NEGOTIATED) {
700 return SSL_TLSEXT_ERR_NOACK;
701 }
Willy Tarreauab861d32013-04-02 02:30:41 +0200702 return SSL_TLSEXT_ERR_OK;
703}
704#endif
705
Emeric Brunfc0421f2012-09-07 17:30:07 +0200706#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
707/* Sets the SSL ctx of <ssl> to match the advertised server name. Returns a
708 * warning when no match is found, which implies the default (first) cert
709 * will keep being used.
710 */
Willy Tarreau2a65ff02012-09-13 17:54:29 +0200711static int ssl_sock_switchctx_cbk(SSL *ssl, int *al, struct bind_conf *s)
Emeric Brunfc0421f2012-09-07 17:30:07 +0200712{
713 const char *servername;
714 const char *wildp = NULL;
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +0200715 struct ebmb_node *node, *n;
Emeric Brunfc0421f2012-09-07 17:30:07 +0200716 int i;
717 (void)al; /* shut gcc stupid warning */
718
719 servername = SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name);
Emmanuel Hocdet65623372013-01-24 17:17:15 +0100720 if (!servername) {
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +0200721 return (s->strict_sni ?
722 SSL_TLSEXT_ERR_ALERT_FATAL :
Emmanuel Hocdet79274e22013-05-31 12:47:44 +0200723 SSL_TLSEXT_ERR_NOACK);
Emmanuel Hocdet65623372013-01-24 17:17:15 +0100724 }
Emeric Brunfc0421f2012-09-07 17:30:07 +0200725
Willy Tarreau19d14ef2012-10-29 16:51:55 +0100726 for (i = 0; i < trash.size; i++) {
Emeric Brunfc0421f2012-09-07 17:30:07 +0200727 if (!servername[i])
728 break;
Willy Tarreau19d14ef2012-10-29 16:51:55 +0100729 trash.str[i] = tolower(servername[i]);
730 if (!wildp && (trash.str[i] == '.'))
731 wildp = &trash.str[i];
Emeric Brunfc0421f2012-09-07 17:30:07 +0200732 }
Willy Tarreau19d14ef2012-10-29 16:51:55 +0100733 trash.str[i] = 0;
Emeric Brunfc0421f2012-09-07 17:30:07 +0200734
735 /* lookup in full qualified names */
Willy Tarreau19d14ef2012-10-29 16:51:55 +0100736 node = ebst_lookup(&s->sni_ctx, trash.str);
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +0200737
738 /* lookup a not neg filter */
739 for (n = node; n; n = ebmb_next_dup(n)) {
740 if (!container_of(n, struct sni_ctx, name)->neg) {
741 node = n;
742 break;
Emmanuel Hocdet65623372013-01-24 17:17:15 +0100743 }
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +0200744 }
745 if (!node && wildp) {
746 /* lookup in wildcards names */
Emeric Brunfc0421f2012-09-07 17:30:07 +0200747 node = ebst_lookup(&s->sni_w_ctx, wildp);
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +0200748 }
749 if (!node || container_of(node, struct sni_ctx, name)->neg) {
750 return (s->strict_sni ?
751 SSL_TLSEXT_ERR_ALERT_FATAL :
752 SSL_TLSEXT_ERR_ALERT_WARNING);
Emeric Brunfc0421f2012-09-07 17:30:07 +0200753 }
754
755 /* switch ctx */
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +0200756 SSL_set_SSL_CTX(ssl, container_of(node, struct sni_ctx, name)->ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +0200757 return SSL_TLSEXT_ERR_OK;
758}
759#endif /* SSL_CTRL_SET_TLSEXT_HOSTNAME */
760
Emeric Bruna4bcd9a2012-09-20 16:19:02 +0200761#ifndef OPENSSL_NO_DH
Remi Gacognef46cd6e2014-06-12 14:58:40 +0200762
763static DH * ssl_get_dh_1024(void)
764{
Lukas Tribus4c0d45a2014-08-18 00:56:32 +0200765#if (OPENSSL_VERSION_NUMBER < 0x0090801fL || defined OPENSSL_IS_BORINGSSL)
Remi Gacognef46cd6e2014-06-12 14:58:40 +0200766 static const unsigned char rfc_2409_prime_1024[] = {
767 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xC9,0x0F,0xDA,0xA2,
768 0x21,0x68,0xC2,0x34,0xC4,0xC6,0x62,0x8B,0x80,0xDC,0x1C,0xD1,
769 0x29,0x02,0x4E,0x08,0x8A,0x67,0xCC,0x74,0x02,0x0B,0xBE,0xA6,
770 0x3B,0x13,0x9B,0x22,0x51,0x4A,0x08,0x79,0x8E,0x34,0x04,0xDD,
771 0xEF,0x95,0x19,0xB3,0xCD,0x3A,0x43,0x1B,0x30,0x2B,0x0A,0x6D,
772 0xF2,0x5F,0x14,0x37,0x4F,0xE1,0x35,0x6D,0x6D,0x51,0xC2,0x45,
773 0xE4,0x85,0xB5,0x76,0x62,0x5E,0x7E,0xC6,0xF4,0x4C,0x42,0xE9,
774 0xA6,0x37,0xED,0x6B,0x0B,0xFF,0x5C,0xB6,0xF4,0x06,0xB7,0xED,
775 0xEE,0x38,0x6B,0xFB,0x5A,0x89,0x9F,0xA5,0xAE,0x9F,0x24,0x11,
776 0x7C,0x4B,0x1F,0xE6,0x49,0x28,0x66,0x51,0xEC,0xE6,0x53,0x81,
777 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
778 };
779#endif
780 DH *dh = DH_new();
781 if (dh) {
Lukas Tribus4c0d45a2014-08-18 00:56:32 +0200782#if (OPENSSL_VERSION_NUMBER >= 0x0090801fL && !defined OPENSSL_IS_BORINGSSL)
Remi Gacognef46cd6e2014-06-12 14:58:40 +0200783 dh->p = get_rfc2409_prime_1024(NULL);
784#else
785 dh->p = BN_bin2bn(rfc_2409_prime_1024, sizeof rfc_2409_prime_1024, NULL);
786#endif
787 /* See RFC 2409, Section 6 "Oakley Groups"
788 for the reason why 2 is used as generator.
789 */
790 BN_dec2bn(&dh->g, "2");
791 if (!dh->p || !dh->g) {
792 DH_free(dh);
793 dh = NULL;
794 }
795 }
796 return dh;
797}
798
799static DH *ssl_get_dh_2048(void)
800{
Lukas Tribus4c0d45a2014-08-18 00:56:32 +0200801#if (OPENSSL_VERSION_NUMBER < 0x0090801fL || defined OPENSSL_IS_BORINGSSL)
Remi Gacognef46cd6e2014-06-12 14:58:40 +0200802 static const unsigned char rfc_3526_prime_2048[] = {
803 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xC9,0x0F,0xDA,0xA2,
804 0x21,0x68,0xC2,0x34,0xC4,0xC6,0x62,0x8B,0x80,0xDC,0x1C,0xD1,
805 0x29,0x02,0x4E,0x08,0x8A,0x67,0xCC,0x74,0x02,0x0B,0xBE,0xA6,
806 0x3B,0x13,0x9B,0x22,0x51,0x4A,0x08,0x79,0x8E,0x34,0x04,0xDD,
807 0xEF,0x95,0x19,0xB3,0xCD,0x3A,0x43,0x1B,0x30,0x2B,0x0A,0x6D,
808 0xF2,0x5F,0x14,0x37,0x4F,0xE1,0x35,0x6D,0x6D,0x51,0xC2,0x45,
809 0xE4,0x85,0xB5,0x76,0x62,0x5E,0x7E,0xC6,0xF4,0x4C,0x42,0xE9,
810 0xA6,0x37,0xED,0x6B,0x0B,0xFF,0x5C,0xB6,0xF4,0x06,0xB7,0xED,
811 0xEE,0x38,0x6B,0xFB,0x5A,0x89,0x9F,0xA5,0xAE,0x9F,0x24,0x11,
812 0x7C,0x4B,0x1F,0xE6,0x49,0x28,0x66,0x51,0xEC,0xE4,0x5B,0x3D,
813 0xC2,0x00,0x7C,0xB8,0xA1,0x63,0xBF,0x05,0x98,0xDA,0x48,0x36,
814 0x1C,0x55,0xD3,0x9A,0x69,0x16,0x3F,0xA8,0xFD,0x24,0xCF,0x5F,
815 0x83,0x65,0x5D,0x23,0xDC,0xA3,0xAD,0x96,0x1C,0x62,0xF3,0x56,
816 0x20,0x85,0x52,0xBB,0x9E,0xD5,0x29,0x07,0x70,0x96,0x96,0x6D,
817 0x67,0x0C,0x35,0x4E,0x4A,0xBC,0x98,0x04,0xF1,0x74,0x6C,0x08,
818 0xCA,0x18,0x21,0x7C,0x32,0x90,0x5E,0x46,0x2E,0x36,0xCE,0x3B,
819 0xE3,0x9E,0x77,0x2C,0x18,0x0E,0x86,0x03,0x9B,0x27,0x83,0xA2,
820 0xEC,0x07,0xA2,0x8F,0xB5,0xC5,0x5D,0xF0,0x6F,0x4C,0x52,0xC9,
821 0xDE,0x2B,0xCB,0xF6,0x95,0x58,0x17,0x18,0x39,0x95,0x49,0x7C,
822 0xEA,0x95,0x6A,0xE5,0x15,0xD2,0x26,0x18,0x98,0xFA,0x05,0x10,
823 0x15,0x72,0x8E,0x5A,0x8A,0xAC,0xAA,0x68,0xFF,0xFF,0xFF,0xFF,
824 0xFF,0xFF,0xFF,0xFF,
825 };
826#endif
827 DH *dh = DH_new();
828 if (dh) {
Lukas Tribus4c0d45a2014-08-18 00:56:32 +0200829#if (OPENSSL_VERSION_NUMBER >= 0x0090801fL && !defined OPENSSL_IS_BORINGSSL)
Remi Gacognef46cd6e2014-06-12 14:58:40 +0200830 dh->p = get_rfc3526_prime_2048(NULL);
831#else
832 dh->p = BN_bin2bn(rfc_3526_prime_2048, sizeof rfc_3526_prime_2048, NULL);
833#endif
834 /* See RFC 3526, Section 3 "2048-bit MODP Group"
835 for the reason why 2 is used as generator.
836 */
837 BN_dec2bn(&dh->g, "2");
838 if (!dh->p || !dh->g) {
839 DH_free(dh);
840 dh = NULL;
841 }
842 }
843 return dh;
844}
845
846static DH *ssl_get_dh_4096(void)
847{
Lukas Tribus4c0d45a2014-08-18 00:56:32 +0200848#if (OPENSSL_VERSION_NUMBER < 0x0090801fL || defined OPENSSL_IS_BORINGSSL)
Remi Gacognef46cd6e2014-06-12 14:58:40 +0200849 static const unsigned char rfc_3526_prime_4096[] = {
850 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xC9,0x0F,0xDA,0xA2,
851 0x21,0x68,0xC2,0x34,0xC4,0xC6,0x62,0x8B,0x80,0xDC,0x1C,0xD1,
852 0x29,0x02,0x4E,0x08,0x8A,0x67,0xCC,0x74,0x02,0x0B,0xBE,0xA6,
853 0x3B,0x13,0x9B,0x22,0x51,0x4A,0x08,0x79,0x8E,0x34,0x04,0xDD,
854 0xEF,0x95,0x19,0xB3,0xCD,0x3A,0x43,0x1B,0x30,0x2B,0x0A,0x6D,
855 0xF2,0x5F,0x14,0x37,0x4F,0xE1,0x35,0x6D,0x6D,0x51,0xC2,0x45,
856 0xE4,0x85,0xB5,0x76,0x62,0x5E,0x7E,0xC6,0xF4,0x4C,0x42,0xE9,
857 0xA6,0x37,0xED,0x6B,0x0B,0xFF,0x5C,0xB6,0xF4,0x06,0xB7,0xED,
858 0xEE,0x38,0x6B,0xFB,0x5A,0x89,0x9F,0xA5,0xAE,0x9F,0x24,0x11,
859 0x7C,0x4B,0x1F,0xE6,0x49,0x28,0x66,0x51,0xEC,0xE4,0x5B,0x3D,
860 0xC2,0x00,0x7C,0xB8,0xA1,0x63,0xBF,0x05,0x98,0xDA,0x48,0x36,
861 0x1C,0x55,0xD3,0x9A,0x69,0x16,0x3F,0xA8,0xFD,0x24,0xCF,0x5F,
862 0x83,0x65,0x5D,0x23,0xDC,0xA3,0xAD,0x96,0x1C,0x62,0xF3,0x56,
863 0x20,0x85,0x52,0xBB,0x9E,0xD5,0x29,0x07,0x70,0x96,0x96,0x6D,
864 0x67,0x0C,0x35,0x4E,0x4A,0xBC,0x98,0x04,0xF1,0x74,0x6C,0x08,
865 0xCA,0x18,0x21,0x7C,0x32,0x90,0x5E,0x46,0x2E,0x36,0xCE,0x3B,
866 0xE3,0x9E,0x77,0x2C,0x18,0x0E,0x86,0x03,0x9B,0x27,0x83,0xA2,
867 0xEC,0x07,0xA2,0x8F,0xB5,0xC5,0x5D,0xF0,0x6F,0x4C,0x52,0xC9,
868 0xDE,0x2B,0xCB,0xF6,0x95,0x58,0x17,0x18,0x39,0x95,0x49,0x7C,
869 0xEA,0x95,0x6A,0xE5,0x15,0xD2,0x26,0x18,0x98,0xFA,0x05,0x10,
870 0x15,0x72,0x8E,0x5A,0x8A,0xAA,0xC4,0x2D,0xAD,0x33,0x17,0x0D,
871 0x04,0x50,0x7A,0x33,0xA8,0x55,0x21,0xAB,0xDF,0x1C,0xBA,0x64,
872 0xEC,0xFB,0x85,0x04,0x58,0xDB,0xEF,0x0A,0x8A,0xEA,0x71,0x57,
873 0x5D,0x06,0x0C,0x7D,0xB3,0x97,0x0F,0x85,0xA6,0xE1,0xE4,0xC7,
874 0xAB,0xF5,0xAE,0x8C,0xDB,0x09,0x33,0xD7,0x1E,0x8C,0x94,0xE0,
875 0x4A,0x25,0x61,0x9D,0xCE,0xE3,0xD2,0x26,0x1A,0xD2,0xEE,0x6B,
876 0xF1,0x2F,0xFA,0x06,0xD9,0x8A,0x08,0x64,0xD8,0x76,0x02,0x73,
877 0x3E,0xC8,0x6A,0x64,0x52,0x1F,0x2B,0x18,0x17,0x7B,0x20,0x0C,
878 0xBB,0xE1,0x17,0x57,0x7A,0x61,0x5D,0x6C,0x77,0x09,0x88,0xC0,
879 0xBA,0xD9,0x46,0xE2,0x08,0xE2,0x4F,0xA0,0x74,0xE5,0xAB,0x31,
880 0x43,0xDB,0x5B,0xFC,0xE0,0xFD,0x10,0x8E,0x4B,0x82,0xD1,0x20,
881 0xA9,0x21,0x08,0x01,0x1A,0x72,0x3C,0x12,0xA7,0x87,0xE6,0xD7,
882 0x88,0x71,0x9A,0x10,0xBD,0xBA,0x5B,0x26,0x99,0xC3,0x27,0x18,
883 0x6A,0xF4,0xE2,0x3C,0x1A,0x94,0x68,0x34,0xB6,0x15,0x0B,0xDA,
884 0x25,0x83,0xE9,0xCA,0x2A,0xD4,0x4C,0xE8,0xDB,0xBB,0xC2,0xDB,
885 0x04,0xDE,0x8E,0xF9,0x2E,0x8E,0xFC,0x14,0x1F,0xBE,0xCA,0xA6,
886 0x28,0x7C,0x59,0x47,0x4E,0x6B,0xC0,0x5D,0x99,0xB2,0x96,0x4F,
887 0xA0,0x90,0xC3,0xA2,0x23,0x3B,0xA1,0x86,0x51,0x5B,0xE7,0xED,
888 0x1F,0x61,0x29,0x70,0xCE,0xE2,0xD7,0xAF,0xB8,0x1B,0xDD,0x76,
889 0x21,0x70,0x48,0x1C,0xD0,0x06,0x91,0x27,0xD5,0xB0,0x5A,0xA9,
890 0x93,0xB4,0xEA,0x98,0x8D,0x8F,0xDD,0xC1,0x86,0xFF,0xB7,0xDC,
891 0x90,0xA6,0xC0,0x8F,0x4D,0xF4,0x35,0xC9,0x34,0x06,0x31,0x99,
892 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
893 };
894#endif
895 DH *dh = DH_new();
896 if (dh) {
Lukas Tribus4c0d45a2014-08-18 00:56:32 +0200897#if (OPENSSL_VERSION_NUMBER >= 0x0090801fL && !defined OPENSSL_IS_BORINGSSL)
Remi Gacognef46cd6e2014-06-12 14:58:40 +0200898 dh->p = get_rfc3526_prime_4096(NULL);
899#else
900 dh->p = BN_bin2bn(rfc_3526_prime_4096, sizeof rfc_3526_prime_4096, NULL);
901#endif
902 /* See RFC 3526, Section 5 "4096-bit MODP Group"
903 for the reason why 2 is used as generator.
904 */
905 BN_dec2bn(&dh->g, "2");
906 if (!dh->p || !dh->g) {
907 DH_free(dh);
908 dh = NULL;
909 }
910 }
911 return dh;
912}
913
914static DH *ssl_get_dh_8192(void)
915{
Lukas Tribus4c0d45a2014-08-18 00:56:32 +0200916#if (OPENSSL_VERSION_NUMBER < 0x0090801fL || defined OPENSSL_IS_BORINGSSL)
Remi Gacognef46cd6e2014-06-12 14:58:40 +0200917 static const unsigned char rfc_3526_prime_8192[] = {
918 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xC9,0x0F,0xDA,0xA2,
919 0x21,0x68,0xC2,0x34,0xC4,0xC6,0x62,0x8B,0x80,0xDC,0x1C,0xD1,
920 0x29,0x02,0x4E,0x08,0x8A,0x67,0xCC,0x74,0x02,0x0B,0xBE,0xA6,
921 0x3B,0x13,0x9B,0x22,0x51,0x4A,0x08,0x79,0x8E,0x34,0x04,0xDD,
922 0xEF,0x95,0x19,0xB3,0xCD,0x3A,0x43,0x1B,0x30,0x2B,0x0A,0x6D,
923 0xF2,0x5F,0x14,0x37,0x4F,0xE1,0x35,0x6D,0x6D,0x51,0xC2,0x45,
924 0xE4,0x85,0xB5,0x76,0x62,0x5E,0x7E,0xC6,0xF4,0x4C,0x42,0xE9,
925 0xA6,0x37,0xED,0x6B,0x0B,0xFF,0x5C,0xB6,0xF4,0x06,0xB7,0xED,
926 0xEE,0x38,0x6B,0xFB,0x5A,0x89,0x9F,0xA5,0xAE,0x9F,0x24,0x11,
927 0x7C,0x4B,0x1F,0xE6,0x49,0x28,0x66,0x51,0xEC,0xE4,0x5B,0x3D,
928 0xC2,0x00,0x7C,0xB8,0xA1,0x63,0xBF,0x05,0x98,0xDA,0x48,0x36,
929 0x1C,0x55,0xD3,0x9A,0x69,0x16,0x3F,0xA8,0xFD,0x24,0xCF,0x5F,
930 0x83,0x65,0x5D,0x23,0xDC,0xA3,0xAD,0x96,0x1C,0x62,0xF3,0x56,
931 0x20,0x85,0x52,0xBB,0x9E,0xD5,0x29,0x07,0x70,0x96,0x96,0x6D,
932 0x67,0x0C,0x35,0x4E,0x4A,0xBC,0x98,0x04,0xF1,0x74,0x6C,0x08,
933 0xCA,0x18,0x21,0x7C,0x32,0x90,0x5E,0x46,0x2E,0x36,0xCE,0x3B,
934 0xE3,0x9E,0x77,0x2C,0x18,0x0E,0x86,0x03,0x9B,0x27,0x83,0xA2,
935 0xEC,0x07,0xA2,0x8F,0xB5,0xC5,0x5D,0xF0,0x6F,0x4C,0x52,0xC9,
936 0xDE,0x2B,0xCB,0xF6,0x95,0x58,0x17,0x18,0x39,0x95,0x49,0x7C,
937 0xEA,0x95,0x6A,0xE5,0x15,0xD2,0x26,0x18,0x98,0xFA,0x05,0x10,
938 0x15,0x72,0x8E,0x5A,0x8A,0xAA,0xC4,0x2D,0xAD,0x33,0x17,0x0D,
939 0x04,0x50,0x7A,0x33,0xA8,0x55,0x21,0xAB,0xDF,0x1C,0xBA,0x64,
940 0xEC,0xFB,0x85,0x04,0x58,0xDB,0xEF,0x0A,0x8A,0xEA,0x71,0x57,
941 0x5D,0x06,0x0C,0x7D,0xB3,0x97,0x0F,0x85,0xA6,0xE1,0xE4,0xC7,
942 0xAB,0xF5,0xAE,0x8C,0xDB,0x09,0x33,0xD7,0x1E,0x8C,0x94,0xE0,
943 0x4A,0x25,0x61,0x9D,0xCE,0xE3,0xD2,0x26,0x1A,0xD2,0xEE,0x6B,
944 0xF1,0x2F,0xFA,0x06,0xD9,0x8A,0x08,0x64,0xD8,0x76,0x02,0x73,
945 0x3E,0xC8,0x6A,0x64,0x52,0x1F,0x2B,0x18,0x17,0x7B,0x20,0x0C,
946 0xBB,0xE1,0x17,0x57,0x7A,0x61,0x5D,0x6C,0x77,0x09,0x88,0xC0,
947 0xBA,0xD9,0x46,0xE2,0x08,0xE2,0x4F,0xA0,0x74,0xE5,0xAB,0x31,
948 0x43,0xDB,0x5B,0xFC,0xE0,0xFD,0x10,0x8E,0x4B,0x82,0xD1,0x20,
949 0xA9,0x21,0x08,0x01,0x1A,0x72,0x3C,0x12,0xA7,0x87,0xE6,0xD7,
950 0x88,0x71,0x9A,0x10,0xBD,0xBA,0x5B,0x26,0x99,0xC3,0x27,0x18,
951 0x6A,0xF4,0xE2,0x3C,0x1A,0x94,0x68,0x34,0xB6,0x15,0x0B,0xDA,
952 0x25,0x83,0xE9,0xCA,0x2A,0xD4,0x4C,0xE8,0xDB,0xBB,0xC2,0xDB,
953 0x04,0xDE,0x8E,0xF9,0x2E,0x8E,0xFC,0x14,0x1F,0xBE,0xCA,0xA6,
954 0x28,0x7C,0x59,0x47,0x4E,0x6B,0xC0,0x5D,0x99,0xB2,0x96,0x4F,
955 0xA0,0x90,0xC3,0xA2,0x23,0x3B,0xA1,0x86,0x51,0x5B,0xE7,0xED,
956 0x1F,0x61,0x29,0x70,0xCE,0xE2,0xD7,0xAF,0xB8,0x1B,0xDD,0x76,
957 0x21,0x70,0x48,0x1C,0xD0,0x06,0x91,0x27,0xD5,0xB0,0x5A,0xA9,
958 0x93,0xB4,0xEA,0x98,0x8D,0x8F,0xDD,0xC1,0x86,0xFF,0xB7,0xDC,
959 0x90,0xA6,0xC0,0x8F,0x4D,0xF4,0x35,0xC9,0x34,0x02,0x84,0x92,
960 0x36,0xC3,0xFA,0xB4,0xD2,0x7C,0x70,0x26,0xC1,0xD4,0xDC,0xB2,
961 0x60,0x26,0x46,0xDE,0xC9,0x75,0x1E,0x76,0x3D,0xBA,0x37,0xBD,
962 0xF8,0xFF,0x94,0x06,0xAD,0x9E,0x53,0x0E,0xE5,0xDB,0x38,0x2F,
963 0x41,0x30,0x01,0xAE,0xB0,0x6A,0x53,0xED,0x90,0x27,0xD8,0x31,
964 0x17,0x97,0x27,0xB0,0x86,0x5A,0x89,0x18,0xDA,0x3E,0xDB,0xEB,
965 0xCF,0x9B,0x14,0xED,0x44,0xCE,0x6C,0xBA,0xCE,0xD4,0xBB,0x1B,
966 0xDB,0x7F,0x14,0x47,0xE6,0xCC,0x25,0x4B,0x33,0x20,0x51,0x51,
967 0x2B,0xD7,0xAF,0x42,0x6F,0xB8,0xF4,0x01,0x37,0x8C,0xD2,0xBF,
968 0x59,0x83,0xCA,0x01,0xC6,0x4B,0x92,0xEC,0xF0,0x32,0xEA,0x15,
969 0xD1,0x72,0x1D,0x03,0xF4,0x82,0xD7,0xCE,0x6E,0x74,0xFE,0xF6,
970 0xD5,0x5E,0x70,0x2F,0x46,0x98,0x0C,0x82,0xB5,0xA8,0x40,0x31,
971 0x90,0x0B,0x1C,0x9E,0x59,0xE7,0xC9,0x7F,0xBE,0xC7,0xE8,0xF3,
972 0x23,0xA9,0x7A,0x7E,0x36,0xCC,0x88,0xBE,0x0F,0x1D,0x45,0xB7,
973 0xFF,0x58,0x5A,0xC5,0x4B,0xD4,0x07,0xB2,0x2B,0x41,0x54,0xAA,
974 0xCC,0x8F,0x6D,0x7E,0xBF,0x48,0xE1,0xD8,0x14,0xCC,0x5E,0xD2,
975 0x0F,0x80,0x37,0xE0,0xA7,0x97,0x15,0xEE,0xF2,0x9B,0xE3,0x28,
976 0x06,0xA1,0xD5,0x8B,0xB7,0xC5,0xDA,0x76,0xF5,0x50,0xAA,0x3D,
977 0x8A,0x1F,0xBF,0xF0,0xEB,0x19,0xCC,0xB1,0xA3,0x13,0xD5,0x5C,
978 0xDA,0x56,0xC9,0xEC,0x2E,0xF2,0x96,0x32,0x38,0x7F,0xE8,0xD7,
979 0x6E,0x3C,0x04,0x68,0x04,0x3E,0x8F,0x66,0x3F,0x48,0x60,0xEE,
980 0x12,0xBF,0x2D,0x5B,0x0B,0x74,0x74,0xD6,0xE6,0x94,0xF9,0x1E,
981 0x6D,0xBE,0x11,0x59,0x74,0xA3,0x92,0x6F,0x12,0xFE,0xE5,0xE4,
982 0x38,0x77,0x7C,0xB6,0xA9,0x32,0xDF,0x8C,0xD8,0xBE,0xC4,0xD0,
983 0x73,0xB9,0x31,0xBA,0x3B,0xC8,0x32,0xB6,0x8D,0x9D,0xD3,0x00,
984 0x74,0x1F,0xA7,0xBF,0x8A,0xFC,0x47,0xED,0x25,0x76,0xF6,0x93,
985 0x6B,0xA4,0x24,0x66,0x3A,0xAB,0x63,0x9C,0x5A,0xE4,0xF5,0x68,
986 0x34,0x23,0xB4,0x74,0x2B,0xF1,0xC9,0x78,0x23,0x8F,0x16,0xCB,
987 0xE3,0x9D,0x65,0x2D,0xE3,0xFD,0xB8,0xBE,0xFC,0x84,0x8A,0xD9,
988 0x22,0x22,0x2E,0x04,0xA4,0x03,0x7C,0x07,0x13,0xEB,0x57,0xA8,
989 0x1A,0x23,0xF0,0xC7,0x34,0x73,0xFC,0x64,0x6C,0xEA,0x30,0x6B,
990 0x4B,0xCB,0xC8,0x86,0x2F,0x83,0x85,0xDD,0xFA,0x9D,0x4B,0x7F,
991 0xA2,0xC0,0x87,0xE8,0x79,0x68,0x33,0x03,0xED,0x5B,0xDD,0x3A,
992 0x06,0x2B,0x3C,0xF5,0xB3,0xA2,0x78,0xA6,0x6D,0x2A,0x13,0xF8,
993 0x3F,0x44,0xF8,0x2D,0xDF,0x31,0x0E,0xE0,0x74,0xAB,0x6A,0x36,
994 0x45,0x97,0xE8,0x99,0xA0,0x25,0x5D,0xC1,0x64,0xF3,0x1C,0xC5,
995 0x08,0x46,0x85,0x1D,0xF9,0xAB,0x48,0x19,0x5D,0xED,0x7E,0xA1,
996 0xB1,0xD5,0x10,0xBD,0x7E,0xE7,0x4D,0x73,0xFA,0xF3,0x6B,0xC3,
997 0x1E,0xCF,0xA2,0x68,0x35,0x90,0x46,0xF4,0xEB,0x87,0x9F,0x92,
998 0x40,0x09,0x43,0x8B,0x48,0x1C,0x6C,0xD7,0x88,0x9A,0x00,0x2E,
999 0xD5,0xEE,0x38,0x2B,0xC9,0x19,0x0D,0xA6,0xFC,0x02,0x6E,0x47,
1000 0x95,0x58,0xE4,0x47,0x56,0x77,0xE9,0xAA,0x9E,0x30,0x50,0xE2,
1001 0x76,0x56,0x94,0xDF,0xC8,0x1F,0x56,0xE8,0x80,0xB9,0x6E,0x71,
1002 0x60,0xC9,0x80,0xDD,0x98,0xED,0xD3,0xDF,0xFF,0xFF,0xFF,0xFF,
1003 0xFF,0xFF,0xFF,0xFF,
1004 };
1005#endif
1006 DH *dh = DH_new();
1007 if (dh) {
Lukas Tribus4c0d45a2014-08-18 00:56:32 +02001008#if (OPENSSL_VERSION_NUMBER >= 0x0090801fL && !defined OPENSSL_IS_BORINGSSL)
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001009 dh->p = get_rfc3526_prime_8192(NULL);
1010#else
1011 dh->p = BN_bin2bn(rfc_3526_prime_8192, sizeof rfc_3526_prime_8192, NULL);
1012#endif
1013 /* See RFC 3526, Section 7 "8192-bit MODP Group"
1014 for the reason why 2 is used as generator.
1015 */
1016 BN_dec2bn(&dh->g, "2");
1017 if (!dh->p || !dh->g) {
1018 DH_free(dh);
1019 dh = NULL;
1020 }
1021 }
1022 return dh;
1023}
1024
1025/* Returns Diffie-Hellman parameters matching the private key length
1026 but not exceeding global.tune.ssl_default_dh_param */
1027static DH *ssl_get_tmp_dh(SSL *ssl, int export, int keylen)
1028{
1029 DH *dh = NULL;
1030 EVP_PKEY *pkey = SSL_get_privatekey(ssl);
1031 int type = pkey ? EVP_PKEY_type(pkey->type) : EVP_PKEY_NONE;
1032
1033 /* The keylen supplied by OpenSSL can only be 512 or 1024.
1034 See ssl3_send_server_key_exchange() in ssl/s3_srvr.c
1035 */
1036 if (type == EVP_PKEY_RSA || type == EVP_PKEY_DSA) {
1037 keylen = EVP_PKEY_bits(pkey);
1038 }
1039
1040 if (keylen > global.tune.ssl_default_dh_param) {
1041 keylen = global.tune.ssl_default_dh_param;
1042 }
1043
1044 if (keylen >= 8192) {
Remi Gacogne8de54152014-07-15 11:36:40 +02001045 dh = local_dh_8192;
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001046 }
1047 else if (keylen >= 4096) {
Remi Gacogne8de54152014-07-15 11:36:40 +02001048 dh = local_dh_4096;
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001049 }
1050 else if (keylen >= 2048) {
Remi Gacogne8de54152014-07-15 11:36:40 +02001051 dh = local_dh_2048;
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001052 }
1053 else {
Remi Gacogne8de54152014-07-15 11:36:40 +02001054 dh = local_dh_1024;
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001055 }
1056
1057 return dh;
1058}
1059
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001060/* Loads Diffie-Hellman parameter from a file. Returns 1 if loaded, else -1
1061 if an error occured, and 0 if parameter not found. */
Willy Tarreau6e774b42014-04-25 21:35:23 +02001062int ssl_sock_load_dh_params(SSL_CTX *ctx, const char *file)
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001063{
1064 int ret = -1;
1065 BIO *in;
1066 DH *dh = NULL;
1067
1068 in = BIO_new(BIO_s_file());
1069 if (in == NULL)
1070 goto end;
1071
1072 if (BIO_read_filename(in, file) <= 0)
1073 goto end;
1074
1075 dh = PEM_read_bio_DHparams(in, NULL, ctx->default_passwd_callback, ctx->default_passwd_callback_userdata);
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001076 if (dh) {
1077 ret = 1;
1078 SSL_CTX_set_tmp_dh(ctx, dh);
1079 /* Setting ssl default dh param to the size of the static DH params
1080 found in the file. This way we know that there is no use
1081 complaining later about ssl-default-dh-param not being set. */
1082 global.tune.ssl_default_dh_param = DH_size(dh) * 8;
1083 }
1084 else {
Emeric Brun41fdb3c2013-04-26 11:05:44 +02001085 /* Clear openssl global errors stack */
1086 ERR_clear_error();
1087
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001088 if (global.tune.ssl_default_dh_param <= 1024) {
1089 /* we are limited to DH parameter of 1024 bits anyway */
Remi Gacogne8de54152014-07-15 11:36:40 +02001090 local_dh_1024 = ssl_get_dh_1024();
1091 if (local_dh_1024 == NULL)
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001092 goto end;
Willy Tarreau6e774b42014-04-25 21:35:23 +02001093
Remi Gacogne8de54152014-07-15 11:36:40 +02001094 SSL_CTX_set_tmp_dh(ctx, local_dh_1024);
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001095 }
1096 else {
1097 SSL_CTX_set_tmp_dh_callback(ctx, ssl_get_tmp_dh);
1098 }
Willy Tarreau6e774b42014-04-25 21:35:23 +02001099
Emeric Brun41fdb3c2013-04-26 11:05:44 +02001100 ret = 0; /* DH params not found */
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001101 }
Emeric Brun644cde02012-12-14 11:21:13 +01001102
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001103end:
1104 if (dh)
1105 DH_free(dh);
1106
1107 if (in)
Emeric Brun41fdb3c2013-04-26 11:05:44 +02001108 BIO_free(in);
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001109
1110 return ret;
1111}
1112#endif
1113
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001114static int ssl_sock_add_cert_sni(SSL_CTX *ctx, struct bind_conf *s, char *name, int order)
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001115{
1116 struct sni_ctx *sc;
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001117 int wild = 0, neg = 0;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001118
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001119 if (*name == '!') {
1120 neg = 1;
1121 name++;
1122 }
1123 if (*name == '*') {
1124 wild = 1;
1125 name++;
1126 }
1127 /* !* filter is a nop */
1128 if (neg && wild)
1129 return order;
1130 if (*name) {
1131 int j, len;
1132 len = strlen(name);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001133 sc = malloc(sizeof(struct sni_ctx) + len + 1);
1134 for (j = 0; j < len; j++)
1135 sc->name.key[j] = tolower(name[j]);
1136 sc->name.key[len] = 0;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001137 sc->ctx = ctx;
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001138 sc->order = order++;
1139 sc->neg = neg;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001140 if (wild)
1141 ebst_insert(&s->sni_w_ctx, &sc->name);
1142 else
1143 ebst_insert(&s->sni_ctx, &sc->name);
1144 }
1145 return order;
1146}
1147
Emeric Brunfc0421f2012-09-07 17:30:07 +02001148/* Loads a certificate key and CA chain from a file. Returns 0 on error, -1 if
1149 * an early error happens and the caller must call SSL_CTX_free() by itelf.
1150 */
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001151static 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 +02001152{
1153 BIO *in;
1154 X509 *x = NULL, *ca;
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001155 int i, err;
Emeric Brunfc0421f2012-09-07 17:30:07 +02001156 int ret = -1;
1157 int order = 0;
1158 X509_NAME *xname;
1159 char *str;
Emeric Brunfc0421f2012-09-07 17:30:07 +02001160#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
1161 STACK_OF(GENERAL_NAME) *names;
1162#endif
1163
1164 in = BIO_new(BIO_s_file());
1165 if (in == NULL)
1166 goto end;
1167
1168 if (BIO_read_filename(in, file) <= 0)
1169 goto end;
1170
1171 x = PEM_read_bio_X509_AUX(in, NULL, ctx->default_passwd_callback, ctx->default_passwd_callback_userdata);
1172 if (x == NULL)
1173 goto end;
1174
Emeric Brun50bcecc2013-04-22 13:05:23 +02001175 if (fcount) {
1176 while (fcount--)
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001177 order = ssl_sock_add_cert_sni(ctx, s, sni_filter[fcount], order);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001178 }
1179 else {
Emeric Brunfc0421f2012-09-07 17:30:07 +02001180#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001181 names = X509_get_ext_d2i(x, NID_subject_alt_name, NULL, NULL);
1182 if (names) {
1183 for (i = 0; i < sk_GENERAL_NAME_num(names); i++) {
1184 GENERAL_NAME *name = sk_GENERAL_NAME_value(names, i);
1185 if (name->type == GEN_DNS) {
1186 if (ASN1_STRING_to_UTF8((unsigned char **)&str, name->d.dNSName) >= 0) {
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001187 order = ssl_sock_add_cert_sni(ctx, s, str, order);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001188 OPENSSL_free(str);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001189 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02001190 }
1191 }
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001192 sk_GENERAL_NAME_pop_free(names, GENERAL_NAME_free);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001193 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02001194#endif /* SSL_CTRL_SET_TLSEXT_HOSTNAME */
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001195 xname = X509_get_subject_name(x);
1196 i = -1;
1197 while ((i = X509_NAME_get_index_by_NID(xname, NID_commonName, i)) != -1) {
1198 X509_NAME_ENTRY *entry = X509_NAME_get_entry(xname, i);
1199 if (ASN1_STRING_to_UTF8((unsigned char **)&str, entry->value) >= 0) {
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001200 order = ssl_sock_add_cert_sni(ctx, s, str, order);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001201 OPENSSL_free(str);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001202 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02001203 }
1204 }
1205
1206 ret = 0; /* the caller must not free the SSL_CTX argument anymore */
1207 if (!SSL_CTX_use_certificate(ctx, x))
1208 goto end;
1209
1210 if (ctx->extra_certs != NULL) {
1211 sk_X509_pop_free(ctx->extra_certs, X509_free);
1212 ctx->extra_certs = NULL;
1213 }
1214
1215 while ((ca = PEM_read_bio_X509(in, NULL, ctx->default_passwd_callback, ctx->default_passwd_callback_userdata))) {
1216 if (!SSL_CTX_add_extra_chain_cert(ctx, ca)) {
1217 X509_free(ca);
1218 goto end;
1219 }
1220 }
1221
1222 err = ERR_get_error();
1223 if (!err || (ERR_GET_LIB(err) == ERR_LIB_PEM && ERR_GET_REASON(err) == PEM_R_NO_START_LINE)) {
1224 /* we successfully reached the last cert in the file */
1225 ret = 1;
1226 }
1227 ERR_clear_error();
1228
1229end:
1230 if (x)
1231 X509_free(x);
1232
1233 if (in)
1234 BIO_free(in);
1235
1236 return ret;
1237}
1238
Emeric Brun50bcecc2013-04-22 13:05:23 +02001239static 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 +02001240{
1241 int ret;
1242 SSL_CTX *ctx;
1243
1244 ctx = SSL_CTX_new(SSLv23_server_method());
1245 if (!ctx) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02001246 memprintf(err, "%sunable to allocate SSL context for cert '%s'.\n",
1247 err && *err ? *err : "", path);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001248 return 1;
1249 }
1250
1251 if (SSL_CTX_use_PrivateKey_file(ctx, path, SSL_FILETYPE_PEM) <= 0) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02001252 memprintf(err, "%sunable to load SSL private key from PEM file '%s'.\n",
1253 err && *err ? *err : "", path);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001254 SSL_CTX_free(ctx);
1255 return 1;
1256 }
1257
Emeric Brun50bcecc2013-04-22 13:05:23 +02001258 ret = ssl_sock_load_cert_chain_file(ctx, path, bind_conf, sni_filter, fcount);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001259 if (ret <= 0) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02001260 memprintf(err, "%sunable to load SSL certificate from PEM file '%s'.\n",
1261 err && *err ? *err : "", path);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001262 if (ret < 0) /* serious error, must do that ourselves */
1263 SSL_CTX_free(ctx);
1264 return 1;
1265 }
Emeric Brun61694ab2012-10-26 13:35:33 +02001266
1267 if (SSL_CTX_check_private_key(ctx) <= 0) {
1268 memprintf(err, "%sinconsistencies between private key and certificate loaded from PEM file '%s'.\n",
1269 err && *err ? *err : "", path);
1270 return 1;
1271 }
1272
Emeric Brunfc0421f2012-09-07 17:30:07 +02001273 /* we must not free the SSL_CTX anymore below, since it's already in
1274 * the tree, so it will be discovered and cleaned in time.
1275 */
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001276#ifndef OPENSSL_NO_DH
1277 ret = ssl_sock_load_dh_params(ctx, path);
1278 if (ret < 0) {
1279 if (err)
1280 memprintf(err, "%sunable to load DH parameters from file '%s'.\n",
1281 *err ? *err : "", path);
1282 return 1;
1283 }
1284#endif
1285
Lukas Tribuse4e30f72014-12-09 16:32:51 +01001286#if (defined SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB && !defined OPENSSL_NO_OCSP)
Emeric Brun4147b2e2014-06-16 18:36:30 +02001287 ret = ssl_sock_load_ocsp(ctx, path);
1288 if (ret < 0) {
1289 if (err)
1290 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",
1291 *err ? *err : "", path);
1292 return 1;
1293 }
1294#endif
1295
Emeric Brunfc0421f2012-09-07 17:30:07 +02001296#ifndef SSL_CTRL_SET_TLSEXT_HOSTNAME
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001297 if (bind_conf->default_ctx) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02001298 memprintf(err, "%sthis version of openssl cannot load multiple SSL certificates.\n",
1299 err && *err ? *err : "");
Emeric Brunfc0421f2012-09-07 17:30:07 +02001300 return 1;
1301 }
1302#endif
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001303 if (!bind_conf->default_ctx)
1304 bind_conf->default_ctx = ctx;
Emeric Brunfc0421f2012-09-07 17:30:07 +02001305
1306 return 0;
1307}
1308
Willy Tarreau79eeafa2012-09-14 07:53:05 +02001309int ssl_sock_load_cert(char *path, struct bind_conf *bind_conf, struct proxy *curproxy, char **err)
Emeric Brunfc0421f2012-09-07 17:30:07 +02001310{
1311 struct dirent *de;
1312 DIR *dir;
1313 struct stat buf;
Willy Tarreauee2663b2012-12-06 11:36:59 +01001314 char *end;
1315 char fp[MAXPATHLEN+1];
Emeric Brunfc0421f2012-09-07 17:30:07 +02001316 int cfgerr = 0;
1317
1318 if (!(dir = opendir(path)))
Emeric Brun50bcecc2013-04-22 13:05:23 +02001319 return ssl_sock_load_cert_file(path, bind_conf, curproxy, NULL, 0, err);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001320
1321 /* strip trailing slashes, including first one */
1322 for (end = path + strlen(path) - 1; end >= path && *end == '/'; end--)
1323 *end = 0;
1324
Emeric Brunfc0421f2012-09-07 17:30:07 +02001325 while ((de = readdir(dir))) {
Emeric Brun2aab7222014-06-18 18:15:09 +02001326 end = strrchr(de->d_name, '.');
1327 if (end && (!strcmp(end, ".issuer") || !strcmp(end, ".ocsp")))
1328 continue;
1329
Willy Tarreauee2663b2012-12-06 11:36:59 +01001330 snprintf(fp, sizeof(fp), "%s/%s", path, de->d_name);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001331 if (stat(fp, &buf) != 0) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02001332 memprintf(err, "%sunable to stat SSL certificate from file '%s' : %s.\n",
1333 err && *err ? *err : "", fp, strerror(errno));
Emeric Brunfc0421f2012-09-07 17:30:07 +02001334 cfgerr++;
1335 continue;
1336 }
1337 if (!S_ISREG(buf.st_mode))
1338 continue;
Emeric Brun50bcecc2013-04-22 13:05:23 +02001339 cfgerr += ssl_sock_load_cert_file(fp, bind_conf, curproxy, NULL, 0, err);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001340 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02001341 closedir(dir);
1342 return cfgerr;
1343}
1344
Thierry Fournier383085f2013-01-24 14:15:43 +01001345/* Make sure openssl opens /dev/urandom before the chroot. The work is only
1346 * done once. Zero is returned if the operation fails. No error is returned
1347 * if the random is said as not implemented, because we expect that openssl
1348 * will use another method once needed.
1349 */
1350static int ssl_initialize_random()
1351{
1352 unsigned char random;
1353 static int random_initialized = 0;
1354
1355 if (!random_initialized && RAND_bytes(&random, 1) != 0)
1356 random_initialized = 1;
1357
1358 return random_initialized;
1359}
1360
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001361int ssl_sock_load_cert_list_file(char *file, struct bind_conf *bind_conf, struct proxy *curproxy, char **err)
1362{
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001363 char thisline[LINESIZE];
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001364 FILE *f;
1365 int linenum = 0;
1366 int cfgerr = 0;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001367
Willy Tarreauad1731d2013-04-02 17:35:58 +02001368 if ((f = fopen(file, "r")) == NULL) {
1369 memprintf(err, "cannot open file '%s' : %s", file, strerror(errno));
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001370 return 1;
Willy Tarreauad1731d2013-04-02 17:35:58 +02001371 }
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001372
1373 while (fgets(thisline, sizeof(thisline), f) != NULL) {
1374 int arg;
Emeric Brun50bcecc2013-04-22 13:05:23 +02001375 int newarg;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001376 char *end;
1377 char *args[MAX_LINE_ARGS + 1];
1378 char *line = thisline;
1379
1380 linenum++;
1381 end = line + strlen(line);
1382 if (end-line == sizeof(thisline)-1 && *(end-1) != '\n') {
1383 /* Check if we reached the limit and the last char is not \n.
1384 * Watch out for the last line without the terminating '\n'!
1385 */
Willy Tarreauad1731d2013-04-02 17:35:58 +02001386 memprintf(err, "line %d too long in file '%s', limit is %d characters",
1387 linenum, file, (int)sizeof(thisline)-1);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001388 cfgerr = 1;
Willy Tarreauad1731d2013-04-02 17:35:58 +02001389 break;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001390 }
1391
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001392 arg = 0;
Emeric Brun50bcecc2013-04-22 13:05:23 +02001393 newarg = 1;
1394 while (*line) {
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001395 if (*line == '#' || *line == '\n' || *line == '\r') {
1396 /* end of string, end of loop */
1397 *line = 0;
1398 break;
1399 }
1400 else if (isspace(*line)) {
Emeric Brun50bcecc2013-04-22 13:05:23 +02001401 newarg = 1;
1402 *line = 0;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001403 }
Emeric Brun50bcecc2013-04-22 13:05:23 +02001404 else if (newarg) {
1405 if (arg == MAX_LINE_ARGS) {
1406 memprintf(err, "too many args on line %d in file '%s'.",
1407 linenum, file);
1408 cfgerr = 1;
1409 break;
1410 }
1411 newarg = 0;
1412 args[arg++] = line;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001413 }
Emeric Brun50bcecc2013-04-22 13:05:23 +02001414 line++;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001415 }
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001416 if (cfgerr)
1417 break;
Willy Tarreauad1731d2013-04-02 17:35:58 +02001418
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001419 /* empty line */
Emeric Brun50bcecc2013-04-22 13:05:23 +02001420 if (!arg)
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001421 continue;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001422
Emeric Brun50bcecc2013-04-22 13:05:23 +02001423 cfgerr = ssl_sock_load_cert_file(args[0], bind_conf, curproxy, &args[1], arg-1, err);
Willy Tarreauad1731d2013-04-02 17:35:58 +02001424 if (cfgerr) {
1425 memprintf(err, "error processing line %d in file '%s' : %s", linenum, file, *err);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001426 break;
Willy Tarreauad1731d2013-04-02 17:35:58 +02001427 }
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001428 }
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001429 fclose(f);
1430 return cfgerr;
1431}
1432
Emeric Brunfc0421f2012-09-07 17:30:07 +02001433#ifndef SSL_OP_CIPHER_SERVER_PREFERENCE /* needs OpenSSL >= 0.9.7 */
1434#define SSL_OP_CIPHER_SERVER_PREFERENCE 0
1435#endif
1436
1437#ifndef SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION /* needs OpenSSL >= 0.9.7 */
1438#define SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION 0
Willy Tarreau7d588ee2012-11-26 18:47:31 +01001439#define SSL_renegotiate_pending(arg) 0
Emeric Brunfc0421f2012-09-07 17:30:07 +02001440#endif
Emeric Brun2b58d042012-09-20 17:10:03 +02001441#ifndef SSL_OP_SINGLE_ECDH_USE /* needs OpenSSL >= 0.9.8 */
1442#define SSL_OP_SINGLE_ECDH_USE 0
1443#endif
Emeric Brun2d0c4822012-10-02 13:45:20 +02001444#ifndef SSL_OP_NO_TICKET /* needs OpenSSL >= 0.9.8 */
1445#define SSL_OP_NO_TICKET 0
1446#endif
Emeric Brunfc0421f2012-09-07 17:30:07 +02001447#ifndef SSL_OP_NO_COMPRESSION /* needs OpenSSL >= 0.9.9 */
1448#define SSL_OP_NO_COMPRESSION 0
1449#endif
Emeric Brunc0ff4922012-09-28 19:37:02 +02001450#ifndef SSL_OP_NO_TLSv1_1 /* needs OpenSSL >= 1.0.1 */
1451#define SSL_OP_NO_TLSv1_1 0
1452#endif
1453#ifndef SSL_OP_NO_TLSv1_2 /* needs OpenSSL >= 1.0.1 */
1454#define SSL_OP_NO_TLSv1_2 0
1455#endif
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001456#ifndef SSL_OP_SINGLE_DH_USE /* needs OpenSSL >= 0.9.6 */
1457#define SSL_OP_SINGLE_DH_USE 0
1458#endif
Emeric Brun2b58d042012-09-20 17:10:03 +02001459#ifndef SSL_OP_SINGLE_ECDH_USE /* needs OpenSSL >= 1.0.0 */
1460#define SSL_OP_SINGLE_ECDH_USE 0
1461#endif
Emeric Brunfc0421f2012-09-07 17:30:07 +02001462#ifndef SSL_MODE_RELEASE_BUFFERS /* needs OpenSSL >= 1.0.0 */
1463#define SSL_MODE_RELEASE_BUFFERS 0
1464#endif
Willy Tarreau396a1862014-11-13 14:06:52 +01001465#ifndef SSL_MODE_SMALL_BUFFERS /* needs small_records.patch */
1466#define SSL_MODE_SMALL_BUFFERS 0
1467#endif
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001468
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001469int ssl_sock_prepare_ctx(struct bind_conf *bind_conf, SSL_CTX *ctx, struct proxy *curproxy)
Emeric Brunfc0421f2012-09-07 17:30:07 +02001470{
1471 int cfgerr = 0;
Emeric Brun850efd52014-01-29 12:24:34 +01001472 int verify = SSL_VERIFY_NONE;
Remi Gacogneaf5c3da2014-05-19 10:29:58 +02001473 long ssloptions =
Emeric Brunfc0421f2012-09-07 17:30:07 +02001474 SSL_OP_ALL | /* all known workarounds for bugs */
1475 SSL_OP_NO_SSLv2 |
1476 SSL_OP_NO_COMPRESSION |
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001477 SSL_OP_SINGLE_DH_USE |
Emeric Brun2b58d042012-09-20 17:10:03 +02001478 SSL_OP_SINGLE_ECDH_USE |
Emeric Brun3c4bc6e2012-10-04 18:44:19 +02001479 SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION |
1480 SSL_OP_CIPHER_SERVER_PREFERENCE;
Remi Gacogneaf5c3da2014-05-19 10:29:58 +02001481 long sslmode =
Emeric Brunfc0421f2012-09-07 17:30:07 +02001482 SSL_MODE_ENABLE_PARTIAL_WRITE |
1483 SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER |
Willy Tarreau396a1862014-11-13 14:06:52 +01001484 SSL_MODE_RELEASE_BUFFERS |
1485 SSL_MODE_SMALL_BUFFERS;
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001486 STACK_OF(SSL_CIPHER) * ciphers = NULL;
Willy Tarreaua616ba62014-10-26 06:49:19 +01001487 SSL_CIPHER * cipher = NULL;
Remi Gacognec1eab8c2014-06-12 18:20:11 +02001488 char cipher_description[128];
1489 /* The description of ciphers using an Ephemeral Diffie Hellman key exchange
1490 contains " Kx=DH " or " Kx=DH(". Beware of " Kx=DH/",
1491 which is not ephemeral DH. */
1492 const char dhe_description[] = " Kx=DH ";
1493 const char dhe_export_description[] = " Kx=DH(";
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001494 int idx = 0;
1495 int dhe_found = 0;
Remi Gacogne23d5d372014-10-10 17:04:26 +02001496 SSL *ssl = NULL;
Emeric Brunfc0421f2012-09-07 17:30:07 +02001497
Thierry Fournier383085f2013-01-24 14:15:43 +01001498 /* Make sure openssl opens /dev/urandom before the chroot */
1499 if (!ssl_initialize_random()) {
1500 Alert("OpenSSL random data generator initialization failed.\n");
1501 cfgerr++;
1502 }
1503
Emeric Brun89675492012-10-05 13:48:26 +02001504 if (bind_conf->ssl_options & BC_SSL_O_NO_SSLV3)
Emeric Brunfc0421f2012-09-07 17:30:07 +02001505 ssloptions |= SSL_OP_NO_SSLv3;
Emeric Brun89675492012-10-05 13:48:26 +02001506 if (bind_conf->ssl_options & BC_SSL_O_NO_TLSV10)
Emeric Brunfc0421f2012-09-07 17:30:07 +02001507 ssloptions |= SSL_OP_NO_TLSv1;
Emeric Brun89675492012-10-05 13:48:26 +02001508 if (bind_conf->ssl_options & BC_SSL_O_NO_TLSV11)
Emeric Brunc0ff4922012-09-28 19:37:02 +02001509 ssloptions |= SSL_OP_NO_TLSv1_1;
Emeric Brun89675492012-10-05 13:48:26 +02001510 if (bind_conf->ssl_options & BC_SSL_O_NO_TLSV12)
Emeric Brunc0ff4922012-09-28 19:37:02 +02001511 ssloptions |= SSL_OP_NO_TLSv1_2;
Emeric Brun89675492012-10-05 13:48:26 +02001512 if (bind_conf->ssl_options & BC_SSL_O_NO_TLS_TICKETS)
Emeric Brun2d0c4822012-10-02 13:45:20 +02001513 ssloptions |= SSL_OP_NO_TICKET;
Emeric Brun2cb7ae52012-10-05 14:14:21 +02001514 if (bind_conf->ssl_options & BC_SSL_O_USE_SSLV3)
1515 SSL_CTX_set_ssl_version(ctx, SSLv3_server_method());
1516 if (bind_conf->ssl_options & BC_SSL_O_USE_TLSV10)
1517 SSL_CTX_set_ssl_version(ctx, TLSv1_server_method());
1518#if SSL_OP_NO_TLSv1_1
1519 if (bind_conf->ssl_options & BC_SSL_O_USE_TLSV11)
1520 SSL_CTX_set_ssl_version(ctx, TLSv1_1_server_method());
1521#endif
1522#if SSL_OP_NO_TLSv1_2
1523 if (bind_conf->ssl_options & BC_SSL_O_USE_TLSV12)
1524 SSL_CTX_set_ssl_version(ctx, TLSv1_2_server_method());
1525#endif
Emeric Brunfc0421f2012-09-07 17:30:07 +02001526
1527 SSL_CTX_set_options(ctx, ssloptions);
1528 SSL_CTX_set_mode(ctx, sslmode);
Emeric Brun850efd52014-01-29 12:24:34 +01001529 switch (bind_conf->verify) {
1530 case SSL_SOCK_VERIFY_NONE:
1531 verify = SSL_VERIFY_NONE;
1532 break;
1533 case SSL_SOCK_VERIFY_OPTIONAL:
1534 verify = SSL_VERIFY_PEER;
1535 break;
1536 case SSL_SOCK_VERIFY_REQUIRED:
1537 verify = SSL_VERIFY_PEER|SSL_VERIFY_FAIL_IF_NO_PEER_CERT;
1538 break;
1539 }
1540 SSL_CTX_set_verify(ctx, verify, ssl_sock_bind_verifycbk);
1541 if (verify & SSL_VERIFY_PEER) {
Emeric Brunfb510ea2012-10-05 12:00:26 +02001542 if (bind_conf->ca_file) {
Emeric Brund94b3fe2012-09-20 18:23:56 +02001543 /* load CAfile to verify */
Emeric Brunfb510ea2012-10-05 12:00:26 +02001544 if (!SSL_CTX_load_verify_locations(ctx, bind_conf->ca_file, NULL)) {
Emeric Brund94b3fe2012-09-20 18:23:56 +02001545 Alert("Proxy '%s': unable to load CA file '%s' for bind '%s' at [%s:%d].\n",
Emeric Brunfb510ea2012-10-05 12:00:26 +02001546 curproxy->id, bind_conf->ca_file, bind_conf->arg, bind_conf->file, bind_conf->line);
Emeric Brund94b3fe2012-09-20 18:23:56 +02001547 cfgerr++;
1548 }
1549 /* set CA names fo client cert request, function returns void */
Emeric Brunfb510ea2012-10-05 12:00:26 +02001550 SSL_CTX_set_client_CA_list(ctx, SSL_load_client_CA_file(bind_conf->ca_file));
Emeric Brund94b3fe2012-09-20 18:23:56 +02001551 }
Emeric Brun850efd52014-01-29 12:24:34 +01001552 else {
1553 Alert("Proxy '%s': verify is enabled but no CA file specified for bind '%s' at [%s:%d].\n",
1554 curproxy->id, bind_conf->arg, bind_conf->file, bind_conf->line);
1555 cfgerr++;
1556 }
Emeric Brun051cdab2012-10-02 19:25:50 +02001557#ifdef X509_V_FLAG_CRL_CHECK
Emeric Brunfb510ea2012-10-05 12:00:26 +02001558 if (bind_conf->crl_file) {
Emeric Brund94b3fe2012-09-20 18:23:56 +02001559 X509_STORE *store = SSL_CTX_get_cert_store(ctx);
1560
Emeric Brunfb510ea2012-10-05 12:00:26 +02001561 if (!store || !X509_STORE_load_locations(store, bind_conf->crl_file, NULL)) {
Emeric Brund94b3fe2012-09-20 18:23:56 +02001562 Alert("Proxy '%s': unable to configure CRL file '%s' for bind '%s' at [%s:%d].\n",
Emeric Brunfb510ea2012-10-05 12:00:26 +02001563 curproxy->id, bind_conf->ca_file, bind_conf->arg, bind_conf->file, bind_conf->line);
Emeric Brund94b3fe2012-09-20 18:23:56 +02001564 cfgerr++;
1565 }
Emeric Brun561e5742012-10-02 15:20:55 +02001566 else {
1567 X509_STORE_set_flags(store, X509_V_FLAG_CRL_CHECK|X509_V_FLAG_CRL_CHECK_ALL);
1568 }
Emeric Brund94b3fe2012-09-20 18:23:56 +02001569 }
Emeric Brun051cdab2012-10-02 19:25:50 +02001570#endif
Emeric Brun644cde02012-12-14 11:21:13 +01001571 ERR_clear_error();
Emeric Brund94b3fe2012-09-20 18:23:56 +02001572 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02001573
Emeric Brun4f65bff2012-11-16 15:11:00 +01001574 if (global.tune.ssllifetime)
1575 SSL_CTX_set_timeout(ctx, global.tune.ssllifetime);
1576
Emeric Brunfc0421f2012-09-07 17:30:07 +02001577 shared_context_set_cache(ctx);
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001578 if (bind_conf->ciphers &&
1579 !SSL_CTX_set_cipher_list(ctx, bind_conf->ciphers)) {
Emeric Brunfc0421f2012-09-07 17:30:07 +02001580 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 +02001581 curproxy->id, bind_conf->ciphers, bind_conf->arg, bind_conf->file, bind_conf->line);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001582 cfgerr++;
1583 }
1584
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001585 /* If tune.ssl.default-dh-param has not been set and
1586 no static DH params were in the certificate file. */
1587 if (global.tune.ssl_default_dh_param == 0) {
Lukas Tribus90132722014-08-18 00:56:33 +02001588
Remi Gacogne23d5d372014-10-10 17:04:26 +02001589 ssl = SSL_new(ctx);
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001590
Remi Gacogne23d5d372014-10-10 17:04:26 +02001591 if (ssl) {
1592 ciphers = SSL_get_ciphers(ssl);
1593
1594 if (ciphers) {
1595 for (idx = 0; idx < sk_SSL_CIPHER_num(ciphers); idx++) {
1596 cipher = sk_SSL_CIPHER_value(ciphers, idx);
1597 if (SSL_CIPHER_description(cipher, cipher_description, sizeof (cipher_description)) == cipher_description) {
1598 if (strstr(cipher_description, dhe_description) != NULL ||
1599 strstr(cipher_description, dhe_export_description) != NULL) {
1600 dhe_found = 1;
1601 break;
1602 }
Remi Gacognec1eab8c2014-06-12 18:20:11 +02001603 }
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001604 }
1605 }
Remi Gacogne23d5d372014-10-10 17:04:26 +02001606 SSL_free(ssl);
1607 ssl = NULL;
Lukas Tribus90132722014-08-18 00:56:33 +02001608 }
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001609
Lukas Tribus90132722014-08-18 00:56:33 +02001610 if (dhe_found) {
1611 Warning("Setting tune.ssl.default-dh-param to 1024 by default, if your workload permits it you should set it to at least 2048. Please set a value >= 1024 to make this warning disappear.\n");
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001612 }
1613
1614 global.tune.ssl_default_dh_param = 1024;
1615 }
Remi Gacogne8de54152014-07-15 11:36:40 +02001616
1617#ifndef OPENSSL_NO_DH
1618 if (global.tune.ssl_default_dh_param >= 1024) {
1619 if (local_dh_1024 == NULL) {
1620 local_dh_1024 = ssl_get_dh_1024();
1621 }
1622 if (global.tune.ssl_default_dh_param >= 2048) {
1623 if (local_dh_2048 == NULL) {
1624 local_dh_2048 = ssl_get_dh_2048();
1625 }
1626 if (global.tune.ssl_default_dh_param >= 4096) {
1627 if (local_dh_4096 == NULL) {
1628 local_dh_4096 = ssl_get_dh_4096();
1629 }
1630 if (global.tune.ssl_default_dh_param >= 8192 &&
1631 local_dh_8192 == NULL) {
1632 local_dh_8192 = ssl_get_dh_8192();
1633 }
1634 }
1635 }
1636 }
1637#endif /* OPENSSL_NO_DH */
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001638
Emeric Brunfc0421f2012-09-07 17:30:07 +02001639 SSL_CTX_set_info_callback(ctx, ssl_sock_infocbk);
Willy Tarreau5cbe4ef2014-05-08 22:45:11 +02001640#if OPENSSL_VERSION_NUMBER >= 0x00907000L
Emeric Brun29f037d2014-04-25 19:05:36 +02001641 SSL_CTX_set_msg_callback(ctx, ssl_sock_msgcbk);
Willy Tarreau5cbe4ef2014-05-08 22:45:11 +02001642#endif
Emeric Brun29f037d2014-04-25 19:05:36 +02001643
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02001644#ifdef OPENSSL_NPN_NEGOTIATED
1645 if (bind_conf->npn_str)
1646 SSL_CTX_set_next_protos_advertised_cb(ctx, ssl_sock_advertise_npn_protos, bind_conf);
1647#endif
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01001648#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Willy Tarreauab861d32013-04-02 02:30:41 +02001649 if (bind_conf->alpn_str)
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01001650 SSL_CTX_set_alpn_select_cb(ctx, ssl_sock_advertise_alpn_protos, bind_conf);
Willy Tarreauab861d32013-04-02 02:30:41 +02001651#endif
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02001652
Emeric Brunfc0421f2012-09-07 17:30:07 +02001653#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
1654 SSL_CTX_set_tlsext_servername_callback(ctx, ssl_sock_switchctx_cbk);
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001655 SSL_CTX_set_tlsext_servername_arg(ctx, bind_conf);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001656#endif
Emeric Brun2b58d042012-09-20 17:10:03 +02001657#if defined(SSL_CTX_set_tmp_ecdh) && !defined(OPENSSL_NO_ECDH)
Emeric Brun6924ef82013-03-06 14:08:53 +01001658 {
Emeric Brun2b58d042012-09-20 17:10:03 +02001659 int i;
1660 EC_KEY *ecdh;
1661
Emeric Brun6924ef82013-03-06 14:08:53 +01001662 i = OBJ_sn2nid(bind_conf->ecdhe ? bind_conf->ecdhe : ECDHE_DEFAULT_CURVE);
Emeric Brun2b58d042012-09-20 17:10:03 +02001663 if (!i || ((ecdh = EC_KEY_new_by_curve_name(i)) == NULL)) {
1664 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 +01001665 curproxy->id, bind_conf->ecdhe ? bind_conf->ecdhe : ECDHE_DEFAULT_CURVE,
1666 bind_conf->arg, bind_conf->file, bind_conf->line);
Emeric Brun2b58d042012-09-20 17:10:03 +02001667 cfgerr++;
1668 }
1669 else {
1670 SSL_CTX_set_tmp_ecdh(ctx, ecdh);
1671 EC_KEY_free(ecdh);
1672 }
1673 }
1674#endif
1675
Emeric Brunfc0421f2012-09-07 17:30:07 +02001676 return cfgerr;
1677}
1678
Evan Broderbe554312013-06-27 00:05:25 -07001679static int ssl_sock_srv_hostcheck(const char *pattern, const char *hostname)
1680{
1681 const char *pattern_wildcard, *pattern_left_label_end, *hostname_left_label_end;
1682 size_t prefixlen, suffixlen;
1683
1684 /* Trivial case */
1685 if (strcmp(pattern, hostname) == 0)
1686 return 1;
1687
Evan Broderbe554312013-06-27 00:05:25 -07001688 /* The rest of this logic is based on RFC 6125, section 6.4.3
1689 * (http://tools.ietf.org/html/rfc6125#section-6.4.3) */
1690
Emeric Bruna848dae2013-10-08 11:27:28 +02001691 pattern_wildcard = NULL;
1692 pattern_left_label_end = pattern;
1693 while (*pattern_left_label_end != '.') {
1694 switch (*pattern_left_label_end) {
1695 case 0:
1696 /* End of label not found */
1697 return 0;
1698 case '*':
1699 /* If there is more than one wildcards */
1700 if (pattern_wildcard)
1701 return 0;
1702 pattern_wildcard = pattern_left_label_end;
1703 break;
1704 }
1705 pattern_left_label_end++;
1706 }
1707
1708 /* If it's not trivial and there is no wildcard, it can't
1709 * match */
1710 if (!pattern_wildcard)
Evan Broderbe554312013-06-27 00:05:25 -07001711 return 0;
1712
1713 /* Make sure all labels match except the leftmost */
1714 hostname_left_label_end = strchr(hostname, '.');
1715 if (!hostname_left_label_end
1716 || strcmp(pattern_left_label_end, hostname_left_label_end) != 0)
1717 return 0;
1718
1719 /* Make sure the leftmost label of the hostname is long enough
1720 * that the wildcard can match */
Emeric Brun369da852013-10-08 11:39:35 +02001721 if (hostname_left_label_end - hostname < (pattern_left_label_end - pattern) - 1)
Evan Broderbe554312013-06-27 00:05:25 -07001722 return 0;
1723
1724 /* Finally compare the string on either side of the
1725 * wildcard */
1726 prefixlen = pattern_wildcard - pattern;
1727 suffixlen = pattern_left_label_end - (pattern_wildcard + 1);
Emeric Bruna848dae2013-10-08 11:27:28 +02001728 if ((prefixlen && (memcmp(pattern, hostname, prefixlen) != 0))
1729 || (suffixlen && (memcmp(pattern_wildcard + 1, hostname_left_label_end - suffixlen, suffixlen) != 0)))
Evan Broderbe554312013-06-27 00:05:25 -07001730 return 0;
1731
1732 return 1;
1733}
1734
1735static int ssl_sock_srv_verifycbk(int ok, X509_STORE_CTX *ctx)
1736{
1737 SSL *ssl;
1738 struct connection *conn;
1739 char *servername;
1740
1741 int depth;
1742 X509 *cert;
1743 STACK_OF(GENERAL_NAME) *alt_names;
1744 int i;
1745 X509_NAME *cert_subject;
1746 char *str;
1747
1748 if (ok == 0)
1749 return ok;
1750
1751 ssl = X509_STORE_CTX_get_ex_data(ctx, SSL_get_ex_data_X509_STORE_CTX_idx());
1752 conn = (struct connection *)SSL_get_app_data(ssl);
1753
1754 servername = objt_server(conn->target)->ssl_ctx.verify_host;
1755
1756 /* We only need to verify the CN on the actual server cert,
1757 * not the indirect CAs */
1758 depth = X509_STORE_CTX_get_error_depth(ctx);
1759 if (depth != 0)
1760 return ok;
1761
1762 /* At this point, the cert is *not* OK unless we can find a
1763 * hostname match */
1764 ok = 0;
1765
1766 cert = X509_STORE_CTX_get_current_cert(ctx);
1767 /* It seems like this might happen if verify peer isn't set */
1768 if (!cert)
1769 return ok;
1770
1771 alt_names = X509_get_ext_d2i(cert, NID_subject_alt_name, NULL, NULL);
1772 if (alt_names) {
1773 for (i = 0; !ok && i < sk_GENERAL_NAME_num(alt_names); i++) {
1774 GENERAL_NAME *name = sk_GENERAL_NAME_value(alt_names, i);
1775 if (name->type == GEN_DNS) {
Emeric Bruna33410c2013-09-17 15:47:48 +02001776#if OPENSSL_VERSION_NUMBER < 0x00907000L
1777 if (ASN1_STRING_to_UTF8((unsigned char **)&str, name->d.ia5) >= 0) {
1778#else
Evan Broderbe554312013-06-27 00:05:25 -07001779 if (ASN1_STRING_to_UTF8((unsigned char **)&str, name->d.dNSName) >= 0) {
Emeric Bruna33410c2013-09-17 15:47:48 +02001780#endif
Evan Broderbe554312013-06-27 00:05:25 -07001781 ok = ssl_sock_srv_hostcheck(str, servername);
1782 OPENSSL_free(str);
1783 }
1784 }
1785 }
Emeric Brun4ad50a42013-09-17 15:19:54 +02001786 sk_GENERAL_NAME_pop_free(alt_names, GENERAL_NAME_free);
Evan Broderbe554312013-06-27 00:05:25 -07001787 }
1788
1789 cert_subject = X509_get_subject_name(cert);
1790 i = -1;
1791 while (!ok && (i = X509_NAME_get_index_by_NID(cert_subject, NID_commonName, i)) != -1) {
1792 X509_NAME_ENTRY *entry = X509_NAME_get_entry(cert_subject, i);
1793 if (ASN1_STRING_to_UTF8((unsigned char **)&str, entry->value) >= 0) {
1794 ok = ssl_sock_srv_hostcheck(str, servername);
1795 OPENSSL_free(str);
1796 }
1797 }
1798
1799 return ok;
1800}
1801
Emeric Brun94324a42012-10-11 14:00:19 +02001802/* prepare ssl context from servers options. Returns an error count */
1803int ssl_sock_prepare_srv_ctx(struct server *srv, struct proxy *curproxy)
1804{
1805 int cfgerr = 0;
Remi Gacogneaf5c3da2014-05-19 10:29:58 +02001806 long options =
Emeric Brun94324a42012-10-11 14:00:19 +02001807 SSL_OP_ALL | /* all known workarounds for bugs */
1808 SSL_OP_NO_SSLv2 |
1809 SSL_OP_NO_COMPRESSION;
Remi Gacogneaf5c3da2014-05-19 10:29:58 +02001810 long mode =
Emeric Brun94324a42012-10-11 14:00:19 +02001811 SSL_MODE_ENABLE_PARTIAL_WRITE |
1812 SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER |
Willy Tarreau396a1862014-11-13 14:06:52 +01001813 SSL_MODE_RELEASE_BUFFERS |
1814 SSL_MODE_SMALL_BUFFERS;
Emeric Brun850efd52014-01-29 12:24:34 +01001815 int verify = SSL_VERIFY_NONE;
Emeric Brun94324a42012-10-11 14:00:19 +02001816
Thierry Fournier383085f2013-01-24 14:15:43 +01001817 /* Make sure openssl opens /dev/urandom before the chroot */
1818 if (!ssl_initialize_random()) {
1819 Alert("OpenSSL random data generator initialization failed.\n");
1820 cfgerr++;
1821 }
1822
Willy Tarreaufce03112015-01-15 21:32:40 +01001823 /* Automatic memory computations need to know we use SSL there */
1824 global.ssl_used_backend = 1;
1825
1826 /* Initiate SSL context for current server */
Emeric Brun94324a42012-10-11 14:00:19 +02001827 srv->ssl_ctx.reused_sess = NULL;
1828 if (srv->use_ssl)
1829 srv->xprt = &ssl_sock;
1830 if (srv->check.use_ssl)
Cyril Bonté9ce13112014-11-15 22:41:27 +01001831 srv->check.xprt = &ssl_sock;
Emeric Brun94324a42012-10-11 14:00:19 +02001832
1833 srv->ssl_ctx.ctx = SSL_CTX_new(SSLv23_client_method());
1834 if (!srv->ssl_ctx.ctx) {
1835 Alert("config : %s '%s', server '%s': unable to allocate ssl context.\n",
1836 proxy_type_str(curproxy), curproxy->id,
1837 srv->id);
1838 cfgerr++;
1839 return cfgerr;
1840 }
Emeric Bruna7aa3092012-10-26 12:58:00 +02001841 if (srv->ssl_ctx.client_crt) {
1842 if (SSL_CTX_use_PrivateKey_file(srv->ssl_ctx.ctx, srv->ssl_ctx.client_crt, SSL_FILETYPE_PEM) <= 0) {
1843 Alert("config : %s '%s', server '%s': unable to load SSL private key from PEM file '%s'.\n",
1844 proxy_type_str(curproxy), curproxy->id,
1845 srv->id, srv->ssl_ctx.client_crt);
1846 cfgerr++;
1847 }
1848 else if (SSL_CTX_use_certificate_chain_file(srv->ssl_ctx.ctx, srv->ssl_ctx.client_crt) <= 0) {
1849 Alert("config : %s '%s', server '%s': unable to load ssl certificate from PEM file '%s'.\n",
1850 proxy_type_str(curproxy), curproxy->id,
1851 srv->id, srv->ssl_ctx.client_crt);
1852 cfgerr++;
1853 }
1854 else if (SSL_CTX_check_private_key(srv->ssl_ctx.ctx) <= 0) {
1855 Alert("config : %s '%s', server '%s': inconsistencies between private key and certificate loaded from PEM file '%s'.\n",
1856 proxy_type_str(curproxy), curproxy->id,
1857 srv->id, srv->ssl_ctx.client_crt);
1858 cfgerr++;
1859 }
1860 }
Emeric Brun94324a42012-10-11 14:00:19 +02001861
1862 if (srv->ssl_ctx.options & SRV_SSL_O_NO_SSLV3)
1863 options |= SSL_OP_NO_SSLv3;
1864 if (srv->ssl_ctx.options & SRV_SSL_O_NO_TLSV10)
1865 options |= SSL_OP_NO_TLSv1;
1866 if (srv->ssl_ctx.options & SRV_SSL_O_NO_TLSV11)
1867 options |= SSL_OP_NO_TLSv1_1;
1868 if (srv->ssl_ctx.options & SRV_SSL_O_NO_TLSV12)
1869 options |= SSL_OP_NO_TLSv1_2;
Emeric Brunf9c5c472012-10-11 15:28:34 +02001870 if (srv->ssl_ctx.options & SRV_SSL_O_NO_TLS_TICKETS)
1871 options |= SSL_OP_NO_TICKET;
Emeric Brun94324a42012-10-11 14:00:19 +02001872 if (srv->ssl_ctx.options & SRV_SSL_O_USE_SSLV3)
1873 SSL_CTX_set_ssl_version(srv->ssl_ctx.ctx, SSLv3_client_method());
1874 if (srv->ssl_ctx.options & SRV_SSL_O_USE_TLSV10)
1875 SSL_CTX_set_ssl_version(srv->ssl_ctx.ctx, TLSv1_client_method());
1876#if SSL_OP_NO_TLSv1_1
1877 if (srv->ssl_ctx.options & SRV_SSL_O_USE_TLSV11)
1878 SSL_CTX_set_ssl_version(srv->ssl_ctx.ctx, TLSv1_1_client_method());
1879#endif
1880#if SSL_OP_NO_TLSv1_2
1881 if (srv->ssl_ctx.options & SRV_SSL_O_USE_TLSV12)
1882 SSL_CTX_set_ssl_version(srv->ssl_ctx.ctx, TLSv1_2_client_method());
1883#endif
1884
1885 SSL_CTX_set_options(srv->ssl_ctx.ctx, options);
1886 SSL_CTX_set_mode(srv->ssl_ctx.ctx, mode);
Emeric Brun850efd52014-01-29 12:24:34 +01001887
1888 if (global.ssl_server_verify == SSL_SERVER_VERIFY_REQUIRED)
1889 verify = SSL_VERIFY_PEER;
1890
1891 switch (srv->ssl_ctx.verify) {
1892 case SSL_SOCK_VERIFY_NONE:
1893 verify = SSL_VERIFY_NONE;
1894 break;
1895 case SSL_SOCK_VERIFY_REQUIRED:
1896 verify = SSL_VERIFY_PEER;
1897 break;
1898 }
Evan Broderbe554312013-06-27 00:05:25 -07001899 SSL_CTX_set_verify(srv->ssl_ctx.ctx,
Emeric Brun850efd52014-01-29 12:24:34 +01001900 verify,
Evan Broderbe554312013-06-27 00:05:25 -07001901 srv->ssl_ctx.verify_host ? ssl_sock_srv_verifycbk : NULL);
Emeric Brun850efd52014-01-29 12:24:34 +01001902 if (verify & SSL_VERIFY_PEER) {
Emeric Brunef42d922012-10-11 16:11:36 +02001903 if (srv->ssl_ctx.ca_file) {
1904 /* load CAfile to verify */
1905 if (!SSL_CTX_load_verify_locations(srv->ssl_ctx.ctx, srv->ssl_ctx.ca_file, NULL)) {
Willy Tarreau07ba08b2014-02-16 19:22:08 +01001906 Alert("Proxy '%s', server '%s' [%s:%d] unable to load CA file '%s'.\n",
Emeric Brunef42d922012-10-11 16:11:36 +02001907 curproxy->id, srv->id,
1908 srv->conf.file, srv->conf.line, srv->ssl_ctx.ca_file);
1909 cfgerr++;
1910 }
1911 }
Emeric Brun850efd52014-01-29 12:24:34 +01001912 else {
1913 if (global.ssl_server_verify == SSL_SERVER_VERIFY_REQUIRED)
Willy Tarreau07ba08b2014-02-16 19:22:08 +01001914 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 +01001915 curproxy->id, srv->id,
1916 srv->conf.file, srv->conf.line);
1917 else
Willy Tarreau07ba08b2014-02-16 19:22:08 +01001918 Alert("Proxy '%s', server '%s' [%s:%d] verify is enabled but no CA file specified.\n",
Emeric Brun850efd52014-01-29 12:24:34 +01001919 curproxy->id, srv->id,
1920 srv->conf.file, srv->conf.line);
1921 cfgerr++;
1922 }
Emeric Brunef42d922012-10-11 16:11:36 +02001923#ifdef X509_V_FLAG_CRL_CHECK
1924 if (srv->ssl_ctx.crl_file) {
1925 X509_STORE *store = SSL_CTX_get_cert_store(srv->ssl_ctx.ctx);
1926
1927 if (!store || !X509_STORE_load_locations(store, srv->ssl_ctx.crl_file, NULL)) {
Willy Tarreau07ba08b2014-02-16 19:22:08 +01001928 Alert("Proxy '%s', server '%s' [%s:%d] unable to configure CRL file '%s'.\n",
Emeric Brunef42d922012-10-11 16:11:36 +02001929 curproxy->id, srv->id,
1930 srv->conf.file, srv->conf.line, srv->ssl_ctx.crl_file);
1931 cfgerr++;
1932 }
1933 else {
1934 X509_STORE_set_flags(store, X509_V_FLAG_CRL_CHECK|X509_V_FLAG_CRL_CHECK_ALL);
1935 }
1936 }
1937#endif
1938 }
1939
Emeric Brun4f65bff2012-11-16 15:11:00 +01001940 if (global.tune.ssllifetime)
1941 SSL_CTX_set_timeout(srv->ssl_ctx.ctx, global.tune.ssllifetime);
1942
Emeric Brun94324a42012-10-11 14:00:19 +02001943 SSL_CTX_set_session_cache_mode(srv->ssl_ctx.ctx, SSL_SESS_CACHE_OFF);
1944 if (srv->ssl_ctx.ciphers &&
1945 !SSL_CTX_set_cipher_list(srv->ssl_ctx.ctx, srv->ssl_ctx.ciphers)) {
1946 Alert("Proxy '%s', server '%s' [%s:%d] : unable to set SSL cipher list to '%s'.\n",
1947 curproxy->id, srv->id,
1948 srv->conf.file, srv->conf.line, srv->ssl_ctx.ciphers);
1949 cfgerr++;
1950 }
1951
1952 return cfgerr;
1953}
1954
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001955/* Walks down the two trees in bind_conf and prepares all certs. The pointer may
Emeric Brunfc0421f2012-09-07 17:30:07 +02001956 * be NULL, in which case nothing is done. Returns the number of errors
1957 * encountered.
1958 */
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001959int ssl_sock_prepare_all_ctx(struct bind_conf *bind_conf, struct proxy *px)
Emeric Brunfc0421f2012-09-07 17:30:07 +02001960{
1961 struct ebmb_node *node;
1962 struct sni_ctx *sni;
1963 int err = 0;
1964
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001965 if (!bind_conf || !bind_conf->is_ssl)
Emeric Brunfc0421f2012-09-07 17:30:07 +02001966 return 0;
1967
Willy Tarreaufce03112015-01-15 21:32:40 +01001968 /* Automatic memory computations need to know we use SSL there */
1969 global.ssl_used_frontend = 1;
1970
Emeric Brun0bed9942014-10-30 19:25:24 +01001971 if (bind_conf->default_ctx)
1972 err += ssl_sock_prepare_ctx(bind_conf, bind_conf->default_ctx, px);
1973
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001974 node = ebmb_first(&bind_conf->sni_ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001975 while (node) {
1976 sni = ebmb_entry(node, struct sni_ctx, name);
Emeric Brun0bed9942014-10-30 19:25:24 +01001977 if (!sni->order && sni->ctx != bind_conf->default_ctx)
1978 /* only initialize the CTX on its first occurrence and
1979 if it is not the default_ctx */
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001980 err += ssl_sock_prepare_ctx(bind_conf, sni->ctx, px);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001981 node = ebmb_next(node);
1982 }
1983
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001984 node = ebmb_first(&bind_conf->sni_w_ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001985 while (node) {
1986 sni = ebmb_entry(node, struct sni_ctx, name);
Emeric Brun0bed9942014-10-30 19:25:24 +01001987 if (!sni->order && sni->ctx != bind_conf->default_ctx)
1988 /* only initialize the CTX on its first occurrence and
1989 if it is not the default_ctx */
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001990 err += ssl_sock_prepare_ctx(bind_conf, sni->ctx, px);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001991 node = ebmb_next(node);
1992 }
1993 return err;
1994}
1995
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001996/* Walks down the two trees in bind_conf and frees all the certs. The pointer may
Emeric Brunfc0421f2012-09-07 17:30:07 +02001997 * be NULL, in which case nothing is done. The default_ctx is nullified too.
1998 */
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001999void ssl_sock_free_all_ctx(struct bind_conf *bind_conf)
Emeric Brunfc0421f2012-09-07 17:30:07 +02002000{
2001 struct ebmb_node *node, *back;
2002 struct sni_ctx *sni;
2003
Willy Tarreau2a65ff02012-09-13 17:54:29 +02002004 if (!bind_conf || !bind_conf->is_ssl)
Emeric Brunfc0421f2012-09-07 17:30:07 +02002005 return;
2006
Willy Tarreau2a65ff02012-09-13 17:54:29 +02002007 node = ebmb_first(&bind_conf->sni_ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002008 while (node) {
2009 sni = ebmb_entry(node, struct sni_ctx, name);
2010 back = ebmb_next(node);
2011 ebmb_delete(node);
2012 if (!sni->order) /* only free the CTX on its first occurrence */
2013 SSL_CTX_free(sni->ctx);
2014 free(sni);
2015 node = back;
2016 }
2017
Willy Tarreau2a65ff02012-09-13 17:54:29 +02002018 node = ebmb_first(&bind_conf->sni_w_ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002019 while (node) {
2020 sni = ebmb_entry(node, struct sni_ctx, name);
2021 back = ebmb_next(node);
2022 ebmb_delete(node);
2023 if (!sni->order) /* only free the CTX on its first occurrence */
2024 SSL_CTX_free(sni->ctx);
2025 free(sni);
2026 node = back;
2027 }
2028
Willy Tarreau2a65ff02012-09-13 17:54:29 +02002029 bind_conf->default_ctx = NULL;
Emeric Brune1f38db2012-09-03 20:36:47 +02002030}
2031
Emeric Brun46591952012-05-18 15:47:34 +02002032/*
2033 * This function is called if SSL * context is not yet allocated. The function
2034 * is designed to be called before any other data-layer operation and sets the
2035 * handshake flag on the connection. It is safe to call it multiple times.
2036 * It returns 0 on success and -1 in error case.
2037 */
2038static int ssl_sock_init(struct connection *conn)
2039{
2040 /* already initialized */
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02002041 if (conn->xprt_ctx)
Emeric Brun46591952012-05-18 15:47:34 +02002042 return 0;
2043
Willy Tarreau3c728722014-01-23 13:50:42 +01002044 if (!conn_ctrl_ready(conn))
Willy Tarreauf79c8172013-10-21 16:30:56 +02002045 return 0;
2046
Willy Tarreau20879a02012-12-03 16:32:10 +01002047 if (global.maxsslconn && sslconns >= global.maxsslconn) {
2048 conn->err_code = CO_ER_SSL_TOO_MANY;
Willy Tarreau403edff2012-09-06 11:58:37 +02002049 return -1;
Willy Tarreau20879a02012-12-03 16:32:10 +01002050 }
Willy Tarreau403edff2012-09-06 11:58:37 +02002051
Emeric Brun46591952012-05-18 15:47:34 +02002052 /* If it is in client mode initiate SSL session
2053 in connect state otherwise accept state */
Willy Tarreau3fdb3662012-11-12 00:42:33 +01002054 if (objt_server(conn->target)) {
Willy Tarreaufba03cd2014-11-13 13:48:58 +01002055 int may_retry = 1;
2056
2057 retry_connect:
Emeric Brun46591952012-05-18 15:47:34 +02002058 /* Alloc a new SSL session ctx */
Willy Tarreau3fdb3662012-11-12 00:42:33 +01002059 conn->xprt_ctx = SSL_new(objt_server(conn->target)->ssl_ctx.ctx);
Willy Tarreau20879a02012-12-03 16:32:10 +01002060 if (!conn->xprt_ctx) {
Willy Tarreaufba03cd2014-11-13 13:48:58 +01002061 if (may_retry--) {
2062 pool_gc2();
2063 goto retry_connect;
2064 }
Willy Tarreau20879a02012-12-03 16:32:10 +01002065 conn->err_code = CO_ER_SSL_NO_MEM;
Emeric Brun46591952012-05-18 15:47:34 +02002066 return -1;
Willy Tarreau20879a02012-12-03 16:32:10 +01002067 }
Emeric Brun46591952012-05-18 15:47:34 +02002068
Emeric Brun46591952012-05-18 15:47:34 +02002069 /* set fd on SSL session context */
Emeric Brun55476152014-11-12 17:35:37 +01002070 if (!SSL_set_fd(conn->xprt_ctx, conn->t.sock.fd)) {
2071 SSL_free(conn->xprt_ctx);
2072 conn->xprt_ctx = NULL;
Willy Tarreaufba03cd2014-11-13 13:48:58 +01002073 if (may_retry--) {
2074 pool_gc2();
2075 goto retry_connect;
2076 }
Emeric Brun55476152014-11-12 17:35:37 +01002077 conn->err_code = CO_ER_SSL_NO_MEM;
2078 return -1;
2079 }
Emeric Brun46591952012-05-18 15:47:34 +02002080
Evan Broderbe554312013-06-27 00:05:25 -07002081 /* set connection pointer */
Emeric Brun55476152014-11-12 17:35:37 +01002082 if (!SSL_set_app_data(conn->xprt_ctx, conn)) {
2083 SSL_free(conn->xprt_ctx);
2084 conn->xprt_ctx = NULL;
Willy Tarreaufba03cd2014-11-13 13:48:58 +01002085 if (may_retry--) {
2086 pool_gc2();
2087 goto retry_connect;
2088 }
Emeric Brun55476152014-11-12 17:35:37 +01002089 conn->err_code = CO_ER_SSL_NO_MEM;
2090 return -1;
2091 }
2092
2093 SSL_set_connect_state(conn->xprt_ctx);
2094 if (objt_server(conn->target)->ssl_ctx.reused_sess) {
2095 if(!SSL_set_session(conn->xprt_ctx, objt_server(conn->target)->ssl_ctx.reused_sess)) {
2096 SSL_SESSION_free(objt_server(conn->target)->ssl_ctx.reused_sess);
2097 objt_server(conn->target)->ssl_ctx.reused_sess = NULL;
2098 }
2099 }
Evan Broderbe554312013-06-27 00:05:25 -07002100
Emeric Brun46591952012-05-18 15:47:34 +02002101 /* leave init state and start handshake */
Willy Tarreau05737472012-09-04 08:03:39 +02002102 conn->flags |= CO_FL_SSL_WAIT_HS | CO_FL_WAIT_L6_CONN;
Willy Tarreau403edff2012-09-06 11:58:37 +02002103
2104 sslconns++;
Willy Tarreau71b734c2014-01-28 15:19:44 +01002105 totalsslconns++;
Emeric Brun46591952012-05-18 15:47:34 +02002106 return 0;
2107 }
Willy Tarreau3fdb3662012-11-12 00:42:33 +01002108 else if (objt_listener(conn->target)) {
Willy Tarreaufba03cd2014-11-13 13:48:58 +01002109 int may_retry = 1;
2110
2111 retry_accept:
Emeric Brun46591952012-05-18 15:47:34 +02002112 /* Alloc a new SSL session ctx */
Willy Tarreau3fdb3662012-11-12 00:42:33 +01002113 conn->xprt_ctx = SSL_new(objt_listener(conn->target)->bind_conf->default_ctx);
Willy Tarreau20879a02012-12-03 16:32:10 +01002114 if (!conn->xprt_ctx) {
Willy Tarreaufba03cd2014-11-13 13:48:58 +01002115 if (may_retry--) {
2116 pool_gc2();
2117 goto retry_accept;
2118 }
Willy Tarreau20879a02012-12-03 16:32:10 +01002119 conn->err_code = CO_ER_SSL_NO_MEM;
Emeric Brun46591952012-05-18 15:47:34 +02002120 return -1;
Willy Tarreau20879a02012-12-03 16:32:10 +01002121 }
Emeric Brun46591952012-05-18 15:47:34 +02002122
Emeric Brun46591952012-05-18 15:47:34 +02002123 /* set fd on SSL session context */
Emeric Brun55476152014-11-12 17:35:37 +01002124 if (!SSL_set_fd(conn->xprt_ctx, conn->t.sock.fd)) {
2125 SSL_free(conn->xprt_ctx);
2126 conn->xprt_ctx = NULL;
Willy Tarreaufba03cd2014-11-13 13:48:58 +01002127 if (may_retry--) {
2128 pool_gc2();
2129 goto retry_accept;
2130 }
Emeric Brun55476152014-11-12 17:35:37 +01002131 conn->err_code = CO_ER_SSL_NO_MEM;
2132 return -1;
2133 }
Emeric Brun46591952012-05-18 15:47:34 +02002134
Emeric Brune1f38db2012-09-03 20:36:47 +02002135 /* set connection pointer */
Emeric Brun55476152014-11-12 17:35:37 +01002136 if (!SSL_set_app_data(conn->xprt_ctx, conn)) {
2137 SSL_free(conn->xprt_ctx);
2138 conn->xprt_ctx = NULL;
Willy Tarreaufba03cd2014-11-13 13:48:58 +01002139 if (may_retry--) {
2140 pool_gc2();
2141 goto retry_accept;
2142 }
Emeric Brun55476152014-11-12 17:35:37 +01002143 conn->err_code = CO_ER_SSL_NO_MEM;
2144 return -1;
2145 }
2146
2147 SSL_set_accept_state(conn->xprt_ctx);
Emeric Brune1f38db2012-09-03 20:36:47 +02002148
Emeric Brun46591952012-05-18 15:47:34 +02002149 /* leave init state and start handshake */
Willy Tarreau05737472012-09-04 08:03:39 +02002150 conn->flags |= CO_FL_SSL_WAIT_HS | CO_FL_WAIT_L6_CONN;
Willy Tarreau403edff2012-09-06 11:58:37 +02002151
2152 sslconns++;
Willy Tarreau71b734c2014-01-28 15:19:44 +01002153 totalsslconns++;
Emeric Brun46591952012-05-18 15:47:34 +02002154 return 0;
2155 }
2156 /* don't know how to handle such a target */
Willy Tarreau20879a02012-12-03 16:32:10 +01002157 conn->err_code = CO_ER_SSL_NO_TARGET;
Emeric Brun46591952012-05-18 15:47:34 +02002158 return -1;
2159}
2160
2161
2162/* This is the callback which is used when an SSL handshake is pending. It
2163 * updates the FD status if it wants some polling before being called again.
2164 * It returns 0 if it fails in a fatal way or needs to poll to go further,
2165 * otherwise it returns non-zero and removes itself from the connection's
2166 * flags (the bit is provided in <flag> by the caller).
2167 */
2168int ssl_sock_handshake(struct connection *conn, unsigned int flag)
2169{
2170 int ret;
2171
Willy Tarreau3c728722014-01-23 13:50:42 +01002172 if (!conn_ctrl_ready(conn))
Willy Tarreauf79c8172013-10-21 16:30:56 +02002173 return 0;
2174
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02002175 if (!conn->xprt_ctx)
Emeric Brun46591952012-05-18 15:47:34 +02002176 goto out_error;
2177
Emeric Brun674b7432012-11-08 19:21:55 +01002178 /* If we use SSL_do_handshake to process a reneg initiated by
2179 * the remote peer, it sometimes returns SSL_ERROR_SSL.
2180 * Usually SSL_write and SSL_read are used and process implicitly
2181 * the reneg handshake.
2182 * Here we use SSL_peek as a workaround for reneg.
2183 */
2184 if ((conn->flags & CO_FL_CONNECTED) && SSL_renegotiate_pending(conn->xprt_ctx)) {
2185 char c;
2186
2187 ret = SSL_peek(conn->xprt_ctx, &c, 1);
2188 if (ret <= 0) {
2189 /* handshake may have not been completed, let's find why */
2190 ret = SSL_get_error(conn->xprt_ctx, ret);
2191 if (ret == SSL_ERROR_WANT_WRITE) {
2192 /* SSL handshake needs to write, L4 connection may not be ready */
2193 __conn_sock_stop_recv(conn);
Willy Tarreaue1f50c42014-01-22 20:02:06 +01002194 __conn_sock_want_send(conn);
2195 fd_cant_send(conn->t.sock.fd);
Emeric Brun674b7432012-11-08 19:21:55 +01002196 return 0;
2197 }
2198 else if (ret == SSL_ERROR_WANT_READ) {
2199 /* handshake may have been completed but we have
2200 * no more data to read.
2201 */
2202 if (!SSL_renegotiate_pending(conn->xprt_ctx)) {
2203 ret = 1;
2204 goto reneg_ok;
2205 }
2206 /* SSL handshake needs to read, L4 connection is ready */
2207 if (conn->flags & CO_FL_WAIT_L4_CONN)
2208 conn->flags &= ~CO_FL_WAIT_L4_CONN;
2209 __conn_sock_stop_send(conn);
Willy Tarreaue1f50c42014-01-22 20:02:06 +01002210 __conn_sock_want_recv(conn);
2211 fd_cant_recv(conn->t.sock.fd);
Emeric Brun674b7432012-11-08 19:21:55 +01002212 return 0;
2213 }
2214 else if (ret == SSL_ERROR_SYSCALL) {
2215 /* if errno is null, then connection was successfully established */
2216 if (!errno && conn->flags & CO_FL_WAIT_L4_CONN)
2217 conn->flags &= ~CO_FL_WAIT_L4_CONN;
Willy Tarreau20879a02012-12-03 16:32:10 +01002218 if (!conn->err_code) {
Emeric Brun29f037d2014-04-25 19:05:36 +02002219 if (!((SSL *)conn->xprt_ctx)->packet_length) {
2220 if (!errno) {
2221 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
2222 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
2223 else
2224 conn->err_code = CO_ER_SSL_EMPTY;
2225 }
2226 else {
2227 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
2228 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
2229 else
2230 conn->err_code = CO_ER_SSL_ABORT;
2231 }
2232 }
2233 else {
2234 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
2235 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
Willy Tarreau20879a02012-12-03 16:32:10 +01002236 else
Emeric Brun29f037d2014-04-25 19:05:36 +02002237 conn->err_code = CO_ER_SSL_HANDSHAKE;
2238 }
Willy Tarreau20879a02012-12-03 16:32:10 +01002239 }
Emeric Brun674b7432012-11-08 19:21:55 +01002240 goto out_error;
2241 }
2242 else {
2243 /* Fail on all other handshake errors */
2244 /* Note: OpenSSL may leave unread bytes in the socket's
2245 * buffer, causing an RST to be emitted upon close() on
2246 * TCP sockets. We first try to drain possibly pending
2247 * data to avoid this as much as possible.
2248 */
Willy Tarreau46be2e52014-01-20 12:10:52 +01002249 conn_drain(conn);
Willy Tarreau20879a02012-12-03 16:32:10 +01002250 if (!conn->err_code)
Willy Tarreauf51c6982014-04-25 20:02:39 +02002251 conn->err_code = (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT) ?
2252 CO_ER_SSL_KILLED_HB : CO_ER_SSL_HANDSHAKE;
Emeric Brun674b7432012-11-08 19:21:55 +01002253 goto out_error;
2254 }
2255 }
2256 /* read some data: consider handshake completed */
2257 goto reneg_ok;
2258 }
2259
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02002260 ret = SSL_do_handshake(conn->xprt_ctx);
Emeric Brun46591952012-05-18 15:47:34 +02002261 if (ret != 1) {
2262 /* handshake did not complete, let's find why */
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02002263 ret = SSL_get_error(conn->xprt_ctx, ret);
Emeric Brun46591952012-05-18 15:47:34 +02002264
2265 if (ret == SSL_ERROR_WANT_WRITE) {
2266 /* SSL handshake needs to write, L4 connection may not be ready */
2267 __conn_sock_stop_recv(conn);
Willy Tarreaue1f50c42014-01-22 20:02:06 +01002268 __conn_sock_want_send(conn);
2269 fd_cant_send(conn->t.sock.fd);
Emeric Brun46591952012-05-18 15:47:34 +02002270 return 0;
2271 }
2272 else if (ret == SSL_ERROR_WANT_READ) {
2273 /* SSL handshake needs to read, L4 connection is ready */
2274 if (conn->flags & CO_FL_WAIT_L4_CONN)
2275 conn->flags &= ~CO_FL_WAIT_L4_CONN;
2276 __conn_sock_stop_send(conn);
Willy Tarreaue1f50c42014-01-22 20:02:06 +01002277 __conn_sock_want_recv(conn);
2278 fd_cant_recv(conn->t.sock.fd);
Emeric Brun46591952012-05-18 15:47:34 +02002279 return 0;
2280 }
Willy Tarreau89230192012-09-28 20:22:13 +02002281 else if (ret == SSL_ERROR_SYSCALL) {
2282 /* if errno is null, then connection was successfully established */
2283 if (!errno && conn->flags & CO_FL_WAIT_L4_CONN)
2284 conn->flags &= ~CO_FL_WAIT_L4_CONN;
Willy Tarreau20879a02012-12-03 16:32:10 +01002285
Emeric Brun29f037d2014-04-25 19:05:36 +02002286 if (!((SSL *)conn->xprt_ctx)->packet_length) {
2287 if (!errno) {
2288 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
2289 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
2290 else
2291 conn->err_code = CO_ER_SSL_EMPTY;
2292 }
2293 else {
2294 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
2295 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
2296 else
2297 conn->err_code = CO_ER_SSL_ABORT;
2298 }
2299 }
2300 else {
2301 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
2302 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
Willy Tarreau20879a02012-12-03 16:32:10 +01002303 else
Emeric Brun29f037d2014-04-25 19:05:36 +02002304 conn->err_code = CO_ER_SSL_HANDSHAKE;
2305 }
Willy Tarreau89230192012-09-28 20:22:13 +02002306 goto out_error;
2307 }
Emeric Brun46591952012-05-18 15:47:34 +02002308 else {
2309 /* Fail on all other handshake errors */
Willy Tarreau566dc552012-10-19 20:52:18 +02002310 /* Note: OpenSSL may leave unread bytes in the socket's
2311 * buffer, causing an RST to be emitted upon close() on
2312 * TCP sockets. We first try to drain possibly pending
2313 * data to avoid this as much as possible.
2314 */
Willy Tarreau46be2e52014-01-20 12:10:52 +01002315 conn_drain(conn);
Willy Tarreau20879a02012-12-03 16:32:10 +01002316 if (!conn->err_code)
Willy Tarreauf51c6982014-04-25 20:02:39 +02002317 conn->err_code = (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT) ?
2318 CO_ER_SSL_KILLED_HB : CO_ER_SSL_HANDSHAKE;
Emeric Brun46591952012-05-18 15:47:34 +02002319 goto out_error;
2320 }
2321 }
2322
Emeric Brun674b7432012-11-08 19:21:55 +01002323reneg_ok:
2324
Emeric Brun46591952012-05-18 15:47:34 +02002325 /* Handshake succeeded */
Willy Tarreau0c9c2722014-05-28 12:28:58 +02002326 if (!SSL_session_reused(conn->xprt_ctx)) {
2327 if (objt_server(conn->target)) {
2328 update_freq_ctr(&global.ssl_be_keys_per_sec, 1);
2329 if (global.ssl_be_keys_per_sec.curr_ctr > global.ssl_be_keys_max)
2330 global.ssl_be_keys_max = global.ssl_be_keys_per_sec.curr_ctr;
2331
Emeric Brun46591952012-05-18 15:47:34 +02002332 /* check if session was reused, if not store current session on server for reuse */
Willy Tarreau3fdb3662012-11-12 00:42:33 +01002333 if (objt_server(conn->target)->ssl_ctx.reused_sess)
2334 SSL_SESSION_free(objt_server(conn->target)->ssl_ctx.reused_sess);
Emeric Brun46591952012-05-18 15:47:34 +02002335
Willy Tarreau3fdb3662012-11-12 00:42:33 +01002336 objt_server(conn->target)->ssl_ctx.reused_sess = SSL_get1_session(conn->xprt_ctx);
Emeric Brun46591952012-05-18 15:47:34 +02002337 }
Willy Tarreau0c9c2722014-05-28 12:28:58 +02002338 else {
2339 update_freq_ctr(&global.ssl_fe_keys_per_sec, 1);
2340 if (global.ssl_fe_keys_per_sec.curr_ctr > global.ssl_fe_keys_max)
2341 global.ssl_fe_keys_max = global.ssl_fe_keys_per_sec.curr_ctr;
2342 }
Emeric Brun46591952012-05-18 15:47:34 +02002343 }
2344
2345 /* The connection is now established at both layers, it's time to leave */
2346 conn->flags &= ~(flag | CO_FL_WAIT_L4_CONN | CO_FL_WAIT_L6_CONN);
2347 return 1;
2348
2349 out_error:
Emeric Brun644cde02012-12-14 11:21:13 +01002350 /* Clear openssl global errors stack */
2351 ERR_clear_error();
2352
Emeric Brun9fa89732012-10-04 17:09:56 +02002353 /* free resumed session if exists */
Willy Tarreau3fdb3662012-11-12 00:42:33 +01002354 if (objt_server(conn->target) && objt_server(conn->target)->ssl_ctx.reused_sess) {
2355 SSL_SESSION_free(objt_server(conn->target)->ssl_ctx.reused_sess);
2356 objt_server(conn->target)->ssl_ctx.reused_sess = NULL;
Emeric Brun9fa89732012-10-04 17:09:56 +02002357 }
2358
Emeric Brun46591952012-05-18 15:47:34 +02002359 /* Fail on all other handshake errors */
2360 conn->flags |= CO_FL_ERROR;
Willy Tarreau20879a02012-12-03 16:32:10 +01002361 if (!conn->err_code)
2362 conn->err_code = CO_ER_SSL_HANDSHAKE;
Emeric Brun46591952012-05-18 15:47:34 +02002363 return 0;
2364}
2365
2366/* Receive up to <count> bytes from connection <conn>'s socket and store them
Willy Tarreauabf08d92014-01-14 11:31:27 +01002367 * into buffer <buf>. Only one call to recv() is performed, unless the
Emeric Brun46591952012-05-18 15:47:34 +02002368 * buffer wraps, in which case a second call may be performed. The connection's
2369 * flags are updated with whatever special event is detected (error, read0,
2370 * empty). The caller is responsible for taking care of those events and
2371 * avoiding the call if inappropriate. The function does not call the
2372 * connection's polling update function, so the caller is responsible for this.
2373 */
2374static int ssl_sock_to_buf(struct connection *conn, struct buffer *buf, int count)
2375{
2376 int ret, done = 0;
Willy Tarreauabf08d92014-01-14 11:31:27 +01002377 int try;
Emeric Brun46591952012-05-18 15:47:34 +02002378
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02002379 if (!conn->xprt_ctx)
Emeric Brun46591952012-05-18 15:47:34 +02002380 goto out_error;
2381
2382 if (conn->flags & CO_FL_HANDSHAKE)
2383 /* a handshake was requested */
2384 return 0;
2385
Willy Tarreauabf08d92014-01-14 11:31:27 +01002386 /* let's realign the buffer to optimize I/O */
2387 if (buffer_empty(buf))
Emeric Brun46591952012-05-18 15:47:34 +02002388 buf->p = buf->data;
Emeric Brun46591952012-05-18 15:47:34 +02002389
2390 /* read the largest possible block. For this, we perform only one call
2391 * to recv() unless the buffer wraps and we exactly fill the first hunk,
2392 * in which case we accept to do it once again. A new attempt is made on
2393 * EINTR too.
2394 */
Willy Tarreau00b0fb92014-01-17 11:09:40 +01002395 while (count > 0) {
Willy Tarreauabf08d92014-01-14 11:31:27 +01002396 /* first check if we have some room after p+i */
2397 try = buf->data + buf->size - (buf->p + buf->i);
2398 /* otherwise continue between data and p-o */
2399 if (try <= 0) {
2400 try = buf->p - (buf->data + buf->o);
2401 if (try <= 0)
2402 break;
2403 }
2404 if (try > count)
2405 try = count;
2406
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02002407 ret = SSL_read(conn->xprt_ctx, bi_end(buf), try);
Emeric Brune1f38db2012-09-03 20:36:47 +02002408 if (conn->flags & CO_FL_ERROR) {
2409 /* CO_FL_ERROR may be set by ssl_sock_infocbk */
Emeric Brun644cde02012-12-14 11:21:13 +01002410 goto out_error;
Emeric Brune1f38db2012-09-03 20:36:47 +02002411 }
Emeric Brun46591952012-05-18 15:47:34 +02002412 if (ret > 0) {
2413 buf->i += ret;
2414 done += ret;
2415 if (ret < try)
2416 break;
2417 count -= ret;
Emeric Brun46591952012-05-18 15:47:34 +02002418 }
2419 else if (ret == 0) {
Emeric Brun644cde02012-12-14 11:21:13 +01002420 ret = SSL_get_error(conn->xprt_ctx, ret);
2421 if (ret != SSL_ERROR_ZERO_RETURN) {
Emeric Brun1c646862012-12-14 12:33:41 +01002422 /* error on protocol or underlying transport */
2423 if ((ret != SSL_ERROR_SYSCALL)
2424 || (errno && (errno != EAGAIN)))
2425 conn->flags |= CO_FL_ERROR;
2426
Emeric Brun644cde02012-12-14 11:21:13 +01002427 /* Clear openssl global errors stack */
2428 ERR_clear_error();
2429 }
Emeric Brun46591952012-05-18 15:47:34 +02002430 goto read0;
2431 }
2432 else {
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02002433 ret = SSL_get_error(conn->xprt_ctx, ret);
Emeric Brun46591952012-05-18 15:47:34 +02002434 if (ret == SSL_ERROR_WANT_WRITE) {
Emeric Brun8af8dd12012-11-08 17:56:20 +01002435 /* handshake is running, and it needs to enable write */
Emeric Brun46591952012-05-18 15:47:34 +02002436 conn->flags |= CO_FL_SSL_WAIT_HS;
Emeric Brun8af8dd12012-11-08 17:56:20 +01002437 __conn_sock_want_send(conn);
Emeric Brun46591952012-05-18 15:47:34 +02002438 break;
2439 }
2440 else if (ret == SSL_ERROR_WANT_READ) {
Emeric Brun282a76a2012-11-08 18:02:56 +01002441 if (SSL_renegotiate_pending(conn->xprt_ctx)) {
2442 /* handshake is running, and it may need to re-enable read */
2443 conn->flags |= CO_FL_SSL_WAIT_HS;
2444 __conn_sock_want_recv(conn);
2445 break;
2446 }
Emeric Brun46591952012-05-18 15:47:34 +02002447 /* we need to poll for retry a read later */
Willy Tarreaue1f50c42014-01-22 20:02:06 +01002448 fd_cant_recv(conn->t.sock.fd);
Emeric Brun46591952012-05-18 15:47:34 +02002449 break;
2450 }
2451 /* otherwise it's a real error */
2452 goto out_error;
2453 }
2454 }
2455 return done;
2456
2457 read0:
2458 conn_sock_read0(conn);
2459 return done;
2460 out_error:
Emeric Brun644cde02012-12-14 11:21:13 +01002461 /* Clear openssl global errors stack */
2462 ERR_clear_error();
2463
Emeric Brun46591952012-05-18 15:47:34 +02002464 conn->flags |= CO_FL_ERROR;
2465 return done;
2466}
2467
2468
2469/* Send all pending bytes from buffer <buf> to connection <conn>'s socket.
Willy Tarreau1049b1f2014-02-02 01:51:17 +01002470 * <flags> may contain some CO_SFL_* flags to hint the system about other
2471 * pending data for example, but this flag is ignored at the moment.
Emeric Brun46591952012-05-18 15:47:34 +02002472 * Only one call to send() is performed, unless the buffer wraps, in which case
2473 * a second call may be performed. The connection's flags are updated with
2474 * whatever special event is detected (error, empty). The caller is responsible
2475 * for taking care of those events and avoiding the call if inappropriate. The
2476 * function does not call the connection's polling update function, so the caller
2477 * is responsible for this.
2478 */
2479static int ssl_sock_from_buf(struct connection *conn, struct buffer *buf, int flags)
2480{
2481 int ret, try, done;
2482
2483 done = 0;
2484
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02002485 if (!conn->xprt_ctx)
Emeric Brun46591952012-05-18 15:47:34 +02002486 goto out_error;
2487
2488 if (conn->flags & CO_FL_HANDSHAKE)
2489 /* a handshake was requested */
2490 return 0;
2491
2492 /* send the largest possible block. For this we perform only one call
2493 * to send() unless the buffer wraps and we exactly fill the first hunk,
2494 * in which case we accept to do it once again.
2495 */
2496 while (buf->o) {
Kevin Hestercad82342013-05-30 15:12:41 -07002497 try = bo_contig_data(buf);
Willy Tarreaubfd59462013-02-21 07:46:09 +01002498
Willy Tarreau7bed9452014-02-02 02:00:24 +01002499 if (!(flags & CO_SFL_STREAMER) &&
Willy Tarreau518cedd2014-02-17 15:43:01 +01002500 !(conn->xprt_st & SSL_SOCK_SEND_UNLIMITED) &&
2501 global.tune.ssl_max_record && try > global.tune.ssl_max_record) {
Willy Tarreaubfd59462013-02-21 07:46:09 +01002502 try = global.tune.ssl_max_record;
Willy Tarreau518cedd2014-02-17 15:43:01 +01002503 }
2504 else {
2505 /* we need to keep the information about the fact that
2506 * we're not limiting the upcoming send(), because if it
2507 * fails, we'll have to retry with at least as many data.
2508 */
2509 conn->xprt_st |= SSL_SOCK_SEND_UNLIMITED;
2510 }
Willy Tarreaubfd59462013-02-21 07:46:09 +01002511
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02002512 ret = SSL_write(conn->xprt_ctx, bo_ptr(buf), try);
Willy Tarreau518cedd2014-02-17 15:43:01 +01002513
Emeric Brune1f38db2012-09-03 20:36:47 +02002514 if (conn->flags & CO_FL_ERROR) {
2515 /* CO_FL_ERROR may be set by ssl_sock_infocbk */
Emeric Brun644cde02012-12-14 11:21:13 +01002516 goto out_error;
Emeric Brune1f38db2012-09-03 20:36:47 +02002517 }
Emeric Brun46591952012-05-18 15:47:34 +02002518 if (ret > 0) {
Willy Tarreau518cedd2014-02-17 15:43:01 +01002519 conn->xprt_st &= ~SSL_SOCK_SEND_UNLIMITED;
2520
Emeric Brun46591952012-05-18 15:47:34 +02002521 buf->o -= ret;
2522 done += ret;
2523
Willy Tarreau5fb38032012-12-16 19:39:09 +01002524 if (likely(buffer_empty(buf)))
Emeric Brun46591952012-05-18 15:47:34 +02002525 /* optimize data alignment in the buffer */
2526 buf->p = buf->data;
2527
2528 /* if the system buffer is full, don't insist */
2529 if (ret < try)
2530 break;
2531 }
2532 else {
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02002533 ret = SSL_get_error(conn->xprt_ctx, ret);
Emeric Brun46591952012-05-18 15:47:34 +02002534 if (ret == SSL_ERROR_WANT_WRITE) {
Emeric Brun282a76a2012-11-08 18:02:56 +01002535 if (SSL_renegotiate_pending(conn->xprt_ctx)) {
2536 /* handshake is running, and it may need to re-enable write */
2537 conn->flags |= CO_FL_SSL_WAIT_HS;
2538 __conn_sock_want_send(conn);
2539 break;
2540 }
Emeric Brun46591952012-05-18 15:47:34 +02002541 /* we need to poll to retry a write later */
Willy Tarreaue1f50c42014-01-22 20:02:06 +01002542 fd_cant_send(conn->t.sock.fd);
Emeric Brun46591952012-05-18 15:47:34 +02002543 break;
2544 }
2545 else if (ret == SSL_ERROR_WANT_READ) {
Emeric Brun8af8dd12012-11-08 17:56:20 +01002546 /* handshake is running, and it needs to enable read */
Emeric Brun46591952012-05-18 15:47:34 +02002547 conn->flags |= CO_FL_SSL_WAIT_HS;
Emeric Brun8af8dd12012-11-08 17:56:20 +01002548 __conn_sock_want_recv(conn);
Emeric Brun46591952012-05-18 15:47:34 +02002549 break;
2550 }
2551 goto out_error;
2552 }
2553 }
2554 return done;
2555
2556 out_error:
Emeric Brun644cde02012-12-14 11:21:13 +01002557 /* Clear openssl global errors stack */
2558 ERR_clear_error();
2559
Emeric Brun46591952012-05-18 15:47:34 +02002560 conn->flags |= CO_FL_ERROR;
2561 return done;
2562}
2563
Emeric Brun46591952012-05-18 15:47:34 +02002564static void ssl_sock_close(struct connection *conn) {
2565
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02002566 if (conn->xprt_ctx) {
2567 SSL_free(conn->xprt_ctx);
2568 conn->xprt_ctx = NULL;
Willy Tarreau403edff2012-09-06 11:58:37 +02002569 sslconns--;
Emeric Brun46591952012-05-18 15:47:34 +02002570 }
Emeric Brun46591952012-05-18 15:47:34 +02002571}
2572
2573/* This function tries to perform a clean shutdown on an SSL connection, and in
2574 * any case, flags the connection as reusable if no handshake was in progress.
2575 */
2576static void ssl_sock_shutw(struct connection *conn, int clean)
2577{
2578 if (conn->flags & CO_FL_HANDSHAKE)
2579 return;
2580 /* no handshake was in progress, try a clean ssl shutdown */
Emeric Brun644cde02012-12-14 11:21:13 +01002581 if (clean && (SSL_shutdown(conn->xprt_ctx) <= 0)) {
2582 /* Clear openssl global errors stack */
2583 ERR_clear_error();
2584 }
Emeric Brun46591952012-05-18 15:47:34 +02002585
2586 /* force flag on ssl to keep session in cache regardless shutdown result */
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02002587 SSL_set_shutdown(conn->xprt_ctx, SSL_SENT_SHUTDOWN);
Emeric Brun46591952012-05-18 15:47:34 +02002588}
2589
Willy Tarreauffc3fcd2012-10-12 20:17:54 +02002590/* used for logging, may be changed for a sample fetch later */
2591const char *ssl_sock_get_cipher_name(struct connection *conn)
2592{
2593 if (!conn->xprt && !conn->xprt_ctx)
2594 return NULL;
2595 return SSL_get_cipher_name(conn->xprt_ctx);
2596}
2597
2598/* used for logging, may be changed for a sample fetch later */
2599const char *ssl_sock_get_proto_version(struct connection *conn)
2600{
2601 if (!conn->xprt && !conn->xprt_ctx)
2602 return NULL;
2603 return SSL_get_version(conn->xprt_ctx);
2604}
2605
Willy Tarreau8d598402012-10-22 17:58:39 +02002606/* Extract a serial from a cert, and copy it to a chunk.
2607 * Returns 1 if serial is found and copied, 0 if no serial found and
2608 * -1 if output is not large enough.
2609 */
2610static int
2611ssl_sock_get_serial(X509 *crt, struct chunk *out)
2612{
2613 ASN1_INTEGER *serial;
2614
2615 serial = X509_get_serialNumber(crt);
2616 if (!serial)
2617 return 0;
2618
2619 if (out->size < serial->length)
2620 return -1;
2621
2622 memcpy(out->str, serial->data, serial->length);
2623 out->len = serial->length;
2624 return 1;
2625}
2626
Emeric Brun43e79582014-10-29 19:03:26 +01002627/* Extract a cert to der, and copy it to a chunk.
2628 * Returns 1 if cert is found and copied, 0 on der convertion failure and
2629 * -1 if output is not large enough.
2630 */
2631static int
2632ssl_sock_crt2der(X509 *crt, struct chunk *out)
2633{
2634 int len;
2635 unsigned char *p = (unsigned char *)out->str;;
2636
2637 len =i2d_X509(crt, NULL);
2638 if (len <= 0)
2639 return 1;
2640
2641 if (out->size < len)
2642 return -1;
2643
2644 i2d_X509(crt,&p);
2645 out->len = len;
2646 return 1;
2647}
2648
Emeric Brunce5ad802012-10-22 14:11:22 +02002649
2650/* Copy Date in ASN1_UTCTIME format in struct chunk out.
2651 * Returns 1 if serial is found and copied, 0 if no valid time found
2652 * and -1 if output is not large enough.
2653 */
2654static int
2655ssl_sock_get_time(ASN1_TIME *tm, struct chunk *out)
2656{
2657 if (tm->type == V_ASN1_GENERALIZEDTIME) {
2658 ASN1_GENERALIZEDTIME *gentm = (ASN1_GENERALIZEDTIME *)tm;
2659
2660 if (gentm->length < 12)
2661 return 0;
2662 if (gentm->data[0] != 0x32 || gentm->data[1] != 0x30)
2663 return 0;
2664 if (out->size < gentm->length-2)
2665 return -1;
2666
2667 memcpy(out->str, gentm->data+2, gentm->length-2);
2668 out->len = gentm->length-2;
2669 return 1;
2670 }
2671 else if (tm->type == V_ASN1_UTCTIME) {
2672 ASN1_UTCTIME *utctm = (ASN1_UTCTIME *)tm;
2673
2674 if (utctm->length < 10)
2675 return 0;
2676 if (utctm->data[0] >= 0x35)
2677 return 0;
2678 if (out->size < utctm->length)
2679 return -1;
2680
2681 memcpy(out->str, utctm->data, utctm->length);
2682 out->len = utctm->length;
2683 return 1;
2684 }
2685
2686 return 0;
2687}
2688
Emeric Brun87855892012-10-17 17:39:35 +02002689/* Extract an entry from a X509_NAME and copy its value to an output chunk.
2690 * Returns 1 if entry found, 0 if entry not found, or -1 if output not large enough.
2691 */
2692static int
2693ssl_sock_get_dn_entry(X509_NAME *a, const struct chunk *entry, int pos, struct chunk *out)
2694{
2695 X509_NAME_ENTRY *ne;
2696 int i, j, n;
2697 int cur = 0;
2698 const char *s;
2699 char tmp[128];
2700
2701 out->len = 0;
2702 for (i = 0; i < sk_X509_NAME_ENTRY_num(a->entries); i++) {
2703 if (pos < 0)
2704 j = (sk_X509_NAME_ENTRY_num(a->entries)-1) - i;
2705 else
2706 j = i;
2707
2708 ne = sk_X509_NAME_ENTRY_value(a->entries, j);
2709 n = OBJ_obj2nid(ne->object);
2710 if ((n == NID_undef) || ((s = OBJ_nid2sn(n)) == NULL)) {
2711 i2t_ASN1_OBJECT(tmp, sizeof(tmp), ne->object);
2712 s = tmp;
2713 }
2714
2715 if (chunk_strcasecmp(entry, s) != 0)
2716 continue;
2717
2718 if (pos < 0)
2719 cur--;
2720 else
2721 cur++;
2722
2723 if (cur != pos)
2724 continue;
2725
2726 if (ne->value->length > out->size)
2727 return -1;
2728
2729 memcpy(out->str, ne->value->data, ne->value->length);
2730 out->len = ne->value->length;
2731 return 1;
2732 }
2733
2734 return 0;
2735
2736}
2737
2738/* Extract and format full DN from a X509_NAME and copy result into a chunk
2739 * Returns 1 if dn entries exits, 0 if no dn entry found or -1 if output is not large enough.
2740 */
2741static int
2742ssl_sock_get_dn_oneline(X509_NAME *a, struct chunk *out)
2743{
2744 X509_NAME_ENTRY *ne;
2745 int i, n, ln;
2746 int l = 0;
2747 const char *s;
2748 char *p;
2749 char tmp[128];
2750
2751 out->len = 0;
2752 p = out->str;
2753 for (i = 0; i < sk_X509_NAME_ENTRY_num(a->entries); i++) {
2754 ne = sk_X509_NAME_ENTRY_value(a->entries, i);
2755 n = OBJ_obj2nid(ne->object);
2756 if ((n == NID_undef) || ((s = OBJ_nid2sn(n)) == NULL)) {
2757 i2t_ASN1_OBJECT(tmp, sizeof(tmp), ne->object);
2758 s = tmp;
2759 }
2760 ln = strlen(s);
2761
2762 l += 1 + ln + 1 + ne->value->length;
2763 if (l > out->size)
2764 return -1;
2765 out->len = l;
2766
2767 *(p++)='/';
2768 memcpy(p, s, ln);
2769 p += ln;
2770 *(p++)='=';
2771 memcpy(p, ne->value->data, ne->value->length);
2772 p += ne->value->length;
2773 }
2774
2775 if (!out->len)
2776 return 0;
2777
2778 return 1;
2779}
2780
David Safb76832014-05-08 23:42:08 -04002781char *ssl_sock_get_version(struct connection *conn)
2782{
2783 if (!ssl_sock_is_ssl(conn))
2784 return NULL;
2785
2786 return (char *)SSL_get_version(conn->xprt_ctx);
2787}
2788
Emeric Brun0abf8362014-06-24 18:26:41 +02002789/* Extract peer certificate's common name into the chunk dest
2790 * Returns
2791 * the len of the extracted common name
2792 * or 0 if no CN found in DN
2793 * or -1 on error case (i.e. no peer certificate)
2794 */
2795int ssl_sock_get_remote_common_name(struct connection *conn, struct chunk *dest)
David Safb76832014-05-08 23:42:08 -04002796{
2797 X509 *crt = NULL;
2798 X509_NAME *name;
David Safb76832014-05-08 23:42:08 -04002799 const char find_cn[] = "CN";
2800 const struct chunk find_cn_chunk = {
2801 .str = (char *)&find_cn,
2802 .len = sizeof(find_cn)-1
2803 };
Emeric Brun0abf8362014-06-24 18:26:41 +02002804 int result = -1;
David Safb76832014-05-08 23:42:08 -04002805
2806 if (!ssl_sock_is_ssl(conn))
Emeric Brun0abf8362014-06-24 18:26:41 +02002807 goto out;
David Safb76832014-05-08 23:42:08 -04002808
2809 /* SSL_get_peer_certificate, it increase X509 * ref count */
2810 crt = SSL_get_peer_certificate(conn->xprt_ctx);
2811 if (!crt)
2812 goto out;
2813
2814 name = X509_get_subject_name(crt);
2815 if (!name)
2816 goto out;
David Safb76832014-05-08 23:42:08 -04002817
Emeric Brun0abf8362014-06-24 18:26:41 +02002818 result = ssl_sock_get_dn_entry(name, &find_cn_chunk, 1, dest);
2819out:
David Safb76832014-05-08 23:42:08 -04002820 if (crt)
2821 X509_free(crt);
2822
2823 return result;
2824}
2825
Dave McCowan328fb582014-07-30 10:39:13 -04002826/* returns 1 if client passed a certificate for this session, 0 if not */
2827int ssl_sock_get_cert_used_sess(struct connection *conn)
2828{
2829 X509 *crt = NULL;
2830
2831 if (!ssl_sock_is_ssl(conn))
2832 return 0;
2833
2834 /* SSL_get_peer_certificate, it increase X509 * ref count */
2835 crt = SSL_get_peer_certificate(conn->xprt_ctx);
2836 if (!crt)
2837 return 0;
2838
2839 X509_free(crt);
2840 return 1;
2841}
2842
2843/* returns 1 if client passed a certificate for this connection, 0 if not */
2844int ssl_sock_get_cert_used_conn(struct connection *conn)
David Safb76832014-05-08 23:42:08 -04002845{
2846 if (!ssl_sock_is_ssl(conn))
2847 return 0;
2848
2849 return SSL_SOCK_ST_FL_VERIFY_DONE & conn->xprt_st ? 1 : 0;
2850}
2851
2852/* returns result from SSL verify */
2853unsigned int ssl_sock_get_verify_result(struct connection *conn)
2854{
2855 if (!ssl_sock_is_ssl(conn))
2856 return (unsigned int)X509_V_ERR_APPLICATION_VERIFICATION;
2857
2858 return (unsigned int)SSL_get_verify_result(conn->xprt_ctx);
2859}
2860
Willy Tarreau7875d092012-09-10 08:20:03 +02002861/***** Below are some sample fetching functions for ACL/patterns *****/
2862
Emeric Brune64aef12012-09-21 13:15:06 +02002863/* boolean, returns true if client cert was present */
2864static int
Emeric Brun2525b6b2012-10-18 15:59:43 +02002865smp_fetch_ssl_fc_has_crt(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002866 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brune64aef12012-09-21 13:15:06 +02002867{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002868 struct connection *conn;
2869
2870 if (!l4)
2871 return 0;
2872
2873 conn = objt_conn(l4->si[0].end);
2874 if (!conn || conn->xprt != &ssl_sock)
Emeric Brune64aef12012-09-21 13:15:06 +02002875 return 0;
2876
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002877 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brune64aef12012-09-21 13:15:06 +02002878 smp->flags |= SMP_F_MAY_CHANGE;
2879 return 0;
2880 }
2881
2882 smp->flags = 0;
2883 smp->type = SMP_T_BOOL;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002884 smp->data.uint = SSL_SOCK_ST_FL_VERIFY_DONE & conn->xprt_st ? 1 : 0;
Emeric Brune64aef12012-09-21 13:15:06 +02002885
2886 return 1;
2887}
2888
Emeric Brun43e79582014-10-29 19:03:26 +01002889/* binary, returns a certificate in a binary chunk (der/raw).
2890 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
2891 * should be use.
2892 */
2893static int
2894smp_fetch_ssl_x_der(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
2895 const struct arg *args, struct sample *smp, const char *kw)
2896{
2897 int cert_peer = (kw[4] == 'c') ? 1 : 0;
2898 X509 *crt = NULL;
2899 int ret = 0;
2900 struct chunk *smp_trash;
2901 struct connection *conn;
2902
2903 if (!l4)
2904 return 0;
2905
2906 conn = objt_conn(l4->si[0].end);
2907 if (!conn || conn->xprt != &ssl_sock)
2908 return 0;
2909
2910 if (!(conn->flags & CO_FL_CONNECTED)) {
2911 smp->flags |= SMP_F_MAY_CHANGE;
2912 return 0;
2913 }
2914
2915 if (cert_peer)
2916 crt = SSL_get_peer_certificate(conn->xprt_ctx);
2917 else
2918 crt = SSL_get_certificate(conn->xprt_ctx);
2919
2920 if (!crt)
2921 goto out;
2922
2923 smp_trash = get_trash_chunk();
2924 if (ssl_sock_crt2der(crt, smp_trash) <= 0)
2925 goto out;
2926
2927 smp->data.str = *smp_trash;
2928 smp->type = SMP_T_BIN;
2929 ret = 1;
2930out:
2931 /* SSL_get_peer_certificate, it increase X509 * ref count */
2932 if (cert_peer && crt)
2933 X509_free(crt);
2934 return ret;
2935}
2936
Emeric Brunba841a12014-04-30 17:05:08 +02002937/* binary, returns serial of certificate in a binary chunk.
2938 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
2939 * should be use.
2940 */
Willy Tarreau8d598402012-10-22 17:58:39 +02002941static int
Emeric Brunba841a12014-04-30 17:05:08 +02002942smp_fetch_ssl_x_serial(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002943 const struct arg *args, struct sample *smp, const char *kw)
Willy Tarreau8d598402012-10-22 17:58:39 +02002944{
Emeric Brunba841a12014-04-30 17:05:08 +02002945 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Willy Tarreau8d598402012-10-22 17:58:39 +02002946 X509 *crt = NULL;
2947 int ret = 0;
2948 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002949 struct connection *conn;
2950
2951 if (!l4)
2952 return 0;
Willy Tarreau8d598402012-10-22 17:58:39 +02002953
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002954 conn = objt_conn(l4->si[0].end);
2955 if (!conn || conn->xprt != &ssl_sock)
Willy Tarreau8d598402012-10-22 17:58:39 +02002956 return 0;
2957
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002958 if (!(conn->flags & CO_FL_CONNECTED)) {
Willy Tarreau8d598402012-10-22 17:58:39 +02002959 smp->flags |= SMP_F_MAY_CHANGE;
2960 return 0;
2961 }
2962
Emeric Brunba841a12014-04-30 17:05:08 +02002963 if (cert_peer)
2964 crt = SSL_get_peer_certificate(conn->xprt_ctx);
2965 else
2966 crt = SSL_get_certificate(conn->xprt_ctx);
2967
Willy Tarreau8d598402012-10-22 17:58:39 +02002968 if (!crt)
2969 goto out;
2970
Willy Tarreau47ca5452012-12-23 20:22:19 +01002971 smp_trash = get_trash_chunk();
Willy Tarreau8d598402012-10-22 17:58:39 +02002972 if (ssl_sock_get_serial(crt, smp_trash) <= 0)
2973 goto out;
2974
2975 smp->data.str = *smp_trash;
2976 smp->type = SMP_T_BIN;
2977 ret = 1;
2978out:
Emeric Brunba841a12014-04-30 17:05:08 +02002979 /* SSL_get_peer_certificate, it increase X509 * ref count */
2980 if (cert_peer && crt)
Willy Tarreau8d598402012-10-22 17:58:39 +02002981 X509_free(crt);
2982 return ret;
2983}
Emeric Brune64aef12012-09-21 13:15:06 +02002984
Emeric Brunba841a12014-04-30 17:05:08 +02002985/* binary, returns the client certificate's SHA-1 fingerprint (SHA-1 hash of DER-encoded certificate) in a binary chunk.
2986 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
2987 * should be use.
2988 */
James Votha051b4a2013-05-14 20:37:59 +02002989static int
Emeric Brunba841a12014-04-30 17:05:08 +02002990smp_fetch_ssl_x_sha1(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002991 const struct arg *args, struct sample *smp, const char *kw)
James Votha051b4a2013-05-14 20:37:59 +02002992{
Emeric Brunba841a12014-04-30 17:05:08 +02002993 int cert_peer = (kw[4] == 'c') ? 1 : 0;
James Votha051b4a2013-05-14 20:37:59 +02002994 X509 *crt = NULL;
2995 const EVP_MD *digest;
2996 int ret = 0;
2997 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002998 struct connection *conn;
James Votha051b4a2013-05-14 20:37:59 +02002999
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003000 if (!l4)
James Votha051b4a2013-05-14 20:37:59 +02003001 return 0;
3002
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003003 conn = objt_conn(l4->si[0].end);
3004 if (!conn || conn->xprt != &ssl_sock)
3005 return 0;
3006
3007 if (!(conn->flags & CO_FL_CONNECTED)) {
James Votha051b4a2013-05-14 20:37:59 +02003008 smp->flags |= SMP_F_MAY_CHANGE;
3009 return 0;
3010 }
3011
Emeric Brunba841a12014-04-30 17:05:08 +02003012 if (cert_peer)
3013 crt = SSL_get_peer_certificate(conn->xprt_ctx);
3014 else
3015 crt = SSL_get_certificate(conn->xprt_ctx);
James Votha051b4a2013-05-14 20:37:59 +02003016 if (!crt)
3017 goto out;
3018
3019 smp_trash = get_trash_chunk();
3020 digest = EVP_sha1();
3021 X509_digest(crt, digest, (unsigned char *)smp_trash->str, (unsigned int *)&smp_trash->len);
3022
3023 smp->data.str = *smp_trash;
3024 smp->type = SMP_T_BIN;
3025 ret = 1;
3026out:
Emeric Brunba841a12014-04-30 17:05:08 +02003027 /* SSL_get_peer_certificate, it increase X509 * ref count */
3028 if (cert_peer && crt)
James Votha051b4a2013-05-14 20:37:59 +02003029 X509_free(crt);
3030 return ret;
3031}
3032
Emeric Brunba841a12014-04-30 17:05:08 +02003033/* string, returns certificate's notafter date in ASN1_UTCTIME format.
3034 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
3035 * should be use.
3036 */
Emeric Brunce5ad802012-10-22 14:11:22 +02003037static int
Emeric Brunba841a12014-04-30 17:05:08 +02003038smp_fetch_ssl_x_notafter(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003039 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brunce5ad802012-10-22 14:11:22 +02003040{
Emeric Brunba841a12014-04-30 17:05:08 +02003041 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brunce5ad802012-10-22 14:11:22 +02003042 X509 *crt = NULL;
3043 int ret = 0;
3044 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003045 struct connection *conn;
Emeric Brunce5ad802012-10-22 14:11:22 +02003046
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003047 if (!l4)
Emeric Brunce5ad802012-10-22 14:11:22 +02003048 return 0;
3049
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003050 conn = objt_conn(l4->si[0].end);
3051 if (!conn || conn->xprt != &ssl_sock)
3052 return 0;
3053
3054 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunce5ad802012-10-22 14:11:22 +02003055 smp->flags |= SMP_F_MAY_CHANGE;
3056 return 0;
3057 }
3058
Emeric Brunba841a12014-04-30 17:05:08 +02003059 if (cert_peer)
3060 crt = SSL_get_peer_certificate(conn->xprt_ctx);
3061 else
3062 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brunce5ad802012-10-22 14:11:22 +02003063 if (!crt)
3064 goto out;
3065
Willy Tarreau47ca5452012-12-23 20:22:19 +01003066 smp_trash = get_trash_chunk();
Emeric Brunce5ad802012-10-22 14:11:22 +02003067 if (ssl_sock_get_time(X509_get_notAfter(crt), smp_trash) <= 0)
3068 goto out;
3069
3070 smp->data.str = *smp_trash;
3071 smp->type = SMP_T_STR;
3072 ret = 1;
3073out:
Emeric Brunba841a12014-04-30 17:05:08 +02003074 /* SSL_get_peer_certificate, it increase X509 * ref count */
3075 if (cert_peer && crt)
Emeric Brunce5ad802012-10-22 14:11:22 +02003076 X509_free(crt);
3077 return ret;
3078}
3079
Emeric Brunba841a12014-04-30 17:05:08 +02003080/* string, returns a string of a formatted full dn \C=..\O=..\OU=.. \CN=.. of certificate's issuer
3081 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
3082 * should be use.
3083 */
Emeric Brun87855892012-10-17 17:39:35 +02003084static int
Emeric Brunba841a12014-04-30 17:05:08 +02003085smp_fetch_ssl_x_i_dn(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003086 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brun87855892012-10-17 17:39:35 +02003087{
Emeric Brunba841a12014-04-30 17:05:08 +02003088 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brun87855892012-10-17 17:39:35 +02003089 X509 *crt = NULL;
3090 X509_NAME *name;
3091 int ret = 0;
3092 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003093 struct connection *conn;
Emeric Brun87855892012-10-17 17:39:35 +02003094
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003095 if (!l4)
Emeric Brun87855892012-10-17 17:39:35 +02003096 return 0;
3097
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003098 conn = objt_conn(l4->si[0].end);
3099 if (!conn || conn->xprt != &ssl_sock)
3100 return 0;
3101
3102 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun87855892012-10-17 17:39:35 +02003103 smp->flags |= SMP_F_MAY_CHANGE;
3104 return 0;
3105 }
3106
Emeric Brunba841a12014-04-30 17:05:08 +02003107 if (cert_peer)
3108 crt = SSL_get_peer_certificate(conn->xprt_ctx);
3109 else
3110 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brun87855892012-10-17 17:39:35 +02003111 if (!crt)
3112 goto out;
3113
3114 name = X509_get_issuer_name(crt);
3115 if (!name)
3116 goto out;
3117
Willy Tarreau47ca5452012-12-23 20:22:19 +01003118 smp_trash = get_trash_chunk();
Emeric Brun87855892012-10-17 17:39:35 +02003119 if (args && args[0].type == ARGT_STR) {
3120 int pos = 1;
3121
3122 if (args[1].type == ARGT_SINT)
3123 pos = args[1].data.sint;
3124 else if (args[1].type == ARGT_UINT)
3125 pos =(int)args[1].data.uint;
3126
3127 if (ssl_sock_get_dn_entry(name, &args[0].data.str, pos, smp_trash) <= 0)
3128 goto out;
3129 }
3130 else if (ssl_sock_get_dn_oneline(name, smp_trash) <= 0)
3131 goto out;
3132
3133 smp->type = SMP_T_STR;
3134 smp->data.str = *smp_trash;
3135 ret = 1;
3136out:
Emeric Brunba841a12014-04-30 17:05:08 +02003137 /* SSL_get_peer_certificate, it increase X509 * ref count */
3138 if (cert_peer && crt)
Emeric Brun87855892012-10-17 17:39:35 +02003139 X509_free(crt);
3140 return ret;
3141}
3142
Emeric Brunba841a12014-04-30 17:05:08 +02003143/* string, returns notbefore date in ASN1_UTCTIME format.
3144 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
3145 * should be use.
3146 */
Emeric Brunce5ad802012-10-22 14:11:22 +02003147static int
Emeric Brunba841a12014-04-30 17:05:08 +02003148smp_fetch_ssl_x_notbefore(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003149 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brunce5ad802012-10-22 14:11:22 +02003150{
Emeric Brunba841a12014-04-30 17:05:08 +02003151 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brunce5ad802012-10-22 14:11:22 +02003152 X509 *crt = NULL;
3153 int ret = 0;
3154 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003155 struct connection *conn;
3156
3157 if (!l4)
3158 return 0;
Emeric Brunce5ad802012-10-22 14:11:22 +02003159
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003160 conn = objt_conn(l4->si[0].end);
3161 if (!conn || conn->xprt != &ssl_sock)
Emeric Brunce5ad802012-10-22 14:11:22 +02003162 return 0;
3163
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003164 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunce5ad802012-10-22 14:11:22 +02003165 smp->flags |= SMP_F_MAY_CHANGE;
3166 return 0;
3167 }
3168
Emeric Brunba841a12014-04-30 17:05:08 +02003169 if (cert_peer)
3170 crt = SSL_get_peer_certificate(conn->xprt_ctx);
3171 else
3172 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brunce5ad802012-10-22 14:11:22 +02003173 if (!crt)
3174 goto out;
3175
Willy Tarreau47ca5452012-12-23 20:22:19 +01003176 smp_trash = get_trash_chunk();
Emeric Brunce5ad802012-10-22 14:11:22 +02003177 if (ssl_sock_get_time(X509_get_notBefore(crt), smp_trash) <= 0)
3178 goto out;
3179
3180 smp->data.str = *smp_trash;
3181 smp->type = SMP_T_STR;
3182 ret = 1;
3183out:
Emeric Brunba841a12014-04-30 17:05:08 +02003184 /* SSL_get_peer_certificate, it increase X509 * ref count */
3185 if (cert_peer && crt)
Emeric Brunce5ad802012-10-22 14:11:22 +02003186 X509_free(crt);
3187 return ret;
3188}
3189
Emeric Brunba841a12014-04-30 17:05:08 +02003190/* string, returns a string of a formatted full dn \C=..\O=..\OU=.. \CN=.. of certificate's subject
3191 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
3192 * should be use.
3193 */
Emeric Brun87855892012-10-17 17:39:35 +02003194static int
Emeric Brunba841a12014-04-30 17:05:08 +02003195smp_fetch_ssl_x_s_dn(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003196 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brun87855892012-10-17 17:39:35 +02003197{
Emeric Brunba841a12014-04-30 17:05:08 +02003198 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brun87855892012-10-17 17:39:35 +02003199 X509 *crt = NULL;
3200 X509_NAME *name;
3201 int ret = 0;
3202 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003203 struct connection *conn;
Emeric Brun87855892012-10-17 17:39:35 +02003204
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003205 if (!l4)
Emeric Brun87855892012-10-17 17:39:35 +02003206 return 0;
3207
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003208 conn = objt_conn(l4->si[0].end);
3209 if (!conn || conn->xprt != &ssl_sock)
3210 return 0;
3211
3212 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun87855892012-10-17 17:39:35 +02003213 smp->flags |= SMP_F_MAY_CHANGE;
3214 return 0;
3215 }
3216
Emeric Brunba841a12014-04-30 17:05:08 +02003217 if (cert_peer)
3218 crt = SSL_get_peer_certificate(conn->xprt_ctx);
3219 else
3220 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brun87855892012-10-17 17:39:35 +02003221 if (!crt)
3222 goto out;
3223
3224 name = X509_get_subject_name(crt);
3225 if (!name)
3226 goto out;
3227
Willy Tarreau47ca5452012-12-23 20:22:19 +01003228 smp_trash = get_trash_chunk();
Emeric Brun87855892012-10-17 17:39:35 +02003229 if (args && args[0].type == ARGT_STR) {
3230 int pos = 1;
3231
3232 if (args[1].type == ARGT_SINT)
3233 pos = args[1].data.sint;
3234 else if (args[1].type == ARGT_UINT)
3235 pos =(int)args[1].data.uint;
3236
3237 if (ssl_sock_get_dn_entry(name, &args[0].data.str, pos, smp_trash) <= 0)
3238 goto out;
3239 }
3240 else if (ssl_sock_get_dn_oneline(name, smp_trash) <= 0)
3241 goto out;
3242
3243 smp->type = SMP_T_STR;
3244 smp->data.str = *smp_trash;
3245 ret = 1;
3246out:
Emeric Brunba841a12014-04-30 17:05:08 +02003247 /* SSL_get_peer_certificate, it increase X509 * ref count */
3248 if (cert_peer && crt)
Emeric Brun87855892012-10-17 17:39:35 +02003249 X509_free(crt);
3250 return ret;
3251}
Emeric Brun9143d372012-12-20 15:44:16 +01003252
3253/* integer, returns true if current session use a client certificate */
3254static int
3255smp_fetch_ssl_c_used(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003256 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brun9143d372012-12-20 15:44:16 +01003257{
3258 X509 *crt;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003259 struct connection *conn;
Emeric Brun9143d372012-12-20 15:44:16 +01003260
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003261 if (!l4)
Emeric Brun9143d372012-12-20 15:44:16 +01003262 return 0;
3263
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003264 conn = objt_conn(l4->si[0].end);
3265 if (!conn || conn->xprt != &ssl_sock)
3266 return 0;
3267
3268 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun9143d372012-12-20 15:44:16 +01003269 smp->flags |= SMP_F_MAY_CHANGE;
3270 return 0;
3271 }
3272
3273 /* SSL_get_peer_certificate returns a ptr on allocated X509 struct */
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003274 crt = SSL_get_peer_certificate(conn->xprt_ctx);
Emeric Brun9143d372012-12-20 15:44:16 +01003275 if (crt) {
3276 X509_free(crt);
3277 }
3278
3279 smp->type = SMP_T_BOOL;
3280 smp->data.uint = (crt != NULL);
3281 return 1;
3282}
3283
Emeric Brunba841a12014-04-30 17:05:08 +02003284/* integer, returns the certificate version
3285 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
3286 * should be use.
3287 */
Emeric Bruna7359fd2012-10-17 15:03:11 +02003288static int
Emeric Brunba841a12014-04-30 17:05:08 +02003289smp_fetch_ssl_x_version(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003290 const struct arg *args, struct sample *smp, const char *kw)
Emeric Bruna7359fd2012-10-17 15:03:11 +02003291{
Emeric Brunba841a12014-04-30 17:05:08 +02003292 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Bruna7359fd2012-10-17 15:03:11 +02003293 X509 *crt;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003294 struct connection *conn;
3295
3296 if (!l4)
3297 return 0;
Emeric Bruna7359fd2012-10-17 15:03:11 +02003298
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003299 conn = objt_conn(l4->si[0].end);
3300 if (!conn || conn->xprt != &ssl_sock)
Emeric Bruna7359fd2012-10-17 15:03:11 +02003301 return 0;
3302
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003303 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Bruna7359fd2012-10-17 15:03:11 +02003304 smp->flags |= SMP_F_MAY_CHANGE;
3305 return 0;
3306 }
3307
Emeric Brunba841a12014-04-30 17:05:08 +02003308 if (cert_peer)
3309 crt = SSL_get_peer_certificate(conn->xprt_ctx);
3310 else
3311 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Bruna7359fd2012-10-17 15:03:11 +02003312 if (!crt)
3313 return 0;
3314
3315 smp->data.uint = (unsigned int)(1 + X509_get_version(crt));
Emeric Brunba841a12014-04-30 17:05:08 +02003316 /* SSL_get_peer_certificate increase X509 * ref count */
3317 if (cert_peer)
3318 X509_free(crt);
Emeric Bruna7359fd2012-10-17 15:03:11 +02003319 smp->type = SMP_T_UINT;
3320
3321 return 1;
3322}
3323
Emeric Brunba841a12014-04-30 17:05:08 +02003324/* string, returns the certificate's signature algorithm.
3325 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
3326 * should be use.
3327 */
Emeric Brun7f56e742012-10-19 18:15:40 +02003328static int
Emeric Brunba841a12014-04-30 17:05:08 +02003329smp_fetch_ssl_x_sig_alg(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003330 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brun7f56e742012-10-19 18:15:40 +02003331{
Emeric Brunba841a12014-04-30 17:05:08 +02003332 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brun7f56e742012-10-19 18:15:40 +02003333 X509 *crt;
3334 int nid;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003335 struct connection *conn;
Emeric Brun7f56e742012-10-19 18:15:40 +02003336
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003337 if (!l4)
Emeric Brun7f56e742012-10-19 18:15:40 +02003338 return 0;
3339
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003340 conn = objt_conn(l4->si[0].end);
3341 if (!conn || conn->xprt != &ssl_sock)
3342 return 0;
3343
3344 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun7f56e742012-10-19 18:15:40 +02003345 smp->flags |= SMP_F_MAY_CHANGE;
3346 return 0;
3347 }
3348
Emeric Brunba841a12014-04-30 17:05:08 +02003349 if (cert_peer)
3350 crt = SSL_get_peer_certificate(conn->xprt_ctx);
3351 else
3352 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brun7f56e742012-10-19 18:15:40 +02003353 if (!crt)
3354 return 0;
3355
3356 nid = OBJ_obj2nid((ASN1_OBJECT *)(crt->cert_info->signature->algorithm));
3357
3358 smp->data.str.str = (char *)OBJ_nid2sn(nid);
Emeric Brun9bf3ba22013-10-07 14:31:44 +02003359 if (!smp->data.str.str) {
Emeric Brunba841a12014-04-30 17:05:08 +02003360 /* SSL_get_peer_certificate increase X509 * ref count */
3361 if (cert_peer)
3362 X509_free(crt);
Emeric Brun7f56e742012-10-19 18:15:40 +02003363 return 0;
Emeric Brun9bf3ba22013-10-07 14:31:44 +02003364 }
Emeric Brun7f56e742012-10-19 18:15:40 +02003365
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01003366 smp->type = SMP_T_STR;
3367 smp->flags |= SMP_F_CONST;
Emeric Brun7f56e742012-10-19 18:15:40 +02003368 smp->data.str.len = strlen(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
3373 return 1;
3374}
3375
Emeric Brunba841a12014-04-30 17:05:08 +02003376/* string, returns the certificate's key algorithm.
3377 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
3378 * should be use.
3379 */
Emeric Brun521a0112012-10-22 12:22:55 +02003380static int
Emeric Brunba841a12014-04-30 17:05:08 +02003381smp_fetch_ssl_x_key_alg(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003382 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brun521a0112012-10-22 12:22:55 +02003383{
Emeric Brunba841a12014-04-30 17:05:08 +02003384 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brun521a0112012-10-22 12:22:55 +02003385 X509 *crt;
3386 int nid;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003387 struct connection *conn;
Emeric Brun521a0112012-10-22 12:22:55 +02003388
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003389 if (!l4)
Emeric Brun521a0112012-10-22 12:22:55 +02003390 return 0;
3391
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003392 conn = objt_conn(l4->si[0].end);
3393 if (!conn || conn->xprt != &ssl_sock)
3394 return 0;
3395
3396 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun521a0112012-10-22 12:22:55 +02003397 smp->flags |= SMP_F_MAY_CHANGE;
3398 return 0;
3399 }
3400
Emeric Brunba841a12014-04-30 17:05:08 +02003401 if (cert_peer)
3402 crt = SSL_get_peer_certificate(conn->xprt_ctx);
3403 else
3404 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brun521a0112012-10-22 12:22:55 +02003405 if (!crt)
3406 return 0;
3407
3408 nid = OBJ_obj2nid((ASN1_OBJECT *)(crt->cert_info->key->algor->algorithm));
3409
3410 smp->data.str.str = (char *)OBJ_nid2sn(nid);
Emeric Brun9bf3ba22013-10-07 14:31:44 +02003411 if (!smp->data.str.str) {
Emeric Brunba841a12014-04-30 17:05:08 +02003412 /* SSL_get_peer_certificate increase X509 * ref count */
3413 if (cert_peer)
3414 X509_free(crt);
Emeric Brun521a0112012-10-22 12:22:55 +02003415 return 0;
Emeric Brun9bf3ba22013-10-07 14:31:44 +02003416 }
Emeric Brun521a0112012-10-22 12:22:55 +02003417
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01003418 smp->type = SMP_T_STR;
3419 smp->flags |= SMP_F_CONST;
Emeric Brun521a0112012-10-22 12:22:55 +02003420 smp->data.str.len = strlen(smp->data.str.str);
Emeric Brunba841a12014-04-30 17:05:08 +02003421 if (cert_peer)
3422 X509_free(crt);
Emeric Brun521a0112012-10-22 12:22:55 +02003423
3424 return 1;
3425}
3426
Emeric Brun645ae792014-04-30 14:21:06 +02003427/* boolean, returns true if front conn. transport layer is SSL.
3428 * This function is also usable on backend conn if the fetch keyword 5th
3429 * char is 'b'.
3430 */
Willy Tarreau7875d092012-09-10 08:20:03 +02003431static int
Emeric Brun2525b6b2012-10-18 15:59:43 +02003432smp_fetch_ssl_fc(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003433 const struct arg *args, struct sample *smp, const char *kw)
Willy Tarreau7875d092012-09-10 08:20:03 +02003434{
Emeric Brun645ae792014-04-30 14:21:06 +02003435 int back_conn = (kw[4] == 'b') ? 1 : 0;
3436 struct connection *conn = objt_conn(l4->si[back_conn].end);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003437
Willy Tarreau7875d092012-09-10 08:20:03 +02003438 smp->type = SMP_T_BOOL;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003439 smp->data.uint = (conn && conn->xprt == &ssl_sock);
Willy Tarreau7875d092012-09-10 08:20:03 +02003440 return 1;
3441}
3442
Emeric Brun2525b6b2012-10-18 15:59:43 +02003443/* boolean, returns true if client present a SNI */
Willy Tarreau7875d092012-09-10 08:20:03 +02003444static int
Emeric Brun2525b6b2012-10-18 15:59:43 +02003445smp_fetch_ssl_fc_has_sni(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003446 const struct arg *args, struct sample *smp, const char *kw)
Willy Tarreau7875d092012-09-10 08:20:03 +02003447{
3448#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003449 struct connection *conn = objt_conn(l4->si[0].end);
3450
Willy Tarreau7875d092012-09-10 08:20:03 +02003451 smp->type = SMP_T_BOOL;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003452 smp->data.uint = (conn && conn->xprt == &ssl_sock) &&
3453 conn->xprt_ctx &&
3454 SSL_get_servername(conn->xprt_ctx, TLSEXT_NAMETYPE_host_name) != NULL;
Willy Tarreau7875d092012-09-10 08:20:03 +02003455 return 1;
3456#else
3457 return 0;
3458#endif
3459}
3460
Emeric Brun645ae792014-04-30 14:21:06 +02003461/* string, returns the used cipher if front conn. transport layer is SSL.
3462 * This function is also usable on backend conn if the fetch keyword 5th
3463 * char is 'b'.
3464 */
Emeric Brun589fcad2012-10-16 14:13:26 +02003465static int
3466smp_fetch_ssl_fc_cipher(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003467 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brun589fcad2012-10-16 14:13:26 +02003468{
Emeric Brun645ae792014-04-30 14:21:06 +02003469 int back_conn = (kw[4] == 'b') ? 1 : 0;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003470 struct connection *conn;
3471
Emeric Brun589fcad2012-10-16 14:13:26 +02003472 smp->flags = 0;
3473
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003474 if (!l4)
3475 return 0;
3476
Emeric Brun645ae792014-04-30 14:21:06 +02003477 conn = objt_conn(l4->si[back_conn].end);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003478 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
Emeric Brun589fcad2012-10-16 14:13:26 +02003479 return 0;
3480
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003481 smp->data.str.str = (char *)SSL_get_cipher_name(conn->xprt_ctx);
Emeric Brun589fcad2012-10-16 14:13:26 +02003482 if (!smp->data.str.str)
3483 return 0;
3484
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01003485 smp->type = SMP_T_STR;
3486 smp->flags |= SMP_F_CONST;
Emeric Brun589fcad2012-10-16 14:13:26 +02003487 smp->data.str.len = strlen(smp->data.str.str);
3488
3489 return 1;
3490}
3491
Emeric Brun645ae792014-04-30 14:21:06 +02003492/* integer, returns the algoritm's keysize if front conn. transport layer
3493 * is SSL.
3494 * This function is also usable on backend conn if the fetch keyword 5th
3495 * char is 'b'.
3496 */
Emeric Brun589fcad2012-10-16 14:13:26 +02003497static int
3498smp_fetch_ssl_fc_alg_keysize(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003499 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brun589fcad2012-10-16 14:13:26 +02003500{
Emeric Brun645ae792014-04-30 14:21:06 +02003501 int back_conn = (kw[4] == 'b') ? 1 : 0;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003502 struct connection *conn;
3503
Emeric Brun589fcad2012-10-16 14:13:26 +02003504 smp->flags = 0;
3505
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003506 if (!l4)
Emeric Brun589fcad2012-10-16 14:13:26 +02003507 return 0;
3508
Emeric Brun645ae792014-04-30 14:21:06 +02003509 conn = objt_conn(l4->si[back_conn].end);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003510 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
Emeric Brun589fcad2012-10-16 14:13:26 +02003511 return 0;
3512
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003513 if (!SSL_get_cipher_bits(conn->xprt_ctx, (int *)&smp->data.uint))
3514 return 0;
3515
Emeric Brun589fcad2012-10-16 14:13:26 +02003516 smp->type = SMP_T_UINT;
3517
3518 return 1;
3519}
3520
Emeric Brun645ae792014-04-30 14:21:06 +02003521/* integer, returns the used keysize if front conn. transport layer is SSL.
3522 * This function is also usable on backend conn if the fetch keyword 5th
3523 * char is 'b'.
3524 */
Emeric Brun589fcad2012-10-16 14:13:26 +02003525static int
3526smp_fetch_ssl_fc_use_keysize(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003527 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brun589fcad2012-10-16 14:13:26 +02003528{
Emeric Brun645ae792014-04-30 14:21:06 +02003529 int back_conn = (kw[4] == 'b') ? 1 : 0;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003530 struct connection *conn;
3531
Emeric Brun589fcad2012-10-16 14:13:26 +02003532 smp->flags = 0;
3533
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003534 if (!l4)
Emeric Brun589fcad2012-10-16 14:13:26 +02003535 return 0;
3536
Emeric Brun645ae792014-04-30 14:21:06 +02003537 conn = objt_conn(l4->si[back_conn].end);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003538 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
3539 return 0;
3540
3541 smp->data.uint = (unsigned int)SSL_get_cipher_bits(conn->xprt_ctx, NULL);
Emeric Brun589fcad2012-10-16 14:13:26 +02003542 if (!smp->data.uint)
3543 return 0;
3544
3545 smp->type = SMP_T_UINT;
3546
3547 return 1;
3548}
3549
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02003550#ifdef OPENSSL_NPN_NEGOTIATED
Willy Tarreau7875d092012-09-10 08:20:03 +02003551static int
Emeric Brun2525b6b2012-10-18 15:59:43 +02003552smp_fetch_ssl_fc_npn(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003553 const struct arg *args, struct sample *smp, const char *kw)
Willy Tarreaua33c6542012-10-15 13:19:06 +02003554{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003555 struct connection *conn;
3556
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01003557 smp->flags = SMP_F_CONST;
3558 smp->type = SMP_T_STR;
Willy Tarreaua33c6542012-10-15 13:19:06 +02003559
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003560 if (!l4)
Willy Tarreaua33c6542012-10-15 13:19:06 +02003561 return 0;
3562
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003563 conn = objt_conn(l4->si[0].end);
3564 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
3565 return 0;
3566
Willy Tarreaua33c6542012-10-15 13:19:06 +02003567 smp->data.str.str = NULL;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003568 SSL_get0_next_proto_negotiated(conn->xprt_ctx,
Willy Tarreaua33c6542012-10-15 13:19:06 +02003569 (const unsigned char **)&smp->data.str.str, (unsigned *)&smp->data.str.len);
3570
3571 if (!smp->data.str.str)
3572 return 0;
3573
3574 return 1;
Willy Tarreaua33c6542012-10-15 13:19:06 +02003575}
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02003576#endif
Willy Tarreaua33c6542012-10-15 13:19:06 +02003577
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01003578#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Willy Tarreauab861d32013-04-02 02:30:41 +02003579static int
3580smp_fetch_ssl_fc_alpn(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003581 const struct arg *args, struct sample *smp, const char *kw)
Willy Tarreauab861d32013-04-02 02:30:41 +02003582{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003583 struct connection *conn;
3584
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01003585 smp->flags = SMP_F_CONST;
3586 smp->type = SMP_T_STR;
Willy Tarreauab861d32013-04-02 02:30:41 +02003587
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003588 if (!l4)
3589 return 0;
3590
3591 conn = objt_conn(l4->si[0].end);
3592 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
Willy Tarreauab861d32013-04-02 02:30:41 +02003593 return 0;
3594
3595 smp->data.str.str = NULL;
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01003596 SSL_get0_alpn_selected(conn->xprt_ctx,
Willy Tarreauab861d32013-04-02 02:30:41 +02003597 (const unsigned char **)&smp->data.str.str, (unsigned *)&smp->data.str.len);
3598
3599 if (!smp->data.str.str)
3600 return 0;
3601
3602 return 1;
3603}
3604#endif
3605
Emeric Brun645ae792014-04-30 14:21:06 +02003606/* string, returns the used protocol if front conn. transport layer is SSL.
3607 * This function is also usable on backend conn if the fetch keyword 5th
3608 * char is 'b'.
3609 */
Willy Tarreaua33c6542012-10-15 13:19:06 +02003610static int
Emeric Brun589fcad2012-10-16 14:13:26 +02003611smp_fetch_ssl_fc_protocol(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003612 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brun589fcad2012-10-16 14:13:26 +02003613{
Emeric Brun645ae792014-04-30 14:21:06 +02003614 int back_conn = (kw[4] == 'b') ? 1 : 0;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003615 struct connection *conn;
3616
Emeric Brun589fcad2012-10-16 14:13:26 +02003617 smp->flags = 0;
3618
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003619 if (!l4)
Emeric Brun589fcad2012-10-16 14:13:26 +02003620 return 0;
3621
Emeric Brun645ae792014-04-30 14:21:06 +02003622 conn = objt_conn(l4->si[back_conn].end);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003623 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
3624 return 0;
3625
3626 smp->data.str.str = (char *)SSL_get_version(conn->xprt_ctx);
Emeric Brun589fcad2012-10-16 14:13:26 +02003627 if (!smp->data.str.str)
3628 return 0;
3629
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01003630 smp->type = SMP_T_STR;
3631 smp->flags = SMP_F_CONST;
Emeric Brun589fcad2012-10-16 14:13:26 +02003632 smp->data.str.len = strlen(smp->data.str.str);
3633
3634 return 1;
3635}
3636
Emeric Brun645ae792014-04-30 14:21:06 +02003637/* binary, returns the SSL session id if front conn. transport layer is SSL.
3638 * This function is also usable on backend conn if the fetch keyword 5th
3639 * char is 'b'.
3640 */
Emeric Brun589fcad2012-10-16 14:13:26 +02003641static int
Emeric Brunfe68f682012-10-16 14:59:28 +02003642smp_fetch_ssl_fc_session_id(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003643 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brunfe68f682012-10-16 14:59:28 +02003644{
3645#if OPENSSL_VERSION_NUMBER > 0x0090800fL
Emeric Brun645ae792014-04-30 14:21:06 +02003646 int back_conn = (kw[4] == 'b') ? 1 : 0;
Emeric Brunfe68f682012-10-16 14:59:28 +02003647 SSL_SESSION *sess;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003648 struct connection *conn;
Emeric Brunfe68f682012-10-16 14:59:28 +02003649
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01003650 smp->flags = SMP_F_CONST;
3651 smp->type = SMP_T_BIN;
Emeric Brunfe68f682012-10-16 14:59:28 +02003652
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003653 if (!l4)
Emeric Brunfe68f682012-10-16 14:59:28 +02003654 return 0;
3655
Emeric Brun645ae792014-04-30 14:21:06 +02003656 conn = objt_conn(l4->si[back_conn].end);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003657 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
3658 return 0;
3659
3660 sess = SSL_get_session(conn->xprt_ctx);
Emeric Brunfe68f682012-10-16 14:59:28 +02003661 if (!sess)
3662 return 0;
3663
3664 smp->data.str.str = (char *)SSL_SESSION_get_id(sess, (unsigned int *)&smp->data.str.len);
3665 if (!smp->data.str.str || !&smp->data.str.len)
3666 return 0;
3667
3668 return 1;
3669#else
3670 return 0;
3671#endif
3672}
3673
3674static int
Emeric Brun2525b6b2012-10-18 15:59:43 +02003675smp_fetch_ssl_fc_sni(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003676 const struct arg *args, struct sample *smp, const char *kw)
Willy Tarreau7875d092012-09-10 08:20:03 +02003677{
3678#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003679 struct connection *conn;
3680
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01003681 smp->flags = SMP_F_CONST;
3682 smp->type = SMP_T_STR;
Willy Tarreau7875d092012-09-10 08:20:03 +02003683
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003684 if (!l4)
Willy Tarreau7875d092012-09-10 08:20:03 +02003685 return 0;
3686
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003687 conn = objt_conn(l4->si[0].end);
3688 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
3689 return 0;
3690
3691 smp->data.str.str = (char *)SSL_get_servername(conn->xprt_ctx, TLSEXT_NAMETYPE_host_name);
Willy Tarreau3e394c92012-09-14 23:56:58 +02003692 if (!smp->data.str.str)
3693 return 0;
3694
Willy Tarreau7875d092012-09-10 08:20:03 +02003695 smp->data.str.len = strlen(smp->data.str.str);
3696 return 1;
3697#else
3698 return 0;
3699#endif
3700}
3701
David Sc1ad52e2014-04-08 18:48:47 -04003702static int
3703smp_fetch_ssl_fc_unique_id(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
3704 const struct arg *args, struct sample *smp, const char *kw)
3705{
3706#if OPENSSL_VERSION_NUMBER > 0x0090800fL
Emeric Brun645ae792014-04-30 14:21:06 +02003707 int back_conn = (kw[4] == 'b') ? 1 : 0;
David Sc1ad52e2014-04-08 18:48:47 -04003708 struct connection *conn;
3709 int finished_len;
David Sc1ad52e2014-04-08 18:48:47 -04003710 struct chunk *finished_trash;
David Sc1ad52e2014-04-08 18:48:47 -04003711
3712 smp->flags = 0;
3713
3714 if (!l4)
3715 return 0;
3716
Emeric Brun645ae792014-04-30 14:21:06 +02003717 conn = objt_conn(l4->si[back_conn].end);
David Sc1ad52e2014-04-08 18:48:47 -04003718 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
3719 return 0;
3720
3721 if (!(conn->flags & CO_FL_CONNECTED)) {
3722 smp->flags |= SMP_F_MAY_CHANGE;
3723 return 0;
3724 }
3725
3726 finished_trash = get_trash_chunk();
3727 if (!SSL_session_reused(conn->xprt_ctx))
3728 finished_len = SSL_get_peer_finished(conn->xprt_ctx, finished_trash->str, finished_trash->size);
3729 else
3730 finished_len = SSL_get_finished(conn->xprt_ctx, finished_trash->str, finished_trash->size);
3731
3732 if (!finished_len)
3733 return 0;
3734
Emeric Brunb73a9b02014-04-30 18:49:19 +02003735 finished_trash->len = finished_len;
3736 smp->data.str = *finished_trash;
3737 smp->type = SMP_T_BIN;
David Sc1ad52e2014-04-08 18:48:47 -04003738
3739 return 1;
3740#else
3741 return 0;
3742#endif
3743}
3744
Emeric Brun2525b6b2012-10-18 15:59:43 +02003745/* integer, returns the first verify error in CA chain of client certificate chain. */
Emeric Brunf282a812012-09-21 15:27:54 +02003746static int
Emeric Brun2525b6b2012-10-18 15:59:43 +02003747smp_fetch_ssl_c_ca_err(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003748 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brunf282a812012-09-21 15:27:54 +02003749{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003750 struct connection *conn;
3751
3752 if (!l4)
Emeric Brunf282a812012-09-21 15:27:54 +02003753 return 0;
3754
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003755 conn = objt_conn(l4->si[0].end);
3756 if (!conn || conn->xprt != &ssl_sock)
3757 return 0;
3758
3759 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunf282a812012-09-21 15:27:54 +02003760 smp->flags = SMP_F_MAY_CHANGE;
3761 return 0;
3762 }
3763
3764 smp->type = SMP_T_UINT;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003765 smp->data.uint = (unsigned int)SSL_SOCK_ST_TO_CA_ERROR(conn->xprt_st);
Emeric Brunf282a812012-09-21 15:27:54 +02003766 smp->flags = 0;
3767
3768 return 1;
3769}
3770
Emeric Brun2525b6b2012-10-18 15:59:43 +02003771/* integer, returns the depth of the first verify error in CA chain of client certificate chain. */
Emeric Brunf282a812012-09-21 15:27:54 +02003772static int
Emeric Brun2525b6b2012-10-18 15:59:43 +02003773smp_fetch_ssl_c_ca_err_depth(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003774 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brunf282a812012-09-21 15:27:54 +02003775{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003776 struct connection *conn;
3777
3778 if (!l4)
3779 return 0;
3780
3781 conn = objt_conn(l4->si[0].end);
3782 if (!conn || conn->xprt != &ssl_sock)
Emeric Brunf282a812012-09-21 15:27:54 +02003783 return 0;
3784
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003785 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunf282a812012-09-21 15:27:54 +02003786 smp->flags = SMP_F_MAY_CHANGE;
3787 return 0;
3788 }
3789
3790 smp->type = SMP_T_UINT;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003791 smp->data.uint = (unsigned int)SSL_SOCK_ST_TO_CAEDEPTH(conn->xprt_st);
Emeric Brunf282a812012-09-21 15:27:54 +02003792 smp->flags = 0;
3793
3794 return 1;
3795}
3796
Emeric Brun2525b6b2012-10-18 15:59:43 +02003797/* integer, returns the first verify error on client certificate */
Emeric Brunf282a812012-09-21 15:27:54 +02003798static int
Emeric Brun2525b6b2012-10-18 15:59:43 +02003799smp_fetch_ssl_c_err(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003800 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brunf282a812012-09-21 15:27:54 +02003801{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003802 struct connection *conn;
3803
3804 if (!l4)
Emeric Brunf282a812012-09-21 15:27:54 +02003805 return 0;
3806
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003807 conn = objt_conn(l4->si[0].end);
3808 if (!conn || conn->xprt != &ssl_sock)
3809 return 0;
3810
3811 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunf282a812012-09-21 15:27:54 +02003812 smp->flags = SMP_F_MAY_CHANGE;
3813 return 0;
3814 }
3815
3816 smp->type = SMP_T_UINT;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003817 smp->data.uint = (unsigned int)SSL_SOCK_ST_TO_CRTERROR(conn->xprt_st);
Emeric Brunf282a812012-09-21 15:27:54 +02003818 smp->flags = 0;
3819
3820 return 1;
3821}
3822
Emeric Brun2525b6b2012-10-18 15:59:43 +02003823/* integer, returns the verify result on client cert */
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02003824static int
Emeric Brun2525b6b2012-10-18 15:59:43 +02003825smp_fetch_ssl_c_verify(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003826 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02003827{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003828 struct connection *conn;
3829
3830 if (!l4)
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02003831 return 0;
3832
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003833 conn = objt_conn(l4->si[0].end);
3834 if (!conn || conn->xprt != &ssl_sock)
3835 return 0;
3836
3837 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02003838 smp->flags = SMP_F_MAY_CHANGE;
3839 return 0;
3840 }
3841
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003842 if (!conn->xprt_ctx)
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02003843 return 0;
3844
3845 smp->type = SMP_T_UINT;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003846 smp->data.uint = (unsigned int)SSL_get_verify_result(conn->xprt_ctx);
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02003847 smp->flags = 0;
3848
3849 return 1;
3850}
3851
Emeric Brunfb510ea2012-10-05 12:00:26 +02003852/* parse the "ca-file" bind keyword */
3853static 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 +02003854{
3855 if (!*args[cur_arg + 1]) {
3856 if (err)
3857 memprintf(err, "'%s' : missing CAfile path", args[cur_arg]);
3858 return ERR_ALERT | ERR_FATAL;
3859 }
3860
Emeric Brunef42d922012-10-11 16:11:36 +02003861 if ((*args[cur_arg + 1] != '/') && global.ca_base)
3862 memprintf(&conf->ca_file, "%s/%s", global.ca_base, args[cur_arg + 1]);
3863 else
3864 memprintf(&conf->ca_file, "%s", args[cur_arg + 1]);
Emeric Brunc8e8d122012-10-02 18:42:10 +02003865
Emeric Brund94b3fe2012-09-20 18:23:56 +02003866 return 0;
3867}
3868
Willy Tarreau79eeafa2012-09-14 07:53:05 +02003869/* parse the "ciphers" bind keyword */
Willy Tarreau4348fad2012-09-20 16:48:07 +02003870static 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 +02003871{
3872 if (!*args[cur_arg + 1]) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02003873 memprintf(err, "'%s' : missing cipher suite", args[cur_arg]);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02003874 return ERR_ALERT | ERR_FATAL;
3875 }
3876
Emeric Brun76d88952012-10-05 15:47:31 +02003877 free(conf->ciphers);
Willy Tarreau4348fad2012-09-20 16:48:07 +02003878 conf->ciphers = strdup(args[cur_arg + 1]);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02003879 return 0;
3880}
3881
3882/* parse the "crt" bind keyword */
Willy Tarreau4348fad2012-09-20 16:48:07 +02003883static 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 +02003884{
Willy Tarreau38011032013-08-13 16:59:39 +02003885 char path[MAXPATHLEN];
Willy Tarreaub75d6922014-04-14 18:05:41 +02003886
Willy Tarreau79eeafa2012-09-14 07:53:05 +02003887 if (!*args[cur_arg + 1]) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02003888 memprintf(err, "'%s' : missing certificate location", args[cur_arg]);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02003889 return ERR_ALERT | ERR_FATAL;
3890 }
3891
Emeric Brunc8e8d122012-10-02 18:42:10 +02003892 if ((*args[cur_arg + 1] != '/' ) && global.crt_base) {
Willy Tarreau38011032013-08-13 16:59:39 +02003893 if ((strlen(global.crt_base) + 1 + strlen(args[cur_arg + 1]) + 1) > MAXPATHLEN) {
Emeric Brunc8e8d122012-10-02 18:42:10 +02003894 memprintf(err, "'%s' : path too long", args[cur_arg]);
3895 return ERR_ALERT | ERR_FATAL;
3896 }
Willy Tarreaub75d6922014-04-14 18:05:41 +02003897 snprintf(path, sizeof(path), "%s/%s", global.crt_base, args[cur_arg + 1]);
Emeric Brunc8e8d122012-10-02 18:42:10 +02003898 if (ssl_sock_load_cert(path, conf, px, err) > 0)
3899 return ERR_ALERT | ERR_FATAL;
3900
3901 return 0;
3902 }
3903
Willy Tarreau4348fad2012-09-20 16:48:07 +02003904 if (ssl_sock_load_cert(args[cur_arg + 1], conf, px, err) > 0)
Willy Tarreau79eeafa2012-09-14 07:53:05 +02003905 return ERR_ALERT | ERR_FATAL;
Emeric Brund94b3fe2012-09-20 18:23:56 +02003906
3907 return 0;
3908}
3909
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01003910/* parse the "crt-list" bind keyword */
3911static int bind_parse_crt_list(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
3912{
3913 if (!*args[cur_arg + 1]) {
3914 memprintf(err, "'%s' : missing certificate location", args[cur_arg]);
3915 return ERR_ALERT | ERR_FATAL;
3916 }
3917
Willy Tarreauad1731d2013-04-02 17:35:58 +02003918 if (ssl_sock_load_cert_list_file(args[cur_arg + 1], conf, px, err) > 0) {
3919 memprintf(err, "'%s' : %s", args[cur_arg], *err);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01003920 return ERR_ALERT | ERR_FATAL;
Willy Tarreauad1731d2013-04-02 17:35:58 +02003921 }
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01003922
3923 return 0;
3924}
3925
Emeric Brunfb510ea2012-10-05 12:00:26 +02003926/* parse the "crl-file" bind keyword */
3927static 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 +02003928{
Emeric Brun051cdab2012-10-02 19:25:50 +02003929#ifndef X509_V_FLAG_CRL_CHECK
3930 if (err)
3931 memprintf(err, "'%s' : library does not support CRL verify", args[cur_arg]);
3932 return ERR_ALERT | ERR_FATAL;
3933#else
Emeric Brund94b3fe2012-09-20 18:23:56 +02003934 if (!*args[cur_arg + 1]) {
3935 if (err)
3936 memprintf(err, "'%s' : missing CRLfile path", args[cur_arg]);
3937 return ERR_ALERT | ERR_FATAL;
3938 }
Emeric Brun2b58d042012-09-20 17:10:03 +02003939
Emeric Brunef42d922012-10-11 16:11:36 +02003940 if ((*args[cur_arg + 1] != '/') && global.ca_base)
3941 memprintf(&conf->crl_file, "%s/%s", global.ca_base, args[cur_arg + 1]);
3942 else
3943 memprintf(&conf->crl_file, "%s", args[cur_arg + 1]);
Emeric Brunc8e8d122012-10-02 18:42:10 +02003944
Emeric Brun2b58d042012-09-20 17:10:03 +02003945 return 0;
Emeric Brun051cdab2012-10-02 19:25:50 +02003946#endif
Emeric Brun2b58d042012-09-20 17:10:03 +02003947}
3948
3949/* parse the "ecdhe" bind keyword keywords */
3950static int bind_parse_ecdhe(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
3951{
3952#if OPENSSL_VERSION_NUMBER < 0x0090800fL
3953 if (err)
3954 memprintf(err, "'%s' : library does not support elliptic curve Diffie-Hellman (too old)", args[cur_arg]);
3955 return ERR_ALERT | ERR_FATAL;
3956#elif defined(OPENSSL_NO_ECDH)
3957 if (err)
3958 memprintf(err, "'%s' : library does not support elliptic curve Diffie-Hellman (disabled via OPENSSL_NO_ECDH)", args[cur_arg]);
3959 return ERR_ALERT | ERR_FATAL;
3960#else
3961 if (!*args[cur_arg + 1]) {
3962 if (err)
3963 memprintf(err, "'%s' : missing named curve", args[cur_arg]);
3964 return ERR_ALERT | ERR_FATAL;
3965 }
3966
3967 conf->ecdhe = strdup(args[cur_arg + 1]);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02003968
3969 return 0;
Emeric Brun2b58d042012-09-20 17:10:03 +02003970#endif
Willy Tarreau79eeafa2012-09-14 07:53:05 +02003971}
3972
Emeric Brun81c00f02012-09-21 14:31:21 +02003973/* parse the "crt_ignerr" and "ca_ignerr" bind keywords */
3974static int bind_parse_ignore_err(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
3975{
3976 int code;
3977 char *p = args[cur_arg + 1];
3978 unsigned long long *ignerr = &conf->crt_ignerr;
3979
3980 if (!*p) {
3981 if (err)
3982 memprintf(err, "'%s' : missing error IDs list", args[cur_arg]);
3983 return ERR_ALERT | ERR_FATAL;
3984 }
3985
3986 if (strcmp(args[cur_arg], "ca-ignore-err") == 0)
3987 ignerr = &conf->ca_ignerr;
3988
3989 if (strcmp(p, "all") == 0) {
3990 *ignerr = ~0ULL;
3991 return 0;
3992 }
3993
3994 while (p) {
3995 code = atoi(p);
3996 if ((code <= 0) || (code > 63)) {
3997 if (err)
3998 memprintf(err, "'%s' : ID '%d' out of range (1..63) in error IDs list '%s'",
3999 args[cur_arg], code, args[cur_arg + 1]);
4000 return ERR_ALERT | ERR_FATAL;
4001 }
4002 *ignerr |= 1ULL << code;
4003 p = strchr(p, ',');
4004 if (p)
4005 p++;
4006 }
4007
Emeric Brun2cb7ae52012-10-05 14:14:21 +02004008 return 0;
4009}
4010
4011/* parse the "force-sslv3" bind keyword */
4012static int bind_parse_force_sslv3(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
4013{
4014 conf->ssl_options |= BC_SSL_O_USE_SSLV3;
4015 return 0;
4016}
4017
4018/* parse the "force-tlsv10" bind keyword */
4019static int bind_parse_force_tlsv10(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
4020{
4021 conf->ssl_options |= BC_SSL_O_USE_TLSV10;
Emeric Brun2d0c4822012-10-02 13:45:20 +02004022 return 0;
4023}
4024
Emeric Brun2cb7ae52012-10-05 14:14:21 +02004025/* parse the "force-tlsv11" bind keyword */
4026static int bind_parse_force_tlsv11(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
4027{
4028#if SSL_OP_NO_TLSv1_1
4029 conf->ssl_options |= BC_SSL_O_USE_TLSV11;
4030 return 0;
4031#else
4032 if (err)
4033 memprintf(err, "'%s' : library does not support protocol TLSv1.1", args[cur_arg]);
4034 return ERR_ALERT | ERR_FATAL;
4035#endif
4036}
4037
4038/* parse the "force-tlsv12" bind keyword */
4039static int bind_parse_force_tlsv12(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
4040{
4041#if SSL_OP_NO_TLSv1_2
4042 conf->ssl_options |= BC_SSL_O_USE_TLSV12;
4043 return 0;
4044#else
4045 if (err)
4046 memprintf(err, "'%s' : library does not support protocol TLSv1.2", args[cur_arg]);
4047 return ERR_ALERT | ERR_FATAL;
4048#endif
4049}
4050
4051
Emeric Brun2d0c4822012-10-02 13:45:20 +02004052/* parse the "no-tls-tickets" bind keyword */
4053static int bind_parse_no_tls_tickets(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
4054{
Emeric Brun89675492012-10-05 13:48:26 +02004055 conf->ssl_options |= BC_SSL_O_NO_TLS_TICKETS;
Emeric Brun81c00f02012-09-21 14:31:21 +02004056 return 0;
4057}
4058
Emeric Brun2d0c4822012-10-02 13:45:20 +02004059
Emeric Brun9b3009b2012-10-05 11:55:06 +02004060/* parse the "no-sslv3" bind keyword */
4061static 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 +02004062{
Emeric Brun89675492012-10-05 13:48:26 +02004063 conf->ssl_options |= BC_SSL_O_NO_SSLV3;
Willy Tarreau79eeafa2012-09-14 07:53:05 +02004064 return 0;
4065}
4066
Emeric Brun9b3009b2012-10-05 11:55:06 +02004067/* parse the "no-tlsv10" bind keyword */
4068static 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 +02004069{
Emeric Brun89675492012-10-05 13:48:26 +02004070 conf->ssl_options |= BC_SSL_O_NO_TLSV10;
Emeric Brunc0ff4922012-09-28 19:37:02 +02004071 return 0;
4072}
4073
Emeric Brun9b3009b2012-10-05 11:55:06 +02004074/* parse the "no-tlsv11" bind keyword */
4075static 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 +02004076{
Emeric Brun89675492012-10-05 13:48:26 +02004077 conf->ssl_options |= BC_SSL_O_NO_TLSV11;
Emeric Brunc0ff4922012-09-28 19:37:02 +02004078 return 0;
4079}
4080
Emeric Brun9b3009b2012-10-05 11:55:06 +02004081/* parse the "no-tlsv12" bind keyword */
4082static 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 +02004083{
Emeric Brun89675492012-10-05 13:48:26 +02004084 conf->ssl_options |= BC_SSL_O_NO_TLSV12;
Willy Tarreau79eeafa2012-09-14 07:53:05 +02004085 return 0;
4086}
4087
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02004088/* parse the "npn" bind keyword */
4089static int bind_parse_npn(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
4090{
4091#ifdef OPENSSL_NPN_NEGOTIATED
4092 char *p1, *p2;
4093
4094 if (!*args[cur_arg + 1]) {
4095 memprintf(err, "'%s' : missing the comma-delimited NPN protocol suite", args[cur_arg]);
4096 return ERR_ALERT | ERR_FATAL;
4097 }
4098
4099 free(conf->npn_str);
4100
4101 /* the NPN string is built as a suite of (<len> <name>)* */
4102 conf->npn_len = strlen(args[cur_arg + 1]) + 1;
4103 conf->npn_str = calloc(1, conf->npn_len);
4104 memcpy(conf->npn_str + 1, args[cur_arg + 1], conf->npn_len);
4105
4106 /* replace commas with the name length */
4107 p1 = conf->npn_str;
4108 p2 = p1 + 1;
4109 while (1) {
4110 p2 = memchr(p1 + 1, ',', conf->npn_str + conf->npn_len - (p1 + 1));
4111 if (!p2)
4112 p2 = p1 + 1 + strlen(p1 + 1);
4113
4114 if (p2 - (p1 + 1) > 255) {
4115 *p2 = '\0';
4116 memprintf(err, "'%s' : NPN protocol name too long : '%s'", args[cur_arg], p1 + 1);
4117 return ERR_ALERT | ERR_FATAL;
4118 }
4119
4120 *p1 = p2 - (p1 + 1);
4121 p1 = p2;
4122
4123 if (!*p2)
4124 break;
4125
4126 *(p2++) = '\0';
4127 }
4128 return 0;
4129#else
4130 if (err)
4131 memprintf(err, "'%s' : library does not support TLS NPN extension", args[cur_arg]);
4132 return ERR_ALERT | ERR_FATAL;
4133#endif
4134}
4135
Willy Tarreauab861d32013-04-02 02:30:41 +02004136/* parse the "alpn" bind keyword */
4137static int bind_parse_alpn(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
4138{
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01004139#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Willy Tarreauab861d32013-04-02 02:30:41 +02004140 char *p1, *p2;
4141
4142 if (!*args[cur_arg + 1]) {
4143 memprintf(err, "'%s' : missing the comma-delimited ALPN protocol suite", args[cur_arg]);
4144 return ERR_ALERT | ERR_FATAL;
4145 }
4146
4147 free(conf->alpn_str);
4148
4149 /* the ALPN string is built as a suite of (<len> <name>)* */
4150 conf->alpn_len = strlen(args[cur_arg + 1]) + 1;
4151 conf->alpn_str = calloc(1, conf->alpn_len);
4152 memcpy(conf->alpn_str + 1, args[cur_arg + 1], conf->alpn_len);
4153
4154 /* replace commas with the name length */
4155 p1 = conf->alpn_str;
4156 p2 = p1 + 1;
4157 while (1) {
4158 p2 = memchr(p1 + 1, ',', conf->alpn_str + conf->alpn_len - (p1 + 1));
4159 if (!p2)
4160 p2 = p1 + 1 + strlen(p1 + 1);
4161
4162 if (p2 - (p1 + 1) > 255) {
4163 *p2 = '\0';
4164 memprintf(err, "'%s' : ALPN protocol name too long : '%s'", args[cur_arg], p1 + 1);
4165 return ERR_ALERT | ERR_FATAL;
4166 }
4167
4168 *p1 = p2 - (p1 + 1);
4169 p1 = p2;
4170
4171 if (!*p2)
4172 break;
4173
4174 *(p2++) = '\0';
4175 }
4176 return 0;
4177#else
4178 if (err)
4179 memprintf(err, "'%s' : library does not support TLS ALPN extension", args[cur_arg]);
4180 return ERR_ALERT | ERR_FATAL;
4181#endif
4182}
4183
Willy Tarreau79eeafa2012-09-14 07:53:05 +02004184/* parse the "ssl" bind keyword */
Willy Tarreau4348fad2012-09-20 16:48:07 +02004185static 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 +02004186{
Willy Tarreau81796be2012-09-22 19:11:47 +02004187 struct listener *l;
4188
Willy Tarreau4348fad2012-09-20 16:48:07 +02004189 conf->is_ssl = 1;
Emeric Brun76d88952012-10-05 15:47:31 +02004190
4191 if (global.listen_default_ciphers && !conf->ciphers)
4192 conf->ciphers = strdup(global.listen_default_ciphers);
Emeric Brun2c86cbf2014-10-30 15:56:50 +01004193 conf->ssl_options |= global.listen_default_ssloptions;
Emeric Brun76d88952012-10-05 15:47:31 +02004194
Willy Tarreau81796be2012-09-22 19:11:47 +02004195 list_for_each_entry(l, &conf->listeners, by_bind)
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02004196 l->xprt = &ssl_sock;
Willy Tarreau81796be2012-09-22 19:11:47 +02004197
Willy Tarreau79eeafa2012-09-14 07:53:05 +02004198 return 0;
4199}
4200
Emmanuel Hocdet65623372013-01-24 17:17:15 +01004201/* parse the "strict-sni" bind keyword */
4202static int bind_parse_strict_sni(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
4203{
4204 conf->strict_sni = 1;
4205 return 0;
4206}
4207
Emeric Brund94b3fe2012-09-20 18:23:56 +02004208/* parse the "verify" bind keyword */
4209static int bind_parse_verify(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
4210{
4211 if (!*args[cur_arg + 1]) {
4212 if (err)
4213 memprintf(err, "'%s' : missing verify method", args[cur_arg]);
4214 return ERR_ALERT | ERR_FATAL;
4215 }
4216
4217 if (strcmp(args[cur_arg + 1], "none") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01004218 conf->verify = SSL_SOCK_VERIFY_NONE;
Emeric Brund94b3fe2012-09-20 18:23:56 +02004219 else if (strcmp(args[cur_arg + 1], "optional") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01004220 conf->verify = SSL_SOCK_VERIFY_OPTIONAL;
Emeric Brund94b3fe2012-09-20 18:23:56 +02004221 else if (strcmp(args[cur_arg + 1], "required") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01004222 conf->verify = SSL_SOCK_VERIFY_REQUIRED;
Emeric Brund94b3fe2012-09-20 18:23:56 +02004223 else {
4224 if (err)
4225 memprintf(err, "'%s' : unknown verify method '%s', only 'none', 'optional', and 'required' are supported\n",
4226 args[cur_arg], args[cur_arg + 1]);
4227 return ERR_ALERT | ERR_FATAL;
4228 }
4229
4230 return 0;
4231}
4232
Willy Tarreau92faadf2012-10-10 23:04:25 +02004233/************** "server" keywords ****************/
4234
Emeric Brunef42d922012-10-11 16:11:36 +02004235/* parse the "ca-file" server keyword */
4236static int srv_parse_ca_file(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4237{
4238 if (!*args[*cur_arg + 1]) {
4239 if (err)
4240 memprintf(err, "'%s' : missing CAfile path", args[*cur_arg]);
4241 return ERR_ALERT | ERR_FATAL;
4242 }
4243
4244 if ((*args[*cur_arg + 1] != '/') && global.ca_base)
4245 memprintf(&newsrv->ssl_ctx.ca_file, "%s/%s", global.ca_base, args[*cur_arg + 1]);
4246 else
4247 memprintf(&newsrv->ssl_ctx.ca_file, "%s", args[*cur_arg + 1]);
4248
4249 return 0;
4250}
4251
Willy Tarreau92faadf2012-10-10 23:04:25 +02004252/* parse the "check-ssl" server keyword */
4253static int srv_parse_check_ssl(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4254{
4255 newsrv->check.use_ssl = 1;
4256 if (global.connect_default_ciphers && !newsrv->ssl_ctx.ciphers)
4257 newsrv->ssl_ctx.ciphers = strdup(global.connect_default_ciphers);
Emeric Brun2c86cbf2014-10-30 15:56:50 +01004258 newsrv->ssl_ctx.options |= global.connect_default_ssloptions;
Willy Tarreau92faadf2012-10-10 23:04:25 +02004259 return 0;
4260}
4261
4262/* parse the "ciphers" server keyword */
4263static int srv_parse_ciphers(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4264{
4265 if (!*args[*cur_arg + 1]) {
4266 memprintf(err, "'%s' : missing cipher suite", args[*cur_arg]);
4267 return ERR_ALERT | ERR_FATAL;
4268 }
4269
4270 free(newsrv->ssl_ctx.ciphers);
4271 newsrv->ssl_ctx.ciphers = strdup(args[*cur_arg + 1]);
4272 return 0;
4273}
4274
Emeric Brunef42d922012-10-11 16:11:36 +02004275/* parse the "crl-file" server keyword */
4276static int srv_parse_crl_file(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4277{
4278#ifndef X509_V_FLAG_CRL_CHECK
4279 if (err)
4280 memprintf(err, "'%s' : library does not support CRL verify", args[*cur_arg]);
4281 return ERR_ALERT | ERR_FATAL;
4282#else
4283 if (!*args[*cur_arg + 1]) {
4284 if (err)
4285 memprintf(err, "'%s' : missing CRLfile path", args[*cur_arg]);
4286 return ERR_ALERT | ERR_FATAL;
4287 }
4288
4289 if ((*args[*cur_arg + 1] != '/') && global.ca_base)
4290 memprintf(&newsrv->ssl_ctx.crl_file, "%s/%s", global.ca_base, args[*cur_arg + 1]);
4291 else
4292 memprintf(&newsrv->ssl_ctx.crl_file, "%s", args[*cur_arg + 1]);
4293
4294 return 0;
4295#endif
4296}
4297
Emeric Bruna7aa3092012-10-26 12:58:00 +02004298/* parse the "crt" server keyword */
4299static int srv_parse_crt(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4300{
4301 if (!*args[*cur_arg + 1]) {
4302 if (err)
4303 memprintf(err, "'%s' : missing certificate file path", args[*cur_arg]);
4304 return ERR_ALERT | ERR_FATAL;
4305 }
4306
4307 if ((*args[*cur_arg + 1] != '/') && global.crt_base)
4308 memprintf(&newsrv->ssl_ctx.client_crt, "%s/%s", global.ca_base, args[*cur_arg + 1]);
4309 else
4310 memprintf(&newsrv->ssl_ctx.client_crt, "%s", args[*cur_arg + 1]);
4311
4312 return 0;
4313}
Emeric Brunef42d922012-10-11 16:11:36 +02004314
Willy Tarreau92faadf2012-10-10 23:04:25 +02004315/* parse the "force-sslv3" server keyword */
4316static int srv_parse_force_sslv3(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4317{
4318 newsrv->ssl_ctx.options |= SRV_SSL_O_USE_SSLV3;
4319 return 0;
4320}
4321
4322/* parse the "force-tlsv10" server keyword */
4323static int srv_parse_force_tlsv10(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4324{
4325 newsrv->ssl_ctx.options |= SRV_SSL_O_USE_TLSV10;
4326 return 0;
4327}
4328
4329/* parse the "force-tlsv11" server keyword */
4330static int srv_parse_force_tlsv11(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4331{
4332#if SSL_OP_NO_TLSv1_1
4333 newsrv->ssl_ctx.options |= SRV_SSL_O_USE_TLSV11;
4334 return 0;
4335#else
4336 if (err)
4337 memprintf(err, "'%s' : library does not support protocol TLSv1.1", args[*cur_arg]);
4338 return ERR_ALERT | ERR_FATAL;
4339#endif
4340}
4341
4342/* parse the "force-tlsv12" server keyword */
4343static int srv_parse_force_tlsv12(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4344{
4345#if SSL_OP_NO_TLSv1_2
4346 newsrv->ssl_ctx.options |= SRV_SSL_O_USE_TLSV12;
4347 return 0;
4348#else
4349 if (err)
4350 memprintf(err, "'%s' : library does not support protocol TLSv1.2", args[*cur_arg]);
4351 return ERR_ALERT | ERR_FATAL;
4352#endif
4353}
4354
4355/* parse the "no-sslv3" server keyword */
4356static int srv_parse_no_sslv3(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4357{
4358 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_SSLV3;
4359 return 0;
4360}
4361
4362/* parse the "no-tlsv10" server keyword */
4363static int srv_parse_no_tlsv10(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4364{
4365 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_TLSV10;
4366 return 0;
4367}
4368
4369/* parse the "no-tlsv11" server keyword */
4370static int srv_parse_no_tlsv11(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4371{
4372 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_TLSV11;
4373 return 0;
4374}
4375
4376/* parse the "no-tlsv12" server keyword */
4377static int srv_parse_no_tlsv12(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4378{
4379 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_TLSV12;
4380 return 0;
4381}
4382
Emeric Brunf9c5c472012-10-11 15:28:34 +02004383/* parse the "no-tls-tickets" server keyword */
4384static int srv_parse_no_tls_tickets(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4385{
4386 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_TLS_TICKETS;
4387 return 0;
4388}
David Safb76832014-05-08 23:42:08 -04004389/* parse the "send-proxy-v2-ssl" server keyword */
4390static int srv_parse_send_proxy_ssl(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4391{
4392 newsrv->pp_opts |= SRV_PP_V2;
4393 newsrv->pp_opts |= SRV_PP_V2_SSL;
4394 return 0;
4395}
4396
4397/* parse the "send-proxy-v2-ssl-cn" server keyword */
4398static int srv_parse_send_proxy_cn(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4399{
4400 newsrv->pp_opts |= SRV_PP_V2;
4401 newsrv->pp_opts |= SRV_PP_V2_SSL;
4402 newsrv->pp_opts |= SRV_PP_V2_SSL_CN;
4403 return 0;
4404}
Emeric Brunf9c5c472012-10-11 15:28:34 +02004405
Willy Tarreau92faadf2012-10-10 23:04:25 +02004406/* parse the "ssl" server keyword */
4407static int srv_parse_ssl(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4408{
4409 newsrv->use_ssl = 1;
4410 if (global.connect_default_ciphers && !newsrv->ssl_ctx.ciphers)
4411 newsrv->ssl_ctx.ciphers = strdup(global.connect_default_ciphers);
4412 return 0;
4413}
4414
Emeric Brunef42d922012-10-11 16:11:36 +02004415/* parse the "verify" server keyword */
4416static int srv_parse_verify(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4417{
4418 if (!*args[*cur_arg + 1]) {
4419 if (err)
4420 memprintf(err, "'%s' : missing verify method", args[*cur_arg]);
4421 return ERR_ALERT | ERR_FATAL;
4422 }
4423
4424 if (strcmp(args[*cur_arg + 1], "none") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01004425 newsrv->ssl_ctx.verify = SSL_SOCK_VERIFY_NONE;
Emeric Brunef42d922012-10-11 16:11:36 +02004426 else if (strcmp(args[*cur_arg + 1], "required") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01004427 newsrv->ssl_ctx.verify = SSL_SOCK_VERIFY_REQUIRED;
Emeric Brunef42d922012-10-11 16:11:36 +02004428 else {
4429 if (err)
4430 memprintf(err, "'%s' : unknown verify method '%s', only 'none' and 'required' are supported\n",
4431 args[*cur_arg], args[*cur_arg + 1]);
4432 return ERR_ALERT | ERR_FATAL;
4433 }
4434
Evan Broderbe554312013-06-27 00:05:25 -07004435 return 0;
4436}
4437
4438/* parse the "verifyhost" server keyword */
4439static int srv_parse_verifyhost(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4440{
4441 if (!*args[*cur_arg + 1]) {
4442 if (err)
4443 memprintf(err, "'%s' : missing hostname to verify against", args[*cur_arg]);
4444 return ERR_ALERT | ERR_FATAL;
4445 }
4446
4447 newsrv->ssl_ctx.verify_host = strdup(args[*cur_arg + 1]);
4448
Emeric Brunef42d922012-10-11 16:11:36 +02004449 return 0;
4450}
4451
Emeric Brun2c86cbf2014-10-30 15:56:50 +01004452/* parse the "ssl-default-bind-options" keyword in global section */
4453static int ssl_parse_default_bind_options(char **args, int section_type, struct proxy *curpx,
4454 struct proxy *defpx, const char *file, int line,
4455 char **err) {
4456 int i = 1;
4457
4458 if (*(args[i]) == 0) {
4459 memprintf(err, "global statement '%s' expects an option as an argument.", args[0]);
4460 return -1;
4461 }
4462 while (*(args[i])) {
4463 if (!strcmp(args[i], "no-sslv3"))
4464 global.listen_default_ssloptions |= BC_SSL_O_NO_SSLV3;
4465 else if (!strcmp(args[i], "no-tlsv10"))
4466 global.listen_default_ssloptions |= BC_SSL_O_NO_TLSV10;
4467 else if (!strcmp(args[i], "no-tlsv11"))
4468 global.listen_default_ssloptions |= BC_SSL_O_NO_TLSV11;
4469 else if (!strcmp(args[i], "no-tlsv12"))
4470 global.listen_default_ssloptions |= BC_SSL_O_NO_TLSV12;
4471 else if (!strcmp(args[i], "force-sslv3"))
4472 global.listen_default_ssloptions |= BC_SSL_O_USE_SSLV3;
4473 else if (!strcmp(args[i], "force-tlsv10"))
4474 global.listen_default_ssloptions |= BC_SSL_O_USE_TLSV10;
4475 else if (!strcmp(args[i], "force-tlsv11")) {
4476#if SSL_OP_NO_TLSv1_1
4477 global.listen_default_ssloptions |= BC_SSL_O_USE_TLSV11;
4478#else
4479 memprintf(err, "'%s' '%s': library does not support protocol TLSv1.1", args[0], args[i]);
4480 return -1;
4481#endif
4482 }
4483 else if (!strcmp(args[i], "force-tlsv12")) {
4484#if SSL_OP_NO_TLSv1_2
4485 global.listen_default_ssloptions |= BC_SSL_O_USE_TLSV12;
4486#else
4487 memprintf(err, "'%s' '%s': library does not support protocol TLSv1.2", args[0], args[i]);
4488 return -1;
4489#endif
4490 }
4491 else if (!strcmp(args[i], "no-tls-tickets"))
4492 global.listen_default_ssloptions |= BC_SSL_O_NO_TLS_TICKETS;
4493 else {
4494 memprintf(err, "unknown option '%s' on global statement '%s'.", args[i], args[0]);
4495 return -1;
4496 }
4497 i++;
4498 }
4499 return 0;
4500}
4501
4502/* parse the "ssl-default-server-options" keyword in global section */
4503static int ssl_parse_default_server_options(char **args, int section_type, struct proxy *curpx,
4504 struct proxy *defpx, const char *file, int line,
4505 char **err) {
4506 int i = 1;
4507
4508 if (*(args[i]) == 0) {
4509 memprintf(err, "global statement '%s' expects an option as an argument.", args[0]);
4510 return -1;
4511 }
4512 while (*(args[i])) {
4513 if (!strcmp(args[i], "no-sslv3"))
4514 global.connect_default_ssloptions |= SRV_SSL_O_NO_SSLV3;
4515 else if (!strcmp(args[i], "no-tlsv10"))
4516 global.connect_default_ssloptions |= SRV_SSL_O_NO_TLSV10;
4517 else if (!strcmp(args[i], "no-tlsv11"))
4518 global.connect_default_ssloptions |= SRV_SSL_O_NO_TLSV11;
4519 else if (!strcmp(args[i], "no-tlsv12"))
4520 global.connect_default_ssloptions |= SRV_SSL_O_NO_TLSV12;
4521 else if (!strcmp(args[i], "force-sslv3"))
4522 global.connect_default_ssloptions |= SRV_SSL_O_USE_SSLV3;
4523 else if (!strcmp(args[i], "force-tlsv10"))
4524 global.connect_default_ssloptions |= SRV_SSL_O_USE_TLSV10;
4525 else if (!strcmp(args[i], "force-tlsv11")) {
4526#if SSL_OP_NO_TLSv1_1
4527 global.connect_default_ssloptions |= SRV_SSL_O_USE_TLSV11;
4528#else
4529 memprintf(err, "'%s' '%s': library does not support protocol TLSv1.1", args[0], args[i]);
4530 return -1;
4531#endif
4532 }
4533 else if (!strcmp(args[i], "force-tlsv12")) {
4534#if SSL_OP_NO_TLSv1_2
4535 global.connect_default_ssloptions |= SRV_SSL_O_USE_TLSV12;
4536#else
4537 memprintf(err, "'%s' '%s': library does not support protocol TLSv1.2", args[0], args[i]);
4538 return -1;
4539#endif
4540 }
4541 else if (!strcmp(args[i], "no-tls-tickets"))
4542 global.connect_default_ssloptions |= SRV_SSL_O_NO_TLS_TICKETS;
4543 else {
4544 memprintf(err, "unknown option '%s' on global statement '%s'.", args[i], args[0]);
4545 return -1;
4546 }
4547 i++;
4548 }
4549 return 0;
4550}
4551
Willy Tarreau7875d092012-09-10 08:20:03 +02004552/* Note: must not be declared <const> as its list will be overwritten.
4553 * Please take care of keeping this list alphabetically sorted.
4554 */
Willy Tarreaudc13c112013-06-21 23:16:39 +02004555static struct sample_fetch_kw_list sample_fetch_keywords = {ILH, {
Emeric Brun645ae792014-04-30 14:21:06 +02004556 { "ssl_bc", smp_fetch_ssl_fc, 0, NULL, SMP_T_BOOL, SMP_USE_L5SRV },
4557 { "ssl_bc_alg_keysize", smp_fetch_ssl_fc_alg_keysize, 0, NULL, SMP_T_UINT, SMP_USE_L5SRV },
4558 { "ssl_bc_cipher", smp_fetch_ssl_fc_cipher, 0, NULL, SMP_T_STR, SMP_USE_L5SRV },
4559 { "ssl_bc_protocol", smp_fetch_ssl_fc_protocol, 0, NULL, SMP_T_STR, SMP_USE_L5SRV },
Emeric Brunb73a9b02014-04-30 18:49:19 +02004560 { "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 +02004561 { "ssl_bc_use_keysize", smp_fetch_ssl_fc_use_keysize, 0, NULL, SMP_T_UINT, SMP_USE_L5SRV },
4562 { "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 +01004563 { "ssl_c_ca_err", smp_fetch_ssl_c_ca_err, 0, NULL, SMP_T_UINT, SMP_USE_L5CLI },
4564 { "ssl_c_ca_err_depth", smp_fetch_ssl_c_ca_err_depth, 0, NULL, SMP_T_UINT, SMP_USE_L5CLI },
Emeric Brun43e79582014-10-29 19:03:26 +01004565 { "ssl_c_der", smp_fetch_ssl_x_der, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Willy Tarreau80aca902013-01-07 15:42:20 +01004566 { "ssl_c_err", smp_fetch_ssl_c_err, 0, NULL, SMP_T_UINT, SMP_USE_L5CLI },
Emeric Brunba841a12014-04-30 17:05:08 +02004567 { "ssl_c_i_dn", smp_fetch_ssl_x_i_dn, ARG2(0,STR,SINT), NULL, SMP_T_STR, SMP_USE_L5CLI },
4568 { "ssl_c_key_alg", smp_fetch_ssl_x_key_alg, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
4569 { "ssl_c_notafter", smp_fetch_ssl_x_notafter, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
4570 { "ssl_c_notbefore", smp_fetch_ssl_x_notbefore, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
4571 { "ssl_c_sig_alg", smp_fetch_ssl_x_sig_alg, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
4572 { "ssl_c_s_dn", smp_fetch_ssl_x_s_dn, ARG2(0,STR,SINT), NULL, SMP_T_STR, SMP_USE_L5CLI },
4573 { "ssl_c_serial", smp_fetch_ssl_x_serial, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
4574 { "ssl_c_sha1", smp_fetch_ssl_x_sha1, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Willy Tarreau80aca902013-01-07 15:42:20 +01004575 { "ssl_c_used", smp_fetch_ssl_c_used, 0, NULL, SMP_T_BOOL, SMP_USE_L5CLI },
4576 { "ssl_c_verify", smp_fetch_ssl_c_verify, 0, NULL, SMP_T_UINT, SMP_USE_L5CLI },
Emeric Brunba841a12014-04-30 17:05:08 +02004577 { "ssl_c_version", smp_fetch_ssl_x_version, 0, NULL, SMP_T_UINT, SMP_USE_L5CLI },
Emeric Brun43e79582014-10-29 19:03:26 +01004578 { "ssl_f_der", smp_fetch_ssl_x_der, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Emeric Brunba841a12014-04-30 17:05:08 +02004579 { "ssl_f_i_dn", smp_fetch_ssl_x_i_dn, ARG2(0,STR,SINT), NULL, SMP_T_STR, SMP_USE_L5CLI },
4580 { "ssl_f_key_alg", smp_fetch_ssl_x_key_alg, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
4581 { "ssl_f_notafter", smp_fetch_ssl_x_notafter, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
4582 { "ssl_f_notbefore", smp_fetch_ssl_x_notbefore, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
4583 { "ssl_f_sig_alg", smp_fetch_ssl_x_sig_alg, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
4584 { "ssl_f_s_dn", smp_fetch_ssl_x_s_dn, ARG2(0,STR,SINT), NULL, SMP_T_STR, SMP_USE_L5CLI },
4585 { "ssl_f_serial", smp_fetch_ssl_x_serial, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Emeric Brun55f4fa82014-04-30 17:11:25 +02004586 { "ssl_f_sha1", smp_fetch_ssl_x_sha1, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Emeric Brunba841a12014-04-30 17:05:08 +02004587 { "ssl_f_version", smp_fetch_ssl_x_version, 0, NULL, SMP_T_UINT, SMP_USE_L5CLI },
Willy Tarreau80aca902013-01-07 15:42:20 +01004588 { "ssl_fc", smp_fetch_ssl_fc, 0, NULL, SMP_T_BOOL, SMP_USE_L5CLI },
4589 { "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 +01004590 { "ssl_fc_cipher", smp_fetch_ssl_fc_cipher, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Willy Tarreau80aca902013-01-07 15:42:20 +01004591 { "ssl_fc_has_crt", smp_fetch_ssl_fc_has_crt, 0, NULL, SMP_T_BOOL, SMP_USE_L5CLI },
4592 { "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 +02004593#ifdef OPENSSL_NPN_NEGOTIATED
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01004594 { "ssl_fc_npn", smp_fetch_ssl_fc_npn, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Willy Tarreaua33c6542012-10-15 13:19:06 +02004595#endif
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01004596#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01004597 { "ssl_fc_alpn", smp_fetch_ssl_fc_alpn, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Willy Tarreauab861d32013-04-02 02:30:41 +02004598#endif
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01004599 { "ssl_fc_protocol", smp_fetch_ssl_fc_protocol, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Emeric Brunb73a9b02014-04-30 18:49:19 +02004600 { "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 +01004601 { "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 +01004602 { "ssl_fc_session_id", smp_fetch_ssl_fc_session_id, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
4603 { "ssl_fc_sni", smp_fetch_ssl_fc_sni, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Willy Tarreau7875d092012-09-10 08:20:03 +02004604 { NULL, NULL, 0, 0, 0 },
4605}};
4606
4607/* Note: must not be declared <const> as its list will be overwritten.
4608 * Please take care of keeping this list alphabetically sorted.
4609 */
Willy Tarreaudc13c112013-06-21 23:16:39 +02004610static struct acl_kw_list acl_kws = {ILH, {
Thierry FOURNIERc5a4e982014-03-05 16:07:08 +01004611 { "ssl_fc_sni_end", "ssl_fc_sni", PAT_MATCH_END },
4612 { "ssl_fc_sni_reg", "ssl_fc_sni", PAT_MATCH_REG },
Willy Tarreau8ed669b2013-01-11 15:49:37 +01004613 { /* END */ },
Willy Tarreau7875d092012-09-10 08:20:03 +02004614}};
4615
Willy Tarreau79eeafa2012-09-14 07:53:05 +02004616/* Note: must not be declared <const> as its list will be overwritten.
4617 * Please take care of keeping this list alphabetically sorted, doing so helps
4618 * all code contributors.
4619 * Optional keywords are also declared with a NULL ->parse() function so that
4620 * the config parser can report an appropriate error when a known keyword was
4621 * not enabled.
4622 */
Willy Tarreau51fb7652012-09-18 18:24:39 +02004623static struct bind_kw_list bind_kws = { "SSL", { }, {
Willy Tarreauab861d32013-04-02 02:30:41 +02004624 { "alpn", bind_parse_alpn, 1 }, /* set ALPN supported protocols */
Emeric Brunfb510ea2012-10-05 12:00:26 +02004625 { "ca-file", bind_parse_ca_file, 1 }, /* set CAfile to process verify on client cert */
Emeric Brun2d0c4822012-10-02 13:45:20 +02004626 { "ca-ignore-err", bind_parse_ignore_err, 1 }, /* set error IDs to ignore on verify depth > 0 */
4627 { "ciphers", bind_parse_ciphers, 1 }, /* set SSL cipher suite */
Emeric Brunfb510ea2012-10-05 12:00:26 +02004628 { "crl-file", bind_parse_crl_file, 1 }, /* set certificat revocation list file use on client cert verify */
Emeric Brun2d0c4822012-10-02 13:45:20 +02004629 { "crt", bind_parse_crt, 1 }, /* load SSL certificates from this location */
4630 { "crt-ignore-err", bind_parse_ignore_err, 1 }, /* set error IDs to ingore on verify depth == 0 */
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01004631 { "crt-list", bind_parse_crt_list, 1 }, /* load a list of crt from this location */
Emeric Brun2d0c4822012-10-02 13:45:20 +02004632 { "ecdhe", bind_parse_ecdhe, 1 }, /* defines named curve for elliptic curve Diffie-Hellman */
Emeric Brun2cb7ae52012-10-05 14:14:21 +02004633 { "force-sslv3", bind_parse_force_sslv3, 0 }, /* force SSLv3 */
4634 { "force-tlsv10", bind_parse_force_tlsv10, 0 }, /* force TLSv10 */
4635 { "force-tlsv11", bind_parse_force_tlsv11, 0 }, /* force TLSv11 */
4636 { "force-tlsv12", bind_parse_force_tlsv12, 0 }, /* force TLSv12 */
Emeric Brun9b3009b2012-10-05 11:55:06 +02004637 { "no-sslv3", bind_parse_no_sslv3, 0 }, /* disable SSLv3 */
4638 { "no-tlsv10", bind_parse_no_tlsv10, 0 }, /* disable TLSv10 */
4639 { "no-tlsv11", bind_parse_no_tlsv11, 0 }, /* disable TLSv11 */
4640 { "no-tlsv12", bind_parse_no_tlsv12, 0 }, /* disable TLSv12 */
Emeric Brun2d0c4822012-10-02 13:45:20 +02004641 { "no-tls-tickets", bind_parse_no_tls_tickets, 0 }, /* disable session resumption tickets */
Emeric Brun2d0c4822012-10-02 13:45:20 +02004642 { "ssl", bind_parse_ssl, 0 }, /* enable SSL processing */
Emmanuel Hocdet65623372013-01-24 17:17:15 +01004643 { "strict-sni", bind_parse_strict_sni, 0 }, /* refuse negotiation if sni doesn't match a certificate */
Emeric Brun2d0c4822012-10-02 13:45:20 +02004644 { "verify", bind_parse_verify, 1 }, /* set SSL verify method */
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02004645 { "npn", bind_parse_npn, 1 }, /* set NPN supported protocols */
Willy Tarreau79eeafa2012-09-14 07:53:05 +02004646 { NULL, NULL, 0 },
4647}};
Emeric Brun46591952012-05-18 15:47:34 +02004648
Willy Tarreau92faadf2012-10-10 23:04:25 +02004649/* Note: must not be declared <const> as its list will be overwritten.
4650 * Please take care of keeping this list alphabetically sorted, doing so helps
4651 * all code contributors.
4652 * Optional keywords are also declared with a NULL ->parse() function so that
4653 * the config parser can report an appropriate error when a known keyword was
4654 * not enabled.
4655 */
4656static struct srv_kw_list srv_kws = { "SSL", { }, {
Emeric Brunef42d922012-10-11 16:11:36 +02004657 { "ca-file", srv_parse_ca_file, 1, 0 }, /* set CAfile to process verify server cert */
Emeric Brunecc91fe2012-10-11 15:05:10 +02004658 { "check-ssl", srv_parse_check_ssl, 0, 0 }, /* enable SSL for health checks */
4659 { "ciphers", srv_parse_ciphers, 1, 0 }, /* select the cipher suite */
Emeric Brunef42d922012-10-11 16:11:36 +02004660 { "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 +02004661 { "crt", srv_parse_crt, 1, 0 }, /* set client certificate */
Emeric Brunecc91fe2012-10-11 15:05:10 +02004662 { "force-sslv3", srv_parse_force_sslv3, 0, 0 }, /* force SSLv3 */
4663 { "force-tlsv10", srv_parse_force_tlsv10, 0, 0 }, /* force TLSv10 */
4664 { "force-tlsv11", srv_parse_force_tlsv11, 0, 0 }, /* force TLSv11 */
4665 { "force-tlsv12", srv_parse_force_tlsv12, 0, 0 }, /* force TLSv12 */
4666 { "no-sslv3", srv_parse_no_sslv3, 0, 0 }, /* disable SSLv3 */
4667 { "no-tlsv10", srv_parse_no_tlsv10, 0, 0 }, /* disable TLSv10 */
4668 { "no-tlsv11", srv_parse_no_tlsv11, 0, 0 }, /* disable TLSv11 */
4669 { "no-tlsv12", srv_parse_no_tlsv12, 0, 0 }, /* disable TLSv12 */
Emeric Brunf9c5c472012-10-11 15:28:34 +02004670 { "no-tls-tickets", srv_parse_no_tls_tickets, 0, 0 }, /* disable session resumption tickets */
David Safb76832014-05-08 23:42:08 -04004671 { "send-proxy-v2-ssl", srv_parse_send_proxy_ssl, 0, 0 }, /* send PROXY protocol header v2 with SSL info */
4672 { "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 +02004673 { "ssl", srv_parse_ssl, 0, 0 }, /* enable SSL processing */
Emeric Brunef42d922012-10-11 16:11:36 +02004674 { "verify", srv_parse_verify, 1, 0 }, /* set SSL verify method */
Evan Broderbe554312013-06-27 00:05:25 -07004675 { "verifyhost", srv_parse_verifyhost, 1, 0 }, /* require that SSL cert verifies for hostname */
Willy Tarreau92faadf2012-10-10 23:04:25 +02004676 { NULL, NULL, 0, 0 },
4677}};
4678
Emeric Brun2c86cbf2014-10-30 15:56:50 +01004679static struct cfg_kw_list cfg_kws = {ILH, {
4680 { CFG_GLOBAL, "ssl-default-bind-options", ssl_parse_default_bind_options },
4681 { CFG_GLOBAL, "ssl-default-server-options", ssl_parse_default_server_options },
4682 { 0, NULL, NULL },
4683}};
4684
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02004685/* transport-layer operations for SSL sockets */
4686struct xprt_ops ssl_sock = {
Emeric Brun46591952012-05-18 15:47:34 +02004687 .snd_buf = ssl_sock_from_buf,
4688 .rcv_buf = ssl_sock_to_buf,
4689 .rcv_pipe = NULL,
4690 .snd_pipe = NULL,
4691 .shutr = NULL,
4692 .shutw = ssl_sock_shutw,
4693 .close = ssl_sock_close,
4694 .init = ssl_sock_init,
4695};
4696
4697__attribute__((constructor))
Willy Tarreau92faadf2012-10-10 23:04:25 +02004698static void __ssl_sock_init(void)
4699{
Emeric Brun46591952012-05-18 15:47:34 +02004700 STACK_OF(SSL_COMP)* cm;
4701
Willy Tarreau610f04b2014-02-13 11:36:41 +01004702#ifdef LISTEN_DEFAULT_CIPHERS
4703 global.listen_default_ciphers = LISTEN_DEFAULT_CIPHERS;
4704#endif
4705#ifdef CONNECT_DEFAULT_CIPHERS
4706 global.connect_default_ciphers = CONNECT_DEFAULT_CIPHERS;
4707#endif
4708 if (global.listen_default_ciphers)
4709 global.listen_default_ciphers = strdup(global.listen_default_ciphers);
4710 if (global.connect_default_ciphers)
4711 global.connect_default_ciphers = strdup(global.connect_default_ciphers);
Emeric Brun2c86cbf2014-10-30 15:56:50 +01004712 global.listen_default_ssloptions = BC_SSL_O_NONE;
4713 global.connect_default_ssloptions = SRV_SSL_O_NONE;
Willy Tarreau610f04b2014-02-13 11:36:41 +01004714
Emeric Brun46591952012-05-18 15:47:34 +02004715 SSL_library_init();
4716 cm = SSL_COMP_get_compression_methods();
4717 sk_SSL_COMP_zero(cm);
Willy Tarreau7875d092012-09-10 08:20:03 +02004718 sample_register_fetches(&sample_fetch_keywords);
4719 acl_register_keywords(&acl_kws);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02004720 bind_register_keywords(&bind_kws);
Willy Tarreau92faadf2012-10-10 23:04:25 +02004721 srv_register_keywords(&srv_kws);
Emeric Brun2c86cbf2014-10-30 15:56:50 +01004722 cfg_register_keywords(&cfg_kws);
Willy Tarreaud92aa5c2015-01-15 21:34:39 +01004723
4724 global.ssl_session_max_cost = SSL_SESSION_MAX_COST;
4725 global.ssl_handshake_max_cost = SSL_HANDSHAKE_MAX_COST;
Emeric Brun46591952012-05-18 15:47:34 +02004726}
4727
4728/*
4729 * Local variables:
4730 * c-indent-level: 8
4731 * c-basic-offset: 8
4732 * End:
4733 */