blob: f8bfbe758222673a4e2bb834779bff1b5e3252bb [file] [log] [blame]
Emeric Brun46591952012-05-18 15:47:34 +02001/*
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02002 * SSL/TLS transport layer over SOCK_STREAM sockets
Emeric Brun46591952012-05-18 15:47:34 +02003 *
4 * Copyright (C) 2012 EXCELIANCE, Emeric Brun <ebrun@exceliance.fr>
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version
9 * 2 of the License, or (at your option) any later version.
10 *
Willy Tarreau69845df2012-09-10 09:43:09 +020011 * Acknowledgement:
12 * We'd like to specially thank the Stud project authors for a very clean
13 * and well documented code which helped us understand how the OpenSSL API
14 * ought to be used in non-blocking mode. This is one difficult part which
15 * is not easy to get from the OpenSSL doc, and reading the Stud code made
16 * it much more obvious than the examples in the OpenSSL package. Keep up
17 * the good works, guys !
18 *
19 * Stud is an extremely efficient and scalable SSL/TLS proxy which combines
20 * particularly well with haproxy. For more info about this project, visit :
21 * https://github.com/bumptech/stud
22 *
Emeric Brun46591952012-05-18 15:47:34 +020023 */
24
25#define _GNU_SOURCE
Emeric Brunfc0421f2012-09-07 17:30:07 +020026#include <ctype.h>
27#include <dirent.h>
Emeric Brun46591952012-05-18 15:47:34 +020028#include <errno.h>
29#include <fcntl.h>
30#include <stdio.h>
31#include <stdlib.h>
Emeric Brunfc0421f2012-09-07 17:30:07 +020032#include <string.h>
33#include <unistd.h>
Emeric Brun46591952012-05-18 15:47:34 +020034
35#include <sys/socket.h>
36#include <sys/stat.h>
37#include <sys/types.h>
38
39#include <netinet/tcp.h>
40
41#include <openssl/ssl.h>
Emeric Brunfc0421f2012-09-07 17:30:07 +020042#include <openssl/x509.h>
43#include <openssl/x509v3.h>
44#include <openssl/x509.h>
45#include <openssl/err.h>
Thierry Fournier383085f2013-01-24 14:15:43 +010046#include <openssl/rand.h>
Emeric Brun4147b2e2014-06-16 18:36:30 +020047#ifdef SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB
48#include <openssl/ocsp.h>
49#endif
Emeric Brun46591952012-05-18 15:47:34 +020050
51#include <common/buffer.h>
52#include <common/compat.h>
53#include <common/config.h>
54#include <common/debug.h>
Willy Tarreau79eeafa2012-09-14 07:53:05 +020055#include <common/errors.h>
Emeric Brun46591952012-05-18 15:47:34 +020056#include <common/standard.h>
57#include <common/ticks.h>
58#include <common/time.h>
Emeric Brun42a3e202014-10-30 15:56:50 +010059#include <common/cfgparse.h>
Emeric Brun46591952012-05-18 15:47:34 +020060
Emeric Brunfc0421f2012-09-07 17:30:07 +020061#include <ebsttree.h>
62
63#include <types/global.h>
64#include <types/ssl_sock.h>
65
Willy Tarreau7875d092012-09-10 08:20:03 +020066#include <proto/acl.h>
67#include <proto/arg.h>
Emeric Brun46591952012-05-18 15:47:34 +020068#include <proto/connection.h>
69#include <proto/fd.h>
70#include <proto/freq_ctr.h>
71#include <proto/frontend.h>
Willy Tarreau79eeafa2012-09-14 07:53:05 +020072#include <proto/listener.h>
Thierry FOURNIERed66c292013-11-28 11:05:19 +010073#include <proto/pattern.h>
Willy Tarreau92faadf2012-10-10 23:04:25 +020074#include <proto/server.h>
Emeric Brun46591952012-05-18 15:47:34 +020075#include <proto/log.h>
Emeric Brun94324a42012-10-11 14:00:19 +020076#include <proto/proxy.h>
Emeric Brunfc0421f2012-09-07 17:30:07 +020077#include <proto/shctx.h>
Emeric Brun46591952012-05-18 15:47:34 +020078#include <proto/ssl_sock.h>
79#include <proto/task.h>
80
Willy Tarreau518cedd2014-02-17 15:43:01 +010081/* Warning, these are bits, not integers! */
Emeric Brune64aef12012-09-21 13:15:06 +020082#define SSL_SOCK_ST_FL_VERIFY_DONE 0x00000001
Emeric Brund8b2bb52014-01-28 15:43:53 +010083#define SSL_SOCK_ST_FL_16K_WBFSIZE 0x00000002
Willy Tarreau518cedd2014-02-17 15:43:01 +010084#define SSL_SOCK_SEND_UNLIMITED 0x00000004
Emeric Brun29f037d2014-04-25 19:05:36 +020085#define SSL_SOCK_RECV_HEARTBEAT 0x00000008
86
Emeric Brunf282a812012-09-21 15:27:54 +020087/* bits 0xFFFF0000 are reserved to store verify errors */
88
89/* Verify errors macros */
90#define SSL_SOCK_CA_ERROR_TO_ST(e) (((e > 63) ? 63 : e) << (16))
91#define SSL_SOCK_CAEDEPTH_TO_ST(d) (((d > 15) ? 15 : d) << (6+16))
92#define SSL_SOCK_CRTERROR_TO_ST(e) (((e > 63) ? 63 : e) << (4+6+16))
93
94#define SSL_SOCK_ST_TO_CA_ERROR(s) ((s >> (16)) & 63)
95#define SSL_SOCK_ST_TO_CAEDEPTH(s) ((s >> (6+16)) & 15)
96#define SSL_SOCK_ST_TO_CRTERROR(s) ((s >> (4+6+16)) & 63)
Emeric Brune64aef12012-09-21 13:15:06 +020097
Emeric Brun850efd52014-01-29 12:24:34 +010098/* server and bind verify method, it uses a global value as default */
99enum {
100 SSL_SOCK_VERIFY_DEFAULT = 0,
101 SSL_SOCK_VERIFY_REQUIRED = 1,
102 SSL_SOCK_VERIFY_OPTIONAL = 2,
103 SSL_SOCK_VERIFY_NONE = 3,
104};
105
Willy Tarreau71b734c2014-01-28 15:19:44 +0100106int sslconns = 0;
107int totalsslconns = 0;
Emeric Brune1f38db2012-09-03 20:36:47 +0200108
Remi Gacogne60d7aeb2014-07-15 11:36:40 +0200109#ifndef OPENSSL_NO_DH
110static DH *local_dh_1024 = NULL;
111static DH *local_dh_2048 = NULL;
112static DH *local_dh_4096 = NULL;
113static DH *local_dh_8192 = NULL;
114#endif /* OPENSSL_NO_DH */
115
Emeric Brun4147b2e2014-06-16 18:36:30 +0200116#ifdef SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB
117struct certificate_ocsp {
118 struct ebmb_node key;
119 unsigned char key_data[OCSP_MAX_CERTID_ASN1_LENGTH];
120 struct chunk response;
Emeric Brun58484372014-06-20 15:46:13 +0200121 long expire;
Emeric Brun4147b2e2014-06-16 18:36:30 +0200122};
123
Emeric Brun58484372014-06-20 15:46:13 +0200124/*
125 * This function returns the number of seconds elapsed
126 * since the Epoch, 1970-01-01 00:00:00 +0000 (UTC) and the
127 * date presented un ASN1_GENERALIZEDTIME.
128 *
129 * In parsing error case, it returns -1.
130 */
131static long asn1_generalizedtime_to_epoch(ASN1_GENERALIZEDTIME *d)
132{
133 long epoch;
134 char *p, *end;
135 const unsigned short month_offset[12] = {
136 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334
137 };
138 int year, month;
139
140 if (!d || (d->type != V_ASN1_GENERALIZEDTIME)) return -1;
141
142 p = (char *)d->data;
143 end = p + d->length;
144
145 if (end - p < 4) return -1;
146 year = 1000 * (p[0] - '0') + 100 * (p[1] - '0') + 10 * (p[2] - '0') + p[3] - '0';
147 p += 4;
148 if (end - p < 2) return -1;
149 month = 10 * (p[0] - '0') + p[1] - '0';
150 if (month < 1 || month > 12) return -1;
151 /* Compute the number of seconds since 1 jan 1970 and the beginning of current month
152 We consider leap years and the current month (<marsh or not) */
153 epoch = ( ((year - 1970) * 365)
154 + ((year - (month < 3)) / 4 - (year - (month < 3)) / 100 + (year - (month < 3)) / 400)
155 - ((1970 - 1) / 4 - (1970 - 1) / 100 + (1970 - 1) / 400)
156 + month_offset[month-1]
157 ) * 24 * 60 * 60;
158 p += 2;
159 if (end - p < 2) return -1;
160 /* Add the number of seconds of completed days of current month */
161 epoch += (10 * (p[0] - '0') + p[1] - '0' - 1) * 24 * 60 * 60;
162 p += 2;
163 if (end - p < 2) return -1;
164 /* Add the completed hours of the current day */
165 epoch += (10 * (p[0] - '0') + p[1] - '0') * 60 * 60;
166 p += 2;
167 if (end - p < 2) return -1;
168 /* Add the completed minutes of the current hour */
169 epoch += (10 * (p[0] - '0') + p[1] - '0') * 60;
170 p += 2;
171 if (p == end) return -1;
172 /* Test if there is available seconds */
173 if (p[0] < '0' || p[0] > '9')
174 goto nosec;
175 if (end - p < 2) return -1;
176 /* Add the seconds of the current minute */
177 epoch += 10 * (p[0] - '0') + p[1] - '0';
178 p += 2;
179 if (p == end) return -1;
180 /* Ignore seconds float part if present */
181 if (p[0] == '.') {
182 do {
183 if (++p == end) return -1;
184 } while (p[0] >= '0' && p[0] <= '9');
185 }
186
187nosec:
188 if (p[0] == 'Z') {
189 if (end - p != 1) return -1;
190 return epoch;
191 }
192 else if (p[0] == '+') {
193 if (end - p != 5) return -1;
194 /* Apply timezone offset */
195 return epoch - ((10 * (p[1] - '0') + p[2] - '0') * 60 + (10 * (p[3] - '0') + p[4] - '0')) * 60;
196 }
197 else if (p[0] == '-') {
198 if (end - p != 5) return -1;
199 /* Apply timezone offset */
200 return epoch + ((10 * (p[1] - '0') + p[2] - '0') * 60 + (10 * (p[3] - '0') + p[4] - '0')) * 60;
201 }
202
203 return -1;
204}
205
Emeric Brun8d914d12014-06-20 15:37:32 +0200206static struct eb_root cert_ocsp_tree = EB_ROOT_UNIQUE;
Emeric Brun4147b2e2014-06-16 18:36:30 +0200207
208/* This function starts to check if the OCSP response (in DER format) contained
209 * in chunk 'ocsp_response' is valid (else exits on error).
210 * If 'cid' is not NULL, it will be compared to the OCSP certificate ID
211 * contained in the OCSP Response and exits on error if no match.
212 * If it's a valid OCSP Response:
213 * If 'ocsp' is not NULL, the chunk is copied in the OCSP response's container
214 * pointed by 'ocsp'.
215 * If 'ocsp' is NULL, the function looks up into the OCSP response's
216 * containers tree (using as index the ASN1 form of the OCSP Certificate ID extracted
217 * from the response) and exits on error if not found. Finally, If an OCSP response is
218 * already present in the container, it will be overwritten.
219 *
220 * Note: OCSP response containing more than one OCSP Single response is not
221 * considered valid.
222 *
223 * Returns 0 on success, 1 in error case.
224 */
225static int ssl_sock_load_ocsp_response(struct chunk *ocsp_response, struct certificate_ocsp *ocsp, OCSP_CERTID *cid, char **err)
226{
227 OCSP_RESPONSE *resp;
228 OCSP_BASICRESP *bs = NULL;
229 OCSP_SINGLERESP *sr;
230 unsigned char *p = (unsigned char *)ocsp_response->str;
231 int rc , count_sr;
Emeric Brun1135ea42014-06-20 15:44:34 +0200232 ASN1_GENERALIZEDTIME *revtime, *thisupd, *nextupd = NULL;
Emeric Brun4147b2e2014-06-16 18:36:30 +0200233 int reason;
234 int ret = 1;
235
236 resp = d2i_OCSP_RESPONSE(NULL, (const unsigned char **)&p, ocsp_response->len);
237 if (!resp) {
238 memprintf(err, "Unable to parse OCSP response");
239 goto out;
240 }
241
242 rc = OCSP_response_status(resp);
243 if (rc != OCSP_RESPONSE_STATUS_SUCCESSFUL) {
244 memprintf(err, "OCSP response status not successful");
245 goto out;
246 }
247
248 bs = OCSP_response_get1_basic(resp);
249 if (!bs) {
250 memprintf(err, "Failed to get basic response from OCSP Response");
251 goto out;
252 }
253
254 count_sr = OCSP_resp_count(bs);
255 if (count_sr > 1) {
256 memprintf(err, "OCSP response ignored because contains multiple single responses (%d)", count_sr);
257 goto out;
258 }
259
260 sr = OCSP_resp_get0(bs, 0);
261 if (!sr) {
262 memprintf(err, "Failed to get OCSP single response");
263 goto out;
264 }
265
266 rc = OCSP_single_get0_status(sr, &reason, &revtime, &thisupd, &nextupd);
267 if (rc != V_OCSP_CERTSTATUS_GOOD) {
268 memprintf(err, "OCSP single response: certificate status not good");
269 goto out;
270 }
271
Emeric Brun1135ea42014-06-20 15:44:34 +0200272 if (!nextupd) {
273 memprintf(err, "OCSP single response: missing nextupdate");
274 goto out;
275 }
276
Emeric Brunc8b27b62014-06-19 14:16:17 +0200277 rc = OCSP_check_validity(thisupd, nextupd, OCSP_MAX_RESPONSE_TIME_SKEW, -1);
Emeric Brun4147b2e2014-06-16 18:36:30 +0200278 if (!rc) {
279 memprintf(err, "OCSP single response: no longer valid.");
280 goto out;
281 }
282
283 if (cid) {
284 if (OCSP_id_cmp(sr->certId, cid)) {
285 memprintf(err, "OCSP single response: Certificate ID does not match certificate and issuer");
286 goto out;
287 }
288 }
289
290 if (!ocsp) {
291 unsigned char key[OCSP_MAX_CERTID_ASN1_LENGTH];
292 unsigned char *p;
293
294 rc = i2d_OCSP_CERTID(sr->certId, NULL);
295 if (!rc) {
296 memprintf(err, "OCSP single response: Unable to encode Certificate ID");
297 goto out;
298 }
299
300 if (rc > OCSP_MAX_CERTID_ASN1_LENGTH) {
301 memprintf(err, "OCSP single response: Certificate ID too long");
302 goto out;
303 }
304
305 p = key;
306 memset(key, 0, OCSP_MAX_CERTID_ASN1_LENGTH);
307 i2d_OCSP_CERTID(sr->certId, &p);
308 ocsp = (struct certificate_ocsp *)ebmb_lookup(&cert_ocsp_tree, key, OCSP_MAX_CERTID_ASN1_LENGTH);
309 if (!ocsp) {
310 memprintf(err, "OCSP single response: Certificate ID does not match any certificate or issuer");
311 goto out;
312 }
313 }
314
315 /* According to comments on "chunk_dup", the
316 previous chunk buffer will be freed */
317 if (!chunk_dup(&ocsp->response, ocsp_response)) {
318 memprintf(err, "OCSP response: Memory allocation error");
319 goto out;
320 }
321
Emeric Brun58484372014-06-20 15:46:13 +0200322 ocsp->expire = asn1_generalizedtime_to_epoch(nextupd) - OCSP_MAX_RESPONSE_TIME_SKEW;
323
Emeric Brun4147b2e2014-06-16 18:36:30 +0200324 ret = 0;
325out:
326 if (bs)
327 OCSP_BASICRESP_free(bs);
328
329 if (resp)
330 OCSP_RESPONSE_free(resp);
331
332 return ret;
333}
334/*
335 * External function use to update the OCSP response in the OCSP response's
336 * containers tree. The chunk 'ocsp_response' must contain the OCSP response
337 * to update in DER format.
338 *
339 * Returns 0 on success, 1 in error case.
340 */
341int ssl_sock_update_ocsp_response(struct chunk *ocsp_response, char **err)
342{
343 return ssl_sock_load_ocsp_response(ocsp_response, NULL, NULL, err);
344}
345
346/*
347 * This function load the OCSP Resonse in DER format contained in file at
348 * path 'ocsp_path' and call 'ssl_sock_load_ocsp_response'
349 *
350 * Returns 0 on success, 1 in error case.
351 */
352static int ssl_sock_load_ocsp_response_from_file(const char *ocsp_path, struct certificate_ocsp *ocsp, OCSP_CERTID *cid, char **err)
353{
354 int fd = -1;
355 int r = 0;
356 int ret = 1;
357
358 fd = open(ocsp_path, O_RDONLY);
359 if (fd == -1) {
360 memprintf(err, "Error opening OCSP response file");
361 goto end;
362 }
363
364 trash.len = 0;
365 while (trash.len < trash.size) {
366 r = read(fd, trash.str + trash.len, trash.size - trash.len);
367 if (r < 0) {
368 if (errno == EINTR)
369 continue;
370
371 memprintf(err, "Error reading OCSP response from file");
372 goto end;
373 }
374 else if (r == 0) {
375 break;
376 }
377 trash.len += r;
378 }
379
380 close(fd);
381 fd = -1;
382
383 ret = ssl_sock_load_ocsp_response(&trash, ocsp, cid, err);
384end:
385 if (fd != -1)
386 close(fd);
387
388 return ret;
389}
390
391/*
392 * Callback used to set OCSP status extension content in server hello.
393 */
394int ssl_sock_ocsp_stapling_cbk(SSL *ssl, void *arg)
395{
396 struct certificate_ocsp *ocsp = (struct certificate_ocsp *)arg;
397 char* ssl_buf;
398
399 if (!ocsp ||
400 !ocsp->response.str ||
Emeric Brun58484372014-06-20 15:46:13 +0200401 !ocsp->response.len ||
402 (ocsp->expire < now.tv_sec))
Emeric Brun4147b2e2014-06-16 18:36:30 +0200403 return SSL_TLSEXT_ERR_NOACK;
404
405 ssl_buf = OPENSSL_malloc(ocsp->response.len);
406 if (!ssl_buf)
407 return SSL_TLSEXT_ERR_NOACK;
408
409 memcpy(ssl_buf, ocsp->response.str, ocsp->response.len);
410 SSL_set_tlsext_status_ocsp_resp(ssl, ssl_buf, ocsp->response.len);
411
412 return SSL_TLSEXT_ERR_OK;
413}
414
415/*
416 * This function enables the handling of OCSP status extension on 'ctx' if a
417 * file name 'cert_path' suffixed using ".ocsp" is present.
418 * To enable OCSP status extension, the issuer's certificate is mandatory.
419 * It should be present in the certificate's extra chain builded from file
420 * 'cert_path'. If not found, the issuer certificate is loaded from a file
421 * named 'cert_path' suffixed using '.issuer'.
422 *
423 * In addition, ".ocsp" file content is loaded as a DER format of an OCSP
424 * response. If file is empty or content is not a valid OCSP response,
425 * OCSP status extension is enabled but OCSP response is ignored (a warning
426 * is displayed).
427 *
428 * Returns 1 if no ".ocsp" file found, 0 if OCSP status extension is
429 * succesfully enabled, or -1 in other error case.
430 */
431static int ssl_sock_load_ocsp(SSL_CTX *ctx, const char *cert_path)
432{
433
434 BIO *in = NULL;
435 X509 *x, *xi = NULL, *issuer = NULL;
436 STACK_OF(X509) *chain = NULL;
437 OCSP_CERTID *cid = NULL;
438 SSL *ssl;
439 char ocsp_path[MAXPATHLEN+1];
440 int i, ret = -1;
441 struct stat st;
442 struct certificate_ocsp *ocsp = NULL, *iocsp;
443 char *warn = NULL;
444 unsigned char *p;
445
446 snprintf(ocsp_path, MAXPATHLEN+1, "%s.ocsp", cert_path);
447
448 if (stat(ocsp_path, &st))
449 return 1;
450
451 ssl = SSL_new(ctx);
452 if (!ssl)
453 goto out;
454
455 x = SSL_get_certificate(ssl);
456 if (!x)
457 goto out;
458
459 /* Try to lookup for issuer in certificate extra chain */
460#ifdef SSL_CTRL_GET_EXTRA_CHAIN_CERTS
461 SSL_CTX_get_extra_chain_certs(ctx, &chain);
462#else
463 chain = ctx->extra_certs;
464#endif
465 for (i = 0; i < sk_X509_num(chain); i++) {
466 issuer = sk_X509_value(chain, i);
467 if (X509_check_issued(issuer, x) == X509_V_OK)
468 break;
469 else
470 issuer = NULL;
471 }
472
473 /* If not found try to load issuer from a suffixed file */
474 if (!issuer) {
475 char issuer_path[MAXPATHLEN+1];
476
477 in = BIO_new(BIO_s_file());
478 if (!in)
479 goto out;
480
481 snprintf(issuer_path, MAXPATHLEN+1, "%s.issuer", cert_path);
482 if (BIO_read_filename(in, issuer_path) <= 0)
483 goto out;
484
485 xi = PEM_read_bio_X509_AUX(in, NULL, ctx->default_passwd_callback, ctx->default_passwd_callback_userdata);
486 if (!xi)
487 goto out;
488
489 if (X509_check_issued(xi, x) != X509_V_OK)
490 goto out;
491
492 issuer = xi;
493 }
494
495 cid = OCSP_cert_to_id(0, x, issuer);
496 if (!cid)
497 goto out;
498
499 i = i2d_OCSP_CERTID(cid, NULL);
500 if (!i || (i > OCSP_MAX_CERTID_ASN1_LENGTH))
501 goto out;
502
503 ocsp = calloc(1, sizeof(struct certificate_ocsp));
504 if (!ocsp)
505 goto out;
506
507 p = ocsp->key_data;
508 i2d_OCSP_CERTID(cid, &p);
509
510 iocsp = (struct certificate_ocsp *)ebmb_insert(&cert_ocsp_tree, &ocsp->key, OCSP_MAX_CERTID_ASN1_LENGTH);
511 if (iocsp == ocsp)
512 ocsp = NULL;
513
514 SSL_CTX_set_tlsext_status_cb(ctx, ssl_sock_ocsp_stapling_cbk);
515 SSL_CTX_set_tlsext_status_arg(ctx, iocsp);
516
517 ret = 0;
518
519 warn = NULL;
520 if (ssl_sock_load_ocsp_response_from_file(ocsp_path, iocsp, cid, &warn)) {
521 memprintf(&warn, "Loading '%s': %s. Content will be ignored", ocsp_path, warn ? warn : "failure");
522 Warning("%s.\n", warn);
523 }
524
525out:
526 if (ssl)
527 SSL_free(ssl);
528
529 if (in)
530 BIO_free(in);
531
532 if (xi)
533 X509_free(xi);
534
535 if (cid)
536 OCSP_CERTID_free(cid);
537
538 if (ocsp)
539 free(ocsp);
540
541 if (warn)
542 free(warn);
543
544
545 return ret;
546}
547
548#endif
549
Emeric Brune1f38db2012-09-03 20:36:47 +0200550void ssl_sock_infocbk(const SSL *ssl, int where, int ret)
551{
552 struct connection *conn = (struct connection *)SSL_get_app_data(ssl);
553 (void)ret; /* shut gcc stupid warning */
Emeric Brund8b2bb52014-01-28 15:43:53 +0100554 BIO *write_bio;
Emeric Brune1f38db2012-09-03 20:36:47 +0200555
556 if (where & SSL_CB_HANDSHAKE_START) {
557 /* Disable renegotiation (CVE-2009-3555) */
Willy Tarreau20879a02012-12-03 16:32:10 +0100558 if (conn->flags & CO_FL_CONNECTED) {
Emeric Brune1f38db2012-09-03 20:36:47 +0200559 conn->flags |= CO_FL_ERROR;
Willy Tarreau20879a02012-12-03 16:32:10 +0100560 conn->err_code = CO_ER_SSL_RENEG;
561 }
Emeric Brune1f38db2012-09-03 20:36:47 +0200562 }
Emeric Brund8b2bb52014-01-28 15:43:53 +0100563
564 if ((where & SSL_CB_ACCEPT_LOOP) == SSL_CB_ACCEPT_LOOP) {
565 if (!(conn->xprt_st & SSL_SOCK_ST_FL_16K_WBFSIZE)) {
566 /* Long certificate chains optimz
567 If write and read bios are differents, we
568 consider that the buffering was activated,
569 so we rise the output buffer size from 4k
570 to 16k */
571 write_bio = SSL_get_wbio(ssl);
572 if (write_bio != SSL_get_rbio(ssl)) {
573 BIO_set_write_buffer_size(write_bio, 16384);
574 conn->xprt_st |= SSL_SOCK_ST_FL_16K_WBFSIZE;
575 }
576 }
577 }
Emeric Brunfc0421f2012-09-07 17:30:07 +0200578}
579
Emeric Brune64aef12012-09-21 13:15:06 +0200580/* Callback is called for each certificate of the chain during a verify
581 ok is set to 1 if preverify detect no error on current certificate.
582 Returns 0 to break the handshake, 1 otherwise. */
Evan Broderbe554312013-06-27 00:05:25 -0700583int ssl_sock_bind_verifycbk(int ok, X509_STORE_CTX *x_store)
Emeric Brune64aef12012-09-21 13:15:06 +0200584{
585 SSL *ssl;
586 struct connection *conn;
Emeric Brun81c00f02012-09-21 14:31:21 +0200587 int err, depth;
Emeric Brune64aef12012-09-21 13:15:06 +0200588
589 ssl = X509_STORE_CTX_get_ex_data(x_store, SSL_get_ex_data_X509_STORE_CTX_idx());
590 conn = (struct connection *)SSL_get_app_data(ssl);
591
Willy Tarreauf7bc57c2012-10-03 00:19:48 +0200592 conn->xprt_st |= SSL_SOCK_ST_FL_VERIFY_DONE;
Emeric Brune64aef12012-09-21 13:15:06 +0200593
Emeric Brun81c00f02012-09-21 14:31:21 +0200594 if (ok) /* no errors */
595 return ok;
596
597 depth = X509_STORE_CTX_get_error_depth(x_store);
598 err = X509_STORE_CTX_get_error(x_store);
599
600 /* check if CA error needs to be ignored */
601 if (depth > 0) {
Willy Tarreauf7bc57c2012-10-03 00:19:48 +0200602 if (!SSL_SOCK_ST_TO_CA_ERROR(conn->xprt_st)) {
603 conn->xprt_st |= SSL_SOCK_CA_ERROR_TO_ST(err);
604 conn->xprt_st |= SSL_SOCK_CAEDEPTH_TO_ST(depth);
Emeric Brunf282a812012-09-21 15:27:54 +0200605 }
606
Emeric Brun1eb20ef2012-12-03 13:24:29 +0100607 if (objt_listener(conn->target)->bind_conf->ca_ignerr & (1ULL << err)) {
608 ERR_clear_error();
Emeric Brun81c00f02012-09-21 14:31:21 +0200609 return 1;
Emeric Brun1eb20ef2012-12-03 13:24:29 +0100610 }
Emeric Brun81c00f02012-09-21 14:31:21 +0200611
Willy Tarreau20879a02012-12-03 16:32:10 +0100612 conn->err_code = CO_ER_SSL_CA_FAIL;
Emeric Brun81c00f02012-09-21 14:31:21 +0200613 return 0;
614 }
615
Willy Tarreauf7bc57c2012-10-03 00:19:48 +0200616 if (!SSL_SOCK_ST_TO_CRTERROR(conn->xprt_st))
617 conn->xprt_st |= SSL_SOCK_CRTERROR_TO_ST(err);
Emeric Brunf282a812012-09-21 15:27:54 +0200618
Emeric Brun81c00f02012-09-21 14:31:21 +0200619 /* check if certificate error needs to be ignored */
Emeric Brun1eb20ef2012-12-03 13:24:29 +0100620 if (objt_listener(conn->target)->bind_conf->crt_ignerr & (1ULL << err)) {
621 ERR_clear_error();
Emeric Brun81c00f02012-09-21 14:31:21 +0200622 return 1;
Emeric Brun1eb20ef2012-12-03 13:24:29 +0100623 }
Emeric Brun81c00f02012-09-21 14:31:21 +0200624
Willy Tarreau20879a02012-12-03 16:32:10 +0100625 conn->err_code = CO_ER_SSL_CRT_FAIL;
Emeric Brun81c00f02012-09-21 14:31:21 +0200626 return 0;
Emeric Brune64aef12012-09-21 13:15:06 +0200627}
628
Emeric Brun29f037d2014-04-25 19:05:36 +0200629/* Callback is called for ssl protocol analyse */
630void ssl_sock_msgcbk(int write_p, int version, int content_type, const void *buf, size_t len, SSL *ssl, void *arg)
631{
Emeric Brun29f037d2014-04-25 19:05:36 +0200632#ifdef TLS1_RT_HEARTBEAT
633 /* test heartbeat received (write_p is set to 0
634 for a received record) */
Willy Tarreauf51c6982014-04-25 20:02:39 +0200635 if ((content_type == TLS1_RT_HEARTBEAT) && (write_p == 0)) {
Willy Tarreau84815002014-04-25 21:40:27 +0200636 struct connection *conn = (struct connection *)SSL_get_app_data(ssl);
Willy Tarreauf51c6982014-04-25 20:02:39 +0200637 const unsigned char *p = buf;
638 unsigned int payload;
639
Emeric Brun29f037d2014-04-25 19:05:36 +0200640 conn->xprt_st |= SSL_SOCK_RECV_HEARTBEAT;
Willy Tarreauf51c6982014-04-25 20:02:39 +0200641
642 /* Check if this is a CVE-2014-0160 exploitation attempt. */
643 if (*p != TLS1_HB_REQUEST)
644 return;
645
Willy Tarreauaeed6722014-04-25 23:59:58 +0200646 if (len < 1 + 2 + 16) /* 1 type + 2 size + 0 payload + 16 padding */
Willy Tarreauf51c6982014-04-25 20:02:39 +0200647 goto kill_it;
648
649 payload = (p[1] * 256) + p[2];
Willy Tarreau3b2fdb62014-04-25 23:44:22 +0200650 if (3 + payload + 16 <= len)
Willy Tarreauf51c6982014-04-25 20:02:39 +0200651 return; /* OK no problem */
Willy Tarreauaeed6722014-04-25 23:59:58 +0200652 kill_it:
Willy Tarreau3b2fdb62014-04-25 23:44:22 +0200653 /* We have a clear heartbleed attack (CVE-2014-0160), the
654 * advertised payload is larger than the advertised packet
655 * length, so we have garbage in the buffer between the
656 * payload and the end of the buffer (p+len). We can't know
657 * if the SSL stack is patched, and we don't know if we can
658 * safely wipe out the area between p+3+len and payload.
659 * So instead, we prevent the response from being sent by
660 * setting the max_send_fragment to 0 and we report an SSL
661 * error, which will kill this connection. It will be reported
662 * above as SSL_ERROR_SSL while an other handshake failure with
Willy Tarreauf51c6982014-04-25 20:02:39 +0200663 * a heartbeat message will be reported as SSL_ERROR_SYSCALL.
664 */
Willy Tarreau3b2fdb62014-04-25 23:44:22 +0200665 ssl->max_send_fragment = 0;
Willy Tarreauf51c6982014-04-25 20:02:39 +0200666 SSLerr(SSL_F_TLS1_HEARTBEAT, SSL_R_SSL_HANDSHAKE_FAILURE);
667 return;
668 }
Emeric Brun29f037d2014-04-25 19:05:36 +0200669#endif
670}
671
Willy Tarreau6c9a3d52012-10-18 18:57:14 +0200672#ifdef OPENSSL_NPN_NEGOTIATED
673/* This callback is used so that the server advertises the list of
674 * negociable protocols for NPN.
675 */
676static int ssl_sock_advertise_npn_protos(SSL *s, const unsigned char **data,
677 unsigned int *len, void *arg)
678{
679 struct bind_conf *conf = arg;
680
681 *data = (const unsigned char *)conf->npn_str;
682 *len = conf->npn_len;
683 return SSL_TLSEXT_ERR_OK;
684}
685#endif
686
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +0100687#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Willy Tarreauab861d32013-04-02 02:30:41 +0200688/* This callback is used so that the server advertises the list of
689 * negociable protocols for ALPN.
690 */
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +0100691static int ssl_sock_advertise_alpn_protos(SSL *s, const unsigned char **out,
692 unsigned char *outlen,
693 const unsigned char *server,
694 unsigned int server_len, void *arg)
Willy Tarreauab861d32013-04-02 02:30:41 +0200695{
696 struct bind_conf *conf = arg;
697
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +0100698 if (SSL_select_next_proto((unsigned char**) out, outlen, (const unsigned char *)conf->alpn_str,
699 conf->alpn_len, server, server_len) != OPENSSL_NPN_NEGOTIATED) {
700 return SSL_TLSEXT_ERR_NOACK;
701 }
Willy Tarreauab861d32013-04-02 02:30:41 +0200702 return SSL_TLSEXT_ERR_OK;
703}
704#endif
705
Emeric Brunfc0421f2012-09-07 17:30:07 +0200706#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
707/* Sets the SSL ctx of <ssl> to match the advertised server name. Returns a
708 * warning when no match is found, which implies the default (first) cert
709 * will keep being used.
710 */
Willy Tarreau2a65ff02012-09-13 17:54:29 +0200711static int ssl_sock_switchctx_cbk(SSL *ssl, int *al, struct bind_conf *s)
Emeric Brunfc0421f2012-09-07 17:30:07 +0200712{
713 const char *servername;
714 const char *wildp = NULL;
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +0200715 struct ebmb_node *node, *n;
Emeric Brunfc0421f2012-09-07 17:30:07 +0200716 int i;
717 (void)al; /* shut gcc stupid warning */
718
719 servername = SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name);
Emmanuel Hocdet65623372013-01-24 17:17:15 +0100720 if (!servername) {
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +0200721 return (s->strict_sni ?
722 SSL_TLSEXT_ERR_ALERT_FATAL :
Emmanuel Hocdet79274e22013-05-31 12:47:44 +0200723 SSL_TLSEXT_ERR_NOACK);
Emmanuel Hocdet65623372013-01-24 17:17:15 +0100724 }
Emeric Brunfc0421f2012-09-07 17:30:07 +0200725
Willy Tarreau19d14ef2012-10-29 16:51:55 +0100726 for (i = 0; i < trash.size; i++) {
Emeric Brunfc0421f2012-09-07 17:30:07 +0200727 if (!servername[i])
728 break;
Willy Tarreau19d14ef2012-10-29 16:51:55 +0100729 trash.str[i] = tolower(servername[i]);
730 if (!wildp && (trash.str[i] == '.'))
731 wildp = &trash.str[i];
Emeric Brunfc0421f2012-09-07 17:30:07 +0200732 }
Willy Tarreau19d14ef2012-10-29 16:51:55 +0100733 trash.str[i] = 0;
Emeric Brunfc0421f2012-09-07 17:30:07 +0200734
735 /* lookup in full qualified names */
Willy Tarreau19d14ef2012-10-29 16:51:55 +0100736 node = ebst_lookup(&s->sni_ctx, trash.str);
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +0200737
738 /* lookup a not neg filter */
739 for (n = node; n; n = ebmb_next_dup(n)) {
740 if (!container_of(n, struct sni_ctx, name)->neg) {
741 node = n;
742 break;
Emmanuel Hocdet65623372013-01-24 17:17:15 +0100743 }
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +0200744 }
745 if (!node && wildp) {
746 /* lookup in wildcards names */
Emeric Brunfc0421f2012-09-07 17:30:07 +0200747 node = ebst_lookup(&s->sni_w_ctx, wildp);
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +0200748 }
749 if (!node || container_of(node, struct sni_ctx, name)->neg) {
750 return (s->strict_sni ?
751 SSL_TLSEXT_ERR_ALERT_FATAL :
752 SSL_TLSEXT_ERR_ALERT_WARNING);
Emeric Brunfc0421f2012-09-07 17:30:07 +0200753 }
754
755 /* switch ctx */
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +0200756 SSL_set_SSL_CTX(ssl, container_of(node, struct sni_ctx, name)->ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +0200757 return SSL_TLSEXT_ERR_OK;
758}
759#endif /* SSL_CTRL_SET_TLSEXT_HOSTNAME */
760
Emeric Bruna4bcd9a2012-09-20 16:19:02 +0200761#ifndef OPENSSL_NO_DH
Remi Gacognef46cd6e2014-06-12 14:58:40 +0200762
763static DH * ssl_get_dh_1024(void)
764{
765#if OPENSSL_VERSION_NUMBER < 0x0090801fL
766 static const unsigned char rfc_2409_prime_1024[] = {
767 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xC9,0x0F,0xDA,0xA2,
768 0x21,0x68,0xC2,0x34,0xC4,0xC6,0x62,0x8B,0x80,0xDC,0x1C,0xD1,
769 0x29,0x02,0x4E,0x08,0x8A,0x67,0xCC,0x74,0x02,0x0B,0xBE,0xA6,
770 0x3B,0x13,0x9B,0x22,0x51,0x4A,0x08,0x79,0x8E,0x34,0x04,0xDD,
771 0xEF,0x95,0x19,0xB3,0xCD,0x3A,0x43,0x1B,0x30,0x2B,0x0A,0x6D,
772 0xF2,0x5F,0x14,0x37,0x4F,0xE1,0x35,0x6D,0x6D,0x51,0xC2,0x45,
773 0xE4,0x85,0xB5,0x76,0x62,0x5E,0x7E,0xC6,0xF4,0x4C,0x42,0xE9,
774 0xA6,0x37,0xED,0x6B,0x0B,0xFF,0x5C,0xB6,0xF4,0x06,0xB7,0xED,
775 0xEE,0x38,0x6B,0xFB,0x5A,0x89,0x9F,0xA5,0xAE,0x9F,0x24,0x11,
776 0x7C,0x4B,0x1F,0xE6,0x49,0x28,0x66,0x51,0xEC,0xE6,0x53,0x81,
777 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
778 };
779#endif
780 DH *dh = DH_new();
781 if (dh) {
782#if OPENSSL_VERSION_NUMBER >= 0x0090801fL
783 dh->p = get_rfc2409_prime_1024(NULL);
784#else
785 dh->p = BN_bin2bn(rfc_2409_prime_1024, sizeof rfc_2409_prime_1024, NULL);
786#endif
787 /* See RFC 2409, Section 6 "Oakley Groups"
788 for the reason why 2 is used as generator.
789 */
790 BN_dec2bn(&dh->g, "2");
791 if (!dh->p || !dh->g) {
792 DH_free(dh);
793 dh = NULL;
794 }
795 }
796 return dh;
797}
798
799static DH *ssl_get_dh_2048(void)
800{
801#if OPENSSL_VERSION_NUMBER < 0x0090801fL
802 static const unsigned char rfc_3526_prime_2048[] = {
803 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xC9,0x0F,0xDA,0xA2,
804 0x21,0x68,0xC2,0x34,0xC4,0xC6,0x62,0x8B,0x80,0xDC,0x1C,0xD1,
805 0x29,0x02,0x4E,0x08,0x8A,0x67,0xCC,0x74,0x02,0x0B,0xBE,0xA6,
806 0x3B,0x13,0x9B,0x22,0x51,0x4A,0x08,0x79,0x8E,0x34,0x04,0xDD,
807 0xEF,0x95,0x19,0xB3,0xCD,0x3A,0x43,0x1B,0x30,0x2B,0x0A,0x6D,
808 0xF2,0x5F,0x14,0x37,0x4F,0xE1,0x35,0x6D,0x6D,0x51,0xC2,0x45,
809 0xE4,0x85,0xB5,0x76,0x62,0x5E,0x7E,0xC6,0xF4,0x4C,0x42,0xE9,
810 0xA6,0x37,0xED,0x6B,0x0B,0xFF,0x5C,0xB6,0xF4,0x06,0xB7,0xED,
811 0xEE,0x38,0x6B,0xFB,0x5A,0x89,0x9F,0xA5,0xAE,0x9F,0x24,0x11,
812 0x7C,0x4B,0x1F,0xE6,0x49,0x28,0x66,0x51,0xEC,0xE4,0x5B,0x3D,
813 0xC2,0x00,0x7C,0xB8,0xA1,0x63,0xBF,0x05,0x98,0xDA,0x48,0x36,
814 0x1C,0x55,0xD3,0x9A,0x69,0x16,0x3F,0xA8,0xFD,0x24,0xCF,0x5F,
815 0x83,0x65,0x5D,0x23,0xDC,0xA3,0xAD,0x96,0x1C,0x62,0xF3,0x56,
816 0x20,0x85,0x52,0xBB,0x9E,0xD5,0x29,0x07,0x70,0x96,0x96,0x6D,
817 0x67,0x0C,0x35,0x4E,0x4A,0xBC,0x98,0x04,0xF1,0x74,0x6C,0x08,
818 0xCA,0x18,0x21,0x7C,0x32,0x90,0x5E,0x46,0x2E,0x36,0xCE,0x3B,
819 0xE3,0x9E,0x77,0x2C,0x18,0x0E,0x86,0x03,0x9B,0x27,0x83,0xA2,
820 0xEC,0x07,0xA2,0x8F,0xB5,0xC5,0x5D,0xF0,0x6F,0x4C,0x52,0xC9,
821 0xDE,0x2B,0xCB,0xF6,0x95,0x58,0x17,0x18,0x39,0x95,0x49,0x7C,
822 0xEA,0x95,0x6A,0xE5,0x15,0xD2,0x26,0x18,0x98,0xFA,0x05,0x10,
823 0x15,0x72,0x8E,0x5A,0x8A,0xAC,0xAA,0x68,0xFF,0xFF,0xFF,0xFF,
824 0xFF,0xFF,0xFF,0xFF,
825 };
826#endif
827 DH *dh = DH_new();
828 if (dh) {
829#if OPENSSL_VERSION_NUMBER >= 0x0090801fL
830 dh->p = get_rfc3526_prime_2048(NULL);
831#else
832 dh->p = BN_bin2bn(rfc_3526_prime_2048, sizeof rfc_3526_prime_2048, NULL);
833#endif
834 /* See RFC 3526, Section 3 "2048-bit MODP Group"
835 for the reason why 2 is used as generator.
836 */
837 BN_dec2bn(&dh->g, "2");
838 if (!dh->p || !dh->g) {
839 DH_free(dh);
840 dh = NULL;
841 }
842 }
843 return dh;
844}
845
846static DH *ssl_get_dh_4096(void)
847{
848#if OPENSSL_VERSION_NUMBER < 0x0090801fL
849 static const unsigned char rfc_3526_prime_4096[] = {
850 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xC9,0x0F,0xDA,0xA2,
851 0x21,0x68,0xC2,0x34,0xC4,0xC6,0x62,0x8B,0x80,0xDC,0x1C,0xD1,
852 0x29,0x02,0x4E,0x08,0x8A,0x67,0xCC,0x74,0x02,0x0B,0xBE,0xA6,
853 0x3B,0x13,0x9B,0x22,0x51,0x4A,0x08,0x79,0x8E,0x34,0x04,0xDD,
854 0xEF,0x95,0x19,0xB3,0xCD,0x3A,0x43,0x1B,0x30,0x2B,0x0A,0x6D,
855 0xF2,0x5F,0x14,0x37,0x4F,0xE1,0x35,0x6D,0x6D,0x51,0xC2,0x45,
856 0xE4,0x85,0xB5,0x76,0x62,0x5E,0x7E,0xC6,0xF4,0x4C,0x42,0xE9,
857 0xA6,0x37,0xED,0x6B,0x0B,0xFF,0x5C,0xB6,0xF4,0x06,0xB7,0xED,
858 0xEE,0x38,0x6B,0xFB,0x5A,0x89,0x9F,0xA5,0xAE,0x9F,0x24,0x11,
859 0x7C,0x4B,0x1F,0xE6,0x49,0x28,0x66,0x51,0xEC,0xE4,0x5B,0x3D,
860 0xC2,0x00,0x7C,0xB8,0xA1,0x63,0xBF,0x05,0x98,0xDA,0x48,0x36,
861 0x1C,0x55,0xD3,0x9A,0x69,0x16,0x3F,0xA8,0xFD,0x24,0xCF,0x5F,
862 0x83,0x65,0x5D,0x23,0xDC,0xA3,0xAD,0x96,0x1C,0x62,0xF3,0x56,
863 0x20,0x85,0x52,0xBB,0x9E,0xD5,0x29,0x07,0x70,0x96,0x96,0x6D,
864 0x67,0x0C,0x35,0x4E,0x4A,0xBC,0x98,0x04,0xF1,0x74,0x6C,0x08,
865 0xCA,0x18,0x21,0x7C,0x32,0x90,0x5E,0x46,0x2E,0x36,0xCE,0x3B,
866 0xE3,0x9E,0x77,0x2C,0x18,0x0E,0x86,0x03,0x9B,0x27,0x83,0xA2,
867 0xEC,0x07,0xA2,0x8F,0xB5,0xC5,0x5D,0xF0,0x6F,0x4C,0x52,0xC9,
868 0xDE,0x2B,0xCB,0xF6,0x95,0x58,0x17,0x18,0x39,0x95,0x49,0x7C,
869 0xEA,0x95,0x6A,0xE5,0x15,0xD2,0x26,0x18,0x98,0xFA,0x05,0x10,
870 0x15,0x72,0x8E,0x5A,0x8A,0xAA,0xC4,0x2D,0xAD,0x33,0x17,0x0D,
871 0x04,0x50,0x7A,0x33,0xA8,0x55,0x21,0xAB,0xDF,0x1C,0xBA,0x64,
872 0xEC,0xFB,0x85,0x04,0x58,0xDB,0xEF,0x0A,0x8A,0xEA,0x71,0x57,
873 0x5D,0x06,0x0C,0x7D,0xB3,0x97,0x0F,0x85,0xA6,0xE1,0xE4,0xC7,
874 0xAB,0xF5,0xAE,0x8C,0xDB,0x09,0x33,0xD7,0x1E,0x8C,0x94,0xE0,
875 0x4A,0x25,0x61,0x9D,0xCE,0xE3,0xD2,0x26,0x1A,0xD2,0xEE,0x6B,
876 0xF1,0x2F,0xFA,0x06,0xD9,0x8A,0x08,0x64,0xD8,0x76,0x02,0x73,
877 0x3E,0xC8,0x6A,0x64,0x52,0x1F,0x2B,0x18,0x17,0x7B,0x20,0x0C,
878 0xBB,0xE1,0x17,0x57,0x7A,0x61,0x5D,0x6C,0x77,0x09,0x88,0xC0,
879 0xBA,0xD9,0x46,0xE2,0x08,0xE2,0x4F,0xA0,0x74,0xE5,0xAB,0x31,
880 0x43,0xDB,0x5B,0xFC,0xE0,0xFD,0x10,0x8E,0x4B,0x82,0xD1,0x20,
881 0xA9,0x21,0x08,0x01,0x1A,0x72,0x3C,0x12,0xA7,0x87,0xE6,0xD7,
882 0x88,0x71,0x9A,0x10,0xBD,0xBA,0x5B,0x26,0x99,0xC3,0x27,0x18,
883 0x6A,0xF4,0xE2,0x3C,0x1A,0x94,0x68,0x34,0xB6,0x15,0x0B,0xDA,
884 0x25,0x83,0xE9,0xCA,0x2A,0xD4,0x4C,0xE8,0xDB,0xBB,0xC2,0xDB,
885 0x04,0xDE,0x8E,0xF9,0x2E,0x8E,0xFC,0x14,0x1F,0xBE,0xCA,0xA6,
886 0x28,0x7C,0x59,0x47,0x4E,0x6B,0xC0,0x5D,0x99,0xB2,0x96,0x4F,
887 0xA0,0x90,0xC3,0xA2,0x23,0x3B,0xA1,0x86,0x51,0x5B,0xE7,0xED,
888 0x1F,0x61,0x29,0x70,0xCE,0xE2,0xD7,0xAF,0xB8,0x1B,0xDD,0x76,
889 0x21,0x70,0x48,0x1C,0xD0,0x06,0x91,0x27,0xD5,0xB0,0x5A,0xA9,
890 0x93,0xB4,0xEA,0x98,0x8D,0x8F,0xDD,0xC1,0x86,0xFF,0xB7,0xDC,
891 0x90,0xA6,0xC0,0x8F,0x4D,0xF4,0x35,0xC9,0x34,0x06,0x31,0x99,
892 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
893 };
894#endif
895 DH *dh = DH_new();
896 if (dh) {
897#if OPENSSL_VERSION_NUMBER >= 0x0090801fL
898 dh->p = get_rfc3526_prime_4096(NULL);
899#else
900 dh->p = BN_bin2bn(rfc_3526_prime_4096, sizeof rfc_3526_prime_4096, NULL);
901#endif
902 /* See RFC 3526, Section 5 "4096-bit MODP Group"
903 for the reason why 2 is used as generator.
904 */
905 BN_dec2bn(&dh->g, "2");
906 if (!dh->p || !dh->g) {
907 DH_free(dh);
908 dh = NULL;
909 }
910 }
911 return dh;
912}
913
914static DH *ssl_get_dh_8192(void)
915{
916#if OPENSSL_VERSION_NUMBER < 0x0090801fL
917 static const unsigned char rfc_3526_prime_8192[] = {
918 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xC9,0x0F,0xDA,0xA2,
919 0x21,0x68,0xC2,0x34,0xC4,0xC6,0x62,0x8B,0x80,0xDC,0x1C,0xD1,
920 0x29,0x02,0x4E,0x08,0x8A,0x67,0xCC,0x74,0x02,0x0B,0xBE,0xA6,
921 0x3B,0x13,0x9B,0x22,0x51,0x4A,0x08,0x79,0x8E,0x34,0x04,0xDD,
922 0xEF,0x95,0x19,0xB3,0xCD,0x3A,0x43,0x1B,0x30,0x2B,0x0A,0x6D,
923 0xF2,0x5F,0x14,0x37,0x4F,0xE1,0x35,0x6D,0x6D,0x51,0xC2,0x45,
924 0xE4,0x85,0xB5,0x76,0x62,0x5E,0x7E,0xC6,0xF4,0x4C,0x42,0xE9,
925 0xA6,0x37,0xED,0x6B,0x0B,0xFF,0x5C,0xB6,0xF4,0x06,0xB7,0xED,
926 0xEE,0x38,0x6B,0xFB,0x5A,0x89,0x9F,0xA5,0xAE,0x9F,0x24,0x11,
927 0x7C,0x4B,0x1F,0xE6,0x49,0x28,0x66,0x51,0xEC,0xE4,0x5B,0x3D,
928 0xC2,0x00,0x7C,0xB8,0xA1,0x63,0xBF,0x05,0x98,0xDA,0x48,0x36,
929 0x1C,0x55,0xD3,0x9A,0x69,0x16,0x3F,0xA8,0xFD,0x24,0xCF,0x5F,
930 0x83,0x65,0x5D,0x23,0xDC,0xA3,0xAD,0x96,0x1C,0x62,0xF3,0x56,
931 0x20,0x85,0x52,0xBB,0x9E,0xD5,0x29,0x07,0x70,0x96,0x96,0x6D,
932 0x67,0x0C,0x35,0x4E,0x4A,0xBC,0x98,0x04,0xF1,0x74,0x6C,0x08,
933 0xCA,0x18,0x21,0x7C,0x32,0x90,0x5E,0x46,0x2E,0x36,0xCE,0x3B,
934 0xE3,0x9E,0x77,0x2C,0x18,0x0E,0x86,0x03,0x9B,0x27,0x83,0xA2,
935 0xEC,0x07,0xA2,0x8F,0xB5,0xC5,0x5D,0xF0,0x6F,0x4C,0x52,0xC9,
936 0xDE,0x2B,0xCB,0xF6,0x95,0x58,0x17,0x18,0x39,0x95,0x49,0x7C,
937 0xEA,0x95,0x6A,0xE5,0x15,0xD2,0x26,0x18,0x98,0xFA,0x05,0x10,
938 0x15,0x72,0x8E,0x5A,0x8A,0xAA,0xC4,0x2D,0xAD,0x33,0x17,0x0D,
939 0x04,0x50,0x7A,0x33,0xA8,0x55,0x21,0xAB,0xDF,0x1C,0xBA,0x64,
940 0xEC,0xFB,0x85,0x04,0x58,0xDB,0xEF,0x0A,0x8A,0xEA,0x71,0x57,
941 0x5D,0x06,0x0C,0x7D,0xB3,0x97,0x0F,0x85,0xA6,0xE1,0xE4,0xC7,
942 0xAB,0xF5,0xAE,0x8C,0xDB,0x09,0x33,0xD7,0x1E,0x8C,0x94,0xE0,
943 0x4A,0x25,0x61,0x9D,0xCE,0xE3,0xD2,0x26,0x1A,0xD2,0xEE,0x6B,
944 0xF1,0x2F,0xFA,0x06,0xD9,0x8A,0x08,0x64,0xD8,0x76,0x02,0x73,
945 0x3E,0xC8,0x6A,0x64,0x52,0x1F,0x2B,0x18,0x17,0x7B,0x20,0x0C,
946 0xBB,0xE1,0x17,0x57,0x7A,0x61,0x5D,0x6C,0x77,0x09,0x88,0xC0,
947 0xBA,0xD9,0x46,0xE2,0x08,0xE2,0x4F,0xA0,0x74,0xE5,0xAB,0x31,
948 0x43,0xDB,0x5B,0xFC,0xE0,0xFD,0x10,0x8E,0x4B,0x82,0xD1,0x20,
949 0xA9,0x21,0x08,0x01,0x1A,0x72,0x3C,0x12,0xA7,0x87,0xE6,0xD7,
950 0x88,0x71,0x9A,0x10,0xBD,0xBA,0x5B,0x26,0x99,0xC3,0x27,0x18,
951 0x6A,0xF4,0xE2,0x3C,0x1A,0x94,0x68,0x34,0xB6,0x15,0x0B,0xDA,
952 0x25,0x83,0xE9,0xCA,0x2A,0xD4,0x4C,0xE8,0xDB,0xBB,0xC2,0xDB,
953 0x04,0xDE,0x8E,0xF9,0x2E,0x8E,0xFC,0x14,0x1F,0xBE,0xCA,0xA6,
954 0x28,0x7C,0x59,0x47,0x4E,0x6B,0xC0,0x5D,0x99,0xB2,0x96,0x4F,
955 0xA0,0x90,0xC3,0xA2,0x23,0x3B,0xA1,0x86,0x51,0x5B,0xE7,0xED,
956 0x1F,0x61,0x29,0x70,0xCE,0xE2,0xD7,0xAF,0xB8,0x1B,0xDD,0x76,
957 0x21,0x70,0x48,0x1C,0xD0,0x06,0x91,0x27,0xD5,0xB0,0x5A,0xA9,
958 0x93,0xB4,0xEA,0x98,0x8D,0x8F,0xDD,0xC1,0x86,0xFF,0xB7,0xDC,
959 0x90,0xA6,0xC0,0x8F,0x4D,0xF4,0x35,0xC9,0x34,0x02,0x84,0x92,
960 0x36,0xC3,0xFA,0xB4,0xD2,0x7C,0x70,0x26,0xC1,0xD4,0xDC,0xB2,
961 0x60,0x26,0x46,0xDE,0xC9,0x75,0x1E,0x76,0x3D,0xBA,0x37,0xBD,
962 0xF8,0xFF,0x94,0x06,0xAD,0x9E,0x53,0x0E,0xE5,0xDB,0x38,0x2F,
963 0x41,0x30,0x01,0xAE,0xB0,0x6A,0x53,0xED,0x90,0x27,0xD8,0x31,
964 0x17,0x97,0x27,0xB0,0x86,0x5A,0x89,0x18,0xDA,0x3E,0xDB,0xEB,
965 0xCF,0x9B,0x14,0xED,0x44,0xCE,0x6C,0xBA,0xCE,0xD4,0xBB,0x1B,
966 0xDB,0x7F,0x14,0x47,0xE6,0xCC,0x25,0x4B,0x33,0x20,0x51,0x51,
967 0x2B,0xD7,0xAF,0x42,0x6F,0xB8,0xF4,0x01,0x37,0x8C,0xD2,0xBF,
968 0x59,0x83,0xCA,0x01,0xC6,0x4B,0x92,0xEC,0xF0,0x32,0xEA,0x15,
969 0xD1,0x72,0x1D,0x03,0xF4,0x82,0xD7,0xCE,0x6E,0x74,0xFE,0xF6,
970 0xD5,0x5E,0x70,0x2F,0x46,0x98,0x0C,0x82,0xB5,0xA8,0x40,0x31,
971 0x90,0x0B,0x1C,0x9E,0x59,0xE7,0xC9,0x7F,0xBE,0xC7,0xE8,0xF3,
972 0x23,0xA9,0x7A,0x7E,0x36,0xCC,0x88,0xBE,0x0F,0x1D,0x45,0xB7,
973 0xFF,0x58,0x5A,0xC5,0x4B,0xD4,0x07,0xB2,0x2B,0x41,0x54,0xAA,
974 0xCC,0x8F,0x6D,0x7E,0xBF,0x48,0xE1,0xD8,0x14,0xCC,0x5E,0xD2,
975 0x0F,0x80,0x37,0xE0,0xA7,0x97,0x15,0xEE,0xF2,0x9B,0xE3,0x28,
976 0x06,0xA1,0xD5,0x8B,0xB7,0xC5,0xDA,0x76,0xF5,0x50,0xAA,0x3D,
977 0x8A,0x1F,0xBF,0xF0,0xEB,0x19,0xCC,0xB1,0xA3,0x13,0xD5,0x5C,
978 0xDA,0x56,0xC9,0xEC,0x2E,0xF2,0x96,0x32,0x38,0x7F,0xE8,0xD7,
979 0x6E,0x3C,0x04,0x68,0x04,0x3E,0x8F,0x66,0x3F,0x48,0x60,0xEE,
980 0x12,0xBF,0x2D,0x5B,0x0B,0x74,0x74,0xD6,0xE6,0x94,0xF9,0x1E,
981 0x6D,0xBE,0x11,0x59,0x74,0xA3,0x92,0x6F,0x12,0xFE,0xE5,0xE4,
982 0x38,0x77,0x7C,0xB6,0xA9,0x32,0xDF,0x8C,0xD8,0xBE,0xC4,0xD0,
983 0x73,0xB9,0x31,0xBA,0x3B,0xC8,0x32,0xB6,0x8D,0x9D,0xD3,0x00,
984 0x74,0x1F,0xA7,0xBF,0x8A,0xFC,0x47,0xED,0x25,0x76,0xF6,0x93,
985 0x6B,0xA4,0x24,0x66,0x3A,0xAB,0x63,0x9C,0x5A,0xE4,0xF5,0x68,
986 0x34,0x23,0xB4,0x74,0x2B,0xF1,0xC9,0x78,0x23,0x8F,0x16,0xCB,
987 0xE3,0x9D,0x65,0x2D,0xE3,0xFD,0xB8,0xBE,0xFC,0x84,0x8A,0xD9,
988 0x22,0x22,0x2E,0x04,0xA4,0x03,0x7C,0x07,0x13,0xEB,0x57,0xA8,
989 0x1A,0x23,0xF0,0xC7,0x34,0x73,0xFC,0x64,0x6C,0xEA,0x30,0x6B,
990 0x4B,0xCB,0xC8,0x86,0x2F,0x83,0x85,0xDD,0xFA,0x9D,0x4B,0x7F,
991 0xA2,0xC0,0x87,0xE8,0x79,0x68,0x33,0x03,0xED,0x5B,0xDD,0x3A,
992 0x06,0x2B,0x3C,0xF5,0xB3,0xA2,0x78,0xA6,0x6D,0x2A,0x13,0xF8,
993 0x3F,0x44,0xF8,0x2D,0xDF,0x31,0x0E,0xE0,0x74,0xAB,0x6A,0x36,
994 0x45,0x97,0xE8,0x99,0xA0,0x25,0x5D,0xC1,0x64,0xF3,0x1C,0xC5,
995 0x08,0x46,0x85,0x1D,0xF9,0xAB,0x48,0x19,0x5D,0xED,0x7E,0xA1,
996 0xB1,0xD5,0x10,0xBD,0x7E,0xE7,0x4D,0x73,0xFA,0xF3,0x6B,0xC3,
997 0x1E,0xCF,0xA2,0x68,0x35,0x90,0x46,0xF4,0xEB,0x87,0x9F,0x92,
998 0x40,0x09,0x43,0x8B,0x48,0x1C,0x6C,0xD7,0x88,0x9A,0x00,0x2E,
999 0xD5,0xEE,0x38,0x2B,0xC9,0x19,0x0D,0xA6,0xFC,0x02,0x6E,0x47,
1000 0x95,0x58,0xE4,0x47,0x56,0x77,0xE9,0xAA,0x9E,0x30,0x50,0xE2,
1001 0x76,0x56,0x94,0xDF,0xC8,0x1F,0x56,0xE8,0x80,0xB9,0x6E,0x71,
1002 0x60,0xC9,0x80,0xDD,0x98,0xED,0xD3,0xDF,0xFF,0xFF,0xFF,0xFF,
1003 0xFF,0xFF,0xFF,0xFF,
1004 };
1005#endif
1006 DH *dh = DH_new();
1007 if (dh) {
1008#if OPENSSL_VERSION_NUMBER >= 0x0090801fL
1009 dh->p = get_rfc3526_prime_8192(NULL);
1010#else
1011 dh->p = BN_bin2bn(rfc_3526_prime_8192, sizeof rfc_3526_prime_8192, NULL);
1012#endif
1013 /* See RFC 3526, Section 7 "8192-bit MODP Group"
1014 for the reason why 2 is used as generator.
1015 */
1016 BN_dec2bn(&dh->g, "2");
1017 if (!dh->p || !dh->g) {
1018 DH_free(dh);
1019 dh = NULL;
1020 }
1021 }
1022 return dh;
1023}
1024
1025/* Returns Diffie-Hellman parameters matching the private key length
1026 but not exceeding global.tune.ssl_default_dh_param */
1027static DH *ssl_get_tmp_dh(SSL *ssl, int export, int keylen)
1028{
1029 DH *dh = NULL;
1030 EVP_PKEY *pkey = SSL_get_privatekey(ssl);
1031 int type = pkey ? EVP_PKEY_type(pkey->type) : EVP_PKEY_NONE;
1032
1033 /* The keylen supplied by OpenSSL can only be 512 or 1024.
1034 See ssl3_send_server_key_exchange() in ssl/s3_srvr.c
1035 */
1036 if (type == EVP_PKEY_RSA || type == EVP_PKEY_DSA) {
1037 keylen = EVP_PKEY_bits(pkey);
1038 }
1039
1040 if (keylen > global.tune.ssl_default_dh_param) {
1041 keylen = global.tune.ssl_default_dh_param;
1042 }
1043
1044 if (keylen >= 8192) {
Remi Gacogne60d7aeb2014-07-15 11:36:40 +02001045 dh = local_dh_8192;
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001046 }
1047 else if (keylen >= 4096) {
Remi Gacogne60d7aeb2014-07-15 11:36:40 +02001048 dh = local_dh_4096;
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001049 }
1050 else if (keylen >= 2048) {
Remi Gacogne60d7aeb2014-07-15 11:36:40 +02001051 dh = local_dh_2048;
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001052 }
1053 else {
Remi Gacogne60d7aeb2014-07-15 11:36:40 +02001054 dh = local_dh_1024;
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001055 }
1056
1057 return dh;
1058}
1059
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001060/* Loads Diffie-Hellman parameter from a file. Returns 1 if loaded, else -1
1061 if an error occured, and 0 if parameter not found. */
Willy Tarreau6e774b42014-04-25 21:35:23 +02001062int ssl_sock_load_dh_params(SSL_CTX *ctx, const char *file)
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001063{
1064 int ret = -1;
1065 BIO *in;
1066 DH *dh = NULL;
1067
1068 in = BIO_new(BIO_s_file());
1069 if (in == NULL)
1070 goto end;
1071
1072 if (BIO_read_filename(in, file) <= 0)
1073 goto end;
1074
1075 dh = PEM_read_bio_DHparams(in, NULL, ctx->default_passwd_callback, ctx->default_passwd_callback_userdata);
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001076 if (dh) {
1077 ret = 1;
1078 SSL_CTX_set_tmp_dh(ctx, dh);
1079 /* Setting ssl default dh param to the size of the static DH params
1080 found in the file. This way we know that there is no use
1081 complaining later about ssl-default-dh-param not being set. */
1082 global.tune.ssl_default_dh_param = DH_size(dh) * 8;
1083 }
1084 else {
Emeric Brun41fdb3c2013-04-26 11:05:44 +02001085 /* Clear openssl global errors stack */
1086 ERR_clear_error();
1087
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001088 if (global.tune.ssl_default_dh_param <= 1024) {
1089 /* we are limited to DH parameter of 1024 bits anyway */
Remi Gacogne60d7aeb2014-07-15 11:36:40 +02001090 local_dh_1024 = ssl_get_dh_1024();
1091 if (local_dh_1024 == NULL)
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001092 goto end;
Willy Tarreau6e774b42014-04-25 21:35:23 +02001093
Remi Gacogne60d7aeb2014-07-15 11:36:40 +02001094 SSL_CTX_set_tmp_dh(ctx, local_dh_1024);
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001095 }
1096 else {
1097 SSL_CTX_set_tmp_dh_callback(ctx, ssl_get_tmp_dh);
1098 }
Willy Tarreau6e774b42014-04-25 21:35:23 +02001099
Emeric Brun41fdb3c2013-04-26 11:05:44 +02001100 ret = 0; /* DH params not found */
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001101 }
Emeric Brun644cde02012-12-14 11:21:13 +01001102
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001103end:
1104 if (dh)
1105 DH_free(dh);
1106
1107 if (in)
Emeric Brun41fdb3c2013-04-26 11:05:44 +02001108 BIO_free(in);
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001109
1110 return ret;
1111}
1112#endif
1113
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001114static int ssl_sock_add_cert_sni(SSL_CTX *ctx, struct bind_conf *s, char *name, int order)
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001115{
1116 struct sni_ctx *sc;
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001117 int wild = 0, neg = 0;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001118
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001119 if (*name == '!') {
1120 neg = 1;
1121 name++;
1122 }
1123 if (*name == '*') {
1124 wild = 1;
1125 name++;
1126 }
1127 /* !* filter is a nop */
1128 if (neg && wild)
1129 return order;
1130 if (*name) {
1131 int j, len;
1132 len = strlen(name);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001133 sc = malloc(sizeof(struct sni_ctx) + len + 1);
1134 for (j = 0; j < len; j++)
1135 sc->name.key[j] = tolower(name[j]);
1136 sc->name.key[len] = 0;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001137 sc->ctx = ctx;
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001138 sc->order = order++;
1139 sc->neg = neg;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001140 if (wild)
1141 ebst_insert(&s->sni_w_ctx, &sc->name);
1142 else
1143 ebst_insert(&s->sni_ctx, &sc->name);
1144 }
1145 return order;
1146}
1147
Emeric Brunfc0421f2012-09-07 17:30:07 +02001148/* Loads a certificate key and CA chain from a file. Returns 0 on error, -1 if
1149 * an early error happens and the caller must call SSL_CTX_free() by itelf.
1150 */
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001151static int ssl_sock_load_cert_chain_file(SSL_CTX *ctx, const char *file, struct bind_conf *s, char **sni_filter, int fcount)
Emeric Brunfc0421f2012-09-07 17:30:07 +02001152{
1153 BIO *in;
1154 X509 *x = NULL, *ca;
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001155 int i, err;
Emeric Brunfc0421f2012-09-07 17:30:07 +02001156 int ret = -1;
1157 int order = 0;
1158 X509_NAME *xname;
1159 char *str;
Emeric Brunfc0421f2012-09-07 17:30:07 +02001160#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
1161 STACK_OF(GENERAL_NAME) *names;
1162#endif
1163
1164 in = BIO_new(BIO_s_file());
1165 if (in == NULL)
1166 goto end;
1167
1168 if (BIO_read_filename(in, file) <= 0)
1169 goto end;
1170
1171 x = PEM_read_bio_X509_AUX(in, NULL, ctx->default_passwd_callback, ctx->default_passwd_callback_userdata);
1172 if (x == NULL)
1173 goto end;
1174
Emeric Brun50bcecc2013-04-22 13:05:23 +02001175 if (fcount) {
1176 while (fcount--)
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001177 order = ssl_sock_add_cert_sni(ctx, s, sni_filter[fcount], order);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001178 }
1179 else {
Emeric Brunfc0421f2012-09-07 17:30:07 +02001180#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001181 names = X509_get_ext_d2i(x, NID_subject_alt_name, NULL, NULL);
1182 if (names) {
1183 for (i = 0; i < sk_GENERAL_NAME_num(names); i++) {
1184 GENERAL_NAME *name = sk_GENERAL_NAME_value(names, i);
1185 if (name->type == GEN_DNS) {
1186 if (ASN1_STRING_to_UTF8((unsigned char **)&str, name->d.dNSName) >= 0) {
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001187 order = ssl_sock_add_cert_sni(ctx, s, str, order);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001188 OPENSSL_free(str);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001189 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02001190 }
1191 }
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001192 sk_GENERAL_NAME_pop_free(names, GENERAL_NAME_free);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001193 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02001194#endif /* SSL_CTRL_SET_TLSEXT_HOSTNAME */
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001195 xname = X509_get_subject_name(x);
1196 i = -1;
1197 while ((i = X509_NAME_get_index_by_NID(xname, NID_commonName, i)) != -1) {
1198 X509_NAME_ENTRY *entry = X509_NAME_get_entry(xname, i);
1199 if (ASN1_STRING_to_UTF8((unsigned char **)&str, entry->value) >= 0) {
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001200 order = ssl_sock_add_cert_sni(ctx, s, str, order);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001201 OPENSSL_free(str);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001202 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02001203 }
1204 }
1205
1206 ret = 0; /* the caller must not free the SSL_CTX argument anymore */
1207 if (!SSL_CTX_use_certificate(ctx, x))
1208 goto end;
1209
1210 if (ctx->extra_certs != NULL) {
1211 sk_X509_pop_free(ctx->extra_certs, X509_free);
1212 ctx->extra_certs = NULL;
1213 }
1214
1215 while ((ca = PEM_read_bio_X509(in, NULL, ctx->default_passwd_callback, ctx->default_passwd_callback_userdata))) {
1216 if (!SSL_CTX_add_extra_chain_cert(ctx, ca)) {
1217 X509_free(ca);
1218 goto end;
1219 }
1220 }
1221
1222 err = ERR_get_error();
1223 if (!err || (ERR_GET_LIB(err) == ERR_LIB_PEM && ERR_GET_REASON(err) == PEM_R_NO_START_LINE)) {
1224 /* we successfully reached the last cert in the file */
1225 ret = 1;
1226 }
1227 ERR_clear_error();
1228
1229end:
1230 if (x)
1231 X509_free(x);
1232
1233 if (in)
1234 BIO_free(in);
1235
1236 return ret;
1237}
1238
Emeric Brun50bcecc2013-04-22 13:05:23 +02001239static int ssl_sock_load_cert_file(const char *path, struct bind_conf *bind_conf, struct proxy *curproxy, char **sni_filter, int fcount, char **err)
Emeric Brunfc0421f2012-09-07 17:30:07 +02001240{
1241 int ret;
1242 SSL_CTX *ctx;
1243
1244 ctx = SSL_CTX_new(SSLv23_server_method());
1245 if (!ctx) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02001246 memprintf(err, "%sunable to allocate SSL context for cert '%s'.\n",
1247 err && *err ? *err : "", path);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001248 return 1;
1249 }
1250
1251 if (SSL_CTX_use_PrivateKey_file(ctx, path, SSL_FILETYPE_PEM) <= 0) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02001252 memprintf(err, "%sunable to load SSL private key from PEM file '%s'.\n",
1253 err && *err ? *err : "", path);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001254 SSL_CTX_free(ctx);
1255 return 1;
1256 }
1257
Emeric Brun50bcecc2013-04-22 13:05:23 +02001258 ret = ssl_sock_load_cert_chain_file(ctx, path, bind_conf, sni_filter, fcount);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001259 if (ret <= 0) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02001260 memprintf(err, "%sunable to load SSL certificate from PEM file '%s'.\n",
1261 err && *err ? *err : "", path);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001262 if (ret < 0) /* serious error, must do that ourselves */
1263 SSL_CTX_free(ctx);
1264 return 1;
1265 }
Emeric Brun61694ab2012-10-26 13:35:33 +02001266
1267 if (SSL_CTX_check_private_key(ctx) <= 0) {
1268 memprintf(err, "%sinconsistencies between private key and certificate loaded from PEM file '%s'.\n",
1269 err && *err ? *err : "", path);
1270 return 1;
1271 }
1272
Emeric Brunfc0421f2012-09-07 17:30:07 +02001273 /* we must not free the SSL_CTX anymore below, since it's already in
1274 * the tree, so it will be discovered and cleaned in time.
1275 */
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001276#ifndef OPENSSL_NO_DH
1277 ret = ssl_sock_load_dh_params(ctx, path);
1278 if (ret < 0) {
1279 if (err)
1280 memprintf(err, "%sunable to load DH parameters from file '%s'.\n",
1281 *err ? *err : "", path);
1282 return 1;
1283 }
1284#endif
1285
Emeric Brun4147b2e2014-06-16 18:36:30 +02001286#ifdef SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB
1287 ret = ssl_sock_load_ocsp(ctx, path);
1288 if (ret < 0) {
1289 if (err)
1290 memprintf(err, "%s '%s.ocsp' is present and activates OCSP but it is impossible to compute the OCSP certificate ID (maybe the issuer could not be found)'.\n",
1291 *err ? *err : "", path);
1292 return 1;
1293 }
1294#endif
1295
Emeric Brunfc0421f2012-09-07 17:30:07 +02001296#ifndef SSL_CTRL_SET_TLSEXT_HOSTNAME
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001297 if (bind_conf->default_ctx) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02001298 memprintf(err, "%sthis version of openssl cannot load multiple SSL certificates.\n",
1299 err && *err ? *err : "");
Emeric Brunfc0421f2012-09-07 17:30:07 +02001300 return 1;
1301 }
1302#endif
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001303 if (!bind_conf->default_ctx)
1304 bind_conf->default_ctx = ctx;
Emeric Brunfc0421f2012-09-07 17:30:07 +02001305
1306 return 0;
1307}
1308
Willy Tarreau79eeafa2012-09-14 07:53:05 +02001309int ssl_sock_load_cert(char *path, struct bind_conf *bind_conf, struct proxy *curproxy, char **err)
Emeric Brunfc0421f2012-09-07 17:30:07 +02001310{
1311 struct dirent *de;
1312 DIR *dir;
1313 struct stat buf;
Willy Tarreauee2663b2012-12-06 11:36:59 +01001314 char *end;
1315 char fp[MAXPATHLEN+1];
Emeric Brunfc0421f2012-09-07 17:30:07 +02001316 int cfgerr = 0;
1317
1318 if (!(dir = opendir(path)))
Emeric Brun50bcecc2013-04-22 13:05:23 +02001319 return ssl_sock_load_cert_file(path, bind_conf, curproxy, NULL, 0, err);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001320
1321 /* strip trailing slashes, including first one */
1322 for (end = path + strlen(path) - 1; end >= path && *end == '/'; end--)
1323 *end = 0;
1324
Emeric Brunfc0421f2012-09-07 17:30:07 +02001325 while ((de = readdir(dir))) {
Emeric Brun2aab7222014-06-18 18:15:09 +02001326 end = strrchr(de->d_name, '.');
1327 if (end && (!strcmp(end, ".issuer") || !strcmp(end, ".ocsp")))
1328 continue;
1329
Willy Tarreauee2663b2012-12-06 11:36:59 +01001330 snprintf(fp, sizeof(fp), "%s/%s", path, de->d_name);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001331 if (stat(fp, &buf) != 0) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02001332 memprintf(err, "%sunable to stat SSL certificate from file '%s' : %s.\n",
1333 err && *err ? *err : "", fp, strerror(errno));
Emeric Brunfc0421f2012-09-07 17:30:07 +02001334 cfgerr++;
1335 continue;
1336 }
1337 if (!S_ISREG(buf.st_mode))
1338 continue;
Emeric Brun50bcecc2013-04-22 13:05:23 +02001339 cfgerr += ssl_sock_load_cert_file(fp, bind_conf, curproxy, NULL, 0, err);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001340 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02001341 closedir(dir);
1342 return cfgerr;
1343}
1344
Thierry Fournier383085f2013-01-24 14:15:43 +01001345/* Make sure openssl opens /dev/urandom before the chroot. The work is only
1346 * done once. Zero is returned if the operation fails. No error is returned
1347 * if the random is said as not implemented, because we expect that openssl
1348 * will use another method once needed.
1349 */
1350static int ssl_initialize_random()
1351{
1352 unsigned char random;
1353 static int random_initialized = 0;
1354
1355 if (!random_initialized && RAND_bytes(&random, 1) != 0)
1356 random_initialized = 1;
1357
1358 return random_initialized;
1359}
1360
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001361int ssl_sock_load_cert_list_file(char *file, struct bind_conf *bind_conf, struct proxy *curproxy, char **err)
1362{
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001363 char thisline[LINESIZE];
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001364 FILE *f;
1365 int linenum = 0;
1366 int cfgerr = 0;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001367
Willy Tarreauad1731d2013-04-02 17:35:58 +02001368 if ((f = fopen(file, "r")) == NULL) {
1369 memprintf(err, "cannot open file '%s' : %s", file, strerror(errno));
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001370 return 1;
Willy Tarreauad1731d2013-04-02 17:35:58 +02001371 }
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001372
1373 while (fgets(thisline, sizeof(thisline), f) != NULL) {
1374 int arg;
Emeric Brun50bcecc2013-04-22 13:05:23 +02001375 int newarg;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001376 char *end;
1377 char *args[MAX_LINE_ARGS + 1];
1378 char *line = thisline;
1379
1380 linenum++;
1381 end = line + strlen(line);
1382 if (end-line == sizeof(thisline)-1 && *(end-1) != '\n') {
1383 /* Check if we reached the limit and the last char is not \n.
1384 * Watch out for the last line without the terminating '\n'!
1385 */
Willy Tarreauad1731d2013-04-02 17:35:58 +02001386 memprintf(err, "line %d too long in file '%s', limit is %d characters",
1387 linenum, file, (int)sizeof(thisline)-1);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001388 cfgerr = 1;
Willy Tarreauad1731d2013-04-02 17:35:58 +02001389 break;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001390 }
1391
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001392 arg = 0;
Emeric Brun50bcecc2013-04-22 13:05:23 +02001393 newarg = 1;
1394 while (*line) {
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001395 if (*line == '#' || *line == '\n' || *line == '\r') {
1396 /* end of string, end of loop */
1397 *line = 0;
1398 break;
1399 }
1400 else if (isspace(*line)) {
Emeric Brun50bcecc2013-04-22 13:05:23 +02001401 newarg = 1;
1402 *line = 0;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001403 }
Emeric Brun50bcecc2013-04-22 13:05:23 +02001404 else if (newarg) {
1405 if (arg == MAX_LINE_ARGS) {
1406 memprintf(err, "too many args on line %d in file '%s'.",
1407 linenum, file);
1408 cfgerr = 1;
1409 break;
1410 }
1411 newarg = 0;
1412 args[arg++] = line;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001413 }
Emeric Brun50bcecc2013-04-22 13:05:23 +02001414 line++;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001415 }
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001416 if (cfgerr)
1417 break;
Willy Tarreauad1731d2013-04-02 17:35:58 +02001418
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001419 /* empty line */
Emeric Brun50bcecc2013-04-22 13:05:23 +02001420 if (!arg)
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001421 continue;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001422
Emeric Brun50bcecc2013-04-22 13:05:23 +02001423 cfgerr = ssl_sock_load_cert_file(args[0], bind_conf, curproxy, &args[1], arg-1, err);
Willy Tarreauad1731d2013-04-02 17:35:58 +02001424 if (cfgerr) {
1425 memprintf(err, "error processing line %d in file '%s' : %s", linenum, file, *err);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001426 break;
Willy Tarreauad1731d2013-04-02 17:35:58 +02001427 }
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001428 }
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001429 fclose(f);
1430 return cfgerr;
1431}
1432
Emeric Brunfc0421f2012-09-07 17:30:07 +02001433#ifndef SSL_OP_CIPHER_SERVER_PREFERENCE /* needs OpenSSL >= 0.9.7 */
1434#define SSL_OP_CIPHER_SERVER_PREFERENCE 0
1435#endif
1436
1437#ifndef SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION /* needs OpenSSL >= 0.9.7 */
1438#define SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION 0
Willy Tarreau7d588ee2012-11-26 18:47:31 +01001439#define SSL_renegotiate_pending(arg) 0
Emeric Brunfc0421f2012-09-07 17:30:07 +02001440#endif
Emeric Brun2b58d042012-09-20 17:10:03 +02001441#ifndef SSL_OP_SINGLE_ECDH_USE /* needs OpenSSL >= 0.9.8 */
1442#define SSL_OP_SINGLE_ECDH_USE 0
1443#endif
Emeric Brun2d0c4822012-10-02 13:45:20 +02001444#ifndef SSL_OP_NO_TICKET /* needs OpenSSL >= 0.9.8 */
1445#define SSL_OP_NO_TICKET 0
1446#endif
Emeric Brunfc0421f2012-09-07 17:30:07 +02001447#ifndef SSL_OP_NO_COMPRESSION /* needs OpenSSL >= 0.9.9 */
1448#define SSL_OP_NO_COMPRESSION 0
1449#endif
Emeric Brunc0ff4922012-09-28 19:37:02 +02001450#ifndef SSL_OP_NO_TLSv1_1 /* needs OpenSSL >= 1.0.1 */
1451#define SSL_OP_NO_TLSv1_1 0
1452#endif
1453#ifndef SSL_OP_NO_TLSv1_2 /* needs OpenSSL >= 1.0.1 */
1454#define SSL_OP_NO_TLSv1_2 0
1455#endif
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001456#ifndef SSL_OP_SINGLE_DH_USE /* needs OpenSSL >= 0.9.6 */
1457#define SSL_OP_SINGLE_DH_USE 0
1458#endif
Emeric Brun2b58d042012-09-20 17:10:03 +02001459#ifndef SSL_OP_SINGLE_ECDH_USE /* needs OpenSSL >= 1.0.0 */
1460#define SSL_OP_SINGLE_ECDH_USE 0
1461#endif
Emeric Brunfc0421f2012-09-07 17:30:07 +02001462#ifndef SSL_MODE_RELEASE_BUFFERS /* needs OpenSSL >= 1.0.0 */
1463#define SSL_MODE_RELEASE_BUFFERS 0
1464#endif
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001465
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001466int ssl_sock_prepare_ctx(struct bind_conf *bind_conf, SSL_CTX *ctx, struct proxy *curproxy)
Emeric Brunfc0421f2012-09-07 17:30:07 +02001467{
1468 int cfgerr = 0;
Emeric Brun850efd52014-01-29 12:24:34 +01001469 int verify = SSL_VERIFY_NONE;
Remi Gacogneaf5c3da2014-05-19 10:29:58 +02001470 long ssloptions =
Emeric Brunfc0421f2012-09-07 17:30:07 +02001471 SSL_OP_ALL | /* all known workarounds for bugs */
1472 SSL_OP_NO_SSLv2 |
1473 SSL_OP_NO_COMPRESSION |
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001474 SSL_OP_SINGLE_DH_USE |
Emeric Brun2b58d042012-09-20 17:10:03 +02001475 SSL_OP_SINGLE_ECDH_USE |
Emeric Brun3c4bc6e2012-10-04 18:44:19 +02001476 SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION |
1477 SSL_OP_CIPHER_SERVER_PREFERENCE;
Remi Gacogneaf5c3da2014-05-19 10:29:58 +02001478 long sslmode =
Emeric Brunfc0421f2012-09-07 17:30:07 +02001479 SSL_MODE_ENABLE_PARTIAL_WRITE |
1480 SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER |
1481 SSL_MODE_RELEASE_BUFFERS;
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001482 STACK_OF(SSL_CIPHER) * ciphers = NULL;
1483 SSL_CIPHER * cipher = NULL;
Remi Gacognec1eab8c2014-06-12 18:20:11 +02001484 char cipher_description[128];
1485 /* The description of ciphers using an Ephemeral Diffie Hellman key exchange
1486 contains " Kx=DH " or " Kx=DH(". Beware of " Kx=DH/",
1487 which is not ephemeral DH. */
1488 const char dhe_description[] = " Kx=DH ";
1489 const char dhe_export_description[] = " Kx=DH(";
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001490 int idx = 0;
1491 int dhe_found = 0;
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) {
1583 ciphers = ctx->cipher_list;
1584
1585 if (ciphers) {
1586 for (idx = 0; idx < sk_SSL_CIPHER_num(ciphers); idx++) {
1587 cipher = sk_SSL_CIPHER_value(ciphers, idx);
Remi Gacognec1eab8c2014-06-12 18:20:11 +02001588 if (SSL_CIPHER_description(cipher, cipher_description, sizeof (cipher_description)) == cipher_description) {
1589 if (strstr(cipher_description, dhe_description) != NULL ||
1590 strstr(cipher_description, dhe_export_description) != NULL) {
1591 dhe_found = 1;
1592 break;
1593 }
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001594 }
1595 }
1596
1597 if (dhe_found) {
1598 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");
1599 }
1600 }
1601
1602 global.tune.ssl_default_dh_param = 1024;
1603 }
Remi Gacogne60d7aeb2014-07-15 11:36:40 +02001604
1605#ifndef OPENSSL_NO_DH
1606 if (global.tune.ssl_default_dh_param >= 1024) {
1607 if (local_dh_1024 == NULL) {
1608 local_dh_1024 = ssl_get_dh_1024();
1609 }
1610 if (global.tune.ssl_default_dh_param >= 2048) {
1611 if (local_dh_2048 == NULL) {
1612 local_dh_2048 = ssl_get_dh_2048();
1613 }
1614 if (global.tune.ssl_default_dh_param >= 4096) {
1615 if (local_dh_4096 == NULL) {
1616 local_dh_4096 = ssl_get_dh_4096();
1617 }
1618 if (global.tune.ssl_default_dh_param >= 8192 &&
1619 local_dh_8192 == NULL) {
1620 local_dh_8192 = ssl_get_dh_8192();
1621 }
1622 }
1623 }
1624 }
1625#endif /* OPENSSL_NO_DH */
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001626
Emeric Brunfc0421f2012-09-07 17:30:07 +02001627 SSL_CTX_set_info_callback(ctx, ssl_sock_infocbk);
Willy Tarreau5cbe4ef2014-05-08 22:45:11 +02001628#if OPENSSL_VERSION_NUMBER >= 0x00907000L
Emeric Brun29f037d2014-04-25 19:05:36 +02001629 SSL_CTX_set_msg_callback(ctx, ssl_sock_msgcbk);
Willy Tarreau5cbe4ef2014-05-08 22:45:11 +02001630#endif
Emeric Brun29f037d2014-04-25 19:05:36 +02001631
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02001632#ifdef OPENSSL_NPN_NEGOTIATED
1633 if (bind_conf->npn_str)
1634 SSL_CTX_set_next_protos_advertised_cb(ctx, ssl_sock_advertise_npn_protos, bind_conf);
1635#endif
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01001636#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Willy Tarreauab861d32013-04-02 02:30:41 +02001637 if (bind_conf->alpn_str)
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01001638 SSL_CTX_set_alpn_select_cb(ctx, ssl_sock_advertise_alpn_protos, bind_conf);
Willy Tarreauab861d32013-04-02 02:30:41 +02001639#endif
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02001640
Emeric Brunfc0421f2012-09-07 17:30:07 +02001641#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
1642 SSL_CTX_set_tlsext_servername_callback(ctx, ssl_sock_switchctx_cbk);
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001643 SSL_CTX_set_tlsext_servername_arg(ctx, bind_conf);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001644#endif
Emeric Brun2b58d042012-09-20 17:10:03 +02001645#if defined(SSL_CTX_set_tmp_ecdh) && !defined(OPENSSL_NO_ECDH)
Emeric Brun6924ef82013-03-06 14:08:53 +01001646 {
Emeric Brun2b58d042012-09-20 17:10:03 +02001647 int i;
1648 EC_KEY *ecdh;
1649
Emeric Brun6924ef82013-03-06 14:08:53 +01001650 i = OBJ_sn2nid(bind_conf->ecdhe ? bind_conf->ecdhe : ECDHE_DEFAULT_CURVE);
Emeric Brun2b58d042012-09-20 17:10:03 +02001651 if (!i || ((ecdh = EC_KEY_new_by_curve_name(i)) == NULL)) {
1652 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 +01001653 curproxy->id, bind_conf->ecdhe ? bind_conf->ecdhe : ECDHE_DEFAULT_CURVE,
1654 bind_conf->arg, bind_conf->file, bind_conf->line);
Emeric Brun2b58d042012-09-20 17:10:03 +02001655 cfgerr++;
1656 }
1657 else {
1658 SSL_CTX_set_tmp_ecdh(ctx, ecdh);
1659 EC_KEY_free(ecdh);
1660 }
1661 }
1662#endif
1663
Emeric Brunfc0421f2012-09-07 17:30:07 +02001664 return cfgerr;
1665}
1666
Evan Broderbe554312013-06-27 00:05:25 -07001667static int ssl_sock_srv_hostcheck(const char *pattern, const char *hostname)
1668{
1669 const char *pattern_wildcard, *pattern_left_label_end, *hostname_left_label_end;
1670 size_t prefixlen, suffixlen;
1671
1672 /* Trivial case */
1673 if (strcmp(pattern, hostname) == 0)
1674 return 1;
1675
Evan Broderbe554312013-06-27 00:05:25 -07001676 /* The rest of this logic is based on RFC 6125, section 6.4.3
1677 * (http://tools.ietf.org/html/rfc6125#section-6.4.3) */
1678
Emeric Bruna848dae2013-10-08 11:27:28 +02001679 pattern_wildcard = NULL;
1680 pattern_left_label_end = pattern;
1681 while (*pattern_left_label_end != '.') {
1682 switch (*pattern_left_label_end) {
1683 case 0:
1684 /* End of label not found */
1685 return 0;
1686 case '*':
1687 /* If there is more than one wildcards */
1688 if (pattern_wildcard)
1689 return 0;
1690 pattern_wildcard = pattern_left_label_end;
1691 break;
1692 }
1693 pattern_left_label_end++;
1694 }
1695
1696 /* If it's not trivial and there is no wildcard, it can't
1697 * match */
1698 if (!pattern_wildcard)
Evan Broderbe554312013-06-27 00:05:25 -07001699 return 0;
1700
1701 /* Make sure all labels match except the leftmost */
1702 hostname_left_label_end = strchr(hostname, '.');
1703 if (!hostname_left_label_end
1704 || strcmp(pattern_left_label_end, hostname_left_label_end) != 0)
1705 return 0;
1706
1707 /* Make sure the leftmost label of the hostname is long enough
1708 * that the wildcard can match */
Emeric Brun369da852013-10-08 11:39:35 +02001709 if (hostname_left_label_end - hostname < (pattern_left_label_end - pattern) - 1)
Evan Broderbe554312013-06-27 00:05:25 -07001710 return 0;
1711
1712 /* Finally compare the string on either side of the
1713 * wildcard */
1714 prefixlen = pattern_wildcard - pattern;
1715 suffixlen = pattern_left_label_end - (pattern_wildcard + 1);
Emeric Bruna848dae2013-10-08 11:27:28 +02001716 if ((prefixlen && (memcmp(pattern, hostname, prefixlen) != 0))
1717 || (suffixlen && (memcmp(pattern_wildcard + 1, hostname_left_label_end - suffixlen, suffixlen) != 0)))
Evan Broderbe554312013-06-27 00:05:25 -07001718 return 0;
1719
1720 return 1;
1721}
1722
1723static int ssl_sock_srv_verifycbk(int ok, X509_STORE_CTX *ctx)
1724{
1725 SSL *ssl;
1726 struct connection *conn;
1727 char *servername;
1728
1729 int depth;
1730 X509 *cert;
1731 STACK_OF(GENERAL_NAME) *alt_names;
1732 int i;
1733 X509_NAME *cert_subject;
1734 char *str;
1735
1736 if (ok == 0)
1737 return ok;
1738
1739 ssl = X509_STORE_CTX_get_ex_data(ctx, SSL_get_ex_data_X509_STORE_CTX_idx());
1740 conn = (struct connection *)SSL_get_app_data(ssl);
1741
1742 servername = objt_server(conn->target)->ssl_ctx.verify_host;
1743
1744 /* We only need to verify the CN on the actual server cert,
1745 * not the indirect CAs */
1746 depth = X509_STORE_CTX_get_error_depth(ctx);
1747 if (depth != 0)
1748 return ok;
1749
1750 /* At this point, the cert is *not* OK unless we can find a
1751 * hostname match */
1752 ok = 0;
1753
1754 cert = X509_STORE_CTX_get_current_cert(ctx);
1755 /* It seems like this might happen if verify peer isn't set */
1756 if (!cert)
1757 return ok;
1758
1759 alt_names = X509_get_ext_d2i(cert, NID_subject_alt_name, NULL, NULL);
1760 if (alt_names) {
1761 for (i = 0; !ok && i < sk_GENERAL_NAME_num(alt_names); i++) {
1762 GENERAL_NAME *name = sk_GENERAL_NAME_value(alt_names, i);
1763 if (name->type == GEN_DNS) {
Emeric Bruna33410c2013-09-17 15:47:48 +02001764#if OPENSSL_VERSION_NUMBER < 0x00907000L
1765 if (ASN1_STRING_to_UTF8((unsigned char **)&str, name->d.ia5) >= 0) {
1766#else
Evan Broderbe554312013-06-27 00:05:25 -07001767 if (ASN1_STRING_to_UTF8((unsigned char **)&str, name->d.dNSName) >= 0) {
Emeric Bruna33410c2013-09-17 15:47:48 +02001768#endif
Evan Broderbe554312013-06-27 00:05:25 -07001769 ok = ssl_sock_srv_hostcheck(str, servername);
1770 OPENSSL_free(str);
1771 }
1772 }
1773 }
Emeric Brun4ad50a42013-09-17 15:19:54 +02001774 sk_GENERAL_NAME_pop_free(alt_names, GENERAL_NAME_free);
Evan Broderbe554312013-06-27 00:05:25 -07001775 }
1776
1777 cert_subject = X509_get_subject_name(cert);
1778 i = -1;
1779 while (!ok && (i = X509_NAME_get_index_by_NID(cert_subject, NID_commonName, i)) != -1) {
1780 X509_NAME_ENTRY *entry = X509_NAME_get_entry(cert_subject, i);
1781 if (ASN1_STRING_to_UTF8((unsigned char **)&str, entry->value) >= 0) {
1782 ok = ssl_sock_srv_hostcheck(str, servername);
1783 OPENSSL_free(str);
1784 }
1785 }
1786
1787 return ok;
1788}
1789
Emeric Brun94324a42012-10-11 14:00:19 +02001790/* prepare ssl context from servers options. Returns an error count */
1791int ssl_sock_prepare_srv_ctx(struct server *srv, struct proxy *curproxy)
1792{
1793 int cfgerr = 0;
Remi Gacogneaf5c3da2014-05-19 10:29:58 +02001794 long options =
Emeric Brun94324a42012-10-11 14:00:19 +02001795 SSL_OP_ALL | /* all known workarounds for bugs */
1796 SSL_OP_NO_SSLv2 |
1797 SSL_OP_NO_COMPRESSION;
Remi Gacogneaf5c3da2014-05-19 10:29:58 +02001798 long mode =
Emeric Brun94324a42012-10-11 14:00:19 +02001799 SSL_MODE_ENABLE_PARTIAL_WRITE |
1800 SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER |
1801 SSL_MODE_RELEASE_BUFFERS;
Emeric Brun850efd52014-01-29 12:24:34 +01001802 int verify = SSL_VERIFY_NONE;
Emeric Brun94324a42012-10-11 14:00:19 +02001803
Thierry Fournier383085f2013-01-24 14:15:43 +01001804 /* Make sure openssl opens /dev/urandom before the chroot */
1805 if (!ssl_initialize_random()) {
1806 Alert("OpenSSL random data generator initialization failed.\n");
1807 cfgerr++;
1808 }
1809
Emeric Brun94324a42012-10-11 14:00:19 +02001810 /* Initiate SSL context for current server */
1811 srv->ssl_ctx.reused_sess = NULL;
1812 if (srv->use_ssl)
1813 srv->xprt = &ssl_sock;
1814 if (srv->check.use_ssl)
Simon Horman66183002013-02-23 10:16:43 +09001815 srv->check_common.xprt = &ssl_sock;
Emeric Brun94324a42012-10-11 14:00:19 +02001816
1817 srv->ssl_ctx.ctx = SSL_CTX_new(SSLv23_client_method());
1818 if (!srv->ssl_ctx.ctx) {
1819 Alert("config : %s '%s', server '%s': unable to allocate ssl context.\n",
1820 proxy_type_str(curproxy), curproxy->id,
1821 srv->id);
1822 cfgerr++;
1823 return cfgerr;
1824 }
Emeric Bruna7aa3092012-10-26 12:58:00 +02001825 if (srv->ssl_ctx.client_crt) {
1826 if (SSL_CTX_use_PrivateKey_file(srv->ssl_ctx.ctx, srv->ssl_ctx.client_crt, SSL_FILETYPE_PEM) <= 0) {
1827 Alert("config : %s '%s', server '%s': unable to load SSL private key from PEM file '%s'.\n",
1828 proxy_type_str(curproxy), curproxy->id,
1829 srv->id, srv->ssl_ctx.client_crt);
1830 cfgerr++;
1831 }
1832 else if (SSL_CTX_use_certificate_chain_file(srv->ssl_ctx.ctx, srv->ssl_ctx.client_crt) <= 0) {
1833 Alert("config : %s '%s', server '%s': unable to load ssl certificate from PEM file '%s'.\n",
1834 proxy_type_str(curproxy), curproxy->id,
1835 srv->id, srv->ssl_ctx.client_crt);
1836 cfgerr++;
1837 }
1838 else if (SSL_CTX_check_private_key(srv->ssl_ctx.ctx) <= 0) {
1839 Alert("config : %s '%s', server '%s': inconsistencies between private key and certificate loaded from PEM file '%s'.\n",
1840 proxy_type_str(curproxy), curproxy->id,
1841 srv->id, srv->ssl_ctx.client_crt);
1842 cfgerr++;
1843 }
1844 }
Emeric Brun94324a42012-10-11 14:00:19 +02001845
1846 if (srv->ssl_ctx.options & SRV_SSL_O_NO_SSLV3)
1847 options |= SSL_OP_NO_SSLv3;
1848 if (srv->ssl_ctx.options & SRV_SSL_O_NO_TLSV10)
1849 options |= SSL_OP_NO_TLSv1;
1850 if (srv->ssl_ctx.options & SRV_SSL_O_NO_TLSV11)
1851 options |= SSL_OP_NO_TLSv1_1;
1852 if (srv->ssl_ctx.options & SRV_SSL_O_NO_TLSV12)
1853 options |= SSL_OP_NO_TLSv1_2;
Emeric Brunf9c5c472012-10-11 15:28:34 +02001854 if (srv->ssl_ctx.options & SRV_SSL_O_NO_TLS_TICKETS)
1855 options |= SSL_OP_NO_TICKET;
Emeric Brun94324a42012-10-11 14:00:19 +02001856 if (srv->ssl_ctx.options & SRV_SSL_O_USE_SSLV3)
1857 SSL_CTX_set_ssl_version(srv->ssl_ctx.ctx, SSLv3_client_method());
1858 if (srv->ssl_ctx.options & SRV_SSL_O_USE_TLSV10)
1859 SSL_CTX_set_ssl_version(srv->ssl_ctx.ctx, TLSv1_client_method());
1860#if SSL_OP_NO_TLSv1_1
1861 if (srv->ssl_ctx.options & SRV_SSL_O_USE_TLSV11)
1862 SSL_CTX_set_ssl_version(srv->ssl_ctx.ctx, TLSv1_1_client_method());
1863#endif
1864#if SSL_OP_NO_TLSv1_2
1865 if (srv->ssl_ctx.options & SRV_SSL_O_USE_TLSV12)
1866 SSL_CTX_set_ssl_version(srv->ssl_ctx.ctx, TLSv1_2_client_method());
1867#endif
1868
1869 SSL_CTX_set_options(srv->ssl_ctx.ctx, options);
1870 SSL_CTX_set_mode(srv->ssl_ctx.ctx, mode);
Emeric Brun850efd52014-01-29 12:24:34 +01001871
1872 if (global.ssl_server_verify == SSL_SERVER_VERIFY_REQUIRED)
1873 verify = SSL_VERIFY_PEER;
1874
1875 switch (srv->ssl_ctx.verify) {
1876 case SSL_SOCK_VERIFY_NONE:
1877 verify = SSL_VERIFY_NONE;
1878 break;
1879 case SSL_SOCK_VERIFY_REQUIRED:
1880 verify = SSL_VERIFY_PEER;
1881 break;
1882 }
Evan Broderbe554312013-06-27 00:05:25 -07001883 SSL_CTX_set_verify(srv->ssl_ctx.ctx,
Emeric Brun850efd52014-01-29 12:24:34 +01001884 verify,
Evan Broderbe554312013-06-27 00:05:25 -07001885 srv->ssl_ctx.verify_host ? ssl_sock_srv_verifycbk : NULL);
Emeric Brun850efd52014-01-29 12:24:34 +01001886 if (verify & SSL_VERIFY_PEER) {
Emeric Brunef42d922012-10-11 16:11:36 +02001887 if (srv->ssl_ctx.ca_file) {
1888 /* load CAfile to verify */
1889 if (!SSL_CTX_load_verify_locations(srv->ssl_ctx.ctx, srv->ssl_ctx.ca_file, NULL)) {
Willy Tarreau07ba08b2014-02-16 19:22:08 +01001890 Alert("Proxy '%s', server '%s' [%s:%d] unable to load CA file '%s'.\n",
Emeric Brunef42d922012-10-11 16:11:36 +02001891 curproxy->id, srv->id,
1892 srv->conf.file, srv->conf.line, srv->ssl_ctx.ca_file);
1893 cfgerr++;
1894 }
1895 }
Emeric Brun850efd52014-01-29 12:24:34 +01001896 else {
1897 if (global.ssl_server_verify == SSL_SERVER_VERIFY_REQUIRED)
Willy Tarreau07ba08b2014-02-16 19:22:08 +01001898 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 +01001899 curproxy->id, srv->id,
1900 srv->conf.file, srv->conf.line);
1901 else
Willy Tarreau07ba08b2014-02-16 19:22:08 +01001902 Alert("Proxy '%s', server '%s' [%s:%d] verify is enabled but no CA file specified.\n",
Emeric Brun850efd52014-01-29 12:24:34 +01001903 curproxy->id, srv->id,
1904 srv->conf.file, srv->conf.line);
1905 cfgerr++;
1906 }
Emeric Brunef42d922012-10-11 16:11:36 +02001907#ifdef X509_V_FLAG_CRL_CHECK
1908 if (srv->ssl_ctx.crl_file) {
1909 X509_STORE *store = SSL_CTX_get_cert_store(srv->ssl_ctx.ctx);
1910
1911 if (!store || !X509_STORE_load_locations(store, srv->ssl_ctx.crl_file, NULL)) {
Willy Tarreau07ba08b2014-02-16 19:22:08 +01001912 Alert("Proxy '%s', server '%s' [%s:%d] unable to configure CRL file '%s'.\n",
Emeric Brunef42d922012-10-11 16:11:36 +02001913 curproxy->id, srv->id,
1914 srv->conf.file, srv->conf.line, srv->ssl_ctx.crl_file);
1915 cfgerr++;
1916 }
1917 else {
1918 X509_STORE_set_flags(store, X509_V_FLAG_CRL_CHECK|X509_V_FLAG_CRL_CHECK_ALL);
1919 }
1920 }
1921#endif
1922 }
1923
Emeric Brun4f65bff2012-11-16 15:11:00 +01001924 if (global.tune.ssllifetime)
1925 SSL_CTX_set_timeout(srv->ssl_ctx.ctx, global.tune.ssllifetime);
1926
Emeric Brun94324a42012-10-11 14:00:19 +02001927 SSL_CTX_set_session_cache_mode(srv->ssl_ctx.ctx, SSL_SESS_CACHE_OFF);
1928 if (srv->ssl_ctx.ciphers &&
1929 !SSL_CTX_set_cipher_list(srv->ssl_ctx.ctx, srv->ssl_ctx.ciphers)) {
1930 Alert("Proxy '%s', server '%s' [%s:%d] : unable to set SSL cipher list to '%s'.\n",
1931 curproxy->id, srv->id,
1932 srv->conf.file, srv->conf.line, srv->ssl_ctx.ciphers);
1933 cfgerr++;
1934 }
1935
1936 return cfgerr;
1937}
1938
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001939/* Walks down the two trees in bind_conf and prepares all certs. The pointer may
Emeric Brunfc0421f2012-09-07 17:30:07 +02001940 * be NULL, in which case nothing is done. Returns the number of errors
1941 * encountered.
1942 */
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001943int ssl_sock_prepare_all_ctx(struct bind_conf *bind_conf, struct proxy *px)
Emeric Brunfc0421f2012-09-07 17:30:07 +02001944{
1945 struct ebmb_node *node;
1946 struct sni_ctx *sni;
1947 int err = 0;
1948
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001949 if (!bind_conf || !bind_conf->is_ssl)
Emeric Brunfc0421f2012-09-07 17:30:07 +02001950 return 0;
1951
Emeric Brun8068b032014-10-30 19:25:24 +01001952 if (bind_conf->default_ctx)
1953 err += ssl_sock_prepare_ctx(bind_conf, bind_conf->default_ctx, px);
1954
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001955 node = ebmb_first(&bind_conf->sni_ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001956 while (node) {
1957 sni = ebmb_entry(node, struct sni_ctx, name);
Emeric Brun8068b032014-10-30 19:25:24 +01001958 if (!sni->order && sni->ctx != bind_conf->default_ctx)
1959 /* only initialize the CTX on its first occurrence and
1960 if it is not the default_ctx */
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001961 err += ssl_sock_prepare_ctx(bind_conf, sni->ctx, px);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001962 node = ebmb_next(node);
1963 }
1964
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001965 node = ebmb_first(&bind_conf->sni_w_ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001966 while (node) {
1967 sni = ebmb_entry(node, struct sni_ctx, name);
Emeric Brun8068b032014-10-30 19:25:24 +01001968 if (!sni->order && sni->ctx != bind_conf->default_ctx)
1969 /* only initialize the CTX on its first occurrence and
1970 if it is not the default_ctx */
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 Brunb3cc4252014-10-29 19:03:26 +01002554/* Extract a cert to der, and copy it to a chunk.
2555 * Returns 1 if cert is found and copied, 0 on der convertion failure and
2556 * -1 if output is not large enough.
2557 */
2558static int
2559ssl_sock_crt2der(X509 *crt, struct chunk *out)
2560{
2561 int len;
2562 unsigned char *p = (unsigned char *)out->str;;
2563
2564 len =i2d_X509(crt, NULL);
2565 if (len <= 0)
2566 return 1;
2567
2568 if (out->size < len)
2569 return -1;
2570
2571 i2d_X509(crt,&p);
2572 out->len = len;
2573 return 1;
2574}
2575
Emeric Brunce5ad802012-10-22 14:11:22 +02002576
2577/* Copy Date in ASN1_UTCTIME format in struct chunk out.
2578 * Returns 1 if serial is found and copied, 0 if no valid time found
2579 * and -1 if output is not large enough.
2580 */
2581static int
2582ssl_sock_get_time(ASN1_TIME *tm, struct chunk *out)
2583{
2584 if (tm->type == V_ASN1_GENERALIZEDTIME) {
2585 ASN1_GENERALIZEDTIME *gentm = (ASN1_GENERALIZEDTIME *)tm;
2586
2587 if (gentm->length < 12)
2588 return 0;
2589 if (gentm->data[0] != 0x32 || gentm->data[1] != 0x30)
2590 return 0;
2591 if (out->size < gentm->length-2)
2592 return -1;
2593
2594 memcpy(out->str, gentm->data+2, gentm->length-2);
2595 out->len = gentm->length-2;
2596 return 1;
2597 }
2598 else if (tm->type == V_ASN1_UTCTIME) {
2599 ASN1_UTCTIME *utctm = (ASN1_UTCTIME *)tm;
2600
2601 if (utctm->length < 10)
2602 return 0;
2603 if (utctm->data[0] >= 0x35)
2604 return 0;
2605 if (out->size < utctm->length)
2606 return -1;
2607
2608 memcpy(out->str, utctm->data, utctm->length);
2609 out->len = utctm->length;
2610 return 1;
2611 }
2612
2613 return 0;
2614}
2615
Emeric Brun87855892012-10-17 17:39:35 +02002616/* Extract an entry from a X509_NAME and copy its value to an output chunk.
2617 * Returns 1 if entry found, 0 if entry not found, or -1 if output not large enough.
2618 */
2619static int
2620ssl_sock_get_dn_entry(X509_NAME *a, const struct chunk *entry, int pos, struct chunk *out)
2621{
2622 X509_NAME_ENTRY *ne;
2623 int i, j, n;
2624 int cur = 0;
2625 const char *s;
2626 char tmp[128];
2627
2628 out->len = 0;
2629 for (i = 0; i < sk_X509_NAME_ENTRY_num(a->entries); i++) {
2630 if (pos < 0)
2631 j = (sk_X509_NAME_ENTRY_num(a->entries)-1) - i;
2632 else
2633 j = i;
2634
2635 ne = sk_X509_NAME_ENTRY_value(a->entries, j);
2636 n = OBJ_obj2nid(ne->object);
2637 if ((n == NID_undef) || ((s = OBJ_nid2sn(n)) == NULL)) {
2638 i2t_ASN1_OBJECT(tmp, sizeof(tmp), ne->object);
2639 s = tmp;
2640 }
2641
2642 if (chunk_strcasecmp(entry, s) != 0)
2643 continue;
2644
2645 if (pos < 0)
2646 cur--;
2647 else
2648 cur++;
2649
2650 if (cur != pos)
2651 continue;
2652
2653 if (ne->value->length > out->size)
2654 return -1;
2655
2656 memcpy(out->str, ne->value->data, ne->value->length);
2657 out->len = ne->value->length;
2658 return 1;
2659 }
2660
2661 return 0;
2662
2663}
2664
2665/* Extract and format full DN from a X509_NAME and copy result into a chunk
2666 * Returns 1 if dn entries exits, 0 if no dn entry found or -1 if output is not large enough.
2667 */
2668static int
2669ssl_sock_get_dn_oneline(X509_NAME *a, struct chunk *out)
2670{
2671 X509_NAME_ENTRY *ne;
2672 int i, n, ln;
2673 int l = 0;
2674 const char *s;
2675 char *p;
2676 char tmp[128];
2677
2678 out->len = 0;
2679 p = out->str;
2680 for (i = 0; i < sk_X509_NAME_ENTRY_num(a->entries); i++) {
2681 ne = sk_X509_NAME_ENTRY_value(a->entries, i);
2682 n = OBJ_obj2nid(ne->object);
2683 if ((n == NID_undef) || ((s = OBJ_nid2sn(n)) == NULL)) {
2684 i2t_ASN1_OBJECT(tmp, sizeof(tmp), ne->object);
2685 s = tmp;
2686 }
2687 ln = strlen(s);
2688
2689 l += 1 + ln + 1 + ne->value->length;
2690 if (l > out->size)
2691 return -1;
2692 out->len = l;
2693
2694 *(p++)='/';
2695 memcpy(p, s, ln);
2696 p += ln;
2697 *(p++)='=';
2698 memcpy(p, ne->value->data, ne->value->length);
2699 p += ne->value->length;
2700 }
2701
2702 if (!out->len)
2703 return 0;
2704
2705 return 1;
2706}
2707
David Safb76832014-05-08 23:42:08 -04002708char *ssl_sock_get_version(struct connection *conn)
2709{
2710 if (!ssl_sock_is_ssl(conn))
2711 return NULL;
2712
2713 return (char *)SSL_get_version(conn->xprt_ctx);
2714}
2715
Emeric Brun49100982014-06-24 18:26:41 +02002716/* Extract peer certificate's common name into the chunk dest
2717 * Returns
2718 * the len of the extracted common name
2719 * or 0 if no CN found in DN
2720 * or -1 on error case (i.e. no peer certificate)
2721 */
2722int ssl_sock_get_remote_common_name(struct connection *conn, struct chunk *dest)
David Safb76832014-05-08 23:42:08 -04002723{
2724 X509 *crt = NULL;
2725 X509_NAME *name;
David Safb76832014-05-08 23:42:08 -04002726 const char find_cn[] = "CN";
2727 const struct chunk find_cn_chunk = {
2728 .str = (char *)&find_cn,
2729 .len = sizeof(find_cn)-1
2730 };
Emeric Brun49100982014-06-24 18:26:41 +02002731 int result = -1;
David Safb76832014-05-08 23:42:08 -04002732
2733 if (!ssl_sock_is_ssl(conn))
Emeric Brun49100982014-06-24 18:26:41 +02002734 goto out;
David Safb76832014-05-08 23:42:08 -04002735
2736 /* SSL_get_peer_certificate, it increase X509 * ref count */
2737 crt = SSL_get_peer_certificate(conn->xprt_ctx);
2738 if (!crt)
2739 goto out;
2740
2741 name = X509_get_subject_name(crt);
2742 if (!name)
2743 goto out;
David Safb76832014-05-08 23:42:08 -04002744
Emeric Brun49100982014-06-24 18:26:41 +02002745 result = ssl_sock_get_dn_entry(name, &find_cn_chunk, 1, dest);
2746out:
David Safb76832014-05-08 23:42:08 -04002747 if (crt)
2748 X509_free(crt);
2749
2750 return result;
2751}
2752
Dave McCowand6ec6052014-07-30 10:39:13 -04002753/* returns 1 if client passed a certificate for this session, 0 if not */
2754int ssl_sock_get_cert_used_sess(struct connection *conn)
2755{
2756 X509 *crt = NULL;
2757
2758 if (!ssl_sock_is_ssl(conn))
2759 return 0;
2760
2761 /* SSL_get_peer_certificate, it increase X509 * ref count */
2762 crt = SSL_get_peer_certificate(conn->xprt_ctx);
2763 if (!crt)
2764 return 0;
2765
2766 X509_free(crt);
2767 return 1;
2768}
2769
2770/* returns 1 if client passed a certificate for this connection, 0 if not */
2771int ssl_sock_get_cert_used_conn(struct connection *conn)
David Safb76832014-05-08 23:42:08 -04002772{
2773 if (!ssl_sock_is_ssl(conn))
2774 return 0;
2775
2776 return SSL_SOCK_ST_FL_VERIFY_DONE & conn->xprt_st ? 1 : 0;
2777}
2778
2779/* returns result from SSL verify */
2780unsigned int ssl_sock_get_verify_result(struct connection *conn)
2781{
2782 if (!ssl_sock_is_ssl(conn))
2783 return (unsigned int)X509_V_ERR_APPLICATION_VERIFICATION;
2784
2785 return (unsigned int)SSL_get_verify_result(conn->xprt_ctx);
2786}
2787
Willy Tarreau7875d092012-09-10 08:20:03 +02002788/***** Below are some sample fetching functions for ACL/patterns *****/
2789
Emeric Brune64aef12012-09-21 13:15:06 +02002790/* boolean, returns true if client cert was present */
2791static int
Emeric Brun2525b6b2012-10-18 15:59:43 +02002792smp_fetch_ssl_fc_has_crt(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002793 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brune64aef12012-09-21 13:15:06 +02002794{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002795 struct connection *conn;
2796
2797 if (!l4)
2798 return 0;
2799
2800 conn = objt_conn(l4->si[0].end);
2801 if (!conn || conn->xprt != &ssl_sock)
Emeric Brune64aef12012-09-21 13:15:06 +02002802 return 0;
2803
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002804 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brune64aef12012-09-21 13:15:06 +02002805 smp->flags |= SMP_F_MAY_CHANGE;
2806 return 0;
2807 }
2808
2809 smp->flags = 0;
2810 smp->type = SMP_T_BOOL;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002811 smp->data.uint = SSL_SOCK_ST_FL_VERIFY_DONE & conn->xprt_st ? 1 : 0;
Emeric Brune64aef12012-09-21 13:15:06 +02002812
2813 return 1;
2814}
2815
Emeric Brunb3cc4252014-10-29 19:03:26 +01002816/* binary, returns a certificate in a binary chunk (der/raw).
2817 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
2818 * should be use.
2819 */
2820static int
2821smp_fetch_ssl_x_der(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
2822 const struct arg *args, struct sample *smp, const char *kw)
2823{
2824 int cert_peer = (kw[4] == 'c') ? 1 : 0;
2825 X509 *crt = NULL;
2826 int ret = 0;
2827 struct chunk *smp_trash;
2828 struct connection *conn;
2829
2830 if (!l4)
2831 return 0;
2832
2833 conn = objt_conn(l4->si[0].end);
2834 if (!conn || conn->xprt != &ssl_sock)
2835 return 0;
2836
2837 if (!(conn->flags & CO_FL_CONNECTED)) {
2838 smp->flags |= SMP_F_MAY_CHANGE;
2839 return 0;
2840 }
2841
2842 if (cert_peer)
2843 crt = SSL_get_peer_certificate(conn->xprt_ctx);
2844 else
2845 crt = SSL_get_certificate(conn->xprt_ctx);
2846
2847 if (!crt)
2848 goto out;
2849
2850 smp_trash = get_trash_chunk();
2851 if (ssl_sock_crt2der(crt, smp_trash) <= 0)
2852 goto out;
2853
2854 smp->data.str = *smp_trash;
2855 smp->type = SMP_T_BIN;
2856 ret = 1;
2857out:
2858 /* SSL_get_peer_certificate, it increase X509 * ref count */
2859 if (cert_peer && crt)
2860 X509_free(crt);
2861 return ret;
2862}
2863
Emeric Brunba841a12014-04-30 17:05:08 +02002864/* binary, returns serial of certificate in a binary chunk.
2865 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
2866 * should be use.
2867 */
Willy Tarreau8d598402012-10-22 17:58:39 +02002868static int
Emeric Brunba841a12014-04-30 17:05:08 +02002869smp_fetch_ssl_x_serial(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002870 const struct arg *args, struct sample *smp, const char *kw)
Willy Tarreau8d598402012-10-22 17:58:39 +02002871{
Emeric Brunba841a12014-04-30 17:05:08 +02002872 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Willy Tarreau8d598402012-10-22 17:58:39 +02002873 X509 *crt = NULL;
2874 int ret = 0;
2875 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002876 struct connection *conn;
2877
2878 if (!l4)
2879 return 0;
Willy Tarreau8d598402012-10-22 17:58:39 +02002880
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002881 conn = objt_conn(l4->si[0].end);
2882 if (!conn || conn->xprt != &ssl_sock)
Willy Tarreau8d598402012-10-22 17:58:39 +02002883 return 0;
2884
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002885 if (!(conn->flags & CO_FL_CONNECTED)) {
Willy Tarreau8d598402012-10-22 17:58:39 +02002886 smp->flags |= SMP_F_MAY_CHANGE;
2887 return 0;
2888 }
2889
Emeric Brunba841a12014-04-30 17:05:08 +02002890 if (cert_peer)
2891 crt = SSL_get_peer_certificate(conn->xprt_ctx);
2892 else
2893 crt = SSL_get_certificate(conn->xprt_ctx);
2894
Willy Tarreau8d598402012-10-22 17:58:39 +02002895 if (!crt)
2896 goto out;
2897
Willy Tarreau47ca5452012-12-23 20:22:19 +01002898 smp_trash = get_trash_chunk();
Willy Tarreau8d598402012-10-22 17:58:39 +02002899 if (ssl_sock_get_serial(crt, smp_trash) <= 0)
2900 goto out;
2901
2902 smp->data.str = *smp_trash;
2903 smp->type = SMP_T_BIN;
2904 ret = 1;
2905out:
Emeric Brunba841a12014-04-30 17:05:08 +02002906 /* SSL_get_peer_certificate, it increase X509 * ref count */
2907 if (cert_peer && crt)
Willy Tarreau8d598402012-10-22 17:58:39 +02002908 X509_free(crt);
2909 return ret;
2910}
Emeric Brune64aef12012-09-21 13:15:06 +02002911
Emeric Brunba841a12014-04-30 17:05:08 +02002912/* binary, returns the client certificate's SHA-1 fingerprint (SHA-1 hash of DER-encoded certificate) in a binary chunk.
2913 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
2914 * should be use.
2915 */
James Votha051b4a2013-05-14 20:37:59 +02002916static int
Emeric Brunba841a12014-04-30 17:05:08 +02002917smp_fetch_ssl_x_sha1(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002918 const struct arg *args, struct sample *smp, const char *kw)
James Votha051b4a2013-05-14 20:37:59 +02002919{
Emeric Brunba841a12014-04-30 17:05:08 +02002920 int cert_peer = (kw[4] == 'c') ? 1 : 0;
James Votha051b4a2013-05-14 20:37:59 +02002921 X509 *crt = NULL;
2922 const EVP_MD *digest;
2923 int ret = 0;
2924 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002925 struct connection *conn;
James Votha051b4a2013-05-14 20:37:59 +02002926
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002927 if (!l4)
James Votha051b4a2013-05-14 20:37:59 +02002928 return 0;
2929
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002930 conn = objt_conn(l4->si[0].end);
2931 if (!conn || conn->xprt != &ssl_sock)
2932 return 0;
2933
2934 if (!(conn->flags & CO_FL_CONNECTED)) {
James Votha051b4a2013-05-14 20:37:59 +02002935 smp->flags |= SMP_F_MAY_CHANGE;
2936 return 0;
2937 }
2938
Emeric Brunba841a12014-04-30 17:05:08 +02002939 if (cert_peer)
2940 crt = SSL_get_peer_certificate(conn->xprt_ctx);
2941 else
2942 crt = SSL_get_certificate(conn->xprt_ctx);
James Votha051b4a2013-05-14 20:37:59 +02002943 if (!crt)
2944 goto out;
2945
2946 smp_trash = get_trash_chunk();
2947 digest = EVP_sha1();
2948 X509_digest(crt, digest, (unsigned char *)smp_trash->str, (unsigned int *)&smp_trash->len);
2949
2950 smp->data.str = *smp_trash;
2951 smp->type = SMP_T_BIN;
2952 ret = 1;
2953out:
Emeric Brunba841a12014-04-30 17:05:08 +02002954 /* SSL_get_peer_certificate, it increase X509 * ref count */
2955 if (cert_peer && crt)
James Votha051b4a2013-05-14 20:37:59 +02002956 X509_free(crt);
2957 return ret;
2958}
2959
Emeric Brunba841a12014-04-30 17:05:08 +02002960/* string, returns certificate's notafter date in ASN1_UTCTIME format.
2961 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
2962 * should be use.
2963 */
Emeric Brunce5ad802012-10-22 14:11:22 +02002964static int
Emeric Brunba841a12014-04-30 17:05:08 +02002965smp_fetch_ssl_x_notafter(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002966 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brunce5ad802012-10-22 14:11:22 +02002967{
Emeric Brunba841a12014-04-30 17:05:08 +02002968 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brunce5ad802012-10-22 14:11:22 +02002969 X509 *crt = NULL;
2970 int ret = 0;
2971 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002972 struct connection *conn;
Emeric Brunce5ad802012-10-22 14:11:22 +02002973
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002974 if (!l4)
Emeric Brunce5ad802012-10-22 14:11:22 +02002975 return 0;
2976
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002977 conn = objt_conn(l4->si[0].end);
2978 if (!conn || conn->xprt != &ssl_sock)
2979 return 0;
2980
2981 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunce5ad802012-10-22 14:11:22 +02002982 smp->flags |= SMP_F_MAY_CHANGE;
2983 return 0;
2984 }
2985
Emeric Brunba841a12014-04-30 17:05:08 +02002986 if (cert_peer)
2987 crt = SSL_get_peer_certificate(conn->xprt_ctx);
2988 else
2989 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brunce5ad802012-10-22 14:11:22 +02002990 if (!crt)
2991 goto out;
2992
Willy Tarreau47ca5452012-12-23 20:22:19 +01002993 smp_trash = get_trash_chunk();
Emeric Brunce5ad802012-10-22 14:11:22 +02002994 if (ssl_sock_get_time(X509_get_notAfter(crt), smp_trash) <= 0)
2995 goto out;
2996
2997 smp->data.str = *smp_trash;
2998 smp->type = SMP_T_STR;
2999 ret = 1;
3000out:
Emeric Brunba841a12014-04-30 17:05:08 +02003001 /* SSL_get_peer_certificate, it increase X509 * ref count */
3002 if (cert_peer && crt)
Emeric Brunce5ad802012-10-22 14:11:22 +02003003 X509_free(crt);
3004 return ret;
3005}
3006
Emeric Brunba841a12014-04-30 17:05:08 +02003007/* string, returns a string of a formatted full dn \C=..\O=..\OU=.. \CN=.. of certificate's issuer
3008 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
3009 * should be use.
3010 */
Emeric Brun87855892012-10-17 17:39:35 +02003011static int
Emeric Brunba841a12014-04-30 17:05:08 +02003012smp_fetch_ssl_x_i_dn(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003013 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brun87855892012-10-17 17:39:35 +02003014{
Emeric Brunba841a12014-04-30 17:05:08 +02003015 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brun87855892012-10-17 17:39:35 +02003016 X509 *crt = NULL;
3017 X509_NAME *name;
3018 int ret = 0;
3019 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003020 struct connection *conn;
Emeric Brun87855892012-10-17 17:39:35 +02003021
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003022 if (!l4)
Emeric Brun87855892012-10-17 17:39:35 +02003023 return 0;
3024
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003025 conn = objt_conn(l4->si[0].end);
3026 if (!conn || conn->xprt != &ssl_sock)
3027 return 0;
3028
3029 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun87855892012-10-17 17:39:35 +02003030 smp->flags |= SMP_F_MAY_CHANGE;
3031 return 0;
3032 }
3033
Emeric Brunba841a12014-04-30 17:05:08 +02003034 if (cert_peer)
3035 crt = SSL_get_peer_certificate(conn->xprt_ctx);
3036 else
3037 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brun87855892012-10-17 17:39:35 +02003038 if (!crt)
3039 goto out;
3040
3041 name = X509_get_issuer_name(crt);
3042 if (!name)
3043 goto out;
3044
Willy Tarreau47ca5452012-12-23 20:22:19 +01003045 smp_trash = get_trash_chunk();
Emeric Brun87855892012-10-17 17:39:35 +02003046 if (args && args[0].type == ARGT_STR) {
3047 int pos = 1;
3048
3049 if (args[1].type == ARGT_SINT)
3050 pos = args[1].data.sint;
3051 else if (args[1].type == ARGT_UINT)
3052 pos =(int)args[1].data.uint;
3053
3054 if (ssl_sock_get_dn_entry(name, &args[0].data.str, pos, smp_trash) <= 0)
3055 goto out;
3056 }
3057 else if (ssl_sock_get_dn_oneline(name, smp_trash) <= 0)
3058 goto out;
3059
3060 smp->type = SMP_T_STR;
3061 smp->data.str = *smp_trash;
3062 ret = 1;
3063out:
Emeric Brunba841a12014-04-30 17:05:08 +02003064 /* SSL_get_peer_certificate, it increase X509 * ref count */
3065 if (cert_peer && crt)
Emeric Brun87855892012-10-17 17:39:35 +02003066 X509_free(crt);
3067 return ret;
3068}
3069
Emeric Brunba841a12014-04-30 17:05:08 +02003070/* string, returns notbefore date in ASN1_UTCTIME format.
3071 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
3072 * should be use.
3073 */
Emeric Brunce5ad802012-10-22 14:11:22 +02003074static int
Emeric Brunba841a12014-04-30 17:05:08 +02003075smp_fetch_ssl_x_notbefore(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003076 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brunce5ad802012-10-22 14:11:22 +02003077{
Emeric Brunba841a12014-04-30 17:05:08 +02003078 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brunce5ad802012-10-22 14:11:22 +02003079 X509 *crt = NULL;
3080 int ret = 0;
3081 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003082 struct connection *conn;
3083
3084 if (!l4)
3085 return 0;
Emeric Brunce5ad802012-10-22 14:11:22 +02003086
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003087 conn = objt_conn(l4->si[0].end);
3088 if (!conn || conn->xprt != &ssl_sock)
Emeric Brunce5ad802012-10-22 14:11:22 +02003089 return 0;
3090
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003091 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunce5ad802012-10-22 14:11:22 +02003092 smp->flags |= SMP_F_MAY_CHANGE;
3093 return 0;
3094 }
3095
Emeric Brunba841a12014-04-30 17:05:08 +02003096 if (cert_peer)
3097 crt = SSL_get_peer_certificate(conn->xprt_ctx);
3098 else
3099 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brunce5ad802012-10-22 14:11:22 +02003100 if (!crt)
3101 goto out;
3102
Willy Tarreau47ca5452012-12-23 20:22:19 +01003103 smp_trash = get_trash_chunk();
Emeric Brunce5ad802012-10-22 14:11:22 +02003104 if (ssl_sock_get_time(X509_get_notBefore(crt), smp_trash) <= 0)
3105 goto out;
3106
3107 smp->data.str = *smp_trash;
3108 smp->type = SMP_T_STR;
3109 ret = 1;
3110out:
Emeric Brunba841a12014-04-30 17:05:08 +02003111 /* SSL_get_peer_certificate, it increase X509 * ref count */
3112 if (cert_peer && crt)
Emeric Brunce5ad802012-10-22 14:11:22 +02003113 X509_free(crt);
3114 return ret;
3115}
3116
Emeric Brunba841a12014-04-30 17:05:08 +02003117/* string, returns a string of a formatted full dn \C=..\O=..\OU=.. \CN=.. of certificate's subject
3118 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
3119 * should be use.
3120 */
Emeric Brun87855892012-10-17 17:39:35 +02003121static int
Emeric Brunba841a12014-04-30 17:05:08 +02003122smp_fetch_ssl_x_s_dn(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003123 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brun87855892012-10-17 17:39:35 +02003124{
Emeric Brunba841a12014-04-30 17:05:08 +02003125 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brun87855892012-10-17 17:39:35 +02003126 X509 *crt = NULL;
3127 X509_NAME *name;
3128 int ret = 0;
3129 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003130 struct connection *conn;
Emeric Brun87855892012-10-17 17:39:35 +02003131
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003132 if (!l4)
Emeric Brun87855892012-10-17 17:39:35 +02003133 return 0;
3134
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003135 conn = objt_conn(l4->si[0].end);
3136 if (!conn || conn->xprt != &ssl_sock)
3137 return 0;
3138
3139 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun87855892012-10-17 17:39:35 +02003140 smp->flags |= SMP_F_MAY_CHANGE;
3141 return 0;
3142 }
3143
Emeric Brunba841a12014-04-30 17:05:08 +02003144 if (cert_peer)
3145 crt = SSL_get_peer_certificate(conn->xprt_ctx);
3146 else
3147 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brun87855892012-10-17 17:39:35 +02003148 if (!crt)
3149 goto out;
3150
3151 name = X509_get_subject_name(crt);
3152 if (!name)
3153 goto out;
3154
Willy Tarreau47ca5452012-12-23 20:22:19 +01003155 smp_trash = get_trash_chunk();
Emeric Brun87855892012-10-17 17:39:35 +02003156 if (args && args[0].type == ARGT_STR) {
3157 int pos = 1;
3158
3159 if (args[1].type == ARGT_SINT)
3160 pos = args[1].data.sint;
3161 else if (args[1].type == ARGT_UINT)
3162 pos =(int)args[1].data.uint;
3163
3164 if (ssl_sock_get_dn_entry(name, &args[0].data.str, pos, smp_trash) <= 0)
3165 goto out;
3166 }
3167 else if (ssl_sock_get_dn_oneline(name, smp_trash) <= 0)
3168 goto out;
3169
3170 smp->type = SMP_T_STR;
3171 smp->data.str = *smp_trash;
3172 ret = 1;
3173out:
Emeric Brunba841a12014-04-30 17:05:08 +02003174 /* SSL_get_peer_certificate, it increase X509 * ref count */
3175 if (cert_peer && crt)
Emeric Brun87855892012-10-17 17:39:35 +02003176 X509_free(crt);
3177 return ret;
3178}
Emeric Brun9143d372012-12-20 15:44:16 +01003179
3180/* integer, returns true if current session use a client certificate */
3181static int
3182smp_fetch_ssl_c_used(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003183 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brun9143d372012-12-20 15:44:16 +01003184{
3185 X509 *crt;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003186 struct connection *conn;
Emeric Brun9143d372012-12-20 15:44:16 +01003187
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003188 if (!l4)
Emeric Brun9143d372012-12-20 15:44:16 +01003189 return 0;
3190
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003191 conn = objt_conn(l4->si[0].end);
3192 if (!conn || conn->xprt != &ssl_sock)
3193 return 0;
3194
3195 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun9143d372012-12-20 15:44:16 +01003196 smp->flags |= SMP_F_MAY_CHANGE;
3197 return 0;
3198 }
3199
3200 /* SSL_get_peer_certificate returns a ptr on allocated X509 struct */
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003201 crt = SSL_get_peer_certificate(conn->xprt_ctx);
Emeric Brun9143d372012-12-20 15:44:16 +01003202 if (crt) {
3203 X509_free(crt);
3204 }
3205
3206 smp->type = SMP_T_BOOL;
3207 smp->data.uint = (crt != NULL);
3208 return 1;
3209}
3210
Emeric Brunba841a12014-04-30 17:05:08 +02003211/* integer, returns the certificate version
3212 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
3213 * should be use.
3214 */
Emeric Bruna7359fd2012-10-17 15:03:11 +02003215static int
Emeric Brunba841a12014-04-30 17:05:08 +02003216smp_fetch_ssl_x_version(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003217 const struct arg *args, struct sample *smp, const char *kw)
Emeric Bruna7359fd2012-10-17 15:03:11 +02003218{
Emeric Brunba841a12014-04-30 17:05:08 +02003219 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Bruna7359fd2012-10-17 15:03:11 +02003220 X509 *crt;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003221 struct connection *conn;
3222
3223 if (!l4)
3224 return 0;
Emeric Bruna7359fd2012-10-17 15:03:11 +02003225
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003226 conn = objt_conn(l4->si[0].end);
3227 if (!conn || conn->xprt != &ssl_sock)
Emeric Bruna7359fd2012-10-17 15:03:11 +02003228 return 0;
3229
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003230 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Bruna7359fd2012-10-17 15:03:11 +02003231 smp->flags |= SMP_F_MAY_CHANGE;
3232 return 0;
3233 }
3234
Emeric Brunba841a12014-04-30 17:05:08 +02003235 if (cert_peer)
3236 crt = SSL_get_peer_certificate(conn->xprt_ctx);
3237 else
3238 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Bruna7359fd2012-10-17 15:03:11 +02003239 if (!crt)
3240 return 0;
3241
3242 smp->data.uint = (unsigned int)(1 + X509_get_version(crt));
Emeric Brunba841a12014-04-30 17:05:08 +02003243 /* SSL_get_peer_certificate increase X509 * ref count */
3244 if (cert_peer)
3245 X509_free(crt);
Emeric Bruna7359fd2012-10-17 15:03:11 +02003246 smp->type = SMP_T_UINT;
3247
3248 return 1;
3249}
3250
Emeric Brunba841a12014-04-30 17:05:08 +02003251/* string, returns the certificate's signature algorithm.
3252 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
3253 * should be use.
3254 */
Emeric Brun7f56e742012-10-19 18:15:40 +02003255static int
Emeric Brunba841a12014-04-30 17:05:08 +02003256smp_fetch_ssl_x_sig_alg(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003257 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brun7f56e742012-10-19 18:15:40 +02003258{
Emeric Brunba841a12014-04-30 17:05:08 +02003259 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brun7f56e742012-10-19 18:15:40 +02003260 X509 *crt;
3261 int nid;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003262 struct connection *conn;
Emeric Brun7f56e742012-10-19 18:15:40 +02003263
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003264 if (!l4)
Emeric Brun7f56e742012-10-19 18:15:40 +02003265 return 0;
3266
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003267 conn = objt_conn(l4->si[0].end);
3268 if (!conn || conn->xprt != &ssl_sock)
3269 return 0;
3270
3271 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun7f56e742012-10-19 18:15:40 +02003272 smp->flags |= SMP_F_MAY_CHANGE;
3273 return 0;
3274 }
3275
Emeric Brunba841a12014-04-30 17:05:08 +02003276 if (cert_peer)
3277 crt = SSL_get_peer_certificate(conn->xprt_ctx);
3278 else
3279 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brun7f56e742012-10-19 18:15:40 +02003280 if (!crt)
3281 return 0;
3282
3283 nid = OBJ_obj2nid((ASN1_OBJECT *)(crt->cert_info->signature->algorithm));
3284
3285 smp->data.str.str = (char *)OBJ_nid2sn(nid);
Emeric Brun9bf3ba22013-10-07 14:31:44 +02003286 if (!smp->data.str.str) {
Emeric Brunba841a12014-04-30 17:05:08 +02003287 /* SSL_get_peer_certificate increase X509 * ref count */
3288 if (cert_peer)
3289 X509_free(crt);
Emeric Brun7f56e742012-10-19 18:15:40 +02003290 return 0;
Emeric Brun9bf3ba22013-10-07 14:31:44 +02003291 }
Emeric Brun7f56e742012-10-19 18:15:40 +02003292
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01003293 smp->type = SMP_T_STR;
3294 smp->flags |= SMP_F_CONST;
Emeric Brun7f56e742012-10-19 18:15:40 +02003295 smp->data.str.len = strlen(smp->data.str.str);
Emeric Brunba841a12014-04-30 17:05:08 +02003296 /* SSL_get_peer_certificate increase X509 * ref count */
3297 if (cert_peer)
3298 X509_free(crt);
Emeric Brun7f56e742012-10-19 18:15:40 +02003299
3300 return 1;
3301}
3302
Emeric Brunba841a12014-04-30 17:05:08 +02003303/* string, returns the certificate's key algorithm.
3304 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
3305 * should be use.
3306 */
Emeric Brun521a0112012-10-22 12:22:55 +02003307static int
Emeric Brunba841a12014-04-30 17:05:08 +02003308smp_fetch_ssl_x_key_alg(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003309 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brun521a0112012-10-22 12:22:55 +02003310{
Emeric Brunba841a12014-04-30 17:05:08 +02003311 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brun521a0112012-10-22 12:22:55 +02003312 X509 *crt;
3313 int nid;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003314 struct connection *conn;
Emeric Brun521a0112012-10-22 12:22:55 +02003315
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003316 if (!l4)
Emeric Brun521a0112012-10-22 12:22:55 +02003317 return 0;
3318
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003319 conn = objt_conn(l4->si[0].end);
3320 if (!conn || conn->xprt != &ssl_sock)
3321 return 0;
3322
3323 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun521a0112012-10-22 12:22:55 +02003324 smp->flags |= SMP_F_MAY_CHANGE;
3325 return 0;
3326 }
3327
Emeric Brunba841a12014-04-30 17:05:08 +02003328 if (cert_peer)
3329 crt = SSL_get_peer_certificate(conn->xprt_ctx);
3330 else
3331 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brun521a0112012-10-22 12:22:55 +02003332 if (!crt)
3333 return 0;
3334
3335 nid = OBJ_obj2nid((ASN1_OBJECT *)(crt->cert_info->key->algor->algorithm));
3336
3337 smp->data.str.str = (char *)OBJ_nid2sn(nid);
Emeric Brun9bf3ba22013-10-07 14:31:44 +02003338 if (!smp->data.str.str) {
Emeric Brunba841a12014-04-30 17:05:08 +02003339 /* SSL_get_peer_certificate increase X509 * ref count */
3340 if (cert_peer)
3341 X509_free(crt);
Emeric Brun521a0112012-10-22 12:22:55 +02003342 return 0;
Emeric Brun9bf3ba22013-10-07 14:31:44 +02003343 }
Emeric Brun521a0112012-10-22 12:22:55 +02003344
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01003345 smp->type = SMP_T_STR;
3346 smp->flags |= SMP_F_CONST;
Emeric Brun521a0112012-10-22 12:22:55 +02003347 smp->data.str.len = strlen(smp->data.str.str);
Emeric Brunba841a12014-04-30 17:05:08 +02003348 if (cert_peer)
3349 X509_free(crt);
Emeric Brun521a0112012-10-22 12:22:55 +02003350
3351 return 1;
3352}
3353
Emeric Brun645ae792014-04-30 14:21:06 +02003354/* boolean, returns true if front conn. transport layer is SSL.
3355 * This function is also usable on backend conn if the fetch keyword 5th
3356 * char is 'b'.
3357 */
Willy Tarreau7875d092012-09-10 08:20:03 +02003358static int
Emeric Brun2525b6b2012-10-18 15:59:43 +02003359smp_fetch_ssl_fc(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003360 const struct arg *args, struct sample *smp, const char *kw)
Willy Tarreau7875d092012-09-10 08:20:03 +02003361{
Emeric Brun645ae792014-04-30 14:21:06 +02003362 int back_conn = (kw[4] == 'b') ? 1 : 0;
3363 struct connection *conn = objt_conn(l4->si[back_conn].end);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003364
Willy Tarreau7875d092012-09-10 08:20:03 +02003365 smp->type = SMP_T_BOOL;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003366 smp->data.uint = (conn && conn->xprt == &ssl_sock);
Willy Tarreau7875d092012-09-10 08:20:03 +02003367 return 1;
3368}
3369
Emeric Brun2525b6b2012-10-18 15:59:43 +02003370/* boolean, returns true if client present a SNI */
Willy Tarreau7875d092012-09-10 08:20:03 +02003371static int
Emeric Brun2525b6b2012-10-18 15:59:43 +02003372smp_fetch_ssl_fc_has_sni(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003373 const struct arg *args, struct sample *smp, const char *kw)
Willy Tarreau7875d092012-09-10 08:20:03 +02003374{
3375#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003376 struct connection *conn = objt_conn(l4->si[0].end);
3377
Willy Tarreau7875d092012-09-10 08:20:03 +02003378 smp->type = SMP_T_BOOL;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003379 smp->data.uint = (conn && conn->xprt == &ssl_sock) &&
3380 conn->xprt_ctx &&
3381 SSL_get_servername(conn->xprt_ctx, TLSEXT_NAMETYPE_host_name) != NULL;
Willy Tarreau7875d092012-09-10 08:20:03 +02003382 return 1;
3383#else
3384 return 0;
3385#endif
3386}
3387
Emeric Brun645ae792014-04-30 14:21:06 +02003388/* string, returns the used cipher if front conn. transport layer is SSL.
3389 * This function is also usable on backend conn if the fetch keyword 5th
3390 * char is 'b'.
3391 */
Emeric Brun589fcad2012-10-16 14:13:26 +02003392static int
3393smp_fetch_ssl_fc_cipher(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003394 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brun589fcad2012-10-16 14:13:26 +02003395{
Emeric Brun645ae792014-04-30 14:21:06 +02003396 int back_conn = (kw[4] == 'b') ? 1 : 0;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003397 struct connection *conn;
3398
Emeric Brun589fcad2012-10-16 14:13:26 +02003399 smp->flags = 0;
3400
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003401 if (!l4)
3402 return 0;
3403
Emeric Brun645ae792014-04-30 14:21:06 +02003404 conn = objt_conn(l4->si[back_conn].end);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003405 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
Emeric Brun589fcad2012-10-16 14:13:26 +02003406 return 0;
3407
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003408 smp->data.str.str = (char *)SSL_get_cipher_name(conn->xprt_ctx);
Emeric Brun589fcad2012-10-16 14:13:26 +02003409 if (!smp->data.str.str)
3410 return 0;
3411
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01003412 smp->type = SMP_T_STR;
3413 smp->flags |= SMP_F_CONST;
Emeric Brun589fcad2012-10-16 14:13:26 +02003414 smp->data.str.len = strlen(smp->data.str.str);
3415
3416 return 1;
3417}
3418
Emeric Brun645ae792014-04-30 14:21:06 +02003419/* integer, returns the algoritm's keysize if front conn. transport layer
3420 * is SSL.
3421 * This function is also usable on backend conn if the fetch keyword 5th
3422 * char is 'b'.
3423 */
Emeric Brun589fcad2012-10-16 14:13:26 +02003424static int
3425smp_fetch_ssl_fc_alg_keysize(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003426 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brun589fcad2012-10-16 14:13:26 +02003427{
Emeric Brun645ae792014-04-30 14:21:06 +02003428 int back_conn = (kw[4] == 'b') ? 1 : 0;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003429 struct connection *conn;
3430
Emeric Brun589fcad2012-10-16 14:13:26 +02003431 smp->flags = 0;
3432
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003433 if (!l4)
Emeric Brun589fcad2012-10-16 14:13:26 +02003434 return 0;
3435
Emeric Brun645ae792014-04-30 14:21:06 +02003436 conn = objt_conn(l4->si[back_conn].end);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003437 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
Emeric Brun589fcad2012-10-16 14:13:26 +02003438 return 0;
3439
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003440 if (!SSL_get_cipher_bits(conn->xprt_ctx, (int *)&smp->data.uint))
3441 return 0;
3442
Emeric Brun589fcad2012-10-16 14:13:26 +02003443 smp->type = SMP_T_UINT;
3444
3445 return 1;
3446}
3447
Emeric Brun645ae792014-04-30 14:21:06 +02003448/* integer, returns the used keysize if front conn. transport layer is SSL.
3449 * This function is also usable on backend conn if the fetch keyword 5th
3450 * char is 'b'.
3451 */
Emeric Brun589fcad2012-10-16 14:13:26 +02003452static int
3453smp_fetch_ssl_fc_use_keysize(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003454 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brun589fcad2012-10-16 14:13:26 +02003455{
Emeric Brun645ae792014-04-30 14:21:06 +02003456 int back_conn = (kw[4] == 'b') ? 1 : 0;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003457 struct connection *conn;
3458
Emeric Brun589fcad2012-10-16 14:13:26 +02003459 smp->flags = 0;
3460
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003461 if (!l4)
Emeric Brun589fcad2012-10-16 14:13:26 +02003462 return 0;
3463
Emeric Brun645ae792014-04-30 14:21:06 +02003464 conn = objt_conn(l4->si[back_conn].end);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003465 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
3466 return 0;
3467
3468 smp->data.uint = (unsigned int)SSL_get_cipher_bits(conn->xprt_ctx, NULL);
Emeric Brun589fcad2012-10-16 14:13:26 +02003469 if (!smp->data.uint)
3470 return 0;
3471
3472 smp->type = SMP_T_UINT;
3473
3474 return 1;
3475}
3476
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02003477#ifdef OPENSSL_NPN_NEGOTIATED
Willy Tarreau7875d092012-09-10 08:20:03 +02003478static int
Emeric Brun2525b6b2012-10-18 15:59:43 +02003479smp_fetch_ssl_fc_npn(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003480 const struct arg *args, struct sample *smp, const char *kw)
Willy Tarreaua33c6542012-10-15 13:19:06 +02003481{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003482 struct connection *conn;
3483
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01003484 smp->flags = SMP_F_CONST;
3485 smp->type = SMP_T_STR;
Willy Tarreaua33c6542012-10-15 13:19:06 +02003486
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003487 if (!l4)
Willy Tarreaua33c6542012-10-15 13:19:06 +02003488 return 0;
3489
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003490 conn = objt_conn(l4->si[0].end);
3491 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
3492 return 0;
3493
Willy Tarreaua33c6542012-10-15 13:19:06 +02003494 smp->data.str.str = NULL;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003495 SSL_get0_next_proto_negotiated(conn->xprt_ctx,
Willy Tarreaua33c6542012-10-15 13:19:06 +02003496 (const unsigned char **)&smp->data.str.str, (unsigned *)&smp->data.str.len);
3497
3498 if (!smp->data.str.str)
3499 return 0;
3500
3501 return 1;
Willy Tarreaua33c6542012-10-15 13:19:06 +02003502}
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02003503#endif
Willy Tarreaua33c6542012-10-15 13:19:06 +02003504
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01003505#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Willy Tarreauab861d32013-04-02 02:30:41 +02003506static int
3507smp_fetch_ssl_fc_alpn(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003508 const struct arg *args, struct sample *smp, const char *kw)
Willy Tarreauab861d32013-04-02 02:30:41 +02003509{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003510 struct connection *conn;
3511
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01003512 smp->flags = SMP_F_CONST;
3513 smp->type = SMP_T_STR;
Willy Tarreauab861d32013-04-02 02:30:41 +02003514
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003515 if (!l4)
3516 return 0;
3517
3518 conn = objt_conn(l4->si[0].end);
3519 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
Willy Tarreauab861d32013-04-02 02:30:41 +02003520 return 0;
3521
3522 smp->data.str.str = NULL;
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01003523 SSL_get0_alpn_selected(conn->xprt_ctx,
Willy Tarreauab861d32013-04-02 02:30:41 +02003524 (const unsigned char **)&smp->data.str.str, (unsigned *)&smp->data.str.len);
3525
3526 if (!smp->data.str.str)
3527 return 0;
3528
3529 return 1;
3530}
3531#endif
3532
Emeric Brun645ae792014-04-30 14:21:06 +02003533/* string, returns the used protocol if front conn. transport layer is SSL.
3534 * This function is also usable on backend conn if the fetch keyword 5th
3535 * char is 'b'.
3536 */
Willy Tarreaua33c6542012-10-15 13:19:06 +02003537static int
Emeric Brun589fcad2012-10-16 14:13:26 +02003538smp_fetch_ssl_fc_protocol(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003539 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brun589fcad2012-10-16 14:13:26 +02003540{
Emeric Brun645ae792014-04-30 14:21:06 +02003541 int back_conn = (kw[4] == 'b') ? 1 : 0;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003542 struct connection *conn;
3543
Emeric Brun589fcad2012-10-16 14:13:26 +02003544 smp->flags = 0;
3545
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003546 if (!l4)
Emeric Brun589fcad2012-10-16 14:13:26 +02003547 return 0;
3548
Emeric Brun645ae792014-04-30 14:21:06 +02003549 conn = objt_conn(l4->si[back_conn].end);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003550 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
3551 return 0;
3552
3553 smp->data.str.str = (char *)SSL_get_version(conn->xprt_ctx);
Emeric Brun589fcad2012-10-16 14:13:26 +02003554 if (!smp->data.str.str)
3555 return 0;
3556
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01003557 smp->type = SMP_T_STR;
3558 smp->flags = SMP_F_CONST;
Emeric Brun589fcad2012-10-16 14:13:26 +02003559 smp->data.str.len = strlen(smp->data.str.str);
3560
3561 return 1;
3562}
3563
Emeric Brun645ae792014-04-30 14:21:06 +02003564/* binary, returns the SSL session id if front conn. transport layer is SSL.
3565 * This function is also usable on backend conn if the fetch keyword 5th
3566 * char is 'b'.
3567 */
Emeric Brun589fcad2012-10-16 14:13:26 +02003568static int
Emeric Brunfe68f682012-10-16 14:59:28 +02003569smp_fetch_ssl_fc_session_id(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003570 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brunfe68f682012-10-16 14:59:28 +02003571{
3572#if OPENSSL_VERSION_NUMBER > 0x0090800fL
Emeric Brun645ae792014-04-30 14:21:06 +02003573 int back_conn = (kw[4] == 'b') ? 1 : 0;
Emeric Brunfe68f682012-10-16 14:59:28 +02003574 SSL_SESSION *sess;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003575 struct connection *conn;
Emeric Brunfe68f682012-10-16 14:59:28 +02003576
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01003577 smp->flags = SMP_F_CONST;
3578 smp->type = SMP_T_BIN;
Emeric Brunfe68f682012-10-16 14:59:28 +02003579
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003580 if (!l4)
Emeric Brunfe68f682012-10-16 14:59:28 +02003581 return 0;
3582
Emeric Brun645ae792014-04-30 14:21:06 +02003583 conn = objt_conn(l4->si[back_conn].end);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003584 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
3585 return 0;
3586
3587 sess = SSL_get_session(conn->xprt_ctx);
Emeric Brunfe68f682012-10-16 14:59:28 +02003588 if (!sess)
3589 return 0;
3590
3591 smp->data.str.str = (char *)SSL_SESSION_get_id(sess, (unsigned int *)&smp->data.str.len);
3592 if (!smp->data.str.str || !&smp->data.str.len)
3593 return 0;
3594
3595 return 1;
3596#else
3597 return 0;
3598#endif
3599}
3600
3601static int
Emeric Brun2525b6b2012-10-18 15:59:43 +02003602smp_fetch_ssl_fc_sni(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003603 const struct arg *args, struct sample *smp, const char *kw)
Willy Tarreau7875d092012-09-10 08:20:03 +02003604{
3605#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003606 struct connection *conn;
3607
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01003608 smp->flags = SMP_F_CONST;
3609 smp->type = SMP_T_STR;
Willy Tarreau7875d092012-09-10 08:20:03 +02003610
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003611 if (!l4)
Willy Tarreau7875d092012-09-10 08:20:03 +02003612 return 0;
3613
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003614 conn = objt_conn(l4->si[0].end);
3615 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
3616 return 0;
3617
3618 smp->data.str.str = (char *)SSL_get_servername(conn->xprt_ctx, TLSEXT_NAMETYPE_host_name);
Willy Tarreau3e394c92012-09-14 23:56:58 +02003619 if (!smp->data.str.str)
3620 return 0;
3621
Willy Tarreau7875d092012-09-10 08:20:03 +02003622 smp->data.str.len = strlen(smp->data.str.str);
3623 return 1;
3624#else
3625 return 0;
3626#endif
3627}
3628
David Sc1ad52e2014-04-08 18:48:47 -04003629static int
3630smp_fetch_ssl_fc_unique_id(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
3631 const struct arg *args, struct sample *smp, const char *kw)
3632{
3633#if OPENSSL_VERSION_NUMBER > 0x0090800fL
Emeric Brun645ae792014-04-30 14:21:06 +02003634 int back_conn = (kw[4] == 'b') ? 1 : 0;
David Sc1ad52e2014-04-08 18:48:47 -04003635 struct connection *conn;
3636 int finished_len;
David Sc1ad52e2014-04-08 18:48:47 -04003637 struct chunk *finished_trash;
David Sc1ad52e2014-04-08 18:48:47 -04003638
3639 smp->flags = 0;
3640
3641 if (!l4)
3642 return 0;
3643
Emeric Brun645ae792014-04-30 14:21:06 +02003644 conn = objt_conn(l4->si[back_conn].end);
David Sc1ad52e2014-04-08 18:48:47 -04003645 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
3646 return 0;
3647
3648 if (!(conn->flags & CO_FL_CONNECTED)) {
3649 smp->flags |= SMP_F_MAY_CHANGE;
3650 return 0;
3651 }
3652
3653 finished_trash = get_trash_chunk();
3654 if (!SSL_session_reused(conn->xprt_ctx))
3655 finished_len = SSL_get_peer_finished(conn->xprt_ctx, finished_trash->str, finished_trash->size);
3656 else
3657 finished_len = SSL_get_finished(conn->xprt_ctx, finished_trash->str, finished_trash->size);
3658
3659 if (!finished_len)
3660 return 0;
3661
Emeric Brunb73a9b02014-04-30 18:49:19 +02003662 finished_trash->len = finished_len;
3663 smp->data.str = *finished_trash;
3664 smp->type = SMP_T_BIN;
David Sc1ad52e2014-04-08 18:48:47 -04003665
3666 return 1;
3667#else
3668 return 0;
3669#endif
3670}
3671
Emeric Brun2525b6b2012-10-18 15:59:43 +02003672/* integer, returns the first verify error in CA chain of client certificate chain. */
Emeric Brunf282a812012-09-21 15:27:54 +02003673static int
Emeric Brun2525b6b2012-10-18 15:59:43 +02003674smp_fetch_ssl_c_ca_err(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003675 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brunf282a812012-09-21 15:27:54 +02003676{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003677 struct connection *conn;
3678
3679 if (!l4)
Emeric Brunf282a812012-09-21 15:27:54 +02003680 return 0;
3681
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003682 conn = objt_conn(l4->si[0].end);
3683 if (!conn || conn->xprt != &ssl_sock)
3684 return 0;
3685
3686 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunf282a812012-09-21 15:27:54 +02003687 smp->flags = SMP_F_MAY_CHANGE;
3688 return 0;
3689 }
3690
3691 smp->type = SMP_T_UINT;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003692 smp->data.uint = (unsigned int)SSL_SOCK_ST_TO_CA_ERROR(conn->xprt_st);
Emeric Brunf282a812012-09-21 15:27:54 +02003693 smp->flags = 0;
3694
3695 return 1;
3696}
3697
Emeric Brun2525b6b2012-10-18 15:59:43 +02003698/* integer, returns the depth of the first verify error in CA chain of client certificate chain. */
Emeric Brunf282a812012-09-21 15:27:54 +02003699static int
Emeric Brun2525b6b2012-10-18 15:59:43 +02003700smp_fetch_ssl_c_ca_err_depth(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003701 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brunf282a812012-09-21 15:27:54 +02003702{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003703 struct connection *conn;
3704
3705 if (!l4)
3706 return 0;
3707
3708 conn = objt_conn(l4->si[0].end);
3709 if (!conn || conn->xprt != &ssl_sock)
Emeric Brunf282a812012-09-21 15:27:54 +02003710 return 0;
3711
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003712 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunf282a812012-09-21 15:27:54 +02003713 smp->flags = SMP_F_MAY_CHANGE;
3714 return 0;
3715 }
3716
3717 smp->type = SMP_T_UINT;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003718 smp->data.uint = (unsigned int)SSL_SOCK_ST_TO_CAEDEPTH(conn->xprt_st);
Emeric Brunf282a812012-09-21 15:27:54 +02003719 smp->flags = 0;
3720
3721 return 1;
3722}
3723
Emeric Brun2525b6b2012-10-18 15:59:43 +02003724/* integer, returns the first verify error on client certificate */
Emeric Brunf282a812012-09-21 15:27:54 +02003725static int
Emeric Brun2525b6b2012-10-18 15:59:43 +02003726smp_fetch_ssl_c_err(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003727 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brunf282a812012-09-21 15:27:54 +02003728{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003729 struct connection *conn;
3730
3731 if (!l4)
Emeric Brunf282a812012-09-21 15:27:54 +02003732 return 0;
3733
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003734 conn = objt_conn(l4->si[0].end);
3735 if (!conn || conn->xprt != &ssl_sock)
3736 return 0;
3737
3738 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunf282a812012-09-21 15:27:54 +02003739 smp->flags = SMP_F_MAY_CHANGE;
3740 return 0;
3741 }
3742
3743 smp->type = SMP_T_UINT;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003744 smp->data.uint = (unsigned int)SSL_SOCK_ST_TO_CRTERROR(conn->xprt_st);
Emeric Brunf282a812012-09-21 15:27:54 +02003745 smp->flags = 0;
3746
3747 return 1;
3748}
3749
Emeric Brun2525b6b2012-10-18 15:59:43 +02003750/* integer, returns the verify result on client cert */
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02003751static int
Emeric Brun2525b6b2012-10-18 15:59:43 +02003752smp_fetch_ssl_c_verify(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003753 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02003754{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003755 struct connection *conn;
3756
3757 if (!l4)
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02003758 return 0;
3759
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003760 conn = objt_conn(l4->si[0].end);
3761 if (!conn || conn->xprt != &ssl_sock)
3762 return 0;
3763
3764 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02003765 smp->flags = SMP_F_MAY_CHANGE;
3766 return 0;
3767 }
3768
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003769 if (!conn->xprt_ctx)
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02003770 return 0;
3771
3772 smp->type = SMP_T_UINT;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003773 smp->data.uint = (unsigned int)SSL_get_verify_result(conn->xprt_ctx);
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02003774 smp->flags = 0;
3775
3776 return 1;
3777}
3778
Emeric Brunfb510ea2012-10-05 12:00:26 +02003779/* parse the "ca-file" bind keyword */
3780static 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 +02003781{
3782 if (!*args[cur_arg + 1]) {
3783 if (err)
3784 memprintf(err, "'%s' : missing CAfile path", args[cur_arg]);
3785 return ERR_ALERT | ERR_FATAL;
3786 }
3787
Emeric Brunef42d922012-10-11 16:11:36 +02003788 if ((*args[cur_arg + 1] != '/') && global.ca_base)
3789 memprintf(&conf->ca_file, "%s/%s", global.ca_base, args[cur_arg + 1]);
3790 else
3791 memprintf(&conf->ca_file, "%s", args[cur_arg + 1]);
Emeric Brunc8e8d122012-10-02 18:42:10 +02003792
Emeric Brund94b3fe2012-09-20 18:23:56 +02003793 return 0;
3794}
3795
Willy Tarreau79eeafa2012-09-14 07:53:05 +02003796/* parse the "ciphers" bind keyword */
Willy Tarreau4348fad2012-09-20 16:48:07 +02003797static 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 +02003798{
3799 if (!*args[cur_arg + 1]) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02003800 memprintf(err, "'%s' : missing cipher suite", args[cur_arg]);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02003801 return ERR_ALERT | ERR_FATAL;
3802 }
3803
Emeric Brun76d88952012-10-05 15:47:31 +02003804 free(conf->ciphers);
Willy Tarreau4348fad2012-09-20 16:48:07 +02003805 conf->ciphers = strdup(args[cur_arg + 1]);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02003806 return 0;
3807}
3808
3809/* parse the "crt" bind keyword */
Willy Tarreau4348fad2012-09-20 16:48:07 +02003810static 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 +02003811{
Willy Tarreau38011032013-08-13 16:59:39 +02003812 char path[MAXPATHLEN];
Willy Tarreaub75d6922014-04-14 18:05:41 +02003813
Willy Tarreau79eeafa2012-09-14 07:53:05 +02003814 if (!*args[cur_arg + 1]) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02003815 memprintf(err, "'%s' : missing certificate location", args[cur_arg]);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02003816 return ERR_ALERT | ERR_FATAL;
3817 }
3818
Emeric Brunc8e8d122012-10-02 18:42:10 +02003819 if ((*args[cur_arg + 1] != '/' ) && global.crt_base) {
Willy Tarreau38011032013-08-13 16:59:39 +02003820 if ((strlen(global.crt_base) + 1 + strlen(args[cur_arg + 1]) + 1) > MAXPATHLEN) {
Emeric Brunc8e8d122012-10-02 18:42:10 +02003821 memprintf(err, "'%s' : path too long", args[cur_arg]);
3822 return ERR_ALERT | ERR_FATAL;
3823 }
Willy Tarreaub75d6922014-04-14 18:05:41 +02003824 snprintf(path, sizeof(path), "%s/%s", global.crt_base, args[cur_arg + 1]);
Emeric Brunc8e8d122012-10-02 18:42:10 +02003825 if (ssl_sock_load_cert(path, conf, px, err) > 0)
3826 return ERR_ALERT | ERR_FATAL;
3827
3828 return 0;
3829 }
3830
Willy Tarreau4348fad2012-09-20 16:48:07 +02003831 if (ssl_sock_load_cert(args[cur_arg + 1], conf, px, err) > 0)
Willy Tarreau79eeafa2012-09-14 07:53:05 +02003832 return ERR_ALERT | ERR_FATAL;
Emeric Brund94b3fe2012-09-20 18:23:56 +02003833
3834 return 0;
3835}
3836
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01003837/* parse the "crt-list" bind keyword */
3838static int bind_parse_crt_list(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
3839{
3840 if (!*args[cur_arg + 1]) {
3841 memprintf(err, "'%s' : missing certificate location", args[cur_arg]);
3842 return ERR_ALERT | ERR_FATAL;
3843 }
3844
Willy Tarreauad1731d2013-04-02 17:35:58 +02003845 if (ssl_sock_load_cert_list_file(args[cur_arg + 1], conf, px, err) > 0) {
3846 memprintf(err, "'%s' : %s", args[cur_arg], *err);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01003847 return ERR_ALERT | ERR_FATAL;
Willy Tarreauad1731d2013-04-02 17:35:58 +02003848 }
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01003849
3850 return 0;
3851}
3852
Emeric Brunfb510ea2012-10-05 12:00:26 +02003853/* parse the "crl-file" bind keyword */
3854static 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 +02003855{
Emeric Brun051cdab2012-10-02 19:25:50 +02003856#ifndef X509_V_FLAG_CRL_CHECK
3857 if (err)
3858 memprintf(err, "'%s' : library does not support CRL verify", args[cur_arg]);
3859 return ERR_ALERT | ERR_FATAL;
3860#else
Emeric Brund94b3fe2012-09-20 18:23:56 +02003861 if (!*args[cur_arg + 1]) {
3862 if (err)
3863 memprintf(err, "'%s' : missing CRLfile path", args[cur_arg]);
3864 return ERR_ALERT | ERR_FATAL;
3865 }
Emeric Brun2b58d042012-09-20 17:10:03 +02003866
Emeric Brunef42d922012-10-11 16:11:36 +02003867 if ((*args[cur_arg + 1] != '/') && global.ca_base)
3868 memprintf(&conf->crl_file, "%s/%s", global.ca_base, args[cur_arg + 1]);
3869 else
3870 memprintf(&conf->crl_file, "%s", args[cur_arg + 1]);
Emeric Brunc8e8d122012-10-02 18:42:10 +02003871
Emeric Brun2b58d042012-09-20 17:10:03 +02003872 return 0;
Emeric Brun051cdab2012-10-02 19:25:50 +02003873#endif
Emeric Brun2b58d042012-09-20 17:10:03 +02003874}
3875
3876/* parse the "ecdhe" bind keyword keywords */
3877static int bind_parse_ecdhe(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
3878{
3879#if OPENSSL_VERSION_NUMBER < 0x0090800fL
3880 if (err)
3881 memprintf(err, "'%s' : library does not support elliptic curve Diffie-Hellman (too old)", args[cur_arg]);
3882 return ERR_ALERT | ERR_FATAL;
3883#elif defined(OPENSSL_NO_ECDH)
3884 if (err)
3885 memprintf(err, "'%s' : library does not support elliptic curve Diffie-Hellman (disabled via OPENSSL_NO_ECDH)", args[cur_arg]);
3886 return ERR_ALERT | ERR_FATAL;
3887#else
3888 if (!*args[cur_arg + 1]) {
3889 if (err)
3890 memprintf(err, "'%s' : missing named curve", args[cur_arg]);
3891 return ERR_ALERT | ERR_FATAL;
3892 }
3893
3894 conf->ecdhe = strdup(args[cur_arg + 1]);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02003895
3896 return 0;
Emeric Brun2b58d042012-09-20 17:10:03 +02003897#endif
Willy Tarreau79eeafa2012-09-14 07:53:05 +02003898}
3899
Emeric Brun81c00f02012-09-21 14:31:21 +02003900/* parse the "crt_ignerr" and "ca_ignerr" bind keywords */
3901static int bind_parse_ignore_err(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
3902{
3903 int code;
3904 char *p = args[cur_arg + 1];
3905 unsigned long long *ignerr = &conf->crt_ignerr;
3906
3907 if (!*p) {
3908 if (err)
3909 memprintf(err, "'%s' : missing error IDs list", args[cur_arg]);
3910 return ERR_ALERT | ERR_FATAL;
3911 }
3912
3913 if (strcmp(args[cur_arg], "ca-ignore-err") == 0)
3914 ignerr = &conf->ca_ignerr;
3915
3916 if (strcmp(p, "all") == 0) {
3917 *ignerr = ~0ULL;
3918 return 0;
3919 }
3920
3921 while (p) {
3922 code = atoi(p);
3923 if ((code <= 0) || (code > 63)) {
3924 if (err)
3925 memprintf(err, "'%s' : ID '%d' out of range (1..63) in error IDs list '%s'",
3926 args[cur_arg], code, args[cur_arg + 1]);
3927 return ERR_ALERT | ERR_FATAL;
3928 }
3929 *ignerr |= 1ULL << code;
3930 p = strchr(p, ',');
3931 if (p)
3932 p++;
3933 }
3934
Emeric Brun2cb7ae52012-10-05 14:14:21 +02003935 return 0;
3936}
3937
3938/* parse the "force-sslv3" bind keyword */
3939static int bind_parse_force_sslv3(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
3940{
3941 conf->ssl_options |= BC_SSL_O_USE_SSLV3;
3942 return 0;
3943}
3944
3945/* parse the "force-tlsv10" bind keyword */
3946static int bind_parse_force_tlsv10(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
3947{
3948 conf->ssl_options |= BC_SSL_O_USE_TLSV10;
Emeric Brun2d0c4822012-10-02 13:45:20 +02003949 return 0;
3950}
3951
Emeric Brun2cb7ae52012-10-05 14:14:21 +02003952/* parse the "force-tlsv11" bind keyword */
3953static int bind_parse_force_tlsv11(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
3954{
3955#if SSL_OP_NO_TLSv1_1
3956 conf->ssl_options |= BC_SSL_O_USE_TLSV11;
3957 return 0;
3958#else
3959 if (err)
3960 memprintf(err, "'%s' : library does not support protocol TLSv1.1", args[cur_arg]);
3961 return ERR_ALERT | ERR_FATAL;
3962#endif
3963}
3964
3965/* parse the "force-tlsv12" bind keyword */
3966static int bind_parse_force_tlsv12(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
3967{
3968#if SSL_OP_NO_TLSv1_2
3969 conf->ssl_options |= BC_SSL_O_USE_TLSV12;
3970 return 0;
3971#else
3972 if (err)
3973 memprintf(err, "'%s' : library does not support protocol TLSv1.2", args[cur_arg]);
3974 return ERR_ALERT | ERR_FATAL;
3975#endif
3976}
3977
3978
Emeric Brun2d0c4822012-10-02 13:45:20 +02003979/* parse the "no-tls-tickets" bind keyword */
3980static int bind_parse_no_tls_tickets(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
3981{
Emeric Brun89675492012-10-05 13:48:26 +02003982 conf->ssl_options |= BC_SSL_O_NO_TLS_TICKETS;
Emeric Brun81c00f02012-09-21 14:31:21 +02003983 return 0;
3984}
3985
Emeric Brun2d0c4822012-10-02 13:45:20 +02003986
Emeric Brun9b3009b2012-10-05 11:55:06 +02003987/* parse the "no-sslv3" bind keyword */
3988static 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 +02003989{
Emeric Brun89675492012-10-05 13:48:26 +02003990 conf->ssl_options |= BC_SSL_O_NO_SSLV3;
Willy Tarreau79eeafa2012-09-14 07:53:05 +02003991 return 0;
3992}
3993
Emeric Brun9b3009b2012-10-05 11:55:06 +02003994/* parse the "no-tlsv10" bind keyword */
3995static 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 +02003996{
Emeric Brun89675492012-10-05 13:48:26 +02003997 conf->ssl_options |= BC_SSL_O_NO_TLSV10;
Emeric Brunc0ff4922012-09-28 19:37:02 +02003998 return 0;
3999}
4000
Emeric Brun9b3009b2012-10-05 11:55:06 +02004001/* parse the "no-tlsv11" bind keyword */
4002static 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 +02004003{
Emeric Brun89675492012-10-05 13:48:26 +02004004 conf->ssl_options |= BC_SSL_O_NO_TLSV11;
Emeric Brunc0ff4922012-09-28 19:37:02 +02004005 return 0;
4006}
4007
Emeric Brun9b3009b2012-10-05 11:55:06 +02004008/* parse the "no-tlsv12" bind keyword */
4009static 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 +02004010{
Emeric Brun89675492012-10-05 13:48:26 +02004011 conf->ssl_options |= BC_SSL_O_NO_TLSV12;
Willy Tarreau79eeafa2012-09-14 07:53:05 +02004012 return 0;
4013}
4014
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02004015/* parse the "npn" bind keyword */
4016static int bind_parse_npn(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
4017{
4018#ifdef OPENSSL_NPN_NEGOTIATED
4019 char *p1, *p2;
4020
4021 if (!*args[cur_arg + 1]) {
4022 memprintf(err, "'%s' : missing the comma-delimited NPN protocol suite", args[cur_arg]);
4023 return ERR_ALERT | ERR_FATAL;
4024 }
4025
4026 free(conf->npn_str);
4027
4028 /* the NPN string is built as a suite of (<len> <name>)* */
4029 conf->npn_len = strlen(args[cur_arg + 1]) + 1;
4030 conf->npn_str = calloc(1, conf->npn_len);
4031 memcpy(conf->npn_str + 1, args[cur_arg + 1], conf->npn_len);
4032
4033 /* replace commas with the name length */
4034 p1 = conf->npn_str;
4035 p2 = p1 + 1;
4036 while (1) {
4037 p2 = memchr(p1 + 1, ',', conf->npn_str + conf->npn_len - (p1 + 1));
4038 if (!p2)
4039 p2 = p1 + 1 + strlen(p1 + 1);
4040
4041 if (p2 - (p1 + 1) > 255) {
4042 *p2 = '\0';
4043 memprintf(err, "'%s' : NPN protocol name too long : '%s'", args[cur_arg], p1 + 1);
4044 return ERR_ALERT | ERR_FATAL;
4045 }
4046
4047 *p1 = p2 - (p1 + 1);
4048 p1 = p2;
4049
4050 if (!*p2)
4051 break;
4052
4053 *(p2++) = '\0';
4054 }
4055 return 0;
4056#else
4057 if (err)
4058 memprintf(err, "'%s' : library does not support TLS NPN extension", args[cur_arg]);
4059 return ERR_ALERT | ERR_FATAL;
4060#endif
4061}
4062
Willy Tarreauab861d32013-04-02 02:30:41 +02004063/* parse the "alpn" bind keyword */
4064static int bind_parse_alpn(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
4065{
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01004066#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Willy Tarreauab861d32013-04-02 02:30:41 +02004067 char *p1, *p2;
4068
4069 if (!*args[cur_arg + 1]) {
4070 memprintf(err, "'%s' : missing the comma-delimited ALPN protocol suite", args[cur_arg]);
4071 return ERR_ALERT | ERR_FATAL;
4072 }
4073
4074 free(conf->alpn_str);
4075
4076 /* the ALPN string is built as a suite of (<len> <name>)* */
4077 conf->alpn_len = strlen(args[cur_arg + 1]) + 1;
4078 conf->alpn_str = calloc(1, conf->alpn_len);
4079 memcpy(conf->alpn_str + 1, args[cur_arg + 1], conf->alpn_len);
4080
4081 /* replace commas with the name length */
4082 p1 = conf->alpn_str;
4083 p2 = p1 + 1;
4084 while (1) {
4085 p2 = memchr(p1 + 1, ',', conf->alpn_str + conf->alpn_len - (p1 + 1));
4086 if (!p2)
4087 p2 = p1 + 1 + strlen(p1 + 1);
4088
4089 if (p2 - (p1 + 1) > 255) {
4090 *p2 = '\0';
4091 memprintf(err, "'%s' : ALPN protocol name too long : '%s'", args[cur_arg], p1 + 1);
4092 return ERR_ALERT | ERR_FATAL;
4093 }
4094
4095 *p1 = p2 - (p1 + 1);
4096 p1 = p2;
4097
4098 if (!*p2)
4099 break;
4100
4101 *(p2++) = '\0';
4102 }
4103 return 0;
4104#else
4105 if (err)
4106 memprintf(err, "'%s' : library does not support TLS ALPN extension", args[cur_arg]);
4107 return ERR_ALERT | ERR_FATAL;
4108#endif
4109}
4110
Willy Tarreau79eeafa2012-09-14 07:53:05 +02004111/* parse the "ssl" bind keyword */
Willy Tarreau4348fad2012-09-20 16:48:07 +02004112static 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 +02004113{
Willy Tarreau81796be2012-09-22 19:11:47 +02004114 struct listener *l;
4115
Willy Tarreau4348fad2012-09-20 16:48:07 +02004116 conf->is_ssl = 1;
Emeric Brun76d88952012-10-05 15:47:31 +02004117
4118 if (global.listen_default_ciphers && !conf->ciphers)
4119 conf->ciphers = strdup(global.listen_default_ciphers);
Emeric Brun42a3e202014-10-30 15:56:50 +01004120 conf->ssl_options |= global.listen_default_ssloptions;
Emeric Brun76d88952012-10-05 15:47:31 +02004121
Willy Tarreau81796be2012-09-22 19:11:47 +02004122 list_for_each_entry(l, &conf->listeners, by_bind)
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02004123 l->xprt = &ssl_sock;
Willy Tarreau81796be2012-09-22 19:11:47 +02004124
Willy Tarreau79eeafa2012-09-14 07:53:05 +02004125 return 0;
4126}
4127
Emmanuel Hocdet65623372013-01-24 17:17:15 +01004128/* parse the "strict-sni" bind keyword */
4129static int bind_parse_strict_sni(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
4130{
4131 conf->strict_sni = 1;
4132 return 0;
4133}
4134
Emeric Brund94b3fe2012-09-20 18:23:56 +02004135/* parse the "verify" bind keyword */
4136static int bind_parse_verify(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
4137{
4138 if (!*args[cur_arg + 1]) {
4139 if (err)
4140 memprintf(err, "'%s' : missing verify method", args[cur_arg]);
4141 return ERR_ALERT | ERR_FATAL;
4142 }
4143
4144 if (strcmp(args[cur_arg + 1], "none") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01004145 conf->verify = SSL_SOCK_VERIFY_NONE;
Emeric Brund94b3fe2012-09-20 18:23:56 +02004146 else if (strcmp(args[cur_arg + 1], "optional") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01004147 conf->verify = SSL_SOCK_VERIFY_OPTIONAL;
Emeric Brund94b3fe2012-09-20 18:23:56 +02004148 else if (strcmp(args[cur_arg + 1], "required") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01004149 conf->verify = SSL_SOCK_VERIFY_REQUIRED;
Emeric Brund94b3fe2012-09-20 18:23:56 +02004150 else {
4151 if (err)
4152 memprintf(err, "'%s' : unknown verify method '%s', only 'none', 'optional', and 'required' are supported\n",
4153 args[cur_arg], args[cur_arg + 1]);
4154 return ERR_ALERT | ERR_FATAL;
4155 }
4156
4157 return 0;
4158}
4159
Willy Tarreau92faadf2012-10-10 23:04:25 +02004160/************** "server" keywords ****************/
4161
Emeric Brunef42d922012-10-11 16:11:36 +02004162/* parse the "ca-file" server keyword */
4163static int srv_parse_ca_file(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4164{
4165 if (!*args[*cur_arg + 1]) {
4166 if (err)
4167 memprintf(err, "'%s' : missing CAfile path", args[*cur_arg]);
4168 return ERR_ALERT | ERR_FATAL;
4169 }
4170
4171 if ((*args[*cur_arg + 1] != '/') && global.ca_base)
4172 memprintf(&newsrv->ssl_ctx.ca_file, "%s/%s", global.ca_base, args[*cur_arg + 1]);
4173 else
4174 memprintf(&newsrv->ssl_ctx.ca_file, "%s", args[*cur_arg + 1]);
4175
4176 return 0;
4177}
4178
Willy Tarreau92faadf2012-10-10 23:04:25 +02004179/* parse the "check-ssl" server keyword */
4180static int srv_parse_check_ssl(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4181{
4182 newsrv->check.use_ssl = 1;
4183 if (global.connect_default_ciphers && !newsrv->ssl_ctx.ciphers)
4184 newsrv->ssl_ctx.ciphers = strdup(global.connect_default_ciphers);
Emeric Brun42a3e202014-10-30 15:56:50 +01004185 newsrv->ssl_ctx.options |= global.connect_default_ssloptions;
Willy Tarreau92faadf2012-10-10 23:04:25 +02004186 return 0;
4187}
4188
4189/* parse the "ciphers" server keyword */
4190static int srv_parse_ciphers(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4191{
4192 if (!*args[*cur_arg + 1]) {
4193 memprintf(err, "'%s' : missing cipher suite", args[*cur_arg]);
4194 return ERR_ALERT | ERR_FATAL;
4195 }
4196
4197 free(newsrv->ssl_ctx.ciphers);
4198 newsrv->ssl_ctx.ciphers = strdup(args[*cur_arg + 1]);
4199 return 0;
4200}
4201
Emeric Brunef42d922012-10-11 16:11:36 +02004202/* parse the "crl-file" server keyword */
4203static int srv_parse_crl_file(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4204{
4205#ifndef X509_V_FLAG_CRL_CHECK
4206 if (err)
4207 memprintf(err, "'%s' : library does not support CRL verify", args[*cur_arg]);
4208 return ERR_ALERT | ERR_FATAL;
4209#else
4210 if (!*args[*cur_arg + 1]) {
4211 if (err)
4212 memprintf(err, "'%s' : missing CRLfile path", args[*cur_arg]);
4213 return ERR_ALERT | ERR_FATAL;
4214 }
4215
4216 if ((*args[*cur_arg + 1] != '/') && global.ca_base)
4217 memprintf(&newsrv->ssl_ctx.crl_file, "%s/%s", global.ca_base, args[*cur_arg + 1]);
4218 else
4219 memprintf(&newsrv->ssl_ctx.crl_file, "%s", args[*cur_arg + 1]);
4220
4221 return 0;
4222#endif
4223}
4224
Emeric Bruna7aa3092012-10-26 12:58:00 +02004225/* parse the "crt" server keyword */
4226static int srv_parse_crt(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4227{
4228 if (!*args[*cur_arg + 1]) {
4229 if (err)
4230 memprintf(err, "'%s' : missing certificate file path", args[*cur_arg]);
4231 return ERR_ALERT | ERR_FATAL;
4232 }
4233
4234 if ((*args[*cur_arg + 1] != '/') && global.crt_base)
4235 memprintf(&newsrv->ssl_ctx.client_crt, "%s/%s", global.ca_base, args[*cur_arg + 1]);
4236 else
4237 memprintf(&newsrv->ssl_ctx.client_crt, "%s", args[*cur_arg + 1]);
4238
4239 return 0;
4240}
Emeric Brunef42d922012-10-11 16:11:36 +02004241
Willy Tarreau92faadf2012-10-10 23:04:25 +02004242/* parse the "force-sslv3" server keyword */
4243static int srv_parse_force_sslv3(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4244{
4245 newsrv->ssl_ctx.options |= SRV_SSL_O_USE_SSLV3;
4246 return 0;
4247}
4248
4249/* parse the "force-tlsv10" server keyword */
4250static int srv_parse_force_tlsv10(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4251{
4252 newsrv->ssl_ctx.options |= SRV_SSL_O_USE_TLSV10;
4253 return 0;
4254}
4255
4256/* parse the "force-tlsv11" server keyword */
4257static int srv_parse_force_tlsv11(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4258{
4259#if SSL_OP_NO_TLSv1_1
4260 newsrv->ssl_ctx.options |= SRV_SSL_O_USE_TLSV11;
4261 return 0;
4262#else
4263 if (err)
4264 memprintf(err, "'%s' : library does not support protocol TLSv1.1", args[*cur_arg]);
4265 return ERR_ALERT | ERR_FATAL;
4266#endif
4267}
4268
4269/* parse the "force-tlsv12" server keyword */
4270static int srv_parse_force_tlsv12(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4271{
4272#if SSL_OP_NO_TLSv1_2
4273 newsrv->ssl_ctx.options |= SRV_SSL_O_USE_TLSV12;
4274 return 0;
4275#else
4276 if (err)
4277 memprintf(err, "'%s' : library does not support protocol TLSv1.2", args[*cur_arg]);
4278 return ERR_ALERT | ERR_FATAL;
4279#endif
4280}
4281
4282/* parse the "no-sslv3" server keyword */
4283static int srv_parse_no_sslv3(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4284{
4285 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_SSLV3;
4286 return 0;
4287}
4288
4289/* parse the "no-tlsv10" server keyword */
4290static int srv_parse_no_tlsv10(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4291{
4292 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_TLSV10;
4293 return 0;
4294}
4295
4296/* parse the "no-tlsv11" server keyword */
4297static int srv_parse_no_tlsv11(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4298{
4299 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_TLSV11;
4300 return 0;
4301}
4302
4303/* parse the "no-tlsv12" server keyword */
4304static int srv_parse_no_tlsv12(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4305{
4306 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_TLSV12;
4307 return 0;
4308}
4309
Emeric Brunf9c5c472012-10-11 15:28:34 +02004310/* parse the "no-tls-tickets" server keyword */
4311static int srv_parse_no_tls_tickets(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4312{
4313 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_TLS_TICKETS;
4314 return 0;
4315}
David Safb76832014-05-08 23:42:08 -04004316/* parse the "send-proxy-v2-ssl" server keyword */
4317static int srv_parse_send_proxy_ssl(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4318{
4319 newsrv->pp_opts |= SRV_PP_V2;
4320 newsrv->pp_opts |= SRV_PP_V2_SSL;
4321 return 0;
4322}
4323
4324/* parse the "send-proxy-v2-ssl-cn" server keyword */
4325static int srv_parse_send_proxy_cn(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4326{
4327 newsrv->pp_opts |= SRV_PP_V2;
4328 newsrv->pp_opts |= SRV_PP_V2_SSL;
4329 newsrv->pp_opts |= SRV_PP_V2_SSL_CN;
4330 return 0;
4331}
Emeric Brunf9c5c472012-10-11 15:28:34 +02004332
Willy Tarreau92faadf2012-10-10 23:04:25 +02004333/* parse the "ssl" server keyword */
4334static int srv_parse_ssl(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4335{
4336 newsrv->use_ssl = 1;
4337 if (global.connect_default_ciphers && !newsrv->ssl_ctx.ciphers)
4338 newsrv->ssl_ctx.ciphers = strdup(global.connect_default_ciphers);
4339 return 0;
4340}
4341
Emeric Brunef42d922012-10-11 16:11:36 +02004342/* parse the "verify" server keyword */
4343static int srv_parse_verify(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4344{
4345 if (!*args[*cur_arg + 1]) {
4346 if (err)
4347 memprintf(err, "'%s' : missing verify method", args[*cur_arg]);
4348 return ERR_ALERT | ERR_FATAL;
4349 }
4350
4351 if (strcmp(args[*cur_arg + 1], "none") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01004352 newsrv->ssl_ctx.verify = SSL_SOCK_VERIFY_NONE;
Emeric Brunef42d922012-10-11 16:11:36 +02004353 else if (strcmp(args[*cur_arg + 1], "required") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01004354 newsrv->ssl_ctx.verify = SSL_SOCK_VERIFY_REQUIRED;
Emeric Brunef42d922012-10-11 16:11:36 +02004355 else {
4356 if (err)
4357 memprintf(err, "'%s' : unknown verify method '%s', only 'none' and 'required' are supported\n",
4358 args[*cur_arg], args[*cur_arg + 1]);
4359 return ERR_ALERT | ERR_FATAL;
4360 }
4361
Evan Broderbe554312013-06-27 00:05:25 -07004362 return 0;
4363}
4364
4365/* parse the "verifyhost" server keyword */
4366static int srv_parse_verifyhost(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4367{
4368 if (!*args[*cur_arg + 1]) {
4369 if (err)
4370 memprintf(err, "'%s' : missing hostname to verify against", args[*cur_arg]);
4371 return ERR_ALERT | ERR_FATAL;
4372 }
4373
4374 newsrv->ssl_ctx.verify_host = strdup(args[*cur_arg + 1]);
4375
Emeric Brunef42d922012-10-11 16:11:36 +02004376 return 0;
4377}
4378
Emeric Brun42a3e202014-10-30 15:56:50 +01004379/* parse the "ssl-default-bind-options" keyword in global section */
4380static int ssl_parse_default_bind_options(char **args, int section_type, struct proxy *curpx,
4381 struct proxy *defpx, const char *file, int line,
4382 char **err) {
4383 int i = 1;
4384
4385 if (*(args[i]) == 0) {
4386 memprintf(err, "global statement '%s' expects an option as an argument.", args[0]);
4387 return -1;
4388 }
4389 while (*(args[i])) {
4390 if (!strcmp(args[i], "no-sslv3"))
4391 global.listen_default_ssloptions |= BC_SSL_O_NO_SSLV3;
4392 else if (!strcmp(args[i], "no-tlsv10"))
4393 global.listen_default_ssloptions |= BC_SSL_O_NO_TLSV10;
4394 else if (!strcmp(args[i], "no-tlsv11"))
4395 global.listen_default_ssloptions |= BC_SSL_O_NO_TLSV11;
4396 else if (!strcmp(args[i], "no-tlsv12"))
4397 global.listen_default_ssloptions |= BC_SSL_O_NO_TLSV12;
4398 else if (!strcmp(args[i], "force-sslv3"))
4399 global.listen_default_ssloptions |= BC_SSL_O_USE_SSLV3;
4400 else if (!strcmp(args[i], "force-tlsv10"))
4401 global.listen_default_ssloptions |= BC_SSL_O_USE_TLSV10;
4402 else if (!strcmp(args[i], "force-tlsv11")) {
4403#if SSL_OP_NO_TLSv1_1
4404 global.listen_default_ssloptions |= BC_SSL_O_USE_TLSV11;
4405#else
4406 memprintf(err, "'%s' '%s': library does not support protocol TLSv1.1", args[0], args[i]);
4407 return -1;
4408#endif
4409 }
4410 else if (!strcmp(args[i], "force-tlsv12")) {
4411#if SSL_OP_NO_TLSv1_2
4412 global.listen_default_ssloptions |= BC_SSL_O_USE_TLSV12;
4413#else
4414 memprintf(err, "'%s' '%s': library does not support protocol TLSv1.2", args[0], args[i]);
4415 return -1;
4416#endif
4417 }
4418 else if (!strcmp(args[i], "no-tls-tickets"))
4419 global.listen_default_ssloptions |= BC_SSL_O_NO_TLS_TICKETS;
4420 else {
4421 memprintf(err, "unknown option '%s' on global statement '%s'.", args[i], args[0]);
4422 return -1;
4423 }
4424 i++;
4425 }
4426 return 0;
4427}
4428
4429/* parse the "ssl-default-server-options" keyword in global section */
4430static int ssl_parse_default_server_options(char **args, int section_type, struct proxy *curpx,
4431 struct proxy *defpx, const char *file, int line,
4432 char **err) {
4433 int i = 1;
4434
4435 if (*(args[i]) == 0) {
4436 memprintf(err, "global statement '%s' expects an option as an argument.", args[0]);
4437 return -1;
4438 }
4439 while (*(args[i])) {
4440 if (!strcmp(args[i], "no-sslv3"))
4441 global.connect_default_ssloptions |= SRV_SSL_O_NO_SSLV3;
4442 else if (!strcmp(args[i], "no-tlsv10"))
4443 global.connect_default_ssloptions |= SRV_SSL_O_NO_TLSV10;
4444 else if (!strcmp(args[i], "no-tlsv11"))
4445 global.connect_default_ssloptions |= SRV_SSL_O_NO_TLSV11;
4446 else if (!strcmp(args[i], "no-tlsv12"))
4447 global.connect_default_ssloptions |= SRV_SSL_O_NO_TLSV12;
4448 else if (!strcmp(args[i], "force-sslv3"))
4449 global.connect_default_ssloptions |= SRV_SSL_O_USE_SSLV3;
4450 else if (!strcmp(args[i], "force-tlsv10"))
4451 global.connect_default_ssloptions |= SRV_SSL_O_USE_TLSV10;
4452 else if (!strcmp(args[i], "force-tlsv11")) {
4453#if SSL_OP_NO_TLSv1_1
4454 global.connect_default_ssloptions |= SRV_SSL_O_USE_TLSV11;
4455#else
4456 memprintf(err, "'%s' '%s': library does not support protocol TLSv1.1", args[0], args[i]);
4457 return -1;
4458#endif
4459 }
4460 else if (!strcmp(args[i], "force-tlsv12")) {
4461#if SSL_OP_NO_TLSv1_2
4462 global.connect_default_ssloptions |= SRV_SSL_O_USE_TLSV12;
4463#else
4464 memprintf(err, "'%s' '%s': library does not support protocol TLSv1.2", args[0], args[i]);
4465 return -1;
4466#endif
4467 }
4468 else if (!strcmp(args[i], "no-tls-tickets"))
4469 global.connect_default_ssloptions |= SRV_SSL_O_NO_TLS_TICKETS;
4470 else {
4471 memprintf(err, "unknown option '%s' on global statement '%s'.", args[i], args[0]);
4472 return -1;
4473 }
4474 i++;
4475 }
4476 return 0;
4477}
4478
Willy Tarreau7875d092012-09-10 08:20:03 +02004479/* Note: must not be declared <const> as its list will be overwritten.
4480 * Please take care of keeping this list alphabetically sorted.
4481 */
Willy Tarreaudc13c112013-06-21 23:16:39 +02004482static struct sample_fetch_kw_list sample_fetch_keywords = {ILH, {
Emeric Brun645ae792014-04-30 14:21:06 +02004483 { "ssl_bc", smp_fetch_ssl_fc, 0, NULL, SMP_T_BOOL, SMP_USE_L5SRV },
4484 { "ssl_bc_alg_keysize", smp_fetch_ssl_fc_alg_keysize, 0, NULL, SMP_T_UINT, SMP_USE_L5SRV },
4485 { "ssl_bc_cipher", smp_fetch_ssl_fc_cipher, 0, NULL, SMP_T_STR, SMP_USE_L5SRV },
4486 { "ssl_bc_protocol", smp_fetch_ssl_fc_protocol, 0, NULL, SMP_T_STR, SMP_USE_L5SRV },
Emeric Brunb73a9b02014-04-30 18:49:19 +02004487 { "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 +02004488 { "ssl_bc_use_keysize", smp_fetch_ssl_fc_use_keysize, 0, NULL, SMP_T_UINT, SMP_USE_L5SRV },
4489 { "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 +01004490 { "ssl_c_ca_err", smp_fetch_ssl_c_ca_err, 0, NULL, SMP_T_UINT, SMP_USE_L5CLI },
4491 { "ssl_c_ca_err_depth", smp_fetch_ssl_c_ca_err_depth, 0, NULL, SMP_T_UINT, SMP_USE_L5CLI },
Emeric Brunb3cc4252014-10-29 19:03:26 +01004492 { "ssl_c_der", smp_fetch_ssl_x_der, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Willy Tarreau80aca902013-01-07 15:42:20 +01004493 { "ssl_c_err", smp_fetch_ssl_c_err, 0, NULL, SMP_T_UINT, SMP_USE_L5CLI },
Emeric Brunba841a12014-04-30 17:05:08 +02004494 { "ssl_c_i_dn", smp_fetch_ssl_x_i_dn, ARG2(0,STR,SINT), NULL, SMP_T_STR, SMP_USE_L5CLI },
4495 { "ssl_c_key_alg", smp_fetch_ssl_x_key_alg, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
4496 { "ssl_c_notafter", smp_fetch_ssl_x_notafter, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
4497 { "ssl_c_notbefore", smp_fetch_ssl_x_notbefore, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
4498 { "ssl_c_sig_alg", smp_fetch_ssl_x_sig_alg, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
4499 { "ssl_c_s_dn", smp_fetch_ssl_x_s_dn, ARG2(0,STR,SINT), NULL, SMP_T_STR, SMP_USE_L5CLI },
4500 { "ssl_c_serial", smp_fetch_ssl_x_serial, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
4501 { "ssl_c_sha1", smp_fetch_ssl_x_sha1, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Willy Tarreau80aca902013-01-07 15:42:20 +01004502 { "ssl_c_used", smp_fetch_ssl_c_used, 0, NULL, SMP_T_BOOL, SMP_USE_L5CLI },
4503 { "ssl_c_verify", smp_fetch_ssl_c_verify, 0, NULL, SMP_T_UINT, SMP_USE_L5CLI },
Emeric Brunba841a12014-04-30 17:05:08 +02004504 { "ssl_c_version", smp_fetch_ssl_x_version, 0, NULL, SMP_T_UINT, SMP_USE_L5CLI },
Emeric Brunb3cc4252014-10-29 19:03:26 +01004505 { "ssl_f_der", smp_fetch_ssl_x_der, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Emeric Brunba841a12014-04-30 17:05:08 +02004506 { "ssl_f_i_dn", smp_fetch_ssl_x_i_dn, ARG2(0,STR,SINT), NULL, SMP_T_STR, SMP_USE_L5CLI },
4507 { "ssl_f_key_alg", smp_fetch_ssl_x_key_alg, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
4508 { "ssl_f_notafter", smp_fetch_ssl_x_notafter, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
4509 { "ssl_f_notbefore", smp_fetch_ssl_x_notbefore, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
4510 { "ssl_f_sig_alg", smp_fetch_ssl_x_sig_alg, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
4511 { "ssl_f_s_dn", smp_fetch_ssl_x_s_dn, ARG2(0,STR,SINT), NULL, SMP_T_STR, SMP_USE_L5CLI },
4512 { "ssl_f_serial", smp_fetch_ssl_x_serial, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Emeric Brun55f4fa82014-04-30 17:11:25 +02004513 { "ssl_f_sha1", smp_fetch_ssl_x_sha1, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Emeric Brunba841a12014-04-30 17:05:08 +02004514 { "ssl_f_version", smp_fetch_ssl_x_version, 0, NULL, SMP_T_UINT, SMP_USE_L5CLI },
Willy Tarreau80aca902013-01-07 15:42:20 +01004515 { "ssl_fc", smp_fetch_ssl_fc, 0, NULL, SMP_T_BOOL, SMP_USE_L5CLI },
4516 { "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 +01004517 { "ssl_fc_cipher", smp_fetch_ssl_fc_cipher, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Willy Tarreau80aca902013-01-07 15:42:20 +01004518 { "ssl_fc_has_crt", smp_fetch_ssl_fc_has_crt, 0, NULL, SMP_T_BOOL, SMP_USE_L5CLI },
4519 { "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 +02004520#ifdef OPENSSL_NPN_NEGOTIATED
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01004521 { "ssl_fc_npn", smp_fetch_ssl_fc_npn, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Willy Tarreaua33c6542012-10-15 13:19:06 +02004522#endif
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01004523#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01004524 { "ssl_fc_alpn", smp_fetch_ssl_fc_alpn, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Willy Tarreauab861d32013-04-02 02:30:41 +02004525#endif
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01004526 { "ssl_fc_protocol", smp_fetch_ssl_fc_protocol, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Emeric Brunb73a9b02014-04-30 18:49:19 +02004527 { "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 +01004528 { "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 +01004529 { "ssl_fc_session_id", smp_fetch_ssl_fc_session_id, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
4530 { "ssl_fc_sni", smp_fetch_ssl_fc_sni, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Willy Tarreau7875d092012-09-10 08:20:03 +02004531 { NULL, NULL, 0, 0, 0 },
4532}};
4533
4534/* Note: must not be declared <const> as its list will be overwritten.
4535 * Please take care of keeping this list alphabetically sorted.
4536 */
Willy Tarreaudc13c112013-06-21 23:16:39 +02004537static struct acl_kw_list acl_kws = {ILH, {
Thierry FOURNIERc5a4e982014-03-05 16:07:08 +01004538 { "ssl_fc_sni_end", "ssl_fc_sni", PAT_MATCH_END },
4539 { "ssl_fc_sni_reg", "ssl_fc_sni", PAT_MATCH_REG },
Willy Tarreau8ed669b2013-01-11 15:49:37 +01004540 { /* END */ },
Willy Tarreau7875d092012-09-10 08:20:03 +02004541}};
4542
Willy Tarreau79eeafa2012-09-14 07:53:05 +02004543/* Note: must not be declared <const> as its list will be overwritten.
4544 * Please take care of keeping this list alphabetically sorted, doing so helps
4545 * all code contributors.
4546 * Optional keywords are also declared with a NULL ->parse() function so that
4547 * the config parser can report an appropriate error when a known keyword was
4548 * not enabled.
4549 */
Willy Tarreau51fb7652012-09-18 18:24:39 +02004550static struct bind_kw_list bind_kws = { "SSL", { }, {
Willy Tarreauab861d32013-04-02 02:30:41 +02004551 { "alpn", bind_parse_alpn, 1 }, /* set ALPN supported protocols */
Emeric Brunfb510ea2012-10-05 12:00:26 +02004552 { "ca-file", bind_parse_ca_file, 1 }, /* set CAfile to process verify on client cert */
Emeric Brun2d0c4822012-10-02 13:45:20 +02004553 { "ca-ignore-err", bind_parse_ignore_err, 1 }, /* set error IDs to ignore on verify depth > 0 */
4554 { "ciphers", bind_parse_ciphers, 1 }, /* set SSL cipher suite */
Emeric Brunfb510ea2012-10-05 12:00:26 +02004555 { "crl-file", bind_parse_crl_file, 1 }, /* set certificat revocation list file use on client cert verify */
Emeric Brun2d0c4822012-10-02 13:45:20 +02004556 { "crt", bind_parse_crt, 1 }, /* load SSL certificates from this location */
4557 { "crt-ignore-err", bind_parse_ignore_err, 1 }, /* set error IDs to ingore on verify depth == 0 */
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01004558 { "crt-list", bind_parse_crt_list, 1 }, /* load a list of crt from this location */
Emeric Brun2d0c4822012-10-02 13:45:20 +02004559 { "ecdhe", bind_parse_ecdhe, 1 }, /* defines named curve for elliptic curve Diffie-Hellman */
Emeric Brun2cb7ae52012-10-05 14:14:21 +02004560 { "force-sslv3", bind_parse_force_sslv3, 0 }, /* force SSLv3 */
4561 { "force-tlsv10", bind_parse_force_tlsv10, 0 }, /* force TLSv10 */
4562 { "force-tlsv11", bind_parse_force_tlsv11, 0 }, /* force TLSv11 */
4563 { "force-tlsv12", bind_parse_force_tlsv12, 0 }, /* force TLSv12 */
Emeric Brun9b3009b2012-10-05 11:55:06 +02004564 { "no-sslv3", bind_parse_no_sslv3, 0 }, /* disable SSLv3 */
4565 { "no-tlsv10", bind_parse_no_tlsv10, 0 }, /* disable TLSv10 */
4566 { "no-tlsv11", bind_parse_no_tlsv11, 0 }, /* disable TLSv11 */
4567 { "no-tlsv12", bind_parse_no_tlsv12, 0 }, /* disable TLSv12 */
Emeric Brun2d0c4822012-10-02 13:45:20 +02004568 { "no-tls-tickets", bind_parse_no_tls_tickets, 0 }, /* disable session resumption tickets */
Emeric Brun2d0c4822012-10-02 13:45:20 +02004569 { "ssl", bind_parse_ssl, 0 }, /* enable SSL processing */
Emmanuel Hocdet65623372013-01-24 17:17:15 +01004570 { "strict-sni", bind_parse_strict_sni, 0 }, /* refuse negotiation if sni doesn't match a certificate */
Emeric Brun2d0c4822012-10-02 13:45:20 +02004571 { "verify", bind_parse_verify, 1 }, /* set SSL verify method */
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02004572 { "npn", bind_parse_npn, 1 }, /* set NPN supported protocols */
Willy Tarreau79eeafa2012-09-14 07:53:05 +02004573 { NULL, NULL, 0 },
4574}};
Emeric Brun46591952012-05-18 15:47:34 +02004575
Willy Tarreau92faadf2012-10-10 23:04:25 +02004576/* Note: must not be declared <const> as its list will be overwritten.
4577 * Please take care of keeping this list alphabetically sorted, doing so helps
4578 * all code contributors.
4579 * Optional keywords are also declared with a NULL ->parse() function so that
4580 * the config parser can report an appropriate error when a known keyword was
4581 * not enabled.
4582 */
4583static struct srv_kw_list srv_kws = { "SSL", { }, {
Emeric Brunef42d922012-10-11 16:11:36 +02004584 { "ca-file", srv_parse_ca_file, 1, 0 }, /* set CAfile to process verify server cert */
Emeric Brunecc91fe2012-10-11 15:05:10 +02004585 { "check-ssl", srv_parse_check_ssl, 0, 0 }, /* enable SSL for health checks */
4586 { "ciphers", srv_parse_ciphers, 1, 0 }, /* select the cipher suite */
Emeric Brunef42d922012-10-11 16:11:36 +02004587 { "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 +02004588 { "crt", srv_parse_crt, 1, 0 }, /* set client certificate */
Emeric Brunecc91fe2012-10-11 15:05:10 +02004589 { "force-sslv3", srv_parse_force_sslv3, 0, 0 }, /* force SSLv3 */
4590 { "force-tlsv10", srv_parse_force_tlsv10, 0, 0 }, /* force TLSv10 */
4591 { "force-tlsv11", srv_parse_force_tlsv11, 0, 0 }, /* force TLSv11 */
4592 { "force-tlsv12", srv_parse_force_tlsv12, 0, 0 }, /* force TLSv12 */
4593 { "no-sslv3", srv_parse_no_sslv3, 0, 0 }, /* disable SSLv3 */
4594 { "no-tlsv10", srv_parse_no_tlsv10, 0, 0 }, /* disable TLSv10 */
4595 { "no-tlsv11", srv_parse_no_tlsv11, 0, 0 }, /* disable TLSv11 */
4596 { "no-tlsv12", srv_parse_no_tlsv12, 0, 0 }, /* disable TLSv12 */
Emeric Brunf9c5c472012-10-11 15:28:34 +02004597 { "no-tls-tickets", srv_parse_no_tls_tickets, 0, 0 }, /* disable session resumption tickets */
David Safb76832014-05-08 23:42:08 -04004598 { "send-proxy-v2-ssl", srv_parse_send_proxy_ssl, 0, 0 }, /* send PROXY protocol header v2 with SSL info */
4599 { "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 +02004600 { "ssl", srv_parse_ssl, 0, 0 }, /* enable SSL processing */
Emeric Brunef42d922012-10-11 16:11:36 +02004601 { "verify", srv_parse_verify, 1, 0 }, /* set SSL verify method */
Evan Broderbe554312013-06-27 00:05:25 -07004602 { "verifyhost", srv_parse_verifyhost, 1, 0 }, /* require that SSL cert verifies for hostname */
Willy Tarreau92faadf2012-10-10 23:04:25 +02004603 { NULL, NULL, 0, 0 },
4604}};
4605
Emeric Brun42a3e202014-10-30 15:56:50 +01004606static struct cfg_kw_list cfg_kws = {ILH, {
4607 { CFG_GLOBAL, "ssl-default-bind-options", ssl_parse_default_bind_options },
4608 { CFG_GLOBAL, "ssl-default-server-options", ssl_parse_default_server_options },
4609 { 0, NULL, NULL },
4610}};
4611
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02004612/* transport-layer operations for SSL sockets */
4613struct xprt_ops ssl_sock = {
Emeric Brun46591952012-05-18 15:47:34 +02004614 .snd_buf = ssl_sock_from_buf,
4615 .rcv_buf = ssl_sock_to_buf,
4616 .rcv_pipe = NULL,
4617 .snd_pipe = NULL,
4618 .shutr = NULL,
4619 .shutw = ssl_sock_shutw,
4620 .close = ssl_sock_close,
4621 .init = ssl_sock_init,
4622};
4623
4624__attribute__((constructor))
Willy Tarreau92faadf2012-10-10 23:04:25 +02004625static void __ssl_sock_init(void)
4626{
Emeric Brun46591952012-05-18 15:47:34 +02004627 STACK_OF(SSL_COMP)* cm;
4628
Willy Tarreau610f04b2014-02-13 11:36:41 +01004629#ifdef LISTEN_DEFAULT_CIPHERS
4630 global.listen_default_ciphers = LISTEN_DEFAULT_CIPHERS;
4631#endif
4632#ifdef CONNECT_DEFAULT_CIPHERS
4633 global.connect_default_ciphers = CONNECT_DEFAULT_CIPHERS;
4634#endif
4635 if (global.listen_default_ciphers)
4636 global.listen_default_ciphers = strdup(global.listen_default_ciphers);
4637 if (global.connect_default_ciphers)
4638 global.connect_default_ciphers = strdup(global.connect_default_ciphers);
Emeric Brun42a3e202014-10-30 15:56:50 +01004639 global.listen_default_ssloptions = BC_SSL_O_NONE;
4640 global.connect_default_ssloptions = SRV_SSL_O_NONE;
Willy Tarreau610f04b2014-02-13 11:36:41 +01004641
Emeric Brun46591952012-05-18 15:47:34 +02004642 SSL_library_init();
4643 cm = SSL_COMP_get_compression_methods();
4644 sk_SSL_COMP_zero(cm);
Willy Tarreau7875d092012-09-10 08:20:03 +02004645 sample_register_fetches(&sample_fetch_keywords);
4646 acl_register_keywords(&acl_kws);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02004647 bind_register_keywords(&bind_kws);
Willy Tarreau92faadf2012-10-10 23:04:25 +02004648 srv_register_keywords(&srv_kws);
Emeric Brun42a3e202014-10-30 15:56:50 +01004649 cfg_register_keywords(&cfg_kws);
Emeric Brun46591952012-05-18 15:47:34 +02004650}
4651
4652/*
4653 * Local variables:
4654 * c-indent-level: 8
4655 * c-basic-offset: 8
4656 * End:
4657 */