blob: 4e39c8b8154ea6218447074122114c9a74ee2595 [file] [log] [blame]
Emeric Brun46591952012-05-18 15:47:34 +02001/*
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02002 * SSL/TLS transport layer over SOCK_STREAM sockets
Emeric Brun46591952012-05-18 15:47:34 +02003 *
4 * Copyright (C) 2012 EXCELIANCE, Emeric Brun <ebrun@exceliance.fr>
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version
9 * 2 of the License, or (at your option) any later version.
10 *
Willy Tarreau69845df2012-09-10 09:43:09 +020011 * Acknowledgement:
12 * We'd like to specially thank the Stud project authors for a very clean
13 * and well documented code which helped us understand how the OpenSSL API
14 * ought to be used in non-blocking mode. This is one difficult part which
15 * is not easy to get from the OpenSSL doc, and reading the Stud code made
16 * it much more obvious than the examples in the OpenSSL package. Keep up
17 * the good works, guys !
18 *
19 * Stud is an extremely efficient and scalable SSL/TLS proxy which combines
20 * particularly well with haproxy. For more info about this project, visit :
21 * https://github.com/bumptech/stud
22 *
Emeric Brun46591952012-05-18 15:47:34 +020023 */
24
25#define _GNU_SOURCE
Emeric Brunfc0421f2012-09-07 17:30:07 +020026#include <ctype.h>
27#include <dirent.h>
Emeric Brun46591952012-05-18 15:47:34 +020028#include <errno.h>
29#include <fcntl.h>
30#include <stdio.h>
31#include <stdlib.h>
Emeric Brunfc0421f2012-09-07 17:30:07 +020032#include <string.h>
33#include <unistd.h>
Emeric Brun46591952012-05-18 15:47:34 +020034
35#include <sys/socket.h>
36#include <sys/stat.h>
37#include <sys/types.h>
38
39#include <netinet/tcp.h>
40
41#include <openssl/ssl.h>
Emeric Brunfc0421f2012-09-07 17:30:07 +020042#include <openssl/x509.h>
43#include <openssl/x509v3.h>
44#include <openssl/x509.h>
45#include <openssl/err.h>
Thierry Fournier383085f2013-01-24 14:15:43 +010046#include <openssl/rand.h>
Lukas Tribus656c5fa2014-08-18 00:56:31 +020047#if (defined SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB && !defined OPENSSL_IS_BORINGSSL)
Emeric Brun4147b2e2014-06-16 18:36:30 +020048#include <openssl/ocsp.h>
49#endif
Emeric Brun46591952012-05-18 15:47:34 +020050
51#include <common/buffer.h>
52#include <common/compat.h>
53#include <common/config.h>
54#include <common/debug.h>
Willy Tarreau79eeafa2012-09-14 07:53:05 +020055#include <common/errors.h>
Emeric Brun46591952012-05-18 15:47:34 +020056#include <common/standard.h>
57#include <common/ticks.h>
58#include <common/time.h>
59
Emeric Brunfc0421f2012-09-07 17:30:07 +020060#include <ebsttree.h>
61
62#include <types/global.h>
63#include <types/ssl_sock.h>
64
Willy Tarreau7875d092012-09-10 08:20:03 +020065#include <proto/acl.h>
66#include <proto/arg.h>
Emeric Brun46591952012-05-18 15:47:34 +020067#include <proto/connection.h>
68#include <proto/fd.h>
69#include <proto/freq_ctr.h>
70#include <proto/frontend.h>
Willy Tarreau79eeafa2012-09-14 07:53:05 +020071#include <proto/listener.h>
Thierry FOURNIERed66c292013-11-28 11:05:19 +010072#include <proto/pattern.h>
Willy Tarreau92faadf2012-10-10 23:04:25 +020073#include <proto/server.h>
Emeric Brun46591952012-05-18 15:47:34 +020074#include <proto/log.h>
Emeric Brun94324a42012-10-11 14:00:19 +020075#include <proto/proxy.h>
Emeric Brunfc0421f2012-09-07 17:30:07 +020076#include <proto/shctx.h>
Emeric Brun46591952012-05-18 15:47:34 +020077#include <proto/ssl_sock.h>
78#include <proto/task.h>
79
Willy Tarreau518cedd2014-02-17 15:43:01 +010080/* Warning, these are bits, not integers! */
Emeric Brune64aef12012-09-21 13:15:06 +020081#define SSL_SOCK_ST_FL_VERIFY_DONE 0x00000001
Emeric Brund8b2bb52014-01-28 15:43:53 +010082#define SSL_SOCK_ST_FL_16K_WBFSIZE 0x00000002
Willy Tarreau518cedd2014-02-17 15:43:01 +010083#define SSL_SOCK_SEND_UNLIMITED 0x00000004
Emeric Brun29f037d2014-04-25 19:05:36 +020084#define SSL_SOCK_RECV_HEARTBEAT 0x00000008
85
Emeric Brunf282a812012-09-21 15:27:54 +020086/* bits 0xFFFF0000 are reserved to store verify errors */
87
88/* Verify errors macros */
89#define SSL_SOCK_CA_ERROR_TO_ST(e) (((e > 63) ? 63 : e) << (16))
90#define SSL_SOCK_CAEDEPTH_TO_ST(d) (((d > 15) ? 15 : d) << (6+16))
91#define SSL_SOCK_CRTERROR_TO_ST(e) (((e > 63) ? 63 : e) << (4+6+16))
92
93#define SSL_SOCK_ST_TO_CA_ERROR(s) ((s >> (16)) & 63)
94#define SSL_SOCK_ST_TO_CAEDEPTH(s) ((s >> (6+16)) & 15)
95#define SSL_SOCK_ST_TO_CRTERROR(s) ((s >> (4+6+16)) & 63)
Emeric Brune64aef12012-09-21 13:15:06 +020096
Emeric Brun850efd52014-01-29 12:24:34 +010097/* server and bind verify method, it uses a global value as default */
98enum {
99 SSL_SOCK_VERIFY_DEFAULT = 0,
100 SSL_SOCK_VERIFY_REQUIRED = 1,
101 SSL_SOCK_VERIFY_OPTIONAL = 2,
102 SSL_SOCK_VERIFY_NONE = 3,
103};
104
Willy Tarreau71b734c2014-01-28 15:19:44 +0100105int sslconns = 0;
106int totalsslconns = 0;
Emeric Brune1f38db2012-09-03 20:36:47 +0200107
Remi Gacogne8de54152014-07-15 11:36:40 +0200108#ifndef OPENSSL_NO_DH
109static DH *local_dh_1024 = NULL;
110static DH *local_dh_2048 = NULL;
111static DH *local_dh_4096 = NULL;
112static DH *local_dh_8192 = NULL;
113#endif /* OPENSSL_NO_DH */
114
Lukas Tribus656c5fa2014-08-18 00:56:31 +0200115#if (defined SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB && !defined OPENSSL_IS_BORINGSSL)
Emeric Brun4147b2e2014-06-16 18:36:30 +0200116struct certificate_ocsp {
117 struct ebmb_node key;
118 unsigned char key_data[OCSP_MAX_CERTID_ASN1_LENGTH];
119 struct chunk response;
Emeric Brun4f3c87a2014-06-20 15:46:13 +0200120 long expire;
Emeric Brun4147b2e2014-06-16 18:36:30 +0200121};
122
Emeric Brun4f3c87a2014-06-20 15:46:13 +0200123/*
124 * This function returns the number of seconds elapsed
125 * since the Epoch, 1970-01-01 00:00:00 +0000 (UTC) and the
126 * date presented un ASN1_GENERALIZEDTIME.
127 *
128 * In parsing error case, it returns -1.
129 */
130static long asn1_generalizedtime_to_epoch(ASN1_GENERALIZEDTIME *d)
131{
132 long epoch;
133 char *p, *end;
134 const unsigned short month_offset[12] = {
135 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334
136 };
137 int year, month;
138
139 if (!d || (d->type != V_ASN1_GENERALIZEDTIME)) return -1;
140
141 p = (char *)d->data;
142 end = p + d->length;
143
144 if (end - p < 4) return -1;
145 year = 1000 * (p[0] - '0') + 100 * (p[1] - '0') + 10 * (p[2] - '0') + p[3] - '0';
146 p += 4;
147 if (end - p < 2) return -1;
148 month = 10 * (p[0] - '0') + p[1] - '0';
149 if (month < 1 || month > 12) return -1;
150 /* Compute the number of seconds since 1 jan 1970 and the beginning of current month
151 We consider leap years and the current month (<marsh or not) */
152 epoch = ( ((year - 1970) * 365)
153 + ((year - (month < 3)) / 4 - (year - (month < 3)) / 100 + (year - (month < 3)) / 400)
154 - ((1970 - 1) / 4 - (1970 - 1) / 100 + (1970 - 1) / 400)
155 + month_offset[month-1]
156 ) * 24 * 60 * 60;
157 p += 2;
158 if (end - p < 2) return -1;
159 /* Add the number of seconds of completed days of current month */
160 epoch += (10 * (p[0] - '0') + p[1] - '0' - 1) * 24 * 60 * 60;
161 p += 2;
162 if (end - p < 2) return -1;
163 /* Add the completed hours of the current day */
164 epoch += (10 * (p[0] - '0') + p[1] - '0') * 60 * 60;
165 p += 2;
166 if (end - p < 2) return -1;
167 /* Add the completed minutes of the current hour */
168 epoch += (10 * (p[0] - '0') + p[1] - '0') * 60;
169 p += 2;
170 if (p == end) return -1;
171 /* Test if there is available seconds */
172 if (p[0] < '0' || p[0] > '9')
173 goto nosec;
174 if (end - p < 2) return -1;
175 /* Add the seconds of the current minute */
176 epoch += 10 * (p[0] - '0') + p[1] - '0';
177 p += 2;
178 if (p == end) return -1;
179 /* Ignore seconds float part if present */
180 if (p[0] == '.') {
181 do {
182 if (++p == end) return -1;
183 } while (p[0] >= '0' && p[0] <= '9');
184 }
185
186nosec:
187 if (p[0] == 'Z') {
188 if (end - p != 1) return -1;
189 return epoch;
190 }
191 else if (p[0] == '+') {
192 if (end - p != 5) return -1;
193 /* Apply timezone offset */
194 return epoch - ((10 * (p[1] - '0') + p[2] - '0') * 60 + (10 * (p[3] - '0') + p[4] - '0')) * 60;
195 }
196 else if (p[0] == '-') {
197 if (end - p != 5) return -1;
198 /* Apply timezone offset */
199 return epoch + ((10 * (p[1] - '0') + p[2] - '0') * 60 + (10 * (p[3] - '0') + p[4] - '0')) * 60;
200 }
201
202 return -1;
203}
204
Emeric Brun1d3865b2014-06-20 15:37:32 +0200205static struct eb_root cert_ocsp_tree = EB_ROOT_UNIQUE;
Emeric Brun4147b2e2014-06-16 18:36:30 +0200206
207/* This function starts to check if the OCSP response (in DER format) contained
208 * in chunk 'ocsp_response' is valid (else exits on error).
209 * If 'cid' is not NULL, it will be compared to the OCSP certificate ID
210 * contained in the OCSP Response and exits on error if no match.
211 * If it's a valid OCSP Response:
212 * If 'ocsp' is not NULL, the chunk is copied in the OCSP response's container
213 * pointed by 'ocsp'.
214 * If 'ocsp' is NULL, the function looks up into the OCSP response's
215 * containers tree (using as index the ASN1 form of the OCSP Certificate ID extracted
216 * from the response) and exits on error if not found. Finally, If an OCSP response is
217 * already present in the container, it will be overwritten.
218 *
219 * Note: OCSP response containing more than one OCSP Single response is not
220 * considered valid.
221 *
222 * Returns 0 on success, 1 in error case.
223 */
224static int ssl_sock_load_ocsp_response(struct chunk *ocsp_response, struct certificate_ocsp *ocsp, OCSP_CERTID *cid, char **err)
225{
226 OCSP_RESPONSE *resp;
227 OCSP_BASICRESP *bs = NULL;
228 OCSP_SINGLERESP *sr;
229 unsigned char *p = (unsigned char *)ocsp_response->str;
230 int rc , count_sr;
Emeric Brun13a6b482014-06-20 15:44:34 +0200231 ASN1_GENERALIZEDTIME *revtime, *thisupd, *nextupd = NULL;
Emeric Brun4147b2e2014-06-16 18:36:30 +0200232 int reason;
233 int ret = 1;
234
235 resp = d2i_OCSP_RESPONSE(NULL, (const unsigned char **)&p, ocsp_response->len);
236 if (!resp) {
237 memprintf(err, "Unable to parse OCSP response");
238 goto out;
239 }
240
241 rc = OCSP_response_status(resp);
242 if (rc != OCSP_RESPONSE_STATUS_SUCCESSFUL) {
243 memprintf(err, "OCSP response status not successful");
244 goto out;
245 }
246
247 bs = OCSP_response_get1_basic(resp);
248 if (!bs) {
249 memprintf(err, "Failed to get basic response from OCSP Response");
250 goto out;
251 }
252
253 count_sr = OCSP_resp_count(bs);
254 if (count_sr > 1) {
255 memprintf(err, "OCSP response ignored because contains multiple single responses (%d)", count_sr);
256 goto out;
257 }
258
259 sr = OCSP_resp_get0(bs, 0);
260 if (!sr) {
261 memprintf(err, "Failed to get OCSP single response");
262 goto out;
263 }
264
265 rc = OCSP_single_get0_status(sr, &reason, &revtime, &thisupd, &nextupd);
266 if (rc != V_OCSP_CERTSTATUS_GOOD) {
267 memprintf(err, "OCSP single response: certificate status not good");
268 goto out;
269 }
270
Emeric Brun13a6b482014-06-20 15:44:34 +0200271 if (!nextupd) {
272 memprintf(err, "OCSP single response: missing nextupdate");
273 goto out;
274 }
275
Emeric Brunc8b27b62014-06-19 14:16:17 +0200276 rc = OCSP_check_validity(thisupd, nextupd, OCSP_MAX_RESPONSE_TIME_SKEW, -1);
Emeric Brun4147b2e2014-06-16 18:36:30 +0200277 if (!rc) {
278 memprintf(err, "OCSP single response: no longer valid.");
279 goto out;
280 }
281
282 if (cid) {
283 if (OCSP_id_cmp(sr->certId, cid)) {
284 memprintf(err, "OCSP single response: Certificate ID does not match certificate and issuer");
285 goto out;
286 }
287 }
288
289 if (!ocsp) {
290 unsigned char key[OCSP_MAX_CERTID_ASN1_LENGTH];
291 unsigned char *p;
292
293 rc = i2d_OCSP_CERTID(sr->certId, NULL);
294 if (!rc) {
295 memprintf(err, "OCSP single response: Unable to encode Certificate ID");
296 goto out;
297 }
298
299 if (rc > OCSP_MAX_CERTID_ASN1_LENGTH) {
300 memprintf(err, "OCSP single response: Certificate ID too long");
301 goto out;
302 }
303
304 p = key;
305 memset(key, 0, OCSP_MAX_CERTID_ASN1_LENGTH);
306 i2d_OCSP_CERTID(sr->certId, &p);
307 ocsp = (struct certificate_ocsp *)ebmb_lookup(&cert_ocsp_tree, key, OCSP_MAX_CERTID_ASN1_LENGTH);
308 if (!ocsp) {
309 memprintf(err, "OCSP single response: Certificate ID does not match any certificate or issuer");
310 goto out;
311 }
312 }
313
314 /* According to comments on "chunk_dup", the
315 previous chunk buffer will be freed */
316 if (!chunk_dup(&ocsp->response, ocsp_response)) {
317 memprintf(err, "OCSP response: Memory allocation error");
318 goto out;
319 }
320
Emeric Brun4f3c87a2014-06-20 15:46:13 +0200321 ocsp->expire = asn1_generalizedtime_to_epoch(nextupd) - OCSP_MAX_RESPONSE_TIME_SKEW;
322
Emeric Brun4147b2e2014-06-16 18:36:30 +0200323 ret = 0;
324out:
325 if (bs)
326 OCSP_BASICRESP_free(bs);
327
328 if (resp)
329 OCSP_RESPONSE_free(resp);
330
331 return ret;
332}
333/*
334 * External function use to update the OCSP response in the OCSP response's
335 * containers tree. The chunk 'ocsp_response' must contain the OCSP response
336 * to update in DER format.
337 *
338 * Returns 0 on success, 1 in error case.
339 */
340int ssl_sock_update_ocsp_response(struct chunk *ocsp_response, char **err)
341{
342 return ssl_sock_load_ocsp_response(ocsp_response, NULL, NULL, err);
343}
344
345/*
346 * This function load the OCSP Resonse in DER format contained in file at
347 * path 'ocsp_path' and call 'ssl_sock_load_ocsp_response'
348 *
349 * Returns 0 on success, 1 in error case.
350 */
351static int ssl_sock_load_ocsp_response_from_file(const char *ocsp_path, struct certificate_ocsp *ocsp, OCSP_CERTID *cid, char **err)
352{
353 int fd = -1;
354 int r = 0;
355 int ret = 1;
356
357 fd = open(ocsp_path, O_RDONLY);
358 if (fd == -1) {
359 memprintf(err, "Error opening OCSP response file");
360 goto end;
361 }
362
363 trash.len = 0;
364 while (trash.len < trash.size) {
365 r = read(fd, trash.str + trash.len, trash.size - trash.len);
366 if (r < 0) {
367 if (errno == EINTR)
368 continue;
369
370 memprintf(err, "Error reading OCSP response from file");
371 goto end;
372 }
373 else if (r == 0) {
374 break;
375 }
376 trash.len += r;
377 }
378
379 close(fd);
380 fd = -1;
381
382 ret = ssl_sock_load_ocsp_response(&trash, ocsp, cid, err);
383end:
384 if (fd != -1)
385 close(fd);
386
387 return ret;
388}
389
390/*
391 * Callback used to set OCSP status extension content in server hello.
392 */
393int ssl_sock_ocsp_stapling_cbk(SSL *ssl, void *arg)
394{
395 struct certificate_ocsp *ocsp = (struct certificate_ocsp *)arg;
396 char* ssl_buf;
397
398 if (!ocsp ||
399 !ocsp->response.str ||
Emeric Brun4f3c87a2014-06-20 15:46:13 +0200400 !ocsp->response.len ||
401 (ocsp->expire < now.tv_sec))
Emeric Brun4147b2e2014-06-16 18:36:30 +0200402 return SSL_TLSEXT_ERR_NOACK;
403
404 ssl_buf = OPENSSL_malloc(ocsp->response.len);
405 if (!ssl_buf)
406 return SSL_TLSEXT_ERR_NOACK;
407
408 memcpy(ssl_buf, ocsp->response.str, ocsp->response.len);
409 SSL_set_tlsext_status_ocsp_resp(ssl, ssl_buf, ocsp->response.len);
410
411 return SSL_TLSEXT_ERR_OK;
412}
413
414/*
415 * This function enables the handling of OCSP status extension on 'ctx' if a
416 * file name 'cert_path' suffixed using ".ocsp" is present.
417 * To enable OCSP status extension, the issuer's certificate is mandatory.
418 * It should be present in the certificate's extra chain builded from file
419 * 'cert_path'. If not found, the issuer certificate is loaded from a file
420 * named 'cert_path' suffixed using '.issuer'.
421 *
422 * In addition, ".ocsp" file content is loaded as a DER format of an OCSP
423 * response. If file is empty or content is not a valid OCSP response,
424 * OCSP status extension is enabled but OCSP response is ignored (a warning
425 * is displayed).
426 *
427 * Returns 1 if no ".ocsp" file found, 0 if OCSP status extension is
428 * succesfully enabled, or -1 in other error case.
429 */
430static int ssl_sock_load_ocsp(SSL_CTX *ctx, const char *cert_path)
431{
432
433 BIO *in = NULL;
434 X509 *x, *xi = NULL, *issuer = NULL;
435 STACK_OF(X509) *chain = NULL;
436 OCSP_CERTID *cid = NULL;
437 SSL *ssl;
438 char ocsp_path[MAXPATHLEN+1];
439 int i, ret = -1;
440 struct stat st;
441 struct certificate_ocsp *ocsp = NULL, *iocsp;
442 char *warn = NULL;
443 unsigned char *p;
444
445 snprintf(ocsp_path, MAXPATHLEN+1, "%s.ocsp", cert_path);
446
447 if (stat(ocsp_path, &st))
448 return 1;
449
450 ssl = SSL_new(ctx);
451 if (!ssl)
452 goto out;
453
454 x = SSL_get_certificate(ssl);
455 if (!x)
456 goto out;
457
458 /* Try to lookup for issuer in certificate extra chain */
459#ifdef SSL_CTRL_GET_EXTRA_CHAIN_CERTS
460 SSL_CTX_get_extra_chain_certs(ctx, &chain);
461#else
462 chain = ctx->extra_certs;
463#endif
464 for (i = 0; i < sk_X509_num(chain); i++) {
465 issuer = sk_X509_value(chain, i);
466 if (X509_check_issued(issuer, x) == X509_V_OK)
467 break;
468 else
469 issuer = NULL;
470 }
471
472 /* If not found try to load issuer from a suffixed file */
473 if (!issuer) {
474 char issuer_path[MAXPATHLEN+1];
475
476 in = BIO_new(BIO_s_file());
477 if (!in)
478 goto out;
479
480 snprintf(issuer_path, MAXPATHLEN+1, "%s.issuer", cert_path);
481 if (BIO_read_filename(in, issuer_path) <= 0)
482 goto out;
483
484 xi = PEM_read_bio_X509_AUX(in, NULL, ctx->default_passwd_callback, ctx->default_passwd_callback_userdata);
485 if (!xi)
486 goto out;
487
488 if (X509_check_issued(xi, x) != X509_V_OK)
489 goto out;
490
491 issuer = xi;
492 }
493
494 cid = OCSP_cert_to_id(0, x, issuer);
495 if (!cid)
496 goto out;
497
498 i = i2d_OCSP_CERTID(cid, NULL);
499 if (!i || (i > OCSP_MAX_CERTID_ASN1_LENGTH))
500 goto out;
501
502 ocsp = calloc(1, sizeof(struct certificate_ocsp));
503 if (!ocsp)
504 goto out;
505
506 p = ocsp->key_data;
507 i2d_OCSP_CERTID(cid, &p);
508
509 iocsp = (struct certificate_ocsp *)ebmb_insert(&cert_ocsp_tree, &ocsp->key, OCSP_MAX_CERTID_ASN1_LENGTH);
510 if (iocsp == ocsp)
511 ocsp = NULL;
512
513 SSL_CTX_set_tlsext_status_cb(ctx, ssl_sock_ocsp_stapling_cbk);
514 SSL_CTX_set_tlsext_status_arg(ctx, iocsp);
515
516 ret = 0;
517
518 warn = NULL;
519 if (ssl_sock_load_ocsp_response_from_file(ocsp_path, iocsp, cid, &warn)) {
520 memprintf(&warn, "Loading '%s': %s. Content will be ignored", ocsp_path, warn ? warn : "failure");
521 Warning("%s.\n", warn);
522 }
523
524out:
525 if (ssl)
526 SSL_free(ssl);
527
528 if (in)
529 BIO_free(in);
530
531 if (xi)
532 X509_free(xi);
533
534 if (cid)
535 OCSP_CERTID_free(cid);
536
537 if (ocsp)
538 free(ocsp);
539
540 if (warn)
541 free(warn);
542
543
544 return ret;
545}
546
547#endif
548
Emeric Brune1f38db2012-09-03 20:36:47 +0200549void ssl_sock_infocbk(const SSL *ssl, int where, int ret)
550{
551 struct connection *conn = (struct connection *)SSL_get_app_data(ssl);
552 (void)ret; /* shut gcc stupid warning */
Emeric Brund8b2bb52014-01-28 15:43:53 +0100553 BIO *write_bio;
Emeric Brune1f38db2012-09-03 20:36:47 +0200554
555 if (where & SSL_CB_HANDSHAKE_START) {
556 /* Disable renegotiation (CVE-2009-3555) */
Willy Tarreau20879a02012-12-03 16:32:10 +0100557 if (conn->flags & CO_FL_CONNECTED) {
Emeric Brune1f38db2012-09-03 20:36:47 +0200558 conn->flags |= CO_FL_ERROR;
Willy Tarreau20879a02012-12-03 16:32:10 +0100559 conn->err_code = CO_ER_SSL_RENEG;
560 }
Emeric Brune1f38db2012-09-03 20:36:47 +0200561 }
Emeric Brund8b2bb52014-01-28 15:43:53 +0100562
563 if ((where & SSL_CB_ACCEPT_LOOP) == SSL_CB_ACCEPT_LOOP) {
564 if (!(conn->xprt_st & SSL_SOCK_ST_FL_16K_WBFSIZE)) {
565 /* Long certificate chains optimz
566 If write and read bios are differents, we
567 consider that the buffering was activated,
568 so we rise the output buffer size from 4k
569 to 16k */
570 write_bio = SSL_get_wbio(ssl);
571 if (write_bio != SSL_get_rbio(ssl)) {
572 BIO_set_write_buffer_size(write_bio, 16384);
573 conn->xprt_st |= SSL_SOCK_ST_FL_16K_WBFSIZE;
574 }
575 }
576 }
Emeric Brunfc0421f2012-09-07 17:30:07 +0200577}
578
Emeric Brune64aef12012-09-21 13:15:06 +0200579/* Callback is called for each certificate of the chain during a verify
580 ok is set to 1 if preverify detect no error on current certificate.
581 Returns 0 to break the handshake, 1 otherwise. */
Evan Broderbe554312013-06-27 00:05:25 -0700582int ssl_sock_bind_verifycbk(int ok, X509_STORE_CTX *x_store)
Emeric Brune64aef12012-09-21 13:15:06 +0200583{
584 SSL *ssl;
585 struct connection *conn;
Emeric Brun81c00f02012-09-21 14:31:21 +0200586 int err, depth;
Emeric Brune64aef12012-09-21 13:15:06 +0200587
588 ssl = X509_STORE_CTX_get_ex_data(x_store, SSL_get_ex_data_X509_STORE_CTX_idx());
589 conn = (struct connection *)SSL_get_app_data(ssl);
590
Willy Tarreauf7bc57c2012-10-03 00:19:48 +0200591 conn->xprt_st |= SSL_SOCK_ST_FL_VERIFY_DONE;
Emeric Brune64aef12012-09-21 13:15:06 +0200592
Emeric Brun81c00f02012-09-21 14:31:21 +0200593 if (ok) /* no errors */
594 return ok;
595
596 depth = X509_STORE_CTX_get_error_depth(x_store);
597 err = X509_STORE_CTX_get_error(x_store);
598
599 /* check if CA error needs to be ignored */
600 if (depth > 0) {
Willy Tarreauf7bc57c2012-10-03 00:19:48 +0200601 if (!SSL_SOCK_ST_TO_CA_ERROR(conn->xprt_st)) {
602 conn->xprt_st |= SSL_SOCK_CA_ERROR_TO_ST(err);
603 conn->xprt_st |= SSL_SOCK_CAEDEPTH_TO_ST(depth);
Emeric Brunf282a812012-09-21 15:27:54 +0200604 }
605
Emeric Brun1eb20ef2012-12-03 13:24:29 +0100606 if (objt_listener(conn->target)->bind_conf->ca_ignerr & (1ULL << err)) {
607 ERR_clear_error();
Emeric Brun81c00f02012-09-21 14:31:21 +0200608 return 1;
Emeric Brun1eb20ef2012-12-03 13:24:29 +0100609 }
Emeric Brun81c00f02012-09-21 14:31:21 +0200610
Willy Tarreau20879a02012-12-03 16:32:10 +0100611 conn->err_code = CO_ER_SSL_CA_FAIL;
Emeric Brun81c00f02012-09-21 14:31:21 +0200612 return 0;
613 }
614
Willy Tarreauf7bc57c2012-10-03 00:19:48 +0200615 if (!SSL_SOCK_ST_TO_CRTERROR(conn->xprt_st))
616 conn->xprt_st |= SSL_SOCK_CRTERROR_TO_ST(err);
Emeric Brunf282a812012-09-21 15:27:54 +0200617
Emeric Brun81c00f02012-09-21 14:31:21 +0200618 /* check if certificate error needs to be ignored */
Emeric Brun1eb20ef2012-12-03 13:24:29 +0100619 if (objt_listener(conn->target)->bind_conf->crt_ignerr & (1ULL << err)) {
620 ERR_clear_error();
Emeric Brun81c00f02012-09-21 14:31:21 +0200621 return 1;
Emeric Brun1eb20ef2012-12-03 13:24:29 +0100622 }
Emeric Brun81c00f02012-09-21 14:31:21 +0200623
Willy Tarreau20879a02012-12-03 16:32:10 +0100624 conn->err_code = CO_ER_SSL_CRT_FAIL;
Emeric Brun81c00f02012-09-21 14:31:21 +0200625 return 0;
Emeric Brune64aef12012-09-21 13:15:06 +0200626}
627
Emeric Brun29f037d2014-04-25 19:05:36 +0200628/* Callback is called for ssl protocol analyse */
629void ssl_sock_msgcbk(int write_p, int version, int content_type, const void *buf, size_t len, SSL *ssl, void *arg)
630{
Emeric Brun29f037d2014-04-25 19:05:36 +0200631#ifdef TLS1_RT_HEARTBEAT
632 /* test heartbeat received (write_p is set to 0
633 for a received record) */
Willy Tarreauf51c6982014-04-25 20:02:39 +0200634 if ((content_type == TLS1_RT_HEARTBEAT) && (write_p == 0)) {
Willy Tarreau84815002014-04-25 21:40:27 +0200635 struct connection *conn = (struct connection *)SSL_get_app_data(ssl);
Willy Tarreauf51c6982014-04-25 20:02:39 +0200636 const unsigned char *p = buf;
637 unsigned int payload;
638
Emeric Brun29f037d2014-04-25 19:05:36 +0200639 conn->xprt_st |= SSL_SOCK_RECV_HEARTBEAT;
Willy Tarreauf51c6982014-04-25 20:02:39 +0200640
641 /* Check if this is a CVE-2014-0160 exploitation attempt. */
642 if (*p != TLS1_HB_REQUEST)
643 return;
644
Willy Tarreauaeed6722014-04-25 23:59:58 +0200645 if (len < 1 + 2 + 16) /* 1 type + 2 size + 0 payload + 16 padding */
Willy Tarreauf51c6982014-04-25 20:02:39 +0200646 goto kill_it;
647
648 payload = (p[1] * 256) + p[2];
Willy Tarreau3b2fdb62014-04-25 23:44:22 +0200649 if (3 + payload + 16 <= len)
Willy Tarreauf51c6982014-04-25 20:02:39 +0200650 return; /* OK no problem */
Willy Tarreauaeed6722014-04-25 23:59:58 +0200651 kill_it:
Willy Tarreau3b2fdb62014-04-25 23:44:22 +0200652 /* We have a clear heartbleed attack (CVE-2014-0160), the
653 * advertised payload is larger than the advertised packet
654 * length, so we have garbage in the buffer between the
655 * payload and the end of the buffer (p+len). We can't know
656 * if the SSL stack is patched, and we don't know if we can
657 * safely wipe out the area between p+3+len and payload.
658 * So instead, we prevent the response from being sent by
659 * setting the max_send_fragment to 0 and we report an SSL
660 * error, which will kill this connection. It will be reported
661 * above as SSL_ERROR_SSL while an other handshake failure with
Willy Tarreauf51c6982014-04-25 20:02:39 +0200662 * a heartbeat message will be reported as SSL_ERROR_SYSCALL.
663 */
Willy Tarreau3b2fdb62014-04-25 23:44:22 +0200664 ssl->max_send_fragment = 0;
Willy Tarreauf51c6982014-04-25 20:02:39 +0200665 SSLerr(SSL_F_TLS1_HEARTBEAT, SSL_R_SSL_HANDSHAKE_FAILURE);
666 return;
667 }
Emeric Brun29f037d2014-04-25 19:05:36 +0200668#endif
669}
670
Willy Tarreau6c9a3d52012-10-18 18:57:14 +0200671#ifdef OPENSSL_NPN_NEGOTIATED
672/* This callback is used so that the server advertises the list of
673 * negociable protocols for NPN.
674 */
675static int ssl_sock_advertise_npn_protos(SSL *s, const unsigned char **data,
676 unsigned int *len, void *arg)
677{
678 struct bind_conf *conf = arg;
679
680 *data = (const unsigned char *)conf->npn_str;
681 *len = conf->npn_len;
682 return SSL_TLSEXT_ERR_OK;
683}
684#endif
685
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +0100686#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Willy Tarreauab861d32013-04-02 02:30:41 +0200687/* This callback is used so that the server advertises the list of
688 * negociable protocols for ALPN.
689 */
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +0100690static int ssl_sock_advertise_alpn_protos(SSL *s, const unsigned char **out,
691 unsigned char *outlen,
692 const unsigned char *server,
693 unsigned int server_len, void *arg)
Willy Tarreauab861d32013-04-02 02:30:41 +0200694{
695 struct bind_conf *conf = arg;
696
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +0100697 if (SSL_select_next_proto((unsigned char**) out, outlen, (const unsigned char *)conf->alpn_str,
698 conf->alpn_len, server, server_len) != OPENSSL_NPN_NEGOTIATED) {
699 return SSL_TLSEXT_ERR_NOACK;
700 }
Willy Tarreauab861d32013-04-02 02:30:41 +0200701 return SSL_TLSEXT_ERR_OK;
702}
703#endif
704
Emeric Brunfc0421f2012-09-07 17:30:07 +0200705#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
706/* Sets the SSL ctx of <ssl> to match the advertised server name. Returns a
707 * warning when no match is found, which implies the default (first) cert
708 * will keep being used.
709 */
Willy Tarreau2a65ff02012-09-13 17:54:29 +0200710static int ssl_sock_switchctx_cbk(SSL *ssl, int *al, struct bind_conf *s)
Emeric Brunfc0421f2012-09-07 17:30:07 +0200711{
712 const char *servername;
713 const char *wildp = NULL;
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +0200714 struct ebmb_node *node, *n;
Emeric Brunfc0421f2012-09-07 17:30:07 +0200715 int i;
716 (void)al; /* shut gcc stupid warning */
717
718 servername = SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name);
Emmanuel Hocdet65623372013-01-24 17:17:15 +0100719 if (!servername) {
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +0200720 return (s->strict_sni ?
721 SSL_TLSEXT_ERR_ALERT_FATAL :
Emmanuel Hocdet79274e22013-05-31 12:47:44 +0200722 SSL_TLSEXT_ERR_NOACK);
Emmanuel Hocdet65623372013-01-24 17:17:15 +0100723 }
Emeric Brunfc0421f2012-09-07 17:30:07 +0200724
Willy Tarreau19d14ef2012-10-29 16:51:55 +0100725 for (i = 0; i < trash.size; i++) {
Emeric Brunfc0421f2012-09-07 17:30:07 +0200726 if (!servername[i])
727 break;
Willy Tarreau19d14ef2012-10-29 16:51:55 +0100728 trash.str[i] = tolower(servername[i]);
729 if (!wildp && (trash.str[i] == '.'))
730 wildp = &trash.str[i];
Emeric Brunfc0421f2012-09-07 17:30:07 +0200731 }
Willy Tarreau19d14ef2012-10-29 16:51:55 +0100732 trash.str[i] = 0;
Emeric Brunfc0421f2012-09-07 17:30:07 +0200733
734 /* lookup in full qualified names */
Willy Tarreau19d14ef2012-10-29 16:51:55 +0100735 node = ebst_lookup(&s->sni_ctx, trash.str);
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +0200736
737 /* lookup a not neg filter */
738 for (n = node; n; n = ebmb_next_dup(n)) {
739 if (!container_of(n, struct sni_ctx, name)->neg) {
740 node = n;
741 break;
Emmanuel Hocdet65623372013-01-24 17:17:15 +0100742 }
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +0200743 }
744 if (!node && wildp) {
745 /* lookup in wildcards names */
Emeric Brunfc0421f2012-09-07 17:30:07 +0200746 node = ebst_lookup(&s->sni_w_ctx, wildp);
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +0200747 }
748 if (!node || container_of(node, struct sni_ctx, name)->neg) {
749 return (s->strict_sni ?
750 SSL_TLSEXT_ERR_ALERT_FATAL :
751 SSL_TLSEXT_ERR_ALERT_WARNING);
Emeric Brunfc0421f2012-09-07 17:30:07 +0200752 }
753
754 /* switch ctx */
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +0200755 SSL_set_SSL_CTX(ssl, container_of(node, struct sni_ctx, name)->ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +0200756 return SSL_TLSEXT_ERR_OK;
757}
758#endif /* SSL_CTRL_SET_TLSEXT_HOSTNAME */
759
Emeric Bruna4bcd9a2012-09-20 16:19:02 +0200760#ifndef OPENSSL_NO_DH
Remi Gacognef46cd6e2014-06-12 14:58:40 +0200761
762static DH * ssl_get_dh_1024(void)
763{
Lukas Tribus4c0d45a2014-08-18 00:56:32 +0200764#if (OPENSSL_VERSION_NUMBER < 0x0090801fL || defined OPENSSL_IS_BORINGSSL)
Remi Gacognef46cd6e2014-06-12 14:58:40 +0200765 static const unsigned char rfc_2409_prime_1024[] = {
766 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xC9,0x0F,0xDA,0xA2,
767 0x21,0x68,0xC2,0x34,0xC4,0xC6,0x62,0x8B,0x80,0xDC,0x1C,0xD1,
768 0x29,0x02,0x4E,0x08,0x8A,0x67,0xCC,0x74,0x02,0x0B,0xBE,0xA6,
769 0x3B,0x13,0x9B,0x22,0x51,0x4A,0x08,0x79,0x8E,0x34,0x04,0xDD,
770 0xEF,0x95,0x19,0xB3,0xCD,0x3A,0x43,0x1B,0x30,0x2B,0x0A,0x6D,
771 0xF2,0x5F,0x14,0x37,0x4F,0xE1,0x35,0x6D,0x6D,0x51,0xC2,0x45,
772 0xE4,0x85,0xB5,0x76,0x62,0x5E,0x7E,0xC6,0xF4,0x4C,0x42,0xE9,
773 0xA6,0x37,0xED,0x6B,0x0B,0xFF,0x5C,0xB6,0xF4,0x06,0xB7,0xED,
774 0xEE,0x38,0x6B,0xFB,0x5A,0x89,0x9F,0xA5,0xAE,0x9F,0x24,0x11,
775 0x7C,0x4B,0x1F,0xE6,0x49,0x28,0x66,0x51,0xEC,0xE6,0x53,0x81,
776 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
777 };
778#endif
779 DH *dh = DH_new();
780 if (dh) {
Lukas Tribus4c0d45a2014-08-18 00:56:32 +0200781#if (OPENSSL_VERSION_NUMBER >= 0x0090801fL && !defined OPENSSL_IS_BORINGSSL)
Remi Gacognef46cd6e2014-06-12 14:58:40 +0200782 dh->p = get_rfc2409_prime_1024(NULL);
783#else
784 dh->p = BN_bin2bn(rfc_2409_prime_1024, sizeof rfc_2409_prime_1024, NULL);
785#endif
786 /* See RFC 2409, Section 6 "Oakley Groups"
787 for the reason why 2 is used as generator.
788 */
789 BN_dec2bn(&dh->g, "2");
790 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{
Lukas Tribus4c0d45a2014-08-18 00:56:32 +0200800#if (OPENSSL_VERSION_NUMBER < 0x0090801fL || defined OPENSSL_IS_BORINGSSL)
Remi Gacognef46cd6e2014-06-12 14:58:40 +0200801 static const unsigned char rfc_3526_prime_2048[] = {
802 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xC9,0x0F,0xDA,0xA2,
803 0x21,0x68,0xC2,0x34,0xC4,0xC6,0x62,0x8B,0x80,0xDC,0x1C,0xD1,
804 0x29,0x02,0x4E,0x08,0x8A,0x67,0xCC,0x74,0x02,0x0B,0xBE,0xA6,
805 0x3B,0x13,0x9B,0x22,0x51,0x4A,0x08,0x79,0x8E,0x34,0x04,0xDD,
806 0xEF,0x95,0x19,0xB3,0xCD,0x3A,0x43,0x1B,0x30,0x2B,0x0A,0x6D,
807 0xF2,0x5F,0x14,0x37,0x4F,0xE1,0x35,0x6D,0x6D,0x51,0xC2,0x45,
808 0xE4,0x85,0xB5,0x76,0x62,0x5E,0x7E,0xC6,0xF4,0x4C,0x42,0xE9,
809 0xA6,0x37,0xED,0x6B,0x0B,0xFF,0x5C,0xB6,0xF4,0x06,0xB7,0xED,
810 0xEE,0x38,0x6B,0xFB,0x5A,0x89,0x9F,0xA5,0xAE,0x9F,0x24,0x11,
811 0x7C,0x4B,0x1F,0xE6,0x49,0x28,0x66,0x51,0xEC,0xE4,0x5B,0x3D,
812 0xC2,0x00,0x7C,0xB8,0xA1,0x63,0xBF,0x05,0x98,0xDA,0x48,0x36,
813 0x1C,0x55,0xD3,0x9A,0x69,0x16,0x3F,0xA8,0xFD,0x24,0xCF,0x5F,
814 0x83,0x65,0x5D,0x23,0xDC,0xA3,0xAD,0x96,0x1C,0x62,0xF3,0x56,
815 0x20,0x85,0x52,0xBB,0x9E,0xD5,0x29,0x07,0x70,0x96,0x96,0x6D,
816 0x67,0x0C,0x35,0x4E,0x4A,0xBC,0x98,0x04,0xF1,0x74,0x6C,0x08,
817 0xCA,0x18,0x21,0x7C,0x32,0x90,0x5E,0x46,0x2E,0x36,0xCE,0x3B,
818 0xE3,0x9E,0x77,0x2C,0x18,0x0E,0x86,0x03,0x9B,0x27,0x83,0xA2,
819 0xEC,0x07,0xA2,0x8F,0xB5,0xC5,0x5D,0xF0,0x6F,0x4C,0x52,0xC9,
820 0xDE,0x2B,0xCB,0xF6,0x95,0x58,0x17,0x18,0x39,0x95,0x49,0x7C,
821 0xEA,0x95,0x6A,0xE5,0x15,0xD2,0x26,0x18,0x98,0xFA,0x05,0x10,
822 0x15,0x72,0x8E,0x5A,0x8A,0xAC,0xAA,0x68,0xFF,0xFF,0xFF,0xFF,
823 0xFF,0xFF,0xFF,0xFF,
824 };
825#endif
826 DH *dh = DH_new();
827 if (dh) {
Lukas Tribus4c0d45a2014-08-18 00:56:32 +0200828#if (OPENSSL_VERSION_NUMBER >= 0x0090801fL && !defined OPENSSL_IS_BORINGSSL)
Remi Gacognef46cd6e2014-06-12 14:58:40 +0200829 dh->p = get_rfc3526_prime_2048(NULL);
830#else
831 dh->p = BN_bin2bn(rfc_3526_prime_2048, sizeof rfc_3526_prime_2048, NULL);
832#endif
833 /* See RFC 3526, Section 3 "2048-bit MODP Group"
834 for the reason why 2 is used as generator.
835 */
836 BN_dec2bn(&dh->g, "2");
837 if (!dh->p || !dh->g) {
838 DH_free(dh);
839 dh = NULL;
840 }
841 }
842 return dh;
843}
844
845static DH *ssl_get_dh_4096(void)
846{
Lukas Tribus4c0d45a2014-08-18 00:56:32 +0200847#if (OPENSSL_VERSION_NUMBER < 0x0090801fL || defined OPENSSL_IS_BORINGSSL)
Remi Gacognef46cd6e2014-06-12 14:58:40 +0200848 static const unsigned char rfc_3526_prime_4096[] = {
849 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xC9,0x0F,0xDA,0xA2,
850 0x21,0x68,0xC2,0x34,0xC4,0xC6,0x62,0x8B,0x80,0xDC,0x1C,0xD1,
851 0x29,0x02,0x4E,0x08,0x8A,0x67,0xCC,0x74,0x02,0x0B,0xBE,0xA6,
852 0x3B,0x13,0x9B,0x22,0x51,0x4A,0x08,0x79,0x8E,0x34,0x04,0xDD,
853 0xEF,0x95,0x19,0xB3,0xCD,0x3A,0x43,0x1B,0x30,0x2B,0x0A,0x6D,
854 0xF2,0x5F,0x14,0x37,0x4F,0xE1,0x35,0x6D,0x6D,0x51,0xC2,0x45,
855 0xE4,0x85,0xB5,0x76,0x62,0x5E,0x7E,0xC6,0xF4,0x4C,0x42,0xE9,
856 0xA6,0x37,0xED,0x6B,0x0B,0xFF,0x5C,0xB6,0xF4,0x06,0xB7,0xED,
857 0xEE,0x38,0x6B,0xFB,0x5A,0x89,0x9F,0xA5,0xAE,0x9F,0x24,0x11,
858 0x7C,0x4B,0x1F,0xE6,0x49,0x28,0x66,0x51,0xEC,0xE4,0x5B,0x3D,
859 0xC2,0x00,0x7C,0xB8,0xA1,0x63,0xBF,0x05,0x98,0xDA,0x48,0x36,
860 0x1C,0x55,0xD3,0x9A,0x69,0x16,0x3F,0xA8,0xFD,0x24,0xCF,0x5F,
861 0x83,0x65,0x5D,0x23,0xDC,0xA3,0xAD,0x96,0x1C,0x62,0xF3,0x56,
862 0x20,0x85,0x52,0xBB,0x9E,0xD5,0x29,0x07,0x70,0x96,0x96,0x6D,
863 0x67,0x0C,0x35,0x4E,0x4A,0xBC,0x98,0x04,0xF1,0x74,0x6C,0x08,
864 0xCA,0x18,0x21,0x7C,0x32,0x90,0x5E,0x46,0x2E,0x36,0xCE,0x3B,
865 0xE3,0x9E,0x77,0x2C,0x18,0x0E,0x86,0x03,0x9B,0x27,0x83,0xA2,
866 0xEC,0x07,0xA2,0x8F,0xB5,0xC5,0x5D,0xF0,0x6F,0x4C,0x52,0xC9,
867 0xDE,0x2B,0xCB,0xF6,0x95,0x58,0x17,0x18,0x39,0x95,0x49,0x7C,
868 0xEA,0x95,0x6A,0xE5,0x15,0xD2,0x26,0x18,0x98,0xFA,0x05,0x10,
869 0x15,0x72,0x8E,0x5A,0x8A,0xAA,0xC4,0x2D,0xAD,0x33,0x17,0x0D,
870 0x04,0x50,0x7A,0x33,0xA8,0x55,0x21,0xAB,0xDF,0x1C,0xBA,0x64,
871 0xEC,0xFB,0x85,0x04,0x58,0xDB,0xEF,0x0A,0x8A,0xEA,0x71,0x57,
872 0x5D,0x06,0x0C,0x7D,0xB3,0x97,0x0F,0x85,0xA6,0xE1,0xE4,0xC7,
873 0xAB,0xF5,0xAE,0x8C,0xDB,0x09,0x33,0xD7,0x1E,0x8C,0x94,0xE0,
874 0x4A,0x25,0x61,0x9D,0xCE,0xE3,0xD2,0x26,0x1A,0xD2,0xEE,0x6B,
875 0xF1,0x2F,0xFA,0x06,0xD9,0x8A,0x08,0x64,0xD8,0x76,0x02,0x73,
876 0x3E,0xC8,0x6A,0x64,0x52,0x1F,0x2B,0x18,0x17,0x7B,0x20,0x0C,
877 0xBB,0xE1,0x17,0x57,0x7A,0x61,0x5D,0x6C,0x77,0x09,0x88,0xC0,
878 0xBA,0xD9,0x46,0xE2,0x08,0xE2,0x4F,0xA0,0x74,0xE5,0xAB,0x31,
879 0x43,0xDB,0x5B,0xFC,0xE0,0xFD,0x10,0x8E,0x4B,0x82,0xD1,0x20,
880 0xA9,0x21,0x08,0x01,0x1A,0x72,0x3C,0x12,0xA7,0x87,0xE6,0xD7,
881 0x88,0x71,0x9A,0x10,0xBD,0xBA,0x5B,0x26,0x99,0xC3,0x27,0x18,
882 0x6A,0xF4,0xE2,0x3C,0x1A,0x94,0x68,0x34,0xB6,0x15,0x0B,0xDA,
883 0x25,0x83,0xE9,0xCA,0x2A,0xD4,0x4C,0xE8,0xDB,0xBB,0xC2,0xDB,
884 0x04,0xDE,0x8E,0xF9,0x2E,0x8E,0xFC,0x14,0x1F,0xBE,0xCA,0xA6,
885 0x28,0x7C,0x59,0x47,0x4E,0x6B,0xC0,0x5D,0x99,0xB2,0x96,0x4F,
886 0xA0,0x90,0xC3,0xA2,0x23,0x3B,0xA1,0x86,0x51,0x5B,0xE7,0xED,
887 0x1F,0x61,0x29,0x70,0xCE,0xE2,0xD7,0xAF,0xB8,0x1B,0xDD,0x76,
888 0x21,0x70,0x48,0x1C,0xD0,0x06,0x91,0x27,0xD5,0xB0,0x5A,0xA9,
889 0x93,0xB4,0xEA,0x98,0x8D,0x8F,0xDD,0xC1,0x86,0xFF,0xB7,0xDC,
890 0x90,0xA6,0xC0,0x8F,0x4D,0xF4,0x35,0xC9,0x34,0x06,0x31,0x99,
891 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
892 };
893#endif
894 DH *dh = DH_new();
895 if (dh) {
Lukas Tribus4c0d45a2014-08-18 00:56:32 +0200896#if (OPENSSL_VERSION_NUMBER >= 0x0090801fL && !defined OPENSSL_IS_BORINGSSL)
Remi Gacognef46cd6e2014-06-12 14:58:40 +0200897 dh->p = get_rfc3526_prime_4096(NULL);
898#else
899 dh->p = BN_bin2bn(rfc_3526_prime_4096, sizeof rfc_3526_prime_4096, NULL);
900#endif
901 /* See RFC 3526, Section 5 "4096-bit MODP Group"
902 for the reason why 2 is used as generator.
903 */
904 BN_dec2bn(&dh->g, "2");
905 if (!dh->p || !dh->g) {
906 DH_free(dh);
907 dh = NULL;
908 }
909 }
910 return dh;
911}
912
913static DH *ssl_get_dh_8192(void)
914{
Lukas Tribus4c0d45a2014-08-18 00:56:32 +0200915#if (OPENSSL_VERSION_NUMBER < 0x0090801fL || defined OPENSSL_IS_BORINGSSL)
Remi Gacognef46cd6e2014-06-12 14:58:40 +0200916 static const unsigned char rfc_3526_prime_8192[] = {
917 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xC9,0x0F,0xDA,0xA2,
918 0x21,0x68,0xC2,0x34,0xC4,0xC6,0x62,0x8B,0x80,0xDC,0x1C,0xD1,
919 0x29,0x02,0x4E,0x08,0x8A,0x67,0xCC,0x74,0x02,0x0B,0xBE,0xA6,
920 0x3B,0x13,0x9B,0x22,0x51,0x4A,0x08,0x79,0x8E,0x34,0x04,0xDD,
921 0xEF,0x95,0x19,0xB3,0xCD,0x3A,0x43,0x1B,0x30,0x2B,0x0A,0x6D,
922 0xF2,0x5F,0x14,0x37,0x4F,0xE1,0x35,0x6D,0x6D,0x51,0xC2,0x45,
923 0xE4,0x85,0xB5,0x76,0x62,0x5E,0x7E,0xC6,0xF4,0x4C,0x42,0xE9,
924 0xA6,0x37,0xED,0x6B,0x0B,0xFF,0x5C,0xB6,0xF4,0x06,0xB7,0xED,
925 0xEE,0x38,0x6B,0xFB,0x5A,0x89,0x9F,0xA5,0xAE,0x9F,0x24,0x11,
926 0x7C,0x4B,0x1F,0xE6,0x49,0x28,0x66,0x51,0xEC,0xE4,0x5B,0x3D,
927 0xC2,0x00,0x7C,0xB8,0xA1,0x63,0xBF,0x05,0x98,0xDA,0x48,0x36,
928 0x1C,0x55,0xD3,0x9A,0x69,0x16,0x3F,0xA8,0xFD,0x24,0xCF,0x5F,
929 0x83,0x65,0x5D,0x23,0xDC,0xA3,0xAD,0x96,0x1C,0x62,0xF3,0x56,
930 0x20,0x85,0x52,0xBB,0x9E,0xD5,0x29,0x07,0x70,0x96,0x96,0x6D,
931 0x67,0x0C,0x35,0x4E,0x4A,0xBC,0x98,0x04,0xF1,0x74,0x6C,0x08,
932 0xCA,0x18,0x21,0x7C,0x32,0x90,0x5E,0x46,0x2E,0x36,0xCE,0x3B,
933 0xE3,0x9E,0x77,0x2C,0x18,0x0E,0x86,0x03,0x9B,0x27,0x83,0xA2,
934 0xEC,0x07,0xA2,0x8F,0xB5,0xC5,0x5D,0xF0,0x6F,0x4C,0x52,0xC9,
935 0xDE,0x2B,0xCB,0xF6,0x95,0x58,0x17,0x18,0x39,0x95,0x49,0x7C,
936 0xEA,0x95,0x6A,0xE5,0x15,0xD2,0x26,0x18,0x98,0xFA,0x05,0x10,
937 0x15,0x72,0x8E,0x5A,0x8A,0xAA,0xC4,0x2D,0xAD,0x33,0x17,0x0D,
938 0x04,0x50,0x7A,0x33,0xA8,0x55,0x21,0xAB,0xDF,0x1C,0xBA,0x64,
939 0xEC,0xFB,0x85,0x04,0x58,0xDB,0xEF,0x0A,0x8A,0xEA,0x71,0x57,
940 0x5D,0x06,0x0C,0x7D,0xB3,0x97,0x0F,0x85,0xA6,0xE1,0xE4,0xC7,
941 0xAB,0xF5,0xAE,0x8C,0xDB,0x09,0x33,0xD7,0x1E,0x8C,0x94,0xE0,
942 0x4A,0x25,0x61,0x9D,0xCE,0xE3,0xD2,0x26,0x1A,0xD2,0xEE,0x6B,
943 0xF1,0x2F,0xFA,0x06,0xD9,0x8A,0x08,0x64,0xD8,0x76,0x02,0x73,
944 0x3E,0xC8,0x6A,0x64,0x52,0x1F,0x2B,0x18,0x17,0x7B,0x20,0x0C,
945 0xBB,0xE1,0x17,0x57,0x7A,0x61,0x5D,0x6C,0x77,0x09,0x88,0xC0,
946 0xBA,0xD9,0x46,0xE2,0x08,0xE2,0x4F,0xA0,0x74,0xE5,0xAB,0x31,
947 0x43,0xDB,0x5B,0xFC,0xE0,0xFD,0x10,0x8E,0x4B,0x82,0xD1,0x20,
948 0xA9,0x21,0x08,0x01,0x1A,0x72,0x3C,0x12,0xA7,0x87,0xE6,0xD7,
949 0x88,0x71,0x9A,0x10,0xBD,0xBA,0x5B,0x26,0x99,0xC3,0x27,0x18,
950 0x6A,0xF4,0xE2,0x3C,0x1A,0x94,0x68,0x34,0xB6,0x15,0x0B,0xDA,
951 0x25,0x83,0xE9,0xCA,0x2A,0xD4,0x4C,0xE8,0xDB,0xBB,0xC2,0xDB,
952 0x04,0xDE,0x8E,0xF9,0x2E,0x8E,0xFC,0x14,0x1F,0xBE,0xCA,0xA6,
953 0x28,0x7C,0x59,0x47,0x4E,0x6B,0xC0,0x5D,0x99,0xB2,0x96,0x4F,
954 0xA0,0x90,0xC3,0xA2,0x23,0x3B,0xA1,0x86,0x51,0x5B,0xE7,0xED,
955 0x1F,0x61,0x29,0x70,0xCE,0xE2,0xD7,0xAF,0xB8,0x1B,0xDD,0x76,
956 0x21,0x70,0x48,0x1C,0xD0,0x06,0x91,0x27,0xD5,0xB0,0x5A,0xA9,
957 0x93,0xB4,0xEA,0x98,0x8D,0x8F,0xDD,0xC1,0x86,0xFF,0xB7,0xDC,
958 0x90,0xA6,0xC0,0x8F,0x4D,0xF4,0x35,0xC9,0x34,0x02,0x84,0x92,
959 0x36,0xC3,0xFA,0xB4,0xD2,0x7C,0x70,0x26,0xC1,0xD4,0xDC,0xB2,
960 0x60,0x26,0x46,0xDE,0xC9,0x75,0x1E,0x76,0x3D,0xBA,0x37,0xBD,
961 0xF8,0xFF,0x94,0x06,0xAD,0x9E,0x53,0x0E,0xE5,0xDB,0x38,0x2F,
962 0x41,0x30,0x01,0xAE,0xB0,0x6A,0x53,0xED,0x90,0x27,0xD8,0x31,
963 0x17,0x97,0x27,0xB0,0x86,0x5A,0x89,0x18,0xDA,0x3E,0xDB,0xEB,
964 0xCF,0x9B,0x14,0xED,0x44,0xCE,0x6C,0xBA,0xCE,0xD4,0xBB,0x1B,
965 0xDB,0x7F,0x14,0x47,0xE6,0xCC,0x25,0x4B,0x33,0x20,0x51,0x51,
966 0x2B,0xD7,0xAF,0x42,0x6F,0xB8,0xF4,0x01,0x37,0x8C,0xD2,0xBF,
967 0x59,0x83,0xCA,0x01,0xC6,0x4B,0x92,0xEC,0xF0,0x32,0xEA,0x15,
968 0xD1,0x72,0x1D,0x03,0xF4,0x82,0xD7,0xCE,0x6E,0x74,0xFE,0xF6,
969 0xD5,0x5E,0x70,0x2F,0x46,0x98,0x0C,0x82,0xB5,0xA8,0x40,0x31,
970 0x90,0x0B,0x1C,0x9E,0x59,0xE7,0xC9,0x7F,0xBE,0xC7,0xE8,0xF3,
971 0x23,0xA9,0x7A,0x7E,0x36,0xCC,0x88,0xBE,0x0F,0x1D,0x45,0xB7,
972 0xFF,0x58,0x5A,0xC5,0x4B,0xD4,0x07,0xB2,0x2B,0x41,0x54,0xAA,
973 0xCC,0x8F,0x6D,0x7E,0xBF,0x48,0xE1,0xD8,0x14,0xCC,0x5E,0xD2,
974 0x0F,0x80,0x37,0xE0,0xA7,0x97,0x15,0xEE,0xF2,0x9B,0xE3,0x28,
975 0x06,0xA1,0xD5,0x8B,0xB7,0xC5,0xDA,0x76,0xF5,0x50,0xAA,0x3D,
976 0x8A,0x1F,0xBF,0xF0,0xEB,0x19,0xCC,0xB1,0xA3,0x13,0xD5,0x5C,
977 0xDA,0x56,0xC9,0xEC,0x2E,0xF2,0x96,0x32,0x38,0x7F,0xE8,0xD7,
978 0x6E,0x3C,0x04,0x68,0x04,0x3E,0x8F,0x66,0x3F,0x48,0x60,0xEE,
979 0x12,0xBF,0x2D,0x5B,0x0B,0x74,0x74,0xD6,0xE6,0x94,0xF9,0x1E,
980 0x6D,0xBE,0x11,0x59,0x74,0xA3,0x92,0x6F,0x12,0xFE,0xE5,0xE4,
981 0x38,0x77,0x7C,0xB6,0xA9,0x32,0xDF,0x8C,0xD8,0xBE,0xC4,0xD0,
982 0x73,0xB9,0x31,0xBA,0x3B,0xC8,0x32,0xB6,0x8D,0x9D,0xD3,0x00,
983 0x74,0x1F,0xA7,0xBF,0x8A,0xFC,0x47,0xED,0x25,0x76,0xF6,0x93,
984 0x6B,0xA4,0x24,0x66,0x3A,0xAB,0x63,0x9C,0x5A,0xE4,0xF5,0x68,
985 0x34,0x23,0xB4,0x74,0x2B,0xF1,0xC9,0x78,0x23,0x8F,0x16,0xCB,
986 0xE3,0x9D,0x65,0x2D,0xE3,0xFD,0xB8,0xBE,0xFC,0x84,0x8A,0xD9,
987 0x22,0x22,0x2E,0x04,0xA4,0x03,0x7C,0x07,0x13,0xEB,0x57,0xA8,
988 0x1A,0x23,0xF0,0xC7,0x34,0x73,0xFC,0x64,0x6C,0xEA,0x30,0x6B,
989 0x4B,0xCB,0xC8,0x86,0x2F,0x83,0x85,0xDD,0xFA,0x9D,0x4B,0x7F,
990 0xA2,0xC0,0x87,0xE8,0x79,0x68,0x33,0x03,0xED,0x5B,0xDD,0x3A,
991 0x06,0x2B,0x3C,0xF5,0xB3,0xA2,0x78,0xA6,0x6D,0x2A,0x13,0xF8,
992 0x3F,0x44,0xF8,0x2D,0xDF,0x31,0x0E,0xE0,0x74,0xAB,0x6A,0x36,
993 0x45,0x97,0xE8,0x99,0xA0,0x25,0x5D,0xC1,0x64,0xF3,0x1C,0xC5,
994 0x08,0x46,0x85,0x1D,0xF9,0xAB,0x48,0x19,0x5D,0xED,0x7E,0xA1,
995 0xB1,0xD5,0x10,0xBD,0x7E,0xE7,0x4D,0x73,0xFA,0xF3,0x6B,0xC3,
996 0x1E,0xCF,0xA2,0x68,0x35,0x90,0x46,0xF4,0xEB,0x87,0x9F,0x92,
997 0x40,0x09,0x43,0x8B,0x48,0x1C,0x6C,0xD7,0x88,0x9A,0x00,0x2E,
998 0xD5,0xEE,0x38,0x2B,0xC9,0x19,0x0D,0xA6,0xFC,0x02,0x6E,0x47,
999 0x95,0x58,0xE4,0x47,0x56,0x77,0xE9,0xAA,0x9E,0x30,0x50,0xE2,
1000 0x76,0x56,0x94,0xDF,0xC8,0x1F,0x56,0xE8,0x80,0xB9,0x6E,0x71,
1001 0x60,0xC9,0x80,0xDD,0x98,0xED,0xD3,0xDF,0xFF,0xFF,0xFF,0xFF,
1002 0xFF,0xFF,0xFF,0xFF,
1003 };
1004#endif
1005 DH *dh = DH_new();
1006 if (dh) {
Lukas Tribus4c0d45a2014-08-18 00:56:32 +02001007#if (OPENSSL_VERSION_NUMBER >= 0x0090801fL && !defined OPENSSL_IS_BORINGSSL)
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001008 dh->p = get_rfc3526_prime_8192(NULL);
1009#else
1010 dh->p = BN_bin2bn(rfc_3526_prime_8192, sizeof rfc_3526_prime_8192, NULL);
1011#endif
1012 /* See RFC 3526, Section 7 "8192-bit MODP Group"
1013 for the reason why 2 is used as generator.
1014 */
1015 BN_dec2bn(&dh->g, "2");
1016 if (!dh->p || !dh->g) {
1017 DH_free(dh);
1018 dh = NULL;
1019 }
1020 }
1021 return dh;
1022}
1023
1024/* Returns Diffie-Hellman parameters matching the private key length
1025 but not exceeding global.tune.ssl_default_dh_param */
1026static DH *ssl_get_tmp_dh(SSL *ssl, int export, int keylen)
1027{
1028 DH *dh = NULL;
1029 EVP_PKEY *pkey = SSL_get_privatekey(ssl);
1030 int type = pkey ? EVP_PKEY_type(pkey->type) : EVP_PKEY_NONE;
1031
1032 /* The keylen supplied by OpenSSL can only be 512 or 1024.
1033 See ssl3_send_server_key_exchange() in ssl/s3_srvr.c
1034 */
1035 if (type == EVP_PKEY_RSA || type == EVP_PKEY_DSA) {
1036 keylen = EVP_PKEY_bits(pkey);
1037 }
1038
1039 if (keylen > global.tune.ssl_default_dh_param) {
1040 keylen = global.tune.ssl_default_dh_param;
1041 }
1042
1043 if (keylen >= 8192) {
Remi Gacogne8de54152014-07-15 11:36:40 +02001044 dh = local_dh_8192;
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001045 }
1046 else if (keylen >= 4096) {
Remi Gacogne8de54152014-07-15 11:36:40 +02001047 dh = local_dh_4096;
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001048 }
1049 else if (keylen >= 2048) {
Remi Gacogne8de54152014-07-15 11:36:40 +02001050 dh = local_dh_2048;
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001051 }
1052 else {
Remi Gacogne8de54152014-07-15 11:36:40 +02001053 dh = local_dh_1024;
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001054 }
1055
1056 return dh;
1057}
1058
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001059/* Loads Diffie-Hellman parameter from a file. Returns 1 if loaded, else -1
1060 if an error occured, and 0 if parameter not found. */
Willy Tarreau6e774b42014-04-25 21:35:23 +02001061int ssl_sock_load_dh_params(SSL_CTX *ctx, const char *file)
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001062{
1063 int ret = -1;
1064 BIO *in;
1065 DH *dh = NULL;
1066
1067 in = BIO_new(BIO_s_file());
1068 if (in == NULL)
1069 goto end;
1070
1071 if (BIO_read_filename(in, file) <= 0)
1072 goto end;
1073
1074 dh = PEM_read_bio_DHparams(in, NULL, ctx->default_passwd_callback, ctx->default_passwd_callback_userdata);
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001075 if (dh) {
1076 ret = 1;
1077 SSL_CTX_set_tmp_dh(ctx, dh);
1078 /* Setting ssl default dh param to the size of the static DH params
1079 found in the file. This way we know that there is no use
1080 complaining later about ssl-default-dh-param not being set. */
1081 global.tune.ssl_default_dh_param = DH_size(dh) * 8;
1082 }
1083 else {
Emeric Brun41fdb3c2013-04-26 11:05:44 +02001084 /* Clear openssl global errors stack */
1085 ERR_clear_error();
1086
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001087 if (global.tune.ssl_default_dh_param <= 1024) {
1088 /* we are limited to DH parameter of 1024 bits anyway */
Remi Gacogne8de54152014-07-15 11:36:40 +02001089 local_dh_1024 = ssl_get_dh_1024();
1090 if (local_dh_1024 == NULL)
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001091 goto end;
Willy Tarreau6e774b42014-04-25 21:35:23 +02001092
Remi Gacogne8de54152014-07-15 11:36:40 +02001093 SSL_CTX_set_tmp_dh(ctx, local_dh_1024);
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001094 }
1095 else {
1096 SSL_CTX_set_tmp_dh_callback(ctx, ssl_get_tmp_dh);
1097 }
Willy Tarreau6e774b42014-04-25 21:35:23 +02001098
Emeric Brun41fdb3c2013-04-26 11:05:44 +02001099 ret = 0; /* DH params not found */
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001100 }
Emeric Brun644cde02012-12-14 11:21:13 +01001101
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001102end:
1103 if (dh)
1104 DH_free(dh);
1105
1106 if (in)
Emeric Brun41fdb3c2013-04-26 11:05:44 +02001107 BIO_free(in);
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001108
1109 return ret;
1110}
1111#endif
1112
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001113static int ssl_sock_add_cert_sni(SSL_CTX *ctx, struct bind_conf *s, char *name, int order)
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001114{
1115 struct sni_ctx *sc;
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001116 int wild = 0, neg = 0;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001117
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001118 if (*name == '!') {
1119 neg = 1;
1120 name++;
1121 }
1122 if (*name == '*') {
1123 wild = 1;
1124 name++;
1125 }
1126 /* !* filter is a nop */
1127 if (neg && wild)
1128 return order;
1129 if (*name) {
1130 int j, len;
1131 len = strlen(name);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001132 sc = malloc(sizeof(struct sni_ctx) + len + 1);
1133 for (j = 0; j < len; j++)
1134 sc->name.key[j] = tolower(name[j]);
1135 sc->name.key[len] = 0;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001136 sc->ctx = ctx;
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001137 sc->order = order++;
1138 sc->neg = neg;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001139 if (wild)
1140 ebst_insert(&s->sni_w_ctx, &sc->name);
1141 else
1142 ebst_insert(&s->sni_ctx, &sc->name);
1143 }
1144 return order;
1145}
1146
Emeric Brunfc0421f2012-09-07 17:30:07 +02001147/* Loads a certificate key and CA chain from a file. Returns 0 on error, -1 if
1148 * an early error happens and the caller must call SSL_CTX_free() by itelf.
1149 */
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001150static 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 +02001151{
1152 BIO *in;
1153 X509 *x = NULL, *ca;
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001154 int i, err;
Emeric Brunfc0421f2012-09-07 17:30:07 +02001155 int ret = -1;
1156 int order = 0;
1157 X509_NAME *xname;
1158 char *str;
Emeric Brunfc0421f2012-09-07 17:30:07 +02001159#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
1160 STACK_OF(GENERAL_NAME) *names;
1161#endif
1162
1163 in = BIO_new(BIO_s_file());
1164 if (in == NULL)
1165 goto end;
1166
1167 if (BIO_read_filename(in, file) <= 0)
1168 goto end;
1169
1170 x = PEM_read_bio_X509_AUX(in, NULL, ctx->default_passwd_callback, ctx->default_passwd_callback_userdata);
1171 if (x == NULL)
1172 goto end;
1173
Emeric Brun50bcecc2013-04-22 13:05:23 +02001174 if (fcount) {
1175 while (fcount--)
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001176 order = ssl_sock_add_cert_sni(ctx, s, sni_filter[fcount], order);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001177 }
1178 else {
Emeric Brunfc0421f2012-09-07 17:30:07 +02001179#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001180 names = X509_get_ext_d2i(x, NID_subject_alt_name, NULL, NULL);
1181 if (names) {
1182 for (i = 0; i < sk_GENERAL_NAME_num(names); i++) {
1183 GENERAL_NAME *name = sk_GENERAL_NAME_value(names, i);
1184 if (name->type == GEN_DNS) {
1185 if (ASN1_STRING_to_UTF8((unsigned char **)&str, name->d.dNSName) >= 0) {
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001186 order = ssl_sock_add_cert_sni(ctx, s, str, order);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001187 OPENSSL_free(str);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001188 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02001189 }
1190 }
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001191 sk_GENERAL_NAME_pop_free(names, GENERAL_NAME_free);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001192 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02001193#endif /* SSL_CTRL_SET_TLSEXT_HOSTNAME */
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001194 xname = X509_get_subject_name(x);
1195 i = -1;
1196 while ((i = X509_NAME_get_index_by_NID(xname, NID_commonName, i)) != -1) {
1197 X509_NAME_ENTRY *entry = X509_NAME_get_entry(xname, i);
1198 if (ASN1_STRING_to_UTF8((unsigned char **)&str, entry->value) >= 0) {
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001199 order = ssl_sock_add_cert_sni(ctx, s, str, order);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001200 OPENSSL_free(str);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001201 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02001202 }
1203 }
1204
1205 ret = 0; /* the caller must not free the SSL_CTX argument anymore */
1206 if (!SSL_CTX_use_certificate(ctx, x))
1207 goto end;
1208
1209 if (ctx->extra_certs != NULL) {
1210 sk_X509_pop_free(ctx->extra_certs, X509_free);
1211 ctx->extra_certs = NULL;
1212 }
1213
1214 while ((ca = PEM_read_bio_X509(in, NULL, ctx->default_passwd_callback, ctx->default_passwd_callback_userdata))) {
1215 if (!SSL_CTX_add_extra_chain_cert(ctx, ca)) {
1216 X509_free(ca);
1217 goto end;
1218 }
1219 }
1220
1221 err = ERR_get_error();
1222 if (!err || (ERR_GET_LIB(err) == ERR_LIB_PEM && ERR_GET_REASON(err) == PEM_R_NO_START_LINE)) {
1223 /* we successfully reached the last cert in the file */
1224 ret = 1;
1225 }
1226 ERR_clear_error();
1227
1228end:
1229 if (x)
1230 X509_free(x);
1231
1232 if (in)
1233 BIO_free(in);
1234
1235 return ret;
1236}
1237
Emeric Brun50bcecc2013-04-22 13:05:23 +02001238static 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 +02001239{
1240 int ret;
1241 SSL_CTX *ctx;
1242
1243 ctx = SSL_CTX_new(SSLv23_server_method());
1244 if (!ctx) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02001245 memprintf(err, "%sunable to allocate SSL context for cert '%s'.\n",
1246 err && *err ? *err : "", path);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001247 return 1;
1248 }
1249
1250 if (SSL_CTX_use_PrivateKey_file(ctx, path, SSL_FILETYPE_PEM) <= 0) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02001251 memprintf(err, "%sunable to load SSL private key from PEM file '%s'.\n",
1252 err && *err ? *err : "", path);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001253 SSL_CTX_free(ctx);
1254 return 1;
1255 }
1256
Emeric Brun50bcecc2013-04-22 13:05:23 +02001257 ret = ssl_sock_load_cert_chain_file(ctx, path, bind_conf, sni_filter, fcount);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001258 if (ret <= 0) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02001259 memprintf(err, "%sunable to load SSL certificate from PEM file '%s'.\n",
1260 err && *err ? *err : "", path);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001261 if (ret < 0) /* serious error, must do that ourselves */
1262 SSL_CTX_free(ctx);
1263 return 1;
1264 }
Emeric Brun61694ab2012-10-26 13:35:33 +02001265
1266 if (SSL_CTX_check_private_key(ctx) <= 0) {
1267 memprintf(err, "%sinconsistencies between private key and certificate loaded from PEM file '%s'.\n",
1268 err && *err ? *err : "", path);
1269 return 1;
1270 }
1271
Emeric Brunfc0421f2012-09-07 17:30:07 +02001272 /* we must not free the SSL_CTX anymore below, since it's already in
1273 * the tree, so it will be discovered and cleaned in time.
1274 */
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001275#ifndef OPENSSL_NO_DH
1276 ret = ssl_sock_load_dh_params(ctx, path);
1277 if (ret < 0) {
1278 if (err)
1279 memprintf(err, "%sunable to load DH parameters from file '%s'.\n",
1280 *err ? *err : "", path);
1281 return 1;
1282 }
1283#endif
1284
Lukas Tribus656c5fa2014-08-18 00:56:31 +02001285#if (defined SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB && !defined OPENSSL_IS_BORINGSSL)
Emeric Brun4147b2e2014-06-16 18:36:30 +02001286 ret = ssl_sock_load_ocsp(ctx, path);
1287 if (ret < 0) {
1288 if (err)
1289 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",
1290 *err ? *err : "", path);
1291 return 1;
1292 }
1293#endif
1294
Emeric Brunfc0421f2012-09-07 17:30:07 +02001295#ifndef SSL_CTRL_SET_TLSEXT_HOSTNAME
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001296 if (bind_conf->default_ctx) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02001297 memprintf(err, "%sthis version of openssl cannot load multiple SSL certificates.\n",
1298 err && *err ? *err : "");
Emeric Brunfc0421f2012-09-07 17:30:07 +02001299 return 1;
1300 }
1301#endif
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001302 if (!bind_conf->default_ctx)
1303 bind_conf->default_ctx = ctx;
Emeric Brunfc0421f2012-09-07 17:30:07 +02001304
1305 return 0;
1306}
1307
Willy Tarreau79eeafa2012-09-14 07:53:05 +02001308int ssl_sock_load_cert(char *path, struct bind_conf *bind_conf, struct proxy *curproxy, char **err)
Emeric Brunfc0421f2012-09-07 17:30:07 +02001309{
1310 struct dirent *de;
1311 DIR *dir;
1312 struct stat buf;
Willy Tarreauee2663b2012-12-06 11:36:59 +01001313 char *end;
1314 char fp[MAXPATHLEN+1];
Emeric Brunfc0421f2012-09-07 17:30:07 +02001315 int cfgerr = 0;
1316
1317 if (!(dir = opendir(path)))
Emeric Brun50bcecc2013-04-22 13:05:23 +02001318 return ssl_sock_load_cert_file(path, bind_conf, curproxy, NULL, 0, err);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001319
1320 /* strip trailing slashes, including first one */
1321 for (end = path + strlen(path) - 1; end >= path && *end == '/'; end--)
1322 *end = 0;
1323
Emeric Brunfc0421f2012-09-07 17:30:07 +02001324 while ((de = readdir(dir))) {
Emeric Brun2aab7222014-06-18 18:15:09 +02001325 end = strrchr(de->d_name, '.');
1326 if (end && (!strcmp(end, ".issuer") || !strcmp(end, ".ocsp")))
1327 continue;
1328
Willy Tarreauee2663b2012-12-06 11:36:59 +01001329 snprintf(fp, sizeof(fp), "%s/%s", path, de->d_name);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001330 if (stat(fp, &buf) != 0) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02001331 memprintf(err, "%sunable to stat SSL certificate from file '%s' : %s.\n",
1332 err && *err ? *err : "", fp, strerror(errno));
Emeric Brunfc0421f2012-09-07 17:30:07 +02001333 cfgerr++;
1334 continue;
1335 }
1336 if (!S_ISREG(buf.st_mode))
1337 continue;
Emeric Brun50bcecc2013-04-22 13:05:23 +02001338 cfgerr += ssl_sock_load_cert_file(fp, bind_conf, curproxy, NULL, 0, err);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001339 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02001340 closedir(dir);
1341 return cfgerr;
1342}
1343
Thierry Fournier383085f2013-01-24 14:15:43 +01001344/* Make sure openssl opens /dev/urandom before the chroot. The work is only
1345 * done once. Zero is returned if the operation fails. No error is returned
1346 * if the random is said as not implemented, because we expect that openssl
1347 * will use another method once needed.
1348 */
1349static int ssl_initialize_random()
1350{
1351 unsigned char random;
1352 static int random_initialized = 0;
1353
1354 if (!random_initialized && RAND_bytes(&random, 1) != 0)
1355 random_initialized = 1;
1356
1357 return random_initialized;
1358}
1359
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001360int ssl_sock_load_cert_list_file(char *file, struct bind_conf *bind_conf, struct proxy *curproxy, char **err)
1361{
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001362 char thisline[LINESIZE];
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001363 FILE *f;
1364 int linenum = 0;
1365 int cfgerr = 0;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001366
Willy Tarreauad1731d2013-04-02 17:35:58 +02001367 if ((f = fopen(file, "r")) == NULL) {
1368 memprintf(err, "cannot open file '%s' : %s", file, strerror(errno));
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001369 return 1;
Willy Tarreauad1731d2013-04-02 17:35:58 +02001370 }
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001371
1372 while (fgets(thisline, sizeof(thisline), f) != NULL) {
1373 int arg;
Emeric Brun50bcecc2013-04-22 13:05:23 +02001374 int newarg;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001375 char *end;
1376 char *args[MAX_LINE_ARGS + 1];
1377 char *line = thisline;
1378
1379 linenum++;
1380 end = line + strlen(line);
1381 if (end-line == sizeof(thisline)-1 && *(end-1) != '\n') {
1382 /* Check if we reached the limit and the last char is not \n.
1383 * Watch out for the last line without the terminating '\n'!
1384 */
Willy Tarreauad1731d2013-04-02 17:35:58 +02001385 memprintf(err, "line %d too long in file '%s', limit is %d characters",
1386 linenum, file, (int)sizeof(thisline)-1);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001387 cfgerr = 1;
Willy Tarreauad1731d2013-04-02 17:35:58 +02001388 break;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001389 }
1390
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001391 arg = 0;
Emeric Brun50bcecc2013-04-22 13:05:23 +02001392 newarg = 1;
1393 while (*line) {
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001394 if (*line == '#' || *line == '\n' || *line == '\r') {
1395 /* end of string, end of loop */
1396 *line = 0;
1397 break;
1398 }
1399 else if (isspace(*line)) {
Emeric Brun50bcecc2013-04-22 13:05:23 +02001400 newarg = 1;
1401 *line = 0;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001402 }
Emeric Brun50bcecc2013-04-22 13:05:23 +02001403 else if (newarg) {
1404 if (arg == MAX_LINE_ARGS) {
1405 memprintf(err, "too many args on line %d in file '%s'.",
1406 linenum, file);
1407 cfgerr = 1;
1408 break;
1409 }
1410 newarg = 0;
1411 args[arg++] = line;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001412 }
Emeric Brun50bcecc2013-04-22 13:05:23 +02001413 line++;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001414 }
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001415 if (cfgerr)
1416 break;
Willy Tarreauad1731d2013-04-02 17:35:58 +02001417
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001418 /* empty line */
Emeric Brun50bcecc2013-04-22 13:05:23 +02001419 if (!arg)
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001420 continue;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001421
Emeric Brun50bcecc2013-04-22 13:05:23 +02001422 cfgerr = ssl_sock_load_cert_file(args[0], bind_conf, curproxy, &args[1], arg-1, err);
Willy Tarreauad1731d2013-04-02 17:35:58 +02001423 if (cfgerr) {
1424 memprintf(err, "error processing line %d in file '%s' : %s", linenum, file, *err);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001425 break;
Willy Tarreauad1731d2013-04-02 17:35:58 +02001426 }
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001427 }
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001428 fclose(f);
1429 return cfgerr;
1430}
1431
Emeric Brunfc0421f2012-09-07 17:30:07 +02001432#ifndef SSL_OP_CIPHER_SERVER_PREFERENCE /* needs OpenSSL >= 0.9.7 */
1433#define SSL_OP_CIPHER_SERVER_PREFERENCE 0
1434#endif
1435
1436#ifndef SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION /* needs OpenSSL >= 0.9.7 */
1437#define SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION 0
Willy Tarreau7d588ee2012-11-26 18:47:31 +01001438#define SSL_renegotiate_pending(arg) 0
Emeric Brunfc0421f2012-09-07 17:30:07 +02001439#endif
Emeric Brun2b58d042012-09-20 17:10:03 +02001440#ifndef SSL_OP_SINGLE_ECDH_USE /* needs OpenSSL >= 0.9.8 */
1441#define SSL_OP_SINGLE_ECDH_USE 0
1442#endif
Emeric Brun2d0c4822012-10-02 13:45:20 +02001443#ifndef SSL_OP_NO_TICKET /* needs OpenSSL >= 0.9.8 */
1444#define SSL_OP_NO_TICKET 0
1445#endif
Emeric Brunfc0421f2012-09-07 17:30:07 +02001446#ifndef SSL_OP_NO_COMPRESSION /* needs OpenSSL >= 0.9.9 */
1447#define SSL_OP_NO_COMPRESSION 0
1448#endif
Emeric Brunc0ff4922012-09-28 19:37:02 +02001449#ifndef SSL_OP_NO_TLSv1_1 /* needs OpenSSL >= 1.0.1 */
1450#define SSL_OP_NO_TLSv1_1 0
1451#endif
1452#ifndef SSL_OP_NO_TLSv1_2 /* needs OpenSSL >= 1.0.1 */
1453#define SSL_OP_NO_TLSv1_2 0
1454#endif
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001455#ifndef SSL_OP_SINGLE_DH_USE /* needs OpenSSL >= 0.9.6 */
1456#define SSL_OP_SINGLE_DH_USE 0
1457#endif
Emeric Brun2b58d042012-09-20 17:10:03 +02001458#ifndef SSL_OP_SINGLE_ECDH_USE /* needs OpenSSL >= 1.0.0 */
1459#define SSL_OP_SINGLE_ECDH_USE 0
1460#endif
Emeric Brunfc0421f2012-09-07 17:30:07 +02001461#ifndef SSL_MODE_RELEASE_BUFFERS /* needs OpenSSL >= 1.0.0 */
1462#define SSL_MODE_RELEASE_BUFFERS 0
1463#endif
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001464
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001465int ssl_sock_prepare_ctx(struct bind_conf *bind_conf, SSL_CTX *ctx, struct proxy *curproxy)
Emeric Brunfc0421f2012-09-07 17:30:07 +02001466{
1467 int cfgerr = 0;
Emeric Brun850efd52014-01-29 12:24:34 +01001468 int verify = SSL_VERIFY_NONE;
Remi Gacogneaf5c3da2014-05-19 10:29:58 +02001469 long ssloptions =
Emeric Brunfc0421f2012-09-07 17:30:07 +02001470 SSL_OP_ALL | /* all known workarounds for bugs */
1471 SSL_OP_NO_SSLv2 |
1472 SSL_OP_NO_COMPRESSION |
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001473 SSL_OP_SINGLE_DH_USE |
Emeric Brun2b58d042012-09-20 17:10:03 +02001474 SSL_OP_SINGLE_ECDH_USE |
Emeric Brun3c4bc6e2012-10-04 18:44:19 +02001475 SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION |
1476 SSL_OP_CIPHER_SERVER_PREFERENCE;
Remi Gacogneaf5c3da2014-05-19 10:29:58 +02001477 long sslmode =
Emeric Brunfc0421f2012-09-07 17:30:07 +02001478 SSL_MODE_ENABLE_PARTIAL_WRITE |
1479 SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER |
1480 SSL_MODE_RELEASE_BUFFERS;
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001481 STACK_OF(SSL_CIPHER) * ciphers = NULL;
Remi Gacogne23d5d372014-10-10 17:04:26 +02001482 SSL_CIPHER const * cipher = NULL;
Remi Gacognec1eab8c2014-06-12 18:20:11 +02001483 char cipher_description[128];
1484 /* The description of ciphers using an Ephemeral Diffie Hellman key exchange
1485 contains " Kx=DH " or " Kx=DH(". Beware of " Kx=DH/",
1486 which is not ephemeral DH. */
1487 const char dhe_description[] = " Kx=DH ";
1488 const char dhe_export_description[] = " Kx=DH(";
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001489 int idx = 0;
1490 int dhe_found = 0;
Remi Gacogne23d5d372014-10-10 17:04:26 +02001491 SSL *ssl = NULL;
Emeric Brunfc0421f2012-09-07 17:30:07 +02001492
Thierry Fournier383085f2013-01-24 14:15:43 +01001493 /* Make sure openssl opens /dev/urandom before the chroot */
1494 if (!ssl_initialize_random()) {
1495 Alert("OpenSSL random data generator initialization failed.\n");
1496 cfgerr++;
1497 }
1498
Emeric Brun89675492012-10-05 13:48:26 +02001499 if (bind_conf->ssl_options & BC_SSL_O_NO_SSLV3)
Emeric Brunfc0421f2012-09-07 17:30:07 +02001500 ssloptions |= SSL_OP_NO_SSLv3;
Emeric Brun89675492012-10-05 13:48:26 +02001501 if (bind_conf->ssl_options & BC_SSL_O_NO_TLSV10)
Emeric Brunfc0421f2012-09-07 17:30:07 +02001502 ssloptions |= SSL_OP_NO_TLSv1;
Emeric Brun89675492012-10-05 13:48:26 +02001503 if (bind_conf->ssl_options & BC_SSL_O_NO_TLSV11)
Emeric Brunc0ff4922012-09-28 19:37:02 +02001504 ssloptions |= SSL_OP_NO_TLSv1_1;
Emeric Brun89675492012-10-05 13:48:26 +02001505 if (bind_conf->ssl_options & BC_SSL_O_NO_TLSV12)
Emeric Brunc0ff4922012-09-28 19:37:02 +02001506 ssloptions |= SSL_OP_NO_TLSv1_2;
Emeric Brun89675492012-10-05 13:48:26 +02001507 if (bind_conf->ssl_options & BC_SSL_O_NO_TLS_TICKETS)
Emeric Brun2d0c4822012-10-02 13:45:20 +02001508 ssloptions |= SSL_OP_NO_TICKET;
Emeric Brun2cb7ae52012-10-05 14:14:21 +02001509 if (bind_conf->ssl_options & BC_SSL_O_USE_SSLV3)
1510 SSL_CTX_set_ssl_version(ctx, SSLv3_server_method());
1511 if (bind_conf->ssl_options & BC_SSL_O_USE_TLSV10)
1512 SSL_CTX_set_ssl_version(ctx, TLSv1_server_method());
1513#if SSL_OP_NO_TLSv1_1
1514 if (bind_conf->ssl_options & BC_SSL_O_USE_TLSV11)
1515 SSL_CTX_set_ssl_version(ctx, TLSv1_1_server_method());
1516#endif
1517#if SSL_OP_NO_TLSv1_2
1518 if (bind_conf->ssl_options & BC_SSL_O_USE_TLSV12)
1519 SSL_CTX_set_ssl_version(ctx, TLSv1_2_server_method());
1520#endif
Emeric Brunfc0421f2012-09-07 17:30:07 +02001521
1522 SSL_CTX_set_options(ctx, ssloptions);
1523 SSL_CTX_set_mode(ctx, sslmode);
Emeric Brun850efd52014-01-29 12:24:34 +01001524 switch (bind_conf->verify) {
1525 case SSL_SOCK_VERIFY_NONE:
1526 verify = SSL_VERIFY_NONE;
1527 break;
1528 case SSL_SOCK_VERIFY_OPTIONAL:
1529 verify = SSL_VERIFY_PEER;
1530 break;
1531 case SSL_SOCK_VERIFY_REQUIRED:
1532 verify = SSL_VERIFY_PEER|SSL_VERIFY_FAIL_IF_NO_PEER_CERT;
1533 break;
1534 }
1535 SSL_CTX_set_verify(ctx, verify, ssl_sock_bind_verifycbk);
1536 if (verify & SSL_VERIFY_PEER) {
Emeric Brunfb510ea2012-10-05 12:00:26 +02001537 if (bind_conf->ca_file) {
Emeric Brund94b3fe2012-09-20 18:23:56 +02001538 /* load CAfile to verify */
Emeric Brunfb510ea2012-10-05 12:00:26 +02001539 if (!SSL_CTX_load_verify_locations(ctx, bind_conf->ca_file, NULL)) {
Emeric Brund94b3fe2012-09-20 18:23:56 +02001540 Alert("Proxy '%s': unable to load CA file '%s' for bind '%s' at [%s:%d].\n",
Emeric Brunfb510ea2012-10-05 12:00:26 +02001541 curproxy->id, bind_conf->ca_file, bind_conf->arg, bind_conf->file, bind_conf->line);
Emeric Brund94b3fe2012-09-20 18:23:56 +02001542 cfgerr++;
1543 }
1544 /* set CA names fo client cert request, function returns void */
Emeric Brunfb510ea2012-10-05 12:00:26 +02001545 SSL_CTX_set_client_CA_list(ctx, SSL_load_client_CA_file(bind_conf->ca_file));
Emeric Brund94b3fe2012-09-20 18:23:56 +02001546 }
Emeric Brun850efd52014-01-29 12:24:34 +01001547 else {
1548 Alert("Proxy '%s': verify is enabled but no CA file specified for bind '%s' at [%s:%d].\n",
1549 curproxy->id, bind_conf->arg, bind_conf->file, bind_conf->line);
1550 cfgerr++;
1551 }
Emeric Brun051cdab2012-10-02 19:25:50 +02001552#ifdef X509_V_FLAG_CRL_CHECK
Emeric Brunfb510ea2012-10-05 12:00:26 +02001553 if (bind_conf->crl_file) {
Emeric Brund94b3fe2012-09-20 18:23:56 +02001554 X509_STORE *store = SSL_CTX_get_cert_store(ctx);
1555
Emeric Brunfb510ea2012-10-05 12:00:26 +02001556 if (!store || !X509_STORE_load_locations(store, bind_conf->crl_file, NULL)) {
Emeric Brund94b3fe2012-09-20 18:23:56 +02001557 Alert("Proxy '%s': unable to configure CRL file '%s' for bind '%s' at [%s:%d].\n",
Emeric Brunfb510ea2012-10-05 12:00:26 +02001558 curproxy->id, bind_conf->ca_file, bind_conf->arg, bind_conf->file, bind_conf->line);
Emeric Brund94b3fe2012-09-20 18:23:56 +02001559 cfgerr++;
1560 }
Emeric Brun561e5742012-10-02 15:20:55 +02001561 else {
1562 X509_STORE_set_flags(store, X509_V_FLAG_CRL_CHECK|X509_V_FLAG_CRL_CHECK_ALL);
1563 }
Emeric Brund94b3fe2012-09-20 18:23:56 +02001564 }
Emeric Brun051cdab2012-10-02 19:25:50 +02001565#endif
Emeric Brun644cde02012-12-14 11:21:13 +01001566 ERR_clear_error();
Emeric Brund94b3fe2012-09-20 18:23:56 +02001567 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02001568
Emeric Brun4f65bff2012-11-16 15:11:00 +01001569 if (global.tune.ssllifetime)
1570 SSL_CTX_set_timeout(ctx, global.tune.ssllifetime);
1571
Emeric Brunfc0421f2012-09-07 17:30:07 +02001572 shared_context_set_cache(ctx);
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001573 if (bind_conf->ciphers &&
1574 !SSL_CTX_set_cipher_list(ctx, bind_conf->ciphers)) {
Emeric Brunfc0421f2012-09-07 17:30:07 +02001575 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 +02001576 curproxy->id, bind_conf->ciphers, bind_conf->arg, bind_conf->file, bind_conf->line);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001577 cfgerr++;
1578 }
1579
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001580 /* If tune.ssl.default-dh-param has not been set and
1581 no static DH params were in the certificate file. */
1582 if (global.tune.ssl_default_dh_param == 0) {
Lukas Tribus90132722014-08-18 00:56:33 +02001583
Remi Gacogne23d5d372014-10-10 17:04:26 +02001584 ssl = SSL_new(ctx);
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001585
Remi Gacogne23d5d372014-10-10 17:04:26 +02001586 if (ssl) {
1587 ciphers = SSL_get_ciphers(ssl);
1588
1589 if (ciphers) {
1590 for (idx = 0; idx < sk_SSL_CIPHER_num(ciphers); idx++) {
1591 cipher = sk_SSL_CIPHER_value(ciphers, idx);
1592 if (SSL_CIPHER_description(cipher, cipher_description, sizeof (cipher_description)) == cipher_description) {
1593 if (strstr(cipher_description, dhe_description) != NULL ||
1594 strstr(cipher_description, dhe_export_description) != NULL) {
1595 dhe_found = 1;
1596 break;
1597 }
Remi Gacognec1eab8c2014-06-12 18:20:11 +02001598 }
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001599 }
1600 }
Remi Gacogne23d5d372014-10-10 17:04:26 +02001601 SSL_free(ssl);
1602 ssl = NULL;
Lukas Tribus90132722014-08-18 00:56:33 +02001603 }
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001604
Lukas Tribus90132722014-08-18 00:56:33 +02001605 if (dhe_found) {
1606 Warning("Setting tune.ssl.default-dh-param to 1024 by default, if your workload permits it you should set it to at least 2048. Please set a value >= 1024 to make this warning disappear.\n");
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001607 }
1608
1609 global.tune.ssl_default_dh_param = 1024;
1610 }
Remi Gacogne8de54152014-07-15 11:36:40 +02001611
1612#ifndef OPENSSL_NO_DH
1613 if (global.tune.ssl_default_dh_param >= 1024) {
1614 if (local_dh_1024 == NULL) {
1615 local_dh_1024 = ssl_get_dh_1024();
1616 }
1617 if (global.tune.ssl_default_dh_param >= 2048) {
1618 if (local_dh_2048 == NULL) {
1619 local_dh_2048 = ssl_get_dh_2048();
1620 }
1621 if (global.tune.ssl_default_dh_param >= 4096) {
1622 if (local_dh_4096 == NULL) {
1623 local_dh_4096 = ssl_get_dh_4096();
1624 }
1625 if (global.tune.ssl_default_dh_param >= 8192 &&
1626 local_dh_8192 == NULL) {
1627 local_dh_8192 = ssl_get_dh_8192();
1628 }
1629 }
1630 }
1631 }
1632#endif /* OPENSSL_NO_DH */
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001633
Emeric Brunfc0421f2012-09-07 17:30:07 +02001634 SSL_CTX_set_info_callback(ctx, ssl_sock_infocbk);
Willy Tarreau5cbe4ef2014-05-08 22:45:11 +02001635#if OPENSSL_VERSION_NUMBER >= 0x00907000L
Emeric Brun29f037d2014-04-25 19:05:36 +02001636 SSL_CTX_set_msg_callback(ctx, ssl_sock_msgcbk);
Willy Tarreau5cbe4ef2014-05-08 22:45:11 +02001637#endif
Emeric Brun29f037d2014-04-25 19:05:36 +02001638
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02001639#ifdef OPENSSL_NPN_NEGOTIATED
1640 if (bind_conf->npn_str)
1641 SSL_CTX_set_next_protos_advertised_cb(ctx, ssl_sock_advertise_npn_protos, bind_conf);
1642#endif
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01001643#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Willy Tarreauab861d32013-04-02 02:30:41 +02001644 if (bind_conf->alpn_str)
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01001645 SSL_CTX_set_alpn_select_cb(ctx, ssl_sock_advertise_alpn_protos, bind_conf);
Willy Tarreauab861d32013-04-02 02:30:41 +02001646#endif
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02001647
Emeric Brunfc0421f2012-09-07 17:30:07 +02001648#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
1649 SSL_CTX_set_tlsext_servername_callback(ctx, ssl_sock_switchctx_cbk);
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001650 SSL_CTX_set_tlsext_servername_arg(ctx, bind_conf);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001651#endif
Emeric Brun2b58d042012-09-20 17:10:03 +02001652#if defined(SSL_CTX_set_tmp_ecdh) && !defined(OPENSSL_NO_ECDH)
Emeric Brun6924ef82013-03-06 14:08:53 +01001653 {
Emeric Brun2b58d042012-09-20 17:10:03 +02001654 int i;
1655 EC_KEY *ecdh;
1656
Emeric Brun6924ef82013-03-06 14:08:53 +01001657 i = OBJ_sn2nid(bind_conf->ecdhe ? bind_conf->ecdhe : ECDHE_DEFAULT_CURVE);
Emeric Brun2b58d042012-09-20 17:10:03 +02001658 if (!i || ((ecdh = EC_KEY_new_by_curve_name(i)) == NULL)) {
1659 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 +01001660 curproxy->id, bind_conf->ecdhe ? bind_conf->ecdhe : ECDHE_DEFAULT_CURVE,
1661 bind_conf->arg, bind_conf->file, bind_conf->line);
Emeric Brun2b58d042012-09-20 17:10:03 +02001662 cfgerr++;
1663 }
1664 else {
1665 SSL_CTX_set_tmp_ecdh(ctx, ecdh);
1666 EC_KEY_free(ecdh);
1667 }
1668 }
1669#endif
1670
Emeric Brunfc0421f2012-09-07 17:30:07 +02001671 return cfgerr;
1672}
1673
Evan Broderbe554312013-06-27 00:05:25 -07001674static int ssl_sock_srv_hostcheck(const char *pattern, const char *hostname)
1675{
1676 const char *pattern_wildcard, *pattern_left_label_end, *hostname_left_label_end;
1677 size_t prefixlen, suffixlen;
1678
1679 /* Trivial case */
1680 if (strcmp(pattern, hostname) == 0)
1681 return 1;
1682
Evan Broderbe554312013-06-27 00:05:25 -07001683 /* The rest of this logic is based on RFC 6125, section 6.4.3
1684 * (http://tools.ietf.org/html/rfc6125#section-6.4.3) */
1685
Emeric Bruna848dae2013-10-08 11:27:28 +02001686 pattern_wildcard = NULL;
1687 pattern_left_label_end = pattern;
1688 while (*pattern_left_label_end != '.') {
1689 switch (*pattern_left_label_end) {
1690 case 0:
1691 /* End of label not found */
1692 return 0;
1693 case '*':
1694 /* If there is more than one wildcards */
1695 if (pattern_wildcard)
1696 return 0;
1697 pattern_wildcard = pattern_left_label_end;
1698 break;
1699 }
1700 pattern_left_label_end++;
1701 }
1702
1703 /* If it's not trivial and there is no wildcard, it can't
1704 * match */
1705 if (!pattern_wildcard)
Evan Broderbe554312013-06-27 00:05:25 -07001706 return 0;
1707
1708 /* Make sure all labels match except the leftmost */
1709 hostname_left_label_end = strchr(hostname, '.');
1710 if (!hostname_left_label_end
1711 || strcmp(pattern_left_label_end, hostname_left_label_end) != 0)
1712 return 0;
1713
1714 /* Make sure the leftmost label of the hostname is long enough
1715 * that the wildcard can match */
Emeric Brun369da852013-10-08 11:39:35 +02001716 if (hostname_left_label_end - hostname < (pattern_left_label_end - pattern) - 1)
Evan Broderbe554312013-06-27 00:05:25 -07001717 return 0;
1718
1719 /* Finally compare the string on either side of the
1720 * wildcard */
1721 prefixlen = pattern_wildcard - pattern;
1722 suffixlen = pattern_left_label_end - (pattern_wildcard + 1);
Emeric Bruna848dae2013-10-08 11:27:28 +02001723 if ((prefixlen && (memcmp(pattern, hostname, prefixlen) != 0))
1724 || (suffixlen && (memcmp(pattern_wildcard + 1, hostname_left_label_end - suffixlen, suffixlen) != 0)))
Evan Broderbe554312013-06-27 00:05:25 -07001725 return 0;
1726
1727 return 1;
1728}
1729
1730static int ssl_sock_srv_verifycbk(int ok, X509_STORE_CTX *ctx)
1731{
1732 SSL *ssl;
1733 struct connection *conn;
1734 char *servername;
1735
1736 int depth;
1737 X509 *cert;
1738 STACK_OF(GENERAL_NAME) *alt_names;
1739 int i;
1740 X509_NAME *cert_subject;
1741 char *str;
1742
1743 if (ok == 0)
1744 return ok;
1745
1746 ssl = X509_STORE_CTX_get_ex_data(ctx, SSL_get_ex_data_X509_STORE_CTX_idx());
1747 conn = (struct connection *)SSL_get_app_data(ssl);
1748
1749 servername = objt_server(conn->target)->ssl_ctx.verify_host;
1750
1751 /* We only need to verify the CN on the actual server cert,
1752 * not the indirect CAs */
1753 depth = X509_STORE_CTX_get_error_depth(ctx);
1754 if (depth != 0)
1755 return ok;
1756
1757 /* At this point, the cert is *not* OK unless we can find a
1758 * hostname match */
1759 ok = 0;
1760
1761 cert = X509_STORE_CTX_get_current_cert(ctx);
1762 /* It seems like this might happen if verify peer isn't set */
1763 if (!cert)
1764 return ok;
1765
1766 alt_names = X509_get_ext_d2i(cert, NID_subject_alt_name, NULL, NULL);
1767 if (alt_names) {
1768 for (i = 0; !ok && i < sk_GENERAL_NAME_num(alt_names); i++) {
1769 GENERAL_NAME *name = sk_GENERAL_NAME_value(alt_names, i);
1770 if (name->type == GEN_DNS) {
Emeric Bruna33410c2013-09-17 15:47:48 +02001771#if OPENSSL_VERSION_NUMBER < 0x00907000L
1772 if (ASN1_STRING_to_UTF8((unsigned char **)&str, name->d.ia5) >= 0) {
1773#else
Evan Broderbe554312013-06-27 00:05:25 -07001774 if (ASN1_STRING_to_UTF8((unsigned char **)&str, name->d.dNSName) >= 0) {
Emeric Bruna33410c2013-09-17 15:47:48 +02001775#endif
Evan Broderbe554312013-06-27 00:05:25 -07001776 ok = ssl_sock_srv_hostcheck(str, servername);
1777 OPENSSL_free(str);
1778 }
1779 }
1780 }
Emeric Brun4ad50a42013-09-17 15:19:54 +02001781 sk_GENERAL_NAME_pop_free(alt_names, GENERAL_NAME_free);
Evan Broderbe554312013-06-27 00:05:25 -07001782 }
1783
1784 cert_subject = X509_get_subject_name(cert);
1785 i = -1;
1786 while (!ok && (i = X509_NAME_get_index_by_NID(cert_subject, NID_commonName, i)) != -1) {
1787 X509_NAME_ENTRY *entry = X509_NAME_get_entry(cert_subject, i);
1788 if (ASN1_STRING_to_UTF8((unsigned char **)&str, entry->value) >= 0) {
1789 ok = ssl_sock_srv_hostcheck(str, servername);
1790 OPENSSL_free(str);
1791 }
1792 }
1793
1794 return ok;
1795}
1796
Emeric Brun94324a42012-10-11 14:00:19 +02001797/* prepare ssl context from servers options. Returns an error count */
1798int ssl_sock_prepare_srv_ctx(struct server *srv, struct proxy *curproxy)
1799{
1800 int cfgerr = 0;
Remi Gacogneaf5c3da2014-05-19 10:29:58 +02001801 long options =
Emeric Brun94324a42012-10-11 14:00:19 +02001802 SSL_OP_ALL | /* all known workarounds for bugs */
1803 SSL_OP_NO_SSLv2 |
1804 SSL_OP_NO_COMPRESSION;
Remi Gacogneaf5c3da2014-05-19 10:29:58 +02001805 long mode =
Emeric Brun94324a42012-10-11 14:00:19 +02001806 SSL_MODE_ENABLE_PARTIAL_WRITE |
1807 SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER |
1808 SSL_MODE_RELEASE_BUFFERS;
Emeric Brun850efd52014-01-29 12:24:34 +01001809 int verify = SSL_VERIFY_NONE;
Emeric Brun94324a42012-10-11 14:00:19 +02001810
Thierry Fournier383085f2013-01-24 14:15:43 +01001811 /* Make sure openssl opens /dev/urandom before the chroot */
1812 if (!ssl_initialize_random()) {
1813 Alert("OpenSSL random data generator initialization failed.\n");
1814 cfgerr++;
1815 }
1816
Emeric Brun94324a42012-10-11 14:00:19 +02001817 /* Initiate SSL context for current server */
1818 srv->ssl_ctx.reused_sess = NULL;
1819 if (srv->use_ssl)
1820 srv->xprt = &ssl_sock;
1821 if (srv->check.use_ssl)
Simon Horman66183002013-02-23 10:16:43 +09001822 srv->check_common.xprt = &ssl_sock;
Emeric Brun94324a42012-10-11 14:00:19 +02001823
1824 srv->ssl_ctx.ctx = SSL_CTX_new(SSLv23_client_method());
1825 if (!srv->ssl_ctx.ctx) {
1826 Alert("config : %s '%s', server '%s': unable to allocate ssl context.\n",
1827 proxy_type_str(curproxy), curproxy->id,
1828 srv->id);
1829 cfgerr++;
1830 return cfgerr;
1831 }
Emeric Bruna7aa3092012-10-26 12:58:00 +02001832 if (srv->ssl_ctx.client_crt) {
1833 if (SSL_CTX_use_PrivateKey_file(srv->ssl_ctx.ctx, srv->ssl_ctx.client_crt, SSL_FILETYPE_PEM) <= 0) {
1834 Alert("config : %s '%s', server '%s': unable to load SSL private key from PEM file '%s'.\n",
1835 proxy_type_str(curproxy), curproxy->id,
1836 srv->id, srv->ssl_ctx.client_crt);
1837 cfgerr++;
1838 }
1839 else if (SSL_CTX_use_certificate_chain_file(srv->ssl_ctx.ctx, srv->ssl_ctx.client_crt) <= 0) {
1840 Alert("config : %s '%s', server '%s': unable to load ssl certificate from PEM file '%s'.\n",
1841 proxy_type_str(curproxy), curproxy->id,
1842 srv->id, srv->ssl_ctx.client_crt);
1843 cfgerr++;
1844 }
1845 else if (SSL_CTX_check_private_key(srv->ssl_ctx.ctx) <= 0) {
1846 Alert("config : %s '%s', server '%s': inconsistencies between private key and certificate loaded from PEM file '%s'.\n",
1847 proxy_type_str(curproxy), curproxy->id,
1848 srv->id, srv->ssl_ctx.client_crt);
1849 cfgerr++;
1850 }
1851 }
Emeric Brun94324a42012-10-11 14:00:19 +02001852
1853 if (srv->ssl_ctx.options & SRV_SSL_O_NO_SSLV3)
1854 options |= SSL_OP_NO_SSLv3;
1855 if (srv->ssl_ctx.options & SRV_SSL_O_NO_TLSV10)
1856 options |= SSL_OP_NO_TLSv1;
1857 if (srv->ssl_ctx.options & SRV_SSL_O_NO_TLSV11)
1858 options |= SSL_OP_NO_TLSv1_1;
1859 if (srv->ssl_ctx.options & SRV_SSL_O_NO_TLSV12)
1860 options |= SSL_OP_NO_TLSv1_2;
Emeric Brunf9c5c472012-10-11 15:28:34 +02001861 if (srv->ssl_ctx.options & SRV_SSL_O_NO_TLS_TICKETS)
1862 options |= SSL_OP_NO_TICKET;
Emeric Brun94324a42012-10-11 14:00:19 +02001863 if (srv->ssl_ctx.options & SRV_SSL_O_USE_SSLV3)
1864 SSL_CTX_set_ssl_version(srv->ssl_ctx.ctx, SSLv3_client_method());
1865 if (srv->ssl_ctx.options & SRV_SSL_O_USE_TLSV10)
1866 SSL_CTX_set_ssl_version(srv->ssl_ctx.ctx, TLSv1_client_method());
1867#if SSL_OP_NO_TLSv1_1
1868 if (srv->ssl_ctx.options & SRV_SSL_O_USE_TLSV11)
1869 SSL_CTX_set_ssl_version(srv->ssl_ctx.ctx, TLSv1_1_client_method());
1870#endif
1871#if SSL_OP_NO_TLSv1_2
1872 if (srv->ssl_ctx.options & SRV_SSL_O_USE_TLSV12)
1873 SSL_CTX_set_ssl_version(srv->ssl_ctx.ctx, TLSv1_2_client_method());
1874#endif
1875
1876 SSL_CTX_set_options(srv->ssl_ctx.ctx, options);
1877 SSL_CTX_set_mode(srv->ssl_ctx.ctx, mode);
Emeric Brun850efd52014-01-29 12:24:34 +01001878
1879 if (global.ssl_server_verify == SSL_SERVER_VERIFY_REQUIRED)
1880 verify = SSL_VERIFY_PEER;
1881
1882 switch (srv->ssl_ctx.verify) {
1883 case SSL_SOCK_VERIFY_NONE:
1884 verify = SSL_VERIFY_NONE;
1885 break;
1886 case SSL_SOCK_VERIFY_REQUIRED:
1887 verify = SSL_VERIFY_PEER;
1888 break;
1889 }
Evan Broderbe554312013-06-27 00:05:25 -07001890 SSL_CTX_set_verify(srv->ssl_ctx.ctx,
Emeric Brun850efd52014-01-29 12:24:34 +01001891 verify,
Evan Broderbe554312013-06-27 00:05:25 -07001892 srv->ssl_ctx.verify_host ? ssl_sock_srv_verifycbk : NULL);
Emeric Brun850efd52014-01-29 12:24:34 +01001893 if (verify & SSL_VERIFY_PEER) {
Emeric Brunef42d922012-10-11 16:11:36 +02001894 if (srv->ssl_ctx.ca_file) {
1895 /* load CAfile to verify */
1896 if (!SSL_CTX_load_verify_locations(srv->ssl_ctx.ctx, srv->ssl_ctx.ca_file, NULL)) {
Willy Tarreau07ba08b2014-02-16 19:22:08 +01001897 Alert("Proxy '%s', server '%s' [%s:%d] unable to load CA file '%s'.\n",
Emeric Brunef42d922012-10-11 16:11:36 +02001898 curproxy->id, srv->id,
1899 srv->conf.file, srv->conf.line, srv->ssl_ctx.ca_file);
1900 cfgerr++;
1901 }
1902 }
Emeric Brun850efd52014-01-29 12:24:34 +01001903 else {
1904 if (global.ssl_server_verify == SSL_SERVER_VERIFY_REQUIRED)
Willy Tarreau07ba08b2014-02-16 19:22:08 +01001905 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 +01001906 curproxy->id, srv->id,
1907 srv->conf.file, srv->conf.line);
1908 else
Willy Tarreau07ba08b2014-02-16 19:22:08 +01001909 Alert("Proxy '%s', server '%s' [%s:%d] verify is enabled but no CA file specified.\n",
Emeric Brun850efd52014-01-29 12:24:34 +01001910 curproxy->id, srv->id,
1911 srv->conf.file, srv->conf.line);
1912 cfgerr++;
1913 }
Emeric Brunef42d922012-10-11 16:11:36 +02001914#ifdef X509_V_FLAG_CRL_CHECK
1915 if (srv->ssl_ctx.crl_file) {
1916 X509_STORE *store = SSL_CTX_get_cert_store(srv->ssl_ctx.ctx);
1917
1918 if (!store || !X509_STORE_load_locations(store, srv->ssl_ctx.crl_file, NULL)) {
Willy Tarreau07ba08b2014-02-16 19:22:08 +01001919 Alert("Proxy '%s', server '%s' [%s:%d] unable to configure CRL file '%s'.\n",
Emeric Brunef42d922012-10-11 16:11:36 +02001920 curproxy->id, srv->id,
1921 srv->conf.file, srv->conf.line, srv->ssl_ctx.crl_file);
1922 cfgerr++;
1923 }
1924 else {
1925 X509_STORE_set_flags(store, X509_V_FLAG_CRL_CHECK|X509_V_FLAG_CRL_CHECK_ALL);
1926 }
1927 }
1928#endif
1929 }
1930
Emeric Brun4f65bff2012-11-16 15:11:00 +01001931 if (global.tune.ssllifetime)
1932 SSL_CTX_set_timeout(srv->ssl_ctx.ctx, global.tune.ssllifetime);
1933
Emeric Brun94324a42012-10-11 14:00:19 +02001934 SSL_CTX_set_session_cache_mode(srv->ssl_ctx.ctx, SSL_SESS_CACHE_OFF);
1935 if (srv->ssl_ctx.ciphers &&
1936 !SSL_CTX_set_cipher_list(srv->ssl_ctx.ctx, srv->ssl_ctx.ciphers)) {
1937 Alert("Proxy '%s', server '%s' [%s:%d] : unable to set SSL cipher list to '%s'.\n",
1938 curproxy->id, srv->id,
1939 srv->conf.file, srv->conf.line, srv->ssl_ctx.ciphers);
1940 cfgerr++;
1941 }
1942
1943 return cfgerr;
1944}
1945
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001946/* Walks down the two trees in bind_conf and prepares all certs. The pointer may
Emeric Brunfc0421f2012-09-07 17:30:07 +02001947 * be NULL, in which case nothing is done. Returns the number of errors
1948 * encountered.
1949 */
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001950int ssl_sock_prepare_all_ctx(struct bind_conf *bind_conf, struct proxy *px)
Emeric Brunfc0421f2012-09-07 17:30:07 +02001951{
1952 struct ebmb_node *node;
1953 struct sni_ctx *sni;
1954 int err = 0;
1955
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001956 if (!bind_conf || !bind_conf->is_ssl)
Emeric Brunfc0421f2012-09-07 17:30:07 +02001957 return 0;
1958
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001959 node = ebmb_first(&bind_conf->sni_ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001960 while (node) {
1961 sni = ebmb_entry(node, struct sni_ctx, name);
1962 if (!sni->order) /* only initialize the CTX on its first occurrence */
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001963 err += ssl_sock_prepare_ctx(bind_conf, sni->ctx, px);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001964 node = ebmb_next(node);
1965 }
1966
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001967 node = ebmb_first(&bind_conf->sni_w_ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001968 while (node) {
1969 sni = ebmb_entry(node, struct sni_ctx, name);
1970 if (!sni->order) /* only initialize the CTX on its first occurrence */
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001971 err += ssl_sock_prepare_ctx(bind_conf, sni->ctx, px);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001972 node = ebmb_next(node);
1973 }
1974 return err;
1975}
1976
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001977/* Walks down the two trees in bind_conf and frees all the certs. The pointer may
Emeric Brunfc0421f2012-09-07 17:30:07 +02001978 * be NULL, in which case nothing is done. The default_ctx is nullified too.
1979 */
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001980void ssl_sock_free_all_ctx(struct bind_conf *bind_conf)
Emeric Brunfc0421f2012-09-07 17:30:07 +02001981{
1982 struct ebmb_node *node, *back;
1983 struct sni_ctx *sni;
1984
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001985 if (!bind_conf || !bind_conf->is_ssl)
Emeric Brunfc0421f2012-09-07 17:30:07 +02001986 return;
1987
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001988 node = ebmb_first(&bind_conf->sni_ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001989 while (node) {
1990 sni = ebmb_entry(node, struct sni_ctx, name);
1991 back = ebmb_next(node);
1992 ebmb_delete(node);
1993 if (!sni->order) /* only free the CTX on its first occurrence */
1994 SSL_CTX_free(sni->ctx);
1995 free(sni);
1996 node = back;
1997 }
1998
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001999 node = ebmb_first(&bind_conf->sni_w_ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002000 while (node) {
2001 sni = ebmb_entry(node, struct sni_ctx, name);
2002 back = ebmb_next(node);
2003 ebmb_delete(node);
2004 if (!sni->order) /* only free the CTX on its first occurrence */
2005 SSL_CTX_free(sni->ctx);
2006 free(sni);
2007 node = back;
2008 }
2009
Willy Tarreau2a65ff02012-09-13 17:54:29 +02002010 bind_conf->default_ctx = NULL;
Emeric Brune1f38db2012-09-03 20:36:47 +02002011}
2012
Emeric Brun46591952012-05-18 15:47:34 +02002013/*
2014 * This function is called if SSL * context is not yet allocated. The function
2015 * is designed to be called before any other data-layer operation and sets the
2016 * handshake flag on the connection. It is safe to call it multiple times.
2017 * It returns 0 on success and -1 in error case.
2018 */
2019static int ssl_sock_init(struct connection *conn)
2020{
2021 /* already initialized */
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02002022 if (conn->xprt_ctx)
Emeric Brun46591952012-05-18 15:47:34 +02002023 return 0;
2024
Willy Tarreau3c728722014-01-23 13:50:42 +01002025 if (!conn_ctrl_ready(conn))
Willy Tarreauf79c8172013-10-21 16:30:56 +02002026 return 0;
2027
Willy Tarreau20879a02012-12-03 16:32:10 +01002028 if (global.maxsslconn && sslconns >= global.maxsslconn) {
2029 conn->err_code = CO_ER_SSL_TOO_MANY;
Willy Tarreau403edff2012-09-06 11:58:37 +02002030 return -1;
Willy Tarreau20879a02012-12-03 16:32:10 +01002031 }
Willy Tarreau403edff2012-09-06 11:58:37 +02002032
Emeric Brun46591952012-05-18 15:47:34 +02002033 /* If it is in client mode initiate SSL session
2034 in connect state otherwise accept state */
Willy Tarreau3fdb3662012-11-12 00:42:33 +01002035 if (objt_server(conn->target)) {
Emeric Brun46591952012-05-18 15:47:34 +02002036 /* Alloc a new SSL session ctx */
Willy Tarreau3fdb3662012-11-12 00:42:33 +01002037 conn->xprt_ctx = SSL_new(objt_server(conn->target)->ssl_ctx.ctx);
Willy Tarreau20879a02012-12-03 16:32:10 +01002038 if (!conn->xprt_ctx) {
2039 conn->err_code = CO_ER_SSL_NO_MEM;
Emeric Brun46591952012-05-18 15:47:34 +02002040 return -1;
Willy Tarreau20879a02012-12-03 16:32:10 +01002041 }
Emeric Brun46591952012-05-18 15:47:34 +02002042
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02002043 SSL_set_connect_state(conn->xprt_ctx);
Willy Tarreau3fdb3662012-11-12 00:42:33 +01002044 if (objt_server(conn->target)->ssl_ctx.reused_sess)
2045 SSL_set_session(conn->xprt_ctx, objt_server(conn->target)->ssl_ctx.reused_sess);
Emeric Brun46591952012-05-18 15:47:34 +02002046
2047 /* set fd on SSL session context */
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02002048 SSL_set_fd(conn->xprt_ctx, conn->t.sock.fd);
Emeric Brun46591952012-05-18 15:47:34 +02002049
Evan Broderbe554312013-06-27 00:05:25 -07002050 /* set connection pointer */
2051 SSL_set_app_data(conn->xprt_ctx, conn);
2052
Emeric Brun46591952012-05-18 15:47:34 +02002053 /* leave init state and start handshake */
Willy Tarreau05737472012-09-04 08:03:39 +02002054 conn->flags |= CO_FL_SSL_WAIT_HS | CO_FL_WAIT_L6_CONN;
Willy Tarreau403edff2012-09-06 11:58:37 +02002055
2056 sslconns++;
Willy Tarreau71b734c2014-01-28 15:19:44 +01002057 totalsslconns++;
Emeric Brun46591952012-05-18 15:47:34 +02002058 return 0;
2059 }
Willy Tarreau3fdb3662012-11-12 00:42:33 +01002060 else if (objt_listener(conn->target)) {
Emeric Brun46591952012-05-18 15:47:34 +02002061 /* Alloc a new SSL session ctx */
Willy Tarreau3fdb3662012-11-12 00:42:33 +01002062 conn->xprt_ctx = SSL_new(objt_listener(conn->target)->bind_conf->default_ctx);
Willy Tarreau20879a02012-12-03 16:32:10 +01002063 if (!conn->xprt_ctx) {
2064 conn->err_code = CO_ER_SSL_NO_MEM;
Emeric Brun46591952012-05-18 15:47:34 +02002065 return -1;
Willy Tarreau20879a02012-12-03 16:32:10 +01002066 }
Emeric Brun46591952012-05-18 15:47:34 +02002067
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02002068 SSL_set_accept_state(conn->xprt_ctx);
Emeric Brun46591952012-05-18 15:47:34 +02002069
2070 /* set fd on SSL session context */
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02002071 SSL_set_fd(conn->xprt_ctx, conn->t.sock.fd);
Emeric Brun46591952012-05-18 15:47:34 +02002072
Emeric Brune1f38db2012-09-03 20:36:47 +02002073 /* set connection pointer */
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02002074 SSL_set_app_data(conn->xprt_ctx, conn);
Emeric Brune1f38db2012-09-03 20:36:47 +02002075
Emeric Brun46591952012-05-18 15:47:34 +02002076 /* leave init state and start handshake */
Willy Tarreau05737472012-09-04 08:03:39 +02002077 conn->flags |= CO_FL_SSL_WAIT_HS | CO_FL_WAIT_L6_CONN;
Willy Tarreau403edff2012-09-06 11:58:37 +02002078
2079 sslconns++;
Willy Tarreau71b734c2014-01-28 15:19:44 +01002080 totalsslconns++;
Emeric Brun46591952012-05-18 15:47:34 +02002081 return 0;
2082 }
2083 /* don't know how to handle such a target */
Willy Tarreau20879a02012-12-03 16:32:10 +01002084 conn->err_code = CO_ER_SSL_NO_TARGET;
Emeric Brun46591952012-05-18 15:47:34 +02002085 return -1;
2086}
2087
2088
2089/* This is the callback which is used when an SSL handshake is pending. It
2090 * updates the FD status if it wants some polling before being called again.
2091 * It returns 0 if it fails in a fatal way or needs to poll to go further,
2092 * otherwise it returns non-zero and removes itself from the connection's
2093 * flags (the bit is provided in <flag> by the caller).
2094 */
2095int ssl_sock_handshake(struct connection *conn, unsigned int flag)
2096{
2097 int ret;
2098
Willy Tarreau3c728722014-01-23 13:50:42 +01002099 if (!conn_ctrl_ready(conn))
Willy Tarreauf79c8172013-10-21 16:30:56 +02002100 return 0;
2101
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02002102 if (!conn->xprt_ctx)
Emeric Brun46591952012-05-18 15:47:34 +02002103 goto out_error;
2104
Emeric Brun674b7432012-11-08 19:21:55 +01002105 /* If we use SSL_do_handshake to process a reneg initiated by
2106 * the remote peer, it sometimes returns SSL_ERROR_SSL.
2107 * Usually SSL_write and SSL_read are used and process implicitly
2108 * the reneg handshake.
2109 * Here we use SSL_peek as a workaround for reneg.
2110 */
2111 if ((conn->flags & CO_FL_CONNECTED) && SSL_renegotiate_pending(conn->xprt_ctx)) {
2112 char c;
2113
2114 ret = SSL_peek(conn->xprt_ctx, &c, 1);
2115 if (ret <= 0) {
2116 /* handshake may have not been completed, let's find why */
2117 ret = SSL_get_error(conn->xprt_ctx, ret);
2118 if (ret == SSL_ERROR_WANT_WRITE) {
2119 /* SSL handshake needs to write, L4 connection may not be ready */
2120 __conn_sock_stop_recv(conn);
Willy Tarreaue1f50c42014-01-22 20:02:06 +01002121 __conn_sock_want_send(conn);
2122 fd_cant_send(conn->t.sock.fd);
Emeric Brun674b7432012-11-08 19:21:55 +01002123 return 0;
2124 }
2125 else if (ret == SSL_ERROR_WANT_READ) {
2126 /* handshake may have been completed but we have
2127 * no more data to read.
2128 */
2129 if (!SSL_renegotiate_pending(conn->xprt_ctx)) {
2130 ret = 1;
2131 goto reneg_ok;
2132 }
2133 /* SSL handshake needs to read, L4 connection is ready */
2134 if (conn->flags & CO_FL_WAIT_L4_CONN)
2135 conn->flags &= ~CO_FL_WAIT_L4_CONN;
2136 __conn_sock_stop_send(conn);
Willy Tarreaue1f50c42014-01-22 20:02:06 +01002137 __conn_sock_want_recv(conn);
2138 fd_cant_recv(conn->t.sock.fd);
Emeric Brun674b7432012-11-08 19:21:55 +01002139 return 0;
2140 }
2141 else if (ret == SSL_ERROR_SYSCALL) {
2142 /* if errno is null, then connection was successfully established */
2143 if (!errno && conn->flags & CO_FL_WAIT_L4_CONN)
2144 conn->flags &= ~CO_FL_WAIT_L4_CONN;
Willy Tarreau20879a02012-12-03 16:32:10 +01002145 if (!conn->err_code) {
Emeric Brun29f037d2014-04-25 19:05:36 +02002146 if (!((SSL *)conn->xprt_ctx)->packet_length) {
2147 if (!errno) {
2148 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
2149 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
2150 else
2151 conn->err_code = CO_ER_SSL_EMPTY;
2152 }
2153 else {
2154 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
2155 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
2156 else
2157 conn->err_code = CO_ER_SSL_ABORT;
2158 }
2159 }
2160 else {
2161 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
2162 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
Willy Tarreau20879a02012-12-03 16:32:10 +01002163 else
Emeric Brun29f037d2014-04-25 19:05:36 +02002164 conn->err_code = CO_ER_SSL_HANDSHAKE;
2165 }
Willy Tarreau20879a02012-12-03 16:32:10 +01002166 }
Emeric Brun674b7432012-11-08 19:21:55 +01002167 goto out_error;
2168 }
2169 else {
2170 /* Fail on all other handshake errors */
2171 /* Note: OpenSSL may leave unread bytes in the socket's
2172 * buffer, causing an RST to be emitted upon close() on
2173 * TCP sockets. We first try to drain possibly pending
2174 * data to avoid this as much as possible.
2175 */
Willy Tarreau46be2e52014-01-20 12:10:52 +01002176 conn_drain(conn);
Willy Tarreau20879a02012-12-03 16:32:10 +01002177 if (!conn->err_code)
Willy Tarreauf51c6982014-04-25 20:02:39 +02002178 conn->err_code = (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT) ?
2179 CO_ER_SSL_KILLED_HB : CO_ER_SSL_HANDSHAKE;
Emeric Brun674b7432012-11-08 19:21:55 +01002180 goto out_error;
2181 }
2182 }
2183 /* read some data: consider handshake completed */
2184 goto reneg_ok;
2185 }
2186
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02002187 ret = SSL_do_handshake(conn->xprt_ctx);
Emeric Brun46591952012-05-18 15:47:34 +02002188 if (ret != 1) {
2189 /* handshake did not complete, let's find why */
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02002190 ret = SSL_get_error(conn->xprt_ctx, ret);
Emeric Brun46591952012-05-18 15:47:34 +02002191
2192 if (ret == SSL_ERROR_WANT_WRITE) {
2193 /* SSL handshake needs to write, L4 connection may not be ready */
2194 __conn_sock_stop_recv(conn);
Willy Tarreaue1f50c42014-01-22 20:02:06 +01002195 __conn_sock_want_send(conn);
2196 fd_cant_send(conn->t.sock.fd);
Emeric Brun46591952012-05-18 15:47:34 +02002197 return 0;
2198 }
2199 else if (ret == SSL_ERROR_WANT_READ) {
2200 /* SSL handshake needs to read, L4 connection is ready */
2201 if (conn->flags & CO_FL_WAIT_L4_CONN)
2202 conn->flags &= ~CO_FL_WAIT_L4_CONN;
2203 __conn_sock_stop_send(conn);
Willy Tarreaue1f50c42014-01-22 20:02:06 +01002204 __conn_sock_want_recv(conn);
2205 fd_cant_recv(conn->t.sock.fd);
Emeric Brun46591952012-05-18 15:47:34 +02002206 return 0;
2207 }
Willy Tarreau89230192012-09-28 20:22:13 +02002208 else if (ret == SSL_ERROR_SYSCALL) {
2209 /* if errno is null, then connection was successfully established */
2210 if (!errno && conn->flags & CO_FL_WAIT_L4_CONN)
2211 conn->flags &= ~CO_FL_WAIT_L4_CONN;
Willy Tarreau20879a02012-12-03 16:32:10 +01002212
Emeric Brun29f037d2014-04-25 19:05:36 +02002213 if (!((SSL *)conn->xprt_ctx)->packet_length) {
2214 if (!errno) {
2215 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
2216 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
2217 else
2218 conn->err_code = CO_ER_SSL_EMPTY;
2219 }
2220 else {
2221 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
2222 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
2223 else
2224 conn->err_code = CO_ER_SSL_ABORT;
2225 }
2226 }
2227 else {
2228 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
2229 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
Willy Tarreau20879a02012-12-03 16:32:10 +01002230 else
Emeric Brun29f037d2014-04-25 19:05:36 +02002231 conn->err_code = CO_ER_SSL_HANDSHAKE;
2232 }
Willy Tarreau89230192012-09-28 20:22:13 +02002233 goto out_error;
2234 }
Emeric Brun46591952012-05-18 15:47:34 +02002235 else {
2236 /* Fail on all other handshake errors */
Willy Tarreau566dc552012-10-19 20:52:18 +02002237 /* Note: OpenSSL may leave unread bytes in the socket's
2238 * buffer, causing an RST to be emitted upon close() on
2239 * TCP sockets. We first try to drain possibly pending
2240 * data to avoid this as much as possible.
2241 */
Willy Tarreau46be2e52014-01-20 12:10:52 +01002242 conn_drain(conn);
Willy Tarreau20879a02012-12-03 16:32:10 +01002243 if (!conn->err_code)
Willy Tarreauf51c6982014-04-25 20:02:39 +02002244 conn->err_code = (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT) ?
2245 CO_ER_SSL_KILLED_HB : CO_ER_SSL_HANDSHAKE;
Emeric Brun46591952012-05-18 15:47:34 +02002246 goto out_error;
2247 }
2248 }
2249
Emeric Brun674b7432012-11-08 19:21:55 +01002250reneg_ok:
2251
Emeric Brun46591952012-05-18 15:47:34 +02002252 /* Handshake succeeded */
Willy Tarreau0c9c2722014-05-28 12:28:58 +02002253 if (!SSL_session_reused(conn->xprt_ctx)) {
2254 if (objt_server(conn->target)) {
2255 update_freq_ctr(&global.ssl_be_keys_per_sec, 1);
2256 if (global.ssl_be_keys_per_sec.curr_ctr > global.ssl_be_keys_max)
2257 global.ssl_be_keys_max = global.ssl_be_keys_per_sec.curr_ctr;
2258
Emeric Brun46591952012-05-18 15:47:34 +02002259 /* check if session was reused, if not store current session on server for reuse */
Willy Tarreau3fdb3662012-11-12 00:42:33 +01002260 if (objt_server(conn->target)->ssl_ctx.reused_sess)
2261 SSL_SESSION_free(objt_server(conn->target)->ssl_ctx.reused_sess);
Emeric Brun46591952012-05-18 15:47:34 +02002262
Willy Tarreau3fdb3662012-11-12 00:42:33 +01002263 objt_server(conn->target)->ssl_ctx.reused_sess = SSL_get1_session(conn->xprt_ctx);
Emeric Brun46591952012-05-18 15:47:34 +02002264 }
Willy Tarreau0c9c2722014-05-28 12:28:58 +02002265 else {
2266 update_freq_ctr(&global.ssl_fe_keys_per_sec, 1);
2267 if (global.ssl_fe_keys_per_sec.curr_ctr > global.ssl_fe_keys_max)
2268 global.ssl_fe_keys_max = global.ssl_fe_keys_per_sec.curr_ctr;
2269 }
Emeric Brun46591952012-05-18 15:47:34 +02002270 }
2271
2272 /* The connection is now established at both layers, it's time to leave */
2273 conn->flags &= ~(flag | CO_FL_WAIT_L4_CONN | CO_FL_WAIT_L6_CONN);
2274 return 1;
2275
2276 out_error:
Emeric Brun644cde02012-12-14 11:21:13 +01002277 /* Clear openssl global errors stack */
2278 ERR_clear_error();
2279
Emeric Brun9fa89732012-10-04 17:09:56 +02002280 /* free resumed session if exists */
Willy Tarreau3fdb3662012-11-12 00:42:33 +01002281 if (objt_server(conn->target) && objt_server(conn->target)->ssl_ctx.reused_sess) {
2282 SSL_SESSION_free(objt_server(conn->target)->ssl_ctx.reused_sess);
2283 objt_server(conn->target)->ssl_ctx.reused_sess = NULL;
Emeric Brun9fa89732012-10-04 17:09:56 +02002284 }
2285
Emeric Brun46591952012-05-18 15:47:34 +02002286 /* Fail on all other handshake errors */
2287 conn->flags |= CO_FL_ERROR;
Willy Tarreau20879a02012-12-03 16:32:10 +01002288 if (!conn->err_code)
2289 conn->err_code = CO_ER_SSL_HANDSHAKE;
Emeric Brun46591952012-05-18 15:47:34 +02002290 return 0;
2291}
2292
2293/* Receive up to <count> bytes from connection <conn>'s socket and store them
Willy Tarreauabf08d92014-01-14 11:31:27 +01002294 * into buffer <buf>. Only one call to recv() is performed, unless the
Emeric Brun46591952012-05-18 15:47:34 +02002295 * buffer wraps, in which case a second call may be performed. The connection's
2296 * flags are updated with whatever special event is detected (error, read0,
2297 * empty). The caller is responsible for taking care of those events and
2298 * avoiding the call if inappropriate. The function does not call the
2299 * connection's polling update function, so the caller is responsible for this.
2300 */
2301static int ssl_sock_to_buf(struct connection *conn, struct buffer *buf, int count)
2302{
2303 int ret, done = 0;
Willy Tarreauabf08d92014-01-14 11:31:27 +01002304 int try;
Emeric Brun46591952012-05-18 15:47:34 +02002305
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02002306 if (!conn->xprt_ctx)
Emeric Brun46591952012-05-18 15:47:34 +02002307 goto out_error;
2308
2309 if (conn->flags & CO_FL_HANDSHAKE)
2310 /* a handshake was requested */
2311 return 0;
2312
Willy Tarreauabf08d92014-01-14 11:31:27 +01002313 /* let's realign the buffer to optimize I/O */
2314 if (buffer_empty(buf))
Emeric Brun46591952012-05-18 15:47:34 +02002315 buf->p = buf->data;
Emeric Brun46591952012-05-18 15:47:34 +02002316
2317 /* read the largest possible block. For this, we perform only one call
2318 * to recv() unless the buffer wraps and we exactly fill the first hunk,
2319 * in which case we accept to do it once again. A new attempt is made on
2320 * EINTR too.
2321 */
Willy Tarreau00b0fb92014-01-17 11:09:40 +01002322 while (count > 0) {
Willy Tarreauabf08d92014-01-14 11:31:27 +01002323 /* first check if we have some room after p+i */
2324 try = buf->data + buf->size - (buf->p + buf->i);
2325 /* otherwise continue between data and p-o */
2326 if (try <= 0) {
2327 try = buf->p - (buf->data + buf->o);
2328 if (try <= 0)
2329 break;
2330 }
2331 if (try > count)
2332 try = count;
2333
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02002334 ret = SSL_read(conn->xprt_ctx, bi_end(buf), try);
Emeric Brune1f38db2012-09-03 20:36:47 +02002335 if (conn->flags & CO_FL_ERROR) {
2336 /* CO_FL_ERROR may be set by ssl_sock_infocbk */
Emeric Brun644cde02012-12-14 11:21:13 +01002337 goto out_error;
Emeric Brune1f38db2012-09-03 20:36:47 +02002338 }
Emeric Brun46591952012-05-18 15:47:34 +02002339 if (ret > 0) {
2340 buf->i += ret;
2341 done += ret;
2342 if (ret < try)
2343 break;
2344 count -= ret;
Emeric Brun46591952012-05-18 15:47:34 +02002345 }
2346 else if (ret == 0) {
Emeric Brun644cde02012-12-14 11:21:13 +01002347 ret = SSL_get_error(conn->xprt_ctx, ret);
2348 if (ret != SSL_ERROR_ZERO_RETURN) {
Emeric Brun1c646862012-12-14 12:33:41 +01002349 /* error on protocol or underlying transport */
2350 if ((ret != SSL_ERROR_SYSCALL)
2351 || (errno && (errno != EAGAIN)))
2352 conn->flags |= CO_FL_ERROR;
2353
Emeric Brun644cde02012-12-14 11:21:13 +01002354 /* Clear openssl global errors stack */
2355 ERR_clear_error();
2356 }
Emeric Brun46591952012-05-18 15:47:34 +02002357 goto read0;
2358 }
2359 else {
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02002360 ret = SSL_get_error(conn->xprt_ctx, ret);
Emeric Brun46591952012-05-18 15:47:34 +02002361 if (ret == SSL_ERROR_WANT_WRITE) {
Emeric Brun8af8dd12012-11-08 17:56:20 +01002362 /* handshake is running, and it needs to enable write */
Emeric Brun46591952012-05-18 15:47:34 +02002363 conn->flags |= CO_FL_SSL_WAIT_HS;
Emeric Brun8af8dd12012-11-08 17:56:20 +01002364 __conn_sock_want_send(conn);
Emeric Brun46591952012-05-18 15:47:34 +02002365 break;
2366 }
2367 else if (ret == SSL_ERROR_WANT_READ) {
Emeric Brun282a76a2012-11-08 18:02:56 +01002368 if (SSL_renegotiate_pending(conn->xprt_ctx)) {
2369 /* handshake is running, and it may need to re-enable read */
2370 conn->flags |= CO_FL_SSL_WAIT_HS;
2371 __conn_sock_want_recv(conn);
2372 break;
2373 }
Emeric Brun46591952012-05-18 15:47:34 +02002374 /* we need to poll for retry a read later */
Willy Tarreaue1f50c42014-01-22 20:02:06 +01002375 fd_cant_recv(conn->t.sock.fd);
Emeric Brun46591952012-05-18 15:47:34 +02002376 break;
2377 }
2378 /* otherwise it's a real error */
2379 goto out_error;
2380 }
2381 }
2382 return done;
2383
2384 read0:
2385 conn_sock_read0(conn);
2386 return done;
2387 out_error:
Emeric Brun644cde02012-12-14 11:21:13 +01002388 /* Clear openssl global errors stack */
2389 ERR_clear_error();
2390
Emeric Brun46591952012-05-18 15:47:34 +02002391 conn->flags |= CO_FL_ERROR;
2392 return done;
2393}
2394
2395
2396/* Send all pending bytes from buffer <buf> to connection <conn>'s socket.
Willy Tarreau1049b1f2014-02-02 01:51:17 +01002397 * <flags> may contain some CO_SFL_* flags to hint the system about other
2398 * pending data for example, but this flag is ignored at the moment.
Emeric Brun46591952012-05-18 15:47:34 +02002399 * Only one call to send() is performed, unless the buffer wraps, in which case
2400 * a second call may be performed. The connection's flags are updated with
2401 * whatever special event is detected (error, empty). The caller is responsible
2402 * for taking care of those events and avoiding the call if inappropriate. The
2403 * function does not call the connection's polling update function, so the caller
2404 * is responsible for this.
2405 */
2406static int ssl_sock_from_buf(struct connection *conn, struct buffer *buf, int flags)
2407{
2408 int ret, try, done;
2409
2410 done = 0;
2411
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02002412 if (!conn->xprt_ctx)
Emeric Brun46591952012-05-18 15:47:34 +02002413 goto out_error;
2414
2415 if (conn->flags & CO_FL_HANDSHAKE)
2416 /* a handshake was requested */
2417 return 0;
2418
2419 /* send the largest possible block. For this we perform only one call
2420 * to send() unless the buffer wraps and we exactly fill the first hunk,
2421 * in which case we accept to do it once again.
2422 */
2423 while (buf->o) {
Kevin Hestercad82342013-05-30 15:12:41 -07002424 try = bo_contig_data(buf);
Willy Tarreaubfd59462013-02-21 07:46:09 +01002425
Willy Tarreau7bed9452014-02-02 02:00:24 +01002426 if (!(flags & CO_SFL_STREAMER) &&
Willy Tarreau518cedd2014-02-17 15:43:01 +01002427 !(conn->xprt_st & SSL_SOCK_SEND_UNLIMITED) &&
2428 global.tune.ssl_max_record && try > global.tune.ssl_max_record) {
Willy Tarreaubfd59462013-02-21 07:46:09 +01002429 try = global.tune.ssl_max_record;
Willy Tarreau518cedd2014-02-17 15:43:01 +01002430 }
2431 else {
2432 /* we need to keep the information about the fact that
2433 * we're not limiting the upcoming send(), because if it
2434 * fails, we'll have to retry with at least as many data.
2435 */
2436 conn->xprt_st |= SSL_SOCK_SEND_UNLIMITED;
2437 }
Willy Tarreaubfd59462013-02-21 07:46:09 +01002438
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02002439 ret = SSL_write(conn->xprt_ctx, bo_ptr(buf), try);
Willy Tarreau518cedd2014-02-17 15:43:01 +01002440
Emeric Brune1f38db2012-09-03 20:36:47 +02002441 if (conn->flags & CO_FL_ERROR) {
2442 /* CO_FL_ERROR may be set by ssl_sock_infocbk */
Emeric Brun644cde02012-12-14 11:21:13 +01002443 goto out_error;
Emeric Brune1f38db2012-09-03 20:36:47 +02002444 }
Emeric Brun46591952012-05-18 15:47:34 +02002445 if (ret > 0) {
Willy Tarreau518cedd2014-02-17 15:43:01 +01002446 conn->xprt_st &= ~SSL_SOCK_SEND_UNLIMITED;
2447
Emeric Brun46591952012-05-18 15:47:34 +02002448 buf->o -= ret;
2449 done += ret;
2450
Willy Tarreau5fb38032012-12-16 19:39:09 +01002451 if (likely(buffer_empty(buf)))
Emeric Brun46591952012-05-18 15:47:34 +02002452 /* optimize data alignment in the buffer */
2453 buf->p = buf->data;
2454
2455 /* if the system buffer is full, don't insist */
2456 if (ret < try)
2457 break;
2458 }
2459 else {
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02002460 ret = SSL_get_error(conn->xprt_ctx, ret);
Emeric Brun46591952012-05-18 15:47:34 +02002461 if (ret == SSL_ERROR_WANT_WRITE) {
Emeric Brun282a76a2012-11-08 18:02:56 +01002462 if (SSL_renegotiate_pending(conn->xprt_ctx)) {
2463 /* handshake is running, and it may need to re-enable write */
2464 conn->flags |= CO_FL_SSL_WAIT_HS;
2465 __conn_sock_want_send(conn);
2466 break;
2467 }
Emeric Brun46591952012-05-18 15:47:34 +02002468 /* we need to poll to retry a write later */
Willy Tarreaue1f50c42014-01-22 20:02:06 +01002469 fd_cant_send(conn->t.sock.fd);
Emeric Brun46591952012-05-18 15:47:34 +02002470 break;
2471 }
2472 else if (ret == SSL_ERROR_WANT_READ) {
Emeric Brun8af8dd12012-11-08 17:56:20 +01002473 /* handshake is running, and it needs to enable read */
Emeric Brun46591952012-05-18 15:47:34 +02002474 conn->flags |= CO_FL_SSL_WAIT_HS;
Emeric Brun8af8dd12012-11-08 17:56:20 +01002475 __conn_sock_want_recv(conn);
Emeric Brun46591952012-05-18 15:47:34 +02002476 break;
2477 }
2478 goto out_error;
2479 }
2480 }
2481 return done;
2482
2483 out_error:
Emeric Brun644cde02012-12-14 11:21:13 +01002484 /* Clear openssl global errors stack */
2485 ERR_clear_error();
2486
Emeric Brun46591952012-05-18 15:47:34 +02002487 conn->flags |= CO_FL_ERROR;
2488 return done;
2489}
2490
Emeric Brun46591952012-05-18 15:47:34 +02002491static void ssl_sock_close(struct connection *conn) {
2492
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02002493 if (conn->xprt_ctx) {
2494 SSL_free(conn->xprt_ctx);
2495 conn->xprt_ctx = NULL;
Willy Tarreau403edff2012-09-06 11:58:37 +02002496 sslconns--;
Emeric Brun46591952012-05-18 15:47:34 +02002497 }
Emeric Brun46591952012-05-18 15:47:34 +02002498}
2499
2500/* This function tries to perform a clean shutdown on an SSL connection, and in
2501 * any case, flags the connection as reusable if no handshake was in progress.
2502 */
2503static void ssl_sock_shutw(struct connection *conn, int clean)
2504{
2505 if (conn->flags & CO_FL_HANDSHAKE)
2506 return;
2507 /* no handshake was in progress, try a clean ssl shutdown */
Emeric Brun644cde02012-12-14 11:21:13 +01002508 if (clean && (SSL_shutdown(conn->xprt_ctx) <= 0)) {
2509 /* Clear openssl global errors stack */
2510 ERR_clear_error();
2511 }
Emeric Brun46591952012-05-18 15:47:34 +02002512
2513 /* force flag on ssl to keep session in cache regardless shutdown result */
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02002514 SSL_set_shutdown(conn->xprt_ctx, SSL_SENT_SHUTDOWN);
Emeric Brun46591952012-05-18 15:47:34 +02002515}
2516
Willy Tarreauffc3fcd2012-10-12 20:17:54 +02002517/* used for logging, may be changed for a sample fetch later */
2518const char *ssl_sock_get_cipher_name(struct connection *conn)
2519{
2520 if (!conn->xprt && !conn->xprt_ctx)
2521 return NULL;
2522 return SSL_get_cipher_name(conn->xprt_ctx);
2523}
2524
2525/* used for logging, may be changed for a sample fetch later */
2526const char *ssl_sock_get_proto_version(struct connection *conn)
2527{
2528 if (!conn->xprt && !conn->xprt_ctx)
2529 return NULL;
2530 return SSL_get_version(conn->xprt_ctx);
2531}
2532
Willy Tarreau8d598402012-10-22 17:58:39 +02002533/* Extract a serial from a cert, and copy it to a chunk.
2534 * Returns 1 if serial is found and copied, 0 if no serial found and
2535 * -1 if output is not large enough.
2536 */
2537static int
2538ssl_sock_get_serial(X509 *crt, struct chunk *out)
2539{
2540 ASN1_INTEGER *serial;
2541
2542 serial = X509_get_serialNumber(crt);
2543 if (!serial)
2544 return 0;
2545
2546 if (out->size < serial->length)
2547 return -1;
2548
2549 memcpy(out->str, serial->data, serial->length);
2550 out->len = serial->length;
2551 return 1;
2552}
2553
Emeric Brunce5ad802012-10-22 14:11:22 +02002554
2555/* Copy Date in ASN1_UTCTIME format in struct chunk out.
2556 * Returns 1 if serial is found and copied, 0 if no valid time found
2557 * and -1 if output is not large enough.
2558 */
2559static int
2560ssl_sock_get_time(ASN1_TIME *tm, struct chunk *out)
2561{
2562 if (tm->type == V_ASN1_GENERALIZEDTIME) {
2563 ASN1_GENERALIZEDTIME *gentm = (ASN1_GENERALIZEDTIME *)tm;
2564
2565 if (gentm->length < 12)
2566 return 0;
2567 if (gentm->data[0] != 0x32 || gentm->data[1] != 0x30)
2568 return 0;
2569 if (out->size < gentm->length-2)
2570 return -1;
2571
2572 memcpy(out->str, gentm->data+2, gentm->length-2);
2573 out->len = gentm->length-2;
2574 return 1;
2575 }
2576 else if (tm->type == V_ASN1_UTCTIME) {
2577 ASN1_UTCTIME *utctm = (ASN1_UTCTIME *)tm;
2578
2579 if (utctm->length < 10)
2580 return 0;
2581 if (utctm->data[0] >= 0x35)
2582 return 0;
2583 if (out->size < utctm->length)
2584 return -1;
2585
2586 memcpy(out->str, utctm->data, utctm->length);
2587 out->len = utctm->length;
2588 return 1;
2589 }
2590
2591 return 0;
2592}
2593
Emeric Brun87855892012-10-17 17:39:35 +02002594/* Extract an entry from a X509_NAME and copy its value to an output chunk.
2595 * Returns 1 if entry found, 0 if entry not found, or -1 if output not large enough.
2596 */
2597static int
2598ssl_sock_get_dn_entry(X509_NAME *a, const struct chunk *entry, int pos, struct chunk *out)
2599{
2600 X509_NAME_ENTRY *ne;
2601 int i, j, n;
2602 int cur = 0;
2603 const char *s;
2604 char tmp[128];
2605
2606 out->len = 0;
2607 for (i = 0; i < sk_X509_NAME_ENTRY_num(a->entries); i++) {
2608 if (pos < 0)
2609 j = (sk_X509_NAME_ENTRY_num(a->entries)-1) - i;
2610 else
2611 j = i;
2612
2613 ne = sk_X509_NAME_ENTRY_value(a->entries, j);
2614 n = OBJ_obj2nid(ne->object);
2615 if ((n == NID_undef) || ((s = OBJ_nid2sn(n)) == NULL)) {
2616 i2t_ASN1_OBJECT(tmp, sizeof(tmp), ne->object);
2617 s = tmp;
2618 }
2619
2620 if (chunk_strcasecmp(entry, s) != 0)
2621 continue;
2622
2623 if (pos < 0)
2624 cur--;
2625 else
2626 cur++;
2627
2628 if (cur != pos)
2629 continue;
2630
2631 if (ne->value->length > out->size)
2632 return -1;
2633
2634 memcpy(out->str, ne->value->data, ne->value->length);
2635 out->len = ne->value->length;
2636 return 1;
2637 }
2638
2639 return 0;
2640
2641}
2642
2643/* Extract and format full DN from a X509_NAME and copy result into a chunk
2644 * Returns 1 if dn entries exits, 0 if no dn entry found or -1 if output is not large enough.
2645 */
2646static int
2647ssl_sock_get_dn_oneline(X509_NAME *a, struct chunk *out)
2648{
2649 X509_NAME_ENTRY *ne;
2650 int i, n, ln;
2651 int l = 0;
2652 const char *s;
2653 char *p;
2654 char tmp[128];
2655
2656 out->len = 0;
2657 p = out->str;
2658 for (i = 0; i < sk_X509_NAME_ENTRY_num(a->entries); i++) {
2659 ne = sk_X509_NAME_ENTRY_value(a->entries, i);
2660 n = OBJ_obj2nid(ne->object);
2661 if ((n == NID_undef) || ((s = OBJ_nid2sn(n)) == NULL)) {
2662 i2t_ASN1_OBJECT(tmp, sizeof(tmp), ne->object);
2663 s = tmp;
2664 }
2665 ln = strlen(s);
2666
2667 l += 1 + ln + 1 + ne->value->length;
2668 if (l > out->size)
2669 return -1;
2670 out->len = l;
2671
2672 *(p++)='/';
2673 memcpy(p, s, ln);
2674 p += ln;
2675 *(p++)='=';
2676 memcpy(p, ne->value->data, ne->value->length);
2677 p += ne->value->length;
2678 }
2679
2680 if (!out->len)
2681 return 0;
2682
2683 return 1;
2684}
2685
David Safb76832014-05-08 23:42:08 -04002686char *ssl_sock_get_version(struct connection *conn)
2687{
2688 if (!ssl_sock_is_ssl(conn))
2689 return NULL;
2690
2691 return (char *)SSL_get_version(conn->xprt_ctx);
2692}
2693
Emeric Brun0abf8362014-06-24 18:26:41 +02002694/* Extract peer certificate's common name into the chunk dest
2695 * Returns
2696 * the len of the extracted common name
2697 * or 0 if no CN found in DN
2698 * or -1 on error case (i.e. no peer certificate)
2699 */
2700int ssl_sock_get_remote_common_name(struct connection *conn, struct chunk *dest)
David Safb76832014-05-08 23:42:08 -04002701{
2702 X509 *crt = NULL;
2703 X509_NAME *name;
David Safb76832014-05-08 23:42:08 -04002704 const char find_cn[] = "CN";
2705 const struct chunk find_cn_chunk = {
2706 .str = (char *)&find_cn,
2707 .len = sizeof(find_cn)-1
2708 };
Emeric Brun0abf8362014-06-24 18:26:41 +02002709 int result = -1;
David Safb76832014-05-08 23:42:08 -04002710
2711 if (!ssl_sock_is_ssl(conn))
Emeric Brun0abf8362014-06-24 18:26:41 +02002712 goto out;
David Safb76832014-05-08 23:42:08 -04002713
2714 /* SSL_get_peer_certificate, it increase X509 * ref count */
2715 crt = SSL_get_peer_certificate(conn->xprt_ctx);
2716 if (!crt)
2717 goto out;
2718
2719 name = X509_get_subject_name(crt);
2720 if (!name)
2721 goto out;
David Safb76832014-05-08 23:42:08 -04002722
Emeric Brun0abf8362014-06-24 18:26:41 +02002723 result = ssl_sock_get_dn_entry(name, &find_cn_chunk, 1, dest);
2724out:
David Safb76832014-05-08 23:42:08 -04002725 if (crt)
2726 X509_free(crt);
2727
2728 return result;
2729}
2730
Dave McCowan328fb582014-07-30 10:39:13 -04002731/* returns 1 if client passed a certificate for this session, 0 if not */
2732int ssl_sock_get_cert_used_sess(struct connection *conn)
2733{
2734 X509 *crt = NULL;
2735
2736 if (!ssl_sock_is_ssl(conn))
2737 return 0;
2738
2739 /* SSL_get_peer_certificate, it increase X509 * ref count */
2740 crt = SSL_get_peer_certificate(conn->xprt_ctx);
2741 if (!crt)
2742 return 0;
2743
2744 X509_free(crt);
2745 return 1;
2746}
2747
2748/* returns 1 if client passed a certificate for this connection, 0 if not */
2749int ssl_sock_get_cert_used_conn(struct connection *conn)
David Safb76832014-05-08 23:42:08 -04002750{
2751 if (!ssl_sock_is_ssl(conn))
2752 return 0;
2753
2754 return SSL_SOCK_ST_FL_VERIFY_DONE & conn->xprt_st ? 1 : 0;
2755}
2756
2757/* returns result from SSL verify */
2758unsigned int ssl_sock_get_verify_result(struct connection *conn)
2759{
2760 if (!ssl_sock_is_ssl(conn))
2761 return (unsigned int)X509_V_ERR_APPLICATION_VERIFICATION;
2762
2763 return (unsigned int)SSL_get_verify_result(conn->xprt_ctx);
2764}
2765
Willy Tarreau7875d092012-09-10 08:20:03 +02002766/***** Below are some sample fetching functions for ACL/patterns *****/
2767
Emeric Brune64aef12012-09-21 13:15:06 +02002768/* boolean, returns true if client cert was present */
2769static int
Emeric Brun2525b6b2012-10-18 15:59:43 +02002770smp_fetch_ssl_fc_has_crt(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002771 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brune64aef12012-09-21 13:15:06 +02002772{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002773 struct connection *conn;
2774
2775 if (!l4)
2776 return 0;
2777
2778 conn = objt_conn(l4->si[0].end);
2779 if (!conn || conn->xprt != &ssl_sock)
Emeric Brune64aef12012-09-21 13:15:06 +02002780 return 0;
2781
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002782 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brune64aef12012-09-21 13:15:06 +02002783 smp->flags |= SMP_F_MAY_CHANGE;
2784 return 0;
2785 }
2786
2787 smp->flags = 0;
2788 smp->type = SMP_T_BOOL;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002789 smp->data.uint = SSL_SOCK_ST_FL_VERIFY_DONE & conn->xprt_st ? 1 : 0;
Emeric Brune64aef12012-09-21 13:15:06 +02002790
2791 return 1;
2792}
2793
Emeric Brunba841a12014-04-30 17:05:08 +02002794/* binary, returns serial of certificate in a binary chunk.
2795 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
2796 * should be use.
2797 */
Willy Tarreau8d598402012-10-22 17:58:39 +02002798static int
Emeric Brunba841a12014-04-30 17:05:08 +02002799smp_fetch_ssl_x_serial(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002800 const struct arg *args, struct sample *smp, const char *kw)
Willy Tarreau8d598402012-10-22 17:58:39 +02002801{
Emeric Brunba841a12014-04-30 17:05:08 +02002802 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Willy Tarreau8d598402012-10-22 17:58:39 +02002803 X509 *crt = NULL;
2804 int ret = 0;
2805 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002806 struct connection *conn;
2807
2808 if (!l4)
2809 return 0;
Willy Tarreau8d598402012-10-22 17:58:39 +02002810
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002811 conn = objt_conn(l4->si[0].end);
2812 if (!conn || conn->xprt != &ssl_sock)
Willy Tarreau8d598402012-10-22 17:58:39 +02002813 return 0;
2814
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002815 if (!(conn->flags & CO_FL_CONNECTED)) {
Willy Tarreau8d598402012-10-22 17:58:39 +02002816 smp->flags |= SMP_F_MAY_CHANGE;
2817 return 0;
2818 }
2819
Emeric Brunba841a12014-04-30 17:05:08 +02002820 if (cert_peer)
2821 crt = SSL_get_peer_certificate(conn->xprt_ctx);
2822 else
2823 crt = SSL_get_certificate(conn->xprt_ctx);
2824
Willy Tarreau8d598402012-10-22 17:58:39 +02002825 if (!crt)
2826 goto out;
2827
Willy Tarreau47ca5452012-12-23 20:22:19 +01002828 smp_trash = get_trash_chunk();
Willy Tarreau8d598402012-10-22 17:58:39 +02002829 if (ssl_sock_get_serial(crt, smp_trash) <= 0)
2830 goto out;
2831
2832 smp->data.str = *smp_trash;
2833 smp->type = SMP_T_BIN;
2834 ret = 1;
2835out:
Emeric Brunba841a12014-04-30 17:05:08 +02002836 /* SSL_get_peer_certificate, it increase X509 * ref count */
2837 if (cert_peer && crt)
Willy Tarreau8d598402012-10-22 17:58:39 +02002838 X509_free(crt);
2839 return ret;
2840}
Emeric Brune64aef12012-09-21 13:15:06 +02002841
Emeric Brunba841a12014-04-30 17:05:08 +02002842/* binary, returns the client certificate's SHA-1 fingerprint (SHA-1 hash of DER-encoded certificate) in a binary chunk.
2843 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
2844 * should be use.
2845 */
James Votha051b4a2013-05-14 20:37:59 +02002846static int
Emeric Brunba841a12014-04-30 17:05:08 +02002847smp_fetch_ssl_x_sha1(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002848 const struct arg *args, struct sample *smp, const char *kw)
James Votha051b4a2013-05-14 20:37:59 +02002849{
Emeric Brunba841a12014-04-30 17:05:08 +02002850 int cert_peer = (kw[4] == 'c') ? 1 : 0;
James Votha051b4a2013-05-14 20:37:59 +02002851 X509 *crt = NULL;
2852 const EVP_MD *digest;
2853 int ret = 0;
2854 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002855 struct connection *conn;
James Votha051b4a2013-05-14 20:37:59 +02002856
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002857 if (!l4)
James Votha051b4a2013-05-14 20:37:59 +02002858 return 0;
2859
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002860 conn = objt_conn(l4->si[0].end);
2861 if (!conn || conn->xprt != &ssl_sock)
2862 return 0;
2863
2864 if (!(conn->flags & CO_FL_CONNECTED)) {
James Votha051b4a2013-05-14 20:37:59 +02002865 smp->flags |= SMP_F_MAY_CHANGE;
2866 return 0;
2867 }
2868
Emeric Brunba841a12014-04-30 17:05:08 +02002869 if (cert_peer)
2870 crt = SSL_get_peer_certificate(conn->xprt_ctx);
2871 else
2872 crt = SSL_get_certificate(conn->xprt_ctx);
James Votha051b4a2013-05-14 20:37:59 +02002873 if (!crt)
2874 goto out;
2875
2876 smp_trash = get_trash_chunk();
2877 digest = EVP_sha1();
2878 X509_digest(crt, digest, (unsigned char *)smp_trash->str, (unsigned int *)&smp_trash->len);
2879
2880 smp->data.str = *smp_trash;
2881 smp->type = SMP_T_BIN;
2882 ret = 1;
2883out:
Emeric Brunba841a12014-04-30 17:05:08 +02002884 /* SSL_get_peer_certificate, it increase X509 * ref count */
2885 if (cert_peer && crt)
James Votha051b4a2013-05-14 20:37:59 +02002886 X509_free(crt);
2887 return ret;
2888}
2889
Emeric Brunba841a12014-04-30 17:05:08 +02002890/* string, returns certificate's notafter date in ASN1_UTCTIME format.
2891 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
2892 * should be use.
2893 */
Emeric Brunce5ad802012-10-22 14:11:22 +02002894static int
Emeric Brunba841a12014-04-30 17:05:08 +02002895smp_fetch_ssl_x_notafter(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002896 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brunce5ad802012-10-22 14:11:22 +02002897{
Emeric Brunba841a12014-04-30 17:05:08 +02002898 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brunce5ad802012-10-22 14:11:22 +02002899 X509 *crt = NULL;
2900 int ret = 0;
2901 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002902 struct connection *conn;
Emeric Brunce5ad802012-10-22 14:11:22 +02002903
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002904 if (!l4)
Emeric Brunce5ad802012-10-22 14:11:22 +02002905 return 0;
2906
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002907 conn = objt_conn(l4->si[0].end);
2908 if (!conn || conn->xprt != &ssl_sock)
2909 return 0;
2910
2911 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunce5ad802012-10-22 14:11:22 +02002912 smp->flags |= SMP_F_MAY_CHANGE;
2913 return 0;
2914 }
2915
Emeric Brunba841a12014-04-30 17:05:08 +02002916 if (cert_peer)
2917 crt = SSL_get_peer_certificate(conn->xprt_ctx);
2918 else
2919 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brunce5ad802012-10-22 14:11:22 +02002920 if (!crt)
2921 goto out;
2922
Willy Tarreau47ca5452012-12-23 20:22:19 +01002923 smp_trash = get_trash_chunk();
Emeric Brunce5ad802012-10-22 14:11:22 +02002924 if (ssl_sock_get_time(X509_get_notAfter(crt), smp_trash) <= 0)
2925 goto out;
2926
2927 smp->data.str = *smp_trash;
2928 smp->type = SMP_T_STR;
2929 ret = 1;
2930out:
Emeric Brunba841a12014-04-30 17:05:08 +02002931 /* SSL_get_peer_certificate, it increase X509 * ref count */
2932 if (cert_peer && crt)
Emeric Brunce5ad802012-10-22 14:11:22 +02002933 X509_free(crt);
2934 return ret;
2935}
2936
Emeric Brunba841a12014-04-30 17:05:08 +02002937/* string, returns a string of a formatted full dn \C=..\O=..\OU=.. \CN=.. of certificate's issuer
2938 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
2939 * should be use.
2940 */
Emeric Brun87855892012-10-17 17:39:35 +02002941static int
Emeric Brunba841a12014-04-30 17:05:08 +02002942smp_fetch_ssl_x_i_dn(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002943 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brun87855892012-10-17 17:39:35 +02002944{
Emeric Brunba841a12014-04-30 17:05:08 +02002945 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brun87855892012-10-17 17:39:35 +02002946 X509 *crt = NULL;
2947 X509_NAME *name;
2948 int ret = 0;
2949 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002950 struct connection *conn;
Emeric Brun87855892012-10-17 17:39:35 +02002951
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002952 if (!l4)
Emeric Brun87855892012-10-17 17:39:35 +02002953 return 0;
2954
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002955 conn = objt_conn(l4->si[0].end);
2956 if (!conn || conn->xprt != &ssl_sock)
2957 return 0;
2958
2959 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun87855892012-10-17 17:39:35 +02002960 smp->flags |= SMP_F_MAY_CHANGE;
2961 return 0;
2962 }
2963
Emeric Brunba841a12014-04-30 17:05:08 +02002964 if (cert_peer)
2965 crt = SSL_get_peer_certificate(conn->xprt_ctx);
2966 else
2967 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brun87855892012-10-17 17:39:35 +02002968 if (!crt)
2969 goto out;
2970
2971 name = X509_get_issuer_name(crt);
2972 if (!name)
2973 goto out;
2974
Willy Tarreau47ca5452012-12-23 20:22:19 +01002975 smp_trash = get_trash_chunk();
Emeric Brun87855892012-10-17 17:39:35 +02002976 if (args && args[0].type == ARGT_STR) {
2977 int pos = 1;
2978
2979 if (args[1].type == ARGT_SINT)
2980 pos = args[1].data.sint;
2981 else if (args[1].type == ARGT_UINT)
2982 pos =(int)args[1].data.uint;
2983
2984 if (ssl_sock_get_dn_entry(name, &args[0].data.str, pos, smp_trash) <= 0)
2985 goto out;
2986 }
2987 else if (ssl_sock_get_dn_oneline(name, smp_trash) <= 0)
2988 goto out;
2989
2990 smp->type = SMP_T_STR;
2991 smp->data.str = *smp_trash;
2992 ret = 1;
2993out:
Emeric Brunba841a12014-04-30 17:05:08 +02002994 /* SSL_get_peer_certificate, it increase X509 * ref count */
2995 if (cert_peer && crt)
Emeric Brun87855892012-10-17 17:39:35 +02002996 X509_free(crt);
2997 return ret;
2998}
2999
Emeric Brunba841a12014-04-30 17:05:08 +02003000/* string, returns notbefore date in ASN1_UTCTIME format.
3001 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
3002 * should be use.
3003 */
Emeric Brunce5ad802012-10-22 14:11:22 +02003004static int
Emeric Brunba841a12014-04-30 17:05:08 +02003005smp_fetch_ssl_x_notbefore(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003006 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brunce5ad802012-10-22 14:11:22 +02003007{
Emeric Brunba841a12014-04-30 17:05:08 +02003008 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brunce5ad802012-10-22 14:11:22 +02003009 X509 *crt = NULL;
3010 int ret = 0;
3011 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003012 struct connection *conn;
3013
3014 if (!l4)
3015 return 0;
Emeric Brunce5ad802012-10-22 14:11:22 +02003016
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003017 conn = objt_conn(l4->si[0].end);
3018 if (!conn || conn->xprt != &ssl_sock)
Emeric Brunce5ad802012-10-22 14:11:22 +02003019 return 0;
3020
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003021 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunce5ad802012-10-22 14:11:22 +02003022 smp->flags |= SMP_F_MAY_CHANGE;
3023 return 0;
3024 }
3025
Emeric Brunba841a12014-04-30 17:05:08 +02003026 if (cert_peer)
3027 crt = SSL_get_peer_certificate(conn->xprt_ctx);
3028 else
3029 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brunce5ad802012-10-22 14:11:22 +02003030 if (!crt)
3031 goto out;
3032
Willy Tarreau47ca5452012-12-23 20:22:19 +01003033 smp_trash = get_trash_chunk();
Emeric Brunce5ad802012-10-22 14:11:22 +02003034 if (ssl_sock_get_time(X509_get_notBefore(crt), smp_trash) <= 0)
3035 goto out;
3036
3037 smp->data.str = *smp_trash;
3038 smp->type = SMP_T_STR;
3039 ret = 1;
3040out:
Emeric Brunba841a12014-04-30 17:05:08 +02003041 /* SSL_get_peer_certificate, it increase X509 * ref count */
3042 if (cert_peer && crt)
Emeric Brunce5ad802012-10-22 14:11:22 +02003043 X509_free(crt);
3044 return ret;
3045}
3046
Emeric Brunba841a12014-04-30 17:05:08 +02003047/* string, returns a string of a formatted full dn \C=..\O=..\OU=.. \CN=.. of certificate's subject
3048 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
3049 * should be use.
3050 */
Emeric Brun87855892012-10-17 17:39:35 +02003051static int
Emeric Brunba841a12014-04-30 17:05:08 +02003052smp_fetch_ssl_x_s_dn(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003053 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brun87855892012-10-17 17:39:35 +02003054{
Emeric Brunba841a12014-04-30 17:05:08 +02003055 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brun87855892012-10-17 17:39:35 +02003056 X509 *crt = NULL;
3057 X509_NAME *name;
3058 int ret = 0;
3059 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003060 struct connection *conn;
Emeric Brun87855892012-10-17 17:39:35 +02003061
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003062 if (!l4)
Emeric Brun87855892012-10-17 17:39:35 +02003063 return 0;
3064
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003065 conn = objt_conn(l4->si[0].end);
3066 if (!conn || conn->xprt != &ssl_sock)
3067 return 0;
3068
3069 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun87855892012-10-17 17:39:35 +02003070 smp->flags |= SMP_F_MAY_CHANGE;
3071 return 0;
3072 }
3073
Emeric Brunba841a12014-04-30 17:05:08 +02003074 if (cert_peer)
3075 crt = SSL_get_peer_certificate(conn->xprt_ctx);
3076 else
3077 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brun87855892012-10-17 17:39:35 +02003078 if (!crt)
3079 goto out;
3080
3081 name = X509_get_subject_name(crt);
3082 if (!name)
3083 goto out;
3084
Willy Tarreau47ca5452012-12-23 20:22:19 +01003085 smp_trash = get_trash_chunk();
Emeric Brun87855892012-10-17 17:39:35 +02003086 if (args && args[0].type == ARGT_STR) {
3087 int pos = 1;
3088
3089 if (args[1].type == ARGT_SINT)
3090 pos = args[1].data.sint;
3091 else if (args[1].type == ARGT_UINT)
3092 pos =(int)args[1].data.uint;
3093
3094 if (ssl_sock_get_dn_entry(name, &args[0].data.str, pos, smp_trash) <= 0)
3095 goto out;
3096 }
3097 else if (ssl_sock_get_dn_oneline(name, smp_trash) <= 0)
3098 goto out;
3099
3100 smp->type = SMP_T_STR;
3101 smp->data.str = *smp_trash;
3102 ret = 1;
3103out:
Emeric Brunba841a12014-04-30 17:05:08 +02003104 /* SSL_get_peer_certificate, it increase X509 * ref count */
3105 if (cert_peer && crt)
Emeric Brun87855892012-10-17 17:39:35 +02003106 X509_free(crt);
3107 return ret;
3108}
Emeric Brun9143d372012-12-20 15:44:16 +01003109
3110/* integer, returns true if current session use a client certificate */
3111static int
3112smp_fetch_ssl_c_used(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003113 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brun9143d372012-12-20 15:44:16 +01003114{
3115 X509 *crt;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003116 struct connection *conn;
Emeric Brun9143d372012-12-20 15:44:16 +01003117
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003118 if (!l4)
Emeric Brun9143d372012-12-20 15:44:16 +01003119 return 0;
3120
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003121 conn = objt_conn(l4->si[0].end);
3122 if (!conn || conn->xprt != &ssl_sock)
3123 return 0;
3124
3125 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun9143d372012-12-20 15:44:16 +01003126 smp->flags |= SMP_F_MAY_CHANGE;
3127 return 0;
3128 }
3129
3130 /* SSL_get_peer_certificate returns a ptr on allocated X509 struct */
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003131 crt = SSL_get_peer_certificate(conn->xprt_ctx);
Emeric Brun9143d372012-12-20 15:44:16 +01003132 if (crt) {
3133 X509_free(crt);
3134 }
3135
3136 smp->type = SMP_T_BOOL;
3137 smp->data.uint = (crt != NULL);
3138 return 1;
3139}
3140
Emeric Brunba841a12014-04-30 17:05:08 +02003141/* integer, returns the certificate version
3142 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
3143 * should be use.
3144 */
Emeric Bruna7359fd2012-10-17 15:03:11 +02003145static int
Emeric Brunba841a12014-04-30 17:05:08 +02003146smp_fetch_ssl_x_version(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003147 const struct arg *args, struct sample *smp, const char *kw)
Emeric Bruna7359fd2012-10-17 15:03:11 +02003148{
Emeric Brunba841a12014-04-30 17:05:08 +02003149 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Bruna7359fd2012-10-17 15:03:11 +02003150 X509 *crt;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003151 struct connection *conn;
3152
3153 if (!l4)
3154 return 0;
Emeric Bruna7359fd2012-10-17 15:03:11 +02003155
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003156 conn = objt_conn(l4->si[0].end);
3157 if (!conn || conn->xprt != &ssl_sock)
Emeric Bruna7359fd2012-10-17 15:03:11 +02003158 return 0;
3159
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003160 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Bruna7359fd2012-10-17 15:03:11 +02003161 smp->flags |= SMP_F_MAY_CHANGE;
3162 return 0;
3163 }
3164
Emeric Brunba841a12014-04-30 17:05:08 +02003165 if (cert_peer)
3166 crt = SSL_get_peer_certificate(conn->xprt_ctx);
3167 else
3168 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Bruna7359fd2012-10-17 15:03:11 +02003169 if (!crt)
3170 return 0;
3171
3172 smp->data.uint = (unsigned int)(1 + X509_get_version(crt));
Emeric Brunba841a12014-04-30 17:05:08 +02003173 /* SSL_get_peer_certificate increase X509 * ref count */
3174 if (cert_peer)
3175 X509_free(crt);
Emeric Bruna7359fd2012-10-17 15:03:11 +02003176 smp->type = SMP_T_UINT;
3177
3178 return 1;
3179}
3180
Emeric Brunba841a12014-04-30 17:05:08 +02003181/* string, returns the certificate's signature algorithm.
3182 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
3183 * should be use.
3184 */
Emeric Brun7f56e742012-10-19 18:15:40 +02003185static int
Emeric Brunba841a12014-04-30 17:05:08 +02003186smp_fetch_ssl_x_sig_alg(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003187 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brun7f56e742012-10-19 18:15:40 +02003188{
Emeric Brunba841a12014-04-30 17:05:08 +02003189 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brun7f56e742012-10-19 18:15:40 +02003190 X509 *crt;
3191 int nid;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003192 struct connection *conn;
Emeric Brun7f56e742012-10-19 18:15:40 +02003193
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003194 if (!l4)
Emeric Brun7f56e742012-10-19 18:15:40 +02003195 return 0;
3196
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003197 conn = objt_conn(l4->si[0].end);
3198 if (!conn || conn->xprt != &ssl_sock)
3199 return 0;
3200
3201 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun7f56e742012-10-19 18:15:40 +02003202 smp->flags |= SMP_F_MAY_CHANGE;
3203 return 0;
3204 }
3205
Emeric Brunba841a12014-04-30 17:05:08 +02003206 if (cert_peer)
3207 crt = SSL_get_peer_certificate(conn->xprt_ctx);
3208 else
3209 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brun7f56e742012-10-19 18:15:40 +02003210 if (!crt)
3211 return 0;
3212
3213 nid = OBJ_obj2nid((ASN1_OBJECT *)(crt->cert_info->signature->algorithm));
3214
3215 smp->data.str.str = (char *)OBJ_nid2sn(nid);
Emeric Brun9bf3ba22013-10-07 14:31:44 +02003216 if (!smp->data.str.str) {
Emeric Brunba841a12014-04-30 17:05:08 +02003217 /* SSL_get_peer_certificate increase X509 * ref count */
3218 if (cert_peer)
3219 X509_free(crt);
Emeric Brun7f56e742012-10-19 18:15:40 +02003220 return 0;
Emeric Brun9bf3ba22013-10-07 14:31:44 +02003221 }
Emeric Brun7f56e742012-10-19 18:15:40 +02003222
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01003223 smp->type = SMP_T_STR;
3224 smp->flags |= SMP_F_CONST;
Emeric Brun7f56e742012-10-19 18:15:40 +02003225 smp->data.str.len = strlen(smp->data.str.str);
Emeric Brunba841a12014-04-30 17:05:08 +02003226 /* SSL_get_peer_certificate increase X509 * ref count */
3227 if (cert_peer)
3228 X509_free(crt);
Emeric Brun7f56e742012-10-19 18:15:40 +02003229
3230 return 1;
3231}
3232
Emeric Brunba841a12014-04-30 17:05:08 +02003233/* string, returns the certificate's key algorithm.
3234 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
3235 * should be use.
3236 */
Emeric Brun521a0112012-10-22 12:22:55 +02003237static int
Emeric Brunba841a12014-04-30 17:05:08 +02003238smp_fetch_ssl_x_key_alg(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003239 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brun521a0112012-10-22 12:22:55 +02003240{
Emeric Brunba841a12014-04-30 17:05:08 +02003241 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brun521a0112012-10-22 12:22:55 +02003242 X509 *crt;
3243 int nid;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003244 struct connection *conn;
Emeric Brun521a0112012-10-22 12:22:55 +02003245
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003246 if (!l4)
Emeric Brun521a0112012-10-22 12:22:55 +02003247 return 0;
3248
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003249 conn = objt_conn(l4->si[0].end);
3250 if (!conn || conn->xprt != &ssl_sock)
3251 return 0;
3252
3253 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun521a0112012-10-22 12:22:55 +02003254 smp->flags |= SMP_F_MAY_CHANGE;
3255 return 0;
3256 }
3257
Emeric Brunba841a12014-04-30 17:05:08 +02003258 if (cert_peer)
3259 crt = SSL_get_peer_certificate(conn->xprt_ctx);
3260 else
3261 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brun521a0112012-10-22 12:22:55 +02003262 if (!crt)
3263 return 0;
3264
3265 nid = OBJ_obj2nid((ASN1_OBJECT *)(crt->cert_info->key->algor->algorithm));
3266
3267 smp->data.str.str = (char *)OBJ_nid2sn(nid);
Emeric Brun9bf3ba22013-10-07 14:31:44 +02003268 if (!smp->data.str.str) {
Emeric Brunba841a12014-04-30 17:05:08 +02003269 /* SSL_get_peer_certificate increase X509 * ref count */
3270 if (cert_peer)
3271 X509_free(crt);
Emeric Brun521a0112012-10-22 12:22:55 +02003272 return 0;
Emeric Brun9bf3ba22013-10-07 14:31:44 +02003273 }
Emeric Brun521a0112012-10-22 12:22:55 +02003274
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01003275 smp->type = SMP_T_STR;
3276 smp->flags |= SMP_F_CONST;
Emeric Brun521a0112012-10-22 12:22:55 +02003277 smp->data.str.len = strlen(smp->data.str.str);
Emeric Brunba841a12014-04-30 17:05:08 +02003278 if (cert_peer)
3279 X509_free(crt);
Emeric Brun521a0112012-10-22 12:22:55 +02003280
3281 return 1;
3282}
3283
Emeric Brun645ae792014-04-30 14:21:06 +02003284/* boolean, returns true if front conn. transport layer is SSL.
3285 * This function is also usable on backend conn if the fetch keyword 5th
3286 * char is 'b'.
3287 */
Willy Tarreau7875d092012-09-10 08:20:03 +02003288static int
Emeric Brun2525b6b2012-10-18 15:59:43 +02003289smp_fetch_ssl_fc(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003290 const struct arg *args, struct sample *smp, const char *kw)
Willy Tarreau7875d092012-09-10 08:20:03 +02003291{
Emeric Brun645ae792014-04-30 14:21:06 +02003292 int back_conn = (kw[4] == 'b') ? 1 : 0;
3293 struct connection *conn = objt_conn(l4->si[back_conn].end);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003294
Willy Tarreau7875d092012-09-10 08:20:03 +02003295 smp->type = SMP_T_BOOL;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003296 smp->data.uint = (conn && conn->xprt == &ssl_sock);
Willy Tarreau7875d092012-09-10 08:20:03 +02003297 return 1;
3298}
3299
Emeric Brun2525b6b2012-10-18 15:59:43 +02003300/* boolean, returns true if client present a SNI */
Willy Tarreau7875d092012-09-10 08:20:03 +02003301static int
Emeric Brun2525b6b2012-10-18 15:59:43 +02003302smp_fetch_ssl_fc_has_sni(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003303 const struct arg *args, struct sample *smp, const char *kw)
Willy Tarreau7875d092012-09-10 08:20:03 +02003304{
3305#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003306 struct connection *conn = objt_conn(l4->si[0].end);
3307
Willy Tarreau7875d092012-09-10 08:20:03 +02003308 smp->type = SMP_T_BOOL;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003309 smp->data.uint = (conn && conn->xprt == &ssl_sock) &&
3310 conn->xprt_ctx &&
3311 SSL_get_servername(conn->xprt_ctx, TLSEXT_NAMETYPE_host_name) != NULL;
Willy Tarreau7875d092012-09-10 08:20:03 +02003312 return 1;
3313#else
3314 return 0;
3315#endif
3316}
3317
Emeric Brun645ae792014-04-30 14:21:06 +02003318/* string, returns the used cipher if front conn. transport layer is SSL.
3319 * This function is also usable on backend conn if the fetch keyword 5th
3320 * char is 'b'.
3321 */
Emeric Brun589fcad2012-10-16 14:13:26 +02003322static int
3323smp_fetch_ssl_fc_cipher(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)
Emeric Brun589fcad2012-10-16 14:13:26 +02003325{
Emeric Brun645ae792014-04-30 14:21:06 +02003326 int back_conn = (kw[4] == 'b') ? 1 : 0;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003327 struct connection *conn;
3328
Emeric Brun589fcad2012-10-16 14:13:26 +02003329 smp->flags = 0;
3330
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003331 if (!l4)
3332 return 0;
3333
Emeric Brun645ae792014-04-30 14:21:06 +02003334 conn = objt_conn(l4->si[back_conn].end);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003335 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
Emeric Brun589fcad2012-10-16 14:13:26 +02003336 return 0;
3337
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003338 smp->data.str.str = (char *)SSL_get_cipher_name(conn->xprt_ctx);
Emeric Brun589fcad2012-10-16 14:13:26 +02003339 if (!smp->data.str.str)
3340 return 0;
3341
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01003342 smp->type = SMP_T_STR;
3343 smp->flags |= SMP_F_CONST;
Emeric Brun589fcad2012-10-16 14:13:26 +02003344 smp->data.str.len = strlen(smp->data.str.str);
3345
3346 return 1;
3347}
3348
Emeric Brun645ae792014-04-30 14:21:06 +02003349/* integer, returns the algoritm's keysize if front conn. transport layer
3350 * is SSL.
3351 * This function is also usable on backend conn if the fetch keyword 5th
3352 * char is 'b'.
3353 */
Emeric Brun589fcad2012-10-16 14:13:26 +02003354static int
3355smp_fetch_ssl_fc_alg_keysize(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003356 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brun589fcad2012-10-16 14:13:26 +02003357{
Emeric Brun645ae792014-04-30 14:21:06 +02003358 int back_conn = (kw[4] == 'b') ? 1 : 0;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003359 struct connection *conn;
3360
Emeric Brun589fcad2012-10-16 14:13:26 +02003361 smp->flags = 0;
3362
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003363 if (!l4)
Emeric Brun589fcad2012-10-16 14:13:26 +02003364 return 0;
3365
Emeric Brun645ae792014-04-30 14:21:06 +02003366 conn = objt_conn(l4->si[back_conn].end);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003367 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
Emeric Brun589fcad2012-10-16 14:13:26 +02003368 return 0;
3369
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003370 if (!SSL_get_cipher_bits(conn->xprt_ctx, (int *)&smp->data.uint))
3371 return 0;
3372
Emeric Brun589fcad2012-10-16 14:13:26 +02003373 smp->type = SMP_T_UINT;
3374
3375 return 1;
3376}
3377
Emeric Brun645ae792014-04-30 14:21:06 +02003378/* integer, returns the used keysize if front conn. transport layer is SSL.
3379 * This function is also usable on backend conn if the fetch keyword 5th
3380 * char is 'b'.
3381 */
Emeric Brun589fcad2012-10-16 14:13:26 +02003382static int
3383smp_fetch_ssl_fc_use_keysize(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003384 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brun589fcad2012-10-16 14:13:26 +02003385{
Emeric Brun645ae792014-04-30 14:21:06 +02003386 int back_conn = (kw[4] == 'b') ? 1 : 0;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003387 struct connection *conn;
3388
Emeric Brun589fcad2012-10-16 14:13:26 +02003389 smp->flags = 0;
3390
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003391 if (!l4)
Emeric Brun589fcad2012-10-16 14:13:26 +02003392 return 0;
3393
Emeric Brun645ae792014-04-30 14:21:06 +02003394 conn = objt_conn(l4->si[back_conn].end);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003395 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
3396 return 0;
3397
3398 smp->data.uint = (unsigned int)SSL_get_cipher_bits(conn->xprt_ctx, NULL);
Emeric Brun589fcad2012-10-16 14:13:26 +02003399 if (!smp->data.uint)
3400 return 0;
3401
3402 smp->type = SMP_T_UINT;
3403
3404 return 1;
3405}
3406
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02003407#ifdef OPENSSL_NPN_NEGOTIATED
Willy Tarreau7875d092012-09-10 08:20:03 +02003408static int
Emeric Brun2525b6b2012-10-18 15:59:43 +02003409smp_fetch_ssl_fc_npn(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003410 const struct arg *args, struct sample *smp, const char *kw)
Willy Tarreaua33c6542012-10-15 13:19:06 +02003411{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003412 struct connection *conn;
3413
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01003414 smp->flags = SMP_F_CONST;
3415 smp->type = SMP_T_STR;
Willy Tarreaua33c6542012-10-15 13:19:06 +02003416
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003417 if (!l4)
Willy Tarreaua33c6542012-10-15 13:19:06 +02003418 return 0;
3419
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003420 conn = objt_conn(l4->si[0].end);
3421 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
3422 return 0;
3423
Willy Tarreaua33c6542012-10-15 13:19:06 +02003424 smp->data.str.str = NULL;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003425 SSL_get0_next_proto_negotiated(conn->xprt_ctx,
Willy Tarreaua33c6542012-10-15 13:19:06 +02003426 (const unsigned char **)&smp->data.str.str, (unsigned *)&smp->data.str.len);
3427
3428 if (!smp->data.str.str)
3429 return 0;
3430
3431 return 1;
Willy Tarreaua33c6542012-10-15 13:19:06 +02003432}
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02003433#endif
Willy Tarreaua33c6542012-10-15 13:19:06 +02003434
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01003435#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Willy Tarreauab861d32013-04-02 02:30:41 +02003436static int
3437smp_fetch_ssl_fc_alpn(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003438 const struct arg *args, struct sample *smp, const char *kw)
Willy Tarreauab861d32013-04-02 02:30:41 +02003439{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003440 struct connection *conn;
3441
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01003442 smp->flags = SMP_F_CONST;
3443 smp->type = SMP_T_STR;
Willy Tarreauab861d32013-04-02 02:30:41 +02003444
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003445 if (!l4)
3446 return 0;
3447
3448 conn = objt_conn(l4->si[0].end);
3449 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
Willy Tarreauab861d32013-04-02 02:30:41 +02003450 return 0;
3451
3452 smp->data.str.str = NULL;
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01003453 SSL_get0_alpn_selected(conn->xprt_ctx,
Willy Tarreauab861d32013-04-02 02:30:41 +02003454 (const unsigned char **)&smp->data.str.str, (unsigned *)&smp->data.str.len);
3455
3456 if (!smp->data.str.str)
3457 return 0;
3458
3459 return 1;
3460}
3461#endif
3462
Emeric Brun645ae792014-04-30 14:21:06 +02003463/* string, returns the used protocol if front conn. transport layer is SSL.
3464 * This function is also usable on backend conn if the fetch keyword 5th
3465 * char is 'b'.
3466 */
Willy Tarreaua33c6542012-10-15 13:19:06 +02003467static int
Emeric Brun589fcad2012-10-16 14:13:26 +02003468smp_fetch_ssl_fc_protocol(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003469 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brun589fcad2012-10-16 14:13:26 +02003470{
Emeric Brun645ae792014-04-30 14:21:06 +02003471 int back_conn = (kw[4] == 'b') ? 1 : 0;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003472 struct connection *conn;
3473
Emeric Brun589fcad2012-10-16 14:13:26 +02003474 smp->flags = 0;
3475
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003476 if (!l4)
Emeric Brun589fcad2012-10-16 14:13:26 +02003477 return 0;
3478
Emeric Brun645ae792014-04-30 14:21:06 +02003479 conn = objt_conn(l4->si[back_conn].end);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003480 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
3481 return 0;
3482
3483 smp->data.str.str = (char *)SSL_get_version(conn->xprt_ctx);
Emeric Brun589fcad2012-10-16 14:13:26 +02003484 if (!smp->data.str.str)
3485 return 0;
3486
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01003487 smp->type = SMP_T_STR;
3488 smp->flags = SMP_F_CONST;
Emeric Brun589fcad2012-10-16 14:13:26 +02003489 smp->data.str.len = strlen(smp->data.str.str);
3490
3491 return 1;
3492}
3493
Emeric Brun645ae792014-04-30 14:21:06 +02003494/* binary, returns the SSL session id if front conn. transport layer is SSL.
3495 * This function is also usable on backend conn if the fetch keyword 5th
3496 * char is 'b'.
3497 */
Emeric Brun589fcad2012-10-16 14:13:26 +02003498static int
Emeric Brunfe68f682012-10-16 14:59:28 +02003499smp_fetch_ssl_fc_session_id(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003500 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brunfe68f682012-10-16 14:59:28 +02003501{
3502#if OPENSSL_VERSION_NUMBER > 0x0090800fL
Emeric Brun645ae792014-04-30 14:21:06 +02003503 int back_conn = (kw[4] == 'b') ? 1 : 0;
Emeric Brunfe68f682012-10-16 14:59:28 +02003504 SSL_SESSION *sess;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003505 struct connection *conn;
Emeric Brunfe68f682012-10-16 14:59:28 +02003506
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01003507 smp->flags = SMP_F_CONST;
3508 smp->type = SMP_T_BIN;
Emeric Brunfe68f682012-10-16 14:59:28 +02003509
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003510 if (!l4)
Emeric Brunfe68f682012-10-16 14:59:28 +02003511 return 0;
3512
Emeric Brun645ae792014-04-30 14:21:06 +02003513 conn = objt_conn(l4->si[back_conn].end);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003514 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
3515 return 0;
3516
3517 sess = SSL_get_session(conn->xprt_ctx);
Emeric Brunfe68f682012-10-16 14:59:28 +02003518 if (!sess)
3519 return 0;
3520
3521 smp->data.str.str = (char *)SSL_SESSION_get_id(sess, (unsigned int *)&smp->data.str.len);
3522 if (!smp->data.str.str || !&smp->data.str.len)
3523 return 0;
3524
3525 return 1;
3526#else
3527 return 0;
3528#endif
3529}
3530
3531static int
Emeric Brun2525b6b2012-10-18 15:59:43 +02003532smp_fetch_ssl_fc_sni(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003533 const struct arg *args, struct sample *smp, const char *kw)
Willy Tarreau7875d092012-09-10 08:20:03 +02003534{
3535#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003536 struct connection *conn;
3537
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01003538 smp->flags = SMP_F_CONST;
3539 smp->type = SMP_T_STR;
Willy Tarreau7875d092012-09-10 08:20:03 +02003540
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003541 if (!l4)
Willy Tarreau7875d092012-09-10 08:20:03 +02003542 return 0;
3543
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003544 conn = objt_conn(l4->si[0].end);
3545 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
3546 return 0;
3547
3548 smp->data.str.str = (char *)SSL_get_servername(conn->xprt_ctx, TLSEXT_NAMETYPE_host_name);
Willy Tarreau3e394c92012-09-14 23:56:58 +02003549 if (!smp->data.str.str)
3550 return 0;
3551
Willy Tarreau7875d092012-09-10 08:20:03 +02003552 smp->data.str.len = strlen(smp->data.str.str);
3553 return 1;
3554#else
3555 return 0;
3556#endif
3557}
3558
David Sc1ad52e2014-04-08 18:48:47 -04003559static int
3560smp_fetch_ssl_fc_unique_id(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
3561 const struct arg *args, struct sample *smp, const char *kw)
3562{
3563#if OPENSSL_VERSION_NUMBER > 0x0090800fL
Emeric Brun645ae792014-04-30 14:21:06 +02003564 int back_conn = (kw[4] == 'b') ? 1 : 0;
David Sc1ad52e2014-04-08 18:48:47 -04003565 struct connection *conn;
3566 int finished_len;
David Sc1ad52e2014-04-08 18:48:47 -04003567 struct chunk *finished_trash;
David Sc1ad52e2014-04-08 18:48:47 -04003568
3569 smp->flags = 0;
3570
3571 if (!l4)
3572 return 0;
3573
Emeric Brun645ae792014-04-30 14:21:06 +02003574 conn = objt_conn(l4->si[back_conn].end);
David Sc1ad52e2014-04-08 18:48:47 -04003575 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
3576 return 0;
3577
3578 if (!(conn->flags & CO_FL_CONNECTED)) {
3579 smp->flags |= SMP_F_MAY_CHANGE;
3580 return 0;
3581 }
3582
3583 finished_trash = get_trash_chunk();
3584 if (!SSL_session_reused(conn->xprt_ctx))
3585 finished_len = SSL_get_peer_finished(conn->xprt_ctx, finished_trash->str, finished_trash->size);
3586 else
3587 finished_len = SSL_get_finished(conn->xprt_ctx, finished_trash->str, finished_trash->size);
3588
3589 if (!finished_len)
3590 return 0;
3591
Emeric Brunb73a9b02014-04-30 18:49:19 +02003592 finished_trash->len = finished_len;
3593 smp->data.str = *finished_trash;
3594 smp->type = SMP_T_BIN;
David Sc1ad52e2014-04-08 18:48:47 -04003595
3596 return 1;
3597#else
3598 return 0;
3599#endif
3600}
3601
Emeric Brun2525b6b2012-10-18 15:59:43 +02003602/* integer, returns the first verify error in CA chain of client certificate chain. */
Emeric Brunf282a812012-09-21 15:27:54 +02003603static int
Emeric Brun2525b6b2012-10-18 15:59:43 +02003604smp_fetch_ssl_c_ca_err(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003605 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brunf282a812012-09-21 15:27:54 +02003606{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003607 struct connection *conn;
3608
3609 if (!l4)
Emeric Brunf282a812012-09-21 15:27:54 +02003610 return 0;
3611
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003612 conn = objt_conn(l4->si[0].end);
3613 if (!conn || conn->xprt != &ssl_sock)
3614 return 0;
3615
3616 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunf282a812012-09-21 15:27:54 +02003617 smp->flags = SMP_F_MAY_CHANGE;
3618 return 0;
3619 }
3620
3621 smp->type = SMP_T_UINT;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003622 smp->data.uint = (unsigned int)SSL_SOCK_ST_TO_CA_ERROR(conn->xprt_st);
Emeric Brunf282a812012-09-21 15:27:54 +02003623 smp->flags = 0;
3624
3625 return 1;
3626}
3627
Emeric Brun2525b6b2012-10-18 15:59:43 +02003628/* integer, returns the depth of the first verify error in CA chain of client certificate chain. */
Emeric Brunf282a812012-09-21 15:27:54 +02003629static int
Emeric Brun2525b6b2012-10-18 15:59:43 +02003630smp_fetch_ssl_c_ca_err_depth(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003631 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brunf282a812012-09-21 15:27:54 +02003632{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003633 struct connection *conn;
3634
3635 if (!l4)
3636 return 0;
3637
3638 conn = objt_conn(l4->si[0].end);
3639 if (!conn || conn->xprt != &ssl_sock)
Emeric Brunf282a812012-09-21 15:27:54 +02003640 return 0;
3641
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003642 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunf282a812012-09-21 15:27:54 +02003643 smp->flags = SMP_F_MAY_CHANGE;
3644 return 0;
3645 }
3646
3647 smp->type = SMP_T_UINT;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003648 smp->data.uint = (unsigned int)SSL_SOCK_ST_TO_CAEDEPTH(conn->xprt_st);
Emeric Brunf282a812012-09-21 15:27:54 +02003649 smp->flags = 0;
3650
3651 return 1;
3652}
3653
Emeric Brun2525b6b2012-10-18 15:59:43 +02003654/* integer, returns the first verify error on client certificate */
Emeric Brunf282a812012-09-21 15:27:54 +02003655static int
Emeric Brun2525b6b2012-10-18 15:59:43 +02003656smp_fetch_ssl_c_err(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003657 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brunf282a812012-09-21 15:27:54 +02003658{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003659 struct connection *conn;
3660
3661 if (!l4)
Emeric Brunf282a812012-09-21 15:27:54 +02003662 return 0;
3663
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003664 conn = objt_conn(l4->si[0].end);
3665 if (!conn || conn->xprt != &ssl_sock)
3666 return 0;
3667
3668 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunf282a812012-09-21 15:27:54 +02003669 smp->flags = SMP_F_MAY_CHANGE;
3670 return 0;
3671 }
3672
3673 smp->type = SMP_T_UINT;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003674 smp->data.uint = (unsigned int)SSL_SOCK_ST_TO_CRTERROR(conn->xprt_st);
Emeric Brunf282a812012-09-21 15:27:54 +02003675 smp->flags = 0;
3676
3677 return 1;
3678}
3679
Emeric Brun2525b6b2012-10-18 15:59:43 +02003680/* integer, returns the verify result on client cert */
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02003681static int
Emeric Brun2525b6b2012-10-18 15:59:43 +02003682smp_fetch_ssl_c_verify(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003683 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02003684{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003685 struct connection *conn;
3686
3687 if (!l4)
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02003688 return 0;
3689
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003690 conn = objt_conn(l4->si[0].end);
3691 if (!conn || conn->xprt != &ssl_sock)
3692 return 0;
3693
3694 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02003695 smp->flags = SMP_F_MAY_CHANGE;
3696 return 0;
3697 }
3698
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003699 if (!conn->xprt_ctx)
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02003700 return 0;
3701
3702 smp->type = SMP_T_UINT;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003703 smp->data.uint = (unsigned int)SSL_get_verify_result(conn->xprt_ctx);
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02003704 smp->flags = 0;
3705
3706 return 1;
3707}
3708
Emeric Brunfb510ea2012-10-05 12:00:26 +02003709/* parse the "ca-file" bind keyword */
3710static 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 +02003711{
3712 if (!*args[cur_arg + 1]) {
3713 if (err)
3714 memprintf(err, "'%s' : missing CAfile path", args[cur_arg]);
3715 return ERR_ALERT | ERR_FATAL;
3716 }
3717
Emeric Brunef42d922012-10-11 16:11:36 +02003718 if ((*args[cur_arg + 1] != '/') && global.ca_base)
3719 memprintf(&conf->ca_file, "%s/%s", global.ca_base, args[cur_arg + 1]);
3720 else
3721 memprintf(&conf->ca_file, "%s", args[cur_arg + 1]);
Emeric Brunc8e8d122012-10-02 18:42:10 +02003722
Emeric Brund94b3fe2012-09-20 18:23:56 +02003723 return 0;
3724}
3725
Willy Tarreau79eeafa2012-09-14 07:53:05 +02003726/* parse the "ciphers" bind keyword */
Willy Tarreau4348fad2012-09-20 16:48:07 +02003727static 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 +02003728{
3729 if (!*args[cur_arg + 1]) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02003730 memprintf(err, "'%s' : missing cipher suite", args[cur_arg]);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02003731 return ERR_ALERT | ERR_FATAL;
3732 }
3733
Emeric Brun76d88952012-10-05 15:47:31 +02003734 free(conf->ciphers);
Willy Tarreau4348fad2012-09-20 16:48:07 +02003735 conf->ciphers = strdup(args[cur_arg + 1]);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02003736 return 0;
3737}
3738
3739/* parse the "crt" bind keyword */
Willy Tarreau4348fad2012-09-20 16:48:07 +02003740static 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 +02003741{
Willy Tarreau38011032013-08-13 16:59:39 +02003742 char path[MAXPATHLEN];
Willy Tarreaub75d6922014-04-14 18:05:41 +02003743
Willy Tarreau79eeafa2012-09-14 07:53:05 +02003744 if (!*args[cur_arg + 1]) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02003745 memprintf(err, "'%s' : missing certificate location", args[cur_arg]);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02003746 return ERR_ALERT | ERR_FATAL;
3747 }
3748
Emeric Brunc8e8d122012-10-02 18:42:10 +02003749 if ((*args[cur_arg + 1] != '/' ) && global.crt_base) {
Willy Tarreau38011032013-08-13 16:59:39 +02003750 if ((strlen(global.crt_base) + 1 + strlen(args[cur_arg + 1]) + 1) > MAXPATHLEN) {
Emeric Brunc8e8d122012-10-02 18:42:10 +02003751 memprintf(err, "'%s' : path too long", args[cur_arg]);
3752 return ERR_ALERT | ERR_FATAL;
3753 }
Willy Tarreaub75d6922014-04-14 18:05:41 +02003754 snprintf(path, sizeof(path), "%s/%s", global.crt_base, args[cur_arg + 1]);
Emeric Brunc8e8d122012-10-02 18:42:10 +02003755 if (ssl_sock_load_cert(path, conf, px, err) > 0)
3756 return ERR_ALERT | ERR_FATAL;
3757
3758 return 0;
3759 }
3760
Willy Tarreau4348fad2012-09-20 16:48:07 +02003761 if (ssl_sock_load_cert(args[cur_arg + 1], conf, px, err) > 0)
Willy Tarreau79eeafa2012-09-14 07:53:05 +02003762 return ERR_ALERT | ERR_FATAL;
Emeric Brund94b3fe2012-09-20 18:23:56 +02003763
3764 return 0;
3765}
3766
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01003767/* parse the "crt-list" bind keyword */
3768static int bind_parse_crt_list(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
3769{
3770 if (!*args[cur_arg + 1]) {
3771 memprintf(err, "'%s' : missing certificate location", args[cur_arg]);
3772 return ERR_ALERT | ERR_FATAL;
3773 }
3774
Willy Tarreauad1731d2013-04-02 17:35:58 +02003775 if (ssl_sock_load_cert_list_file(args[cur_arg + 1], conf, px, err) > 0) {
3776 memprintf(err, "'%s' : %s", args[cur_arg], *err);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01003777 return ERR_ALERT | ERR_FATAL;
Willy Tarreauad1731d2013-04-02 17:35:58 +02003778 }
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01003779
3780 return 0;
3781}
3782
Emeric Brunfb510ea2012-10-05 12:00:26 +02003783/* parse the "crl-file" bind keyword */
3784static 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 +02003785{
Emeric Brun051cdab2012-10-02 19:25:50 +02003786#ifndef X509_V_FLAG_CRL_CHECK
3787 if (err)
3788 memprintf(err, "'%s' : library does not support CRL verify", args[cur_arg]);
3789 return ERR_ALERT | ERR_FATAL;
3790#else
Emeric Brund94b3fe2012-09-20 18:23:56 +02003791 if (!*args[cur_arg + 1]) {
3792 if (err)
3793 memprintf(err, "'%s' : missing CRLfile path", args[cur_arg]);
3794 return ERR_ALERT | ERR_FATAL;
3795 }
Emeric Brun2b58d042012-09-20 17:10:03 +02003796
Emeric Brunef42d922012-10-11 16:11:36 +02003797 if ((*args[cur_arg + 1] != '/') && global.ca_base)
3798 memprintf(&conf->crl_file, "%s/%s", global.ca_base, args[cur_arg + 1]);
3799 else
3800 memprintf(&conf->crl_file, "%s", args[cur_arg + 1]);
Emeric Brunc8e8d122012-10-02 18:42:10 +02003801
Emeric Brun2b58d042012-09-20 17:10:03 +02003802 return 0;
Emeric Brun051cdab2012-10-02 19:25:50 +02003803#endif
Emeric Brun2b58d042012-09-20 17:10:03 +02003804}
3805
3806/* parse the "ecdhe" bind keyword keywords */
3807static int bind_parse_ecdhe(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
3808{
3809#if OPENSSL_VERSION_NUMBER < 0x0090800fL
3810 if (err)
3811 memprintf(err, "'%s' : library does not support elliptic curve Diffie-Hellman (too old)", args[cur_arg]);
3812 return ERR_ALERT | ERR_FATAL;
3813#elif defined(OPENSSL_NO_ECDH)
3814 if (err)
3815 memprintf(err, "'%s' : library does not support elliptic curve Diffie-Hellman (disabled via OPENSSL_NO_ECDH)", args[cur_arg]);
3816 return ERR_ALERT | ERR_FATAL;
3817#else
3818 if (!*args[cur_arg + 1]) {
3819 if (err)
3820 memprintf(err, "'%s' : missing named curve", args[cur_arg]);
3821 return ERR_ALERT | ERR_FATAL;
3822 }
3823
3824 conf->ecdhe = strdup(args[cur_arg + 1]);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02003825
3826 return 0;
Emeric Brun2b58d042012-09-20 17:10:03 +02003827#endif
Willy Tarreau79eeafa2012-09-14 07:53:05 +02003828}
3829
Emeric Brun81c00f02012-09-21 14:31:21 +02003830/* parse the "crt_ignerr" and "ca_ignerr" bind keywords */
3831static int bind_parse_ignore_err(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
3832{
3833 int code;
3834 char *p = args[cur_arg + 1];
3835 unsigned long long *ignerr = &conf->crt_ignerr;
3836
3837 if (!*p) {
3838 if (err)
3839 memprintf(err, "'%s' : missing error IDs list", args[cur_arg]);
3840 return ERR_ALERT | ERR_FATAL;
3841 }
3842
3843 if (strcmp(args[cur_arg], "ca-ignore-err") == 0)
3844 ignerr = &conf->ca_ignerr;
3845
3846 if (strcmp(p, "all") == 0) {
3847 *ignerr = ~0ULL;
3848 return 0;
3849 }
3850
3851 while (p) {
3852 code = atoi(p);
3853 if ((code <= 0) || (code > 63)) {
3854 if (err)
3855 memprintf(err, "'%s' : ID '%d' out of range (1..63) in error IDs list '%s'",
3856 args[cur_arg], code, args[cur_arg + 1]);
3857 return ERR_ALERT | ERR_FATAL;
3858 }
3859 *ignerr |= 1ULL << code;
3860 p = strchr(p, ',');
3861 if (p)
3862 p++;
3863 }
3864
Emeric Brun2cb7ae52012-10-05 14:14:21 +02003865 return 0;
3866}
3867
3868/* parse the "force-sslv3" bind keyword */
3869static int bind_parse_force_sslv3(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
3870{
3871 conf->ssl_options |= BC_SSL_O_USE_SSLV3;
3872 return 0;
3873}
3874
3875/* parse the "force-tlsv10" bind keyword */
3876static int bind_parse_force_tlsv10(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
3877{
3878 conf->ssl_options |= BC_SSL_O_USE_TLSV10;
Emeric Brun2d0c4822012-10-02 13:45:20 +02003879 return 0;
3880}
3881
Emeric Brun2cb7ae52012-10-05 14:14:21 +02003882/* parse the "force-tlsv11" bind keyword */
3883static int bind_parse_force_tlsv11(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
3884{
3885#if SSL_OP_NO_TLSv1_1
3886 conf->ssl_options |= BC_SSL_O_USE_TLSV11;
3887 return 0;
3888#else
3889 if (err)
3890 memprintf(err, "'%s' : library does not support protocol TLSv1.1", args[cur_arg]);
3891 return ERR_ALERT | ERR_FATAL;
3892#endif
3893}
3894
3895/* parse the "force-tlsv12" bind keyword */
3896static int bind_parse_force_tlsv12(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
3897{
3898#if SSL_OP_NO_TLSv1_2
3899 conf->ssl_options |= BC_SSL_O_USE_TLSV12;
3900 return 0;
3901#else
3902 if (err)
3903 memprintf(err, "'%s' : library does not support protocol TLSv1.2", args[cur_arg]);
3904 return ERR_ALERT | ERR_FATAL;
3905#endif
3906}
3907
3908
Emeric Brun2d0c4822012-10-02 13:45:20 +02003909/* parse the "no-tls-tickets" bind keyword */
3910static int bind_parse_no_tls_tickets(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
3911{
Emeric Brun89675492012-10-05 13:48:26 +02003912 conf->ssl_options |= BC_SSL_O_NO_TLS_TICKETS;
Emeric Brun81c00f02012-09-21 14:31:21 +02003913 return 0;
3914}
3915
Emeric Brun2d0c4822012-10-02 13:45:20 +02003916
Emeric Brun9b3009b2012-10-05 11:55:06 +02003917/* parse the "no-sslv3" bind keyword */
3918static 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 +02003919{
Emeric Brun89675492012-10-05 13:48:26 +02003920 conf->ssl_options |= BC_SSL_O_NO_SSLV3;
Willy Tarreau79eeafa2012-09-14 07:53:05 +02003921 return 0;
3922}
3923
Emeric Brun9b3009b2012-10-05 11:55:06 +02003924/* parse the "no-tlsv10" bind keyword */
3925static 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 +02003926{
Emeric Brun89675492012-10-05 13:48:26 +02003927 conf->ssl_options |= BC_SSL_O_NO_TLSV10;
Emeric Brunc0ff4922012-09-28 19:37:02 +02003928 return 0;
3929}
3930
Emeric Brun9b3009b2012-10-05 11:55:06 +02003931/* parse the "no-tlsv11" bind keyword */
3932static 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 +02003933{
Emeric Brun89675492012-10-05 13:48:26 +02003934 conf->ssl_options |= BC_SSL_O_NO_TLSV11;
Emeric Brunc0ff4922012-09-28 19:37:02 +02003935 return 0;
3936}
3937
Emeric Brun9b3009b2012-10-05 11:55:06 +02003938/* parse the "no-tlsv12" bind keyword */
3939static 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 +02003940{
Emeric Brun89675492012-10-05 13:48:26 +02003941 conf->ssl_options |= BC_SSL_O_NO_TLSV12;
Willy Tarreau79eeafa2012-09-14 07:53:05 +02003942 return 0;
3943}
3944
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02003945/* parse the "npn" bind keyword */
3946static int bind_parse_npn(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
3947{
3948#ifdef OPENSSL_NPN_NEGOTIATED
3949 char *p1, *p2;
3950
3951 if (!*args[cur_arg + 1]) {
3952 memprintf(err, "'%s' : missing the comma-delimited NPN protocol suite", args[cur_arg]);
3953 return ERR_ALERT | ERR_FATAL;
3954 }
3955
3956 free(conf->npn_str);
3957
3958 /* the NPN string is built as a suite of (<len> <name>)* */
3959 conf->npn_len = strlen(args[cur_arg + 1]) + 1;
3960 conf->npn_str = calloc(1, conf->npn_len);
3961 memcpy(conf->npn_str + 1, args[cur_arg + 1], conf->npn_len);
3962
3963 /* replace commas with the name length */
3964 p1 = conf->npn_str;
3965 p2 = p1 + 1;
3966 while (1) {
3967 p2 = memchr(p1 + 1, ',', conf->npn_str + conf->npn_len - (p1 + 1));
3968 if (!p2)
3969 p2 = p1 + 1 + strlen(p1 + 1);
3970
3971 if (p2 - (p1 + 1) > 255) {
3972 *p2 = '\0';
3973 memprintf(err, "'%s' : NPN protocol name too long : '%s'", args[cur_arg], p1 + 1);
3974 return ERR_ALERT | ERR_FATAL;
3975 }
3976
3977 *p1 = p2 - (p1 + 1);
3978 p1 = p2;
3979
3980 if (!*p2)
3981 break;
3982
3983 *(p2++) = '\0';
3984 }
3985 return 0;
3986#else
3987 if (err)
3988 memprintf(err, "'%s' : library does not support TLS NPN extension", args[cur_arg]);
3989 return ERR_ALERT | ERR_FATAL;
3990#endif
3991}
3992
Willy Tarreauab861d32013-04-02 02:30:41 +02003993/* parse the "alpn" bind keyword */
3994static int bind_parse_alpn(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
3995{
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01003996#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Willy Tarreauab861d32013-04-02 02:30:41 +02003997 char *p1, *p2;
3998
3999 if (!*args[cur_arg + 1]) {
4000 memprintf(err, "'%s' : missing the comma-delimited ALPN protocol suite", args[cur_arg]);
4001 return ERR_ALERT | ERR_FATAL;
4002 }
4003
4004 free(conf->alpn_str);
4005
4006 /* the ALPN string is built as a suite of (<len> <name>)* */
4007 conf->alpn_len = strlen(args[cur_arg + 1]) + 1;
4008 conf->alpn_str = calloc(1, conf->alpn_len);
4009 memcpy(conf->alpn_str + 1, args[cur_arg + 1], conf->alpn_len);
4010
4011 /* replace commas with the name length */
4012 p1 = conf->alpn_str;
4013 p2 = p1 + 1;
4014 while (1) {
4015 p2 = memchr(p1 + 1, ',', conf->alpn_str + conf->alpn_len - (p1 + 1));
4016 if (!p2)
4017 p2 = p1 + 1 + strlen(p1 + 1);
4018
4019 if (p2 - (p1 + 1) > 255) {
4020 *p2 = '\0';
4021 memprintf(err, "'%s' : ALPN protocol name too long : '%s'", args[cur_arg], p1 + 1);
4022 return ERR_ALERT | ERR_FATAL;
4023 }
4024
4025 *p1 = p2 - (p1 + 1);
4026 p1 = p2;
4027
4028 if (!*p2)
4029 break;
4030
4031 *(p2++) = '\0';
4032 }
4033 return 0;
4034#else
4035 if (err)
4036 memprintf(err, "'%s' : library does not support TLS ALPN extension", args[cur_arg]);
4037 return ERR_ALERT | ERR_FATAL;
4038#endif
4039}
4040
Willy Tarreau79eeafa2012-09-14 07:53:05 +02004041/* parse the "ssl" bind keyword */
Willy Tarreau4348fad2012-09-20 16:48:07 +02004042static 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 +02004043{
Willy Tarreau81796be2012-09-22 19:11:47 +02004044 struct listener *l;
4045
Willy Tarreau4348fad2012-09-20 16:48:07 +02004046 conf->is_ssl = 1;
Emeric Brun76d88952012-10-05 15:47:31 +02004047
4048 if (global.listen_default_ciphers && !conf->ciphers)
4049 conf->ciphers = strdup(global.listen_default_ciphers);
4050
Willy Tarreau81796be2012-09-22 19:11:47 +02004051 list_for_each_entry(l, &conf->listeners, by_bind)
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02004052 l->xprt = &ssl_sock;
Willy Tarreau81796be2012-09-22 19:11:47 +02004053
Willy Tarreau79eeafa2012-09-14 07:53:05 +02004054 return 0;
4055}
4056
Emmanuel Hocdet65623372013-01-24 17:17:15 +01004057/* parse the "strict-sni" bind keyword */
4058static int bind_parse_strict_sni(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
4059{
4060 conf->strict_sni = 1;
4061 return 0;
4062}
4063
Emeric Brund94b3fe2012-09-20 18:23:56 +02004064/* parse the "verify" bind keyword */
4065static int bind_parse_verify(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
4066{
4067 if (!*args[cur_arg + 1]) {
4068 if (err)
4069 memprintf(err, "'%s' : missing verify method", args[cur_arg]);
4070 return ERR_ALERT | ERR_FATAL;
4071 }
4072
4073 if (strcmp(args[cur_arg + 1], "none") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01004074 conf->verify = SSL_SOCK_VERIFY_NONE;
Emeric Brund94b3fe2012-09-20 18:23:56 +02004075 else if (strcmp(args[cur_arg + 1], "optional") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01004076 conf->verify = SSL_SOCK_VERIFY_OPTIONAL;
Emeric Brund94b3fe2012-09-20 18:23:56 +02004077 else if (strcmp(args[cur_arg + 1], "required") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01004078 conf->verify = SSL_SOCK_VERIFY_REQUIRED;
Emeric Brund94b3fe2012-09-20 18:23:56 +02004079 else {
4080 if (err)
4081 memprintf(err, "'%s' : unknown verify method '%s', only 'none', 'optional', and 'required' are supported\n",
4082 args[cur_arg], args[cur_arg + 1]);
4083 return ERR_ALERT | ERR_FATAL;
4084 }
4085
4086 return 0;
4087}
4088
Willy Tarreau92faadf2012-10-10 23:04:25 +02004089/************** "server" keywords ****************/
4090
Emeric Brunef42d922012-10-11 16:11:36 +02004091/* parse the "ca-file" server keyword */
4092static int srv_parse_ca_file(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4093{
4094 if (!*args[*cur_arg + 1]) {
4095 if (err)
4096 memprintf(err, "'%s' : missing CAfile path", args[*cur_arg]);
4097 return ERR_ALERT | ERR_FATAL;
4098 }
4099
4100 if ((*args[*cur_arg + 1] != '/') && global.ca_base)
4101 memprintf(&newsrv->ssl_ctx.ca_file, "%s/%s", global.ca_base, args[*cur_arg + 1]);
4102 else
4103 memprintf(&newsrv->ssl_ctx.ca_file, "%s", args[*cur_arg + 1]);
4104
4105 return 0;
4106}
4107
Willy Tarreau92faadf2012-10-10 23:04:25 +02004108/* parse the "check-ssl" server keyword */
4109static int srv_parse_check_ssl(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4110{
4111 newsrv->check.use_ssl = 1;
4112 if (global.connect_default_ciphers && !newsrv->ssl_ctx.ciphers)
4113 newsrv->ssl_ctx.ciphers = strdup(global.connect_default_ciphers);
4114 return 0;
4115}
4116
4117/* parse the "ciphers" server keyword */
4118static int srv_parse_ciphers(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4119{
4120 if (!*args[*cur_arg + 1]) {
4121 memprintf(err, "'%s' : missing cipher suite", args[*cur_arg]);
4122 return ERR_ALERT | ERR_FATAL;
4123 }
4124
4125 free(newsrv->ssl_ctx.ciphers);
4126 newsrv->ssl_ctx.ciphers = strdup(args[*cur_arg + 1]);
4127 return 0;
4128}
4129
Emeric Brunef42d922012-10-11 16:11:36 +02004130/* parse the "crl-file" server keyword */
4131static int srv_parse_crl_file(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4132{
4133#ifndef X509_V_FLAG_CRL_CHECK
4134 if (err)
4135 memprintf(err, "'%s' : library does not support CRL verify", args[*cur_arg]);
4136 return ERR_ALERT | ERR_FATAL;
4137#else
4138 if (!*args[*cur_arg + 1]) {
4139 if (err)
4140 memprintf(err, "'%s' : missing CRLfile path", args[*cur_arg]);
4141 return ERR_ALERT | ERR_FATAL;
4142 }
4143
4144 if ((*args[*cur_arg + 1] != '/') && global.ca_base)
4145 memprintf(&newsrv->ssl_ctx.crl_file, "%s/%s", global.ca_base, args[*cur_arg + 1]);
4146 else
4147 memprintf(&newsrv->ssl_ctx.crl_file, "%s", args[*cur_arg + 1]);
4148
4149 return 0;
4150#endif
4151}
4152
Emeric Bruna7aa3092012-10-26 12:58:00 +02004153/* parse the "crt" server keyword */
4154static int srv_parse_crt(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4155{
4156 if (!*args[*cur_arg + 1]) {
4157 if (err)
4158 memprintf(err, "'%s' : missing certificate file path", args[*cur_arg]);
4159 return ERR_ALERT | ERR_FATAL;
4160 }
4161
4162 if ((*args[*cur_arg + 1] != '/') && global.crt_base)
4163 memprintf(&newsrv->ssl_ctx.client_crt, "%s/%s", global.ca_base, args[*cur_arg + 1]);
4164 else
4165 memprintf(&newsrv->ssl_ctx.client_crt, "%s", args[*cur_arg + 1]);
4166
4167 return 0;
4168}
Emeric Brunef42d922012-10-11 16:11:36 +02004169
Willy Tarreau92faadf2012-10-10 23:04:25 +02004170/* parse the "force-sslv3" server keyword */
4171static int srv_parse_force_sslv3(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4172{
4173 newsrv->ssl_ctx.options |= SRV_SSL_O_USE_SSLV3;
4174 return 0;
4175}
4176
4177/* parse the "force-tlsv10" server keyword */
4178static int srv_parse_force_tlsv10(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4179{
4180 newsrv->ssl_ctx.options |= SRV_SSL_O_USE_TLSV10;
4181 return 0;
4182}
4183
4184/* parse the "force-tlsv11" server keyword */
4185static int srv_parse_force_tlsv11(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4186{
4187#if SSL_OP_NO_TLSv1_1
4188 newsrv->ssl_ctx.options |= SRV_SSL_O_USE_TLSV11;
4189 return 0;
4190#else
4191 if (err)
4192 memprintf(err, "'%s' : library does not support protocol TLSv1.1", args[*cur_arg]);
4193 return ERR_ALERT | ERR_FATAL;
4194#endif
4195}
4196
4197/* parse the "force-tlsv12" server keyword */
4198static int srv_parse_force_tlsv12(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4199{
4200#if SSL_OP_NO_TLSv1_2
4201 newsrv->ssl_ctx.options |= SRV_SSL_O_USE_TLSV12;
4202 return 0;
4203#else
4204 if (err)
4205 memprintf(err, "'%s' : library does not support protocol TLSv1.2", args[*cur_arg]);
4206 return ERR_ALERT | ERR_FATAL;
4207#endif
4208}
4209
4210/* parse the "no-sslv3" server keyword */
4211static int srv_parse_no_sslv3(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4212{
4213 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_SSLV3;
4214 return 0;
4215}
4216
4217/* parse the "no-tlsv10" server keyword */
4218static int srv_parse_no_tlsv10(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4219{
4220 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_TLSV10;
4221 return 0;
4222}
4223
4224/* parse the "no-tlsv11" server keyword */
4225static int srv_parse_no_tlsv11(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4226{
4227 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_TLSV11;
4228 return 0;
4229}
4230
4231/* parse the "no-tlsv12" server keyword */
4232static int srv_parse_no_tlsv12(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4233{
4234 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_TLSV12;
4235 return 0;
4236}
4237
Emeric Brunf9c5c472012-10-11 15:28:34 +02004238/* parse the "no-tls-tickets" server keyword */
4239static int srv_parse_no_tls_tickets(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4240{
4241 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_TLS_TICKETS;
4242 return 0;
4243}
David Safb76832014-05-08 23:42:08 -04004244/* parse the "send-proxy-v2-ssl" server keyword */
4245static int srv_parse_send_proxy_ssl(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4246{
4247 newsrv->pp_opts |= SRV_PP_V2;
4248 newsrv->pp_opts |= SRV_PP_V2_SSL;
4249 return 0;
4250}
4251
4252/* parse the "send-proxy-v2-ssl-cn" server keyword */
4253static int srv_parse_send_proxy_cn(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4254{
4255 newsrv->pp_opts |= SRV_PP_V2;
4256 newsrv->pp_opts |= SRV_PP_V2_SSL;
4257 newsrv->pp_opts |= SRV_PP_V2_SSL_CN;
4258 return 0;
4259}
Emeric Brunf9c5c472012-10-11 15:28:34 +02004260
Willy Tarreau92faadf2012-10-10 23:04:25 +02004261/* parse the "ssl" server keyword */
4262static int srv_parse_ssl(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4263{
4264 newsrv->use_ssl = 1;
4265 if (global.connect_default_ciphers && !newsrv->ssl_ctx.ciphers)
4266 newsrv->ssl_ctx.ciphers = strdup(global.connect_default_ciphers);
4267 return 0;
4268}
4269
Emeric Brunef42d922012-10-11 16:11:36 +02004270/* parse the "verify" server keyword */
4271static int srv_parse_verify(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4272{
4273 if (!*args[*cur_arg + 1]) {
4274 if (err)
4275 memprintf(err, "'%s' : missing verify method", args[*cur_arg]);
4276 return ERR_ALERT | ERR_FATAL;
4277 }
4278
4279 if (strcmp(args[*cur_arg + 1], "none") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01004280 newsrv->ssl_ctx.verify = SSL_SOCK_VERIFY_NONE;
Emeric Brunef42d922012-10-11 16:11:36 +02004281 else if (strcmp(args[*cur_arg + 1], "required") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01004282 newsrv->ssl_ctx.verify = SSL_SOCK_VERIFY_REQUIRED;
Emeric Brunef42d922012-10-11 16:11:36 +02004283 else {
4284 if (err)
4285 memprintf(err, "'%s' : unknown verify method '%s', only 'none' and 'required' are supported\n",
4286 args[*cur_arg], args[*cur_arg + 1]);
4287 return ERR_ALERT | ERR_FATAL;
4288 }
4289
Evan Broderbe554312013-06-27 00:05:25 -07004290 return 0;
4291}
4292
4293/* parse the "verifyhost" server keyword */
4294static int srv_parse_verifyhost(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 hostname to verify against", args[*cur_arg]);
4299 return ERR_ALERT | ERR_FATAL;
4300 }
4301
4302 newsrv->ssl_ctx.verify_host = strdup(args[*cur_arg + 1]);
4303
Emeric Brunef42d922012-10-11 16:11:36 +02004304 return 0;
4305}
4306
Willy Tarreau7875d092012-09-10 08:20:03 +02004307/* Note: must not be declared <const> as its list will be overwritten.
4308 * Please take care of keeping this list alphabetically sorted.
4309 */
Willy Tarreaudc13c112013-06-21 23:16:39 +02004310static struct sample_fetch_kw_list sample_fetch_keywords = {ILH, {
Emeric Brun645ae792014-04-30 14:21:06 +02004311 { "ssl_bc", smp_fetch_ssl_fc, 0, NULL, SMP_T_BOOL, SMP_USE_L5SRV },
4312 { "ssl_bc_alg_keysize", smp_fetch_ssl_fc_alg_keysize, 0, NULL, SMP_T_UINT, SMP_USE_L5SRV },
4313 { "ssl_bc_cipher", smp_fetch_ssl_fc_cipher, 0, NULL, SMP_T_STR, SMP_USE_L5SRV },
4314 { "ssl_bc_protocol", smp_fetch_ssl_fc_protocol, 0, NULL, SMP_T_STR, SMP_USE_L5SRV },
Emeric Brunb73a9b02014-04-30 18:49:19 +02004315 { "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 +02004316 { "ssl_bc_use_keysize", smp_fetch_ssl_fc_use_keysize, 0, NULL, SMP_T_UINT, SMP_USE_L5SRV },
4317 { "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 +01004318 { "ssl_c_ca_err", smp_fetch_ssl_c_ca_err, 0, NULL, SMP_T_UINT, SMP_USE_L5CLI },
4319 { "ssl_c_ca_err_depth", smp_fetch_ssl_c_ca_err_depth, 0, NULL, SMP_T_UINT, SMP_USE_L5CLI },
4320 { "ssl_c_err", smp_fetch_ssl_c_err, 0, NULL, SMP_T_UINT, SMP_USE_L5CLI },
Emeric Brunba841a12014-04-30 17:05:08 +02004321 { "ssl_c_i_dn", smp_fetch_ssl_x_i_dn, ARG2(0,STR,SINT), NULL, SMP_T_STR, SMP_USE_L5CLI },
4322 { "ssl_c_key_alg", smp_fetch_ssl_x_key_alg, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
4323 { "ssl_c_notafter", smp_fetch_ssl_x_notafter, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
4324 { "ssl_c_notbefore", smp_fetch_ssl_x_notbefore, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
4325 { "ssl_c_sig_alg", smp_fetch_ssl_x_sig_alg, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
4326 { "ssl_c_s_dn", smp_fetch_ssl_x_s_dn, ARG2(0,STR,SINT), NULL, SMP_T_STR, SMP_USE_L5CLI },
4327 { "ssl_c_serial", smp_fetch_ssl_x_serial, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
4328 { "ssl_c_sha1", smp_fetch_ssl_x_sha1, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Willy Tarreau80aca902013-01-07 15:42:20 +01004329 { "ssl_c_used", smp_fetch_ssl_c_used, 0, NULL, SMP_T_BOOL, SMP_USE_L5CLI },
4330 { "ssl_c_verify", smp_fetch_ssl_c_verify, 0, NULL, SMP_T_UINT, SMP_USE_L5CLI },
Emeric Brunba841a12014-04-30 17:05:08 +02004331 { "ssl_c_version", smp_fetch_ssl_x_version, 0, NULL, SMP_T_UINT, SMP_USE_L5CLI },
4332 { "ssl_f_i_dn", smp_fetch_ssl_x_i_dn, ARG2(0,STR,SINT), NULL, SMP_T_STR, SMP_USE_L5CLI },
4333 { "ssl_f_key_alg", smp_fetch_ssl_x_key_alg, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
4334 { "ssl_f_notafter", smp_fetch_ssl_x_notafter, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
4335 { "ssl_f_notbefore", smp_fetch_ssl_x_notbefore, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
4336 { "ssl_f_sig_alg", smp_fetch_ssl_x_sig_alg, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
4337 { "ssl_f_s_dn", smp_fetch_ssl_x_s_dn, ARG2(0,STR,SINT), NULL, SMP_T_STR, SMP_USE_L5CLI },
4338 { "ssl_f_serial", smp_fetch_ssl_x_serial, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Emeric Brun55f4fa82014-04-30 17:11:25 +02004339 { "ssl_f_sha1", smp_fetch_ssl_x_sha1, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Emeric Brunba841a12014-04-30 17:05:08 +02004340 { "ssl_f_version", smp_fetch_ssl_x_version, 0, NULL, SMP_T_UINT, SMP_USE_L5CLI },
Willy Tarreau80aca902013-01-07 15:42:20 +01004341 { "ssl_fc", smp_fetch_ssl_fc, 0, NULL, SMP_T_BOOL, SMP_USE_L5CLI },
4342 { "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 +01004343 { "ssl_fc_cipher", smp_fetch_ssl_fc_cipher, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Willy Tarreau80aca902013-01-07 15:42:20 +01004344 { "ssl_fc_has_crt", smp_fetch_ssl_fc_has_crt, 0, NULL, SMP_T_BOOL, SMP_USE_L5CLI },
4345 { "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 +02004346#ifdef OPENSSL_NPN_NEGOTIATED
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01004347 { "ssl_fc_npn", smp_fetch_ssl_fc_npn, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Willy Tarreaua33c6542012-10-15 13:19:06 +02004348#endif
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01004349#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01004350 { "ssl_fc_alpn", smp_fetch_ssl_fc_alpn, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Willy Tarreauab861d32013-04-02 02:30:41 +02004351#endif
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01004352 { "ssl_fc_protocol", smp_fetch_ssl_fc_protocol, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Emeric Brunb73a9b02014-04-30 18:49:19 +02004353 { "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 +01004354 { "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 +01004355 { "ssl_fc_session_id", smp_fetch_ssl_fc_session_id, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
4356 { "ssl_fc_sni", smp_fetch_ssl_fc_sni, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Willy Tarreau7875d092012-09-10 08:20:03 +02004357 { NULL, NULL, 0, 0, 0 },
4358}};
4359
4360/* Note: must not be declared <const> as its list will be overwritten.
4361 * Please take care of keeping this list alphabetically sorted.
4362 */
Willy Tarreaudc13c112013-06-21 23:16:39 +02004363static struct acl_kw_list acl_kws = {ILH, {
Thierry FOURNIERc5a4e982014-03-05 16:07:08 +01004364 { "ssl_fc_sni_end", "ssl_fc_sni", PAT_MATCH_END },
4365 { "ssl_fc_sni_reg", "ssl_fc_sni", PAT_MATCH_REG },
Willy Tarreau8ed669b2013-01-11 15:49:37 +01004366 { /* END */ },
Willy Tarreau7875d092012-09-10 08:20:03 +02004367}};
4368
Willy Tarreau79eeafa2012-09-14 07:53:05 +02004369/* Note: must not be declared <const> as its list will be overwritten.
4370 * Please take care of keeping this list alphabetically sorted, doing so helps
4371 * all code contributors.
4372 * Optional keywords are also declared with a NULL ->parse() function so that
4373 * the config parser can report an appropriate error when a known keyword was
4374 * not enabled.
4375 */
Willy Tarreau51fb7652012-09-18 18:24:39 +02004376static struct bind_kw_list bind_kws = { "SSL", { }, {
Willy Tarreauab861d32013-04-02 02:30:41 +02004377 { "alpn", bind_parse_alpn, 1 }, /* set ALPN supported protocols */
Emeric Brunfb510ea2012-10-05 12:00:26 +02004378 { "ca-file", bind_parse_ca_file, 1 }, /* set CAfile to process verify on client cert */
Emeric Brun2d0c4822012-10-02 13:45:20 +02004379 { "ca-ignore-err", bind_parse_ignore_err, 1 }, /* set error IDs to ignore on verify depth > 0 */
4380 { "ciphers", bind_parse_ciphers, 1 }, /* set SSL cipher suite */
Emeric Brunfb510ea2012-10-05 12:00:26 +02004381 { "crl-file", bind_parse_crl_file, 1 }, /* set certificat revocation list file use on client cert verify */
Emeric Brun2d0c4822012-10-02 13:45:20 +02004382 { "crt", bind_parse_crt, 1 }, /* load SSL certificates from this location */
4383 { "crt-ignore-err", bind_parse_ignore_err, 1 }, /* set error IDs to ingore on verify depth == 0 */
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01004384 { "crt-list", bind_parse_crt_list, 1 }, /* load a list of crt from this location */
Emeric Brun2d0c4822012-10-02 13:45:20 +02004385 { "ecdhe", bind_parse_ecdhe, 1 }, /* defines named curve for elliptic curve Diffie-Hellman */
Emeric Brun2cb7ae52012-10-05 14:14:21 +02004386 { "force-sslv3", bind_parse_force_sslv3, 0 }, /* force SSLv3 */
4387 { "force-tlsv10", bind_parse_force_tlsv10, 0 }, /* force TLSv10 */
4388 { "force-tlsv11", bind_parse_force_tlsv11, 0 }, /* force TLSv11 */
4389 { "force-tlsv12", bind_parse_force_tlsv12, 0 }, /* force TLSv12 */
Emeric Brun9b3009b2012-10-05 11:55:06 +02004390 { "no-sslv3", bind_parse_no_sslv3, 0 }, /* disable SSLv3 */
4391 { "no-tlsv10", bind_parse_no_tlsv10, 0 }, /* disable TLSv10 */
4392 { "no-tlsv11", bind_parse_no_tlsv11, 0 }, /* disable TLSv11 */
4393 { "no-tlsv12", bind_parse_no_tlsv12, 0 }, /* disable TLSv12 */
Emeric Brun2d0c4822012-10-02 13:45:20 +02004394 { "no-tls-tickets", bind_parse_no_tls_tickets, 0 }, /* disable session resumption tickets */
Emeric Brun2d0c4822012-10-02 13:45:20 +02004395 { "ssl", bind_parse_ssl, 0 }, /* enable SSL processing */
Emmanuel Hocdet65623372013-01-24 17:17:15 +01004396 { "strict-sni", bind_parse_strict_sni, 0 }, /* refuse negotiation if sni doesn't match a certificate */
Emeric Brun2d0c4822012-10-02 13:45:20 +02004397 { "verify", bind_parse_verify, 1 }, /* set SSL verify method */
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02004398 { "npn", bind_parse_npn, 1 }, /* set NPN supported protocols */
Willy Tarreau79eeafa2012-09-14 07:53:05 +02004399 { NULL, NULL, 0 },
4400}};
Emeric Brun46591952012-05-18 15:47:34 +02004401
Willy Tarreau92faadf2012-10-10 23:04:25 +02004402/* Note: must not be declared <const> as its list will be overwritten.
4403 * Please take care of keeping this list alphabetically sorted, doing so helps
4404 * all code contributors.
4405 * Optional keywords are also declared with a NULL ->parse() function so that
4406 * the config parser can report an appropriate error when a known keyword was
4407 * not enabled.
4408 */
4409static struct srv_kw_list srv_kws = { "SSL", { }, {
Emeric Brunef42d922012-10-11 16:11:36 +02004410 { "ca-file", srv_parse_ca_file, 1, 0 }, /* set CAfile to process verify server cert */
Emeric Brunecc91fe2012-10-11 15:05:10 +02004411 { "check-ssl", srv_parse_check_ssl, 0, 0 }, /* enable SSL for health checks */
4412 { "ciphers", srv_parse_ciphers, 1, 0 }, /* select the cipher suite */
Emeric Brunef42d922012-10-11 16:11:36 +02004413 { "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 +02004414 { "crt", srv_parse_crt, 1, 0 }, /* set client certificate */
Emeric Brunecc91fe2012-10-11 15:05:10 +02004415 { "force-sslv3", srv_parse_force_sslv3, 0, 0 }, /* force SSLv3 */
4416 { "force-tlsv10", srv_parse_force_tlsv10, 0, 0 }, /* force TLSv10 */
4417 { "force-tlsv11", srv_parse_force_tlsv11, 0, 0 }, /* force TLSv11 */
4418 { "force-tlsv12", srv_parse_force_tlsv12, 0, 0 }, /* force TLSv12 */
4419 { "no-sslv3", srv_parse_no_sslv3, 0, 0 }, /* disable SSLv3 */
4420 { "no-tlsv10", srv_parse_no_tlsv10, 0, 0 }, /* disable TLSv10 */
4421 { "no-tlsv11", srv_parse_no_tlsv11, 0, 0 }, /* disable TLSv11 */
4422 { "no-tlsv12", srv_parse_no_tlsv12, 0, 0 }, /* disable TLSv12 */
Emeric Brunf9c5c472012-10-11 15:28:34 +02004423 { "no-tls-tickets", srv_parse_no_tls_tickets, 0, 0 }, /* disable session resumption tickets */
David Safb76832014-05-08 23:42:08 -04004424 { "send-proxy-v2-ssl", srv_parse_send_proxy_ssl, 0, 0 }, /* send PROXY protocol header v2 with SSL info */
4425 { "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 +02004426 { "ssl", srv_parse_ssl, 0, 0 }, /* enable SSL processing */
Emeric Brunef42d922012-10-11 16:11:36 +02004427 { "verify", srv_parse_verify, 1, 0 }, /* set SSL verify method */
Evan Broderbe554312013-06-27 00:05:25 -07004428 { "verifyhost", srv_parse_verifyhost, 1, 0 }, /* require that SSL cert verifies for hostname */
Willy Tarreau92faadf2012-10-10 23:04:25 +02004429 { NULL, NULL, 0, 0 },
4430}};
4431
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02004432/* transport-layer operations for SSL sockets */
4433struct xprt_ops ssl_sock = {
Emeric Brun46591952012-05-18 15:47:34 +02004434 .snd_buf = ssl_sock_from_buf,
4435 .rcv_buf = ssl_sock_to_buf,
4436 .rcv_pipe = NULL,
4437 .snd_pipe = NULL,
4438 .shutr = NULL,
4439 .shutw = ssl_sock_shutw,
4440 .close = ssl_sock_close,
4441 .init = ssl_sock_init,
4442};
4443
4444__attribute__((constructor))
Willy Tarreau92faadf2012-10-10 23:04:25 +02004445static void __ssl_sock_init(void)
4446{
Emeric Brun46591952012-05-18 15:47:34 +02004447 STACK_OF(SSL_COMP)* cm;
4448
Willy Tarreau610f04b2014-02-13 11:36:41 +01004449#ifdef LISTEN_DEFAULT_CIPHERS
4450 global.listen_default_ciphers = LISTEN_DEFAULT_CIPHERS;
4451#endif
4452#ifdef CONNECT_DEFAULT_CIPHERS
4453 global.connect_default_ciphers = CONNECT_DEFAULT_CIPHERS;
4454#endif
4455 if (global.listen_default_ciphers)
4456 global.listen_default_ciphers = strdup(global.listen_default_ciphers);
4457 if (global.connect_default_ciphers)
4458 global.connect_default_ciphers = strdup(global.connect_default_ciphers);
4459
Emeric Brun46591952012-05-18 15:47:34 +02004460 SSL_library_init();
4461 cm = SSL_COMP_get_compression_methods();
4462 sk_SSL_COMP_zero(cm);
Willy Tarreau7875d092012-09-10 08:20:03 +02004463 sample_register_fetches(&sample_fetch_keywords);
4464 acl_register_keywords(&acl_kws);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02004465 bind_register_keywords(&bind_kws);
Willy Tarreau92faadf2012-10-10 23:04:25 +02004466 srv_register_keywords(&srv_kws);
Emeric Brun46591952012-05-18 15:47:34 +02004467}
4468
4469/*
4470 * Local variables:
4471 * c-indent-level: 8
4472 * c-basic-offset: 8
4473 * End:
4474 */