blob: 8fb8b5f037a94eebe89bc0d4549bae77e87d7b67 [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>
Emeric Brun46591952012-05-18 15:47:34 +020047
48#include <common/buffer.h>
49#include <common/compat.h>
50#include <common/config.h>
51#include <common/debug.h>
Willy Tarreau79eeafa2012-09-14 07:53:05 +020052#include <common/errors.h>
Emeric Brun46591952012-05-18 15:47:34 +020053#include <common/standard.h>
54#include <common/ticks.h>
55#include <common/time.h>
56
Emeric Brunfc0421f2012-09-07 17:30:07 +020057#include <ebsttree.h>
58
59#include <types/global.h>
60#include <types/ssl_sock.h>
61
Willy Tarreau7875d092012-09-10 08:20:03 +020062#include <proto/acl.h>
63#include <proto/arg.h>
Emeric Brun46591952012-05-18 15:47:34 +020064#include <proto/connection.h>
65#include <proto/fd.h>
66#include <proto/freq_ctr.h>
67#include <proto/frontend.h>
Willy Tarreau79eeafa2012-09-14 07:53:05 +020068#include <proto/listener.h>
Thierry FOURNIERed66c292013-11-28 11:05:19 +010069#include <proto/pattern.h>
Willy Tarreau92faadf2012-10-10 23:04:25 +020070#include <proto/server.h>
Emeric Brun46591952012-05-18 15:47:34 +020071#include <proto/log.h>
Emeric Brun94324a42012-10-11 14:00:19 +020072#include <proto/proxy.h>
Emeric Brunfc0421f2012-09-07 17:30:07 +020073#include <proto/shctx.h>
Emeric Brun46591952012-05-18 15:47:34 +020074#include <proto/ssl_sock.h>
75#include <proto/task.h>
76
Willy Tarreau518cedd2014-02-17 15:43:01 +010077/* Warning, these are bits, not integers! */
Emeric Brune64aef12012-09-21 13:15:06 +020078#define SSL_SOCK_ST_FL_VERIFY_DONE 0x00000001
Emeric Brund8b2bb52014-01-28 15:43:53 +010079#define SSL_SOCK_ST_FL_16K_WBFSIZE 0x00000002
Willy Tarreau518cedd2014-02-17 15:43:01 +010080#define SSL_SOCK_SEND_UNLIMITED 0x00000004
Emeric Brun29f037d2014-04-25 19:05:36 +020081#define SSL_SOCK_RECV_HEARTBEAT 0x00000008
82
Emeric Brunf282a812012-09-21 15:27:54 +020083/* bits 0xFFFF0000 are reserved to store verify errors */
84
85/* Verify errors macros */
86#define SSL_SOCK_CA_ERROR_TO_ST(e) (((e > 63) ? 63 : e) << (16))
87#define SSL_SOCK_CAEDEPTH_TO_ST(d) (((d > 15) ? 15 : d) << (6+16))
88#define SSL_SOCK_CRTERROR_TO_ST(e) (((e > 63) ? 63 : e) << (4+6+16))
89
90#define SSL_SOCK_ST_TO_CA_ERROR(s) ((s >> (16)) & 63)
91#define SSL_SOCK_ST_TO_CAEDEPTH(s) ((s >> (6+16)) & 15)
92#define SSL_SOCK_ST_TO_CRTERROR(s) ((s >> (4+6+16)) & 63)
Emeric Brune64aef12012-09-21 13:15:06 +020093
Emeric Brun850efd52014-01-29 12:24:34 +010094/* server and bind verify method, it uses a global value as default */
95enum {
96 SSL_SOCK_VERIFY_DEFAULT = 0,
97 SSL_SOCK_VERIFY_REQUIRED = 1,
98 SSL_SOCK_VERIFY_OPTIONAL = 2,
99 SSL_SOCK_VERIFY_NONE = 3,
100};
101
Willy Tarreau71b734c2014-01-28 15:19:44 +0100102int sslconns = 0;
103int totalsslconns = 0;
Emeric Brune1f38db2012-09-03 20:36:47 +0200104
105void ssl_sock_infocbk(const SSL *ssl, int where, int ret)
106{
107 struct connection *conn = (struct connection *)SSL_get_app_data(ssl);
108 (void)ret; /* shut gcc stupid warning */
Emeric Brund8b2bb52014-01-28 15:43:53 +0100109 BIO *write_bio;
Emeric Brune1f38db2012-09-03 20:36:47 +0200110
111 if (where & SSL_CB_HANDSHAKE_START) {
112 /* Disable renegotiation (CVE-2009-3555) */
Willy Tarreau20879a02012-12-03 16:32:10 +0100113 if (conn->flags & CO_FL_CONNECTED) {
Emeric Brune1f38db2012-09-03 20:36:47 +0200114 conn->flags |= CO_FL_ERROR;
Willy Tarreau20879a02012-12-03 16:32:10 +0100115 conn->err_code = CO_ER_SSL_RENEG;
116 }
Emeric Brune1f38db2012-09-03 20:36:47 +0200117 }
Emeric Brund8b2bb52014-01-28 15:43:53 +0100118
119 if ((where & SSL_CB_ACCEPT_LOOP) == SSL_CB_ACCEPT_LOOP) {
120 if (!(conn->xprt_st & SSL_SOCK_ST_FL_16K_WBFSIZE)) {
121 /* Long certificate chains optimz
122 If write and read bios are differents, we
123 consider that the buffering was activated,
124 so we rise the output buffer size from 4k
125 to 16k */
126 write_bio = SSL_get_wbio(ssl);
127 if (write_bio != SSL_get_rbio(ssl)) {
128 BIO_set_write_buffer_size(write_bio, 16384);
129 conn->xprt_st |= SSL_SOCK_ST_FL_16K_WBFSIZE;
130 }
131 }
132 }
Emeric Brunfc0421f2012-09-07 17:30:07 +0200133}
134
Emeric Brune64aef12012-09-21 13:15:06 +0200135/* Callback is called for each certificate of the chain during a verify
136 ok is set to 1 if preverify detect no error on current certificate.
137 Returns 0 to break the handshake, 1 otherwise. */
Evan Broderbe554312013-06-27 00:05:25 -0700138int ssl_sock_bind_verifycbk(int ok, X509_STORE_CTX *x_store)
Emeric Brune64aef12012-09-21 13:15:06 +0200139{
140 SSL *ssl;
141 struct connection *conn;
Emeric Brun81c00f02012-09-21 14:31:21 +0200142 int err, depth;
Emeric Brune64aef12012-09-21 13:15:06 +0200143
144 ssl = X509_STORE_CTX_get_ex_data(x_store, SSL_get_ex_data_X509_STORE_CTX_idx());
145 conn = (struct connection *)SSL_get_app_data(ssl);
146
Willy Tarreauf7bc57c2012-10-03 00:19:48 +0200147 conn->xprt_st |= SSL_SOCK_ST_FL_VERIFY_DONE;
Emeric Brune64aef12012-09-21 13:15:06 +0200148
Emeric Brun81c00f02012-09-21 14:31:21 +0200149 if (ok) /* no errors */
150 return ok;
151
152 depth = X509_STORE_CTX_get_error_depth(x_store);
153 err = X509_STORE_CTX_get_error(x_store);
154
155 /* check if CA error needs to be ignored */
156 if (depth > 0) {
Willy Tarreauf7bc57c2012-10-03 00:19:48 +0200157 if (!SSL_SOCK_ST_TO_CA_ERROR(conn->xprt_st)) {
158 conn->xprt_st |= SSL_SOCK_CA_ERROR_TO_ST(err);
159 conn->xprt_st |= SSL_SOCK_CAEDEPTH_TO_ST(depth);
Emeric Brunf282a812012-09-21 15:27:54 +0200160 }
161
Emeric Brun1eb20ef2012-12-03 13:24:29 +0100162 if (objt_listener(conn->target)->bind_conf->ca_ignerr & (1ULL << err)) {
163 ERR_clear_error();
Emeric Brun81c00f02012-09-21 14:31:21 +0200164 return 1;
Emeric Brun1eb20ef2012-12-03 13:24:29 +0100165 }
Emeric Brun81c00f02012-09-21 14:31:21 +0200166
Willy Tarreau20879a02012-12-03 16:32:10 +0100167 conn->err_code = CO_ER_SSL_CA_FAIL;
Emeric Brun81c00f02012-09-21 14:31:21 +0200168 return 0;
169 }
170
Willy Tarreauf7bc57c2012-10-03 00:19:48 +0200171 if (!SSL_SOCK_ST_TO_CRTERROR(conn->xprt_st))
172 conn->xprt_st |= SSL_SOCK_CRTERROR_TO_ST(err);
Emeric Brunf282a812012-09-21 15:27:54 +0200173
Emeric Brun81c00f02012-09-21 14:31:21 +0200174 /* check if certificate error needs to be ignored */
Emeric Brun1eb20ef2012-12-03 13:24:29 +0100175 if (objt_listener(conn->target)->bind_conf->crt_ignerr & (1ULL << err)) {
176 ERR_clear_error();
Emeric Brun81c00f02012-09-21 14:31:21 +0200177 return 1;
Emeric Brun1eb20ef2012-12-03 13:24:29 +0100178 }
Emeric Brun81c00f02012-09-21 14:31:21 +0200179
Willy Tarreau20879a02012-12-03 16:32:10 +0100180 conn->err_code = CO_ER_SSL_CRT_FAIL;
Emeric Brun81c00f02012-09-21 14:31:21 +0200181 return 0;
Emeric Brune64aef12012-09-21 13:15:06 +0200182}
183
Emeric Brun29f037d2014-04-25 19:05:36 +0200184/* Callback is called for ssl protocol analyse */
185void ssl_sock_msgcbk(int write_p, int version, int content_type, const void *buf, size_t len, SSL *ssl, void *arg)
186{
Emeric Brun29f037d2014-04-25 19:05:36 +0200187#ifdef TLS1_RT_HEARTBEAT
188 /* test heartbeat received (write_p is set to 0
189 for a received record) */
Willy Tarreauf51c6982014-04-25 20:02:39 +0200190 if ((content_type == TLS1_RT_HEARTBEAT) && (write_p == 0)) {
Willy Tarreau84815002014-04-25 21:40:27 +0200191 struct connection *conn = (struct connection *)SSL_get_app_data(ssl);
Willy Tarreauf51c6982014-04-25 20:02:39 +0200192 const unsigned char *p = buf;
193 unsigned int payload;
194
Emeric Brun29f037d2014-04-25 19:05:36 +0200195 conn->xprt_st |= SSL_SOCK_RECV_HEARTBEAT;
Willy Tarreauf51c6982014-04-25 20:02:39 +0200196
197 /* Check if this is a CVE-2014-0160 exploitation attempt. */
198 if (*p != TLS1_HB_REQUEST)
199 return;
200
Willy Tarreauaeed6722014-04-25 23:59:58 +0200201 if (len < 1 + 2 + 16) /* 1 type + 2 size + 0 payload + 16 padding */
Willy Tarreauf51c6982014-04-25 20:02:39 +0200202 goto kill_it;
203
204 payload = (p[1] * 256) + p[2];
Willy Tarreau3b2fdb62014-04-25 23:44:22 +0200205 if (3 + payload + 16 <= len)
Willy Tarreauf51c6982014-04-25 20:02:39 +0200206 return; /* OK no problem */
Willy Tarreauaeed6722014-04-25 23:59:58 +0200207 kill_it:
Willy Tarreau3b2fdb62014-04-25 23:44:22 +0200208 /* We have a clear heartbleed attack (CVE-2014-0160), the
209 * advertised payload is larger than the advertised packet
210 * length, so we have garbage in the buffer between the
211 * payload and the end of the buffer (p+len). We can't know
212 * if the SSL stack is patched, and we don't know if we can
213 * safely wipe out the area between p+3+len and payload.
214 * So instead, we prevent the response from being sent by
215 * setting the max_send_fragment to 0 and we report an SSL
216 * error, which will kill this connection. It will be reported
217 * above as SSL_ERROR_SSL while an other handshake failure with
Willy Tarreauf51c6982014-04-25 20:02:39 +0200218 * a heartbeat message will be reported as SSL_ERROR_SYSCALL.
219 */
Willy Tarreau3b2fdb62014-04-25 23:44:22 +0200220 ssl->max_send_fragment = 0;
Willy Tarreauf51c6982014-04-25 20:02:39 +0200221 SSLerr(SSL_F_TLS1_HEARTBEAT, SSL_R_SSL_HANDSHAKE_FAILURE);
222 return;
223 }
Emeric Brun29f037d2014-04-25 19:05:36 +0200224#endif
225}
226
Willy Tarreau6c9a3d52012-10-18 18:57:14 +0200227#ifdef OPENSSL_NPN_NEGOTIATED
228/* This callback is used so that the server advertises the list of
229 * negociable protocols for NPN.
230 */
231static int ssl_sock_advertise_npn_protos(SSL *s, const unsigned char **data,
232 unsigned int *len, void *arg)
233{
234 struct bind_conf *conf = arg;
235
236 *data = (const unsigned char *)conf->npn_str;
237 *len = conf->npn_len;
238 return SSL_TLSEXT_ERR_OK;
239}
240#endif
241
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +0100242#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Willy Tarreauab861d32013-04-02 02:30:41 +0200243/* This callback is used so that the server advertises the list of
244 * negociable protocols for ALPN.
245 */
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +0100246static int ssl_sock_advertise_alpn_protos(SSL *s, const unsigned char **out,
247 unsigned char *outlen,
248 const unsigned char *server,
249 unsigned int server_len, void *arg)
Willy Tarreauab861d32013-04-02 02:30:41 +0200250{
251 struct bind_conf *conf = arg;
252
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +0100253 if (SSL_select_next_proto((unsigned char**) out, outlen, (const unsigned char *)conf->alpn_str,
254 conf->alpn_len, server, server_len) != OPENSSL_NPN_NEGOTIATED) {
255 return SSL_TLSEXT_ERR_NOACK;
256 }
Willy Tarreauab861d32013-04-02 02:30:41 +0200257 return SSL_TLSEXT_ERR_OK;
258}
259#endif
260
Emeric Brunfc0421f2012-09-07 17:30:07 +0200261#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
262/* Sets the SSL ctx of <ssl> to match the advertised server name. Returns a
263 * warning when no match is found, which implies the default (first) cert
264 * will keep being used.
265 */
Willy Tarreau2a65ff02012-09-13 17:54:29 +0200266static int ssl_sock_switchctx_cbk(SSL *ssl, int *al, struct bind_conf *s)
Emeric Brunfc0421f2012-09-07 17:30:07 +0200267{
268 const char *servername;
269 const char *wildp = NULL;
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +0200270 struct ebmb_node *node, *n;
Emeric Brunfc0421f2012-09-07 17:30:07 +0200271 int i;
272 (void)al; /* shut gcc stupid warning */
273
274 servername = SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name);
Emmanuel Hocdet65623372013-01-24 17:17:15 +0100275 if (!servername) {
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +0200276 return (s->strict_sni ?
277 SSL_TLSEXT_ERR_ALERT_FATAL :
Emmanuel Hocdet79274e22013-05-31 12:47:44 +0200278 SSL_TLSEXT_ERR_NOACK);
Emmanuel Hocdet65623372013-01-24 17:17:15 +0100279 }
Emeric Brunfc0421f2012-09-07 17:30:07 +0200280
Willy Tarreau19d14ef2012-10-29 16:51:55 +0100281 for (i = 0; i < trash.size; i++) {
Emeric Brunfc0421f2012-09-07 17:30:07 +0200282 if (!servername[i])
283 break;
Willy Tarreau19d14ef2012-10-29 16:51:55 +0100284 trash.str[i] = tolower(servername[i]);
285 if (!wildp && (trash.str[i] == '.'))
286 wildp = &trash.str[i];
Emeric Brunfc0421f2012-09-07 17:30:07 +0200287 }
Willy Tarreau19d14ef2012-10-29 16:51:55 +0100288 trash.str[i] = 0;
Emeric Brunfc0421f2012-09-07 17:30:07 +0200289
290 /* lookup in full qualified names */
Willy Tarreau19d14ef2012-10-29 16:51:55 +0100291 node = ebst_lookup(&s->sni_ctx, trash.str);
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +0200292
293 /* lookup a not neg filter */
294 for (n = node; n; n = ebmb_next_dup(n)) {
295 if (!container_of(n, struct sni_ctx, name)->neg) {
296 node = n;
297 break;
Emmanuel Hocdet65623372013-01-24 17:17:15 +0100298 }
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +0200299 }
300 if (!node && wildp) {
301 /* lookup in wildcards names */
Emeric Brunfc0421f2012-09-07 17:30:07 +0200302 node = ebst_lookup(&s->sni_w_ctx, wildp);
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +0200303 }
304 if (!node || container_of(node, struct sni_ctx, name)->neg) {
305 return (s->strict_sni ?
306 SSL_TLSEXT_ERR_ALERT_FATAL :
307 SSL_TLSEXT_ERR_ALERT_WARNING);
Emeric Brunfc0421f2012-09-07 17:30:07 +0200308 }
309
310 /* switch ctx */
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +0200311 SSL_set_SSL_CTX(ssl, container_of(node, struct sni_ctx, name)->ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +0200312 return SSL_TLSEXT_ERR_OK;
313}
314#endif /* SSL_CTRL_SET_TLSEXT_HOSTNAME */
315
Emeric Bruna4bcd9a2012-09-20 16:19:02 +0200316#ifndef OPENSSL_NO_DH
Remi Gacognef46cd6e2014-06-12 14:58:40 +0200317
318static DH * ssl_get_dh_1024(void)
319{
320#if OPENSSL_VERSION_NUMBER < 0x0090801fL
321 static const unsigned char rfc_2409_prime_1024[] = {
322 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xC9,0x0F,0xDA,0xA2,
323 0x21,0x68,0xC2,0x34,0xC4,0xC6,0x62,0x8B,0x80,0xDC,0x1C,0xD1,
324 0x29,0x02,0x4E,0x08,0x8A,0x67,0xCC,0x74,0x02,0x0B,0xBE,0xA6,
325 0x3B,0x13,0x9B,0x22,0x51,0x4A,0x08,0x79,0x8E,0x34,0x04,0xDD,
326 0xEF,0x95,0x19,0xB3,0xCD,0x3A,0x43,0x1B,0x30,0x2B,0x0A,0x6D,
327 0xF2,0x5F,0x14,0x37,0x4F,0xE1,0x35,0x6D,0x6D,0x51,0xC2,0x45,
328 0xE4,0x85,0xB5,0x76,0x62,0x5E,0x7E,0xC6,0xF4,0x4C,0x42,0xE9,
329 0xA6,0x37,0xED,0x6B,0x0B,0xFF,0x5C,0xB6,0xF4,0x06,0xB7,0xED,
330 0xEE,0x38,0x6B,0xFB,0x5A,0x89,0x9F,0xA5,0xAE,0x9F,0x24,0x11,
331 0x7C,0x4B,0x1F,0xE6,0x49,0x28,0x66,0x51,0xEC,0xE6,0x53,0x81,
332 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
333 };
334#endif
335 DH *dh = DH_new();
336 if (dh) {
337#if OPENSSL_VERSION_NUMBER >= 0x0090801fL
338 dh->p = get_rfc2409_prime_1024(NULL);
339#else
340 dh->p = BN_bin2bn(rfc_2409_prime_1024, sizeof rfc_2409_prime_1024, NULL);
341#endif
342 /* See RFC 2409, Section 6 "Oakley Groups"
343 for the reason why 2 is used as generator.
344 */
345 BN_dec2bn(&dh->g, "2");
346 if (!dh->p || !dh->g) {
347 DH_free(dh);
348 dh = NULL;
349 }
350 }
351 return dh;
352}
353
354static DH *ssl_get_dh_2048(void)
355{
356#if OPENSSL_VERSION_NUMBER < 0x0090801fL
357 static const unsigned char rfc_3526_prime_2048[] = {
358 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xC9,0x0F,0xDA,0xA2,
359 0x21,0x68,0xC2,0x34,0xC4,0xC6,0x62,0x8B,0x80,0xDC,0x1C,0xD1,
360 0x29,0x02,0x4E,0x08,0x8A,0x67,0xCC,0x74,0x02,0x0B,0xBE,0xA6,
361 0x3B,0x13,0x9B,0x22,0x51,0x4A,0x08,0x79,0x8E,0x34,0x04,0xDD,
362 0xEF,0x95,0x19,0xB3,0xCD,0x3A,0x43,0x1B,0x30,0x2B,0x0A,0x6D,
363 0xF2,0x5F,0x14,0x37,0x4F,0xE1,0x35,0x6D,0x6D,0x51,0xC2,0x45,
364 0xE4,0x85,0xB5,0x76,0x62,0x5E,0x7E,0xC6,0xF4,0x4C,0x42,0xE9,
365 0xA6,0x37,0xED,0x6B,0x0B,0xFF,0x5C,0xB6,0xF4,0x06,0xB7,0xED,
366 0xEE,0x38,0x6B,0xFB,0x5A,0x89,0x9F,0xA5,0xAE,0x9F,0x24,0x11,
367 0x7C,0x4B,0x1F,0xE6,0x49,0x28,0x66,0x51,0xEC,0xE4,0x5B,0x3D,
368 0xC2,0x00,0x7C,0xB8,0xA1,0x63,0xBF,0x05,0x98,0xDA,0x48,0x36,
369 0x1C,0x55,0xD3,0x9A,0x69,0x16,0x3F,0xA8,0xFD,0x24,0xCF,0x5F,
370 0x83,0x65,0x5D,0x23,0xDC,0xA3,0xAD,0x96,0x1C,0x62,0xF3,0x56,
371 0x20,0x85,0x52,0xBB,0x9E,0xD5,0x29,0x07,0x70,0x96,0x96,0x6D,
372 0x67,0x0C,0x35,0x4E,0x4A,0xBC,0x98,0x04,0xF1,0x74,0x6C,0x08,
373 0xCA,0x18,0x21,0x7C,0x32,0x90,0x5E,0x46,0x2E,0x36,0xCE,0x3B,
374 0xE3,0x9E,0x77,0x2C,0x18,0x0E,0x86,0x03,0x9B,0x27,0x83,0xA2,
375 0xEC,0x07,0xA2,0x8F,0xB5,0xC5,0x5D,0xF0,0x6F,0x4C,0x52,0xC9,
376 0xDE,0x2B,0xCB,0xF6,0x95,0x58,0x17,0x18,0x39,0x95,0x49,0x7C,
377 0xEA,0x95,0x6A,0xE5,0x15,0xD2,0x26,0x18,0x98,0xFA,0x05,0x10,
378 0x15,0x72,0x8E,0x5A,0x8A,0xAC,0xAA,0x68,0xFF,0xFF,0xFF,0xFF,
379 0xFF,0xFF,0xFF,0xFF,
380 };
381#endif
382 DH *dh = DH_new();
383 if (dh) {
384#if OPENSSL_VERSION_NUMBER >= 0x0090801fL
385 dh->p = get_rfc3526_prime_2048(NULL);
386#else
387 dh->p = BN_bin2bn(rfc_3526_prime_2048, sizeof rfc_3526_prime_2048, NULL);
388#endif
389 /* See RFC 3526, Section 3 "2048-bit MODP Group"
390 for the reason why 2 is used as generator.
391 */
392 BN_dec2bn(&dh->g, "2");
393 if (!dh->p || !dh->g) {
394 DH_free(dh);
395 dh = NULL;
396 }
397 }
398 return dh;
399}
400
401static DH *ssl_get_dh_4096(void)
402{
403#if OPENSSL_VERSION_NUMBER < 0x0090801fL
404 static const unsigned char rfc_3526_prime_4096[] = {
405 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xC9,0x0F,0xDA,0xA2,
406 0x21,0x68,0xC2,0x34,0xC4,0xC6,0x62,0x8B,0x80,0xDC,0x1C,0xD1,
407 0x29,0x02,0x4E,0x08,0x8A,0x67,0xCC,0x74,0x02,0x0B,0xBE,0xA6,
408 0x3B,0x13,0x9B,0x22,0x51,0x4A,0x08,0x79,0x8E,0x34,0x04,0xDD,
409 0xEF,0x95,0x19,0xB3,0xCD,0x3A,0x43,0x1B,0x30,0x2B,0x0A,0x6D,
410 0xF2,0x5F,0x14,0x37,0x4F,0xE1,0x35,0x6D,0x6D,0x51,0xC2,0x45,
411 0xE4,0x85,0xB5,0x76,0x62,0x5E,0x7E,0xC6,0xF4,0x4C,0x42,0xE9,
412 0xA6,0x37,0xED,0x6B,0x0B,0xFF,0x5C,0xB6,0xF4,0x06,0xB7,0xED,
413 0xEE,0x38,0x6B,0xFB,0x5A,0x89,0x9F,0xA5,0xAE,0x9F,0x24,0x11,
414 0x7C,0x4B,0x1F,0xE6,0x49,0x28,0x66,0x51,0xEC,0xE4,0x5B,0x3D,
415 0xC2,0x00,0x7C,0xB8,0xA1,0x63,0xBF,0x05,0x98,0xDA,0x48,0x36,
416 0x1C,0x55,0xD3,0x9A,0x69,0x16,0x3F,0xA8,0xFD,0x24,0xCF,0x5F,
417 0x83,0x65,0x5D,0x23,0xDC,0xA3,0xAD,0x96,0x1C,0x62,0xF3,0x56,
418 0x20,0x85,0x52,0xBB,0x9E,0xD5,0x29,0x07,0x70,0x96,0x96,0x6D,
419 0x67,0x0C,0x35,0x4E,0x4A,0xBC,0x98,0x04,0xF1,0x74,0x6C,0x08,
420 0xCA,0x18,0x21,0x7C,0x32,0x90,0x5E,0x46,0x2E,0x36,0xCE,0x3B,
421 0xE3,0x9E,0x77,0x2C,0x18,0x0E,0x86,0x03,0x9B,0x27,0x83,0xA2,
422 0xEC,0x07,0xA2,0x8F,0xB5,0xC5,0x5D,0xF0,0x6F,0x4C,0x52,0xC9,
423 0xDE,0x2B,0xCB,0xF6,0x95,0x58,0x17,0x18,0x39,0x95,0x49,0x7C,
424 0xEA,0x95,0x6A,0xE5,0x15,0xD2,0x26,0x18,0x98,0xFA,0x05,0x10,
425 0x15,0x72,0x8E,0x5A,0x8A,0xAA,0xC4,0x2D,0xAD,0x33,0x17,0x0D,
426 0x04,0x50,0x7A,0x33,0xA8,0x55,0x21,0xAB,0xDF,0x1C,0xBA,0x64,
427 0xEC,0xFB,0x85,0x04,0x58,0xDB,0xEF,0x0A,0x8A,0xEA,0x71,0x57,
428 0x5D,0x06,0x0C,0x7D,0xB3,0x97,0x0F,0x85,0xA6,0xE1,0xE4,0xC7,
429 0xAB,0xF5,0xAE,0x8C,0xDB,0x09,0x33,0xD7,0x1E,0x8C,0x94,0xE0,
430 0x4A,0x25,0x61,0x9D,0xCE,0xE3,0xD2,0x26,0x1A,0xD2,0xEE,0x6B,
431 0xF1,0x2F,0xFA,0x06,0xD9,0x8A,0x08,0x64,0xD8,0x76,0x02,0x73,
432 0x3E,0xC8,0x6A,0x64,0x52,0x1F,0x2B,0x18,0x17,0x7B,0x20,0x0C,
433 0xBB,0xE1,0x17,0x57,0x7A,0x61,0x5D,0x6C,0x77,0x09,0x88,0xC0,
434 0xBA,0xD9,0x46,0xE2,0x08,0xE2,0x4F,0xA0,0x74,0xE5,0xAB,0x31,
435 0x43,0xDB,0x5B,0xFC,0xE0,0xFD,0x10,0x8E,0x4B,0x82,0xD1,0x20,
436 0xA9,0x21,0x08,0x01,0x1A,0x72,0x3C,0x12,0xA7,0x87,0xE6,0xD7,
437 0x88,0x71,0x9A,0x10,0xBD,0xBA,0x5B,0x26,0x99,0xC3,0x27,0x18,
438 0x6A,0xF4,0xE2,0x3C,0x1A,0x94,0x68,0x34,0xB6,0x15,0x0B,0xDA,
439 0x25,0x83,0xE9,0xCA,0x2A,0xD4,0x4C,0xE8,0xDB,0xBB,0xC2,0xDB,
440 0x04,0xDE,0x8E,0xF9,0x2E,0x8E,0xFC,0x14,0x1F,0xBE,0xCA,0xA6,
441 0x28,0x7C,0x59,0x47,0x4E,0x6B,0xC0,0x5D,0x99,0xB2,0x96,0x4F,
442 0xA0,0x90,0xC3,0xA2,0x23,0x3B,0xA1,0x86,0x51,0x5B,0xE7,0xED,
443 0x1F,0x61,0x29,0x70,0xCE,0xE2,0xD7,0xAF,0xB8,0x1B,0xDD,0x76,
444 0x21,0x70,0x48,0x1C,0xD0,0x06,0x91,0x27,0xD5,0xB0,0x5A,0xA9,
445 0x93,0xB4,0xEA,0x98,0x8D,0x8F,0xDD,0xC1,0x86,0xFF,0xB7,0xDC,
446 0x90,0xA6,0xC0,0x8F,0x4D,0xF4,0x35,0xC9,0x34,0x06,0x31,0x99,
447 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
448 };
449#endif
450 DH *dh = DH_new();
451 if (dh) {
452#if OPENSSL_VERSION_NUMBER >= 0x0090801fL
453 dh->p = get_rfc3526_prime_4096(NULL);
454#else
455 dh->p = BN_bin2bn(rfc_3526_prime_4096, sizeof rfc_3526_prime_4096, NULL);
456#endif
457 /* See RFC 3526, Section 5 "4096-bit MODP Group"
458 for the reason why 2 is used as generator.
459 */
460 BN_dec2bn(&dh->g, "2");
461 if (!dh->p || !dh->g) {
462 DH_free(dh);
463 dh = NULL;
464 }
465 }
466 return dh;
467}
468
469static DH *ssl_get_dh_8192(void)
470{
471#if OPENSSL_VERSION_NUMBER < 0x0090801fL
472 static const unsigned char rfc_3526_prime_8192[] = {
473 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xC9,0x0F,0xDA,0xA2,
474 0x21,0x68,0xC2,0x34,0xC4,0xC6,0x62,0x8B,0x80,0xDC,0x1C,0xD1,
475 0x29,0x02,0x4E,0x08,0x8A,0x67,0xCC,0x74,0x02,0x0B,0xBE,0xA6,
476 0x3B,0x13,0x9B,0x22,0x51,0x4A,0x08,0x79,0x8E,0x34,0x04,0xDD,
477 0xEF,0x95,0x19,0xB3,0xCD,0x3A,0x43,0x1B,0x30,0x2B,0x0A,0x6D,
478 0xF2,0x5F,0x14,0x37,0x4F,0xE1,0x35,0x6D,0x6D,0x51,0xC2,0x45,
479 0xE4,0x85,0xB5,0x76,0x62,0x5E,0x7E,0xC6,0xF4,0x4C,0x42,0xE9,
480 0xA6,0x37,0xED,0x6B,0x0B,0xFF,0x5C,0xB6,0xF4,0x06,0xB7,0xED,
481 0xEE,0x38,0x6B,0xFB,0x5A,0x89,0x9F,0xA5,0xAE,0x9F,0x24,0x11,
482 0x7C,0x4B,0x1F,0xE6,0x49,0x28,0x66,0x51,0xEC,0xE4,0x5B,0x3D,
483 0xC2,0x00,0x7C,0xB8,0xA1,0x63,0xBF,0x05,0x98,0xDA,0x48,0x36,
484 0x1C,0x55,0xD3,0x9A,0x69,0x16,0x3F,0xA8,0xFD,0x24,0xCF,0x5F,
485 0x83,0x65,0x5D,0x23,0xDC,0xA3,0xAD,0x96,0x1C,0x62,0xF3,0x56,
486 0x20,0x85,0x52,0xBB,0x9E,0xD5,0x29,0x07,0x70,0x96,0x96,0x6D,
487 0x67,0x0C,0x35,0x4E,0x4A,0xBC,0x98,0x04,0xF1,0x74,0x6C,0x08,
488 0xCA,0x18,0x21,0x7C,0x32,0x90,0x5E,0x46,0x2E,0x36,0xCE,0x3B,
489 0xE3,0x9E,0x77,0x2C,0x18,0x0E,0x86,0x03,0x9B,0x27,0x83,0xA2,
490 0xEC,0x07,0xA2,0x8F,0xB5,0xC5,0x5D,0xF0,0x6F,0x4C,0x52,0xC9,
491 0xDE,0x2B,0xCB,0xF6,0x95,0x58,0x17,0x18,0x39,0x95,0x49,0x7C,
492 0xEA,0x95,0x6A,0xE5,0x15,0xD2,0x26,0x18,0x98,0xFA,0x05,0x10,
493 0x15,0x72,0x8E,0x5A,0x8A,0xAA,0xC4,0x2D,0xAD,0x33,0x17,0x0D,
494 0x04,0x50,0x7A,0x33,0xA8,0x55,0x21,0xAB,0xDF,0x1C,0xBA,0x64,
495 0xEC,0xFB,0x85,0x04,0x58,0xDB,0xEF,0x0A,0x8A,0xEA,0x71,0x57,
496 0x5D,0x06,0x0C,0x7D,0xB3,0x97,0x0F,0x85,0xA6,0xE1,0xE4,0xC7,
497 0xAB,0xF5,0xAE,0x8C,0xDB,0x09,0x33,0xD7,0x1E,0x8C,0x94,0xE0,
498 0x4A,0x25,0x61,0x9D,0xCE,0xE3,0xD2,0x26,0x1A,0xD2,0xEE,0x6B,
499 0xF1,0x2F,0xFA,0x06,0xD9,0x8A,0x08,0x64,0xD8,0x76,0x02,0x73,
500 0x3E,0xC8,0x6A,0x64,0x52,0x1F,0x2B,0x18,0x17,0x7B,0x20,0x0C,
501 0xBB,0xE1,0x17,0x57,0x7A,0x61,0x5D,0x6C,0x77,0x09,0x88,0xC0,
502 0xBA,0xD9,0x46,0xE2,0x08,0xE2,0x4F,0xA0,0x74,0xE5,0xAB,0x31,
503 0x43,0xDB,0x5B,0xFC,0xE0,0xFD,0x10,0x8E,0x4B,0x82,0xD1,0x20,
504 0xA9,0x21,0x08,0x01,0x1A,0x72,0x3C,0x12,0xA7,0x87,0xE6,0xD7,
505 0x88,0x71,0x9A,0x10,0xBD,0xBA,0x5B,0x26,0x99,0xC3,0x27,0x18,
506 0x6A,0xF4,0xE2,0x3C,0x1A,0x94,0x68,0x34,0xB6,0x15,0x0B,0xDA,
507 0x25,0x83,0xE9,0xCA,0x2A,0xD4,0x4C,0xE8,0xDB,0xBB,0xC2,0xDB,
508 0x04,0xDE,0x8E,0xF9,0x2E,0x8E,0xFC,0x14,0x1F,0xBE,0xCA,0xA6,
509 0x28,0x7C,0x59,0x47,0x4E,0x6B,0xC0,0x5D,0x99,0xB2,0x96,0x4F,
510 0xA0,0x90,0xC3,0xA2,0x23,0x3B,0xA1,0x86,0x51,0x5B,0xE7,0xED,
511 0x1F,0x61,0x29,0x70,0xCE,0xE2,0xD7,0xAF,0xB8,0x1B,0xDD,0x76,
512 0x21,0x70,0x48,0x1C,0xD0,0x06,0x91,0x27,0xD5,0xB0,0x5A,0xA9,
513 0x93,0xB4,0xEA,0x98,0x8D,0x8F,0xDD,0xC1,0x86,0xFF,0xB7,0xDC,
514 0x90,0xA6,0xC0,0x8F,0x4D,0xF4,0x35,0xC9,0x34,0x02,0x84,0x92,
515 0x36,0xC3,0xFA,0xB4,0xD2,0x7C,0x70,0x26,0xC1,0xD4,0xDC,0xB2,
516 0x60,0x26,0x46,0xDE,0xC9,0x75,0x1E,0x76,0x3D,0xBA,0x37,0xBD,
517 0xF8,0xFF,0x94,0x06,0xAD,0x9E,0x53,0x0E,0xE5,0xDB,0x38,0x2F,
518 0x41,0x30,0x01,0xAE,0xB0,0x6A,0x53,0xED,0x90,0x27,0xD8,0x31,
519 0x17,0x97,0x27,0xB0,0x86,0x5A,0x89,0x18,0xDA,0x3E,0xDB,0xEB,
520 0xCF,0x9B,0x14,0xED,0x44,0xCE,0x6C,0xBA,0xCE,0xD4,0xBB,0x1B,
521 0xDB,0x7F,0x14,0x47,0xE6,0xCC,0x25,0x4B,0x33,0x20,0x51,0x51,
522 0x2B,0xD7,0xAF,0x42,0x6F,0xB8,0xF4,0x01,0x37,0x8C,0xD2,0xBF,
523 0x59,0x83,0xCA,0x01,0xC6,0x4B,0x92,0xEC,0xF0,0x32,0xEA,0x15,
524 0xD1,0x72,0x1D,0x03,0xF4,0x82,0xD7,0xCE,0x6E,0x74,0xFE,0xF6,
525 0xD5,0x5E,0x70,0x2F,0x46,0x98,0x0C,0x82,0xB5,0xA8,0x40,0x31,
526 0x90,0x0B,0x1C,0x9E,0x59,0xE7,0xC9,0x7F,0xBE,0xC7,0xE8,0xF3,
527 0x23,0xA9,0x7A,0x7E,0x36,0xCC,0x88,0xBE,0x0F,0x1D,0x45,0xB7,
528 0xFF,0x58,0x5A,0xC5,0x4B,0xD4,0x07,0xB2,0x2B,0x41,0x54,0xAA,
529 0xCC,0x8F,0x6D,0x7E,0xBF,0x48,0xE1,0xD8,0x14,0xCC,0x5E,0xD2,
530 0x0F,0x80,0x37,0xE0,0xA7,0x97,0x15,0xEE,0xF2,0x9B,0xE3,0x28,
531 0x06,0xA1,0xD5,0x8B,0xB7,0xC5,0xDA,0x76,0xF5,0x50,0xAA,0x3D,
532 0x8A,0x1F,0xBF,0xF0,0xEB,0x19,0xCC,0xB1,0xA3,0x13,0xD5,0x5C,
533 0xDA,0x56,0xC9,0xEC,0x2E,0xF2,0x96,0x32,0x38,0x7F,0xE8,0xD7,
534 0x6E,0x3C,0x04,0x68,0x04,0x3E,0x8F,0x66,0x3F,0x48,0x60,0xEE,
535 0x12,0xBF,0x2D,0x5B,0x0B,0x74,0x74,0xD6,0xE6,0x94,0xF9,0x1E,
536 0x6D,0xBE,0x11,0x59,0x74,0xA3,0x92,0x6F,0x12,0xFE,0xE5,0xE4,
537 0x38,0x77,0x7C,0xB6,0xA9,0x32,0xDF,0x8C,0xD8,0xBE,0xC4,0xD0,
538 0x73,0xB9,0x31,0xBA,0x3B,0xC8,0x32,0xB6,0x8D,0x9D,0xD3,0x00,
539 0x74,0x1F,0xA7,0xBF,0x8A,0xFC,0x47,0xED,0x25,0x76,0xF6,0x93,
540 0x6B,0xA4,0x24,0x66,0x3A,0xAB,0x63,0x9C,0x5A,0xE4,0xF5,0x68,
541 0x34,0x23,0xB4,0x74,0x2B,0xF1,0xC9,0x78,0x23,0x8F,0x16,0xCB,
542 0xE3,0x9D,0x65,0x2D,0xE3,0xFD,0xB8,0xBE,0xFC,0x84,0x8A,0xD9,
543 0x22,0x22,0x2E,0x04,0xA4,0x03,0x7C,0x07,0x13,0xEB,0x57,0xA8,
544 0x1A,0x23,0xF0,0xC7,0x34,0x73,0xFC,0x64,0x6C,0xEA,0x30,0x6B,
545 0x4B,0xCB,0xC8,0x86,0x2F,0x83,0x85,0xDD,0xFA,0x9D,0x4B,0x7F,
546 0xA2,0xC0,0x87,0xE8,0x79,0x68,0x33,0x03,0xED,0x5B,0xDD,0x3A,
547 0x06,0x2B,0x3C,0xF5,0xB3,0xA2,0x78,0xA6,0x6D,0x2A,0x13,0xF8,
548 0x3F,0x44,0xF8,0x2D,0xDF,0x31,0x0E,0xE0,0x74,0xAB,0x6A,0x36,
549 0x45,0x97,0xE8,0x99,0xA0,0x25,0x5D,0xC1,0x64,0xF3,0x1C,0xC5,
550 0x08,0x46,0x85,0x1D,0xF9,0xAB,0x48,0x19,0x5D,0xED,0x7E,0xA1,
551 0xB1,0xD5,0x10,0xBD,0x7E,0xE7,0x4D,0x73,0xFA,0xF3,0x6B,0xC3,
552 0x1E,0xCF,0xA2,0x68,0x35,0x90,0x46,0xF4,0xEB,0x87,0x9F,0x92,
553 0x40,0x09,0x43,0x8B,0x48,0x1C,0x6C,0xD7,0x88,0x9A,0x00,0x2E,
554 0xD5,0xEE,0x38,0x2B,0xC9,0x19,0x0D,0xA6,0xFC,0x02,0x6E,0x47,
555 0x95,0x58,0xE4,0x47,0x56,0x77,0xE9,0xAA,0x9E,0x30,0x50,0xE2,
556 0x76,0x56,0x94,0xDF,0xC8,0x1F,0x56,0xE8,0x80,0xB9,0x6E,0x71,
557 0x60,0xC9,0x80,0xDD,0x98,0xED,0xD3,0xDF,0xFF,0xFF,0xFF,0xFF,
558 0xFF,0xFF,0xFF,0xFF,
559 };
560#endif
561 DH *dh = DH_new();
562 if (dh) {
563#if OPENSSL_VERSION_NUMBER >= 0x0090801fL
564 dh->p = get_rfc3526_prime_8192(NULL);
565#else
566 dh->p = BN_bin2bn(rfc_3526_prime_8192, sizeof rfc_3526_prime_8192, NULL);
567#endif
568 /* See RFC 3526, Section 7 "8192-bit MODP Group"
569 for the reason why 2 is used as generator.
570 */
571 BN_dec2bn(&dh->g, "2");
572 if (!dh->p || !dh->g) {
573 DH_free(dh);
574 dh = NULL;
575 }
576 }
577 return dh;
578}
579
580/* Returns Diffie-Hellman parameters matching the private key length
581 but not exceeding global.tune.ssl_default_dh_param */
582static DH *ssl_get_tmp_dh(SSL *ssl, int export, int keylen)
583{
584 DH *dh = NULL;
585 EVP_PKEY *pkey = SSL_get_privatekey(ssl);
586 int type = pkey ? EVP_PKEY_type(pkey->type) : EVP_PKEY_NONE;
587
588 /* The keylen supplied by OpenSSL can only be 512 or 1024.
589 See ssl3_send_server_key_exchange() in ssl/s3_srvr.c
590 */
591 if (type == EVP_PKEY_RSA || type == EVP_PKEY_DSA) {
592 keylen = EVP_PKEY_bits(pkey);
593 }
594
595 if (keylen > global.tune.ssl_default_dh_param) {
596 keylen = global.tune.ssl_default_dh_param;
597 }
598
599 if (keylen >= 8192) {
600 dh = ssl_get_dh_8192();
601 }
602 else if (keylen >= 4096) {
603 dh = ssl_get_dh_4096();
604 }
605 else if (keylen >= 2048) {
606 dh = ssl_get_dh_2048();
607 }
608 else {
609 dh = ssl_get_dh_1024();
610 }
611
612 return dh;
613}
614
Emeric Bruna4bcd9a2012-09-20 16:19:02 +0200615/* Loads Diffie-Hellman parameter from a file. Returns 1 if loaded, else -1
616 if an error occured, and 0 if parameter not found. */
Willy Tarreau6e774b42014-04-25 21:35:23 +0200617int ssl_sock_load_dh_params(SSL_CTX *ctx, const char *file)
Emeric Bruna4bcd9a2012-09-20 16:19:02 +0200618{
619 int ret = -1;
620 BIO *in;
621 DH *dh = NULL;
622
623 in = BIO_new(BIO_s_file());
624 if (in == NULL)
625 goto end;
626
627 if (BIO_read_filename(in, file) <= 0)
628 goto end;
629
630 dh = PEM_read_bio_DHparams(in, NULL, ctx->default_passwd_callback, ctx->default_passwd_callback_userdata);
Remi Gacognef46cd6e2014-06-12 14:58:40 +0200631 if (dh) {
632 ret = 1;
633 SSL_CTX_set_tmp_dh(ctx, dh);
634 /* Setting ssl default dh param to the size of the static DH params
635 found in the file. This way we know that there is no use
636 complaining later about ssl-default-dh-param not being set. */
637 global.tune.ssl_default_dh_param = DH_size(dh) * 8;
638 }
639 else {
Emeric Brun41fdb3c2013-04-26 11:05:44 +0200640 /* Clear openssl global errors stack */
641 ERR_clear_error();
642
Remi Gacognef46cd6e2014-06-12 14:58:40 +0200643 if (global.tune.ssl_default_dh_param <= 1024) {
644 /* we are limited to DH parameter of 1024 bits anyway */
645 dh = ssl_get_dh_1024();
646 if (dh == NULL)
647 goto end;
Willy Tarreau6e774b42014-04-25 21:35:23 +0200648
Remi Gacognef46cd6e2014-06-12 14:58:40 +0200649 SSL_CTX_set_tmp_dh(ctx, dh);
650 }
651 else {
652 SSL_CTX_set_tmp_dh_callback(ctx, ssl_get_tmp_dh);
653 }
Willy Tarreau6e774b42014-04-25 21:35:23 +0200654
Emeric Brun41fdb3c2013-04-26 11:05:44 +0200655 ret = 0; /* DH params not found */
Emeric Bruna4bcd9a2012-09-20 16:19:02 +0200656 }
Emeric Brun644cde02012-12-14 11:21:13 +0100657
Emeric Bruna4bcd9a2012-09-20 16:19:02 +0200658end:
659 if (dh)
660 DH_free(dh);
661
662 if (in)
Emeric Brun41fdb3c2013-04-26 11:05:44 +0200663 BIO_free(in);
Emeric Bruna4bcd9a2012-09-20 16:19:02 +0200664
665 return ret;
666}
667#endif
668
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +0200669static int ssl_sock_add_cert_sni(SSL_CTX *ctx, struct bind_conf *s, char *name, int order)
Emmanuel Hocdetfe616562013-01-22 15:31:15 +0100670{
671 struct sni_ctx *sc;
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +0200672 int wild = 0, neg = 0;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +0100673
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +0200674 if (*name == '!') {
675 neg = 1;
676 name++;
677 }
678 if (*name == '*') {
679 wild = 1;
680 name++;
681 }
682 /* !* filter is a nop */
683 if (neg && wild)
684 return order;
685 if (*name) {
686 int j, len;
687 len = strlen(name);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +0100688 sc = malloc(sizeof(struct sni_ctx) + len + 1);
689 for (j = 0; j < len; j++)
690 sc->name.key[j] = tolower(name[j]);
691 sc->name.key[len] = 0;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +0100692 sc->ctx = ctx;
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +0200693 sc->order = order++;
694 sc->neg = neg;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +0100695 if (wild)
696 ebst_insert(&s->sni_w_ctx, &sc->name);
697 else
698 ebst_insert(&s->sni_ctx, &sc->name);
699 }
700 return order;
701}
702
Emeric Brunfc0421f2012-09-07 17:30:07 +0200703/* Loads a certificate key and CA chain from a file. Returns 0 on error, -1 if
704 * an early error happens and the caller must call SSL_CTX_free() by itelf.
705 */
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +0200706static 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 +0200707{
708 BIO *in;
709 X509 *x = NULL, *ca;
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +0200710 int i, err;
Emeric Brunfc0421f2012-09-07 17:30:07 +0200711 int ret = -1;
712 int order = 0;
713 X509_NAME *xname;
714 char *str;
Emeric Brunfc0421f2012-09-07 17:30:07 +0200715#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
716 STACK_OF(GENERAL_NAME) *names;
717#endif
718
719 in = BIO_new(BIO_s_file());
720 if (in == NULL)
721 goto end;
722
723 if (BIO_read_filename(in, file) <= 0)
724 goto end;
725
726 x = PEM_read_bio_X509_AUX(in, NULL, ctx->default_passwd_callback, ctx->default_passwd_callback_userdata);
727 if (x == NULL)
728 goto end;
729
Emeric Brun50bcecc2013-04-22 13:05:23 +0200730 if (fcount) {
731 while (fcount--)
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +0200732 order = ssl_sock_add_cert_sni(ctx, s, sni_filter[fcount], order);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +0100733 }
734 else {
Emeric Brunfc0421f2012-09-07 17:30:07 +0200735#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Emmanuel Hocdetfe616562013-01-22 15:31:15 +0100736 names = X509_get_ext_d2i(x, NID_subject_alt_name, NULL, NULL);
737 if (names) {
738 for (i = 0; i < sk_GENERAL_NAME_num(names); i++) {
739 GENERAL_NAME *name = sk_GENERAL_NAME_value(names, i);
740 if (name->type == GEN_DNS) {
741 if (ASN1_STRING_to_UTF8((unsigned char **)&str, name->d.dNSName) >= 0) {
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +0200742 order = ssl_sock_add_cert_sni(ctx, s, str, order);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +0100743 OPENSSL_free(str);
Emeric Brunfc0421f2012-09-07 17:30:07 +0200744 }
Emeric Brunfc0421f2012-09-07 17:30:07 +0200745 }
746 }
Emmanuel Hocdetfe616562013-01-22 15:31:15 +0100747 sk_GENERAL_NAME_pop_free(names, GENERAL_NAME_free);
Emeric Brunfc0421f2012-09-07 17:30:07 +0200748 }
Emeric Brunfc0421f2012-09-07 17:30:07 +0200749#endif /* SSL_CTRL_SET_TLSEXT_HOSTNAME */
Emmanuel Hocdetfe616562013-01-22 15:31:15 +0100750 xname = X509_get_subject_name(x);
751 i = -1;
752 while ((i = X509_NAME_get_index_by_NID(xname, NID_commonName, i)) != -1) {
753 X509_NAME_ENTRY *entry = X509_NAME_get_entry(xname, i);
754 if (ASN1_STRING_to_UTF8((unsigned char **)&str, entry->value) >= 0) {
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +0200755 order = ssl_sock_add_cert_sni(ctx, s, str, order);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +0100756 OPENSSL_free(str);
Emeric Brunfc0421f2012-09-07 17:30:07 +0200757 }
Emeric Brunfc0421f2012-09-07 17:30:07 +0200758 }
759 }
760
761 ret = 0; /* the caller must not free the SSL_CTX argument anymore */
762 if (!SSL_CTX_use_certificate(ctx, x))
763 goto end;
764
765 if (ctx->extra_certs != NULL) {
766 sk_X509_pop_free(ctx->extra_certs, X509_free);
767 ctx->extra_certs = NULL;
768 }
769
770 while ((ca = PEM_read_bio_X509(in, NULL, ctx->default_passwd_callback, ctx->default_passwd_callback_userdata))) {
771 if (!SSL_CTX_add_extra_chain_cert(ctx, ca)) {
772 X509_free(ca);
773 goto end;
774 }
775 }
776
777 err = ERR_get_error();
778 if (!err || (ERR_GET_LIB(err) == ERR_LIB_PEM && ERR_GET_REASON(err) == PEM_R_NO_START_LINE)) {
779 /* we successfully reached the last cert in the file */
780 ret = 1;
781 }
782 ERR_clear_error();
783
784end:
785 if (x)
786 X509_free(x);
787
788 if (in)
789 BIO_free(in);
790
791 return ret;
792}
793
Emeric Brun50bcecc2013-04-22 13:05:23 +0200794static 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 +0200795{
796 int ret;
797 SSL_CTX *ctx;
798
799 ctx = SSL_CTX_new(SSLv23_server_method());
800 if (!ctx) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +0200801 memprintf(err, "%sunable to allocate SSL context for cert '%s'.\n",
802 err && *err ? *err : "", path);
Emeric Brunfc0421f2012-09-07 17:30:07 +0200803 return 1;
804 }
805
806 if (SSL_CTX_use_PrivateKey_file(ctx, path, SSL_FILETYPE_PEM) <= 0) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +0200807 memprintf(err, "%sunable to load SSL private key from PEM file '%s'.\n",
808 err && *err ? *err : "", path);
Emeric Brunfc0421f2012-09-07 17:30:07 +0200809 SSL_CTX_free(ctx);
810 return 1;
811 }
812
Emeric Brun50bcecc2013-04-22 13:05:23 +0200813 ret = ssl_sock_load_cert_chain_file(ctx, path, bind_conf, sni_filter, fcount);
Emeric Brunfc0421f2012-09-07 17:30:07 +0200814 if (ret <= 0) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +0200815 memprintf(err, "%sunable to load SSL certificate from PEM file '%s'.\n",
816 err && *err ? *err : "", path);
Emeric Brunfc0421f2012-09-07 17:30:07 +0200817 if (ret < 0) /* serious error, must do that ourselves */
818 SSL_CTX_free(ctx);
819 return 1;
820 }
Emeric Brun61694ab2012-10-26 13:35:33 +0200821
822 if (SSL_CTX_check_private_key(ctx) <= 0) {
823 memprintf(err, "%sinconsistencies between private key and certificate loaded from PEM file '%s'.\n",
824 err && *err ? *err : "", path);
825 return 1;
826 }
827
Emeric Brunfc0421f2012-09-07 17:30:07 +0200828 /* we must not free the SSL_CTX anymore below, since it's already in
829 * the tree, so it will be discovered and cleaned in time.
830 */
Emeric Bruna4bcd9a2012-09-20 16:19:02 +0200831#ifndef OPENSSL_NO_DH
832 ret = ssl_sock_load_dh_params(ctx, path);
833 if (ret < 0) {
834 if (err)
835 memprintf(err, "%sunable to load DH parameters from file '%s'.\n",
836 *err ? *err : "", path);
837 return 1;
838 }
839#endif
840
Emeric Brunfc0421f2012-09-07 17:30:07 +0200841#ifndef SSL_CTRL_SET_TLSEXT_HOSTNAME
Willy Tarreau2a65ff02012-09-13 17:54:29 +0200842 if (bind_conf->default_ctx) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +0200843 memprintf(err, "%sthis version of openssl cannot load multiple SSL certificates.\n",
844 err && *err ? *err : "");
Emeric Brunfc0421f2012-09-07 17:30:07 +0200845 return 1;
846 }
847#endif
Willy Tarreau2a65ff02012-09-13 17:54:29 +0200848 if (!bind_conf->default_ctx)
849 bind_conf->default_ctx = ctx;
Emeric Brunfc0421f2012-09-07 17:30:07 +0200850
851 return 0;
852}
853
Willy Tarreau79eeafa2012-09-14 07:53:05 +0200854int ssl_sock_load_cert(char *path, struct bind_conf *bind_conf, struct proxy *curproxy, char **err)
Emeric Brunfc0421f2012-09-07 17:30:07 +0200855{
856 struct dirent *de;
857 DIR *dir;
858 struct stat buf;
Willy Tarreauee2663b2012-12-06 11:36:59 +0100859 char *end;
860 char fp[MAXPATHLEN+1];
Emeric Brunfc0421f2012-09-07 17:30:07 +0200861 int cfgerr = 0;
862
863 if (!(dir = opendir(path)))
Emeric Brun50bcecc2013-04-22 13:05:23 +0200864 return ssl_sock_load_cert_file(path, bind_conf, curproxy, NULL, 0, err);
Emeric Brunfc0421f2012-09-07 17:30:07 +0200865
866 /* strip trailing slashes, including first one */
867 for (end = path + strlen(path) - 1; end >= path && *end == '/'; end--)
868 *end = 0;
869
Emeric Brunfc0421f2012-09-07 17:30:07 +0200870 while ((de = readdir(dir))) {
Willy Tarreauee2663b2012-12-06 11:36:59 +0100871 snprintf(fp, sizeof(fp), "%s/%s", path, de->d_name);
Emeric Brunfc0421f2012-09-07 17:30:07 +0200872 if (stat(fp, &buf) != 0) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +0200873 memprintf(err, "%sunable to stat SSL certificate from file '%s' : %s.\n",
874 err && *err ? *err : "", fp, strerror(errno));
Emeric Brunfc0421f2012-09-07 17:30:07 +0200875 cfgerr++;
876 continue;
877 }
878 if (!S_ISREG(buf.st_mode))
879 continue;
Emeric Brun50bcecc2013-04-22 13:05:23 +0200880 cfgerr += ssl_sock_load_cert_file(fp, bind_conf, curproxy, NULL, 0, err);
Emeric Brunfc0421f2012-09-07 17:30:07 +0200881 }
Emeric Brunfc0421f2012-09-07 17:30:07 +0200882 closedir(dir);
883 return cfgerr;
884}
885
Thierry Fournier383085f2013-01-24 14:15:43 +0100886/* Make sure openssl opens /dev/urandom before the chroot. The work is only
887 * done once. Zero is returned if the operation fails. No error is returned
888 * if the random is said as not implemented, because we expect that openssl
889 * will use another method once needed.
890 */
891static int ssl_initialize_random()
892{
893 unsigned char random;
894 static int random_initialized = 0;
895
896 if (!random_initialized && RAND_bytes(&random, 1) != 0)
897 random_initialized = 1;
898
899 return random_initialized;
900}
901
Emmanuel Hocdetfe616562013-01-22 15:31:15 +0100902int ssl_sock_load_cert_list_file(char *file, struct bind_conf *bind_conf, struct proxy *curproxy, char **err)
903{
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +0200904 char thisline[LINESIZE];
Emmanuel Hocdetfe616562013-01-22 15:31:15 +0100905 FILE *f;
906 int linenum = 0;
907 int cfgerr = 0;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +0100908
Willy Tarreauad1731d2013-04-02 17:35:58 +0200909 if ((f = fopen(file, "r")) == NULL) {
910 memprintf(err, "cannot open file '%s' : %s", file, strerror(errno));
Emmanuel Hocdetfe616562013-01-22 15:31:15 +0100911 return 1;
Willy Tarreauad1731d2013-04-02 17:35:58 +0200912 }
Emmanuel Hocdetfe616562013-01-22 15:31:15 +0100913
914 while (fgets(thisline, sizeof(thisline), f) != NULL) {
915 int arg;
Emeric Brun50bcecc2013-04-22 13:05:23 +0200916 int newarg;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +0100917 char *end;
918 char *args[MAX_LINE_ARGS + 1];
919 char *line = thisline;
920
921 linenum++;
922 end = line + strlen(line);
923 if (end-line == sizeof(thisline)-1 && *(end-1) != '\n') {
924 /* Check if we reached the limit and the last char is not \n.
925 * Watch out for the last line without the terminating '\n'!
926 */
Willy Tarreauad1731d2013-04-02 17:35:58 +0200927 memprintf(err, "line %d too long in file '%s', limit is %d characters",
928 linenum, file, (int)sizeof(thisline)-1);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +0100929 cfgerr = 1;
Willy Tarreauad1731d2013-04-02 17:35:58 +0200930 break;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +0100931 }
932
Emmanuel Hocdetfe616562013-01-22 15:31:15 +0100933 arg = 0;
Emeric Brun50bcecc2013-04-22 13:05:23 +0200934 newarg = 1;
935 while (*line) {
Emmanuel Hocdetfe616562013-01-22 15:31:15 +0100936 if (*line == '#' || *line == '\n' || *line == '\r') {
937 /* end of string, end of loop */
938 *line = 0;
939 break;
940 }
941 else if (isspace(*line)) {
Emeric Brun50bcecc2013-04-22 13:05:23 +0200942 newarg = 1;
943 *line = 0;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +0100944 }
Emeric Brun50bcecc2013-04-22 13:05:23 +0200945 else if (newarg) {
946 if (arg == MAX_LINE_ARGS) {
947 memprintf(err, "too many args on line %d in file '%s'.",
948 linenum, file);
949 cfgerr = 1;
950 break;
951 }
952 newarg = 0;
953 args[arg++] = line;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +0100954 }
Emeric Brun50bcecc2013-04-22 13:05:23 +0200955 line++;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +0100956 }
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +0200957 if (cfgerr)
958 break;
Willy Tarreauad1731d2013-04-02 17:35:58 +0200959
Emmanuel Hocdetfe616562013-01-22 15:31:15 +0100960 /* empty line */
Emeric Brun50bcecc2013-04-22 13:05:23 +0200961 if (!arg)
Emmanuel Hocdetfe616562013-01-22 15:31:15 +0100962 continue;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +0100963
Emeric Brun50bcecc2013-04-22 13:05:23 +0200964 cfgerr = ssl_sock_load_cert_file(args[0], bind_conf, curproxy, &args[1], arg-1, err);
Willy Tarreauad1731d2013-04-02 17:35:58 +0200965 if (cfgerr) {
966 memprintf(err, "error processing line %d in file '%s' : %s", linenum, file, *err);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +0100967 break;
Willy Tarreauad1731d2013-04-02 17:35:58 +0200968 }
Emmanuel Hocdetfe616562013-01-22 15:31:15 +0100969 }
Emmanuel Hocdetfe616562013-01-22 15:31:15 +0100970 fclose(f);
971 return cfgerr;
972}
973
Emeric Brunfc0421f2012-09-07 17:30:07 +0200974#ifndef SSL_OP_CIPHER_SERVER_PREFERENCE /* needs OpenSSL >= 0.9.7 */
975#define SSL_OP_CIPHER_SERVER_PREFERENCE 0
976#endif
977
978#ifndef SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION /* needs OpenSSL >= 0.9.7 */
979#define SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION 0
Willy Tarreau7d588ee2012-11-26 18:47:31 +0100980#define SSL_renegotiate_pending(arg) 0
Emeric Brunfc0421f2012-09-07 17:30:07 +0200981#endif
Emeric Brun2b58d042012-09-20 17:10:03 +0200982#ifndef SSL_OP_SINGLE_ECDH_USE /* needs OpenSSL >= 0.9.8 */
983#define SSL_OP_SINGLE_ECDH_USE 0
984#endif
Emeric Brun2d0c4822012-10-02 13:45:20 +0200985#ifndef SSL_OP_NO_TICKET /* needs OpenSSL >= 0.9.8 */
986#define SSL_OP_NO_TICKET 0
987#endif
Emeric Brunfc0421f2012-09-07 17:30:07 +0200988#ifndef SSL_OP_NO_COMPRESSION /* needs OpenSSL >= 0.9.9 */
989#define SSL_OP_NO_COMPRESSION 0
990#endif
Emeric Brunc0ff4922012-09-28 19:37:02 +0200991#ifndef SSL_OP_NO_TLSv1_1 /* needs OpenSSL >= 1.0.1 */
992#define SSL_OP_NO_TLSv1_1 0
993#endif
994#ifndef SSL_OP_NO_TLSv1_2 /* needs OpenSSL >= 1.0.1 */
995#define SSL_OP_NO_TLSv1_2 0
996#endif
Emeric Bruna4bcd9a2012-09-20 16:19:02 +0200997#ifndef SSL_OP_SINGLE_DH_USE /* needs OpenSSL >= 0.9.6 */
998#define SSL_OP_SINGLE_DH_USE 0
999#endif
Emeric Brun2b58d042012-09-20 17:10:03 +02001000#ifndef SSL_OP_SINGLE_ECDH_USE /* needs OpenSSL >= 1.0.0 */
1001#define SSL_OP_SINGLE_ECDH_USE 0
1002#endif
Emeric Brunfc0421f2012-09-07 17:30:07 +02001003#ifndef SSL_MODE_RELEASE_BUFFERS /* needs OpenSSL >= 1.0.0 */
1004#define SSL_MODE_RELEASE_BUFFERS 0
1005#endif
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001006
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001007int ssl_sock_prepare_ctx(struct bind_conf *bind_conf, SSL_CTX *ctx, struct proxy *curproxy)
Emeric Brunfc0421f2012-09-07 17:30:07 +02001008{
1009 int cfgerr = 0;
Emeric Brun850efd52014-01-29 12:24:34 +01001010 int verify = SSL_VERIFY_NONE;
Remi Gacogneaf5c3da2014-05-19 10:29:58 +02001011 long ssloptions =
Emeric Brunfc0421f2012-09-07 17:30:07 +02001012 SSL_OP_ALL | /* all known workarounds for bugs */
1013 SSL_OP_NO_SSLv2 |
1014 SSL_OP_NO_COMPRESSION |
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001015 SSL_OP_SINGLE_DH_USE |
Emeric Brun2b58d042012-09-20 17:10:03 +02001016 SSL_OP_SINGLE_ECDH_USE |
Emeric Brun3c4bc6e2012-10-04 18:44:19 +02001017 SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION |
1018 SSL_OP_CIPHER_SERVER_PREFERENCE;
Remi Gacogneaf5c3da2014-05-19 10:29:58 +02001019 long sslmode =
Emeric Brunfc0421f2012-09-07 17:30:07 +02001020 SSL_MODE_ENABLE_PARTIAL_WRITE |
1021 SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER |
1022 SSL_MODE_RELEASE_BUFFERS;
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001023 STACK_OF(SSL_CIPHER) * ciphers = NULL;
1024 SSL_CIPHER * cipher = NULL;
Remi Gacognec1eab8c2014-06-12 18:20:11 +02001025 char cipher_description[128];
1026 /* The description of ciphers using an Ephemeral Diffie Hellman key exchange
1027 contains " Kx=DH " or " Kx=DH(". Beware of " Kx=DH/",
1028 which is not ephemeral DH. */
1029 const char dhe_description[] = " Kx=DH ";
1030 const char dhe_export_description[] = " Kx=DH(";
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001031 int idx = 0;
1032 int dhe_found = 0;
Emeric Brunfc0421f2012-09-07 17:30:07 +02001033
Thierry Fournier383085f2013-01-24 14:15:43 +01001034 /* Make sure openssl opens /dev/urandom before the chroot */
1035 if (!ssl_initialize_random()) {
1036 Alert("OpenSSL random data generator initialization failed.\n");
1037 cfgerr++;
1038 }
1039
Emeric Brun89675492012-10-05 13:48:26 +02001040 if (bind_conf->ssl_options & BC_SSL_O_NO_SSLV3)
Emeric Brunfc0421f2012-09-07 17:30:07 +02001041 ssloptions |= SSL_OP_NO_SSLv3;
Emeric Brun89675492012-10-05 13:48:26 +02001042 if (bind_conf->ssl_options & BC_SSL_O_NO_TLSV10)
Emeric Brunfc0421f2012-09-07 17:30:07 +02001043 ssloptions |= SSL_OP_NO_TLSv1;
Emeric Brun89675492012-10-05 13:48:26 +02001044 if (bind_conf->ssl_options & BC_SSL_O_NO_TLSV11)
Emeric Brunc0ff4922012-09-28 19:37:02 +02001045 ssloptions |= SSL_OP_NO_TLSv1_1;
Emeric Brun89675492012-10-05 13:48:26 +02001046 if (bind_conf->ssl_options & BC_SSL_O_NO_TLSV12)
Emeric Brunc0ff4922012-09-28 19:37:02 +02001047 ssloptions |= SSL_OP_NO_TLSv1_2;
Emeric Brun89675492012-10-05 13:48:26 +02001048 if (bind_conf->ssl_options & BC_SSL_O_NO_TLS_TICKETS)
Emeric Brun2d0c4822012-10-02 13:45:20 +02001049 ssloptions |= SSL_OP_NO_TICKET;
Emeric Brun2cb7ae52012-10-05 14:14:21 +02001050 if (bind_conf->ssl_options & BC_SSL_O_USE_SSLV3)
1051 SSL_CTX_set_ssl_version(ctx, SSLv3_server_method());
1052 if (bind_conf->ssl_options & BC_SSL_O_USE_TLSV10)
1053 SSL_CTX_set_ssl_version(ctx, TLSv1_server_method());
1054#if SSL_OP_NO_TLSv1_1
1055 if (bind_conf->ssl_options & BC_SSL_O_USE_TLSV11)
1056 SSL_CTX_set_ssl_version(ctx, TLSv1_1_server_method());
1057#endif
1058#if SSL_OP_NO_TLSv1_2
1059 if (bind_conf->ssl_options & BC_SSL_O_USE_TLSV12)
1060 SSL_CTX_set_ssl_version(ctx, TLSv1_2_server_method());
1061#endif
Emeric Brunfc0421f2012-09-07 17:30:07 +02001062
1063 SSL_CTX_set_options(ctx, ssloptions);
1064 SSL_CTX_set_mode(ctx, sslmode);
Emeric Brun850efd52014-01-29 12:24:34 +01001065 switch (bind_conf->verify) {
1066 case SSL_SOCK_VERIFY_NONE:
1067 verify = SSL_VERIFY_NONE;
1068 break;
1069 case SSL_SOCK_VERIFY_OPTIONAL:
1070 verify = SSL_VERIFY_PEER;
1071 break;
1072 case SSL_SOCK_VERIFY_REQUIRED:
1073 verify = SSL_VERIFY_PEER|SSL_VERIFY_FAIL_IF_NO_PEER_CERT;
1074 break;
1075 }
1076 SSL_CTX_set_verify(ctx, verify, ssl_sock_bind_verifycbk);
1077 if (verify & SSL_VERIFY_PEER) {
Emeric Brunfb510ea2012-10-05 12:00:26 +02001078 if (bind_conf->ca_file) {
Emeric Brund94b3fe2012-09-20 18:23:56 +02001079 /* load CAfile to verify */
Emeric Brunfb510ea2012-10-05 12:00:26 +02001080 if (!SSL_CTX_load_verify_locations(ctx, bind_conf->ca_file, NULL)) {
Emeric Brund94b3fe2012-09-20 18:23:56 +02001081 Alert("Proxy '%s': unable to load CA file '%s' for bind '%s' at [%s:%d].\n",
Emeric Brunfb510ea2012-10-05 12:00:26 +02001082 curproxy->id, bind_conf->ca_file, bind_conf->arg, bind_conf->file, bind_conf->line);
Emeric Brund94b3fe2012-09-20 18:23:56 +02001083 cfgerr++;
1084 }
1085 /* set CA names fo client cert request, function returns void */
Emeric Brunfb510ea2012-10-05 12:00:26 +02001086 SSL_CTX_set_client_CA_list(ctx, SSL_load_client_CA_file(bind_conf->ca_file));
Emeric Brund94b3fe2012-09-20 18:23:56 +02001087 }
Emeric Brun850efd52014-01-29 12:24:34 +01001088 else {
1089 Alert("Proxy '%s': verify is enabled but no CA file specified for bind '%s' at [%s:%d].\n",
1090 curproxy->id, bind_conf->arg, bind_conf->file, bind_conf->line);
1091 cfgerr++;
1092 }
Emeric Brun051cdab2012-10-02 19:25:50 +02001093#ifdef X509_V_FLAG_CRL_CHECK
Emeric Brunfb510ea2012-10-05 12:00:26 +02001094 if (bind_conf->crl_file) {
Emeric Brund94b3fe2012-09-20 18:23:56 +02001095 X509_STORE *store = SSL_CTX_get_cert_store(ctx);
1096
Emeric Brunfb510ea2012-10-05 12:00:26 +02001097 if (!store || !X509_STORE_load_locations(store, bind_conf->crl_file, NULL)) {
Emeric Brund94b3fe2012-09-20 18:23:56 +02001098 Alert("Proxy '%s': unable to configure CRL file '%s' for bind '%s' at [%s:%d].\n",
Emeric Brunfb510ea2012-10-05 12:00:26 +02001099 curproxy->id, bind_conf->ca_file, bind_conf->arg, bind_conf->file, bind_conf->line);
Emeric Brund94b3fe2012-09-20 18:23:56 +02001100 cfgerr++;
1101 }
Emeric Brun561e5742012-10-02 15:20:55 +02001102 else {
1103 X509_STORE_set_flags(store, X509_V_FLAG_CRL_CHECK|X509_V_FLAG_CRL_CHECK_ALL);
1104 }
Emeric Brund94b3fe2012-09-20 18:23:56 +02001105 }
Emeric Brun051cdab2012-10-02 19:25:50 +02001106#endif
Emeric Brun644cde02012-12-14 11:21:13 +01001107 ERR_clear_error();
Emeric Brund94b3fe2012-09-20 18:23:56 +02001108 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02001109
Emeric Brun4f65bff2012-11-16 15:11:00 +01001110 if (global.tune.ssllifetime)
1111 SSL_CTX_set_timeout(ctx, global.tune.ssllifetime);
1112
Emeric Brunfc0421f2012-09-07 17:30:07 +02001113 shared_context_set_cache(ctx);
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001114 if (bind_conf->ciphers &&
1115 !SSL_CTX_set_cipher_list(ctx, bind_conf->ciphers)) {
Emeric Brunfc0421f2012-09-07 17:30:07 +02001116 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 +02001117 curproxy->id, bind_conf->ciphers, bind_conf->arg, bind_conf->file, bind_conf->line);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001118 cfgerr++;
1119 }
1120
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001121 /* If tune.ssl.default-dh-param has not been set and
1122 no static DH params were in the certificate file. */
1123 if (global.tune.ssl_default_dh_param == 0) {
1124 ciphers = ctx->cipher_list;
1125
1126 if (ciphers) {
1127 for (idx = 0; idx < sk_SSL_CIPHER_num(ciphers); idx++) {
1128 cipher = sk_SSL_CIPHER_value(ciphers, idx);
Remi Gacognec1eab8c2014-06-12 18:20:11 +02001129 if (SSL_CIPHER_description(cipher, cipher_description, sizeof (cipher_description)) == cipher_description) {
1130 if (strstr(cipher_description, dhe_description) != NULL ||
1131 strstr(cipher_description, dhe_export_description) != NULL) {
1132 dhe_found = 1;
1133 break;
1134 }
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001135 }
1136 }
1137
1138 if (dhe_found) {
1139 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");
1140 }
1141 }
1142
1143 global.tune.ssl_default_dh_param = 1024;
1144 }
1145
Emeric Brunfc0421f2012-09-07 17:30:07 +02001146 SSL_CTX_set_info_callback(ctx, ssl_sock_infocbk);
Willy Tarreau5cbe4ef2014-05-08 22:45:11 +02001147#if OPENSSL_VERSION_NUMBER >= 0x00907000L
Emeric Brun29f037d2014-04-25 19:05:36 +02001148 SSL_CTX_set_msg_callback(ctx, ssl_sock_msgcbk);
Willy Tarreau5cbe4ef2014-05-08 22:45:11 +02001149#endif
Emeric Brun29f037d2014-04-25 19:05:36 +02001150
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02001151#ifdef OPENSSL_NPN_NEGOTIATED
1152 if (bind_conf->npn_str)
1153 SSL_CTX_set_next_protos_advertised_cb(ctx, ssl_sock_advertise_npn_protos, bind_conf);
1154#endif
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01001155#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Willy Tarreauab861d32013-04-02 02:30:41 +02001156 if (bind_conf->alpn_str)
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01001157 SSL_CTX_set_alpn_select_cb(ctx, ssl_sock_advertise_alpn_protos, bind_conf);
Willy Tarreauab861d32013-04-02 02:30:41 +02001158#endif
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02001159
Emeric Brunfc0421f2012-09-07 17:30:07 +02001160#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
1161 SSL_CTX_set_tlsext_servername_callback(ctx, ssl_sock_switchctx_cbk);
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001162 SSL_CTX_set_tlsext_servername_arg(ctx, bind_conf);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001163#endif
Emeric Brun2b58d042012-09-20 17:10:03 +02001164#if defined(SSL_CTX_set_tmp_ecdh) && !defined(OPENSSL_NO_ECDH)
Emeric Brun6924ef82013-03-06 14:08:53 +01001165 {
Emeric Brun2b58d042012-09-20 17:10:03 +02001166 int i;
1167 EC_KEY *ecdh;
1168
Emeric Brun6924ef82013-03-06 14:08:53 +01001169 i = OBJ_sn2nid(bind_conf->ecdhe ? bind_conf->ecdhe : ECDHE_DEFAULT_CURVE);
Emeric Brun2b58d042012-09-20 17:10:03 +02001170 if (!i || ((ecdh = EC_KEY_new_by_curve_name(i)) == NULL)) {
1171 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 +01001172 curproxy->id, bind_conf->ecdhe ? bind_conf->ecdhe : ECDHE_DEFAULT_CURVE,
1173 bind_conf->arg, bind_conf->file, bind_conf->line);
Emeric Brun2b58d042012-09-20 17:10:03 +02001174 cfgerr++;
1175 }
1176 else {
1177 SSL_CTX_set_tmp_ecdh(ctx, ecdh);
1178 EC_KEY_free(ecdh);
1179 }
1180 }
1181#endif
1182
Emeric Brunfc0421f2012-09-07 17:30:07 +02001183 return cfgerr;
1184}
1185
Evan Broderbe554312013-06-27 00:05:25 -07001186static int ssl_sock_srv_hostcheck(const char *pattern, const char *hostname)
1187{
1188 const char *pattern_wildcard, *pattern_left_label_end, *hostname_left_label_end;
1189 size_t prefixlen, suffixlen;
1190
1191 /* Trivial case */
1192 if (strcmp(pattern, hostname) == 0)
1193 return 1;
1194
Evan Broderbe554312013-06-27 00:05:25 -07001195 /* The rest of this logic is based on RFC 6125, section 6.4.3
1196 * (http://tools.ietf.org/html/rfc6125#section-6.4.3) */
1197
Emeric Bruna848dae2013-10-08 11:27:28 +02001198 pattern_wildcard = NULL;
1199 pattern_left_label_end = pattern;
1200 while (*pattern_left_label_end != '.') {
1201 switch (*pattern_left_label_end) {
1202 case 0:
1203 /* End of label not found */
1204 return 0;
1205 case '*':
1206 /* If there is more than one wildcards */
1207 if (pattern_wildcard)
1208 return 0;
1209 pattern_wildcard = pattern_left_label_end;
1210 break;
1211 }
1212 pattern_left_label_end++;
1213 }
1214
1215 /* If it's not trivial and there is no wildcard, it can't
1216 * match */
1217 if (!pattern_wildcard)
Evan Broderbe554312013-06-27 00:05:25 -07001218 return 0;
1219
1220 /* Make sure all labels match except the leftmost */
1221 hostname_left_label_end = strchr(hostname, '.');
1222 if (!hostname_left_label_end
1223 || strcmp(pattern_left_label_end, hostname_left_label_end) != 0)
1224 return 0;
1225
1226 /* Make sure the leftmost label of the hostname is long enough
1227 * that the wildcard can match */
Emeric Brun369da852013-10-08 11:39:35 +02001228 if (hostname_left_label_end - hostname < (pattern_left_label_end - pattern) - 1)
Evan Broderbe554312013-06-27 00:05:25 -07001229 return 0;
1230
1231 /* Finally compare the string on either side of the
1232 * wildcard */
1233 prefixlen = pattern_wildcard - pattern;
1234 suffixlen = pattern_left_label_end - (pattern_wildcard + 1);
Emeric Bruna848dae2013-10-08 11:27:28 +02001235 if ((prefixlen && (memcmp(pattern, hostname, prefixlen) != 0))
1236 || (suffixlen && (memcmp(pattern_wildcard + 1, hostname_left_label_end - suffixlen, suffixlen) != 0)))
Evan Broderbe554312013-06-27 00:05:25 -07001237 return 0;
1238
1239 return 1;
1240}
1241
1242static int ssl_sock_srv_verifycbk(int ok, X509_STORE_CTX *ctx)
1243{
1244 SSL *ssl;
1245 struct connection *conn;
1246 char *servername;
1247
1248 int depth;
1249 X509 *cert;
1250 STACK_OF(GENERAL_NAME) *alt_names;
1251 int i;
1252 X509_NAME *cert_subject;
1253 char *str;
1254
1255 if (ok == 0)
1256 return ok;
1257
1258 ssl = X509_STORE_CTX_get_ex_data(ctx, SSL_get_ex_data_X509_STORE_CTX_idx());
1259 conn = (struct connection *)SSL_get_app_data(ssl);
1260
1261 servername = objt_server(conn->target)->ssl_ctx.verify_host;
1262
1263 /* We only need to verify the CN on the actual server cert,
1264 * not the indirect CAs */
1265 depth = X509_STORE_CTX_get_error_depth(ctx);
1266 if (depth != 0)
1267 return ok;
1268
1269 /* At this point, the cert is *not* OK unless we can find a
1270 * hostname match */
1271 ok = 0;
1272
1273 cert = X509_STORE_CTX_get_current_cert(ctx);
1274 /* It seems like this might happen if verify peer isn't set */
1275 if (!cert)
1276 return ok;
1277
1278 alt_names = X509_get_ext_d2i(cert, NID_subject_alt_name, NULL, NULL);
1279 if (alt_names) {
1280 for (i = 0; !ok && i < sk_GENERAL_NAME_num(alt_names); i++) {
1281 GENERAL_NAME *name = sk_GENERAL_NAME_value(alt_names, i);
1282 if (name->type == GEN_DNS) {
Emeric Bruna33410c2013-09-17 15:47:48 +02001283#if OPENSSL_VERSION_NUMBER < 0x00907000L
1284 if (ASN1_STRING_to_UTF8((unsigned char **)&str, name->d.ia5) >= 0) {
1285#else
Evan Broderbe554312013-06-27 00:05:25 -07001286 if (ASN1_STRING_to_UTF8((unsigned char **)&str, name->d.dNSName) >= 0) {
Emeric Bruna33410c2013-09-17 15:47:48 +02001287#endif
Evan Broderbe554312013-06-27 00:05:25 -07001288 ok = ssl_sock_srv_hostcheck(str, servername);
1289 OPENSSL_free(str);
1290 }
1291 }
1292 }
Emeric Brun4ad50a42013-09-17 15:19:54 +02001293 sk_GENERAL_NAME_pop_free(alt_names, GENERAL_NAME_free);
Evan Broderbe554312013-06-27 00:05:25 -07001294 }
1295
1296 cert_subject = X509_get_subject_name(cert);
1297 i = -1;
1298 while (!ok && (i = X509_NAME_get_index_by_NID(cert_subject, NID_commonName, i)) != -1) {
1299 X509_NAME_ENTRY *entry = X509_NAME_get_entry(cert_subject, i);
1300 if (ASN1_STRING_to_UTF8((unsigned char **)&str, entry->value) >= 0) {
1301 ok = ssl_sock_srv_hostcheck(str, servername);
1302 OPENSSL_free(str);
1303 }
1304 }
1305
1306 return ok;
1307}
1308
Emeric Brun94324a42012-10-11 14:00:19 +02001309/* prepare ssl context from servers options. Returns an error count */
1310int ssl_sock_prepare_srv_ctx(struct server *srv, struct proxy *curproxy)
1311{
1312 int cfgerr = 0;
Remi Gacogneaf5c3da2014-05-19 10:29:58 +02001313 long options =
Emeric Brun94324a42012-10-11 14:00:19 +02001314 SSL_OP_ALL | /* all known workarounds for bugs */
1315 SSL_OP_NO_SSLv2 |
1316 SSL_OP_NO_COMPRESSION;
Remi Gacogneaf5c3da2014-05-19 10:29:58 +02001317 long mode =
Emeric Brun94324a42012-10-11 14:00:19 +02001318 SSL_MODE_ENABLE_PARTIAL_WRITE |
1319 SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER |
1320 SSL_MODE_RELEASE_BUFFERS;
Emeric Brun850efd52014-01-29 12:24:34 +01001321 int verify = SSL_VERIFY_NONE;
Emeric Brun94324a42012-10-11 14:00:19 +02001322
Thierry Fournier383085f2013-01-24 14:15:43 +01001323 /* Make sure openssl opens /dev/urandom before the chroot */
1324 if (!ssl_initialize_random()) {
1325 Alert("OpenSSL random data generator initialization failed.\n");
1326 cfgerr++;
1327 }
1328
Emeric Brun94324a42012-10-11 14:00:19 +02001329 /* Initiate SSL context for current server */
1330 srv->ssl_ctx.reused_sess = NULL;
1331 if (srv->use_ssl)
1332 srv->xprt = &ssl_sock;
1333 if (srv->check.use_ssl)
Simon Horman66183002013-02-23 10:16:43 +09001334 srv->check_common.xprt = &ssl_sock;
Emeric Brun94324a42012-10-11 14:00:19 +02001335
1336 srv->ssl_ctx.ctx = SSL_CTX_new(SSLv23_client_method());
1337 if (!srv->ssl_ctx.ctx) {
1338 Alert("config : %s '%s', server '%s': unable to allocate ssl context.\n",
1339 proxy_type_str(curproxy), curproxy->id,
1340 srv->id);
1341 cfgerr++;
1342 return cfgerr;
1343 }
Emeric Bruna7aa3092012-10-26 12:58:00 +02001344 if (srv->ssl_ctx.client_crt) {
1345 if (SSL_CTX_use_PrivateKey_file(srv->ssl_ctx.ctx, srv->ssl_ctx.client_crt, SSL_FILETYPE_PEM) <= 0) {
1346 Alert("config : %s '%s', server '%s': unable to load SSL private key from PEM file '%s'.\n",
1347 proxy_type_str(curproxy), curproxy->id,
1348 srv->id, srv->ssl_ctx.client_crt);
1349 cfgerr++;
1350 }
1351 else if (SSL_CTX_use_certificate_chain_file(srv->ssl_ctx.ctx, srv->ssl_ctx.client_crt) <= 0) {
1352 Alert("config : %s '%s', server '%s': unable to load ssl certificate from PEM file '%s'.\n",
1353 proxy_type_str(curproxy), curproxy->id,
1354 srv->id, srv->ssl_ctx.client_crt);
1355 cfgerr++;
1356 }
1357 else if (SSL_CTX_check_private_key(srv->ssl_ctx.ctx) <= 0) {
1358 Alert("config : %s '%s', server '%s': inconsistencies between private key and certificate loaded from PEM file '%s'.\n",
1359 proxy_type_str(curproxy), curproxy->id,
1360 srv->id, srv->ssl_ctx.client_crt);
1361 cfgerr++;
1362 }
1363 }
Emeric Brun94324a42012-10-11 14:00:19 +02001364
1365 if (srv->ssl_ctx.options & SRV_SSL_O_NO_SSLV3)
1366 options |= SSL_OP_NO_SSLv3;
1367 if (srv->ssl_ctx.options & SRV_SSL_O_NO_TLSV10)
1368 options |= SSL_OP_NO_TLSv1;
1369 if (srv->ssl_ctx.options & SRV_SSL_O_NO_TLSV11)
1370 options |= SSL_OP_NO_TLSv1_1;
1371 if (srv->ssl_ctx.options & SRV_SSL_O_NO_TLSV12)
1372 options |= SSL_OP_NO_TLSv1_2;
Emeric Brunf9c5c472012-10-11 15:28:34 +02001373 if (srv->ssl_ctx.options & SRV_SSL_O_NO_TLS_TICKETS)
1374 options |= SSL_OP_NO_TICKET;
Emeric Brun94324a42012-10-11 14:00:19 +02001375 if (srv->ssl_ctx.options & SRV_SSL_O_USE_SSLV3)
1376 SSL_CTX_set_ssl_version(srv->ssl_ctx.ctx, SSLv3_client_method());
1377 if (srv->ssl_ctx.options & SRV_SSL_O_USE_TLSV10)
1378 SSL_CTX_set_ssl_version(srv->ssl_ctx.ctx, TLSv1_client_method());
1379#if SSL_OP_NO_TLSv1_1
1380 if (srv->ssl_ctx.options & SRV_SSL_O_USE_TLSV11)
1381 SSL_CTX_set_ssl_version(srv->ssl_ctx.ctx, TLSv1_1_client_method());
1382#endif
1383#if SSL_OP_NO_TLSv1_2
1384 if (srv->ssl_ctx.options & SRV_SSL_O_USE_TLSV12)
1385 SSL_CTX_set_ssl_version(srv->ssl_ctx.ctx, TLSv1_2_client_method());
1386#endif
1387
1388 SSL_CTX_set_options(srv->ssl_ctx.ctx, options);
1389 SSL_CTX_set_mode(srv->ssl_ctx.ctx, mode);
Emeric Brun850efd52014-01-29 12:24:34 +01001390
1391 if (global.ssl_server_verify == SSL_SERVER_VERIFY_REQUIRED)
1392 verify = SSL_VERIFY_PEER;
1393
1394 switch (srv->ssl_ctx.verify) {
1395 case SSL_SOCK_VERIFY_NONE:
1396 verify = SSL_VERIFY_NONE;
1397 break;
1398 case SSL_SOCK_VERIFY_REQUIRED:
1399 verify = SSL_VERIFY_PEER;
1400 break;
1401 }
Evan Broderbe554312013-06-27 00:05:25 -07001402 SSL_CTX_set_verify(srv->ssl_ctx.ctx,
Emeric Brun850efd52014-01-29 12:24:34 +01001403 verify,
Evan Broderbe554312013-06-27 00:05:25 -07001404 srv->ssl_ctx.verify_host ? ssl_sock_srv_verifycbk : NULL);
Emeric Brun850efd52014-01-29 12:24:34 +01001405 if (verify & SSL_VERIFY_PEER) {
Emeric Brunef42d922012-10-11 16:11:36 +02001406 if (srv->ssl_ctx.ca_file) {
1407 /* load CAfile to verify */
1408 if (!SSL_CTX_load_verify_locations(srv->ssl_ctx.ctx, srv->ssl_ctx.ca_file, NULL)) {
Willy Tarreau07ba08b2014-02-16 19:22:08 +01001409 Alert("Proxy '%s', server '%s' [%s:%d] unable to load CA file '%s'.\n",
Emeric Brunef42d922012-10-11 16:11:36 +02001410 curproxy->id, srv->id,
1411 srv->conf.file, srv->conf.line, srv->ssl_ctx.ca_file);
1412 cfgerr++;
1413 }
1414 }
Emeric Brun850efd52014-01-29 12:24:34 +01001415 else {
1416 if (global.ssl_server_verify == SSL_SERVER_VERIFY_REQUIRED)
Willy Tarreau07ba08b2014-02-16 19:22:08 +01001417 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 +01001418 curproxy->id, srv->id,
1419 srv->conf.file, srv->conf.line);
1420 else
Willy Tarreau07ba08b2014-02-16 19:22:08 +01001421 Alert("Proxy '%s', server '%s' [%s:%d] verify is enabled but no CA file specified.\n",
Emeric Brun850efd52014-01-29 12:24:34 +01001422 curproxy->id, srv->id,
1423 srv->conf.file, srv->conf.line);
1424 cfgerr++;
1425 }
Emeric Brunef42d922012-10-11 16:11:36 +02001426#ifdef X509_V_FLAG_CRL_CHECK
1427 if (srv->ssl_ctx.crl_file) {
1428 X509_STORE *store = SSL_CTX_get_cert_store(srv->ssl_ctx.ctx);
1429
1430 if (!store || !X509_STORE_load_locations(store, srv->ssl_ctx.crl_file, NULL)) {
Willy Tarreau07ba08b2014-02-16 19:22:08 +01001431 Alert("Proxy '%s', server '%s' [%s:%d] unable to configure CRL file '%s'.\n",
Emeric Brunef42d922012-10-11 16:11:36 +02001432 curproxy->id, srv->id,
1433 srv->conf.file, srv->conf.line, srv->ssl_ctx.crl_file);
1434 cfgerr++;
1435 }
1436 else {
1437 X509_STORE_set_flags(store, X509_V_FLAG_CRL_CHECK|X509_V_FLAG_CRL_CHECK_ALL);
1438 }
1439 }
1440#endif
1441 }
1442
Emeric Brun4f65bff2012-11-16 15:11:00 +01001443 if (global.tune.ssllifetime)
1444 SSL_CTX_set_timeout(srv->ssl_ctx.ctx, global.tune.ssllifetime);
1445
Emeric Brun94324a42012-10-11 14:00:19 +02001446 SSL_CTX_set_session_cache_mode(srv->ssl_ctx.ctx, SSL_SESS_CACHE_OFF);
1447 if (srv->ssl_ctx.ciphers &&
1448 !SSL_CTX_set_cipher_list(srv->ssl_ctx.ctx, srv->ssl_ctx.ciphers)) {
1449 Alert("Proxy '%s', server '%s' [%s:%d] : unable to set SSL cipher list to '%s'.\n",
1450 curproxy->id, srv->id,
1451 srv->conf.file, srv->conf.line, srv->ssl_ctx.ciphers);
1452 cfgerr++;
1453 }
1454
1455 return cfgerr;
1456}
1457
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001458/* Walks down the two trees in bind_conf and prepares all certs. The pointer may
Emeric Brunfc0421f2012-09-07 17:30:07 +02001459 * be NULL, in which case nothing is done. Returns the number of errors
1460 * encountered.
1461 */
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001462int ssl_sock_prepare_all_ctx(struct bind_conf *bind_conf, struct proxy *px)
Emeric Brunfc0421f2012-09-07 17:30:07 +02001463{
1464 struct ebmb_node *node;
1465 struct sni_ctx *sni;
1466 int err = 0;
1467
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001468 if (!bind_conf || !bind_conf->is_ssl)
Emeric Brunfc0421f2012-09-07 17:30:07 +02001469 return 0;
1470
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001471 node = ebmb_first(&bind_conf->sni_ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001472 while (node) {
1473 sni = ebmb_entry(node, struct sni_ctx, name);
1474 if (!sni->order) /* only initialize the CTX on its first occurrence */
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001475 err += ssl_sock_prepare_ctx(bind_conf, sni->ctx, px);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001476 node = ebmb_next(node);
1477 }
1478
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001479 node = ebmb_first(&bind_conf->sni_w_ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001480 while (node) {
1481 sni = ebmb_entry(node, struct sni_ctx, name);
1482 if (!sni->order) /* only initialize the CTX on its first occurrence */
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001483 err += ssl_sock_prepare_ctx(bind_conf, sni->ctx, px);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001484 node = ebmb_next(node);
1485 }
1486 return err;
1487}
1488
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001489/* Walks down the two trees in bind_conf and frees all the certs. The pointer may
Emeric Brunfc0421f2012-09-07 17:30:07 +02001490 * be NULL, in which case nothing is done. The default_ctx is nullified too.
1491 */
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001492void ssl_sock_free_all_ctx(struct bind_conf *bind_conf)
Emeric Brunfc0421f2012-09-07 17:30:07 +02001493{
1494 struct ebmb_node *node, *back;
1495 struct sni_ctx *sni;
1496
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001497 if (!bind_conf || !bind_conf->is_ssl)
Emeric Brunfc0421f2012-09-07 17:30:07 +02001498 return;
1499
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001500 node = ebmb_first(&bind_conf->sni_ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001501 while (node) {
1502 sni = ebmb_entry(node, struct sni_ctx, name);
1503 back = ebmb_next(node);
1504 ebmb_delete(node);
1505 if (!sni->order) /* only free the CTX on its first occurrence */
1506 SSL_CTX_free(sni->ctx);
1507 free(sni);
1508 node = back;
1509 }
1510
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001511 node = ebmb_first(&bind_conf->sni_w_ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001512 while (node) {
1513 sni = ebmb_entry(node, struct sni_ctx, name);
1514 back = ebmb_next(node);
1515 ebmb_delete(node);
1516 if (!sni->order) /* only free the CTX on its first occurrence */
1517 SSL_CTX_free(sni->ctx);
1518 free(sni);
1519 node = back;
1520 }
1521
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001522 bind_conf->default_ctx = NULL;
Emeric Brune1f38db2012-09-03 20:36:47 +02001523}
1524
Emeric Brun46591952012-05-18 15:47:34 +02001525/*
1526 * This function is called if SSL * context is not yet allocated. The function
1527 * is designed to be called before any other data-layer operation and sets the
1528 * handshake flag on the connection. It is safe to call it multiple times.
1529 * It returns 0 on success and -1 in error case.
1530 */
1531static int ssl_sock_init(struct connection *conn)
1532{
1533 /* already initialized */
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02001534 if (conn->xprt_ctx)
Emeric Brun46591952012-05-18 15:47:34 +02001535 return 0;
1536
Willy Tarreau3c728722014-01-23 13:50:42 +01001537 if (!conn_ctrl_ready(conn))
Willy Tarreauf79c8172013-10-21 16:30:56 +02001538 return 0;
1539
Willy Tarreau20879a02012-12-03 16:32:10 +01001540 if (global.maxsslconn && sslconns >= global.maxsslconn) {
1541 conn->err_code = CO_ER_SSL_TOO_MANY;
Willy Tarreau403edff2012-09-06 11:58:37 +02001542 return -1;
Willy Tarreau20879a02012-12-03 16:32:10 +01001543 }
Willy Tarreau403edff2012-09-06 11:58:37 +02001544
Emeric Brun46591952012-05-18 15:47:34 +02001545 /* If it is in client mode initiate SSL session
1546 in connect state otherwise accept state */
Willy Tarreau3fdb3662012-11-12 00:42:33 +01001547 if (objt_server(conn->target)) {
Emeric Brun46591952012-05-18 15:47:34 +02001548 /* Alloc a new SSL session ctx */
Willy Tarreau3fdb3662012-11-12 00:42:33 +01001549 conn->xprt_ctx = SSL_new(objt_server(conn->target)->ssl_ctx.ctx);
Willy Tarreau20879a02012-12-03 16:32:10 +01001550 if (!conn->xprt_ctx) {
1551 conn->err_code = CO_ER_SSL_NO_MEM;
Emeric Brun46591952012-05-18 15:47:34 +02001552 return -1;
Willy Tarreau20879a02012-12-03 16:32:10 +01001553 }
Emeric Brun46591952012-05-18 15:47:34 +02001554
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02001555 SSL_set_connect_state(conn->xprt_ctx);
Willy Tarreau3fdb3662012-11-12 00:42:33 +01001556 if (objt_server(conn->target)->ssl_ctx.reused_sess)
1557 SSL_set_session(conn->xprt_ctx, objt_server(conn->target)->ssl_ctx.reused_sess);
Emeric Brun46591952012-05-18 15:47:34 +02001558
1559 /* set fd on SSL session context */
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02001560 SSL_set_fd(conn->xprt_ctx, conn->t.sock.fd);
Emeric Brun46591952012-05-18 15:47:34 +02001561
Evan Broderbe554312013-06-27 00:05:25 -07001562 /* set connection pointer */
1563 SSL_set_app_data(conn->xprt_ctx, conn);
1564
Emeric Brun46591952012-05-18 15:47:34 +02001565 /* leave init state and start handshake */
Willy Tarreau05737472012-09-04 08:03:39 +02001566 conn->flags |= CO_FL_SSL_WAIT_HS | CO_FL_WAIT_L6_CONN;
Willy Tarreau403edff2012-09-06 11:58:37 +02001567
1568 sslconns++;
Willy Tarreau71b734c2014-01-28 15:19:44 +01001569 totalsslconns++;
Emeric Brun46591952012-05-18 15:47:34 +02001570 return 0;
1571 }
Willy Tarreau3fdb3662012-11-12 00:42:33 +01001572 else if (objt_listener(conn->target)) {
Emeric Brun46591952012-05-18 15:47:34 +02001573 /* Alloc a new SSL session ctx */
Willy Tarreau3fdb3662012-11-12 00:42:33 +01001574 conn->xprt_ctx = SSL_new(objt_listener(conn->target)->bind_conf->default_ctx);
Willy Tarreau20879a02012-12-03 16:32:10 +01001575 if (!conn->xprt_ctx) {
1576 conn->err_code = CO_ER_SSL_NO_MEM;
Emeric Brun46591952012-05-18 15:47:34 +02001577 return -1;
Willy Tarreau20879a02012-12-03 16:32:10 +01001578 }
Emeric Brun46591952012-05-18 15:47:34 +02001579
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02001580 SSL_set_accept_state(conn->xprt_ctx);
Emeric Brun46591952012-05-18 15:47:34 +02001581
1582 /* set fd on SSL session context */
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02001583 SSL_set_fd(conn->xprt_ctx, conn->t.sock.fd);
Emeric Brun46591952012-05-18 15:47:34 +02001584
Emeric Brune1f38db2012-09-03 20:36:47 +02001585 /* set connection pointer */
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02001586 SSL_set_app_data(conn->xprt_ctx, conn);
Emeric Brune1f38db2012-09-03 20:36:47 +02001587
Emeric Brun46591952012-05-18 15:47:34 +02001588 /* leave init state and start handshake */
Willy Tarreau05737472012-09-04 08:03:39 +02001589 conn->flags |= CO_FL_SSL_WAIT_HS | CO_FL_WAIT_L6_CONN;
Willy Tarreau403edff2012-09-06 11:58:37 +02001590
1591 sslconns++;
Willy Tarreau71b734c2014-01-28 15:19:44 +01001592 totalsslconns++;
Emeric Brun46591952012-05-18 15:47:34 +02001593 return 0;
1594 }
1595 /* don't know how to handle such a target */
Willy Tarreau20879a02012-12-03 16:32:10 +01001596 conn->err_code = CO_ER_SSL_NO_TARGET;
Emeric Brun46591952012-05-18 15:47:34 +02001597 return -1;
1598}
1599
1600
1601/* This is the callback which is used when an SSL handshake is pending. It
1602 * updates the FD status if it wants some polling before being called again.
1603 * It returns 0 if it fails in a fatal way or needs to poll to go further,
1604 * otherwise it returns non-zero and removes itself from the connection's
1605 * flags (the bit is provided in <flag> by the caller).
1606 */
1607int ssl_sock_handshake(struct connection *conn, unsigned int flag)
1608{
1609 int ret;
1610
Willy Tarreau3c728722014-01-23 13:50:42 +01001611 if (!conn_ctrl_ready(conn))
Willy Tarreauf79c8172013-10-21 16:30:56 +02001612 return 0;
1613
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02001614 if (!conn->xprt_ctx)
Emeric Brun46591952012-05-18 15:47:34 +02001615 goto out_error;
1616
Emeric Brun674b7432012-11-08 19:21:55 +01001617 /* If we use SSL_do_handshake to process a reneg initiated by
1618 * the remote peer, it sometimes returns SSL_ERROR_SSL.
1619 * Usually SSL_write and SSL_read are used and process implicitly
1620 * the reneg handshake.
1621 * Here we use SSL_peek as a workaround for reneg.
1622 */
1623 if ((conn->flags & CO_FL_CONNECTED) && SSL_renegotiate_pending(conn->xprt_ctx)) {
1624 char c;
1625
1626 ret = SSL_peek(conn->xprt_ctx, &c, 1);
1627 if (ret <= 0) {
1628 /* handshake may have not been completed, let's find why */
1629 ret = SSL_get_error(conn->xprt_ctx, ret);
1630 if (ret == SSL_ERROR_WANT_WRITE) {
1631 /* SSL handshake needs to write, L4 connection may not be ready */
1632 __conn_sock_stop_recv(conn);
Willy Tarreaue1f50c42014-01-22 20:02:06 +01001633 __conn_sock_want_send(conn);
1634 fd_cant_send(conn->t.sock.fd);
Emeric Brun674b7432012-11-08 19:21:55 +01001635 return 0;
1636 }
1637 else if (ret == SSL_ERROR_WANT_READ) {
1638 /* handshake may have been completed but we have
1639 * no more data to read.
1640 */
1641 if (!SSL_renegotiate_pending(conn->xprt_ctx)) {
1642 ret = 1;
1643 goto reneg_ok;
1644 }
1645 /* SSL handshake needs to read, L4 connection is ready */
1646 if (conn->flags & CO_FL_WAIT_L4_CONN)
1647 conn->flags &= ~CO_FL_WAIT_L4_CONN;
1648 __conn_sock_stop_send(conn);
Willy Tarreaue1f50c42014-01-22 20:02:06 +01001649 __conn_sock_want_recv(conn);
1650 fd_cant_recv(conn->t.sock.fd);
Emeric Brun674b7432012-11-08 19:21:55 +01001651 return 0;
1652 }
1653 else if (ret == SSL_ERROR_SYSCALL) {
1654 /* if errno is null, then connection was successfully established */
1655 if (!errno && conn->flags & CO_FL_WAIT_L4_CONN)
1656 conn->flags &= ~CO_FL_WAIT_L4_CONN;
Willy Tarreau20879a02012-12-03 16:32:10 +01001657 if (!conn->err_code) {
Emeric Brun29f037d2014-04-25 19:05:36 +02001658 if (!((SSL *)conn->xprt_ctx)->packet_length) {
1659 if (!errno) {
1660 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
1661 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
1662 else
1663 conn->err_code = CO_ER_SSL_EMPTY;
1664 }
1665 else {
1666 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
1667 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
1668 else
1669 conn->err_code = CO_ER_SSL_ABORT;
1670 }
1671 }
1672 else {
1673 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
1674 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
Willy Tarreau20879a02012-12-03 16:32:10 +01001675 else
Emeric Brun29f037d2014-04-25 19:05:36 +02001676 conn->err_code = CO_ER_SSL_HANDSHAKE;
1677 }
Willy Tarreau20879a02012-12-03 16:32:10 +01001678 }
Emeric Brun674b7432012-11-08 19:21:55 +01001679 goto out_error;
1680 }
1681 else {
1682 /* Fail on all other handshake errors */
1683 /* Note: OpenSSL may leave unread bytes in the socket's
1684 * buffer, causing an RST to be emitted upon close() on
1685 * TCP sockets. We first try to drain possibly pending
1686 * data to avoid this as much as possible.
1687 */
Willy Tarreau46be2e52014-01-20 12:10:52 +01001688 conn_drain(conn);
Willy Tarreau20879a02012-12-03 16:32:10 +01001689 if (!conn->err_code)
Willy Tarreauf51c6982014-04-25 20:02:39 +02001690 conn->err_code = (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT) ?
1691 CO_ER_SSL_KILLED_HB : CO_ER_SSL_HANDSHAKE;
Emeric Brun674b7432012-11-08 19:21:55 +01001692 goto out_error;
1693 }
1694 }
1695 /* read some data: consider handshake completed */
1696 goto reneg_ok;
1697 }
1698
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02001699 ret = SSL_do_handshake(conn->xprt_ctx);
Emeric Brun46591952012-05-18 15:47:34 +02001700 if (ret != 1) {
1701 /* handshake did not complete, let's find why */
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02001702 ret = SSL_get_error(conn->xprt_ctx, ret);
Emeric Brun46591952012-05-18 15:47:34 +02001703
1704 if (ret == SSL_ERROR_WANT_WRITE) {
1705 /* SSL handshake needs to write, L4 connection may not be ready */
1706 __conn_sock_stop_recv(conn);
Willy Tarreaue1f50c42014-01-22 20:02:06 +01001707 __conn_sock_want_send(conn);
1708 fd_cant_send(conn->t.sock.fd);
Emeric Brun46591952012-05-18 15:47:34 +02001709 return 0;
1710 }
1711 else if (ret == SSL_ERROR_WANT_READ) {
1712 /* SSL handshake needs to read, L4 connection is ready */
1713 if (conn->flags & CO_FL_WAIT_L4_CONN)
1714 conn->flags &= ~CO_FL_WAIT_L4_CONN;
1715 __conn_sock_stop_send(conn);
Willy Tarreaue1f50c42014-01-22 20:02:06 +01001716 __conn_sock_want_recv(conn);
1717 fd_cant_recv(conn->t.sock.fd);
Emeric Brun46591952012-05-18 15:47:34 +02001718 return 0;
1719 }
Willy Tarreau89230192012-09-28 20:22:13 +02001720 else if (ret == SSL_ERROR_SYSCALL) {
1721 /* if errno is null, then connection was successfully established */
1722 if (!errno && conn->flags & CO_FL_WAIT_L4_CONN)
1723 conn->flags &= ~CO_FL_WAIT_L4_CONN;
Willy Tarreau20879a02012-12-03 16:32:10 +01001724
Emeric Brun29f037d2014-04-25 19:05:36 +02001725 if (!((SSL *)conn->xprt_ctx)->packet_length) {
1726 if (!errno) {
1727 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
1728 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
1729 else
1730 conn->err_code = CO_ER_SSL_EMPTY;
1731 }
1732 else {
1733 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
1734 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
1735 else
1736 conn->err_code = CO_ER_SSL_ABORT;
1737 }
1738 }
1739 else {
1740 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
1741 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
Willy Tarreau20879a02012-12-03 16:32:10 +01001742 else
Emeric Brun29f037d2014-04-25 19:05:36 +02001743 conn->err_code = CO_ER_SSL_HANDSHAKE;
1744 }
Willy Tarreau89230192012-09-28 20:22:13 +02001745 goto out_error;
1746 }
Emeric Brun46591952012-05-18 15:47:34 +02001747 else {
1748 /* Fail on all other handshake errors */
Willy Tarreau566dc552012-10-19 20:52:18 +02001749 /* Note: OpenSSL may leave unread bytes in the socket's
1750 * buffer, causing an RST to be emitted upon close() on
1751 * TCP sockets. We first try to drain possibly pending
1752 * data to avoid this as much as possible.
1753 */
Willy Tarreau46be2e52014-01-20 12:10:52 +01001754 conn_drain(conn);
Willy Tarreau20879a02012-12-03 16:32:10 +01001755 if (!conn->err_code)
Willy Tarreauf51c6982014-04-25 20:02:39 +02001756 conn->err_code = (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT) ?
1757 CO_ER_SSL_KILLED_HB : CO_ER_SSL_HANDSHAKE;
Emeric Brun46591952012-05-18 15:47:34 +02001758 goto out_error;
1759 }
1760 }
1761
Emeric Brun674b7432012-11-08 19:21:55 +01001762reneg_ok:
1763
Emeric Brun46591952012-05-18 15:47:34 +02001764 /* Handshake succeeded */
Willy Tarreau0c9c2722014-05-28 12:28:58 +02001765 if (!SSL_session_reused(conn->xprt_ctx)) {
1766 if (objt_server(conn->target)) {
1767 update_freq_ctr(&global.ssl_be_keys_per_sec, 1);
1768 if (global.ssl_be_keys_per_sec.curr_ctr > global.ssl_be_keys_max)
1769 global.ssl_be_keys_max = global.ssl_be_keys_per_sec.curr_ctr;
1770
Emeric Brun46591952012-05-18 15:47:34 +02001771 /* check if session was reused, if not store current session on server for reuse */
Willy Tarreau3fdb3662012-11-12 00:42:33 +01001772 if (objt_server(conn->target)->ssl_ctx.reused_sess)
1773 SSL_SESSION_free(objt_server(conn->target)->ssl_ctx.reused_sess);
Emeric Brun46591952012-05-18 15:47:34 +02001774
Willy Tarreau3fdb3662012-11-12 00:42:33 +01001775 objt_server(conn->target)->ssl_ctx.reused_sess = SSL_get1_session(conn->xprt_ctx);
Emeric Brun46591952012-05-18 15:47:34 +02001776 }
Willy Tarreau0c9c2722014-05-28 12:28:58 +02001777 else {
1778 update_freq_ctr(&global.ssl_fe_keys_per_sec, 1);
1779 if (global.ssl_fe_keys_per_sec.curr_ctr > global.ssl_fe_keys_max)
1780 global.ssl_fe_keys_max = global.ssl_fe_keys_per_sec.curr_ctr;
1781 }
Emeric Brun46591952012-05-18 15:47:34 +02001782 }
1783
1784 /* The connection is now established at both layers, it's time to leave */
1785 conn->flags &= ~(flag | CO_FL_WAIT_L4_CONN | CO_FL_WAIT_L6_CONN);
1786 return 1;
1787
1788 out_error:
Emeric Brun644cde02012-12-14 11:21:13 +01001789 /* Clear openssl global errors stack */
1790 ERR_clear_error();
1791
Emeric Brun9fa89732012-10-04 17:09:56 +02001792 /* free resumed session if exists */
Willy Tarreau3fdb3662012-11-12 00:42:33 +01001793 if (objt_server(conn->target) && objt_server(conn->target)->ssl_ctx.reused_sess) {
1794 SSL_SESSION_free(objt_server(conn->target)->ssl_ctx.reused_sess);
1795 objt_server(conn->target)->ssl_ctx.reused_sess = NULL;
Emeric Brun9fa89732012-10-04 17:09:56 +02001796 }
1797
Emeric Brun46591952012-05-18 15:47:34 +02001798 /* Fail on all other handshake errors */
1799 conn->flags |= CO_FL_ERROR;
Willy Tarreau20879a02012-12-03 16:32:10 +01001800 if (!conn->err_code)
1801 conn->err_code = CO_ER_SSL_HANDSHAKE;
Emeric Brun46591952012-05-18 15:47:34 +02001802 return 0;
1803}
1804
1805/* Receive up to <count> bytes from connection <conn>'s socket and store them
Willy Tarreauabf08d92014-01-14 11:31:27 +01001806 * into buffer <buf>. Only one call to recv() is performed, unless the
Emeric Brun46591952012-05-18 15:47:34 +02001807 * buffer wraps, in which case a second call may be performed. The connection's
1808 * flags are updated with whatever special event is detected (error, read0,
1809 * empty). The caller is responsible for taking care of those events and
1810 * avoiding the call if inappropriate. The function does not call the
1811 * connection's polling update function, so the caller is responsible for this.
1812 */
1813static int ssl_sock_to_buf(struct connection *conn, struct buffer *buf, int count)
1814{
1815 int ret, done = 0;
Willy Tarreauabf08d92014-01-14 11:31:27 +01001816 int try;
Emeric Brun46591952012-05-18 15:47:34 +02001817
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02001818 if (!conn->xprt_ctx)
Emeric Brun46591952012-05-18 15:47:34 +02001819 goto out_error;
1820
1821 if (conn->flags & CO_FL_HANDSHAKE)
1822 /* a handshake was requested */
1823 return 0;
1824
Willy Tarreauabf08d92014-01-14 11:31:27 +01001825 /* let's realign the buffer to optimize I/O */
1826 if (buffer_empty(buf))
Emeric Brun46591952012-05-18 15:47:34 +02001827 buf->p = buf->data;
Emeric Brun46591952012-05-18 15:47:34 +02001828
1829 /* read the largest possible block. For this, we perform only one call
1830 * to recv() unless the buffer wraps and we exactly fill the first hunk,
1831 * in which case we accept to do it once again. A new attempt is made on
1832 * EINTR too.
1833 */
Willy Tarreau00b0fb92014-01-17 11:09:40 +01001834 while (count > 0) {
Willy Tarreauabf08d92014-01-14 11:31:27 +01001835 /* first check if we have some room after p+i */
1836 try = buf->data + buf->size - (buf->p + buf->i);
1837 /* otherwise continue between data and p-o */
1838 if (try <= 0) {
1839 try = buf->p - (buf->data + buf->o);
1840 if (try <= 0)
1841 break;
1842 }
1843 if (try > count)
1844 try = count;
1845
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02001846 ret = SSL_read(conn->xprt_ctx, bi_end(buf), try);
Emeric Brune1f38db2012-09-03 20:36:47 +02001847 if (conn->flags & CO_FL_ERROR) {
1848 /* CO_FL_ERROR may be set by ssl_sock_infocbk */
Emeric Brun644cde02012-12-14 11:21:13 +01001849 goto out_error;
Emeric Brune1f38db2012-09-03 20:36:47 +02001850 }
Emeric Brun46591952012-05-18 15:47:34 +02001851 if (ret > 0) {
1852 buf->i += ret;
1853 done += ret;
1854 if (ret < try)
1855 break;
1856 count -= ret;
Emeric Brun46591952012-05-18 15:47:34 +02001857 }
1858 else if (ret == 0) {
Emeric Brun644cde02012-12-14 11:21:13 +01001859 ret = SSL_get_error(conn->xprt_ctx, ret);
1860 if (ret != SSL_ERROR_ZERO_RETURN) {
Emeric Brun1c646862012-12-14 12:33:41 +01001861 /* error on protocol or underlying transport */
1862 if ((ret != SSL_ERROR_SYSCALL)
1863 || (errno && (errno != EAGAIN)))
1864 conn->flags |= CO_FL_ERROR;
1865
Emeric Brun644cde02012-12-14 11:21:13 +01001866 /* Clear openssl global errors stack */
1867 ERR_clear_error();
1868 }
Emeric Brun46591952012-05-18 15:47:34 +02001869 goto read0;
1870 }
1871 else {
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02001872 ret = SSL_get_error(conn->xprt_ctx, ret);
Emeric Brun46591952012-05-18 15:47:34 +02001873 if (ret == SSL_ERROR_WANT_WRITE) {
Emeric Brun8af8dd12012-11-08 17:56:20 +01001874 /* handshake is running, and it needs to enable write */
Emeric Brun46591952012-05-18 15:47:34 +02001875 conn->flags |= CO_FL_SSL_WAIT_HS;
Emeric Brun8af8dd12012-11-08 17:56:20 +01001876 __conn_sock_want_send(conn);
Emeric Brun46591952012-05-18 15:47:34 +02001877 break;
1878 }
1879 else if (ret == SSL_ERROR_WANT_READ) {
Emeric Brun282a76a2012-11-08 18:02:56 +01001880 if (SSL_renegotiate_pending(conn->xprt_ctx)) {
1881 /* handshake is running, and it may need to re-enable read */
1882 conn->flags |= CO_FL_SSL_WAIT_HS;
1883 __conn_sock_want_recv(conn);
1884 break;
1885 }
Emeric Brun46591952012-05-18 15:47:34 +02001886 /* we need to poll for retry a read later */
Willy Tarreaue1f50c42014-01-22 20:02:06 +01001887 fd_cant_recv(conn->t.sock.fd);
Emeric Brun46591952012-05-18 15:47:34 +02001888 break;
1889 }
1890 /* otherwise it's a real error */
1891 goto out_error;
1892 }
1893 }
1894 return done;
1895
1896 read0:
1897 conn_sock_read0(conn);
1898 return done;
1899 out_error:
Emeric Brun644cde02012-12-14 11:21:13 +01001900 /* Clear openssl global errors stack */
1901 ERR_clear_error();
1902
Emeric Brun46591952012-05-18 15:47:34 +02001903 conn->flags |= CO_FL_ERROR;
1904 return done;
1905}
1906
1907
1908/* Send all pending bytes from buffer <buf> to connection <conn>'s socket.
Willy Tarreau1049b1f2014-02-02 01:51:17 +01001909 * <flags> may contain some CO_SFL_* flags to hint the system about other
1910 * pending data for example, but this flag is ignored at the moment.
Emeric Brun46591952012-05-18 15:47:34 +02001911 * Only one call to send() is performed, unless the buffer wraps, in which case
1912 * a second call may be performed. The connection's flags are updated with
1913 * whatever special event is detected (error, empty). The caller is responsible
1914 * for taking care of those events and avoiding the call if inappropriate. The
1915 * function does not call the connection's polling update function, so the caller
1916 * is responsible for this.
1917 */
1918static int ssl_sock_from_buf(struct connection *conn, struct buffer *buf, int flags)
1919{
1920 int ret, try, done;
1921
1922 done = 0;
1923
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02001924 if (!conn->xprt_ctx)
Emeric Brun46591952012-05-18 15:47:34 +02001925 goto out_error;
1926
1927 if (conn->flags & CO_FL_HANDSHAKE)
1928 /* a handshake was requested */
1929 return 0;
1930
1931 /* send the largest possible block. For this we perform only one call
1932 * to send() unless the buffer wraps and we exactly fill the first hunk,
1933 * in which case we accept to do it once again.
1934 */
1935 while (buf->o) {
Kevin Hestercad82342013-05-30 15:12:41 -07001936 try = bo_contig_data(buf);
Willy Tarreaubfd59462013-02-21 07:46:09 +01001937
Willy Tarreau7bed9452014-02-02 02:00:24 +01001938 if (!(flags & CO_SFL_STREAMER) &&
Willy Tarreau518cedd2014-02-17 15:43:01 +01001939 !(conn->xprt_st & SSL_SOCK_SEND_UNLIMITED) &&
1940 global.tune.ssl_max_record && try > global.tune.ssl_max_record) {
Willy Tarreaubfd59462013-02-21 07:46:09 +01001941 try = global.tune.ssl_max_record;
Willy Tarreau518cedd2014-02-17 15:43:01 +01001942 }
1943 else {
1944 /* we need to keep the information about the fact that
1945 * we're not limiting the upcoming send(), because if it
1946 * fails, we'll have to retry with at least as many data.
1947 */
1948 conn->xprt_st |= SSL_SOCK_SEND_UNLIMITED;
1949 }
Willy Tarreaubfd59462013-02-21 07:46:09 +01001950
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02001951 ret = SSL_write(conn->xprt_ctx, bo_ptr(buf), try);
Willy Tarreau518cedd2014-02-17 15:43:01 +01001952
Emeric Brune1f38db2012-09-03 20:36:47 +02001953 if (conn->flags & CO_FL_ERROR) {
1954 /* CO_FL_ERROR may be set by ssl_sock_infocbk */
Emeric Brun644cde02012-12-14 11:21:13 +01001955 goto out_error;
Emeric Brune1f38db2012-09-03 20:36:47 +02001956 }
Emeric Brun46591952012-05-18 15:47:34 +02001957 if (ret > 0) {
Willy Tarreau518cedd2014-02-17 15:43:01 +01001958 conn->xprt_st &= ~SSL_SOCK_SEND_UNLIMITED;
1959
Emeric Brun46591952012-05-18 15:47:34 +02001960 buf->o -= ret;
1961 done += ret;
1962
Willy Tarreau5fb38032012-12-16 19:39:09 +01001963 if (likely(buffer_empty(buf)))
Emeric Brun46591952012-05-18 15:47:34 +02001964 /* optimize data alignment in the buffer */
1965 buf->p = buf->data;
1966
1967 /* if the system buffer is full, don't insist */
1968 if (ret < try)
1969 break;
1970 }
1971 else {
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02001972 ret = SSL_get_error(conn->xprt_ctx, ret);
Emeric Brun46591952012-05-18 15:47:34 +02001973 if (ret == SSL_ERROR_WANT_WRITE) {
Emeric Brun282a76a2012-11-08 18:02:56 +01001974 if (SSL_renegotiate_pending(conn->xprt_ctx)) {
1975 /* handshake is running, and it may need to re-enable write */
1976 conn->flags |= CO_FL_SSL_WAIT_HS;
1977 __conn_sock_want_send(conn);
1978 break;
1979 }
Emeric Brun46591952012-05-18 15:47:34 +02001980 /* we need to poll to retry a write later */
Willy Tarreaue1f50c42014-01-22 20:02:06 +01001981 fd_cant_send(conn->t.sock.fd);
Emeric Brun46591952012-05-18 15:47:34 +02001982 break;
1983 }
1984 else if (ret == SSL_ERROR_WANT_READ) {
Emeric Brun8af8dd12012-11-08 17:56:20 +01001985 /* handshake is running, and it needs to enable read */
Emeric Brun46591952012-05-18 15:47:34 +02001986 conn->flags |= CO_FL_SSL_WAIT_HS;
Emeric Brun8af8dd12012-11-08 17:56:20 +01001987 __conn_sock_want_recv(conn);
Emeric Brun46591952012-05-18 15:47:34 +02001988 break;
1989 }
1990 goto out_error;
1991 }
1992 }
1993 return done;
1994
1995 out_error:
Emeric Brun644cde02012-12-14 11:21:13 +01001996 /* Clear openssl global errors stack */
1997 ERR_clear_error();
1998
Emeric Brun46591952012-05-18 15:47:34 +02001999 conn->flags |= CO_FL_ERROR;
2000 return done;
2001}
2002
Emeric Brun46591952012-05-18 15:47:34 +02002003static void ssl_sock_close(struct connection *conn) {
2004
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02002005 if (conn->xprt_ctx) {
2006 SSL_free(conn->xprt_ctx);
2007 conn->xprt_ctx = NULL;
Willy Tarreau403edff2012-09-06 11:58:37 +02002008 sslconns--;
Emeric Brun46591952012-05-18 15:47:34 +02002009 }
Emeric Brun46591952012-05-18 15:47:34 +02002010}
2011
2012/* This function tries to perform a clean shutdown on an SSL connection, and in
2013 * any case, flags the connection as reusable if no handshake was in progress.
2014 */
2015static void ssl_sock_shutw(struct connection *conn, int clean)
2016{
2017 if (conn->flags & CO_FL_HANDSHAKE)
2018 return;
2019 /* no handshake was in progress, try a clean ssl shutdown */
Emeric Brun644cde02012-12-14 11:21:13 +01002020 if (clean && (SSL_shutdown(conn->xprt_ctx) <= 0)) {
2021 /* Clear openssl global errors stack */
2022 ERR_clear_error();
2023 }
Emeric Brun46591952012-05-18 15:47:34 +02002024
2025 /* force flag on ssl to keep session in cache regardless shutdown result */
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02002026 SSL_set_shutdown(conn->xprt_ctx, SSL_SENT_SHUTDOWN);
Emeric Brun46591952012-05-18 15:47:34 +02002027}
2028
Willy Tarreauffc3fcd2012-10-12 20:17:54 +02002029/* used for logging, may be changed for a sample fetch later */
2030const char *ssl_sock_get_cipher_name(struct connection *conn)
2031{
2032 if (!conn->xprt && !conn->xprt_ctx)
2033 return NULL;
2034 return SSL_get_cipher_name(conn->xprt_ctx);
2035}
2036
2037/* used for logging, may be changed for a sample fetch later */
2038const char *ssl_sock_get_proto_version(struct connection *conn)
2039{
2040 if (!conn->xprt && !conn->xprt_ctx)
2041 return NULL;
2042 return SSL_get_version(conn->xprt_ctx);
2043}
2044
Willy Tarreau8d598402012-10-22 17:58:39 +02002045/* Extract a serial from a cert, and copy it to a chunk.
2046 * Returns 1 if serial is found and copied, 0 if no serial found and
2047 * -1 if output is not large enough.
2048 */
2049static int
2050ssl_sock_get_serial(X509 *crt, struct chunk *out)
2051{
2052 ASN1_INTEGER *serial;
2053
2054 serial = X509_get_serialNumber(crt);
2055 if (!serial)
2056 return 0;
2057
2058 if (out->size < serial->length)
2059 return -1;
2060
2061 memcpy(out->str, serial->data, serial->length);
2062 out->len = serial->length;
2063 return 1;
2064}
2065
Emeric Brunce5ad802012-10-22 14:11:22 +02002066
2067/* Copy Date in ASN1_UTCTIME format in struct chunk out.
2068 * Returns 1 if serial is found and copied, 0 if no valid time found
2069 * and -1 if output is not large enough.
2070 */
2071static int
2072ssl_sock_get_time(ASN1_TIME *tm, struct chunk *out)
2073{
2074 if (tm->type == V_ASN1_GENERALIZEDTIME) {
2075 ASN1_GENERALIZEDTIME *gentm = (ASN1_GENERALIZEDTIME *)tm;
2076
2077 if (gentm->length < 12)
2078 return 0;
2079 if (gentm->data[0] != 0x32 || gentm->data[1] != 0x30)
2080 return 0;
2081 if (out->size < gentm->length-2)
2082 return -1;
2083
2084 memcpy(out->str, gentm->data+2, gentm->length-2);
2085 out->len = gentm->length-2;
2086 return 1;
2087 }
2088 else if (tm->type == V_ASN1_UTCTIME) {
2089 ASN1_UTCTIME *utctm = (ASN1_UTCTIME *)tm;
2090
2091 if (utctm->length < 10)
2092 return 0;
2093 if (utctm->data[0] >= 0x35)
2094 return 0;
2095 if (out->size < utctm->length)
2096 return -1;
2097
2098 memcpy(out->str, utctm->data, utctm->length);
2099 out->len = utctm->length;
2100 return 1;
2101 }
2102
2103 return 0;
2104}
2105
Emeric Brun87855892012-10-17 17:39:35 +02002106/* Extract an entry from a X509_NAME and copy its value to an output chunk.
2107 * Returns 1 if entry found, 0 if entry not found, or -1 if output not large enough.
2108 */
2109static int
2110ssl_sock_get_dn_entry(X509_NAME *a, const struct chunk *entry, int pos, struct chunk *out)
2111{
2112 X509_NAME_ENTRY *ne;
2113 int i, j, n;
2114 int cur = 0;
2115 const char *s;
2116 char tmp[128];
2117
2118 out->len = 0;
2119 for (i = 0; i < sk_X509_NAME_ENTRY_num(a->entries); i++) {
2120 if (pos < 0)
2121 j = (sk_X509_NAME_ENTRY_num(a->entries)-1) - i;
2122 else
2123 j = i;
2124
2125 ne = sk_X509_NAME_ENTRY_value(a->entries, j);
2126 n = OBJ_obj2nid(ne->object);
2127 if ((n == NID_undef) || ((s = OBJ_nid2sn(n)) == NULL)) {
2128 i2t_ASN1_OBJECT(tmp, sizeof(tmp), ne->object);
2129 s = tmp;
2130 }
2131
2132 if (chunk_strcasecmp(entry, s) != 0)
2133 continue;
2134
2135 if (pos < 0)
2136 cur--;
2137 else
2138 cur++;
2139
2140 if (cur != pos)
2141 continue;
2142
2143 if (ne->value->length > out->size)
2144 return -1;
2145
2146 memcpy(out->str, ne->value->data, ne->value->length);
2147 out->len = ne->value->length;
2148 return 1;
2149 }
2150
2151 return 0;
2152
2153}
2154
2155/* Extract and format full DN from a X509_NAME and copy result into a chunk
2156 * Returns 1 if dn entries exits, 0 if no dn entry found or -1 if output is not large enough.
2157 */
2158static int
2159ssl_sock_get_dn_oneline(X509_NAME *a, struct chunk *out)
2160{
2161 X509_NAME_ENTRY *ne;
2162 int i, n, ln;
2163 int l = 0;
2164 const char *s;
2165 char *p;
2166 char tmp[128];
2167
2168 out->len = 0;
2169 p = out->str;
2170 for (i = 0; i < sk_X509_NAME_ENTRY_num(a->entries); i++) {
2171 ne = sk_X509_NAME_ENTRY_value(a->entries, i);
2172 n = OBJ_obj2nid(ne->object);
2173 if ((n == NID_undef) || ((s = OBJ_nid2sn(n)) == NULL)) {
2174 i2t_ASN1_OBJECT(tmp, sizeof(tmp), ne->object);
2175 s = tmp;
2176 }
2177 ln = strlen(s);
2178
2179 l += 1 + ln + 1 + ne->value->length;
2180 if (l > out->size)
2181 return -1;
2182 out->len = l;
2183
2184 *(p++)='/';
2185 memcpy(p, s, ln);
2186 p += ln;
2187 *(p++)='=';
2188 memcpy(p, ne->value->data, ne->value->length);
2189 p += ne->value->length;
2190 }
2191
2192 if (!out->len)
2193 return 0;
2194
2195 return 1;
2196}
2197
David Safb76832014-05-08 23:42:08 -04002198char *ssl_sock_get_version(struct connection *conn)
2199{
2200 if (!ssl_sock_is_ssl(conn))
2201 return NULL;
2202
2203 return (char *)SSL_get_version(conn->xprt_ctx);
2204}
2205
2206/* returns common name, NULL terminated, from client certificate, or NULL if none */
2207char *ssl_sock_get_common_name(struct connection *conn)
2208{
2209 X509 *crt = NULL;
2210 X509_NAME *name;
2211 struct chunk *cn_trash;
2212 const char find_cn[] = "CN";
2213 const struct chunk find_cn_chunk = {
2214 .str = (char *)&find_cn,
2215 .len = sizeof(find_cn)-1
2216 };
2217 char *result = NULL;
2218
2219 if (!ssl_sock_is_ssl(conn))
2220 return NULL;
2221
2222 /* SSL_get_peer_certificate, it increase X509 * ref count */
2223 crt = SSL_get_peer_certificate(conn->xprt_ctx);
2224 if (!crt)
2225 goto out;
2226
2227 name = X509_get_subject_name(crt);
2228 if (!name)
2229 goto out;
2230
2231 cn_trash = get_trash_chunk();
2232 if (ssl_sock_get_dn_entry(name, &find_cn_chunk, 1, cn_trash) <= 0)
2233 goto out;
2234 cn_trash->str[cn_trash->len] = '\0';
2235 result = cn_trash->str;
2236
2237 out:
2238 if (crt)
2239 X509_free(crt);
2240
2241 return result;
2242}
2243
2244/* returns 1 if client passed a certificate, 0 if not */
2245int ssl_sock_get_cert_used(struct connection *conn)
2246{
2247 if (!ssl_sock_is_ssl(conn))
2248 return 0;
2249
2250 return SSL_SOCK_ST_FL_VERIFY_DONE & conn->xprt_st ? 1 : 0;
2251}
2252
2253/* returns result from SSL verify */
2254unsigned int ssl_sock_get_verify_result(struct connection *conn)
2255{
2256 if (!ssl_sock_is_ssl(conn))
2257 return (unsigned int)X509_V_ERR_APPLICATION_VERIFICATION;
2258
2259 return (unsigned int)SSL_get_verify_result(conn->xprt_ctx);
2260}
2261
Willy Tarreau7875d092012-09-10 08:20:03 +02002262/***** Below are some sample fetching functions for ACL/patterns *****/
2263
Emeric Brune64aef12012-09-21 13:15:06 +02002264/* boolean, returns true if client cert was present */
2265static int
Emeric Brun2525b6b2012-10-18 15:59:43 +02002266smp_fetch_ssl_fc_has_crt(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002267 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brune64aef12012-09-21 13:15:06 +02002268{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002269 struct connection *conn;
2270
2271 if (!l4)
2272 return 0;
2273
2274 conn = objt_conn(l4->si[0].end);
2275 if (!conn || conn->xprt != &ssl_sock)
Emeric Brune64aef12012-09-21 13:15:06 +02002276 return 0;
2277
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002278 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brune64aef12012-09-21 13:15:06 +02002279 smp->flags |= SMP_F_MAY_CHANGE;
2280 return 0;
2281 }
2282
2283 smp->flags = 0;
2284 smp->type = SMP_T_BOOL;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002285 smp->data.uint = SSL_SOCK_ST_FL_VERIFY_DONE & conn->xprt_st ? 1 : 0;
Emeric Brune64aef12012-09-21 13:15:06 +02002286
2287 return 1;
2288}
2289
Emeric Brunba841a12014-04-30 17:05:08 +02002290/* binary, returns serial of certificate in a binary chunk.
2291 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
2292 * should be use.
2293 */
Willy Tarreau8d598402012-10-22 17:58:39 +02002294static int
Emeric Brunba841a12014-04-30 17:05:08 +02002295smp_fetch_ssl_x_serial(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002296 const struct arg *args, struct sample *smp, const char *kw)
Willy Tarreau8d598402012-10-22 17:58:39 +02002297{
Emeric Brunba841a12014-04-30 17:05:08 +02002298 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Willy Tarreau8d598402012-10-22 17:58:39 +02002299 X509 *crt = NULL;
2300 int ret = 0;
2301 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002302 struct connection *conn;
2303
2304 if (!l4)
2305 return 0;
Willy Tarreau8d598402012-10-22 17:58:39 +02002306
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002307 conn = objt_conn(l4->si[0].end);
2308 if (!conn || conn->xprt != &ssl_sock)
Willy Tarreau8d598402012-10-22 17:58:39 +02002309 return 0;
2310
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002311 if (!(conn->flags & CO_FL_CONNECTED)) {
Willy Tarreau8d598402012-10-22 17:58:39 +02002312 smp->flags |= SMP_F_MAY_CHANGE;
2313 return 0;
2314 }
2315
Emeric Brunba841a12014-04-30 17:05:08 +02002316 if (cert_peer)
2317 crt = SSL_get_peer_certificate(conn->xprt_ctx);
2318 else
2319 crt = SSL_get_certificate(conn->xprt_ctx);
2320
Willy Tarreau8d598402012-10-22 17:58:39 +02002321 if (!crt)
2322 goto out;
2323
Willy Tarreau47ca5452012-12-23 20:22:19 +01002324 smp_trash = get_trash_chunk();
Willy Tarreau8d598402012-10-22 17:58:39 +02002325 if (ssl_sock_get_serial(crt, smp_trash) <= 0)
2326 goto out;
2327
2328 smp->data.str = *smp_trash;
2329 smp->type = SMP_T_BIN;
2330 ret = 1;
2331out:
Emeric Brunba841a12014-04-30 17:05:08 +02002332 /* SSL_get_peer_certificate, it increase X509 * ref count */
2333 if (cert_peer && crt)
Willy Tarreau8d598402012-10-22 17:58:39 +02002334 X509_free(crt);
2335 return ret;
2336}
Emeric Brune64aef12012-09-21 13:15:06 +02002337
Emeric Brunba841a12014-04-30 17:05:08 +02002338/* binary, returns the client certificate's SHA-1 fingerprint (SHA-1 hash of DER-encoded certificate) in a binary chunk.
2339 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
2340 * should be use.
2341 */
James Votha051b4a2013-05-14 20:37:59 +02002342static int
Emeric Brunba841a12014-04-30 17:05:08 +02002343smp_fetch_ssl_x_sha1(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002344 const struct arg *args, struct sample *smp, const char *kw)
James Votha051b4a2013-05-14 20:37:59 +02002345{
Emeric Brunba841a12014-04-30 17:05:08 +02002346 int cert_peer = (kw[4] == 'c') ? 1 : 0;
James Votha051b4a2013-05-14 20:37:59 +02002347 X509 *crt = NULL;
2348 const EVP_MD *digest;
2349 int ret = 0;
2350 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002351 struct connection *conn;
James Votha051b4a2013-05-14 20:37:59 +02002352
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002353 if (!l4)
James Votha051b4a2013-05-14 20:37:59 +02002354 return 0;
2355
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002356 conn = objt_conn(l4->si[0].end);
2357 if (!conn || conn->xprt != &ssl_sock)
2358 return 0;
2359
2360 if (!(conn->flags & CO_FL_CONNECTED)) {
James Votha051b4a2013-05-14 20:37:59 +02002361 smp->flags |= SMP_F_MAY_CHANGE;
2362 return 0;
2363 }
2364
Emeric Brunba841a12014-04-30 17:05:08 +02002365 if (cert_peer)
2366 crt = SSL_get_peer_certificate(conn->xprt_ctx);
2367 else
2368 crt = SSL_get_certificate(conn->xprt_ctx);
James Votha051b4a2013-05-14 20:37:59 +02002369 if (!crt)
2370 goto out;
2371
2372 smp_trash = get_trash_chunk();
2373 digest = EVP_sha1();
2374 X509_digest(crt, digest, (unsigned char *)smp_trash->str, (unsigned int *)&smp_trash->len);
2375
2376 smp->data.str = *smp_trash;
2377 smp->type = SMP_T_BIN;
2378 ret = 1;
2379out:
Emeric Brunba841a12014-04-30 17:05:08 +02002380 /* SSL_get_peer_certificate, it increase X509 * ref count */
2381 if (cert_peer && crt)
James Votha051b4a2013-05-14 20:37:59 +02002382 X509_free(crt);
2383 return ret;
2384}
2385
Emeric Brunba841a12014-04-30 17:05:08 +02002386/* string, returns certificate's notafter date in ASN1_UTCTIME format.
2387 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
2388 * should be use.
2389 */
Emeric Brunce5ad802012-10-22 14:11:22 +02002390static int
Emeric Brunba841a12014-04-30 17:05:08 +02002391smp_fetch_ssl_x_notafter(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002392 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brunce5ad802012-10-22 14:11:22 +02002393{
Emeric Brunba841a12014-04-30 17:05:08 +02002394 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brunce5ad802012-10-22 14:11:22 +02002395 X509 *crt = NULL;
2396 int ret = 0;
2397 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002398 struct connection *conn;
Emeric Brunce5ad802012-10-22 14:11:22 +02002399
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002400 if (!l4)
Emeric Brunce5ad802012-10-22 14:11:22 +02002401 return 0;
2402
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002403 conn = objt_conn(l4->si[0].end);
2404 if (!conn || conn->xprt != &ssl_sock)
2405 return 0;
2406
2407 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunce5ad802012-10-22 14:11:22 +02002408 smp->flags |= SMP_F_MAY_CHANGE;
2409 return 0;
2410 }
2411
Emeric Brunba841a12014-04-30 17:05:08 +02002412 if (cert_peer)
2413 crt = SSL_get_peer_certificate(conn->xprt_ctx);
2414 else
2415 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brunce5ad802012-10-22 14:11:22 +02002416 if (!crt)
2417 goto out;
2418
Willy Tarreau47ca5452012-12-23 20:22:19 +01002419 smp_trash = get_trash_chunk();
Emeric Brunce5ad802012-10-22 14:11:22 +02002420 if (ssl_sock_get_time(X509_get_notAfter(crt), smp_trash) <= 0)
2421 goto out;
2422
2423 smp->data.str = *smp_trash;
2424 smp->type = SMP_T_STR;
2425 ret = 1;
2426out:
Emeric Brunba841a12014-04-30 17:05:08 +02002427 /* SSL_get_peer_certificate, it increase X509 * ref count */
2428 if (cert_peer && crt)
Emeric Brunce5ad802012-10-22 14:11:22 +02002429 X509_free(crt);
2430 return ret;
2431}
2432
Emeric Brunba841a12014-04-30 17:05:08 +02002433/* string, returns a string of a formatted full dn \C=..\O=..\OU=.. \CN=.. of certificate's issuer
2434 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
2435 * should be use.
2436 */
Emeric Brun87855892012-10-17 17:39:35 +02002437static int
Emeric Brunba841a12014-04-30 17:05:08 +02002438smp_fetch_ssl_x_i_dn(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002439 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brun87855892012-10-17 17:39:35 +02002440{
Emeric Brunba841a12014-04-30 17:05:08 +02002441 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brun87855892012-10-17 17:39:35 +02002442 X509 *crt = NULL;
2443 X509_NAME *name;
2444 int ret = 0;
2445 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002446 struct connection *conn;
Emeric Brun87855892012-10-17 17:39:35 +02002447
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002448 if (!l4)
Emeric Brun87855892012-10-17 17:39:35 +02002449 return 0;
2450
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002451 conn = objt_conn(l4->si[0].end);
2452 if (!conn || conn->xprt != &ssl_sock)
2453 return 0;
2454
2455 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun87855892012-10-17 17:39:35 +02002456 smp->flags |= SMP_F_MAY_CHANGE;
2457 return 0;
2458 }
2459
Emeric Brunba841a12014-04-30 17:05:08 +02002460 if (cert_peer)
2461 crt = SSL_get_peer_certificate(conn->xprt_ctx);
2462 else
2463 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brun87855892012-10-17 17:39:35 +02002464 if (!crt)
2465 goto out;
2466
2467 name = X509_get_issuer_name(crt);
2468 if (!name)
2469 goto out;
2470
Willy Tarreau47ca5452012-12-23 20:22:19 +01002471 smp_trash = get_trash_chunk();
Emeric Brun87855892012-10-17 17:39:35 +02002472 if (args && args[0].type == ARGT_STR) {
2473 int pos = 1;
2474
2475 if (args[1].type == ARGT_SINT)
2476 pos = args[1].data.sint;
2477 else if (args[1].type == ARGT_UINT)
2478 pos =(int)args[1].data.uint;
2479
2480 if (ssl_sock_get_dn_entry(name, &args[0].data.str, pos, smp_trash) <= 0)
2481 goto out;
2482 }
2483 else if (ssl_sock_get_dn_oneline(name, smp_trash) <= 0)
2484 goto out;
2485
2486 smp->type = SMP_T_STR;
2487 smp->data.str = *smp_trash;
2488 ret = 1;
2489out:
Emeric Brunba841a12014-04-30 17:05:08 +02002490 /* SSL_get_peer_certificate, it increase X509 * ref count */
2491 if (cert_peer && crt)
Emeric Brun87855892012-10-17 17:39:35 +02002492 X509_free(crt);
2493 return ret;
2494}
2495
Emeric Brunba841a12014-04-30 17:05:08 +02002496/* string, returns notbefore date in ASN1_UTCTIME format.
2497 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
2498 * should be use.
2499 */
Emeric Brunce5ad802012-10-22 14:11:22 +02002500static int
Emeric Brunba841a12014-04-30 17:05:08 +02002501smp_fetch_ssl_x_notbefore(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002502 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brunce5ad802012-10-22 14:11:22 +02002503{
Emeric Brunba841a12014-04-30 17:05:08 +02002504 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brunce5ad802012-10-22 14:11:22 +02002505 X509 *crt = NULL;
2506 int ret = 0;
2507 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002508 struct connection *conn;
2509
2510 if (!l4)
2511 return 0;
Emeric Brunce5ad802012-10-22 14:11:22 +02002512
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002513 conn = objt_conn(l4->si[0].end);
2514 if (!conn || conn->xprt != &ssl_sock)
Emeric Brunce5ad802012-10-22 14:11:22 +02002515 return 0;
2516
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002517 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunce5ad802012-10-22 14:11:22 +02002518 smp->flags |= SMP_F_MAY_CHANGE;
2519 return 0;
2520 }
2521
Emeric Brunba841a12014-04-30 17:05:08 +02002522 if (cert_peer)
2523 crt = SSL_get_peer_certificate(conn->xprt_ctx);
2524 else
2525 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brunce5ad802012-10-22 14:11:22 +02002526 if (!crt)
2527 goto out;
2528
Willy Tarreau47ca5452012-12-23 20:22:19 +01002529 smp_trash = get_trash_chunk();
Emeric Brunce5ad802012-10-22 14:11:22 +02002530 if (ssl_sock_get_time(X509_get_notBefore(crt), smp_trash) <= 0)
2531 goto out;
2532
2533 smp->data.str = *smp_trash;
2534 smp->type = SMP_T_STR;
2535 ret = 1;
2536out:
Emeric Brunba841a12014-04-30 17:05:08 +02002537 /* SSL_get_peer_certificate, it increase X509 * ref count */
2538 if (cert_peer && crt)
Emeric Brunce5ad802012-10-22 14:11:22 +02002539 X509_free(crt);
2540 return ret;
2541}
2542
Emeric Brunba841a12014-04-30 17:05:08 +02002543/* string, returns a string of a formatted full dn \C=..\O=..\OU=.. \CN=.. of certificate's subject
2544 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
2545 * should be use.
2546 */
Emeric Brun87855892012-10-17 17:39:35 +02002547static int
Emeric Brunba841a12014-04-30 17:05:08 +02002548smp_fetch_ssl_x_s_dn(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002549 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brun87855892012-10-17 17:39:35 +02002550{
Emeric Brunba841a12014-04-30 17:05:08 +02002551 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brun87855892012-10-17 17:39:35 +02002552 X509 *crt = NULL;
2553 X509_NAME *name;
2554 int ret = 0;
2555 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002556 struct connection *conn;
Emeric Brun87855892012-10-17 17:39:35 +02002557
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002558 if (!l4)
Emeric Brun87855892012-10-17 17:39:35 +02002559 return 0;
2560
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002561 conn = objt_conn(l4->si[0].end);
2562 if (!conn || conn->xprt != &ssl_sock)
2563 return 0;
2564
2565 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun87855892012-10-17 17:39:35 +02002566 smp->flags |= SMP_F_MAY_CHANGE;
2567 return 0;
2568 }
2569
Emeric Brunba841a12014-04-30 17:05:08 +02002570 if (cert_peer)
2571 crt = SSL_get_peer_certificate(conn->xprt_ctx);
2572 else
2573 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brun87855892012-10-17 17:39:35 +02002574 if (!crt)
2575 goto out;
2576
2577 name = X509_get_subject_name(crt);
2578 if (!name)
2579 goto out;
2580
Willy Tarreau47ca5452012-12-23 20:22:19 +01002581 smp_trash = get_trash_chunk();
Emeric Brun87855892012-10-17 17:39:35 +02002582 if (args && args[0].type == ARGT_STR) {
2583 int pos = 1;
2584
2585 if (args[1].type == ARGT_SINT)
2586 pos = args[1].data.sint;
2587 else if (args[1].type == ARGT_UINT)
2588 pos =(int)args[1].data.uint;
2589
2590 if (ssl_sock_get_dn_entry(name, &args[0].data.str, pos, smp_trash) <= 0)
2591 goto out;
2592 }
2593 else if (ssl_sock_get_dn_oneline(name, smp_trash) <= 0)
2594 goto out;
2595
2596 smp->type = SMP_T_STR;
2597 smp->data.str = *smp_trash;
2598 ret = 1;
2599out:
Emeric Brunba841a12014-04-30 17:05:08 +02002600 /* SSL_get_peer_certificate, it increase X509 * ref count */
2601 if (cert_peer && crt)
Emeric Brun87855892012-10-17 17:39:35 +02002602 X509_free(crt);
2603 return ret;
2604}
Emeric Brun9143d372012-12-20 15:44:16 +01002605
2606/* integer, returns true if current session use a client certificate */
2607static int
2608smp_fetch_ssl_c_used(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002609 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brun9143d372012-12-20 15:44:16 +01002610{
2611 X509 *crt;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002612 struct connection *conn;
Emeric Brun9143d372012-12-20 15:44:16 +01002613
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002614 if (!l4)
Emeric Brun9143d372012-12-20 15:44:16 +01002615 return 0;
2616
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002617 conn = objt_conn(l4->si[0].end);
2618 if (!conn || conn->xprt != &ssl_sock)
2619 return 0;
2620
2621 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun9143d372012-12-20 15:44:16 +01002622 smp->flags |= SMP_F_MAY_CHANGE;
2623 return 0;
2624 }
2625
2626 /* SSL_get_peer_certificate returns a ptr on allocated X509 struct */
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002627 crt = SSL_get_peer_certificate(conn->xprt_ctx);
Emeric Brun9143d372012-12-20 15:44:16 +01002628 if (crt) {
2629 X509_free(crt);
2630 }
2631
2632 smp->type = SMP_T_BOOL;
2633 smp->data.uint = (crt != NULL);
2634 return 1;
2635}
2636
Emeric Brunba841a12014-04-30 17:05:08 +02002637/* integer, returns the certificate version
2638 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
2639 * should be use.
2640 */
Emeric Bruna7359fd2012-10-17 15:03:11 +02002641static int
Emeric Brunba841a12014-04-30 17:05:08 +02002642smp_fetch_ssl_x_version(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002643 const struct arg *args, struct sample *smp, const char *kw)
Emeric Bruna7359fd2012-10-17 15:03:11 +02002644{
Emeric Brunba841a12014-04-30 17:05:08 +02002645 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Bruna7359fd2012-10-17 15:03:11 +02002646 X509 *crt;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002647 struct connection *conn;
2648
2649 if (!l4)
2650 return 0;
Emeric Bruna7359fd2012-10-17 15:03:11 +02002651
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002652 conn = objt_conn(l4->si[0].end);
2653 if (!conn || conn->xprt != &ssl_sock)
Emeric Bruna7359fd2012-10-17 15:03:11 +02002654 return 0;
2655
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002656 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Bruna7359fd2012-10-17 15:03:11 +02002657 smp->flags |= SMP_F_MAY_CHANGE;
2658 return 0;
2659 }
2660
Emeric Brunba841a12014-04-30 17:05:08 +02002661 if (cert_peer)
2662 crt = SSL_get_peer_certificate(conn->xprt_ctx);
2663 else
2664 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Bruna7359fd2012-10-17 15:03:11 +02002665 if (!crt)
2666 return 0;
2667
2668 smp->data.uint = (unsigned int)(1 + X509_get_version(crt));
Emeric Brunba841a12014-04-30 17:05:08 +02002669 /* SSL_get_peer_certificate increase X509 * ref count */
2670 if (cert_peer)
2671 X509_free(crt);
Emeric Bruna7359fd2012-10-17 15:03:11 +02002672 smp->type = SMP_T_UINT;
2673
2674 return 1;
2675}
2676
Emeric Brunba841a12014-04-30 17:05:08 +02002677/* string, returns the certificate's signature algorithm.
2678 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
2679 * should be use.
2680 */
Emeric Brun7f56e742012-10-19 18:15:40 +02002681static int
Emeric Brunba841a12014-04-30 17:05:08 +02002682smp_fetch_ssl_x_sig_alg(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002683 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brun7f56e742012-10-19 18:15:40 +02002684{
Emeric Brunba841a12014-04-30 17:05:08 +02002685 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brun7f56e742012-10-19 18:15:40 +02002686 X509 *crt;
2687 int nid;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002688 struct connection *conn;
Emeric Brun7f56e742012-10-19 18:15:40 +02002689
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002690 if (!l4)
Emeric Brun7f56e742012-10-19 18:15:40 +02002691 return 0;
2692
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002693 conn = objt_conn(l4->si[0].end);
2694 if (!conn || conn->xprt != &ssl_sock)
2695 return 0;
2696
2697 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun7f56e742012-10-19 18:15:40 +02002698 smp->flags |= SMP_F_MAY_CHANGE;
2699 return 0;
2700 }
2701
Emeric Brunba841a12014-04-30 17:05:08 +02002702 if (cert_peer)
2703 crt = SSL_get_peer_certificate(conn->xprt_ctx);
2704 else
2705 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brun7f56e742012-10-19 18:15:40 +02002706 if (!crt)
2707 return 0;
2708
2709 nid = OBJ_obj2nid((ASN1_OBJECT *)(crt->cert_info->signature->algorithm));
2710
2711 smp->data.str.str = (char *)OBJ_nid2sn(nid);
Emeric Brun9bf3ba22013-10-07 14:31:44 +02002712 if (!smp->data.str.str) {
Emeric Brunba841a12014-04-30 17:05:08 +02002713 /* SSL_get_peer_certificate increase X509 * ref count */
2714 if (cert_peer)
2715 X509_free(crt);
Emeric Brun7f56e742012-10-19 18:15:40 +02002716 return 0;
Emeric Brun9bf3ba22013-10-07 14:31:44 +02002717 }
Emeric Brun7f56e742012-10-19 18:15:40 +02002718
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01002719 smp->type = SMP_T_STR;
2720 smp->flags |= SMP_F_CONST;
Emeric Brun7f56e742012-10-19 18:15:40 +02002721 smp->data.str.len = strlen(smp->data.str.str);
Emeric Brunba841a12014-04-30 17:05:08 +02002722 /* SSL_get_peer_certificate increase X509 * ref count */
2723 if (cert_peer)
2724 X509_free(crt);
Emeric Brun7f56e742012-10-19 18:15:40 +02002725
2726 return 1;
2727}
2728
Emeric Brunba841a12014-04-30 17:05:08 +02002729/* string, returns the certificate's key algorithm.
2730 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
2731 * should be use.
2732 */
Emeric Brun521a0112012-10-22 12:22:55 +02002733static int
Emeric Brunba841a12014-04-30 17:05:08 +02002734smp_fetch_ssl_x_key_alg(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002735 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brun521a0112012-10-22 12:22:55 +02002736{
Emeric Brunba841a12014-04-30 17:05:08 +02002737 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brun521a0112012-10-22 12:22:55 +02002738 X509 *crt;
2739 int nid;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002740 struct connection *conn;
Emeric Brun521a0112012-10-22 12:22:55 +02002741
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002742 if (!l4)
Emeric Brun521a0112012-10-22 12:22:55 +02002743 return 0;
2744
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002745 conn = objt_conn(l4->si[0].end);
2746 if (!conn || conn->xprt != &ssl_sock)
2747 return 0;
2748
2749 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun521a0112012-10-22 12:22:55 +02002750 smp->flags |= SMP_F_MAY_CHANGE;
2751 return 0;
2752 }
2753
Emeric Brunba841a12014-04-30 17:05:08 +02002754 if (cert_peer)
2755 crt = SSL_get_peer_certificate(conn->xprt_ctx);
2756 else
2757 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brun521a0112012-10-22 12:22:55 +02002758 if (!crt)
2759 return 0;
2760
2761 nid = OBJ_obj2nid((ASN1_OBJECT *)(crt->cert_info->key->algor->algorithm));
2762
2763 smp->data.str.str = (char *)OBJ_nid2sn(nid);
Emeric Brun9bf3ba22013-10-07 14:31:44 +02002764 if (!smp->data.str.str) {
Emeric Brunba841a12014-04-30 17:05:08 +02002765 /* SSL_get_peer_certificate increase X509 * ref count */
2766 if (cert_peer)
2767 X509_free(crt);
Emeric Brun521a0112012-10-22 12:22:55 +02002768 return 0;
Emeric Brun9bf3ba22013-10-07 14:31:44 +02002769 }
Emeric Brun521a0112012-10-22 12:22:55 +02002770
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01002771 smp->type = SMP_T_STR;
2772 smp->flags |= SMP_F_CONST;
Emeric Brun521a0112012-10-22 12:22:55 +02002773 smp->data.str.len = strlen(smp->data.str.str);
Emeric Brunba841a12014-04-30 17:05:08 +02002774 if (cert_peer)
2775 X509_free(crt);
Emeric Brun521a0112012-10-22 12:22:55 +02002776
2777 return 1;
2778}
2779
Emeric Brun645ae792014-04-30 14:21:06 +02002780/* boolean, returns true if front conn. transport layer is SSL.
2781 * This function is also usable on backend conn if the fetch keyword 5th
2782 * char is 'b'.
2783 */
Willy Tarreau7875d092012-09-10 08:20:03 +02002784static int
Emeric Brun2525b6b2012-10-18 15:59:43 +02002785smp_fetch_ssl_fc(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002786 const struct arg *args, struct sample *smp, const char *kw)
Willy Tarreau7875d092012-09-10 08:20:03 +02002787{
Emeric Brun645ae792014-04-30 14:21:06 +02002788 int back_conn = (kw[4] == 'b') ? 1 : 0;
2789 struct connection *conn = objt_conn(l4->si[back_conn].end);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002790
Willy Tarreau7875d092012-09-10 08:20:03 +02002791 smp->type = SMP_T_BOOL;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002792 smp->data.uint = (conn && conn->xprt == &ssl_sock);
Willy Tarreau7875d092012-09-10 08:20:03 +02002793 return 1;
2794}
2795
Emeric Brun2525b6b2012-10-18 15:59:43 +02002796/* boolean, returns true if client present a SNI */
Willy Tarreau7875d092012-09-10 08:20:03 +02002797static int
Emeric Brun2525b6b2012-10-18 15:59:43 +02002798smp_fetch_ssl_fc_has_sni(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002799 const struct arg *args, struct sample *smp, const char *kw)
Willy Tarreau7875d092012-09-10 08:20:03 +02002800{
2801#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002802 struct connection *conn = objt_conn(l4->si[0].end);
2803
Willy Tarreau7875d092012-09-10 08:20:03 +02002804 smp->type = SMP_T_BOOL;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002805 smp->data.uint = (conn && conn->xprt == &ssl_sock) &&
2806 conn->xprt_ctx &&
2807 SSL_get_servername(conn->xprt_ctx, TLSEXT_NAMETYPE_host_name) != NULL;
Willy Tarreau7875d092012-09-10 08:20:03 +02002808 return 1;
2809#else
2810 return 0;
2811#endif
2812}
2813
Emeric Brun645ae792014-04-30 14:21:06 +02002814/* string, returns the used cipher if front conn. transport layer is SSL.
2815 * This function is also usable on backend conn if the fetch keyword 5th
2816 * char is 'b'.
2817 */
Emeric Brun589fcad2012-10-16 14:13:26 +02002818static int
2819smp_fetch_ssl_fc_cipher(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002820 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brun589fcad2012-10-16 14:13:26 +02002821{
Emeric Brun645ae792014-04-30 14:21:06 +02002822 int back_conn = (kw[4] == 'b') ? 1 : 0;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002823 struct connection *conn;
2824
Emeric Brun589fcad2012-10-16 14:13:26 +02002825 smp->flags = 0;
2826
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002827 if (!l4)
2828 return 0;
2829
Emeric Brun645ae792014-04-30 14:21:06 +02002830 conn = objt_conn(l4->si[back_conn].end);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002831 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
Emeric Brun589fcad2012-10-16 14:13:26 +02002832 return 0;
2833
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002834 smp->data.str.str = (char *)SSL_get_cipher_name(conn->xprt_ctx);
Emeric Brun589fcad2012-10-16 14:13:26 +02002835 if (!smp->data.str.str)
2836 return 0;
2837
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01002838 smp->type = SMP_T_STR;
2839 smp->flags |= SMP_F_CONST;
Emeric Brun589fcad2012-10-16 14:13:26 +02002840 smp->data.str.len = strlen(smp->data.str.str);
2841
2842 return 1;
2843}
2844
Emeric Brun645ae792014-04-30 14:21:06 +02002845/* integer, returns the algoritm's keysize if front conn. transport layer
2846 * is SSL.
2847 * This function is also usable on backend conn if the fetch keyword 5th
2848 * char is 'b'.
2849 */
Emeric Brun589fcad2012-10-16 14:13:26 +02002850static int
2851smp_fetch_ssl_fc_alg_keysize(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002852 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brun589fcad2012-10-16 14:13:26 +02002853{
Emeric Brun645ae792014-04-30 14:21:06 +02002854 int back_conn = (kw[4] == 'b') ? 1 : 0;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002855 struct connection *conn;
2856
Emeric Brun589fcad2012-10-16 14:13:26 +02002857 smp->flags = 0;
2858
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002859 if (!l4)
Emeric Brun589fcad2012-10-16 14:13:26 +02002860 return 0;
2861
Emeric Brun645ae792014-04-30 14:21:06 +02002862 conn = objt_conn(l4->si[back_conn].end);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002863 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
Emeric Brun589fcad2012-10-16 14:13:26 +02002864 return 0;
2865
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002866 if (!SSL_get_cipher_bits(conn->xprt_ctx, (int *)&smp->data.uint))
2867 return 0;
2868
Emeric Brun589fcad2012-10-16 14:13:26 +02002869 smp->type = SMP_T_UINT;
2870
2871 return 1;
2872}
2873
Emeric Brun645ae792014-04-30 14:21:06 +02002874/* integer, returns the used keysize if front conn. transport layer is SSL.
2875 * This function is also usable on backend conn if the fetch keyword 5th
2876 * char is 'b'.
2877 */
Emeric Brun589fcad2012-10-16 14:13:26 +02002878static int
2879smp_fetch_ssl_fc_use_keysize(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002880 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brun589fcad2012-10-16 14:13:26 +02002881{
Emeric Brun645ae792014-04-30 14:21:06 +02002882 int back_conn = (kw[4] == 'b') ? 1 : 0;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002883 struct connection *conn;
2884
Emeric Brun589fcad2012-10-16 14:13:26 +02002885 smp->flags = 0;
2886
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002887 if (!l4)
Emeric Brun589fcad2012-10-16 14:13:26 +02002888 return 0;
2889
Emeric Brun645ae792014-04-30 14:21:06 +02002890 conn = objt_conn(l4->si[back_conn].end);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002891 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
2892 return 0;
2893
2894 smp->data.uint = (unsigned int)SSL_get_cipher_bits(conn->xprt_ctx, NULL);
Emeric Brun589fcad2012-10-16 14:13:26 +02002895 if (!smp->data.uint)
2896 return 0;
2897
2898 smp->type = SMP_T_UINT;
2899
2900 return 1;
2901}
2902
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02002903#ifdef OPENSSL_NPN_NEGOTIATED
Willy Tarreau7875d092012-09-10 08:20:03 +02002904static int
Emeric Brun2525b6b2012-10-18 15:59:43 +02002905smp_fetch_ssl_fc_npn(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002906 const struct arg *args, struct sample *smp, const char *kw)
Willy Tarreaua33c6542012-10-15 13:19:06 +02002907{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002908 struct connection *conn;
2909
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01002910 smp->flags = SMP_F_CONST;
2911 smp->type = SMP_T_STR;
Willy Tarreaua33c6542012-10-15 13:19:06 +02002912
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002913 if (!l4)
Willy Tarreaua33c6542012-10-15 13:19:06 +02002914 return 0;
2915
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002916 conn = objt_conn(l4->si[0].end);
2917 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
2918 return 0;
2919
Willy Tarreaua33c6542012-10-15 13:19:06 +02002920 smp->data.str.str = NULL;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002921 SSL_get0_next_proto_negotiated(conn->xprt_ctx,
Willy Tarreaua33c6542012-10-15 13:19:06 +02002922 (const unsigned char **)&smp->data.str.str, (unsigned *)&smp->data.str.len);
2923
2924 if (!smp->data.str.str)
2925 return 0;
2926
2927 return 1;
Willy Tarreaua33c6542012-10-15 13:19:06 +02002928}
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02002929#endif
Willy Tarreaua33c6542012-10-15 13:19:06 +02002930
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01002931#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Willy Tarreauab861d32013-04-02 02:30:41 +02002932static int
2933smp_fetch_ssl_fc_alpn(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002934 const struct arg *args, struct sample *smp, const char *kw)
Willy Tarreauab861d32013-04-02 02:30:41 +02002935{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002936 struct connection *conn;
2937
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01002938 smp->flags = SMP_F_CONST;
2939 smp->type = SMP_T_STR;
Willy Tarreauab861d32013-04-02 02:30:41 +02002940
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002941 if (!l4)
2942 return 0;
2943
2944 conn = objt_conn(l4->si[0].end);
2945 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
Willy Tarreauab861d32013-04-02 02:30:41 +02002946 return 0;
2947
2948 smp->data.str.str = NULL;
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01002949 SSL_get0_alpn_selected(conn->xprt_ctx,
Willy Tarreauab861d32013-04-02 02:30:41 +02002950 (const unsigned char **)&smp->data.str.str, (unsigned *)&smp->data.str.len);
2951
2952 if (!smp->data.str.str)
2953 return 0;
2954
2955 return 1;
2956}
2957#endif
2958
Emeric Brun645ae792014-04-30 14:21:06 +02002959/* string, returns the used protocol if front conn. transport layer is SSL.
2960 * This function is also usable on backend conn if the fetch keyword 5th
2961 * char is 'b'.
2962 */
Willy Tarreaua33c6542012-10-15 13:19:06 +02002963static int
Emeric Brun589fcad2012-10-16 14:13:26 +02002964smp_fetch_ssl_fc_protocol(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002965 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brun589fcad2012-10-16 14:13:26 +02002966{
Emeric Brun645ae792014-04-30 14:21:06 +02002967 int back_conn = (kw[4] == 'b') ? 1 : 0;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002968 struct connection *conn;
2969
Emeric Brun589fcad2012-10-16 14:13:26 +02002970 smp->flags = 0;
2971
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002972 if (!l4)
Emeric Brun589fcad2012-10-16 14:13:26 +02002973 return 0;
2974
Emeric Brun645ae792014-04-30 14:21:06 +02002975 conn = objt_conn(l4->si[back_conn].end);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002976 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
2977 return 0;
2978
2979 smp->data.str.str = (char *)SSL_get_version(conn->xprt_ctx);
Emeric Brun589fcad2012-10-16 14:13:26 +02002980 if (!smp->data.str.str)
2981 return 0;
2982
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01002983 smp->type = SMP_T_STR;
2984 smp->flags = SMP_F_CONST;
Emeric Brun589fcad2012-10-16 14:13:26 +02002985 smp->data.str.len = strlen(smp->data.str.str);
2986
2987 return 1;
2988}
2989
Emeric Brun645ae792014-04-30 14:21:06 +02002990/* binary, returns the SSL session id if front conn. transport layer is SSL.
2991 * This function is also usable on backend conn if the fetch keyword 5th
2992 * char is 'b'.
2993 */
Emeric Brun589fcad2012-10-16 14:13:26 +02002994static int
Emeric Brunfe68f682012-10-16 14:59:28 +02002995smp_fetch_ssl_fc_session_id(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002996 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brunfe68f682012-10-16 14:59:28 +02002997{
2998#if OPENSSL_VERSION_NUMBER > 0x0090800fL
Emeric Brun645ae792014-04-30 14:21:06 +02002999 int back_conn = (kw[4] == 'b') ? 1 : 0;
Emeric Brunfe68f682012-10-16 14:59:28 +02003000 SSL_SESSION *sess;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003001 struct connection *conn;
Emeric Brunfe68f682012-10-16 14:59:28 +02003002
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01003003 smp->flags = SMP_F_CONST;
3004 smp->type = SMP_T_BIN;
Emeric Brunfe68f682012-10-16 14:59:28 +02003005
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003006 if (!l4)
Emeric Brunfe68f682012-10-16 14:59:28 +02003007 return 0;
3008
Emeric Brun645ae792014-04-30 14:21:06 +02003009 conn = objt_conn(l4->si[back_conn].end);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003010 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
3011 return 0;
3012
3013 sess = SSL_get_session(conn->xprt_ctx);
Emeric Brunfe68f682012-10-16 14:59:28 +02003014 if (!sess)
3015 return 0;
3016
3017 smp->data.str.str = (char *)SSL_SESSION_get_id(sess, (unsigned int *)&smp->data.str.len);
3018 if (!smp->data.str.str || !&smp->data.str.len)
3019 return 0;
3020
3021 return 1;
3022#else
3023 return 0;
3024#endif
3025}
3026
3027static int
Emeric Brun2525b6b2012-10-18 15:59:43 +02003028smp_fetch_ssl_fc_sni(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003029 const struct arg *args, struct sample *smp, const char *kw)
Willy Tarreau7875d092012-09-10 08:20:03 +02003030{
3031#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003032 struct connection *conn;
3033
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01003034 smp->flags = SMP_F_CONST;
3035 smp->type = SMP_T_STR;
Willy Tarreau7875d092012-09-10 08:20:03 +02003036
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003037 if (!l4)
Willy Tarreau7875d092012-09-10 08:20:03 +02003038 return 0;
3039
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003040 conn = objt_conn(l4->si[0].end);
3041 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
3042 return 0;
3043
3044 smp->data.str.str = (char *)SSL_get_servername(conn->xprt_ctx, TLSEXT_NAMETYPE_host_name);
Willy Tarreau3e394c92012-09-14 23:56:58 +02003045 if (!smp->data.str.str)
3046 return 0;
3047
Willy Tarreau7875d092012-09-10 08:20:03 +02003048 smp->data.str.len = strlen(smp->data.str.str);
3049 return 1;
3050#else
3051 return 0;
3052#endif
3053}
3054
David Sc1ad52e2014-04-08 18:48:47 -04003055static int
3056smp_fetch_ssl_fc_unique_id(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
3057 const struct arg *args, struct sample *smp, const char *kw)
3058{
3059#if OPENSSL_VERSION_NUMBER > 0x0090800fL
Emeric Brun645ae792014-04-30 14:21:06 +02003060 int back_conn = (kw[4] == 'b') ? 1 : 0;
David Sc1ad52e2014-04-08 18:48:47 -04003061 struct connection *conn;
3062 int finished_len;
David Sc1ad52e2014-04-08 18:48:47 -04003063 struct chunk *finished_trash;
David Sc1ad52e2014-04-08 18:48:47 -04003064
3065 smp->flags = 0;
3066
3067 if (!l4)
3068 return 0;
3069
Emeric Brun645ae792014-04-30 14:21:06 +02003070 conn = objt_conn(l4->si[back_conn].end);
David Sc1ad52e2014-04-08 18:48:47 -04003071 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
3072 return 0;
3073
3074 if (!(conn->flags & CO_FL_CONNECTED)) {
3075 smp->flags |= SMP_F_MAY_CHANGE;
3076 return 0;
3077 }
3078
3079 finished_trash = get_trash_chunk();
3080 if (!SSL_session_reused(conn->xprt_ctx))
3081 finished_len = SSL_get_peer_finished(conn->xprt_ctx, finished_trash->str, finished_trash->size);
3082 else
3083 finished_len = SSL_get_finished(conn->xprt_ctx, finished_trash->str, finished_trash->size);
3084
3085 if (!finished_len)
3086 return 0;
3087
Emeric Brunb73a9b02014-04-30 18:49:19 +02003088 finished_trash->len = finished_len;
3089 smp->data.str = *finished_trash;
3090 smp->type = SMP_T_BIN;
David Sc1ad52e2014-04-08 18:48:47 -04003091
3092 return 1;
3093#else
3094 return 0;
3095#endif
3096}
3097
Emeric Brun2525b6b2012-10-18 15:59:43 +02003098/* integer, returns the first verify error in CA chain of client certificate chain. */
Emeric Brunf282a812012-09-21 15:27:54 +02003099static int
Emeric Brun2525b6b2012-10-18 15:59:43 +02003100smp_fetch_ssl_c_ca_err(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003101 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brunf282a812012-09-21 15:27:54 +02003102{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003103 struct connection *conn;
3104
3105 if (!l4)
Emeric Brunf282a812012-09-21 15:27:54 +02003106 return 0;
3107
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003108 conn = objt_conn(l4->si[0].end);
3109 if (!conn || conn->xprt != &ssl_sock)
3110 return 0;
3111
3112 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunf282a812012-09-21 15:27:54 +02003113 smp->flags = SMP_F_MAY_CHANGE;
3114 return 0;
3115 }
3116
3117 smp->type = SMP_T_UINT;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003118 smp->data.uint = (unsigned int)SSL_SOCK_ST_TO_CA_ERROR(conn->xprt_st);
Emeric Brunf282a812012-09-21 15:27:54 +02003119 smp->flags = 0;
3120
3121 return 1;
3122}
3123
Emeric Brun2525b6b2012-10-18 15:59:43 +02003124/* integer, returns the depth of the first verify error in CA chain of client certificate chain. */
Emeric Brunf282a812012-09-21 15:27:54 +02003125static int
Emeric Brun2525b6b2012-10-18 15:59:43 +02003126smp_fetch_ssl_c_ca_err_depth(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003127 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brunf282a812012-09-21 15:27:54 +02003128{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003129 struct connection *conn;
3130
3131 if (!l4)
3132 return 0;
3133
3134 conn = objt_conn(l4->si[0].end);
3135 if (!conn || conn->xprt != &ssl_sock)
Emeric Brunf282a812012-09-21 15:27:54 +02003136 return 0;
3137
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003138 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunf282a812012-09-21 15:27:54 +02003139 smp->flags = SMP_F_MAY_CHANGE;
3140 return 0;
3141 }
3142
3143 smp->type = SMP_T_UINT;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003144 smp->data.uint = (unsigned int)SSL_SOCK_ST_TO_CAEDEPTH(conn->xprt_st);
Emeric Brunf282a812012-09-21 15:27:54 +02003145 smp->flags = 0;
3146
3147 return 1;
3148}
3149
Emeric Brun2525b6b2012-10-18 15:59:43 +02003150/* integer, returns the first verify error on client certificate */
Emeric Brunf282a812012-09-21 15:27:54 +02003151static int
Emeric Brun2525b6b2012-10-18 15:59:43 +02003152smp_fetch_ssl_c_err(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003153 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brunf282a812012-09-21 15:27:54 +02003154{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003155 struct connection *conn;
3156
3157 if (!l4)
Emeric Brunf282a812012-09-21 15:27:54 +02003158 return 0;
3159
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003160 conn = objt_conn(l4->si[0].end);
3161 if (!conn || conn->xprt != &ssl_sock)
3162 return 0;
3163
3164 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunf282a812012-09-21 15:27:54 +02003165 smp->flags = SMP_F_MAY_CHANGE;
3166 return 0;
3167 }
3168
3169 smp->type = SMP_T_UINT;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003170 smp->data.uint = (unsigned int)SSL_SOCK_ST_TO_CRTERROR(conn->xprt_st);
Emeric Brunf282a812012-09-21 15:27:54 +02003171 smp->flags = 0;
3172
3173 return 1;
3174}
3175
Emeric Brun2525b6b2012-10-18 15:59:43 +02003176/* integer, returns the verify result on client cert */
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02003177static int
Emeric Brun2525b6b2012-10-18 15:59:43 +02003178smp_fetch_ssl_c_verify(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003179 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02003180{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003181 struct connection *conn;
3182
3183 if (!l4)
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02003184 return 0;
3185
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003186 conn = objt_conn(l4->si[0].end);
3187 if (!conn || conn->xprt != &ssl_sock)
3188 return 0;
3189
3190 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02003191 smp->flags = SMP_F_MAY_CHANGE;
3192 return 0;
3193 }
3194
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003195 if (!conn->xprt_ctx)
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02003196 return 0;
3197
3198 smp->type = SMP_T_UINT;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003199 smp->data.uint = (unsigned int)SSL_get_verify_result(conn->xprt_ctx);
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02003200 smp->flags = 0;
3201
3202 return 1;
3203}
3204
Emeric Brunfb510ea2012-10-05 12:00:26 +02003205/* parse the "ca-file" bind keyword */
3206static 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 +02003207{
3208 if (!*args[cur_arg + 1]) {
3209 if (err)
3210 memprintf(err, "'%s' : missing CAfile path", args[cur_arg]);
3211 return ERR_ALERT | ERR_FATAL;
3212 }
3213
Emeric Brunef42d922012-10-11 16:11:36 +02003214 if ((*args[cur_arg + 1] != '/') && global.ca_base)
3215 memprintf(&conf->ca_file, "%s/%s", global.ca_base, args[cur_arg + 1]);
3216 else
3217 memprintf(&conf->ca_file, "%s", args[cur_arg + 1]);
Emeric Brunc8e8d122012-10-02 18:42:10 +02003218
Emeric Brund94b3fe2012-09-20 18:23:56 +02003219 return 0;
3220}
3221
Willy Tarreau79eeafa2012-09-14 07:53:05 +02003222/* parse the "ciphers" bind keyword */
Willy Tarreau4348fad2012-09-20 16:48:07 +02003223static 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 +02003224{
3225 if (!*args[cur_arg + 1]) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02003226 memprintf(err, "'%s' : missing cipher suite", args[cur_arg]);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02003227 return ERR_ALERT | ERR_FATAL;
3228 }
3229
Emeric Brun76d88952012-10-05 15:47:31 +02003230 free(conf->ciphers);
Willy Tarreau4348fad2012-09-20 16:48:07 +02003231 conf->ciphers = strdup(args[cur_arg + 1]);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02003232 return 0;
3233}
3234
3235/* parse the "crt" bind keyword */
Willy Tarreau4348fad2012-09-20 16:48:07 +02003236static 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 +02003237{
Willy Tarreau38011032013-08-13 16:59:39 +02003238 char path[MAXPATHLEN];
Willy Tarreaub75d6922014-04-14 18:05:41 +02003239
Willy Tarreau79eeafa2012-09-14 07:53:05 +02003240 if (!*args[cur_arg + 1]) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02003241 memprintf(err, "'%s' : missing certificate location", args[cur_arg]);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02003242 return ERR_ALERT | ERR_FATAL;
3243 }
3244
Emeric Brunc8e8d122012-10-02 18:42:10 +02003245 if ((*args[cur_arg + 1] != '/' ) && global.crt_base) {
Willy Tarreau38011032013-08-13 16:59:39 +02003246 if ((strlen(global.crt_base) + 1 + strlen(args[cur_arg + 1]) + 1) > MAXPATHLEN) {
Emeric Brunc8e8d122012-10-02 18:42:10 +02003247 memprintf(err, "'%s' : path too long", args[cur_arg]);
3248 return ERR_ALERT | ERR_FATAL;
3249 }
Willy Tarreaub75d6922014-04-14 18:05:41 +02003250 snprintf(path, sizeof(path), "%s/%s", global.crt_base, args[cur_arg + 1]);
Emeric Brunc8e8d122012-10-02 18:42:10 +02003251 if (ssl_sock_load_cert(path, conf, px, err) > 0)
3252 return ERR_ALERT | ERR_FATAL;
3253
3254 return 0;
3255 }
3256
Willy Tarreau4348fad2012-09-20 16:48:07 +02003257 if (ssl_sock_load_cert(args[cur_arg + 1], conf, px, err) > 0)
Willy Tarreau79eeafa2012-09-14 07:53:05 +02003258 return ERR_ALERT | ERR_FATAL;
Emeric Brund94b3fe2012-09-20 18:23:56 +02003259
3260 return 0;
3261}
3262
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01003263/* parse the "crt-list" bind keyword */
3264static int bind_parse_crt_list(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
3265{
3266 if (!*args[cur_arg + 1]) {
3267 memprintf(err, "'%s' : missing certificate location", args[cur_arg]);
3268 return ERR_ALERT | ERR_FATAL;
3269 }
3270
Willy Tarreauad1731d2013-04-02 17:35:58 +02003271 if (ssl_sock_load_cert_list_file(args[cur_arg + 1], conf, px, err) > 0) {
3272 memprintf(err, "'%s' : %s", args[cur_arg], *err);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01003273 return ERR_ALERT | ERR_FATAL;
Willy Tarreauad1731d2013-04-02 17:35:58 +02003274 }
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01003275
3276 return 0;
3277}
3278
Emeric Brunfb510ea2012-10-05 12:00:26 +02003279/* parse the "crl-file" bind keyword */
3280static 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 +02003281{
Emeric Brun051cdab2012-10-02 19:25:50 +02003282#ifndef X509_V_FLAG_CRL_CHECK
3283 if (err)
3284 memprintf(err, "'%s' : library does not support CRL verify", args[cur_arg]);
3285 return ERR_ALERT | ERR_FATAL;
3286#else
Emeric Brund94b3fe2012-09-20 18:23:56 +02003287 if (!*args[cur_arg + 1]) {
3288 if (err)
3289 memprintf(err, "'%s' : missing CRLfile path", args[cur_arg]);
3290 return ERR_ALERT | ERR_FATAL;
3291 }
Emeric Brun2b58d042012-09-20 17:10:03 +02003292
Emeric Brunef42d922012-10-11 16:11:36 +02003293 if ((*args[cur_arg + 1] != '/') && global.ca_base)
3294 memprintf(&conf->crl_file, "%s/%s", global.ca_base, args[cur_arg + 1]);
3295 else
3296 memprintf(&conf->crl_file, "%s", args[cur_arg + 1]);
Emeric Brunc8e8d122012-10-02 18:42:10 +02003297
Emeric Brun2b58d042012-09-20 17:10:03 +02003298 return 0;
Emeric Brun051cdab2012-10-02 19:25:50 +02003299#endif
Emeric Brun2b58d042012-09-20 17:10:03 +02003300}
3301
3302/* parse the "ecdhe" bind keyword keywords */
3303static int bind_parse_ecdhe(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
3304{
3305#if OPENSSL_VERSION_NUMBER < 0x0090800fL
3306 if (err)
3307 memprintf(err, "'%s' : library does not support elliptic curve Diffie-Hellman (too old)", args[cur_arg]);
3308 return ERR_ALERT | ERR_FATAL;
3309#elif defined(OPENSSL_NO_ECDH)
3310 if (err)
3311 memprintf(err, "'%s' : library does not support elliptic curve Diffie-Hellman (disabled via OPENSSL_NO_ECDH)", args[cur_arg]);
3312 return ERR_ALERT | ERR_FATAL;
3313#else
3314 if (!*args[cur_arg + 1]) {
3315 if (err)
3316 memprintf(err, "'%s' : missing named curve", args[cur_arg]);
3317 return ERR_ALERT | ERR_FATAL;
3318 }
3319
3320 conf->ecdhe = strdup(args[cur_arg + 1]);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02003321
3322 return 0;
Emeric Brun2b58d042012-09-20 17:10:03 +02003323#endif
Willy Tarreau79eeafa2012-09-14 07:53:05 +02003324}
3325
Emeric Brun81c00f02012-09-21 14:31:21 +02003326/* parse the "crt_ignerr" and "ca_ignerr" bind keywords */
3327static int bind_parse_ignore_err(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
3328{
3329 int code;
3330 char *p = args[cur_arg + 1];
3331 unsigned long long *ignerr = &conf->crt_ignerr;
3332
3333 if (!*p) {
3334 if (err)
3335 memprintf(err, "'%s' : missing error IDs list", args[cur_arg]);
3336 return ERR_ALERT | ERR_FATAL;
3337 }
3338
3339 if (strcmp(args[cur_arg], "ca-ignore-err") == 0)
3340 ignerr = &conf->ca_ignerr;
3341
3342 if (strcmp(p, "all") == 0) {
3343 *ignerr = ~0ULL;
3344 return 0;
3345 }
3346
3347 while (p) {
3348 code = atoi(p);
3349 if ((code <= 0) || (code > 63)) {
3350 if (err)
3351 memprintf(err, "'%s' : ID '%d' out of range (1..63) in error IDs list '%s'",
3352 args[cur_arg], code, args[cur_arg + 1]);
3353 return ERR_ALERT | ERR_FATAL;
3354 }
3355 *ignerr |= 1ULL << code;
3356 p = strchr(p, ',');
3357 if (p)
3358 p++;
3359 }
3360
Emeric Brun2cb7ae52012-10-05 14:14:21 +02003361 return 0;
3362}
3363
3364/* parse the "force-sslv3" bind keyword */
3365static int bind_parse_force_sslv3(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
3366{
3367 conf->ssl_options |= BC_SSL_O_USE_SSLV3;
3368 return 0;
3369}
3370
3371/* parse the "force-tlsv10" bind keyword */
3372static int bind_parse_force_tlsv10(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
3373{
3374 conf->ssl_options |= BC_SSL_O_USE_TLSV10;
Emeric Brun2d0c4822012-10-02 13:45:20 +02003375 return 0;
3376}
3377
Emeric Brun2cb7ae52012-10-05 14:14:21 +02003378/* parse the "force-tlsv11" bind keyword */
3379static int bind_parse_force_tlsv11(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
3380{
3381#if SSL_OP_NO_TLSv1_1
3382 conf->ssl_options |= BC_SSL_O_USE_TLSV11;
3383 return 0;
3384#else
3385 if (err)
3386 memprintf(err, "'%s' : library does not support protocol TLSv1.1", args[cur_arg]);
3387 return ERR_ALERT | ERR_FATAL;
3388#endif
3389}
3390
3391/* parse the "force-tlsv12" bind keyword */
3392static int bind_parse_force_tlsv12(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
3393{
3394#if SSL_OP_NO_TLSv1_2
3395 conf->ssl_options |= BC_SSL_O_USE_TLSV12;
3396 return 0;
3397#else
3398 if (err)
3399 memprintf(err, "'%s' : library does not support protocol TLSv1.2", args[cur_arg]);
3400 return ERR_ALERT | ERR_FATAL;
3401#endif
3402}
3403
3404
Emeric Brun2d0c4822012-10-02 13:45:20 +02003405/* parse the "no-tls-tickets" bind keyword */
3406static int bind_parse_no_tls_tickets(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
3407{
Emeric Brun89675492012-10-05 13:48:26 +02003408 conf->ssl_options |= BC_SSL_O_NO_TLS_TICKETS;
Emeric Brun81c00f02012-09-21 14:31:21 +02003409 return 0;
3410}
3411
Emeric Brun2d0c4822012-10-02 13:45:20 +02003412
Emeric Brun9b3009b2012-10-05 11:55:06 +02003413/* parse the "no-sslv3" bind keyword */
3414static 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 +02003415{
Emeric Brun89675492012-10-05 13:48:26 +02003416 conf->ssl_options |= BC_SSL_O_NO_SSLV3;
Willy Tarreau79eeafa2012-09-14 07:53:05 +02003417 return 0;
3418}
3419
Emeric Brun9b3009b2012-10-05 11:55:06 +02003420/* parse the "no-tlsv10" bind keyword */
3421static 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 +02003422{
Emeric Brun89675492012-10-05 13:48:26 +02003423 conf->ssl_options |= BC_SSL_O_NO_TLSV10;
Emeric Brunc0ff4922012-09-28 19:37:02 +02003424 return 0;
3425}
3426
Emeric Brun9b3009b2012-10-05 11:55:06 +02003427/* parse the "no-tlsv11" bind keyword */
3428static 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 +02003429{
Emeric Brun89675492012-10-05 13:48:26 +02003430 conf->ssl_options |= BC_SSL_O_NO_TLSV11;
Emeric Brunc0ff4922012-09-28 19:37:02 +02003431 return 0;
3432}
3433
Emeric Brun9b3009b2012-10-05 11:55:06 +02003434/* parse the "no-tlsv12" bind keyword */
3435static 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 +02003436{
Emeric Brun89675492012-10-05 13:48:26 +02003437 conf->ssl_options |= BC_SSL_O_NO_TLSV12;
Willy Tarreau79eeafa2012-09-14 07:53:05 +02003438 return 0;
3439}
3440
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02003441/* parse the "npn" bind keyword */
3442static int bind_parse_npn(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
3443{
3444#ifdef OPENSSL_NPN_NEGOTIATED
3445 char *p1, *p2;
3446
3447 if (!*args[cur_arg + 1]) {
3448 memprintf(err, "'%s' : missing the comma-delimited NPN protocol suite", args[cur_arg]);
3449 return ERR_ALERT | ERR_FATAL;
3450 }
3451
3452 free(conf->npn_str);
3453
3454 /* the NPN string is built as a suite of (<len> <name>)* */
3455 conf->npn_len = strlen(args[cur_arg + 1]) + 1;
3456 conf->npn_str = calloc(1, conf->npn_len);
3457 memcpy(conf->npn_str + 1, args[cur_arg + 1], conf->npn_len);
3458
3459 /* replace commas with the name length */
3460 p1 = conf->npn_str;
3461 p2 = p1 + 1;
3462 while (1) {
3463 p2 = memchr(p1 + 1, ',', conf->npn_str + conf->npn_len - (p1 + 1));
3464 if (!p2)
3465 p2 = p1 + 1 + strlen(p1 + 1);
3466
3467 if (p2 - (p1 + 1) > 255) {
3468 *p2 = '\0';
3469 memprintf(err, "'%s' : NPN protocol name too long : '%s'", args[cur_arg], p1 + 1);
3470 return ERR_ALERT | ERR_FATAL;
3471 }
3472
3473 *p1 = p2 - (p1 + 1);
3474 p1 = p2;
3475
3476 if (!*p2)
3477 break;
3478
3479 *(p2++) = '\0';
3480 }
3481 return 0;
3482#else
3483 if (err)
3484 memprintf(err, "'%s' : library does not support TLS NPN extension", args[cur_arg]);
3485 return ERR_ALERT | ERR_FATAL;
3486#endif
3487}
3488
Willy Tarreauab861d32013-04-02 02:30:41 +02003489/* parse the "alpn" bind keyword */
3490static int bind_parse_alpn(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
3491{
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01003492#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Willy Tarreauab861d32013-04-02 02:30:41 +02003493 char *p1, *p2;
3494
3495 if (!*args[cur_arg + 1]) {
3496 memprintf(err, "'%s' : missing the comma-delimited ALPN protocol suite", args[cur_arg]);
3497 return ERR_ALERT | ERR_FATAL;
3498 }
3499
3500 free(conf->alpn_str);
3501
3502 /* the ALPN string is built as a suite of (<len> <name>)* */
3503 conf->alpn_len = strlen(args[cur_arg + 1]) + 1;
3504 conf->alpn_str = calloc(1, conf->alpn_len);
3505 memcpy(conf->alpn_str + 1, args[cur_arg + 1], conf->alpn_len);
3506
3507 /* replace commas with the name length */
3508 p1 = conf->alpn_str;
3509 p2 = p1 + 1;
3510 while (1) {
3511 p2 = memchr(p1 + 1, ',', conf->alpn_str + conf->alpn_len - (p1 + 1));
3512 if (!p2)
3513 p2 = p1 + 1 + strlen(p1 + 1);
3514
3515 if (p2 - (p1 + 1) > 255) {
3516 *p2 = '\0';
3517 memprintf(err, "'%s' : ALPN protocol name too long : '%s'", args[cur_arg], p1 + 1);
3518 return ERR_ALERT | ERR_FATAL;
3519 }
3520
3521 *p1 = p2 - (p1 + 1);
3522 p1 = p2;
3523
3524 if (!*p2)
3525 break;
3526
3527 *(p2++) = '\0';
3528 }
3529 return 0;
3530#else
3531 if (err)
3532 memprintf(err, "'%s' : library does not support TLS ALPN extension", args[cur_arg]);
3533 return ERR_ALERT | ERR_FATAL;
3534#endif
3535}
3536
Willy Tarreau79eeafa2012-09-14 07:53:05 +02003537/* parse the "ssl" bind keyword */
Willy Tarreau4348fad2012-09-20 16:48:07 +02003538static 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 +02003539{
Willy Tarreau81796be2012-09-22 19:11:47 +02003540 struct listener *l;
3541
Willy Tarreau4348fad2012-09-20 16:48:07 +02003542 conf->is_ssl = 1;
Emeric Brun76d88952012-10-05 15:47:31 +02003543
3544 if (global.listen_default_ciphers && !conf->ciphers)
3545 conf->ciphers = strdup(global.listen_default_ciphers);
3546
Willy Tarreau81796be2012-09-22 19:11:47 +02003547 list_for_each_entry(l, &conf->listeners, by_bind)
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02003548 l->xprt = &ssl_sock;
Willy Tarreau81796be2012-09-22 19:11:47 +02003549
Willy Tarreau79eeafa2012-09-14 07:53:05 +02003550 return 0;
3551}
3552
Emmanuel Hocdet65623372013-01-24 17:17:15 +01003553/* parse the "strict-sni" bind keyword */
3554static int bind_parse_strict_sni(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
3555{
3556 conf->strict_sni = 1;
3557 return 0;
3558}
3559
Emeric Brund94b3fe2012-09-20 18:23:56 +02003560/* parse the "verify" bind keyword */
3561static int bind_parse_verify(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
3562{
3563 if (!*args[cur_arg + 1]) {
3564 if (err)
3565 memprintf(err, "'%s' : missing verify method", args[cur_arg]);
3566 return ERR_ALERT | ERR_FATAL;
3567 }
3568
3569 if (strcmp(args[cur_arg + 1], "none") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01003570 conf->verify = SSL_SOCK_VERIFY_NONE;
Emeric Brund94b3fe2012-09-20 18:23:56 +02003571 else if (strcmp(args[cur_arg + 1], "optional") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01003572 conf->verify = SSL_SOCK_VERIFY_OPTIONAL;
Emeric Brund94b3fe2012-09-20 18:23:56 +02003573 else if (strcmp(args[cur_arg + 1], "required") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01003574 conf->verify = SSL_SOCK_VERIFY_REQUIRED;
Emeric Brund94b3fe2012-09-20 18:23:56 +02003575 else {
3576 if (err)
3577 memprintf(err, "'%s' : unknown verify method '%s', only 'none', 'optional', and 'required' are supported\n",
3578 args[cur_arg], args[cur_arg + 1]);
3579 return ERR_ALERT | ERR_FATAL;
3580 }
3581
3582 return 0;
3583}
3584
Willy Tarreau92faadf2012-10-10 23:04:25 +02003585/************** "server" keywords ****************/
3586
Emeric Brunef42d922012-10-11 16:11:36 +02003587/* parse the "ca-file" server keyword */
3588static int srv_parse_ca_file(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
3589{
3590 if (!*args[*cur_arg + 1]) {
3591 if (err)
3592 memprintf(err, "'%s' : missing CAfile path", args[*cur_arg]);
3593 return ERR_ALERT | ERR_FATAL;
3594 }
3595
3596 if ((*args[*cur_arg + 1] != '/') && global.ca_base)
3597 memprintf(&newsrv->ssl_ctx.ca_file, "%s/%s", global.ca_base, args[*cur_arg + 1]);
3598 else
3599 memprintf(&newsrv->ssl_ctx.ca_file, "%s", args[*cur_arg + 1]);
3600
3601 return 0;
3602}
3603
Willy Tarreau92faadf2012-10-10 23:04:25 +02003604/* parse the "check-ssl" server keyword */
3605static int srv_parse_check_ssl(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
3606{
3607 newsrv->check.use_ssl = 1;
3608 if (global.connect_default_ciphers && !newsrv->ssl_ctx.ciphers)
3609 newsrv->ssl_ctx.ciphers = strdup(global.connect_default_ciphers);
3610 return 0;
3611}
3612
3613/* parse the "ciphers" server keyword */
3614static int srv_parse_ciphers(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
3615{
3616 if (!*args[*cur_arg + 1]) {
3617 memprintf(err, "'%s' : missing cipher suite", args[*cur_arg]);
3618 return ERR_ALERT | ERR_FATAL;
3619 }
3620
3621 free(newsrv->ssl_ctx.ciphers);
3622 newsrv->ssl_ctx.ciphers = strdup(args[*cur_arg + 1]);
3623 return 0;
3624}
3625
Emeric Brunef42d922012-10-11 16:11:36 +02003626/* parse the "crl-file" server keyword */
3627static int srv_parse_crl_file(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
3628{
3629#ifndef X509_V_FLAG_CRL_CHECK
3630 if (err)
3631 memprintf(err, "'%s' : library does not support CRL verify", args[*cur_arg]);
3632 return ERR_ALERT | ERR_FATAL;
3633#else
3634 if (!*args[*cur_arg + 1]) {
3635 if (err)
3636 memprintf(err, "'%s' : missing CRLfile path", args[*cur_arg]);
3637 return ERR_ALERT | ERR_FATAL;
3638 }
3639
3640 if ((*args[*cur_arg + 1] != '/') && global.ca_base)
3641 memprintf(&newsrv->ssl_ctx.crl_file, "%s/%s", global.ca_base, args[*cur_arg + 1]);
3642 else
3643 memprintf(&newsrv->ssl_ctx.crl_file, "%s", args[*cur_arg + 1]);
3644
3645 return 0;
3646#endif
3647}
3648
Emeric Bruna7aa3092012-10-26 12:58:00 +02003649/* parse the "crt" server keyword */
3650static int srv_parse_crt(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
3651{
3652 if (!*args[*cur_arg + 1]) {
3653 if (err)
3654 memprintf(err, "'%s' : missing certificate file path", args[*cur_arg]);
3655 return ERR_ALERT | ERR_FATAL;
3656 }
3657
3658 if ((*args[*cur_arg + 1] != '/') && global.crt_base)
3659 memprintf(&newsrv->ssl_ctx.client_crt, "%s/%s", global.ca_base, args[*cur_arg + 1]);
3660 else
3661 memprintf(&newsrv->ssl_ctx.client_crt, "%s", args[*cur_arg + 1]);
3662
3663 return 0;
3664}
Emeric Brunef42d922012-10-11 16:11:36 +02003665
Willy Tarreau92faadf2012-10-10 23:04:25 +02003666/* parse the "force-sslv3" server keyword */
3667static int srv_parse_force_sslv3(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
3668{
3669 newsrv->ssl_ctx.options |= SRV_SSL_O_USE_SSLV3;
3670 return 0;
3671}
3672
3673/* parse the "force-tlsv10" server keyword */
3674static int srv_parse_force_tlsv10(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
3675{
3676 newsrv->ssl_ctx.options |= SRV_SSL_O_USE_TLSV10;
3677 return 0;
3678}
3679
3680/* parse the "force-tlsv11" server keyword */
3681static int srv_parse_force_tlsv11(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
3682{
3683#if SSL_OP_NO_TLSv1_1
3684 newsrv->ssl_ctx.options |= SRV_SSL_O_USE_TLSV11;
3685 return 0;
3686#else
3687 if (err)
3688 memprintf(err, "'%s' : library does not support protocol TLSv1.1", args[*cur_arg]);
3689 return ERR_ALERT | ERR_FATAL;
3690#endif
3691}
3692
3693/* parse the "force-tlsv12" server keyword */
3694static int srv_parse_force_tlsv12(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
3695{
3696#if SSL_OP_NO_TLSv1_2
3697 newsrv->ssl_ctx.options |= SRV_SSL_O_USE_TLSV12;
3698 return 0;
3699#else
3700 if (err)
3701 memprintf(err, "'%s' : library does not support protocol TLSv1.2", args[*cur_arg]);
3702 return ERR_ALERT | ERR_FATAL;
3703#endif
3704}
3705
3706/* parse the "no-sslv3" server keyword */
3707static int srv_parse_no_sslv3(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
3708{
3709 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_SSLV3;
3710 return 0;
3711}
3712
3713/* parse the "no-tlsv10" server keyword */
3714static int srv_parse_no_tlsv10(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
3715{
3716 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_TLSV10;
3717 return 0;
3718}
3719
3720/* parse the "no-tlsv11" server keyword */
3721static int srv_parse_no_tlsv11(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
3722{
3723 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_TLSV11;
3724 return 0;
3725}
3726
3727/* parse the "no-tlsv12" server keyword */
3728static int srv_parse_no_tlsv12(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
3729{
3730 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_TLSV12;
3731 return 0;
3732}
3733
Emeric Brunf9c5c472012-10-11 15:28:34 +02003734/* parse the "no-tls-tickets" server keyword */
3735static int srv_parse_no_tls_tickets(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
3736{
3737 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_TLS_TICKETS;
3738 return 0;
3739}
David Safb76832014-05-08 23:42:08 -04003740/* parse the "send-proxy-v2-ssl" server keyword */
3741static int srv_parse_send_proxy_ssl(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
3742{
3743 newsrv->pp_opts |= SRV_PP_V2;
3744 newsrv->pp_opts |= SRV_PP_V2_SSL;
3745 return 0;
3746}
3747
3748/* parse the "send-proxy-v2-ssl-cn" server keyword */
3749static int srv_parse_send_proxy_cn(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
3750{
3751 newsrv->pp_opts |= SRV_PP_V2;
3752 newsrv->pp_opts |= SRV_PP_V2_SSL;
3753 newsrv->pp_opts |= SRV_PP_V2_SSL_CN;
3754 return 0;
3755}
Emeric Brunf9c5c472012-10-11 15:28:34 +02003756
Willy Tarreau92faadf2012-10-10 23:04:25 +02003757/* parse the "ssl" server keyword */
3758static int srv_parse_ssl(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
3759{
3760 newsrv->use_ssl = 1;
3761 if (global.connect_default_ciphers && !newsrv->ssl_ctx.ciphers)
3762 newsrv->ssl_ctx.ciphers = strdup(global.connect_default_ciphers);
3763 return 0;
3764}
3765
Emeric Brunef42d922012-10-11 16:11:36 +02003766/* parse the "verify" server keyword */
3767static int srv_parse_verify(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
3768{
3769 if (!*args[*cur_arg + 1]) {
3770 if (err)
3771 memprintf(err, "'%s' : missing verify method", args[*cur_arg]);
3772 return ERR_ALERT | ERR_FATAL;
3773 }
3774
3775 if (strcmp(args[*cur_arg + 1], "none") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01003776 newsrv->ssl_ctx.verify = SSL_SOCK_VERIFY_NONE;
Emeric Brunef42d922012-10-11 16:11:36 +02003777 else if (strcmp(args[*cur_arg + 1], "required") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01003778 newsrv->ssl_ctx.verify = SSL_SOCK_VERIFY_REQUIRED;
Emeric Brunef42d922012-10-11 16:11:36 +02003779 else {
3780 if (err)
3781 memprintf(err, "'%s' : unknown verify method '%s', only 'none' and 'required' are supported\n",
3782 args[*cur_arg], args[*cur_arg + 1]);
3783 return ERR_ALERT | ERR_FATAL;
3784 }
3785
Evan Broderbe554312013-06-27 00:05:25 -07003786 return 0;
3787}
3788
3789/* parse the "verifyhost" server keyword */
3790static int srv_parse_verifyhost(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
3791{
3792 if (!*args[*cur_arg + 1]) {
3793 if (err)
3794 memprintf(err, "'%s' : missing hostname to verify against", args[*cur_arg]);
3795 return ERR_ALERT | ERR_FATAL;
3796 }
3797
3798 newsrv->ssl_ctx.verify_host = strdup(args[*cur_arg + 1]);
3799
Emeric Brunef42d922012-10-11 16:11:36 +02003800 return 0;
3801}
3802
Willy Tarreau7875d092012-09-10 08:20:03 +02003803/* Note: must not be declared <const> as its list will be overwritten.
3804 * Please take care of keeping this list alphabetically sorted.
3805 */
Willy Tarreaudc13c112013-06-21 23:16:39 +02003806static struct sample_fetch_kw_list sample_fetch_keywords = {ILH, {
Emeric Brun645ae792014-04-30 14:21:06 +02003807 { "ssl_bc", smp_fetch_ssl_fc, 0, NULL, SMP_T_BOOL, SMP_USE_L5SRV },
3808 { "ssl_bc_alg_keysize", smp_fetch_ssl_fc_alg_keysize, 0, NULL, SMP_T_UINT, SMP_USE_L5SRV },
3809 { "ssl_bc_cipher", smp_fetch_ssl_fc_cipher, 0, NULL, SMP_T_STR, SMP_USE_L5SRV },
3810 { "ssl_bc_protocol", smp_fetch_ssl_fc_protocol, 0, NULL, SMP_T_STR, SMP_USE_L5SRV },
Emeric Brunb73a9b02014-04-30 18:49:19 +02003811 { "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 +02003812 { "ssl_bc_use_keysize", smp_fetch_ssl_fc_use_keysize, 0, NULL, SMP_T_UINT, SMP_USE_L5SRV },
3813 { "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 +01003814 { "ssl_c_ca_err", smp_fetch_ssl_c_ca_err, 0, NULL, SMP_T_UINT, SMP_USE_L5CLI },
3815 { "ssl_c_ca_err_depth", smp_fetch_ssl_c_ca_err_depth, 0, NULL, SMP_T_UINT, SMP_USE_L5CLI },
3816 { "ssl_c_err", smp_fetch_ssl_c_err, 0, NULL, SMP_T_UINT, SMP_USE_L5CLI },
Emeric Brunba841a12014-04-30 17:05:08 +02003817 { "ssl_c_i_dn", smp_fetch_ssl_x_i_dn, ARG2(0,STR,SINT), NULL, SMP_T_STR, SMP_USE_L5CLI },
3818 { "ssl_c_key_alg", smp_fetch_ssl_x_key_alg, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
3819 { "ssl_c_notafter", smp_fetch_ssl_x_notafter, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
3820 { "ssl_c_notbefore", smp_fetch_ssl_x_notbefore, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
3821 { "ssl_c_sig_alg", smp_fetch_ssl_x_sig_alg, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
3822 { "ssl_c_s_dn", smp_fetch_ssl_x_s_dn, ARG2(0,STR,SINT), NULL, SMP_T_STR, SMP_USE_L5CLI },
3823 { "ssl_c_serial", smp_fetch_ssl_x_serial, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
3824 { "ssl_c_sha1", smp_fetch_ssl_x_sha1, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Willy Tarreau80aca902013-01-07 15:42:20 +01003825 { "ssl_c_used", smp_fetch_ssl_c_used, 0, NULL, SMP_T_BOOL, SMP_USE_L5CLI },
3826 { "ssl_c_verify", smp_fetch_ssl_c_verify, 0, NULL, SMP_T_UINT, SMP_USE_L5CLI },
Emeric Brunba841a12014-04-30 17:05:08 +02003827 { "ssl_c_version", smp_fetch_ssl_x_version, 0, NULL, SMP_T_UINT, SMP_USE_L5CLI },
3828 { "ssl_f_i_dn", smp_fetch_ssl_x_i_dn, ARG2(0,STR,SINT), NULL, SMP_T_STR, SMP_USE_L5CLI },
3829 { "ssl_f_key_alg", smp_fetch_ssl_x_key_alg, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
3830 { "ssl_f_notafter", smp_fetch_ssl_x_notafter, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
3831 { "ssl_f_notbefore", smp_fetch_ssl_x_notbefore, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
3832 { "ssl_f_sig_alg", smp_fetch_ssl_x_sig_alg, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
3833 { "ssl_f_s_dn", smp_fetch_ssl_x_s_dn, ARG2(0,STR,SINT), NULL, SMP_T_STR, SMP_USE_L5CLI },
3834 { "ssl_f_serial", smp_fetch_ssl_x_serial, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Emeric Brun55f4fa82014-04-30 17:11:25 +02003835 { "ssl_f_sha1", smp_fetch_ssl_x_sha1, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Emeric Brunba841a12014-04-30 17:05:08 +02003836 { "ssl_f_version", smp_fetch_ssl_x_version, 0, NULL, SMP_T_UINT, SMP_USE_L5CLI },
Willy Tarreau80aca902013-01-07 15:42:20 +01003837 { "ssl_fc", smp_fetch_ssl_fc, 0, NULL, SMP_T_BOOL, SMP_USE_L5CLI },
3838 { "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 +01003839 { "ssl_fc_cipher", smp_fetch_ssl_fc_cipher, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Willy Tarreau80aca902013-01-07 15:42:20 +01003840 { "ssl_fc_has_crt", smp_fetch_ssl_fc_has_crt, 0, NULL, SMP_T_BOOL, SMP_USE_L5CLI },
3841 { "ssl_fc_has_sni", smp_fetch_ssl_fc_has_sni, 0, NULL, SMP_T_BOOL, SMP_USE_L5CLI },
Willy Tarreaua33c6542012-10-15 13:19:06 +02003842#ifdef OPENSSL_NPN_NEGOTIATED
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01003843 { "ssl_fc_npn", smp_fetch_ssl_fc_npn, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Willy Tarreaua33c6542012-10-15 13:19:06 +02003844#endif
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01003845#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01003846 { "ssl_fc_alpn", smp_fetch_ssl_fc_alpn, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Willy Tarreauab861d32013-04-02 02:30:41 +02003847#endif
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01003848 { "ssl_fc_protocol", smp_fetch_ssl_fc_protocol, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Emeric Brunb73a9b02014-04-30 18:49:19 +02003849 { "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 +01003850 { "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 +01003851 { "ssl_fc_session_id", smp_fetch_ssl_fc_session_id, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
3852 { "ssl_fc_sni", smp_fetch_ssl_fc_sni, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Willy Tarreau7875d092012-09-10 08:20:03 +02003853 { NULL, NULL, 0, 0, 0 },
3854}};
3855
3856/* Note: must not be declared <const> as its list will be overwritten.
3857 * Please take care of keeping this list alphabetically sorted.
3858 */
Willy Tarreaudc13c112013-06-21 23:16:39 +02003859static struct acl_kw_list acl_kws = {ILH, {
Thierry FOURNIERc5a4e982014-03-05 16:07:08 +01003860 { "ssl_fc_sni_end", "ssl_fc_sni", PAT_MATCH_END },
3861 { "ssl_fc_sni_reg", "ssl_fc_sni", PAT_MATCH_REG },
Willy Tarreau8ed669b2013-01-11 15:49:37 +01003862 { /* END */ },
Willy Tarreau7875d092012-09-10 08:20:03 +02003863}};
3864
Willy Tarreau79eeafa2012-09-14 07:53:05 +02003865/* Note: must not be declared <const> as its list will be overwritten.
3866 * Please take care of keeping this list alphabetically sorted, doing so helps
3867 * all code contributors.
3868 * Optional keywords are also declared with a NULL ->parse() function so that
3869 * the config parser can report an appropriate error when a known keyword was
3870 * not enabled.
3871 */
Willy Tarreau51fb7652012-09-18 18:24:39 +02003872static struct bind_kw_list bind_kws = { "SSL", { }, {
Willy Tarreauab861d32013-04-02 02:30:41 +02003873 { "alpn", bind_parse_alpn, 1 }, /* set ALPN supported protocols */
Emeric Brunfb510ea2012-10-05 12:00:26 +02003874 { "ca-file", bind_parse_ca_file, 1 }, /* set CAfile to process verify on client cert */
Emeric Brun2d0c4822012-10-02 13:45:20 +02003875 { "ca-ignore-err", bind_parse_ignore_err, 1 }, /* set error IDs to ignore on verify depth > 0 */
3876 { "ciphers", bind_parse_ciphers, 1 }, /* set SSL cipher suite */
Emeric Brunfb510ea2012-10-05 12:00:26 +02003877 { "crl-file", bind_parse_crl_file, 1 }, /* set certificat revocation list file use on client cert verify */
Emeric Brun2d0c4822012-10-02 13:45:20 +02003878 { "crt", bind_parse_crt, 1 }, /* load SSL certificates from this location */
3879 { "crt-ignore-err", bind_parse_ignore_err, 1 }, /* set error IDs to ingore on verify depth == 0 */
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01003880 { "crt-list", bind_parse_crt_list, 1 }, /* load a list of crt from this location */
Emeric Brun2d0c4822012-10-02 13:45:20 +02003881 { "ecdhe", bind_parse_ecdhe, 1 }, /* defines named curve for elliptic curve Diffie-Hellman */
Emeric Brun2cb7ae52012-10-05 14:14:21 +02003882 { "force-sslv3", bind_parse_force_sslv3, 0 }, /* force SSLv3 */
3883 { "force-tlsv10", bind_parse_force_tlsv10, 0 }, /* force TLSv10 */
3884 { "force-tlsv11", bind_parse_force_tlsv11, 0 }, /* force TLSv11 */
3885 { "force-tlsv12", bind_parse_force_tlsv12, 0 }, /* force TLSv12 */
Emeric Brun9b3009b2012-10-05 11:55:06 +02003886 { "no-sslv3", bind_parse_no_sslv3, 0 }, /* disable SSLv3 */
3887 { "no-tlsv10", bind_parse_no_tlsv10, 0 }, /* disable TLSv10 */
3888 { "no-tlsv11", bind_parse_no_tlsv11, 0 }, /* disable TLSv11 */
3889 { "no-tlsv12", bind_parse_no_tlsv12, 0 }, /* disable TLSv12 */
Emeric Brun2d0c4822012-10-02 13:45:20 +02003890 { "no-tls-tickets", bind_parse_no_tls_tickets, 0 }, /* disable session resumption tickets */
Emeric Brun2d0c4822012-10-02 13:45:20 +02003891 { "ssl", bind_parse_ssl, 0 }, /* enable SSL processing */
Emmanuel Hocdet65623372013-01-24 17:17:15 +01003892 { "strict-sni", bind_parse_strict_sni, 0 }, /* refuse negotiation if sni doesn't match a certificate */
Emeric Brun2d0c4822012-10-02 13:45:20 +02003893 { "verify", bind_parse_verify, 1 }, /* set SSL verify method */
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02003894 { "npn", bind_parse_npn, 1 }, /* set NPN supported protocols */
Willy Tarreau79eeafa2012-09-14 07:53:05 +02003895 { NULL, NULL, 0 },
3896}};
Emeric Brun46591952012-05-18 15:47:34 +02003897
Willy Tarreau92faadf2012-10-10 23:04:25 +02003898/* Note: must not be declared <const> as its list will be overwritten.
3899 * Please take care of keeping this list alphabetically sorted, doing so helps
3900 * all code contributors.
3901 * Optional keywords are also declared with a NULL ->parse() function so that
3902 * the config parser can report an appropriate error when a known keyword was
3903 * not enabled.
3904 */
3905static struct srv_kw_list srv_kws = { "SSL", { }, {
Emeric Brunef42d922012-10-11 16:11:36 +02003906 { "ca-file", srv_parse_ca_file, 1, 0 }, /* set CAfile to process verify server cert */
Emeric Brunecc91fe2012-10-11 15:05:10 +02003907 { "check-ssl", srv_parse_check_ssl, 0, 0 }, /* enable SSL for health checks */
3908 { "ciphers", srv_parse_ciphers, 1, 0 }, /* select the cipher suite */
Emeric Brunef42d922012-10-11 16:11:36 +02003909 { "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 +02003910 { "crt", srv_parse_crt, 1, 0 }, /* set client certificate */
Emeric Brunecc91fe2012-10-11 15:05:10 +02003911 { "force-sslv3", srv_parse_force_sslv3, 0, 0 }, /* force SSLv3 */
3912 { "force-tlsv10", srv_parse_force_tlsv10, 0, 0 }, /* force TLSv10 */
3913 { "force-tlsv11", srv_parse_force_tlsv11, 0, 0 }, /* force TLSv11 */
3914 { "force-tlsv12", srv_parse_force_tlsv12, 0, 0 }, /* force TLSv12 */
3915 { "no-sslv3", srv_parse_no_sslv3, 0, 0 }, /* disable SSLv3 */
3916 { "no-tlsv10", srv_parse_no_tlsv10, 0, 0 }, /* disable TLSv10 */
3917 { "no-tlsv11", srv_parse_no_tlsv11, 0, 0 }, /* disable TLSv11 */
3918 { "no-tlsv12", srv_parse_no_tlsv12, 0, 0 }, /* disable TLSv12 */
Emeric Brunf9c5c472012-10-11 15:28:34 +02003919 { "no-tls-tickets", srv_parse_no_tls_tickets, 0, 0 }, /* disable session resumption tickets */
David Safb76832014-05-08 23:42:08 -04003920 { "send-proxy-v2-ssl", srv_parse_send_proxy_ssl, 0, 0 }, /* send PROXY protocol header v2 with SSL info */
3921 { "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 +02003922 { "ssl", srv_parse_ssl, 0, 0 }, /* enable SSL processing */
Emeric Brunef42d922012-10-11 16:11:36 +02003923 { "verify", srv_parse_verify, 1, 0 }, /* set SSL verify method */
Evan Broderbe554312013-06-27 00:05:25 -07003924 { "verifyhost", srv_parse_verifyhost, 1, 0 }, /* require that SSL cert verifies for hostname */
Willy Tarreau92faadf2012-10-10 23:04:25 +02003925 { NULL, NULL, 0, 0 },
3926}};
3927
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02003928/* transport-layer operations for SSL sockets */
3929struct xprt_ops ssl_sock = {
Emeric Brun46591952012-05-18 15:47:34 +02003930 .snd_buf = ssl_sock_from_buf,
3931 .rcv_buf = ssl_sock_to_buf,
3932 .rcv_pipe = NULL,
3933 .snd_pipe = NULL,
3934 .shutr = NULL,
3935 .shutw = ssl_sock_shutw,
3936 .close = ssl_sock_close,
3937 .init = ssl_sock_init,
3938};
3939
3940__attribute__((constructor))
Willy Tarreau92faadf2012-10-10 23:04:25 +02003941static void __ssl_sock_init(void)
3942{
Emeric Brun46591952012-05-18 15:47:34 +02003943 STACK_OF(SSL_COMP)* cm;
3944
Willy Tarreau610f04b2014-02-13 11:36:41 +01003945#ifdef LISTEN_DEFAULT_CIPHERS
3946 global.listen_default_ciphers = LISTEN_DEFAULT_CIPHERS;
3947#endif
3948#ifdef CONNECT_DEFAULT_CIPHERS
3949 global.connect_default_ciphers = CONNECT_DEFAULT_CIPHERS;
3950#endif
3951 if (global.listen_default_ciphers)
3952 global.listen_default_ciphers = strdup(global.listen_default_ciphers);
3953 if (global.connect_default_ciphers)
3954 global.connect_default_ciphers = strdup(global.connect_default_ciphers);
3955
Emeric Brun46591952012-05-18 15:47:34 +02003956 SSL_library_init();
3957 cm = SSL_COMP_get_compression_methods();
3958 sk_SSL_COMP_zero(cm);
Willy Tarreau7875d092012-09-10 08:20:03 +02003959 sample_register_fetches(&sample_fetch_keywords);
3960 acl_register_keywords(&acl_kws);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02003961 bind_register_keywords(&bind_kws);
Willy Tarreau92faadf2012-10-10 23:04:25 +02003962 srv_register_keywords(&srv_kws);
Emeric Brun46591952012-05-18 15:47:34 +02003963}
3964
3965/*
3966 * Local variables:
3967 * c-indent-level: 8
3968 * c-basic-offset: 8
3969 * End:
3970 */