blob: 375225d19f72c4bc797be651b96d4f75b7fd491f [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>
59
Emeric Brunfc0421f2012-09-07 17:30:07 +020060#include <ebsttree.h>
61
62#include <types/global.h>
63#include <types/ssl_sock.h>
64
Willy Tarreau7875d092012-09-10 08:20:03 +020065#include <proto/acl.h>
66#include <proto/arg.h>
Emeric Brun46591952012-05-18 15:47:34 +020067#include <proto/connection.h>
68#include <proto/fd.h>
69#include <proto/freq_ctr.h>
70#include <proto/frontend.h>
Willy Tarreau79eeafa2012-09-14 07:53:05 +020071#include <proto/listener.h>
Thierry FOURNIERed66c292013-11-28 11:05:19 +010072#include <proto/pattern.h>
Willy Tarreau92faadf2012-10-10 23:04:25 +020073#include <proto/server.h>
Emeric Brun46591952012-05-18 15:47:34 +020074#include <proto/log.h>
Emeric Brun94324a42012-10-11 14:00:19 +020075#include <proto/proxy.h>
Emeric Brunfc0421f2012-09-07 17:30:07 +020076#include <proto/shctx.h>
Emeric Brun46591952012-05-18 15:47:34 +020077#include <proto/ssl_sock.h>
78#include <proto/task.h>
79
Willy Tarreau518cedd2014-02-17 15:43:01 +010080/* Warning, these are bits, not integers! */
Emeric Brune64aef12012-09-21 13:15:06 +020081#define SSL_SOCK_ST_FL_VERIFY_DONE 0x00000001
Emeric Brund8b2bb52014-01-28 15:43:53 +010082#define SSL_SOCK_ST_FL_16K_WBFSIZE 0x00000002
Willy Tarreau518cedd2014-02-17 15:43:01 +010083#define SSL_SOCK_SEND_UNLIMITED 0x00000004
Emeric Brun29f037d2014-04-25 19:05:36 +020084#define SSL_SOCK_RECV_HEARTBEAT 0x00000008
85
Emeric Brunf282a812012-09-21 15:27:54 +020086/* bits 0xFFFF0000 are reserved to store verify errors */
87
88/* Verify errors macros */
89#define SSL_SOCK_CA_ERROR_TO_ST(e) (((e > 63) ? 63 : e) << (16))
90#define SSL_SOCK_CAEDEPTH_TO_ST(d) (((d > 15) ? 15 : d) << (6+16))
91#define SSL_SOCK_CRTERROR_TO_ST(e) (((e > 63) ? 63 : e) << (4+6+16))
92
93#define SSL_SOCK_ST_TO_CA_ERROR(s) ((s >> (16)) & 63)
94#define SSL_SOCK_ST_TO_CAEDEPTH(s) ((s >> (6+16)) & 15)
95#define SSL_SOCK_ST_TO_CRTERROR(s) ((s >> (4+6+16)) & 63)
Emeric Brune64aef12012-09-21 13:15:06 +020096
Emeric Brun850efd52014-01-29 12:24:34 +010097/* server and bind verify method, it uses a global value as default */
98enum {
99 SSL_SOCK_VERIFY_DEFAULT = 0,
100 SSL_SOCK_VERIFY_REQUIRED = 1,
101 SSL_SOCK_VERIFY_OPTIONAL = 2,
102 SSL_SOCK_VERIFY_NONE = 3,
103};
104
Willy Tarreau71b734c2014-01-28 15:19:44 +0100105int sslconns = 0;
106int totalsslconns = 0;
Emeric Brune1f38db2012-09-03 20:36:47 +0200107
Emeric Brun4147b2e2014-06-16 18:36:30 +0200108#ifdef SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB
109struct certificate_ocsp {
110 struct ebmb_node key;
111 unsigned char key_data[OCSP_MAX_CERTID_ASN1_LENGTH];
112 struct chunk response;
Emeric Brun4f3c87a2014-06-20 15:46:13 +0200113 long expire;
Emeric Brun4147b2e2014-06-16 18:36:30 +0200114};
115
Emeric Brun4f3c87a2014-06-20 15:46:13 +0200116/*
117 * This function returns the number of seconds elapsed
118 * since the Epoch, 1970-01-01 00:00:00 +0000 (UTC) and the
119 * date presented un ASN1_GENERALIZEDTIME.
120 *
121 * In parsing error case, it returns -1.
122 */
123static long asn1_generalizedtime_to_epoch(ASN1_GENERALIZEDTIME *d)
124{
125 long epoch;
126 char *p, *end;
127 const unsigned short month_offset[12] = {
128 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334
129 };
130 int year, month;
131
132 if (!d || (d->type != V_ASN1_GENERALIZEDTIME)) return -1;
133
134 p = (char *)d->data;
135 end = p + d->length;
136
137 if (end - p < 4) return -1;
138 year = 1000 * (p[0] - '0') + 100 * (p[1] - '0') + 10 * (p[2] - '0') + p[3] - '0';
139 p += 4;
140 if (end - p < 2) return -1;
141 month = 10 * (p[0] - '0') + p[1] - '0';
142 if (month < 1 || month > 12) return -1;
143 /* Compute the number of seconds since 1 jan 1970 and the beginning of current month
144 We consider leap years and the current month (<marsh or not) */
145 epoch = ( ((year - 1970) * 365)
146 + ((year - (month < 3)) / 4 - (year - (month < 3)) / 100 + (year - (month < 3)) / 400)
147 - ((1970 - 1) / 4 - (1970 - 1) / 100 + (1970 - 1) / 400)
148 + month_offset[month-1]
149 ) * 24 * 60 * 60;
150 p += 2;
151 if (end - p < 2) return -1;
152 /* Add the number of seconds of completed days of current month */
153 epoch += (10 * (p[0] - '0') + p[1] - '0' - 1) * 24 * 60 * 60;
154 p += 2;
155 if (end - p < 2) return -1;
156 /* Add the completed hours of the current day */
157 epoch += (10 * (p[0] - '0') + p[1] - '0') * 60 * 60;
158 p += 2;
159 if (end - p < 2) return -1;
160 /* Add the completed minutes of the current hour */
161 epoch += (10 * (p[0] - '0') + p[1] - '0') * 60;
162 p += 2;
163 if (p == end) return -1;
164 /* Test if there is available seconds */
165 if (p[0] < '0' || p[0] > '9')
166 goto nosec;
167 if (end - p < 2) return -1;
168 /* Add the seconds of the current minute */
169 epoch += 10 * (p[0] - '0') + p[1] - '0';
170 p += 2;
171 if (p == end) return -1;
172 /* Ignore seconds float part if present */
173 if (p[0] == '.') {
174 do {
175 if (++p == end) return -1;
176 } while (p[0] >= '0' && p[0] <= '9');
177 }
178
179nosec:
180 if (p[0] == 'Z') {
181 if (end - p != 1) return -1;
182 return epoch;
183 }
184 else if (p[0] == '+') {
185 if (end - p != 5) return -1;
186 /* Apply timezone offset */
187 return epoch - ((10 * (p[1] - '0') + p[2] - '0') * 60 + (10 * (p[3] - '0') + p[4] - '0')) * 60;
188 }
189 else if (p[0] == '-') {
190 if (end - p != 5) return -1;
191 /* Apply timezone offset */
192 return epoch + ((10 * (p[1] - '0') + p[2] - '0') * 60 + (10 * (p[3] - '0') + p[4] - '0')) * 60;
193 }
194
195 return -1;
196}
197
Emeric Brun1d3865b2014-06-20 15:37:32 +0200198static struct eb_root cert_ocsp_tree = EB_ROOT_UNIQUE;
Emeric Brun4147b2e2014-06-16 18:36:30 +0200199
200/* This function starts to check if the OCSP response (in DER format) contained
201 * in chunk 'ocsp_response' is valid (else exits on error).
202 * If 'cid' is not NULL, it will be compared to the OCSP certificate ID
203 * contained in the OCSP Response and exits on error if no match.
204 * If it's a valid OCSP Response:
205 * If 'ocsp' is not NULL, the chunk is copied in the OCSP response's container
206 * pointed by 'ocsp'.
207 * If 'ocsp' is NULL, the function looks up into the OCSP response's
208 * containers tree (using as index the ASN1 form of the OCSP Certificate ID extracted
209 * from the response) and exits on error if not found. Finally, If an OCSP response is
210 * already present in the container, it will be overwritten.
211 *
212 * Note: OCSP response containing more than one OCSP Single response is not
213 * considered valid.
214 *
215 * Returns 0 on success, 1 in error case.
216 */
217static int ssl_sock_load_ocsp_response(struct chunk *ocsp_response, struct certificate_ocsp *ocsp, OCSP_CERTID *cid, char **err)
218{
219 OCSP_RESPONSE *resp;
220 OCSP_BASICRESP *bs = NULL;
221 OCSP_SINGLERESP *sr;
222 unsigned char *p = (unsigned char *)ocsp_response->str;
223 int rc , count_sr;
Emeric Brun13a6b482014-06-20 15:44:34 +0200224 ASN1_GENERALIZEDTIME *revtime, *thisupd, *nextupd = NULL;
Emeric Brun4147b2e2014-06-16 18:36:30 +0200225 int reason;
226 int ret = 1;
227
228 resp = d2i_OCSP_RESPONSE(NULL, (const unsigned char **)&p, ocsp_response->len);
229 if (!resp) {
230 memprintf(err, "Unable to parse OCSP response");
231 goto out;
232 }
233
234 rc = OCSP_response_status(resp);
235 if (rc != OCSP_RESPONSE_STATUS_SUCCESSFUL) {
236 memprintf(err, "OCSP response status not successful");
237 goto out;
238 }
239
240 bs = OCSP_response_get1_basic(resp);
241 if (!bs) {
242 memprintf(err, "Failed to get basic response from OCSP Response");
243 goto out;
244 }
245
246 count_sr = OCSP_resp_count(bs);
247 if (count_sr > 1) {
248 memprintf(err, "OCSP response ignored because contains multiple single responses (%d)", count_sr);
249 goto out;
250 }
251
252 sr = OCSP_resp_get0(bs, 0);
253 if (!sr) {
254 memprintf(err, "Failed to get OCSP single response");
255 goto out;
256 }
257
258 rc = OCSP_single_get0_status(sr, &reason, &revtime, &thisupd, &nextupd);
259 if (rc != V_OCSP_CERTSTATUS_GOOD) {
260 memprintf(err, "OCSP single response: certificate status not good");
261 goto out;
262 }
263
Emeric Brun13a6b482014-06-20 15:44:34 +0200264 if (!nextupd) {
265 memprintf(err, "OCSP single response: missing nextupdate");
266 goto out;
267 }
268
Emeric Brunc8b27b62014-06-19 14:16:17 +0200269 rc = OCSP_check_validity(thisupd, nextupd, OCSP_MAX_RESPONSE_TIME_SKEW, -1);
Emeric Brun4147b2e2014-06-16 18:36:30 +0200270 if (!rc) {
271 memprintf(err, "OCSP single response: no longer valid.");
272 goto out;
273 }
274
275 if (cid) {
276 if (OCSP_id_cmp(sr->certId, cid)) {
277 memprintf(err, "OCSP single response: Certificate ID does not match certificate and issuer");
278 goto out;
279 }
280 }
281
282 if (!ocsp) {
283 unsigned char key[OCSP_MAX_CERTID_ASN1_LENGTH];
284 unsigned char *p;
285
286 rc = i2d_OCSP_CERTID(sr->certId, NULL);
287 if (!rc) {
288 memprintf(err, "OCSP single response: Unable to encode Certificate ID");
289 goto out;
290 }
291
292 if (rc > OCSP_MAX_CERTID_ASN1_LENGTH) {
293 memprintf(err, "OCSP single response: Certificate ID too long");
294 goto out;
295 }
296
297 p = key;
298 memset(key, 0, OCSP_MAX_CERTID_ASN1_LENGTH);
299 i2d_OCSP_CERTID(sr->certId, &p);
300 ocsp = (struct certificate_ocsp *)ebmb_lookup(&cert_ocsp_tree, key, OCSP_MAX_CERTID_ASN1_LENGTH);
301 if (!ocsp) {
302 memprintf(err, "OCSP single response: Certificate ID does not match any certificate or issuer");
303 goto out;
304 }
305 }
306
307 /* According to comments on "chunk_dup", the
308 previous chunk buffer will be freed */
309 if (!chunk_dup(&ocsp->response, ocsp_response)) {
310 memprintf(err, "OCSP response: Memory allocation error");
311 goto out;
312 }
313
Emeric Brun4f3c87a2014-06-20 15:46:13 +0200314 ocsp->expire = asn1_generalizedtime_to_epoch(nextupd) - OCSP_MAX_RESPONSE_TIME_SKEW;
315
Emeric Brun4147b2e2014-06-16 18:36:30 +0200316 ret = 0;
317out:
318 if (bs)
319 OCSP_BASICRESP_free(bs);
320
321 if (resp)
322 OCSP_RESPONSE_free(resp);
323
324 return ret;
325}
326/*
327 * External function use to update the OCSP response in the OCSP response's
328 * containers tree. The chunk 'ocsp_response' must contain the OCSP response
329 * to update in DER format.
330 *
331 * Returns 0 on success, 1 in error case.
332 */
333int ssl_sock_update_ocsp_response(struct chunk *ocsp_response, char **err)
334{
335 return ssl_sock_load_ocsp_response(ocsp_response, NULL, NULL, err);
336}
337
338/*
339 * This function load the OCSP Resonse in DER format contained in file at
340 * path 'ocsp_path' and call 'ssl_sock_load_ocsp_response'
341 *
342 * Returns 0 on success, 1 in error case.
343 */
344static int ssl_sock_load_ocsp_response_from_file(const char *ocsp_path, struct certificate_ocsp *ocsp, OCSP_CERTID *cid, char **err)
345{
346 int fd = -1;
347 int r = 0;
348 int ret = 1;
349
350 fd = open(ocsp_path, O_RDONLY);
351 if (fd == -1) {
352 memprintf(err, "Error opening OCSP response file");
353 goto end;
354 }
355
356 trash.len = 0;
357 while (trash.len < trash.size) {
358 r = read(fd, trash.str + trash.len, trash.size - trash.len);
359 if (r < 0) {
360 if (errno == EINTR)
361 continue;
362
363 memprintf(err, "Error reading OCSP response from file");
364 goto end;
365 }
366 else if (r == 0) {
367 break;
368 }
369 trash.len += r;
370 }
371
372 close(fd);
373 fd = -1;
374
375 ret = ssl_sock_load_ocsp_response(&trash, ocsp, cid, err);
376end:
377 if (fd != -1)
378 close(fd);
379
380 return ret;
381}
382
383/*
384 * Callback used to set OCSP status extension content in server hello.
385 */
386int ssl_sock_ocsp_stapling_cbk(SSL *ssl, void *arg)
387{
388 struct certificate_ocsp *ocsp = (struct certificate_ocsp *)arg;
389 char* ssl_buf;
390
391 if (!ocsp ||
392 !ocsp->response.str ||
Emeric Brun4f3c87a2014-06-20 15:46:13 +0200393 !ocsp->response.len ||
394 (ocsp->expire < now.tv_sec))
Emeric Brun4147b2e2014-06-16 18:36:30 +0200395 return SSL_TLSEXT_ERR_NOACK;
396
397 ssl_buf = OPENSSL_malloc(ocsp->response.len);
398 if (!ssl_buf)
399 return SSL_TLSEXT_ERR_NOACK;
400
401 memcpy(ssl_buf, ocsp->response.str, ocsp->response.len);
402 SSL_set_tlsext_status_ocsp_resp(ssl, ssl_buf, ocsp->response.len);
403
404 return SSL_TLSEXT_ERR_OK;
405}
406
407/*
408 * This function enables the handling of OCSP status extension on 'ctx' if a
409 * file name 'cert_path' suffixed using ".ocsp" is present.
410 * To enable OCSP status extension, the issuer's certificate is mandatory.
411 * It should be present in the certificate's extra chain builded from file
412 * 'cert_path'. If not found, the issuer certificate is loaded from a file
413 * named 'cert_path' suffixed using '.issuer'.
414 *
415 * In addition, ".ocsp" file content is loaded as a DER format of an OCSP
416 * response. If file is empty or content is not a valid OCSP response,
417 * OCSP status extension is enabled but OCSP response is ignored (a warning
418 * is displayed).
419 *
420 * Returns 1 if no ".ocsp" file found, 0 if OCSP status extension is
421 * succesfully enabled, or -1 in other error case.
422 */
423static int ssl_sock_load_ocsp(SSL_CTX *ctx, const char *cert_path)
424{
425
426 BIO *in = NULL;
427 X509 *x, *xi = NULL, *issuer = NULL;
428 STACK_OF(X509) *chain = NULL;
429 OCSP_CERTID *cid = NULL;
430 SSL *ssl;
431 char ocsp_path[MAXPATHLEN+1];
432 int i, ret = -1;
433 struct stat st;
434 struct certificate_ocsp *ocsp = NULL, *iocsp;
435 char *warn = NULL;
436 unsigned char *p;
437
438 snprintf(ocsp_path, MAXPATHLEN+1, "%s.ocsp", cert_path);
439
440 if (stat(ocsp_path, &st))
441 return 1;
442
443 ssl = SSL_new(ctx);
444 if (!ssl)
445 goto out;
446
447 x = SSL_get_certificate(ssl);
448 if (!x)
449 goto out;
450
451 /* Try to lookup for issuer in certificate extra chain */
452#ifdef SSL_CTRL_GET_EXTRA_CHAIN_CERTS
453 SSL_CTX_get_extra_chain_certs(ctx, &chain);
454#else
455 chain = ctx->extra_certs;
456#endif
457 for (i = 0; i < sk_X509_num(chain); i++) {
458 issuer = sk_X509_value(chain, i);
459 if (X509_check_issued(issuer, x) == X509_V_OK)
460 break;
461 else
462 issuer = NULL;
463 }
464
465 /* If not found try to load issuer from a suffixed file */
466 if (!issuer) {
467 char issuer_path[MAXPATHLEN+1];
468
469 in = BIO_new(BIO_s_file());
470 if (!in)
471 goto out;
472
473 snprintf(issuer_path, MAXPATHLEN+1, "%s.issuer", cert_path);
474 if (BIO_read_filename(in, issuer_path) <= 0)
475 goto out;
476
477 xi = PEM_read_bio_X509_AUX(in, NULL, ctx->default_passwd_callback, ctx->default_passwd_callback_userdata);
478 if (!xi)
479 goto out;
480
481 if (X509_check_issued(xi, x) != X509_V_OK)
482 goto out;
483
484 issuer = xi;
485 }
486
487 cid = OCSP_cert_to_id(0, x, issuer);
488 if (!cid)
489 goto out;
490
491 i = i2d_OCSP_CERTID(cid, NULL);
492 if (!i || (i > OCSP_MAX_CERTID_ASN1_LENGTH))
493 goto out;
494
495 ocsp = calloc(1, sizeof(struct certificate_ocsp));
496 if (!ocsp)
497 goto out;
498
499 p = ocsp->key_data;
500 i2d_OCSP_CERTID(cid, &p);
501
502 iocsp = (struct certificate_ocsp *)ebmb_insert(&cert_ocsp_tree, &ocsp->key, OCSP_MAX_CERTID_ASN1_LENGTH);
503 if (iocsp == ocsp)
504 ocsp = NULL;
505
506 SSL_CTX_set_tlsext_status_cb(ctx, ssl_sock_ocsp_stapling_cbk);
507 SSL_CTX_set_tlsext_status_arg(ctx, iocsp);
508
509 ret = 0;
510
511 warn = NULL;
512 if (ssl_sock_load_ocsp_response_from_file(ocsp_path, iocsp, cid, &warn)) {
513 memprintf(&warn, "Loading '%s': %s. Content will be ignored", ocsp_path, warn ? warn : "failure");
514 Warning("%s.\n", warn);
515 }
516
517out:
518 if (ssl)
519 SSL_free(ssl);
520
521 if (in)
522 BIO_free(in);
523
524 if (xi)
525 X509_free(xi);
526
527 if (cid)
528 OCSP_CERTID_free(cid);
529
530 if (ocsp)
531 free(ocsp);
532
533 if (warn)
534 free(warn);
535
536
537 return ret;
538}
539
540#endif
541
Emeric Brune1f38db2012-09-03 20:36:47 +0200542void ssl_sock_infocbk(const SSL *ssl, int where, int ret)
543{
544 struct connection *conn = (struct connection *)SSL_get_app_data(ssl);
545 (void)ret; /* shut gcc stupid warning */
Emeric Brund8b2bb52014-01-28 15:43:53 +0100546 BIO *write_bio;
Emeric Brune1f38db2012-09-03 20:36:47 +0200547
548 if (where & SSL_CB_HANDSHAKE_START) {
549 /* Disable renegotiation (CVE-2009-3555) */
Willy Tarreau20879a02012-12-03 16:32:10 +0100550 if (conn->flags & CO_FL_CONNECTED) {
Emeric Brune1f38db2012-09-03 20:36:47 +0200551 conn->flags |= CO_FL_ERROR;
Willy Tarreau20879a02012-12-03 16:32:10 +0100552 conn->err_code = CO_ER_SSL_RENEG;
553 }
Emeric Brune1f38db2012-09-03 20:36:47 +0200554 }
Emeric Brund8b2bb52014-01-28 15:43:53 +0100555
556 if ((where & SSL_CB_ACCEPT_LOOP) == SSL_CB_ACCEPT_LOOP) {
557 if (!(conn->xprt_st & SSL_SOCK_ST_FL_16K_WBFSIZE)) {
558 /* Long certificate chains optimz
559 If write and read bios are differents, we
560 consider that the buffering was activated,
561 so we rise the output buffer size from 4k
562 to 16k */
563 write_bio = SSL_get_wbio(ssl);
564 if (write_bio != SSL_get_rbio(ssl)) {
565 BIO_set_write_buffer_size(write_bio, 16384);
566 conn->xprt_st |= SSL_SOCK_ST_FL_16K_WBFSIZE;
567 }
568 }
569 }
Emeric Brunfc0421f2012-09-07 17:30:07 +0200570}
571
Emeric Brune64aef12012-09-21 13:15:06 +0200572/* Callback is called for each certificate of the chain during a verify
573 ok is set to 1 if preverify detect no error on current certificate.
574 Returns 0 to break the handshake, 1 otherwise. */
Evan Broderbe554312013-06-27 00:05:25 -0700575int ssl_sock_bind_verifycbk(int ok, X509_STORE_CTX *x_store)
Emeric Brune64aef12012-09-21 13:15:06 +0200576{
577 SSL *ssl;
578 struct connection *conn;
Emeric Brun81c00f02012-09-21 14:31:21 +0200579 int err, depth;
Emeric Brune64aef12012-09-21 13:15:06 +0200580
581 ssl = X509_STORE_CTX_get_ex_data(x_store, SSL_get_ex_data_X509_STORE_CTX_idx());
582 conn = (struct connection *)SSL_get_app_data(ssl);
583
Willy Tarreauf7bc57c2012-10-03 00:19:48 +0200584 conn->xprt_st |= SSL_SOCK_ST_FL_VERIFY_DONE;
Emeric Brune64aef12012-09-21 13:15:06 +0200585
Emeric Brun81c00f02012-09-21 14:31:21 +0200586 if (ok) /* no errors */
587 return ok;
588
589 depth = X509_STORE_CTX_get_error_depth(x_store);
590 err = X509_STORE_CTX_get_error(x_store);
591
592 /* check if CA error needs to be ignored */
593 if (depth > 0) {
Willy Tarreauf7bc57c2012-10-03 00:19:48 +0200594 if (!SSL_SOCK_ST_TO_CA_ERROR(conn->xprt_st)) {
595 conn->xprt_st |= SSL_SOCK_CA_ERROR_TO_ST(err);
596 conn->xprt_st |= SSL_SOCK_CAEDEPTH_TO_ST(depth);
Emeric Brunf282a812012-09-21 15:27:54 +0200597 }
598
Emeric Brun1eb20ef2012-12-03 13:24:29 +0100599 if (objt_listener(conn->target)->bind_conf->ca_ignerr & (1ULL << err)) {
600 ERR_clear_error();
Emeric Brun81c00f02012-09-21 14:31:21 +0200601 return 1;
Emeric Brun1eb20ef2012-12-03 13:24:29 +0100602 }
Emeric Brun81c00f02012-09-21 14:31:21 +0200603
Willy Tarreau20879a02012-12-03 16:32:10 +0100604 conn->err_code = CO_ER_SSL_CA_FAIL;
Emeric Brun81c00f02012-09-21 14:31:21 +0200605 return 0;
606 }
607
Willy Tarreauf7bc57c2012-10-03 00:19:48 +0200608 if (!SSL_SOCK_ST_TO_CRTERROR(conn->xprt_st))
609 conn->xprt_st |= SSL_SOCK_CRTERROR_TO_ST(err);
Emeric Brunf282a812012-09-21 15:27:54 +0200610
Emeric Brun81c00f02012-09-21 14:31:21 +0200611 /* check if certificate error needs to be ignored */
Emeric Brun1eb20ef2012-12-03 13:24:29 +0100612 if (objt_listener(conn->target)->bind_conf->crt_ignerr & (1ULL << err)) {
613 ERR_clear_error();
Emeric Brun81c00f02012-09-21 14:31:21 +0200614 return 1;
Emeric Brun1eb20ef2012-12-03 13:24:29 +0100615 }
Emeric Brun81c00f02012-09-21 14:31:21 +0200616
Willy Tarreau20879a02012-12-03 16:32:10 +0100617 conn->err_code = CO_ER_SSL_CRT_FAIL;
Emeric Brun81c00f02012-09-21 14:31:21 +0200618 return 0;
Emeric Brune64aef12012-09-21 13:15:06 +0200619}
620
Emeric Brun29f037d2014-04-25 19:05:36 +0200621/* Callback is called for ssl protocol analyse */
622void ssl_sock_msgcbk(int write_p, int version, int content_type, const void *buf, size_t len, SSL *ssl, void *arg)
623{
Emeric Brun29f037d2014-04-25 19:05:36 +0200624#ifdef TLS1_RT_HEARTBEAT
625 /* test heartbeat received (write_p is set to 0
626 for a received record) */
Willy Tarreauf51c6982014-04-25 20:02:39 +0200627 if ((content_type == TLS1_RT_HEARTBEAT) && (write_p == 0)) {
Willy Tarreau84815002014-04-25 21:40:27 +0200628 struct connection *conn = (struct connection *)SSL_get_app_data(ssl);
Willy Tarreauf51c6982014-04-25 20:02:39 +0200629 const unsigned char *p = buf;
630 unsigned int payload;
631
Emeric Brun29f037d2014-04-25 19:05:36 +0200632 conn->xprt_st |= SSL_SOCK_RECV_HEARTBEAT;
Willy Tarreauf51c6982014-04-25 20:02:39 +0200633
634 /* Check if this is a CVE-2014-0160 exploitation attempt. */
635 if (*p != TLS1_HB_REQUEST)
636 return;
637
Willy Tarreauaeed6722014-04-25 23:59:58 +0200638 if (len < 1 + 2 + 16) /* 1 type + 2 size + 0 payload + 16 padding */
Willy Tarreauf51c6982014-04-25 20:02:39 +0200639 goto kill_it;
640
641 payload = (p[1] * 256) + p[2];
Willy Tarreau3b2fdb62014-04-25 23:44:22 +0200642 if (3 + payload + 16 <= len)
Willy Tarreauf51c6982014-04-25 20:02:39 +0200643 return; /* OK no problem */
Willy Tarreauaeed6722014-04-25 23:59:58 +0200644 kill_it:
Willy Tarreau3b2fdb62014-04-25 23:44:22 +0200645 /* We have a clear heartbleed attack (CVE-2014-0160), the
646 * advertised payload is larger than the advertised packet
647 * length, so we have garbage in the buffer between the
648 * payload and the end of the buffer (p+len). We can't know
649 * if the SSL stack is patched, and we don't know if we can
650 * safely wipe out the area between p+3+len and payload.
651 * So instead, we prevent the response from being sent by
652 * setting the max_send_fragment to 0 and we report an SSL
653 * error, which will kill this connection. It will be reported
654 * above as SSL_ERROR_SSL while an other handshake failure with
Willy Tarreauf51c6982014-04-25 20:02:39 +0200655 * a heartbeat message will be reported as SSL_ERROR_SYSCALL.
656 */
Willy Tarreau3b2fdb62014-04-25 23:44:22 +0200657 ssl->max_send_fragment = 0;
Willy Tarreauf51c6982014-04-25 20:02:39 +0200658 SSLerr(SSL_F_TLS1_HEARTBEAT, SSL_R_SSL_HANDSHAKE_FAILURE);
659 return;
660 }
Emeric Brun29f037d2014-04-25 19:05:36 +0200661#endif
662}
663
Willy Tarreau6c9a3d52012-10-18 18:57:14 +0200664#ifdef OPENSSL_NPN_NEGOTIATED
665/* This callback is used so that the server advertises the list of
666 * negociable protocols for NPN.
667 */
668static int ssl_sock_advertise_npn_protos(SSL *s, const unsigned char **data,
669 unsigned int *len, void *arg)
670{
671 struct bind_conf *conf = arg;
672
673 *data = (const unsigned char *)conf->npn_str;
674 *len = conf->npn_len;
675 return SSL_TLSEXT_ERR_OK;
676}
677#endif
678
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +0100679#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Willy Tarreauab861d32013-04-02 02:30:41 +0200680/* This callback is used so that the server advertises the list of
681 * negociable protocols for ALPN.
682 */
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +0100683static int ssl_sock_advertise_alpn_protos(SSL *s, const unsigned char **out,
684 unsigned char *outlen,
685 const unsigned char *server,
686 unsigned int server_len, void *arg)
Willy Tarreauab861d32013-04-02 02:30:41 +0200687{
688 struct bind_conf *conf = arg;
689
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +0100690 if (SSL_select_next_proto((unsigned char**) out, outlen, (const unsigned char *)conf->alpn_str,
691 conf->alpn_len, server, server_len) != OPENSSL_NPN_NEGOTIATED) {
692 return SSL_TLSEXT_ERR_NOACK;
693 }
Willy Tarreauab861d32013-04-02 02:30:41 +0200694 return SSL_TLSEXT_ERR_OK;
695}
696#endif
697
Emeric Brunfc0421f2012-09-07 17:30:07 +0200698#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
699/* Sets the SSL ctx of <ssl> to match the advertised server name. Returns a
700 * warning when no match is found, which implies the default (first) cert
701 * will keep being used.
702 */
Willy Tarreau2a65ff02012-09-13 17:54:29 +0200703static int ssl_sock_switchctx_cbk(SSL *ssl, int *al, struct bind_conf *s)
Emeric Brunfc0421f2012-09-07 17:30:07 +0200704{
705 const char *servername;
706 const char *wildp = NULL;
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +0200707 struct ebmb_node *node, *n;
Emeric Brunfc0421f2012-09-07 17:30:07 +0200708 int i;
709 (void)al; /* shut gcc stupid warning */
710
711 servername = SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name);
Emmanuel Hocdet65623372013-01-24 17:17:15 +0100712 if (!servername) {
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +0200713 return (s->strict_sni ?
714 SSL_TLSEXT_ERR_ALERT_FATAL :
Emmanuel Hocdet79274e22013-05-31 12:47:44 +0200715 SSL_TLSEXT_ERR_NOACK);
Emmanuel Hocdet65623372013-01-24 17:17:15 +0100716 }
Emeric Brunfc0421f2012-09-07 17:30:07 +0200717
Willy Tarreau19d14ef2012-10-29 16:51:55 +0100718 for (i = 0; i < trash.size; i++) {
Emeric Brunfc0421f2012-09-07 17:30:07 +0200719 if (!servername[i])
720 break;
Willy Tarreau19d14ef2012-10-29 16:51:55 +0100721 trash.str[i] = tolower(servername[i]);
722 if (!wildp && (trash.str[i] == '.'))
723 wildp = &trash.str[i];
Emeric Brunfc0421f2012-09-07 17:30:07 +0200724 }
Willy Tarreau19d14ef2012-10-29 16:51:55 +0100725 trash.str[i] = 0;
Emeric Brunfc0421f2012-09-07 17:30:07 +0200726
727 /* lookup in full qualified names */
Willy Tarreau19d14ef2012-10-29 16:51:55 +0100728 node = ebst_lookup(&s->sni_ctx, trash.str);
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +0200729
730 /* lookup a not neg filter */
731 for (n = node; n; n = ebmb_next_dup(n)) {
732 if (!container_of(n, struct sni_ctx, name)->neg) {
733 node = n;
734 break;
Emmanuel Hocdet65623372013-01-24 17:17:15 +0100735 }
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +0200736 }
737 if (!node && wildp) {
738 /* lookup in wildcards names */
Emeric Brunfc0421f2012-09-07 17:30:07 +0200739 node = ebst_lookup(&s->sni_w_ctx, wildp);
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +0200740 }
741 if (!node || container_of(node, struct sni_ctx, name)->neg) {
742 return (s->strict_sni ?
743 SSL_TLSEXT_ERR_ALERT_FATAL :
744 SSL_TLSEXT_ERR_ALERT_WARNING);
Emeric Brunfc0421f2012-09-07 17:30:07 +0200745 }
746
747 /* switch ctx */
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +0200748 SSL_set_SSL_CTX(ssl, container_of(node, struct sni_ctx, name)->ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +0200749 return SSL_TLSEXT_ERR_OK;
750}
751#endif /* SSL_CTRL_SET_TLSEXT_HOSTNAME */
752
Emeric Bruna4bcd9a2012-09-20 16:19:02 +0200753#ifndef OPENSSL_NO_DH
Remi Gacognef46cd6e2014-06-12 14:58:40 +0200754
755static DH * ssl_get_dh_1024(void)
756{
757#if OPENSSL_VERSION_NUMBER < 0x0090801fL
758 static const unsigned char rfc_2409_prime_1024[] = {
759 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xC9,0x0F,0xDA,0xA2,
760 0x21,0x68,0xC2,0x34,0xC4,0xC6,0x62,0x8B,0x80,0xDC,0x1C,0xD1,
761 0x29,0x02,0x4E,0x08,0x8A,0x67,0xCC,0x74,0x02,0x0B,0xBE,0xA6,
762 0x3B,0x13,0x9B,0x22,0x51,0x4A,0x08,0x79,0x8E,0x34,0x04,0xDD,
763 0xEF,0x95,0x19,0xB3,0xCD,0x3A,0x43,0x1B,0x30,0x2B,0x0A,0x6D,
764 0xF2,0x5F,0x14,0x37,0x4F,0xE1,0x35,0x6D,0x6D,0x51,0xC2,0x45,
765 0xE4,0x85,0xB5,0x76,0x62,0x5E,0x7E,0xC6,0xF4,0x4C,0x42,0xE9,
766 0xA6,0x37,0xED,0x6B,0x0B,0xFF,0x5C,0xB6,0xF4,0x06,0xB7,0xED,
767 0xEE,0x38,0x6B,0xFB,0x5A,0x89,0x9F,0xA5,0xAE,0x9F,0x24,0x11,
768 0x7C,0x4B,0x1F,0xE6,0x49,0x28,0x66,0x51,0xEC,0xE6,0x53,0x81,
769 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
770 };
771#endif
772 DH *dh = DH_new();
773 if (dh) {
774#if OPENSSL_VERSION_NUMBER >= 0x0090801fL
775 dh->p = get_rfc2409_prime_1024(NULL);
776#else
777 dh->p = BN_bin2bn(rfc_2409_prime_1024, sizeof rfc_2409_prime_1024, NULL);
778#endif
779 /* See RFC 2409, Section 6 "Oakley Groups"
780 for the reason why 2 is used as generator.
781 */
782 BN_dec2bn(&dh->g, "2");
783 if (!dh->p || !dh->g) {
784 DH_free(dh);
785 dh = NULL;
786 }
787 }
788 return dh;
789}
790
791static DH *ssl_get_dh_2048(void)
792{
793#if OPENSSL_VERSION_NUMBER < 0x0090801fL
794 static const unsigned char rfc_3526_prime_2048[] = {
795 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xC9,0x0F,0xDA,0xA2,
796 0x21,0x68,0xC2,0x34,0xC4,0xC6,0x62,0x8B,0x80,0xDC,0x1C,0xD1,
797 0x29,0x02,0x4E,0x08,0x8A,0x67,0xCC,0x74,0x02,0x0B,0xBE,0xA6,
798 0x3B,0x13,0x9B,0x22,0x51,0x4A,0x08,0x79,0x8E,0x34,0x04,0xDD,
799 0xEF,0x95,0x19,0xB3,0xCD,0x3A,0x43,0x1B,0x30,0x2B,0x0A,0x6D,
800 0xF2,0x5F,0x14,0x37,0x4F,0xE1,0x35,0x6D,0x6D,0x51,0xC2,0x45,
801 0xE4,0x85,0xB5,0x76,0x62,0x5E,0x7E,0xC6,0xF4,0x4C,0x42,0xE9,
802 0xA6,0x37,0xED,0x6B,0x0B,0xFF,0x5C,0xB6,0xF4,0x06,0xB7,0xED,
803 0xEE,0x38,0x6B,0xFB,0x5A,0x89,0x9F,0xA5,0xAE,0x9F,0x24,0x11,
804 0x7C,0x4B,0x1F,0xE6,0x49,0x28,0x66,0x51,0xEC,0xE4,0x5B,0x3D,
805 0xC2,0x00,0x7C,0xB8,0xA1,0x63,0xBF,0x05,0x98,0xDA,0x48,0x36,
806 0x1C,0x55,0xD3,0x9A,0x69,0x16,0x3F,0xA8,0xFD,0x24,0xCF,0x5F,
807 0x83,0x65,0x5D,0x23,0xDC,0xA3,0xAD,0x96,0x1C,0x62,0xF3,0x56,
808 0x20,0x85,0x52,0xBB,0x9E,0xD5,0x29,0x07,0x70,0x96,0x96,0x6D,
809 0x67,0x0C,0x35,0x4E,0x4A,0xBC,0x98,0x04,0xF1,0x74,0x6C,0x08,
810 0xCA,0x18,0x21,0x7C,0x32,0x90,0x5E,0x46,0x2E,0x36,0xCE,0x3B,
811 0xE3,0x9E,0x77,0x2C,0x18,0x0E,0x86,0x03,0x9B,0x27,0x83,0xA2,
812 0xEC,0x07,0xA2,0x8F,0xB5,0xC5,0x5D,0xF0,0x6F,0x4C,0x52,0xC9,
813 0xDE,0x2B,0xCB,0xF6,0x95,0x58,0x17,0x18,0x39,0x95,0x49,0x7C,
814 0xEA,0x95,0x6A,0xE5,0x15,0xD2,0x26,0x18,0x98,0xFA,0x05,0x10,
815 0x15,0x72,0x8E,0x5A,0x8A,0xAC,0xAA,0x68,0xFF,0xFF,0xFF,0xFF,
816 0xFF,0xFF,0xFF,0xFF,
817 };
818#endif
819 DH *dh = DH_new();
820 if (dh) {
821#if OPENSSL_VERSION_NUMBER >= 0x0090801fL
822 dh->p = get_rfc3526_prime_2048(NULL);
823#else
824 dh->p = BN_bin2bn(rfc_3526_prime_2048, sizeof rfc_3526_prime_2048, NULL);
825#endif
826 /* See RFC 3526, Section 3 "2048-bit MODP Group"
827 for the reason why 2 is used as generator.
828 */
829 BN_dec2bn(&dh->g, "2");
830 if (!dh->p || !dh->g) {
831 DH_free(dh);
832 dh = NULL;
833 }
834 }
835 return dh;
836}
837
838static DH *ssl_get_dh_4096(void)
839{
840#if OPENSSL_VERSION_NUMBER < 0x0090801fL
841 static const unsigned char rfc_3526_prime_4096[] = {
842 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xC9,0x0F,0xDA,0xA2,
843 0x21,0x68,0xC2,0x34,0xC4,0xC6,0x62,0x8B,0x80,0xDC,0x1C,0xD1,
844 0x29,0x02,0x4E,0x08,0x8A,0x67,0xCC,0x74,0x02,0x0B,0xBE,0xA6,
845 0x3B,0x13,0x9B,0x22,0x51,0x4A,0x08,0x79,0x8E,0x34,0x04,0xDD,
846 0xEF,0x95,0x19,0xB3,0xCD,0x3A,0x43,0x1B,0x30,0x2B,0x0A,0x6D,
847 0xF2,0x5F,0x14,0x37,0x4F,0xE1,0x35,0x6D,0x6D,0x51,0xC2,0x45,
848 0xE4,0x85,0xB5,0x76,0x62,0x5E,0x7E,0xC6,0xF4,0x4C,0x42,0xE9,
849 0xA6,0x37,0xED,0x6B,0x0B,0xFF,0x5C,0xB6,0xF4,0x06,0xB7,0xED,
850 0xEE,0x38,0x6B,0xFB,0x5A,0x89,0x9F,0xA5,0xAE,0x9F,0x24,0x11,
851 0x7C,0x4B,0x1F,0xE6,0x49,0x28,0x66,0x51,0xEC,0xE4,0x5B,0x3D,
852 0xC2,0x00,0x7C,0xB8,0xA1,0x63,0xBF,0x05,0x98,0xDA,0x48,0x36,
853 0x1C,0x55,0xD3,0x9A,0x69,0x16,0x3F,0xA8,0xFD,0x24,0xCF,0x5F,
854 0x83,0x65,0x5D,0x23,0xDC,0xA3,0xAD,0x96,0x1C,0x62,0xF3,0x56,
855 0x20,0x85,0x52,0xBB,0x9E,0xD5,0x29,0x07,0x70,0x96,0x96,0x6D,
856 0x67,0x0C,0x35,0x4E,0x4A,0xBC,0x98,0x04,0xF1,0x74,0x6C,0x08,
857 0xCA,0x18,0x21,0x7C,0x32,0x90,0x5E,0x46,0x2E,0x36,0xCE,0x3B,
858 0xE3,0x9E,0x77,0x2C,0x18,0x0E,0x86,0x03,0x9B,0x27,0x83,0xA2,
859 0xEC,0x07,0xA2,0x8F,0xB5,0xC5,0x5D,0xF0,0x6F,0x4C,0x52,0xC9,
860 0xDE,0x2B,0xCB,0xF6,0x95,0x58,0x17,0x18,0x39,0x95,0x49,0x7C,
861 0xEA,0x95,0x6A,0xE5,0x15,0xD2,0x26,0x18,0x98,0xFA,0x05,0x10,
862 0x15,0x72,0x8E,0x5A,0x8A,0xAA,0xC4,0x2D,0xAD,0x33,0x17,0x0D,
863 0x04,0x50,0x7A,0x33,0xA8,0x55,0x21,0xAB,0xDF,0x1C,0xBA,0x64,
864 0xEC,0xFB,0x85,0x04,0x58,0xDB,0xEF,0x0A,0x8A,0xEA,0x71,0x57,
865 0x5D,0x06,0x0C,0x7D,0xB3,0x97,0x0F,0x85,0xA6,0xE1,0xE4,0xC7,
866 0xAB,0xF5,0xAE,0x8C,0xDB,0x09,0x33,0xD7,0x1E,0x8C,0x94,0xE0,
867 0x4A,0x25,0x61,0x9D,0xCE,0xE3,0xD2,0x26,0x1A,0xD2,0xEE,0x6B,
868 0xF1,0x2F,0xFA,0x06,0xD9,0x8A,0x08,0x64,0xD8,0x76,0x02,0x73,
869 0x3E,0xC8,0x6A,0x64,0x52,0x1F,0x2B,0x18,0x17,0x7B,0x20,0x0C,
870 0xBB,0xE1,0x17,0x57,0x7A,0x61,0x5D,0x6C,0x77,0x09,0x88,0xC0,
871 0xBA,0xD9,0x46,0xE2,0x08,0xE2,0x4F,0xA0,0x74,0xE5,0xAB,0x31,
872 0x43,0xDB,0x5B,0xFC,0xE0,0xFD,0x10,0x8E,0x4B,0x82,0xD1,0x20,
873 0xA9,0x21,0x08,0x01,0x1A,0x72,0x3C,0x12,0xA7,0x87,0xE6,0xD7,
874 0x88,0x71,0x9A,0x10,0xBD,0xBA,0x5B,0x26,0x99,0xC3,0x27,0x18,
875 0x6A,0xF4,0xE2,0x3C,0x1A,0x94,0x68,0x34,0xB6,0x15,0x0B,0xDA,
876 0x25,0x83,0xE9,0xCA,0x2A,0xD4,0x4C,0xE8,0xDB,0xBB,0xC2,0xDB,
877 0x04,0xDE,0x8E,0xF9,0x2E,0x8E,0xFC,0x14,0x1F,0xBE,0xCA,0xA6,
878 0x28,0x7C,0x59,0x47,0x4E,0x6B,0xC0,0x5D,0x99,0xB2,0x96,0x4F,
879 0xA0,0x90,0xC3,0xA2,0x23,0x3B,0xA1,0x86,0x51,0x5B,0xE7,0xED,
880 0x1F,0x61,0x29,0x70,0xCE,0xE2,0xD7,0xAF,0xB8,0x1B,0xDD,0x76,
881 0x21,0x70,0x48,0x1C,0xD0,0x06,0x91,0x27,0xD5,0xB0,0x5A,0xA9,
882 0x93,0xB4,0xEA,0x98,0x8D,0x8F,0xDD,0xC1,0x86,0xFF,0xB7,0xDC,
883 0x90,0xA6,0xC0,0x8F,0x4D,0xF4,0x35,0xC9,0x34,0x06,0x31,0x99,
884 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
885 };
886#endif
887 DH *dh = DH_new();
888 if (dh) {
889#if OPENSSL_VERSION_NUMBER >= 0x0090801fL
890 dh->p = get_rfc3526_prime_4096(NULL);
891#else
892 dh->p = BN_bin2bn(rfc_3526_prime_4096, sizeof rfc_3526_prime_4096, NULL);
893#endif
894 /* See RFC 3526, Section 5 "4096-bit MODP Group"
895 for the reason why 2 is used as generator.
896 */
897 BN_dec2bn(&dh->g, "2");
898 if (!dh->p || !dh->g) {
899 DH_free(dh);
900 dh = NULL;
901 }
902 }
903 return dh;
904}
905
906static DH *ssl_get_dh_8192(void)
907{
908#if OPENSSL_VERSION_NUMBER < 0x0090801fL
909 static const unsigned char rfc_3526_prime_8192[] = {
910 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xC9,0x0F,0xDA,0xA2,
911 0x21,0x68,0xC2,0x34,0xC4,0xC6,0x62,0x8B,0x80,0xDC,0x1C,0xD1,
912 0x29,0x02,0x4E,0x08,0x8A,0x67,0xCC,0x74,0x02,0x0B,0xBE,0xA6,
913 0x3B,0x13,0x9B,0x22,0x51,0x4A,0x08,0x79,0x8E,0x34,0x04,0xDD,
914 0xEF,0x95,0x19,0xB3,0xCD,0x3A,0x43,0x1B,0x30,0x2B,0x0A,0x6D,
915 0xF2,0x5F,0x14,0x37,0x4F,0xE1,0x35,0x6D,0x6D,0x51,0xC2,0x45,
916 0xE4,0x85,0xB5,0x76,0x62,0x5E,0x7E,0xC6,0xF4,0x4C,0x42,0xE9,
917 0xA6,0x37,0xED,0x6B,0x0B,0xFF,0x5C,0xB6,0xF4,0x06,0xB7,0xED,
918 0xEE,0x38,0x6B,0xFB,0x5A,0x89,0x9F,0xA5,0xAE,0x9F,0x24,0x11,
919 0x7C,0x4B,0x1F,0xE6,0x49,0x28,0x66,0x51,0xEC,0xE4,0x5B,0x3D,
920 0xC2,0x00,0x7C,0xB8,0xA1,0x63,0xBF,0x05,0x98,0xDA,0x48,0x36,
921 0x1C,0x55,0xD3,0x9A,0x69,0x16,0x3F,0xA8,0xFD,0x24,0xCF,0x5F,
922 0x83,0x65,0x5D,0x23,0xDC,0xA3,0xAD,0x96,0x1C,0x62,0xF3,0x56,
923 0x20,0x85,0x52,0xBB,0x9E,0xD5,0x29,0x07,0x70,0x96,0x96,0x6D,
924 0x67,0x0C,0x35,0x4E,0x4A,0xBC,0x98,0x04,0xF1,0x74,0x6C,0x08,
925 0xCA,0x18,0x21,0x7C,0x32,0x90,0x5E,0x46,0x2E,0x36,0xCE,0x3B,
926 0xE3,0x9E,0x77,0x2C,0x18,0x0E,0x86,0x03,0x9B,0x27,0x83,0xA2,
927 0xEC,0x07,0xA2,0x8F,0xB5,0xC5,0x5D,0xF0,0x6F,0x4C,0x52,0xC9,
928 0xDE,0x2B,0xCB,0xF6,0x95,0x58,0x17,0x18,0x39,0x95,0x49,0x7C,
929 0xEA,0x95,0x6A,0xE5,0x15,0xD2,0x26,0x18,0x98,0xFA,0x05,0x10,
930 0x15,0x72,0x8E,0x5A,0x8A,0xAA,0xC4,0x2D,0xAD,0x33,0x17,0x0D,
931 0x04,0x50,0x7A,0x33,0xA8,0x55,0x21,0xAB,0xDF,0x1C,0xBA,0x64,
932 0xEC,0xFB,0x85,0x04,0x58,0xDB,0xEF,0x0A,0x8A,0xEA,0x71,0x57,
933 0x5D,0x06,0x0C,0x7D,0xB3,0x97,0x0F,0x85,0xA6,0xE1,0xE4,0xC7,
934 0xAB,0xF5,0xAE,0x8C,0xDB,0x09,0x33,0xD7,0x1E,0x8C,0x94,0xE0,
935 0x4A,0x25,0x61,0x9D,0xCE,0xE3,0xD2,0x26,0x1A,0xD2,0xEE,0x6B,
936 0xF1,0x2F,0xFA,0x06,0xD9,0x8A,0x08,0x64,0xD8,0x76,0x02,0x73,
937 0x3E,0xC8,0x6A,0x64,0x52,0x1F,0x2B,0x18,0x17,0x7B,0x20,0x0C,
938 0xBB,0xE1,0x17,0x57,0x7A,0x61,0x5D,0x6C,0x77,0x09,0x88,0xC0,
939 0xBA,0xD9,0x46,0xE2,0x08,0xE2,0x4F,0xA0,0x74,0xE5,0xAB,0x31,
940 0x43,0xDB,0x5B,0xFC,0xE0,0xFD,0x10,0x8E,0x4B,0x82,0xD1,0x20,
941 0xA9,0x21,0x08,0x01,0x1A,0x72,0x3C,0x12,0xA7,0x87,0xE6,0xD7,
942 0x88,0x71,0x9A,0x10,0xBD,0xBA,0x5B,0x26,0x99,0xC3,0x27,0x18,
943 0x6A,0xF4,0xE2,0x3C,0x1A,0x94,0x68,0x34,0xB6,0x15,0x0B,0xDA,
944 0x25,0x83,0xE9,0xCA,0x2A,0xD4,0x4C,0xE8,0xDB,0xBB,0xC2,0xDB,
945 0x04,0xDE,0x8E,0xF9,0x2E,0x8E,0xFC,0x14,0x1F,0xBE,0xCA,0xA6,
946 0x28,0x7C,0x59,0x47,0x4E,0x6B,0xC0,0x5D,0x99,0xB2,0x96,0x4F,
947 0xA0,0x90,0xC3,0xA2,0x23,0x3B,0xA1,0x86,0x51,0x5B,0xE7,0xED,
948 0x1F,0x61,0x29,0x70,0xCE,0xE2,0xD7,0xAF,0xB8,0x1B,0xDD,0x76,
949 0x21,0x70,0x48,0x1C,0xD0,0x06,0x91,0x27,0xD5,0xB0,0x5A,0xA9,
950 0x93,0xB4,0xEA,0x98,0x8D,0x8F,0xDD,0xC1,0x86,0xFF,0xB7,0xDC,
951 0x90,0xA6,0xC0,0x8F,0x4D,0xF4,0x35,0xC9,0x34,0x02,0x84,0x92,
952 0x36,0xC3,0xFA,0xB4,0xD2,0x7C,0x70,0x26,0xC1,0xD4,0xDC,0xB2,
953 0x60,0x26,0x46,0xDE,0xC9,0x75,0x1E,0x76,0x3D,0xBA,0x37,0xBD,
954 0xF8,0xFF,0x94,0x06,0xAD,0x9E,0x53,0x0E,0xE5,0xDB,0x38,0x2F,
955 0x41,0x30,0x01,0xAE,0xB0,0x6A,0x53,0xED,0x90,0x27,0xD8,0x31,
956 0x17,0x97,0x27,0xB0,0x86,0x5A,0x89,0x18,0xDA,0x3E,0xDB,0xEB,
957 0xCF,0x9B,0x14,0xED,0x44,0xCE,0x6C,0xBA,0xCE,0xD4,0xBB,0x1B,
958 0xDB,0x7F,0x14,0x47,0xE6,0xCC,0x25,0x4B,0x33,0x20,0x51,0x51,
959 0x2B,0xD7,0xAF,0x42,0x6F,0xB8,0xF4,0x01,0x37,0x8C,0xD2,0xBF,
960 0x59,0x83,0xCA,0x01,0xC6,0x4B,0x92,0xEC,0xF0,0x32,0xEA,0x15,
961 0xD1,0x72,0x1D,0x03,0xF4,0x82,0xD7,0xCE,0x6E,0x74,0xFE,0xF6,
962 0xD5,0x5E,0x70,0x2F,0x46,0x98,0x0C,0x82,0xB5,0xA8,0x40,0x31,
963 0x90,0x0B,0x1C,0x9E,0x59,0xE7,0xC9,0x7F,0xBE,0xC7,0xE8,0xF3,
964 0x23,0xA9,0x7A,0x7E,0x36,0xCC,0x88,0xBE,0x0F,0x1D,0x45,0xB7,
965 0xFF,0x58,0x5A,0xC5,0x4B,0xD4,0x07,0xB2,0x2B,0x41,0x54,0xAA,
966 0xCC,0x8F,0x6D,0x7E,0xBF,0x48,0xE1,0xD8,0x14,0xCC,0x5E,0xD2,
967 0x0F,0x80,0x37,0xE0,0xA7,0x97,0x15,0xEE,0xF2,0x9B,0xE3,0x28,
968 0x06,0xA1,0xD5,0x8B,0xB7,0xC5,0xDA,0x76,0xF5,0x50,0xAA,0x3D,
969 0x8A,0x1F,0xBF,0xF0,0xEB,0x19,0xCC,0xB1,0xA3,0x13,0xD5,0x5C,
970 0xDA,0x56,0xC9,0xEC,0x2E,0xF2,0x96,0x32,0x38,0x7F,0xE8,0xD7,
971 0x6E,0x3C,0x04,0x68,0x04,0x3E,0x8F,0x66,0x3F,0x48,0x60,0xEE,
972 0x12,0xBF,0x2D,0x5B,0x0B,0x74,0x74,0xD6,0xE6,0x94,0xF9,0x1E,
973 0x6D,0xBE,0x11,0x59,0x74,0xA3,0x92,0x6F,0x12,0xFE,0xE5,0xE4,
974 0x38,0x77,0x7C,0xB6,0xA9,0x32,0xDF,0x8C,0xD8,0xBE,0xC4,0xD0,
975 0x73,0xB9,0x31,0xBA,0x3B,0xC8,0x32,0xB6,0x8D,0x9D,0xD3,0x00,
976 0x74,0x1F,0xA7,0xBF,0x8A,0xFC,0x47,0xED,0x25,0x76,0xF6,0x93,
977 0x6B,0xA4,0x24,0x66,0x3A,0xAB,0x63,0x9C,0x5A,0xE4,0xF5,0x68,
978 0x34,0x23,0xB4,0x74,0x2B,0xF1,0xC9,0x78,0x23,0x8F,0x16,0xCB,
979 0xE3,0x9D,0x65,0x2D,0xE3,0xFD,0xB8,0xBE,0xFC,0x84,0x8A,0xD9,
980 0x22,0x22,0x2E,0x04,0xA4,0x03,0x7C,0x07,0x13,0xEB,0x57,0xA8,
981 0x1A,0x23,0xF0,0xC7,0x34,0x73,0xFC,0x64,0x6C,0xEA,0x30,0x6B,
982 0x4B,0xCB,0xC8,0x86,0x2F,0x83,0x85,0xDD,0xFA,0x9D,0x4B,0x7F,
983 0xA2,0xC0,0x87,0xE8,0x79,0x68,0x33,0x03,0xED,0x5B,0xDD,0x3A,
984 0x06,0x2B,0x3C,0xF5,0xB3,0xA2,0x78,0xA6,0x6D,0x2A,0x13,0xF8,
985 0x3F,0x44,0xF8,0x2D,0xDF,0x31,0x0E,0xE0,0x74,0xAB,0x6A,0x36,
986 0x45,0x97,0xE8,0x99,0xA0,0x25,0x5D,0xC1,0x64,0xF3,0x1C,0xC5,
987 0x08,0x46,0x85,0x1D,0xF9,0xAB,0x48,0x19,0x5D,0xED,0x7E,0xA1,
988 0xB1,0xD5,0x10,0xBD,0x7E,0xE7,0x4D,0x73,0xFA,0xF3,0x6B,0xC3,
989 0x1E,0xCF,0xA2,0x68,0x35,0x90,0x46,0xF4,0xEB,0x87,0x9F,0x92,
990 0x40,0x09,0x43,0x8B,0x48,0x1C,0x6C,0xD7,0x88,0x9A,0x00,0x2E,
991 0xD5,0xEE,0x38,0x2B,0xC9,0x19,0x0D,0xA6,0xFC,0x02,0x6E,0x47,
992 0x95,0x58,0xE4,0x47,0x56,0x77,0xE9,0xAA,0x9E,0x30,0x50,0xE2,
993 0x76,0x56,0x94,0xDF,0xC8,0x1F,0x56,0xE8,0x80,0xB9,0x6E,0x71,
994 0x60,0xC9,0x80,0xDD,0x98,0xED,0xD3,0xDF,0xFF,0xFF,0xFF,0xFF,
995 0xFF,0xFF,0xFF,0xFF,
996 };
997#endif
998 DH *dh = DH_new();
999 if (dh) {
1000#if OPENSSL_VERSION_NUMBER >= 0x0090801fL
1001 dh->p = get_rfc3526_prime_8192(NULL);
1002#else
1003 dh->p = BN_bin2bn(rfc_3526_prime_8192, sizeof rfc_3526_prime_8192, NULL);
1004#endif
1005 /* See RFC 3526, Section 7 "8192-bit MODP Group"
1006 for the reason why 2 is used as generator.
1007 */
1008 BN_dec2bn(&dh->g, "2");
1009 if (!dh->p || !dh->g) {
1010 DH_free(dh);
1011 dh = NULL;
1012 }
1013 }
1014 return dh;
1015}
1016
1017/* Returns Diffie-Hellman parameters matching the private key length
1018 but not exceeding global.tune.ssl_default_dh_param */
1019static DH *ssl_get_tmp_dh(SSL *ssl, int export, int keylen)
1020{
1021 DH *dh = NULL;
1022 EVP_PKEY *pkey = SSL_get_privatekey(ssl);
1023 int type = pkey ? EVP_PKEY_type(pkey->type) : EVP_PKEY_NONE;
1024
1025 /* The keylen supplied by OpenSSL can only be 512 or 1024.
1026 See ssl3_send_server_key_exchange() in ssl/s3_srvr.c
1027 */
1028 if (type == EVP_PKEY_RSA || type == EVP_PKEY_DSA) {
1029 keylen = EVP_PKEY_bits(pkey);
1030 }
1031
1032 if (keylen > global.tune.ssl_default_dh_param) {
1033 keylen = global.tune.ssl_default_dh_param;
1034 }
1035
1036 if (keylen >= 8192) {
1037 dh = ssl_get_dh_8192();
1038 }
1039 else if (keylen >= 4096) {
1040 dh = ssl_get_dh_4096();
1041 }
1042 else if (keylen >= 2048) {
1043 dh = ssl_get_dh_2048();
1044 }
1045 else {
1046 dh = ssl_get_dh_1024();
1047 }
1048
1049 return dh;
1050}
1051
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001052/* Loads Diffie-Hellman parameter from a file. Returns 1 if loaded, else -1
1053 if an error occured, and 0 if parameter not found. */
Willy Tarreau6e774b42014-04-25 21:35:23 +02001054int ssl_sock_load_dh_params(SSL_CTX *ctx, const char *file)
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001055{
1056 int ret = -1;
1057 BIO *in;
1058 DH *dh = NULL;
1059
1060 in = BIO_new(BIO_s_file());
1061 if (in == NULL)
1062 goto end;
1063
1064 if (BIO_read_filename(in, file) <= 0)
1065 goto end;
1066
1067 dh = PEM_read_bio_DHparams(in, NULL, ctx->default_passwd_callback, ctx->default_passwd_callback_userdata);
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001068 if (dh) {
1069 ret = 1;
1070 SSL_CTX_set_tmp_dh(ctx, dh);
1071 /* Setting ssl default dh param to the size of the static DH params
1072 found in the file. This way we know that there is no use
1073 complaining later about ssl-default-dh-param not being set. */
1074 global.tune.ssl_default_dh_param = DH_size(dh) * 8;
1075 }
1076 else {
Emeric Brun41fdb3c2013-04-26 11:05:44 +02001077 /* Clear openssl global errors stack */
1078 ERR_clear_error();
1079
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001080 if (global.tune.ssl_default_dh_param <= 1024) {
1081 /* we are limited to DH parameter of 1024 bits anyway */
1082 dh = ssl_get_dh_1024();
1083 if (dh == NULL)
1084 goto end;
Willy Tarreau6e774b42014-04-25 21:35:23 +02001085
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001086 SSL_CTX_set_tmp_dh(ctx, dh);
1087 }
1088 else {
1089 SSL_CTX_set_tmp_dh_callback(ctx, ssl_get_tmp_dh);
1090 }
Willy Tarreau6e774b42014-04-25 21:35:23 +02001091
Emeric Brun41fdb3c2013-04-26 11:05:44 +02001092 ret = 0; /* DH params not found */
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001093 }
Emeric Brun644cde02012-12-14 11:21:13 +01001094
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001095end:
1096 if (dh)
1097 DH_free(dh);
1098
1099 if (in)
Emeric Brun41fdb3c2013-04-26 11:05:44 +02001100 BIO_free(in);
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001101
1102 return ret;
1103}
1104#endif
1105
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001106static int ssl_sock_add_cert_sni(SSL_CTX *ctx, struct bind_conf *s, char *name, int order)
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001107{
1108 struct sni_ctx *sc;
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001109 int wild = 0, neg = 0;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001110
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001111 if (*name == '!') {
1112 neg = 1;
1113 name++;
1114 }
1115 if (*name == '*') {
1116 wild = 1;
1117 name++;
1118 }
1119 /* !* filter is a nop */
1120 if (neg && wild)
1121 return order;
1122 if (*name) {
1123 int j, len;
1124 len = strlen(name);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001125 sc = malloc(sizeof(struct sni_ctx) + len + 1);
1126 for (j = 0; j < len; j++)
1127 sc->name.key[j] = tolower(name[j]);
1128 sc->name.key[len] = 0;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001129 sc->ctx = ctx;
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001130 sc->order = order++;
1131 sc->neg = neg;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001132 if (wild)
1133 ebst_insert(&s->sni_w_ctx, &sc->name);
1134 else
1135 ebst_insert(&s->sni_ctx, &sc->name);
1136 }
1137 return order;
1138}
1139
Emeric Brunfc0421f2012-09-07 17:30:07 +02001140/* Loads a certificate key and CA chain from a file. Returns 0 on error, -1 if
1141 * an early error happens and the caller must call SSL_CTX_free() by itelf.
1142 */
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001143static 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 +02001144{
1145 BIO *in;
1146 X509 *x = NULL, *ca;
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001147 int i, err;
Emeric Brunfc0421f2012-09-07 17:30:07 +02001148 int ret = -1;
1149 int order = 0;
1150 X509_NAME *xname;
1151 char *str;
Emeric Brunfc0421f2012-09-07 17:30:07 +02001152#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
1153 STACK_OF(GENERAL_NAME) *names;
1154#endif
1155
1156 in = BIO_new(BIO_s_file());
1157 if (in == NULL)
1158 goto end;
1159
1160 if (BIO_read_filename(in, file) <= 0)
1161 goto end;
1162
1163 x = PEM_read_bio_X509_AUX(in, NULL, ctx->default_passwd_callback, ctx->default_passwd_callback_userdata);
1164 if (x == NULL)
1165 goto end;
1166
Emeric Brun50bcecc2013-04-22 13:05:23 +02001167 if (fcount) {
1168 while (fcount--)
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001169 order = ssl_sock_add_cert_sni(ctx, s, sni_filter[fcount], order);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001170 }
1171 else {
Emeric Brunfc0421f2012-09-07 17:30:07 +02001172#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001173 names = X509_get_ext_d2i(x, NID_subject_alt_name, NULL, NULL);
1174 if (names) {
1175 for (i = 0; i < sk_GENERAL_NAME_num(names); i++) {
1176 GENERAL_NAME *name = sk_GENERAL_NAME_value(names, i);
1177 if (name->type == GEN_DNS) {
1178 if (ASN1_STRING_to_UTF8((unsigned char **)&str, name->d.dNSName) >= 0) {
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001179 order = ssl_sock_add_cert_sni(ctx, s, str, order);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001180 OPENSSL_free(str);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001181 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02001182 }
1183 }
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001184 sk_GENERAL_NAME_pop_free(names, GENERAL_NAME_free);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001185 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02001186#endif /* SSL_CTRL_SET_TLSEXT_HOSTNAME */
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001187 xname = X509_get_subject_name(x);
1188 i = -1;
1189 while ((i = X509_NAME_get_index_by_NID(xname, NID_commonName, i)) != -1) {
1190 X509_NAME_ENTRY *entry = X509_NAME_get_entry(xname, i);
1191 if (ASN1_STRING_to_UTF8((unsigned char **)&str, entry->value) >= 0) {
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001192 order = ssl_sock_add_cert_sni(ctx, s, str, order);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001193 OPENSSL_free(str);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001194 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02001195 }
1196 }
1197
1198 ret = 0; /* the caller must not free the SSL_CTX argument anymore */
1199 if (!SSL_CTX_use_certificate(ctx, x))
1200 goto end;
1201
1202 if (ctx->extra_certs != NULL) {
1203 sk_X509_pop_free(ctx->extra_certs, X509_free);
1204 ctx->extra_certs = NULL;
1205 }
1206
1207 while ((ca = PEM_read_bio_X509(in, NULL, ctx->default_passwd_callback, ctx->default_passwd_callback_userdata))) {
1208 if (!SSL_CTX_add_extra_chain_cert(ctx, ca)) {
1209 X509_free(ca);
1210 goto end;
1211 }
1212 }
1213
1214 err = ERR_get_error();
1215 if (!err || (ERR_GET_LIB(err) == ERR_LIB_PEM && ERR_GET_REASON(err) == PEM_R_NO_START_LINE)) {
1216 /* we successfully reached the last cert in the file */
1217 ret = 1;
1218 }
1219 ERR_clear_error();
1220
1221end:
1222 if (x)
1223 X509_free(x);
1224
1225 if (in)
1226 BIO_free(in);
1227
1228 return ret;
1229}
1230
Emeric Brun50bcecc2013-04-22 13:05:23 +02001231static 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 +02001232{
1233 int ret;
1234 SSL_CTX *ctx;
1235
1236 ctx = SSL_CTX_new(SSLv23_server_method());
1237 if (!ctx) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02001238 memprintf(err, "%sunable to allocate SSL context for cert '%s'.\n",
1239 err && *err ? *err : "", path);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001240 return 1;
1241 }
1242
1243 if (SSL_CTX_use_PrivateKey_file(ctx, path, SSL_FILETYPE_PEM) <= 0) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02001244 memprintf(err, "%sunable to load SSL private key from PEM file '%s'.\n",
1245 err && *err ? *err : "", path);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001246 SSL_CTX_free(ctx);
1247 return 1;
1248 }
1249
Emeric Brun50bcecc2013-04-22 13:05:23 +02001250 ret = ssl_sock_load_cert_chain_file(ctx, path, bind_conf, sni_filter, fcount);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001251 if (ret <= 0) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02001252 memprintf(err, "%sunable to load SSL certificate from PEM file '%s'.\n",
1253 err && *err ? *err : "", path);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001254 if (ret < 0) /* serious error, must do that ourselves */
1255 SSL_CTX_free(ctx);
1256 return 1;
1257 }
Emeric Brun61694ab2012-10-26 13:35:33 +02001258
1259 if (SSL_CTX_check_private_key(ctx) <= 0) {
1260 memprintf(err, "%sinconsistencies between private key and certificate loaded from PEM file '%s'.\n",
1261 err && *err ? *err : "", path);
1262 return 1;
1263 }
1264
Emeric Brunfc0421f2012-09-07 17:30:07 +02001265 /* we must not free the SSL_CTX anymore below, since it's already in
1266 * the tree, so it will be discovered and cleaned in time.
1267 */
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001268#ifndef OPENSSL_NO_DH
1269 ret = ssl_sock_load_dh_params(ctx, path);
1270 if (ret < 0) {
1271 if (err)
1272 memprintf(err, "%sunable to load DH parameters from file '%s'.\n",
1273 *err ? *err : "", path);
1274 return 1;
1275 }
1276#endif
1277
Emeric Brun4147b2e2014-06-16 18:36:30 +02001278#ifdef SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB
1279 ret = ssl_sock_load_ocsp(ctx, path);
1280 if (ret < 0) {
1281 if (err)
1282 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",
1283 *err ? *err : "", path);
1284 return 1;
1285 }
1286#endif
1287
Emeric Brunfc0421f2012-09-07 17:30:07 +02001288#ifndef SSL_CTRL_SET_TLSEXT_HOSTNAME
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001289 if (bind_conf->default_ctx) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02001290 memprintf(err, "%sthis version of openssl cannot load multiple SSL certificates.\n",
1291 err && *err ? *err : "");
Emeric Brunfc0421f2012-09-07 17:30:07 +02001292 return 1;
1293 }
1294#endif
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001295 if (!bind_conf->default_ctx)
1296 bind_conf->default_ctx = ctx;
Emeric Brunfc0421f2012-09-07 17:30:07 +02001297
1298 return 0;
1299}
1300
Willy Tarreau79eeafa2012-09-14 07:53:05 +02001301int ssl_sock_load_cert(char *path, struct bind_conf *bind_conf, struct proxy *curproxy, char **err)
Emeric Brunfc0421f2012-09-07 17:30:07 +02001302{
1303 struct dirent *de;
1304 DIR *dir;
1305 struct stat buf;
Willy Tarreauee2663b2012-12-06 11:36:59 +01001306 char *end;
1307 char fp[MAXPATHLEN+1];
Emeric Brunfc0421f2012-09-07 17:30:07 +02001308 int cfgerr = 0;
1309
1310 if (!(dir = opendir(path)))
Emeric Brun50bcecc2013-04-22 13:05:23 +02001311 return ssl_sock_load_cert_file(path, bind_conf, curproxy, NULL, 0, err);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001312
1313 /* strip trailing slashes, including first one */
1314 for (end = path + strlen(path) - 1; end >= path && *end == '/'; end--)
1315 *end = 0;
1316
Emeric Brunfc0421f2012-09-07 17:30:07 +02001317 while ((de = readdir(dir))) {
Emeric Brun2aab7222014-06-18 18:15:09 +02001318 end = strrchr(de->d_name, '.');
1319 if (end && (!strcmp(end, ".issuer") || !strcmp(end, ".ocsp")))
1320 continue;
1321
Willy Tarreauee2663b2012-12-06 11:36:59 +01001322 snprintf(fp, sizeof(fp), "%s/%s", path, de->d_name);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001323 if (stat(fp, &buf) != 0) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02001324 memprintf(err, "%sunable to stat SSL certificate from file '%s' : %s.\n",
1325 err && *err ? *err : "", fp, strerror(errno));
Emeric Brunfc0421f2012-09-07 17:30:07 +02001326 cfgerr++;
1327 continue;
1328 }
1329 if (!S_ISREG(buf.st_mode))
1330 continue;
Emeric Brun50bcecc2013-04-22 13:05:23 +02001331 cfgerr += ssl_sock_load_cert_file(fp, bind_conf, curproxy, NULL, 0, err);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001332 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02001333 closedir(dir);
1334 return cfgerr;
1335}
1336
Thierry Fournier383085f2013-01-24 14:15:43 +01001337/* Make sure openssl opens /dev/urandom before the chroot. The work is only
1338 * done once. Zero is returned if the operation fails. No error is returned
1339 * if the random is said as not implemented, because we expect that openssl
1340 * will use another method once needed.
1341 */
1342static int ssl_initialize_random()
1343{
1344 unsigned char random;
1345 static int random_initialized = 0;
1346
1347 if (!random_initialized && RAND_bytes(&random, 1) != 0)
1348 random_initialized = 1;
1349
1350 return random_initialized;
1351}
1352
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001353int ssl_sock_load_cert_list_file(char *file, struct bind_conf *bind_conf, struct proxy *curproxy, char **err)
1354{
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001355 char thisline[LINESIZE];
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001356 FILE *f;
1357 int linenum = 0;
1358 int cfgerr = 0;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001359
Willy Tarreauad1731d2013-04-02 17:35:58 +02001360 if ((f = fopen(file, "r")) == NULL) {
1361 memprintf(err, "cannot open file '%s' : %s", file, strerror(errno));
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001362 return 1;
Willy Tarreauad1731d2013-04-02 17:35:58 +02001363 }
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001364
1365 while (fgets(thisline, sizeof(thisline), f) != NULL) {
1366 int arg;
Emeric Brun50bcecc2013-04-22 13:05:23 +02001367 int newarg;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001368 char *end;
1369 char *args[MAX_LINE_ARGS + 1];
1370 char *line = thisline;
1371
1372 linenum++;
1373 end = line + strlen(line);
1374 if (end-line == sizeof(thisline)-1 && *(end-1) != '\n') {
1375 /* Check if we reached the limit and the last char is not \n.
1376 * Watch out for the last line without the terminating '\n'!
1377 */
Willy Tarreauad1731d2013-04-02 17:35:58 +02001378 memprintf(err, "line %d too long in file '%s', limit is %d characters",
1379 linenum, file, (int)sizeof(thisline)-1);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001380 cfgerr = 1;
Willy Tarreauad1731d2013-04-02 17:35:58 +02001381 break;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001382 }
1383
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001384 arg = 0;
Emeric Brun50bcecc2013-04-22 13:05:23 +02001385 newarg = 1;
1386 while (*line) {
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001387 if (*line == '#' || *line == '\n' || *line == '\r') {
1388 /* end of string, end of loop */
1389 *line = 0;
1390 break;
1391 }
1392 else if (isspace(*line)) {
Emeric Brun50bcecc2013-04-22 13:05:23 +02001393 newarg = 1;
1394 *line = 0;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001395 }
Emeric Brun50bcecc2013-04-22 13:05:23 +02001396 else if (newarg) {
1397 if (arg == MAX_LINE_ARGS) {
1398 memprintf(err, "too many args on line %d in file '%s'.",
1399 linenum, file);
1400 cfgerr = 1;
1401 break;
1402 }
1403 newarg = 0;
1404 args[arg++] = line;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001405 }
Emeric Brun50bcecc2013-04-22 13:05:23 +02001406 line++;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001407 }
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001408 if (cfgerr)
1409 break;
Willy Tarreauad1731d2013-04-02 17:35:58 +02001410
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001411 /* empty line */
Emeric Brun50bcecc2013-04-22 13:05:23 +02001412 if (!arg)
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001413 continue;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001414
Emeric Brun50bcecc2013-04-22 13:05:23 +02001415 cfgerr = ssl_sock_load_cert_file(args[0], bind_conf, curproxy, &args[1], arg-1, err);
Willy Tarreauad1731d2013-04-02 17:35:58 +02001416 if (cfgerr) {
1417 memprintf(err, "error processing line %d in file '%s' : %s", linenum, file, *err);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001418 break;
Willy Tarreauad1731d2013-04-02 17:35:58 +02001419 }
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001420 }
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001421 fclose(f);
1422 return cfgerr;
1423}
1424
Emeric Brunfc0421f2012-09-07 17:30:07 +02001425#ifndef SSL_OP_CIPHER_SERVER_PREFERENCE /* needs OpenSSL >= 0.9.7 */
1426#define SSL_OP_CIPHER_SERVER_PREFERENCE 0
1427#endif
1428
1429#ifndef SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION /* needs OpenSSL >= 0.9.7 */
1430#define SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION 0
Willy Tarreau7d588ee2012-11-26 18:47:31 +01001431#define SSL_renegotiate_pending(arg) 0
Emeric Brunfc0421f2012-09-07 17:30:07 +02001432#endif
Emeric Brun2b58d042012-09-20 17:10:03 +02001433#ifndef SSL_OP_SINGLE_ECDH_USE /* needs OpenSSL >= 0.9.8 */
1434#define SSL_OP_SINGLE_ECDH_USE 0
1435#endif
Emeric Brun2d0c4822012-10-02 13:45:20 +02001436#ifndef SSL_OP_NO_TICKET /* needs OpenSSL >= 0.9.8 */
1437#define SSL_OP_NO_TICKET 0
1438#endif
Emeric Brunfc0421f2012-09-07 17:30:07 +02001439#ifndef SSL_OP_NO_COMPRESSION /* needs OpenSSL >= 0.9.9 */
1440#define SSL_OP_NO_COMPRESSION 0
1441#endif
Emeric Brunc0ff4922012-09-28 19:37:02 +02001442#ifndef SSL_OP_NO_TLSv1_1 /* needs OpenSSL >= 1.0.1 */
1443#define SSL_OP_NO_TLSv1_1 0
1444#endif
1445#ifndef SSL_OP_NO_TLSv1_2 /* needs OpenSSL >= 1.0.1 */
1446#define SSL_OP_NO_TLSv1_2 0
1447#endif
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001448#ifndef SSL_OP_SINGLE_DH_USE /* needs OpenSSL >= 0.9.6 */
1449#define SSL_OP_SINGLE_DH_USE 0
1450#endif
Emeric Brun2b58d042012-09-20 17:10:03 +02001451#ifndef SSL_OP_SINGLE_ECDH_USE /* needs OpenSSL >= 1.0.0 */
1452#define SSL_OP_SINGLE_ECDH_USE 0
1453#endif
Emeric Brunfc0421f2012-09-07 17:30:07 +02001454#ifndef SSL_MODE_RELEASE_BUFFERS /* needs OpenSSL >= 1.0.0 */
1455#define SSL_MODE_RELEASE_BUFFERS 0
1456#endif
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001457
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001458int ssl_sock_prepare_ctx(struct bind_conf *bind_conf, SSL_CTX *ctx, struct proxy *curproxy)
Emeric Brunfc0421f2012-09-07 17:30:07 +02001459{
1460 int cfgerr = 0;
Emeric Brun850efd52014-01-29 12:24:34 +01001461 int verify = SSL_VERIFY_NONE;
Remi Gacogneaf5c3da2014-05-19 10:29:58 +02001462 long ssloptions =
Emeric Brunfc0421f2012-09-07 17:30:07 +02001463 SSL_OP_ALL | /* all known workarounds for bugs */
1464 SSL_OP_NO_SSLv2 |
1465 SSL_OP_NO_COMPRESSION |
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001466 SSL_OP_SINGLE_DH_USE |
Emeric Brun2b58d042012-09-20 17:10:03 +02001467 SSL_OP_SINGLE_ECDH_USE |
Emeric Brun3c4bc6e2012-10-04 18:44:19 +02001468 SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION |
1469 SSL_OP_CIPHER_SERVER_PREFERENCE;
Remi Gacogneaf5c3da2014-05-19 10:29:58 +02001470 long sslmode =
Emeric Brunfc0421f2012-09-07 17:30:07 +02001471 SSL_MODE_ENABLE_PARTIAL_WRITE |
1472 SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER |
1473 SSL_MODE_RELEASE_BUFFERS;
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001474 STACK_OF(SSL_CIPHER) * ciphers = NULL;
1475 SSL_CIPHER * cipher = NULL;
Remi Gacognec1eab8c2014-06-12 18:20:11 +02001476 char cipher_description[128];
1477 /* The description of ciphers using an Ephemeral Diffie Hellman key exchange
1478 contains " Kx=DH " or " Kx=DH(". Beware of " Kx=DH/",
1479 which is not ephemeral DH. */
1480 const char dhe_description[] = " Kx=DH ";
1481 const char dhe_export_description[] = " Kx=DH(";
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001482 int idx = 0;
1483 int dhe_found = 0;
Emeric Brunfc0421f2012-09-07 17:30:07 +02001484
Thierry Fournier383085f2013-01-24 14:15:43 +01001485 /* Make sure openssl opens /dev/urandom before the chroot */
1486 if (!ssl_initialize_random()) {
1487 Alert("OpenSSL random data generator initialization failed.\n");
1488 cfgerr++;
1489 }
1490
Emeric Brun89675492012-10-05 13:48:26 +02001491 if (bind_conf->ssl_options & BC_SSL_O_NO_SSLV3)
Emeric Brunfc0421f2012-09-07 17:30:07 +02001492 ssloptions |= SSL_OP_NO_SSLv3;
Emeric Brun89675492012-10-05 13:48:26 +02001493 if (bind_conf->ssl_options & BC_SSL_O_NO_TLSV10)
Emeric Brunfc0421f2012-09-07 17:30:07 +02001494 ssloptions |= SSL_OP_NO_TLSv1;
Emeric Brun89675492012-10-05 13:48:26 +02001495 if (bind_conf->ssl_options & BC_SSL_O_NO_TLSV11)
Emeric Brunc0ff4922012-09-28 19:37:02 +02001496 ssloptions |= SSL_OP_NO_TLSv1_1;
Emeric Brun89675492012-10-05 13:48:26 +02001497 if (bind_conf->ssl_options & BC_SSL_O_NO_TLSV12)
Emeric Brunc0ff4922012-09-28 19:37:02 +02001498 ssloptions |= SSL_OP_NO_TLSv1_2;
Emeric Brun89675492012-10-05 13:48:26 +02001499 if (bind_conf->ssl_options & BC_SSL_O_NO_TLS_TICKETS)
Emeric Brun2d0c4822012-10-02 13:45:20 +02001500 ssloptions |= SSL_OP_NO_TICKET;
Emeric Brun2cb7ae52012-10-05 14:14:21 +02001501 if (bind_conf->ssl_options & BC_SSL_O_USE_SSLV3)
1502 SSL_CTX_set_ssl_version(ctx, SSLv3_server_method());
1503 if (bind_conf->ssl_options & BC_SSL_O_USE_TLSV10)
1504 SSL_CTX_set_ssl_version(ctx, TLSv1_server_method());
1505#if SSL_OP_NO_TLSv1_1
1506 if (bind_conf->ssl_options & BC_SSL_O_USE_TLSV11)
1507 SSL_CTX_set_ssl_version(ctx, TLSv1_1_server_method());
1508#endif
1509#if SSL_OP_NO_TLSv1_2
1510 if (bind_conf->ssl_options & BC_SSL_O_USE_TLSV12)
1511 SSL_CTX_set_ssl_version(ctx, TLSv1_2_server_method());
1512#endif
Emeric Brunfc0421f2012-09-07 17:30:07 +02001513
1514 SSL_CTX_set_options(ctx, ssloptions);
1515 SSL_CTX_set_mode(ctx, sslmode);
Emeric Brun850efd52014-01-29 12:24:34 +01001516 switch (bind_conf->verify) {
1517 case SSL_SOCK_VERIFY_NONE:
1518 verify = SSL_VERIFY_NONE;
1519 break;
1520 case SSL_SOCK_VERIFY_OPTIONAL:
1521 verify = SSL_VERIFY_PEER;
1522 break;
1523 case SSL_SOCK_VERIFY_REQUIRED:
1524 verify = SSL_VERIFY_PEER|SSL_VERIFY_FAIL_IF_NO_PEER_CERT;
1525 break;
1526 }
1527 SSL_CTX_set_verify(ctx, verify, ssl_sock_bind_verifycbk);
1528 if (verify & SSL_VERIFY_PEER) {
Emeric Brunfb510ea2012-10-05 12:00:26 +02001529 if (bind_conf->ca_file) {
Emeric Brund94b3fe2012-09-20 18:23:56 +02001530 /* load CAfile to verify */
Emeric Brunfb510ea2012-10-05 12:00:26 +02001531 if (!SSL_CTX_load_verify_locations(ctx, bind_conf->ca_file, NULL)) {
Emeric Brund94b3fe2012-09-20 18:23:56 +02001532 Alert("Proxy '%s': unable to load CA file '%s' for bind '%s' at [%s:%d].\n",
Emeric Brunfb510ea2012-10-05 12:00:26 +02001533 curproxy->id, bind_conf->ca_file, bind_conf->arg, bind_conf->file, bind_conf->line);
Emeric Brund94b3fe2012-09-20 18:23:56 +02001534 cfgerr++;
1535 }
1536 /* set CA names fo client cert request, function returns void */
Emeric Brunfb510ea2012-10-05 12:00:26 +02001537 SSL_CTX_set_client_CA_list(ctx, SSL_load_client_CA_file(bind_conf->ca_file));
Emeric Brund94b3fe2012-09-20 18:23:56 +02001538 }
Emeric Brun850efd52014-01-29 12:24:34 +01001539 else {
1540 Alert("Proxy '%s': verify is enabled but no CA file specified for bind '%s' at [%s:%d].\n",
1541 curproxy->id, bind_conf->arg, bind_conf->file, bind_conf->line);
1542 cfgerr++;
1543 }
Emeric Brun051cdab2012-10-02 19:25:50 +02001544#ifdef X509_V_FLAG_CRL_CHECK
Emeric Brunfb510ea2012-10-05 12:00:26 +02001545 if (bind_conf->crl_file) {
Emeric Brund94b3fe2012-09-20 18:23:56 +02001546 X509_STORE *store = SSL_CTX_get_cert_store(ctx);
1547
Emeric Brunfb510ea2012-10-05 12:00:26 +02001548 if (!store || !X509_STORE_load_locations(store, bind_conf->crl_file, NULL)) {
Emeric Brund94b3fe2012-09-20 18:23:56 +02001549 Alert("Proxy '%s': unable to configure CRL file '%s' for bind '%s' at [%s:%d].\n",
Emeric Brunfb510ea2012-10-05 12:00:26 +02001550 curproxy->id, bind_conf->ca_file, bind_conf->arg, bind_conf->file, bind_conf->line);
Emeric Brund94b3fe2012-09-20 18:23:56 +02001551 cfgerr++;
1552 }
Emeric Brun561e5742012-10-02 15:20:55 +02001553 else {
1554 X509_STORE_set_flags(store, X509_V_FLAG_CRL_CHECK|X509_V_FLAG_CRL_CHECK_ALL);
1555 }
Emeric Brund94b3fe2012-09-20 18:23:56 +02001556 }
Emeric Brun051cdab2012-10-02 19:25:50 +02001557#endif
Emeric Brun644cde02012-12-14 11:21:13 +01001558 ERR_clear_error();
Emeric Brund94b3fe2012-09-20 18:23:56 +02001559 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02001560
Emeric Brun4f65bff2012-11-16 15:11:00 +01001561 if (global.tune.ssllifetime)
1562 SSL_CTX_set_timeout(ctx, global.tune.ssllifetime);
1563
Emeric Brunfc0421f2012-09-07 17:30:07 +02001564 shared_context_set_cache(ctx);
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001565 if (bind_conf->ciphers &&
1566 !SSL_CTX_set_cipher_list(ctx, bind_conf->ciphers)) {
Emeric Brunfc0421f2012-09-07 17:30:07 +02001567 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 +02001568 curproxy->id, bind_conf->ciphers, bind_conf->arg, bind_conf->file, bind_conf->line);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001569 cfgerr++;
1570 }
1571
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001572 /* If tune.ssl.default-dh-param has not been set and
1573 no static DH params were in the certificate file. */
1574 if (global.tune.ssl_default_dh_param == 0) {
1575 ciphers = ctx->cipher_list;
1576
1577 if (ciphers) {
1578 for (idx = 0; idx < sk_SSL_CIPHER_num(ciphers); idx++) {
1579 cipher = sk_SSL_CIPHER_value(ciphers, idx);
Remi Gacognec1eab8c2014-06-12 18:20:11 +02001580 if (SSL_CIPHER_description(cipher, cipher_description, sizeof (cipher_description)) == cipher_description) {
1581 if (strstr(cipher_description, dhe_description) != NULL ||
1582 strstr(cipher_description, dhe_export_description) != NULL) {
1583 dhe_found = 1;
1584 break;
1585 }
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001586 }
1587 }
1588
1589 if (dhe_found) {
1590 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");
1591 }
1592 }
1593
1594 global.tune.ssl_default_dh_param = 1024;
1595 }
1596
Emeric Brunfc0421f2012-09-07 17:30:07 +02001597 SSL_CTX_set_info_callback(ctx, ssl_sock_infocbk);
Willy Tarreau5cbe4ef2014-05-08 22:45:11 +02001598#if OPENSSL_VERSION_NUMBER >= 0x00907000L
Emeric Brun29f037d2014-04-25 19:05:36 +02001599 SSL_CTX_set_msg_callback(ctx, ssl_sock_msgcbk);
Willy Tarreau5cbe4ef2014-05-08 22:45:11 +02001600#endif
Emeric Brun29f037d2014-04-25 19:05:36 +02001601
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02001602#ifdef OPENSSL_NPN_NEGOTIATED
1603 if (bind_conf->npn_str)
1604 SSL_CTX_set_next_protos_advertised_cb(ctx, ssl_sock_advertise_npn_protos, bind_conf);
1605#endif
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01001606#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Willy Tarreauab861d32013-04-02 02:30:41 +02001607 if (bind_conf->alpn_str)
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01001608 SSL_CTX_set_alpn_select_cb(ctx, ssl_sock_advertise_alpn_protos, bind_conf);
Willy Tarreauab861d32013-04-02 02:30:41 +02001609#endif
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02001610
Emeric Brunfc0421f2012-09-07 17:30:07 +02001611#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
1612 SSL_CTX_set_tlsext_servername_callback(ctx, ssl_sock_switchctx_cbk);
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001613 SSL_CTX_set_tlsext_servername_arg(ctx, bind_conf);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001614#endif
Emeric Brun2b58d042012-09-20 17:10:03 +02001615#if defined(SSL_CTX_set_tmp_ecdh) && !defined(OPENSSL_NO_ECDH)
Emeric Brun6924ef82013-03-06 14:08:53 +01001616 {
Emeric Brun2b58d042012-09-20 17:10:03 +02001617 int i;
1618 EC_KEY *ecdh;
1619
Emeric Brun6924ef82013-03-06 14:08:53 +01001620 i = OBJ_sn2nid(bind_conf->ecdhe ? bind_conf->ecdhe : ECDHE_DEFAULT_CURVE);
Emeric Brun2b58d042012-09-20 17:10:03 +02001621 if (!i || ((ecdh = EC_KEY_new_by_curve_name(i)) == NULL)) {
1622 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 +01001623 curproxy->id, bind_conf->ecdhe ? bind_conf->ecdhe : ECDHE_DEFAULT_CURVE,
1624 bind_conf->arg, bind_conf->file, bind_conf->line);
Emeric Brun2b58d042012-09-20 17:10:03 +02001625 cfgerr++;
1626 }
1627 else {
1628 SSL_CTX_set_tmp_ecdh(ctx, ecdh);
1629 EC_KEY_free(ecdh);
1630 }
1631 }
1632#endif
1633
Emeric Brunfc0421f2012-09-07 17:30:07 +02001634 return cfgerr;
1635}
1636
Evan Broderbe554312013-06-27 00:05:25 -07001637static int ssl_sock_srv_hostcheck(const char *pattern, const char *hostname)
1638{
1639 const char *pattern_wildcard, *pattern_left_label_end, *hostname_left_label_end;
1640 size_t prefixlen, suffixlen;
1641
1642 /* Trivial case */
1643 if (strcmp(pattern, hostname) == 0)
1644 return 1;
1645
Evan Broderbe554312013-06-27 00:05:25 -07001646 /* The rest of this logic is based on RFC 6125, section 6.4.3
1647 * (http://tools.ietf.org/html/rfc6125#section-6.4.3) */
1648
Emeric Bruna848dae2013-10-08 11:27:28 +02001649 pattern_wildcard = NULL;
1650 pattern_left_label_end = pattern;
1651 while (*pattern_left_label_end != '.') {
1652 switch (*pattern_left_label_end) {
1653 case 0:
1654 /* End of label not found */
1655 return 0;
1656 case '*':
1657 /* If there is more than one wildcards */
1658 if (pattern_wildcard)
1659 return 0;
1660 pattern_wildcard = pattern_left_label_end;
1661 break;
1662 }
1663 pattern_left_label_end++;
1664 }
1665
1666 /* If it's not trivial and there is no wildcard, it can't
1667 * match */
1668 if (!pattern_wildcard)
Evan Broderbe554312013-06-27 00:05:25 -07001669 return 0;
1670
1671 /* Make sure all labels match except the leftmost */
1672 hostname_left_label_end = strchr(hostname, '.');
1673 if (!hostname_left_label_end
1674 || strcmp(pattern_left_label_end, hostname_left_label_end) != 0)
1675 return 0;
1676
1677 /* Make sure the leftmost label of the hostname is long enough
1678 * that the wildcard can match */
Emeric Brun369da852013-10-08 11:39:35 +02001679 if (hostname_left_label_end - hostname < (pattern_left_label_end - pattern) - 1)
Evan Broderbe554312013-06-27 00:05:25 -07001680 return 0;
1681
1682 /* Finally compare the string on either side of the
1683 * wildcard */
1684 prefixlen = pattern_wildcard - pattern;
1685 suffixlen = pattern_left_label_end - (pattern_wildcard + 1);
Emeric Bruna848dae2013-10-08 11:27:28 +02001686 if ((prefixlen && (memcmp(pattern, hostname, prefixlen) != 0))
1687 || (suffixlen && (memcmp(pattern_wildcard + 1, hostname_left_label_end - suffixlen, suffixlen) != 0)))
Evan Broderbe554312013-06-27 00:05:25 -07001688 return 0;
1689
1690 return 1;
1691}
1692
1693static int ssl_sock_srv_verifycbk(int ok, X509_STORE_CTX *ctx)
1694{
1695 SSL *ssl;
1696 struct connection *conn;
1697 char *servername;
1698
1699 int depth;
1700 X509 *cert;
1701 STACK_OF(GENERAL_NAME) *alt_names;
1702 int i;
1703 X509_NAME *cert_subject;
1704 char *str;
1705
1706 if (ok == 0)
1707 return ok;
1708
1709 ssl = X509_STORE_CTX_get_ex_data(ctx, SSL_get_ex_data_X509_STORE_CTX_idx());
1710 conn = (struct connection *)SSL_get_app_data(ssl);
1711
1712 servername = objt_server(conn->target)->ssl_ctx.verify_host;
1713
1714 /* We only need to verify the CN on the actual server cert,
1715 * not the indirect CAs */
1716 depth = X509_STORE_CTX_get_error_depth(ctx);
1717 if (depth != 0)
1718 return ok;
1719
1720 /* At this point, the cert is *not* OK unless we can find a
1721 * hostname match */
1722 ok = 0;
1723
1724 cert = X509_STORE_CTX_get_current_cert(ctx);
1725 /* It seems like this might happen if verify peer isn't set */
1726 if (!cert)
1727 return ok;
1728
1729 alt_names = X509_get_ext_d2i(cert, NID_subject_alt_name, NULL, NULL);
1730 if (alt_names) {
1731 for (i = 0; !ok && i < sk_GENERAL_NAME_num(alt_names); i++) {
1732 GENERAL_NAME *name = sk_GENERAL_NAME_value(alt_names, i);
1733 if (name->type == GEN_DNS) {
Emeric Bruna33410c2013-09-17 15:47:48 +02001734#if OPENSSL_VERSION_NUMBER < 0x00907000L
1735 if (ASN1_STRING_to_UTF8((unsigned char **)&str, name->d.ia5) >= 0) {
1736#else
Evan Broderbe554312013-06-27 00:05:25 -07001737 if (ASN1_STRING_to_UTF8((unsigned char **)&str, name->d.dNSName) >= 0) {
Emeric Bruna33410c2013-09-17 15:47:48 +02001738#endif
Evan Broderbe554312013-06-27 00:05:25 -07001739 ok = ssl_sock_srv_hostcheck(str, servername);
1740 OPENSSL_free(str);
1741 }
1742 }
1743 }
Emeric Brun4ad50a42013-09-17 15:19:54 +02001744 sk_GENERAL_NAME_pop_free(alt_names, GENERAL_NAME_free);
Evan Broderbe554312013-06-27 00:05:25 -07001745 }
1746
1747 cert_subject = X509_get_subject_name(cert);
1748 i = -1;
1749 while (!ok && (i = X509_NAME_get_index_by_NID(cert_subject, NID_commonName, i)) != -1) {
1750 X509_NAME_ENTRY *entry = X509_NAME_get_entry(cert_subject, i);
1751 if (ASN1_STRING_to_UTF8((unsigned char **)&str, entry->value) >= 0) {
1752 ok = ssl_sock_srv_hostcheck(str, servername);
1753 OPENSSL_free(str);
1754 }
1755 }
1756
1757 return ok;
1758}
1759
Emeric Brun94324a42012-10-11 14:00:19 +02001760/* prepare ssl context from servers options. Returns an error count */
1761int ssl_sock_prepare_srv_ctx(struct server *srv, struct proxy *curproxy)
1762{
1763 int cfgerr = 0;
Remi Gacogneaf5c3da2014-05-19 10:29:58 +02001764 long options =
Emeric Brun94324a42012-10-11 14:00:19 +02001765 SSL_OP_ALL | /* all known workarounds for bugs */
1766 SSL_OP_NO_SSLv2 |
1767 SSL_OP_NO_COMPRESSION;
Remi Gacogneaf5c3da2014-05-19 10:29:58 +02001768 long mode =
Emeric Brun94324a42012-10-11 14:00:19 +02001769 SSL_MODE_ENABLE_PARTIAL_WRITE |
1770 SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER |
1771 SSL_MODE_RELEASE_BUFFERS;
Emeric Brun850efd52014-01-29 12:24:34 +01001772 int verify = SSL_VERIFY_NONE;
Emeric Brun94324a42012-10-11 14:00:19 +02001773
Thierry Fournier383085f2013-01-24 14:15:43 +01001774 /* Make sure openssl opens /dev/urandom before the chroot */
1775 if (!ssl_initialize_random()) {
1776 Alert("OpenSSL random data generator initialization failed.\n");
1777 cfgerr++;
1778 }
1779
Emeric Brun94324a42012-10-11 14:00:19 +02001780 /* Initiate SSL context for current server */
1781 srv->ssl_ctx.reused_sess = NULL;
1782 if (srv->use_ssl)
1783 srv->xprt = &ssl_sock;
1784 if (srv->check.use_ssl)
Simon Horman66183002013-02-23 10:16:43 +09001785 srv->check_common.xprt = &ssl_sock;
Emeric Brun94324a42012-10-11 14:00:19 +02001786
1787 srv->ssl_ctx.ctx = SSL_CTX_new(SSLv23_client_method());
1788 if (!srv->ssl_ctx.ctx) {
1789 Alert("config : %s '%s', server '%s': unable to allocate ssl context.\n",
1790 proxy_type_str(curproxy), curproxy->id,
1791 srv->id);
1792 cfgerr++;
1793 return cfgerr;
1794 }
Emeric Bruna7aa3092012-10-26 12:58:00 +02001795 if (srv->ssl_ctx.client_crt) {
1796 if (SSL_CTX_use_PrivateKey_file(srv->ssl_ctx.ctx, srv->ssl_ctx.client_crt, SSL_FILETYPE_PEM) <= 0) {
1797 Alert("config : %s '%s', server '%s': unable to load SSL private key from PEM file '%s'.\n",
1798 proxy_type_str(curproxy), curproxy->id,
1799 srv->id, srv->ssl_ctx.client_crt);
1800 cfgerr++;
1801 }
1802 else if (SSL_CTX_use_certificate_chain_file(srv->ssl_ctx.ctx, srv->ssl_ctx.client_crt) <= 0) {
1803 Alert("config : %s '%s', server '%s': unable to load ssl certificate from PEM file '%s'.\n",
1804 proxy_type_str(curproxy), curproxy->id,
1805 srv->id, srv->ssl_ctx.client_crt);
1806 cfgerr++;
1807 }
1808 else if (SSL_CTX_check_private_key(srv->ssl_ctx.ctx) <= 0) {
1809 Alert("config : %s '%s', server '%s': inconsistencies between private key and certificate loaded from PEM file '%s'.\n",
1810 proxy_type_str(curproxy), curproxy->id,
1811 srv->id, srv->ssl_ctx.client_crt);
1812 cfgerr++;
1813 }
1814 }
Emeric Brun94324a42012-10-11 14:00:19 +02001815
1816 if (srv->ssl_ctx.options & SRV_SSL_O_NO_SSLV3)
1817 options |= SSL_OP_NO_SSLv3;
1818 if (srv->ssl_ctx.options & SRV_SSL_O_NO_TLSV10)
1819 options |= SSL_OP_NO_TLSv1;
1820 if (srv->ssl_ctx.options & SRV_SSL_O_NO_TLSV11)
1821 options |= SSL_OP_NO_TLSv1_1;
1822 if (srv->ssl_ctx.options & SRV_SSL_O_NO_TLSV12)
1823 options |= SSL_OP_NO_TLSv1_2;
Emeric Brunf9c5c472012-10-11 15:28:34 +02001824 if (srv->ssl_ctx.options & SRV_SSL_O_NO_TLS_TICKETS)
1825 options |= SSL_OP_NO_TICKET;
Emeric Brun94324a42012-10-11 14:00:19 +02001826 if (srv->ssl_ctx.options & SRV_SSL_O_USE_SSLV3)
1827 SSL_CTX_set_ssl_version(srv->ssl_ctx.ctx, SSLv3_client_method());
1828 if (srv->ssl_ctx.options & SRV_SSL_O_USE_TLSV10)
1829 SSL_CTX_set_ssl_version(srv->ssl_ctx.ctx, TLSv1_client_method());
1830#if SSL_OP_NO_TLSv1_1
1831 if (srv->ssl_ctx.options & SRV_SSL_O_USE_TLSV11)
1832 SSL_CTX_set_ssl_version(srv->ssl_ctx.ctx, TLSv1_1_client_method());
1833#endif
1834#if SSL_OP_NO_TLSv1_2
1835 if (srv->ssl_ctx.options & SRV_SSL_O_USE_TLSV12)
1836 SSL_CTX_set_ssl_version(srv->ssl_ctx.ctx, TLSv1_2_client_method());
1837#endif
1838
1839 SSL_CTX_set_options(srv->ssl_ctx.ctx, options);
1840 SSL_CTX_set_mode(srv->ssl_ctx.ctx, mode);
Emeric Brun850efd52014-01-29 12:24:34 +01001841
1842 if (global.ssl_server_verify == SSL_SERVER_VERIFY_REQUIRED)
1843 verify = SSL_VERIFY_PEER;
1844
1845 switch (srv->ssl_ctx.verify) {
1846 case SSL_SOCK_VERIFY_NONE:
1847 verify = SSL_VERIFY_NONE;
1848 break;
1849 case SSL_SOCK_VERIFY_REQUIRED:
1850 verify = SSL_VERIFY_PEER;
1851 break;
1852 }
Evan Broderbe554312013-06-27 00:05:25 -07001853 SSL_CTX_set_verify(srv->ssl_ctx.ctx,
Emeric Brun850efd52014-01-29 12:24:34 +01001854 verify,
Evan Broderbe554312013-06-27 00:05:25 -07001855 srv->ssl_ctx.verify_host ? ssl_sock_srv_verifycbk : NULL);
Emeric Brun850efd52014-01-29 12:24:34 +01001856 if (verify & SSL_VERIFY_PEER) {
Emeric Brunef42d922012-10-11 16:11:36 +02001857 if (srv->ssl_ctx.ca_file) {
1858 /* load CAfile to verify */
1859 if (!SSL_CTX_load_verify_locations(srv->ssl_ctx.ctx, srv->ssl_ctx.ca_file, NULL)) {
Willy Tarreau07ba08b2014-02-16 19:22:08 +01001860 Alert("Proxy '%s', server '%s' [%s:%d] unable to load CA file '%s'.\n",
Emeric Brunef42d922012-10-11 16:11:36 +02001861 curproxy->id, srv->id,
1862 srv->conf.file, srv->conf.line, srv->ssl_ctx.ca_file);
1863 cfgerr++;
1864 }
1865 }
Emeric Brun850efd52014-01-29 12:24:34 +01001866 else {
1867 if (global.ssl_server_verify == SSL_SERVER_VERIFY_REQUIRED)
Willy Tarreau07ba08b2014-02-16 19:22:08 +01001868 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 +01001869 curproxy->id, srv->id,
1870 srv->conf.file, srv->conf.line);
1871 else
Willy Tarreau07ba08b2014-02-16 19:22:08 +01001872 Alert("Proxy '%s', server '%s' [%s:%d] verify is enabled but no CA file specified.\n",
Emeric Brun850efd52014-01-29 12:24:34 +01001873 curproxy->id, srv->id,
1874 srv->conf.file, srv->conf.line);
1875 cfgerr++;
1876 }
Emeric Brunef42d922012-10-11 16:11:36 +02001877#ifdef X509_V_FLAG_CRL_CHECK
1878 if (srv->ssl_ctx.crl_file) {
1879 X509_STORE *store = SSL_CTX_get_cert_store(srv->ssl_ctx.ctx);
1880
1881 if (!store || !X509_STORE_load_locations(store, srv->ssl_ctx.crl_file, NULL)) {
Willy Tarreau07ba08b2014-02-16 19:22:08 +01001882 Alert("Proxy '%s', server '%s' [%s:%d] unable to configure CRL file '%s'.\n",
Emeric Brunef42d922012-10-11 16:11:36 +02001883 curproxy->id, srv->id,
1884 srv->conf.file, srv->conf.line, srv->ssl_ctx.crl_file);
1885 cfgerr++;
1886 }
1887 else {
1888 X509_STORE_set_flags(store, X509_V_FLAG_CRL_CHECK|X509_V_FLAG_CRL_CHECK_ALL);
1889 }
1890 }
1891#endif
1892 }
1893
Emeric Brun4f65bff2012-11-16 15:11:00 +01001894 if (global.tune.ssllifetime)
1895 SSL_CTX_set_timeout(srv->ssl_ctx.ctx, global.tune.ssllifetime);
1896
Emeric Brun94324a42012-10-11 14:00:19 +02001897 SSL_CTX_set_session_cache_mode(srv->ssl_ctx.ctx, SSL_SESS_CACHE_OFF);
1898 if (srv->ssl_ctx.ciphers &&
1899 !SSL_CTX_set_cipher_list(srv->ssl_ctx.ctx, srv->ssl_ctx.ciphers)) {
1900 Alert("Proxy '%s', server '%s' [%s:%d] : unable to set SSL cipher list to '%s'.\n",
1901 curproxy->id, srv->id,
1902 srv->conf.file, srv->conf.line, srv->ssl_ctx.ciphers);
1903 cfgerr++;
1904 }
1905
1906 return cfgerr;
1907}
1908
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001909/* Walks down the two trees in bind_conf and prepares all certs. The pointer may
Emeric Brunfc0421f2012-09-07 17:30:07 +02001910 * be NULL, in which case nothing is done. Returns the number of errors
1911 * encountered.
1912 */
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001913int ssl_sock_prepare_all_ctx(struct bind_conf *bind_conf, struct proxy *px)
Emeric Brunfc0421f2012-09-07 17:30:07 +02001914{
1915 struct ebmb_node *node;
1916 struct sni_ctx *sni;
1917 int err = 0;
1918
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001919 if (!bind_conf || !bind_conf->is_ssl)
Emeric Brunfc0421f2012-09-07 17:30:07 +02001920 return 0;
1921
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001922 node = ebmb_first(&bind_conf->sni_ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001923 while (node) {
1924 sni = ebmb_entry(node, struct sni_ctx, name);
1925 if (!sni->order) /* only initialize the CTX on its first occurrence */
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001926 err += ssl_sock_prepare_ctx(bind_conf, sni->ctx, px);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001927 node = ebmb_next(node);
1928 }
1929
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001930 node = ebmb_first(&bind_conf->sni_w_ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001931 while (node) {
1932 sni = ebmb_entry(node, struct sni_ctx, name);
1933 if (!sni->order) /* only initialize the CTX on its first occurrence */
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001934 err += ssl_sock_prepare_ctx(bind_conf, sni->ctx, px);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001935 node = ebmb_next(node);
1936 }
1937 return err;
1938}
1939
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001940/* Walks down the two trees in bind_conf and frees all the certs. The pointer may
Emeric Brunfc0421f2012-09-07 17:30:07 +02001941 * be NULL, in which case nothing is done. The default_ctx is nullified too.
1942 */
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001943void ssl_sock_free_all_ctx(struct bind_conf *bind_conf)
Emeric Brunfc0421f2012-09-07 17:30:07 +02001944{
1945 struct ebmb_node *node, *back;
1946 struct sni_ctx *sni;
1947
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001948 if (!bind_conf || !bind_conf->is_ssl)
Emeric Brunfc0421f2012-09-07 17:30:07 +02001949 return;
1950
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001951 node = ebmb_first(&bind_conf->sni_ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001952 while (node) {
1953 sni = ebmb_entry(node, struct sni_ctx, name);
1954 back = ebmb_next(node);
1955 ebmb_delete(node);
1956 if (!sni->order) /* only free the CTX on its first occurrence */
1957 SSL_CTX_free(sni->ctx);
1958 free(sni);
1959 node = back;
1960 }
1961
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001962 node = ebmb_first(&bind_conf->sni_w_ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001963 while (node) {
1964 sni = ebmb_entry(node, struct sni_ctx, name);
1965 back = ebmb_next(node);
1966 ebmb_delete(node);
1967 if (!sni->order) /* only free the CTX on its first occurrence */
1968 SSL_CTX_free(sni->ctx);
1969 free(sni);
1970 node = back;
1971 }
1972
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001973 bind_conf->default_ctx = NULL;
Emeric Brune1f38db2012-09-03 20:36:47 +02001974}
1975
Emeric Brun46591952012-05-18 15:47:34 +02001976/*
1977 * This function is called if SSL * context is not yet allocated. The function
1978 * is designed to be called before any other data-layer operation and sets the
1979 * handshake flag on the connection. It is safe to call it multiple times.
1980 * It returns 0 on success and -1 in error case.
1981 */
1982static int ssl_sock_init(struct connection *conn)
1983{
1984 /* already initialized */
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02001985 if (conn->xprt_ctx)
Emeric Brun46591952012-05-18 15:47:34 +02001986 return 0;
1987
Willy Tarreau3c728722014-01-23 13:50:42 +01001988 if (!conn_ctrl_ready(conn))
Willy Tarreauf79c8172013-10-21 16:30:56 +02001989 return 0;
1990
Willy Tarreau20879a02012-12-03 16:32:10 +01001991 if (global.maxsslconn && sslconns >= global.maxsslconn) {
1992 conn->err_code = CO_ER_SSL_TOO_MANY;
Willy Tarreau403edff2012-09-06 11:58:37 +02001993 return -1;
Willy Tarreau20879a02012-12-03 16:32:10 +01001994 }
Willy Tarreau403edff2012-09-06 11:58:37 +02001995
Emeric Brun46591952012-05-18 15:47:34 +02001996 /* If it is in client mode initiate SSL session
1997 in connect state otherwise accept state */
Willy Tarreau3fdb3662012-11-12 00:42:33 +01001998 if (objt_server(conn->target)) {
Emeric Brun46591952012-05-18 15:47:34 +02001999 /* Alloc a new SSL session ctx */
Willy Tarreau3fdb3662012-11-12 00:42:33 +01002000 conn->xprt_ctx = SSL_new(objt_server(conn->target)->ssl_ctx.ctx);
Willy Tarreau20879a02012-12-03 16:32:10 +01002001 if (!conn->xprt_ctx) {
2002 conn->err_code = CO_ER_SSL_NO_MEM;
Emeric Brun46591952012-05-18 15:47:34 +02002003 return -1;
Willy Tarreau20879a02012-12-03 16:32:10 +01002004 }
Emeric Brun46591952012-05-18 15:47:34 +02002005
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02002006 SSL_set_connect_state(conn->xprt_ctx);
Willy Tarreau3fdb3662012-11-12 00:42:33 +01002007 if (objt_server(conn->target)->ssl_ctx.reused_sess)
2008 SSL_set_session(conn->xprt_ctx, objt_server(conn->target)->ssl_ctx.reused_sess);
Emeric Brun46591952012-05-18 15:47:34 +02002009
2010 /* set fd on SSL session context */
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02002011 SSL_set_fd(conn->xprt_ctx, conn->t.sock.fd);
Emeric Brun46591952012-05-18 15:47:34 +02002012
Evan Broderbe554312013-06-27 00:05:25 -07002013 /* set connection pointer */
2014 SSL_set_app_data(conn->xprt_ctx, conn);
2015
Emeric Brun46591952012-05-18 15:47:34 +02002016 /* leave init state and start handshake */
Willy Tarreau05737472012-09-04 08:03:39 +02002017 conn->flags |= CO_FL_SSL_WAIT_HS | CO_FL_WAIT_L6_CONN;
Willy Tarreau403edff2012-09-06 11:58:37 +02002018
2019 sslconns++;
Willy Tarreau71b734c2014-01-28 15:19:44 +01002020 totalsslconns++;
Emeric Brun46591952012-05-18 15:47:34 +02002021 return 0;
2022 }
Willy Tarreau3fdb3662012-11-12 00:42:33 +01002023 else if (objt_listener(conn->target)) {
Emeric Brun46591952012-05-18 15:47:34 +02002024 /* Alloc a new SSL session ctx */
Willy Tarreau3fdb3662012-11-12 00:42:33 +01002025 conn->xprt_ctx = SSL_new(objt_listener(conn->target)->bind_conf->default_ctx);
Willy Tarreau20879a02012-12-03 16:32:10 +01002026 if (!conn->xprt_ctx) {
2027 conn->err_code = CO_ER_SSL_NO_MEM;
Emeric Brun46591952012-05-18 15:47:34 +02002028 return -1;
Willy Tarreau20879a02012-12-03 16:32:10 +01002029 }
Emeric Brun46591952012-05-18 15:47:34 +02002030
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02002031 SSL_set_accept_state(conn->xprt_ctx);
Emeric Brun46591952012-05-18 15:47:34 +02002032
2033 /* set fd on SSL session context */
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02002034 SSL_set_fd(conn->xprt_ctx, conn->t.sock.fd);
Emeric Brun46591952012-05-18 15:47:34 +02002035
Emeric Brune1f38db2012-09-03 20:36:47 +02002036 /* set connection pointer */
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02002037 SSL_set_app_data(conn->xprt_ctx, conn);
Emeric Brune1f38db2012-09-03 20:36:47 +02002038
Emeric Brun46591952012-05-18 15:47:34 +02002039 /* leave init state and start handshake */
Willy Tarreau05737472012-09-04 08:03:39 +02002040 conn->flags |= CO_FL_SSL_WAIT_HS | CO_FL_WAIT_L6_CONN;
Willy Tarreau403edff2012-09-06 11:58:37 +02002041
2042 sslconns++;
Willy Tarreau71b734c2014-01-28 15:19:44 +01002043 totalsslconns++;
Emeric Brun46591952012-05-18 15:47:34 +02002044 return 0;
2045 }
2046 /* don't know how to handle such a target */
Willy Tarreau20879a02012-12-03 16:32:10 +01002047 conn->err_code = CO_ER_SSL_NO_TARGET;
Emeric Brun46591952012-05-18 15:47:34 +02002048 return -1;
2049}
2050
2051
2052/* This is the callback which is used when an SSL handshake is pending. It
2053 * updates the FD status if it wants some polling before being called again.
2054 * It returns 0 if it fails in a fatal way or needs to poll to go further,
2055 * otherwise it returns non-zero and removes itself from the connection's
2056 * flags (the bit is provided in <flag> by the caller).
2057 */
2058int ssl_sock_handshake(struct connection *conn, unsigned int flag)
2059{
2060 int ret;
2061
Willy Tarreau3c728722014-01-23 13:50:42 +01002062 if (!conn_ctrl_ready(conn))
Willy Tarreauf79c8172013-10-21 16:30:56 +02002063 return 0;
2064
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02002065 if (!conn->xprt_ctx)
Emeric Brun46591952012-05-18 15:47:34 +02002066 goto out_error;
2067
Emeric Brun674b7432012-11-08 19:21:55 +01002068 /* If we use SSL_do_handshake to process a reneg initiated by
2069 * the remote peer, it sometimes returns SSL_ERROR_SSL.
2070 * Usually SSL_write and SSL_read are used and process implicitly
2071 * the reneg handshake.
2072 * Here we use SSL_peek as a workaround for reneg.
2073 */
2074 if ((conn->flags & CO_FL_CONNECTED) && SSL_renegotiate_pending(conn->xprt_ctx)) {
2075 char c;
2076
2077 ret = SSL_peek(conn->xprt_ctx, &c, 1);
2078 if (ret <= 0) {
2079 /* handshake may have not been completed, let's find why */
2080 ret = SSL_get_error(conn->xprt_ctx, ret);
2081 if (ret == SSL_ERROR_WANT_WRITE) {
2082 /* SSL handshake needs to write, L4 connection may not be ready */
2083 __conn_sock_stop_recv(conn);
Willy Tarreaue1f50c42014-01-22 20:02:06 +01002084 __conn_sock_want_send(conn);
2085 fd_cant_send(conn->t.sock.fd);
Emeric Brun674b7432012-11-08 19:21:55 +01002086 return 0;
2087 }
2088 else if (ret == SSL_ERROR_WANT_READ) {
2089 /* handshake may have been completed but we have
2090 * no more data to read.
2091 */
2092 if (!SSL_renegotiate_pending(conn->xprt_ctx)) {
2093 ret = 1;
2094 goto reneg_ok;
2095 }
2096 /* SSL handshake needs to read, L4 connection is ready */
2097 if (conn->flags & CO_FL_WAIT_L4_CONN)
2098 conn->flags &= ~CO_FL_WAIT_L4_CONN;
2099 __conn_sock_stop_send(conn);
Willy Tarreaue1f50c42014-01-22 20:02:06 +01002100 __conn_sock_want_recv(conn);
2101 fd_cant_recv(conn->t.sock.fd);
Emeric Brun674b7432012-11-08 19:21:55 +01002102 return 0;
2103 }
2104 else if (ret == SSL_ERROR_SYSCALL) {
2105 /* if errno is null, then connection was successfully established */
2106 if (!errno && conn->flags & CO_FL_WAIT_L4_CONN)
2107 conn->flags &= ~CO_FL_WAIT_L4_CONN;
Willy Tarreau20879a02012-12-03 16:32:10 +01002108 if (!conn->err_code) {
Emeric Brun29f037d2014-04-25 19:05:36 +02002109 if (!((SSL *)conn->xprt_ctx)->packet_length) {
2110 if (!errno) {
2111 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
2112 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
2113 else
2114 conn->err_code = CO_ER_SSL_EMPTY;
2115 }
2116 else {
2117 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
2118 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
2119 else
2120 conn->err_code = CO_ER_SSL_ABORT;
2121 }
2122 }
2123 else {
2124 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
2125 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
Willy Tarreau20879a02012-12-03 16:32:10 +01002126 else
Emeric Brun29f037d2014-04-25 19:05:36 +02002127 conn->err_code = CO_ER_SSL_HANDSHAKE;
2128 }
Willy Tarreau20879a02012-12-03 16:32:10 +01002129 }
Emeric Brun674b7432012-11-08 19:21:55 +01002130 goto out_error;
2131 }
2132 else {
2133 /* Fail on all other handshake errors */
2134 /* Note: OpenSSL may leave unread bytes in the socket's
2135 * buffer, causing an RST to be emitted upon close() on
2136 * TCP sockets. We first try to drain possibly pending
2137 * data to avoid this as much as possible.
2138 */
Willy Tarreau46be2e52014-01-20 12:10:52 +01002139 conn_drain(conn);
Willy Tarreau20879a02012-12-03 16:32:10 +01002140 if (!conn->err_code)
Willy Tarreauf51c6982014-04-25 20:02:39 +02002141 conn->err_code = (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT) ?
2142 CO_ER_SSL_KILLED_HB : CO_ER_SSL_HANDSHAKE;
Emeric Brun674b7432012-11-08 19:21:55 +01002143 goto out_error;
2144 }
2145 }
2146 /* read some data: consider handshake completed */
2147 goto reneg_ok;
2148 }
2149
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02002150 ret = SSL_do_handshake(conn->xprt_ctx);
Emeric Brun46591952012-05-18 15:47:34 +02002151 if (ret != 1) {
2152 /* handshake did not complete, let's find why */
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02002153 ret = SSL_get_error(conn->xprt_ctx, ret);
Emeric Brun46591952012-05-18 15:47:34 +02002154
2155 if (ret == SSL_ERROR_WANT_WRITE) {
2156 /* SSL handshake needs to write, L4 connection may not be ready */
2157 __conn_sock_stop_recv(conn);
Willy Tarreaue1f50c42014-01-22 20:02:06 +01002158 __conn_sock_want_send(conn);
2159 fd_cant_send(conn->t.sock.fd);
Emeric Brun46591952012-05-18 15:47:34 +02002160 return 0;
2161 }
2162 else if (ret == SSL_ERROR_WANT_READ) {
2163 /* SSL handshake needs to read, L4 connection is ready */
2164 if (conn->flags & CO_FL_WAIT_L4_CONN)
2165 conn->flags &= ~CO_FL_WAIT_L4_CONN;
2166 __conn_sock_stop_send(conn);
Willy Tarreaue1f50c42014-01-22 20:02:06 +01002167 __conn_sock_want_recv(conn);
2168 fd_cant_recv(conn->t.sock.fd);
Emeric Brun46591952012-05-18 15:47:34 +02002169 return 0;
2170 }
Willy Tarreau89230192012-09-28 20:22:13 +02002171 else if (ret == SSL_ERROR_SYSCALL) {
2172 /* if errno is null, then connection was successfully established */
2173 if (!errno && conn->flags & CO_FL_WAIT_L4_CONN)
2174 conn->flags &= ~CO_FL_WAIT_L4_CONN;
Willy Tarreau20879a02012-12-03 16:32:10 +01002175
Emeric Brun29f037d2014-04-25 19:05:36 +02002176 if (!((SSL *)conn->xprt_ctx)->packet_length) {
2177 if (!errno) {
2178 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
2179 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
2180 else
2181 conn->err_code = CO_ER_SSL_EMPTY;
2182 }
2183 else {
2184 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
2185 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
2186 else
2187 conn->err_code = CO_ER_SSL_ABORT;
2188 }
2189 }
2190 else {
2191 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
2192 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
Willy Tarreau20879a02012-12-03 16:32:10 +01002193 else
Emeric Brun29f037d2014-04-25 19:05:36 +02002194 conn->err_code = CO_ER_SSL_HANDSHAKE;
2195 }
Willy Tarreau89230192012-09-28 20:22:13 +02002196 goto out_error;
2197 }
Emeric Brun46591952012-05-18 15:47:34 +02002198 else {
2199 /* Fail on all other handshake errors */
Willy Tarreau566dc552012-10-19 20:52:18 +02002200 /* Note: OpenSSL may leave unread bytes in the socket's
2201 * buffer, causing an RST to be emitted upon close() on
2202 * TCP sockets. We first try to drain possibly pending
2203 * data to avoid this as much as possible.
2204 */
Willy Tarreau46be2e52014-01-20 12:10:52 +01002205 conn_drain(conn);
Willy Tarreau20879a02012-12-03 16:32:10 +01002206 if (!conn->err_code)
Willy Tarreauf51c6982014-04-25 20:02:39 +02002207 conn->err_code = (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT) ?
2208 CO_ER_SSL_KILLED_HB : CO_ER_SSL_HANDSHAKE;
Emeric Brun46591952012-05-18 15:47:34 +02002209 goto out_error;
2210 }
2211 }
2212
Emeric Brun674b7432012-11-08 19:21:55 +01002213reneg_ok:
2214
Emeric Brun46591952012-05-18 15:47:34 +02002215 /* Handshake succeeded */
Willy Tarreau0c9c2722014-05-28 12:28:58 +02002216 if (!SSL_session_reused(conn->xprt_ctx)) {
2217 if (objt_server(conn->target)) {
2218 update_freq_ctr(&global.ssl_be_keys_per_sec, 1);
2219 if (global.ssl_be_keys_per_sec.curr_ctr > global.ssl_be_keys_max)
2220 global.ssl_be_keys_max = global.ssl_be_keys_per_sec.curr_ctr;
2221
Emeric Brun46591952012-05-18 15:47:34 +02002222 /* check if session was reused, if not store current session on server for reuse */
Willy Tarreau3fdb3662012-11-12 00:42:33 +01002223 if (objt_server(conn->target)->ssl_ctx.reused_sess)
2224 SSL_SESSION_free(objt_server(conn->target)->ssl_ctx.reused_sess);
Emeric Brun46591952012-05-18 15:47:34 +02002225
Willy Tarreau3fdb3662012-11-12 00:42:33 +01002226 objt_server(conn->target)->ssl_ctx.reused_sess = SSL_get1_session(conn->xprt_ctx);
Emeric Brun46591952012-05-18 15:47:34 +02002227 }
Willy Tarreau0c9c2722014-05-28 12:28:58 +02002228 else {
2229 update_freq_ctr(&global.ssl_fe_keys_per_sec, 1);
2230 if (global.ssl_fe_keys_per_sec.curr_ctr > global.ssl_fe_keys_max)
2231 global.ssl_fe_keys_max = global.ssl_fe_keys_per_sec.curr_ctr;
2232 }
Emeric Brun46591952012-05-18 15:47:34 +02002233 }
2234
2235 /* The connection is now established at both layers, it's time to leave */
2236 conn->flags &= ~(flag | CO_FL_WAIT_L4_CONN | CO_FL_WAIT_L6_CONN);
2237 return 1;
2238
2239 out_error:
Emeric Brun644cde02012-12-14 11:21:13 +01002240 /* Clear openssl global errors stack */
2241 ERR_clear_error();
2242
Emeric Brun9fa89732012-10-04 17:09:56 +02002243 /* free resumed session if exists */
Willy Tarreau3fdb3662012-11-12 00:42:33 +01002244 if (objt_server(conn->target) && objt_server(conn->target)->ssl_ctx.reused_sess) {
2245 SSL_SESSION_free(objt_server(conn->target)->ssl_ctx.reused_sess);
2246 objt_server(conn->target)->ssl_ctx.reused_sess = NULL;
Emeric Brun9fa89732012-10-04 17:09:56 +02002247 }
2248
Emeric Brun46591952012-05-18 15:47:34 +02002249 /* Fail on all other handshake errors */
2250 conn->flags |= CO_FL_ERROR;
Willy Tarreau20879a02012-12-03 16:32:10 +01002251 if (!conn->err_code)
2252 conn->err_code = CO_ER_SSL_HANDSHAKE;
Emeric Brun46591952012-05-18 15:47:34 +02002253 return 0;
2254}
2255
2256/* Receive up to <count> bytes from connection <conn>'s socket and store them
Willy Tarreauabf08d92014-01-14 11:31:27 +01002257 * into buffer <buf>. Only one call to recv() is performed, unless the
Emeric Brun46591952012-05-18 15:47:34 +02002258 * buffer wraps, in which case a second call may be performed. The connection's
2259 * flags are updated with whatever special event is detected (error, read0,
2260 * empty). The caller is responsible for taking care of those events and
2261 * avoiding the call if inappropriate. The function does not call the
2262 * connection's polling update function, so the caller is responsible for this.
2263 */
2264static int ssl_sock_to_buf(struct connection *conn, struct buffer *buf, int count)
2265{
2266 int ret, done = 0;
Willy Tarreauabf08d92014-01-14 11:31:27 +01002267 int try;
Emeric Brun46591952012-05-18 15:47:34 +02002268
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02002269 if (!conn->xprt_ctx)
Emeric Brun46591952012-05-18 15:47:34 +02002270 goto out_error;
2271
2272 if (conn->flags & CO_FL_HANDSHAKE)
2273 /* a handshake was requested */
2274 return 0;
2275
Willy Tarreauabf08d92014-01-14 11:31:27 +01002276 /* let's realign the buffer to optimize I/O */
2277 if (buffer_empty(buf))
Emeric Brun46591952012-05-18 15:47:34 +02002278 buf->p = buf->data;
Emeric Brun46591952012-05-18 15:47:34 +02002279
2280 /* read the largest possible block. For this, we perform only one call
2281 * to recv() unless the buffer wraps and we exactly fill the first hunk,
2282 * in which case we accept to do it once again. A new attempt is made on
2283 * EINTR too.
2284 */
Willy Tarreau00b0fb92014-01-17 11:09:40 +01002285 while (count > 0) {
Willy Tarreauabf08d92014-01-14 11:31:27 +01002286 /* first check if we have some room after p+i */
2287 try = buf->data + buf->size - (buf->p + buf->i);
2288 /* otherwise continue between data and p-o */
2289 if (try <= 0) {
2290 try = buf->p - (buf->data + buf->o);
2291 if (try <= 0)
2292 break;
2293 }
2294 if (try > count)
2295 try = count;
2296
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02002297 ret = SSL_read(conn->xprt_ctx, bi_end(buf), try);
Emeric Brune1f38db2012-09-03 20:36:47 +02002298 if (conn->flags & CO_FL_ERROR) {
2299 /* CO_FL_ERROR may be set by ssl_sock_infocbk */
Emeric Brun644cde02012-12-14 11:21:13 +01002300 goto out_error;
Emeric Brune1f38db2012-09-03 20:36:47 +02002301 }
Emeric Brun46591952012-05-18 15:47:34 +02002302 if (ret > 0) {
2303 buf->i += ret;
2304 done += ret;
2305 if (ret < try)
2306 break;
2307 count -= ret;
Emeric Brun46591952012-05-18 15:47:34 +02002308 }
2309 else if (ret == 0) {
Emeric Brun644cde02012-12-14 11:21:13 +01002310 ret = SSL_get_error(conn->xprt_ctx, ret);
2311 if (ret != SSL_ERROR_ZERO_RETURN) {
Emeric Brun1c646862012-12-14 12:33:41 +01002312 /* error on protocol or underlying transport */
2313 if ((ret != SSL_ERROR_SYSCALL)
2314 || (errno && (errno != EAGAIN)))
2315 conn->flags |= CO_FL_ERROR;
2316
Emeric Brun644cde02012-12-14 11:21:13 +01002317 /* Clear openssl global errors stack */
2318 ERR_clear_error();
2319 }
Emeric Brun46591952012-05-18 15:47:34 +02002320 goto read0;
2321 }
2322 else {
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02002323 ret = SSL_get_error(conn->xprt_ctx, ret);
Emeric Brun46591952012-05-18 15:47:34 +02002324 if (ret == SSL_ERROR_WANT_WRITE) {
Emeric Brun8af8dd12012-11-08 17:56:20 +01002325 /* handshake is running, and it needs to enable write */
Emeric Brun46591952012-05-18 15:47:34 +02002326 conn->flags |= CO_FL_SSL_WAIT_HS;
Emeric Brun8af8dd12012-11-08 17:56:20 +01002327 __conn_sock_want_send(conn);
Emeric Brun46591952012-05-18 15:47:34 +02002328 break;
2329 }
2330 else if (ret == SSL_ERROR_WANT_READ) {
Emeric Brun282a76a2012-11-08 18:02:56 +01002331 if (SSL_renegotiate_pending(conn->xprt_ctx)) {
2332 /* handshake is running, and it may need to re-enable read */
2333 conn->flags |= CO_FL_SSL_WAIT_HS;
2334 __conn_sock_want_recv(conn);
2335 break;
2336 }
Emeric Brun46591952012-05-18 15:47:34 +02002337 /* we need to poll for retry a read later */
Willy Tarreaue1f50c42014-01-22 20:02:06 +01002338 fd_cant_recv(conn->t.sock.fd);
Emeric Brun46591952012-05-18 15:47:34 +02002339 break;
2340 }
2341 /* otherwise it's a real error */
2342 goto out_error;
2343 }
2344 }
2345 return done;
2346
2347 read0:
2348 conn_sock_read0(conn);
2349 return done;
2350 out_error:
Emeric Brun644cde02012-12-14 11:21:13 +01002351 /* Clear openssl global errors stack */
2352 ERR_clear_error();
2353
Emeric Brun46591952012-05-18 15:47:34 +02002354 conn->flags |= CO_FL_ERROR;
2355 return done;
2356}
2357
2358
2359/* Send all pending bytes from buffer <buf> to connection <conn>'s socket.
Willy Tarreau1049b1f2014-02-02 01:51:17 +01002360 * <flags> may contain some CO_SFL_* flags to hint the system about other
2361 * pending data for example, but this flag is ignored at the moment.
Emeric Brun46591952012-05-18 15:47:34 +02002362 * Only one call to send() is performed, unless the buffer wraps, in which case
2363 * a second call may be performed. The connection's flags are updated with
2364 * whatever special event is detected (error, empty). The caller is responsible
2365 * for taking care of those events and avoiding the call if inappropriate. The
2366 * function does not call the connection's polling update function, so the caller
2367 * is responsible for this.
2368 */
2369static int ssl_sock_from_buf(struct connection *conn, struct buffer *buf, int flags)
2370{
2371 int ret, try, done;
2372
2373 done = 0;
2374
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02002375 if (!conn->xprt_ctx)
Emeric Brun46591952012-05-18 15:47:34 +02002376 goto out_error;
2377
2378 if (conn->flags & CO_FL_HANDSHAKE)
2379 /* a handshake was requested */
2380 return 0;
2381
2382 /* send the largest possible block. For this we perform only one call
2383 * to send() unless the buffer wraps and we exactly fill the first hunk,
2384 * in which case we accept to do it once again.
2385 */
2386 while (buf->o) {
Kevin Hestercad82342013-05-30 15:12:41 -07002387 try = bo_contig_data(buf);
Willy Tarreaubfd59462013-02-21 07:46:09 +01002388
Willy Tarreau7bed9452014-02-02 02:00:24 +01002389 if (!(flags & CO_SFL_STREAMER) &&
Willy Tarreau518cedd2014-02-17 15:43:01 +01002390 !(conn->xprt_st & SSL_SOCK_SEND_UNLIMITED) &&
2391 global.tune.ssl_max_record && try > global.tune.ssl_max_record) {
Willy Tarreaubfd59462013-02-21 07:46:09 +01002392 try = global.tune.ssl_max_record;
Willy Tarreau518cedd2014-02-17 15:43:01 +01002393 }
2394 else {
2395 /* we need to keep the information about the fact that
2396 * we're not limiting the upcoming send(), because if it
2397 * fails, we'll have to retry with at least as many data.
2398 */
2399 conn->xprt_st |= SSL_SOCK_SEND_UNLIMITED;
2400 }
Willy Tarreaubfd59462013-02-21 07:46:09 +01002401
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02002402 ret = SSL_write(conn->xprt_ctx, bo_ptr(buf), try);
Willy Tarreau518cedd2014-02-17 15:43:01 +01002403
Emeric Brune1f38db2012-09-03 20:36:47 +02002404 if (conn->flags & CO_FL_ERROR) {
2405 /* CO_FL_ERROR may be set by ssl_sock_infocbk */
Emeric Brun644cde02012-12-14 11:21:13 +01002406 goto out_error;
Emeric Brune1f38db2012-09-03 20:36:47 +02002407 }
Emeric Brun46591952012-05-18 15:47:34 +02002408 if (ret > 0) {
Willy Tarreau518cedd2014-02-17 15:43:01 +01002409 conn->xprt_st &= ~SSL_SOCK_SEND_UNLIMITED;
2410
Emeric Brun46591952012-05-18 15:47:34 +02002411 buf->o -= ret;
2412 done += ret;
2413
Willy Tarreau5fb38032012-12-16 19:39:09 +01002414 if (likely(buffer_empty(buf)))
Emeric Brun46591952012-05-18 15:47:34 +02002415 /* optimize data alignment in the buffer */
2416 buf->p = buf->data;
2417
2418 /* if the system buffer is full, don't insist */
2419 if (ret < try)
2420 break;
2421 }
2422 else {
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02002423 ret = SSL_get_error(conn->xprt_ctx, ret);
Emeric Brun46591952012-05-18 15:47:34 +02002424 if (ret == SSL_ERROR_WANT_WRITE) {
Emeric Brun282a76a2012-11-08 18:02:56 +01002425 if (SSL_renegotiate_pending(conn->xprt_ctx)) {
2426 /* handshake is running, and it may need to re-enable write */
2427 conn->flags |= CO_FL_SSL_WAIT_HS;
2428 __conn_sock_want_send(conn);
2429 break;
2430 }
Emeric Brun46591952012-05-18 15:47:34 +02002431 /* we need to poll to retry a write later */
Willy Tarreaue1f50c42014-01-22 20:02:06 +01002432 fd_cant_send(conn->t.sock.fd);
Emeric Brun46591952012-05-18 15:47:34 +02002433 break;
2434 }
2435 else if (ret == SSL_ERROR_WANT_READ) {
Emeric Brun8af8dd12012-11-08 17:56:20 +01002436 /* handshake is running, and it needs to enable read */
Emeric Brun46591952012-05-18 15:47:34 +02002437 conn->flags |= CO_FL_SSL_WAIT_HS;
Emeric Brun8af8dd12012-11-08 17:56:20 +01002438 __conn_sock_want_recv(conn);
Emeric Brun46591952012-05-18 15:47:34 +02002439 break;
2440 }
2441 goto out_error;
2442 }
2443 }
2444 return done;
2445
2446 out_error:
Emeric Brun644cde02012-12-14 11:21:13 +01002447 /* Clear openssl global errors stack */
2448 ERR_clear_error();
2449
Emeric Brun46591952012-05-18 15:47:34 +02002450 conn->flags |= CO_FL_ERROR;
2451 return done;
2452}
2453
Emeric Brun46591952012-05-18 15:47:34 +02002454static void ssl_sock_close(struct connection *conn) {
2455
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02002456 if (conn->xprt_ctx) {
2457 SSL_free(conn->xprt_ctx);
2458 conn->xprt_ctx = NULL;
Willy Tarreau403edff2012-09-06 11:58:37 +02002459 sslconns--;
Emeric Brun46591952012-05-18 15:47:34 +02002460 }
Emeric Brun46591952012-05-18 15:47:34 +02002461}
2462
2463/* This function tries to perform a clean shutdown on an SSL connection, and in
2464 * any case, flags the connection as reusable if no handshake was in progress.
2465 */
2466static void ssl_sock_shutw(struct connection *conn, int clean)
2467{
2468 if (conn->flags & CO_FL_HANDSHAKE)
2469 return;
2470 /* no handshake was in progress, try a clean ssl shutdown */
Emeric Brun644cde02012-12-14 11:21:13 +01002471 if (clean && (SSL_shutdown(conn->xprt_ctx) <= 0)) {
2472 /* Clear openssl global errors stack */
2473 ERR_clear_error();
2474 }
Emeric Brun46591952012-05-18 15:47:34 +02002475
2476 /* force flag on ssl to keep session in cache regardless shutdown result */
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02002477 SSL_set_shutdown(conn->xprt_ctx, SSL_SENT_SHUTDOWN);
Emeric Brun46591952012-05-18 15:47:34 +02002478}
2479
Willy Tarreauffc3fcd2012-10-12 20:17:54 +02002480/* used for logging, may be changed for a sample fetch later */
2481const char *ssl_sock_get_cipher_name(struct connection *conn)
2482{
2483 if (!conn->xprt && !conn->xprt_ctx)
2484 return NULL;
2485 return SSL_get_cipher_name(conn->xprt_ctx);
2486}
2487
2488/* used for logging, may be changed for a sample fetch later */
2489const char *ssl_sock_get_proto_version(struct connection *conn)
2490{
2491 if (!conn->xprt && !conn->xprt_ctx)
2492 return NULL;
2493 return SSL_get_version(conn->xprt_ctx);
2494}
2495
Willy Tarreau8d598402012-10-22 17:58:39 +02002496/* Extract a serial from a cert, and copy it to a chunk.
2497 * Returns 1 if serial is found and copied, 0 if no serial found and
2498 * -1 if output is not large enough.
2499 */
2500static int
2501ssl_sock_get_serial(X509 *crt, struct chunk *out)
2502{
2503 ASN1_INTEGER *serial;
2504
2505 serial = X509_get_serialNumber(crt);
2506 if (!serial)
2507 return 0;
2508
2509 if (out->size < serial->length)
2510 return -1;
2511
2512 memcpy(out->str, serial->data, serial->length);
2513 out->len = serial->length;
2514 return 1;
2515}
2516
Emeric Brunce5ad802012-10-22 14:11:22 +02002517
2518/* Copy Date in ASN1_UTCTIME format in struct chunk out.
2519 * Returns 1 if serial is found and copied, 0 if no valid time found
2520 * and -1 if output is not large enough.
2521 */
2522static int
2523ssl_sock_get_time(ASN1_TIME *tm, struct chunk *out)
2524{
2525 if (tm->type == V_ASN1_GENERALIZEDTIME) {
2526 ASN1_GENERALIZEDTIME *gentm = (ASN1_GENERALIZEDTIME *)tm;
2527
2528 if (gentm->length < 12)
2529 return 0;
2530 if (gentm->data[0] != 0x32 || gentm->data[1] != 0x30)
2531 return 0;
2532 if (out->size < gentm->length-2)
2533 return -1;
2534
2535 memcpy(out->str, gentm->data+2, gentm->length-2);
2536 out->len = gentm->length-2;
2537 return 1;
2538 }
2539 else if (tm->type == V_ASN1_UTCTIME) {
2540 ASN1_UTCTIME *utctm = (ASN1_UTCTIME *)tm;
2541
2542 if (utctm->length < 10)
2543 return 0;
2544 if (utctm->data[0] >= 0x35)
2545 return 0;
2546 if (out->size < utctm->length)
2547 return -1;
2548
2549 memcpy(out->str, utctm->data, utctm->length);
2550 out->len = utctm->length;
2551 return 1;
2552 }
2553
2554 return 0;
2555}
2556
Emeric Brun87855892012-10-17 17:39:35 +02002557/* Extract an entry from a X509_NAME and copy its value to an output chunk.
2558 * Returns 1 if entry found, 0 if entry not found, or -1 if output not large enough.
2559 */
2560static int
2561ssl_sock_get_dn_entry(X509_NAME *a, const struct chunk *entry, int pos, struct chunk *out)
2562{
2563 X509_NAME_ENTRY *ne;
2564 int i, j, n;
2565 int cur = 0;
2566 const char *s;
2567 char tmp[128];
2568
2569 out->len = 0;
2570 for (i = 0; i < sk_X509_NAME_ENTRY_num(a->entries); i++) {
2571 if (pos < 0)
2572 j = (sk_X509_NAME_ENTRY_num(a->entries)-1) - i;
2573 else
2574 j = i;
2575
2576 ne = sk_X509_NAME_ENTRY_value(a->entries, j);
2577 n = OBJ_obj2nid(ne->object);
2578 if ((n == NID_undef) || ((s = OBJ_nid2sn(n)) == NULL)) {
2579 i2t_ASN1_OBJECT(tmp, sizeof(tmp), ne->object);
2580 s = tmp;
2581 }
2582
2583 if (chunk_strcasecmp(entry, s) != 0)
2584 continue;
2585
2586 if (pos < 0)
2587 cur--;
2588 else
2589 cur++;
2590
2591 if (cur != pos)
2592 continue;
2593
2594 if (ne->value->length > out->size)
2595 return -1;
2596
2597 memcpy(out->str, ne->value->data, ne->value->length);
2598 out->len = ne->value->length;
2599 return 1;
2600 }
2601
2602 return 0;
2603
2604}
2605
2606/* Extract and format full DN from a X509_NAME and copy result into a chunk
2607 * Returns 1 if dn entries exits, 0 if no dn entry found or -1 if output is not large enough.
2608 */
2609static int
2610ssl_sock_get_dn_oneline(X509_NAME *a, struct chunk *out)
2611{
2612 X509_NAME_ENTRY *ne;
2613 int i, n, ln;
2614 int l = 0;
2615 const char *s;
2616 char *p;
2617 char tmp[128];
2618
2619 out->len = 0;
2620 p = out->str;
2621 for (i = 0; i < sk_X509_NAME_ENTRY_num(a->entries); i++) {
2622 ne = sk_X509_NAME_ENTRY_value(a->entries, i);
2623 n = OBJ_obj2nid(ne->object);
2624 if ((n == NID_undef) || ((s = OBJ_nid2sn(n)) == NULL)) {
2625 i2t_ASN1_OBJECT(tmp, sizeof(tmp), ne->object);
2626 s = tmp;
2627 }
2628 ln = strlen(s);
2629
2630 l += 1 + ln + 1 + ne->value->length;
2631 if (l > out->size)
2632 return -1;
2633 out->len = l;
2634
2635 *(p++)='/';
2636 memcpy(p, s, ln);
2637 p += ln;
2638 *(p++)='=';
2639 memcpy(p, ne->value->data, ne->value->length);
2640 p += ne->value->length;
2641 }
2642
2643 if (!out->len)
2644 return 0;
2645
2646 return 1;
2647}
2648
David Safb76832014-05-08 23:42:08 -04002649char *ssl_sock_get_version(struct connection *conn)
2650{
2651 if (!ssl_sock_is_ssl(conn))
2652 return NULL;
2653
2654 return (char *)SSL_get_version(conn->xprt_ctx);
2655}
2656
Emeric Brun0abf8362014-06-24 18:26:41 +02002657/* Extract peer certificate's common name into the chunk dest
2658 * Returns
2659 * the len of the extracted common name
2660 * or 0 if no CN found in DN
2661 * or -1 on error case (i.e. no peer certificate)
2662 */
2663int ssl_sock_get_remote_common_name(struct connection *conn, struct chunk *dest)
David Safb76832014-05-08 23:42:08 -04002664{
2665 X509 *crt = NULL;
2666 X509_NAME *name;
David Safb76832014-05-08 23:42:08 -04002667 const char find_cn[] = "CN";
2668 const struct chunk find_cn_chunk = {
2669 .str = (char *)&find_cn,
2670 .len = sizeof(find_cn)-1
2671 };
Emeric Brun0abf8362014-06-24 18:26:41 +02002672 int result = -1;
David Safb76832014-05-08 23:42:08 -04002673
2674 if (!ssl_sock_is_ssl(conn))
Emeric Brun0abf8362014-06-24 18:26:41 +02002675 goto out;
David Safb76832014-05-08 23:42:08 -04002676
2677 /* SSL_get_peer_certificate, it increase X509 * ref count */
2678 crt = SSL_get_peer_certificate(conn->xprt_ctx);
2679 if (!crt)
2680 goto out;
2681
2682 name = X509_get_subject_name(crt);
2683 if (!name)
2684 goto out;
David Safb76832014-05-08 23:42:08 -04002685
Emeric Brun0abf8362014-06-24 18:26:41 +02002686 result = ssl_sock_get_dn_entry(name, &find_cn_chunk, 1, dest);
2687out:
David Safb76832014-05-08 23:42:08 -04002688 if (crt)
2689 X509_free(crt);
2690
2691 return result;
2692}
2693
2694/* returns 1 if client passed a certificate, 0 if not */
2695int ssl_sock_get_cert_used(struct connection *conn)
2696{
2697 if (!ssl_sock_is_ssl(conn))
2698 return 0;
2699
2700 return SSL_SOCK_ST_FL_VERIFY_DONE & conn->xprt_st ? 1 : 0;
2701}
2702
2703/* returns result from SSL verify */
2704unsigned int ssl_sock_get_verify_result(struct connection *conn)
2705{
2706 if (!ssl_sock_is_ssl(conn))
2707 return (unsigned int)X509_V_ERR_APPLICATION_VERIFICATION;
2708
2709 return (unsigned int)SSL_get_verify_result(conn->xprt_ctx);
2710}
2711
Willy Tarreau7875d092012-09-10 08:20:03 +02002712/***** Below are some sample fetching functions for ACL/patterns *****/
2713
Emeric Brune64aef12012-09-21 13:15:06 +02002714/* boolean, returns true if client cert was present */
2715static int
Emeric Brun2525b6b2012-10-18 15:59:43 +02002716smp_fetch_ssl_fc_has_crt(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002717 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brune64aef12012-09-21 13:15:06 +02002718{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002719 struct connection *conn;
2720
2721 if (!l4)
2722 return 0;
2723
2724 conn = objt_conn(l4->si[0].end);
2725 if (!conn || conn->xprt != &ssl_sock)
Emeric Brune64aef12012-09-21 13:15:06 +02002726 return 0;
2727
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002728 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brune64aef12012-09-21 13:15:06 +02002729 smp->flags |= SMP_F_MAY_CHANGE;
2730 return 0;
2731 }
2732
2733 smp->flags = 0;
2734 smp->type = SMP_T_BOOL;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002735 smp->data.uint = SSL_SOCK_ST_FL_VERIFY_DONE & conn->xprt_st ? 1 : 0;
Emeric Brune64aef12012-09-21 13:15:06 +02002736
2737 return 1;
2738}
2739
Emeric Brunba841a12014-04-30 17:05:08 +02002740/* binary, returns serial of certificate in a binary chunk.
2741 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
2742 * should be use.
2743 */
Willy Tarreau8d598402012-10-22 17:58:39 +02002744static int
Emeric Brunba841a12014-04-30 17:05:08 +02002745smp_fetch_ssl_x_serial(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002746 const struct arg *args, struct sample *smp, const char *kw)
Willy Tarreau8d598402012-10-22 17:58:39 +02002747{
Emeric Brunba841a12014-04-30 17:05:08 +02002748 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Willy Tarreau8d598402012-10-22 17:58:39 +02002749 X509 *crt = NULL;
2750 int ret = 0;
2751 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002752 struct connection *conn;
2753
2754 if (!l4)
2755 return 0;
Willy Tarreau8d598402012-10-22 17:58:39 +02002756
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002757 conn = objt_conn(l4->si[0].end);
2758 if (!conn || conn->xprt != &ssl_sock)
Willy Tarreau8d598402012-10-22 17:58:39 +02002759 return 0;
2760
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002761 if (!(conn->flags & CO_FL_CONNECTED)) {
Willy Tarreau8d598402012-10-22 17:58:39 +02002762 smp->flags |= SMP_F_MAY_CHANGE;
2763 return 0;
2764 }
2765
Emeric Brunba841a12014-04-30 17:05:08 +02002766 if (cert_peer)
2767 crt = SSL_get_peer_certificate(conn->xprt_ctx);
2768 else
2769 crt = SSL_get_certificate(conn->xprt_ctx);
2770
Willy Tarreau8d598402012-10-22 17:58:39 +02002771 if (!crt)
2772 goto out;
2773
Willy Tarreau47ca5452012-12-23 20:22:19 +01002774 smp_trash = get_trash_chunk();
Willy Tarreau8d598402012-10-22 17:58:39 +02002775 if (ssl_sock_get_serial(crt, smp_trash) <= 0)
2776 goto out;
2777
2778 smp->data.str = *smp_trash;
2779 smp->type = SMP_T_BIN;
2780 ret = 1;
2781out:
Emeric Brunba841a12014-04-30 17:05:08 +02002782 /* SSL_get_peer_certificate, it increase X509 * ref count */
2783 if (cert_peer && crt)
Willy Tarreau8d598402012-10-22 17:58:39 +02002784 X509_free(crt);
2785 return ret;
2786}
Emeric Brune64aef12012-09-21 13:15:06 +02002787
Emeric Brunba841a12014-04-30 17:05:08 +02002788/* binary, returns the client certificate's SHA-1 fingerprint (SHA-1 hash of DER-encoded certificate) in a binary chunk.
2789 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
2790 * should be use.
2791 */
James Votha051b4a2013-05-14 20:37:59 +02002792static int
Emeric Brunba841a12014-04-30 17:05:08 +02002793smp_fetch_ssl_x_sha1(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002794 const struct arg *args, struct sample *smp, const char *kw)
James Votha051b4a2013-05-14 20:37:59 +02002795{
Emeric Brunba841a12014-04-30 17:05:08 +02002796 int cert_peer = (kw[4] == 'c') ? 1 : 0;
James Votha051b4a2013-05-14 20:37:59 +02002797 X509 *crt = NULL;
2798 const EVP_MD *digest;
2799 int ret = 0;
2800 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002801 struct connection *conn;
James Votha051b4a2013-05-14 20:37:59 +02002802
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002803 if (!l4)
James Votha051b4a2013-05-14 20:37:59 +02002804 return 0;
2805
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002806 conn = objt_conn(l4->si[0].end);
2807 if (!conn || conn->xprt != &ssl_sock)
2808 return 0;
2809
2810 if (!(conn->flags & CO_FL_CONNECTED)) {
James Votha051b4a2013-05-14 20:37:59 +02002811 smp->flags |= SMP_F_MAY_CHANGE;
2812 return 0;
2813 }
2814
Emeric Brunba841a12014-04-30 17:05:08 +02002815 if (cert_peer)
2816 crt = SSL_get_peer_certificate(conn->xprt_ctx);
2817 else
2818 crt = SSL_get_certificate(conn->xprt_ctx);
James Votha051b4a2013-05-14 20:37:59 +02002819 if (!crt)
2820 goto out;
2821
2822 smp_trash = get_trash_chunk();
2823 digest = EVP_sha1();
2824 X509_digest(crt, digest, (unsigned char *)smp_trash->str, (unsigned int *)&smp_trash->len);
2825
2826 smp->data.str = *smp_trash;
2827 smp->type = SMP_T_BIN;
2828 ret = 1;
2829out:
Emeric Brunba841a12014-04-30 17:05:08 +02002830 /* SSL_get_peer_certificate, it increase X509 * ref count */
2831 if (cert_peer && crt)
James Votha051b4a2013-05-14 20:37:59 +02002832 X509_free(crt);
2833 return ret;
2834}
2835
Emeric Brunba841a12014-04-30 17:05:08 +02002836/* string, returns certificate's notafter date in ASN1_UTCTIME format.
2837 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
2838 * should be use.
2839 */
Emeric Brunce5ad802012-10-22 14:11:22 +02002840static int
Emeric Brunba841a12014-04-30 17:05:08 +02002841smp_fetch_ssl_x_notafter(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002842 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brunce5ad802012-10-22 14:11:22 +02002843{
Emeric Brunba841a12014-04-30 17:05:08 +02002844 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brunce5ad802012-10-22 14:11:22 +02002845 X509 *crt = NULL;
2846 int ret = 0;
2847 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002848 struct connection *conn;
Emeric Brunce5ad802012-10-22 14:11:22 +02002849
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002850 if (!l4)
Emeric Brunce5ad802012-10-22 14:11:22 +02002851 return 0;
2852
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002853 conn = objt_conn(l4->si[0].end);
2854 if (!conn || conn->xprt != &ssl_sock)
2855 return 0;
2856
2857 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunce5ad802012-10-22 14:11:22 +02002858 smp->flags |= SMP_F_MAY_CHANGE;
2859 return 0;
2860 }
2861
Emeric Brunba841a12014-04-30 17:05:08 +02002862 if (cert_peer)
2863 crt = SSL_get_peer_certificate(conn->xprt_ctx);
2864 else
2865 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brunce5ad802012-10-22 14:11:22 +02002866 if (!crt)
2867 goto out;
2868
Willy Tarreau47ca5452012-12-23 20:22:19 +01002869 smp_trash = get_trash_chunk();
Emeric Brunce5ad802012-10-22 14:11:22 +02002870 if (ssl_sock_get_time(X509_get_notAfter(crt), smp_trash) <= 0)
2871 goto out;
2872
2873 smp->data.str = *smp_trash;
2874 smp->type = SMP_T_STR;
2875 ret = 1;
2876out:
Emeric Brunba841a12014-04-30 17:05:08 +02002877 /* SSL_get_peer_certificate, it increase X509 * ref count */
2878 if (cert_peer && crt)
Emeric Brunce5ad802012-10-22 14:11:22 +02002879 X509_free(crt);
2880 return ret;
2881}
2882
Emeric Brunba841a12014-04-30 17:05:08 +02002883/* string, returns a string of a formatted full dn \C=..\O=..\OU=.. \CN=.. of certificate's issuer
2884 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
2885 * should be use.
2886 */
Emeric Brun87855892012-10-17 17:39:35 +02002887static int
Emeric Brunba841a12014-04-30 17:05:08 +02002888smp_fetch_ssl_x_i_dn(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002889 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brun87855892012-10-17 17:39:35 +02002890{
Emeric Brunba841a12014-04-30 17:05:08 +02002891 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brun87855892012-10-17 17:39:35 +02002892 X509 *crt = NULL;
2893 X509_NAME *name;
2894 int ret = 0;
2895 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002896 struct connection *conn;
Emeric Brun87855892012-10-17 17:39:35 +02002897
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002898 if (!l4)
Emeric Brun87855892012-10-17 17:39:35 +02002899 return 0;
2900
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002901 conn = objt_conn(l4->si[0].end);
2902 if (!conn || conn->xprt != &ssl_sock)
2903 return 0;
2904
2905 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun87855892012-10-17 17:39:35 +02002906 smp->flags |= SMP_F_MAY_CHANGE;
2907 return 0;
2908 }
2909
Emeric Brunba841a12014-04-30 17:05:08 +02002910 if (cert_peer)
2911 crt = SSL_get_peer_certificate(conn->xprt_ctx);
2912 else
2913 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brun87855892012-10-17 17:39:35 +02002914 if (!crt)
2915 goto out;
2916
2917 name = X509_get_issuer_name(crt);
2918 if (!name)
2919 goto out;
2920
Willy Tarreau47ca5452012-12-23 20:22:19 +01002921 smp_trash = get_trash_chunk();
Emeric Brun87855892012-10-17 17:39:35 +02002922 if (args && args[0].type == ARGT_STR) {
2923 int pos = 1;
2924
2925 if (args[1].type == ARGT_SINT)
2926 pos = args[1].data.sint;
2927 else if (args[1].type == ARGT_UINT)
2928 pos =(int)args[1].data.uint;
2929
2930 if (ssl_sock_get_dn_entry(name, &args[0].data.str, pos, smp_trash) <= 0)
2931 goto out;
2932 }
2933 else if (ssl_sock_get_dn_oneline(name, smp_trash) <= 0)
2934 goto out;
2935
2936 smp->type = SMP_T_STR;
2937 smp->data.str = *smp_trash;
2938 ret = 1;
2939out:
Emeric Brunba841a12014-04-30 17:05:08 +02002940 /* SSL_get_peer_certificate, it increase X509 * ref count */
2941 if (cert_peer && crt)
Emeric Brun87855892012-10-17 17:39:35 +02002942 X509_free(crt);
2943 return ret;
2944}
2945
Emeric Brunba841a12014-04-30 17:05:08 +02002946/* string, returns notbefore date in ASN1_UTCTIME format.
2947 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
2948 * should be use.
2949 */
Emeric Brunce5ad802012-10-22 14:11:22 +02002950static int
Emeric Brunba841a12014-04-30 17:05:08 +02002951smp_fetch_ssl_x_notbefore(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002952 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brunce5ad802012-10-22 14:11:22 +02002953{
Emeric Brunba841a12014-04-30 17:05:08 +02002954 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brunce5ad802012-10-22 14:11:22 +02002955 X509 *crt = NULL;
2956 int ret = 0;
2957 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002958 struct connection *conn;
2959
2960 if (!l4)
2961 return 0;
Emeric Brunce5ad802012-10-22 14:11:22 +02002962
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002963 conn = objt_conn(l4->si[0].end);
2964 if (!conn || conn->xprt != &ssl_sock)
Emeric Brunce5ad802012-10-22 14:11:22 +02002965 return 0;
2966
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002967 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunce5ad802012-10-22 14:11:22 +02002968 smp->flags |= SMP_F_MAY_CHANGE;
2969 return 0;
2970 }
2971
Emeric Brunba841a12014-04-30 17:05:08 +02002972 if (cert_peer)
2973 crt = SSL_get_peer_certificate(conn->xprt_ctx);
2974 else
2975 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brunce5ad802012-10-22 14:11:22 +02002976 if (!crt)
2977 goto out;
2978
Willy Tarreau47ca5452012-12-23 20:22:19 +01002979 smp_trash = get_trash_chunk();
Emeric Brunce5ad802012-10-22 14:11:22 +02002980 if (ssl_sock_get_time(X509_get_notBefore(crt), smp_trash) <= 0)
2981 goto out;
2982
2983 smp->data.str = *smp_trash;
2984 smp->type = SMP_T_STR;
2985 ret = 1;
2986out:
Emeric Brunba841a12014-04-30 17:05:08 +02002987 /* SSL_get_peer_certificate, it increase X509 * ref count */
2988 if (cert_peer && crt)
Emeric Brunce5ad802012-10-22 14:11:22 +02002989 X509_free(crt);
2990 return ret;
2991}
2992
Emeric Brunba841a12014-04-30 17:05:08 +02002993/* string, returns a string of a formatted full dn \C=..\O=..\OU=.. \CN=.. of certificate's subject
2994 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
2995 * should be use.
2996 */
Emeric Brun87855892012-10-17 17:39:35 +02002997static int
Emeric Brunba841a12014-04-30 17:05:08 +02002998smp_fetch_ssl_x_s_dn(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002999 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brun87855892012-10-17 17:39:35 +02003000{
Emeric Brunba841a12014-04-30 17:05:08 +02003001 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brun87855892012-10-17 17:39:35 +02003002 X509 *crt = NULL;
3003 X509_NAME *name;
3004 int ret = 0;
3005 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003006 struct connection *conn;
Emeric Brun87855892012-10-17 17:39:35 +02003007
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003008 if (!l4)
Emeric Brun87855892012-10-17 17:39:35 +02003009 return 0;
3010
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003011 conn = objt_conn(l4->si[0].end);
3012 if (!conn || conn->xprt != &ssl_sock)
3013 return 0;
3014
3015 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun87855892012-10-17 17:39:35 +02003016 smp->flags |= SMP_F_MAY_CHANGE;
3017 return 0;
3018 }
3019
Emeric Brunba841a12014-04-30 17:05:08 +02003020 if (cert_peer)
3021 crt = SSL_get_peer_certificate(conn->xprt_ctx);
3022 else
3023 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brun87855892012-10-17 17:39:35 +02003024 if (!crt)
3025 goto out;
3026
3027 name = X509_get_subject_name(crt);
3028 if (!name)
3029 goto out;
3030
Willy Tarreau47ca5452012-12-23 20:22:19 +01003031 smp_trash = get_trash_chunk();
Emeric Brun87855892012-10-17 17:39:35 +02003032 if (args && args[0].type == ARGT_STR) {
3033 int pos = 1;
3034
3035 if (args[1].type == ARGT_SINT)
3036 pos = args[1].data.sint;
3037 else if (args[1].type == ARGT_UINT)
3038 pos =(int)args[1].data.uint;
3039
3040 if (ssl_sock_get_dn_entry(name, &args[0].data.str, pos, smp_trash) <= 0)
3041 goto out;
3042 }
3043 else if (ssl_sock_get_dn_oneline(name, smp_trash) <= 0)
3044 goto out;
3045
3046 smp->type = SMP_T_STR;
3047 smp->data.str = *smp_trash;
3048 ret = 1;
3049out:
Emeric Brunba841a12014-04-30 17:05:08 +02003050 /* SSL_get_peer_certificate, it increase X509 * ref count */
3051 if (cert_peer && crt)
Emeric Brun87855892012-10-17 17:39:35 +02003052 X509_free(crt);
3053 return ret;
3054}
Emeric Brun9143d372012-12-20 15:44:16 +01003055
3056/* integer, returns true if current session use a client certificate */
3057static int
3058smp_fetch_ssl_c_used(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003059 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brun9143d372012-12-20 15:44:16 +01003060{
3061 X509 *crt;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003062 struct connection *conn;
Emeric Brun9143d372012-12-20 15:44:16 +01003063
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003064 if (!l4)
Emeric Brun9143d372012-12-20 15:44:16 +01003065 return 0;
3066
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003067 conn = objt_conn(l4->si[0].end);
3068 if (!conn || conn->xprt != &ssl_sock)
3069 return 0;
3070
3071 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun9143d372012-12-20 15:44:16 +01003072 smp->flags |= SMP_F_MAY_CHANGE;
3073 return 0;
3074 }
3075
3076 /* SSL_get_peer_certificate returns a ptr on allocated X509 struct */
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003077 crt = SSL_get_peer_certificate(conn->xprt_ctx);
Emeric Brun9143d372012-12-20 15:44:16 +01003078 if (crt) {
3079 X509_free(crt);
3080 }
3081
3082 smp->type = SMP_T_BOOL;
3083 smp->data.uint = (crt != NULL);
3084 return 1;
3085}
3086
Emeric Brunba841a12014-04-30 17:05:08 +02003087/* integer, returns the certificate version
3088 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
3089 * should be use.
3090 */
Emeric Bruna7359fd2012-10-17 15:03:11 +02003091static int
Emeric Brunba841a12014-04-30 17:05:08 +02003092smp_fetch_ssl_x_version(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003093 const struct arg *args, struct sample *smp, const char *kw)
Emeric Bruna7359fd2012-10-17 15:03:11 +02003094{
Emeric Brunba841a12014-04-30 17:05:08 +02003095 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Bruna7359fd2012-10-17 15:03:11 +02003096 X509 *crt;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003097 struct connection *conn;
3098
3099 if (!l4)
3100 return 0;
Emeric Bruna7359fd2012-10-17 15:03:11 +02003101
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003102 conn = objt_conn(l4->si[0].end);
3103 if (!conn || conn->xprt != &ssl_sock)
Emeric Bruna7359fd2012-10-17 15:03:11 +02003104 return 0;
3105
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003106 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Bruna7359fd2012-10-17 15:03:11 +02003107 smp->flags |= SMP_F_MAY_CHANGE;
3108 return 0;
3109 }
3110
Emeric Brunba841a12014-04-30 17:05:08 +02003111 if (cert_peer)
3112 crt = SSL_get_peer_certificate(conn->xprt_ctx);
3113 else
3114 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Bruna7359fd2012-10-17 15:03:11 +02003115 if (!crt)
3116 return 0;
3117
3118 smp->data.uint = (unsigned int)(1 + X509_get_version(crt));
Emeric Brunba841a12014-04-30 17:05:08 +02003119 /* SSL_get_peer_certificate increase X509 * ref count */
3120 if (cert_peer)
3121 X509_free(crt);
Emeric Bruna7359fd2012-10-17 15:03:11 +02003122 smp->type = SMP_T_UINT;
3123
3124 return 1;
3125}
3126
Emeric Brunba841a12014-04-30 17:05:08 +02003127/* string, returns the certificate's signature algorithm.
3128 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
3129 * should be use.
3130 */
Emeric Brun7f56e742012-10-19 18:15:40 +02003131static int
Emeric Brunba841a12014-04-30 17:05:08 +02003132smp_fetch_ssl_x_sig_alg(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003133 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brun7f56e742012-10-19 18:15:40 +02003134{
Emeric Brunba841a12014-04-30 17:05:08 +02003135 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brun7f56e742012-10-19 18:15:40 +02003136 X509 *crt;
3137 int nid;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003138 struct connection *conn;
Emeric Brun7f56e742012-10-19 18:15:40 +02003139
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003140 if (!l4)
Emeric Brun7f56e742012-10-19 18:15:40 +02003141 return 0;
3142
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003143 conn = objt_conn(l4->si[0].end);
3144 if (!conn || conn->xprt != &ssl_sock)
3145 return 0;
3146
3147 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun7f56e742012-10-19 18:15:40 +02003148 smp->flags |= SMP_F_MAY_CHANGE;
3149 return 0;
3150 }
3151
Emeric Brunba841a12014-04-30 17:05:08 +02003152 if (cert_peer)
3153 crt = SSL_get_peer_certificate(conn->xprt_ctx);
3154 else
3155 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brun7f56e742012-10-19 18:15:40 +02003156 if (!crt)
3157 return 0;
3158
3159 nid = OBJ_obj2nid((ASN1_OBJECT *)(crt->cert_info->signature->algorithm));
3160
3161 smp->data.str.str = (char *)OBJ_nid2sn(nid);
Emeric Brun9bf3ba22013-10-07 14:31:44 +02003162 if (!smp->data.str.str) {
Emeric Brunba841a12014-04-30 17:05:08 +02003163 /* SSL_get_peer_certificate increase X509 * ref count */
3164 if (cert_peer)
3165 X509_free(crt);
Emeric Brun7f56e742012-10-19 18:15:40 +02003166 return 0;
Emeric Brun9bf3ba22013-10-07 14:31:44 +02003167 }
Emeric Brun7f56e742012-10-19 18:15:40 +02003168
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01003169 smp->type = SMP_T_STR;
3170 smp->flags |= SMP_F_CONST;
Emeric Brun7f56e742012-10-19 18:15:40 +02003171 smp->data.str.len = strlen(smp->data.str.str);
Emeric Brunba841a12014-04-30 17:05:08 +02003172 /* SSL_get_peer_certificate increase X509 * ref count */
3173 if (cert_peer)
3174 X509_free(crt);
Emeric Brun7f56e742012-10-19 18:15:40 +02003175
3176 return 1;
3177}
3178
Emeric Brunba841a12014-04-30 17:05:08 +02003179/* string, returns the certificate's key algorithm.
3180 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
3181 * should be use.
3182 */
Emeric Brun521a0112012-10-22 12:22:55 +02003183static int
Emeric Brunba841a12014-04-30 17:05:08 +02003184smp_fetch_ssl_x_key_alg(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003185 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brun521a0112012-10-22 12:22:55 +02003186{
Emeric Brunba841a12014-04-30 17:05:08 +02003187 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brun521a0112012-10-22 12:22:55 +02003188 X509 *crt;
3189 int nid;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003190 struct connection *conn;
Emeric Brun521a0112012-10-22 12:22:55 +02003191
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003192 if (!l4)
Emeric Brun521a0112012-10-22 12:22:55 +02003193 return 0;
3194
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003195 conn = objt_conn(l4->si[0].end);
3196 if (!conn || conn->xprt != &ssl_sock)
3197 return 0;
3198
3199 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun521a0112012-10-22 12:22:55 +02003200 smp->flags |= SMP_F_MAY_CHANGE;
3201 return 0;
3202 }
3203
Emeric Brunba841a12014-04-30 17:05:08 +02003204 if (cert_peer)
3205 crt = SSL_get_peer_certificate(conn->xprt_ctx);
3206 else
3207 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brun521a0112012-10-22 12:22:55 +02003208 if (!crt)
3209 return 0;
3210
3211 nid = OBJ_obj2nid((ASN1_OBJECT *)(crt->cert_info->key->algor->algorithm));
3212
3213 smp->data.str.str = (char *)OBJ_nid2sn(nid);
Emeric Brun9bf3ba22013-10-07 14:31:44 +02003214 if (!smp->data.str.str) {
Emeric Brunba841a12014-04-30 17:05:08 +02003215 /* SSL_get_peer_certificate increase X509 * ref count */
3216 if (cert_peer)
3217 X509_free(crt);
Emeric Brun521a0112012-10-22 12:22:55 +02003218 return 0;
Emeric Brun9bf3ba22013-10-07 14:31:44 +02003219 }
Emeric Brun521a0112012-10-22 12:22:55 +02003220
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01003221 smp->type = SMP_T_STR;
3222 smp->flags |= SMP_F_CONST;
Emeric Brun521a0112012-10-22 12:22:55 +02003223 smp->data.str.len = strlen(smp->data.str.str);
Emeric Brunba841a12014-04-30 17:05:08 +02003224 if (cert_peer)
3225 X509_free(crt);
Emeric Brun521a0112012-10-22 12:22:55 +02003226
3227 return 1;
3228}
3229
Emeric Brun645ae792014-04-30 14:21:06 +02003230/* boolean, returns true if front conn. transport layer is SSL.
3231 * This function is also usable on backend conn if the fetch keyword 5th
3232 * char is 'b'.
3233 */
Willy Tarreau7875d092012-09-10 08:20:03 +02003234static int
Emeric Brun2525b6b2012-10-18 15:59:43 +02003235smp_fetch_ssl_fc(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003236 const struct arg *args, struct sample *smp, const char *kw)
Willy Tarreau7875d092012-09-10 08:20:03 +02003237{
Emeric Brun645ae792014-04-30 14:21:06 +02003238 int back_conn = (kw[4] == 'b') ? 1 : 0;
3239 struct connection *conn = objt_conn(l4->si[back_conn].end);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003240
Willy Tarreau7875d092012-09-10 08:20:03 +02003241 smp->type = SMP_T_BOOL;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003242 smp->data.uint = (conn && conn->xprt == &ssl_sock);
Willy Tarreau7875d092012-09-10 08:20:03 +02003243 return 1;
3244}
3245
Emeric Brun2525b6b2012-10-18 15:59:43 +02003246/* boolean, returns true if client present a SNI */
Willy Tarreau7875d092012-09-10 08:20:03 +02003247static int
Emeric Brun2525b6b2012-10-18 15:59:43 +02003248smp_fetch_ssl_fc_has_sni(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003249 const struct arg *args, struct sample *smp, const char *kw)
Willy Tarreau7875d092012-09-10 08:20:03 +02003250{
3251#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003252 struct connection *conn = objt_conn(l4->si[0].end);
3253
Willy Tarreau7875d092012-09-10 08:20:03 +02003254 smp->type = SMP_T_BOOL;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003255 smp->data.uint = (conn && conn->xprt == &ssl_sock) &&
3256 conn->xprt_ctx &&
3257 SSL_get_servername(conn->xprt_ctx, TLSEXT_NAMETYPE_host_name) != NULL;
Willy Tarreau7875d092012-09-10 08:20:03 +02003258 return 1;
3259#else
3260 return 0;
3261#endif
3262}
3263
Emeric Brun645ae792014-04-30 14:21:06 +02003264/* string, returns the used cipher if front conn. transport layer is SSL.
3265 * This function is also usable on backend conn if the fetch keyword 5th
3266 * char is 'b'.
3267 */
Emeric Brun589fcad2012-10-16 14:13:26 +02003268static int
3269smp_fetch_ssl_fc_cipher(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003270 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brun589fcad2012-10-16 14:13:26 +02003271{
Emeric Brun645ae792014-04-30 14:21:06 +02003272 int back_conn = (kw[4] == 'b') ? 1 : 0;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003273 struct connection *conn;
3274
Emeric Brun589fcad2012-10-16 14:13:26 +02003275 smp->flags = 0;
3276
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003277 if (!l4)
3278 return 0;
3279
Emeric Brun645ae792014-04-30 14:21:06 +02003280 conn = objt_conn(l4->si[back_conn].end);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003281 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
Emeric Brun589fcad2012-10-16 14:13:26 +02003282 return 0;
3283
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003284 smp->data.str.str = (char *)SSL_get_cipher_name(conn->xprt_ctx);
Emeric Brun589fcad2012-10-16 14:13:26 +02003285 if (!smp->data.str.str)
3286 return 0;
3287
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01003288 smp->type = SMP_T_STR;
3289 smp->flags |= SMP_F_CONST;
Emeric Brun589fcad2012-10-16 14:13:26 +02003290 smp->data.str.len = strlen(smp->data.str.str);
3291
3292 return 1;
3293}
3294
Emeric Brun645ae792014-04-30 14:21:06 +02003295/* integer, returns the algoritm's keysize if front conn. transport layer
3296 * is SSL.
3297 * This function is also usable on backend conn if the fetch keyword 5th
3298 * char is 'b'.
3299 */
Emeric Brun589fcad2012-10-16 14:13:26 +02003300static int
3301smp_fetch_ssl_fc_alg_keysize(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003302 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brun589fcad2012-10-16 14:13:26 +02003303{
Emeric Brun645ae792014-04-30 14:21:06 +02003304 int back_conn = (kw[4] == 'b') ? 1 : 0;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003305 struct connection *conn;
3306
Emeric Brun589fcad2012-10-16 14:13:26 +02003307 smp->flags = 0;
3308
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003309 if (!l4)
Emeric Brun589fcad2012-10-16 14:13:26 +02003310 return 0;
3311
Emeric Brun645ae792014-04-30 14:21:06 +02003312 conn = objt_conn(l4->si[back_conn].end);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003313 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
Emeric Brun589fcad2012-10-16 14:13:26 +02003314 return 0;
3315
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003316 if (!SSL_get_cipher_bits(conn->xprt_ctx, (int *)&smp->data.uint))
3317 return 0;
3318
Emeric Brun589fcad2012-10-16 14:13:26 +02003319 smp->type = SMP_T_UINT;
3320
3321 return 1;
3322}
3323
Emeric Brun645ae792014-04-30 14:21:06 +02003324/* integer, returns the used keysize if front conn. transport layer is SSL.
3325 * This function is also usable on backend conn if the fetch keyword 5th
3326 * char is 'b'.
3327 */
Emeric Brun589fcad2012-10-16 14:13:26 +02003328static int
3329smp_fetch_ssl_fc_use_keysize(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003330 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brun589fcad2012-10-16 14:13:26 +02003331{
Emeric Brun645ae792014-04-30 14:21:06 +02003332 int back_conn = (kw[4] == 'b') ? 1 : 0;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003333 struct connection *conn;
3334
Emeric Brun589fcad2012-10-16 14:13:26 +02003335 smp->flags = 0;
3336
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003337 if (!l4)
Emeric Brun589fcad2012-10-16 14:13:26 +02003338 return 0;
3339
Emeric Brun645ae792014-04-30 14:21:06 +02003340 conn = objt_conn(l4->si[back_conn].end);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003341 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
3342 return 0;
3343
3344 smp->data.uint = (unsigned int)SSL_get_cipher_bits(conn->xprt_ctx, NULL);
Emeric Brun589fcad2012-10-16 14:13:26 +02003345 if (!smp->data.uint)
3346 return 0;
3347
3348 smp->type = SMP_T_UINT;
3349
3350 return 1;
3351}
3352
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02003353#ifdef OPENSSL_NPN_NEGOTIATED
Willy Tarreau7875d092012-09-10 08:20:03 +02003354static int
Emeric Brun2525b6b2012-10-18 15:59:43 +02003355smp_fetch_ssl_fc_npn(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003356 const struct arg *args, struct sample *smp, const char *kw)
Willy Tarreaua33c6542012-10-15 13:19:06 +02003357{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003358 struct connection *conn;
3359
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01003360 smp->flags = SMP_F_CONST;
3361 smp->type = SMP_T_STR;
Willy Tarreaua33c6542012-10-15 13:19:06 +02003362
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003363 if (!l4)
Willy Tarreaua33c6542012-10-15 13:19:06 +02003364 return 0;
3365
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003366 conn = objt_conn(l4->si[0].end);
3367 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
3368 return 0;
3369
Willy Tarreaua33c6542012-10-15 13:19:06 +02003370 smp->data.str.str = NULL;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003371 SSL_get0_next_proto_negotiated(conn->xprt_ctx,
Willy Tarreaua33c6542012-10-15 13:19:06 +02003372 (const unsigned char **)&smp->data.str.str, (unsigned *)&smp->data.str.len);
3373
3374 if (!smp->data.str.str)
3375 return 0;
3376
3377 return 1;
Willy Tarreaua33c6542012-10-15 13:19:06 +02003378}
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02003379#endif
Willy Tarreaua33c6542012-10-15 13:19:06 +02003380
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01003381#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Willy Tarreauab861d32013-04-02 02:30:41 +02003382static int
3383smp_fetch_ssl_fc_alpn(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003384 const struct arg *args, struct sample *smp, const char *kw)
Willy Tarreauab861d32013-04-02 02:30:41 +02003385{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003386 struct connection *conn;
3387
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01003388 smp->flags = SMP_F_CONST;
3389 smp->type = SMP_T_STR;
Willy Tarreauab861d32013-04-02 02:30:41 +02003390
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003391 if (!l4)
3392 return 0;
3393
3394 conn = objt_conn(l4->si[0].end);
3395 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
Willy Tarreauab861d32013-04-02 02:30:41 +02003396 return 0;
3397
3398 smp->data.str.str = NULL;
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01003399 SSL_get0_alpn_selected(conn->xprt_ctx,
Willy Tarreauab861d32013-04-02 02:30:41 +02003400 (const unsigned char **)&smp->data.str.str, (unsigned *)&smp->data.str.len);
3401
3402 if (!smp->data.str.str)
3403 return 0;
3404
3405 return 1;
3406}
3407#endif
3408
Emeric Brun645ae792014-04-30 14:21:06 +02003409/* string, returns the used protocol if front conn. transport layer is SSL.
3410 * This function is also usable on backend conn if the fetch keyword 5th
3411 * char is 'b'.
3412 */
Willy Tarreaua33c6542012-10-15 13:19:06 +02003413static int
Emeric Brun589fcad2012-10-16 14:13:26 +02003414smp_fetch_ssl_fc_protocol(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003415 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brun589fcad2012-10-16 14:13:26 +02003416{
Emeric Brun645ae792014-04-30 14:21:06 +02003417 int back_conn = (kw[4] == 'b') ? 1 : 0;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003418 struct connection *conn;
3419
Emeric Brun589fcad2012-10-16 14:13:26 +02003420 smp->flags = 0;
3421
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003422 if (!l4)
Emeric Brun589fcad2012-10-16 14:13:26 +02003423 return 0;
3424
Emeric Brun645ae792014-04-30 14:21:06 +02003425 conn = objt_conn(l4->si[back_conn].end);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003426 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
3427 return 0;
3428
3429 smp->data.str.str = (char *)SSL_get_version(conn->xprt_ctx);
Emeric Brun589fcad2012-10-16 14:13:26 +02003430 if (!smp->data.str.str)
3431 return 0;
3432
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01003433 smp->type = SMP_T_STR;
3434 smp->flags = SMP_F_CONST;
Emeric Brun589fcad2012-10-16 14:13:26 +02003435 smp->data.str.len = strlen(smp->data.str.str);
3436
3437 return 1;
3438}
3439
Emeric Brun645ae792014-04-30 14:21:06 +02003440/* binary, returns the SSL session id if front conn. transport layer is SSL.
3441 * This function is also usable on backend conn if the fetch keyword 5th
3442 * char is 'b'.
3443 */
Emeric Brun589fcad2012-10-16 14:13:26 +02003444static int
Emeric Brunfe68f682012-10-16 14:59:28 +02003445smp_fetch_ssl_fc_session_id(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003446 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brunfe68f682012-10-16 14:59:28 +02003447{
3448#if OPENSSL_VERSION_NUMBER > 0x0090800fL
Emeric Brun645ae792014-04-30 14:21:06 +02003449 int back_conn = (kw[4] == 'b') ? 1 : 0;
Emeric Brunfe68f682012-10-16 14:59:28 +02003450 SSL_SESSION *sess;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003451 struct connection *conn;
Emeric Brunfe68f682012-10-16 14:59:28 +02003452
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01003453 smp->flags = SMP_F_CONST;
3454 smp->type = SMP_T_BIN;
Emeric Brunfe68f682012-10-16 14:59:28 +02003455
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003456 if (!l4)
Emeric Brunfe68f682012-10-16 14:59:28 +02003457 return 0;
3458
Emeric Brun645ae792014-04-30 14:21:06 +02003459 conn = objt_conn(l4->si[back_conn].end);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003460 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
3461 return 0;
3462
3463 sess = SSL_get_session(conn->xprt_ctx);
Emeric Brunfe68f682012-10-16 14:59:28 +02003464 if (!sess)
3465 return 0;
3466
3467 smp->data.str.str = (char *)SSL_SESSION_get_id(sess, (unsigned int *)&smp->data.str.len);
3468 if (!smp->data.str.str || !&smp->data.str.len)
3469 return 0;
3470
3471 return 1;
3472#else
3473 return 0;
3474#endif
3475}
3476
3477static int
Emeric Brun2525b6b2012-10-18 15:59:43 +02003478smp_fetch_ssl_fc_sni(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003479 const struct arg *args, struct sample *smp, const char *kw)
Willy Tarreau7875d092012-09-10 08:20:03 +02003480{
3481#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
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 Tarreau7875d092012-09-10 08:20:03 +02003486
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003487 if (!l4)
Willy Tarreau7875d092012-09-10 08:20:03 +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
3494 smp->data.str.str = (char *)SSL_get_servername(conn->xprt_ctx, TLSEXT_NAMETYPE_host_name);
Willy Tarreau3e394c92012-09-14 23:56:58 +02003495 if (!smp->data.str.str)
3496 return 0;
3497
Willy Tarreau7875d092012-09-10 08:20:03 +02003498 smp->data.str.len = strlen(smp->data.str.str);
3499 return 1;
3500#else
3501 return 0;
3502#endif
3503}
3504
David Sc1ad52e2014-04-08 18:48:47 -04003505static int
3506smp_fetch_ssl_fc_unique_id(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
3507 const struct arg *args, struct sample *smp, const char *kw)
3508{
3509#if OPENSSL_VERSION_NUMBER > 0x0090800fL
Emeric Brun645ae792014-04-30 14:21:06 +02003510 int back_conn = (kw[4] == 'b') ? 1 : 0;
David Sc1ad52e2014-04-08 18:48:47 -04003511 struct connection *conn;
3512 int finished_len;
David Sc1ad52e2014-04-08 18:48:47 -04003513 struct chunk *finished_trash;
David Sc1ad52e2014-04-08 18:48:47 -04003514
3515 smp->flags = 0;
3516
3517 if (!l4)
3518 return 0;
3519
Emeric Brun645ae792014-04-30 14:21:06 +02003520 conn = objt_conn(l4->si[back_conn].end);
David Sc1ad52e2014-04-08 18:48:47 -04003521 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
3522 return 0;
3523
3524 if (!(conn->flags & CO_FL_CONNECTED)) {
3525 smp->flags |= SMP_F_MAY_CHANGE;
3526 return 0;
3527 }
3528
3529 finished_trash = get_trash_chunk();
3530 if (!SSL_session_reused(conn->xprt_ctx))
3531 finished_len = SSL_get_peer_finished(conn->xprt_ctx, finished_trash->str, finished_trash->size);
3532 else
3533 finished_len = SSL_get_finished(conn->xprt_ctx, finished_trash->str, finished_trash->size);
3534
3535 if (!finished_len)
3536 return 0;
3537
Emeric Brunb73a9b02014-04-30 18:49:19 +02003538 finished_trash->len = finished_len;
3539 smp->data.str = *finished_trash;
3540 smp->type = SMP_T_BIN;
David Sc1ad52e2014-04-08 18:48:47 -04003541
3542 return 1;
3543#else
3544 return 0;
3545#endif
3546}
3547
Emeric Brun2525b6b2012-10-18 15:59:43 +02003548/* integer, returns the first verify error in CA chain of client certificate chain. */
Emeric Brunf282a812012-09-21 15:27:54 +02003549static int
Emeric Brun2525b6b2012-10-18 15:59:43 +02003550smp_fetch_ssl_c_ca_err(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003551 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brunf282a812012-09-21 15:27:54 +02003552{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003553 struct connection *conn;
3554
3555 if (!l4)
Emeric Brunf282a812012-09-21 15:27:54 +02003556 return 0;
3557
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003558 conn = objt_conn(l4->si[0].end);
3559 if (!conn || conn->xprt != &ssl_sock)
3560 return 0;
3561
3562 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunf282a812012-09-21 15:27:54 +02003563 smp->flags = SMP_F_MAY_CHANGE;
3564 return 0;
3565 }
3566
3567 smp->type = SMP_T_UINT;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003568 smp->data.uint = (unsigned int)SSL_SOCK_ST_TO_CA_ERROR(conn->xprt_st);
Emeric Brunf282a812012-09-21 15:27:54 +02003569 smp->flags = 0;
3570
3571 return 1;
3572}
3573
Emeric Brun2525b6b2012-10-18 15:59:43 +02003574/* integer, returns the depth of the first verify error in CA chain of client certificate chain. */
Emeric Brunf282a812012-09-21 15:27:54 +02003575static int
Emeric Brun2525b6b2012-10-18 15:59:43 +02003576smp_fetch_ssl_c_ca_err_depth(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003577 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brunf282a812012-09-21 15:27:54 +02003578{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003579 struct connection *conn;
3580
3581 if (!l4)
3582 return 0;
3583
3584 conn = objt_conn(l4->si[0].end);
3585 if (!conn || conn->xprt != &ssl_sock)
Emeric Brunf282a812012-09-21 15:27:54 +02003586 return 0;
3587
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003588 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunf282a812012-09-21 15:27:54 +02003589 smp->flags = SMP_F_MAY_CHANGE;
3590 return 0;
3591 }
3592
3593 smp->type = SMP_T_UINT;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003594 smp->data.uint = (unsigned int)SSL_SOCK_ST_TO_CAEDEPTH(conn->xprt_st);
Emeric Brunf282a812012-09-21 15:27:54 +02003595 smp->flags = 0;
3596
3597 return 1;
3598}
3599
Emeric Brun2525b6b2012-10-18 15:59:43 +02003600/* integer, returns the first verify error on client certificate */
Emeric Brunf282a812012-09-21 15:27:54 +02003601static int
Emeric Brun2525b6b2012-10-18 15:59:43 +02003602smp_fetch_ssl_c_err(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)
Emeric Brunf282a812012-09-21 15:27:54 +02003604{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003605 struct connection *conn;
3606
3607 if (!l4)
Emeric Brunf282a812012-09-21 15:27:54 +02003608 return 0;
3609
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003610 conn = objt_conn(l4->si[0].end);
3611 if (!conn || conn->xprt != &ssl_sock)
3612 return 0;
3613
3614 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunf282a812012-09-21 15:27:54 +02003615 smp->flags = SMP_F_MAY_CHANGE;
3616 return 0;
3617 }
3618
3619 smp->type = SMP_T_UINT;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003620 smp->data.uint = (unsigned int)SSL_SOCK_ST_TO_CRTERROR(conn->xprt_st);
Emeric Brunf282a812012-09-21 15:27:54 +02003621 smp->flags = 0;
3622
3623 return 1;
3624}
3625
Emeric Brun2525b6b2012-10-18 15:59:43 +02003626/* integer, returns the verify result on client cert */
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02003627static int
Emeric Brun2525b6b2012-10-18 15:59:43 +02003628smp_fetch_ssl_c_verify(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003629 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02003630{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003631 struct connection *conn;
3632
3633 if (!l4)
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02003634 return 0;
3635
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003636 conn = objt_conn(l4->si[0].end);
3637 if (!conn || conn->xprt != &ssl_sock)
3638 return 0;
3639
3640 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02003641 smp->flags = SMP_F_MAY_CHANGE;
3642 return 0;
3643 }
3644
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003645 if (!conn->xprt_ctx)
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02003646 return 0;
3647
3648 smp->type = SMP_T_UINT;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003649 smp->data.uint = (unsigned int)SSL_get_verify_result(conn->xprt_ctx);
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02003650 smp->flags = 0;
3651
3652 return 1;
3653}
3654
Emeric Brunfb510ea2012-10-05 12:00:26 +02003655/* parse the "ca-file" bind keyword */
3656static 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 +02003657{
3658 if (!*args[cur_arg + 1]) {
3659 if (err)
3660 memprintf(err, "'%s' : missing CAfile path", args[cur_arg]);
3661 return ERR_ALERT | ERR_FATAL;
3662 }
3663
Emeric Brunef42d922012-10-11 16:11:36 +02003664 if ((*args[cur_arg + 1] != '/') && global.ca_base)
3665 memprintf(&conf->ca_file, "%s/%s", global.ca_base, args[cur_arg + 1]);
3666 else
3667 memprintf(&conf->ca_file, "%s", args[cur_arg + 1]);
Emeric Brunc8e8d122012-10-02 18:42:10 +02003668
Emeric Brund94b3fe2012-09-20 18:23:56 +02003669 return 0;
3670}
3671
Willy Tarreau79eeafa2012-09-14 07:53:05 +02003672/* parse the "ciphers" bind keyword */
Willy Tarreau4348fad2012-09-20 16:48:07 +02003673static 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 +02003674{
3675 if (!*args[cur_arg + 1]) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02003676 memprintf(err, "'%s' : missing cipher suite", args[cur_arg]);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02003677 return ERR_ALERT | ERR_FATAL;
3678 }
3679
Emeric Brun76d88952012-10-05 15:47:31 +02003680 free(conf->ciphers);
Willy Tarreau4348fad2012-09-20 16:48:07 +02003681 conf->ciphers = strdup(args[cur_arg + 1]);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02003682 return 0;
3683}
3684
3685/* parse the "crt" bind keyword */
Willy Tarreau4348fad2012-09-20 16:48:07 +02003686static 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 +02003687{
Willy Tarreau38011032013-08-13 16:59:39 +02003688 char path[MAXPATHLEN];
Willy Tarreaub75d6922014-04-14 18:05:41 +02003689
Willy Tarreau79eeafa2012-09-14 07:53:05 +02003690 if (!*args[cur_arg + 1]) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02003691 memprintf(err, "'%s' : missing certificate location", args[cur_arg]);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02003692 return ERR_ALERT | ERR_FATAL;
3693 }
3694
Emeric Brunc8e8d122012-10-02 18:42:10 +02003695 if ((*args[cur_arg + 1] != '/' ) && global.crt_base) {
Willy Tarreau38011032013-08-13 16:59:39 +02003696 if ((strlen(global.crt_base) + 1 + strlen(args[cur_arg + 1]) + 1) > MAXPATHLEN) {
Emeric Brunc8e8d122012-10-02 18:42:10 +02003697 memprintf(err, "'%s' : path too long", args[cur_arg]);
3698 return ERR_ALERT | ERR_FATAL;
3699 }
Willy Tarreaub75d6922014-04-14 18:05:41 +02003700 snprintf(path, sizeof(path), "%s/%s", global.crt_base, args[cur_arg + 1]);
Emeric Brunc8e8d122012-10-02 18:42:10 +02003701 if (ssl_sock_load_cert(path, conf, px, err) > 0)
3702 return ERR_ALERT | ERR_FATAL;
3703
3704 return 0;
3705 }
3706
Willy Tarreau4348fad2012-09-20 16:48:07 +02003707 if (ssl_sock_load_cert(args[cur_arg + 1], conf, px, err) > 0)
Willy Tarreau79eeafa2012-09-14 07:53:05 +02003708 return ERR_ALERT | ERR_FATAL;
Emeric Brund94b3fe2012-09-20 18:23:56 +02003709
3710 return 0;
3711}
3712
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01003713/* parse the "crt-list" bind keyword */
3714static int bind_parse_crt_list(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
3715{
3716 if (!*args[cur_arg + 1]) {
3717 memprintf(err, "'%s' : missing certificate location", args[cur_arg]);
3718 return ERR_ALERT | ERR_FATAL;
3719 }
3720
Willy Tarreauad1731d2013-04-02 17:35:58 +02003721 if (ssl_sock_load_cert_list_file(args[cur_arg + 1], conf, px, err) > 0) {
3722 memprintf(err, "'%s' : %s", args[cur_arg], *err);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01003723 return ERR_ALERT | ERR_FATAL;
Willy Tarreauad1731d2013-04-02 17:35:58 +02003724 }
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01003725
3726 return 0;
3727}
3728
Emeric Brunfb510ea2012-10-05 12:00:26 +02003729/* parse the "crl-file" bind keyword */
3730static 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 +02003731{
Emeric Brun051cdab2012-10-02 19:25:50 +02003732#ifndef X509_V_FLAG_CRL_CHECK
3733 if (err)
3734 memprintf(err, "'%s' : library does not support CRL verify", args[cur_arg]);
3735 return ERR_ALERT | ERR_FATAL;
3736#else
Emeric Brund94b3fe2012-09-20 18:23:56 +02003737 if (!*args[cur_arg + 1]) {
3738 if (err)
3739 memprintf(err, "'%s' : missing CRLfile path", args[cur_arg]);
3740 return ERR_ALERT | ERR_FATAL;
3741 }
Emeric Brun2b58d042012-09-20 17:10:03 +02003742
Emeric Brunef42d922012-10-11 16:11:36 +02003743 if ((*args[cur_arg + 1] != '/') && global.ca_base)
3744 memprintf(&conf->crl_file, "%s/%s", global.ca_base, args[cur_arg + 1]);
3745 else
3746 memprintf(&conf->crl_file, "%s", args[cur_arg + 1]);
Emeric Brunc8e8d122012-10-02 18:42:10 +02003747
Emeric Brun2b58d042012-09-20 17:10:03 +02003748 return 0;
Emeric Brun051cdab2012-10-02 19:25:50 +02003749#endif
Emeric Brun2b58d042012-09-20 17:10:03 +02003750}
3751
3752/* parse the "ecdhe" bind keyword keywords */
3753static int bind_parse_ecdhe(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
3754{
3755#if OPENSSL_VERSION_NUMBER < 0x0090800fL
3756 if (err)
3757 memprintf(err, "'%s' : library does not support elliptic curve Diffie-Hellman (too old)", args[cur_arg]);
3758 return ERR_ALERT | ERR_FATAL;
3759#elif defined(OPENSSL_NO_ECDH)
3760 if (err)
3761 memprintf(err, "'%s' : library does not support elliptic curve Diffie-Hellman (disabled via OPENSSL_NO_ECDH)", args[cur_arg]);
3762 return ERR_ALERT | ERR_FATAL;
3763#else
3764 if (!*args[cur_arg + 1]) {
3765 if (err)
3766 memprintf(err, "'%s' : missing named curve", args[cur_arg]);
3767 return ERR_ALERT | ERR_FATAL;
3768 }
3769
3770 conf->ecdhe = strdup(args[cur_arg + 1]);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02003771
3772 return 0;
Emeric Brun2b58d042012-09-20 17:10:03 +02003773#endif
Willy Tarreau79eeafa2012-09-14 07:53:05 +02003774}
3775
Emeric Brun81c00f02012-09-21 14:31:21 +02003776/* parse the "crt_ignerr" and "ca_ignerr" bind keywords */
3777static int bind_parse_ignore_err(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
3778{
3779 int code;
3780 char *p = args[cur_arg + 1];
3781 unsigned long long *ignerr = &conf->crt_ignerr;
3782
3783 if (!*p) {
3784 if (err)
3785 memprintf(err, "'%s' : missing error IDs list", args[cur_arg]);
3786 return ERR_ALERT | ERR_FATAL;
3787 }
3788
3789 if (strcmp(args[cur_arg], "ca-ignore-err") == 0)
3790 ignerr = &conf->ca_ignerr;
3791
3792 if (strcmp(p, "all") == 0) {
3793 *ignerr = ~0ULL;
3794 return 0;
3795 }
3796
3797 while (p) {
3798 code = atoi(p);
3799 if ((code <= 0) || (code > 63)) {
3800 if (err)
3801 memprintf(err, "'%s' : ID '%d' out of range (1..63) in error IDs list '%s'",
3802 args[cur_arg], code, args[cur_arg + 1]);
3803 return ERR_ALERT | ERR_FATAL;
3804 }
3805 *ignerr |= 1ULL << code;
3806 p = strchr(p, ',');
3807 if (p)
3808 p++;
3809 }
3810
Emeric Brun2cb7ae52012-10-05 14:14:21 +02003811 return 0;
3812}
3813
3814/* parse the "force-sslv3" bind keyword */
3815static int bind_parse_force_sslv3(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
3816{
3817 conf->ssl_options |= BC_SSL_O_USE_SSLV3;
3818 return 0;
3819}
3820
3821/* parse the "force-tlsv10" bind keyword */
3822static int bind_parse_force_tlsv10(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
3823{
3824 conf->ssl_options |= BC_SSL_O_USE_TLSV10;
Emeric Brun2d0c4822012-10-02 13:45:20 +02003825 return 0;
3826}
3827
Emeric Brun2cb7ae52012-10-05 14:14:21 +02003828/* parse the "force-tlsv11" bind keyword */
3829static int bind_parse_force_tlsv11(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
3830{
3831#if SSL_OP_NO_TLSv1_1
3832 conf->ssl_options |= BC_SSL_O_USE_TLSV11;
3833 return 0;
3834#else
3835 if (err)
3836 memprintf(err, "'%s' : library does not support protocol TLSv1.1", args[cur_arg]);
3837 return ERR_ALERT | ERR_FATAL;
3838#endif
3839}
3840
3841/* parse the "force-tlsv12" bind keyword */
3842static int bind_parse_force_tlsv12(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
3843{
3844#if SSL_OP_NO_TLSv1_2
3845 conf->ssl_options |= BC_SSL_O_USE_TLSV12;
3846 return 0;
3847#else
3848 if (err)
3849 memprintf(err, "'%s' : library does not support protocol TLSv1.2", args[cur_arg]);
3850 return ERR_ALERT | ERR_FATAL;
3851#endif
3852}
3853
3854
Emeric Brun2d0c4822012-10-02 13:45:20 +02003855/* parse the "no-tls-tickets" bind keyword */
3856static int bind_parse_no_tls_tickets(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
3857{
Emeric Brun89675492012-10-05 13:48:26 +02003858 conf->ssl_options |= BC_SSL_O_NO_TLS_TICKETS;
Emeric Brun81c00f02012-09-21 14:31:21 +02003859 return 0;
3860}
3861
Emeric Brun2d0c4822012-10-02 13:45:20 +02003862
Emeric Brun9b3009b2012-10-05 11:55:06 +02003863/* parse the "no-sslv3" bind keyword */
3864static 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 +02003865{
Emeric Brun89675492012-10-05 13:48:26 +02003866 conf->ssl_options |= BC_SSL_O_NO_SSLV3;
Willy Tarreau79eeafa2012-09-14 07:53:05 +02003867 return 0;
3868}
3869
Emeric Brun9b3009b2012-10-05 11:55:06 +02003870/* parse the "no-tlsv10" bind keyword */
3871static 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 +02003872{
Emeric Brun89675492012-10-05 13:48:26 +02003873 conf->ssl_options |= BC_SSL_O_NO_TLSV10;
Emeric Brunc0ff4922012-09-28 19:37:02 +02003874 return 0;
3875}
3876
Emeric Brun9b3009b2012-10-05 11:55:06 +02003877/* parse the "no-tlsv11" bind keyword */
3878static 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 +02003879{
Emeric Brun89675492012-10-05 13:48:26 +02003880 conf->ssl_options |= BC_SSL_O_NO_TLSV11;
Emeric Brunc0ff4922012-09-28 19:37:02 +02003881 return 0;
3882}
3883
Emeric Brun9b3009b2012-10-05 11:55:06 +02003884/* parse the "no-tlsv12" bind keyword */
3885static 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 +02003886{
Emeric Brun89675492012-10-05 13:48:26 +02003887 conf->ssl_options |= BC_SSL_O_NO_TLSV12;
Willy Tarreau79eeafa2012-09-14 07:53:05 +02003888 return 0;
3889}
3890
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02003891/* parse the "npn" bind keyword */
3892static int bind_parse_npn(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
3893{
3894#ifdef OPENSSL_NPN_NEGOTIATED
3895 char *p1, *p2;
3896
3897 if (!*args[cur_arg + 1]) {
3898 memprintf(err, "'%s' : missing the comma-delimited NPN protocol suite", args[cur_arg]);
3899 return ERR_ALERT | ERR_FATAL;
3900 }
3901
3902 free(conf->npn_str);
3903
3904 /* the NPN string is built as a suite of (<len> <name>)* */
3905 conf->npn_len = strlen(args[cur_arg + 1]) + 1;
3906 conf->npn_str = calloc(1, conf->npn_len);
3907 memcpy(conf->npn_str + 1, args[cur_arg + 1], conf->npn_len);
3908
3909 /* replace commas with the name length */
3910 p1 = conf->npn_str;
3911 p2 = p1 + 1;
3912 while (1) {
3913 p2 = memchr(p1 + 1, ',', conf->npn_str + conf->npn_len - (p1 + 1));
3914 if (!p2)
3915 p2 = p1 + 1 + strlen(p1 + 1);
3916
3917 if (p2 - (p1 + 1) > 255) {
3918 *p2 = '\0';
3919 memprintf(err, "'%s' : NPN protocol name too long : '%s'", args[cur_arg], p1 + 1);
3920 return ERR_ALERT | ERR_FATAL;
3921 }
3922
3923 *p1 = p2 - (p1 + 1);
3924 p1 = p2;
3925
3926 if (!*p2)
3927 break;
3928
3929 *(p2++) = '\0';
3930 }
3931 return 0;
3932#else
3933 if (err)
3934 memprintf(err, "'%s' : library does not support TLS NPN extension", args[cur_arg]);
3935 return ERR_ALERT | ERR_FATAL;
3936#endif
3937}
3938
Willy Tarreauab861d32013-04-02 02:30:41 +02003939/* parse the "alpn" bind keyword */
3940static int bind_parse_alpn(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
3941{
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01003942#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Willy Tarreauab861d32013-04-02 02:30:41 +02003943 char *p1, *p2;
3944
3945 if (!*args[cur_arg + 1]) {
3946 memprintf(err, "'%s' : missing the comma-delimited ALPN protocol suite", args[cur_arg]);
3947 return ERR_ALERT | ERR_FATAL;
3948 }
3949
3950 free(conf->alpn_str);
3951
3952 /* the ALPN string is built as a suite of (<len> <name>)* */
3953 conf->alpn_len = strlen(args[cur_arg + 1]) + 1;
3954 conf->alpn_str = calloc(1, conf->alpn_len);
3955 memcpy(conf->alpn_str + 1, args[cur_arg + 1], conf->alpn_len);
3956
3957 /* replace commas with the name length */
3958 p1 = conf->alpn_str;
3959 p2 = p1 + 1;
3960 while (1) {
3961 p2 = memchr(p1 + 1, ',', conf->alpn_str + conf->alpn_len - (p1 + 1));
3962 if (!p2)
3963 p2 = p1 + 1 + strlen(p1 + 1);
3964
3965 if (p2 - (p1 + 1) > 255) {
3966 *p2 = '\0';
3967 memprintf(err, "'%s' : ALPN protocol name too long : '%s'", args[cur_arg], p1 + 1);
3968 return ERR_ALERT | ERR_FATAL;
3969 }
3970
3971 *p1 = p2 - (p1 + 1);
3972 p1 = p2;
3973
3974 if (!*p2)
3975 break;
3976
3977 *(p2++) = '\0';
3978 }
3979 return 0;
3980#else
3981 if (err)
3982 memprintf(err, "'%s' : library does not support TLS ALPN extension", args[cur_arg]);
3983 return ERR_ALERT | ERR_FATAL;
3984#endif
3985}
3986
Willy Tarreau79eeafa2012-09-14 07:53:05 +02003987/* parse the "ssl" bind keyword */
Willy Tarreau4348fad2012-09-20 16:48:07 +02003988static 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 +02003989{
Willy Tarreau81796be2012-09-22 19:11:47 +02003990 struct listener *l;
3991
Willy Tarreau4348fad2012-09-20 16:48:07 +02003992 conf->is_ssl = 1;
Emeric Brun76d88952012-10-05 15:47:31 +02003993
3994 if (global.listen_default_ciphers && !conf->ciphers)
3995 conf->ciphers = strdup(global.listen_default_ciphers);
3996
Willy Tarreau81796be2012-09-22 19:11:47 +02003997 list_for_each_entry(l, &conf->listeners, by_bind)
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02003998 l->xprt = &ssl_sock;
Willy Tarreau81796be2012-09-22 19:11:47 +02003999
Willy Tarreau79eeafa2012-09-14 07:53:05 +02004000 return 0;
4001}
4002
Emmanuel Hocdet65623372013-01-24 17:17:15 +01004003/* parse the "strict-sni" bind keyword */
4004static int bind_parse_strict_sni(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
4005{
4006 conf->strict_sni = 1;
4007 return 0;
4008}
4009
Emeric Brund94b3fe2012-09-20 18:23:56 +02004010/* parse the "verify" bind keyword */
4011static int bind_parse_verify(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
4012{
4013 if (!*args[cur_arg + 1]) {
4014 if (err)
4015 memprintf(err, "'%s' : missing verify method", args[cur_arg]);
4016 return ERR_ALERT | ERR_FATAL;
4017 }
4018
4019 if (strcmp(args[cur_arg + 1], "none") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01004020 conf->verify = SSL_SOCK_VERIFY_NONE;
Emeric Brund94b3fe2012-09-20 18:23:56 +02004021 else if (strcmp(args[cur_arg + 1], "optional") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01004022 conf->verify = SSL_SOCK_VERIFY_OPTIONAL;
Emeric Brund94b3fe2012-09-20 18:23:56 +02004023 else if (strcmp(args[cur_arg + 1], "required") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01004024 conf->verify = SSL_SOCK_VERIFY_REQUIRED;
Emeric Brund94b3fe2012-09-20 18:23:56 +02004025 else {
4026 if (err)
4027 memprintf(err, "'%s' : unknown verify method '%s', only 'none', 'optional', and 'required' are supported\n",
4028 args[cur_arg], args[cur_arg + 1]);
4029 return ERR_ALERT | ERR_FATAL;
4030 }
4031
4032 return 0;
4033}
4034
Willy Tarreau92faadf2012-10-10 23:04:25 +02004035/************** "server" keywords ****************/
4036
Emeric Brunef42d922012-10-11 16:11:36 +02004037/* parse the "ca-file" server keyword */
4038static int srv_parse_ca_file(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4039{
4040 if (!*args[*cur_arg + 1]) {
4041 if (err)
4042 memprintf(err, "'%s' : missing CAfile path", args[*cur_arg]);
4043 return ERR_ALERT | ERR_FATAL;
4044 }
4045
4046 if ((*args[*cur_arg + 1] != '/') && global.ca_base)
4047 memprintf(&newsrv->ssl_ctx.ca_file, "%s/%s", global.ca_base, args[*cur_arg + 1]);
4048 else
4049 memprintf(&newsrv->ssl_ctx.ca_file, "%s", args[*cur_arg + 1]);
4050
4051 return 0;
4052}
4053
Willy Tarreau92faadf2012-10-10 23:04:25 +02004054/* parse the "check-ssl" server keyword */
4055static int srv_parse_check_ssl(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4056{
4057 newsrv->check.use_ssl = 1;
4058 if (global.connect_default_ciphers && !newsrv->ssl_ctx.ciphers)
4059 newsrv->ssl_ctx.ciphers = strdup(global.connect_default_ciphers);
4060 return 0;
4061}
4062
4063/* parse the "ciphers" server keyword */
4064static int srv_parse_ciphers(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4065{
4066 if (!*args[*cur_arg + 1]) {
4067 memprintf(err, "'%s' : missing cipher suite", args[*cur_arg]);
4068 return ERR_ALERT | ERR_FATAL;
4069 }
4070
4071 free(newsrv->ssl_ctx.ciphers);
4072 newsrv->ssl_ctx.ciphers = strdup(args[*cur_arg + 1]);
4073 return 0;
4074}
4075
Emeric Brunef42d922012-10-11 16:11:36 +02004076/* parse the "crl-file" server keyword */
4077static int srv_parse_crl_file(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4078{
4079#ifndef X509_V_FLAG_CRL_CHECK
4080 if (err)
4081 memprintf(err, "'%s' : library does not support CRL verify", args[*cur_arg]);
4082 return ERR_ALERT | ERR_FATAL;
4083#else
4084 if (!*args[*cur_arg + 1]) {
4085 if (err)
4086 memprintf(err, "'%s' : missing CRLfile path", args[*cur_arg]);
4087 return ERR_ALERT | ERR_FATAL;
4088 }
4089
4090 if ((*args[*cur_arg + 1] != '/') && global.ca_base)
4091 memprintf(&newsrv->ssl_ctx.crl_file, "%s/%s", global.ca_base, args[*cur_arg + 1]);
4092 else
4093 memprintf(&newsrv->ssl_ctx.crl_file, "%s", args[*cur_arg + 1]);
4094
4095 return 0;
4096#endif
4097}
4098
Emeric Bruna7aa3092012-10-26 12:58:00 +02004099/* parse the "crt" server keyword */
4100static int srv_parse_crt(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4101{
4102 if (!*args[*cur_arg + 1]) {
4103 if (err)
4104 memprintf(err, "'%s' : missing certificate file path", args[*cur_arg]);
4105 return ERR_ALERT | ERR_FATAL;
4106 }
4107
4108 if ((*args[*cur_arg + 1] != '/') && global.crt_base)
4109 memprintf(&newsrv->ssl_ctx.client_crt, "%s/%s", global.ca_base, args[*cur_arg + 1]);
4110 else
4111 memprintf(&newsrv->ssl_ctx.client_crt, "%s", args[*cur_arg + 1]);
4112
4113 return 0;
4114}
Emeric Brunef42d922012-10-11 16:11:36 +02004115
Willy Tarreau92faadf2012-10-10 23:04:25 +02004116/* parse the "force-sslv3" server keyword */
4117static int srv_parse_force_sslv3(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4118{
4119 newsrv->ssl_ctx.options |= SRV_SSL_O_USE_SSLV3;
4120 return 0;
4121}
4122
4123/* parse the "force-tlsv10" server keyword */
4124static int srv_parse_force_tlsv10(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4125{
4126 newsrv->ssl_ctx.options |= SRV_SSL_O_USE_TLSV10;
4127 return 0;
4128}
4129
4130/* parse the "force-tlsv11" server keyword */
4131static int srv_parse_force_tlsv11(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4132{
4133#if SSL_OP_NO_TLSv1_1
4134 newsrv->ssl_ctx.options |= SRV_SSL_O_USE_TLSV11;
4135 return 0;
4136#else
4137 if (err)
4138 memprintf(err, "'%s' : library does not support protocol TLSv1.1", args[*cur_arg]);
4139 return ERR_ALERT | ERR_FATAL;
4140#endif
4141}
4142
4143/* parse the "force-tlsv12" server keyword */
4144static int srv_parse_force_tlsv12(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4145{
4146#if SSL_OP_NO_TLSv1_2
4147 newsrv->ssl_ctx.options |= SRV_SSL_O_USE_TLSV12;
4148 return 0;
4149#else
4150 if (err)
4151 memprintf(err, "'%s' : library does not support protocol TLSv1.2", args[*cur_arg]);
4152 return ERR_ALERT | ERR_FATAL;
4153#endif
4154}
4155
4156/* parse the "no-sslv3" server keyword */
4157static int srv_parse_no_sslv3(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4158{
4159 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_SSLV3;
4160 return 0;
4161}
4162
4163/* parse the "no-tlsv10" server keyword */
4164static int srv_parse_no_tlsv10(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4165{
4166 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_TLSV10;
4167 return 0;
4168}
4169
4170/* parse the "no-tlsv11" server keyword */
4171static int srv_parse_no_tlsv11(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4172{
4173 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_TLSV11;
4174 return 0;
4175}
4176
4177/* parse the "no-tlsv12" server keyword */
4178static int srv_parse_no_tlsv12(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4179{
4180 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_TLSV12;
4181 return 0;
4182}
4183
Emeric Brunf9c5c472012-10-11 15:28:34 +02004184/* parse the "no-tls-tickets" server keyword */
4185static int srv_parse_no_tls_tickets(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4186{
4187 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_TLS_TICKETS;
4188 return 0;
4189}
David Safb76832014-05-08 23:42:08 -04004190/* parse the "send-proxy-v2-ssl" server keyword */
4191static int srv_parse_send_proxy_ssl(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4192{
4193 newsrv->pp_opts |= SRV_PP_V2;
4194 newsrv->pp_opts |= SRV_PP_V2_SSL;
4195 return 0;
4196}
4197
4198/* parse the "send-proxy-v2-ssl-cn" server keyword */
4199static int srv_parse_send_proxy_cn(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4200{
4201 newsrv->pp_opts |= SRV_PP_V2;
4202 newsrv->pp_opts |= SRV_PP_V2_SSL;
4203 newsrv->pp_opts |= SRV_PP_V2_SSL_CN;
4204 return 0;
4205}
Emeric Brunf9c5c472012-10-11 15:28:34 +02004206
Willy Tarreau92faadf2012-10-10 23:04:25 +02004207/* parse the "ssl" server keyword */
4208static int srv_parse_ssl(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4209{
4210 newsrv->use_ssl = 1;
4211 if (global.connect_default_ciphers && !newsrv->ssl_ctx.ciphers)
4212 newsrv->ssl_ctx.ciphers = strdup(global.connect_default_ciphers);
4213 return 0;
4214}
4215
Emeric Brunef42d922012-10-11 16:11:36 +02004216/* parse the "verify" server keyword */
4217static int srv_parse_verify(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4218{
4219 if (!*args[*cur_arg + 1]) {
4220 if (err)
4221 memprintf(err, "'%s' : missing verify method", args[*cur_arg]);
4222 return ERR_ALERT | ERR_FATAL;
4223 }
4224
4225 if (strcmp(args[*cur_arg + 1], "none") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01004226 newsrv->ssl_ctx.verify = SSL_SOCK_VERIFY_NONE;
Emeric Brunef42d922012-10-11 16:11:36 +02004227 else if (strcmp(args[*cur_arg + 1], "required") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01004228 newsrv->ssl_ctx.verify = SSL_SOCK_VERIFY_REQUIRED;
Emeric Brunef42d922012-10-11 16:11:36 +02004229 else {
4230 if (err)
4231 memprintf(err, "'%s' : unknown verify method '%s', only 'none' and 'required' are supported\n",
4232 args[*cur_arg], args[*cur_arg + 1]);
4233 return ERR_ALERT | ERR_FATAL;
4234 }
4235
Evan Broderbe554312013-06-27 00:05:25 -07004236 return 0;
4237}
4238
4239/* parse the "verifyhost" server keyword */
4240static int srv_parse_verifyhost(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4241{
4242 if (!*args[*cur_arg + 1]) {
4243 if (err)
4244 memprintf(err, "'%s' : missing hostname to verify against", args[*cur_arg]);
4245 return ERR_ALERT | ERR_FATAL;
4246 }
4247
4248 newsrv->ssl_ctx.verify_host = strdup(args[*cur_arg + 1]);
4249
Emeric Brunef42d922012-10-11 16:11:36 +02004250 return 0;
4251}
4252
Willy Tarreau7875d092012-09-10 08:20:03 +02004253/* Note: must not be declared <const> as its list will be overwritten.
4254 * Please take care of keeping this list alphabetically sorted.
4255 */
Willy Tarreaudc13c112013-06-21 23:16:39 +02004256static struct sample_fetch_kw_list sample_fetch_keywords = {ILH, {
Emeric Brun645ae792014-04-30 14:21:06 +02004257 { "ssl_bc", smp_fetch_ssl_fc, 0, NULL, SMP_T_BOOL, SMP_USE_L5SRV },
4258 { "ssl_bc_alg_keysize", smp_fetch_ssl_fc_alg_keysize, 0, NULL, SMP_T_UINT, SMP_USE_L5SRV },
4259 { "ssl_bc_cipher", smp_fetch_ssl_fc_cipher, 0, NULL, SMP_T_STR, SMP_USE_L5SRV },
4260 { "ssl_bc_protocol", smp_fetch_ssl_fc_protocol, 0, NULL, SMP_T_STR, SMP_USE_L5SRV },
Emeric Brunb73a9b02014-04-30 18:49:19 +02004261 { "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 +02004262 { "ssl_bc_use_keysize", smp_fetch_ssl_fc_use_keysize, 0, NULL, SMP_T_UINT, SMP_USE_L5SRV },
4263 { "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 +01004264 { "ssl_c_ca_err", smp_fetch_ssl_c_ca_err, 0, NULL, SMP_T_UINT, SMP_USE_L5CLI },
4265 { "ssl_c_ca_err_depth", smp_fetch_ssl_c_ca_err_depth, 0, NULL, SMP_T_UINT, SMP_USE_L5CLI },
4266 { "ssl_c_err", smp_fetch_ssl_c_err, 0, NULL, SMP_T_UINT, SMP_USE_L5CLI },
Emeric Brunba841a12014-04-30 17:05:08 +02004267 { "ssl_c_i_dn", smp_fetch_ssl_x_i_dn, ARG2(0,STR,SINT), NULL, SMP_T_STR, SMP_USE_L5CLI },
4268 { "ssl_c_key_alg", smp_fetch_ssl_x_key_alg, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
4269 { "ssl_c_notafter", smp_fetch_ssl_x_notafter, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
4270 { "ssl_c_notbefore", smp_fetch_ssl_x_notbefore, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
4271 { "ssl_c_sig_alg", smp_fetch_ssl_x_sig_alg, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
4272 { "ssl_c_s_dn", smp_fetch_ssl_x_s_dn, ARG2(0,STR,SINT), NULL, SMP_T_STR, SMP_USE_L5CLI },
4273 { "ssl_c_serial", smp_fetch_ssl_x_serial, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
4274 { "ssl_c_sha1", smp_fetch_ssl_x_sha1, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Willy Tarreau80aca902013-01-07 15:42:20 +01004275 { "ssl_c_used", smp_fetch_ssl_c_used, 0, NULL, SMP_T_BOOL, SMP_USE_L5CLI },
4276 { "ssl_c_verify", smp_fetch_ssl_c_verify, 0, NULL, SMP_T_UINT, SMP_USE_L5CLI },
Emeric Brunba841a12014-04-30 17:05:08 +02004277 { "ssl_c_version", smp_fetch_ssl_x_version, 0, NULL, SMP_T_UINT, SMP_USE_L5CLI },
4278 { "ssl_f_i_dn", smp_fetch_ssl_x_i_dn, ARG2(0,STR,SINT), NULL, SMP_T_STR, SMP_USE_L5CLI },
4279 { "ssl_f_key_alg", smp_fetch_ssl_x_key_alg, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
4280 { "ssl_f_notafter", smp_fetch_ssl_x_notafter, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
4281 { "ssl_f_notbefore", smp_fetch_ssl_x_notbefore, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
4282 { "ssl_f_sig_alg", smp_fetch_ssl_x_sig_alg, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
4283 { "ssl_f_s_dn", smp_fetch_ssl_x_s_dn, ARG2(0,STR,SINT), NULL, SMP_T_STR, SMP_USE_L5CLI },
4284 { "ssl_f_serial", smp_fetch_ssl_x_serial, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Emeric Brun55f4fa82014-04-30 17:11:25 +02004285 { "ssl_f_sha1", smp_fetch_ssl_x_sha1, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Emeric Brunba841a12014-04-30 17:05:08 +02004286 { "ssl_f_version", smp_fetch_ssl_x_version, 0, NULL, SMP_T_UINT, SMP_USE_L5CLI },
Willy Tarreau80aca902013-01-07 15:42:20 +01004287 { "ssl_fc", smp_fetch_ssl_fc, 0, NULL, SMP_T_BOOL, SMP_USE_L5CLI },
4288 { "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 +01004289 { "ssl_fc_cipher", smp_fetch_ssl_fc_cipher, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Willy Tarreau80aca902013-01-07 15:42:20 +01004290 { "ssl_fc_has_crt", smp_fetch_ssl_fc_has_crt, 0, NULL, SMP_T_BOOL, SMP_USE_L5CLI },
4291 { "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 +02004292#ifdef OPENSSL_NPN_NEGOTIATED
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01004293 { "ssl_fc_npn", smp_fetch_ssl_fc_npn, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Willy Tarreaua33c6542012-10-15 13:19:06 +02004294#endif
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01004295#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01004296 { "ssl_fc_alpn", smp_fetch_ssl_fc_alpn, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Willy Tarreauab861d32013-04-02 02:30:41 +02004297#endif
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01004298 { "ssl_fc_protocol", smp_fetch_ssl_fc_protocol, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Emeric Brunb73a9b02014-04-30 18:49:19 +02004299 { "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 +01004300 { "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 +01004301 { "ssl_fc_session_id", smp_fetch_ssl_fc_session_id, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
4302 { "ssl_fc_sni", smp_fetch_ssl_fc_sni, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Willy Tarreau7875d092012-09-10 08:20:03 +02004303 { NULL, NULL, 0, 0, 0 },
4304}};
4305
4306/* Note: must not be declared <const> as its list will be overwritten.
4307 * Please take care of keeping this list alphabetically sorted.
4308 */
Willy Tarreaudc13c112013-06-21 23:16:39 +02004309static struct acl_kw_list acl_kws = {ILH, {
Thierry FOURNIERc5a4e982014-03-05 16:07:08 +01004310 { "ssl_fc_sni_end", "ssl_fc_sni", PAT_MATCH_END },
4311 { "ssl_fc_sni_reg", "ssl_fc_sni", PAT_MATCH_REG },
Willy Tarreau8ed669b2013-01-11 15:49:37 +01004312 { /* END */ },
Willy Tarreau7875d092012-09-10 08:20:03 +02004313}};
4314
Willy Tarreau79eeafa2012-09-14 07:53:05 +02004315/* Note: must not be declared <const> as its list will be overwritten.
4316 * Please take care of keeping this list alphabetically sorted, doing so helps
4317 * all code contributors.
4318 * Optional keywords are also declared with a NULL ->parse() function so that
4319 * the config parser can report an appropriate error when a known keyword was
4320 * not enabled.
4321 */
Willy Tarreau51fb7652012-09-18 18:24:39 +02004322static struct bind_kw_list bind_kws = { "SSL", { }, {
Willy Tarreauab861d32013-04-02 02:30:41 +02004323 { "alpn", bind_parse_alpn, 1 }, /* set ALPN supported protocols */
Emeric Brunfb510ea2012-10-05 12:00:26 +02004324 { "ca-file", bind_parse_ca_file, 1 }, /* set CAfile to process verify on client cert */
Emeric Brun2d0c4822012-10-02 13:45:20 +02004325 { "ca-ignore-err", bind_parse_ignore_err, 1 }, /* set error IDs to ignore on verify depth > 0 */
4326 { "ciphers", bind_parse_ciphers, 1 }, /* set SSL cipher suite */
Emeric Brunfb510ea2012-10-05 12:00:26 +02004327 { "crl-file", bind_parse_crl_file, 1 }, /* set certificat revocation list file use on client cert verify */
Emeric Brun2d0c4822012-10-02 13:45:20 +02004328 { "crt", bind_parse_crt, 1 }, /* load SSL certificates from this location */
4329 { "crt-ignore-err", bind_parse_ignore_err, 1 }, /* set error IDs to ingore on verify depth == 0 */
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01004330 { "crt-list", bind_parse_crt_list, 1 }, /* load a list of crt from this location */
Emeric Brun2d0c4822012-10-02 13:45:20 +02004331 { "ecdhe", bind_parse_ecdhe, 1 }, /* defines named curve for elliptic curve Diffie-Hellman */
Emeric Brun2cb7ae52012-10-05 14:14:21 +02004332 { "force-sslv3", bind_parse_force_sslv3, 0 }, /* force SSLv3 */
4333 { "force-tlsv10", bind_parse_force_tlsv10, 0 }, /* force TLSv10 */
4334 { "force-tlsv11", bind_parse_force_tlsv11, 0 }, /* force TLSv11 */
4335 { "force-tlsv12", bind_parse_force_tlsv12, 0 }, /* force TLSv12 */
Emeric Brun9b3009b2012-10-05 11:55:06 +02004336 { "no-sslv3", bind_parse_no_sslv3, 0 }, /* disable SSLv3 */
4337 { "no-tlsv10", bind_parse_no_tlsv10, 0 }, /* disable TLSv10 */
4338 { "no-tlsv11", bind_parse_no_tlsv11, 0 }, /* disable TLSv11 */
4339 { "no-tlsv12", bind_parse_no_tlsv12, 0 }, /* disable TLSv12 */
Emeric Brun2d0c4822012-10-02 13:45:20 +02004340 { "no-tls-tickets", bind_parse_no_tls_tickets, 0 }, /* disable session resumption tickets */
Emeric Brun2d0c4822012-10-02 13:45:20 +02004341 { "ssl", bind_parse_ssl, 0 }, /* enable SSL processing */
Emmanuel Hocdet65623372013-01-24 17:17:15 +01004342 { "strict-sni", bind_parse_strict_sni, 0 }, /* refuse negotiation if sni doesn't match a certificate */
Emeric Brun2d0c4822012-10-02 13:45:20 +02004343 { "verify", bind_parse_verify, 1 }, /* set SSL verify method */
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02004344 { "npn", bind_parse_npn, 1 }, /* set NPN supported protocols */
Willy Tarreau79eeafa2012-09-14 07:53:05 +02004345 { NULL, NULL, 0 },
4346}};
Emeric Brun46591952012-05-18 15:47:34 +02004347
Willy Tarreau92faadf2012-10-10 23:04:25 +02004348/* Note: must not be declared <const> as its list will be overwritten.
4349 * Please take care of keeping this list alphabetically sorted, doing so helps
4350 * all code contributors.
4351 * Optional keywords are also declared with a NULL ->parse() function so that
4352 * the config parser can report an appropriate error when a known keyword was
4353 * not enabled.
4354 */
4355static struct srv_kw_list srv_kws = { "SSL", { }, {
Emeric Brunef42d922012-10-11 16:11:36 +02004356 { "ca-file", srv_parse_ca_file, 1, 0 }, /* set CAfile to process verify server cert */
Emeric Brunecc91fe2012-10-11 15:05:10 +02004357 { "check-ssl", srv_parse_check_ssl, 0, 0 }, /* enable SSL for health checks */
4358 { "ciphers", srv_parse_ciphers, 1, 0 }, /* select the cipher suite */
Emeric Brunef42d922012-10-11 16:11:36 +02004359 { "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 +02004360 { "crt", srv_parse_crt, 1, 0 }, /* set client certificate */
Emeric Brunecc91fe2012-10-11 15:05:10 +02004361 { "force-sslv3", srv_parse_force_sslv3, 0, 0 }, /* force SSLv3 */
4362 { "force-tlsv10", srv_parse_force_tlsv10, 0, 0 }, /* force TLSv10 */
4363 { "force-tlsv11", srv_parse_force_tlsv11, 0, 0 }, /* force TLSv11 */
4364 { "force-tlsv12", srv_parse_force_tlsv12, 0, 0 }, /* force TLSv12 */
4365 { "no-sslv3", srv_parse_no_sslv3, 0, 0 }, /* disable SSLv3 */
4366 { "no-tlsv10", srv_parse_no_tlsv10, 0, 0 }, /* disable TLSv10 */
4367 { "no-tlsv11", srv_parse_no_tlsv11, 0, 0 }, /* disable TLSv11 */
4368 { "no-tlsv12", srv_parse_no_tlsv12, 0, 0 }, /* disable TLSv12 */
Emeric Brunf9c5c472012-10-11 15:28:34 +02004369 { "no-tls-tickets", srv_parse_no_tls_tickets, 0, 0 }, /* disable session resumption tickets */
David Safb76832014-05-08 23:42:08 -04004370 { "send-proxy-v2-ssl", srv_parse_send_proxy_ssl, 0, 0 }, /* send PROXY protocol header v2 with SSL info */
4371 { "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 +02004372 { "ssl", srv_parse_ssl, 0, 0 }, /* enable SSL processing */
Emeric Brunef42d922012-10-11 16:11:36 +02004373 { "verify", srv_parse_verify, 1, 0 }, /* set SSL verify method */
Evan Broderbe554312013-06-27 00:05:25 -07004374 { "verifyhost", srv_parse_verifyhost, 1, 0 }, /* require that SSL cert verifies for hostname */
Willy Tarreau92faadf2012-10-10 23:04:25 +02004375 { NULL, NULL, 0, 0 },
4376}};
4377
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02004378/* transport-layer operations for SSL sockets */
4379struct xprt_ops ssl_sock = {
Emeric Brun46591952012-05-18 15:47:34 +02004380 .snd_buf = ssl_sock_from_buf,
4381 .rcv_buf = ssl_sock_to_buf,
4382 .rcv_pipe = NULL,
4383 .snd_pipe = NULL,
4384 .shutr = NULL,
4385 .shutw = ssl_sock_shutw,
4386 .close = ssl_sock_close,
4387 .init = ssl_sock_init,
4388};
4389
4390__attribute__((constructor))
Willy Tarreau92faadf2012-10-10 23:04:25 +02004391static void __ssl_sock_init(void)
4392{
Emeric Brun46591952012-05-18 15:47:34 +02004393 STACK_OF(SSL_COMP)* cm;
4394
Willy Tarreau610f04b2014-02-13 11:36:41 +01004395#ifdef LISTEN_DEFAULT_CIPHERS
4396 global.listen_default_ciphers = LISTEN_DEFAULT_CIPHERS;
4397#endif
4398#ifdef CONNECT_DEFAULT_CIPHERS
4399 global.connect_default_ciphers = CONNECT_DEFAULT_CIPHERS;
4400#endif
4401 if (global.listen_default_ciphers)
4402 global.listen_default_ciphers = strdup(global.listen_default_ciphers);
4403 if (global.connect_default_ciphers)
4404 global.connect_default_ciphers = strdup(global.connect_default_ciphers);
4405
Emeric Brun46591952012-05-18 15:47:34 +02004406 SSL_library_init();
4407 cm = SSL_COMP_get_compression_methods();
4408 sk_SSL_COMP_zero(cm);
Willy Tarreau7875d092012-09-10 08:20:03 +02004409 sample_register_fetches(&sample_fetch_keywords);
4410 acl_register_keywords(&acl_kws);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02004411 bind_register_keywords(&bind_kws);
Willy Tarreau92faadf2012-10-10 23:04:25 +02004412 srv_register_keywords(&srv_kws);
Emeric Brun46591952012-05-18 15:47:34 +02004413}
4414
4415/*
4416 * Local variables:
4417 * c-indent-level: 8
4418 * c-basic-offset: 8
4419 * End:
4420 */