blob: 93aab8b57f8564d9409afaa7b92ec01ea3c15863 [file] [log] [blame]
Emeric Brun46591952012-05-18 15:47:34 +02001/*
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02002 * SSL/TLS transport layer over SOCK_STREAM sockets
Emeric Brun46591952012-05-18 15:47:34 +02003 *
4 * Copyright (C) 2012 EXCELIANCE, Emeric Brun <ebrun@exceliance.fr>
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version
9 * 2 of the License, or (at your option) any later version.
10 *
Willy Tarreau69845df2012-09-10 09:43:09 +020011 * Acknowledgement:
12 * We'd like to specially thank the Stud project authors for a very clean
13 * and well documented code which helped us understand how the OpenSSL API
14 * ought to be used in non-blocking mode. This is one difficult part which
15 * is not easy to get from the OpenSSL doc, and reading the Stud code made
16 * it much more obvious than the examples in the OpenSSL package. Keep up
17 * the good works, guys !
18 *
19 * Stud is an extremely efficient and scalable SSL/TLS proxy which combines
20 * particularly well with haproxy. For more info about this project, visit :
21 * https://github.com/bumptech/stud
22 *
Emeric Brun46591952012-05-18 15:47:34 +020023 */
24
25#define _GNU_SOURCE
Emeric Brunfc0421f2012-09-07 17:30:07 +020026#include <ctype.h>
27#include <dirent.h>
Emeric Brun46591952012-05-18 15:47:34 +020028#include <errno.h>
29#include <fcntl.h>
30#include <stdio.h>
31#include <stdlib.h>
Emeric Brunfc0421f2012-09-07 17:30:07 +020032#include <string.h>
33#include <unistd.h>
Emeric Brun46591952012-05-18 15:47:34 +020034
35#include <sys/socket.h>
36#include <sys/stat.h>
37#include <sys/types.h>
38
39#include <netinet/tcp.h>
40
41#include <openssl/ssl.h>
Emeric Brunfc0421f2012-09-07 17:30:07 +020042#include <openssl/x509.h>
43#include <openssl/x509v3.h>
44#include <openssl/x509.h>
45#include <openssl/err.h>
Thierry Fournier383085f2013-01-24 14:15:43 +010046#include <openssl/rand.h>
Emeric Brun4147b2e2014-06-16 18:36:30 +020047#ifdef SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB
48#include <openssl/ocsp.h>
49#endif
Remi Gacogne5d769ca2015-05-28 16:23:00 +020050#ifndef OPENSSL_NO_DH
51#include <openssl/dh.h>
52#endif
Emeric Brun46591952012-05-18 15:47:34 +020053
54#include <common/buffer.h>
55#include <common/compat.h>
56#include <common/config.h>
57#include <common/debug.h>
Willy Tarreau79eeafa2012-09-14 07:53:05 +020058#include <common/errors.h>
Emeric Brun46591952012-05-18 15:47:34 +020059#include <common/standard.h>
60#include <common/ticks.h>
61#include <common/time.h>
Emeric Brun42a3e202014-10-30 15:56:50 +010062#include <common/cfgparse.h>
Emeric Brun46591952012-05-18 15:47:34 +020063
Emeric Brunfc0421f2012-09-07 17:30:07 +020064#include <ebsttree.h>
65
66#include <types/global.h>
67#include <types/ssl_sock.h>
68
Willy Tarreau7875d092012-09-10 08:20:03 +020069#include <proto/acl.h>
70#include <proto/arg.h>
Emeric Brun46591952012-05-18 15:47:34 +020071#include <proto/connection.h>
72#include <proto/fd.h>
73#include <proto/freq_ctr.h>
74#include <proto/frontend.h>
Willy Tarreau79eeafa2012-09-14 07:53:05 +020075#include <proto/listener.h>
Thierry FOURNIERed66c292013-11-28 11:05:19 +010076#include <proto/pattern.h>
Willy Tarreau92faadf2012-10-10 23:04:25 +020077#include <proto/server.h>
Emeric Brun46591952012-05-18 15:47:34 +020078#include <proto/log.h>
Emeric Brun94324a42012-10-11 14:00:19 +020079#include <proto/proxy.h>
Emeric Brunfc0421f2012-09-07 17:30:07 +020080#include <proto/shctx.h>
Emeric Brun46591952012-05-18 15:47:34 +020081#include <proto/ssl_sock.h>
82#include <proto/task.h>
83
Willy Tarreau518cedd2014-02-17 15:43:01 +010084/* Warning, these are bits, not integers! */
Emeric Brune64aef12012-09-21 13:15:06 +020085#define SSL_SOCK_ST_FL_VERIFY_DONE 0x00000001
Emeric Brund8b2bb52014-01-28 15:43:53 +010086#define SSL_SOCK_ST_FL_16K_WBFSIZE 0x00000002
Willy Tarreau518cedd2014-02-17 15:43:01 +010087#define SSL_SOCK_SEND_UNLIMITED 0x00000004
Emeric Brun29f037d2014-04-25 19:05:36 +020088#define SSL_SOCK_RECV_HEARTBEAT 0x00000008
89
Emeric Brunf282a812012-09-21 15:27:54 +020090/* bits 0xFFFF0000 are reserved to store verify errors */
91
92/* Verify errors macros */
93#define SSL_SOCK_CA_ERROR_TO_ST(e) (((e > 63) ? 63 : e) << (16))
94#define SSL_SOCK_CAEDEPTH_TO_ST(d) (((d > 15) ? 15 : d) << (6+16))
95#define SSL_SOCK_CRTERROR_TO_ST(e) (((e > 63) ? 63 : e) << (4+6+16))
96
97#define SSL_SOCK_ST_TO_CA_ERROR(s) ((s >> (16)) & 63)
98#define SSL_SOCK_ST_TO_CAEDEPTH(s) ((s >> (6+16)) & 15)
99#define SSL_SOCK_ST_TO_CRTERROR(s) ((s >> (4+6+16)) & 63)
Emeric Brune64aef12012-09-21 13:15:06 +0200100
Emeric Brun850efd52014-01-29 12:24:34 +0100101/* server and bind verify method, it uses a global value as default */
102enum {
103 SSL_SOCK_VERIFY_DEFAULT = 0,
104 SSL_SOCK_VERIFY_REQUIRED = 1,
105 SSL_SOCK_VERIFY_OPTIONAL = 2,
106 SSL_SOCK_VERIFY_NONE = 3,
107};
108
Willy Tarreau71b734c2014-01-28 15:19:44 +0100109int sslconns = 0;
110int totalsslconns = 0;
Emeric Brune1f38db2012-09-03 20:36:47 +0200111
Remi Gacogne60d7aeb2014-07-15 11:36:40 +0200112#ifndef OPENSSL_NO_DH
Remi Gacogne5d769ca2015-05-28 16:23:00 +0200113static int ssl_dh_ptr_index = -1;
Remi Gacogne60d7aeb2014-07-15 11:36:40 +0200114static DH *local_dh_1024 = NULL;
115static DH *local_dh_2048 = NULL;
116static DH *local_dh_4096 = NULL;
Remi Gacogne60d7aeb2014-07-15 11:36:40 +0200117#endif /* OPENSSL_NO_DH */
118
Emeric Brun4147b2e2014-06-16 18:36:30 +0200119#ifdef SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB
120struct certificate_ocsp {
121 struct ebmb_node key;
122 unsigned char key_data[OCSP_MAX_CERTID_ASN1_LENGTH];
123 struct chunk response;
Emeric Brun58484372014-06-20 15:46:13 +0200124 long expire;
Emeric Brun4147b2e2014-06-16 18:36:30 +0200125};
126
Emeric Brun58484372014-06-20 15:46:13 +0200127/*
128 * This function returns the number of seconds elapsed
129 * since the Epoch, 1970-01-01 00:00:00 +0000 (UTC) and the
130 * date presented un ASN1_GENERALIZEDTIME.
131 *
132 * In parsing error case, it returns -1.
133 */
134static long asn1_generalizedtime_to_epoch(ASN1_GENERALIZEDTIME *d)
135{
136 long epoch;
137 char *p, *end;
138 const unsigned short month_offset[12] = {
139 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334
140 };
141 int year, month;
142
143 if (!d || (d->type != V_ASN1_GENERALIZEDTIME)) return -1;
144
145 p = (char *)d->data;
146 end = p + d->length;
147
148 if (end - p < 4) return -1;
149 year = 1000 * (p[0] - '0') + 100 * (p[1] - '0') + 10 * (p[2] - '0') + p[3] - '0';
150 p += 4;
151 if (end - p < 2) return -1;
152 month = 10 * (p[0] - '0') + p[1] - '0';
153 if (month < 1 || month > 12) return -1;
154 /* Compute the number of seconds since 1 jan 1970 and the beginning of current month
155 We consider leap years and the current month (<marsh or not) */
156 epoch = ( ((year - 1970) * 365)
157 + ((year - (month < 3)) / 4 - (year - (month < 3)) / 100 + (year - (month < 3)) / 400)
158 - ((1970 - 1) / 4 - (1970 - 1) / 100 + (1970 - 1) / 400)
159 + month_offset[month-1]
160 ) * 24 * 60 * 60;
161 p += 2;
162 if (end - p < 2) return -1;
163 /* Add the number of seconds of completed days of current month */
164 epoch += (10 * (p[0] - '0') + p[1] - '0' - 1) * 24 * 60 * 60;
165 p += 2;
166 if (end - p < 2) return -1;
167 /* Add the completed hours of the current day */
168 epoch += (10 * (p[0] - '0') + p[1] - '0') * 60 * 60;
169 p += 2;
170 if (end - p < 2) return -1;
171 /* Add the completed minutes of the current hour */
172 epoch += (10 * (p[0] - '0') + p[1] - '0') * 60;
173 p += 2;
174 if (p == end) return -1;
175 /* Test if there is available seconds */
176 if (p[0] < '0' || p[0] > '9')
177 goto nosec;
178 if (end - p < 2) return -1;
179 /* Add the seconds of the current minute */
180 epoch += 10 * (p[0] - '0') + p[1] - '0';
181 p += 2;
182 if (p == end) return -1;
183 /* Ignore seconds float part if present */
184 if (p[0] == '.') {
185 do {
186 if (++p == end) return -1;
187 } while (p[0] >= '0' && p[0] <= '9');
188 }
189
190nosec:
191 if (p[0] == 'Z') {
192 if (end - p != 1) return -1;
193 return epoch;
194 }
195 else if (p[0] == '+') {
196 if (end - p != 5) return -1;
197 /* Apply timezone offset */
198 return epoch - ((10 * (p[1] - '0') + p[2] - '0') * 60 + (10 * (p[3] - '0') + p[4] - '0')) * 60;
199 }
200 else if (p[0] == '-') {
201 if (end - p != 5) return -1;
202 /* Apply timezone offset */
203 return epoch + ((10 * (p[1] - '0') + p[2] - '0') * 60 + (10 * (p[3] - '0') + p[4] - '0')) * 60;
204 }
205
206 return -1;
207}
208
Emeric Brun8d914d12014-06-20 15:37:32 +0200209static struct eb_root cert_ocsp_tree = EB_ROOT_UNIQUE;
Emeric Brun4147b2e2014-06-16 18:36:30 +0200210
211/* This function starts to check if the OCSP response (in DER format) contained
212 * in chunk 'ocsp_response' is valid (else exits on error).
213 * If 'cid' is not NULL, it will be compared to the OCSP certificate ID
214 * contained in the OCSP Response and exits on error if no match.
215 * If it's a valid OCSP Response:
216 * If 'ocsp' is not NULL, the chunk is copied in the OCSP response's container
217 * pointed by 'ocsp'.
218 * If 'ocsp' is NULL, the function looks up into the OCSP response's
219 * containers tree (using as index the ASN1 form of the OCSP Certificate ID extracted
220 * from the response) and exits on error if not found. Finally, If an OCSP response is
221 * already present in the container, it will be overwritten.
222 *
223 * Note: OCSP response containing more than one OCSP Single response is not
224 * considered valid.
225 *
226 * Returns 0 on success, 1 in error case.
227 */
228static int ssl_sock_load_ocsp_response(struct chunk *ocsp_response, struct certificate_ocsp *ocsp, OCSP_CERTID *cid, char **err)
229{
230 OCSP_RESPONSE *resp;
231 OCSP_BASICRESP *bs = NULL;
232 OCSP_SINGLERESP *sr;
233 unsigned char *p = (unsigned char *)ocsp_response->str;
234 int rc , count_sr;
Emeric Brun1135ea42014-06-20 15:44:34 +0200235 ASN1_GENERALIZEDTIME *revtime, *thisupd, *nextupd = NULL;
Emeric Brun4147b2e2014-06-16 18:36:30 +0200236 int reason;
237 int ret = 1;
238
239 resp = d2i_OCSP_RESPONSE(NULL, (const unsigned char **)&p, ocsp_response->len);
240 if (!resp) {
241 memprintf(err, "Unable to parse OCSP response");
242 goto out;
243 }
244
245 rc = OCSP_response_status(resp);
246 if (rc != OCSP_RESPONSE_STATUS_SUCCESSFUL) {
247 memprintf(err, "OCSP response status not successful");
248 goto out;
249 }
250
251 bs = OCSP_response_get1_basic(resp);
252 if (!bs) {
253 memprintf(err, "Failed to get basic response from OCSP Response");
254 goto out;
255 }
256
257 count_sr = OCSP_resp_count(bs);
258 if (count_sr > 1) {
259 memprintf(err, "OCSP response ignored because contains multiple single responses (%d)", count_sr);
260 goto out;
261 }
262
263 sr = OCSP_resp_get0(bs, 0);
264 if (!sr) {
265 memprintf(err, "Failed to get OCSP single response");
266 goto out;
267 }
268
269 rc = OCSP_single_get0_status(sr, &reason, &revtime, &thisupd, &nextupd);
270 if (rc != V_OCSP_CERTSTATUS_GOOD) {
271 memprintf(err, "OCSP single response: certificate status not good");
272 goto out;
273 }
274
Emeric Brun1135ea42014-06-20 15:44:34 +0200275 if (!nextupd) {
276 memprintf(err, "OCSP single response: missing nextupdate");
277 goto out;
278 }
279
Emeric Brunc8b27b62014-06-19 14:16:17 +0200280 rc = OCSP_check_validity(thisupd, nextupd, OCSP_MAX_RESPONSE_TIME_SKEW, -1);
Emeric Brun4147b2e2014-06-16 18:36:30 +0200281 if (!rc) {
282 memprintf(err, "OCSP single response: no longer valid.");
283 goto out;
284 }
285
286 if (cid) {
287 if (OCSP_id_cmp(sr->certId, cid)) {
288 memprintf(err, "OCSP single response: Certificate ID does not match certificate and issuer");
289 goto out;
290 }
291 }
292
293 if (!ocsp) {
294 unsigned char key[OCSP_MAX_CERTID_ASN1_LENGTH];
295 unsigned char *p;
296
297 rc = i2d_OCSP_CERTID(sr->certId, NULL);
298 if (!rc) {
299 memprintf(err, "OCSP single response: Unable to encode Certificate ID");
300 goto out;
301 }
302
303 if (rc > OCSP_MAX_CERTID_ASN1_LENGTH) {
304 memprintf(err, "OCSP single response: Certificate ID too long");
305 goto out;
306 }
307
308 p = key;
309 memset(key, 0, OCSP_MAX_CERTID_ASN1_LENGTH);
310 i2d_OCSP_CERTID(sr->certId, &p);
311 ocsp = (struct certificate_ocsp *)ebmb_lookup(&cert_ocsp_tree, key, OCSP_MAX_CERTID_ASN1_LENGTH);
312 if (!ocsp) {
313 memprintf(err, "OCSP single response: Certificate ID does not match any certificate or issuer");
314 goto out;
315 }
316 }
317
318 /* According to comments on "chunk_dup", the
319 previous chunk buffer will be freed */
320 if (!chunk_dup(&ocsp->response, ocsp_response)) {
321 memprintf(err, "OCSP response: Memory allocation error");
322 goto out;
323 }
324
Emeric Brun58484372014-06-20 15:46:13 +0200325 ocsp->expire = asn1_generalizedtime_to_epoch(nextupd) - OCSP_MAX_RESPONSE_TIME_SKEW;
326
Emeric Brun4147b2e2014-06-16 18:36:30 +0200327 ret = 0;
328out:
329 if (bs)
330 OCSP_BASICRESP_free(bs);
331
332 if (resp)
333 OCSP_RESPONSE_free(resp);
334
335 return ret;
336}
337/*
338 * External function use to update the OCSP response in the OCSP response's
339 * containers tree. The chunk 'ocsp_response' must contain the OCSP response
340 * to update in DER format.
341 *
342 * Returns 0 on success, 1 in error case.
343 */
344int ssl_sock_update_ocsp_response(struct chunk *ocsp_response, char **err)
345{
346 return ssl_sock_load_ocsp_response(ocsp_response, NULL, NULL, err);
347}
348
349/*
350 * This function load the OCSP Resonse in DER format contained in file at
351 * path 'ocsp_path' and call 'ssl_sock_load_ocsp_response'
352 *
353 * Returns 0 on success, 1 in error case.
354 */
355static int ssl_sock_load_ocsp_response_from_file(const char *ocsp_path, struct certificate_ocsp *ocsp, OCSP_CERTID *cid, char **err)
356{
357 int fd = -1;
358 int r = 0;
359 int ret = 1;
360
361 fd = open(ocsp_path, O_RDONLY);
362 if (fd == -1) {
363 memprintf(err, "Error opening OCSP response file");
364 goto end;
365 }
366
367 trash.len = 0;
368 while (trash.len < trash.size) {
369 r = read(fd, trash.str + trash.len, trash.size - trash.len);
370 if (r < 0) {
371 if (errno == EINTR)
372 continue;
373
374 memprintf(err, "Error reading OCSP response from file");
375 goto end;
376 }
377 else if (r == 0) {
378 break;
379 }
380 trash.len += r;
381 }
382
383 close(fd);
384 fd = -1;
385
386 ret = ssl_sock_load_ocsp_response(&trash, ocsp, cid, err);
387end:
388 if (fd != -1)
389 close(fd);
390
391 return ret;
392}
393
394/*
395 * Callback used to set OCSP status extension content in server hello.
396 */
397int ssl_sock_ocsp_stapling_cbk(SSL *ssl, void *arg)
398{
399 struct certificate_ocsp *ocsp = (struct certificate_ocsp *)arg;
400 char* ssl_buf;
401
402 if (!ocsp ||
403 !ocsp->response.str ||
Emeric Brun58484372014-06-20 15:46:13 +0200404 !ocsp->response.len ||
405 (ocsp->expire < now.tv_sec))
Emeric Brun4147b2e2014-06-16 18:36:30 +0200406 return SSL_TLSEXT_ERR_NOACK;
407
408 ssl_buf = OPENSSL_malloc(ocsp->response.len);
409 if (!ssl_buf)
410 return SSL_TLSEXT_ERR_NOACK;
411
412 memcpy(ssl_buf, ocsp->response.str, ocsp->response.len);
413 SSL_set_tlsext_status_ocsp_resp(ssl, ssl_buf, ocsp->response.len);
414
415 return SSL_TLSEXT_ERR_OK;
416}
417
418/*
419 * This function enables the handling of OCSP status extension on 'ctx' if a
420 * file name 'cert_path' suffixed using ".ocsp" is present.
421 * To enable OCSP status extension, the issuer's certificate is mandatory.
422 * It should be present in the certificate's extra chain builded from file
423 * 'cert_path'. If not found, the issuer certificate is loaded from a file
424 * named 'cert_path' suffixed using '.issuer'.
425 *
426 * In addition, ".ocsp" file content is loaded as a DER format of an OCSP
427 * response. If file is empty or content is not a valid OCSP response,
428 * OCSP status extension is enabled but OCSP response is ignored (a warning
429 * is displayed).
430 *
431 * Returns 1 if no ".ocsp" file found, 0 if OCSP status extension is
432 * succesfully enabled, or -1 in other error case.
433 */
434static int ssl_sock_load_ocsp(SSL_CTX *ctx, const char *cert_path)
435{
436
437 BIO *in = NULL;
438 X509 *x, *xi = NULL, *issuer = NULL;
439 STACK_OF(X509) *chain = NULL;
440 OCSP_CERTID *cid = NULL;
441 SSL *ssl;
442 char ocsp_path[MAXPATHLEN+1];
443 int i, ret = -1;
444 struct stat st;
445 struct certificate_ocsp *ocsp = NULL, *iocsp;
446 char *warn = NULL;
447 unsigned char *p;
448
449 snprintf(ocsp_path, MAXPATHLEN+1, "%s.ocsp", cert_path);
450
451 if (stat(ocsp_path, &st))
452 return 1;
453
454 ssl = SSL_new(ctx);
455 if (!ssl)
456 goto out;
457
458 x = SSL_get_certificate(ssl);
459 if (!x)
460 goto out;
461
462 /* Try to lookup for issuer in certificate extra chain */
463#ifdef SSL_CTRL_GET_EXTRA_CHAIN_CERTS
464 SSL_CTX_get_extra_chain_certs(ctx, &chain);
465#else
466 chain = ctx->extra_certs;
467#endif
468 for (i = 0; i < sk_X509_num(chain); i++) {
469 issuer = sk_X509_value(chain, i);
470 if (X509_check_issued(issuer, x) == X509_V_OK)
471 break;
472 else
473 issuer = NULL;
474 }
475
476 /* If not found try to load issuer from a suffixed file */
477 if (!issuer) {
478 char issuer_path[MAXPATHLEN+1];
479
480 in = BIO_new(BIO_s_file());
481 if (!in)
482 goto out;
483
484 snprintf(issuer_path, MAXPATHLEN+1, "%s.issuer", cert_path);
485 if (BIO_read_filename(in, issuer_path) <= 0)
486 goto out;
487
488 xi = PEM_read_bio_X509_AUX(in, NULL, ctx->default_passwd_callback, ctx->default_passwd_callback_userdata);
489 if (!xi)
490 goto out;
491
492 if (X509_check_issued(xi, x) != X509_V_OK)
493 goto out;
494
495 issuer = xi;
496 }
497
498 cid = OCSP_cert_to_id(0, x, issuer);
499 if (!cid)
500 goto out;
501
502 i = i2d_OCSP_CERTID(cid, NULL);
503 if (!i || (i > OCSP_MAX_CERTID_ASN1_LENGTH))
504 goto out;
505
506 ocsp = calloc(1, sizeof(struct certificate_ocsp));
507 if (!ocsp)
508 goto out;
509
510 p = ocsp->key_data;
511 i2d_OCSP_CERTID(cid, &p);
512
513 iocsp = (struct certificate_ocsp *)ebmb_insert(&cert_ocsp_tree, &ocsp->key, OCSP_MAX_CERTID_ASN1_LENGTH);
514 if (iocsp == ocsp)
515 ocsp = NULL;
516
517 SSL_CTX_set_tlsext_status_cb(ctx, ssl_sock_ocsp_stapling_cbk);
518 SSL_CTX_set_tlsext_status_arg(ctx, iocsp);
519
520 ret = 0;
521
522 warn = NULL;
523 if (ssl_sock_load_ocsp_response_from_file(ocsp_path, iocsp, cid, &warn)) {
524 memprintf(&warn, "Loading '%s': %s. Content will be ignored", ocsp_path, warn ? warn : "failure");
525 Warning("%s.\n", warn);
526 }
527
528out:
529 if (ssl)
530 SSL_free(ssl);
531
532 if (in)
533 BIO_free(in);
534
535 if (xi)
536 X509_free(xi);
537
538 if (cid)
539 OCSP_CERTID_free(cid);
540
541 if (ocsp)
542 free(ocsp);
543
544 if (warn)
545 free(warn);
546
547
548 return ret;
549}
550
551#endif
552
Emeric Brune1f38db2012-09-03 20:36:47 +0200553void ssl_sock_infocbk(const SSL *ssl, int where, int ret)
554{
555 struct connection *conn = (struct connection *)SSL_get_app_data(ssl);
556 (void)ret; /* shut gcc stupid warning */
Emeric Brund8b2bb52014-01-28 15:43:53 +0100557 BIO *write_bio;
Emeric Brune1f38db2012-09-03 20:36:47 +0200558
559 if (where & SSL_CB_HANDSHAKE_START) {
560 /* Disable renegotiation (CVE-2009-3555) */
Willy Tarreau20879a02012-12-03 16:32:10 +0100561 if (conn->flags & CO_FL_CONNECTED) {
Emeric Brune1f38db2012-09-03 20:36:47 +0200562 conn->flags |= CO_FL_ERROR;
Willy Tarreau20879a02012-12-03 16:32:10 +0100563 conn->err_code = CO_ER_SSL_RENEG;
564 }
Emeric Brune1f38db2012-09-03 20:36:47 +0200565 }
Emeric Brund8b2bb52014-01-28 15:43:53 +0100566
567 if ((where & SSL_CB_ACCEPT_LOOP) == SSL_CB_ACCEPT_LOOP) {
568 if (!(conn->xprt_st & SSL_SOCK_ST_FL_16K_WBFSIZE)) {
569 /* Long certificate chains optimz
570 If write and read bios are differents, we
571 consider that the buffering was activated,
572 so we rise the output buffer size from 4k
573 to 16k */
574 write_bio = SSL_get_wbio(ssl);
575 if (write_bio != SSL_get_rbio(ssl)) {
576 BIO_set_write_buffer_size(write_bio, 16384);
577 conn->xprt_st |= SSL_SOCK_ST_FL_16K_WBFSIZE;
578 }
579 }
580 }
Emeric Brunfc0421f2012-09-07 17:30:07 +0200581}
582
Emeric Brune64aef12012-09-21 13:15:06 +0200583/* Callback is called for each certificate of the chain during a verify
584 ok is set to 1 if preverify detect no error on current certificate.
585 Returns 0 to break the handshake, 1 otherwise. */
Evan Broderbe554312013-06-27 00:05:25 -0700586int ssl_sock_bind_verifycbk(int ok, X509_STORE_CTX *x_store)
Emeric Brune64aef12012-09-21 13:15:06 +0200587{
588 SSL *ssl;
589 struct connection *conn;
Emeric Brun81c00f02012-09-21 14:31:21 +0200590 int err, depth;
Emeric Brune64aef12012-09-21 13:15:06 +0200591
592 ssl = X509_STORE_CTX_get_ex_data(x_store, SSL_get_ex_data_X509_STORE_CTX_idx());
593 conn = (struct connection *)SSL_get_app_data(ssl);
594
Willy Tarreauf7bc57c2012-10-03 00:19:48 +0200595 conn->xprt_st |= SSL_SOCK_ST_FL_VERIFY_DONE;
Emeric Brune64aef12012-09-21 13:15:06 +0200596
Emeric Brun81c00f02012-09-21 14:31:21 +0200597 if (ok) /* no errors */
598 return ok;
599
600 depth = X509_STORE_CTX_get_error_depth(x_store);
601 err = X509_STORE_CTX_get_error(x_store);
602
603 /* check if CA error needs to be ignored */
604 if (depth > 0) {
Willy Tarreauf7bc57c2012-10-03 00:19:48 +0200605 if (!SSL_SOCK_ST_TO_CA_ERROR(conn->xprt_st)) {
606 conn->xprt_st |= SSL_SOCK_CA_ERROR_TO_ST(err);
607 conn->xprt_st |= SSL_SOCK_CAEDEPTH_TO_ST(depth);
Emeric Brunf282a812012-09-21 15:27:54 +0200608 }
609
Emeric Brun1eb20ef2012-12-03 13:24:29 +0100610 if (objt_listener(conn->target)->bind_conf->ca_ignerr & (1ULL << err)) {
611 ERR_clear_error();
Emeric Brun81c00f02012-09-21 14:31:21 +0200612 return 1;
Emeric Brun1eb20ef2012-12-03 13:24:29 +0100613 }
Emeric Brun81c00f02012-09-21 14:31:21 +0200614
Willy Tarreau20879a02012-12-03 16:32:10 +0100615 conn->err_code = CO_ER_SSL_CA_FAIL;
Emeric Brun81c00f02012-09-21 14:31:21 +0200616 return 0;
617 }
618
Willy Tarreauf7bc57c2012-10-03 00:19:48 +0200619 if (!SSL_SOCK_ST_TO_CRTERROR(conn->xprt_st))
620 conn->xprt_st |= SSL_SOCK_CRTERROR_TO_ST(err);
Emeric Brunf282a812012-09-21 15:27:54 +0200621
Emeric Brun81c00f02012-09-21 14:31:21 +0200622 /* check if certificate error needs to be ignored */
Emeric Brun1eb20ef2012-12-03 13:24:29 +0100623 if (objt_listener(conn->target)->bind_conf->crt_ignerr & (1ULL << err)) {
624 ERR_clear_error();
Emeric Brun81c00f02012-09-21 14:31:21 +0200625 return 1;
Emeric Brun1eb20ef2012-12-03 13:24:29 +0100626 }
Emeric Brun81c00f02012-09-21 14:31:21 +0200627
Willy Tarreau20879a02012-12-03 16:32:10 +0100628 conn->err_code = CO_ER_SSL_CRT_FAIL;
Emeric Brun81c00f02012-09-21 14:31:21 +0200629 return 0;
Emeric Brune64aef12012-09-21 13:15:06 +0200630}
631
Emeric Brun29f037d2014-04-25 19:05:36 +0200632/* Callback is called for ssl protocol analyse */
633void ssl_sock_msgcbk(int write_p, int version, int content_type, const void *buf, size_t len, SSL *ssl, void *arg)
634{
Emeric Brun29f037d2014-04-25 19:05:36 +0200635#ifdef TLS1_RT_HEARTBEAT
636 /* test heartbeat received (write_p is set to 0
637 for a received record) */
Willy Tarreauf51c6982014-04-25 20:02:39 +0200638 if ((content_type == TLS1_RT_HEARTBEAT) && (write_p == 0)) {
Willy Tarreau84815002014-04-25 21:40:27 +0200639 struct connection *conn = (struct connection *)SSL_get_app_data(ssl);
Willy Tarreauf51c6982014-04-25 20:02:39 +0200640 const unsigned char *p = buf;
641 unsigned int payload;
642
Emeric Brun29f037d2014-04-25 19:05:36 +0200643 conn->xprt_st |= SSL_SOCK_RECV_HEARTBEAT;
Willy Tarreauf51c6982014-04-25 20:02:39 +0200644
645 /* Check if this is a CVE-2014-0160 exploitation attempt. */
646 if (*p != TLS1_HB_REQUEST)
647 return;
648
Willy Tarreauaeed6722014-04-25 23:59:58 +0200649 if (len < 1 + 2 + 16) /* 1 type + 2 size + 0 payload + 16 padding */
Willy Tarreauf51c6982014-04-25 20:02:39 +0200650 goto kill_it;
651
652 payload = (p[1] * 256) + p[2];
Willy Tarreau3b2fdb62014-04-25 23:44:22 +0200653 if (3 + payload + 16 <= len)
Willy Tarreauf51c6982014-04-25 20:02:39 +0200654 return; /* OK no problem */
Willy Tarreauaeed6722014-04-25 23:59:58 +0200655 kill_it:
Willy Tarreau3b2fdb62014-04-25 23:44:22 +0200656 /* We have a clear heartbleed attack (CVE-2014-0160), the
657 * advertised payload is larger than the advertised packet
658 * length, so we have garbage in the buffer between the
659 * payload and the end of the buffer (p+len). We can't know
660 * if the SSL stack is patched, and we don't know if we can
661 * safely wipe out the area between p+3+len and payload.
662 * So instead, we prevent the response from being sent by
663 * setting the max_send_fragment to 0 and we report an SSL
664 * error, which will kill this connection. It will be reported
665 * above as SSL_ERROR_SSL while an other handshake failure with
Willy Tarreauf51c6982014-04-25 20:02:39 +0200666 * a heartbeat message will be reported as SSL_ERROR_SYSCALL.
667 */
Willy Tarreau3b2fdb62014-04-25 23:44:22 +0200668 ssl->max_send_fragment = 0;
Willy Tarreauf51c6982014-04-25 20:02:39 +0200669 SSLerr(SSL_F_TLS1_HEARTBEAT, SSL_R_SSL_HANDSHAKE_FAILURE);
670 return;
671 }
Emeric Brun29f037d2014-04-25 19:05:36 +0200672#endif
673}
674
Willy Tarreau6c9a3d52012-10-18 18:57:14 +0200675#ifdef OPENSSL_NPN_NEGOTIATED
676/* This callback is used so that the server advertises the list of
677 * negociable protocols for NPN.
678 */
679static int ssl_sock_advertise_npn_protos(SSL *s, const unsigned char **data,
680 unsigned int *len, void *arg)
681{
682 struct bind_conf *conf = arg;
683
684 *data = (const unsigned char *)conf->npn_str;
685 *len = conf->npn_len;
686 return SSL_TLSEXT_ERR_OK;
687}
688#endif
689
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +0100690#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Willy Tarreauab861d32013-04-02 02:30:41 +0200691/* This callback is used so that the server advertises the list of
692 * negociable protocols for ALPN.
693 */
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +0100694static int ssl_sock_advertise_alpn_protos(SSL *s, const unsigned char **out,
695 unsigned char *outlen,
696 const unsigned char *server,
697 unsigned int server_len, void *arg)
Willy Tarreauab861d32013-04-02 02:30:41 +0200698{
699 struct bind_conf *conf = arg;
700
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +0100701 if (SSL_select_next_proto((unsigned char**) out, outlen, (const unsigned char *)conf->alpn_str,
702 conf->alpn_len, server, server_len) != OPENSSL_NPN_NEGOTIATED) {
703 return SSL_TLSEXT_ERR_NOACK;
704 }
Willy Tarreauab861d32013-04-02 02:30:41 +0200705 return SSL_TLSEXT_ERR_OK;
706}
707#endif
708
Emeric Brunfc0421f2012-09-07 17:30:07 +0200709#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
710/* Sets the SSL ctx of <ssl> to match the advertised server name. Returns a
711 * warning when no match is found, which implies the default (first) cert
712 * will keep being used.
713 */
Willy Tarreau2a65ff02012-09-13 17:54:29 +0200714static int ssl_sock_switchctx_cbk(SSL *ssl, int *al, struct bind_conf *s)
Emeric Brunfc0421f2012-09-07 17:30:07 +0200715{
716 const char *servername;
717 const char *wildp = NULL;
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +0200718 struct ebmb_node *node, *n;
Emeric Brunfc0421f2012-09-07 17:30:07 +0200719 int i;
720 (void)al; /* shut gcc stupid warning */
721
722 servername = SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name);
Emmanuel Hocdet65623372013-01-24 17:17:15 +0100723 if (!servername) {
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +0200724 return (s->strict_sni ?
725 SSL_TLSEXT_ERR_ALERT_FATAL :
Emmanuel Hocdet79274e22013-05-31 12:47:44 +0200726 SSL_TLSEXT_ERR_NOACK);
Emmanuel Hocdet65623372013-01-24 17:17:15 +0100727 }
Emeric Brunfc0421f2012-09-07 17:30:07 +0200728
Willy Tarreau19d14ef2012-10-29 16:51:55 +0100729 for (i = 0; i < trash.size; i++) {
Emeric Brunfc0421f2012-09-07 17:30:07 +0200730 if (!servername[i])
731 break;
Willy Tarreau19d14ef2012-10-29 16:51:55 +0100732 trash.str[i] = tolower(servername[i]);
733 if (!wildp && (trash.str[i] == '.'))
734 wildp = &trash.str[i];
Emeric Brunfc0421f2012-09-07 17:30:07 +0200735 }
Willy Tarreau19d14ef2012-10-29 16:51:55 +0100736 trash.str[i] = 0;
Emeric Brunfc0421f2012-09-07 17:30:07 +0200737
738 /* lookup in full qualified names */
Willy Tarreau19d14ef2012-10-29 16:51:55 +0100739 node = ebst_lookup(&s->sni_ctx, trash.str);
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +0200740
741 /* lookup a not neg filter */
742 for (n = node; n; n = ebmb_next_dup(n)) {
743 if (!container_of(n, struct sni_ctx, name)->neg) {
744 node = n;
745 break;
Emmanuel Hocdet65623372013-01-24 17:17:15 +0100746 }
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +0200747 }
748 if (!node && wildp) {
749 /* lookup in wildcards names */
Emeric Brunfc0421f2012-09-07 17:30:07 +0200750 node = ebst_lookup(&s->sni_w_ctx, wildp);
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +0200751 }
752 if (!node || container_of(node, struct sni_ctx, name)->neg) {
753 return (s->strict_sni ?
754 SSL_TLSEXT_ERR_ALERT_FATAL :
755 SSL_TLSEXT_ERR_ALERT_WARNING);
Emeric Brunfc0421f2012-09-07 17:30:07 +0200756 }
757
758 /* switch ctx */
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +0200759 SSL_set_SSL_CTX(ssl, container_of(node, struct sni_ctx, name)->ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +0200760 return SSL_TLSEXT_ERR_OK;
761}
762#endif /* SSL_CTRL_SET_TLSEXT_HOSTNAME */
763
Emeric Bruna4bcd9a2012-09-20 16:19:02 +0200764#ifndef OPENSSL_NO_DH
Remi Gacognef46cd6e2014-06-12 14:58:40 +0200765
766static DH * ssl_get_dh_1024(void)
767{
Remi Gacogne2ad3ec12015-05-29 16:26:17 +0200768 static unsigned char dh1024_p[]={
769 0xFA,0xF9,0x2A,0x22,0x2A,0xA7,0x7F,0xE1,0x67,0x4E,0x53,0xF7,
770 0x56,0x13,0xC3,0xB1,0xE3,0x29,0x6B,0x66,0x31,0x6A,0x7F,0xB3,
771 0xC2,0x68,0x6B,0xCB,0x1D,0x57,0x39,0x1D,0x1F,0xFF,0x1C,0xC9,
772 0xA6,0xA4,0x98,0x82,0x31,0x5D,0x25,0xFF,0x8A,0xE0,0x73,0x96,
773 0x81,0xC8,0x83,0x79,0xC1,0x5A,0x04,0xF8,0x37,0x0D,0xA8,0x3D,
774 0xAE,0x74,0xBC,0xDB,0xB6,0xA4,0x75,0xD9,0x71,0x8A,0xA0,0x17,
775 0x9E,0x2D,0xC8,0xA8,0xDF,0x2C,0x5F,0x82,0x95,0xF8,0x92,0x9B,
776 0xA7,0x33,0x5F,0x89,0x71,0xC8,0x2D,0x6B,0x18,0x86,0xC4,0x94,
777 0x22,0xA5,0x52,0x8D,0xF6,0xF6,0xD2,0x37,0x92,0x0F,0xA5,0xCC,
778 0xDB,0x7B,0x1D,0x3D,0xA1,0x31,0xB7,0x80,0x8F,0x0B,0x67,0x5E,
779 0x36,0xA5,0x60,0x0C,0xF1,0x95,0x33,0x8B,
780 };
781 static unsigned char dh1024_g[]={
782 0x02,
783 };
784
Remi Gacognef46cd6e2014-06-12 14:58:40 +0200785 DH *dh = DH_new();
786 if (dh) {
Remi Gacogne2ad3ec12015-05-29 16:26:17 +0200787 dh->p = BN_bin2bn(dh1024_p, sizeof dh1024_p, NULL);
788 dh->g = BN_bin2bn(dh1024_g, sizeof dh1024_g, NULL);
789
Remi Gacognef46cd6e2014-06-12 14:58:40 +0200790 if (!dh->p || !dh->g) {
791 DH_free(dh);
792 dh = NULL;
793 }
794 }
795 return dh;
796}
797
798static DH *ssl_get_dh_2048(void)
799{
Remi Gacogne2ad3ec12015-05-29 16:26:17 +0200800 static unsigned char dh2048_p[]={
801 0xEC,0x86,0xF8,0x70,0xA0,0x33,0x16,0xEC,0x05,0x1A,0x73,0x59,
802 0xCD,0x1F,0x8B,0xF8,0x29,0xE4,0xD2,0xCF,0x52,0xDD,0xC2,0x24,
803 0x8D,0xB5,0x38,0x9A,0xFB,0x5C,0xA4,0xE4,0xB2,0xDA,0xCE,0x66,
804 0x50,0x74,0xA6,0x85,0x4D,0x4B,0x1D,0x30,0xB8,0x2B,0xF3,0x10,
805 0xE9,0xA7,0x2D,0x05,0x71,0xE7,0x81,0xDF,0x8B,0x59,0x52,0x3B,
806 0x5F,0x43,0x0B,0x68,0xF1,0xDB,0x07,0xBE,0x08,0x6B,0x1B,0x23,
807 0xEE,0x4D,0xCC,0x9E,0x0E,0x43,0xA0,0x1E,0xDF,0x43,0x8C,0xEC,
808 0xBE,0xBE,0x90,0xB4,0x51,0x54,0xB9,0x2F,0x7B,0x64,0x76,0x4E,
809 0x5D,0xD4,0x2E,0xAE,0xC2,0x9E,0xAE,0x51,0x43,0x59,0xC7,0x77,
810 0x9C,0x50,0x3C,0x0E,0xED,0x73,0x04,0x5F,0xF1,0x4C,0x76,0x2A,
811 0xD8,0xF8,0xCF,0xFC,0x34,0x40,0xD1,0xB4,0x42,0x61,0x84,0x66,
812 0x42,0x39,0x04,0xF8,0x68,0xB2,0x62,0xD7,0x55,0xED,0x1B,0x74,
813 0x75,0x91,0xE0,0xC5,0x69,0xC1,0x31,0x5C,0xDB,0x7B,0x44,0x2E,
814 0xCE,0x84,0x58,0x0D,0x1E,0x66,0x0C,0xC8,0x44,0x9E,0xFD,0x40,
815 0x08,0x67,0x5D,0xFB,0xA7,0x76,0x8F,0x00,0x11,0x87,0xE9,0x93,
816 0xF9,0x7D,0xC4,0xBC,0x74,0x55,0x20,0xD4,0x4A,0x41,0x2F,0x43,
817 0x42,0x1A,0xC1,0xF2,0x97,0x17,0x49,0x27,0x37,0x6B,0x2F,0x88,
818 0x7E,0x1C,0xA0,0xA1,0x89,0x92,0x27,0xD9,0x56,0x5A,0x71,0xC1,
819 0x56,0x37,0x7E,0x3A,0x9D,0x05,0xE7,0xEE,0x5D,0x8F,0x82,0x17,
820 0xBC,0xE9,0xC2,0x93,0x30,0x82,0xF9,0xF4,0xC9,0xAE,0x49,0xDB,
821 0xD0,0x54,0xB4,0xD9,0x75,0x4D,0xFA,0x06,0xB8,0xD6,0x38,0x41,
822 0xB7,0x1F,0x77,0xF3,
823 };
824 static unsigned char dh2048_g[]={
825 0x02,
826 };
827
Remi Gacognef46cd6e2014-06-12 14:58:40 +0200828 DH *dh = DH_new();
829 if (dh) {
Remi Gacogne2ad3ec12015-05-29 16:26:17 +0200830 dh->p = BN_bin2bn(dh2048_p, sizeof dh2048_p, NULL);
831 dh->g = BN_bin2bn(dh2048_g, sizeof dh2048_g, NULL);
832
Remi Gacognef46cd6e2014-06-12 14:58:40 +0200833 if (!dh->p || !dh->g) {
834 DH_free(dh);
835 dh = NULL;
836 }
837 }
838 return dh;
839}
840
841static DH *ssl_get_dh_4096(void)
842{
Remi Gacogne2ad3ec12015-05-29 16:26:17 +0200843 static unsigned char dh4096_p[]={
844 0xDE,0x16,0x94,0xCD,0x99,0x58,0x07,0xF1,0xF7,0x32,0x96,0x11,
845 0x04,0x82,0xD4,0x84,0x72,0x80,0x99,0x06,0xCA,0xF0,0xA3,0x68,
846 0x07,0xCE,0x64,0x50,0xE7,0x74,0x45,0x20,0x80,0x5E,0x4D,0xAD,
847 0xA5,0xB6,0xED,0xFA,0x80,0x6C,0x3B,0x35,0xC4,0x9A,0x14,0x6B,
848 0x32,0xBB,0xFD,0x1F,0x17,0x8E,0xB7,0x1F,0xD6,0xFA,0x3F,0x7B,
849 0xEE,0x16,0xA5,0x62,0x33,0x0D,0xED,0xBC,0x4E,0x58,0xE5,0x47,
850 0x4D,0xE9,0xAB,0x8E,0x38,0xD3,0x6E,0x90,0x57,0xE3,0x22,0x15,
851 0x33,0xBD,0xF6,0x43,0x45,0xB5,0x10,0x0A,0xBE,0x2C,0xB4,0x35,
852 0xB8,0x53,0x8D,0xAD,0xFB,0xA7,0x1F,0x85,0x58,0x41,0x7A,0x79,
853 0x20,0x68,0xB3,0xE1,0x3D,0x08,0x76,0xBF,0x86,0x0D,0x49,0xE3,
854 0x82,0x71,0x8C,0xB4,0x8D,0x81,0x84,0xD4,0xE7,0xBE,0x91,0xDC,
855 0x26,0x39,0x48,0x0F,0x35,0xC4,0xCA,0x65,0xE3,0x40,0x93,0x52,
856 0x76,0x58,0x7D,0xDD,0x51,0x75,0xDC,0x69,0x61,0xBF,0x47,0x2C,
857 0x16,0x68,0x2D,0xC9,0x29,0xD3,0xE6,0xC0,0x99,0x48,0xA0,0x9A,
858 0xC8,0x78,0xC0,0x6D,0x81,0x67,0x12,0x61,0x3F,0x71,0xBA,0x41,
859 0x1F,0x6C,0x89,0x44,0x03,0xBA,0x3B,0x39,0x60,0xAA,0x28,0x55,
860 0x59,0xAE,0xB8,0xFA,0xCB,0x6F,0xA5,0x1A,0xF7,0x2B,0xDD,0x52,
861 0x8A,0x8B,0xE2,0x71,0xA6,0x5E,0x7E,0xD8,0x2E,0x18,0xE0,0x66,
862 0xDF,0xDD,0x22,0x21,0x99,0x52,0x73,0xA6,0x33,0x20,0x65,0x0E,
863 0x53,0xE7,0x6B,0x9B,0xC5,0xA3,0x2F,0x97,0x65,0x76,0xD3,0x47,
864 0x23,0x77,0x12,0xB6,0x11,0x7B,0x24,0xED,0xF1,0xEF,0xC0,0xE2,
865 0xA3,0x7E,0x67,0x05,0x3E,0x96,0x4D,0x45,0xC2,0x18,0xD1,0x73,
866 0x9E,0x07,0xF3,0x81,0x6E,0x52,0x63,0xF6,0x20,0x76,0xB9,0x13,
867 0xD2,0x65,0x30,0x18,0x16,0x09,0x16,0x9E,0x8F,0xF1,0xD2,0x10,
868 0x5A,0xD3,0xD4,0xAF,0x16,0x61,0xDA,0x55,0x2E,0x18,0x5E,0x14,
869 0x08,0x54,0x2E,0x2A,0x25,0xA2,0x1A,0x9B,0x8B,0x32,0xA9,0xFD,
870 0xC2,0x48,0x96,0xE1,0x80,0xCA,0xE9,0x22,0x17,0xBB,0xCE,0x3E,
871 0x9E,0xED,0xC7,0xF1,0x1F,0xEC,0x17,0x21,0xDC,0x7B,0x82,0x48,
872 0x8E,0xBB,0x4B,0x9D,0x5B,0x04,0x04,0xDA,0xDB,0x39,0xDF,0x01,
873 0x40,0xC3,0xAA,0x26,0x23,0x89,0x75,0xC6,0x0B,0xD0,0xA2,0x60,
874 0x6A,0xF1,0xCC,0x65,0x18,0x98,0x1B,0x52,0xD2,0x74,0x61,0xCC,
875 0xBD,0x60,0xAE,0xA3,0xA0,0x66,0x6A,0x16,0x34,0x92,0x3F,0x41,
876 0x40,0x31,0x29,0xC0,0x2C,0x63,0xB2,0x07,0x8D,0xEB,0x94,0xB8,
877 0xE8,0x47,0x92,0x52,0x93,0x6A,0x1B,0x7E,0x1A,0x61,0xB3,0x1B,
878 0xF0,0xD6,0x72,0x9B,0xF1,0xB0,0xAF,0xBF,0x3E,0x65,0xEF,0x23,
879 0x1D,0x6F,0xFF,0x70,0xCD,0x8A,0x4C,0x8A,0xA0,0x72,0x9D,0xBE,
880 0xD4,0xBB,0x24,0x47,0x4A,0x68,0xB5,0xF5,0xC6,0xD5,0x7A,0xCD,
881 0xCA,0x06,0x41,0x07,0xAD,0xC2,0x1E,0xE6,0x54,0xA7,0xAD,0x03,
882 0xD9,0x12,0xC1,0x9C,0x13,0xB1,0xC9,0x0A,0x43,0x8E,0x1E,0x08,
883 0xCE,0x50,0x82,0x73,0x5F,0xA7,0x55,0x1D,0xD9,0x59,0xAC,0xB5,
884 0xEA,0x02,0x7F,0x6C,0x5B,0x74,0x96,0x98,0x67,0x24,0xA3,0x0F,
885 0x15,0xFC,0xA9,0x7D,0x3E,0x67,0xD1,0x70,0xF8,0x97,0xF3,0x67,
886 0xC5,0x8C,0x88,0x44,0x08,0x02,0xC7,0x2B,
Remi Gacognef46cd6e2014-06-12 14:58:40 +0200887 };
Remi Gacogne2ad3ec12015-05-29 16:26:17 +0200888 static unsigned char dh4096_g[]={
889 0x02,
890 };
Remi Gacognef46cd6e2014-06-12 14:58:40 +0200891
Remi Gacognef46cd6e2014-06-12 14:58:40 +0200892 DH *dh = DH_new();
893 if (dh) {
Remi Gacogne2ad3ec12015-05-29 16:26:17 +0200894 dh->p = BN_bin2bn(dh4096_p, sizeof dh4096_p, NULL);
895 dh->g = BN_bin2bn(dh4096_g, sizeof dh4096_g, NULL);
896
Remi Gacognef46cd6e2014-06-12 14:58:40 +0200897 if (!dh->p || !dh->g) {
898 DH_free(dh);
899 dh = NULL;
900 }
901 }
902 return dh;
903}
904
905/* Returns Diffie-Hellman parameters matching the private key length
906 but not exceeding global.tune.ssl_default_dh_param */
907static DH *ssl_get_tmp_dh(SSL *ssl, int export, int keylen)
908{
909 DH *dh = NULL;
910 EVP_PKEY *pkey = SSL_get_privatekey(ssl);
911 int type = pkey ? EVP_PKEY_type(pkey->type) : EVP_PKEY_NONE;
912
913 /* The keylen supplied by OpenSSL can only be 512 or 1024.
914 See ssl3_send_server_key_exchange() in ssl/s3_srvr.c
915 */
916 if (type == EVP_PKEY_RSA || type == EVP_PKEY_DSA) {
917 keylen = EVP_PKEY_bits(pkey);
918 }
919
920 if (keylen > global.tune.ssl_default_dh_param) {
921 keylen = global.tune.ssl_default_dh_param;
922 }
923
Remi Gacogne2ad3ec12015-05-29 16:26:17 +0200924 if (keylen >= 4096) {
Remi Gacogne60d7aeb2014-07-15 11:36:40 +0200925 dh = local_dh_4096;
Remi Gacognef46cd6e2014-06-12 14:58:40 +0200926 }
927 else if (keylen >= 2048) {
Remi Gacogne60d7aeb2014-07-15 11:36:40 +0200928 dh = local_dh_2048;
Remi Gacognef46cd6e2014-06-12 14:58:40 +0200929 }
930 else {
Remi Gacogne60d7aeb2014-07-15 11:36:40 +0200931 dh = local_dh_1024;
Remi Gacognef46cd6e2014-06-12 14:58:40 +0200932 }
933
934 return dh;
935}
936
Emeric Bruna4bcd9a2012-09-20 16:19:02 +0200937/* Loads Diffie-Hellman parameter from a file. Returns 1 if loaded, else -1
938 if an error occured, and 0 if parameter not found. */
Willy Tarreau6e774b42014-04-25 21:35:23 +0200939int ssl_sock_load_dh_params(SSL_CTX *ctx, const char *file)
Emeric Bruna4bcd9a2012-09-20 16:19:02 +0200940{
941 int ret = -1;
942 BIO *in;
943 DH *dh = NULL;
944
945 in = BIO_new(BIO_s_file());
946 if (in == NULL)
947 goto end;
948
949 if (BIO_read_filename(in, file) <= 0)
950 goto end;
951
952 dh = PEM_read_bio_DHparams(in, NULL, ctx->default_passwd_callback, ctx->default_passwd_callback_userdata);
Remi Gacognef46cd6e2014-06-12 14:58:40 +0200953 if (dh) {
954 ret = 1;
955 SSL_CTX_set_tmp_dh(ctx, dh);
Remi Gacogne5d769ca2015-05-28 16:23:00 +0200956
957 if (ssl_dh_ptr_index >= 0) {
958 /* store a pointer to the DH params to avoid complaining about
959 ssl-default-dh-param not being set for this SSL_CTX */
960 SSL_CTX_set_ex_data(ctx, ssl_dh_ptr_index, dh);
961 }
Remi Gacognef46cd6e2014-06-12 14:58:40 +0200962 }
963 else {
Emeric Brun41fdb3c2013-04-26 11:05:44 +0200964 /* Clear openssl global errors stack */
965 ERR_clear_error();
966
Remi Gacognef46cd6e2014-06-12 14:58:40 +0200967 if (global.tune.ssl_default_dh_param <= 1024) {
968 /* we are limited to DH parameter of 1024 bits anyway */
Remi Gacogne60d7aeb2014-07-15 11:36:40 +0200969 local_dh_1024 = ssl_get_dh_1024();
970 if (local_dh_1024 == NULL)
Remi Gacognef46cd6e2014-06-12 14:58:40 +0200971 goto end;
Willy Tarreau6e774b42014-04-25 21:35:23 +0200972
Remi Gacogne60d7aeb2014-07-15 11:36:40 +0200973 SSL_CTX_set_tmp_dh(ctx, local_dh_1024);
Remi Gacognef46cd6e2014-06-12 14:58:40 +0200974 }
975 else {
976 SSL_CTX_set_tmp_dh_callback(ctx, ssl_get_tmp_dh);
977 }
Willy Tarreau6e774b42014-04-25 21:35:23 +0200978
Emeric Brun41fdb3c2013-04-26 11:05:44 +0200979 ret = 0; /* DH params not found */
Emeric Bruna4bcd9a2012-09-20 16:19:02 +0200980 }
Emeric Brun644cde02012-12-14 11:21:13 +0100981
Emeric Bruna4bcd9a2012-09-20 16:19:02 +0200982end:
983 if (dh)
984 DH_free(dh);
985
986 if (in)
Emeric Brun41fdb3c2013-04-26 11:05:44 +0200987 BIO_free(in);
Emeric Bruna4bcd9a2012-09-20 16:19:02 +0200988
989 return ret;
990}
991#endif
992
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +0200993static int ssl_sock_add_cert_sni(SSL_CTX *ctx, struct bind_conf *s, char *name, int order)
Emmanuel Hocdetfe616562013-01-22 15:31:15 +0100994{
995 struct sni_ctx *sc;
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +0200996 int wild = 0, neg = 0;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +0100997
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +0200998 if (*name == '!') {
999 neg = 1;
1000 name++;
1001 }
1002 if (*name == '*') {
1003 wild = 1;
1004 name++;
1005 }
1006 /* !* filter is a nop */
1007 if (neg && wild)
1008 return order;
1009 if (*name) {
1010 int j, len;
1011 len = strlen(name);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001012 sc = malloc(sizeof(struct sni_ctx) + len + 1);
1013 for (j = 0; j < len; j++)
1014 sc->name.key[j] = tolower(name[j]);
1015 sc->name.key[len] = 0;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001016 sc->ctx = ctx;
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001017 sc->order = order++;
1018 sc->neg = neg;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001019 if (wild)
1020 ebst_insert(&s->sni_w_ctx, &sc->name);
1021 else
1022 ebst_insert(&s->sni_ctx, &sc->name);
1023 }
1024 return order;
1025}
1026
Emeric Brunfc0421f2012-09-07 17:30:07 +02001027/* Loads a certificate key and CA chain from a file. Returns 0 on error, -1 if
1028 * an early error happens and the caller must call SSL_CTX_free() by itelf.
1029 */
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001030static int ssl_sock_load_cert_chain_file(SSL_CTX *ctx, const char *file, struct bind_conf *s, char **sni_filter, int fcount)
Emeric Brunfc0421f2012-09-07 17:30:07 +02001031{
1032 BIO *in;
1033 X509 *x = NULL, *ca;
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001034 int i, err;
Emeric Brunfc0421f2012-09-07 17:30:07 +02001035 int ret = -1;
1036 int order = 0;
1037 X509_NAME *xname;
1038 char *str;
Emeric Brunfc0421f2012-09-07 17:30:07 +02001039#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
1040 STACK_OF(GENERAL_NAME) *names;
1041#endif
1042
1043 in = BIO_new(BIO_s_file());
1044 if (in == NULL)
1045 goto end;
1046
1047 if (BIO_read_filename(in, file) <= 0)
1048 goto end;
1049
1050 x = PEM_read_bio_X509_AUX(in, NULL, ctx->default_passwd_callback, ctx->default_passwd_callback_userdata);
1051 if (x == NULL)
1052 goto end;
1053
Emeric Brun50bcecc2013-04-22 13:05:23 +02001054 if (fcount) {
1055 while (fcount--)
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001056 order = ssl_sock_add_cert_sni(ctx, s, sni_filter[fcount], order);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001057 }
1058 else {
Emeric Brunfc0421f2012-09-07 17:30:07 +02001059#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001060 names = X509_get_ext_d2i(x, NID_subject_alt_name, NULL, NULL);
1061 if (names) {
1062 for (i = 0; i < sk_GENERAL_NAME_num(names); i++) {
1063 GENERAL_NAME *name = sk_GENERAL_NAME_value(names, i);
1064 if (name->type == GEN_DNS) {
1065 if (ASN1_STRING_to_UTF8((unsigned char **)&str, name->d.dNSName) >= 0) {
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001066 order = ssl_sock_add_cert_sni(ctx, s, str, order);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001067 OPENSSL_free(str);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001068 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02001069 }
1070 }
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001071 sk_GENERAL_NAME_pop_free(names, GENERAL_NAME_free);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001072 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02001073#endif /* SSL_CTRL_SET_TLSEXT_HOSTNAME */
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001074 xname = X509_get_subject_name(x);
1075 i = -1;
1076 while ((i = X509_NAME_get_index_by_NID(xname, NID_commonName, i)) != -1) {
1077 X509_NAME_ENTRY *entry = X509_NAME_get_entry(xname, i);
1078 if (ASN1_STRING_to_UTF8((unsigned char **)&str, entry->value) >= 0) {
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001079 order = ssl_sock_add_cert_sni(ctx, s, str, order);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001080 OPENSSL_free(str);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001081 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02001082 }
1083 }
1084
1085 ret = 0; /* the caller must not free the SSL_CTX argument anymore */
1086 if (!SSL_CTX_use_certificate(ctx, x))
1087 goto end;
1088
1089 if (ctx->extra_certs != NULL) {
1090 sk_X509_pop_free(ctx->extra_certs, X509_free);
1091 ctx->extra_certs = NULL;
1092 }
1093
1094 while ((ca = PEM_read_bio_X509(in, NULL, ctx->default_passwd_callback, ctx->default_passwd_callback_userdata))) {
1095 if (!SSL_CTX_add_extra_chain_cert(ctx, ca)) {
1096 X509_free(ca);
1097 goto end;
1098 }
1099 }
1100
1101 err = ERR_get_error();
1102 if (!err || (ERR_GET_LIB(err) == ERR_LIB_PEM && ERR_GET_REASON(err) == PEM_R_NO_START_LINE)) {
1103 /* we successfully reached the last cert in the file */
1104 ret = 1;
1105 }
1106 ERR_clear_error();
1107
1108end:
1109 if (x)
1110 X509_free(x);
1111
1112 if (in)
1113 BIO_free(in);
1114
1115 return ret;
1116}
1117
Emeric Brun50bcecc2013-04-22 13:05:23 +02001118static int ssl_sock_load_cert_file(const char *path, struct bind_conf *bind_conf, struct proxy *curproxy, char **sni_filter, int fcount, char **err)
Emeric Brunfc0421f2012-09-07 17:30:07 +02001119{
1120 int ret;
1121 SSL_CTX *ctx;
1122
1123 ctx = SSL_CTX_new(SSLv23_server_method());
1124 if (!ctx) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02001125 memprintf(err, "%sunable to allocate SSL context for cert '%s'.\n",
1126 err && *err ? *err : "", path);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001127 return 1;
1128 }
1129
1130 if (SSL_CTX_use_PrivateKey_file(ctx, path, SSL_FILETYPE_PEM) <= 0) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02001131 memprintf(err, "%sunable to load SSL private key from PEM file '%s'.\n",
1132 err && *err ? *err : "", path);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001133 SSL_CTX_free(ctx);
1134 return 1;
1135 }
1136
Emeric Brun50bcecc2013-04-22 13:05:23 +02001137 ret = ssl_sock_load_cert_chain_file(ctx, path, bind_conf, sni_filter, fcount);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001138 if (ret <= 0) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02001139 memprintf(err, "%sunable to load SSL certificate from PEM file '%s'.\n",
1140 err && *err ? *err : "", path);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001141 if (ret < 0) /* serious error, must do that ourselves */
1142 SSL_CTX_free(ctx);
1143 return 1;
1144 }
Emeric Brun61694ab2012-10-26 13:35:33 +02001145
1146 if (SSL_CTX_check_private_key(ctx) <= 0) {
1147 memprintf(err, "%sinconsistencies between private key and certificate loaded from PEM file '%s'.\n",
1148 err && *err ? *err : "", path);
1149 return 1;
1150 }
1151
Emeric Brunfc0421f2012-09-07 17:30:07 +02001152 /* we must not free the SSL_CTX anymore below, since it's already in
1153 * the tree, so it will be discovered and cleaned in time.
1154 */
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001155#ifndef OPENSSL_NO_DH
Remi Gacogne5d769ca2015-05-28 16:23:00 +02001156 /* store a NULL pointer to indicate we have not yet loaded
1157 a custom DH param file */
1158 if (ssl_dh_ptr_index >= 0) {
1159 SSL_CTX_set_ex_data(ctx, ssl_dh_ptr_index, NULL);
1160 }
1161
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001162 ret = ssl_sock_load_dh_params(ctx, path);
1163 if (ret < 0) {
1164 if (err)
1165 memprintf(err, "%sunable to load DH parameters from file '%s'.\n",
1166 *err ? *err : "", path);
1167 return 1;
1168 }
1169#endif
1170
Emeric Brun4147b2e2014-06-16 18:36:30 +02001171#ifdef SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB
1172 ret = ssl_sock_load_ocsp(ctx, path);
1173 if (ret < 0) {
1174 if (err)
1175 memprintf(err, "%s '%s.ocsp' is present and activates OCSP but it is impossible to compute the OCSP certificate ID (maybe the issuer could not be found)'.\n",
1176 *err ? *err : "", path);
1177 return 1;
1178 }
1179#endif
1180
Emeric Brunfc0421f2012-09-07 17:30:07 +02001181#ifndef SSL_CTRL_SET_TLSEXT_HOSTNAME
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001182 if (bind_conf->default_ctx) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02001183 memprintf(err, "%sthis version of openssl cannot load multiple SSL certificates.\n",
1184 err && *err ? *err : "");
Emeric Brunfc0421f2012-09-07 17:30:07 +02001185 return 1;
1186 }
1187#endif
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001188 if (!bind_conf->default_ctx)
1189 bind_conf->default_ctx = ctx;
Emeric Brunfc0421f2012-09-07 17:30:07 +02001190
1191 return 0;
1192}
1193
Willy Tarreau79eeafa2012-09-14 07:53:05 +02001194int ssl_sock_load_cert(char *path, struct bind_conf *bind_conf, struct proxy *curproxy, char **err)
Emeric Brunfc0421f2012-09-07 17:30:07 +02001195{
Cyril Bonté62043c92015-01-25 00:16:08 +01001196 struct dirent **de_list;
1197 int i, n;
Emeric Brunfc0421f2012-09-07 17:30:07 +02001198 DIR *dir;
1199 struct stat buf;
Willy Tarreauee2663b2012-12-06 11:36:59 +01001200 char *end;
1201 char fp[MAXPATHLEN+1];
Emeric Brunfc0421f2012-09-07 17:30:07 +02001202 int cfgerr = 0;
1203
1204 if (!(dir = opendir(path)))
Emeric Brun50bcecc2013-04-22 13:05:23 +02001205 return ssl_sock_load_cert_file(path, bind_conf, curproxy, NULL, 0, err);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001206
1207 /* strip trailing slashes, including first one */
1208 for (end = path + strlen(path) - 1; end >= path && *end == '/'; end--)
1209 *end = 0;
1210
Cyril Bonté62043c92015-01-25 00:16:08 +01001211 n = scandir(path, &de_list, 0, alphasort);
1212 if (n < 0) {
1213 memprintf(err, "%sunable to scan directory '%s' : %s.\n",
1214 err && *err ? *err : "", path, strerror(errno));
1215 cfgerr++;
1216 }
1217 else {
1218 for (i = 0; i < n; i++) {
1219 struct dirent *de = de_list[i];
Emeric Brun2aab7222014-06-18 18:15:09 +02001220
Cyril Bonté62043c92015-01-25 00:16:08 +01001221 end = strrchr(de->d_name, '.');
1222 if (end && (!strcmp(end, ".issuer") || !strcmp(end, ".ocsp")))
1223 goto ignore_entry;
1224
1225 snprintf(fp, sizeof(fp), "%s/%s", path, de->d_name);
1226 if (stat(fp, &buf) != 0) {
1227 memprintf(err, "%sunable to stat SSL certificate from file '%s' : %s.\n",
1228 err && *err ? *err : "", fp, strerror(errno));
1229 cfgerr++;
1230 goto ignore_entry;
1231 }
1232 if (!S_ISREG(buf.st_mode))
1233 goto ignore_entry;
1234 cfgerr += ssl_sock_load_cert_file(fp, bind_conf, curproxy, NULL, 0, err);
1235 ignore_entry:
1236 free(de);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001237 }
Cyril Bonté62043c92015-01-25 00:16:08 +01001238 free(de_list);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001239 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02001240 closedir(dir);
1241 return cfgerr;
1242}
1243
Thierry Fournier383085f2013-01-24 14:15:43 +01001244/* Make sure openssl opens /dev/urandom before the chroot. The work is only
1245 * done once. Zero is returned if the operation fails. No error is returned
1246 * if the random is said as not implemented, because we expect that openssl
1247 * will use another method once needed.
1248 */
1249static int ssl_initialize_random()
1250{
1251 unsigned char random;
1252 static int random_initialized = 0;
1253
1254 if (!random_initialized && RAND_bytes(&random, 1) != 0)
1255 random_initialized = 1;
1256
1257 return random_initialized;
1258}
1259
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001260int ssl_sock_load_cert_list_file(char *file, struct bind_conf *bind_conf, struct proxy *curproxy, char **err)
1261{
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001262 char thisline[LINESIZE];
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001263 FILE *f;
1264 int linenum = 0;
1265 int cfgerr = 0;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001266
Willy Tarreauad1731d2013-04-02 17:35:58 +02001267 if ((f = fopen(file, "r")) == NULL) {
1268 memprintf(err, "cannot open file '%s' : %s", file, strerror(errno));
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001269 return 1;
Willy Tarreauad1731d2013-04-02 17:35:58 +02001270 }
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001271
1272 while (fgets(thisline, sizeof(thisline), f) != NULL) {
1273 int arg;
Emeric Brun50bcecc2013-04-22 13:05:23 +02001274 int newarg;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001275 char *end;
1276 char *args[MAX_LINE_ARGS + 1];
1277 char *line = thisline;
1278
1279 linenum++;
1280 end = line + strlen(line);
1281 if (end-line == sizeof(thisline)-1 && *(end-1) != '\n') {
1282 /* Check if we reached the limit and the last char is not \n.
1283 * Watch out for the last line without the terminating '\n'!
1284 */
Willy Tarreauad1731d2013-04-02 17:35:58 +02001285 memprintf(err, "line %d too long in file '%s', limit is %d characters",
1286 linenum, file, (int)sizeof(thisline)-1);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001287 cfgerr = 1;
Willy Tarreauad1731d2013-04-02 17:35:58 +02001288 break;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001289 }
1290
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001291 arg = 0;
Emeric Brun50bcecc2013-04-22 13:05:23 +02001292 newarg = 1;
1293 while (*line) {
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001294 if (*line == '#' || *line == '\n' || *line == '\r') {
1295 /* end of string, end of loop */
1296 *line = 0;
1297 break;
1298 }
1299 else if (isspace(*line)) {
Emeric Brun50bcecc2013-04-22 13:05:23 +02001300 newarg = 1;
1301 *line = 0;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001302 }
Emeric Brun50bcecc2013-04-22 13:05:23 +02001303 else if (newarg) {
1304 if (arg == MAX_LINE_ARGS) {
1305 memprintf(err, "too many args on line %d in file '%s'.",
1306 linenum, file);
1307 cfgerr = 1;
1308 break;
1309 }
1310 newarg = 0;
1311 args[arg++] = line;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001312 }
Emeric Brun50bcecc2013-04-22 13:05:23 +02001313 line++;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001314 }
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001315 if (cfgerr)
1316 break;
Willy Tarreauad1731d2013-04-02 17:35:58 +02001317
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001318 /* empty line */
Emeric Brun50bcecc2013-04-22 13:05:23 +02001319 if (!arg)
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001320 continue;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001321
Emeric Brun50bcecc2013-04-22 13:05:23 +02001322 cfgerr = ssl_sock_load_cert_file(args[0], bind_conf, curproxy, &args[1], arg-1, err);
Willy Tarreauad1731d2013-04-02 17:35:58 +02001323 if (cfgerr) {
1324 memprintf(err, "error processing line %d in file '%s' : %s", linenum, file, *err);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001325 break;
Willy Tarreauad1731d2013-04-02 17:35:58 +02001326 }
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001327 }
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001328 fclose(f);
1329 return cfgerr;
1330}
1331
Emeric Brunfc0421f2012-09-07 17:30:07 +02001332#ifndef SSL_OP_CIPHER_SERVER_PREFERENCE /* needs OpenSSL >= 0.9.7 */
1333#define SSL_OP_CIPHER_SERVER_PREFERENCE 0
1334#endif
1335
1336#ifndef SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION /* needs OpenSSL >= 0.9.7 */
1337#define SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION 0
Willy Tarreau7d588ee2012-11-26 18:47:31 +01001338#define SSL_renegotiate_pending(arg) 0
Emeric Brunfc0421f2012-09-07 17:30:07 +02001339#endif
Emeric Brun2b58d042012-09-20 17:10:03 +02001340#ifndef SSL_OP_SINGLE_ECDH_USE /* needs OpenSSL >= 0.9.8 */
1341#define SSL_OP_SINGLE_ECDH_USE 0
1342#endif
Emeric Brun2d0c4822012-10-02 13:45:20 +02001343#ifndef SSL_OP_NO_TICKET /* needs OpenSSL >= 0.9.8 */
1344#define SSL_OP_NO_TICKET 0
1345#endif
Emeric Brunfc0421f2012-09-07 17:30:07 +02001346#ifndef SSL_OP_NO_COMPRESSION /* needs OpenSSL >= 0.9.9 */
1347#define SSL_OP_NO_COMPRESSION 0
1348#endif
Emeric Brunc0ff4922012-09-28 19:37:02 +02001349#ifndef SSL_OP_NO_TLSv1_1 /* needs OpenSSL >= 1.0.1 */
1350#define SSL_OP_NO_TLSv1_1 0
1351#endif
1352#ifndef SSL_OP_NO_TLSv1_2 /* needs OpenSSL >= 1.0.1 */
1353#define SSL_OP_NO_TLSv1_2 0
1354#endif
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001355#ifndef SSL_OP_SINGLE_DH_USE /* needs OpenSSL >= 0.9.6 */
1356#define SSL_OP_SINGLE_DH_USE 0
1357#endif
Emeric Brun2b58d042012-09-20 17:10:03 +02001358#ifndef SSL_OP_SINGLE_ECDH_USE /* needs OpenSSL >= 1.0.0 */
1359#define SSL_OP_SINGLE_ECDH_USE 0
1360#endif
Emeric Brunfc0421f2012-09-07 17:30:07 +02001361#ifndef SSL_MODE_RELEASE_BUFFERS /* needs OpenSSL >= 1.0.0 */
1362#define SSL_MODE_RELEASE_BUFFERS 0
1363#endif
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001364
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001365int ssl_sock_prepare_ctx(struct bind_conf *bind_conf, SSL_CTX *ctx, struct proxy *curproxy)
Emeric Brunfc0421f2012-09-07 17:30:07 +02001366{
1367 int cfgerr = 0;
Emeric Brun850efd52014-01-29 12:24:34 +01001368 int verify = SSL_VERIFY_NONE;
Remi Gacogneaf5c3da2014-05-19 10:29:58 +02001369 long ssloptions =
Emeric Brunfc0421f2012-09-07 17:30:07 +02001370 SSL_OP_ALL | /* all known workarounds for bugs */
1371 SSL_OP_NO_SSLv2 |
1372 SSL_OP_NO_COMPRESSION |
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001373 SSL_OP_SINGLE_DH_USE |
Emeric Brun2b58d042012-09-20 17:10:03 +02001374 SSL_OP_SINGLE_ECDH_USE |
Emeric Brun3c4bc6e2012-10-04 18:44:19 +02001375 SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION |
1376 SSL_OP_CIPHER_SERVER_PREFERENCE;
Remi Gacogneaf5c3da2014-05-19 10:29:58 +02001377 long sslmode =
Emeric Brunfc0421f2012-09-07 17:30:07 +02001378 SSL_MODE_ENABLE_PARTIAL_WRITE |
1379 SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER |
1380 SSL_MODE_RELEASE_BUFFERS;
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001381 STACK_OF(SSL_CIPHER) * ciphers = NULL;
1382 SSL_CIPHER * cipher = NULL;
Remi Gacognec1eab8c2014-06-12 18:20:11 +02001383 char cipher_description[128];
1384 /* The description of ciphers using an Ephemeral Diffie Hellman key exchange
1385 contains " Kx=DH " or " Kx=DH(". Beware of " Kx=DH/",
1386 which is not ephemeral DH. */
1387 const char dhe_description[] = " Kx=DH ";
1388 const char dhe_export_description[] = " Kx=DH(";
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001389 int idx = 0;
1390 int dhe_found = 0;
Emeric Brunfc0421f2012-09-07 17:30:07 +02001391
Thierry Fournier383085f2013-01-24 14:15:43 +01001392 /* Make sure openssl opens /dev/urandom before the chroot */
1393 if (!ssl_initialize_random()) {
1394 Alert("OpenSSL random data generator initialization failed.\n");
1395 cfgerr++;
1396 }
1397
Emeric Brun89675492012-10-05 13:48:26 +02001398 if (bind_conf->ssl_options & BC_SSL_O_NO_SSLV3)
Emeric Brunfc0421f2012-09-07 17:30:07 +02001399 ssloptions |= SSL_OP_NO_SSLv3;
Emeric Brun89675492012-10-05 13:48:26 +02001400 if (bind_conf->ssl_options & BC_SSL_O_NO_TLSV10)
Emeric Brunfc0421f2012-09-07 17:30:07 +02001401 ssloptions |= SSL_OP_NO_TLSv1;
Emeric Brun89675492012-10-05 13:48:26 +02001402 if (bind_conf->ssl_options & BC_SSL_O_NO_TLSV11)
Emeric Brunc0ff4922012-09-28 19:37:02 +02001403 ssloptions |= SSL_OP_NO_TLSv1_1;
Emeric Brun89675492012-10-05 13:48:26 +02001404 if (bind_conf->ssl_options & BC_SSL_O_NO_TLSV12)
Emeric Brunc0ff4922012-09-28 19:37:02 +02001405 ssloptions |= SSL_OP_NO_TLSv1_2;
Emeric Brun89675492012-10-05 13:48:26 +02001406 if (bind_conf->ssl_options & BC_SSL_O_NO_TLS_TICKETS)
Emeric Brun2d0c4822012-10-02 13:45:20 +02001407 ssloptions |= SSL_OP_NO_TICKET;
Emeric Brun2cb7ae52012-10-05 14:14:21 +02001408 if (bind_conf->ssl_options & BC_SSL_O_USE_SSLV3)
1409 SSL_CTX_set_ssl_version(ctx, SSLv3_server_method());
1410 if (bind_conf->ssl_options & BC_SSL_O_USE_TLSV10)
1411 SSL_CTX_set_ssl_version(ctx, TLSv1_server_method());
1412#if SSL_OP_NO_TLSv1_1
1413 if (bind_conf->ssl_options & BC_SSL_O_USE_TLSV11)
1414 SSL_CTX_set_ssl_version(ctx, TLSv1_1_server_method());
1415#endif
1416#if SSL_OP_NO_TLSv1_2
1417 if (bind_conf->ssl_options & BC_SSL_O_USE_TLSV12)
1418 SSL_CTX_set_ssl_version(ctx, TLSv1_2_server_method());
1419#endif
Emeric Brunfc0421f2012-09-07 17:30:07 +02001420
1421 SSL_CTX_set_options(ctx, ssloptions);
1422 SSL_CTX_set_mode(ctx, sslmode);
Emeric Brun850efd52014-01-29 12:24:34 +01001423 switch (bind_conf->verify) {
1424 case SSL_SOCK_VERIFY_NONE:
1425 verify = SSL_VERIFY_NONE;
1426 break;
1427 case SSL_SOCK_VERIFY_OPTIONAL:
1428 verify = SSL_VERIFY_PEER;
1429 break;
1430 case SSL_SOCK_VERIFY_REQUIRED:
1431 verify = SSL_VERIFY_PEER|SSL_VERIFY_FAIL_IF_NO_PEER_CERT;
1432 break;
1433 }
1434 SSL_CTX_set_verify(ctx, verify, ssl_sock_bind_verifycbk);
1435 if (verify & SSL_VERIFY_PEER) {
Emeric Brunfb510ea2012-10-05 12:00:26 +02001436 if (bind_conf->ca_file) {
Emeric Brund94b3fe2012-09-20 18:23:56 +02001437 /* load CAfile to verify */
Emeric Brunfb510ea2012-10-05 12:00:26 +02001438 if (!SSL_CTX_load_verify_locations(ctx, bind_conf->ca_file, NULL)) {
Emeric Brund94b3fe2012-09-20 18:23:56 +02001439 Alert("Proxy '%s': unable to load CA file '%s' for bind '%s' at [%s:%d].\n",
Emeric Brunfb510ea2012-10-05 12:00:26 +02001440 curproxy->id, bind_conf->ca_file, bind_conf->arg, bind_conf->file, bind_conf->line);
Emeric Brund94b3fe2012-09-20 18:23:56 +02001441 cfgerr++;
1442 }
1443 /* set CA names fo client cert request, function returns void */
Emeric Brunfb510ea2012-10-05 12:00:26 +02001444 SSL_CTX_set_client_CA_list(ctx, SSL_load_client_CA_file(bind_conf->ca_file));
Emeric Brund94b3fe2012-09-20 18:23:56 +02001445 }
Emeric Brun850efd52014-01-29 12:24:34 +01001446 else {
1447 Alert("Proxy '%s': verify is enabled but no CA file specified for bind '%s' at [%s:%d].\n",
1448 curproxy->id, bind_conf->arg, bind_conf->file, bind_conf->line);
1449 cfgerr++;
1450 }
Emeric Brun051cdab2012-10-02 19:25:50 +02001451#ifdef X509_V_FLAG_CRL_CHECK
Emeric Brunfb510ea2012-10-05 12:00:26 +02001452 if (bind_conf->crl_file) {
Emeric Brund94b3fe2012-09-20 18:23:56 +02001453 X509_STORE *store = SSL_CTX_get_cert_store(ctx);
1454
Emeric Brunfb510ea2012-10-05 12:00:26 +02001455 if (!store || !X509_STORE_load_locations(store, bind_conf->crl_file, NULL)) {
Emeric Brund94b3fe2012-09-20 18:23:56 +02001456 Alert("Proxy '%s': unable to configure CRL file '%s' for bind '%s' at [%s:%d].\n",
Alexander Rigbo37dc94c2015-04-07 14:02:16 +02001457 curproxy->id, bind_conf->crl_file, bind_conf->arg, bind_conf->file, bind_conf->line);
Emeric Brund94b3fe2012-09-20 18:23:56 +02001458 cfgerr++;
1459 }
Emeric Brun561e5742012-10-02 15:20:55 +02001460 else {
1461 X509_STORE_set_flags(store, X509_V_FLAG_CRL_CHECK|X509_V_FLAG_CRL_CHECK_ALL);
1462 }
Emeric Brund94b3fe2012-09-20 18:23:56 +02001463 }
Emeric Brun051cdab2012-10-02 19:25:50 +02001464#endif
Emeric Brun644cde02012-12-14 11:21:13 +01001465 ERR_clear_error();
Emeric Brund94b3fe2012-09-20 18:23:56 +02001466 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02001467
Emeric Brun4f65bff2012-11-16 15:11:00 +01001468 if (global.tune.ssllifetime)
1469 SSL_CTX_set_timeout(ctx, global.tune.ssllifetime);
1470
Emeric Brunfc0421f2012-09-07 17:30:07 +02001471 shared_context_set_cache(ctx);
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001472 if (bind_conf->ciphers &&
1473 !SSL_CTX_set_cipher_list(ctx, bind_conf->ciphers)) {
Emeric Brunfc0421f2012-09-07 17:30:07 +02001474 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 +02001475 curproxy->id, bind_conf->ciphers, bind_conf->arg, bind_conf->file, bind_conf->line);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001476 cfgerr++;
1477 }
1478
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001479 /* If tune.ssl.default-dh-param has not been set and
1480 no static DH params were in the certificate file. */
Remi Gacogne5d769ca2015-05-28 16:23:00 +02001481 if (global.tune.ssl_default_dh_param == 0 &&
1482 (ssl_dh_ptr_index == -1 ||
1483 SSL_CTX_get_ex_data(ctx, ssl_dh_ptr_index) == NULL)) {
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001484 ciphers = ctx->cipher_list;
1485
1486 if (ciphers) {
1487 for (idx = 0; idx < sk_SSL_CIPHER_num(ciphers); idx++) {
1488 cipher = sk_SSL_CIPHER_value(ciphers, idx);
Remi Gacognec1eab8c2014-06-12 18:20:11 +02001489 if (SSL_CIPHER_description(cipher, cipher_description, sizeof (cipher_description)) == cipher_description) {
1490 if (strstr(cipher_description, dhe_description) != NULL ||
1491 strstr(cipher_description, dhe_export_description) != NULL) {
1492 dhe_found = 1;
1493 break;
1494 }
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001495 }
1496 }
1497
1498 if (dhe_found) {
1499 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");
1500 }
1501 }
1502
1503 global.tune.ssl_default_dh_param = 1024;
1504 }
Remi Gacogne60d7aeb2014-07-15 11:36:40 +02001505
1506#ifndef OPENSSL_NO_DH
1507 if (global.tune.ssl_default_dh_param >= 1024) {
1508 if (local_dh_1024 == NULL) {
1509 local_dh_1024 = ssl_get_dh_1024();
1510 }
1511 if (global.tune.ssl_default_dh_param >= 2048) {
1512 if (local_dh_2048 == NULL) {
1513 local_dh_2048 = ssl_get_dh_2048();
1514 }
1515 if (global.tune.ssl_default_dh_param >= 4096) {
1516 if (local_dh_4096 == NULL) {
1517 local_dh_4096 = ssl_get_dh_4096();
1518 }
Remi Gacogne60d7aeb2014-07-15 11:36:40 +02001519 }
1520 }
1521 }
1522#endif /* OPENSSL_NO_DH */
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001523
Emeric Brunfc0421f2012-09-07 17:30:07 +02001524 SSL_CTX_set_info_callback(ctx, ssl_sock_infocbk);
Willy Tarreau5cbe4ef2014-05-08 22:45:11 +02001525#if OPENSSL_VERSION_NUMBER >= 0x00907000L
Emeric Brun29f037d2014-04-25 19:05:36 +02001526 SSL_CTX_set_msg_callback(ctx, ssl_sock_msgcbk);
Willy Tarreau5cbe4ef2014-05-08 22:45:11 +02001527#endif
Emeric Brun29f037d2014-04-25 19:05:36 +02001528
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02001529#ifdef OPENSSL_NPN_NEGOTIATED
1530 if (bind_conf->npn_str)
1531 SSL_CTX_set_next_protos_advertised_cb(ctx, ssl_sock_advertise_npn_protos, bind_conf);
1532#endif
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01001533#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Willy Tarreauab861d32013-04-02 02:30:41 +02001534 if (bind_conf->alpn_str)
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01001535 SSL_CTX_set_alpn_select_cb(ctx, ssl_sock_advertise_alpn_protos, bind_conf);
Willy Tarreauab861d32013-04-02 02:30:41 +02001536#endif
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02001537
Emeric Brunfc0421f2012-09-07 17:30:07 +02001538#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
1539 SSL_CTX_set_tlsext_servername_callback(ctx, ssl_sock_switchctx_cbk);
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001540 SSL_CTX_set_tlsext_servername_arg(ctx, bind_conf);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001541#endif
Emeric Brun2b58d042012-09-20 17:10:03 +02001542#if defined(SSL_CTX_set_tmp_ecdh) && !defined(OPENSSL_NO_ECDH)
Emeric Brun6924ef82013-03-06 14:08:53 +01001543 {
Emeric Brun2b58d042012-09-20 17:10:03 +02001544 int i;
1545 EC_KEY *ecdh;
1546
Emeric Brun6924ef82013-03-06 14:08:53 +01001547 i = OBJ_sn2nid(bind_conf->ecdhe ? bind_conf->ecdhe : ECDHE_DEFAULT_CURVE);
Emeric Brun2b58d042012-09-20 17:10:03 +02001548 if (!i || ((ecdh = EC_KEY_new_by_curve_name(i)) == NULL)) {
1549 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 +01001550 curproxy->id, bind_conf->ecdhe ? bind_conf->ecdhe : ECDHE_DEFAULT_CURVE,
1551 bind_conf->arg, bind_conf->file, bind_conf->line);
Emeric Brun2b58d042012-09-20 17:10:03 +02001552 cfgerr++;
1553 }
1554 else {
1555 SSL_CTX_set_tmp_ecdh(ctx, ecdh);
1556 EC_KEY_free(ecdh);
1557 }
1558 }
1559#endif
1560
Emeric Brunfc0421f2012-09-07 17:30:07 +02001561 return cfgerr;
1562}
1563
Evan Broderbe554312013-06-27 00:05:25 -07001564static int ssl_sock_srv_hostcheck(const char *pattern, const char *hostname)
1565{
1566 const char *pattern_wildcard, *pattern_left_label_end, *hostname_left_label_end;
1567 size_t prefixlen, suffixlen;
1568
1569 /* Trivial case */
1570 if (strcmp(pattern, hostname) == 0)
1571 return 1;
1572
Evan Broderbe554312013-06-27 00:05:25 -07001573 /* The rest of this logic is based on RFC 6125, section 6.4.3
1574 * (http://tools.ietf.org/html/rfc6125#section-6.4.3) */
1575
Emeric Bruna848dae2013-10-08 11:27:28 +02001576 pattern_wildcard = NULL;
1577 pattern_left_label_end = pattern;
1578 while (*pattern_left_label_end != '.') {
1579 switch (*pattern_left_label_end) {
1580 case 0:
1581 /* End of label not found */
1582 return 0;
1583 case '*':
1584 /* If there is more than one wildcards */
1585 if (pattern_wildcard)
1586 return 0;
1587 pattern_wildcard = pattern_left_label_end;
1588 break;
1589 }
1590 pattern_left_label_end++;
1591 }
1592
1593 /* If it's not trivial and there is no wildcard, it can't
1594 * match */
1595 if (!pattern_wildcard)
Evan Broderbe554312013-06-27 00:05:25 -07001596 return 0;
1597
1598 /* Make sure all labels match except the leftmost */
1599 hostname_left_label_end = strchr(hostname, '.');
1600 if (!hostname_left_label_end
1601 || strcmp(pattern_left_label_end, hostname_left_label_end) != 0)
1602 return 0;
1603
1604 /* Make sure the leftmost label of the hostname is long enough
1605 * that the wildcard can match */
Emeric Brun369da852013-10-08 11:39:35 +02001606 if (hostname_left_label_end - hostname < (pattern_left_label_end - pattern) - 1)
Evan Broderbe554312013-06-27 00:05:25 -07001607 return 0;
1608
1609 /* Finally compare the string on either side of the
1610 * wildcard */
1611 prefixlen = pattern_wildcard - pattern;
1612 suffixlen = pattern_left_label_end - (pattern_wildcard + 1);
Emeric Bruna848dae2013-10-08 11:27:28 +02001613 if ((prefixlen && (memcmp(pattern, hostname, prefixlen) != 0))
1614 || (suffixlen && (memcmp(pattern_wildcard + 1, hostname_left_label_end - suffixlen, suffixlen) != 0)))
Evan Broderbe554312013-06-27 00:05:25 -07001615 return 0;
1616
1617 return 1;
1618}
1619
1620static int ssl_sock_srv_verifycbk(int ok, X509_STORE_CTX *ctx)
1621{
1622 SSL *ssl;
1623 struct connection *conn;
1624 char *servername;
1625
1626 int depth;
1627 X509 *cert;
1628 STACK_OF(GENERAL_NAME) *alt_names;
1629 int i;
1630 X509_NAME *cert_subject;
1631 char *str;
1632
1633 if (ok == 0)
1634 return ok;
1635
1636 ssl = X509_STORE_CTX_get_ex_data(ctx, SSL_get_ex_data_X509_STORE_CTX_idx());
1637 conn = (struct connection *)SSL_get_app_data(ssl);
1638
1639 servername = objt_server(conn->target)->ssl_ctx.verify_host;
1640
1641 /* We only need to verify the CN on the actual server cert,
1642 * not the indirect CAs */
1643 depth = X509_STORE_CTX_get_error_depth(ctx);
1644 if (depth != 0)
1645 return ok;
1646
1647 /* At this point, the cert is *not* OK unless we can find a
1648 * hostname match */
1649 ok = 0;
1650
1651 cert = X509_STORE_CTX_get_current_cert(ctx);
1652 /* It seems like this might happen if verify peer isn't set */
1653 if (!cert)
1654 return ok;
1655
1656 alt_names = X509_get_ext_d2i(cert, NID_subject_alt_name, NULL, NULL);
1657 if (alt_names) {
1658 for (i = 0; !ok && i < sk_GENERAL_NAME_num(alt_names); i++) {
1659 GENERAL_NAME *name = sk_GENERAL_NAME_value(alt_names, i);
1660 if (name->type == GEN_DNS) {
Emeric Bruna33410c2013-09-17 15:47:48 +02001661#if OPENSSL_VERSION_NUMBER < 0x00907000L
1662 if (ASN1_STRING_to_UTF8((unsigned char **)&str, name->d.ia5) >= 0) {
1663#else
Evan Broderbe554312013-06-27 00:05:25 -07001664 if (ASN1_STRING_to_UTF8((unsigned char **)&str, name->d.dNSName) >= 0) {
Emeric Bruna33410c2013-09-17 15:47:48 +02001665#endif
Evan Broderbe554312013-06-27 00:05:25 -07001666 ok = ssl_sock_srv_hostcheck(str, servername);
1667 OPENSSL_free(str);
1668 }
1669 }
1670 }
Emeric Brun4ad50a42013-09-17 15:19:54 +02001671 sk_GENERAL_NAME_pop_free(alt_names, GENERAL_NAME_free);
Evan Broderbe554312013-06-27 00:05:25 -07001672 }
1673
1674 cert_subject = X509_get_subject_name(cert);
1675 i = -1;
1676 while (!ok && (i = X509_NAME_get_index_by_NID(cert_subject, NID_commonName, i)) != -1) {
1677 X509_NAME_ENTRY *entry = X509_NAME_get_entry(cert_subject, i);
1678 if (ASN1_STRING_to_UTF8((unsigned char **)&str, entry->value) >= 0) {
1679 ok = ssl_sock_srv_hostcheck(str, servername);
1680 OPENSSL_free(str);
1681 }
1682 }
1683
1684 return ok;
1685}
1686
Emeric Brun94324a42012-10-11 14:00:19 +02001687/* prepare ssl context from servers options. Returns an error count */
1688int ssl_sock_prepare_srv_ctx(struct server *srv, struct proxy *curproxy)
1689{
1690 int cfgerr = 0;
Remi Gacogneaf5c3da2014-05-19 10:29:58 +02001691 long options =
Emeric Brun94324a42012-10-11 14:00:19 +02001692 SSL_OP_ALL | /* all known workarounds for bugs */
1693 SSL_OP_NO_SSLv2 |
1694 SSL_OP_NO_COMPRESSION;
Remi Gacogneaf5c3da2014-05-19 10:29:58 +02001695 long mode =
Emeric Brun94324a42012-10-11 14:00:19 +02001696 SSL_MODE_ENABLE_PARTIAL_WRITE |
1697 SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER |
1698 SSL_MODE_RELEASE_BUFFERS;
Emeric Brun850efd52014-01-29 12:24:34 +01001699 int verify = SSL_VERIFY_NONE;
Emeric Brun94324a42012-10-11 14:00:19 +02001700
Thierry Fournier383085f2013-01-24 14:15:43 +01001701 /* Make sure openssl opens /dev/urandom before the chroot */
1702 if (!ssl_initialize_random()) {
1703 Alert("OpenSSL random data generator initialization failed.\n");
1704 cfgerr++;
1705 }
1706
Emeric Brun94324a42012-10-11 14:00:19 +02001707 /* Initiate SSL context for current server */
1708 srv->ssl_ctx.reused_sess = NULL;
1709 if (srv->use_ssl)
1710 srv->xprt = &ssl_sock;
1711 if (srv->check.use_ssl)
Cyril Bonté1f96a872014-11-15 22:41:27 +01001712 srv->check.xprt = &ssl_sock;
Emeric Brun94324a42012-10-11 14:00:19 +02001713
1714 srv->ssl_ctx.ctx = SSL_CTX_new(SSLv23_client_method());
1715 if (!srv->ssl_ctx.ctx) {
1716 Alert("config : %s '%s', server '%s': unable to allocate ssl context.\n",
1717 proxy_type_str(curproxy), curproxy->id,
1718 srv->id);
1719 cfgerr++;
1720 return cfgerr;
1721 }
Emeric Bruna7aa3092012-10-26 12:58:00 +02001722 if (srv->ssl_ctx.client_crt) {
1723 if (SSL_CTX_use_PrivateKey_file(srv->ssl_ctx.ctx, srv->ssl_ctx.client_crt, SSL_FILETYPE_PEM) <= 0) {
1724 Alert("config : %s '%s', server '%s': unable to load SSL private key from PEM file '%s'.\n",
1725 proxy_type_str(curproxy), curproxy->id,
1726 srv->id, srv->ssl_ctx.client_crt);
1727 cfgerr++;
1728 }
1729 else if (SSL_CTX_use_certificate_chain_file(srv->ssl_ctx.ctx, srv->ssl_ctx.client_crt) <= 0) {
1730 Alert("config : %s '%s', server '%s': unable to load ssl certificate from PEM file '%s'.\n",
1731 proxy_type_str(curproxy), curproxy->id,
1732 srv->id, srv->ssl_ctx.client_crt);
1733 cfgerr++;
1734 }
1735 else if (SSL_CTX_check_private_key(srv->ssl_ctx.ctx) <= 0) {
1736 Alert("config : %s '%s', server '%s': inconsistencies between private key and certificate loaded from PEM file '%s'.\n",
1737 proxy_type_str(curproxy), curproxy->id,
1738 srv->id, srv->ssl_ctx.client_crt);
1739 cfgerr++;
1740 }
1741 }
Emeric Brun94324a42012-10-11 14:00:19 +02001742
1743 if (srv->ssl_ctx.options & SRV_SSL_O_NO_SSLV3)
1744 options |= SSL_OP_NO_SSLv3;
1745 if (srv->ssl_ctx.options & SRV_SSL_O_NO_TLSV10)
1746 options |= SSL_OP_NO_TLSv1;
1747 if (srv->ssl_ctx.options & SRV_SSL_O_NO_TLSV11)
1748 options |= SSL_OP_NO_TLSv1_1;
1749 if (srv->ssl_ctx.options & SRV_SSL_O_NO_TLSV12)
1750 options |= SSL_OP_NO_TLSv1_2;
Emeric Brunf9c5c472012-10-11 15:28:34 +02001751 if (srv->ssl_ctx.options & SRV_SSL_O_NO_TLS_TICKETS)
1752 options |= SSL_OP_NO_TICKET;
Emeric Brun94324a42012-10-11 14:00:19 +02001753 if (srv->ssl_ctx.options & SRV_SSL_O_USE_SSLV3)
1754 SSL_CTX_set_ssl_version(srv->ssl_ctx.ctx, SSLv3_client_method());
1755 if (srv->ssl_ctx.options & SRV_SSL_O_USE_TLSV10)
1756 SSL_CTX_set_ssl_version(srv->ssl_ctx.ctx, TLSv1_client_method());
1757#if SSL_OP_NO_TLSv1_1
1758 if (srv->ssl_ctx.options & SRV_SSL_O_USE_TLSV11)
1759 SSL_CTX_set_ssl_version(srv->ssl_ctx.ctx, TLSv1_1_client_method());
1760#endif
1761#if SSL_OP_NO_TLSv1_2
1762 if (srv->ssl_ctx.options & SRV_SSL_O_USE_TLSV12)
1763 SSL_CTX_set_ssl_version(srv->ssl_ctx.ctx, TLSv1_2_client_method());
1764#endif
1765
1766 SSL_CTX_set_options(srv->ssl_ctx.ctx, options);
1767 SSL_CTX_set_mode(srv->ssl_ctx.ctx, mode);
Emeric Brun850efd52014-01-29 12:24:34 +01001768
1769 if (global.ssl_server_verify == SSL_SERVER_VERIFY_REQUIRED)
1770 verify = SSL_VERIFY_PEER;
1771
1772 switch (srv->ssl_ctx.verify) {
1773 case SSL_SOCK_VERIFY_NONE:
1774 verify = SSL_VERIFY_NONE;
1775 break;
1776 case SSL_SOCK_VERIFY_REQUIRED:
1777 verify = SSL_VERIFY_PEER;
1778 break;
1779 }
Evan Broderbe554312013-06-27 00:05:25 -07001780 SSL_CTX_set_verify(srv->ssl_ctx.ctx,
Emeric Brun850efd52014-01-29 12:24:34 +01001781 verify,
Evan Broderbe554312013-06-27 00:05:25 -07001782 srv->ssl_ctx.verify_host ? ssl_sock_srv_verifycbk : NULL);
Emeric Brun850efd52014-01-29 12:24:34 +01001783 if (verify & SSL_VERIFY_PEER) {
Emeric Brunef42d922012-10-11 16:11:36 +02001784 if (srv->ssl_ctx.ca_file) {
1785 /* load CAfile to verify */
1786 if (!SSL_CTX_load_verify_locations(srv->ssl_ctx.ctx, srv->ssl_ctx.ca_file, NULL)) {
Willy Tarreau07ba08b2014-02-16 19:22:08 +01001787 Alert("Proxy '%s', server '%s' [%s:%d] unable to load CA file '%s'.\n",
Emeric Brunef42d922012-10-11 16:11:36 +02001788 curproxy->id, srv->id,
1789 srv->conf.file, srv->conf.line, srv->ssl_ctx.ca_file);
1790 cfgerr++;
1791 }
1792 }
Emeric Brun850efd52014-01-29 12:24:34 +01001793 else {
1794 if (global.ssl_server_verify == SSL_SERVER_VERIFY_REQUIRED)
Willy Tarreau07ba08b2014-02-16 19:22:08 +01001795 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 +01001796 curproxy->id, srv->id,
1797 srv->conf.file, srv->conf.line);
1798 else
Willy Tarreau07ba08b2014-02-16 19:22:08 +01001799 Alert("Proxy '%s', server '%s' [%s:%d] verify is enabled but no CA file specified.\n",
Emeric Brun850efd52014-01-29 12:24:34 +01001800 curproxy->id, srv->id,
1801 srv->conf.file, srv->conf.line);
1802 cfgerr++;
1803 }
Emeric Brunef42d922012-10-11 16:11:36 +02001804#ifdef X509_V_FLAG_CRL_CHECK
1805 if (srv->ssl_ctx.crl_file) {
1806 X509_STORE *store = SSL_CTX_get_cert_store(srv->ssl_ctx.ctx);
1807
1808 if (!store || !X509_STORE_load_locations(store, srv->ssl_ctx.crl_file, NULL)) {
Willy Tarreau07ba08b2014-02-16 19:22:08 +01001809 Alert("Proxy '%s', server '%s' [%s:%d] unable to configure CRL file '%s'.\n",
Emeric Brunef42d922012-10-11 16:11:36 +02001810 curproxy->id, srv->id,
1811 srv->conf.file, srv->conf.line, srv->ssl_ctx.crl_file);
1812 cfgerr++;
1813 }
1814 else {
1815 X509_STORE_set_flags(store, X509_V_FLAG_CRL_CHECK|X509_V_FLAG_CRL_CHECK_ALL);
1816 }
1817 }
1818#endif
1819 }
1820
Emeric Brun4f65bff2012-11-16 15:11:00 +01001821 if (global.tune.ssllifetime)
1822 SSL_CTX_set_timeout(srv->ssl_ctx.ctx, global.tune.ssllifetime);
1823
Emeric Brun94324a42012-10-11 14:00:19 +02001824 SSL_CTX_set_session_cache_mode(srv->ssl_ctx.ctx, SSL_SESS_CACHE_OFF);
1825 if (srv->ssl_ctx.ciphers &&
1826 !SSL_CTX_set_cipher_list(srv->ssl_ctx.ctx, srv->ssl_ctx.ciphers)) {
1827 Alert("Proxy '%s', server '%s' [%s:%d] : unable to set SSL cipher list to '%s'.\n",
1828 curproxy->id, srv->id,
1829 srv->conf.file, srv->conf.line, srv->ssl_ctx.ciphers);
1830 cfgerr++;
1831 }
1832
1833 return cfgerr;
1834}
1835
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001836/* Walks down the two trees in bind_conf and prepares all certs. The pointer may
Emeric Brunfc0421f2012-09-07 17:30:07 +02001837 * be NULL, in which case nothing is done. Returns the number of errors
1838 * encountered.
1839 */
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001840int ssl_sock_prepare_all_ctx(struct bind_conf *bind_conf, struct proxy *px)
Emeric Brunfc0421f2012-09-07 17:30:07 +02001841{
1842 struct ebmb_node *node;
1843 struct sni_ctx *sni;
1844 int err = 0;
1845
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001846 if (!bind_conf || !bind_conf->is_ssl)
Emeric Brunfc0421f2012-09-07 17:30:07 +02001847 return 0;
1848
Emeric Brun8068b032014-10-30 19:25:24 +01001849 if (bind_conf->default_ctx)
1850 err += ssl_sock_prepare_ctx(bind_conf, bind_conf->default_ctx, px);
1851
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001852 node = ebmb_first(&bind_conf->sni_ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001853 while (node) {
1854 sni = ebmb_entry(node, struct sni_ctx, name);
Emeric Brun8068b032014-10-30 19:25:24 +01001855 if (!sni->order && sni->ctx != bind_conf->default_ctx)
1856 /* only initialize the CTX on its first occurrence and
1857 if it is not the default_ctx */
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001858 err += ssl_sock_prepare_ctx(bind_conf, sni->ctx, px);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001859 node = ebmb_next(node);
1860 }
1861
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001862 node = ebmb_first(&bind_conf->sni_w_ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001863 while (node) {
1864 sni = ebmb_entry(node, struct sni_ctx, name);
Emeric Brun8068b032014-10-30 19:25:24 +01001865 if (!sni->order && sni->ctx != bind_conf->default_ctx)
1866 /* only initialize the CTX on its first occurrence and
1867 if it is not the default_ctx */
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001868 err += ssl_sock_prepare_ctx(bind_conf, sni->ctx, px);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001869 node = ebmb_next(node);
1870 }
1871 return err;
1872}
1873
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001874/* Walks down the two trees in bind_conf and frees all the certs. The pointer may
Emeric Brunfc0421f2012-09-07 17:30:07 +02001875 * be NULL, in which case nothing is done. The default_ctx is nullified too.
1876 */
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001877void ssl_sock_free_all_ctx(struct bind_conf *bind_conf)
Emeric Brunfc0421f2012-09-07 17:30:07 +02001878{
1879 struct ebmb_node *node, *back;
1880 struct sni_ctx *sni;
1881
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001882 if (!bind_conf || !bind_conf->is_ssl)
Emeric Brunfc0421f2012-09-07 17:30:07 +02001883 return;
1884
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001885 node = ebmb_first(&bind_conf->sni_ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001886 while (node) {
1887 sni = ebmb_entry(node, struct sni_ctx, name);
1888 back = ebmb_next(node);
1889 ebmb_delete(node);
1890 if (!sni->order) /* only free the CTX on its first occurrence */
1891 SSL_CTX_free(sni->ctx);
1892 free(sni);
1893 node = back;
1894 }
1895
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001896 node = ebmb_first(&bind_conf->sni_w_ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001897 while (node) {
1898 sni = ebmb_entry(node, struct sni_ctx, name);
1899 back = ebmb_next(node);
1900 ebmb_delete(node);
1901 if (!sni->order) /* only free the CTX on its first occurrence */
1902 SSL_CTX_free(sni->ctx);
1903 free(sni);
1904 node = back;
1905 }
1906
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001907 bind_conf->default_ctx = NULL;
Emeric Brune1f38db2012-09-03 20:36:47 +02001908}
1909
Emeric Brun46591952012-05-18 15:47:34 +02001910/*
1911 * This function is called if SSL * context is not yet allocated. The function
1912 * is designed to be called before any other data-layer operation and sets the
1913 * handshake flag on the connection. It is safe to call it multiple times.
1914 * It returns 0 on success and -1 in error case.
1915 */
1916static int ssl_sock_init(struct connection *conn)
1917{
1918 /* already initialized */
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02001919 if (conn->xprt_ctx)
Emeric Brun46591952012-05-18 15:47:34 +02001920 return 0;
1921
Willy Tarreau3c728722014-01-23 13:50:42 +01001922 if (!conn_ctrl_ready(conn))
Willy Tarreauf79c8172013-10-21 16:30:56 +02001923 return 0;
1924
Willy Tarreau20879a02012-12-03 16:32:10 +01001925 if (global.maxsslconn && sslconns >= global.maxsslconn) {
1926 conn->err_code = CO_ER_SSL_TOO_MANY;
Willy Tarreau403edff2012-09-06 11:58:37 +02001927 return -1;
Willy Tarreau20879a02012-12-03 16:32:10 +01001928 }
Willy Tarreau403edff2012-09-06 11:58:37 +02001929
Emeric Brun46591952012-05-18 15:47:34 +02001930 /* If it is in client mode initiate SSL session
1931 in connect state otherwise accept state */
Willy Tarreau3fdb3662012-11-12 00:42:33 +01001932 if (objt_server(conn->target)) {
Willy Tarreau9bcc01a2014-11-13 13:48:58 +01001933 int may_retry = 1;
1934
1935 retry_connect:
Emeric Brun46591952012-05-18 15:47:34 +02001936 /* Alloc a new SSL session ctx */
Willy Tarreau3fdb3662012-11-12 00:42:33 +01001937 conn->xprt_ctx = SSL_new(objt_server(conn->target)->ssl_ctx.ctx);
Willy Tarreau20879a02012-12-03 16:32:10 +01001938 if (!conn->xprt_ctx) {
Willy Tarreau9bcc01a2014-11-13 13:48:58 +01001939 if (may_retry--) {
1940 pool_gc2();
1941 goto retry_connect;
1942 }
Willy Tarreau20879a02012-12-03 16:32:10 +01001943 conn->err_code = CO_ER_SSL_NO_MEM;
Emeric Brun46591952012-05-18 15:47:34 +02001944 return -1;
Willy Tarreau20879a02012-12-03 16:32:10 +01001945 }
Emeric Brun46591952012-05-18 15:47:34 +02001946
Emeric Brun46591952012-05-18 15:47:34 +02001947 /* set fd on SSL session context */
Emeric Brun90951492014-11-12 17:35:37 +01001948 if (!SSL_set_fd(conn->xprt_ctx, conn->t.sock.fd)) {
1949 SSL_free(conn->xprt_ctx);
1950 conn->xprt_ctx = NULL;
Willy Tarreau9bcc01a2014-11-13 13:48:58 +01001951 if (may_retry--) {
1952 pool_gc2();
1953 goto retry_connect;
1954 }
Emeric Brun90951492014-11-12 17:35:37 +01001955 conn->err_code = CO_ER_SSL_NO_MEM;
1956 return -1;
1957 }
Emeric Brun46591952012-05-18 15:47:34 +02001958
Evan Broderbe554312013-06-27 00:05:25 -07001959 /* set connection pointer */
Emeric Brun90951492014-11-12 17:35:37 +01001960 if (!SSL_set_app_data(conn->xprt_ctx, conn)) {
1961 SSL_free(conn->xprt_ctx);
1962 conn->xprt_ctx = NULL;
Willy Tarreau9bcc01a2014-11-13 13:48:58 +01001963 if (may_retry--) {
1964 pool_gc2();
1965 goto retry_connect;
1966 }
Emeric Brun90951492014-11-12 17:35:37 +01001967 conn->err_code = CO_ER_SSL_NO_MEM;
1968 return -1;
1969 }
1970
1971 SSL_set_connect_state(conn->xprt_ctx);
1972 if (objt_server(conn->target)->ssl_ctx.reused_sess) {
1973 if(!SSL_set_session(conn->xprt_ctx, objt_server(conn->target)->ssl_ctx.reused_sess)) {
1974 SSL_SESSION_free(objt_server(conn->target)->ssl_ctx.reused_sess);
1975 objt_server(conn->target)->ssl_ctx.reused_sess = NULL;
1976 }
1977 }
Evan Broderbe554312013-06-27 00:05:25 -07001978
Emeric Brun46591952012-05-18 15:47:34 +02001979 /* leave init state and start handshake */
Willy Tarreau05737472012-09-04 08:03:39 +02001980 conn->flags |= CO_FL_SSL_WAIT_HS | CO_FL_WAIT_L6_CONN;
Willy Tarreau403edff2012-09-06 11:58:37 +02001981
1982 sslconns++;
Willy Tarreau71b734c2014-01-28 15:19:44 +01001983 totalsslconns++;
Emeric Brun46591952012-05-18 15:47:34 +02001984 return 0;
1985 }
Willy Tarreau3fdb3662012-11-12 00:42:33 +01001986 else if (objt_listener(conn->target)) {
Willy Tarreau9bcc01a2014-11-13 13:48:58 +01001987 int may_retry = 1;
1988
1989 retry_accept:
Emeric Brun46591952012-05-18 15:47:34 +02001990 /* Alloc a new SSL session ctx */
Willy Tarreau3fdb3662012-11-12 00:42:33 +01001991 conn->xprt_ctx = SSL_new(objt_listener(conn->target)->bind_conf->default_ctx);
Willy Tarreau20879a02012-12-03 16:32:10 +01001992 if (!conn->xprt_ctx) {
Willy Tarreau9bcc01a2014-11-13 13:48:58 +01001993 if (may_retry--) {
1994 pool_gc2();
1995 goto retry_accept;
1996 }
Willy Tarreau20879a02012-12-03 16:32:10 +01001997 conn->err_code = CO_ER_SSL_NO_MEM;
Emeric Brun46591952012-05-18 15:47:34 +02001998 return -1;
Willy Tarreau20879a02012-12-03 16:32:10 +01001999 }
Emeric Brun46591952012-05-18 15:47:34 +02002000
Emeric Brun46591952012-05-18 15:47:34 +02002001 /* set fd on SSL session context */
Emeric Brun90951492014-11-12 17:35:37 +01002002 if (!SSL_set_fd(conn->xprt_ctx, conn->t.sock.fd)) {
2003 SSL_free(conn->xprt_ctx);
2004 conn->xprt_ctx = NULL;
Willy Tarreau9bcc01a2014-11-13 13:48:58 +01002005 if (may_retry--) {
2006 pool_gc2();
2007 goto retry_accept;
2008 }
Emeric Brun90951492014-11-12 17:35:37 +01002009 conn->err_code = CO_ER_SSL_NO_MEM;
2010 return -1;
2011 }
Emeric Brun46591952012-05-18 15:47:34 +02002012
Emeric Brune1f38db2012-09-03 20:36:47 +02002013 /* set connection pointer */
Emeric Brun90951492014-11-12 17:35:37 +01002014 if (!SSL_set_app_data(conn->xprt_ctx, conn)) {
2015 SSL_free(conn->xprt_ctx);
2016 conn->xprt_ctx = NULL;
Willy Tarreau9bcc01a2014-11-13 13:48:58 +01002017 if (may_retry--) {
2018 pool_gc2();
2019 goto retry_accept;
2020 }
Emeric Brun90951492014-11-12 17:35:37 +01002021 conn->err_code = CO_ER_SSL_NO_MEM;
2022 return -1;
2023 }
2024
2025 SSL_set_accept_state(conn->xprt_ctx);
Emeric Brune1f38db2012-09-03 20:36:47 +02002026
Emeric Brun46591952012-05-18 15:47:34 +02002027 /* leave init state and start handshake */
Willy Tarreau05737472012-09-04 08:03:39 +02002028 conn->flags |= CO_FL_SSL_WAIT_HS | CO_FL_WAIT_L6_CONN;
Willy Tarreau403edff2012-09-06 11:58:37 +02002029
2030 sslconns++;
Willy Tarreau71b734c2014-01-28 15:19:44 +01002031 totalsslconns++;
Emeric Brun46591952012-05-18 15:47:34 +02002032 return 0;
2033 }
2034 /* don't know how to handle such a target */
Willy Tarreau20879a02012-12-03 16:32:10 +01002035 conn->err_code = CO_ER_SSL_NO_TARGET;
Emeric Brun46591952012-05-18 15:47:34 +02002036 return -1;
2037}
2038
2039
2040/* This is the callback which is used when an SSL handshake is pending. It
2041 * updates the FD status if it wants some polling before being called again.
2042 * It returns 0 if it fails in a fatal way or needs to poll to go further,
2043 * otherwise it returns non-zero and removes itself from the connection's
2044 * flags (the bit is provided in <flag> by the caller).
2045 */
2046int ssl_sock_handshake(struct connection *conn, unsigned int flag)
2047{
2048 int ret;
2049
Willy Tarreau3c728722014-01-23 13:50:42 +01002050 if (!conn_ctrl_ready(conn))
Willy Tarreauf79c8172013-10-21 16:30:56 +02002051 return 0;
2052
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02002053 if (!conn->xprt_ctx)
Emeric Brun46591952012-05-18 15:47:34 +02002054 goto out_error;
2055
Emeric Brun674b7432012-11-08 19:21:55 +01002056 /* If we use SSL_do_handshake to process a reneg initiated by
2057 * the remote peer, it sometimes returns SSL_ERROR_SSL.
2058 * Usually SSL_write and SSL_read are used and process implicitly
2059 * the reneg handshake.
2060 * Here we use SSL_peek as a workaround for reneg.
2061 */
2062 if ((conn->flags & CO_FL_CONNECTED) && SSL_renegotiate_pending(conn->xprt_ctx)) {
2063 char c;
2064
2065 ret = SSL_peek(conn->xprt_ctx, &c, 1);
2066 if (ret <= 0) {
2067 /* handshake may have not been completed, let's find why */
2068 ret = SSL_get_error(conn->xprt_ctx, ret);
2069 if (ret == SSL_ERROR_WANT_WRITE) {
2070 /* SSL handshake needs to write, L4 connection may not be ready */
2071 __conn_sock_stop_recv(conn);
Willy Tarreaue1f50c42014-01-22 20:02:06 +01002072 __conn_sock_want_send(conn);
2073 fd_cant_send(conn->t.sock.fd);
Emeric Brun674b7432012-11-08 19:21:55 +01002074 return 0;
2075 }
2076 else if (ret == SSL_ERROR_WANT_READ) {
2077 /* handshake may have been completed but we have
2078 * no more data to read.
2079 */
2080 if (!SSL_renegotiate_pending(conn->xprt_ctx)) {
2081 ret = 1;
2082 goto reneg_ok;
2083 }
2084 /* SSL handshake needs to read, L4 connection is ready */
2085 if (conn->flags & CO_FL_WAIT_L4_CONN)
2086 conn->flags &= ~CO_FL_WAIT_L4_CONN;
2087 __conn_sock_stop_send(conn);
Willy Tarreaue1f50c42014-01-22 20:02:06 +01002088 __conn_sock_want_recv(conn);
2089 fd_cant_recv(conn->t.sock.fd);
Emeric Brun674b7432012-11-08 19:21:55 +01002090 return 0;
2091 }
2092 else if (ret == SSL_ERROR_SYSCALL) {
2093 /* if errno is null, then connection was successfully established */
2094 if (!errno && conn->flags & CO_FL_WAIT_L4_CONN)
2095 conn->flags &= ~CO_FL_WAIT_L4_CONN;
Willy Tarreau20879a02012-12-03 16:32:10 +01002096 if (!conn->err_code) {
Emeric Brun29f037d2014-04-25 19:05:36 +02002097 if (!((SSL *)conn->xprt_ctx)->packet_length) {
2098 if (!errno) {
2099 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
2100 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
2101 else
2102 conn->err_code = CO_ER_SSL_EMPTY;
2103 }
2104 else {
2105 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
2106 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
2107 else
2108 conn->err_code = CO_ER_SSL_ABORT;
2109 }
2110 }
2111 else {
2112 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
2113 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
Willy Tarreau20879a02012-12-03 16:32:10 +01002114 else
Emeric Brun29f037d2014-04-25 19:05:36 +02002115 conn->err_code = CO_ER_SSL_HANDSHAKE;
2116 }
Willy Tarreau20879a02012-12-03 16:32:10 +01002117 }
Emeric Brun674b7432012-11-08 19:21:55 +01002118 goto out_error;
2119 }
2120 else {
2121 /* Fail on all other handshake errors */
2122 /* Note: OpenSSL may leave unread bytes in the socket's
2123 * buffer, causing an RST to be emitted upon close() on
2124 * TCP sockets. We first try to drain possibly pending
2125 * data to avoid this as much as possible.
2126 */
Willy Tarreau46be2e52014-01-20 12:10:52 +01002127 conn_drain(conn);
Willy Tarreau20879a02012-12-03 16:32:10 +01002128 if (!conn->err_code)
Willy Tarreauf51c6982014-04-25 20:02:39 +02002129 conn->err_code = (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT) ?
2130 CO_ER_SSL_KILLED_HB : CO_ER_SSL_HANDSHAKE;
Emeric Brun674b7432012-11-08 19:21:55 +01002131 goto out_error;
2132 }
2133 }
2134 /* read some data: consider handshake completed */
2135 goto reneg_ok;
2136 }
2137
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02002138 ret = SSL_do_handshake(conn->xprt_ctx);
Emeric Brun46591952012-05-18 15:47:34 +02002139 if (ret != 1) {
2140 /* handshake did not complete, let's find why */
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02002141 ret = SSL_get_error(conn->xprt_ctx, ret);
Emeric Brun46591952012-05-18 15:47:34 +02002142
2143 if (ret == SSL_ERROR_WANT_WRITE) {
2144 /* SSL handshake needs to write, L4 connection may not be ready */
2145 __conn_sock_stop_recv(conn);
Willy Tarreaue1f50c42014-01-22 20:02:06 +01002146 __conn_sock_want_send(conn);
2147 fd_cant_send(conn->t.sock.fd);
Emeric Brun46591952012-05-18 15:47:34 +02002148 return 0;
2149 }
2150 else if (ret == SSL_ERROR_WANT_READ) {
2151 /* SSL handshake needs to read, L4 connection is ready */
2152 if (conn->flags & CO_FL_WAIT_L4_CONN)
2153 conn->flags &= ~CO_FL_WAIT_L4_CONN;
2154 __conn_sock_stop_send(conn);
Willy Tarreaue1f50c42014-01-22 20:02:06 +01002155 __conn_sock_want_recv(conn);
2156 fd_cant_recv(conn->t.sock.fd);
Emeric Brun46591952012-05-18 15:47:34 +02002157 return 0;
2158 }
Willy Tarreau89230192012-09-28 20:22:13 +02002159 else if (ret == SSL_ERROR_SYSCALL) {
2160 /* if errno is null, then connection was successfully established */
2161 if (!errno && conn->flags & CO_FL_WAIT_L4_CONN)
2162 conn->flags &= ~CO_FL_WAIT_L4_CONN;
Willy Tarreau20879a02012-12-03 16:32:10 +01002163
Emeric Brun29f037d2014-04-25 19:05:36 +02002164 if (!((SSL *)conn->xprt_ctx)->packet_length) {
2165 if (!errno) {
2166 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
2167 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
2168 else
2169 conn->err_code = CO_ER_SSL_EMPTY;
2170 }
2171 else {
2172 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
2173 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
2174 else
2175 conn->err_code = CO_ER_SSL_ABORT;
2176 }
2177 }
2178 else {
2179 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
2180 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
Willy Tarreau20879a02012-12-03 16:32:10 +01002181 else
Emeric Brun29f037d2014-04-25 19:05:36 +02002182 conn->err_code = CO_ER_SSL_HANDSHAKE;
2183 }
Willy Tarreau89230192012-09-28 20:22:13 +02002184 goto out_error;
2185 }
Emeric Brun46591952012-05-18 15:47:34 +02002186 else {
2187 /* Fail on all other handshake errors */
Willy Tarreau566dc552012-10-19 20:52:18 +02002188 /* Note: OpenSSL may leave unread bytes in the socket's
2189 * buffer, causing an RST to be emitted upon close() on
2190 * TCP sockets. We first try to drain possibly pending
2191 * data to avoid this as much as possible.
2192 */
Willy Tarreau46be2e52014-01-20 12:10:52 +01002193 conn_drain(conn);
Willy Tarreau20879a02012-12-03 16:32:10 +01002194 if (!conn->err_code)
Willy Tarreauf51c6982014-04-25 20:02:39 +02002195 conn->err_code = (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT) ?
2196 CO_ER_SSL_KILLED_HB : CO_ER_SSL_HANDSHAKE;
Emeric Brun46591952012-05-18 15:47:34 +02002197 goto out_error;
2198 }
2199 }
2200
Emeric Brun674b7432012-11-08 19:21:55 +01002201reneg_ok:
2202
Emeric Brun46591952012-05-18 15:47:34 +02002203 /* Handshake succeeded */
Willy Tarreau0c9c2722014-05-28 12:28:58 +02002204 if (!SSL_session_reused(conn->xprt_ctx)) {
2205 if (objt_server(conn->target)) {
2206 update_freq_ctr(&global.ssl_be_keys_per_sec, 1);
2207 if (global.ssl_be_keys_per_sec.curr_ctr > global.ssl_be_keys_max)
2208 global.ssl_be_keys_max = global.ssl_be_keys_per_sec.curr_ctr;
2209
Emeric Brun46591952012-05-18 15:47:34 +02002210 /* check if session was reused, if not store current session on server for reuse */
Willy Tarreau3fdb3662012-11-12 00:42:33 +01002211 if (objt_server(conn->target)->ssl_ctx.reused_sess)
2212 SSL_SESSION_free(objt_server(conn->target)->ssl_ctx.reused_sess);
Emeric Brun46591952012-05-18 15:47:34 +02002213
Willy Tarreau3fdb3662012-11-12 00:42:33 +01002214 objt_server(conn->target)->ssl_ctx.reused_sess = SSL_get1_session(conn->xprt_ctx);
Emeric Brun46591952012-05-18 15:47:34 +02002215 }
Willy Tarreau0c9c2722014-05-28 12:28:58 +02002216 else {
2217 update_freq_ctr(&global.ssl_fe_keys_per_sec, 1);
2218 if (global.ssl_fe_keys_per_sec.curr_ctr > global.ssl_fe_keys_max)
2219 global.ssl_fe_keys_max = global.ssl_fe_keys_per_sec.curr_ctr;
2220 }
Emeric Brun46591952012-05-18 15:47:34 +02002221 }
2222
2223 /* The connection is now established at both layers, it's time to leave */
2224 conn->flags &= ~(flag | CO_FL_WAIT_L4_CONN | CO_FL_WAIT_L6_CONN);
2225 return 1;
2226
2227 out_error:
Emeric Brun644cde02012-12-14 11:21:13 +01002228 /* Clear openssl global errors stack */
2229 ERR_clear_error();
2230
Emeric Brun9fa89732012-10-04 17:09:56 +02002231 /* free resumed session if exists */
Willy Tarreau3fdb3662012-11-12 00:42:33 +01002232 if (objt_server(conn->target) && objt_server(conn->target)->ssl_ctx.reused_sess) {
2233 SSL_SESSION_free(objt_server(conn->target)->ssl_ctx.reused_sess);
2234 objt_server(conn->target)->ssl_ctx.reused_sess = NULL;
Emeric Brun9fa89732012-10-04 17:09:56 +02002235 }
2236
Emeric Brun46591952012-05-18 15:47:34 +02002237 /* Fail on all other handshake errors */
2238 conn->flags |= CO_FL_ERROR;
Willy Tarreau20879a02012-12-03 16:32:10 +01002239 if (!conn->err_code)
2240 conn->err_code = CO_ER_SSL_HANDSHAKE;
Emeric Brun46591952012-05-18 15:47:34 +02002241 return 0;
2242}
2243
2244/* Receive up to <count> bytes from connection <conn>'s socket and store them
Willy Tarreauabf08d92014-01-14 11:31:27 +01002245 * into buffer <buf>. Only one call to recv() is performed, unless the
Emeric Brun46591952012-05-18 15:47:34 +02002246 * buffer wraps, in which case a second call may be performed. The connection's
2247 * flags are updated with whatever special event is detected (error, read0,
2248 * empty). The caller is responsible for taking care of those events and
2249 * avoiding the call if inappropriate. The function does not call the
2250 * connection's polling update function, so the caller is responsible for this.
2251 */
2252static int ssl_sock_to_buf(struct connection *conn, struct buffer *buf, int count)
2253{
2254 int ret, done = 0;
Willy Tarreauabf08d92014-01-14 11:31:27 +01002255 int try;
Emeric Brun46591952012-05-18 15:47:34 +02002256
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02002257 if (!conn->xprt_ctx)
Emeric Brun46591952012-05-18 15:47:34 +02002258 goto out_error;
2259
2260 if (conn->flags & CO_FL_HANDSHAKE)
2261 /* a handshake was requested */
2262 return 0;
2263
Willy Tarreauabf08d92014-01-14 11:31:27 +01002264 /* let's realign the buffer to optimize I/O */
2265 if (buffer_empty(buf))
Emeric Brun46591952012-05-18 15:47:34 +02002266 buf->p = buf->data;
Emeric Brun46591952012-05-18 15:47:34 +02002267
2268 /* read the largest possible block. For this, we perform only one call
2269 * to recv() unless the buffer wraps and we exactly fill the first hunk,
2270 * in which case we accept to do it once again. A new attempt is made on
2271 * EINTR too.
2272 */
Willy Tarreau00b0fb92014-01-17 11:09:40 +01002273 while (count > 0) {
Willy Tarreauabf08d92014-01-14 11:31:27 +01002274 /* first check if we have some room after p+i */
2275 try = buf->data + buf->size - (buf->p + buf->i);
2276 /* otherwise continue between data and p-o */
2277 if (try <= 0) {
2278 try = buf->p - (buf->data + buf->o);
2279 if (try <= 0)
2280 break;
2281 }
2282 if (try > count)
2283 try = count;
2284
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02002285 ret = SSL_read(conn->xprt_ctx, bi_end(buf), try);
Emeric Brune1f38db2012-09-03 20:36:47 +02002286 if (conn->flags & CO_FL_ERROR) {
2287 /* CO_FL_ERROR may be set by ssl_sock_infocbk */
Emeric Brun644cde02012-12-14 11:21:13 +01002288 goto out_error;
Emeric Brune1f38db2012-09-03 20:36:47 +02002289 }
Emeric Brun46591952012-05-18 15:47:34 +02002290 if (ret > 0) {
2291 buf->i += ret;
2292 done += ret;
2293 if (ret < try)
2294 break;
2295 count -= ret;
Emeric Brun46591952012-05-18 15:47:34 +02002296 }
2297 else if (ret == 0) {
Emeric Brun644cde02012-12-14 11:21:13 +01002298 ret = SSL_get_error(conn->xprt_ctx, ret);
2299 if (ret != SSL_ERROR_ZERO_RETURN) {
Emeric Brun1c646862012-12-14 12:33:41 +01002300 /* error on protocol or underlying transport */
2301 if ((ret != SSL_ERROR_SYSCALL)
2302 || (errno && (errno != EAGAIN)))
2303 conn->flags |= CO_FL_ERROR;
2304
Emeric Brun644cde02012-12-14 11:21:13 +01002305 /* Clear openssl global errors stack */
2306 ERR_clear_error();
2307 }
Emeric Brun46591952012-05-18 15:47:34 +02002308 goto read0;
2309 }
2310 else {
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02002311 ret = SSL_get_error(conn->xprt_ctx, ret);
Emeric Brun46591952012-05-18 15:47:34 +02002312 if (ret == SSL_ERROR_WANT_WRITE) {
Emeric Brun8af8dd12012-11-08 17:56:20 +01002313 /* handshake is running, and it needs to enable write */
Emeric Brun46591952012-05-18 15:47:34 +02002314 conn->flags |= CO_FL_SSL_WAIT_HS;
Emeric Brun8af8dd12012-11-08 17:56:20 +01002315 __conn_sock_want_send(conn);
Emeric Brun46591952012-05-18 15:47:34 +02002316 break;
2317 }
2318 else if (ret == SSL_ERROR_WANT_READ) {
Emeric Brun282a76a2012-11-08 18:02:56 +01002319 if (SSL_renegotiate_pending(conn->xprt_ctx)) {
2320 /* handshake is running, and it may need to re-enable read */
2321 conn->flags |= CO_FL_SSL_WAIT_HS;
2322 __conn_sock_want_recv(conn);
2323 break;
2324 }
Emeric Brun46591952012-05-18 15:47:34 +02002325 /* we need to poll for retry a read later */
Willy Tarreaue1f50c42014-01-22 20:02:06 +01002326 fd_cant_recv(conn->t.sock.fd);
Emeric Brun46591952012-05-18 15:47:34 +02002327 break;
2328 }
2329 /* otherwise it's a real error */
2330 goto out_error;
2331 }
2332 }
2333 return done;
2334
2335 read0:
2336 conn_sock_read0(conn);
2337 return done;
2338 out_error:
Emeric Brun644cde02012-12-14 11:21:13 +01002339 /* Clear openssl global errors stack */
2340 ERR_clear_error();
2341
Emeric Brun46591952012-05-18 15:47:34 +02002342 conn->flags |= CO_FL_ERROR;
2343 return done;
2344}
2345
2346
2347/* Send all pending bytes from buffer <buf> to connection <conn>'s socket.
Willy Tarreau1049b1f2014-02-02 01:51:17 +01002348 * <flags> may contain some CO_SFL_* flags to hint the system about other
2349 * pending data for example, but this flag is ignored at the moment.
Emeric Brun46591952012-05-18 15:47:34 +02002350 * Only one call to send() is performed, unless the buffer wraps, in which case
2351 * a second call may be performed. The connection's flags are updated with
2352 * whatever special event is detected (error, empty). The caller is responsible
2353 * for taking care of those events and avoiding the call if inappropriate. The
2354 * function does not call the connection's polling update function, so the caller
2355 * is responsible for this.
2356 */
2357static int ssl_sock_from_buf(struct connection *conn, struct buffer *buf, int flags)
2358{
2359 int ret, try, done;
2360
2361 done = 0;
2362
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02002363 if (!conn->xprt_ctx)
Emeric Brun46591952012-05-18 15:47:34 +02002364 goto out_error;
2365
2366 if (conn->flags & CO_FL_HANDSHAKE)
2367 /* a handshake was requested */
2368 return 0;
2369
2370 /* send the largest possible block. For this we perform only one call
2371 * to send() unless the buffer wraps and we exactly fill the first hunk,
2372 * in which case we accept to do it once again.
2373 */
2374 while (buf->o) {
Kevin Hestercad82342013-05-30 15:12:41 -07002375 try = bo_contig_data(buf);
Willy Tarreaubfd59462013-02-21 07:46:09 +01002376
Willy Tarreau7bed9452014-02-02 02:00:24 +01002377 if (!(flags & CO_SFL_STREAMER) &&
Willy Tarreau518cedd2014-02-17 15:43:01 +01002378 !(conn->xprt_st & SSL_SOCK_SEND_UNLIMITED) &&
2379 global.tune.ssl_max_record && try > global.tune.ssl_max_record) {
Willy Tarreaubfd59462013-02-21 07:46:09 +01002380 try = global.tune.ssl_max_record;
Willy Tarreau518cedd2014-02-17 15:43:01 +01002381 }
2382 else {
2383 /* we need to keep the information about the fact that
2384 * we're not limiting the upcoming send(), because if it
2385 * fails, we'll have to retry with at least as many data.
2386 */
2387 conn->xprt_st |= SSL_SOCK_SEND_UNLIMITED;
2388 }
Willy Tarreaubfd59462013-02-21 07:46:09 +01002389
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02002390 ret = SSL_write(conn->xprt_ctx, bo_ptr(buf), try);
Willy Tarreau518cedd2014-02-17 15:43:01 +01002391
Emeric Brune1f38db2012-09-03 20:36:47 +02002392 if (conn->flags & CO_FL_ERROR) {
2393 /* CO_FL_ERROR may be set by ssl_sock_infocbk */
Emeric Brun644cde02012-12-14 11:21:13 +01002394 goto out_error;
Emeric Brune1f38db2012-09-03 20:36:47 +02002395 }
Emeric Brun46591952012-05-18 15:47:34 +02002396 if (ret > 0) {
Willy Tarreau518cedd2014-02-17 15:43:01 +01002397 conn->xprt_st &= ~SSL_SOCK_SEND_UNLIMITED;
2398
Emeric Brun46591952012-05-18 15:47:34 +02002399 buf->o -= ret;
2400 done += ret;
2401
Willy Tarreau5fb38032012-12-16 19:39:09 +01002402 if (likely(buffer_empty(buf)))
Emeric Brun46591952012-05-18 15:47:34 +02002403 /* optimize data alignment in the buffer */
2404 buf->p = buf->data;
2405
2406 /* if the system buffer is full, don't insist */
2407 if (ret < try)
2408 break;
2409 }
2410 else {
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02002411 ret = SSL_get_error(conn->xprt_ctx, ret);
Emeric Brun46591952012-05-18 15:47:34 +02002412 if (ret == SSL_ERROR_WANT_WRITE) {
Emeric Brun282a76a2012-11-08 18:02:56 +01002413 if (SSL_renegotiate_pending(conn->xprt_ctx)) {
2414 /* handshake is running, and it may need to re-enable write */
2415 conn->flags |= CO_FL_SSL_WAIT_HS;
2416 __conn_sock_want_send(conn);
2417 break;
2418 }
Emeric Brun46591952012-05-18 15:47:34 +02002419 /* we need to poll to retry a write later */
Willy Tarreaue1f50c42014-01-22 20:02:06 +01002420 fd_cant_send(conn->t.sock.fd);
Emeric Brun46591952012-05-18 15:47:34 +02002421 break;
2422 }
2423 else if (ret == SSL_ERROR_WANT_READ) {
Emeric Brun8af8dd12012-11-08 17:56:20 +01002424 /* handshake is running, and it needs to enable read */
Emeric Brun46591952012-05-18 15:47:34 +02002425 conn->flags |= CO_FL_SSL_WAIT_HS;
Emeric Brun8af8dd12012-11-08 17:56:20 +01002426 __conn_sock_want_recv(conn);
Emeric Brun46591952012-05-18 15:47:34 +02002427 break;
2428 }
2429 goto out_error;
2430 }
2431 }
2432 return done;
2433
2434 out_error:
Emeric Brun644cde02012-12-14 11:21:13 +01002435 /* Clear openssl global errors stack */
2436 ERR_clear_error();
2437
Emeric Brun46591952012-05-18 15:47:34 +02002438 conn->flags |= CO_FL_ERROR;
2439 return done;
2440}
2441
Emeric Brun46591952012-05-18 15:47:34 +02002442static void ssl_sock_close(struct connection *conn) {
2443
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02002444 if (conn->xprt_ctx) {
2445 SSL_free(conn->xprt_ctx);
2446 conn->xprt_ctx = NULL;
Willy Tarreau403edff2012-09-06 11:58:37 +02002447 sslconns--;
Emeric Brun46591952012-05-18 15:47:34 +02002448 }
Emeric Brun46591952012-05-18 15:47:34 +02002449}
2450
2451/* This function tries to perform a clean shutdown on an SSL connection, and in
2452 * any case, flags the connection as reusable if no handshake was in progress.
2453 */
2454static void ssl_sock_shutw(struct connection *conn, int clean)
2455{
2456 if (conn->flags & CO_FL_HANDSHAKE)
2457 return;
2458 /* no handshake was in progress, try a clean ssl shutdown */
Emeric Brun644cde02012-12-14 11:21:13 +01002459 if (clean && (SSL_shutdown(conn->xprt_ctx) <= 0)) {
2460 /* Clear openssl global errors stack */
2461 ERR_clear_error();
2462 }
Emeric Brun46591952012-05-18 15:47:34 +02002463
2464 /* force flag on ssl to keep session in cache regardless shutdown result */
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02002465 SSL_set_shutdown(conn->xprt_ctx, SSL_SENT_SHUTDOWN);
Emeric Brun46591952012-05-18 15:47:34 +02002466}
2467
Willy Tarreauffc3fcd2012-10-12 20:17:54 +02002468/* used for logging, may be changed for a sample fetch later */
2469const char *ssl_sock_get_cipher_name(struct connection *conn)
2470{
2471 if (!conn->xprt && !conn->xprt_ctx)
2472 return NULL;
2473 return SSL_get_cipher_name(conn->xprt_ctx);
2474}
2475
2476/* used for logging, may be changed for a sample fetch later */
2477const char *ssl_sock_get_proto_version(struct connection *conn)
2478{
2479 if (!conn->xprt && !conn->xprt_ctx)
2480 return NULL;
2481 return SSL_get_version(conn->xprt_ctx);
2482}
2483
Willy Tarreau8d598402012-10-22 17:58:39 +02002484/* Extract a serial from a cert, and copy it to a chunk.
2485 * Returns 1 if serial is found and copied, 0 if no serial found and
2486 * -1 if output is not large enough.
2487 */
2488static int
2489ssl_sock_get_serial(X509 *crt, struct chunk *out)
2490{
2491 ASN1_INTEGER *serial;
2492
2493 serial = X509_get_serialNumber(crt);
2494 if (!serial)
2495 return 0;
2496
2497 if (out->size < serial->length)
2498 return -1;
2499
2500 memcpy(out->str, serial->data, serial->length);
2501 out->len = serial->length;
2502 return 1;
2503}
2504
Emeric Brunb3cc4252014-10-29 19:03:26 +01002505/* Extract a cert to der, and copy it to a chunk.
2506 * Returns 1 if cert is found and copied, 0 on der convertion failure and
2507 * -1 if output is not large enough.
2508 */
2509static int
2510ssl_sock_crt2der(X509 *crt, struct chunk *out)
2511{
2512 int len;
2513 unsigned char *p = (unsigned char *)out->str;;
2514
2515 len =i2d_X509(crt, NULL);
2516 if (len <= 0)
2517 return 1;
2518
2519 if (out->size < len)
2520 return -1;
2521
2522 i2d_X509(crt,&p);
2523 out->len = len;
2524 return 1;
2525}
2526
Emeric Brunce5ad802012-10-22 14:11:22 +02002527
2528/* Copy Date in ASN1_UTCTIME format in struct chunk out.
2529 * Returns 1 if serial is found and copied, 0 if no valid time found
2530 * and -1 if output is not large enough.
2531 */
2532static int
2533ssl_sock_get_time(ASN1_TIME *tm, struct chunk *out)
2534{
2535 if (tm->type == V_ASN1_GENERALIZEDTIME) {
2536 ASN1_GENERALIZEDTIME *gentm = (ASN1_GENERALIZEDTIME *)tm;
2537
2538 if (gentm->length < 12)
2539 return 0;
2540 if (gentm->data[0] != 0x32 || gentm->data[1] != 0x30)
2541 return 0;
2542 if (out->size < gentm->length-2)
2543 return -1;
2544
2545 memcpy(out->str, gentm->data+2, gentm->length-2);
2546 out->len = gentm->length-2;
2547 return 1;
2548 }
2549 else if (tm->type == V_ASN1_UTCTIME) {
2550 ASN1_UTCTIME *utctm = (ASN1_UTCTIME *)tm;
2551
2552 if (utctm->length < 10)
2553 return 0;
2554 if (utctm->data[0] >= 0x35)
2555 return 0;
2556 if (out->size < utctm->length)
2557 return -1;
2558
2559 memcpy(out->str, utctm->data, utctm->length);
2560 out->len = utctm->length;
2561 return 1;
2562 }
2563
2564 return 0;
2565}
2566
Emeric Brun87855892012-10-17 17:39:35 +02002567/* Extract an entry from a X509_NAME and copy its value to an output chunk.
2568 * Returns 1 if entry found, 0 if entry not found, or -1 if output not large enough.
2569 */
2570static int
2571ssl_sock_get_dn_entry(X509_NAME *a, const struct chunk *entry, int pos, struct chunk *out)
2572{
2573 X509_NAME_ENTRY *ne;
2574 int i, j, n;
2575 int cur = 0;
2576 const char *s;
2577 char tmp[128];
2578
2579 out->len = 0;
2580 for (i = 0; i < sk_X509_NAME_ENTRY_num(a->entries); i++) {
2581 if (pos < 0)
2582 j = (sk_X509_NAME_ENTRY_num(a->entries)-1) - i;
2583 else
2584 j = i;
2585
2586 ne = sk_X509_NAME_ENTRY_value(a->entries, j);
2587 n = OBJ_obj2nid(ne->object);
2588 if ((n == NID_undef) || ((s = OBJ_nid2sn(n)) == NULL)) {
2589 i2t_ASN1_OBJECT(tmp, sizeof(tmp), ne->object);
2590 s = tmp;
2591 }
2592
2593 if (chunk_strcasecmp(entry, s) != 0)
2594 continue;
2595
2596 if (pos < 0)
2597 cur--;
2598 else
2599 cur++;
2600
2601 if (cur != pos)
2602 continue;
2603
2604 if (ne->value->length > out->size)
2605 return -1;
2606
2607 memcpy(out->str, ne->value->data, ne->value->length);
2608 out->len = ne->value->length;
2609 return 1;
2610 }
2611
2612 return 0;
2613
2614}
2615
2616/* Extract and format full DN from a X509_NAME and copy result into a chunk
2617 * Returns 1 if dn entries exits, 0 if no dn entry found or -1 if output is not large enough.
2618 */
2619static int
2620ssl_sock_get_dn_oneline(X509_NAME *a, struct chunk *out)
2621{
2622 X509_NAME_ENTRY *ne;
2623 int i, n, ln;
2624 int l = 0;
2625 const char *s;
2626 char *p;
2627 char tmp[128];
2628
2629 out->len = 0;
2630 p = out->str;
2631 for (i = 0; i < sk_X509_NAME_ENTRY_num(a->entries); i++) {
2632 ne = sk_X509_NAME_ENTRY_value(a->entries, i);
2633 n = OBJ_obj2nid(ne->object);
2634 if ((n == NID_undef) || ((s = OBJ_nid2sn(n)) == NULL)) {
2635 i2t_ASN1_OBJECT(tmp, sizeof(tmp), ne->object);
2636 s = tmp;
2637 }
2638 ln = strlen(s);
2639
2640 l += 1 + ln + 1 + ne->value->length;
2641 if (l > out->size)
2642 return -1;
2643 out->len = l;
2644
2645 *(p++)='/';
2646 memcpy(p, s, ln);
2647 p += ln;
2648 *(p++)='=';
2649 memcpy(p, ne->value->data, ne->value->length);
2650 p += ne->value->length;
2651 }
2652
2653 if (!out->len)
2654 return 0;
2655
2656 return 1;
2657}
2658
David Safb76832014-05-08 23:42:08 -04002659char *ssl_sock_get_version(struct connection *conn)
2660{
2661 if (!ssl_sock_is_ssl(conn))
2662 return NULL;
2663
2664 return (char *)SSL_get_version(conn->xprt_ctx);
2665}
2666
Emeric Brun49100982014-06-24 18:26:41 +02002667/* Extract peer certificate's common name into the chunk dest
2668 * Returns
2669 * the len of the extracted common name
2670 * or 0 if no CN found in DN
2671 * or -1 on error case (i.e. no peer certificate)
2672 */
2673int ssl_sock_get_remote_common_name(struct connection *conn, struct chunk *dest)
David Safb76832014-05-08 23:42:08 -04002674{
2675 X509 *crt = NULL;
2676 X509_NAME *name;
David Safb76832014-05-08 23:42:08 -04002677 const char find_cn[] = "CN";
2678 const struct chunk find_cn_chunk = {
2679 .str = (char *)&find_cn,
2680 .len = sizeof(find_cn)-1
2681 };
Emeric Brun49100982014-06-24 18:26:41 +02002682 int result = -1;
David Safb76832014-05-08 23:42:08 -04002683
2684 if (!ssl_sock_is_ssl(conn))
Emeric Brun49100982014-06-24 18:26:41 +02002685 goto out;
David Safb76832014-05-08 23:42:08 -04002686
2687 /* SSL_get_peer_certificate, it increase X509 * ref count */
2688 crt = SSL_get_peer_certificate(conn->xprt_ctx);
2689 if (!crt)
2690 goto out;
2691
2692 name = X509_get_subject_name(crt);
2693 if (!name)
2694 goto out;
David Safb76832014-05-08 23:42:08 -04002695
Emeric Brun49100982014-06-24 18:26:41 +02002696 result = ssl_sock_get_dn_entry(name, &find_cn_chunk, 1, dest);
2697out:
David Safb76832014-05-08 23:42:08 -04002698 if (crt)
2699 X509_free(crt);
2700
2701 return result;
2702}
2703
Dave McCowand6ec6052014-07-30 10:39:13 -04002704/* returns 1 if client passed a certificate for this session, 0 if not */
2705int ssl_sock_get_cert_used_sess(struct connection *conn)
2706{
2707 X509 *crt = NULL;
2708
2709 if (!ssl_sock_is_ssl(conn))
2710 return 0;
2711
2712 /* SSL_get_peer_certificate, it increase X509 * ref count */
2713 crt = SSL_get_peer_certificate(conn->xprt_ctx);
2714 if (!crt)
2715 return 0;
2716
2717 X509_free(crt);
2718 return 1;
2719}
2720
2721/* returns 1 if client passed a certificate for this connection, 0 if not */
2722int ssl_sock_get_cert_used_conn(struct connection *conn)
David Safb76832014-05-08 23:42:08 -04002723{
2724 if (!ssl_sock_is_ssl(conn))
2725 return 0;
2726
2727 return SSL_SOCK_ST_FL_VERIFY_DONE & conn->xprt_st ? 1 : 0;
2728}
2729
2730/* returns result from SSL verify */
2731unsigned int ssl_sock_get_verify_result(struct connection *conn)
2732{
2733 if (!ssl_sock_is_ssl(conn))
2734 return (unsigned int)X509_V_ERR_APPLICATION_VERIFICATION;
2735
2736 return (unsigned int)SSL_get_verify_result(conn->xprt_ctx);
2737}
2738
Willy Tarreau7875d092012-09-10 08:20:03 +02002739/***** Below are some sample fetching functions for ACL/patterns *****/
2740
Emeric Brune64aef12012-09-21 13:15:06 +02002741/* boolean, returns true if client cert was present */
2742static int
Emeric Brun2525b6b2012-10-18 15:59:43 +02002743smp_fetch_ssl_fc_has_crt(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002744 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brune64aef12012-09-21 13:15:06 +02002745{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002746 struct connection *conn;
2747
2748 if (!l4)
2749 return 0;
2750
2751 conn = objt_conn(l4->si[0].end);
2752 if (!conn || conn->xprt != &ssl_sock)
Emeric Brune64aef12012-09-21 13:15:06 +02002753 return 0;
2754
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002755 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brune64aef12012-09-21 13:15:06 +02002756 smp->flags |= SMP_F_MAY_CHANGE;
2757 return 0;
2758 }
2759
2760 smp->flags = 0;
2761 smp->type = SMP_T_BOOL;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002762 smp->data.uint = SSL_SOCK_ST_FL_VERIFY_DONE & conn->xprt_st ? 1 : 0;
Emeric Brune64aef12012-09-21 13:15:06 +02002763
2764 return 1;
2765}
2766
Emeric Brunb3cc4252014-10-29 19:03:26 +01002767/* binary, returns a certificate in a binary chunk (der/raw).
2768 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
2769 * should be use.
2770 */
2771static int
2772smp_fetch_ssl_x_der(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
2773 const struct arg *args, struct sample *smp, const char *kw)
2774{
2775 int cert_peer = (kw[4] == 'c') ? 1 : 0;
2776 X509 *crt = NULL;
2777 int ret = 0;
2778 struct chunk *smp_trash;
2779 struct connection *conn;
2780
2781 if (!l4)
2782 return 0;
2783
2784 conn = objt_conn(l4->si[0].end);
2785 if (!conn || conn->xprt != &ssl_sock)
2786 return 0;
2787
2788 if (!(conn->flags & CO_FL_CONNECTED)) {
2789 smp->flags |= SMP_F_MAY_CHANGE;
2790 return 0;
2791 }
2792
2793 if (cert_peer)
2794 crt = SSL_get_peer_certificate(conn->xprt_ctx);
2795 else
2796 crt = SSL_get_certificate(conn->xprt_ctx);
2797
2798 if (!crt)
2799 goto out;
2800
2801 smp_trash = get_trash_chunk();
2802 if (ssl_sock_crt2der(crt, smp_trash) <= 0)
2803 goto out;
2804
2805 smp->data.str = *smp_trash;
2806 smp->type = SMP_T_BIN;
2807 ret = 1;
2808out:
2809 /* SSL_get_peer_certificate, it increase X509 * ref count */
2810 if (cert_peer && crt)
2811 X509_free(crt);
2812 return ret;
2813}
2814
Emeric Brunba841a12014-04-30 17:05:08 +02002815/* binary, returns serial of certificate in a binary chunk.
2816 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
2817 * should be use.
2818 */
Willy Tarreau8d598402012-10-22 17:58:39 +02002819static int
Emeric Brunba841a12014-04-30 17:05:08 +02002820smp_fetch_ssl_x_serial(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002821 const struct arg *args, struct sample *smp, const char *kw)
Willy Tarreau8d598402012-10-22 17:58:39 +02002822{
Emeric Brunba841a12014-04-30 17:05:08 +02002823 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Willy Tarreau8d598402012-10-22 17:58:39 +02002824 X509 *crt = NULL;
2825 int ret = 0;
2826 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002827 struct connection *conn;
2828
2829 if (!l4)
2830 return 0;
Willy Tarreau8d598402012-10-22 17:58:39 +02002831
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002832 conn = objt_conn(l4->si[0].end);
2833 if (!conn || conn->xprt != &ssl_sock)
Willy Tarreau8d598402012-10-22 17:58:39 +02002834 return 0;
2835
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002836 if (!(conn->flags & CO_FL_CONNECTED)) {
Willy Tarreau8d598402012-10-22 17:58:39 +02002837 smp->flags |= SMP_F_MAY_CHANGE;
2838 return 0;
2839 }
2840
Emeric Brunba841a12014-04-30 17:05:08 +02002841 if (cert_peer)
2842 crt = SSL_get_peer_certificate(conn->xprt_ctx);
2843 else
2844 crt = SSL_get_certificate(conn->xprt_ctx);
2845
Willy Tarreau8d598402012-10-22 17:58:39 +02002846 if (!crt)
2847 goto out;
2848
Willy Tarreau47ca5452012-12-23 20:22:19 +01002849 smp_trash = get_trash_chunk();
Willy Tarreau8d598402012-10-22 17:58:39 +02002850 if (ssl_sock_get_serial(crt, smp_trash) <= 0)
2851 goto out;
2852
2853 smp->data.str = *smp_trash;
2854 smp->type = SMP_T_BIN;
2855 ret = 1;
2856out:
Emeric Brunba841a12014-04-30 17:05:08 +02002857 /* SSL_get_peer_certificate, it increase X509 * ref count */
2858 if (cert_peer && crt)
Willy Tarreau8d598402012-10-22 17:58:39 +02002859 X509_free(crt);
2860 return ret;
2861}
Emeric Brune64aef12012-09-21 13:15:06 +02002862
Emeric Brunba841a12014-04-30 17:05:08 +02002863/* binary, returns the client certificate's SHA-1 fingerprint (SHA-1 hash of DER-encoded certificate) in a binary chunk.
2864 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
2865 * should be use.
2866 */
James Votha051b4a2013-05-14 20:37:59 +02002867static int
Emeric Brunba841a12014-04-30 17:05:08 +02002868smp_fetch_ssl_x_sha1(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002869 const struct arg *args, struct sample *smp, const char *kw)
James Votha051b4a2013-05-14 20:37:59 +02002870{
Emeric Brunba841a12014-04-30 17:05:08 +02002871 int cert_peer = (kw[4] == 'c') ? 1 : 0;
James Votha051b4a2013-05-14 20:37:59 +02002872 X509 *crt = NULL;
2873 const EVP_MD *digest;
2874 int ret = 0;
2875 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002876 struct connection *conn;
James Votha051b4a2013-05-14 20:37:59 +02002877
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002878 if (!l4)
James Votha051b4a2013-05-14 20:37:59 +02002879 return 0;
2880
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002881 conn = objt_conn(l4->si[0].end);
2882 if (!conn || conn->xprt != &ssl_sock)
2883 return 0;
2884
2885 if (!(conn->flags & CO_FL_CONNECTED)) {
James Votha051b4a2013-05-14 20:37:59 +02002886 smp->flags |= SMP_F_MAY_CHANGE;
2887 return 0;
2888 }
2889
Emeric Brunba841a12014-04-30 17:05:08 +02002890 if (cert_peer)
2891 crt = SSL_get_peer_certificate(conn->xprt_ctx);
2892 else
2893 crt = SSL_get_certificate(conn->xprt_ctx);
James Votha051b4a2013-05-14 20:37:59 +02002894 if (!crt)
2895 goto out;
2896
2897 smp_trash = get_trash_chunk();
2898 digest = EVP_sha1();
2899 X509_digest(crt, digest, (unsigned char *)smp_trash->str, (unsigned int *)&smp_trash->len);
2900
2901 smp->data.str = *smp_trash;
2902 smp->type = SMP_T_BIN;
2903 ret = 1;
2904out:
Emeric Brunba841a12014-04-30 17:05:08 +02002905 /* SSL_get_peer_certificate, it increase X509 * ref count */
2906 if (cert_peer && crt)
James Votha051b4a2013-05-14 20:37:59 +02002907 X509_free(crt);
2908 return ret;
2909}
2910
Emeric Brunba841a12014-04-30 17:05:08 +02002911/* string, returns certificate's notafter date in ASN1_UTCTIME format.
2912 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
2913 * should be use.
2914 */
Emeric Brunce5ad802012-10-22 14:11:22 +02002915static int
Emeric Brunba841a12014-04-30 17:05:08 +02002916smp_fetch_ssl_x_notafter(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002917 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brunce5ad802012-10-22 14:11:22 +02002918{
Emeric Brunba841a12014-04-30 17:05:08 +02002919 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brunce5ad802012-10-22 14:11:22 +02002920 X509 *crt = NULL;
2921 int ret = 0;
2922 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002923 struct connection *conn;
Emeric Brunce5ad802012-10-22 14:11:22 +02002924
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002925 if (!l4)
Emeric Brunce5ad802012-10-22 14:11:22 +02002926 return 0;
2927
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002928 conn = objt_conn(l4->si[0].end);
2929 if (!conn || conn->xprt != &ssl_sock)
2930 return 0;
2931
2932 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunce5ad802012-10-22 14:11:22 +02002933 smp->flags |= SMP_F_MAY_CHANGE;
2934 return 0;
2935 }
2936
Emeric Brunba841a12014-04-30 17:05:08 +02002937 if (cert_peer)
2938 crt = SSL_get_peer_certificate(conn->xprt_ctx);
2939 else
2940 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brunce5ad802012-10-22 14:11:22 +02002941 if (!crt)
2942 goto out;
2943
Willy Tarreau47ca5452012-12-23 20:22:19 +01002944 smp_trash = get_trash_chunk();
Emeric Brunce5ad802012-10-22 14:11:22 +02002945 if (ssl_sock_get_time(X509_get_notAfter(crt), smp_trash) <= 0)
2946 goto out;
2947
2948 smp->data.str = *smp_trash;
2949 smp->type = SMP_T_STR;
2950 ret = 1;
2951out:
Emeric Brunba841a12014-04-30 17:05:08 +02002952 /* SSL_get_peer_certificate, it increase X509 * ref count */
2953 if (cert_peer && crt)
Emeric Brunce5ad802012-10-22 14:11:22 +02002954 X509_free(crt);
2955 return ret;
2956}
2957
Emeric Brunba841a12014-04-30 17:05:08 +02002958/* string, returns a string of a formatted full dn \C=..\O=..\OU=.. \CN=.. of certificate's issuer
2959 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
2960 * should be use.
2961 */
Emeric Brun87855892012-10-17 17:39:35 +02002962static int
Emeric Brunba841a12014-04-30 17:05:08 +02002963smp_fetch_ssl_x_i_dn(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002964 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brun87855892012-10-17 17:39:35 +02002965{
Emeric Brunba841a12014-04-30 17:05:08 +02002966 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brun87855892012-10-17 17:39:35 +02002967 X509 *crt = NULL;
2968 X509_NAME *name;
2969 int ret = 0;
2970 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002971 struct connection *conn;
Emeric Brun87855892012-10-17 17:39:35 +02002972
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002973 if (!l4)
Emeric Brun87855892012-10-17 17:39:35 +02002974 return 0;
2975
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002976 conn = objt_conn(l4->si[0].end);
2977 if (!conn || conn->xprt != &ssl_sock)
2978 return 0;
2979
2980 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun87855892012-10-17 17:39:35 +02002981 smp->flags |= SMP_F_MAY_CHANGE;
2982 return 0;
2983 }
2984
Emeric Brunba841a12014-04-30 17:05:08 +02002985 if (cert_peer)
2986 crt = SSL_get_peer_certificate(conn->xprt_ctx);
2987 else
2988 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brun87855892012-10-17 17:39:35 +02002989 if (!crt)
2990 goto out;
2991
2992 name = X509_get_issuer_name(crt);
2993 if (!name)
2994 goto out;
2995
Willy Tarreau47ca5452012-12-23 20:22:19 +01002996 smp_trash = get_trash_chunk();
Emeric Brun87855892012-10-17 17:39:35 +02002997 if (args && args[0].type == ARGT_STR) {
2998 int pos = 1;
2999
3000 if (args[1].type == ARGT_SINT)
3001 pos = args[1].data.sint;
3002 else if (args[1].type == ARGT_UINT)
3003 pos =(int)args[1].data.uint;
3004
3005 if (ssl_sock_get_dn_entry(name, &args[0].data.str, pos, smp_trash) <= 0)
3006 goto out;
3007 }
3008 else if (ssl_sock_get_dn_oneline(name, smp_trash) <= 0)
3009 goto out;
3010
3011 smp->type = SMP_T_STR;
3012 smp->data.str = *smp_trash;
3013 ret = 1;
3014out:
Emeric Brunba841a12014-04-30 17:05:08 +02003015 /* SSL_get_peer_certificate, it increase X509 * ref count */
3016 if (cert_peer && crt)
Emeric Brun87855892012-10-17 17:39:35 +02003017 X509_free(crt);
3018 return ret;
3019}
3020
Emeric Brunba841a12014-04-30 17:05:08 +02003021/* string, returns notbefore date in ASN1_UTCTIME format.
3022 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
3023 * should be use.
3024 */
Emeric Brunce5ad802012-10-22 14:11:22 +02003025static int
Emeric Brunba841a12014-04-30 17:05:08 +02003026smp_fetch_ssl_x_notbefore(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003027 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brunce5ad802012-10-22 14:11:22 +02003028{
Emeric Brunba841a12014-04-30 17:05:08 +02003029 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brunce5ad802012-10-22 14:11:22 +02003030 X509 *crt = NULL;
3031 int ret = 0;
3032 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003033 struct connection *conn;
3034
3035 if (!l4)
3036 return 0;
Emeric Brunce5ad802012-10-22 14:11:22 +02003037
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003038 conn = objt_conn(l4->si[0].end);
3039 if (!conn || conn->xprt != &ssl_sock)
Emeric Brunce5ad802012-10-22 14:11:22 +02003040 return 0;
3041
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003042 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunce5ad802012-10-22 14:11:22 +02003043 smp->flags |= SMP_F_MAY_CHANGE;
3044 return 0;
3045 }
3046
Emeric Brunba841a12014-04-30 17:05:08 +02003047 if (cert_peer)
3048 crt = SSL_get_peer_certificate(conn->xprt_ctx);
3049 else
3050 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brunce5ad802012-10-22 14:11:22 +02003051 if (!crt)
3052 goto out;
3053
Willy Tarreau47ca5452012-12-23 20:22:19 +01003054 smp_trash = get_trash_chunk();
Emeric Brunce5ad802012-10-22 14:11:22 +02003055 if (ssl_sock_get_time(X509_get_notBefore(crt), smp_trash) <= 0)
3056 goto out;
3057
3058 smp->data.str = *smp_trash;
3059 smp->type = SMP_T_STR;
3060 ret = 1;
3061out:
Emeric Brunba841a12014-04-30 17:05:08 +02003062 /* SSL_get_peer_certificate, it increase X509 * ref count */
3063 if (cert_peer && crt)
Emeric Brunce5ad802012-10-22 14:11:22 +02003064 X509_free(crt);
3065 return ret;
3066}
3067
Emeric Brunba841a12014-04-30 17:05:08 +02003068/* string, returns a string of a formatted full dn \C=..\O=..\OU=.. \CN=.. of certificate's subject
3069 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
3070 * should be use.
3071 */
Emeric Brun87855892012-10-17 17:39:35 +02003072static int
Emeric Brunba841a12014-04-30 17:05:08 +02003073smp_fetch_ssl_x_s_dn(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003074 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brun87855892012-10-17 17:39:35 +02003075{
Emeric Brunba841a12014-04-30 17:05:08 +02003076 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brun87855892012-10-17 17:39:35 +02003077 X509 *crt = NULL;
3078 X509_NAME *name;
3079 int ret = 0;
3080 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003081 struct connection *conn;
Emeric Brun87855892012-10-17 17:39:35 +02003082
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003083 if (!l4)
Emeric Brun87855892012-10-17 17:39:35 +02003084 return 0;
3085
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003086 conn = objt_conn(l4->si[0].end);
3087 if (!conn || conn->xprt != &ssl_sock)
3088 return 0;
3089
3090 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun87855892012-10-17 17:39:35 +02003091 smp->flags |= SMP_F_MAY_CHANGE;
3092 return 0;
3093 }
3094
Emeric Brunba841a12014-04-30 17:05:08 +02003095 if (cert_peer)
3096 crt = SSL_get_peer_certificate(conn->xprt_ctx);
3097 else
3098 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brun87855892012-10-17 17:39:35 +02003099 if (!crt)
3100 goto out;
3101
3102 name = X509_get_subject_name(crt);
3103 if (!name)
3104 goto out;
3105
Willy Tarreau47ca5452012-12-23 20:22:19 +01003106 smp_trash = get_trash_chunk();
Emeric Brun87855892012-10-17 17:39:35 +02003107 if (args && args[0].type == ARGT_STR) {
3108 int pos = 1;
3109
3110 if (args[1].type == ARGT_SINT)
3111 pos = args[1].data.sint;
3112 else if (args[1].type == ARGT_UINT)
3113 pos =(int)args[1].data.uint;
3114
3115 if (ssl_sock_get_dn_entry(name, &args[0].data.str, pos, smp_trash) <= 0)
3116 goto out;
3117 }
3118 else if (ssl_sock_get_dn_oneline(name, smp_trash) <= 0)
3119 goto out;
3120
3121 smp->type = SMP_T_STR;
3122 smp->data.str = *smp_trash;
3123 ret = 1;
3124out:
Emeric Brunba841a12014-04-30 17:05:08 +02003125 /* SSL_get_peer_certificate, it increase X509 * ref count */
3126 if (cert_peer && crt)
Emeric Brun87855892012-10-17 17:39:35 +02003127 X509_free(crt);
3128 return ret;
3129}
Emeric Brun9143d372012-12-20 15:44:16 +01003130
3131/* integer, returns true if current session use a client certificate */
3132static int
3133smp_fetch_ssl_c_used(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003134 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brun9143d372012-12-20 15:44:16 +01003135{
3136 X509 *crt;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003137 struct connection *conn;
Emeric Brun9143d372012-12-20 15:44:16 +01003138
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003139 if (!l4)
Emeric Brun9143d372012-12-20 15:44:16 +01003140 return 0;
3141
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003142 conn = objt_conn(l4->si[0].end);
3143 if (!conn || conn->xprt != &ssl_sock)
3144 return 0;
3145
3146 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun9143d372012-12-20 15:44:16 +01003147 smp->flags |= SMP_F_MAY_CHANGE;
3148 return 0;
3149 }
3150
3151 /* SSL_get_peer_certificate returns a ptr on allocated X509 struct */
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003152 crt = SSL_get_peer_certificate(conn->xprt_ctx);
Emeric Brun9143d372012-12-20 15:44:16 +01003153 if (crt) {
3154 X509_free(crt);
3155 }
3156
3157 smp->type = SMP_T_BOOL;
3158 smp->data.uint = (crt != NULL);
3159 return 1;
3160}
3161
Emeric Brunba841a12014-04-30 17:05:08 +02003162/* integer, returns the certificate version
3163 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
3164 * should be use.
3165 */
Emeric Bruna7359fd2012-10-17 15:03:11 +02003166static int
Emeric Brunba841a12014-04-30 17:05:08 +02003167smp_fetch_ssl_x_version(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003168 const struct arg *args, struct sample *smp, const char *kw)
Emeric Bruna7359fd2012-10-17 15:03:11 +02003169{
Emeric Brunba841a12014-04-30 17:05:08 +02003170 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Bruna7359fd2012-10-17 15:03:11 +02003171 X509 *crt;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003172 struct connection *conn;
3173
3174 if (!l4)
3175 return 0;
Emeric Bruna7359fd2012-10-17 15:03:11 +02003176
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003177 conn = objt_conn(l4->si[0].end);
3178 if (!conn || conn->xprt != &ssl_sock)
Emeric Bruna7359fd2012-10-17 15:03:11 +02003179 return 0;
3180
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003181 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Bruna7359fd2012-10-17 15:03:11 +02003182 smp->flags |= SMP_F_MAY_CHANGE;
3183 return 0;
3184 }
3185
Emeric Brunba841a12014-04-30 17:05:08 +02003186 if (cert_peer)
3187 crt = SSL_get_peer_certificate(conn->xprt_ctx);
3188 else
3189 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Bruna7359fd2012-10-17 15:03:11 +02003190 if (!crt)
3191 return 0;
3192
3193 smp->data.uint = (unsigned int)(1 + X509_get_version(crt));
Emeric Brunba841a12014-04-30 17:05:08 +02003194 /* SSL_get_peer_certificate increase X509 * ref count */
3195 if (cert_peer)
3196 X509_free(crt);
Emeric Bruna7359fd2012-10-17 15:03:11 +02003197 smp->type = SMP_T_UINT;
3198
3199 return 1;
3200}
3201
Emeric Brunba841a12014-04-30 17:05:08 +02003202/* string, returns the certificate's signature algorithm.
3203 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
3204 * should be use.
3205 */
Emeric Brun7f56e742012-10-19 18:15:40 +02003206static int
Emeric Brunba841a12014-04-30 17:05:08 +02003207smp_fetch_ssl_x_sig_alg(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003208 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brun7f56e742012-10-19 18:15:40 +02003209{
Emeric Brunba841a12014-04-30 17:05:08 +02003210 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brun7f56e742012-10-19 18:15:40 +02003211 X509 *crt;
3212 int nid;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003213 struct connection *conn;
Emeric Brun7f56e742012-10-19 18:15:40 +02003214
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003215 if (!l4)
Emeric Brun7f56e742012-10-19 18:15:40 +02003216 return 0;
3217
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003218 conn = objt_conn(l4->si[0].end);
3219 if (!conn || conn->xprt != &ssl_sock)
3220 return 0;
3221
3222 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun7f56e742012-10-19 18:15:40 +02003223 smp->flags |= SMP_F_MAY_CHANGE;
3224 return 0;
3225 }
3226
Emeric Brunba841a12014-04-30 17:05:08 +02003227 if (cert_peer)
3228 crt = SSL_get_peer_certificate(conn->xprt_ctx);
3229 else
3230 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brun7f56e742012-10-19 18:15:40 +02003231 if (!crt)
3232 return 0;
3233
3234 nid = OBJ_obj2nid((ASN1_OBJECT *)(crt->cert_info->signature->algorithm));
3235
3236 smp->data.str.str = (char *)OBJ_nid2sn(nid);
Emeric Brun9bf3ba22013-10-07 14:31:44 +02003237 if (!smp->data.str.str) {
Emeric Brunba841a12014-04-30 17:05:08 +02003238 /* SSL_get_peer_certificate increase X509 * ref count */
3239 if (cert_peer)
3240 X509_free(crt);
Emeric Brun7f56e742012-10-19 18:15:40 +02003241 return 0;
Emeric Brun9bf3ba22013-10-07 14:31:44 +02003242 }
Emeric Brun7f56e742012-10-19 18:15:40 +02003243
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01003244 smp->type = SMP_T_STR;
3245 smp->flags |= SMP_F_CONST;
Emeric Brun7f56e742012-10-19 18:15:40 +02003246 smp->data.str.len = strlen(smp->data.str.str);
Emeric Brunba841a12014-04-30 17:05:08 +02003247 /* SSL_get_peer_certificate increase X509 * ref count */
3248 if (cert_peer)
3249 X509_free(crt);
Emeric Brun7f56e742012-10-19 18:15:40 +02003250
3251 return 1;
3252}
3253
Emeric Brunba841a12014-04-30 17:05:08 +02003254/* string, returns the certificate's key algorithm.
3255 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
3256 * should be use.
3257 */
Emeric Brun521a0112012-10-22 12:22:55 +02003258static int
Emeric Brunba841a12014-04-30 17:05:08 +02003259smp_fetch_ssl_x_key_alg(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003260 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brun521a0112012-10-22 12:22:55 +02003261{
Emeric Brunba841a12014-04-30 17:05:08 +02003262 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brun521a0112012-10-22 12:22:55 +02003263 X509 *crt;
3264 int nid;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003265 struct connection *conn;
Emeric Brun521a0112012-10-22 12:22:55 +02003266
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003267 if (!l4)
Emeric Brun521a0112012-10-22 12:22:55 +02003268 return 0;
3269
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003270 conn = objt_conn(l4->si[0].end);
3271 if (!conn || conn->xprt != &ssl_sock)
3272 return 0;
3273
3274 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun521a0112012-10-22 12:22:55 +02003275 smp->flags |= SMP_F_MAY_CHANGE;
3276 return 0;
3277 }
3278
Emeric Brunba841a12014-04-30 17:05:08 +02003279 if (cert_peer)
3280 crt = SSL_get_peer_certificate(conn->xprt_ctx);
3281 else
3282 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brun521a0112012-10-22 12:22:55 +02003283 if (!crt)
3284 return 0;
3285
3286 nid = OBJ_obj2nid((ASN1_OBJECT *)(crt->cert_info->key->algor->algorithm));
3287
3288 smp->data.str.str = (char *)OBJ_nid2sn(nid);
Emeric Brun9bf3ba22013-10-07 14:31:44 +02003289 if (!smp->data.str.str) {
Emeric Brunba841a12014-04-30 17:05:08 +02003290 /* SSL_get_peer_certificate increase X509 * ref count */
3291 if (cert_peer)
3292 X509_free(crt);
Emeric Brun521a0112012-10-22 12:22:55 +02003293 return 0;
Emeric Brun9bf3ba22013-10-07 14:31:44 +02003294 }
Emeric Brun521a0112012-10-22 12:22:55 +02003295
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01003296 smp->type = SMP_T_STR;
3297 smp->flags |= SMP_F_CONST;
Emeric Brun521a0112012-10-22 12:22:55 +02003298 smp->data.str.len = strlen(smp->data.str.str);
Emeric Brunba841a12014-04-30 17:05:08 +02003299 if (cert_peer)
3300 X509_free(crt);
Emeric Brun521a0112012-10-22 12:22:55 +02003301
3302 return 1;
3303}
3304
Emeric Brun645ae792014-04-30 14:21:06 +02003305/* boolean, returns true if front conn. transport layer is SSL.
3306 * This function is also usable on backend conn if the fetch keyword 5th
3307 * char is 'b'.
3308 */
Willy Tarreau7875d092012-09-10 08:20:03 +02003309static int
Emeric Brun2525b6b2012-10-18 15:59:43 +02003310smp_fetch_ssl_fc(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003311 const struct arg *args, struct sample *smp, const char *kw)
Willy Tarreau7875d092012-09-10 08:20:03 +02003312{
Emeric Brun645ae792014-04-30 14:21:06 +02003313 int back_conn = (kw[4] == 'b') ? 1 : 0;
3314 struct connection *conn = objt_conn(l4->si[back_conn].end);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003315
Willy Tarreau7875d092012-09-10 08:20:03 +02003316 smp->type = SMP_T_BOOL;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003317 smp->data.uint = (conn && conn->xprt == &ssl_sock);
Willy Tarreau7875d092012-09-10 08:20:03 +02003318 return 1;
3319}
3320
Emeric Brun2525b6b2012-10-18 15:59:43 +02003321/* boolean, returns true if client present a SNI */
Willy Tarreau7875d092012-09-10 08:20:03 +02003322static int
Emeric Brun2525b6b2012-10-18 15:59:43 +02003323smp_fetch_ssl_fc_has_sni(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003324 const struct arg *args, struct sample *smp, const char *kw)
Willy Tarreau7875d092012-09-10 08:20:03 +02003325{
3326#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003327 struct connection *conn = objt_conn(l4->si[0].end);
3328
Willy Tarreau7875d092012-09-10 08:20:03 +02003329 smp->type = SMP_T_BOOL;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003330 smp->data.uint = (conn && conn->xprt == &ssl_sock) &&
3331 conn->xprt_ctx &&
3332 SSL_get_servername(conn->xprt_ctx, TLSEXT_NAMETYPE_host_name) != NULL;
Willy Tarreau7875d092012-09-10 08:20:03 +02003333 return 1;
3334#else
3335 return 0;
3336#endif
3337}
3338
Emeric Brun645ae792014-04-30 14:21:06 +02003339/* string, returns the used cipher if front conn. transport layer is SSL.
3340 * This function is also usable on backend conn if the fetch keyword 5th
3341 * char is 'b'.
3342 */
Emeric Brun589fcad2012-10-16 14:13:26 +02003343static int
3344smp_fetch_ssl_fc_cipher(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003345 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brun589fcad2012-10-16 14:13:26 +02003346{
Emeric Brun645ae792014-04-30 14:21:06 +02003347 int back_conn = (kw[4] == 'b') ? 1 : 0;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003348 struct connection *conn;
3349
Emeric Brun589fcad2012-10-16 14:13:26 +02003350 smp->flags = 0;
3351
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003352 if (!l4)
3353 return 0;
3354
Emeric Brun645ae792014-04-30 14:21:06 +02003355 conn = objt_conn(l4->si[back_conn].end);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003356 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
Emeric Brun589fcad2012-10-16 14:13:26 +02003357 return 0;
3358
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003359 smp->data.str.str = (char *)SSL_get_cipher_name(conn->xprt_ctx);
Emeric Brun589fcad2012-10-16 14:13:26 +02003360 if (!smp->data.str.str)
3361 return 0;
3362
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01003363 smp->type = SMP_T_STR;
3364 smp->flags |= SMP_F_CONST;
Emeric Brun589fcad2012-10-16 14:13:26 +02003365 smp->data.str.len = strlen(smp->data.str.str);
3366
3367 return 1;
3368}
3369
Emeric Brun645ae792014-04-30 14:21:06 +02003370/* integer, returns the algoritm's keysize if front conn. transport layer
3371 * is SSL.
3372 * This function is also usable on backend conn if the fetch keyword 5th
3373 * char is 'b'.
3374 */
Emeric Brun589fcad2012-10-16 14:13:26 +02003375static int
3376smp_fetch_ssl_fc_alg_keysize(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003377 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brun589fcad2012-10-16 14:13:26 +02003378{
Emeric Brun645ae792014-04-30 14:21:06 +02003379 int back_conn = (kw[4] == 'b') ? 1 : 0;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003380 struct connection *conn;
3381
Emeric Brun589fcad2012-10-16 14:13:26 +02003382 smp->flags = 0;
3383
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003384 if (!l4)
Emeric Brun589fcad2012-10-16 14:13:26 +02003385 return 0;
3386
Emeric Brun645ae792014-04-30 14:21:06 +02003387 conn = objt_conn(l4->si[back_conn].end);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003388 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
Emeric Brun589fcad2012-10-16 14:13:26 +02003389 return 0;
3390
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003391 if (!SSL_get_cipher_bits(conn->xprt_ctx, (int *)&smp->data.uint))
3392 return 0;
3393
Emeric Brun589fcad2012-10-16 14:13:26 +02003394 smp->type = SMP_T_UINT;
3395
3396 return 1;
3397}
3398
Emeric Brun645ae792014-04-30 14:21:06 +02003399/* integer, returns the used keysize if front conn. transport layer is SSL.
3400 * This function is also usable on backend conn if the fetch keyword 5th
3401 * char is 'b'.
3402 */
Emeric Brun589fcad2012-10-16 14:13:26 +02003403static int
3404smp_fetch_ssl_fc_use_keysize(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003405 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brun589fcad2012-10-16 14:13:26 +02003406{
Emeric Brun645ae792014-04-30 14:21:06 +02003407 int back_conn = (kw[4] == 'b') ? 1 : 0;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003408 struct connection *conn;
3409
Emeric Brun589fcad2012-10-16 14:13:26 +02003410 smp->flags = 0;
3411
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003412 if (!l4)
Emeric Brun589fcad2012-10-16 14:13:26 +02003413 return 0;
3414
Emeric Brun645ae792014-04-30 14:21:06 +02003415 conn = objt_conn(l4->si[back_conn].end);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003416 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
3417 return 0;
3418
3419 smp->data.uint = (unsigned int)SSL_get_cipher_bits(conn->xprt_ctx, NULL);
Emeric Brun589fcad2012-10-16 14:13:26 +02003420 if (!smp->data.uint)
3421 return 0;
3422
3423 smp->type = SMP_T_UINT;
3424
3425 return 1;
3426}
3427
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02003428#ifdef OPENSSL_NPN_NEGOTIATED
Willy Tarreau7875d092012-09-10 08:20:03 +02003429static int
Emeric Brun2525b6b2012-10-18 15:59:43 +02003430smp_fetch_ssl_fc_npn(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003431 const struct arg *args, struct sample *smp, const char *kw)
Willy Tarreaua33c6542012-10-15 13:19:06 +02003432{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003433 struct connection *conn;
3434
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01003435 smp->flags = SMP_F_CONST;
3436 smp->type = SMP_T_STR;
Willy Tarreaua33c6542012-10-15 13:19:06 +02003437
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003438 if (!l4)
Willy Tarreaua33c6542012-10-15 13:19:06 +02003439 return 0;
3440
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003441 conn = objt_conn(l4->si[0].end);
3442 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
3443 return 0;
3444
Willy Tarreaua33c6542012-10-15 13:19:06 +02003445 smp->data.str.str = NULL;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003446 SSL_get0_next_proto_negotiated(conn->xprt_ctx,
Willy Tarreaua33c6542012-10-15 13:19:06 +02003447 (const unsigned char **)&smp->data.str.str, (unsigned *)&smp->data.str.len);
3448
3449 if (!smp->data.str.str)
3450 return 0;
3451
3452 return 1;
Willy Tarreaua33c6542012-10-15 13:19:06 +02003453}
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02003454#endif
Willy Tarreaua33c6542012-10-15 13:19:06 +02003455
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01003456#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Willy Tarreauab861d32013-04-02 02:30:41 +02003457static int
3458smp_fetch_ssl_fc_alpn(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003459 const struct arg *args, struct sample *smp, const char *kw)
Willy Tarreauab861d32013-04-02 02:30:41 +02003460{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003461 struct connection *conn;
3462
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01003463 smp->flags = SMP_F_CONST;
3464 smp->type = SMP_T_STR;
Willy Tarreauab861d32013-04-02 02:30:41 +02003465
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003466 if (!l4)
3467 return 0;
3468
3469 conn = objt_conn(l4->si[0].end);
3470 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
Willy Tarreauab861d32013-04-02 02:30:41 +02003471 return 0;
3472
3473 smp->data.str.str = NULL;
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01003474 SSL_get0_alpn_selected(conn->xprt_ctx,
Willy Tarreauab861d32013-04-02 02:30:41 +02003475 (const unsigned char **)&smp->data.str.str, (unsigned *)&smp->data.str.len);
3476
3477 if (!smp->data.str.str)
3478 return 0;
3479
3480 return 1;
3481}
3482#endif
3483
Emeric Brun645ae792014-04-30 14:21:06 +02003484/* string, returns the used protocol if front conn. transport layer is SSL.
3485 * This function is also usable on backend conn if the fetch keyword 5th
3486 * char is 'b'.
3487 */
Willy Tarreaua33c6542012-10-15 13:19:06 +02003488static int
Emeric Brun589fcad2012-10-16 14:13:26 +02003489smp_fetch_ssl_fc_protocol(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003490 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brun589fcad2012-10-16 14:13:26 +02003491{
Emeric Brun645ae792014-04-30 14:21:06 +02003492 int back_conn = (kw[4] == 'b') ? 1 : 0;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003493 struct connection *conn;
3494
Emeric Brun589fcad2012-10-16 14:13:26 +02003495 smp->flags = 0;
3496
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003497 if (!l4)
Emeric Brun589fcad2012-10-16 14:13:26 +02003498 return 0;
3499
Emeric Brun645ae792014-04-30 14:21:06 +02003500 conn = objt_conn(l4->si[back_conn].end);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003501 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
3502 return 0;
3503
3504 smp->data.str.str = (char *)SSL_get_version(conn->xprt_ctx);
Emeric Brun589fcad2012-10-16 14:13:26 +02003505 if (!smp->data.str.str)
3506 return 0;
3507
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01003508 smp->type = SMP_T_STR;
3509 smp->flags = SMP_F_CONST;
Emeric Brun589fcad2012-10-16 14:13:26 +02003510 smp->data.str.len = strlen(smp->data.str.str);
3511
3512 return 1;
3513}
3514
Emeric Brun645ae792014-04-30 14:21:06 +02003515/* binary, returns the SSL session id if front conn. transport layer is SSL.
3516 * This function is also usable on backend conn if the fetch keyword 5th
3517 * char is 'b'.
3518 */
Emeric Brun589fcad2012-10-16 14:13:26 +02003519static int
Emeric Brunfe68f682012-10-16 14:59:28 +02003520smp_fetch_ssl_fc_session_id(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003521 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brunfe68f682012-10-16 14:59:28 +02003522{
3523#if OPENSSL_VERSION_NUMBER > 0x0090800fL
Emeric Brun645ae792014-04-30 14:21:06 +02003524 int back_conn = (kw[4] == 'b') ? 1 : 0;
Emeric Brunfe68f682012-10-16 14:59:28 +02003525 SSL_SESSION *sess;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003526 struct connection *conn;
Emeric Brunfe68f682012-10-16 14:59:28 +02003527
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01003528 smp->flags = SMP_F_CONST;
3529 smp->type = SMP_T_BIN;
Emeric Brunfe68f682012-10-16 14:59:28 +02003530
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003531 if (!l4)
Emeric Brunfe68f682012-10-16 14:59:28 +02003532 return 0;
3533
Emeric Brun645ae792014-04-30 14:21:06 +02003534 conn = objt_conn(l4->si[back_conn].end);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003535 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
3536 return 0;
3537
3538 sess = SSL_get_session(conn->xprt_ctx);
Emeric Brunfe68f682012-10-16 14:59:28 +02003539 if (!sess)
3540 return 0;
3541
3542 smp->data.str.str = (char *)SSL_SESSION_get_id(sess, (unsigned int *)&smp->data.str.len);
3543 if (!smp->data.str.str || !&smp->data.str.len)
3544 return 0;
3545
3546 return 1;
3547#else
3548 return 0;
3549#endif
3550}
3551
3552static int
Emeric Brun2525b6b2012-10-18 15:59:43 +02003553smp_fetch_ssl_fc_sni(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003554 const struct arg *args, struct sample *smp, const char *kw)
Willy Tarreau7875d092012-09-10 08:20:03 +02003555{
3556#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003557 struct connection *conn;
3558
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01003559 smp->flags = SMP_F_CONST;
3560 smp->type = SMP_T_STR;
Willy Tarreau7875d092012-09-10 08:20:03 +02003561
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003562 if (!l4)
Willy Tarreau7875d092012-09-10 08:20:03 +02003563 return 0;
3564
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003565 conn = objt_conn(l4->si[0].end);
3566 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
3567 return 0;
3568
3569 smp->data.str.str = (char *)SSL_get_servername(conn->xprt_ctx, TLSEXT_NAMETYPE_host_name);
Willy Tarreau3e394c92012-09-14 23:56:58 +02003570 if (!smp->data.str.str)
3571 return 0;
3572
Willy Tarreau7875d092012-09-10 08:20:03 +02003573 smp->data.str.len = strlen(smp->data.str.str);
3574 return 1;
3575#else
3576 return 0;
3577#endif
3578}
3579
David Sc1ad52e2014-04-08 18:48:47 -04003580static int
3581smp_fetch_ssl_fc_unique_id(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
3582 const struct arg *args, struct sample *smp, const char *kw)
3583{
3584#if OPENSSL_VERSION_NUMBER > 0x0090800fL
Emeric Brun645ae792014-04-30 14:21:06 +02003585 int back_conn = (kw[4] == 'b') ? 1 : 0;
David Sc1ad52e2014-04-08 18:48:47 -04003586 struct connection *conn;
3587 int finished_len;
David Sc1ad52e2014-04-08 18:48:47 -04003588 struct chunk *finished_trash;
David Sc1ad52e2014-04-08 18:48:47 -04003589
3590 smp->flags = 0;
3591
3592 if (!l4)
3593 return 0;
3594
Emeric Brun645ae792014-04-30 14:21:06 +02003595 conn = objt_conn(l4->si[back_conn].end);
David Sc1ad52e2014-04-08 18:48:47 -04003596 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
3597 return 0;
3598
3599 if (!(conn->flags & CO_FL_CONNECTED)) {
3600 smp->flags |= SMP_F_MAY_CHANGE;
3601 return 0;
3602 }
3603
3604 finished_trash = get_trash_chunk();
3605 if (!SSL_session_reused(conn->xprt_ctx))
3606 finished_len = SSL_get_peer_finished(conn->xprt_ctx, finished_trash->str, finished_trash->size);
3607 else
3608 finished_len = SSL_get_finished(conn->xprt_ctx, finished_trash->str, finished_trash->size);
3609
3610 if (!finished_len)
3611 return 0;
3612
Emeric Brunb73a9b02014-04-30 18:49:19 +02003613 finished_trash->len = finished_len;
3614 smp->data.str = *finished_trash;
3615 smp->type = SMP_T_BIN;
David Sc1ad52e2014-04-08 18:48:47 -04003616
3617 return 1;
3618#else
3619 return 0;
3620#endif
3621}
3622
Emeric Brun2525b6b2012-10-18 15:59:43 +02003623/* integer, returns the first verify error in CA chain of client certificate chain. */
Emeric Brunf282a812012-09-21 15:27:54 +02003624static int
Emeric Brun2525b6b2012-10-18 15:59:43 +02003625smp_fetch_ssl_c_ca_err(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003626 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brunf282a812012-09-21 15:27:54 +02003627{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003628 struct connection *conn;
3629
3630 if (!l4)
Emeric Brunf282a812012-09-21 15:27:54 +02003631 return 0;
3632
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003633 conn = objt_conn(l4->si[0].end);
3634 if (!conn || conn->xprt != &ssl_sock)
3635 return 0;
3636
3637 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunf282a812012-09-21 15:27:54 +02003638 smp->flags = SMP_F_MAY_CHANGE;
3639 return 0;
3640 }
3641
3642 smp->type = SMP_T_UINT;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003643 smp->data.uint = (unsigned int)SSL_SOCK_ST_TO_CA_ERROR(conn->xprt_st);
Emeric Brunf282a812012-09-21 15:27:54 +02003644 smp->flags = 0;
3645
3646 return 1;
3647}
3648
Emeric Brun2525b6b2012-10-18 15:59:43 +02003649/* integer, returns the depth of the first verify error in CA chain of client certificate chain. */
Emeric Brunf282a812012-09-21 15:27:54 +02003650static int
Emeric Brun2525b6b2012-10-18 15:59:43 +02003651smp_fetch_ssl_c_ca_err_depth(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003652 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brunf282a812012-09-21 15:27:54 +02003653{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003654 struct connection *conn;
3655
3656 if (!l4)
3657 return 0;
3658
3659 conn = objt_conn(l4->si[0].end);
3660 if (!conn || conn->xprt != &ssl_sock)
Emeric Brunf282a812012-09-21 15:27:54 +02003661 return 0;
3662
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003663 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunf282a812012-09-21 15:27:54 +02003664 smp->flags = SMP_F_MAY_CHANGE;
3665 return 0;
3666 }
3667
3668 smp->type = SMP_T_UINT;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003669 smp->data.uint = (unsigned int)SSL_SOCK_ST_TO_CAEDEPTH(conn->xprt_st);
Emeric Brunf282a812012-09-21 15:27:54 +02003670 smp->flags = 0;
3671
3672 return 1;
3673}
3674
Emeric Brun2525b6b2012-10-18 15:59:43 +02003675/* integer, returns the first verify error on client certificate */
Emeric Brunf282a812012-09-21 15:27:54 +02003676static int
Emeric Brun2525b6b2012-10-18 15:59:43 +02003677smp_fetch_ssl_c_err(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003678 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brunf282a812012-09-21 15:27:54 +02003679{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003680 struct connection *conn;
3681
3682 if (!l4)
Emeric Brunf282a812012-09-21 15:27:54 +02003683 return 0;
3684
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003685 conn = objt_conn(l4->si[0].end);
3686 if (!conn || conn->xprt != &ssl_sock)
3687 return 0;
3688
3689 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunf282a812012-09-21 15:27:54 +02003690 smp->flags = SMP_F_MAY_CHANGE;
3691 return 0;
3692 }
3693
3694 smp->type = SMP_T_UINT;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003695 smp->data.uint = (unsigned int)SSL_SOCK_ST_TO_CRTERROR(conn->xprt_st);
Emeric Brunf282a812012-09-21 15:27:54 +02003696 smp->flags = 0;
3697
3698 return 1;
3699}
3700
Emeric Brun2525b6b2012-10-18 15:59:43 +02003701/* integer, returns the verify result on client cert */
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02003702static int
Emeric Brun2525b6b2012-10-18 15:59:43 +02003703smp_fetch_ssl_c_verify(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003704 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02003705{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003706 struct connection *conn;
3707
3708 if (!l4)
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02003709 return 0;
3710
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003711 conn = objt_conn(l4->si[0].end);
3712 if (!conn || conn->xprt != &ssl_sock)
3713 return 0;
3714
3715 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02003716 smp->flags = SMP_F_MAY_CHANGE;
3717 return 0;
3718 }
3719
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003720 if (!conn->xprt_ctx)
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02003721 return 0;
3722
3723 smp->type = SMP_T_UINT;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003724 smp->data.uint = (unsigned int)SSL_get_verify_result(conn->xprt_ctx);
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02003725 smp->flags = 0;
3726
3727 return 1;
3728}
3729
Emeric Brunfb510ea2012-10-05 12:00:26 +02003730/* parse the "ca-file" bind keyword */
3731static 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 +02003732{
3733 if (!*args[cur_arg + 1]) {
3734 if (err)
3735 memprintf(err, "'%s' : missing CAfile path", args[cur_arg]);
3736 return ERR_ALERT | ERR_FATAL;
3737 }
3738
Emeric Brunef42d922012-10-11 16:11:36 +02003739 if ((*args[cur_arg + 1] != '/') && global.ca_base)
3740 memprintf(&conf->ca_file, "%s/%s", global.ca_base, args[cur_arg + 1]);
3741 else
3742 memprintf(&conf->ca_file, "%s", args[cur_arg + 1]);
Emeric Brunc8e8d122012-10-02 18:42:10 +02003743
Emeric Brund94b3fe2012-09-20 18:23:56 +02003744 return 0;
3745}
3746
Willy Tarreau79eeafa2012-09-14 07:53:05 +02003747/* parse the "ciphers" bind keyword */
Willy Tarreau4348fad2012-09-20 16:48:07 +02003748static 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 +02003749{
3750 if (!*args[cur_arg + 1]) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02003751 memprintf(err, "'%s' : missing cipher suite", args[cur_arg]);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02003752 return ERR_ALERT | ERR_FATAL;
3753 }
3754
Emeric Brun76d88952012-10-05 15:47:31 +02003755 free(conf->ciphers);
Willy Tarreau4348fad2012-09-20 16:48:07 +02003756 conf->ciphers = strdup(args[cur_arg + 1]);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02003757 return 0;
3758}
3759
3760/* parse the "crt" bind keyword */
Willy Tarreau4348fad2012-09-20 16:48:07 +02003761static 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 +02003762{
Willy Tarreau38011032013-08-13 16:59:39 +02003763 char path[MAXPATHLEN];
Willy Tarreaub75d6922014-04-14 18:05:41 +02003764
Willy Tarreau79eeafa2012-09-14 07:53:05 +02003765 if (!*args[cur_arg + 1]) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02003766 memprintf(err, "'%s' : missing certificate location", args[cur_arg]);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02003767 return ERR_ALERT | ERR_FATAL;
3768 }
3769
Emeric Brunc8e8d122012-10-02 18:42:10 +02003770 if ((*args[cur_arg + 1] != '/' ) && global.crt_base) {
Willy Tarreau38011032013-08-13 16:59:39 +02003771 if ((strlen(global.crt_base) + 1 + strlen(args[cur_arg + 1]) + 1) > MAXPATHLEN) {
Emeric Brunc8e8d122012-10-02 18:42:10 +02003772 memprintf(err, "'%s' : path too long", args[cur_arg]);
3773 return ERR_ALERT | ERR_FATAL;
3774 }
Willy Tarreaub75d6922014-04-14 18:05:41 +02003775 snprintf(path, sizeof(path), "%s/%s", global.crt_base, args[cur_arg + 1]);
Emeric Brunc8e8d122012-10-02 18:42:10 +02003776 if (ssl_sock_load_cert(path, conf, px, err) > 0)
3777 return ERR_ALERT | ERR_FATAL;
3778
3779 return 0;
3780 }
3781
Willy Tarreau4348fad2012-09-20 16:48:07 +02003782 if (ssl_sock_load_cert(args[cur_arg + 1], conf, px, err) > 0)
Willy Tarreau79eeafa2012-09-14 07:53:05 +02003783 return ERR_ALERT | ERR_FATAL;
Emeric Brund94b3fe2012-09-20 18:23:56 +02003784
3785 return 0;
3786}
3787
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01003788/* parse the "crt-list" bind keyword */
3789static int bind_parse_crt_list(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
3790{
3791 if (!*args[cur_arg + 1]) {
3792 memprintf(err, "'%s' : missing certificate location", args[cur_arg]);
3793 return ERR_ALERT | ERR_FATAL;
3794 }
3795
Willy Tarreauad1731d2013-04-02 17:35:58 +02003796 if (ssl_sock_load_cert_list_file(args[cur_arg + 1], conf, px, err) > 0) {
3797 memprintf(err, "'%s' : %s", args[cur_arg], *err);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01003798 return ERR_ALERT | ERR_FATAL;
Willy Tarreauad1731d2013-04-02 17:35:58 +02003799 }
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01003800
3801 return 0;
3802}
3803
Emeric Brunfb510ea2012-10-05 12:00:26 +02003804/* parse the "crl-file" bind keyword */
3805static 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 +02003806{
Emeric Brun051cdab2012-10-02 19:25:50 +02003807#ifndef X509_V_FLAG_CRL_CHECK
3808 if (err)
3809 memprintf(err, "'%s' : library does not support CRL verify", args[cur_arg]);
3810 return ERR_ALERT | ERR_FATAL;
3811#else
Emeric Brund94b3fe2012-09-20 18:23:56 +02003812 if (!*args[cur_arg + 1]) {
3813 if (err)
3814 memprintf(err, "'%s' : missing CRLfile path", args[cur_arg]);
3815 return ERR_ALERT | ERR_FATAL;
3816 }
Emeric Brun2b58d042012-09-20 17:10:03 +02003817
Emeric Brunef42d922012-10-11 16:11:36 +02003818 if ((*args[cur_arg + 1] != '/') && global.ca_base)
3819 memprintf(&conf->crl_file, "%s/%s", global.ca_base, args[cur_arg + 1]);
3820 else
3821 memprintf(&conf->crl_file, "%s", args[cur_arg + 1]);
Emeric Brunc8e8d122012-10-02 18:42:10 +02003822
Emeric Brun2b58d042012-09-20 17:10:03 +02003823 return 0;
Emeric Brun051cdab2012-10-02 19:25:50 +02003824#endif
Emeric Brun2b58d042012-09-20 17:10:03 +02003825}
3826
3827/* parse the "ecdhe" bind keyword keywords */
3828static int bind_parse_ecdhe(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
3829{
3830#if OPENSSL_VERSION_NUMBER < 0x0090800fL
3831 if (err)
3832 memprintf(err, "'%s' : library does not support elliptic curve Diffie-Hellman (too old)", args[cur_arg]);
3833 return ERR_ALERT | ERR_FATAL;
3834#elif defined(OPENSSL_NO_ECDH)
3835 if (err)
3836 memprintf(err, "'%s' : library does not support elliptic curve Diffie-Hellman (disabled via OPENSSL_NO_ECDH)", args[cur_arg]);
3837 return ERR_ALERT | ERR_FATAL;
3838#else
3839 if (!*args[cur_arg + 1]) {
3840 if (err)
3841 memprintf(err, "'%s' : missing named curve", args[cur_arg]);
3842 return ERR_ALERT | ERR_FATAL;
3843 }
3844
3845 conf->ecdhe = strdup(args[cur_arg + 1]);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02003846
3847 return 0;
Emeric Brun2b58d042012-09-20 17:10:03 +02003848#endif
Willy Tarreau79eeafa2012-09-14 07:53:05 +02003849}
3850
Emeric Brun81c00f02012-09-21 14:31:21 +02003851/* parse the "crt_ignerr" and "ca_ignerr" bind keywords */
3852static int bind_parse_ignore_err(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
3853{
3854 int code;
3855 char *p = args[cur_arg + 1];
3856 unsigned long long *ignerr = &conf->crt_ignerr;
3857
3858 if (!*p) {
3859 if (err)
3860 memprintf(err, "'%s' : missing error IDs list", args[cur_arg]);
3861 return ERR_ALERT | ERR_FATAL;
3862 }
3863
3864 if (strcmp(args[cur_arg], "ca-ignore-err") == 0)
3865 ignerr = &conf->ca_ignerr;
3866
3867 if (strcmp(p, "all") == 0) {
3868 *ignerr = ~0ULL;
3869 return 0;
3870 }
3871
3872 while (p) {
3873 code = atoi(p);
3874 if ((code <= 0) || (code > 63)) {
3875 if (err)
3876 memprintf(err, "'%s' : ID '%d' out of range (1..63) in error IDs list '%s'",
3877 args[cur_arg], code, args[cur_arg + 1]);
3878 return ERR_ALERT | ERR_FATAL;
3879 }
3880 *ignerr |= 1ULL << code;
3881 p = strchr(p, ',');
3882 if (p)
3883 p++;
3884 }
3885
Emeric Brun2cb7ae52012-10-05 14:14:21 +02003886 return 0;
3887}
3888
3889/* parse the "force-sslv3" bind keyword */
3890static int bind_parse_force_sslv3(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
3891{
3892 conf->ssl_options |= BC_SSL_O_USE_SSLV3;
3893 return 0;
3894}
3895
3896/* parse the "force-tlsv10" bind keyword */
3897static int bind_parse_force_tlsv10(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
3898{
3899 conf->ssl_options |= BC_SSL_O_USE_TLSV10;
Emeric Brun2d0c4822012-10-02 13:45:20 +02003900 return 0;
3901}
3902
Emeric Brun2cb7ae52012-10-05 14:14:21 +02003903/* parse the "force-tlsv11" bind keyword */
3904static int bind_parse_force_tlsv11(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
3905{
3906#if SSL_OP_NO_TLSv1_1
3907 conf->ssl_options |= BC_SSL_O_USE_TLSV11;
3908 return 0;
3909#else
3910 if (err)
3911 memprintf(err, "'%s' : library does not support protocol TLSv1.1", args[cur_arg]);
3912 return ERR_ALERT | ERR_FATAL;
3913#endif
3914}
3915
3916/* parse the "force-tlsv12" bind keyword */
3917static int bind_parse_force_tlsv12(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
3918{
3919#if SSL_OP_NO_TLSv1_2
3920 conf->ssl_options |= BC_SSL_O_USE_TLSV12;
3921 return 0;
3922#else
3923 if (err)
3924 memprintf(err, "'%s' : library does not support protocol TLSv1.2", args[cur_arg]);
3925 return ERR_ALERT | ERR_FATAL;
3926#endif
3927}
3928
3929
Emeric Brun2d0c4822012-10-02 13:45:20 +02003930/* parse the "no-tls-tickets" bind keyword */
3931static int bind_parse_no_tls_tickets(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
3932{
Emeric Brun89675492012-10-05 13:48:26 +02003933 conf->ssl_options |= BC_SSL_O_NO_TLS_TICKETS;
Emeric Brun81c00f02012-09-21 14:31:21 +02003934 return 0;
3935}
3936
Emeric Brun2d0c4822012-10-02 13:45:20 +02003937
Emeric Brun9b3009b2012-10-05 11:55:06 +02003938/* parse the "no-sslv3" bind keyword */
3939static 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 +02003940{
Emeric Brun89675492012-10-05 13:48:26 +02003941 conf->ssl_options |= BC_SSL_O_NO_SSLV3;
Willy Tarreau79eeafa2012-09-14 07:53:05 +02003942 return 0;
3943}
3944
Emeric Brun9b3009b2012-10-05 11:55:06 +02003945/* parse the "no-tlsv10" bind keyword */
3946static 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 +02003947{
Emeric Brun89675492012-10-05 13:48:26 +02003948 conf->ssl_options |= BC_SSL_O_NO_TLSV10;
Emeric Brunc0ff4922012-09-28 19:37:02 +02003949 return 0;
3950}
3951
Emeric Brun9b3009b2012-10-05 11:55:06 +02003952/* parse the "no-tlsv11" bind keyword */
3953static 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 +02003954{
Emeric Brun89675492012-10-05 13:48:26 +02003955 conf->ssl_options |= BC_SSL_O_NO_TLSV11;
Emeric Brunc0ff4922012-09-28 19:37:02 +02003956 return 0;
3957}
3958
Emeric Brun9b3009b2012-10-05 11:55:06 +02003959/* parse the "no-tlsv12" bind keyword */
3960static 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 +02003961{
Emeric Brun89675492012-10-05 13:48:26 +02003962 conf->ssl_options |= BC_SSL_O_NO_TLSV12;
Willy Tarreau79eeafa2012-09-14 07:53:05 +02003963 return 0;
3964}
3965
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02003966/* parse the "npn" bind keyword */
3967static int bind_parse_npn(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
3968{
3969#ifdef OPENSSL_NPN_NEGOTIATED
3970 char *p1, *p2;
3971
3972 if (!*args[cur_arg + 1]) {
3973 memprintf(err, "'%s' : missing the comma-delimited NPN protocol suite", args[cur_arg]);
3974 return ERR_ALERT | ERR_FATAL;
3975 }
3976
3977 free(conf->npn_str);
3978
3979 /* the NPN string is built as a suite of (<len> <name>)* */
3980 conf->npn_len = strlen(args[cur_arg + 1]) + 1;
3981 conf->npn_str = calloc(1, conf->npn_len);
3982 memcpy(conf->npn_str + 1, args[cur_arg + 1], conf->npn_len);
3983
3984 /* replace commas with the name length */
3985 p1 = conf->npn_str;
3986 p2 = p1 + 1;
3987 while (1) {
3988 p2 = memchr(p1 + 1, ',', conf->npn_str + conf->npn_len - (p1 + 1));
3989 if (!p2)
3990 p2 = p1 + 1 + strlen(p1 + 1);
3991
3992 if (p2 - (p1 + 1) > 255) {
3993 *p2 = '\0';
3994 memprintf(err, "'%s' : NPN protocol name too long : '%s'", args[cur_arg], p1 + 1);
3995 return ERR_ALERT | ERR_FATAL;
3996 }
3997
3998 *p1 = p2 - (p1 + 1);
3999 p1 = p2;
4000
4001 if (!*p2)
4002 break;
4003
4004 *(p2++) = '\0';
4005 }
4006 return 0;
4007#else
4008 if (err)
4009 memprintf(err, "'%s' : library does not support TLS NPN extension", args[cur_arg]);
4010 return ERR_ALERT | ERR_FATAL;
4011#endif
4012}
4013
Willy Tarreauab861d32013-04-02 02:30:41 +02004014/* parse the "alpn" bind keyword */
4015static int bind_parse_alpn(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
4016{
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01004017#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Willy Tarreauab861d32013-04-02 02:30:41 +02004018 char *p1, *p2;
4019
4020 if (!*args[cur_arg + 1]) {
4021 memprintf(err, "'%s' : missing the comma-delimited ALPN protocol suite", args[cur_arg]);
4022 return ERR_ALERT | ERR_FATAL;
4023 }
4024
4025 free(conf->alpn_str);
4026
4027 /* the ALPN string is built as a suite of (<len> <name>)* */
4028 conf->alpn_len = strlen(args[cur_arg + 1]) + 1;
4029 conf->alpn_str = calloc(1, conf->alpn_len);
4030 memcpy(conf->alpn_str + 1, args[cur_arg + 1], conf->alpn_len);
4031
4032 /* replace commas with the name length */
4033 p1 = conf->alpn_str;
4034 p2 = p1 + 1;
4035 while (1) {
4036 p2 = memchr(p1 + 1, ',', conf->alpn_str + conf->alpn_len - (p1 + 1));
4037 if (!p2)
4038 p2 = p1 + 1 + strlen(p1 + 1);
4039
4040 if (p2 - (p1 + 1) > 255) {
4041 *p2 = '\0';
4042 memprintf(err, "'%s' : ALPN protocol name too long : '%s'", args[cur_arg], p1 + 1);
4043 return ERR_ALERT | ERR_FATAL;
4044 }
4045
4046 *p1 = p2 - (p1 + 1);
4047 p1 = p2;
4048
4049 if (!*p2)
4050 break;
4051
4052 *(p2++) = '\0';
4053 }
4054 return 0;
4055#else
4056 if (err)
4057 memprintf(err, "'%s' : library does not support TLS ALPN extension", args[cur_arg]);
4058 return ERR_ALERT | ERR_FATAL;
4059#endif
4060}
4061
Willy Tarreau79eeafa2012-09-14 07:53:05 +02004062/* parse the "ssl" bind keyword */
Willy Tarreau4348fad2012-09-20 16:48:07 +02004063static 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 +02004064{
Willy Tarreau81796be2012-09-22 19:11:47 +02004065 struct listener *l;
4066
Willy Tarreau4348fad2012-09-20 16:48:07 +02004067 conf->is_ssl = 1;
Emeric Brun76d88952012-10-05 15:47:31 +02004068
4069 if (global.listen_default_ciphers && !conf->ciphers)
4070 conf->ciphers = strdup(global.listen_default_ciphers);
Emeric Brun42a3e202014-10-30 15:56:50 +01004071 conf->ssl_options |= global.listen_default_ssloptions;
Emeric Brun76d88952012-10-05 15:47:31 +02004072
Willy Tarreau81796be2012-09-22 19:11:47 +02004073 list_for_each_entry(l, &conf->listeners, by_bind)
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02004074 l->xprt = &ssl_sock;
Willy Tarreau81796be2012-09-22 19:11:47 +02004075
Willy Tarreau79eeafa2012-09-14 07:53:05 +02004076 return 0;
4077}
4078
Emmanuel Hocdet65623372013-01-24 17:17:15 +01004079/* parse the "strict-sni" bind keyword */
4080static int bind_parse_strict_sni(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
4081{
4082 conf->strict_sni = 1;
4083 return 0;
4084}
4085
Emeric Brund94b3fe2012-09-20 18:23:56 +02004086/* parse the "verify" bind keyword */
4087static int bind_parse_verify(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
4088{
4089 if (!*args[cur_arg + 1]) {
4090 if (err)
4091 memprintf(err, "'%s' : missing verify method", args[cur_arg]);
4092 return ERR_ALERT | ERR_FATAL;
4093 }
4094
4095 if (strcmp(args[cur_arg + 1], "none") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01004096 conf->verify = SSL_SOCK_VERIFY_NONE;
Emeric Brund94b3fe2012-09-20 18:23:56 +02004097 else if (strcmp(args[cur_arg + 1], "optional") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01004098 conf->verify = SSL_SOCK_VERIFY_OPTIONAL;
Emeric Brund94b3fe2012-09-20 18:23:56 +02004099 else if (strcmp(args[cur_arg + 1], "required") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01004100 conf->verify = SSL_SOCK_VERIFY_REQUIRED;
Emeric Brund94b3fe2012-09-20 18:23:56 +02004101 else {
4102 if (err)
4103 memprintf(err, "'%s' : unknown verify method '%s', only 'none', 'optional', and 'required' are supported\n",
4104 args[cur_arg], args[cur_arg + 1]);
4105 return ERR_ALERT | ERR_FATAL;
4106 }
4107
4108 return 0;
4109}
4110
Willy Tarreau92faadf2012-10-10 23:04:25 +02004111/************** "server" keywords ****************/
4112
Emeric Brunef42d922012-10-11 16:11:36 +02004113/* parse the "ca-file" server keyword */
4114static int srv_parse_ca_file(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4115{
4116 if (!*args[*cur_arg + 1]) {
4117 if (err)
4118 memprintf(err, "'%s' : missing CAfile path", args[*cur_arg]);
4119 return ERR_ALERT | ERR_FATAL;
4120 }
4121
4122 if ((*args[*cur_arg + 1] != '/') && global.ca_base)
4123 memprintf(&newsrv->ssl_ctx.ca_file, "%s/%s", global.ca_base, args[*cur_arg + 1]);
4124 else
4125 memprintf(&newsrv->ssl_ctx.ca_file, "%s", args[*cur_arg + 1]);
4126
4127 return 0;
4128}
4129
Willy Tarreau92faadf2012-10-10 23:04:25 +02004130/* parse the "check-ssl" server keyword */
4131static int srv_parse_check_ssl(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4132{
4133 newsrv->check.use_ssl = 1;
4134 if (global.connect_default_ciphers && !newsrv->ssl_ctx.ciphers)
4135 newsrv->ssl_ctx.ciphers = strdup(global.connect_default_ciphers);
Emeric Brun42a3e202014-10-30 15:56:50 +01004136 newsrv->ssl_ctx.options |= global.connect_default_ssloptions;
Willy Tarreau92faadf2012-10-10 23:04:25 +02004137 return 0;
4138}
4139
4140/* parse the "ciphers" server keyword */
4141static int srv_parse_ciphers(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4142{
4143 if (!*args[*cur_arg + 1]) {
4144 memprintf(err, "'%s' : missing cipher suite", args[*cur_arg]);
4145 return ERR_ALERT | ERR_FATAL;
4146 }
4147
4148 free(newsrv->ssl_ctx.ciphers);
4149 newsrv->ssl_ctx.ciphers = strdup(args[*cur_arg + 1]);
4150 return 0;
4151}
4152
Emeric Brunef42d922012-10-11 16:11:36 +02004153/* parse the "crl-file" server keyword */
4154static int srv_parse_crl_file(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4155{
4156#ifndef X509_V_FLAG_CRL_CHECK
4157 if (err)
4158 memprintf(err, "'%s' : library does not support CRL verify", args[*cur_arg]);
4159 return ERR_ALERT | ERR_FATAL;
4160#else
4161 if (!*args[*cur_arg + 1]) {
4162 if (err)
4163 memprintf(err, "'%s' : missing CRLfile path", args[*cur_arg]);
4164 return ERR_ALERT | ERR_FATAL;
4165 }
4166
4167 if ((*args[*cur_arg + 1] != '/') && global.ca_base)
4168 memprintf(&newsrv->ssl_ctx.crl_file, "%s/%s", global.ca_base, args[*cur_arg + 1]);
4169 else
4170 memprintf(&newsrv->ssl_ctx.crl_file, "%s", args[*cur_arg + 1]);
4171
4172 return 0;
4173#endif
4174}
4175
Emeric Bruna7aa3092012-10-26 12:58:00 +02004176/* parse the "crt" server keyword */
4177static int srv_parse_crt(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4178{
4179 if (!*args[*cur_arg + 1]) {
4180 if (err)
4181 memprintf(err, "'%s' : missing certificate file path", args[*cur_arg]);
4182 return ERR_ALERT | ERR_FATAL;
4183 }
4184
4185 if ((*args[*cur_arg + 1] != '/') && global.crt_base)
4186 memprintf(&newsrv->ssl_ctx.client_crt, "%s/%s", global.ca_base, args[*cur_arg + 1]);
4187 else
4188 memprintf(&newsrv->ssl_ctx.client_crt, "%s", args[*cur_arg + 1]);
4189
4190 return 0;
4191}
Emeric Brunef42d922012-10-11 16:11:36 +02004192
Willy Tarreau92faadf2012-10-10 23:04:25 +02004193/* parse the "force-sslv3" server keyword */
4194static int srv_parse_force_sslv3(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4195{
4196 newsrv->ssl_ctx.options |= SRV_SSL_O_USE_SSLV3;
4197 return 0;
4198}
4199
4200/* parse the "force-tlsv10" server keyword */
4201static int srv_parse_force_tlsv10(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4202{
4203 newsrv->ssl_ctx.options |= SRV_SSL_O_USE_TLSV10;
4204 return 0;
4205}
4206
4207/* parse the "force-tlsv11" server keyword */
4208static int srv_parse_force_tlsv11(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4209{
4210#if SSL_OP_NO_TLSv1_1
4211 newsrv->ssl_ctx.options |= SRV_SSL_O_USE_TLSV11;
4212 return 0;
4213#else
4214 if (err)
4215 memprintf(err, "'%s' : library does not support protocol TLSv1.1", args[*cur_arg]);
4216 return ERR_ALERT | ERR_FATAL;
4217#endif
4218}
4219
4220/* parse the "force-tlsv12" server keyword */
4221static int srv_parse_force_tlsv12(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4222{
4223#if SSL_OP_NO_TLSv1_2
4224 newsrv->ssl_ctx.options |= SRV_SSL_O_USE_TLSV12;
4225 return 0;
4226#else
4227 if (err)
4228 memprintf(err, "'%s' : library does not support protocol TLSv1.2", args[*cur_arg]);
4229 return ERR_ALERT | ERR_FATAL;
4230#endif
4231}
4232
4233/* parse the "no-sslv3" server keyword */
4234static int srv_parse_no_sslv3(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4235{
4236 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_SSLV3;
4237 return 0;
4238}
4239
4240/* parse the "no-tlsv10" server keyword */
4241static int srv_parse_no_tlsv10(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4242{
4243 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_TLSV10;
4244 return 0;
4245}
4246
4247/* parse the "no-tlsv11" server keyword */
4248static int srv_parse_no_tlsv11(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4249{
4250 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_TLSV11;
4251 return 0;
4252}
4253
4254/* parse the "no-tlsv12" server keyword */
4255static int srv_parse_no_tlsv12(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4256{
4257 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_TLSV12;
4258 return 0;
4259}
4260
Emeric Brunf9c5c472012-10-11 15:28:34 +02004261/* parse the "no-tls-tickets" server keyword */
4262static int srv_parse_no_tls_tickets(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4263{
4264 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_TLS_TICKETS;
4265 return 0;
4266}
David Safb76832014-05-08 23:42:08 -04004267/* parse the "send-proxy-v2-ssl" server keyword */
4268static int srv_parse_send_proxy_ssl(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4269{
4270 newsrv->pp_opts |= SRV_PP_V2;
4271 newsrv->pp_opts |= SRV_PP_V2_SSL;
4272 return 0;
4273}
4274
4275/* parse the "send-proxy-v2-ssl-cn" server keyword */
4276static int srv_parse_send_proxy_cn(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4277{
4278 newsrv->pp_opts |= SRV_PP_V2;
4279 newsrv->pp_opts |= SRV_PP_V2_SSL;
4280 newsrv->pp_opts |= SRV_PP_V2_SSL_CN;
4281 return 0;
4282}
Emeric Brunf9c5c472012-10-11 15:28:34 +02004283
Willy Tarreau92faadf2012-10-10 23:04:25 +02004284/* parse the "ssl" server keyword */
4285static int srv_parse_ssl(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4286{
4287 newsrv->use_ssl = 1;
4288 if (global.connect_default_ciphers && !newsrv->ssl_ctx.ciphers)
4289 newsrv->ssl_ctx.ciphers = strdup(global.connect_default_ciphers);
4290 return 0;
4291}
4292
Emeric Brunef42d922012-10-11 16:11:36 +02004293/* parse the "verify" server keyword */
4294static int srv_parse_verify(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4295{
4296 if (!*args[*cur_arg + 1]) {
4297 if (err)
4298 memprintf(err, "'%s' : missing verify method", args[*cur_arg]);
4299 return ERR_ALERT | ERR_FATAL;
4300 }
4301
4302 if (strcmp(args[*cur_arg + 1], "none") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01004303 newsrv->ssl_ctx.verify = SSL_SOCK_VERIFY_NONE;
Emeric Brunef42d922012-10-11 16:11:36 +02004304 else if (strcmp(args[*cur_arg + 1], "required") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01004305 newsrv->ssl_ctx.verify = SSL_SOCK_VERIFY_REQUIRED;
Emeric Brunef42d922012-10-11 16:11:36 +02004306 else {
4307 if (err)
4308 memprintf(err, "'%s' : unknown verify method '%s', only 'none' and 'required' are supported\n",
4309 args[*cur_arg], args[*cur_arg + 1]);
4310 return ERR_ALERT | ERR_FATAL;
4311 }
4312
Evan Broderbe554312013-06-27 00:05:25 -07004313 return 0;
4314}
4315
4316/* parse the "verifyhost" server keyword */
4317static int srv_parse_verifyhost(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4318{
4319 if (!*args[*cur_arg + 1]) {
4320 if (err)
4321 memprintf(err, "'%s' : missing hostname to verify against", args[*cur_arg]);
4322 return ERR_ALERT | ERR_FATAL;
4323 }
4324
4325 newsrv->ssl_ctx.verify_host = strdup(args[*cur_arg + 1]);
4326
Emeric Brunef42d922012-10-11 16:11:36 +02004327 return 0;
4328}
4329
Emeric Brun42a3e202014-10-30 15:56:50 +01004330/* parse the "ssl-default-bind-options" keyword in global section */
4331static int ssl_parse_default_bind_options(char **args, int section_type, struct proxy *curpx,
4332 struct proxy *defpx, const char *file, int line,
4333 char **err) {
4334 int i = 1;
4335
4336 if (*(args[i]) == 0) {
4337 memprintf(err, "global statement '%s' expects an option as an argument.", args[0]);
4338 return -1;
4339 }
4340 while (*(args[i])) {
4341 if (!strcmp(args[i], "no-sslv3"))
4342 global.listen_default_ssloptions |= BC_SSL_O_NO_SSLV3;
4343 else if (!strcmp(args[i], "no-tlsv10"))
4344 global.listen_default_ssloptions |= BC_SSL_O_NO_TLSV10;
4345 else if (!strcmp(args[i], "no-tlsv11"))
4346 global.listen_default_ssloptions |= BC_SSL_O_NO_TLSV11;
4347 else if (!strcmp(args[i], "no-tlsv12"))
4348 global.listen_default_ssloptions |= BC_SSL_O_NO_TLSV12;
4349 else if (!strcmp(args[i], "force-sslv3"))
4350 global.listen_default_ssloptions |= BC_SSL_O_USE_SSLV3;
4351 else if (!strcmp(args[i], "force-tlsv10"))
4352 global.listen_default_ssloptions |= BC_SSL_O_USE_TLSV10;
4353 else if (!strcmp(args[i], "force-tlsv11")) {
4354#if SSL_OP_NO_TLSv1_1
4355 global.listen_default_ssloptions |= BC_SSL_O_USE_TLSV11;
4356#else
4357 memprintf(err, "'%s' '%s': library does not support protocol TLSv1.1", args[0], args[i]);
4358 return -1;
4359#endif
4360 }
4361 else if (!strcmp(args[i], "force-tlsv12")) {
4362#if SSL_OP_NO_TLSv1_2
4363 global.listen_default_ssloptions |= BC_SSL_O_USE_TLSV12;
4364#else
4365 memprintf(err, "'%s' '%s': library does not support protocol TLSv1.2", args[0], args[i]);
4366 return -1;
4367#endif
4368 }
4369 else if (!strcmp(args[i], "no-tls-tickets"))
4370 global.listen_default_ssloptions |= BC_SSL_O_NO_TLS_TICKETS;
4371 else {
4372 memprintf(err, "unknown option '%s' on global statement '%s'.", args[i], args[0]);
4373 return -1;
4374 }
4375 i++;
4376 }
4377 return 0;
4378}
4379
4380/* parse the "ssl-default-server-options" keyword in global section */
4381static int ssl_parse_default_server_options(char **args, int section_type, struct proxy *curpx,
4382 struct proxy *defpx, const char *file, int line,
4383 char **err) {
4384 int i = 1;
4385
4386 if (*(args[i]) == 0) {
4387 memprintf(err, "global statement '%s' expects an option as an argument.", args[0]);
4388 return -1;
4389 }
4390 while (*(args[i])) {
4391 if (!strcmp(args[i], "no-sslv3"))
4392 global.connect_default_ssloptions |= SRV_SSL_O_NO_SSLV3;
4393 else if (!strcmp(args[i], "no-tlsv10"))
4394 global.connect_default_ssloptions |= SRV_SSL_O_NO_TLSV10;
4395 else if (!strcmp(args[i], "no-tlsv11"))
4396 global.connect_default_ssloptions |= SRV_SSL_O_NO_TLSV11;
4397 else if (!strcmp(args[i], "no-tlsv12"))
4398 global.connect_default_ssloptions |= SRV_SSL_O_NO_TLSV12;
4399 else if (!strcmp(args[i], "force-sslv3"))
4400 global.connect_default_ssloptions |= SRV_SSL_O_USE_SSLV3;
4401 else if (!strcmp(args[i], "force-tlsv10"))
4402 global.connect_default_ssloptions |= SRV_SSL_O_USE_TLSV10;
4403 else if (!strcmp(args[i], "force-tlsv11")) {
4404#if SSL_OP_NO_TLSv1_1
4405 global.connect_default_ssloptions |= SRV_SSL_O_USE_TLSV11;
4406#else
4407 memprintf(err, "'%s' '%s': library does not support protocol TLSv1.1", args[0], args[i]);
4408 return -1;
4409#endif
4410 }
4411 else if (!strcmp(args[i], "force-tlsv12")) {
4412#if SSL_OP_NO_TLSv1_2
4413 global.connect_default_ssloptions |= SRV_SSL_O_USE_TLSV12;
4414#else
4415 memprintf(err, "'%s' '%s': library does not support protocol TLSv1.2", args[0], args[i]);
4416 return -1;
4417#endif
4418 }
4419 else if (!strcmp(args[i], "no-tls-tickets"))
4420 global.connect_default_ssloptions |= SRV_SSL_O_NO_TLS_TICKETS;
4421 else {
4422 memprintf(err, "unknown option '%s' on global statement '%s'.", args[i], args[0]);
4423 return -1;
4424 }
4425 i++;
4426 }
4427 return 0;
4428}
4429
Willy Tarreau7875d092012-09-10 08:20:03 +02004430/* Note: must not be declared <const> as its list will be overwritten.
4431 * Please take care of keeping this list alphabetically sorted.
4432 */
Willy Tarreaudc13c112013-06-21 23:16:39 +02004433static struct sample_fetch_kw_list sample_fetch_keywords = {ILH, {
Emeric Brun645ae792014-04-30 14:21:06 +02004434 { "ssl_bc", smp_fetch_ssl_fc, 0, NULL, SMP_T_BOOL, SMP_USE_L5SRV },
4435 { "ssl_bc_alg_keysize", smp_fetch_ssl_fc_alg_keysize, 0, NULL, SMP_T_UINT, SMP_USE_L5SRV },
4436 { "ssl_bc_cipher", smp_fetch_ssl_fc_cipher, 0, NULL, SMP_T_STR, SMP_USE_L5SRV },
4437 { "ssl_bc_protocol", smp_fetch_ssl_fc_protocol, 0, NULL, SMP_T_STR, SMP_USE_L5SRV },
Emeric Brunb73a9b02014-04-30 18:49:19 +02004438 { "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 +02004439 { "ssl_bc_use_keysize", smp_fetch_ssl_fc_use_keysize, 0, NULL, SMP_T_UINT, SMP_USE_L5SRV },
4440 { "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 +01004441 { "ssl_c_ca_err", smp_fetch_ssl_c_ca_err, 0, NULL, SMP_T_UINT, SMP_USE_L5CLI },
4442 { "ssl_c_ca_err_depth", smp_fetch_ssl_c_ca_err_depth, 0, NULL, SMP_T_UINT, SMP_USE_L5CLI },
Emeric Brunb3cc4252014-10-29 19:03:26 +01004443 { "ssl_c_der", smp_fetch_ssl_x_der, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Willy Tarreau80aca902013-01-07 15:42:20 +01004444 { "ssl_c_err", smp_fetch_ssl_c_err, 0, NULL, SMP_T_UINT, SMP_USE_L5CLI },
Emeric Brunba841a12014-04-30 17:05:08 +02004445 { "ssl_c_i_dn", smp_fetch_ssl_x_i_dn, ARG2(0,STR,SINT), NULL, SMP_T_STR, SMP_USE_L5CLI },
4446 { "ssl_c_key_alg", smp_fetch_ssl_x_key_alg, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
4447 { "ssl_c_notafter", smp_fetch_ssl_x_notafter, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
4448 { "ssl_c_notbefore", smp_fetch_ssl_x_notbefore, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
4449 { "ssl_c_sig_alg", smp_fetch_ssl_x_sig_alg, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
4450 { "ssl_c_s_dn", smp_fetch_ssl_x_s_dn, ARG2(0,STR,SINT), NULL, SMP_T_STR, SMP_USE_L5CLI },
4451 { "ssl_c_serial", smp_fetch_ssl_x_serial, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
4452 { "ssl_c_sha1", smp_fetch_ssl_x_sha1, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Willy Tarreau80aca902013-01-07 15:42:20 +01004453 { "ssl_c_used", smp_fetch_ssl_c_used, 0, NULL, SMP_T_BOOL, SMP_USE_L5CLI },
4454 { "ssl_c_verify", smp_fetch_ssl_c_verify, 0, NULL, SMP_T_UINT, SMP_USE_L5CLI },
Emeric Brunba841a12014-04-30 17:05:08 +02004455 { "ssl_c_version", smp_fetch_ssl_x_version, 0, NULL, SMP_T_UINT, SMP_USE_L5CLI },
Emeric Brunb3cc4252014-10-29 19:03:26 +01004456 { "ssl_f_der", smp_fetch_ssl_x_der, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Emeric Brunba841a12014-04-30 17:05:08 +02004457 { "ssl_f_i_dn", smp_fetch_ssl_x_i_dn, ARG2(0,STR,SINT), NULL, SMP_T_STR, SMP_USE_L5CLI },
4458 { "ssl_f_key_alg", smp_fetch_ssl_x_key_alg, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
4459 { "ssl_f_notafter", smp_fetch_ssl_x_notafter, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
4460 { "ssl_f_notbefore", smp_fetch_ssl_x_notbefore, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
4461 { "ssl_f_sig_alg", smp_fetch_ssl_x_sig_alg, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
4462 { "ssl_f_s_dn", smp_fetch_ssl_x_s_dn, ARG2(0,STR,SINT), NULL, SMP_T_STR, SMP_USE_L5CLI },
4463 { "ssl_f_serial", smp_fetch_ssl_x_serial, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Emeric Brun55f4fa82014-04-30 17:11:25 +02004464 { "ssl_f_sha1", smp_fetch_ssl_x_sha1, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Emeric Brunba841a12014-04-30 17:05:08 +02004465 { "ssl_f_version", smp_fetch_ssl_x_version, 0, NULL, SMP_T_UINT, SMP_USE_L5CLI },
Willy Tarreau80aca902013-01-07 15:42:20 +01004466 { "ssl_fc", smp_fetch_ssl_fc, 0, NULL, SMP_T_BOOL, SMP_USE_L5CLI },
4467 { "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 +01004468 { "ssl_fc_cipher", smp_fetch_ssl_fc_cipher, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Willy Tarreau80aca902013-01-07 15:42:20 +01004469 { "ssl_fc_has_crt", smp_fetch_ssl_fc_has_crt, 0, NULL, SMP_T_BOOL, SMP_USE_L5CLI },
4470 { "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 +02004471#ifdef OPENSSL_NPN_NEGOTIATED
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01004472 { "ssl_fc_npn", smp_fetch_ssl_fc_npn, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Willy Tarreaua33c6542012-10-15 13:19:06 +02004473#endif
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01004474#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01004475 { "ssl_fc_alpn", smp_fetch_ssl_fc_alpn, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Willy Tarreauab861d32013-04-02 02:30:41 +02004476#endif
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01004477 { "ssl_fc_protocol", smp_fetch_ssl_fc_protocol, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Emeric Brunb73a9b02014-04-30 18:49:19 +02004478 { "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 +01004479 { "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 +01004480 { "ssl_fc_session_id", smp_fetch_ssl_fc_session_id, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
4481 { "ssl_fc_sni", smp_fetch_ssl_fc_sni, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Willy Tarreau7875d092012-09-10 08:20:03 +02004482 { NULL, NULL, 0, 0, 0 },
4483}};
4484
4485/* Note: must not be declared <const> as its list will be overwritten.
4486 * Please take care of keeping this list alphabetically sorted.
4487 */
Willy Tarreaudc13c112013-06-21 23:16:39 +02004488static struct acl_kw_list acl_kws = {ILH, {
Thierry FOURNIERc5a4e982014-03-05 16:07:08 +01004489 { "ssl_fc_sni_end", "ssl_fc_sni", PAT_MATCH_END },
4490 { "ssl_fc_sni_reg", "ssl_fc_sni", PAT_MATCH_REG },
Willy Tarreau8ed669b2013-01-11 15:49:37 +01004491 { /* END */ },
Willy Tarreau7875d092012-09-10 08:20:03 +02004492}};
4493
Willy Tarreau79eeafa2012-09-14 07:53:05 +02004494/* Note: must not be declared <const> as its list will be overwritten.
4495 * Please take care of keeping this list alphabetically sorted, doing so helps
4496 * all code contributors.
4497 * Optional keywords are also declared with a NULL ->parse() function so that
4498 * the config parser can report an appropriate error when a known keyword was
4499 * not enabled.
4500 */
Willy Tarreau51fb7652012-09-18 18:24:39 +02004501static struct bind_kw_list bind_kws = { "SSL", { }, {
Willy Tarreauab861d32013-04-02 02:30:41 +02004502 { "alpn", bind_parse_alpn, 1 }, /* set ALPN supported protocols */
Emeric Brunfb510ea2012-10-05 12:00:26 +02004503 { "ca-file", bind_parse_ca_file, 1 }, /* set CAfile to process verify on client cert */
Emeric Brun2d0c4822012-10-02 13:45:20 +02004504 { "ca-ignore-err", bind_parse_ignore_err, 1 }, /* set error IDs to ignore on verify depth > 0 */
4505 { "ciphers", bind_parse_ciphers, 1 }, /* set SSL cipher suite */
Emeric Brunfb510ea2012-10-05 12:00:26 +02004506 { "crl-file", bind_parse_crl_file, 1 }, /* set certificat revocation list file use on client cert verify */
Emeric Brun2d0c4822012-10-02 13:45:20 +02004507 { "crt", bind_parse_crt, 1 }, /* load SSL certificates from this location */
4508 { "crt-ignore-err", bind_parse_ignore_err, 1 }, /* set error IDs to ingore on verify depth == 0 */
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01004509 { "crt-list", bind_parse_crt_list, 1 }, /* load a list of crt from this location */
Emeric Brun2d0c4822012-10-02 13:45:20 +02004510 { "ecdhe", bind_parse_ecdhe, 1 }, /* defines named curve for elliptic curve Diffie-Hellman */
Emeric Brun2cb7ae52012-10-05 14:14:21 +02004511 { "force-sslv3", bind_parse_force_sslv3, 0 }, /* force SSLv3 */
4512 { "force-tlsv10", bind_parse_force_tlsv10, 0 }, /* force TLSv10 */
4513 { "force-tlsv11", bind_parse_force_tlsv11, 0 }, /* force TLSv11 */
4514 { "force-tlsv12", bind_parse_force_tlsv12, 0 }, /* force TLSv12 */
Emeric Brun9b3009b2012-10-05 11:55:06 +02004515 { "no-sslv3", bind_parse_no_sslv3, 0 }, /* disable SSLv3 */
4516 { "no-tlsv10", bind_parse_no_tlsv10, 0 }, /* disable TLSv10 */
4517 { "no-tlsv11", bind_parse_no_tlsv11, 0 }, /* disable TLSv11 */
4518 { "no-tlsv12", bind_parse_no_tlsv12, 0 }, /* disable TLSv12 */
Emeric Brun2d0c4822012-10-02 13:45:20 +02004519 { "no-tls-tickets", bind_parse_no_tls_tickets, 0 }, /* disable session resumption tickets */
Emeric Brun2d0c4822012-10-02 13:45:20 +02004520 { "ssl", bind_parse_ssl, 0 }, /* enable SSL processing */
Emmanuel Hocdet65623372013-01-24 17:17:15 +01004521 { "strict-sni", bind_parse_strict_sni, 0 }, /* refuse negotiation if sni doesn't match a certificate */
Emeric Brun2d0c4822012-10-02 13:45:20 +02004522 { "verify", bind_parse_verify, 1 }, /* set SSL verify method */
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02004523 { "npn", bind_parse_npn, 1 }, /* set NPN supported protocols */
Willy Tarreau79eeafa2012-09-14 07:53:05 +02004524 { NULL, NULL, 0 },
4525}};
Emeric Brun46591952012-05-18 15:47:34 +02004526
Willy Tarreau92faadf2012-10-10 23:04:25 +02004527/* Note: must not be declared <const> as its list will be overwritten.
4528 * Please take care of keeping this list alphabetically sorted, doing so helps
4529 * all code contributors.
4530 * Optional keywords are also declared with a NULL ->parse() function so that
4531 * the config parser can report an appropriate error when a known keyword was
4532 * not enabled.
4533 */
4534static struct srv_kw_list srv_kws = { "SSL", { }, {
Emeric Brunef42d922012-10-11 16:11:36 +02004535 { "ca-file", srv_parse_ca_file, 1, 0 }, /* set CAfile to process verify server cert */
Emeric Brunecc91fe2012-10-11 15:05:10 +02004536 { "check-ssl", srv_parse_check_ssl, 0, 0 }, /* enable SSL for health checks */
4537 { "ciphers", srv_parse_ciphers, 1, 0 }, /* select the cipher suite */
Emeric Brunef42d922012-10-11 16:11:36 +02004538 { "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 +02004539 { "crt", srv_parse_crt, 1, 0 }, /* set client certificate */
Emeric Brunecc91fe2012-10-11 15:05:10 +02004540 { "force-sslv3", srv_parse_force_sslv3, 0, 0 }, /* force SSLv3 */
4541 { "force-tlsv10", srv_parse_force_tlsv10, 0, 0 }, /* force TLSv10 */
4542 { "force-tlsv11", srv_parse_force_tlsv11, 0, 0 }, /* force TLSv11 */
4543 { "force-tlsv12", srv_parse_force_tlsv12, 0, 0 }, /* force TLSv12 */
4544 { "no-sslv3", srv_parse_no_sslv3, 0, 0 }, /* disable SSLv3 */
4545 { "no-tlsv10", srv_parse_no_tlsv10, 0, 0 }, /* disable TLSv10 */
4546 { "no-tlsv11", srv_parse_no_tlsv11, 0, 0 }, /* disable TLSv11 */
4547 { "no-tlsv12", srv_parse_no_tlsv12, 0, 0 }, /* disable TLSv12 */
Emeric Brunf9c5c472012-10-11 15:28:34 +02004548 { "no-tls-tickets", srv_parse_no_tls_tickets, 0, 0 }, /* disable session resumption tickets */
David Safb76832014-05-08 23:42:08 -04004549 { "send-proxy-v2-ssl", srv_parse_send_proxy_ssl, 0, 0 }, /* send PROXY protocol header v2 with SSL info */
4550 { "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 +02004551 { "ssl", srv_parse_ssl, 0, 0 }, /* enable SSL processing */
Emeric Brunef42d922012-10-11 16:11:36 +02004552 { "verify", srv_parse_verify, 1, 0 }, /* set SSL verify method */
Evan Broderbe554312013-06-27 00:05:25 -07004553 { "verifyhost", srv_parse_verifyhost, 1, 0 }, /* require that SSL cert verifies for hostname */
Willy Tarreau92faadf2012-10-10 23:04:25 +02004554 { NULL, NULL, 0, 0 },
4555}};
4556
Emeric Brun42a3e202014-10-30 15:56:50 +01004557static struct cfg_kw_list cfg_kws = {ILH, {
4558 { CFG_GLOBAL, "ssl-default-bind-options", ssl_parse_default_bind_options },
4559 { CFG_GLOBAL, "ssl-default-server-options", ssl_parse_default_server_options },
4560 { 0, NULL, NULL },
4561}};
4562
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02004563/* transport-layer operations for SSL sockets */
4564struct xprt_ops ssl_sock = {
Emeric Brun46591952012-05-18 15:47:34 +02004565 .snd_buf = ssl_sock_from_buf,
4566 .rcv_buf = ssl_sock_to_buf,
4567 .rcv_pipe = NULL,
4568 .snd_pipe = NULL,
4569 .shutr = NULL,
4570 .shutw = ssl_sock_shutw,
4571 .close = ssl_sock_close,
4572 .init = ssl_sock_init,
4573};
4574
4575__attribute__((constructor))
Willy Tarreau92faadf2012-10-10 23:04:25 +02004576static void __ssl_sock_init(void)
4577{
Emeric Brun46591952012-05-18 15:47:34 +02004578 STACK_OF(SSL_COMP)* cm;
4579
Willy Tarreau610f04b2014-02-13 11:36:41 +01004580#ifdef LISTEN_DEFAULT_CIPHERS
4581 global.listen_default_ciphers = LISTEN_DEFAULT_CIPHERS;
4582#endif
4583#ifdef CONNECT_DEFAULT_CIPHERS
4584 global.connect_default_ciphers = CONNECT_DEFAULT_CIPHERS;
4585#endif
4586 if (global.listen_default_ciphers)
4587 global.listen_default_ciphers = strdup(global.listen_default_ciphers);
4588 if (global.connect_default_ciphers)
4589 global.connect_default_ciphers = strdup(global.connect_default_ciphers);
Emeric Brun42a3e202014-10-30 15:56:50 +01004590 global.listen_default_ssloptions = BC_SSL_O_NONE;
4591 global.connect_default_ssloptions = SRV_SSL_O_NONE;
Willy Tarreau610f04b2014-02-13 11:36:41 +01004592
Emeric Brun46591952012-05-18 15:47:34 +02004593 SSL_library_init();
4594 cm = SSL_COMP_get_compression_methods();
4595 sk_SSL_COMP_zero(cm);
Willy Tarreau7875d092012-09-10 08:20:03 +02004596 sample_register_fetches(&sample_fetch_keywords);
4597 acl_register_keywords(&acl_kws);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02004598 bind_register_keywords(&bind_kws);
Willy Tarreau92faadf2012-10-10 23:04:25 +02004599 srv_register_keywords(&srv_kws);
Emeric Brun42a3e202014-10-30 15:56:50 +01004600 cfg_register_keywords(&cfg_kws);
Remi Gacogne5d769ca2015-05-28 16:23:00 +02004601
4602#ifndef OPENSSL_NO_DH
4603 ssl_dh_ptr_index = SSL_CTX_get_ex_new_index(0, NULL, NULL, NULL, NULL);
4604#endif
Emeric Brun46591952012-05-18 15:47:34 +02004605}
4606
Remi Gacogne269a02f2015-05-28 16:39:47 +02004607__attribute__((destructor))
4608static void __ssl_sock_deinit(void)
4609{
4610#ifndef OPENSSL_NO_DH
4611 if (local_dh_1024) {
4612 DH_free(local_dh_1024);
4613 local_dh_1024 = NULL;
4614 }
4615
4616 if (local_dh_2048) {
4617 DH_free(local_dh_2048);
4618 local_dh_2048 = NULL;
4619 }
4620
4621 if (local_dh_4096) {
4622 DH_free(local_dh_4096);
4623 local_dh_4096 = NULL;
4624 }
Remi Gacogne269a02f2015-05-28 16:39:47 +02004625#endif
4626
4627 ERR_remove_state(0);
4628 ERR_free_strings();
4629
4630 EVP_cleanup();
4631
4632#if OPENSSL_VERSION_NUMBER >= 0x00907000L
4633 CRYPTO_cleanup_all_ex_data();
4634#endif
4635}
4636
4637
Emeric Brun46591952012-05-18 15:47:34 +02004638/*
4639 * Local variables:
4640 * c-indent-level: 8
4641 * c-basic-offset: 8
4642 * End:
4643 */