blob: 75876a26d9875c7a8076c01de1882cb6bfd0c27d [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>
Christopher Faulet31af49d2015-06-09 17:29:50 +020038#include <netdb.h>
Emeric Brun46591952012-05-18 15:47:34 +020039#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
Remi Gacogne4f902b82015-05-28 16:23:00 +020050#ifndef OPENSSL_NO_DH
51#include <openssl/dh.h>
52#endif
Emeric Brun46591952012-05-18 15:47:34 +020053
Christopher Faulet31af49d2015-06-09 17:29:50 +020054#include <import/lru.h>
55#include <import/xxhash.h>
56
Emeric Brun46591952012-05-18 15:47:34 +020057#include <common/buffer.h>
58#include <common/compat.h>
59#include <common/config.h>
60#include <common/debug.h>
Willy Tarreau79eeafa2012-09-14 07:53:05 +020061#include <common/errors.h>
Emeric Brun46591952012-05-18 15:47:34 +020062#include <common/standard.h>
63#include <common/ticks.h>
64#include <common/time.h>
Emeric Brun2c86cbf2014-10-30 15:56:50 +010065#include <common/cfgparse.h>
Nenad Merdanovic05552d42015-02-27 19:56:49 +010066#include <common/base64.h>
Emeric Brun46591952012-05-18 15:47:34 +020067
Emeric Brunfc0421f2012-09-07 17:30:07 +020068#include <ebsttree.h>
69
70#include <types/global.h>
71#include <types/ssl_sock.h>
72
Willy Tarreau7875d092012-09-10 08:20:03 +020073#include <proto/acl.h>
74#include <proto/arg.h>
Emeric Brun46591952012-05-18 15:47:34 +020075#include <proto/connection.h>
76#include <proto/fd.h>
77#include <proto/freq_ctr.h>
78#include <proto/frontend.h>
Willy Tarreau79eeafa2012-09-14 07:53:05 +020079#include <proto/listener.h>
Thierry FOURNIERed66c292013-11-28 11:05:19 +010080#include <proto/pattern.h>
Christopher Faulet31af49d2015-06-09 17:29:50 +020081#include <proto/proto_tcp.h>
Willy Tarreau92faadf2012-10-10 23:04:25 +020082#include <proto/server.h>
Emeric Brun46591952012-05-18 15:47:34 +020083#include <proto/log.h>
Emeric Brun94324a42012-10-11 14:00:19 +020084#include <proto/proxy.h>
Emeric Brunfc0421f2012-09-07 17:30:07 +020085#include <proto/shctx.h>
Emeric Brun46591952012-05-18 15:47:34 +020086#include <proto/ssl_sock.h>
Willy Tarreau9ad7bd42015-04-03 19:19:59 +020087#include <proto/stream.h>
Emeric Brun46591952012-05-18 15:47:34 +020088#include <proto/task.h>
89
Willy Tarreau518cedd2014-02-17 15:43:01 +010090/* Warning, these are bits, not integers! */
Emeric Brune64aef12012-09-21 13:15:06 +020091#define SSL_SOCK_ST_FL_VERIFY_DONE 0x00000001
Emeric Brund8b2bb52014-01-28 15:43:53 +010092#define SSL_SOCK_ST_FL_16K_WBFSIZE 0x00000002
Willy Tarreau518cedd2014-02-17 15:43:01 +010093#define SSL_SOCK_SEND_UNLIMITED 0x00000004
Emeric Brun29f037d2014-04-25 19:05:36 +020094#define SSL_SOCK_RECV_HEARTBEAT 0x00000008
95
Emeric Brunf282a812012-09-21 15:27:54 +020096/* bits 0xFFFF0000 are reserved to store verify errors */
97
98/* Verify errors macros */
99#define SSL_SOCK_CA_ERROR_TO_ST(e) (((e > 63) ? 63 : e) << (16))
100#define SSL_SOCK_CAEDEPTH_TO_ST(d) (((d > 15) ? 15 : d) << (6+16))
101#define SSL_SOCK_CRTERROR_TO_ST(e) (((e > 63) ? 63 : e) << (4+6+16))
102
103#define SSL_SOCK_ST_TO_CA_ERROR(s) ((s >> (16)) & 63)
104#define SSL_SOCK_ST_TO_CAEDEPTH(s) ((s >> (6+16)) & 15)
105#define SSL_SOCK_ST_TO_CRTERROR(s) ((s >> (4+6+16)) & 63)
Emeric Brune64aef12012-09-21 13:15:06 +0200106
Nenad Merdanovic05552d42015-02-27 19:56:49 +0100107/* Supported hash function for TLS tickets */
108#ifdef OPENSSL_NO_SHA256
109#define HASH_FUNCT EVP_sha1
110#else
111#define HASH_FUNCT EVP_sha256
112#endif /* OPENSSL_NO_SHA256 */
113
Emeric Brun850efd52014-01-29 12:24:34 +0100114/* server and bind verify method, it uses a global value as default */
115enum {
116 SSL_SOCK_VERIFY_DEFAULT = 0,
117 SSL_SOCK_VERIFY_REQUIRED = 1,
118 SSL_SOCK_VERIFY_OPTIONAL = 2,
119 SSL_SOCK_VERIFY_NONE = 3,
120};
121
Willy Tarreau71b734c2014-01-28 15:19:44 +0100122int sslconns = 0;
123int totalsslconns = 0;
Emeric Brune1f38db2012-09-03 20:36:47 +0200124
Nenad Merdanovic200b0fa2015-05-09 08:46:01 +0200125#if (defined SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB && TLS_TICKETS_NO > 0)
126struct list tlskeys_reference = LIST_HEAD_INIT(tlskeys_reference);
127#endif
128
Remi Gacogne8de54152014-07-15 11:36:40 +0200129#ifndef OPENSSL_NO_DH
Remi Gacogne4f902b82015-05-28 16:23:00 +0200130static int ssl_dh_ptr_index = -1;
Remi Gacogne47783ef2015-05-29 15:53:22 +0200131static DH *global_dh = NULL;
Remi Gacogne8de54152014-07-15 11:36:40 +0200132static DH *local_dh_1024 = NULL;
133static DH *local_dh_2048 = NULL;
134static DH *local_dh_4096 = NULL;
Remi Gacogne8de54152014-07-15 11:36:40 +0200135#endif /* OPENSSL_NO_DH */
136
Lukas Tribuse4e30f72014-12-09 16:32:51 +0100137#if (defined SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB && !defined OPENSSL_NO_OCSP)
Emeric Brun4147b2e2014-06-16 18:36:30 +0200138struct certificate_ocsp {
139 struct ebmb_node key;
140 unsigned char key_data[OCSP_MAX_CERTID_ASN1_LENGTH];
141 struct chunk response;
Emeric Brun4f3c87a2014-06-20 15:46:13 +0200142 long expire;
Emeric Brun4147b2e2014-06-16 18:36:30 +0200143};
144
Christopher Faulet31af49d2015-06-09 17:29:50 +0200145/* X509V3 Extensions that will be added on generated certificates */
146#define X509V3_EXT_SIZE 5
147static char *x509v3_ext_names[X509V3_EXT_SIZE] = {
148 "basicConstraints",
149 "nsComment",
150 "subjectKeyIdentifier",
151 "authorityKeyIdentifier",
152 "keyUsage",
153};
154static char *x509v3_ext_values[X509V3_EXT_SIZE] = {
155 "CA:FALSE",
156 "\"OpenSSL Generated Certificate\"",
157 "hash",
158 "keyid,issuer:always",
159 "nonRepudiation,digitalSignature,keyEncipherment"
160};
161
162/* LRU cache to store generated certificate */
163static struct lru64_head *ssl_ctx_lru_tree = NULL;
164static unsigned int ssl_ctx_lru_seed = 0;
165
Emeric Brun4f3c87a2014-06-20 15:46:13 +0200166/*
167 * This function returns the number of seconds elapsed
168 * since the Epoch, 1970-01-01 00:00:00 +0000 (UTC) and the
169 * date presented un ASN1_GENERALIZEDTIME.
170 *
171 * In parsing error case, it returns -1.
172 */
173static long asn1_generalizedtime_to_epoch(ASN1_GENERALIZEDTIME *d)
174{
175 long epoch;
176 char *p, *end;
177 const unsigned short month_offset[12] = {
178 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334
179 };
180 int year, month;
181
182 if (!d || (d->type != V_ASN1_GENERALIZEDTIME)) return -1;
183
184 p = (char *)d->data;
185 end = p + d->length;
186
187 if (end - p < 4) return -1;
188 year = 1000 * (p[0] - '0') + 100 * (p[1] - '0') + 10 * (p[2] - '0') + p[3] - '0';
189 p += 4;
190 if (end - p < 2) return -1;
191 month = 10 * (p[0] - '0') + p[1] - '0';
192 if (month < 1 || month > 12) return -1;
193 /* Compute the number of seconds since 1 jan 1970 and the beginning of current month
194 We consider leap years and the current month (<marsh or not) */
195 epoch = ( ((year - 1970) * 365)
196 + ((year - (month < 3)) / 4 - (year - (month < 3)) / 100 + (year - (month < 3)) / 400)
197 - ((1970 - 1) / 4 - (1970 - 1) / 100 + (1970 - 1) / 400)
198 + month_offset[month-1]
199 ) * 24 * 60 * 60;
200 p += 2;
201 if (end - p < 2) return -1;
202 /* Add the number of seconds of completed days of current month */
203 epoch += (10 * (p[0] - '0') + p[1] - '0' - 1) * 24 * 60 * 60;
204 p += 2;
205 if (end - p < 2) return -1;
206 /* Add the completed hours of the current day */
207 epoch += (10 * (p[0] - '0') + p[1] - '0') * 60 * 60;
208 p += 2;
209 if (end - p < 2) return -1;
210 /* Add the completed minutes of the current hour */
211 epoch += (10 * (p[0] - '0') + p[1] - '0') * 60;
212 p += 2;
213 if (p == end) return -1;
214 /* Test if there is available seconds */
215 if (p[0] < '0' || p[0] > '9')
216 goto nosec;
217 if (end - p < 2) return -1;
218 /* Add the seconds of the current minute */
219 epoch += 10 * (p[0] - '0') + p[1] - '0';
220 p += 2;
221 if (p == end) return -1;
222 /* Ignore seconds float part if present */
223 if (p[0] == '.') {
224 do {
225 if (++p == end) return -1;
226 } while (p[0] >= '0' && p[0] <= '9');
227 }
228
229nosec:
230 if (p[0] == 'Z') {
231 if (end - p != 1) return -1;
232 return epoch;
233 }
234 else if (p[0] == '+') {
235 if (end - p != 5) return -1;
236 /* Apply timezone offset */
237 return epoch - ((10 * (p[1] - '0') + p[2] - '0') * 60 + (10 * (p[3] - '0') + p[4] - '0')) * 60;
238 }
239 else if (p[0] == '-') {
240 if (end - p != 5) return -1;
241 /* Apply timezone offset */
242 return epoch + ((10 * (p[1] - '0') + p[2] - '0') * 60 + (10 * (p[3] - '0') + p[4] - '0')) * 60;
243 }
244
245 return -1;
246}
247
Emeric Brun1d3865b2014-06-20 15:37:32 +0200248static struct eb_root cert_ocsp_tree = EB_ROOT_UNIQUE;
Emeric Brun4147b2e2014-06-16 18:36:30 +0200249
250/* This function starts to check if the OCSP response (in DER format) contained
251 * in chunk 'ocsp_response' is valid (else exits on error).
252 * If 'cid' is not NULL, it will be compared to the OCSP certificate ID
253 * contained in the OCSP Response and exits on error if no match.
254 * If it's a valid OCSP Response:
255 * If 'ocsp' is not NULL, the chunk is copied in the OCSP response's container
256 * pointed by 'ocsp'.
257 * If 'ocsp' is NULL, the function looks up into the OCSP response's
258 * containers tree (using as index the ASN1 form of the OCSP Certificate ID extracted
259 * from the response) and exits on error if not found. Finally, If an OCSP response is
260 * already present in the container, it will be overwritten.
261 *
262 * Note: OCSP response containing more than one OCSP Single response is not
263 * considered valid.
264 *
265 * Returns 0 on success, 1 in error case.
266 */
267static int ssl_sock_load_ocsp_response(struct chunk *ocsp_response, struct certificate_ocsp *ocsp, OCSP_CERTID *cid, char **err)
268{
269 OCSP_RESPONSE *resp;
270 OCSP_BASICRESP *bs = NULL;
271 OCSP_SINGLERESP *sr;
272 unsigned char *p = (unsigned char *)ocsp_response->str;
273 int rc , count_sr;
Emeric Brun13a6b482014-06-20 15:44:34 +0200274 ASN1_GENERALIZEDTIME *revtime, *thisupd, *nextupd = NULL;
Emeric Brun4147b2e2014-06-16 18:36:30 +0200275 int reason;
276 int ret = 1;
277
278 resp = d2i_OCSP_RESPONSE(NULL, (const unsigned char **)&p, ocsp_response->len);
279 if (!resp) {
280 memprintf(err, "Unable to parse OCSP response");
281 goto out;
282 }
283
284 rc = OCSP_response_status(resp);
285 if (rc != OCSP_RESPONSE_STATUS_SUCCESSFUL) {
286 memprintf(err, "OCSP response status not successful");
287 goto out;
288 }
289
290 bs = OCSP_response_get1_basic(resp);
291 if (!bs) {
292 memprintf(err, "Failed to get basic response from OCSP Response");
293 goto out;
294 }
295
296 count_sr = OCSP_resp_count(bs);
297 if (count_sr > 1) {
298 memprintf(err, "OCSP response ignored because contains multiple single responses (%d)", count_sr);
299 goto out;
300 }
301
302 sr = OCSP_resp_get0(bs, 0);
303 if (!sr) {
304 memprintf(err, "Failed to get OCSP single response");
305 goto out;
306 }
307
308 rc = OCSP_single_get0_status(sr, &reason, &revtime, &thisupd, &nextupd);
309 if (rc != V_OCSP_CERTSTATUS_GOOD) {
310 memprintf(err, "OCSP single response: certificate status not good");
311 goto out;
312 }
313
Emeric Brun13a6b482014-06-20 15:44:34 +0200314 if (!nextupd) {
315 memprintf(err, "OCSP single response: missing nextupdate");
316 goto out;
317 }
318
Emeric Brunc8b27b62014-06-19 14:16:17 +0200319 rc = OCSP_check_validity(thisupd, nextupd, OCSP_MAX_RESPONSE_TIME_SKEW, -1);
Emeric Brun4147b2e2014-06-16 18:36:30 +0200320 if (!rc) {
321 memprintf(err, "OCSP single response: no longer valid.");
322 goto out;
323 }
324
325 if (cid) {
326 if (OCSP_id_cmp(sr->certId, cid)) {
327 memprintf(err, "OCSP single response: Certificate ID does not match certificate and issuer");
328 goto out;
329 }
330 }
331
332 if (!ocsp) {
333 unsigned char key[OCSP_MAX_CERTID_ASN1_LENGTH];
334 unsigned char *p;
335
336 rc = i2d_OCSP_CERTID(sr->certId, NULL);
337 if (!rc) {
338 memprintf(err, "OCSP single response: Unable to encode Certificate ID");
339 goto out;
340 }
341
342 if (rc > OCSP_MAX_CERTID_ASN1_LENGTH) {
343 memprintf(err, "OCSP single response: Certificate ID too long");
344 goto out;
345 }
346
347 p = key;
348 memset(key, 0, OCSP_MAX_CERTID_ASN1_LENGTH);
349 i2d_OCSP_CERTID(sr->certId, &p);
350 ocsp = (struct certificate_ocsp *)ebmb_lookup(&cert_ocsp_tree, key, OCSP_MAX_CERTID_ASN1_LENGTH);
351 if (!ocsp) {
352 memprintf(err, "OCSP single response: Certificate ID does not match any certificate or issuer");
353 goto out;
354 }
355 }
356
357 /* According to comments on "chunk_dup", the
358 previous chunk buffer will be freed */
359 if (!chunk_dup(&ocsp->response, ocsp_response)) {
360 memprintf(err, "OCSP response: Memory allocation error");
361 goto out;
362 }
363
Emeric Brun4f3c87a2014-06-20 15:46:13 +0200364 ocsp->expire = asn1_generalizedtime_to_epoch(nextupd) - OCSP_MAX_RESPONSE_TIME_SKEW;
365
Emeric Brun4147b2e2014-06-16 18:36:30 +0200366 ret = 0;
367out:
368 if (bs)
369 OCSP_BASICRESP_free(bs);
370
371 if (resp)
372 OCSP_RESPONSE_free(resp);
373
374 return ret;
375}
376/*
377 * External function use to update the OCSP response in the OCSP response's
378 * containers tree. The chunk 'ocsp_response' must contain the OCSP response
379 * to update in DER format.
380 *
381 * Returns 0 on success, 1 in error case.
382 */
383int ssl_sock_update_ocsp_response(struct chunk *ocsp_response, char **err)
384{
385 return ssl_sock_load_ocsp_response(ocsp_response, NULL, NULL, err);
386}
387
388/*
389 * This function load the OCSP Resonse in DER format contained in file at
390 * path 'ocsp_path' and call 'ssl_sock_load_ocsp_response'
391 *
392 * Returns 0 on success, 1 in error case.
393 */
394static int ssl_sock_load_ocsp_response_from_file(const char *ocsp_path, struct certificate_ocsp *ocsp, OCSP_CERTID *cid, char **err)
395{
396 int fd = -1;
397 int r = 0;
398 int ret = 1;
399
400 fd = open(ocsp_path, O_RDONLY);
401 if (fd == -1) {
402 memprintf(err, "Error opening OCSP response file");
403 goto end;
404 }
405
406 trash.len = 0;
407 while (trash.len < trash.size) {
408 r = read(fd, trash.str + trash.len, trash.size - trash.len);
409 if (r < 0) {
410 if (errno == EINTR)
411 continue;
412
413 memprintf(err, "Error reading OCSP response from file");
414 goto end;
415 }
416 else if (r == 0) {
417 break;
418 }
419 trash.len += r;
420 }
421
422 close(fd);
423 fd = -1;
424
425 ret = ssl_sock_load_ocsp_response(&trash, ocsp, cid, err);
426end:
427 if (fd != -1)
428 close(fd);
429
430 return ret;
431}
432
Nenad Merdanovic05552d42015-02-27 19:56:49 +0100433#if (defined SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB && TLS_TICKETS_NO > 0)
434static 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)
435{
436 struct tls_sess_key *keys;
437 struct connection *conn;
438 int head;
439 int i;
440
441 conn = (struct connection *)SSL_get_app_data(s);
Nenad Merdanovic146defa2015-05-09 08:46:00 +0200442 keys = objt_listener(conn->target)->bind_conf->keys_ref->tlskeys;
443 head = objt_listener(conn->target)->bind_conf->keys_ref->tls_ticket_enc_index;
Nenad Merdanovic05552d42015-02-27 19:56:49 +0100444
445 if (enc) {
446 memcpy(key_name, keys[head].name, 16);
447
448 if(!RAND_pseudo_bytes(iv, EVP_MAX_IV_LENGTH))
449 return -1;
450
451 if(!EVP_EncryptInit_ex(ectx, EVP_aes_128_cbc(), NULL, keys[head].aes_key, iv))
452 return -1;
453
454 HMAC_Init_ex(hctx, keys[head].hmac_key, 16, HASH_FUNCT(), NULL);
455
456 return 1;
457 } else {
458 for (i = 0; i < TLS_TICKETS_NO; i++) {
459 if (!memcmp(key_name, keys[(head + i) % TLS_TICKETS_NO].name, 16))
460 goto found;
461 }
462 return 0;
463
464 found:
465 HMAC_Init_ex(hctx, keys[(head + i) % TLS_TICKETS_NO].hmac_key, 16, HASH_FUNCT(), NULL);
466 if(!EVP_DecryptInit_ex(ectx, EVP_aes_128_cbc(), NULL, keys[(head + i) % TLS_TICKETS_NO].aes_key, iv))
467 return -1;
468 /* 2 for key renewal, 1 if current key is still valid */
469 return i ? 2 : 1;
470 }
Nenad Merdanovic200b0fa2015-05-09 08:46:01 +0200471}
472
473struct tls_keys_ref *tlskeys_ref_lookup(const char *filename)
474{
475 struct tls_keys_ref *ref;
476
477 list_for_each_entry(ref, &tlskeys_reference, list)
478 if (ref->filename && strcmp(filename, ref->filename) == 0)
479 return ref;
480 return NULL;
481}
482
483struct tls_keys_ref *tlskeys_ref_lookupid(int unique_id)
484{
485 struct tls_keys_ref *ref;
486
487 list_for_each_entry(ref, &tlskeys_reference, list)
488 if (ref->unique_id == unique_id)
489 return ref;
490 return NULL;
491}
492
493int ssl_sock_update_tlskey(char *filename, struct chunk *tlskey, char **err) {
494 struct tls_keys_ref *ref = tlskeys_ref_lookup(filename);
495
496 if(!ref) {
497 memprintf(err, "Unable to locate the referenced filename: %s", filename);
498 return 1;
499 }
500
501 memcpy((char *) (ref->tlskeys + 2 % TLS_TICKETS_NO), tlskey->str, tlskey->len);
502 ref->tls_ticket_enc_index = ref->tls_ticket_enc_index + 1 % TLS_TICKETS_NO;
503
504 return 0;
Nenad Merdanovic05552d42015-02-27 19:56:49 +0100505}
Nenad Merdanovic200b0fa2015-05-09 08:46:01 +0200506
507/* This function finalize the configuration parsing. Its set all the
508 * automatic ids
509 */
510void tlskeys_finalize_config(void)
511{
512 int i = 0;
513 struct tls_keys_ref *ref, *ref2, *ref3;
514 struct list tkr = LIST_HEAD_INIT(tkr);
515
516 list_for_each_entry(ref, &tlskeys_reference, list) {
517 if (ref->unique_id == -1) {
518 /* Look for the first free id. */
519 while (1) {
520 list_for_each_entry(ref2, &tlskeys_reference, list) {
521 if (ref2->unique_id == i) {
522 i++;
523 break;
524 }
525 }
526 if (&ref2->list == &tlskeys_reference)
527 break;
528 }
529
530 /* Uses the unique id and increment it for the next entry. */
531 ref->unique_id = i;
532 i++;
533 }
534 }
535
536 /* This sort the reference list by id. */
537 list_for_each_entry_safe(ref, ref2, &tlskeys_reference, list) {
538 LIST_DEL(&ref->list);
539 list_for_each_entry(ref3, &tkr, list) {
540 if (ref->unique_id < ref3->unique_id) {
541 LIST_ADDQ(&ref3->list, &ref->list);
542 break;
543 }
544 }
545 if (&ref3->list == &tkr)
546 LIST_ADDQ(&tkr, &ref->list);
547 }
548
549 /* swap root */
550 LIST_ADD(&tkr, &tlskeys_reference);
551 LIST_DEL(&tkr);
552}
553
Nenad Merdanovic05552d42015-02-27 19:56:49 +0100554#endif /* SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB */
555
Emeric Brun4147b2e2014-06-16 18:36:30 +0200556/*
557 * Callback used to set OCSP status extension content in server hello.
558 */
559int ssl_sock_ocsp_stapling_cbk(SSL *ssl, void *arg)
560{
561 struct certificate_ocsp *ocsp = (struct certificate_ocsp *)arg;
562 char* ssl_buf;
563
564 if (!ocsp ||
565 !ocsp->response.str ||
Emeric Brun4f3c87a2014-06-20 15:46:13 +0200566 !ocsp->response.len ||
567 (ocsp->expire < now.tv_sec))
Emeric Brun4147b2e2014-06-16 18:36:30 +0200568 return SSL_TLSEXT_ERR_NOACK;
569
570 ssl_buf = OPENSSL_malloc(ocsp->response.len);
571 if (!ssl_buf)
572 return SSL_TLSEXT_ERR_NOACK;
573
574 memcpy(ssl_buf, ocsp->response.str, ocsp->response.len);
575 SSL_set_tlsext_status_ocsp_resp(ssl, ssl_buf, ocsp->response.len);
576
577 return SSL_TLSEXT_ERR_OK;
578}
579
580/*
581 * This function enables the handling of OCSP status extension on 'ctx' if a
582 * file name 'cert_path' suffixed using ".ocsp" is present.
583 * To enable OCSP status extension, the issuer's certificate is mandatory.
584 * It should be present in the certificate's extra chain builded from file
585 * 'cert_path'. If not found, the issuer certificate is loaded from a file
586 * named 'cert_path' suffixed using '.issuer'.
587 *
588 * In addition, ".ocsp" file content is loaded as a DER format of an OCSP
589 * response. If file is empty or content is not a valid OCSP response,
590 * OCSP status extension is enabled but OCSP response is ignored (a warning
591 * is displayed).
592 *
593 * Returns 1 if no ".ocsp" file found, 0 if OCSP status extension is
594 * succesfully enabled, or -1 in other error case.
595 */
596static int ssl_sock_load_ocsp(SSL_CTX *ctx, const char *cert_path)
597{
598
599 BIO *in = NULL;
600 X509 *x, *xi = NULL, *issuer = NULL;
601 STACK_OF(X509) *chain = NULL;
602 OCSP_CERTID *cid = NULL;
603 SSL *ssl;
604 char ocsp_path[MAXPATHLEN+1];
605 int i, ret = -1;
606 struct stat st;
607 struct certificate_ocsp *ocsp = NULL, *iocsp;
608 char *warn = NULL;
609 unsigned char *p;
610
611 snprintf(ocsp_path, MAXPATHLEN+1, "%s.ocsp", cert_path);
612
613 if (stat(ocsp_path, &st))
614 return 1;
615
616 ssl = SSL_new(ctx);
617 if (!ssl)
618 goto out;
619
620 x = SSL_get_certificate(ssl);
621 if (!x)
622 goto out;
623
624 /* Try to lookup for issuer in certificate extra chain */
625#ifdef SSL_CTRL_GET_EXTRA_CHAIN_CERTS
626 SSL_CTX_get_extra_chain_certs(ctx, &chain);
627#else
628 chain = ctx->extra_certs;
629#endif
630 for (i = 0; i < sk_X509_num(chain); i++) {
631 issuer = sk_X509_value(chain, i);
632 if (X509_check_issued(issuer, x) == X509_V_OK)
633 break;
634 else
635 issuer = NULL;
636 }
637
638 /* If not found try to load issuer from a suffixed file */
639 if (!issuer) {
640 char issuer_path[MAXPATHLEN+1];
641
642 in = BIO_new(BIO_s_file());
643 if (!in)
644 goto out;
645
646 snprintf(issuer_path, MAXPATHLEN+1, "%s.issuer", cert_path);
647 if (BIO_read_filename(in, issuer_path) <= 0)
648 goto out;
649
650 xi = PEM_read_bio_X509_AUX(in, NULL, ctx->default_passwd_callback, ctx->default_passwd_callback_userdata);
651 if (!xi)
652 goto out;
653
654 if (X509_check_issued(xi, x) != X509_V_OK)
655 goto out;
656
657 issuer = xi;
658 }
659
660 cid = OCSP_cert_to_id(0, x, issuer);
661 if (!cid)
662 goto out;
663
664 i = i2d_OCSP_CERTID(cid, NULL);
665 if (!i || (i > OCSP_MAX_CERTID_ASN1_LENGTH))
666 goto out;
667
668 ocsp = calloc(1, sizeof(struct certificate_ocsp));
669 if (!ocsp)
670 goto out;
671
672 p = ocsp->key_data;
673 i2d_OCSP_CERTID(cid, &p);
674
675 iocsp = (struct certificate_ocsp *)ebmb_insert(&cert_ocsp_tree, &ocsp->key, OCSP_MAX_CERTID_ASN1_LENGTH);
676 if (iocsp == ocsp)
677 ocsp = NULL;
678
679 SSL_CTX_set_tlsext_status_cb(ctx, ssl_sock_ocsp_stapling_cbk);
680 SSL_CTX_set_tlsext_status_arg(ctx, iocsp);
681
682 ret = 0;
683
684 warn = NULL;
685 if (ssl_sock_load_ocsp_response_from_file(ocsp_path, iocsp, cid, &warn)) {
686 memprintf(&warn, "Loading '%s': %s. Content will be ignored", ocsp_path, warn ? warn : "failure");
687 Warning("%s.\n", warn);
688 }
689
690out:
691 if (ssl)
692 SSL_free(ssl);
693
694 if (in)
695 BIO_free(in);
696
697 if (xi)
698 X509_free(xi);
699
700 if (cid)
701 OCSP_CERTID_free(cid);
702
703 if (ocsp)
704 free(ocsp);
705
706 if (warn)
707 free(warn);
708
709
710 return ret;
711}
712
713#endif
714
Janusz Dziemidowicz2c701b52015-03-07 23:03:59 +0100715#if (OPENSSL_VERSION_NUMBER >= 0x1000200fL && !defined OPENSSL_NO_TLSEXT && !defined OPENSSL_IS_BORINGSSL)
716
717#define CT_EXTENSION_TYPE 18
718
719static int sctl_ex_index = -1;
720
721/*
722 * Try to parse Signed Certificate Timestamp List structure. This function
723 * makes only basic test if the data seems like SCTL. No signature validation
724 * is performed.
725 */
726static int ssl_sock_parse_sctl(struct chunk *sctl)
727{
728 int ret = 1;
729 int len, pos, sct_len;
730 unsigned char *data;
731
732 if (sctl->len < 2)
733 goto out;
734
735 data = (unsigned char *)sctl->str;
736 len = (data[0] << 8) | data[1];
737
738 if (len + 2 != sctl->len)
739 goto out;
740
741 data = data + 2;
742 pos = 0;
743 while (pos < len) {
744 if (len - pos < 2)
745 goto out;
746
747 sct_len = (data[pos] << 8) | data[pos + 1];
748 if (pos + sct_len + 2 > len)
749 goto out;
750
751 pos += sct_len + 2;
752 }
753
754 ret = 0;
755
756out:
757 return ret;
758}
759
760static int ssl_sock_load_sctl_from_file(const char *sctl_path, struct chunk **sctl)
761{
762 int fd = -1;
763 int r = 0;
764 int ret = 1;
765
766 *sctl = NULL;
767
768 fd = open(sctl_path, O_RDONLY);
769 if (fd == -1)
770 goto end;
771
772 trash.len = 0;
773 while (trash.len < trash.size) {
774 r = read(fd, trash.str + trash.len, trash.size - trash.len);
775 if (r < 0) {
776 if (errno == EINTR)
777 continue;
778
779 goto end;
780 }
781 else if (r == 0) {
782 break;
783 }
784 trash.len += r;
785 }
786
787 ret = ssl_sock_parse_sctl(&trash);
788 if (ret)
789 goto end;
790
791 *sctl = calloc(1, sizeof(struct chunk));
792 if (!chunk_dup(*sctl, &trash)) {
793 free(*sctl);
794 *sctl = NULL;
795 goto end;
796 }
797
798end:
799 if (fd != -1)
800 close(fd);
801
802 return ret;
803}
804
805int ssl_sock_sctl_add_cbk(SSL *ssl, unsigned ext_type, const unsigned char **out, size_t *outlen, int *al, void *add_arg)
806{
807 struct chunk *sctl = (struct chunk *)add_arg;
808
809 *out = (unsigned char *)sctl->str;
810 *outlen = sctl->len;
811
812 return 1;
813}
814
815int ssl_sock_sctl_parse_cbk(SSL *s, unsigned int ext_type, const unsigned char *in, size_t inlen, int *al, void *parse_arg)
816{
817 return 1;
818}
819
820static int ssl_sock_load_sctl(SSL_CTX *ctx, const char *cert_path)
821{
822 char sctl_path[MAXPATHLEN+1];
823 int ret = -1;
824 struct stat st;
825 struct chunk *sctl = NULL;
826
827 snprintf(sctl_path, MAXPATHLEN+1, "%s.sctl", cert_path);
828
829 if (stat(sctl_path, &st))
830 return 1;
831
832 if (ssl_sock_load_sctl_from_file(sctl_path, &sctl))
833 goto out;
834
835 if (!SSL_CTX_add_server_custom_ext(ctx, CT_EXTENSION_TYPE, ssl_sock_sctl_add_cbk, NULL, sctl, ssl_sock_sctl_parse_cbk, NULL)) {
836 free(sctl);
837 goto out;
838 }
839
840 SSL_CTX_set_ex_data(ctx, sctl_ex_index, sctl);
841
842 ret = 0;
843
844out:
845 return ret;
846}
847
848#endif
849
Emeric Brune1f38db2012-09-03 20:36:47 +0200850void ssl_sock_infocbk(const SSL *ssl, int where, int ret)
851{
852 struct connection *conn = (struct connection *)SSL_get_app_data(ssl);
Emeric Brund8b2bb52014-01-28 15:43:53 +0100853 BIO *write_bio;
Willy Tarreau622317d2015-02-27 16:36:16 +0100854 (void)ret; /* shut gcc stupid warning */
Emeric Brune1f38db2012-09-03 20:36:47 +0200855
856 if (where & SSL_CB_HANDSHAKE_START) {
857 /* Disable renegotiation (CVE-2009-3555) */
Willy Tarreau20879a02012-12-03 16:32:10 +0100858 if (conn->flags & CO_FL_CONNECTED) {
Emeric Brune1f38db2012-09-03 20:36:47 +0200859 conn->flags |= CO_FL_ERROR;
Willy Tarreau20879a02012-12-03 16:32:10 +0100860 conn->err_code = CO_ER_SSL_RENEG;
861 }
Emeric Brune1f38db2012-09-03 20:36:47 +0200862 }
Emeric Brund8b2bb52014-01-28 15:43:53 +0100863
864 if ((where & SSL_CB_ACCEPT_LOOP) == SSL_CB_ACCEPT_LOOP) {
865 if (!(conn->xprt_st & SSL_SOCK_ST_FL_16K_WBFSIZE)) {
866 /* Long certificate chains optimz
867 If write and read bios are differents, we
868 consider that the buffering was activated,
869 so we rise the output buffer size from 4k
870 to 16k */
871 write_bio = SSL_get_wbio(ssl);
872 if (write_bio != SSL_get_rbio(ssl)) {
873 BIO_set_write_buffer_size(write_bio, 16384);
874 conn->xprt_st |= SSL_SOCK_ST_FL_16K_WBFSIZE;
875 }
876 }
877 }
Emeric Brunfc0421f2012-09-07 17:30:07 +0200878}
879
Emeric Brune64aef12012-09-21 13:15:06 +0200880/* Callback is called for each certificate of the chain during a verify
881 ok is set to 1 if preverify detect no error on current certificate.
882 Returns 0 to break the handshake, 1 otherwise. */
Evan Broderbe554312013-06-27 00:05:25 -0700883int ssl_sock_bind_verifycbk(int ok, X509_STORE_CTX *x_store)
Emeric Brune64aef12012-09-21 13:15:06 +0200884{
885 SSL *ssl;
886 struct connection *conn;
Emeric Brun81c00f02012-09-21 14:31:21 +0200887 int err, depth;
Emeric Brune64aef12012-09-21 13:15:06 +0200888
889 ssl = X509_STORE_CTX_get_ex_data(x_store, SSL_get_ex_data_X509_STORE_CTX_idx());
890 conn = (struct connection *)SSL_get_app_data(ssl);
891
Willy Tarreauf7bc57c2012-10-03 00:19:48 +0200892 conn->xprt_st |= SSL_SOCK_ST_FL_VERIFY_DONE;
Emeric Brune64aef12012-09-21 13:15:06 +0200893
Emeric Brun81c00f02012-09-21 14:31:21 +0200894 if (ok) /* no errors */
895 return ok;
896
897 depth = X509_STORE_CTX_get_error_depth(x_store);
898 err = X509_STORE_CTX_get_error(x_store);
899
900 /* check if CA error needs to be ignored */
901 if (depth > 0) {
Willy Tarreauf7bc57c2012-10-03 00:19:48 +0200902 if (!SSL_SOCK_ST_TO_CA_ERROR(conn->xprt_st)) {
903 conn->xprt_st |= SSL_SOCK_CA_ERROR_TO_ST(err);
904 conn->xprt_st |= SSL_SOCK_CAEDEPTH_TO_ST(depth);
Emeric Brunf282a812012-09-21 15:27:54 +0200905 }
906
Emeric Brun1eb20ef2012-12-03 13:24:29 +0100907 if (objt_listener(conn->target)->bind_conf->ca_ignerr & (1ULL << err)) {
908 ERR_clear_error();
Emeric Brun81c00f02012-09-21 14:31:21 +0200909 return 1;
Emeric Brun1eb20ef2012-12-03 13:24:29 +0100910 }
Emeric Brun81c00f02012-09-21 14:31:21 +0200911
Willy Tarreau20879a02012-12-03 16:32:10 +0100912 conn->err_code = CO_ER_SSL_CA_FAIL;
Emeric Brun81c00f02012-09-21 14:31:21 +0200913 return 0;
914 }
915
Willy Tarreauf7bc57c2012-10-03 00:19:48 +0200916 if (!SSL_SOCK_ST_TO_CRTERROR(conn->xprt_st))
917 conn->xprt_st |= SSL_SOCK_CRTERROR_TO_ST(err);
Emeric Brunf282a812012-09-21 15:27:54 +0200918
Emeric Brun81c00f02012-09-21 14:31:21 +0200919 /* check if certificate error needs to be ignored */
Emeric Brun1eb20ef2012-12-03 13:24:29 +0100920 if (objt_listener(conn->target)->bind_conf->crt_ignerr & (1ULL << err)) {
921 ERR_clear_error();
Emeric Brun81c00f02012-09-21 14:31:21 +0200922 return 1;
Emeric Brun1eb20ef2012-12-03 13:24:29 +0100923 }
Emeric Brun81c00f02012-09-21 14:31:21 +0200924
Willy Tarreau20879a02012-12-03 16:32:10 +0100925 conn->err_code = CO_ER_SSL_CRT_FAIL;
Emeric Brun81c00f02012-09-21 14:31:21 +0200926 return 0;
Emeric Brune64aef12012-09-21 13:15:06 +0200927}
928
Emeric Brun29f037d2014-04-25 19:05:36 +0200929/* Callback is called for ssl protocol analyse */
930void ssl_sock_msgcbk(int write_p, int version, int content_type, const void *buf, size_t len, SSL *ssl, void *arg)
931{
Emeric Brun29f037d2014-04-25 19:05:36 +0200932#ifdef TLS1_RT_HEARTBEAT
933 /* test heartbeat received (write_p is set to 0
934 for a received record) */
Willy Tarreauf51c6982014-04-25 20:02:39 +0200935 if ((content_type == TLS1_RT_HEARTBEAT) && (write_p == 0)) {
Willy Tarreau84815002014-04-25 21:40:27 +0200936 struct connection *conn = (struct connection *)SSL_get_app_data(ssl);
Willy Tarreauf51c6982014-04-25 20:02:39 +0200937 const unsigned char *p = buf;
938 unsigned int payload;
939
Emeric Brun29f037d2014-04-25 19:05:36 +0200940 conn->xprt_st |= SSL_SOCK_RECV_HEARTBEAT;
Willy Tarreauf51c6982014-04-25 20:02:39 +0200941
942 /* Check if this is a CVE-2014-0160 exploitation attempt. */
943 if (*p != TLS1_HB_REQUEST)
944 return;
945
Willy Tarreauaeed6722014-04-25 23:59:58 +0200946 if (len < 1 + 2 + 16) /* 1 type + 2 size + 0 payload + 16 padding */
Willy Tarreauf51c6982014-04-25 20:02:39 +0200947 goto kill_it;
948
949 payload = (p[1] * 256) + p[2];
Willy Tarreau3b2fdb62014-04-25 23:44:22 +0200950 if (3 + payload + 16 <= len)
Willy Tarreauf51c6982014-04-25 20:02:39 +0200951 return; /* OK no problem */
Willy Tarreauaeed6722014-04-25 23:59:58 +0200952 kill_it:
Willy Tarreau3b2fdb62014-04-25 23:44:22 +0200953 /* We have a clear heartbleed attack (CVE-2014-0160), the
954 * advertised payload is larger than the advertised packet
955 * length, so we have garbage in the buffer between the
956 * payload and the end of the buffer (p+len). We can't know
957 * if the SSL stack is patched, and we don't know if we can
958 * safely wipe out the area between p+3+len and payload.
959 * So instead, we prevent the response from being sent by
960 * setting the max_send_fragment to 0 and we report an SSL
961 * error, which will kill this connection. It will be reported
962 * above as SSL_ERROR_SSL while an other handshake failure with
Willy Tarreauf51c6982014-04-25 20:02:39 +0200963 * a heartbeat message will be reported as SSL_ERROR_SYSCALL.
964 */
Willy Tarreau3b2fdb62014-04-25 23:44:22 +0200965 ssl->max_send_fragment = 0;
Willy Tarreauf51c6982014-04-25 20:02:39 +0200966 SSLerr(SSL_F_TLS1_HEARTBEAT, SSL_R_SSL_HANDSHAKE_FAILURE);
967 return;
968 }
Emeric Brun29f037d2014-04-25 19:05:36 +0200969#endif
970}
971
Willy Tarreau6c9a3d52012-10-18 18:57:14 +0200972#ifdef OPENSSL_NPN_NEGOTIATED
973/* This callback is used so that the server advertises the list of
974 * negociable protocols for NPN.
975 */
976static int ssl_sock_advertise_npn_protos(SSL *s, const unsigned char **data,
977 unsigned int *len, void *arg)
978{
979 struct bind_conf *conf = arg;
980
981 *data = (const unsigned char *)conf->npn_str;
982 *len = conf->npn_len;
983 return SSL_TLSEXT_ERR_OK;
984}
985#endif
986
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +0100987#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Willy Tarreauab861d32013-04-02 02:30:41 +0200988/* This callback is used so that the server advertises the list of
989 * negociable protocols for ALPN.
990 */
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +0100991static int ssl_sock_advertise_alpn_protos(SSL *s, const unsigned char **out,
992 unsigned char *outlen,
993 const unsigned char *server,
994 unsigned int server_len, void *arg)
Willy Tarreauab861d32013-04-02 02:30:41 +0200995{
996 struct bind_conf *conf = arg;
997
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +0100998 if (SSL_select_next_proto((unsigned char**) out, outlen, (const unsigned char *)conf->alpn_str,
999 conf->alpn_len, server, server_len) != OPENSSL_NPN_NEGOTIATED) {
1000 return SSL_TLSEXT_ERR_NOACK;
1001 }
Willy Tarreauab861d32013-04-02 02:30:41 +02001002 return SSL_TLSEXT_ERR_OK;
1003}
1004#endif
1005
Christopher Faulet31af49d2015-06-09 17:29:50 +02001006static SSL_CTX *
1007ssl_sock_create_cert(const char *servername, unsigned int serial, X509 *cacert, EVP_PKEY *capkey)
1008{
1009 SSL_CTX *ssl_ctx = NULL;
1010 X509 *newcrt = NULL;
1011 EVP_PKEY *pkey = NULL;
1012 RSA *rsa;
1013 X509_NAME *name;
1014 const EVP_MD *digest;
1015 X509V3_CTX ctx;
1016 unsigned int i;
1017
1018 /* Generate the public key */
1019 if (!(rsa = RSA_generate_key(2048, 3, NULL, NULL)))
1020 goto mkcert_error;
1021 if (!(pkey = EVP_PKEY_new()))
1022 goto mkcert_error;
1023 if (EVP_PKEY_assign_RSA(pkey, rsa) != 1)
1024 goto mkcert_error;
1025
1026 /* Create the certificate */
1027 if (!(newcrt = X509_new()))
1028 goto mkcert_error;
1029
1030 /* Set version number for the certificate (X509v3) and the serial
1031 * number */
1032 if (X509_set_version(newcrt, 2L) != 1)
1033 goto mkcert_error;
1034 ASN1_INTEGER_set(X509_get_serialNumber(newcrt), serial);
1035
1036 /* Set duration for the certificate */
1037 if (!X509_gmtime_adj(X509_get_notBefore(newcrt), (long)-60*60*24) ||
1038 !X509_gmtime_adj(X509_get_notAfter(newcrt),(long)60*60*24*365))
1039 goto mkcert_error;
1040
1041 /* set public key in the certificate */
1042 if (X509_set_pubkey(newcrt, pkey) != 1)
1043 goto mkcert_error;
1044
1045 /* Set issuer name from the CA */
1046 if (!(name = X509_get_subject_name(cacert)))
1047 goto mkcert_error;
1048 if (X509_set_issuer_name(newcrt, name) != 1)
1049 goto mkcert_error;
1050
1051 /* Set the subject name using the same, but the CN */
1052 name = X509_NAME_dup(name);
1053 if (X509_NAME_add_entry_by_txt(name, "CN", MBSTRING_ASC,
1054 (const unsigned char *)servername,
1055 -1, -1, 0) != 1) {
1056 X509_NAME_free(name);
1057 goto mkcert_error;
1058 }
1059 if (X509_set_subject_name(newcrt, name) != 1) {
1060 X509_NAME_free(name);
1061 goto mkcert_error;
1062 }
1063 X509_NAME_free(name);
1064
1065 /* Add x509v3 extensions as specified */
1066 X509V3_set_ctx(&ctx, cacert, newcrt, NULL, NULL, 0);
1067 for (i = 0; i < X509V3_EXT_SIZE; i++) {
1068 X509_EXTENSION *ext;
1069
1070 if (!(ext = X509V3_EXT_conf(NULL, &ctx, x509v3_ext_names[i], x509v3_ext_values[i])))
1071 goto mkcert_error;
1072 if (!X509_add_ext(newcrt, ext, -1)) {
1073 X509_EXTENSION_free(ext);
1074 goto mkcert_error;
1075 }
1076 X509_EXTENSION_free(ext);
1077 }
1078
1079 /* Sign the certificate with the CA private key */
1080 if (EVP_PKEY_type(capkey->type) == EVP_PKEY_DSA)
1081 digest = EVP_dss1();
1082 else if (EVP_PKEY_type (capkey->type) == EVP_PKEY_RSA)
1083 digest = EVP_sha256();
1084 else
1085 goto mkcert_error;
1086 if (!(X509_sign(newcrt, capkey, digest)))
1087 goto mkcert_error;
1088
1089 /* Create and set the new SSL_CTX */
1090 if (!(ssl_ctx = SSL_CTX_new(SSLv23_server_method())))
1091 goto mkcert_error;
1092 if (!SSL_CTX_use_PrivateKey(ssl_ctx, pkey))
1093 goto mkcert_error;
1094 if (!SSL_CTX_use_certificate(ssl_ctx, newcrt))
1095 goto mkcert_error;
1096 if (!SSL_CTX_check_private_key(ssl_ctx))
1097 goto mkcert_error;
1098
1099 if (newcrt) X509_free(newcrt);
1100 if (pkey) EVP_PKEY_free(pkey);
1101 return ssl_ctx;
1102
1103 mkcert_error:
1104 if (ssl_ctx) SSL_CTX_free(ssl_ctx);
1105 if (newcrt) X509_free(newcrt);
1106 if (pkey) EVP_PKEY_free(pkey);
1107 return NULL;
1108}
1109
1110static SSL_CTX *
1111ssl_sock_generate_certificate(const char *servername, struct bind_conf *bind_conf)
1112{
1113 X509 *cacert = bind_conf->ca_sign_cert;
1114 EVP_PKEY *capkey = bind_conf->ca_sign_pkey;
1115 SSL_CTX *ssl_ctx = NULL;
1116 struct lru64 *lru = NULL;
1117 unsigned int serial;
1118
1119 serial = XXH32(servername, strlen(servername), ssl_ctx_lru_seed);
1120 if (ssl_ctx_lru_tree) {
1121 lru = lru64_get(serial, ssl_ctx_lru_tree, cacert, 0);
1122 if (lru && lru->domain)
1123 ssl_ctx = (SSL_CTX *)lru->data;
1124 }
1125
1126 if (!ssl_ctx) {
1127 ssl_ctx = ssl_sock_create_cert(servername, serial, cacert, capkey);
1128 if (lru)
1129 lru64_commit(lru, ssl_ctx, cacert, 0, (void (*)(void *))SSL_CTX_free);
1130 }
1131 return ssl_ctx;
1132}
1133
Emeric Brunfc0421f2012-09-07 17:30:07 +02001134#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
1135/* Sets the SSL ctx of <ssl> to match the advertised server name. Returns a
1136 * warning when no match is found, which implies the default (first) cert
1137 * will keep being used.
1138 */
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001139static int ssl_sock_switchctx_cbk(SSL *ssl, int *al, struct bind_conf *s)
Emeric Brunfc0421f2012-09-07 17:30:07 +02001140{
1141 const char *servername;
1142 const char *wildp = NULL;
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001143 struct ebmb_node *node, *n;
Emeric Brunfc0421f2012-09-07 17:30:07 +02001144 int i;
1145 (void)al; /* shut gcc stupid warning */
1146
1147 servername = SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name);
Emmanuel Hocdet65623372013-01-24 17:17:15 +01001148 if (!servername) {
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001149 return (s->strict_sni ?
1150 SSL_TLSEXT_ERR_ALERT_FATAL :
Emmanuel Hocdet79274e22013-05-31 12:47:44 +02001151 SSL_TLSEXT_ERR_NOACK);
Emmanuel Hocdet65623372013-01-24 17:17:15 +01001152 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02001153
Willy Tarreau19d14ef2012-10-29 16:51:55 +01001154 for (i = 0; i < trash.size; i++) {
Emeric Brunfc0421f2012-09-07 17:30:07 +02001155 if (!servername[i])
1156 break;
Willy Tarreau19d14ef2012-10-29 16:51:55 +01001157 trash.str[i] = tolower(servername[i]);
1158 if (!wildp && (trash.str[i] == '.'))
1159 wildp = &trash.str[i];
Emeric Brunfc0421f2012-09-07 17:30:07 +02001160 }
Willy Tarreau19d14ef2012-10-29 16:51:55 +01001161 trash.str[i] = 0;
Emeric Brunfc0421f2012-09-07 17:30:07 +02001162
1163 /* lookup in full qualified names */
Willy Tarreau19d14ef2012-10-29 16:51:55 +01001164 node = ebst_lookup(&s->sni_ctx, trash.str);
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001165
1166 /* lookup a not neg filter */
1167 for (n = node; n; n = ebmb_next_dup(n)) {
1168 if (!container_of(n, struct sni_ctx, name)->neg) {
1169 node = n;
1170 break;
Emmanuel Hocdet65623372013-01-24 17:17:15 +01001171 }
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001172 }
1173 if (!node && wildp) {
1174 /* lookup in wildcards names */
Emeric Brunfc0421f2012-09-07 17:30:07 +02001175 node = ebst_lookup(&s->sni_w_ctx, wildp);
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001176 }
1177 if (!node || container_of(node, struct sni_ctx, name)->neg) {
Christopher Faulet31af49d2015-06-09 17:29:50 +02001178 SSL_CTX *ctx;
1179
1180 if (s->generate_certs &&
1181 (ctx = ssl_sock_generate_certificate(servername, s))) {
1182 /* switch ctx */
1183 SSL_set_SSL_CTX(ssl, ctx);
1184 return SSL_TLSEXT_ERR_OK;
1185 }
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001186 return (s->strict_sni ?
1187 SSL_TLSEXT_ERR_ALERT_FATAL :
1188 SSL_TLSEXT_ERR_ALERT_WARNING);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001189 }
1190
1191 /* switch ctx */
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001192 SSL_set_SSL_CTX(ssl, container_of(node, struct sni_ctx, name)->ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001193 return SSL_TLSEXT_ERR_OK;
1194}
1195#endif /* SSL_CTRL_SET_TLSEXT_HOSTNAME */
1196
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001197#ifndef OPENSSL_NO_DH
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001198
1199static DH * ssl_get_dh_1024(void)
1200{
Remi Gacogned3a341a2015-05-29 16:26:17 +02001201 static unsigned char dh1024_p[]={
1202 0xFA,0xF9,0x2A,0x22,0x2A,0xA7,0x7F,0xE1,0x67,0x4E,0x53,0xF7,
1203 0x56,0x13,0xC3,0xB1,0xE3,0x29,0x6B,0x66,0x31,0x6A,0x7F,0xB3,
1204 0xC2,0x68,0x6B,0xCB,0x1D,0x57,0x39,0x1D,0x1F,0xFF,0x1C,0xC9,
1205 0xA6,0xA4,0x98,0x82,0x31,0x5D,0x25,0xFF,0x8A,0xE0,0x73,0x96,
1206 0x81,0xC8,0x83,0x79,0xC1,0x5A,0x04,0xF8,0x37,0x0D,0xA8,0x3D,
1207 0xAE,0x74,0xBC,0xDB,0xB6,0xA4,0x75,0xD9,0x71,0x8A,0xA0,0x17,
1208 0x9E,0x2D,0xC8,0xA8,0xDF,0x2C,0x5F,0x82,0x95,0xF8,0x92,0x9B,
1209 0xA7,0x33,0x5F,0x89,0x71,0xC8,0x2D,0x6B,0x18,0x86,0xC4,0x94,
1210 0x22,0xA5,0x52,0x8D,0xF6,0xF6,0xD2,0x37,0x92,0x0F,0xA5,0xCC,
1211 0xDB,0x7B,0x1D,0x3D,0xA1,0x31,0xB7,0x80,0x8F,0x0B,0x67,0x5E,
1212 0x36,0xA5,0x60,0x0C,0xF1,0x95,0x33,0x8B,
1213 };
1214 static unsigned char dh1024_g[]={
1215 0x02,
1216 };
1217
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001218 DH *dh = DH_new();
1219 if (dh) {
Remi Gacogned3a341a2015-05-29 16:26:17 +02001220 dh->p = BN_bin2bn(dh1024_p, sizeof dh1024_p, NULL);
1221 dh->g = BN_bin2bn(dh1024_g, sizeof dh1024_g, NULL);
1222
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001223 if (!dh->p || !dh->g) {
1224 DH_free(dh);
1225 dh = NULL;
1226 }
1227 }
1228 return dh;
1229}
1230
1231static DH *ssl_get_dh_2048(void)
1232{
Remi Gacogned3a341a2015-05-29 16:26:17 +02001233 static unsigned char dh2048_p[]={
1234 0xEC,0x86,0xF8,0x70,0xA0,0x33,0x16,0xEC,0x05,0x1A,0x73,0x59,
1235 0xCD,0x1F,0x8B,0xF8,0x29,0xE4,0xD2,0xCF,0x52,0xDD,0xC2,0x24,
1236 0x8D,0xB5,0x38,0x9A,0xFB,0x5C,0xA4,0xE4,0xB2,0xDA,0xCE,0x66,
1237 0x50,0x74,0xA6,0x85,0x4D,0x4B,0x1D,0x30,0xB8,0x2B,0xF3,0x10,
1238 0xE9,0xA7,0x2D,0x05,0x71,0xE7,0x81,0xDF,0x8B,0x59,0x52,0x3B,
1239 0x5F,0x43,0x0B,0x68,0xF1,0xDB,0x07,0xBE,0x08,0x6B,0x1B,0x23,
1240 0xEE,0x4D,0xCC,0x9E,0x0E,0x43,0xA0,0x1E,0xDF,0x43,0x8C,0xEC,
1241 0xBE,0xBE,0x90,0xB4,0x51,0x54,0xB9,0x2F,0x7B,0x64,0x76,0x4E,
1242 0x5D,0xD4,0x2E,0xAE,0xC2,0x9E,0xAE,0x51,0x43,0x59,0xC7,0x77,
1243 0x9C,0x50,0x3C,0x0E,0xED,0x73,0x04,0x5F,0xF1,0x4C,0x76,0x2A,
1244 0xD8,0xF8,0xCF,0xFC,0x34,0x40,0xD1,0xB4,0x42,0x61,0x84,0x66,
1245 0x42,0x39,0x04,0xF8,0x68,0xB2,0x62,0xD7,0x55,0xED,0x1B,0x74,
1246 0x75,0x91,0xE0,0xC5,0x69,0xC1,0x31,0x5C,0xDB,0x7B,0x44,0x2E,
1247 0xCE,0x84,0x58,0x0D,0x1E,0x66,0x0C,0xC8,0x44,0x9E,0xFD,0x40,
1248 0x08,0x67,0x5D,0xFB,0xA7,0x76,0x8F,0x00,0x11,0x87,0xE9,0x93,
1249 0xF9,0x7D,0xC4,0xBC,0x74,0x55,0x20,0xD4,0x4A,0x41,0x2F,0x43,
1250 0x42,0x1A,0xC1,0xF2,0x97,0x17,0x49,0x27,0x37,0x6B,0x2F,0x88,
1251 0x7E,0x1C,0xA0,0xA1,0x89,0x92,0x27,0xD9,0x56,0x5A,0x71,0xC1,
1252 0x56,0x37,0x7E,0x3A,0x9D,0x05,0xE7,0xEE,0x5D,0x8F,0x82,0x17,
1253 0xBC,0xE9,0xC2,0x93,0x30,0x82,0xF9,0xF4,0xC9,0xAE,0x49,0xDB,
1254 0xD0,0x54,0xB4,0xD9,0x75,0x4D,0xFA,0x06,0xB8,0xD6,0x38,0x41,
1255 0xB7,0x1F,0x77,0xF3,
1256 };
1257 static unsigned char dh2048_g[]={
1258 0x02,
1259 };
1260
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001261 DH *dh = DH_new();
1262 if (dh) {
Remi Gacogned3a341a2015-05-29 16:26:17 +02001263 dh->p = BN_bin2bn(dh2048_p, sizeof dh2048_p, NULL);
1264 dh->g = BN_bin2bn(dh2048_g, sizeof dh2048_g, NULL);
1265
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001266 if (!dh->p || !dh->g) {
1267 DH_free(dh);
1268 dh = NULL;
1269 }
1270 }
1271 return dh;
1272}
1273
1274static DH *ssl_get_dh_4096(void)
1275{
Remi Gacogned3a341a2015-05-29 16:26:17 +02001276 static unsigned char dh4096_p[]={
1277 0xDE,0x16,0x94,0xCD,0x99,0x58,0x07,0xF1,0xF7,0x32,0x96,0x11,
1278 0x04,0x82,0xD4,0x84,0x72,0x80,0x99,0x06,0xCA,0xF0,0xA3,0x68,
1279 0x07,0xCE,0x64,0x50,0xE7,0x74,0x45,0x20,0x80,0x5E,0x4D,0xAD,
1280 0xA5,0xB6,0xED,0xFA,0x80,0x6C,0x3B,0x35,0xC4,0x9A,0x14,0x6B,
1281 0x32,0xBB,0xFD,0x1F,0x17,0x8E,0xB7,0x1F,0xD6,0xFA,0x3F,0x7B,
1282 0xEE,0x16,0xA5,0x62,0x33,0x0D,0xED,0xBC,0x4E,0x58,0xE5,0x47,
1283 0x4D,0xE9,0xAB,0x8E,0x38,0xD3,0x6E,0x90,0x57,0xE3,0x22,0x15,
1284 0x33,0xBD,0xF6,0x43,0x45,0xB5,0x10,0x0A,0xBE,0x2C,0xB4,0x35,
1285 0xB8,0x53,0x8D,0xAD,0xFB,0xA7,0x1F,0x85,0x58,0x41,0x7A,0x79,
1286 0x20,0x68,0xB3,0xE1,0x3D,0x08,0x76,0xBF,0x86,0x0D,0x49,0xE3,
1287 0x82,0x71,0x8C,0xB4,0x8D,0x81,0x84,0xD4,0xE7,0xBE,0x91,0xDC,
1288 0x26,0x39,0x48,0x0F,0x35,0xC4,0xCA,0x65,0xE3,0x40,0x93,0x52,
1289 0x76,0x58,0x7D,0xDD,0x51,0x75,0xDC,0x69,0x61,0xBF,0x47,0x2C,
1290 0x16,0x68,0x2D,0xC9,0x29,0xD3,0xE6,0xC0,0x99,0x48,0xA0,0x9A,
1291 0xC8,0x78,0xC0,0x6D,0x81,0x67,0x12,0x61,0x3F,0x71,0xBA,0x41,
1292 0x1F,0x6C,0x89,0x44,0x03,0xBA,0x3B,0x39,0x60,0xAA,0x28,0x55,
1293 0x59,0xAE,0xB8,0xFA,0xCB,0x6F,0xA5,0x1A,0xF7,0x2B,0xDD,0x52,
1294 0x8A,0x8B,0xE2,0x71,0xA6,0x5E,0x7E,0xD8,0x2E,0x18,0xE0,0x66,
1295 0xDF,0xDD,0x22,0x21,0x99,0x52,0x73,0xA6,0x33,0x20,0x65,0x0E,
1296 0x53,0xE7,0x6B,0x9B,0xC5,0xA3,0x2F,0x97,0x65,0x76,0xD3,0x47,
1297 0x23,0x77,0x12,0xB6,0x11,0x7B,0x24,0xED,0xF1,0xEF,0xC0,0xE2,
1298 0xA3,0x7E,0x67,0x05,0x3E,0x96,0x4D,0x45,0xC2,0x18,0xD1,0x73,
1299 0x9E,0x07,0xF3,0x81,0x6E,0x52,0x63,0xF6,0x20,0x76,0xB9,0x13,
1300 0xD2,0x65,0x30,0x18,0x16,0x09,0x16,0x9E,0x8F,0xF1,0xD2,0x10,
1301 0x5A,0xD3,0xD4,0xAF,0x16,0x61,0xDA,0x55,0x2E,0x18,0x5E,0x14,
1302 0x08,0x54,0x2E,0x2A,0x25,0xA2,0x1A,0x9B,0x8B,0x32,0xA9,0xFD,
1303 0xC2,0x48,0x96,0xE1,0x80,0xCA,0xE9,0x22,0x17,0xBB,0xCE,0x3E,
1304 0x9E,0xED,0xC7,0xF1,0x1F,0xEC,0x17,0x21,0xDC,0x7B,0x82,0x48,
1305 0x8E,0xBB,0x4B,0x9D,0x5B,0x04,0x04,0xDA,0xDB,0x39,0xDF,0x01,
1306 0x40,0xC3,0xAA,0x26,0x23,0x89,0x75,0xC6,0x0B,0xD0,0xA2,0x60,
1307 0x6A,0xF1,0xCC,0x65,0x18,0x98,0x1B,0x52,0xD2,0x74,0x61,0xCC,
1308 0xBD,0x60,0xAE,0xA3,0xA0,0x66,0x6A,0x16,0x34,0x92,0x3F,0x41,
1309 0x40,0x31,0x29,0xC0,0x2C,0x63,0xB2,0x07,0x8D,0xEB,0x94,0xB8,
1310 0xE8,0x47,0x92,0x52,0x93,0x6A,0x1B,0x7E,0x1A,0x61,0xB3,0x1B,
1311 0xF0,0xD6,0x72,0x9B,0xF1,0xB0,0xAF,0xBF,0x3E,0x65,0xEF,0x23,
1312 0x1D,0x6F,0xFF,0x70,0xCD,0x8A,0x4C,0x8A,0xA0,0x72,0x9D,0xBE,
1313 0xD4,0xBB,0x24,0x47,0x4A,0x68,0xB5,0xF5,0xC6,0xD5,0x7A,0xCD,
1314 0xCA,0x06,0x41,0x07,0xAD,0xC2,0x1E,0xE6,0x54,0xA7,0xAD,0x03,
1315 0xD9,0x12,0xC1,0x9C,0x13,0xB1,0xC9,0x0A,0x43,0x8E,0x1E,0x08,
1316 0xCE,0x50,0x82,0x73,0x5F,0xA7,0x55,0x1D,0xD9,0x59,0xAC,0xB5,
1317 0xEA,0x02,0x7F,0x6C,0x5B,0x74,0x96,0x98,0x67,0x24,0xA3,0x0F,
1318 0x15,0xFC,0xA9,0x7D,0x3E,0x67,0xD1,0x70,0xF8,0x97,0xF3,0x67,
1319 0xC5,0x8C,0x88,0x44,0x08,0x02,0xC7,0x2B,
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001320 };
Remi Gacogned3a341a2015-05-29 16:26:17 +02001321 static unsigned char dh4096_g[]={
1322 0x02,
1323 };
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001324
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001325 DH *dh = DH_new();
1326 if (dh) {
Remi Gacogned3a341a2015-05-29 16:26:17 +02001327 dh->p = BN_bin2bn(dh4096_p, sizeof dh4096_p, NULL);
1328 dh->g = BN_bin2bn(dh4096_g, sizeof dh4096_g, NULL);
1329
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001330 if (!dh->p || !dh->g) {
1331 DH_free(dh);
1332 dh = NULL;
1333 }
1334 }
1335 return dh;
1336}
1337
1338/* Returns Diffie-Hellman parameters matching the private key length
1339 but not exceeding global.tune.ssl_default_dh_param */
1340static DH *ssl_get_tmp_dh(SSL *ssl, int export, int keylen)
1341{
1342 DH *dh = NULL;
1343 EVP_PKEY *pkey = SSL_get_privatekey(ssl);
1344 int type = pkey ? EVP_PKEY_type(pkey->type) : EVP_PKEY_NONE;
1345
1346 /* The keylen supplied by OpenSSL can only be 512 or 1024.
1347 See ssl3_send_server_key_exchange() in ssl/s3_srvr.c
1348 */
1349 if (type == EVP_PKEY_RSA || type == EVP_PKEY_DSA) {
1350 keylen = EVP_PKEY_bits(pkey);
1351 }
1352
1353 if (keylen > global.tune.ssl_default_dh_param) {
1354 keylen = global.tune.ssl_default_dh_param;
1355 }
1356
Remi Gacogned3a341a2015-05-29 16:26:17 +02001357 if (keylen >= 4096) {
Remi Gacogne8de54152014-07-15 11:36:40 +02001358 dh = local_dh_4096;
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001359 }
1360 else if (keylen >= 2048) {
Remi Gacogne8de54152014-07-15 11:36:40 +02001361 dh = local_dh_2048;
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001362 }
1363 else {
Remi Gacogne8de54152014-07-15 11:36:40 +02001364 dh = local_dh_1024;
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001365 }
1366
1367 return dh;
1368}
1369
Remi Gacogne47783ef2015-05-29 15:53:22 +02001370static DH * ssl_sock_get_dh_from_file(const char *filename)
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001371{
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001372 DH *dh = NULL;
Remi Gacogne47783ef2015-05-29 15:53:22 +02001373 BIO *in = BIO_new(BIO_s_file());
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001374
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001375 if (in == NULL)
1376 goto end;
1377
Remi Gacogne47783ef2015-05-29 15:53:22 +02001378 if (BIO_read_filename(in, filename) <= 0)
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001379 goto end;
1380
Remi Gacogne47783ef2015-05-29 15:53:22 +02001381 dh = PEM_read_bio_DHparams(in, NULL, NULL, NULL);
1382
1383end:
1384 if (in)
1385 BIO_free(in);
1386
1387 return dh;
1388}
1389
1390int ssl_sock_load_global_dh_param_from_file(const char *filename)
1391{
1392 global_dh = ssl_sock_get_dh_from_file(filename);
1393
1394 if (global_dh) {
1395 return 0;
1396 }
1397
1398 return -1;
1399}
1400
1401/* Loads Diffie-Hellman parameter from a file. Returns 1 if loaded, else -1
1402 if an error occured, and 0 if parameter not found. */
1403int ssl_sock_load_dh_params(SSL_CTX *ctx, const char *file)
1404{
1405 int ret = -1;
1406 DH *dh = ssl_sock_get_dh_from_file(file);
1407
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001408 if (dh) {
1409 ret = 1;
1410 SSL_CTX_set_tmp_dh(ctx, dh);
Remi Gacogne4f902b82015-05-28 16:23:00 +02001411
1412 if (ssl_dh_ptr_index >= 0) {
1413 /* store a pointer to the DH params to avoid complaining about
1414 ssl-default-dh-param not being set for this SSL_CTX */
1415 SSL_CTX_set_ex_data(ctx, ssl_dh_ptr_index, dh);
1416 }
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001417 }
Remi Gacogne47783ef2015-05-29 15:53:22 +02001418 else if (global_dh) {
1419 SSL_CTX_set_tmp_dh(ctx, global_dh);
1420 ret = 0; /* DH params not found */
1421 }
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001422 else {
Emeric Brun41fdb3c2013-04-26 11:05:44 +02001423 /* Clear openssl global errors stack */
1424 ERR_clear_error();
1425
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001426 if (global.tune.ssl_default_dh_param <= 1024) {
1427 /* we are limited to DH parameter of 1024 bits anyway */
Remi Gacogne8de54152014-07-15 11:36:40 +02001428 local_dh_1024 = ssl_get_dh_1024();
1429 if (local_dh_1024 == NULL)
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001430 goto end;
Willy Tarreau6e774b42014-04-25 21:35:23 +02001431
Remi Gacogne8de54152014-07-15 11:36:40 +02001432 SSL_CTX_set_tmp_dh(ctx, local_dh_1024);
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001433 }
1434 else {
1435 SSL_CTX_set_tmp_dh_callback(ctx, ssl_get_tmp_dh);
1436 }
Willy Tarreau6e774b42014-04-25 21:35:23 +02001437
Emeric Brun41fdb3c2013-04-26 11:05:44 +02001438 ret = 0; /* DH params not found */
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001439 }
Emeric Brun644cde02012-12-14 11:21:13 +01001440
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001441end:
1442 if (dh)
1443 DH_free(dh);
1444
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001445 return ret;
1446}
1447#endif
1448
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001449static int ssl_sock_add_cert_sni(SSL_CTX *ctx, struct bind_conf *s, char *name, int order)
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001450{
1451 struct sni_ctx *sc;
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001452 int wild = 0, neg = 0;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001453
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001454 if (*name == '!') {
1455 neg = 1;
1456 name++;
1457 }
1458 if (*name == '*') {
1459 wild = 1;
1460 name++;
1461 }
1462 /* !* filter is a nop */
1463 if (neg && wild)
1464 return order;
1465 if (*name) {
1466 int j, len;
1467 len = strlen(name);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001468 sc = malloc(sizeof(struct sni_ctx) + len + 1);
1469 for (j = 0; j < len; j++)
1470 sc->name.key[j] = tolower(name[j]);
1471 sc->name.key[len] = 0;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001472 sc->ctx = ctx;
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001473 sc->order = order++;
1474 sc->neg = neg;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001475 if (wild)
1476 ebst_insert(&s->sni_w_ctx, &sc->name);
1477 else
1478 ebst_insert(&s->sni_ctx, &sc->name);
1479 }
1480 return order;
1481}
1482
Emeric Brunfc0421f2012-09-07 17:30:07 +02001483/* Loads a certificate key and CA chain from a file. Returns 0 on error, -1 if
1484 * an early error happens and the caller must call SSL_CTX_free() by itelf.
1485 */
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001486static 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 +02001487{
1488 BIO *in;
1489 X509 *x = NULL, *ca;
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001490 int i, err;
Emeric Brunfc0421f2012-09-07 17:30:07 +02001491 int ret = -1;
1492 int order = 0;
1493 X509_NAME *xname;
1494 char *str;
Emeric Brunfc0421f2012-09-07 17:30:07 +02001495#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
1496 STACK_OF(GENERAL_NAME) *names;
1497#endif
1498
1499 in = BIO_new(BIO_s_file());
1500 if (in == NULL)
1501 goto end;
1502
1503 if (BIO_read_filename(in, file) <= 0)
1504 goto end;
1505
1506 x = PEM_read_bio_X509_AUX(in, NULL, ctx->default_passwd_callback, ctx->default_passwd_callback_userdata);
1507 if (x == NULL)
1508 goto end;
1509
Emeric Brun50bcecc2013-04-22 13:05:23 +02001510 if (fcount) {
1511 while (fcount--)
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001512 order = ssl_sock_add_cert_sni(ctx, s, sni_filter[fcount], order);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001513 }
1514 else {
Emeric Brunfc0421f2012-09-07 17:30:07 +02001515#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001516 names = X509_get_ext_d2i(x, NID_subject_alt_name, NULL, NULL);
1517 if (names) {
1518 for (i = 0; i < sk_GENERAL_NAME_num(names); i++) {
1519 GENERAL_NAME *name = sk_GENERAL_NAME_value(names, i);
1520 if (name->type == GEN_DNS) {
1521 if (ASN1_STRING_to_UTF8((unsigned char **)&str, name->d.dNSName) >= 0) {
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001522 order = ssl_sock_add_cert_sni(ctx, s, str, order);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001523 OPENSSL_free(str);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001524 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02001525 }
1526 }
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001527 sk_GENERAL_NAME_pop_free(names, GENERAL_NAME_free);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001528 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02001529#endif /* SSL_CTRL_SET_TLSEXT_HOSTNAME */
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001530 xname = X509_get_subject_name(x);
1531 i = -1;
1532 while ((i = X509_NAME_get_index_by_NID(xname, NID_commonName, i)) != -1) {
1533 X509_NAME_ENTRY *entry = X509_NAME_get_entry(xname, i);
1534 if (ASN1_STRING_to_UTF8((unsigned char **)&str, entry->value) >= 0) {
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001535 order = ssl_sock_add_cert_sni(ctx, s, str, order);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001536 OPENSSL_free(str);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001537 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02001538 }
1539 }
1540
1541 ret = 0; /* the caller must not free the SSL_CTX argument anymore */
1542 if (!SSL_CTX_use_certificate(ctx, x))
1543 goto end;
1544
1545 if (ctx->extra_certs != NULL) {
1546 sk_X509_pop_free(ctx->extra_certs, X509_free);
1547 ctx->extra_certs = NULL;
1548 }
1549
1550 while ((ca = PEM_read_bio_X509(in, NULL, ctx->default_passwd_callback, ctx->default_passwd_callback_userdata))) {
1551 if (!SSL_CTX_add_extra_chain_cert(ctx, ca)) {
1552 X509_free(ca);
1553 goto end;
1554 }
1555 }
1556
1557 err = ERR_get_error();
1558 if (!err || (ERR_GET_LIB(err) == ERR_LIB_PEM && ERR_GET_REASON(err) == PEM_R_NO_START_LINE)) {
1559 /* we successfully reached the last cert in the file */
1560 ret = 1;
1561 }
1562 ERR_clear_error();
1563
1564end:
1565 if (x)
1566 X509_free(x);
1567
1568 if (in)
1569 BIO_free(in);
1570
1571 return ret;
1572}
1573
Emeric Brun50bcecc2013-04-22 13:05:23 +02001574static 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 +02001575{
1576 int ret;
1577 SSL_CTX *ctx;
1578
1579 ctx = SSL_CTX_new(SSLv23_server_method());
1580 if (!ctx) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02001581 memprintf(err, "%sunable to allocate SSL context for cert '%s'.\n",
1582 err && *err ? *err : "", path);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001583 return 1;
1584 }
1585
1586 if (SSL_CTX_use_PrivateKey_file(ctx, path, SSL_FILETYPE_PEM) <= 0) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02001587 memprintf(err, "%sunable to load SSL private key from PEM file '%s'.\n",
1588 err && *err ? *err : "", path);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001589 SSL_CTX_free(ctx);
1590 return 1;
1591 }
1592
Emeric Brun50bcecc2013-04-22 13:05:23 +02001593 ret = ssl_sock_load_cert_chain_file(ctx, path, bind_conf, sni_filter, fcount);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001594 if (ret <= 0) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02001595 memprintf(err, "%sunable to load SSL certificate from PEM file '%s'.\n",
1596 err && *err ? *err : "", path);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001597 if (ret < 0) /* serious error, must do that ourselves */
1598 SSL_CTX_free(ctx);
1599 return 1;
1600 }
Emeric Brun61694ab2012-10-26 13:35:33 +02001601
1602 if (SSL_CTX_check_private_key(ctx) <= 0) {
1603 memprintf(err, "%sinconsistencies between private key and certificate loaded from PEM file '%s'.\n",
1604 err && *err ? *err : "", path);
1605 return 1;
1606 }
1607
Emeric Brunfc0421f2012-09-07 17:30:07 +02001608 /* we must not free the SSL_CTX anymore below, since it's already in
1609 * the tree, so it will be discovered and cleaned in time.
1610 */
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001611#ifndef OPENSSL_NO_DH
Remi Gacogne4f902b82015-05-28 16:23:00 +02001612 /* store a NULL pointer to indicate we have not yet loaded
1613 a custom DH param file */
1614 if (ssl_dh_ptr_index >= 0) {
1615 SSL_CTX_set_ex_data(ctx, ssl_dh_ptr_index, NULL);
1616 }
1617
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001618 ret = ssl_sock_load_dh_params(ctx, path);
1619 if (ret < 0) {
1620 if (err)
1621 memprintf(err, "%sunable to load DH parameters from file '%s'.\n",
1622 *err ? *err : "", path);
1623 return 1;
1624 }
1625#endif
1626
Lukas Tribuse4e30f72014-12-09 16:32:51 +01001627#if (defined SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB && !defined OPENSSL_NO_OCSP)
Emeric Brun4147b2e2014-06-16 18:36:30 +02001628 ret = ssl_sock_load_ocsp(ctx, path);
1629 if (ret < 0) {
1630 if (err)
1631 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",
1632 *err ? *err : "", path);
1633 return 1;
1634 }
1635#endif
1636
Janusz Dziemidowicz2c701b52015-03-07 23:03:59 +01001637#if (OPENSSL_VERSION_NUMBER >= 0x1000200fL && !defined OPENSSL_NO_TLSEXT && !defined OPENSSL_IS_BORINGSSL)
1638 if (sctl_ex_index >= 0) {
1639 ret = ssl_sock_load_sctl(ctx, path);
1640 if (ret < 0) {
1641 if (err)
1642 memprintf(err, "%s '%s.sctl' is present but cannot be read or parsed'.\n",
1643 *err ? *err : "", path);
1644 return 1;
1645 }
1646 }
1647#endif
1648
Emeric Brunfc0421f2012-09-07 17:30:07 +02001649#ifndef SSL_CTRL_SET_TLSEXT_HOSTNAME
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001650 if (bind_conf->default_ctx) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02001651 memprintf(err, "%sthis version of openssl cannot load multiple SSL certificates.\n",
1652 err && *err ? *err : "");
Emeric Brunfc0421f2012-09-07 17:30:07 +02001653 return 1;
1654 }
1655#endif
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001656 if (!bind_conf->default_ctx)
1657 bind_conf->default_ctx = ctx;
Emeric Brunfc0421f2012-09-07 17:30:07 +02001658
1659 return 0;
1660}
1661
Willy Tarreau79eeafa2012-09-14 07:53:05 +02001662int ssl_sock_load_cert(char *path, struct bind_conf *bind_conf, struct proxy *curproxy, char **err)
Emeric Brunfc0421f2012-09-07 17:30:07 +02001663{
Cyril Bonté3180f7b2015-01-25 00:16:08 +01001664 struct dirent **de_list;
1665 int i, n;
Emeric Brunfc0421f2012-09-07 17:30:07 +02001666 DIR *dir;
1667 struct stat buf;
Willy Tarreauee2663b2012-12-06 11:36:59 +01001668 char *end;
1669 char fp[MAXPATHLEN+1];
Emeric Brunfc0421f2012-09-07 17:30:07 +02001670 int cfgerr = 0;
1671
1672 if (!(dir = opendir(path)))
Emeric Brun50bcecc2013-04-22 13:05:23 +02001673 return ssl_sock_load_cert_file(path, bind_conf, curproxy, NULL, 0, err);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001674
1675 /* strip trailing slashes, including first one */
1676 for (end = path + strlen(path) - 1; end >= path && *end == '/'; end--)
1677 *end = 0;
1678
Cyril Bonté3180f7b2015-01-25 00:16:08 +01001679 n = scandir(path, &de_list, 0, alphasort);
1680 if (n < 0) {
1681 memprintf(err, "%sunable to scan directory '%s' : %s.\n",
1682 err && *err ? *err : "", path, strerror(errno));
1683 cfgerr++;
1684 }
1685 else {
1686 for (i = 0; i < n; i++) {
1687 struct dirent *de = de_list[i];
Emeric Brun2aab7222014-06-18 18:15:09 +02001688
Cyril Bonté3180f7b2015-01-25 00:16:08 +01001689 end = strrchr(de->d_name, '.');
Janusz Dziemidowicz2c701b52015-03-07 23:03:59 +01001690 if (end && (!strcmp(end, ".issuer") || !strcmp(end, ".ocsp") || !strcmp(end, ".sctl")))
Cyril Bonté3180f7b2015-01-25 00:16:08 +01001691 goto ignore_entry;
1692
1693 snprintf(fp, sizeof(fp), "%s/%s", path, de->d_name);
1694 if (stat(fp, &buf) != 0) {
1695 memprintf(err, "%sunable to stat SSL certificate from file '%s' : %s.\n",
1696 err && *err ? *err : "", fp, strerror(errno));
1697 cfgerr++;
1698 goto ignore_entry;
1699 }
1700 if (!S_ISREG(buf.st_mode))
1701 goto ignore_entry;
1702 cfgerr += ssl_sock_load_cert_file(fp, bind_conf, curproxy, NULL, 0, err);
1703 ignore_entry:
1704 free(de);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001705 }
Cyril Bonté3180f7b2015-01-25 00:16:08 +01001706 free(de_list);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001707 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02001708 closedir(dir);
1709 return cfgerr;
1710}
1711
Thierry Fournier383085f2013-01-24 14:15:43 +01001712/* Make sure openssl opens /dev/urandom before the chroot. The work is only
1713 * done once. Zero is returned if the operation fails. No error is returned
1714 * if the random is said as not implemented, because we expect that openssl
1715 * will use another method once needed.
1716 */
1717static int ssl_initialize_random()
1718{
1719 unsigned char random;
1720 static int random_initialized = 0;
1721
1722 if (!random_initialized && RAND_bytes(&random, 1) != 0)
1723 random_initialized = 1;
1724
1725 return random_initialized;
1726}
1727
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001728int ssl_sock_load_cert_list_file(char *file, struct bind_conf *bind_conf, struct proxy *curproxy, char **err)
1729{
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001730 char thisline[LINESIZE];
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001731 FILE *f;
1732 int linenum = 0;
1733 int cfgerr = 0;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001734
Willy Tarreauad1731d2013-04-02 17:35:58 +02001735 if ((f = fopen(file, "r")) == NULL) {
1736 memprintf(err, "cannot open file '%s' : %s", file, strerror(errno));
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001737 return 1;
Willy Tarreauad1731d2013-04-02 17:35:58 +02001738 }
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001739
1740 while (fgets(thisline, sizeof(thisline), f) != NULL) {
1741 int arg;
Emeric Brun50bcecc2013-04-22 13:05:23 +02001742 int newarg;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001743 char *end;
1744 char *args[MAX_LINE_ARGS + 1];
1745 char *line = thisline;
1746
1747 linenum++;
1748 end = line + strlen(line);
1749 if (end-line == sizeof(thisline)-1 && *(end-1) != '\n') {
1750 /* Check if we reached the limit and the last char is not \n.
1751 * Watch out for the last line without the terminating '\n'!
1752 */
Willy Tarreauad1731d2013-04-02 17:35:58 +02001753 memprintf(err, "line %d too long in file '%s', limit is %d characters",
1754 linenum, file, (int)sizeof(thisline)-1);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001755 cfgerr = 1;
Willy Tarreauad1731d2013-04-02 17:35:58 +02001756 break;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001757 }
1758
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001759 arg = 0;
Emeric Brun50bcecc2013-04-22 13:05:23 +02001760 newarg = 1;
1761 while (*line) {
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001762 if (*line == '#' || *line == '\n' || *line == '\r') {
1763 /* end of string, end of loop */
1764 *line = 0;
1765 break;
1766 }
1767 else if (isspace(*line)) {
Emeric Brun50bcecc2013-04-22 13:05:23 +02001768 newarg = 1;
1769 *line = 0;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001770 }
Emeric Brun50bcecc2013-04-22 13:05:23 +02001771 else if (newarg) {
1772 if (arg == MAX_LINE_ARGS) {
1773 memprintf(err, "too many args on line %d in file '%s'.",
1774 linenum, file);
1775 cfgerr = 1;
1776 break;
1777 }
1778 newarg = 0;
1779 args[arg++] = line;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001780 }
Emeric Brun50bcecc2013-04-22 13:05:23 +02001781 line++;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001782 }
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001783 if (cfgerr)
1784 break;
Willy Tarreauad1731d2013-04-02 17:35:58 +02001785
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001786 /* empty line */
Emeric Brun50bcecc2013-04-22 13:05:23 +02001787 if (!arg)
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001788 continue;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001789
Emeric Brun50bcecc2013-04-22 13:05:23 +02001790 cfgerr = ssl_sock_load_cert_file(args[0], bind_conf, curproxy, &args[1], arg-1, err);
Willy Tarreauad1731d2013-04-02 17:35:58 +02001791 if (cfgerr) {
1792 memprintf(err, "error processing line %d in file '%s' : %s", linenum, file, *err);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001793 break;
Willy Tarreauad1731d2013-04-02 17:35:58 +02001794 }
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001795 }
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001796 fclose(f);
1797 return cfgerr;
1798}
1799
Emeric Brunfc0421f2012-09-07 17:30:07 +02001800#ifndef SSL_OP_CIPHER_SERVER_PREFERENCE /* needs OpenSSL >= 0.9.7 */
1801#define SSL_OP_CIPHER_SERVER_PREFERENCE 0
1802#endif
1803
1804#ifndef SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION /* needs OpenSSL >= 0.9.7 */
1805#define SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION 0
Willy Tarreau7d588ee2012-11-26 18:47:31 +01001806#define SSL_renegotiate_pending(arg) 0
Emeric Brunfc0421f2012-09-07 17:30:07 +02001807#endif
Emeric Brun2b58d042012-09-20 17:10:03 +02001808#ifndef SSL_OP_SINGLE_ECDH_USE /* needs OpenSSL >= 0.9.8 */
1809#define SSL_OP_SINGLE_ECDH_USE 0
1810#endif
Emeric Brun2d0c4822012-10-02 13:45:20 +02001811#ifndef SSL_OP_NO_TICKET /* needs OpenSSL >= 0.9.8 */
1812#define SSL_OP_NO_TICKET 0
1813#endif
Emeric Brunfc0421f2012-09-07 17:30:07 +02001814#ifndef SSL_OP_NO_COMPRESSION /* needs OpenSSL >= 0.9.9 */
1815#define SSL_OP_NO_COMPRESSION 0
1816#endif
Emeric Brunc0ff4922012-09-28 19:37:02 +02001817#ifndef SSL_OP_NO_TLSv1_1 /* needs OpenSSL >= 1.0.1 */
1818#define SSL_OP_NO_TLSv1_1 0
1819#endif
1820#ifndef SSL_OP_NO_TLSv1_2 /* needs OpenSSL >= 1.0.1 */
1821#define SSL_OP_NO_TLSv1_2 0
1822#endif
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001823#ifndef SSL_OP_SINGLE_DH_USE /* needs OpenSSL >= 0.9.6 */
1824#define SSL_OP_SINGLE_DH_USE 0
1825#endif
Emeric Brun2b58d042012-09-20 17:10:03 +02001826#ifndef SSL_OP_SINGLE_ECDH_USE /* needs OpenSSL >= 1.0.0 */
1827#define SSL_OP_SINGLE_ECDH_USE 0
1828#endif
Emeric Brunfc0421f2012-09-07 17:30:07 +02001829#ifndef SSL_MODE_RELEASE_BUFFERS /* needs OpenSSL >= 1.0.0 */
1830#define SSL_MODE_RELEASE_BUFFERS 0
1831#endif
Willy Tarreau396a1862014-11-13 14:06:52 +01001832#ifndef SSL_MODE_SMALL_BUFFERS /* needs small_records.patch */
1833#define SSL_MODE_SMALL_BUFFERS 0
1834#endif
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001835
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001836int ssl_sock_prepare_ctx(struct bind_conf *bind_conf, SSL_CTX *ctx, struct proxy *curproxy)
Emeric Brunfc0421f2012-09-07 17:30:07 +02001837{
1838 int cfgerr = 0;
Emeric Brun850efd52014-01-29 12:24:34 +01001839 int verify = SSL_VERIFY_NONE;
Remi Gacogneaf5c3da2014-05-19 10:29:58 +02001840 long ssloptions =
Emeric Brunfc0421f2012-09-07 17:30:07 +02001841 SSL_OP_ALL | /* all known workarounds for bugs */
1842 SSL_OP_NO_SSLv2 |
1843 SSL_OP_NO_COMPRESSION |
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001844 SSL_OP_SINGLE_DH_USE |
Emeric Brun2b58d042012-09-20 17:10:03 +02001845 SSL_OP_SINGLE_ECDH_USE |
Emeric Brun3c4bc6e2012-10-04 18:44:19 +02001846 SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION |
1847 SSL_OP_CIPHER_SERVER_PREFERENCE;
Remi Gacogneaf5c3da2014-05-19 10:29:58 +02001848 long sslmode =
Emeric Brunfc0421f2012-09-07 17:30:07 +02001849 SSL_MODE_ENABLE_PARTIAL_WRITE |
1850 SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER |
Willy Tarreau396a1862014-11-13 14:06:52 +01001851 SSL_MODE_RELEASE_BUFFERS |
1852 SSL_MODE_SMALL_BUFFERS;
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001853 STACK_OF(SSL_CIPHER) * ciphers = NULL;
Willy Tarreaua616ba62014-10-26 06:49:19 +01001854 SSL_CIPHER * cipher = NULL;
Remi Gacognec1eab8c2014-06-12 18:20:11 +02001855 char cipher_description[128];
1856 /* The description of ciphers using an Ephemeral Diffie Hellman key exchange
1857 contains " Kx=DH " or " Kx=DH(". Beware of " Kx=DH/",
1858 which is not ephemeral DH. */
1859 const char dhe_description[] = " Kx=DH ";
1860 const char dhe_export_description[] = " Kx=DH(";
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001861 int idx = 0;
1862 int dhe_found = 0;
Remi Gacogne23d5d372014-10-10 17:04:26 +02001863 SSL *ssl = NULL;
Emeric Brunfc0421f2012-09-07 17:30:07 +02001864
Thierry Fournier383085f2013-01-24 14:15:43 +01001865 /* Make sure openssl opens /dev/urandom before the chroot */
1866 if (!ssl_initialize_random()) {
1867 Alert("OpenSSL random data generator initialization failed.\n");
1868 cfgerr++;
1869 }
1870
Emeric Brun89675492012-10-05 13:48:26 +02001871 if (bind_conf->ssl_options & BC_SSL_O_NO_SSLV3)
Emeric Brunfc0421f2012-09-07 17:30:07 +02001872 ssloptions |= SSL_OP_NO_SSLv3;
Emeric Brun89675492012-10-05 13:48:26 +02001873 if (bind_conf->ssl_options & BC_SSL_O_NO_TLSV10)
Emeric Brunfc0421f2012-09-07 17:30:07 +02001874 ssloptions |= SSL_OP_NO_TLSv1;
Emeric Brun89675492012-10-05 13:48:26 +02001875 if (bind_conf->ssl_options & BC_SSL_O_NO_TLSV11)
Emeric Brunc0ff4922012-09-28 19:37:02 +02001876 ssloptions |= SSL_OP_NO_TLSv1_1;
Emeric Brun89675492012-10-05 13:48:26 +02001877 if (bind_conf->ssl_options & BC_SSL_O_NO_TLSV12)
Emeric Brunc0ff4922012-09-28 19:37:02 +02001878 ssloptions |= SSL_OP_NO_TLSv1_2;
Emeric Brun89675492012-10-05 13:48:26 +02001879 if (bind_conf->ssl_options & BC_SSL_O_NO_TLS_TICKETS)
Emeric Brun2d0c4822012-10-02 13:45:20 +02001880 ssloptions |= SSL_OP_NO_TICKET;
Emeric Brun2cb7ae52012-10-05 14:14:21 +02001881 if (bind_conf->ssl_options & BC_SSL_O_USE_SSLV3)
1882 SSL_CTX_set_ssl_version(ctx, SSLv3_server_method());
1883 if (bind_conf->ssl_options & BC_SSL_O_USE_TLSV10)
1884 SSL_CTX_set_ssl_version(ctx, TLSv1_server_method());
1885#if SSL_OP_NO_TLSv1_1
1886 if (bind_conf->ssl_options & BC_SSL_O_USE_TLSV11)
1887 SSL_CTX_set_ssl_version(ctx, TLSv1_1_server_method());
1888#endif
1889#if SSL_OP_NO_TLSv1_2
1890 if (bind_conf->ssl_options & BC_SSL_O_USE_TLSV12)
1891 SSL_CTX_set_ssl_version(ctx, TLSv1_2_server_method());
1892#endif
Emeric Brunfc0421f2012-09-07 17:30:07 +02001893
1894 SSL_CTX_set_options(ctx, ssloptions);
1895 SSL_CTX_set_mode(ctx, sslmode);
Emeric Brun850efd52014-01-29 12:24:34 +01001896 switch (bind_conf->verify) {
1897 case SSL_SOCK_VERIFY_NONE:
1898 verify = SSL_VERIFY_NONE;
1899 break;
1900 case SSL_SOCK_VERIFY_OPTIONAL:
1901 verify = SSL_VERIFY_PEER;
1902 break;
1903 case SSL_SOCK_VERIFY_REQUIRED:
1904 verify = SSL_VERIFY_PEER|SSL_VERIFY_FAIL_IF_NO_PEER_CERT;
1905 break;
1906 }
1907 SSL_CTX_set_verify(ctx, verify, ssl_sock_bind_verifycbk);
1908 if (verify & SSL_VERIFY_PEER) {
Emeric Brunfb510ea2012-10-05 12:00:26 +02001909 if (bind_conf->ca_file) {
Emeric Brund94b3fe2012-09-20 18:23:56 +02001910 /* load CAfile to verify */
Emeric Brunfb510ea2012-10-05 12:00:26 +02001911 if (!SSL_CTX_load_verify_locations(ctx, bind_conf->ca_file, NULL)) {
Emeric Brund94b3fe2012-09-20 18:23:56 +02001912 Alert("Proxy '%s': unable to load CA file '%s' for bind '%s' at [%s:%d].\n",
Emeric Brunfb510ea2012-10-05 12:00:26 +02001913 curproxy->id, bind_conf->ca_file, bind_conf->arg, bind_conf->file, bind_conf->line);
Emeric Brund94b3fe2012-09-20 18:23:56 +02001914 cfgerr++;
1915 }
1916 /* set CA names fo client cert request, function returns void */
Emeric Brunfb510ea2012-10-05 12:00:26 +02001917 SSL_CTX_set_client_CA_list(ctx, SSL_load_client_CA_file(bind_conf->ca_file));
Emeric Brund94b3fe2012-09-20 18:23:56 +02001918 }
Emeric Brun850efd52014-01-29 12:24:34 +01001919 else {
1920 Alert("Proxy '%s': verify is enabled but no CA file specified for bind '%s' at [%s:%d].\n",
1921 curproxy->id, bind_conf->arg, bind_conf->file, bind_conf->line);
1922 cfgerr++;
1923 }
Emeric Brun051cdab2012-10-02 19:25:50 +02001924#ifdef X509_V_FLAG_CRL_CHECK
Emeric Brunfb510ea2012-10-05 12:00:26 +02001925 if (bind_conf->crl_file) {
Emeric Brund94b3fe2012-09-20 18:23:56 +02001926 X509_STORE *store = SSL_CTX_get_cert_store(ctx);
1927
Emeric Brunfb510ea2012-10-05 12:00:26 +02001928 if (!store || !X509_STORE_load_locations(store, bind_conf->crl_file, NULL)) {
Emeric Brund94b3fe2012-09-20 18:23:56 +02001929 Alert("Proxy '%s': unable to configure CRL file '%s' for bind '%s' at [%s:%d].\n",
Alexander Rigbofc65af02015-04-07 14:02:16 +02001930 curproxy->id, bind_conf->crl_file, bind_conf->arg, bind_conf->file, bind_conf->line);
Emeric Brund94b3fe2012-09-20 18:23:56 +02001931 cfgerr++;
1932 }
Emeric Brun561e5742012-10-02 15:20:55 +02001933 else {
1934 X509_STORE_set_flags(store, X509_V_FLAG_CRL_CHECK|X509_V_FLAG_CRL_CHECK_ALL);
1935 }
Emeric Brund94b3fe2012-09-20 18:23:56 +02001936 }
Emeric Brun051cdab2012-10-02 19:25:50 +02001937#endif
Emeric Brun644cde02012-12-14 11:21:13 +01001938 ERR_clear_error();
Emeric Brund94b3fe2012-09-20 18:23:56 +02001939 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02001940
Nenad Merdanovic05552d42015-02-27 19:56:49 +01001941#if (defined SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB && TLS_TICKETS_NO > 0)
Nenad Merdanovic146defa2015-05-09 08:46:00 +02001942 if(bind_conf->keys_ref) {
Nenad Merdanovic05552d42015-02-27 19:56:49 +01001943 if (!SSL_CTX_set_tlsext_ticket_key_cb(ctx, ssl_tlsext_ticket_key_cb)) {
1944 Alert("Proxy '%s': unable to set callback for TLS ticket validation for bind '%s' at [%s:%d].\n",
1945 curproxy->id, bind_conf->arg, bind_conf->file, bind_conf->line);
1946 cfgerr++;
1947 }
1948 }
1949#endif
1950
Emeric Brun4f65bff2012-11-16 15:11:00 +01001951 if (global.tune.ssllifetime)
1952 SSL_CTX_set_timeout(ctx, global.tune.ssllifetime);
1953
Emeric Brunfc0421f2012-09-07 17:30:07 +02001954 shared_context_set_cache(ctx);
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001955 if (bind_conf->ciphers &&
1956 !SSL_CTX_set_cipher_list(ctx, bind_conf->ciphers)) {
Emeric Brunfc0421f2012-09-07 17:30:07 +02001957 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 +02001958 curproxy->id, bind_conf->ciphers, bind_conf->arg, bind_conf->file, bind_conf->line);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001959 cfgerr++;
1960 }
1961
Remi Gacogne47783ef2015-05-29 15:53:22 +02001962 /* If tune.ssl.default-dh-param has not been set,
1963 neither has ssl-default-dh-file and no static DH
1964 params were in the certificate file. */
Remi Gacogne4f902b82015-05-28 16:23:00 +02001965 if (global.tune.ssl_default_dh_param == 0 &&
Remi Gacogne47783ef2015-05-29 15:53:22 +02001966 global_dh == NULL &&
Remi Gacogne4f902b82015-05-28 16:23:00 +02001967 (ssl_dh_ptr_index == -1 ||
1968 SSL_CTX_get_ex_data(ctx, ssl_dh_ptr_index) == NULL)) {
Lukas Tribus90132722014-08-18 00:56:33 +02001969
Remi Gacogne23d5d372014-10-10 17:04:26 +02001970 ssl = SSL_new(ctx);
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001971
Remi Gacogne23d5d372014-10-10 17:04:26 +02001972 if (ssl) {
1973 ciphers = SSL_get_ciphers(ssl);
1974
1975 if (ciphers) {
1976 for (idx = 0; idx < sk_SSL_CIPHER_num(ciphers); idx++) {
1977 cipher = sk_SSL_CIPHER_value(ciphers, idx);
1978 if (SSL_CIPHER_description(cipher, cipher_description, sizeof (cipher_description)) == cipher_description) {
1979 if (strstr(cipher_description, dhe_description) != NULL ||
1980 strstr(cipher_description, dhe_export_description) != NULL) {
1981 dhe_found = 1;
1982 break;
1983 }
Remi Gacognec1eab8c2014-06-12 18:20:11 +02001984 }
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001985 }
1986 }
Remi Gacogne23d5d372014-10-10 17:04:26 +02001987 SSL_free(ssl);
1988 ssl = NULL;
Lukas Tribus90132722014-08-18 00:56:33 +02001989 }
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001990
Lukas Tribus90132722014-08-18 00:56:33 +02001991 if (dhe_found) {
1992 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 +02001993 }
1994
1995 global.tune.ssl_default_dh_param = 1024;
1996 }
Remi Gacogne8de54152014-07-15 11:36:40 +02001997
1998#ifndef OPENSSL_NO_DH
1999 if (global.tune.ssl_default_dh_param >= 1024) {
2000 if (local_dh_1024 == NULL) {
2001 local_dh_1024 = ssl_get_dh_1024();
2002 }
2003 if (global.tune.ssl_default_dh_param >= 2048) {
2004 if (local_dh_2048 == NULL) {
2005 local_dh_2048 = ssl_get_dh_2048();
2006 }
2007 if (global.tune.ssl_default_dh_param >= 4096) {
2008 if (local_dh_4096 == NULL) {
2009 local_dh_4096 = ssl_get_dh_4096();
2010 }
Remi Gacogne8de54152014-07-15 11:36:40 +02002011 }
2012 }
2013 }
2014#endif /* OPENSSL_NO_DH */
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002015
Emeric Brunfc0421f2012-09-07 17:30:07 +02002016 SSL_CTX_set_info_callback(ctx, ssl_sock_infocbk);
Willy Tarreau5cbe4ef2014-05-08 22:45:11 +02002017#if OPENSSL_VERSION_NUMBER >= 0x00907000L
Emeric Brun29f037d2014-04-25 19:05:36 +02002018 SSL_CTX_set_msg_callback(ctx, ssl_sock_msgcbk);
Willy Tarreau5cbe4ef2014-05-08 22:45:11 +02002019#endif
Emeric Brun29f037d2014-04-25 19:05:36 +02002020
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02002021#ifdef OPENSSL_NPN_NEGOTIATED
2022 if (bind_conf->npn_str)
2023 SSL_CTX_set_next_protos_advertised_cb(ctx, ssl_sock_advertise_npn_protos, bind_conf);
2024#endif
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01002025#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Willy Tarreauab861d32013-04-02 02:30:41 +02002026 if (bind_conf->alpn_str)
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01002027 SSL_CTX_set_alpn_select_cb(ctx, ssl_sock_advertise_alpn_protos, bind_conf);
Willy Tarreauab861d32013-04-02 02:30:41 +02002028#endif
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02002029
Emeric Brunfc0421f2012-09-07 17:30:07 +02002030#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
2031 SSL_CTX_set_tlsext_servername_callback(ctx, ssl_sock_switchctx_cbk);
Willy Tarreau2a65ff02012-09-13 17:54:29 +02002032 SSL_CTX_set_tlsext_servername_arg(ctx, bind_conf);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002033#endif
Emeric Brun2b58d042012-09-20 17:10:03 +02002034#if defined(SSL_CTX_set_tmp_ecdh) && !defined(OPENSSL_NO_ECDH)
Emeric Brun6924ef82013-03-06 14:08:53 +01002035 {
Emeric Brun2b58d042012-09-20 17:10:03 +02002036 int i;
2037 EC_KEY *ecdh;
2038
Emeric Brun6924ef82013-03-06 14:08:53 +01002039 i = OBJ_sn2nid(bind_conf->ecdhe ? bind_conf->ecdhe : ECDHE_DEFAULT_CURVE);
Emeric Brun2b58d042012-09-20 17:10:03 +02002040 if (!i || ((ecdh = EC_KEY_new_by_curve_name(i)) == NULL)) {
2041 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 +01002042 curproxy->id, bind_conf->ecdhe ? bind_conf->ecdhe : ECDHE_DEFAULT_CURVE,
2043 bind_conf->arg, bind_conf->file, bind_conf->line);
Emeric Brun2b58d042012-09-20 17:10:03 +02002044 cfgerr++;
2045 }
2046 else {
2047 SSL_CTX_set_tmp_ecdh(ctx, ecdh);
2048 EC_KEY_free(ecdh);
2049 }
2050 }
2051#endif
2052
Emeric Brunfc0421f2012-09-07 17:30:07 +02002053 return cfgerr;
2054}
2055
Evan Broderbe554312013-06-27 00:05:25 -07002056static int ssl_sock_srv_hostcheck(const char *pattern, const char *hostname)
2057{
2058 const char *pattern_wildcard, *pattern_left_label_end, *hostname_left_label_end;
2059 size_t prefixlen, suffixlen;
2060
2061 /* Trivial case */
2062 if (strcmp(pattern, hostname) == 0)
2063 return 1;
2064
Evan Broderbe554312013-06-27 00:05:25 -07002065 /* The rest of this logic is based on RFC 6125, section 6.4.3
2066 * (http://tools.ietf.org/html/rfc6125#section-6.4.3) */
2067
Emeric Bruna848dae2013-10-08 11:27:28 +02002068 pattern_wildcard = NULL;
2069 pattern_left_label_end = pattern;
2070 while (*pattern_left_label_end != '.') {
2071 switch (*pattern_left_label_end) {
2072 case 0:
2073 /* End of label not found */
2074 return 0;
2075 case '*':
2076 /* If there is more than one wildcards */
2077 if (pattern_wildcard)
2078 return 0;
2079 pattern_wildcard = pattern_left_label_end;
2080 break;
2081 }
2082 pattern_left_label_end++;
2083 }
2084
2085 /* If it's not trivial and there is no wildcard, it can't
2086 * match */
2087 if (!pattern_wildcard)
Evan Broderbe554312013-06-27 00:05:25 -07002088 return 0;
2089
2090 /* Make sure all labels match except the leftmost */
2091 hostname_left_label_end = strchr(hostname, '.');
2092 if (!hostname_left_label_end
2093 || strcmp(pattern_left_label_end, hostname_left_label_end) != 0)
2094 return 0;
2095
2096 /* Make sure the leftmost label of the hostname is long enough
2097 * that the wildcard can match */
Emeric Brun369da852013-10-08 11:39:35 +02002098 if (hostname_left_label_end - hostname < (pattern_left_label_end - pattern) - 1)
Evan Broderbe554312013-06-27 00:05:25 -07002099 return 0;
2100
2101 /* Finally compare the string on either side of the
2102 * wildcard */
2103 prefixlen = pattern_wildcard - pattern;
2104 suffixlen = pattern_left_label_end - (pattern_wildcard + 1);
Emeric Bruna848dae2013-10-08 11:27:28 +02002105 if ((prefixlen && (memcmp(pattern, hostname, prefixlen) != 0))
2106 || (suffixlen && (memcmp(pattern_wildcard + 1, hostname_left_label_end - suffixlen, suffixlen) != 0)))
Evan Broderbe554312013-06-27 00:05:25 -07002107 return 0;
2108
2109 return 1;
2110}
2111
2112static int ssl_sock_srv_verifycbk(int ok, X509_STORE_CTX *ctx)
2113{
2114 SSL *ssl;
2115 struct connection *conn;
2116 char *servername;
2117
2118 int depth;
2119 X509 *cert;
2120 STACK_OF(GENERAL_NAME) *alt_names;
2121 int i;
2122 X509_NAME *cert_subject;
2123 char *str;
2124
2125 if (ok == 0)
2126 return ok;
2127
2128 ssl = X509_STORE_CTX_get_ex_data(ctx, SSL_get_ex_data_X509_STORE_CTX_idx());
2129 conn = (struct connection *)SSL_get_app_data(ssl);
2130
2131 servername = objt_server(conn->target)->ssl_ctx.verify_host;
2132
2133 /* We only need to verify the CN on the actual server cert,
2134 * not the indirect CAs */
2135 depth = X509_STORE_CTX_get_error_depth(ctx);
2136 if (depth != 0)
2137 return ok;
2138
2139 /* At this point, the cert is *not* OK unless we can find a
2140 * hostname match */
2141 ok = 0;
2142
2143 cert = X509_STORE_CTX_get_current_cert(ctx);
2144 /* It seems like this might happen if verify peer isn't set */
2145 if (!cert)
2146 return ok;
2147
2148 alt_names = X509_get_ext_d2i(cert, NID_subject_alt_name, NULL, NULL);
2149 if (alt_names) {
2150 for (i = 0; !ok && i < sk_GENERAL_NAME_num(alt_names); i++) {
2151 GENERAL_NAME *name = sk_GENERAL_NAME_value(alt_names, i);
2152 if (name->type == GEN_DNS) {
Emeric Bruna33410c2013-09-17 15:47:48 +02002153#if OPENSSL_VERSION_NUMBER < 0x00907000L
2154 if (ASN1_STRING_to_UTF8((unsigned char **)&str, name->d.ia5) >= 0) {
2155#else
Evan Broderbe554312013-06-27 00:05:25 -07002156 if (ASN1_STRING_to_UTF8((unsigned char **)&str, name->d.dNSName) >= 0) {
Emeric Bruna33410c2013-09-17 15:47:48 +02002157#endif
Evan Broderbe554312013-06-27 00:05:25 -07002158 ok = ssl_sock_srv_hostcheck(str, servername);
2159 OPENSSL_free(str);
2160 }
2161 }
2162 }
Emeric Brun4ad50a42013-09-17 15:19:54 +02002163 sk_GENERAL_NAME_pop_free(alt_names, GENERAL_NAME_free);
Evan Broderbe554312013-06-27 00:05:25 -07002164 }
2165
2166 cert_subject = X509_get_subject_name(cert);
2167 i = -1;
2168 while (!ok && (i = X509_NAME_get_index_by_NID(cert_subject, NID_commonName, i)) != -1) {
2169 X509_NAME_ENTRY *entry = X509_NAME_get_entry(cert_subject, i);
2170 if (ASN1_STRING_to_UTF8((unsigned char **)&str, entry->value) >= 0) {
2171 ok = ssl_sock_srv_hostcheck(str, servername);
2172 OPENSSL_free(str);
2173 }
2174 }
2175
2176 return ok;
2177}
2178
Emeric Brun94324a42012-10-11 14:00:19 +02002179/* prepare ssl context from servers options. Returns an error count */
2180int ssl_sock_prepare_srv_ctx(struct server *srv, struct proxy *curproxy)
2181{
2182 int cfgerr = 0;
Remi Gacogneaf5c3da2014-05-19 10:29:58 +02002183 long options =
Emeric Brun94324a42012-10-11 14:00:19 +02002184 SSL_OP_ALL | /* all known workarounds for bugs */
2185 SSL_OP_NO_SSLv2 |
2186 SSL_OP_NO_COMPRESSION;
Remi Gacogneaf5c3da2014-05-19 10:29:58 +02002187 long mode =
Emeric Brun94324a42012-10-11 14:00:19 +02002188 SSL_MODE_ENABLE_PARTIAL_WRITE |
2189 SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER |
Willy Tarreau396a1862014-11-13 14:06:52 +01002190 SSL_MODE_RELEASE_BUFFERS |
2191 SSL_MODE_SMALL_BUFFERS;
Emeric Brun850efd52014-01-29 12:24:34 +01002192 int verify = SSL_VERIFY_NONE;
Emeric Brun94324a42012-10-11 14:00:19 +02002193
Thierry Fournier383085f2013-01-24 14:15:43 +01002194 /* Make sure openssl opens /dev/urandom before the chroot */
2195 if (!ssl_initialize_random()) {
2196 Alert("OpenSSL random data generator initialization failed.\n");
2197 cfgerr++;
2198 }
2199
Willy Tarreaufce03112015-01-15 21:32:40 +01002200 /* Automatic memory computations need to know we use SSL there */
2201 global.ssl_used_backend = 1;
2202
2203 /* Initiate SSL context for current server */
Emeric Brun94324a42012-10-11 14:00:19 +02002204 srv->ssl_ctx.reused_sess = NULL;
2205 if (srv->use_ssl)
2206 srv->xprt = &ssl_sock;
2207 if (srv->check.use_ssl)
Cyril Bonté9ce13112014-11-15 22:41:27 +01002208 srv->check.xprt = &ssl_sock;
Emeric Brun94324a42012-10-11 14:00:19 +02002209
2210 srv->ssl_ctx.ctx = SSL_CTX_new(SSLv23_client_method());
2211 if (!srv->ssl_ctx.ctx) {
2212 Alert("config : %s '%s', server '%s': unable to allocate ssl context.\n",
2213 proxy_type_str(curproxy), curproxy->id,
2214 srv->id);
2215 cfgerr++;
2216 return cfgerr;
2217 }
Emeric Bruna7aa3092012-10-26 12:58:00 +02002218 if (srv->ssl_ctx.client_crt) {
2219 if (SSL_CTX_use_PrivateKey_file(srv->ssl_ctx.ctx, srv->ssl_ctx.client_crt, SSL_FILETYPE_PEM) <= 0) {
2220 Alert("config : %s '%s', server '%s': unable to load SSL private key from PEM file '%s'.\n",
2221 proxy_type_str(curproxy), curproxy->id,
2222 srv->id, srv->ssl_ctx.client_crt);
2223 cfgerr++;
2224 }
2225 else if (SSL_CTX_use_certificate_chain_file(srv->ssl_ctx.ctx, srv->ssl_ctx.client_crt) <= 0) {
2226 Alert("config : %s '%s', server '%s': unable to load ssl certificate from PEM file '%s'.\n",
2227 proxy_type_str(curproxy), curproxy->id,
2228 srv->id, srv->ssl_ctx.client_crt);
2229 cfgerr++;
2230 }
2231 else if (SSL_CTX_check_private_key(srv->ssl_ctx.ctx) <= 0) {
2232 Alert("config : %s '%s', server '%s': inconsistencies between private key and certificate loaded from PEM file '%s'.\n",
2233 proxy_type_str(curproxy), curproxy->id,
2234 srv->id, srv->ssl_ctx.client_crt);
2235 cfgerr++;
2236 }
2237 }
Emeric Brun94324a42012-10-11 14:00:19 +02002238
2239 if (srv->ssl_ctx.options & SRV_SSL_O_NO_SSLV3)
2240 options |= SSL_OP_NO_SSLv3;
2241 if (srv->ssl_ctx.options & SRV_SSL_O_NO_TLSV10)
2242 options |= SSL_OP_NO_TLSv1;
2243 if (srv->ssl_ctx.options & SRV_SSL_O_NO_TLSV11)
2244 options |= SSL_OP_NO_TLSv1_1;
2245 if (srv->ssl_ctx.options & SRV_SSL_O_NO_TLSV12)
2246 options |= SSL_OP_NO_TLSv1_2;
Emeric Brunf9c5c472012-10-11 15:28:34 +02002247 if (srv->ssl_ctx.options & SRV_SSL_O_NO_TLS_TICKETS)
2248 options |= SSL_OP_NO_TICKET;
Emeric Brun94324a42012-10-11 14:00:19 +02002249 if (srv->ssl_ctx.options & SRV_SSL_O_USE_SSLV3)
2250 SSL_CTX_set_ssl_version(srv->ssl_ctx.ctx, SSLv3_client_method());
2251 if (srv->ssl_ctx.options & SRV_SSL_O_USE_TLSV10)
2252 SSL_CTX_set_ssl_version(srv->ssl_ctx.ctx, TLSv1_client_method());
2253#if SSL_OP_NO_TLSv1_1
2254 if (srv->ssl_ctx.options & SRV_SSL_O_USE_TLSV11)
2255 SSL_CTX_set_ssl_version(srv->ssl_ctx.ctx, TLSv1_1_client_method());
2256#endif
2257#if SSL_OP_NO_TLSv1_2
2258 if (srv->ssl_ctx.options & SRV_SSL_O_USE_TLSV12)
2259 SSL_CTX_set_ssl_version(srv->ssl_ctx.ctx, TLSv1_2_client_method());
2260#endif
2261
2262 SSL_CTX_set_options(srv->ssl_ctx.ctx, options);
2263 SSL_CTX_set_mode(srv->ssl_ctx.ctx, mode);
Emeric Brun850efd52014-01-29 12:24:34 +01002264
2265 if (global.ssl_server_verify == SSL_SERVER_VERIFY_REQUIRED)
2266 verify = SSL_VERIFY_PEER;
2267
2268 switch (srv->ssl_ctx.verify) {
2269 case SSL_SOCK_VERIFY_NONE:
2270 verify = SSL_VERIFY_NONE;
2271 break;
2272 case SSL_SOCK_VERIFY_REQUIRED:
2273 verify = SSL_VERIFY_PEER;
2274 break;
2275 }
Evan Broderbe554312013-06-27 00:05:25 -07002276 SSL_CTX_set_verify(srv->ssl_ctx.ctx,
Emeric Brun850efd52014-01-29 12:24:34 +01002277 verify,
Evan Broderbe554312013-06-27 00:05:25 -07002278 srv->ssl_ctx.verify_host ? ssl_sock_srv_verifycbk : NULL);
Emeric Brun850efd52014-01-29 12:24:34 +01002279 if (verify & SSL_VERIFY_PEER) {
Emeric Brunef42d922012-10-11 16:11:36 +02002280 if (srv->ssl_ctx.ca_file) {
2281 /* load CAfile to verify */
2282 if (!SSL_CTX_load_verify_locations(srv->ssl_ctx.ctx, srv->ssl_ctx.ca_file, NULL)) {
Willy Tarreau07ba08b2014-02-16 19:22:08 +01002283 Alert("Proxy '%s', server '%s' [%s:%d] unable to load CA file '%s'.\n",
Emeric Brunef42d922012-10-11 16:11:36 +02002284 curproxy->id, srv->id,
2285 srv->conf.file, srv->conf.line, srv->ssl_ctx.ca_file);
2286 cfgerr++;
2287 }
2288 }
Emeric Brun850efd52014-01-29 12:24:34 +01002289 else {
2290 if (global.ssl_server_verify == SSL_SERVER_VERIFY_REQUIRED)
Willy Tarreau07ba08b2014-02-16 19:22:08 +01002291 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 +01002292 curproxy->id, srv->id,
2293 srv->conf.file, srv->conf.line);
2294 else
Willy Tarreau07ba08b2014-02-16 19:22:08 +01002295 Alert("Proxy '%s', server '%s' [%s:%d] verify is enabled but no CA file specified.\n",
Emeric Brun850efd52014-01-29 12:24:34 +01002296 curproxy->id, srv->id,
2297 srv->conf.file, srv->conf.line);
2298 cfgerr++;
2299 }
Emeric Brunef42d922012-10-11 16:11:36 +02002300#ifdef X509_V_FLAG_CRL_CHECK
2301 if (srv->ssl_ctx.crl_file) {
2302 X509_STORE *store = SSL_CTX_get_cert_store(srv->ssl_ctx.ctx);
2303
2304 if (!store || !X509_STORE_load_locations(store, srv->ssl_ctx.crl_file, NULL)) {
Willy Tarreau07ba08b2014-02-16 19:22:08 +01002305 Alert("Proxy '%s', server '%s' [%s:%d] unable to configure CRL file '%s'.\n",
Emeric Brunef42d922012-10-11 16:11:36 +02002306 curproxy->id, srv->id,
2307 srv->conf.file, srv->conf.line, srv->ssl_ctx.crl_file);
2308 cfgerr++;
2309 }
2310 else {
2311 X509_STORE_set_flags(store, X509_V_FLAG_CRL_CHECK|X509_V_FLAG_CRL_CHECK_ALL);
2312 }
2313 }
2314#endif
2315 }
2316
Emeric Brun4f65bff2012-11-16 15:11:00 +01002317 if (global.tune.ssllifetime)
2318 SSL_CTX_set_timeout(srv->ssl_ctx.ctx, global.tune.ssllifetime);
2319
Emeric Brun94324a42012-10-11 14:00:19 +02002320 SSL_CTX_set_session_cache_mode(srv->ssl_ctx.ctx, SSL_SESS_CACHE_OFF);
2321 if (srv->ssl_ctx.ciphers &&
2322 !SSL_CTX_set_cipher_list(srv->ssl_ctx.ctx, srv->ssl_ctx.ciphers)) {
2323 Alert("Proxy '%s', server '%s' [%s:%d] : unable to set SSL cipher list to '%s'.\n",
2324 curproxy->id, srv->id,
2325 srv->conf.file, srv->conf.line, srv->ssl_ctx.ciphers);
2326 cfgerr++;
2327 }
2328
2329 return cfgerr;
2330}
2331
Willy Tarreau2a65ff02012-09-13 17:54:29 +02002332/* Walks down the two trees in bind_conf and prepares all certs. The pointer may
Emeric Brunfc0421f2012-09-07 17:30:07 +02002333 * be NULL, in which case nothing is done. Returns the number of errors
2334 * encountered.
2335 */
Willy Tarreau2a65ff02012-09-13 17:54:29 +02002336int ssl_sock_prepare_all_ctx(struct bind_conf *bind_conf, struct proxy *px)
Emeric Brunfc0421f2012-09-07 17:30:07 +02002337{
2338 struct ebmb_node *node;
2339 struct sni_ctx *sni;
2340 int err = 0;
2341
Willy Tarreau2a65ff02012-09-13 17:54:29 +02002342 if (!bind_conf || !bind_conf->is_ssl)
Emeric Brunfc0421f2012-09-07 17:30:07 +02002343 return 0;
2344
Willy Tarreaufce03112015-01-15 21:32:40 +01002345 /* Automatic memory computations need to know we use SSL there */
2346 global.ssl_used_frontend = 1;
2347
Emeric Brun0bed9942014-10-30 19:25:24 +01002348 if (bind_conf->default_ctx)
2349 err += ssl_sock_prepare_ctx(bind_conf, bind_conf->default_ctx, px);
2350
Willy Tarreau2a65ff02012-09-13 17:54:29 +02002351 node = ebmb_first(&bind_conf->sni_ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002352 while (node) {
2353 sni = ebmb_entry(node, struct sni_ctx, name);
Emeric Brun0bed9942014-10-30 19:25:24 +01002354 if (!sni->order && sni->ctx != bind_conf->default_ctx)
2355 /* only initialize the CTX on its first occurrence and
2356 if it is not the default_ctx */
Willy Tarreau2a65ff02012-09-13 17:54:29 +02002357 err += ssl_sock_prepare_ctx(bind_conf, sni->ctx, px);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002358 node = ebmb_next(node);
2359 }
2360
Willy Tarreau2a65ff02012-09-13 17:54:29 +02002361 node = ebmb_first(&bind_conf->sni_w_ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002362 while (node) {
2363 sni = ebmb_entry(node, struct sni_ctx, name);
Emeric Brun0bed9942014-10-30 19:25:24 +01002364 if (!sni->order && sni->ctx != bind_conf->default_ctx)
2365 /* only initialize the CTX on its first occurrence and
2366 if it is not the default_ctx */
Willy Tarreau2a65ff02012-09-13 17:54:29 +02002367 err += ssl_sock_prepare_ctx(bind_conf, sni->ctx, px);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002368 node = ebmb_next(node);
2369 }
2370 return err;
2371}
2372
Willy Tarreau2a65ff02012-09-13 17:54:29 +02002373/* Walks down the two trees in bind_conf and frees all the certs. The pointer may
Emeric Brunfc0421f2012-09-07 17:30:07 +02002374 * be NULL, in which case nothing is done. The default_ctx is nullified too.
2375 */
Willy Tarreau2a65ff02012-09-13 17:54:29 +02002376void ssl_sock_free_all_ctx(struct bind_conf *bind_conf)
Emeric Brunfc0421f2012-09-07 17:30:07 +02002377{
2378 struct ebmb_node *node, *back;
2379 struct sni_ctx *sni;
2380
Willy Tarreau2a65ff02012-09-13 17:54:29 +02002381 if (!bind_conf || !bind_conf->is_ssl)
Emeric Brunfc0421f2012-09-07 17:30:07 +02002382 return;
2383
Willy Tarreau2a65ff02012-09-13 17:54:29 +02002384 node = ebmb_first(&bind_conf->sni_ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002385 while (node) {
2386 sni = ebmb_entry(node, struct sni_ctx, name);
2387 back = ebmb_next(node);
2388 ebmb_delete(node);
2389 if (!sni->order) /* only free the CTX on its first occurrence */
2390 SSL_CTX_free(sni->ctx);
2391 free(sni);
2392 node = back;
2393 }
2394
Willy Tarreau2a65ff02012-09-13 17:54:29 +02002395 node = ebmb_first(&bind_conf->sni_w_ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002396 while (node) {
2397 sni = ebmb_entry(node, struct sni_ctx, name);
2398 back = ebmb_next(node);
2399 ebmb_delete(node);
2400 if (!sni->order) /* only free the CTX on its first occurrence */
2401 SSL_CTX_free(sni->ctx);
2402 free(sni);
2403 node = back;
2404 }
2405
Willy Tarreau2a65ff02012-09-13 17:54:29 +02002406 bind_conf->default_ctx = NULL;
Emeric Brune1f38db2012-09-03 20:36:47 +02002407}
2408
Christopher Faulet31af49d2015-06-09 17:29:50 +02002409/* Load CA cert file and private key used to generate certificates */
2410int
2411ssl_sock_load_ca(struct bind_conf *bind_conf, struct proxy *px)
2412{
2413 FILE *fp;
2414 X509 *cacert = NULL;
2415 EVP_PKEY *capkey = NULL;
2416 int err = 0;
2417
2418 if (!bind_conf || !bind_conf->generate_certs)
2419 return err;
2420
2421 if (!bind_conf->ca_sign_file) {
2422 Alert("Proxy '%s': cannot enable certificate generation, "
2423 "no CA certificate File configured at [%s:%d].\n",
2424 px->id, bind_conf->file, bind_conf->line);
2425 err++;
2426 }
2427
2428 if (err)
2429 goto load_error;
2430
2431 /* read in the CA certificate */
2432 if (!(fp = fopen(bind_conf->ca_sign_file, "r"))) {
2433 Alert("Proxy '%s': Failed to read CA certificate file '%s' at [%s:%d].\n",
2434 px->id, bind_conf->ca_sign_file, bind_conf->file, bind_conf->line);
2435 err++;
2436 goto load_error;
2437 }
2438 if (!(cacert = PEM_read_X509(fp, NULL, NULL, NULL))) {
2439 Alert("Proxy '%s': Failed to read CA certificate file '%s' at [%s:%d].\n",
2440 px->id, bind_conf->ca_sign_file, bind_conf->file, bind_conf->line);
2441 fclose (fp);
2442 err++;
2443 goto load_error;
2444 }
2445 if (!(capkey = PEM_read_PrivateKey(fp, NULL, NULL, bind_conf->ca_sign_pass))) {
2446 Alert("Proxy '%s': Failed to read CA private key file '%s' at [%s:%d].\n",
2447 px->id, bind_conf->ca_sign_file, bind_conf->file, bind_conf->line);
2448 fclose (fp);
2449 err++;
2450 goto load_error;
2451 }
2452 fclose (fp);
2453
2454 bind_conf->ca_sign_cert = cacert;
2455 bind_conf->ca_sign_pkey = capkey;
2456 return err;
2457
2458 load_error:
2459 bind_conf->generate_certs = 0;
2460 if (capkey) EVP_PKEY_free(capkey);
2461 if (cacert) X509_free(cacert);
2462 return err;
2463}
2464
2465/* Release CA cert and private key used to generate certificated */
2466void
2467ssl_sock_free_ca(struct bind_conf *bind_conf)
2468{
2469 if (!bind_conf)
2470 return;
2471
2472 if (bind_conf->ca_sign_pkey)
2473 EVP_PKEY_free(bind_conf->ca_sign_pkey);
2474 if (bind_conf->ca_sign_cert)
2475 X509_free(bind_conf->ca_sign_cert);
2476}
2477
Emeric Brun46591952012-05-18 15:47:34 +02002478/*
2479 * This function is called if SSL * context is not yet allocated. The function
2480 * is designed to be called before any other data-layer operation and sets the
2481 * handshake flag on the connection. It is safe to call it multiple times.
2482 * It returns 0 on success and -1 in error case.
2483 */
2484static int ssl_sock_init(struct connection *conn)
2485{
2486 /* already initialized */
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02002487 if (conn->xprt_ctx)
Emeric Brun46591952012-05-18 15:47:34 +02002488 return 0;
2489
Willy Tarreau3c728722014-01-23 13:50:42 +01002490 if (!conn_ctrl_ready(conn))
Willy Tarreauf79c8172013-10-21 16:30:56 +02002491 return 0;
2492
Willy Tarreau20879a02012-12-03 16:32:10 +01002493 if (global.maxsslconn && sslconns >= global.maxsslconn) {
2494 conn->err_code = CO_ER_SSL_TOO_MANY;
Willy Tarreau403edff2012-09-06 11:58:37 +02002495 return -1;
Willy Tarreau20879a02012-12-03 16:32:10 +01002496 }
Willy Tarreau403edff2012-09-06 11:58:37 +02002497
Emeric Brun46591952012-05-18 15:47:34 +02002498 /* If it is in client mode initiate SSL session
2499 in connect state otherwise accept state */
Willy Tarreau3fdb3662012-11-12 00:42:33 +01002500 if (objt_server(conn->target)) {
Willy Tarreaufba03cd2014-11-13 13:48:58 +01002501 int may_retry = 1;
2502
2503 retry_connect:
Emeric Brun46591952012-05-18 15:47:34 +02002504 /* Alloc a new SSL session ctx */
Willy Tarreau3fdb3662012-11-12 00:42:33 +01002505 conn->xprt_ctx = SSL_new(objt_server(conn->target)->ssl_ctx.ctx);
Willy Tarreau20879a02012-12-03 16:32:10 +01002506 if (!conn->xprt_ctx) {
Willy Tarreaufba03cd2014-11-13 13:48:58 +01002507 if (may_retry--) {
2508 pool_gc2();
2509 goto retry_connect;
2510 }
Willy Tarreau20879a02012-12-03 16:32:10 +01002511 conn->err_code = CO_ER_SSL_NO_MEM;
Emeric Brun46591952012-05-18 15:47:34 +02002512 return -1;
Willy Tarreau20879a02012-12-03 16:32:10 +01002513 }
Emeric Brun46591952012-05-18 15:47:34 +02002514
Emeric Brun46591952012-05-18 15:47:34 +02002515 /* set fd on SSL session context */
Emeric Brun55476152014-11-12 17:35:37 +01002516 if (!SSL_set_fd(conn->xprt_ctx, conn->t.sock.fd)) {
2517 SSL_free(conn->xprt_ctx);
2518 conn->xprt_ctx = NULL;
Willy Tarreaufba03cd2014-11-13 13:48:58 +01002519 if (may_retry--) {
2520 pool_gc2();
2521 goto retry_connect;
2522 }
Emeric Brun55476152014-11-12 17:35:37 +01002523 conn->err_code = CO_ER_SSL_NO_MEM;
2524 return -1;
2525 }
Emeric Brun46591952012-05-18 15:47:34 +02002526
Evan Broderbe554312013-06-27 00:05:25 -07002527 /* set connection pointer */
Emeric Brun55476152014-11-12 17:35:37 +01002528 if (!SSL_set_app_data(conn->xprt_ctx, conn)) {
2529 SSL_free(conn->xprt_ctx);
2530 conn->xprt_ctx = NULL;
Willy Tarreaufba03cd2014-11-13 13:48:58 +01002531 if (may_retry--) {
2532 pool_gc2();
2533 goto retry_connect;
2534 }
Emeric Brun55476152014-11-12 17:35:37 +01002535 conn->err_code = CO_ER_SSL_NO_MEM;
2536 return -1;
2537 }
2538
2539 SSL_set_connect_state(conn->xprt_ctx);
2540 if (objt_server(conn->target)->ssl_ctx.reused_sess) {
2541 if(!SSL_set_session(conn->xprt_ctx, objt_server(conn->target)->ssl_ctx.reused_sess)) {
2542 SSL_SESSION_free(objt_server(conn->target)->ssl_ctx.reused_sess);
2543 objt_server(conn->target)->ssl_ctx.reused_sess = NULL;
2544 }
2545 }
Evan Broderbe554312013-06-27 00:05:25 -07002546
Emeric Brun46591952012-05-18 15:47:34 +02002547 /* leave init state and start handshake */
Willy Tarreau05737472012-09-04 08:03:39 +02002548 conn->flags |= CO_FL_SSL_WAIT_HS | CO_FL_WAIT_L6_CONN;
Willy Tarreau403edff2012-09-06 11:58:37 +02002549
2550 sslconns++;
Willy Tarreau71b734c2014-01-28 15:19:44 +01002551 totalsslconns++;
Emeric Brun46591952012-05-18 15:47:34 +02002552 return 0;
2553 }
Willy Tarreau3fdb3662012-11-12 00:42:33 +01002554 else if (objt_listener(conn->target)) {
Willy Tarreaufba03cd2014-11-13 13:48:58 +01002555 int may_retry = 1;
2556
2557 retry_accept:
Emeric Brun46591952012-05-18 15:47:34 +02002558 /* Alloc a new SSL session ctx */
Willy Tarreau3fdb3662012-11-12 00:42:33 +01002559 conn->xprt_ctx = SSL_new(objt_listener(conn->target)->bind_conf->default_ctx);
Willy Tarreau20879a02012-12-03 16:32:10 +01002560 if (!conn->xprt_ctx) {
Willy Tarreaufba03cd2014-11-13 13:48:58 +01002561 if (may_retry--) {
2562 pool_gc2();
2563 goto retry_accept;
2564 }
Willy Tarreau20879a02012-12-03 16:32:10 +01002565 conn->err_code = CO_ER_SSL_NO_MEM;
Emeric Brun46591952012-05-18 15:47:34 +02002566 return -1;
Willy Tarreau20879a02012-12-03 16:32:10 +01002567 }
Emeric Brun46591952012-05-18 15:47:34 +02002568
Emeric Brun46591952012-05-18 15:47:34 +02002569 /* set fd on SSL session context */
Emeric Brun55476152014-11-12 17:35:37 +01002570 if (!SSL_set_fd(conn->xprt_ctx, conn->t.sock.fd)) {
2571 SSL_free(conn->xprt_ctx);
2572 conn->xprt_ctx = NULL;
Willy Tarreaufba03cd2014-11-13 13:48:58 +01002573 if (may_retry--) {
2574 pool_gc2();
2575 goto retry_accept;
2576 }
Emeric Brun55476152014-11-12 17:35:37 +01002577 conn->err_code = CO_ER_SSL_NO_MEM;
2578 return -1;
2579 }
Emeric Brun46591952012-05-18 15:47:34 +02002580
Emeric Brune1f38db2012-09-03 20:36:47 +02002581 /* set connection pointer */
Emeric Brun55476152014-11-12 17:35:37 +01002582 if (!SSL_set_app_data(conn->xprt_ctx, conn)) {
2583 SSL_free(conn->xprt_ctx);
2584 conn->xprt_ctx = NULL;
Willy Tarreaufba03cd2014-11-13 13:48:58 +01002585 if (may_retry--) {
2586 pool_gc2();
2587 goto retry_accept;
2588 }
Emeric Brun55476152014-11-12 17:35:37 +01002589 conn->err_code = CO_ER_SSL_NO_MEM;
2590 return -1;
2591 }
2592
2593 SSL_set_accept_state(conn->xprt_ctx);
Emeric Brune1f38db2012-09-03 20:36:47 +02002594
Emeric Brun46591952012-05-18 15:47:34 +02002595 /* leave init state and start handshake */
Willy Tarreau05737472012-09-04 08:03:39 +02002596 conn->flags |= CO_FL_SSL_WAIT_HS | CO_FL_WAIT_L6_CONN;
Willy Tarreau403edff2012-09-06 11:58:37 +02002597
2598 sslconns++;
Willy Tarreau71b734c2014-01-28 15:19:44 +01002599 totalsslconns++;
Emeric Brun46591952012-05-18 15:47:34 +02002600 return 0;
2601 }
2602 /* don't know how to handle such a target */
Willy Tarreau20879a02012-12-03 16:32:10 +01002603 conn->err_code = CO_ER_SSL_NO_TARGET;
Emeric Brun46591952012-05-18 15:47:34 +02002604 return -1;
2605}
2606
2607
2608/* This is the callback which is used when an SSL handshake is pending. It
2609 * updates the FD status if it wants some polling before being called again.
2610 * It returns 0 if it fails in a fatal way or needs to poll to go further,
2611 * otherwise it returns non-zero and removes itself from the connection's
2612 * flags (the bit is provided in <flag> by the caller).
2613 */
2614int ssl_sock_handshake(struct connection *conn, unsigned int flag)
2615{
2616 int ret;
2617
Willy Tarreau3c728722014-01-23 13:50:42 +01002618 if (!conn_ctrl_ready(conn))
Willy Tarreauf79c8172013-10-21 16:30:56 +02002619 return 0;
2620
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02002621 if (!conn->xprt_ctx)
Emeric Brun46591952012-05-18 15:47:34 +02002622 goto out_error;
2623
Emeric Brun674b7432012-11-08 19:21:55 +01002624 /* If we use SSL_do_handshake to process a reneg initiated by
2625 * the remote peer, it sometimes returns SSL_ERROR_SSL.
2626 * Usually SSL_write and SSL_read are used and process implicitly
2627 * the reneg handshake.
2628 * Here we use SSL_peek as a workaround for reneg.
2629 */
2630 if ((conn->flags & CO_FL_CONNECTED) && SSL_renegotiate_pending(conn->xprt_ctx)) {
2631 char c;
2632
2633 ret = SSL_peek(conn->xprt_ctx, &c, 1);
2634 if (ret <= 0) {
2635 /* handshake may have not been completed, let's find why */
2636 ret = SSL_get_error(conn->xprt_ctx, ret);
2637 if (ret == SSL_ERROR_WANT_WRITE) {
2638 /* SSL handshake needs to write, L4 connection may not be ready */
2639 __conn_sock_stop_recv(conn);
Willy Tarreaue1f50c42014-01-22 20:02:06 +01002640 __conn_sock_want_send(conn);
2641 fd_cant_send(conn->t.sock.fd);
Emeric Brun674b7432012-11-08 19:21:55 +01002642 return 0;
2643 }
2644 else if (ret == SSL_ERROR_WANT_READ) {
2645 /* handshake may have been completed but we have
2646 * no more data to read.
2647 */
2648 if (!SSL_renegotiate_pending(conn->xprt_ctx)) {
2649 ret = 1;
2650 goto reneg_ok;
2651 }
2652 /* SSL handshake needs to read, L4 connection is ready */
2653 if (conn->flags & CO_FL_WAIT_L4_CONN)
2654 conn->flags &= ~CO_FL_WAIT_L4_CONN;
2655 __conn_sock_stop_send(conn);
Willy Tarreaue1f50c42014-01-22 20:02:06 +01002656 __conn_sock_want_recv(conn);
2657 fd_cant_recv(conn->t.sock.fd);
Emeric Brun674b7432012-11-08 19:21:55 +01002658 return 0;
2659 }
2660 else if (ret == SSL_ERROR_SYSCALL) {
2661 /* if errno is null, then connection was successfully established */
2662 if (!errno && conn->flags & CO_FL_WAIT_L4_CONN)
2663 conn->flags &= ~CO_FL_WAIT_L4_CONN;
Willy Tarreau20879a02012-12-03 16:32:10 +01002664 if (!conn->err_code) {
Emeric Brun29f037d2014-04-25 19:05:36 +02002665 if (!((SSL *)conn->xprt_ctx)->packet_length) {
2666 if (!errno) {
2667 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
2668 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
2669 else
2670 conn->err_code = CO_ER_SSL_EMPTY;
2671 }
2672 else {
2673 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
2674 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
2675 else
2676 conn->err_code = CO_ER_SSL_ABORT;
2677 }
2678 }
2679 else {
2680 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
2681 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
Willy Tarreau20879a02012-12-03 16:32:10 +01002682 else
Emeric Brun29f037d2014-04-25 19:05:36 +02002683 conn->err_code = CO_ER_SSL_HANDSHAKE;
2684 }
Willy Tarreau20879a02012-12-03 16:32:10 +01002685 }
Emeric Brun674b7432012-11-08 19:21:55 +01002686 goto out_error;
2687 }
2688 else {
2689 /* Fail on all other handshake errors */
2690 /* Note: OpenSSL may leave unread bytes in the socket's
2691 * buffer, causing an RST to be emitted upon close() on
2692 * TCP sockets. We first try to drain possibly pending
2693 * data to avoid this as much as possible.
2694 */
Willy Tarreaud85c4852015-03-13 00:40:28 +01002695 conn_sock_drain(conn);
Willy Tarreau20879a02012-12-03 16:32:10 +01002696 if (!conn->err_code)
Willy Tarreauf51c6982014-04-25 20:02:39 +02002697 conn->err_code = (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT) ?
2698 CO_ER_SSL_KILLED_HB : CO_ER_SSL_HANDSHAKE;
Emeric Brun674b7432012-11-08 19:21:55 +01002699 goto out_error;
2700 }
2701 }
2702 /* read some data: consider handshake completed */
2703 goto reneg_ok;
2704 }
2705
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02002706 ret = SSL_do_handshake(conn->xprt_ctx);
Emeric Brun46591952012-05-18 15:47:34 +02002707 if (ret != 1) {
2708 /* handshake did not complete, let's find why */
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02002709 ret = SSL_get_error(conn->xprt_ctx, ret);
Emeric Brun46591952012-05-18 15:47:34 +02002710
2711 if (ret == SSL_ERROR_WANT_WRITE) {
2712 /* SSL handshake needs to write, L4 connection may not be ready */
2713 __conn_sock_stop_recv(conn);
Willy Tarreaue1f50c42014-01-22 20:02:06 +01002714 __conn_sock_want_send(conn);
2715 fd_cant_send(conn->t.sock.fd);
Emeric Brun46591952012-05-18 15:47:34 +02002716 return 0;
2717 }
2718 else if (ret == SSL_ERROR_WANT_READ) {
2719 /* SSL handshake needs to read, L4 connection is ready */
2720 if (conn->flags & CO_FL_WAIT_L4_CONN)
2721 conn->flags &= ~CO_FL_WAIT_L4_CONN;
2722 __conn_sock_stop_send(conn);
Willy Tarreaue1f50c42014-01-22 20:02:06 +01002723 __conn_sock_want_recv(conn);
2724 fd_cant_recv(conn->t.sock.fd);
Emeric Brun46591952012-05-18 15:47:34 +02002725 return 0;
2726 }
Willy Tarreau89230192012-09-28 20:22:13 +02002727 else if (ret == SSL_ERROR_SYSCALL) {
2728 /* if errno is null, then connection was successfully established */
2729 if (!errno && conn->flags & CO_FL_WAIT_L4_CONN)
2730 conn->flags &= ~CO_FL_WAIT_L4_CONN;
Willy Tarreau20879a02012-12-03 16:32:10 +01002731
Emeric Brun29f037d2014-04-25 19:05:36 +02002732 if (!((SSL *)conn->xprt_ctx)->packet_length) {
2733 if (!errno) {
2734 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
2735 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
2736 else
2737 conn->err_code = CO_ER_SSL_EMPTY;
2738 }
2739 else {
2740 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
2741 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
2742 else
2743 conn->err_code = CO_ER_SSL_ABORT;
2744 }
2745 }
2746 else {
2747 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
2748 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
Willy Tarreau20879a02012-12-03 16:32:10 +01002749 else
Emeric Brun29f037d2014-04-25 19:05:36 +02002750 conn->err_code = CO_ER_SSL_HANDSHAKE;
2751 }
Willy Tarreau89230192012-09-28 20:22:13 +02002752 goto out_error;
2753 }
Emeric Brun46591952012-05-18 15:47:34 +02002754 else {
2755 /* Fail on all other handshake errors */
Willy Tarreau566dc552012-10-19 20:52:18 +02002756 /* Note: OpenSSL may leave unread bytes in the socket's
2757 * buffer, causing an RST to be emitted upon close() on
2758 * TCP sockets. We first try to drain possibly pending
2759 * data to avoid this as much as possible.
2760 */
Willy Tarreaud85c4852015-03-13 00:40:28 +01002761 conn_sock_drain(conn);
Willy Tarreau20879a02012-12-03 16:32:10 +01002762 if (!conn->err_code)
Willy Tarreauf51c6982014-04-25 20:02:39 +02002763 conn->err_code = (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT) ?
2764 CO_ER_SSL_KILLED_HB : CO_ER_SSL_HANDSHAKE;
Emeric Brun46591952012-05-18 15:47:34 +02002765 goto out_error;
2766 }
2767 }
2768
Emeric Brun674b7432012-11-08 19:21:55 +01002769reneg_ok:
2770
Emeric Brun46591952012-05-18 15:47:34 +02002771 /* Handshake succeeded */
Willy Tarreau0c9c2722014-05-28 12:28:58 +02002772 if (!SSL_session_reused(conn->xprt_ctx)) {
2773 if (objt_server(conn->target)) {
2774 update_freq_ctr(&global.ssl_be_keys_per_sec, 1);
2775 if (global.ssl_be_keys_per_sec.curr_ctr > global.ssl_be_keys_max)
2776 global.ssl_be_keys_max = global.ssl_be_keys_per_sec.curr_ctr;
2777
Emeric Brun46591952012-05-18 15:47:34 +02002778 /* check if session was reused, if not store current session on server for reuse */
Willy Tarreau3fdb3662012-11-12 00:42:33 +01002779 if (objt_server(conn->target)->ssl_ctx.reused_sess)
2780 SSL_SESSION_free(objt_server(conn->target)->ssl_ctx.reused_sess);
Emeric Brun46591952012-05-18 15:47:34 +02002781
Willy Tarreau2a3fb1c2015-02-05 16:47:07 +01002782 if (!(objt_server(conn->target)->ssl_ctx.options & SRV_SSL_O_NO_REUSE))
2783 objt_server(conn->target)->ssl_ctx.reused_sess = SSL_get1_session(conn->xprt_ctx);
Emeric Brun46591952012-05-18 15:47:34 +02002784 }
Willy Tarreau0c9c2722014-05-28 12:28:58 +02002785 else {
2786 update_freq_ctr(&global.ssl_fe_keys_per_sec, 1);
2787 if (global.ssl_fe_keys_per_sec.curr_ctr > global.ssl_fe_keys_max)
2788 global.ssl_fe_keys_max = global.ssl_fe_keys_per_sec.curr_ctr;
2789 }
Emeric Brun46591952012-05-18 15:47:34 +02002790 }
2791
2792 /* The connection is now established at both layers, it's time to leave */
2793 conn->flags &= ~(flag | CO_FL_WAIT_L4_CONN | CO_FL_WAIT_L6_CONN);
2794 return 1;
2795
2796 out_error:
Emeric Brun644cde02012-12-14 11:21:13 +01002797 /* Clear openssl global errors stack */
2798 ERR_clear_error();
2799
Emeric Brun9fa89732012-10-04 17:09:56 +02002800 /* free resumed session if exists */
Willy Tarreau3fdb3662012-11-12 00:42:33 +01002801 if (objt_server(conn->target) && objt_server(conn->target)->ssl_ctx.reused_sess) {
2802 SSL_SESSION_free(objt_server(conn->target)->ssl_ctx.reused_sess);
2803 objt_server(conn->target)->ssl_ctx.reused_sess = NULL;
Emeric Brun9fa89732012-10-04 17:09:56 +02002804 }
2805
Emeric Brun46591952012-05-18 15:47:34 +02002806 /* Fail on all other handshake errors */
2807 conn->flags |= CO_FL_ERROR;
Willy Tarreau20879a02012-12-03 16:32:10 +01002808 if (!conn->err_code)
2809 conn->err_code = CO_ER_SSL_HANDSHAKE;
Emeric Brun46591952012-05-18 15:47:34 +02002810 return 0;
2811}
2812
2813/* Receive up to <count> bytes from connection <conn>'s socket and store them
Willy Tarreauabf08d92014-01-14 11:31:27 +01002814 * into buffer <buf>. Only one call to recv() is performed, unless the
Emeric Brun46591952012-05-18 15:47:34 +02002815 * buffer wraps, in which case a second call may be performed. The connection's
2816 * flags are updated with whatever special event is detected (error, read0,
2817 * empty). The caller is responsible for taking care of those events and
2818 * avoiding the call if inappropriate. The function does not call the
2819 * connection's polling update function, so the caller is responsible for this.
2820 */
2821static int ssl_sock_to_buf(struct connection *conn, struct buffer *buf, int count)
2822{
2823 int ret, done = 0;
Willy Tarreauabf08d92014-01-14 11:31:27 +01002824 int try;
Emeric Brun46591952012-05-18 15:47:34 +02002825
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02002826 if (!conn->xprt_ctx)
Emeric Brun46591952012-05-18 15:47:34 +02002827 goto out_error;
2828
2829 if (conn->flags & CO_FL_HANDSHAKE)
2830 /* a handshake was requested */
2831 return 0;
2832
Willy Tarreauabf08d92014-01-14 11:31:27 +01002833 /* let's realign the buffer to optimize I/O */
2834 if (buffer_empty(buf))
Emeric Brun46591952012-05-18 15:47:34 +02002835 buf->p = buf->data;
Emeric Brun46591952012-05-18 15:47:34 +02002836
2837 /* read the largest possible block. For this, we perform only one call
2838 * to recv() unless the buffer wraps and we exactly fill the first hunk,
2839 * in which case we accept to do it once again. A new attempt is made on
2840 * EINTR too.
2841 */
Willy Tarreau00b0fb92014-01-17 11:09:40 +01002842 while (count > 0) {
Willy Tarreauabf08d92014-01-14 11:31:27 +01002843 /* first check if we have some room after p+i */
2844 try = buf->data + buf->size - (buf->p + buf->i);
2845 /* otherwise continue between data and p-o */
2846 if (try <= 0) {
2847 try = buf->p - (buf->data + buf->o);
2848 if (try <= 0)
2849 break;
2850 }
2851 if (try > count)
2852 try = count;
2853
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02002854 ret = SSL_read(conn->xprt_ctx, bi_end(buf), try);
Emeric Brune1f38db2012-09-03 20:36:47 +02002855 if (conn->flags & CO_FL_ERROR) {
2856 /* CO_FL_ERROR may be set by ssl_sock_infocbk */
Emeric Brun644cde02012-12-14 11:21:13 +01002857 goto out_error;
Emeric Brune1f38db2012-09-03 20:36:47 +02002858 }
Emeric Brun46591952012-05-18 15:47:34 +02002859 if (ret > 0) {
2860 buf->i += ret;
2861 done += ret;
2862 if (ret < try)
2863 break;
2864 count -= ret;
Emeric Brun46591952012-05-18 15:47:34 +02002865 }
2866 else if (ret == 0) {
Emeric Brun644cde02012-12-14 11:21:13 +01002867 ret = SSL_get_error(conn->xprt_ctx, ret);
2868 if (ret != SSL_ERROR_ZERO_RETURN) {
Emeric Brun1c646862012-12-14 12:33:41 +01002869 /* error on protocol or underlying transport */
2870 if ((ret != SSL_ERROR_SYSCALL)
2871 || (errno && (errno != EAGAIN)))
2872 conn->flags |= CO_FL_ERROR;
2873
Emeric Brun644cde02012-12-14 11:21:13 +01002874 /* Clear openssl global errors stack */
2875 ERR_clear_error();
2876 }
Emeric Brun46591952012-05-18 15:47:34 +02002877 goto read0;
2878 }
2879 else {
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02002880 ret = SSL_get_error(conn->xprt_ctx, ret);
Emeric Brun46591952012-05-18 15:47:34 +02002881 if (ret == SSL_ERROR_WANT_WRITE) {
Emeric Brun8af8dd12012-11-08 17:56:20 +01002882 /* handshake is running, and it needs to enable write */
Emeric Brun46591952012-05-18 15:47:34 +02002883 conn->flags |= CO_FL_SSL_WAIT_HS;
Emeric Brun8af8dd12012-11-08 17:56:20 +01002884 __conn_sock_want_send(conn);
Emeric Brun46591952012-05-18 15:47:34 +02002885 break;
2886 }
2887 else if (ret == SSL_ERROR_WANT_READ) {
Emeric Brun282a76a2012-11-08 18:02:56 +01002888 if (SSL_renegotiate_pending(conn->xprt_ctx)) {
2889 /* handshake is running, and it may need to re-enable read */
2890 conn->flags |= CO_FL_SSL_WAIT_HS;
2891 __conn_sock_want_recv(conn);
2892 break;
2893 }
Emeric Brun46591952012-05-18 15:47:34 +02002894 /* we need to poll for retry a read later */
Willy Tarreaue1f50c42014-01-22 20:02:06 +01002895 fd_cant_recv(conn->t.sock.fd);
Emeric Brun46591952012-05-18 15:47:34 +02002896 break;
2897 }
2898 /* otherwise it's a real error */
2899 goto out_error;
2900 }
2901 }
2902 return done;
2903
2904 read0:
2905 conn_sock_read0(conn);
2906 return done;
2907 out_error:
Emeric Brun644cde02012-12-14 11:21:13 +01002908 /* Clear openssl global errors stack */
2909 ERR_clear_error();
2910
Emeric Brun46591952012-05-18 15:47:34 +02002911 conn->flags |= CO_FL_ERROR;
2912 return done;
2913}
2914
2915
2916/* Send all pending bytes from buffer <buf> to connection <conn>'s socket.
Willy Tarreau1049b1f2014-02-02 01:51:17 +01002917 * <flags> may contain some CO_SFL_* flags to hint the system about other
2918 * pending data for example, but this flag is ignored at the moment.
Emeric Brun46591952012-05-18 15:47:34 +02002919 * Only one call to send() is performed, unless the buffer wraps, in which case
2920 * a second call may be performed. The connection's flags are updated with
2921 * whatever special event is detected (error, empty). The caller is responsible
2922 * for taking care of those events and avoiding the call if inappropriate. The
2923 * function does not call the connection's polling update function, so the caller
2924 * is responsible for this.
2925 */
2926static int ssl_sock_from_buf(struct connection *conn, struct buffer *buf, int flags)
2927{
2928 int ret, try, done;
2929
2930 done = 0;
2931
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02002932 if (!conn->xprt_ctx)
Emeric Brun46591952012-05-18 15:47:34 +02002933 goto out_error;
2934
2935 if (conn->flags & CO_FL_HANDSHAKE)
2936 /* a handshake was requested */
2937 return 0;
2938
2939 /* send the largest possible block. For this we perform only one call
2940 * to send() unless the buffer wraps and we exactly fill the first hunk,
2941 * in which case we accept to do it once again.
2942 */
2943 while (buf->o) {
Kevin Hestercad82342013-05-30 15:12:41 -07002944 try = bo_contig_data(buf);
Willy Tarreaubfd59462013-02-21 07:46:09 +01002945
Willy Tarreau7bed9452014-02-02 02:00:24 +01002946 if (!(flags & CO_SFL_STREAMER) &&
Willy Tarreau518cedd2014-02-17 15:43:01 +01002947 !(conn->xprt_st & SSL_SOCK_SEND_UNLIMITED) &&
2948 global.tune.ssl_max_record && try > global.tune.ssl_max_record) {
Willy Tarreaubfd59462013-02-21 07:46:09 +01002949 try = global.tune.ssl_max_record;
Willy Tarreau518cedd2014-02-17 15:43:01 +01002950 }
2951 else {
2952 /* we need to keep the information about the fact that
2953 * we're not limiting the upcoming send(), because if it
2954 * fails, we'll have to retry with at least as many data.
2955 */
2956 conn->xprt_st |= SSL_SOCK_SEND_UNLIMITED;
2957 }
Willy Tarreaubfd59462013-02-21 07:46:09 +01002958
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02002959 ret = SSL_write(conn->xprt_ctx, bo_ptr(buf), try);
Willy Tarreau518cedd2014-02-17 15:43:01 +01002960
Emeric Brune1f38db2012-09-03 20:36:47 +02002961 if (conn->flags & CO_FL_ERROR) {
2962 /* CO_FL_ERROR may be set by ssl_sock_infocbk */
Emeric Brun644cde02012-12-14 11:21:13 +01002963 goto out_error;
Emeric Brune1f38db2012-09-03 20:36:47 +02002964 }
Emeric Brun46591952012-05-18 15:47:34 +02002965 if (ret > 0) {
Willy Tarreau518cedd2014-02-17 15:43:01 +01002966 conn->xprt_st &= ~SSL_SOCK_SEND_UNLIMITED;
2967
Emeric Brun46591952012-05-18 15:47:34 +02002968 buf->o -= ret;
2969 done += ret;
2970
Willy Tarreau5fb38032012-12-16 19:39:09 +01002971 if (likely(buffer_empty(buf)))
Emeric Brun46591952012-05-18 15:47:34 +02002972 /* optimize data alignment in the buffer */
2973 buf->p = buf->data;
2974
2975 /* if the system buffer is full, don't insist */
2976 if (ret < try)
2977 break;
2978 }
2979 else {
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02002980 ret = SSL_get_error(conn->xprt_ctx, ret);
Emeric Brun46591952012-05-18 15:47:34 +02002981 if (ret == SSL_ERROR_WANT_WRITE) {
Emeric Brun282a76a2012-11-08 18:02:56 +01002982 if (SSL_renegotiate_pending(conn->xprt_ctx)) {
2983 /* handshake is running, and it may need to re-enable write */
2984 conn->flags |= CO_FL_SSL_WAIT_HS;
2985 __conn_sock_want_send(conn);
2986 break;
2987 }
Emeric Brun46591952012-05-18 15:47:34 +02002988 /* we need to poll to retry a write later */
Willy Tarreaue1f50c42014-01-22 20:02:06 +01002989 fd_cant_send(conn->t.sock.fd);
Emeric Brun46591952012-05-18 15:47:34 +02002990 break;
2991 }
2992 else if (ret == SSL_ERROR_WANT_READ) {
Emeric Brun8af8dd12012-11-08 17:56:20 +01002993 /* handshake is running, and it needs to enable read */
Emeric Brun46591952012-05-18 15:47:34 +02002994 conn->flags |= CO_FL_SSL_WAIT_HS;
Emeric Brun8af8dd12012-11-08 17:56:20 +01002995 __conn_sock_want_recv(conn);
Emeric Brun46591952012-05-18 15:47:34 +02002996 break;
2997 }
2998 goto out_error;
2999 }
3000 }
3001 return done;
3002
3003 out_error:
Emeric Brun644cde02012-12-14 11:21:13 +01003004 /* Clear openssl global errors stack */
3005 ERR_clear_error();
3006
Emeric Brun46591952012-05-18 15:47:34 +02003007 conn->flags |= CO_FL_ERROR;
3008 return done;
3009}
3010
Emeric Brun46591952012-05-18 15:47:34 +02003011static void ssl_sock_close(struct connection *conn) {
3012
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02003013 if (conn->xprt_ctx) {
3014 SSL_free(conn->xprt_ctx);
3015 conn->xprt_ctx = NULL;
Willy Tarreau403edff2012-09-06 11:58:37 +02003016 sslconns--;
Emeric Brun46591952012-05-18 15:47:34 +02003017 }
Emeric Brun46591952012-05-18 15:47:34 +02003018}
3019
3020/* This function tries to perform a clean shutdown on an SSL connection, and in
3021 * any case, flags the connection as reusable if no handshake was in progress.
3022 */
3023static void ssl_sock_shutw(struct connection *conn, int clean)
3024{
3025 if (conn->flags & CO_FL_HANDSHAKE)
3026 return;
3027 /* no handshake was in progress, try a clean ssl shutdown */
Emeric Brun644cde02012-12-14 11:21:13 +01003028 if (clean && (SSL_shutdown(conn->xprt_ctx) <= 0)) {
3029 /* Clear openssl global errors stack */
3030 ERR_clear_error();
3031 }
Emeric Brun46591952012-05-18 15:47:34 +02003032
3033 /* force flag on ssl to keep session in cache regardless shutdown result */
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02003034 SSL_set_shutdown(conn->xprt_ctx, SSL_SENT_SHUTDOWN);
Emeric Brun46591952012-05-18 15:47:34 +02003035}
3036
Willy Tarreauffc3fcd2012-10-12 20:17:54 +02003037/* used for logging, may be changed for a sample fetch later */
3038const char *ssl_sock_get_cipher_name(struct connection *conn)
3039{
3040 if (!conn->xprt && !conn->xprt_ctx)
3041 return NULL;
3042 return SSL_get_cipher_name(conn->xprt_ctx);
3043}
3044
3045/* used for logging, may be changed for a sample fetch later */
3046const char *ssl_sock_get_proto_version(struct connection *conn)
3047{
3048 if (!conn->xprt && !conn->xprt_ctx)
3049 return NULL;
3050 return SSL_get_version(conn->xprt_ctx);
3051}
3052
Willy Tarreau8d598402012-10-22 17:58:39 +02003053/* Extract a serial from a cert, and copy it to a chunk.
3054 * Returns 1 if serial is found and copied, 0 if no serial found and
3055 * -1 if output is not large enough.
3056 */
3057static int
3058ssl_sock_get_serial(X509 *crt, struct chunk *out)
3059{
3060 ASN1_INTEGER *serial;
3061
3062 serial = X509_get_serialNumber(crt);
3063 if (!serial)
3064 return 0;
3065
3066 if (out->size < serial->length)
3067 return -1;
3068
3069 memcpy(out->str, serial->data, serial->length);
3070 out->len = serial->length;
3071 return 1;
3072}
3073
Emeric Brun43e79582014-10-29 19:03:26 +01003074/* Extract a cert to der, and copy it to a chunk.
3075 * Returns 1 if cert is found and copied, 0 on der convertion failure and
3076 * -1 if output is not large enough.
3077 */
3078static int
3079ssl_sock_crt2der(X509 *crt, struct chunk *out)
3080{
3081 int len;
3082 unsigned char *p = (unsigned char *)out->str;;
3083
3084 len =i2d_X509(crt, NULL);
3085 if (len <= 0)
3086 return 1;
3087
3088 if (out->size < len)
3089 return -1;
3090
3091 i2d_X509(crt,&p);
3092 out->len = len;
3093 return 1;
3094}
3095
Emeric Brunce5ad802012-10-22 14:11:22 +02003096
3097/* Copy Date in ASN1_UTCTIME format in struct chunk out.
3098 * Returns 1 if serial is found and copied, 0 if no valid time found
3099 * and -1 if output is not large enough.
3100 */
3101static int
3102ssl_sock_get_time(ASN1_TIME *tm, struct chunk *out)
3103{
3104 if (tm->type == V_ASN1_GENERALIZEDTIME) {
3105 ASN1_GENERALIZEDTIME *gentm = (ASN1_GENERALIZEDTIME *)tm;
3106
3107 if (gentm->length < 12)
3108 return 0;
3109 if (gentm->data[0] != 0x32 || gentm->data[1] != 0x30)
3110 return 0;
3111 if (out->size < gentm->length-2)
3112 return -1;
3113
3114 memcpy(out->str, gentm->data+2, gentm->length-2);
3115 out->len = gentm->length-2;
3116 return 1;
3117 }
3118 else if (tm->type == V_ASN1_UTCTIME) {
3119 ASN1_UTCTIME *utctm = (ASN1_UTCTIME *)tm;
3120
3121 if (utctm->length < 10)
3122 return 0;
3123 if (utctm->data[0] >= 0x35)
3124 return 0;
3125 if (out->size < utctm->length)
3126 return -1;
3127
3128 memcpy(out->str, utctm->data, utctm->length);
3129 out->len = utctm->length;
3130 return 1;
3131 }
3132
3133 return 0;
3134}
3135
Emeric Brun87855892012-10-17 17:39:35 +02003136/* Extract an entry from a X509_NAME and copy its value to an output chunk.
3137 * Returns 1 if entry found, 0 if entry not found, or -1 if output not large enough.
3138 */
3139static int
3140ssl_sock_get_dn_entry(X509_NAME *a, const struct chunk *entry, int pos, struct chunk *out)
3141{
3142 X509_NAME_ENTRY *ne;
3143 int i, j, n;
3144 int cur = 0;
3145 const char *s;
3146 char tmp[128];
3147
3148 out->len = 0;
3149 for (i = 0; i < sk_X509_NAME_ENTRY_num(a->entries); i++) {
3150 if (pos < 0)
3151 j = (sk_X509_NAME_ENTRY_num(a->entries)-1) - i;
3152 else
3153 j = i;
3154
3155 ne = sk_X509_NAME_ENTRY_value(a->entries, j);
3156 n = OBJ_obj2nid(ne->object);
3157 if ((n == NID_undef) || ((s = OBJ_nid2sn(n)) == NULL)) {
3158 i2t_ASN1_OBJECT(tmp, sizeof(tmp), ne->object);
3159 s = tmp;
3160 }
3161
3162 if (chunk_strcasecmp(entry, s) != 0)
3163 continue;
3164
3165 if (pos < 0)
3166 cur--;
3167 else
3168 cur++;
3169
3170 if (cur != pos)
3171 continue;
3172
3173 if (ne->value->length > out->size)
3174 return -1;
3175
3176 memcpy(out->str, ne->value->data, ne->value->length);
3177 out->len = ne->value->length;
3178 return 1;
3179 }
3180
3181 return 0;
3182
3183}
3184
3185/* Extract and format full DN from a X509_NAME and copy result into a chunk
3186 * Returns 1 if dn entries exits, 0 if no dn entry found or -1 if output is not large enough.
3187 */
3188static int
3189ssl_sock_get_dn_oneline(X509_NAME *a, struct chunk *out)
3190{
3191 X509_NAME_ENTRY *ne;
3192 int i, n, ln;
3193 int l = 0;
3194 const char *s;
3195 char *p;
3196 char tmp[128];
3197
3198 out->len = 0;
3199 p = out->str;
3200 for (i = 0; i < sk_X509_NAME_ENTRY_num(a->entries); i++) {
3201 ne = sk_X509_NAME_ENTRY_value(a->entries, i);
3202 n = OBJ_obj2nid(ne->object);
3203 if ((n == NID_undef) || ((s = OBJ_nid2sn(n)) == NULL)) {
3204 i2t_ASN1_OBJECT(tmp, sizeof(tmp), ne->object);
3205 s = tmp;
3206 }
3207 ln = strlen(s);
3208
3209 l += 1 + ln + 1 + ne->value->length;
3210 if (l > out->size)
3211 return -1;
3212 out->len = l;
3213
3214 *(p++)='/';
3215 memcpy(p, s, ln);
3216 p += ln;
3217 *(p++)='=';
3218 memcpy(p, ne->value->data, ne->value->length);
3219 p += ne->value->length;
3220 }
3221
3222 if (!out->len)
3223 return 0;
3224
3225 return 1;
3226}
3227
David Safb76832014-05-08 23:42:08 -04003228char *ssl_sock_get_version(struct connection *conn)
3229{
3230 if (!ssl_sock_is_ssl(conn))
3231 return NULL;
3232
3233 return (char *)SSL_get_version(conn->xprt_ctx);
3234}
3235
Emeric Brun0abf8362014-06-24 18:26:41 +02003236/* Extract peer certificate's common name into the chunk dest
3237 * Returns
3238 * the len of the extracted common name
3239 * or 0 if no CN found in DN
3240 * or -1 on error case (i.e. no peer certificate)
3241 */
3242int ssl_sock_get_remote_common_name(struct connection *conn, struct chunk *dest)
David Safb76832014-05-08 23:42:08 -04003243{
3244 X509 *crt = NULL;
3245 X509_NAME *name;
David Safb76832014-05-08 23:42:08 -04003246 const char find_cn[] = "CN";
3247 const struct chunk find_cn_chunk = {
3248 .str = (char *)&find_cn,
3249 .len = sizeof(find_cn)-1
3250 };
Emeric Brun0abf8362014-06-24 18:26:41 +02003251 int result = -1;
David Safb76832014-05-08 23:42:08 -04003252
3253 if (!ssl_sock_is_ssl(conn))
Emeric Brun0abf8362014-06-24 18:26:41 +02003254 goto out;
David Safb76832014-05-08 23:42:08 -04003255
3256 /* SSL_get_peer_certificate, it increase X509 * ref count */
3257 crt = SSL_get_peer_certificate(conn->xprt_ctx);
3258 if (!crt)
3259 goto out;
3260
3261 name = X509_get_subject_name(crt);
3262 if (!name)
3263 goto out;
David Safb76832014-05-08 23:42:08 -04003264
Emeric Brun0abf8362014-06-24 18:26:41 +02003265 result = ssl_sock_get_dn_entry(name, &find_cn_chunk, 1, dest);
3266out:
David Safb76832014-05-08 23:42:08 -04003267 if (crt)
3268 X509_free(crt);
3269
3270 return result;
3271}
3272
Dave McCowan328fb582014-07-30 10:39:13 -04003273/* returns 1 if client passed a certificate for this session, 0 if not */
3274int ssl_sock_get_cert_used_sess(struct connection *conn)
3275{
3276 X509 *crt = NULL;
3277
3278 if (!ssl_sock_is_ssl(conn))
3279 return 0;
3280
3281 /* SSL_get_peer_certificate, it increase X509 * ref count */
3282 crt = SSL_get_peer_certificate(conn->xprt_ctx);
3283 if (!crt)
3284 return 0;
3285
3286 X509_free(crt);
3287 return 1;
3288}
3289
3290/* returns 1 if client passed a certificate for this connection, 0 if not */
3291int ssl_sock_get_cert_used_conn(struct connection *conn)
David Safb76832014-05-08 23:42:08 -04003292{
3293 if (!ssl_sock_is_ssl(conn))
3294 return 0;
3295
3296 return SSL_SOCK_ST_FL_VERIFY_DONE & conn->xprt_st ? 1 : 0;
3297}
3298
3299/* returns result from SSL verify */
3300unsigned int ssl_sock_get_verify_result(struct connection *conn)
3301{
3302 if (!ssl_sock_is_ssl(conn))
3303 return (unsigned int)X509_V_ERR_APPLICATION_VERIFICATION;
3304
3305 return (unsigned int)SSL_get_verify_result(conn->xprt_ctx);
3306}
3307
Willy Tarreau7875d092012-09-10 08:20:03 +02003308/***** Below are some sample fetching functions for ACL/patterns *****/
3309
Emeric Brune64aef12012-09-21 13:15:06 +02003310/* boolean, returns true if client cert was present */
3311static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02003312smp_fetch_ssl_fc_has_crt(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brune64aef12012-09-21 13:15:06 +02003313{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003314 struct connection *conn;
3315
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02003316 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003317 if (!conn || conn->xprt != &ssl_sock)
Emeric Brune64aef12012-09-21 13:15:06 +02003318 return 0;
3319
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003320 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brune64aef12012-09-21 13:15:06 +02003321 smp->flags |= SMP_F_MAY_CHANGE;
3322 return 0;
3323 }
3324
3325 smp->flags = 0;
3326 smp->type = SMP_T_BOOL;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003327 smp->data.uint = SSL_SOCK_ST_FL_VERIFY_DONE & conn->xprt_st ? 1 : 0;
Emeric Brune64aef12012-09-21 13:15:06 +02003328
3329 return 1;
3330}
3331
Emeric Brun43e79582014-10-29 19:03:26 +01003332/* binary, returns a certificate in a binary chunk (der/raw).
3333 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
3334 * should be use.
3335 */
3336static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02003337smp_fetch_ssl_x_der(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun43e79582014-10-29 19:03:26 +01003338{
3339 int cert_peer = (kw[4] == 'c') ? 1 : 0;
3340 X509 *crt = NULL;
3341 int ret = 0;
3342 struct chunk *smp_trash;
3343 struct connection *conn;
3344
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02003345 conn = objt_conn(smp->sess->origin);
Emeric Brun43e79582014-10-29 19:03:26 +01003346 if (!conn || conn->xprt != &ssl_sock)
3347 return 0;
3348
3349 if (!(conn->flags & CO_FL_CONNECTED)) {
3350 smp->flags |= SMP_F_MAY_CHANGE;
3351 return 0;
3352 }
3353
3354 if (cert_peer)
3355 crt = SSL_get_peer_certificate(conn->xprt_ctx);
3356 else
3357 crt = SSL_get_certificate(conn->xprt_ctx);
3358
3359 if (!crt)
3360 goto out;
3361
3362 smp_trash = get_trash_chunk();
3363 if (ssl_sock_crt2der(crt, smp_trash) <= 0)
3364 goto out;
3365
3366 smp->data.str = *smp_trash;
3367 smp->type = SMP_T_BIN;
3368 ret = 1;
3369out:
3370 /* SSL_get_peer_certificate, it increase X509 * ref count */
3371 if (cert_peer && crt)
3372 X509_free(crt);
3373 return ret;
3374}
3375
Emeric Brunba841a12014-04-30 17:05:08 +02003376/* binary, returns serial of certificate in a binary chunk.
3377 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
3378 * should be use.
3379 */
Willy Tarreau8d598402012-10-22 17:58:39 +02003380static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02003381smp_fetch_ssl_x_serial(const struct arg *args, struct sample *smp, const char *kw, void *private)
Willy Tarreau8d598402012-10-22 17:58:39 +02003382{
Emeric Brunba841a12014-04-30 17:05:08 +02003383 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Willy Tarreau8d598402012-10-22 17:58:39 +02003384 X509 *crt = NULL;
3385 int ret = 0;
3386 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003387 struct connection *conn;
3388
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02003389 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003390 if (!conn || conn->xprt != &ssl_sock)
Willy Tarreau8d598402012-10-22 17:58:39 +02003391 return 0;
3392
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003393 if (!(conn->flags & CO_FL_CONNECTED)) {
Willy Tarreau8d598402012-10-22 17:58:39 +02003394 smp->flags |= SMP_F_MAY_CHANGE;
3395 return 0;
3396 }
3397
Emeric Brunba841a12014-04-30 17:05:08 +02003398 if (cert_peer)
3399 crt = SSL_get_peer_certificate(conn->xprt_ctx);
3400 else
3401 crt = SSL_get_certificate(conn->xprt_ctx);
3402
Willy Tarreau8d598402012-10-22 17:58:39 +02003403 if (!crt)
3404 goto out;
3405
Willy Tarreau47ca5452012-12-23 20:22:19 +01003406 smp_trash = get_trash_chunk();
Willy Tarreau8d598402012-10-22 17:58:39 +02003407 if (ssl_sock_get_serial(crt, smp_trash) <= 0)
3408 goto out;
3409
3410 smp->data.str = *smp_trash;
3411 smp->type = SMP_T_BIN;
3412 ret = 1;
3413out:
Emeric Brunba841a12014-04-30 17:05:08 +02003414 /* SSL_get_peer_certificate, it increase X509 * ref count */
3415 if (cert_peer && crt)
Willy Tarreau8d598402012-10-22 17:58:39 +02003416 X509_free(crt);
3417 return ret;
3418}
Emeric Brune64aef12012-09-21 13:15:06 +02003419
Emeric Brunba841a12014-04-30 17:05:08 +02003420/* binary, returns the client certificate's SHA-1 fingerprint (SHA-1 hash of DER-encoded certificate) in a binary chunk.
3421 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
3422 * should be use.
3423 */
James Votha051b4a2013-05-14 20:37:59 +02003424static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02003425smp_fetch_ssl_x_sha1(const struct arg *args, struct sample *smp, const char *kw, void *private)
James Votha051b4a2013-05-14 20:37:59 +02003426{
Emeric Brunba841a12014-04-30 17:05:08 +02003427 int cert_peer = (kw[4] == 'c') ? 1 : 0;
James Votha051b4a2013-05-14 20:37:59 +02003428 X509 *crt = NULL;
3429 const EVP_MD *digest;
3430 int ret = 0;
3431 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003432 struct connection *conn;
James Votha051b4a2013-05-14 20:37:59 +02003433
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02003434 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003435 if (!conn || conn->xprt != &ssl_sock)
3436 return 0;
3437
3438 if (!(conn->flags & CO_FL_CONNECTED)) {
James Votha051b4a2013-05-14 20:37:59 +02003439 smp->flags |= SMP_F_MAY_CHANGE;
3440 return 0;
3441 }
3442
Emeric Brunba841a12014-04-30 17:05:08 +02003443 if (cert_peer)
3444 crt = SSL_get_peer_certificate(conn->xprt_ctx);
3445 else
3446 crt = SSL_get_certificate(conn->xprt_ctx);
James Votha051b4a2013-05-14 20:37:59 +02003447 if (!crt)
3448 goto out;
3449
3450 smp_trash = get_trash_chunk();
3451 digest = EVP_sha1();
3452 X509_digest(crt, digest, (unsigned char *)smp_trash->str, (unsigned int *)&smp_trash->len);
3453
3454 smp->data.str = *smp_trash;
3455 smp->type = SMP_T_BIN;
3456 ret = 1;
3457out:
Emeric Brunba841a12014-04-30 17:05:08 +02003458 /* SSL_get_peer_certificate, it increase X509 * ref count */
3459 if (cert_peer && crt)
James Votha051b4a2013-05-14 20:37:59 +02003460 X509_free(crt);
3461 return ret;
3462}
3463
Emeric Brunba841a12014-04-30 17:05:08 +02003464/* string, returns certificate's notafter date in ASN1_UTCTIME format.
3465 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
3466 * should be use.
3467 */
Emeric Brunce5ad802012-10-22 14:11:22 +02003468static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02003469smp_fetch_ssl_x_notafter(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brunce5ad802012-10-22 14:11:22 +02003470{
Emeric Brunba841a12014-04-30 17:05:08 +02003471 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brunce5ad802012-10-22 14:11:22 +02003472 X509 *crt = NULL;
3473 int ret = 0;
3474 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003475 struct connection *conn;
Emeric Brunce5ad802012-10-22 14:11:22 +02003476
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02003477 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003478 if (!conn || conn->xprt != &ssl_sock)
3479 return 0;
3480
3481 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunce5ad802012-10-22 14:11:22 +02003482 smp->flags |= SMP_F_MAY_CHANGE;
3483 return 0;
3484 }
3485
Emeric Brunba841a12014-04-30 17:05:08 +02003486 if (cert_peer)
3487 crt = SSL_get_peer_certificate(conn->xprt_ctx);
3488 else
3489 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brunce5ad802012-10-22 14:11:22 +02003490 if (!crt)
3491 goto out;
3492
Willy Tarreau47ca5452012-12-23 20:22:19 +01003493 smp_trash = get_trash_chunk();
Emeric Brunce5ad802012-10-22 14:11:22 +02003494 if (ssl_sock_get_time(X509_get_notAfter(crt), smp_trash) <= 0)
3495 goto out;
3496
3497 smp->data.str = *smp_trash;
3498 smp->type = SMP_T_STR;
3499 ret = 1;
3500out:
Emeric Brunba841a12014-04-30 17:05:08 +02003501 /* SSL_get_peer_certificate, it increase X509 * ref count */
3502 if (cert_peer && crt)
Emeric Brunce5ad802012-10-22 14:11:22 +02003503 X509_free(crt);
3504 return ret;
3505}
3506
Emeric Brunba841a12014-04-30 17:05:08 +02003507/* string, returns a string of a formatted full dn \C=..\O=..\OU=.. \CN=.. of certificate's issuer
3508 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
3509 * should be use.
3510 */
Emeric Brun87855892012-10-17 17:39:35 +02003511static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02003512smp_fetch_ssl_x_i_dn(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun87855892012-10-17 17:39:35 +02003513{
Emeric Brunba841a12014-04-30 17:05:08 +02003514 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brun87855892012-10-17 17:39:35 +02003515 X509 *crt = NULL;
3516 X509_NAME *name;
3517 int ret = 0;
3518 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003519 struct connection *conn;
Emeric Brun87855892012-10-17 17:39:35 +02003520
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02003521 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003522 if (!conn || conn->xprt != &ssl_sock)
3523 return 0;
3524
3525 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun87855892012-10-17 17:39:35 +02003526 smp->flags |= SMP_F_MAY_CHANGE;
3527 return 0;
3528 }
3529
Emeric Brunba841a12014-04-30 17:05:08 +02003530 if (cert_peer)
3531 crt = SSL_get_peer_certificate(conn->xprt_ctx);
3532 else
3533 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brun87855892012-10-17 17:39:35 +02003534 if (!crt)
3535 goto out;
3536
3537 name = X509_get_issuer_name(crt);
3538 if (!name)
3539 goto out;
3540
Willy Tarreau47ca5452012-12-23 20:22:19 +01003541 smp_trash = get_trash_chunk();
Emeric Brun87855892012-10-17 17:39:35 +02003542 if (args && args[0].type == ARGT_STR) {
3543 int pos = 1;
3544
3545 if (args[1].type == ARGT_SINT)
3546 pos = args[1].data.sint;
3547 else if (args[1].type == ARGT_UINT)
3548 pos =(int)args[1].data.uint;
3549
3550 if (ssl_sock_get_dn_entry(name, &args[0].data.str, pos, smp_trash) <= 0)
3551 goto out;
3552 }
3553 else if (ssl_sock_get_dn_oneline(name, smp_trash) <= 0)
3554 goto out;
3555
3556 smp->type = SMP_T_STR;
3557 smp->data.str = *smp_trash;
3558 ret = 1;
3559out:
Emeric Brunba841a12014-04-30 17:05:08 +02003560 /* SSL_get_peer_certificate, it increase X509 * ref count */
3561 if (cert_peer && crt)
Emeric Brun87855892012-10-17 17:39:35 +02003562 X509_free(crt);
3563 return ret;
3564}
3565
Emeric Brunba841a12014-04-30 17:05:08 +02003566/* string, returns notbefore date in ASN1_UTCTIME format.
3567 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
3568 * should be use.
3569 */
Emeric Brunce5ad802012-10-22 14:11:22 +02003570static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02003571smp_fetch_ssl_x_notbefore(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brunce5ad802012-10-22 14:11:22 +02003572{
Emeric Brunba841a12014-04-30 17:05:08 +02003573 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brunce5ad802012-10-22 14:11:22 +02003574 X509 *crt = NULL;
3575 int ret = 0;
3576 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003577 struct connection *conn;
3578
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02003579 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003580 if (!conn || conn->xprt != &ssl_sock)
Emeric Brunce5ad802012-10-22 14:11:22 +02003581 return 0;
3582
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003583 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunce5ad802012-10-22 14:11:22 +02003584 smp->flags |= SMP_F_MAY_CHANGE;
3585 return 0;
3586 }
3587
Emeric Brunba841a12014-04-30 17:05:08 +02003588 if (cert_peer)
3589 crt = SSL_get_peer_certificate(conn->xprt_ctx);
3590 else
3591 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brunce5ad802012-10-22 14:11:22 +02003592 if (!crt)
3593 goto out;
3594
Willy Tarreau47ca5452012-12-23 20:22:19 +01003595 smp_trash = get_trash_chunk();
Emeric Brunce5ad802012-10-22 14:11:22 +02003596 if (ssl_sock_get_time(X509_get_notBefore(crt), smp_trash) <= 0)
3597 goto out;
3598
3599 smp->data.str = *smp_trash;
3600 smp->type = SMP_T_STR;
3601 ret = 1;
3602out:
Emeric Brunba841a12014-04-30 17:05:08 +02003603 /* SSL_get_peer_certificate, it increase X509 * ref count */
3604 if (cert_peer && crt)
Emeric Brunce5ad802012-10-22 14:11:22 +02003605 X509_free(crt);
3606 return ret;
3607}
3608
Emeric Brunba841a12014-04-30 17:05:08 +02003609/* string, returns a string of a formatted full dn \C=..\O=..\OU=.. \CN=.. of certificate's subject
3610 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
3611 * should be use.
3612 */
Emeric Brun87855892012-10-17 17:39:35 +02003613static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02003614smp_fetch_ssl_x_s_dn(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun87855892012-10-17 17:39:35 +02003615{
Emeric Brunba841a12014-04-30 17:05:08 +02003616 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brun87855892012-10-17 17:39:35 +02003617 X509 *crt = NULL;
3618 X509_NAME *name;
3619 int ret = 0;
3620 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003621 struct connection *conn;
Emeric Brun87855892012-10-17 17:39:35 +02003622
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02003623 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003624 if (!conn || conn->xprt != &ssl_sock)
3625 return 0;
3626
3627 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun87855892012-10-17 17:39:35 +02003628 smp->flags |= SMP_F_MAY_CHANGE;
3629 return 0;
3630 }
3631
Emeric Brunba841a12014-04-30 17:05:08 +02003632 if (cert_peer)
3633 crt = SSL_get_peer_certificate(conn->xprt_ctx);
3634 else
3635 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brun87855892012-10-17 17:39:35 +02003636 if (!crt)
3637 goto out;
3638
3639 name = X509_get_subject_name(crt);
3640 if (!name)
3641 goto out;
3642
Willy Tarreau47ca5452012-12-23 20:22:19 +01003643 smp_trash = get_trash_chunk();
Emeric Brun87855892012-10-17 17:39:35 +02003644 if (args && args[0].type == ARGT_STR) {
3645 int pos = 1;
3646
3647 if (args[1].type == ARGT_SINT)
3648 pos = args[1].data.sint;
3649 else if (args[1].type == ARGT_UINT)
3650 pos =(int)args[1].data.uint;
3651
3652 if (ssl_sock_get_dn_entry(name, &args[0].data.str, pos, smp_trash) <= 0)
3653 goto out;
3654 }
3655 else if (ssl_sock_get_dn_oneline(name, smp_trash) <= 0)
3656 goto out;
3657
3658 smp->type = SMP_T_STR;
3659 smp->data.str = *smp_trash;
3660 ret = 1;
3661out:
Emeric Brunba841a12014-04-30 17:05:08 +02003662 /* SSL_get_peer_certificate, it increase X509 * ref count */
3663 if (cert_peer && crt)
Emeric Brun87855892012-10-17 17:39:35 +02003664 X509_free(crt);
3665 return ret;
3666}
Emeric Brun9143d372012-12-20 15:44:16 +01003667
3668/* integer, returns true if current session use a client certificate */
3669static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02003670smp_fetch_ssl_c_used(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun9143d372012-12-20 15:44:16 +01003671{
3672 X509 *crt;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003673 struct connection *conn;
Emeric Brun9143d372012-12-20 15:44:16 +01003674
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02003675 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003676 if (!conn || conn->xprt != &ssl_sock)
3677 return 0;
3678
3679 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun9143d372012-12-20 15:44:16 +01003680 smp->flags |= SMP_F_MAY_CHANGE;
3681 return 0;
3682 }
3683
3684 /* SSL_get_peer_certificate returns a ptr on allocated X509 struct */
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003685 crt = SSL_get_peer_certificate(conn->xprt_ctx);
Emeric Brun9143d372012-12-20 15:44:16 +01003686 if (crt) {
3687 X509_free(crt);
3688 }
3689
3690 smp->type = SMP_T_BOOL;
3691 smp->data.uint = (crt != NULL);
3692 return 1;
3693}
3694
Emeric Brunba841a12014-04-30 17:05:08 +02003695/* integer, returns the certificate version
3696 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
3697 * should be use.
3698 */
Emeric Bruna7359fd2012-10-17 15:03:11 +02003699static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02003700smp_fetch_ssl_x_version(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Bruna7359fd2012-10-17 15:03:11 +02003701{
Emeric Brunba841a12014-04-30 17:05:08 +02003702 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Bruna7359fd2012-10-17 15:03:11 +02003703 X509 *crt;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003704 struct connection *conn;
3705
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02003706 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003707 if (!conn || conn->xprt != &ssl_sock)
Emeric Bruna7359fd2012-10-17 15:03:11 +02003708 return 0;
3709
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003710 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Bruna7359fd2012-10-17 15:03:11 +02003711 smp->flags |= SMP_F_MAY_CHANGE;
3712 return 0;
3713 }
3714
Emeric Brunba841a12014-04-30 17:05:08 +02003715 if (cert_peer)
3716 crt = SSL_get_peer_certificate(conn->xprt_ctx);
3717 else
3718 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Bruna7359fd2012-10-17 15:03:11 +02003719 if (!crt)
3720 return 0;
3721
3722 smp->data.uint = (unsigned int)(1 + X509_get_version(crt));
Emeric Brunba841a12014-04-30 17:05:08 +02003723 /* SSL_get_peer_certificate increase X509 * ref count */
3724 if (cert_peer)
3725 X509_free(crt);
Emeric Bruna7359fd2012-10-17 15:03:11 +02003726 smp->type = SMP_T_UINT;
3727
3728 return 1;
3729}
3730
Emeric Brunba841a12014-04-30 17:05:08 +02003731/* string, returns the certificate's signature algorithm.
3732 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
3733 * should be use.
3734 */
Emeric Brun7f56e742012-10-19 18:15:40 +02003735static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02003736smp_fetch_ssl_x_sig_alg(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun7f56e742012-10-19 18:15:40 +02003737{
Emeric Brunba841a12014-04-30 17:05:08 +02003738 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brun7f56e742012-10-19 18:15:40 +02003739 X509 *crt;
3740 int nid;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003741 struct connection *conn;
Emeric Brun7f56e742012-10-19 18:15:40 +02003742
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02003743 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003744 if (!conn || conn->xprt != &ssl_sock)
3745 return 0;
3746
3747 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun7f56e742012-10-19 18:15:40 +02003748 smp->flags |= SMP_F_MAY_CHANGE;
3749 return 0;
3750 }
3751
Emeric Brunba841a12014-04-30 17:05:08 +02003752 if (cert_peer)
3753 crt = SSL_get_peer_certificate(conn->xprt_ctx);
3754 else
3755 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brun7f56e742012-10-19 18:15:40 +02003756 if (!crt)
3757 return 0;
3758
3759 nid = OBJ_obj2nid((ASN1_OBJECT *)(crt->cert_info->signature->algorithm));
3760
3761 smp->data.str.str = (char *)OBJ_nid2sn(nid);
Emeric Brun9bf3ba22013-10-07 14:31:44 +02003762 if (!smp->data.str.str) {
Emeric Brunba841a12014-04-30 17:05:08 +02003763 /* SSL_get_peer_certificate increase X509 * ref count */
3764 if (cert_peer)
3765 X509_free(crt);
Emeric Brun7f56e742012-10-19 18:15:40 +02003766 return 0;
Emeric Brun9bf3ba22013-10-07 14:31:44 +02003767 }
Emeric Brun7f56e742012-10-19 18:15:40 +02003768
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01003769 smp->type = SMP_T_STR;
3770 smp->flags |= SMP_F_CONST;
Emeric Brun7f56e742012-10-19 18:15:40 +02003771 smp->data.str.len = strlen(smp->data.str.str);
Emeric Brunba841a12014-04-30 17:05:08 +02003772 /* SSL_get_peer_certificate increase X509 * ref count */
3773 if (cert_peer)
3774 X509_free(crt);
Emeric Brun7f56e742012-10-19 18:15:40 +02003775
3776 return 1;
3777}
3778
Emeric Brunba841a12014-04-30 17:05:08 +02003779/* string, returns the certificate's key algorithm.
3780 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
3781 * should be use.
3782 */
Emeric Brun521a0112012-10-22 12:22:55 +02003783static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02003784smp_fetch_ssl_x_key_alg(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun521a0112012-10-22 12:22:55 +02003785{
Emeric Brunba841a12014-04-30 17:05:08 +02003786 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brun521a0112012-10-22 12:22:55 +02003787 X509 *crt;
3788 int nid;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003789 struct connection *conn;
Emeric Brun521a0112012-10-22 12:22:55 +02003790
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02003791 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003792 if (!conn || conn->xprt != &ssl_sock)
3793 return 0;
3794
3795 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun521a0112012-10-22 12:22:55 +02003796 smp->flags |= SMP_F_MAY_CHANGE;
3797 return 0;
3798 }
3799
Emeric Brunba841a12014-04-30 17:05:08 +02003800 if (cert_peer)
3801 crt = SSL_get_peer_certificate(conn->xprt_ctx);
3802 else
3803 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brun521a0112012-10-22 12:22:55 +02003804 if (!crt)
3805 return 0;
3806
3807 nid = OBJ_obj2nid((ASN1_OBJECT *)(crt->cert_info->key->algor->algorithm));
3808
3809 smp->data.str.str = (char *)OBJ_nid2sn(nid);
Emeric Brun9bf3ba22013-10-07 14:31:44 +02003810 if (!smp->data.str.str) {
Emeric Brunba841a12014-04-30 17:05:08 +02003811 /* SSL_get_peer_certificate increase X509 * ref count */
3812 if (cert_peer)
3813 X509_free(crt);
Emeric Brun521a0112012-10-22 12:22:55 +02003814 return 0;
Emeric Brun9bf3ba22013-10-07 14:31:44 +02003815 }
Emeric Brun521a0112012-10-22 12:22:55 +02003816
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01003817 smp->type = SMP_T_STR;
3818 smp->flags |= SMP_F_CONST;
Emeric Brun521a0112012-10-22 12:22:55 +02003819 smp->data.str.len = strlen(smp->data.str.str);
Emeric Brunba841a12014-04-30 17:05:08 +02003820 if (cert_peer)
3821 X509_free(crt);
Emeric Brun521a0112012-10-22 12:22:55 +02003822
3823 return 1;
3824}
3825
Emeric Brun645ae792014-04-30 14:21:06 +02003826/* boolean, returns true if front conn. transport layer is SSL.
3827 * This function is also usable on backend conn if the fetch keyword 5th
3828 * char is 'b'.
3829 */
Willy Tarreau7875d092012-09-10 08:20:03 +02003830static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02003831smp_fetch_ssl_fc(const struct arg *args, struct sample *smp, const char *kw, void *private)
Willy Tarreau7875d092012-09-10 08:20:03 +02003832{
Emeric Brun645ae792014-04-30 14:21:06 +02003833 int back_conn = (kw[4] == 'b') ? 1 : 0;
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02003834 struct connection *conn = objt_conn(smp->strm->si[back_conn].end);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003835
Willy Tarreau7875d092012-09-10 08:20:03 +02003836 smp->type = SMP_T_BOOL;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003837 smp->data.uint = (conn && conn->xprt == &ssl_sock);
Willy Tarreau7875d092012-09-10 08:20:03 +02003838 return 1;
3839}
3840
Emeric Brun2525b6b2012-10-18 15:59:43 +02003841/* boolean, returns true if client present a SNI */
Willy Tarreau7875d092012-09-10 08:20:03 +02003842static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02003843smp_fetch_ssl_fc_has_sni(const struct arg *args, struct sample *smp, const char *kw, void *private)
Willy Tarreau7875d092012-09-10 08:20:03 +02003844{
3845#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02003846 struct connection *conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003847
Willy Tarreau7875d092012-09-10 08:20:03 +02003848 smp->type = SMP_T_BOOL;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003849 smp->data.uint = (conn && conn->xprt == &ssl_sock) &&
3850 conn->xprt_ctx &&
3851 SSL_get_servername(conn->xprt_ctx, TLSEXT_NAMETYPE_host_name) != NULL;
Willy Tarreau7875d092012-09-10 08:20:03 +02003852 return 1;
3853#else
3854 return 0;
3855#endif
3856}
3857
Nenad Merdanovic26ea8222015-05-18 02:28:57 +02003858/* boolean, returns true if client session has been resumed */
3859static int
3860smp_fetch_ssl_fc_is_resumed(const struct arg *args, struct sample *smp, const char *kw, void *private)
3861{
3862 struct connection *conn = objt_conn(smp->sess->origin);
3863
3864 smp->type = SMP_T_BOOL;
3865 smp->data.uint = (conn && conn->xprt == &ssl_sock) &&
3866 conn->xprt_ctx &&
3867 SSL_session_reused(conn->xprt_ctx);
3868 return 1;
3869}
3870
Emeric Brun645ae792014-04-30 14:21:06 +02003871/* string, returns the used cipher if front conn. transport layer is SSL.
3872 * This function is also usable on backend conn if the fetch keyword 5th
3873 * char is 'b'.
3874 */
Emeric Brun589fcad2012-10-16 14:13:26 +02003875static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02003876smp_fetch_ssl_fc_cipher(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun589fcad2012-10-16 14:13:26 +02003877{
Emeric Brun645ae792014-04-30 14:21:06 +02003878 int back_conn = (kw[4] == 'b') ? 1 : 0;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003879 struct connection *conn;
3880
Emeric Brun589fcad2012-10-16 14:13:26 +02003881 smp->flags = 0;
3882
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02003883 conn = objt_conn(smp->strm->si[back_conn].end);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003884 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
Emeric Brun589fcad2012-10-16 14:13:26 +02003885 return 0;
3886
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003887 smp->data.str.str = (char *)SSL_get_cipher_name(conn->xprt_ctx);
Emeric Brun589fcad2012-10-16 14:13:26 +02003888 if (!smp->data.str.str)
3889 return 0;
3890
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01003891 smp->type = SMP_T_STR;
3892 smp->flags |= SMP_F_CONST;
Emeric Brun589fcad2012-10-16 14:13:26 +02003893 smp->data.str.len = strlen(smp->data.str.str);
3894
3895 return 1;
3896}
3897
Emeric Brun645ae792014-04-30 14:21:06 +02003898/* integer, returns the algoritm's keysize if front conn. transport layer
3899 * is SSL.
3900 * This function is also usable on backend conn if the fetch keyword 5th
3901 * char is 'b'.
3902 */
Emeric Brun589fcad2012-10-16 14:13:26 +02003903static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02003904smp_fetch_ssl_fc_alg_keysize(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun589fcad2012-10-16 14:13:26 +02003905{
Emeric Brun645ae792014-04-30 14:21:06 +02003906 int back_conn = (kw[4] == 'b') ? 1 : 0;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003907 struct connection *conn;
3908
Emeric Brun589fcad2012-10-16 14:13:26 +02003909 smp->flags = 0;
3910
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02003911 conn = objt_conn(smp->strm->si[back_conn].end);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003912 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
Emeric Brun589fcad2012-10-16 14:13:26 +02003913 return 0;
3914
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003915 if (!SSL_get_cipher_bits(conn->xprt_ctx, (int *)&smp->data.uint))
3916 return 0;
3917
Emeric Brun589fcad2012-10-16 14:13:26 +02003918 smp->type = SMP_T_UINT;
3919
3920 return 1;
3921}
3922
Emeric Brun645ae792014-04-30 14:21:06 +02003923/* integer, returns the used keysize if front conn. transport layer is SSL.
3924 * This function is also usable on backend conn if the fetch keyword 5th
3925 * char is 'b'.
3926 */
Emeric Brun589fcad2012-10-16 14:13:26 +02003927static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02003928smp_fetch_ssl_fc_use_keysize(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun589fcad2012-10-16 14:13:26 +02003929{
Emeric Brun645ae792014-04-30 14:21:06 +02003930 int back_conn = (kw[4] == 'b') ? 1 : 0;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003931 struct connection *conn;
3932
Emeric Brun589fcad2012-10-16 14:13:26 +02003933 smp->flags = 0;
3934
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02003935 conn = objt_conn(smp->strm->si[back_conn].end);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003936 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
3937 return 0;
3938
3939 smp->data.uint = (unsigned int)SSL_get_cipher_bits(conn->xprt_ctx, NULL);
Emeric Brun589fcad2012-10-16 14:13:26 +02003940 if (!smp->data.uint)
3941 return 0;
3942
3943 smp->type = SMP_T_UINT;
3944
3945 return 1;
3946}
3947
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02003948#ifdef OPENSSL_NPN_NEGOTIATED
Willy Tarreau7875d092012-09-10 08:20:03 +02003949static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02003950smp_fetch_ssl_fc_npn(const struct arg *args, struct sample *smp, const char *kw, void *private)
Willy Tarreaua33c6542012-10-15 13:19:06 +02003951{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003952 struct connection *conn;
3953
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01003954 smp->flags = SMP_F_CONST;
3955 smp->type = SMP_T_STR;
Willy Tarreaua33c6542012-10-15 13:19:06 +02003956
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02003957 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003958 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
3959 return 0;
3960
Willy Tarreaua33c6542012-10-15 13:19:06 +02003961 smp->data.str.str = NULL;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003962 SSL_get0_next_proto_negotiated(conn->xprt_ctx,
Willy Tarreaua33c6542012-10-15 13:19:06 +02003963 (const unsigned char **)&smp->data.str.str, (unsigned *)&smp->data.str.len);
3964
3965 if (!smp->data.str.str)
3966 return 0;
3967
3968 return 1;
Willy Tarreaua33c6542012-10-15 13:19:06 +02003969}
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02003970#endif
Willy Tarreaua33c6542012-10-15 13:19:06 +02003971
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01003972#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Willy Tarreauab861d32013-04-02 02:30:41 +02003973static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02003974smp_fetch_ssl_fc_alpn(const struct arg *args, struct sample *smp, const char *kw, void *private)
Willy Tarreauab861d32013-04-02 02:30:41 +02003975{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003976 struct connection *conn;
3977
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01003978 smp->flags = SMP_F_CONST;
3979 smp->type = SMP_T_STR;
Willy Tarreauab861d32013-04-02 02:30:41 +02003980
Willy Tarreaue26bf052015-05-12 10:30:12 +02003981 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003982 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
Willy Tarreauab861d32013-04-02 02:30:41 +02003983 return 0;
3984
3985 smp->data.str.str = NULL;
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01003986 SSL_get0_alpn_selected(conn->xprt_ctx,
Willy Tarreauab861d32013-04-02 02:30:41 +02003987 (const unsigned char **)&smp->data.str.str, (unsigned *)&smp->data.str.len);
3988
3989 if (!smp->data.str.str)
3990 return 0;
3991
3992 return 1;
3993}
3994#endif
3995
Emeric Brun645ae792014-04-30 14:21:06 +02003996/* string, returns the used protocol if front conn. transport layer is SSL.
3997 * This function is also usable on backend conn if the fetch keyword 5th
3998 * char is 'b'.
3999 */
Willy Tarreaua33c6542012-10-15 13:19:06 +02004000static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004001smp_fetch_ssl_fc_protocol(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun589fcad2012-10-16 14:13:26 +02004002{
Emeric Brun645ae792014-04-30 14:21:06 +02004003 int back_conn = (kw[4] == 'b') ? 1 : 0;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004004 struct connection *conn;
4005
Emeric Brun589fcad2012-10-16 14:13:26 +02004006 smp->flags = 0;
4007
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004008 conn = objt_conn(smp->strm->si[back_conn].end);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004009 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
4010 return 0;
4011
4012 smp->data.str.str = (char *)SSL_get_version(conn->xprt_ctx);
Emeric Brun589fcad2012-10-16 14:13:26 +02004013 if (!smp->data.str.str)
4014 return 0;
4015
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01004016 smp->type = SMP_T_STR;
4017 smp->flags = SMP_F_CONST;
Emeric Brun589fcad2012-10-16 14:13:26 +02004018 smp->data.str.len = strlen(smp->data.str.str);
4019
4020 return 1;
4021}
4022
Willy Tarreau87b09662015-04-03 00:22:06 +02004023/* binary, returns the SSL stream id if front conn. transport layer is SSL.
Emeric Brun645ae792014-04-30 14:21:06 +02004024 * This function is also usable on backend conn if the fetch keyword 5th
4025 * char is 'b'.
4026 */
Emeric Brun589fcad2012-10-16 14:13:26 +02004027static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004028smp_fetch_ssl_fc_session_id(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brunfe68f682012-10-16 14:59:28 +02004029{
4030#if OPENSSL_VERSION_NUMBER > 0x0090800fL
Emeric Brun645ae792014-04-30 14:21:06 +02004031 int back_conn = (kw[4] == 'b') ? 1 : 0;
Willy Tarreau192252e2015-04-04 01:47:55 +02004032 SSL_SESSION *ssl_sess;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004033 struct connection *conn;
Emeric Brunfe68f682012-10-16 14:59:28 +02004034
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01004035 smp->flags = SMP_F_CONST;
4036 smp->type = SMP_T_BIN;
Emeric Brunfe68f682012-10-16 14:59:28 +02004037
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004038 conn = objt_conn(smp->strm->si[back_conn].end);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004039 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
4040 return 0;
4041
Willy Tarreau192252e2015-04-04 01:47:55 +02004042 ssl_sess = SSL_get_session(conn->xprt_ctx);
4043 if (!ssl_sess)
Emeric Brunfe68f682012-10-16 14:59:28 +02004044 return 0;
4045
Willy Tarreau192252e2015-04-04 01:47:55 +02004046 smp->data.str.str = (char *)SSL_SESSION_get_id(ssl_sess, (unsigned int *)&smp->data.str.len);
Emeric Brunfe68f682012-10-16 14:59:28 +02004047 if (!smp->data.str.str || !&smp->data.str.len)
4048 return 0;
4049
4050 return 1;
4051#else
4052 return 0;
4053#endif
4054}
4055
4056static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004057smp_fetch_ssl_fc_sni(const struct arg *args, struct sample *smp, const char *kw, void *private)
Willy Tarreau7875d092012-09-10 08:20:03 +02004058{
4059#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004060 struct connection *conn;
4061
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01004062 smp->flags = SMP_F_CONST;
4063 smp->type = SMP_T_STR;
Willy Tarreau7875d092012-09-10 08:20:03 +02004064
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004065 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004066 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
4067 return 0;
4068
4069 smp->data.str.str = (char *)SSL_get_servername(conn->xprt_ctx, TLSEXT_NAMETYPE_host_name);
Willy Tarreau3e394c92012-09-14 23:56:58 +02004070 if (!smp->data.str.str)
4071 return 0;
4072
Willy Tarreau7875d092012-09-10 08:20:03 +02004073 smp->data.str.len = strlen(smp->data.str.str);
4074 return 1;
4075#else
4076 return 0;
4077#endif
4078}
4079
David Sc1ad52e2014-04-08 18:48:47 -04004080static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004081smp_fetch_ssl_fc_unique_id(const struct arg *args, struct sample *smp, const char *kw, void *private)
David Sc1ad52e2014-04-08 18:48:47 -04004082{
4083#if OPENSSL_VERSION_NUMBER > 0x0090800fL
Emeric Brun645ae792014-04-30 14:21:06 +02004084 int back_conn = (kw[4] == 'b') ? 1 : 0;
David Sc1ad52e2014-04-08 18:48:47 -04004085 struct connection *conn;
4086 int finished_len;
David Sc1ad52e2014-04-08 18:48:47 -04004087 struct chunk *finished_trash;
David Sc1ad52e2014-04-08 18:48:47 -04004088
4089 smp->flags = 0;
4090
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004091 conn = objt_conn(smp->strm->si[back_conn].end);
David Sc1ad52e2014-04-08 18:48:47 -04004092 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
4093 return 0;
4094
4095 if (!(conn->flags & CO_FL_CONNECTED)) {
4096 smp->flags |= SMP_F_MAY_CHANGE;
4097 return 0;
4098 }
4099
4100 finished_trash = get_trash_chunk();
4101 if (!SSL_session_reused(conn->xprt_ctx))
4102 finished_len = SSL_get_peer_finished(conn->xprt_ctx, finished_trash->str, finished_trash->size);
4103 else
4104 finished_len = SSL_get_finished(conn->xprt_ctx, finished_trash->str, finished_trash->size);
4105
4106 if (!finished_len)
4107 return 0;
4108
Emeric Brunb73a9b02014-04-30 18:49:19 +02004109 finished_trash->len = finished_len;
4110 smp->data.str = *finished_trash;
4111 smp->type = SMP_T_BIN;
David Sc1ad52e2014-04-08 18:48:47 -04004112
4113 return 1;
4114#else
4115 return 0;
4116#endif
4117}
4118
Emeric Brun2525b6b2012-10-18 15:59:43 +02004119/* integer, returns the first verify error in CA chain of client certificate chain. */
Emeric Brunf282a812012-09-21 15:27:54 +02004120static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004121smp_fetch_ssl_c_ca_err(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brunf282a812012-09-21 15:27:54 +02004122{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004123 struct connection *conn;
4124
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004125 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004126 if (!conn || conn->xprt != &ssl_sock)
4127 return 0;
4128
4129 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunf282a812012-09-21 15:27:54 +02004130 smp->flags = SMP_F_MAY_CHANGE;
4131 return 0;
4132 }
4133
4134 smp->type = SMP_T_UINT;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004135 smp->data.uint = (unsigned int)SSL_SOCK_ST_TO_CA_ERROR(conn->xprt_st);
Emeric Brunf282a812012-09-21 15:27:54 +02004136 smp->flags = 0;
4137
4138 return 1;
4139}
4140
Emeric Brun2525b6b2012-10-18 15:59:43 +02004141/* integer, returns the depth of the first verify error in CA chain of client certificate chain. */
Emeric Brunf282a812012-09-21 15:27:54 +02004142static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004143smp_fetch_ssl_c_ca_err_depth(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brunf282a812012-09-21 15:27:54 +02004144{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004145 struct connection *conn;
4146
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004147 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004148 if (!conn || conn->xprt != &ssl_sock)
Emeric Brunf282a812012-09-21 15:27:54 +02004149 return 0;
4150
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004151 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunf282a812012-09-21 15:27:54 +02004152 smp->flags = SMP_F_MAY_CHANGE;
4153 return 0;
4154 }
4155
4156 smp->type = SMP_T_UINT;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004157 smp->data.uint = (unsigned int)SSL_SOCK_ST_TO_CAEDEPTH(conn->xprt_st);
Emeric Brunf282a812012-09-21 15:27:54 +02004158 smp->flags = 0;
4159
4160 return 1;
4161}
4162
Emeric Brun2525b6b2012-10-18 15:59:43 +02004163/* integer, returns the first verify error on client certificate */
Emeric Brunf282a812012-09-21 15:27:54 +02004164static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004165smp_fetch_ssl_c_err(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brunf282a812012-09-21 15:27:54 +02004166{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004167 struct connection *conn;
4168
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004169 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004170 if (!conn || conn->xprt != &ssl_sock)
4171 return 0;
4172
4173 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunf282a812012-09-21 15:27:54 +02004174 smp->flags = SMP_F_MAY_CHANGE;
4175 return 0;
4176 }
4177
4178 smp->type = SMP_T_UINT;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004179 smp->data.uint = (unsigned int)SSL_SOCK_ST_TO_CRTERROR(conn->xprt_st);
Emeric Brunf282a812012-09-21 15:27:54 +02004180 smp->flags = 0;
4181
4182 return 1;
4183}
4184
Emeric Brun2525b6b2012-10-18 15:59:43 +02004185/* integer, returns the verify result on client cert */
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02004186static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004187smp_fetch_ssl_c_verify(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02004188{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004189 struct connection *conn;
4190
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004191 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004192 if (!conn || conn->xprt != &ssl_sock)
4193 return 0;
4194
4195 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02004196 smp->flags = SMP_F_MAY_CHANGE;
4197 return 0;
4198 }
4199
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004200 if (!conn->xprt_ctx)
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02004201 return 0;
4202
4203 smp->type = SMP_T_UINT;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004204 smp->data.uint = (unsigned int)SSL_get_verify_result(conn->xprt_ctx);
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02004205 smp->flags = 0;
4206
4207 return 1;
4208}
4209
Emeric Brunfb510ea2012-10-05 12:00:26 +02004210/* parse the "ca-file" bind keyword */
4211static 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 +02004212{
4213 if (!*args[cur_arg + 1]) {
4214 if (err)
4215 memprintf(err, "'%s' : missing CAfile path", args[cur_arg]);
4216 return ERR_ALERT | ERR_FATAL;
4217 }
4218
Emeric Brunef42d922012-10-11 16:11:36 +02004219 if ((*args[cur_arg + 1] != '/') && global.ca_base)
4220 memprintf(&conf->ca_file, "%s/%s", global.ca_base, args[cur_arg + 1]);
4221 else
4222 memprintf(&conf->ca_file, "%s", args[cur_arg + 1]);
Emeric Brunc8e8d122012-10-02 18:42:10 +02004223
Emeric Brund94b3fe2012-09-20 18:23:56 +02004224 return 0;
4225}
4226
Christopher Faulet31af49d2015-06-09 17:29:50 +02004227/* parse the "ca-sign-file" bind keyword */
4228static int bind_parse_ca_sign_file(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
4229{
4230 if (!*args[cur_arg + 1]) {
4231 if (err)
4232 memprintf(err, "'%s' : missing CAfile path", args[cur_arg]);
4233 return ERR_ALERT | ERR_FATAL;
4234 }
4235
4236 if ((*args[cur_arg + 1] != '/') && global.ca_base)
4237 memprintf(&conf->ca_sign_file, "%s/%s", global.ca_base, args[cur_arg + 1]);
4238 else
4239 memprintf(&conf->ca_sign_file, "%s", args[cur_arg + 1]);
4240
4241 return 0;
4242}
4243
4244/* parse the ca-sign-pass bind keyword */
4245
4246static int bind_parse_ca_sign_pass(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
4247{
4248 if (!*args[cur_arg + 1]) {
4249 if (err)
4250 memprintf(err, "'%s' : missing CAkey password", args[cur_arg]);
4251 return ERR_ALERT | ERR_FATAL;
4252 }
4253 memprintf(&conf->ca_sign_pass, "%s", args[cur_arg + 1]);
4254 return 0;
4255}
4256
Willy Tarreau79eeafa2012-09-14 07:53:05 +02004257/* parse the "ciphers" bind keyword */
Willy Tarreau4348fad2012-09-20 16:48:07 +02004258static 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 +02004259{
4260 if (!*args[cur_arg + 1]) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02004261 memprintf(err, "'%s' : missing cipher suite", args[cur_arg]);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02004262 return ERR_ALERT | ERR_FATAL;
4263 }
4264
Emeric Brun76d88952012-10-05 15:47:31 +02004265 free(conf->ciphers);
Willy Tarreau4348fad2012-09-20 16:48:07 +02004266 conf->ciphers = strdup(args[cur_arg + 1]);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02004267 return 0;
4268}
4269
4270/* parse the "crt" bind keyword */
Willy Tarreau4348fad2012-09-20 16:48:07 +02004271static 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 +02004272{
Willy Tarreau38011032013-08-13 16:59:39 +02004273 char path[MAXPATHLEN];
Willy Tarreaub75d6922014-04-14 18:05:41 +02004274
Willy Tarreau79eeafa2012-09-14 07:53:05 +02004275 if (!*args[cur_arg + 1]) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02004276 memprintf(err, "'%s' : missing certificate location", args[cur_arg]);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02004277 return ERR_ALERT | ERR_FATAL;
4278 }
4279
Emeric Brunc8e8d122012-10-02 18:42:10 +02004280 if ((*args[cur_arg + 1] != '/' ) && global.crt_base) {
Willy Tarreau38011032013-08-13 16:59:39 +02004281 if ((strlen(global.crt_base) + 1 + strlen(args[cur_arg + 1]) + 1) > MAXPATHLEN) {
Emeric Brunc8e8d122012-10-02 18:42:10 +02004282 memprintf(err, "'%s' : path too long", args[cur_arg]);
4283 return ERR_ALERT | ERR_FATAL;
4284 }
Willy Tarreaub75d6922014-04-14 18:05:41 +02004285 snprintf(path, sizeof(path), "%s/%s", global.crt_base, args[cur_arg + 1]);
Emeric Brunc8e8d122012-10-02 18:42:10 +02004286 if (ssl_sock_load_cert(path, conf, px, err) > 0)
4287 return ERR_ALERT | ERR_FATAL;
4288
4289 return 0;
4290 }
4291
Willy Tarreau4348fad2012-09-20 16:48:07 +02004292 if (ssl_sock_load_cert(args[cur_arg + 1], conf, px, err) > 0)
Willy Tarreau79eeafa2012-09-14 07:53:05 +02004293 return ERR_ALERT | ERR_FATAL;
Emeric Brund94b3fe2012-09-20 18:23:56 +02004294
4295 return 0;
4296}
4297
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01004298/* parse the "crt-list" bind keyword */
4299static int bind_parse_crt_list(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
4300{
4301 if (!*args[cur_arg + 1]) {
4302 memprintf(err, "'%s' : missing certificate location", args[cur_arg]);
4303 return ERR_ALERT | ERR_FATAL;
4304 }
4305
Willy Tarreauad1731d2013-04-02 17:35:58 +02004306 if (ssl_sock_load_cert_list_file(args[cur_arg + 1], conf, px, err) > 0) {
4307 memprintf(err, "'%s' : %s", args[cur_arg], *err);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01004308 return ERR_ALERT | ERR_FATAL;
Willy Tarreauad1731d2013-04-02 17:35:58 +02004309 }
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01004310
4311 return 0;
4312}
4313
Emeric Brunfb510ea2012-10-05 12:00:26 +02004314/* parse the "crl-file" bind keyword */
4315static 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 +02004316{
Emeric Brun051cdab2012-10-02 19:25:50 +02004317#ifndef X509_V_FLAG_CRL_CHECK
4318 if (err)
4319 memprintf(err, "'%s' : library does not support CRL verify", args[cur_arg]);
4320 return ERR_ALERT | ERR_FATAL;
4321#else
Emeric Brund94b3fe2012-09-20 18:23:56 +02004322 if (!*args[cur_arg + 1]) {
4323 if (err)
4324 memprintf(err, "'%s' : missing CRLfile path", args[cur_arg]);
4325 return ERR_ALERT | ERR_FATAL;
4326 }
Emeric Brun2b58d042012-09-20 17:10:03 +02004327
Emeric Brunef42d922012-10-11 16:11:36 +02004328 if ((*args[cur_arg + 1] != '/') && global.ca_base)
4329 memprintf(&conf->crl_file, "%s/%s", global.ca_base, args[cur_arg + 1]);
4330 else
4331 memprintf(&conf->crl_file, "%s", args[cur_arg + 1]);
Emeric Brunc8e8d122012-10-02 18:42:10 +02004332
Emeric Brun2b58d042012-09-20 17:10:03 +02004333 return 0;
Emeric Brun051cdab2012-10-02 19:25:50 +02004334#endif
Emeric Brun2b58d042012-09-20 17:10:03 +02004335}
4336
4337/* parse the "ecdhe" bind keyword keywords */
4338static int bind_parse_ecdhe(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
4339{
4340#if OPENSSL_VERSION_NUMBER < 0x0090800fL
4341 if (err)
4342 memprintf(err, "'%s' : library does not support elliptic curve Diffie-Hellman (too old)", args[cur_arg]);
4343 return ERR_ALERT | ERR_FATAL;
4344#elif defined(OPENSSL_NO_ECDH)
4345 if (err)
4346 memprintf(err, "'%s' : library does not support elliptic curve Diffie-Hellman (disabled via OPENSSL_NO_ECDH)", args[cur_arg]);
4347 return ERR_ALERT | ERR_FATAL;
4348#else
4349 if (!*args[cur_arg + 1]) {
4350 if (err)
4351 memprintf(err, "'%s' : missing named curve", args[cur_arg]);
4352 return ERR_ALERT | ERR_FATAL;
4353 }
4354
4355 conf->ecdhe = strdup(args[cur_arg + 1]);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02004356
4357 return 0;
Emeric Brun2b58d042012-09-20 17:10:03 +02004358#endif
Willy Tarreau79eeafa2012-09-14 07:53:05 +02004359}
4360
Emeric Brun81c00f02012-09-21 14:31:21 +02004361/* parse the "crt_ignerr" and "ca_ignerr" bind keywords */
4362static int bind_parse_ignore_err(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
4363{
4364 int code;
4365 char *p = args[cur_arg + 1];
4366 unsigned long long *ignerr = &conf->crt_ignerr;
4367
4368 if (!*p) {
4369 if (err)
4370 memprintf(err, "'%s' : missing error IDs list", args[cur_arg]);
4371 return ERR_ALERT | ERR_FATAL;
4372 }
4373
4374 if (strcmp(args[cur_arg], "ca-ignore-err") == 0)
4375 ignerr = &conf->ca_ignerr;
4376
4377 if (strcmp(p, "all") == 0) {
4378 *ignerr = ~0ULL;
4379 return 0;
4380 }
4381
4382 while (p) {
4383 code = atoi(p);
4384 if ((code <= 0) || (code > 63)) {
4385 if (err)
4386 memprintf(err, "'%s' : ID '%d' out of range (1..63) in error IDs list '%s'",
4387 args[cur_arg], code, args[cur_arg + 1]);
4388 return ERR_ALERT | ERR_FATAL;
4389 }
4390 *ignerr |= 1ULL << code;
4391 p = strchr(p, ',');
4392 if (p)
4393 p++;
4394 }
4395
Emeric Brun2cb7ae52012-10-05 14:14:21 +02004396 return 0;
4397}
4398
4399/* parse the "force-sslv3" bind keyword */
4400static int bind_parse_force_sslv3(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
4401{
4402 conf->ssl_options |= BC_SSL_O_USE_SSLV3;
4403 return 0;
4404}
4405
4406/* parse the "force-tlsv10" bind keyword */
4407static int bind_parse_force_tlsv10(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
4408{
4409 conf->ssl_options |= BC_SSL_O_USE_TLSV10;
Emeric Brun2d0c4822012-10-02 13:45:20 +02004410 return 0;
4411}
4412
Emeric Brun2cb7ae52012-10-05 14:14:21 +02004413/* parse the "force-tlsv11" bind keyword */
4414static int bind_parse_force_tlsv11(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
4415{
4416#if SSL_OP_NO_TLSv1_1
4417 conf->ssl_options |= BC_SSL_O_USE_TLSV11;
4418 return 0;
4419#else
4420 if (err)
4421 memprintf(err, "'%s' : library does not support protocol TLSv1.1", args[cur_arg]);
4422 return ERR_ALERT | ERR_FATAL;
4423#endif
4424}
4425
4426/* parse the "force-tlsv12" bind keyword */
4427static int bind_parse_force_tlsv12(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
4428{
4429#if SSL_OP_NO_TLSv1_2
4430 conf->ssl_options |= BC_SSL_O_USE_TLSV12;
4431 return 0;
4432#else
4433 if (err)
4434 memprintf(err, "'%s' : library does not support protocol TLSv1.2", args[cur_arg]);
4435 return ERR_ALERT | ERR_FATAL;
4436#endif
4437}
4438
4439
Emeric Brun2d0c4822012-10-02 13:45:20 +02004440/* parse the "no-tls-tickets" bind keyword */
4441static int bind_parse_no_tls_tickets(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
4442{
Emeric Brun89675492012-10-05 13:48:26 +02004443 conf->ssl_options |= BC_SSL_O_NO_TLS_TICKETS;
Emeric Brun81c00f02012-09-21 14:31:21 +02004444 return 0;
4445}
4446
Emeric Brun2d0c4822012-10-02 13:45:20 +02004447
Emeric Brun9b3009b2012-10-05 11:55:06 +02004448/* parse the "no-sslv3" bind keyword */
4449static 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 +02004450{
Emeric Brun89675492012-10-05 13:48:26 +02004451 conf->ssl_options |= BC_SSL_O_NO_SSLV3;
Willy Tarreau79eeafa2012-09-14 07:53:05 +02004452 return 0;
4453}
4454
Emeric Brun9b3009b2012-10-05 11:55:06 +02004455/* parse the "no-tlsv10" bind keyword */
4456static 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 +02004457{
Emeric Brun89675492012-10-05 13:48:26 +02004458 conf->ssl_options |= BC_SSL_O_NO_TLSV10;
Emeric Brunc0ff4922012-09-28 19:37:02 +02004459 return 0;
4460}
4461
Emeric Brun9b3009b2012-10-05 11:55:06 +02004462/* parse the "no-tlsv11" bind keyword */
4463static 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 +02004464{
Emeric Brun89675492012-10-05 13:48:26 +02004465 conf->ssl_options |= BC_SSL_O_NO_TLSV11;
Emeric Brunc0ff4922012-09-28 19:37:02 +02004466 return 0;
4467}
4468
Emeric Brun9b3009b2012-10-05 11:55:06 +02004469/* parse the "no-tlsv12" bind keyword */
4470static 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 +02004471{
Emeric Brun89675492012-10-05 13:48:26 +02004472 conf->ssl_options |= BC_SSL_O_NO_TLSV12;
Willy Tarreau79eeafa2012-09-14 07:53:05 +02004473 return 0;
4474}
4475
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02004476/* parse the "npn" bind keyword */
4477static int bind_parse_npn(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
4478{
4479#ifdef OPENSSL_NPN_NEGOTIATED
4480 char *p1, *p2;
4481
4482 if (!*args[cur_arg + 1]) {
4483 memprintf(err, "'%s' : missing the comma-delimited NPN protocol suite", args[cur_arg]);
4484 return ERR_ALERT | ERR_FATAL;
4485 }
4486
4487 free(conf->npn_str);
4488
4489 /* the NPN string is built as a suite of (<len> <name>)* */
4490 conf->npn_len = strlen(args[cur_arg + 1]) + 1;
4491 conf->npn_str = calloc(1, conf->npn_len);
4492 memcpy(conf->npn_str + 1, args[cur_arg + 1], conf->npn_len);
4493
4494 /* replace commas with the name length */
4495 p1 = conf->npn_str;
4496 p2 = p1 + 1;
4497 while (1) {
4498 p2 = memchr(p1 + 1, ',', conf->npn_str + conf->npn_len - (p1 + 1));
4499 if (!p2)
4500 p2 = p1 + 1 + strlen(p1 + 1);
4501
4502 if (p2 - (p1 + 1) > 255) {
4503 *p2 = '\0';
4504 memprintf(err, "'%s' : NPN protocol name too long : '%s'", args[cur_arg], p1 + 1);
4505 return ERR_ALERT | ERR_FATAL;
4506 }
4507
4508 *p1 = p2 - (p1 + 1);
4509 p1 = p2;
4510
4511 if (!*p2)
4512 break;
4513
4514 *(p2++) = '\0';
4515 }
4516 return 0;
4517#else
4518 if (err)
4519 memprintf(err, "'%s' : library does not support TLS NPN extension", args[cur_arg]);
4520 return ERR_ALERT | ERR_FATAL;
4521#endif
4522}
4523
Willy Tarreauab861d32013-04-02 02:30:41 +02004524/* parse the "alpn" bind keyword */
4525static int bind_parse_alpn(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
4526{
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01004527#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Willy Tarreauab861d32013-04-02 02:30:41 +02004528 char *p1, *p2;
4529
4530 if (!*args[cur_arg + 1]) {
4531 memprintf(err, "'%s' : missing the comma-delimited ALPN protocol suite", args[cur_arg]);
4532 return ERR_ALERT | ERR_FATAL;
4533 }
4534
4535 free(conf->alpn_str);
4536
4537 /* the ALPN string is built as a suite of (<len> <name>)* */
4538 conf->alpn_len = strlen(args[cur_arg + 1]) + 1;
4539 conf->alpn_str = calloc(1, conf->alpn_len);
4540 memcpy(conf->alpn_str + 1, args[cur_arg + 1], conf->alpn_len);
4541
4542 /* replace commas with the name length */
4543 p1 = conf->alpn_str;
4544 p2 = p1 + 1;
4545 while (1) {
4546 p2 = memchr(p1 + 1, ',', conf->alpn_str + conf->alpn_len - (p1 + 1));
4547 if (!p2)
4548 p2 = p1 + 1 + strlen(p1 + 1);
4549
4550 if (p2 - (p1 + 1) > 255) {
4551 *p2 = '\0';
4552 memprintf(err, "'%s' : ALPN protocol name too long : '%s'", args[cur_arg], p1 + 1);
4553 return ERR_ALERT | ERR_FATAL;
4554 }
4555
4556 *p1 = p2 - (p1 + 1);
4557 p1 = p2;
4558
4559 if (!*p2)
4560 break;
4561
4562 *(p2++) = '\0';
4563 }
4564 return 0;
4565#else
4566 if (err)
4567 memprintf(err, "'%s' : library does not support TLS ALPN extension", args[cur_arg]);
4568 return ERR_ALERT | ERR_FATAL;
4569#endif
4570}
4571
Willy Tarreau79eeafa2012-09-14 07:53:05 +02004572/* parse the "ssl" bind keyword */
Willy Tarreau4348fad2012-09-20 16:48:07 +02004573static 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 +02004574{
Willy Tarreau81796be2012-09-22 19:11:47 +02004575 struct listener *l;
4576
Willy Tarreau4348fad2012-09-20 16:48:07 +02004577 conf->is_ssl = 1;
Emeric Brun76d88952012-10-05 15:47:31 +02004578
4579 if (global.listen_default_ciphers && !conf->ciphers)
4580 conf->ciphers = strdup(global.listen_default_ciphers);
Emeric Brun2c86cbf2014-10-30 15:56:50 +01004581 conf->ssl_options |= global.listen_default_ssloptions;
Emeric Brun76d88952012-10-05 15:47:31 +02004582
Willy Tarreau81796be2012-09-22 19:11:47 +02004583 list_for_each_entry(l, &conf->listeners, by_bind)
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02004584 l->xprt = &ssl_sock;
Willy Tarreau81796be2012-09-22 19:11:47 +02004585
Willy Tarreau79eeafa2012-09-14 07:53:05 +02004586 return 0;
4587}
4588
Christopher Faulet31af49d2015-06-09 17:29:50 +02004589/* parse the "generate-certificates" bind keyword */
4590static int bind_parse_generate_certs(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
4591{
4592#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
4593 conf->generate_certs = 1;
4594#else
4595 memprintf(err, "%sthis version of openssl cannot generate SSL certificates.\n",
4596 err && *err ? *err : "");
4597#endif
4598 return 0;
4599}
4600
Emmanuel Hocdet65623372013-01-24 17:17:15 +01004601/* parse the "strict-sni" bind keyword */
4602static int bind_parse_strict_sni(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
4603{
4604 conf->strict_sni = 1;
4605 return 0;
Nenad Merdanovic05552d42015-02-27 19:56:49 +01004606}
4607
4608/* parse the "tls-ticket-keys" bind keyword */
4609static int bind_parse_tls_ticket_keys(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
4610{
4611#if (defined SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB && TLS_TICKETS_NO > 0)
4612 FILE *f;
4613 int i = 0;
4614 char thisline[LINESIZE];
Nenad Merdanovic146defa2015-05-09 08:46:00 +02004615 struct tls_keys_ref *keys_ref;
Nenad Merdanovic05552d42015-02-27 19:56:49 +01004616
4617 if (!*args[cur_arg + 1]) {
4618 if (err)
4619 memprintf(err, "'%s' : missing TLS ticket keys file path", args[cur_arg]);
4620 return ERR_ALERT | ERR_FATAL;
4621 }
4622
Nenad Merdanovic200b0fa2015-05-09 08:46:01 +02004623 keys_ref = tlskeys_ref_lookup(args[cur_arg + 1]);
4624 if(keys_ref) {
4625 conf->keys_ref = keys_ref;
4626 return 0;
4627 }
4628
Nenad Merdanovic146defa2015-05-09 08:46:00 +02004629 keys_ref = malloc(sizeof(struct tls_keys_ref));
4630 keys_ref->tlskeys = malloc(TLS_TICKETS_NO * sizeof(struct tls_sess_key));
Nenad Merdanovic05552d42015-02-27 19:56:49 +01004631
4632 if ((f = fopen(args[cur_arg + 1], "r")) == NULL) {
4633 if (err)
4634 memprintf(err, "'%s' : unable to load ssl tickets keys file", args[cur_arg+1]);
4635 return ERR_ALERT | ERR_FATAL;
4636 }
4637
Nenad Merdanovic146defa2015-05-09 08:46:00 +02004638 keys_ref->filename = strdup(args[cur_arg + 1]);
4639
Nenad Merdanovic05552d42015-02-27 19:56:49 +01004640 while (fgets(thisline, sizeof(thisline), f) != NULL) {
4641 int len = strlen(thisline);
4642 /* Strip newline characters from the end */
4643 if(thisline[len - 1] == '\n')
4644 thisline[--len] = 0;
4645
4646 if(thisline[len - 1] == '\r')
4647 thisline[--len] = 0;
4648
Nenad Merdanovic146defa2015-05-09 08:46:00 +02004649 if (base64dec(thisline, len, (char *) (keys_ref->tlskeys + i % TLS_TICKETS_NO), sizeof(struct tls_sess_key)) != sizeof(struct tls_sess_key)) {
Nenad Merdanovic05552d42015-02-27 19:56:49 +01004650 if (err)
4651 memprintf(err, "'%s' : unable to decode base64 key on line %d", args[cur_arg+1], i + 1);
4652 return ERR_ALERT | ERR_FATAL;
4653 }
4654 i++;
4655 }
4656
4657 if (i < TLS_TICKETS_NO) {
4658 if (err)
4659 memprintf(err, "'%s' : please supply at least %d keys in the tls-tickets-file", args[cur_arg+1], TLS_TICKETS_NO);
4660 return ERR_ALERT | ERR_FATAL;
4661 }
4662
4663 fclose(f);
4664
4665 /* Use penultimate key for encryption, handle when TLS_TICKETS_NO = 1 */
4666 i-=2;
Nenad Merdanovic146defa2015-05-09 08:46:00 +02004667 keys_ref->tls_ticket_enc_index = i < 0 ? 0 : i;
Nenad Merdanovic200b0fa2015-05-09 08:46:01 +02004668 keys_ref->unique_id = -1;
Nenad Merdanovic146defa2015-05-09 08:46:00 +02004669 conf->keys_ref = keys_ref;
Nenad Merdanovic05552d42015-02-27 19:56:49 +01004670
Nenad Merdanovic200b0fa2015-05-09 08:46:01 +02004671 LIST_ADD(&tlskeys_reference, &keys_ref->list);
4672
Nenad Merdanovic05552d42015-02-27 19:56:49 +01004673 return 0;
4674#else
4675 if (err)
4676 memprintf(err, "'%s' : TLS ticket callback extension not supported", args[cur_arg]);
4677 return ERR_ALERT | ERR_FATAL;
4678#endif /* SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB */
Emmanuel Hocdet65623372013-01-24 17:17:15 +01004679}
4680
Emeric Brund94b3fe2012-09-20 18:23:56 +02004681/* parse the "verify" bind keyword */
4682static int bind_parse_verify(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
4683{
4684 if (!*args[cur_arg + 1]) {
4685 if (err)
4686 memprintf(err, "'%s' : missing verify method", args[cur_arg]);
4687 return ERR_ALERT | ERR_FATAL;
4688 }
4689
4690 if (strcmp(args[cur_arg + 1], "none") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01004691 conf->verify = SSL_SOCK_VERIFY_NONE;
Emeric Brund94b3fe2012-09-20 18:23:56 +02004692 else if (strcmp(args[cur_arg + 1], "optional") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01004693 conf->verify = SSL_SOCK_VERIFY_OPTIONAL;
Emeric Brund94b3fe2012-09-20 18:23:56 +02004694 else if (strcmp(args[cur_arg + 1], "required") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01004695 conf->verify = SSL_SOCK_VERIFY_REQUIRED;
Emeric Brund94b3fe2012-09-20 18:23:56 +02004696 else {
4697 if (err)
4698 memprintf(err, "'%s' : unknown verify method '%s', only 'none', 'optional', and 'required' are supported\n",
4699 args[cur_arg], args[cur_arg + 1]);
4700 return ERR_ALERT | ERR_FATAL;
4701 }
4702
4703 return 0;
4704}
4705
Willy Tarreau92faadf2012-10-10 23:04:25 +02004706/************** "server" keywords ****************/
4707
Emeric Brunef42d922012-10-11 16:11:36 +02004708/* parse the "ca-file" server keyword */
4709static int srv_parse_ca_file(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4710{
4711 if (!*args[*cur_arg + 1]) {
4712 if (err)
4713 memprintf(err, "'%s' : missing CAfile path", args[*cur_arg]);
4714 return ERR_ALERT | ERR_FATAL;
4715 }
4716
4717 if ((*args[*cur_arg + 1] != '/') && global.ca_base)
4718 memprintf(&newsrv->ssl_ctx.ca_file, "%s/%s", global.ca_base, args[*cur_arg + 1]);
4719 else
4720 memprintf(&newsrv->ssl_ctx.ca_file, "%s", args[*cur_arg + 1]);
4721
4722 return 0;
4723}
4724
Willy Tarreau92faadf2012-10-10 23:04:25 +02004725/* parse the "check-ssl" server keyword */
4726static int srv_parse_check_ssl(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4727{
4728 newsrv->check.use_ssl = 1;
4729 if (global.connect_default_ciphers && !newsrv->ssl_ctx.ciphers)
4730 newsrv->ssl_ctx.ciphers = strdup(global.connect_default_ciphers);
Emeric Brun2c86cbf2014-10-30 15:56:50 +01004731 newsrv->ssl_ctx.options |= global.connect_default_ssloptions;
Willy Tarreau92faadf2012-10-10 23:04:25 +02004732 return 0;
4733}
4734
4735/* parse the "ciphers" server keyword */
4736static int srv_parse_ciphers(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4737{
4738 if (!*args[*cur_arg + 1]) {
4739 memprintf(err, "'%s' : missing cipher suite", args[*cur_arg]);
4740 return ERR_ALERT | ERR_FATAL;
4741 }
4742
4743 free(newsrv->ssl_ctx.ciphers);
4744 newsrv->ssl_ctx.ciphers = strdup(args[*cur_arg + 1]);
4745 return 0;
4746}
4747
Emeric Brunef42d922012-10-11 16:11:36 +02004748/* parse the "crl-file" server keyword */
4749static int srv_parse_crl_file(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4750{
4751#ifndef X509_V_FLAG_CRL_CHECK
4752 if (err)
4753 memprintf(err, "'%s' : library does not support CRL verify", args[*cur_arg]);
4754 return ERR_ALERT | ERR_FATAL;
4755#else
4756 if (!*args[*cur_arg + 1]) {
4757 if (err)
4758 memprintf(err, "'%s' : missing CRLfile path", args[*cur_arg]);
4759 return ERR_ALERT | ERR_FATAL;
4760 }
4761
4762 if ((*args[*cur_arg + 1] != '/') && global.ca_base)
4763 memprintf(&newsrv->ssl_ctx.crl_file, "%s/%s", global.ca_base, args[*cur_arg + 1]);
4764 else
4765 memprintf(&newsrv->ssl_ctx.crl_file, "%s", args[*cur_arg + 1]);
4766
4767 return 0;
4768#endif
4769}
4770
Emeric Bruna7aa3092012-10-26 12:58:00 +02004771/* parse the "crt" server keyword */
4772static int srv_parse_crt(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4773{
4774 if (!*args[*cur_arg + 1]) {
4775 if (err)
4776 memprintf(err, "'%s' : missing certificate file path", args[*cur_arg]);
4777 return ERR_ALERT | ERR_FATAL;
4778 }
4779
4780 if ((*args[*cur_arg + 1] != '/') && global.crt_base)
4781 memprintf(&newsrv->ssl_ctx.client_crt, "%s/%s", global.ca_base, args[*cur_arg + 1]);
4782 else
4783 memprintf(&newsrv->ssl_ctx.client_crt, "%s", args[*cur_arg + 1]);
4784
4785 return 0;
4786}
Emeric Brunef42d922012-10-11 16:11:36 +02004787
Willy Tarreau92faadf2012-10-10 23:04:25 +02004788/* parse the "force-sslv3" server keyword */
4789static int srv_parse_force_sslv3(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4790{
4791 newsrv->ssl_ctx.options |= SRV_SSL_O_USE_SSLV3;
4792 return 0;
4793}
4794
4795/* parse the "force-tlsv10" server keyword */
4796static int srv_parse_force_tlsv10(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4797{
4798 newsrv->ssl_ctx.options |= SRV_SSL_O_USE_TLSV10;
4799 return 0;
4800}
4801
4802/* parse the "force-tlsv11" server keyword */
4803static int srv_parse_force_tlsv11(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4804{
4805#if SSL_OP_NO_TLSv1_1
4806 newsrv->ssl_ctx.options |= SRV_SSL_O_USE_TLSV11;
4807 return 0;
4808#else
4809 if (err)
4810 memprintf(err, "'%s' : library does not support protocol TLSv1.1", args[*cur_arg]);
4811 return ERR_ALERT | ERR_FATAL;
4812#endif
4813}
4814
4815/* parse the "force-tlsv12" server keyword */
4816static int srv_parse_force_tlsv12(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4817{
4818#if SSL_OP_NO_TLSv1_2
4819 newsrv->ssl_ctx.options |= SRV_SSL_O_USE_TLSV12;
4820 return 0;
4821#else
4822 if (err)
4823 memprintf(err, "'%s' : library does not support protocol TLSv1.2", args[*cur_arg]);
4824 return ERR_ALERT | ERR_FATAL;
4825#endif
4826}
4827
Willy Tarreau2a3fb1c2015-02-05 16:47:07 +01004828/* parse the "no-ssl-reuse" server keyword */
4829static int srv_parse_no_ssl_reuse(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4830{
4831 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_REUSE;
4832 return 0;
4833}
4834
Willy Tarreau92faadf2012-10-10 23:04:25 +02004835/* parse the "no-sslv3" server keyword */
4836static int srv_parse_no_sslv3(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4837{
4838 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_SSLV3;
4839 return 0;
4840}
4841
4842/* parse the "no-tlsv10" server keyword */
4843static int srv_parse_no_tlsv10(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4844{
4845 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_TLSV10;
4846 return 0;
4847}
4848
4849/* parse the "no-tlsv11" server keyword */
4850static int srv_parse_no_tlsv11(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4851{
4852 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_TLSV11;
4853 return 0;
4854}
4855
4856/* parse the "no-tlsv12" server keyword */
4857static int srv_parse_no_tlsv12(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4858{
4859 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_TLSV12;
4860 return 0;
4861}
4862
Emeric Brunf9c5c472012-10-11 15:28:34 +02004863/* parse the "no-tls-tickets" server keyword */
4864static int srv_parse_no_tls_tickets(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4865{
4866 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_TLS_TICKETS;
4867 return 0;
4868}
David Safb76832014-05-08 23:42:08 -04004869/* parse the "send-proxy-v2-ssl" server keyword */
4870static int srv_parse_send_proxy_ssl(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4871{
4872 newsrv->pp_opts |= SRV_PP_V2;
4873 newsrv->pp_opts |= SRV_PP_V2_SSL;
4874 return 0;
4875}
4876
4877/* parse the "send-proxy-v2-ssl-cn" server keyword */
4878static int srv_parse_send_proxy_cn(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4879{
4880 newsrv->pp_opts |= SRV_PP_V2;
4881 newsrv->pp_opts |= SRV_PP_V2_SSL;
4882 newsrv->pp_opts |= SRV_PP_V2_SSL_CN;
4883 return 0;
4884}
Emeric Brunf9c5c472012-10-11 15:28:34 +02004885
Willy Tarreau92faadf2012-10-10 23:04:25 +02004886/* parse the "ssl" server keyword */
4887static int srv_parse_ssl(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4888{
4889 newsrv->use_ssl = 1;
4890 if (global.connect_default_ciphers && !newsrv->ssl_ctx.ciphers)
4891 newsrv->ssl_ctx.ciphers = strdup(global.connect_default_ciphers);
4892 return 0;
4893}
4894
Emeric Brunef42d922012-10-11 16:11:36 +02004895/* parse the "verify" server keyword */
4896static int srv_parse_verify(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4897{
4898 if (!*args[*cur_arg + 1]) {
4899 if (err)
4900 memprintf(err, "'%s' : missing verify method", args[*cur_arg]);
4901 return ERR_ALERT | ERR_FATAL;
4902 }
4903
4904 if (strcmp(args[*cur_arg + 1], "none") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01004905 newsrv->ssl_ctx.verify = SSL_SOCK_VERIFY_NONE;
Emeric Brunef42d922012-10-11 16:11:36 +02004906 else if (strcmp(args[*cur_arg + 1], "required") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01004907 newsrv->ssl_ctx.verify = SSL_SOCK_VERIFY_REQUIRED;
Emeric Brunef42d922012-10-11 16:11:36 +02004908 else {
4909 if (err)
4910 memprintf(err, "'%s' : unknown verify method '%s', only 'none' and 'required' are supported\n",
4911 args[*cur_arg], args[*cur_arg + 1]);
4912 return ERR_ALERT | ERR_FATAL;
4913 }
4914
Evan Broderbe554312013-06-27 00:05:25 -07004915 return 0;
4916}
4917
4918/* parse the "verifyhost" server keyword */
4919static int srv_parse_verifyhost(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4920{
4921 if (!*args[*cur_arg + 1]) {
4922 if (err)
4923 memprintf(err, "'%s' : missing hostname to verify against", args[*cur_arg]);
4924 return ERR_ALERT | ERR_FATAL;
4925 }
4926
4927 newsrv->ssl_ctx.verify_host = strdup(args[*cur_arg + 1]);
4928
Emeric Brunef42d922012-10-11 16:11:36 +02004929 return 0;
4930}
4931
Emeric Brun2c86cbf2014-10-30 15:56:50 +01004932/* parse the "ssl-default-bind-options" keyword in global section */
4933static int ssl_parse_default_bind_options(char **args, int section_type, struct proxy *curpx,
4934 struct proxy *defpx, const char *file, int line,
4935 char **err) {
4936 int i = 1;
4937
4938 if (*(args[i]) == 0) {
4939 memprintf(err, "global statement '%s' expects an option as an argument.", args[0]);
4940 return -1;
4941 }
4942 while (*(args[i])) {
4943 if (!strcmp(args[i], "no-sslv3"))
4944 global.listen_default_ssloptions |= BC_SSL_O_NO_SSLV3;
4945 else if (!strcmp(args[i], "no-tlsv10"))
4946 global.listen_default_ssloptions |= BC_SSL_O_NO_TLSV10;
4947 else if (!strcmp(args[i], "no-tlsv11"))
4948 global.listen_default_ssloptions |= BC_SSL_O_NO_TLSV11;
4949 else if (!strcmp(args[i], "no-tlsv12"))
4950 global.listen_default_ssloptions |= BC_SSL_O_NO_TLSV12;
4951 else if (!strcmp(args[i], "force-sslv3"))
4952 global.listen_default_ssloptions |= BC_SSL_O_USE_SSLV3;
4953 else if (!strcmp(args[i], "force-tlsv10"))
4954 global.listen_default_ssloptions |= BC_SSL_O_USE_TLSV10;
4955 else if (!strcmp(args[i], "force-tlsv11")) {
4956#if SSL_OP_NO_TLSv1_1
4957 global.listen_default_ssloptions |= BC_SSL_O_USE_TLSV11;
4958#else
4959 memprintf(err, "'%s' '%s': library does not support protocol TLSv1.1", args[0], args[i]);
4960 return -1;
4961#endif
4962 }
4963 else if (!strcmp(args[i], "force-tlsv12")) {
4964#if SSL_OP_NO_TLSv1_2
4965 global.listen_default_ssloptions |= BC_SSL_O_USE_TLSV12;
4966#else
4967 memprintf(err, "'%s' '%s': library does not support protocol TLSv1.2", args[0], args[i]);
4968 return -1;
4969#endif
4970 }
4971 else if (!strcmp(args[i], "no-tls-tickets"))
4972 global.listen_default_ssloptions |= BC_SSL_O_NO_TLS_TICKETS;
4973 else {
4974 memprintf(err, "unknown option '%s' on global statement '%s'.", args[i], args[0]);
4975 return -1;
4976 }
4977 i++;
4978 }
4979 return 0;
4980}
4981
4982/* parse the "ssl-default-server-options" keyword in global section */
4983static int ssl_parse_default_server_options(char **args, int section_type, struct proxy *curpx,
4984 struct proxy *defpx, const char *file, int line,
4985 char **err) {
4986 int i = 1;
4987
4988 if (*(args[i]) == 0) {
4989 memprintf(err, "global statement '%s' expects an option as an argument.", args[0]);
4990 return -1;
4991 }
4992 while (*(args[i])) {
4993 if (!strcmp(args[i], "no-sslv3"))
4994 global.connect_default_ssloptions |= SRV_SSL_O_NO_SSLV3;
4995 else if (!strcmp(args[i], "no-tlsv10"))
4996 global.connect_default_ssloptions |= SRV_SSL_O_NO_TLSV10;
4997 else if (!strcmp(args[i], "no-tlsv11"))
4998 global.connect_default_ssloptions |= SRV_SSL_O_NO_TLSV11;
4999 else if (!strcmp(args[i], "no-tlsv12"))
5000 global.connect_default_ssloptions |= SRV_SSL_O_NO_TLSV12;
5001 else if (!strcmp(args[i], "force-sslv3"))
5002 global.connect_default_ssloptions |= SRV_SSL_O_USE_SSLV3;
5003 else if (!strcmp(args[i], "force-tlsv10"))
5004 global.connect_default_ssloptions |= SRV_SSL_O_USE_TLSV10;
5005 else if (!strcmp(args[i], "force-tlsv11")) {
5006#if SSL_OP_NO_TLSv1_1
5007 global.connect_default_ssloptions |= SRV_SSL_O_USE_TLSV11;
5008#else
5009 memprintf(err, "'%s' '%s': library does not support protocol TLSv1.1", args[0], args[i]);
5010 return -1;
5011#endif
5012 }
5013 else if (!strcmp(args[i], "force-tlsv12")) {
5014#if SSL_OP_NO_TLSv1_2
5015 global.connect_default_ssloptions |= SRV_SSL_O_USE_TLSV12;
5016#else
5017 memprintf(err, "'%s' '%s': library does not support protocol TLSv1.2", args[0], args[i]);
5018 return -1;
5019#endif
5020 }
5021 else if (!strcmp(args[i], "no-tls-tickets"))
5022 global.connect_default_ssloptions |= SRV_SSL_O_NO_TLS_TICKETS;
5023 else {
5024 memprintf(err, "unknown option '%s' on global statement '%s'.", args[i], args[0]);
5025 return -1;
5026 }
5027 i++;
5028 }
5029 return 0;
5030}
5031
Willy Tarreau7875d092012-09-10 08:20:03 +02005032/* Note: must not be declared <const> as its list will be overwritten.
5033 * Please take care of keeping this list alphabetically sorted.
5034 */
Willy Tarreaudc13c112013-06-21 23:16:39 +02005035static struct sample_fetch_kw_list sample_fetch_keywords = {ILH, {
Emeric Brun645ae792014-04-30 14:21:06 +02005036 { "ssl_bc", smp_fetch_ssl_fc, 0, NULL, SMP_T_BOOL, SMP_USE_L5SRV },
5037 { "ssl_bc_alg_keysize", smp_fetch_ssl_fc_alg_keysize, 0, NULL, SMP_T_UINT, SMP_USE_L5SRV },
5038 { "ssl_bc_cipher", smp_fetch_ssl_fc_cipher, 0, NULL, SMP_T_STR, SMP_USE_L5SRV },
5039 { "ssl_bc_protocol", smp_fetch_ssl_fc_protocol, 0, NULL, SMP_T_STR, SMP_USE_L5SRV },
Emeric Brunb73a9b02014-04-30 18:49:19 +02005040 { "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 +02005041 { "ssl_bc_use_keysize", smp_fetch_ssl_fc_use_keysize, 0, NULL, SMP_T_UINT, SMP_USE_L5SRV },
5042 { "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 +01005043 { "ssl_c_ca_err", smp_fetch_ssl_c_ca_err, 0, NULL, SMP_T_UINT, SMP_USE_L5CLI },
5044 { "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 +01005045 { "ssl_c_der", smp_fetch_ssl_x_der, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Willy Tarreau80aca902013-01-07 15:42:20 +01005046 { "ssl_c_err", smp_fetch_ssl_c_err, 0, NULL, SMP_T_UINT, SMP_USE_L5CLI },
Emeric Brunba841a12014-04-30 17:05:08 +02005047 { "ssl_c_i_dn", smp_fetch_ssl_x_i_dn, ARG2(0,STR,SINT), NULL, SMP_T_STR, SMP_USE_L5CLI },
5048 { "ssl_c_key_alg", smp_fetch_ssl_x_key_alg, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
5049 { "ssl_c_notafter", smp_fetch_ssl_x_notafter, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
5050 { "ssl_c_notbefore", smp_fetch_ssl_x_notbefore, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
5051 { "ssl_c_sig_alg", smp_fetch_ssl_x_sig_alg, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
5052 { "ssl_c_s_dn", smp_fetch_ssl_x_s_dn, ARG2(0,STR,SINT), NULL, SMP_T_STR, SMP_USE_L5CLI },
5053 { "ssl_c_serial", smp_fetch_ssl_x_serial, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
5054 { "ssl_c_sha1", smp_fetch_ssl_x_sha1, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Willy Tarreau80aca902013-01-07 15:42:20 +01005055 { "ssl_c_used", smp_fetch_ssl_c_used, 0, NULL, SMP_T_BOOL, SMP_USE_L5CLI },
5056 { "ssl_c_verify", smp_fetch_ssl_c_verify, 0, NULL, SMP_T_UINT, SMP_USE_L5CLI },
Emeric Brunba841a12014-04-30 17:05:08 +02005057 { "ssl_c_version", smp_fetch_ssl_x_version, 0, NULL, SMP_T_UINT, SMP_USE_L5CLI },
Emeric Brun43e79582014-10-29 19:03:26 +01005058 { "ssl_f_der", smp_fetch_ssl_x_der, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Emeric Brunba841a12014-04-30 17:05:08 +02005059 { "ssl_f_i_dn", smp_fetch_ssl_x_i_dn, ARG2(0,STR,SINT), NULL, SMP_T_STR, SMP_USE_L5CLI },
5060 { "ssl_f_key_alg", smp_fetch_ssl_x_key_alg, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
5061 { "ssl_f_notafter", smp_fetch_ssl_x_notafter, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
5062 { "ssl_f_notbefore", smp_fetch_ssl_x_notbefore, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
5063 { "ssl_f_sig_alg", smp_fetch_ssl_x_sig_alg, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
5064 { "ssl_f_s_dn", smp_fetch_ssl_x_s_dn, ARG2(0,STR,SINT), NULL, SMP_T_STR, SMP_USE_L5CLI },
5065 { "ssl_f_serial", smp_fetch_ssl_x_serial, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Emeric Brun55f4fa82014-04-30 17:11:25 +02005066 { "ssl_f_sha1", smp_fetch_ssl_x_sha1, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Emeric Brunba841a12014-04-30 17:05:08 +02005067 { "ssl_f_version", smp_fetch_ssl_x_version, 0, NULL, SMP_T_UINT, SMP_USE_L5CLI },
Willy Tarreau80aca902013-01-07 15:42:20 +01005068 { "ssl_fc", smp_fetch_ssl_fc, 0, NULL, SMP_T_BOOL, SMP_USE_L5CLI },
5069 { "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 +01005070 { "ssl_fc_cipher", smp_fetch_ssl_fc_cipher, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Willy Tarreau80aca902013-01-07 15:42:20 +01005071 { "ssl_fc_has_crt", smp_fetch_ssl_fc_has_crt, 0, NULL, SMP_T_BOOL, SMP_USE_L5CLI },
5072 { "ssl_fc_has_sni", smp_fetch_ssl_fc_has_sni, 0, NULL, SMP_T_BOOL, SMP_USE_L5CLI },
Nenad Merdanovic26ea8222015-05-18 02:28:57 +02005073 { "ssl_fc_is_resumed", smp_fetch_ssl_fc_is_resumed, 0, NULL, SMP_T_BOOL, SMP_USE_L5CLI },
Willy Tarreaua33c6542012-10-15 13:19:06 +02005074#ifdef OPENSSL_NPN_NEGOTIATED
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01005075 { "ssl_fc_npn", smp_fetch_ssl_fc_npn, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Willy Tarreaua33c6542012-10-15 13:19:06 +02005076#endif
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01005077#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01005078 { "ssl_fc_alpn", smp_fetch_ssl_fc_alpn, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Willy Tarreauab861d32013-04-02 02:30:41 +02005079#endif
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01005080 { "ssl_fc_protocol", smp_fetch_ssl_fc_protocol, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Emeric Brunb73a9b02014-04-30 18:49:19 +02005081 { "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 +01005082 { "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 +01005083 { "ssl_fc_session_id", smp_fetch_ssl_fc_session_id, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
5084 { "ssl_fc_sni", smp_fetch_ssl_fc_sni, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Willy Tarreau7875d092012-09-10 08:20:03 +02005085 { NULL, NULL, 0, 0, 0 },
5086}};
5087
5088/* Note: must not be declared <const> as its list will be overwritten.
5089 * Please take care of keeping this list alphabetically sorted.
5090 */
Willy Tarreaudc13c112013-06-21 23:16:39 +02005091static struct acl_kw_list acl_kws = {ILH, {
Thierry FOURNIERc5a4e982014-03-05 16:07:08 +01005092 { "ssl_fc_sni_end", "ssl_fc_sni", PAT_MATCH_END },
5093 { "ssl_fc_sni_reg", "ssl_fc_sni", PAT_MATCH_REG },
Willy Tarreau8ed669b2013-01-11 15:49:37 +01005094 { /* END */ },
Willy Tarreau7875d092012-09-10 08:20:03 +02005095}};
5096
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005097/* Note: must not be declared <const> as its list will be overwritten.
5098 * Please take care of keeping this list alphabetically sorted, doing so helps
5099 * all code contributors.
5100 * Optional keywords are also declared with a NULL ->parse() function so that
5101 * the config parser can report an appropriate error when a known keyword was
5102 * not enabled.
5103 */
Willy Tarreau51fb7652012-09-18 18:24:39 +02005104static struct bind_kw_list bind_kws = { "SSL", { }, {
Nenad Merdanovic05552d42015-02-27 19:56:49 +01005105 { "alpn", bind_parse_alpn, 1 }, /* set ALPN supported protocols */
5106 { "ca-file", bind_parse_ca_file, 1 }, /* set CAfile to process verify on client cert */
5107 { "ca-ignore-err", bind_parse_ignore_err, 1 }, /* set error IDs to ignore on verify depth > 0 */
Christopher Faulet31af49d2015-06-09 17:29:50 +02005108 { "ca-sign-file", bind_parse_ca_sign_file, 1 }, /* set CAFile used to generate and sign server certs */
5109 { "ca-sign-pass", bind_parse_ca_sign_pass, 1 }, /* set CAKey passphrase */
Nenad Merdanovic05552d42015-02-27 19:56:49 +01005110 { "ciphers", bind_parse_ciphers, 1 }, /* set SSL cipher suite */
5111 { "crl-file", bind_parse_crl_file, 1 }, /* set certificat revocation list file use on client cert verify */
5112 { "crt", bind_parse_crt, 1 }, /* load SSL certificates from this location */
5113 { "crt-ignore-err", bind_parse_ignore_err, 1 }, /* set error IDs to ingore on verify depth == 0 */
5114 { "crt-list", bind_parse_crt_list, 1 }, /* load a list of crt from this location */
5115 { "ecdhe", bind_parse_ecdhe, 1 }, /* defines named curve for elliptic curve Diffie-Hellman */
5116 { "force-sslv3", bind_parse_force_sslv3, 0 }, /* force SSLv3 */
5117 { "force-tlsv10", bind_parse_force_tlsv10, 0 }, /* force TLSv10 */
5118 { "force-tlsv11", bind_parse_force_tlsv11, 0 }, /* force TLSv11 */
5119 { "force-tlsv12", bind_parse_force_tlsv12, 0 }, /* force TLSv12 */
Christopher Faulet31af49d2015-06-09 17:29:50 +02005120 { "generate-certificates", bind_parse_generate_certs, 0 }, /* enable the server certificates generation */
Nenad Merdanovic05552d42015-02-27 19:56:49 +01005121 { "no-sslv3", bind_parse_no_sslv3, 0 }, /* disable SSLv3 */
5122 { "no-tlsv10", bind_parse_no_tlsv10, 0 }, /* disable TLSv10 */
5123 { "no-tlsv11", bind_parse_no_tlsv11, 0 }, /* disable TLSv11 */
5124 { "no-tlsv12", bind_parse_no_tlsv12, 0 }, /* disable TLSv12 */
5125 { "no-tls-tickets", bind_parse_no_tls_tickets, 0 }, /* disable session resumption tickets */
5126 { "ssl", bind_parse_ssl, 0 }, /* enable SSL processing */
5127 { "strict-sni", bind_parse_strict_sni, 0 }, /* refuse negotiation if sni doesn't match a certificate */
5128 { "tls-ticket-keys", bind_parse_tls_ticket_keys, 1 }, /* set file to load TLS ticket keys from */
5129 { "verify", bind_parse_verify, 1 }, /* set SSL verify method */
5130 { "npn", bind_parse_npn, 1 }, /* set NPN supported protocols */
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005131 { NULL, NULL, 0 },
5132}};
Emeric Brun46591952012-05-18 15:47:34 +02005133
Willy Tarreau92faadf2012-10-10 23:04:25 +02005134/* Note: must not be declared <const> as its list will be overwritten.
5135 * Please take care of keeping this list alphabetically sorted, doing so helps
5136 * all code contributors.
5137 * Optional keywords are also declared with a NULL ->parse() function so that
5138 * the config parser can report an appropriate error when a known keyword was
5139 * not enabled.
5140 */
5141static struct srv_kw_list srv_kws = { "SSL", { }, {
Emeric Brunef42d922012-10-11 16:11:36 +02005142 { "ca-file", srv_parse_ca_file, 1, 0 }, /* set CAfile to process verify server cert */
Emeric Brunecc91fe2012-10-11 15:05:10 +02005143 { "check-ssl", srv_parse_check_ssl, 0, 0 }, /* enable SSL for health checks */
5144 { "ciphers", srv_parse_ciphers, 1, 0 }, /* select the cipher suite */
Emeric Brunef42d922012-10-11 16:11:36 +02005145 { "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 +02005146 { "crt", srv_parse_crt, 1, 0 }, /* set client certificate */
Emeric Brunecc91fe2012-10-11 15:05:10 +02005147 { "force-sslv3", srv_parse_force_sslv3, 0, 0 }, /* force SSLv3 */
5148 { "force-tlsv10", srv_parse_force_tlsv10, 0, 0 }, /* force TLSv10 */
5149 { "force-tlsv11", srv_parse_force_tlsv11, 0, 0 }, /* force TLSv11 */
5150 { "force-tlsv12", srv_parse_force_tlsv12, 0, 0 }, /* force TLSv12 */
Willy Tarreau2a3fb1c2015-02-05 16:47:07 +01005151 { "no-ssl-reuse", srv_parse_no_ssl_reuse, 0, 0 }, /* disable session reuse */
Emeric Brunecc91fe2012-10-11 15:05:10 +02005152 { "no-sslv3", srv_parse_no_sslv3, 0, 0 }, /* disable SSLv3 */
5153 { "no-tlsv10", srv_parse_no_tlsv10, 0, 0 }, /* disable TLSv10 */
5154 { "no-tlsv11", srv_parse_no_tlsv11, 0, 0 }, /* disable TLSv11 */
5155 { "no-tlsv12", srv_parse_no_tlsv12, 0, 0 }, /* disable TLSv12 */
Emeric Brunf9c5c472012-10-11 15:28:34 +02005156 { "no-tls-tickets", srv_parse_no_tls_tickets, 0, 0 }, /* disable session resumption tickets */
David Safb76832014-05-08 23:42:08 -04005157 { "send-proxy-v2-ssl", srv_parse_send_proxy_ssl, 0, 0 }, /* send PROXY protocol header v2 with SSL info */
5158 { "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 +02005159 { "ssl", srv_parse_ssl, 0, 0 }, /* enable SSL processing */
Emeric Brunef42d922012-10-11 16:11:36 +02005160 { "verify", srv_parse_verify, 1, 0 }, /* set SSL verify method */
Evan Broderbe554312013-06-27 00:05:25 -07005161 { "verifyhost", srv_parse_verifyhost, 1, 0 }, /* require that SSL cert verifies for hostname */
Willy Tarreau92faadf2012-10-10 23:04:25 +02005162 { NULL, NULL, 0, 0 },
5163}};
5164
Emeric Brun2c86cbf2014-10-30 15:56:50 +01005165static struct cfg_kw_list cfg_kws = {ILH, {
5166 { CFG_GLOBAL, "ssl-default-bind-options", ssl_parse_default_bind_options },
5167 { CFG_GLOBAL, "ssl-default-server-options", ssl_parse_default_server_options },
5168 { 0, NULL, NULL },
5169}};
5170
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02005171/* transport-layer operations for SSL sockets */
5172struct xprt_ops ssl_sock = {
Emeric Brun46591952012-05-18 15:47:34 +02005173 .snd_buf = ssl_sock_from_buf,
5174 .rcv_buf = ssl_sock_to_buf,
5175 .rcv_pipe = NULL,
5176 .snd_pipe = NULL,
5177 .shutr = NULL,
5178 .shutw = ssl_sock_shutw,
5179 .close = ssl_sock_close,
5180 .init = ssl_sock_init,
5181};
5182
Janusz Dziemidowicz2c701b52015-03-07 23:03:59 +01005183#if (OPENSSL_VERSION_NUMBER >= 0x1000200fL && !defined OPENSSL_NO_TLSEXT && !defined OPENSSL_IS_BORINGSSL)
5184
5185static void ssl_sock_sctl_free_func(void *parent, void *ptr, CRYPTO_EX_DATA *ad, int idx, long argl, void *argp)
5186{
5187 if (ptr) {
5188 chunk_destroy(ptr);
5189 free(ptr);
5190 }
5191}
5192
5193#endif
5194
Emeric Brun46591952012-05-18 15:47:34 +02005195__attribute__((constructor))
Willy Tarreau92faadf2012-10-10 23:04:25 +02005196static void __ssl_sock_init(void)
5197{
Emeric Brun46591952012-05-18 15:47:34 +02005198 STACK_OF(SSL_COMP)* cm;
5199
Willy Tarreau610f04b2014-02-13 11:36:41 +01005200#ifdef LISTEN_DEFAULT_CIPHERS
5201 global.listen_default_ciphers = LISTEN_DEFAULT_CIPHERS;
5202#endif
5203#ifdef CONNECT_DEFAULT_CIPHERS
5204 global.connect_default_ciphers = CONNECT_DEFAULT_CIPHERS;
5205#endif
5206 if (global.listen_default_ciphers)
5207 global.listen_default_ciphers = strdup(global.listen_default_ciphers);
5208 if (global.connect_default_ciphers)
5209 global.connect_default_ciphers = strdup(global.connect_default_ciphers);
Emeric Brun2c86cbf2014-10-30 15:56:50 +01005210 global.listen_default_ssloptions = BC_SSL_O_NONE;
5211 global.connect_default_ssloptions = SRV_SSL_O_NONE;
Willy Tarreau610f04b2014-02-13 11:36:41 +01005212
Emeric Brun46591952012-05-18 15:47:34 +02005213 SSL_library_init();
5214 cm = SSL_COMP_get_compression_methods();
5215 sk_SSL_COMP_zero(cm);
Janusz Dziemidowicz2c701b52015-03-07 23:03:59 +01005216#if (OPENSSL_VERSION_NUMBER >= 0x1000200fL && !defined OPENSSL_NO_TLSEXT && !defined OPENSSL_IS_BORINGSSL)
5217 sctl_ex_index = SSL_CTX_get_ex_new_index(0, NULL, NULL, NULL, ssl_sock_sctl_free_func);
5218#endif
Willy Tarreau7875d092012-09-10 08:20:03 +02005219 sample_register_fetches(&sample_fetch_keywords);
5220 acl_register_keywords(&acl_kws);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005221 bind_register_keywords(&bind_kws);
Willy Tarreau92faadf2012-10-10 23:04:25 +02005222 srv_register_keywords(&srv_kws);
Emeric Brun2c86cbf2014-10-30 15:56:50 +01005223 cfg_register_keywords(&cfg_kws);
Willy Tarreaud92aa5c2015-01-15 21:34:39 +01005224
5225 global.ssl_session_max_cost = SSL_SESSION_MAX_COST;
5226 global.ssl_handshake_max_cost = SSL_HANDSHAKE_MAX_COST;
Remi Gacogne4f902b82015-05-28 16:23:00 +02005227
5228#ifndef OPENSSL_NO_DH
5229 ssl_dh_ptr_index = SSL_CTX_get_ex_new_index(0, NULL, NULL, NULL, NULL);
5230#endif
Christopher Faulet31af49d2015-06-09 17:29:50 +02005231
5232 /* Add a global parameter for the LRU cache size */
5233 if (global.tune.ssl_ctx_cache)
5234 ssl_ctx_lru_tree = lru64_new(global.tune.ssl_ctx_cache);
5235 ssl_ctx_lru_seed = (unsigned int)time(NULL);
Emeric Brun46591952012-05-18 15:47:34 +02005236}
5237
Remi Gacogned3a23c32015-05-28 16:39:47 +02005238__attribute__((destructor))
5239static void __ssl_sock_deinit(void)
5240{
Christopher Faulet31af49d2015-06-09 17:29:50 +02005241 lru64_destroy(ssl_ctx_lru_tree);
5242
Remi Gacogned3a23c32015-05-28 16:39:47 +02005243#ifndef OPENSSL_NO_DH
5244 if (local_dh_1024) {
5245 DH_free(local_dh_1024);
5246 local_dh_1024 = NULL;
5247 }
5248
5249 if (local_dh_2048) {
5250 DH_free(local_dh_2048);
5251 local_dh_2048 = NULL;
5252 }
5253
5254 if (local_dh_4096) {
5255 DH_free(local_dh_4096);
5256 local_dh_4096 = NULL;
5257 }
5258
Remi Gacogne47783ef2015-05-29 15:53:22 +02005259 if (global_dh) {
5260 DH_free(global_dh);
5261 global_dh = NULL;
5262 }
Remi Gacogned3a23c32015-05-28 16:39:47 +02005263#endif
5264
5265 ERR_remove_state(0);
5266 ERR_free_strings();
5267
5268 EVP_cleanup();
5269
5270#if OPENSSL_VERSION_NUMBER >= 0x00907000L
5271 CRYPTO_cleanup_all_ex_data();
5272#endif
5273}
5274
5275
Emeric Brun46591952012-05-18 15:47:34 +02005276/*
5277 * Local variables:
5278 * c-indent-level: 8
5279 * c-basic-offset: 8
5280 * End:
5281 */