blob: 69f754c808471d03bd7c6efb2a7cd4cdd4c0cc4a [file] [log] [blame]
Emeric Brun46591952012-05-18 15:47:34 +02001/*
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02002 * SSL/TLS transport layer over SOCK_STREAM sockets
Emeric Brun46591952012-05-18 15:47:34 +02003 *
4 * Copyright (C) 2012 EXCELIANCE, Emeric Brun <ebrun@exceliance.fr>
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version
9 * 2 of the License, or (at your option) any later version.
10 *
Willy Tarreau69845df2012-09-10 09:43:09 +020011 * Acknowledgement:
12 * We'd like to specially thank the Stud project authors for a very clean
13 * and well documented code which helped us understand how the OpenSSL API
14 * ought to be used in non-blocking mode. This is one difficult part which
15 * is not easy to get from the OpenSSL doc, and reading the Stud code made
16 * it much more obvious than the examples in the OpenSSL package. Keep up
17 * the good works, guys !
18 *
19 * Stud is an extremely efficient and scalable SSL/TLS proxy which combines
20 * particularly well with haproxy. For more info about this project, visit :
21 * https://github.com/bumptech/stud
22 *
Emeric Brun46591952012-05-18 15:47:34 +020023 */
24
25#define _GNU_SOURCE
Emeric Brunfc0421f2012-09-07 17:30:07 +020026#include <ctype.h>
27#include <dirent.h>
Emeric Brun46591952012-05-18 15:47:34 +020028#include <errno.h>
29#include <fcntl.h>
30#include <stdio.h>
31#include <stdlib.h>
Emeric Brunfc0421f2012-09-07 17:30:07 +020032#include <string.h>
33#include <unistd.h>
Emeric Brun46591952012-05-18 15:47:34 +020034
35#include <sys/socket.h>
36#include <sys/stat.h>
37#include <sys/types.h>
38
39#include <netinet/tcp.h>
40
41#include <openssl/ssl.h>
Emeric Brunfc0421f2012-09-07 17:30:07 +020042#include <openssl/x509.h>
43#include <openssl/x509v3.h>
44#include <openssl/x509.h>
45#include <openssl/err.h>
Thierry Fournier383085f2013-01-24 14:15:43 +010046#include <openssl/rand.h>
Lukas Tribuse4e30f72014-12-09 16:32:51 +010047#if (defined SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB && !defined OPENSSL_NO_OCSP)
Emeric Brun4147b2e2014-06-16 18:36:30 +020048#include <openssl/ocsp.h>
49#endif
Emeric Brun46591952012-05-18 15:47:34 +020050
51#include <common/buffer.h>
52#include <common/compat.h>
53#include <common/config.h>
54#include <common/debug.h>
Willy Tarreau79eeafa2012-09-14 07:53:05 +020055#include <common/errors.h>
Emeric Brun46591952012-05-18 15:47:34 +020056#include <common/standard.h>
57#include <common/ticks.h>
58#include <common/time.h>
Emeric Brun2c86cbf2014-10-30 15:56:50 +010059#include <common/cfgparse.h>
Nenad Merdanovic05552d42015-02-27 19:56:49 +010060#include <common/base64.h>
Emeric Brun46591952012-05-18 15:47:34 +020061
Emeric Brunfc0421f2012-09-07 17:30:07 +020062#include <ebsttree.h>
63
64#include <types/global.h>
65#include <types/ssl_sock.h>
66
Willy Tarreau7875d092012-09-10 08:20:03 +020067#include <proto/acl.h>
68#include <proto/arg.h>
Emeric Brun46591952012-05-18 15:47:34 +020069#include <proto/connection.h>
70#include <proto/fd.h>
71#include <proto/freq_ctr.h>
72#include <proto/frontend.h>
Willy Tarreau79eeafa2012-09-14 07:53:05 +020073#include <proto/listener.h>
Thierry FOURNIERed66c292013-11-28 11:05:19 +010074#include <proto/pattern.h>
Willy Tarreau92faadf2012-10-10 23:04:25 +020075#include <proto/server.h>
Emeric Brun46591952012-05-18 15:47:34 +020076#include <proto/log.h>
Emeric Brun94324a42012-10-11 14:00:19 +020077#include <proto/proxy.h>
Emeric Brunfc0421f2012-09-07 17:30:07 +020078#include <proto/shctx.h>
Emeric Brun46591952012-05-18 15:47:34 +020079#include <proto/ssl_sock.h>
80#include <proto/task.h>
81
Willy Tarreau518cedd2014-02-17 15:43:01 +010082/* Warning, these are bits, not integers! */
Emeric Brune64aef12012-09-21 13:15:06 +020083#define SSL_SOCK_ST_FL_VERIFY_DONE 0x00000001
Emeric Brund8b2bb52014-01-28 15:43:53 +010084#define SSL_SOCK_ST_FL_16K_WBFSIZE 0x00000002
Willy Tarreau518cedd2014-02-17 15:43:01 +010085#define SSL_SOCK_SEND_UNLIMITED 0x00000004
Emeric Brun29f037d2014-04-25 19:05:36 +020086#define SSL_SOCK_RECV_HEARTBEAT 0x00000008
87
Emeric Brunf282a812012-09-21 15:27:54 +020088/* bits 0xFFFF0000 are reserved to store verify errors */
89
90/* Verify errors macros */
91#define SSL_SOCK_CA_ERROR_TO_ST(e) (((e > 63) ? 63 : e) << (16))
92#define SSL_SOCK_CAEDEPTH_TO_ST(d) (((d > 15) ? 15 : d) << (6+16))
93#define SSL_SOCK_CRTERROR_TO_ST(e) (((e > 63) ? 63 : e) << (4+6+16))
94
95#define SSL_SOCK_ST_TO_CA_ERROR(s) ((s >> (16)) & 63)
96#define SSL_SOCK_ST_TO_CAEDEPTH(s) ((s >> (6+16)) & 15)
97#define SSL_SOCK_ST_TO_CRTERROR(s) ((s >> (4+6+16)) & 63)
Emeric Brune64aef12012-09-21 13:15:06 +020098
Nenad Merdanovic05552d42015-02-27 19:56:49 +010099/* Supported hash function for TLS tickets */
100#ifdef OPENSSL_NO_SHA256
101#define HASH_FUNCT EVP_sha1
102#else
103#define HASH_FUNCT EVP_sha256
104#endif /* OPENSSL_NO_SHA256 */
105
Emeric Brun850efd52014-01-29 12:24:34 +0100106/* server and bind verify method, it uses a global value as default */
107enum {
108 SSL_SOCK_VERIFY_DEFAULT = 0,
109 SSL_SOCK_VERIFY_REQUIRED = 1,
110 SSL_SOCK_VERIFY_OPTIONAL = 2,
111 SSL_SOCK_VERIFY_NONE = 3,
112};
113
Willy Tarreau71b734c2014-01-28 15:19:44 +0100114int sslconns = 0;
115int totalsslconns = 0;
Emeric Brune1f38db2012-09-03 20:36:47 +0200116
Remi Gacogne8de54152014-07-15 11:36:40 +0200117#ifndef OPENSSL_NO_DH
118static DH *local_dh_1024 = NULL;
119static DH *local_dh_2048 = NULL;
120static DH *local_dh_4096 = NULL;
121static DH *local_dh_8192 = NULL;
122#endif /* OPENSSL_NO_DH */
123
Lukas Tribuse4e30f72014-12-09 16:32:51 +0100124#if (defined SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB && !defined OPENSSL_NO_OCSP)
Emeric Brun4147b2e2014-06-16 18:36:30 +0200125struct certificate_ocsp {
126 struct ebmb_node key;
127 unsigned char key_data[OCSP_MAX_CERTID_ASN1_LENGTH];
128 struct chunk response;
Emeric Brun4f3c87a2014-06-20 15:46:13 +0200129 long expire;
Emeric Brun4147b2e2014-06-16 18:36:30 +0200130};
131
Emeric Brun4f3c87a2014-06-20 15:46:13 +0200132/*
133 * This function returns the number of seconds elapsed
134 * since the Epoch, 1970-01-01 00:00:00 +0000 (UTC) and the
135 * date presented un ASN1_GENERALIZEDTIME.
136 *
137 * In parsing error case, it returns -1.
138 */
139static long asn1_generalizedtime_to_epoch(ASN1_GENERALIZEDTIME *d)
140{
141 long epoch;
142 char *p, *end;
143 const unsigned short month_offset[12] = {
144 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334
145 };
146 int year, month;
147
148 if (!d || (d->type != V_ASN1_GENERALIZEDTIME)) return -1;
149
150 p = (char *)d->data;
151 end = p + d->length;
152
153 if (end - p < 4) return -1;
154 year = 1000 * (p[0] - '0') + 100 * (p[1] - '0') + 10 * (p[2] - '0') + p[3] - '0';
155 p += 4;
156 if (end - p < 2) return -1;
157 month = 10 * (p[0] - '0') + p[1] - '0';
158 if (month < 1 || month > 12) return -1;
159 /* Compute the number of seconds since 1 jan 1970 and the beginning of current month
160 We consider leap years and the current month (<marsh or not) */
161 epoch = ( ((year - 1970) * 365)
162 + ((year - (month < 3)) / 4 - (year - (month < 3)) / 100 + (year - (month < 3)) / 400)
163 - ((1970 - 1) / 4 - (1970 - 1) / 100 + (1970 - 1) / 400)
164 + month_offset[month-1]
165 ) * 24 * 60 * 60;
166 p += 2;
167 if (end - p < 2) return -1;
168 /* Add the number of seconds of completed days of current month */
169 epoch += (10 * (p[0] - '0') + p[1] - '0' - 1) * 24 * 60 * 60;
170 p += 2;
171 if (end - p < 2) return -1;
172 /* Add the completed hours of the current day */
173 epoch += (10 * (p[0] - '0') + p[1] - '0') * 60 * 60;
174 p += 2;
175 if (end - p < 2) return -1;
176 /* Add the completed minutes of the current hour */
177 epoch += (10 * (p[0] - '0') + p[1] - '0') * 60;
178 p += 2;
179 if (p == end) return -1;
180 /* Test if there is available seconds */
181 if (p[0] < '0' || p[0] > '9')
182 goto nosec;
183 if (end - p < 2) return -1;
184 /* Add the seconds of the current minute */
185 epoch += 10 * (p[0] - '0') + p[1] - '0';
186 p += 2;
187 if (p == end) return -1;
188 /* Ignore seconds float part if present */
189 if (p[0] == '.') {
190 do {
191 if (++p == end) return -1;
192 } while (p[0] >= '0' && p[0] <= '9');
193 }
194
195nosec:
196 if (p[0] == 'Z') {
197 if (end - p != 1) return -1;
198 return epoch;
199 }
200 else if (p[0] == '+') {
201 if (end - p != 5) return -1;
202 /* Apply timezone offset */
203 return epoch - ((10 * (p[1] - '0') + p[2] - '0') * 60 + (10 * (p[3] - '0') + p[4] - '0')) * 60;
204 }
205 else if (p[0] == '-') {
206 if (end - p != 5) return -1;
207 /* Apply timezone offset */
208 return epoch + ((10 * (p[1] - '0') + p[2] - '0') * 60 + (10 * (p[3] - '0') + p[4] - '0')) * 60;
209 }
210
211 return -1;
212}
213
Emeric Brun1d3865b2014-06-20 15:37:32 +0200214static struct eb_root cert_ocsp_tree = EB_ROOT_UNIQUE;
Emeric Brun4147b2e2014-06-16 18:36:30 +0200215
216/* This function starts to check if the OCSP response (in DER format) contained
217 * in chunk 'ocsp_response' is valid (else exits on error).
218 * If 'cid' is not NULL, it will be compared to the OCSP certificate ID
219 * contained in the OCSP Response and exits on error if no match.
220 * If it's a valid OCSP Response:
221 * If 'ocsp' is not NULL, the chunk is copied in the OCSP response's container
222 * pointed by 'ocsp'.
223 * If 'ocsp' is NULL, the function looks up into the OCSP response's
224 * containers tree (using as index the ASN1 form of the OCSP Certificate ID extracted
225 * from the response) and exits on error if not found. Finally, If an OCSP response is
226 * already present in the container, it will be overwritten.
227 *
228 * Note: OCSP response containing more than one OCSP Single response is not
229 * considered valid.
230 *
231 * Returns 0 on success, 1 in error case.
232 */
233static int ssl_sock_load_ocsp_response(struct chunk *ocsp_response, struct certificate_ocsp *ocsp, OCSP_CERTID *cid, char **err)
234{
235 OCSP_RESPONSE *resp;
236 OCSP_BASICRESP *bs = NULL;
237 OCSP_SINGLERESP *sr;
238 unsigned char *p = (unsigned char *)ocsp_response->str;
239 int rc , count_sr;
Emeric Brun13a6b482014-06-20 15:44:34 +0200240 ASN1_GENERALIZEDTIME *revtime, *thisupd, *nextupd = NULL;
Emeric Brun4147b2e2014-06-16 18:36:30 +0200241 int reason;
242 int ret = 1;
243
244 resp = d2i_OCSP_RESPONSE(NULL, (const unsigned char **)&p, ocsp_response->len);
245 if (!resp) {
246 memprintf(err, "Unable to parse OCSP response");
247 goto out;
248 }
249
250 rc = OCSP_response_status(resp);
251 if (rc != OCSP_RESPONSE_STATUS_SUCCESSFUL) {
252 memprintf(err, "OCSP response status not successful");
253 goto out;
254 }
255
256 bs = OCSP_response_get1_basic(resp);
257 if (!bs) {
258 memprintf(err, "Failed to get basic response from OCSP Response");
259 goto out;
260 }
261
262 count_sr = OCSP_resp_count(bs);
263 if (count_sr > 1) {
264 memprintf(err, "OCSP response ignored because contains multiple single responses (%d)", count_sr);
265 goto out;
266 }
267
268 sr = OCSP_resp_get0(bs, 0);
269 if (!sr) {
270 memprintf(err, "Failed to get OCSP single response");
271 goto out;
272 }
273
274 rc = OCSP_single_get0_status(sr, &reason, &revtime, &thisupd, &nextupd);
275 if (rc != V_OCSP_CERTSTATUS_GOOD) {
276 memprintf(err, "OCSP single response: certificate status not good");
277 goto out;
278 }
279
Emeric Brun13a6b482014-06-20 15:44:34 +0200280 if (!nextupd) {
281 memprintf(err, "OCSP single response: missing nextupdate");
282 goto out;
283 }
284
Emeric Brunc8b27b62014-06-19 14:16:17 +0200285 rc = OCSP_check_validity(thisupd, nextupd, OCSP_MAX_RESPONSE_TIME_SKEW, -1);
Emeric Brun4147b2e2014-06-16 18:36:30 +0200286 if (!rc) {
287 memprintf(err, "OCSP single response: no longer valid.");
288 goto out;
289 }
290
291 if (cid) {
292 if (OCSP_id_cmp(sr->certId, cid)) {
293 memprintf(err, "OCSP single response: Certificate ID does not match certificate and issuer");
294 goto out;
295 }
296 }
297
298 if (!ocsp) {
299 unsigned char key[OCSP_MAX_CERTID_ASN1_LENGTH];
300 unsigned char *p;
301
302 rc = i2d_OCSP_CERTID(sr->certId, NULL);
303 if (!rc) {
304 memprintf(err, "OCSP single response: Unable to encode Certificate ID");
305 goto out;
306 }
307
308 if (rc > OCSP_MAX_CERTID_ASN1_LENGTH) {
309 memprintf(err, "OCSP single response: Certificate ID too long");
310 goto out;
311 }
312
313 p = key;
314 memset(key, 0, OCSP_MAX_CERTID_ASN1_LENGTH);
315 i2d_OCSP_CERTID(sr->certId, &p);
316 ocsp = (struct certificate_ocsp *)ebmb_lookup(&cert_ocsp_tree, key, OCSP_MAX_CERTID_ASN1_LENGTH);
317 if (!ocsp) {
318 memprintf(err, "OCSP single response: Certificate ID does not match any certificate or issuer");
319 goto out;
320 }
321 }
322
323 /* According to comments on "chunk_dup", the
324 previous chunk buffer will be freed */
325 if (!chunk_dup(&ocsp->response, ocsp_response)) {
326 memprintf(err, "OCSP response: Memory allocation error");
327 goto out;
328 }
329
Emeric Brun4f3c87a2014-06-20 15:46:13 +0200330 ocsp->expire = asn1_generalizedtime_to_epoch(nextupd) - OCSP_MAX_RESPONSE_TIME_SKEW;
331
Emeric Brun4147b2e2014-06-16 18:36:30 +0200332 ret = 0;
333out:
334 if (bs)
335 OCSP_BASICRESP_free(bs);
336
337 if (resp)
338 OCSP_RESPONSE_free(resp);
339
340 return ret;
341}
342/*
343 * External function use to update the OCSP response in the OCSP response's
344 * containers tree. The chunk 'ocsp_response' must contain the OCSP response
345 * to update in DER format.
346 *
347 * Returns 0 on success, 1 in error case.
348 */
349int ssl_sock_update_ocsp_response(struct chunk *ocsp_response, char **err)
350{
351 return ssl_sock_load_ocsp_response(ocsp_response, NULL, NULL, err);
352}
353
354/*
355 * This function load the OCSP Resonse in DER format contained in file at
356 * path 'ocsp_path' and call 'ssl_sock_load_ocsp_response'
357 *
358 * Returns 0 on success, 1 in error case.
359 */
360static int ssl_sock_load_ocsp_response_from_file(const char *ocsp_path, struct certificate_ocsp *ocsp, OCSP_CERTID *cid, char **err)
361{
362 int fd = -1;
363 int r = 0;
364 int ret = 1;
365
366 fd = open(ocsp_path, O_RDONLY);
367 if (fd == -1) {
368 memprintf(err, "Error opening OCSP response file");
369 goto end;
370 }
371
372 trash.len = 0;
373 while (trash.len < trash.size) {
374 r = read(fd, trash.str + trash.len, trash.size - trash.len);
375 if (r < 0) {
376 if (errno == EINTR)
377 continue;
378
379 memprintf(err, "Error reading OCSP response from file");
380 goto end;
381 }
382 else if (r == 0) {
383 break;
384 }
385 trash.len += r;
386 }
387
388 close(fd);
389 fd = -1;
390
391 ret = ssl_sock_load_ocsp_response(&trash, ocsp, cid, err);
392end:
393 if (fd != -1)
394 close(fd);
395
396 return ret;
397}
398
Nenad Merdanovic05552d42015-02-27 19:56:49 +0100399#if (defined SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB && TLS_TICKETS_NO > 0)
400static int ssl_tlsext_ticket_key_cb(SSL *s, unsigned char key_name[16], unsigned char *iv, EVP_CIPHER_CTX *ectx, HMAC_CTX *hctx, int enc)
401{
402 struct tls_sess_key *keys;
403 struct connection *conn;
404 int head;
405 int i;
406
407 conn = (struct connection *)SSL_get_app_data(s);
408 keys = objt_listener(conn->target)->bind_conf->tls_ticket_keys;
409 head = objt_listener(conn->target)->bind_conf->tls_ticket_enc_index;
410
411 if (enc) {
412 memcpy(key_name, keys[head].name, 16);
413
414 if(!RAND_pseudo_bytes(iv, EVP_MAX_IV_LENGTH))
415 return -1;
416
417 if(!EVP_EncryptInit_ex(ectx, EVP_aes_128_cbc(), NULL, keys[head].aes_key, iv))
418 return -1;
419
420 HMAC_Init_ex(hctx, keys[head].hmac_key, 16, HASH_FUNCT(), NULL);
421
422 return 1;
423 } else {
424 for (i = 0; i < TLS_TICKETS_NO; i++) {
425 if (!memcmp(key_name, keys[(head + i) % TLS_TICKETS_NO].name, 16))
426 goto found;
427 }
428 return 0;
429
430 found:
431 HMAC_Init_ex(hctx, keys[(head + i) % TLS_TICKETS_NO].hmac_key, 16, HASH_FUNCT(), NULL);
432 if(!EVP_DecryptInit_ex(ectx, EVP_aes_128_cbc(), NULL, keys[(head + i) % TLS_TICKETS_NO].aes_key, iv))
433 return -1;
434 /* 2 for key renewal, 1 if current key is still valid */
435 return i ? 2 : 1;
436 }
437}
438#endif /* SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB */
439
Emeric Brun4147b2e2014-06-16 18:36:30 +0200440/*
441 * Callback used to set OCSP status extension content in server hello.
442 */
443int ssl_sock_ocsp_stapling_cbk(SSL *ssl, void *arg)
444{
445 struct certificate_ocsp *ocsp = (struct certificate_ocsp *)arg;
446 char* ssl_buf;
447
448 if (!ocsp ||
449 !ocsp->response.str ||
Emeric Brun4f3c87a2014-06-20 15:46:13 +0200450 !ocsp->response.len ||
451 (ocsp->expire < now.tv_sec))
Emeric Brun4147b2e2014-06-16 18:36:30 +0200452 return SSL_TLSEXT_ERR_NOACK;
453
454 ssl_buf = OPENSSL_malloc(ocsp->response.len);
455 if (!ssl_buf)
456 return SSL_TLSEXT_ERR_NOACK;
457
458 memcpy(ssl_buf, ocsp->response.str, ocsp->response.len);
459 SSL_set_tlsext_status_ocsp_resp(ssl, ssl_buf, ocsp->response.len);
460
461 return SSL_TLSEXT_ERR_OK;
462}
463
464/*
465 * This function enables the handling of OCSP status extension on 'ctx' if a
466 * file name 'cert_path' suffixed using ".ocsp" is present.
467 * To enable OCSP status extension, the issuer's certificate is mandatory.
468 * It should be present in the certificate's extra chain builded from file
469 * 'cert_path'. If not found, the issuer certificate is loaded from a file
470 * named 'cert_path' suffixed using '.issuer'.
471 *
472 * In addition, ".ocsp" file content is loaded as a DER format of an OCSP
473 * response. If file is empty or content is not a valid OCSP response,
474 * OCSP status extension is enabled but OCSP response is ignored (a warning
475 * is displayed).
476 *
477 * Returns 1 if no ".ocsp" file found, 0 if OCSP status extension is
478 * succesfully enabled, or -1 in other error case.
479 */
480static int ssl_sock_load_ocsp(SSL_CTX *ctx, const char *cert_path)
481{
482
483 BIO *in = NULL;
484 X509 *x, *xi = NULL, *issuer = NULL;
485 STACK_OF(X509) *chain = NULL;
486 OCSP_CERTID *cid = NULL;
487 SSL *ssl;
488 char ocsp_path[MAXPATHLEN+1];
489 int i, ret = -1;
490 struct stat st;
491 struct certificate_ocsp *ocsp = NULL, *iocsp;
492 char *warn = NULL;
493 unsigned char *p;
494
495 snprintf(ocsp_path, MAXPATHLEN+1, "%s.ocsp", cert_path);
496
497 if (stat(ocsp_path, &st))
498 return 1;
499
500 ssl = SSL_new(ctx);
501 if (!ssl)
502 goto out;
503
504 x = SSL_get_certificate(ssl);
505 if (!x)
506 goto out;
507
508 /* Try to lookup for issuer in certificate extra chain */
509#ifdef SSL_CTRL_GET_EXTRA_CHAIN_CERTS
510 SSL_CTX_get_extra_chain_certs(ctx, &chain);
511#else
512 chain = ctx->extra_certs;
513#endif
514 for (i = 0; i < sk_X509_num(chain); i++) {
515 issuer = sk_X509_value(chain, i);
516 if (X509_check_issued(issuer, x) == X509_V_OK)
517 break;
518 else
519 issuer = NULL;
520 }
521
522 /* If not found try to load issuer from a suffixed file */
523 if (!issuer) {
524 char issuer_path[MAXPATHLEN+1];
525
526 in = BIO_new(BIO_s_file());
527 if (!in)
528 goto out;
529
530 snprintf(issuer_path, MAXPATHLEN+1, "%s.issuer", cert_path);
531 if (BIO_read_filename(in, issuer_path) <= 0)
532 goto out;
533
534 xi = PEM_read_bio_X509_AUX(in, NULL, ctx->default_passwd_callback, ctx->default_passwd_callback_userdata);
535 if (!xi)
536 goto out;
537
538 if (X509_check_issued(xi, x) != X509_V_OK)
539 goto out;
540
541 issuer = xi;
542 }
543
544 cid = OCSP_cert_to_id(0, x, issuer);
545 if (!cid)
546 goto out;
547
548 i = i2d_OCSP_CERTID(cid, NULL);
549 if (!i || (i > OCSP_MAX_CERTID_ASN1_LENGTH))
550 goto out;
551
552 ocsp = calloc(1, sizeof(struct certificate_ocsp));
553 if (!ocsp)
554 goto out;
555
556 p = ocsp->key_data;
557 i2d_OCSP_CERTID(cid, &p);
558
559 iocsp = (struct certificate_ocsp *)ebmb_insert(&cert_ocsp_tree, &ocsp->key, OCSP_MAX_CERTID_ASN1_LENGTH);
560 if (iocsp == ocsp)
561 ocsp = NULL;
562
563 SSL_CTX_set_tlsext_status_cb(ctx, ssl_sock_ocsp_stapling_cbk);
564 SSL_CTX_set_tlsext_status_arg(ctx, iocsp);
565
566 ret = 0;
567
568 warn = NULL;
569 if (ssl_sock_load_ocsp_response_from_file(ocsp_path, iocsp, cid, &warn)) {
570 memprintf(&warn, "Loading '%s': %s. Content will be ignored", ocsp_path, warn ? warn : "failure");
571 Warning("%s.\n", warn);
572 }
573
574out:
575 if (ssl)
576 SSL_free(ssl);
577
578 if (in)
579 BIO_free(in);
580
581 if (xi)
582 X509_free(xi);
583
584 if (cid)
585 OCSP_CERTID_free(cid);
586
587 if (ocsp)
588 free(ocsp);
589
590 if (warn)
591 free(warn);
592
593
594 return ret;
595}
596
597#endif
598
Emeric Brune1f38db2012-09-03 20:36:47 +0200599void ssl_sock_infocbk(const SSL *ssl, int where, int ret)
600{
601 struct connection *conn = (struct connection *)SSL_get_app_data(ssl);
Emeric Brund8b2bb52014-01-28 15:43:53 +0100602 BIO *write_bio;
Willy Tarreau622317d2015-02-27 16:36:16 +0100603 (void)ret; /* shut gcc stupid warning */
Emeric Brune1f38db2012-09-03 20:36:47 +0200604
605 if (where & SSL_CB_HANDSHAKE_START) {
606 /* Disable renegotiation (CVE-2009-3555) */
Willy Tarreau20879a02012-12-03 16:32:10 +0100607 if (conn->flags & CO_FL_CONNECTED) {
Emeric Brune1f38db2012-09-03 20:36:47 +0200608 conn->flags |= CO_FL_ERROR;
Willy Tarreau20879a02012-12-03 16:32:10 +0100609 conn->err_code = CO_ER_SSL_RENEG;
610 }
Emeric Brune1f38db2012-09-03 20:36:47 +0200611 }
Emeric Brund8b2bb52014-01-28 15:43:53 +0100612
613 if ((where & SSL_CB_ACCEPT_LOOP) == SSL_CB_ACCEPT_LOOP) {
614 if (!(conn->xprt_st & SSL_SOCK_ST_FL_16K_WBFSIZE)) {
615 /* Long certificate chains optimz
616 If write and read bios are differents, we
617 consider that the buffering was activated,
618 so we rise the output buffer size from 4k
619 to 16k */
620 write_bio = SSL_get_wbio(ssl);
621 if (write_bio != SSL_get_rbio(ssl)) {
622 BIO_set_write_buffer_size(write_bio, 16384);
623 conn->xprt_st |= SSL_SOCK_ST_FL_16K_WBFSIZE;
624 }
625 }
626 }
Emeric Brunfc0421f2012-09-07 17:30:07 +0200627}
628
Emeric Brune64aef12012-09-21 13:15:06 +0200629/* Callback is called for each certificate of the chain during a verify
630 ok is set to 1 if preverify detect no error on current certificate.
631 Returns 0 to break the handshake, 1 otherwise. */
Evan Broderbe554312013-06-27 00:05:25 -0700632int ssl_sock_bind_verifycbk(int ok, X509_STORE_CTX *x_store)
Emeric Brune64aef12012-09-21 13:15:06 +0200633{
634 SSL *ssl;
635 struct connection *conn;
Emeric Brun81c00f02012-09-21 14:31:21 +0200636 int err, depth;
Emeric Brune64aef12012-09-21 13:15:06 +0200637
638 ssl = X509_STORE_CTX_get_ex_data(x_store, SSL_get_ex_data_X509_STORE_CTX_idx());
639 conn = (struct connection *)SSL_get_app_data(ssl);
640
Willy Tarreauf7bc57c2012-10-03 00:19:48 +0200641 conn->xprt_st |= SSL_SOCK_ST_FL_VERIFY_DONE;
Emeric Brune64aef12012-09-21 13:15:06 +0200642
Emeric Brun81c00f02012-09-21 14:31:21 +0200643 if (ok) /* no errors */
644 return ok;
645
646 depth = X509_STORE_CTX_get_error_depth(x_store);
647 err = X509_STORE_CTX_get_error(x_store);
648
649 /* check if CA error needs to be ignored */
650 if (depth > 0) {
Willy Tarreauf7bc57c2012-10-03 00:19:48 +0200651 if (!SSL_SOCK_ST_TO_CA_ERROR(conn->xprt_st)) {
652 conn->xprt_st |= SSL_SOCK_CA_ERROR_TO_ST(err);
653 conn->xprt_st |= SSL_SOCK_CAEDEPTH_TO_ST(depth);
Emeric Brunf282a812012-09-21 15:27:54 +0200654 }
655
Emeric Brun1eb20ef2012-12-03 13:24:29 +0100656 if (objt_listener(conn->target)->bind_conf->ca_ignerr & (1ULL << err)) {
657 ERR_clear_error();
Emeric Brun81c00f02012-09-21 14:31:21 +0200658 return 1;
Emeric Brun1eb20ef2012-12-03 13:24:29 +0100659 }
Emeric Brun81c00f02012-09-21 14:31:21 +0200660
Willy Tarreau20879a02012-12-03 16:32:10 +0100661 conn->err_code = CO_ER_SSL_CA_FAIL;
Emeric Brun81c00f02012-09-21 14:31:21 +0200662 return 0;
663 }
664
Willy Tarreauf7bc57c2012-10-03 00:19:48 +0200665 if (!SSL_SOCK_ST_TO_CRTERROR(conn->xprt_st))
666 conn->xprt_st |= SSL_SOCK_CRTERROR_TO_ST(err);
Emeric Brunf282a812012-09-21 15:27:54 +0200667
Emeric Brun81c00f02012-09-21 14:31:21 +0200668 /* check if certificate error needs to be ignored */
Emeric Brun1eb20ef2012-12-03 13:24:29 +0100669 if (objt_listener(conn->target)->bind_conf->crt_ignerr & (1ULL << err)) {
670 ERR_clear_error();
Emeric Brun81c00f02012-09-21 14:31:21 +0200671 return 1;
Emeric Brun1eb20ef2012-12-03 13:24:29 +0100672 }
Emeric Brun81c00f02012-09-21 14:31:21 +0200673
Willy Tarreau20879a02012-12-03 16:32:10 +0100674 conn->err_code = CO_ER_SSL_CRT_FAIL;
Emeric Brun81c00f02012-09-21 14:31:21 +0200675 return 0;
Emeric Brune64aef12012-09-21 13:15:06 +0200676}
677
Emeric Brun29f037d2014-04-25 19:05:36 +0200678/* Callback is called for ssl protocol analyse */
679void ssl_sock_msgcbk(int write_p, int version, int content_type, const void *buf, size_t len, SSL *ssl, void *arg)
680{
Emeric Brun29f037d2014-04-25 19:05:36 +0200681#ifdef TLS1_RT_HEARTBEAT
682 /* test heartbeat received (write_p is set to 0
683 for a received record) */
Willy Tarreauf51c6982014-04-25 20:02:39 +0200684 if ((content_type == TLS1_RT_HEARTBEAT) && (write_p == 0)) {
Willy Tarreau84815002014-04-25 21:40:27 +0200685 struct connection *conn = (struct connection *)SSL_get_app_data(ssl);
Willy Tarreauf51c6982014-04-25 20:02:39 +0200686 const unsigned char *p = buf;
687 unsigned int payload;
688
Emeric Brun29f037d2014-04-25 19:05:36 +0200689 conn->xprt_st |= SSL_SOCK_RECV_HEARTBEAT;
Willy Tarreauf51c6982014-04-25 20:02:39 +0200690
691 /* Check if this is a CVE-2014-0160 exploitation attempt. */
692 if (*p != TLS1_HB_REQUEST)
693 return;
694
Willy Tarreauaeed6722014-04-25 23:59:58 +0200695 if (len < 1 + 2 + 16) /* 1 type + 2 size + 0 payload + 16 padding */
Willy Tarreauf51c6982014-04-25 20:02:39 +0200696 goto kill_it;
697
698 payload = (p[1] * 256) + p[2];
Willy Tarreau3b2fdb62014-04-25 23:44:22 +0200699 if (3 + payload + 16 <= len)
Willy Tarreauf51c6982014-04-25 20:02:39 +0200700 return; /* OK no problem */
Willy Tarreauaeed6722014-04-25 23:59:58 +0200701 kill_it:
Willy Tarreau3b2fdb62014-04-25 23:44:22 +0200702 /* We have a clear heartbleed attack (CVE-2014-0160), the
703 * advertised payload is larger than the advertised packet
704 * length, so we have garbage in the buffer between the
705 * payload and the end of the buffer (p+len). We can't know
706 * if the SSL stack is patched, and we don't know if we can
707 * safely wipe out the area between p+3+len and payload.
708 * So instead, we prevent the response from being sent by
709 * setting the max_send_fragment to 0 and we report an SSL
710 * error, which will kill this connection. It will be reported
711 * above as SSL_ERROR_SSL while an other handshake failure with
Willy Tarreauf51c6982014-04-25 20:02:39 +0200712 * a heartbeat message will be reported as SSL_ERROR_SYSCALL.
713 */
Willy Tarreau3b2fdb62014-04-25 23:44:22 +0200714 ssl->max_send_fragment = 0;
Willy Tarreauf51c6982014-04-25 20:02:39 +0200715 SSLerr(SSL_F_TLS1_HEARTBEAT, SSL_R_SSL_HANDSHAKE_FAILURE);
716 return;
717 }
Emeric Brun29f037d2014-04-25 19:05:36 +0200718#endif
719}
720
Willy Tarreau6c9a3d52012-10-18 18:57:14 +0200721#ifdef OPENSSL_NPN_NEGOTIATED
722/* This callback is used so that the server advertises the list of
723 * negociable protocols for NPN.
724 */
725static int ssl_sock_advertise_npn_protos(SSL *s, const unsigned char **data,
726 unsigned int *len, void *arg)
727{
728 struct bind_conf *conf = arg;
729
730 *data = (const unsigned char *)conf->npn_str;
731 *len = conf->npn_len;
732 return SSL_TLSEXT_ERR_OK;
733}
734#endif
735
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +0100736#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Willy Tarreauab861d32013-04-02 02:30:41 +0200737/* This callback is used so that the server advertises the list of
738 * negociable protocols for ALPN.
739 */
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +0100740static int ssl_sock_advertise_alpn_protos(SSL *s, const unsigned char **out,
741 unsigned char *outlen,
742 const unsigned char *server,
743 unsigned int server_len, void *arg)
Willy Tarreauab861d32013-04-02 02:30:41 +0200744{
745 struct bind_conf *conf = arg;
746
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +0100747 if (SSL_select_next_proto((unsigned char**) out, outlen, (const unsigned char *)conf->alpn_str,
748 conf->alpn_len, server, server_len) != OPENSSL_NPN_NEGOTIATED) {
749 return SSL_TLSEXT_ERR_NOACK;
750 }
Willy Tarreauab861d32013-04-02 02:30:41 +0200751 return SSL_TLSEXT_ERR_OK;
752}
753#endif
754
Emeric Brunfc0421f2012-09-07 17:30:07 +0200755#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
756/* Sets the SSL ctx of <ssl> to match the advertised server name. Returns a
757 * warning when no match is found, which implies the default (first) cert
758 * will keep being used.
759 */
Willy Tarreau2a65ff02012-09-13 17:54:29 +0200760static int ssl_sock_switchctx_cbk(SSL *ssl, int *al, struct bind_conf *s)
Emeric Brunfc0421f2012-09-07 17:30:07 +0200761{
762 const char *servername;
763 const char *wildp = NULL;
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +0200764 struct ebmb_node *node, *n;
Emeric Brunfc0421f2012-09-07 17:30:07 +0200765 int i;
766 (void)al; /* shut gcc stupid warning */
767
768 servername = SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name);
Emmanuel Hocdet65623372013-01-24 17:17:15 +0100769 if (!servername) {
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +0200770 return (s->strict_sni ?
771 SSL_TLSEXT_ERR_ALERT_FATAL :
Emmanuel Hocdet79274e22013-05-31 12:47:44 +0200772 SSL_TLSEXT_ERR_NOACK);
Emmanuel Hocdet65623372013-01-24 17:17:15 +0100773 }
Emeric Brunfc0421f2012-09-07 17:30:07 +0200774
Willy Tarreau19d14ef2012-10-29 16:51:55 +0100775 for (i = 0; i < trash.size; i++) {
Emeric Brunfc0421f2012-09-07 17:30:07 +0200776 if (!servername[i])
777 break;
Willy Tarreau19d14ef2012-10-29 16:51:55 +0100778 trash.str[i] = tolower(servername[i]);
779 if (!wildp && (trash.str[i] == '.'))
780 wildp = &trash.str[i];
Emeric Brunfc0421f2012-09-07 17:30:07 +0200781 }
Willy Tarreau19d14ef2012-10-29 16:51:55 +0100782 trash.str[i] = 0;
Emeric Brunfc0421f2012-09-07 17:30:07 +0200783
784 /* lookup in full qualified names */
Willy Tarreau19d14ef2012-10-29 16:51:55 +0100785 node = ebst_lookup(&s->sni_ctx, trash.str);
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +0200786
787 /* lookup a not neg filter */
788 for (n = node; n; n = ebmb_next_dup(n)) {
789 if (!container_of(n, struct sni_ctx, name)->neg) {
790 node = n;
791 break;
Emmanuel Hocdet65623372013-01-24 17:17:15 +0100792 }
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +0200793 }
794 if (!node && wildp) {
795 /* lookup in wildcards names */
Emeric Brunfc0421f2012-09-07 17:30:07 +0200796 node = ebst_lookup(&s->sni_w_ctx, wildp);
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +0200797 }
798 if (!node || container_of(node, struct sni_ctx, name)->neg) {
799 return (s->strict_sni ?
800 SSL_TLSEXT_ERR_ALERT_FATAL :
801 SSL_TLSEXT_ERR_ALERT_WARNING);
Emeric Brunfc0421f2012-09-07 17:30:07 +0200802 }
803
804 /* switch ctx */
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +0200805 SSL_set_SSL_CTX(ssl, container_of(node, struct sni_ctx, name)->ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +0200806 return SSL_TLSEXT_ERR_OK;
807}
808#endif /* SSL_CTRL_SET_TLSEXT_HOSTNAME */
809
Emeric Bruna4bcd9a2012-09-20 16:19:02 +0200810#ifndef OPENSSL_NO_DH
Remi Gacognef46cd6e2014-06-12 14:58:40 +0200811
812static DH * ssl_get_dh_1024(void)
813{
Lukas Tribus4c0d45a2014-08-18 00:56:32 +0200814#if (OPENSSL_VERSION_NUMBER < 0x0090801fL || defined OPENSSL_IS_BORINGSSL)
Remi Gacognef46cd6e2014-06-12 14:58:40 +0200815 static const unsigned char rfc_2409_prime_1024[] = {
816 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xC9,0x0F,0xDA,0xA2,
817 0x21,0x68,0xC2,0x34,0xC4,0xC6,0x62,0x8B,0x80,0xDC,0x1C,0xD1,
818 0x29,0x02,0x4E,0x08,0x8A,0x67,0xCC,0x74,0x02,0x0B,0xBE,0xA6,
819 0x3B,0x13,0x9B,0x22,0x51,0x4A,0x08,0x79,0x8E,0x34,0x04,0xDD,
820 0xEF,0x95,0x19,0xB3,0xCD,0x3A,0x43,0x1B,0x30,0x2B,0x0A,0x6D,
821 0xF2,0x5F,0x14,0x37,0x4F,0xE1,0x35,0x6D,0x6D,0x51,0xC2,0x45,
822 0xE4,0x85,0xB5,0x76,0x62,0x5E,0x7E,0xC6,0xF4,0x4C,0x42,0xE9,
823 0xA6,0x37,0xED,0x6B,0x0B,0xFF,0x5C,0xB6,0xF4,0x06,0xB7,0xED,
824 0xEE,0x38,0x6B,0xFB,0x5A,0x89,0x9F,0xA5,0xAE,0x9F,0x24,0x11,
825 0x7C,0x4B,0x1F,0xE6,0x49,0x28,0x66,0x51,0xEC,0xE6,0x53,0x81,
826 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
827 };
828#endif
829 DH *dh = DH_new();
830 if (dh) {
Lukas Tribus4c0d45a2014-08-18 00:56:32 +0200831#if (OPENSSL_VERSION_NUMBER >= 0x0090801fL && !defined OPENSSL_IS_BORINGSSL)
Remi Gacognef46cd6e2014-06-12 14:58:40 +0200832 dh->p = get_rfc2409_prime_1024(NULL);
833#else
834 dh->p = BN_bin2bn(rfc_2409_prime_1024, sizeof rfc_2409_prime_1024, NULL);
835#endif
836 /* See RFC 2409, Section 6 "Oakley Groups"
837 for the reason why 2 is used as generator.
838 */
839 BN_dec2bn(&dh->g, "2");
840 if (!dh->p || !dh->g) {
841 DH_free(dh);
842 dh = NULL;
843 }
844 }
845 return dh;
846}
847
848static DH *ssl_get_dh_2048(void)
849{
Lukas Tribus4c0d45a2014-08-18 00:56:32 +0200850#if (OPENSSL_VERSION_NUMBER < 0x0090801fL || defined OPENSSL_IS_BORINGSSL)
Remi Gacognef46cd6e2014-06-12 14:58:40 +0200851 static const unsigned char rfc_3526_prime_2048[] = {
852 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xC9,0x0F,0xDA,0xA2,
853 0x21,0x68,0xC2,0x34,0xC4,0xC6,0x62,0x8B,0x80,0xDC,0x1C,0xD1,
854 0x29,0x02,0x4E,0x08,0x8A,0x67,0xCC,0x74,0x02,0x0B,0xBE,0xA6,
855 0x3B,0x13,0x9B,0x22,0x51,0x4A,0x08,0x79,0x8E,0x34,0x04,0xDD,
856 0xEF,0x95,0x19,0xB3,0xCD,0x3A,0x43,0x1B,0x30,0x2B,0x0A,0x6D,
857 0xF2,0x5F,0x14,0x37,0x4F,0xE1,0x35,0x6D,0x6D,0x51,0xC2,0x45,
858 0xE4,0x85,0xB5,0x76,0x62,0x5E,0x7E,0xC6,0xF4,0x4C,0x42,0xE9,
859 0xA6,0x37,0xED,0x6B,0x0B,0xFF,0x5C,0xB6,0xF4,0x06,0xB7,0xED,
860 0xEE,0x38,0x6B,0xFB,0x5A,0x89,0x9F,0xA5,0xAE,0x9F,0x24,0x11,
861 0x7C,0x4B,0x1F,0xE6,0x49,0x28,0x66,0x51,0xEC,0xE4,0x5B,0x3D,
862 0xC2,0x00,0x7C,0xB8,0xA1,0x63,0xBF,0x05,0x98,0xDA,0x48,0x36,
863 0x1C,0x55,0xD3,0x9A,0x69,0x16,0x3F,0xA8,0xFD,0x24,0xCF,0x5F,
864 0x83,0x65,0x5D,0x23,0xDC,0xA3,0xAD,0x96,0x1C,0x62,0xF3,0x56,
865 0x20,0x85,0x52,0xBB,0x9E,0xD5,0x29,0x07,0x70,0x96,0x96,0x6D,
866 0x67,0x0C,0x35,0x4E,0x4A,0xBC,0x98,0x04,0xF1,0x74,0x6C,0x08,
867 0xCA,0x18,0x21,0x7C,0x32,0x90,0x5E,0x46,0x2E,0x36,0xCE,0x3B,
868 0xE3,0x9E,0x77,0x2C,0x18,0x0E,0x86,0x03,0x9B,0x27,0x83,0xA2,
869 0xEC,0x07,0xA2,0x8F,0xB5,0xC5,0x5D,0xF0,0x6F,0x4C,0x52,0xC9,
870 0xDE,0x2B,0xCB,0xF6,0x95,0x58,0x17,0x18,0x39,0x95,0x49,0x7C,
871 0xEA,0x95,0x6A,0xE5,0x15,0xD2,0x26,0x18,0x98,0xFA,0x05,0x10,
872 0x15,0x72,0x8E,0x5A,0x8A,0xAC,0xAA,0x68,0xFF,0xFF,0xFF,0xFF,
873 0xFF,0xFF,0xFF,0xFF,
874 };
875#endif
876 DH *dh = DH_new();
877 if (dh) {
Lukas Tribus4c0d45a2014-08-18 00:56:32 +0200878#if (OPENSSL_VERSION_NUMBER >= 0x0090801fL && !defined OPENSSL_IS_BORINGSSL)
Remi Gacognef46cd6e2014-06-12 14:58:40 +0200879 dh->p = get_rfc3526_prime_2048(NULL);
880#else
881 dh->p = BN_bin2bn(rfc_3526_prime_2048, sizeof rfc_3526_prime_2048, NULL);
882#endif
883 /* See RFC 3526, Section 3 "2048-bit MODP Group"
884 for the reason why 2 is used as generator.
885 */
886 BN_dec2bn(&dh->g, "2");
887 if (!dh->p || !dh->g) {
888 DH_free(dh);
889 dh = NULL;
890 }
891 }
892 return dh;
893}
894
895static DH *ssl_get_dh_4096(void)
896{
Lukas Tribus4c0d45a2014-08-18 00:56:32 +0200897#if (OPENSSL_VERSION_NUMBER < 0x0090801fL || defined OPENSSL_IS_BORINGSSL)
Remi Gacognef46cd6e2014-06-12 14:58:40 +0200898 static const unsigned char rfc_3526_prime_4096[] = {
899 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xC9,0x0F,0xDA,0xA2,
900 0x21,0x68,0xC2,0x34,0xC4,0xC6,0x62,0x8B,0x80,0xDC,0x1C,0xD1,
901 0x29,0x02,0x4E,0x08,0x8A,0x67,0xCC,0x74,0x02,0x0B,0xBE,0xA6,
902 0x3B,0x13,0x9B,0x22,0x51,0x4A,0x08,0x79,0x8E,0x34,0x04,0xDD,
903 0xEF,0x95,0x19,0xB3,0xCD,0x3A,0x43,0x1B,0x30,0x2B,0x0A,0x6D,
904 0xF2,0x5F,0x14,0x37,0x4F,0xE1,0x35,0x6D,0x6D,0x51,0xC2,0x45,
905 0xE4,0x85,0xB5,0x76,0x62,0x5E,0x7E,0xC6,0xF4,0x4C,0x42,0xE9,
906 0xA6,0x37,0xED,0x6B,0x0B,0xFF,0x5C,0xB6,0xF4,0x06,0xB7,0xED,
907 0xEE,0x38,0x6B,0xFB,0x5A,0x89,0x9F,0xA5,0xAE,0x9F,0x24,0x11,
908 0x7C,0x4B,0x1F,0xE6,0x49,0x28,0x66,0x51,0xEC,0xE4,0x5B,0x3D,
909 0xC2,0x00,0x7C,0xB8,0xA1,0x63,0xBF,0x05,0x98,0xDA,0x48,0x36,
910 0x1C,0x55,0xD3,0x9A,0x69,0x16,0x3F,0xA8,0xFD,0x24,0xCF,0x5F,
911 0x83,0x65,0x5D,0x23,0xDC,0xA3,0xAD,0x96,0x1C,0x62,0xF3,0x56,
912 0x20,0x85,0x52,0xBB,0x9E,0xD5,0x29,0x07,0x70,0x96,0x96,0x6D,
913 0x67,0x0C,0x35,0x4E,0x4A,0xBC,0x98,0x04,0xF1,0x74,0x6C,0x08,
914 0xCA,0x18,0x21,0x7C,0x32,0x90,0x5E,0x46,0x2E,0x36,0xCE,0x3B,
915 0xE3,0x9E,0x77,0x2C,0x18,0x0E,0x86,0x03,0x9B,0x27,0x83,0xA2,
916 0xEC,0x07,0xA2,0x8F,0xB5,0xC5,0x5D,0xF0,0x6F,0x4C,0x52,0xC9,
917 0xDE,0x2B,0xCB,0xF6,0x95,0x58,0x17,0x18,0x39,0x95,0x49,0x7C,
918 0xEA,0x95,0x6A,0xE5,0x15,0xD2,0x26,0x18,0x98,0xFA,0x05,0x10,
919 0x15,0x72,0x8E,0x5A,0x8A,0xAA,0xC4,0x2D,0xAD,0x33,0x17,0x0D,
920 0x04,0x50,0x7A,0x33,0xA8,0x55,0x21,0xAB,0xDF,0x1C,0xBA,0x64,
921 0xEC,0xFB,0x85,0x04,0x58,0xDB,0xEF,0x0A,0x8A,0xEA,0x71,0x57,
922 0x5D,0x06,0x0C,0x7D,0xB3,0x97,0x0F,0x85,0xA6,0xE1,0xE4,0xC7,
923 0xAB,0xF5,0xAE,0x8C,0xDB,0x09,0x33,0xD7,0x1E,0x8C,0x94,0xE0,
924 0x4A,0x25,0x61,0x9D,0xCE,0xE3,0xD2,0x26,0x1A,0xD2,0xEE,0x6B,
925 0xF1,0x2F,0xFA,0x06,0xD9,0x8A,0x08,0x64,0xD8,0x76,0x02,0x73,
926 0x3E,0xC8,0x6A,0x64,0x52,0x1F,0x2B,0x18,0x17,0x7B,0x20,0x0C,
927 0xBB,0xE1,0x17,0x57,0x7A,0x61,0x5D,0x6C,0x77,0x09,0x88,0xC0,
928 0xBA,0xD9,0x46,0xE2,0x08,0xE2,0x4F,0xA0,0x74,0xE5,0xAB,0x31,
929 0x43,0xDB,0x5B,0xFC,0xE0,0xFD,0x10,0x8E,0x4B,0x82,0xD1,0x20,
930 0xA9,0x21,0x08,0x01,0x1A,0x72,0x3C,0x12,0xA7,0x87,0xE6,0xD7,
931 0x88,0x71,0x9A,0x10,0xBD,0xBA,0x5B,0x26,0x99,0xC3,0x27,0x18,
932 0x6A,0xF4,0xE2,0x3C,0x1A,0x94,0x68,0x34,0xB6,0x15,0x0B,0xDA,
933 0x25,0x83,0xE9,0xCA,0x2A,0xD4,0x4C,0xE8,0xDB,0xBB,0xC2,0xDB,
934 0x04,0xDE,0x8E,0xF9,0x2E,0x8E,0xFC,0x14,0x1F,0xBE,0xCA,0xA6,
935 0x28,0x7C,0x59,0x47,0x4E,0x6B,0xC0,0x5D,0x99,0xB2,0x96,0x4F,
936 0xA0,0x90,0xC3,0xA2,0x23,0x3B,0xA1,0x86,0x51,0x5B,0xE7,0xED,
937 0x1F,0x61,0x29,0x70,0xCE,0xE2,0xD7,0xAF,0xB8,0x1B,0xDD,0x76,
938 0x21,0x70,0x48,0x1C,0xD0,0x06,0x91,0x27,0xD5,0xB0,0x5A,0xA9,
939 0x93,0xB4,0xEA,0x98,0x8D,0x8F,0xDD,0xC1,0x86,0xFF,0xB7,0xDC,
940 0x90,0xA6,0xC0,0x8F,0x4D,0xF4,0x35,0xC9,0x34,0x06,0x31,0x99,
941 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
942 };
943#endif
944 DH *dh = DH_new();
945 if (dh) {
Lukas Tribus4c0d45a2014-08-18 00:56:32 +0200946#if (OPENSSL_VERSION_NUMBER >= 0x0090801fL && !defined OPENSSL_IS_BORINGSSL)
Remi Gacognef46cd6e2014-06-12 14:58:40 +0200947 dh->p = get_rfc3526_prime_4096(NULL);
948#else
949 dh->p = BN_bin2bn(rfc_3526_prime_4096, sizeof rfc_3526_prime_4096, NULL);
950#endif
951 /* See RFC 3526, Section 5 "4096-bit MODP Group"
952 for the reason why 2 is used as generator.
953 */
954 BN_dec2bn(&dh->g, "2");
955 if (!dh->p || !dh->g) {
956 DH_free(dh);
957 dh = NULL;
958 }
959 }
960 return dh;
961}
962
963static DH *ssl_get_dh_8192(void)
964{
Lukas Tribus4c0d45a2014-08-18 00:56:32 +0200965#if (OPENSSL_VERSION_NUMBER < 0x0090801fL || defined OPENSSL_IS_BORINGSSL)
Remi Gacognef46cd6e2014-06-12 14:58:40 +0200966 static const unsigned char rfc_3526_prime_8192[] = {
967 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xC9,0x0F,0xDA,0xA2,
968 0x21,0x68,0xC2,0x34,0xC4,0xC6,0x62,0x8B,0x80,0xDC,0x1C,0xD1,
969 0x29,0x02,0x4E,0x08,0x8A,0x67,0xCC,0x74,0x02,0x0B,0xBE,0xA6,
970 0x3B,0x13,0x9B,0x22,0x51,0x4A,0x08,0x79,0x8E,0x34,0x04,0xDD,
971 0xEF,0x95,0x19,0xB3,0xCD,0x3A,0x43,0x1B,0x30,0x2B,0x0A,0x6D,
972 0xF2,0x5F,0x14,0x37,0x4F,0xE1,0x35,0x6D,0x6D,0x51,0xC2,0x45,
973 0xE4,0x85,0xB5,0x76,0x62,0x5E,0x7E,0xC6,0xF4,0x4C,0x42,0xE9,
974 0xA6,0x37,0xED,0x6B,0x0B,0xFF,0x5C,0xB6,0xF4,0x06,0xB7,0xED,
975 0xEE,0x38,0x6B,0xFB,0x5A,0x89,0x9F,0xA5,0xAE,0x9F,0x24,0x11,
976 0x7C,0x4B,0x1F,0xE6,0x49,0x28,0x66,0x51,0xEC,0xE4,0x5B,0x3D,
977 0xC2,0x00,0x7C,0xB8,0xA1,0x63,0xBF,0x05,0x98,0xDA,0x48,0x36,
978 0x1C,0x55,0xD3,0x9A,0x69,0x16,0x3F,0xA8,0xFD,0x24,0xCF,0x5F,
979 0x83,0x65,0x5D,0x23,0xDC,0xA3,0xAD,0x96,0x1C,0x62,0xF3,0x56,
980 0x20,0x85,0x52,0xBB,0x9E,0xD5,0x29,0x07,0x70,0x96,0x96,0x6D,
981 0x67,0x0C,0x35,0x4E,0x4A,0xBC,0x98,0x04,0xF1,0x74,0x6C,0x08,
982 0xCA,0x18,0x21,0x7C,0x32,0x90,0x5E,0x46,0x2E,0x36,0xCE,0x3B,
983 0xE3,0x9E,0x77,0x2C,0x18,0x0E,0x86,0x03,0x9B,0x27,0x83,0xA2,
984 0xEC,0x07,0xA2,0x8F,0xB5,0xC5,0x5D,0xF0,0x6F,0x4C,0x52,0xC9,
985 0xDE,0x2B,0xCB,0xF6,0x95,0x58,0x17,0x18,0x39,0x95,0x49,0x7C,
986 0xEA,0x95,0x6A,0xE5,0x15,0xD2,0x26,0x18,0x98,0xFA,0x05,0x10,
987 0x15,0x72,0x8E,0x5A,0x8A,0xAA,0xC4,0x2D,0xAD,0x33,0x17,0x0D,
988 0x04,0x50,0x7A,0x33,0xA8,0x55,0x21,0xAB,0xDF,0x1C,0xBA,0x64,
989 0xEC,0xFB,0x85,0x04,0x58,0xDB,0xEF,0x0A,0x8A,0xEA,0x71,0x57,
990 0x5D,0x06,0x0C,0x7D,0xB3,0x97,0x0F,0x85,0xA6,0xE1,0xE4,0xC7,
991 0xAB,0xF5,0xAE,0x8C,0xDB,0x09,0x33,0xD7,0x1E,0x8C,0x94,0xE0,
992 0x4A,0x25,0x61,0x9D,0xCE,0xE3,0xD2,0x26,0x1A,0xD2,0xEE,0x6B,
993 0xF1,0x2F,0xFA,0x06,0xD9,0x8A,0x08,0x64,0xD8,0x76,0x02,0x73,
994 0x3E,0xC8,0x6A,0x64,0x52,0x1F,0x2B,0x18,0x17,0x7B,0x20,0x0C,
995 0xBB,0xE1,0x17,0x57,0x7A,0x61,0x5D,0x6C,0x77,0x09,0x88,0xC0,
996 0xBA,0xD9,0x46,0xE2,0x08,0xE2,0x4F,0xA0,0x74,0xE5,0xAB,0x31,
997 0x43,0xDB,0x5B,0xFC,0xE0,0xFD,0x10,0x8E,0x4B,0x82,0xD1,0x20,
998 0xA9,0x21,0x08,0x01,0x1A,0x72,0x3C,0x12,0xA7,0x87,0xE6,0xD7,
999 0x88,0x71,0x9A,0x10,0xBD,0xBA,0x5B,0x26,0x99,0xC3,0x27,0x18,
1000 0x6A,0xF4,0xE2,0x3C,0x1A,0x94,0x68,0x34,0xB6,0x15,0x0B,0xDA,
1001 0x25,0x83,0xE9,0xCA,0x2A,0xD4,0x4C,0xE8,0xDB,0xBB,0xC2,0xDB,
1002 0x04,0xDE,0x8E,0xF9,0x2E,0x8E,0xFC,0x14,0x1F,0xBE,0xCA,0xA6,
1003 0x28,0x7C,0x59,0x47,0x4E,0x6B,0xC0,0x5D,0x99,0xB2,0x96,0x4F,
1004 0xA0,0x90,0xC3,0xA2,0x23,0x3B,0xA1,0x86,0x51,0x5B,0xE7,0xED,
1005 0x1F,0x61,0x29,0x70,0xCE,0xE2,0xD7,0xAF,0xB8,0x1B,0xDD,0x76,
1006 0x21,0x70,0x48,0x1C,0xD0,0x06,0x91,0x27,0xD5,0xB0,0x5A,0xA9,
1007 0x93,0xB4,0xEA,0x98,0x8D,0x8F,0xDD,0xC1,0x86,0xFF,0xB7,0xDC,
1008 0x90,0xA6,0xC0,0x8F,0x4D,0xF4,0x35,0xC9,0x34,0x02,0x84,0x92,
1009 0x36,0xC3,0xFA,0xB4,0xD2,0x7C,0x70,0x26,0xC1,0xD4,0xDC,0xB2,
1010 0x60,0x26,0x46,0xDE,0xC9,0x75,0x1E,0x76,0x3D,0xBA,0x37,0xBD,
1011 0xF8,0xFF,0x94,0x06,0xAD,0x9E,0x53,0x0E,0xE5,0xDB,0x38,0x2F,
1012 0x41,0x30,0x01,0xAE,0xB0,0x6A,0x53,0xED,0x90,0x27,0xD8,0x31,
1013 0x17,0x97,0x27,0xB0,0x86,0x5A,0x89,0x18,0xDA,0x3E,0xDB,0xEB,
1014 0xCF,0x9B,0x14,0xED,0x44,0xCE,0x6C,0xBA,0xCE,0xD4,0xBB,0x1B,
1015 0xDB,0x7F,0x14,0x47,0xE6,0xCC,0x25,0x4B,0x33,0x20,0x51,0x51,
1016 0x2B,0xD7,0xAF,0x42,0x6F,0xB8,0xF4,0x01,0x37,0x8C,0xD2,0xBF,
1017 0x59,0x83,0xCA,0x01,0xC6,0x4B,0x92,0xEC,0xF0,0x32,0xEA,0x15,
1018 0xD1,0x72,0x1D,0x03,0xF4,0x82,0xD7,0xCE,0x6E,0x74,0xFE,0xF6,
1019 0xD5,0x5E,0x70,0x2F,0x46,0x98,0x0C,0x82,0xB5,0xA8,0x40,0x31,
1020 0x90,0x0B,0x1C,0x9E,0x59,0xE7,0xC9,0x7F,0xBE,0xC7,0xE8,0xF3,
1021 0x23,0xA9,0x7A,0x7E,0x36,0xCC,0x88,0xBE,0x0F,0x1D,0x45,0xB7,
1022 0xFF,0x58,0x5A,0xC5,0x4B,0xD4,0x07,0xB2,0x2B,0x41,0x54,0xAA,
1023 0xCC,0x8F,0x6D,0x7E,0xBF,0x48,0xE1,0xD8,0x14,0xCC,0x5E,0xD2,
1024 0x0F,0x80,0x37,0xE0,0xA7,0x97,0x15,0xEE,0xF2,0x9B,0xE3,0x28,
1025 0x06,0xA1,0xD5,0x8B,0xB7,0xC5,0xDA,0x76,0xF5,0x50,0xAA,0x3D,
1026 0x8A,0x1F,0xBF,0xF0,0xEB,0x19,0xCC,0xB1,0xA3,0x13,0xD5,0x5C,
1027 0xDA,0x56,0xC9,0xEC,0x2E,0xF2,0x96,0x32,0x38,0x7F,0xE8,0xD7,
1028 0x6E,0x3C,0x04,0x68,0x04,0x3E,0x8F,0x66,0x3F,0x48,0x60,0xEE,
1029 0x12,0xBF,0x2D,0x5B,0x0B,0x74,0x74,0xD6,0xE6,0x94,0xF9,0x1E,
1030 0x6D,0xBE,0x11,0x59,0x74,0xA3,0x92,0x6F,0x12,0xFE,0xE5,0xE4,
1031 0x38,0x77,0x7C,0xB6,0xA9,0x32,0xDF,0x8C,0xD8,0xBE,0xC4,0xD0,
1032 0x73,0xB9,0x31,0xBA,0x3B,0xC8,0x32,0xB6,0x8D,0x9D,0xD3,0x00,
1033 0x74,0x1F,0xA7,0xBF,0x8A,0xFC,0x47,0xED,0x25,0x76,0xF6,0x93,
1034 0x6B,0xA4,0x24,0x66,0x3A,0xAB,0x63,0x9C,0x5A,0xE4,0xF5,0x68,
1035 0x34,0x23,0xB4,0x74,0x2B,0xF1,0xC9,0x78,0x23,0x8F,0x16,0xCB,
1036 0xE3,0x9D,0x65,0x2D,0xE3,0xFD,0xB8,0xBE,0xFC,0x84,0x8A,0xD9,
1037 0x22,0x22,0x2E,0x04,0xA4,0x03,0x7C,0x07,0x13,0xEB,0x57,0xA8,
1038 0x1A,0x23,0xF0,0xC7,0x34,0x73,0xFC,0x64,0x6C,0xEA,0x30,0x6B,
1039 0x4B,0xCB,0xC8,0x86,0x2F,0x83,0x85,0xDD,0xFA,0x9D,0x4B,0x7F,
1040 0xA2,0xC0,0x87,0xE8,0x79,0x68,0x33,0x03,0xED,0x5B,0xDD,0x3A,
1041 0x06,0x2B,0x3C,0xF5,0xB3,0xA2,0x78,0xA6,0x6D,0x2A,0x13,0xF8,
1042 0x3F,0x44,0xF8,0x2D,0xDF,0x31,0x0E,0xE0,0x74,0xAB,0x6A,0x36,
1043 0x45,0x97,0xE8,0x99,0xA0,0x25,0x5D,0xC1,0x64,0xF3,0x1C,0xC5,
1044 0x08,0x46,0x85,0x1D,0xF9,0xAB,0x48,0x19,0x5D,0xED,0x7E,0xA1,
1045 0xB1,0xD5,0x10,0xBD,0x7E,0xE7,0x4D,0x73,0xFA,0xF3,0x6B,0xC3,
1046 0x1E,0xCF,0xA2,0x68,0x35,0x90,0x46,0xF4,0xEB,0x87,0x9F,0x92,
1047 0x40,0x09,0x43,0x8B,0x48,0x1C,0x6C,0xD7,0x88,0x9A,0x00,0x2E,
1048 0xD5,0xEE,0x38,0x2B,0xC9,0x19,0x0D,0xA6,0xFC,0x02,0x6E,0x47,
1049 0x95,0x58,0xE4,0x47,0x56,0x77,0xE9,0xAA,0x9E,0x30,0x50,0xE2,
1050 0x76,0x56,0x94,0xDF,0xC8,0x1F,0x56,0xE8,0x80,0xB9,0x6E,0x71,
1051 0x60,0xC9,0x80,0xDD,0x98,0xED,0xD3,0xDF,0xFF,0xFF,0xFF,0xFF,
1052 0xFF,0xFF,0xFF,0xFF,
1053 };
1054#endif
1055 DH *dh = DH_new();
1056 if (dh) {
Lukas Tribus4c0d45a2014-08-18 00:56:32 +02001057#if (OPENSSL_VERSION_NUMBER >= 0x0090801fL && !defined OPENSSL_IS_BORINGSSL)
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001058 dh->p = get_rfc3526_prime_8192(NULL);
1059#else
1060 dh->p = BN_bin2bn(rfc_3526_prime_8192, sizeof rfc_3526_prime_8192, NULL);
1061#endif
1062 /* See RFC 3526, Section 7 "8192-bit MODP Group"
1063 for the reason why 2 is used as generator.
1064 */
1065 BN_dec2bn(&dh->g, "2");
1066 if (!dh->p || !dh->g) {
1067 DH_free(dh);
1068 dh = NULL;
1069 }
1070 }
1071 return dh;
1072}
1073
1074/* Returns Diffie-Hellman parameters matching the private key length
1075 but not exceeding global.tune.ssl_default_dh_param */
1076static DH *ssl_get_tmp_dh(SSL *ssl, int export, int keylen)
1077{
1078 DH *dh = NULL;
1079 EVP_PKEY *pkey = SSL_get_privatekey(ssl);
1080 int type = pkey ? EVP_PKEY_type(pkey->type) : EVP_PKEY_NONE;
1081
1082 /* The keylen supplied by OpenSSL can only be 512 or 1024.
1083 See ssl3_send_server_key_exchange() in ssl/s3_srvr.c
1084 */
1085 if (type == EVP_PKEY_RSA || type == EVP_PKEY_DSA) {
1086 keylen = EVP_PKEY_bits(pkey);
1087 }
1088
1089 if (keylen > global.tune.ssl_default_dh_param) {
1090 keylen = global.tune.ssl_default_dh_param;
1091 }
1092
1093 if (keylen >= 8192) {
Remi Gacogne8de54152014-07-15 11:36:40 +02001094 dh = local_dh_8192;
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001095 }
1096 else if (keylen >= 4096) {
Remi Gacogne8de54152014-07-15 11:36:40 +02001097 dh = local_dh_4096;
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001098 }
1099 else if (keylen >= 2048) {
Remi Gacogne8de54152014-07-15 11:36:40 +02001100 dh = local_dh_2048;
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001101 }
1102 else {
Remi Gacogne8de54152014-07-15 11:36:40 +02001103 dh = local_dh_1024;
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001104 }
1105
1106 return dh;
1107}
1108
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001109/* Loads Diffie-Hellman parameter from a file. Returns 1 if loaded, else -1
1110 if an error occured, and 0 if parameter not found. */
Willy Tarreau6e774b42014-04-25 21:35:23 +02001111int ssl_sock_load_dh_params(SSL_CTX *ctx, const char *file)
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001112{
1113 int ret = -1;
1114 BIO *in;
1115 DH *dh = NULL;
1116
1117 in = BIO_new(BIO_s_file());
1118 if (in == NULL)
1119 goto end;
1120
1121 if (BIO_read_filename(in, file) <= 0)
1122 goto end;
1123
1124 dh = PEM_read_bio_DHparams(in, NULL, ctx->default_passwd_callback, ctx->default_passwd_callback_userdata);
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001125 if (dh) {
1126 ret = 1;
1127 SSL_CTX_set_tmp_dh(ctx, dh);
1128 /* Setting ssl default dh param to the size of the static DH params
1129 found in the file. This way we know that there is no use
1130 complaining later about ssl-default-dh-param not being set. */
1131 global.tune.ssl_default_dh_param = DH_size(dh) * 8;
1132 }
1133 else {
Emeric Brun41fdb3c2013-04-26 11:05:44 +02001134 /* Clear openssl global errors stack */
1135 ERR_clear_error();
1136
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001137 if (global.tune.ssl_default_dh_param <= 1024) {
1138 /* we are limited to DH parameter of 1024 bits anyway */
Remi Gacogne8de54152014-07-15 11:36:40 +02001139 local_dh_1024 = ssl_get_dh_1024();
1140 if (local_dh_1024 == NULL)
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001141 goto end;
Willy Tarreau6e774b42014-04-25 21:35:23 +02001142
Remi Gacogne8de54152014-07-15 11:36:40 +02001143 SSL_CTX_set_tmp_dh(ctx, local_dh_1024);
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001144 }
1145 else {
1146 SSL_CTX_set_tmp_dh_callback(ctx, ssl_get_tmp_dh);
1147 }
Willy Tarreau6e774b42014-04-25 21:35:23 +02001148
Emeric Brun41fdb3c2013-04-26 11:05:44 +02001149 ret = 0; /* DH params not found */
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001150 }
Emeric Brun644cde02012-12-14 11:21:13 +01001151
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001152end:
1153 if (dh)
1154 DH_free(dh);
1155
1156 if (in)
Emeric Brun41fdb3c2013-04-26 11:05:44 +02001157 BIO_free(in);
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001158
1159 return ret;
1160}
1161#endif
1162
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001163static int ssl_sock_add_cert_sni(SSL_CTX *ctx, struct bind_conf *s, char *name, int order)
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001164{
1165 struct sni_ctx *sc;
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001166 int wild = 0, neg = 0;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001167
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001168 if (*name == '!') {
1169 neg = 1;
1170 name++;
1171 }
1172 if (*name == '*') {
1173 wild = 1;
1174 name++;
1175 }
1176 /* !* filter is a nop */
1177 if (neg && wild)
1178 return order;
1179 if (*name) {
1180 int j, len;
1181 len = strlen(name);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001182 sc = malloc(sizeof(struct sni_ctx) + len + 1);
1183 for (j = 0; j < len; j++)
1184 sc->name.key[j] = tolower(name[j]);
1185 sc->name.key[len] = 0;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001186 sc->ctx = ctx;
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001187 sc->order = order++;
1188 sc->neg = neg;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001189 if (wild)
1190 ebst_insert(&s->sni_w_ctx, &sc->name);
1191 else
1192 ebst_insert(&s->sni_ctx, &sc->name);
1193 }
1194 return order;
1195}
1196
Emeric Brunfc0421f2012-09-07 17:30:07 +02001197/* Loads a certificate key and CA chain from a file. Returns 0 on error, -1 if
1198 * an early error happens and the caller must call SSL_CTX_free() by itelf.
1199 */
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001200static 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 +02001201{
1202 BIO *in;
1203 X509 *x = NULL, *ca;
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001204 int i, err;
Emeric Brunfc0421f2012-09-07 17:30:07 +02001205 int ret = -1;
1206 int order = 0;
1207 X509_NAME *xname;
1208 char *str;
Emeric Brunfc0421f2012-09-07 17:30:07 +02001209#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
1210 STACK_OF(GENERAL_NAME) *names;
1211#endif
1212
1213 in = BIO_new(BIO_s_file());
1214 if (in == NULL)
1215 goto end;
1216
1217 if (BIO_read_filename(in, file) <= 0)
1218 goto end;
1219
1220 x = PEM_read_bio_X509_AUX(in, NULL, ctx->default_passwd_callback, ctx->default_passwd_callback_userdata);
1221 if (x == NULL)
1222 goto end;
1223
Emeric Brun50bcecc2013-04-22 13:05:23 +02001224 if (fcount) {
1225 while (fcount--)
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001226 order = ssl_sock_add_cert_sni(ctx, s, sni_filter[fcount], order);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001227 }
1228 else {
Emeric Brunfc0421f2012-09-07 17:30:07 +02001229#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001230 names = X509_get_ext_d2i(x, NID_subject_alt_name, NULL, NULL);
1231 if (names) {
1232 for (i = 0; i < sk_GENERAL_NAME_num(names); i++) {
1233 GENERAL_NAME *name = sk_GENERAL_NAME_value(names, i);
1234 if (name->type == GEN_DNS) {
1235 if (ASN1_STRING_to_UTF8((unsigned char **)&str, name->d.dNSName) >= 0) {
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001236 order = ssl_sock_add_cert_sni(ctx, s, str, order);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001237 OPENSSL_free(str);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001238 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02001239 }
1240 }
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001241 sk_GENERAL_NAME_pop_free(names, GENERAL_NAME_free);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001242 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02001243#endif /* SSL_CTRL_SET_TLSEXT_HOSTNAME */
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001244 xname = X509_get_subject_name(x);
1245 i = -1;
1246 while ((i = X509_NAME_get_index_by_NID(xname, NID_commonName, i)) != -1) {
1247 X509_NAME_ENTRY *entry = X509_NAME_get_entry(xname, i);
1248 if (ASN1_STRING_to_UTF8((unsigned char **)&str, entry->value) >= 0) {
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001249 order = ssl_sock_add_cert_sni(ctx, s, str, order);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001250 OPENSSL_free(str);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001251 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02001252 }
1253 }
1254
1255 ret = 0; /* the caller must not free the SSL_CTX argument anymore */
1256 if (!SSL_CTX_use_certificate(ctx, x))
1257 goto end;
1258
1259 if (ctx->extra_certs != NULL) {
1260 sk_X509_pop_free(ctx->extra_certs, X509_free);
1261 ctx->extra_certs = NULL;
1262 }
1263
1264 while ((ca = PEM_read_bio_X509(in, NULL, ctx->default_passwd_callback, ctx->default_passwd_callback_userdata))) {
1265 if (!SSL_CTX_add_extra_chain_cert(ctx, ca)) {
1266 X509_free(ca);
1267 goto end;
1268 }
1269 }
1270
1271 err = ERR_get_error();
1272 if (!err || (ERR_GET_LIB(err) == ERR_LIB_PEM && ERR_GET_REASON(err) == PEM_R_NO_START_LINE)) {
1273 /* we successfully reached the last cert in the file */
1274 ret = 1;
1275 }
1276 ERR_clear_error();
1277
1278end:
1279 if (x)
1280 X509_free(x);
1281
1282 if (in)
1283 BIO_free(in);
1284
1285 return ret;
1286}
1287
Emeric Brun50bcecc2013-04-22 13:05:23 +02001288static 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 +02001289{
1290 int ret;
1291 SSL_CTX *ctx;
1292
1293 ctx = SSL_CTX_new(SSLv23_server_method());
1294 if (!ctx) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02001295 memprintf(err, "%sunable to allocate SSL context for cert '%s'.\n",
1296 err && *err ? *err : "", path);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001297 return 1;
1298 }
1299
1300 if (SSL_CTX_use_PrivateKey_file(ctx, path, SSL_FILETYPE_PEM) <= 0) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02001301 memprintf(err, "%sunable to load SSL private key from PEM file '%s'.\n",
1302 err && *err ? *err : "", path);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001303 SSL_CTX_free(ctx);
1304 return 1;
1305 }
1306
Emeric Brun50bcecc2013-04-22 13:05:23 +02001307 ret = ssl_sock_load_cert_chain_file(ctx, path, bind_conf, sni_filter, fcount);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001308 if (ret <= 0) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02001309 memprintf(err, "%sunable to load SSL certificate from PEM file '%s'.\n",
1310 err && *err ? *err : "", path);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001311 if (ret < 0) /* serious error, must do that ourselves */
1312 SSL_CTX_free(ctx);
1313 return 1;
1314 }
Emeric Brun61694ab2012-10-26 13:35:33 +02001315
1316 if (SSL_CTX_check_private_key(ctx) <= 0) {
1317 memprintf(err, "%sinconsistencies between private key and certificate loaded from PEM file '%s'.\n",
1318 err && *err ? *err : "", path);
1319 return 1;
1320 }
1321
Emeric Brunfc0421f2012-09-07 17:30:07 +02001322 /* we must not free the SSL_CTX anymore below, since it's already in
1323 * the tree, so it will be discovered and cleaned in time.
1324 */
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001325#ifndef OPENSSL_NO_DH
1326 ret = ssl_sock_load_dh_params(ctx, path);
1327 if (ret < 0) {
1328 if (err)
1329 memprintf(err, "%sunable to load DH parameters from file '%s'.\n",
1330 *err ? *err : "", path);
1331 return 1;
1332 }
1333#endif
1334
Lukas Tribuse4e30f72014-12-09 16:32:51 +01001335#if (defined SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB && !defined OPENSSL_NO_OCSP)
Emeric Brun4147b2e2014-06-16 18:36:30 +02001336 ret = ssl_sock_load_ocsp(ctx, path);
1337 if (ret < 0) {
1338 if (err)
1339 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",
1340 *err ? *err : "", path);
1341 return 1;
1342 }
1343#endif
1344
Emeric Brunfc0421f2012-09-07 17:30:07 +02001345#ifndef SSL_CTRL_SET_TLSEXT_HOSTNAME
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001346 if (bind_conf->default_ctx) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02001347 memprintf(err, "%sthis version of openssl cannot load multiple SSL certificates.\n",
1348 err && *err ? *err : "");
Emeric Brunfc0421f2012-09-07 17:30:07 +02001349 return 1;
1350 }
1351#endif
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001352 if (!bind_conf->default_ctx)
1353 bind_conf->default_ctx = ctx;
Emeric Brunfc0421f2012-09-07 17:30:07 +02001354
1355 return 0;
1356}
1357
Willy Tarreau79eeafa2012-09-14 07:53:05 +02001358int ssl_sock_load_cert(char *path, struct bind_conf *bind_conf, struct proxy *curproxy, char **err)
Emeric Brunfc0421f2012-09-07 17:30:07 +02001359{
Cyril Bonté3180f7b2015-01-25 00:16:08 +01001360 struct dirent **de_list;
1361 int i, n;
Emeric Brunfc0421f2012-09-07 17:30:07 +02001362 DIR *dir;
1363 struct stat buf;
Willy Tarreauee2663b2012-12-06 11:36:59 +01001364 char *end;
1365 char fp[MAXPATHLEN+1];
Emeric Brunfc0421f2012-09-07 17:30:07 +02001366 int cfgerr = 0;
1367
1368 if (!(dir = opendir(path)))
Emeric Brun50bcecc2013-04-22 13:05:23 +02001369 return ssl_sock_load_cert_file(path, bind_conf, curproxy, NULL, 0, err);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001370
1371 /* strip trailing slashes, including first one */
1372 for (end = path + strlen(path) - 1; end >= path && *end == '/'; end--)
1373 *end = 0;
1374
Cyril Bonté3180f7b2015-01-25 00:16:08 +01001375 n = scandir(path, &de_list, 0, alphasort);
1376 if (n < 0) {
1377 memprintf(err, "%sunable to scan directory '%s' : %s.\n",
1378 err && *err ? *err : "", path, strerror(errno));
1379 cfgerr++;
1380 }
1381 else {
1382 for (i = 0; i < n; i++) {
1383 struct dirent *de = de_list[i];
Emeric Brun2aab7222014-06-18 18:15:09 +02001384
Cyril Bonté3180f7b2015-01-25 00:16:08 +01001385 end = strrchr(de->d_name, '.');
1386 if (end && (!strcmp(end, ".issuer") || !strcmp(end, ".ocsp")))
1387 goto ignore_entry;
1388
1389 snprintf(fp, sizeof(fp), "%s/%s", path, de->d_name);
1390 if (stat(fp, &buf) != 0) {
1391 memprintf(err, "%sunable to stat SSL certificate from file '%s' : %s.\n",
1392 err && *err ? *err : "", fp, strerror(errno));
1393 cfgerr++;
1394 goto ignore_entry;
1395 }
1396 if (!S_ISREG(buf.st_mode))
1397 goto ignore_entry;
1398 cfgerr += ssl_sock_load_cert_file(fp, bind_conf, curproxy, NULL, 0, err);
1399 ignore_entry:
1400 free(de);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001401 }
Cyril Bonté3180f7b2015-01-25 00:16:08 +01001402 free(de_list);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001403 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02001404 closedir(dir);
1405 return cfgerr;
1406}
1407
Thierry Fournier383085f2013-01-24 14:15:43 +01001408/* Make sure openssl opens /dev/urandom before the chroot. The work is only
1409 * done once. Zero is returned if the operation fails. No error is returned
1410 * if the random is said as not implemented, because we expect that openssl
1411 * will use another method once needed.
1412 */
1413static int ssl_initialize_random()
1414{
1415 unsigned char random;
1416 static int random_initialized = 0;
1417
1418 if (!random_initialized && RAND_bytes(&random, 1) != 0)
1419 random_initialized = 1;
1420
1421 return random_initialized;
1422}
1423
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001424int ssl_sock_load_cert_list_file(char *file, struct bind_conf *bind_conf, struct proxy *curproxy, char **err)
1425{
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001426 char thisline[LINESIZE];
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001427 FILE *f;
1428 int linenum = 0;
1429 int cfgerr = 0;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001430
Willy Tarreauad1731d2013-04-02 17:35:58 +02001431 if ((f = fopen(file, "r")) == NULL) {
1432 memprintf(err, "cannot open file '%s' : %s", file, strerror(errno));
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001433 return 1;
Willy Tarreauad1731d2013-04-02 17:35:58 +02001434 }
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001435
1436 while (fgets(thisline, sizeof(thisline), f) != NULL) {
1437 int arg;
Emeric Brun50bcecc2013-04-22 13:05:23 +02001438 int newarg;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001439 char *end;
1440 char *args[MAX_LINE_ARGS + 1];
1441 char *line = thisline;
1442
1443 linenum++;
1444 end = line + strlen(line);
1445 if (end-line == sizeof(thisline)-1 && *(end-1) != '\n') {
1446 /* Check if we reached the limit and the last char is not \n.
1447 * Watch out for the last line without the terminating '\n'!
1448 */
Willy Tarreauad1731d2013-04-02 17:35:58 +02001449 memprintf(err, "line %d too long in file '%s', limit is %d characters",
1450 linenum, file, (int)sizeof(thisline)-1);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001451 cfgerr = 1;
Willy Tarreauad1731d2013-04-02 17:35:58 +02001452 break;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001453 }
1454
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001455 arg = 0;
Emeric Brun50bcecc2013-04-22 13:05:23 +02001456 newarg = 1;
1457 while (*line) {
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001458 if (*line == '#' || *line == '\n' || *line == '\r') {
1459 /* end of string, end of loop */
1460 *line = 0;
1461 break;
1462 }
1463 else if (isspace(*line)) {
Emeric Brun50bcecc2013-04-22 13:05:23 +02001464 newarg = 1;
1465 *line = 0;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001466 }
Emeric Brun50bcecc2013-04-22 13:05:23 +02001467 else if (newarg) {
1468 if (arg == MAX_LINE_ARGS) {
1469 memprintf(err, "too many args on line %d in file '%s'.",
1470 linenum, file);
1471 cfgerr = 1;
1472 break;
1473 }
1474 newarg = 0;
1475 args[arg++] = line;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001476 }
Emeric Brun50bcecc2013-04-22 13:05:23 +02001477 line++;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001478 }
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001479 if (cfgerr)
1480 break;
Willy Tarreauad1731d2013-04-02 17:35:58 +02001481
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001482 /* empty line */
Emeric Brun50bcecc2013-04-22 13:05:23 +02001483 if (!arg)
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001484 continue;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001485
Emeric Brun50bcecc2013-04-22 13:05:23 +02001486 cfgerr = ssl_sock_load_cert_file(args[0], bind_conf, curproxy, &args[1], arg-1, err);
Willy Tarreauad1731d2013-04-02 17:35:58 +02001487 if (cfgerr) {
1488 memprintf(err, "error processing line %d in file '%s' : %s", linenum, file, *err);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001489 break;
Willy Tarreauad1731d2013-04-02 17:35:58 +02001490 }
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001491 }
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001492 fclose(f);
1493 return cfgerr;
1494}
1495
Emeric Brunfc0421f2012-09-07 17:30:07 +02001496#ifndef SSL_OP_CIPHER_SERVER_PREFERENCE /* needs OpenSSL >= 0.9.7 */
1497#define SSL_OP_CIPHER_SERVER_PREFERENCE 0
1498#endif
1499
1500#ifndef SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION /* needs OpenSSL >= 0.9.7 */
1501#define SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION 0
Willy Tarreau7d588ee2012-11-26 18:47:31 +01001502#define SSL_renegotiate_pending(arg) 0
Emeric Brunfc0421f2012-09-07 17:30:07 +02001503#endif
Emeric Brun2b58d042012-09-20 17:10:03 +02001504#ifndef SSL_OP_SINGLE_ECDH_USE /* needs OpenSSL >= 0.9.8 */
1505#define SSL_OP_SINGLE_ECDH_USE 0
1506#endif
Emeric Brun2d0c4822012-10-02 13:45:20 +02001507#ifndef SSL_OP_NO_TICKET /* needs OpenSSL >= 0.9.8 */
1508#define SSL_OP_NO_TICKET 0
1509#endif
Emeric Brunfc0421f2012-09-07 17:30:07 +02001510#ifndef SSL_OP_NO_COMPRESSION /* needs OpenSSL >= 0.9.9 */
1511#define SSL_OP_NO_COMPRESSION 0
1512#endif
Emeric Brunc0ff4922012-09-28 19:37:02 +02001513#ifndef SSL_OP_NO_TLSv1_1 /* needs OpenSSL >= 1.0.1 */
1514#define SSL_OP_NO_TLSv1_1 0
1515#endif
1516#ifndef SSL_OP_NO_TLSv1_2 /* needs OpenSSL >= 1.0.1 */
1517#define SSL_OP_NO_TLSv1_2 0
1518#endif
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001519#ifndef SSL_OP_SINGLE_DH_USE /* needs OpenSSL >= 0.9.6 */
1520#define SSL_OP_SINGLE_DH_USE 0
1521#endif
Emeric Brun2b58d042012-09-20 17:10:03 +02001522#ifndef SSL_OP_SINGLE_ECDH_USE /* needs OpenSSL >= 1.0.0 */
1523#define SSL_OP_SINGLE_ECDH_USE 0
1524#endif
Emeric Brunfc0421f2012-09-07 17:30:07 +02001525#ifndef SSL_MODE_RELEASE_BUFFERS /* needs OpenSSL >= 1.0.0 */
1526#define SSL_MODE_RELEASE_BUFFERS 0
1527#endif
Willy Tarreau396a1862014-11-13 14:06:52 +01001528#ifndef SSL_MODE_SMALL_BUFFERS /* needs small_records.patch */
1529#define SSL_MODE_SMALL_BUFFERS 0
1530#endif
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001531
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001532int ssl_sock_prepare_ctx(struct bind_conf *bind_conf, SSL_CTX *ctx, struct proxy *curproxy)
Emeric Brunfc0421f2012-09-07 17:30:07 +02001533{
1534 int cfgerr = 0;
Emeric Brun850efd52014-01-29 12:24:34 +01001535 int verify = SSL_VERIFY_NONE;
Remi Gacogneaf5c3da2014-05-19 10:29:58 +02001536 long ssloptions =
Emeric Brunfc0421f2012-09-07 17:30:07 +02001537 SSL_OP_ALL | /* all known workarounds for bugs */
1538 SSL_OP_NO_SSLv2 |
1539 SSL_OP_NO_COMPRESSION |
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001540 SSL_OP_SINGLE_DH_USE |
Emeric Brun2b58d042012-09-20 17:10:03 +02001541 SSL_OP_SINGLE_ECDH_USE |
Emeric Brun3c4bc6e2012-10-04 18:44:19 +02001542 SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION |
1543 SSL_OP_CIPHER_SERVER_PREFERENCE;
Remi Gacogneaf5c3da2014-05-19 10:29:58 +02001544 long sslmode =
Emeric Brunfc0421f2012-09-07 17:30:07 +02001545 SSL_MODE_ENABLE_PARTIAL_WRITE |
1546 SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER |
Willy Tarreau396a1862014-11-13 14:06:52 +01001547 SSL_MODE_RELEASE_BUFFERS |
1548 SSL_MODE_SMALL_BUFFERS;
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001549 STACK_OF(SSL_CIPHER) * ciphers = NULL;
Willy Tarreaua616ba62014-10-26 06:49:19 +01001550 SSL_CIPHER * cipher = NULL;
Remi Gacognec1eab8c2014-06-12 18:20:11 +02001551 char cipher_description[128];
1552 /* The description of ciphers using an Ephemeral Diffie Hellman key exchange
1553 contains " Kx=DH " or " Kx=DH(". Beware of " Kx=DH/",
1554 which is not ephemeral DH. */
1555 const char dhe_description[] = " Kx=DH ";
1556 const char dhe_export_description[] = " Kx=DH(";
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001557 int idx = 0;
1558 int dhe_found = 0;
Remi Gacogne23d5d372014-10-10 17:04:26 +02001559 SSL *ssl = NULL;
Emeric Brunfc0421f2012-09-07 17:30:07 +02001560
Thierry Fournier383085f2013-01-24 14:15:43 +01001561 /* Make sure openssl opens /dev/urandom before the chroot */
1562 if (!ssl_initialize_random()) {
1563 Alert("OpenSSL random data generator initialization failed.\n");
1564 cfgerr++;
1565 }
1566
Emeric Brun89675492012-10-05 13:48:26 +02001567 if (bind_conf->ssl_options & BC_SSL_O_NO_SSLV3)
Emeric Brunfc0421f2012-09-07 17:30:07 +02001568 ssloptions |= SSL_OP_NO_SSLv3;
Emeric Brun89675492012-10-05 13:48:26 +02001569 if (bind_conf->ssl_options & BC_SSL_O_NO_TLSV10)
Emeric Brunfc0421f2012-09-07 17:30:07 +02001570 ssloptions |= SSL_OP_NO_TLSv1;
Emeric Brun89675492012-10-05 13:48:26 +02001571 if (bind_conf->ssl_options & BC_SSL_O_NO_TLSV11)
Emeric Brunc0ff4922012-09-28 19:37:02 +02001572 ssloptions |= SSL_OP_NO_TLSv1_1;
Emeric Brun89675492012-10-05 13:48:26 +02001573 if (bind_conf->ssl_options & BC_SSL_O_NO_TLSV12)
Emeric Brunc0ff4922012-09-28 19:37:02 +02001574 ssloptions |= SSL_OP_NO_TLSv1_2;
Emeric Brun89675492012-10-05 13:48:26 +02001575 if (bind_conf->ssl_options & BC_SSL_O_NO_TLS_TICKETS)
Emeric Brun2d0c4822012-10-02 13:45:20 +02001576 ssloptions |= SSL_OP_NO_TICKET;
Emeric Brun2cb7ae52012-10-05 14:14:21 +02001577 if (bind_conf->ssl_options & BC_SSL_O_USE_SSLV3)
1578 SSL_CTX_set_ssl_version(ctx, SSLv3_server_method());
1579 if (bind_conf->ssl_options & BC_SSL_O_USE_TLSV10)
1580 SSL_CTX_set_ssl_version(ctx, TLSv1_server_method());
1581#if SSL_OP_NO_TLSv1_1
1582 if (bind_conf->ssl_options & BC_SSL_O_USE_TLSV11)
1583 SSL_CTX_set_ssl_version(ctx, TLSv1_1_server_method());
1584#endif
1585#if SSL_OP_NO_TLSv1_2
1586 if (bind_conf->ssl_options & BC_SSL_O_USE_TLSV12)
1587 SSL_CTX_set_ssl_version(ctx, TLSv1_2_server_method());
1588#endif
Emeric Brunfc0421f2012-09-07 17:30:07 +02001589
1590 SSL_CTX_set_options(ctx, ssloptions);
1591 SSL_CTX_set_mode(ctx, sslmode);
Emeric Brun850efd52014-01-29 12:24:34 +01001592 switch (bind_conf->verify) {
1593 case SSL_SOCK_VERIFY_NONE:
1594 verify = SSL_VERIFY_NONE;
1595 break;
1596 case SSL_SOCK_VERIFY_OPTIONAL:
1597 verify = SSL_VERIFY_PEER;
1598 break;
1599 case SSL_SOCK_VERIFY_REQUIRED:
1600 verify = SSL_VERIFY_PEER|SSL_VERIFY_FAIL_IF_NO_PEER_CERT;
1601 break;
1602 }
1603 SSL_CTX_set_verify(ctx, verify, ssl_sock_bind_verifycbk);
1604 if (verify & SSL_VERIFY_PEER) {
Emeric Brunfb510ea2012-10-05 12:00:26 +02001605 if (bind_conf->ca_file) {
Emeric Brund94b3fe2012-09-20 18:23:56 +02001606 /* load CAfile to verify */
Emeric Brunfb510ea2012-10-05 12:00:26 +02001607 if (!SSL_CTX_load_verify_locations(ctx, bind_conf->ca_file, NULL)) {
Emeric Brund94b3fe2012-09-20 18:23:56 +02001608 Alert("Proxy '%s': unable to load CA file '%s' for bind '%s' at [%s:%d].\n",
Emeric Brunfb510ea2012-10-05 12:00:26 +02001609 curproxy->id, bind_conf->ca_file, bind_conf->arg, bind_conf->file, bind_conf->line);
Emeric Brund94b3fe2012-09-20 18:23:56 +02001610 cfgerr++;
1611 }
1612 /* set CA names fo client cert request, function returns void */
Emeric Brunfb510ea2012-10-05 12:00:26 +02001613 SSL_CTX_set_client_CA_list(ctx, SSL_load_client_CA_file(bind_conf->ca_file));
Emeric Brund94b3fe2012-09-20 18:23:56 +02001614 }
Emeric Brun850efd52014-01-29 12:24:34 +01001615 else {
1616 Alert("Proxy '%s': verify is enabled but no CA file specified for bind '%s' at [%s:%d].\n",
1617 curproxy->id, bind_conf->arg, bind_conf->file, bind_conf->line);
1618 cfgerr++;
1619 }
Emeric Brun051cdab2012-10-02 19:25:50 +02001620#ifdef X509_V_FLAG_CRL_CHECK
Emeric Brunfb510ea2012-10-05 12:00:26 +02001621 if (bind_conf->crl_file) {
Emeric Brund94b3fe2012-09-20 18:23:56 +02001622 X509_STORE *store = SSL_CTX_get_cert_store(ctx);
1623
Emeric Brunfb510ea2012-10-05 12:00:26 +02001624 if (!store || !X509_STORE_load_locations(store, bind_conf->crl_file, NULL)) {
Emeric Brund94b3fe2012-09-20 18:23:56 +02001625 Alert("Proxy '%s': unable to configure CRL file '%s' for bind '%s' at [%s:%d].\n",
Emeric Brunfb510ea2012-10-05 12:00:26 +02001626 curproxy->id, bind_conf->ca_file, bind_conf->arg, bind_conf->file, bind_conf->line);
Emeric Brund94b3fe2012-09-20 18:23:56 +02001627 cfgerr++;
1628 }
Emeric Brun561e5742012-10-02 15:20:55 +02001629 else {
1630 X509_STORE_set_flags(store, X509_V_FLAG_CRL_CHECK|X509_V_FLAG_CRL_CHECK_ALL);
1631 }
Emeric Brund94b3fe2012-09-20 18:23:56 +02001632 }
Emeric Brun051cdab2012-10-02 19:25:50 +02001633#endif
Emeric Brun644cde02012-12-14 11:21:13 +01001634 ERR_clear_error();
Emeric Brund94b3fe2012-09-20 18:23:56 +02001635 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02001636
Nenad Merdanovic05552d42015-02-27 19:56:49 +01001637#if (defined SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB && TLS_TICKETS_NO > 0)
1638 if(bind_conf->tls_ticket_keys) {
1639 if (!SSL_CTX_set_tlsext_ticket_key_cb(ctx, ssl_tlsext_ticket_key_cb)) {
1640 Alert("Proxy '%s': unable to set callback for TLS ticket validation for bind '%s' at [%s:%d].\n",
1641 curproxy->id, bind_conf->arg, bind_conf->file, bind_conf->line);
1642 cfgerr++;
1643 }
1644 }
1645#endif
1646
Emeric Brun4f65bff2012-11-16 15:11:00 +01001647 if (global.tune.ssllifetime)
1648 SSL_CTX_set_timeout(ctx, global.tune.ssllifetime);
1649
Emeric Brunfc0421f2012-09-07 17:30:07 +02001650 shared_context_set_cache(ctx);
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001651 if (bind_conf->ciphers &&
1652 !SSL_CTX_set_cipher_list(ctx, bind_conf->ciphers)) {
Emeric Brunfc0421f2012-09-07 17:30:07 +02001653 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 +02001654 curproxy->id, bind_conf->ciphers, bind_conf->arg, bind_conf->file, bind_conf->line);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001655 cfgerr++;
1656 }
1657
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001658 /* If tune.ssl.default-dh-param has not been set and
1659 no static DH params were in the certificate file. */
1660 if (global.tune.ssl_default_dh_param == 0) {
Lukas Tribus90132722014-08-18 00:56:33 +02001661
Remi Gacogne23d5d372014-10-10 17:04:26 +02001662 ssl = SSL_new(ctx);
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001663
Remi Gacogne23d5d372014-10-10 17:04:26 +02001664 if (ssl) {
1665 ciphers = SSL_get_ciphers(ssl);
1666
1667 if (ciphers) {
1668 for (idx = 0; idx < sk_SSL_CIPHER_num(ciphers); idx++) {
1669 cipher = sk_SSL_CIPHER_value(ciphers, idx);
1670 if (SSL_CIPHER_description(cipher, cipher_description, sizeof (cipher_description)) == cipher_description) {
1671 if (strstr(cipher_description, dhe_description) != NULL ||
1672 strstr(cipher_description, dhe_export_description) != NULL) {
1673 dhe_found = 1;
1674 break;
1675 }
Remi Gacognec1eab8c2014-06-12 18:20:11 +02001676 }
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001677 }
1678 }
Remi Gacogne23d5d372014-10-10 17:04:26 +02001679 SSL_free(ssl);
1680 ssl = NULL;
Lukas Tribus90132722014-08-18 00:56:33 +02001681 }
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001682
Lukas Tribus90132722014-08-18 00:56:33 +02001683 if (dhe_found) {
1684 Warning("Setting tune.ssl.default-dh-param to 1024 by default, if your workload permits it you should set it to at least 2048. Please set a value >= 1024 to make this warning disappear.\n");
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001685 }
1686
1687 global.tune.ssl_default_dh_param = 1024;
1688 }
Remi Gacogne8de54152014-07-15 11:36:40 +02001689
1690#ifndef OPENSSL_NO_DH
1691 if (global.tune.ssl_default_dh_param >= 1024) {
1692 if (local_dh_1024 == NULL) {
1693 local_dh_1024 = ssl_get_dh_1024();
1694 }
1695 if (global.tune.ssl_default_dh_param >= 2048) {
1696 if (local_dh_2048 == NULL) {
1697 local_dh_2048 = ssl_get_dh_2048();
1698 }
1699 if (global.tune.ssl_default_dh_param >= 4096) {
1700 if (local_dh_4096 == NULL) {
1701 local_dh_4096 = ssl_get_dh_4096();
1702 }
1703 if (global.tune.ssl_default_dh_param >= 8192 &&
1704 local_dh_8192 == NULL) {
1705 local_dh_8192 = ssl_get_dh_8192();
1706 }
1707 }
1708 }
1709 }
1710#endif /* OPENSSL_NO_DH */
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001711
Emeric Brunfc0421f2012-09-07 17:30:07 +02001712 SSL_CTX_set_info_callback(ctx, ssl_sock_infocbk);
Willy Tarreau5cbe4ef2014-05-08 22:45:11 +02001713#if OPENSSL_VERSION_NUMBER >= 0x00907000L
Emeric Brun29f037d2014-04-25 19:05:36 +02001714 SSL_CTX_set_msg_callback(ctx, ssl_sock_msgcbk);
Willy Tarreau5cbe4ef2014-05-08 22:45:11 +02001715#endif
Emeric Brun29f037d2014-04-25 19:05:36 +02001716
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02001717#ifdef OPENSSL_NPN_NEGOTIATED
1718 if (bind_conf->npn_str)
1719 SSL_CTX_set_next_protos_advertised_cb(ctx, ssl_sock_advertise_npn_protos, bind_conf);
1720#endif
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01001721#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Willy Tarreauab861d32013-04-02 02:30:41 +02001722 if (bind_conf->alpn_str)
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01001723 SSL_CTX_set_alpn_select_cb(ctx, ssl_sock_advertise_alpn_protos, bind_conf);
Willy Tarreauab861d32013-04-02 02:30:41 +02001724#endif
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02001725
Emeric Brunfc0421f2012-09-07 17:30:07 +02001726#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
1727 SSL_CTX_set_tlsext_servername_callback(ctx, ssl_sock_switchctx_cbk);
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001728 SSL_CTX_set_tlsext_servername_arg(ctx, bind_conf);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001729#endif
Emeric Brun2b58d042012-09-20 17:10:03 +02001730#if defined(SSL_CTX_set_tmp_ecdh) && !defined(OPENSSL_NO_ECDH)
Emeric Brun6924ef82013-03-06 14:08:53 +01001731 {
Emeric Brun2b58d042012-09-20 17:10:03 +02001732 int i;
1733 EC_KEY *ecdh;
1734
Emeric Brun6924ef82013-03-06 14:08:53 +01001735 i = OBJ_sn2nid(bind_conf->ecdhe ? bind_conf->ecdhe : ECDHE_DEFAULT_CURVE);
Emeric Brun2b58d042012-09-20 17:10:03 +02001736 if (!i || ((ecdh = EC_KEY_new_by_curve_name(i)) == NULL)) {
1737 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 +01001738 curproxy->id, bind_conf->ecdhe ? bind_conf->ecdhe : ECDHE_DEFAULT_CURVE,
1739 bind_conf->arg, bind_conf->file, bind_conf->line);
Emeric Brun2b58d042012-09-20 17:10:03 +02001740 cfgerr++;
1741 }
1742 else {
1743 SSL_CTX_set_tmp_ecdh(ctx, ecdh);
1744 EC_KEY_free(ecdh);
1745 }
1746 }
1747#endif
1748
Emeric Brunfc0421f2012-09-07 17:30:07 +02001749 return cfgerr;
1750}
1751
Evan Broderbe554312013-06-27 00:05:25 -07001752static int ssl_sock_srv_hostcheck(const char *pattern, const char *hostname)
1753{
1754 const char *pattern_wildcard, *pattern_left_label_end, *hostname_left_label_end;
1755 size_t prefixlen, suffixlen;
1756
1757 /* Trivial case */
1758 if (strcmp(pattern, hostname) == 0)
1759 return 1;
1760
Evan Broderbe554312013-06-27 00:05:25 -07001761 /* The rest of this logic is based on RFC 6125, section 6.4.3
1762 * (http://tools.ietf.org/html/rfc6125#section-6.4.3) */
1763
Emeric Bruna848dae2013-10-08 11:27:28 +02001764 pattern_wildcard = NULL;
1765 pattern_left_label_end = pattern;
1766 while (*pattern_left_label_end != '.') {
1767 switch (*pattern_left_label_end) {
1768 case 0:
1769 /* End of label not found */
1770 return 0;
1771 case '*':
1772 /* If there is more than one wildcards */
1773 if (pattern_wildcard)
1774 return 0;
1775 pattern_wildcard = pattern_left_label_end;
1776 break;
1777 }
1778 pattern_left_label_end++;
1779 }
1780
1781 /* If it's not trivial and there is no wildcard, it can't
1782 * match */
1783 if (!pattern_wildcard)
Evan Broderbe554312013-06-27 00:05:25 -07001784 return 0;
1785
1786 /* Make sure all labels match except the leftmost */
1787 hostname_left_label_end = strchr(hostname, '.');
1788 if (!hostname_left_label_end
1789 || strcmp(pattern_left_label_end, hostname_left_label_end) != 0)
1790 return 0;
1791
1792 /* Make sure the leftmost label of the hostname is long enough
1793 * that the wildcard can match */
Emeric Brun369da852013-10-08 11:39:35 +02001794 if (hostname_left_label_end - hostname < (pattern_left_label_end - pattern) - 1)
Evan Broderbe554312013-06-27 00:05:25 -07001795 return 0;
1796
1797 /* Finally compare the string on either side of the
1798 * wildcard */
1799 prefixlen = pattern_wildcard - pattern;
1800 suffixlen = pattern_left_label_end - (pattern_wildcard + 1);
Emeric Bruna848dae2013-10-08 11:27:28 +02001801 if ((prefixlen && (memcmp(pattern, hostname, prefixlen) != 0))
1802 || (suffixlen && (memcmp(pattern_wildcard + 1, hostname_left_label_end - suffixlen, suffixlen) != 0)))
Evan Broderbe554312013-06-27 00:05:25 -07001803 return 0;
1804
1805 return 1;
1806}
1807
1808static int ssl_sock_srv_verifycbk(int ok, X509_STORE_CTX *ctx)
1809{
1810 SSL *ssl;
1811 struct connection *conn;
1812 char *servername;
1813
1814 int depth;
1815 X509 *cert;
1816 STACK_OF(GENERAL_NAME) *alt_names;
1817 int i;
1818 X509_NAME *cert_subject;
1819 char *str;
1820
1821 if (ok == 0)
1822 return ok;
1823
1824 ssl = X509_STORE_CTX_get_ex_data(ctx, SSL_get_ex_data_X509_STORE_CTX_idx());
1825 conn = (struct connection *)SSL_get_app_data(ssl);
1826
1827 servername = objt_server(conn->target)->ssl_ctx.verify_host;
1828
1829 /* We only need to verify the CN on the actual server cert,
1830 * not the indirect CAs */
1831 depth = X509_STORE_CTX_get_error_depth(ctx);
1832 if (depth != 0)
1833 return ok;
1834
1835 /* At this point, the cert is *not* OK unless we can find a
1836 * hostname match */
1837 ok = 0;
1838
1839 cert = X509_STORE_CTX_get_current_cert(ctx);
1840 /* It seems like this might happen if verify peer isn't set */
1841 if (!cert)
1842 return ok;
1843
1844 alt_names = X509_get_ext_d2i(cert, NID_subject_alt_name, NULL, NULL);
1845 if (alt_names) {
1846 for (i = 0; !ok && i < sk_GENERAL_NAME_num(alt_names); i++) {
1847 GENERAL_NAME *name = sk_GENERAL_NAME_value(alt_names, i);
1848 if (name->type == GEN_DNS) {
Emeric Bruna33410c2013-09-17 15:47:48 +02001849#if OPENSSL_VERSION_NUMBER < 0x00907000L
1850 if (ASN1_STRING_to_UTF8((unsigned char **)&str, name->d.ia5) >= 0) {
1851#else
Evan Broderbe554312013-06-27 00:05:25 -07001852 if (ASN1_STRING_to_UTF8((unsigned char **)&str, name->d.dNSName) >= 0) {
Emeric Bruna33410c2013-09-17 15:47:48 +02001853#endif
Evan Broderbe554312013-06-27 00:05:25 -07001854 ok = ssl_sock_srv_hostcheck(str, servername);
1855 OPENSSL_free(str);
1856 }
1857 }
1858 }
Emeric Brun4ad50a42013-09-17 15:19:54 +02001859 sk_GENERAL_NAME_pop_free(alt_names, GENERAL_NAME_free);
Evan Broderbe554312013-06-27 00:05:25 -07001860 }
1861
1862 cert_subject = X509_get_subject_name(cert);
1863 i = -1;
1864 while (!ok && (i = X509_NAME_get_index_by_NID(cert_subject, NID_commonName, i)) != -1) {
1865 X509_NAME_ENTRY *entry = X509_NAME_get_entry(cert_subject, i);
1866 if (ASN1_STRING_to_UTF8((unsigned char **)&str, entry->value) >= 0) {
1867 ok = ssl_sock_srv_hostcheck(str, servername);
1868 OPENSSL_free(str);
1869 }
1870 }
1871
1872 return ok;
1873}
1874
Emeric Brun94324a42012-10-11 14:00:19 +02001875/* prepare ssl context from servers options. Returns an error count */
1876int ssl_sock_prepare_srv_ctx(struct server *srv, struct proxy *curproxy)
1877{
1878 int cfgerr = 0;
Remi Gacogneaf5c3da2014-05-19 10:29:58 +02001879 long options =
Emeric Brun94324a42012-10-11 14:00:19 +02001880 SSL_OP_ALL | /* all known workarounds for bugs */
1881 SSL_OP_NO_SSLv2 |
1882 SSL_OP_NO_COMPRESSION;
Remi Gacogneaf5c3da2014-05-19 10:29:58 +02001883 long mode =
Emeric Brun94324a42012-10-11 14:00:19 +02001884 SSL_MODE_ENABLE_PARTIAL_WRITE |
1885 SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER |
Willy Tarreau396a1862014-11-13 14:06:52 +01001886 SSL_MODE_RELEASE_BUFFERS |
1887 SSL_MODE_SMALL_BUFFERS;
Emeric Brun850efd52014-01-29 12:24:34 +01001888 int verify = SSL_VERIFY_NONE;
Emeric Brun94324a42012-10-11 14:00:19 +02001889
Thierry Fournier383085f2013-01-24 14:15:43 +01001890 /* Make sure openssl opens /dev/urandom before the chroot */
1891 if (!ssl_initialize_random()) {
1892 Alert("OpenSSL random data generator initialization failed.\n");
1893 cfgerr++;
1894 }
1895
Willy Tarreaufce03112015-01-15 21:32:40 +01001896 /* Automatic memory computations need to know we use SSL there */
1897 global.ssl_used_backend = 1;
1898
1899 /* Initiate SSL context for current server */
Emeric Brun94324a42012-10-11 14:00:19 +02001900 srv->ssl_ctx.reused_sess = NULL;
1901 if (srv->use_ssl)
1902 srv->xprt = &ssl_sock;
1903 if (srv->check.use_ssl)
Cyril Bonté9ce13112014-11-15 22:41:27 +01001904 srv->check.xprt = &ssl_sock;
Emeric Brun94324a42012-10-11 14:00:19 +02001905
1906 srv->ssl_ctx.ctx = SSL_CTX_new(SSLv23_client_method());
1907 if (!srv->ssl_ctx.ctx) {
1908 Alert("config : %s '%s', server '%s': unable to allocate ssl context.\n",
1909 proxy_type_str(curproxy), curproxy->id,
1910 srv->id);
1911 cfgerr++;
1912 return cfgerr;
1913 }
Emeric Bruna7aa3092012-10-26 12:58:00 +02001914 if (srv->ssl_ctx.client_crt) {
1915 if (SSL_CTX_use_PrivateKey_file(srv->ssl_ctx.ctx, srv->ssl_ctx.client_crt, SSL_FILETYPE_PEM) <= 0) {
1916 Alert("config : %s '%s', server '%s': unable to load SSL private key from PEM file '%s'.\n",
1917 proxy_type_str(curproxy), curproxy->id,
1918 srv->id, srv->ssl_ctx.client_crt);
1919 cfgerr++;
1920 }
1921 else if (SSL_CTX_use_certificate_chain_file(srv->ssl_ctx.ctx, srv->ssl_ctx.client_crt) <= 0) {
1922 Alert("config : %s '%s', server '%s': unable to load ssl certificate from PEM file '%s'.\n",
1923 proxy_type_str(curproxy), curproxy->id,
1924 srv->id, srv->ssl_ctx.client_crt);
1925 cfgerr++;
1926 }
1927 else if (SSL_CTX_check_private_key(srv->ssl_ctx.ctx) <= 0) {
1928 Alert("config : %s '%s', server '%s': inconsistencies between private key and certificate loaded from PEM file '%s'.\n",
1929 proxy_type_str(curproxy), curproxy->id,
1930 srv->id, srv->ssl_ctx.client_crt);
1931 cfgerr++;
1932 }
1933 }
Emeric Brun94324a42012-10-11 14:00:19 +02001934
1935 if (srv->ssl_ctx.options & SRV_SSL_O_NO_SSLV3)
1936 options |= SSL_OP_NO_SSLv3;
1937 if (srv->ssl_ctx.options & SRV_SSL_O_NO_TLSV10)
1938 options |= SSL_OP_NO_TLSv1;
1939 if (srv->ssl_ctx.options & SRV_SSL_O_NO_TLSV11)
1940 options |= SSL_OP_NO_TLSv1_1;
1941 if (srv->ssl_ctx.options & SRV_SSL_O_NO_TLSV12)
1942 options |= SSL_OP_NO_TLSv1_2;
Emeric Brunf9c5c472012-10-11 15:28:34 +02001943 if (srv->ssl_ctx.options & SRV_SSL_O_NO_TLS_TICKETS)
1944 options |= SSL_OP_NO_TICKET;
Emeric Brun94324a42012-10-11 14:00:19 +02001945 if (srv->ssl_ctx.options & SRV_SSL_O_USE_SSLV3)
1946 SSL_CTX_set_ssl_version(srv->ssl_ctx.ctx, SSLv3_client_method());
1947 if (srv->ssl_ctx.options & SRV_SSL_O_USE_TLSV10)
1948 SSL_CTX_set_ssl_version(srv->ssl_ctx.ctx, TLSv1_client_method());
1949#if SSL_OP_NO_TLSv1_1
1950 if (srv->ssl_ctx.options & SRV_SSL_O_USE_TLSV11)
1951 SSL_CTX_set_ssl_version(srv->ssl_ctx.ctx, TLSv1_1_client_method());
1952#endif
1953#if SSL_OP_NO_TLSv1_2
1954 if (srv->ssl_ctx.options & SRV_SSL_O_USE_TLSV12)
1955 SSL_CTX_set_ssl_version(srv->ssl_ctx.ctx, TLSv1_2_client_method());
1956#endif
1957
1958 SSL_CTX_set_options(srv->ssl_ctx.ctx, options);
1959 SSL_CTX_set_mode(srv->ssl_ctx.ctx, mode);
Emeric Brun850efd52014-01-29 12:24:34 +01001960
1961 if (global.ssl_server_verify == SSL_SERVER_VERIFY_REQUIRED)
1962 verify = SSL_VERIFY_PEER;
1963
1964 switch (srv->ssl_ctx.verify) {
1965 case SSL_SOCK_VERIFY_NONE:
1966 verify = SSL_VERIFY_NONE;
1967 break;
1968 case SSL_SOCK_VERIFY_REQUIRED:
1969 verify = SSL_VERIFY_PEER;
1970 break;
1971 }
Evan Broderbe554312013-06-27 00:05:25 -07001972 SSL_CTX_set_verify(srv->ssl_ctx.ctx,
Emeric Brun850efd52014-01-29 12:24:34 +01001973 verify,
Evan Broderbe554312013-06-27 00:05:25 -07001974 srv->ssl_ctx.verify_host ? ssl_sock_srv_verifycbk : NULL);
Emeric Brun850efd52014-01-29 12:24:34 +01001975 if (verify & SSL_VERIFY_PEER) {
Emeric Brunef42d922012-10-11 16:11:36 +02001976 if (srv->ssl_ctx.ca_file) {
1977 /* load CAfile to verify */
1978 if (!SSL_CTX_load_verify_locations(srv->ssl_ctx.ctx, srv->ssl_ctx.ca_file, NULL)) {
Willy Tarreau07ba08b2014-02-16 19:22:08 +01001979 Alert("Proxy '%s', server '%s' [%s:%d] unable to load CA file '%s'.\n",
Emeric Brunef42d922012-10-11 16:11:36 +02001980 curproxy->id, srv->id,
1981 srv->conf.file, srv->conf.line, srv->ssl_ctx.ca_file);
1982 cfgerr++;
1983 }
1984 }
Emeric Brun850efd52014-01-29 12:24:34 +01001985 else {
1986 if (global.ssl_server_verify == SSL_SERVER_VERIFY_REQUIRED)
Willy Tarreau07ba08b2014-02-16 19:22:08 +01001987 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 +01001988 curproxy->id, srv->id,
1989 srv->conf.file, srv->conf.line);
1990 else
Willy Tarreau07ba08b2014-02-16 19:22:08 +01001991 Alert("Proxy '%s', server '%s' [%s:%d] verify is enabled but no CA file specified.\n",
Emeric Brun850efd52014-01-29 12:24:34 +01001992 curproxy->id, srv->id,
1993 srv->conf.file, srv->conf.line);
1994 cfgerr++;
1995 }
Emeric Brunef42d922012-10-11 16:11:36 +02001996#ifdef X509_V_FLAG_CRL_CHECK
1997 if (srv->ssl_ctx.crl_file) {
1998 X509_STORE *store = SSL_CTX_get_cert_store(srv->ssl_ctx.ctx);
1999
2000 if (!store || !X509_STORE_load_locations(store, srv->ssl_ctx.crl_file, NULL)) {
Willy Tarreau07ba08b2014-02-16 19:22:08 +01002001 Alert("Proxy '%s', server '%s' [%s:%d] unable to configure CRL file '%s'.\n",
Emeric Brunef42d922012-10-11 16:11:36 +02002002 curproxy->id, srv->id,
2003 srv->conf.file, srv->conf.line, srv->ssl_ctx.crl_file);
2004 cfgerr++;
2005 }
2006 else {
2007 X509_STORE_set_flags(store, X509_V_FLAG_CRL_CHECK|X509_V_FLAG_CRL_CHECK_ALL);
2008 }
2009 }
2010#endif
2011 }
2012
Emeric Brun4f65bff2012-11-16 15:11:00 +01002013 if (global.tune.ssllifetime)
2014 SSL_CTX_set_timeout(srv->ssl_ctx.ctx, global.tune.ssllifetime);
2015
Emeric Brun94324a42012-10-11 14:00:19 +02002016 SSL_CTX_set_session_cache_mode(srv->ssl_ctx.ctx, SSL_SESS_CACHE_OFF);
2017 if (srv->ssl_ctx.ciphers &&
2018 !SSL_CTX_set_cipher_list(srv->ssl_ctx.ctx, srv->ssl_ctx.ciphers)) {
2019 Alert("Proxy '%s', server '%s' [%s:%d] : unable to set SSL cipher list to '%s'.\n",
2020 curproxy->id, srv->id,
2021 srv->conf.file, srv->conf.line, srv->ssl_ctx.ciphers);
2022 cfgerr++;
2023 }
2024
2025 return cfgerr;
2026}
2027
Willy Tarreau2a65ff02012-09-13 17:54:29 +02002028/* Walks down the two trees in bind_conf and prepares all certs. The pointer may
Emeric Brunfc0421f2012-09-07 17:30:07 +02002029 * be NULL, in which case nothing is done. Returns the number of errors
2030 * encountered.
2031 */
Willy Tarreau2a65ff02012-09-13 17:54:29 +02002032int ssl_sock_prepare_all_ctx(struct bind_conf *bind_conf, struct proxy *px)
Emeric Brunfc0421f2012-09-07 17:30:07 +02002033{
2034 struct ebmb_node *node;
2035 struct sni_ctx *sni;
2036 int err = 0;
2037
Willy Tarreau2a65ff02012-09-13 17:54:29 +02002038 if (!bind_conf || !bind_conf->is_ssl)
Emeric Brunfc0421f2012-09-07 17:30:07 +02002039 return 0;
2040
Willy Tarreaufce03112015-01-15 21:32:40 +01002041 /* Automatic memory computations need to know we use SSL there */
2042 global.ssl_used_frontend = 1;
2043
Emeric Brun0bed9942014-10-30 19:25:24 +01002044 if (bind_conf->default_ctx)
2045 err += ssl_sock_prepare_ctx(bind_conf, bind_conf->default_ctx, px);
2046
Willy Tarreau2a65ff02012-09-13 17:54:29 +02002047 node = ebmb_first(&bind_conf->sni_ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002048 while (node) {
2049 sni = ebmb_entry(node, struct sni_ctx, name);
Emeric Brun0bed9942014-10-30 19:25:24 +01002050 if (!sni->order && sni->ctx != bind_conf->default_ctx)
2051 /* only initialize the CTX on its first occurrence and
2052 if it is not the default_ctx */
Willy Tarreau2a65ff02012-09-13 17:54:29 +02002053 err += ssl_sock_prepare_ctx(bind_conf, sni->ctx, px);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002054 node = ebmb_next(node);
2055 }
2056
Willy Tarreau2a65ff02012-09-13 17:54:29 +02002057 node = ebmb_first(&bind_conf->sni_w_ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002058 while (node) {
2059 sni = ebmb_entry(node, struct sni_ctx, name);
Emeric Brun0bed9942014-10-30 19:25:24 +01002060 if (!sni->order && sni->ctx != bind_conf->default_ctx)
2061 /* only initialize the CTX on its first occurrence and
2062 if it is not the default_ctx */
Willy Tarreau2a65ff02012-09-13 17:54:29 +02002063 err += ssl_sock_prepare_ctx(bind_conf, sni->ctx, px);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002064 node = ebmb_next(node);
2065 }
2066 return err;
2067}
2068
Willy Tarreau2a65ff02012-09-13 17:54:29 +02002069/* Walks down the two trees in bind_conf and frees all the certs. The pointer may
Emeric Brunfc0421f2012-09-07 17:30:07 +02002070 * be NULL, in which case nothing is done. The default_ctx is nullified too.
2071 */
Willy Tarreau2a65ff02012-09-13 17:54:29 +02002072void ssl_sock_free_all_ctx(struct bind_conf *bind_conf)
Emeric Brunfc0421f2012-09-07 17:30:07 +02002073{
2074 struct ebmb_node *node, *back;
2075 struct sni_ctx *sni;
2076
Willy Tarreau2a65ff02012-09-13 17:54:29 +02002077 if (!bind_conf || !bind_conf->is_ssl)
Emeric Brunfc0421f2012-09-07 17:30:07 +02002078 return;
2079
Willy Tarreau2a65ff02012-09-13 17:54:29 +02002080 node = ebmb_first(&bind_conf->sni_ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002081 while (node) {
2082 sni = ebmb_entry(node, struct sni_ctx, name);
2083 back = ebmb_next(node);
2084 ebmb_delete(node);
2085 if (!sni->order) /* only free the CTX on its first occurrence */
2086 SSL_CTX_free(sni->ctx);
2087 free(sni);
2088 node = back;
2089 }
2090
Willy Tarreau2a65ff02012-09-13 17:54:29 +02002091 node = ebmb_first(&bind_conf->sni_w_ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002092 while (node) {
2093 sni = ebmb_entry(node, struct sni_ctx, name);
2094 back = ebmb_next(node);
2095 ebmb_delete(node);
2096 if (!sni->order) /* only free the CTX on its first occurrence */
2097 SSL_CTX_free(sni->ctx);
2098 free(sni);
2099 node = back;
2100 }
2101
Willy Tarreau2a65ff02012-09-13 17:54:29 +02002102 bind_conf->default_ctx = NULL;
Emeric Brune1f38db2012-09-03 20:36:47 +02002103}
2104
Emeric Brun46591952012-05-18 15:47:34 +02002105/*
2106 * This function is called if SSL * context is not yet allocated. The function
2107 * is designed to be called before any other data-layer operation and sets the
2108 * handshake flag on the connection. It is safe to call it multiple times.
2109 * It returns 0 on success and -1 in error case.
2110 */
2111static int ssl_sock_init(struct connection *conn)
2112{
2113 /* already initialized */
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02002114 if (conn->xprt_ctx)
Emeric Brun46591952012-05-18 15:47:34 +02002115 return 0;
2116
Willy Tarreau3c728722014-01-23 13:50:42 +01002117 if (!conn_ctrl_ready(conn))
Willy Tarreauf79c8172013-10-21 16:30:56 +02002118 return 0;
2119
Willy Tarreau20879a02012-12-03 16:32:10 +01002120 if (global.maxsslconn && sslconns >= global.maxsslconn) {
2121 conn->err_code = CO_ER_SSL_TOO_MANY;
Willy Tarreau403edff2012-09-06 11:58:37 +02002122 return -1;
Willy Tarreau20879a02012-12-03 16:32:10 +01002123 }
Willy Tarreau403edff2012-09-06 11:58:37 +02002124
Emeric Brun46591952012-05-18 15:47:34 +02002125 /* If it is in client mode initiate SSL session
2126 in connect state otherwise accept state */
Willy Tarreau3fdb3662012-11-12 00:42:33 +01002127 if (objt_server(conn->target)) {
Willy Tarreaufba03cd2014-11-13 13:48:58 +01002128 int may_retry = 1;
2129
2130 retry_connect:
Emeric Brun46591952012-05-18 15:47:34 +02002131 /* Alloc a new SSL session ctx */
Willy Tarreau3fdb3662012-11-12 00:42:33 +01002132 conn->xprt_ctx = SSL_new(objt_server(conn->target)->ssl_ctx.ctx);
Willy Tarreau20879a02012-12-03 16:32:10 +01002133 if (!conn->xprt_ctx) {
Willy Tarreaufba03cd2014-11-13 13:48:58 +01002134 if (may_retry--) {
2135 pool_gc2();
2136 goto retry_connect;
2137 }
Willy Tarreau20879a02012-12-03 16:32:10 +01002138 conn->err_code = CO_ER_SSL_NO_MEM;
Emeric Brun46591952012-05-18 15:47:34 +02002139 return -1;
Willy Tarreau20879a02012-12-03 16:32:10 +01002140 }
Emeric Brun46591952012-05-18 15:47:34 +02002141
Emeric Brun46591952012-05-18 15:47:34 +02002142 /* set fd on SSL session context */
Emeric Brun55476152014-11-12 17:35:37 +01002143 if (!SSL_set_fd(conn->xprt_ctx, conn->t.sock.fd)) {
2144 SSL_free(conn->xprt_ctx);
2145 conn->xprt_ctx = NULL;
Willy Tarreaufba03cd2014-11-13 13:48:58 +01002146 if (may_retry--) {
2147 pool_gc2();
2148 goto retry_connect;
2149 }
Emeric Brun55476152014-11-12 17:35:37 +01002150 conn->err_code = CO_ER_SSL_NO_MEM;
2151 return -1;
2152 }
Emeric Brun46591952012-05-18 15:47:34 +02002153
Evan Broderbe554312013-06-27 00:05:25 -07002154 /* set connection pointer */
Emeric Brun55476152014-11-12 17:35:37 +01002155 if (!SSL_set_app_data(conn->xprt_ctx, conn)) {
2156 SSL_free(conn->xprt_ctx);
2157 conn->xprt_ctx = NULL;
Willy Tarreaufba03cd2014-11-13 13:48:58 +01002158 if (may_retry--) {
2159 pool_gc2();
2160 goto retry_connect;
2161 }
Emeric Brun55476152014-11-12 17:35:37 +01002162 conn->err_code = CO_ER_SSL_NO_MEM;
2163 return -1;
2164 }
2165
2166 SSL_set_connect_state(conn->xprt_ctx);
2167 if (objt_server(conn->target)->ssl_ctx.reused_sess) {
2168 if(!SSL_set_session(conn->xprt_ctx, objt_server(conn->target)->ssl_ctx.reused_sess)) {
2169 SSL_SESSION_free(objt_server(conn->target)->ssl_ctx.reused_sess);
2170 objt_server(conn->target)->ssl_ctx.reused_sess = NULL;
2171 }
2172 }
Evan Broderbe554312013-06-27 00:05:25 -07002173
Emeric Brun46591952012-05-18 15:47:34 +02002174 /* leave init state and start handshake */
Willy Tarreau05737472012-09-04 08:03:39 +02002175 conn->flags |= CO_FL_SSL_WAIT_HS | CO_FL_WAIT_L6_CONN;
Willy Tarreau403edff2012-09-06 11:58:37 +02002176
2177 sslconns++;
Willy Tarreau71b734c2014-01-28 15:19:44 +01002178 totalsslconns++;
Emeric Brun46591952012-05-18 15:47:34 +02002179 return 0;
2180 }
Willy Tarreau3fdb3662012-11-12 00:42:33 +01002181 else if (objt_listener(conn->target)) {
Willy Tarreaufba03cd2014-11-13 13:48:58 +01002182 int may_retry = 1;
2183
2184 retry_accept:
Emeric Brun46591952012-05-18 15:47:34 +02002185 /* Alloc a new SSL session ctx */
Willy Tarreau3fdb3662012-11-12 00:42:33 +01002186 conn->xprt_ctx = SSL_new(objt_listener(conn->target)->bind_conf->default_ctx);
Willy Tarreau20879a02012-12-03 16:32:10 +01002187 if (!conn->xprt_ctx) {
Willy Tarreaufba03cd2014-11-13 13:48:58 +01002188 if (may_retry--) {
2189 pool_gc2();
2190 goto retry_accept;
2191 }
Willy Tarreau20879a02012-12-03 16:32:10 +01002192 conn->err_code = CO_ER_SSL_NO_MEM;
Emeric Brun46591952012-05-18 15:47:34 +02002193 return -1;
Willy Tarreau20879a02012-12-03 16:32:10 +01002194 }
Emeric Brun46591952012-05-18 15:47:34 +02002195
Emeric Brun46591952012-05-18 15:47:34 +02002196 /* set fd on SSL session context */
Emeric Brun55476152014-11-12 17:35:37 +01002197 if (!SSL_set_fd(conn->xprt_ctx, conn->t.sock.fd)) {
2198 SSL_free(conn->xprt_ctx);
2199 conn->xprt_ctx = NULL;
Willy Tarreaufba03cd2014-11-13 13:48:58 +01002200 if (may_retry--) {
2201 pool_gc2();
2202 goto retry_accept;
2203 }
Emeric Brun55476152014-11-12 17:35:37 +01002204 conn->err_code = CO_ER_SSL_NO_MEM;
2205 return -1;
2206 }
Emeric Brun46591952012-05-18 15:47:34 +02002207
Emeric Brune1f38db2012-09-03 20:36:47 +02002208 /* set connection pointer */
Emeric Brun55476152014-11-12 17:35:37 +01002209 if (!SSL_set_app_data(conn->xprt_ctx, conn)) {
2210 SSL_free(conn->xprt_ctx);
2211 conn->xprt_ctx = NULL;
Willy Tarreaufba03cd2014-11-13 13:48:58 +01002212 if (may_retry--) {
2213 pool_gc2();
2214 goto retry_accept;
2215 }
Emeric Brun55476152014-11-12 17:35:37 +01002216 conn->err_code = CO_ER_SSL_NO_MEM;
2217 return -1;
2218 }
2219
2220 SSL_set_accept_state(conn->xprt_ctx);
Emeric Brune1f38db2012-09-03 20:36:47 +02002221
Emeric Brun46591952012-05-18 15:47:34 +02002222 /* leave init state and start handshake */
Willy Tarreau05737472012-09-04 08:03:39 +02002223 conn->flags |= CO_FL_SSL_WAIT_HS | CO_FL_WAIT_L6_CONN;
Willy Tarreau403edff2012-09-06 11:58:37 +02002224
2225 sslconns++;
Willy Tarreau71b734c2014-01-28 15:19:44 +01002226 totalsslconns++;
Emeric Brun46591952012-05-18 15:47:34 +02002227 return 0;
2228 }
2229 /* don't know how to handle such a target */
Willy Tarreau20879a02012-12-03 16:32:10 +01002230 conn->err_code = CO_ER_SSL_NO_TARGET;
Emeric Brun46591952012-05-18 15:47:34 +02002231 return -1;
2232}
2233
2234
2235/* This is the callback which is used when an SSL handshake is pending. It
2236 * updates the FD status if it wants some polling before being called again.
2237 * It returns 0 if it fails in a fatal way or needs to poll to go further,
2238 * otherwise it returns non-zero and removes itself from the connection's
2239 * flags (the bit is provided in <flag> by the caller).
2240 */
2241int ssl_sock_handshake(struct connection *conn, unsigned int flag)
2242{
2243 int ret;
2244
Willy Tarreau3c728722014-01-23 13:50:42 +01002245 if (!conn_ctrl_ready(conn))
Willy Tarreauf79c8172013-10-21 16:30:56 +02002246 return 0;
2247
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02002248 if (!conn->xprt_ctx)
Emeric Brun46591952012-05-18 15:47:34 +02002249 goto out_error;
2250
Emeric Brun674b7432012-11-08 19:21:55 +01002251 /* If we use SSL_do_handshake to process a reneg initiated by
2252 * the remote peer, it sometimes returns SSL_ERROR_SSL.
2253 * Usually SSL_write and SSL_read are used and process implicitly
2254 * the reneg handshake.
2255 * Here we use SSL_peek as a workaround for reneg.
2256 */
2257 if ((conn->flags & CO_FL_CONNECTED) && SSL_renegotiate_pending(conn->xprt_ctx)) {
2258 char c;
2259
2260 ret = SSL_peek(conn->xprt_ctx, &c, 1);
2261 if (ret <= 0) {
2262 /* handshake may have not been completed, let's find why */
2263 ret = SSL_get_error(conn->xprt_ctx, ret);
2264 if (ret == SSL_ERROR_WANT_WRITE) {
2265 /* SSL handshake needs to write, L4 connection may not be ready */
2266 __conn_sock_stop_recv(conn);
Willy Tarreaue1f50c42014-01-22 20:02:06 +01002267 __conn_sock_want_send(conn);
2268 fd_cant_send(conn->t.sock.fd);
Emeric Brun674b7432012-11-08 19:21:55 +01002269 return 0;
2270 }
2271 else if (ret == SSL_ERROR_WANT_READ) {
2272 /* handshake may have been completed but we have
2273 * no more data to read.
2274 */
2275 if (!SSL_renegotiate_pending(conn->xprt_ctx)) {
2276 ret = 1;
2277 goto reneg_ok;
2278 }
2279 /* SSL handshake needs to read, L4 connection is ready */
2280 if (conn->flags & CO_FL_WAIT_L4_CONN)
2281 conn->flags &= ~CO_FL_WAIT_L4_CONN;
2282 __conn_sock_stop_send(conn);
Willy Tarreaue1f50c42014-01-22 20:02:06 +01002283 __conn_sock_want_recv(conn);
2284 fd_cant_recv(conn->t.sock.fd);
Emeric Brun674b7432012-11-08 19:21:55 +01002285 return 0;
2286 }
2287 else if (ret == SSL_ERROR_SYSCALL) {
2288 /* if errno is null, then connection was successfully established */
2289 if (!errno && conn->flags & CO_FL_WAIT_L4_CONN)
2290 conn->flags &= ~CO_FL_WAIT_L4_CONN;
Willy Tarreau20879a02012-12-03 16:32:10 +01002291 if (!conn->err_code) {
Emeric Brun29f037d2014-04-25 19:05:36 +02002292 if (!((SSL *)conn->xprt_ctx)->packet_length) {
2293 if (!errno) {
2294 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
2295 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
2296 else
2297 conn->err_code = CO_ER_SSL_EMPTY;
2298 }
2299 else {
2300 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
2301 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
2302 else
2303 conn->err_code = CO_ER_SSL_ABORT;
2304 }
2305 }
2306 else {
2307 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
2308 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
Willy Tarreau20879a02012-12-03 16:32:10 +01002309 else
Emeric Brun29f037d2014-04-25 19:05:36 +02002310 conn->err_code = CO_ER_SSL_HANDSHAKE;
2311 }
Willy Tarreau20879a02012-12-03 16:32:10 +01002312 }
Emeric Brun674b7432012-11-08 19:21:55 +01002313 goto out_error;
2314 }
2315 else {
2316 /* Fail on all other handshake errors */
2317 /* Note: OpenSSL may leave unread bytes in the socket's
2318 * buffer, causing an RST to be emitted upon close() on
2319 * TCP sockets. We first try to drain possibly pending
2320 * data to avoid this as much as possible.
2321 */
Willy Tarreau46be2e52014-01-20 12:10:52 +01002322 conn_drain(conn);
Willy Tarreau20879a02012-12-03 16:32:10 +01002323 if (!conn->err_code)
Willy Tarreauf51c6982014-04-25 20:02:39 +02002324 conn->err_code = (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT) ?
2325 CO_ER_SSL_KILLED_HB : CO_ER_SSL_HANDSHAKE;
Emeric Brun674b7432012-11-08 19:21:55 +01002326 goto out_error;
2327 }
2328 }
2329 /* read some data: consider handshake completed */
2330 goto reneg_ok;
2331 }
2332
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02002333 ret = SSL_do_handshake(conn->xprt_ctx);
Emeric Brun46591952012-05-18 15:47:34 +02002334 if (ret != 1) {
2335 /* handshake did not complete, let's find why */
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02002336 ret = SSL_get_error(conn->xprt_ctx, ret);
Emeric Brun46591952012-05-18 15:47:34 +02002337
2338 if (ret == SSL_ERROR_WANT_WRITE) {
2339 /* SSL handshake needs to write, L4 connection may not be ready */
2340 __conn_sock_stop_recv(conn);
Willy Tarreaue1f50c42014-01-22 20:02:06 +01002341 __conn_sock_want_send(conn);
2342 fd_cant_send(conn->t.sock.fd);
Emeric Brun46591952012-05-18 15:47:34 +02002343 return 0;
2344 }
2345 else if (ret == SSL_ERROR_WANT_READ) {
2346 /* SSL handshake needs to read, L4 connection is ready */
2347 if (conn->flags & CO_FL_WAIT_L4_CONN)
2348 conn->flags &= ~CO_FL_WAIT_L4_CONN;
2349 __conn_sock_stop_send(conn);
Willy Tarreaue1f50c42014-01-22 20:02:06 +01002350 __conn_sock_want_recv(conn);
2351 fd_cant_recv(conn->t.sock.fd);
Emeric Brun46591952012-05-18 15:47:34 +02002352 return 0;
2353 }
Willy Tarreau89230192012-09-28 20:22:13 +02002354 else if (ret == SSL_ERROR_SYSCALL) {
2355 /* if errno is null, then connection was successfully established */
2356 if (!errno && conn->flags & CO_FL_WAIT_L4_CONN)
2357 conn->flags &= ~CO_FL_WAIT_L4_CONN;
Willy Tarreau20879a02012-12-03 16:32:10 +01002358
Emeric Brun29f037d2014-04-25 19:05:36 +02002359 if (!((SSL *)conn->xprt_ctx)->packet_length) {
2360 if (!errno) {
2361 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
2362 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
2363 else
2364 conn->err_code = CO_ER_SSL_EMPTY;
2365 }
2366 else {
2367 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
2368 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
2369 else
2370 conn->err_code = CO_ER_SSL_ABORT;
2371 }
2372 }
2373 else {
2374 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
2375 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
Willy Tarreau20879a02012-12-03 16:32:10 +01002376 else
Emeric Brun29f037d2014-04-25 19:05:36 +02002377 conn->err_code = CO_ER_SSL_HANDSHAKE;
2378 }
Willy Tarreau89230192012-09-28 20:22:13 +02002379 goto out_error;
2380 }
Emeric Brun46591952012-05-18 15:47:34 +02002381 else {
2382 /* Fail on all other handshake errors */
Willy Tarreau566dc552012-10-19 20:52:18 +02002383 /* Note: OpenSSL may leave unread bytes in the socket's
2384 * buffer, causing an RST to be emitted upon close() on
2385 * TCP sockets. We first try to drain possibly pending
2386 * data to avoid this as much as possible.
2387 */
Willy Tarreau46be2e52014-01-20 12:10:52 +01002388 conn_drain(conn);
Willy Tarreau20879a02012-12-03 16:32:10 +01002389 if (!conn->err_code)
Willy Tarreauf51c6982014-04-25 20:02:39 +02002390 conn->err_code = (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT) ?
2391 CO_ER_SSL_KILLED_HB : CO_ER_SSL_HANDSHAKE;
Emeric Brun46591952012-05-18 15:47:34 +02002392 goto out_error;
2393 }
2394 }
2395
Emeric Brun674b7432012-11-08 19:21:55 +01002396reneg_ok:
2397
Emeric Brun46591952012-05-18 15:47:34 +02002398 /* Handshake succeeded */
Willy Tarreau0c9c2722014-05-28 12:28:58 +02002399 if (!SSL_session_reused(conn->xprt_ctx)) {
2400 if (objt_server(conn->target)) {
2401 update_freq_ctr(&global.ssl_be_keys_per_sec, 1);
2402 if (global.ssl_be_keys_per_sec.curr_ctr > global.ssl_be_keys_max)
2403 global.ssl_be_keys_max = global.ssl_be_keys_per_sec.curr_ctr;
2404
Emeric Brun46591952012-05-18 15:47:34 +02002405 /* check if session was reused, if not store current session on server for reuse */
Willy Tarreau3fdb3662012-11-12 00:42:33 +01002406 if (objt_server(conn->target)->ssl_ctx.reused_sess)
2407 SSL_SESSION_free(objt_server(conn->target)->ssl_ctx.reused_sess);
Emeric Brun46591952012-05-18 15:47:34 +02002408
Willy Tarreau2a3fb1c2015-02-05 16:47:07 +01002409 if (!(objt_server(conn->target)->ssl_ctx.options & SRV_SSL_O_NO_REUSE))
2410 objt_server(conn->target)->ssl_ctx.reused_sess = SSL_get1_session(conn->xprt_ctx);
Emeric Brun46591952012-05-18 15:47:34 +02002411 }
Willy Tarreau0c9c2722014-05-28 12:28:58 +02002412 else {
2413 update_freq_ctr(&global.ssl_fe_keys_per_sec, 1);
2414 if (global.ssl_fe_keys_per_sec.curr_ctr > global.ssl_fe_keys_max)
2415 global.ssl_fe_keys_max = global.ssl_fe_keys_per_sec.curr_ctr;
2416 }
Emeric Brun46591952012-05-18 15:47:34 +02002417 }
2418
2419 /* The connection is now established at both layers, it's time to leave */
2420 conn->flags &= ~(flag | CO_FL_WAIT_L4_CONN | CO_FL_WAIT_L6_CONN);
2421 return 1;
2422
2423 out_error:
Emeric Brun644cde02012-12-14 11:21:13 +01002424 /* Clear openssl global errors stack */
2425 ERR_clear_error();
2426
Emeric Brun9fa89732012-10-04 17:09:56 +02002427 /* free resumed session if exists */
Willy Tarreau3fdb3662012-11-12 00:42:33 +01002428 if (objt_server(conn->target) && objt_server(conn->target)->ssl_ctx.reused_sess) {
2429 SSL_SESSION_free(objt_server(conn->target)->ssl_ctx.reused_sess);
2430 objt_server(conn->target)->ssl_ctx.reused_sess = NULL;
Emeric Brun9fa89732012-10-04 17:09:56 +02002431 }
2432
Emeric Brun46591952012-05-18 15:47:34 +02002433 /* Fail on all other handshake errors */
2434 conn->flags |= CO_FL_ERROR;
Willy Tarreau20879a02012-12-03 16:32:10 +01002435 if (!conn->err_code)
2436 conn->err_code = CO_ER_SSL_HANDSHAKE;
Emeric Brun46591952012-05-18 15:47:34 +02002437 return 0;
2438}
2439
2440/* Receive up to <count> bytes from connection <conn>'s socket and store them
Willy Tarreauabf08d92014-01-14 11:31:27 +01002441 * into buffer <buf>. Only one call to recv() is performed, unless the
Emeric Brun46591952012-05-18 15:47:34 +02002442 * buffer wraps, in which case a second call may be performed. The connection's
2443 * flags are updated with whatever special event is detected (error, read0,
2444 * empty). The caller is responsible for taking care of those events and
2445 * avoiding the call if inappropriate. The function does not call the
2446 * connection's polling update function, so the caller is responsible for this.
2447 */
2448static int ssl_sock_to_buf(struct connection *conn, struct buffer *buf, int count)
2449{
2450 int ret, done = 0;
Willy Tarreauabf08d92014-01-14 11:31:27 +01002451 int try;
Emeric Brun46591952012-05-18 15:47:34 +02002452
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02002453 if (!conn->xprt_ctx)
Emeric Brun46591952012-05-18 15:47:34 +02002454 goto out_error;
2455
2456 if (conn->flags & CO_FL_HANDSHAKE)
2457 /* a handshake was requested */
2458 return 0;
2459
Willy Tarreauabf08d92014-01-14 11:31:27 +01002460 /* let's realign the buffer to optimize I/O */
2461 if (buffer_empty(buf))
Emeric Brun46591952012-05-18 15:47:34 +02002462 buf->p = buf->data;
Emeric Brun46591952012-05-18 15:47:34 +02002463
2464 /* read the largest possible block. For this, we perform only one call
2465 * to recv() unless the buffer wraps and we exactly fill the first hunk,
2466 * in which case we accept to do it once again. A new attempt is made on
2467 * EINTR too.
2468 */
Willy Tarreau00b0fb92014-01-17 11:09:40 +01002469 while (count > 0) {
Willy Tarreauabf08d92014-01-14 11:31:27 +01002470 /* first check if we have some room after p+i */
2471 try = buf->data + buf->size - (buf->p + buf->i);
2472 /* otherwise continue between data and p-o */
2473 if (try <= 0) {
2474 try = buf->p - (buf->data + buf->o);
2475 if (try <= 0)
2476 break;
2477 }
2478 if (try > count)
2479 try = count;
2480
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02002481 ret = SSL_read(conn->xprt_ctx, bi_end(buf), try);
Emeric Brune1f38db2012-09-03 20:36:47 +02002482 if (conn->flags & CO_FL_ERROR) {
2483 /* CO_FL_ERROR may be set by ssl_sock_infocbk */
Emeric Brun644cde02012-12-14 11:21:13 +01002484 goto out_error;
Emeric Brune1f38db2012-09-03 20:36:47 +02002485 }
Emeric Brun46591952012-05-18 15:47:34 +02002486 if (ret > 0) {
2487 buf->i += ret;
2488 done += ret;
2489 if (ret < try)
2490 break;
2491 count -= ret;
Emeric Brun46591952012-05-18 15:47:34 +02002492 }
2493 else if (ret == 0) {
Emeric Brun644cde02012-12-14 11:21:13 +01002494 ret = SSL_get_error(conn->xprt_ctx, ret);
2495 if (ret != SSL_ERROR_ZERO_RETURN) {
Emeric Brun1c646862012-12-14 12:33:41 +01002496 /* error on protocol or underlying transport */
2497 if ((ret != SSL_ERROR_SYSCALL)
2498 || (errno && (errno != EAGAIN)))
2499 conn->flags |= CO_FL_ERROR;
2500
Emeric Brun644cde02012-12-14 11:21:13 +01002501 /* Clear openssl global errors stack */
2502 ERR_clear_error();
2503 }
Emeric Brun46591952012-05-18 15:47:34 +02002504 goto read0;
2505 }
2506 else {
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02002507 ret = SSL_get_error(conn->xprt_ctx, ret);
Emeric Brun46591952012-05-18 15:47:34 +02002508 if (ret == SSL_ERROR_WANT_WRITE) {
Emeric Brun8af8dd12012-11-08 17:56:20 +01002509 /* handshake is running, and it needs to enable write */
Emeric Brun46591952012-05-18 15:47:34 +02002510 conn->flags |= CO_FL_SSL_WAIT_HS;
Emeric Brun8af8dd12012-11-08 17:56:20 +01002511 __conn_sock_want_send(conn);
Emeric Brun46591952012-05-18 15:47:34 +02002512 break;
2513 }
2514 else if (ret == SSL_ERROR_WANT_READ) {
Emeric Brun282a76a2012-11-08 18:02:56 +01002515 if (SSL_renegotiate_pending(conn->xprt_ctx)) {
2516 /* handshake is running, and it may need to re-enable read */
2517 conn->flags |= CO_FL_SSL_WAIT_HS;
2518 __conn_sock_want_recv(conn);
2519 break;
2520 }
Emeric Brun46591952012-05-18 15:47:34 +02002521 /* we need to poll for retry a read later */
Willy Tarreaue1f50c42014-01-22 20:02:06 +01002522 fd_cant_recv(conn->t.sock.fd);
Emeric Brun46591952012-05-18 15:47:34 +02002523 break;
2524 }
2525 /* otherwise it's a real error */
2526 goto out_error;
2527 }
2528 }
2529 return done;
2530
2531 read0:
2532 conn_sock_read0(conn);
2533 return done;
2534 out_error:
Emeric Brun644cde02012-12-14 11:21:13 +01002535 /* Clear openssl global errors stack */
2536 ERR_clear_error();
2537
Emeric Brun46591952012-05-18 15:47:34 +02002538 conn->flags |= CO_FL_ERROR;
2539 return done;
2540}
2541
2542
2543/* Send all pending bytes from buffer <buf> to connection <conn>'s socket.
Willy Tarreau1049b1f2014-02-02 01:51:17 +01002544 * <flags> may contain some CO_SFL_* flags to hint the system about other
2545 * pending data for example, but this flag is ignored at the moment.
Emeric Brun46591952012-05-18 15:47:34 +02002546 * Only one call to send() is performed, unless the buffer wraps, in which case
2547 * a second call may be performed. The connection's flags are updated with
2548 * whatever special event is detected (error, empty). The caller is responsible
2549 * for taking care of those events and avoiding the call if inappropriate. The
2550 * function does not call the connection's polling update function, so the caller
2551 * is responsible for this.
2552 */
2553static int ssl_sock_from_buf(struct connection *conn, struct buffer *buf, int flags)
2554{
2555 int ret, try, done;
2556
2557 done = 0;
2558
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02002559 if (!conn->xprt_ctx)
Emeric Brun46591952012-05-18 15:47:34 +02002560 goto out_error;
2561
2562 if (conn->flags & CO_FL_HANDSHAKE)
2563 /* a handshake was requested */
2564 return 0;
2565
2566 /* send the largest possible block. For this we perform only one call
2567 * to send() unless the buffer wraps and we exactly fill the first hunk,
2568 * in which case we accept to do it once again.
2569 */
2570 while (buf->o) {
Kevin Hestercad82342013-05-30 15:12:41 -07002571 try = bo_contig_data(buf);
Willy Tarreaubfd59462013-02-21 07:46:09 +01002572
Willy Tarreau7bed9452014-02-02 02:00:24 +01002573 if (!(flags & CO_SFL_STREAMER) &&
Willy Tarreau518cedd2014-02-17 15:43:01 +01002574 !(conn->xprt_st & SSL_SOCK_SEND_UNLIMITED) &&
2575 global.tune.ssl_max_record && try > global.tune.ssl_max_record) {
Willy Tarreaubfd59462013-02-21 07:46:09 +01002576 try = global.tune.ssl_max_record;
Willy Tarreau518cedd2014-02-17 15:43:01 +01002577 }
2578 else {
2579 /* we need to keep the information about the fact that
2580 * we're not limiting the upcoming send(), because if it
2581 * fails, we'll have to retry with at least as many data.
2582 */
2583 conn->xprt_st |= SSL_SOCK_SEND_UNLIMITED;
2584 }
Willy Tarreaubfd59462013-02-21 07:46:09 +01002585
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02002586 ret = SSL_write(conn->xprt_ctx, bo_ptr(buf), try);
Willy Tarreau518cedd2014-02-17 15:43:01 +01002587
Emeric Brune1f38db2012-09-03 20:36:47 +02002588 if (conn->flags & CO_FL_ERROR) {
2589 /* CO_FL_ERROR may be set by ssl_sock_infocbk */
Emeric Brun644cde02012-12-14 11:21:13 +01002590 goto out_error;
Emeric Brune1f38db2012-09-03 20:36:47 +02002591 }
Emeric Brun46591952012-05-18 15:47:34 +02002592 if (ret > 0) {
Willy Tarreau518cedd2014-02-17 15:43:01 +01002593 conn->xprt_st &= ~SSL_SOCK_SEND_UNLIMITED;
2594
Emeric Brun46591952012-05-18 15:47:34 +02002595 buf->o -= ret;
2596 done += ret;
2597
Willy Tarreau5fb38032012-12-16 19:39:09 +01002598 if (likely(buffer_empty(buf)))
Emeric Brun46591952012-05-18 15:47:34 +02002599 /* optimize data alignment in the buffer */
2600 buf->p = buf->data;
2601
2602 /* if the system buffer is full, don't insist */
2603 if (ret < try)
2604 break;
2605 }
2606 else {
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02002607 ret = SSL_get_error(conn->xprt_ctx, ret);
Emeric Brun46591952012-05-18 15:47:34 +02002608 if (ret == SSL_ERROR_WANT_WRITE) {
Emeric Brun282a76a2012-11-08 18:02:56 +01002609 if (SSL_renegotiate_pending(conn->xprt_ctx)) {
2610 /* handshake is running, and it may need to re-enable write */
2611 conn->flags |= CO_FL_SSL_WAIT_HS;
2612 __conn_sock_want_send(conn);
2613 break;
2614 }
Emeric Brun46591952012-05-18 15:47:34 +02002615 /* we need to poll to retry a write later */
Willy Tarreaue1f50c42014-01-22 20:02:06 +01002616 fd_cant_send(conn->t.sock.fd);
Emeric Brun46591952012-05-18 15:47:34 +02002617 break;
2618 }
2619 else if (ret == SSL_ERROR_WANT_READ) {
Emeric Brun8af8dd12012-11-08 17:56:20 +01002620 /* handshake is running, and it needs to enable read */
Emeric Brun46591952012-05-18 15:47:34 +02002621 conn->flags |= CO_FL_SSL_WAIT_HS;
Emeric Brun8af8dd12012-11-08 17:56:20 +01002622 __conn_sock_want_recv(conn);
Emeric Brun46591952012-05-18 15:47:34 +02002623 break;
2624 }
2625 goto out_error;
2626 }
2627 }
2628 return done;
2629
2630 out_error:
Emeric Brun644cde02012-12-14 11:21:13 +01002631 /* Clear openssl global errors stack */
2632 ERR_clear_error();
2633
Emeric Brun46591952012-05-18 15:47:34 +02002634 conn->flags |= CO_FL_ERROR;
2635 return done;
2636}
2637
Emeric Brun46591952012-05-18 15:47:34 +02002638static void ssl_sock_close(struct connection *conn) {
2639
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02002640 if (conn->xprt_ctx) {
2641 SSL_free(conn->xprt_ctx);
2642 conn->xprt_ctx = NULL;
Willy Tarreau403edff2012-09-06 11:58:37 +02002643 sslconns--;
Emeric Brun46591952012-05-18 15:47:34 +02002644 }
Emeric Brun46591952012-05-18 15:47:34 +02002645}
2646
2647/* This function tries to perform a clean shutdown on an SSL connection, and in
2648 * any case, flags the connection as reusable if no handshake was in progress.
2649 */
2650static void ssl_sock_shutw(struct connection *conn, int clean)
2651{
2652 if (conn->flags & CO_FL_HANDSHAKE)
2653 return;
2654 /* no handshake was in progress, try a clean ssl shutdown */
Emeric Brun644cde02012-12-14 11:21:13 +01002655 if (clean && (SSL_shutdown(conn->xprt_ctx) <= 0)) {
2656 /* Clear openssl global errors stack */
2657 ERR_clear_error();
2658 }
Emeric Brun46591952012-05-18 15:47:34 +02002659
2660 /* force flag on ssl to keep session in cache regardless shutdown result */
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02002661 SSL_set_shutdown(conn->xprt_ctx, SSL_SENT_SHUTDOWN);
Emeric Brun46591952012-05-18 15:47:34 +02002662}
2663
Willy Tarreauffc3fcd2012-10-12 20:17:54 +02002664/* used for logging, may be changed for a sample fetch later */
2665const char *ssl_sock_get_cipher_name(struct connection *conn)
2666{
2667 if (!conn->xprt && !conn->xprt_ctx)
2668 return NULL;
2669 return SSL_get_cipher_name(conn->xprt_ctx);
2670}
2671
2672/* used for logging, may be changed for a sample fetch later */
2673const char *ssl_sock_get_proto_version(struct connection *conn)
2674{
2675 if (!conn->xprt && !conn->xprt_ctx)
2676 return NULL;
2677 return SSL_get_version(conn->xprt_ctx);
2678}
2679
Willy Tarreau8d598402012-10-22 17:58:39 +02002680/* Extract a serial from a cert, and copy it to a chunk.
2681 * Returns 1 if serial is found and copied, 0 if no serial found and
2682 * -1 if output is not large enough.
2683 */
2684static int
2685ssl_sock_get_serial(X509 *crt, struct chunk *out)
2686{
2687 ASN1_INTEGER *serial;
2688
2689 serial = X509_get_serialNumber(crt);
2690 if (!serial)
2691 return 0;
2692
2693 if (out->size < serial->length)
2694 return -1;
2695
2696 memcpy(out->str, serial->data, serial->length);
2697 out->len = serial->length;
2698 return 1;
2699}
2700
Emeric Brun43e79582014-10-29 19:03:26 +01002701/* Extract a cert to der, and copy it to a chunk.
2702 * Returns 1 if cert is found and copied, 0 on der convertion failure and
2703 * -1 if output is not large enough.
2704 */
2705static int
2706ssl_sock_crt2der(X509 *crt, struct chunk *out)
2707{
2708 int len;
2709 unsigned char *p = (unsigned char *)out->str;;
2710
2711 len =i2d_X509(crt, NULL);
2712 if (len <= 0)
2713 return 1;
2714
2715 if (out->size < len)
2716 return -1;
2717
2718 i2d_X509(crt,&p);
2719 out->len = len;
2720 return 1;
2721}
2722
Emeric Brunce5ad802012-10-22 14:11:22 +02002723
2724/* Copy Date in ASN1_UTCTIME format in struct chunk out.
2725 * Returns 1 if serial is found and copied, 0 if no valid time found
2726 * and -1 if output is not large enough.
2727 */
2728static int
2729ssl_sock_get_time(ASN1_TIME *tm, struct chunk *out)
2730{
2731 if (tm->type == V_ASN1_GENERALIZEDTIME) {
2732 ASN1_GENERALIZEDTIME *gentm = (ASN1_GENERALIZEDTIME *)tm;
2733
2734 if (gentm->length < 12)
2735 return 0;
2736 if (gentm->data[0] != 0x32 || gentm->data[1] != 0x30)
2737 return 0;
2738 if (out->size < gentm->length-2)
2739 return -1;
2740
2741 memcpy(out->str, gentm->data+2, gentm->length-2);
2742 out->len = gentm->length-2;
2743 return 1;
2744 }
2745 else if (tm->type == V_ASN1_UTCTIME) {
2746 ASN1_UTCTIME *utctm = (ASN1_UTCTIME *)tm;
2747
2748 if (utctm->length < 10)
2749 return 0;
2750 if (utctm->data[0] >= 0x35)
2751 return 0;
2752 if (out->size < utctm->length)
2753 return -1;
2754
2755 memcpy(out->str, utctm->data, utctm->length);
2756 out->len = utctm->length;
2757 return 1;
2758 }
2759
2760 return 0;
2761}
2762
Emeric Brun87855892012-10-17 17:39:35 +02002763/* Extract an entry from a X509_NAME and copy its value to an output chunk.
2764 * Returns 1 if entry found, 0 if entry not found, or -1 if output not large enough.
2765 */
2766static int
2767ssl_sock_get_dn_entry(X509_NAME *a, const struct chunk *entry, int pos, struct chunk *out)
2768{
2769 X509_NAME_ENTRY *ne;
2770 int i, j, n;
2771 int cur = 0;
2772 const char *s;
2773 char tmp[128];
2774
2775 out->len = 0;
2776 for (i = 0; i < sk_X509_NAME_ENTRY_num(a->entries); i++) {
2777 if (pos < 0)
2778 j = (sk_X509_NAME_ENTRY_num(a->entries)-1) - i;
2779 else
2780 j = i;
2781
2782 ne = sk_X509_NAME_ENTRY_value(a->entries, j);
2783 n = OBJ_obj2nid(ne->object);
2784 if ((n == NID_undef) || ((s = OBJ_nid2sn(n)) == NULL)) {
2785 i2t_ASN1_OBJECT(tmp, sizeof(tmp), ne->object);
2786 s = tmp;
2787 }
2788
2789 if (chunk_strcasecmp(entry, s) != 0)
2790 continue;
2791
2792 if (pos < 0)
2793 cur--;
2794 else
2795 cur++;
2796
2797 if (cur != pos)
2798 continue;
2799
2800 if (ne->value->length > out->size)
2801 return -1;
2802
2803 memcpy(out->str, ne->value->data, ne->value->length);
2804 out->len = ne->value->length;
2805 return 1;
2806 }
2807
2808 return 0;
2809
2810}
2811
2812/* Extract and format full DN from a X509_NAME and copy result into a chunk
2813 * Returns 1 if dn entries exits, 0 if no dn entry found or -1 if output is not large enough.
2814 */
2815static int
2816ssl_sock_get_dn_oneline(X509_NAME *a, struct chunk *out)
2817{
2818 X509_NAME_ENTRY *ne;
2819 int i, n, ln;
2820 int l = 0;
2821 const char *s;
2822 char *p;
2823 char tmp[128];
2824
2825 out->len = 0;
2826 p = out->str;
2827 for (i = 0; i < sk_X509_NAME_ENTRY_num(a->entries); i++) {
2828 ne = sk_X509_NAME_ENTRY_value(a->entries, i);
2829 n = OBJ_obj2nid(ne->object);
2830 if ((n == NID_undef) || ((s = OBJ_nid2sn(n)) == NULL)) {
2831 i2t_ASN1_OBJECT(tmp, sizeof(tmp), ne->object);
2832 s = tmp;
2833 }
2834 ln = strlen(s);
2835
2836 l += 1 + ln + 1 + ne->value->length;
2837 if (l > out->size)
2838 return -1;
2839 out->len = l;
2840
2841 *(p++)='/';
2842 memcpy(p, s, ln);
2843 p += ln;
2844 *(p++)='=';
2845 memcpy(p, ne->value->data, ne->value->length);
2846 p += ne->value->length;
2847 }
2848
2849 if (!out->len)
2850 return 0;
2851
2852 return 1;
2853}
2854
David Safb76832014-05-08 23:42:08 -04002855char *ssl_sock_get_version(struct connection *conn)
2856{
2857 if (!ssl_sock_is_ssl(conn))
2858 return NULL;
2859
2860 return (char *)SSL_get_version(conn->xprt_ctx);
2861}
2862
Emeric Brun0abf8362014-06-24 18:26:41 +02002863/* Extract peer certificate's common name into the chunk dest
2864 * Returns
2865 * the len of the extracted common name
2866 * or 0 if no CN found in DN
2867 * or -1 on error case (i.e. no peer certificate)
2868 */
2869int ssl_sock_get_remote_common_name(struct connection *conn, struct chunk *dest)
David Safb76832014-05-08 23:42:08 -04002870{
2871 X509 *crt = NULL;
2872 X509_NAME *name;
David Safb76832014-05-08 23:42:08 -04002873 const char find_cn[] = "CN";
2874 const struct chunk find_cn_chunk = {
2875 .str = (char *)&find_cn,
2876 .len = sizeof(find_cn)-1
2877 };
Emeric Brun0abf8362014-06-24 18:26:41 +02002878 int result = -1;
David Safb76832014-05-08 23:42:08 -04002879
2880 if (!ssl_sock_is_ssl(conn))
Emeric Brun0abf8362014-06-24 18:26:41 +02002881 goto out;
David Safb76832014-05-08 23:42:08 -04002882
2883 /* SSL_get_peer_certificate, it increase X509 * ref count */
2884 crt = SSL_get_peer_certificate(conn->xprt_ctx);
2885 if (!crt)
2886 goto out;
2887
2888 name = X509_get_subject_name(crt);
2889 if (!name)
2890 goto out;
David Safb76832014-05-08 23:42:08 -04002891
Emeric Brun0abf8362014-06-24 18:26:41 +02002892 result = ssl_sock_get_dn_entry(name, &find_cn_chunk, 1, dest);
2893out:
David Safb76832014-05-08 23:42:08 -04002894 if (crt)
2895 X509_free(crt);
2896
2897 return result;
2898}
2899
Dave McCowan328fb582014-07-30 10:39:13 -04002900/* returns 1 if client passed a certificate for this session, 0 if not */
2901int ssl_sock_get_cert_used_sess(struct connection *conn)
2902{
2903 X509 *crt = NULL;
2904
2905 if (!ssl_sock_is_ssl(conn))
2906 return 0;
2907
2908 /* SSL_get_peer_certificate, it increase X509 * ref count */
2909 crt = SSL_get_peer_certificate(conn->xprt_ctx);
2910 if (!crt)
2911 return 0;
2912
2913 X509_free(crt);
2914 return 1;
2915}
2916
2917/* returns 1 if client passed a certificate for this connection, 0 if not */
2918int ssl_sock_get_cert_used_conn(struct connection *conn)
David Safb76832014-05-08 23:42:08 -04002919{
2920 if (!ssl_sock_is_ssl(conn))
2921 return 0;
2922
2923 return SSL_SOCK_ST_FL_VERIFY_DONE & conn->xprt_st ? 1 : 0;
2924}
2925
2926/* returns result from SSL verify */
2927unsigned int ssl_sock_get_verify_result(struct connection *conn)
2928{
2929 if (!ssl_sock_is_ssl(conn))
2930 return (unsigned int)X509_V_ERR_APPLICATION_VERIFICATION;
2931
2932 return (unsigned int)SSL_get_verify_result(conn->xprt_ctx);
2933}
2934
Willy Tarreau7875d092012-09-10 08:20:03 +02002935/***** Below are some sample fetching functions for ACL/patterns *****/
2936
Emeric Brune64aef12012-09-21 13:15:06 +02002937/* boolean, returns true if client cert was present */
2938static int
Emeric Brun2525b6b2012-10-18 15:59:43 +02002939smp_fetch_ssl_fc_has_crt(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Thierry FOURNIERf41a8092014-12-07 18:37:57 +01002940 const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brune64aef12012-09-21 13:15:06 +02002941{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002942 struct connection *conn;
2943
2944 if (!l4)
2945 return 0;
2946
2947 conn = objt_conn(l4->si[0].end);
2948 if (!conn || conn->xprt != &ssl_sock)
Emeric Brune64aef12012-09-21 13:15:06 +02002949 return 0;
2950
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002951 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brune64aef12012-09-21 13:15:06 +02002952 smp->flags |= SMP_F_MAY_CHANGE;
2953 return 0;
2954 }
2955
2956 smp->flags = 0;
2957 smp->type = SMP_T_BOOL;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002958 smp->data.uint = SSL_SOCK_ST_FL_VERIFY_DONE & conn->xprt_st ? 1 : 0;
Emeric Brune64aef12012-09-21 13:15:06 +02002959
2960 return 1;
2961}
2962
Emeric Brun43e79582014-10-29 19:03:26 +01002963/* binary, returns a certificate in a binary chunk (der/raw).
2964 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
2965 * should be use.
2966 */
2967static int
2968smp_fetch_ssl_x_der(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Thierry FOURNIERf41a8092014-12-07 18:37:57 +01002969 const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun43e79582014-10-29 19:03:26 +01002970{
2971 int cert_peer = (kw[4] == 'c') ? 1 : 0;
2972 X509 *crt = NULL;
2973 int ret = 0;
2974 struct chunk *smp_trash;
2975 struct connection *conn;
2976
2977 if (!l4)
2978 return 0;
2979
2980 conn = objt_conn(l4->si[0].end);
2981 if (!conn || conn->xprt != &ssl_sock)
2982 return 0;
2983
2984 if (!(conn->flags & CO_FL_CONNECTED)) {
2985 smp->flags |= SMP_F_MAY_CHANGE;
2986 return 0;
2987 }
2988
2989 if (cert_peer)
2990 crt = SSL_get_peer_certificate(conn->xprt_ctx);
2991 else
2992 crt = SSL_get_certificate(conn->xprt_ctx);
2993
2994 if (!crt)
2995 goto out;
2996
2997 smp_trash = get_trash_chunk();
2998 if (ssl_sock_crt2der(crt, smp_trash) <= 0)
2999 goto out;
3000
3001 smp->data.str = *smp_trash;
3002 smp->type = SMP_T_BIN;
3003 ret = 1;
3004out:
3005 /* SSL_get_peer_certificate, it increase X509 * ref count */
3006 if (cert_peer && crt)
3007 X509_free(crt);
3008 return ret;
3009}
3010
Emeric Brunba841a12014-04-30 17:05:08 +02003011/* binary, returns serial of certificate in a binary chunk.
3012 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
3013 * should be use.
3014 */
Willy Tarreau8d598402012-10-22 17:58:39 +02003015static int
Emeric Brunba841a12014-04-30 17:05:08 +02003016smp_fetch_ssl_x_serial(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Thierry FOURNIERf41a8092014-12-07 18:37:57 +01003017 const struct arg *args, struct sample *smp, const char *kw, void *private)
Willy Tarreau8d598402012-10-22 17:58:39 +02003018{
Emeric Brunba841a12014-04-30 17:05:08 +02003019 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Willy Tarreau8d598402012-10-22 17:58:39 +02003020 X509 *crt = NULL;
3021 int ret = 0;
3022 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003023 struct connection *conn;
3024
3025 if (!l4)
3026 return 0;
Willy Tarreau8d598402012-10-22 17:58:39 +02003027
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003028 conn = objt_conn(l4->si[0].end);
3029 if (!conn || conn->xprt != &ssl_sock)
Willy Tarreau8d598402012-10-22 17:58:39 +02003030 return 0;
3031
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003032 if (!(conn->flags & CO_FL_CONNECTED)) {
Willy Tarreau8d598402012-10-22 17:58:39 +02003033 smp->flags |= SMP_F_MAY_CHANGE;
3034 return 0;
3035 }
3036
Emeric Brunba841a12014-04-30 17:05:08 +02003037 if (cert_peer)
3038 crt = SSL_get_peer_certificate(conn->xprt_ctx);
3039 else
3040 crt = SSL_get_certificate(conn->xprt_ctx);
3041
Willy Tarreau8d598402012-10-22 17:58:39 +02003042 if (!crt)
3043 goto out;
3044
Willy Tarreau47ca5452012-12-23 20:22:19 +01003045 smp_trash = get_trash_chunk();
Willy Tarreau8d598402012-10-22 17:58:39 +02003046 if (ssl_sock_get_serial(crt, smp_trash) <= 0)
3047 goto out;
3048
3049 smp->data.str = *smp_trash;
3050 smp->type = SMP_T_BIN;
3051 ret = 1;
3052out:
Emeric Brunba841a12014-04-30 17:05:08 +02003053 /* SSL_get_peer_certificate, it increase X509 * ref count */
3054 if (cert_peer && crt)
Willy Tarreau8d598402012-10-22 17:58:39 +02003055 X509_free(crt);
3056 return ret;
3057}
Emeric Brune64aef12012-09-21 13:15:06 +02003058
Emeric Brunba841a12014-04-30 17:05:08 +02003059/* binary, returns the client certificate's SHA-1 fingerprint (SHA-1 hash of DER-encoded certificate) in a binary chunk.
3060 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
3061 * should be use.
3062 */
James Votha051b4a2013-05-14 20:37:59 +02003063static int
Emeric Brunba841a12014-04-30 17:05:08 +02003064smp_fetch_ssl_x_sha1(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Thierry FOURNIERf41a8092014-12-07 18:37:57 +01003065 const struct arg *args, struct sample *smp, const char *kw, void *private)
James Votha051b4a2013-05-14 20:37:59 +02003066{
Emeric Brunba841a12014-04-30 17:05:08 +02003067 int cert_peer = (kw[4] == 'c') ? 1 : 0;
James Votha051b4a2013-05-14 20:37:59 +02003068 X509 *crt = NULL;
3069 const EVP_MD *digest;
3070 int ret = 0;
3071 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003072 struct connection *conn;
James Votha051b4a2013-05-14 20:37:59 +02003073
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003074 if (!l4)
James Votha051b4a2013-05-14 20:37:59 +02003075 return 0;
3076
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003077 conn = objt_conn(l4->si[0].end);
3078 if (!conn || conn->xprt != &ssl_sock)
3079 return 0;
3080
3081 if (!(conn->flags & CO_FL_CONNECTED)) {
James Votha051b4a2013-05-14 20:37:59 +02003082 smp->flags |= SMP_F_MAY_CHANGE;
3083 return 0;
3084 }
3085
Emeric Brunba841a12014-04-30 17:05:08 +02003086 if (cert_peer)
3087 crt = SSL_get_peer_certificate(conn->xprt_ctx);
3088 else
3089 crt = SSL_get_certificate(conn->xprt_ctx);
James Votha051b4a2013-05-14 20:37:59 +02003090 if (!crt)
3091 goto out;
3092
3093 smp_trash = get_trash_chunk();
3094 digest = EVP_sha1();
3095 X509_digest(crt, digest, (unsigned char *)smp_trash->str, (unsigned int *)&smp_trash->len);
3096
3097 smp->data.str = *smp_trash;
3098 smp->type = SMP_T_BIN;
3099 ret = 1;
3100out:
Emeric Brunba841a12014-04-30 17:05:08 +02003101 /* SSL_get_peer_certificate, it increase X509 * ref count */
3102 if (cert_peer && crt)
James Votha051b4a2013-05-14 20:37:59 +02003103 X509_free(crt);
3104 return ret;
3105}
3106
Emeric Brunba841a12014-04-30 17:05:08 +02003107/* string, returns certificate's notafter date in ASN1_UTCTIME format.
3108 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
3109 * should be use.
3110 */
Emeric Brunce5ad802012-10-22 14:11:22 +02003111static int
Emeric Brunba841a12014-04-30 17:05:08 +02003112smp_fetch_ssl_x_notafter(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Thierry FOURNIERf41a8092014-12-07 18:37:57 +01003113 const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brunce5ad802012-10-22 14:11:22 +02003114{
Emeric Brunba841a12014-04-30 17:05:08 +02003115 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brunce5ad802012-10-22 14:11:22 +02003116 X509 *crt = NULL;
3117 int ret = 0;
3118 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003119 struct connection *conn;
Emeric Brunce5ad802012-10-22 14:11:22 +02003120
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003121 if (!l4)
Emeric Brunce5ad802012-10-22 14:11:22 +02003122 return 0;
3123
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003124 conn = objt_conn(l4->si[0].end);
3125 if (!conn || conn->xprt != &ssl_sock)
3126 return 0;
3127
3128 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunce5ad802012-10-22 14:11:22 +02003129 smp->flags |= SMP_F_MAY_CHANGE;
3130 return 0;
3131 }
3132
Emeric Brunba841a12014-04-30 17:05:08 +02003133 if (cert_peer)
3134 crt = SSL_get_peer_certificate(conn->xprt_ctx);
3135 else
3136 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brunce5ad802012-10-22 14:11:22 +02003137 if (!crt)
3138 goto out;
3139
Willy Tarreau47ca5452012-12-23 20:22:19 +01003140 smp_trash = get_trash_chunk();
Emeric Brunce5ad802012-10-22 14:11:22 +02003141 if (ssl_sock_get_time(X509_get_notAfter(crt), smp_trash) <= 0)
3142 goto out;
3143
3144 smp->data.str = *smp_trash;
3145 smp->type = SMP_T_STR;
3146 ret = 1;
3147out:
Emeric Brunba841a12014-04-30 17:05:08 +02003148 /* SSL_get_peer_certificate, it increase X509 * ref count */
3149 if (cert_peer && crt)
Emeric Brunce5ad802012-10-22 14:11:22 +02003150 X509_free(crt);
3151 return ret;
3152}
3153
Emeric Brunba841a12014-04-30 17:05:08 +02003154/* string, returns a string of a formatted full dn \C=..\O=..\OU=.. \CN=.. of certificate's issuer
3155 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
3156 * should be use.
3157 */
Emeric Brun87855892012-10-17 17:39:35 +02003158static int
Emeric Brunba841a12014-04-30 17:05:08 +02003159smp_fetch_ssl_x_i_dn(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Thierry FOURNIERf41a8092014-12-07 18:37:57 +01003160 const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun87855892012-10-17 17:39:35 +02003161{
Emeric Brunba841a12014-04-30 17:05:08 +02003162 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brun87855892012-10-17 17:39:35 +02003163 X509 *crt = NULL;
3164 X509_NAME *name;
3165 int ret = 0;
3166 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003167 struct connection *conn;
Emeric Brun87855892012-10-17 17:39:35 +02003168
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003169 if (!l4)
Emeric Brun87855892012-10-17 17:39:35 +02003170 return 0;
3171
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003172 conn = objt_conn(l4->si[0].end);
3173 if (!conn || conn->xprt != &ssl_sock)
3174 return 0;
3175
3176 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun87855892012-10-17 17:39:35 +02003177 smp->flags |= SMP_F_MAY_CHANGE;
3178 return 0;
3179 }
3180
Emeric Brunba841a12014-04-30 17:05:08 +02003181 if (cert_peer)
3182 crt = SSL_get_peer_certificate(conn->xprt_ctx);
3183 else
3184 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brun87855892012-10-17 17:39:35 +02003185 if (!crt)
3186 goto out;
3187
3188 name = X509_get_issuer_name(crt);
3189 if (!name)
3190 goto out;
3191
Willy Tarreau47ca5452012-12-23 20:22:19 +01003192 smp_trash = get_trash_chunk();
Emeric Brun87855892012-10-17 17:39:35 +02003193 if (args && args[0].type == ARGT_STR) {
3194 int pos = 1;
3195
3196 if (args[1].type == ARGT_SINT)
3197 pos = args[1].data.sint;
3198 else if (args[1].type == ARGT_UINT)
3199 pos =(int)args[1].data.uint;
3200
3201 if (ssl_sock_get_dn_entry(name, &args[0].data.str, pos, smp_trash) <= 0)
3202 goto out;
3203 }
3204 else if (ssl_sock_get_dn_oneline(name, smp_trash) <= 0)
3205 goto out;
3206
3207 smp->type = SMP_T_STR;
3208 smp->data.str = *smp_trash;
3209 ret = 1;
3210out:
Emeric Brunba841a12014-04-30 17:05:08 +02003211 /* SSL_get_peer_certificate, it increase X509 * ref count */
3212 if (cert_peer && crt)
Emeric Brun87855892012-10-17 17:39:35 +02003213 X509_free(crt);
3214 return ret;
3215}
3216
Emeric Brunba841a12014-04-30 17:05:08 +02003217/* string, returns notbefore date in ASN1_UTCTIME format.
3218 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
3219 * should be use.
3220 */
Emeric Brunce5ad802012-10-22 14:11:22 +02003221static int
Emeric Brunba841a12014-04-30 17:05:08 +02003222smp_fetch_ssl_x_notbefore(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Thierry FOURNIERf41a8092014-12-07 18:37:57 +01003223 const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brunce5ad802012-10-22 14:11:22 +02003224{
Emeric Brunba841a12014-04-30 17:05:08 +02003225 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brunce5ad802012-10-22 14:11:22 +02003226 X509 *crt = NULL;
3227 int ret = 0;
3228 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003229 struct connection *conn;
3230
3231 if (!l4)
3232 return 0;
Emeric Brunce5ad802012-10-22 14:11:22 +02003233
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003234 conn = objt_conn(l4->si[0].end);
3235 if (!conn || conn->xprt != &ssl_sock)
Emeric Brunce5ad802012-10-22 14:11:22 +02003236 return 0;
3237
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003238 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunce5ad802012-10-22 14:11:22 +02003239 smp->flags |= SMP_F_MAY_CHANGE;
3240 return 0;
3241 }
3242
Emeric Brunba841a12014-04-30 17:05:08 +02003243 if (cert_peer)
3244 crt = SSL_get_peer_certificate(conn->xprt_ctx);
3245 else
3246 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brunce5ad802012-10-22 14:11:22 +02003247 if (!crt)
3248 goto out;
3249
Willy Tarreau47ca5452012-12-23 20:22:19 +01003250 smp_trash = get_trash_chunk();
Emeric Brunce5ad802012-10-22 14:11:22 +02003251 if (ssl_sock_get_time(X509_get_notBefore(crt), smp_trash) <= 0)
3252 goto out;
3253
3254 smp->data.str = *smp_trash;
3255 smp->type = SMP_T_STR;
3256 ret = 1;
3257out:
Emeric Brunba841a12014-04-30 17:05:08 +02003258 /* SSL_get_peer_certificate, it increase X509 * ref count */
3259 if (cert_peer && crt)
Emeric Brunce5ad802012-10-22 14:11:22 +02003260 X509_free(crt);
3261 return ret;
3262}
3263
Emeric Brunba841a12014-04-30 17:05:08 +02003264/* string, returns a string of a formatted full dn \C=..\O=..\OU=.. \CN=.. of certificate's subject
3265 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
3266 * should be use.
3267 */
Emeric Brun87855892012-10-17 17:39:35 +02003268static int
Emeric Brunba841a12014-04-30 17:05:08 +02003269smp_fetch_ssl_x_s_dn(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Thierry FOURNIERf41a8092014-12-07 18:37:57 +01003270 const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun87855892012-10-17 17:39:35 +02003271{
Emeric Brunba841a12014-04-30 17:05:08 +02003272 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brun87855892012-10-17 17:39:35 +02003273 X509 *crt = NULL;
3274 X509_NAME *name;
3275 int ret = 0;
3276 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003277 struct connection *conn;
Emeric Brun87855892012-10-17 17:39:35 +02003278
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003279 if (!l4)
Emeric Brun87855892012-10-17 17:39:35 +02003280 return 0;
3281
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003282 conn = objt_conn(l4->si[0].end);
3283 if (!conn || conn->xprt != &ssl_sock)
3284 return 0;
3285
3286 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun87855892012-10-17 17:39:35 +02003287 smp->flags |= SMP_F_MAY_CHANGE;
3288 return 0;
3289 }
3290
Emeric Brunba841a12014-04-30 17:05:08 +02003291 if (cert_peer)
3292 crt = SSL_get_peer_certificate(conn->xprt_ctx);
3293 else
3294 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brun87855892012-10-17 17:39:35 +02003295 if (!crt)
3296 goto out;
3297
3298 name = X509_get_subject_name(crt);
3299 if (!name)
3300 goto out;
3301
Willy Tarreau47ca5452012-12-23 20:22:19 +01003302 smp_trash = get_trash_chunk();
Emeric Brun87855892012-10-17 17:39:35 +02003303 if (args && args[0].type == ARGT_STR) {
3304 int pos = 1;
3305
3306 if (args[1].type == ARGT_SINT)
3307 pos = args[1].data.sint;
3308 else if (args[1].type == ARGT_UINT)
3309 pos =(int)args[1].data.uint;
3310
3311 if (ssl_sock_get_dn_entry(name, &args[0].data.str, pos, smp_trash) <= 0)
3312 goto out;
3313 }
3314 else if (ssl_sock_get_dn_oneline(name, smp_trash) <= 0)
3315 goto out;
3316
3317 smp->type = SMP_T_STR;
3318 smp->data.str = *smp_trash;
3319 ret = 1;
3320out:
Emeric Brunba841a12014-04-30 17:05:08 +02003321 /* SSL_get_peer_certificate, it increase X509 * ref count */
3322 if (cert_peer && crt)
Emeric Brun87855892012-10-17 17:39:35 +02003323 X509_free(crt);
3324 return ret;
3325}
Emeric Brun9143d372012-12-20 15:44:16 +01003326
3327/* integer, returns true if current session use a client certificate */
3328static int
3329smp_fetch_ssl_c_used(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Thierry FOURNIERf41a8092014-12-07 18:37:57 +01003330 const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun9143d372012-12-20 15:44:16 +01003331{
3332 X509 *crt;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003333 struct connection *conn;
Emeric Brun9143d372012-12-20 15:44:16 +01003334
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003335 if (!l4)
Emeric Brun9143d372012-12-20 15:44:16 +01003336 return 0;
3337
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003338 conn = objt_conn(l4->si[0].end);
3339 if (!conn || conn->xprt != &ssl_sock)
3340 return 0;
3341
3342 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun9143d372012-12-20 15:44:16 +01003343 smp->flags |= SMP_F_MAY_CHANGE;
3344 return 0;
3345 }
3346
3347 /* SSL_get_peer_certificate returns a ptr on allocated X509 struct */
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003348 crt = SSL_get_peer_certificate(conn->xprt_ctx);
Emeric Brun9143d372012-12-20 15:44:16 +01003349 if (crt) {
3350 X509_free(crt);
3351 }
3352
3353 smp->type = SMP_T_BOOL;
3354 smp->data.uint = (crt != NULL);
3355 return 1;
3356}
3357
Emeric Brunba841a12014-04-30 17:05:08 +02003358/* integer, returns the certificate version
3359 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
3360 * should be use.
3361 */
Emeric Bruna7359fd2012-10-17 15:03:11 +02003362static int
Emeric Brunba841a12014-04-30 17:05:08 +02003363smp_fetch_ssl_x_version(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Thierry FOURNIERf41a8092014-12-07 18:37:57 +01003364 const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Bruna7359fd2012-10-17 15:03:11 +02003365{
Emeric Brunba841a12014-04-30 17:05:08 +02003366 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Bruna7359fd2012-10-17 15:03:11 +02003367 X509 *crt;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003368 struct connection *conn;
3369
3370 if (!l4)
3371 return 0;
Emeric Bruna7359fd2012-10-17 15:03:11 +02003372
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003373 conn = objt_conn(l4->si[0].end);
3374 if (!conn || conn->xprt != &ssl_sock)
Emeric Bruna7359fd2012-10-17 15:03:11 +02003375 return 0;
3376
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003377 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Bruna7359fd2012-10-17 15:03:11 +02003378 smp->flags |= SMP_F_MAY_CHANGE;
3379 return 0;
3380 }
3381
Emeric Brunba841a12014-04-30 17:05:08 +02003382 if (cert_peer)
3383 crt = SSL_get_peer_certificate(conn->xprt_ctx);
3384 else
3385 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Bruna7359fd2012-10-17 15:03:11 +02003386 if (!crt)
3387 return 0;
3388
3389 smp->data.uint = (unsigned int)(1 + X509_get_version(crt));
Emeric Brunba841a12014-04-30 17:05:08 +02003390 /* SSL_get_peer_certificate increase X509 * ref count */
3391 if (cert_peer)
3392 X509_free(crt);
Emeric Bruna7359fd2012-10-17 15:03:11 +02003393 smp->type = SMP_T_UINT;
3394
3395 return 1;
3396}
3397
Emeric Brunba841a12014-04-30 17:05:08 +02003398/* string, returns the certificate's signature algorithm.
3399 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
3400 * should be use.
3401 */
Emeric Brun7f56e742012-10-19 18:15:40 +02003402static int
Emeric Brunba841a12014-04-30 17:05:08 +02003403smp_fetch_ssl_x_sig_alg(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Thierry FOURNIERf41a8092014-12-07 18:37:57 +01003404 const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun7f56e742012-10-19 18:15:40 +02003405{
Emeric Brunba841a12014-04-30 17:05:08 +02003406 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brun7f56e742012-10-19 18:15:40 +02003407 X509 *crt;
3408 int nid;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003409 struct connection *conn;
Emeric Brun7f56e742012-10-19 18:15:40 +02003410
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003411 if (!l4)
Emeric Brun7f56e742012-10-19 18:15:40 +02003412 return 0;
3413
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003414 conn = objt_conn(l4->si[0].end);
3415 if (!conn || conn->xprt != &ssl_sock)
3416 return 0;
3417
3418 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun7f56e742012-10-19 18:15:40 +02003419 smp->flags |= SMP_F_MAY_CHANGE;
3420 return 0;
3421 }
3422
Emeric Brunba841a12014-04-30 17:05:08 +02003423 if (cert_peer)
3424 crt = SSL_get_peer_certificate(conn->xprt_ctx);
3425 else
3426 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brun7f56e742012-10-19 18:15:40 +02003427 if (!crt)
3428 return 0;
3429
3430 nid = OBJ_obj2nid((ASN1_OBJECT *)(crt->cert_info->signature->algorithm));
3431
3432 smp->data.str.str = (char *)OBJ_nid2sn(nid);
Emeric Brun9bf3ba22013-10-07 14:31:44 +02003433 if (!smp->data.str.str) {
Emeric Brunba841a12014-04-30 17:05:08 +02003434 /* SSL_get_peer_certificate increase X509 * ref count */
3435 if (cert_peer)
3436 X509_free(crt);
Emeric Brun7f56e742012-10-19 18:15:40 +02003437 return 0;
Emeric Brun9bf3ba22013-10-07 14:31:44 +02003438 }
Emeric Brun7f56e742012-10-19 18:15:40 +02003439
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01003440 smp->type = SMP_T_STR;
3441 smp->flags |= SMP_F_CONST;
Emeric Brun7f56e742012-10-19 18:15:40 +02003442 smp->data.str.len = strlen(smp->data.str.str);
Emeric Brunba841a12014-04-30 17:05:08 +02003443 /* SSL_get_peer_certificate increase X509 * ref count */
3444 if (cert_peer)
3445 X509_free(crt);
Emeric Brun7f56e742012-10-19 18:15:40 +02003446
3447 return 1;
3448}
3449
Emeric Brunba841a12014-04-30 17:05:08 +02003450/* string, returns the certificate's key algorithm.
3451 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
3452 * should be use.
3453 */
Emeric Brun521a0112012-10-22 12:22:55 +02003454static int
Emeric Brunba841a12014-04-30 17:05:08 +02003455smp_fetch_ssl_x_key_alg(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Thierry FOURNIERf41a8092014-12-07 18:37:57 +01003456 const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun521a0112012-10-22 12:22:55 +02003457{
Emeric Brunba841a12014-04-30 17:05:08 +02003458 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brun521a0112012-10-22 12:22:55 +02003459 X509 *crt;
3460 int nid;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003461 struct connection *conn;
Emeric Brun521a0112012-10-22 12:22:55 +02003462
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003463 if (!l4)
Emeric Brun521a0112012-10-22 12:22:55 +02003464 return 0;
3465
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003466 conn = objt_conn(l4->si[0].end);
3467 if (!conn || conn->xprt != &ssl_sock)
3468 return 0;
3469
3470 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun521a0112012-10-22 12:22:55 +02003471 smp->flags |= SMP_F_MAY_CHANGE;
3472 return 0;
3473 }
3474
Emeric Brunba841a12014-04-30 17:05:08 +02003475 if (cert_peer)
3476 crt = SSL_get_peer_certificate(conn->xprt_ctx);
3477 else
3478 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brun521a0112012-10-22 12:22:55 +02003479 if (!crt)
3480 return 0;
3481
3482 nid = OBJ_obj2nid((ASN1_OBJECT *)(crt->cert_info->key->algor->algorithm));
3483
3484 smp->data.str.str = (char *)OBJ_nid2sn(nid);
Emeric Brun9bf3ba22013-10-07 14:31:44 +02003485 if (!smp->data.str.str) {
Emeric Brunba841a12014-04-30 17:05:08 +02003486 /* SSL_get_peer_certificate increase X509 * ref count */
3487 if (cert_peer)
3488 X509_free(crt);
Emeric Brun521a0112012-10-22 12:22:55 +02003489 return 0;
Emeric Brun9bf3ba22013-10-07 14:31:44 +02003490 }
Emeric Brun521a0112012-10-22 12:22:55 +02003491
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01003492 smp->type = SMP_T_STR;
3493 smp->flags |= SMP_F_CONST;
Emeric Brun521a0112012-10-22 12:22:55 +02003494 smp->data.str.len = strlen(smp->data.str.str);
Emeric Brunba841a12014-04-30 17:05:08 +02003495 if (cert_peer)
3496 X509_free(crt);
Emeric Brun521a0112012-10-22 12:22:55 +02003497
3498 return 1;
3499}
3500
Emeric Brun645ae792014-04-30 14:21:06 +02003501/* boolean, returns true if front conn. transport layer is SSL.
3502 * This function is also usable on backend conn if the fetch keyword 5th
3503 * char is 'b'.
3504 */
Willy Tarreau7875d092012-09-10 08:20:03 +02003505static int
Emeric Brun2525b6b2012-10-18 15:59:43 +02003506smp_fetch_ssl_fc(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Thierry FOURNIERf41a8092014-12-07 18:37:57 +01003507 const struct arg *args, struct sample *smp, const char *kw, void *private)
Willy Tarreau7875d092012-09-10 08:20:03 +02003508{
Emeric Brun645ae792014-04-30 14:21:06 +02003509 int back_conn = (kw[4] == 'b') ? 1 : 0;
3510 struct connection *conn = objt_conn(l4->si[back_conn].end);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003511
Willy Tarreau7875d092012-09-10 08:20:03 +02003512 smp->type = SMP_T_BOOL;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003513 smp->data.uint = (conn && conn->xprt == &ssl_sock);
Willy Tarreau7875d092012-09-10 08:20:03 +02003514 return 1;
3515}
3516
Emeric Brun2525b6b2012-10-18 15:59:43 +02003517/* boolean, returns true if client present a SNI */
Willy Tarreau7875d092012-09-10 08:20:03 +02003518static int
Emeric Brun2525b6b2012-10-18 15:59:43 +02003519smp_fetch_ssl_fc_has_sni(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Thierry FOURNIERf41a8092014-12-07 18:37:57 +01003520 const struct arg *args, struct sample *smp, const char *kw, void *private)
Willy Tarreau7875d092012-09-10 08:20:03 +02003521{
3522#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003523 struct connection *conn = objt_conn(l4->si[0].end);
3524
Willy Tarreau7875d092012-09-10 08:20:03 +02003525 smp->type = SMP_T_BOOL;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003526 smp->data.uint = (conn && conn->xprt == &ssl_sock) &&
3527 conn->xprt_ctx &&
3528 SSL_get_servername(conn->xprt_ctx, TLSEXT_NAMETYPE_host_name) != NULL;
Willy Tarreau7875d092012-09-10 08:20:03 +02003529 return 1;
3530#else
3531 return 0;
3532#endif
3533}
3534
Emeric Brun645ae792014-04-30 14:21:06 +02003535/* string, returns the used cipher if front conn. transport layer is SSL.
3536 * This function is also usable on backend conn if the fetch keyword 5th
3537 * char is 'b'.
3538 */
Emeric Brun589fcad2012-10-16 14:13:26 +02003539static int
3540smp_fetch_ssl_fc_cipher(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Thierry FOURNIERf41a8092014-12-07 18:37:57 +01003541 const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun589fcad2012-10-16 14:13:26 +02003542{
Emeric Brun645ae792014-04-30 14:21:06 +02003543 int back_conn = (kw[4] == 'b') ? 1 : 0;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003544 struct connection *conn;
3545
Emeric Brun589fcad2012-10-16 14:13:26 +02003546 smp->flags = 0;
3547
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003548 if (!l4)
3549 return 0;
3550
Emeric Brun645ae792014-04-30 14:21:06 +02003551 conn = objt_conn(l4->si[back_conn].end);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003552 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
Emeric Brun589fcad2012-10-16 14:13:26 +02003553 return 0;
3554
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003555 smp->data.str.str = (char *)SSL_get_cipher_name(conn->xprt_ctx);
Emeric Brun589fcad2012-10-16 14:13:26 +02003556 if (!smp->data.str.str)
3557 return 0;
3558
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01003559 smp->type = SMP_T_STR;
3560 smp->flags |= SMP_F_CONST;
Emeric Brun589fcad2012-10-16 14:13:26 +02003561 smp->data.str.len = strlen(smp->data.str.str);
3562
3563 return 1;
3564}
3565
Emeric Brun645ae792014-04-30 14:21:06 +02003566/* integer, returns the algoritm's keysize if front conn. transport layer
3567 * is SSL.
3568 * This function is also usable on backend conn if the fetch keyword 5th
3569 * char is 'b'.
3570 */
Emeric Brun589fcad2012-10-16 14:13:26 +02003571static int
3572smp_fetch_ssl_fc_alg_keysize(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Thierry FOURNIERf41a8092014-12-07 18:37:57 +01003573 const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun589fcad2012-10-16 14:13:26 +02003574{
Emeric Brun645ae792014-04-30 14:21:06 +02003575 int back_conn = (kw[4] == 'b') ? 1 : 0;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003576 struct connection *conn;
3577
Emeric Brun589fcad2012-10-16 14:13:26 +02003578 smp->flags = 0;
3579
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003580 if (!l4)
Emeric Brun589fcad2012-10-16 14:13:26 +02003581 return 0;
3582
Emeric Brun645ae792014-04-30 14:21:06 +02003583 conn = objt_conn(l4->si[back_conn].end);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003584 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
Emeric Brun589fcad2012-10-16 14:13:26 +02003585 return 0;
3586
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003587 if (!SSL_get_cipher_bits(conn->xprt_ctx, (int *)&smp->data.uint))
3588 return 0;
3589
Emeric Brun589fcad2012-10-16 14:13:26 +02003590 smp->type = SMP_T_UINT;
3591
3592 return 1;
3593}
3594
Emeric Brun645ae792014-04-30 14:21:06 +02003595/* integer, returns the used keysize if front conn. transport layer is SSL.
3596 * This function is also usable on backend conn if the fetch keyword 5th
3597 * char is 'b'.
3598 */
Emeric Brun589fcad2012-10-16 14:13:26 +02003599static int
3600smp_fetch_ssl_fc_use_keysize(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Thierry FOURNIERf41a8092014-12-07 18:37:57 +01003601 const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun589fcad2012-10-16 14:13:26 +02003602{
Emeric Brun645ae792014-04-30 14:21:06 +02003603 int back_conn = (kw[4] == 'b') ? 1 : 0;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003604 struct connection *conn;
3605
Emeric Brun589fcad2012-10-16 14:13:26 +02003606 smp->flags = 0;
3607
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003608 if (!l4)
Emeric Brun589fcad2012-10-16 14:13:26 +02003609 return 0;
3610
Emeric Brun645ae792014-04-30 14:21:06 +02003611 conn = objt_conn(l4->si[back_conn].end);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003612 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
3613 return 0;
3614
3615 smp->data.uint = (unsigned int)SSL_get_cipher_bits(conn->xprt_ctx, NULL);
Emeric Brun589fcad2012-10-16 14:13:26 +02003616 if (!smp->data.uint)
3617 return 0;
3618
3619 smp->type = SMP_T_UINT;
3620
3621 return 1;
3622}
3623
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02003624#ifdef OPENSSL_NPN_NEGOTIATED
Willy Tarreau7875d092012-09-10 08:20:03 +02003625static int
Emeric Brun2525b6b2012-10-18 15:59:43 +02003626smp_fetch_ssl_fc_npn(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Thierry FOURNIERf41a8092014-12-07 18:37:57 +01003627 const struct arg *args, struct sample *smp, const char *kw, void *private)
Willy Tarreaua33c6542012-10-15 13:19:06 +02003628{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003629 struct connection *conn;
3630
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01003631 smp->flags = SMP_F_CONST;
3632 smp->type = SMP_T_STR;
Willy Tarreaua33c6542012-10-15 13:19:06 +02003633
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003634 if (!l4)
Willy Tarreaua33c6542012-10-15 13:19:06 +02003635 return 0;
3636
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003637 conn = objt_conn(l4->si[0].end);
3638 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
3639 return 0;
3640
Willy Tarreaua33c6542012-10-15 13:19:06 +02003641 smp->data.str.str = NULL;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003642 SSL_get0_next_proto_negotiated(conn->xprt_ctx,
Willy Tarreaua33c6542012-10-15 13:19:06 +02003643 (const unsigned char **)&smp->data.str.str, (unsigned *)&smp->data.str.len);
3644
3645 if (!smp->data.str.str)
3646 return 0;
3647
3648 return 1;
Willy Tarreaua33c6542012-10-15 13:19:06 +02003649}
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02003650#endif
Willy Tarreaua33c6542012-10-15 13:19:06 +02003651
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01003652#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Willy Tarreauab861d32013-04-02 02:30:41 +02003653static int
3654smp_fetch_ssl_fc_alpn(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Thierry FOURNIERf41a8092014-12-07 18:37:57 +01003655 const struct arg *args, struct sample *smp, const char *kw, void *private)
Willy Tarreauab861d32013-04-02 02:30:41 +02003656{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003657 struct connection *conn;
3658
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01003659 smp->flags = SMP_F_CONST;
3660 smp->type = SMP_T_STR;
Willy Tarreauab861d32013-04-02 02:30:41 +02003661
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003662 if (!l4)
3663 return 0;
3664
3665 conn = objt_conn(l4->si[0].end);
3666 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
Willy Tarreauab861d32013-04-02 02:30:41 +02003667 return 0;
3668
3669 smp->data.str.str = NULL;
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01003670 SSL_get0_alpn_selected(conn->xprt_ctx,
Willy Tarreauab861d32013-04-02 02:30:41 +02003671 (const unsigned char **)&smp->data.str.str, (unsigned *)&smp->data.str.len);
3672
3673 if (!smp->data.str.str)
3674 return 0;
3675
3676 return 1;
3677}
3678#endif
3679
Emeric Brun645ae792014-04-30 14:21:06 +02003680/* string, returns the used protocol if front conn. transport layer is SSL.
3681 * This function is also usable on backend conn if the fetch keyword 5th
3682 * char is 'b'.
3683 */
Willy Tarreaua33c6542012-10-15 13:19:06 +02003684static int
Emeric Brun589fcad2012-10-16 14:13:26 +02003685smp_fetch_ssl_fc_protocol(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Thierry FOURNIERf41a8092014-12-07 18:37:57 +01003686 const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun589fcad2012-10-16 14:13:26 +02003687{
Emeric Brun645ae792014-04-30 14:21:06 +02003688 int back_conn = (kw[4] == 'b') ? 1 : 0;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003689 struct connection *conn;
3690
Emeric Brun589fcad2012-10-16 14:13:26 +02003691 smp->flags = 0;
3692
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003693 if (!l4)
Emeric Brun589fcad2012-10-16 14:13:26 +02003694 return 0;
3695
Emeric Brun645ae792014-04-30 14:21:06 +02003696 conn = objt_conn(l4->si[back_conn].end);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003697 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
3698 return 0;
3699
3700 smp->data.str.str = (char *)SSL_get_version(conn->xprt_ctx);
Emeric Brun589fcad2012-10-16 14:13:26 +02003701 if (!smp->data.str.str)
3702 return 0;
3703
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01003704 smp->type = SMP_T_STR;
3705 smp->flags = SMP_F_CONST;
Emeric Brun589fcad2012-10-16 14:13:26 +02003706 smp->data.str.len = strlen(smp->data.str.str);
3707
3708 return 1;
3709}
3710
Emeric Brun645ae792014-04-30 14:21:06 +02003711/* binary, returns the SSL session id if front conn. transport layer is SSL.
3712 * This function is also usable on backend conn if the fetch keyword 5th
3713 * char is 'b'.
3714 */
Emeric Brun589fcad2012-10-16 14:13:26 +02003715static int
Emeric Brunfe68f682012-10-16 14:59:28 +02003716smp_fetch_ssl_fc_session_id(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Thierry FOURNIERf41a8092014-12-07 18:37:57 +01003717 const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brunfe68f682012-10-16 14:59:28 +02003718{
3719#if OPENSSL_VERSION_NUMBER > 0x0090800fL
Emeric Brun645ae792014-04-30 14:21:06 +02003720 int back_conn = (kw[4] == 'b') ? 1 : 0;
Emeric Brunfe68f682012-10-16 14:59:28 +02003721 SSL_SESSION *sess;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003722 struct connection *conn;
Emeric Brunfe68f682012-10-16 14:59:28 +02003723
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01003724 smp->flags = SMP_F_CONST;
3725 smp->type = SMP_T_BIN;
Emeric Brunfe68f682012-10-16 14:59:28 +02003726
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003727 if (!l4)
Emeric Brunfe68f682012-10-16 14:59:28 +02003728 return 0;
3729
Emeric Brun645ae792014-04-30 14:21:06 +02003730 conn = objt_conn(l4->si[back_conn].end);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003731 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
3732 return 0;
3733
3734 sess = SSL_get_session(conn->xprt_ctx);
Emeric Brunfe68f682012-10-16 14:59:28 +02003735 if (!sess)
3736 return 0;
3737
3738 smp->data.str.str = (char *)SSL_SESSION_get_id(sess, (unsigned int *)&smp->data.str.len);
3739 if (!smp->data.str.str || !&smp->data.str.len)
3740 return 0;
3741
3742 return 1;
3743#else
3744 return 0;
3745#endif
3746}
3747
3748static int
Emeric Brun2525b6b2012-10-18 15:59:43 +02003749smp_fetch_ssl_fc_sni(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Thierry FOURNIERf41a8092014-12-07 18:37:57 +01003750 const struct arg *args, struct sample *smp, const char *kw, void *private)
Willy Tarreau7875d092012-09-10 08:20:03 +02003751{
3752#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003753 struct connection *conn;
3754
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01003755 smp->flags = SMP_F_CONST;
3756 smp->type = SMP_T_STR;
Willy Tarreau7875d092012-09-10 08:20:03 +02003757
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003758 if (!l4)
Willy Tarreau7875d092012-09-10 08:20:03 +02003759 return 0;
3760
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003761 conn = objt_conn(l4->si[0].end);
3762 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
3763 return 0;
3764
3765 smp->data.str.str = (char *)SSL_get_servername(conn->xprt_ctx, TLSEXT_NAMETYPE_host_name);
Willy Tarreau3e394c92012-09-14 23:56:58 +02003766 if (!smp->data.str.str)
3767 return 0;
3768
Willy Tarreau7875d092012-09-10 08:20:03 +02003769 smp->data.str.len = strlen(smp->data.str.str);
3770 return 1;
3771#else
3772 return 0;
3773#endif
3774}
3775
David Sc1ad52e2014-04-08 18:48:47 -04003776static int
3777smp_fetch_ssl_fc_unique_id(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Thierry FOURNIERf41a8092014-12-07 18:37:57 +01003778 const struct arg *args, struct sample *smp, const char *kw, void *private)
David Sc1ad52e2014-04-08 18:48:47 -04003779{
3780#if OPENSSL_VERSION_NUMBER > 0x0090800fL
Emeric Brun645ae792014-04-30 14:21:06 +02003781 int back_conn = (kw[4] == 'b') ? 1 : 0;
David Sc1ad52e2014-04-08 18:48:47 -04003782 struct connection *conn;
3783 int finished_len;
David Sc1ad52e2014-04-08 18:48:47 -04003784 struct chunk *finished_trash;
David Sc1ad52e2014-04-08 18:48:47 -04003785
3786 smp->flags = 0;
3787
3788 if (!l4)
3789 return 0;
3790
Emeric Brun645ae792014-04-30 14:21:06 +02003791 conn = objt_conn(l4->si[back_conn].end);
David Sc1ad52e2014-04-08 18:48:47 -04003792 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
3793 return 0;
3794
3795 if (!(conn->flags & CO_FL_CONNECTED)) {
3796 smp->flags |= SMP_F_MAY_CHANGE;
3797 return 0;
3798 }
3799
3800 finished_trash = get_trash_chunk();
3801 if (!SSL_session_reused(conn->xprt_ctx))
3802 finished_len = SSL_get_peer_finished(conn->xprt_ctx, finished_trash->str, finished_trash->size);
3803 else
3804 finished_len = SSL_get_finished(conn->xprt_ctx, finished_trash->str, finished_trash->size);
3805
3806 if (!finished_len)
3807 return 0;
3808
Emeric Brunb73a9b02014-04-30 18:49:19 +02003809 finished_trash->len = finished_len;
3810 smp->data.str = *finished_trash;
3811 smp->type = SMP_T_BIN;
David Sc1ad52e2014-04-08 18:48:47 -04003812
3813 return 1;
3814#else
3815 return 0;
3816#endif
3817}
3818
Emeric Brun2525b6b2012-10-18 15:59:43 +02003819/* integer, returns the first verify error in CA chain of client certificate chain. */
Emeric Brunf282a812012-09-21 15:27:54 +02003820static int
Emeric Brun2525b6b2012-10-18 15:59:43 +02003821smp_fetch_ssl_c_ca_err(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Thierry FOURNIERf41a8092014-12-07 18:37:57 +01003822 const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brunf282a812012-09-21 15:27:54 +02003823{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003824 struct connection *conn;
3825
3826 if (!l4)
Emeric Brunf282a812012-09-21 15:27:54 +02003827 return 0;
3828
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003829 conn = objt_conn(l4->si[0].end);
3830 if (!conn || conn->xprt != &ssl_sock)
3831 return 0;
3832
3833 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunf282a812012-09-21 15:27:54 +02003834 smp->flags = SMP_F_MAY_CHANGE;
3835 return 0;
3836 }
3837
3838 smp->type = SMP_T_UINT;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003839 smp->data.uint = (unsigned int)SSL_SOCK_ST_TO_CA_ERROR(conn->xprt_st);
Emeric Brunf282a812012-09-21 15:27:54 +02003840 smp->flags = 0;
3841
3842 return 1;
3843}
3844
Emeric Brun2525b6b2012-10-18 15:59:43 +02003845/* integer, returns the depth of the first verify error in CA chain of client certificate chain. */
Emeric Brunf282a812012-09-21 15:27:54 +02003846static int
Emeric Brun2525b6b2012-10-18 15:59:43 +02003847smp_fetch_ssl_c_ca_err_depth(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Thierry FOURNIERf41a8092014-12-07 18:37:57 +01003848 const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brunf282a812012-09-21 15:27:54 +02003849{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003850 struct connection *conn;
3851
3852 if (!l4)
3853 return 0;
3854
3855 conn = objt_conn(l4->si[0].end);
3856 if (!conn || conn->xprt != &ssl_sock)
Emeric Brunf282a812012-09-21 15:27:54 +02003857 return 0;
3858
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003859 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunf282a812012-09-21 15:27:54 +02003860 smp->flags = SMP_F_MAY_CHANGE;
3861 return 0;
3862 }
3863
3864 smp->type = SMP_T_UINT;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003865 smp->data.uint = (unsigned int)SSL_SOCK_ST_TO_CAEDEPTH(conn->xprt_st);
Emeric Brunf282a812012-09-21 15:27:54 +02003866 smp->flags = 0;
3867
3868 return 1;
3869}
3870
Emeric Brun2525b6b2012-10-18 15:59:43 +02003871/* integer, returns the first verify error on client certificate */
Emeric Brunf282a812012-09-21 15:27:54 +02003872static int
Emeric Brun2525b6b2012-10-18 15:59:43 +02003873smp_fetch_ssl_c_err(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Thierry FOURNIERf41a8092014-12-07 18:37:57 +01003874 const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brunf282a812012-09-21 15:27:54 +02003875{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003876 struct connection *conn;
3877
3878 if (!l4)
Emeric Brunf282a812012-09-21 15:27:54 +02003879 return 0;
3880
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003881 conn = objt_conn(l4->si[0].end);
3882 if (!conn || conn->xprt != &ssl_sock)
3883 return 0;
3884
3885 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunf282a812012-09-21 15:27:54 +02003886 smp->flags = SMP_F_MAY_CHANGE;
3887 return 0;
3888 }
3889
3890 smp->type = SMP_T_UINT;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003891 smp->data.uint = (unsigned int)SSL_SOCK_ST_TO_CRTERROR(conn->xprt_st);
Emeric Brunf282a812012-09-21 15:27:54 +02003892 smp->flags = 0;
3893
3894 return 1;
3895}
3896
Emeric Brun2525b6b2012-10-18 15:59:43 +02003897/* integer, returns the verify result on client cert */
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02003898static int
Emeric Brun2525b6b2012-10-18 15:59:43 +02003899smp_fetch_ssl_c_verify(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Thierry FOURNIERf41a8092014-12-07 18:37:57 +01003900 const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02003901{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003902 struct connection *conn;
3903
3904 if (!l4)
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02003905 return 0;
3906
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003907 conn = objt_conn(l4->si[0].end);
3908 if (!conn || conn->xprt != &ssl_sock)
3909 return 0;
3910
3911 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02003912 smp->flags = SMP_F_MAY_CHANGE;
3913 return 0;
3914 }
3915
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003916 if (!conn->xprt_ctx)
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02003917 return 0;
3918
3919 smp->type = SMP_T_UINT;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003920 smp->data.uint = (unsigned int)SSL_get_verify_result(conn->xprt_ctx);
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02003921 smp->flags = 0;
3922
3923 return 1;
3924}
3925
Emeric Brunfb510ea2012-10-05 12:00:26 +02003926/* parse the "ca-file" bind keyword */
3927static 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 +02003928{
3929 if (!*args[cur_arg + 1]) {
3930 if (err)
3931 memprintf(err, "'%s' : missing CAfile path", args[cur_arg]);
3932 return ERR_ALERT | ERR_FATAL;
3933 }
3934
Emeric Brunef42d922012-10-11 16:11:36 +02003935 if ((*args[cur_arg + 1] != '/') && global.ca_base)
3936 memprintf(&conf->ca_file, "%s/%s", global.ca_base, args[cur_arg + 1]);
3937 else
3938 memprintf(&conf->ca_file, "%s", args[cur_arg + 1]);
Emeric Brunc8e8d122012-10-02 18:42:10 +02003939
Emeric Brund94b3fe2012-09-20 18:23:56 +02003940 return 0;
3941}
3942
Willy Tarreau79eeafa2012-09-14 07:53:05 +02003943/* parse the "ciphers" bind keyword */
Willy Tarreau4348fad2012-09-20 16:48:07 +02003944static 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 +02003945{
3946 if (!*args[cur_arg + 1]) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02003947 memprintf(err, "'%s' : missing cipher suite", args[cur_arg]);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02003948 return ERR_ALERT | ERR_FATAL;
3949 }
3950
Emeric Brun76d88952012-10-05 15:47:31 +02003951 free(conf->ciphers);
Willy Tarreau4348fad2012-09-20 16:48:07 +02003952 conf->ciphers = strdup(args[cur_arg + 1]);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02003953 return 0;
3954}
3955
3956/* parse the "crt" bind keyword */
Willy Tarreau4348fad2012-09-20 16:48:07 +02003957static 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 +02003958{
Willy Tarreau38011032013-08-13 16:59:39 +02003959 char path[MAXPATHLEN];
Willy Tarreaub75d6922014-04-14 18:05:41 +02003960
Willy Tarreau79eeafa2012-09-14 07:53:05 +02003961 if (!*args[cur_arg + 1]) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02003962 memprintf(err, "'%s' : missing certificate location", args[cur_arg]);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02003963 return ERR_ALERT | ERR_FATAL;
3964 }
3965
Emeric Brunc8e8d122012-10-02 18:42:10 +02003966 if ((*args[cur_arg + 1] != '/' ) && global.crt_base) {
Willy Tarreau38011032013-08-13 16:59:39 +02003967 if ((strlen(global.crt_base) + 1 + strlen(args[cur_arg + 1]) + 1) > MAXPATHLEN) {
Emeric Brunc8e8d122012-10-02 18:42:10 +02003968 memprintf(err, "'%s' : path too long", args[cur_arg]);
3969 return ERR_ALERT | ERR_FATAL;
3970 }
Willy Tarreaub75d6922014-04-14 18:05:41 +02003971 snprintf(path, sizeof(path), "%s/%s", global.crt_base, args[cur_arg + 1]);
Emeric Brunc8e8d122012-10-02 18:42:10 +02003972 if (ssl_sock_load_cert(path, conf, px, err) > 0)
3973 return ERR_ALERT | ERR_FATAL;
3974
3975 return 0;
3976 }
3977
Willy Tarreau4348fad2012-09-20 16:48:07 +02003978 if (ssl_sock_load_cert(args[cur_arg + 1], conf, px, err) > 0)
Willy Tarreau79eeafa2012-09-14 07:53:05 +02003979 return ERR_ALERT | ERR_FATAL;
Emeric Brund94b3fe2012-09-20 18:23:56 +02003980
3981 return 0;
3982}
3983
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01003984/* parse the "crt-list" bind keyword */
3985static int bind_parse_crt_list(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
3986{
3987 if (!*args[cur_arg + 1]) {
3988 memprintf(err, "'%s' : missing certificate location", args[cur_arg]);
3989 return ERR_ALERT | ERR_FATAL;
3990 }
3991
Willy Tarreauad1731d2013-04-02 17:35:58 +02003992 if (ssl_sock_load_cert_list_file(args[cur_arg + 1], conf, px, err) > 0) {
3993 memprintf(err, "'%s' : %s", args[cur_arg], *err);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01003994 return ERR_ALERT | ERR_FATAL;
Willy Tarreauad1731d2013-04-02 17:35:58 +02003995 }
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01003996
3997 return 0;
3998}
3999
Emeric Brunfb510ea2012-10-05 12:00:26 +02004000/* parse the "crl-file" bind keyword */
4001static 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 +02004002{
Emeric Brun051cdab2012-10-02 19:25:50 +02004003#ifndef X509_V_FLAG_CRL_CHECK
4004 if (err)
4005 memprintf(err, "'%s' : library does not support CRL verify", args[cur_arg]);
4006 return ERR_ALERT | ERR_FATAL;
4007#else
Emeric Brund94b3fe2012-09-20 18:23:56 +02004008 if (!*args[cur_arg + 1]) {
4009 if (err)
4010 memprintf(err, "'%s' : missing CRLfile path", args[cur_arg]);
4011 return ERR_ALERT | ERR_FATAL;
4012 }
Emeric Brun2b58d042012-09-20 17:10:03 +02004013
Emeric Brunef42d922012-10-11 16:11:36 +02004014 if ((*args[cur_arg + 1] != '/') && global.ca_base)
4015 memprintf(&conf->crl_file, "%s/%s", global.ca_base, args[cur_arg + 1]);
4016 else
4017 memprintf(&conf->crl_file, "%s", args[cur_arg + 1]);
Emeric Brunc8e8d122012-10-02 18:42:10 +02004018
Emeric Brun2b58d042012-09-20 17:10:03 +02004019 return 0;
Emeric Brun051cdab2012-10-02 19:25:50 +02004020#endif
Emeric Brun2b58d042012-09-20 17:10:03 +02004021}
4022
4023/* parse the "ecdhe" bind keyword keywords */
4024static int bind_parse_ecdhe(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
4025{
4026#if OPENSSL_VERSION_NUMBER < 0x0090800fL
4027 if (err)
4028 memprintf(err, "'%s' : library does not support elliptic curve Diffie-Hellman (too old)", args[cur_arg]);
4029 return ERR_ALERT | ERR_FATAL;
4030#elif defined(OPENSSL_NO_ECDH)
4031 if (err)
4032 memprintf(err, "'%s' : library does not support elliptic curve Diffie-Hellman (disabled via OPENSSL_NO_ECDH)", args[cur_arg]);
4033 return ERR_ALERT | ERR_FATAL;
4034#else
4035 if (!*args[cur_arg + 1]) {
4036 if (err)
4037 memprintf(err, "'%s' : missing named curve", args[cur_arg]);
4038 return ERR_ALERT | ERR_FATAL;
4039 }
4040
4041 conf->ecdhe = strdup(args[cur_arg + 1]);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02004042
4043 return 0;
Emeric Brun2b58d042012-09-20 17:10:03 +02004044#endif
Willy Tarreau79eeafa2012-09-14 07:53:05 +02004045}
4046
Emeric Brun81c00f02012-09-21 14:31:21 +02004047/* parse the "crt_ignerr" and "ca_ignerr" bind keywords */
4048static int bind_parse_ignore_err(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
4049{
4050 int code;
4051 char *p = args[cur_arg + 1];
4052 unsigned long long *ignerr = &conf->crt_ignerr;
4053
4054 if (!*p) {
4055 if (err)
4056 memprintf(err, "'%s' : missing error IDs list", args[cur_arg]);
4057 return ERR_ALERT | ERR_FATAL;
4058 }
4059
4060 if (strcmp(args[cur_arg], "ca-ignore-err") == 0)
4061 ignerr = &conf->ca_ignerr;
4062
4063 if (strcmp(p, "all") == 0) {
4064 *ignerr = ~0ULL;
4065 return 0;
4066 }
4067
4068 while (p) {
4069 code = atoi(p);
4070 if ((code <= 0) || (code > 63)) {
4071 if (err)
4072 memprintf(err, "'%s' : ID '%d' out of range (1..63) in error IDs list '%s'",
4073 args[cur_arg], code, args[cur_arg + 1]);
4074 return ERR_ALERT | ERR_FATAL;
4075 }
4076 *ignerr |= 1ULL << code;
4077 p = strchr(p, ',');
4078 if (p)
4079 p++;
4080 }
4081
Emeric Brun2cb7ae52012-10-05 14:14:21 +02004082 return 0;
4083}
4084
4085/* parse the "force-sslv3" bind keyword */
4086static int bind_parse_force_sslv3(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
4087{
4088 conf->ssl_options |= BC_SSL_O_USE_SSLV3;
4089 return 0;
4090}
4091
4092/* parse the "force-tlsv10" bind keyword */
4093static int bind_parse_force_tlsv10(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
4094{
4095 conf->ssl_options |= BC_SSL_O_USE_TLSV10;
Emeric Brun2d0c4822012-10-02 13:45:20 +02004096 return 0;
4097}
4098
Emeric Brun2cb7ae52012-10-05 14:14:21 +02004099/* parse the "force-tlsv11" bind keyword */
4100static int bind_parse_force_tlsv11(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
4101{
4102#if SSL_OP_NO_TLSv1_1
4103 conf->ssl_options |= BC_SSL_O_USE_TLSV11;
4104 return 0;
4105#else
4106 if (err)
4107 memprintf(err, "'%s' : library does not support protocol TLSv1.1", args[cur_arg]);
4108 return ERR_ALERT | ERR_FATAL;
4109#endif
4110}
4111
4112/* parse the "force-tlsv12" bind keyword */
4113static int bind_parse_force_tlsv12(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
4114{
4115#if SSL_OP_NO_TLSv1_2
4116 conf->ssl_options |= BC_SSL_O_USE_TLSV12;
4117 return 0;
4118#else
4119 if (err)
4120 memprintf(err, "'%s' : library does not support protocol TLSv1.2", args[cur_arg]);
4121 return ERR_ALERT | ERR_FATAL;
4122#endif
4123}
4124
4125
Emeric Brun2d0c4822012-10-02 13:45:20 +02004126/* parse the "no-tls-tickets" bind keyword */
4127static int bind_parse_no_tls_tickets(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
4128{
Emeric Brun89675492012-10-05 13:48:26 +02004129 conf->ssl_options |= BC_SSL_O_NO_TLS_TICKETS;
Emeric Brun81c00f02012-09-21 14:31:21 +02004130 return 0;
4131}
4132
Emeric Brun2d0c4822012-10-02 13:45:20 +02004133
Emeric Brun9b3009b2012-10-05 11:55:06 +02004134/* parse the "no-sslv3" bind keyword */
4135static 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 +02004136{
Emeric Brun89675492012-10-05 13:48:26 +02004137 conf->ssl_options |= BC_SSL_O_NO_SSLV3;
Willy Tarreau79eeafa2012-09-14 07:53:05 +02004138 return 0;
4139}
4140
Emeric Brun9b3009b2012-10-05 11:55:06 +02004141/* parse the "no-tlsv10" bind keyword */
4142static 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 +02004143{
Emeric Brun89675492012-10-05 13:48:26 +02004144 conf->ssl_options |= BC_SSL_O_NO_TLSV10;
Emeric Brunc0ff4922012-09-28 19:37:02 +02004145 return 0;
4146}
4147
Emeric Brun9b3009b2012-10-05 11:55:06 +02004148/* parse the "no-tlsv11" bind keyword */
4149static 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 +02004150{
Emeric Brun89675492012-10-05 13:48:26 +02004151 conf->ssl_options |= BC_SSL_O_NO_TLSV11;
Emeric Brunc0ff4922012-09-28 19:37:02 +02004152 return 0;
4153}
4154
Emeric Brun9b3009b2012-10-05 11:55:06 +02004155/* parse the "no-tlsv12" bind keyword */
4156static 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 +02004157{
Emeric Brun89675492012-10-05 13:48:26 +02004158 conf->ssl_options |= BC_SSL_O_NO_TLSV12;
Willy Tarreau79eeafa2012-09-14 07:53:05 +02004159 return 0;
4160}
4161
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02004162/* parse the "npn" bind keyword */
4163static int bind_parse_npn(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
4164{
4165#ifdef OPENSSL_NPN_NEGOTIATED
4166 char *p1, *p2;
4167
4168 if (!*args[cur_arg + 1]) {
4169 memprintf(err, "'%s' : missing the comma-delimited NPN protocol suite", args[cur_arg]);
4170 return ERR_ALERT | ERR_FATAL;
4171 }
4172
4173 free(conf->npn_str);
4174
4175 /* the NPN string is built as a suite of (<len> <name>)* */
4176 conf->npn_len = strlen(args[cur_arg + 1]) + 1;
4177 conf->npn_str = calloc(1, conf->npn_len);
4178 memcpy(conf->npn_str + 1, args[cur_arg + 1], conf->npn_len);
4179
4180 /* replace commas with the name length */
4181 p1 = conf->npn_str;
4182 p2 = p1 + 1;
4183 while (1) {
4184 p2 = memchr(p1 + 1, ',', conf->npn_str + conf->npn_len - (p1 + 1));
4185 if (!p2)
4186 p2 = p1 + 1 + strlen(p1 + 1);
4187
4188 if (p2 - (p1 + 1) > 255) {
4189 *p2 = '\0';
4190 memprintf(err, "'%s' : NPN protocol name too long : '%s'", args[cur_arg], p1 + 1);
4191 return ERR_ALERT | ERR_FATAL;
4192 }
4193
4194 *p1 = p2 - (p1 + 1);
4195 p1 = p2;
4196
4197 if (!*p2)
4198 break;
4199
4200 *(p2++) = '\0';
4201 }
4202 return 0;
4203#else
4204 if (err)
4205 memprintf(err, "'%s' : library does not support TLS NPN extension", args[cur_arg]);
4206 return ERR_ALERT | ERR_FATAL;
4207#endif
4208}
4209
Willy Tarreauab861d32013-04-02 02:30:41 +02004210/* parse the "alpn" bind keyword */
4211static int bind_parse_alpn(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
4212{
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01004213#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Willy Tarreauab861d32013-04-02 02:30:41 +02004214 char *p1, *p2;
4215
4216 if (!*args[cur_arg + 1]) {
4217 memprintf(err, "'%s' : missing the comma-delimited ALPN protocol suite", args[cur_arg]);
4218 return ERR_ALERT | ERR_FATAL;
4219 }
4220
4221 free(conf->alpn_str);
4222
4223 /* the ALPN string is built as a suite of (<len> <name>)* */
4224 conf->alpn_len = strlen(args[cur_arg + 1]) + 1;
4225 conf->alpn_str = calloc(1, conf->alpn_len);
4226 memcpy(conf->alpn_str + 1, args[cur_arg + 1], conf->alpn_len);
4227
4228 /* replace commas with the name length */
4229 p1 = conf->alpn_str;
4230 p2 = p1 + 1;
4231 while (1) {
4232 p2 = memchr(p1 + 1, ',', conf->alpn_str + conf->alpn_len - (p1 + 1));
4233 if (!p2)
4234 p2 = p1 + 1 + strlen(p1 + 1);
4235
4236 if (p2 - (p1 + 1) > 255) {
4237 *p2 = '\0';
4238 memprintf(err, "'%s' : ALPN protocol name too long : '%s'", args[cur_arg], p1 + 1);
4239 return ERR_ALERT | ERR_FATAL;
4240 }
4241
4242 *p1 = p2 - (p1 + 1);
4243 p1 = p2;
4244
4245 if (!*p2)
4246 break;
4247
4248 *(p2++) = '\0';
4249 }
4250 return 0;
4251#else
4252 if (err)
4253 memprintf(err, "'%s' : library does not support TLS ALPN extension", args[cur_arg]);
4254 return ERR_ALERT | ERR_FATAL;
4255#endif
4256}
4257
Willy Tarreau79eeafa2012-09-14 07:53:05 +02004258/* parse the "ssl" bind keyword */
Willy Tarreau4348fad2012-09-20 16:48:07 +02004259static 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 +02004260{
Willy Tarreau81796be2012-09-22 19:11:47 +02004261 struct listener *l;
4262
Willy Tarreau4348fad2012-09-20 16:48:07 +02004263 conf->is_ssl = 1;
Emeric Brun76d88952012-10-05 15:47:31 +02004264
4265 if (global.listen_default_ciphers && !conf->ciphers)
4266 conf->ciphers = strdup(global.listen_default_ciphers);
Emeric Brun2c86cbf2014-10-30 15:56:50 +01004267 conf->ssl_options |= global.listen_default_ssloptions;
Emeric Brun76d88952012-10-05 15:47:31 +02004268
Willy Tarreau81796be2012-09-22 19:11:47 +02004269 list_for_each_entry(l, &conf->listeners, by_bind)
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02004270 l->xprt = &ssl_sock;
Willy Tarreau81796be2012-09-22 19:11:47 +02004271
Willy Tarreau79eeafa2012-09-14 07:53:05 +02004272 return 0;
4273}
4274
Emmanuel Hocdet65623372013-01-24 17:17:15 +01004275/* parse the "strict-sni" bind keyword */
4276static int bind_parse_strict_sni(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
4277{
4278 conf->strict_sni = 1;
4279 return 0;
Nenad Merdanovic05552d42015-02-27 19:56:49 +01004280}
4281
4282/* parse the "tls-ticket-keys" bind keyword */
4283static int bind_parse_tls_ticket_keys(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
4284{
4285#if (defined SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB && TLS_TICKETS_NO > 0)
4286 FILE *f;
4287 int i = 0;
4288 char thisline[LINESIZE];
4289
4290 if (!*args[cur_arg + 1]) {
4291 if (err)
4292 memprintf(err, "'%s' : missing TLS ticket keys file path", args[cur_arg]);
4293 return ERR_ALERT | ERR_FATAL;
4294 }
4295
4296 conf->tls_ticket_keys = malloc(TLS_TICKETS_NO * sizeof(struct tls_sess_key));
4297
4298 if ((f = fopen(args[cur_arg + 1], "r")) == NULL) {
4299 if (err)
4300 memprintf(err, "'%s' : unable to load ssl tickets keys file", args[cur_arg+1]);
4301 return ERR_ALERT | ERR_FATAL;
4302 }
4303
4304 while (fgets(thisline, sizeof(thisline), f) != NULL) {
4305 int len = strlen(thisline);
4306 /* Strip newline characters from the end */
4307 if(thisline[len - 1] == '\n')
4308 thisline[--len] = 0;
4309
4310 if(thisline[len - 1] == '\r')
4311 thisline[--len] = 0;
4312
4313 if (base64dec(thisline, len, (char *) (conf->tls_ticket_keys + i % TLS_TICKETS_NO), sizeof(struct tls_sess_key)) != sizeof(struct tls_sess_key)) {
4314 if (err)
4315 memprintf(err, "'%s' : unable to decode base64 key on line %d", args[cur_arg+1], i + 1);
4316 return ERR_ALERT | ERR_FATAL;
4317 }
4318 i++;
4319 }
4320
4321 if (i < TLS_TICKETS_NO) {
4322 if (err)
4323 memprintf(err, "'%s' : please supply at least %d keys in the tls-tickets-file", args[cur_arg+1], TLS_TICKETS_NO);
4324 return ERR_ALERT | ERR_FATAL;
4325 }
4326
4327 fclose(f);
4328
4329 /* Use penultimate key for encryption, handle when TLS_TICKETS_NO = 1 */
4330 i-=2;
4331 conf->tls_ticket_enc_index = i < 0 ? 0 : i;
4332
4333 return 0;
4334#else
4335 if (err)
4336 memprintf(err, "'%s' : TLS ticket callback extension not supported", args[cur_arg]);
4337 return ERR_ALERT | ERR_FATAL;
4338#endif /* SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB */
Emmanuel Hocdet65623372013-01-24 17:17:15 +01004339}
4340
Emeric Brund94b3fe2012-09-20 18:23:56 +02004341/* parse the "verify" bind keyword */
4342static int bind_parse_verify(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
4343{
4344 if (!*args[cur_arg + 1]) {
4345 if (err)
4346 memprintf(err, "'%s' : missing verify method", args[cur_arg]);
4347 return ERR_ALERT | ERR_FATAL;
4348 }
4349
4350 if (strcmp(args[cur_arg + 1], "none") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01004351 conf->verify = SSL_SOCK_VERIFY_NONE;
Emeric Brund94b3fe2012-09-20 18:23:56 +02004352 else if (strcmp(args[cur_arg + 1], "optional") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01004353 conf->verify = SSL_SOCK_VERIFY_OPTIONAL;
Emeric Brund94b3fe2012-09-20 18:23:56 +02004354 else if (strcmp(args[cur_arg + 1], "required") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01004355 conf->verify = SSL_SOCK_VERIFY_REQUIRED;
Emeric Brund94b3fe2012-09-20 18:23:56 +02004356 else {
4357 if (err)
4358 memprintf(err, "'%s' : unknown verify method '%s', only 'none', 'optional', and 'required' are supported\n",
4359 args[cur_arg], args[cur_arg + 1]);
4360 return ERR_ALERT | ERR_FATAL;
4361 }
4362
4363 return 0;
4364}
4365
Willy Tarreau92faadf2012-10-10 23:04:25 +02004366/************** "server" keywords ****************/
4367
Emeric Brunef42d922012-10-11 16:11:36 +02004368/* parse the "ca-file" server keyword */
4369static int srv_parse_ca_file(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4370{
4371 if (!*args[*cur_arg + 1]) {
4372 if (err)
4373 memprintf(err, "'%s' : missing CAfile path", args[*cur_arg]);
4374 return ERR_ALERT | ERR_FATAL;
4375 }
4376
4377 if ((*args[*cur_arg + 1] != '/') && global.ca_base)
4378 memprintf(&newsrv->ssl_ctx.ca_file, "%s/%s", global.ca_base, args[*cur_arg + 1]);
4379 else
4380 memprintf(&newsrv->ssl_ctx.ca_file, "%s", args[*cur_arg + 1]);
4381
4382 return 0;
4383}
4384
Willy Tarreau92faadf2012-10-10 23:04:25 +02004385/* parse the "check-ssl" server keyword */
4386static int srv_parse_check_ssl(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4387{
4388 newsrv->check.use_ssl = 1;
4389 if (global.connect_default_ciphers && !newsrv->ssl_ctx.ciphers)
4390 newsrv->ssl_ctx.ciphers = strdup(global.connect_default_ciphers);
Emeric Brun2c86cbf2014-10-30 15:56:50 +01004391 newsrv->ssl_ctx.options |= global.connect_default_ssloptions;
Willy Tarreau92faadf2012-10-10 23:04:25 +02004392 return 0;
4393}
4394
4395/* parse the "ciphers" server keyword */
4396static int srv_parse_ciphers(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4397{
4398 if (!*args[*cur_arg + 1]) {
4399 memprintf(err, "'%s' : missing cipher suite", args[*cur_arg]);
4400 return ERR_ALERT | ERR_FATAL;
4401 }
4402
4403 free(newsrv->ssl_ctx.ciphers);
4404 newsrv->ssl_ctx.ciphers = strdup(args[*cur_arg + 1]);
4405 return 0;
4406}
4407
Emeric Brunef42d922012-10-11 16:11:36 +02004408/* parse the "crl-file" server keyword */
4409static int srv_parse_crl_file(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4410{
4411#ifndef X509_V_FLAG_CRL_CHECK
4412 if (err)
4413 memprintf(err, "'%s' : library does not support CRL verify", args[*cur_arg]);
4414 return ERR_ALERT | ERR_FATAL;
4415#else
4416 if (!*args[*cur_arg + 1]) {
4417 if (err)
4418 memprintf(err, "'%s' : missing CRLfile path", args[*cur_arg]);
4419 return ERR_ALERT | ERR_FATAL;
4420 }
4421
4422 if ((*args[*cur_arg + 1] != '/') && global.ca_base)
4423 memprintf(&newsrv->ssl_ctx.crl_file, "%s/%s", global.ca_base, args[*cur_arg + 1]);
4424 else
4425 memprintf(&newsrv->ssl_ctx.crl_file, "%s", args[*cur_arg + 1]);
4426
4427 return 0;
4428#endif
4429}
4430
Emeric Bruna7aa3092012-10-26 12:58:00 +02004431/* parse the "crt" server keyword */
4432static int srv_parse_crt(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4433{
4434 if (!*args[*cur_arg + 1]) {
4435 if (err)
4436 memprintf(err, "'%s' : missing certificate file path", args[*cur_arg]);
4437 return ERR_ALERT | ERR_FATAL;
4438 }
4439
4440 if ((*args[*cur_arg + 1] != '/') && global.crt_base)
4441 memprintf(&newsrv->ssl_ctx.client_crt, "%s/%s", global.ca_base, args[*cur_arg + 1]);
4442 else
4443 memprintf(&newsrv->ssl_ctx.client_crt, "%s", args[*cur_arg + 1]);
4444
4445 return 0;
4446}
Emeric Brunef42d922012-10-11 16:11:36 +02004447
Willy Tarreau92faadf2012-10-10 23:04:25 +02004448/* parse the "force-sslv3" server keyword */
4449static int srv_parse_force_sslv3(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4450{
4451 newsrv->ssl_ctx.options |= SRV_SSL_O_USE_SSLV3;
4452 return 0;
4453}
4454
4455/* parse the "force-tlsv10" server keyword */
4456static int srv_parse_force_tlsv10(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4457{
4458 newsrv->ssl_ctx.options |= SRV_SSL_O_USE_TLSV10;
4459 return 0;
4460}
4461
4462/* parse the "force-tlsv11" server keyword */
4463static int srv_parse_force_tlsv11(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4464{
4465#if SSL_OP_NO_TLSv1_1
4466 newsrv->ssl_ctx.options |= SRV_SSL_O_USE_TLSV11;
4467 return 0;
4468#else
4469 if (err)
4470 memprintf(err, "'%s' : library does not support protocol TLSv1.1", args[*cur_arg]);
4471 return ERR_ALERT | ERR_FATAL;
4472#endif
4473}
4474
4475/* parse the "force-tlsv12" server keyword */
4476static int srv_parse_force_tlsv12(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4477{
4478#if SSL_OP_NO_TLSv1_2
4479 newsrv->ssl_ctx.options |= SRV_SSL_O_USE_TLSV12;
4480 return 0;
4481#else
4482 if (err)
4483 memprintf(err, "'%s' : library does not support protocol TLSv1.2", args[*cur_arg]);
4484 return ERR_ALERT | ERR_FATAL;
4485#endif
4486}
4487
Willy Tarreau2a3fb1c2015-02-05 16:47:07 +01004488/* parse the "no-ssl-reuse" server keyword */
4489static int srv_parse_no_ssl_reuse(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4490{
4491 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_REUSE;
4492 return 0;
4493}
4494
Willy Tarreau92faadf2012-10-10 23:04:25 +02004495/* parse the "no-sslv3" server keyword */
4496static int srv_parse_no_sslv3(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4497{
4498 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_SSLV3;
4499 return 0;
4500}
4501
4502/* parse the "no-tlsv10" server keyword */
4503static int srv_parse_no_tlsv10(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4504{
4505 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_TLSV10;
4506 return 0;
4507}
4508
4509/* parse the "no-tlsv11" server keyword */
4510static int srv_parse_no_tlsv11(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4511{
4512 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_TLSV11;
4513 return 0;
4514}
4515
4516/* parse the "no-tlsv12" server keyword */
4517static int srv_parse_no_tlsv12(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4518{
4519 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_TLSV12;
4520 return 0;
4521}
4522
Emeric Brunf9c5c472012-10-11 15:28:34 +02004523/* parse the "no-tls-tickets" server keyword */
4524static int srv_parse_no_tls_tickets(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4525{
4526 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_TLS_TICKETS;
4527 return 0;
4528}
David Safb76832014-05-08 23:42:08 -04004529/* parse the "send-proxy-v2-ssl" server keyword */
4530static int srv_parse_send_proxy_ssl(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4531{
4532 newsrv->pp_opts |= SRV_PP_V2;
4533 newsrv->pp_opts |= SRV_PP_V2_SSL;
4534 return 0;
4535}
4536
4537/* parse the "send-proxy-v2-ssl-cn" server keyword */
4538static int srv_parse_send_proxy_cn(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4539{
4540 newsrv->pp_opts |= SRV_PP_V2;
4541 newsrv->pp_opts |= SRV_PP_V2_SSL;
4542 newsrv->pp_opts |= SRV_PP_V2_SSL_CN;
4543 return 0;
4544}
Emeric Brunf9c5c472012-10-11 15:28:34 +02004545
Willy Tarreau92faadf2012-10-10 23:04:25 +02004546/* parse the "ssl" server keyword */
4547static int srv_parse_ssl(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4548{
4549 newsrv->use_ssl = 1;
4550 if (global.connect_default_ciphers && !newsrv->ssl_ctx.ciphers)
4551 newsrv->ssl_ctx.ciphers = strdup(global.connect_default_ciphers);
4552 return 0;
4553}
4554
Emeric Brunef42d922012-10-11 16:11:36 +02004555/* parse the "verify" server keyword */
4556static int srv_parse_verify(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4557{
4558 if (!*args[*cur_arg + 1]) {
4559 if (err)
4560 memprintf(err, "'%s' : missing verify method", args[*cur_arg]);
4561 return ERR_ALERT | ERR_FATAL;
4562 }
4563
4564 if (strcmp(args[*cur_arg + 1], "none") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01004565 newsrv->ssl_ctx.verify = SSL_SOCK_VERIFY_NONE;
Emeric Brunef42d922012-10-11 16:11:36 +02004566 else if (strcmp(args[*cur_arg + 1], "required") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01004567 newsrv->ssl_ctx.verify = SSL_SOCK_VERIFY_REQUIRED;
Emeric Brunef42d922012-10-11 16:11:36 +02004568 else {
4569 if (err)
4570 memprintf(err, "'%s' : unknown verify method '%s', only 'none' and 'required' are supported\n",
4571 args[*cur_arg], args[*cur_arg + 1]);
4572 return ERR_ALERT | ERR_FATAL;
4573 }
4574
Evan Broderbe554312013-06-27 00:05:25 -07004575 return 0;
4576}
4577
4578/* parse the "verifyhost" server keyword */
4579static int srv_parse_verifyhost(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4580{
4581 if (!*args[*cur_arg + 1]) {
4582 if (err)
4583 memprintf(err, "'%s' : missing hostname to verify against", args[*cur_arg]);
4584 return ERR_ALERT | ERR_FATAL;
4585 }
4586
4587 newsrv->ssl_ctx.verify_host = strdup(args[*cur_arg + 1]);
4588
Emeric Brunef42d922012-10-11 16:11:36 +02004589 return 0;
4590}
4591
Emeric Brun2c86cbf2014-10-30 15:56:50 +01004592/* parse the "ssl-default-bind-options" keyword in global section */
4593static int ssl_parse_default_bind_options(char **args, int section_type, struct proxy *curpx,
4594 struct proxy *defpx, const char *file, int line,
4595 char **err) {
4596 int i = 1;
4597
4598 if (*(args[i]) == 0) {
4599 memprintf(err, "global statement '%s' expects an option as an argument.", args[0]);
4600 return -1;
4601 }
4602 while (*(args[i])) {
4603 if (!strcmp(args[i], "no-sslv3"))
4604 global.listen_default_ssloptions |= BC_SSL_O_NO_SSLV3;
4605 else if (!strcmp(args[i], "no-tlsv10"))
4606 global.listen_default_ssloptions |= BC_SSL_O_NO_TLSV10;
4607 else if (!strcmp(args[i], "no-tlsv11"))
4608 global.listen_default_ssloptions |= BC_SSL_O_NO_TLSV11;
4609 else if (!strcmp(args[i], "no-tlsv12"))
4610 global.listen_default_ssloptions |= BC_SSL_O_NO_TLSV12;
4611 else if (!strcmp(args[i], "force-sslv3"))
4612 global.listen_default_ssloptions |= BC_SSL_O_USE_SSLV3;
4613 else if (!strcmp(args[i], "force-tlsv10"))
4614 global.listen_default_ssloptions |= BC_SSL_O_USE_TLSV10;
4615 else if (!strcmp(args[i], "force-tlsv11")) {
4616#if SSL_OP_NO_TLSv1_1
4617 global.listen_default_ssloptions |= BC_SSL_O_USE_TLSV11;
4618#else
4619 memprintf(err, "'%s' '%s': library does not support protocol TLSv1.1", args[0], args[i]);
4620 return -1;
4621#endif
4622 }
4623 else if (!strcmp(args[i], "force-tlsv12")) {
4624#if SSL_OP_NO_TLSv1_2
4625 global.listen_default_ssloptions |= BC_SSL_O_USE_TLSV12;
4626#else
4627 memprintf(err, "'%s' '%s': library does not support protocol TLSv1.2", args[0], args[i]);
4628 return -1;
4629#endif
4630 }
4631 else if (!strcmp(args[i], "no-tls-tickets"))
4632 global.listen_default_ssloptions |= BC_SSL_O_NO_TLS_TICKETS;
4633 else {
4634 memprintf(err, "unknown option '%s' on global statement '%s'.", args[i], args[0]);
4635 return -1;
4636 }
4637 i++;
4638 }
4639 return 0;
4640}
4641
4642/* parse the "ssl-default-server-options" keyword in global section */
4643static int ssl_parse_default_server_options(char **args, int section_type, struct proxy *curpx,
4644 struct proxy *defpx, const char *file, int line,
4645 char **err) {
4646 int i = 1;
4647
4648 if (*(args[i]) == 0) {
4649 memprintf(err, "global statement '%s' expects an option as an argument.", args[0]);
4650 return -1;
4651 }
4652 while (*(args[i])) {
4653 if (!strcmp(args[i], "no-sslv3"))
4654 global.connect_default_ssloptions |= SRV_SSL_O_NO_SSLV3;
4655 else if (!strcmp(args[i], "no-tlsv10"))
4656 global.connect_default_ssloptions |= SRV_SSL_O_NO_TLSV10;
4657 else if (!strcmp(args[i], "no-tlsv11"))
4658 global.connect_default_ssloptions |= SRV_SSL_O_NO_TLSV11;
4659 else if (!strcmp(args[i], "no-tlsv12"))
4660 global.connect_default_ssloptions |= SRV_SSL_O_NO_TLSV12;
4661 else if (!strcmp(args[i], "force-sslv3"))
4662 global.connect_default_ssloptions |= SRV_SSL_O_USE_SSLV3;
4663 else if (!strcmp(args[i], "force-tlsv10"))
4664 global.connect_default_ssloptions |= SRV_SSL_O_USE_TLSV10;
4665 else if (!strcmp(args[i], "force-tlsv11")) {
4666#if SSL_OP_NO_TLSv1_1
4667 global.connect_default_ssloptions |= SRV_SSL_O_USE_TLSV11;
4668#else
4669 memprintf(err, "'%s' '%s': library does not support protocol TLSv1.1", args[0], args[i]);
4670 return -1;
4671#endif
4672 }
4673 else if (!strcmp(args[i], "force-tlsv12")) {
4674#if SSL_OP_NO_TLSv1_2
4675 global.connect_default_ssloptions |= SRV_SSL_O_USE_TLSV12;
4676#else
4677 memprintf(err, "'%s' '%s': library does not support protocol TLSv1.2", args[0], args[i]);
4678 return -1;
4679#endif
4680 }
4681 else if (!strcmp(args[i], "no-tls-tickets"))
4682 global.connect_default_ssloptions |= SRV_SSL_O_NO_TLS_TICKETS;
4683 else {
4684 memprintf(err, "unknown option '%s' on global statement '%s'.", args[i], args[0]);
4685 return -1;
4686 }
4687 i++;
4688 }
4689 return 0;
4690}
4691
Willy Tarreau7875d092012-09-10 08:20:03 +02004692/* Note: must not be declared <const> as its list will be overwritten.
4693 * Please take care of keeping this list alphabetically sorted.
4694 */
Willy Tarreaudc13c112013-06-21 23:16:39 +02004695static struct sample_fetch_kw_list sample_fetch_keywords = {ILH, {
Emeric Brun645ae792014-04-30 14:21:06 +02004696 { "ssl_bc", smp_fetch_ssl_fc, 0, NULL, SMP_T_BOOL, SMP_USE_L5SRV },
4697 { "ssl_bc_alg_keysize", smp_fetch_ssl_fc_alg_keysize, 0, NULL, SMP_T_UINT, SMP_USE_L5SRV },
4698 { "ssl_bc_cipher", smp_fetch_ssl_fc_cipher, 0, NULL, SMP_T_STR, SMP_USE_L5SRV },
4699 { "ssl_bc_protocol", smp_fetch_ssl_fc_protocol, 0, NULL, SMP_T_STR, SMP_USE_L5SRV },
Emeric Brunb73a9b02014-04-30 18:49:19 +02004700 { "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 +02004701 { "ssl_bc_use_keysize", smp_fetch_ssl_fc_use_keysize, 0, NULL, SMP_T_UINT, SMP_USE_L5SRV },
4702 { "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 +01004703 { "ssl_c_ca_err", smp_fetch_ssl_c_ca_err, 0, NULL, SMP_T_UINT, SMP_USE_L5CLI },
4704 { "ssl_c_ca_err_depth", smp_fetch_ssl_c_ca_err_depth, 0, NULL, SMP_T_UINT, SMP_USE_L5CLI },
Emeric Brun43e79582014-10-29 19:03:26 +01004705 { "ssl_c_der", smp_fetch_ssl_x_der, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Willy Tarreau80aca902013-01-07 15:42:20 +01004706 { "ssl_c_err", smp_fetch_ssl_c_err, 0, NULL, SMP_T_UINT, SMP_USE_L5CLI },
Emeric Brunba841a12014-04-30 17:05:08 +02004707 { "ssl_c_i_dn", smp_fetch_ssl_x_i_dn, ARG2(0,STR,SINT), NULL, SMP_T_STR, SMP_USE_L5CLI },
4708 { "ssl_c_key_alg", smp_fetch_ssl_x_key_alg, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
4709 { "ssl_c_notafter", smp_fetch_ssl_x_notafter, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
4710 { "ssl_c_notbefore", smp_fetch_ssl_x_notbefore, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
4711 { "ssl_c_sig_alg", smp_fetch_ssl_x_sig_alg, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
4712 { "ssl_c_s_dn", smp_fetch_ssl_x_s_dn, ARG2(0,STR,SINT), NULL, SMP_T_STR, SMP_USE_L5CLI },
4713 { "ssl_c_serial", smp_fetch_ssl_x_serial, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
4714 { "ssl_c_sha1", smp_fetch_ssl_x_sha1, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Willy Tarreau80aca902013-01-07 15:42:20 +01004715 { "ssl_c_used", smp_fetch_ssl_c_used, 0, NULL, SMP_T_BOOL, SMP_USE_L5CLI },
4716 { "ssl_c_verify", smp_fetch_ssl_c_verify, 0, NULL, SMP_T_UINT, SMP_USE_L5CLI },
Emeric Brunba841a12014-04-30 17:05:08 +02004717 { "ssl_c_version", smp_fetch_ssl_x_version, 0, NULL, SMP_T_UINT, SMP_USE_L5CLI },
Emeric Brun43e79582014-10-29 19:03:26 +01004718 { "ssl_f_der", smp_fetch_ssl_x_der, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Emeric Brunba841a12014-04-30 17:05:08 +02004719 { "ssl_f_i_dn", smp_fetch_ssl_x_i_dn, ARG2(0,STR,SINT), NULL, SMP_T_STR, SMP_USE_L5CLI },
4720 { "ssl_f_key_alg", smp_fetch_ssl_x_key_alg, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
4721 { "ssl_f_notafter", smp_fetch_ssl_x_notafter, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
4722 { "ssl_f_notbefore", smp_fetch_ssl_x_notbefore, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
4723 { "ssl_f_sig_alg", smp_fetch_ssl_x_sig_alg, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
4724 { "ssl_f_s_dn", smp_fetch_ssl_x_s_dn, ARG2(0,STR,SINT), NULL, SMP_T_STR, SMP_USE_L5CLI },
4725 { "ssl_f_serial", smp_fetch_ssl_x_serial, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Emeric Brun55f4fa82014-04-30 17:11:25 +02004726 { "ssl_f_sha1", smp_fetch_ssl_x_sha1, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Emeric Brunba841a12014-04-30 17:05:08 +02004727 { "ssl_f_version", smp_fetch_ssl_x_version, 0, NULL, SMP_T_UINT, SMP_USE_L5CLI },
Willy Tarreau80aca902013-01-07 15:42:20 +01004728 { "ssl_fc", smp_fetch_ssl_fc, 0, NULL, SMP_T_BOOL, SMP_USE_L5CLI },
4729 { "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 +01004730 { "ssl_fc_cipher", smp_fetch_ssl_fc_cipher, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Willy Tarreau80aca902013-01-07 15:42:20 +01004731 { "ssl_fc_has_crt", smp_fetch_ssl_fc_has_crt, 0, NULL, SMP_T_BOOL, SMP_USE_L5CLI },
4732 { "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 +02004733#ifdef OPENSSL_NPN_NEGOTIATED
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01004734 { "ssl_fc_npn", smp_fetch_ssl_fc_npn, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Willy Tarreaua33c6542012-10-15 13:19:06 +02004735#endif
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01004736#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01004737 { "ssl_fc_alpn", smp_fetch_ssl_fc_alpn, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Willy Tarreauab861d32013-04-02 02:30:41 +02004738#endif
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01004739 { "ssl_fc_protocol", smp_fetch_ssl_fc_protocol, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Emeric Brunb73a9b02014-04-30 18:49:19 +02004740 { "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 +01004741 { "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 +01004742 { "ssl_fc_session_id", smp_fetch_ssl_fc_session_id, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
4743 { "ssl_fc_sni", smp_fetch_ssl_fc_sni, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Willy Tarreau7875d092012-09-10 08:20:03 +02004744 { NULL, NULL, 0, 0, 0 },
4745}};
4746
4747/* Note: must not be declared <const> as its list will be overwritten.
4748 * Please take care of keeping this list alphabetically sorted.
4749 */
Willy Tarreaudc13c112013-06-21 23:16:39 +02004750static struct acl_kw_list acl_kws = {ILH, {
Thierry FOURNIERc5a4e982014-03-05 16:07:08 +01004751 { "ssl_fc_sni_end", "ssl_fc_sni", PAT_MATCH_END },
4752 { "ssl_fc_sni_reg", "ssl_fc_sni", PAT_MATCH_REG },
Willy Tarreau8ed669b2013-01-11 15:49:37 +01004753 { /* END */ },
Willy Tarreau7875d092012-09-10 08:20:03 +02004754}};
4755
Willy Tarreau79eeafa2012-09-14 07:53:05 +02004756/* Note: must not be declared <const> as its list will be overwritten.
4757 * Please take care of keeping this list alphabetically sorted, doing so helps
4758 * all code contributors.
4759 * Optional keywords are also declared with a NULL ->parse() function so that
4760 * the config parser can report an appropriate error when a known keyword was
4761 * not enabled.
4762 */
Willy Tarreau51fb7652012-09-18 18:24:39 +02004763static struct bind_kw_list bind_kws = { "SSL", { }, {
Nenad Merdanovic05552d42015-02-27 19:56:49 +01004764 { "alpn", bind_parse_alpn, 1 }, /* set ALPN supported protocols */
4765 { "ca-file", bind_parse_ca_file, 1 }, /* set CAfile to process verify on client cert */
4766 { "ca-ignore-err", bind_parse_ignore_err, 1 }, /* set error IDs to ignore on verify depth > 0 */
4767 { "ciphers", bind_parse_ciphers, 1 }, /* set SSL cipher suite */
4768 { "crl-file", bind_parse_crl_file, 1 }, /* set certificat revocation list file use on client cert verify */
4769 { "crt", bind_parse_crt, 1 }, /* load SSL certificates from this location */
4770 { "crt-ignore-err", bind_parse_ignore_err, 1 }, /* set error IDs to ingore on verify depth == 0 */
4771 { "crt-list", bind_parse_crt_list, 1 }, /* load a list of crt from this location */
4772 { "ecdhe", bind_parse_ecdhe, 1 }, /* defines named curve for elliptic curve Diffie-Hellman */
4773 { "force-sslv3", bind_parse_force_sslv3, 0 }, /* force SSLv3 */
4774 { "force-tlsv10", bind_parse_force_tlsv10, 0 }, /* force TLSv10 */
4775 { "force-tlsv11", bind_parse_force_tlsv11, 0 }, /* force TLSv11 */
4776 { "force-tlsv12", bind_parse_force_tlsv12, 0 }, /* force TLSv12 */
4777 { "no-sslv3", bind_parse_no_sslv3, 0 }, /* disable SSLv3 */
4778 { "no-tlsv10", bind_parse_no_tlsv10, 0 }, /* disable TLSv10 */
4779 { "no-tlsv11", bind_parse_no_tlsv11, 0 }, /* disable TLSv11 */
4780 { "no-tlsv12", bind_parse_no_tlsv12, 0 }, /* disable TLSv12 */
4781 { "no-tls-tickets", bind_parse_no_tls_tickets, 0 }, /* disable session resumption tickets */
4782 { "ssl", bind_parse_ssl, 0 }, /* enable SSL processing */
4783 { "strict-sni", bind_parse_strict_sni, 0 }, /* refuse negotiation if sni doesn't match a certificate */
4784 { "tls-ticket-keys", bind_parse_tls_ticket_keys, 1 }, /* set file to load TLS ticket keys from */
4785 { "verify", bind_parse_verify, 1 }, /* set SSL verify method */
4786 { "npn", bind_parse_npn, 1 }, /* set NPN supported protocols */
Willy Tarreau79eeafa2012-09-14 07:53:05 +02004787 { NULL, NULL, 0 },
4788}};
Emeric Brun46591952012-05-18 15:47:34 +02004789
Willy Tarreau92faadf2012-10-10 23:04:25 +02004790/* Note: must not be declared <const> as its list will be overwritten.
4791 * Please take care of keeping this list alphabetically sorted, doing so helps
4792 * all code contributors.
4793 * Optional keywords are also declared with a NULL ->parse() function so that
4794 * the config parser can report an appropriate error when a known keyword was
4795 * not enabled.
4796 */
4797static struct srv_kw_list srv_kws = { "SSL", { }, {
Emeric Brunef42d922012-10-11 16:11:36 +02004798 { "ca-file", srv_parse_ca_file, 1, 0 }, /* set CAfile to process verify server cert */
Emeric Brunecc91fe2012-10-11 15:05:10 +02004799 { "check-ssl", srv_parse_check_ssl, 0, 0 }, /* enable SSL for health checks */
4800 { "ciphers", srv_parse_ciphers, 1, 0 }, /* select the cipher suite */
Emeric Brunef42d922012-10-11 16:11:36 +02004801 { "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 +02004802 { "crt", srv_parse_crt, 1, 0 }, /* set client certificate */
Emeric Brunecc91fe2012-10-11 15:05:10 +02004803 { "force-sslv3", srv_parse_force_sslv3, 0, 0 }, /* force SSLv3 */
4804 { "force-tlsv10", srv_parse_force_tlsv10, 0, 0 }, /* force TLSv10 */
4805 { "force-tlsv11", srv_parse_force_tlsv11, 0, 0 }, /* force TLSv11 */
4806 { "force-tlsv12", srv_parse_force_tlsv12, 0, 0 }, /* force TLSv12 */
Willy Tarreau2a3fb1c2015-02-05 16:47:07 +01004807 { "no-ssl-reuse", srv_parse_no_ssl_reuse, 0, 0 }, /* disable session reuse */
Emeric Brunecc91fe2012-10-11 15:05:10 +02004808 { "no-sslv3", srv_parse_no_sslv3, 0, 0 }, /* disable SSLv3 */
4809 { "no-tlsv10", srv_parse_no_tlsv10, 0, 0 }, /* disable TLSv10 */
4810 { "no-tlsv11", srv_parse_no_tlsv11, 0, 0 }, /* disable TLSv11 */
4811 { "no-tlsv12", srv_parse_no_tlsv12, 0, 0 }, /* disable TLSv12 */
Emeric Brunf9c5c472012-10-11 15:28:34 +02004812 { "no-tls-tickets", srv_parse_no_tls_tickets, 0, 0 }, /* disable session resumption tickets */
David Safb76832014-05-08 23:42:08 -04004813 { "send-proxy-v2-ssl", srv_parse_send_proxy_ssl, 0, 0 }, /* send PROXY protocol header v2 with SSL info */
4814 { "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 +02004815 { "ssl", srv_parse_ssl, 0, 0 }, /* enable SSL processing */
Emeric Brunef42d922012-10-11 16:11:36 +02004816 { "verify", srv_parse_verify, 1, 0 }, /* set SSL verify method */
Evan Broderbe554312013-06-27 00:05:25 -07004817 { "verifyhost", srv_parse_verifyhost, 1, 0 }, /* require that SSL cert verifies for hostname */
Willy Tarreau92faadf2012-10-10 23:04:25 +02004818 { NULL, NULL, 0, 0 },
4819}};
4820
Emeric Brun2c86cbf2014-10-30 15:56:50 +01004821static struct cfg_kw_list cfg_kws = {ILH, {
4822 { CFG_GLOBAL, "ssl-default-bind-options", ssl_parse_default_bind_options },
4823 { CFG_GLOBAL, "ssl-default-server-options", ssl_parse_default_server_options },
4824 { 0, NULL, NULL },
4825}};
4826
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02004827/* transport-layer operations for SSL sockets */
4828struct xprt_ops ssl_sock = {
Emeric Brun46591952012-05-18 15:47:34 +02004829 .snd_buf = ssl_sock_from_buf,
4830 .rcv_buf = ssl_sock_to_buf,
4831 .rcv_pipe = NULL,
4832 .snd_pipe = NULL,
4833 .shutr = NULL,
4834 .shutw = ssl_sock_shutw,
4835 .close = ssl_sock_close,
4836 .init = ssl_sock_init,
4837};
4838
4839__attribute__((constructor))
Willy Tarreau92faadf2012-10-10 23:04:25 +02004840static void __ssl_sock_init(void)
4841{
Emeric Brun46591952012-05-18 15:47:34 +02004842 STACK_OF(SSL_COMP)* cm;
4843
Willy Tarreau610f04b2014-02-13 11:36:41 +01004844#ifdef LISTEN_DEFAULT_CIPHERS
4845 global.listen_default_ciphers = LISTEN_DEFAULT_CIPHERS;
4846#endif
4847#ifdef CONNECT_DEFAULT_CIPHERS
4848 global.connect_default_ciphers = CONNECT_DEFAULT_CIPHERS;
4849#endif
4850 if (global.listen_default_ciphers)
4851 global.listen_default_ciphers = strdup(global.listen_default_ciphers);
4852 if (global.connect_default_ciphers)
4853 global.connect_default_ciphers = strdup(global.connect_default_ciphers);
Emeric Brun2c86cbf2014-10-30 15:56:50 +01004854 global.listen_default_ssloptions = BC_SSL_O_NONE;
4855 global.connect_default_ssloptions = SRV_SSL_O_NONE;
Willy Tarreau610f04b2014-02-13 11:36:41 +01004856
Emeric Brun46591952012-05-18 15:47:34 +02004857 SSL_library_init();
4858 cm = SSL_COMP_get_compression_methods();
4859 sk_SSL_COMP_zero(cm);
Willy Tarreau7875d092012-09-10 08:20:03 +02004860 sample_register_fetches(&sample_fetch_keywords);
4861 acl_register_keywords(&acl_kws);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02004862 bind_register_keywords(&bind_kws);
Willy Tarreau92faadf2012-10-10 23:04:25 +02004863 srv_register_keywords(&srv_kws);
Emeric Brun2c86cbf2014-10-30 15:56:50 +01004864 cfg_register_keywords(&cfg_kws);
Willy Tarreaud92aa5c2015-01-15 21:34:39 +01004865
4866 global.ssl_session_max_cost = SSL_SESSION_MAX_COST;
4867 global.ssl_handshake_max_cost = SSL_HANDSHAKE_MAX_COST;
Emeric Brun46591952012-05-18 15:47:34 +02004868}
4869
4870/*
4871 * Local variables:
4872 * c-indent-level: 8
4873 * c-basic-offset: 8
4874 * End:
4875 */