blob: 328b97880b8d025b0ecad90ccdf0a25c242f04e2 [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 Brun58484372014-06-20 15:46:13 +0200113 long expire;
Emeric Brun4147b2e2014-06-16 18:36:30 +0200114};
115
Emeric Brun58484372014-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 Brun8d914d12014-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 Brun1135ea42014-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 Brun1135ea42014-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 Brun58484372014-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 Brun58484372014-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
2657/* returns common name, NULL terminated, from client certificate, or NULL if none */
2658char *ssl_sock_get_common_name(struct connection *conn)
2659{
2660 X509 *crt = NULL;
2661 X509_NAME *name;
2662 struct chunk *cn_trash;
2663 const char find_cn[] = "CN";
2664 const struct chunk find_cn_chunk = {
2665 .str = (char *)&find_cn,
2666 .len = sizeof(find_cn)-1
2667 };
2668 char *result = NULL;
2669
2670 if (!ssl_sock_is_ssl(conn))
2671 return NULL;
2672
2673 /* SSL_get_peer_certificate, it increase X509 * ref count */
2674 crt = SSL_get_peer_certificate(conn->xprt_ctx);
2675 if (!crt)
2676 goto out;
2677
2678 name = X509_get_subject_name(crt);
2679 if (!name)
2680 goto out;
2681
2682 cn_trash = get_trash_chunk();
2683 if (ssl_sock_get_dn_entry(name, &find_cn_chunk, 1, cn_trash) <= 0)
2684 goto out;
2685 cn_trash->str[cn_trash->len] = '\0';
2686 result = cn_trash->str;
2687
2688 out:
2689 if (crt)
2690 X509_free(crt);
2691
2692 return result;
2693}
2694
2695/* returns 1 if client passed a certificate, 0 if not */
2696int ssl_sock_get_cert_used(struct connection *conn)
2697{
2698 if (!ssl_sock_is_ssl(conn))
2699 return 0;
2700
2701 return SSL_SOCK_ST_FL_VERIFY_DONE & conn->xprt_st ? 1 : 0;
2702}
2703
2704/* returns result from SSL verify */
2705unsigned int ssl_sock_get_verify_result(struct connection *conn)
2706{
2707 if (!ssl_sock_is_ssl(conn))
2708 return (unsigned int)X509_V_ERR_APPLICATION_VERIFICATION;
2709
2710 return (unsigned int)SSL_get_verify_result(conn->xprt_ctx);
2711}
2712
Willy Tarreau7875d092012-09-10 08:20:03 +02002713/***** Below are some sample fetching functions for ACL/patterns *****/
2714
Emeric Brune64aef12012-09-21 13:15:06 +02002715/* boolean, returns true if client cert was present */
2716static int
Emeric Brun2525b6b2012-10-18 15:59:43 +02002717smp_fetch_ssl_fc_has_crt(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002718 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brune64aef12012-09-21 13:15:06 +02002719{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002720 struct connection *conn;
2721
2722 if (!l4)
2723 return 0;
2724
2725 conn = objt_conn(l4->si[0].end);
2726 if (!conn || conn->xprt != &ssl_sock)
Emeric Brune64aef12012-09-21 13:15:06 +02002727 return 0;
2728
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002729 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brune64aef12012-09-21 13:15:06 +02002730 smp->flags |= SMP_F_MAY_CHANGE;
2731 return 0;
2732 }
2733
2734 smp->flags = 0;
2735 smp->type = SMP_T_BOOL;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002736 smp->data.uint = SSL_SOCK_ST_FL_VERIFY_DONE & conn->xprt_st ? 1 : 0;
Emeric Brune64aef12012-09-21 13:15:06 +02002737
2738 return 1;
2739}
2740
Emeric Brunba841a12014-04-30 17:05:08 +02002741/* binary, returns serial of certificate in a binary chunk.
2742 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
2743 * should be use.
2744 */
Willy Tarreau8d598402012-10-22 17:58:39 +02002745static int
Emeric Brunba841a12014-04-30 17:05:08 +02002746smp_fetch_ssl_x_serial(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002747 const struct arg *args, struct sample *smp, const char *kw)
Willy Tarreau8d598402012-10-22 17:58:39 +02002748{
Emeric Brunba841a12014-04-30 17:05:08 +02002749 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Willy Tarreau8d598402012-10-22 17:58:39 +02002750 X509 *crt = NULL;
2751 int ret = 0;
2752 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002753 struct connection *conn;
2754
2755 if (!l4)
2756 return 0;
Willy Tarreau8d598402012-10-22 17:58:39 +02002757
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002758 conn = objt_conn(l4->si[0].end);
2759 if (!conn || conn->xprt != &ssl_sock)
Willy Tarreau8d598402012-10-22 17:58:39 +02002760 return 0;
2761
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002762 if (!(conn->flags & CO_FL_CONNECTED)) {
Willy Tarreau8d598402012-10-22 17:58:39 +02002763 smp->flags |= SMP_F_MAY_CHANGE;
2764 return 0;
2765 }
2766
Emeric Brunba841a12014-04-30 17:05:08 +02002767 if (cert_peer)
2768 crt = SSL_get_peer_certificate(conn->xprt_ctx);
2769 else
2770 crt = SSL_get_certificate(conn->xprt_ctx);
2771
Willy Tarreau8d598402012-10-22 17:58:39 +02002772 if (!crt)
2773 goto out;
2774
Willy Tarreau47ca5452012-12-23 20:22:19 +01002775 smp_trash = get_trash_chunk();
Willy Tarreau8d598402012-10-22 17:58:39 +02002776 if (ssl_sock_get_serial(crt, smp_trash) <= 0)
2777 goto out;
2778
2779 smp->data.str = *smp_trash;
2780 smp->type = SMP_T_BIN;
2781 ret = 1;
2782out:
Emeric Brunba841a12014-04-30 17:05:08 +02002783 /* SSL_get_peer_certificate, it increase X509 * ref count */
2784 if (cert_peer && crt)
Willy Tarreau8d598402012-10-22 17:58:39 +02002785 X509_free(crt);
2786 return ret;
2787}
Emeric Brune64aef12012-09-21 13:15:06 +02002788
Emeric Brunba841a12014-04-30 17:05:08 +02002789/* binary, returns the client certificate's SHA-1 fingerprint (SHA-1 hash of DER-encoded certificate) in a binary chunk.
2790 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
2791 * should be use.
2792 */
James Votha051b4a2013-05-14 20:37:59 +02002793static int
Emeric Brunba841a12014-04-30 17:05:08 +02002794smp_fetch_ssl_x_sha1(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002795 const struct arg *args, struct sample *smp, const char *kw)
James Votha051b4a2013-05-14 20:37:59 +02002796{
Emeric Brunba841a12014-04-30 17:05:08 +02002797 int cert_peer = (kw[4] == 'c') ? 1 : 0;
James Votha051b4a2013-05-14 20:37:59 +02002798 X509 *crt = NULL;
2799 const EVP_MD *digest;
2800 int ret = 0;
2801 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002802 struct connection *conn;
James Votha051b4a2013-05-14 20:37:59 +02002803
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002804 if (!l4)
James Votha051b4a2013-05-14 20:37:59 +02002805 return 0;
2806
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002807 conn = objt_conn(l4->si[0].end);
2808 if (!conn || conn->xprt != &ssl_sock)
2809 return 0;
2810
2811 if (!(conn->flags & CO_FL_CONNECTED)) {
James Votha051b4a2013-05-14 20:37:59 +02002812 smp->flags |= SMP_F_MAY_CHANGE;
2813 return 0;
2814 }
2815
Emeric Brunba841a12014-04-30 17:05:08 +02002816 if (cert_peer)
2817 crt = SSL_get_peer_certificate(conn->xprt_ctx);
2818 else
2819 crt = SSL_get_certificate(conn->xprt_ctx);
James Votha051b4a2013-05-14 20:37:59 +02002820 if (!crt)
2821 goto out;
2822
2823 smp_trash = get_trash_chunk();
2824 digest = EVP_sha1();
2825 X509_digest(crt, digest, (unsigned char *)smp_trash->str, (unsigned int *)&smp_trash->len);
2826
2827 smp->data.str = *smp_trash;
2828 smp->type = SMP_T_BIN;
2829 ret = 1;
2830out:
Emeric Brunba841a12014-04-30 17:05:08 +02002831 /* SSL_get_peer_certificate, it increase X509 * ref count */
2832 if (cert_peer && crt)
James Votha051b4a2013-05-14 20:37:59 +02002833 X509_free(crt);
2834 return ret;
2835}
2836
Emeric Brunba841a12014-04-30 17:05:08 +02002837/* string, returns certificate's notafter date in ASN1_UTCTIME format.
2838 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
2839 * should be use.
2840 */
Emeric Brunce5ad802012-10-22 14:11:22 +02002841static int
Emeric Brunba841a12014-04-30 17:05:08 +02002842smp_fetch_ssl_x_notafter(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002843 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brunce5ad802012-10-22 14:11:22 +02002844{
Emeric Brunba841a12014-04-30 17:05:08 +02002845 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brunce5ad802012-10-22 14:11:22 +02002846 X509 *crt = NULL;
2847 int ret = 0;
2848 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002849 struct connection *conn;
Emeric Brunce5ad802012-10-22 14:11:22 +02002850
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002851 if (!l4)
Emeric Brunce5ad802012-10-22 14:11:22 +02002852 return 0;
2853
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002854 conn = objt_conn(l4->si[0].end);
2855 if (!conn || conn->xprt != &ssl_sock)
2856 return 0;
2857
2858 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunce5ad802012-10-22 14:11:22 +02002859 smp->flags |= SMP_F_MAY_CHANGE;
2860 return 0;
2861 }
2862
Emeric Brunba841a12014-04-30 17:05:08 +02002863 if (cert_peer)
2864 crt = SSL_get_peer_certificate(conn->xprt_ctx);
2865 else
2866 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brunce5ad802012-10-22 14:11:22 +02002867 if (!crt)
2868 goto out;
2869
Willy Tarreau47ca5452012-12-23 20:22:19 +01002870 smp_trash = get_trash_chunk();
Emeric Brunce5ad802012-10-22 14:11:22 +02002871 if (ssl_sock_get_time(X509_get_notAfter(crt), smp_trash) <= 0)
2872 goto out;
2873
2874 smp->data.str = *smp_trash;
2875 smp->type = SMP_T_STR;
2876 ret = 1;
2877out:
Emeric Brunba841a12014-04-30 17:05:08 +02002878 /* SSL_get_peer_certificate, it increase X509 * ref count */
2879 if (cert_peer && crt)
Emeric Brunce5ad802012-10-22 14:11:22 +02002880 X509_free(crt);
2881 return ret;
2882}
2883
Emeric Brunba841a12014-04-30 17:05:08 +02002884/* string, returns a string of a formatted full dn \C=..\O=..\OU=.. \CN=.. of certificate's issuer
2885 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
2886 * should be use.
2887 */
Emeric Brun87855892012-10-17 17:39:35 +02002888static int
Emeric Brunba841a12014-04-30 17:05:08 +02002889smp_fetch_ssl_x_i_dn(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002890 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brun87855892012-10-17 17:39:35 +02002891{
Emeric Brunba841a12014-04-30 17:05:08 +02002892 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brun87855892012-10-17 17:39:35 +02002893 X509 *crt = NULL;
2894 X509_NAME *name;
2895 int ret = 0;
2896 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002897 struct connection *conn;
Emeric Brun87855892012-10-17 17:39:35 +02002898
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002899 if (!l4)
Emeric Brun87855892012-10-17 17:39:35 +02002900 return 0;
2901
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002902 conn = objt_conn(l4->si[0].end);
2903 if (!conn || conn->xprt != &ssl_sock)
2904 return 0;
2905
2906 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun87855892012-10-17 17:39:35 +02002907 smp->flags |= SMP_F_MAY_CHANGE;
2908 return 0;
2909 }
2910
Emeric Brunba841a12014-04-30 17:05:08 +02002911 if (cert_peer)
2912 crt = SSL_get_peer_certificate(conn->xprt_ctx);
2913 else
2914 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brun87855892012-10-17 17:39:35 +02002915 if (!crt)
2916 goto out;
2917
2918 name = X509_get_issuer_name(crt);
2919 if (!name)
2920 goto out;
2921
Willy Tarreau47ca5452012-12-23 20:22:19 +01002922 smp_trash = get_trash_chunk();
Emeric Brun87855892012-10-17 17:39:35 +02002923 if (args && args[0].type == ARGT_STR) {
2924 int pos = 1;
2925
2926 if (args[1].type == ARGT_SINT)
2927 pos = args[1].data.sint;
2928 else if (args[1].type == ARGT_UINT)
2929 pos =(int)args[1].data.uint;
2930
2931 if (ssl_sock_get_dn_entry(name, &args[0].data.str, pos, smp_trash) <= 0)
2932 goto out;
2933 }
2934 else if (ssl_sock_get_dn_oneline(name, smp_trash) <= 0)
2935 goto out;
2936
2937 smp->type = SMP_T_STR;
2938 smp->data.str = *smp_trash;
2939 ret = 1;
2940out:
Emeric Brunba841a12014-04-30 17:05:08 +02002941 /* SSL_get_peer_certificate, it increase X509 * ref count */
2942 if (cert_peer && crt)
Emeric Brun87855892012-10-17 17:39:35 +02002943 X509_free(crt);
2944 return ret;
2945}
2946
Emeric Brunba841a12014-04-30 17:05:08 +02002947/* string, returns notbefore date in ASN1_UTCTIME format.
2948 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
2949 * should be use.
2950 */
Emeric Brunce5ad802012-10-22 14:11:22 +02002951static int
Emeric Brunba841a12014-04-30 17:05:08 +02002952smp_fetch_ssl_x_notbefore(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002953 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brunce5ad802012-10-22 14:11:22 +02002954{
Emeric Brunba841a12014-04-30 17:05:08 +02002955 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brunce5ad802012-10-22 14:11:22 +02002956 X509 *crt = NULL;
2957 int ret = 0;
2958 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002959 struct connection *conn;
2960
2961 if (!l4)
2962 return 0;
Emeric Brunce5ad802012-10-22 14:11:22 +02002963
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002964 conn = objt_conn(l4->si[0].end);
2965 if (!conn || conn->xprt != &ssl_sock)
Emeric Brunce5ad802012-10-22 14:11:22 +02002966 return 0;
2967
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002968 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunce5ad802012-10-22 14:11:22 +02002969 smp->flags |= SMP_F_MAY_CHANGE;
2970 return 0;
2971 }
2972
Emeric Brunba841a12014-04-30 17:05:08 +02002973 if (cert_peer)
2974 crt = SSL_get_peer_certificate(conn->xprt_ctx);
2975 else
2976 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brunce5ad802012-10-22 14:11:22 +02002977 if (!crt)
2978 goto out;
2979
Willy Tarreau47ca5452012-12-23 20:22:19 +01002980 smp_trash = get_trash_chunk();
Emeric Brunce5ad802012-10-22 14:11:22 +02002981 if (ssl_sock_get_time(X509_get_notBefore(crt), smp_trash) <= 0)
2982 goto out;
2983
2984 smp->data.str = *smp_trash;
2985 smp->type = SMP_T_STR;
2986 ret = 1;
2987out:
Emeric Brunba841a12014-04-30 17:05:08 +02002988 /* SSL_get_peer_certificate, it increase X509 * ref count */
2989 if (cert_peer && crt)
Emeric Brunce5ad802012-10-22 14:11:22 +02002990 X509_free(crt);
2991 return ret;
2992}
2993
Emeric Brunba841a12014-04-30 17:05:08 +02002994/* string, returns a string of a formatted full dn \C=..\O=..\OU=.. \CN=.. of certificate's subject
2995 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
2996 * should be use.
2997 */
Emeric Brun87855892012-10-17 17:39:35 +02002998static int
Emeric Brunba841a12014-04-30 17:05:08 +02002999smp_fetch_ssl_x_s_dn(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003000 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brun87855892012-10-17 17:39:35 +02003001{
Emeric Brunba841a12014-04-30 17:05:08 +02003002 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brun87855892012-10-17 17:39:35 +02003003 X509 *crt = NULL;
3004 X509_NAME *name;
3005 int ret = 0;
3006 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003007 struct connection *conn;
Emeric Brun87855892012-10-17 17:39:35 +02003008
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003009 if (!l4)
Emeric Brun87855892012-10-17 17:39:35 +02003010 return 0;
3011
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003012 conn = objt_conn(l4->si[0].end);
3013 if (!conn || conn->xprt != &ssl_sock)
3014 return 0;
3015
3016 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun87855892012-10-17 17:39:35 +02003017 smp->flags |= SMP_F_MAY_CHANGE;
3018 return 0;
3019 }
3020
Emeric Brunba841a12014-04-30 17:05:08 +02003021 if (cert_peer)
3022 crt = SSL_get_peer_certificate(conn->xprt_ctx);
3023 else
3024 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brun87855892012-10-17 17:39:35 +02003025 if (!crt)
3026 goto out;
3027
3028 name = X509_get_subject_name(crt);
3029 if (!name)
3030 goto out;
3031
Willy Tarreau47ca5452012-12-23 20:22:19 +01003032 smp_trash = get_trash_chunk();
Emeric Brun87855892012-10-17 17:39:35 +02003033 if (args && args[0].type == ARGT_STR) {
3034 int pos = 1;
3035
3036 if (args[1].type == ARGT_SINT)
3037 pos = args[1].data.sint;
3038 else if (args[1].type == ARGT_UINT)
3039 pos =(int)args[1].data.uint;
3040
3041 if (ssl_sock_get_dn_entry(name, &args[0].data.str, pos, smp_trash) <= 0)
3042 goto out;
3043 }
3044 else if (ssl_sock_get_dn_oneline(name, smp_trash) <= 0)
3045 goto out;
3046
3047 smp->type = SMP_T_STR;
3048 smp->data.str = *smp_trash;
3049 ret = 1;
3050out:
Emeric Brunba841a12014-04-30 17:05:08 +02003051 /* SSL_get_peer_certificate, it increase X509 * ref count */
3052 if (cert_peer && crt)
Emeric Brun87855892012-10-17 17:39:35 +02003053 X509_free(crt);
3054 return ret;
3055}
Emeric Brun9143d372012-12-20 15:44:16 +01003056
3057/* integer, returns true if current session use a client certificate */
3058static int
3059smp_fetch_ssl_c_used(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003060 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brun9143d372012-12-20 15:44:16 +01003061{
3062 X509 *crt;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003063 struct connection *conn;
Emeric Brun9143d372012-12-20 15:44:16 +01003064
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003065 if (!l4)
Emeric Brun9143d372012-12-20 15:44:16 +01003066 return 0;
3067
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003068 conn = objt_conn(l4->si[0].end);
3069 if (!conn || conn->xprt != &ssl_sock)
3070 return 0;
3071
3072 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun9143d372012-12-20 15:44:16 +01003073 smp->flags |= SMP_F_MAY_CHANGE;
3074 return 0;
3075 }
3076
3077 /* SSL_get_peer_certificate returns a ptr on allocated X509 struct */
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003078 crt = SSL_get_peer_certificate(conn->xprt_ctx);
Emeric Brun9143d372012-12-20 15:44:16 +01003079 if (crt) {
3080 X509_free(crt);
3081 }
3082
3083 smp->type = SMP_T_BOOL;
3084 smp->data.uint = (crt != NULL);
3085 return 1;
3086}
3087
Emeric Brunba841a12014-04-30 17:05:08 +02003088/* integer, returns the certificate version
3089 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
3090 * should be use.
3091 */
Emeric Bruna7359fd2012-10-17 15:03:11 +02003092static int
Emeric Brunba841a12014-04-30 17:05:08 +02003093smp_fetch_ssl_x_version(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003094 const struct arg *args, struct sample *smp, const char *kw)
Emeric Bruna7359fd2012-10-17 15:03:11 +02003095{
Emeric Brunba841a12014-04-30 17:05:08 +02003096 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Bruna7359fd2012-10-17 15:03:11 +02003097 X509 *crt;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003098 struct connection *conn;
3099
3100 if (!l4)
3101 return 0;
Emeric Bruna7359fd2012-10-17 15:03:11 +02003102
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003103 conn = objt_conn(l4->si[0].end);
3104 if (!conn || conn->xprt != &ssl_sock)
Emeric Bruna7359fd2012-10-17 15:03:11 +02003105 return 0;
3106
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003107 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Bruna7359fd2012-10-17 15:03:11 +02003108 smp->flags |= SMP_F_MAY_CHANGE;
3109 return 0;
3110 }
3111
Emeric Brunba841a12014-04-30 17:05:08 +02003112 if (cert_peer)
3113 crt = SSL_get_peer_certificate(conn->xprt_ctx);
3114 else
3115 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Bruna7359fd2012-10-17 15:03:11 +02003116 if (!crt)
3117 return 0;
3118
3119 smp->data.uint = (unsigned int)(1 + X509_get_version(crt));
Emeric Brunba841a12014-04-30 17:05:08 +02003120 /* SSL_get_peer_certificate increase X509 * ref count */
3121 if (cert_peer)
3122 X509_free(crt);
Emeric Bruna7359fd2012-10-17 15:03:11 +02003123 smp->type = SMP_T_UINT;
3124
3125 return 1;
3126}
3127
Emeric Brunba841a12014-04-30 17:05:08 +02003128/* string, returns the certificate's signature algorithm.
3129 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
3130 * should be use.
3131 */
Emeric Brun7f56e742012-10-19 18:15:40 +02003132static int
Emeric Brunba841a12014-04-30 17:05:08 +02003133smp_fetch_ssl_x_sig_alg(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003134 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brun7f56e742012-10-19 18:15:40 +02003135{
Emeric Brunba841a12014-04-30 17:05:08 +02003136 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brun7f56e742012-10-19 18:15:40 +02003137 X509 *crt;
3138 int nid;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003139 struct connection *conn;
Emeric Brun7f56e742012-10-19 18:15:40 +02003140
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003141 if (!l4)
Emeric Brun7f56e742012-10-19 18:15:40 +02003142 return 0;
3143
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003144 conn = objt_conn(l4->si[0].end);
3145 if (!conn || conn->xprt != &ssl_sock)
3146 return 0;
3147
3148 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun7f56e742012-10-19 18:15:40 +02003149 smp->flags |= SMP_F_MAY_CHANGE;
3150 return 0;
3151 }
3152
Emeric Brunba841a12014-04-30 17:05:08 +02003153 if (cert_peer)
3154 crt = SSL_get_peer_certificate(conn->xprt_ctx);
3155 else
3156 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brun7f56e742012-10-19 18:15:40 +02003157 if (!crt)
3158 return 0;
3159
3160 nid = OBJ_obj2nid((ASN1_OBJECT *)(crt->cert_info->signature->algorithm));
3161
3162 smp->data.str.str = (char *)OBJ_nid2sn(nid);
Emeric Brun9bf3ba22013-10-07 14:31:44 +02003163 if (!smp->data.str.str) {
Emeric Brunba841a12014-04-30 17:05:08 +02003164 /* SSL_get_peer_certificate increase X509 * ref count */
3165 if (cert_peer)
3166 X509_free(crt);
Emeric Brun7f56e742012-10-19 18:15:40 +02003167 return 0;
Emeric Brun9bf3ba22013-10-07 14:31:44 +02003168 }
Emeric Brun7f56e742012-10-19 18:15:40 +02003169
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01003170 smp->type = SMP_T_STR;
3171 smp->flags |= SMP_F_CONST;
Emeric Brun7f56e742012-10-19 18:15:40 +02003172 smp->data.str.len = strlen(smp->data.str.str);
Emeric Brunba841a12014-04-30 17:05:08 +02003173 /* SSL_get_peer_certificate increase X509 * ref count */
3174 if (cert_peer)
3175 X509_free(crt);
Emeric Brun7f56e742012-10-19 18:15:40 +02003176
3177 return 1;
3178}
3179
Emeric Brunba841a12014-04-30 17:05:08 +02003180/* string, returns the certificate's key algorithm.
3181 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
3182 * should be use.
3183 */
Emeric Brun521a0112012-10-22 12:22:55 +02003184static int
Emeric Brunba841a12014-04-30 17:05:08 +02003185smp_fetch_ssl_x_key_alg(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003186 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brun521a0112012-10-22 12:22:55 +02003187{
Emeric Brunba841a12014-04-30 17:05:08 +02003188 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brun521a0112012-10-22 12:22:55 +02003189 X509 *crt;
3190 int nid;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003191 struct connection *conn;
Emeric Brun521a0112012-10-22 12:22:55 +02003192
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003193 if (!l4)
Emeric Brun521a0112012-10-22 12:22:55 +02003194 return 0;
3195
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003196 conn = objt_conn(l4->si[0].end);
3197 if (!conn || conn->xprt != &ssl_sock)
3198 return 0;
3199
3200 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun521a0112012-10-22 12:22:55 +02003201 smp->flags |= SMP_F_MAY_CHANGE;
3202 return 0;
3203 }
3204
Emeric Brunba841a12014-04-30 17:05:08 +02003205 if (cert_peer)
3206 crt = SSL_get_peer_certificate(conn->xprt_ctx);
3207 else
3208 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brun521a0112012-10-22 12:22:55 +02003209 if (!crt)
3210 return 0;
3211
3212 nid = OBJ_obj2nid((ASN1_OBJECT *)(crt->cert_info->key->algor->algorithm));
3213
3214 smp->data.str.str = (char *)OBJ_nid2sn(nid);
Emeric Brun9bf3ba22013-10-07 14:31:44 +02003215 if (!smp->data.str.str) {
Emeric Brunba841a12014-04-30 17:05:08 +02003216 /* SSL_get_peer_certificate increase X509 * ref count */
3217 if (cert_peer)
3218 X509_free(crt);
Emeric Brun521a0112012-10-22 12:22:55 +02003219 return 0;
Emeric Brun9bf3ba22013-10-07 14:31:44 +02003220 }
Emeric Brun521a0112012-10-22 12:22:55 +02003221
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01003222 smp->type = SMP_T_STR;
3223 smp->flags |= SMP_F_CONST;
Emeric Brun521a0112012-10-22 12:22:55 +02003224 smp->data.str.len = strlen(smp->data.str.str);
Emeric Brunba841a12014-04-30 17:05:08 +02003225 if (cert_peer)
3226 X509_free(crt);
Emeric Brun521a0112012-10-22 12:22:55 +02003227
3228 return 1;
3229}
3230
Emeric Brun645ae792014-04-30 14:21:06 +02003231/* boolean, returns true if front conn. transport layer is SSL.
3232 * This function is also usable on backend conn if the fetch keyword 5th
3233 * char is 'b'.
3234 */
Willy Tarreau7875d092012-09-10 08:20:03 +02003235static int
Emeric Brun2525b6b2012-10-18 15:59:43 +02003236smp_fetch_ssl_fc(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003237 const struct arg *args, struct sample *smp, const char *kw)
Willy Tarreau7875d092012-09-10 08:20:03 +02003238{
Emeric Brun645ae792014-04-30 14:21:06 +02003239 int back_conn = (kw[4] == 'b') ? 1 : 0;
3240 struct connection *conn = objt_conn(l4->si[back_conn].end);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003241
Willy Tarreau7875d092012-09-10 08:20:03 +02003242 smp->type = SMP_T_BOOL;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003243 smp->data.uint = (conn && conn->xprt == &ssl_sock);
Willy Tarreau7875d092012-09-10 08:20:03 +02003244 return 1;
3245}
3246
Emeric Brun2525b6b2012-10-18 15:59:43 +02003247/* boolean, returns true if client present a SNI */
Willy Tarreau7875d092012-09-10 08:20:03 +02003248static int
Emeric Brun2525b6b2012-10-18 15:59:43 +02003249smp_fetch_ssl_fc_has_sni(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003250 const struct arg *args, struct sample *smp, const char *kw)
Willy Tarreau7875d092012-09-10 08:20:03 +02003251{
3252#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003253 struct connection *conn = objt_conn(l4->si[0].end);
3254
Willy Tarreau7875d092012-09-10 08:20:03 +02003255 smp->type = SMP_T_BOOL;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003256 smp->data.uint = (conn && conn->xprt == &ssl_sock) &&
3257 conn->xprt_ctx &&
3258 SSL_get_servername(conn->xprt_ctx, TLSEXT_NAMETYPE_host_name) != NULL;
Willy Tarreau7875d092012-09-10 08:20:03 +02003259 return 1;
3260#else
3261 return 0;
3262#endif
3263}
3264
Emeric Brun645ae792014-04-30 14:21:06 +02003265/* string, returns the used cipher if front conn. transport layer is SSL.
3266 * This function is also usable on backend conn if the fetch keyword 5th
3267 * char is 'b'.
3268 */
Emeric Brun589fcad2012-10-16 14:13:26 +02003269static int
3270smp_fetch_ssl_fc_cipher(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003271 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brun589fcad2012-10-16 14:13:26 +02003272{
Emeric Brun645ae792014-04-30 14:21:06 +02003273 int back_conn = (kw[4] == 'b') ? 1 : 0;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003274 struct connection *conn;
3275
Emeric Brun589fcad2012-10-16 14:13:26 +02003276 smp->flags = 0;
3277
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003278 if (!l4)
3279 return 0;
3280
Emeric Brun645ae792014-04-30 14:21:06 +02003281 conn = objt_conn(l4->si[back_conn].end);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003282 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
Emeric Brun589fcad2012-10-16 14:13:26 +02003283 return 0;
3284
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003285 smp->data.str.str = (char *)SSL_get_cipher_name(conn->xprt_ctx);
Emeric Brun589fcad2012-10-16 14:13:26 +02003286 if (!smp->data.str.str)
3287 return 0;
3288
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01003289 smp->type = SMP_T_STR;
3290 smp->flags |= SMP_F_CONST;
Emeric Brun589fcad2012-10-16 14:13:26 +02003291 smp->data.str.len = strlen(smp->data.str.str);
3292
3293 return 1;
3294}
3295
Emeric Brun645ae792014-04-30 14:21:06 +02003296/* integer, returns the algoritm's keysize if front conn. transport layer
3297 * is SSL.
3298 * This function is also usable on backend conn if the fetch keyword 5th
3299 * char is 'b'.
3300 */
Emeric Brun589fcad2012-10-16 14:13:26 +02003301static int
3302smp_fetch_ssl_fc_alg_keysize(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003303 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brun589fcad2012-10-16 14:13:26 +02003304{
Emeric Brun645ae792014-04-30 14:21:06 +02003305 int back_conn = (kw[4] == 'b') ? 1 : 0;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003306 struct connection *conn;
3307
Emeric Brun589fcad2012-10-16 14:13:26 +02003308 smp->flags = 0;
3309
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003310 if (!l4)
Emeric Brun589fcad2012-10-16 14:13:26 +02003311 return 0;
3312
Emeric Brun645ae792014-04-30 14:21:06 +02003313 conn = objt_conn(l4->si[back_conn].end);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003314 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
Emeric Brun589fcad2012-10-16 14:13:26 +02003315 return 0;
3316
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003317 if (!SSL_get_cipher_bits(conn->xprt_ctx, (int *)&smp->data.uint))
3318 return 0;
3319
Emeric Brun589fcad2012-10-16 14:13:26 +02003320 smp->type = SMP_T_UINT;
3321
3322 return 1;
3323}
3324
Emeric Brun645ae792014-04-30 14:21:06 +02003325/* integer, returns the used keysize if front conn. transport layer is SSL.
3326 * This function is also usable on backend conn if the fetch keyword 5th
3327 * char is 'b'.
3328 */
Emeric Brun589fcad2012-10-16 14:13:26 +02003329static int
3330smp_fetch_ssl_fc_use_keysize(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003331 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brun589fcad2012-10-16 14:13:26 +02003332{
Emeric Brun645ae792014-04-30 14:21:06 +02003333 int back_conn = (kw[4] == 'b') ? 1 : 0;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003334 struct connection *conn;
3335
Emeric Brun589fcad2012-10-16 14:13:26 +02003336 smp->flags = 0;
3337
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003338 if (!l4)
Emeric Brun589fcad2012-10-16 14:13:26 +02003339 return 0;
3340
Emeric Brun645ae792014-04-30 14:21:06 +02003341 conn = objt_conn(l4->si[back_conn].end);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003342 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
3343 return 0;
3344
3345 smp->data.uint = (unsigned int)SSL_get_cipher_bits(conn->xprt_ctx, NULL);
Emeric Brun589fcad2012-10-16 14:13:26 +02003346 if (!smp->data.uint)
3347 return 0;
3348
3349 smp->type = SMP_T_UINT;
3350
3351 return 1;
3352}
3353
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02003354#ifdef OPENSSL_NPN_NEGOTIATED
Willy Tarreau7875d092012-09-10 08:20:03 +02003355static int
Emeric Brun2525b6b2012-10-18 15:59:43 +02003356smp_fetch_ssl_fc_npn(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003357 const struct arg *args, struct sample *smp, const char *kw)
Willy Tarreaua33c6542012-10-15 13:19:06 +02003358{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003359 struct connection *conn;
3360
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01003361 smp->flags = SMP_F_CONST;
3362 smp->type = SMP_T_STR;
Willy Tarreaua33c6542012-10-15 13:19:06 +02003363
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003364 if (!l4)
Willy Tarreaua33c6542012-10-15 13:19:06 +02003365 return 0;
3366
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003367 conn = objt_conn(l4->si[0].end);
3368 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
3369 return 0;
3370
Willy Tarreaua33c6542012-10-15 13:19:06 +02003371 smp->data.str.str = NULL;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003372 SSL_get0_next_proto_negotiated(conn->xprt_ctx,
Willy Tarreaua33c6542012-10-15 13:19:06 +02003373 (const unsigned char **)&smp->data.str.str, (unsigned *)&smp->data.str.len);
3374
3375 if (!smp->data.str.str)
3376 return 0;
3377
3378 return 1;
Willy Tarreaua33c6542012-10-15 13:19:06 +02003379}
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02003380#endif
Willy Tarreaua33c6542012-10-15 13:19:06 +02003381
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01003382#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Willy Tarreauab861d32013-04-02 02:30:41 +02003383static int
3384smp_fetch_ssl_fc_alpn(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003385 const struct arg *args, struct sample *smp, const char *kw)
Willy Tarreauab861d32013-04-02 02:30:41 +02003386{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003387 struct connection *conn;
3388
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01003389 smp->flags = SMP_F_CONST;
3390 smp->type = SMP_T_STR;
Willy Tarreauab861d32013-04-02 02:30:41 +02003391
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003392 if (!l4)
3393 return 0;
3394
3395 conn = objt_conn(l4->si[0].end);
3396 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
Willy Tarreauab861d32013-04-02 02:30:41 +02003397 return 0;
3398
3399 smp->data.str.str = NULL;
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01003400 SSL_get0_alpn_selected(conn->xprt_ctx,
Willy Tarreauab861d32013-04-02 02:30:41 +02003401 (const unsigned char **)&smp->data.str.str, (unsigned *)&smp->data.str.len);
3402
3403 if (!smp->data.str.str)
3404 return 0;
3405
3406 return 1;
3407}
3408#endif
3409
Emeric Brun645ae792014-04-30 14:21:06 +02003410/* string, returns the used protocol if front conn. transport layer is SSL.
3411 * This function is also usable on backend conn if the fetch keyword 5th
3412 * char is 'b'.
3413 */
Willy Tarreaua33c6542012-10-15 13:19:06 +02003414static int
Emeric Brun589fcad2012-10-16 14:13:26 +02003415smp_fetch_ssl_fc_protocol(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003416 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brun589fcad2012-10-16 14:13:26 +02003417{
Emeric Brun645ae792014-04-30 14:21:06 +02003418 int back_conn = (kw[4] == 'b') ? 1 : 0;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003419 struct connection *conn;
3420
Emeric Brun589fcad2012-10-16 14:13:26 +02003421 smp->flags = 0;
3422
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003423 if (!l4)
Emeric Brun589fcad2012-10-16 14:13:26 +02003424 return 0;
3425
Emeric Brun645ae792014-04-30 14:21:06 +02003426 conn = objt_conn(l4->si[back_conn].end);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003427 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
3428 return 0;
3429
3430 smp->data.str.str = (char *)SSL_get_version(conn->xprt_ctx);
Emeric Brun589fcad2012-10-16 14:13:26 +02003431 if (!smp->data.str.str)
3432 return 0;
3433
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01003434 smp->type = SMP_T_STR;
3435 smp->flags = SMP_F_CONST;
Emeric Brun589fcad2012-10-16 14:13:26 +02003436 smp->data.str.len = strlen(smp->data.str.str);
3437
3438 return 1;
3439}
3440
Emeric Brun645ae792014-04-30 14:21:06 +02003441/* binary, returns the SSL session id if front conn. transport layer is SSL.
3442 * This function is also usable on backend conn if the fetch keyword 5th
3443 * char is 'b'.
3444 */
Emeric Brun589fcad2012-10-16 14:13:26 +02003445static int
Emeric Brunfe68f682012-10-16 14:59:28 +02003446smp_fetch_ssl_fc_session_id(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003447 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brunfe68f682012-10-16 14:59:28 +02003448{
3449#if OPENSSL_VERSION_NUMBER > 0x0090800fL
Emeric Brun645ae792014-04-30 14:21:06 +02003450 int back_conn = (kw[4] == 'b') ? 1 : 0;
Emeric Brunfe68f682012-10-16 14:59:28 +02003451 SSL_SESSION *sess;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003452 struct connection *conn;
Emeric Brunfe68f682012-10-16 14:59:28 +02003453
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01003454 smp->flags = SMP_F_CONST;
3455 smp->type = SMP_T_BIN;
Emeric Brunfe68f682012-10-16 14:59:28 +02003456
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003457 if (!l4)
Emeric Brunfe68f682012-10-16 14:59:28 +02003458 return 0;
3459
Emeric Brun645ae792014-04-30 14:21:06 +02003460 conn = objt_conn(l4->si[back_conn].end);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003461 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
3462 return 0;
3463
3464 sess = SSL_get_session(conn->xprt_ctx);
Emeric Brunfe68f682012-10-16 14:59:28 +02003465 if (!sess)
3466 return 0;
3467
3468 smp->data.str.str = (char *)SSL_SESSION_get_id(sess, (unsigned int *)&smp->data.str.len);
3469 if (!smp->data.str.str || !&smp->data.str.len)
3470 return 0;
3471
3472 return 1;
3473#else
3474 return 0;
3475#endif
3476}
3477
3478static int
Emeric Brun2525b6b2012-10-18 15:59:43 +02003479smp_fetch_ssl_fc_sni(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003480 const struct arg *args, struct sample *smp, const char *kw)
Willy Tarreau7875d092012-09-10 08:20:03 +02003481{
3482#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003483 struct connection *conn;
3484
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01003485 smp->flags = SMP_F_CONST;
3486 smp->type = SMP_T_STR;
Willy Tarreau7875d092012-09-10 08:20:03 +02003487
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003488 if (!l4)
Willy Tarreau7875d092012-09-10 08:20:03 +02003489 return 0;
3490
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003491 conn = objt_conn(l4->si[0].end);
3492 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
3493 return 0;
3494
3495 smp->data.str.str = (char *)SSL_get_servername(conn->xprt_ctx, TLSEXT_NAMETYPE_host_name);
Willy Tarreau3e394c92012-09-14 23:56:58 +02003496 if (!smp->data.str.str)
3497 return 0;
3498
Willy Tarreau7875d092012-09-10 08:20:03 +02003499 smp->data.str.len = strlen(smp->data.str.str);
3500 return 1;
3501#else
3502 return 0;
3503#endif
3504}
3505
David Sc1ad52e2014-04-08 18:48:47 -04003506static int
3507smp_fetch_ssl_fc_unique_id(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
3508 const struct arg *args, struct sample *smp, const char *kw)
3509{
3510#if OPENSSL_VERSION_NUMBER > 0x0090800fL
Emeric Brun645ae792014-04-30 14:21:06 +02003511 int back_conn = (kw[4] == 'b') ? 1 : 0;
David Sc1ad52e2014-04-08 18:48:47 -04003512 struct connection *conn;
3513 int finished_len;
David Sc1ad52e2014-04-08 18:48:47 -04003514 struct chunk *finished_trash;
David Sc1ad52e2014-04-08 18:48:47 -04003515
3516 smp->flags = 0;
3517
3518 if (!l4)
3519 return 0;
3520
Emeric Brun645ae792014-04-30 14:21:06 +02003521 conn = objt_conn(l4->si[back_conn].end);
David Sc1ad52e2014-04-08 18:48:47 -04003522 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
3523 return 0;
3524
3525 if (!(conn->flags & CO_FL_CONNECTED)) {
3526 smp->flags |= SMP_F_MAY_CHANGE;
3527 return 0;
3528 }
3529
3530 finished_trash = get_trash_chunk();
3531 if (!SSL_session_reused(conn->xprt_ctx))
3532 finished_len = SSL_get_peer_finished(conn->xprt_ctx, finished_trash->str, finished_trash->size);
3533 else
3534 finished_len = SSL_get_finished(conn->xprt_ctx, finished_trash->str, finished_trash->size);
3535
3536 if (!finished_len)
3537 return 0;
3538
Emeric Brunb73a9b02014-04-30 18:49:19 +02003539 finished_trash->len = finished_len;
3540 smp->data.str = *finished_trash;
3541 smp->type = SMP_T_BIN;
David Sc1ad52e2014-04-08 18:48:47 -04003542
3543 return 1;
3544#else
3545 return 0;
3546#endif
3547}
3548
Emeric Brun2525b6b2012-10-18 15:59:43 +02003549/* integer, returns the first verify error in CA chain of client certificate chain. */
Emeric Brunf282a812012-09-21 15:27:54 +02003550static int
Emeric Brun2525b6b2012-10-18 15:59:43 +02003551smp_fetch_ssl_c_ca_err(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003552 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brunf282a812012-09-21 15:27:54 +02003553{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003554 struct connection *conn;
3555
3556 if (!l4)
Emeric Brunf282a812012-09-21 15:27:54 +02003557 return 0;
3558
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003559 conn = objt_conn(l4->si[0].end);
3560 if (!conn || conn->xprt != &ssl_sock)
3561 return 0;
3562
3563 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunf282a812012-09-21 15:27:54 +02003564 smp->flags = SMP_F_MAY_CHANGE;
3565 return 0;
3566 }
3567
3568 smp->type = SMP_T_UINT;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003569 smp->data.uint = (unsigned int)SSL_SOCK_ST_TO_CA_ERROR(conn->xprt_st);
Emeric Brunf282a812012-09-21 15:27:54 +02003570 smp->flags = 0;
3571
3572 return 1;
3573}
3574
Emeric Brun2525b6b2012-10-18 15:59:43 +02003575/* integer, returns the depth of the first verify error in CA chain of client certificate chain. */
Emeric Brunf282a812012-09-21 15:27:54 +02003576static int
Emeric Brun2525b6b2012-10-18 15:59:43 +02003577smp_fetch_ssl_c_ca_err_depth(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003578 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brunf282a812012-09-21 15:27:54 +02003579{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003580 struct connection *conn;
3581
3582 if (!l4)
3583 return 0;
3584
3585 conn = objt_conn(l4->si[0].end);
3586 if (!conn || conn->xprt != &ssl_sock)
Emeric Brunf282a812012-09-21 15:27:54 +02003587 return 0;
3588
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003589 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunf282a812012-09-21 15:27:54 +02003590 smp->flags = SMP_F_MAY_CHANGE;
3591 return 0;
3592 }
3593
3594 smp->type = SMP_T_UINT;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003595 smp->data.uint = (unsigned int)SSL_SOCK_ST_TO_CAEDEPTH(conn->xprt_st);
Emeric Brunf282a812012-09-21 15:27:54 +02003596 smp->flags = 0;
3597
3598 return 1;
3599}
3600
Emeric Brun2525b6b2012-10-18 15:59:43 +02003601/* integer, returns the first verify error on client certificate */
Emeric Brunf282a812012-09-21 15:27:54 +02003602static int
Emeric Brun2525b6b2012-10-18 15:59:43 +02003603smp_fetch_ssl_c_err(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003604 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brunf282a812012-09-21 15:27:54 +02003605{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003606 struct connection *conn;
3607
3608 if (!l4)
Emeric Brunf282a812012-09-21 15:27:54 +02003609 return 0;
3610
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003611 conn = objt_conn(l4->si[0].end);
3612 if (!conn || conn->xprt != &ssl_sock)
3613 return 0;
3614
3615 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunf282a812012-09-21 15:27:54 +02003616 smp->flags = SMP_F_MAY_CHANGE;
3617 return 0;
3618 }
3619
3620 smp->type = SMP_T_UINT;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003621 smp->data.uint = (unsigned int)SSL_SOCK_ST_TO_CRTERROR(conn->xprt_st);
Emeric Brunf282a812012-09-21 15:27:54 +02003622 smp->flags = 0;
3623
3624 return 1;
3625}
3626
Emeric Brun2525b6b2012-10-18 15:59:43 +02003627/* integer, returns the verify result on client cert */
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02003628static int
Emeric Brun2525b6b2012-10-18 15:59:43 +02003629smp_fetch_ssl_c_verify(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003630 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02003631{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003632 struct connection *conn;
3633
3634 if (!l4)
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02003635 return 0;
3636
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003637 conn = objt_conn(l4->si[0].end);
3638 if (!conn || conn->xprt != &ssl_sock)
3639 return 0;
3640
3641 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02003642 smp->flags = SMP_F_MAY_CHANGE;
3643 return 0;
3644 }
3645
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003646 if (!conn->xprt_ctx)
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02003647 return 0;
3648
3649 smp->type = SMP_T_UINT;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003650 smp->data.uint = (unsigned int)SSL_get_verify_result(conn->xprt_ctx);
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02003651 smp->flags = 0;
3652
3653 return 1;
3654}
3655
Emeric Brunfb510ea2012-10-05 12:00:26 +02003656/* parse the "ca-file" bind keyword */
3657static 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 +02003658{
3659 if (!*args[cur_arg + 1]) {
3660 if (err)
3661 memprintf(err, "'%s' : missing CAfile path", args[cur_arg]);
3662 return ERR_ALERT | ERR_FATAL;
3663 }
3664
Emeric Brunef42d922012-10-11 16:11:36 +02003665 if ((*args[cur_arg + 1] != '/') && global.ca_base)
3666 memprintf(&conf->ca_file, "%s/%s", global.ca_base, args[cur_arg + 1]);
3667 else
3668 memprintf(&conf->ca_file, "%s", args[cur_arg + 1]);
Emeric Brunc8e8d122012-10-02 18:42:10 +02003669
Emeric Brund94b3fe2012-09-20 18:23:56 +02003670 return 0;
3671}
3672
Willy Tarreau79eeafa2012-09-14 07:53:05 +02003673/* parse the "ciphers" bind keyword */
Willy Tarreau4348fad2012-09-20 16:48:07 +02003674static 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 +02003675{
3676 if (!*args[cur_arg + 1]) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02003677 memprintf(err, "'%s' : missing cipher suite", args[cur_arg]);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02003678 return ERR_ALERT | ERR_FATAL;
3679 }
3680
Emeric Brun76d88952012-10-05 15:47:31 +02003681 free(conf->ciphers);
Willy Tarreau4348fad2012-09-20 16:48:07 +02003682 conf->ciphers = strdup(args[cur_arg + 1]);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02003683 return 0;
3684}
3685
3686/* parse the "crt" bind keyword */
Willy Tarreau4348fad2012-09-20 16:48:07 +02003687static 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 +02003688{
Willy Tarreau38011032013-08-13 16:59:39 +02003689 char path[MAXPATHLEN];
Willy Tarreaub75d6922014-04-14 18:05:41 +02003690
Willy Tarreau79eeafa2012-09-14 07:53:05 +02003691 if (!*args[cur_arg + 1]) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02003692 memprintf(err, "'%s' : missing certificate location", args[cur_arg]);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02003693 return ERR_ALERT | ERR_FATAL;
3694 }
3695
Emeric Brunc8e8d122012-10-02 18:42:10 +02003696 if ((*args[cur_arg + 1] != '/' ) && global.crt_base) {
Willy Tarreau38011032013-08-13 16:59:39 +02003697 if ((strlen(global.crt_base) + 1 + strlen(args[cur_arg + 1]) + 1) > MAXPATHLEN) {
Emeric Brunc8e8d122012-10-02 18:42:10 +02003698 memprintf(err, "'%s' : path too long", args[cur_arg]);
3699 return ERR_ALERT | ERR_FATAL;
3700 }
Willy Tarreaub75d6922014-04-14 18:05:41 +02003701 snprintf(path, sizeof(path), "%s/%s", global.crt_base, args[cur_arg + 1]);
Emeric Brunc8e8d122012-10-02 18:42:10 +02003702 if (ssl_sock_load_cert(path, conf, px, err) > 0)
3703 return ERR_ALERT | ERR_FATAL;
3704
3705 return 0;
3706 }
3707
Willy Tarreau4348fad2012-09-20 16:48:07 +02003708 if (ssl_sock_load_cert(args[cur_arg + 1], conf, px, err) > 0)
Willy Tarreau79eeafa2012-09-14 07:53:05 +02003709 return ERR_ALERT | ERR_FATAL;
Emeric Brund94b3fe2012-09-20 18:23:56 +02003710
3711 return 0;
3712}
3713
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01003714/* parse the "crt-list" bind keyword */
3715static int bind_parse_crt_list(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
3716{
3717 if (!*args[cur_arg + 1]) {
3718 memprintf(err, "'%s' : missing certificate location", args[cur_arg]);
3719 return ERR_ALERT | ERR_FATAL;
3720 }
3721
Willy Tarreauad1731d2013-04-02 17:35:58 +02003722 if (ssl_sock_load_cert_list_file(args[cur_arg + 1], conf, px, err) > 0) {
3723 memprintf(err, "'%s' : %s", args[cur_arg], *err);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01003724 return ERR_ALERT | ERR_FATAL;
Willy Tarreauad1731d2013-04-02 17:35:58 +02003725 }
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01003726
3727 return 0;
3728}
3729
Emeric Brunfb510ea2012-10-05 12:00:26 +02003730/* parse the "crl-file" bind keyword */
3731static 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 +02003732{
Emeric Brun051cdab2012-10-02 19:25:50 +02003733#ifndef X509_V_FLAG_CRL_CHECK
3734 if (err)
3735 memprintf(err, "'%s' : library does not support CRL verify", args[cur_arg]);
3736 return ERR_ALERT | ERR_FATAL;
3737#else
Emeric Brund94b3fe2012-09-20 18:23:56 +02003738 if (!*args[cur_arg + 1]) {
3739 if (err)
3740 memprintf(err, "'%s' : missing CRLfile path", args[cur_arg]);
3741 return ERR_ALERT | ERR_FATAL;
3742 }
Emeric Brun2b58d042012-09-20 17:10:03 +02003743
Emeric Brunef42d922012-10-11 16:11:36 +02003744 if ((*args[cur_arg + 1] != '/') && global.ca_base)
3745 memprintf(&conf->crl_file, "%s/%s", global.ca_base, args[cur_arg + 1]);
3746 else
3747 memprintf(&conf->crl_file, "%s", args[cur_arg + 1]);
Emeric Brunc8e8d122012-10-02 18:42:10 +02003748
Emeric Brun2b58d042012-09-20 17:10:03 +02003749 return 0;
Emeric Brun051cdab2012-10-02 19:25:50 +02003750#endif
Emeric Brun2b58d042012-09-20 17:10:03 +02003751}
3752
3753/* parse the "ecdhe" bind keyword keywords */
3754static int bind_parse_ecdhe(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
3755{
3756#if OPENSSL_VERSION_NUMBER < 0x0090800fL
3757 if (err)
3758 memprintf(err, "'%s' : library does not support elliptic curve Diffie-Hellman (too old)", args[cur_arg]);
3759 return ERR_ALERT | ERR_FATAL;
3760#elif defined(OPENSSL_NO_ECDH)
3761 if (err)
3762 memprintf(err, "'%s' : library does not support elliptic curve Diffie-Hellman (disabled via OPENSSL_NO_ECDH)", args[cur_arg]);
3763 return ERR_ALERT | ERR_FATAL;
3764#else
3765 if (!*args[cur_arg + 1]) {
3766 if (err)
3767 memprintf(err, "'%s' : missing named curve", args[cur_arg]);
3768 return ERR_ALERT | ERR_FATAL;
3769 }
3770
3771 conf->ecdhe = strdup(args[cur_arg + 1]);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02003772
3773 return 0;
Emeric Brun2b58d042012-09-20 17:10:03 +02003774#endif
Willy Tarreau79eeafa2012-09-14 07:53:05 +02003775}
3776
Emeric Brun81c00f02012-09-21 14:31:21 +02003777/* parse the "crt_ignerr" and "ca_ignerr" bind keywords */
3778static int bind_parse_ignore_err(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
3779{
3780 int code;
3781 char *p = args[cur_arg + 1];
3782 unsigned long long *ignerr = &conf->crt_ignerr;
3783
3784 if (!*p) {
3785 if (err)
3786 memprintf(err, "'%s' : missing error IDs list", args[cur_arg]);
3787 return ERR_ALERT | ERR_FATAL;
3788 }
3789
3790 if (strcmp(args[cur_arg], "ca-ignore-err") == 0)
3791 ignerr = &conf->ca_ignerr;
3792
3793 if (strcmp(p, "all") == 0) {
3794 *ignerr = ~0ULL;
3795 return 0;
3796 }
3797
3798 while (p) {
3799 code = atoi(p);
3800 if ((code <= 0) || (code > 63)) {
3801 if (err)
3802 memprintf(err, "'%s' : ID '%d' out of range (1..63) in error IDs list '%s'",
3803 args[cur_arg], code, args[cur_arg + 1]);
3804 return ERR_ALERT | ERR_FATAL;
3805 }
3806 *ignerr |= 1ULL << code;
3807 p = strchr(p, ',');
3808 if (p)
3809 p++;
3810 }
3811
Emeric Brun2cb7ae52012-10-05 14:14:21 +02003812 return 0;
3813}
3814
3815/* parse the "force-sslv3" bind keyword */
3816static int bind_parse_force_sslv3(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
3817{
3818 conf->ssl_options |= BC_SSL_O_USE_SSLV3;
3819 return 0;
3820}
3821
3822/* parse the "force-tlsv10" bind keyword */
3823static int bind_parse_force_tlsv10(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
3824{
3825 conf->ssl_options |= BC_SSL_O_USE_TLSV10;
Emeric Brun2d0c4822012-10-02 13:45:20 +02003826 return 0;
3827}
3828
Emeric Brun2cb7ae52012-10-05 14:14:21 +02003829/* parse the "force-tlsv11" bind keyword */
3830static int bind_parse_force_tlsv11(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
3831{
3832#if SSL_OP_NO_TLSv1_1
3833 conf->ssl_options |= BC_SSL_O_USE_TLSV11;
3834 return 0;
3835#else
3836 if (err)
3837 memprintf(err, "'%s' : library does not support protocol TLSv1.1", args[cur_arg]);
3838 return ERR_ALERT | ERR_FATAL;
3839#endif
3840}
3841
3842/* parse the "force-tlsv12" bind keyword */
3843static int bind_parse_force_tlsv12(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
3844{
3845#if SSL_OP_NO_TLSv1_2
3846 conf->ssl_options |= BC_SSL_O_USE_TLSV12;
3847 return 0;
3848#else
3849 if (err)
3850 memprintf(err, "'%s' : library does not support protocol TLSv1.2", args[cur_arg]);
3851 return ERR_ALERT | ERR_FATAL;
3852#endif
3853}
3854
3855
Emeric Brun2d0c4822012-10-02 13:45:20 +02003856/* parse the "no-tls-tickets" bind keyword */
3857static int bind_parse_no_tls_tickets(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
3858{
Emeric Brun89675492012-10-05 13:48:26 +02003859 conf->ssl_options |= BC_SSL_O_NO_TLS_TICKETS;
Emeric Brun81c00f02012-09-21 14:31:21 +02003860 return 0;
3861}
3862
Emeric Brun2d0c4822012-10-02 13:45:20 +02003863
Emeric Brun9b3009b2012-10-05 11:55:06 +02003864/* parse the "no-sslv3" bind keyword */
3865static 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 +02003866{
Emeric Brun89675492012-10-05 13:48:26 +02003867 conf->ssl_options |= BC_SSL_O_NO_SSLV3;
Willy Tarreau79eeafa2012-09-14 07:53:05 +02003868 return 0;
3869}
3870
Emeric Brun9b3009b2012-10-05 11:55:06 +02003871/* parse the "no-tlsv10" bind keyword */
3872static 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 +02003873{
Emeric Brun89675492012-10-05 13:48:26 +02003874 conf->ssl_options |= BC_SSL_O_NO_TLSV10;
Emeric Brunc0ff4922012-09-28 19:37:02 +02003875 return 0;
3876}
3877
Emeric Brun9b3009b2012-10-05 11:55:06 +02003878/* parse the "no-tlsv11" bind keyword */
3879static 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 +02003880{
Emeric Brun89675492012-10-05 13:48:26 +02003881 conf->ssl_options |= BC_SSL_O_NO_TLSV11;
Emeric Brunc0ff4922012-09-28 19:37:02 +02003882 return 0;
3883}
3884
Emeric Brun9b3009b2012-10-05 11:55:06 +02003885/* parse the "no-tlsv12" bind keyword */
3886static 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 +02003887{
Emeric Brun89675492012-10-05 13:48:26 +02003888 conf->ssl_options |= BC_SSL_O_NO_TLSV12;
Willy Tarreau79eeafa2012-09-14 07:53:05 +02003889 return 0;
3890}
3891
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02003892/* parse the "npn" bind keyword */
3893static int bind_parse_npn(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
3894{
3895#ifdef OPENSSL_NPN_NEGOTIATED
3896 char *p1, *p2;
3897
3898 if (!*args[cur_arg + 1]) {
3899 memprintf(err, "'%s' : missing the comma-delimited NPN protocol suite", args[cur_arg]);
3900 return ERR_ALERT | ERR_FATAL;
3901 }
3902
3903 free(conf->npn_str);
3904
3905 /* the NPN string is built as a suite of (<len> <name>)* */
3906 conf->npn_len = strlen(args[cur_arg + 1]) + 1;
3907 conf->npn_str = calloc(1, conf->npn_len);
3908 memcpy(conf->npn_str + 1, args[cur_arg + 1], conf->npn_len);
3909
3910 /* replace commas with the name length */
3911 p1 = conf->npn_str;
3912 p2 = p1 + 1;
3913 while (1) {
3914 p2 = memchr(p1 + 1, ',', conf->npn_str + conf->npn_len - (p1 + 1));
3915 if (!p2)
3916 p2 = p1 + 1 + strlen(p1 + 1);
3917
3918 if (p2 - (p1 + 1) > 255) {
3919 *p2 = '\0';
3920 memprintf(err, "'%s' : NPN protocol name too long : '%s'", args[cur_arg], p1 + 1);
3921 return ERR_ALERT | ERR_FATAL;
3922 }
3923
3924 *p1 = p2 - (p1 + 1);
3925 p1 = p2;
3926
3927 if (!*p2)
3928 break;
3929
3930 *(p2++) = '\0';
3931 }
3932 return 0;
3933#else
3934 if (err)
3935 memprintf(err, "'%s' : library does not support TLS NPN extension", args[cur_arg]);
3936 return ERR_ALERT | ERR_FATAL;
3937#endif
3938}
3939
Willy Tarreauab861d32013-04-02 02:30:41 +02003940/* parse the "alpn" bind keyword */
3941static int bind_parse_alpn(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
3942{
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01003943#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Willy Tarreauab861d32013-04-02 02:30:41 +02003944 char *p1, *p2;
3945
3946 if (!*args[cur_arg + 1]) {
3947 memprintf(err, "'%s' : missing the comma-delimited ALPN protocol suite", args[cur_arg]);
3948 return ERR_ALERT | ERR_FATAL;
3949 }
3950
3951 free(conf->alpn_str);
3952
3953 /* the ALPN string is built as a suite of (<len> <name>)* */
3954 conf->alpn_len = strlen(args[cur_arg + 1]) + 1;
3955 conf->alpn_str = calloc(1, conf->alpn_len);
3956 memcpy(conf->alpn_str + 1, args[cur_arg + 1], conf->alpn_len);
3957
3958 /* replace commas with the name length */
3959 p1 = conf->alpn_str;
3960 p2 = p1 + 1;
3961 while (1) {
3962 p2 = memchr(p1 + 1, ',', conf->alpn_str + conf->alpn_len - (p1 + 1));
3963 if (!p2)
3964 p2 = p1 + 1 + strlen(p1 + 1);
3965
3966 if (p2 - (p1 + 1) > 255) {
3967 *p2 = '\0';
3968 memprintf(err, "'%s' : ALPN protocol name too long : '%s'", args[cur_arg], p1 + 1);
3969 return ERR_ALERT | ERR_FATAL;
3970 }
3971
3972 *p1 = p2 - (p1 + 1);
3973 p1 = p2;
3974
3975 if (!*p2)
3976 break;
3977
3978 *(p2++) = '\0';
3979 }
3980 return 0;
3981#else
3982 if (err)
3983 memprintf(err, "'%s' : library does not support TLS ALPN extension", args[cur_arg]);
3984 return ERR_ALERT | ERR_FATAL;
3985#endif
3986}
3987
Willy Tarreau79eeafa2012-09-14 07:53:05 +02003988/* parse the "ssl" bind keyword */
Willy Tarreau4348fad2012-09-20 16:48:07 +02003989static 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 +02003990{
Willy Tarreau81796be2012-09-22 19:11:47 +02003991 struct listener *l;
3992
Willy Tarreau4348fad2012-09-20 16:48:07 +02003993 conf->is_ssl = 1;
Emeric Brun76d88952012-10-05 15:47:31 +02003994
3995 if (global.listen_default_ciphers && !conf->ciphers)
3996 conf->ciphers = strdup(global.listen_default_ciphers);
3997
Willy Tarreau81796be2012-09-22 19:11:47 +02003998 list_for_each_entry(l, &conf->listeners, by_bind)
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02003999 l->xprt = &ssl_sock;
Willy Tarreau81796be2012-09-22 19:11:47 +02004000
Willy Tarreau79eeafa2012-09-14 07:53:05 +02004001 return 0;
4002}
4003
Emmanuel Hocdet65623372013-01-24 17:17:15 +01004004/* parse the "strict-sni" bind keyword */
4005static int bind_parse_strict_sni(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
4006{
4007 conf->strict_sni = 1;
4008 return 0;
4009}
4010
Emeric Brund94b3fe2012-09-20 18:23:56 +02004011/* parse the "verify" bind keyword */
4012static int bind_parse_verify(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
4013{
4014 if (!*args[cur_arg + 1]) {
4015 if (err)
4016 memprintf(err, "'%s' : missing verify method", args[cur_arg]);
4017 return ERR_ALERT | ERR_FATAL;
4018 }
4019
4020 if (strcmp(args[cur_arg + 1], "none") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01004021 conf->verify = SSL_SOCK_VERIFY_NONE;
Emeric Brund94b3fe2012-09-20 18:23:56 +02004022 else if (strcmp(args[cur_arg + 1], "optional") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01004023 conf->verify = SSL_SOCK_VERIFY_OPTIONAL;
Emeric Brund94b3fe2012-09-20 18:23:56 +02004024 else if (strcmp(args[cur_arg + 1], "required") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01004025 conf->verify = SSL_SOCK_VERIFY_REQUIRED;
Emeric Brund94b3fe2012-09-20 18:23:56 +02004026 else {
4027 if (err)
4028 memprintf(err, "'%s' : unknown verify method '%s', only 'none', 'optional', and 'required' are supported\n",
4029 args[cur_arg], args[cur_arg + 1]);
4030 return ERR_ALERT | ERR_FATAL;
4031 }
4032
4033 return 0;
4034}
4035
Willy Tarreau92faadf2012-10-10 23:04:25 +02004036/************** "server" keywords ****************/
4037
Emeric Brunef42d922012-10-11 16:11:36 +02004038/* parse the "ca-file" server keyword */
4039static int srv_parse_ca_file(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4040{
4041 if (!*args[*cur_arg + 1]) {
4042 if (err)
4043 memprintf(err, "'%s' : missing CAfile path", args[*cur_arg]);
4044 return ERR_ALERT | ERR_FATAL;
4045 }
4046
4047 if ((*args[*cur_arg + 1] != '/') && global.ca_base)
4048 memprintf(&newsrv->ssl_ctx.ca_file, "%s/%s", global.ca_base, args[*cur_arg + 1]);
4049 else
4050 memprintf(&newsrv->ssl_ctx.ca_file, "%s", args[*cur_arg + 1]);
4051
4052 return 0;
4053}
4054
Willy Tarreau92faadf2012-10-10 23:04:25 +02004055/* parse the "check-ssl" server keyword */
4056static int srv_parse_check_ssl(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4057{
4058 newsrv->check.use_ssl = 1;
4059 if (global.connect_default_ciphers && !newsrv->ssl_ctx.ciphers)
4060 newsrv->ssl_ctx.ciphers = strdup(global.connect_default_ciphers);
4061 return 0;
4062}
4063
4064/* parse the "ciphers" server keyword */
4065static int srv_parse_ciphers(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4066{
4067 if (!*args[*cur_arg + 1]) {
4068 memprintf(err, "'%s' : missing cipher suite", args[*cur_arg]);
4069 return ERR_ALERT | ERR_FATAL;
4070 }
4071
4072 free(newsrv->ssl_ctx.ciphers);
4073 newsrv->ssl_ctx.ciphers = strdup(args[*cur_arg + 1]);
4074 return 0;
4075}
4076
Emeric Brunef42d922012-10-11 16:11:36 +02004077/* parse the "crl-file" server keyword */
4078static int srv_parse_crl_file(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4079{
4080#ifndef X509_V_FLAG_CRL_CHECK
4081 if (err)
4082 memprintf(err, "'%s' : library does not support CRL verify", args[*cur_arg]);
4083 return ERR_ALERT | ERR_FATAL;
4084#else
4085 if (!*args[*cur_arg + 1]) {
4086 if (err)
4087 memprintf(err, "'%s' : missing CRLfile path", args[*cur_arg]);
4088 return ERR_ALERT | ERR_FATAL;
4089 }
4090
4091 if ((*args[*cur_arg + 1] != '/') && global.ca_base)
4092 memprintf(&newsrv->ssl_ctx.crl_file, "%s/%s", global.ca_base, args[*cur_arg + 1]);
4093 else
4094 memprintf(&newsrv->ssl_ctx.crl_file, "%s", args[*cur_arg + 1]);
4095
4096 return 0;
4097#endif
4098}
4099
Emeric Bruna7aa3092012-10-26 12:58:00 +02004100/* parse the "crt" server keyword */
4101static int srv_parse_crt(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4102{
4103 if (!*args[*cur_arg + 1]) {
4104 if (err)
4105 memprintf(err, "'%s' : missing certificate file path", args[*cur_arg]);
4106 return ERR_ALERT | ERR_FATAL;
4107 }
4108
4109 if ((*args[*cur_arg + 1] != '/') && global.crt_base)
4110 memprintf(&newsrv->ssl_ctx.client_crt, "%s/%s", global.ca_base, args[*cur_arg + 1]);
4111 else
4112 memprintf(&newsrv->ssl_ctx.client_crt, "%s", args[*cur_arg + 1]);
4113
4114 return 0;
4115}
Emeric Brunef42d922012-10-11 16:11:36 +02004116
Willy Tarreau92faadf2012-10-10 23:04:25 +02004117/* parse the "force-sslv3" server keyword */
4118static int srv_parse_force_sslv3(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4119{
4120 newsrv->ssl_ctx.options |= SRV_SSL_O_USE_SSLV3;
4121 return 0;
4122}
4123
4124/* parse the "force-tlsv10" server keyword */
4125static int srv_parse_force_tlsv10(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4126{
4127 newsrv->ssl_ctx.options |= SRV_SSL_O_USE_TLSV10;
4128 return 0;
4129}
4130
4131/* parse the "force-tlsv11" server keyword */
4132static int srv_parse_force_tlsv11(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4133{
4134#if SSL_OP_NO_TLSv1_1
4135 newsrv->ssl_ctx.options |= SRV_SSL_O_USE_TLSV11;
4136 return 0;
4137#else
4138 if (err)
4139 memprintf(err, "'%s' : library does not support protocol TLSv1.1", args[*cur_arg]);
4140 return ERR_ALERT | ERR_FATAL;
4141#endif
4142}
4143
4144/* parse the "force-tlsv12" server keyword */
4145static int srv_parse_force_tlsv12(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4146{
4147#if SSL_OP_NO_TLSv1_2
4148 newsrv->ssl_ctx.options |= SRV_SSL_O_USE_TLSV12;
4149 return 0;
4150#else
4151 if (err)
4152 memprintf(err, "'%s' : library does not support protocol TLSv1.2", args[*cur_arg]);
4153 return ERR_ALERT | ERR_FATAL;
4154#endif
4155}
4156
4157/* parse the "no-sslv3" server keyword */
4158static int srv_parse_no_sslv3(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4159{
4160 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_SSLV3;
4161 return 0;
4162}
4163
4164/* parse the "no-tlsv10" server keyword */
4165static int srv_parse_no_tlsv10(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4166{
4167 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_TLSV10;
4168 return 0;
4169}
4170
4171/* parse the "no-tlsv11" server keyword */
4172static int srv_parse_no_tlsv11(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4173{
4174 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_TLSV11;
4175 return 0;
4176}
4177
4178/* parse the "no-tlsv12" server keyword */
4179static int srv_parse_no_tlsv12(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4180{
4181 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_TLSV12;
4182 return 0;
4183}
4184
Emeric Brunf9c5c472012-10-11 15:28:34 +02004185/* parse the "no-tls-tickets" server keyword */
4186static int srv_parse_no_tls_tickets(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4187{
4188 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_TLS_TICKETS;
4189 return 0;
4190}
David Safb76832014-05-08 23:42:08 -04004191/* parse the "send-proxy-v2-ssl" server keyword */
4192static int srv_parse_send_proxy_ssl(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4193{
4194 newsrv->pp_opts |= SRV_PP_V2;
4195 newsrv->pp_opts |= SRV_PP_V2_SSL;
4196 return 0;
4197}
4198
4199/* parse the "send-proxy-v2-ssl-cn" server keyword */
4200static int srv_parse_send_proxy_cn(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4201{
4202 newsrv->pp_opts |= SRV_PP_V2;
4203 newsrv->pp_opts |= SRV_PP_V2_SSL;
4204 newsrv->pp_opts |= SRV_PP_V2_SSL_CN;
4205 return 0;
4206}
Emeric Brunf9c5c472012-10-11 15:28:34 +02004207
Willy Tarreau92faadf2012-10-10 23:04:25 +02004208/* parse the "ssl" server keyword */
4209static int srv_parse_ssl(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4210{
4211 newsrv->use_ssl = 1;
4212 if (global.connect_default_ciphers && !newsrv->ssl_ctx.ciphers)
4213 newsrv->ssl_ctx.ciphers = strdup(global.connect_default_ciphers);
4214 return 0;
4215}
4216
Emeric Brunef42d922012-10-11 16:11:36 +02004217/* parse the "verify" server keyword */
4218static int srv_parse_verify(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4219{
4220 if (!*args[*cur_arg + 1]) {
4221 if (err)
4222 memprintf(err, "'%s' : missing verify method", args[*cur_arg]);
4223 return ERR_ALERT | ERR_FATAL;
4224 }
4225
4226 if (strcmp(args[*cur_arg + 1], "none") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01004227 newsrv->ssl_ctx.verify = SSL_SOCK_VERIFY_NONE;
Emeric Brunef42d922012-10-11 16:11:36 +02004228 else if (strcmp(args[*cur_arg + 1], "required") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01004229 newsrv->ssl_ctx.verify = SSL_SOCK_VERIFY_REQUIRED;
Emeric Brunef42d922012-10-11 16:11:36 +02004230 else {
4231 if (err)
4232 memprintf(err, "'%s' : unknown verify method '%s', only 'none' and 'required' are supported\n",
4233 args[*cur_arg], args[*cur_arg + 1]);
4234 return ERR_ALERT | ERR_FATAL;
4235 }
4236
Evan Broderbe554312013-06-27 00:05:25 -07004237 return 0;
4238}
4239
4240/* parse the "verifyhost" server keyword */
4241static int srv_parse_verifyhost(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4242{
4243 if (!*args[*cur_arg + 1]) {
4244 if (err)
4245 memprintf(err, "'%s' : missing hostname to verify against", args[*cur_arg]);
4246 return ERR_ALERT | ERR_FATAL;
4247 }
4248
4249 newsrv->ssl_ctx.verify_host = strdup(args[*cur_arg + 1]);
4250
Emeric Brunef42d922012-10-11 16:11:36 +02004251 return 0;
4252}
4253
Willy Tarreau7875d092012-09-10 08:20:03 +02004254/* Note: must not be declared <const> as its list will be overwritten.
4255 * Please take care of keeping this list alphabetically sorted.
4256 */
Willy Tarreaudc13c112013-06-21 23:16:39 +02004257static struct sample_fetch_kw_list sample_fetch_keywords = {ILH, {
Emeric Brun645ae792014-04-30 14:21:06 +02004258 { "ssl_bc", smp_fetch_ssl_fc, 0, NULL, SMP_T_BOOL, SMP_USE_L5SRV },
4259 { "ssl_bc_alg_keysize", smp_fetch_ssl_fc_alg_keysize, 0, NULL, SMP_T_UINT, SMP_USE_L5SRV },
4260 { "ssl_bc_cipher", smp_fetch_ssl_fc_cipher, 0, NULL, SMP_T_STR, SMP_USE_L5SRV },
4261 { "ssl_bc_protocol", smp_fetch_ssl_fc_protocol, 0, NULL, SMP_T_STR, SMP_USE_L5SRV },
Emeric Brunb73a9b02014-04-30 18:49:19 +02004262 { "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 +02004263 { "ssl_bc_use_keysize", smp_fetch_ssl_fc_use_keysize, 0, NULL, SMP_T_UINT, SMP_USE_L5SRV },
4264 { "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 +01004265 { "ssl_c_ca_err", smp_fetch_ssl_c_ca_err, 0, NULL, SMP_T_UINT, SMP_USE_L5CLI },
4266 { "ssl_c_ca_err_depth", smp_fetch_ssl_c_ca_err_depth, 0, NULL, SMP_T_UINT, SMP_USE_L5CLI },
4267 { "ssl_c_err", smp_fetch_ssl_c_err, 0, NULL, SMP_T_UINT, SMP_USE_L5CLI },
Emeric Brunba841a12014-04-30 17:05:08 +02004268 { "ssl_c_i_dn", smp_fetch_ssl_x_i_dn, ARG2(0,STR,SINT), NULL, SMP_T_STR, SMP_USE_L5CLI },
4269 { "ssl_c_key_alg", smp_fetch_ssl_x_key_alg, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
4270 { "ssl_c_notafter", smp_fetch_ssl_x_notafter, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
4271 { "ssl_c_notbefore", smp_fetch_ssl_x_notbefore, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
4272 { "ssl_c_sig_alg", smp_fetch_ssl_x_sig_alg, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
4273 { "ssl_c_s_dn", smp_fetch_ssl_x_s_dn, ARG2(0,STR,SINT), NULL, SMP_T_STR, SMP_USE_L5CLI },
4274 { "ssl_c_serial", smp_fetch_ssl_x_serial, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
4275 { "ssl_c_sha1", smp_fetch_ssl_x_sha1, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Willy Tarreau80aca902013-01-07 15:42:20 +01004276 { "ssl_c_used", smp_fetch_ssl_c_used, 0, NULL, SMP_T_BOOL, SMP_USE_L5CLI },
4277 { "ssl_c_verify", smp_fetch_ssl_c_verify, 0, NULL, SMP_T_UINT, SMP_USE_L5CLI },
Emeric Brunba841a12014-04-30 17:05:08 +02004278 { "ssl_c_version", smp_fetch_ssl_x_version, 0, NULL, SMP_T_UINT, SMP_USE_L5CLI },
4279 { "ssl_f_i_dn", smp_fetch_ssl_x_i_dn, ARG2(0,STR,SINT), NULL, SMP_T_STR, SMP_USE_L5CLI },
4280 { "ssl_f_key_alg", smp_fetch_ssl_x_key_alg, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
4281 { "ssl_f_notafter", smp_fetch_ssl_x_notafter, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
4282 { "ssl_f_notbefore", smp_fetch_ssl_x_notbefore, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
4283 { "ssl_f_sig_alg", smp_fetch_ssl_x_sig_alg, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
4284 { "ssl_f_s_dn", smp_fetch_ssl_x_s_dn, ARG2(0,STR,SINT), NULL, SMP_T_STR, SMP_USE_L5CLI },
4285 { "ssl_f_serial", smp_fetch_ssl_x_serial, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Emeric Brun55f4fa82014-04-30 17:11:25 +02004286 { "ssl_f_sha1", smp_fetch_ssl_x_sha1, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Emeric Brunba841a12014-04-30 17:05:08 +02004287 { "ssl_f_version", smp_fetch_ssl_x_version, 0, NULL, SMP_T_UINT, SMP_USE_L5CLI },
Willy Tarreau80aca902013-01-07 15:42:20 +01004288 { "ssl_fc", smp_fetch_ssl_fc, 0, NULL, SMP_T_BOOL, SMP_USE_L5CLI },
4289 { "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 +01004290 { "ssl_fc_cipher", smp_fetch_ssl_fc_cipher, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Willy Tarreau80aca902013-01-07 15:42:20 +01004291 { "ssl_fc_has_crt", smp_fetch_ssl_fc_has_crt, 0, NULL, SMP_T_BOOL, SMP_USE_L5CLI },
4292 { "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 +02004293#ifdef OPENSSL_NPN_NEGOTIATED
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01004294 { "ssl_fc_npn", smp_fetch_ssl_fc_npn, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Willy Tarreaua33c6542012-10-15 13:19:06 +02004295#endif
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01004296#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01004297 { "ssl_fc_alpn", smp_fetch_ssl_fc_alpn, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Willy Tarreauab861d32013-04-02 02:30:41 +02004298#endif
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01004299 { "ssl_fc_protocol", smp_fetch_ssl_fc_protocol, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Emeric Brunb73a9b02014-04-30 18:49:19 +02004300 { "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 +01004301 { "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 +01004302 { "ssl_fc_session_id", smp_fetch_ssl_fc_session_id, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
4303 { "ssl_fc_sni", smp_fetch_ssl_fc_sni, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Willy Tarreau7875d092012-09-10 08:20:03 +02004304 { NULL, NULL, 0, 0, 0 },
4305}};
4306
4307/* Note: must not be declared <const> as its list will be overwritten.
4308 * Please take care of keeping this list alphabetically sorted.
4309 */
Willy Tarreaudc13c112013-06-21 23:16:39 +02004310static struct acl_kw_list acl_kws = {ILH, {
Thierry FOURNIERc5a4e982014-03-05 16:07:08 +01004311 { "ssl_fc_sni_end", "ssl_fc_sni", PAT_MATCH_END },
4312 { "ssl_fc_sni_reg", "ssl_fc_sni", PAT_MATCH_REG },
Willy Tarreau8ed669b2013-01-11 15:49:37 +01004313 { /* END */ },
Willy Tarreau7875d092012-09-10 08:20:03 +02004314}};
4315
Willy Tarreau79eeafa2012-09-14 07:53:05 +02004316/* Note: must not be declared <const> as its list will be overwritten.
4317 * Please take care of keeping this list alphabetically sorted, doing so helps
4318 * all code contributors.
4319 * Optional keywords are also declared with a NULL ->parse() function so that
4320 * the config parser can report an appropriate error when a known keyword was
4321 * not enabled.
4322 */
Willy Tarreau51fb7652012-09-18 18:24:39 +02004323static struct bind_kw_list bind_kws = { "SSL", { }, {
Willy Tarreauab861d32013-04-02 02:30:41 +02004324 { "alpn", bind_parse_alpn, 1 }, /* set ALPN supported protocols */
Emeric Brunfb510ea2012-10-05 12:00:26 +02004325 { "ca-file", bind_parse_ca_file, 1 }, /* set CAfile to process verify on client cert */
Emeric Brun2d0c4822012-10-02 13:45:20 +02004326 { "ca-ignore-err", bind_parse_ignore_err, 1 }, /* set error IDs to ignore on verify depth > 0 */
4327 { "ciphers", bind_parse_ciphers, 1 }, /* set SSL cipher suite */
Emeric Brunfb510ea2012-10-05 12:00:26 +02004328 { "crl-file", bind_parse_crl_file, 1 }, /* set certificat revocation list file use on client cert verify */
Emeric Brun2d0c4822012-10-02 13:45:20 +02004329 { "crt", bind_parse_crt, 1 }, /* load SSL certificates from this location */
4330 { "crt-ignore-err", bind_parse_ignore_err, 1 }, /* set error IDs to ingore on verify depth == 0 */
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01004331 { "crt-list", bind_parse_crt_list, 1 }, /* load a list of crt from this location */
Emeric Brun2d0c4822012-10-02 13:45:20 +02004332 { "ecdhe", bind_parse_ecdhe, 1 }, /* defines named curve for elliptic curve Diffie-Hellman */
Emeric Brun2cb7ae52012-10-05 14:14:21 +02004333 { "force-sslv3", bind_parse_force_sslv3, 0 }, /* force SSLv3 */
4334 { "force-tlsv10", bind_parse_force_tlsv10, 0 }, /* force TLSv10 */
4335 { "force-tlsv11", bind_parse_force_tlsv11, 0 }, /* force TLSv11 */
4336 { "force-tlsv12", bind_parse_force_tlsv12, 0 }, /* force TLSv12 */
Emeric Brun9b3009b2012-10-05 11:55:06 +02004337 { "no-sslv3", bind_parse_no_sslv3, 0 }, /* disable SSLv3 */
4338 { "no-tlsv10", bind_parse_no_tlsv10, 0 }, /* disable TLSv10 */
4339 { "no-tlsv11", bind_parse_no_tlsv11, 0 }, /* disable TLSv11 */
4340 { "no-tlsv12", bind_parse_no_tlsv12, 0 }, /* disable TLSv12 */
Emeric Brun2d0c4822012-10-02 13:45:20 +02004341 { "no-tls-tickets", bind_parse_no_tls_tickets, 0 }, /* disable session resumption tickets */
Emeric Brun2d0c4822012-10-02 13:45:20 +02004342 { "ssl", bind_parse_ssl, 0 }, /* enable SSL processing */
Emmanuel Hocdet65623372013-01-24 17:17:15 +01004343 { "strict-sni", bind_parse_strict_sni, 0 }, /* refuse negotiation if sni doesn't match a certificate */
Emeric Brun2d0c4822012-10-02 13:45:20 +02004344 { "verify", bind_parse_verify, 1 }, /* set SSL verify method */
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02004345 { "npn", bind_parse_npn, 1 }, /* set NPN supported protocols */
Willy Tarreau79eeafa2012-09-14 07:53:05 +02004346 { NULL, NULL, 0 },
4347}};
Emeric Brun46591952012-05-18 15:47:34 +02004348
Willy Tarreau92faadf2012-10-10 23:04:25 +02004349/* Note: must not be declared <const> as its list will be overwritten.
4350 * Please take care of keeping this list alphabetically sorted, doing so helps
4351 * all code contributors.
4352 * Optional keywords are also declared with a NULL ->parse() function so that
4353 * the config parser can report an appropriate error when a known keyword was
4354 * not enabled.
4355 */
4356static struct srv_kw_list srv_kws = { "SSL", { }, {
Emeric Brunef42d922012-10-11 16:11:36 +02004357 { "ca-file", srv_parse_ca_file, 1, 0 }, /* set CAfile to process verify server cert */
Emeric Brunecc91fe2012-10-11 15:05:10 +02004358 { "check-ssl", srv_parse_check_ssl, 0, 0 }, /* enable SSL for health checks */
4359 { "ciphers", srv_parse_ciphers, 1, 0 }, /* select the cipher suite */
Emeric Brunef42d922012-10-11 16:11:36 +02004360 { "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 +02004361 { "crt", srv_parse_crt, 1, 0 }, /* set client certificate */
Emeric Brunecc91fe2012-10-11 15:05:10 +02004362 { "force-sslv3", srv_parse_force_sslv3, 0, 0 }, /* force SSLv3 */
4363 { "force-tlsv10", srv_parse_force_tlsv10, 0, 0 }, /* force TLSv10 */
4364 { "force-tlsv11", srv_parse_force_tlsv11, 0, 0 }, /* force TLSv11 */
4365 { "force-tlsv12", srv_parse_force_tlsv12, 0, 0 }, /* force TLSv12 */
4366 { "no-sslv3", srv_parse_no_sslv3, 0, 0 }, /* disable SSLv3 */
4367 { "no-tlsv10", srv_parse_no_tlsv10, 0, 0 }, /* disable TLSv10 */
4368 { "no-tlsv11", srv_parse_no_tlsv11, 0, 0 }, /* disable TLSv11 */
4369 { "no-tlsv12", srv_parse_no_tlsv12, 0, 0 }, /* disable TLSv12 */
Emeric Brunf9c5c472012-10-11 15:28:34 +02004370 { "no-tls-tickets", srv_parse_no_tls_tickets, 0, 0 }, /* disable session resumption tickets */
David Safb76832014-05-08 23:42:08 -04004371 { "send-proxy-v2-ssl", srv_parse_send_proxy_ssl, 0, 0 }, /* send PROXY protocol header v2 with SSL info */
4372 { "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 +02004373 { "ssl", srv_parse_ssl, 0, 0 }, /* enable SSL processing */
Emeric Brunef42d922012-10-11 16:11:36 +02004374 { "verify", srv_parse_verify, 1, 0 }, /* set SSL verify method */
Evan Broderbe554312013-06-27 00:05:25 -07004375 { "verifyhost", srv_parse_verifyhost, 1, 0 }, /* require that SSL cert verifies for hostname */
Willy Tarreau92faadf2012-10-10 23:04:25 +02004376 { NULL, NULL, 0, 0 },
4377}};
4378
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02004379/* transport-layer operations for SSL sockets */
4380struct xprt_ops ssl_sock = {
Emeric Brun46591952012-05-18 15:47:34 +02004381 .snd_buf = ssl_sock_from_buf,
4382 .rcv_buf = ssl_sock_to_buf,
4383 .rcv_pipe = NULL,
4384 .snd_pipe = NULL,
4385 .shutr = NULL,
4386 .shutw = ssl_sock_shutw,
4387 .close = ssl_sock_close,
4388 .init = ssl_sock_init,
4389};
4390
4391__attribute__((constructor))
Willy Tarreau92faadf2012-10-10 23:04:25 +02004392static void __ssl_sock_init(void)
4393{
Emeric Brun46591952012-05-18 15:47:34 +02004394 STACK_OF(SSL_COMP)* cm;
4395
Willy Tarreau610f04b2014-02-13 11:36:41 +01004396#ifdef LISTEN_DEFAULT_CIPHERS
4397 global.listen_default_ciphers = LISTEN_DEFAULT_CIPHERS;
4398#endif
4399#ifdef CONNECT_DEFAULT_CIPHERS
4400 global.connect_default_ciphers = CONNECT_DEFAULT_CIPHERS;
4401#endif
4402 if (global.listen_default_ciphers)
4403 global.listen_default_ciphers = strdup(global.listen_default_ciphers);
4404 if (global.connect_default_ciphers)
4405 global.connect_default_ciphers = strdup(global.connect_default_ciphers);
4406
Emeric Brun46591952012-05-18 15:47:34 +02004407 SSL_library_init();
4408 cm = SSL_COMP_get_compression_methods();
4409 sk_SSL_COMP_zero(cm);
Willy Tarreau7875d092012-09-10 08:20:03 +02004410 sample_register_fetches(&sample_fetch_keywords);
4411 acl_register_keywords(&acl_kws);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02004412 bind_register_keywords(&bind_kws);
Willy Tarreau92faadf2012-10-10 23:04:25 +02004413 srv_register_keywords(&srv_kws);
Emeric Brun46591952012-05-18 15:47:34 +02004414}
4415
4416/*
4417 * Local variables:
4418 * c-indent-level: 8
4419 * c-basic-offset: 8
4420 * End:
4421 */