blob: e528db2aec2dd3e8a57ef5423d4dd4ffcd4d03de [file] [log] [blame]
Emeric Brun46591952012-05-18 15:47:34 +02001/*
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02002 * SSL/TLS transport layer over SOCK_STREAM sockets
Emeric Brun46591952012-05-18 15:47:34 +02003 *
4 * Copyright (C) 2012 EXCELIANCE, Emeric Brun <ebrun@exceliance.fr>
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version
9 * 2 of the License, or (at your option) any later version.
10 *
Willy Tarreau69845df2012-09-10 09:43:09 +020011 * Acknowledgement:
12 * We'd like to specially thank the Stud project authors for a very clean
13 * and well documented code which helped us understand how the OpenSSL API
14 * ought to be used in non-blocking mode. This is one difficult part which
15 * is not easy to get from the OpenSSL doc, and reading the Stud code made
16 * it much more obvious than the examples in the OpenSSL package. Keep up
17 * the good works, guys !
18 *
19 * Stud is an extremely efficient and scalable SSL/TLS proxy which combines
20 * particularly well with haproxy. For more info about this project, visit :
21 * https://github.com/bumptech/stud
22 *
Emeric Brun46591952012-05-18 15:47:34 +020023 */
24
25#define _GNU_SOURCE
Emeric Brunfc0421f2012-09-07 17:30:07 +020026#include <ctype.h>
27#include <dirent.h>
Emeric Brun46591952012-05-18 15:47:34 +020028#include <errno.h>
29#include <fcntl.h>
30#include <stdio.h>
31#include <stdlib.h>
Emeric Brunfc0421f2012-09-07 17:30:07 +020032#include <string.h>
33#include <unistd.h>
Emeric Brun46591952012-05-18 15:47:34 +020034
35#include <sys/socket.h>
36#include <sys/stat.h>
37#include <sys/types.h>
38
39#include <netinet/tcp.h>
40
41#include <openssl/ssl.h>
Emeric Brunfc0421f2012-09-07 17:30:07 +020042#include <openssl/x509.h>
43#include <openssl/x509v3.h>
44#include <openssl/x509.h>
45#include <openssl/err.h>
Thierry Fournier383085f2013-01-24 14:15:43 +010046#include <openssl/rand.h>
Lukas Tribuse4e30f72014-12-09 16:32:51 +010047#if (defined SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB && !defined OPENSSL_NO_OCSP)
Emeric Brun4147b2e2014-06-16 18:36:30 +020048#include <openssl/ocsp.h>
49#endif
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
54#include <common/buffer.h>
55#include <common/compat.h>
56#include <common/config.h>
57#include <common/debug.h>
Willy Tarreau79eeafa2012-09-14 07:53:05 +020058#include <common/errors.h>
Emeric Brun46591952012-05-18 15:47:34 +020059#include <common/standard.h>
60#include <common/ticks.h>
61#include <common/time.h>
Emeric Brun2c86cbf2014-10-30 15:56:50 +010062#include <common/cfgparse.h>
Nenad Merdanovic05552d42015-02-27 19:56:49 +010063#include <common/base64.h>
Emeric Brun46591952012-05-18 15:47:34 +020064
Emeric Brunfc0421f2012-09-07 17:30:07 +020065#include <ebsttree.h>
66
67#include <types/global.h>
68#include <types/ssl_sock.h>
69
Willy Tarreau7875d092012-09-10 08:20:03 +020070#include <proto/acl.h>
71#include <proto/arg.h>
Emeric Brun46591952012-05-18 15:47:34 +020072#include <proto/connection.h>
73#include <proto/fd.h>
74#include <proto/freq_ctr.h>
75#include <proto/frontend.h>
Willy Tarreau79eeafa2012-09-14 07:53:05 +020076#include <proto/listener.h>
Thierry FOURNIERed66c292013-11-28 11:05:19 +010077#include <proto/pattern.h>
Willy Tarreau92faadf2012-10-10 23:04:25 +020078#include <proto/server.h>
Emeric Brun46591952012-05-18 15:47:34 +020079#include <proto/log.h>
Emeric Brun94324a42012-10-11 14:00:19 +020080#include <proto/proxy.h>
Emeric Brunfc0421f2012-09-07 17:30:07 +020081#include <proto/shctx.h>
Emeric Brun46591952012-05-18 15:47:34 +020082#include <proto/ssl_sock.h>
Willy Tarreau9ad7bd42015-04-03 19:19:59 +020083#include <proto/stream.h>
Emeric Brun46591952012-05-18 15:47:34 +020084#include <proto/task.h>
85
Willy Tarreau518cedd2014-02-17 15:43:01 +010086/* Warning, these are bits, not integers! */
Emeric Brune64aef12012-09-21 13:15:06 +020087#define SSL_SOCK_ST_FL_VERIFY_DONE 0x00000001
Emeric Brund8b2bb52014-01-28 15:43:53 +010088#define SSL_SOCK_ST_FL_16K_WBFSIZE 0x00000002
Willy Tarreau518cedd2014-02-17 15:43:01 +010089#define SSL_SOCK_SEND_UNLIMITED 0x00000004
Emeric Brun29f037d2014-04-25 19:05:36 +020090#define SSL_SOCK_RECV_HEARTBEAT 0x00000008
91
Emeric Brunf282a812012-09-21 15:27:54 +020092/* bits 0xFFFF0000 are reserved to store verify errors */
93
94/* Verify errors macros */
95#define SSL_SOCK_CA_ERROR_TO_ST(e) (((e > 63) ? 63 : e) << (16))
96#define SSL_SOCK_CAEDEPTH_TO_ST(d) (((d > 15) ? 15 : d) << (6+16))
97#define SSL_SOCK_CRTERROR_TO_ST(e) (((e > 63) ? 63 : e) << (4+6+16))
98
99#define SSL_SOCK_ST_TO_CA_ERROR(s) ((s >> (16)) & 63)
100#define SSL_SOCK_ST_TO_CAEDEPTH(s) ((s >> (6+16)) & 15)
101#define SSL_SOCK_ST_TO_CRTERROR(s) ((s >> (4+6+16)) & 63)
Emeric Brune64aef12012-09-21 13:15:06 +0200102
Nenad Merdanovic05552d42015-02-27 19:56:49 +0100103/* Supported hash function for TLS tickets */
104#ifdef OPENSSL_NO_SHA256
105#define HASH_FUNCT EVP_sha1
106#else
107#define HASH_FUNCT EVP_sha256
108#endif /* OPENSSL_NO_SHA256 */
109
Emeric Brun850efd52014-01-29 12:24:34 +0100110/* server and bind verify method, it uses a global value as default */
111enum {
112 SSL_SOCK_VERIFY_DEFAULT = 0,
113 SSL_SOCK_VERIFY_REQUIRED = 1,
114 SSL_SOCK_VERIFY_OPTIONAL = 2,
115 SSL_SOCK_VERIFY_NONE = 3,
116};
117
Willy Tarreau71b734c2014-01-28 15:19:44 +0100118int sslconns = 0;
119int totalsslconns = 0;
Emeric Brune1f38db2012-09-03 20:36:47 +0200120
Nenad Merdanovic200b0fa2015-05-09 08:46:01 +0200121#if (defined SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB && TLS_TICKETS_NO > 0)
122struct list tlskeys_reference = LIST_HEAD_INIT(tlskeys_reference);
123#endif
124
Remi Gacogne8de54152014-07-15 11:36:40 +0200125#ifndef OPENSSL_NO_DH
Remi Gacogne4f902b82015-05-28 16:23:00 +0200126static int ssl_dh_ptr_index = -1;
Remi Gacogne8de54152014-07-15 11:36:40 +0200127static DH *local_dh_1024 = NULL;
128static DH *local_dh_2048 = NULL;
129static DH *local_dh_4096 = NULL;
130static DH *local_dh_8192 = NULL;
131#endif /* OPENSSL_NO_DH */
132
Lukas Tribuse4e30f72014-12-09 16:32:51 +0100133#if (defined SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB && !defined OPENSSL_NO_OCSP)
Emeric Brun4147b2e2014-06-16 18:36:30 +0200134struct certificate_ocsp {
135 struct ebmb_node key;
136 unsigned char key_data[OCSP_MAX_CERTID_ASN1_LENGTH];
137 struct chunk response;
Emeric Brun4f3c87a2014-06-20 15:46:13 +0200138 long expire;
Emeric Brun4147b2e2014-06-16 18:36:30 +0200139};
140
Emeric Brun4f3c87a2014-06-20 15:46:13 +0200141/*
142 * This function returns the number of seconds elapsed
143 * since the Epoch, 1970-01-01 00:00:00 +0000 (UTC) and the
144 * date presented un ASN1_GENERALIZEDTIME.
145 *
146 * In parsing error case, it returns -1.
147 */
148static long asn1_generalizedtime_to_epoch(ASN1_GENERALIZEDTIME *d)
149{
150 long epoch;
151 char *p, *end;
152 const unsigned short month_offset[12] = {
153 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334
154 };
155 int year, month;
156
157 if (!d || (d->type != V_ASN1_GENERALIZEDTIME)) return -1;
158
159 p = (char *)d->data;
160 end = p + d->length;
161
162 if (end - p < 4) return -1;
163 year = 1000 * (p[0] - '0') + 100 * (p[1] - '0') + 10 * (p[2] - '0') + p[3] - '0';
164 p += 4;
165 if (end - p < 2) return -1;
166 month = 10 * (p[0] - '0') + p[1] - '0';
167 if (month < 1 || month > 12) return -1;
168 /* Compute the number of seconds since 1 jan 1970 and the beginning of current month
169 We consider leap years and the current month (<marsh or not) */
170 epoch = ( ((year - 1970) * 365)
171 + ((year - (month < 3)) / 4 - (year - (month < 3)) / 100 + (year - (month < 3)) / 400)
172 - ((1970 - 1) / 4 - (1970 - 1) / 100 + (1970 - 1) / 400)
173 + month_offset[month-1]
174 ) * 24 * 60 * 60;
175 p += 2;
176 if (end - p < 2) return -1;
177 /* Add the number of seconds of completed days of current month */
178 epoch += (10 * (p[0] - '0') + p[1] - '0' - 1) * 24 * 60 * 60;
179 p += 2;
180 if (end - p < 2) return -1;
181 /* Add the completed hours of the current day */
182 epoch += (10 * (p[0] - '0') + p[1] - '0') * 60 * 60;
183 p += 2;
184 if (end - p < 2) return -1;
185 /* Add the completed minutes of the current hour */
186 epoch += (10 * (p[0] - '0') + p[1] - '0') * 60;
187 p += 2;
188 if (p == end) return -1;
189 /* Test if there is available seconds */
190 if (p[0] < '0' || p[0] > '9')
191 goto nosec;
192 if (end - p < 2) return -1;
193 /* Add the seconds of the current minute */
194 epoch += 10 * (p[0] - '0') + p[1] - '0';
195 p += 2;
196 if (p == end) return -1;
197 /* Ignore seconds float part if present */
198 if (p[0] == '.') {
199 do {
200 if (++p == end) return -1;
201 } while (p[0] >= '0' && p[0] <= '9');
202 }
203
204nosec:
205 if (p[0] == 'Z') {
206 if (end - p != 1) return -1;
207 return epoch;
208 }
209 else if (p[0] == '+') {
210 if (end - p != 5) return -1;
211 /* Apply timezone offset */
212 return epoch - ((10 * (p[1] - '0') + p[2] - '0') * 60 + (10 * (p[3] - '0') + p[4] - '0')) * 60;
213 }
214 else if (p[0] == '-') {
215 if (end - p != 5) return -1;
216 /* Apply timezone offset */
217 return epoch + ((10 * (p[1] - '0') + p[2] - '0') * 60 + (10 * (p[3] - '0') + p[4] - '0')) * 60;
218 }
219
220 return -1;
221}
222
Emeric Brun1d3865b2014-06-20 15:37:32 +0200223static struct eb_root cert_ocsp_tree = EB_ROOT_UNIQUE;
Emeric Brun4147b2e2014-06-16 18:36:30 +0200224
225/* This function starts to check if the OCSP response (in DER format) contained
226 * in chunk 'ocsp_response' is valid (else exits on error).
227 * If 'cid' is not NULL, it will be compared to the OCSP certificate ID
228 * contained in the OCSP Response and exits on error if no match.
229 * If it's a valid OCSP Response:
230 * If 'ocsp' is not NULL, the chunk is copied in the OCSP response's container
231 * pointed by 'ocsp'.
232 * If 'ocsp' is NULL, the function looks up into the OCSP response's
233 * containers tree (using as index the ASN1 form of the OCSP Certificate ID extracted
234 * from the response) and exits on error if not found. Finally, If an OCSP response is
235 * already present in the container, it will be overwritten.
236 *
237 * Note: OCSP response containing more than one OCSP Single response is not
238 * considered valid.
239 *
240 * Returns 0 on success, 1 in error case.
241 */
242static int ssl_sock_load_ocsp_response(struct chunk *ocsp_response, struct certificate_ocsp *ocsp, OCSP_CERTID *cid, char **err)
243{
244 OCSP_RESPONSE *resp;
245 OCSP_BASICRESP *bs = NULL;
246 OCSP_SINGLERESP *sr;
247 unsigned char *p = (unsigned char *)ocsp_response->str;
248 int rc , count_sr;
Emeric Brun13a6b482014-06-20 15:44:34 +0200249 ASN1_GENERALIZEDTIME *revtime, *thisupd, *nextupd = NULL;
Emeric Brun4147b2e2014-06-16 18:36:30 +0200250 int reason;
251 int ret = 1;
252
253 resp = d2i_OCSP_RESPONSE(NULL, (const unsigned char **)&p, ocsp_response->len);
254 if (!resp) {
255 memprintf(err, "Unable to parse OCSP response");
256 goto out;
257 }
258
259 rc = OCSP_response_status(resp);
260 if (rc != OCSP_RESPONSE_STATUS_SUCCESSFUL) {
261 memprintf(err, "OCSP response status not successful");
262 goto out;
263 }
264
265 bs = OCSP_response_get1_basic(resp);
266 if (!bs) {
267 memprintf(err, "Failed to get basic response from OCSP Response");
268 goto out;
269 }
270
271 count_sr = OCSP_resp_count(bs);
272 if (count_sr > 1) {
273 memprintf(err, "OCSP response ignored because contains multiple single responses (%d)", count_sr);
274 goto out;
275 }
276
277 sr = OCSP_resp_get0(bs, 0);
278 if (!sr) {
279 memprintf(err, "Failed to get OCSP single response");
280 goto out;
281 }
282
283 rc = OCSP_single_get0_status(sr, &reason, &revtime, &thisupd, &nextupd);
284 if (rc != V_OCSP_CERTSTATUS_GOOD) {
285 memprintf(err, "OCSP single response: certificate status not good");
286 goto out;
287 }
288
Emeric Brun13a6b482014-06-20 15:44:34 +0200289 if (!nextupd) {
290 memprintf(err, "OCSP single response: missing nextupdate");
291 goto out;
292 }
293
Emeric Brunc8b27b62014-06-19 14:16:17 +0200294 rc = OCSP_check_validity(thisupd, nextupd, OCSP_MAX_RESPONSE_TIME_SKEW, -1);
Emeric Brun4147b2e2014-06-16 18:36:30 +0200295 if (!rc) {
296 memprintf(err, "OCSP single response: no longer valid.");
297 goto out;
298 }
299
300 if (cid) {
301 if (OCSP_id_cmp(sr->certId, cid)) {
302 memprintf(err, "OCSP single response: Certificate ID does not match certificate and issuer");
303 goto out;
304 }
305 }
306
307 if (!ocsp) {
308 unsigned char key[OCSP_MAX_CERTID_ASN1_LENGTH];
309 unsigned char *p;
310
311 rc = i2d_OCSP_CERTID(sr->certId, NULL);
312 if (!rc) {
313 memprintf(err, "OCSP single response: Unable to encode Certificate ID");
314 goto out;
315 }
316
317 if (rc > OCSP_MAX_CERTID_ASN1_LENGTH) {
318 memprintf(err, "OCSP single response: Certificate ID too long");
319 goto out;
320 }
321
322 p = key;
323 memset(key, 0, OCSP_MAX_CERTID_ASN1_LENGTH);
324 i2d_OCSP_CERTID(sr->certId, &p);
325 ocsp = (struct certificate_ocsp *)ebmb_lookup(&cert_ocsp_tree, key, OCSP_MAX_CERTID_ASN1_LENGTH);
326 if (!ocsp) {
327 memprintf(err, "OCSP single response: Certificate ID does not match any certificate or issuer");
328 goto out;
329 }
330 }
331
332 /* According to comments on "chunk_dup", the
333 previous chunk buffer will be freed */
334 if (!chunk_dup(&ocsp->response, ocsp_response)) {
335 memprintf(err, "OCSP response: Memory allocation error");
336 goto out;
337 }
338
Emeric Brun4f3c87a2014-06-20 15:46:13 +0200339 ocsp->expire = asn1_generalizedtime_to_epoch(nextupd) - OCSP_MAX_RESPONSE_TIME_SKEW;
340
Emeric Brun4147b2e2014-06-16 18:36:30 +0200341 ret = 0;
342out:
343 if (bs)
344 OCSP_BASICRESP_free(bs);
345
346 if (resp)
347 OCSP_RESPONSE_free(resp);
348
349 return ret;
350}
351/*
352 * External function use to update the OCSP response in the OCSP response's
353 * containers tree. The chunk 'ocsp_response' must contain the OCSP response
354 * to update in DER format.
355 *
356 * Returns 0 on success, 1 in error case.
357 */
358int ssl_sock_update_ocsp_response(struct chunk *ocsp_response, char **err)
359{
360 return ssl_sock_load_ocsp_response(ocsp_response, NULL, NULL, err);
361}
362
363/*
364 * This function load the OCSP Resonse in DER format contained in file at
365 * path 'ocsp_path' and call 'ssl_sock_load_ocsp_response'
366 *
367 * Returns 0 on success, 1 in error case.
368 */
369static int ssl_sock_load_ocsp_response_from_file(const char *ocsp_path, struct certificate_ocsp *ocsp, OCSP_CERTID *cid, char **err)
370{
371 int fd = -1;
372 int r = 0;
373 int ret = 1;
374
375 fd = open(ocsp_path, O_RDONLY);
376 if (fd == -1) {
377 memprintf(err, "Error opening OCSP response file");
378 goto end;
379 }
380
381 trash.len = 0;
382 while (trash.len < trash.size) {
383 r = read(fd, trash.str + trash.len, trash.size - trash.len);
384 if (r < 0) {
385 if (errno == EINTR)
386 continue;
387
388 memprintf(err, "Error reading OCSP response from file");
389 goto end;
390 }
391 else if (r == 0) {
392 break;
393 }
394 trash.len += r;
395 }
396
397 close(fd);
398 fd = -1;
399
400 ret = ssl_sock_load_ocsp_response(&trash, ocsp, cid, err);
401end:
402 if (fd != -1)
403 close(fd);
404
405 return ret;
406}
407
Nenad Merdanovic05552d42015-02-27 19:56:49 +0100408#if (defined SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB && TLS_TICKETS_NO > 0)
409static 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)
410{
411 struct tls_sess_key *keys;
412 struct connection *conn;
413 int head;
414 int i;
415
416 conn = (struct connection *)SSL_get_app_data(s);
Nenad Merdanovic146defa2015-05-09 08:46:00 +0200417 keys = objt_listener(conn->target)->bind_conf->keys_ref->tlskeys;
418 head = objt_listener(conn->target)->bind_conf->keys_ref->tls_ticket_enc_index;
Nenad Merdanovic05552d42015-02-27 19:56:49 +0100419
420 if (enc) {
421 memcpy(key_name, keys[head].name, 16);
422
423 if(!RAND_pseudo_bytes(iv, EVP_MAX_IV_LENGTH))
424 return -1;
425
426 if(!EVP_EncryptInit_ex(ectx, EVP_aes_128_cbc(), NULL, keys[head].aes_key, iv))
427 return -1;
428
429 HMAC_Init_ex(hctx, keys[head].hmac_key, 16, HASH_FUNCT(), NULL);
430
431 return 1;
432 } else {
433 for (i = 0; i < TLS_TICKETS_NO; i++) {
434 if (!memcmp(key_name, keys[(head + i) % TLS_TICKETS_NO].name, 16))
435 goto found;
436 }
437 return 0;
438
439 found:
440 HMAC_Init_ex(hctx, keys[(head + i) % TLS_TICKETS_NO].hmac_key, 16, HASH_FUNCT(), NULL);
441 if(!EVP_DecryptInit_ex(ectx, EVP_aes_128_cbc(), NULL, keys[(head + i) % TLS_TICKETS_NO].aes_key, iv))
442 return -1;
443 /* 2 for key renewal, 1 if current key is still valid */
444 return i ? 2 : 1;
445 }
Nenad Merdanovic200b0fa2015-05-09 08:46:01 +0200446}
447
448struct tls_keys_ref *tlskeys_ref_lookup(const char *filename)
449{
450 struct tls_keys_ref *ref;
451
452 list_for_each_entry(ref, &tlskeys_reference, list)
453 if (ref->filename && strcmp(filename, ref->filename) == 0)
454 return ref;
455 return NULL;
456}
457
458struct tls_keys_ref *tlskeys_ref_lookupid(int unique_id)
459{
460 struct tls_keys_ref *ref;
461
462 list_for_each_entry(ref, &tlskeys_reference, list)
463 if (ref->unique_id == unique_id)
464 return ref;
465 return NULL;
466}
467
468int ssl_sock_update_tlskey(char *filename, struct chunk *tlskey, char **err) {
469 struct tls_keys_ref *ref = tlskeys_ref_lookup(filename);
470
471 if(!ref) {
472 memprintf(err, "Unable to locate the referenced filename: %s", filename);
473 return 1;
474 }
475
476 memcpy((char *) (ref->tlskeys + 2 % TLS_TICKETS_NO), tlskey->str, tlskey->len);
477 ref->tls_ticket_enc_index = ref->tls_ticket_enc_index + 1 % TLS_TICKETS_NO;
478
479 return 0;
Nenad Merdanovic05552d42015-02-27 19:56:49 +0100480}
Nenad Merdanovic200b0fa2015-05-09 08:46:01 +0200481
482/* This function finalize the configuration parsing. Its set all the
483 * automatic ids
484 */
485void tlskeys_finalize_config(void)
486{
487 int i = 0;
488 struct tls_keys_ref *ref, *ref2, *ref3;
489 struct list tkr = LIST_HEAD_INIT(tkr);
490
491 list_for_each_entry(ref, &tlskeys_reference, list) {
492 if (ref->unique_id == -1) {
493 /* Look for the first free id. */
494 while (1) {
495 list_for_each_entry(ref2, &tlskeys_reference, list) {
496 if (ref2->unique_id == i) {
497 i++;
498 break;
499 }
500 }
501 if (&ref2->list == &tlskeys_reference)
502 break;
503 }
504
505 /* Uses the unique id and increment it for the next entry. */
506 ref->unique_id = i;
507 i++;
508 }
509 }
510
511 /* This sort the reference list by id. */
512 list_for_each_entry_safe(ref, ref2, &tlskeys_reference, list) {
513 LIST_DEL(&ref->list);
514 list_for_each_entry(ref3, &tkr, list) {
515 if (ref->unique_id < ref3->unique_id) {
516 LIST_ADDQ(&ref3->list, &ref->list);
517 break;
518 }
519 }
520 if (&ref3->list == &tkr)
521 LIST_ADDQ(&tkr, &ref->list);
522 }
523
524 /* swap root */
525 LIST_ADD(&tkr, &tlskeys_reference);
526 LIST_DEL(&tkr);
527}
528
Nenad Merdanovic05552d42015-02-27 19:56:49 +0100529#endif /* SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB */
530
Emeric Brun4147b2e2014-06-16 18:36:30 +0200531/*
532 * Callback used to set OCSP status extension content in server hello.
533 */
534int ssl_sock_ocsp_stapling_cbk(SSL *ssl, void *arg)
535{
536 struct certificate_ocsp *ocsp = (struct certificate_ocsp *)arg;
537 char* ssl_buf;
538
539 if (!ocsp ||
540 !ocsp->response.str ||
Emeric Brun4f3c87a2014-06-20 15:46:13 +0200541 !ocsp->response.len ||
542 (ocsp->expire < now.tv_sec))
Emeric Brun4147b2e2014-06-16 18:36:30 +0200543 return SSL_TLSEXT_ERR_NOACK;
544
545 ssl_buf = OPENSSL_malloc(ocsp->response.len);
546 if (!ssl_buf)
547 return SSL_TLSEXT_ERR_NOACK;
548
549 memcpy(ssl_buf, ocsp->response.str, ocsp->response.len);
550 SSL_set_tlsext_status_ocsp_resp(ssl, ssl_buf, ocsp->response.len);
551
552 return SSL_TLSEXT_ERR_OK;
553}
554
555/*
556 * This function enables the handling of OCSP status extension on 'ctx' if a
557 * file name 'cert_path' suffixed using ".ocsp" is present.
558 * To enable OCSP status extension, the issuer's certificate is mandatory.
559 * It should be present in the certificate's extra chain builded from file
560 * 'cert_path'. If not found, the issuer certificate is loaded from a file
561 * named 'cert_path' suffixed using '.issuer'.
562 *
563 * In addition, ".ocsp" file content is loaded as a DER format of an OCSP
564 * response. If file is empty or content is not a valid OCSP response,
565 * OCSP status extension is enabled but OCSP response is ignored (a warning
566 * is displayed).
567 *
568 * Returns 1 if no ".ocsp" file found, 0 if OCSP status extension is
569 * succesfully enabled, or -1 in other error case.
570 */
571static int ssl_sock_load_ocsp(SSL_CTX *ctx, const char *cert_path)
572{
573
574 BIO *in = NULL;
575 X509 *x, *xi = NULL, *issuer = NULL;
576 STACK_OF(X509) *chain = NULL;
577 OCSP_CERTID *cid = NULL;
578 SSL *ssl;
579 char ocsp_path[MAXPATHLEN+1];
580 int i, ret = -1;
581 struct stat st;
582 struct certificate_ocsp *ocsp = NULL, *iocsp;
583 char *warn = NULL;
584 unsigned char *p;
585
586 snprintf(ocsp_path, MAXPATHLEN+1, "%s.ocsp", cert_path);
587
588 if (stat(ocsp_path, &st))
589 return 1;
590
591 ssl = SSL_new(ctx);
592 if (!ssl)
593 goto out;
594
595 x = SSL_get_certificate(ssl);
596 if (!x)
597 goto out;
598
599 /* Try to lookup for issuer in certificate extra chain */
600#ifdef SSL_CTRL_GET_EXTRA_CHAIN_CERTS
601 SSL_CTX_get_extra_chain_certs(ctx, &chain);
602#else
603 chain = ctx->extra_certs;
604#endif
605 for (i = 0; i < sk_X509_num(chain); i++) {
606 issuer = sk_X509_value(chain, i);
607 if (X509_check_issued(issuer, x) == X509_V_OK)
608 break;
609 else
610 issuer = NULL;
611 }
612
613 /* If not found try to load issuer from a suffixed file */
614 if (!issuer) {
615 char issuer_path[MAXPATHLEN+1];
616
617 in = BIO_new(BIO_s_file());
618 if (!in)
619 goto out;
620
621 snprintf(issuer_path, MAXPATHLEN+1, "%s.issuer", cert_path);
622 if (BIO_read_filename(in, issuer_path) <= 0)
623 goto out;
624
625 xi = PEM_read_bio_X509_AUX(in, NULL, ctx->default_passwd_callback, ctx->default_passwd_callback_userdata);
626 if (!xi)
627 goto out;
628
629 if (X509_check_issued(xi, x) != X509_V_OK)
630 goto out;
631
632 issuer = xi;
633 }
634
635 cid = OCSP_cert_to_id(0, x, issuer);
636 if (!cid)
637 goto out;
638
639 i = i2d_OCSP_CERTID(cid, NULL);
640 if (!i || (i > OCSP_MAX_CERTID_ASN1_LENGTH))
641 goto out;
642
643 ocsp = calloc(1, sizeof(struct certificate_ocsp));
644 if (!ocsp)
645 goto out;
646
647 p = ocsp->key_data;
648 i2d_OCSP_CERTID(cid, &p);
649
650 iocsp = (struct certificate_ocsp *)ebmb_insert(&cert_ocsp_tree, &ocsp->key, OCSP_MAX_CERTID_ASN1_LENGTH);
651 if (iocsp == ocsp)
652 ocsp = NULL;
653
654 SSL_CTX_set_tlsext_status_cb(ctx, ssl_sock_ocsp_stapling_cbk);
655 SSL_CTX_set_tlsext_status_arg(ctx, iocsp);
656
657 ret = 0;
658
659 warn = NULL;
660 if (ssl_sock_load_ocsp_response_from_file(ocsp_path, iocsp, cid, &warn)) {
661 memprintf(&warn, "Loading '%s': %s. Content will be ignored", ocsp_path, warn ? warn : "failure");
662 Warning("%s.\n", warn);
663 }
664
665out:
666 if (ssl)
667 SSL_free(ssl);
668
669 if (in)
670 BIO_free(in);
671
672 if (xi)
673 X509_free(xi);
674
675 if (cid)
676 OCSP_CERTID_free(cid);
677
678 if (ocsp)
679 free(ocsp);
680
681 if (warn)
682 free(warn);
683
684
685 return ret;
686}
687
688#endif
689
Janusz Dziemidowicz2c701b52015-03-07 23:03:59 +0100690#if (OPENSSL_VERSION_NUMBER >= 0x1000200fL && !defined OPENSSL_NO_TLSEXT && !defined OPENSSL_IS_BORINGSSL)
691
692#define CT_EXTENSION_TYPE 18
693
694static int sctl_ex_index = -1;
695
696/*
697 * Try to parse Signed Certificate Timestamp List structure. This function
698 * makes only basic test if the data seems like SCTL. No signature validation
699 * is performed.
700 */
701static int ssl_sock_parse_sctl(struct chunk *sctl)
702{
703 int ret = 1;
704 int len, pos, sct_len;
705 unsigned char *data;
706
707 if (sctl->len < 2)
708 goto out;
709
710 data = (unsigned char *)sctl->str;
711 len = (data[0] << 8) | data[1];
712
713 if (len + 2 != sctl->len)
714 goto out;
715
716 data = data + 2;
717 pos = 0;
718 while (pos < len) {
719 if (len - pos < 2)
720 goto out;
721
722 sct_len = (data[pos] << 8) | data[pos + 1];
723 if (pos + sct_len + 2 > len)
724 goto out;
725
726 pos += sct_len + 2;
727 }
728
729 ret = 0;
730
731out:
732 return ret;
733}
734
735static int ssl_sock_load_sctl_from_file(const char *sctl_path, struct chunk **sctl)
736{
737 int fd = -1;
738 int r = 0;
739 int ret = 1;
740
741 *sctl = NULL;
742
743 fd = open(sctl_path, O_RDONLY);
744 if (fd == -1)
745 goto end;
746
747 trash.len = 0;
748 while (trash.len < trash.size) {
749 r = read(fd, trash.str + trash.len, trash.size - trash.len);
750 if (r < 0) {
751 if (errno == EINTR)
752 continue;
753
754 goto end;
755 }
756 else if (r == 0) {
757 break;
758 }
759 trash.len += r;
760 }
761
762 ret = ssl_sock_parse_sctl(&trash);
763 if (ret)
764 goto end;
765
766 *sctl = calloc(1, sizeof(struct chunk));
767 if (!chunk_dup(*sctl, &trash)) {
768 free(*sctl);
769 *sctl = NULL;
770 goto end;
771 }
772
773end:
774 if (fd != -1)
775 close(fd);
776
777 return ret;
778}
779
780int ssl_sock_sctl_add_cbk(SSL *ssl, unsigned ext_type, const unsigned char **out, size_t *outlen, int *al, void *add_arg)
781{
782 struct chunk *sctl = (struct chunk *)add_arg;
783
784 *out = (unsigned char *)sctl->str;
785 *outlen = sctl->len;
786
787 return 1;
788}
789
790int ssl_sock_sctl_parse_cbk(SSL *s, unsigned int ext_type, const unsigned char *in, size_t inlen, int *al, void *parse_arg)
791{
792 return 1;
793}
794
795static int ssl_sock_load_sctl(SSL_CTX *ctx, const char *cert_path)
796{
797 char sctl_path[MAXPATHLEN+1];
798 int ret = -1;
799 struct stat st;
800 struct chunk *sctl = NULL;
801
802 snprintf(sctl_path, MAXPATHLEN+1, "%s.sctl", cert_path);
803
804 if (stat(sctl_path, &st))
805 return 1;
806
807 if (ssl_sock_load_sctl_from_file(sctl_path, &sctl))
808 goto out;
809
810 if (!SSL_CTX_add_server_custom_ext(ctx, CT_EXTENSION_TYPE, ssl_sock_sctl_add_cbk, NULL, sctl, ssl_sock_sctl_parse_cbk, NULL)) {
811 free(sctl);
812 goto out;
813 }
814
815 SSL_CTX_set_ex_data(ctx, sctl_ex_index, sctl);
816
817 ret = 0;
818
819out:
820 return ret;
821}
822
823#endif
824
Emeric Brune1f38db2012-09-03 20:36:47 +0200825void ssl_sock_infocbk(const SSL *ssl, int where, int ret)
826{
827 struct connection *conn = (struct connection *)SSL_get_app_data(ssl);
Emeric Brund8b2bb52014-01-28 15:43:53 +0100828 BIO *write_bio;
Willy Tarreau622317d2015-02-27 16:36:16 +0100829 (void)ret; /* shut gcc stupid warning */
Emeric Brune1f38db2012-09-03 20:36:47 +0200830
831 if (where & SSL_CB_HANDSHAKE_START) {
832 /* Disable renegotiation (CVE-2009-3555) */
Willy Tarreau20879a02012-12-03 16:32:10 +0100833 if (conn->flags & CO_FL_CONNECTED) {
Emeric Brune1f38db2012-09-03 20:36:47 +0200834 conn->flags |= CO_FL_ERROR;
Willy Tarreau20879a02012-12-03 16:32:10 +0100835 conn->err_code = CO_ER_SSL_RENEG;
836 }
Emeric Brune1f38db2012-09-03 20:36:47 +0200837 }
Emeric Brund8b2bb52014-01-28 15:43:53 +0100838
839 if ((where & SSL_CB_ACCEPT_LOOP) == SSL_CB_ACCEPT_LOOP) {
840 if (!(conn->xprt_st & SSL_SOCK_ST_FL_16K_WBFSIZE)) {
841 /* Long certificate chains optimz
842 If write and read bios are differents, we
843 consider that the buffering was activated,
844 so we rise the output buffer size from 4k
845 to 16k */
846 write_bio = SSL_get_wbio(ssl);
847 if (write_bio != SSL_get_rbio(ssl)) {
848 BIO_set_write_buffer_size(write_bio, 16384);
849 conn->xprt_st |= SSL_SOCK_ST_FL_16K_WBFSIZE;
850 }
851 }
852 }
Emeric Brunfc0421f2012-09-07 17:30:07 +0200853}
854
Emeric Brune64aef12012-09-21 13:15:06 +0200855/* Callback is called for each certificate of the chain during a verify
856 ok is set to 1 if preverify detect no error on current certificate.
857 Returns 0 to break the handshake, 1 otherwise. */
Evan Broderbe554312013-06-27 00:05:25 -0700858int ssl_sock_bind_verifycbk(int ok, X509_STORE_CTX *x_store)
Emeric Brune64aef12012-09-21 13:15:06 +0200859{
860 SSL *ssl;
861 struct connection *conn;
Emeric Brun81c00f02012-09-21 14:31:21 +0200862 int err, depth;
Emeric Brune64aef12012-09-21 13:15:06 +0200863
864 ssl = X509_STORE_CTX_get_ex_data(x_store, SSL_get_ex_data_X509_STORE_CTX_idx());
865 conn = (struct connection *)SSL_get_app_data(ssl);
866
Willy Tarreauf7bc57c2012-10-03 00:19:48 +0200867 conn->xprt_st |= SSL_SOCK_ST_FL_VERIFY_DONE;
Emeric Brune64aef12012-09-21 13:15:06 +0200868
Emeric Brun81c00f02012-09-21 14:31:21 +0200869 if (ok) /* no errors */
870 return ok;
871
872 depth = X509_STORE_CTX_get_error_depth(x_store);
873 err = X509_STORE_CTX_get_error(x_store);
874
875 /* check if CA error needs to be ignored */
876 if (depth > 0) {
Willy Tarreauf7bc57c2012-10-03 00:19:48 +0200877 if (!SSL_SOCK_ST_TO_CA_ERROR(conn->xprt_st)) {
878 conn->xprt_st |= SSL_SOCK_CA_ERROR_TO_ST(err);
879 conn->xprt_st |= SSL_SOCK_CAEDEPTH_TO_ST(depth);
Emeric Brunf282a812012-09-21 15:27:54 +0200880 }
881
Emeric Brun1eb20ef2012-12-03 13:24:29 +0100882 if (objt_listener(conn->target)->bind_conf->ca_ignerr & (1ULL << err)) {
883 ERR_clear_error();
Emeric Brun81c00f02012-09-21 14:31:21 +0200884 return 1;
Emeric Brun1eb20ef2012-12-03 13:24:29 +0100885 }
Emeric Brun81c00f02012-09-21 14:31:21 +0200886
Willy Tarreau20879a02012-12-03 16:32:10 +0100887 conn->err_code = CO_ER_SSL_CA_FAIL;
Emeric Brun81c00f02012-09-21 14:31:21 +0200888 return 0;
889 }
890
Willy Tarreauf7bc57c2012-10-03 00:19:48 +0200891 if (!SSL_SOCK_ST_TO_CRTERROR(conn->xprt_st))
892 conn->xprt_st |= SSL_SOCK_CRTERROR_TO_ST(err);
Emeric Brunf282a812012-09-21 15:27:54 +0200893
Emeric Brun81c00f02012-09-21 14:31:21 +0200894 /* check if certificate error needs to be ignored */
Emeric Brun1eb20ef2012-12-03 13:24:29 +0100895 if (objt_listener(conn->target)->bind_conf->crt_ignerr & (1ULL << err)) {
896 ERR_clear_error();
Emeric Brun81c00f02012-09-21 14:31:21 +0200897 return 1;
Emeric Brun1eb20ef2012-12-03 13:24:29 +0100898 }
Emeric Brun81c00f02012-09-21 14:31:21 +0200899
Willy Tarreau20879a02012-12-03 16:32:10 +0100900 conn->err_code = CO_ER_SSL_CRT_FAIL;
Emeric Brun81c00f02012-09-21 14:31:21 +0200901 return 0;
Emeric Brune64aef12012-09-21 13:15:06 +0200902}
903
Emeric Brun29f037d2014-04-25 19:05:36 +0200904/* Callback is called for ssl protocol analyse */
905void ssl_sock_msgcbk(int write_p, int version, int content_type, const void *buf, size_t len, SSL *ssl, void *arg)
906{
Emeric Brun29f037d2014-04-25 19:05:36 +0200907#ifdef TLS1_RT_HEARTBEAT
908 /* test heartbeat received (write_p is set to 0
909 for a received record) */
Willy Tarreauf51c6982014-04-25 20:02:39 +0200910 if ((content_type == TLS1_RT_HEARTBEAT) && (write_p == 0)) {
Willy Tarreau84815002014-04-25 21:40:27 +0200911 struct connection *conn = (struct connection *)SSL_get_app_data(ssl);
Willy Tarreauf51c6982014-04-25 20:02:39 +0200912 const unsigned char *p = buf;
913 unsigned int payload;
914
Emeric Brun29f037d2014-04-25 19:05:36 +0200915 conn->xprt_st |= SSL_SOCK_RECV_HEARTBEAT;
Willy Tarreauf51c6982014-04-25 20:02:39 +0200916
917 /* Check if this is a CVE-2014-0160 exploitation attempt. */
918 if (*p != TLS1_HB_REQUEST)
919 return;
920
Willy Tarreauaeed6722014-04-25 23:59:58 +0200921 if (len < 1 + 2 + 16) /* 1 type + 2 size + 0 payload + 16 padding */
Willy Tarreauf51c6982014-04-25 20:02:39 +0200922 goto kill_it;
923
924 payload = (p[1] * 256) + p[2];
Willy Tarreau3b2fdb62014-04-25 23:44:22 +0200925 if (3 + payload + 16 <= len)
Willy Tarreauf51c6982014-04-25 20:02:39 +0200926 return; /* OK no problem */
Willy Tarreauaeed6722014-04-25 23:59:58 +0200927 kill_it:
Willy Tarreau3b2fdb62014-04-25 23:44:22 +0200928 /* We have a clear heartbleed attack (CVE-2014-0160), the
929 * advertised payload is larger than the advertised packet
930 * length, so we have garbage in the buffer between the
931 * payload and the end of the buffer (p+len). We can't know
932 * if the SSL stack is patched, and we don't know if we can
933 * safely wipe out the area between p+3+len and payload.
934 * So instead, we prevent the response from being sent by
935 * setting the max_send_fragment to 0 and we report an SSL
936 * error, which will kill this connection. It will be reported
937 * above as SSL_ERROR_SSL while an other handshake failure with
Willy Tarreauf51c6982014-04-25 20:02:39 +0200938 * a heartbeat message will be reported as SSL_ERROR_SYSCALL.
939 */
Willy Tarreau3b2fdb62014-04-25 23:44:22 +0200940 ssl->max_send_fragment = 0;
Willy Tarreauf51c6982014-04-25 20:02:39 +0200941 SSLerr(SSL_F_TLS1_HEARTBEAT, SSL_R_SSL_HANDSHAKE_FAILURE);
942 return;
943 }
Emeric Brun29f037d2014-04-25 19:05:36 +0200944#endif
945}
946
Willy Tarreau6c9a3d52012-10-18 18:57:14 +0200947#ifdef OPENSSL_NPN_NEGOTIATED
948/* This callback is used so that the server advertises the list of
949 * negociable protocols for NPN.
950 */
951static int ssl_sock_advertise_npn_protos(SSL *s, const unsigned char **data,
952 unsigned int *len, void *arg)
953{
954 struct bind_conf *conf = arg;
955
956 *data = (const unsigned char *)conf->npn_str;
957 *len = conf->npn_len;
958 return SSL_TLSEXT_ERR_OK;
959}
960#endif
961
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +0100962#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Willy Tarreauab861d32013-04-02 02:30:41 +0200963/* This callback is used so that the server advertises the list of
964 * negociable protocols for ALPN.
965 */
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +0100966static int ssl_sock_advertise_alpn_protos(SSL *s, const unsigned char **out,
967 unsigned char *outlen,
968 const unsigned char *server,
969 unsigned int server_len, void *arg)
Willy Tarreauab861d32013-04-02 02:30:41 +0200970{
971 struct bind_conf *conf = arg;
972
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +0100973 if (SSL_select_next_proto((unsigned char**) out, outlen, (const unsigned char *)conf->alpn_str,
974 conf->alpn_len, server, server_len) != OPENSSL_NPN_NEGOTIATED) {
975 return SSL_TLSEXT_ERR_NOACK;
976 }
Willy Tarreauab861d32013-04-02 02:30:41 +0200977 return SSL_TLSEXT_ERR_OK;
978}
979#endif
980
Emeric Brunfc0421f2012-09-07 17:30:07 +0200981#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
982/* Sets the SSL ctx of <ssl> to match the advertised server name. Returns a
983 * warning when no match is found, which implies the default (first) cert
984 * will keep being used.
985 */
Willy Tarreau2a65ff02012-09-13 17:54:29 +0200986static int ssl_sock_switchctx_cbk(SSL *ssl, int *al, struct bind_conf *s)
Emeric Brunfc0421f2012-09-07 17:30:07 +0200987{
988 const char *servername;
989 const char *wildp = NULL;
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +0200990 struct ebmb_node *node, *n;
Emeric Brunfc0421f2012-09-07 17:30:07 +0200991 int i;
992 (void)al; /* shut gcc stupid warning */
993
994 servername = SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name);
Emmanuel Hocdet65623372013-01-24 17:17:15 +0100995 if (!servername) {
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +0200996 return (s->strict_sni ?
997 SSL_TLSEXT_ERR_ALERT_FATAL :
Emmanuel Hocdet79274e22013-05-31 12:47:44 +0200998 SSL_TLSEXT_ERR_NOACK);
Emmanuel Hocdet65623372013-01-24 17:17:15 +0100999 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02001000
Willy Tarreau19d14ef2012-10-29 16:51:55 +01001001 for (i = 0; i < trash.size; i++) {
Emeric Brunfc0421f2012-09-07 17:30:07 +02001002 if (!servername[i])
1003 break;
Willy Tarreau19d14ef2012-10-29 16:51:55 +01001004 trash.str[i] = tolower(servername[i]);
1005 if (!wildp && (trash.str[i] == '.'))
1006 wildp = &trash.str[i];
Emeric Brunfc0421f2012-09-07 17:30:07 +02001007 }
Willy Tarreau19d14ef2012-10-29 16:51:55 +01001008 trash.str[i] = 0;
Emeric Brunfc0421f2012-09-07 17:30:07 +02001009
1010 /* lookup in full qualified names */
Willy Tarreau19d14ef2012-10-29 16:51:55 +01001011 node = ebst_lookup(&s->sni_ctx, trash.str);
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001012
1013 /* lookup a not neg filter */
1014 for (n = node; n; n = ebmb_next_dup(n)) {
1015 if (!container_of(n, struct sni_ctx, name)->neg) {
1016 node = n;
1017 break;
Emmanuel Hocdet65623372013-01-24 17:17:15 +01001018 }
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001019 }
1020 if (!node && wildp) {
1021 /* lookup in wildcards names */
Emeric Brunfc0421f2012-09-07 17:30:07 +02001022 node = ebst_lookup(&s->sni_w_ctx, wildp);
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001023 }
1024 if (!node || container_of(node, struct sni_ctx, name)->neg) {
1025 return (s->strict_sni ?
1026 SSL_TLSEXT_ERR_ALERT_FATAL :
1027 SSL_TLSEXT_ERR_ALERT_WARNING);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001028 }
1029
1030 /* switch ctx */
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001031 SSL_set_SSL_CTX(ssl, container_of(node, struct sni_ctx, name)->ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001032 return SSL_TLSEXT_ERR_OK;
1033}
1034#endif /* SSL_CTRL_SET_TLSEXT_HOSTNAME */
1035
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001036#ifndef OPENSSL_NO_DH
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001037
1038static DH * ssl_get_dh_1024(void)
1039{
Lukas Tribus4c0d45a2014-08-18 00:56:32 +02001040#if (OPENSSL_VERSION_NUMBER < 0x0090801fL || defined OPENSSL_IS_BORINGSSL)
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001041 static const unsigned char rfc_2409_prime_1024[] = {
1042 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xC9,0x0F,0xDA,0xA2,
1043 0x21,0x68,0xC2,0x34,0xC4,0xC6,0x62,0x8B,0x80,0xDC,0x1C,0xD1,
1044 0x29,0x02,0x4E,0x08,0x8A,0x67,0xCC,0x74,0x02,0x0B,0xBE,0xA6,
1045 0x3B,0x13,0x9B,0x22,0x51,0x4A,0x08,0x79,0x8E,0x34,0x04,0xDD,
1046 0xEF,0x95,0x19,0xB3,0xCD,0x3A,0x43,0x1B,0x30,0x2B,0x0A,0x6D,
1047 0xF2,0x5F,0x14,0x37,0x4F,0xE1,0x35,0x6D,0x6D,0x51,0xC2,0x45,
1048 0xE4,0x85,0xB5,0x76,0x62,0x5E,0x7E,0xC6,0xF4,0x4C,0x42,0xE9,
1049 0xA6,0x37,0xED,0x6B,0x0B,0xFF,0x5C,0xB6,0xF4,0x06,0xB7,0xED,
1050 0xEE,0x38,0x6B,0xFB,0x5A,0x89,0x9F,0xA5,0xAE,0x9F,0x24,0x11,
1051 0x7C,0x4B,0x1F,0xE6,0x49,0x28,0x66,0x51,0xEC,0xE6,0x53,0x81,
1052 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
1053 };
1054#endif
1055 DH *dh = DH_new();
1056 if (dh) {
Lukas Tribus4c0d45a2014-08-18 00:56:32 +02001057#if (OPENSSL_VERSION_NUMBER >= 0x0090801fL && !defined OPENSSL_IS_BORINGSSL)
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001058 dh->p = get_rfc2409_prime_1024(NULL);
1059#else
1060 dh->p = BN_bin2bn(rfc_2409_prime_1024, sizeof rfc_2409_prime_1024, NULL);
1061#endif
1062 /* See RFC 2409, Section 6 "Oakley Groups"
1063 for the reason why 2 is used as generator.
1064 */
1065 BN_dec2bn(&dh->g, "2");
1066 if (!dh->p || !dh->g) {
1067 DH_free(dh);
1068 dh = NULL;
1069 }
1070 }
1071 return dh;
1072}
1073
1074static DH *ssl_get_dh_2048(void)
1075{
Lukas Tribus4c0d45a2014-08-18 00:56:32 +02001076#if (OPENSSL_VERSION_NUMBER < 0x0090801fL || defined OPENSSL_IS_BORINGSSL)
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001077 static const unsigned char rfc_3526_prime_2048[] = {
1078 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xC9,0x0F,0xDA,0xA2,
1079 0x21,0x68,0xC2,0x34,0xC4,0xC6,0x62,0x8B,0x80,0xDC,0x1C,0xD1,
1080 0x29,0x02,0x4E,0x08,0x8A,0x67,0xCC,0x74,0x02,0x0B,0xBE,0xA6,
1081 0x3B,0x13,0x9B,0x22,0x51,0x4A,0x08,0x79,0x8E,0x34,0x04,0xDD,
1082 0xEF,0x95,0x19,0xB3,0xCD,0x3A,0x43,0x1B,0x30,0x2B,0x0A,0x6D,
1083 0xF2,0x5F,0x14,0x37,0x4F,0xE1,0x35,0x6D,0x6D,0x51,0xC2,0x45,
1084 0xE4,0x85,0xB5,0x76,0x62,0x5E,0x7E,0xC6,0xF4,0x4C,0x42,0xE9,
1085 0xA6,0x37,0xED,0x6B,0x0B,0xFF,0x5C,0xB6,0xF4,0x06,0xB7,0xED,
1086 0xEE,0x38,0x6B,0xFB,0x5A,0x89,0x9F,0xA5,0xAE,0x9F,0x24,0x11,
1087 0x7C,0x4B,0x1F,0xE6,0x49,0x28,0x66,0x51,0xEC,0xE4,0x5B,0x3D,
1088 0xC2,0x00,0x7C,0xB8,0xA1,0x63,0xBF,0x05,0x98,0xDA,0x48,0x36,
1089 0x1C,0x55,0xD3,0x9A,0x69,0x16,0x3F,0xA8,0xFD,0x24,0xCF,0x5F,
1090 0x83,0x65,0x5D,0x23,0xDC,0xA3,0xAD,0x96,0x1C,0x62,0xF3,0x56,
1091 0x20,0x85,0x52,0xBB,0x9E,0xD5,0x29,0x07,0x70,0x96,0x96,0x6D,
1092 0x67,0x0C,0x35,0x4E,0x4A,0xBC,0x98,0x04,0xF1,0x74,0x6C,0x08,
1093 0xCA,0x18,0x21,0x7C,0x32,0x90,0x5E,0x46,0x2E,0x36,0xCE,0x3B,
1094 0xE3,0x9E,0x77,0x2C,0x18,0x0E,0x86,0x03,0x9B,0x27,0x83,0xA2,
1095 0xEC,0x07,0xA2,0x8F,0xB5,0xC5,0x5D,0xF0,0x6F,0x4C,0x52,0xC9,
1096 0xDE,0x2B,0xCB,0xF6,0x95,0x58,0x17,0x18,0x39,0x95,0x49,0x7C,
1097 0xEA,0x95,0x6A,0xE5,0x15,0xD2,0x26,0x18,0x98,0xFA,0x05,0x10,
1098 0x15,0x72,0x8E,0x5A,0x8A,0xAC,0xAA,0x68,0xFF,0xFF,0xFF,0xFF,
1099 0xFF,0xFF,0xFF,0xFF,
1100 };
1101#endif
1102 DH *dh = DH_new();
1103 if (dh) {
Lukas Tribus4c0d45a2014-08-18 00:56:32 +02001104#if (OPENSSL_VERSION_NUMBER >= 0x0090801fL && !defined OPENSSL_IS_BORINGSSL)
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001105 dh->p = get_rfc3526_prime_2048(NULL);
1106#else
1107 dh->p = BN_bin2bn(rfc_3526_prime_2048, sizeof rfc_3526_prime_2048, NULL);
1108#endif
1109 /* See RFC 3526, Section 3 "2048-bit MODP Group"
1110 for the reason why 2 is used as generator.
1111 */
1112 BN_dec2bn(&dh->g, "2");
1113 if (!dh->p || !dh->g) {
1114 DH_free(dh);
1115 dh = NULL;
1116 }
1117 }
1118 return dh;
1119}
1120
1121static DH *ssl_get_dh_4096(void)
1122{
Lukas Tribus4c0d45a2014-08-18 00:56:32 +02001123#if (OPENSSL_VERSION_NUMBER < 0x0090801fL || defined OPENSSL_IS_BORINGSSL)
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001124 static const unsigned char rfc_3526_prime_4096[] = {
1125 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xC9,0x0F,0xDA,0xA2,
1126 0x21,0x68,0xC2,0x34,0xC4,0xC6,0x62,0x8B,0x80,0xDC,0x1C,0xD1,
1127 0x29,0x02,0x4E,0x08,0x8A,0x67,0xCC,0x74,0x02,0x0B,0xBE,0xA6,
1128 0x3B,0x13,0x9B,0x22,0x51,0x4A,0x08,0x79,0x8E,0x34,0x04,0xDD,
1129 0xEF,0x95,0x19,0xB3,0xCD,0x3A,0x43,0x1B,0x30,0x2B,0x0A,0x6D,
1130 0xF2,0x5F,0x14,0x37,0x4F,0xE1,0x35,0x6D,0x6D,0x51,0xC2,0x45,
1131 0xE4,0x85,0xB5,0x76,0x62,0x5E,0x7E,0xC6,0xF4,0x4C,0x42,0xE9,
1132 0xA6,0x37,0xED,0x6B,0x0B,0xFF,0x5C,0xB6,0xF4,0x06,0xB7,0xED,
1133 0xEE,0x38,0x6B,0xFB,0x5A,0x89,0x9F,0xA5,0xAE,0x9F,0x24,0x11,
1134 0x7C,0x4B,0x1F,0xE6,0x49,0x28,0x66,0x51,0xEC,0xE4,0x5B,0x3D,
1135 0xC2,0x00,0x7C,0xB8,0xA1,0x63,0xBF,0x05,0x98,0xDA,0x48,0x36,
1136 0x1C,0x55,0xD3,0x9A,0x69,0x16,0x3F,0xA8,0xFD,0x24,0xCF,0x5F,
1137 0x83,0x65,0x5D,0x23,0xDC,0xA3,0xAD,0x96,0x1C,0x62,0xF3,0x56,
1138 0x20,0x85,0x52,0xBB,0x9E,0xD5,0x29,0x07,0x70,0x96,0x96,0x6D,
1139 0x67,0x0C,0x35,0x4E,0x4A,0xBC,0x98,0x04,0xF1,0x74,0x6C,0x08,
1140 0xCA,0x18,0x21,0x7C,0x32,0x90,0x5E,0x46,0x2E,0x36,0xCE,0x3B,
1141 0xE3,0x9E,0x77,0x2C,0x18,0x0E,0x86,0x03,0x9B,0x27,0x83,0xA2,
1142 0xEC,0x07,0xA2,0x8F,0xB5,0xC5,0x5D,0xF0,0x6F,0x4C,0x52,0xC9,
1143 0xDE,0x2B,0xCB,0xF6,0x95,0x58,0x17,0x18,0x39,0x95,0x49,0x7C,
1144 0xEA,0x95,0x6A,0xE5,0x15,0xD2,0x26,0x18,0x98,0xFA,0x05,0x10,
1145 0x15,0x72,0x8E,0x5A,0x8A,0xAA,0xC4,0x2D,0xAD,0x33,0x17,0x0D,
1146 0x04,0x50,0x7A,0x33,0xA8,0x55,0x21,0xAB,0xDF,0x1C,0xBA,0x64,
1147 0xEC,0xFB,0x85,0x04,0x58,0xDB,0xEF,0x0A,0x8A,0xEA,0x71,0x57,
1148 0x5D,0x06,0x0C,0x7D,0xB3,0x97,0x0F,0x85,0xA6,0xE1,0xE4,0xC7,
1149 0xAB,0xF5,0xAE,0x8C,0xDB,0x09,0x33,0xD7,0x1E,0x8C,0x94,0xE0,
1150 0x4A,0x25,0x61,0x9D,0xCE,0xE3,0xD2,0x26,0x1A,0xD2,0xEE,0x6B,
1151 0xF1,0x2F,0xFA,0x06,0xD9,0x8A,0x08,0x64,0xD8,0x76,0x02,0x73,
1152 0x3E,0xC8,0x6A,0x64,0x52,0x1F,0x2B,0x18,0x17,0x7B,0x20,0x0C,
1153 0xBB,0xE1,0x17,0x57,0x7A,0x61,0x5D,0x6C,0x77,0x09,0x88,0xC0,
1154 0xBA,0xD9,0x46,0xE2,0x08,0xE2,0x4F,0xA0,0x74,0xE5,0xAB,0x31,
1155 0x43,0xDB,0x5B,0xFC,0xE0,0xFD,0x10,0x8E,0x4B,0x82,0xD1,0x20,
1156 0xA9,0x21,0x08,0x01,0x1A,0x72,0x3C,0x12,0xA7,0x87,0xE6,0xD7,
1157 0x88,0x71,0x9A,0x10,0xBD,0xBA,0x5B,0x26,0x99,0xC3,0x27,0x18,
1158 0x6A,0xF4,0xE2,0x3C,0x1A,0x94,0x68,0x34,0xB6,0x15,0x0B,0xDA,
1159 0x25,0x83,0xE9,0xCA,0x2A,0xD4,0x4C,0xE8,0xDB,0xBB,0xC2,0xDB,
1160 0x04,0xDE,0x8E,0xF9,0x2E,0x8E,0xFC,0x14,0x1F,0xBE,0xCA,0xA6,
1161 0x28,0x7C,0x59,0x47,0x4E,0x6B,0xC0,0x5D,0x99,0xB2,0x96,0x4F,
1162 0xA0,0x90,0xC3,0xA2,0x23,0x3B,0xA1,0x86,0x51,0x5B,0xE7,0xED,
1163 0x1F,0x61,0x29,0x70,0xCE,0xE2,0xD7,0xAF,0xB8,0x1B,0xDD,0x76,
1164 0x21,0x70,0x48,0x1C,0xD0,0x06,0x91,0x27,0xD5,0xB0,0x5A,0xA9,
1165 0x93,0xB4,0xEA,0x98,0x8D,0x8F,0xDD,0xC1,0x86,0xFF,0xB7,0xDC,
1166 0x90,0xA6,0xC0,0x8F,0x4D,0xF4,0x35,0xC9,0x34,0x06,0x31,0x99,
1167 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
1168 };
1169#endif
1170 DH *dh = DH_new();
1171 if (dh) {
Lukas Tribus4c0d45a2014-08-18 00:56:32 +02001172#if (OPENSSL_VERSION_NUMBER >= 0x0090801fL && !defined OPENSSL_IS_BORINGSSL)
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001173 dh->p = get_rfc3526_prime_4096(NULL);
1174#else
1175 dh->p = BN_bin2bn(rfc_3526_prime_4096, sizeof rfc_3526_prime_4096, NULL);
1176#endif
1177 /* See RFC 3526, Section 5 "4096-bit MODP Group"
1178 for the reason why 2 is used as generator.
1179 */
1180 BN_dec2bn(&dh->g, "2");
1181 if (!dh->p || !dh->g) {
1182 DH_free(dh);
1183 dh = NULL;
1184 }
1185 }
1186 return dh;
1187}
1188
1189static DH *ssl_get_dh_8192(void)
1190{
Lukas Tribus4c0d45a2014-08-18 00:56:32 +02001191#if (OPENSSL_VERSION_NUMBER < 0x0090801fL || defined OPENSSL_IS_BORINGSSL)
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001192 static const unsigned char rfc_3526_prime_8192[] = {
1193 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xC9,0x0F,0xDA,0xA2,
1194 0x21,0x68,0xC2,0x34,0xC4,0xC6,0x62,0x8B,0x80,0xDC,0x1C,0xD1,
1195 0x29,0x02,0x4E,0x08,0x8A,0x67,0xCC,0x74,0x02,0x0B,0xBE,0xA6,
1196 0x3B,0x13,0x9B,0x22,0x51,0x4A,0x08,0x79,0x8E,0x34,0x04,0xDD,
1197 0xEF,0x95,0x19,0xB3,0xCD,0x3A,0x43,0x1B,0x30,0x2B,0x0A,0x6D,
1198 0xF2,0x5F,0x14,0x37,0x4F,0xE1,0x35,0x6D,0x6D,0x51,0xC2,0x45,
1199 0xE4,0x85,0xB5,0x76,0x62,0x5E,0x7E,0xC6,0xF4,0x4C,0x42,0xE9,
1200 0xA6,0x37,0xED,0x6B,0x0B,0xFF,0x5C,0xB6,0xF4,0x06,0xB7,0xED,
1201 0xEE,0x38,0x6B,0xFB,0x5A,0x89,0x9F,0xA5,0xAE,0x9F,0x24,0x11,
1202 0x7C,0x4B,0x1F,0xE6,0x49,0x28,0x66,0x51,0xEC,0xE4,0x5B,0x3D,
1203 0xC2,0x00,0x7C,0xB8,0xA1,0x63,0xBF,0x05,0x98,0xDA,0x48,0x36,
1204 0x1C,0x55,0xD3,0x9A,0x69,0x16,0x3F,0xA8,0xFD,0x24,0xCF,0x5F,
1205 0x83,0x65,0x5D,0x23,0xDC,0xA3,0xAD,0x96,0x1C,0x62,0xF3,0x56,
1206 0x20,0x85,0x52,0xBB,0x9E,0xD5,0x29,0x07,0x70,0x96,0x96,0x6D,
1207 0x67,0x0C,0x35,0x4E,0x4A,0xBC,0x98,0x04,0xF1,0x74,0x6C,0x08,
1208 0xCA,0x18,0x21,0x7C,0x32,0x90,0x5E,0x46,0x2E,0x36,0xCE,0x3B,
1209 0xE3,0x9E,0x77,0x2C,0x18,0x0E,0x86,0x03,0x9B,0x27,0x83,0xA2,
1210 0xEC,0x07,0xA2,0x8F,0xB5,0xC5,0x5D,0xF0,0x6F,0x4C,0x52,0xC9,
1211 0xDE,0x2B,0xCB,0xF6,0x95,0x58,0x17,0x18,0x39,0x95,0x49,0x7C,
1212 0xEA,0x95,0x6A,0xE5,0x15,0xD2,0x26,0x18,0x98,0xFA,0x05,0x10,
1213 0x15,0x72,0x8E,0x5A,0x8A,0xAA,0xC4,0x2D,0xAD,0x33,0x17,0x0D,
1214 0x04,0x50,0x7A,0x33,0xA8,0x55,0x21,0xAB,0xDF,0x1C,0xBA,0x64,
1215 0xEC,0xFB,0x85,0x04,0x58,0xDB,0xEF,0x0A,0x8A,0xEA,0x71,0x57,
1216 0x5D,0x06,0x0C,0x7D,0xB3,0x97,0x0F,0x85,0xA6,0xE1,0xE4,0xC7,
1217 0xAB,0xF5,0xAE,0x8C,0xDB,0x09,0x33,0xD7,0x1E,0x8C,0x94,0xE0,
1218 0x4A,0x25,0x61,0x9D,0xCE,0xE3,0xD2,0x26,0x1A,0xD2,0xEE,0x6B,
1219 0xF1,0x2F,0xFA,0x06,0xD9,0x8A,0x08,0x64,0xD8,0x76,0x02,0x73,
1220 0x3E,0xC8,0x6A,0x64,0x52,0x1F,0x2B,0x18,0x17,0x7B,0x20,0x0C,
1221 0xBB,0xE1,0x17,0x57,0x7A,0x61,0x5D,0x6C,0x77,0x09,0x88,0xC0,
1222 0xBA,0xD9,0x46,0xE2,0x08,0xE2,0x4F,0xA0,0x74,0xE5,0xAB,0x31,
1223 0x43,0xDB,0x5B,0xFC,0xE0,0xFD,0x10,0x8E,0x4B,0x82,0xD1,0x20,
1224 0xA9,0x21,0x08,0x01,0x1A,0x72,0x3C,0x12,0xA7,0x87,0xE6,0xD7,
1225 0x88,0x71,0x9A,0x10,0xBD,0xBA,0x5B,0x26,0x99,0xC3,0x27,0x18,
1226 0x6A,0xF4,0xE2,0x3C,0x1A,0x94,0x68,0x34,0xB6,0x15,0x0B,0xDA,
1227 0x25,0x83,0xE9,0xCA,0x2A,0xD4,0x4C,0xE8,0xDB,0xBB,0xC2,0xDB,
1228 0x04,0xDE,0x8E,0xF9,0x2E,0x8E,0xFC,0x14,0x1F,0xBE,0xCA,0xA6,
1229 0x28,0x7C,0x59,0x47,0x4E,0x6B,0xC0,0x5D,0x99,0xB2,0x96,0x4F,
1230 0xA0,0x90,0xC3,0xA2,0x23,0x3B,0xA1,0x86,0x51,0x5B,0xE7,0xED,
1231 0x1F,0x61,0x29,0x70,0xCE,0xE2,0xD7,0xAF,0xB8,0x1B,0xDD,0x76,
1232 0x21,0x70,0x48,0x1C,0xD0,0x06,0x91,0x27,0xD5,0xB0,0x5A,0xA9,
1233 0x93,0xB4,0xEA,0x98,0x8D,0x8F,0xDD,0xC1,0x86,0xFF,0xB7,0xDC,
1234 0x90,0xA6,0xC0,0x8F,0x4D,0xF4,0x35,0xC9,0x34,0x02,0x84,0x92,
1235 0x36,0xC3,0xFA,0xB4,0xD2,0x7C,0x70,0x26,0xC1,0xD4,0xDC,0xB2,
1236 0x60,0x26,0x46,0xDE,0xC9,0x75,0x1E,0x76,0x3D,0xBA,0x37,0xBD,
1237 0xF8,0xFF,0x94,0x06,0xAD,0x9E,0x53,0x0E,0xE5,0xDB,0x38,0x2F,
1238 0x41,0x30,0x01,0xAE,0xB0,0x6A,0x53,0xED,0x90,0x27,0xD8,0x31,
1239 0x17,0x97,0x27,0xB0,0x86,0x5A,0x89,0x18,0xDA,0x3E,0xDB,0xEB,
1240 0xCF,0x9B,0x14,0xED,0x44,0xCE,0x6C,0xBA,0xCE,0xD4,0xBB,0x1B,
1241 0xDB,0x7F,0x14,0x47,0xE6,0xCC,0x25,0x4B,0x33,0x20,0x51,0x51,
1242 0x2B,0xD7,0xAF,0x42,0x6F,0xB8,0xF4,0x01,0x37,0x8C,0xD2,0xBF,
1243 0x59,0x83,0xCA,0x01,0xC6,0x4B,0x92,0xEC,0xF0,0x32,0xEA,0x15,
1244 0xD1,0x72,0x1D,0x03,0xF4,0x82,0xD7,0xCE,0x6E,0x74,0xFE,0xF6,
1245 0xD5,0x5E,0x70,0x2F,0x46,0x98,0x0C,0x82,0xB5,0xA8,0x40,0x31,
1246 0x90,0x0B,0x1C,0x9E,0x59,0xE7,0xC9,0x7F,0xBE,0xC7,0xE8,0xF3,
1247 0x23,0xA9,0x7A,0x7E,0x36,0xCC,0x88,0xBE,0x0F,0x1D,0x45,0xB7,
1248 0xFF,0x58,0x5A,0xC5,0x4B,0xD4,0x07,0xB2,0x2B,0x41,0x54,0xAA,
1249 0xCC,0x8F,0x6D,0x7E,0xBF,0x48,0xE1,0xD8,0x14,0xCC,0x5E,0xD2,
1250 0x0F,0x80,0x37,0xE0,0xA7,0x97,0x15,0xEE,0xF2,0x9B,0xE3,0x28,
1251 0x06,0xA1,0xD5,0x8B,0xB7,0xC5,0xDA,0x76,0xF5,0x50,0xAA,0x3D,
1252 0x8A,0x1F,0xBF,0xF0,0xEB,0x19,0xCC,0xB1,0xA3,0x13,0xD5,0x5C,
1253 0xDA,0x56,0xC9,0xEC,0x2E,0xF2,0x96,0x32,0x38,0x7F,0xE8,0xD7,
1254 0x6E,0x3C,0x04,0x68,0x04,0x3E,0x8F,0x66,0x3F,0x48,0x60,0xEE,
1255 0x12,0xBF,0x2D,0x5B,0x0B,0x74,0x74,0xD6,0xE6,0x94,0xF9,0x1E,
1256 0x6D,0xBE,0x11,0x59,0x74,0xA3,0x92,0x6F,0x12,0xFE,0xE5,0xE4,
1257 0x38,0x77,0x7C,0xB6,0xA9,0x32,0xDF,0x8C,0xD8,0xBE,0xC4,0xD0,
1258 0x73,0xB9,0x31,0xBA,0x3B,0xC8,0x32,0xB6,0x8D,0x9D,0xD3,0x00,
1259 0x74,0x1F,0xA7,0xBF,0x8A,0xFC,0x47,0xED,0x25,0x76,0xF6,0x93,
1260 0x6B,0xA4,0x24,0x66,0x3A,0xAB,0x63,0x9C,0x5A,0xE4,0xF5,0x68,
1261 0x34,0x23,0xB4,0x74,0x2B,0xF1,0xC9,0x78,0x23,0x8F,0x16,0xCB,
1262 0xE3,0x9D,0x65,0x2D,0xE3,0xFD,0xB8,0xBE,0xFC,0x84,0x8A,0xD9,
1263 0x22,0x22,0x2E,0x04,0xA4,0x03,0x7C,0x07,0x13,0xEB,0x57,0xA8,
1264 0x1A,0x23,0xF0,0xC7,0x34,0x73,0xFC,0x64,0x6C,0xEA,0x30,0x6B,
1265 0x4B,0xCB,0xC8,0x86,0x2F,0x83,0x85,0xDD,0xFA,0x9D,0x4B,0x7F,
1266 0xA2,0xC0,0x87,0xE8,0x79,0x68,0x33,0x03,0xED,0x5B,0xDD,0x3A,
1267 0x06,0x2B,0x3C,0xF5,0xB3,0xA2,0x78,0xA6,0x6D,0x2A,0x13,0xF8,
1268 0x3F,0x44,0xF8,0x2D,0xDF,0x31,0x0E,0xE0,0x74,0xAB,0x6A,0x36,
1269 0x45,0x97,0xE8,0x99,0xA0,0x25,0x5D,0xC1,0x64,0xF3,0x1C,0xC5,
1270 0x08,0x46,0x85,0x1D,0xF9,0xAB,0x48,0x19,0x5D,0xED,0x7E,0xA1,
1271 0xB1,0xD5,0x10,0xBD,0x7E,0xE7,0x4D,0x73,0xFA,0xF3,0x6B,0xC3,
1272 0x1E,0xCF,0xA2,0x68,0x35,0x90,0x46,0xF4,0xEB,0x87,0x9F,0x92,
1273 0x40,0x09,0x43,0x8B,0x48,0x1C,0x6C,0xD7,0x88,0x9A,0x00,0x2E,
1274 0xD5,0xEE,0x38,0x2B,0xC9,0x19,0x0D,0xA6,0xFC,0x02,0x6E,0x47,
1275 0x95,0x58,0xE4,0x47,0x56,0x77,0xE9,0xAA,0x9E,0x30,0x50,0xE2,
1276 0x76,0x56,0x94,0xDF,0xC8,0x1F,0x56,0xE8,0x80,0xB9,0x6E,0x71,
1277 0x60,0xC9,0x80,0xDD,0x98,0xED,0xD3,0xDF,0xFF,0xFF,0xFF,0xFF,
1278 0xFF,0xFF,0xFF,0xFF,
1279 };
1280#endif
1281 DH *dh = DH_new();
1282 if (dh) {
Lukas Tribus4c0d45a2014-08-18 00:56:32 +02001283#if (OPENSSL_VERSION_NUMBER >= 0x0090801fL && !defined OPENSSL_IS_BORINGSSL)
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001284 dh->p = get_rfc3526_prime_8192(NULL);
1285#else
1286 dh->p = BN_bin2bn(rfc_3526_prime_8192, sizeof rfc_3526_prime_8192, NULL);
1287#endif
1288 /* See RFC 3526, Section 7 "8192-bit MODP Group"
1289 for the reason why 2 is used as generator.
1290 */
1291 BN_dec2bn(&dh->g, "2");
1292 if (!dh->p || !dh->g) {
1293 DH_free(dh);
1294 dh = NULL;
1295 }
1296 }
1297 return dh;
1298}
1299
1300/* Returns Diffie-Hellman parameters matching the private key length
1301 but not exceeding global.tune.ssl_default_dh_param */
1302static DH *ssl_get_tmp_dh(SSL *ssl, int export, int keylen)
1303{
1304 DH *dh = NULL;
1305 EVP_PKEY *pkey = SSL_get_privatekey(ssl);
1306 int type = pkey ? EVP_PKEY_type(pkey->type) : EVP_PKEY_NONE;
1307
1308 /* The keylen supplied by OpenSSL can only be 512 or 1024.
1309 See ssl3_send_server_key_exchange() in ssl/s3_srvr.c
1310 */
1311 if (type == EVP_PKEY_RSA || type == EVP_PKEY_DSA) {
1312 keylen = EVP_PKEY_bits(pkey);
1313 }
1314
1315 if (keylen > global.tune.ssl_default_dh_param) {
1316 keylen = global.tune.ssl_default_dh_param;
1317 }
1318
1319 if (keylen >= 8192) {
Remi Gacogne8de54152014-07-15 11:36:40 +02001320 dh = local_dh_8192;
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001321 }
1322 else if (keylen >= 4096) {
Remi Gacogne8de54152014-07-15 11:36:40 +02001323 dh = local_dh_4096;
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001324 }
1325 else if (keylen >= 2048) {
Remi Gacogne8de54152014-07-15 11:36:40 +02001326 dh = local_dh_2048;
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001327 }
1328 else {
Remi Gacogne8de54152014-07-15 11:36:40 +02001329 dh = local_dh_1024;
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001330 }
1331
1332 return dh;
1333}
1334
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001335/* Loads Diffie-Hellman parameter from a file. Returns 1 if loaded, else -1
1336 if an error occured, and 0 if parameter not found. */
Willy Tarreau6e774b42014-04-25 21:35:23 +02001337int ssl_sock_load_dh_params(SSL_CTX *ctx, const char *file)
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001338{
1339 int ret = -1;
1340 BIO *in;
1341 DH *dh = NULL;
1342
1343 in = BIO_new(BIO_s_file());
1344 if (in == NULL)
1345 goto end;
1346
1347 if (BIO_read_filename(in, file) <= 0)
1348 goto end;
1349
1350 dh = PEM_read_bio_DHparams(in, NULL, ctx->default_passwd_callback, ctx->default_passwd_callback_userdata);
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001351 if (dh) {
1352 ret = 1;
1353 SSL_CTX_set_tmp_dh(ctx, dh);
Remi Gacogne4f902b82015-05-28 16:23:00 +02001354
1355 if (ssl_dh_ptr_index >= 0) {
1356 /* store a pointer to the DH params to avoid complaining about
1357 ssl-default-dh-param not being set for this SSL_CTX */
1358 SSL_CTX_set_ex_data(ctx, ssl_dh_ptr_index, dh);
1359 }
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001360 }
1361 else {
Emeric Brun41fdb3c2013-04-26 11:05:44 +02001362 /* Clear openssl global errors stack */
1363 ERR_clear_error();
1364
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001365 if (global.tune.ssl_default_dh_param <= 1024) {
1366 /* we are limited to DH parameter of 1024 bits anyway */
Remi Gacogne8de54152014-07-15 11:36:40 +02001367 local_dh_1024 = ssl_get_dh_1024();
1368 if (local_dh_1024 == NULL)
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001369 goto end;
Willy Tarreau6e774b42014-04-25 21:35:23 +02001370
Remi Gacogne8de54152014-07-15 11:36:40 +02001371 SSL_CTX_set_tmp_dh(ctx, local_dh_1024);
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001372 }
1373 else {
1374 SSL_CTX_set_tmp_dh_callback(ctx, ssl_get_tmp_dh);
1375 }
Willy Tarreau6e774b42014-04-25 21:35:23 +02001376
Emeric Brun41fdb3c2013-04-26 11:05:44 +02001377 ret = 0; /* DH params not found */
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001378 }
Emeric Brun644cde02012-12-14 11:21:13 +01001379
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001380end:
1381 if (dh)
1382 DH_free(dh);
1383
1384 if (in)
Emeric Brun41fdb3c2013-04-26 11:05:44 +02001385 BIO_free(in);
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001386
1387 return ret;
1388}
1389#endif
1390
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001391static int ssl_sock_add_cert_sni(SSL_CTX *ctx, struct bind_conf *s, char *name, int order)
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001392{
1393 struct sni_ctx *sc;
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001394 int wild = 0, neg = 0;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001395
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001396 if (*name == '!') {
1397 neg = 1;
1398 name++;
1399 }
1400 if (*name == '*') {
1401 wild = 1;
1402 name++;
1403 }
1404 /* !* filter is a nop */
1405 if (neg && wild)
1406 return order;
1407 if (*name) {
1408 int j, len;
1409 len = strlen(name);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001410 sc = malloc(sizeof(struct sni_ctx) + len + 1);
1411 for (j = 0; j < len; j++)
1412 sc->name.key[j] = tolower(name[j]);
1413 sc->name.key[len] = 0;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001414 sc->ctx = ctx;
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001415 sc->order = order++;
1416 sc->neg = neg;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001417 if (wild)
1418 ebst_insert(&s->sni_w_ctx, &sc->name);
1419 else
1420 ebst_insert(&s->sni_ctx, &sc->name);
1421 }
1422 return order;
1423}
1424
Emeric Brunfc0421f2012-09-07 17:30:07 +02001425/* Loads a certificate key and CA chain from a file. Returns 0 on error, -1 if
1426 * an early error happens and the caller must call SSL_CTX_free() by itelf.
1427 */
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001428static 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 +02001429{
1430 BIO *in;
1431 X509 *x = NULL, *ca;
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001432 int i, err;
Emeric Brunfc0421f2012-09-07 17:30:07 +02001433 int ret = -1;
1434 int order = 0;
1435 X509_NAME *xname;
1436 char *str;
Emeric Brunfc0421f2012-09-07 17:30:07 +02001437#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
1438 STACK_OF(GENERAL_NAME) *names;
1439#endif
1440
1441 in = BIO_new(BIO_s_file());
1442 if (in == NULL)
1443 goto end;
1444
1445 if (BIO_read_filename(in, file) <= 0)
1446 goto end;
1447
1448 x = PEM_read_bio_X509_AUX(in, NULL, ctx->default_passwd_callback, ctx->default_passwd_callback_userdata);
1449 if (x == NULL)
1450 goto end;
1451
Emeric Brun50bcecc2013-04-22 13:05:23 +02001452 if (fcount) {
1453 while (fcount--)
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001454 order = ssl_sock_add_cert_sni(ctx, s, sni_filter[fcount], order);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001455 }
1456 else {
Emeric Brunfc0421f2012-09-07 17:30:07 +02001457#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001458 names = X509_get_ext_d2i(x, NID_subject_alt_name, NULL, NULL);
1459 if (names) {
1460 for (i = 0; i < sk_GENERAL_NAME_num(names); i++) {
1461 GENERAL_NAME *name = sk_GENERAL_NAME_value(names, i);
1462 if (name->type == GEN_DNS) {
1463 if (ASN1_STRING_to_UTF8((unsigned char **)&str, name->d.dNSName) >= 0) {
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001464 order = ssl_sock_add_cert_sni(ctx, s, str, order);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001465 OPENSSL_free(str);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001466 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02001467 }
1468 }
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001469 sk_GENERAL_NAME_pop_free(names, GENERAL_NAME_free);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001470 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02001471#endif /* SSL_CTRL_SET_TLSEXT_HOSTNAME */
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001472 xname = X509_get_subject_name(x);
1473 i = -1;
1474 while ((i = X509_NAME_get_index_by_NID(xname, NID_commonName, i)) != -1) {
1475 X509_NAME_ENTRY *entry = X509_NAME_get_entry(xname, i);
1476 if (ASN1_STRING_to_UTF8((unsigned char **)&str, entry->value) >= 0) {
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001477 order = ssl_sock_add_cert_sni(ctx, s, str, order);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001478 OPENSSL_free(str);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001479 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02001480 }
1481 }
1482
1483 ret = 0; /* the caller must not free the SSL_CTX argument anymore */
1484 if (!SSL_CTX_use_certificate(ctx, x))
1485 goto end;
1486
1487 if (ctx->extra_certs != NULL) {
1488 sk_X509_pop_free(ctx->extra_certs, X509_free);
1489 ctx->extra_certs = NULL;
1490 }
1491
1492 while ((ca = PEM_read_bio_X509(in, NULL, ctx->default_passwd_callback, ctx->default_passwd_callback_userdata))) {
1493 if (!SSL_CTX_add_extra_chain_cert(ctx, ca)) {
1494 X509_free(ca);
1495 goto end;
1496 }
1497 }
1498
1499 err = ERR_get_error();
1500 if (!err || (ERR_GET_LIB(err) == ERR_LIB_PEM && ERR_GET_REASON(err) == PEM_R_NO_START_LINE)) {
1501 /* we successfully reached the last cert in the file */
1502 ret = 1;
1503 }
1504 ERR_clear_error();
1505
1506end:
1507 if (x)
1508 X509_free(x);
1509
1510 if (in)
1511 BIO_free(in);
1512
1513 return ret;
1514}
1515
Emeric Brun50bcecc2013-04-22 13:05:23 +02001516static 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 +02001517{
1518 int ret;
1519 SSL_CTX *ctx;
1520
1521 ctx = SSL_CTX_new(SSLv23_server_method());
1522 if (!ctx) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02001523 memprintf(err, "%sunable to allocate SSL context for cert '%s'.\n",
1524 err && *err ? *err : "", path);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001525 return 1;
1526 }
1527
1528 if (SSL_CTX_use_PrivateKey_file(ctx, path, SSL_FILETYPE_PEM) <= 0) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02001529 memprintf(err, "%sunable to load SSL private key from PEM file '%s'.\n",
1530 err && *err ? *err : "", path);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001531 SSL_CTX_free(ctx);
1532 return 1;
1533 }
1534
Emeric Brun50bcecc2013-04-22 13:05:23 +02001535 ret = ssl_sock_load_cert_chain_file(ctx, path, bind_conf, sni_filter, fcount);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001536 if (ret <= 0) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02001537 memprintf(err, "%sunable to load SSL certificate from PEM file '%s'.\n",
1538 err && *err ? *err : "", path);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001539 if (ret < 0) /* serious error, must do that ourselves */
1540 SSL_CTX_free(ctx);
1541 return 1;
1542 }
Emeric Brun61694ab2012-10-26 13:35:33 +02001543
1544 if (SSL_CTX_check_private_key(ctx) <= 0) {
1545 memprintf(err, "%sinconsistencies between private key and certificate loaded from PEM file '%s'.\n",
1546 err && *err ? *err : "", path);
1547 return 1;
1548 }
1549
Emeric Brunfc0421f2012-09-07 17:30:07 +02001550 /* we must not free the SSL_CTX anymore below, since it's already in
1551 * the tree, so it will be discovered and cleaned in time.
1552 */
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001553#ifndef OPENSSL_NO_DH
Remi Gacogne4f902b82015-05-28 16:23:00 +02001554 /* store a NULL pointer to indicate we have not yet loaded
1555 a custom DH param file */
1556 if (ssl_dh_ptr_index >= 0) {
1557 SSL_CTX_set_ex_data(ctx, ssl_dh_ptr_index, NULL);
1558 }
1559
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001560 ret = ssl_sock_load_dh_params(ctx, path);
1561 if (ret < 0) {
1562 if (err)
1563 memprintf(err, "%sunable to load DH parameters from file '%s'.\n",
1564 *err ? *err : "", path);
1565 return 1;
1566 }
1567#endif
1568
Lukas Tribuse4e30f72014-12-09 16:32:51 +01001569#if (defined SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB && !defined OPENSSL_NO_OCSP)
Emeric Brun4147b2e2014-06-16 18:36:30 +02001570 ret = ssl_sock_load_ocsp(ctx, path);
1571 if (ret < 0) {
1572 if (err)
1573 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",
1574 *err ? *err : "", path);
1575 return 1;
1576 }
1577#endif
1578
Janusz Dziemidowicz2c701b52015-03-07 23:03:59 +01001579#if (OPENSSL_VERSION_NUMBER >= 0x1000200fL && !defined OPENSSL_NO_TLSEXT && !defined OPENSSL_IS_BORINGSSL)
1580 if (sctl_ex_index >= 0) {
1581 ret = ssl_sock_load_sctl(ctx, path);
1582 if (ret < 0) {
1583 if (err)
1584 memprintf(err, "%s '%s.sctl' is present but cannot be read or parsed'.\n",
1585 *err ? *err : "", path);
1586 return 1;
1587 }
1588 }
1589#endif
1590
Emeric Brunfc0421f2012-09-07 17:30:07 +02001591#ifndef SSL_CTRL_SET_TLSEXT_HOSTNAME
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001592 if (bind_conf->default_ctx) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02001593 memprintf(err, "%sthis version of openssl cannot load multiple SSL certificates.\n",
1594 err && *err ? *err : "");
Emeric Brunfc0421f2012-09-07 17:30:07 +02001595 return 1;
1596 }
1597#endif
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001598 if (!bind_conf->default_ctx)
1599 bind_conf->default_ctx = ctx;
Emeric Brunfc0421f2012-09-07 17:30:07 +02001600
1601 return 0;
1602}
1603
Willy Tarreau79eeafa2012-09-14 07:53:05 +02001604int ssl_sock_load_cert(char *path, struct bind_conf *bind_conf, struct proxy *curproxy, char **err)
Emeric Brunfc0421f2012-09-07 17:30:07 +02001605{
Cyril Bonté3180f7b2015-01-25 00:16:08 +01001606 struct dirent **de_list;
1607 int i, n;
Emeric Brunfc0421f2012-09-07 17:30:07 +02001608 DIR *dir;
1609 struct stat buf;
Willy Tarreauee2663b2012-12-06 11:36:59 +01001610 char *end;
1611 char fp[MAXPATHLEN+1];
Emeric Brunfc0421f2012-09-07 17:30:07 +02001612 int cfgerr = 0;
1613
1614 if (!(dir = opendir(path)))
Emeric Brun50bcecc2013-04-22 13:05:23 +02001615 return ssl_sock_load_cert_file(path, bind_conf, curproxy, NULL, 0, err);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001616
1617 /* strip trailing slashes, including first one */
1618 for (end = path + strlen(path) - 1; end >= path && *end == '/'; end--)
1619 *end = 0;
1620
Cyril Bonté3180f7b2015-01-25 00:16:08 +01001621 n = scandir(path, &de_list, 0, alphasort);
1622 if (n < 0) {
1623 memprintf(err, "%sunable to scan directory '%s' : %s.\n",
1624 err && *err ? *err : "", path, strerror(errno));
1625 cfgerr++;
1626 }
1627 else {
1628 for (i = 0; i < n; i++) {
1629 struct dirent *de = de_list[i];
Emeric Brun2aab7222014-06-18 18:15:09 +02001630
Cyril Bonté3180f7b2015-01-25 00:16:08 +01001631 end = strrchr(de->d_name, '.');
Janusz Dziemidowicz2c701b52015-03-07 23:03:59 +01001632 if (end && (!strcmp(end, ".issuer") || !strcmp(end, ".ocsp") || !strcmp(end, ".sctl")))
Cyril Bonté3180f7b2015-01-25 00:16:08 +01001633 goto ignore_entry;
1634
1635 snprintf(fp, sizeof(fp), "%s/%s", path, de->d_name);
1636 if (stat(fp, &buf) != 0) {
1637 memprintf(err, "%sunable to stat SSL certificate from file '%s' : %s.\n",
1638 err && *err ? *err : "", fp, strerror(errno));
1639 cfgerr++;
1640 goto ignore_entry;
1641 }
1642 if (!S_ISREG(buf.st_mode))
1643 goto ignore_entry;
1644 cfgerr += ssl_sock_load_cert_file(fp, bind_conf, curproxy, NULL, 0, err);
1645 ignore_entry:
1646 free(de);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001647 }
Cyril Bonté3180f7b2015-01-25 00:16:08 +01001648 free(de_list);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001649 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02001650 closedir(dir);
1651 return cfgerr;
1652}
1653
Thierry Fournier383085f2013-01-24 14:15:43 +01001654/* Make sure openssl opens /dev/urandom before the chroot. The work is only
1655 * done once. Zero is returned if the operation fails. No error is returned
1656 * if the random is said as not implemented, because we expect that openssl
1657 * will use another method once needed.
1658 */
1659static int ssl_initialize_random()
1660{
1661 unsigned char random;
1662 static int random_initialized = 0;
1663
1664 if (!random_initialized && RAND_bytes(&random, 1) != 0)
1665 random_initialized = 1;
1666
1667 return random_initialized;
1668}
1669
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001670int ssl_sock_load_cert_list_file(char *file, struct bind_conf *bind_conf, struct proxy *curproxy, char **err)
1671{
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001672 char thisline[LINESIZE];
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001673 FILE *f;
1674 int linenum = 0;
1675 int cfgerr = 0;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001676
Willy Tarreauad1731d2013-04-02 17:35:58 +02001677 if ((f = fopen(file, "r")) == NULL) {
1678 memprintf(err, "cannot open file '%s' : %s", file, strerror(errno));
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001679 return 1;
Willy Tarreauad1731d2013-04-02 17:35:58 +02001680 }
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001681
1682 while (fgets(thisline, sizeof(thisline), f) != NULL) {
1683 int arg;
Emeric Brun50bcecc2013-04-22 13:05:23 +02001684 int newarg;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001685 char *end;
1686 char *args[MAX_LINE_ARGS + 1];
1687 char *line = thisline;
1688
1689 linenum++;
1690 end = line + strlen(line);
1691 if (end-line == sizeof(thisline)-1 && *(end-1) != '\n') {
1692 /* Check if we reached the limit and the last char is not \n.
1693 * Watch out for the last line without the terminating '\n'!
1694 */
Willy Tarreauad1731d2013-04-02 17:35:58 +02001695 memprintf(err, "line %d too long in file '%s', limit is %d characters",
1696 linenum, file, (int)sizeof(thisline)-1);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001697 cfgerr = 1;
Willy Tarreauad1731d2013-04-02 17:35:58 +02001698 break;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001699 }
1700
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001701 arg = 0;
Emeric Brun50bcecc2013-04-22 13:05:23 +02001702 newarg = 1;
1703 while (*line) {
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001704 if (*line == '#' || *line == '\n' || *line == '\r') {
1705 /* end of string, end of loop */
1706 *line = 0;
1707 break;
1708 }
1709 else if (isspace(*line)) {
Emeric Brun50bcecc2013-04-22 13:05:23 +02001710 newarg = 1;
1711 *line = 0;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001712 }
Emeric Brun50bcecc2013-04-22 13:05:23 +02001713 else if (newarg) {
1714 if (arg == MAX_LINE_ARGS) {
1715 memprintf(err, "too many args on line %d in file '%s'.",
1716 linenum, file);
1717 cfgerr = 1;
1718 break;
1719 }
1720 newarg = 0;
1721 args[arg++] = line;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001722 }
Emeric Brun50bcecc2013-04-22 13:05:23 +02001723 line++;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001724 }
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001725 if (cfgerr)
1726 break;
Willy Tarreauad1731d2013-04-02 17:35:58 +02001727
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001728 /* empty line */
Emeric Brun50bcecc2013-04-22 13:05:23 +02001729 if (!arg)
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001730 continue;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001731
Emeric Brun50bcecc2013-04-22 13:05:23 +02001732 cfgerr = ssl_sock_load_cert_file(args[0], bind_conf, curproxy, &args[1], arg-1, err);
Willy Tarreauad1731d2013-04-02 17:35:58 +02001733 if (cfgerr) {
1734 memprintf(err, "error processing line %d in file '%s' : %s", linenum, file, *err);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001735 break;
Willy Tarreauad1731d2013-04-02 17:35:58 +02001736 }
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001737 }
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001738 fclose(f);
1739 return cfgerr;
1740}
1741
Emeric Brunfc0421f2012-09-07 17:30:07 +02001742#ifndef SSL_OP_CIPHER_SERVER_PREFERENCE /* needs OpenSSL >= 0.9.7 */
1743#define SSL_OP_CIPHER_SERVER_PREFERENCE 0
1744#endif
1745
1746#ifndef SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION /* needs OpenSSL >= 0.9.7 */
1747#define SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION 0
Willy Tarreau7d588ee2012-11-26 18:47:31 +01001748#define SSL_renegotiate_pending(arg) 0
Emeric Brunfc0421f2012-09-07 17:30:07 +02001749#endif
Emeric Brun2b58d042012-09-20 17:10:03 +02001750#ifndef SSL_OP_SINGLE_ECDH_USE /* needs OpenSSL >= 0.9.8 */
1751#define SSL_OP_SINGLE_ECDH_USE 0
1752#endif
Emeric Brun2d0c4822012-10-02 13:45:20 +02001753#ifndef SSL_OP_NO_TICKET /* needs OpenSSL >= 0.9.8 */
1754#define SSL_OP_NO_TICKET 0
1755#endif
Emeric Brunfc0421f2012-09-07 17:30:07 +02001756#ifndef SSL_OP_NO_COMPRESSION /* needs OpenSSL >= 0.9.9 */
1757#define SSL_OP_NO_COMPRESSION 0
1758#endif
Emeric Brunc0ff4922012-09-28 19:37:02 +02001759#ifndef SSL_OP_NO_TLSv1_1 /* needs OpenSSL >= 1.0.1 */
1760#define SSL_OP_NO_TLSv1_1 0
1761#endif
1762#ifndef SSL_OP_NO_TLSv1_2 /* needs OpenSSL >= 1.0.1 */
1763#define SSL_OP_NO_TLSv1_2 0
1764#endif
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001765#ifndef SSL_OP_SINGLE_DH_USE /* needs OpenSSL >= 0.9.6 */
1766#define SSL_OP_SINGLE_DH_USE 0
1767#endif
Emeric Brun2b58d042012-09-20 17:10:03 +02001768#ifndef SSL_OP_SINGLE_ECDH_USE /* needs OpenSSL >= 1.0.0 */
1769#define SSL_OP_SINGLE_ECDH_USE 0
1770#endif
Emeric Brunfc0421f2012-09-07 17:30:07 +02001771#ifndef SSL_MODE_RELEASE_BUFFERS /* needs OpenSSL >= 1.0.0 */
1772#define SSL_MODE_RELEASE_BUFFERS 0
1773#endif
Willy Tarreau396a1862014-11-13 14:06:52 +01001774#ifndef SSL_MODE_SMALL_BUFFERS /* needs small_records.patch */
1775#define SSL_MODE_SMALL_BUFFERS 0
1776#endif
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001777
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001778int ssl_sock_prepare_ctx(struct bind_conf *bind_conf, SSL_CTX *ctx, struct proxy *curproxy)
Emeric Brunfc0421f2012-09-07 17:30:07 +02001779{
1780 int cfgerr = 0;
Emeric Brun850efd52014-01-29 12:24:34 +01001781 int verify = SSL_VERIFY_NONE;
Remi Gacogneaf5c3da2014-05-19 10:29:58 +02001782 long ssloptions =
Emeric Brunfc0421f2012-09-07 17:30:07 +02001783 SSL_OP_ALL | /* all known workarounds for bugs */
1784 SSL_OP_NO_SSLv2 |
1785 SSL_OP_NO_COMPRESSION |
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001786 SSL_OP_SINGLE_DH_USE |
Emeric Brun2b58d042012-09-20 17:10:03 +02001787 SSL_OP_SINGLE_ECDH_USE |
Emeric Brun3c4bc6e2012-10-04 18:44:19 +02001788 SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION |
1789 SSL_OP_CIPHER_SERVER_PREFERENCE;
Remi Gacogneaf5c3da2014-05-19 10:29:58 +02001790 long sslmode =
Emeric Brunfc0421f2012-09-07 17:30:07 +02001791 SSL_MODE_ENABLE_PARTIAL_WRITE |
1792 SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER |
Willy Tarreau396a1862014-11-13 14:06:52 +01001793 SSL_MODE_RELEASE_BUFFERS |
1794 SSL_MODE_SMALL_BUFFERS;
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001795 STACK_OF(SSL_CIPHER) * ciphers = NULL;
Willy Tarreaua616ba62014-10-26 06:49:19 +01001796 SSL_CIPHER * cipher = NULL;
Remi Gacognec1eab8c2014-06-12 18:20:11 +02001797 char cipher_description[128];
1798 /* The description of ciphers using an Ephemeral Diffie Hellman key exchange
1799 contains " Kx=DH " or " Kx=DH(". Beware of " Kx=DH/",
1800 which is not ephemeral DH. */
1801 const char dhe_description[] = " Kx=DH ";
1802 const char dhe_export_description[] = " Kx=DH(";
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001803 int idx = 0;
1804 int dhe_found = 0;
Remi Gacogne23d5d372014-10-10 17:04:26 +02001805 SSL *ssl = NULL;
Emeric Brunfc0421f2012-09-07 17:30:07 +02001806
Thierry Fournier383085f2013-01-24 14:15:43 +01001807 /* Make sure openssl opens /dev/urandom before the chroot */
1808 if (!ssl_initialize_random()) {
1809 Alert("OpenSSL random data generator initialization failed.\n");
1810 cfgerr++;
1811 }
1812
Emeric Brun89675492012-10-05 13:48:26 +02001813 if (bind_conf->ssl_options & BC_SSL_O_NO_SSLV3)
Emeric Brunfc0421f2012-09-07 17:30:07 +02001814 ssloptions |= SSL_OP_NO_SSLv3;
Emeric Brun89675492012-10-05 13:48:26 +02001815 if (bind_conf->ssl_options & BC_SSL_O_NO_TLSV10)
Emeric Brunfc0421f2012-09-07 17:30:07 +02001816 ssloptions |= SSL_OP_NO_TLSv1;
Emeric Brun89675492012-10-05 13:48:26 +02001817 if (bind_conf->ssl_options & BC_SSL_O_NO_TLSV11)
Emeric Brunc0ff4922012-09-28 19:37:02 +02001818 ssloptions |= SSL_OP_NO_TLSv1_1;
Emeric Brun89675492012-10-05 13:48:26 +02001819 if (bind_conf->ssl_options & BC_SSL_O_NO_TLSV12)
Emeric Brunc0ff4922012-09-28 19:37:02 +02001820 ssloptions |= SSL_OP_NO_TLSv1_2;
Emeric Brun89675492012-10-05 13:48:26 +02001821 if (bind_conf->ssl_options & BC_SSL_O_NO_TLS_TICKETS)
Emeric Brun2d0c4822012-10-02 13:45:20 +02001822 ssloptions |= SSL_OP_NO_TICKET;
Emeric Brun2cb7ae52012-10-05 14:14:21 +02001823 if (bind_conf->ssl_options & BC_SSL_O_USE_SSLV3)
1824 SSL_CTX_set_ssl_version(ctx, SSLv3_server_method());
1825 if (bind_conf->ssl_options & BC_SSL_O_USE_TLSV10)
1826 SSL_CTX_set_ssl_version(ctx, TLSv1_server_method());
1827#if SSL_OP_NO_TLSv1_1
1828 if (bind_conf->ssl_options & BC_SSL_O_USE_TLSV11)
1829 SSL_CTX_set_ssl_version(ctx, TLSv1_1_server_method());
1830#endif
1831#if SSL_OP_NO_TLSv1_2
1832 if (bind_conf->ssl_options & BC_SSL_O_USE_TLSV12)
1833 SSL_CTX_set_ssl_version(ctx, TLSv1_2_server_method());
1834#endif
Emeric Brunfc0421f2012-09-07 17:30:07 +02001835
1836 SSL_CTX_set_options(ctx, ssloptions);
1837 SSL_CTX_set_mode(ctx, sslmode);
Emeric Brun850efd52014-01-29 12:24:34 +01001838 switch (bind_conf->verify) {
1839 case SSL_SOCK_VERIFY_NONE:
1840 verify = SSL_VERIFY_NONE;
1841 break;
1842 case SSL_SOCK_VERIFY_OPTIONAL:
1843 verify = SSL_VERIFY_PEER;
1844 break;
1845 case SSL_SOCK_VERIFY_REQUIRED:
1846 verify = SSL_VERIFY_PEER|SSL_VERIFY_FAIL_IF_NO_PEER_CERT;
1847 break;
1848 }
1849 SSL_CTX_set_verify(ctx, verify, ssl_sock_bind_verifycbk);
1850 if (verify & SSL_VERIFY_PEER) {
Emeric Brunfb510ea2012-10-05 12:00:26 +02001851 if (bind_conf->ca_file) {
Emeric Brund94b3fe2012-09-20 18:23:56 +02001852 /* load CAfile to verify */
Emeric Brunfb510ea2012-10-05 12:00:26 +02001853 if (!SSL_CTX_load_verify_locations(ctx, bind_conf->ca_file, NULL)) {
Emeric Brund94b3fe2012-09-20 18:23:56 +02001854 Alert("Proxy '%s': unable to load CA file '%s' for bind '%s' at [%s:%d].\n",
Emeric Brunfb510ea2012-10-05 12:00:26 +02001855 curproxy->id, bind_conf->ca_file, bind_conf->arg, bind_conf->file, bind_conf->line);
Emeric Brund94b3fe2012-09-20 18:23:56 +02001856 cfgerr++;
1857 }
1858 /* set CA names fo client cert request, function returns void */
Emeric Brunfb510ea2012-10-05 12:00:26 +02001859 SSL_CTX_set_client_CA_list(ctx, SSL_load_client_CA_file(bind_conf->ca_file));
Emeric Brund94b3fe2012-09-20 18:23:56 +02001860 }
Emeric Brun850efd52014-01-29 12:24:34 +01001861 else {
1862 Alert("Proxy '%s': verify is enabled but no CA file specified for bind '%s' at [%s:%d].\n",
1863 curproxy->id, bind_conf->arg, bind_conf->file, bind_conf->line);
1864 cfgerr++;
1865 }
Emeric Brun051cdab2012-10-02 19:25:50 +02001866#ifdef X509_V_FLAG_CRL_CHECK
Emeric Brunfb510ea2012-10-05 12:00:26 +02001867 if (bind_conf->crl_file) {
Emeric Brund94b3fe2012-09-20 18:23:56 +02001868 X509_STORE *store = SSL_CTX_get_cert_store(ctx);
1869
Emeric Brunfb510ea2012-10-05 12:00:26 +02001870 if (!store || !X509_STORE_load_locations(store, bind_conf->crl_file, NULL)) {
Emeric Brund94b3fe2012-09-20 18:23:56 +02001871 Alert("Proxy '%s': unable to configure CRL file '%s' for bind '%s' at [%s:%d].\n",
Alexander Rigbofc65af02015-04-07 14:02:16 +02001872 curproxy->id, bind_conf->crl_file, bind_conf->arg, bind_conf->file, bind_conf->line);
Emeric Brund94b3fe2012-09-20 18:23:56 +02001873 cfgerr++;
1874 }
Emeric Brun561e5742012-10-02 15:20:55 +02001875 else {
1876 X509_STORE_set_flags(store, X509_V_FLAG_CRL_CHECK|X509_V_FLAG_CRL_CHECK_ALL);
1877 }
Emeric Brund94b3fe2012-09-20 18:23:56 +02001878 }
Emeric Brun051cdab2012-10-02 19:25:50 +02001879#endif
Emeric Brun644cde02012-12-14 11:21:13 +01001880 ERR_clear_error();
Emeric Brund94b3fe2012-09-20 18:23:56 +02001881 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02001882
Nenad Merdanovic05552d42015-02-27 19:56:49 +01001883#if (defined SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB && TLS_TICKETS_NO > 0)
Nenad Merdanovic146defa2015-05-09 08:46:00 +02001884 if(bind_conf->keys_ref) {
Nenad Merdanovic05552d42015-02-27 19:56:49 +01001885 if (!SSL_CTX_set_tlsext_ticket_key_cb(ctx, ssl_tlsext_ticket_key_cb)) {
1886 Alert("Proxy '%s': unable to set callback for TLS ticket validation for bind '%s' at [%s:%d].\n",
1887 curproxy->id, bind_conf->arg, bind_conf->file, bind_conf->line);
1888 cfgerr++;
1889 }
1890 }
1891#endif
1892
Emeric Brun4f65bff2012-11-16 15:11:00 +01001893 if (global.tune.ssllifetime)
1894 SSL_CTX_set_timeout(ctx, global.tune.ssllifetime);
1895
Emeric Brunfc0421f2012-09-07 17:30:07 +02001896 shared_context_set_cache(ctx);
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001897 if (bind_conf->ciphers &&
1898 !SSL_CTX_set_cipher_list(ctx, bind_conf->ciphers)) {
Emeric Brunfc0421f2012-09-07 17:30:07 +02001899 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 +02001900 curproxy->id, bind_conf->ciphers, bind_conf->arg, bind_conf->file, bind_conf->line);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001901 cfgerr++;
1902 }
1903
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001904 /* If tune.ssl.default-dh-param has not been set and
1905 no static DH params were in the certificate file. */
Remi Gacogne4f902b82015-05-28 16:23:00 +02001906 if (global.tune.ssl_default_dh_param == 0 &&
1907 (ssl_dh_ptr_index == -1 ||
1908 SSL_CTX_get_ex_data(ctx, ssl_dh_ptr_index) == NULL)) {
Lukas Tribus90132722014-08-18 00:56:33 +02001909
Remi Gacogne23d5d372014-10-10 17:04:26 +02001910 ssl = SSL_new(ctx);
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001911
Remi Gacogne23d5d372014-10-10 17:04:26 +02001912 if (ssl) {
1913 ciphers = SSL_get_ciphers(ssl);
1914
1915 if (ciphers) {
1916 for (idx = 0; idx < sk_SSL_CIPHER_num(ciphers); idx++) {
1917 cipher = sk_SSL_CIPHER_value(ciphers, idx);
1918 if (SSL_CIPHER_description(cipher, cipher_description, sizeof (cipher_description)) == cipher_description) {
1919 if (strstr(cipher_description, dhe_description) != NULL ||
1920 strstr(cipher_description, dhe_export_description) != NULL) {
1921 dhe_found = 1;
1922 break;
1923 }
Remi Gacognec1eab8c2014-06-12 18:20:11 +02001924 }
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001925 }
1926 }
Remi Gacogne23d5d372014-10-10 17:04:26 +02001927 SSL_free(ssl);
1928 ssl = NULL;
Lukas Tribus90132722014-08-18 00:56:33 +02001929 }
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001930
Lukas Tribus90132722014-08-18 00:56:33 +02001931 if (dhe_found) {
1932 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 +02001933 }
1934
1935 global.tune.ssl_default_dh_param = 1024;
1936 }
Remi Gacogne8de54152014-07-15 11:36:40 +02001937
1938#ifndef OPENSSL_NO_DH
1939 if (global.tune.ssl_default_dh_param >= 1024) {
1940 if (local_dh_1024 == NULL) {
1941 local_dh_1024 = ssl_get_dh_1024();
1942 }
1943 if (global.tune.ssl_default_dh_param >= 2048) {
1944 if (local_dh_2048 == NULL) {
1945 local_dh_2048 = ssl_get_dh_2048();
1946 }
1947 if (global.tune.ssl_default_dh_param >= 4096) {
1948 if (local_dh_4096 == NULL) {
1949 local_dh_4096 = ssl_get_dh_4096();
1950 }
1951 if (global.tune.ssl_default_dh_param >= 8192 &&
1952 local_dh_8192 == NULL) {
1953 local_dh_8192 = ssl_get_dh_8192();
1954 }
1955 }
1956 }
1957 }
1958#endif /* OPENSSL_NO_DH */
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001959
Emeric Brunfc0421f2012-09-07 17:30:07 +02001960 SSL_CTX_set_info_callback(ctx, ssl_sock_infocbk);
Willy Tarreau5cbe4ef2014-05-08 22:45:11 +02001961#if OPENSSL_VERSION_NUMBER >= 0x00907000L
Emeric Brun29f037d2014-04-25 19:05:36 +02001962 SSL_CTX_set_msg_callback(ctx, ssl_sock_msgcbk);
Willy Tarreau5cbe4ef2014-05-08 22:45:11 +02001963#endif
Emeric Brun29f037d2014-04-25 19:05:36 +02001964
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02001965#ifdef OPENSSL_NPN_NEGOTIATED
1966 if (bind_conf->npn_str)
1967 SSL_CTX_set_next_protos_advertised_cb(ctx, ssl_sock_advertise_npn_protos, bind_conf);
1968#endif
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01001969#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Willy Tarreauab861d32013-04-02 02:30:41 +02001970 if (bind_conf->alpn_str)
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01001971 SSL_CTX_set_alpn_select_cb(ctx, ssl_sock_advertise_alpn_protos, bind_conf);
Willy Tarreauab861d32013-04-02 02:30:41 +02001972#endif
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02001973
Emeric Brunfc0421f2012-09-07 17:30:07 +02001974#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
1975 SSL_CTX_set_tlsext_servername_callback(ctx, ssl_sock_switchctx_cbk);
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001976 SSL_CTX_set_tlsext_servername_arg(ctx, bind_conf);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001977#endif
Emeric Brun2b58d042012-09-20 17:10:03 +02001978#if defined(SSL_CTX_set_tmp_ecdh) && !defined(OPENSSL_NO_ECDH)
Emeric Brun6924ef82013-03-06 14:08:53 +01001979 {
Emeric Brun2b58d042012-09-20 17:10:03 +02001980 int i;
1981 EC_KEY *ecdh;
1982
Emeric Brun6924ef82013-03-06 14:08:53 +01001983 i = OBJ_sn2nid(bind_conf->ecdhe ? bind_conf->ecdhe : ECDHE_DEFAULT_CURVE);
Emeric Brun2b58d042012-09-20 17:10:03 +02001984 if (!i || ((ecdh = EC_KEY_new_by_curve_name(i)) == NULL)) {
1985 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 +01001986 curproxy->id, bind_conf->ecdhe ? bind_conf->ecdhe : ECDHE_DEFAULT_CURVE,
1987 bind_conf->arg, bind_conf->file, bind_conf->line);
Emeric Brun2b58d042012-09-20 17:10:03 +02001988 cfgerr++;
1989 }
1990 else {
1991 SSL_CTX_set_tmp_ecdh(ctx, ecdh);
1992 EC_KEY_free(ecdh);
1993 }
1994 }
1995#endif
1996
Emeric Brunfc0421f2012-09-07 17:30:07 +02001997 return cfgerr;
1998}
1999
Evan Broderbe554312013-06-27 00:05:25 -07002000static int ssl_sock_srv_hostcheck(const char *pattern, const char *hostname)
2001{
2002 const char *pattern_wildcard, *pattern_left_label_end, *hostname_left_label_end;
2003 size_t prefixlen, suffixlen;
2004
2005 /* Trivial case */
2006 if (strcmp(pattern, hostname) == 0)
2007 return 1;
2008
Evan Broderbe554312013-06-27 00:05:25 -07002009 /* The rest of this logic is based on RFC 6125, section 6.4.3
2010 * (http://tools.ietf.org/html/rfc6125#section-6.4.3) */
2011
Emeric Bruna848dae2013-10-08 11:27:28 +02002012 pattern_wildcard = NULL;
2013 pattern_left_label_end = pattern;
2014 while (*pattern_left_label_end != '.') {
2015 switch (*pattern_left_label_end) {
2016 case 0:
2017 /* End of label not found */
2018 return 0;
2019 case '*':
2020 /* If there is more than one wildcards */
2021 if (pattern_wildcard)
2022 return 0;
2023 pattern_wildcard = pattern_left_label_end;
2024 break;
2025 }
2026 pattern_left_label_end++;
2027 }
2028
2029 /* If it's not trivial and there is no wildcard, it can't
2030 * match */
2031 if (!pattern_wildcard)
Evan Broderbe554312013-06-27 00:05:25 -07002032 return 0;
2033
2034 /* Make sure all labels match except the leftmost */
2035 hostname_left_label_end = strchr(hostname, '.');
2036 if (!hostname_left_label_end
2037 || strcmp(pattern_left_label_end, hostname_left_label_end) != 0)
2038 return 0;
2039
2040 /* Make sure the leftmost label of the hostname is long enough
2041 * that the wildcard can match */
Emeric Brun369da852013-10-08 11:39:35 +02002042 if (hostname_left_label_end - hostname < (pattern_left_label_end - pattern) - 1)
Evan Broderbe554312013-06-27 00:05:25 -07002043 return 0;
2044
2045 /* Finally compare the string on either side of the
2046 * wildcard */
2047 prefixlen = pattern_wildcard - pattern;
2048 suffixlen = pattern_left_label_end - (pattern_wildcard + 1);
Emeric Bruna848dae2013-10-08 11:27:28 +02002049 if ((prefixlen && (memcmp(pattern, hostname, prefixlen) != 0))
2050 || (suffixlen && (memcmp(pattern_wildcard + 1, hostname_left_label_end - suffixlen, suffixlen) != 0)))
Evan Broderbe554312013-06-27 00:05:25 -07002051 return 0;
2052
2053 return 1;
2054}
2055
2056static int ssl_sock_srv_verifycbk(int ok, X509_STORE_CTX *ctx)
2057{
2058 SSL *ssl;
2059 struct connection *conn;
2060 char *servername;
2061
2062 int depth;
2063 X509 *cert;
2064 STACK_OF(GENERAL_NAME) *alt_names;
2065 int i;
2066 X509_NAME *cert_subject;
2067 char *str;
2068
2069 if (ok == 0)
2070 return ok;
2071
2072 ssl = X509_STORE_CTX_get_ex_data(ctx, SSL_get_ex_data_X509_STORE_CTX_idx());
2073 conn = (struct connection *)SSL_get_app_data(ssl);
2074
2075 servername = objt_server(conn->target)->ssl_ctx.verify_host;
2076
2077 /* We only need to verify the CN on the actual server cert,
2078 * not the indirect CAs */
2079 depth = X509_STORE_CTX_get_error_depth(ctx);
2080 if (depth != 0)
2081 return ok;
2082
2083 /* At this point, the cert is *not* OK unless we can find a
2084 * hostname match */
2085 ok = 0;
2086
2087 cert = X509_STORE_CTX_get_current_cert(ctx);
2088 /* It seems like this might happen if verify peer isn't set */
2089 if (!cert)
2090 return ok;
2091
2092 alt_names = X509_get_ext_d2i(cert, NID_subject_alt_name, NULL, NULL);
2093 if (alt_names) {
2094 for (i = 0; !ok && i < sk_GENERAL_NAME_num(alt_names); i++) {
2095 GENERAL_NAME *name = sk_GENERAL_NAME_value(alt_names, i);
2096 if (name->type == GEN_DNS) {
Emeric Bruna33410c2013-09-17 15:47:48 +02002097#if OPENSSL_VERSION_NUMBER < 0x00907000L
2098 if (ASN1_STRING_to_UTF8((unsigned char **)&str, name->d.ia5) >= 0) {
2099#else
Evan Broderbe554312013-06-27 00:05:25 -07002100 if (ASN1_STRING_to_UTF8((unsigned char **)&str, name->d.dNSName) >= 0) {
Emeric Bruna33410c2013-09-17 15:47:48 +02002101#endif
Evan Broderbe554312013-06-27 00:05:25 -07002102 ok = ssl_sock_srv_hostcheck(str, servername);
2103 OPENSSL_free(str);
2104 }
2105 }
2106 }
Emeric Brun4ad50a42013-09-17 15:19:54 +02002107 sk_GENERAL_NAME_pop_free(alt_names, GENERAL_NAME_free);
Evan Broderbe554312013-06-27 00:05:25 -07002108 }
2109
2110 cert_subject = X509_get_subject_name(cert);
2111 i = -1;
2112 while (!ok && (i = X509_NAME_get_index_by_NID(cert_subject, NID_commonName, i)) != -1) {
2113 X509_NAME_ENTRY *entry = X509_NAME_get_entry(cert_subject, i);
2114 if (ASN1_STRING_to_UTF8((unsigned char **)&str, entry->value) >= 0) {
2115 ok = ssl_sock_srv_hostcheck(str, servername);
2116 OPENSSL_free(str);
2117 }
2118 }
2119
2120 return ok;
2121}
2122
Emeric Brun94324a42012-10-11 14:00:19 +02002123/* prepare ssl context from servers options. Returns an error count */
2124int ssl_sock_prepare_srv_ctx(struct server *srv, struct proxy *curproxy)
2125{
2126 int cfgerr = 0;
Remi Gacogneaf5c3da2014-05-19 10:29:58 +02002127 long options =
Emeric Brun94324a42012-10-11 14:00:19 +02002128 SSL_OP_ALL | /* all known workarounds for bugs */
2129 SSL_OP_NO_SSLv2 |
2130 SSL_OP_NO_COMPRESSION;
Remi Gacogneaf5c3da2014-05-19 10:29:58 +02002131 long mode =
Emeric Brun94324a42012-10-11 14:00:19 +02002132 SSL_MODE_ENABLE_PARTIAL_WRITE |
2133 SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER |
Willy Tarreau396a1862014-11-13 14:06:52 +01002134 SSL_MODE_RELEASE_BUFFERS |
2135 SSL_MODE_SMALL_BUFFERS;
Emeric Brun850efd52014-01-29 12:24:34 +01002136 int verify = SSL_VERIFY_NONE;
Emeric Brun94324a42012-10-11 14:00:19 +02002137
Thierry Fournier383085f2013-01-24 14:15:43 +01002138 /* Make sure openssl opens /dev/urandom before the chroot */
2139 if (!ssl_initialize_random()) {
2140 Alert("OpenSSL random data generator initialization failed.\n");
2141 cfgerr++;
2142 }
2143
Willy Tarreaufce03112015-01-15 21:32:40 +01002144 /* Automatic memory computations need to know we use SSL there */
2145 global.ssl_used_backend = 1;
2146
2147 /* Initiate SSL context for current server */
Emeric Brun94324a42012-10-11 14:00:19 +02002148 srv->ssl_ctx.reused_sess = NULL;
2149 if (srv->use_ssl)
2150 srv->xprt = &ssl_sock;
2151 if (srv->check.use_ssl)
Cyril Bonté9ce13112014-11-15 22:41:27 +01002152 srv->check.xprt = &ssl_sock;
Emeric Brun94324a42012-10-11 14:00:19 +02002153
2154 srv->ssl_ctx.ctx = SSL_CTX_new(SSLv23_client_method());
2155 if (!srv->ssl_ctx.ctx) {
2156 Alert("config : %s '%s', server '%s': unable to allocate ssl context.\n",
2157 proxy_type_str(curproxy), curproxy->id,
2158 srv->id);
2159 cfgerr++;
2160 return cfgerr;
2161 }
Emeric Bruna7aa3092012-10-26 12:58:00 +02002162 if (srv->ssl_ctx.client_crt) {
2163 if (SSL_CTX_use_PrivateKey_file(srv->ssl_ctx.ctx, srv->ssl_ctx.client_crt, SSL_FILETYPE_PEM) <= 0) {
2164 Alert("config : %s '%s', server '%s': unable to load SSL private key from PEM file '%s'.\n",
2165 proxy_type_str(curproxy), curproxy->id,
2166 srv->id, srv->ssl_ctx.client_crt);
2167 cfgerr++;
2168 }
2169 else if (SSL_CTX_use_certificate_chain_file(srv->ssl_ctx.ctx, srv->ssl_ctx.client_crt) <= 0) {
2170 Alert("config : %s '%s', server '%s': unable to load ssl certificate from PEM file '%s'.\n",
2171 proxy_type_str(curproxy), curproxy->id,
2172 srv->id, srv->ssl_ctx.client_crt);
2173 cfgerr++;
2174 }
2175 else if (SSL_CTX_check_private_key(srv->ssl_ctx.ctx) <= 0) {
2176 Alert("config : %s '%s', server '%s': inconsistencies between private key and certificate loaded from PEM file '%s'.\n",
2177 proxy_type_str(curproxy), curproxy->id,
2178 srv->id, srv->ssl_ctx.client_crt);
2179 cfgerr++;
2180 }
2181 }
Emeric Brun94324a42012-10-11 14:00:19 +02002182
2183 if (srv->ssl_ctx.options & SRV_SSL_O_NO_SSLV3)
2184 options |= SSL_OP_NO_SSLv3;
2185 if (srv->ssl_ctx.options & SRV_SSL_O_NO_TLSV10)
2186 options |= SSL_OP_NO_TLSv1;
2187 if (srv->ssl_ctx.options & SRV_SSL_O_NO_TLSV11)
2188 options |= SSL_OP_NO_TLSv1_1;
2189 if (srv->ssl_ctx.options & SRV_SSL_O_NO_TLSV12)
2190 options |= SSL_OP_NO_TLSv1_2;
Emeric Brunf9c5c472012-10-11 15:28:34 +02002191 if (srv->ssl_ctx.options & SRV_SSL_O_NO_TLS_TICKETS)
2192 options |= SSL_OP_NO_TICKET;
Emeric Brun94324a42012-10-11 14:00:19 +02002193 if (srv->ssl_ctx.options & SRV_SSL_O_USE_SSLV3)
2194 SSL_CTX_set_ssl_version(srv->ssl_ctx.ctx, SSLv3_client_method());
2195 if (srv->ssl_ctx.options & SRV_SSL_O_USE_TLSV10)
2196 SSL_CTX_set_ssl_version(srv->ssl_ctx.ctx, TLSv1_client_method());
2197#if SSL_OP_NO_TLSv1_1
2198 if (srv->ssl_ctx.options & SRV_SSL_O_USE_TLSV11)
2199 SSL_CTX_set_ssl_version(srv->ssl_ctx.ctx, TLSv1_1_client_method());
2200#endif
2201#if SSL_OP_NO_TLSv1_2
2202 if (srv->ssl_ctx.options & SRV_SSL_O_USE_TLSV12)
2203 SSL_CTX_set_ssl_version(srv->ssl_ctx.ctx, TLSv1_2_client_method());
2204#endif
2205
2206 SSL_CTX_set_options(srv->ssl_ctx.ctx, options);
2207 SSL_CTX_set_mode(srv->ssl_ctx.ctx, mode);
Emeric Brun850efd52014-01-29 12:24:34 +01002208
2209 if (global.ssl_server_verify == SSL_SERVER_VERIFY_REQUIRED)
2210 verify = SSL_VERIFY_PEER;
2211
2212 switch (srv->ssl_ctx.verify) {
2213 case SSL_SOCK_VERIFY_NONE:
2214 verify = SSL_VERIFY_NONE;
2215 break;
2216 case SSL_SOCK_VERIFY_REQUIRED:
2217 verify = SSL_VERIFY_PEER;
2218 break;
2219 }
Evan Broderbe554312013-06-27 00:05:25 -07002220 SSL_CTX_set_verify(srv->ssl_ctx.ctx,
Emeric Brun850efd52014-01-29 12:24:34 +01002221 verify,
Evan Broderbe554312013-06-27 00:05:25 -07002222 srv->ssl_ctx.verify_host ? ssl_sock_srv_verifycbk : NULL);
Emeric Brun850efd52014-01-29 12:24:34 +01002223 if (verify & SSL_VERIFY_PEER) {
Emeric Brunef42d922012-10-11 16:11:36 +02002224 if (srv->ssl_ctx.ca_file) {
2225 /* load CAfile to verify */
2226 if (!SSL_CTX_load_verify_locations(srv->ssl_ctx.ctx, srv->ssl_ctx.ca_file, NULL)) {
Willy Tarreau07ba08b2014-02-16 19:22:08 +01002227 Alert("Proxy '%s', server '%s' [%s:%d] unable to load CA file '%s'.\n",
Emeric Brunef42d922012-10-11 16:11:36 +02002228 curproxy->id, srv->id,
2229 srv->conf.file, srv->conf.line, srv->ssl_ctx.ca_file);
2230 cfgerr++;
2231 }
2232 }
Emeric Brun850efd52014-01-29 12:24:34 +01002233 else {
2234 if (global.ssl_server_verify == SSL_SERVER_VERIFY_REQUIRED)
Willy Tarreau07ba08b2014-02-16 19:22:08 +01002235 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 +01002236 curproxy->id, srv->id,
2237 srv->conf.file, srv->conf.line);
2238 else
Willy Tarreau07ba08b2014-02-16 19:22:08 +01002239 Alert("Proxy '%s', server '%s' [%s:%d] verify is enabled but no CA file specified.\n",
Emeric Brun850efd52014-01-29 12:24:34 +01002240 curproxy->id, srv->id,
2241 srv->conf.file, srv->conf.line);
2242 cfgerr++;
2243 }
Emeric Brunef42d922012-10-11 16:11:36 +02002244#ifdef X509_V_FLAG_CRL_CHECK
2245 if (srv->ssl_ctx.crl_file) {
2246 X509_STORE *store = SSL_CTX_get_cert_store(srv->ssl_ctx.ctx);
2247
2248 if (!store || !X509_STORE_load_locations(store, srv->ssl_ctx.crl_file, NULL)) {
Willy Tarreau07ba08b2014-02-16 19:22:08 +01002249 Alert("Proxy '%s', server '%s' [%s:%d] unable to configure CRL file '%s'.\n",
Emeric Brunef42d922012-10-11 16:11:36 +02002250 curproxy->id, srv->id,
2251 srv->conf.file, srv->conf.line, srv->ssl_ctx.crl_file);
2252 cfgerr++;
2253 }
2254 else {
2255 X509_STORE_set_flags(store, X509_V_FLAG_CRL_CHECK|X509_V_FLAG_CRL_CHECK_ALL);
2256 }
2257 }
2258#endif
2259 }
2260
Emeric Brun4f65bff2012-11-16 15:11:00 +01002261 if (global.tune.ssllifetime)
2262 SSL_CTX_set_timeout(srv->ssl_ctx.ctx, global.tune.ssllifetime);
2263
Emeric Brun94324a42012-10-11 14:00:19 +02002264 SSL_CTX_set_session_cache_mode(srv->ssl_ctx.ctx, SSL_SESS_CACHE_OFF);
2265 if (srv->ssl_ctx.ciphers &&
2266 !SSL_CTX_set_cipher_list(srv->ssl_ctx.ctx, srv->ssl_ctx.ciphers)) {
2267 Alert("Proxy '%s', server '%s' [%s:%d] : unable to set SSL cipher list to '%s'.\n",
2268 curproxy->id, srv->id,
2269 srv->conf.file, srv->conf.line, srv->ssl_ctx.ciphers);
2270 cfgerr++;
2271 }
2272
2273 return cfgerr;
2274}
2275
Willy Tarreau2a65ff02012-09-13 17:54:29 +02002276/* Walks down the two trees in bind_conf and prepares all certs. The pointer may
Emeric Brunfc0421f2012-09-07 17:30:07 +02002277 * be NULL, in which case nothing is done. Returns the number of errors
2278 * encountered.
2279 */
Willy Tarreau2a65ff02012-09-13 17:54:29 +02002280int ssl_sock_prepare_all_ctx(struct bind_conf *bind_conf, struct proxy *px)
Emeric Brunfc0421f2012-09-07 17:30:07 +02002281{
2282 struct ebmb_node *node;
2283 struct sni_ctx *sni;
2284 int err = 0;
2285
Willy Tarreau2a65ff02012-09-13 17:54:29 +02002286 if (!bind_conf || !bind_conf->is_ssl)
Emeric Brunfc0421f2012-09-07 17:30:07 +02002287 return 0;
2288
Willy Tarreaufce03112015-01-15 21:32:40 +01002289 /* Automatic memory computations need to know we use SSL there */
2290 global.ssl_used_frontend = 1;
2291
Emeric Brun0bed9942014-10-30 19:25:24 +01002292 if (bind_conf->default_ctx)
2293 err += ssl_sock_prepare_ctx(bind_conf, bind_conf->default_ctx, px);
2294
Willy Tarreau2a65ff02012-09-13 17:54:29 +02002295 node = ebmb_first(&bind_conf->sni_ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002296 while (node) {
2297 sni = ebmb_entry(node, struct sni_ctx, name);
Emeric Brun0bed9942014-10-30 19:25:24 +01002298 if (!sni->order && sni->ctx != bind_conf->default_ctx)
2299 /* only initialize the CTX on its first occurrence and
2300 if it is not the default_ctx */
Willy Tarreau2a65ff02012-09-13 17:54:29 +02002301 err += ssl_sock_prepare_ctx(bind_conf, sni->ctx, px);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002302 node = ebmb_next(node);
2303 }
2304
Willy Tarreau2a65ff02012-09-13 17:54:29 +02002305 node = ebmb_first(&bind_conf->sni_w_ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002306 while (node) {
2307 sni = ebmb_entry(node, struct sni_ctx, name);
Emeric Brun0bed9942014-10-30 19:25:24 +01002308 if (!sni->order && sni->ctx != bind_conf->default_ctx)
2309 /* only initialize the CTX on its first occurrence and
2310 if it is not the default_ctx */
Willy Tarreau2a65ff02012-09-13 17:54:29 +02002311 err += ssl_sock_prepare_ctx(bind_conf, sni->ctx, px);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002312 node = ebmb_next(node);
2313 }
2314 return err;
2315}
2316
Willy Tarreau2a65ff02012-09-13 17:54:29 +02002317/* Walks down the two trees in bind_conf and frees all the certs. The pointer may
Emeric Brunfc0421f2012-09-07 17:30:07 +02002318 * be NULL, in which case nothing is done. The default_ctx is nullified too.
2319 */
Willy Tarreau2a65ff02012-09-13 17:54:29 +02002320void ssl_sock_free_all_ctx(struct bind_conf *bind_conf)
Emeric Brunfc0421f2012-09-07 17:30:07 +02002321{
2322 struct ebmb_node *node, *back;
2323 struct sni_ctx *sni;
2324
Willy Tarreau2a65ff02012-09-13 17:54:29 +02002325 if (!bind_conf || !bind_conf->is_ssl)
Emeric Brunfc0421f2012-09-07 17:30:07 +02002326 return;
2327
Willy Tarreau2a65ff02012-09-13 17:54:29 +02002328 node = ebmb_first(&bind_conf->sni_ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002329 while (node) {
2330 sni = ebmb_entry(node, struct sni_ctx, name);
2331 back = ebmb_next(node);
2332 ebmb_delete(node);
2333 if (!sni->order) /* only free the CTX on its first occurrence */
2334 SSL_CTX_free(sni->ctx);
2335 free(sni);
2336 node = back;
2337 }
2338
Willy Tarreau2a65ff02012-09-13 17:54:29 +02002339 node = ebmb_first(&bind_conf->sni_w_ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002340 while (node) {
2341 sni = ebmb_entry(node, struct sni_ctx, name);
2342 back = ebmb_next(node);
2343 ebmb_delete(node);
2344 if (!sni->order) /* only free the CTX on its first occurrence */
2345 SSL_CTX_free(sni->ctx);
2346 free(sni);
2347 node = back;
2348 }
2349
Willy Tarreau2a65ff02012-09-13 17:54:29 +02002350 bind_conf->default_ctx = NULL;
Emeric Brune1f38db2012-09-03 20:36:47 +02002351}
2352
Emeric Brun46591952012-05-18 15:47:34 +02002353/*
2354 * This function is called if SSL * context is not yet allocated. The function
2355 * is designed to be called before any other data-layer operation and sets the
2356 * handshake flag on the connection. It is safe to call it multiple times.
2357 * It returns 0 on success and -1 in error case.
2358 */
2359static int ssl_sock_init(struct connection *conn)
2360{
2361 /* already initialized */
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02002362 if (conn->xprt_ctx)
Emeric Brun46591952012-05-18 15:47:34 +02002363 return 0;
2364
Willy Tarreau3c728722014-01-23 13:50:42 +01002365 if (!conn_ctrl_ready(conn))
Willy Tarreauf79c8172013-10-21 16:30:56 +02002366 return 0;
2367
Willy Tarreau20879a02012-12-03 16:32:10 +01002368 if (global.maxsslconn && sslconns >= global.maxsslconn) {
2369 conn->err_code = CO_ER_SSL_TOO_MANY;
Willy Tarreau403edff2012-09-06 11:58:37 +02002370 return -1;
Willy Tarreau20879a02012-12-03 16:32:10 +01002371 }
Willy Tarreau403edff2012-09-06 11:58:37 +02002372
Emeric Brun46591952012-05-18 15:47:34 +02002373 /* If it is in client mode initiate SSL session
2374 in connect state otherwise accept state */
Willy Tarreau3fdb3662012-11-12 00:42:33 +01002375 if (objt_server(conn->target)) {
Willy Tarreaufba03cd2014-11-13 13:48:58 +01002376 int may_retry = 1;
2377
2378 retry_connect:
Emeric Brun46591952012-05-18 15:47:34 +02002379 /* Alloc a new SSL session ctx */
Willy Tarreau3fdb3662012-11-12 00:42:33 +01002380 conn->xprt_ctx = SSL_new(objt_server(conn->target)->ssl_ctx.ctx);
Willy Tarreau20879a02012-12-03 16:32:10 +01002381 if (!conn->xprt_ctx) {
Willy Tarreaufba03cd2014-11-13 13:48:58 +01002382 if (may_retry--) {
2383 pool_gc2();
2384 goto retry_connect;
2385 }
Willy Tarreau20879a02012-12-03 16:32:10 +01002386 conn->err_code = CO_ER_SSL_NO_MEM;
Emeric Brun46591952012-05-18 15:47:34 +02002387 return -1;
Willy Tarreau20879a02012-12-03 16:32:10 +01002388 }
Emeric Brun46591952012-05-18 15:47:34 +02002389
Emeric Brun46591952012-05-18 15:47:34 +02002390 /* set fd on SSL session context */
Emeric Brun55476152014-11-12 17:35:37 +01002391 if (!SSL_set_fd(conn->xprt_ctx, conn->t.sock.fd)) {
2392 SSL_free(conn->xprt_ctx);
2393 conn->xprt_ctx = NULL;
Willy Tarreaufba03cd2014-11-13 13:48:58 +01002394 if (may_retry--) {
2395 pool_gc2();
2396 goto retry_connect;
2397 }
Emeric Brun55476152014-11-12 17:35:37 +01002398 conn->err_code = CO_ER_SSL_NO_MEM;
2399 return -1;
2400 }
Emeric Brun46591952012-05-18 15:47:34 +02002401
Evan Broderbe554312013-06-27 00:05:25 -07002402 /* set connection pointer */
Emeric Brun55476152014-11-12 17:35:37 +01002403 if (!SSL_set_app_data(conn->xprt_ctx, conn)) {
2404 SSL_free(conn->xprt_ctx);
2405 conn->xprt_ctx = NULL;
Willy Tarreaufba03cd2014-11-13 13:48:58 +01002406 if (may_retry--) {
2407 pool_gc2();
2408 goto retry_connect;
2409 }
Emeric Brun55476152014-11-12 17:35:37 +01002410 conn->err_code = CO_ER_SSL_NO_MEM;
2411 return -1;
2412 }
2413
2414 SSL_set_connect_state(conn->xprt_ctx);
2415 if (objt_server(conn->target)->ssl_ctx.reused_sess) {
2416 if(!SSL_set_session(conn->xprt_ctx, objt_server(conn->target)->ssl_ctx.reused_sess)) {
2417 SSL_SESSION_free(objt_server(conn->target)->ssl_ctx.reused_sess);
2418 objt_server(conn->target)->ssl_ctx.reused_sess = NULL;
2419 }
2420 }
Evan Broderbe554312013-06-27 00:05:25 -07002421
Emeric Brun46591952012-05-18 15:47:34 +02002422 /* leave init state and start handshake */
Willy Tarreau05737472012-09-04 08:03:39 +02002423 conn->flags |= CO_FL_SSL_WAIT_HS | CO_FL_WAIT_L6_CONN;
Willy Tarreau403edff2012-09-06 11:58:37 +02002424
2425 sslconns++;
Willy Tarreau71b734c2014-01-28 15:19:44 +01002426 totalsslconns++;
Emeric Brun46591952012-05-18 15:47:34 +02002427 return 0;
2428 }
Willy Tarreau3fdb3662012-11-12 00:42:33 +01002429 else if (objt_listener(conn->target)) {
Willy Tarreaufba03cd2014-11-13 13:48:58 +01002430 int may_retry = 1;
2431
2432 retry_accept:
Emeric Brun46591952012-05-18 15:47:34 +02002433 /* Alloc a new SSL session ctx */
Willy Tarreau3fdb3662012-11-12 00:42:33 +01002434 conn->xprt_ctx = SSL_new(objt_listener(conn->target)->bind_conf->default_ctx);
Willy Tarreau20879a02012-12-03 16:32:10 +01002435 if (!conn->xprt_ctx) {
Willy Tarreaufba03cd2014-11-13 13:48:58 +01002436 if (may_retry--) {
2437 pool_gc2();
2438 goto retry_accept;
2439 }
Willy Tarreau20879a02012-12-03 16:32:10 +01002440 conn->err_code = CO_ER_SSL_NO_MEM;
Emeric Brun46591952012-05-18 15:47:34 +02002441 return -1;
Willy Tarreau20879a02012-12-03 16:32:10 +01002442 }
Emeric Brun46591952012-05-18 15:47:34 +02002443
Emeric Brun46591952012-05-18 15:47:34 +02002444 /* set fd on SSL session context */
Emeric Brun55476152014-11-12 17:35:37 +01002445 if (!SSL_set_fd(conn->xprt_ctx, conn->t.sock.fd)) {
2446 SSL_free(conn->xprt_ctx);
2447 conn->xprt_ctx = NULL;
Willy Tarreaufba03cd2014-11-13 13:48:58 +01002448 if (may_retry--) {
2449 pool_gc2();
2450 goto retry_accept;
2451 }
Emeric Brun55476152014-11-12 17:35:37 +01002452 conn->err_code = CO_ER_SSL_NO_MEM;
2453 return -1;
2454 }
Emeric Brun46591952012-05-18 15:47:34 +02002455
Emeric Brune1f38db2012-09-03 20:36:47 +02002456 /* set connection pointer */
Emeric Brun55476152014-11-12 17:35:37 +01002457 if (!SSL_set_app_data(conn->xprt_ctx, conn)) {
2458 SSL_free(conn->xprt_ctx);
2459 conn->xprt_ctx = NULL;
Willy Tarreaufba03cd2014-11-13 13:48:58 +01002460 if (may_retry--) {
2461 pool_gc2();
2462 goto retry_accept;
2463 }
Emeric Brun55476152014-11-12 17:35:37 +01002464 conn->err_code = CO_ER_SSL_NO_MEM;
2465 return -1;
2466 }
2467
2468 SSL_set_accept_state(conn->xprt_ctx);
Emeric Brune1f38db2012-09-03 20:36:47 +02002469
Emeric Brun46591952012-05-18 15:47:34 +02002470 /* leave init state and start handshake */
Willy Tarreau05737472012-09-04 08:03:39 +02002471 conn->flags |= CO_FL_SSL_WAIT_HS | CO_FL_WAIT_L6_CONN;
Willy Tarreau403edff2012-09-06 11:58:37 +02002472
2473 sslconns++;
Willy Tarreau71b734c2014-01-28 15:19:44 +01002474 totalsslconns++;
Emeric Brun46591952012-05-18 15:47:34 +02002475 return 0;
2476 }
2477 /* don't know how to handle such a target */
Willy Tarreau20879a02012-12-03 16:32:10 +01002478 conn->err_code = CO_ER_SSL_NO_TARGET;
Emeric Brun46591952012-05-18 15:47:34 +02002479 return -1;
2480}
2481
2482
2483/* This is the callback which is used when an SSL handshake is pending. It
2484 * updates the FD status if it wants some polling before being called again.
2485 * It returns 0 if it fails in a fatal way or needs to poll to go further,
2486 * otherwise it returns non-zero and removes itself from the connection's
2487 * flags (the bit is provided in <flag> by the caller).
2488 */
2489int ssl_sock_handshake(struct connection *conn, unsigned int flag)
2490{
2491 int ret;
2492
Willy Tarreau3c728722014-01-23 13:50:42 +01002493 if (!conn_ctrl_ready(conn))
Willy Tarreauf79c8172013-10-21 16:30:56 +02002494 return 0;
2495
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02002496 if (!conn->xprt_ctx)
Emeric Brun46591952012-05-18 15:47:34 +02002497 goto out_error;
2498
Emeric Brun674b7432012-11-08 19:21:55 +01002499 /* If we use SSL_do_handshake to process a reneg initiated by
2500 * the remote peer, it sometimes returns SSL_ERROR_SSL.
2501 * Usually SSL_write and SSL_read are used and process implicitly
2502 * the reneg handshake.
2503 * Here we use SSL_peek as a workaround for reneg.
2504 */
2505 if ((conn->flags & CO_FL_CONNECTED) && SSL_renegotiate_pending(conn->xprt_ctx)) {
2506 char c;
2507
2508 ret = SSL_peek(conn->xprt_ctx, &c, 1);
2509 if (ret <= 0) {
2510 /* handshake may have not been completed, let's find why */
2511 ret = SSL_get_error(conn->xprt_ctx, ret);
2512 if (ret == SSL_ERROR_WANT_WRITE) {
2513 /* SSL handshake needs to write, L4 connection may not be ready */
2514 __conn_sock_stop_recv(conn);
Willy Tarreaue1f50c42014-01-22 20:02:06 +01002515 __conn_sock_want_send(conn);
2516 fd_cant_send(conn->t.sock.fd);
Emeric Brun674b7432012-11-08 19:21:55 +01002517 return 0;
2518 }
2519 else if (ret == SSL_ERROR_WANT_READ) {
2520 /* handshake may have been completed but we have
2521 * no more data to read.
2522 */
2523 if (!SSL_renegotiate_pending(conn->xprt_ctx)) {
2524 ret = 1;
2525 goto reneg_ok;
2526 }
2527 /* SSL handshake needs to read, L4 connection is ready */
2528 if (conn->flags & CO_FL_WAIT_L4_CONN)
2529 conn->flags &= ~CO_FL_WAIT_L4_CONN;
2530 __conn_sock_stop_send(conn);
Willy Tarreaue1f50c42014-01-22 20:02:06 +01002531 __conn_sock_want_recv(conn);
2532 fd_cant_recv(conn->t.sock.fd);
Emeric Brun674b7432012-11-08 19:21:55 +01002533 return 0;
2534 }
2535 else if (ret == SSL_ERROR_SYSCALL) {
2536 /* if errno is null, then connection was successfully established */
2537 if (!errno && conn->flags & CO_FL_WAIT_L4_CONN)
2538 conn->flags &= ~CO_FL_WAIT_L4_CONN;
Willy Tarreau20879a02012-12-03 16:32:10 +01002539 if (!conn->err_code) {
Emeric Brun29f037d2014-04-25 19:05:36 +02002540 if (!((SSL *)conn->xprt_ctx)->packet_length) {
2541 if (!errno) {
2542 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
2543 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
2544 else
2545 conn->err_code = CO_ER_SSL_EMPTY;
2546 }
2547 else {
2548 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
2549 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
2550 else
2551 conn->err_code = CO_ER_SSL_ABORT;
2552 }
2553 }
2554 else {
2555 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
2556 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
Willy Tarreau20879a02012-12-03 16:32:10 +01002557 else
Emeric Brun29f037d2014-04-25 19:05:36 +02002558 conn->err_code = CO_ER_SSL_HANDSHAKE;
2559 }
Willy Tarreau20879a02012-12-03 16:32:10 +01002560 }
Emeric Brun674b7432012-11-08 19:21:55 +01002561 goto out_error;
2562 }
2563 else {
2564 /* Fail on all other handshake errors */
2565 /* Note: OpenSSL may leave unread bytes in the socket's
2566 * buffer, causing an RST to be emitted upon close() on
2567 * TCP sockets. We first try to drain possibly pending
2568 * data to avoid this as much as possible.
2569 */
Willy Tarreaud85c4852015-03-13 00:40:28 +01002570 conn_sock_drain(conn);
Willy Tarreau20879a02012-12-03 16:32:10 +01002571 if (!conn->err_code)
Willy Tarreauf51c6982014-04-25 20:02:39 +02002572 conn->err_code = (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT) ?
2573 CO_ER_SSL_KILLED_HB : CO_ER_SSL_HANDSHAKE;
Emeric Brun674b7432012-11-08 19:21:55 +01002574 goto out_error;
2575 }
2576 }
2577 /* read some data: consider handshake completed */
2578 goto reneg_ok;
2579 }
2580
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02002581 ret = SSL_do_handshake(conn->xprt_ctx);
Emeric Brun46591952012-05-18 15:47:34 +02002582 if (ret != 1) {
2583 /* handshake did not complete, let's find why */
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02002584 ret = SSL_get_error(conn->xprt_ctx, ret);
Emeric Brun46591952012-05-18 15:47:34 +02002585
2586 if (ret == SSL_ERROR_WANT_WRITE) {
2587 /* SSL handshake needs to write, L4 connection may not be ready */
2588 __conn_sock_stop_recv(conn);
Willy Tarreaue1f50c42014-01-22 20:02:06 +01002589 __conn_sock_want_send(conn);
2590 fd_cant_send(conn->t.sock.fd);
Emeric Brun46591952012-05-18 15:47:34 +02002591 return 0;
2592 }
2593 else if (ret == SSL_ERROR_WANT_READ) {
2594 /* SSL handshake needs to read, L4 connection is ready */
2595 if (conn->flags & CO_FL_WAIT_L4_CONN)
2596 conn->flags &= ~CO_FL_WAIT_L4_CONN;
2597 __conn_sock_stop_send(conn);
Willy Tarreaue1f50c42014-01-22 20:02:06 +01002598 __conn_sock_want_recv(conn);
2599 fd_cant_recv(conn->t.sock.fd);
Emeric Brun46591952012-05-18 15:47:34 +02002600 return 0;
2601 }
Willy Tarreau89230192012-09-28 20:22:13 +02002602 else if (ret == SSL_ERROR_SYSCALL) {
2603 /* if errno is null, then connection was successfully established */
2604 if (!errno && conn->flags & CO_FL_WAIT_L4_CONN)
2605 conn->flags &= ~CO_FL_WAIT_L4_CONN;
Willy Tarreau20879a02012-12-03 16:32:10 +01002606
Emeric Brun29f037d2014-04-25 19:05:36 +02002607 if (!((SSL *)conn->xprt_ctx)->packet_length) {
2608 if (!errno) {
2609 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
2610 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
2611 else
2612 conn->err_code = CO_ER_SSL_EMPTY;
2613 }
2614 else {
2615 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
2616 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
2617 else
2618 conn->err_code = CO_ER_SSL_ABORT;
2619 }
2620 }
2621 else {
2622 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
2623 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
Willy Tarreau20879a02012-12-03 16:32:10 +01002624 else
Emeric Brun29f037d2014-04-25 19:05:36 +02002625 conn->err_code = CO_ER_SSL_HANDSHAKE;
2626 }
Willy Tarreau89230192012-09-28 20:22:13 +02002627 goto out_error;
2628 }
Emeric Brun46591952012-05-18 15:47:34 +02002629 else {
2630 /* Fail on all other handshake errors */
Willy Tarreau566dc552012-10-19 20:52:18 +02002631 /* Note: OpenSSL may leave unread bytes in the socket's
2632 * buffer, causing an RST to be emitted upon close() on
2633 * TCP sockets. We first try to drain possibly pending
2634 * data to avoid this as much as possible.
2635 */
Willy Tarreaud85c4852015-03-13 00:40:28 +01002636 conn_sock_drain(conn);
Willy Tarreau20879a02012-12-03 16:32:10 +01002637 if (!conn->err_code)
Willy Tarreauf51c6982014-04-25 20:02:39 +02002638 conn->err_code = (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT) ?
2639 CO_ER_SSL_KILLED_HB : CO_ER_SSL_HANDSHAKE;
Emeric Brun46591952012-05-18 15:47:34 +02002640 goto out_error;
2641 }
2642 }
2643
Emeric Brun674b7432012-11-08 19:21:55 +01002644reneg_ok:
2645
Emeric Brun46591952012-05-18 15:47:34 +02002646 /* Handshake succeeded */
Willy Tarreau0c9c2722014-05-28 12:28:58 +02002647 if (!SSL_session_reused(conn->xprt_ctx)) {
2648 if (objt_server(conn->target)) {
2649 update_freq_ctr(&global.ssl_be_keys_per_sec, 1);
2650 if (global.ssl_be_keys_per_sec.curr_ctr > global.ssl_be_keys_max)
2651 global.ssl_be_keys_max = global.ssl_be_keys_per_sec.curr_ctr;
2652
Emeric Brun46591952012-05-18 15:47:34 +02002653 /* check if session was reused, if not store current session on server for reuse */
Willy Tarreau3fdb3662012-11-12 00:42:33 +01002654 if (objt_server(conn->target)->ssl_ctx.reused_sess)
2655 SSL_SESSION_free(objt_server(conn->target)->ssl_ctx.reused_sess);
Emeric Brun46591952012-05-18 15:47:34 +02002656
Willy Tarreau2a3fb1c2015-02-05 16:47:07 +01002657 if (!(objt_server(conn->target)->ssl_ctx.options & SRV_SSL_O_NO_REUSE))
2658 objt_server(conn->target)->ssl_ctx.reused_sess = SSL_get1_session(conn->xprt_ctx);
Emeric Brun46591952012-05-18 15:47:34 +02002659 }
Willy Tarreau0c9c2722014-05-28 12:28:58 +02002660 else {
2661 update_freq_ctr(&global.ssl_fe_keys_per_sec, 1);
2662 if (global.ssl_fe_keys_per_sec.curr_ctr > global.ssl_fe_keys_max)
2663 global.ssl_fe_keys_max = global.ssl_fe_keys_per_sec.curr_ctr;
2664 }
Emeric Brun46591952012-05-18 15:47:34 +02002665 }
2666
2667 /* The connection is now established at both layers, it's time to leave */
2668 conn->flags &= ~(flag | CO_FL_WAIT_L4_CONN | CO_FL_WAIT_L6_CONN);
2669 return 1;
2670
2671 out_error:
Emeric Brun644cde02012-12-14 11:21:13 +01002672 /* Clear openssl global errors stack */
2673 ERR_clear_error();
2674
Emeric Brun9fa89732012-10-04 17:09:56 +02002675 /* free resumed session if exists */
Willy Tarreau3fdb3662012-11-12 00:42:33 +01002676 if (objt_server(conn->target) && objt_server(conn->target)->ssl_ctx.reused_sess) {
2677 SSL_SESSION_free(objt_server(conn->target)->ssl_ctx.reused_sess);
2678 objt_server(conn->target)->ssl_ctx.reused_sess = NULL;
Emeric Brun9fa89732012-10-04 17:09:56 +02002679 }
2680
Emeric Brun46591952012-05-18 15:47:34 +02002681 /* Fail on all other handshake errors */
2682 conn->flags |= CO_FL_ERROR;
Willy Tarreau20879a02012-12-03 16:32:10 +01002683 if (!conn->err_code)
2684 conn->err_code = CO_ER_SSL_HANDSHAKE;
Emeric Brun46591952012-05-18 15:47:34 +02002685 return 0;
2686}
2687
2688/* Receive up to <count> bytes from connection <conn>'s socket and store them
Willy Tarreauabf08d92014-01-14 11:31:27 +01002689 * into buffer <buf>. Only one call to recv() is performed, unless the
Emeric Brun46591952012-05-18 15:47:34 +02002690 * buffer wraps, in which case a second call may be performed. The connection's
2691 * flags are updated with whatever special event is detected (error, read0,
2692 * empty). The caller is responsible for taking care of those events and
2693 * avoiding the call if inappropriate. The function does not call the
2694 * connection's polling update function, so the caller is responsible for this.
2695 */
2696static int ssl_sock_to_buf(struct connection *conn, struct buffer *buf, int count)
2697{
2698 int ret, done = 0;
Willy Tarreauabf08d92014-01-14 11:31:27 +01002699 int try;
Emeric Brun46591952012-05-18 15:47:34 +02002700
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02002701 if (!conn->xprt_ctx)
Emeric Brun46591952012-05-18 15:47:34 +02002702 goto out_error;
2703
2704 if (conn->flags & CO_FL_HANDSHAKE)
2705 /* a handshake was requested */
2706 return 0;
2707
Willy Tarreauabf08d92014-01-14 11:31:27 +01002708 /* let's realign the buffer to optimize I/O */
2709 if (buffer_empty(buf))
Emeric Brun46591952012-05-18 15:47:34 +02002710 buf->p = buf->data;
Emeric Brun46591952012-05-18 15:47:34 +02002711
2712 /* read the largest possible block. For this, we perform only one call
2713 * to recv() unless the buffer wraps and we exactly fill the first hunk,
2714 * in which case we accept to do it once again. A new attempt is made on
2715 * EINTR too.
2716 */
Willy Tarreau00b0fb92014-01-17 11:09:40 +01002717 while (count > 0) {
Willy Tarreauabf08d92014-01-14 11:31:27 +01002718 /* first check if we have some room after p+i */
2719 try = buf->data + buf->size - (buf->p + buf->i);
2720 /* otherwise continue between data and p-o */
2721 if (try <= 0) {
2722 try = buf->p - (buf->data + buf->o);
2723 if (try <= 0)
2724 break;
2725 }
2726 if (try > count)
2727 try = count;
2728
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02002729 ret = SSL_read(conn->xprt_ctx, bi_end(buf), try);
Emeric Brune1f38db2012-09-03 20:36:47 +02002730 if (conn->flags & CO_FL_ERROR) {
2731 /* CO_FL_ERROR may be set by ssl_sock_infocbk */
Emeric Brun644cde02012-12-14 11:21:13 +01002732 goto out_error;
Emeric Brune1f38db2012-09-03 20:36:47 +02002733 }
Emeric Brun46591952012-05-18 15:47:34 +02002734 if (ret > 0) {
2735 buf->i += ret;
2736 done += ret;
2737 if (ret < try)
2738 break;
2739 count -= ret;
Emeric Brun46591952012-05-18 15:47:34 +02002740 }
2741 else if (ret == 0) {
Emeric Brun644cde02012-12-14 11:21:13 +01002742 ret = SSL_get_error(conn->xprt_ctx, ret);
2743 if (ret != SSL_ERROR_ZERO_RETURN) {
Emeric Brun1c646862012-12-14 12:33:41 +01002744 /* error on protocol or underlying transport */
2745 if ((ret != SSL_ERROR_SYSCALL)
2746 || (errno && (errno != EAGAIN)))
2747 conn->flags |= CO_FL_ERROR;
2748
Emeric Brun644cde02012-12-14 11:21:13 +01002749 /* Clear openssl global errors stack */
2750 ERR_clear_error();
2751 }
Emeric Brun46591952012-05-18 15:47:34 +02002752 goto read0;
2753 }
2754 else {
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02002755 ret = SSL_get_error(conn->xprt_ctx, ret);
Emeric Brun46591952012-05-18 15:47:34 +02002756 if (ret == SSL_ERROR_WANT_WRITE) {
Emeric Brun8af8dd12012-11-08 17:56:20 +01002757 /* handshake is running, and it needs to enable write */
Emeric Brun46591952012-05-18 15:47:34 +02002758 conn->flags |= CO_FL_SSL_WAIT_HS;
Emeric Brun8af8dd12012-11-08 17:56:20 +01002759 __conn_sock_want_send(conn);
Emeric Brun46591952012-05-18 15:47:34 +02002760 break;
2761 }
2762 else if (ret == SSL_ERROR_WANT_READ) {
Emeric Brun282a76a2012-11-08 18:02:56 +01002763 if (SSL_renegotiate_pending(conn->xprt_ctx)) {
2764 /* handshake is running, and it may need to re-enable read */
2765 conn->flags |= CO_FL_SSL_WAIT_HS;
2766 __conn_sock_want_recv(conn);
2767 break;
2768 }
Emeric Brun46591952012-05-18 15:47:34 +02002769 /* we need to poll for retry a read later */
Willy Tarreaue1f50c42014-01-22 20:02:06 +01002770 fd_cant_recv(conn->t.sock.fd);
Emeric Brun46591952012-05-18 15:47:34 +02002771 break;
2772 }
2773 /* otherwise it's a real error */
2774 goto out_error;
2775 }
2776 }
2777 return done;
2778
2779 read0:
2780 conn_sock_read0(conn);
2781 return done;
2782 out_error:
Emeric Brun644cde02012-12-14 11:21:13 +01002783 /* Clear openssl global errors stack */
2784 ERR_clear_error();
2785
Emeric Brun46591952012-05-18 15:47:34 +02002786 conn->flags |= CO_FL_ERROR;
2787 return done;
2788}
2789
2790
2791/* Send all pending bytes from buffer <buf> to connection <conn>'s socket.
Willy Tarreau1049b1f2014-02-02 01:51:17 +01002792 * <flags> may contain some CO_SFL_* flags to hint the system about other
2793 * pending data for example, but this flag is ignored at the moment.
Emeric Brun46591952012-05-18 15:47:34 +02002794 * Only one call to send() is performed, unless the buffer wraps, in which case
2795 * a second call may be performed. The connection's flags are updated with
2796 * whatever special event is detected (error, empty). The caller is responsible
2797 * for taking care of those events and avoiding the call if inappropriate. The
2798 * function does not call the connection's polling update function, so the caller
2799 * is responsible for this.
2800 */
2801static int ssl_sock_from_buf(struct connection *conn, struct buffer *buf, int flags)
2802{
2803 int ret, try, done;
2804
2805 done = 0;
2806
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02002807 if (!conn->xprt_ctx)
Emeric Brun46591952012-05-18 15:47:34 +02002808 goto out_error;
2809
2810 if (conn->flags & CO_FL_HANDSHAKE)
2811 /* a handshake was requested */
2812 return 0;
2813
2814 /* send the largest possible block. For this we perform only one call
2815 * to send() unless the buffer wraps and we exactly fill the first hunk,
2816 * in which case we accept to do it once again.
2817 */
2818 while (buf->o) {
Kevin Hestercad82342013-05-30 15:12:41 -07002819 try = bo_contig_data(buf);
Willy Tarreaubfd59462013-02-21 07:46:09 +01002820
Willy Tarreau7bed9452014-02-02 02:00:24 +01002821 if (!(flags & CO_SFL_STREAMER) &&
Willy Tarreau518cedd2014-02-17 15:43:01 +01002822 !(conn->xprt_st & SSL_SOCK_SEND_UNLIMITED) &&
2823 global.tune.ssl_max_record && try > global.tune.ssl_max_record) {
Willy Tarreaubfd59462013-02-21 07:46:09 +01002824 try = global.tune.ssl_max_record;
Willy Tarreau518cedd2014-02-17 15:43:01 +01002825 }
2826 else {
2827 /* we need to keep the information about the fact that
2828 * we're not limiting the upcoming send(), because if it
2829 * fails, we'll have to retry with at least as many data.
2830 */
2831 conn->xprt_st |= SSL_SOCK_SEND_UNLIMITED;
2832 }
Willy Tarreaubfd59462013-02-21 07:46:09 +01002833
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02002834 ret = SSL_write(conn->xprt_ctx, bo_ptr(buf), try);
Willy Tarreau518cedd2014-02-17 15:43:01 +01002835
Emeric Brune1f38db2012-09-03 20:36:47 +02002836 if (conn->flags & CO_FL_ERROR) {
2837 /* CO_FL_ERROR may be set by ssl_sock_infocbk */
Emeric Brun644cde02012-12-14 11:21:13 +01002838 goto out_error;
Emeric Brune1f38db2012-09-03 20:36:47 +02002839 }
Emeric Brun46591952012-05-18 15:47:34 +02002840 if (ret > 0) {
Willy Tarreau518cedd2014-02-17 15:43:01 +01002841 conn->xprt_st &= ~SSL_SOCK_SEND_UNLIMITED;
2842
Emeric Brun46591952012-05-18 15:47:34 +02002843 buf->o -= ret;
2844 done += ret;
2845
Willy Tarreau5fb38032012-12-16 19:39:09 +01002846 if (likely(buffer_empty(buf)))
Emeric Brun46591952012-05-18 15:47:34 +02002847 /* optimize data alignment in the buffer */
2848 buf->p = buf->data;
2849
2850 /* if the system buffer is full, don't insist */
2851 if (ret < try)
2852 break;
2853 }
2854 else {
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02002855 ret = SSL_get_error(conn->xprt_ctx, ret);
Emeric Brun46591952012-05-18 15:47:34 +02002856 if (ret == SSL_ERROR_WANT_WRITE) {
Emeric Brun282a76a2012-11-08 18:02:56 +01002857 if (SSL_renegotiate_pending(conn->xprt_ctx)) {
2858 /* handshake is running, and it may need to re-enable write */
2859 conn->flags |= CO_FL_SSL_WAIT_HS;
2860 __conn_sock_want_send(conn);
2861 break;
2862 }
Emeric Brun46591952012-05-18 15:47:34 +02002863 /* we need to poll to retry a write later */
Willy Tarreaue1f50c42014-01-22 20:02:06 +01002864 fd_cant_send(conn->t.sock.fd);
Emeric Brun46591952012-05-18 15:47:34 +02002865 break;
2866 }
2867 else if (ret == SSL_ERROR_WANT_READ) {
Emeric Brun8af8dd12012-11-08 17:56:20 +01002868 /* handshake is running, and it needs to enable read */
Emeric Brun46591952012-05-18 15:47:34 +02002869 conn->flags |= CO_FL_SSL_WAIT_HS;
Emeric Brun8af8dd12012-11-08 17:56:20 +01002870 __conn_sock_want_recv(conn);
Emeric Brun46591952012-05-18 15:47:34 +02002871 break;
2872 }
2873 goto out_error;
2874 }
2875 }
2876 return done;
2877
2878 out_error:
Emeric Brun644cde02012-12-14 11:21:13 +01002879 /* Clear openssl global errors stack */
2880 ERR_clear_error();
2881
Emeric Brun46591952012-05-18 15:47:34 +02002882 conn->flags |= CO_FL_ERROR;
2883 return done;
2884}
2885
Emeric Brun46591952012-05-18 15:47:34 +02002886static void ssl_sock_close(struct connection *conn) {
2887
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02002888 if (conn->xprt_ctx) {
2889 SSL_free(conn->xprt_ctx);
2890 conn->xprt_ctx = NULL;
Willy Tarreau403edff2012-09-06 11:58:37 +02002891 sslconns--;
Emeric Brun46591952012-05-18 15:47:34 +02002892 }
Emeric Brun46591952012-05-18 15:47:34 +02002893}
2894
2895/* This function tries to perform a clean shutdown on an SSL connection, and in
2896 * any case, flags the connection as reusable if no handshake was in progress.
2897 */
2898static void ssl_sock_shutw(struct connection *conn, int clean)
2899{
2900 if (conn->flags & CO_FL_HANDSHAKE)
2901 return;
2902 /* no handshake was in progress, try a clean ssl shutdown */
Emeric Brun644cde02012-12-14 11:21:13 +01002903 if (clean && (SSL_shutdown(conn->xprt_ctx) <= 0)) {
2904 /* Clear openssl global errors stack */
2905 ERR_clear_error();
2906 }
Emeric Brun46591952012-05-18 15:47:34 +02002907
2908 /* force flag on ssl to keep session in cache regardless shutdown result */
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02002909 SSL_set_shutdown(conn->xprt_ctx, SSL_SENT_SHUTDOWN);
Emeric Brun46591952012-05-18 15:47:34 +02002910}
2911
Willy Tarreauffc3fcd2012-10-12 20:17:54 +02002912/* used for logging, may be changed for a sample fetch later */
2913const char *ssl_sock_get_cipher_name(struct connection *conn)
2914{
2915 if (!conn->xprt && !conn->xprt_ctx)
2916 return NULL;
2917 return SSL_get_cipher_name(conn->xprt_ctx);
2918}
2919
2920/* used for logging, may be changed for a sample fetch later */
2921const char *ssl_sock_get_proto_version(struct connection *conn)
2922{
2923 if (!conn->xprt && !conn->xprt_ctx)
2924 return NULL;
2925 return SSL_get_version(conn->xprt_ctx);
2926}
2927
Willy Tarreau8d598402012-10-22 17:58:39 +02002928/* Extract a serial from a cert, and copy it to a chunk.
2929 * Returns 1 if serial is found and copied, 0 if no serial found and
2930 * -1 if output is not large enough.
2931 */
2932static int
2933ssl_sock_get_serial(X509 *crt, struct chunk *out)
2934{
2935 ASN1_INTEGER *serial;
2936
2937 serial = X509_get_serialNumber(crt);
2938 if (!serial)
2939 return 0;
2940
2941 if (out->size < serial->length)
2942 return -1;
2943
2944 memcpy(out->str, serial->data, serial->length);
2945 out->len = serial->length;
2946 return 1;
2947}
2948
Emeric Brun43e79582014-10-29 19:03:26 +01002949/* Extract a cert to der, and copy it to a chunk.
2950 * Returns 1 if cert is found and copied, 0 on der convertion failure and
2951 * -1 if output is not large enough.
2952 */
2953static int
2954ssl_sock_crt2der(X509 *crt, struct chunk *out)
2955{
2956 int len;
2957 unsigned char *p = (unsigned char *)out->str;;
2958
2959 len =i2d_X509(crt, NULL);
2960 if (len <= 0)
2961 return 1;
2962
2963 if (out->size < len)
2964 return -1;
2965
2966 i2d_X509(crt,&p);
2967 out->len = len;
2968 return 1;
2969}
2970
Emeric Brunce5ad802012-10-22 14:11:22 +02002971
2972/* Copy Date in ASN1_UTCTIME format in struct chunk out.
2973 * Returns 1 if serial is found and copied, 0 if no valid time found
2974 * and -1 if output is not large enough.
2975 */
2976static int
2977ssl_sock_get_time(ASN1_TIME *tm, struct chunk *out)
2978{
2979 if (tm->type == V_ASN1_GENERALIZEDTIME) {
2980 ASN1_GENERALIZEDTIME *gentm = (ASN1_GENERALIZEDTIME *)tm;
2981
2982 if (gentm->length < 12)
2983 return 0;
2984 if (gentm->data[0] != 0x32 || gentm->data[1] != 0x30)
2985 return 0;
2986 if (out->size < gentm->length-2)
2987 return -1;
2988
2989 memcpy(out->str, gentm->data+2, gentm->length-2);
2990 out->len = gentm->length-2;
2991 return 1;
2992 }
2993 else if (tm->type == V_ASN1_UTCTIME) {
2994 ASN1_UTCTIME *utctm = (ASN1_UTCTIME *)tm;
2995
2996 if (utctm->length < 10)
2997 return 0;
2998 if (utctm->data[0] >= 0x35)
2999 return 0;
3000 if (out->size < utctm->length)
3001 return -1;
3002
3003 memcpy(out->str, utctm->data, utctm->length);
3004 out->len = utctm->length;
3005 return 1;
3006 }
3007
3008 return 0;
3009}
3010
Emeric Brun87855892012-10-17 17:39:35 +02003011/* Extract an entry from a X509_NAME and copy its value to an output chunk.
3012 * Returns 1 if entry found, 0 if entry not found, or -1 if output not large enough.
3013 */
3014static int
3015ssl_sock_get_dn_entry(X509_NAME *a, const struct chunk *entry, int pos, struct chunk *out)
3016{
3017 X509_NAME_ENTRY *ne;
3018 int i, j, n;
3019 int cur = 0;
3020 const char *s;
3021 char tmp[128];
3022
3023 out->len = 0;
3024 for (i = 0; i < sk_X509_NAME_ENTRY_num(a->entries); i++) {
3025 if (pos < 0)
3026 j = (sk_X509_NAME_ENTRY_num(a->entries)-1) - i;
3027 else
3028 j = i;
3029
3030 ne = sk_X509_NAME_ENTRY_value(a->entries, j);
3031 n = OBJ_obj2nid(ne->object);
3032 if ((n == NID_undef) || ((s = OBJ_nid2sn(n)) == NULL)) {
3033 i2t_ASN1_OBJECT(tmp, sizeof(tmp), ne->object);
3034 s = tmp;
3035 }
3036
3037 if (chunk_strcasecmp(entry, s) != 0)
3038 continue;
3039
3040 if (pos < 0)
3041 cur--;
3042 else
3043 cur++;
3044
3045 if (cur != pos)
3046 continue;
3047
3048 if (ne->value->length > out->size)
3049 return -1;
3050
3051 memcpy(out->str, ne->value->data, ne->value->length);
3052 out->len = ne->value->length;
3053 return 1;
3054 }
3055
3056 return 0;
3057
3058}
3059
3060/* Extract and format full DN from a X509_NAME and copy result into a chunk
3061 * Returns 1 if dn entries exits, 0 if no dn entry found or -1 if output is not large enough.
3062 */
3063static int
3064ssl_sock_get_dn_oneline(X509_NAME *a, struct chunk *out)
3065{
3066 X509_NAME_ENTRY *ne;
3067 int i, n, ln;
3068 int l = 0;
3069 const char *s;
3070 char *p;
3071 char tmp[128];
3072
3073 out->len = 0;
3074 p = out->str;
3075 for (i = 0; i < sk_X509_NAME_ENTRY_num(a->entries); i++) {
3076 ne = sk_X509_NAME_ENTRY_value(a->entries, i);
3077 n = OBJ_obj2nid(ne->object);
3078 if ((n == NID_undef) || ((s = OBJ_nid2sn(n)) == NULL)) {
3079 i2t_ASN1_OBJECT(tmp, sizeof(tmp), ne->object);
3080 s = tmp;
3081 }
3082 ln = strlen(s);
3083
3084 l += 1 + ln + 1 + ne->value->length;
3085 if (l > out->size)
3086 return -1;
3087 out->len = l;
3088
3089 *(p++)='/';
3090 memcpy(p, s, ln);
3091 p += ln;
3092 *(p++)='=';
3093 memcpy(p, ne->value->data, ne->value->length);
3094 p += ne->value->length;
3095 }
3096
3097 if (!out->len)
3098 return 0;
3099
3100 return 1;
3101}
3102
David Safb76832014-05-08 23:42:08 -04003103char *ssl_sock_get_version(struct connection *conn)
3104{
3105 if (!ssl_sock_is_ssl(conn))
3106 return NULL;
3107
3108 return (char *)SSL_get_version(conn->xprt_ctx);
3109}
3110
Emeric Brun0abf8362014-06-24 18:26:41 +02003111/* Extract peer certificate's common name into the chunk dest
3112 * Returns
3113 * the len of the extracted common name
3114 * or 0 if no CN found in DN
3115 * or -1 on error case (i.e. no peer certificate)
3116 */
3117int ssl_sock_get_remote_common_name(struct connection *conn, struct chunk *dest)
David Safb76832014-05-08 23:42:08 -04003118{
3119 X509 *crt = NULL;
3120 X509_NAME *name;
David Safb76832014-05-08 23:42:08 -04003121 const char find_cn[] = "CN";
3122 const struct chunk find_cn_chunk = {
3123 .str = (char *)&find_cn,
3124 .len = sizeof(find_cn)-1
3125 };
Emeric Brun0abf8362014-06-24 18:26:41 +02003126 int result = -1;
David Safb76832014-05-08 23:42:08 -04003127
3128 if (!ssl_sock_is_ssl(conn))
Emeric Brun0abf8362014-06-24 18:26:41 +02003129 goto out;
David Safb76832014-05-08 23:42:08 -04003130
3131 /* SSL_get_peer_certificate, it increase X509 * ref count */
3132 crt = SSL_get_peer_certificate(conn->xprt_ctx);
3133 if (!crt)
3134 goto out;
3135
3136 name = X509_get_subject_name(crt);
3137 if (!name)
3138 goto out;
David Safb76832014-05-08 23:42:08 -04003139
Emeric Brun0abf8362014-06-24 18:26:41 +02003140 result = ssl_sock_get_dn_entry(name, &find_cn_chunk, 1, dest);
3141out:
David Safb76832014-05-08 23:42:08 -04003142 if (crt)
3143 X509_free(crt);
3144
3145 return result;
3146}
3147
Dave McCowan328fb582014-07-30 10:39:13 -04003148/* returns 1 if client passed a certificate for this session, 0 if not */
3149int ssl_sock_get_cert_used_sess(struct connection *conn)
3150{
3151 X509 *crt = NULL;
3152
3153 if (!ssl_sock_is_ssl(conn))
3154 return 0;
3155
3156 /* SSL_get_peer_certificate, it increase X509 * ref count */
3157 crt = SSL_get_peer_certificate(conn->xprt_ctx);
3158 if (!crt)
3159 return 0;
3160
3161 X509_free(crt);
3162 return 1;
3163}
3164
3165/* returns 1 if client passed a certificate for this connection, 0 if not */
3166int ssl_sock_get_cert_used_conn(struct connection *conn)
David Safb76832014-05-08 23:42:08 -04003167{
3168 if (!ssl_sock_is_ssl(conn))
3169 return 0;
3170
3171 return SSL_SOCK_ST_FL_VERIFY_DONE & conn->xprt_st ? 1 : 0;
3172}
3173
3174/* returns result from SSL verify */
3175unsigned int ssl_sock_get_verify_result(struct connection *conn)
3176{
3177 if (!ssl_sock_is_ssl(conn))
3178 return (unsigned int)X509_V_ERR_APPLICATION_VERIFICATION;
3179
3180 return (unsigned int)SSL_get_verify_result(conn->xprt_ctx);
3181}
3182
Willy Tarreau7875d092012-09-10 08:20:03 +02003183/***** Below are some sample fetching functions for ACL/patterns *****/
3184
Emeric Brune64aef12012-09-21 13:15:06 +02003185/* boolean, returns true if client cert was present */
3186static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02003187smp_fetch_ssl_fc_has_crt(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brune64aef12012-09-21 13:15:06 +02003188{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003189 struct connection *conn;
3190
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02003191 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003192 if (!conn || conn->xprt != &ssl_sock)
Emeric Brune64aef12012-09-21 13:15:06 +02003193 return 0;
3194
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003195 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brune64aef12012-09-21 13:15:06 +02003196 smp->flags |= SMP_F_MAY_CHANGE;
3197 return 0;
3198 }
3199
3200 smp->flags = 0;
3201 smp->type = SMP_T_BOOL;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003202 smp->data.uint = SSL_SOCK_ST_FL_VERIFY_DONE & conn->xprt_st ? 1 : 0;
Emeric Brune64aef12012-09-21 13:15:06 +02003203
3204 return 1;
3205}
3206
Emeric Brun43e79582014-10-29 19:03:26 +01003207/* binary, returns a certificate in a binary chunk (der/raw).
3208 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
3209 * should be use.
3210 */
3211static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02003212smp_fetch_ssl_x_der(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun43e79582014-10-29 19:03:26 +01003213{
3214 int cert_peer = (kw[4] == 'c') ? 1 : 0;
3215 X509 *crt = NULL;
3216 int ret = 0;
3217 struct chunk *smp_trash;
3218 struct connection *conn;
3219
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02003220 conn = objt_conn(smp->sess->origin);
Emeric Brun43e79582014-10-29 19:03:26 +01003221 if (!conn || conn->xprt != &ssl_sock)
3222 return 0;
3223
3224 if (!(conn->flags & CO_FL_CONNECTED)) {
3225 smp->flags |= SMP_F_MAY_CHANGE;
3226 return 0;
3227 }
3228
3229 if (cert_peer)
3230 crt = SSL_get_peer_certificate(conn->xprt_ctx);
3231 else
3232 crt = SSL_get_certificate(conn->xprt_ctx);
3233
3234 if (!crt)
3235 goto out;
3236
3237 smp_trash = get_trash_chunk();
3238 if (ssl_sock_crt2der(crt, smp_trash) <= 0)
3239 goto out;
3240
3241 smp->data.str = *smp_trash;
3242 smp->type = SMP_T_BIN;
3243 ret = 1;
3244out:
3245 /* SSL_get_peer_certificate, it increase X509 * ref count */
3246 if (cert_peer && crt)
3247 X509_free(crt);
3248 return ret;
3249}
3250
Emeric Brunba841a12014-04-30 17:05:08 +02003251/* binary, returns serial of certificate in a binary chunk.
3252 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
3253 * should be use.
3254 */
Willy Tarreau8d598402012-10-22 17:58:39 +02003255static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02003256smp_fetch_ssl_x_serial(const struct arg *args, struct sample *smp, const char *kw, void *private)
Willy Tarreau8d598402012-10-22 17:58:39 +02003257{
Emeric Brunba841a12014-04-30 17:05:08 +02003258 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Willy Tarreau8d598402012-10-22 17:58:39 +02003259 X509 *crt = NULL;
3260 int ret = 0;
3261 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003262 struct connection *conn;
3263
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02003264 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003265 if (!conn || conn->xprt != &ssl_sock)
Willy Tarreau8d598402012-10-22 17:58:39 +02003266 return 0;
3267
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003268 if (!(conn->flags & CO_FL_CONNECTED)) {
Willy Tarreau8d598402012-10-22 17:58:39 +02003269 smp->flags |= SMP_F_MAY_CHANGE;
3270 return 0;
3271 }
3272
Emeric Brunba841a12014-04-30 17:05:08 +02003273 if (cert_peer)
3274 crt = SSL_get_peer_certificate(conn->xprt_ctx);
3275 else
3276 crt = SSL_get_certificate(conn->xprt_ctx);
3277
Willy Tarreau8d598402012-10-22 17:58:39 +02003278 if (!crt)
3279 goto out;
3280
Willy Tarreau47ca5452012-12-23 20:22:19 +01003281 smp_trash = get_trash_chunk();
Willy Tarreau8d598402012-10-22 17:58:39 +02003282 if (ssl_sock_get_serial(crt, smp_trash) <= 0)
3283 goto out;
3284
3285 smp->data.str = *smp_trash;
3286 smp->type = SMP_T_BIN;
3287 ret = 1;
3288out:
Emeric Brunba841a12014-04-30 17:05:08 +02003289 /* SSL_get_peer_certificate, it increase X509 * ref count */
3290 if (cert_peer && crt)
Willy Tarreau8d598402012-10-22 17:58:39 +02003291 X509_free(crt);
3292 return ret;
3293}
Emeric Brune64aef12012-09-21 13:15:06 +02003294
Emeric Brunba841a12014-04-30 17:05:08 +02003295/* binary, returns the client certificate's SHA-1 fingerprint (SHA-1 hash of DER-encoded certificate) in a binary chunk.
3296 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
3297 * should be use.
3298 */
James Votha051b4a2013-05-14 20:37:59 +02003299static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02003300smp_fetch_ssl_x_sha1(const struct arg *args, struct sample *smp, const char *kw, void *private)
James Votha051b4a2013-05-14 20:37:59 +02003301{
Emeric Brunba841a12014-04-30 17:05:08 +02003302 int cert_peer = (kw[4] == 'c') ? 1 : 0;
James Votha051b4a2013-05-14 20:37:59 +02003303 X509 *crt = NULL;
3304 const EVP_MD *digest;
3305 int ret = 0;
3306 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003307 struct connection *conn;
James Votha051b4a2013-05-14 20:37:59 +02003308
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02003309 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003310 if (!conn || conn->xprt != &ssl_sock)
3311 return 0;
3312
3313 if (!(conn->flags & CO_FL_CONNECTED)) {
James Votha051b4a2013-05-14 20:37:59 +02003314 smp->flags |= SMP_F_MAY_CHANGE;
3315 return 0;
3316 }
3317
Emeric Brunba841a12014-04-30 17:05:08 +02003318 if (cert_peer)
3319 crt = SSL_get_peer_certificate(conn->xprt_ctx);
3320 else
3321 crt = SSL_get_certificate(conn->xprt_ctx);
James Votha051b4a2013-05-14 20:37:59 +02003322 if (!crt)
3323 goto out;
3324
3325 smp_trash = get_trash_chunk();
3326 digest = EVP_sha1();
3327 X509_digest(crt, digest, (unsigned char *)smp_trash->str, (unsigned int *)&smp_trash->len);
3328
3329 smp->data.str = *smp_trash;
3330 smp->type = SMP_T_BIN;
3331 ret = 1;
3332out:
Emeric Brunba841a12014-04-30 17:05:08 +02003333 /* SSL_get_peer_certificate, it increase X509 * ref count */
3334 if (cert_peer && crt)
James Votha051b4a2013-05-14 20:37:59 +02003335 X509_free(crt);
3336 return ret;
3337}
3338
Emeric Brunba841a12014-04-30 17:05:08 +02003339/* string, returns certificate's notafter date in ASN1_UTCTIME format.
3340 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
3341 * should be use.
3342 */
Emeric Brunce5ad802012-10-22 14:11:22 +02003343static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02003344smp_fetch_ssl_x_notafter(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brunce5ad802012-10-22 14:11:22 +02003345{
Emeric Brunba841a12014-04-30 17:05:08 +02003346 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brunce5ad802012-10-22 14:11:22 +02003347 X509 *crt = NULL;
3348 int ret = 0;
3349 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003350 struct connection *conn;
Emeric Brunce5ad802012-10-22 14:11:22 +02003351
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02003352 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003353 if (!conn || conn->xprt != &ssl_sock)
3354 return 0;
3355
3356 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunce5ad802012-10-22 14:11:22 +02003357 smp->flags |= SMP_F_MAY_CHANGE;
3358 return 0;
3359 }
3360
Emeric Brunba841a12014-04-30 17:05:08 +02003361 if (cert_peer)
3362 crt = SSL_get_peer_certificate(conn->xprt_ctx);
3363 else
3364 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brunce5ad802012-10-22 14:11:22 +02003365 if (!crt)
3366 goto out;
3367
Willy Tarreau47ca5452012-12-23 20:22:19 +01003368 smp_trash = get_trash_chunk();
Emeric Brunce5ad802012-10-22 14:11:22 +02003369 if (ssl_sock_get_time(X509_get_notAfter(crt), smp_trash) <= 0)
3370 goto out;
3371
3372 smp->data.str = *smp_trash;
3373 smp->type = SMP_T_STR;
3374 ret = 1;
3375out:
Emeric Brunba841a12014-04-30 17:05:08 +02003376 /* SSL_get_peer_certificate, it increase X509 * ref count */
3377 if (cert_peer && crt)
Emeric Brunce5ad802012-10-22 14:11:22 +02003378 X509_free(crt);
3379 return ret;
3380}
3381
Emeric Brunba841a12014-04-30 17:05:08 +02003382/* string, returns a string of a formatted full dn \C=..\O=..\OU=.. \CN=.. of certificate's issuer
3383 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
3384 * should be use.
3385 */
Emeric Brun87855892012-10-17 17:39:35 +02003386static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02003387smp_fetch_ssl_x_i_dn(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun87855892012-10-17 17:39:35 +02003388{
Emeric Brunba841a12014-04-30 17:05:08 +02003389 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brun87855892012-10-17 17:39:35 +02003390 X509 *crt = NULL;
3391 X509_NAME *name;
3392 int ret = 0;
3393 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003394 struct connection *conn;
Emeric Brun87855892012-10-17 17:39:35 +02003395
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02003396 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003397 if (!conn || conn->xprt != &ssl_sock)
3398 return 0;
3399
3400 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun87855892012-10-17 17:39:35 +02003401 smp->flags |= SMP_F_MAY_CHANGE;
3402 return 0;
3403 }
3404
Emeric Brunba841a12014-04-30 17:05:08 +02003405 if (cert_peer)
3406 crt = SSL_get_peer_certificate(conn->xprt_ctx);
3407 else
3408 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brun87855892012-10-17 17:39:35 +02003409 if (!crt)
3410 goto out;
3411
3412 name = X509_get_issuer_name(crt);
3413 if (!name)
3414 goto out;
3415
Willy Tarreau47ca5452012-12-23 20:22:19 +01003416 smp_trash = get_trash_chunk();
Emeric Brun87855892012-10-17 17:39:35 +02003417 if (args && args[0].type == ARGT_STR) {
3418 int pos = 1;
3419
3420 if (args[1].type == ARGT_SINT)
3421 pos = args[1].data.sint;
3422 else if (args[1].type == ARGT_UINT)
3423 pos =(int)args[1].data.uint;
3424
3425 if (ssl_sock_get_dn_entry(name, &args[0].data.str, pos, smp_trash) <= 0)
3426 goto out;
3427 }
3428 else if (ssl_sock_get_dn_oneline(name, smp_trash) <= 0)
3429 goto out;
3430
3431 smp->type = SMP_T_STR;
3432 smp->data.str = *smp_trash;
3433 ret = 1;
3434out:
Emeric Brunba841a12014-04-30 17:05:08 +02003435 /* SSL_get_peer_certificate, it increase X509 * ref count */
3436 if (cert_peer && crt)
Emeric Brun87855892012-10-17 17:39:35 +02003437 X509_free(crt);
3438 return ret;
3439}
3440
Emeric Brunba841a12014-04-30 17:05:08 +02003441/* string, returns notbefore date in ASN1_UTCTIME format.
3442 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
3443 * should be use.
3444 */
Emeric Brunce5ad802012-10-22 14:11:22 +02003445static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02003446smp_fetch_ssl_x_notbefore(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brunce5ad802012-10-22 14:11:22 +02003447{
Emeric Brunba841a12014-04-30 17:05:08 +02003448 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brunce5ad802012-10-22 14:11:22 +02003449 X509 *crt = NULL;
3450 int ret = 0;
3451 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003452 struct connection *conn;
3453
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02003454 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003455 if (!conn || conn->xprt != &ssl_sock)
Emeric Brunce5ad802012-10-22 14:11:22 +02003456 return 0;
3457
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003458 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunce5ad802012-10-22 14:11:22 +02003459 smp->flags |= SMP_F_MAY_CHANGE;
3460 return 0;
3461 }
3462
Emeric Brunba841a12014-04-30 17:05:08 +02003463 if (cert_peer)
3464 crt = SSL_get_peer_certificate(conn->xprt_ctx);
3465 else
3466 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brunce5ad802012-10-22 14:11:22 +02003467 if (!crt)
3468 goto out;
3469
Willy Tarreau47ca5452012-12-23 20:22:19 +01003470 smp_trash = get_trash_chunk();
Emeric Brunce5ad802012-10-22 14:11:22 +02003471 if (ssl_sock_get_time(X509_get_notBefore(crt), smp_trash) <= 0)
3472 goto out;
3473
3474 smp->data.str = *smp_trash;
3475 smp->type = SMP_T_STR;
3476 ret = 1;
3477out:
Emeric Brunba841a12014-04-30 17:05:08 +02003478 /* SSL_get_peer_certificate, it increase X509 * ref count */
3479 if (cert_peer && crt)
Emeric Brunce5ad802012-10-22 14:11:22 +02003480 X509_free(crt);
3481 return ret;
3482}
3483
Emeric Brunba841a12014-04-30 17:05:08 +02003484/* string, returns a string of a formatted full dn \C=..\O=..\OU=.. \CN=.. of certificate's subject
3485 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
3486 * should be use.
3487 */
Emeric Brun87855892012-10-17 17:39:35 +02003488static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02003489smp_fetch_ssl_x_s_dn(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun87855892012-10-17 17:39:35 +02003490{
Emeric Brunba841a12014-04-30 17:05:08 +02003491 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brun87855892012-10-17 17:39:35 +02003492 X509 *crt = NULL;
3493 X509_NAME *name;
3494 int ret = 0;
3495 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003496 struct connection *conn;
Emeric Brun87855892012-10-17 17:39:35 +02003497
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02003498 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003499 if (!conn || conn->xprt != &ssl_sock)
3500 return 0;
3501
3502 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun87855892012-10-17 17:39:35 +02003503 smp->flags |= SMP_F_MAY_CHANGE;
3504 return 0;
3505 }
3506
Emeric Brunba841a12014-04-30 17:05:08 +02003507 if (cert_peer)
3508 crt = SSL_get_peer_certificate(conn->xprt_ctx);
3509 else
3510 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brun87855892012-10-17 17:39:35 +02003511 if (!crt)
3512 goto out;
3513
3514 name = X509_get_subject_name(crt);
3515 if (!name)
3516 goto out;
3517
Willy Tarreau47ca5452012-12-23 20:22:19 +01003518 smp_trash = get_trash_chunk();
Emeric Brun87855892012-10-17 17:39:35 +02003519 if (args && args[0].type == ARGT_STR) {
3520 int pos = 1;
3521
3522 if (args[1].type == ARGT_SINT)
3523 pos = args[1].data.sint;
3524 else if (args[1].type == ARGT_UINT)
3525 pos =(int)args[1].data.uint;
3526
3527 if (ssl_sock_get_dn_entry(name, &args[0].data.str, pos, smp_trash) <= 0)
3528 goto out;
3529 }
3530 else if (ssl_sock_get_dn_oneline(name, smp_trash) <= 0)
3531 goto out;
3532
3533 smp->type = SMP_T_STR;
3534 smp->data.str = *smp_trash;
3535 ret = 1;
3536out:
Emeric Brunba841a12014-04-30 17:05:08 +02003537 /* SSL_get_peer_certificate, it increase X509 * ref count */
3538 if (cert_peer && crt)
Emeric Brun87855892012-10-17 17:39:35 +02003539 X509_free(crt);
3540 return ret;
3541}
Emeric Brun9143d372012-12-20 15:44:16 +01003542
3543/* integer, returns true if current session use a client certificate */
3544static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02003545smp_fetch_ssl_c_used(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun9143d372012-12-20 15:44:16 +01003546{
3547 X509 *crt;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003548 struct connection *conn;
Emeric Brun9143d372012-12-20 15:44:16 +01003549
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02003550 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003551 if (!conn || conn->xprt != &ssl_sock)
3552 return 0;
3553
3554 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun9143d372012-12-20 15:44:16 +01003555 smp->flags |= SMP_F_MAY_CHANGE;
3556 return 0;
3557 }
3558
3559 /* SSL_get_peer_certificate returns a ptr on allocated X509 struct */
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003560 crt = SSL_get_peer_certificate(conn->xprt_ctx);
Emeric Brun9143d372012-12-20 15:44:16 +01003561 if (crt) {
3562 X509_free(crt);
3563 }
3564
3565 smp->type = SMP_T_BOOL;
3566 smp->data.uint = (crt != NULL);
3567 return 1;
3568}
3569
Emeric Brunba841a12014-04-30 17:05:08 +02003570/* integer, returns the certificate version
3571 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
3572 * should be use.
3573 */
Emeric Bruna7359fd2012-10-17 15:03:11 +02003574static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02003575smp_fetch_ssl_x_version(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Bruna7359fd2012-10-17 15:03:11 +02003576{
Emeric Brunba841a12014-04-30 17:05:08 +02003577 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Bruna7359fd2012-10-17 15:03:11 +02003578 X509 *crt;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003579 struct connection *conn;
3580
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02003581 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003582 if (!conn || conn->xprt != &ssl_sock)
Emeric Bruna7359fd2012-10-17 15:03:11 +02003583 return 0;
3584
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003585 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Bruna7359fd2012-10-17 15:03:11 +02003586 smp->flags |= SMP_F_MAY_CHANGE;
3587 return 0;
3588 }
3589
Emeric Brunba841a12014-04-30 17:05:08 +02003590 if (cert_peer)
3591 crt = SSL_get_peer_certificate(conn->xprt_ctx);
3592 else
3593 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Bruna7359fd2012-10-17 15:03:11 +02003594 if (!crt)
3595 return 0;
3596
3597 smp->data.uint = (unsigned int)(1 + X509_get_version(crt));
Emeric Brunba841a12014-04-30 17:05:08 +02003598 /* SSL_get_peer_certificate increase X509 * ref count */
3599 if (cert_peer)
3600 X509_free(crt);
Emeric Bruna7359fd2012-10-17 15:03:11 +02003601 smp->type = SMP_T_UINT;
3602
3603 return 1;
3604}
3605
Emeric Brunba841a12014-04-30 17:05:08 +02003606/* string, returns the certificate's signature algorithm.
3607 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
3608 * should be use.
3609 */
Emeric Brun7f56e742012-10-19 18:15:40 +02003610static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02003611smp_fetch_ssl_x_sig_alg(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun7f56e742012-10-19 18:15:40 +02003612{
Emeric Brunba841a12014-04-30 17:05:08 +02003613 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brun7f56e742012-10-19 18:15:40 +02003614 X509 *crt;
3615 int nid;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003616 struct connection *conn;
Emeric Brun7f56e742012-10-19 18:15:40 +02003617
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02003618 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003619 if (!conn || conn->xprt != &ssl_sock)
3620 return 0;
3621
3622 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun7f56e742012-10-19 18:15:40 +02003623 smp->flags |= SMP_F_MAY_CHANGE;
3624 return 0;
3625 }
3626
Emeric Brunba841a12014-04-30 17:05:08 +02003627 if (cert_peer)
3628 crt = SSL_get_peer_certificate(conn->xprt_ctx);
3629 else
3630 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brun7f56e742012-10-19 18:15:40 +02003631 if (!crt)
3632 return 0;
3633
3634 nid = OBJ_obj2nid((ASN1_OBJECT *)(crt->cert_info->signature->algorithm));
3635
3636 smp->data.str.str = (char *)OBJ_nid2sn(nid);
Emeric Brun9bf3ba22013-10-07 14:31:44 +02003637 if (!smp->data.str.str) {
Emeric Brunba841a12014-04-30 17:05:08 +02003638 /* SSL_get_peer_certificate increase X509 * ref count */
3639 if (cert_peer)
3640 X509_free(crt);
Emeric Brun7f56e742012-10-19 18:15:40 +02003641 return 0;
Emeric Brun9bf3ba22013-10-07 14:31:44 +02003642 }
Emeric Brun7f56e742012-10-19 18:15:40 +02003643
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01003644 smp->type = SMP_T_STR;
3645 smp->flags |= SMP_F_CONST;
Emeric Brun7f56e742012-10-19 18:15:40 +02003646 smp->data.str.len = strlen(smp->data.str.str);
Emeric Brunba841a12014-04-30 17:05:08 +02003647 /* SSL_get_peer_certificate increase X509 * ref count */
3648 if (cert_peer)
3649 X509_free(crt);
Emeric Brun7f56e742012-10-19 18:15:40 +02003650
3651 return 1;
3652}
3653
Emeric Brunba841a12014-04-30 17:05:08 +02003654/* string, returns the certificate's key algorithm.
3655 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
3656 * should be use.
3657 */
Emeric Brun521a0112012-10-22 12:22:55 +02003658static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02003659smp_fetch_ssl_x_key_alg(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun521a0112012-10-22 12:22:55 +02003660{
Emeric Brunba841a12014-04-30 17:05:08 +02003661 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brun521a0112012-10-22 12:22:55 +02003662 X509 *crt;
3663 int nid;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003664 struct connection *conn;
Emeric Brun521a0112012-10-22 12:22:55 +02003665
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02003666 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003667 if (!conn || conn->xprt != &ssl_sock)
3668 return 0;
3669
3670 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun521a0112012-10-22 12:22:55 +02003671 smp->flags |= SMP_F_MAY_CHANGE;
3672 return 0;
3673 }
3674
Emeric Brunba841a12014-04-30 17:05:08 +02003675 if (cert_peer)
3676 crt = SSL_get_peer_certificate(conn->xprt_ctx);
3677 else
3678 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brun521a0112012-10-22 12:22:55 +02003679 if (!crt)
3680 return 0;
3681
3682 nid = OBJ_obj2nid((ASN1_OBJECT *)(crt->cert_info->key->algor->algorithm));
3683
3684 smp->data.str.str = (char *)OBJ_nid2sn(nid);
Emeric Brun9bf3ba22013-10-07 14:31:44 +02003685 if (!smp->data.str.str) {
Emeric Brunba841a12014-04-30 17:05:08 +02003686 /* SSL_get_peer_certificate increase X509 * ref count */
3687 if (cert_peer)
3688 X509_free(crt);
Emeric Brun521a0112012-10-22 12:22:55 +02003689 return 0;
Emeric Brun9bf3ba22013-10-07 14:31:44 +02003690 }
Emeric Brun521a0112012-10-22 12:22:55 +02003691
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01003692 smp->type = SMP_T_STR;
3693 smp->flags |= SMP_F_CONST;
Emeric Brun521a0112012-10-22 12:22:55 +02003694 smp->data.str.len = strlen(smp->data.str.str);
Emeric Brunba841a12014-04-30 17:05:08 +02003695 if (cert_peer)
3696 X509_free(crt);
Emeric Brun521a0112012-10-22 12:22:55 +02003697
3698 return 1;
3699}
3700
Emeric Brun645ae792014-04-30 14:21:06 +02003701/* boolean, returns true if front conn. transport layer is SSL.
3702 * This function is also usable on backend conn if the fetch keyword 5th
3703 * char is 'b'.
3704 */
Willy Tarreau7875d092012-09-10 08:20:03 +02003705static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02003706smp_fetch_ssl_fc(const struct arg *args, struct sample *smp, const char *kw, void *private)
Willy Tarreau7875d092012-09-10 08:20:03 +02003707{
Emeric Brun645ae792014-04-30 14:21:06 +02003708 int back_conn = (kw[4] == 'b') ? 1 : 0;
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02003709 struct connection *conn = objt_conn(smp->strm->si[back_conn].end);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003710
Willy Tarreau7875d092012-09-10 08:20:03 +02003711 smp->type = SMP_T_BOOL;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003712 smp->data.uint = (conn && conn->xprt == &ssl_sock);
Willy Tarreau7875d092012-09-10 08:20:03 +02003713 return 1;
3714}
3715
Emeric Brun2525b6b2012-10-18 15:59:43 +02003716/* boolean, returns true if client present a SNI */
Willy Tarreau7875d092012-09-10 08:20:03 +02003717static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02003718smp_fetch_ssl_fc_has_sni(const struct arg *args, struct sample *smp, const char *kw, void *private)
Willy Tarreau7875d092012-09-10 08:20:03 +02003719{
3720#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02003721 struct connection *conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003722
Willy Tarreau7875d092012-09-10 08:20:03 +02003723 smp->type = SMP_T_BOOL;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003724 smp->data.uint = (conn && conn->xprt == &ssl_sock) &&
3725 conn->xprt_ctx &&
3726 SSL_get_servername(conn->xprt_ctx, TLSEXT_NAMETYPE_host_name) != NULL;
Willy Tarreau7875d092012-09-10 08:20:03 +02003727 return 1;
3728#else
3729 return 0;
3730#endif
3731}
3732
Nenad Merdanovic26ea8222015-05-18 02:28:57 +02003733/* boolean, returns true if client session has been resumed */
3734static int
3735smp_fetch_ssl_fc_is_resumed(const struct arg *args, struct sample *smp, const char *kw, void *private)
3736{
3737 struct connection *conn = objt_conn(smp->sess->origin);
3738
3739 smp->type = SMP_T_BOOL;
3740 smp->data.uint = (conn && conn->xprt == &ssl_sock) &&
3741 conn->xprt_ctx &&
3742 SSL_session_reused(conn->xprt_ctx);
3743 return 1;
3744}
3745
Emeric Brun645ae792014-04-30 14:21:06 +02003746/* string, returns the used cipher if front conn. transport layer is SSL.
3747 * This function is also usable on backend conn if the fetch keyword 5th
3748 * char is 'b'.
3749 */
Emeric Brun589fcad2012-10-16 14:13:26 +02003750static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02003751smp_fetch_ssl_fc_cipher(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun589fcad2012-10-16 14:13:26 +02003752{
Emeric Brun645ae792014-04-30 14:21:06 +02003753 int back_conn = (kw[4] == 'b') ? 1 : 0;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003754 struct connection *conn;
3755
Emeric Brun589fcad2012-10-16 14:13:26 +02003756 smp->flags = 0;
3757
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02003758 conn = objt_conn(smp->strm->si[back_conn].end);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003759 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
Emeric Brun589fcad2012-10-16 14:13:26 +02003760 return 0;
3761
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003762 smp->data.str.str = (char *)SSL_get_cipher_name(conn->xprt_ctx);
Emeric Brun589fcad2012-10-16 14:13:26 +02003763 if (!smp->data.str.str)
3764 return 0;
3765
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01003766 smp->type = SMP_T_STR;
3767 smp->flags |= SMP_F_CONST;
Emeric Brun589fcad2012-10-16 14:13:26 +02003768 smp->data.str.len = strlen(smp->data.str.str);
3769
3770 return 1;
3771}
3772
Emeric Brun645ae792014-04-30 14:21:06 +02003773/* integer, returns the algoritm's keysize if front conn. transport layer
3774 * is SSL.
3775 * This function is also usable on backend conn if the fetch keyword 5th
3776 * char is 'b'.
3777 */
Emeric Brun589fcad2012-10-16 14:13:26 +02003778static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02003779smp_fetch_ssl_fc_alg_keysize(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun589fcad2012-10-16 14:13:26 +02003780{
Emeric Brun645ae792014-04-30 14:21:06 +02003781 int back_conn = (kw[4] == 'b') ? 1 : 0;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003782 struct connection *conn;
3783
Emeric Brun589fcad2012-10-16 14:13:26 +02003784 smp->flags = 0;
3785
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02003786 conn = objt_conn(smp->strm->si[back_conn].end);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003787 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
Emeric Brun589fcad2012-10-16 14:13:26 +02003788 return 0;
3789
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003790 if (!SSL_get_cipher_bits(conn->xprt_ctx, (int *)&smp->data.uint))
3791 return 0;
3792
Emeric Brun589fcad2012-10-16 14:13:26 +02003793 smp->type = SMP_T_UINT;
3794
3795 return 1;
3796}
3797
Emeric Brun645ae792014-04-30 14:21:06 +02003798/* integer, returns the used keysize if front conn. transport layer is SSL.
3799 * This function is also usable on backend conn if the fetch keyword 5th
3800 * char is 'b'.
3801 */
Emeric Brun589fcad2012-10-16 14:13:26 +02003802static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02003803smp_fetch_ssl_fc_use_keysize(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun589fcad2012-10-16 14:13:26 +02003804{
Emeric Brun645ae792014-04-30 14:21:06 +02003805 int back_conn = (kw[4] == 'b') ? 1 : 0;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003806 struct connection *conn;
3807
Emeric Brun589fcad2012-10-16 14:13:26 +02003808 smp->flags = 0;
3809
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02003810 conn = objt_conn(smp->strm->si[back_conn].end);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003811 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
3812 return 0;
3813
3814 smp->data.uint = (unsigned int)SSL_get_cipher_bits(conn->xprt_ctx, NULL);
Emeric Brun589fcad2012-10-16 14:13:26 +02003815 if (!smp->data.uint)
3816 return 0;
3817
3818 smp->type = SMP_T_UINT;
3819
3820 return 1;
3821}
3822
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02003823#ifdef OPENSSL_NPN_NEGOTIATED
Willy Tarreau7875d092012-09-10 08:20:03 +02003824static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02003825smp_fetch_ssl_fc_npn(const struct arg *args, struct sample *smp, const char *kw, void *private)
Willy Tarreaua33c6542012-10-15 13:19:06 +02003826{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003827 struct connection *conn;
3828
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01003829 smp->flags = SMP_F_CONST;
3830 smp->type = SMP_T_STR;
Willy Tarreaua33c6542012-10-15 13:19:06 +02003831
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02003832 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003833 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
3834 return 0;
3835
Willy Tarreaua33c6542012-10-15 13:19:06 +02003836 smp->data.str.str = NULL;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003837 SSL_get0_next_proto_negotiated(conn->xprt_ctx,
Willy Tarreaua33c6542012-10-15 13:19:06 +02003838 (const unsigned char **)&smp->data.str.str, (unsigned *)&smp->data.str.len);
3839
3840 if (!smp->data.str.str)
3841 return 0;
3842
3843 return 1;
Willy Tarreaua33c6542012-10-15 13:19:06 +02003844}
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02003845#endif
Willy Tarreaua33c6542012-10-15 13:19:06 +02003846
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01003847#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Willy Tarreauab861d32013-04-02 02:30:41 +02003848static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02003849smp_fetch_ssl_fc_alpn(const struct arg *args, struct sample *smp, const char *kw, void *private)
Willy Tarreauab861d32013-04-02 02:30:41 +02003850{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003851 struct connection *conn;
3852
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01003853 smp->flags = SMP_F_CONST;
3854 smp->type = SMP_T_STR;
Willy Tarreauab861d32013-04-02 02:30:41 +02003855
Willy Tarreaue26bf052015-05-12 10:30:12 +02003856 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003857 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
Willy Tarreauab861d32013-04-02 02:30:41 +02003858 return 0;
3859
3860 smp->data.str.str = NULL;
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01003861 SSL_get0_alpn_selected(conn->xprt_ctx,
Willy Tarreauab861d32013-04-02 02:30:41 +02003862 (const unsigned char **)&smp->data.str.str, (unsigned *)&smp->data.str.len);
3863
3864 if (!smp->data.str.str)
3865 return 0;
3866
3867 return 1;
3868}
3869#endif
3870
Emeric Brun645ae792014-04-30 14:21:06 +02003871/* string, returns the used protocol if front conn. transport layer is SSL.
3872 * This function is also usable on backend conn if the fetch keyword 5th
3873 * char is 'b'.
3874 */
Willy Tarreaua33c6542012-10-15 13:19:06 +02003875static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02003876smp_fetch_ssl_fc_protocol(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun589fcad2012-10-16 14:13:26 +02003877{
Emeric Brun645ae792014-04-30 14:21:06 +02003878 int back_conn = (kw[4] == 'b') ? 1 : 0;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003879 struct connection *conn;
3880
Emeric Brun589fcad2012-10-16 14:13:26 +02003881 smp->flags = 0;
3882
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02003883 conn = objt_conn(smp->strm->si[back_conn].end);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003884 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
3885 return 0;
3886
3887 smp->data.str.str = (char *)SSL_get_version(conn->xprt_ctx);
Emeric Brun589fcad2012-10-16 14:13:26 +02003888 if (!smp->data.str.str)
3889 return 0;
3890
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01003891 smp->type = SMP_T_STR;
3892 smp->flags = SMP_F_CONST;
Emeric Brun589fcad2012-10-16 14:13:26 +02003893 smp->data.str.len = strlen(smp->data.str.str);
3894
3895 return 1;
3896}
3897
Willy Tarreau87b09662015-04-03 00:22:06 +02003898/* binary, returns the SSL stream id if front conn. transport layer is SSL.
Emeric Brun645ae792014-04-30 14:21:06 +02003899 * This function is also usable on backend conn if the fetch keyword 5th
3900 * char is 'b'.
3901 */
Emeric Brun589fcad2012-10-16 14:13:26 +02003902static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02003903smp_fetch_ssl_fc_session_id(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brunfe68f682012-10-16 14:59:28 +02003904{
3905#if OPENSSL_VERSION_NUMBER > 0x0090800fL
Emeric Brun645ae792014-04-30 14:21:06 +02003906 int back_conn = (kw[4] == 'b') ? 1 : 0;
Willy Tarreau192252e2015-04-04 01:47:55 +02003907 SSL_SESSION *ssl_sess;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003908 struct connection *conn;
Emeric Brunfe68f682012-10-16 14:59:28 +02003909
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01003910 smp->flags = SMP_F_CONST;
3911 smp->type = SMP_T_BIN;
Emeric Brunfe68f682012-10-16 14:59:28 +02003912
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02003913 conn = objt_conn(smp->strm->si[back_conn].end);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003914 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
3915 return 0;
3916
Willy Tarreau192252e2015-04-04 01:47:55 +02003917 ssl_sess = SSL_get_session(conn->xprt_ctx);
3918 if (!ssl_sess)
Emeric Brunfe68f682012-10-16 14:59:28 +02003919 return 0;
3920
Willy Tarreau192252e2015-04-04 01:47:55 +02003921 smp->data.str.str = (char *)SSL_SESSION_get_id(ssl_sess, (unsigned int *)&smp->data.str.len);
Emeric Brunfe68f682012-10-16 14:59:28 +02003922 if (!smp->data.str.str || !&smp->data.str.len)
3923 return 0;
3924
3925 return 1;
3926#else
3927 return 0;
3928#endif
3929}
3930
3931static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02003932smp_fetch_ssl_fc_sni(const struct arg *args, struct sample *smp, const char *kw, void *private)
Willy Tarreau7875d092012-09-10 08:20:03 +02003933{
3934#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003935 struct connection *conn;
3936
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01003937 smp->flags = SMP_F_CONST;
3938 smp->type = SMP_T_STR;
Willy Tarreau7875d092012-09-10 08:20:03 +02003939
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02003940 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003941 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
3942 return 0;
3943
3944 smp->data.str.str = (char *)SSL_get_servername(conn->xprt_ctx, TLSEXT_NAMETYPE_host_name);
Willy Tarreau3e394c92012-09-14 23:56:58 +02003945 if (!smp->data.str.str)
3946 return 0;
3947
Willy Tarreau7875d092012-09-10 08:20:03 +02003948 smp->data.str.len = strlen(smp->data.str.str);
3949 return 1;
3950#else
3951 return 0;
3952#endif
3953}
3954
David Sc1ad52e2014-04-08 18:48:47 -04003955static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02003956smp_fetch_ssl_fc_unique_id(const struct arg *args, struct sample *smp, const char *kw, void *private)
David Sc1ad52e2014-04-08 18:48:47 -04003957{
3958#if OPENSSL_VERSION_NUMBER > 0x0090800fL
Emeric Brun645ae792014-04-30 14:21:06 +02003959 int back_conn = (kw[4] == 'b') ? 1 : 0;
David Sc1ad52e2014-04-08 18:48:47 -04003960 struct connection *conn;
3961 int finished_len;
David Sc1ad52e2014-04-08 18:48:47 -04003962 struct chunk *finished_trash;
David Sc1ad52e2014-04-08 18:48:47 -04003963
3964 smp->flags = 0;
3965
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02003966 conn = objt_conn(smp->strm->si[back_conn].end);
David Sc1ad52e2014-04-08 18:48:47 -04003967 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
3968 return 0;
3969
3970 if (!(conn->flags & CO_FL_CONNECTED)) {
3971 smp->flags |= SMP_F_MAY_CHANGE;
3972 return 0;
3973 }
3974
3975 finished_trash = get_trash_chunk();
3976 if (!SSL_session_reused(conn->xprt_ctx))
3977 finished_len = SSL_get_peer_finished(conn->xprt_ctx, finished_trash->str, finished_trash->size);
3978 else
3979 finished_len = SSL_get_finished(conn->xprt_ctx, finished_trash->str, finished_trash->size);
3980
3981 if (!finished_len)
3982 return 0;
3983
Emeric Brunb73a9b02014-04-30 18:49:19 +02003984 finished_trash->len = finished_len;
3985 smp->data.str = *finished_trash;
3986 smp->type = SMP_T_BIN;
David Sc1ad52e2014-04-08 18:48:47 -04003987
3988 return 1;
3989#else
3990 return 0;
3991#endif
3992}
3993
Emeric Brun2525b6b2012-10-18 15:59:43 +02003994/* integer, returns the first verify error in CA chain of client certificate chain. */
Emeric Brunf282a812012-09-21 15:27:54 +02003995static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02003996smp_fetch_ssl_c_ca_err(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brunf282a812012-09-21 15:27:54 +02003997{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003998 struct connection *conn;
3999
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004000 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004001 if (!conn || conn->xprt != &ssl_sock)
4002 return 0;
4003
4004 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunf282a812012-09-21 15:27:54 +02004005 smp->flags = SMP_F_MAY_CHANGE;
4006 return 0;
4007 }
4008
4009 smp->type = SMP_T_UINT;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004010 smp->data.uint = (unsigned int)SSL_SOCK_ST_TO_CA_ERROR(conn->xprt_st);
Emeric Brunf282a812012-09-21 15:27:54 +02004011 smp->flags = 0;
4012
4013 return 1;
4014}
4015
Emeric Brun2525b6b2012-10-18 15:59:43 +02004016/* integer, returns the depth of the first verify error in CA chain of client certificate chain. */
Emeric Brunf282a812012-09-21 15:27:54 +02004017static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004018smp_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 +02004019{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004020 struct connection *conn;
4021
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004022 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004023 if (!conn || conn->xprt != &ssl_sock)
Emeric Brunf282a812012-09-21 15:27:54 +02004024 return 0;
4025
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004026 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunf282a812012-09-21 15:27:54 +02004027 smp->flags = SMP_F_MAY_CHANGE;
4028 return 0;
4029 }
4030
4031 smp->type = SMP_T_UINT;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004032 smp->data.uint = (unsigned int)SSL_SOCK_ST_TO_CAEDEPTH(conn->xprt_st);
Emeric Brunf282a812012-09-21 15:27:54 +02004033 smp->flags = 0;
4034
4035 return 1;
4036}
4037
Emeric Brun2525b6b2012-10-18 15:59:43 +02004038/* integer, returns the first verify error on client certificate */
Emeric Brunf282a812012-09-21 15:27:54 +02004039static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004040smp_fetch_ssl_c_err(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brunf282a812012-09-21 15:27:54 +02004041{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004042 struct connection *conn;
4043
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004044 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004045 if (!conn || conn->xprt != &ssl_sock)
4046 return 0;
4047
4048 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunf282a812012-09-21 15:27:54 +02004049 smp->flags = SMP_F_MAY_CHANGE;
4050 return 0;
4051 }
4052
4053 smp->type = SMP_T_UINT;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004054 smp->data.uint = (unsigned int)SSL_SOCK_ST_TO_CRTERROR(conn->xprt_st);
Emeric Brunf282a812012-09-21 15:27:54 +02004055 smp->flags = 0;
4056
4057 return 1;
4058}
4059
Emeric Brun2525b6b2012-10-18 15:59:43 +02004060/* integer, returns the verify result on client cert */
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02004061static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004062smp_fetch_ssl_c_verify(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02004063{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004064 struct connection *conn;
4065
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004066 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004067 if (!conn || conn->xprt != &ssl_sock)
4068 return 0;
4069
4070 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02004071 smp->flags = SMP_F_MAY_CHANGE;
4072 return 0;
4073 }
4074
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004075 if (!conn->xprt_ctx)
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02004076 return 0;
4077
4078 smp->type = SMP_T_UINT;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004079 smp->data.uint = (unsigned int)SSL_get_verify_result(conn->xprt_ctx);
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02004080 smp->flags = 0;
4081
4082 return 1;
4083}
4084
Emeric Brunfb510ea2012-10-05 12:00:26 +02004085/* parse the "ca-file" bind keyword */
4086static 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 +02004087{
4088 if (!*args[cur_arg + 1]) {
4089 if (err)
4090 memprintf(err, "'%s' : missing CAfile path", args[cur_arg]);
4091 return ERR_ALERT | ERR_FATAL;
4092 }
4093
Emeric Brunef42d922012-10-11 16:11:36 +02004094 if ((*args[cur_arg + 1] != '/') && global.ca_base)
4095 memprintf(&conf->ca_file, "%s/%s", global.ca_base, args[cur_arg + 1]);
4096 else
4097 memprintf(&conf->ca_file, "%s", args[cur_arg + 1]);
Emeric Brunc8e8d122012-10-02 18:42:10 +02004098
Emeric Brund94b3fe2012-09-20 18:23:56 +02004099 return 0;
4100}
4101
Willy Tarreau79eeafa2012-09-14 07:53:05 +02004102/* parse the "ciphers" bind keyword */
Willy Tarreau4348fad2012-09-20 16:48:07 +02004103static 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 +02004104{
4105 if (!*args[cur_arg + 1]) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02004106 memprintf(err, "'%s' : missing cipher suite", args[cur_arg]);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02004107 return ERR_ALERT | ERR_FATAL;
4108 }
4109
Emeric Brun76d88952012-10-05 15:47:31 +02004110 free(conf->ciphers);
Willy Tarreau4348fad2012-09-20 16:48:07 +02004111 conf->ciphers = strdup(args[cur_arg + 1]);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02004112 return 0;
4113}
4114
4115/* parse the "crt" bind keyword */
Willy Tarreau4348fad2012-09-20 16:48:07 +02004116static 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 +02004117{
Willy Tarreau38011032013-08-13 16:59:39 +02004118 char path[MAXPATHLEN];
Willy Tarreaub75d6922014-04-14 18:05:41 +02004119
Willy Tarreau79eeafa2012-09-14 07:53:05 +02004120 if (!*args[cur_arg + 1]) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02004121 memprintf(err, "'%s' : missing certificate location", args[cur_arg]);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02004122 return ERR_ALERT | ERR_FATAL;
4123 }
4124
Emeric Brunc8e8d122012-10-02 18:42:10 +02004125 if ((*args[cur_arg + 1] != '/' ) && global.crt_base) {
Willy Tarreau38011032013-08-13 16:59:39 +02004126 if ((strlen(global.crt_base) + 1 + strlen(args[cur_arg + 1]) + 1) > MAXPATHLEN) {
Emeric Brunc8e8d122012-10-02 18:42:10 +02004127 memprintf(err, "'%s' : path too long", args[cur_arg]);
4128 return ERR_ALERT | ERR_FATAL;
4129 }
Willy Tarreaub75d6922014-04-14 18:05:41 +02004130 snprintf(path, sizeof(path), "%s/%s", global.crt_base, args[cur_arg + 1]);
Emeric Brunc8e8d122012-10-02 18:42:10 +02004131 if (ssl_sock_load_cert(path, conf, px, err) > 0)
4132 return ERR_ALERT | ERR_FATAL;
4133
4134 return 0;
4135 }
4136
Willy Tarreau4348fad2012-09-20 16:48:07 +02004137 if (ssl_sock_load_cert(args[cur_arg + 1], conf, px, err) > 0)
Willy Tarreau79eeafa2012-09-14 07:53:05 +02004138 return ERR_ALERT | ERR_FATAL;
Emeric Brund94b3fe2012-09-20 18:23:56 +02004139
4140 return 0;
4141}
4142
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01004143/* parse the "crt-list" bind keyword */
4144static int bind_parse_crt_list(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
4145{
4146 if (!*args[cur_arg + 1]) {
4147 memprintf(err, "'%s' : missing certificate location", args[cur_arg]);
4148 return ERR_ALERT | ERR_FATAL;
4149 }
4150
Willy Tarreauad1731d2013-04-02 17:35:58 +02004151 if (ssl_sock_load_cert_list_file(args[cur_arg + 1], conf, px, err) > 0) {
4152 memprintf(err, "'%s' : %s", args[cur_arg], *err);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01004153 return ERR_ALERT | ERR_FATAL;
Willy Tarreauad1731d2013-04-02 17:35:58 +02004154 }
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01004155
4156 return 0;
4157}
4158
Emeric Brunfb510ea2012-10-05 12:00:26 +02004159/* parse the "crl-file" bind keyword */
4160static 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 +02004161{
Emeric Brun051cdab2012-10-02 19:25:50 +02004162#ifndef X509_V_FLAG_CRL_CHECK
4163 if (err)
4164 memprintf(err, "'%s' : library does not support CRL verify", args[cur_arg]);
4165 return ERR_ALERT | ERR_FATAL;
4166#else
Emeric Brund94b3fe2012-09-20 18:23:56 +02004167 if (!*args[cur_arg + 1]) {
4168 if (err)
4169 memprintf(err, "'%s' : missing CRLfile path", args[cur_arg]);
4170 return ERR_ALERT | ERR_FATAL;
4171 }
Emeric Brun2b58d042012-09-20 17:10:03 +02004172
Emeric Brunef42d922012-10-11 16:11:36 +02004173 if ((*args[cur_arg + 1] != '/') && global.ca_base)
4174 memprintf(&conf->crl_file, "%s/%s", global.ca_base, args[cur_arg + 1]);
4175 else
4176 memprintf(&conf->crl_file, "%s", args[cur_arg + 1]);
Emeric Brunc8e8d122012-10-02 18:42:10 +02004177
Emeric Brun2b58d042012-09-20 17:10:03 +02004178 return 0;
Emeric Brun051cdab2012-10-02 19:25:50 +02004179#endif
Emeric Brun2b58d042012-09-20 17:10:03 +02004180}
4181
4182/* parse the "ecdhe" bind keyword keywords */
4183static int bind_parse_ecdhe(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
4184{
4185#if OPENSSL_VERSION_NUMBER < 0x0090800fL
4186 if (err)
4187 memprintf(err, "'%s' : library does not support elliptic curve Diffie-Hellman (too old)", args[cur_arg]);
4188 return ERR_ALERT | ERR_FATAL;
4189#elif defined(OPENSSL_NO_ECDH)
4190 if (err)
4191 memprintf(err, "'%s' : library does not support elliptic curve Diffie-Hellman (disabled via OPENSSL_NO_ECDH)", args[cur_arg]);
4192 return ERR_ALERT | ERR_FATAL;
4193#else
4194 if (!*args[cur_arg + 1]) {
4195 if (err)
4196 memprintf(err, "'%s' : missing named curve", args[cur_arg]);
4197 return ERR_ALERT | ERR_FATAL;
4198 }
4199
4200 conf->ecdhe = strdup(args[cur_arg + 1]);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02004201
4202 return 0;
Emeric Brun2b58d042012-09-20 17:10:03 +02004203#endif
Willy Tarreau79eeafa2012-09-14 07:53:05 +02004204}
4205
Emeric Brun81c00f02012-09-21 14:31:21 +02004206/* parse the "crt_ignerr" and "ca_ignerr" bind keywords */
4207static int bind_parse_ignore_err(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
4208{
4209 int code;
4210 char *p = args[cur_arg + 1];
4211 unsigned long long *ignerr = &conf->crt_ignerr;
4212
4213 if (!*p) {
4214 if (err)
4215 memprintf(err, "'%s' : missing error IDs list", args[cur_arg]);
4216 return ERR_ALERT | ERR_FATAL;
4217 }
4218
4219 if (strcmp(args[cur_arg], "ca-ignore-err") == 0)
4220 ignerr = &conf->ca_ignerr;
4221
4222 if (strcmp(p, "all") == 0) {
4223 *ignerr = ~0ULL;
4224 return 0;
4225 }
4226
4227 while (p) {
4228 code = atoi(p);
4229 if ((code <= 0) || (code > 63)) {
4230 if (err)
4231 memprintf(err, "'%s' : ID '%d' out of range (1..63) in error IDs list '%s'",
4232 args[cur_arg], code, args[cur_arg + 1]);
4233 return ERR_ALERT | ERR_FATAL;
4234 }
4235 *ignerr |= 1ULL << code;
4236 p = strchr(p, ',');
4237 if (p)
4238 p++;
4239 }
4240
Emeric Brun2cb7ae52012-10-05 14:14:21 +02004241 return 0;
4242}
4243
4244/* parse the "force-sslv3" bind keyword */
4245static int bind_parse_force_sslv3(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
4246{
4247 conf->ssl_options |= BC_SSL_O_USE_SSLV3;
4248 return 0;
4249}
4250
4251/* parse the "force-tlsv10" bind keyword */
4252static int bind_parse_force_tlsv10(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
4253{
4254 conf->ssl_options |= BC_SSL_O_USE_TLSV10;
Emeric Brun2d0c4822012-10-02 13:45:20 +02004255 return 0;
4256}
4257
Emeric Brun2cb7ae52012-10-05 14:14:21 +02004258/* parse the "force-tlsv11" bind keyword */
4259static int bind_parse_force_tlsv11(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
4260{
4261#if SSL_OP_NO_TLSv1_1
4262 conf->ssl_options |= BC_SSL_O_USE_TLSV11;
4263 return 0;
4264#else
4265 if (err)
4266 memprintf(err, "'%s' : library does not support protocol TLSv1.1", args[cur_arg]);
4267 return ERR_ALERT | ERR_FATAL;
4268#endif
4269}
4270
4271/* parse the "force-tlsv12" bind keyword */
4272static int bind_parse_force_tlsv12(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
4273{
4274#if SSL_OP_NO_TLSv1_2
4275 conf->ssl_options |= BC_SSL_O_USE_TLSV12;
4276 return 0;
4277#else
4278 if (err)
4279 memprintf(err, "'%s' : library does not support protocol TLSv1.2", args[cur_arg]);
4280 return ERR_ALERT | ERR_FATAL;
4281#endif
4282}
4283
4284
Emeric Brun2d0c4822012-10-02 13:45:20 +02004285/* parse the "no-tls-tickets" bind keyword */
4286static int bind_parse_no_tls_tickets(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
4287{
Emeric Brun89675492012-10-05 13:48:26 +02004288 conf->ssl_options |= BC_SSL_O_NO_TLS_TICKETS;
Emeric Brun81c00f02012-09-21 14:31:21 +02004289 return 0;
4290}
4291
Emeric Brun2d0c4822012-10-02 13:45:20 +02004292
Emeric Brun9b3009b2012-10-05 11:55:06 +02004293/* parse the "no-sslv3" bind keyword */
4294static 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 +02004295{
Emeric Brun89675492012-10-05 13:48:26 +02004296 conf->ssl_options |= BC_SSL_O_NO_SSLV3;
Willy Tarreau79eeafa2012-09-14 07:53:05 +02004297 return 0;
4298}
4299
Emeric Brun9b3009b2012-10-05 11:55:06 +02004300/* parse the "no-tlsv10" bind keyword */
4301static 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 +02004302{
Emeric Brun89675492012-10-05 13:48:26 +02004303 conf->ssl_options |= BC_SSL_O_NO_TLSV10;
Emeric Brunc0ff4922012-09-28 19:37:02 +02004304 return 0;
4305}
4306
Emeric Brun9b3009b2012-10-05 11:55:06 +02004307/* parse the "no-tlsv11" bind keyword */
4308static 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 +02004309{
Emeric Brun89675492012-10-05 13:48:26 +02004310 conf->ssl_options |= BC_SSL_O_NO_TLSV11;
Emeric Brunc0ff4922012-09-28 19:37:02 +02004311 return 0;
4312}
4313
Emeric Brun9b3009b2012-10-05 11:55:06 +02004314/* parse the "no-tlsv12" bind keyword */
4315static 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 +02004316{
Emeric Brun89675492012-10-05 13:48:26 +02004317 conf->ssl_options |= BC_SSL_O_NO_TLSV12;
Willy Tarreau79eeafa2012-09-14 07:53:05 +02004318 return 0;
4319}
4320
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02004321/* parse the "npn" bind keyword */
4322static int bind_parse_npn(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
4323{
4324#ifdef OPENSSL_NPN_NEGOTIATED
4325 char *p1, *p2;
4326
4327 if (!*args[cur_arg + 1]) {
4328 memprintf(err, "'%s' : missing the comma-delimited NPN protocol suite", args[cur_arg]);
4329 return ERR_ALERT | ERR_FATAL;
4330 }
4331
4332 free(conf->npn_str);
4333
4334 /* the NPN string is built as a suite of (<len> <name>)* */
4335 conf->npn_len = strlen(args[cur_arg + 1]) + 1;
4336 conf->npn_str = calloc(1, conf->npn_len);
4337 memcpy(conf->npn_str + 1, args[cur_arg + 1], conf->npn_len);
4338
4339 /* replace commas with the name length */
4340 p1 = conf->npn_str;
4341 p2 = p1 + 1;
4342 while (1) {
4343 p2 = memchr(p1 + 1, ',', conf->npn_str + conf->npn_len - (p1 + 1));
4344 if (!p2)
4345 p2 = p1 + 1 + strlen(p1 + 1);
4346
4347 if (p2 - (p1 + 1) > 255) {
4348 *p2 = '\0';
4349 memprintf(err, "'%s' : NPN protocol name too long : '%s'", args[cur_arg], p1 + 1);
4350 return ERR_ALERT | ERR_FATAL;
4351 }
4352
4353 *p1 = p2 - (p1 + 1);
4354 p1 = p2;
4355
4356 if (!*p2)
4357 break;
4358
4359 *(p2++) = '\0';
4360 }
4361 return 0;
4362#else
4363 if (err)
4364 memprintf(err, "'%s' : library does not support TLS NPN extension", args[cur_arg]);
4365 return ERR_ALERT | ERR_FATAL;
4366#endif
4367}
4368
Willy Tarreauab861d32013-04-02 02:30:41 +02004369/* parse the "alpn" bind keyword */
4370static int bind_parse_alpn(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
4371{
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01004372#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Willy Tarreauab861d32013-04-02 02:30:41 +02004373 char *p1, *p2;
4374
4375 if (!*args[cur_arg + 1]) {
4376 memprintf(err, "'%s' : missing the comma-delimited ALPN protocol suite", args[cur_arg]);
4377 return ERR_ALERT | ERR_FATAL;
4378 }
4379
4380 free(conf->alpn_str);
4381
4382 /* the ALPN string is built as a suite of (<len> <name>)* */
4383 conf->alpn_len = strlen(args[cur_arg + 1]) + 1;
4384 conf->alpn_str = calloc(1, conf->alpn_len);
4385 memcpy(conf->alpn_str + 1, args[cur_arg + 1], conf->alpn_len);
4386
4387 /* replace commas with the name length */
4388 p1 = conf->alpn_str;
4389 p2 = p1 + 1;
4390 while (1) {
4391 p2 = memchr(p1 + 1, ',', conf->alpn_str + conf->alpn_len - (p1 + 1));
4392 if (!p2)
4393 p2 = p1 + 1 + strlen(p1 + 1);
4394
4395 if (p2 - (p1 + 1) > 255) {
4396 *p2 = '\0';
4397 memprintf(err, "'%s' : ALPN protocol name too long : '%s'", args[cur_arg], p1 + 1);
4398 return ERR_ALERT | ERR_FATAL;
4399 }
4400
4401 *p1 = p2 - (p1 + 1);
4402 p1 = p2;
4403
4404 if (!*p2)
4405 break;
4406
4407 *(p2++) = '\0';
4408 }
4409 return 0;
4410#else
4411 if (err)
4412 memprintf(err, "'%s' : library does not support TLS ALPN extension", args[cur_arg]);
4413 return ERR_ALERT | ERR_FATAL;
4414#endif
4415}
4416
Willy Tarreau79eeafa2012-09-14 07:53:05 +02004417/* parse the "ssl" bind keyword */
Willy Tarreau4348fad2012-09-20 16:48:07 +02004418static 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 +02004419{
Willy Tarreau81796be2012-09-22 19:11:47 +02004420 struct listener *l;
4421
Willy Tarreau4348fad2012-09-20 16:48:07 +02004422 conf->is_ssl = 1;
Emeric Brun76d88952012-10-05 15:47:31 +02004423
4424 if (global.listen_default_ciphers && !conf->ciphers)
4425 conf->ciphers = strdup(global.listen_default_ciphers);
Emeric Brun2c86cbf2014-10-30 15:56:50 +01004426 conf->ssl_options |= global.listen_default_ssloptions;
Emeric Brun76d88952012-10-05 15:47:31 +02004427
Willy Tarreau81796be2012-09-22 19:11:47 +02004428 list_for_each_entry(l, &conf->listeners, by_bind)
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02004429 l->xprt = &ssl_sock;
Willy Tarreau81796be2012-09-22 19:11:47 +02004430
Willy Tarreau79eeafa2012-09-14 07:53:05 +02004431 return 0;
4432}
4433
Emmanuel Hocdet65623372013-01-24 17:17:15 +01004434/* parse the "strict-sni" bind keyword */
4435static int bind_parse_strict_sni(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
4436{
4437 conf->strict_sni = 1;
4438 return 0;
Nenad Merdanovic05552d42015-02-27 19:56:49 +01004439}
4440
4441/* parse the "tls-ticket-keys" bind keyword */
4442static int bind_parse_tls_ticket_keys(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
4443{
4444#if (defined SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB && TLS_TICKETS_NO > 0)
4445 FILE *f;
4446 int i = 0;
4447 char thisline[LINESIZE];
Nenad Merdanovic146defa2015-05-09 08:46:00 +02004448 struct tls_keys_ref *keys_ref;
Nenad Merdanovic05552d42015-02-27 19:56:49 +01004449
4450 if (!*args[cur_arg + 1]) {
4451 if (err)
4452 memprintf(err, "'%s' : missing TLS ticket keys file path", args[cur_arg]);
4453 return ERR_ALERT | ERR_FATAL;
4454 }
4455
Nenad Merdanovic200b0fa2015-05-09 08:46:01 +02004456 keys_ref = tlskeys_ref_lookup(args[cur_arg + 1]);
4457 if(keys_ref) {
4458 conf->keys_ref = keys_ref;
4459 return 0;
4460 }
4461
Nenad Merdanovic146defa2015-05-09 08:46:00 +02004462 keys_ref = malloc(sizeof(struct tls_keys_ref));
4463 keys_ref->tlskeys = malloc(TLS_TICKETS_NO * sizeof(struct tls_sess_key));
Nenad Merdanovic05552d42015-02-27 19:56:49 +01004464
4465 if ((f = fopen(args[cur_arg + 1], "r")) == NULL) {
4466 if (err)
4467 memprintf(err, "'%s' : unable to load ssl tickets keys file", args[cur_arg+1]);
4468 return ERR_ALERT | ERR_FATAL;
4469 }
4470
Nenad Merdanovic146defa2015-05-09 08:46:00 +02004471 keys_ref->filename = strdup(args[cur_arg + 1]);
4472
Nenad Merdanovic05552d42015-02-27 19:56:49 +01004473 while (fgets(thisline, sizeof(thisline), f) != NULL) {
4474 int len = strlen(thisline);
4475 /* Strip newline characters from the end */
4476 if(thisline[len - 1] == '\n')
4477 thisline[--len] = 0;
4478
4479 if(thisline[len - 1] == '\r')
4480 thisline[--len] = 0;
4481
Nenad Merdanovic146defa2015-05-09 08:46:00 +02004482 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 +01004483 if (err)
4484 memprintf(err, "'%s' : unable to decode base64 key on line %d", args[cur_arg+1], i + 1);
4485 return ERR_ALERT | ERR_FATAL;
4486 }
4487 i++;
4488 }
4489
4490 if (i < TLS_TICKETS_NO) {
4491 if (err)
4492 memprintf(err, "'%s' : please supply at least %d keys in the tls-tickets-file", args[cur_arg+1], TLS_TICKETS_NO);
4493 return ERR_ALERT | ERR_FATAL;
4494 }
4495
4496 fclose(f);
4497
4498 /* Use penultimate key for encryption, handle when TLS_TICKETS_NO = 1 */
4499 i-=2;
Nenad Merdanovic146defa2015-05-09 08:46:00 +02004500 keys_ref->tls_ticket_enc_index = i < 0 ? 0 : i;
Nenad Merdanovic200b0fa2015-05-09 08:46:01 +02004501 keys_ref->unique_id = -1;
Nenad Merdanovic146defa2015-05-09 08:46:00 +02004502 conf->keys_ref = keys_ref;
Nenad Merdanovic05552d42015-02-27 19:56:49 +01004503
Nenad Merdanovic200b0fa2015-05-09 08:46:01 +02004504 LIST_ADD(&tlskeys_reference, &keys_ref->list);
4505
Nenad Merdanovic05552d42015-02-27 19:56:49 +01004506 return 0;
4507#else
4508 if (err)
4509 memprintf(err, "'%s' : TLS ticket callback extension not supported", args[cur_arg]);
4510 return ERR_ALERT | ERR_FATAL;
4511#endif /* SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB */
Emmanuel Hocdet65623372013-01-24 17:17:15 +01004512}
4513
Emeric Brund94b3fe2012-09-20 18:23:56 +02004514/* parse the "verify" bind keyword */
4515static int bind_parse_verify(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
4516{
4517 if (!*args[cur_arg + 1]) {
4518 if (err)
4519 memprintf(err, "'%s' : missing verify method", args[cur_arg]);
4520 return ERR_ALERT | ERR_FATAL;
4521 }
4522
4523 if (strcmp(args[cur_arg + 1], "none") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01004524 conf->verify = SSL_SOCK_VERIFY_NONE;
Emeric Brund94b3fe2012-09-20 18:23:56 +02004525 else if (strcmp(args[cur_arg + 1], "optional") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01004526 conf->verify = SSL_SOCK_VERIFY_OPTIONAL;
Emeric Brund94b3fe2012-09-20 18:23:56 +02004527 else if (strcmp(args[cur_arg + 1], "required") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01004528 conf->verify = SSL_SOCK_VERIFY_REQUIRED;
Emeric Brund94b3fe2012-09-20 18:23:56 +02004529 else {
4530 if (err)
4531 memprintf(err, "'%s' : unknown verify method '%s', only 'none', 'optional', and 'required' are supported\n",
4532 args[cur_arg], args[cur_arg + 1]);
4533 return ERR_ALERT | ERR_FATAL;
4534 }
4535
4536 return 0;
4537}
4538
Willy Tarreau92faadf2012-10-10 23:04:25 +02004539/************** "server" keywords ****************/
4540
Emeric Brunef42d922012-10-11 16:11:36 +02004541/* parse the "ca-file" server keyword */
4542static int srv_parse_ca_file(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4543{
4544 if (!*args[*cur_arg + 1]) {
4545 if (err)
4546 memprintf(err, "'%s' : missing CAfile path", args[*cur_arg]);
4547 return ERR_ALERT | ERR_FATAL;
4548 }
4549
4550 if ((*args[*cur_arg + 1] != '/') && global.ca_base)
4551 memprintf(&newsrv->ssl_ctx.ca_file, "%s/%s", global.ca_base, args[*cur_arg + 1]);
4552 else
4553 memprintf(&newsrv->ssl_ctx.ca_file, "%s", args[*cur_arg + 1]);
4554
4555 return 0;
4556}
4557
Willy Tarreau92faadf2012-10-10 23:04:25 +02004558/* parse the "check-ssl" server keyword */
4559static int srv_parse_check_ssl(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4560{
4561 newsrv->check.use_ssl = 1;
4562 if (global.connect_default_ciphers && !newsrv->ssl_ctx.ciphers)
4563 newsrv->ssl_ctx.ciphers = strdup(global.connect_default_ciphers);
Emeric Brun2c86cbf2014-10-30 15:56:50 +01004564 newsrv->ssl_ctx.options |= global.connect_default_ssloptions;
Willy Tarreau92faadf2012-10-10 23:04:25 +02004565 return 0;
4566}
4567
4568/* parse the "ciphers" server keyword */
4569static int srv_parse_ciphers(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4570{
4571 if (!*args[*cur_arg + 1]) {
4572 memprintf(err, "'%s' : missing cipher suite", args[*cur_arg]);
4573 return ERR_ALERT | ERR_FATAL;
4574 }
4575
4576 free(newsrv->ssl_ctx.ciphers);
4577 newsrv->ssl_ctx.ciphers = strdup(args[*cur_arg + 1]);
4578 return 0;
4579}
4580
Emeric Brunef42d922012-10-11 16:11:36 +02004581/* parse the "crl-file" server keyword */
4582static int srv_parse_crl_file(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4583{
4584#ifndef X509_V_FLAG_CRL_CHECK
4585 if (err)
4586 memprintf(err, "'%s' : library does not support CRL verify", args[*cur_arg]);
4587 return ERR_ALERT | ERR_FATAL;
4588#else
4589 if (!*args[*cur_arg + 1]) {
4590 if (err)
4591 memprintf(err, "'%s' : missing CRLfile path", args[*cur_arg]);
4592 return ERR_ALERT | ERR_FATAL;
4593 }
4594
4595 if ((*args[*cur_arg + 1] != '/') && global.ca_base)
4596 memprintf(&newsrv->ssl_ctx.crl_file, "%s/%s", global.ca_base, args[*cur_arg + 1]);
4597 else
4598 memprintf(&newsrv->ssl_ctx.crl_file, "%s", args[*cur_arg + 1]);
4599
4600 return 0;
4601#endif
4602}
4603
Emeric Bruna7aa3092012-10-26 12:58:00 +02004604/* parse the "crt" server keyword */
4605static int srv_parse_crt(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4606{
4607 if (!*args[*cur_arg + 1]) {
4608 if (err)
4609 memprintf(err, "'%s' : missing certificate file path", args[*cur_arg]);
4610 return ERR_ALERT | ERR_FATAL;
4611 }
4612
4613 if ((*args[*cur_arg + 1] != '/') && global.crt_base)
4614 memprintf(&newsrv->ssl_ctx.client_crt, "%s/%s", global.ca_base, args[*cur_arg + 1]);
4615 else
4616 memprintf(&newsrv->ssl_ctx.client_crt, "%s", args[*cur_arg + 1]);
4617
4618 return 0;
4619}
Emeric Brunef42d922012-10-11 16:11:36 +02004620
Willy Tarreau92faadf2012-10-10 23:04:25 +02004621/* parse the "force-sslv3" server keyword */
4622static int srv_parse_force_sslv3(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4623{
4624 newsrv->ssl_ctx.options |= SRV_SSL_O_USE_SSLV3;
4625 return 0;
4626}
4627
4628/* parse the "force-tlsv10" server keyword */
4629static int srv_parse_force_tlsv10(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4630{
4631 newsrv->ssl_ctx.options |= SRV_SSL_O_USE_TLSV10;
4632 return 0;
4633}
4634
4635/* parse the "force-tlsv11" server keyword */
4636static int srv_parse_force_tlsv11(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4637{
4638#if SSL_OP_NO_TLSv1_1
4639 newsrv->ssl_ctx.options |= SRV_SSL_O_USE_TLSV11;
4640 return 0;
4641#else
4642 if (err)
4643 memprintf(err, "'%s' : library does not support protocol TLSv1.1", args[*cur_arg]);
4644 return ERR_ALERT | ERR_FATAL;
4645#endif
4646}
4647
4648/* parse the "force-tlsv12" server keyword */
4649static int srv_parse_force_tlsv12(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4650{
4651#if SSL_OP_NO_TLSv1_2
4652 newsrv->ssl_ctx.options |= SRV_SSL_O_USE_TLSV12;
4653 return 0;
4654#else
4655 if (err)
4656 memprintf(err, "'%s' : library does not support protocol TLSv1.2", args[*cur_arg]);
4657 return ERR_ALERT | ERR_FATAL;
4658#endif
4659}
4660
Willy Tarreau2a3fb1c2015-02-05 16:47:07 +01004661/* parse the "no-ssl-reuse" server keyword */
4662static int srv_parse_no_ssl_reuse(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4663{
4664 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_REUSE;
4665 return 0;
4666}
4667
Willy Tarreau92faadf2012-10-10 23:04:25 +02004668/* parse the "no-sslv3" server keyword */
4669static int srv_parse_no_sslv3(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4670{
4671 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_SSLV3;
4672 return 0;
4673}
4674
4675/* parse the "no-tlsv10" server keyword */
4676static int srv_parse_no_tlsv10(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4677{
4678 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_TLSV10;
4679 return 0;
4680}
4681
4682/* parse the "no-tlsv11" server keyword */
4683static int srv_parse_no_tlsv11(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4684{
4685 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_TLSV11;
4686 return 0;
4687}
4688
4689/* parse the "no-tlsv12" server keyword */
4690static int srv_parse_no_tlsv12(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4691{
4692 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_TLSV12;
4693 return 0;
4694}
4695
Emeric Brunf9c5c472012-10-11 15:28:34 +02004696/* parse the "no-tls-tickets" server keyword */
4697static int srv_parse_no_tls_tickets(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4698{
4699 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_TLS_TICKETS;
4700 return 0;
4701}
David Safb76832014-05-08 23:42:08 -04004702/* parse the "send-proxy-v2-ssl" server keyword */
4703static int srv_parse_send_proxy_ssl(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4704{
4705 newsrv->pp_opts |= SRV_PP_V2;
4706 newsrv->pp_opts |= SRV_PP_V2_SSL;
4707 return 0;
4708}
4709
4710/* parse the "send-proxy-v2-ssl-cn" server keyword */
4711static int srv_parse_send_proxy_cn(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4712{
4713 newsrv->pp_opts |= SRV_PP_V2;
4714 newsrv->pp_opts |= SRV_PP_V2_SSL;
4715 newsrv->pp_opts |= SRV_PP_V2_SSL_CN;
4716 return 0;
4717}
Emeric Brunf9c5c472012-10-11 15:28:34 +02004718
Willy Tarreau92faadf2012-10-10 23:04:25 +02004719/* parse the "ssl" server keyword */
4720static int srv_parse_ssl(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4721{
4722 newsrv->use_ssl = 1;
4723 if (global.connect_default_ciphers && !newsrv->ssl_ctx.ciphers)
4724 newsrv->ssl_ctx.ciphers = strdup(global.connect_default_ciphers);
4725 return 0;
4726}
4727
Emeric Brunef42d922012-10-11 16:11:36 +02004728/* parse the "verify" server keyword */
4729static int srv_parse_verify(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4730{
4731 if (!*args[*cur_arg + 1]) {
4732 if (err)
4733 memprintf(err, "'%s' : missing verify method", args[*cur_arg]);
4734 return ERR_ALERT | ERR_FATAL;
4735 }
4736
4737 if (strcmp(args[*cur_arg + 1], "none") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01004738 newsrv->ssl_ctx.verify = SSL_SOCK_VERIFY_NONE;
Emeric Brunef42d922012-10-11 16:11:36 +02004739 else if (strcmp(args[*cur_arg + 1], "required") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01004740 newsrv->ssl_ctx.verify = SSL_SOCK_VERIFY_REQUIRED;
Emeric Brunef42d922012-10-11 16:11:36 +02004741 else {
4742 if (err)
4743 memprintf(err, "'%s' : unknown verify method '%s', only 'none' and 'required' are supported\n",
4744 args[*cur_arg], args[*cur_arg + 1]);
4745 return ERR_ALERT | ERR_FATAL;
4746 }
4747
Evan Broderbe554312013-06-27 00:05:25 -07004748 return 0;
4749}
4750
4751/* parse the "verifyhost" server keyword */
4752static int srv_parse_verifyhost(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4753{
4754 if (!*args[*cur_arg + 1]) {
4755 if (err)
4756 memprintf(err, "'%s' : missing hostname to verify against", args[*cur_arg]);
4757 return ERR_ALERT | ERR_FATAL;
4758 }
4759
4760 newsrv->ssl_ctx.verify_host = strdup(args[*cur_arg + 1]);
4761
Emeric Brunef42d922012-10-11 16:11:36 +02004762 return 0;
4763}
4764
Emeric Brun2c86cbf2014-10-30 15:56:50 +01004765/* parse the "ssl-default-bind-options" keyword in global section */
4766static int ssl_parse_default_bind_options(char **args, int section_type, struct proxy *curpx,
4767 struct proxy *defpx, const char *file, int line,
4768 char **err) {
4769 int i = 1;
4770
4771 if (*(args[i]) == 0) {
4772 memprintf(err, "global statement '%s' expects an option as an argument.", args[0]);
4773 return -1;
4774 }
4775 while (*(args[i])) {
4776 if (!strcmp(args[i], "no-sslv3"))
4777 global.listen_default_ssloptions |= BC_SSL_O_NO_SSLV3;
4778 else if (!strcmp(args[i], "no-tlsv10"))
4779 global.listen_default_ssloptions |= BC_SSL_O_NO_TLSV10;
4780 else if (!strcmp(args[i], "no-tlsv11"))
4781 global.listen_default_ssloptions |= BC_SSL_O_NO_TLSV11;
4782 else if (!strcmp(args[i], "no-tlsv12"))
4783 global.listen_default_ssloptions |= BC_SSL_O_NO_TLSV12;
4784 else if (!strcmp(args[i], "force-sslv3"))
4785 global.listen_default_ssloptions |= BC_SSL_O_USE_SSLV3;
4786 else if (!strcmp(args[i], "force-tlsv10"))
4787 global.listen_default_ssloptions |= BC_SSL_O_USE_TLSV10;
4788 else if (!strcmp(args[i], "force-tlsv11")) {
4789#if SSL_OP_NO_TLSv1_1
4790 global.listen_default_ssloptions |= BC_SSL_O_USE_TLSV11;
4791#else
4792 memprintf(err, "'%s' '%s': library does not support protocol TLSv1.1", args[0], args[i]);
4793 return -1;
4794#endif
4795 }
4796 else if (!strcmp(args[i], "force-tlsv12")) {
4797#if SSL_OP_NO_TLSv1_2
4798 global.listen_default_ssloptions |= BC_SSL_O_USE_TLSV12;
4799#else
4800 memprintf(err, "'%s' '%s': library does not support protocol TLSv1.2", args[0], args[i]);
4801 return -1;
4802#endif
4803 }
4804 else if (!strcmp(args[i], "no-tls-tickets"))
4805 global.listen_default_ssloptions |= BC_SSL_O_NO_TLS_TICKETS;
4806 else {
4807 memprintf(err, "unknown option '%s' on global statement '%s'.", args[i], args[0]);
4808 return -1;
4809 }
4810 i++;
4811 }
4812 return 0;
4813}
4814
4815/* parse the "ssl-default-server-options" keyword in global section */
4816static int ssl_parse_default_server_options(char **args, int section_type, struct proxy *curpx,
4817 struct proxy *defpx, const char *file, int line,
4818 char **err) {
4819 int i = 1;
4820
4821 if (*(args[i]) == 0) {
4822 memprintf(err, "global statement '%s' expects an option as an argument.", args[0]);
4823 return -1;
4824 }
4825 while (*(args[i])) {
4826 if (!strcmp(args[i], "no-sslv3"))
4827 global.connect_default_ssloptions |= SRV_SSL_O_NO_SSLV3;
4828 else if (!strcmp(args[i], "no-tlsv10"))
4829 global.connect_default_ssloptions |= SRV_SSL_O_NO_TLSV10;
4830 else if (!strcmp(args[i], "no-tlsv11"))
4831 global.connect_default_ssloptions |= SRV_SSL_O_NO_TLSV11;
4832 else if (!strcmp(args[i], "no-tlsv12"))
4833 global.connect_default_ssloptions |= SRV_SSL_O_NO_TLSV12;
4834 else if (!strcmp(args[i], "force-sslv3"))
4835 global.connect_default_ssloptions |= SRV_SSL_O_USE_SSLV3;
4836 else if (!strcmp(args[i], "force-tlsv10"))
4837 global.connect_default_ssloptions |= SRV_SSL_O_USE_TLSV10;
4838 else if (!strcmp(args[i], "force-tlsv11")) {
4839#if SSL_OP_NO_TLSv1_1
4840 global.connect_default_ssloptions |= SRV_SSL_O_USE_TLSV11;
4841#else
4842 memprintf(err, "'%s' '%s': library does not support protocol TLSv1.1", args[0], args[i]);
4843 return -1;
4844#endif
4845 }
4846 else if (!strcmp(args[i], "force-tlsv12")) {
4847#if SSL_OP_NO_TLSv1_2
4848 global.connect_default_ssloptions |= SRV_SSL_O_USE_TLSV12;
4849#else
4850 memprintf(err, "'%s' '%s': library does not support protocol TLSv1.2", args[0], args[i]);
4851 return -1;
4852#endif
4853 }
4854 else if (!strcmp(args[i], "no-tls-tickets"))
4855 global.connect_default_ssloptions |= SRV_SSL_O_NO_TLS_TICKETS;
4856 else {
4857 memprintf(err, "unknown option '%s' on global statement '%s'.", args[i], args[0]);
4858 return -1;
4859 }
4860 i++;
4861 }
4862 return 0;
4863}
4864
Willy Tarreau7875d092012-09-10 08:20:03 +02004865/* Note: must not be declared <const> as its list will be overwritten.
4866 * Please take care of keeping this list alphabetically sorted.
4867 */
Willy Tarreaudc13c112013-06-21 23:16:39 +02004868static struct sample_fetch_kw_list sample_fetch_keywords = {ILH, {
Emeric Brun645ae792014-04-30 14:21:06 +02004869 { "ssl_bc", smp_fetch_ssl_fc, 0, NULL, SMP_T_BOOL, SMP_USE_L5SRV },
4870 { "ssl_bc_alg_keysize", smp_fetch_ssl_fc_alg_keysize, 0, NULL, SMP_T_UINT, SMP_USE_L5SRV },
4871 { "ssl_bc_cipher", smp_fetch_ssl_fc_cipher, 0, NULL, SMP_T_STR, SMP_USE_L5SRV },
4872 { "ssl_bc_protocol", smp_fetch_ssl_fc_protocol, 0, NULL, SMP_T_STR, SMP_USE_L5SRV },
Emeric Brunb73a9b02014-04-30 18:49:19 +02004873 { "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 +02004874 { "ssl_bc_use_keysize", smp_fetch_ssl_fc_use_keysize, 0, NULL, SMP_T_UINT, SMP_USE_L5SRV },
4875 { "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 +01004876 { "ssl_c_ca_err", smp_fetch_ssl_c_ca_err, 0, NULL, SMP_T_UINT, SMP_USE_L5CLI },
4877 { "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 +01004878 { "ssl_c_der", smp_fetch_ssl_x_der, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Willy Tarreau80aca902013-01-07 15:42:20 +01004879 { "ssl_c_err", smp_fetch_ssl_c_err, 0, NULL, SMP_T_UINT, SMP_USE_L5CLI },
Emeric Brunba841a12014-04-30 17:05:08 +02004880 { "ssl_c_i_dn", smp_fetch_ssl_x_i_dn, ARG2(0,STR,SINT), NULL, SMP_T_STR, SMP_USE_L5CLI },
4881 { "ssl_c_key_alg", smp_fetch_ssl_x_key_alg, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
4882 { "ssl_c_notafter", smp_fetch_ssl_x_notafter, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
4883 { "ssl_c_notbefore", smp_fetch_ssl_x_notbefore, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
4884 { "ssl_c_sig_alg", smp_fetch_ssl_x_sig_alg, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
4885 { "ssl_c_s_dn", smp_fetch_ssl_x_s_dn, ARG2(0,STR,SINT), NULL, SMP_T_STR, SMP_USE_L5CLI },
4886 { "ssl_c_serial", smp_fetch_ssl_x_serial, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
4887 { "ssl_c_sha1", smp_fetch_ssl_x_sha1, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Willy Tarreau80aca902013-01-07 15:42:20 +01004888 { "ssl_c_used", smp_fetch_ssl_c_used, 0, NULL, SMP_T_BOOL, SMP_USE_L5CLI },
4889 { "ssl_c_verify", smp_fetch_ssl_c_verify, 0, NULL, SMP_T_UINT, SMP_USE_L5CLI },
Emeric Brunba841a12014-04-30 17:05:08 +02004890 { "ssl_c_version", smp_fetch_ssl_x_version, 0, NULL, SMP_T_UINT, SMP_USE_L5CLI },
Emeric Brun43e79582014-10-29 19:03:26 +01004891 { "ssl_f_der", smp_fetch_ssl_x_der, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Emeric Brunba841a12014-04-30 17:05:08 +02004892 { "ssl_f_i_dn", smp_fetch_ssl_x_i_dn, ARG2(0,STR,SINT), NULL, SMP_T_STR, SMP_USE_L5CLI },
4893 { "ssl_f_key_alg", smp_fetch_ssl_x_key_alg, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
4894 { "ssl_f_notafter", smp_fetch_ssl_x_notafter, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
4895 { "ssl_f_notbefore", smp_fetch_ssl_x_notbefore, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
4896 { "ssl_f_sig_alg", smp_fetch_ssl_x_sig_alg, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
4897 { "ssl_f_s_dn", smp_fetch_ssl_x_s_dn, ARG2(0,STR,SINT), NULL, SMP_T_STR, SMP_USE_L5CLI },
4898 { "ssl_f_serial", smp_fetch_ssl_x_serial, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Emeric Brun55f4fa82014-04-30 17:11:25 +02004899 { "ssl_f_sha1", smp_fetch_ssl_x_sha1, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Emeric Brunba841a12014-04-30 17:05:08 +02004900 { "ssl_f_version", smp_fetch_ssl_x_version, 0, NULL, SMP_T_UINT, SMP_USE_L5CLI },
Willy Tarreau80aca902013-01-07 15:42:20 +01004901 { "ssl_fc", smp_fetch_ssl_fc, 0, NULL, SMP_T_BOOL, SMP_USE_L5CLI },
4902 { "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 +01004903 { "ssl_fc_cipher", smp_fetch_ssl_fc_cipher, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Willy Tarreau80aca902013-01-07 15:42:20 +01004904 { "ssl_fc_has_crt", smp_fetch_ssl_fc_has_crt, 0, NULL, SMP_T_BOOL, SMP_USE_L5CLI },
4905 { "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 +02004906 { "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 +02004907#ifdef OPENSSL_NPN_NEGOTIATED
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01004908 { "ssl_fc_npn", smp_fetch_ssl_fc_npn, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Willy Tarreaua33c6542012-10-15 13:19:06 +02004909#endif
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01004910#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01004911 { "ssl_fc_alpn", smp_fetch_ssl_fc_alpn, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Willy Tarreauab861d32013-04-02 02:30:41 +02004912#endif
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01004913 { "ssl_fc_protocol", smp_fetch_ssl_fc_protocol, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Emeric Brunb73a9b02014-04-30 18:49:19 +02004914 { "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 +01004915 { "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 +01004916 { "ssl_fc_session_id", smp_fetch_ssl_fc_session_id, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
4917 { "ssl_fc_sni", smp_fetch_ssl_fc_sni, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Willy Tarreau7875d092012-09-10 08:20:03 +02004918 { NULL, NULL, 0, 0, 0 },
4919}};
4920
4921/* Note: must not be declared <const> as its list will be overwritten.
4922 * Please take care of keeping this list alphabetically sorted.
4923 */
Willy Tarreaudc13c112013-06-21 23:16:39 +02004924static struct acl_kw_list acl_kws = {ILH, {
Thierry FOURNIERc5a4e982014-03-05 16:07:08 +01004925 { "ssl_fc_sni_end", "ssl_fc_sni", PAT_MATCH_END },
4926 { "ssl_fc_sni_reg", "ssl_fc_sni", PAT_MATCH_REG },
Willy Tarreau8ed669b2013-01-11 15:49:37 +01004927 { /* END */ },
Willy Tarreau7875d092012-09-10 08:20:03 +02004928}};
4929
Willy Tarreau79eeafa2012-09-14 07:53:05 +02004930/* Note: must not be declared <const> as its list will be overwritten.
4931 * Please take care of keeping this list alphabetically sorted, doing so helps
4932 * all code contributors.
4933 * Optional keywords are also declared with a NULL ->parse() function so that
4934 * the config parser can report an appropriate error when a known keyword was
4935 * not enabled.
4936 */
Willy Tarreau51fb7652012-09-18 18:24:39 +02004937static struct bind_kw_list bind_kws = { "SSL", { }, {
Nenad Merdanovic05552d42015-02-27 19:56:49 +01004938 { "alpn", bind_parse_alpn, 1 }, /* set ALPN supported protocols */
4939 { "ca-file", bind_parse_ca_file, 1 }, /* set CAfile to process verify on client cert */
4940 { "ca-ignore-err", bind_parse_ignore_err, 1 }, /* set error IDs to ignore on verify depth > 0 */
4941 { "ciphers", bind_parse_ciphers, 1 }, /* set SSL cipher suite */
4942 { "crl-file", bind_parse_crl_file, 1 }, /* set certificat revocation list file use on client cert verify */
4943 { "crt", bind_parse_crt, 1 }, /* load SSL certificates from this location */
4944 { "crt-ignore-err", bind_parse_ignore_err, 1 }, /* set error IDs to ingore on verify depth == 0 */
4945 { "crt-list", bind_parse_crt_list, 1 }, /* load a list of crt from this location */
4946 { "ecdhe", bind_parse_ecdhe, 1 }, /* defines named curve for elliptic curve Diffie-Hellman */
4947 { "force-sslv3", bind_parse_force_sslv3, 0 }, /* force SSLv3 */
4948 { "force-tlsv10", bind_parse_force_tlsv10, 0 }, /* force TLSv10 */
4949 { "force-tlsv11", bind_parse_force_tlsv11, 0 }, /* force TLSv11 */
4950 { "force-tlsv12", bind_parse_force_tlsv12, 0 }, /* force TLSv12 */
4951 { "no-sslv3", bind_parse_no_sslv3, 0 }, /* disable SSLv3 */
4952 { "no-tlsv10", bind_parse_no_tlsv10, 0 }, /* disable TLSv10 */
4953 { "no-tlsv11", bind_parse_no_tlsv11, 0 }, /* disable TLSv11 */
4954 { "no-tlsv12", bind_parse_no_tlsv12, 0 }, /* disable TLSv12 */
4955 { "no-tls-tickets", bind_parse_no_tls_tickets, 0 }, /* disable session resumption tickets */
4956 { "ssl", bind_parse_ssl, 0 }, /* enable SSL processing */
4957 { "strict-sni", bind_parse_strict_sni, 0 }, /* refuse negotiation if sni doesn't match a certificate */
4958 { "tls-ticket-keys", bind_parse_tls_ticket_keys, 1 }, /* set file to load TLS ticket keys from */
4959 { "verify", bind_parse_verify, 1 }, /* set SSL verify method */
4960 { "npn", bind_parse_npn, 1 }, /* set NPN supported protocols */
Willy Tarreau79eeafa2012-09-14 07:53:05 +02004961 { NULL, NULL, 0 },
4962}};
Emeric Brun46591952012-05-18 15:47:34 +02004963
Willy Tarreau92faadf2012-10-10 23:04:25 +02004964/* Note: must not be declared <const> as its list will be overwritten.
4965 * Please take care of keeping this list alphabetically sorted, doing so helps
4966 * all code contributors.
4967 * Optional keywords are also declared with a NULL ->parse() function so that
4968 * the config parser can report an appropriate error when a known keyword was
4969 * not enabled.
4970 */
4971static struct srv_kw_list srv_kws = { "SSL", { }, {
Emeric Brunef42d922012-10-11 16:11:36 +02004972 { "ca-file", srv_parse_ca_file, 1, 0 }, /* set CAfile to process verify server cert */
Emeric Brunecc91fe2012-10-11 15:05:10 +02004973 { "check-ssl", srv_parse_check_ssl, 0, 0 }, /* enable SSL for health checks */
4974 { "ciphers", srv_parse_ciphers, 1, 0 }, /* select the cipher suite */
Emeric Brunef42d922012-10-11 16:11:36 +02004975 { "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 +02004976 { "crt", srv_parse_crt, 1, 0 }, /* set client certificate */
Emeric Brunecc91fe2012-10-11 15:05:10 +02004977 { "force-sslv3", srv_parse_force_sslv3, 0, 0 }, /* force SSLv3 */
4978 { "force-tlsv10", srv_parse_force_tlsv10, 0, 0 }, /* force TLSv10 */
4979 { "force-tlsv11", srv_parse_force_tlsv11, 0, 0 }, /* force TLSv11 */
4980 { "force-tlsv12", srv_parse_force_tlsv12, 0, 0 }, /* force TLSv12 */
Willy Tarreau2a3fb1c2015-02-05 16:47:07 +01004981 { "no-ssl-reuse", srv_parse_no_ssl_reuse, 0, 0 }, /* disable session reuse */
Emeric Brunecc91fe2012-10-11 15:05:10 +02004982 { "no-sslv3", srv_parse_no_sslv3, 0, 0 }, /* disable SSLv3 */
4983 { "no-tlsv10", srv_parse_no_tlsv10, 0, 0 }, /* disable TLSv10 */
4984 { "no-tlsv11", srv_parse_no_tlsv11, 0, 0 }, /* disable TLSv11 */
4985 { "no-tlsv12", srv_parse_no_tlsv12, 0, 0 }, /* disable TLSv12 */
Emeric Brunf9c5c472012-10-11 15:28:34 +02004986 { "no-tls-tickets", srv_parse_no_tls_tickets, 0, 0 }, /* disable session resumption tickets */
David Safb76832014-05-08 23:42:08 -04004987 { "send-proxy-v2-ssl", srv_parse_send_proxy_ssl, 0, 0 }, /* send PROXY protocol header v2 with SSL info */
4988 { "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 +02004989 { "ssl", srv_parse_ssl, 0, 0 }, /* enable SSL processing */
Emeric Brunef42d922012-10-11 16:11:36 +02004990 { "verify", srv_parse_verify, 1, 0 }, /* set SSL verify method */
Evan Broderbe554312013-06-27 00:05:25 -07004991 { "verifyhost", srv_parse_verifyhost, 1, 0 }, /* require that SSL cert verifies for hostname */
Willy Tarreau92faadf2012-10-10 23:04:25 +02004992 { NULL, NULL, 0, 0 },
4993}};
4994
Emeric Brun2c86cbf2014-10-30 15:56:50 +01004995static struct cfg_kw_list cfg_kws = {ILH, {
4996 { CFG_GLOBAL, "ssl-default-bind-options", ssl_parse_default_bind_options },
4997 { CFG_GLOBAL, "ssl-default-server-options", ssl_parse_default_server_options },
4998 { 0, NULL, NULL },
4999}};
5000
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02005001/* transport-layer operations for SSL sockets */
5002struct xprt_ops ssl_sock = {
Emeric Brun46591952012-05-18 15:47:34 +02005003 .snd_buf = ssl_sock_from_buf,
5004 .rcv_buf = ssl_sock_to_buf,
5005 .rcv_pipe = NULL,
5006 .snd_pipe = NULL,
5007 .shutr = NULL,
5008 .shutw = ssl_sock_shutw,
5009 .close = ssl_sock_close,
5010 .init = ssl_sock_init,
5011};
5012
Janusz Dziemidowicz2c701b52015-03-07 23:03:59 +01005013#if (OPENSSL_VERSION_NUMBER >= 0x1000200fL && !defined OPENSSL_NO_TLSEXT && !defined OPENSSL_IS_BORINGSSL)
5014
5015static void ssl_sock_sctl_free_func(void *parent, void *ptr, CRYPTO_EX_DATA *ad, int idx, long argl, void *argp)
5016{
5017 if (ptr) {
5018 chunk_destroy(ptr);
5019 free(ptr);
5020 }
5021}
5022
5023#endif
5024
Emeric Brun46591952012-05-18 15:47:34 +02005025__attribute__((constructor))
Willy Tarreau92faadf2012-10-10 23:04:25 +02005026static void __ssl_sock_init(void)
5027{
Emeric Brun46591952012-05-18 15:47:34 +02005028 STACK_OF(SSL_COMP)* cm;
5029
Willy Tarreau610f04b2014-02-13 11:36:41 +01005030#ifdef LISTEN_DEFAULT_CIPHERS
5031 global.listen_default_ciphers = LISTEN_DEFAULT_CIPHERS;
5032#endif
5033#ifdef CONNECT_DEFAULT_CIPHERS
5034 global.connect_default_ciphers = CONNECT_DEFAULT_CIPHERS;
5035#endif
5036 if (global.listen_default_ciphers)
5037 global.listen_default_ciphers = strdup(global.listen_default_ciphers);
5038 if (global.connect_default_ciphers)
5039 global.connect_default_ciphers = strdup(global.connect_default_ciphers);
Emeric Brun2c86cbf2014-10-30 15:56:50 +01005040 global.listen_default_ssloptions = BC_SSL_O_NONE;
5041 global.connect_default_ssloptions = SRV_SSL_O_NONE;
Willy Tarreau610f04b2014-02-13 11:36:41 +01005042
Emeric Brun46591952012-05-18 15:47:34 +02005043 SSL_library_init();
5044 cm = SSL_COMP_get_compression_methods();
5045 sk_SSL_COMP_zero(cm);
Janusz Dziemidowicz2c701b52015-03-07 23:03:59 +01005046#if (OPENSSL_VERSION_NUMBER >= 0x1000200fL && !defined OPENSSL_NO_TLSEXT && !defined OPENSSL_IS_BORINGSSL)
5047 sctl_ex_index = SSL_CTX_get_ex_new_index(0, NULL, NULL, NULL, ssl_sock_sctl_free_func);
5048#endif
Willy Tarreau7875d092012-09-10 08:20:03 +02005049 sample_register_fetches(&sample_fetch_keywords);
5050 acl_register_keywords(&acl_kws);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005051 bind_register_keywords(&bind_kws);
Willy Tarreau92faadf2012-10-10 23:04:25 +02005052 srv_register_keywords(&srv_kws);
Emeric Brun2c86cbf2014-10-30 15:56:50 +01005053 cfg_register_keywords(&cfg_kws);
Willy Tarreaud92aa5c2015-01-15 21:34:39 +01005054
5055 global.ssl_session_max_cost = SSL_SESSION_MAX_COST;
5056 global.ssl_handshake_max_cost = SSL_HANDSHAKE_MAX_COST;
Remi Gacogne4f902b82015-05-28 16:23:00 +02005057
5058#ifndef OPENSSL_NO_DH
5059 ssl_dh_ptr_index = SSL_CTX_get_ex_new_index(0, NULL, NULL, NULL, NULL);
5060#endif
Emeric Brun46591952012-05-18 15:47:34 +02005061}
5062
Remi Gacogned3a23c32015-05-28 16:39:47 +02005063__attribute__((destructor))
5064static void __ssl_sock_deinit(void)
5065{
5066#ifndef OPENSSL_NO_DH
5067 if (local_dh_1024) {
5068 DH_free(local_dh_1024);
5069 local_dh_1024 = NULL;
5070 }
5071
5072 if (local_dh_2048) {
5073 DH_free(local_dh_2048);
5074 local_dh_2048 = NULL;
5075 }
5076
5077 if (local_dh_4096) {
5078 DH_free(local_dh_4096);
5079 local_dh_4096 = NULL;
5080 }
5081
5082 if (local_dh_8192) {
5083 DH_free(local_dh_8192);
5084 local_dh_8192 = NULL;
5085 }
5086#endif
5087
5088 ERR_remove_state(0);
5089 ERR_free_strings();
5090
5091 EVP_cleanup();
5092
5093#if OPENSSL_VERSION_NUMBER >= 0x00907000L
5094 CRYPTO_cleanup_all_ex_data();
5095#endif
5096}
5097
5098
Emeric Brun46591952012-05-18 15:47:34 +02005099/*
5100 * Local variables:
5101 * c-indent-level: 8
5102 * c-basic-offset: 8
5103 * End:
5104 */