blob: e06e96d97522fc2cb2bf48aa0b312fa0a5b13593 [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>
Willy Tarreau9ad7bd42015-04-03 19:19:59 +020080#include <proto/stream.h>
Emeric Brun46591952012-05-18 15:47:34 +020081#include <proto/task.h>
82
Willy Tarreau518cedd2014-02-17 15:43:01 +010083/* Warning, these are bits, not integers! */
Emeric Brune64aef12012-09-21 13:15:06 +020084#define SSL_SOCK_ST_FL_VERIFY_DONE 0x00000001
Emeric Brund8b2bb52014-01-28 15:43:53 +010085#define SSL_SOCK_ST_FL_16K_WBFSIZE 0x00000002
Willy Tarreau518cedd2014-02-17 15:43:01 +010086#define SSL_SOCK_SEND_UNLIMITED 0x00000004
Emeric Brun29f037d2014-04-25 19:05:36 +020087#define SSL_SOCK_RECV_HEARTBEAT 0x00000008
88
Emeric Brunf282a812012-09-21 15:27:54 +020089/* bits 0xFFFF0000 are reserved to store verify errors */
90
91/* Verify errors macros */
92#define SSL_SOCK_CA_ERROR_TO_ST(e) (((e > 63) ? 63 : e) << (16))
93#define SSL_SOCK_CAEDEPTH_TO_ST(d) (((d > 15) ? 15 : d) << (6+16))
94#define SSL_SOCK_CRTERROR_TO_ST(e) (((e > 63) ? 63 : e) << (4+6+16))
95
96#define SSL_SOCK_ST_TO_CA_ERROR(s) ((s >> (16)) & 63)
97#define SSL_SOCK_ST_TO_CAEDEPTH(s) ((s >> (6+16)) & 15)
98#define SSL_SOCK_ST_TO_CRTERROR(s) ((s >> (4+6+16)) & 63)
Emeric Brune64aef12012-09-21 13:15:06 +020099
Nenad Merdanovic05552d42015-02-27 19:56:49 +0100100/* Supported hash function for TLS tickets */
101#ifdef OPENSSL_NO_SHA256
102#define HASH_FUNCT EVP_sha1
103#else
104#define HASH_FUNCT EVP_sha256
105#endif /* OPENSSL_NO_SHA256 */
106
Emeric Brun850efd52014-01-29 12:24:34 +0100107/* server and bind verify method, it uses a global value as default */
108enum {
109 SSL_SOCK_VERIFY_DEFAULT = 0,
110 SSL_SOCK_VERIFY_REQUIRED = 1,
111 SSL_SOCK_VERIFY_OPTIONAL = 2,
112 SSL_SOCK_VERIFY_NONE = 3,
113};
114
Willy Tarreau71b734c2014-01-28 15:19:44 +0100115int sslconns = 0;
116int totalsslconns = 0;
Emeric Brune1f38db2012-09-03 20:36:47 +0200117
Remi Gacogne8de54152014-07-15 11:36:40 +0200118#ifndef OPENSSL_NO_DH
119static DH *local_dh_1024 = NULL;
120static DH *local_dh_2048 = NULL;
121static DH *local_dh_4096 = NULL;
122static DH *local_dh_8192 = NULL;
123#endif /* OPENSSL_NO_DH */
124
Lukas Tribuse4e30f72014-12-09 16:32:51 +0100125#if (defined SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB && !defined OPENSSL_NO_OCSP)
Emeric Brun4147b2e2014-06-16 18:36:30 +0200126struct certificate_ocsp {
127 struct ebmb_node key;
128 unsigned char key_data[OCSP_MAX_CERTID_ASN1_LENGTH];
129 struct chunk response;
Emeric Brun4f3c87a2014-06-20 15:46:13 +0200130 long expire;
Emeric Brun4147b2e2014-06-16 18:36:30 +0200131};
132
Emeric Brun4f3c87a2014-06-20 15:46:13 +0200133/*
134 * This function returns the number of seconds elapsed
135 * since the Epoch, 1970-01-01 00:00:00 +0000 (UTC) and the
136 * date presented un ASN1_GENERALIZEDTIME.
137 *
138 * In parsing error case, it returns -1.
139 */
140static long asn1_generalizedtime_to_epoch(ASN1_GENERALIZEDTIME *d)
141{
142 long epoch;
143 char *p, *end;
144 const unsigned short month_offset[12] = {
145 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334
146 };
147 int year, month;
148
149 if (!d || (d->type != V_ASN1_GENERALIZEDTIME)) return -1;
150
151 p = (char *)d->data;
152 end = p + d->length;
153
154 if (end - p < 4) return -1;
155 year = 1000 * (p[0] - '0') + 100 * (p[1] - '0') + 10 * (p[2] - '0') + p[3] - '0';
156 p += 4;
157 if (end - p < 2) return -1;
158 month = 10 * (p[0] - '0') + p[1] - '0';
159 if (month < 1 || month > 12) return -1;
160 /* Compute the number of seconds since 1 jan 1970 and the beginning of current month
161 We consider leap years and the current month (<marsh or not) */
162 epoch = ( ((year - 1970) * 365)
163 + ((year - (month < 3)) / 4 - (year - (month < 3)) / 100 + (year - (month < 3)) / 400)
164 - ((1970 - 1) / 4 - (1970 - 1) / 100 + (1970 - 1) / 400)
165 + month_offset[month-1]
166 ) * 24 * 60 * 60;
167 p += 2;
168 if (end - p < 2) return -1;
169 /* Add the number of seconds of completed days of current month */
170 epoch += (10 * (p[0] - '0') + p[1] - '0' - 1) * 24 * 60 * 60;
171 p += 2;
172 if (end - p < 2) return -1;
173 /* Add the completed hours of the current day */
174 epoch += (10 * (p[0] - '0') + p[1] - '0') * 60 * 60;
175 p += 2;
176 if (end - p < 2) return -1;
177 /* Add the completed minutes of the current hour */
178 epoch += (10 * (p[0] - '0') + p[1] - '0') * 60;
179 p += 2;
180 if (p == end) return -1;
181 /* Test if there is available seconds */
182 if (p[0] < '0' || p[0] > '9')
183 goto nosec;
184 if (end - p < 2) return -1;
185 /* Add the seconds of the current minute */
186 epoch += 10 * (p[0] - '0') + p[1] - '0';
187 p += 2;
188 if (p == end) return -1;
189 /* Ignore seconds float part if present */
190 if (p[0] == '.') {
191 do {
192 if (++p == end) return -1;
193 } while (p[0] >= '0' && p[0] <= '9');
194 }
195
196nosec:
197 if (p[0] == 'Z') {
198 if (end - p != 1) return -1;
199 return epoch;
200 }
201 else if (p[0] == '+') {
202 if (end - p != 5) return -1;
203 /* Apply timezone offset */
204 return epoch - ((10 * (p[1] - '0') + p[2] - '0') * 60 + (10 * (p[3] - '0') + p[4] - '0')) * 60;
205 }
206 else if (p[0] == '-') {
207 if (end - p != 5) return -1;
208 /* Apply timezone offset */
209 return epoch + ((10 * (p[1] - '0') + p[2] - '0') * 60 + (10 * (p[3] - '0') + p[4] - '0')) * 60;
210 }
211
212 return -1;
213}
214
Emeric Brun1d3865b2014-06-20 15:37:32 +0200215static struct eb_root cert_ocsp_tree = EB_ROOT_UNIQUE;
Emeric Brun4147b2e2014-06-16 18:36:30 +0200216
217/* This function starts to check if the OCSP response (in DER format) contained
218 * in chunk 'ocsp_response' is valid (else exits on error).
219 * If 'cid' is not NULL, it will be compared to the OCSP certificate ID
220 * contained in the OCSP Response and exits on error if no match.
221 * If it's a valid OCSP Response:
222 * If 'ocsp' is not NULL, the chunk is copied in the OCSP response's container
223 * pointed by 'ocsp'.
224 * If 'ocsp' is NULL, the function looks up into the OCSP response's
225 * containers tree (using as index the ASN1 form of the OCSP Certificate ID extracted
226 * from the response) and exits on error if not found. Finally, If an OCSP response is
227 * already present in the container, it will be overwritten.
228 *
229 * Note: OCSP response containing more than one OCSP Single response is not
230 * considered valid.
231 *
232 * Returns 0 on success, 1 in error case.
233 */
234static int ssl_sock_load_ocsp_response(struct chunk *ocsp_response, struct certificate_ocsp *ocsp, OCSP_CERTID *cid, char **err)
235{
236 OCSP_RESPONSE *resp;
237 OCSP_BASICRESP *bs = NULL;
238 OCSP_SINGLERESP *sr;
239 unsigned char *p = (unsigned char *)ocsp_response->str;
240 int rc , count_sr;
Emeric Brun13a6b482014-06-20 15:44:34 +0200241 ASN1_GENERALIZEDTIME *revtime, *thisupd, *nextupd = NULL;
Emeric Brun4147b2e2014-06-16 18:36:30 +0200242 int reason;
243 int ret = 1;
244
245 resp = d2i_OCSP_RESPONSE(NULL, (const unsigned char **)&p, ocsp_response->len);
246 if (!resp) {
247 memprintf(err, "Unable to parse OCSP response");
248 goto out;
249 }
250
251 rc = OCSP_response_status(resp);
252 if (rc != OCSP_RESPONSE_STATUS_SUCCESSFUL) {
253 memprintf(err, "OCSP response status not successful");
254 goto out;
255 }
256
257 bs = OCSP_response_get1_basic(resp);
258 if (!bs) {
259 memprintf(err, "Failed to get basic response from OCSP Response");
260 goto out;
261 }
262
263 count_sr = OCSP_resp_count(bs);
264 if (count_sr > 1) {
265 memprintf(err, "OCSP response ignored because contains multiple single responses (%d)", count_sr);
266 goto out;
267 }
268
269 sr = OCSP_resp_get0(bs, 0);
270 if (!sr) {
271 memprintf(err, "Failed to get OCSP single response");
272 goto out;
273 }
274
275 rc = OCSP_single_get0_status(sr, &reason, &revtime, &thisupd, &nextupd);
276 if (rc != V_OCSP_CERTSTATUS_GOOD) {
277 memprintf(err, "OCSP single response: certificate status not good");
278 goto out;
279 }
280
Emeric Brun13a6b482014-06-20 15:44:34 +0200281 if (!nextupd) {
282 memprintf(err, "OCSP single response: missing nextupdate");
283 goto out;
284 }
285
Emeric Brunc8b27b62014-06-19 14:16:17 +0200286 rc = OCSP_check_validity(thisupd, nextupd, OCSP_MAX_RESPONSE_TIME_SKEW, -1);
Emeric Brun4147b2e2014-06-16 18:36:30 +0200287 if (!rc) {
288 memprintf(err, "OCSP single response: no longer valid.");
289 goto out;
290 }
291
292 if (cid) {
293 if (OCSP_id_cmp(sr->certId, cid)) {
294 memprintf(err, "OCSP single response: Certificate ID does not match certificate and issuer");
295 goto out;
296 }
297 }
298
299 if (!ocsp) {
300 unsigned char key[OCSP_MAX_CERTID_ASN1_LENGTH];
301 unsigned char *p;
302
303 rc = i2d_OCSP_CERTID(sr->certId, NULL);
304 if (!rc) {
305 memprintf(err, "OCSP single response: Unable to encode Certificate ID");
306 goto out;
307 }
308
309 if (rc > OCSP_MAX_CERTID_ASN1_LENGTH) {
310 memprintf(err, "OCSP single response: Certificate ID too long");
311 goto out;
312 }
313
314 p = key;
315 memset(key, 0, OCSP_MAX_CERTID_ASN1_LENGTH);
316 i2d_OCSP_CERTID(sr->certId, &p);
317 ocsp = (struct certificate_ocsp *)ebmb_lookup(&cert_ocsp_tree, key, OCSP_MAX_CERTID_ASN1_LENGTH);
318 if (!ocsp) {
319 memprintf(err, "OCSP single response: Certificate ID does not match any certificate or issuer");
320 goto out;
321 }
322 }
323
324 /* According to comments on "chunk_dup", the
325 previous chunk buffer will be freed */
326 if (!chunk_dup(&ocsp->response, ocsp_response)) {
327 memprintf(err, "OCSP response: Memory allocation error");
328 goto out;
329 }
330
Emeric Brun4f3c87a2014-06-20 15:46:13 +0200331 ocsp->expire = asn1_generalizedtime_to_epoch(nextupd) - OCSP_MAX_RESPONSE_TIME_SKEW;
332
Emeric Brun4147b2e2014-06-16 18:36:30 +0200333 ret = 0;
334out:
335 if (bs)
336 OCSP_BASICRESP_free(bs);
337
338 if (resp)
339 OCSP_RESPONSE_free(resp);
340
341 return ret;
342}
343/*
344 * External function use to update the OCSP response in the OCSP response's
345 * containers tree. The chunk 'ocsp_response' must contain the OCSP response
346 * to update in DER format.
347 *
348 * Returns 0 on success, 1 in error case.
349 */
350int ssl_sock_update_ocsp_response(struct chunk *ocsp_response, char **err)
351{
352 return ssl_sock_load_ocsp_response(ocsp_response, NULL, NULL, err);
353}
354
355/*
356 * This function load the OCSP Resonse in DER format contained in file at
357 * path 'ocsp_path' and call 'ssl_sock_load_ocsp_response'
358 *
359 * Returns 0 on success, 1 in error case.
360 */
361static int ssl_sock_load_ocsp_response_from_file(const char *ocsp_path, struct certificate_ocsp *ocsp, OCSP_CERTID *cid, char **err)
362{
363 int fd = -1;
364 int r = 0;
365 int ret = 1;
366
367 fd = open(ocsp_path, O_RDONLY);
368 if (fd == -1) {
369 memprintf(err, "Error opening OCSP response file");
370 goto end;
371 }
372
373 trash.len = 0;
374 while (trash.len < trash.size) {
375 r = read(fd, trash.str + trash.len, trash.size - trash.len);
376 if (r < 0) {
377 if (errno == EINTR)
378 continue;
379
380 memprintf(err, "Error reading OCSP response from file");
381 goto end;
382 }
383 else if (r == 0) {
384 break;
385 }
386 trash.len += r;
387 }
388
389 close(fd);
390 fd = -1;
391
392 ret = ssl_sock_load_ocsp_response(&trash, ocsp, cid, err);
393end:
394 if (fd != -1)
395 close(fd);
396
397 return ret;
398}
399
Nenad Merdanovic05552d42015-02-27 19:56:49 +0100400#if (defined SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB && TLS_TICKETS_NO > 0)
401static 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)
402{
403 struct tls_sess_key *keys;
404 struct connection *conn;
405 int head;
406 int i;
407
408 conn = (struct connection *)SSL_get_app_data(s);
409 keys = objt_listener(conn->target)->bind_conf->tls_ticket_keys;
410 head = objt_listener(conn->target)->bind_conf->tls_ticket_enc_index;
411
412 if (enc) {
413 memcpy(key_name, keys[head].name, 16);
414
415 if(!RAND_pseudo_bytes(iv, EVP_MAX_IV_LENGTH))
416 return -1;
417
418 if(!EVP_EncryptInit_ex(ectx, EVP_aes_128_cbc(), NULL, keys[head].aes_key, iv))
419 return -1;
420
421 HMAC_Init_ex(hctx, keys[head].hmac_key, 16, HASH_FUNCT(), NULL);
422
423 return 1;
424 } else {
425 for (i = 0; i < TLS_TICKETS_NO; i++) {
426 if (!memcmp(key_name, keys[(head + i) % TLS_TICKETS_NO].name, 16))
427 goto found;
428 }
429 return 0;
430
431 found:
432 HMAC_Init_ex(hctx, keys[(head + i) % TLS_TICKETS_NO].hmac_key, 16, HASH_FUNCT(), NULL);
433 if(!EVP_DecryptInit_ex(ectx, EVP_aes_128_cbc(), NULL, keys[(head + i) % TLS_TICKETS_NO].aes_key, iv))
434 return -1;
435 /* 2 for key renewal, 1 if current key is still valid */
436 return i ? 2 : 1;
437 }
438}
439#endif /* SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB */
440
Emeric Brun4147b2e2014-06-16 18:36:30 +0200441/*
442 * Callback used to set OCSP status extension content in server hello.
443 */
444int ssl_sock_ocsp_stapling_cbk(SSL *ssl, void *arg)
445{
446 struct certificate_ocsp *ocsp = (struct certificate_ocsp *)arg;
447 char* ssl_buf;
448
449 if (!ocsp ||
450 !ocsp->response.str ||
Emeric Brun4f3c87a2014-06-20 15:46:13 +0200451 !ocsp->response.len ||
452 (ocsp->expire < now.tv_sec))
Emeric Brun4147b2e2014-06-16 18:36:30 +0200453 return SSL_TLSEXT_ERR_NOACK;
454
455 ssl_buf = OPENSSL_malloc(ocsp->response.len);
456 if (!ssl_buf)
457 return SSL_TLSEXT_ERR_NOACK;
458
459 memcpy(ssl_buf, ocsp->response.str, ocsp->response.len);
460 SSL_set_tlsext_status_ocsp_resp(ssl, ssl_buf, ocsp->response.len);
461
462 return SSL_TLSEXT_ERR_OK;
463}
464
465/*
466 * This function enables the handling of OCSP status extension on 'ctx' if a
467 * file name 'cert_path' suffixed using ".ocsp" is present.
468 * To enable OCSP status extension, the issuer's certificate is mandatory.
469 * It should be present in the certificate's extra chain builded from file
470 * 'cert_path'. If not found, the issuer certificate is loaded from a file
471 * named 'cert_path' suffixed using '.issuer'.
472 *
473 * In addition, ".ocsp" file content is loaded as a DER format of an OCSP
474 * response. If file is empty or content is not a valid OCSP response,
475 * OCSP status extension is enabled but OCSP response is ignored (a warning
476 * is displayed).
477 *
478 * Returns 1 if no ".ocsp" file found, 0 if OCSP status extension is
479 * succesfully enabled, or -1 in other error case.
480 */
481static int ssl_sock_load_ocsp(SSL_CTX *ctx, const char *cert_path)
482{
483
484 BIO *in = NULL;
485 X509 *x, *xi = NULL, *issuer = NULL;
486 STACK_OF(X509) *chain = NULL;
487 OCSP_CERTID *cid = NULL;
488 SSL *ssl;
489 char ocsp_path[MAXPATHLEN+1];
490 int i, ret = -1;
491 struct stat st;
492 struct certificate_ocsp *ocsp = NULL, *iocsp;
493 char *warn = NULL;
494 unsigned char *p;
495
496 snprintf(ocsp_path, MAXPATHLEN+1, "%s.ocsp", cert_path);
497
498 if (stat(ocsp_path, &st))
499 return 1;
500
501 ssl = SSL_new(ctx);
502 if (!ssl)
503 goto out;
504
505 x = SSL_get_certificate(ssl);
506 if (!x)
507 goto out;
508
509 /* Try to lookup for issuer in certificate extra chain */
510#ifdef SSL_CTRL_GET_EXTRA_CHAIN_CERTS
511 SSL_CTX_get_extra_chain_certs(ctx, &chain);
512#else
513 chain = ctx->extra_certs;
514#endif
515 for (i = 0; i < sk_X509_num(chain); i++) {
516 issuer = sk_X509_value(chain, i);
517 if (X509_check_issued(issuer, x) == X509_V_OK)
518 break;
519 else
520 issuer = NULL;
521 }
522
523 /* If not found try to load issuer from a suffixed file */
524 if (!issuer) {
525 char issuer_path[MAXPATHLEN+1];
526
527 in = BIO_new(BIO_s_file());
528 if (!in)
529 goto out;
530
531 snprintf(issuer_path, MAXPATHLEN+1, "%s.issuer", cert_path);
532 if (BIO_read_filename(in, issuer_path) <= 0)
533 goto out;
534
535 xi = PEM_read_bio_X509_AUX(in, NULL, ctx->default_passwd_callback, ctx->default_passwd_callback_userdata);
536 if (!xi)
537 goto out;
538
539 if (X509_check_issued(xi, x) != X509_V_OK)
540 goto out;
541
542 issuer = xi;
543 }
544
545 cid = OCSP_cert_to_id(0, x, issuer);
546 if (!cid)
547 goto out;
548
549 i = i2d_OCSP_CERTID(cid, NULL);
550 if (!i || (i > OCSP_MAX_CERTID_ASN1_LENGTH))
551 goto out;
552
553 ocsp = calloc(1, sizeof(struct certificate_ocsp));
554 if (!ocsp)
555 goto out;
556
557 p = ocsp->key_data;
558 i2d_OCSP_CERTID(cid, &p);
559
560 iocsp = (struct certificate_ocsp *)ebmb_insert(&cert_ocsp_tree, &ocsp->key, OCSP_MAX_CERTID_ASN1_LENGTH);
561 if (iocsp == ocsp)
562 ocsp = NULL;
563
564 SSL_CTX_set_tlsext_status_cb(ctx, ssl_sock_ocsp_stapling_cbk);
565 SSL_CTX_set_tlsext_status_arg(ctx, iocsp);
566
567 ret = 0;
568
569 warn = NULL;
570 if (ssl_sock_load_ocsp_response_from_file(ocsp_path, iocsp, cid, &warn)) {
571 memprintf(&warn, "Loading '%s': %s. Content will be ignored", ocsp_path, warn ? warn : "failure");
572 Warning("%s.\n", warn);
573 }
574
575out:
576 if (ssl)
577 SSL_free(ssl);
578
579 if (in)
580 BIO_free(in);
581
582 if (xi)
583 X509_free(xi);
584
585 if (cid)
586 OCSP_CERTID_free(cid);
587
588 if (ocsp)
589 free(ocsp);
590
591 if (warn)
592 free(warn);
593
594
595 return ret;
596}
597
598#endif
599
Janusz Dziemidowicz2c701b52015-03-07 23:03:59 +0100600#if (OPENSSL_VERSION_NUMBER >= 0x1000200fL && !defined OPENSSL_NO_TLSEXT && !defined OPENSSL_IS_BORINGSSL)
601
602#define CT_EXTENSION_TYPE 18
603
604static int sctl_ex_index = -1;
605
606/*
607 * Try to parse Signed Certificate Timestamp List structure. This function
608 * makes only basic test if the data seems like SCTL. No signature validation
609 * is performed.
610 */
611static int ssl_sock_parse_sctl(struct chunk *sctl)
612{
613 int ret = 1;
614 int len, pos, sct_len;
615 unsigned char *data;
616
617 if (sctl->len < 2)
618 goto out;
619
620 data = (unsigned char *)sctl->str;
621 len = (data[0] << 8) | data[1];
622
623 if (len + 2 != sctl->len)
624 goto out;
625
626 data = data + 2;
627 pos = 0;
628 while (pos < len) {
629 if (len - pos < 2)
630 goto out;
631
632 sct_len = (data[pos] << 8) | data[pos + 1];
633 if (pos + sct_len + 2 > len)
634 goto out;
635
636 pos += sct_len + 2;
637 }
638
639 ret = 0;
640
641out:
642 return ret;
643}
644
645static int ssl_sock_load_sctl_from_file(const char *sctl_path, struct chunk **sctl)
646{
647 int fd = -1;
648 int r = 0;
649 int ret = 1;
650
651 *sctl = NULL;
652
653 fd = open(sctl_path, O_RDONLY);
654 if (fd == -1)
655 goto end;
656
657 trash.len = 0;
658 while (trash.len < trash.size) {
659 r = read(fd, trash.str + trash.len, trash.size - trash.len);
660 if (r < 0) {
661 if (errno == EINTR)
662 continue;
663
664 goto end;
665 }
666 else if (r == 0) {
667 break;
668 }
669 trash.len += r;
670 }
671
672 ret = ssl_sock_parse_sctl(&trash);
673 if (ret)
674 goto end;
675
676 *sctl = calloc(1, sizeof(struct chunk));
677 if (!chunk_dup(*sctl, &trash)) {
678 free(*sctl);
679 *sctl = NULL;
680 goto end;
681 }
682
683end:
684 if (fd != -1)
685 close(fd);
686
687 return ret;
688}
689
690int ssl_sock_sctl_add_cbk(SSL *ssl, unsigned ext_type, const unsigned char **out, size_t *outlen, int *al, void *add_arg)
691{
692 struct chunk *sctl = (struct chunk *)add_arg;
693
694 *out = (unsigned char *)sctl->str;
695 *outlen = sctl->len;
696
697 return 1;
698}
699
700int ssl_sock_sctl_parse_cbk(SSL *s, unsigned int ext_type, const unsigned char *in, size_t inlen, int *al, void *parse_arg)
701{
702 return 1;
703}
704
705static int ssl_sock_load_sctl(SSL_CTX *ctx, const char *cert_path)
706{
707 char sctl_path[MAXPATHLEN+1];
708 int ret = -1;
709 struct stat st;
710 struct chunk *sctl = NULL;
711
712 snprintf(sctl_path, MAXPATHLEN+1, "%s.sctl", cert_path);
713
714 if (stat(sctl_path, &st))
715 return 1;
716
717 if (ssl_sock_load_sctl_from_file(sctl_path, &sctl))
718 goto out;
719
720 if (!SSL_CTX_add_server_custom_ext(ctx, CT_EXTENSION_TYPE, ssl_sock_sctl_add_cbk, NULL, sctl, ssl_sock_sctl_parse_cbk, NULL)) {
721 free(sctl);
722 goto out;
723 }
724
725 SSL_CTX_set_ex_data(ctx, sctl_ex_index, sctl);
726
727 ret = 0;
728
729out:
730 return ret;
731}
732
733#endif
734
Emeric Brune1f38db2012-09-03 20:36:47 +0200735void ssl_sock_infocbk(const SSL *ssl, int where, int ret)
736{
737 struct connection *conn = (struct connection *)SSL_get_app_data(ssl);
Emeric Brund8b2bb52014-01-28 15:43:53 +0100738 BIO *write_bio;
Willy Tarreau622317d2015-02-27 16:36:16 +0100739 (void)ret; /* shut gcc stupid warning */
Emeric Brune1f38db2012-09-03 20:36:47 +0200740
741 if (where & SSL_CB_HANDSHAKE_START) {
742 /* Disable renegotiation (CVE-2009-3555) */
Willy Tarreau20879a02012-12-03 16:32:10 +0100743 if (conn->flags & CO_FL_CONNECTED) {
Emeric Brune1f38db2012-09-03 20:36:47 +0200744 conn->flags |= CO_FL_ERROR;
Willy Tarreau20879a02012-12-03 16:32:10 +0100745 conn->err_code = CO_ER_SSL_RENEG;
746 }
Emeric Brune1f38db2012-09-03 20:36:47 +0200747 }
Emeric Brund8b2bb52014-01-28 15:43:53 +0100748
749 if ((where & SSL_CB_ACCEPT_LOOP) == SSL_CB_ACCEPT_LOOP) {
750 if (!(conn->xprt_st & SSL_SOCK_ST_FL_16K_WBFSIZE)) {
751 /* Long certificate chains optimz
752 If write and read bios are differents, we
753 consider that the buffering was activated,
754 so we rise the output buffer size from 4k
755 to 16k */
756 write_bio = SSL_get_wbio(ssl);
757 if (write_bio != SSL_get_rbio(ssl)) {
758 BIO_set_write_buffer_size(write_bio, 16384);
759 conn->xprt_st |= SSL_SOCK_ST_FL_16K_WBFSIZE;
760 }
761 }
762 }
Emeric Brunfc0421f2012-09-07 17:30:07 +0200763}
764
Emeric Brune64aef12012-09-21 13:15:06 +0200765/* Callback is called for each certificate of the chain during a verify
766 ok is set to 1 if preverify detect no error on current certificate.
767 Returns 0 to break the handshake, 1 otherwise. */
Evan Broderbe554312013-06-27 00:05:25 -0700768int ssl_sock_bind_verifycbk(int ok, X509_STORE_CTX *x_store)
Emeric Brune64aef12012-09-21 13:15:06 +0200769{
770 SSL *ssl;
771 struct connection *conn;
Emeric Brun81c00f02012-09-21 14:31:21 +0200772 int err, depth;
Emeric Brune64aef12012-09-21 13:15:06 +0200773
774 ssl = X509_STORE_CTX_get_ex_data(x_store, SSL_get_ex_data_X509_STORE_CTX_idx());
775 conn = (struct connection *)SSL_get_app_data(ssl);
776
Willy Tarreauf7bc57c2012-10-03 00:19:48 +0200777 conn->xprt_st |= SSL_SOCK_ST_FL_VERIFY_DONE;
Emeric Brune64aef12012-09-21 13:15:06 +0200778
Emeric Brun81c00f02012-09-21 14:31:21 +0200779 if (ok) /* no errors */
780 return ok;
781
782 depth = X509_STORE_CTX_get_error_depth(x_store);
783 err = X509_STORE_CTX_get_error(x_store);
784
785 /* check if CA error needs to be ignored */
786 if (depth > 0) {
Willy Tarreauf7bc57c2012-10-03 00:19:48 +0200787 if (!SSL_SOCK_ST_TO_CA_ERROR(conn->xprt_st)) {
788 conn->xprt_st |= SSL_SOCK_CA_ERROR_TO_ST(err);
789 conn->xprt_st |= SSL_SOCK_CAEDEPTH_TO_ST(depth);
Emeric Brunf282a812012-09-21 15:27:54 +0200790 }
791
Emeric Brun1eb20ef2012-12-03 13:24:29 +0100792 if (objt_listener(conn->target)->bind_conf->ca_ignerr & (1ULL << err)) {
793 ERR_clear_error();
Emeric Brun81c00f02012-09-21 14:31:21 +0200794 return 1;
Emeric Brun1eb20ef2012-12-03 13:24:29 +0100795 }
Emeric Brun81c00f02012-09-21 14:31:21 +0200796
Willy Tarreau20879a02012-12-03 16:32:10 +0100797 conn->err_code = CO_ER_SSL_CA_FAIL;
Emeric Brun81c00f02012-09-21 14:31:21 +0200798 return 0;
799 }
800
Willy Tarreauf7bc57c2012-10-03 00:19:48 +0200801 if (!SSL_SOCK_ST_TO_CRTERROR(conn->xprt_st))
802 conn->xprt_st |= SSL_SOCK_CRTERROR_TO_ST(err);
Emeric Brunf282a812012-09-21 15:27:54 +0200803
Emeric Brun81c00f02012-09-21 14:31:21 +0200804 /* check if certificate error needs to be ignored */
Emeric Brun1eb20ef2012-12-03 13:24:29 +0100805 if (objt_listener(conn->target)->bind_conf->crt_ignerr & (1ULL << err)) {
806 ERR_clear_error();
Emeric Brun81c00f02012-09-21 14:31:21 +0200807 return 1;
Emeric Brun1eb20ef2012-12-03 13:24:29 +0100808 }
Emeric Brun81c00f02012-09-21 14:31:21 +0200809
Willy Tarreau20879a02012-12-03 16:32:10 +0100810 conn->err_code = CO_ER_SSL_CRT_FAIL;
Emeric Brun81c00f02012-09-21 14:31:21 +0200811 return 0;
Emeric Brune64aef12012-09-21 13:15:06 +0200812}
813
Emeric Brun29f037d2014-04-25 19:05:36 +0200814/* Callback is called for ssl protocol analyse */
815void ssl_sock_msgcbk(int write_p, int version, int content_type, const void *buf, size_t len, SSL *ssl, void *arg)
816{
Emeric Brun29f037d2014-04-25 19:05:36 +0200817#ifdef TLS1_RT_HEARTBEAT
818 /* test heartbeat received (write_p is set to 0
819 for a received record) */
Willy Tarreauf51c6982014-04-25 20:02:39 +0200820 if ((content_type == TLS1_RT_HEARTBEAT) && (write_p == 0)) {
Willy Tarreau84815002014-04-25 21:40:27 +0200821 struct connection *conn = (struct connection *)SSL_get_app_data(ssl);
Willy Tarreauf51c6982014-04-25 20:02:39 +0200822 const unsigned char *p = buf;
823 unsigned int payload;
824
Emeric Brun29f037d2014-04-25 19:05:36 +0200825 conn->xprt_st |= SSL_SOCK_RECV_HEARTBEAT;
Willy Tarreauf51c6982014-04-25 20:02:39 +0200826
827 /* Check if this is a CVE-2014-0160 exploitation attempt. */
828 if (*p != TLS1_HB_REQUEST)
829 return;
830
Willy Tarreauaeed6722014-04-25 23:59:58 +0200831 if (len < 1 + 2 + 16) /* 1 type + 2 size + 0 payload + 16 padding */
Willy Tarreauf51c6982014-04-25 20:02:39 +0200832 goto kill_it;
833
834 payload = (p[1] * 256) + p[2];
Willy Tarreau3b2fdb62014-04-25 23:44:22 +0200835 if (3 + payload + 16 <= len)
Willy Tarreauf51c6982014-04-25 20:02:39 +0200836 return; /* OK no problem */
Willy Tarreauaeed6722014-04-25 23:59:58 +0200837 kill_it:
Willy Tarreau3b2fdb62014-04-25 23:44:22 +0200838 /* We have a clear heartbleed attack (CVE-2014-0160), the
839 * advertised payload is larger than the advertised packet
840 * length, so we have garbage in the buffer between the
841 * payload and the end of the buffer (p+len). We can't know
842 * if the SSL stack is patched, and we don't know if we can
843 * safely wipe out the area between p+3+len and payload.
844 * So instead, we prevent the response from being sent by
845 * setting the max_send_fragment to 0 and we report an SSL
846 * error, which will kill this connection. It will be reported
847 * above as SSL_ERROR_SSL while an other handshake failure with
Willy Tarreauf51c6982014-04-25 20:02:39 +0200848 * a heartbeat message will be reported as SSL_ERROR_SYSCALL.
849 */
Willy Tarreau3b2fdb62014-04-25 23:44:22 +0200850 ssl->max_send_fragment = 0;
Willy Tarreauf51c6982014-04-25 20:02:39 +0200851 SSLerr(SSL_F_TLS1_HEARTBEAT, SSL_R_SSL_HANDSHAKE_FAILURE);
852 return;
853 }
Emeric Brun29f037d2014-04-25 19:05:36 +0200854#endif
855}
856
Willy Tarreau6c9a3d52012-10-18 18:57:14 +0200857#ifdef OPENSSL_NPN_NEGOTIATED
858/* This callback is used so that the server advertises the list of
859 * negociable protocols for NPN.
860 */
861static int ssl_sock_advertise_npn_protos(SSL *s, const unsigned char **data,
862 unsigned int *len, void *arg)
863{
864 struct bind_conf *conf = arg;
865
866 *data = (const unsigned char *)conf->npn_str;
867 *len = conf->npn_len;
868 return SSL_TLSEXT_ERR_OK;
869}
870#endif
871
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +0100872#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Willy Tarreauab861d32013-04-02 02:30:41 +0200873/* This callback is used so that the server advertises the list of
874 * negociable protocols for ALPN.
875 */
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +0100876static int ssl_sock_advertise_alpn_protos(SSL *s, const unsigned char **out,
877 unsigned char *outlen,
878 const unsigned char *server,
879 unsigned int server_len, void *arg)
Willy Tarreauab861d32013-04-02 02:30:41 +0200880{
881 struct bind_conf *conf = arg;
882
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +0100883 if (SSL_select_next_proto((unsigned char**) out, outlen, (const unsigned char *)conf->alpn_str,
884 conf->alpn_len, server, server_len) != OPENSSL_NPN_NEGOTIATED) {
885 return SSL_TLSEXT_ERR_NOACK;
886 }
Willy Tarreauab861d32013-04-02 02:30:41 +0200887 return SSL_TLSEXT_ERR_OK;
888}
889#endif
890
Emeric Brunfc0421f2012-09-07 17:30:07 +0200891#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
892/* Sets the SSL ctx of <ssl> to match the advertised server name. Returns a
893 * warning when no match is found, which implies the default (first) cert
894 * will keep being used.
895 */
Willy Tarreau2a65ff02012-09-13 17:54:29 +0200896static int ssl_sock_switchctx_cbk(SSL *ssl, int *al, struct bind_conf *s)
Emeric Brunfc0421f2012-09-07 17:30:07 +0200897{
898 const char *servername;
899 const char *wildp = NULL;
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +0200900 struct ebmb_node *node, *n;
Emeric Brunfc0421f2012-09-07 17:30:07 +0200901 int i;
902 (void)al; /* shut gcc stupid warning */
903
904 servername = SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name);
Emmanuel Hocdet65623372013-01-24 17:17:15 +0100905 if (!servername) {
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +0200906 return (s->strict_sni ?
907 SSL_TLSEXT_ERR_ALERT_FATAL :
Emmanuel Hocdet79274e22013-05-31 12:47:44 +0200908 SSL_TLSEXT_ERR_NOACK);
Emmanuel Hocdet65623372013-01-24 17:17:15 +0100909 }
Emeric Brunfc0421f2012-09-07 17:30:07 +0200910
Willy Tarreau19d14ef2012-10-29 16:51:55 +0100911 for (i = 0; i < trash.size; i++) {
Emeric Brunfc0421f2012-09-07 17:30:07 +0200912 if (!servername[i])
913 break;
Willy Tarreau19d14ef2012-10-29 16:51:55 +0100914 trash.str[i] = tolower(servername[i]);
915 if (!wildp && (trash.str[i] == '.'))
916 wildp = &trash.str[i];
Emeric Brunfc0421f2012-09-07 17:30:07 +0200917 }
Willy Tarreau19d14ef2012-10-29 16:51:55 +0100918 trash.str[i] = 0;
Emeric Brunfc0421f2012-09-07 17:30:07 +0200919
920 /* lookup in full qualified names */
Willy Tarreau19d14ef2012-10-29 16:51:55 +0100921 node = ebst_lookup(&s->sni_ctx, trash.str);
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +0200922
923 /* lookup a not neg filter */
924 for (n = node; n; n = ebmb_next_dup(n)) {
925 if (!container_of(n, struct sni_ctx, name)->neg) {
926 node = n;
927 break;
Emmanuel Hocdet65623372013-01-24 17:17:15 +0100928 }
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +0200929 }
930 if (!node && wildp) {
931 /* lookup in wildcards names */
Emeric Brunfc0421f2012-09-07 17:30:07 +0200932 node = ebst_lookup(&s->sni_w_ctx, wildp);
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +0200933 }
934 if (!node || container_of(node, struct sni_ctx, name)->neg) {
935 return (s->strict_sni ?
936 SSL_TLSEXT_ERR_ALERT_FATAL :
937 SSL_TLSEXT_ERR_ALERT_WARNING);
Emeric Brunfc0421f2012-09-07 17:30:07 +0200938 }
939
940 /* switch ctx */
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +0200941 SSL_set_SSL_CTX(ssl, container_of(node, struct sni_ctx, name)->ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +0200942 return SSL_TLSEXT_ERR_OK;
943}
944#endif /* SSL_CTRL_SET_TLSEXT_HOSTNAME */
945
Emeric Bruna4bcd9a2012-09-20 16:19:02 +0200946#ifndef OPENSSL_NO_DH
Remi Gacognef46cd6e2014-06-12 14:58:40 +0200947
948static DH * ssl_get_dh_1024(void)
949{
Lukas Tribus4c0d45a2014-08-18 00:56:32 +0200950#if (OPENSSL_VERSION_NUMBER < 0x0090801fL || defined OPENSSL_IS_BORINGSSL)
Remi Gacognef46cd6e2014-06-12 14:58:40 +0200951 static const unsigned char rfc_2409_prime_1024[] = {
952 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xC9,0x0F,0xDA,0xA2,
953 0x21,0x68,0xC2,0x34,0xC4,0xC6,0x62,0x8B,0x80,0xDC,0x1C,0xD1,
954 0x29,0x02,0x4E,0x08,0x8A,0x67,0xCC,0x74,0x02,0x0B,0xBE,0xA6,
955 0x3B,0x13,0x9B,0x22,0x51,0x4A,0x08,0x79,0x8E,0x34,0x04,0xDD,
956 0xEF,0x95,0x19,0xB3,0xCD,0x3A,0x43,0x1B,0x30,0x2B,0x0A,0x6D,
957 0xF2,0x5F,0x14,0x37,0x4F,0xE1,0x35,0x6D,0x6D,0x51,0xC2,0x45,
958 0xE4,0x85,0xB5,0x76,0x62,0x5E,0x7E,0xC6,0xF4,0x4C,0x42,0xE9,
959 0xA6,0x37,0xED,0x6B,0x0B,0xFF,0x5C,0xB6,0xF4,0x06,0xB7,0xED,
960 0xEE,0x38,0x6B,0xFB,0x5A,0x89,0x9F,0xA5,0xAE,0x9F,0x24,0x11,
961 0x7C,0x4B,0x1F,0xE6,0x49,0x28,0x66,0x51,0xEC,0xE6,0x53,0x81,
962 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
963 };
964#endif
965 DH *dh = DH_new();
966 if (dh) {
Lukas Tribus4c0d45a2014-08-18 00:56:32 +0200967#if (OPENSSL_VERSION_NUMBER >= 0x0090801fL && !defined OPENSSL_IS_BORINGSSL)
Remi Gacognef46cd6e2014-06-12 14:58:40 +0200968 dh->p = get_rfc2409_prime_1024(NULL);
969#else
970 dh->p = BN_bin2bn(rfc_2409_prime_1024, sizeof rfc_2409_prime_1024, NULL);
971#endif
972 /* See RFC 2409, Section 6 "Oakley Groups"
973 for the reason why 2 is used as generator.
974 */
975 BN_dec2bn(&dh->g, "2");
976 if (!dh->p || !dh->g) {
977 DH_free(dh);
978 dh = NULL;
979 }
980 }
981 return dh;
982}
983
984static DH *ssl_get_dh_2048(void)
985{
Lukas Tribus4c0d45a2014-08-18 00:56:32 +0200986#if (OPENSSL_VERSION_NUMBER < 0x0090801fL || defined OPENSSL_IS_BORINGSSL)
Remi Gacognef46cd6e2014-06-12 14:58:40 +0200987 static const unsigned char rfc_3526_prime_2048[] = {
988 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xC9,0x0F,0xDA,0xA2,
989 0x21,0x68,0xC2,0x34,0xC4,0xC6,0x62,0x8B,0x80,0xDC,0x1C,0xD1,
990 0x29,0x02,0x4E,0x08,0x8A,0x67,0xCC,0x74,0x02,0x0B,0xBE,0xA6,
991 0x3B,0x13,0x9B,0x22,0x51,0x4A,0x08,0x79,0x8E,0x34,0x04,0xDD,
992 0xEF,0x95,0x19,0xB3,0xCD,0x3A,0x43,0x1B,0x30,0x2B,0x0A,0x6D,
993 0xF2,0x5F,0x14,0x37,0x4F,0xE1,0x35,0x6D,0x6D,0x51,0xC2,0x45,
994 0xE4,0x85,0xB5,0x76,0x62,0x5E,0x7E,0xC6,0xF4,0x4C,0x42,0xE9,
995 0xA6,0x37,0xED,0x6B,0x0B,0xFF,0x5C,0xB6,0xF4,0x06,0xB7,0xED,
996 0xEE,0x38,0x6B,0xFB,0x5A,0x89,0x9F,0xA5,0xAE,0x9F,0x24,0x11,
997 0x7C,0x4B,0x1F,0xE6,0x49,0x28,0x66,0x51,0xEC,0xE4,0x5B,0x3D,
998 0xC2,0x00,0x7C,0xB8,0xA1,0x63,0xBF,0x05,0x98,0xDA,0x48,0x36,
999 0x1C,0x55,0xD3,0x9A,0x69,0x16,0x3F,0xA8,0xFD,0x24,0xCF,0x5F,
1000 0x83,0x65,0x5D,0x23,0xDC,0xA3,0xAD,0x96,0x1C,0x62,0xF3,0x56,
1001 0x20,0x85,0x52,0xBB,0x9E,0xD5,0x29,0x07,0x70,0x96,0x96,0x6D,
1002 0x67,0x0C,0x35,0x4E,0x4A,0xBC,0x98,0x04,0xF1,0x74,0x6C,0x08,
1003 0xCA,0x18,0x21,0x7C,0x32,0x90,0x5E,0x46,0x2E,0x36,0xCE,0x3B,
1004 0xE3,0x9E,0x77,0x2C,0x18,0x0E,0x86,0x03,0x9B,0x27,0x83,0xA2,
1005 0xEC,0x07,0xA2,0x8F,0xB5,0xC5,0x5D,0xF0,0x6F,0x4C,0x52,0xC9,
1006 0xDE,0x2B,0xCB,0xF6,0x95,0x58,0x17,0x18,0x39,0x95,0x49,0x7C,
1007 0xEA,0x95,0x6A,0xE5,0x15,0xD2,0x26,0x18,0x98,0xFA,0x05,0x10,
1008 0x15,0x72,0x8E,0x5A,0x8A,0xAC,0xAA,0x68,0xFF,0xFF,0xFF,0xFF,
1009 0xFF,0xFF,0xFF,0xFF,
1010 };
1011#endif
1012 DH *dh = DH_new();
1013 if (dh) {
Lukas Tribus4c0d45a2014-08-18 00:56:32 +02001014#if (OPENSSL_VERSION_NUMBER >= 0x0090801fL && !defined OPENSSL_IS_BORINGSSL)
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001015 dh->p = get_rfc3526_prime_2048(NULL);
1016#else
1017 dh->p = BN_bin2bn(rfc_3526_prime_2048, sizeof rfc_3526_prime_2048, NULL);
1018#endif
1019 /* See RFC 3526, Section 3 "2048-bit MODP Group"
1020 for the reason why 2 is used as generator.
1021 */
1022 BN_dec2bn(&dh->g, "2");
1023 if (!dh->p || !dh->g) {
1024 DH_free(dh);
1025 dh = NULL;
1026 }
1027 }
1028 return dh;
1029}
1030
1031static DH *ssl_get_dh_4096(void)
1032{
Lukas Tribus4c0d45a2014-08-18 00:56:32 +02001033#if (OPENSSL_VERSION_NUMBER < 0x0090801fL || defined OPENSSL_IS_BORINGSSL)
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001034 static const unsigned char rfc_3526_prime_4096[] = {
1035 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xC9,0x0F,0xDA,0xA2,
1036 0x21,0x68,0xC2,0x34,0xC4,0xC6,0x62,0x8B,0x80,0xDC,0x1C,0xD1,
1037 0x29,0x02,0x4E,0x08,0x8A,0x67,0xCC,0x74,0x02,0x0B,0xBE,0xA6,
1038 0x3B,0x13,0x9B,0x22,0x51,0x4A,0x08,0x79,0x8E,0x34,0x04,0xDD,
1039 0xEF,0x95,0x19,0xB3,0xCD,0x3A,0x43,0x1B,0x30,0x2B,0x0A,0x6D,
1040 0xF2,0x5F,0x14,0x37,0x4F,0xE1,0x35,0x6D,0x6D,0x51,0xC2,0x45,
1041 0xE4,0x85,0xB5,0x76,0x62,0x5E,0x7E,0xC6,0xF4,0x4C,0x42,0xE9,
1042 0xA6,0x37,0xED,0x6B,0x0B,0xFF,0x5C,0xB6,0xF4,0x06,0xB7,0xED,
1043 0xEE,0x38,0x6B,0xFB,0x5A,0x89,0x9F,0xA5,0xAE,0x9F,0x24,0x11,
1044 0x7C,0x4B,0x1F,0xE6,0x49,0x28,0x66,0x51,0xEC,0xE4,0x5B,0x3D,
1045 0xC2,0x00,0x7C,0xB8,0xA1,0x63,0xBF,0x05,0x98,0xDA,0x48,0x36,
1046 0x1C,0x55,0xD3,0x9A,0x69,0x16,0x3F,0xA8,0xFD,0x24,0xCF,0x5F,
1047 0x83,0x65,0x5D,0x23,0xDC,0xA3,0xAD,0x96,0x1C,0x62,0xF3,0x56,
1048 0x20,0x85,0x52,0xBB,0x9E,0xD5,0x29,0x07,0x70,0x96,0x96,0x6D,
1049 0x67,0x0C,0x35,0x4E,0x4A,0xBC,0x98,0x04,0xF1,0x74,0x6C,0x08,
1050 0xCA,0x18,0x21,0x7C,0x32,0x90,0x5E,0x46,0x2E,0x36,0xCE,0x3B,
1051 0xE3,0x9E,0x77,0x2C,0x18,0x0E,0x86,0x03,0x9B,0x27,0x83,0xA2,
1052 0xEC,0x07,0xA2,0x8F,0xB5,0xC5,0x5D,0xF0,0x6F,0x4C,0x52,0xC9,
1053 0xDE,0x2B,0xCB,0xF6,0x95,0x58,0x17,0x18,0x39,0x95,0x49,0x7C,
1054 0xEA,0x95,0x6A,0xE5,0x15,0xD2,0x26,0x18,0x98,0xFA,0x05,0x10,
1055 0x15,0x72,0x8E,0x5A,0x8A,0xAA,0xC4,0x2D,0xAD,0x33,0x17,0x0D,
1056 0x04,0x50,0x7A,0x33,0xA8,0x55,0x21,0xAB,0xDF,0x1C,0xBA,0x64,
1057 0xEC,0xFB,0x85,0x04,0x58,0xDB,0xEF,0x0A,0x8A,0xEA,0x71,0x57,
1058 0x5D,0x06,0x0C,0x7D,0xB3,0x97,0x0F,0x85,0xA6,0xE1,0xE4,0xC7,
1059 0xAB,0xF5,0xAE,0x8C,0xDB,0x09,0x33,0xD7,0x1E,0x8C,0x94,0xE0,
1060 0x4A,0x25,0x61,0x9D,0xCE,0xE3,0xD2,0x26,0x1A,0xD2,0xEE,0x6B,
1061 0xF1,0x2F,0xFA,0x06,0xD9,0x8A,0x08,0x64,0xD8,0x76,0x02,0x73,
1062 0x3E,0xC8,0x6A,0x64,0x52,0x1F,0x2B,0x18,0x17,0x7B,0x20,0x0C,
1063 0xBB,0xE1,0x17,0x57,0x7A,0x61,0x5D,0x6C,0x77,0x09,0x88,0xC0,
1064 0xBA,0xD9,0x46,0xE2,0x08,0xE2,0x4F,0xA0,0x74,0xE5,0xAB,0x31,
1065 0x43,0xDB,0x5B,0xFC,0xE0,0xFD,0x10,0x8E,0x4B,0x82,0xD1,0x20,
1066 0xA9,0x21,0x08,0x01,0x1A,0x72,0x3C,0x12,0xA7,0x87,0xE6,0xD7,
1067 0x88,0x71,0x9A,0x10,0xBD,0xBA,0x5B,0x26,0x99,0xC3,0x27,0x18,
1068 0x6A,0xF4,0xE2,0x3C,0x1A,0x94,0x68,0x34,0xB6,0x15,0x0B,0xDA,
1069 0x25,0x83,0xE9,0xCA,0x2A,0xD4,0x4C,0xE8,0xDB,0xBB,0xC2,0xDB,
1070 0x04,0xDE,0x8E,0xF9,0x2E,0x8E,0xFC,0x14,0x1F,0xBE,0xCA,0xA6,
1071 0x28,0x7C,0x59,0x47,0x4E,0x6B,0xC0,0x5D,0x99,0xB2,0x96,0x4F,
1072 0xA0,0x90,0xC3,0xA2,0x23,0x3B,0xA1,0x86,0x51,0x5B,0xE7,0xED,
1073 0x1F,0x61,0x29,0x70,0xCE,0xE2,0xD7,0xAF,0xB8,0x1B,0xDD,0x76,
1074 0x21,0x70,0x48,0x1C,0xD0,0x06,0x91,0x27,0xD5,0xB0,0x5A,0xA9,
1075 0x93,0xB4,0xEA,0x98,0x8D,0x8F,0xDD,0xC1,0x86,0xFF,0xB7,0xDC,
1076 0x90,0xA6,0xC0,0x8F,0x4D,0xF4,0x35,0xC9,0x34,0x06,0x31,0x99,
1077 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
1078 };
1079#endif
1080 DH *dh = DH_new();
1081 if (dh) {
Lukas Tribus4c0d45a2014-08-18 00:56:32 +02001082#if (OPENSSL_VERSION_NUMBER >= 0x0090801fL && !defined OPENSSL_IS_BORINGSSL)
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001083 dh->p = get_rfc3526_prime_4096(NULL);
1084#else
1085 dh->p = BN_bin2bn(rfc_3526_prime_4096, sizeof rfc_3526_prime_4096, NULL);
1086#endif
1087 /* See RFC 3526, Section 5 "4096-bit MODP Group"
1088 for the reason why 2 is used as generator.
1089 */
1090 BN_dec2bn(&dh->g, "2");
1091 if (!dh->p || !dh->g) {
1092 DH_free(dh);
1093 dh = NULL;
1094 }
1095 }
1096 return dh;
1097}
1098
1099static DH *ssl_get_dh_8192(void)
1100{
Lukas Tribus4c0d45a2014-08-18 00:56:32 +02001101#if (OPENSSL_VERSION_NUMBER < 0x0090801fL || defined OPENSSL_IS_BORINGSSL)
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001102 static const unsigned char rfc_3526_prime_8192[] = {
1103 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xC9,0x0F,0xDA,0xA2,
1104 0x21,0x68,0xC2,0x34,0xC4,0xC6,0x62,0x8B,0x80,0xDC,0x1C,0xD1,
1105 0x29,0x02,0x4E,0x08,0x8A,0x67,0xCC,0x74,0x02,0x0B,0xBE,0xA6,
1106 0x3B,0x13,0x9B,0x22,0x51,0x4A,0x08,0x79,0x8E,0x34,0x04,0xDD,
1107 0xEF,0x95,0x19,0xB3,0xCD,0x3A,0x43,0x1B,0x30,0x2B,0x0A,0x6D,
1108 0xF2,0x5F,0x14,0x37,0x4F,0xE1,0x35,0x6D,0x6D,0x51,0xC2,0x45,
1109 0xE4,0x85,0xB5,0x76,0x62,0x5E,0x7E,0xC6,0xF4,0x4C,0x42,0xE9,
1110 0xA6,0x37,0xED,0x6B,0x0B,0xFF,0x5C,0xB6,0xF4,0x06,0xB7,0xED,
1111 0xEE,0x38,0x6B,0xFB,0x5A,0x89,0x9F,0xA5,0xAE,0x9F,0x24,0x11,
1112 0x7C,0x4B,0x1F,0xE6,0x49,0x28,0x66,0x51,0xEC,0xE4,0x5B,0x3D,
1113 0xC2,0x00,0x7C,0xB8,0xA1,0x63,0xBF,0x05,0x98,0xDA,0x48,0x36,
1114 0x1C,0x55,0xD3,0x9A,0x69,0x16,0x3F,0xA8,0xFD,0x24,0xCF,0x5F,
1115 0x83,0x65,0x5D,0x23,0xDC,0xA3,0xAD,0x96,0x1C,0x62,0xF3,0x56,
1116 0x20,0x85,0x52,0xBB,0x9E,0xD5,0x29,0x07,0x70,0x96,0x96,0x6D,
1117 0x67,0x0C,0x35,0x4E,0x4A,0xBC,0x98,0x04,0xF1,0x74,0x6C,0x08,
1118 0xCA,0x18,0x21,0x7C,0x32,0x90,0x5E,0x46,0x2E,0x36,0xCE,0x3B,
1119 0xE3,0x9E,0x77,0x2C,0x18,0x0E,0x86,0x03,0x9B,0x27,0x83,0xA2,
1120 0xEC,0x07,0xA2,0x8F,0xB5,0xC5,0x5D,0xF0,0x6F,0x4C,0x52,0xC9,
1121 0xDE,0x2B,0xCB,0xF6,0x95,0x58,0x17,0x18,0x39,0x95,0x49,0x7C,
1122 0xEA,0x95,0x6A,0xE5,0x15,0xD2,0x26,0x18,0x98,0xFA,0x05,0x10,
1123 0x15,0x72,0x8E,0x5A,0x8A,0xAA,0xC4,0x2D,0xAD,0x33,0x17,0x0D,
1124 0x04,0x50,0x7A,0x33,0xA8,0x55,0x21,0xAB,0xDF,0x1C,0xBA,0x64,
1125 0xEC,0xFB,0x85,0x04,0x58,0xDB,0xEF,0x0A,0x8A,0xEA,0x71,0x57,
1126 0x5D,0x06,0x0C,0x7D,0xB3,0x97,0x0F,0x85,0xA6,0xE1,0xE4,0xC7,
1127 0xAB,0xF5,0xAE,0x8C,0xDB,0x09,0x33,0xD7,0x1E,0x8C,0x94,0xE0,
1128 0x4A,0x25,0x61,0x9D,0xCE,0xE3,0xD2,0x26,0x1A,0xD2,0xEE,0x6B,
1129 0xF1,0x2F,0xFA,0x06,0xD9,0x8A,0x08,0x64,0xD8,0x76,0x02,0x73,
1130 0x3E,0xC8,0x6A,0x64,0x52,0x1F,0x2B,0x18,0x17,0x7B,0x20,0x0C,
1131 0xBB,0xE1,0x17,0x57,0x7A,0x61,0x5D,0x6C,0x77,0x09,0x88,0xC0,
1132 0xBA,0xD9,0x46,0xE2,0x08,0xE2,0x4F,0xA0,0x74,0xE5,0xAB,0x31,
1133 0x43,0xDB,0x5B,0xFC,0xE0,0xFD,0x10,0x8E,0x4B,0x82,0xD1,0x20,
1134 0xA9,0x21,0x08,0x01,0x1A,0x72,0x3C,0x12,0xA7,0x87,0xE6,0xD7,
1135 0x88,0x71,0x9A,0x10,0xBD,0xBA,0x5B,0x26,0x99,0xC3,0x27,0x18,
1136 0x6A,0xF4,0xE2,0x3C,0x1A,0x94,0x68,0x34,0xB6,0x15,0x0B,0xDA,
1137 0x25,0x83,0xE9,0xCA,0x2A,0xD4,0x4C,0xE8,0xDB,0xBB,0xC2,0xDB,
1138 0x04,0xDE,0x8E,0xF9,0x2E,0x8E,0xFC,0x14,0x1F,0xBE,0xCA,0xA6,
1139 0x28,0x7C,0x59,0x47,0x4E,0x6B,0xC0,0x5D,0x99,0xB2,0x96,0x4F,
1140 0xA0,0x90,0xC3,0xA2,0x23,0x3B,0xA1,0x86,0x51,0x5B,0xE7,0xED,
1141 0x1F,0x61,0x29,0x70,0xCE,0xE2,0xD7,0xAF,0xB8,0x1B,0xDD,0x76,
1142 0x21,0x70,0x48,0x1C,0xD0,0x06,0x91,0x27,0xD5,0xB0,0x5A,0xA9,
1143 0x93,0xB4,0xEA,0x98,0x8D,0x8F,0xDD,0xC1,0x86,0xFF,0xB7,0xDC,
1144 0x90,0xA6,0xC0,0x8F,0x4D,0xF4,0x35,0xC9,0x34,0x02,0x84,0x92,
1145 0x36,0xC3,0xFA,0xB4,0xD2,0x7C,0x70,0x26,0xC1,0xD4,0xDC,0xB2,
1146 0x60,0x26,0x46,0xDE,0xC9,0x75,0x1E,0x76,0x3D,0xBA,0x37,0xBD,
1147 0xF8,0xFF,0x94,0x06,0xAD,0x9E,0x53,0x0E,0xE5,0xDB,0x38,0x2F,
1148 0x41,0x30,0x01,0xAE,0xB0,0x6A,0x53,0xED,0x90,0x27,0xD8,0x31,
1149 0x17,0x97,0x27,0xB0,0x86,0x5A,0x89,0x18,0xDA,0x3E,0xDB,0xEB,
1150 0xCF,0x9B,0x14,0xED,0x44,0xCE,0x6C,0xBA,0xCE,0xD4,0xBB,0x1B,
1151 0xDB,0x7F,0x14,0x47,0xE6,0xCC,0x25,0x4B,0x33,0x20,0x51,0x51,
1152 0x2B,0xD7,0xAF,0x42,0x6F,0xB8,0xF4,0x01,0x37,0x8C,0xD2,0xBF,
1153 0x59,0x83,0xCA,0x01,0xC6,0x4B,0x92,0xEC,0xF0,0x32,0xEA,0x15,
1154 0xD1,0x72,0x1D,0x03,0xF4,0x82,0xD7,0xCE,0x6E,0x74,0xFE,0xF6,
1155 0xD5,0x5E,0x70,0x2F,0x46,0x98,0x0C,0x82,0xB5,0xA8,0x40,0x31,
1156 0x90,0x0B,0x1C,0x9E,0x59,0xE7,0xC9,0x7F,0xBE,0xC7,0xE8,0xF3,
1157 0x23,0xA9,0x7A,0x7E,0x36,0xCC,0x88,0xBE,0x0F,0x1D,0x45,0xB7,
1158 0xFF,0x58,0x5A,0xC5,0x4B,0xD4,0x07,0xB2,0x2B,0x41,0x54,0xAA,
1159 0xCC,0x8F,0x6D,0x7E,0xBF,0x48,0xE1,0xD8,0x14,0xCC,0x5E,0xD2,
1160 0x0F,0x80,0x37,0xE0,0xA7,0x97,0x15,0xEE,0xF2,0x9B,0xE3,0x28,
1161 0x06,0xA1,0xD5,0x8B,0xB7,0xC5,0xDA,0x76,0xF5,0x50,0xAA,0x3D,
1162 0x8A,0x1F,0xBF,0xF0,0xEB,0x19,0xCC,0xB1,0xA3,0x13,0xD5,0x5C,
1163 0xDA,0x56,0xC9,0xEC,0x2E,0xF2,0x96,0x32,0x38,0x7F,0xE8,0xD7,
1164 0x6E,0x3C,0x04,0x68,0x04,0x3E,0x8F,0x66,0x3F,0x48,0x60,0xEE,
1165 0x12,0xBF,0x2D,0x5B,0x0B,0x74,0x74,0xD6,0xE6,0x94,0xF9,0x1E,
1166 0x6D,0xBE,0x11,0x59,0x74,0xA3,0x92,0x6F,0x12,0xFE,0xE5,0xE4,
1167 0x38,0x77,0x7C,0xB6,0xA9,0x32,0xDF,0x8C,0xD8,0xBE,0xC4,0xD0,
1168 0x73,0xB9,0x31,0xBA,0x3B,0xC8,0x32,0xB6,0x8D,0x9D,0xD3,0x00,
1169 0x74,0x1F,0xA7,0xBF,0x8A,0xFC,0x47,0xED,0x25,0x76,0xF6,0x93,
1170 0x6B,0xA4,0x24,0x66,0x3A,0xAB,0x63,0x9C,0x5A,0xE4,0xF5,0x68,
1171 0x34,0x23,0xB4,0x74,0x2B,0xF1,0xC9,0x78,0x23,0x8F,0x16,0xCB,
1172 0xE3,0x9D,0x65,0x2D,0xE3,0xFD,0xB8,0xBE,0xFC,0x84,0x8A,0xD9,
1173 0x22,0x22,0x2E,0x04,0xA4,0x03,0x7C,0x07,0x13,0xEB,0x57,0xA8,
1174 0x1A,0x23,0xF0,0xC7,0x34,0x73,0xFC,0x64,0x6C,0xEA,0x30,0x6B,
1175 0x4B,0xCB,0xC8,0x86,0x2F,0x83,0x85,0xDD,0xFA,0x9D,0x4B,0x7F,
1176 0xA2,0xC0,0x87,0xE8,0x79,0x68,0x33,0x03,0xED,0x5B,0xDD,0x3A,
1177 0x06,0x2B,0x3C,0xF5,0xB3,0xA2,0x78,0xA6,0x6D,0x2A,0x13,0xF8,
1178 0x3F,0x44,0xF8,0x2D,0xDF,0x31,0x0E,0xE0,0x74,0xAB,0x6A,0x36,
1179 0x45,0x97,0xE8,0x99,0xA0,0x25,0x5D,0xC1,0x64,0xF3,0x1C,0xC5,
1180 0x08,0x46,0x85,0x1D,0xF9,0xAB,0x48,0x19,0x5D,0xED,0x7E,0xA1,
1181 0xB1,0xD5,0x10,0xBD,0x7E,0xE7,0x4D,0x73,0xFA,0xF3,0x6B,0xC3,
1182 0x1E,0xCF,0xA2,0x68,0x35,0x90,0x46,0xF4,0xEB,0x87,0x9F,0x92,
1183 0x40,0x09,0x43,0x8B,0x48,0x1C,0x6C,0xD7,0x88,0x9A,0x00,0x2E,
1184 0xD5,0xEE,0x38,0x2B,0xC9,0x19,0x0D,0xA6,0xFC,0x02,0x6E,0x47,
1185 0x95,0x58,0xE4,0x47,0x56,0x77,0xE9,0xAA,0x9E,0x30,0x50,0xE2,
1186 0x76,0x56,0x94,0xDF,0xC8,0x1F,0x56,0xE8,0x80,0xB9,0x6E,0x71,
1187 0x60,0xC9,0x80,0xDD,0x98,0xED,0xD3,0xDF,0xFF,0xFF,0xFF,0xFF,
1188 0xFF,0xFF,0xFF,0xFF,
1189 };
1190#endif
1191 DH *dh = DH_new();
1192 if (dh) {
Lukas Tribus4c0d45a2014-08-18 00:56:32 +02001193#if (OPENSSL_VERSION_NUMBER >= 0x0090801fL && !defined OPENSSL_IS_BORINGSSL)
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001194 dh->p = get_rfc3526_prime_8192(NULL);
1195#else
1196 dh->p = BN_bin2bn(rfc_3526_prime_8192, sizeof rfc_3526_prime_8192, NULL);
1197#endif
1198 /* See RFC 3526, Section 7 "8192-bit MODP Group"
1199 for the reason why 2 is used as generator.
1200 */
1201 BN_dec2bn(&dh->g, "2");
1202 if (!dh->p || !dh->g) {
1203 DH_free(dh);
1204 dh = NULL;
1205 }
1206 }
1207 return dh;
1208}
1209
1210/* Returns Diffie-Hellman parameters matching the private key length
1211 but not exceeding global.tune.ssl_default_dh_param */
1212static DH *ssl_get_tmp_dh(SSL *ssl, int export, int keylen)
1213{
1214 DH *dh = NULL;
1215 EVP_PKEY *pkey = SSL_get_privatekey(ssl);
1216 int type = pkey ? EVP_PKEY_type(pkey->type) : EVP_PKEY_NONE;
1217
1218 /* The keylen supplied by OpenSSL can only be 512 or 1024.
1219 See ssl3_send_server_key_exchange() in ssl/s3_srvr.c
1220 */
1221 if (type == EVP_PKEY_RSA || type == EVP_PKEY_DSA) {
1222 keylen = EVP_PKEY_bits(pkey);
1223 }
1224
1225 if (keylen > global.tune.ssl_default_dh_param) {
1226 keylen = global.tune.ssl_default_dh_param;
1227 }
1228
1229 if (keylen >= 8192) {
Remi Gacogne8de54152014-07-15 11:36:40 +02001230 dh = local_dh_8192;
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001231 }
1232 else if (keylen >= 4096) {
Remi Gacogne8de54152014-07-15 11:36:40 +02001233 dh = local_dh_4096;
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001234 }
1235 else if (keylen >= 2048) {
Remi Gacogne8de54152014-07-15 11:36:40 +02001236 dh = local_dh_2048;
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001237 }
1238 else {
Remi Gacogne8de54152014-07-15 11:36:40 +02001239 dh = local_dh_1024;
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001240 }
1241
1242 return dh;
1243}
1244
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001245/* Loads Diffie-Hellman parameter from a file. Returns 1 if loaded, else -1
1246 if an error occured, and 0 if parameter not found. */
Willy Tarreau6e774b42014-04-25 21:35:23 +02001247int ssl_sock_load_dh_params(SSL_CTX *ctx, const char *file)
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001248{
1249 int ret = -1;
1250 BIO *in;
1251 DH *dh = NULL;
1252
1253 in = BIO_new(BIO_s_file());
1254 if (in == NULL)
1255 goto end;
1256
1257 if (BIO_read_filename(in, file) <= 0)
1258 goto end;
1259
1260 dh = PEM_read_bio_DHparams(in, NULL, ctx->default_passwd_callback, ctx->default_passwd_callback_userdata);
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001261 if (dh) {
1262 ret = 1;
1263 SSL_CTX_set_tmp_dh(ctx, dh);
1264 /* Setting ssl default dh param to the size of the static DH params
1265 found in the file. This way we know that there is no use
1266 complaining later about ssl-default-dh-param not being set. */
1267 global.tune.ssl_default_dh_param = DH_size(dh) * 8;
1268 }
1269 else {
Emeric Brun41fdb3c2013-04-26 11:05:44 +02001270 /* Clear openssl global errors stack */
1271 ERR_clear_error();
1272
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001273 if (global.tune.ssl_default_dh_param <= 1024) {
1274 /* we are limited to DH parameter of 1024 bits anyway */
Remi Gacogne8de54152014-07-15 11:36:40 +02001275 local_dh_1024 = ssl_get_dh_1024();
1276 if (local_dh_1024 == NULL)
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001277 goto end;
Willy Tarreau6e774b42014-04-25 21:35:23 +02001278
Remi Gacogne8de54152014-07-15 11:36:40 +02001279 SSL_CTX_set_tmp_dh(ctx, local_dh_1024);
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001280 }
1281 else {
1282 SSL_CTX_set_tmp_dh_callback(ctx, ssl_get_tmp_dh);
1283 }
Willy Tarreau6e774b42014-04-25 21:35:23 +02001284
Emeric Brun41fdb3c2013-04-26 11:05:44 +02001285 ret = 0; /* DH params not found */
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001286 }
Emeric Brun644cde02012-12-14 11:21:13 +01001287
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001288end:
1289 if (dh)
1290 DH_free(dh);
1291
1292 if (in)
Emeric Brun41fdb3c2013-04-26 11:05:44 +02001293 BIO_free(in);
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001294
1295 return ret;
1296}
1297#endif
1298
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001299static int ssl_sock_add_cert_sni(SSL_CTX *ctx, struct bind_conf *s, char *name, int order)
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001300{
1301 struct sni_ctx *sc;
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001302 int wild = 0, neg = 0;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001303
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001304 if (*name == '!') {
1305 neg = 1;
1306 name++;
1307 }
1308 if (*name == '*') {
1309 wild = 1;
1310 name++;
1311 }
1312 /* !* filter is a nop */
1313 if (neg && wild)
1314 return order;
1315 if (*name) {
1316 int j, len;
1317 len = strlen(name);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001318 sc = malloc(sizeof(struct sni_ctx) + len + 1);
1319 for (j = 0; j < len; j++)
1320 sc->name.key[j] = tolower(name[j]);
1321 sc->name.key[len] = 0;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001322 sc->ctx = ctx;
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001323 sc->order = order++;
1324 sc->neg = neg;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001325 if (wild)
1326 ebst_insert(&s->sni_w_ctx, &sc->name);
1327 else
1328 ebst_insert(&s->sni_ctx, &sc->name);
1329 }
1330 return order;
1331}
1332
Emeric Brunfc0421f2012-09-07 17:30:07 +02001333/* Loads a certificate key and CA chain from a file. Returns 0 on error, -1 if
1334 * an early error happens and the caller must call SSL_CTX_free() by itelf.
1335 */
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001336static 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 +02001337{
1338 BIO *in;
1339 X509 *x = NULL, *ca;
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001340 int i, err;
Emeric Brunfc0421f2012-09-07 17:30:07 +02001341 int ret = -1;
1342 int order = 0;
1343 X509_NAME *xname;
1344 char *str;
Emeric Brunfc0421f2012-09-07 17:30:07 +02001345#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
1346 STACK_OF(GENERAL_NAME) *names;
1347#endif
1348
1349 in = BIO_new(BIO_s_file());
1350 if (in == NULL)
1351 goto end;
1352
1353 if (BIO_read_filename(in, file) <= 0)
1354 goto end;
1355
1356 x = PEM_read_bio_X509_AUX(in, NULL, ctx->default_passwd_callback, ctx->default_passwd_callback_userdata);
1357 if (x == NULL)
1358 goto end;
1359
Emeric Brun50bcecc2013-04-22 13:05:23 +02001360 if (fcount) {
1361 while (fcount--)
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001362 order = ssl_sock_add_cert_sni(ctx, s, sni_filter[fcount], order);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001363 }
1364 else {
Emeric Brunfc0421f2012-09-07 17:30:07 +02001365#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001366 names = X509_get_ext_d2i(x, NID_subject_alt_name, NULL, NULL);
1367 if (names) {
1368 for (i = 0; i < sk_GENERAL_NAME_num(names); i++) {
1369 GENERAL_NAME *name = sk_GENERAL_NAME_value(names, i);
1370 if (name->type == GEN_DNS) {
1371 if (ASN1_STRING_to_UTF8((unsigned char **)&str, name->d.dNSName) >= 0) {
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001372 order = ssl_sock_add_cert_sni(ctx, s, str, order);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001373 OPENSSL_free(str);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001374 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02001375 }
1376 }
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001377 sk_GENERAL_NAME_pop_free(names, GENERAL_NAME_free);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001378 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02001379#endif /* SSL_CTRL_SET_TLSEXT_HOSTNAME */
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001380 xname = X509_get_subject_name(x);
1381 i = -1;
1382 while ((i = X509_NAME_get_index_by_NID(xname, NID_commonName, i)) != -1) {
1383 X509_NAME_ENTRY *entry = X509_NAME_get_entry(xname, i);
1384 if (ASN1_STRING_to_UTF8((unsigned char **)&str, entry->value) >= 0) {
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001385 order = ssl_sock_add_cert_sni(ctx, s, str, order);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001386 OPENSSL_free(str);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001387 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02001388 }
1389 }
1390
1391 ret = 0; /* the caller must not free the SSL_CTX argument anymore */
1392 if (!SSL_CTX_use_certificate(ctx, x))
1393 goto end;
1394
1395 if (ctx->extra_certs != NULL) {
1396 sk_X509_pop_free(ctx->extra_certs, X509_free);
1397 ctx->extra_certs = NULL;
1398 }
1399
1400 while ((ca = PEM_read_bio_X509(in, NULL, ctx->default_passwd_callback, ctx->default_passwd_callback_userdata))) {
1401 if (!SSL_CTX_add_extra_chain_cert(ctx, ca)) {
1402 X509_free(ca);
1403 goto end;
1404 }
1405 }
1406
1407 err = ERR_get_error();
1408 if (!err || (ERR_GET_LIB(err) == ERR_LIB_PEM && ERR_GET_REASON(err) == PEM_R_NO_START_LINE)) {
1409 /* we successfully reached the last cert in the file */
1410 ret = 1;
1411 }
1412 ERR_clear_error();
1413
1414end:
1415 if (x)
1416 X509_free(x);
1417
1418 if (in)
1419 BIO_free(in);
1420
1421 return ret;
1422}
1423
Emeric Brun50bcecc2013-04-22 13:05:23 +02001424static 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 +02001425{
1426 int ret;
1427 SSL_CTX *ctx;
1428
1429 ctx = SSL_CTX_new(SSLv23_server_method());
1430 if (!ctx) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02001431 memprintf(err, "%sunable to allocate SSL context for cert '%s'.\n",
1432 err && *err ? *err : "", path);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001433 return 1;
1434 }
1435
1436 if (SSL_CTX_use_PrivateKey_file(ctx, path, SSL_FILETYPE_PEM) <= 0) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02001437 memprintf(err, "%sunable to load SSL private key from PEM file '%s'.\n",
1438 err && *err ? *err : "", path);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001439 SSL_CTX_free(ctx);
1440 return 1;
1441 }
1442
Emeric Brun50bcecc2013-04-22 13:05:23 +02001443 ret = ssl_sock_load_cert_chain_file(ctx, path, bind_conf, sni_filter, fcount);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001444 if (ret <= 0) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02001445 memprintf(err, "%sunable to load SSL certificate from PEM file '%s'.\n",
1446 err && *err ? *err : "", path);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001447 if (ret < 0) /* serious error, must do that ourselves */
1448 SSL_CTX_free(ctx);
1449 return 1;
1450 }
Emeric Brun61694ab2012-10-26 13:35:33 +02001451
1452 if (SSL_CTX_check_private_key(ctx) <= 0) {
1453 memprintf(err, "%sinconsistencies between private key and certificate loaded from PEM file '%s'.\n",
1454 err && *err ? *err : "", path);
1455 return 1;
1456 }
1457
Emeric Brunfc0421f2012-09-07 17:30:07 +02001458 /* we must not free the SSL_CTX anymore below, since it's already in
1459 * the tree, so it will be discovered and cleaned in time.
1460 */
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001461#ifndef OPENSSL_NO_DH
1462 ret = ssl_sock_load_dh_params(ctx, path);
1463 if (ret < 0) {
1464 if (err)
1465 memprintf(err, "%sunable to load DH parameters from file '%s'.\n",
1466 *err ? *err : "", path);
1467 return 1;
1468 }
1469#endif
1470
Lukas Tribuse4e30f72014-12-09 16:32:51 +01001471#if (defined SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB && !defined OPENSSL_NO_OCSP)
Emeric Brun4147b2e2014-06-16 18:36:30 +02001472 ret = ssl_sock_load_ocsp(ctx, path);
1473 if (ret < 0) {
1474 if (err)
1475 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",
1476 *err ? *err : "", path);
1477 return 1;
1478 }
1479#endif
1480
Janusz Dziemidowicz2c701b52015-03-07 23:03:59 +01001481#if (OPENSSL_VERSION_NUMBER >= 0x1000200fL && !defined OPENSSL_NO_TLSEXT && !defined OPENSSL_IS_BORINGSSL)
1482 if (sctl_ex_index >= 0) {
1483 ret = ssl_sock_load_sctl(ctx, path);
1484 if (ret < 0) {
1485 if (err)
1486 memprintf(err, "%s '%s.sctl' is present but cannot be read or parsed'.\n",
1487 *err ? *err : "", path);
1488 return 1;
1489 }
1490 }
1491#endif
1492
Emeric Brunfc0421f2012-09-07 17:30:07 +02001493#ifndef SSL_CTRL_SET_TLSEXT_HOSTNAME
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001494 if (bind_conf->default_ctx) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02001495 memprintf(err, "%sthis version of openssl cannot load multiple SSL certificates.\n",
1496 err && *err ? *err : "");
Emeric Brunfc0421f2012-09-07 17:30:07 +02001497 return 1;
1498 }
1499#endif
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001500 if (!bind_conf->default_ctx)
1501 bind_conf->default_ctx = ctx;
Emeric Brunfc0421f2012-09-07 17:30:07 +02001502
1503 return 0;
1504}
1505
Willy Tarreau79eeafa2012-09-14 07:53:05 +02001506int ssl_sock_load_cert(char *path, struct bind_conf *bind_conf, struct proxy *curproxy, char **err)
Emeric Brunfc0421f2012-09-07 17:30:07 +02001507{
Cyril Bonté3180f7b2015-01-25 00:16:08 +01001508 struct dirent **de_list;
1509 int i, n;
Emeric Brunfc0421f2012-09-07 17:30:07 +02001510 DIR *dir;
1511 struct stat buf;
Willy Tarreauee2663b2012-12-06 11:36:59 +01001512 char *end;
1513 char fp[MAXPATHLEN+1];
Emeric Brunfc0421f2012-09-07 17:30:07 +02001514 int cfgerr = 0;
1515
1516 if (!(dir = opendir(path)))
Emeric Brun50bcecc2013-04-22 13:05:23 +02001517 return ssl_sock_load_cert_file(path, bind_conf, curproxy, NULL, 0, err);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001518
1519 /* strip trailing slashes, including first one */
1520 for (end = path + strlen(path) - 1; end >= path && *end == '/'; end--)
1521 *end = 0;
1522
Cyril Bonté3180f7b2015-01-25 00:16:08 +01001523 n = scandir(path, &de_list, 0, alphasort);
1524 if (n < 0) {
1525 memprintf(err, "%sunable to scan directory '%s' : %s.\n",
1526 err && *err ? *err : "", path, strerror(errno));
1527 cfgerr++;
1528 }
1529 else {
1530 for (i = 0; i < n; i++) {
1531 struct dirent *de = de_list[i];
Emeric Brun2aab7222014-06-18 18:15:09 +02001532
Cyril Bonté3180f7b2015-01-25 00:16:08 +01001533 end = strrchr(de->d_name, '.');
Janusz Dziemidowicz2c701b52015-03-07 23:03:59 +01001534 if (end && (!strcmp(end, ".issuer") || !strcmp(end, ".ocsp") || !strcmp(end, ".sctl")))
Cyril Bonté3180f7b2015-01-25 00:16:08 +01001535 goto ignore_entry;
1536
1537 snprintf(fp, sizeof(fp), "%s/%s", path, de->d_name);
1538 if (stat(fp, &buf) != 0) {
1539 memprintf(err, "%sunable to stat SSL certificate from file '%s' : %s.\n",
1540 err && *err ? *err : "", fp, strerror(errno));
1541 cfgerr++;
1542 goto ignore_entry;
1543 }
1544 if (!S_ISREG(buf.st_mode))
1545 goto ignore_entry;
1546 cfgerr += ssl_sock_load_cert_file(fp, bind_conf, curproxy, NULL, 0, err);
1547 ignore_entry:
1548 free(de);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001549 }
Cyril Bonté3180f7b2015-01-25 00:16:08 +01001550 free(de_list);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001551 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02001552 closedir(dir);
1553 return cfgerr;
1554}
1555
Thierry Fournier383085f2013-01-24 14:15:43 +01001556/* Make sure openssl opens /dev/urandom before the chroot. The work is only
1557 * done once. Zero is returned if the operation fails. No error is returned
1558 * if the random is said as not implemented, because we expect that openssl
1559 * will use another method once needed.
1560 */
1561static int ssl_initialize_random()
1562{
1563 unsigned char random;
1564 static int random_initialized = 0;
1565
1566 if (!random_initialized && RAND_bytes(&random, 1) != 0)
1567 random_initialized = 1;
1568
1569 return random_initialized;
1570}
1571
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001572int ssl_sock_load_cert_list_file(char *file, struct bind_conf *bind_conf, struct proxy *curproxy, char **err)
1573{
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001574 char thisline[LINESIZE];
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001575 FILE *f;
1576 int linenum = 0;
1577 int cfgerr = 0;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001578
Willy Tarreauad1731d2013-04-02 17:35:58 +02001579 if ((f = fopen(file, "r")) == NULL) {
1580 memprintf(err, "cannot open file '%s' : %s", file, strerror(errno));
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001581 return 1;
Willy Tarreauad1731d2013-04-02 17:35:58 +02001582 }
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001583
1584 while (fgets(thisline, sizeof(thisline), f) != NULL) {
1585 int arg;
Emeric Brun50bcecc2013-04-22 13:05:23 +02001586 int newarg;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001587 char *end;
1588 char *args[MAX_LINE_ARGS + 1];
1589 char *line = thisline;
1590
1591 linenum++;
1592 end = line + strlen(line);
1593 if (end-line == sizeof(thisline)-1 && *(end-1) != '\n') {
1594 /* Check if we reached the limit and the last char is not \n.
1595 * Watch out for the last line without the terminating '\n'!
1596 */
Willy Tarreauad1731d2013-04-02 17:35:58 +02001597 memprintf(err, "line %d too long in file '%s', limit is %d characters",
1598 linenum, file, (int)sizeof(thisline)-1);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001599 cfgerr = 1;
Willy Tarreauad1731d2013-04-02 17:35:58 +02001600 break;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001601 }
1602
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001603 arg = 0;
Emeric Brun50bcecc2013-04-22 13:05:23 +02001604 newarg = 1;
1605 while (*line) {
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001606 if (*line == '#' || *line == '\n' || *line == '\r') {
1607 /* end of string, end of loop */
1608 *line = 0;
1609 break;
1610 }
1611 else if (isspace(*line)) {
Emeric Brun50bcecc2013-04-22 13:05:23 +02001612 newarg = 1;
1613 *line = 0;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001614 }
Emeric Brun50bcecc2013-04-22 13:05:23 +02001615 else if (newarg) {
1616 if (arg == MAX_LINE_ARGS) {
1617 memprintf(err, "too many args on line %d in file '%s'.",
1618 linenum, file);
1619 cfgerr = 1;
1620 break;
1621 }
1622 newarg = 0;
1623 args[arg++] = line;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001624 }
Emeric Brun50bcecc2013-04-22 13:05:23 +02001625 line++;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001626 }
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001627 if (cfgerr)
1628 break;
Willy Tarreauad1731d2013-04-02 17:35:58 +02001629
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001630 /* empty line */
Emeric Brun50bcecc2013-04-22 13:05:23 +02001631 if (!arg)
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001632 continue;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001633
Emeric Brun50bcecc2013-04-22 13:05:23 +02001634 cfgerr = ssl_sock_load_cert_file(args[0], bind_conf, curproxy, &args[1], arg-1, err);
Willy Tarreauad1731d2013-04-02 17:35:58 +02001635 if (cfgerr) {
1636 memprintf(err, "error processing line %d in file '%s' : %s", linenum, file, *err);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001637 break;
Willy Tarreauad1731d2013-04-02 17:35:58 +02001638 }
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001639 }
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001640 fclose(f);
1641 return cfgerr;
1642}
1643
Emeric Brunfc0421f2012-09-07 17:30:07 +02001644#ifndef SSL_OP_CIPHER_SERVER_PREFERENCE /* needs OpenSSL >= 0.9.7 */
1645#define SSL_OP_CIPHER_SERVER_PREFERENCE 0
1646#endif
1647
1648#ifndef SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION /* needs OpenSSL >= 0.9.7 */
1649#define SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION 0
Willy Tarreau7d588ee2012-11-26 18:47:31 +01001650#define SSL_renegotiate_pending(arg) 0
Emeric Brunfc0421f2012-09-07 17:30:07 +02001651#endif
Emeric Brun2b58d042012-09-20 17:10:03 +02001652#ifndef SSL_OP_SINGLE_ECDH_USE /* needs OpenSSL >= 0.9.8 */
1653#define SSL_OP_SINGLE_ECDH_USE 0
1654#endif
Emeric Brun2d0c4822012-10-02 13:45:20 +02001655#ifndef SSL_OP_NO_TICKET /* needs OpenSSL >= 0.9.8 */
1656#define SSL_OP_NO_TICKET 0
1657#endif
Emeric Brunfc0421f2012-09-07 17:30:07 +02001658#ifndef SSL_OP_NO_COMPRESSION /* needs OpenSSL >= 0.9.9 */
1659#define SSL_OP_NO_COMPRESSION 0
1660#endif
Emeric Brunc0ff4922012-09-28 19:37:02 +02001661#ifndef SSL_OP_NO_TLSv1_1 /* needs OpenSSL >= 1.0.1 */
1662#define SSL_OP_NO_TLSv1_1 0
1663#endif
1664#ifndef SSL_OP_NO_TLSv1_2 /* needs OpenSSL >= 1.0.1 */
1665#define SSL_OP_NO_TLSv1_2 0
1666#endif
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001667#ifndef SSL_OP_SINGLE_DH_USE /* needs OpenSSL >= 0.9.6 */
1668#define SSL_OP_SINGLE_DH_USE 0
1669#endif
Emeric Brun2b58d042012-09-20 17:10:03 +02001670#ifndef SSL_OP_SINGLE_ECDH_USE /* needs OpenSSL >= 1.0.0 */
1671#define SSL_OP_SINGLE_ECDH_USE 0
1672#endif
Emeric Brunfc0421f2012-09-07 17:30:07 +02001673#ifndef SSL_MODE_RELEASE_BUFFERS /* needs OpenSSL >= 1.0.0 */
1674#define SSL_MODE_RELEASE_BUFFERS 0
1675#endif
Willy Tarreau396a1862014-11-13 14:06:52 +01001676#ifndef SSL_MODE_SMALL_BUFFERS /* needs small_records.patch */
1677#define SSL_MODE_SMALL_BUFFERS 0
1678#endif
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001679
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001680int ssl_sock_prepare_ctx(struct bind_conf *bind_conf, SSL_CTX *ctx, struct proxy *curproxy)
Emeric Brunfc0421f2012-09-07 17:30:07 +02001681{
1682 int cfgerr = 0;
Emeric Brun850efd52014-01-29 12:24:34 +01001683 int verify = SSL_VERIFY_NONE;
Remi Gacogneaf5c3da2014-05-19 10:29:58 +02001684 long ssloptions =
Emeric Brunfc0421f2012-09-07 17:30:07 +02001685 SSL_OP_ALL | /* all known workarounds for bugs */
1686 SSL_OP_NO_SSLv2 |
1687 SSL_OP_NO_COMPRESSION |
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001688 SSL_OP_SINGLE_DH_USE |
Emeric Brun2b58d042012-09-20 17:10:03 +02001689 SSL_OP_SINGLE_ECDH_USE |
Emeric Brun3c4bc6e2012-10-04 18:44:19 +02001690 SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION |
1691 SSL_OP_CIPHER_SERVER_PREFERENCE;
Remi Gacogneaf5c3da2014-05-19 10:29:58 +02001692 long sslmode =
Emeric Brunfc0421f2012-09-07 17:30:07 +02001693 SSL_MODE_ENABLE_PARTIAL_WRITE |
1694 SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER |
Willy Tarreau396a1862014-11-13 14:06:52 +01001695 SSL_MODE_RELEASE_BUFFERS |
1696 SSL_MODE_SMALL_BUFFERS;
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001697 STACK_OF(SSL_CIPHER) * ciphers = NULL;
Willy Tarreaua616ba62014-10-26 06:49:19 +01001698 SSL_CIPHER * cipher = NULL;
Remi Gacognec1eab8c2014-06-12 18:20:11 +02001699 char cipher_description[128];
1700 /* The description of ciphers using an Ephemeral Diffie Hellman key exchange
1701 contains " Kx=DH " or " Kx=DH(". Beware of " Kx=DH/",
1702 which is not ephemeral DH. */
1703 const char dhe_description[] = " Kx=DH ";
1704 const char dhe_export_description[] = " Kx=DH(";
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001705 int idx = 0;
1706 int dhe_found = 0;
Remi Gacogne23d5d372014-10-10 17:04:26 +02001707 SSL *ssl = NULL;
Emeric Brunfc0421f2012-09-07 17:30:07 +02001708
Thierry Fournier383085f2013-01-24 14:15:43 +01001709 /* Make sure openssl opens /dev/urandom before the chroot */
1710 if (!ssl_initialize_random()) {
1711 Alert("OpenSSL random data generator initialization failed.\n");
1712 cfgerr++;
1713 }
1714
Emeric Brun89675492012-10-05 13:48:26 +02001715 if (bind_conf->ssl_options & BC_SSL_O_NO_SSLV3)
Emeric Brunfc0421f2012-09-07 17:30:07 +02001716 ssloptions |= SSL_OP_NO_SSLv3;
Emeric Brun89675492012-10-05 13:48:26 +02001717 if (bind_conf->ssl_options & BC_SSL_O_NO_TLSV10)
Emeric Brunfc0421f2012-09-07 17:30:07 +02001718 ssloptions |= SSL_OP_NO_TLSv1;
Emeric Brun89675492012-10-05 13:48:26 +02001719 if (bind_conf->ssl_options & BC_SSL_O_NO_TLSV11)
Emeric Brunc0ff4922012-09-28 19:37:02 +02001720 ssloptions |= SSL_OP_NO_TLSv1_1;
Emeric Brun89675492012-10-05 13:48:26 +02001721 if (bind_conf->ssl_options & BC_SSL_O_NO_TLSV12)
Emeric Brunc0ff4922012-09-28 19:37:02 +02001722 ssloptions |= SSL_OP_NO_TLSv1_2;
Emeric Brun89675492012-10-05 13:48:26 +02001723 if (bind_conf->ssl_options & BC_SSL_O_NO_TLS_TICKETS)
Emeric Brun2d0c4822012-10-02 13:45:20 +02001724 ssloptions |= SSL_OP_NO_TICKET;
Emeric Brun2cb7ae52012-10-05 14:14:21 +02001725 if (bind_conf->ssl_options & BC_SSL_O_USE_SSLV3)
1726 SSL_CTX_set_ssl_version(ctx, SSLv3_server_method());
1727 if (bind_conf->ssl_options & BC_SSL_O_USE_TLSV10)
1728 SSL_CTX_set_ssl_version(ctx, TLSv1_server_method());
1729#if SSL_OP_NO_TLSv1_1
1730 if (bind_conf->ssl_options & BC_SSL_O_USE_TLSV11)
1731 SSL_CTX_set_ssl_version(ctx, TLSv1_1_server_method());
1732#endif
1733#if SSL_OP_NO_TLSv1_2
1734 if (bind_conf->ssl_options & BC_SSL_O_USE_TLSV12)
1735 SSL_CTX_set_ssl_version(ctx, TLSv1_2_server_method());
1736#endif
Emeric Brunfc0421f2012-09-07 17:30:07 +02001737
1738 SSL_CTX_set_options(ctx, ssloptions);
1739 SSL_CTX_set_mode(ctx, sslmode);
Emeric Brun850efd52014-01-29 12:24:34 +01001740 switch (bind_conf->verify) {
1741 case SSL_SOCK_VERIFY_NONE:
1742 verify = SSL_VERIFY_NONE;
1743 break;
1744 case SSL_SOCK_VERIFY_OPTIONAL:
1745 verify = SSL_VERIFY_PEER;
1746 break;
1747 case SSL_SOCK_VERIFY_REQUIRED:
1748 verify = SSL_VERIFY_PEER|SSL_VERIFY_FAIL_IF_NO_PEER_CERT;
1749 break;
1750 }
1751 SSL_CTX_set_verify(ctx, verify, ssl_sock_bind_verifycbk);
1752 if (verify & SSL_VERIFY_PEER) {
Emeric Brunfb510ea2012-10-05 12:00:26 +02001753 if (bind_conf->ca_file) {
Emeric Brund94b3fe2012-09-20 18:23:56 +02001754 /* load CAfile to verify */
Emeric Brunfb510ea2012-10-05 12:00:26 +02001755 if (!SSL_CTX_load_verify_locations(ctx, bind_conf->ca_file, NULL)) {
Emeric Brund94b3fe2012-09-20 18:23:56 +02001756 Alert("Proxy '%s': unable to load CA file '%s' for bind '%s' at [%s:%d].\n",
Emeric Brunfb510ea2012-10-05 12:00:26 +02001757 curproxy->id, bind_conf->ca_file, bind_conf->arg, bind_conf->file, bind_conf->line);
Emeric Brund94b3fe2012-09-20 18:23:56 +02001758 cfgerr++;
1759 }
1760 /* set CA names fo client cert request, function returns void */
Emeric Brunfb510ea2012-10-05 12:00:26 +02001761 SSL_CTX_set_client_CA_list(ctx, SSL_load_client_CA_file(bind_conf->ca_file));
Emeric Brund94b3fe2012-09-20 18:23:56 +02001762 }
Emeric Brun850efd52014-01-29 12:24:34 +01001763 else {
1764 Alert("Proxy '%s': verify is enabled but no CA file specified for bind '%s' at [%s:%d].\n",
1765 curproxy->id, bind_conf->arg, bind_conf->file, bind_conf->line);
1766 cfgerr++;
1767 }
Emeric Brun051cdab2012-10-02 19:25:50 +02001768#ifdef X509_V_FLAG_CRL_CHECK
Emeric Brunfb510ea2012-10-05 12:00:26 +02001769 if (bind_conf->crl_file) {
Emeric Brund94b3fe2012-09-20 18:23:56 +02001770 X509_STORE *store = SSL_CTX_get_cert_store(ctx);
1771
Emeric Brunfb510ea2012-10-05 12:00:26 +02001772 if (!store || !X509_STORE_load_locations(store, bind_conf->crl_file, NULL)) {
Emeric Brund94b3fe2012-09-20 18:23:56 +02001773 Alert("Proxy '%s': unable to configure CRL file '%s' for bind '%s' at [%s:%d].\n",
Emeric Brunfb510ea2012-10-05 12:00:26 +02001774 curproxy->id, bind_conf->ca_file, bind_conf->arg, bind_conf->file, bind_conf->line);
Emeric Brund94b3fe2012-09-20 18:23:56 +02001775 cfgerr++;
1776 }
Emeric Brun561e5742012-10-02 15:20:55 +02001777 else {
1778 X509_STORE_set_flags(store, X509_V_FLAG_CRL_CHECK|X509_V_FLAG_CRL_CHECK_ALL);
1779 }
Emeric Brund94b3fe2012-09-20 18:23:56 +02001780 }
Emeric Brun051cdab2012-10-02 19:25:50 +02001781#endif
Emeric Brun644cde02012-12-14 11:21:13 +01001782 ERR_clear_error();
Emeric Brund94b3fe2012-09-20 18:23:56 +02001783 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02001784
Nenad Merdanovic05552d42015-02-27 19:56:49 +01001785#if (defined SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB && TLS_TICKETS_NO > 0)
1786 if(bind_conf->tls_ticket_keys) {
1787 if (!SSL_CTX_set_tlsext_ticket_key_cb(ctx, ssl_tlsext_ticket_key_cb)) {
1788 Alert("Proxy '%s': unable to set callback for TLS ticket validation for bind '%s' at [%s:%d].\n",
1789 curproxy->id, bind_conf->arg, bind_conf->file, bind_conf->line);
1790 cfgerr++;
1791 }
1792 }
1793#endif
1794
Emeric Brun4f65bff2012-11-16 15:11:00 +01001795 if (global.tune.ssllifetime)
1796 SSL_CTX_set_timeout(ctx, global.tune.ssllifetime);
1797
Emeric Brunfc0421f2012-09-07 17:30:07 +02001798 shared_context_set_cache(ctx);
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001799 if (bind_conf->ciphers &&
1800 !SSL_CTX_set_cipher_list(ctx, bind_conf->ciphers)) {
Emeric Brunfc0421f2012-09-07 17:30:07 +02001801 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 +02001802 curproxy->id, bind_conf->ciphers, bind_conf->arg, bind_conf->file, bind_conf->line);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001803 cfgerr++;
1804 }
1805
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001806 /* If tune.ssl.default-dh-param has not been set and
1807 no static DH params were in the certificate file. */
1808 if (global.tune.ssl_default_dh_param == 0) {
Lukas Tribus90132722014-08-18 00:56:33 +02001809
Remi Gacogne23d5d372014-10-10 17:04:26 +02001810 ssl = SSL_new(ctx);
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001811
Remi Gacogne23d5d372014-10-10 17:04:26 +02001812 if (ssl) {
1813 ciphers = SSL_get_ciphers(ssl);
1814
1815 if (ciphers) {
1816 for (idx = 0; idx < sk_SSL_CIPHER_num(ciphers); idx++) {
1817 cipher = sk_SSL_CIPHER_value(ciphers, idx);
1818 if (SSL_CIPHER_description(cipher, cipher_description, sizeof (cipher_description)) == cipher_description) {
1819 if (strstr(cipher_description, dhe_description) != NULL ||
1820 strstr(cipher_description, dhe_export_description) != NULL) {
1821 dhe_found = 1;
1822 break;
1823 }
Remi Gacognec1eab8c2014-06-12 18:20:11 +02001824 }
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001825 }
1826 }
Remi Gacogne23d5d372014-10-10 17:04:26 +02001827 SSL_free(ssl);
1828 ssl = NULL;
Lukas Tribus90132722014-08-18 00:56:33 +02001829 }
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001830
Lukas Tribus90132722014-08-18 00:56:33 +02001831 if (dhe_found) {
1832 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 +02001833 }
1834
1835 global.tune.ssl_default_dh_param = 1024;
1836 }
Remi Gacogne8de54152014-07-15 11:36:40 +02001837
1838#ifndef OPENSSL_NO_DH
1839 if (global.tune.ssl_default_dh_param >= 1024) {
1840 if (local_dh_1024 == NULL) {
1841 local_dh_1024 = ssl_get_dh_1024();
1842 }
1843 if (global.tune.ssl_default_dh_param >= 2048) {
1844 if (local_dh_2048 == NULL) {
1845 local_dh_2048 = ssl_get_dh_2048();
1846 }
1847 if (global.tune.ssl_default_dh_param >= 4096) {
1848 if (local_dh_4096 == NULL) {
1849 local_dh_4096 = ssl_get_dh_4096();
1850 }
1851 if (global.tune.ssl_default_dh_param >= 8192 &&
1852 local_dh_8192 == NULL) {
1853 local_dh_8192 = ssl_get_dh_8192();
1854 }
1855 }
1856 }
1857 }
1858#endif /* OPENSSL_NO_DH */
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001859
Emeric Brunfc0421f2012-09-07 17:30:07 +02001860 SSL_CTX_set_info_callback(ctx, ssl_sock_infocbk);
Willy Tarreau5cbe4ef2014-05-08 22:45:11 +02001861#if OPENSSL_VERSION_NUMBER >= 0x00907000L
Emeric Brun29f037d2014-04-25 19:05:36 +02001862 SSL_CTX_set_msg_callback(ctx, ssl_sock_msgcbk);
Willy Tarreau5cbe4ef2014-05-08 22:45:11 +02001863#endif
Emeric Brun29f037d2014-04-25 19:05:36 +02001864
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02001865#ifdef OPENSSL_NPN_NEGOTIATED
1866 if (bind_conf->npn_str)
1867 SSL_CTX_set_next_protos_advertised_cb(ctx, ssl_sock_advertise_npn_protos, bind_conf);
1868#endif
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01001869#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Willy Tarreauab861d32013-04-02 02:30:41 +02001870 if (bind_conf->alpn_str)
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01001871 SSL_CTX_set_alpn_select_cb(ctx, ssl_sock_advertise_alpn_protos, bind_conf);
Willy Tarreauab861d32013-04-02 02:30:41 +02001872#endif
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02001873
Emeric Brunfc0421f2012-09-07 17:30:07 +02001874#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
1875 SSL_CTX_set_tlsext_servername_callback(ctx, ssl_sock_switchctx_cbk);
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001876 SSL_CTX_set_tlsext_servername_arg(ctx, bind_conf);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001877#endif
Emeric Brun2b58d042012-09-20 17:10:03 +02001878#if defined(SSL_CTX_set_tmp_ecdh) && !defined(OPENSSL_NO_ECDH)
Emeric Brun6924ef82013-03-06 14:08:53 +01001879 {
Emeric Brun2b58d042012-09-20 17:10:03 +02001880 int i;
1881 EC_KEY *ecdh;
1882
Emeric Brun6924ef82013-03-06 14:08:53 +01001883 i = OBJ_sn2nid(bind_conf->ecdhe ? bind_conf->ecdhe : ECDHE_DEFAULT_CURVE);
Emeric Brun2b58d042012-09-20 17:10:03 +02001884 if (!i || ((ecdh = EC_KEY_new_by_curve_name(i)) == NULL)) {
1885 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 +01001886 curproxy->id, bind_conf->ecdhe ? bind_conf->ecdhe : ECDHE_DEFAULT_CURVE,
1887 bind_conf->arg, bind_conf->file, bind_conf->line);
Emeric Brun2b58d042012-09-20 17:10:03 +02001888 cfgerr++;
1889 }
1890 else {
1891 SSL_CTX_set_tmp_ecdh(ctx, ecdh);
1892 EC_KEY_free(ecdh);
1893 }
1894 }
1895#endif
1896
Emeric Brunfc0421f2012-09-07 17:30:07 +02001897 return cfgerr;
1898}
1899
Evan Broderbe554312013-06-27 00:05:25 -07001900static int ssl_sock_srv_hostcheck(const char *pattern, const char *hostname)
1901{
1902 const char *pattern_wildcard, *pattern_left_label_end, *hostname_left_label_end;
1903 size_t prefixlen, suffixlen;
1904
1905 /* Trivial case */
1906 if (strcmp(pattern, hostname) == 0)
1907 return 1;
1908
Evan Broderbe554312013-06-27 00:05:25 -07001909 /* The rest of this logic is based on RFC 6125, section 6.4.3
1910 * (http://tools.ietf.org/html/rfc6125#section-6.4.3) */
1911
Emeric Bruna848dae2013-10-08 11:27:28 +02001912 pattern_wildcard = NULL;
1913 pattern_left_label_end = pattern;
1914 while (*pattern_left_label_end != '.') {
1915 switch (*pattern_left_label_end) {
1916 case 0:
1917 /* End of label not found */
1918 return 0;
1919 case '*':
1920 /* If there is more than one wildcards */
1921 if (pattern_wildcard)
1922 return 0;
1923 pattern_wildcard = pattern_left_label_end;
1924 break;
1925 }
1926 pattern_left_label_end++;
1927 }
1928
1929 /* If it's not trivial and there is no wildcard, it can't
1930 * match */
1931 if (!pattern_wildcard)
Evan Broderbe554312013-06-27 00:05:25 -07001932 return 0;
1933
1934 /* Make sure all labels match except the leftmost */
1935 hostname_left_label_end = strchr(hostname, '.');
1936 if (!hostname_left_label_end
1937 || strcmp(pattern_left_label_end, hostname_left_label_end) != 0)
1938 return 0;
1939
1940 /* Make sure the leftmost label of the hostname is long enough
1941 * that the wildcard can match */
Emeric Brun369da852013-10-08 11:39:35 +02001942 if (hostname_left_label_end - hostname < (pattern_left_label_end - pattern) - 1)
Evan Broderbe554312013-06-27 00:05:25 -07001943 return 0;
1944
1945 /* Finally compare the string on either side of the
1946 * wildcard */
1947 prefixlen = pattern_wildcard - pattern;
1948 suffixlen = pattern_left_label_end - (pattern_wildcard + 1);
Emeric Bruna848dae2013-10-08 11:27:28 +02001949 if ((prefixlen && (memcmp(pattern, hostname, prefixlen) != 0))
1950 || (suffixlen && (memcmp(pattern_wildcard + 1, hostname_left_label_end - suffixlen, suffixlen) != 0)))
Evan Broderbe554312013-06-27 00:05:25 -07001951 return 0;
1952
1953 return 1;
1954}
1955
1956static int ssl_sock_srv_verifycbk(int ok, X509_STORE_CTX *ctx)
1957{
1958 SSL *ssl;
1959 struct connection *conn;
1960 char *servername;
1961
1962 int depth;
1963 X509 *cert;
1964 STACK_OF(GENERAL_NAME) *alt_names;
1965 int i;
1966 X509_NAME *cert_subject;
1967 char *str;
1968
1969 if (ok == 0)
1970 return ok;
1971
1972 ssl = X509_STORE_CTX_get_ex_data(ctx, SSL_get_ex_data_X509_STORE_CTX_idx());
1973 conn = (struct connection *)SSL_get_app_data(ssl);
1974
1975 servername = objt_server(conn->target)->ssl_ctx.verify_host;
1976
1977 /* We only need to verify the CN on the actual server cert,
1978 * not the indirect CAs */
1979 depth = X509_STORE_CTX_get_error_depth(ctx);
1980 if (depth != 0)
1981 return ok;
1982
1983 /* At this point, the cert is *not* OK unless we can find a
1984 * hostname match */
1985 ok = 0;
1986
1987 cert = X509_STORE_CTX_get_current_cert(ctx);
1988 /* It seems like this might happen if verify peer isn't set */
1989 if (!cert)
1990 return ok;
1991
1992 alt_names = X509_get_ext_d2i(cert, NID_subject_alt_name, NULL, NULL);
1993 if (alt_names) {
1994 for (i = 0; !ok && i < sk_GENERAL_NAME_num(alt_names); i++) {
1995 GENERAL_NAME *name = sk_GENERAL_NAME_value(alt_names, i);
1996 if (name->type == GEN_DNS) {
Emeric Bruna33410c2013-09-17 15:47:48 +02001997#if OPENSSL_VERSION_NUMBER < 0x00907000L
1998 if (ASN1_STRING_to_UTF8((unsigned char **)&str, name->d.ia5) >= 0) {
1999#else
Evan Broderbe554312013-06-27 00:05:25 -07002000 if (ASN1_STRING_to_UTF8((unsigned char **)&str, name->d.dNSName) >= 0) {
Emeric Bruna33410c2013-09-17 15:47:48 +02002001#endif
Evan Broderbe554312013-06-27 00:05:25 -07002002 ok = ssl_sock_srv_hostcheck(str, servername);
2003 OPENSSL_free(str);
2004 }
2005 }
2006 }
Emeric Brun4ad50a42013-09-17 15:19:54 +02002007 sk_GENERAL_NAME_pop_free(alt_names, GENERAL_NAME_free);
Evan Broderbe554312013-06-27 00:05:25 -07002008 }
2009
2010 cert_subject = X509_get_subject_name(cert);
2011 i = -1;
2012 while (!ok && (i = X509_NAME_get_index_by_NID(cert_subject, NID_commonName, i)) != -1) {
2013 X509_NAME_ENTRY *entry = X509_NAME_get_entry(cert_subject, i);
2014 if (ASN1_STRING_to_UTF8((unsigned char **)&str, entry->value) >= 0) {
2015 ok = ssl_sock_srv_hostcheck(str, servername);
2016 OPENSSL_free(str);
2017 }
2018 }
2019
2020 return ok;
2021}
2022
Emeric Brun94324a42012-10-11 14:00:19 +02002023/* prepare ssl context from servers options. Returns an error count */
2024int ssl_sock_prepare_srv_ctx(struct server *srv, struct proxy *curproxy)
2025{
2026 int cfgerr = 0;
Remi Gacogneaf5c3da2014-05-19 10:29:58 +02002027 long options =
Emeric Brun94324a42012-10-11 14:00:19 +02002028 SSL_OP_ALL | /* all known workarounds for bugs */
2029 SSL_OP_NO_SSLv2 |
2030 SSL_OP_NO_COMPRESSION;
Remi Gacogneaf5c3da2014-05-19 10:29:58 +02002031 long mode =
Emeric Brun94324a42012-10-11 14:00:19 +02002032 SSL_MODE_ENABLE_PARTIAL_WRITE |
2033 SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER |
Willy Tarreau396a1862014-11-13 14:06:52 +01002034 SSL_MODE_RELEASE_BUFFERS |
2035 SSL_MODE_SMALL_BUFFERS;
Emeric Brun850efd52014-01-29 12:24:34 +01002036 int verify = SSL_VERIFY_NONE;
Emeric Brun94324a42012-10-11 14:00:19 +02002037
Thierry Fournier383085f2013-01-24 14:15:43 +01002038 /* Make sure openssl opens /dev/urandom before the chroot */
2039 if (!ssl_initialize_random()) {
2040 Alert("OpenSSL random data generator initialization failed.\n");
2041 cfgerr++;
2042 }
2043
Willy Tarreaufce03112015-01-15 21:32:40 +01002044 /* Automatic memory computations need to know we use SSL there */
2045 global.ssl_used_backend = 1;
2046
2047 /* Initiate SSL context for current server */
Emeric Brun94324a42012-10-11 14:00:19 +02002048 srv->ssl_ctx.reused_sess = NULL;
2049 if (srv->use_ssl)
2050 srv->xprt = &ssl_sock;
2051 if (srv->check.use_ssl)
Cyril Bonté9ce13112014-11-15 22:41:27 +01002052 srv->check.xprt = &ssl_sock;
Emeric Brun94324a42012-10-11 14:00:19 +02002053
2054 srv->ssl_ctx.ctx = SSL_CTX_new(SSLv23_client_method());
2055 if (!srv->ssl_ctx.ctx) {
2056 Alert("config : %s '%s', server '%s': unable to allocate ssl context.\n",
2057 proxy_type_str(curproxy), curproxy->id,
2058 srv->id);
2059 cfgerr++;
2060 return cfgerr;
2061 }
Emeric Bruna7aa3092012-10-26 12:58:00 +02002062 if (srv->ssl_ctx.client_crt) {
2063 if (SSL_CTX_use_PrivateKey_file(srv->ssl_ctx.ctx, srv->ssl_ctx.client_crt, SSL_FILETYPE_PEM) <= 0) {
2064 Alert("config : %s '%s', server '%s': unable to load SSL private key from PEM file '%s'.\n",
2065 proxy_type_str(curproxy), curproxy->id,
2066 srv->id, srv->ssl_ctx.client_crt);
2067 cfgerr++;
2068 }
2069 else if (SSL_CTX_use_certificate_chain_file(srv->ssl_ctx.ctx, srv->ssl_ctx.client_crt) <= 0) {
2070 Alert("config : %s '%s', server '%s': unable to load ssl certificate from PEM file '%s'.\n",
2071 proxy_type_str(curproxy), curproxy->id,
2072 srv->id, srv->ssl_ctx.client_crt);
2073 cfgerr++;
2074 }
2075 else if (SSL_CTX_check_private_key(srv->ssl_ctx.ctx) <= 0) {
2076 Alert("config : %s '%s', server '%s': inconsistencies between private key and certificate loaded from PEM file '%s'.\n",
2077 proxy_type_str(curproxy), curproxy->id,
2078 srv->id, srv->ssl_ctx.client_crt);
2079 cfgerr++;
2080 }
2081 }
Emeric Brun94324a42012-10-11 14:00:19 +02002082
2083 if (srv->ssl_ctx.options & SRV_SSL_O_NO_SSLV3)
2084 options |= SSL_OP_NO_SSLv3;
2085 if (srv->ssl_ctx.options & SRV_SSL_O_NO_TLSV10)
2086 options |= SSL_OP_NO_TLSv1;
2087 if (srv->ssl_ctx.options & SRV_SSL_O_NO_TLSV11)
2088 options |= SSL_OP_NO_TLSv1_1;
2089 if (srv->ssl_ctx.options & SRV_SSL_O_NO_TLSV12)
2090 options |= SSL_OP_NO_TLSv1_2;
Emeric Brunf9c5c472012-10-11 15:28:34 +02002091 if (srv->ssl_ctx.options & SRV_SSL_O_NO_TLS_TICKETS)
2092 options |= SSL_OP_NO_TICKET;
Emeric Brun94324a42012-10-11 14:00:19 +02002093 if (srv->ssl_ctx.options & SRV_SSL_O_USE_SSLV3)
2094 SSL_CTX_set_ssl_version(srv->ssl_ctx.ctx, SSLv3_client_method());
2095 if (srv->ssl_ctx.options & SRV_SSL_O_USE_TLSV10)
2096 SSL_CTX_set_ssl_version(srv->ssl_ctx.ctx, TLSv1_client_method());
2097#if SSL_OP_NO_TLSv1_1
2098 if (srv->ssl_ctx.options & SRV_SSL_O_USE_TLSV11)
2099 SSL_CTX_set_ssl_version(srv->ssl_ctx.ctx, TLSv1_1_client_method());
2100#endif
2101#if SSL_OP_NO_TLSv1_2
2102 if (srv->ssl_ctx.options & SRV_SSL_O_USE_TLSV12)
2103 SSL_CTX_set_ssl_version(srv->ssl_ctx.ctx, TLSv1_2_client_method());
2104#endif
2105
2106 SSL_CTX_set_options(srv->ssl_ctx.ctx, options);
2107 SSL_CTX_set_mode(srv->ssl_ctx.ctx, mode);
Emeric Brun850efd52014-01-29 12:24:34 +01002108
2109 if (global.ssl_server_verify == SSL_SERVER_VERIFY_REQUIRED)
2110 verify = SSL_VERIFY_PEER;
2111
2112 switch (srv->ssl_ctx.verify) {
2113 case SSL_SOCK_VERIFY_NONE:
2114 verify = SSL_VERIFY_NONE;
2115 break;
2116 case SSL_SOCK_VERIFY_REQUIRED:
2117 verify = SSL_VERIFY_PEER;
2118 break;
2119 }
Evan Broderbe554312013-06-27 00:05:25 -07002120 SSL_CTX_set_verify(srv->ssl_ctx.ctx,
Emeric Brun850efd52014-01-29 12:24:34 +01002121 verify,
Evan Broderbe554312013-06-27 00:05:25 -07002122 srv->ssl_ctx.verify_host ? ssl_sock_srv_verifycbk : NULL);
Emeric Brun850efd52014-01-29 12:24:34 +01002123 if (verify & SSL_VERIFY_PEER) {
Emeric Brunef42d922012-10-11 16:11:36 +02002124 if (srv->ssl_ctx.ca_file) {
2125 /* load CAfile to verify */
2126 if (!SSL_CTX_load_verify_locations(srv->ssl_ctx.ctx, srv->ssl_ctx.ca_file, NULL)) {
Willy Tarreau07ba08b2014-02-16 19:22:08 +01002127 Alert("Proxy '%s', server '%s' [%s:%d] unable to load CA file '%s'.\n",
Emeric Brunef42d922012-10-11 16:11:36 +02002128 curproxy->id, srv->id,
2129 srv->conf.file, srv->conf.line, srv->ssl_ctx.ca_file);
2130 cfgerr++;
2131 }
2132 }
Emeric Brun850efd52014-01-29 12:24:34 +01002133 else {
2134 if (global.ssl_server_verify == SSL_SERVER_VERIFY_REQUIRED)
Willy Tarreau07ba08b2014-02-16 19:22:08 +01002135 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 +01002136 curproxy->id, srv->id,
2137 srv->conf.file, srv->conf.line);
2138 else
Willy Tarreau07ba08b2014-02-16 19:22:08 +01002139 Alert("Proxy '%s', server '%s' [%s:%d] verify is enabled but no CA file specified.\n",
Emeric Brun850efd52014-01-29 12:24:34 +01002140 curproxy->id, srv->id,
2141 srv->conf.file, srv->conf.line);
2142 cfgerr++;
2143 }
Emeric Brunef42d922012-10-11 16:11:36 +02002144#ifdef X509_V_FLAG_CRL_CHECK
2145 if (srv->ssl_ctx.crl_file) {
2146 X509_STORE *store = SSL_CTX_get_cert_store(srv->ssl_ctx.ctx);
2147
2148 if (!store || !X509_STORE_load_locations(store, srv->ssl_ctx.crl_file, NULL)) {
Willy Tarreau07ba08b2014-02-16 19:22:08 +01002149 Alert("Proxy '%s', server '%s' [%s:%d] unable to configure CRL file '%s'.\n",
Emeric Brunef42d922012-10-11 16:11:36 +02002150 curproxy->id, srv->id,
2151 srv->conf.file, srv->conf.line, srv->ssl_ctx.crl_file);
2152 cfgerr++;
2153 }
2154 else {
2155 X509_STORE_set_flags(store, X509_V_FLAG_CRL_CHECK|X509_V_FLAG_CRL_CHECK_ALL);
2156 }
2157 }
2158#endif
2159 }
2160
Emeric Brun4f65bff2012-11-16 15:11:00 +01002161 if (global.tune.ssllifetime)
2162 SSL_CTX_set_timeout(srv->ssl_ctx.ctx, global.tune.ssllifetime);
2163
Emeric Brun94324a42012-10-11 14:00:19 +02002164 SSL_CTX_set_session_cache_mode(srv->ssl_ctx.ctx, SSL_SESS_CACHE_OFF);
2165 if (srv->ssl_ctx.ciphers &&
2166 !SSL_CTX_set_cipher_list(srv->ssl_ctx.ctx, srv->ssl_ctx.ciphers)) {
2167 Alert("Proxy '%s', server '%s' [%s:%d] : unable to set SSL cipher list to '%s'.\n",
2168 curproxy->id, srv->id,
2169 srv->conf.file, srv->conf.line, srv->ssl_ctx.ciphers);
2170 cfgerr++;
2171 }
2172
2173 return cfgerr;
2174}
2175
Willy Tarreau2a65ff02012-09-13 17:54:29 +02002176/* Walks down the two trees in bind_conf and prepares all certs. The pointer may
Emeric Brunfc0421f2012-09-07 17:30:07 +02002177 * be NULL, in which case nothing is done. Returns the number of errors
2178 * encountered.
2179 */
Willy Tarreau2a65ff02012-09-13 17:54:29 +02002180int ssl_sock_prepare_all_ctx(struct bind_conf *bind_conf, struct proxy *px)
Emeric Brunfc0421f2012-09-07 17:30:07 +02002181{
2182 struct ebmb_node *node;
2183 struct sni_ctx *sni;
2184 int err = 0;
2185
Willy Tarreau2a65ff02012-09-13 17:54:29 +02002186 if (!bind_conf || !bind_conf->is_ssl)
Emeric Brunfc0421f2012-09-07 17:30:07 +02002187 return 0;
2188
Willy Tarreaufce03112015-01-15 21:32:40 +01002189 /* Automatic memory computations need to know we use SSL there */
2190 global.ssl_used_frontend = 1;
2191
Emeric Brun0bed9942014-10-30 19:25:24 +01002192 if (bind_conf->default_ctx)
2193 err += ssl_sock_prepare_ctx(bind_conf, bind_conf->default_ctx, px);
2194
Willy Tarreau2a65ff02012-09-13 17:54:29 +02002195 node = ebmb_first(&bind_conf->sni_ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002196 while (node) {
2197 sni = ebmb_entry(node, struct sni_ctx, name);
Emeric Brun0bed9942014-10-30 19:25:24 +01002198 if (!sni->order && sni->ctx != bind_conf->default_ctx)
2199 /* only initialize the CTX on its first occurrence and
2200 if it is not the default_ctx */
Willy Tarreau2a65ff02012-09-13 17:54:29 +02002201 err += ssl_sock_prepare_ctx(bind_conf, sni->ctx, px);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002202 node = ebmb_next(node);
2203 }
2204
Willy Tarreau2a65ff02012-09-13 17:54:29 +02002205 node = ebmb_first(&bind_conf->sni_w_ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002206 while (node) {
2207 sni = ebmb_entry(node, struct sni_ctx, name);
Emeric Brun0bed9942014-10-30 19:25:24 +01002208 if (!sni->order && sni->ctx != bind_conf->default_ctx)
2209 /* only initialize the CTX on its first occurrence and
2210 if it is not the default_ctx */
Willy Tarreau2a65ff02012-09-13 17:54:29 +02002211 err += ssl_sock_prepare_ctx(bind_conf, sni->ctx, px);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002212 node = ebmb_next(node);
2213 }
2214 return err;
2215}
2216
Willy Tarreau2a65ff02012-09-13 17:54:29 +02002217/* Walks down the two trees in bind_conf and frees all the certs. The pointer may
Emeric Brunfc0421f2012-09-07 17:30:07 +02002218 * be NULL, in which case nothing is done. The default_ctx is nullified too.
2219 */
Willy Tarreau2a65ff02012-09-13 17:54:29 +02002220void ssl_sock_free_all_ctx(struct bind_conf *bind_conf)
Emeric Brunfc0421f2012-09-07 17:30:07 +02002221{
2222 struct ebmb_node *node, *back;
2223 struct sni_ctx *sni;
2224
Willy Tarreau2a65ff02012-09-13 17:54:29 +02002225 if (!bind_conf || !bind_conf->is_ssl)
Emeric Brunfc0421f2012-09-07 17:30:07 +02002226 return;
2227
Willy Tarreau2a65ff02012-09-13 17:54:29 +02002228 node = ebmb_first(&bind_conf->sni_ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002229 while (node) {
2230 sni = ebmb_entry(node, struct sni_ctx, name);
2231 back = ebmb_next(node);
2232 ebmb_delete(node);
2233 if (!sni->order) /* only free the CTX on its first occurrence */
2234 SSL_CTX_free(sni->ctx);
2235 free(sni);
2236 node = back;
2237 }
2238
Willy Tarreau2a65ff02012-09-13 17:54:29 +02002239 node = ebmb_first(&bind_conf->sni_w_ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002240 while (node) {
2241 sni = ebmb_entry(node, struct sni_ctx, name);
2242 back = ebmb_next(node);
2243 ebmb_delete(node);
2244 if (!sni->order) /* only free the CTX on its first occurrence */
2245 SSL_CTX_free(sni->ctx);
2246 free(sni);
2247 node = back;
2248 }
2249
Willy Tarreau2a65ff02012-09-13 17:54:29 +02002250 bind_conf->default_ctx = NULL;
Emeric Brune1f38db2012-09-03 20:36:47 +02002251}
2252
Emeric Brun46591952012-05-18 15:47:34 +02002253/*
2254 * This function is called if SSL * context is not yet allocated. The function
2255 * is designed to be called before any other data-layer operation and sets the
2256 * handshake flag on the connection. It is safe to call it multiple times.
2257 * It returns 0 on success and -1 in error case.
2258 */
2259static int ssl_sock_init(struct connection *conn)
2260{
2261 /* already initialized */
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02002262 if (conn->xprt_ctx)
Emeric Brun46591952012-05-18 15:47:34 +02002263 return 0;
2264
Willy Tarreau3c728722014-01-23 13:50:42 +01002265 if (!conn_ctrl_ready(conn))
Willy Tarreauf79c8172013-10-21 16:30:56 +02002266 return 0;
2267
Willy Tarreau20879a02012-12-03 16:32:10 +01002268 if (global.maxsslconn && sslconns >= global.maxsslconn) {
2269 conn->err_code = CO_ER_SSL_TOO_MANY;
Willy Tarreau403edff2012-09-06 11:58:37 +02002270 return -1;
Willy Tarreau20879a02012-12-03 16:32:10 +01002271 }
Willy Tarreau403edff2012-09-06 11:58:37 +02002272
Emeric Brun46591952012-05-18 15:47:34 +02002273 /* If it is in client mode initiate SSL session
2274 in connect state otherwise accept state */
Willy Tarreau3fdb3662012-11-12 00:42:33 +01002275 if (objt_server(conn->target)) {
Willy Tarreaufba03cd2014-11-13 13:48:58 +01002276 int may_retry = 1;
2277
2278 retry_connect:
Emeric Brun46591952012-05-18 15:47:34 +02002279 /* Alloc a new SSL session ctx */
Willy Tarreau3fdb3662012-11-12 00:42:33 +01002280 conn->xprt_ctx = SSL_new(objt_server(conn->target)->ssl_ctx.ctx);
Willy Tarreau20879a02012-12-03 16:32:10 +01002281 if (!conn->xprt_ctx) {
Willy Tarreaufba03cd2014-11-13 13:48:58 +01002282 if (may_retry--) {
2283 pool_gc2();
2284 goto retry_connect;
2285 }
Willy Tarreau20879a02012-12-03 16:32:10 +01002286 conn->err_code = CO_ER_SSL_NO_MEM;
Emeric Brun46591952012-05-18 15:47:34 +02002287 return -1;
Willy Tarreau20879a02012-12-03 16:32:10 +01002288 }
Emeric Brun46591952012-05-18 15:47:34 +02002289
Emeric Brun46591952012-05-18 15:47:34 +02002290 /* set fd on SSL session context */
Emeric Brun55476152014-11-12 17:35:37 +01002291 if (!SSL_set_fd(conn->xprt_ctx, conn->t.sock.fd)) {
2292 SSL_free(conn->xprt_ctx);
2293 conn->xprt_ctx = NULL;
Willy Tarreaufba03cd2014-11-13 13:48:58 +01002294 if (may_retry--) {
2295 pool_gc2();
2296 goto retry_connect;
2297 }
Emeric Brun55476152014-11-12 17:35:37 +01002298 conn->err_code = CO_ER_SSL_NO_MEM;
2299 return -1;
2300 }
Emeric Brun46591952012-05-18 15:47:34 +02002301
Evan Broderbe554312013-06-27 00:05:25 -07002302 /* set connection pointer */
Emeric Brun55476152014-11-12 17:35:37 +01002303 if (!SSL_set_app_data(conn->xprt_ctx, conn)) {
2304 SSL_free(conn->xprt_ctx);
2305 conn->xprt_ctx = NULL;
Willy Tarreaufba03cd2014-11-13 13:48:58 +01002306 if (may_retry--) {
2307 pool_gc2();
2308 goto retry_connect;
2309 }
Emeric Brun55476152014-11-12 17:35:37 +01002310 conn->err_code = CO_ER_SSL_NO_MEM;
2311 return -1;
2312 }
2313
2314 SSL_set_connect_state(conn->xprt_ctx);
2315 if (objt_server(conn->target)->ssl_ctx.reused_sess) {
2316 if(!SSL_set_session(conn->xprt_ctx, objt_server(conn->target)->ssl_ctx.reused_sess)) {
2317 SSL_SESSION_free(objt_server(conn->target)->ssl_ctx.reused_sess);
2318 objt_server(conn->target)->ssl_ctx.reused_sess = NULL;
2319 }
2320 }
Evan Broderbe554312013-06-27 00:05:25 -07002321
Emeric Brun46591952012-05-18 15:47:34 +02002322 /* leave init state and start handshake */
Willy Tarreau05737472012-09-04 08:03:39 +02002323 conn->flags |= CO_FL_SSL_WAIT_HS | CO_FL_WAIT_L6_CONN;
Willy Tarreau403edff2012-09-06 11:58:37 +02002324
2325 sslconns++;
Willy Tarreau71b734c2014-01-28 15:19:44 +01002326 totalsslconns++;
Emeric Brun46591952012-05-18 15:47:34 +02002327 return 0;
2328 }
Willy Tarreau3fdb3662012-11-12 00:42:33 +01002329 else if (objt_listener(conn->target)) {
Willy Tarreaufba03cd2014-11-13 13:48:58 +01002330 int may_retry = 1;
2331
2332 retry_accept:
Emeric Brun46591952012-05-18 15:47:34 +02002333 /* Alloc a new SSL session ctx */
Willy Tarreau3fdb3662012-11-12 00:42:33 +01002334 conn->xprt_ctx = SSL_new(objt_listener(conn->target)->bind_conf->default_ctx);
Willy Tarreau20879a02012-12-03 16:32:10 +01002335 if (!conn->xprt_ctx) {
Willy Tarreaufba03cd2014-11-13 13:48:58 +01002336 if (may_retry--) {
2337 pool_gc2();
2338 goto retry_accept;
2339 }
Willy Tarreau20879a02012-12-03 16:32:10 +01002340 conn->err_code = CO_ER_SSL_NO_MEM;
Emeric Brun46591952012-05-18 15:47:34 +02002341 return -1;
Willy Tarreau20879a02012-12-03 16:32:10 +01002342 }
Emeric Brun46591952012-05-18 15:47:34 +02002343
Emeric Brun46591952012-05-18 15:47:34 +02002344 /* set fd on SSL session context */
Emeric Brun55476152014-11-12 17:35:37 +01002345 if (!SSL_set_fd(conn->xprt_ctx, conn->t.sock.fd)) {
2346 SSL_free(conn->xprt_ctx);
2347 conn->xprt_ctx = NULL;
Willy Tarreaufba03cd2014-11-13 13:48:58 +01002348 if (may_retry--) {
2349 pool_gc2();
2350 goto retry_accept;
2351 }
Emeric Brun55476152014-11-12 17:35:37 +01002352 conn->err_code = CO_ER_SSL_NO_MEM;
2353 return -1;
2354 }
Emeric Brun46591952012-05-18 15:47:34 +02002355
Emeric Brune1f38db2012-09-03 20:36:47 +02002356 /* set connection pointer */
Emeric Brun55476152014-11-12 17:35:37 +01002357 if (!SSL_set_app_data(conn->xprt_ctx, conn)) {
2358 SSL_free(conn->xprt_ctx);
2359 conn->xprt_ctx = NULL;
Willy Tarreaufba03cd2014-11-13 13:48:58 +01002360 if (may_retry--) {
2361 pool_gc2();
2362 goto retry_accept;
2363 }
Emeric Brun55476152014-11-12 17:35:37 +01002364 conn->err_code = CO_ER_SSL_NO_MEM;
2365 return -1;
2366 }
2367
2368 SSL_set_accept_state(conn->xprt_ctx);
Emeric Brune1f38db2012-09-03 20:36:47 +02002369
Emeric Brun46591952012-05-18 15:47:34 +02002370 /* leave init state and start handshake */
Willy Tarreau05737472012-09-04 08:03:39 +02002371 conn->flags |= CO_FL_SSL_WAIT_HS | CO_FL_WAIT_L6_CONN;
Willy Tarreau403edff2012-09-06 11:58:37 +02002372
2373 sslconns++;
Willy Tarreau71b734c2014-01-28 15:19:44 +01002374 totalsslconns++;
Emeric Brun46591952012-05-18 15:47:34 +02002375 return 0;
2376 }
2377 /* don't know how to handle such a target */
Willy Tarreau20879a02012-12-03 16:32:10 +01002378 conn->err_code = CO_ER_SSL_NO_TARGET;
Emeric Brun46591952012-05-18 15:47:34 +02002379 return -1;
2380}
2381
2382
2383/* This is the callback which is used when an SSL handshake is pending. It
2384 * updates the FD status if it wants some polling before being called again.
2385 * It returns 0 if it fails in a fatal way or needs to poll to go further,
2386 * otherwise it returns non-zero and removes itself from the connection's
2387 * flags (the bit is provided in <flag> by the caller).
2388 */
2389int ssl_sock_handshake(struct connection *conn, unsigned int flag)
2390{
2391 int ret;
2392
Willy Tarreau3c728722014-01-23 13:50:42 +01002393 if (!conn_ctrl_ready(conn))
Willy Tarreauf79c8172013-10-21 16:30:56 +02002394 return 0;
2395
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02002396 if (!conn->xprt_ctx)
Emeric Brun46591952012-05-18 15:47:34 +02002397 goto out_error;
2398
Emeric Brun674b7432012-11-08 19:21:55 +01002399 /* If we use SSL_do_handshake to process a reneg initiated by
2400 * the remote peer, it sometimes returns SSL_ERROR_SSL.
2401 * Usually SSL_write and SSL_read are used and process implicitly
2402 * the reneg handshake.
2403 * Here we use SSL_peek as a workaround for reneg.
2404 */
2405 if ((conn->flags & CO_FL_CONNECTED) && SSL_renegotiate_pending(conn->xprt_ctx)) {
2406 char c;
2407
2408 ret = SSL_peek(conn->xprt_ctx, &c, 1);
2409 if (ret <= 0) {
2410 /* handshake may have not been completed, let's find why */
2411 ret = SSL_get_error(conn->xprt_ctx, ret);
2412 if (ret == SSL_ERROR_WANT_WRITE) {
2413 /* SSL handshake needs to write, L4 connection may not be ready */
2414 __conn_sock_stop_recv(conn);
Willy Tarreaue1f50c42014-01-22 20:02:06 +01002415 __conn_sock_want_send(conn);
2416 fd_cant_send(conn->t.sock.fd);
Emeric Brun674b7432012-11-08 19:21:55 +01002417 return 0;
2418 }
2419 else if (ret == SSL_ERROR_WANT_READ) {
2420 /* handshake may have been completed but we have
2421 * no more data to read.
2422 */
2423 if (!SSL_renegotiate_pending(conn->xprt_ctx)) {
2424 ret = 1;
2425 goto reneg_ok;
2426 }
2427 /* SSL handshake needs to read, L4 connection is ready */
2428 if (conn->flags & CO_FL_WAIT_L4_CONN)
2429 conn->flags &= ~CO_FL_WAIT_L4_CONN;
2430 __conn_sock_stop_send(conn);
Willy Tarreaue1f50c42014-01-22 20:02:06 +01002431 __conn_sock_want_recv(conn);
2432 fd_cant_recv(conn->t.sock.fd);
Emeric Brun674b7432012-11-08 19:21:55 +01002433 return 0;
2434 }
2435 else if (ret == SSL_ERROR_SYSCALL) {
2436 /* if errno is null, then connection was successfully established */
2437 if (!errno && conn->flags & CO_FL_WAIT_L4_CONN)
2438 conn->flags &= ~CO_FL_WAIT_L4_CONN;
Willy Tarreau20879a02012-12-03 16:32:10 +01002439 if (!conn->err_code) {
Emeric Brun29f037d2014-04-25 19:05:36 +02002440 if (!((SSL *)conn->xprt_ctx)->packet_length) {
2441 if (!errno) {
2442 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
2443 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
2444 else
2445 conn->err_code = CO_ER_SSL_EMPTY;
2446 }
2447 else {
2448 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
2449 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
2450 else
2451 conn->err_code = CO_ER_SSL_ABORT;
2452 }
2453 }
2454 else {
2455 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
2456 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
Willy Tarreau20879a02012-12-03 16:32:10 +01002457 else
Emeric Brun29f037d2014-04-25 19:05:36 +02002458 conn->err_code = CO_ER_SSL_HANDSHAKE;
2459 }
Willy Tarreau20879a02012-12-03 16:32:10 +01002460 }
Emeric Brun674b7432012-11-08 19:21:55 +01002461 goto out_error;
2462 }
2463 else {
2464 /* Fail on all other handshake errors */
2465 /* Note: OpenSSL may leave unread bytes in the socket's
2466 * buffer, causing an RST to be emitted upon close() on
2467 * TCP sockets. We first try to drain possibly pending
2468 * data to avoid this as much as possible.
2469 */
Willy Tarreaud85c4852015-03-13 00:40:28 +01002470 conn_sock_drain(conn);
Willy Tarreau20879a02012-12-03 16:32:10 +01002471 if (!conn->err_code)
Willy Tarreauf51c6982014-04-25 20:02:39 +02002472 conn->err_code = (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT) ?
2473 CO_ER_SSL_KILLED_HB : CO_ER_SSL_HANDSHAKE;
Emeric Brun674b7432012-11-08 19:21:55 +01002474 goto out_error;
2475 }
2476 }
2477 /* read some data: consider handshake completed */
2478 goto reneg_ok;
2479 }
2480
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02002481 ret = SSL_do_handshake(conn->xprt_ctx);
Emeric Brun46591952012-05-18 15:47:34 +02002482 if (ret != 1) {
2483 /* handshake did not complete, let's find why */
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02002484 ret = SSL_get_error(conn->xprt_ctx, ret);
Emeric Brun46591952012-05-18 15:47:34 +02002485
2486 if (ret == SSL_ERROR_WANT_WRITE) {
2487 /* SSL handshake needs to write, L4 connection may not be ready */
2488 __conn_sock_stop_recv(conn);
Willy Tarreaue1f50c42014-01-22 20:02:06 +01002489 __conn_sock_want_send(conn);
2490 fd_cant_send(conn->t.sock.fd);
Emeric Brun46591952012-05-18 15:47:34 +02002491 return 0;
2492 }
2493 else if (ret == SSL_ERROR_WANT_READ) {
2494 /* SSL handshake needs to read, L4 connection is ready */
2495 if (conn->flags & CO_FL_WAIT_L4_CONN)
2496 conn->flags &= ~CO_FL_WAIT_L4_CONN;
2497 __conn_sock_stop_send(conn);
Willy Tarreaue1f50c42014-01-22 20:02:06 +01002498 __conn_sock_want_recv(conn);
2499 fd_cant_recv(conn->t.sock.fd);
Emeric Brun46591952012-05-18 15:47:34 +02002500 return 0;
2501 }
Willy Tarreau89230192012-09-28 20:22:13 +02002502 else if (ret == SSL_ERROR_SYSCALL) {
2503 /* if errno is null, then connection was successfully established */
2504 if (!errno && conn->flags & CO_FL_WAIT_L4_CONN)
2505 conn->flags &= ~CO_FL_WAIT_L4_CONN;
Willy Tarreau20879a02012-12-03 16:32:10 +01002506
Emeric Brun29f037d2014-04-25 19:05:36 +02002507 if (!((SSL *)conn->xprt_ctx)->packet_length) {
2508 if (!errno) {
2509 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
2510 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
2511 else
2512 conn->err_code = CO_ER_SSL_EMPTY;
2513 }
2514 else {
2515 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
2516 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
2517 else
2518 conn->err_code = CO_ER_SSL_ABORT;
2519 }
2520 }
2521 else {
2522 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
2523 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
Willy Tarreau20879a02012-12-03 16:32:10 +01002524 else
Emeric Brun29f037d2014-04-25 19:05:36 +02002525 conn->err_code = CO_ER_SSL_HANDSHAKE;
2526 }
Willy Tarreau89230192012-09-28 20:22:13 +02002527 goto out_error;
2528 }
Emeric Brun46591952012-05-18 15:47:34 +02002529 else {
2530 /* Fail on all other handshake errors */
Willy Tarreau566dc552012-10-19 20:52:18 +02002531 /* Note: OpenSSL may leave unread bytes in the socket's
2532 * buffer, causing an RST to be emitted upon close() on
2533 * TCP sockets. We first try to drain possibly pending
2534 * data to avoid this as much as possible.
2535 */
Willy Tarreaud85c4852015-03-13 00:40:28 +01002536 conn_sock_drain(conn);
Willy Tarreau20879a02012-12-03 16:32:10 +01002537 if (!conn->err_code)
Willy Tarreauf51c6982014-04-25 20:02:39 +02002538 conn->err_code = (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT) ?
2539 CO_ER_SSL_KILLED_HB : CO_ER_SSL_HANDSHAKE;
Emeric Brun46591952012-05-18 15:47:34 +02002540 goto out_error;
2541 }
2542 }
2543
Emeric Brun674b7432012-11-08 19:21:55 +01002544reneg_ok:
2545
Emeric Brun46591952012-05-18 15:47:34 +02002546 /* Handshake succeeded */
Willy Tarreau0c9c2722014-05-28 12:28:58 +02002547 if (!SSL_session_reused(conn->xprt_ctx)) {
2548 if (objt_server(conn->target)) {
2549 update_freq_ctr(&global.ssl_be_keys_per_sec, 1);
2550 if (global.ssl_be_keys_per_sec.curr_ctr > global.ssl_be_keys_max)
2551 global.ssl_be_keys_max = global.ssl_be_keys_per_sec.curr_ctr;
2552
Emeric Brun46591952012-05-18 15:47:34 +02002553 /* check if session was reused, if not store current session on server for reuse */
Willy Tarreau3fdb3662012-11-12 00:42:33 +01002554 if (objt_server(conn->target)->ssl_ctx.reused_sess)
2555 SSL_SESSION_free(objt_server(conn->target)->ssl_ctx.reused_sess);
Emeric Brun46591952012-05-18 15:47:34 +02002556
Willy Tarreau2a3fb1c2015-02-05 16:47:07 +01002557 if (!(objt_server(conn->target)->ssl_ctx.options & SRV_SSL_O_NO_REUSE))
2558 objt_server(conn->target)->ssl_ctx.reused_sess = SSL_get1_session(conn->xprt_ctx);
Emeric Brun46591952012-05-18 15:47:34 +02002559 }
Willy Tarreau0c9c2722014-05-28 12:28:58 +02002560 else {
2561 update_freq_ctr(&global.ssl_fe_keys_per_sec, 1);
2562 if (global.ssl_fe_keys_per_sec.curr_ctr > global.ssl_fe_keys_max)
2563 global.ssl_fe_keys_max = global.ssl_fe_keys_per_sec.curr_ctr;
2564 }
Emeric Brun46591952012-05-18 15:47:34 +02002565 }
2566
2567 /* The connection is now established at both layers, it's time to leave */
2568 conn->flags &= ~(flag | CO_FL_WAIT_L4_CONN | CO_FL_WAIT_L6_CONN);
2569 return 1;
2570
2571 out_error:
Emeric Brun644cde02012-12-14 11:21:13 +01002572 /* Clear openssl global errors stack */
2573 ERR_clear_error();
2574
Emeric Brun9fa89732012-10-04 17:09:56 +02002575 /* free resumed session if exists */
Willy Tarreau3fdb3662012-11-12 00:42:33 +01002576 if (objt_server(conn->target) && objt_server(conn->target)->ssl_ctx.reused_sess) {
2577 SSL_SESSION_free(objt_server(conn->target)->ssl_ctx.reused_sess);
2578 objt_server(conn->target)->ssl_ctx.reused_sess = NULL;
Emeric Brun9fa89732012-10-04 17:09:56 +02002579 }
2580
Emeric Brun46591952012-05-18 15:47:34 +02002581 /* Fail on all other handshake errors */
2582 conn->flags |= CO_FL_ERROR;
Willy Tarreau20879a02012-12-03 16:32:10 +01002583 if (!conn->err_code)
2584 conn->err_code = CO_ER_SSL_HANDSHAKE;
Emeric Brun46591952012-05-18 15:47:34 +02002585 return 0;
2586}
2587
2588/* Receive up to <count> bytes from connection <conn>'s socket and store them
Willy Tarreauabf08d92014-01-14 11:31:27 +01002589 * into buffer <buf>. Only one call to recv() is performed, unless the
Emeric Brun46591952012-05-18 15:47:34 +02002590 * buffer wraps, in which case a second call may be performed. The connection's
2591 * flags are updated with whatever special event is detected (error, read0,
2592 * empty). The caller is responsible for taking care of those events and
2593 * avoiding the call if inappropriate. The function does not call the
2594 * connection's polling update function, so the caller is responsible for this.
2595 */
2596static int ssl_sock_to_buf(struct connection *conn, struct buffer *buf, int count)
2597{
2598 int ret, done = 0;
Willy Tarreauabf08d92014-01-14 11:31:27 +01002599 int try;
Emeric Brun46591952012-05-18 15:47:34 +02002600
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02002601 if (!conn->xprt_ctx)
Emeric Brun46591952012-05-18 15:47:34 +02002602 goto out_error;
2603
2604 if (conn->flags & CO_FL_HANDSHAKE)
2605 /* a handshake was requested */
2606 return 0;
2607
Willy Tarreauabf08d92014-01-14 11:31:27 +01002608 /* let's realign the buffer to optimize I/O */
2609 if (buffer_empty(buf))
Emeric Brun46591952012-05-18 15:47:34 +02002610 buf->p = buf->data;
Emeric Brun46591952012-05-18 15:47:34 +02002611
2612 /* read the largest possible block. For this, we perform only one call
2613 * to recv() unless the buffer wraps and we exactly fill the first hunk,
2614 * in which case we accept to do it once again. A new attempt is made on
2615 * EINTR too.
2616 */
Willy Tarreau00b0fb92014-01-17 11:09:40 +01002617 while (count > 0) {
Willy Tarreauabf08d92014-01-14 11:31:27 +01002618 /* first check if we have some room after p+i */
2619 try = buf->data + buf->size - (buf->p + buf->i);
2620 /* otherwise continue between data and p-o */
2621 if (try <= 0) {
2622 try = buf->p - (buf->data + buf->o);
2623 if (try <= 0)
2624 break;
2625 }
2626 if (try > count)
2627 try = count;
2628
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02002629 ret = SSL_read(conn->xprt_ctx, bi_end(buf), try);
Emeric Brune1f38db2012-09-03 20:36:47 +02002630 if (conn->flags & CO_FL_ERROR) {
2631 /* CO_FL_ERROR may be set by ssl_sock_infocbk */
Emeric Brun644cde02012-12-14 11:21:13 +01002632 goto out_error;
Emeric Brune1f38db2012-09-03 20:36:47 +02002633 }
Emeric Brun46591952012-05-18 15:47:34 +02002634 if (ret > 0) {
2635 buf->i += ret;
2636 done += ret;
2637 if (ret < try)
2638 break;
2639 count -= ret;
Emeric Brun46591952012-05-18 15:47:34 +02002640 }
2641 else if (ret == 0) {
Emeric Brun644cde02012-12-14 11:21:13 +01002642 ret = SSL_get_error(conn->xprt_ctx, ret);
2643 if (ret != SSL_ERROR_ZERO_RETURN) {
Emeric Brun1c646862012-12-14 12:33:41 +01002644 /* error on protocol or underlying transport */
2645 if ((ret != SSL_ERROR_SYSCALL)
2646 || (errno && (errno != EAGAIN)))
2647 conn->flags |= CO_FL_ERROR;
2648
Emeric Brun644cde02012-12-14 11:21:13 +01002649 /* Clear openssl global errors stack */
2650 ERR_clear_error();
2651 }
Emeric Brun46591952012-05-18 15:47:34 +02002652 goto read0;
2653 }
2654 else {
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02002655 ret = SSL_get_error(conn->xprt_ctx, ret);
Emeric Brun46591952012-05-18 15:47:34 +02002656 if (ret == SSL_ERROR_WANT_WRITE) {
Emeric Brun8af8dd12012-11-08 17:56:20 +01002657 /* handshake is running, and it needs to enable write */
Emeric Brun46591952012-05-18 15:47:34 +02002658 conn->flags |= CO_FL_SSL_WAIT_HS;
Emeric Brun8af8dd12012-11-08 17:56:20 +01002659 __conn_sock_want_send(conn);
Emeric Brun46591952012-05-18 15:47:34 +02002660 break;
2661 }
2662 else if (ret == SSL_ERROR_WANT_READ) {
Emeric Brun282a76a2012-11-08 18:02:56 +01002663 if (SSL_renegotiate_pending(conn->xprt_ctx)) {
2664 /* handshake is running, and it may need to re-enable read */
2665 conn->flags |= CO_FL_SSL_WAIT_HS;
2666 __conn_sock_want_recv(conn);
2667 break;
2668 }
Emeric Brun46591952012-05-18 15:47:34 +02002669 /* we need to poll for retry a read later */
Willy Tarreaue1f50c42014-01-22 20:02:06 +01002670 fd_cant_recv(conn->t.sock.fd);
Emeric Brun46591952012-05-18 15:47:34 +02002671 break;
2672 }
2673 /* otherwise it's a real error */
2674 goto out_error;
2675 }
2676 }
2677 return done;
2678
2679 read0:
2680 conn_sock_read0(conn);
2681 return done;
2682 out_error:
Emeric Brun644cde02012-12-14 11:21:13 +01002683 /* Clear openssl global errors stack */
2684 ERR_clear_error();
2685
Emeric Brun46591952012-05-18 15:47:34 +02002686 conn->flags |= CO_FL_ERROR;
2687 return done;
2688}
2689
2690
2691/* Send all pending bytes from buffer <buf> to connection <conn>'s socket.
Willy Tarreau1049b1f2014-02-02 01:51:17 +01002692 * <flags> may contain some CO_SFL_* flags to hint the system about other
2693 * pending data for example, but this flag is ignored at the moment.
Emeric Brun46591952012-05-18 15:47:34 +02002694 * Only one call to send() is performed, unless the buffer wraps, in which case
2695 * a second call may be performed. The connection's flags are updated with
2696 * whatever special event is detected (error, empty). The caller is responsible
2697 * for taking care of those events and avoiding the call if inappropriate. The
2698 * function does not call the connection's polling update function, so the caller
2699 * is responsible for this.
2700 */
2701static int ssl_sock_from_buf(struct connection *conn, struct buffer *buf, int flags)
2702{
2703 int ret, try, done;
2704
2705 done = 0;
2706
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02002707 if (!conn->xprt_ctx)
Emeric Brun46591952012-05-18 15:47:34 +02002708 goto out_error;
2709
2710 if (conn->flags & CO_FL_HANDSHAKE)
2711 /* a handshake was requested */
2712 return 0;
2713
2714 /* send the largest possible block. For this we perform only one call
2715 * to send() unless the buffer wraps and we exactly fill the first hunk,
2716 * in which case we accept to do it once again.
2717 */
2718 while (buf->o) {
Kevin Hestercad82342013-05-30 15:12:41 -07002719 try = bo_contig_data(buf);
Willy Tarreaubfd59462013-02-21 07:46:09 +01002720
Willy Tarreau7bed9452014-02-02 02:00:24 +01002721 if (!(flags & CO_SFL_STREAMER) &&
Willy Tarreau518cedd2014-02-17 15:43:01 +01002722 !(conn->xprt_st & SSL_SOCK_SEND_UNLIMITED) &&
2723 global.tune.ssl_max_record && try > global.tune.ssl_max_record) {
Willy Tarreaubfd59462013-02-21 07:46:09 +01002724 try = global.tune.ssl_max_record;
Willy Tarreau518cedd2014-02-17 15:43:01 +01002725 }
2726 else {
2727 /* we need to keep the information about the fact that
2728 * we're not limiting the upcoming send(), because if it
2729 * fails, we'll have to retry with at least as many data.
2730 */
2731 conn->xprt_st |= SSL_SOCK_SEND_UNLIMITED;
2732 }
Willy Tarreaubfd59462013-02-21 07:46:09 +01002733
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02002734 ret = SSL_write(conn->xprt_ctx, bo_ptr(buf), try);
Willy Tarreau518cedd2014-02-17 15:43:01 +01002735
Emeric Brune1f38db2012-09-03 20:36:47 +02002736 if (conn->flags & CO_FL_ERROR) {
2737 /* CO_FL_ERROR may be set by ssl_sock_infocbk */
Emeric Brun644cde02012-12-14 11:21:13 +01002738 goto out_error;
Emeric Brune1f38db2012-09-03 20:36:47 +02002739 }
Emeric Brun46591952012-05-18 15:47:34 +02002740 if (ret > 0) {
Willy Tarreau518cedd2014-02-17 15:43:01 +01002741 conn->xprt_st &= ~SSL_SOCK_SEND_UNLIMITED;
2742
Emeric Brun46591952012-05-18 15:47:34 +02002743 buf->o -= ret;
2744 done += ret;
2745
Willy Tarreau5fb38032012-12-16 19:39:09 +01002746 if (likely(buffer_empty(buf)))
Emeric Brun46591952012-05-18 15:47:34 +02002747 /* optimize data alignment in the buffer */
2748 buf->p = buf->data;
2749
2750 /* if the system buffer is full, don't insist */
2751 if (ret < try)
2752 break;
2753 }
2754 else {
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02002755 ret = SSL_get_error(conn->xprt_ctx, ret);
Emeric Brun46591952012-05-18 15:47:34 +02002756 if (ret == SSL_ERROR_WANT_WRITE) {
Emeric Brun282a76a2012-11-08 18:02:56 +01002757 if (SSL_renegotiate_pending(conn->xprt_ctx)) {
2758 /* handshake is running, and it may need to re-enable write */
2759 conn->flags |= CO_FL_SSL_WAIT_HS;
2760 __conn_sock_want_send(conn);
2761 break;
2762 }
Emeric Brun46591952012-05-18 15:47:34 +02002763 /* we need to poll to retry a write later */
Willy Tarreaue1f50c42014-01-22 20:02:06 +01002764 fd_cant_send(conn->t.sock.fd);
Emeric Brun46591952012-05-18 15:47:34 +02002765 break;
2766 }
2767 else if (ret == SSL_ERROR_WANT_READ) {
Emeric Brun8af8dd12012-11-08 17:56:20 +01002768 /* handshake is running, and it needs to enable read */
Emeric Brun46591952012-05-18 15:47:34 +02002769 conn->flags |= CO_FL_SSL_WAIT_HS;
Emeric Brun8af8dd12012-11-08 17:56:20 +01002770 __conn_sock_want_recv(conn);
Emeric Brun46591952012-05-18 15:47:34 +02002771 break;
2772 }
2773 goto out_error;
2774 }
2775 }
2776 return done;
2777
2778 out_error:
Emeric Brun644cde02012-12-14 11:21:13 +01002779 /* Clear openssl global errors stack */
2780 ERR_clear_error();
2781
Emeric Brun46591952012-05-18 15:47:34 +02002782 conn->flags |= CO_FL_ERROR;
2783 return done;
2784}
2785
Emeric Brun46591952012-05-18 15:47:34 +02002786static void ssl_sock_close(struct connection *conn) {
2787
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02002788 if (conn->xprt_ctx) {
2789 SSL_free(conn->xprt_ctx);
2790 conn->xprt_ctx = NULL;
Willy Tarreau403edff2012-09-06 11:58:37 +02002791 sslconns--;
Emeric Brun46591952012-05-18 15:47:34 +02002792 }
Emeric Brun46591952012-05-18 15:47:34 +02002793}
2794
2795/* This function tries to perform a clean shutdown on an SSL connection, and in
2796 * any case, flags the connection as reusable if no handshake was in progress.
2797 */
2798static void ssl_sock_shutw(struct connection *conn, int clean)
2799{
2800 if (conn->flags & CO_FL_HANDSHAKE)
2801 return;
2802 /* no handshake was in progress, try a clean ssl shutdown */
Emeric Brun644cde02012-12-14 11:21:13 +01002803 if (clean && (SSL_shutdown(conn->xprt_ctx) <= 0)) {
2804 /* Clear openssl global errors stack */
2805 ERR_clear_error();
2806 }
Emeric Brun46591952012-05-18 15:47:34 +02002807
2808 /* force flag on ssl to keep session in cache regardless shutdown result */
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02002809 SSL_set_shutdown(conn->xprt_ctx, SSL_SENT_SHUTDOWN);
Emeric Brun46591952012-05-18 15:47:34 +02002810}
2811
Willy Tarreauffc3fcd2012-10-12 20:17:54 +02002812/* used for logging, may be changed for a sample fetch later */
2813const char *ssl_sock_get_cipher_name(struct connection *conn)
2814{
2815 if (!conn->xprt && !conn->xprt_ctx)
2816 return NULL;
2817 return SSL_get_cipher_name(conn->xprt_ctx);
2818}
2819
2820/* used for logging, may be changed for a sample fetch later */
2821const char *ssl_sock_get_proto_version(struct connection *conn)
2822{
2823 if (!conn->xprt && !conn->xprt_ctx)
2824 return NULL;
2825 return SSL_get_version(conn->xprt_ctx);
2826}
2827
Willy Tarreau8d598402012-10-22 17:58:39 +02002828/* Extract a serial from a cert, and copy it to a chunk.
2829 * Returns 1 if serial is found and copied, 0 if no serial found and
2830 * -1 if output is not large enough.
2831 */
2832static int
2833ssl_sock_get_serial(X509 *crt, struct chunk *out)
2834{
2835 ASN1_INTEGER *serial;
2836
2837 serial = X509_get_serialNumber(crt);
2838 if (!serial)
2839 return 0;
2840
2841 if (out->size < serial->length)
2842 return -1;
2843
2844 memcpy(out->str, serial->data, serial->length);
2845 out->len = serial->length;
2846 return 1;
2847}
2848
Emeric Brun43e79582014-10-29 19:03:26 +01002849/* Extract a cert to der, and copy it to a chunk.
2850 * Returns 1 if cert is found and copied, 0 on der convertion failure and
2851 * -1 if output is not large enough.
2852 */
2853static int
2854ssl_sock_crt2der(X509 *crt, struct chunk *out)
2855{
2856 int len;
2857 unsigned char *p = (unsigned char *)out->str;;
2858
2859 len =i2d_X509(crt, NULL);
2860 if (len <= 0)
2861 return 1;
2862
2863 if (out->size < len)
2864 return -1;
2865
2866 i2d_X509(crt,&p);
2867 out->len = len;
2868 return 1;
2869}
2870
Emeric Brunce5ad802012-10-22 14:11:22 +02002871
2872/* Copy Date in ASN1_UTCTIME format in struct chunk out.
2873 * Returns 1 if serial is found and copied, 0 if no valid time found
2874 * and -1 if output is not large enough.
2875 */
2876static int
2877ssl_sock_get_time(ASN1_TIME *tm, struct chunk *out)
2878{
2879 if (tm->type == V_ASN1_GENERALIZEDTIME) {
2880 ASN1_GENERALIZEDTIME *gentm = (ASN1_GENERALIZEDTIME *)tm;
2881
2882 if (gentm->length < 12)
2883 return 0;
2884 if (gentm->data[0] != 0x32 || gentm->data[1] != 0x30)
2885 return 0;
2886 if (out->size < gentm->length-2)
2887 return -1;
2888
2889 memcpy(out->str, gentm->data+2, gentm->length-2);
2890 out->len = gentm->length-2;
2891 return 1;
2892 }
2893 else if (tm->type == V_ASN1_UTCTIME) {
2894 ASN1_UTCTIME *utctm = (ASN1_UTCTIME *)tm;
2895
2896 if (utctm->length < 10)
2897 return 0;
2898 if (utctm->data[0] >= 0x35)
2899 return 0;
2900 if (out->size < utctm->length)
2901 return -1;
2902
2903 memcpy(out->str, utctm->data, utctm->length);
2904 out->len = utctm->length;
2905 return 1;
2906 }
2907
2908 return 0;
2909}
2910
Emeric Brun87855892012-10-17 17:39:35 +02002911/* Extract an entry from a X509_NAME and copy its value to an output chunk.
2912 * Returns 1 if entry found, 0 if entry not found, or -1 if output not large enough.
2913 */
2914static int
2915ssl_sock_get_dn_entry(X509_NAME *a, const struct chunk *entry, int pos, struct chunk *out)
2916{
2917 X509_NAME_ENTRY *ne;
2918 int i, j, n;
2919 int cur = 0;
2920 const char *s;
2921 char tmp[128];
2922
2923 out->len = 0;
2924 for (i = 0; i < sk_X509_NAME_ENTRY_num(a->entries); i++) {
2925 if (pos < 0)
2926 j = (sk_X509_NAME_ENTRY_num(a->entries)-1) - i;
2927 else
2928 j = i;
2929
2930 ne = sk_X509_NAME_ENTRY_value(a->entries, j);
2931 n = OBJ_obj2nid(ne->object);
2932 if ((n == NID_undef) || ((s = OBJ_nid2sn(n)) == NULL)) {
2933 i2t_ASN1_OBJECT(tmp, sizeof(tmp), ne->object);
2934 s = tmp;
2935 }
2936
2937 if (chunk_strcasecmp(entry, s) != 0)
2938 continue;
2939
2940 if (pos < 0)
2941 cur--;
2942 else
2943 cur++;
2944
2945 if (cur != pos)
2946 continue;
2947
2948 if (ne->value->length > out->size)
2949 return -1;
2950
2951 memcpy(out->str, ne->value->data, ne->value->length);
2952 out->len = ne->value->length;
2953 return 1;
2954 }
2955
2956 return 0;
2957
2958}
2959
2960/* Extract and format full DN from a X509_NAME and copy result into a chunk
2961 * Returns 1 if dn entries exits, 0 if no dn entry found or -1 if output is not large enough.
2962 */
2963static int
2964ssl_sock_get_dn_oneline(X509_NAME *a, struct chunk *out)
2965{
2966 X509_NAME_ENTRY *ne;
2967 int i, n, ln;
2968 int l = 0;
2969 const char *s;
2970 char *p;
2971 char tmp[128];
2972
2973 out->len = 0;
2974 p = out->str;
2975 for (i = 0; i < sk_X509_NAME_ENTRY_num(a->entries); i++) {
2976 ne = sk_X509_NAME_ENTRY_value(a->entries, i);
2977 n = OBJ_obj2nid(ne->object);
2978 if ((n == NID_undef) || ((s = OBJ_nid2sn(n)) == NULL)) {
2979 i2t_ASN1_OBJECT(tmp, sizeof(tmp), ne->object);
2980 s = tmp;
2981 }
2982 ln = strlen(s);
2983
2984 l += 1 + ln + 1 + ne->value->length;
2985 if (l > out->size)
2986 return -1;
2987 out->len = l;
2988
2989 *(p++)='/';
2990 memcpy(p, s, ln);
2991 p += ln;
2992 *(p++)='=';
2993 memcpy(p, ne->value->data, ne->value->length);
2994 p += ne->value->length;
2995 }
2996
2997 if (!out->len)
2998 return 0;
2999
3000 return 1;
3001}
3002
David Safb76832014-05-08 23:42:08 -04003003char *ssl_sock_get_version(struct connection *conn)
3004{
3005 if (!ssl_sock_is_ssl(conn))
3006 return NULL;
3007
3008 return (char *)SSL_get_version(conn->xprt_ctx);
3009}
3010
Emeric Brun0abf8362014-06-24 18:26:41 +02003011/* Extract peer certificate's common name into the chunk dest
3012 * Returns
3013 * the len of the extracted common name
3014 * or 0 if no CN found in DN
3015 * or -1 on error case (i.e. no peer certificate)
3016 */
3017int ssl_sock_get_remote_common_name(struct connection *conn, struct chunk *dest)
David Safb76832014-05-08 23:42:08 -04003018{
3019 X509 *crt = NULL;
3020 X509_NAME *name;
David Safb76832014-05-08 23:42:08 -04003021 const char find_cn[] = "CN";
3022 const struct chunk find_cn_chunk = {
3023 .str = (char *)&find_cn,
3024 .len = sizeof(find_cn)-1
3025 };
Emeric Brun0abf8362014-06-24 18:26:41 +02003026 int result = -1;
David Safb76832014-05-08 23:42:08 -04003027
3028 if (!ssl_sock_is_ssl(conn))
Emeric Brun0abf8362014-06-24 18:26:41 +02003029 goto out;
David Safb76832014-05-08 23:42:08 -04003030
3031 /* SSL_get_peer_certificate, it increase X509 * ref count */
3032 crt = SSL_get_peer_certificate(conn->xprt_ctx);
3033 if (!crt)
3034 goto out;
3035
3036 name = X509_get_subject_name(crt);
3037 if (!name)
3038 goto out;
David Safb76832014-05-08 23:42:08 -04003039
Emeric Brun0abf8362014-06-24 18:26:41 +02003040 result = ssl_sock_get_dn_entry(name, &find_cn_chunk, 1, dest);
3041out:
David Safb76832014-05-08 23:42:08 -04003042 if (crt)
3043 X509_free(crt);
3044
3045 return result;
3046}
3047
Dave McCowan328fb582014-07-30 10:39:13 -04003048/* returns 1 if client passed a certificate for this session, 0 if not */
3049int ssl_sock_get_cert_used_sess(struct connection *conn)
3050{
3051 X509 *crt = NULL;
3052
3053 if (!ssl_sock_is_ssl(conn))
3054 return 0;
3055
3056 /* SSL_get_peer_certificate, it increase X509 * ref count */
3057 crt = SSL_get_peer_certificate(conn->xprt_ctx);
3058 if (!crt)
3059 return 0;
3060
3061 X509_free(crt);
3062 return 1;
3063}
3064
3065/* returns 1 if client passed a certificate for this connection, 0 if not */
3066int ssl_sock_get_cert_used_conn(struct connection *conn)
David Safb76832014-05-08 23:42:08 -04003067{
3068 if (!ssl_sock_is_ssl(conn))
3069 return 0;
3070
3071 return SSL_SOCK_ST_FL_VERIFY_DONE & conn->xprt_st ? 1 : 0;
3072}
3073
3074/* returns result from SSL verify */
3075unsigned int ssl_sock_get_verify_result(struct connection *conn)
3076{
3077 if (!ssl_sock_is_ssl(conn))
3078 return (unsigned int)X509_V_ERR_APPLICATION_VERIFICATION;
3079
3080 return (unsigned int)SSL_get_verify_result(conn->xprt_ctx);
3081}
3082
Willy Tarreau7875d092012-09-10 08:20:03 +02003083/***** Below are some sample fetching functions for ACL/patterns *****/
3084
Emeric Brune64aef12012-09-21 13:15:06 +02003085/* boolean, returns true if client cert was present */
3086static int
Willy Tarreau87b09662015-04-03 00:22:06 +02003087smp_fetch_ssl_fc_has_crt(struct proxy *px, struct stream *l4, void *l7, unsigned int opt,
Thierry FOURNIERf41a8092014-12-07 18:37:57 +01003088 const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brune64aef12012-09-21 13:15:06 +02003089{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003090 struct connection *conn;
Willy Tarreau9ad7bd42015-04-03 19:19:59 +02003091 struct session *sess = l4->sess;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003092
Willy Tarreau9ad7bd42015-04-03 19:19:59 +02003093 conn = objt_conn(sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003094 if (!conn || conn->xprt != &ssl_sock)
Emeric Brune64aef12012-09-21 13:15:06 +02003095 return 0;
3096
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003097 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brune64aef12012-09-21 13:15:06 +02003098 smp->flags |= SMP_F_MAY_CHANGE;
3099 return 0;
3100 }
3101
3102 smp->flags = 0;
3103 smp->type = SMP_T_BOOL;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003104 smp->data.uint = SSL_SOCK_ST_FL_VERIFY_DONE & conn->xprt_st ? 1 : 0;
Emeric Brune64aef12012-09-21 13:15:06 +02003105
3106 return 1;
3107}
3108
Emeric Brun43e79582014-10-29 19:03:26 +01003109/* binary, returns a certificate in a binary chunk (der/raw).
3110 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
3111 * should be use.
3112 */
3113static int
Willy Tarreau87b09662015-04-03 00:22:06 +02003114smp_fetch_ssl_x_der(struct proxy *px, struct stream *l4, void *l7, unsigned int opt,
Thierry FOURNIERf41a8092014-12-07 18:37:57 +01003115 const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun43e79582014-10-29 19:03:26 +01003116{
3117 int cert_peer = (kw[4] == 'c') ? 1 : 0;
3118 X509 *crt = NULL;
3119 int ret = 0;
3120 struct chunk *smp_trash;
Willy Tarreau9ad7bd42015-04-03 19:19:59 +02003121 struct session *sess = strm_sess(l4);
Emeric Brun43e79582014-10-29 19:03:26 +01003122 struct connection *conn;
3123
Willy Tarreau9ad7bd42015-04-03 19:19:59 +02003124 conn = objt_conn(sess->origin);
Emeric Brun43e79582014-10-29 19:03:26 +01003125 if (!conn || conn->xprt != &ssl_sock)
3126 return 0;
3127
3128 if (!(conn->flags & CO_FL_CONNECTED)) {
3129 smp->flags |= SMP_F_MAY_CHANGE;
3130 return 0;
3131 }
3132
3133 if (cert_peer)
3134 crt = SSL_get_peer_certificate(conn->xprt_ctx);
3135 else
3136 crt = SSL_get_certificate(conn->xprt_ctx);
3137
3138 if (!crt)
3139 goto out;
3140
3141 smp_trash = get_trash_chunk();
3142 if (ssl_sock_crt2der(crt, smp_trash) <= 0)
3143 goto out;
3144
3145 smp->data.str = *smp_trash;
3146 smp->type = SMP_T_BIN;
3147 ret = 1;
3148out:
3149 /* SSL_get_peer_certificate, it increase X509 * ref count */
3150 if (cert_peer && crt)
3151 X509_free(crt);
3152 return ret;
3153}
3154
Emeric Brunba841a12014-04-30 17:05:08 +02003155/* binary, returns serial of certificate in a binary chunk.
3156 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
3157 * should be use.
3158 */
Willy Tarreau8d598402012-10-22 17:58:39 +02003159static int
Willy Tarreau87b09662015-04-03 00:22:06 +02003160smp_fetch_ssl_x_serial(struct proxy *px, struct stream *l4, void *l7, unsigned int opt,
Thierry FOURNIERf41a8092014-12-07 18:37:57 +01003161 const struct arg *args, struct sample *smp, const char *kw, void *private)
Willy Tarreau8d598402012-10-22 17:58:39 +02003162{
Emeric Brunba841a12014-04-30 17:05:08 +02003163 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Willy Tarreau8d598402012-10-22 17:58:39 +02003164 X509 *crt = NULL;
3165 int ret = 0;
3166 struct chunk *smp_trash;
Willy Tarreau9ad7bd42015-04-03 19:19:59 +02003167 struct session *sess = strm_sess(l4);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003168 struct connection *conn;
3169
Willy Tarreau9ad7bd42015-04-03 19:19:59 +02003170 conn = objt_conn(sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003171 if (!conn || conn->xprt != &ssl_sock)
Willy Tarreau8d598402012-10-22 17:58:39 +02003172 return 0;
3173
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003174 if (!(conn->flags & CO_FL_CONNECTED)) {
Willy Tarreau8d598402012-10-22 17:58:39 +02003175 smp->flags |= SMP_F_MAY_CHANGE;
3176 return 0;
3177 }
3178
Emeric Brunba841a12014-04-30 17:05:08 +02003179 if (cert_peer)
3180 crt = SSL_get_peer_certificate(conn->xprt_ctx);
3181 else
3182 crt = SSL_get_certificate(conn->xprt_ctx);
3183
Willy Tarreau8d598402012-10-22 17:58:39 +02003184 if (!crt)
3185 goto out;
3186
Willy Tarreau47ca5452012-12-23 20:22:19 +01003187 smp_trash = get_trash_chunk();
Willy Tarreau8d598402012-10-22 17:58:39 +02003188 if (ssl_sock_get_serial(crt, smp_trash) <= 0)
3189 goto out;
3190
3191 smp->data.str = *smp_trash;
3192 smp->type = SMP_T_BIN;
3193 ret = 1;
3194out:
Emeric Brunba841a12014-04-30 17:05:08 +02003195 /* SSL_get_peer_certificate, it increase X509 * ref count */
3196 if (cert_peer && crt)
Willy Tarreau8d598402012-10-22 17:58:39 +02003197 X509_free(crt);
3198 return ret;
3199}
Emeric Brune64aef12012-09-21 13:15:06 +02003200
Emeric Brunba841a12014-04-30 17:05:08 +02003201/* binary, returns the client certificate's SHA-1 fingerprint (SHA-1 hash of DER-encoded certificate) in a binary chunk.
3202 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
3203 * should be use.
3204 */
James Votha051b4a2013-05-14 20:37:59 +02003205static int
Willy Tarreau87b09662015-04-03 00:22:06 +02003206smp_fetch_ssl_x_sha1(struct proxy *px, struct stream *l4, void *l7, unsigned int opt,
Thierry FOURNIERf41a8092014-12-07 18:37:57 +01003207 const struct arg *args, struct sample *smp, const char *kw, void *private)
James Votha051b4a2013-05-14 20:37:59 +02003208{
Emeric Brunba841a12014-04-30 17:05:08 +02003209 int cert_peer = (kw[4] == 'c') ? 1 : 0;
James Votha051b4a2013-05-14 20:37:59 +02003210 X509 *crt = NULL;
3211 const EVP_MD *digest;
3212 int ret = 0;
3213 struct chunk *smp_trash;
Willy Tarreau9ad7bd42015-04-03 19:19:59 +02003214 struct session *sess = strm_sess(l4);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003215 struct connection *conn;
James Votha051b4a2013-05-14 20:37:59 +02003216
Willy Tarreau9ad7bd42015-04-03 19:19:59 +02003217 conn = objt_conn(sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003218 if (!conn || conn->xprt != &ssl_sock)
3219 return 0;
3220
3221 if (!(conn->flags & CO_FL_CONNECTED)) {
James Votha051b4a2013-05-14 20:37:59 +02003222 smp->flags |= SMP_F_MAY_CHANGE;
3223 return 0;
3224 }
3225
Emeric Brunba841a12014-04-30 17:05:08 +02003226 if (cert_peer)
3227 crt = SSL_get_peer_certificate(conn->xprt_ctx);
3228 else
3229 crt = SSL_get_certificate(conn->xprt_ctx);
James Votha051b4a2013-05-14 20:37:59 +02003230 if (!crt)
3231 goto out;
3232
3233 smp_trash = get_trash_chunk();
3234 digest = EVP_sha1();
3235 X509_digest(crt, digest, (unsigned char *)smp_trash->str, (unsigned int *)&smp_trash->len);
3236
3237 smp->data.str = *smp_trash;
3238 smp->type = SMP_T_BIN;
3239 ret = 1;
3240out:
Emeric Brunba841a12014-04-30 17:05:08 +02003241 /* SSL_get_peer_certificate, it increase X509 * ref count */
3242 if (cert_peer && crt)
James Votha051b4a2013-05-14 20:37:59 +02003243 X509_free(crt);
3244 return ret;
3245}
3246
Emeric Brunba841a12014-04-30 17:05:08 +02003247/* string, returns certificate's notafter date in ASN1_UTCTIME format.
3248 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
3249 * should be use.
3250 */
Emeric Brunce5ad802012-10-22 14:11:22 +02003251static int
Willy Tarreau87b09662015-04-03 00:22:06 +02003252smp_fetch_ssl_x_notafter(struct proxy *px, struct stream *l4, void *l7, unsigned int opt,
Thierry FOURNIERf41a8092014-12-07 18:37:57 +01003253 const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brunce5ad802012-10-22 14:11:22 +02003254{
Emeric Brunba841a12014-04-30 17:05:08 +02003255 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brunce5ad802012-10-22 14:11:22 +02003256 X509 *crt = NULL;
3257 int ret = 0;
3258 struct chunk *smp_trash;
Willy Tarreau9ad7bd42015-04-03 19:19:59 +02003259 struct session *sess = strm_sess(l4);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003260 struct connection *conn;
Emeric Brunce5ad802012-10-22 14:11:22 +02003261
Willy Tarreau9ad7bd42015-04-03 19:19:59 +02003262 conn = objt_conn(sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003263 if (!conn || conn->xprt != &ssl_sock)
3264 return 0;
3265
3266 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunce5ad802012-10-22 14:11:22 +02003267 smp->flags |= SMP_F_MAY_CHANGE;
3268 return 0;
3269 }
3270
Emeric Brunba841a12014-04-30 17:05:08 +02003271 if (cert_peer)
3272 crt = SSL_get_peer_certificate(conn->xprt_ctx);
3273 else
3274 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brunce5ad802012-10-22 14:11:22 +02003275 if (!crt)
3276 goto out;
3277
Willy Tarreau47ca5452012-12-23 20:22:19 +01003278 smp_trash = get_trash_chunk();
Emeric Brunce5ad802012-10-22 14:11:22 +02003279 if (ssl_sock_get_time(X509_get_notAfter(crt), smp_trash) <= 0)
3280 goto out;
3281
3282 smp->data.str = *smp_trash;
3283 smp->type = SMP_T_STR;
3284 ret = 1;
3285out:
Emeric Brunba841a12014-04-30 17:05:08 +02003286 /* SSL_get_peer_certificate, it increase X509 * ref count */
3287 if (cert_peer && crt)
Emeric Brunce5ad802012-10-22 14:11:22 +02003288 X509_free(crt);
3289 return ret;
3290}
3291
Emeric Brunba841a12014-04-30 17:05:08 +02003292/* string, returns a string of a formatted full dn \C=..\O=..\OU=.. \CN=.. of certificate's issuer
3293 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
3294 * should be use.
3295 */
Emeric Brun87855892012-10-17 17:39:35 +02003296static int
Willy Tarreau87b09662015-04-03 00:22:06 +02003297smp_fetch_ssl_x_i_dn(struct proxy *px, struct stream *l4, void *l7, unsigned int opt,
Thierry FOURNIERf41a8092014-12-07 18:37:57 +01003298 const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun87855892012-10-17 17:39:35 +02003299{
Emeric Brunba841a12014-04-30 17:05:08 +02003300 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brun87855892012-10-17 17:39:35 +02003301 X509 *crt = NULL;
3302 X509_NAME *name;
3303 int ret = 0;
3304 struct chunk *smp_trash;
Willy Tarreau9ad7bd42015-04-03 19:19:59 +02003305 struct session *sess = strm_sess(l4);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003306 struct connection *conn;
Emeric Brun87855892012-10-17 17:39:35 +02003307
Willy Tarreau9ad7bd42015-04-03 19:19:59 +02003308 conn = objt_conn(sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003309 if (!conn || conn->xprt != &ssl_sock)
3310 return 0;
3311
3312 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun87855892012-10-17 17:39:35 +02003313 smp->flags |= SMP_F_MAY_CHANGE;
3314 return 0;
3315 }
3316
Emeric Brunba841a12014-04-30 17:05:08 +02003317 if (cert_peer)
3318 crt = SSL_get_peer_certificate(conn->xprt_ctx);
3319 else
3320 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brun87855892012-10-17 17:39:35 +02003321 if (!crt)
3322 goto out;
3323
3324 name = X509_get_issuer_name(crt);
3325 if (!name)
3326 goto out;
3327
Willy Tarreau47ca5452012-12-23 20:22:19 +01003328 smp_trash = get_trash_chunk();
Emeric Brun87855892012-10-17 17:39:35 +02003329 if (args && args[0].type == ARGT_STR) {
3330 int pos = 1;
3331
3332 if (args[1].type == ARGT_SINT)
3333 pos = args[1].data.sint;
3334 else if (args[1].type == ARGT_UINT)
3335 pos =(int)args[1].data.uint;
3336
3337 if (ssl_sock_get_dn_entry(name, &args[0].data.str, pos, smp_trash) <= 0)
3338 goto out;
3339 }
3340 else if (ssl_sock_get_dn_oneline(name, smp_trash) <= 0)
3341 goto out;
3342
3343 smp->type = SMP_T_STR;
3344 smp->data.str = *smp_trash;
3345 ret = 1;
3346out:
Emeric Brunba841a12014-04-30 17:05:08 +02003347 /* SSL_get_peer_certificate, it increase X509 * ref count */
3348 if (cert_peer && crt)
Emeric Brun87855892012-10-17 17:39:35 +02003349 X509_free(crt);
3350 return ret;
3351}
3352
Emeric Brunba841a12014-04-30 17:05:08 +02003353/* string, returns notbefore date in ASN1_UTCTIME format.
3354 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
3355 * should be use.
3356 */
Emeric Brunce5ad802012-10-22 14:11:22 +02003357static int
Willy Tarreau87b09662015-04-03 00:22:06 +02003358smp_fetch_ssl_x_notbefore(struct proxy *px, struct stream *l4, void *l7, unsigned int opt,
Thierry FOURNIERf41a8092014-12-07 18:37:57 +01003359 const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brunce5ad802012-10-22 14:11:22 +02003360{
Emeric Brunba841a12014-04-30 17:05:08 +02003361 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brunce5ad802012-10-22 14:11:22 +02003362 X509 *crt = NULL;
3363 int ret = 0;
3364 struct chunk *smp_trash;
Willy Tarreau9ad7bd42015-04-03 19:19:59 +02003365 struct session *sess = strm_sess(l4);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003366 struct connection *conn;
3367
Willy Tarreau9ad7bd42015-04-03 19:19:59 +02003368 conn = objt_conn(sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003369 if (!conn || conn->xprt != &ssl_sock)
Emeric Brunce5ad802012-10-22 14:11:22 +02003370 return 0;
3371
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003372 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunce5ad802012-10-22 14:11:22 +02003373 smp->flags |= SMP_F_MAY_CHANGE;
3374 return 0;
3375 }
3376
Emeric Brunba841a12014-04-30 17:05:08 +02003377 if (cert_peer)
3378 crt = SSL_get_peer_certificate(conn->xprt_ctx);
3379 else
3380 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brunce5ad802012-10-22 14:11:22 +02003381 if (!crt)
3382 goto out;
3383
Willy Tarreau47ca5452012-12-23 20:22:19 +01003384 smp_trash = get_trash_chunk();
Emeric Brunce5ad802012-10-22 14:11:22 +02003385 if (ssl_sock_get_time(X509_get_notBefore(crt), smp_trash) <= 0)
3386 goto out;
3387
3388 smp->data.str = *smp_trash;
3389 smp->type = SMP_T_STR;
3390 ret = 1;
3391out:
Emeric Brunba841a12014-04-30 17:05:08 +02003392 /* SSL_get_peer_certificate, it increase X509 * ref count */
3393 if (cert_peer && crt)
Emeric Brunce5ad802012-10-22 14:11:22 +02003394 X509_free(crt);
3395 return ret;
3396}
3397
Emeric Brunba841a12014-04-30 17:05:08 +02003398/* string, returns a string of a formatted full dn \C=..\O=..\OU=.. \CN=.. of certificate's subject
3399 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
3400 * should be use.
3401 */
Emeric Brun87855892012-10-17 17:39:35 +02003402static int
Willy Tarreau87b09662015-04-03 00:22:06 +02003403smp_fetch_ssl_x_s_dn(struct proxy *px, struct stream *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 Brun87855892012-10-17 17:39:35 +02003405{
Emeric Brunba841a12014-04-30 17:05:08 +02003406 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brun87855892012-10-17 17:39:35 +02003407 X509 *crt = NULL;
3408 X509_NAME *name;
3409 int ret = 0;
3410 struct chunk *smp_trash;
Willy Tarreau9ad7bd42015-04-03 19:19:59 +02003411 struct session *sess = strm_sess(l4);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003412 struct connection *conn;
Emeric Brun87855892012-10-17 17:39:35 +02003413
Willy Tarreau9ad7bd42015-04-03 19:19:59 +02003414 conn = objt_conn(sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003415 if (!conn || conn->xprt != &ssl_sock)
3416 return 0;
3417
3418 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun87855892012-10-17 17:39:35 +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 Brun87855892012-10-17 17:39:35 +02003427 if (!crt)
3428 goto out;
3429
3430 name = X509_get_subject_name(crt);
3431 if (!name)
3432 goto out;
3433
Willy Tarreau47ca5452012-12-23 20:22:19 +01003434 smp_trash = get_trash_chunk();
Emeric Brun87855892012-10-17 17:39:35 +02003435 if (args && args[0].type == ARGT_STR) {
3436 int pos = 1;
3437
3438 if (args[1].type == ARGT_SINT)
3439 pos = args[1].data.sint;
3440 else if (args[1].type == ARGT_UINT)
3441 pos =(int)args[1].data.uint;
3442
3443 if (ssl_sock_get_dn_entry(name, &args[0].data.str, pos, smp_trash) <= 0)
3444 goto out;
3445 }
3446 else if (ssl_sock_get_dn_oneline(name, smp_trash) <= 0)
3447 goto out;
3448
3449 smp->type = SMP_T_STR;
3450 smp->data.str = *smp_trash;
3451 ret = 1;
3452out:
Emeric Brunba841a12014-04-30 17:05:08 +02003453 /* SSL_get_peer_certificate, it increase X509 * ref count */
3454 if (cert_peer && crt)
Emeric Brun87855892012-10-17 17:39:35 +02003455 X509_free(crt);
3456 return ret;
3457}
Emeric Brun9143d372012-12-20 15:44:16 +01003458
3459/* integer, returns true if current session use a client certificate */
3460static int
Willy Tarreau87b09662015-04-03 00:22:06 +02003461smp_fetch_ssl_c_used(struct proxy *px, struct stream *l4, void *l7, unsigned int opt,
Thierry FOURNIERf41a8092014-12-07 18:37:57 +01003462 const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun9143d372012-12-20 15:44:16 +01003463{
3464 X509 *crt;
Willy Tarreau9ad7bd42015-04-03 19:19:59 +02003465 struct session *sess = strm_sess(l4);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003466 struct connection *conn;
Emeric Brun9143d372012-12-20 15:44:16 +01003467
Willy Tarreau9ad7bd42015-04-03 19:19:59 +02003468 conn = objt_conn(sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003469 if (!conn || conn->xprt != &ssl_sock)
3470 return 0;
3471
3472 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun9143d372012-12-20 15:44:16 +01003473 smp->flags |= SMP_F_MAY_CHANGE;
3474 return 0;
3475 }
3476
3477 /* SSL_get_peer_certificate returns a ptr on allocated X509 struct */
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003478 crt = SSL_get_peer_certificate(conn->xprt_ctx);
Emeric Brun9143d372012-12-20 15:44:16 +01003479 if (crt) {
3480 X509_free(crt);
3481 }
3482
3483 smp->type = SMP_T_BOOL;
3484 smp->data.uint = (crt != NULL);
3485 return 1;
3486}
3487
Emeric Brunba841a12014-04-30 17:05:08 +02003488/* integer, returns the certificate version
3489 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
3490 * should be use.
3491 */
Emeric Bruna7359fd2012-10-17 15:03:11 +02003492static int
Willy Tarreau87b09662015-04-03 00:22:06 +02003493smp_fetch_ssl_x_version(struct proxy *px, struct stream *l4, void *l7, unsigned int opt,
Thierry FOURNIERf41a8092014-12-07 18:37:57 +01003494 const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Bruna7359fd2012-10-17 15:03:11 +02003495{
Emeric Brunba841a12014-04-30 17:05:08 +02003496 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Bruna7359fd2012-10-17 15:03:11 +02003497 X509 *crt;
Willy Tarreau9ad7bd42015-04-03 19:19:59 +02003498 struct session *sess = strm_sess(l4);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003499 struct connection *conn;
3500
Willy Tarreau9ad7bd42015-04-03 19:19:59 +02003501 conn = objt_conn(sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003502 if (!conn || conn->xprt != &ssl_sock)
Emeric Bruna7359fd2012-10-17 15:03:11 +02003503 return 0;
3504
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003505 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Bruna7359fd2012-10-17 15:03:11 +02003506 smp->flags |= SMP_F_MAY_CHANGE;
3507 return 0;
3508 }
3509
Emeric Brunba841a12014-04-30 17:05:08 +02003510 if (cert_peer)
3511 crt = SSL_get_peer_certificate(conn->xprt_ctx);
3512 else
3513 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Bruna7359fd2012-10-17 15:03:11 +02003514 if (!crt)
3515 return 0;
3516
3517 smp->data.uint = (unsigned int)(1 + X509_get_version(crt));
Emeric Brunba841a12014-04-30 17:05:08 +02003518 /* SSL_get_peer_certificate increase X509 * ref count */
3519 if (cert_peer)
3520 X509_free(crt);
Emeric Bruna7359fd2012-10-17 15:03:11 +02003521 smp->type = SMP_T_UINT;
3522
3523 return 1;
3524}
3525
Emeric Brunba841a12014-04-30 17:05:08 +02003526/* string, returns the certificate's signature algorithm.
3527 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
3528 * should be use.
3529 */
Emeric Brun7f56e742012-10-19 18:15:40 +02003530static int
Willy Tarreau87b09662015-04-03 00:22:06 +02003531smp_fetch_ssl_x_sig_alg(struct proxy *px, struct stream *l4, void *l7, unsigned int opt,
Thierry FOURNIERf41a8092014-12-07 18:37:57 +01003532 const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun7f56e742012-10-19 18:15:40 +02003533{
Emeric Brunba841a12014-04-30 17:05:08 +02003534 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brun7f56e742012-10-19 18:15:40 +02003535 X509 *crt;
3536 int nid;
Willy Tarreau9ad7bd42015-04-03 19:19:59 +02003537 struct session *sess = strm_sess(l4);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003538 struct connection *conn;
Emeric Brun7f56e742012-10-19 18:15:40 +02003539
Willy Tarreau9ad7bd42015-04-03 19:19:59 +02003540 conn = objt_conn(sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003541 if (!conn || conn->xprt != &ssl_sock)
3542 return 0;
3543
3544 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun7f56e742012-10-19 18:15:40 +02003545 smp->flags |= SMP_F_MAY_CHANGE;
3546 return 0;
3547 }
3548
Emeric Brunba841a12014-04-30 17:05:08 +02003549 if (cert_peer)
3550 crt = SSL_get_peer_certificate(conn->xprt_ctx);
3551 else
3552 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brun7f56e742012-10-19 18:15:40 +02003553 if (!crt)
3554 return 0;
3555
3556 nid = OBJ_obj2nid((ASN1_OBJECT *)(crt->cert_info->signature->algorithm));
3557
3558 smp->data.str.str = (char *)OBJ_nid2sn(nid);
Emeric Brun9bf3ba22013-10-07 14:31:44 +02003559 if (!smp->data.str.str) {
Emeric Brunba841a12014-04-30 17:05:08 +02003560 /* SSL_get_peer_certificate increase X509 * ref count */
3561 if (cert_peer)
3562 X509_free(crt);
Emeric Brun7f56e742012-10-19 18:15:40 +02003563 return 0;
Emeric Brun9bf3ba22013-10-07 14:31:44 +02003564 }
Emeric Brun7f56e742012-10-19 18:15:40 +02003565
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01003566 smp->type = SMP_T_STR;
3567 smp->flags |= SMP_F_CONST;
Emeric Brun7f56e742012-10-19 18:15:40 +02003568 smp->data.str.len = strlen(smp->data.str.str);
Emeric Brunba841a12014-04-30 17:05:08 +02003569 /* SSL_get_peer_certificate increase X509 * ref count */
3570 if (cert_peer)
3571 X509_free(crt);
Emeric Brun7f56e742012-10-19 18:15:40 +02003572
3573 return 1;
3574}
3575
Emeric Brunba841a12014-04-30 17:05:08 +02003576/* string, returns the certificate's key algorithm.
3577 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
3578 * should be use.
3579 */
Emeric Brun521a0112012-10-22 12:22:55 +02003580static int
Willy Tarreau87b09662015-04-03 00:22:06 +02003581smp_fetch_ssl_x_key_alg(struct proxy *px, struct stream *l4, void *l7, unsigned int opt,
Thierry FOURNIERf41a8092014-12-07 18:37:57 +01003582 const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun521a0112012-10-22 12:22:55 +02003583{
Emeric Brunba841a12014-04-30 17:05:08 +02003584 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brun521a0112012-10-22 12:22:55 +02003585 X509 *crt;
3586 int nid;
Willy Tarreau9ad7bd42015-04-03 19:19:59 +02003587 struct session *sess = strm_sess(l4);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003588 struct connection *conn;
Emeric Brun521a0112012-10-22 12:22:55 +02003589
Willy Tarreau9ad7bd42015-04-03 19:19:59 +02003590 conn = objt_conn(sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003591 if (!conn || conn->xprt != &ssl_sock)
3592 return 0;
3593
3594 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun521a0112012-10-22 12:22:55 +02003595 smp->flags |= SMP_F_MAY_CHANGE;
3596 return 0;
3597 }
3598
Emeric Brunba841a12014-04-30 17:05:08 +02003599 if (cert_peer)
3600 crt = SSL_get_peer_certificate(conn->xprt_ctx);
3601 else
3602 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brun521a0112012-10-22 12:22:55 +02003603 if (!crt)
3604 return 0;
3605
3606 nid = OBJ_obj2nid((ASN1_OBJECT *)(crt->cert_info->key->algor->algorithm));
3607
3608 smp->data.str.str = (char *)OBJ_nid2sn(nid);
Emeric Brun9bf3ba22013-10-07 14:31:44 +02003609 if (!smp->data.str.str) {
Emeric Brunba841a12014-04-30 17:05:08 +02003610 /* SSL_get_peer_certificate increase X509 * ref count */
3611 if (cert_peer)
3612 X509_free(crt);
Emeric Brun521a0112012-10-22 12:22:55 +02003613 return 0;
Emeric Brun9bf3ba22013-10-07 14:31:44 +02003614 }
Emeric Brun521a0112012-10-22 12:22:55 +02003615
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01003616 smp->type = SMP_T_STR;
3617 smp->flags |= SMP_F_CONST;
Emeric Brun521a0112012-10-22 12:22:55 +02003618 smp->data.str.len = strlen(smp->data.str.str);
Emeric Brunba841a12014-04-30 17:05:08 +02003619 if (cert_peer)
3620 X509_free(crt);
Emeric Brun521a0112012-10-22 12:22:55 +02003621
3622 return 1;
3623}
3624
Emeric Brun645ae792014-04-30 14:21:06 +02003625/* boolean, returns true if front conn. transport layer is SSL.
3626 * This function is also usable on backend conn if the fetch keyword 5th
3627 * char is 'b'.
3628 */
Willy Tarreau7875d092012-09-10 08:20:03 +02003629static int
Willy Tarreau87b09662015-04-03 00:22:06 +02003630smp_fetch_ssl_fc(struct proxy *px, struct stream *l4, void *l7, unsigned int opt,
Thierry FOURNIERf41a8092014-12-07 18:37:57 +01003631 const struct arg *args, struct sample *smp, const char *kw, void *private)
Willy Tarreau7875d092012-09-10 08:20:03 +02003632{
Emeric Brun645ae792014-04-30 14:21:06 +02003633 int back_conn = (kw[4] == 'b') ? 1 : 0;
3634 struct connection *conn = objt_conn(l4->si[back_conn].end);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003635
Willy Tarreau7875d092012-09-10 08:20:03 +02003636 smp->type = SMP_T_BOOL;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003637 smp->data.uint = (conn && conn->xprt == &ssl_sock);
Willy Tarreau7875d092012-09-10 08:20:03 +02003638 return 1;
3639}
3640
Emeric Brun2525b6b2012-10-18 15:59:43 +02003641/* boolean, returns true if client present a SNI */
Willy Tarreau7875d092012-09-10 08:20:03 +02003642static int
Willy Tarreau87b09662015-04-03 00:22:06 +02003643smp_fetch_ssl_fc_has_sni(struct proxy *px, struct stream *l4, void *l7, unsigned int opt,
Thierry FOURNIERf41a8092014-12-07 18:37:57 +01003644 const struct arg *args, struct sample *smp, const char *kw, void *private)
Willy Tarreau7875d092012-09-10 08:20:03 +02003645{
3646#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Willy Tarreau9ad7bd42015-04-03 19:19:59 +02003647 struct session *sess = strm_sess(l4);
3648 struct connection *conn = objt_conn(sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003649
Willy Tarreau7875d092012-09-10 08:20:03 +02003650 smp->type = SMP_T_BOOL;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003651 smp->data.uint = (conn && conn->xprt == &ssl_sock) &&
3652 conn->xprt_ctx &&
3653 SSL_get_servername(conn->xprt_ctx, TLSEXT_NAMETYPE_host_name) != NULL;
Willy Tarreau7875d092012-09-10 08:20:03 +02003654 return 1;
3655#else
3656 return 0;
3657#endif
3658}
3659
Emeric Brun645ae792014-04-30 14:21:06 +02003660/* string, returns the used cipher if front conn. transport layer is SSL.
3661 * This function is also usable on backend conn if the fetch keyword 5th
3662 * char is 'b'.
3663 */
Emeric Brun589fcad2012-10-16 14:13:26 +02003664static int
Willy Tarreau87b09662015-04-03 00:22:06 +02003665smp_fetch_ssl_fc_cipher(struct proxy *px, struct stream *l4, void *l7, unsigned int opt,
Thierry FOURNIERf41a8092014-12-07 18:37:57 +01003666 const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun589fcad2012-10-16 14:13:26 +02003667{
Emeric Brun645ae792014-04-30 14:21:06 +02003668 int back_conn = (kw[4] == 'b') ? 1 : 0;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003669 struct connection *conn;
3670
Emeric Brun589fcad2012-10-16 14:13:26 +02003671 smp->flags = 0;
3672
Emeric Brun645ae792014-04-30 14:21:06 +02003673 conn = objt_conn(l4->si[back_conn].end);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003674 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
Emeric Brun589fcad2012-10-16 14:13:26 +02003675 return 0;
3676
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003677 smp->data.str.str = (char *)SSL_get_cipher_name(conn->xprt_ctx);
Emeric Brun589fcad2012-10-16 14:13:26 +02003678 if (!smp->data.str.str)
3679 return 0;
3680
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01003681 smp->type = SMP_T_STR;
3682 smp->flags |= SMP_F_CONST;
Emeric Brun589fcad2012-10-16 14:13:26 +02003683 smp->data.str.len = strlen(smp->data.str.str);
3684
3685 return 1;
3686}
3687
Emeric Brun645ae792014-04-30 14:21:06 +02003688/* integer, returns the algoritm's keysize if front conn. transport layer
3689 * is SSL.
3690 * This function is also usable on backend conn if the fetch keyword 5th
3691 * char is 'b'.
3692 */
Emeric Brun589fcad2012-10-16 14:13:26 +02003693static int
Willy Tarreau87b09662015-04-03 00:22:06 +02003694smp_fetch_ssl_fc_alg_keysize(struct proxy *px, struct stream *l4, void *l7, unsigned int opt,
Thierry FOURNIERf41a8092014-12-07 18:37:57 +01003695 const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun589fcad2012-10-16 14:13:26 +02003696{
Emeric Brun645ae792014-04-30 14:21:06 +02003697 int back_conn = (kw[4] == 'b') ? 1 : 0;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003698 struct connection *conn;
3699
Emeric Brun589fcad2012-10-16 14:13:26 +02003700 smp->flags = 0;
3701
Emeric Brun645ae792014-04-30 14:21:06 +02003702 conn = objt_conn(l4->si[back_conn].end);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003703 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
Emeric Brun589fcad2012-10-16 14:13:26 +02003704 return 0;
3705
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003706 if (!SSL_get_cipher_bits(conn->xprt_ctx, (int *)&smp->data.uint))
3707 return 0;
3708
Emeric Brun589fcad2012-10-16 14:13:26 +02003709 smp->type = SMP_T_UINT;
3710
3711 return 1;
3712}
3713
Emeric Brun645ae792014-04-30 14:21:06 +02003714/* integer, returns the used keysize if front conn. transport layer is SSL.
3715 * This function is also usable on backend conn if the fetch keyword 5th
3716 * char is 'b'.
3717 */
Emeric Brun589fcad2012-10-16 14:13:26 +02003718static int
Willy Tarreau87b09662015-04-03 00:22:06 +02003719smp_fetch_ssl_fc_use_keysize(struct proxy *px, struct stream *l4, void *l7, unsigned int opt,
Thierry FOURNIERf41a8092014-12-07 18:37:57 +01003720 const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun589fcad2012-10-16 14:13:26 +02003721{
Emeric Brun645ae792014-04-30 14:21:06 +02003722 int back_conn = (kw[4] == 'b') ? 1 : 0;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003723 struct connection *conn;
3724
Emeric Brun589fcad2012-10-16 14:13:26 +02003725 smp->flags = 0;
3726
Emeric Brun645ae792014-04-30 14:21:06 +02003727 conn = objt_conn(l4->si[back_conn].end);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003728 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
3729 return 0;
3730
3731 smp->data.uint = (unsigned int)SSL_get_cipher_bits(conn->xprt_ctx, NULL);
Emeric Brun589fcad2012-10-16 14:13:26 +02003732 if (!smp->data.uint)
3733 return 0;
3734
3735 smp->type = SMP_T_UINT;
3736
3737 return 1;
3738}
3739
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02003740#ifdef OPENSSL_NPN_NEGOTIATED
Willy Tarreau7875d092012-09-10 08:20:03 +02003741static int
Willy Tarreau87b09662015-04-03 00:22:06 +02003742smp_fetch_ssl_fc_npn(struct proxy *px, struct stream *l4, void *l7, unsigned int opt,
Thierry FOURNIERf41a8092014-12-07 18:37:57 +01003743 const struct arg *args, struct sample *smp, const char *kw, void *private)
Willy Tarreaua33c6542012-10-15 13:19:06 +02003744{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003745 struct connection *conn;
Willy Tarreau9ad7bd42015-04-03 19:19:59 +02003746 struct session *sess = strm_sess(l4);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003747
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01003748 smp->flags = SMP_F_CONST;
3749 smp->type = SMP_T_STR;
Willy Tarreaua33c6542012-10-15 13:19:06 +02003750
Willy Tarreau9ad7bd42015-04-03 19:19:59 +02003751 conn = objt_conn(sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003752 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
3753 return 0;
3754
Willy Tarreaua33c6542012-10-15 13:19:06 +02003755 smp->data.str.str = NULL;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003756 SSL_get0_next_proto_negotiated(conn->xprt_ctx,
Willy Tarreaua33c6542012-10-15 13:19:06 +02003757 (const unsigned char **)&smp->data.str.str, (unsigned *)&smp->data.str.len);
3758
3759 if (!smp->data.str.str)
3760 return 0;
3761
3762 return 1;
Willy Tarreaua33c6542012-10-15 13:19:06 +02003763}
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02003764#endif
Willy Tarreaua33c6542012-10-15 13:19:06 +02003765
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01003766#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Willy Tarreauab861d32013-04-02 02:30:41 +02003767static int
Willy Tarreau87b09662015-04-03 00:22:06 +02003768smp_fetch_ssl_fc_alpn(struct proxy *px, struct stream *l4, void *l7, unsigned int opt,
Thierry FOURNIERf41a8092014-12-07 18:37:57 +01003769 const struct arg *args, struct sample *smp, const char *kw, void *private)
Willy Tarreauab861d32013-04-02 02:30:41 +02003770{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003771 struct connection *conn;
Willy Tarreau9ad7bd42015-04-03 19:19:59 +02003772 struct session *sess = strm_sess(l4);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003773
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01003774 smp->flags = SMP_F_CONST;
3775 smp->type = SMP_T_STR;
Willy Tarreauab861d32013-04-02 02:30:41 +02003776
Willy Tarreau9ad7bd42015-04-03 19:19:59 +02003777 conn = objt_conn(sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003778 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
Willy Tarreauab861d32013-04-02 02:30:41 +02003779 return 0;
3780
3781 smp->data.str.str = NULL;
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01003782 SSL_get0_alpn_selected(conn->xprt_ctx,
Willy Tarreauab861d32013-04-02 02:30:41 +02003783 (const unsigned char **)&smp->data.str.str, (unsigned *)&smp->data.str.len);
3784
3785 if (!smp->data.str.str)
3786 return 0;
3787
3788 return 1;
3789}
3790#endif
3791
Emeric Brun645ae792014-04-30 14:21:06 +02003792/* string, returns the used protocol if front conn. transport layer is SSL.
3793 * This function is also usable on backend conn if the fetch keyword 5th
3794 * char is 'b'.
3795 */
Willy Tarreaua33c6542012-10-15 13:19:06 +02003796static int
Willy Tarreau87b09662015-04-03 00:22:06 +02003797smp_fetch_ssl_fc_protocol(struct proxy *px, struct stream *l4, void *l7, unsigned int opt,
Thierry FOURNIERf41a8092014-12-07 18:37:57 +01003798 const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun589fcad2012-10-16 14:13:26 +02003799{
Emeric Brun645ae792014-04-30 14:21:06 +02003800 int back_conn = (kw[4] == 'b') ? 1 : 0;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003801 struct connection *conn;
3802
Emeric Brun589fcad2012-10-16 14:13:26 +02003803 smp->flags = 0;
3804
Emeric Brun645ae792014-04-30 14:21:06 +02003805 conn = objt_conn(l4->si[back_conn].end);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003806 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
3807 return 0;
3808
3809 smp->data.str.str = (char *)SSL_get_version(conn->xprt_ctx);
Emeric Brun589fcad2012-10-16 14:13:26 +02003810 if (!smp->data.str.str)
3811 return 0;
3812
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01003813 smp->type = SMP_T_STR;
3814 smp->flags = SMP_F_CONST;
Emeric Brun589fcad2012-10-16 14:13:26 +02003815 smp->data.str.len = strlen(smp->data.str.str);
3816
3817 return 1;
3818}
3819
Willy Tarreau87b09662015-04-03 00:22:06 +02003820/* binary, returns the SSL stream id if front conn. transport layer is SSL.
Emeric Brun645ae792014-04-30 14:21:06 +02003821 * This function is also usable on backend conn if the fetch keyword 5th
3822 * char is 'b'.
3823 */
Emeric Brun589fcad2012-10-16 14:13:26 +02003824static int
Willy Tarreau87b09662015-04-03 00:22:06 +02003825smp_fetch_ssl_fc_session_id(struct proxy *px, struct stream *l4, void *l7, unsigned int opt,
Thierry FOURNIERf41a8092014-12-07 18:37:57 +01003826 const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brunfe68f682012-10-16 14:59:28 +02003827{
3828#if OPENSSL_VERSION_NUMBER > 0x0090800fL
Emeric Brun645ae792014-04-30 14:21:06 +02003829 int back_conn = (kw[4] == 'b') ? 1 : 0;
Emeric Brunfe68f682012-10-16 14:59:28 +02003830 SSL_SESSION *sess;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003831 struct connection *conn;
Emeric Brunfe68f682012-10-16 14:59:28 +02003832
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01003833 smp->flags = SMP_F_CONST;
3834 smp->type = SMP_T_BIN;
Emeric Brunfe68f682012-10-16 14:59:28 +02003835
Emeric Brun645ae792014-04-30 14:21:06 +02003836 conn = objt_conn(l4->si[back_conn].end);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003837 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
3838 return 0;
3839
3840 sess = SSL_get_session(conn->xprt_ctx);
Emeric Brunfe68f682012-10-16 14:59:28 +02003841 if (!sess)
3842 return 0;
3843
3844 smp->data.str.str = (char *)SSL_SESSION_get_id(sess, (unsigned int *)&smp->data.str.len);
3845 if (!smp->data.str.str || !&smp->data.str.len)
3846 return 0;
3847
3848 return 1;
3849#else
3850 return 0;
3851#endif
3852}
3853
3854static int
Willy Tarreau87b09662015-04-03 00:22:06 +02003855smp_fetch_ssl_fc_sni(struct proxy *px, struct stream *l4, void *l7, unsigned int opt,
Thierry FOURNIERf41a8092014-12-07 18:37:57 +01003856 const struct arg *args, struct sample *smp, const char *kw, void *private)
Willy Tarreau7875d092012-09-10 08:20:03 +02003857{
3858#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003859 struct connection *conn;
Willy Tarreau9ad7bd42015-04-03 19:19:59 +02003860 struct session *sess = strm_sess(l4);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003861
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01003862 smp->flags = SMP_F_CONST;
3863 smp->type = SMP_T_STR;
Willy Tarreau7875d092012-09-10 08:20:03 +02003864
Willy Tarreau9ad7bd42015-04-03 19:19:59 +02003865 conn = objt_conn(sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003866 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
3867 return 0;
3868
3869 smp->data.str.str = (char *)SSL_get_servername(conn->xprt_ctx, TLSEXT_NAMETYPE_host_name);
Willy Tarreau3e394c92012-09-14 23:56:58 +02003870 if (!smp->data.str.str)
3871 return 0;
3872
Willy Tarreau7875d092012-09-10 08:20:03 +02003873 smp->data.str.len = strlen(smp->data.str.str);
3874 return 1;
3875#else
3876 return 0;
3877#endif
3878}
3879
David Sc1ad52e2014-04-08 18:48:47 -04003880static int
Willy Tarreau87b09662015-04-03 00:22:06 +02003881smp_fetch_ssl_fc_unique_id(struct proxy *px, struct stream *l4, void *l7, unsigned int opt,
Thierry FOURNIERf41a8092014-12-07 18:37:57 +01003882 const struct arg *args, struct sample *smp, const char *kw, void *private)
David Sc1ad52e2014-04-08 18:48:47 -04003883{
3884#if OPENSSL_VERSION_NUMBER > 0x0090800fL
Emeric Brun645ae792014-04-30 14:21:06 +02003885 int back_conn = (kw[4] == 'b') ? 1 : 0;
David Sc1ad52e2014-04-08 18:48:47 -04003886 struct connection *conn;
3887 int finished_len;
David Sc1ad52e2014-04-08 18:48:47 -04003888 struct chunk *finished_trash;
David Sc1ad52e2014-04-08 18:48:47 -04003889
3890 smp->flags = 0;
3891
Emeric Brun645ae792014-04-30 14:21:06 +02003892 conn = objt_conn(l4->si[back_conn].end);
David Sc1ad52e2014-04-08 18:48:47 -04003893 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
3894 return 0;
3895
3896 if (!(conn->flags & CO_FL_CONNECTED)) {
3897 smp->flags |= SMP_F_MAY_CHANGE;
3898 return 0;
3899 }
3900
3901 finished_trash = get_trash_chunk();
3902 if (!SSL_session_reused(conn->xprt_ctx))
3903 finished_len = SSL_get_peer_finished(conn->xprt_ctx, finished_trash->str, finished_trash->size);
3904 else
3905 finished_len = SSL_get_finished(conn->xprt_ctx, finished_trash->str, finished_trash->size);
3906
3907 if (!finished_len)
3908 return 0;
3909
Emeric Brunb73a9b02014-04-30 18:49:19 +02003910 finished_trash->len = finished_len;
3911 smp->data.str = *finished_trash;
3912 smp->type = SMP_T_BIN;
David Sc1ad52e2014-04-08 18:48:47 -04003913
3914 return 1;
3915#else
3916 return 0;
3917#endif
3918}
3919
Emeric Brun2525b6b2012-10-18 15:59:43 +02003920/* integer, returns the first verify error in CA chain of client certificate chain. */
Emeric Brunf282a812012-09-21 15:27:54 +02003921static int
Willy Tarreau87b09662015-04-03 00:22:06 +02003922smp_fetch_ssl_c_ca_err(struct proxy *px, struct stream *l4, void *l7, unsigned int opt,
Thierry FOURNIERf41a8092014-12-07 18:37:57 +01003923 const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brunf282a812012-09-21 15:27:54 +02003924{
Willy Tarreau9ad7bd42015-04-03 19:19:59 +02003925 struct session *sess = strm_sess(l4);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003926 struct connection *conn;
3927
Willy Tarreau9ad7bd42015-04-03 19:19:59 +02003928 conn = objt_conn(sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003929 if (!conn || conn->xprt != &ssl_sock)
3930 return 0;
3931
3932 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunf282a812012-09-21 15:27:54 +02003933 smp->flags = SMP_F_MAY_CHANGE;
3934 return 0;
3935 }
3936
3937 smp->type = SMP_T_UINT;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003938 smp->data.uint = (unsigned int)SSL_SOCK_ST_TO_CA_ERROR(conn->xprt_st);
Emeric Brunf282a812012-09-21 15:27:54 +02003939 smp->flags = 0;
3940
3941 return 1;
3942}
3943
Emeric Brun2525b6b2012-10-18 15:59:43 +02003944/* integer, returns the depth of the first verify error in CA chain of client certificate chain. */
Emeric Brunf282a812012-09-21 15:27:54 +02003945static int
Willy Tarreau87b09662015-04-03 00:22:06 +02003946smp_fetch_ssl_c_ca_err_depth(struct proxy *px, struct stream *l4, void *l7, unsigned int opt,
Thierry FOURNIERf41a8092014-12-07 18:37:57 +01003947 const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brunf282a812012-09-21 15:27:54 +02003948{
Willy Tarreau9ad7bd42015-04-03 19:19:59 +02003949 struct session *sess = strm_sess(l4);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003950 struct connection *conn;
3951
Willy Tarreau9ad7bd42015-04-03 19:19:59 +02003952 conn = objt_conn(sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003953 if (!conn || conn->xprt != &ssl_sock)
Emeric Brunf282a812012-09-21 15:27:54 +02003954 return 0;
3955
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003956 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunf282a812012-09-21 15:27:54 +02003957 smp->flags = SMP_F_MAY_CHANGE;
3958 return 0;
3959 }
3960
3961 smp->type = SMP_T_UINT;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003962 smp->data.uint = (unsigned int)SSL_SOCK_ST_TO_CAEDEPTH(conn->xprt_st);
Emeric Brunf282a812012-09-21 15:27:54 +02003963 smp->flags = 0;
3964
3965 return 1;
3966}
3967
Emeric Brun2525b6b2012-10-18 15:59:43 +02003968/* integer, returns the first verify error on client certificate */
Emeric Brunf282a812012-09-21 15:27:54 +02003969static int
Willy Tarreau87b09662015-04-03 00:22:06 +02003970smp_fetch_ssl_c_err(struct proxy *px, struct stream *l4, void *l7, unsigned int opt,
Thierry FOURNIERf41a8092014-12-07 18:37:57 +01003971 const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brunf282a812012-09-21 15:27:54 +02003972{
Willy Tarreau9ad7bd42015-04-03 19:19:59 +02003973 struct session *sess = strm_sess(l4);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003974 struct connection *conn;
3975
Willy Tarreau9ad7bd42015-04-03 19:19:59 +02003976 conn = objt_conn(sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003977 if (!conn || conn->xprt != &ssl_sock)
3978 return 0;
3979
3980 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunf282a812012-09-21 15:27:54 +02003981 smp->flags = SMP_F_MAY_CHANGE;
3982 return 0;
3983 }
3984
3985 smp->type = SMP_T_UINT;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003986 smp->data.uint = (unsigned int)SSL_SOCK_ST_TO_CRTERROR(conn->xprt_st);
Emeric Brunf282a812012-09-21 15:27:54 +02003987 smp->flags = 0;
3988
3989 return 1;
3990}
3991
Emeric Brun2525b6b2012-10-18 15:59:43 +02003992/* integer, returns the verify result on client cert */
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02003993static int
Willy Tarreau87b09662015-04-03 00:22:06 +02003994smp_fetch_ssl_c_verify(struct proxy *px, struct stream *l4, void *l7, unsigned int opt,
Thierry FOURNIERf41a8092014-12-07 18:37:57 +01003995 const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02003996{
Willy Tarreau9ad7bd42015-04-03 19:19:59 +02003997 struct session *sess = strm_sess(l4);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003998 struct connection *conn;
3999
Willy Tarreau9ad7bd42015-04-03 19:19:59 +02004000 conn = objt_conn(sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004001 if (!conn || conn->xprt != &ssl_sock)
4002 return 0;
4003
4004 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02004005 smp->flags = SMP_F_MAY_CHANGE;
4006 return 0;
4007 }
4008
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004009 if (!conn->xprt_ctx)
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02004010 return 0;
4011
4012 smp->type = SMP_T_UINT;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004013 smp->data.uint = (unsigned int)SSL_get_verify_result(conn->xprt_ctx);
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02004014 smp->flags = 0;
4015
4016 return 1;
4017}
4018
Emeric Brunfb510ea2012-10-05 12:00:26 +02004019/* parse the "ca-file" bind keyword */
4020static 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 +02004021{
4022 if (!*args[cur_arg + 1]) {
4023 if (err)
4024 memprintf(err, "'%s' : missing CAfile path", args[cur_arg]);
4025 return ERR_ALERT | ERR_FATAL;
4026 }
4027
Emeric Brunef42d922012-10-11 16:11:36 +02004028 if ((*args[cur_arg + 1] != '/') && global.ca_base)
4029 memprintf(&conf->ca_file, "%s/%s", global.ca_base, args[cur_arg + 1]);
4030 else
4031 memprintf(&conf->ca_file, "%s", args[cur_arg + 1]);
Emeric Brunc8e8d122012-10-02 18:42:10 +02004032
Emeric Brund94b3fe2012-09-20 18:23:56 +02004033 return 0;
4034}
4035
Willy Tarreau79eeafa2012-09-14 07:53:05 +02004036/* parse the "ciphers" bind keyword */
Willy Tarreau4348fad2012-09-20 16:48:07 +02004037static 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 +02004038{
4039 if (!*args[cur_arg + 1]) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02004040 memprintf(err, "'%s' : missing cipher suite", args[cur_arg]);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02004041 return ERR_ALERT | ERR_FATAL;
4042 }
4043
Emeric Brun76d88952012-10-05 15:47:31 +02004044 free(conf->ciphers);
Willy Tarreau4348fad2012-09-20 16:48:07 +02004045 conf->ciphers = strdup(args[cur_arg + 1]);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02004046 return 0;
4047}
4048
4049/* parse the "crt" bind keyword */
Willy Tarreau4348fad2012-09-20 16:48:07 +02004050static 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 +02004051{
Willy Tarreau38011032013-08-13 16:59:39 +02004052 char path[MAXPATHLEN];
Willy Tarreaub75d6922014-04-14 18:05:41 +02004053
Willy Tarreau79eeafa2012-09-14 07:53:05 +02004054 if (!*args[cur_arg + 1]) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02004055 memprintf(err, "'%s' : missing certificate location", args[cur_arg]);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02004056 return ERR_ALERT | ERR_FATAL;
4057 }
4058
Emeric Brunc8e8d122012-10-02 18:42:10 +02004059 if ((*args[cur_arg + 1] != '/' ) && global.crt_base) {
Willy Tarreau38011032013-08-13 16:59:39 +02004060 if ((strlen(global.crt_base) + 1 + strlen(args[cur_arg + 1]) + 1) > MAXPATHLEN) {
Emeric Brunc8e8d122012-10-02 18:42:10 +02004061 memprintf(err, "'%s' : path too long", args[cur_arg]);
4062 return ERR_ALERT | ERR_FATAL;
4063 }
Willy Tarreaub75d6922014-04-14 18:05:41 +02004064 snprintf(path, sizeof(path), "%s/%s", global.crt_base, args[cur_arg + 1]);
Emeric Brunc8e8d122012-10-02 18:42:10 +02004065 if (ssl_sock_load_cert(path, conf, px, err) > 0)
4066 return ERR_ALERT | ERR_FATAL;
4067
4068 return 0;
4069 }
4070
Willy Tarreau4348fad2012-09-20 16:48:07 +02004071 if (ssl_sock_load_cert(args[cur_arg + 1], conf, px, err) > 0)
Willy Tarreau79eeafa2012-09-14 07:53:05 +02004072 return ERR_ALERT | ERR_FATAL;
Emeric Brund94b3fe2012-09-20 18:23:56 +02004073
4074 return 0;
4075}
4076
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01004077/* parse the "crt-list" bind keyword */
4078static int bind_parse_crt_list(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
4079{
4080 if (!*args[cur_arg + 1]) {
4081 memprintf(err, "'%s' : missing certificate location", args[cur_arg]);
4082 return ERR_ALERT | ERR_FATAL;
4083 }
4084
Willy Tarreauad1731d2013-04-02 17:35:58 +02004085 if (ssl_sock_load_cert_list_file(args[cur_arg + 1], conf, px, err) > 0) {
4086 memprintf(err, "'%s' : %s", args[cur_arg], *err);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01004087 return ERR_ALERT | ERR_FATAL;
Willy Tarreauad1731d2013-04-02 17:35:58 +02004088 }
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01004089
4090 return 0;
4091}
4092
Emeric Brunfb510ea2012-10-05 12:00:26 +02004093/* parse the "crl-file" bind keyword */
4094static 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 +02004095{
Emeric Brun051cdab2012-10-02 19:25:50 +02004096#ifndef X509_V_FLAG_CRL_CHECK
4097 if (err)
4098 memprintf(err, "'%s' : library does not support CRL verify", args[cur_arg]);
4099 return ERR_ALERT | ERR_FATAL;
4100#else
Emeric Brund94b3fe2012-09-20 18:23:56 +02004101 if (!*args[cur_arg + 1]) {
4102 if (err)
4103 memprintf(err, "'%s' : missing CRLfile path", args[cur_arg]);
4104 return ERR_ALERT | ERR_FATAL;
4105 }
Emeric Brun2b58d042012-09-20 17:10:03 +02004106
Emeric Brunef42d922012-10-11 16:11:36 +02004107 if ((*args[cur_arg + 1] != '/') && global.ca_base)
4108 memprintf(&conf->crl_file, "%s/%s", global.ca_base, args[cur_arg + 1]);
4109 else
4110 memprintf(&conf->crl_file, "%s", args[cur_arg + 1]);
Emeric Brunc8e8d122012-10-02 18:42:10 +02004111
Emeric Brun2b58d042012-09-20 17:10:03 +02004112 return 0;
Emeric Brun051cdab2012-10-02 19:25:50 +02004113#endif
Emeric Brun2b58d042012-09-20 17:10:03 +02004114}
4115
4116/* parse the "ecdhe" bind keyword keywords */
4117static int bind_parse_ecdhe(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
4118{
4119#if OPENSSL_VERSION_NUMBER < 0x0090800fL
4120 if (err)
4121 memprintf(err, "'%s' : library does not support elliptic curve Diffie-Hellman (too old)", args[cur_arg]);
4122 return ERR_ALERT | ERR_FATAL;
4123#elif defined(OPENSSL_NO_ECDH)
4124 if (err)
4125 memprintf(err, "'%s' : library does not support elliptic curve Diffie-Hellman (disabled via OPENSSL_NO_ECDH)", args[cur_arg]);
4126 return ERR_ALERT | ERR_FATAL;
4127#else
4128 if (!*args[cur_arg + 1]) {
4129 if (err)
4130 memprintf(err, "'%s' : missing named curve", args[cur_arg]);
4131 return ERR_ALERT | ERR_FATAL;
4132 }
4133
4134 conf->ecdhe = strdup(args[cur_arg + 1]);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02004135
4136 return 0;
Emeric Brun2b58d042012-09-20 17:10:03 +02004137#endif
Willy Tarreau79eeafa2012-09-14 07:53:05 +02004138}
4139
Emeric Brun81c00f02012-09-21 14:31:21 +02004140/* parse the "crt_ignerr" and "ca_ignerr" bind keywords */
4141static int bind_parse_ignore_err(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
4142{
4143 int code;
4144 char *p = args[cur_arg + 1];
4145 unsigned long long *ignerr = &conf->crt_ignerr;
4146
4147 if (!*p) {
4148 if (err)
4149 memprintf(err, "'%s' : missing error IDs list", args[cur_arg]);
4150 return ERR_ALERT | ERR_FATAL;
4151 }
4152
4153 if (strcmp(args[cur_arg], "ca-ignore-err") == 0)
4154 ignerr = &conf->ca_ignerr;
4155
4156 if (strcmp(p, "all") == 0) {
4157 *ignerr = ~0ULL;
4158 return 0;
4159 }
4160
4161 while (p) {
4162 code = atoi(p);
4163 if ((code <= 0) || (code > 63)) {
4164 if (err)
4165 memprintf(err, "'%s' : ID '%d' out of range (1..63) in error IDs list '%s'",
4166 args[cur_arg], code, args[cur_arg + 1]);
4167 return ERR_ALERT | ERR_FATAL;
4168 }
4169 *ignerr |= 1ULL << code;
4170 p = strchr(p, ',');
4171 if (p)
4172 p++;
4173 }
4174
Emeric Brun2cb7ae52012-10-05 14:14:21 +02004175 return 0;
4176}
4177
4178/* parse the "force-sslv3" bind keyword */
4179static int bind_parse_force_sslv3(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
4180{
4181 conf->ssl_options |= BC_SSL_O_USE_SSLV3;
4182 return 0;
4183}
4184
4185/* parse the "force-tlsv10" bind keyword */
4186static int bind_parse_force_tlsv10(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
4187{
4188 conf->ssl_options |= BC_SSL_O_USE_TLSV10;
Emeric Brun2d0c4822012-10-02 13:45:20 +02004189 return 0;
4190}
4191
Emeric Brun2cb7ae52012-10-05 14:14:21 +02004192/* parse the "force-tlsv11" bind keyword */
4193static int bind_parse_force_tlsv11(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
4194{
4195#if SSL_OP_NO_TLSv1_1
4196 conf->ssl_options |= BC_SSL_O_USE_TLSV11;
4197 return 0;
4198#else
4199 if (err)
4200 memprintf(err, "'%s' : library does not support protocol TLSv1.1", args[cur_arg]);
4201 return ERR_ALERT | ERR_FATAL;
4202#endif
4203}
4204
4205/* parse the "force-tlsv12" bind keyword */
4206static int bind_parse_force_tlsv12(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
4207{
4208#if SSL_OP_NO_TLSv1_2
4209 conf->ssl_options |= BC_SSL_O_USE_TLSV12;
4210 return 0;
4211#else
4212 if (err)
4213 memprintf(err, "'%s' : library does not support protocol TLSv1.2", args[cur_arg]);
4214 return ERR_ALERT | ERR_FATAL;
4215#endif
4216}
4217
4218
Emeric Brun2d0c4822012-10-02 13:45:20 +02004219/* parse the "no-tls-tickets" bind keyword */
4220static int bind_parse_no_tls_tickets(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
4221{
Emeric Brun89675492012-10-05 13:48:26 +02004222 conf->ssl_options |= BC_SSL_O_NO_TLS_TICKETS;
Emeric Brun81c00f02012-09-21 14:31:21 +02004223 return 0;
4224}
4225
Emeric Brun2d0c4822012-10-02 13:45:20 +02004226
Emeric Brun9b3009b2012-10-05 11:55:06 +02004227/* parse the "no-sslv3" bind keyword */
4228static 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 +02004229{
Emeric Brun89675492012-10-05 13:48:26 +02004230 conf->ssl_options |= BC_SSL_O_NO_SSLV3;
Willy Tarreau79eeafa2012-09-14 07:53:05 +02004231 return 0;
4232}
4233
Emeric Brun9b3009b2012-10-05 11:55:06 +02004234/* parse the "no-tlsv10" bind keyword */
4235static 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 +02004236{
Emeric Brun89675492012-10-05 13:48:26 +02004237 conf->ssl_options |= BC_SSL_O_NO_TLSV10;
Emeric Brunc0ff4922012-09-28 19:37:02 +02004238 return 0;
4239}
4240
Emeric Brun9b3009b2012-10-05 11:55:06 +02004241/* parse the "no-tlsv11" bind keyword */
4242static 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 +02004243{
Emeric Brun89675492012-10-05 13:48:26 +02004244 conf->ssl_options |= BC_SSL_O_NO_TLSV11;
Emeric Brunc0ff4922012-09-28 19:37:02 +02004245 return 0;
4246}
4247
Emeric Brun9b3009b2012-10-05 11:55:06 +02004248/* parse the "no-tlsv12" bind keyword */
4249static 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 +02004250{
Emeric Brun89675492012-10-05 13:48:26 +02004251 conf->ssl_options |= BC_SSL_O_NO_TLSV12;
Willy Tarreau79eeafa2012-09-14 07:53:05 +02004252 return 0;
4253}
4254
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02004255/* parse the "npn" bind keyword */
4256static int bind_parse_npn(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
4257{
4258#ifdef OPENSSL_NPN_NEGOTIATED
4259 char *p1, *p2;
4260
4261 if (!*args[cur_arg + 1]) {
4262 memprintf(err, "'%s' : missing the comma-delimited NPN protocol suite", args[cur_arg]);
4263 return ERR_ALERT | ERR_FATAL;
4264 }
4265
4266 free(conf->npn_str);
4267
4268 /* the NPN string is built as a suite of (<len> <name>)* */
4269 conf->npn_len = strlen(args[cur_arg + 1]) + 1;
4270 conf->npn_str = calloc(1, conf->npn_len);
4271 memcpy(conf->npn_str + 1, args[cur_arg + 1], conf->npn_len);
4272
4273 /* replace commas with the name length */
4274 p1 = conf->npn_str;
4275 p2 = p1 + 1;
4276 while (1) {
4277 p2 = memchr(p1 + 1, ',', conf->npn_str + conf->npn_len - (p1 + 1));
4278 if (!p2)
4279 p2 = p1 + 1 + strlen(p1 + 1);
4280
4281 if (p2 - (p1 + 1) > 255) {
4282 *p2 = '\0';
4283 memprintf(err, "'%s' : NPN protocol name too long : '%s'", args[cur_arg], p1 + 1);
4284 return ERR_ALERT | ERR_FATAL;
4285 }
4286
4287 *p1 = p2 - (p1 + 1);
4288 p1 = p2;
4289
4290 if (!*p2)
4291 break;
4292
4293 *(p2++) = '\0';
4294 }
4295 return 0;
4296#else
4297 if (err)
4298 memprintf(err, "'%s' : library does not support TLS NPN extension", args[cur_arg]);
4299 return ERR_ALERT | ERR_FATAL;
4300#endif
4301}
4302
Willy Tarreauab861d32013-04-02 02:30:41 +02004303/* parse the "alpn" bind keyword */
4304static int bind_parse_alpn(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
4305{
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01004306#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Willy Tarreauab861d32013-04-02 02:30:41 +02004307 char *p1, *p2;
4308
4309 if (!*args[cur_arg + 1]) {
4310 memprintf(err, "'%s' : missing the comma-delimited ALPN protocol suite", args[cur_arg]);
4311 return ERR_ALERT | ERR_FATAL;
4312 }
4313
4314 free(conf->alpn_str);
4315
4316 /* the ALPN string is built as a suite of (<len> <name>)* */
4317 conf->alpn_len = strlen(args[cur_arg + 1]) + 1;
4318 conf->alpn_str = calloc(1, conf->alpn_len);
4319 memcpy(conf->alpn_str + 1, args[cur_arg + 1], conf->alpn_len);
4320
4321 /* replace commas with the name length */
4322 p1 = conf->alpn_str;
4323 p2 = p1 + 1;
4324 while (1) {
4325 p2 = memchr(p1 + 1, ',', conf->alpn_str + conf->alpn_len - (p1 + 1));
4326 if (!p2)
4327 p2 = p1 + 1 + strlen(p1 + 1);
4328
4329 if (p2 - (p1 + 1) > 255) {
4330 *p2 = '\0';
4331 memprintf(err, "'%s' : ALPN protocol name too long : '%s'", args[cur_arg], p1 + 1);
4332 return ERR_ALERT | ERR_FATAL;
4333 }
4334
4335 *p1 = p2 - (p1 + 1);
4336 p1 = p2;
4337
4338 if (!*p2)
4339 break;
4340
4341 *(p2++) = '\0';
4342 }
4343 return 0;
4344#else
4345 if (err)
4346 memprintf(err, "'%s' : library does not support TLS ALPN extension", args[cur_arg]);
4347 return ERR_ALERT | ERR_FATAL;
4348#endif
4349}
4350
Willy Tarreau79eeafa2012-09-14 07:53:05 +02004351/* parse the "ssl" bind keyword */
Willy Tarreau4348fad2012-09-20 16:48:07 +02004352static 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 +02004353{
Willy Tarreau81796be2012-09-22 19:11:47 +02004354 struct listener *l;
4355
Willy Tarreau4348fad2012-09-20 16:48:07 +02004356 conf->is_ssl = 1;
Emeric Brun76d88952012-10-05 15:47:31 +02004357
4358 if (global.listen_default_ciphers && !conf->ciphers)
4359 conf->ciphers = strdup(global.listen_default_ciphers);
Emeric Brun2c86cbf2014-10-30 15:56:50 +01004360 conf->ssl_options |= global.listen_default_ssloptions;
Emeric Brun76d88952012-10-05 15:47:31 +02004361
Willy Tarreau81796be2012-09-22 19:11:47 +02004362 list_for_each_entry(l, &conf->listeners, by_bind)
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02004363 l->xprt = &ssl_sock;
Willy Tarreau81796be2012-09-22 19:11:47 +02004364
Willy Tarreau79eeafa2012-09-14 07:53:05 +02004365 return 0;
4366}
4367
Emmanuel Hocdet65623372013-01-24 17:17:15 +01004368/* parse the "strict-sni" bind keyword */
4369static int bind_parse_strict_sni(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
4370{
4371 conf->strict_sni = 1;
4372 return 0;
Nenad Merdanovic05552d42015-02-27 19:56:49 +01004373}
4374
4375/* parse the "tls-ticket-keys" bind keyword */
4376static int bind_parse_tls_ticket_keys(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
4377{
4378#if (defined SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB && TLS_TICKETS_NO > 0)
4379 FILE *f;
4380 int i = 0;
4381 char thisline[LINESIZE];
4382
4383 if (!*args[cur_arg + 1]) {
4384 if (err)
4385 memprintf(err, "'%s' : missing TLS ticket keys file path", args[cur_arg]);
4386 return ERR_ALERT | ERR_FATAL;
4387 }
4388
4389 conf->tls_ticket_keys = malloc(TLS_TICKETS_NO * sizeof(struct tls_sess_key));
4390
4391 if ((f = fopen(args[cur_arg + 1], "r")) == NULL) {
4392 if (err)
4393 memprintf(err, "'%s' : unable to load ssl tickets keys file", args[cur_arg+1]);
4394 return ERR_ALERT | ERR_FATAL;
4395 }
4396
4397 while (fgets(thisline, sizeof(thisline), f) != NULL) {
4398 int len = strlen(thisline);
4399 /* Strip newline characters from the end */
4400 if(thisline[len - 1] == '\n')
4401 thisline[--len] = 0;
4402
4403 if(thisline[len - 1] == '\r')
4404 thisline[--len] = 0;
4405
4406 if (base64dec(thisline, len, (char *) (conf->tls_ticket_keys + i % TLS_TICKETS_NO), sizeof(struct tls_sess_key)) != sizeof(struct tls_sess_key)) {
4407 if (err)
4408 memprintf(err, "'%s' : unable to decode base64 key on line %d", args[cur_arg+1], i + 1);
4409 return ERR_ALERT | ERR_FATAL;
4410 }
4411 i++;
4412 }
4413
4414 if (i < TLS_TICKETS_NO) {
4415 if (err)
4416 memprintf(err, "'%s' : please supply at least %d keys in the tls-tickets-file", args[cur_arg+1], TLS_TICKETS_NO);
4417 return ERR_ALERT | ERR_FATAL;
4418 }
4419
4420 fclose(f);
4421
4422 /* Use penultimate key for encryption, handle when TLS_TICKETS_NO = 1 */
4423 i-=2;
4424 conf->tls_ticket_enc_index = i < 0 ? 0 : i;
4425
4426 return 0;
4427#else
4428 if (err)
4429 memprintf(err, "'%s' : TLS ticket callback extension not supported", args[cur_arg]);
4430 return ERR_ALERT | ERR_FATAL;
4431#endif /* SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB */
Emmanuel Hocdet65623372013-01-24 17:17:15 +01004432}
4433
Emeric Brund94b3fe2012-09-20 18:23:56 +02004434/* parse the "verify" bind keyword */
4435static int bind_parse_verify(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
4436{
4437 if (!*args[cur_arg + 1]) {
4438 if (err)
4439 memprintf(err, "'%s' : missing verify method", args[cur_arg]);
4440 return ERR_ALERT | ERR_FATAL;
4441 }
4442
4443 if (strcmp(args[cur_arg + 1], "none") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01004444 conf->verify = SSL_SOCK_VERIFY_NONE;
Emeric Brund94b3fe2012-09-20 18:23:56 +02004445 else if (strcmp(args[cur_arg + 1], "optional") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01004446 conf->verify = SSL_SOCK_VERIFY_OPTIONAL;
Emeric Brund94b3fe2012-09-20 18:23:56 +02004447 else if (strcmp(args[cur_arg + 1], "required") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01004448 conf->verify = SSL_SOCK_VERIFY_REQUIRED;
Emeric Brund94b3fe2012-09-20 18:23:56 +02004449 else {
4450 if (err)
4451 memprintf(err, "'%s' : unknown verify method '%s', only 'none', 'optional', and 'required' are supported\n",
4452 args[cur_arg], args[cur_arg + 1]);
4453 return ERR_ALERT | ERR_FATAL;
4454 }
4455
4456 return 0;
4457}
4458
Willy Tarreau92faadf2012-10-10 23:04:25 +02004459/************** "server" keywords ****************/
4460
Emeric Brunef42d922012-10-11 16:11:36 +02004461/* parse the "ca-file" server keyword */
4462static int srv_parse_ca_file(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4463{
4464 if (!*args[*cur_arg + 1]) {
4465 if (err)
4466 memprintf(err, "'%s' : missing CAfile path", args[*cur_arg]);
4467 return ERR_ALERT | ERR_FATAL;
4468 }
4469
4470 if ((*args[*cur_arg + 1] != '/') && global.ca_base)
4471 memprintf(&newsrv->ssl_ctx.ca_file, "%s/%s", global.ca_base, args[*cur_arg + 1]);
4472 else
4473 memprintf(&newsrv->ssl_ctx.ca_file, "%s", args[*cur_arg + 1]);
4474
4475 return 0;
4476}
4477
Willy Tarreau92faadf2012-10-10 23:04:25 +02004478/* parse the "check-ssl" server keyword */
4479static int srv_parse_check_ssl(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4480{
4481 newsrv->check.use_ssl = 1;
4482 if (global.connect_default_ciphers && !newsrv->ssl_ctx.ciphers)
4483 newsrv->ssl_ctx.ciphers = strdup(global.connect_default_ciphers);
Emeric Brun2c86cbf2014-10-30 15:56:50 +01004484 newsrv->ssl_ctx.options |= global.connect_default_ssloptions;
Willy Tarreau92faadf2012-10-10 23:04:25 +02004485 return 0;
4486}
4487
4488/* parse the "ciphers" server keyword */
4489static int srv_parse_ciphers(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4490{
4491 if (!*args[*cur_arg + 1]) {
4492 memprintf(err, "'%s' : missing cipher suite", args[*cur_arg]);
4493 return ERR_ALERT | ERR_FATAL;
4494 }
4495
4496 free(newsrv->ssl_ctx.ciphers);
4497 newsrv->ssl_ctx.ciphers = strdup(args[*cur_arg + 1]);
4498 return 0;
4499}
4500
Emeric Brunef42d922012-10-11 16:11:36 +02004501/* parse the "crl-file" server keyword */
4502static int srv_parse_crl_file(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4503{
4504#ifndef X509_V_FLAG_CRL_CHECK
4505 if (err)
4506 memprintf(err, "'%s' : library does not support CRL verify", args[*cur_arg]);
4507 return ERR_ALERT | ERR_FATAL;
4508#else
4509 if (!*args[*cur_arg + 1]) {
4510 if (err)
4511 memprintf(err, "'%s' : missing CRLfile path", args[*cur_arg]);
4512 return ERR_ALERT | ERR_FATAL;
4513 }
4514
4515 if ((*args[*cur_arg + 1] != '/') && global.ca_base)
4516 memprintf(&newsrv->ssl_ctx.crl_file, "%s/%s", global.ca_base, args[*cur_arg + 1]);
4517 else
4518 memprintf(&newsrv->ssl_ctx.crl_file, "%s", args[*cur_arg + 1]);
4519
4520 return 0;
4521#endif
4522}
4523
Emeric Bruna7aa3092012-10-26 12:58:00 +02004524/* parse the "crt" server keyword */
4525static int srv_parse_crt(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4526{
4527 if (!*args[*cur_arg + 1]) {
4528 if (err)
4529 memprintf(err, "'%s' : missing certificate file path", args[*cur_arg]);
4530 return ERR_ALERT | ERR_FATAL;
4531 }
4532
4533 if ((*args[*cur_arg + 1] != '/') && global.crt_base)
4534 memprintf(&newsrv->ssl_ctx.client_crt, "%s/%s", global.ca_base, args[*cur_arg + 1]);
4535 else
4536 memprintf(&newsrv->ssl_ctx.client_crt, "%s", args[*cur_arg + 1]);
4537
4538 return 0;
4539}
Emeric Brunef42d922012-10-11 16:11:36 +02004540
Willy Tarreau92faadf2012-10-10 23:04:25 +02004541/* parse the "force-sslv3" server keyword */
4542static int srv_parse_force_sslv3(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4543{
4544 newsrv->ssl_ctx.options |= SRV_SSL_O_USE_SSLV3;
4545 return 0;
4546}
4547
4548/* parse the "force-tlsv10" server keyword */
4549static int srv_parse_force_tlsv10(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4550{
4551 newsrv->ssl_ctx.options |= SRV_SSL_O_USE_TLSV10;
4552 return 0;
4553}
4554
4555/* parse the "force-tlsv11" server keyword */
4556static int srv_parse_force_tlsv11(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4557{
4558#if SSL_OP_NO_TLSv1_1
4559 newsrv->ssl_ctx.options |= SRV_SSL_O_USE_TLSV11;
4560 return 0;
4561#else
4562 if (err)
4563 memprintf(err, "'%s' : library does not support protocol TLSv1.1", args[*cur_arg]);
4564 return ERR_ALERT | ERR_FATAL;
4565#endif
4566}
4567
4568/* parse the "force-tlsv12" server keyword */
4569static int srv_parse_force_tlsv12(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4570{
4571#if SSL_OP_NO_TLSv1_2
4572 newsrv->ssl_ctx.options |= SRV_SSL_O_USE_TLSV12;
4573 return 0;
4574#else
4575 if (err)
4576 memprintf(err, "'%s' : library does not support protocol TLSv1.2", args[*cur_arg]);
4577 return ERR_ALERT | ERR_FATAL;
4578#endif
4579}
4580
Willy Tarreau2a3fb1c2015-02-05 16:47:07 +01004581/* parse the "no-ssl-reuse" server keyword */
4582static int srv_parse_no_ssl_reuse(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4583{
4584 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_REUSE;
4585 return 0;
4586}
4587
Willy Tarreau92faadf2012-10-10 23:04:25 +02004588/* parse the "no-sslv3" server keyword */
4589static int srv_parse_no_sslv3(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4590{
4591 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_SSLV3;
4592 return 0;
4593}
4594
4595/* parse the "no-tlsv10" server keyword */
4596static int srv_parse_no_tlsv10(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4597{
4598 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_TLSV10;
4599 return 0;
4600}
4601
4602/* parse the "no-tlsv11" server keyword */
4603static int srv_parse_no_tlsv11(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4604{
4605 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_TLSV11;
4606 return 0;
4607}
4608
4609/* parse the "no-tlsv12" server keyword */
4610static int srv_parse_no_tlsv12(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4611{
4612 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_TLSV12;
4613 return 0;
4614}
4615
Emeric Brunf9c5c472012-10-11 15:28:34 +02004616/* parse the "no-tls-tickets" server keyword */
4617static int srv_parse_no_tls_tickets(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4618{
4619 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_TLS_TICKETS;
4620 return 0;
4621}
David Safb76832014-05-08 23:42:08 -04004622/* parse the "send-proxy-v2-ssl" server keyword */
4623static int srv_parse_send_proxy_ssl(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4624{
4625 newsrv->pp_opts |= SRV_PP_V2;
4626 newsrv->pp_opts |= SRV_PP_V2_SSL;
4627 return 0;
4628}
4629
4630/* parse the "send-proxy-v2-ssl-cn" server keyword */
4631static int srv_parse_send_proxy_cn(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4632{
4633 newsrv->pp_opts |= SRV_PP_V2;
4634 newsrv->pp_opts |= SRV_PP_V2_SSL;
4635 newsrv->pp_opts |= SRV_PP_V2_SSL_CN;
4636 return 0;
4637}
Emeric Brunf9c5c472012-10-11 15:28:34 +02004638
Willy Tarreau92faadf2012-10-10 23:04:25 +02004639/* parse the "ssl" server keyword */
4640static int srv_parse_ssl(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4641{
4642 newsrv->use_ssl = 1;
4643 if (global.connect_default_ciphers && !newsrv->ssl_ctx.ciphers)
4644 newsrv->ssl_ctx.ciphers = strdup(global.connect_default_ciphers);
4645 return 0;
4646}
4647
Emeric Brunef42d922012-10-11 16:11:36 +02004648/* parse the "verify" server keyword */
4649static int srv_parse_verify(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4650{
4651 if (!*args[*cur_arg + 1]) {
4652 if (err)
4653 memprintf(err, "'%s' : missing verify method", args[*cur_arg]);
4654 return ERR_ALERT | ERR_FATAL;
4655 }
4656
4657 if (strcmp(args[*cur_arg + 1], "none") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01004658 newsrv->ssl_ctx.verify = SSL_SOCK_VERIFY_NONE;
Emeric Brunef42d922012-10-11 16:11:36 +02004659 else if (strcmp(args[*cur_arg + 1], "required") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01004660 newsrv->ssl_ctx.verify = SSL_SOCK_VERIFY_REQUIRED;
Emeric Brunef42d922012-10-11 16:11:36 +02004661 else {
4662 if (err)
4663 memprintf(err, "'%s' : unknown verify method '%s', only 'none' and 'required' are supported\n",
4664 args[*cur_arg], args[*cur_arg + 1]);
4665 return ERR_ALERT | ERR_FATAL;
4666 }
4667
Evan Broderbe554312013-06-27 00:05:25 -07004668 return 0;
4669}
4670
4671/* parse the "verifyhost" server keyword */
4672static int srv_parse_verifyhost(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4673{
4674 if (!*args[*cur_arg + 1]) {
4675 if (err)
4676 memprintf(err, "'%s' : missing hostname to verify against", args[*cur_arg]);
4677 return ERR_ALERT | ERR_FATAL;
4678 }
4679
4680 newsrv->ssl_ctx.verify_host = strdup(args[*cur_arg + 1]);
4681
Emeric Brunef42d922012-10-11 16:11:36 +02004682 return 0;
4683}
4684
Emeric Brun2c86cbf2014-10-30 15:56:50 +01004685/* parse the "ssl-default-bind-options" keyword in global section */
4686static int ssl_parse_default_bind_options(char **args, int section_type, struct proxy *curpx,
4687 struct proxy *defpx, const char *file, int line,
4688 char **err) {
4689 int i = 1;
4690
4691 if (*(args[i]) == 0) {
4692 memprintf(err, "global statement '%s' expects an option as an argument.", args[0]);
4693 return -1;
4694 }
4695 while (*(args[i])) {
4696 if (!strcmp(args[i], "no-sslv3"))
4697 global.listen_default_ssloptions |= BC_SSL_O_NO_SSLV3;
4698 else if (!strcmp(args[i], "no-tlsv10"))
4699 global.listen_default_ssloptions |= BC_SSL_O_NO_TLSV10;
4700 else if (!strcmp(args[i], "no-tlsv11"))
4701 global.listen_default_ssloptions |= BC_SSL_O_NO_TLSV11;
4702 else if (!strcmp(args[i], "no-tlsv12"))
4703 global.listen_default_ssloptions |= BC_SSL_O_NO_TLSV12;
4704 else if (!strcmp(args[i], "force-sslv3"))
4705 global.listen_default_ssloptions |= BC_SSL_O_USE_SSLV3;
4706 else if (!strcmp(args[i], "force-tlsv10"))
4707 global.listen_default_ssloptions |= BC_SSL_O_USE_TLSV10;
4708 else if (!strcmp(args[i], "force-tlsv11")) {
4709#if SSL_OP_NO_TLSv1_1
4710 global.listen_default_ssloptions |= BC_SSL_O_USE_TLSV11;
4711#else
4712 memprintf(err, "'%s' '%s': library does not support protocol TLSv1.1", args[0], args[i]);
4713 return -1;
4714#endif
4715 }
4716 else if (!strcmp(args[i], "force-tlsv12")) {
4717#if SSL_OP_NO_TLSv1_2
4718 global.listen_default_ssloptions |= BC_SSL_O_USE_TLSV12;
4719#else
4720 memprintf(err, "'%s' '%s': library does not support protocol TLSv1.2", args[0], args[i]);
4721 return -1;
4722#endif
4723 }
4724 else if (!strcmp(args[i], "no-tls-tickets"))
4725 global.listen_default_ssloptions |= BC_SSL_O_NO_TLS_TICKETS;
4726 else {
4727 memprintf(err, "unknown option '%s' on global statement '%s'.", args[i], args[0]);
4728 return -1;
4729 }
4730 i++;
4731 }
4732 return 0;
4733}
4734
4735/* parse the "ssl-default-server-options" keyword in global section */
4736static int ssl_parse_default_server_options(char **args, int section_type, struct proxy *curpx,
4737 struct proxy *defpx, const char *file, int line,
4738 char **err) {
4739 int i = 1;
4740
4741 if (*(args[i]) == 0) {
4742 memprintf(err, "global statement '%s' expects an option as an argument.", args[0]);
4743 return -1;
4744 }
4745 while (*(args[i])) {
4746 if (!strcmp(args[i], "no-sslv3"))
4747 global.connect_default_ssloptions |= SRV_SSL_O_NO_SSLV3;
4748 else if (!strcmp(args[i], "no-tlsv10"))
4749 global.connect_default_ssloptions |= SRV_SSL_O_NO_TLSV10;
4750 else if (!strcmp(args[i], "no-tlsv11"))
4751 global.connect_default_ssloptions |= SRV_SSL_O_NO_TLSV11;
4752 else if (!strcmp(args[i], "no-tlsv12"))
4753 global.connect_default_ssloptions |= SRV_SSL_O_NO_TLSV12;
4754 else if (!strcmp(args[i], "force-sslv3"))
4755 global.connect_default_ssloptions |= SRV_SSL_O_USE_SSLV3;
4756 else if (!strcmp(args[i], "force-tlsv10"))
4757 global.connect_default_ssloptions |= SRV_SSL_O_USE_TLSV10;
4758 else if (!strcmp(args[i], "force-tlsv11")) {
4759#if SSL_OP_NO_TLSv1_1
4760 global.connect_default_ssloptions |= SRV_SSL_O_USE_TLSV11;
4761#else
4762 memprintf(err, "'%s' '%s': library does not support protocol TLSv1.1", args[0], args[i]);
4763 return -1;
4764#endif
4765 }
4766 else if (!strcmp(args[i], "force-tlsv12")) {
4767#if SSL_OP_NO_TLSv1_2
4768 global.connect_default_ssloptions |= SRV_SSL_O_USE_TLSV12;
4769#else
4770 memprintf(err, "'%s' '%s': library does not support protocol TLSv1.2", args[0], args[i]);
4771 return -1;
4772#endif
4773 }
4774 else if (!strcmp(args[i], "no-tls-tickets"))
4775 global.connect_default_ssloptions |= SRV_SSL_O_NO_TLS_TICKETS;
4776 else {
4777 memprintf(err, "unknown option '%s' on global statement '%s'.", args[i], args[0]);
4778 return -1;
4779 }
4780 i++;
4781 }
4782 return 0;
4783}
4784
Willy Tarreau7875d092012-09-10 08:20:03 +02004785/* Note: must not be declared <const> as its list will be overwritten.
4786 * Please take care of keeping this list alphabetically sorted.
4787 */
Willy Tarreaudc13c112013-06-21 23:16:39 +02004788static struct sample_fetch_kw_list sample_fetch_keywords = {ILH, {
Emeric Brun645ae792014-04-30 14:21:06 +02004789 { "ssl_bc", smp_fetch_ssl_fc, 0, NULL, SMP_T_BOOL, SMP_USE_L5SRV },
4790 { "ssl_bc_alg_keysize", smp_fetch_ssl_fc_alg_keysize, 0, NULL, SMP_T_UINT, SMP_USE_L5SRV },
4791 { "ssl_bc_cipher", smp_fetch_ssl_fc_cipher, 0, NULL, SMP_T_STR, SMP_USE_L5SRV },
4792 { "ssl_bc_protocol", smp_fetch_ssl_fc_protocol, 0, NULL, SMP_T_STR, SMP_USE_L5SRV },
Emeric Brunb73a9b02014-04-30 18:49:19 +02004793 { "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 +02004794 { "ssl_bc_use_keysize", smp_fetch_ssl_fc_use_keysize, 0, NULL, SMP_T_UINT, SMP_USE_L5SRV },
4795 { "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 +01004796 { "ssl_c_ca_err", smp_fetch_ssl_c_ca_err, 0, NULL, SMP_T_UINT, SMP_USE_L5CLI },
4797 { "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 +01004798 { "ssl_c_der", smp_fetch_ssl_x_der, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Willy Tarreau80aca902013-01-07 15:42:20 +01004799 { "ssl_c_err", smp_fetch_ssl_c_err, 0, NULL, SMP_T_UINT, SMP_USE_L5CLI },
Emeric Brunba841a12014-04-30 17:05:08 +02004800 { "ssl_c_i_dn", smp_fetch_ssl_x_i_dn, ARG2(0,STR,SINT), NULL, SMP_T_STR, SMP_USE_L5CLI },
4801 { "ssl_c_key_alg", smp_fetch_ssl_x_key_alg, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
4802 { "ssl_c_notafter", smp_fetch_ssl_x_notafter, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
4803 { "ssl_c_notbefore", smp_fetch_ssl_x_notbefore, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
4804 { "ssl_c_sig_alg", smp_fetch_ssl_x_sig_alg, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
4805 { "ssl_c_s_dn", smp_fetch_ssl_x_s_dn, ARG2(0,STR,SINT), NULL, SMP_T_STR, SMP_USE_L5CLI },
4806 { "ssl_c_serial", smp_fetch_ssl_x_serial, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
4807 { "ssl_c_sha1", smp_fetch_ssl_x_sha1, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Willy Tarreau80aca902013-01-07 15:42:20 +01004808 { "ssl_c_used", smp_fetch_ssl_c_used, 0, NULL, SMP_T_BOOL, SMP_USE_L5CLI },
4809 { "ssl_c_verify", smp_fetch_ssl_c_verify, 0, NULL, SMP_T_UINT, SMP_USE_L5CLI },
Emeric Brunba841a12014-04-30 17:05:08 +02004810 { "ssl_c_version", smp_fetch_ssl_x_version, 0, NULL, SMP_T_UINT, SMP_USE_L5CLI },
Emeric Brun43e79582014-10-29 19:03:26 +01004811 { "ssl_f_der", smp_fetch_ssl_x_der, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Emeric Brunba841a12014-04-30 17:05:08 +02004812 { "ssl_f_i_dn", smp_fetch_ssl_x_i_dn, ARG2(0,STR,SINT), NULL, SMP_T_STR, SMP_USE_L5CLI },
4813 { "ssl_f_key_alg", smp_fetch_ssl_x_key_alg, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
4814 { "ssl_f_notafter", smp_fetch_ssl_x_notafter, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
4815 { "ssl_f_notbefore", smp_fetch_ssl_x_notbefore, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
4816 { "ssl_f_sig_alg", smp_fetch_ssl_x_sig_alg, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
4817 { "ssl_f_s_dn", smp_fetch_ssl_x_s_dn, ARG2(0,STR,SINT), NULL, SMP_T_STR, SMP_USE_L5CLI },
4818 { "ssl_f_serial", smp_fetch_ssl_x_serial, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Emeric Brun55f4fa82014-04-30 17:11:25 +02004819 { "ssl_f_sha1", smp_fetch_ssl_x_sha1, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Emeric Brunba841a12014-04-30 17:05:08 +02004820 { "ssl_f_version", smp_fetch_ssl_x_version, 0, NULL, SMP_T_UINT, SMP_USE_L5CLI },
Willy Tarreau80aca902013-01-07 15:42:20 +01004821 { "ssl_fc", smp_fetch_ssl_fc, 0, NULL, SMP_T_BOOL, SMP_USE_L5CLI },
4822 { "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 +01004823 { "ssl_fc_cipher", smp_fetch_ssl_fc_cipher, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Willy Tarreau80aca902013-01-07 15:42:20 +01004824 { "ssl_fc_has_crt", smp_fetch_ssl_fc_has_crt, 0, NULL, SMP_T_BOOL, SMP_USE_L5CLI },
4825 { "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 +02004826#ifdef OPENSSL_NPN_NEGOTIATED
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01004827 { "ssl_fc_npn", smp_fetch_ssl_fc_npn, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Willy Tarreaua33c6542012-10-15 13:19:06 +02004828#endif
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01004829#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01004830 { "ssl_fc_alpn", smp_fetch_ssl_fc_alpn, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Willy Tarreauab861d32013-04-02 02:30:41 +02004831#endif
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01004832 { "ssl_fc_protocol", smp_fetch_ssl_fc_protocol, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Emeric Brunb73a9b02014-04-30 18:49:19 +02004833 { "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 +01004834 { "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 +01004835 { "ssl_fc_session_id", smp_fetch_ssl_fc_session_id, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
4836 { "ssl_fc_sni", smp_fetch_ssl_fc_sni, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Willy Tarreau7875d092012-09-10 08:20:03 +02004837 { NULL, NULL, 0, 0, 0 },
4838}};
4839
4840/* Note: must not be declared <const> as its list will be overwritten.
4841 * Please take care of keeping this list alphabetically sorted.
4842 */
Willy Tarreaudc13c112013-06-21 23:16:39 +02004843static struct acl_kw_list acl_kws = {ILH, {
Thierry FOURNIERc5a4e982014-03-05 16:07:08 +01004844 { "ssl_fc_sni_end", "ssl_fc_sni", PAT_MATCH_END },
4845 { "ssl_fc_sni_reg", "ssl_fc_sni", PAT_MATCH_REG },
Willy Tarreau8ed669b2013-01-11 15:49:37 +01004846 { /* END */ },
Willy Tarreau7875d092012-09-10 08:20:03 +02004847}};
4848
Willy Tarreau79eeafa2012-09-14 07:53:05 +02004849/* Note: must not be declared <const> as its list will be overwritten.
4850 * Please take care of keeping this list alphabetically sorted, doing so helps
4851 * all code contributors.
4852 * Optional keywords are also declared with a NULL ->parse() function so that
4853 * the config parser can report an appropriate error when a known keyword was
4854 * not enabled.
4855 */
Willy Tarreau51fb7652012-09-18 18:24:39 +02004856static struct bind_kw_list bind_kws = { "SSL", { }, {
Nenad Merdanovic05552d42015-02-27 19:56:49 +01004857 { "alpn", bind_parse_alpn, 1 }, /* set ALPN supported protocols */
4858 { "ca-file", bind_parse_ca_file, 1 }, /* set CAfile to process verify on client cert */
4859 { "ca-ignore-err", bind_parse_ignore_err, 1 }, /* set error IDs to ignore on verify depth > 0 */
4860 { "ciphers", bind_parse_ciphers, 1 }, /* set SSL cipher suite */
4861 { "crl-file", bind_parse_crl_file, 1 }, /* set certificat revocation list file use on client cert verify */
4862 { "crt", bind_parse_crt, 1 }, /* load SSL certificates from this location */
4863 { "crt-ignore-err", bind_parse_ignore_err, 1 }, /* set error IDs to ingore on verify depth == 0 */
4864 { "crt-list", bind_parse_crt_list, 1 }, /* load a list of crt from this location */
4865 { "ecdhe", bind_parse_ecdhe, 1 }, /* defines named curve for elliptic curve Diffie-Hellman */
4866 { "force-sslv3", bind_parse_force_sslv3, 0 }, /* force SSLv3 */
4867 { "force-tlsv10", bind_parse_force_tlsv10, 0 }, /* force TLSv10 */
4868 { "force-tlsv11", bind_parse_force_tlsv11, 0 }, /* force TLSv11 */
4869 { "force-tlsv12", bind_parse_force_tlsv12, 0 }, /* force TLSv12 */
4870 { "no-sslv3", bind_parse_no_sslv3, 0 }, /* disable SSLv3 */
4871 { "no-tlsv10", bind_parse_no_tlsv10, 0 }, /* disable TLSv10 */
4872 { "no-tlsv11", bind_parse_no_tlsv11, 0 }, /* disable TLSv11 */
4873 { "no-tlsv12", bind_parse_no_tlsv12, 0 }, /* disable TLSv12 */
4874 { "no-tls-tickets", bind_parse_no_tls_tickets, 0 }, /* disable session resumption tickets */
4875 { "ssl", bind_parse_ssl, 0 }, /* enable SSL processing */
4876 { "strict-sni", bind_parse_strict_sni, 0 }, /* refuse negotiation if sni doesn't match a certificate */
4877 { "tls-ticket-keys", bind_parse_tls_ticket_keys, 1 }, /* set file to load TLS ticket keys from */
4878 { "verify", bind_parse_verify, 1 }, /* set SSL verify method */
4879 { "npn", bind_parse_npn, 1 }, /* set NPN supported protocols */
Willy Tarreau79eeafa2012-09-14 07:53:05 +02004880 { NULL, NULL, 0 },
4881}};
Emeric Brun46591952012-05-18 15:47:34 +02004882
Willy Tarreau92faadf2012-10-10 23:04:25 +02004883/* Note: must not be declared <const> as its list will be overwritten.
4884 * Please take care of keeping this list alphabetically sorted, doing so helps
4885 * all code contributors.
4886 * Optional keywords are also declared with a NULL ->parse() function so that
4887 * the config parser can report an appropriate error when a known keyword was
4888 * not enabled.
4889 */
4890static struct srv_kw_list srv_kws = { "SSL", { }, {
Emeric Brunef42d922012-10-11 16:11:36 +02004891 { "ca-file", srv_parse_ca_file, 1, 0 }, /* set CAfile to process verify server cert */
Emeric Brunecc91fe2012-10-11 15:05:10 +02004892 { "check-ssl", srv_parse_check_ssl, 0, 0 }, /* enable SSL for health checks */
4893 { "ciphers", srv_parse_ciphers, 1, 0 }, /* select the cipher suite */
Emeric Brunef42d922012-10-11 16:11:36 +02004894 { "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 +02004895 { "crt", srv_parse_crt, 1, 0 }, /* set client certificate */
Emeric Brunecc91fe2012-10-11 15:05:10 +02004896 { "force-sslv3", srv_parse_force_sslv3, 0, 0 }, /* force SSLv3 */
4897 { "force-tlsv10", srv_parse_force_tlsv10, 0, 0 }, /* force TLSv10 */
4898 { "force-tlsv11", srv_parse_force_tlsv11, 0, 0 }, /* force TLSv11 */
4899 { "force-tlsv12", srv_parse_force_tlsv12, 0, 0 }, /* force TLSv12 */
Willy Tarreau2a3fb1c2015-02-05 16:47:07 +01004900 { "no-ssl-reuse", srv_parse_no_ssl_reuse, 0, 0 }, /* disable session reuse */
Emeric Brunecc91fe2012-10-11 15:05:10 +02004901 { "no-sslv3", srv_parse_no_sslv3, 0, 0 }, /* disable SSLv3 */
4902 { "no-tlsv10", srv_parse_no_tlsv10, 0, 0 }, /* disable TLSv10 */
4903 { "no-tlsv11", srv_parse_no_tlsv11, 0, 0 }, /* disable TLSv11 */
4904 { "no-tlsv12", srv_parse_no_tlsv12, 0, 0 }, /* disable TLSv12 */
Emeric Brunf9c5c472012-10-11 15:28:34 +02004905 { "no-tls-tickets", srv_parse_no_tls_tickets, 0, 0 }, /* disable session resumption tickets */
David Safb76832014-05-08 23:42:08 -04004906 { "send-proxy-v2-ssl", srv_parse_send_proxy_ssl, 0, 0 }, /* send PROXY protocol header v2 with SSL info */
4907 { "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 +02004908 { "ssl", srv_parse_ssl, 0, 0 }, /* enable SSL processing */
Emeric Brunef42d922012-10-11 16:11:36 +02004909 { "verify", srv_parse_verify, 1, 0 }, /* set SSL verify method */
Evan Broderbe554312013-06-27 00:05:25 -07004910 { "verifyhost", srv_parse_verifyhost, 1, 0 }, /* require that SSL cert verifies for hostname */
Willy Tarreau92faadf2012-10-10 23:04:25 +02004911 { NULL, NULL, 0, 0 },
4912}};
4913
Emeric Brun2c86cbf2014-10-30 15:56:50 +01004914static struct cfg_kw_list cfg_kws = {ILH, {
4915 { CFG_GLOBAL, "ssl-default-bind-options", ssl_parse_default_bind_options },
4916 { CFG_GLOBAL, "ssl-default-server-options", ssl_parse_default_server_options },
4917 { 0, NULL, NULL },
4918}};
4919
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02004920/* transport-layer operations for SSL sockets */
4921struct xprt_ops ssl_sock = {
Emeric Brun46591952012-05-18 15:47:34 +02004922 .snd_buf = ssl_sock_from_buf,
4923 .rcv_buf = ssl_sock_to_buf,
4924 .rcv_pipe = NULL,
4925 .snd_pipe = NULL,
4926 .shutr = NULL,
4927 .shutw = ssl_sock_shutw,
4928 .close = ssl_sock_close,
4929 .init = ssl_sock_init,
4930};
4931
Janusz Dziemidowicz2c701b52015-03-07 23:03:59 +01004932#if (OPENSSL_VERSION_NUMBER >= 0x1000200fL && !defined OPENSSL_NO_TLSEXT && !defined OPENSSL_IS_BORINGSSL)
4933
4934static void ssl_sock_sctl_free_func(void *parent, void *ptr, CRYPTO_EX_DATA *ad, int idx, long argl, void *argp)
4935{
4936 if (ptr) {
4937 chunk_destroy(ptr);
4938 free(ptr);
4939 }
4940}
4941
4942#endif
4943
Emeric Brun46591952012-05-18 15:47:34 +02004944__attribute__((constructor))
Willy Tarreau92faadf2012-10-10 23:04:25 +02004945static void __ssl_sock_init(void)
4946{
Emeric Brun46591952012-05-18 15:47:34 +02004947 STACK_OF(SSL_COMP)* cm;
4948
Willy Tarreau610f04b2014-02-13 11:36:41 +01004949#ifdef LISTEN_DEFAULT_CIPHERS
4950 global.listen_default_ciphers = LISTEN_DEFAULT_CIPHERS;
4951#endif
4952#ifdef CONNECT_DEFAULT_CIPHERS
4953 global.connect_default_ciphers = CONNECT_DEFAULT_CIPHERS;
4954#endif
4955 if (global.listen_default_ciphers)
4956 global.listen_default_ciphers = strdup(global.listen_default_ciphers);
4957 if (global.connect_default_ciphers)
4958 global.connect_default_ciphers = strdup(global.connect_default_ciphers);
Emeric Brun2c86cbf2014-10-30 15:56:50 +01004959 global.listen_default_ssloptions = BC_SSL_O_NONE;
4960 global.connect_default_ssloptions = SRV_SSL_O_NONE;
Willy Tarreau610f04b2014-02-13 11:36:41 +01004961
Emeric Brun46591952012-05-18 15:47:34 +02004962 SSL_library_init();
4963 cm = SSL_COMP_get_compression_methods();
4964 sk_SSL_COMP_zero(cm);
Janusz Dziemidowicz2c701b52015-03-07 23:03:59 +01004965#if (OPENSSL_VERSION_NUMBER >= 0x1000200fL && !defined OPENSSL_NO_TLSEXT && !defined OPENSSL_IS_BORINGSSL)
4966 sctl_ex_index = SSL_CTX_get_ex_new_index(0, NULL, NULL, NULL, ssl_sock_sctl_free_func);
4967#endif
Willy Tarreau7875d092012-09-10 08:20:03 +02004968 sample_register_fetches(&sample_fetch_keywords);
4969 acl_register_keywords(&acl_kws);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02004970 bind_register_keywords(&bind_kws);
Willy Tarreau92faadf2012-10-10 23:04:25 +02004971 srv_register_keywords(&srv_kws);
Emeric Brun2c86cbf2014-10-30 15:56:50 +01004972 cfg_register_keywords(&cfg_kws);
Willy Tarreaud92aa5c2015-01-15 21:34:39 +01004973
4974 global.ssl_session_max_cost = SSL_SESSION_MAX_COST;
4975 global.ssl_handshake_max_cost = SSL_HANDSHAKE_MAX_COST;
Emeric Brun46591952012-05-18 15:47:34 +02004976}
4977
4978/*
4979 * Local variables:
4980 * c-indent-level: 8
4981 * c-basic-offset: 8
4982 * End:
4983 */