blob: dfc992549c7c0f3c6f3044e8df9000e8c39905fb [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 Faulet30548802015-06-11 13:39:32 +02001006/* Create a X509 certificate with the specified servername and serial. This
1007 * function returns a SSL_CTX object or NULL if an error occurs. */
1008SSL_CTX *
Christopher Faulet31af49d2015-06-09 17:29:50 +02001009ssl_sock_create_cert(const char *servername, unsigned int serial, X509 *cacert, EVP_PKEY *capkey)
1010{
1011 SSL_CTX *ssl_ctx = NULL;
1012 X509 *newcrt = NULL;
1013 EVP_PKEY *pkey = NULL;
1014 RSA *rsa;
1015 X509_NAME *name;
1016 const EVP_MD *digest;
1017 X509V3_CTX ctx;
1018 unsigned int i;
1019
1020 /* Generate the public key */
1021 if (!(rsa = RSA_generate_key(2048, 3, NULL, NULL)))
1022 goto mkcert_error;
1023 if (!(pkey = EVP_PKEY_new()))
1024 goto mkcert_error;
1025 if (EVP_PKEY_assign_RSA(pkey, rsa) != 1)
1026 goto mkcert_error;
1027
1028 /* Create the certificate */
1029 if (!(newcrt = X509_new()))
1030 goto mkcert_error;
1031
1032 /* Set version number for the certificate (X509v3) and the serial
1033 * number */
1034 if (X509_set_version(newcrt, 2L) != 1)
1035 goto mkcert_error;
1036 ASN1_INTEGER_set(X509_get_serialNumber(newcrt), serial);
1037
1038 /* Set duration for the certificate */
1039 if (!X509_gmtime_adj(X509_get_notBefore(newcrt), (long)-60*60*24) ||
1040 !X509_gmtime_adj(X509_get_notAfter(newcrt),(long)60*60*24*365))
1041 goto mkcert_error;
1042
1043 /* set public key in the certificate */
1044 if (X509_set_pubkey(newcrt, pkey) != 1)
1045 goto mkcert_error;
1046
1047 /* Set issuer name from the CA */
1048 if (!(name = X509_get_subject_name(cacert)))
1049 goto mkcert_error;
1050 if (X509_set_issuer_name(newcrt, name) != 1)
1051 goto mkcert_error;
1052
1053 /* Set the subject name using the same, but the CN */
1054 name = X509_NAME_dup(name);
1055 if (X509_NAME_add_entry_by_txt(name, "CN", MBSTRING_ASC,
1056 (const unsigned char *)servername,
1057 -1, -1, 0) != 1) {
1058 X509_NAME_free(name);
1059 goto mkcert_error;
1060 }
1061 if (X509_set_subject_name(newcrt, name) != 1) {
1062 X509_NAME_free(name);
1063 goto mkcert_error;
1064 }
1065 X509_NAME_free(name);
1066
1067 /* Add x509v3 extensions as specified */
1068 X509V3_set_ctx(&ctx, cacert, newcrt, NULL, NULL, 0);
1069 for (i = 0; i < X509V3_EXT_SIZE; i++) {
1070 X509_EXTENSION *ext;
1071
1072 if (!(ext = X509V3_EXT_conf(NULL, &ctx, x509v3_ext_names[i], x509v3_ext_values[i])))
1073 goto mkcert_error;
1074 if (!X509_add_ext(newcrt, ext, -1)) {
1075 X509_EXTENSION_free(ext);
1076 goto mkcert_error;
1077 }
1078 X509_EXTENSION_free(ext);
1079 }
1080
1081 /* Sign the certificate with the CA private key */
1082 if (EVP_PKEY_type(capkey->type) == EVP_PKEY_DSA)
1083 digest = EVP_dss1();
1084 else if (EVP_PKEY_type (capkey->type) == EVP_PKEY_RSA)
1085 digest = EVP_sha256();
1086 else
1087 goto mkcert_error;
1088 if (!(X509_sign(newcrt, capkey, digest)))
1089 goto mkcert_error;
1090
1091 /* Create and set the new SSL_CTX */
1092 if (!(ssl_ctx = SSL_CTX_new(SSLv23_server_method())))
1093 goto mkcert_error;
1094 if (!SSL_CTX_use_PrivateKey(ssl_ctx, pkey))
1095 goto mkcert_error;
1096 if (!SSL_CTX_use_certificate(ssl_ctx, newcrt))
1097 goto mkcert_error;
1098 if (!SSL_CTX_check_private_key(ssl_ctx))
1099 goto mkcert_error;
1100
1101 if (newcrt) X509_free(newcrt);
1102 if (pkey) EVP_PKEY_free(pkey);
1103 return ssl_ctx;
1104
1105 mkcert_error:
1106 if (ssl_ctx) SSL_CTX_free(ssl_ctx);
1107 if (newcrt) X509_free(newcrt);
1108 if (pkey) EVP_PKEY_free(pkey);
1109 return NULL;
1110}
1111
Christopher Faulet30548802015-06-11 13:39:32 +02001112/* Do a lookup for a certificate in the LRU cache used to store generated
1113 * certificates. */
1114SSL_CTX *
1115ssl_sock_get_generated_cert(unsigned int serial, X509 *cacert)
1116{
1117 struct lru64 *lru = NULL;
1118
1119 if (ssl_ctx_lru_tree) {
1120 lru = lru64_lookup(serial, ssl_ctx_lru_tree, cacert, 0);
1121 if (lru && lru->domain)
1122 return (SSL_CTX *)lru->data;
1123 }
1124 return NULL;
1125}
1126
1127/* Set a certificate int the LRU cache used to store generated certificate. */
1128void
1129ssl_sock_set_generated_cert(SSL_CTX *ssl_ctx, unsigned int serial, X509 *cacert)
1130{
1131 struct lru64 *lru = NULL;
1132
1133 if (ssl_ctx_lru_tree) {
1134 lru = lru64_get(serial, ssl_ctx_lru_tree, cacert, 0);
1135 if (!lru)
1136 return;
1137 if (lru->domain && lru->data)
1138 lru->free((SSL_CTX *)lru->data);
1139 lru64_commit(lru, ssl_ctx, cacert, 0, (void (*)(void *))SSL_CTX_free);
1140 }
1141}
1142
1143/* Compute the serial that will be used to create/set/get a certificate. */
1144unsigned int
1145ssl_sock_generated_cert_serial(void *data, size_t len)
1146{
1147 return XXH32(data, len, ssl_ctx_lru_seed);
1148}
1149
Christopher Faulet31af49d2015-06-09 17:29:50 +02001150static SSL_CTX *
1151ssl_sock_generate_certificate(const char *servername, struct bind_conf *bind_conf)
1152{
1153 X509 *cacert = bind_conf->ca_sign_cert;
1154 EVP_PKEY *capkey = bind_conf->ca_sign_pkey;
1155 SSL_CTX *ssl_ctx = NULL;
1156 struct lru64 *lru = NULL;
1157 unsigned int serial;
1158
1159 serial = XXH32(servername, strlen(servername), ssl_ctx_lru_seed);
1160 if (ssl_ctx_lru_tree) {
1161 lru = lru64_get(serial, ssl_ctx_lru_tree, cacert, 0);
1162 if (lru && lru->domain)
1163 ssl_ctx = (SSL_CTX *)lru->data;
1164 }
1165
1166 if (!ssl_ctx) {
1167 ssl_ctx = ssl_sock_create_cert(servername, serial, cacert, capkey);
1168 if (lru)
1169 lru64_commit(lru, ssl_ctx, cacert, 0, (void (*)(void *))SSL_CTX_free);
1170 }
1171 return ssl_ctx;
1172}
1173
Emeric Brunfc0421f2012-09-07 17:30:07 +02001174#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
1175/* Sets the SSL ctx of <ssl> to match the advertised server name. Returns a
1176 * warning when no match is found, which implies the default (first) cert
1177 * will keep being used.
1178 */
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001179static int ssl_sock_switchctx_cbk(SSL *ssl, int *al, struct bind_conf *s)
Emeric Brunfc0421f2012-09-07 17:30:07 +02001180{
1181 const char *servername;
1182 const char *wildp = NULL;
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001183 struct ebmb_node *node, *n;
Emeric Brunfc0421f2012-09-07 17:30:07 +02001184 int i;
1185 (void)al; /* shut gcc stupid warning */
1186
1187 servername = SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name);
Emmanuel Hocdet65623372013-01-24 17:17:15 +01001188 if (!servername) {
Christopher Faulet30548802015-06-11 13:39:32 +02001189 struct sockaddr to;
1190 int fd;
1191
1192 if (s->generate_certs &&
1193 (fd = SSL_get_fd(ssl)) != -1 &&
1194 tcp_get_dst(fd, &to, sizeof(to), 0) != -1) {
1195 unsigned int serial = ssl_sock_generated_cert_serial(&to, sizeof(to));
1196 SSL_CTX *ctx = ssl_sock_get_generated_cert(serial, s->ca_sign_cert);
1197 if (ctx) {
1198 /* switch ctx */
1199 SSL_set_SSL_CTX(ssl, ctx);
1200 return SSL_TLSEXT_ERR_OK;
1201 }
1202 }
1203
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001204 return (s->strict_sni ?
1205 SSL_TLSEXT_ERR_ALERT_FATAL :
Emmanuel Hocdet79274e22013-05-31 12:47:44 +02001206 SSL_TLSEXT_ERR_NOACK);
Emmanuel Hocdet65623372013-01-24 17:17:15 +01001207 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02001208
Willy Tarreau19d14ef2012-10-29 16:51:55 +01001209 for (i = 0; i < trash.size; i++) {
Emeric Brunfc0421f2012-09-07 17:30:07 +02001210 if (!servername[i])
1211 break;
Willy Tarreau19d14ef2012-10-29 16:51:55 +01001212 trash.str[i] = tolower(servername[i]);
1213 if (!wildp && (trash.str[i] == '.'))
1214 wildp = &trash.str[i];
Emeric Brunfc0421f2012-09-07 17:30:07 +02001215 }
Willy Tarreau19d14ef2012-10-29 16:51:55 +01001216 trash.str[i] = 0;
Emeric Brunfc0421f2012-09-07 17:30:07 +02001217
1218 /* lookup in full qualified names */
Willy Tarreau19d14ef2012-10-29 16:51:55 +01001219 node = ebst_lookup(&s->sni_ctx, trash.str);
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001220
1221 /* lookup a not neg filter */
1222 for (n = node; n; n = ebmb_next_dup(n)) {
1223 if (!container_of(n, struct sni_ctx, name)->neg) {
1224 node = n;
1225 break;
Emmanuel Hocdet65623372013-01-24 17:17:15 +01001226 }
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001227 }
1228 if (!node && wildp) {
1229 /* lookup in wildcards names */
Emeric Brunfc0421f2012-09-07 17:30:07 +02001230 node = ebst_lookup(&s->sni_w_ctx, wildp);
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001231 }
1232 if (!node || container_of(node, struct sni_ctx, name)->neg) {
Christopher Faulet31af49d2015-06-09 17:29:50 +02001233 SSL_CTX *ctx;
1234
1235 if (s->generate_certs &&
1236 (ctx = ssl_sock_generate_certificate(servername, s))) {
1237 /* switch ctx */
1238 SSL_set_SSL_CTX(ssl, ctx);
1239 return SSL_TLSEXT_ERR_OK;
1240 }
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001241 return (s->strict_sni ?
1242 SSL_TLSEXT_ERR_ALERT_FATAL :
1243 SSL_TLSEXT_ERR_ALERT_WARNING);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001244 }
1245
1246 /* switch ctx */
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001247 SSL_set_SSL_CTX(ssl, container_of(node, struct sni_ctx, name)->ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001248 return SSL_TLSEXT_ERR_OK;
1249}
1250#endif /* SSL_CTRL_SET_TLSEXT_HOSTNAME */
1251
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001252#ifndef OPENSSL_NO_DH
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001253
1254static DH * ssl_get_dh_1024(void)
1255{
Remi Gacogned3a341a2015-05-29 16:26:17 +02001256 static unsigned char dh1024_p[]={
1257 0xFA,0xF9,0x2A,0x22,0x2A,0xA7,0x7F,0xE1,0x67,0x4E,0x53,0xF7,
1258 0x56,0x13,0xC3,0xB1,0xE3,0x29,0x6B,0x66,0x31,0x6A,0x7F,0xB3,
1259 0xC2,0x68,0x6B,0xCB,0x1D,0x57,0x39,0x1D,0x1F,0xFF,0x1C,0xC9,
1260 0xA6,0xA4,0x98,0x82,0x31,0x5D,0x25,0xFF,0x8A,0xE0,0x73,0x96,
1261 0x81,0xC8,0x83,0x79,0xC1,0x5A,0x04,0xF8,0x37,0x0D,0xA8,0x3D,
1262 0xAE,0x74,0xBC,0xDB,0xB6,0xA4,0x75,0xD9,0x71,0x8A,0xA0,0x17,
1263 0x9E,0x2D,0xC8,0xA8,0xDF,0x2C,0x5F,0x82,0x95,0xF8,0x92,0x9B,
1264 0xA7,0x33,0x5F,0x89,0x71,0xC8,0x2D,0x6B,0x18,0x86,0xC4,0x94,
1265 0x22,0xA5,0x52,0x8D,0xF6,0xF6,0xD2,0x37,0x92,0x0F,0xA5,0xCC,
1266 0xDB,0x7B,0x1D,0x3D,0xA1,0x31,0xB7,0x80,0x8F,0x0B,0x67,0x5E,
1267 0x36,0xA5,0x60,0x0C,0xF1,0x95,0x33,0x8B,
1268 };
1269 static unsigned char dh1024_g[]={
1270 0x02,
1271 };
1272
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001273 DH *dh = DH_new();
1274 if (dh) {
Remi Gacogned3a341a2015-05-29 16:26:17 +02001275 dh->p = BN_bin2bn(dh1024_p, sizeof dh1024_p, NULL);
1276 dh->g = BN_bin2bn(dh1024_g, sizeof dh1024_g, NULL);
1277
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001278 if (!dh->p || !dh->g) {
1279 DH_free(dh);
1280 dh = NULL;
1281 }
1282 }
1283 return dh;
1284}
1285
1286static DH *ssl_get_dh_2048(void)
1287{
Remi Gacogned3a341a2015-05-29 16:26:17 +02001288 static unsigned char dh2048_p[]={
1289 0xEC,0x86,0xF8,0x70,0xA0,0x33,0x16,0xEC,0x05,0x1A,0x73,0x59,
1290 0xCD,0x1F,0x8B,0xF8,0x29,0xE4,0xD2,0xCF,0x52,0xDD,0xC2,0x24,
1291 0x8D,0xB5,0x38,0x9A,0xFB,0x5C,0xA4,0xE4,0xB2,0xDA,0xCE,0x66,
1292 0x50,0x74,0xA6,0x85,0x4D,0x4B,0x1D,0x30,0xB8,0x2B,0xF3,0x10,
1293 0xE9,0xA7,0x2D,0x05,0x71,0xE7,0x81,0xDF,0x8B,0x59,0x52,0x3B,
1294 0x5F,0x43,0x0B,0x68,0xF1,0xDB,0x07,0xBE,0x08,0x6B,0x1B,0x23,
1295 0xEE,0x4D,0xCC,0x9E,0x0E,0x43,0xA0,0x1E,0xDF,0x43,0x8C,0xEC,
1296 0xBE,0xBE,0x90,0xB4,0x51,0x54,0xB9,0x2F,0x7B,0x64,0x76,0x4E,
1297 0x5D,0xD4,0x2E,0xAE,0xC2,0x9E,0xAE,0x51,0x43,0x59,0xC7,0x77,
1298 0x9C,0x50,0x3C,0x0E,0xED,0x73,0x04,0x5F,0xF1,0x4C,0x76,0x2A,
1299 0xD8,0xF8,0xCF,0xFC,0x34,0x40,0xD1,0xB4,0x42,0x61,0x84,0x66,
1300 0x42,0x39,0x04,0xF8,0x68,0xB2,0x62,0xD7,0x55,0xED,0x1B,0x74,
1301 0x75,0x91,0xE0,0xC5,0x69,0xC1,0x31,0x5C,0xDB,0x7B,0x44,0x2E,
1302 0xCE,0x84,0x58,0x0D,0x1E,0x66,0x0C,0xC8,0x44,0x9E,0xFD,0x40,
1303 0x08,0x67,0x5D,0xFB,0xA7,0x76,0x8F,0x00,0x11,0x87,0xE9,0x93,
1304 0xF9,0x7D,0xC4,0xBC,0x74,0x55,0x20,0xD4,0x4A,0x41,0x2F,0x43,
1305 0x42,0x1A,0xC1,0xF2,0x97,0x17,0x49,0x27,0x37,0x6B,0x2F,0x88,
1306 0x7E,0x1C,0xA0,0xA1,0x89,0x92,0x27,0xD9,0x56,0x5A,0x71,0xC1,
1307 0x56,0x37,0x7E,0x3A,0x9D,0x05,0xE7,0xEE,0x5D,0x8F,0x82,0x17,
1308 0xBC,0xE9,0xC2,0x93,0x30,0x82,0xF9,0xF4,0xC9,0xAE,0x49,0xDB,
1309 0xD0,0x54,0xB4,0xD9,0x75,0x4D,0xFA,0x06,0xB8,0xD6,0x38,0x41,
1310 0xB7,0x1F,0x77,0xF3,
1311 };
1312 static unsigned char dh2048_g[]={
1313 0x02,
1314 };
1315
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001316 DH *dh = DH_new();
1317 if (dh) {
Remi Gacogned3a341a2015-05-29 16:26:17 +02001318 dh->p = BN_bin2bn(dh2048_p, sizeof dh2048_p, NULL);
1319 dh->g = BN_bin2bn(dh2048_g, sizeof dh2048_g, NULL);
1320
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001321 if (!dh->p || !dh->g) {
1322 DH_free(dh);
1323 dh = NULL;
1324 }
1325 }
1326 return dh;
1327}
1328
1329static DH *ssl_get_dh_4096(void)
1330{
Remi Gacogned3a341a2015-05-29 16:26:17 +02001331 static unsigned char dh4096_p[]={
1332 0xDE,0x16,0x94,0xCD,0x99,0x58,0x07,0xF1,0xF7,0x32,0x96,0x11,
1333 0x04,0x82,0xD4,0x84,0x72,0x80,0x99,0x06,0xCA,0xF0,0xA3,0x68,
1334 0x07,0xCE,0x64,0x50,0xE7,0x74,0x45,0x20,0x80,0x5E,0x4D,0xAD,
1335 0xA5,0xB6,0xED,0xFA,0x80,0x6C,0x3B,0x35,0xC4,0x9A,0x14,0x6B,
1336 0x32,0xBB,0xFD,0x1F,0x17,0x8E,0xB7,0x1F,0xD6,0xFA,0x3F,0x7B,
1337 0xEE,0x16,0xA5,0x62,0x33,0x0D,0xED,0xBC,0x4E,0x58,0xE5,0x47,
1338 0x4D,0xE9,0xAB,0x8E,0x38,0xD3,0x6E,0x90,0x57,0xE3,0x22,0x15,
1339 0x33,0xBD,0xF6,0x43,0x45,0xB5,0x10,0x0A,0xBE,0x2C,0xB4,0x35,
1340 0xB8,0x53,0x8D,0xAD,0xFB,0xA7,0x1F,0x85,0x58,0x41,0x7A,0x79,
1341 0x20,0x68,0xB3,0xE1,0x3D,0x08,0x76,0xBF,0x86,0x0D,0x49,0xE3,
1342 0x82,0x71,0x8C,0xB4,0x8D,0x81,0x84,0xD4,0xE7,0xBE,0x91,0xDC,
1343 0x26,0x39,0x48,0x0F,0x35,0xC4,0xCA,0x65,0xE3,0x40,0x93,0x52,
1344 0x76,0x58,0x7D,0xDD,0x51,0x75,0xDC,0x69,0x61,0xBF,0x47,0x2C,
1345 0x16,0x68,0x2D,0xC9,0x29,0xD3,0xE6,0xC0,0x99,0x48,0xA0,0x9A,
1346 0xC8,0x78,0xC0,0x6D,0x81,0x67,0x12,0x61,0x3F,0x71,0xBA,0x41,
1347 0x1F,0x6C,0x89,0x44,0x03,0xBA,0x3B,0x39,0x60,0xAA,0x28,0x55,
1348 0x59,0xAE,0xB8,0xFA,0xCB,0x6F,0xA5,0x1A,0xF7,0x2B,0xDD,0x52,
1349 0x8A,0x8B,0xE2,0x71,0xA6,0x5E,0x7E,0xD8,0x2E,0x18,0xE0,0x66,
1350 0xDF,0xDD,0x22,0x21,0x99,0x52,0x73,0xA6,0x33,0x20,0x65,0x0E,
1351 0x53,0xE7,0x6B,0x9B,0xC5,0xA3,0x2F,0x97,0x65,0x76,0xD3,0x47,
1352 0x23,0x77,0x12,0xB6,0x11,0x7B,0x24,0xED,0xF1,0xEF,0xC0,0xE2,
1353 0xA3,0x7E,0x67,0x05,0x3E,0x96,0x4D,0x45,0xC2,0x18,0xD1,0x73,
1354 0x9E,0x07,0xF3,0x81,0x6E,0x52,0x63,0xF6,0x20,0x76,0xB9,0x13,
1355 0xD2,0x65,0x30,0x18,0x16,0x09,0x16,0x9E,0x8F,0xF1,0xD2,0x10,
1356 0x5A,0xD3,0xD4,0xAF,0x16,0x61,0xDA,0x55,0x2E,0x18,0x5E,0x14,
1357 0x08,0x54,0x2E,0x2A,0x25,0xA2,0x1A,0x9B,0x8B,0x32,0xA9,0xFD,
1358 0xC2,0x48,0x96,0xE1,0x80,0xCA,0xE9,0x22,0x17,0xBB,0xCE,0x3E,
1359 0x9E,0xED,0xC7,0xF1,0x1F,0xEC,0x17,0x21,0xDC,0x7B,0x82,0x48,
1360 0x8E,0xBB,0x4B,0x9D,0x5B,0x04,0x04,0xDA,0xDB,0x39,0xDF,0x01,
1361 0x40,0xC3,0xAA,0x26,0x23,0x89,0x75,0xC6,0x0B,0xD0,0xA2,0x60,
1362 0x6A,0xF1,0xCC,0x65,0x18,0x98,0x1B,0x52,0xD2,0x74,0x61,0xCC,
1363 0xBD,0x60,0xAE,0xA3,0xA0,0x66,0x6A,0x16,0x34,0x92,0x3F,0x41,
1364 0x40,0x31,0x29,0xC0,0x2C,0x63,0xB2,0x07,0x8D,0xEB,0x94,0xB8,
1365 0xE8,0x47,0x92,0x52,0x93,0x6A,0x1B,0x7E,0x1A,0x61,0xB3,0x1B,
1366 0xF0,0xD6,0x72,0x9B,0xF1,0xB0,0xAF,0xBF,0x3E,0x65,0xEF,0x23,
1367 0x1D,0x6F,0xFF,0x70,0xCD,0x8A,0x4C,0x8A,0xA0,0x72,0x9D,0xBE,
1368 0xD4,0xBB,0x24,0x47,0x4A,0x68,0xB5,0xF5,0xC6,0xD5,0x7A,0xCD,
1369 0xCA,0x06,0x41,0x07,0xAD,0xC2,0x1E,0xE6,0x54,0xA7,0xAD,0x03,
1370 0xD9,0x12,0xC1,0x9C,0x13,0xB1,0xC9,0x0A,0x43,0x8E,0x1E,0x08,
1371 0xCE,0x50,0x82,0x73,0x5F,0xA7,0x55,0x1D,0xD9,0x59,0xAC,0xB5,
1372 0xEA,0x02,0x7F,0x6C,0x5B,0x74,0x96,0x98,0x67,0x24,0xA3,0x0F,
1373 0x15,0xFC,0xA9,0x7D,0x3E,0x67,0xD1,0x70,0xF8,0x97,0xF3,0x67,
1374 0xC5,0x8C,0x88,0x44,0x08,0x02,0xC7,0x2B,
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001375 };
Remi Gacogned3a341a2015-05-29 16:26:17 +02001376 static unsigned char dh4096_g[]={
1377 0x02,
1378 };
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001379
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001380 DH *dh = DH_new();
1381 if (dh) {
Remi Gacogned3a341a2015-05-29 16:26:17 +02001382 dh->p = BN_bin2bn(dh4096_p, sizeof dh4096_p, NULL);
1383 dh->g = BN_bin2bn(dh4096_g, sizeof dh4096_g, NULL);
1384
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001385 if (!dh->p || !dh->g) {
1386 DH_free(dh);
1387 dh = NULL;
1388 }
1389 }
1390 return dh;
1391}
1392
1393/* Returns Diffie-Hellman parameters matching the private key length
1394 but not exceeding global.tune.ssl_default_dh_param */
1395static DH *ssl_get_tmp_dh(SSL *ssl, int export, int keylen)
1396{
1397 DH *dh = NULL;
1398 EVP_PKEY *pkey = SSL_get_privatekey(ssl);
1399 int type = pkey ? EVP_PKEY_type(pkey->type) : EVP_PKEY_NONE;
1400
1401 /* The keylen supplied by OpenSSL can only be 512 or 1024.
1402 See ssl3_send_server_key_exchange() in ssl/s3_srvr.c
1403 */
1404 if (type == EVP_PKEY_RSA || type == EVP_PKEY_DSA) {
1405 keylen = EVP_PKEY_bits(pkey);
1406 }
1407
1408 if (keylen > global.tune.ssl_default_dh_param) {
1409 keylen = global.tune.ssl_default_dh_param;
1410 }
1411
Remi Gacogned3a341a2015-05-29 16:26:17 +02001412 if (keylen >= 4096) {
Remi Gacogne8de54152014-07-15 11:36:40 +02001413 dh = local_dh_4096;
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001414 }
1415 else if (keylen >= 2048) {
Remi Gacogne8de54152014-07-15 11:36:40 +02001416 dh = local_dh_2048;
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001417 }
1418 else {
Remi Gacogne8de54152014-07-15 11:36:40 +02001419 dh = local_dh_1024;
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001420 }
1421
1422 return dh;
1423}
1424
Remi Gacogne47783ef2015-05-29 15:53:22 +02001425static DH * ssl_sock_get_dh_from_file(const char *filename)
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001426{
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001427 DH *dh = NULL;
Remi Gacogne47783ef2015-05-29 15:53:22 +02001428 BIO *in = BIO_new(BIO_s_file());
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001429
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001430 if (in == NULL)
1431 goto end;
1432
Remi Gacogne47783ef2015-05-29 15:53:22 +02001433 if (BIO_read_filename(in, filename) <= 0)
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001434 goto end;
1435
Remi Gacogne47783ef2015-05-29 15:53:22 +02001436 dh = PEM_read_bio_DHparams(in, NULL, NULL, NULL);
1437
1438end:
1439 if (in)
1440 BIO_free(in);
1441
1442 return dh;
1443}
1444
1445int ssl_sock_load_global_dh_param_from_file(const char *filename)
1446{
1447 global_dh = ssl_sock_get_dh_from_file(filename);
1448
1449 if (global_dh) {
1450 return 0;
1451 }
1452
1453 return -1;
1454}
1455
1456/* Loads Diffie-Hellman parameter from a file. Returns 1 if loaded, else -1
1457 if an error occured, and 0 if parameter not found. */
1458int ssl_sock_load_dh_params(SSL_CTX *ctx, const char *file)
1459{
1460 int ret = -1;
1461 DH *dh = ssl_sock_get_dh_from_file(file);
1462
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001463 if (dh) {
1464 ret = 1;
1465 SSL_CTX_set_tmp_dh(ctx, dh);
Remi Gacogne4f902b82015-05-28 16:23:00 +02001466
1467 if (ssl_dh_ptr_index >= 0) {
1468 /* store a pointer to the DH params to avoid complaining about
1469 ssl-default-dh-param not being set for this SSL_CTX */
1470 SSL_CTX_set_ex_data(ctx, ssl_dh_ptr_index, dh);
1471 }
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001472 }
Remi Gacogne47783ef2015-05-29 15:53:22 +02001473 else if (global_dh) {
1474 SSL_CTX_set_tmp_dh(ctx, global_dh);
1475 ret = 0; /* DH params not found */
1476 }
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001477 else {
Emeric Brun41fdb3c2013-04-26 11:05:44 +02001478 /* Clear openssl global errors stack */
1479 ERR_clear_error();
1480
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001481 if (global.tune.ssl_default_dh_param <= 1024) {
1482 /* we are limited to DH parameter of 1024 bits anyway */
Remi Gacogne8de54152014-07-15 11:36:40 +02001483 local_dh_1024 = ssl_get_dh_1024();
1484 if (local_dh_1024 == NULL)
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001485 goto end;
Willy Tarreau6e774b42014-04-25 21:35:23 +02001486
Remi Gacogne8de54152014-07-15 11:36:40 +02001487 SSL_CTX_set_tmp_dh(ctx, local_dh_1024);
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001488 }
1489 else {
1490 SSL_CTX_set_tmp_dh_callback(ctx, ssl_get_tmp_dh);
1491 }
Willy Tarreau6e774b42014-04-25 21:35:23 +02001492
Emeric Brun41fdb3c2013-04-26 11:05:44 +02001493 ret = 0; /* DH params not found */
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001494 }
Emeric Brun644cde02012-12-14 11:21:13 +01001495
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001496end:
1497 if (dh)
1498 DH_free(dh);
1499
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001500 return ret;
1501}
1502#endif
1503
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001504static int ssl_sock_add_cert_sni(SSL_CTX *ctx, struct bind_conf *s, char *name, int order)
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001505{
1506 struct sni_ctx *sc;
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001507 int wild = 0, neg = 0;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001508
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001509 if (*name == '!') {
1510 neg = 1;
1511 name++;
1512 }
1513 if (*name == '*') {
1514 wild = 1;
1515 name++;
1516 }
1517 /* !* filter is a nop */
1518 if (neg && wild)
1519 return order;
1520 if (*name) {
1521 int j, len;
1522 len = strlen(name);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001523 sc = malloc(sizeof(struct sni_ctx) + len + 1);
1524 for (j = 0; j < len; j++)
1525 sc->name.key[j] = tolower(name[j]);
1526 sc->name.key[len] = 0;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001527 sc->ctx = ctx;
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001528 sc->order = order++;
1529 sc->neg = neg;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001530 if (wild)
1531 ebst_insert(&s->sni_w_ctx, &sc->name);
1532 else
1533 ebst_insert(&s->sni_ctx, &sc->name);
1534 }
1535 return order;
1536}
1537
Emeric Brunfc0421f2012-09-07 17:30:07 +02001538/* Loads a certificate key and CA chain from a file. Returns 0 on error, -1 if
1539 * an early error happens and the caller must call SSL_CTX_free() by itelf.
1540 */
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001541static 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 +02001542{
1543 BIO *in;
1544 X509 *x = NULL, *ca;
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001545 int i, err;
Emeric Brunfc0421f2012-09-07 17:30:07 +02001546 int ret = -1;
1547 int order = 0;
1548 X509_NAME *xname;
1549 char *str;
Emeric Brunfc0421f2012-09-07 17:30:07 +02001550#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
1551 STACK_OF(GENERAL_NAME) *names;
1552#endif
1553
1554 in = BIO_new(BIO_s_file());
1555 if (in == NULL)
1556 goto end;
1557
1558 if (BIO_read_filename(in, file) <= 0)
1559 goto end;
1560
1561 x = PEM_read_bio_X509_AUX(in, NULL, ctx->default_passwd_callback, ctx->default_passwd_callback_userdata);
1562 if (x == NULL)
1563 goto end;
1564
Emeric Brun50bcecc2013-04-22 13:05:23 +02001565 if (fcount) {
1566 while (fcount--)
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001567 order = ssl_sock_add_cert_sni(ctx, s, sni_filter[fcount], order);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001568 }
1569 else {
Emeric Brunfc0421f2012-09-07 17:30:07 +02001570#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001571 names = X509_get_ext_d2i(x, NID_subject_alt_name, NULL, NULL);
1572 if (names) {
1573 for (i = 0; i < sk_GENERAL_NAME_num(names); i++) {
1574 GENERAL_NAME *name = sk_GENERAL_NAME_value(names, i);
1575 if (name->type == GEN_DNS) {
1576 if (ASN1_STRING_to_UTF8((unsigned char **)&str, name->d.dNSName) >= 0) {
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001577 order = ssl_sock_add_cert_sni(ctx, s, str, order);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001578 OPENSSL_free(str);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001579 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02001580 }
1581 }
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001582 sk_GENERAL_NAME_pop_free(names, GENERAL_NAME_free);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001583 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02001584#endif /* SSL_CTRL_SET_TLSEXT_HOSTNAME */
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001585 xname = X509_get_subject_name(x);
1586 i = -1;
1587 while ((i = X509_NAME_get_index_by_NID(xname, NID_commonName, i)) != -1) {
1588 X509_NAME_ENTRY *entry = X509_NAME_get_entry(xname, i);
1589 if (ASN1_STRING_to_UTF8((unsigned char **)&str, entry->value) >= 0) {
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001590 order = ssl_sock_add_cert_sni(ctx, s, str, order);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001591 OPENSSL_free(str);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001592 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02001593 }
1594 }
1595
1596 ret = 0; /* the caller must not free the SSL_CTX argument anymore */
1597 if (!SSL_CTX_use_certificate(ctx, x))
1598 goto end;
1599
1600 if (ctx->extra_certs != NULL) {
1601 sk_X509_pop_free(ctx->extra_certs, X509_free);
1602 ctx->extra_certs = NULL;
1603 }
1604
1605 while ((ca = PEM_read_bio_X509(in, NULL, ctx->default_passwd_callback, ctx->default_passwd_callback_userdata))) {
1606 if (!SSL_CTX_add_extra_chain_cert(ctx, ca)) {
1607 X509_free(ca);
1608 goto end;
1609 }
1610 }
1611
1612 err = ERR_get_error();
1613 if (!err || (ERR_GET_LIB(err) == ERR_LIB_PEM && ERR_GET_REASON(err) == PEM_R_NO_START_LINE)) {
1614 /* we successfully reached the last cert in the file */
1615 ret = 1;
1616 }
1617 ERR_clear_error();
1618
1619end:
1620 if (x)
1621 X509_free(x);
1622
1623 if (in)
1624 BIO_free(in);
1625
1626 return ret;
1627}
1628
Emeric Brun50bcecc2013-04-22 13:05:23 +02001629static 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 +02001630{
1631 int ret;
1632 SSL_CTX *ctx;
1633
1634 ctx = SSL_CTX_new(SSLv23_server_method());
1635 if (!ctx) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02001636 memprintf(err, "%sunable to allocate SSL context for cert '%s'.\n",
1637 err && *err ? *err : "", path);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001638 return 1;
1639 }
1640
1641 if (SSL_CTX_use_PrivateKey_file(ctx, path, SSL_FILETYPE_PEM) <= 0) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02001642 memprintf(err, "%sunable to load SSL private key from PEM file '%s'.\n",
1643 err && *err ? *err : "", path);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001644 SSL_CTX_free(ctx);
1645 return 1;
1646 }
1647
Emeric Brun50bcecc2013-04-22 13:05:23 +02001648 ret = ssl_sock_load_cert_chain_file(ctx, path, bind_conf, sni_filter, fcount);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001649 if (ret <= 0) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02001650 memprintf(err, "%sunable to load SSL certificate from PEM file '%s'.\n",
1651 err && *err ? *err : "", path);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001652 if (ret < 0) /* serious error, must do that ourselves */
1653 SSL_CTX_free(ctx);
1654 return 1;
1655 }
Emeric Brun61694ab2012-10-26 13:35:33 +02001656
1657 if (SSL_CTX_check_private_key(ctx) <= 0) {
1658 memprintf(err, "%sinconsistencies between private key and certificate loaded from PEM file '%s'.\n",
1659 err && *err ? *err : "", path);
1660 return 1;
1661 }
1662
Emeric Brunfc0421f2012-09-07 17:30:07 +02001663 /* we must not free the SSL_CTX anymore below, since it's already in
1664 * the tree, so it will be discovered and cleaned in time.
1665 */
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001666#ifndef OPENSSL_NO_DH
Remi Gacogne4f902b82015-05-28 16:23:00 +02001667 /* store a NULL pointer to indicate we have not yet loaded
1668 a custom DH param file */
1669 if (ssl_dh_ptr_index >= 0) {
1670 SSL_CTX_set_ex_data(ctx, ssl_dh_ptr_index, NULL);
1671 }
1672
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001673 ret = ssl_sock_load_dh_params(ctx, path);
1674 if (ret < 0) {
1675 if (err)
1676 memprintf(err, "%sunable to load DH parameters from file '%s'.\n",
1677 *err ? *err : "", path);
1678 return 1;
1679 }
1680#endif
1681
Lukas Tribuse4e30f72014-12-09 16:32:51 +01001682#if (defined SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB && !defined OPENSSL_NO_OCSP)
Emeric Brun4147b2e2014-06-16 18:36:30 +02001683 ret = ssl_sock_load_ocsp(ctx, path);
1684 if (ret < 0) {
1685 if (err)
1686 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",
1687 *err ? *err : "", path);
1688 return 1;
1689 }
1690#endif
1691
Janusz Dziemidowicz2c701b52015-03-07 23:03:59 +01001692#if (OPENSSL_VERSION_NUMBER >= 0x1000200fL && !defined OPENSSL_NO_TLSEXT && !defined OPENSSL_IS_BORINGSSL)
1693 if (sctl_ex_index >= 0) {
1694 ret = ssl_sock_load_sctl(ctx, path);
1695 if (ret < 0) {
1696 if (err)
1697 memprintf(err, "%s '%s.sctl' is present but cannot be read or parsed'.\n",
1698 *err ? *err : "", path);
1699 return 1;
1700 }
1701 }
1702#endif
1703
Emeric Brunfc0421f2012-09-07 17:30:07 +02001704#ifndef SSL_CTRL_SET_TLSEXT_HOSTNAME
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001705 if (bind_conf->default_ctx) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02001706 memprintf(err, "%sthis version of openssl cannot load multiple SSL certificates.\n",
1707 err && *err ? *err : "");
Emeric Brunfc0421f2012-09-07 17:30:07 +02001708 return 1;
1709 }
1710#endif
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001711 if (!bind_conf->default_ctx)
1712 bind_conf->default_ctx = ctx;
Emeric Brunfc0421f2012-09-07 17:30:07 +02001713
1714 return 0;
1715}
1716
Willy Tarreau79eeafa2012-09-14 07:53:05 +02001717int ssl_sock_load_cert(char *path, struct bind_conf *bind_conf, struct proxy *curproxy, char **err)
Emeric Brunfc0421f2012-09-07 17:30:07 +02001718{
Cyril Bonté3180f7b2015-01-25 00:16:08 +01001719 struct dirent **de_list;
1720 int i, n;
Emeric Brunfc0421f2012-09-07 17:30:07 +02001721 DIR *dir;
1722 struct stat buf;
Willy Tarreauee2663b2012-12-06 11:36:59 +01001723 char *end;
1724 char fp[MAXPATHLEN+1];
Emeric Brunfc0421f2012-09-07 17:30:07 +02001725 int cfgerr = 0;
1726
1727 if (!(dir = opendir(path)))
Emeric Brun50bcecc2013-04-22 13:05:23 +02001728 return ssl_sock_load_cert_file(path, bind_conf, curproxy, NULL, 0, err);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001729
1730 /* strip trailing slashes, including first one */
1731 for (end = path + strlen(path) - 1; end >= path && *end == '/'; end--)
1732 *end = 0;
1733
Cyril Bonté3180f7b2015-01-25 00:16:08 +01001734 n = scandir(path, &de_list, 0, alphasort);
1735 if (n < 0) {
1736 memprintf(err, "%sunable to scan directory '%s' : %s.\n",
1737 err && *err ? *err : "", path, strerror(errno));
1738 cfgerr++;
1739 }
1740 else {
1741 for (i = 0; i < n; i++) {
1742 struct dirent *de = de_list[i];
Emeric Brun2aab7222014-06-18 18:15:09 +02001743
Cyril Bonté3180f7b2015-01-25 00:16:08 +01001744 end = strrchr(de->d_name, '.');
Janusz Dziemidowicz2c701b52015-03-07 23:03:59 +01001745 if (end && (!strcmp(end, ".issuer") || !strcmp(end, ".ocsp") || !strcmp(end, ".sctl")))
Cyril Bonté3180f7b2015-01-25 00:16:08 +01001746 goto ignore_entry;
1747
1748 snprintf(fp, sizeof(fp), "%s/%s", path, de->d_name);
1749 if (stat(fp, &buf) != 0) {
1750 memprintf(err, "%sunable to stat SSL certificate from file '%s' : %s.\n",
1751 err && *err ? *err : "", fp, strerror(errno));
1752 cfgerr++;
1753 goto ignore_entry;
1754 }
1755 if (!S_ISREG(buf.st_mode))
1756 goto ignore_entry;
1757 cfgerr += ssl_sock_load_cert_file(fp, bind_conf, curproxy, NULL, 0, err);
1758 ignore_entry:
1759 free(de);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001760 }
Cyril Bonté3180f7b2015-01-25 00:16:08 +01001761 free(de_list);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001762 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02001763 closedir(dir);
1764 return cfgerr;
1765}
1766
Thierry Fournier383085f2013-01-24 14:15:43 +01001767/* Make sure openssl opens /dev/urandom before the chroot. The work is only
1768 * done once. Zero is returned if the operation fails. No error is returned
1769 * if the random is said as not implemented, because we expect that openssl
1770 * will use another method once needed.
1771 */
1772static int ssl_initialize_random()
1773{
1774 unsigned char random;
1775 static int random_initialized = 0;
1776
1777 if (!random_initialized && RAND_bytes(&random, 1) != 0)
1778 random_initialized = 1;
1779
1780 return random_initialized;
1781}
1782
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001783int ssl_sock_load_cert_list_file(char *file, struct bind_conf *bind_conf, struct proxy *curproxy, char **err)
1784{
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001785 char thisline[LINESIZE];
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001786 FILE *f;
1787 int linenum = 0;
1788 int cfgerr = 0;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001789
Willy Tarreauad1731d2013-04-02 17:35:58 +02001790 if ((f = fopen(file, "r")) == NULL) {
1791 memprintf(err, "cannot open file '%s' : %s", file, strerror(errno));
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001792 return 1;
Willy Tarreauad1731d2013-04-02 17:35:58 +02001793 }
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001794
1795 while (fgets(thisline, sizeof(thisline), f) != NULL) {
1796 int arg;
Emeric Brun50bcecc2013-04-22 13:05:23 +02001797 int newarg;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001798 char *end;
1799 char *args[MAX_LINE_ARGS + 1];
1800 char *line = thisline;
1801
1802 linenum++;
1803 end = line + strlen(line);
1804 if (end-line == sizeof(thisline)-1 && *(end-1) != '\n') {
1805 /* Check if we reached the limit and the last char is not \n.
1806 * Watch out for the last line without the terminating '\n'!
1807 */
Willy Tarreauad1731d2013-04-02 17:35:58 +02001808 memprintf(err, "line %d too long in file '%s', limit is %d characters",
1809 linenum, file, (int)sizeof(thisline)-1);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001810 cfgerr = 1;
Willy Tarreauad1731d2013-04-02 17:35:58 +02001811 break;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001812 }
1813
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001814 arg = 0;
Emeric Brun50bcecc2013-04-22 13:05:23 +02001815 newarg = 1;
1816 while (*line) {
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001817 if (*line == '#' || *line == '\n' || *line == '\r') {
1818 /* end of string, end of loop */
1819 *line = 0;
1820 break;
1821 }
1822 else if (isspace(*line)) {
Emeric Brun50bcecc2013-04-22 13:05:23 +02001823 newarg = 1;
1824 *line = 0;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001825 }
Emeric Brun50bcecc2013-04-22 13:05:23 +02001826 else if (newarg) {
1827 if (arg == MAX_LINE_ARGS) {
1828 memprintf(err, "too many args on line %d in file '%s'.",
1829 linenum, file);
1830 cfgerr = 1;
1831 break;
1832 }
1833 newarg = 0;
1834 args[arg++] = line;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001835 }
Emeric Brun50bcecc2013-04-22 13:05:23 +02001836 line++;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001837 }
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001838 if (cfgerr)
1839 break;
Willy Tarreauad1731d2013-04-02 17:35:58 +02001840
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001841 /* empty line */
Emeric Brun50bcecc2013-04-22 13:05:23 +02001842 if (!arg)
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001843 continue;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001844
Emeric Brun50bcecc2013-04-22 13:05:23 +02001845 cfgerr = ssl_sock_load_cert_file(args[0], bind_conf, curproxy, &args[1], arg-1, err);
Willy Tarreauad1731d2013-04-02 17:35:58 +02001846 if (cfgerr) {
1847 memprintf(err, "error processing line %d in file '%s' : %s", linenum, file, *err);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001848 break;
Willy Tarreauad1731d2013-04-02 17:35:58 +02001849 }
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001850 }
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001851 fclose(f);
1852 return cfgerr;
1853}
1854
Emeric Brunfc0421f2012-09-07 17:30:07 +02001855#ifndef SSL_OP_CIPHER_SERVER_PREFERENCE /* needs OpenSSL >= 0.9.7 */
1856#define SSL_OP_CIPHER_SERVER_PREFERENCE 0
1857#endif
1858
1859#ifndef SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION /* needs OpenSSL >= 0.9.7 */
1860#define SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION 0
Willy Tarreau7d588ee2012-11-26 18:47:31 +01001861#define SSL_renegotiate_pending(arg) 0
Emeric Brunfc0421f2012-09-07 17:30:07 +02001862#endif
Emeric Brun2b58d042012-09-20 17:10:03 +02001863#ifndef SSL_OP_SINGLE_ECDH_USE /* needs OpenSSL >= 0.9.8 */
1864#define SSL_OP_SINGLE_ECDH_USE 0
1865#endif
Emeric Brun2d0c4822012-10-02 13:45:20 +02001866#ifndef SSL_OP_NO_TICKET /* needs OpenSSL >= 0.9.8 */
1867#define SSL_OP_NO_TICKET 0
1868#endif
Emeric Brunfc0421f2012-09-07 17:30:07 +02001869#ifndef SSL_OP_NO_COMPRESSION /* needs OpenSSL >= 0.9.9 */
1870#define SSL_OP_NO_COMPRESSION 0
1871#endif
Emeric Brunc0ff4922012-09-28 19:37:02 +02001872#ifndef SSL_OP_NO_TLSv1_1 /* needs OpenSSL >= 1.0.1 */
1873#define SSL_OP_NO_TLSv1_1 0
1874#endif
1875#ifndef SSL_OP_NO_TLSv1_2 /* needs OpenSSL >= 1.0.1 */
1876#define SSL_OP_NO_TLSv1_2 0
1877#endif
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001878#ifndef SSL_OP_SINGLE_DH_USE /* needs OpenSSL >= 0.9.6 */
1879#define SSL_OP_SINGLE_DH_USE 0
1880#endif
Emeric Brun2b58d042012-09-20 17:10:03 +02001881#ifndef SSL_OP_SINGLE_ECDH_USE /* needs OpenSSL >= 1.0.0 */
1882#define SSL_OP_SINGLE_ECDH_USE 0
1883#endif
Emeric Brunfc0421f2012-09-07 17:30:07 +02001884#ifndef SSL_MODE_RELEASE_BUFFERS /* needs OpenSSL >= 1.0.0 */
1885#define SSL_MODE_RELEASE_BUFFERS 0
1886#endif
Willy Tarreau396a1862014-11-13 14:06:52 +01001887#ifndef SSL_MODE_SMALL_BUFFERS /* needs small_records.patch */
1888#define SSL_MODE_SMALL_BUFFERS 0
1889#endif
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001890
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001891int ssl_sock_prepare_ctx(struct bind_conf *bind_conf, SSL_CTX *ctx, struct proxy *curproxy)
Emeric Brunfc0421f2012-09-07 17:30:07 +02001892{
1893 int cfgerr = 0;
Emeric Brun850efd52014-01-29 12:24:34 +01001894 int verify = SSL_VERIFY_NONE;
Remi Gacogneaf5c3da2014-05-19 10:29:58 +02001895 long ssloptions =
Emeric Brunfc0421f2012-09-07 17:30:07 +02001896 SSL_OP_ALL | /* all known workarounds for bugs */
1897 SSL_OP_NO_SSLv2 |
1898 SSL_OP_NO_COMPRESSION |
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001899 SSL_OP_SINGLE_DH_USE |
Emeric Brun2b58d042012-09-20 17:10:03 +02001900 SSL_OP_SINGLE_ECDH_USE |
Emeric Brun3c4bc6e2012-10-04 18:44:19 +02001901 SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION |
1902 SSL_OP_CIPHER_SERVER_PREFERENCE;
Remi Gacogneaf5c3da2014-05-19 10:29:58 +02001903 long sslmode =
Emeric Brunfc0421f2012-09-07 17:30:07 +02001904 SSL_MODE_ENABLE_PARTIAL_WRITE |
1905 SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER |
Willy Tarreau396a1862014-11-13 14:06:52 +01001906 SSL_MODE_RELEASE_BUFFERS |
1907 SSL_MODE_SMALL_BUFFERS;
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001908 STACK_OF(SSL_CIPHER) * ciphers = NULL;
Willy Tarreaua616ba62014-10-26 06:49:19 +01001909 SSL_CIPHER * cipher = NULL;
Remi Gacognec1eab8c2014-06-12 18:20:11 +02001910 char cipher_description[128];
1911 /* The description of ciphers using an Ephemeral Diffie Hellman key exchange
1912 contains " Kx=DH " or " Kx=DH(". Beware of " Kx=DH/",
1913 which is not ephemeral DH. */
1914 const char dhe_description[] = " Kx=DH ";
1915 const char dhe_export_description[] = " Kx=DH(";
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001916 int idx = 0;
1917 int dhe_found = 0;
Remi Gacogne23d5d372014-10-10 17:04:26 +02001918 SSL *ssl = NULL;
Emeric Brunfc0421f2012-09-07 17:30:07 +02001919
Thierry Fournier383085f2013-01-24 14:15:43 +01001920 /* Make sure openssl opens /dev/urandom before the chroot */
1921 if (!ssl_initialize_random()) {
1922 Alert("OpenSSL random data generator initialization failed.\n");
1923 cfgerr++;
1924 }
1925
Emeric Brun89675492012-10-05 13:48:26 +02001926 if (bind_conf->ssl_options & BC_SSL_O_NO_SSLV3)
Emeric Brunfc0421f2012-09-07 17:30:07 +02001927 ssloptions |= SSL_OP_NO_SSLv3;
Emeric Brun89675492012-10-05 13:48:26 +02001928 if (bind_conf->ssl_options & BC_SSL_O_NO_TLSV10)
Emeric Brunfc0421f2012-09-07 17:30:07 +02001929 ssloptions |= SSL_OP_NO_TLSv1;
Emeric Brun89675492012-10-05 13:48:26 +02001930 if (bind_conf->ssl_options & BC_SSL_O_NO_TLSV11)
Emeric Brunc0ff4922012-09-28 19:37:02 +02001931 ssloptions |= SSL_OP_NO_TLSv1_1;
Emeric Brun89675492012-10-05 13:48:26 +02001932 if (bind_conf->ssl_options & BC_SSL_O_NO_TLSV12)
Emeric Brunc0ff4922012-09-28 19:37:02 +02001933 ssloptions |= SSL_OP_NO_TLSv1_2;
Emeric Brun89675492012-10-05 13:48:26 +02001934 if (bind_conf->ssl_options & BC_SSL_O_NO_TLS_TICKETS)
Emeric Brun2d0c4822012-10-02 13:45:20 +02001935 ssloptions |= SSL_OP_NO_TICKET;
Emeric Brun2cb7ae52012-10-05 14:14:21 +02001936 if (bind_conf->ssl_options & BC_SSL_O_USE_SSLV3)
1937 SSL_CTX_set_ssl_version(ctx, SSLv3_server_method());
1938 if (bind_conf->ssl_options & BC_SSL_O_USE_TLSV10)
1939 SSL_CTX_set_ssl_version(ctx, TLSv1_server_method());
1940#if SSL_OP_NO_TLSv1_1
1941 if (bind_conf->ssl_options & BC_SSL_O_USE_TLSV11)
1942 SSL_CTX_set_ssl_version(ctx, TLSv1_1_server_method());
1943#endif
1944#if SSL_OP_NO_TLSv1_2
1945 if (bind_conf->ssl_options & BC_SSL_O_USE_TLSV12)
1946 SSL_CTX_set_ssl_version(ctx, TLSv1_2_server_method());
1947#endif
Emeric Brunfc0421f2012-09-07 17:30:07 +02001948
1949 SSL_CTX_set_options(ctx, ssloptions);
1950 SSL_CTX_set_mode(ctx, sslmode);
Emeric Brun850efd52014-01-29 12:24:34 +01001951 switch (bind_conf->verify) {
1952 case SSL_SOCK_VERIFY_NONE:
1953 verify = SSL_VERIFY_NONE;
1954 break;
1955 case SSL_SOCK_VERIFY_OPTIONAL:
1956 verify = SSL_VERIFY_PEER;
1957 break;
1958 case SSL_SOCK_VERIFY_REQUIRED:
1959 verify = SSL_VERIFY_PEER|SSL_VERIFY_FAIL_IF_NO_PEER_CERT;
1960 break;
1961 }
1962 SSL_CTX_set_verify(ctx, verify, ssl_sock_bind_verifycbk);
1963 if (verify & SSL_VERIFY_PEER) {
Emeric Brunfb510ea2012-10-05 12:00:26 +02001964 if (bind_conf->ca_file) {
Emeric Brund94b3fe2012-09-20 18:23:56 +02001965 /* load CAfile to verify */
Emeric Brunfb510ea2012-10-05 12:00:26 +02001966 if (!SSL_CTX_load_verify_locations(ctx, bind_conf->ca_file, NULL)) {
Emeric Brund94b3fe2012-09-20 18:23:56 +02001967 Alert("Proxy '%s': unable to load CA file '%s' for bind '%s' at [%s:%d].\n",
Emeric Brunfb510ea2012-10-05 12:00:26 +02001968 curproxy->id, bind_conf->ca_file, bind_conf->arg, bind_conf->file, bind_conf->line);
Emeric Brund94b3fe2012-09-20 18:23:56 +02001969 cfgerr++;
1970 }
1971 /* set CA names fo client cert request, function returns void */
Emeric Brunfb510ea2012-10-05 12:00:26 +02001972 SSL_CTX_set_client_CA_list(ctx, SSL_load_client_CA_file(bind_conf->ca_file));
Emeric Brund94b3fe2012-09-20 18:23:56 +02001973 }
Emeric Brun850efd52014-01-29 12:24:34 +01001974 else {
1975 Alert("Proxy '%s': verify is enabled but no CA file specified for bind '%s' at [%s:%d].\n",
1976 curproxy->id, bind_conf->arg, bind_conf->file, bind_conf->line);
1977 cfgerr++;
1978 }
Emeric Brun051cdab2012-10-02 19:25:50 +02001979#ifdef X509_V_FLAG_CRL_CHECK
Emeric Brunfb510ea2012-10-05 12:00:26 +02001980 if (bind_conf->crl_file) {
Emeric Brund94b3fe2012-09-20 18:23:56 +02001981 X509_STORE *store = SSL_CTX_get_cert_store(ctx);
1982
Emeric Brunfb510ea2012-10-05 12:00:26 +02001983 if (!store || !X509_STORE_load_locations(store, bind_conf->crl_file, NULL)) {
Emeric Brund94b3fe2012-09-20 18:23:56 +02001984 Alert("Proxy '%s': unable to configure CRL file '%s' for bind '%s' at [%s:%d].\n",
Alexander Rigbofc65af02015-04-07 14:02:16 +02001985 curproxy->id, bind_conf->crl_file, bind_conf->arg, bind_conf->file, bind_conf->line);
Emeric Brund94b3fe2012-09-20 18:23:56 +02001986 cfgerr++;
1987 }
Emeric Brun561e5742012-10-02 15:20:55 +02001988 else {
1989 X509_STORE_set_flags(store, X509_V_FLAG_CRL_CHECK|X509_V_FLAG_CRL_CHECK_ALL);
1990 }
Emeric Brund94b3fe2012-09-20 18:23:56 +02001991 }
Emeric Brun051cdab2012-10-02 19:25:50 +02001992#endif
Emeric Brun644cde02012-12-14 11:21:13 +01001993 ERR_clear_error();
Emeric Brund94b3fe2012-09-20 18:23:56 +02001994 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02001995
Nenad Merdanovic05552d42015-02-27 19:56:49 +01001996#if (defined SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB && TLS_TICKETS_NO > 0)
Nenad Merdanovic146defa2015-05-09 08:46:00 +02001997 if(bind_conf->keys_ref) {
Nenad Merdanovic05552d42015-02-27 19:56:49 +01001998 if (!SSL_CTX_set_tlsext_ticket_key_cb(ctx, ssl_tlsext_ticket_key_cb)) {
1999 Alert("Proxy '%s': unable to set callback for TLS ticket validation for bind '%s' at [%s:%d].\n",
2000 curproxy->id, bind_conf->arg, bind_conf->file, bind_conf->line);
2001 cfgerr++;
2002 }
2003 }
2004#endif
2005
Emeric Brun4f65bff2012-11-16 15:11:00 +01002006 if (global.tune.ssllifetime)
2007 SSL_CTX_set_timeout(ctx, global.tune.ssllifetime);
2008
Emeric Brunfc0421f2012-09-07 17:30:07 +02002009 shared_context_set_cache(ctx);
Willy Tarreau2a65ff02012-09-13 17:54:29 +02002010 if (bind_conf->ciphers &&
2011 !SSL_CTX_set_cipher_list(ctx, bind_conf->ciphers)) {
Emeric Brunfc0421f2012-09-07 17:30:07 +02002012 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 +02002013 curproxy->id, bind_conf->ciphers, bind_conf->arg, bind_conf->file, bind_conf->line);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002014 cfgerr++;
2015 }
2016
Remi Gacogne47783ef2015-05-29 15:53:22 +02002017 /* If tune.ssl.default-dh-param has not been set,
2018 neither has ssl-default-dh-file and no static DH
2019 params were in the certificate file. */
Remi Gacogne4f902b82015-05-28 16:23:00 +02002020 if (global.tune.ssl_default_dh_param == 0 &&
Remi Gacogne47783ef2015-05-29 15:53:22 +02002021 global_dh == NULL &&
Remi Gacogne4f902b82015-05-28 16:23:00 +02002022 (ssl_dh_ptr_index == -1 ||
2023 SSL_CTX_get_ex_data(ctx, ssl_dh_ptr_index) == NULL)) {
Lukas Tribus90132722014-08-18 00:56:33 +02002024
Remi Gacogne23d5d372014-10-10 17:04:26 +02002025 ssl = SSL_new(ctx);
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002026
Remi Gacogne23d5d372014-10-10 17:04:26 +02002027 if (ssl) {
2028 ciphers = SSL_get_ciphers(ssl);
2029
2030 if (ciphers) {
2031 for (idx = 0; idx < sk_SSL_CIPHER_num(ciphers); idx++) {
2032 cipher = sk_SSL_CIPHER_value(ciphers, idx);
2033 if (SSL_CIPHER_description(cipher, cipher_description, sizeof (cipher_description)) == cipher_description) {
2034 if (strstr(cipher_description, dhe_description) != NULL ||
2035 strstr(cipher_description, dhe_export_description) != NULL) {
2036 dhe_found = 1;
2037 break;
2038 }
Remi Gacognec1eab8c2014-06-12 18:20:11 +02002039 }
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002040 }
2041 }
Remi Gacogne23d5d372014-10-10 17:04:26 +02002042 SSL_free(ssl);
2043 ssl = NULL;
Lukas Tribus90132722014-08-18 00:56:33 +02002044 }
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002045
Lukas Tribus90132722014-08-18 00:56:33 +02002046 if (dhe_found) {
2047 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 +02002048 }
2049
2050 global.tune.ssl_default_dh_param = 1024;
2051 }
Remi Gacogne8de54152014-07-15 11:36:40 +02002052
2053#ifndef OPENSSL_NO_DH
2054 if (global.tune.ssl_default_dh_param >= 1024) {
2055 if (local_dh_1024 == NULL) {
2056 local_dh_1024 = ssl_get_dh_1024();
2057 }
2058 if (global.tune.ssl_default_dh_param >= 2048) {
2059 if (local_dh_2048 == NULL) {
2060 local_dh_2048 = ssl_get_dh_2048();
2061 }
2062 if (global.tune.ssl_default_dh_param >= 4096) {
2063 if (local_dh_4096 == NULL) {
2064 local_dh_4096 = ssl_get_dh_4096();
2065 }
Remi Gacogne8de54152014-07-15 11:36:40 +02002066 }
2067 }
2068 }
2069#endif /* OPENSSL_NO_DH */
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002070
Emeric Brunfc0421f2012-09-07 17:30:07 +02002071 SSL_CTX_set_info_callback(ctx, ssl_sock_infocbk);
Willy Tarreau5cbe4ef2014-05-08 22:45:11 +02002072#if OPENSSL_VERSION_NUMBER >= 0x00907000L
Emeric Brun29f037d2014-04-25 19:05:36 +02002073 SSL_CTX_set_msg_callback(ctx, ssl_sock_msgcbk);
Willy Tarreau5cbe4ef2014-05-08 22:45:11 +02002074#endif
Emeric Brun29f037d2014-04-25 19:05:36 +02002075
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02002076#ifdef OPENSSL_NPN_NEGOTIATED
2077 if (bind_conf->npn_str)
2078 SSL_CTX_set_next_protos_advertised_cb(ctx, ssl_sock_advertise_npn_protos, bind_conf);
2079#endif
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01002080#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Willy Tarreauab861d32013-04-02 02:30:41 +02002081 if (bind_conf->alpn_str)
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01002082 SSL_CTX_set_alpn_select_cb(ctx, ssl_sock_advertise_alpn_protos, bind_conf);
Willy Tarreauab861d32013-04-02 02:30:41 +02002083#endif
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02002084
Emeric Brunfc0421f2012-09-07 17:30:07 +02002085#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
2086 SSL_CTX_set_tlsext_servername_callback(ctx, ssl_sock_switchctx_cbk);
Willy Tarreau2a65ff02012-09-13 17:54:29 +02002087 SSL_CTX_set_tlsext_servername_arg(ctx, bind_conf);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002088#endif
Emeric Brun2b58d042012-09-20 17:10:03 +02002089#if defined(SSL_CTX_set_tmp_ecdh) && !defined(OPENSSL_NO_ECDH)
Emeric Brun6924ef82013-03-06 14:08:53 +01002090 {
Emeric Brun2b58d042012-09-20 17:10:03 +02002091 int i;
2092 EC_KEY *ecdh;
2093
Emeric Brun6924ef82013-03-06 14:08:53 +01002094 i = OBJ_sn2nid(bind_conf->ecdhe ? bind_conf->ecdhe : ECDHE_DEFAULT_CURVE);
Emeric Brun2b58d042012-09-20 17:10:03 +02002095 if (!i || ((ecdh = EC_KEY_new_by_curve_name(i)) == NULL)) {
2096 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 +01002097 curproxy->id, bind_conf->ecdhe ? bind_conf->ecdhe : ECDHE_DEFAULT_CURVE,
2098 bind_conf->arg, bind_conf->file, bind_conf->line);
Emeric Brun2b58d042012-09-20 17:10:03 +02002099 cfgerr++;
2100 }
2101 else {
2102 SSL_CTX_set_tmp_ecdh(ctx, ecdh);
2103 EC_KEY_free(ecdh);
2104 }
2105 }
2106#endif
2107
Emeric Brunfc0421f2012-09-07 17:30:07 +02002108 return cfgerr;
2109}
2110
Evan Broderbe554312013-06-27 00:05:25 -07002111static int ssl_sock_srv_hostcheck(const char *pattern, const char *hostname)
2112{
2113 const char *pattern_wildcard, *pattern_left_label_end, *hostname_left_label_end;
2114 size_t prefixlen, suffixlen;
2115
2116 /* Trivial case */
2117 if (strcmp(pattern, hostname) == 0)
2118 return 1;
2119
Evan Broderbe554312013-06-27 00:05:25 -07002120 /* The rest of this logic is based on RFC 6125, section 6.4.3
2121 * (http://tools.ietf.org/html/rfc6125#section-6.4.3) */
2122
Emeric Bruna848dae2013-10-08 11:27:28 +02002123 pattern_wildcard = NULL;
2124 pattern_left_label_end = pattern;
2125 while (*pattern_left_label_end != '.') {
2126 switch (*pattern_left_label_end) {
2127 case 0:
2128 /* End of label not found */
2129 return 0;
2130 case '*':
2131 /* If there is more than one wildcards */
2132 if (pattern_wildcard)
2133 return 0;
2134 pattern_wildcard = pattern_left_label_end;
2135 break;
2136 }
2137 pattern_left_label_end++;
2138 }
2139
2140 /* If it's not trivial and there is no wildcard, it can't
2141 * match */
2142 if (!pattern_wildcard)
Evan Broderbe554312013-06-27 00:05:25 -07002143 return 0;
2144
2145 /* Make sure all labels match except the leftmost */
2146 hostname_left_label_end = strchr(hostname, '.');
2147 if (!hostname_left_label_end
2148 || strcmp(pattern_left_label_end, hostname_left_label_end) != 0)
2149 return 0;
2150
2151 /* Make sure the leftmost label of the hostname is long enough
2152 * that the wildcard can match */
Emeric Brun369da852013-10-08 11:39:35 +02002153 if (hostname_left_label_end - hostname < (pattern_left_label_end - pattern) - 1)
Evan Broderbe554312013-06-27 00:05:25 -07002154 return 0;
2155
2156 /* Finally compare the string on either side of the
2157 * wildcard */
2158 prefixlen = pattern_wildcard - pattern;
2159 suffixlen = pattern_left_label_end - (pattern_wildcard + 1);
Emeric Bruna848dae2013-10-08 11:27:28 +02002160 if ((prefixlen && (memcmp(pattern, hostname, prefixlen) != 0))
2161 || (suffixlen && (memcmp(pattern_wildcard + 1, hostname_left_label_end - suffixlen, suffixlen) != 0)))
Evan Broderbe554312013-06-27 00:05:25 -07002162 return 0;
2163
2164 return 1;
2165}
2166
2167static int ssl_sock_srv_verifycbk(int ok, X509_STORE_CTX *ctx)
2168{
2169 SSL *ssl;
2170 struct connection *conn;
2171 char *servername;
2172
2173 int depth;
2174 X509 *cert;
2175 STACK_OF(GENERAL_NAME) *alt_names;
2176 int i;
2177 X509_NAME *cert_subject;
2178 char *str;
2179
2180 if (ok == 0)
2181 return ok;
2182
2183 ssl = X509_STORE_CTX_get_ex_data(ctx, SSL_get_ex_data_X509_STORE_CTX_idx());
2184 conn = (struct connection *)SSL_get_app_data(ssl);
2185
2186 servername = objt_server(conn->target)->ssl_ctx.verify_host;
2187
2188 /* We only need to verify the CN on the actual server cert,
2189 * not the indirect CAs */
2190 depth = X509_STORE_CTX_get_error_depth(ctx);
2191 if (depth != 0)
2192 return ok;
2193
2194 /* At this point, the cert is *not* OK unless we can find a
2195 * hostname match */
2196 ok = 0;
2197
2198 cert = X509_STORE_CTX_get_current_cert(ctx);
2199 /* It seems like this might happen if verify peer isn't set */
2200 if (!cert)
2201 return ok;
2202
2203 alt_names = X509_get_ext_d2i(cert, NID_subject_alt_name, NULL, NULL);
2204 if (alt_names) {
2205 for (i = 0; !ok && i < sk_GENERAL_NAME_num(alt_names); i++) {
2206 GENERAL_NAME *name = sk_GENERAL_NAME_value(alt_names, i);
2207 if (name->type == GEN_DNS) {
Emeric Bruna33410c2013-09-17 15:47:48 +02002208#if OPENSSL_VERSION_NUMBER < 0x00907000L
2209 if (ASN1_STRING_to_UTF8((unsigned char **)&str, name->d.ia5) >= 0) {
2210#else
Evan Broderbe554312013-06-27 00:05:25 -07002211 if (ASN1_STRING_to_UTF8((unsigned char **)&str, name->d.dNSName) >= 0) {
Emeric Bruna33410c2013-09-17 15:47:48 +02002212#endif
Evan Broderbe554312013-06-27 00:05:25 -07002213 ok = ssl_sock_srv_hostcheck(str, servername);
2214 OPENSSL_free(str);
2215 }
2216 }
2217 }
Emeric Brun4ad50a42013-09-17 15:19:54 +02002218 sk_GENERAL_NAME_pop_free(alt_names, GENERAL_NAME_free);
Evan Broderbe554312013-06-27 00:05:25 -07002219 }
2220
2221 cert_subject = X509_get_subject_name(cert);
2222 i = -1;
2223 while (!ok && (i = X509_NAME_get_index_by_NID(cert_subject, NID_commonName, i)) != -1) {
2224 X509_NAME_ENTRY *entry = X509_NAME_get_entry(cert_subject, i);
2225 if (ASN1_STRING_to_UTF8((unsigned char **)&str, entry->value) >= 0) {
2226 ok = ssl_sock_srv_hostcheck(str, servername);
2227 OPENSSL_free(str);
2228 }
2229 }
2230
2231 return ok;
2232}
2233
Emeric Brun94324a42012-10-11 14:00:19 +02002234/* prepare ssl context from servers options. Returns an error count */
2235int ssl_sock_prepare_srv_ctx(struct server *srv, struct proxy *curproxy)
2236{
2237 int cfgerr = 0;
Remi Gacogneaf5c3da2014-05-19 10:29:58 +02002238 long options =
Emeric Brun94324a42012-10-11 14:00:19 +02002239 SSL_OP_ALL | /* all known workarounds for bugs */
2240 SSL_OP_NO_SSLv2 |
2241 SSL_OP_NO_COMPRESSION;
Remi Gacogneaf5c3da2014-05-19 10:29:58 +02002242 long mode =
Emeric Brun94324a42012-10-11 14:00:19 +02002243 SSL_MODE_ENABLE_PARTIAL_WRITE |
2244 SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER |
Willy Tarreau396a1862014-11-13 14:06:52 +01002245 SSL_MODE_RELEASE_BUFFERS |
2246 SSL_MODE_SMALL_BUFFERS;
Emeric Brun850efd52014-01-29 12:24:34 +01002247 int verify = SSL_VERIFY_NONE;
Emeric Brun94324a42012-10-11 14:00:19 +02002248
Thierry Fournier383085f2013-01-24 14:15:43 +01002249 /* Make sure openssl opens /dev/urandom before the chroot */
2250 if (!ssl_initialize_random()) {
2251 Alert("OpenSSL random data generator initialization failed.\n");
2252 cfgerr++;
2253 }
2254
Willy Tarreaufce03112015-01-15 21:32:40 +01002255 /* Automatic memory computations need to know we use SSL there */
2256 global.ssl_used_backend = 1;
2257
2258 /* Initiate SSL context for current server */
Emeric Brun94324a42012-10-11 14:00:19 +02002259 srv->ssl_ctx.reused_sess = NULL;
2260 if (srv->use_ssl)
2261 srv->xprt = &ssl_sock;
2262 if (srv->check.use_ssl)
Cyril Bonté9ce13112014-11-15 22:41:27 +01002263 srv->check.xprt = &ssl_sock;
Emeric Brun94324a42012-10-11 14:00:19 +02002264
2265 srv->ssl_ctx.ctx = SSL_CTX_new(SSLv23_client_method());
2266 if (!srv->ssl_ctx.ctx) {
2267 Alert("config : %s '%s', server '%s': unable to allocate ssl context.\n",
2268 proxy_type_str(curproxy), curproxy->id,
2269 srv->id);
2270 cfgerr++;
2271 return cfgerr;
2272 }
Emeric Bruna7aa3092012-10-26 12:58:00 +02002273 if (srv->ssl_ctx.client_crt) {
2274 if (SSL_CTX_use_PrivateKey_file(srv->ssl_ctx.ctx, srv->ssl_ctx.client_crt, SSL_FILETYPE_PEM) <= 0) {
2275 Alert("config : %s '%s', server '%s': unable to load SSL private key from PEM file '%s'.\n",
2276 proxy_type_str(curproxy), curproxy->id,
2277 srv->id, srv->ssl_ctx.client_crt);
2278 cfgerr++;
2279 }
2280 else if (SSL_CTX_use_certificate_chain_file(srv->ssl_ctx.ctx, srv->ssl_ctx.client_crt) <= 0) {
2281 Alert("config : %s '%s', server '%s': unable to load ssl certificate from PEM file '%s'.\n",
2282 proxy_type_str(curproxy), curproxy->id,
2283 srv->id, srv->ssl_ctx.client_crt);
2284 cfgerr++;
2285 }
2286 else if (SSL_CTX_check_private_key(srv->ssl_ctx.ctx) <= 0) {
2287 Alert("config : %s '%s', server '%s': inconsistencies between private key and certificate loaded from PEM file '%s'.\n",
2288 proxy_type_str(curproxy), curproxy->id,
2289 srv->id, srv->ssl_ctx.client_crt);
2290 cfgerr++;
2291 }
2292 }
Emeric Brun94324a42012-10-11 14:00:19 +02002293
2294 if (srv->ssl_ctx.options & SRV_SSL_O_NO_SSLV3)
2295 options |= SSL_OP_NO_SSLv3;
2296 if (srv->ssl_ctx.options & SRV_SSL_O_NO_TLSV10)
2297 options |= SSL_OP_NO_TLSv1;
2298 if (srv->ssl_ctx.options & SRV_SSL_O_NO_TLSV11)
2299 options |= SSL_OP_NO_TLSv1_1;
2300 if (srv->ssl_ctx.options & SRV_SSL_O_NO_TLSV12)
2301 options |= SSL_OP_NO_TLSv1_2;
Emeric Brunf9c5c472012-10-11 15:28:34 +02002302 if (srv->ssl_ctx.options & SRV_SSL_O_NO_TLS_TICKETS)
2303 options |= SSL_OP_NO_TICKET;
Emeric Brun94324a42012-10-11 14:00:19 +02002304 if (srv->ssl_ctx.options & SRV_SSL_O_USE_SSLV3)
2305 SSL_CTX_set_ssl_version(srv->ssl_ctx.ctx, SSLv3_client_method());
2306 if (srv->ssl_ctx.options & SRV_SSL_O_USE_TLSV10)
2307 SSL_CTX_set_ssl_version(srv->ssl_ctx.ctx, TLSv1_client_method());
2308#if SSL_OP_NO_TLSv1_1
2309 if (srv->ssl_ctx.options & SRV_SSL_O_USE_TLSV11)
2310 SSL_CTX_set_ssl_version(srv->ssl_ctx.ctx, TLSv1_1_client_method());
2311#endif
2312#if SSL_OP_NO_TLSv1_2
2313 if (srv->ssl_ctx.options & SRV_SSL_O_USE_TLSV12)
2314 SSL_CTX_set_ssl_version(srv->ssl_ctx.ctx, TLSv1_2_client_method());
2315#endif
2316
2317 SSL_CTX_set_options(srv->ssl_ctx.ctx, options);
2318 SSL_CTX_set_mode(srv->ssl_ctx.ctx, mode);
Emeric Brun850efd52014-01-29 12:24:34 +01002319
2320 if (global.ssl_server_verify == SSL_SERVER_VERIFY_REQUIRED)
2321 verify = SSL_VERIFY_PEER;
2322
2323 switch (srv->ssl_ctx.verify) {
2324 case SSL_SOCK_VERIFY_NONE:
2325 verify = SSL_VERIFY_NONE;
2326 break;
2327 case SSL_SOCK_VERIFY_REQUIRED:
2328 verify = SSL_VERIFY_PEER;
2329 break;
2330 }
Evan Broderbe554312013-06-27 00:05:25 -07002331 SSL_CTX_set_verify(srv->ssl_ctx.ctx,
Emeric Brun850efd52014-01-29 12:24:34 +01002332 verify,
Evan Broderbe554312013-06-27 00:05:25 -07002333 srv->ssl_ctx.verify_host ? ssl_sock_srv_verifycbk : NULL);
Emeric Brun850efd52014-01-29 12:24:34 +01002334 if (verify & SSL_VERIFY_PEER) {
Emeric Brunef42d922012-10-11 16:11:36 +02002335 if (srv->ssl_ctx.ca_file) {
2336 /* load CAfile to verify */
2337 if (!SSL_CTX_load_verify_locations(srv->ssl_ctx.ctx, srv->ssl_ctx.ca_file, NULL)) {
Willy Tarreau07ba08b2014-02-16 19:22:08 +01002338 Alert("Proxy '%s', server '%s' [%s:%d] unable to load CA file '%s'.\n",
Emeric Brunef42d922012-10-11 16:11:36 +02002339 curproxy->id, srv->id,
2340 srv->conf.file, srv->conf.line, srv->ssl_ctx.ca_file);
2341 cfgerr++;
2342 }
2343 }
Emeric Brun850efd52014-01-29 12:24:34 +01002344 else {
2345 if (global.ssl_server_verify == SSL_SERVER_VERIFY_REQUIRED)
Willy Tarreau07ba08b2014-02-16 19:22:08 +01002346 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 +01002347 curproxy->id, srv->id,
2348 srv->conf.file, srv->conf.line);
2349 else
Willy Tarreau07ba08b2014-02-16 19:22:08 +01002350 Alert("Proxy '%s', server '%s' [%s:%d] verify is enabled but no CA file specified.\n",
Emeric Brun850efd52014-01-29 12:24:34 +01002351 curproxy->id, srv->id,
2352 srv->conf.file, srv->conf.line);
2353 cfgerr++;
2354 }
Emeric Brunef42d922012-10-11 16:11:36 +02002355#ifdef X509_V_FLAG_CRL_CHECK
2356 if (srv->ssl_ctx.crl_file) {
2357 X509_STORE *store = SSL_CTX_get_cert_store(srv->ssl_ctx.ctx);
2358
2359 if (!store || !X509_STORE_load_locations(store, srv->ssl_ctx.crl_file, NULL)) {
Willy Tarreau07ba08b2014-02-16 19:22:08 +01002360 Alert("Proxy '%s', server '%s' [%s:%d] unable to configure CRL file '%s'.\n",
Emeric Brunef42d922012-10-11 16:11:36 +02002361 curproxy->id, srv->id,
2362 srv->conf.file, srv->conf.line, srv->ssl_ctx.crl_file);
2363 cfgerr++;
2364 }
2365 else {
2366 X509_STORE_set_flags(store, X509_V_FLAG_CRL_CHECK|X509_V_FLAG_CRL_CHECK_ALL);
2367 }
2368 }
2369#endif
2370 }
2371
Emeric Brun4f65bff2012-11-16 15:11:00 +01002372 if (global.tune.ssllifetime)
2373 SSL_CTX_set_timeout(srv->ssl_ctx.ctx, global.tune.ssllifetime);
2374
Emeric Brun94324a42012-10-11 14:00:19 +02002375 SSL_CTX_set_session_cache_mode(srv->ssl_ctx.ctx, SSL_SESS_CACHE_OFF);
2376 if (srv->ssl_ctx.ciphers &&
2377 !SSL_CTX_set_cipher_list(srv->ssl_ctx.ctx, srv->ssl_ctx.ciphers)) {
2378 Alert("Proxy '%s', server '%s' [%s:%d] : unable to set SSL cipher list to '%s'.\n",
2379 curproxy->id, srv->id,
2380 srv->conf.file, srv->conf.line, srv->ssl_ctx.ciphers);
2381 cfgerr++;
2382 }
2383
2384 return cfgerr;
2385}
2386
Willy Tarreau2a65ff02012-09-13 17:54:29 +02002387/* Walks down the two trees in bind_conf and prepares all certs. The pointer may
Emeric Brunfc0421f2012-09-07 17:30:07 +02002388 * be NULL, in which case nothing is done. Returns the number of errors
2389 * encountered.
2390 */
Willy Tarreau2a65ff02012-09-13 17:54:29 +02002391int ssl_sock_prepare_all_ctx(struct bind_conf *bind_conf, struct proxy *px)
Emeric Brunfc0421f2012-09-07 17:30:07 +02002392{
2393 struct ebmb_node *node;
2394 struct sni_ctx *sni;
2395 int err = 0;
2396
Willy Tarreau2a65ff02012-09-13 17:54:29 +02002397 if (!bind_conf || !bind_conf->is_ssl)
Emeric Brunfc0421f2012-09-07 17:30:07 +02002398 return 0;
2399
Willy Tarreaufce03112015-01-15 21:32:40 +01002400 /* Automatic memory computations need to know we use SSL there */
2401 global.ssl_used_frontend = 1;
2402
Emeric Brun0bed9942014-10-30 19:25:24 +01002403 if (bind_conf->default_ctx)
2404 err += ssl_sock_prepare_ctx(bind_conf, bind_conf->default_ctx, px);
2405
Willy Tarreau2a65ff02012-09-13 17:54:29 +02002406 node = ebmb_first(&bind_conf->sni_ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002407 while (node) {
2408 sni = ebmb_entry(node, struct sni_ctx, name);
Emeric Brun0bed9942014-10-30 19:25:24 +01002409 if (!sni->order && sni->ctx != bind_conf->default_ctx)
2410 /* only initialize the CTX on its first occurrence and
2411 if it is not the default_ctx */
Willy Tarreau2a65ff02012-09-13 17:54:29 +02002412 err += ssl_sock_prepare_ctx(bind_conf, sni->ctx, px);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002413 node = ebmb_next(node);
2414 }
2415
Willy Tarreau2a65ff02012-09-13 17:54:29 +02002416 node = ebmb_first(&bind_conf->sni_w_ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002417 while (node) {
2418 sni = ebmb_entry(node, struct sni_ctx, name);
Emeric Brun0bed9942014-10-30 19:25:24 +01002419 if (!sni->order && sni->ctx != bind_conf->default_ctx)
2420 /* only initialize the CTX on its first occurrence and
2421 if it is not the default_ctx */
Willy Tarreau2a65ff02012-09-13 17:54:29 +02002422 err += ssl_sock_prepare_ctx(bind_conf, sni->ctx, px);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002423 node = ebmb_next(node);
2424 }
2425 return err;
2426}
2427
Willy Tarreau2a65ff02012-09-13 17:54:29 +02002428/* Walks down the two trees in bind_conf and frees all the certs. The pointer may
Emeric Brunfc0421f2012-09-07 17:30:07 +02002429 * be NULL, in which case nothing is done. The default_ctx is nullified too.
2430 */
Willy Tarreau2a65ff02012-09-13 17:54:29 +02002431void ssl_sock_free_all_ctx(struct bind_conf *bind_conf)
Emeric Brunfc0421f2012-09-07 17:30:07 +02002432{
2433 struct ebmb_node *node, *back;
2434 struct sni_ctx *sni;
2435
Willy Tarreau2a65ff02012-09-13 17:54:29 +02002436 if (!bind_conf || !bind_conf->is_ssl)
Emeric Brunfc0421f2012-09-07 17:30:07 +02002437 return;
2438
Willy Tarreau2a65ff02012-09-13 17:54:29 +02002439 node = ebmb_first(&bind_conf->sni_ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002440 while (node) {
2441 sni = ebmb_entry(node, struct sni_ctx, name);
2442 back = ebmb_next(node);
2443 ebmb_delete(node);
2444 if (!sni->order) /* only free the CTX on its first occurrence */
2445 SSL_CTX_free(sni->ctx);
2446 free(sni);
2447 node = back;
2448 }
2449
Willy Tarreau2a65ff02012-09-13 17:54:29 +02002450 node = ebmb_first(&bind_conf->sni_w_ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002451 while (node) {
2452 sni = ebmb_entry(node, struct sni_ctx, name);
2453 back = ebmb_next(node);
2454 ebmb_delete(node);
2455 if (!sni->order) /* only free the CTX on its first occurrence */
2456 SSL_CTX_free(sni->ctx);
2457 free(sni);
2458 node = back;
2459 }
2460
Willy Tarreau2a65ff02012-09-13 17:54:29 +02002461 bind_conf->default_ctx = NULL;
Emeric Brune1f38db2012-09-03 20:36:47 +02002462}
2463
Christopher Faulet31af49d2015-06-09 17:29:50 +02002464/* Load CA cert file and private key used to generate certificates */
2465int
2466ssl_sock_load_ca(struct bind_conf *bind_conf, struct proxy *px)
2467{
2468 FILE *fp;
2469 X509 *cacert = NULL;
2470 EVP_PKEY *capkey = NULL;
2471 int err = 0;
2472
2473 if (!bind_conf || !bind_conf->generate_certs)
2474 return err;
2475
2476 if (!bind_conf->ca_sign_file) {
2477 Alert("Proxy '%s': cannot enable certificate generation, "
2478 "no CA certificate File configured at [%s:%d].\n",
2479 px->id, bind_conf->file, bind_conf->line);
2480 err++;
2481 }
2482
2483 if (err)
2484 goto load_error;
2485
2486 /* read in the CA certificate */
2487 if (!(fp = fopen(bind_conf->ca_sign_file, "r"))) {
2488 Alert("Proxy '%s': Failed to read CA certificate file '%s' at [%s:%d].\n",
2489 px->id, bind_conf->ca_sign_file, bind_conf->file, bind_conf->line);
2490 err++;
2491 goto load_error;
2492 }
2493 if (!(cacert = PEM_read_X509(fp, NULL, NULL, NULL))) {
2494 Alert("Proxy '%s': Failed to read CA certificate file '%s' at [%s:%d].\n",
2495 px->id, bind_conf->ca_sign_file, bind_conf->file, bind_conf->line);
2496 fclose (fp);
2497 err++;
2498 goto load_error;
2499 }
2500 if (!(capkey = PEM_read_PrivateKey(fp, NULL, NULL, bind_conf->ca_sign_pass))) {
2501 Alert("Proxy '%s': Failed to read CA private key file '%s' at [%s:%d].\n",
2502 px->id, bind_conf->ca_sign_file, bind_conf->file, bind_conf->line);
2503 fclose (fp);
2504 err++;
2505 goto load_error;
2506 }
2507 fclose (fp);
2508
2509 bind_conf->ca_sign_cert = cacert;
2510 bind_conf->ca_sign_pkey = capkey;
2511 return err;
2512
2513 load_error:
2514 bind_conf->generate_certs = 0;
2515 if (capkey) EVP_PKEY_free(capkey);
2516 if (cacert) X509_free(cacert);
2517 return err;
2518}
2519
2520/* Release CA cert and private key used to generate certificated */
2521void
2522ssl_sock_free_ca(struct bind_conf *bind_conf)
2523{
2524 if (!bind_conf)
2525 return;
2526
2527 if (bind_conf->ca_sign_pkey)
2528 EVP_PKEY_free(bind_conf->ca_sign_pkey);
2529 if (bind_conf->ca_sign_cert)
2530 X509_free(bind_conf->ca_sign_cert);
2531}
2532
Emeric Brun46591952012-05-18 15:47:34 +02002533/*
2534 * This function is called if SSL * context is not yet allocated. The function
2535 * is designed to be called before any other data-layer operation and sets the
2536 * handshake flag on the connection. It is safe to call it multiple times.
2537 * It returns 0 on success and -1 in error case.
2538 */
2539static int ssl_sock_init(struct connection *conn)
2540{
2541 /* already initialized */
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02002542 if (conn->xprt_ctx)
Emeric Brun46591952012-05-18 15:47:34 +02002543 return 0;
2544
Willy Tarreau3c728722014-01-23 13:50:42 +01002545 if (!conn_ctrl_ready(conn))
Willy Tarreauf79c8172013-10-21 16:30:56 +02002546 return 0;
2547
Willy Tarreau20879a02012-12-03 16:32:10 +01002548 if (global.maxsslconn && sslconns >= global.maxsslconn) {
2549 conn->err_code = CO_ER_SSL_TOO_MANY;
Willy Tarreau403edff2012-09-06 11:58:37 +02002550 return -1;
Willy Tarreau20879a02012-12-03 16:32:10 +01002551 }
Willy Tarreau403edff2012-09-06 11:58:37 +02002552
Emeric Brun46591952012-05-18 15:47:34 +02002553 /* If it is in client mode initiate SSL session
2554 in connect state otherwise accept state */
Willy Tarreau3fdb3662012-11-12 00:42:33 +01002555 if (objt_server(conn->target)) {
Willy Tarreaufba03cd2014-11-13 13:48:58 +01002556 int may_retry = 1;
2557
2558 retry_connect:
Emeric Brun46591952012-05-18 15:47:34 +02002559 /* Alloc a new SSL session ctx */
Willy Tarreau3fdb3662012-11-12 00:42:33 +01002560 conn->xprt_ctx = SSL_new(objt_server(conn->target)->ssl_ctx.ctx);
Willy Tarreau20879a02012-12-03 16:32:10 +01002561 if (!conn->xprt_ctx) {
Willy Tarreaufba03cd2014-11-13 13:48:58 +01002562 if (may_retry--) {
2563 pool_gc2();
2564 goto retry_connect;
2565 }
Willy Tarreau20879a02012-12-03 16:32:10 +01002566 conn->err_code = CO_ER_SSL_NO_MEM;
Emeric Brun46591952012-05-18 15:47:34 +02002567 return -1;
Willy Tarreau20879a02012-12-03 16:32:10 +01002568 }
Emeric Brun46591952012-05-18 15:47:34 +02002569
Emeric Brun46591952012-05-18 15:47:34 +02002570 /* set fd on SSL session context */
Emeric Brun55476152014-11-12 17:35:37 +01002571 if (!SSL_set_fd(conn->xprt_ctx, conn->t.sock.fd)) {
2572 SSL_free(conn->xprt_ctx);
2573 conn->xprt_ctx = NULL;
Willy Tarreaufba03cd2014-11-13 13:48:58 +01002574 if (may_retry--) {
2575 pool_gc2();
2576 goto retry_connect;
2577 }
Emeric Brun55476152014-11-12 17:35:37 +01002578 conn->err_code = CO_ER_SSL_NO_MEM;
2579 return -1;
2580 }
Emeric Brun46591952012-05-18 15:47:34 +02002581
Evan Broderbe554312013-06-27 00:05:25 -07002582 /* set connection pointer */
Emeric Brun55476152014-11-12 17:35:37 +01002583 if (!SSL_set_app_data(conn->xprt_ctx, conn)) {
2584 SSL_free(conn->xprt_ctx);
2585 conn->xprt_ctx = NULL;
Willy Tarreaufba03cd2014-11-13 13:48:58 +01002586 if (may_retry--) {
2587 pool_gc2();
2588 goto retry_connect;
2589 }
Emeric Brun55476152014-11-12 17:35:37 +01002590 conn->err_code = CO_ER_SSL_NO_MEM;
2591 return -1;
2592 }
2593
2594 SSL_set_connect_state(conn->xprt_ctx);
2595 if (objt_server(conn->target)->ssl_ctx.reused_sess) {
2596 if(!SSL_set_session(conn->xprt_ctx, objt_server(conn->target)->ssl_ctx.reused_sess)) {
2597 SSL_SESSION_free(objt_server(conn->target)->ssl_ctx.reused_sess);
2598 objt_server(conn->target)->ssl_ctx.reused_sess = NULL;
2599 }
2600 }
Evan Broderbe554312013-06-27 00:05:25 -07002601
Emeric Brun46591952012-05-18 15:47:34 +02002602 /* leave init state and start handshake */
Willy Tarreau05737472012-09-04 08:03:39 +02002603 conn->flags |= CO_FL_SSL_WAIT_HS | CO_FL_WAIT_L6_CONN;
Willy Tarreau403edff2012-09-06 11:58:37 +02002604
2605 sslconns++;
Willy Tarreau71b734c2014-01-28 15:19:44 +01002606 totalsslconns++;
Emeric Brun46591952012-05-18 15:47:34 +02002607 return 0;
2608 }
Willy Tarreau3fdb3662012-11-12 00:42:33 +01002609 else if (objt_listener(conn->target)) {
Willy Tarreaufba03cd2014-11-13 13:48:58 +01002610 int may_retry = 1;
2611
2612 retry_accept:
Emeric Brun46591952012-05-18 15:47:34 +02002613 /* Alloc a new SSL session ctx */
Willy Tarreau3fdb3662012-11-12 00:42:33 +01002614 conn->xprt_ctx = SSL_new(objt_listener(conn->target)->bind_conf->default_ctx);
Willy Tarreau20879a02012-12-03 16:32:10 +01002615 if (!conn->xprt_ctx) {
Willy Tarreaufba03cd2014-11-13 13:48:58 +01002616 if (may_retry--) {
2617 pool_gc2();
2618 goto retry_accept;
2619 }
Willy Tarreau20879a02012-12-03 16:32:10 +01002620 conn->err_code = CO_ER_SSL_NO_MEM;
Emeric Brun46591952012-05-18 15:47:34 +02002621 return -1;
Willy Tarreau20879a02012-12-03 16:32:10 +01002622 }
Emeric Brun46591952012-05-18 15:47:34 +02002623
Emeric Brun46591952012-05-18 15:47:34 +02002624 /* set fd on SSL session context */
Emeric Brun55476152014-11-12 17:35:37 +01002625 if (!SSL_set_fd(conn->xprt_ctx, conn->t.sock.fd)) {
2626 SSL_free(conn->xprt_ctx);
2627 conn->xprt_ctx = NULL;
Willy Tarreaufba03cd2014-11-13 13:48:58 +01002628 if (may_retry--) {
2629 pool_gc2();
2630 goto retry_accept;
2631 }
Emeric Brun55476152014-11-12 17:35:37 +01002632 conn->err_code = CO_ER_SSL_NO_MEM;
2633 return -1;
2634 }
Emeric Brun46591952012-05-18 15:47:34 +02002635
Emeric Brune1f38db2012-09-03 20:36:47 +02002636 /* set connection pointer */
Emeric Brun55476152014-11-12 17:35:37 +01002637 if (!SSL_set_app_data(conn->xprt_ctx, conn)) {
2638 SSL_free(conn->xprt_ctx);
2639 conn->xprt_ctx = NULL;
Willy Tarreaufba03cd2014-11-13 13:48:58 +01002640 if (may_retry--) {
2641 pool_gc2();
2642 goto retry_accept;
2643 }
Emeric Brun55476152014-11-12 17:35:37 +01002644 conn->err_code = CO_ER_SSL_NO_MEM;
2645 return -1;
2646 }
2647
2648 SSL_set_accept_state(conn->xprt_ctx);
Emeric Brune1f38db2012-09-03 20:36:47 +02002649
Emeric Brun46591952012-05-18 15:47:34 +02002650 /* leave init state and start handshake */
Willy Tarreau05737472012-09-04 08:03:39 +02002651 conn->flags |= CO_FL_SSL_WAIT_HS | CO_FL_WAIT_L6_CONN;
Willy Tarreau403edff2012-09-06 11:58:37 +02002652
2653 sslconns++;
Willy Tarreau71b734c2014-01-28 15:19:44 +01002654 totalsslconns++;
Emeric Brun46591952012-05-18 15:47:34 +02002655 return 0;
2656 }
2657 /* don't know how to handle such a target */
Willy Tarreau20879a02012-12-03 16:32:10 +01002658 conn->err_code = CO_ER_SSL_NO_TARGET;
Emeric Brun46591952012-05-18 15:47:34 +02002659 return -1;
2660}
2661
2662
2663/* This is the callback which is used when an SSL handshake is pending. It
2664 * updates the FD status if it wants some polling before being called again.
2665 * It returns 0 if it fails in a fatal way or needs to poll to go further,
2666 * otherwise it returns non-zero and removes itself from the connection's
2667 * flags (the bit is provided in <flag> by the caller).
2668 */
2669int ssl_sock_handshake(struct connection *conn, unsigned int flag)
2670{
2671 int ret;
2672
Willy Tarreau3c728722014-01-23 13:50:42 +01002673 if (!conn_ctrl_ready(conn))
Willy Tarreauf79c8172013-10-21 16:30:56 +02002674 return 0;
2675
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02002676 if (!conn->xprt_ctx)
Emeric Brun46591952012-05-18 15:47:34 +02002677 goto out_error;
2678
Emeric Brun674b7432012-11-08 19:21:55 +01002679 /* If we use SSL_do_handshake to process a reneg initiated by
2680 * the remote peer, it sometimes returns SSL_ERROR_SSL.
2681 * Usually SSL_write and SSL_read are used and process implicitly
2682 * the reneg handshake.
2683 * Here we use SSL_peek as a workaround for reneg.
2684 */
2685 if ((conn->flags & CO_FL_CONNECTED) && SSL_renegotiate_pending(conn->xprt_ctx)) {
2686 char c;
2687
2688 ret = SSL_peek(conn->xprt_ctx, &c, 1);
2689 if (ret <= 0) {
2690 /* handshake may have not been completed, let's find why */
2691 ret = SSL_get_error(conn->xprt_ctx, ret);
2692 if (ret == SSL_ERROR_WANT_WRITE) {
2693 /* SSL handshake needs to write, L4 connection may not be ready */
2694 __conn_sock_stop_recv(conn);
Willy Tarreaue1f50c42014-01-22 20:02:06 +01002695 __conn_sock_want_send(conn);
2696 fd_cant_send(conn->t.sock.fd);
Emeric Brun674b7432012-11-08 19:21:55 +01002697 return 0;
2698 }
2699 else if (ret == SSL_ERROR_WANT_READ) {
2700 /* handshake may have been completed but we have
2701 * no more data to read.
2702 */
2703 if (!SSL_renegotiate_pending(conn->xprt_ctx)) {
2704 ret = 1;
2705 goto reneg_ok;
2706 }
2707 /* SSL handshake needs to read, L4 connection is ready */
2708 if (conn->flags & CO_FL_WAIT_L4_CONN)
2709 conn->flags &= ~CO_FL_WAIT_L4_CONN;
2710 __conn_sock_stop_send(conn);
Willy Tarreaue1f50c42014-01-22 20:02:06 +01002711 __conn_sock_want_recv(conn);
2712 fd_cant_recv(conn->t.sock.fd);
Emeric Brun674b7432012-11-08 19:21:55 +01002713 return 0;
2714 }
2715 else if (ret == SSL_ERROR_SYSCALL) {
2716 /* if errno is null, then connection was successfully established */
2717 if (!errno && conn->flags & CO_FL_WAIT_L4_CONN)
2718 conn->flags &= ~CO_FL_WAIT_L4_CONN;
Willy Tarreau20879a02012-12-03 16:32:10 +01002719 if (!conn->err_code) {
Emeric Brun29f037d2014-04-25 19:05:36 +02002720 if (!((SSL *)conn->xprt_ctx)->packet_length) {
2721 if (!errno) {
2722 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
2723 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
2724 else
2725 conn->err_code = CO_ER_SSL_EMPTY;
2726 }
2727 else {
2728 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
2729 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
2730 else
2731 conn->err_code = CO_ER_SSL_ABORT;
2732 }
2733 }
2734 else {
2735 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
2736 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
Willy Tarreau20879a02012-12-03 16:32:10 +01002737 else
Emeric Brun29f037d2014-04-25 19:05:36 +02002738 conn->err_code = CO_ER_SSL_HANDSHAKE;
2739 }
Willy Tarreau20879a02012-12-03 16:32:10 +01002740 }
Emeric Brun674b7432012-11-08 19:21:55 +01002741 goto out_error;
2742 }
2743 else {
2744 /* Fail on all other handshake errors */
2745 /* Note: OpenSSL may leave unread bytes in the socket's
2746 * buffer, causing an RST to be emitted upon close() on
2747 * TCP sockets. We first try to drain possibly pending
2748 * data to avoid this as much as possible.
2749 */
Willy Tarreaud85c4852015-03-13 00:40:28 +01002750 conn_sock_drain(conn);
Willy Tarreau20879a02012-12-03 16:32:10 +01002751 if (!conn->err_code)
Willy Tarreauf51c6982014-04-25 20:02:39 +02002752 conn->err_code = (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT) ?
2753 CO_ER_SSL_KILLED_HB : CO_ER_SSL_HANDSHAKE;
Emeric Brun674b7432012-11-08 19:21:55 +01002754 goto out_error;
2755 }
2756 }
2757 /* read some data: consider handshake completed */
2758 goto reneg_ok;
2759 }
2760
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02002761 ret = SSL_do_handshake(conn->xprt_ctx);
Emeric Brun46591952012-05-18 15:47:34 +02002762 if (ret != 1) {
2763 /* handshake did not complete, let's find why */
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02002764 ret = SSL_get_error(conn->xprt_ctx, ret);
Emeric Brun46591952012-05-18 15:47:34 +02002765
2766 if (ret == SSL_ERROR_WANT_WRITE) {
2767 /* SSL handshake needs to write, L4 connection may not be ready */
2768 __conn_sock_stop_recv(conn);
Willy Tarreaue1f50c42014-01-22 20:02:06 +01002769 __conn_sock_want_send(conn);
2770 fd_cant_send(conn->t.sock.fd);
Emeric Brun46591952012-05-18 15:47:34 +02002771 return 0;
2772 }
2773 else if (ret == SSL_ERROR_WANT_READ) {
2774 /* SSL handshake needs to read, L4 connection is ready */
2775 if (conn->flags & CO_FL_WAIT_L4_CONN)
2776 conn->flags &= ~CO_FL_WAIT_L4_CONN;
2777 __conn_sock_stop_send(conn);
Willy Tarreaue1f50c42014-01-22 20:02:06 +01002778 __conn_sock_want_recv(conn);
2779 fd_cant_recv(conn->t.sock.fd);
Emeric Brun46591952012-05-18 15:47:34 +02002780 return 0;
2781 }
Willy Tarreau89230192012-09-28 20:22:13 +02002782 else if (ret == SSL_ERROR_SYSCALL) {
2783 /* if errno is null, then connection was successfully established */
2784 if (!errno && conn->flags & CO_FL_WAIT_L4_CONN)
2785 conn->flags &= ~CO_FL_WAIT_L4_CONN;
Willy Tarreau20879a02012-12-03 16:32:10 +01002786
Emeric Brun29f037d2014-04-25 19:05:36 +02002787 if (!((SSL *)conn->xprt_ctx)->packet_length) {
2788 if (!errno) {
2789 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
2790 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
2791 else
2792 conn->err_code = CO_ER_SSL_EMPTY;
2793 }
2794 else {
2795 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
2796 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
2797 else
2798 conn->err_code = CO_ER_SSL_ABORT;
2799 }
2800 }
2801 else {
2802 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
2803 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
Willy Tarreau20879a02012-12-03 16:32:10 +01002804 else
Emeric Brun29f037d2014-04-25 19:05:36 +02002805 conn->err_code = CO_ER_SSL_HANDSHAKE;
2806 }
Willy Tarreau89230192012-09-28 20:22:13 +02002807 goto out_error;
2808 }
Emeric Brun46591952012-05-18 15:47:34 +02002809 else {
2810 /* Fail on all other handshake errors */
Willy Tarreau566dc552012-10-19 20:52:18 +02002811 /* Note: OpenSSL may leave unread bytes in the socket's
2812 * buffer, causing an RST to be emitted upon close() on
2813 * TCP sockets. We first try to drain possibly pending
2814 * data to avoid this as much as possible.
2815 */
Willy Tarreaud85c4852015-03-13 00:40:28 +01002816 conn_sock_drain(conn);
Willy Tarreau20879a02012-12-03 16:32:10 +01002817 if (!conn->err_code)
Willy Tarreauf51c6982014-04-25 20:02:39 +02002818 conn->err_code = (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT) ?
2819 CO_ER_SSL_KILLED_HB : CO_ER_SSL_HANDSHAKE;
Emeric Brun46591952012-05-18 15:47:34 +02002820 goto out_error;
2821 }
2822 }
2823
Emeric Brun674b7432012-11-08 19:21:55 +01002824reneg_ok:
2825
Emeric Brun46591952012-05-18 15:47:34 +02002826 /* Handshake succeeded */
Willy Tarreau0c9c2722014-05-28 12:28:58 +02002827 if (!SSL_session_reused(conn->xprt_ctx)) {
2828 if (objt_server(conn->target)) {
2829 update_freq_ctr(&global.ssl_be_keys_per_sec, 1);
2830 if (global.ssl_be_keys_per_sec.curr_ctr > global.ssl_be_keys_max)
2831 global.ssl_be_keys_max = global.ssl_be_keys_per_sec.curr_ctr;
2832
Emeric Brun46591952012-05-18 15:47:34 +02002833 /* check if session was reused, if not store current session on server for reuse */
Willy Tarreau3fdb3662012-11-12 00:42:33 +01002834 if (objt_server(conn->target)->ssl_ctx.reused_sess)
2835 SSL_SESSION_free(objt_server(conn->target)->ssl_ctx.reused_sess);
Emeric Brun46591952012-05-18 15:47:34 +02002836
Willy Tarreau2a3fb1c2015-02-05 16:47:07 +01002837 if (!(objt_server(conn->target)->ssl_ctx.options & SRV_SSL_O_NO_REUSE))
2838 objt_server(conn->target)->ssl_ctx.reused_sess = SSL_get1_session(conn->xprt_ctx);
Emeric Brun46591952012-05-18 15:47:34 +02002839 }
Willy Tarreau0c9c2722014-05-28 12:28:58 +02002840 else {
2841 update_freq_ctr(&global.ssl_fe_keys_per_sec, 1);
2842 if (global.ssl_fe_keys_per_sec.curr_ctr > global.ssl_fe_keys_max)
2843 global.ssl_fe_keys_max = global.ssl_fe_keys_per_sec.curr_ctr;
2844 }
Emeric Brun46591952012-05-18 15:47:34 +02002845 }
2846
2847 /* The connection is now established at both layers, it's time to leave */
2848 conn->flags &= ~(flag | CO_FL_WAIT_L4_CONN | CO_FL_WAIT_L6_CONN);
2849 return 1;
2850
2851 out_error:
Emeric Brun644cde02012-12-14 11:21:13 +01002852 /* Clear openssl global errors stack */
2853 ERR_clear_error();
2854
Emeric Brun9fa89732012-10-04 17:09:56 +02002855 /* free resumed session if exists */
Willy Tarreau3fdb3662012-11-12 00:42:33 +01002856 if (objt_server(conn->target) && objt_server(conn->target)->ssl_ctx.reused_sess) {
2857 SSL_SESSION_free(objt_server(conn->target)->ssl_ctx.reused_sess);
2858 objt_server(conn->target)->ssl_ctx.reused_sess = NULL;
Emeric Brun9fa89732012-10-04 17:09:56 +02002859 }
2860
Emeric Brun46591952012-05-18 15:47:34 +02002861 /* Fail on all other handshake errors */
2862 conn->flags |= CO_FL_ERROR;
Willy Tarreau20879a02012-12-03 16:32:10 +01002863 if (!conn->err_code)
2864 conn->err_code = CO_ER_SSL_HANDSHAKE;
Emeric Brun46591952012-05-18 15:47:34 +02002865 return 0;
2866}
2867
2868/* Receive up to <count> bytes from connection <conn>'s socket and store them
Willy Tarreauabf08d92014-01-14 11:31:27 +01002869 * into buffer <buf>. Only one call to recv() is performed, unless the
Emeric Brun46591952012-05-18 15:47:34 +02002870 * buffer wraps, in which case a second call may be performed. The connection's
2871 * flags are updated with whatever special event is detected (error, read0,
2872 * empty). The caller is responsible for taking care of those events and
2873 * avoiding the call if inappropriate. The function does not call the
2874 * connection's polling update function, so the caller is responsible for this.
2875 */
2876static int ssl_sock_to_buf(struct connection *conn, struct buffer *buf, int count)
2877{
2878 int ret, done = 0;
Willy Tarreauabf08d92014-01-14 11:31:27 +01002879 int try;
Emeric Brun46591952012-05-18 15:47:34 +02002880
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02002881 if (!conn->xprt_ctx)
Emeric Brun46591952012-05-18 15:47:34 +02002882 goto out_error;
2883
2884 if (conn->flags & CO_FL_HANDSHAKE)
2885 /* a handshake was requested */
2886 return 0;
2887
Willy Tarreauabf08d92014-01-14 11:31:27 +01002888 /* let's realign the buffer to optimize I/O */
2889 if (buffer_empty(buf))
Emeric Brun46591952012-05-18 15:47:34 +02002890 buf->p = buf->data;
Emeric Brun46591952012-05-18 15:47:34 +02002891
2892 /* read the largest possible block. For this, we perform only one call
2893 * to recv() unless the buffer wraps and we exactly fill the first hunk,
2894 * in which case we accept to do it once again. A new attempt is made on
2895 * EINTR too.
2896 */
Willy Tarreau00b0fb92014-01-17 11:09:40 +01002897 while (count > 0) {
Willy Tarreauabf08d92014-01-14 11:31:27 +01002898 /* first check if we have some room after p+i */
2899 try = buf->data + buf->size - (buf->p + buf->i);
2900 /* otherwise continue between data and p-o */
2901 if (try <= 0) {
2902 try = buf->p - (buf->data + buf->o);
2903 if (try <= 0)
2904 break;
2905 }
2906 if (try > count)
2907 try = count;
2908
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02002909 ret = SSL_read(conn->xprt_ctx, bi_end(buf), try);
Emeric Brune1f38db2012-09-03 20:36:47 +02002910 if (conn->flags & CO_FL_ERROR) {
2911 /* CO_FL_ERROR may be set by ssl_sock_infocbk */
Emeric Brun644cde02012-12-14 11:21:13 +01002912 goto out_error;
Emeric Brune1f38db2012-09-03 20:36:47 +02002913 }
Emeric Brun46591952012-05-18 15:47:34 +02002914 if (ret > 0) {
2915 buf->i += ret;
2916 done += ret;
2917 if (ret < try)
2918 break;
2919 count -= ret;
Emeric Brun46591952012-05-18 15:47:34 +02002920 }
2921 else if (ret == 0) {
Emeric Brun644cde02012-12-14 11:21:13 +01002922 ret = SSL_get_error(conn->xprt_ctx, ret);
2923 if (ret != SSL_ERROR_ZERO_RETURN) {
Emeric Brun1c646862012-12-14 12:33:41 +01002924 /* error on protocol or underlying transport */
2925 if ((ret != SSL_ERROR_SYSCALL)
2926 || (errno && (errno != EAGAIN)))
2927 conn->flags |= CO_FL_ERROR;
2928
Emeric Brun644cde02012-12-14 11:21:13 +01002929 /* Clear openssl global errors stack */
2930 ERR_clear_error();
2931 }
Emeric Brun46591952012-05-18 15:47:34 +02002932 goto read0;
2933 }
2934 else {
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02002935 ret = SSL_get_error(conn->xprt_ctx, ret);
Emeric Brun46591952012-05-18 15:47:34 +02002936 if (ret == SSL_ERROR_WANT_WRITE) {
Emeric Brun8af8dd12012-11-08 17:56:20 +01002937 /* handshake is running, and it needs to enable write */
Emeric Brun46591952012-05-18 15:47:34 +02002938 conn->flags |= CO_FL_SSL_WAIT_HS;
Emeric Brun8af8dd12012-11-08 17:56:20 +01002939 __conn_sock_want_send(conn);
Emeric Brun46591952012-05-18 15:47:34 +02002940 break;
2941 }
2942 else if (ret == SSL_ERROR_WANT_READ) {
Emeric Brun282a76a2012-11-08 18:02:56 +01002943 if (SSL_renegotiate_pending(conn->xprt_ctx)) {
2944 /* handshake is running, and it may need to re-enable read */
2945 conn->flags |= CO_FL_SSL_WAIT_HS;
2946 __conn_sock_want_recv(conn);
2947 break;
2948 }
Emeric Brun46591952012-05-18 15:47:34 +02002949 /* we need to poll for retry a read later */
Willy Tarreaue1f50c42014-01-22 20:02:06 +01002950 fd_cant_recv(conn->t.sock.fd);
Emeric Brun46591952012-05-18 15:47:34 +02002951 break;
2952 }
2953 /* otherwise it's a real error */
2954 goto out_error;
2955 }
2956 }
2957 return done;
2958
2959 read0:
2960 conn_sock_read0(conn);
2961 return done;
2962 out_error:
Emeric Brun644cde02012-12-14 11:21:13 +01002963 /* Clear openssl global errors stack */
2964 ERR_clear_error();
2965
Emeric Brun46591952012-05-18 15:47:34 +02002966 conn->flags |= CO_FL_ERROR;
2967 return done;
2968}
2969
2970
2971/* Send all pending bytes from buffer <buf> to connection <conn>'s socket.
Willy Tarreau1049b1f2014-02-02 01:51:17 +01002972 * <flags> may contain some CO_SFL_* flags to hint the system about other
2973 * pending data for example, but this flag is ignored at the moment.
Emeric Brun46591952012-05-18 15:47:34 +02002974 * Only one call to send() is performed, unless the buffer wraps, in which case
2975 * a second call may be performed. The connection's flags are updated with
2976 * whatever special event is detected (error, empty). The caller is responsible
2977 * for taking care of those events and avoiding the call if inappropriate. The
2978 * function does not call the connection's polling update function, so the caller
2979 * is responsible for this.
2980 */
2981static int ssl_sock_from_buf(struct connection *conn, struct buffer *buf, int flags)
2982{
2983 int ret, try, done;
2984
2985 done = 0;
2986
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02002987 if (!conn->xprt_ctx)
Emeric Brun46591952012-05-18 15:47:34 +02002988 goto out_error;
2989
2990 if (conn->flags & CO_FL_HANDSHAKE)
2991 /* a handshake was requested */
2992 return 0;
2993
2994 /* send the largest possible block. For this we perform only one call
2995 * to send() unless the buffer wraps and we exactly fill the first hunk,
2996 * in which case we accept to do it once again.
2997 */
2998 while (buf->o) {
Kevin Hestercad82342013-05-30 15:12:41 -07002999 try = bo_contig_data(buf);
Willy Tarreaubfd59462013-02-21 07:46:09 +01003000
Willy Tarreau7bed9452014-02-02 02:00:24 +01003001 if (!(flags & CO_SFL_STREAMER) &&
Willy Tarreau518cedd2014-02-17 15:43:01 +01003002 !(conn->xprt_st & SSL_SOCK_SEND_UNLIMITED) &&
3003 global.tune.ssl_max_record && try > global.tune.ssl_max_record) {
Willy Tarreaubfd59462013-02-21 07:46:09 +01003004 try = global.tune.ssl_max_record;
Willy Tarreau518cedd2014-02-17 15:43:01 +01003005 }
3006 else {
3007 /* we need to keep the information about the fact that
3008 * we're not limiting the upcoming send(), because if it
3009 * fails, we'll have to retry with at least as many data.
3010 */
3011 conn->xprt_st |= SSL_SOCK_SEND_UNLIMITED;
3012 }
Willy Tarreaubfd59462013-02-21 07:46:09 +01003013
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02003014 ret = SSL_write(conn->xprt_ctx, bo_ptr(buf), try);
Willy Tarreau518cedd2014-02-17 15:43:01 +01003015
Emeric Brune1f38db2012-09-03 20:36:47 +02003016 if (conn->flags & CO_FL_ERROR) {
3017 /* CO_FL_ERROR may be set by ssl_sock_infocbk */
Emeric Brun644cde02012-12-14 11:21:13 +01003018 goto out_error;
Emeric Brune1f38db2012-09-03 20:36:47 +02003019 }
Emeric Brun46591952012-05-18 15:47:34 +02003020 if (ret > 0) {
Willy Tarreau518cedd2014-02-17 15:43:01 +01003021 conn->xprt_st &= ~SSL_SOCK_SEND_UNLIMITED;
3022
Emeric Brun46591952012-05-18 15:47:34 +02003023 buf->o -= ret;
3024 done += ret;
3025
Willy Tarreau5fb38032012-12-16 19:39:09 +01003026 if (likely(buffer_empty(buf)))
Emeric Brun46591952012-05-18 15:47:34 +02003027 /* optimize data alignment in the buffer */
3028 buf->p = buf->data;
3029
3030 /* if the system buffer is full, don't insist */
3031 if (ret < try)
3032 break;
3033 }
3034 else {
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02003035 ret = SSL_get_error(conn->xprt_ctx, ret);
Emeric Brun46591952012-05-18 15:47:34 +02003036 if (ret == SSL_ERROR_WANT_WRITE) {
Emeric Brun282a76a2012-11-08 18:02:56 +01003037 if (SSL_renegotiate_pending(conn->xprt_ctx)) {
3038 /* handshake is running, and it may need to re-enable write */
3039 conn->flags |= CO_FL_SSL_WAIT_HS;
3040 __conn_sock_want_send(conn);
3041 break;
3042 }
Emeric Brun46591952012-05-18 15:47:34 +02003043 /* we need to poll to retry a write later */
Willy Tarreaue1f50c42014-01-22 20:02:06 +01003044 fd_cant_send(conn->t.sock.fd);
Emeric Brun46591952012-05-18 15:47:34 +02003045 break;
3046 }
3047 else if (ret == SSL_ERROR_WANT_READ) {
Emeric Brun8af8dd12012-11-08 17:56:20 +01003048 /* handshake is running, and it needs to enable read */
Emeric Brun46591952012-05-18 15:47:34 +02003049 conn->flags |= CO_FL_SSL_WAIT_HS;
Emeric Brun8af8dd12012-11-08 17:56:20 +01003050 __conn_sock_want_recv(conn);
Emeric Brun46591952012-05-18 15:47:34 +02003051 break;
3052 }
3053 goto out_error;
3054 }
3055 }
3056 return done;
3057
3058 out_error:
Emeric Brun644cde02012-12-14 11:21:13 +01003059 /* Clear openssl global errors stack */
3060 ERR_clear_error();
3061
Emeric Brun46591952012-05-18 15:47:34 +02003062 conn->flags |= CO_FL_ERROR;
3063 return done;
3064}
3065
Emeric Brun46591952012-05-18 15:47:34 +02003066static void ssl_sock_close(struct connection *conn) {
3067
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02003068 if (conn->xprt_ctx) {
3069 SSL_free(conn->xprt_ctx);
3070 conn->xprt_ctx = NULL;
Willy Tarreau403edff2012-09-06 11:58:37 +02003071 sslconns--;
Emeric Brun46591952012-05-18 15:47:34 +02003072 }
Emeric Brun46591952012-05-18 15:47:34 +02003073}
3074
3075/* This function tries to perform a clean shutdown on an SSL connection, and in
3076 * any case, flags the connection as reusable if no handshake was in progress.
3077 */
3078static void ssl_sock_shutw(struct connection *conn, int clean)
3079{
3080 if (conn->flags & CO_FL_HANDSHAKE)
3081 return;
3082 /* no handshake was in progress, try a clean ssl shutdown */
Emeric Brun644cde02012-12-14 11:21:13 +01003083 if (clean && (SSL_shutdown(conn->xprt_ctx) <= 0)) {
3084 /* Clear openssl global errors stack */
3085 ERR_clear_error();
3086 }
Emeric Brun46591952012-05-18 15:47:34 +02003087
3088 /* force flag on ssl to keep session in cache regardless shutdown result */
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02003089 SSL_set_shutdown(conn->xprt_ctx, SSL_SENT_SHUTDOWN);
Emeric Brun46591952012-05-18 15:47:34 +02003090}
3091
Willy Tarreauffc3fcd2012-10-12 20:17:54 +02003092/* used for logging, may be changed for a sample fetch later */
3093const char *ssl_sock_get_cipher_name(struct connection *conn)
3094{
3095 if (!conn->xprt && !conn->xprt_ctx)
3096 return NULL;
3097 return SSL_get_cipher_name(conn->xprt_ctx);
3098}
3099
3100/* used for logging, may be changed for a sample fetch later */
3101const char *ssl_sock_get_proto_version(struct connection *conn)
3102{
3103 if (!conn->xprt && !conn->xprt_ctx)
3104 return NULL;
3105 return SSL_get_version(conn->xprt_ctx);
3106}
3107
Willy Tarreau8d598402012-10-22 17:58:39 +02003108/* Extract a serial from a cert, and copy it to a chunk.
3109 * Returns 1 if serial is found and copied, 0 if no serial found and
3110 * -1 if output is not large enough.
3111 */
3112static int
3113ssl_sock_get_serial(X509 *crt, struct chunk *out)
3114{
3115 ASN1_INTEGER *serial;
3116
3117 serial = X509_get_serialNumber(crt);
3118 if (!serial)
3119 return 0;
3120
3121 if (out->size < serial->length)
3122 return -1;
3123
3124 memcpy(out->str, serial->data, serial->length);
3125 out->len = serial->length;
3126 return 1;
3127}
3128
Emeric Brun43e79582014-10-29 19:03:26 +01003129/* Extract a cert to der, and copy it to a chunk.
3130 * Returns 1 if cert is found and copied, 0 on der convertion failure and
3131 * -1 if output is not large enough.
3132 */
3133static int
3134ssl_sock_crt2der(X509 *crt, struct chunk *out)
3135{
3136 int len;
3137 unsigned char *p = (unsigned char *)out->str;;
3138
3139 len =i2d_X509(crt, NULL);
3140 if (len <= 0)
3141 return 1;
3142
3143 if (out->size < len)
3144 return -1;
3145
3146 i2d_X509(crt,&p);
3147 out->len = len;
3148 return 1;
3149}
3150
Emeric Brunce5ad802012-10-22 14:11:22 +02003151
3152/* Copy Date in ASN1_UTCTIME format in struct chunk out.
3153 * Returns 1 if serial is found and copied, 0 if no valid time found
3154 * and -1 if output is not large enough.
3155 */
3156static int
3157ssl_sock_get_time(ASN1_TIME *tm, struct chunk *out)
3158{
3159 if (tm->type == V_ASN1_GENERALIZEDTIME) {
3160 ASN1_GENERALIZEDTIME *gentm = (ASN1_GENERALIZEDTIME *)tm;
3161
3162 if (gentm->length < 12)
3163 return 0;
3164 if (gentm->data[0] != 0x32 || gentm->data[1] != 0x30)
3165 return 0;
3166 if (out->size < gentm->length-2)
3167 return -1;
3168
3169 memcpy(out->str, gentm->data+2, gentm->length-2);
3170 out->len = gentm->length-2;
3171 return 1;
3172 }
3173 else if (tm->type == V_ASN1_UTCTIME) {
3174 ASN1_UTCTIME *utctm = (ASN1_UTCTIME *)tm;
3175
3176 if (utctm->length < 10)
3177 return 0;
3178 if (utctm->data[0] >= 0x35)
3179 return 0;
3180 if (out->size < utctm->length)
3181 return -1;
3182
3183 memcpy(out->str, utctm->data, utctm->length);
3184 out->len = utctm->length;
3185 return 1;
3186 }
3187
3188 return 0;
3189}
3190
Emeric Brun87855892012-10-17 17:39:35 +02003191/* Extract an entry from a X509_NAME and copy its value to an output chunk.
3192 * Returns 1 if entry found, 0 if entry not found, or -1 if output not large enough.
3193 */
3194static int
3195ssl_sock_get_dn_entry(X509_NAME *a, const struct chunk *entry, int pos, struct chunk *out)
3196{
3197 X509_NAME_ENTRY *ne;
3198 int i, j, n;
3199 int cur = 0;
3200 const char *s;
3201 char tmp[128];
3202
3203 out->len = 0;
3204 for (i = 0; i < sk_X509_NAME_ENTRY_num(a->entries); i++) {
3205 if (pos < 0)
3206 j = (sk_X509_NAME_ENTRY_num(a->entries)-1) - i;
3207 else
3208 j = i;
3209
3210 ne = sk_X509_NAME_ENTRY_value(a->entries, j);
3211 n = OBJ_obj2nid(ne->object);
3212 if ((n == NID_undef) || ((s = OBJ_nid2sn(n)) == NULL)) {
3213 i2t_ASN1_OBJECT(tmp, sizeof(tmp), ne->object);
3214 s = tmp;
3215 }
3216
3217 if (chunk_strcasecmp(entry, s) != 0)
3218 continue;
3219
3220 if (pos < 0)
3221 cur--;
3222 else
3223 cur++;
3224
3225 if (cur != pos)
3226 continue;
3227
3228 if (ne->value->length > out->size)
3229 return -1;
3230
3231 memcpy(out->str, ne->value->data, ne->value->length);
3232 out->len = ne->value->length;
3233 return 1;
3234 }
3235
3236 return 0;
3237
3238}
3239
3240/* Extract and format full DN from a X509_NAME and copy result into a chunk
3241 * Returns 1 if dn entries exits, 0 if no dn entry found or -1 if output is not large enough.
3242 */
3243static int
3244ssl_sock_get_dn_oneline(X509_NAME *a, struct chunk *out)
3245{
3246 X509_NAME_ENTRY *ne;
3247 int i, n, ln;
3248 int l = 0;
3249 const char *s;
3250 char *p;
3251 char tmp[128];
3252
3253 out->len = 0;
3254 p = out->str;
3255 for (i = 0; i < sk_X509_NAME_ENTRY_num(a->entries); i++) {
3256 ne = sk_X509_NAME_ENTRY_value(a->entries, i);
3257 n = OBJ_obj2nid(ne->object);
3258 if ((n == NID_undef) || ((s = OBJ_nid2sn(n)) == NULL)) {
3259 i2t_ASN1_OBJECT(tmp, sizeof(tmp), ne->object);
3260 s = tmp;
3261 }
3262 ln = strlen(s);
3263
3264 l += 1 + ln + 1 + ne->value->length;
3265 if (l > out->size)
3266 return -1;
3267 out->len = l;
3268
3269 *(p++)='/';
3270 memcpy(p, s, ln);
3271 p += ln;
3272 *(p++)='=';
3273 memcpy(p, ne->value->data, ne->value->length);
3274 p += ne->value->length;
3275 }
3276
3277 if (!out->len)
3278 return 0;
3279
3280 return 1;
3281}
3282
David Safb76832014-05-08 23:42:08 -04003283char *ssl_sock_get_version(struct connection *conn)
3284{
3285 if (!ssl_sock_is_ssl(conn))
3286 return NULL;
3287
3288 return (char *)SSL_get_version(conn->xprt_ctx);
3289}
3290
Emeric Brun0abf8362014-06-24 18:26:41 +02003291/* Extract peer certificate's common name into the chunk dest
3292 * Returns
3293 * the len of the extracted common name
3294 * or 0 if no CN found in DN
3295 * or -1 on error case (i.e. no peer certificate)
3296 */
3297int ssl_sock_get_remote_common_name(struct connection *conn, struct chunk *dest)
David Safb76832014-05-08 23:42:08 -04003298{
3299 X509 *crt = NULL;
3300 X509_NAME *name;
David Safb76832014-05-08 23:42:08 -04003301 const char find_cn[] = "CN";
3302 const struct chunk find_cn_chunk = {
3303 .str = (char *)&find_cn,
3304 .len = sizeof(find_cn)-1
3305 };
Emeric Brun0abf8362014-06-24 18:26:41 +02003306 int result = -1;
David Safb76832014-05-08 23:42:08 -04003307
3308 if (!ssl_sock_is_ssl(conn))
Emeric Brun0abf8362014-06-24 18:26:41 +02003309 goto out;
David Safb76832014-05-08 23:42:08 -04003310
3311 /* SSL_get_peer_certificate, it increase X509 * ref count */
3312 crt = SSL_get_peer_certificate(conn->xprt_ctx);
3313 if (!crt)
3314 goto out;
3315
3316 name = X509_get_subject_name(crt);
3317 if (!name)
3318 goto out;
David Safb76832014-05-08 23:42:08 -04003319
Emeric Brun0abf8362014-06-24 18:26:41 +02003320 result = ssl_sock_get_dn_entry(name, &find_cn_chunk, 1, dest);
3321out:
David Safb76832014-05-08 23:42:08 -04003322 if (crt)
3323 X509_free(crt);
3324
3325 return result;
3326}
3327
Dave McCowan328fb582014-07-30 10:39:13 -04003328/* returns 1 if client passed a certificate for this session, 0 if not */
3329int ssl_sock_get_cert_used_sess(struct connection *conn)
3330{
3331 X509 *crt = NULL;
3332
3333 if (!ssl_sock_is_ssl(conn))
3334 return 0;
3335
3336 /* SSL_get_peer_certificate, it increase X509 * ref count */
3337 crt = SSL_get_peer_certificate(conn->xprt_ctx);
3338 if (!crt)
3339 return 0;
3340
3341 X509_free(crt);
3342 return 1;
3343}
3344
3345/* returns 1 if client passed a certificate for this connection, 0 if not */
3346int ssl_sock_get_cert_used_conn(struct connection *conn)
David Safb76832014-05-08 23:42:08 -04003347{
3348 if (!ssl_sock_is_ssl(conn))
3349 return 0;
3350
3351 return SSL_SOCK_ST_FL_VERIFY_DONE & conn->xprt_st ? 1 : 0;
3352}
3353
3354/* returns result from SSL verify */
3355unsigned int ssl_sock_get_verify_result(struct connection *conn)
3356{
3357 if (!ssl_sock_is_ssl(conn))
3358 return (unsigned int)X509_V_ERR_APPLICATION_VERIFICATION;
3359
3360 return (unsigned int)SSL_get_verify_result(conn->xprt_ctx);
3361}
3362
Willy Tarreau7875d092012-09-10 08:20:03 +02003363/***** Below are some sample fetching functions for ACL/patterns *****/
3364
Emeric Brune64aef12012-09-21 13:15:06 +02003365/* boolean, returns true if client cert was present */
3366static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02003367smp_fetch_ssl_fc_has_crt(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brune64aef12012-09-21 13:15:06 +02003368{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003369 struct connection *conn;
3370
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02003371 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003372 if (!conn || conn->xprt != &ssl_sock)
Emeric Brune64aef12012-09-21 13:15:06 +02003373 return 0;
3374
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003375 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brune64aef12012-09-21 13:15:06 +02003376 smp->flags |= SMP_F_MAY_CHANGE;
3377 return 0;
3378 }
3379
3380 smp->flags = 0;
3381 smp->type = SMP_T_BOOL;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003382 smp->data.uint = SSL_SOCK_ST_FL_VERIFY_DONE & conn->xprt_st ? 1 : 0;
Emeric Brune64aef12012-09-21 13:15:06 +02003383
3384 return 1;
3385}
3386
Emeric Brun43e79582014-10-29 19:03:26 +01003387/* binary, returns a certificate in a binary chunk (der/raw).
3388 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
3389 * should be use.
3390 */
3391static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02003392smp_fetch_ssl_x_der(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun43e79582014-10-29 19:03:26 +01003393{
3394 int cert_peer = (kw[4] == 'c') ? 1 : 0;
3395 X509 *crt = NULL;
3396 int ret = 0;
3397 struct chunk *smp_trash;
3398 struct connection *conn;
3399
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02003400 conn = objt_conn(smp->sess->origin);
Emeric Brun43e79582014-10-29 19:03:26 +01003401 if (!conn || conn->xprt != &ssl_sock)
3402 return 0;
3403
3404 if (!(conn->flags & CO_FL_CONNECTED)) {
3405 smp->flags |= SMP_F_MAY_CHANGE;
3406 return 0;
3407 }
3408
3409 if (cert_peer)
3410 crt = SSL_get_peer_certificate(conn->xprt_ctx);
3411 else
3412 crt = SSL_get_certificate(conn->xprt_ctx);
3413
3414 if (!crt)
3415 goto out;
3416
3417 smp_trash = get_trash_chunk();
3418 if (ssl_sock_crt2der(crt, smp_trash) <= 0)
3419 goto out;
3420
3421 smp->data.str = *smp_trash;
3422 smp->type = SMP_T_BIN;
3423 ret = 1;
3424out:
3425 /* SSL_get_peer_certificate, it increase X509 * ref count */
3426 if (cert_peer && crt)
3427 X509_free(crt);
3428 return ret;
3429}
3430
Emeric Brunba841a12014-04-30 17:05:08 +02003431/* binary, returns serial of certificate in a binary chunk.
3432 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
3433 * should be use.
3434 */
Willy Tarreau8d598402012-10-22 17:58:39 +02003435static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02003436smp_fetch_ssl_x_serial(const struct arg *args, struct sample *smp, const char *kw, void *private)
Willy Tarreau8d598402012-10-22 17:58:39 +02003437{
Emeric Brunba841a12014-04-30 17:05:08 +02003438 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Willy Tarreau8d598402012-10-22 17:58:39 +02003439 X509 *crt = NULL;
3440 int ret = 0;
3441 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003442 struct connection *conn;
3443
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02003444 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003445 if (!conn || conn->xprt != &ssl_sock)
Willy Tarreau8d598402012-10-22 17:58:39 +02003446 return 0;
3447
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003448 if (!(conn->flags & CO_FL_CONNECTED)) {
Willy Tarreau8d598402012-10-22 17:58:39 +02003449 smp->flags |= SMP_F_MAY_CHANGE;
3450 return 0;
3451 }
3452
Emeric Brunba841a12014-04-30 17:05:08 +02003453 if (cert_peer)
3454 crt = SSL_get_peer_certificate(conn->xprt_ctx);
3455 else
3456 crt = SSL_get_certificate(conn->xprt_ctx);
3457
Willy Tarreau8d598402012-10-22 17:58:39 +02003458 if (!crt)
3459 goto out;
3460
Willy Tarreau47ca5452012-12-23 20:22:19 +01003461 smp_trash = get_trash_chunk();
Willy Tarreau8d598402012-10-22 17:58:39 +02003462 if (ssl_sock_get_serial(crt, smp_trash) <= 0)
3463 goto out;
3464
3465 smp->data.str = *smp_trash;
3466 smp->type = SMP_T_BIN;
3467 ret = 1;
3468out:
Emeric Brunba841a12014-04-30 17:05:08 +02003469 /* SSL_get_peer_certificate, it increase X509 * ref count */
3470 if (cert_peer && crt)
Willy Tarreau8d598402012-10-22 17:58:39 +02003471 X509_free(crt);
3472 return ret;
3473}
Emeric Brune64aef12012-09-21 13:15:06 +02003474
Emeric Brunba841a12014-04-30 17:05:08 +02003475/* binary, returns the client certificate's SHA-1 fingerprint (SHA-1 hash of DER-encoded certificate) in a binary chunk.
3476 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
3477 * should be use.
3478 */
James Votha051b4a2013-05-14 20:37:59 +02003479static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02003480smp_fetch_ssl_x_sha1(const struct arg *args, struct sample *smp, const char *kw, void *private)
James Votha051b4a2013-05-14 20:37:59 +02003481{
Emeric Brunba841a12014-04-30 17:05:08 +02003482 int cert_peer = (kw[4] == 'c') ? 1 : 0;
James Votha051b4a2013-05-14 20:37:59 +02003483 X509 *crt = NULL;
3484 const EVP_MD *digest;
3485 int ret = 0;
3486 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003487 struct connection *conn;
James Votha051b4a2013-05-14 20:37:59 +02003488
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02003489 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003490 if (!conn || conn->xprt != &ssl_sock)
3491 return 0;
3492
3493 if (!(conn->flags & CO_FL_CONNECTED)) {
James Votha051b4a2013-05-14 20:37:59 +02003494 smp->flags |= SMP_F_MAY_CHANGE;
3495 return 0;
3496 }
3497
Emeric Brunba841a12014-04-30 17:05:08 +02003498 if (cert_peer)
3499 crt = SSL_get_peer_certificate(conn->xprt_ctx);
3500 else
3501 crt = SSL_get_certificate(conn->xprt_ctx);
James Votha051b4a2013-05-14 20:37:59 +02003502 if (!crt)
3503 goto out;
3504
3505 smp_trash = get_trash_chunk();
3506 digest = EVP_sha1();
3507 X509_digest(crt, digest, (unsigned char *)smp_trash->str, (unsigned int *)&smp_trash->len);
3508
3509 smp->data.str = *smp_trash;
3510 smp->type = SMP_T_BIN;
3511 ret = 1;
3512out:
Emeric Brunba841a12014-04-30 17:05:08 +02003513 /* SSL_get_peer_certificate, it increase X509 * ref count */
3514 if (cert_peer && crt)
James Votha051b4a2013-05-14 20:37:59 +02003515 X509_free(crt);
3516 return ret;
3517}
3518
Emeric Brunba841a12014-04-30 17:05:08 +02003519/* string, returns certificate's notafter date in ASN1_UTCTIME format.
3520 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
3521 * should be use.
3522 */
Emeric Brunce5ad802012-10-22 14:11:22 +02003523static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02003524smp_fetch_ssl_x_notafter(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brunce5ad802012-10-22 14:11:22 +02003525{
Emeric Brunba841a12014-04-30 17:05:08 +02003526 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brunce5ad802012-10-22 14:11:22 +02003527 X509 *crt = NULL;
3528 int ret = 0;
3529 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003530 struct connection *conn;
Emeric Brunce5ad802012-10-22 14:11:22 +02003531
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02003532 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003533 if (!conn || conn->xprt != &ssl_sock)
3534 return 0;
3535
3536 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunce5ad802012-10-22 14:11:22 +02003537 smp->flags |= SMP_F_MAY_CHANGE;
3538 return 0;
3539 }
3540
Emeric Brunba841a12014-04-30 17:05:08 +02003541 if (cert_peer)
3542 crt = SSL_get_peer_certificate(conn->xprt_ctx);
3543 else
3544 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brunce5ad802012-10-22 14:11:22 +02003545 if (!crt)
3546 goto out;
3547
Willy Tarreau47ca5452012-12-23 20:22:19 +01003548 smp_trash = get_trash_chunk();
Emeric Brunce5ad802012-10-22 14:11:22 +02003549 if (ssl_sock_get_time(X509_get_notAfter(crt), smp_trash) <= 0)
3550 goto out;
3551
3552 smp->data.str = *smp_trash;
3553 smp->type = SMP_T_STR;
3554 ret = 1;
3555out:
Emeric Brunba841a12014-04-30 17:05:08 +02003556 /* SSL_get_peer_certificate, it increase X509 * ref count */
3557 if (cert_peer && crt)
Emeric Brunce5ad802012-10-22 14:11:22 +02003558 X509_free(crt);
3559 return ret;
3560}
3561
Emeric Brunba841a12014-04-30 17:05:08 +02003562/* string, returns a string of a formatted full dn \C=..\O=..\OU=.. \CN=.. of certificate's issuer
3563 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
3564 * should be use.
3565 */
Emeric Brun87855892012-10-17 17:39:35 +02003566static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02003567smp_fetch_ssl_x_i_dn(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun87855892012-10-17 17:39:35 +02003568{
Emeric Brunba841a12014-04-30 17:05:08 +02003569 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brun87855892012-10-17 17:39:35 +02003570 X509 *crt = NULL;
3571 X509_NAME *name;
3572 int ret = 0;
3573 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003574 struct connection *conn;
Emeric Brun87855892012-10-17 17:39:35 +02003575
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02003576 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003577 if (!conn || conn->xprt != &ssl_sock)
3578 return 0;
3579
3580 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun87855892012-10-17 17:39:35 +02003581 smp->flags |= SMP_F_MAY_CHANGE;
3582 return 0;
3583 }
3584
Emeric Brunba841a12014-04-30 17:05:08 +02003585 if (cert_peer)
3586 crt = SSL_get_peer_certificate(conn->xprt_ctx);
3587 else
3588 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brun87855892012-10-17 17:39:35 +02003589 if (!crt)
3590 goto out;
3591
3592 name = X509_get_issuer_name(crt);
3593 if (!name)
3594 goto out;
3595
Willy Tarreau47ca5452012-12-23 20:22:19 +01003596 smp_trash = get_trash_chunk();
Emeric Brun87855892012-10-17 17:39:35 +02003597 if (args && args[0].type == ARGT_STR) {
3598 int pos = 1;
3599
3600 if (args[1].type == ARGT_SINT)
3601 pos = args[1].data.sint;
3602 else if (args[1].type == ARGT_UINT)
3603 pos =(int)args[1].data.uint;
3604
3605 if (ssl_sock_get_dn_entry(name, &args[0].data.str, pos, smp_trash) <= 0)
3606 goto out;
3607 }
3608 else if (ssl_sock_get_dn_oneline(name, smp_trash) <= 0)
3609 goto out;
3610
3611 smp->type = SMP_T_STR;
3612 smp->data.str = *smp_trash;
3613 ret = 1;
3614out:
Emeric Brunba841a12014-04-30 17:05:08 +02003615 /* SSL_get_peer_certificate, it increase X509 * ref count */
3616 if (cert_peer && crt)
Emeric Brun87855892012-10-17 17:39:35 +02003617 X509_free(crt);
3618 return ret;
3619}
3620
Emeric Brunba841a12014-04-30 17:05:08 +02003621/* string, returns notbefore date in ASN1_UTCTIME format.
3622 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
3623 * should be use.
3624 */
Emeric Brunce5ad802012-10-22 14:11:22 +02003625static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02003626smp_fetch_ssl_x_notbefore(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brunce5ad802012-10-22 14:11:22 +02003627{
Emeric Brunba841a12014-04-30 17:05:08 +02003628 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brunce5ad802012-10-22 14:11:22 +02003629 X509 *crt = NULL;
3630 int ret = 0;
3631 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003632 struct connection *conn;
3633
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02003634 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003635 if (!conn || conn->xprt != &ssl_sock)
Emeric Brunce5ad802012-10-22 14:11:22 +02003636 return 0;
3637
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003638 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunce5ad802012-10-22 14:11:22 +02003639 smp->flags |= SMP_F_MAY_CHANGE;
3640 return 0;
3641 }
3642
Emeric Brunba841a12014-04-30 17:05:08 +02003643 if (cert_peer)
3644 crt = SSL_get_peer_certificate(conn->xprt_ctx);
3645 else
3646 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brunce5ad802012-10-22 14:11:22 +02003647 if (!crt)
3648 goto out;
3649
Willy Tarreau47ca5452012-12-23 20:22:19 +01003650 smp_trash = get_trash_chunk();
Emeric Brunce5ad802012-10-22 14:11:22 +02003651 if (ssl_sock_get_time(X509_get_notBefore(crt), smp_trash) <= 0)
3652 goto out;
3653
3654 smp->data.str = *smp_trash;
3655 smp->type = SMP_T_STR;
3656 ret = 1;
3657out:
Emeric Brunba841a12014-04-30 17:05:08 +02003658 /* SSL_get_peer_certificate, it increase X509 * ref count */
3659 if (cert_peer && crt)
Emeric Brunce5ad802012-10-22 14:11:22 +02003660 X509_free(crt);
3661 return ret;
3662}
3663
Emeric Brunba841a12014-04-30 17:05:08 +02003664/* string, returns a string of a formatted full dn \C=..\O=..\OU=.. \CN=.. of certificate's subject
3665 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
3666 * should be use.
3667 */
Emeric Brun87855892012-10-17 17:39:35 +02003668static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02003669smp_fetch_ssl_x_s_dn(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun87855892012-10-17 17:39:35 +02003670{
Emeric Brunba841a12014-04-30 17:05:08 +02003671 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brun87855892012-10-17 17:39:35 +02003672 X509 *crt = NULL;
3673 X509_NAME *name;
3674 int ret = 0;
3675 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003676 struct connection *conn;
Emeric Brun87855892012-10-17 17:39:35 +02003677
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02003678 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003679 if (!conn || conn->xprt != &ssl_sock)
3680 return 0;
3681
3682 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun87855892012-10-17 17:39:35 +02003683 smp->flags |= SMP_F_MAY_CHANGE;
3684 return 0;
3685 }
3686
Emeric Brunba841a12014-04-30 17:05:08 +02003687 if (cert_peer)
3688 crt = SSL_get_peer_certificate(conn->xprt_ctx);
3689 else
3690 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brun87855892012-10-17 17:39:35 +02003691 if (!crt)
3692 goto out;
3693
3694 name = X509_get_subject_name(crt);
3695 if (!name)
3696 goto out;
3697
Willy Tarreau47ca5452012-12-23 20:22:19 +01003698 smp_trash = get_trash_chunk();
Emeric Brun87855892012-10-17 17:39:35 +02003699 if (args && args[0].type == ARGT_STR) {
3700 int pos = 1;
3701
3702 if (args[1].type == ARGT_SINT)
3703 pos = args[1].data.sint;
3704 else if (args[1].type == ARGT_UINT)
3705 pos =(int)args[1].data.uint;
3706
3707 if (ssl_sock_get_dn_entry(name, &args[0].data.str, pos, smp_trash) <= 0)
3708 goto out;
3709 }
3710 else if (ssl_sock_get_dn_oneline(name, smp_trash) <= 0)
3711 goto out;
3712
3713 smp->type = SMP_T_STR;
3714 smp->data.str = *smp_trash;
3715 ret = 1;
3716out:
Emeric Brunba841a12014-04-30 17:05:08 +02003717 /* SSL_get_peer_certificate, it increase X509 * ref count */
3718 if (cert_peer && crt)
Emeric Brun87855892012-10-17 17:39:35 +02003719 X509_free(crt);
3720 return ret;
3721}
Emeric Brun9143d372012-12-20 15:44:16 +01003722
3723/* integer, returns true if current session use a client certificate */
3724static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02003725smp_fetch_ssl_c_used(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun9143d372012-12-20 15:44:16 +01003726{
3727 X509 *crt;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003728 struct connection *conn;
Emeric Brun9143d372012-12-20 15:44:16 +01003729
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02003730 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003731 if (!conn || conn->xprt != &ssl_sock)
3732 return 0;
3733
3734 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun9143d372012-12-20 15:44:16 +01003735 smp->flags |= SMP_F_MAY_CHANGE;
3736 return 0;
3737 }
3738
3739 /* SSL_get_peer_certificate returns a ptr on allocated X509 struct */
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003740 crt = SSL_get_peer_certificate(conn->xprt_ctx);
Emeric Brun9143d372012-12-20 15:44:16 +01003741 if (crt) {
3742 X509_free(crt);
3743 }
3744
3745 smp->type = SMP_T_BOOL;
3746 smp->data.uint = (crt != NULL);
3747 return 1;
3748}
3749
Emeric Brunba841a12014-04-30 17:05:08 +02003750/* integer, returns the certificate version
3751 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
3752 * should be use.
3753 */
Emeric Bruna7359fd2012-10-17 15:03:11 +02003754static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02003755smp_fetch_ssl_x_version(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Bruna7359fd2012-10-17 15:03:11 +02003756{
Emeric Brunba841a12014-04-30 17:05:08 +02003757 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Bruna7359fd2012-10-17 15:03:11 +02003758 X509 *crt;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003759 struct connection *conn;
3760
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02003761 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003762 if (!conn || conn->xprt != &ssl_sock)
Emeric Bruna7359fd2012-10-17 15:03:11 +02003763 return 0;
3764
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003765 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Bruna7359fd2012-10-17 15:03:11 +02003766 smp->flags |= SMP_F_MAY_CHANGE;
3767 return 0;
3768 }
3769
Emeric Brunba841a12014-04-30 17:05:08 +02003770 if (cert_peer)
3771 crt = SSL_get_peer_certificate(conn->xprt_ctx);
3772 else
3773 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Bruna7359fd2012-10-17 15:03:11 +02003774 if (!crt)
3775 return 0;
3776
3777 smp->data.uint = (unsigned int)(1 + X509_get_version(crt));
Emeric Brunba841a12014-04-30 17:05:08 +02003778 /* SSL_get_peer_certificate increase X509 * ref count */
3779 if (cert_peer)
3780 X509_free(crt);
Emeric Bruna7359fd2012-10-17 15:03:11 +02003781 smp->type = SMP_T_UINT;
3782
3783 return 1;
3784}
3785
Emeric Brunba841a12014-04-30 17:05:08 +02003786/* string, returns the certificate's signature algorithm.
3787 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
3788 * should be use.
3789 */
Emeric Brun7f56e742012-10-19 18:15:40 +02003790static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02003791smp_fetch_ssl_x_sig_alg(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun7f56e742012-10-19 18:15:40 +02003792{
Emeric Brunba841a12014-04-30 17:05:08 +02003793 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brun7f56e742012-10-19 18:15:40 +02003794 X509 *crt;
3795 int nid;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003796 struct connection *conn;
Emeric Brun7f56e742012-10-19 18:15:40 +02003797
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02003798 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003799 if (!conn || conn->xprt != &ssl_sock)
3800 return 0;
3801
3802 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun7f56e742012-10-19 18:15:40 +02003803 smp->flags |= SMP_F_MAY_CHANGE;
3804 return 0;
3805 }
3806
Emeric Brunba841a12014-04-30 17:05:08 +02003807 if (cert_peer)
3808 crt = SSL_get_peer_certificate(conn->xprt_ctx);
3809 else
3810 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brun7f56e742012-10-19 18:15:40 +02003811 if (!crt)
3812 return 0;
3813
3814 nid = OBJ_obj2nid((ASN1_OBJECT *)(crt->cert_info->signature->algorithm));
3815
3816 smp->data.str.str = (char *)OBJ_nid2sn(nid);
Emeric Brun9bf3ba22013-10-07 14:31:44 +02003817 if (!smp->data.str.str) {
Emeric Brunba841a12014-04-30 17:05:08 +02003818 /* SSL_get_peer_certificate increase X509 * ref count */
3819 if (cert_peer)
3820 X509_free(crt);
Emeric Brun7f56e742012-10-19 18:15:40 +02003821 return 0;
Emeric Brun9bf3ba22013-10-07 14:31:44 +02003822 }
Emeric Brun7f56e742012-10-19 18:15:40 +02003823
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01003824 smp->type = SMP_T_STR;
3825 smp->flags |= SMP_F_CONST;
Emeric Brun7f56e742012-10-19 18:15:40 +02003826 smp->data.str.len = strlen(smp->data.str.str);
Emeric Brunba841a12014-04-30 17:05:08 +02003827 /* SSL_get_peer_certificate increase X509 * ref count */
3828 if (cert_peer)
3829 X509_free(crt);
Emeric Brun7f56e742012-10-19 18:15:40 +02003830
3831 return 1;
3832}
3833
Emeric Brunba841a12014-04-30 17:05:08 +02003834/* string, returns the certificate's key algorithm.
3835 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
3836 * should be use.
3837 */
Emeric Brun521a0112012-10-22 12:22:55 +02003838static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02003839smp_fetch_ssl_x_key_alg(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun521a0112012-10-22 12:22:55 +02003840{
Emeric Brunba841a12014-04-30 17:05:08 +02003841 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brun521a0112012-10-22 12:22:55 +02003842 X509 *crt;
3843 int nid;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003844 struct connection *conn;
Emeric Brun521a0112012-10-22 12:22:55 +02003845
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02003846 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003847 if (!conn || conn->xprt != &ssl_sock)
3848 return 0;
3849
3850 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun521a0112012-10-22 12:22:55 +02003851 smp->flags |= SMP_F_MAY_CHANGE;
3852 return 0;
3853 }
3854
Emeric Brunba841a12014-04-30 17:05:08 +02003855 if (cert_peer)
3856 crt = SSL_get_peer_certificate(conn->xprt_ctx);
3857 else
3858 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brun521a0112012-10-22 12:22:55 +02003859 if (!crt)
3860 return 0;
3861
3862 nid = OBJ_obj2nid((ASN1_OBJECT *)(crt->cert_info->key->algor->algorithm));
3863
3864 smp->data.str.str = (char *)OBJ_nid2sn(nid);
Emeric Brun9bf3ba22013-10-07 14:31:44 +02003865 if (!smp->data.str.str) {
Emeric Brunba841a12014-04-30 17:05:08 +02003866 /* SSL_get_peer_certificate increase X509 * ref count */
3867 if (cert_peer)
3868 X509_free(crt);
Emeric Brun521a0112012-10-22 12:22:55 +02003869 return 0;
Emeric Brun9bf3ba22013-10-07 14:31:44 +02003870 }
Emeric Brun521a0112012-10-22 12:22:55 +02003871
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01003872 smp->type = SMP_T_STR;
3873 smp->flags |= SMP_F_CONST;
Emeric Brun521a0112012-10-22 12:22:55 +02003874 smp->data.str.len = strlen(smp->data.str.str);
Emeric Brunba841a12014-04-30 17:05:08 +02003875 if (cert_peer)
3876 X509_free(crt);
Emeric Brun521a0112012-10-22 12:22:55 +02003877
3878 return 1;
3879}
3880
Emeric Brun645ae792014-04-30 14:21:06 +02003881/* boolean, returns true if front conn. transport layer is SSL.
3882 * This function is also usable on backend conn if the fetch keyword 5th
3883 * char is 'b'.
3884 */
Willy Tarreau7875d092012-09-10 08:20:03 +02003885static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02003886smp_fetch_ssl_fc(const struct arg *args, struct sample *smp, const char *kw, void *private)
Willy Tarreau7875d092012-09-10 08:20:03 +02003887{
Emeric Brun645ae792014-04-30 14:21:06 +02003888 int back_conn = (kw[4] == 'b') ? 1 : 0;
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02003889 struct connection *conn = objt_conn(smp->strm->si[back_conn].end);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003890
Willy Tarreau7875d092012-09-10 08:20:03 +02003891 smp->type = SMP_T_BOOL;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003892 smp->data.uint = (conn && conn->xprt == &ssl_sock);
Willy Tarreau7875d092012-09-10 08:20:03 +02003893 return 1;
3894}
3895
Emeric Brun2525b6b2012-10-18 15:59:43 +02003896/* boolean, returns true if client present a SNI */
Willy Tarreau7875d092012-09-10 08:20:03 +02003897static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02003898smp_fetch_ssl_fc_has_sni(const struct arg *args, struct sample *smp, const char *kw, void *private)
Willy Tarreau7875d092012-09-10 08:20:03 +02003899{
3900#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02003901 struct connection *conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003902
Willy Tarreau7875d092012-09-10 08:20:03 +02003903 smp->type = SMP_T_BOOL;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003904 smp->data.uint = (conn && conn->xprt == &ssl_sock) &&
3905 conn->xprt_ctx &&
3906 SSL_get_servername(conn->xprt_ctx, TLSEXT_NAMETYPE_host_name) != NULL;
Willy Tarreau7875d092012-09-10 08:20:03 +02003907 return 1;
3908#else
3909 return 0;
3910#endif
3911}
3912
Nenad Merdanovic26ea8222015-05-18 02:28:57 +02003913/* boolean, returns true if client session has been resumed */
3914static int
3915smp_fetch_ssl_fc_is_resumed(const struct arg *args, struct sample *smp, const char *kw, void *private)
3916{
3917 struct connection *conn = objt_conn(smp->sess->origin);
3918
3919 smp->type = SMP_T_BOOL;
3920 smp->data.uint = (conn && conn->xprt == &ssl_sock) &&
3921 conn->xprt_ctx &&
3922 SSL_session_reused(conn->xprt_ctx);
3923 return 1;
3924}
3925
Emeric Brun645ae792014-04-30 14:21:06 +02003926/* string, returns the used cipher if front conn. transport layer is SSL.
3927 * This function is also usable on backend conn if the fetch keyword 5th
3928 * char is 'b'.
3929 */
Emeric Brun589fcad2012-10-16 14:13:26 +02003930static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02003931smp_fetch_ssl_fc_cipher(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun589fcad2012-10-16 14:13:26 +02003932{
Emeric Brun645ae792014-04-30 14:21:06 +02003933 int back_conn = (kw[4] == 'b') ? 1 : 0;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003934 struct connection *conn;
3935
Emeric Brun589fcad2012-10-16 14:13:26 +02003936 smp->flags = 0;
3937
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02003938 conn = objt_conn(smp->strm->si[back_conn].end);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003939 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
Emeric Brun589fcad2012-10-16 14:13:26 +02003940 return 0;
3941
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003942 smp->data.str.str = (char *)SSL_get_cipher_name(conn->xprt_ctx);
Emeric Brun589fcad2012-10-16 14:13:26 +02003943 if (!smp->data.str.str)
3944 return 0;
3945
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01003946 smp->type = SMP_T_STR;
3947 smp->flags |= SMP_F_CONST;
Emeric Brun589fcad2012-10-16 14:13:26 +02003948 smp->data.str.len = strlen(smp->data.str.str);
3949
3950 return 1;
3951}
3952
Emeric Brun645ae792014-04-30 14:21:06 +02003953/* integer, returns the algoritm's keysize if front conn. transport layer
3954 * is SSL.
3955 * This function is also usable on backend conn if the fetch keyword 5th
3956 * char is 'b'.
3957 */
Emeric Brun589fcad2012-10-16 14:13:26 +02003958static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02003959smp_fetch_ssl_fc_alg_keysize(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun589fcad2012-10-16 14:13:26 +02003960{
Emeric Brun645ae792014-04-30 14:21:06 +02003961 int back_conn = (kw[4] == 'b') ? 1 : 0;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003962 struct connection *conn;
3963
Emeric Brun589fcad2012-10-16 14:13:26 +02003964 smp->flags = 0;
3965
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02003966 conn = objt_conn(smp->strm->si[back_conn].end);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003967 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
Emeric Brun589fcad2012-10-16 14:13:26 +02003968 return 0;
3969
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003970 if (!SSL_get_cipher_bits(conn->xprt_ctx, (int *)&smp->data.uint))
3971 return 0;
3972
Emeric Brun589fcad2012-10-16 14:13:26 +02003973 smp->type = SMP_T_UINT;
3974
3975 return 1;
3976}
3977
Emeric Brun645ae792014-04-30 14:21:06 +02003978/* integer, returns the used keysize if front conn. transport layer is SSL.
3979 * This function is also usable on backend conn if the fetch keyword 5th
3980 * char is 'b'.
3981 */
Emeric Brun589fcad2012-10-16 14:13:26 +02003982static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02003983smp_fetch_ssl_fc_use_keysize(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun589fcad2012-10-16 14:13:26 +02003984{
Emeric Brun645ae792014-04-30 14:21:06 +02003985 int back_conn = (kw[4] == 'b') ? 1 : 0;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003986 struct connection *conn;
3987
Emeric Brun589fcad2012-10-16 14:13:26 +02003988 smp->flags = 0;
3989
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02003990 conn = objt_conn(smp->strm->si[back_conn].end);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003991 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
3992 return 0;
3993
3994 smp->data.uint = (unsigned int)SSL_get_cipher_bits(conn->xprt_ctx, NULL);
Emeric Brun589fcad2012-10-16 14:13:26 +02003995 if (!smp->data.uint)
3996 return 0;
3997
3998 smp->type = SMP_T_UINT;
3999
4000 return 1;
4001}
4002
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02004003#ifdef OPENSSL_NPN_NEGOTIATED
Willy Tarreau7875d092012-09-10 08:20:03 +02004004static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004005smp_fetch_ssl_fc_npn(const struct arg *args, struct sample *smp, const char *kw, void *private)
Willy Tarreaua33c6542012-10-15 13:19:06 +02004006{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004007 struct connection *conn;
4008
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01004009 smp->flags = SMP_F_CONST;
4010 smp->type = SMP_T_STR;
Willy Tarreaua33c6542012-10-15 13:19:06 +02004011
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004012 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004013 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
4014 return 0;
4015
Willy Tarreaua33c6542012-10-15 13:19:06 +02004016 smp->data.str.str = NULL;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004017 SSL_get0_next_proto_negotiated(conn->xprt_ctx,
Willy Tarreaua33c6542012-10-15 13:19:06 +02004018 (const unsigned char **)&smp->data.str.str, (unsigned *)&smp->data.str.len);
4019
4020 if (!smp->data.str.str)
4021 return 0;
4022
4023 return 1;
Willy Tarreaua33c6542012-10-15 13:19:06 +02004024}
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02004025#endif
Willy Tarreaua33c6542012-10-15 13:19:06 +02004026
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01004027#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Willy Tarreauab861d32013-04-02 02:30:41 +02004028static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004029smp_fetch_ssl_fc_alpn(const struct arg *args, struct sample *smp, const char *kw, void *private)
Willy Tarreauab861d32013-04-02 02:30:41 +02004030{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004031 struct connection *conn;
4032
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01004033 smp->flags = SMP_F_CONST;
4034 smp->type = SMP_T_STR;
Willy Tarreauab861d32013-04-02 02:30:41 +02004035
Willy Tarreaue26bf052015-05-12 10:30:12 +02004036 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004037 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
Willy Tarreauab861d32013-04-02 02:30:41 +02004038 return 0;
4039
4040 smp->data.str.str = NULL;
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01004041 SSL_get0_alpn_selected(conn->xprt_ctx,
Willy Tarreauab861d32013-04-02 02:30:41 +02004042 (const unsigned char **)&smp->data.str.str, (unsigned *)&smp->data.str.len);
4043
4044 if (!smp->data.str.str)
4045 return 0;
4046
4047 return 1;
4048}
4049#endif
4050
Emeric Brun645ae792014-04-30 14:21:06 +02004051/* string, returns the used protocol if front conn. transport layer is SSL.
4052 * This function is also usable on backend conn if the fetch keyword 5th
4053 * char is 'b'.
4054 */
Willy Tarreaua33c6542012-10-15 13:19:06 +02004055static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004056smp_fetch_ssl_fc_protocol(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun589fcad2012-10-16 14:13:26 +02004057{
Emeric Brun645ae792014-04-30 14:21:06 +02004058 int back_conn = (kw[4] == 'b') ? 1 : 0;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004059 struct connection *conn;
4060
Emeric Brun589fcad2012-10-16 14:13:26 +02004061 smp->flags = 0;
4062
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004063 conn = objt_conn(smp->strm->si[back_conn].end);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004064 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
4065 return 0;
4066
4067 smp->data.str.str = (char *)SSL_get_version(conn->xprt_ctx);
Emeric Brun589fcad2012-10-16 14:13:26 +02004068 if (!smp->data.str.str)
4069 return 0;
4070
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01004071 smp->type = SMP_T_STR;
4072 smp->flags = SMP_F_CONST;
Emeric Brun589fcad2012-10-16 14:13:26 +02004073 smp->data.str.len = strlen(smp->data.str.str);
4074
4075 return 1;
4076}
4077
Willy Tarreau87b09662015-04-03 00:22:06 +02004078/* binary, returns the SSL stream id if front conn. transport layer is SSL.
Emeric Brun645ae792014-04-30 14:21:06 +02004079 * This function is also usable on backend conn if the fetch keyword 5th
4080 * char is 'b'.
4081 */
Emeric Brun589fcad2012-10-16 14:13:26 +02004082static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004083smp_fetch_ssl_fc_session_id(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brunfe68f682012-10-16 14:59:28 +02004084{
4085#if OPENSSL_VERSION_NUMBER > 0x0090800fL
Emeric Brun645ae792014-04-30 14:21:06 +02004086 int back_conn = (kw[4] == 'b') ? 1 : 0;
Willy Tarreau192252e2015-04-04 01:47:55 +02004087 SSL_SESSION *ssl_sess;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004088 struct connection *conn;
Emeric Brunfe68f682012-10-16 14:59:28 +02004089
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01004090 smp->flags = SMP_F_CONST;
4091 smp->type = SMP_T_BIN;
Emeric Brunfe68f682012-10-16 14:59:28 +02004092
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004093 conn = objt_conn(smp->strm->si[back_conn].end);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004094 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
4095 return 0;
4096
Willy Tarreau192252e2015-04-04 01:47:55 +02004097 ssl_sess = SSL_get_session(conn->xprt_ctx);
4098 if (!ssl_sess)
Emeric Brunfe68f682012-10-16 14:59:28 +02004099 return 0;
4100
Willy Tarreau192252e2015-04-04 01:47:55 +02004101 smp->data.str.str = (char *)SSL_SESSION_get_id(ssl_sess, (unsigned int *)&smp->data.str.len);
Emeric Brunfe68f682012-10-16 14:59:28 +02004102 if (!smp->data.str.str || !&smp->data.str.len)
4103 return 0;
4104
4105 return 1;
4106#else
4107 return 0;
4108#endif
4109}
4110
4111static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004112smp_fetch_ssl_fc_sni(const struct arg *args, struct sample *smp, const char *kw, void *private)
Willy Tarreau7875d092012-09-10 08:20:03 +02004113{
4114#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004115 struct connection *conn;
4116
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01004117 smp->flags = SMP_F_CONST;
4118 smp->type = SMP_T_STR;
Willy Tarreau7875d092012-09-10 08:20:03 +02004119
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004120 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004121 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
4122 return 0;
4123
4124 smp->data.str.str = (char *)SSL_get_servername(conn->xprt_ctx, TLSEXT_NAMETYPE_host_name);
Willy Tarreau3e394c92012-09-14 23:56:58 +02004125 if (!smp->data.str.str)
4126 return 0;
4127
Willy Tarreau7875d092012-09-10 08:20:03 +02004128 smp->data.str.len = strlen(smp->data.str.str);
4129 return 1;
4130#else
4131 return 0;
4132#endif
4133}
4134
David Sc1ad52e2014-04-08 18:48:47 -04004135static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004136smp_fetch_ssl_fc_unique_id(const struct arg *args, struct sample *smp, const char *kw, void *private)
David Sc1ad52e2014-04-08 18:48:47 -04004137{
4138#if OPENSSL_VERSION_NUMBER > 0x0090800fL
Emeric Brun645ae792014-04-30 14:21:06 +02004139 int back_conn = (kw[4] == 'b') ? 1 : 0;
David Sc1ad52e2014-04-08 18:48:47 -04004140 struct connection *conn;
4141 int finished_len;
David Sc1ad52e2014-04-08 18:48:47 -04004142 struct chunk *finished_trash;
David Sc1ad52e2014-04-08 18:48:47 -04004143
4144 smp->flags = 0;
4145
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004146 conn = objt_conn(smp->strm->si[back_conn].end);
David Sc1ad52e2014-04-08 18:48:47 -04004147 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
4148 return 0;
4149
4150 if (!(conn->flags & CO_FL_CONNECTED)) {
4151 smp->flags |= SMP_F_MAY_CHANGE;
4152 return 0;
4153 }
4154
4155 finished_trash = get_trash_chunk();
4156 if (!SSL_session_reused(conn->xprt_ctx))
4157 finished_len = SSL_get_peer_finished(conn->xprt_ctx, finished_trash->str, finished_trash->size);
4158 else
4159 finished_len = SSL_get_finished(conn->xprt_ctx, finished_trash->str, finished_trash->size);
4160
4161 if (!finished_len)
4162 return 0;
4163
Emeric Brunb73a9b02014-04-30 18:49:19 +02004164 finished_trash->len = finished_len;
4165 smp->data.str = *finished_trash;
4166 smp->type = SMP_T_BIN;
David Sc1ad52e2014-04-08 18:48:47 -04004167
4168 return 1;
4169#else
4170 return 0;
4171#endif
4172}
4173
Emeric Brun2525b6b2012-10-18 15:59:43 +02004174/* integer, returns the first verify error in CA chain of client certificate chain. */
Emeric Brunf282a812012-09-21 15:27:54 +02004175static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004176smp_fetch_ssl_c_ca_err(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brunf282a812012-09-21 15:27:54 +02004177{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004178 struct connection *conn;
4179
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004180 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004181 if (!conn || conn->xprt != &ssl_sock)
4182 return 0;
4183
4184 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunf282a812012-09-21 15:27:54 +02004185 smp->flags = SMP_F_MAY_CHANGE;
4186 return 0;
4187 }
4188
4189 smp->type = SMP_T_UINT;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004190 smp->data.uint = (unsigned int)SSL_SOCK_ST_TO_CA_ERROR(conn->xprt_st);
Emeric Brunf282a812012-09-21 15:27:54 +02004191 smp->flags = 0;
4192
4193 return 1;
4194}
4195
Emeric Brun2525b6b2012-10-18 15:59:43 +02004196/* integer, returns the depth of the first verify error in CA chain of client certificate chain. */
Emeric Brunf282a812012-09-21 15:27:54 +02004197static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004198smp_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 +02004199{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004200 struct connection *conn;
4201
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004202 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004203 if (!conn || conn->xprt != &ssl_sock)
Emeric Brunf282a812012-09-21 15:27:54 +02004204 return 0;
4205
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004206 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunf282a812012-09-21 15:27:54 +02004207 smp->flags = SMP_F_MAY_CHANGE;
4208 return 0;
4209 }
4210
4211 smp->type = SMP_T_UINT;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004212 smp->data.uint = (unsigned int)SSL_SOCK_ST_TO_CAEDEPTH(conn->xprt_st);
Emeric Brunf282a812012-09-21 15:27:54 +02004213 smp->flags = 0;
4214
4215 return 1;
4216}
4217
Emeric Brun2525b6b2012-10-18 15:59:43 +02004218/* integer, returns the first verify error on client certificate */
Emeric Brunf282a812012-09-21 15:27:54 +02004219static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004220smp_fetch_ssl_c_err(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brunf282a812012-09-21 15:27:54 +02004221{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004222 struct connection *conn;
4223
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004224 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004225 if (!conn || conn->xprt != &ssl_sock)
4226 return 0;
4227
4228 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunf282a812012-09-21 15:27:54 +02004229 smp->flags = SMP_F_MAY_CHANGE;
4230 return 0;
4231 }
4232
4233 smp->type = SMP_T_UINT;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004234 smp->data.uint = (unsigned int)SSL_SOCK_ST_TO_CRTERROR(conn->xprt_st);
Emeric Brunf282a812012-09-21 15:27:54 +02004235 smp->flags = 0;
4236
4237 return 1;
4238}
4239
Emeric Brun2525b6b2012-10-18 15:59:43 +02004240/* integer, returns the verify result on client cert */
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02004241static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004242smp_fetch_ssl_c_verify(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02004243{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004244 struct connection *conn;
4245
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004246 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004247 if (!conn || conn->xprt != &ssl_sock)
4248 return 0;
4249
4250 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02004251 smp->flags = SMP_F_MAY_CHANGE;
4252 return 0;
4253 }
4254
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004255 if (!conn->xprt_ctx)
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02004256 return 0;
4257
4258 smp->type = SMP_T_UINT;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004259 smp->data.uint = (unsigned int)SSL_get_verify_result(conn->xprt_ctx);
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02004260 smp->flags = 0;
4261
4262 return 1;
4263}
4264
Emeric Brunfb510ea2012-10-05 12:00:26 +02004265/* parse the "ca-file" bind keyword */
4266static 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 +02004267{
4268 if (!*args[cur_arg + 1]) {
4269 if (err)
4270 memprintf(err, "'%s' : missing CAfile path", args[cur_arg]);
4271 return ERR_ALERT | ERR_FATAL;
4272 }
4273
Emeric Brunef42d922012-10-11 16:11:36 +02004274 if ((*args[cur_arg + 1] != '/') && global.ca_base)
4275 memprintf(&conf->ca_file, "%s/%s", global.ca_base, args[cur_arg + 1]);
4276 else
4277 memprintf(&conf->ca_file, "%s", args[cur_arg + 1]);
Emeric Brunc8e8d122012-10-02 18:42:10 +02004278
Emeric Brund94b3fe2012-09-20 18:23:56 +02004279 return 0;
4280}
4281
Christopher Faulet31af49d2015-06-09 17:29:50 +02004282/* parse the "ca-sign-file" bind keyword */
4283static int bind_parse_ca_sign_file(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
4284{
4285 if (!*args[cur_arg + 1]) {
4286 if (err)
4287 memprintf(err, "'%s' : missing CAfile path", args[cur_arg]);
4288 return ERR_ALERT | ERR_FATAL;
4289 }
4290
4291 if ((*args[cur_arg + 1] != '/') && global.ca_base)
4292 memprintf(&conf->ca_sign_file, "%s/%s", global.ca_base, args[cur_arg + 1]);
4293 else
4294 memprintf(&conf->ca_sign_file, "%s", args[cur_arg + 1]);
4295
4296 return 0;
4297}
4298
4299/* parse the ca-sign-pass bind keyword */
4300
4301static int bind_parse_ca_sign_pass(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
4302{
4303 if (!*args[cur_arg + 1]) {
4304 if (err)
4305 memprintf(err, "'%s' : missing CAkey password", args[cur_arg]);
4306 return ERR_ALERT | ERR_FATAL;
4307 }
4308 memprintf(&conf->ca_sign_pass, "%s", args[cur_arg + 1]);
4309 return 0;
4310}
4311
Willy Tarreau79eeafa2012-09-14 07:53:05 +02004312/* parse the "ciphers" bind keyword */
Willy Tarreau4348fad2012-09-20 16:48:07 +02004313static 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 +02004314{
4315 if (!*args[cur_arg + 1]) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02004316 memprintf(err, "'%s' : missing cipher suite", args[cur_arg]);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02004317 return ERR_ALERT | ERR_FATAL;
4318 }
4319
Emeric Brun76d88952012-10-05 15:47:31 +02004320 free(conf->ciphers);
Willy Tarreau4348fad2012-09-20 16:48:07 +02004321 conf->ciphers = strdup(args[cur_arg + 1]);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02004322 return 0;
4323}
4324
4325/* parse the "crt" bind keyword */
Willy Tarreau4348fad2012-09-20 16:48:07 +02004326static 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 +02004327{
Willy Tarreau38011032013-08-13 16:59:39 +02004328 char path[MAXPATHLEN];
Willy Tarreaub75d6922014-04-14 18:05:41 +02004329
Willy Tarreau79eeafa2012-09-14 07:53:05 +02004330 if (!*args[cur_arg + 1]) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02004331 memprintf(err, "'%s' : missing certificate location", args[cur_arg]);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02004332 return ERR_ALERT | ERR_FATAL;
4333 }
4334
Emeric Brunc8e8d122012-10-02 18:42:10 +02004335 if ((*args[cur_arg + 1] != '/' ) && global.crt_base) {
Willy Tarreau38011032013-08-13 16:59:39 +02004336 if ((strlen(global.crt_base) + 1 + strlen(args[cur_arg + 1]) + 1) > MAXPATHLEN) {
Emeric Brunc8e8d122012-10-02 18:42:10 +02004337 memprintf(err, "'%s' : path too long", args[cur_arg]);
4338 return ERR_ALERT | ERR_FATAL;
4339 }
Willy Tarreaub75d6922014-04-14 18:05:41 +02004340 snprintf(path, sizeof(path), "%s/%s", global.crt_base, args[cur_arg + 1]);
Emeric Brunc8e8d122012-10-02 18:42:10 +02004341 if (ssl_sock_load_cert(path, conf, px, err) > 0)
4342 return ERR_ALERT | ERR_FATAL;
4343
4344 return 0;
4345 }
4346
Willy Tarreau4348fad2012-09-20 16:48:07 +02004347 if (ssl_sock_load_cert(args[cur_arg + 1], conf, px, err) > 0)
Willy Tarreau79eeafa2012-09-14 07:53:05 +02004348 return ERR_ALERT | ERR_FATAL;
Emeric Brund94b3fe2012-09-20 18:23:56 +02004349
4350 return 0;
4351}
4352
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01004353/* parse the "crt-list" bind keyword */
4354static int bind_parse_crt_list(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
4355{
4356 if (!*args[cur_arg + 1]) {
4357 memprintf(err, "'%s' : missing certificate location", args[cur_arg]);
4358 return ERR_ALERT | ERR_FATAL;
4359 }
4360
Willy Tarreauad1731d2013-04-02 17:35:58 +02004361 if (ssl_sock_load_cert_list_file(args[cur_arg + 1], conf, px, err) > 0) {
4362 memprintf(err, "'%s' : %s", args[cur_arg], *err);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01004363 return ERR_ALERT | ERR_FATAL;
Willy Tarreauad1731d2013-04-02 17:35:58 +02004364 }
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01004365
4366 return 0;
4367}
4368
Emeric Brunfb510ea2012-10-05 12:00:26 +02004369/* parse the "crl-file" bind keyword */
4370static 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 +02004371{
Emeric Brun051cdab2012-10-02 19:25:50 +02004372#ifndef X509_V_FLAG_CRL_CHECK
4373 if (err)
4374 memprintf(err, "'%s' : library does not support CRL verify", args[cur_arg]);
4375 return ERR_ALERT | ERR_FATAL;
4376#else
Emeric Brund94b3fe2012-09-20 18:23:56 +02004377 if (!*args[cur_arg + 1]) {
4378 if (err)
4379 memprintf(err, "'%s' : missing CRLfile path", args[cur_arg]);
4380 return ERR_ALERT | ERR_FATAL;
4381 }
Emeric Brun2b58d042012-09-20 17:10:03 +02004382
Emeric Brunef42d922012-10-11 16:11:36 +02004383 if ((*args[cur_arg + 1] != '/') && global.ca_base)
4384 memprintf(&conf->crl_file, "%s/%s", global.ca_base, args[cur_arg + 1]);
4385 else
4386 memprintf(&conf->crl_file, "%s", args[cur_arg + 1]);
Emeric Brunc8e8d122012-10-02 18:42:10 +02004387
Emeric Brun2b58d042012-09-20 17:10:03 +02004388 return 0;
Emeric Brun051cdab2012-10-02 19:25:50 +02004389#endif
Emeric Brun2b58d042012-09-20 17:10:03 +02004390}
4391
4392/* parse the "ecdhe" bind keyword keywords */
4393static int bind_parse_ecdhe(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
4394{
4395#if OPENSSL_VERSION_NUMBER < 0x0090800fL
4396 if (err)
4397 memprintf(err, "'%s' : library does not support elliptic curve Diffie-Hellman (too old)", args[cur_arg]);
4398 return ERR_ALERT | ERR_FATAL;
4399#elif defined(OPENSSL_NO_ECDH)
4400 if (err)
4401 memprintf(err, "'%s' : library does not support elliptic curve Diffie-Hellman (disabled via OPENSSL_NO_ECDH)", args[cur_arg]);
4402 return ERR_ALERT | ERR_FATAL;
4403#else
4404 if (!*args[cur_arg + 1]) {
4405 if (err)
4406 memprintf(err, "'%s' : missing named curve", args[cur_arg]);
4407 return ERR_ALERT | ERR_FATAL;
4408 }
4409
4410 conf->ecdhe = strdup(args[cur_arg + 1]);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02004411
4412 return 0;
Emeric Brun2b58d042012-09-20 17:10:03 +02004413#endif
Willy Tarreau79eeafa2012-09-14 07:53:05 +02004414}
4415
Emeric Brun81c00f02012-09-21 14:31:21 +02004416/* parse the "crt_ignerr" and "ca_ignerr" bind keywords */
4417static int bind_parse_ignore_err(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
4418{
4419 int code;
4420 char *p = args[cur_arg + 1];
4421 unsigned long long *ignerr = &conf->crt_ignerr;
4422
4423 if (!*p) {
4424 if (err)
4425 memprintf(err, "'%s' : missing error IDs list", args[cur_arg]);
4426 return ERR_ALERT | ERR_FATAL;
4427 }
4428
4429 if (strcmp(args[cur_arg], "ca-ignore-err") == 0)
4430 ignerr = &conf->ca_ignerr;
4431
4432 if (strcmp(p, "all") == 0) {
4433 *ignerr = ~0ULL;
4434 return 0;
4435 }
4436
4437 while (p) {
4438 code = atoi(p);
4439 if ((code <= 0) || (code > 63)) {
4440 if (err)
4441 memprintf(err, "'%s' : ID '%d' out of range (1..63) in error IDs list '%s'",
4442 args[cur_arg], code, args[cur_arg + 1]);
4443 return ERR_ALERT | ERR_FATAL;
4444 }
4445 *ignerr |= 1ULL << code;
4446 p = strchr(p, ',');
4447 if (p)
4448 p++;
4449 }
4450
Emeric Brun2cb7ae52012-10-05 14:14:21 +02004451 return 0;
4452}
4453
4454/* parse the "force-sslv3" bind keyword */
4455static int bind_parse_force_sslv3(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
4456{
4457 conf->ssl_options |= BC_SSL_O_USE_SSLV3;
4458 return 0;
4459}
4460
4461/* parse the "force-tlsv10" bind keyword */
4462static int bind_parse_force_tlsv10(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
4463{
4464 conf->ssl_options |= BC_SSL_O_USE_TLSV10;
Emeric Brun2d0c4822012-10-02 13:45:20 +02004465 return 0;
4466}
4467
Emeric Brun2cb7ae52012-10-05 14:14:21 +02004468/* parse the "force-tlsv11" bind keyword */
4469static int bind_parse_force_tlsv11(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
4470{
4471#if SSL_OP_NO_TLSv1_1
4472 conf->ssl_options |= BC_SSL_O_USE_TLSV11;
4473 return 0;
4474#else
4475 if (err)
4476 memprintf(err, "'%s' : library does not support protocol TLSv1.1", args[cur_arg]);
4477 return ERR_ALERT | ERR_FATAL;
4478#endif
4479}
4480
4481/* parse the "force-tlsv12" bind keyword */
4482static int bind_parse_force_tlsv12(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
4483{
4484#if SSL_OP_NO_TLSv1_2
4485 conf->ssl_options |= BC_SSL_O_USE_TLSV12;
4486 return 0;
4487#else
4488 if (err)
4489 memprintf(err, "'%s' : library does not support protocol TLSv1.2", args[cur_arg]);
4490 return ERR_ALERT | ERR_FATAL;
4491#endif
4492}
4493
4494
Emeric Brun2d0c4822012-10-02 13:45:20 +02004495/* parse the "no-tls-tickets" bind keyword */
4496static int bind_parse_no_tls_tickets(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
4497{
Emeric Brun89675492012-10-05 13:48:26 +02004498 conf->ssl_options |= BC_SSL_O_NO_TLS_TICKETS;
Emeric Brun81c00f02012-09-21 14:31:21 +02004499 return 0;
4500}
4501
Emeric Brun2d0c4822012-10-02 13:45:20 +02004502
Emeric Brun9b3009b2012-10-05 11:55:06 +02004503/* parse the "no-sslv3" bind keyword */
4504static 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 +02004505{
Emeric Brun89675492012-10-05 13:48:26 +02004506 conf->ssl_options |= BC_SSL_O_NO_SSLV3;
Willy Tarreau79eeafa2012-09-14 07:53:05 +02004507 return 0;
4508}
4509
Emeric Brun9b3009b2012-10-05 11:55:06 +02004510/* parse the "no-tlsv10" bind keyword */
4511static 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 +02004512{
Emeric Brun89675492012-10-05 13:48:26 +02004513 conf->ssl_options |= BC_SSL_O_NO_TLSV10;
Emeric Brunc0ff4922012-09-28 19:37:02 +02004514 return 0;
4515}
4516
Emeric Brun9b3009b2012-10-05 11:55:06 +02004517/* parse the "no-tlsv11" bind keyword */
4518static 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 +02004519{
Emeric Brun89675492012-10-05 13:48:26 +02004520 conf->ssl_options |= BC_SSL_O_NO_TLSV11;
Emeric Brunc0ff4922012-09-28 19:37:02 +02004521 return 0;
4522}
4523
Emeric Brun9b3009b2012-10-05 11:55:06 +02004524/* parse the "no-tlsv12" bind keyword */
4525static 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 +02004526{
Emeric Brun89675492012-10-05 13:48:26 +02004527 conf->ssl_options |= BC_SSL_O_NO_TLSV12;
Willy Tarreau79eeafa2012-09-14 07:53:05 +02004528 return 0;
4529}
4530
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02004531/* parse the "npn" bind keyword */
4532static int bind_parse_npn(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
4533{
4534#ifdef OPENSSL_NPN_NEGOTIATED
4535 char *p1, *p2;
4536
4537 if (!*args[cur_arg + 1]) {
4538 memprintf(err, "'%s' : missing the comma-delimited NPN protocol suite", args[cur_arg]);
4539 return ERR_ALERT | ERR_FATAL;
4540 }
4541
4542 free(conf->npn_str);
4543
4544 /* the NPN string is built as a suite of (<len> <name>)* */
4545 conf->npn_len = strlen(args[cur_arg + 1]) + 1;
4546 conf->npn_str = calloc(1, conf->npn_len);
4547 memcpy(conf->npn_str + 1, args[cur_arg + 1], conf->npn_len);
4548
4549 /* replace commas with the name length */
4550 p1 = conf->npn_str;
4551 p2 = p1 + 1;
4552 while (1) {
4553 p2 = memchr(p1 + 1, ',', conf->npn_str + conf->npn_len - (p1 + 1));
4554 if (!p2)
4555 p2 = p1 + 1 + strlen(p1 + 1);
4556
4557 if (p2 - (p1 + 1) > 255) {
4558 *p2 = '\0';
4559 memprintf(err, "'%s' : NPN protocol name too long : '%s'", args[cur_arg], p1 + 1);
4560 return ERR_ALERT | ERR_FATAL;
4561 }
4562
4563 *p1 = p2 - (p1 + 1);
4564 p1 = p2;
4565
4566 if (!*p2)
4567 break;
4568
4569 *(p2++) = '\0';
4570 }
4571 return 0;
4572#else
4573 if (err)
4574 memprintf(err, "'%s' : library does not support TLS NPN extension", args[cur_arg]);
4575 return ERR_ALERT | ERR_FATAL;
4576#endif
4577}
4578
Willy Tarreauab861d32013-04-02 02:30:41 +02004579/* parse the "alpn" bind keyword */
4580static int bind_parse_alpn(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
4581{
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01004582#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Willy Tarreauab861d32013-04-02 02:30:41 +02004583 char *p1, *p2;
4584
4585 if (!*args[cur_arg + 1]) {
4586 memprintf(err, "'%s' : missing the comma-delimited ALPN protocol suite", args[cur_arg]);
4587 return ERR_ALERT | ERR_FATAL;
4588 }
4589
4590 free(conf->alpn_str);
4591
4592 /* the ALPN string is built as a suite of (<len> <name>)* */
4593 conf->alpn_len = strlen(args[cur_arg + 1]) + 1;
4594 conf->alpn_str = calloc(1, conf->alpn_len);
4595 memcpy(conf->alpn_str + 1, args[cur_arg + 1], conf->alpn_len);
4596
4597 /* replace commas with the name length */
4598 p1 = conf->alpn_str;
4599 p2 = p1 + 1;
4600 while (1) {
4601 p2 = memchr(p1 + 1, ',', conf->alpn_str + conf->alpn_len - (p1 + 1));
4602 if (!p2)
4603 p2 = p1 + 1 + strlen(p1 + 1);
4604
4605 if (p2 - (p1 + 1) > 255) {
4606 *p2 = '\0';
4607 memprintf(err, "'%s' : ALPN protocol name too long : '%s'", args[cur_arg], p1 + 1);
4608 return ERR_ALERT | ERR_FATAL;
4609 }
4610
4611 *p1 = p2 - (p1 + 1);
4612 p1 = p2;
4613
4614 if (!*p2)
4615 break;
4616
4617 *(p2++) = '\0';
4618 }
4619 return 0;
4620#else
4621 if (err)
4622 memprintf(err, "'%s' : library does not support TLS ALPN extension", args[cur_arg]);
4623 return ERR_ALERT | ERR_FATAL;
4624#endif
4625}
4626
Willy Tarreau79eeafa2012-09-14 07:53:05 +02004627/* parse the "ssl" bind keyword */
Willy Tarreau4348fad2012-09-20 16:48:07 +02004628static 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 +02004629{
Willy Tarreau81796be2012-09-22 19:11:47 +02004630 struct listener *l;
4631
Willy Tarreau4348fad2012-09-20 16:48:07 +02004632 conf->is_ssl = 1;
Emeric Brun76d88952012-10-05 15:47:31 +02004633
4634 if (global.listen_default_ciphers && !conf->ciphers)
4635 conf->ciphers = strdup(global.listen_default_ciphers);
Emeric Brun2c86cbf2014-10-30 15:56:50 +01004636 conf->ssl_options |= global.listen_default_ssloptions;
Emeric Brun76d88952012-10-05 15:47:31 +02004637
Willy Tarreau81796be2012-09-22 19:11:47 +02004638 list_for_each_entry(l, &conf->listeners, by_bind)
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02004639 l->xprt = &ssl_sock;
Willy Tarreau81796be2012-09-22 19:11:47 +02004640
Willy Tarreau79eeafa2012-09-14 07:53:05 +02004641 return 0;
4642}
4643
Christopher Faulet31af49d2015-06-09 17:29:50 +02004644/* parse the "generate-certificates" bind keyword */
4645static int bind_parse_generate_certs(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
4646{
4647#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
4648 conf->generate_certs = 1;
4649#else
4650 memprintf(err, "%sthis version of openssl cannot generate SSL certificates.\n",
4651 err && *err ? *err : "");
4652#endif
4653 return 0;
4654}
4655
Emmanuel Hocdet65623372013-01-24 17:17:15 +01004656/* parse the "strict-sni" bind keyword */
4657static int bind_parse_strict_sni(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
4658{
4659 conf->strict_sni = 1;
4660 return 0;
Nenad Merdanovic05552d42015-02-27 19:56:49 +01004661}
4662
4663/* parse the "tls-ticket-keys" bind keyword */
4664static int bind_parse_tls_ticket_keys(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
4665{
4666#if (defined SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB && TLS_TICKETS_NO > 0)
4667 FILE *f;
4668 int i = 0;
4669 char thisline[LINESIZE];
Nenad Merdanovic146defa2015-05-09 08:46:00 +02004670 struct tls_keys_ref *keys_ref;
Nenad Merdanovic05552d42015-02-27 19:56:49 +01004671
4672 if (!*args[cur_arg + 1]) {
4673 if (err)
4674 memprintf(err, "'%s' : missing TLS ticket keys file path", args[cur_arg]);
4675 return ERR_ALERT | ERR_FATAL;
4676 }
4677
Nenad Merdanovic200b0fa2015-05-09 08:46:01 +02004678 keys_ref = tlskeys_ref_lookup(args[cur_arg + 1]);
4679 if(keys_ref) {
4680 conf->keys_ref = keys_ref;
4681 return 0;
4682 }
4683
Nenad Merdanovic146defa2015-05-09 08:46:00 +02004684 keys_ref = malloc(sizeof(struct tls_keys_ref));
4685 keys_ref->tlskeys = malloc(TLS_TICKETS_NO * sizeof(struct tls_sess_key));
Nenad Merdanovic05552d42015-02-27 19:56:49 +01004686
4687 if ((f = fopen(args[cur_arg + 1], "r")) == NULL) {
4688 if (err)
4689 memprintf(err, "'%s' : unable to load ssl tickets keys file", args[cur_arg+1]);
4690 return ERR_ALERT | ERR_FATAL;
4691 }
4692
Nenad Merdanovic146defa2015-05-09 08:46:00 +02004693 keys_ref->filename = strdup(args[cur_arg + 1]);
4694
Nenad Merdanovic05552d42015-02-27 19:56:49 +01004695 while (fgets(thisline, sizeof(thisline), f) != NULL) {
4696 int len = strlen(thisline);
4697 /* Strip newline characters from the end */
4698 if(thisline[len - 1] == '\n')
4699 thisline[--len] = 0;
4700
4701 if(thisline[len - 1] == '\r')
4702 thisline[--len] = 0;
4703
Nenad Merdanovic146defa2015-05-09 08:46:00 +02004704 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 +01004705 if (err)
4706 memprintf(err, "'%s' : unable to decode base64 key on line %d", args[cur_arg+1], i + 1);
4707 return ERR_ALERT | ERR_FATAL;
4708 }
4709 i++;
4710 }
4711
4712 if (i < TLS_TICKETS_NO) {
4713 if (err)
4714 memprintf(err, "'%s' : please supply at least %d keys in the tls-tickets-file", args[cur_arg+1], TLS_TICKETS_NO);
4715 return ERR_ALERT | ERR_FATAL;
4716 }
4717
4718 fclose(f);
4719
4720 /* Use penultimate key for encryption, handle when TLS_TICKETS_NO = 1 */
4721 i-=2;
Nenad Merdanovic146defa2015-05-09 08:46:00 +02004722 keys_ref->tls_ticket_enc_index = i < 0 ? 0 : i;
Nenad Merdanovic200b0fa2015-05-09 08:46:01 +02004723 keys_ref->unique_id = -1;
Nenad Merdanovic146defa2015-05-09 08:46:00 +02004724 conf->keys_ref = keys_ref;
Nenad Merdanovic05552d42015-02-27 19:56:49 +01004725
Nenad Merdanovic200b0fa2015-05-09 08:46:01 +02004726 LIST_ADD(&tlskeys_reference, &keys_ref->list);
4727
Nenad Merdanovic05552d42015-02-27 19:56:49 +01004728 return 0;
4729#else
4730 if (err)
4731 memprintf(err, "'%s' : TLS ticket callback extension not supported", args[cur_arg]);
4732 return ERR_ALERT | ERR_FATAL;
4733#endif /* SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB */
Emmanuel Hocdet65623372013-01-24 17:17:15 +01004734}
4735
Emeric Brund94b3fe2012-09-20 18:23:56 +02004736/* parse the "verify" bind keyword */
4737static int bind_parse_verify(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
4738{
4739 if (!*args[cur_arg + 1]) {
4740 if (err)
4741 memprintf(err, "'%s' : missing verify method", args[cur_arg]);
4742 return ERR_ALERT | ERR_FATAL;
4743 }
4744
4745 if (strcmp(args[cur_arg + 1], "none") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01004746 conf->verify = SSL_SOCK_VERIFY_NONE;
Emeric Brund94b3fe2012-09-20 18:23:56 +02004747 else if (strcmp(args[cur_arg + 1], "optional") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01004748 conf->verify = SSL_SOCK_VERIFY_OPTIONAL;
Emeric Brund94b3fe2012-09-20 18:23:56 +02004749 else if (strcmp(args[cur_arg + 1], "required") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01004750 conf->verify = SSL_SOCK_VERIFY_REQUIRED;
Emeric Brund94b3fe2012-09-20 18:23:56 +02004751 else {
4752 if (err)
4753 memprintf(err, "'%s' : unknown verify method '%s', only 'none', 'optional', and 'required' are supported\n",
4754 args[cur_arg], args[cur_arg + 1]);
4755 return ERR_ALERT | ERR_FATAL;
4756 }
4757
4758 return 0;
4759}
4760
Willy Tarreau92faadf2012-10-10 23:04:25 +02004761/************** "server" keywords ****************/
4762
Emeric Brunef42d922012-10-11 16:11:36 +02004763/* parse the "ca-file" server keyword */
4764static int srv_parse_ca_file(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4765{
4766 if (!*args[*cur_arg + 1]) {
4767 if (err)
4768 memprintf(err, "'%s' : missing CAfile path", args[*cur_arg]);
4769 return ERR_ALERT | ERR_FATAL;
4770 }
4771
4772 if ((*args[*cur_arg + 1] != '/') && global.ca_base)
4773 memprintf(&newsrv->ssl_ctx.ca_file, "%s/%s", global.ca_base, args[*cur_arg + 1]);
4774 else
4775 memprintf(&newsrv->ssl_ctx.ca_file, "%s", args[*cur_arg + 1]);
4776
4777 return 0;
4778}
4779
Willy Tarreau92faadf2012-10-10 23:04:25 +02004780/* parse the "check-ssl" server keyword */
4781static int srv_parse_check_ssl(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4782{
4783 newsrv->check.use_ssl = 1;
4784 if (global.connect_default_ciphers && !newsrv->ssl_ctx.ciphers)
4785 newsrv->ssl_ctx.ciphers = strdup(global.connect_default_ciphers);
Emeric Brun2c86cbf2014-10-30 15:56:50 +01004786 newsrv->ssl_ctx.options |= global.connect_default_ssloptions;
Willy Tarreau92faadf2012-10-10 23:04:25 +02004787 return 0;
4788}
4789
4790/* parse the "ciphers" server keyword */
4791static int srv_parse_ciphers(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4792{
4793 if (!*args[*cur_arg + 1]) {
4794 memprintf(err, "'%s' : missing cipher suite", args[*cur_arg]);
4795 return ERR_ALERT | ERR_FATAL;
4796 }
4797
4798 free(newsrv->ssl_ctx.ciphers);
4799 newsrv->ssl_ctx.ciphers = strdup(args[*cur_arg + 1]);
4800 return 0;
4801}
4802
Emeric Brunef42d922012-10-11 16:11:36 +02004803/* parse the "crl-file" server keyword */
4804static int srv_parse_crl_file(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4805{
4806#ifndef X509_V_FLAG_CRL_CHECK
4807 if (err)
4808 memprintf(err, "'%s' : library does not support CRL verify", args[*cur_arg]);
4809 return ERR_ALERT | ERR_FATAL;
4810#else
4811 if (!*args[*cur_arg + 1]) {
4812 if (err)
4813 memprintf(err, "'%s' : missing CRLfile path", args[*cur_arg]);
4814 return ERR_ALERT | ERR_FATAL;
4815 }
4816
4817 if ((*args[*cur_arg + 1] != '/') && global.ca_base)
4818 memprintf(&newsrv->ssl_ctx.crl_file, "%s/%s", global.ca_base, args[*cur_arg + 1]);
4819 else
4820 memprintf(&newsrv->ssl_ctx.crl_file, "%s", args[*cur_arg + 1]);
4821
4822 return 0;
4823#endif
4824}
4825
Emeric Bruna7aa3092012-10-26 12:58:00 +02004826/* parse the "crt" server keyword */
4827static int srv_parse_crt(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4828{
4829 if (!*args[*cur_arg + 1]) {
4830 if (err)
4831 memprintf(err, "'%s' : missing certificate file path", args[*cur_arg]);
4832 return ERR_ALERT | ERR_FATAL;
4833 }
4834
4835 if ((*args[*cur_arg + 1] != '/') && global.crt_base)
4836 memprintf(&newsrv->ssl_ctx.client_crt, "%s/%s", global.ca_base, args[*cur_arg + 1]);
4837 else
4838 memprintf(&newsrv->ssl_ctx.client_crt, "%s", args[*cur_arg + 1]);
4839
4840 return 0;
4841}
Emeric Brunef42d922012-10-11 16:11:36 +02004842
Willy Tarreau92faadf2012-10-10 23:04:25 +02004843/* parse the "force-sslv3" server keyword */
4844static int srv_parse_force_sslv3(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4845{
4846 newsrv->ssl_ctx.options |= SRV_SSL_O_USE_SSLV3;
4847 return 0;
4848}
4849
4850/* parse the "force-tlsv10" server keyword */
4851static int srv_parse_force_tlsv10(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4852{
4853 newsrv->ssl_ctx.options |= SRV_SSL_O_USE_TLSV10;
4854 return 0;
4855}
4856
4857/* parse the "force-tlsv11" server keyword */
4858static int srv_parse_force_tlsv11(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4859{
4860#if SSL_OP_NO_TLSv1_1
4861 newsrv->ssl_ctx.options |= SRV_SSL_O_USE_TLSV11;
4862 return 0;
4863#else
4864 if (err)
4865 memprintf(err, "'%s' : library does not support protocol TLSv1.1", args[*cur_arg]);
4866 return ERR_ALERT | ERR_FATAL;
4867#endif
4868}
4869
4870/* parse the "force-tlsv12" server keyword */
4871static int srv_parse_force_tlsv12(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4872{
4873#if SSL_OP_NO_TLSv1_2
4874 newsrv->ssl_ctx.options |= SRV_SSL_O_USE_TLSV12;
4875 return 0;
4876#else
4877 if (err)
4878 memprintf(err, "'%s' : library does not support protocol TLSv1.2", args[*cur_arg]);
4879 return ERR_ALERT | ERR_FATAL;
4880#endif
4881}
4882
Willy Tarreau2a3fb1c2015-02-05 16:47:07 +01004883/* parse the "no-ssl-reuse" server keyword */
4884static int srv_parse_no_ssl_reuse(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4885{
4886 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_REUSE;
4887 return 0;
4888}
4889
Willy Tarreau92faadf2012-10-10 23:04:25 +02004890/* parse the "no-sslv3" server keyword */
4891static int srv_parse_no_sslv3(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4892{
4893 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_SSLV3;
4894 return 0;
4895}
4896
4897/* parse the "no-tlsv10" server keyword */
4898static int srv_parse_no_tlsv10(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4899{
4900 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_TLSV10;
4901 return 0;
4902}
4903
4904/* parse the "no-tlsv11" server keyword */
4905static int srv_parse_no_tlsv11(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4906{
4907 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_TLSV11;
4908 return 0;
4909}
4910
4911/* parse the "no-tlsv12" server keyword */
4912static int srv_parse_no_tlsv12(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4913{
4914 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_TLSV12;
4915 return 0;
4916}
4917
Emeric Brunf9c5c472012-10-11 15:28:34 +02004918/* parse the "no-tls-tickets" server keyword */
4919static int srv_parse_no_tls_tickets(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4920{
4921 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_TLS_TICKETS;
4922 return 0;
4923}
David Safb76832014-05-08 23:42:08 -04004924/* parse the "send-proxy-v2-ssl" server keyword */
4925static int srv_parse_send_proxy_ssl(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4926{
4927 newsrv->pp_opts |= SRV_PP_V2;
4928 newsrv->pp_opts |= SRV_PP_V2_SSL;
4929 return 0;
4930}
4931
4932/* parse the "send-proxy-v2-ssl-cn" server keyword */
4933static int srv_parse_send_proxy_cn(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4934{
4935 newsrv->pp_opts |= SRV_PP_V2;
4936 newsrv->pp_opts |= SRV_PP_V2_SSL;
4937 newsrv->pp_opts |= SRV_PP_V2_SSL_CN;
4938 return 0;
4939}
Emeric Brunf9c5c472012-10-11 15:28:34 +02004940
Willy Tarreau92faadf2012-10-10 23:04:25 +02004941/* parse the "ssl" server keyword */
4942static int srv_parse_ssl(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4943{
4944 newsrv->use_ssl = 1;
4945 if (global.connect_default_ciphers && !newsrv->ssl_ctx.ciphers)
4946 newsrv->ssl_ctx.ciphers = strdup(global.connect_default_ciphers);
4947 return 0;
4948}
4949
Emeric Brunef42d922012-10-11 16:11:36 +02004950/* parse the "verify" server keyword */
4951static int srv_parse_verify(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4952{
4953 if (!*args[*cur_arg + 1]) {
4954 if (err)
4955 memprintf(err, "'%s' : missing verify method", args[*cur_arg]);
4956 return ERR_ALERT | ERR_FATAL;
4957 }
4958
4959 if (strcmp(args[*cur_arg + 1], "none") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01004960 newsrv->ssl_ctx.verify = SSL_SOCK_VERIFY_NONE;
Emeric Brunef42d922012-10-11 16:11:36 +02004961 else if (strcmp(args[*cur_arg + 1], "required") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01004962 newsrv->ssl_ctx.verify = SSL_SOCK_VERIFY_REQUIRED;
Emeric Brunef42d922012-10-11 16:11:36 +02004963 else {
4964 if (err)
4965 memprintf(err, "'%s' : unknown verify method '%s', only 'none' and 'required' are supported\n",
4966 args[*cur_arg], args[*cur_arg + 1]);
4967 return ERR_ALERT | ERR_FATAL;
4968 }
4969
Evan Broderbe554312013-06-27 00:05:25 -07004970 return 0;
4971}
4972
4973/* parse the "verifyhost" server keyword */
4974static int srv_parse_verifyhost(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4975{
4976 if (!*args[*cur_arg + 1]) {
4977 if (err)
4978 memprintf(err, "'%s' : missing hostname to verify against", args[*cur_arg]);
4979 return ERR_ALERT | ERR_FATAL;
4980 }
4981
4982 newsrv->ssl_ctx.verify_host = strdup(args[*cur_arg + 1]);
4983
Emeric Brunef42d922012-10-11 16:11:36 +02004984 return 0;
4985}
4986
Emeric Brun2c86cbf2014-10-30 15:56:50 +01004987/* parse the "ssl-default-bind-options" keyword in global section */
4988static int ssl_parse_default_bind_options(char **args, int section_type, struct proxy *curpx,
4989 struct proxy *defpx, const char *file, int line,
4990 char **err) {
4991 int i = 1;
4992
4993 if (*(args[i]) == 0) {
4994 memprintf(err, "global statement '%s' expects an option as an argument.", args[0]);
4995 return -1;
4996 }
4997 while (*(args[i])) {
4998 if (!strcmp(args[i], "no-sslv3"))
4999 global.listen_default_ssloptions |= BC_SSL_O_NO_SSLV3;
5000 else if (!strcmp(args[i], "no-tlsv10"))
5001 global.listen_default_ssloptions |= BC_SSL_O_NO_TLSV10;
5002 else if (!strcmp(args[i], "no-tlsv11"))
5003 global.listen_default_ssloptions |= BC_SSL_O_NO_TLSV11;
5004 else if (!strcmp(args[i], "no-tlsv12"))
5005 global.listen_default_ssloptions |= BC_SSL_O_NO_TLSV12;
5006 else if (!strcmp(args[i], "force-sslv3"))
5007 global.listen_default_ssloptions |= BC_SSL_O_USE_SSLV3;
5008 else if (!strcmp(args[i], "force-tlsv10"))
5009 global.listen_default_ssloptions |= BC_SSL_O_USE_TLSV10;
5010 else if (!strcmp(args[i], "force-tlsv11")) {
5011#if SSL_OP_NO_TLSv1_1
5012 global.listen_default_ssloptions |= BC_SSL_O_USE_TLSV11;
5013#else
5014 memprintf(err, "'%s' '%s': library does not support protocol TLSv1.1", args[0], args[i]);
5015 return -1;
5016#endif
5017 }
5018 else if (!strcmp(args[i], "force-tlsv12")) {
5019#if SSL_OP_NO_TLSv1_2
5020 global.listen_default_ssloptions |= BC_SSL_O_USE_TLSV12;
5021#else
5022 memprintf(err, "'%s' '%s': library does not support protocol TLSv1.2", args[0], args[i]);
5023 return -1;
5024#endif
5025 }
5026 else if (!strcmp(args[i], "no-tls-tickets"))
5027 global.listen_default_ssloptions |= BC_SSL_O_NO_TLS_TICKETS;
5028 else {
5029 memprintf(err, "unknown option '%s' on global statement '%s'.", args[i], args[0]);
5030 return -1;
5031 }
5032 i++;
5033 }
5034 return 0;
5035}
5036
5037/* parse the "ssl-default-server-options" keyword in global section */
5038static int ssl_parse_default_server_options(char **args, int section_type, struct proxy *curpx,
5039 struct proxy *defpx, const char *file, int line,
5040 char **err) {
5041 int i = 1;
5042
5043 if (*(args[i]) == 0) {
5044 memprintf(err, "global statement '%s' expects an option as an argument.", args[0]);
5045 return -1;
5046 }
5047 while (*(args[i])) {
5048 if (!strcmp(args[i], "no-sslv3"))
5049 global.connect_default_ssloptions |= SRV_SSL_O_NO_SSLV3;
5050 else if (!strcmp(args[i], "no-tlsv10"))
5051 global.connect_default_ssloptions |= SRV_SSL_O_NO_TLSV10;
5052 else if (!strcmp(args[i], "no-tlsv11"))
5053 global.connect_default_ssloptions |= SRV_SSL_O_NO_TLSV11;
5054 else if (!strcmp(args[i], "no-tlsv12"))
5055 global.connect_default_ssloptions |= SRV_SSL_O_NO_TLSV12;
5056 else if (!strcmp(args[i], "force-sslv3"))
5057 global.connect_default_ssloptions |= SRV_SSL_O_USE_SSLV3;
5058 else if (!strcmp(args[i], "force-tlsv10"))
5059 global.connect_default_ssloptions |= SRV_SSL_O_USE_TLSV10;
5060 else if (!strcmp(args[i], "force-tlsv11")) {
5061#if SSL_OP_NO_TLSv1_1
5062 global.connect_default_ssloptions |= SRV_SSL_O_USE_TLSV11;
5063#else
5064 memprintf(err, "'%s' '%s': library does not support protocol TLSv1.1", args[0], args[i]);
5065 return -1;
5066#endif
5067 }
5068 else if (!strcmp(args[i], "force-tlsv12")) {
5069#if SSL_OP_NO_TLSv1_2
5070 global.connect_default_ssloptions |= SRV_SSL_O_USE_TLSV12;
5071#else
5072 memprintf(err, "'%s' '%s': library does not support protocol TLSv1.2", args[0], args[i]);
5073 return -1;
5074#endif
5075 }
5076 else if (!strcmp(args[i], "no-tls-tickets"))
5077 global.connect_default_ssloptions |= SRV_SSL_O_NO_TLS_TICKETS;
5078 else {
5079 memprintf(err, "unknown option '%s' on global statement '%s'.", args[i], args[0]);
5080 return -1;
5081 }
5082 i++;
5083 }
5084 return 0;
5085}
5086
Willy Tarreau7875d092012-09-10 08:20:03 +02005087/* Note: must not be declared <const> as its list will be overwritten.
5088 * Please take care of keeping this list alphabetically sorted.
5089 */
Willy Tarreaudc13c112013-06-21 23:16:39 +02005090static struct sample_fetch_kw_list sample_fetch_keywords = {ILH, {
Emeric Brun645ae792014-04-30 14:21:06 +02005091 { "ssl_bc", smp_fetch_ssl_fc, 0, NULL, SMP_T_BOOL, SMP_USE_L5SRV },
5092 { "ssl_bc_alg_keysize", smp_fetch_ssl_fc_alg_keysize, 0, NULL, SMP_T_UINT, SMP_USE_L5SRV },
5093 { "ssl_bc_cipher", smp_fetch_ssl_fc_cipher, 0, NULL, SMP_T_STR, SMP_USE_L5SRV },
5094 { "ssl_bc_protocol", smp_fetch_ssl_fc_protocol, 0, NULL, SMP_T_STR, SMP_USE_L5SRV },
Emeric Brunb73a9b02014-04-30 18:49:19 +02005095 { "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 +02005096 { "ssl_bc_use_keysize", smp_fetch_ssl_fc_use_keysize, 0, NULL, SMP_T_UINT, SMP_USE_L5SRV },
5097 { "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 +01005098 { "ssl_c_ca_err", smp_fetch_ssl_c_ca_err, 0, NULL, SMP_T_UINT, SMP_USE_L5CLI },
5099 { "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 +01005100 { "ssl_c_der", smp_fetch_ssl_x_der, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Willy Tarreau80aca902013-01-07 15:42:20 +01005101 { "ssl_c_err", smp_fetch_ssl_c_err, 0, NULL, SMP_T_UINT, SMP_USE_L5CLI },
Emeric Brunba841a12014-04-30 17:05:08 +02005102 { "ssl_c_i_dn", smp_fetch_ssl_x_i_dn, ARG2(0,STR,SINT), NULL, SMP_T_STR, SMP_USE_L5CLI },
5103 { "ssl_c_key_alg", smp_fetch_ssl_x_key_alg, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
5104 { "ssl_c_notafter", smp_fetch_ssl_x_notafter, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
5105 { "ssl_c_notbefore", smp_fetch_ssl_x_notbefore, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
5106 { "ssl_c_sig_alg", smp_fetch_ssl_x_sig_alg, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
5107 { "ssl_c_s_dn", smp_fetch_ssl_x_s_dn, ARG2(0,STR,SINT), NULL, SMP_T_STR, SMP_USE_L5CLI },
5108 { "ssl_c_serial", smp_fetch_ssl_x_serial, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
5109 { "ssl_c_sha1", smp_fetch_ssl_x_sha1, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Willy Tarreau80aca902013-01-07 15:42:20 +01005110 { "ssl_c_used", smp_fetch_ssl_c_used, 0, NULL, SMP_T_BOOL, SMP_USE_L5CLI },
5111 { "ssl_c_verify", smp_fetch_ssl_c_verify, 0, NULL, SMP_T_UINT, SMP_USE_L5CLI },
Emeric Brunba841a12014-04-30 17:05:08 +02005112 { "ssl_c_version", smp_fetch_ssl_x_version, 0, NULL, SMP_T_UINT, SMP_USE_L5CLI },
Emeric Brun43e79582014-10-29 19:03:26 +01005113 { "ssl_f_der", smp_fetch_ssl_x_der, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Emeric Brunba841a12014-04-30 17:05:08 +02005114 { "ssl_f_i_dn", smp_fetch_ssl_x_i_dn, ARG2(0,STR,SINT), NULL, SMP_T_STR, SMP_USE_L5CLI },
5115 { "ssl_f_key_alg", smp_fetch_ssl_x_key_alg, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
5116 { "ssl_f_notafter", smp_fetch_ssl_x_notafter, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
5117 { "ssl_f_notbefore", smp_fetch_ssl_x_notbefore, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
5118 { "ssl_f_sig_alg", smp_fetch_ssl_x_sig_alg, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
5119 { "ssl_f_s_dn", smp_fetch_ssl_x_s_dn, ARG2(0,STR,SINT), NULL, SMP_T_STR, SMP_USE_L5CLI },
5120 { "ssl_f_serial", smp_fetch_ssl_x_serial, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Emeric Brun55f4fa82014-04-30 17:11:25 +02005121 { "ssl_f_sha1", smp_fetch_ssl_x_sha1, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Emeric Brunba841a12014-04-30 17:05:08 +02005122 { "ssl_f_version", smp_fetch_ssl_x_version, 0, NULL, SMP_T_UINT, SMP_USE_L5CLI },
Willy Tarreau80aca902013-01-07 15:42:20 +01005123 { "ssl_fc", smp_fetch_ssl_fc, 0, NULL, SMP_T_BOOL, SMP_USE_L5CLI },
5124 { "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 +01005125 { "ssl_fc_cipher", smp_fetch_ssl_fc_cipher, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Willy Tarreau80aca902013-01-07 15:42:20 +01005126 { "ssl_fc_has_crt", smp_fetch_ssl_fc_has_crt, 0, NULL, SMP_T_BOOL, SMP_USE_L5CLI },
5127 { "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 +02005128 { "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 +02005129#ifdef OPENSSL_NPN_NEGOTIATED
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01005130 { "ssl_fc_npn", smp_fetch_ssl_fc_npn, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Willy Tarreaua33c6542012-10-15 13:19:06 +02005131#endif
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01005132#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01005133 { "ssl_fc_alpn", smp_fetch_ssl_fc_alpn, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Willy Tarreauab861d32013-04-02 02:30:41 +02005134#endif
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01005135 { "ssl_fc_protocol", smp_fetch_ssl_fc_protocol, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Emeric Brunb73a9b02014-04-30 18:49:19 +02005136 { "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 +01005137 { "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 +01005138 { "ssl_fc_session_id", smp_fetch_ssl_fc_session_id, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
5139 { "ssl_fc_sni", smp_fetch_ssl_fc_sni, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Willy Tarreau7875d092012-09-10 08:20:03 +02005140 { NULL, NULL, 0, 0, 0 },
5141}};
5142
5143/* Note: must not be declared <const> as its list will be overwritten.
5144 * Please take care of keeping this list alphabetically sorted.
5145 */
Willy Tarreaudc13c112013-06-21 23:16:39 +02005146static struct acl_kw_list acl_kws = {ILH, {
Thierry FOURNIERc5a4e982014-03-05 16:07:08 +01005147 { "ssl_fc_sni_end", "ssl_fc_sni", PAT_MATCH_END },
5148 { "ssl_fc_sni_reg", "ssl_fc_sni", PAT_MATCH_REG },
Willy Tarreau8ed669b2013-01-11 15:49:37 +01005149 { /* END */ },
Willy Tarreau7875d092012-09-10 08:20:03 +02005150}};
5151
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005152/* Note: must not be declared <const> as its list will be overwritten.
5153 * Please take care of keeping this list alphabetically sorted, doing so helps
5154 * all code contributors.
5155 * Optional keywords are also declared with a NULL ->parse() function so that
5156 * the config parser can report an appropriate error when a known keyword was
5157 * not enabled.
5158 */
Willy Tarreau51fb7652012-09-18 18:24:39 +02005159static struct bind_kw_list bind_kws = { "SSL", { }, {
Nenad Merdanovic05552d42015-02-27 19:56:49 +01005160 { "alpn", bind_parse_alpn, 1 }, /* set ALPN supported protocols */
5161 { "ca-file", bind_parse_ca_file, 1 }, /* set CAfile to process verify on client cert */
5162 { "ca-ignore-err", bind_parse_ignore_err, 1 }, /* set error IDs to ignore on verify depth > 0 */
Christopher Faulet31af49d2015-06-09 17:29:50 +02005163 { "ca-sign-file", bind_parse_ca_sign_file, 1 }, /* set CAFile used to generate and sign server certs */
5164 { "ca-sign-pass", bind_parse_ca_sign_pass, 1 }, /* set CAKey passphrase */
Nenad Merdanovic05552d42015-02-27 19:56:49 +01005165 { "ciphers", bind_parse_ciphers, 1 }, /* set SSL cipher suite */
5166 { "crl-file", bind_parse_crl_file, 1 }, /* set certificat revocation list file use on client cert verify */
5167 { "crt", bind_parse_crt, 1 }, /* load SSL certificates from this location */
5168 { "crt-ignore-err", bind_parse_ignore_err, 1 }, /* set error IDs to ingore on verify depth == 0 */
5169 { "crt-list", bind_parse_crt_list, 1 }, /* load a list of crt from this location */
5170 { "ecdhe", bind_parse_ecdhe, 1 }, /* defines named curve for elliptic curve Diffie-Hellman */
5171 { "force-sslv3", bind_parse_force_sslv3, 0 }, /* force SSLv3 */
5172 { "force-tlsv10", bind_parse_force_tlsv10, 0 }, /* force TLSv10 */
5173 { "force-tlsv11", bind_parse_force_tlsv11, 0 }, /* force TLSv11 */
5174 { "force-tlsv12", bind_parse_force_tlsv12, 0 }, /* force TLSv12 */
Christopher Faulet31af49d2015-06-09 17:29:50 +02005175 { "generate-certificates", bind_parse_generate_certs, 0 }, /* enable the server certificates generation */
Nenad Merdanovic05552d42015-02-27 19:56:49 +01005176 { "no-sslv3", bind_parse_no_sslv3, 0 }, /* disable SSLv3 */
5177 { "no-tlsv10", bind_parse_no_tlsv10, 0 }, /* disable TLSv10 */
5178 { "no-tlsv11", bind_parse_no_tlsv11, 0 }, /* disable TLSv11 */
5179 { "no-tlsv12", bind_parse_no_tlsv12, 0 }, /* disable TLSv12 */
5180 { "no-tls-tickets", bind_parse_no_tls_tickets, 0 }, /* disable session resumption tickets */
5181 { "ssl", bind_parse_ssl, 0 }, /* enable SSL processing */
5182 { "strict-sni", bind_parse_strict_sni, 0 }, /* refuse negotiation if sni doesn't match a certificate */
5183 { "tls-ticket-keys", bind_parse_tls_ticket_keys, 1 }, /* set file to load TLS ticket keys from */
5184 { "verify", bind_parse_verify, 1 }, /* set SSL verify method */
5185 { "npn", bind_parse_npn, 1 }, /* set NPN supported protocols */
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005186 { NULL, NULL, 0 },
5187}};
Emeric Brun46591952012-05-18 15:47:34 +02005188
Willy Tarreau92faadf2012-10-10 23:04:25 +02005189/* Note: must not be declared <const> as its list will be overwritten.
5190 * Please take care of keeping this list alphabetically sorted, doing so helps
5191 * all code contributors.
5192 * Optional keywords are also declared with a NULL ->parse() function so that
5193 * the config parser can report an appropriate error when a known keyword was
5194 * not enabled.
5195 */
5196static struct srv_kw_list srv_kws = { "SSL", { }, {
Emeric Brunef42d922012-10-11 16:11:36 +02005197 { "ca-file", srv_parse_ca_file, 1, 0 }, /* set CAfile to process verify server cert */
Emeric Brunecc91fe2012-10-11 15:05:10 +02005198 { "check-ssl", srv_parse_check_ssl, 0, 0 }, /* enable SSL for health checks */
5199 { "ciphers", srv_parse_ciphers, 1, 0 }, /* select the cipher suite */
Emeric Brunef42d922012-10-11 16:11:36 +02005200 { "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 +02005201 { "crt", srv_parse_crt, 1, 0 }, /* set client certificate */
Emeric Brunecc91fe2012-10-11 15:05:10 +02005202 { "force-sslv3", srv_parse_force_sslv3, 0, 0 }, /* force SSLv3 */
5203 { "force-tlsv10", srv_parse_force_tlsv10, 0, 0 }, /* force TLSv10 */
5204 { "force-tlsv11", srv_parse_force_tlsv11, 0, 0 }, /* force TLSv11 */
5205 { "force-tlsv12", srv_parse_force_tlsv12, 0, 0 }, /* force TLSv12 */
Willy Tarreau2a3fb1c2015-02-05 16:47:07 +01005206 { "no-ssl-reuse", srv_parse_no_ssl_reuse, 0, 0 }, /* disable session reuse */
Emeric Brunecc91fe2012-10-11 15:05:10 +02005207 { "no-sslv3", srv_parse_no_sslv3, 0, 0 }, /* disable SSLv3 */
5208 { "no-tlsv10", srv_parse_no_tlsv10, 0, 0 }, /* disable TLSv10 */
5209 { "no-tlsv11", srv_parse_no_tlsv11, 0, 0 }, /* disable TLSv11 */
5210 { "no-tlsv12", srv_parse_no_tlsv12, 0, 0 }, /* disable TLSv12 */
Emeric Brunf9c5c472012-10-11 15:28:34 +02005211 { "no-tls-tickets", srv_parse_no_tls_tickets, 0, 0 }, /* disable session resumption tickets */
David Safb76832014-05-08 23:42:08 -04005212 { "send-proxy-v2-ssl", srv_parse_send_proxy_ssl, 0, 0 }, /* send PROXY protocol header v2 with SSL info */
5213 { "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 +02005214 { "ssl", srv_parse_ssl, 0, 0 }, /* enable SSL processing */
Emeric Brunef42d922012-10-11 16:11:36 +02005215 { "verify", srv_parse_verify, 1, 0 }, /* set SSL verify method */
Evan Broderbe554312013-06-27 00:05:25 -07005216 { "verifyhost", srv_parse_verifyhost, 1, 0 }, /* require that SSL cert verifies for hostname */
Willy Tarreau92faadf2012-10-10 23:04:25 +02005217 { NULL, NULL, 0, 0 },
5218}};
5219
Emeric Brun2c86cbf2014-10-30 15:56:50 +01005220static struct cfg_kw_list cfg_kws = {ILH, {
5221 { CFG_GLOBAL, "ssl-default-bind-options", ssl_parse_default_bind_options },
5222 { CFG_GLOBAL, "ssl-default-server-options", ssl_parse_default_server_options },
5223 { 0, NULL, NULL },
5224}};
5225
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02005226/* transport-layer operations for SSL sockets */
5227struct xprt_ops ssl_sock = {
Emeric Brun46591952012-05-18 15:47:34 +02005228 .snd_buf = ssl_sock_from_buf,
5229 .rcv_buf = ssl_sock_to_buf,
5230 .rcv_pipe = NULL,
5231 .snd_pipe = NULL,
5232 .shutr = NULL,
5233 .shutw = ssl_sock_shutw,
5234 .close = ssl_sock_close,
5235 .init = ssl_sock_init,
5236};
5237
Janusz Dziemidowicz2c701b52015-03-07 23:03:59 +01005238#if (OPENSSL_VERSION_NUMBER >= 0x1000200fL && !defined OPENSSL_NO_TLSEXT && !defined OPENSSL_IS_BORINGSSL)
5239
5240static void ssl_sock_sctl_free_func(void *parent, void *ptr, CRYPTO_EX_DATA *ad, int idx, long argl, void *argp)
5241{
5242 if (ptr) {
5243 chunk_destroy(ptr);
5244 free(ptr);
5245 }
5246}
5247
5248#endif
5249
Emeric Brun46591952012-05-18 15:47:34 +02005250__attribute__((constructor))
Willy Tarreau92faadf2012-10-10 23:04:25 +02005251static void __ssl_sock_init(void)
5252{
Emeric Brun46591952012-05-18 15:47:34 +02005253 STACK_OF(SSL_COMP)* cm;
5254
Willy Tarreau610f04b2014-02-13 11:36:41 +01005255#ifdef LISTEN_DEFAULT_CIPHERS
5256 global.listen_default_ciphers = LISTEN_DEFAULT_CIPHERS;
5257#endif
5258#ifdef CONNECT_DEFAULT_CIPHERS
5259 global.connect_default_ciphers = CONNECT_DEFAULT_CIPHERS;
5260#endif
5261 if (global.listen_default_ciphers)
5262 global.listen_default_ciphers = strdup(global.listen_default_ciphers);
5263 if (global.connect_default_ciphers)
5264 global.connect_default_ciphers = strdup(global.connect_default_ciphers);
Emeric Brun2c86cbf2014-10-30 15:56:50 +01005265 global.listen_default_ssloptions = BC_SSL_O_NONE;
5266 global.connect_default_ssloptions = SRV_SSL_O_NONE;
Willy Tarreau610f04b2014-02-13 11:36:41 +01005267
Emeric Brun46591952012-05-18 15:47:34 +02005268 SSL_library_init();
5269 cm = SSL_COMP_get_compression_methods();
5270 sk_SSL_COMP_zero(cm);
Janusz Dziemidowicz2c701b52015-03-07 23:03:59 +01005271#if (OPENSSL_VERSION_NUMBER >= 0x1000200fL && !defined OPENSSL_NO_TLSEXT && !defined OPENSSL_IS_BORINGSSL)
5272 sctl_ex_index = SSL_CTX_get_ex_new_index(0, NULL, NULL, NULL, ssl_sock_sctl_free_func);
5273#endif
Willy Tarreau7875d092012-09-10 08:20:03 +02005274 sample_register_fetches(&sample_fetch_keywords);
5275 acl_register_keywords(&acl_kws);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005276 bind_register_keywords(&bind_kws);
Willy Tarreau92faadf2012-10-10 23:04:25 +02005277 srv_register_keywords(&srv_kws);
Emeric Brun2c86cbf2014-10-30 15:56:50 +01005278 cfg_register_keywords(&cfg_kws);
Willy Tarreaud92aa5c2015-01-15 21:34:39 +01005279
5280 global.ssl_session_max_cost = SSL_SESSION_MAX_COST;
5281 global.ssl_handshake_max_cost = SSL_HANDSHAKE_MAX_COST;
Remi Gacogne4f902b82015-05-28 16:23:00 +02005282
5283#ifndef OPENSSL_NO_DH
5284 ssl_dh_ptr_index = SSL_CTX_get_ex_new_index(0, NULL, NULL, NULL, NULL);
5285#endif
Christopher Faulet31af49d2015-06-09 17:29:50 +02005286
5287 /* Add a global parameter for the LRU cache size */
5288 if (global.tune.ssl_ctx_cache)
5289 ssl_ctx_lru_tree = lru64_new(global.tune.ssl_ctx_cache);
5290 ssl_ctx_lru_seed = (unsigned int)time(NULL);
Emeric Brun46591952012-05-18 15:47:34 +02005291}
5292
Remi Gacogned3a23c32015-05-28 16:39:47 +02005293__attribute__((destructor))
5294static void __ssl_sock_deinit(void)
5295{
Christopher Faulet31af49d2015-06-09 17:29:50 +02005296 lru64_destroy(ssl_ctx_lru_tree);
5297
Remi Gacogned3a23c32015-05-28 16:39:47 +02005298#ifndef OPENSSL_NO_DH
5299 if (local_dh_1024) {
5300 DH_free(local_dh_1024);
5301 local_dh_1024 = NULL;
5302 }
5303
5304 if (local_dh_2048) {
5305 DH_free(local_dh_2048);
5306 local_dh_2048 = NULL;
5307 }
5308
5309 if (local_dh_4096) {
5310 DH_free(local_dh_4096);
5311 local_dh_4096 = NULL;
5312 }
5313
Remi Gacogne47783ef2015-05-29 15:53:22 +02005314 if (global_dh) {
5315 DH_free(global_dh);
5316 global_dh = NULL;
5317 }
Remi Gacogned3a23c32015-05-28 16:39:47 +02005318#endif
5319
5320 ERR_remove_state(0);
5321 ERR_free_strings();
5322
5323 EVP_cleanup();
5324
5325#if OPENSSL_VERSION_NUMBER >= 0x00907000L
5326 CRYPTO_cleanup_all_ex_data();
5327#endif
5328}
5329
5330
Emeric Brun46591952012-05-18 15:47:34 +02005331/*
5332 * Local variables:
5333 * c-indent-level: 8
5334 * c-basic-offset: 8
5335 * End:
5336 */