blob: 9381f11d0fdce0b22dc94bafd6f848ebecd5207e [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
David Sc1ad52e2014-04-08 18:48:47 -040048#include <common/base64.h>
Emeric Brun46591952012-05-18 15:47:34 +020049#include <common/buffer.h>
50#include <common/compat.h>
51#include <common/config.h>
52#include <common/debug.h>
Willy Tarreau79eeafa2012-09-14 07:53:05 +020053#include <common/errors.h>
Emeric Brun46591952012-05-18 15:47:34 +020054#include <common/standard.h>
55#include <common/ticks.h>
56#include <common/time.h>
57
Emeric Brunfc0421f2012-09-07 17:30:07 +020058#include <ebsttree.h>
59
60#include <types/global.h>
61#include <types/ssl_sock.h>
62
Willy Tarreau7875d092012-09-10 08:20:03 +020063#include <proto/acl.h>
64#include <proto/arg.h>
Emeric Brun46591952012-05-18 15:47:34 +020065#include <proto/connection.h>
66#include <proto/fd.h>
67#include <proto/freq_ctr.h>
68#include <proto/frontend.h>
Willy Tarreau79eeafa2012-09-14 07:53:05 +020069#include <proto/listener.h>
Thierry FOURNIERed66c292013-11-28 11:05:19 +010070#include <proto/pattern.h>
Willy Tarreau92faadf2012-10-10 23:04:25 +020071#include <proto/server.h>
Emeric Brun46591952012-05-18 15:47:34 +020072#include <proto/log.h>
Emeric Brun94324a42012-10-11 14:00:19 +020073#include <proto/proxy.h>
Emeric Brunfc0421f2012-09-07 17:30:07 +020074#include <proto/shctx.h>
Emeric Brun46591952012-05-18 15:47:34 +020075#include <proto/ssl_sock.h>
76#include <proto/task.h>
77
Willy Tarreau518cedd2014-02-17 15:43:01 +010078/* Warning, these are bits, not integers! */
Emeric Brune64aef12012-09-21 13:15:06 +020079#define SSL_SOCK_ST_FL_VERIFY_DONE 0x00000001
Emeric Brund8b2bb52014-01-28 15:43:53 +010080#define SSL_SOCK_ST_FL_16K_WBFSIZE 0x00000002
Willy Tarreau518cedd2014-02-17 15:43:01 +010081#define SSL_SOCK_SEND_UNLIMITED 0x00000004
Emeric Brun29f037d2014-04-25 19:05:36 +020082#define SSL_SOCK_RECV_HEARTBEAT 0x00000008
83
Emeric Brunf282a812012-09-21 15:27:54 +020084/* bits 0xFFFF0000 are reserved to store verify errors */
85
86/* Verify errors macros */
87#define SSL_SOCK_CA_ERROR_TO_ST(e) (((e > 63) ? 63 : e) << (16))
88#define SSL_SOCK_CAEDEPTH_TO_ST(d) (((d > 15) ? 15 : d) << (6+16))
89#define SSL_SOCK_CRTERROR_TO_ST(e) (((e > 63) ? 63 : e) << (4+6+16))
90
91#define SSL_SOCK_ST_TO_CA_ERROR(s) ((s >> (16)) & 63)
92#define SSL_SOCK_ST_TO_CAEDEPTH(s) ((s >> (6+16)) & 15)
93#define SSL_SOCK_ST_TO_CRTERROR(s) ((s >> (4+6+16)) & 63)
Emeric Brune64aef12012-09-21 13:15:06 +020094
Emeric Brun850efd52014-01-29 12:24:34 +010095/* server and bind verify method, it uses a global value as default */
96enum {
97 SSL_SOCK_VERIFY_DEFAULT = 0,
98 SSL_SOCK_VERIFY_REQUIRED = 1,
99 SSL_SOCK_VERIFY_OPTIONAL = 2,
100 SSL_SOCK_VERIFY_NONE = 3,
101};
102
Willy Tarreau71b734c2014-01-28 15:19:44 +0100103int sslconns = 0;
104int totalsslconns = 0;
Emeric Brune1f38db2012-09-03 20:36:47 +0200105
106void ssl_sock_infocbk(const SSL *ssl, int where, int ret)
107{
108 struct connection *conn = (struct connection *)SSL_get_app_data(ssl);
109 (void)ret; /* shut gcc stupid warning */
Emeric Brund8b2bb52014-01-28 15:43:53 +0100110 BIO *write_bio;
Emeric Brune1f38db2012-09-03 20:36:47 +0200111
112 if (where & SSL_CB_HANDSHAKE_START) {
113 /* Disable renegotiation (CVE-2009-3555) */
Willy Tarreau20879a02012-12-03 16:32:10 +0100114 if (conn->flags & CO_FL_CONNECTED) {
Emeric Brune1f38db2012-09-03 20:36:47 +0200115 conn->flags |= CO_FL_ERROR;
Willy Tarreau20879a02012-12-03 16:32:10 +0100116 conn->err_code = CO_ER_SSL_RENEG;
117 }
Emeric Brune1f38db2012-09-03 20:36:47 +0200118 }
Emeric Brund8b2bb52014-01-28 15:43:53 +0100119
120 if ((where & SSL_CB_ACCEPT_LOOP) == SSL_CB_ACCEPT_LOOP) {
121 if (!(conn->xprt_st & SSL_SOCK_ST_FL_16K_WBFSIZE)) {
122 /* Long certificate chains optimz
123 If write and read bios are differents, we
124 consider that the buffering was activated,
125 so we rise the output buffer size from 4k
126 to 16k */
127 write_bio = SSL_get_wbio(ssl);
128 if (write_bio != SSL_get_rbio(ssl)) {
129 BIO_set_write_buffer_size(write_bio, 16384);
130 conn->xprt_st |= SSL_SOCK_ST_FL_16K_WBFSIZE;
131 }
132 }
133 }
Emeric Brunfc0421f2012-09-07 17:30:07 +0200134}
135
Emeric Brune64aef12012-09-21 13:15:06 +0200136/* Callback is called for each certificate of the chain during a verify
137 ok is set to 1 if preverify detect no error on current certificate.
138 Returns 0 to break the handshake, 1 otherwise. */
Evan Broderbe554312013-06-27 00:05:25 -0700139int ssl_sock_bind_verifycbk(int ok, X509_STORE_CTX *x_store)
Emeric Brune64aef12012-09-21 13:15:06 +0200140{
141 SSL *ssl;
142 struct connection *conn;
Emeric Brun81c00f02012-09-21 14:31:21 +0200143 int err, depth;
Emeric Brune64aef12012-09-21 13:15:06 +0200144
145 ssl = X509_STORE_CTX_get_ex_data(x_store, SSL_get_ex_data_X509_STORE_CTX_idx());
146 conn = (struct connection *)SSL_get_app_data(ssl);
147
Willy Tarreauf7bc57c2012-10-03 00:19:48 +0200148 conn->xprt_st |= SSL_SOCK_ST_FL_VERIFY_DONE;
Emeric Brune64aef12012-09-21 13:15:06 +0200149
Emeric Brun81c00f02012-09-21 14:31:21 +0200150 if (ok) /* no errors */
151 return ok;
152
153 depth = X509_STORE_CTX_get_error_depth(x_store);
154 err = X509_STORE_CTX_get_error(x_store);
155
156 /* check if CA error needs to be ignored */
157 if (depth > 0) {
Willy Tarreauf7bc57c2012-10-03 00:19:48 +0200158 if (!SSL_SOCK_ST_TO_CA_ERROR(conn->xprt_st)) {
159 conn->xprt_st |= SSL_SOCK_CA_ERROR_TO_ST(err);
160 conn->xprt_st |= SSL_SOCK_CAEDEPTH_TO_ST(depth);
Emeric Brunf282a812012-09-21 15:27:54 +0200161 }
162
Emeric Brun1eb20ef2012-12-03 13:24:29 +0100163 if (objt_listener(conn->target)->bind_conf->ca_ignerr & (1ULL << err)) {
164 ERR_clear_error();
Emeric Brun81c00f02012-09-21 14:31:21 +0200165 return 1;
Emeric Brun1eb20ef2012-12-03 13:24:29 +0100166 }
Emeric Brun81c00f02012-09-21 14:31:21 +0200167
Willy Tarreau20879a02012-12-03 16:32:10 +0100168 conn->err_code = CO_ER_SSL_CA_FAIL;
Emeric Brun81c00f02012-09-21 14:31:21 +0200169 return 0;
170 }
171
Willy Tarreauf7bc57c2012-10-03 00:19:48 +0200172 if (!SSL_SOCK_ST_TO_CRTERROR(conn->xprt_st))
173 conn->xprt_st |= SSL_SOCK_CRTERROR_TO_ST(err);
Emeric Brunf282a812012-09-21 15:27:54 +0200174
Emeric Brun81c00f02012-09-21 14:31:21 +0200175 /* check if certificate error needs to be ignored */
Emeric Brun1eb20ef2012-12-03 13:24:29 +0100176 if (objt_listener(conn->target)->bind_conf->crt_ignerr & (1ULL << err)) {
177 ERR_clear_error();
Emeric Brun81c00f02012-09-21 14:31:21 +0200178 return 1;
Emeric Brun1eb20ef2012-12-03 13:24:29 +0100179 }
Emeric Brun81c00f02012-09-21 14:31:21 +0200180
Willy Tarreau20879a02012-12-03 16:32:10 +0100181 conn->err_code = CO_ER_SSL_CRT_FAIL;
Emeric Brun81c00f02012-09-21 14:31:21 +0200182 return 0;
Emeric Brune64aef12012-09-21 13:15:06 +0200183}
184
Emeric Brun29f037d2014-04-25 19:05:36 +0200185/* Callback is called for ssl protocol analyse */
186void ssl_sock_msgcbk(int write_p, int version, int content_type, const void *buf, size_t len, SSL *ssl, void *arg)
187{
188 struct connection *conn = (struct connection *)SSL_get_app_data(ssl);
189
190#ifdef TLS1_RT_HEARTBEAT
191 /* test heartbeat received (write_p is set to 0
192 for a received record) */
Willy Tarreauf51c6982014-04-25 20:02:39 +0200193 if ((content_type == TLS1_RT_HEARTBEAT) && (write_p == 0)) {
194 const unsigned char *p = buf;
195 unsigned int payload;
196
Emeric Brun29f037d2014-04-25 19:05:36 +0200197 conn->xprt_st |= SSL_SOCK_RECV_HEARTBEAT;
Willy Tarreauf51c6982014-04-25 20:02:39 +0200198
199 /* Check if this is a CVE-2014-0160 exploitation attempt. */
200 if (*p != TLS1_HB_REQUEST)
201 return;
202
203 if (len < 1 + 2 + 16)
204 goto kill_it;
205
206 payload = (p[1] * 256) + p[2];
207 if (1 + 2 + payload + 16 <= len)
208 return; /* OK no problem */
209 kill_it:
210 /* we have a clear heartbleed attack (CVE-2014-0160),
211 * we can't know if the SSL stack is patched, so better
212 * kill the connection before OpenSSL tries to send the
213 * bytes back to the attacker. It will be reported above
214 * as SSL_ERROR_SSL while an other handshake failure with
215 * a heartbeat message will be reported as SSL_ERROR_SYSCALL.
216 */
217 SSLerr(SSL_F_TLS1_HEARTBEAT, SSL_R_SSL_HANDSHAKE_FAILURE);
218 return;
219 }
Emeric Brun29f037d2014-04-25 19:05:36 +0200220#endif
221}
222
Willy Tarreau6c9a3d52012-10-18 18:57:14 +0200223#ifdef OPENSSL_NPN_NEGOTIATED
224/* This callback is used so that the server advertises the list of
225 * negociable protocols for NPN.
226 */
227static int ssl_sock_advertise_npn_protos(SSL *s, const unsigned char **data,
228 unsigned int *len, void *arg)
229{
230 struct bind_conf *conf = arg;
231
232 *data = (const unsigned char *)conf->npn_str;
233 *len = conf->npn_len;
234 return SSL_TLSEXT_ERR_OK;
235}
236#endif
237
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +0100238#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Willy Tarreauab861d32013-04-02 02:30:41 +0200239/* This callback is used so that the server advertises the list of
240 * negociable protocols for ALPN.
241 */
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +0100242static int ssl_sock_advertise_alpn_protos(SSL *s, const unsigned char **out,
243 unsigned char *outlen,
244 const unsigned char *server,
245 unsigned int server_len, void *arg)
Willy Tarreauab861d32013-04-02 02:30:41 +0200246{
247 struct bind_conf *conf = arg;
248
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +0100249 if (SSL_select_next_proto((unsigned char**) out, outlen, (const unsigned char *)conf->alpn_str,
250 conf->alpn_len, server, server_len) != OPENSSL_NPN_NEGOTIATED) {
251 return SSL_TLSEXT_ERR_NOACK;
252 }
Willy Tarreauab861d32013-04-02 02:30:41 +0200253 return SSL_TLSEXT_ERR_OK;
254}
255#endif
256
Emeric Brunfc0421f2012-09-07 17:30:07 +0200257#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
258/* Sets the SSL ctx of <ssl> to match the advertised server name. Returns a
259 * warning when no match is found, which implies the default (first) cert
260 * will keep being used.
261 */
Willy Tarreau2a65ff02012-09-13 17:54:29 +0200262static int ssl_sock_switchctx_cbk(SSL *ssl, int *al, struct bind_conf *s)
Emeric Brunfc0421f2012-09-07 17:30:07 +0200263{
264 const char *servername;
265 const char *wildp = NULL;
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +0200266 struct ebmb_node *node, *n;
Emeric Brunfc0421f2012-09-07 17:30:07 +0200267 int i;
268 (void)al; /* shut gcc stupid warning */
269
270 servername = SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name);
Emmanuel Hocdet65623372013-01-24 17:17:15 +0100271 if (!servername) {
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +0200272 return (s->strict_sni ?
273 SSL_TLSEXT_ERR_ALERT_FATAL :
Emmanuel Hocdet79274e22013-05-31 12:47:44 +0200274 SSL_TLSEXT_ERR_NOACK);
Emmanuel Hocdet65623372013-01-24 17:17:15 +0100275 }
Emeric Brunfc0421f2012-09-07 17:30:07 +0200276
Willy Tarreau19d14ef2012-10-29 16:51:55 +0100277 for (i = 0; i < trash.size; i++) {
Emeric Brunfc0421f2012-09-07 17:30:07 +0200278 if (!servername[i])
279 break;
Willy Tarreau19d14ef2012-10-29 16:51:55 +0100280 trash.str[i] = tolower(servername[i]);
281 if (!wildp && (trash.str[i] == '.'))
282 wildp = &trash.str[i];
Emeric Brunfc0421f2012-09-07 17:30:07 +0200283 }
Willy Tarreau19d14ef2012-10-29 16:51:55 +0100284 trash.str[i] = 0;
Emeric Brunfc0421f2012-09-07 17:30:07 +0200285
286 /* lookup in full qualified names */
Willy Tarreau19d14ef2012-10-29 16:51:55 +0100287 node = ebst_lookup(&s->sni_ctx, trash.str);
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +0200288
289 /* lookup a not neg filter */
290 for (n = node; n; n = ebmb_next_dup(n)) {
291 if (!container_of(n, struct sni_ctx, name)->neg) {
292 node = n;
293 break;
Emmanuel Hocdet65623372013-01-24 17:17:15 +0100294 }
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +0200295 }
296 if (!node && wildp) {
297 /* lookup in wildcards names */
Emeric Brunfc0421f2012-09-07 17:30:07 +0200298 node = ebst_lookup(&s->sni_w_ctx, wildp);
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +0200299 }
300 if (!node || container_of(node, struct sni_ctx, name)->neg) {
301 return (s->strict_sni ?
302 SSL_TLSEXT_ERR_ALERT_FATAL :
303 SSL_TLSEXT_ERR_ALERT_WARNING);
Emeric Brunfc0421f2012-09-07 17:30:07 +0200304 }
305
306 /* switch ctx */
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +0200307 SSL_set_SSL_CTX(ssl, container_of(node, struct sni_ctx, name)->ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +0200308 return SSL_TLSEXT_ERR_OK;
309}
310#endif /* SSL_CTRL_SET_TLSEXT_HOSTNAME */
311
Emeric Bruna4bcd9a2012-09-20 16:19:02 +0200312#ifndef OPENSSL_NO_DH
313/* Loads Diffie-Hellman parameter from a file. Returns 1 if loaded, else -1
314 if an error occured, and 0 if parameter not found. */
Willy Tarreau6e774b42014-04-25 21:35:23 +0200315int ssl_sock_load_dh_params(SSL_CTX *ctx, const char *file)
Emeric Bruna4bcd9a2012-09-20 16:19:02 +0200316{
317 int ret = -1;
318 BIO *in;
319 DH *dh = NULL;
Willy Tarreau6e774b42014-04-25 21:35:23 +0200320 /* If not present, use parameters generated using 'openssl dhparam 1024 -C':
321 * -----BEGIN DH PARAMETERS-----
322 * MIGHAoGBAJJAJDXDoS5E03MNjnjK36eOL1tRqVa/9NuOVlI+lpXmPjJQbP65EvKn
323 * fSLnG7VMhoCJO4KtG88zf393ltP7loGB2bofcDSr+x+XsxBM8yA/Zj6BmQt+CQ9s
324 * TF7hoOV+wXTT6ErZ5y5qx9pq6hLfKXwTGFT78hrE6HnCO7xgtPdTAgEC
325 * -----END DH PARAMETERS-----
326 */
327 static const unsigned char dh1024_p[] = {
328 0x92, 0x40, 0x24, 0x35, 0xC3, 0xA1, 0x2E, 0x44, 0xD3, 0x73, 0x0D, 0x8E,
329 0x78, 0xCA, 0xDF, 0xA7, 0x8E, 0x2F, 0x5B, 0x51, 0xA9, 0x56, 0xBF, 0xF4,
330 0xDB, 0x8E, 0x56, 0x52, 0x3E, 0x96, 0x95, 0xE6, 0x3E, 0x32, 0x50, 0x6C,
331 0xFE, 0xB9, 0x12, 0xF2, 0xA7, 0x7D, 0x22, 0xE7, 0x1B, 0xB5, 0x4C, 0x86,
332 0x80, 0x89, 0x3B, 0x82, 0xAD, 0x1B, 0xCF, 0x33, 0x7F, 0x7F, 0x77, 0x96,
333 0xD3, 0xFB, 0x96, 0x81, 0x81, 0xD9, 0xBA, 0x1F, 0x70, 0x34, 0xAB, 0xFB,
334 0x1F, 0x97, 0xB3, 0x10, 0x4C, 0xF3, 0x20, 0x3F, 0x66, 0x3E, 0x81, 0x99,
335 0x0B, 0x7E, 0x09, 0x0F, 0x6C, 0x4C, 0x5E, 0xE1, 0xA0, 0xE5, 0x7E, 0xC1,
336 0x74, 0xD3, 0xE8, 0x4A, 0xD9, 0xE7, 0x2E, 0x6A, 0xC7, 0xDA, 0x6A, 0xEA,
337 0x12, 0xDF, 0x29, 0x7C, 0x13, 0x18, 0x54, 0xFB, 0xF2, 0x1A, 0xC4, 0xE8,
338 0x79, 0xC2, 0x3B, 0xBC, 0x60, 0xB4, 0xF7, 0x53,
339 };
340 static const unsigned char dh1024_g[] = {
341 0x02,
342 };
Emeric Bruna4bcd9a2012-09-20 16:19:02 +0200343
344 in = BIO_new(BIO_s_file());
345 if (in == NULL)
346 goto end;
347
348 if (BIO_read_filename(in, file) <= 0)
349 goto end;
350
351 dh = PEM_read_bio_DHparams(in, NULL, ctx->default_passwd_callback, ctx->default_passwd_callback_userdata);
Willy Tarreau6e774b42014-04-25 21:35:23 +0200352 if (!dh) {
Emeric Brun41fdb3c2013-04-26 11:05:44 +0200353 /* Clear openssl global errors stack */
354 ERR_clear_error();
355
Willy Tarreau6e774b42014-04-25 21:35:23 +0200356 dh = DH_new();
357 if (dh == NULL)
358 goto end;
359
360 dh->p = BN_bin2bn(dh1024_p, sizeof(dh1024_p), NULL);
361 if (dh->p == NULL)
362 goto end;
363
364 dh->g = BN_bin2bn(dh1024_g, sizeof(dh1024_g), NULL);
365 if (dh->g == NULL)
366 goto end;
367
Emeric Brun41fdb3c2013-04-26 11:05:44 +0200368 ret = 0; /* DH params not found */
Emeric Bruna4bcd9a2012-09-20 16:19:02 +0200369 }
Willy Tarreau6e774b42014-04-25 21:35:23 +0200370 else
371 ret = 1;
372
373 SSL_CTX_set_tmp_dh(ctx, dh);
Emeric Brun644cde02012-12-14 11:21:13 +0100374
Emeric Bruna4bcd9a2012-09-20 16:19:02 +0200375end:
376 if (dh)
377 DH_free(dh);
378
379 if (in)
Emeric Brun41fdb3c2013-04-26 11:05:44 +0200380 BIO_free(in);
Emeric Bruna4bcd9a2012-09-20 16:19:02 +0200381
382 return ret;
383}
384#endif
385
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +0200386static int ssl_sock_add_cert_sni(SSL_CTX *ctx, struct bind_conf *s, char *name, int order)
Emmanuel Hocdetfe616562013-01-22 15:31:15 +0100387{
388 struct sni_ctx *sc;
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +0200389 int wild = 0, neg = 0;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +0100390
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +0200391 if (*name == '!') {
392 neg = 1;
393 name++;
394 }
395 if (*name == '*') {
396 wild = 1;
397 name++;
398 }
399 /* !* filter is a nop */
400 if (neg && wild)
401 return order;
402 if (*name) {
403 int j, len;
404 len = strlen(name);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +0100405 sc = malloc(sizeof(struct sni_ctx) + len + 1);
406 for (j = 0; j < len; j++)
407 sc->name.key[j] = tolower(name[j]);
408 sc->name.key[len] = 0;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +0100409 sc->ctx = ctx;
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +0200410 sc->order = order++;
411 sc->neg = neg;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +0100412 if (wild)
413 ebst_insert(&s->sni_w_ctx, &sc->name);
414 else
415 ebst_insert(&s->sni_ctx, &sc->name);
416 }
417 return order;
418}
419
Emeric Brunfc0421f2012-09-07 17:30:07 +0200420/* Loads a certificate key and CA chain from a file. Returns 0 on error, -1 if
421 * an early error happens and the caller must call SSL_CTX_free() by itelf.
422 */
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +0200423static 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 +0200424{
425 BIO *in;
426 X509 *x = NULL, *ca;
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +0200427 int i, err;
Emeric Brunfc0421f2012-09-07 17:30:07 +0200428 int ret = -1;
429 int order = 0;
430 X509_NAME *xname;
431 char *str;
Emeric Brunfc0421f2012-09-07 17:30:07 +0200432#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
433 STACK_OF(GENERAL_NAME) *names;
434#endif
435
436 in = BIO_new(BIO_s_file());
437 if (in == NULL)
438 goto end;
439
440 if (BIO_read_filename(in, file) <= 0)
441 goto end;
442
443 x = PEM_read_bio_X509_AUX(in, NULL, ctx->default_passwd_callback, ctx->default_passwd_callback_userdata);
444 if (x == NULL)
445 goto end;
446
Emeric Brun50bcecc2013-04-22 13:05:23 +0200447 if (fcount) {
448 while (fcount--)
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +0200449 order = ssl_sock_add_cert_sni(ctx, s, sni_filter[fcount], order);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +0100450 }
451 else {
Emeric Brunfc0421f2012-09-07 17:30:07 +0200452#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Emmanuel Hocdetfe616562013-01-22 15:31:15 +0100453 names = X509_get_ext_d2i(x, NID_subject_alt_name, NULL, NULL);
454 if (names) {
455 for (i = 0; i < sk_GENERAL_NAME_num(names); i++) {
456 GENERAL_NAME *name = sk_GENERAL_NAME_value(names, i);
457 if (name->type == GEN_DNS) {
458 if (ASN1_STRING_to_UTF8((unsigned char **)&str, name->d.dNSName) >= 0) {
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +0200459 order = ssl_sock_add_cert_sni(ctx, s, str, order);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +0100460 OPENSSL_free(str);
Emeric Brunfc0421f2012-09-07 17:30:07 +0200461 }
Emeric Brunfc0421f2012-09-07 17:30:07 +0200462 }
463 }
Emmanuel Hocdetfe616562013-01-22 15:31:15 +0100464 sk_GENERAL_NAME_pop_free(names, GENERAL_NAME_free);
Emeric Brunfc0421f2012-09-07 17:30:07 +0200465 }
Emeric Brunfc0421f2012-09-07 17:30:07 +0200466#endif /* SSL_CTRL_SET_TLSEXT_HOSTNAME */
Emmanuel Hocdetfe616562013-01-22 15:31:15 +0100467 xname = X509_get_subject_name(x);
468 i = -1;
469 while ((i = X509_NAME_get_index_by_NID(xname, NID_commonName, i)) != -1) {
470 X509_NAME_ENTRY *entry = X509_NAME_get_entry(xname, i);
471 if (ASN1_STRING_to_UTF8((unsigned char **)&str, entry->value) >= 0) {
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +0200472 order = ssl_sock_add_cert_sni(ctx, s, str, order);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +0100473 OPENSSL_free(str);
Emeric Brunfc0421f2012-09-07 17:30:07 +0200474 }
Emeric Brunfc0421f2012-09-07 17:30:07 +0200475 }
476 }
477
478 ret = 0; /* the caller must not free the SSL_CTX argument anymore */
479 if (!SSL_CTX_use_certificate(ctx, x))
480 goto end;
481
482 if (ctx->extra_certs != NULL) {
483 sk_X509_pop_free(ctx->extra_certs, X509_free);
484 ctx->extra_certs = NULL;
485 }
486
487 while ((ca = PEM_read_bio_X509(in, NULL, ctx->default_passwd_callback, ctx->default_passwd_callback_userdata))) {
488 if (!SSL_CTX_add_extra_chain_cert(ctx, ca)) {
489 X509_free(ca);
490 goto end;
491 }
492 }
493
494 err = ERR_get_error();
495 if (!err || (ERR_GET_LIB(err) == ERR_LIB_PEM && ERR_GET_REASON(err) == PEM_R_NO_START_LINE)) {
496 /* we successfully reached the last cert in the file */
497 ret = 1;
498 }
499 ERR_clear_error();
500
501end:
502 if (x)
503 X509_free(x);
504
505 if (in)
506 BIO_free(in);
507
508 return ret;
509}
510
Emeric Brun50bcecc2013-04-22 13:05:23 +0200511static 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 +0200512{
513 int ret;
514 SSL_CTX *ctx;
515
516 ctx = SSL_CTX_new(SSLv23_server_method());
517 if (!ctx) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +0200518 memprintf(err, "%sunable to allocate SSL context for cert '%s'.\n",
519 err && *err ? *err : "", path);
Emeric Brunfc0421f2012-09-07 17:30:07 +0200520 return 1;
521 }
522
523 if (SSL_CTX_use_PrivateKey_file(ctx, path, SSL_FILETYPE_PEM) <= 0) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +0200524 memprintf(err, "%sunable to load SSL private key from PEM file '%s'.\n",
525 err && *err ? *err : "", path);
Emeric Brunfc0421f2012-09-07 17:30:07 +0200526 SSL_CTX_free(ctx);
527 return 1;
528 }
529
Emeric Brun50bcecc2013-04-22 13:05:23 +0200530 ret = ssl_sock_load_cert_chain_file(ctx, path, bind_conf, sni_filter, fcount);
Emeric Brunfc0421f2012-09-07 17:30:07 +0200531 if (ret <= 0) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +0200532 memprintf(err, "%sunable to load SSL certificate from PEM file '%s'.\n",
533 err && *err ? *err : "", path);
Emeric Brunfc0421f2012-09-07 17:30:07 +0200534 if (ret < 0) /* serious error, must do that ourselves */
535 SSL_CTX_free(ctx);
536 return 1;
537 }
Emeric Brun61694ab2012-10-26 13:35:33 +0200538
539 if (SSL_CTX_check_private_key(ctx) <= 0) {
540 memprintf(err, "%sinconsistencies between private key and certificate loaded from PEM file '%s'.\n",
541 err && *err ? *err : "", path);
542 return 1;
543 }
544
Emeric Brunfc0421f2012-09-07 17:30:07 +0200545 /* we must not free the SSL_CTX anymore below, since it's already in
546 * the tree, so it will be discovered and cleaned in time.
547 */
Emeric Bruna4bcd9a2012-09-20 16:19:02 +0200548#ifndef OPENSSL_NO_DH
549 ret = ssl_sock_load_dh_params(ctx, path);
550 if (ret < 0) {
551 if (err)
552 memprintf(err, "%sunable to load DH parameters from file '%s'.\n",
553 *err ? *err : "", path);
554 return 1;
555 }
556#endif
557
Emeric Brunfc0421f2012-09-07 17:30:07 +0200558#ifndef SSL_CTRL_SET_TLSEXT_HOSTNAME
Willy Tarreau2a65ff02012-09-13 17:54:29 +0200559 if (bind_conf->default_ctx) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +0200560 memprintf(err, "%sthis version of openssl cannot load multiple SSL certificates.\n",
561 err && *err ? *err : "");
Emeric Brunfc0421f2012-09-07 17:30:07 +0200562 return 1;
563 }
564#endif
Willy Tarreau2a65ff02012-09-13 17:54:29 +0200565 if (!bind_conf->default_ctx)
566 bind_conf->default_ctx = ctx;
Emeric Brunfc0421f2012-09-07 17:30:07 +0200567
568 return 0;
569}
570
Willy Tarreau79eeafa2012-09-14 07:53:05 +0200571int ssl_sock_load_cert(char *path, struct bind_conf *bind_conf, struct proxy *curproxy, char **err)
Emeric Brunfc0421f2012-09-07 17:30:07 +0200572{
573 struct dirent *de;
574 DIR *dir;
575 struct stat buf;
Willy Tarreauee2663b2012-12-06 11:36:59 +0100576 char *end;
577 char fp[MAXPATHLEN+1];
Emeric Brunfc0421f2012-09-07 17:30:07 +0200578 int cfgerr = 0;
579
580 if (!(dir = opendir(path)))
Emeric Brun50bcecc2013-04-22 13:05:23 +0200581 return ssl_sock_load_cert_file(path, bind_conf, curproxy, NULL, 0, err);
Emeric Brunfc0421f2012-09-07 17:30:07 +0200582
583 /* strip trailing slashes, including first one */
584 for (end = path + strlen(path) - 1; end >= path && *end == '/'; end--)
585 *end = 0;
586
Emeric Brunfc0421f2012-09-07 17:30:07 +0200587 while ((de = readdir(dir))) {
Willy Tarreauee2663b2012-12-06 11:36:59 +0100588 snprintf(fp, sizeof(fp), "%s/%s", path, de->d_name);
Emeric Brunfc0421f2012-09-07 17:30:07 +0200589 if (stat(fp, &buf) != 0) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +0200590 memprintf(err, "%sunable to stat SSL certificate from file '%s' : %s.\n",
591 err && *err ? *err : "", fp, strerror(errno));
Emeric Brunfc0421f2012-09-07 17:30:07 +0200592 cfgerr++;
593 continue;
594 }
595 if (!S_ISREG(buf.st_mode))
596 continue;
Emeric Brun50bcecc2013-04-22 13:05:23 +0200597 cfgerr += ssl_sock_load_cert_file(fp, bind_conf, curproxy, NULL, 0, err);
Emeric Brunfc0421f2012-09-07 17:30:07 +0200598 }
Emeric Brunfc0421f2012-09-07 17:30:07 +0200599 closedir(dir);
600 return cfgerr;
601}
602
Thierry Fournier383085f2013-01-24 14:15:43 +0100603/* Make sure openssl opens /dev/urandom before the chroot. The work is only
604 * done once. Zero is returned if the operation fails. No error is returned
605 * if the random is said as not implemented, because we expect that openssl
606 * will use another method once needed.
607 */
608static int ssl_initialize_random()
609{
610 unsigned char random;
611 static int random_initialized = 0;
612
613 if (!random_initialized && RAND_bytes(&random, 1) != 0)
614 random_initialized = 1;
615
616 return random_initialized;
617}
618
Emmanuel Hocdetfe616562013-01-22 15:31:15 +0100619int ssl_sock_load_cert_list_file(char *file, struct bind_conf *bind_conf, struct proxy *curproxy, char **err)
620{
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +0200621 char thisline[LINESIZE];
Emmanuel Hocdetfe616562013-01-22 15:31:15 +0100622 FILE *f;
623 int linenum = 0;
624 int cfgerr = 0;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +0100625
Willy Tarreauad1731d2013-04-02 17:35:58 +0200626 if ((f = fopen(file, "r")) == NULL) {
627 memprintf(err, "cannot open file '%s' : %s", file, strerror(errno));
Emmanuel Hocdetfe616562013-01-22 15:31:15 +0100628 return 1;
Willy Tarreauad1731d2013-04-02 17:35:58 +0200629 }
Emmanuel Hocdetfe616562013-01-22 15:31:15 +0100630
631 while (fgets(thisline, sizeof(thisline), f) != NULL) {
632 int arg;
Emeric Brun50bcecc2013-04-22 13:05:23 +0200633 int newarg;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +0100634 char *end;
635 char *args[MAX_LINE_ARGS + 1];
636 char *line = thisline;
637
638 linenum++;
639 end = line + strlen(line);
640 if (end-line == sizeof(thisline)-1 && *(end-1) != '\n') {
641 /* Check if we reached the limit and the last char is not \n.
642 * Watch out for the last line without the terminating '\n'!
643 */
Willy Tarreauad1731d2013-04-02 17:35:58 +0200644 memprintf(err, "line %d too long in file '%s', limit is %d characters",
645 linenum, file, (int)sizeof(thisline)-1);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +0100646 cfgerr = 1;
Willy Tarreauad1731d2013-04-02 17:35:58 +0200647 break;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +0100648 }
649
Emmanuel Hocdetfe616562013-01-22 15:31:15 +0100650 arg = 0;
Emeric Brun50bcecc2013-04-22 13:05:23 +0200651 newarg = 1;
652 while (*line) {
Emmanuel Hocdetfe616562013-01-22 15:31:15 +0100653 if (*line == '#' || *line == '\n' || *line == '\r') {
654 /* end of string, end of loop */
655 *line = 0;
656 break;
657 }
658 else if (isspace(*line)) {
Emeric Brun50bcecc2013-04-22 13:05:23 +0200659 newarg = 1;
660 *line = 0;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +0100661 }
Emeric Brun50bcecc2013-04-22 13:05:23 +0200662 else if (newarg) {
663 if (arg == MAX_LINE_ARGS) {
664 memprintf(err, "too many args on line %d in file '%s'.",
665 linenum, file);
666 cfgerr = 1;
667 break;
668 }
669 newarg = 0;
670 args[arg++] = line;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +0100671 }
Emeric Brun50bcecc2013-04-22 13:05:23 +0200672 line++;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +0100673 }
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +0200674 if (cfgerr)
675 break;
Willy Tarreauad1731d2013-04-02 17:35:58 +0200676
Emmanuel Hocdetfe616562013-01-22 15:31:15 +0100677 /* empty line */
Emeric Brun50bcecc2013-04-22 13:05:23 +0200678 if (!arg)
Emmanuel Hocdetfe616562013-01-22 15:31:15 +0100679 continue;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +0100680
Emeric Brun50bcecc2013-04-22 13:05:23 +0200681 cfgerr = ssl_sock_load_cert_file(args[0], bind_conf, curproxy, &args[1], arg-1, err);
Willy Tarreauad1731d2013-04-02 17:35:58 +0200682 if (cfgerr) {
683 memprintf(err, "error processing line %d in file '%s' : %s", linenum, file, *err);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +0100684 break;
Willy Tarreauad1731d2013-04-02 17:35:58 +0200685 }
Emmanuel Hocdetfe616562013-01-22 15:31:15 +0100686 }
Emmanuel Hocdetfe616562013-01-22 15:31:15 +0100687 fclose(f);
688 return cfgerr;
689}
690
Emeric Brunfc0421f2012-09-07 17:30:07 +0200691#ifndef SSL_OP_CIPHER_SERVER_PREFERENCE /* needs OpenSSL >= 0.9.7 */
692#define SSL_OP_CIPHER_SERVER_PREFERENCE 0
693#endif
694
695#ifndef SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION /* needs OpenSSL >= 0.9.7 */
696#define SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION 0
Willy Tarreau7d588ee2012-11-26 18:47:31 +0100697#define SSL_renegotiate_pending(arg) 0
Emeric Brunfc0421f2012-09-07 17:30:07 +0200698#endif
Emeric Brun2b58d042012-09-20 17:10:03 +0200699#ifndef SSL_OP_SINGLE_ECDH_USE /* needs OpenSSL >= 0.9.8 */
700#define SSL_OP_SINGLE_ECDH_USE 0
701#endif
Emeric Brun2d0c4822012-10-02 13:45:20 +0200702#ifndef SSL_OP_NO_TICKET /* needs OpenSSL >= 0.9.8 */
703#define SSL_OP_NO_TICKET 0
704#endif
Emeric Brunfc0421f2012-09-07 17:30:07 +0200705#ifndef SSL_OP_NO_COMPRESSION /* needs OpenSSL >= 0.9.9 */
706#define SSL_OP_NO_COMPRESSION 0
707#endif
Emeric Brunc0ff4922012-09-28 19:37:02 +0200708#ifndef SSL_OP_NO_TLSv1_1 /* needs OpenSSL >= 1.0.1 */
709#define SSL_OP_NO_TLSv1_1 0
710#endif
711#ifndef SSL_OP_NO_TLSv1_2 /* needs OpenSSL >= 1.0.1 */
712#define SSL_OP_NO_TLSv1_2 0
713#endif
Emeric Bruna4bcd9a2012-09-20 16:19:02 +0200714#ifndef SSL_OP_SINGLE_DH_USE /* needs OpenSSL >= 0.9.6 */
715#define SSL_OP_SINGLE_DH_USE 0
716#endif
Emeric Brun2b58d042012-09-20 17:10:03 +0200717#ifndef SSL_OP_SINGLE_ECDH_USE /* needs OpenSSL >= 1.0.0 */
718#define SSL_OP_SINGLE_ECDH_USE 0
719#endif
Emeric Brunfc0421f2012-09-07 17:30:07 +0200720#ifndef SSL_MODE_RELEASE_BUFFERS /* needs OpenSSL >= 1.0.0 */
721#define SSL_MODE_RELEASE_BUFFERS 0
722#endif
Willy Tarreau2a65ff02012-09-13 17:54:29 +0200723int ssl_sock_prepare_ctx(struct bind_conf *bind_conf, SSL_CTX *ctx, struct proxy *curproxy)
Emeric Brunfc0421f2012-09-07 17:30:07 +0200724{
725 int cfgerr = 0;
Emeric Brun850efd52014-01-29 12:24:34 +0100726 int verify = SSL_VERIFY_NONE;
Emeric Brunfc0421f2012-09-07 17:30:07 +0200727 int ssloptions =
728 SSL_OP_ALL | /* all known workarounds for bugs */
729 SSL_OP_NO_SSLv2 |
730 SSL_OP_NO_COMPRESSION |
Emeric Bruna4bcd9a2012-09-20 16:19:02 +0200731 SSL_OP_SINGLE_DH_USE |
Emeric Brun2b58d042012-09-20 17:10:03 +0200732 SSL_OP_SINGLE_ECDH_USE |
Emeric Brun3c4bc6e2012-10-04 18:44:19 +0200733 SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION |
734 SSL_OP_CIPHER_SERVER_PREFERENCE;
Emeric Brunfc0421f2012-09-07 17:30:07 +0200735 int sslmode =
736 SSL_MODE_ENABLE_PARTIAL_WRITE |
737 SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER |
738 SSL_MODE_RELEASE_BUFFERS;
739
Thierry Fournier383085f2013-01-24 14:15:43 +0100740 /* Make sure openssl opens /dev/urandom before the chroot */
741 if (!ssl_initialize_random()) {
742 Alert("OpenSSL random data generator initialization failed.\n");
743 cfgerr++;
744 }
745
Emeric Brun89675492012-10-05 13:48:26 +0200746 if (bind_conf->ssl_options & BC_SSL_O_NO_SSLV3)
Emeric Brunfc0421f2012-09-07 17:30:07 +0200747 ssloptions |= SSL_OP_NO_SSLv3;
Emeric Brun89675492012-10-05 13:48:26 +0200748 if (bind_conf->ssl_options & BC_SSL_O_NO_TLSV10)
Emeric Brunfc0421f2012-09-07 17:30:07 +0200749 ssloptions |= SSL_OP_NO_TLSv1;
Emeric Brun89675492012-10-05 13:48:26 +0200750 if (bind_conf->ssl_options & BC_SSL_O_NO_TLSV11)
Emeric Brunc0ff4922012-09-28 19:37:02 +0200751 ssloptions |= SSL_OP_NO_TLSv1_1;
Emeric Brun89675492012-10-05 13:48:26 +0200752 if (bind_conf->ssl_options & BC_SSL_O_NO_TLSV12)
Emeric Brunc0ff4922012-09-28 19:37:02 +0200753 ssloptions |= SSL_OP_NO_TLSv1_2;
Emeric Brun89675492012-10-05 13:48:26 +0200754 if (bind_conf->ssl_options & BC_SSL_O_NO_TLS_TICKETS)
Emeric Brun2d0c4822012-10-02 13:45:20 +0200755 ssloptions |= SSL_OP_NO_TICKET;
Emeric Brun2cb7ae52012-10-05 14:14:21 +0200756 if (bind_conf->ssl_options & BC_SSL_O_USE_SSLV3)
757 SSL_CTX_set_ssl_version(ctx, SSLv3_server_method());
758 if (bind_conf->ssl_options & BC_SSL_O_USE_TLSV10)
759 SSL_CTX_set_ssl_version(ctx, TLSv1_server_method());
760#if SSL_OP_NO_TLSv1_1
761 if (bind_conf->ssl_options & BC_SSL_O_USE_TLSV11)
762 SSL_CTX_set_ssl_version(ctx, TLSv1_1_server_method());
763#endif
764#if SSL_OP_NO_TLSv1_2
765 if (bind_conf->ssl_options & BC_SSL_O_USE_TLSV12)
766 SSL_CTX_set_ssl_version(ctx, TLSv1_2_server_method());
767#endif
Emeric Brunfc0421f2012-09-07 17:30:07 +0200768
769 SSL_CTX_set_options(ctx, ssloptions);
770 SSL_CTX_set_mode(ctx, sslmode);
Emeric Brun850efd52014-01-29 12:24:34 +0100771 switch (bind_conf->verify) {
772 case SSL_SOCK_VERIFY_NONE:
773 verify = SSL_VERIFY_NONE;
774 break;
775 case SSL_SOCK_VERIFY_OPTIONAL:
776 verify = SSL_VERIFY_PEER;
777 break;
778 case SSL_SOCK_VERIFY_REQUIRED:
779 verify = SSL_VERIFY_PEER|SSL_VERIFY_FAIL_IF_NO_PEER_CERT;
780 break;
781 }
782 SSL_CTX_set_verify(ctx, verify, ssl_sock_bind_verifycbk);
783 if (verify & SSL_VERIFY_PEER) {
Emeric Brunfb510ea2012-10-05 12:00:26 +0200784 if (bind_conf->ca_file) {
Emeric Brund94b3fe2012-09-20 18:23:56 +0200785 /* load CAfile to verify */
Emeric Brunfb510ea2012-10-05 12:00:26 +0200786 if (!SSL_CTX_load_verify_locations(ctx, bind_conf->ca_file, NULL)) {
Emeric Brund94b3fe2012-09-20 18:23:56 +0200787 Alert("Proxy '%s': unable to load CA file '%s' for bind '%s' at [%s:%d].\n",
Emeric Brunfb510ea2012-10-05 12:00:26 +0200788 curproxy->id, bind_conf->ca_file, bind_conf->arg, bind_conf->file, bind_conf->line);
Emeric Brund94b3fe2012-09-20 18:23:56 +0200789 cfgerr++;
790 }
791 /* set CA names fo client cert request, function returns void */
Emeric Brunfb510ea2012-10-05 12:00:26 +0200792 SSL_CTX_set_client_CA_list(ctx, SSL_load_client_CA_file(bind_conf->ca_file));
Emeric Brund94b3fe2012-09-20 18:23:56 +0200793 }
Emeric Brun850efd52014-01-29 12:24:34 +0100794 else {
795 Alert("Proxy '%s': verify is enabled but no CA file specified for bind '%s' at [%s:%d].\n",
796 curproxy->id, bind_conf->arg, bind_conf->file, bind_conf->line);
797 cfgerr++;
798 }
Emeric Brun051cdab2012-10-02 19:25:50 +0200799#ifdef X509_V_FLAG_CRL_CHECK
Emeric Brunfb510ea2012-10-05 12:00:26 +0200800 if (bind_conf->crl_file) {
Emeric Brund94b3fe2012-09-20 18:23:56 +0200801 X509_STORE *store = SSL_CTX_get_cert_store(ctx);
802
Emeric Brunfb510ea2012-10-05 12:00:26 +0200803 if (!store || !X509_STORE_load_locations(store, bind_conf->crl_file, NULL)) {
Emeric Brund94b3fe2012-09-20 18:23:56 +0200804 Alert("Proxy '%s': unable to configure CRL file '%s' for bind '%s' at [%s:%d].\n",
Emeric Brunfb510ea2012-10-05 12:00:26 +0200805 curproxy->id, bind_conf->ca_file, bind_conf->arg, bind_conf->file, bind_conf->line);
Emeric Brund94b3fe2012-09-20 18:23:56 +0200806 cfgerr++;
807 }
Emeric Brun561e5742012-10-02 15:20:55 +0200808 else {
809 X509_STORE_set_flags(store, X509_V_FLAG_CRL_CHECK|X509_V_FLAG_CRL_CHECK_ALL);
810 }
Emeric Brund94b3fe2012-09-20 18:23:56 +0200811 }
Emeric Brun051cdab2012-10-02 19:25:50 +0200812#endif
Emeric Brun644cde02012-12-14 11:21:13 +0100813 ERR_clear_error();
Emeric Brund94b3fe2012-09-20 18:23:56 +0200814 }
Emeric Brunfc0421f2012-09-07 17:30:07 +0200815
Emeric Brun4f65bff2012-11-16 15:11:00 +0100816 if (global.tune.ssllifetime)
817 SSL_CTX_set_timeout(ctx, global.tune.ssllifetime);
818
Emeric Brunfc0421f2012-09-07 17:30:07 +0200819 shared_context_set_cache(ctx);
Willy Tarreau2a65ff02012-09-13 17:54:29 +0200820 if (bind_conf->ciphers &&
821 !SSL_CTX_set_cipher_list(ctx, bind_conf->ciphers)) {
Emeric Brunfc0421f2012-09-07 17:30:07 +0200822 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 +0200823 curproxy->id, bind_conf->ciphers, bind_conf->arg, bind_conf->file, bind_conf->line);
Emeric Brunfc0421f2012-09-07 17:30:07 +0200824 cfgerr++;
825 }
826
827 SSL_CTX_set_info_callback(ctx, ssl_sock_infocbk);
Emeric Brun29f037d2014-04-25 19:05:36 +0200828 SSL_CTX_set_msg_callback(ctx, ssl_sock_msgcbk);
829
Willy Tarreau6c9a3d52012-10-18 18:57:14 +0200830#ifdef OPENSSL_NPN_NEGOTIATED
831 if (bind_conf->npn_str)
832 SSL_CTX_set_next_protos_advertised_cb(ctx, ssl_sock_advertise_npn_protos, bind_conf);
833#endif
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +0100834#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Willy Tarreauab861d32013-04-02 02:30:41 +0200835 if (bind_conf->alpn_str)
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +0100836 SSL_CTX_set_alpn_select_cb(ctx, ssl_sock_advertise_alpn_protos, bind_conf);
Willy Tarreauab861d32013-04-02 02:30:41 +0200837#endif
Willy Tarreau6c9a3d52012-10-18 18:57:14 +0200838
Emeric Brunfc0421f2012-09-07 17:30:07 +0200839#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
840 SSL_CTX_set_tlsext_servername_callback(ctx, ssl_sock_switchctx_cbk);
Willy Tarreau2a65ff02012-09-13 17:54:29 +0200841 SSL_CTX_set_tlsext_servername_arg(ctx, bind_conf);
Emeric Brunfc0421f2012-09-07 17:30:07 +0200842#endif
Emeric Brun2b58d042012-09-20 17:10:03 +0200843#if defined(SSL_CTX_set_tmp_ecdh) && !defined(OPENSSL_NO_ECDH)
Emeric Brun6924ef82013-03-06 14:08:53 +0100844 {
Emeric Brun2b58d042012-09-20 17:10:03 +0200845 int i;
846 EC_KEY *ecdh;
847
Emeric Brun6924ef82013-03-06 14:08:53 +0100848 i = OBJ_sn2nid(bind_conf->ecdhe ? bind_conf->ecdhe : ECDHE_DEFAULT_CURVE);
Emeric Brun2b58d042012-09-20 17:10:03 +0200849 if (!i || ((ecdh = EC_KEY_new_by_curve_name(i)) == NULL)) {
850 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 +0100851 curproxy->id, bind_conf->ecdhe ? bind_conf->ecdhe : ECDHE_DEFAULT_CURVE,
852 bind_conf->arg, bind_conf->file, bind_conf->line);
Emeric Brun2b58d042012-09-20 17:10:03 +0200853 cfgerr++;
854 }
855 else {
856 SSL_CTX_set_tmp_ecdh(ctx, ecdh);
857 EC_KEY_free(ecdh);
858 }
859 }
860#endif
861
Emeric Brunfc0421f2012-09-07 17:30:07 +0200862 return cfgerr;
863}
864
Evan Broderbe554312013-06-27 00:05:25 -0700865static int ssl_sock_srv_hostcheck(const char *pattern, const char *hostname)
866{
867 const char *pattern_wildcard, *pattern_left_label_end, *hostname_left_label_end;
868 size_t prefixlen, suffixlen;
869
870 /* Trivial case */
871 if (strcmp(pattern, hostname) == 0)
872 return 1;
873
Evan Broderbe554312013-06-27 00:05:25 -0700874 /* The rest of this logic is based on RFC 6125, section 6.4.3
875 * (http://tools.ietf.org/html/rfc6125#section-6.4.3) */
876
Emeric Bruna848dae2013-10-08 11:27:28 +0200877 pattern_wildcard = NULL;
878 pattern_left_label_end = pattern;
879 while (*pattern_left_label_end != '.') {
880 switch (*pattern_left_label_end) {
881 case 0:
882 /* End of label not found */
883 return 0;
884 case '*':
885 /* If there is more than one wildcards */
886 if (pattern_wildcard)
887 return 0;
888 pattern_wildcard = pattern_left_label_end;
889 break;
890 }
891 pattern_left_label_end++;
892 }
893
894 /* If it's not trivial and there is no wildcard, it can't
895 * match */
896 if (!pattern_wildcard)
Evan Broderbe554312013-06-27 00:05:25 -0700897 return 0;
898
899 /* Make sure all labels match except the leftmost */
900 hostname_left_label_end = strchr(hostname, '.');
901 if (!hostname_left_label_end
902 || strcmp(pattern_left_label_end, hostname_left_label_end) != 0)
903 return 0;
904
905 /* Make sure the leftmost label of the hostname is long enough
906 * that the wildcard can match */
Emeric Brun369da852013-10-08 11:39:35 +0200907 if (hostname_left_label_end - hostname < (pattern_left_label_end - pattern) - 1)
Evan Broderbe554312013-06-27 00:05:25 -0700908 return 0;
909
910 /* Finally compare the string on either side of the
911 * wildcard */
912 prefixlen = pattern_wildcard - pattern;
913 suffixlen = pattern_left_label_end - (pattern_wildcard + 1);
Emeric Bruna848dae2013-10-08 11:27:28 +0200914 if ((prefixlen && (memcmp(pattern, hostname, prefixlen) != 0))
915 || (suffixlen && (memcmp(pattern_wildcard + 1, hostname_left_label_end - suffixlen, suffixlen) != 0)))
Evan Broderbe554312013-06-27 00:05:25 -0700916 return 0;
917
918 return 1;
919}
920
921static int ssl_sock_srv_verifycbk(int ok, X509_STORE_CTX *ctx)
922{
923 SSL *ssl;
924 struct connection *conn;
925 char *servername;
926
927 int depth;
928 X509 *cert;
929 STACK_OF(GENERAL_NAME) *alt_names;
930 int i;
931 X509_NAME *cert_subject;
932 char *str;
933
934 if (ok == 0)
935 return ok;
936
937 ssl = X509_STORE_CTX_get_ex_data(ctx, SSL_get_ex_data_X509_STORE_CTX_idx());
938 conn = (struct connection *)SSL_get_app_data(ssl);
939
940 servername = objt_server(conn->target)->ssl_ctx.verify_host;
941
942 /* We only need to verify the CN on the actual server cert,
943 * not the indirect CAs */
944 depth = X509_STORE_CTX_get_error_depth(ctx);
945 if (depth != 0)
946 return ok;
947
948 /* At this point, the cert is *not* OK unless we can find a
949 * hostname match */
950 ok = 0;
951
952 cert = X509_STORE_CTX_get_current_cert(ctx);
953 /* It seems like this might happen if verify peer isn't set */
954 if (!cert)
955 return ok;
956
957 alt_names = X509_get_ext_d2i(cert, NID_subject_alt_name, NULL, NULL);
958 if (alt_names) {
959 for (i = 0; !ok && i < sk_GENERAL_NAME_num(alt_names); i++) {
960 GENERAL_NAME *name = sk_GENERAL_NAME_value(alt_names, i);
961 if (name->type == GEN_DNS) {
Emeric Bruna33410c2013-09-17 15:47:48 +0200962#if OPENSSL_VERSION_NUMBER < 0x00907000L
963 if (ASN1_STRING_to_UTF8((unsigned char **)&str, name->d.ia5) >= 0) {
964#else
Evan Broderbe554312013-06-27 00:05:25 -0700965 if (ASN1_STRING_to_UTF8((unsigned char **)&str, name->d.dNSName) >= 0) {
Emeric Bruna33410c2013-09-17 15:47:48 +0200966#endif
Evan Broderbe554312013-06-27 00:05:25 -0700967 ok = ssl_sock_srv_hostcheck(str, servername);
968 OPENSSL_free(str);
969 }
970 }
971 }
Emeric Brun4ad50a42013-09-17 15:19:54 +0200972 sk_GENERAL_NAME_pop_free(alt_names, GENERAL_NAME_free);
Evan Broderbe554312013-06-27 00:05:25 -0700973 }
974
975 cert_subject = X509_get_subject_name(cert);
976 i = -1;
977 while (!ok && (i = X509_NAME_get_index_by_NID(cert_subject, NID_commonName, i)) != -1) {
978 X509_NAME_ENTRY *entry = X509_NAME_get_entry(cert_subject, i);
979 if (ASN1_STRING_to_UTF8((unsigned char **)&str, entry->value) >= 0) {
980 ok = ssl_sock_srv_hostcheck(str, servername);
981 OPENSSL_free(str);
982 }
983 }
984
985 return ok;
986}
987
Emeric Brun94324a42012-10-11 14:00:19 +0200988/* prepare ssl context from servers options. Returns an error count */
989int ssl_sock_prepare_srv_ctx(struct server *srv, struct proxy *curproxy)
990{
991 int cfgerr = 0;
992 int options =
993 SSL_OP_ALL | /* all known workarounds for bugs */
994 SSL_OP_NO_SSLv2 |
995 SSL_OP_NO_COMPRESSION;
996 int mode =
997 SSL_MODE_ENABLE_PARTIAL_WRITE |
998 SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER |
999 SSL_MODE_RELEASE_BUFFERS;
Emeric Brun850efd52014-01-29 12:24:34 +01001000 int verify = SSL_VERIFY_NONE;
Emeric Brun94324a42012-10-11 14:00:19 +02001001
Thierry Fournier383085f2013-01-24 14:15:43 +01001002 /* Make sure openssl opens /dev/urandom before the chroot */
1003 if (!ssl_initialize_random()) {
1004 Alert("OpenSSL random data generator initialization failed.\n");
1005 cfgerr++;
1006 }
1007
Emeric Brun94324a42012-10-11 14:00:19 +02001008 /* Initiate SSL context for current server */
1009 srv->ssl_ctx.reused_sess = NULL;
1010 if (srv->use_ssl)
1011 srv->xprt = &ssl_sock;
1012 if (srv->check.use_ssl)
Simon Horman66183002013-02-23 10:16:43 +09001013 srv->check_common.xprt = &ssl_sock;
Emeric Brun94324a42012-10-11 14:00:19 +02001014
1015 srv->ssl_ctx.ctx = SSL_CTX_new(SSLv23_client_method());
1016 if (!srv->ssl_ctx.ctx) {
1017 Alert("config : %s '%s', server '%s': unable to allocate ssl context.\n",
1018 proxy_type_str(curproxy), curproxy->id,
1019 srv->id);
1020 cfgerr++;
1021 return cfgerr;
1022 }
Emeric Bruna7aa3092012-10-26 12:58:00 +02001023 if (srv->ssl_ctx.client_crt) {
1024 if (SSL_CTX_use_PrivateKey_file(srv->ssl_ctx.ctx, srv->ssl_ctx.client_crt, SSL_FILETYPE_PEM) <= 0) {
1025 Alert("config : %s '%s', server '%s': unable to load SSL private key from PEM file '%s'.\n",
1026 proxy_type_str(curproxy), curproxy->id,
1027 srv->id, srv->ssl_ctx.client_crt);
1028 cfgerr++;
1029 }
1030 else if (SSL_CTX_use_certificate_chain_file(srv->ssl_ctx.ctx, srv->ssl_ctx.client_crt) <= 0) {
1031 Alert("config : %s '%s', server '%s': unable to load ssl certificate from PEM file '%s'.\n",
1032 proxy_type_str(curproxy), curproxy->id,
1033 srv->id, srv->ssl_ctx.client_crt);
1034 cfgerr++;
1035 }
1036 else if (SSL_CTX_check_private_key(srv->ssl_ctx.ctx) <= 0) {
1037 Alert("config : %s '%s', server '%s': inconsistencies between private key and certificate loaded from PEM file '%s'.\n",
1038 proxy_type_str(curproxy), curproxy->id,
1039 srv->id, srv->ssl_ctx.client_crt);
1040 cfgerr++;
1041 }
1042 }
Emeric Brun94324a42012-10-11 14:00:19 +02001043
1044 if (srv->ssl_ctx.options & SRV_SSL_O_NO_SSLV3)
1045 options |= SSL_OP_NO_SSLv3;
1046 if (srv->ssl_ctx.options & SRV_SSL_O_NO_TLSV10)
1047 options |= SSL_OP_NO_TLSv1;
1048 if (srv->ssl_ctx.options & SRV_SSL_O_NO_TLSV11)
1049 options |= SSL_OP_NO_TLSv1_1;
1050 if (srv->ssl_ctx.options & SRV_SSL_O_NO_TLSV12)
1051 options |= SSL_OP_NO_TLSv1_2;
Emeric Brunf9c5c472012-10-11 15:28:34 +02001052 if (srv->ssl_ctx.options & SRV_SSL_O_NO_TLS_TICKETS)
1053 options |= SSL_OP_NO_TICKET;
Emeric Brun94324a42012-10-11 14:00:19 +02001054 if (srv->ssl_ctx.options & SRV_SSL_O_USE_SSLV3)
1055 SSL_CTX_set_ssl_version(srv->ssl_ctx.ctx, SSLv3_client_method());
1056 if (srv->ssl_ctx.options & SRV_SSL_O_USE_TLSV10)
1057 SSL_CTX_set_ssl_version(srv->ssl_ctx.ctx, TLSv1_client_method());
1058#if SSL_OP_NO_TLSv1_1
1059 if (srv->ssl_ctx.options & SRV_SSL_O_USE_TLSV11)
1060 SSL_CTX_set_ssl_version(srv->ssl_ctx.ctx, TLSv1_1_client_method());
1061#endif
1062#if SSL_OP_NO_TLSv1_2
1063 if (srv->ssl_ctx.options & SRV_SSL_O_USE_TLSV12)
1064 SSL_CTX_set_ssl_version(srv->ssl_ctx.ctx, TLSv1_2_client_method());
1065#endif
1066
1067 SSL_CTX_set_options(srv->ssl_ctx.ctx, options);
1068 SSL_CTX_set_mode(srv->ssl_ctx.ctx, mode);
Emeric Brun850efd52014-01-29 12:24:34 +01001069
1070 if (global.ssl_server_verify == SSL_SERVER_VERIFY_REQUIRED)
1071 verify = SSL_VERIFY_PEER;
1072
1073 switch (srv->ssl_ctx.verify) {
1074 case SSL_SOCK_VERIFY_NONE:
1075 verify = SSL_VERIFY_NONE;
1076 break;
1077 case SSL_SOCK_VERIFY_REQUIRED:
1078 verify = SSL_VERIFY_PEER;
1079 break;
1080 }
Evan Broderbe554312013-06-27 00:05:25 -07001081 SSL_CTX_set_verify(srv->ssl_ctx.ctx,
Emeric Brun850efd52014-01-29 12:24:34 +01001082 verify,
Evan Broderbe554312013-06-27 00:05:25 -07001083 srv->ssl_ctx.verify_host ? ssl_sock_srv_verifycbk : NULL);
Emeric Brun850efd52014-01-29 12:24:34 +01001084 if (verify & SSL_VERIFY_PEER) {
Emeric Brunef42d922012-10-11 16:11:36 +02001085 if (srv->ssl_ctx.ca_file) {
1086 /* load CAfile to verify */
1087 if (!SSL_CTX_load_verify_locations(srv->ssl_ctx.ctx, srv->ssl_ctx.ca_file, NULL)) {
Willy Tarreau07ba08b2014-02-16 19:22:08 +01001088 Alert("Proxy '%s', server '%s' [%s:%d] unable to load CA file '%s'.\n",
Emeric Brunef42d922012-10-11 16:11:36 +02001089 curproxy->id, srv->id,
1090 srv->conf.file, srv->conf.line, srv->ssl_ctx.ca_file);
1091 cfgerr++;
1092 }
1093 }
Emeric Brun850efd52014-01-29 12:24:34 +01001094 else {
1095 if (global.ssl_server_verify == SSL_SERVER_VERIFY_REQUIRED)
Willy Tarreau07ba08b2014-02-16 19:22:08 +01001096 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 +01001097 curproxy->id, srv->id,
1098 srv->conf.file, srv->conf.line);
1099 else
Willy Tarreau07ba08b2014-02-16 19:22:08 +01001100 Alert("Proxy '%s', server '%s' [%s:%d] verify is enabled but no CA file specified.\n",
Emeric Brun850efd52014-01-29 12:24:34 +01001101 curproxy->id, srv->id,
1102 srv->conf.file, srv->conf.line);
1103 cfgerr++;
1104 }
Emeric Brunef42d922012-10-11 16:11:36 +02001105#ifdef X509_V_FLAG_CRL_CHECK
1106 if (srv->ssl_ctx.crl_file) {
1107 X509_STORE *store = SSL_CTX_get_cert_store(srv->ssl_ctx.ctx);
1108
1109 if (!store || !X509_STORE_load_locations(store, srv->ssl_ctx.crl_file, NULL)) {
Willy Tarreau07ba08b2014-02-16 19:22:08 +01001110 Alert("Proxy '%s', server '%s' [%s:%d] unable to configure CRL file '%s'.\n",
Emeric Brunef42d922012-10-11 16:11:36 +02001111 curproxy->id, srv->id,
1112 srv->conf.file, srv->conf.line, srv->ssl_ctx.crl_file);
1113 cfgerr++;
1114 }
1115 else {
1116 X509_STORE_set_flags(store, X509_V_FLAG_CRL_CHECK|X509_V_FLAG_CRL_CHECK_ALL);
1117 }
1118 }
1119#endif
1120 }
1121
Emeric Brun4f65bff2012-11-16 15:11:00 +01001122 if (global.tune.ssllifetime)
1123 SSL_CTX_set_timeout(srv->ssl_ctx.ctx, global.tune.ssllifetime);
1124
Emeric Brun94324a42012-10-11 14:00:19 +02001125 SSL_CTX_set_session_cache_mode(srv->ssl_ctx.ctx, SSL_SESS_CACHE_OFF);
1126 if (srv->ssl_ctx.ciphers &&
1127 !SSL_CTX_set_cipher_list(srv->ssl_ctx.ctx, srv->ssl_ctx.ciphers)) {
1128 Alert("Proxy '%s', server '%s' [%s:%d] : unable to set SSL cipher list to '%s'.\n",
1129 curproxy->id, srv->id,
1130 srv->conf.file, srv->conf.line, srv->ssl_ctx.ciphers);
1131 cfgerr++;
1132 }
1133
1134 return cfgerr;
1135}
1136
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001137/* Walks down the two trees in bind_conf and prepares all certs. The pointer may
Emeric Brunfc0421f2012-09-07 17:30:07 +02001138 * be NULL, in which case nothing is done. Returns the number of errors
1139 * encountered.
1140 */
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001141int ssl_sock_prepare_all_ctx(struct bind_conf *bind_conf, struct proxy *px)
Emeric Brunfc0421f2012-09-07 17:30:07 +02001142{
1143 struct ebmb_node *node;
1144 struct sni_ctx *sni;
1145 int err = 0;
1146
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001147 if (!bind_conf || !bind_conf->is_ssl)
Emeric Brunfc0421f2012-09-07 17:30:07 +02001148 return 0;
1149
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001150 node = ebmb_first(&bind_conf->sni_ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001151 while (node) {
1152 sni = ebmb_entry(node, struct sni_ctx, name);
1153 if (!sni->order) /* only initialize the CTX on its first occurrence */
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001154 err += ssl_sock_prepare_ctx(bind_conf, sni->ctx, px);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001155 node = ebmb_next(node);
1156 }
1157
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001158 node = ebmb_first(&bind_conf->sni_w_ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001159 while (node) {
1160 sni = ebmb_entry(node, struct sni_ctx, name);
1161 if (!sni->order) /* only initialize the CTX on its first occurrence */
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001162 err += ssl_sock_prepare_ctx(bind_conf, sni->ctx, px);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001163 node = ebmb_next(node);
1164 }
1165 return err;
1166}
1167
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001168/* Walks down the two trees in bind_conf and frees all the certs. The pointer may
Emeric Brunfc0421f2012-09-07 17:30:07 +02001169 * be NULL, in which case nothing is done. The default_ctx is nullified too.
1170 */
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001171void ssl_sock_free_all_ctx(struct bind_conf *bind_conf)
Emeric Brunfc0421f2012-09-07 17:30:07 +02001172{
1173 struct ebmb_node *node, *back;
1174 struct sni_ctx *sni;
1175
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001176 if (!bind_conf || !bind_conf->is_ssl)
Emeric Brunfc0421f2012-09-07 17:30:07 +02001177 return;
1178
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001179 node = ebmb_first(&bind_conf->sni_ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001180 while (node) {
1181 sni = ebmb_entry(node, struct sni_ctx, name);
1182 back = ebmb_next(node);
1183 ebmb_delete(node);
1184 if (!sni->order) /* only free the CTX on its first occurrence */
1185 SSL_CTX_free(sni->ctx);
1186 free(sni);
1187 node = back;
1188 }
1189
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001190 node = ebmb_first(&bind_conf->sni_w_ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001191 while (node) {
1192 sni = ebmb_entry(node, struct sni_ctx, name);
1193 back = ebmb_next(node);
1194 ebmb_delete(node);
1195 if (!sni->order) /* only free the CTX on its first occurrence */
1196 SSL_CTX_free(sni->ctx);
1197 free(sni);
1198 node = back;
1199 }
1200
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001201 bind_conf->default_ctx = NULL;
Emeric Brune1f38db2012-09-03 20:36:47 +02001202}
1203
Emeric Brun46591952012-05-18 15:47:34 +02001204/*
1205 * This function is called if SSL * context is not yet allocated. The function
1206 * is designed to be called before any other data-layer operation and sets the
1207 * handshake flag on the connection. It is safe to call it multiple times.
1208 * It returns 0 on success and -1 in error case.
1209 */
1210static int ssl_sock_init(struct connection *conn)
1211{
1212 /* already initialized */
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02001213 if (conn->xprt_ctx)
Emeric Brun46591952012-05-18 15:47:34 +02001214 return 0;
1215
Willy Tarreau3c728722014-01-23 13:50:42 +01001216 if (!conn_ctrl_ready(conn))
Willy Tarreauf79c8172013-10-21 16:30:56 +02001217 return 0;
1218
Willy Tarreau20879a02012-12-03 16:32:10 +01001219 if (global.maxsslconn && sslconns >= global.maxsslconn) {
1220 conn->err_code = CO_ER_SSL_TOO_MANY;
Willy Tarreau403edff2012-09-06 11:58:37 +02001221 return -1;
Willy Tarreau20879a02012-12-03 16:32:10 +01001222 }
Willy Tarreau403edff2012-09-06 11:58:37 +02001223
Emeric Brun46591952012-05-18 15:47:34 +02001224 /* If it is in client mode initiate SSL session
1225 in connect state otherwise accept state */
Willy Tarreau3fdb3662012-11-12 00:42:33 +01001226 if (objt_server(conn->target)) {
Emeric Brun46591952012-05-18 15:47:34 +02001227 /* Alloc a new SSL session ctx */
Willy Tarreau3fdb3662012-11-12 00:42:33 +01001228 conn->xprt_ctx = SSL_new(objt_server(conn->target)->ssl_ctx.ctx);
Willy Tarreau20879a02012-12-03 16:32:10 +01001229 if (!conn->xprt_ctx) {
1230 conn->err_code = CO_ER_SSL_NO_MEM;
Emeric Brun46591952012-05-18 15:47:34 +02001231 return -1;
Willy Tarreau20879a02012-12-03 16:32:10 +01001232 }
Emeric Brun46591952012-05-18 15:47:34 +02001233
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02001234 SSL_set_connect_state(conn->xprt_ctx);
Willy Tarreau3fdb3662012-11-12 00:42:33 +01001235 if (objt_server(conn->target)->ssl_ctx.reused_sess)
1236 SSL_set_session(conn->xprt_ctx, objt_server(conn->target)->ssl_ctx.reused_sess);
Emeric Brun46591952012-05-18 15:47:34 +02001237
1238 /* set fd on SSL session context */
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02001239 SSL_set_fd(conn->xprt_ctx, conn->t.sock.fd);
Emeric Brun46591952012-05-18 15:47:34 +02001240
Evan Broderbe554312013-06-27 00:05:25 -07001241 /* set connection pointer */
1242 SSL_set_app_data(conn->xprt_ctx, conn);
1243
Emeric Brun46591952012-05-18 15:47:34 +02001244 /* leave init state and start handshake */
Willy Tarreau05737472012-09-04 08:03:39 +02001245 conn->flags |= CO_FL_SSL_WAIT_HS | CO_FL_WAIT_L6_CONN;
Willy Tarreau403edff2012-09-06 11:58:37 +02001246
1247 sslconns++;
Willy Tarreau71b734c2014-01-28 15:19:44 +01001248 totalsslconns++;
Emeric Brun46591952012-05-18 15:47:34 +02001249 return 0;
1250 }
Willy Tarreau3fdb3662012-11-12 00:42:33 +01001251 else if (objt_listener(conn->target)) {
Emeric Brun46591952012-05-18 15:47:34 +02001252 /* Alloc a new SSL session ctx */
Willy Tarreau3fdb3662012-11-12 00:42:33 +01001253 conn->xprt_ctx = SSL_new(objt_listener(conn->target)->bind_conf->default_ctx);
Willy Tarreau20879a02012-12-03 16:32:10 +01001254 if (!conn->xprt_ctx) {
1255 conn->err_code = CO_ER_SSL_NO_MEM;
Emeric Brun46591952012-05-18 15:47:34 +02001256 return -1;
Willy Tarreau20879a02012-12-03 16:32:10 +01001257 }
Emeric Brun46591952012-05-18 15:47:34 +02001258
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02001259 SSL_set_accept_state(conn->xprt_ctx);
Emeric Brun46591952012-05-18 15:47:34 +02001260
1261 /* set fd on SSL session context */
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02001262 SSL_set_fd(conn->xprt_ctx, conn->t.sock.fd);
Emeric Brun46591952012-05-18 15:47:34 +02001263
Emeric Brune1f38db2012-09-03 20:36:47 +02001264 /* set connection pointer */
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02001265 SSL_set_app_data(conn->xprt_ctx, conn);
Emeric Brune1f38db2012-09-03 20:36:47 +02001266
Emeric Brun46591952012-05-18 15:47:34 +02001267 /* leave init state and start handshake */
Willy Tarreau05737472012-09-04 08:03:39 +02001268 conn->flags |= CO_FL_SSL_WAIT_HS | CO_FL_WAIT_L6_CONN;
Willy Tarreau403edff2012-09-06 11:58:37 +02001269
1270 sslconns++;
Willy Tarreau71b734c2014-01-28 15:19:44 +01001271 totalsslconns++;
Emeric Brun46591952012-05-18 15:47:34 +02001272 return 0;
1273 }
1274 /* don't know how to handle such a target */
Willy Tarreau20879a02012-12-03 16:32:10 +01001275 conn->err_code = CO_ER_SSL_NO_TARGET;
Emeric Brun46591952012-05-18 15:47:34 +02001276 return -1;
1277}
1278
1279
1280/* This is the callback which is used when an SSL handshake is pending. It
1281 * updates the FD status if it wants some polling before being called again.
1282 * It returns 0 if it fails in a fatal way or needs to poll to go further,
1283 * otherwise it returns non-zero and removes itself from the connection's
1284 * flags (the bit is provided in <flag> by the caller).
1285 */
1286int ssl_sock_handshake(struct connection *conn, unsigned int flag)
1287{
1288 int ret;
1289
Willy Tarreau3c728722014-01-23 13:50:42 +01001290 if (!conn_ctrl_ready(conn))
Willy Tarreauf79c8172013-10-21 16:30:56 +02001291 return 0;
1292
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02001293 if (!conn->xprt_ctx)
Emeric Brun46591952012-05-18 15:47:34 +02001294 goto out_error;
1295
Emeric Brun674b7432012-11-08 19:21:55 +01001296 /* If we use SSL_do_handshake to process a reneg initiated by
1297 * the remote peer, it sometimes returns SSL_ERROR_SSL.
1298 * Usually SSL_write and SSL_read are used and process implicitly
1299 * the reneg handshake.
1300 * Here we use SSL_peek as a workaround for reneg.
1301 */
1302 if ((conn->flags & CO_FL_CONNECTED) && SSL_renegotiate_pending(conn->xprt_ctx)) {
1303 char c;
1304
1305 ret = SSL_peek(conn->xprt_ctx, &c, 1);
1306 if (ret <= 0) {
1307 /* handshake may have not been completed, let's find why */
1308 ret = SSL_get_error(conn->xprt_ctx, ret);
1309 if (ret == SSL_ERROR_WANT_WRITE) {
1310 /* SSL handshake needs to write, L4 connection may not be ready */
1311 __conn_sock_stop_recv(conn);
Willy Tarreaue1f50c42014-01-22 20:02:06 +01001312 __conn_sock_want_send(conn);
1313 fd_cant_send(conn->t.sock.fd);
Emeric Brun674b7432012-11-08 19:21:55 +01001314 return 0;
1315 }
1316 else if (ret == SSL_ERROR_WANT_READ) {
1317 /* handshake may have been completed but we have
1318 * no more data to read.
1319 */
1320 if (!SSL_renegotiate_pending(conn->xprt_ctx)) {
1321 ret = 1;
1322 goto reneg_ok;
1323 }
1324 /* SSL handshake needs to read, L4 connection is ready */
1325 if (conn->flags & CO_FL_WAIT_L4_CONN)
1326 conn->flags &= ~CO_FL_WAIT_L4_CONN;
1327 __conn_sock_stop_send(conn);
Willy Tarreaue1f50c42014-01-22 20:02:06 +01001328 __conn_sock_want_recv(conn);
1329 fd_cant_recv(conn->t.sock.fd);
Emeric Brun674b7432012-11-08 19:21:55 +01001330 return 0;
1331 }
1332 else if (ret == SSL_ERROR_SYSCALL) {
1333 /* if errno is null, then connection was successfully established */
1334 if (!errno && conn->flags & CO_FL_WAIT_L4_CONN)
1335 conn->flags &= ~CO_FL_WAIT_L4_CONN;
Willy Tarreau20879a02012-12-03 16:32:10 +01001336 if (!conn->err_code) {
Emeric Brun29f037d2014-04-25 19:05:36 +02001337 if (!((SSL *)conn->xprt_ctx)->packet_length) {
1338 if (!errno) {
1339 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
1340 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
1341 else
1342 conn->err_code = CO_ER_SSL_EMPTY;
1343 }
1344 else {
1345 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
1346 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
1347 else
1348 conn->err_code = CO_ER_SSL_ABORT;
1349 }
1350 }
1351 else {
1352 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
1353 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
Willy Tarreau20879a02012-12-03 16:32:10 +01001354 else
Emeric Brun29f037d2014-04-25 19:05:36 +02001355 conn->err_code = CO_ER_SSL_HANDSHAKE;
1356 }
Willy Tarreau20879a02012-12-03 16:32:10 +01001357 }
Emeric Brun674b7432012-11-08 19:21:55 +01001358 goto out_error;
1359 }
1360 else {
1361 /* Fail on all other handshake errors */
1362 /* Note: OpenSSL may leave unread bytes in the socket's
1363 * buffer, causing an RST to be emitted upon close() on
1364 * TCP sockets. We first try to drain possibly pending
1365 * data to avoid this as much as possible.
1366 */
Willy Tarreau46be2e52014-01-20 12:10:52 +01001367 conn_drain(conn);
Willy Tarreau20879a02012-12-03 16:32:10 +01001368 if (!conn->err_code)
Willy Tarreauf51c6982014-04-25 20:02:39 +02001369 conn->err_code = (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT) ?
1370 CO_ER_SSL_KILLED_HB : CO_ER_SSL_HANDSHAKE;
Emeric Brun674b7432012-11-08 19:21:55 +01001371 goto out_error;
1372 }
1373 }
1374 /* read some data: consider handshake completed */
1375 goto reneg_ok;
1376 }
1377
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02001378 ret = SSL_do_handshake(conn->xprt_ctx);
Emeric Brun46591952012-05-18 15:47:34 +02001379 if (ret != 1) {
1380 /* handshake did not complete, let's find why */
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02001381 ret = SSL_get_error(conn->xprt_ctx, ret);
Emeric Brun46591952012-05-18 15:47:34 +02001382
1383 if (ret == SSL_ERROR_WANT_WRITE) {
1384 /* SSL handshake needs to write, L4 connection may not be ready */
1385 __conn_sock_stop_recv(conn);
Willy Tarreaue1f50c42014-01-22 20:02:06 +01001386 __conn_sock_want_send(conn);
1387 fd_cant_send(conn->t.sock.fd);
Emeric Brun46591952012-05-18 15:47:34 +02001388 return 0;
1389 }
1390 else if (ret == SSL_ERROR_WANT_READ) {
1391 /* SSL handshake needs to read, L4 connection is ready */
1392 if (conn->flags & CO_FL_WAIT_L4_CONN)
1393 conn->flags &= ~CO_FL_WAIT_L4_CONN;
1394 __conn_sock_stop_send(conn);
Willy Tarreaue1f50c42014-01-22 20:02:06 +01001395 __conn_sock_want_recv(conn);
1396 fd_cant_recv(conn->t.sock.fd);
Emeric Brun46591952012-05-18 15:47:34 +02001397 return 0;
1398 }
Willy Tarreau89230192012-09-28 20:22:13 +02001399 else if (ret == SSL_ERROR_SYSCALL) {
1400 /* if errno is null, then connection was successfully established */
1401 if (!errno && conn->flags & CO_FL_WAIT_L4_CONN)
1402 conn->flags &= ~CO_FL_WAIT_L4_CONN;
Willy Tarreau20879a02012-12-03 16:32:10 +01001403
Emeric Brun29f037d2014-04-25 19:05:36 +02001404 if (!((SSL *)conn->xprt_ctx)->packet_length) {
1405 if (!errno) {
1406 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
1407 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
1408 else
1409 conn->err_code = CO_ER_SSL_EMPTY;
1410 }
1411 else {
1412 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
1413 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
1414 else
1415 conn->err_code = CO_ER_SSL_ABORT;
1416 }
1417 }
1418 else {
1419 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
1420 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
Willy Tarreau20879a02012-12-03 16:32:10 +01001421 else
Emeric Brun29f037d2014-04-25 19:05:36 +02001422 conn->err_code = CO_ER_SSL_HANDSHAKE;
1423 }
Willy Tarreau89230192012-09-28 20:22:13 +02001424 goto out_error;
1425 }
Emeric Brun46591952012-05-18 15:47:34 +02001426 else {
1427 /* Fail on all other handshake errors */
Willy Tarreau566dc552012-10-19 20:52:18 +02001428 /* Note: OpenSSL may leave unread bytes in the socket's
1429 * buffer, causing an RST to be emitted upon close() on
1430 * TCP sockets. We first try to drain possibly pending
1431 * data to avoid this as much as possible.
1432 */
Willy Tarreau46be2e52014-01-20 12:10:52 +01001433 conn_drain(conn);
Willy Tarreau20879a02012-12-03 16:32:10 +01001434 if (!conn->err_code)
Willy Tarreauf51c6982014-04-25 20:02:39 +02001435 conn->err_code = (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT) ?
1436 CO_ER_SSL_KILLED_HB : CO_ER_SSL_HANDSHAKE;
Emeric Brun46591952012-05-18 15:47:34 +02001437 goto out_error;
1438 }
1439 }
1440
Emeric Brun674b7432012-11-08 19:21:55 +01001441reneg_ok:
1442
Emeric Brun46591952012-05-18 15:47:34 +02001443 /* Handshake succeeded */
Willy Tarreau3fdb3662012-11-12 00:42:33 +01001444 if (objt_server(conn->target)) {
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02001445 if (!SSL_session_reused(conn->xprt_ctx)) {
Emeric Brun46591952012-05-18 15:47:34 +02001446 /* check if session was reused, if not store current session on server for reuse */
Willy Tarreau3fdb3662012-11-12 00:42:33 +01001447 if (objt_server(conn->target)->ssl_ctx.reused_sess)
1448 SSL_SESSION_free(objt_server(conn->target)->ssl_ctx.reused_sess);
Emeric Brun46591952012-05-18 15:47:34 +02001449
Willy Tarreau3fdb3662012-11-12 00:42:33 +01001450 objt_server(conn->target)->ssl_ctx.reused_sess = SSL_get1_session(conn->xprt_ctx);
Emeric Brun46591952012-05-18 15:47:34 +02001451 }
1452 }
1453
1454 /* The connection is now established at both layers, it's time to leave */
1455 conn->flags &= ~(flag | CO_FL_WAIT_L4_CONN | CO_FL_WAIT_L6_CONN);
1456 return 1;
1457
1458 out_error:
Emeric Brun644cde02012-12-14 11:21:13 +01001459 /* Clear openssl global errors stack */
1460 ERR_clear_error();
1461
Emeric Brun9fa89732012-10-04 17:09:56 +02001462 /* free resumed session if exists */
Willy Tarreau3fdb3662012-11-12 00:42:33 +01001463 if (objt_server(conn->target) && objt_server(conn->target)->ssl_ctx.reused_sess) {
1464 SSL_SESSION_free(objt_server(conn->target)->ssl_ctx.reused_sess);
1465 objt_server(conn->target)->ssl_ctx.reused_sess = NULL;
Emeric Brun9fa89732012-10-04 17:09:56 +02001466 }
1467
Emeric Brun46591952012-05-18 15:47:34 +02001468 /* Fail on all other handshake errors */
1469 conn->flags |= CO_FL_ERROR;
Willy Tarreau20879a02012-12-03 16:32:10 +01001470 if (!conn->err_code)
1471 conn->err_code = CO_ER_SSL_HANDSHAKE;
Emeric Brun46591952012-05-18 15:47:34 +02001472 return 0;
1473}
1474
1475/* Receive up to <count> bytes from connection <conn>'s socket and store them
Willy Tarreauabf08d92014-01-14 11:31:27 +01001476 * into buffer <buf>. Only one call to recv() is performed, unless the
Emeric Brun46591952012-05-18 15:47:34 +02001477 * buffer wraps, in which case a second call may be performed. The connection's
1478 * flags are updated with whatever special event is detected (error, read0,
1479 * empty). The caller is responsible for taking care of those events and
1480 * avoiding the call if inappropriate. The function does not call the
1481 * connection's polling update function, so the caller is responsible for this.
1482 */
1483static int ssl_sock_to_buf(struct connection *conn, struct buffer *buf, int count)
1484{
1485 int ret, done = 0;
Willy Tarreauabf08d92014-01-14 11:31:27 +01001486 int try;
Emeric Brun46591952012-05-18 15:47:34 +02001487
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02001488 if (!conn->xprt_ctx)
Emeric Brun46591952012-05-18 15:47:34 +02001489 goto out_error;
1490
1491 if (conn->flags & CO_FL_HANDSHAKE)
1492 /* a handshake was requested */
1493 return 0;
1494
Willy Tarreauabf08d92014-01-14 11:31:27 +01001495 /* let's realign the buffer to optimize I/O */
1496 if (buffer_empty(buf))
Emeric Brun46591952012-05-18 15:47:34 +02001497 buf->p = buf->data;
Emeric Brun46591952012-05-18 15:47:34 +02001498
1499 /* read the largest possible block. For this, we perform only one call
1500 * to recv() unless the buffer wraps and we exactly fill the first hunk,
1501 * in which case we accept to do it once again. A new attempt is made on
1502 * EINTR too.
1503 */
Willy Tarreau00b0fb92014-01-17 11:09:40 +01001504 while (count > 0) {
Willy Tarreauabf08d92014-01-14 11:31:27 +01001505 /* first check if we have some room after p+i */
1506 try = buf->data + buf->size - (buf->p + buf->i);
1507 /* otherwise continue between data and p-o */
1508 if (try <= 0) {
1509 try = buf->p - (buf->data + buf->o);
1510 if (try <= 0)
1511 break;
1512 }
1513 if (try > count)
1514 try = count;
1515
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02001516 ret = SSL_read(conn->xprt_ctx, bi_end(buf), try);
Emeric Brune1f38db2012-09-03 20:36:47 +02001517 if (conn->flags & CO_FL_ERROR) {
1518 /* CO_FL_ERROR may be set by ssl_sock_infocbk */
Emeric Brun644cde02012-12-14 11:21:13 +01001519 goto out_error;
Emeric Brune1f38db2012-09-03 20:36:47 +02001520 }
Emeric Brun46591952012-05-18 15:47:34 +02001521 if (ret > 0) {
1522 buf->i += ret;
1523 done += ret;
1524 if (ret < try)
1525 break;
1526 count -= ret;
Emeric Brun46591952012-05-18 15:47:34 +02001527 }
1528 else if (ret == 0) {
Emeric Brun644cde02012-12-14 11:21:13 +01001529 ret = SSL_get_error(conn->xprt_ctx, ret);
1530 if (ret != SSL_ERROR_ZERO_RETURN) {
Emeric Brun1c646862012-12-14 12:33:41 +01001531 /* error on protocol or underlying transport */
1532 if ((ret != SSL_ERROR_SYSCALL)
1533 || (errno && (errno != EAGAIN)))
1534 conn->flags |= CO_FL_ERROR;
1535
Emeric Brun644cde02012-12-14 11:21:13 +01001536 /* Clear openssl global errors stack */
1537 ERR_clear_error();
1538 }
Emeric Brun46591952012-05-18 15:47:34 +02001539 goto read0;
1540 }
1541 else {
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02001542 ret = SSL_get_error(conn->xprt_ctx, ret);
Emeric Brun46591952012-05-18 15:47:34 +02001543 if (ret == SSL_ERROR_WANT_WRITE) {
Emeric Brun8af8dd12012-11-08 17:56:20 +01001544 /* handshake is running, and it needs to enable write */
Emeric Brun46591952012-05-18 15:47:34 +02001545 conn->flags |= CO_FL_SSL_WAIT_HS;
Emeric Brun8af8dd12012-11-08 17:56:20 +01001546 __conn_sock_want_send(conn);
Emeric Brun46591952012-05-18 15:47:34 +02001547 break;
1548 }
1549 else if (ret == SSL_ERROR_WANT_READ) {
Emeric Brun282a76a2012-11-08 18:02:56 +01001550 if (SSL_renegotiate_pending(conn->xprt_ctx)) {
1551 /* handshake is running, and it may need to re-enable read */
1552 conn->flags |= CO_FL_SSL_WAIT_HS;
1553 __conn_sock_want_recv(conn);
1554 break;
1555 }
Emeric Brun46591952012-05-18 15:47:34 +02001556 /* we need to poll for retry a read later */
Willy Tarreaue1f50c42014-01-22 20:02:06 +01001557 fd_cant_recv(conn->t.sock.fd);
Emeric Brun46591952012-05-18 15:47:34 +02001558 break;
1559 }
1560 /* otherwise it's a real error */
1561 goto out_error;
1562 }
1563 }
1564 return done;
1565
1566 read0:
1567 conn_sock_read0(conn);
1568 return done;
1569 out_error:
Emeric Brun644cde02012-12-14 11:21:13 +01001570 /* Clear openssl global errors stack */
1571 ERR_clear_error();
1572
Emeric Brun46591952012-05-18 15:47:34 +02001573 conn->flags |= CO_FL_ERROR;
1574 return done;
1575}
1576
1577
1578/* Send all pending bytes from buffer <buf> to connection <conn>'s socket.
Willy Tarreau1049b1f2014-02-02 01:51:17 +01001579 * <flags> may contain some CO_SFL_* flags to hint the system about other
1580 * pending data for example, but this flag is ignored at the moment.
Emeric Brun46591952012-05-18 15:47:34 +02001581 * Only one call to send() is performed, unless the buffer wraps, in which case
1582 * a second call may be performed. The connection's flags are updated with
1583 * whatever special event is detected (error, empty). The caller is responsible
1584 * for taking care of those events and avoiding the call if inappropriate. The
1585 * function does not call the connection's polling update function, so the caller
1586 * is responsible for this.
1587 */
1588static int ssl_sock_from_buf(struct connection *conn, struct buffer *buf, int flags)
1589{
1590 int ret, try, done;
1591
1592 done = 0;
1593
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02001594 if (!conn->xprt_ctx)
Emeric Brun46591952012-05-18 15:47:34 +02001595 goto out_error;
1596
1597 if (conn->flags & CO_FL_HANDSHAKE)
1598 /* a handshake was requested */
1599 return 0;
1600
1601 /* send the largest possible block. For this we perform only one call
1602 * to send() unless the buffer wraps and we exactly fill the first hunk,
1603 * in which case we accept to do it once again.
1604 */
1605 while (buf->o) {
Kevin Hestercad82342013-05-30 15:12:41 -07001606 try = bo_contig_data(buf);
Willy Tarreaubfd59462013-02-21 07:46:09 +01001607
Willy Tarreau7bed9452014-02-02 02:00:24 +01001608 if (!(flags & CO_SFL_STREAMER) &&
Willy Tarreau518cedd2014-02-17 15:43:01 +01001609 !(conn->xprt_st & SSL_SOCK_SEND_UNLIMITED) &&
1610 global.tune.ssl_max_record && try > global.tune.ssl_max_record) {
Willy Tarreaubfd59462013-02-21 07:46:09 +01001611 try = global.tune.ssl_max_record;
Willy Tarreau518cedd2014-02-17 15:43:01 +01001612 }
1613 else {
1614 /* we need to keep the information about the fact that
1615 * we're not limiting the upcoming send(), because if it
1616 * fails, we'll have to retry with at least as many data.
1617 */
1618 conn->xprt_st |= SSL_SOCK_SEND_UNLIMITED;
1619 }
Willy Tarreaubfd59462013-02-21 07:46:09 +01001620
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02001621 ret = SSL_write(conn->xprt_ctx, bo_ptr(buf), try);
Willy Tarreau518cedd2014-02-17 15:43:01 +01001622
Emeric Brune1f38db2012-09-03 20:36:47 +02001623 if (conn->flags & CO_FL_ERROR) {
1624 /* CO_FL_ERROR may be set by ssl_sock_infocbk */
Emeric Brun644cde02012-12-14 11:21:13 +01001625 goto out_error;
Emeric Brune1f38db2012-09-03 20:36:47 +02001626 }
Emeric Brun46591952012-05-18 15:47:34 +02001627 if (ret > 0) {
Willy Tarreau518cedd2014-02-17 15:43:01 +01001628 conn->xprt_st &= ~SSL_SOCK_SEND_UNLIMITED;
1629
Emeric Brun46591952012-05-18 15:47:34 +02001630 buf->o -= ret;
1631 done += ret;
1632
Willy Tarreau5fb38032012-12-16 19:39:09 +01001633 if (likely(buffer_empty(buf)))
Emeric Brun46591952012-05-18 15:47:34 +02001634 /* optimize data alignment in the buffer */
1635 buf->p = buf->data;
1636
1637 /* if the system buffer is full, don't insist */
1638 if (ret < try)
1639 break;
1640 }
1641 else {
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02001642 ret = SSL_get_error(conn->xprt_ctx, ret);
Emeric Brun46591952012-05-18 15:47:34 +02001643 if (ret == SSL_ERROR_WANT_WRITE) {
Emeric Brun282a76a2012-11-08 18:02:56 +01001644 if (SSL_renegotiate_pending(conn->xprt_ctx)) {
1645 /* handshake is running, and it may need to re-enable write */
1646 conn->flags |= CO_FL_SSL_WAIT_HS;
1647 __conn_sock_want_send(conn);
1648 break;
1649 }
Emeric Brun46591952012-05-18 15:47:34 +02001650 /* we need to poll to retry a write later */
Willy Tarreaue1f50c42014-01-22 20:02:06 +01001651 fd_cant_send(conn->t.sock.fd);
Emeric Brun46591952012-05-18 15:47:34 +02001652 break;
1653 }
1654 else if (ret == SSL_ERROR_WANT_READ) {
Emeric Brun8af8dd12012-11-08 17:56:20 +01001655 /* handshake is running, and it needs to enable read */
Emeric Brun46591952012-05-18 15:47:34 +02001656 conn->flags |= CO_FL_SSL_WAIT_HS;
Emeric Brun8af8dd12012-11-08 17:56:20 +01001657 __conn_sock_want_recv(conn);
Emeric Brun46591952012-05-18 15:47:34 +02001658 break;
1659 }
1660 goto out_error;
1661 }
1662 }
1663 return done;
1664
1665 out_error:
Emeric Brun644cde02012-12-14 11:21:13 +01001666 /* Clear openssl global errors stack */
1667 ERR_clear_error();
1668
Emeric Brun46591952012-05-18 15:47:34 +02001669 conn->flags |= CO_FL_ERROR;
1670 return done;
1671}
1672
Emeric Brun46591952012-05-18 15:47:34 +02001673static void ssl_sock_close(struct connection *conn) {
1674
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02001675 if (conn->xprt_ctx) {
1676 SSL_free(conn->xprt_ctx);
1677 conn->xprt_ctx = NULL;
Willy Tarreau403edff2012-09-06 11:58:37 +02001678 sslconns--;
Emeric Brun46591952012-05-18 15:47:34 +02001679 }
Emeric Brun46591952012-05-18 15:47:34 +02001680}
1681
1682/* This function tries to perform a clean shutdown on an SSL connection, and in
1683 * any case, flags the connection as reusable if no handshake was in progress.
1684 */
1685static void ssl_sock_shutw(struct connection *conn, int clean)
1686{
1687 if (conn->flags & CO_FL_HANDSHAKE)
1688 return;
1689 /* no handshake was in progress, try a clean ssl shutdown */
Emeric Brun644cde02012-12-14 11:21:13 +01001690 if (clean && (SSL_shutdown(conn->xprt_ctx) <= 0)) {
1691 /* Clear openssl global errors stack */
1692 ERR_clear_error();
1693 }
Emeric Brun46591952012-05-18 15:47:34 +02001694
1695 /* force flag on ssl to keep session in cache regardless shutdown result */
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02001696 SSL_set_shutdown(conn->xprt_ctx, SSL_SENT_SHUTDOWN);
Emeric Brun46591952012-05-18 15:47:34 +02001697}
1698
Willy Tarreauffc3fcd2012-10-12 20:17:54 +02001699/* used for logging, may be changed for a sample fetch later */
1700const char *ssl_sock_get_cipher_name(struct connection *conn)
1701{
1702 if (!conn->xprt && !conn->xprt_ctx)
1703 return NULL;
1704 return SSL_get_cipher_name(conn->xprt_ctx);
1705}
1706
1707/* used for logging, may be changed for a sample fetch later */
1708const char *ssl_sock_get_proto_version(struct connection *conn)
1709{
1710 if (!conn->xprt && !conn->xprt_ctx)
1711 return NULL;
1712 return SSL_get_version(conn->xprt_ctx);
1713}
1714
Willy Tarreau8d598402012-10-22 17:58:39 +02001715/* Extract a serial from a cert, and copy it to a chunk.
1716 * Returns 1 if serial is found and copied, 0 if no serial found and
1717 * -1 if output is not large enough.
1718 */
1719static int
1720ssl_sock_get_serial(X509 *crt, struct chunk *out)
1721{
1722 ASN1_INTEGER *serial;
1723
1724 serial = X509_get_serialNumber(crt);
1725 if (!serial)
1726 return 0;
1727
1728 if (out->size < serial->length)
1729 return -1;
1730
1731 memcpy(out->str, serial->data, serial->length);
1732 out->len = serial->length;
1733 return 1;
1734}
1735
Emeric Brunce5ad802012-10-22 14:11:22 +02001736
1737/* Copy Date in ASN1_UTCTIME format in struct chunk out.
1738 * Returns 1 if serial is found and copied, 0 if no valid time found
1739 * and -1 if output is not large enough.
1740 */
1741static int
1742ssl_sock_get_time(ASN1_TIME *tm, struct chunk *out)
1743{
1744 if (tm->type == V_ASN1_GENERALIZEDTIME) {
1745 ASN1_GENERALIZEDTIME *gentm = (ASN1_GENERALIZEDTIME *)tm;
1746
1747 if (gentm->length < 12)
1748 return 0;
1749 if (gentm->data[0] != 0x32 || gentm->data[1] != 0x30)
1750 return 0;
1751 if (out->size < gentm->length-2)
1752 return -1;
1753
1754 memcpy(out->str, gentm->data+2, gentm->length-2);
1755 out->len = gentm->length-2;
1756 return 1;
1757 }
1758 else if (tm->type == V_ASN1_UTCTIME) {
1759 ASN1_UTCTIME *utctm = (ASN1_UTCTIME *)tm;
1760
1761 if (utctm->length < 10)
1762 return 0;
1763 if (utctm->data[0] >= 0x35)
1764 return 0;
1765 if (out->size < utctm->length)
1766 return -1;
1767
1768 memcpy(out->str, utctm->data, utctm->length);
1769 out->len = utctm->length;
1770 return 1;
1771 }
1772
1773 return 0;
1774}
1775
Emeric Brun87855892012-10-17 17:39:35 +02001776/* Extract an entry from a X509_NAME and copy its value to an output chunk.
1777 * Returns 1 if entry found, 0 if entry not found, or -1 if output not large enough.
1778 */
1779static int
1780ssl_sock_get_dn_entry(X509_NAME *a, const struct chunk *entry, int pos, struct chunk *out)
1781{
1782 X509_NAME_ENTRY *ne;
1783 int i, j, n;
1784 int cur = 0;
1785 const char *s;
1786 char tmp[128];
1787
1788 out->len = 0;
1789 for (i = 0; i < sk_X509_NAME_ENTRY_num(a->entries); i++) {
1790 if (pos < 0)
1791 j = (sk_X509_NAME_ENTRY_num(a->entries)-1) - i;
1792 else
1793 j = i;
1794
1795 ne = sk_X509_NAME_ENTRY_value(a->entries, j);
1796 n = OBJ_obj2nid(ne->object);
1797 if ((n == NID_undef) || ((s = OBJ_nid2sn(n)) == NULL)) {
1798 i2t_ASN1_OBJECT(tmp, sizeof(tmp), ne->object);
1799 s = tmp;
1800 }
1801
1802 if (chunk_strcasecmp(entry, s) != 0)
1803 continue;
1804
1805 if (pos < 0)
1806 cur--;
1807 else
1808 cur++;
1809
1810 if (cur != pos)
1811 continue;
1812
1813 if (ne->value->length > out->size)
1814 return -1;
1815
1816 memcpy(out->str, ne->value->data, ne->value->length);
1817 out->len = ne->value->length;
1818 return 1;
1819 }
1820
1821 return 0;
1822
1823}
1824
1825/* Extract and format full DN from a X509_NAME and copy result into a chunk
1826 * Returns 1 if dn entries exits, 0 if no dn entry found or -1 if output is not large enough.
1827 */
1828static int
1829ssl_sock_get_dn_oneline(X509_NAME *a, struct chunk *out)
1830{
1831 X509_NAME_ENTRY *ne;
1832 int i, n, ln;
1833 int l = 0;
1834 const char *s;
1835 char *p;
1836 char tmp[128];
1837
1838 out->len = 0;
1839 p = out->str;
1840 for (i = 0; i < sk_X509_NAME_ENTRY_num(a->entries); i++) {
1841 ne = sk_X509_NAME_ENTRY_value(a->entries, i);
1842 n = OBJ_obj2nid(ne->object);
1843 if ((n == NID_undef) || ((s = OBJ_nid2sn(n)) == NULL)) {
1844 i2t_ASN1_OBJECT(tmp, sizeof(tmp), ne->object);
1845 s = tmp;
1846 }
1847 ln = strlen(s);
1848
1849 l += 1 + ln + 1 + ne->value->length;
1850 if (l > out->size)
1851 return -1;
1852 out->len = l;
1853
1854 *(p++)='/';
1855 memcpy(p, s, ln);
1856 p += ln;
1857 *(p++)='=';
1858 memcpy(p, ne->value->data, ne->value->length);
1859 p += ne->value->length;
1860 }
1861
1862 if (!out->len)
1863 return 0;
1864
1865 return 1;
1866}
1867
Willy Tarreau7875d092012-09-10 08:20:03 +02001868/***** Below are some sample fetching functions for ACL/patterns *****/
1869
Emeric Brune64aef12012-09-21 13:15:06 +02001870/* boolean, returns true if client cert was present */
1871static int
Emeric Brun2525b6b2012-10-18 15:59:43 +02001872smp_fetch_ssl_fc_has_crt(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02001873 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brune64aef12012-09-21 13:15:06 +02001874{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02001875 struct connection *conn;
1876
1877 if (!l4)
1878 return 0;
1879
1880 conn = objt_conn(l4->si[0].end);
1881 if (!conn || conn->xprt != &ssl_sock)
Emeric Brune64aef12012-09-21 13:15:06 +02001882 return 0;
1883
Willy Tarreaub363a1f2013-10-01 10:45:07 +02001884 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brune64aef12012-09-21 13:15:06 +02001885 smp->flags |= SMP_F_MAY_CHANGE;
1886 return 0;
1887 }
1888
1889 smp->flags = 0;
1890 smp->type = SMP_T_BOOL;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02001891 smp->data.uint = SSL_SOCK_ST_FL_VERIFY_DONE & conn->xprt_st ? 1 : 0;
Emeric Brune64aef12012-09-21 13:15:06 +02001892
1893 return 1;
1894}
1895
Willy Tarreau8d598402012-10-22 17:58:39 +02001896/* bin, returns serial in a binary chunk */
1897static int
1898smp_fetch_ssl_c_serial(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02001899 const struct arg *args, struct sample *smp, const char *kw)
Willy Tarreau8d598402012-10-22 17:58:39 +02001900{
1901 X509 *crt = NULL;
1902 int ret = 0;
1903 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02001904 struct connection *conn;
1905
1906 if (!l4)
1907 return 0;
Willy Tarreau8d598402012-10-22 17:58:39 +02001908
Willy Tarreaub363a1f2013-10-01 10:45:07 +02001909 conn = objt_conn(l4->si[0].end);
1910 if (!conn || conn->xprt != &ssl_sock)
Willy Tarreau8d598402012-10-22 17:58:39 +02001911 return 0;
1912
Willy Tarreaub363a1f2013-10-01 10:45:07 +02001913 if (!(conn->flags & CO_FL_CONNECTED)) {
Willy Tarreau8d598402012-10-22 17:58:39 +02001914 smp->flags |= SMP_F_MAY_CHANGE;
1915 return 0;
1916 }
1917
1918 /* SSL_get_peer_certificate, it increase X509 * ref count */
Willy Tarreaub363a1f2013-10-01 10:45:07 +02001919 crt = SSL_get_peer_certificate(conn->xprt_ctx);
Willy Tarreau8d598402012-10-22 17:58:39 +02001920 if (!crt)
1921 goto out;
1922
Willy Tarreau47ca5452012-12-23 20:22:19 +01001923 smp_trash = get_trash_chunk();
Willy Tarreau8d598402012-10-22 17:58:39 +02001924 if (ssl_sock_get_serial(crt, smp_trash) <= 0)
1925 goto out;
1926
1927 smp->data.str = *smp_trash;
1928 smp->type = SMP_T_BIN;
1929 ret = 1;
1930out:
1931 if (crt)
1932 X509_free(crt);
1933 return ret;
1934}
Emeric Brune64aef12012-09-21 13:15:06 +02001935
James Votha051b4a2013-05-14 20:37:59 +02001936/* bin, returns the client certificate's SHA-1 fingerprint (SHA-1 hash of DER-encoded certificate) in a binary chunk */
1937static int
1938smp_fetch_ssl_c_sha1(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02001939 const struct arg *args, struct sample *smp, const char *kw)
James Votha051b4a2013-05-14 20:37:59 +02001940{
1941 X509 *crt = NULL;
1942 const EVP_MD *digest;
1943 int ret = 0;
1944 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02001945 struct connection *conn;
James Votha051b4a2013-05-14 20:37:59 +02001946
Willy Tarreaub363a1f2013-10-01 10:45:07 +02001947 if (!l4)
James Votha051b4a2013-05-14 20:37:59 +02001948 return 0;
1949
Willy Tarreaub363a1f2013-10-01 10:45:07 +02001950 conn = objt_conn(l4->si[0].end);
1951 if (!conn || conn->xprt != &ssl_sock)
1952 return 0;
1953
1954 if (!(conn->flags & CO_FL_CONNECTED)) {
James Votha051b4a2013-05-14 20:37:59 +02001955 smp->flags |= SMP_F_MAY_CHANGE;
1956 return 0;
1957 }
1958
1959 /* SSL_get_peer_certificate, it increase X509 * ref count */
Willy Tarreaub363a1f2013-10-01 10:45:07 +02001960 crt = SSL_get_peer_certificate(conn->xprt_ctx);
James Votha051b4a2013-05-14 20:37:59 +02001961 if (!crt)
1962 goto out;
1963
1964 smp_trash = get_trash_chunk();
1965 digest = EVP_sha1();
1966 X509_digest(crt, digest, (unsigned char *)smp_trash->str, (unsigned int *)&smp_trash->len);
1967
1968 smp->data.str = *smp_trash;
1969 smp->type = SMP_T_BIN;
1970 ret = 1;
1971out:
1972 if (crt)
1973 X509_free(crt);
1974 return ret;
1975}
1976
Emeric Brunce5ad802012-10-22 14:11:22 +02001977/*str, returns notafter date in ASN1_UTCTIME format */
1978static int
1979smp_fetch_ssl_c_notafter(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02001980 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brunce5ad802012-10-22 14:11:22 +02001981{
1982 X509 *crt = NULL;
1983 int ret = 0;
1984 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02001985 struct connection *conn;
Emeric Brunce5ad802012-10-22 14:11:22 +02001986
Willy Tarreaub363a1f2013-10-01 10:45:07 +02001987 if (!l4)
Emeric Brunce5ad802012-10-22 14:11:22 +02001988 return 0;
1989
Willy Tarreaub363a1f2013-10-01 10:45:07 +02001990 conn = objt_conn(l4->si[0].end);
1991 if (!conn || conn->xprt != &ssl_sock)
1992 return 0;
1993
1994 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunce5ad802012-10-22 14:11:22 +02001995 smp->flags |= SMP_F_MAY_CHANGE;
1996 return 0;
1997 }
1998
1999 /* SSL_get_peer_certificate, it increase X509 * ref count */
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002000 crt = SSL_get_peer_certificate(conn->xprt_ctx);
Emeric Brunce5ad802012-10-22 14:11:22 +02002001 if (!crt)
2002 goto out;
2003
Willy Tarreau47ca5452012-12-23 20:22:19 +01002004 smp_trash = get_trash_chunk();
Emeric Brunce5ad802012-10-22 14:11:22 +02002005 if (ssl_sock_get_time(X509_get_notAfter(crt), smp_trash) <= 0)
2006 goto out;
2007
2008 smp->data.str = *smp_trash;
2009 smp->type = SMP_T_STR;
2010 ret = 1;
2011out:
2012 if (crt)
2013 X509_free(crt);
2014 return ret;
2015}
2016
Emeric Brun87855892012-10-17 17:39:35 +02002017/* str, returns a string of a formatted full dn \C=..\O=..\OU=.. \CN=.. */
2018static int
2019smp_fetch_ssl_c_i_dn(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002020 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brun87855892012-10-17 17:39:35 +02002021{
2022 X509 *crt = NULL;
2023 X509_NAME *name;
2024 int ret = 0;
2025 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002026 struct connection *conn;
Emeric Brun87855892012-10-17 17:39:35 +02002027
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002028 if (!l4)
Emeric Brun87855892012-10-17 17:39:35 +02002029 return 0;
2030
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002031 conn = objt_conn(l4->si[0].end);
2032 if (!conn || conn->xprt != &ssl_sock)
2033 return 0;
2034
2035 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun87855892012-10-17 17:39:35 +02002036 smp->flags |= SMP_F_MAY_CHANGE;
2037 return 0;
2038 }
2039
2040 /* SSL_get_peer_certificate, it increase X509 * ref count */
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002041 crt = SSL_get_peer_certificate(conn->xprt_ctx);
Emeric Brun87855892012-10-17 17:39:35 +02002042 if (!crt)
2043 goto out;
2044
2045 name = X509_get_issuer_name(crt);
2046 if (!name)
2047 goto out;
2048
Willy Tarreau47ca5452012-12-23 20:22:19 +01002049 smp_trash = get_trash_chunk();
Emeric Brun87855892012-10-17 17:39:35 +02002050 if (args && args[0].type == ARGT_STR) {
2051 int pos = 1;
2052
2053 if (args[1].type == ARGT_SINT)
2054 pos = args[1].data.sint;
2055 else if (args[1].type == ARGT_UINT)
2056 pos =(int)args[1].data.uint;
2057
2058 if (ssl_sock_get_dn_entry(name, &args[0].data.str, pos, smp_trash) <= 0)
2059 goto out;
2060 }
2061 else if (ssl_sock_get_dn_oneline(name, smp_trash) <= 0)
2062 goto out;
2063
2064 smp->type = SMP_T_STR;
2065 smp->data.str = *smp_trash;
2066 ret = 1;
2067out:
2068 if (crt)
2069 X509_free(crt);
2070 return ret;
2071}
2072
Emeric Brunce5ad802012-10-22 14:11:22 +02002073/*str, returns notbefore date in ASN1_UTCTIME format */
2074static int
2075smp_fetch_ssl_c_notbefore(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002076 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brunce5ad802012-10-22 14:11:22 +02002077{
2078 X509 *crt = NULL;
2079 int ret = 0;
2080 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002081 struct connection *conn;
2082
2083 if (!l4)
2084 return 0;
Emeric Brunce5ad802012-10-22 14:11:22 +02002085
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002086 conn = objt_conn(l4->si[0].end);
2087 if (!conn || conn->xprt != &ssl_sock)
Emeric Brunce5ad802012-10-22 14:11:22 +02002088 return 0;
2089
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002090 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunce5ad802012-10-22 14:11:22 +02002091 smp->flags |= SMP_F_MAY_CHANGE;
2092 return 0;
2093 }
2094
2095 /* SSL_get_peer_certificate, it increase X509 * ref count */
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002096 crt = SSL_get_peer_certificate(conn->xprt_ctx);
Emeric Brunce5ad802012-10-22 14:11:22 +02002097 if (!crt)
2098 goto out;
2099
Willy Tarreau47ca5452012-12-23 20:22:19 +01002100 smp_trash = get_trash_chunk();
Emeric Brunce5ad802012-10-22 14:11:22 +02002101 if (ssl_sock_get_time(X509_get_notBefore(crt), smp_trash) <= 0)
2102 goto out;
2103
2104 smp->data.str = *smp_trash;
2105 smp->type = SMP_T_STR;
2106 ret = 1;
2107out:
2108 if (crt)
2109 X509_free(crt);
2110 return ret;
2111}
2112
Emeric Brun87855892012-10-17 17:39:35 +02002113/* str, returns a string of a formatted full dn \C=..\O=..\OU=.. \CN=.. */
2114static int
2115smp_fetch_ssl_c_s_dn(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002116 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brun87855892012-10-17 17:39:35 +02002117{
2118 X509 *crt = NULL;
2119 X509_NAME *name;
2120 int ret = 0;
2121 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002122 struct connection *conn;
Emeric Brun87855892012-10-17 17:39:35 +02002123
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002124 if (!l4)
Emeric Brun87855892012-10-17 17:39:35 +02002125 return 0;
2126
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002127 conn = objt_conn(l4->si[0].end);
2128 if (!conn || conn->xprt != &ssl_sock)
2129 return 0;
2130
2131 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun87855892012-10-17 17:39:35 +02002132 smp->flags |= SMP_F_MAY_CHANGE;
2133 return 0;
2134 }
2135
2136 /* SSL_get_peer_certificate, it increase X509 * ref count */
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002137 crt = SSL_get_peer_certificate(conn->xprt_ctx);
Emeric Brun87855892012-10-17 17:39:35 +02002138 if (!crt)
2139 goto out;
2140
2141 name = X509_get_subject_name(crt);
2142 if (!name)
2143 goto out;
2144
Willy Tarreau47ca5452012-12-23 20:22:19 +01002145 smp_trash = get_trash_chunk();
Emeric Brun87855892012-10-17 17:39:35 +02002146 if (args && args[0].type == ARGT_STR) {
2147 int pos = 1;
2148
2149 if (args[1].type == ARGT_SINT)
2150 pos = args[1].data.sint;
2151 else if (args[1].type == ARGT_UINT)
2152 pos =(int)args[1].data.uint;
2153
2154 if (ssl_sock_get_dn_entry(name, &args[0].data.str, pos, smp_trash) <= 0)
2155 goto out;
2156 }
2157 else if (ssl_sock_get_dn_oneline(name, smp_trash) <= 0)
2158 goto out;
2159
2160 smp->type = SMP_T_STR;
2161 smp->data.str = *smp_trash;
2162 ret = 1;
2163out:
2164 if (crt)
2165 X509_free(crt);
2166 return ret;
2167}
Emeric Brun9143d372012-12-20 15:44:16 +01002168
2169/* integer, returns true if current session use a client certificate */
2170static int
2171smp_fetch_ssl_c_used(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002172 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brun9143d372012-12-20 15:44:16 +01002173{
2174 X509 *crt;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002175 struct connection *conn;
Emeric Brun9143d372012-12-20 15:44:16 +01002176
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002177 if (!l4)
Emeric Brun9143d372012-12-20 15:44:16 +01002178 return 0;
2179
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002180 conn = objt_conn(l4->si[0].end);
2181 if (!conn || conn->xprt != &ssl_sock)
2182 return 0;
2183
2184 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun9143d372012-12-20 15:44:16 +01002185 smp->flags |= SMP_F_MAY_CHANGE;
2186 return 0;
2187 }
2188
2189 /* SSL_get_peer_certificate returns a ptr on allocated X509 struct */
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002190 crt = SSL_get_peer_certificate(conn->xprt_ctx);
Emeric Brun9143d372012-12-20 15:44:16 +01002191 if (crt) {
2192 X509_free(crt);
2193 }
2194
2195 smp->type = SMP_T_BOOL;
2196 smp->data.uint = (crt != NULL);
2197 return 1;
2198}
2199
Emeric Bruna7359fd2012-10-17 15:03:11 +02002200/* integer, returns the client certificate version */
2201static int
2202smp_fetch_ssl_c_version(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002203 const struct arg *args, struct sample *smp, const char *kw)
Emeric Bruna7359fd2012-10-17 15:03:11 +02002204{
2205 X509 *crt;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002206 struct connection *conn;
2207
2208 if (!l4)
2209 return 0;
Emeric Bruna7359fd2012-10-17 15:03:11 +02002210
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002211 conn = objt_conn(l4->si[0].end);
2212 if (!conn || conn->xprt != &ssl_sock)
Emeric Bruna7359fd2012-10-17 15:03:11 +02002213 return 0;
2214
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002215 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Bruna7359fd2012-10-17 15:03:11 +02002216 smp->flags |= SMP_F_MAY_CHANGE;
2217 return 0;
2218 }
2219
2220 /* SSL_get_peer_certificate returns a ptr on allocated X509 struct */
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002221 crt = SSL_get_peer_certificate(conn->xprt_ctx);
Emeric Bruna7359fd2012-10-17 15:03:11 +02002222 if (!crt)
2223 return 0;
2224
2225 smp->data.uint = (unsigned int)(1 + X509_get_version(crt));
2226 X509_free(crt);
2227 smp->type = SMP_T_UINT;
2228
2229 return 1;
2230}
2231
Emeric Brun7f56e742012-10-19 18:15:40 +02002232/* str, returns the client certificate sig alg */
2233static int
2234smp_fetch_ssl_c_sig_alg(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002235 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brun7f56e742012-10-19 18:15:40 +02002236{
2237 X509 *crt;
2238 int nid;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002239 struct connection *conn;
Emeric Brun7f56e742012-10-19 18:15:40 +02002240
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002241 if (!l4)
Emeric Brun7f56e742012-10-19 18:15:40 +02002242 return 0;
2243
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002244 conn = objt_conn(l4->si[0].end);
2245 if (!conn || conn->xprt != &ssl_sock)
2246 return 0;
2247
2248 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun7f56e742012-10-19 18:15:40 +02002249 smp->flags |= SMP_F_MAY_CHANGE;
2250 return 0;
2251 }
2252
2253 /* SSL_get_peer_certificate increase X509 * ref count */
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002254 crt = SSL_get_peer_certificate(conn->xprt_ctx);
Emeric Brun7f56e742012-10-19 18:15:40 +02002255 if (!crt)
2256 return 0;
2257
2258 nid = OBJ_obj2nid((ASN1_OBJECT *)(crt->cert_info->signature->algorithm));
2259
2260 smp->data.str.str = (char *)OBJ_nid2sn(nid);
Emeric Brun9bf3ba22013-10-07 14:31:44 +02002261 if (!smp->data.str.str) {
2262 X509_free(crt);
Emeric Brun7f56e742012-10-19 18:15:40 +02002263 return 0;
Emeric Brun9bf3ba22013-10-07 14:31:44 +02002264 }
Emeric Brun7f56e742012-10-19 18:15:40 +02002265
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01002266 smp->type = SMP_T_STR;
2267 smp->flags |= SMP_F_CONST;
Emeric Brun7f56e742012-10-19 18:15:40 +02002268 smp->data.str.len = strlen(smp->data.str.str);
2269 X509_free(crt);
2270
2271 return 1;
2272}
2273
Emeric Brun521a0112012-10-22 12:22:55 +02002274/* str, returns the client certificate key alg */
2275static int
2276smp_fetch_ssl_c_key_alg(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002277 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brun521a0112012-10-22 12:22:55 +02002278{
2279 X509 *crt;
2280 int nid;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002281 struct connection *conn;
Emeric Brun521a0112012-10-22 12:22:55 +02002282
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002283 if (!l4)
Emeric Brun521a0112012-10-22 12:22:55 +02002284 return 0;
2285
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002286 conn = objt_conn(l4->si[0].end);
2287 if (!conn || conn->xprt != &ssl_sock)
2288 return 0;
2289
2290 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun521a0112012-10-22 12:22:55 +02002291 smp->flags |= SMP_F_MAY_CHANGE;
2292 return 0;
2293 }
2294
2295 /* SSL_get_peer_certificate increase X509 * ref count */
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002296 crt = SSL_get_peer_certificate(conn->xprt_ctx);
Emeric Brun521a0112012-10-22 12:22:55 +02002297 if (!crt)
2298 return 0;
2299
2300 nid = OBJ_obj2nid((ASN1_OBJECT *)(crt->cert_info->key->algor->algorithm));
2301
2302 smp->data.str.str = (char *)OBJ_nid2sn(nid);
Emeric Brun9bf3ba22013-10-07 14:31:44 +02002303 if (!smp->data.str.str) {
2304 X509_free(crt);
Emeric Brun521a0112012-10-22 12:22:55 +02002305 return 0;
Emeric Brun9bf3ba22013-10-07 14:31:44 +02002306 }
Emeric Brun521a0112012-10-22 12:22:55 +02002307
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01002308 smp->type = SMP_T_STR;
2309 smp->flags |= SMP_F_CONST;
Emeric Brun521a0112012-10-22 12:22:55 +02002310 smp->data.str.len = strlen(smp->data.str.str);
2311 X509_free(crt);
2312
2313 return 1;
2314}
2315
Emeric Brun2525b6b2012-10-18 15:59:43 +02002316/* boolean, returns true if front conn. transport layer is SSL */
Willy Tarreau7875d092012-09-10 08:20:03 +02002317static int
Emeric Brun2525b6b2012-10-18 15:59:43 +02002318smp_fetch_ssl_fc(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002319 const struct arg *args, struct sample *smp, const char *kw)
Willy Tarreau7875d092012-09-10 08:20:03 +02002320{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002321 struct connection *conn = objt_conn(l4->si[0].end);
2322
Willy Tarreau7875d092012-09-10 08:20:03 +02002323 smp->type = SMP_T_BOOL;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002324 smp->data.uint = (conn && conn->xprt == &ssl_sock);
Willy Tarreau7875d092012-09-10 08:20:03 +02002325 return 1;
2326}
2327
Emeric Brun2525b6b2012-10-18 15:59:43 +02002328/* boolean, returns true if client present a SNI */
Willy Tarreau7875d092012-09-10 08:20:03 +02002329static int
Emeric Brun2525b6b2012-10-18 15:59:43 +02002330smp_fetch_ssl_fc_has_sni(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002331 const struct arg *args, struct sample *smp, const char *kw)
Willy Tarreau7875d092012-09-10 08:20:03 +02002332{
2333#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002334 struct connection *conn = objt_conn(l4->si[0].end);
2335
Willy Tarreau7875d092012-09-10 08:20:03 +02002336 smp->type = SMP_T_BOOL;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002337 smp->data.uint = (conn && conn->xprt == &ssl_sock) &&
2338 conn->xprt_ctx &&
2339 SSL_get_servername(conn->xprt_ctx, TLSEXT_NAMETYPE_host_name) != NULL;
Willy Tarreau7875d092012-09-10 08:20:03 +02002340 return 1;
2341#else
2342 return 0;
2343#endif
2344}
2345
Willy Tarreau8d598402012-10-22 17:58:39 +02002346/* bin, returns serial in a binary chunk */
2347static int
2348smp_fetch_ssl_f_serial(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002349 const struct arg *args, struct sample *smp, const char *kw)
Willy Tarreau8d598402012-10-22 17:58:39 +02002350{
2351 X509 *crt = NULL;
2352 int ret = 0;
2353 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002354 struct connection *conn;
2355
2356 if (!l4)
2357 return 0;
Willy Tarreau8d598402012-10-22 17:58:39 +02002358
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002359 conn = objt_conn(l4->si[0].end);
2360 if (!conn || conn->xprt != &ssl_sock)
Willy Tarreau8d598402012-10-22 17:58:39 +02002361 return 0;
2362
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002363 if (!(conn->flags & CO_FL_CONNECTED)) {
Willy Tarreau8d598402012-10-22 17:58:39 +02002364 smp->flags |= SMP_F_MAY_CHANGE;
2365 return 0;
2366 }
2367
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002368 crt = SSL_get_certificate(conn->xprt_ctx);
Willy Tarreau8d598402012-10-22 17:58:39 +02002369 if (!crt)
2370 goto out;
2371
Willy Tarreau47ca5452012-12-23 20:22:19 +01002372 smp_trash = get_trash_chunk();
Willy Tarreau8d598402012-10-22 17:58:39 +02002373 if (ssl_sock_get_serial(crt, smp_trash) <= 0)
2374 goto out;
2375
2376 smp->data.str = *smp_trash;
2377 smp->type = SMP_T_BIN;
2378 ret = 1;
2379out:
2380 return ret;
2381}
Emeric Brunce5ad802012-10-22 14:11:22 +02002382/*str, returns notafter date in ASN1_UTCTIME format */
2383static int
2384smp_fetch_ssl_f_notafter(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002385 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brunce5ad802012-10-22 14:11:22 +02002386{
2387 X509 *crt = NULL;
2388 int ret = 0;
2389 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002390 struct connection *conn;
Emeric Brunce5ad802012-10-22 14:11:22 +02002391
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002392 if (!l4)
Emeric Brunce5ad802012-10-22 14:11:22 +02002393 return 0;
2394
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002395 conn = objt_conn(l4->si[0].end);
2396 if (!conn || conn->xprt != &ssl_sock)
2397 return 0;
2398
2399 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunce5ad802012-10-22 14:11:22 +02002400 smp->flags |= SMP_F_MAY_CHANGE;
2401 return 0;
2402 }
2403
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002404 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brunce5ad802012-10-22 14:11:22 +02002405 if (!crt)
2406 goto out;
2407
Willy Tarreau47ca5452012-12-23 20:22:19 +01002408 smp_trash = get_trash_chunk();
Emeric Brunce5ad802012-10-22 14:11:22 +02002409 if (ssl_sock_get_time(X509_get_notAfter(crt), smp_trash) <= 0)
2410 goto out;
2411
2412 smp->data.str = *smp_trash;
2413 smp->type = SMP_T_STR;
2414 ret = 1;
2415out:
2416 return ret;
2417}
2418
2419/*str, returns notbefore date in ASN1_UTCTIME format */
2420static int
2421smp_fetch_ssl_f_notbefore(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002422 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brunce5ad802012-10-22 14:11:22 +02002423{
2424 X509 *crt = NULL;
2425 int ret = 0;
2426 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002427 struct connection *conn;
Emeric Brunce5ad802012-10-22 14:11:22 +02002428
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002429 if (!l4)
Emeric Brunce5ad802012-10-22 14:11:22 +02002430 return 0;
2431
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002432 conn = objt_conn(l4->si[0].end);
2433 if (!conn || conn->xprt != &ssl_sock)
2434 return 0;
2435
2436 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunce5ad802012-10-22 14:11:22 +02002437 smp->flags |= SMP_F_MAY_CHANGE;
2438 return 0;
2439 }
2440
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002441 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brunce5ad802012-10-22 14:11:22 +02002442 if (!crt)
2443 goto out;
2444
Willy Tarreau47ca5452012-12-23 20:22:19 +01002445 smp_trash = get_trash_chunk();
Emeric Brunce5ad802012-10-22 14:11:22 +02002446 if (ssl_sock_get_time(X509_get_notBefore(crt), smp_trash) <= 0)
2447 goto out;
2448
2449 smp->data.str = *smp_trash;
2450 smp->type = SMP_T_STR;
2451 ret = 1;
2452out:
2453 return ret;
2454}
Willy Tarreau8d598402012-10-22 17:58:39 +02002455
Emeric Bruna7359fd2012-10-17 15:03:11 +02002456/* integer, returns the frontend certificate version */
2457static int
2458smp_fetch_ssl_f_version(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002459 const struct arg *args, struct sample *smp, const char *kw)
Emeric Bruna7359fd2012-10-17 15:03:11 +02002460{
2461 X509 *crt;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002462 struct connection *conn;
Emeric Bruna7359fd2012-10-17 15:03:11 +02002463
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002464 if (!l4)
Emeric Bruna7359fd2012-10-17 15:03:11 +02002465 return 0;
2466
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002467 conn = objt_conn(l4->si[0].end);
2468 if (!conn || conn->xprt != &ssl_sock)
2469 return 0;
2470
2471 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Bruna7359fd2012-10-17 15:03:11 +02002472 smp->flags |= SMP_F_MAY_CHANGE;
2473 return 0;
2474 }
2475
2476 /* SSL_get_certificate returns a ptr on an SSL * internal sub struct */
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002477 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Bruna7359fd2012-10-17 15:03:11 +02002478 if (!crt)
2479 return 0;
2480
2481 smp->data.uint = (unsigned int)(1 + X509_get_version(crt));
2482 smp->type = SMP_T_UINT;
2483
2484 return 1;
2485}
2486
Emeric Brun7f56e742012-10-19 18:15:40 +02002487/* str, returns the client certificate sig alg */
2488static int
2489smp_fetch_ssl_f_sig_alg(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002490 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brun7f56e742012-10-19 18:15:40 +02002491{
2492 X509 *crt;
2493 int nid;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002494 struct connection *conn;
Emeric Brun7f56e742012-10-19 18:15:40 +02002495
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002496 if (!l4)
Emeric Brun7f56e742012-10-19 18:15:40 +02002497 return 0;
2498
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002499 conn = objt_conn(l4->si[0].end);
2500 if (!conn || conn->xprt != &ssl_sock)
2501 return 0;
2502
2503 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun7f56e742012-10-19 18:15:40 +02002504 smp->flags |= SMP_F_MAY_CHANGE;
2505 return 0;
2506 }
2507
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002508 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brun7f56e742012-10-19 18:15:40 +02002509 if (!crt)
2510 return 0;
2511
2512 nid = OBJ_obj2nid((ASN1_OBJECT *)(crt->cert_info->signature->algorithm));
2513
2514 smp->data.str.str = (char *)OBJ_nid2sn(nid);
2515 if (!smp->data.str.str)
2516 return 0;
2517
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01002518 smp->type = SMP_T_STR;
2519 smp->flags |= SMP_F_CONST;
Emeric Brun7f56e742012-10-19 18:15:40 +02002520 smp->data.str.len = strlen(smp->data.str.str);
2521
2522 return 1;
2523}
2524
Emeric Brun521a0112012-10-22 12:22:55 +02002525/* str, returns the client certificate key alg */
2526static int
2527smp_fetch_ssl_f_key_alg(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002528 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brun521a0112012-10-22 12:22:55 +02002529{
2530 X509 *crt;
2531 int nid;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002532 struct connection *conn;
2533
2534 if (!l4)
2535 return 0;
Emeric Brun521a0112012-10-22 12:22:55 +02002536
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002537 conn = objt_conn(l4->si[0].end);
2538 if (!conn || conn->xprt != &ssl_sock)
Emeric Brun521a0112012-10-22 12:22:55 +02002539 return 0;
2540
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002541 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun521a0112012-10-22 12:22:55 +02002542 smp->flags |= SMP_F_MAY_CHANGE;
2543 return 0;
2544 }
2545
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002546 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brun521a0112012-10-22 12:22:55 +02002547 if (!crt)
2548 return 0;
2549
2550 nid = OBJ_obj2nid((ASN1_OBJECT *)(crt->cert_info->key->algor->algorithm));
2551
2552 smp->data.str.str = (char *)OBJ_nid2sn(nid);
2553 if (!smp->data.str.str)
2554 return 0;
2555
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01002556 smp->type = SMP_T_STR;
2557 smp->flags |= SMP_F_CONST;
Emeric Brun521a0112012-10-22 12:22:55 +02002558 smp->data.str.len = strlen(smp->data.str.str);
2559
2560 return 1;
2561}
2562
Emeric Brun87855892012-10-17 17:39:35 +02002563/* str, returns a string of a formatted full dn \C=..\O=..\OU=.. \CN=.. */
2564static int
2565smp_fetch_ssl_f_i_dn(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002566 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brun87855892012-10-17 17:39:35 +02002567{
2568 X509 *crt = NULL;
2569 X509_NAME *name;
2570 int ret = 0;
2571 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002572 struct connection *conn;
2573
2574 if (!l4)
2575 return 0;
Emeric Brun87855892012-10-17 17:39:35 +02002576
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002577 conn = objt_conn(l4->si[0].end);
2578 if (!conn || conn->xprt != &ssl_sock)
Emeric Brun87855892012-10-17 17:39:35 +02002579 return 0;
2580
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002581 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun87855892012-10-17 17:39:35 +02002582 smp->flags |= SMP_F_MAY_CHANGE;
2583 return 0;
2584 }
2585
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002586 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brun87855892012-10-17 17:39:35 +02002587 if (!crt)
2588 goto out;
2589
2590 name = X509_get_issuer_name(crt);
2591 if (!name)
2592 goto out;
2593
Willy Tarreau47ca5452012-12-23 20:22:19 +01002594 smp_trash = get_trash_chunk();
Emeric Brun87855892012-10-17 17:39:35 +02002595 if (args && args[0].type == ARGT_STR) {
2596 int pos = 1;
2597
2598 if (args[1].type == ARGT_SINT)
2599 pos = args[1].data.sint;
2600 else if (args[1].type == ARGT_UINT)
2601 pos =(int)args[1].data.uint;
2602
2603 if (ssl_sock_get_dn_entry(name, &args[0].data.str, pos, smp_trash) <= 0)
2604 goto out;
2605 }
2606 else if (ssl_sock_get_dn_oneline(name, smp_trash) <= 0)
2607 goto out;
2608
2609 smp->type = SMP_T_STR;
2610 smp->data.str = *smp_trash;
2611 ret = 1;
2612out:
2613 return ret;
2614}
2615
2616/* str, returns a string of a formatted full dn \C=..\O=..\OU=.. \CN=.. */
2617static int
2618smp_fetch_ssl_f_s_dn(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002619 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brun87855892012-10-17 17:39:35 +02002620{
2621 X509 *crt = NULL;
2622 X509_NAME *name;
2623 int ret = 0;
2624 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002625 struct connection *conn;
2626
2627 if (!l4)
2628 return 0;
Emeric Brun87855892012-10-17 17:39:35 +02002629
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002630 conn = objt_conn(l4->si[0].end);
2631 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
Emeric Brun87855892012-10-17 17:39:35 +02002632 return 0;
2633
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002634 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun87855892012-10-17 17:39:35 +02002635 smp->flags |= SMP_F_MAY_CHANGE;
2636 return 0;
2637 }
2638
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002639 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brun87855892012-10-17 17:39:35 +02002640 if (!crt)
2641 goto out;
2642
2643 name = X509_get_subject_name(crt);
2644 if (!name)
2645 goto out;
2646
Willy Tarreau47ca5452012-12-23 20:22:19 +01002647 smp_trash = get_trash_chunk();
Emeric Brun87855892012-10-17 17:39:35 +02002648 if (args && args[0].type == ARGT_STR) {
2649 int pos = 1;
2650
2651 if (args[1].type == ARGT_SINT)
2652 pos = args[1].data.sint;
2653 else if (args[1].type == ARGT_UINT)
2654 pos =(int)args[1].data.uint;
2655
2656 if (ssl_sock_get_dn_entry(name, &args[0].data.str, pos, smp_trash) <= 0)
2657 goto out;
2658 }
2659 else if (ssl_sock_get_dn_oneline(name, smp_trash) <= 0)
2660 goto out;
2661
2662 smp->type = SMP_T_STR;
2663 smp->data.str = *smp_trash;
2664 ret = 1;
2665out:
2666 return ret;
2667}
2668
Emeric Brun589fcad2012-10-16 14:13:26 +02002669static int
2670smp_fetch_ssl_fc_cipher(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002671 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brun589fcad2012-10-16 14:13:26 +02002672{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002673 struct connection *conn;
2674
Emeric Brun589fcad2012-10-16 14:13:26 +02002675 smp->flags = 0;
2676
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002677 if (!l4)
2678 return 0;
2679
2680 conn = objt_conn(l4->si[0].end);
2681 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
Emeric Brun589fcad2012-10-16 14:13:26 +02002682 return 0;
2683
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002684 smp->data.str.str = (char *)SSL_get_cipher_name(conn->xprt_ctx);
Emeric Brun589fcad2012-10-16 14:13:26 +02002685 if (!smp->data.str.str)
2686 return 0;
2687
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01002688 smp->type = SMP_T_STR;
2689 smp->flags |= SMP_F_CONST;
Emeric Brun589fcad2012-10-16 14:13:26 +02002690 smp->data.str.len = strlen(smp->data.str.str);
2691
2692 return 1;
2693}
2694
2695static int
2696smp_fetch_ssl_fc_alg_keysize(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002697 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brun589fcad2012-10-16 14:13:26 +02002698{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002699 struct connection *conn;
2700
Emeric Brun589fcad2012-10-16 14:13:26 +02002701 smp->flags = 0;
2702
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002703 if (!l4)
Emeric Brun589fcad2012-10-16 14:13:26 +02002704 return 0;
2705
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002706 conn = objt_conn(l4->si[0].end);
2707 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
Emeric Brun589fcad2012-10-16 14:13:26 +02002708 return 0;
2709
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002710 if (!SSL_get_cipher_bits(conn->xprt_ctx, (int *)&smp->data.uint))
2711 return 0;
2712
Emeric Brun589fcad2012-10-16 14:13:26 +02002713 smp->type = SMP_T_UINT;
2714
2715 return 1;
2716}
2717
2718static int
2719smp_fetch_ssl_fc_use_keysize(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002720 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brun589fcad2012-10-16 14:13:26 +02002721{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002722 struct connection *conn;
2723
Emeric Brun589fcad2012-10-16 14:13:26 +02002724 smp->flags = 0;
2725
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002726 if (!l4)
Emeric Brun589fcad2012-10-16 14:13:26 +02002727 return 0;
2728
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002729 conn = objt_conn(l4->si[0].end);
2730 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
2731 return 0;
2732
2733 smp->data.uint = (unsigned int)SSL_get_cipher_bits(conn->xprt_ctx, NULL);
Emeric Brun589fcad2012-10-16 14:13:26 +02002734 if (!smp->data.uint)
2735 return 0;
2736
2737 smp->type = SMP_T_UINT;
2738
2739 return 1;
2740}
2741
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02002742#ifdef OPENSSL_NPN_NEGOTIATED
Willy Tarreau7875d092012-09-10 08:20:03 +02002743static int
Emeric Brun2525b6b2012-10-18 15:59:43 +02002744smp_fetch_ssl_fc_npn(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002745 const struct arg *args, struct sample *smp, const char *kw)
Willy Tarreaua33c6542012-10-15 13:19:06 +02002746{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002747 struct connection *conn;
2748
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01002749 smp->flags = SMP_F_CONST;
2750 smp->type = SMP_T_STR;
Willy Tarreaua33c6542012-10-15 13:19:06 +02002751
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002752 if (!l4)
Willy Tarreaua33c6542012-10-15 13:19:06 +02002753 return 0;
2754
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002755 conn = objt_conn(l4->si[0].end);
2756 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
2757 return 0;
2758
Willy Tarreaua33c6542012-10-15 13:19:06 +02002759 smp->data.str.str = NULL;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002760 SSL_get0_next_proto_negotiated(conn->xprt_ctx,
Willy Tarreaua33c6542012-10-15 13:19:06 +02002761 (const unsigned char **)&smp->data.str.str, (unsigned *)&smp->data.str.len);
2762
2763 if (!smp->data.str.str)
2764 return 0;
2765
2766 return 1;
Willy Tarreaua33c6542012-10-15 13:19:06 +02002767}
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02002768#endif
Willy Tarreaua33c6542012-10-15 13:19:06 +02002769
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01002770#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Willy Tarreauab861d32013-04-02 02:30:41 +02002771static int
2772smp_fetch_ssl_fc_alpn(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002773 const struct arg *args, struct sample *smp, const char *kw)
Willy Tarreauab861d32013-04-02 02:30:41 +02002774{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002775 struct connection *conn;
2776
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01002777 smp->flags = SMP_F_CONST;
2778 smp->type = SMP_T_STR;
Willy Tarreauab861d32013-04-02 02:30:41 +02002779
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002780 if (!l4)
2781 return 0;
2782
2783 conn = objt_conn(l4->si[0].end);
2784 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
Willy Tarreauab861d32013-04-02 02:30:41 +02002785 return 0;
2786
2787 smp->data.str.str = NULL;
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01002788 SSL_get0_alpn_selected(conn->xprt_ctx,
Willy Tarreauab861d32013-04-02 02:30:41 +02002789 (const unsigned char **)&smp->data.str.str, (unsigned *)&smp->data.str.len);
2790
2791 if (!smp->data.str.str)
2792 return 0;
2793
2794 return 1;
2795}
2796#endif
2797
Willy Tarreaua33c6542012-10-15 13:19:06 +02002798static int
Emeric Brun589fcad2012-10-16 14:13:26 +02002799smp_fetch_ssl_fc_protocol(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002800 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brun589fcad2012-10-16 14:13:26 +02002801{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002802 struct connection *conn;
2803
Emeric Brun589fcad2012-10-16 14:13:26 +02002804 smp->flags = 0;
2805
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002806 if (!l4)
Emeric Brun589fcad2012-10-16 14:13:26 +02002807 return 0;
2808
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002809 conn = objt_conn(l4->si[0].end);
2810 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
2811 return 0;
2812
2813 smp->data.str.str = (char *)SSL_get_version(conn->xprt_ctx);
Emeric Brun589fcad2012-10-16 14:13:26 +02002814 if (!smp->data.str.str)
2815 return 0;
2816
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01002817 smp->type = SMP_T_STR;
2818 smp->flags = SMP_F_CONST;
Emeric Brun589fcad2012-10-16 14:13:26 +02002819 smp->data.str.len = strlen(smp->data.str.str);
2820
2821 return 1;
2822}
2823
2824static int
Emeric Brunfe68f682012-10-16 14:59:28 +02002825smp_fetch_ssl_fc_session_id(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002826 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brunfe68f682012-10-16 14:59:28 +02002827{
2828#if OPENSSL_VERSION_NUMBER > 0x0090800fL
2829 SSL_SESSION *sess;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002830 struct connection *conn;
Emeric Brunfe68f682012-10-16 14:59:28 +02002831
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01002832 smp->flags = SMP_F_CONST;
2833 smp->type = SMP_T_BIN;
Emeric Brunfe68f682012-10-16 14:59:28 +02002834
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002835 if (!l4)
Emeric Brunfe68f682012-10-16 14:59:28 +02002836 return 0;
2837
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002838 conn = objt_conn(l4->si[0].end);
2839 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
2840 return 0;
2841
2842 sess = SSL_get_session(conn->xprt_ctx);
Emeric Brunfe68f682012-10-16 14:59:28 +02002843 if (!sess)
2844 return 0;
2845
2846 smp->data.str.str = (char *)SSL_SESSION_get_id(sess, (unsigned int *)&smp->data.str.len);
2847 if (!smp->data.str.str || !&smp->data.str.len)
2848 return 0;
2849
2850 return 1;
2851#else
2852 return 0;
2853#endif
2854}
2855
2856static int
Emeric Brun2525b6b2012-10-18 15:59:43 +02002857smp_fetch_ssl_fc_sni(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002858 const struct arg *args, struct sample *smp, const char *kw)
Willy Tarreau7875d092012-09-10 08:20:03 +02002859{
2860#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002861 struct connection *conn;
2862
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01002863 smp->flags = SMP_F_CONST;
2864 smp->type = SMP_T_STR;
Willy Tarreau7875d092012-09-10 08:20:03 +02002865
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002866 if (!l4)
Willy Tarreau7875d092012-09-10 08:20:03 +02002867 return 0;
2868
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002869 conn = objt_conn(l4->si[0].end);
2870 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
2871 return 0;
2872
2873 smp->data.str.str = (char *)SSL_get_servername(conn->xprt_ctx, TLSEXT_NAMETYPE_host_name);
Willy Tarreau3e394c92012-09-14 23:56:58 +02002874 if (!smp->data.str.str)
2875 return 0;
2876
Willy Tarreau7875d092012-09-10 08:20:03 +02002877 smp->data.str.len = strlen(smp->data.str.str);
2878 return 1;
2879#else
2880 return 0;
2881#endif
2882}
2883
David Sc1ad52e2014-04-08 18:48:47 -04002884static int
2885smp_fetch_ssl_fc_unique_id(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
2886 const struct arg *args, struct sample *smp, const char *kw)
2887{
2888#if OPENSSL_VERSION_NUMBER > 0x0090800fL
2889 struct connection *conn;
2890 int finished_len;
2891 int b64_len;
2892 struct chunk *finished_trash;
2893 struct chunk *smp_trash;
2894
2895 smp->flags = 0;
2896
2897 if (!l4)
2898 return 0;
2899
2900 conn = objt_conn(l4->si[0].end);
2901 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
2902 return 0;
2903
2904 if (!(conn->flags & CO_FL_CONNECTED)) {
2905 smp->flags |= SMP_F_MAY_CHANGE;
2906 return 0;
2907 }
2908
2909 finished_trash = get_trash_chunk();
2910 if (!SSL_session_reused(conn->xprt_ctx))
2911 finished_len = SSL_get_peer_finished(conn->xprt_ctx, finished_trash->str, finished_trash->size);
2912 else
2913 finished_len = SSL_get_finished(conn->xprt_ctx, finished_trash->str, finished_trash->size);
2914
2915 if (!finished_len)
2916 return 0;
2917
2918 smp_trash = get_trash_chunk();
2919 b64_len = a2base64(finished_trash->str, finished_len, smp_trash->str, smp_trash->size);
2920 if (b64_len < 0)
2921 return 0;
2922
2923 smp->data.str.str = smp_trash->str;
Willy Tarreau073edf32014-04-09 15:40:42 +02002924 smp->type = SMP_T_STR;
2925 smp->flags |= SMP_F_CONST;
David Sc1ad52e2014-04-08 18:48:47 -04002926 smp->data.str.len = b64_len;
2927
2928 return 1;
2929#else
2930 return 0;
2931#endif
2932}
2933
Emeric Brun2525b6b2012-10-18 15:59:43 +02002934/* integer, returns the first verify error in CA chain of client certificate chain. */
Emeric Brunf282a812012-09-21 15:27:54 +02002935static int
Emeric Brun2525b6b2012-10-18 15:59:43 +02002936smp_fetch_ssl_c_ca_err(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002937 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brunf282a812012-09-21 15:27:54 +02002938{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002939 struct connection *conn;
2940
2941 if (!l4)
Emeric Brunf282a812012-09-21 15:27:54 +02002942 return 0;
2943
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002944 conn = objt_conn(l4->si[0].end);
2945 if (!conn || conn->xprt != &ssl_sock)
2946 return 0;
2947
2948 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunf282a812012-09-21 15:27:54 +02002949 smp->flags = SMP_F_MAY_CHANGE;
2950 return 0;
2951 }
2952
2953 smp->type = SMP_T_UINT;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002954 smp->data.uint = (unsigned int)SSL_SOCK_ST_TO_CA_ERROR(conn->xprt_st);
Emeric Brunf282a812012-09-21 15:27:54 +02002955 smp->flags = 0;
2956
2957 return 1;
2958}
2959
Emeric Brun2525b6b2012-10-18 15:59:43 +02002960/* integer, returns the depth of the first verify error in CA chain of client certificate chain. */
Emeric Brunf282a812012-09-21 15:27:54 +02002961static int
Emeric Brun2525b6b2012-10-18 15:59:43 +02002962smp_fetch_ssl_c_ca_err_depth(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002963 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brunf282a812012-09-21 15:27:54 +02002964{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002965 struct connection *conn;
2966
2967 if (!l4)
2968 return 0;
2969
2970 conn = objt_conn(l4->si[0].end);
2971 if (!conn || conn->xprt != &ssl_sock)
Emeric Brunf282a812012-09-21 15:27:54 +02002972 return 0;
2973
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002974 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunf282a812012-09-21 15:27:54 +02002975 smp->flags = SMP_F_MAY_CHANGE;
2976 return 0;
2977 }
2978
2979 smp->type = SMP_T_UINT;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002980 smp->data.uint = (unsigned int)SSL_SOCK_ST_TO_CAEDEPTH(conn->xprt_st);
Emeric Brunf282a812012-09-21 15:27:54 +02002981 smp->flags = 0;
2982
2983 return 1;
2984}
2985
Emeric Brun2525b6b2012-10-18 15:59:43 +02002986/* integer, returns the first verify error on client certificate */
Emeric Brunf282a812012-09-21 15:27:54 +02002987static int
Emeric Brun2525b6b2012-10-18 15:59:43 +02002988smp_fetch_ssl_c_err(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002989 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brunf282a812012-09-21 15:27:54 +02002990{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002991 struct connection *conn;
2992
2993 if (!l4)
Emeric Brunf282a812012-09-21 15:27:54 +02002994 return 0;
2995
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002996 conn = objt_conn(l4->si[0].end);
2997 if (!conn || conn->xprt != &ssl_sock)
2998 return 0;
2999
3000 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunf282a812012-09-21 15:27:54 +02003001 smp->flags = SMP_F_MAY_CHANGE;
3002 return 0;
3003 }
3004
3005 smp->type = SMP_T_UINT;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003006 smp->data.uint = (unsigned int)SSL_SOCK_ST_TO_CRTERROR(conn->xprt_st);
Emeric Brunf282a812012-09-21 15:27:54 +02003007 smp->flags = 0;
3008
3009 return 1;
3010}
3011
Emeric Brun2525b6b2012-10-18 15:59:43 +02003012/* integer, returns the verify result on client cert */
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02003013static int
Emeric Brun2525b6b2012-10-18 15:59:43 +02003014smp_fetch_ssl_c_verify(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003015 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02003016{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003017 struct connection *conn;
3018
3019 if (!l4)
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02003020 return 0;
3021
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003022 conn = objt_conn(l4->si[0].end);
3023 if (!conn || conn->xprt != &ssl_sock)
3024 return 0;
3025
3026 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02003027 smp->flags = SMP_F_MAY_CHANGE;
3028 return 0;
3029 }
3030
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003031 if (!conn->xprt_ctx)
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02003032 return 0;
3033
3034 smp->type = SMP_T_UINT;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003035 smp->data.uint = (unsigned int)SSL_get_verify_result(conn->xprt_ctx);
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02003036 smp->flags = 0;
3037
3038 return 1;
3039}
3040
Emeric Brunfb510ea2012-10-05 12:00:26 +02003041/* parse the "ca-file" bind keyword */
3042static 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 +02003043{
3044 if (!*args[cur_arg + 1]) {
3045 if (err)
3046 memprintf(err, "'%s' : missing CAfile path", args[cur_arg]);
3047 return ERR_ALERT | ERR_FATAL;
3048 }
3049
Emeric Brunef42d922012-10-11 16:11:36 +02003050 if ((*args[cur_arg + 1] != '/') && global.ca_base)
3051 memprintf(&conf->ca_file, "%s/%s", global.ca_base, args[cur_arg + 1]);
3052 else
3053 memprintf(&conf->ca_file, "%s", args[cur_arg + 1]);
Emeric Brunc8e8d122012-10-02 18:42:10 +02003054
Emeric Brund94b3fe2012-09-20 18:23:56 +02003055 return 0;
3056}
3057
Willy Tarreau79eeafa2012-09-14 07:53:05 +02003058/* parse the "ciphers" bind keyword */
Willy Tarreau4348fad2012-09-20 16:48:07 +02003059static 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 +02003060{
3061 if (!*args[cur_arg + 1]) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02003062 memprintf(err, "'%s' : missing cipher suite", args[cur_arg]);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02003063 return ERR_ALERT | ERR_FATAL;
3064 }
3065
Emeric Brun76d88952012-10-05 15:47:31 +02003066 free(conf->ciphers);
Willy Tarreau4348fad2012-09-20 16:48:07 +02003067 conf->ciphers = strdup(args[cur_arg + 1]);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02003068 return 0;
3069}
3070
3071/* parse the "crt" bind keyword */
Willy Tarreau4348fad2012-09-20 16:48:07 +02003072static 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 +02003073{
Willy Tarreau38011032013-08-13 16:59:39 +02003074 char path[MAXPATHLEN];
Willy Tarreaub75d6922014-04-14 18:05:41 +02003075
Willy Tarreau79eeafa2012-09-14 07:53:05 +02003076 if (!*args[cur_arg + 1]) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02003077 memprintf(err, "'%s' : missing certificate location", args[cur_arg]);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02003078 return ERR_ALERT | ERR_FATAL;
3079 }
3080
Emeric Brunc8e8d122012-10-02 18:42:10 +02003081 if ((*args[cur_arg + 1] != '/' ) && global.crt_base) {
Willy Tarreau38011032013-08-13 16:59:39 +02003082 if ((strlen(global.crt_base) + 1 + strlen(args[cur_arg + 1]) + 1) > MAXPATHLEN) {
Emeric Brunc8e8d122012-10-02 18:42:10 +02003083 memprintf(err, "'%s' : path too long", args[cur_arg]);
3084 return ERR_ALERT | ERR_FATAL;
3085 }
Willy Tarreaub75d6922014-04-14 18:05:41 +02003086 snprintf(path, sizeof(path), "%s/%s", global.crt_base, args[cur_arg + 1]);
Emeric Brunc8e8d122012-10-02 18:42:10 +02003087 if (ssl_sock_load_cert(path, conf, px, err) > 0)
3088 return ERR_ALERT | ERR_FATAL;
3089
3090 return 0;
3091 }
3092
Willy Tarreau4348fad2012-09-20 16:48:07 +02003093 if (ssl_sock_load_cert(args[cur_arg + 1], conf, px, err) > 0)
Willy Tarreau79eeafa2012-09-14 07:53:05 +02003094 return ERR_ALERT | ERR_FATAL;
Emeric Brund94b3fe2012-09-20 18:23:56 +02003095
3096 return 0;
3097}
3098
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01003099/* parse the "crt-list" bind keyword */
3100static int bind_parse_crt_list(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
3101{
3102 if (!*args[cur_arg + 1]) {
3103 memprintf(err, "'%s' : missing certificate location", args[cur_arg]);
3104 return ERR_ALERT | ERR_FATAL;
3105 }
3106
Willy Tarreauad1731d2013-04-02 17:35:58 +02003107 if (ssl_sock_load_cert_list_file(args[cur_arg + 1], conf, px, err) > 0) {
3108 memprintf(err, "'%s' : %s", args[cur_arg], *err);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01003109 return ERR_ALERT | ERR_FATAL;
Willy Tarreauad1731d2013-04-02 17:35:58 +02003110 }
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01003111
3112 return 0;
3113}
3114
Emeric Brunfb510ea2012-10-05 12:00:26 +02003115/* parse the "crl-file" bind keyword */
3116static 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 +02003117{
Emeric Brun051cdab2012-10-02 19:25:50 +02003118#ifndef X509_V_FLAG_CRL_CHECK
3119 if (err)
3120 memprintf(err, "'%s' : library does not support CRL verify", args[cur_arg]);
3121 return ERR_ALERT | ERR_FATAL;
3122#else
Emeric Brund94b3fe2012-09-20 18:23:56 +02003123 if (!*args[cur_arg + 1]) {
3124 if (err)
3125 memprintf(err, "'%s' : missing CRLfile path", args[cur_arg]);
3126 return ERR_ALERT | ERR_FATAL;
3127 }
Emeric Brun2b58d042012-09-20 17:10:03 +02003128
Emeric Brunef42d922012-10-11 16:11:36 +02003129 if ((*args[cur_arg + 1] != '/') && global.ca_base)
3130 memprintf(&conf->crl_file, "%s/%s", global.ca_base, args[cur_arg + 1]);
3131 else
3132 memprintf(&conf->crl_file, "%s", args[cur_arg + 1]);
Emeric Brunc8e8d122012-10-02 18:42:10 +02003133
Emeric Brun2b58d042012-09-20 17:10:03 +02003134 return 0;
Emeric Brun051cdab2012-10-02 19:25:50 +02003135#endif
Emeric Brun2b58d042012-09-20 17:10:03 +02003136}
3137
3138/* parse the "ecdhe" bind keyword keywords */
3139static int bind_parse_ecdhe(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
3140{
3141#if OPENSSL_VERSION_NUMBER < 0x0090800fL
3142 if (err)
3143 memprintf(err, "'%s' : library does not support elliptic curve Diffie-Hellman (too old)", args[cur_arg]);
3144 return ERR_ALERT | ERR_FATAL;
3145#elif defined(OPENSSL_NO_ECDH)
3146 if (err)
3147 memprintf(err, "'%s' : library does not support elliptic curve Diffie-Hellman (disabled via OPENSSL_NO_ECDH)", args[cur_arg]);
3148 return ERR_ALERT | ERR_FATAL;
3149#else
3150 if (!*args[cur_arg + 1]) {
3151 if (err)
3152 memprintf(err, "'%s' : missing named curve", args[cur_arg]);
3153 return ERR_ALERT | ERR_FATAL;
3154 }
3155
3156 conf->ecdhe = strdup(args[cur_arg + 1]);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02003157
3158 return 0;
Emeric Brun2b58d042012-09-20 17:10:03 +02003159#endif
Willy Tarreau79eeafa2012-09-14 07:53:05 +02003160}
3161
Emeric Brun81c00f02012-09-21 14:31:21 +02003162/* parse the "crt_ignerr" and "ca_ignerr" bind keywords */
3163static int bind_parse_ignore_err(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
3164{
3165 int code;
3166 char *p = args[cur_arg + 1];
3167 unsigned long long *ignerr = &conf->crt_ignerr;
3168
3169 if (!*p) {
3170 if (err)
3171 memprintf(err, "'%s' : missing error IDs list", args[cur_arg]);
3172 return ERR_ALERT | ERR_FATAL;
3173 }
3174
3175 if (strcmp(args[cur_arg], "ca-ignore-err") == 0)
3176 ignerr = &conf->ca_ignerr;
3177
3178 if (strcmp(p, "all") == 0) {
3179 *ignerr = ~0ULL;
3180 return 0;
3181 }
3182
3183 while (p) {
3184 code = atoi(p);
3185 if ((code <= 0) || (code > 63)) {
3186 if (err)
3187 memprintf(err, "'%s' : ID '%d' out of range (1..63) in error IDs list '%s'",
3188 args[cur_arg], code, args[cur_arg + 1]);
3189 return ERR_ALERT | ERR_FATAL;
3190 }
3191 *ignerr |= 1ULL << code;
3192 p = strchr(p, ',');
3193 if (p)
3194 p++;
3195 }
3196
Emeric Brun2cb7ae52012-10-05 14:14:21 +02003197 return 0;
3198}
3199
3200/* parse the "force-sslv3" bind keyword */
3201static int bind_parse_force_sslv3(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
3202{
3203 conf->ssl_options |= BC_SSL_O_USE_SSLV3;
3204 return 0;
3205}
3206
3207/* parse the "force-tlsv10" bind keyword */
3208static int bind_parse_force_tlsv10(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
3209{
3210 conf->ssl_options |= BC_SSL_O_USE_TLSV10;
Emeric Brun2d0c4822012-10-02 13:45:20 +02003211 return 0;
3212}
3213
Emeric Brun2cb7ae52012-10-05 14:14:21 +02003214/* parse the "force-tlsv11" bind keyword */
3215static int bind_parse_force_tlsv11(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
3216{
3217#if SSL_OP_NO_TLSv1_1
3218 conf->ssl_options |= BC_SSL_O_USE_TLSV11;
3219 return 0;
3220#else
3221 if (err)
3222 memprintf(err, "'%s' : library does not support protocol TLSv1.1", args[cur_arg]);
3223 return ERR_ALERT | ERR_FATAL;
3224#endif
3225}
3226
3227/* parse the "force-tlsv12" bind keyword */
3228static int bind_parse_force_tlsv12(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
3229{
3230#if SSL_OP_NO_TLSv1_2
3231 conf->ssl_options |= BC_SSL_O_USE_TLSV12;
3232 return 0;
3233#else
3234 if (err)
3235 memprintf(err, "'%s' : library does not support protocol TLSv1.2", args[cur_arg]);
3236 return ERR_ALERT | ERR_FATAL;
3237#endif
3238}
3239
3240
Emeric Brun2d0c4822012-10-02 13:45:20 +02003241/* parse the "no-tls-tickets" bind keyword */
3242static int bind_parse_no_tls_tickets(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
3243{
Emeric Brun89675492012-10-05 13:48:26 +02003244 conf->ssl_options |= BC_SSL_O_NO_TLS_TICKETS;
Emeric Brun81c00f02012-09-21 14:31:21 +02003245 return 0;
3246}
3247
Emeric Brun2d0c4822012-10-02 13:45:20 +02003248
Emeric Brun9b3009b2012-10-05 11:55:06 +02003249/* parse the "no-sslv3" bind keyword */
3250static 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 +02003251{
Emeric Brun89675492012-10-05 13:48:26 +02003252 conf->ssl_options |= BC_SSL_O_NO_SSLV3;
Willy Tarreau79eeafa2012-09-14 07:53:05 +02003253 return 0;
3254}
3255
Emeric Brun9b3009b2012-10-05 11:55:06 +02003256/* parse the "no-tlsv10" bind keyword */
3257static 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 +02003258{
Emeric Brun89675492012-10-05 13:48:26 +02003259 conf->ssl_options |= BC_SSL_O_NO_TLSV10;
Emeric Brunc0ff4922012-09-28 19:37:02 +02003260 return 0;
3261}
3262
Emeric Brun9b3009b2012-10-05 11:55:06 +02003263/* parse the "no-tlsv11" bind keyword */
3264static 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 +02003265{
Emeric Brun89675492012-10-05 13:48:26 +02003266 conf->ssl_options |= BC_SSL_O_NO_TLSV11;
Emeric Brunc0ff4922012-09-28 19:37:02 +02003267 return 0;
3268}
3269
Emeric Brun9b3009b2012-10-05 11:55:06 +02003270/* parse the "no-tlsv12" bind keyword */
3271static 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 +02003272{
Emeric Brun89675492012-10-05 13:48:26 +02003273 conf->ssl_options |= BC_SSL_O_NO_TLSV12;
Willy Tarreau79eeafa2012-09-14 07:53:05 +02003274 return 0;
3275}
3276
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02003277/* parse the "npn" bind keyword */
3278static int bind_parse_npn(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
3279{
3280#ifdef OPENSSL_NPN_NEGOTIATED
3281 char *p1, *p2;
3282
3283 if (!*args[cur_arg + 1]) {
3284 memprintf(err, "'%s' : missing the comma-delimited NPN protocol suite", args[cur_arg]);
3285 return ERR_ALERT | ERR_FATAL;
3286 }
3287
3288 free(conf->npn_str);
3289
3290 /* the NPN string is built as a suite of (<len> <name>)* */
3291 conf->npn_len = strlen(args[cur_arg + 1]) + 1;
3292 conf->npn_str = calloc(1, conf->npn_len);
3293 memcpy(conf->npn_str + 1, args[cur_arg + 1], conf->npn_len);
3294
3295 /* replace commas with the name length */
3296 p1 = conf->npn_str;
3297 p2 = p1 + 1;
3298 while (1) {
3299 p2 = memchr(p1 + 1, ',', conf->npn_str + conf->npn_len - (p1 + 1));
3300 if (!p2)
3301 p2 = p1 + 1 + strlen(p1 + 1);
3302
3303 if (p2 - (p1 + 1) > 255) {
3304 *p2 = '\0';
3305 memprintf(err, "'%s' : NPN protocol name too long : '%s'", args[cur_arg], p1 + 1);
3306 return ERR_ALERT | ERR_FATAL;
3307 }
3308
3309 *p1 = p2 - (p1 + 1);
3310 p1 = p2;
3311
3312 if (!*p2)
3313 break;
3314
3315 *(p2++) = '\0';
3316 }
3317 return 0;
3318#else
3319 if (err)
3320 memprintf(err, "'%s' : library does not support TLS NPN extension", args[cur_arg]);
3321 return ERR_ALERT | ERR_FATAL;
3322#endif
3323}
3324
Willy Tarreauab861d32013-04-02 02:30:41 +02003325/* parse the "alpn" bind keyword */
3326static int bind_parse_alpn(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
3327{
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01003328#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Willy Tarreauab861d32013-04-02 02:30:41 +02003329 char *p1, *p2;
3330
3331 if (!*args[cur_arg + 1]) {
3332 memprintf(err, "'%s' : missing the comma-delimited ALPN protocol suite", args[cur_arg]);
3333 return ERR_ALERT | ERR_FATAL;
3334 }
3335
3336 free(conf->alpn_str);
3337
3338 /* the ALPN string is built as a suite of (<len> <name>)* */
3339 conf->alpn_len = strlen(args[cur_arg + 1]) + 1;
3340 conf->alpn_str = calloc(1, conf->alpn_len);
3341 memcpy(conf->alpn_str + 1, args[cur_arg + 1], conf->alpn_len);
3342
3343 /* replace commas with the name length */
3344 p1 = conf->alpn_str;
3345 p2 = p1 + 1;
3346 while (1) {
3347 p2 = memchr(p1 + 1, ',', conf->alpn_str + conf->alpn_len - (p1 + 1));
3348 if (!p2)
3349 p2 = p1 + 1 + strlen(p1 + 1);
3350
3351 if (p2 - (p1 + 1) > 255) {
3352 *p2 = '\0';
3353 memprintf(err, "'%s' : ALPN protocol name too long : '%s'", args[cur_arg], p1 + 1);
3354 return ERR_ALERT | ERR_FATAL;
3355 }
3356
3357 *p1 = p2 - (p1 + 1);
3358 p1 = p2;
3359
3360 if (!*p2)
3361 break;
3362
3363 *(p2++) = '\0';
3364 }
3365 return 0;
3366#else
3367 if (err)
3368 memprintf(err, "'%s' : library does not support TLS ALPN extension", args[cur_arg]);
3369 return ERR_ALERT | ERR_FATAL;
3370#endif
3371}
3372
Willy Tarreau79eeafa2012-09-14 07:53:05 +02003373/* parse the "ssl" bind keyword */
Willy Tarreau4348fad2012-09-20 16:48:07 +02003374static 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 +02003375{
Willy Tarreau81796be2012-09-22 19:11:47 +02003376 struct listener *l;
3377
Willy Tarreau4348fad2012-09-20 16:48:07 +02003378 conf->is_ssl = 1;
Emeric Brun76d88952012-10-05 15:47:31 +02003379
3380 if (global.listen_default_ciphers && !conf->ciphers)
3381 conf->ciphers = strdup(global.listen_default_ciphers);
3382
Willy Tarreau81796be2012-09-22 19:11:47 +02003383 list_for_each_entry(l, &conf->listeners, by_bind)
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02003384 l->xprt = &ssl_sock;
Willy Tarreau81796be2012-09-22 19:11:47 +02003385
Willy Tarreau79eeafa2012-09-14 07:53:05 +02003386 return 0;
3387}
3388
Emmanuel Hocdet65623372013-01-24 17:17:15 +01003389/* parse the "strict-sni" bind keyword */
3390static int bind_parse_strict_sni(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
3391{
3392 conf->strict_sni = 1;
3393 return 0;
3394}
3395
Emeric Brund94b3fe2012-09-20 18:23:56 +02003396/* parse the "verify" bind keyword */
3397static int bind_parse_verify(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
3398{
3399 if (!*args[cur_arg + 1]) {
3400 if (err)
3401 memprintf(err, "'%s' : missing verify method", args[cur_arg]);
3402 return ERR_ALERT | ERR_FATAL;
3403 }
3404
3405 if (strcmp(args[cur_arg + 1], "none") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01003406 conf->verify = SSL_SOCK_VERIFY_NONE;
Emeric Brund94b3fe2012-09-20 18:23:56 +02003407 else if (strcmp(args[cur_arg + 1], "optional") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01003408 conf->verify = SSL_SOCK_VERIFY_OPTIONAL;
Emeric Brund94b3fe2012-09-20 18:23:56 +02003409 else if (strcmp(args[cur_arg + 1], "required") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01003410 conf->verify = SSL_SOCK_VERIFY_REQUIRED;
Emeric Brund94b3fe2012-09-20 18:23:56 +02003411 else {
3412 if (err)
3413 memprintf(err, "'%s' : unknown verify method '%s', only 'none', 'optional', and 'required' are supported\n",
3414 args[cur_arg], args[cur_arg + 1]);
3415 return ERR_ALERT | ERR_FATAL;
3416 }
3417
3418 return 0;
3419}
3420
Willy Tarreau92faadf2012-10-10 23:04:25 +02003421/************** "server" keywords ****************/
3422
Emeric Brunef42d922012-10-11 16:11:36 +02003423/* parse the "ca-file" server keyword */
3424static int srv_parse_ca_file(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
3425{
3426 if (!*args[*cur_arg + 1]) {
3427 if (err)
3428 memprintf(err, "'%s' : missing CAfile path", args[*cur_arg]);
3429 return ERR_ALERT | ERR_FATAL;
3430 }
3431
3432 if ((*args[*cur_arg + 1] != '/') && global.ca_base)
3433 memprintf(&newsrv->ssl_ctx.ca_file, "%s/%s", global.ca_base, args[*cur_arg + 1]);
3434 else
3435 memprintf(&newsrv->ssl_ctx.ca_file, "%s", args[*cur_arg + 1]);
3436
3437 return 0;
3438}
3439
Willy Tarreau92faadf2012-10-10 23:04:25 +02003440/* parse the "check-ssl" server keyword */
3441static int srv_parse_check_ssl(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
3442{
3443 newsrv->check.use_ssl = 1;
3444 if (global.connect_default_ciphers && !newsrv->ssl_ctx.ciphers)
3445 newsrv->ssl_ctx.ciphers = strdup(global.connect_default_ciphers);
3446 return 0;
3447}
3448
3449/* parse the "ciphers" server keyword */
3450static int srv_parse_ciphers(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
3451{
3452 if (!*args[*cur_arg + 1]) {
3453 memprintf(err, "'%s' : missing cipher suite", args[*cur_arg]);
3454 return ERR_ALERT | ERR_FATAL;
3455 }
3456
3457 free(newsrv->ssl_ctx.ciphers);
3458 newsrv->ssl_ctx.ciphers = strdup(args[*cur_arg + 1]);
3459 return 0;
3460}
3461
Emeric Brunef42d922012-10-11 16:11:36 +02003462/* parse the "crl-file" server keyword */
3463static int srv_parse_crl_file(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
3464{
3465#ifndef X509_V_FLAG_CRL_CHECK
3466 if (err)
3467 memprintf(err, "'%s' : library does not support CRL verify", args[*cur_arg]);
3468 return ERR_ALERT | ERR_FATAL;
3469#else
3470 if (!*args[*cur_arg + 1]) {
3471 if (err)
3472 memprintf(err, "'%s' : missing CRLfile path", args[*cur_arg]);
3473 return ERR_ALERT | ERR_FATAL;
3474 }
3475
3476 if ((*args[*cur_arg + 1] != '/') && global.ca_base)
3477 memprintf(&newsrv->ssl_ctx.crl_file, "%s/%s", global.ca_base, args[*cur_arg + 1]);
3478 else
3479 memprintf(&newsrv->ssl_ctx.crl_file, "%s", args[*cur_arg + 1]);
3480
3481 return 0;
3482#endif
3483}
3484
Emeric Bruna7aa3092012-10-26 12:58:00 +02003485/* parse the "crt" server keyword */
3486static int srv_parse_crt(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
3487{
3488 if (!*args[*cur_arg + 1]) {
3489 if (err)
3490 memprintf(err, "'%s' : missing certificate file path", args[*cur_arg]);
3491 return ERR_ALERT | ERR_FATAL;
3492 }
3493
3494 if ((*args[*cur_arg + 1] != '/') && global.crt_base)
3495 memprintf(&newsrv->ssl_ctx.client_crt, "%s/%s", global.ca_base, args[*cur_arg + 1]);
3496 else
3497 memprintf(&newsrv->ssl_ctx.client_crt, "%s", args[*cur_arg + 1]);
3498
3499 return 0;
3500}
Emeric Brunef42d922012-10-11 16:11:36 +02003501
Willy Tarreau92faadf2012-10-10 23:04:25 +02003502/* parse the "force-sslv3" server keyword */
3503static int srv_parse_force_sslv3(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
3504{
3505 newsrv->ssl_ctx.options |= SRV_SSL_O_USE_SSLV3;
3506 return 0;
3507}
3508
3509/* parse the "force-tlsv10" server keyword */
3510static int srv_parse_force_tlsv10(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
3511{
3512 newsrv->ssl_ctx.options |= SRV_SSL_O_USE_TLSV10;
3513 return 0;
3514}
3515
3516/* parse the "force-tlsv11" server keyword */
3517static int srv_parse_force_tlsv11(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
3518{
3519#if SSL_OP_NO_TLSv1_1
3520 newsrv->ssl_ctx.options |= SRV_SSL_O_USE_TLSV11;
3521 return 0;
3522#else
3523 if (err)
3524 memprintf(err, "'%s' : library does not support protocol TLSv1.1", args[*cur_arg]);
3525 return ERR_ALERT | ERR_FATAL;
3526#endif
3527}
3528
3529/* parse the "force-tlsv12" server keyword */
3530static int srv_parse_force_tlsv12(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
3531{
3532#if SSL_OP_NO_TLSv1_2
3533 newsrv->ssl_ctx.options |= SRV_SSL_O_USE_TLSV12;
3534 return 0;
3535#else
3536 if (err)
3537 memprintf(err, "'%s' : library does not support protocol TLSv1.2", args[*cur_arg]);
3538 return ERR_ALERT | ERR_FATAL;
3539#endif
3540}
3541
3542/* parse the "no-sslv3" server keyword */
3543static int srv_parse_no_sslv3(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
3544{
3545 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_SSLV3;
3546 return 0;
3547}
3548
3549/* parse the "no-tlsv10" server keyword */
3550static int srv_parse_no_tlsv10(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
3551{
3552 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_TLSV10;
3553 return 0;
3554}
3555
3556/* parse the "no-tlsv11" server keyword */
3557static int srv_parse_no_tlsv11(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
3558{
3559 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_TLSV11;
3560 return 0;
3561}
3562
3563/* parse the "no-tlsv12" server keyword */
3564static int srv_parse_no_tlsv12(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
3565{
3566 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_TLSV12;
3567 return 0;
3568}
3569
Emeric Brunf9c5c472012-10-11 15:28:34 +02003570/* parse the "no-tls-tickets" server keyword */
3571static int srv_parse_no_tls_tickets(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
3572{
3573 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_TLS_TICKETS;
3574 return 0;
3575}
3576
Willy Tarreau92faadf2012-10-10 23:04:25 +02003577/* parse the "ssl" server keyword */
3578static int srv_parse_ssl(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
3579{
3580 newsrv->use_ssl = 1;
3581 if (global.connect_default_ciphers && !newsrv->ssl_ctx.ciphers)
3582 newsrv->ssl_ctx.ciphers = strdup(global.connect_default_ciphers);
3583 return 0;
3584}
3585
Emeric Brunef42d922012-10-11 16:11:36 +02003586/* parse the "verify" server keyword */
3587static int srv_parse_verify(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
3588{
3589 if (!*args[*cur_arg + 1]) {
3590 if (err)
3591 memprintf(err, "'%s' : missing verify method", args[*cur_arg]);
3592 return ERR_ALERT | ERR_FATAL;
3593 }
3594
3595 if (strcmp(args[*cur_arg + 1], "none") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01003596 newsrv->ssl_ctx.verify = SSL_SOCK_VERIFY_NONE;
Emeric Brunef42d922012-10-11 16:11:36 +02003597 else if (strcmp(args[*cur_arg + 1], "required") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01003598 newsrv->ssl_ctx.verify = SSL_SOCK_VERIFY_REQUIRED;
Emeric Brunef42d922012-10-11 16:11:36 +02003599 else {
3600 if (err)
3601 memprintf(err, "'%s' : unknown verify method '%s', only 'none' and 'required' are supported\n",
3602 args[*cur_arg], args[*cur_arg + 1]);
3603 return ERR_ALERT | ERR_FATAL;
3604 }
3605
Evan Broderbe554312013-06-27 00:05:25 -07003606 return 0;
3607}
3608
3609/* parse the "verifyhost" server keyword */
3610static int srv_parse_verifyhost(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
3611{
3612 if (!*args[*cur_arg + 1]) {
3613 if (err)
3614 memprintf(err, "'%s' : missing hostname to verify against", args[*cur_arg]);
3615 return ERR_ALERT | ERR_FATAL;
3616 }
3617
3618 newsrv->ssl_ctx.verify_host = strdup(args[*cur_arg + 1]);
3619
Emeric Brunef42d922012-10-11 16:11:36 +02003620 return 0;
3621}
3622
Willy Tarreau7875d092012-09-10 08:20:03 +02003623/* Note: must not be declared <const> as its list will be overwritten.
3624 * Please take care of keeping this list alphabetically sorted.
3625 */
Willy Tarreaudc13c112013-06-21 23:16:39 +02003626static struct sample_fetch_kw_list sample_fetch_keywords = {ILH, {
Willy Tarreau80aca902013-01-07 15:42:20 +01003627 { "ssl_c_ca_err", smp_fetch_ssl_c_ca_err, 0, NULL, SMP_T_UINT, SMP_USE_L5CLI },
3628 { "ssl_c_ca_err_depth", smp_fetch_ssl_c_ca_err_depth, 0, NULL, SMP_T_UINT, SMP_USE_L5CLI },
3629 { "ssl_c_err", smp_fetch_ssl_c_err, 0, NULL, SMP_T_UINT, SMP_USE_L5CLI },
3630 { "ssl_c_i_dn", smp_fetch_ssl_c_i_dn, ARG2(0,STR,SINT), NULL, SMP_T_STR, SMP_USE_L5CLI },
3631 { "ssl_c_key_alg", smp_fetch_ssl_c_key_alg, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
3632 { "ssl_c_notafter", smp_fetch_ssl_c_notafter, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
3633 { "ssl_c_notbefore", smp_fetch_ssl_c_notbefore, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
3634 { "ssl_c_sig_alg", smp_fetch_ssl_c_sig_alg, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
3635 { "ssl_c_s_dn", smp_fetch_ssl_c_s_dn, ARG2(0,STR,SINT), NULL, SMP_T_STR, SMP_USE_L5CLI },
3636 { "ssl_c_serial", smp_fetch_ssl_c_serial, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
James Votha051b4a2013-05-14 20:37:59 +02003637 { "ssl_c_sha1", smp_fetch_ssl_c_sha1, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Willy Tarreau80aca902013-01-07 15:42:20 +01003638 { "ssl_c_used", smp_fetch_ssl_c_used, 0, NULL, SMP_T_BOOL, SMP_USE_L5CLI },
3639 { "ssl_c_verify", smp_fetch_ssl_c_verify, 0, NULL, SMP_T_UINT, SMP_USE_L5CLI },
3640 { "ssl_c_version", smp_fetch_ssl_c_version, 0, NULL, SMP_T_UINT, SMP_USE_L5CLI },
3641 { "ssl_f_i_dn", smp_fetch_ssl_f_i_dn, ARG2(0,STR,SINT), NULL, SMP_T_STR, SMP_USE_L5CLI },
3642 { "ssl_f_key_alg", smp_fetch_ssl_f_key_alg, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
3643 { "ssl_f_notafter", smp_fetch_ssl_f_notafter, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
3644 { "ssl_f_notbefore", smp_fetch_ssl_f_notbefore, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
3645 { "ssl_f_sig_alg", smp_fetch_ssl_f_sig_alg, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
3646 { "ssl_f_s_dn", smp_fetch_ssl_f_s_dn, ARG2(0,STR,SINT), NULL, SMP_T_STR, SMP_USE_L5CLI },
3647 { "ssl_f_serial", smp_fetch_ssl_f_serial, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
3648 { "ssl_f_version", smp_fetch_ssl_f_version, 0, NULL, SMP_T_UINT, SMP_USE_L5CLI },
3649 { "ssl_fc", smp_fetch_ssl_fc, 0, NULL, SMP_T_BOOL, SMP_USE_L5CLI },
3650 { "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 +01003651 { "ssl_fc_cipher", smp_fetch_ssl_fc_cipher, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Willy Tarreau80aca902013-01-07 15:42:20 +01003652 { "ssl_fc_has_crt", smp_fetch_ssl_fc_has_crt, 0, NULL, SMP_T_BOOL, SMP_USE_L5CLI },
3653 { "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 +02003654#ifdef OPENSSL_NPN_NEGOTIATED
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01003655 { "ssl_fc_npn", smp_fetch_ssl_fc_npn, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Willy Tarreaua33c6542012-10-15 13:19:06 +02003656#endif
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01003657#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01003658 { "ssl_fc_alpn", smp_fetch_ssl_fc_alpn, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Willy Tarreauab861d32013-04-02 02:30:41 +02003659#endif
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01003660 { "ssl_fc_protocol", smp_fetch_ssl_fc_protocol, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Willy Tarreau073edf32014-04-09 15:40:42 +02003661 { "ssl_fc_unique_id", smp_fetch_ssl_fc_unique_id, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Willy Tarreau80aca902013-01-07 15:42:20 +01003662 { "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 +01003663 { "ssl_fc_session_id", smp_fetch_ssl_fc_session_id, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
3664 { "ssl_fc_sni", smp_fetch_ssl_fc_sni, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Willy Tarreau7875d092012-09-10 08:20:03 +02003665 { NULL, NULL, 0, 0, 0 },
3666}};
3667
3668/* Note: must not be declared <const> as its list will be overwritten.
3669 * Please take care of keeping this list alphabetically sorted.
3670 */
Willy Tarreaudc13c112013-06-21 23:16:39 +02003671static struct acl_kw_list acl_kws = {ILH, {
Thierry FOURNIERc5a4e982014-03-05 16:07:08 +01003672 { "ssl_c_i_dn", NULL, PAT_MATCH_STR },
3673 { "ssl_c_key_alg", NULL, PAT_MATCH_STR },
3674 { "ssl_c_notafter", NULL, PAT_MATCH_STR },
3675 { "ssl_c_notbefore", NULL, PAT_MATCH_STR },
3676 { "ssl_c_sig_alg", NULL, PAT_MATCH_STR },
3677 { "ssl_c_s_dn", NULL, PAT_MATCH_STR },
3678 { "ssl_c_serial", NULL, PAT_MATCH_BIN },
3679 { "ssl_f_i_dn", NULL, PAT_MATCH_STR },
3680 { "ssl_f_key_alg", NULL, PAT_MATCH_STR },
3681 { "ssl_f_notafter", NULL, PAT_MATCH_STR },
3682 { "ssl_f_notbefore", NULL, PAT_MATCH_STR },
3683 { "ssl_f_sig_alg", NULL, PAT_MATCH_STR },
3684 { "ssl_f_s_dn", NULL, PAT_MATCH_STR },
3685 { "ssl_f_serial", NULL, PAT_MATCH_BIN },
3686 { "ssl_fc_cipher", NULL, PAT_MATCH_STR },
Willy Tarreaua33c6542012-10-15 13:19:06 +02003687#ifdef OPENSSL_NPN_NEGOTIATED
Thierry FOURNIERc5a4e982014-03-05 16:07:08 +01003688 { "ssl_fc_npn", NULL, PAT_MATCH_STR },
Willy Tarreaua33c6542012-10-15 13:19:06 +02003689#endif
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01003690#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Thierry FOURNIERc5a4e982014-03-05 16:07:08 +01003691 { "ssl_fc_alpn", NULL, PAT_MATCH_STR },
Willy Tarreauab861d32013-04-02 02:30:41 +02003692#endif
Thierry FOURNIERc5a4e982014-03-05 16:07:08 +01003693 { "ssl_fc_protocol", NULL, PAT_MATCH_STR },
3694 { "ssl_fc_sni", "ssl_fc_sni", PAT_MATCH_STR },
3695 { "ssl_fc_sni_end", "ssl_fc_sni", PAT_MATCH_END },
3696 { "ssl_fc_sni_reg", "ssl_fc_sni", PAT_MATCH_REG },
Willy Tarreau8ed669b2013-01-11 15:49:37 +01003697 { /* END */ },
Willy Tarreau7875d092012-09-10 08:20:03 +02003698}};
3699
Willy Tarreau79eeafa2012-09-14 07:53:05 +02003700/* Note: must not be declared <const> as its list will be overwritten.
3701 * Please take care of keeping this list alphabetically sorted, doing so helps
3702 * all code contributors.
3703 * Optional keywords are also declared with a NULL ->parse() function so that
3704 * the config parser can report an appropriate error when a known keyword was
3705 * not enabled.
3706 */
Willy Tarreau51fb7652012-09-18 18:24:39 +02003707static struct bind_kw_list bind_kws = { "SSL", { }, {
Willy Tarreauab861d32013-04-02 02:30:41 +02003708 { "alpn", bind_parse_alpn, 1 }, /* set ALPN supported protocols */
Emeric Brunfb510ea2012-10-05 12:00:26 +02003709 { "ca-file", bind_parse_ca_file, 1 }, /* set CAfile to process verify on client cert */
Emeric Brun2d0c4822012-10-02 13:45:20 +02003710 { "ca-ignore-err", bind_parse_ignore_err, 1 }, /* set error IDs to ignore on verify depth > 0 */
3711 { "ciphers", bind_parse_ciphers, 1 }, /* set SSL cipher suite */
Emeric Brunfb510ea2012-10-05 12:00:26 +02003712 { "crl-file", bind_parse_crl_file, 1 }, /* set certificat revocation list file use on client cert verify */
Emeric Brun2d0c4822012-10-02 13:45:20 +02003713 { "crt", bind_parse_crt, 1 }, /* load SSL certificates from this location */
3714 { "crt-ignore-err", bind_parse_ignore_err, 1 }, /* set error IDs to ingore on verify depth == 0 */
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01003715 { "crt-list", bind_parse_crt_list, 1 }, /* load a list of crt from this location */
Emeric Brun2d0c4822012-10-02 13:45:20 +02003716 { "ecdhe", bind_parse_ecdhe, 1 }, /* defines named curve for elliptic curve Diffie-Hellman */
Emeric Brun2cb7ae52012-10-05 14:14:21 +02003717 { "force-sslv3", bind_parse_force_sslv3, 0 }, /* force SSLv3 */
3718 { "force-tlsv10", bind_parse_force_tlsv10, 0 }, /* force TLSv10 */
3719 { "force-tlsv11", bind_parse_force_tlsv11, 0 }, /* force TLSv11 */
3720 { "force-tlsv12", bind_parse_force_tlsv12, 0 }, /* force TLSv12 */
Emeric Brun9b3009b2012-10-05 11:55:06 +02003721 { "no-sslv3", bind_parse_no_sslv3, 0 }, /* disable SSLv3 */
3722 { "no-tlsv10", bind_parse_no_tlsv10, 0 }, /* disable TLSv10 */
3723 { "no-tlsv11", bind_parse_no_tlsv11, 0 }, /* disable TLSv11 */
3724 { "no-tlsv12", bind_parse_no_tlsv12, 0 }, /* disable TLSv12 */
Emeric Brun2d0c4822012-10-02 13:45:20 +02003725 { "no-tls-tickets", bind_parse_no_tls_tickets, 0 }, /* disable session resumption tickets */
Emeric Brun2d0c4822012-10-02 13:45:20 +02003726 { "ssl", bind_parse_ssl, 0 }, /* enable SSL processing */
Emmanuel Hocdet65623372013-01-24 17:17:15 +01003727 { "strict-sni", bind_parse_strict_sni, 0 }, /* refuse negotiation if sni doesn't match a certificate */
Emeric Brun2d0c4822012-10-02 13:45:20 +02003728 { "verify", bind_parse_verify, 1 }, /* set SSL verify method */
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02003729 { "npn", bind_parse_npn, 1 }, /* set NPN supported protocols */
Willy Tarreau79eeafa2012-09-14 07:53:05 +02003730 { NULL, NULL, 0 },
3731}};
Emeric Brun46591952012-05-18 15:47:34 +02003732
Willy Tarreau92faadf2012-10-10 23:04:25 +02003733/* Note: must not be declared <const> as its list will be overwritten.
3734 * Please take care of keeping this list alphabetically sorted, doing so helps
3735 * all code contributors.
3736 * Optional keywords are also declared with a NULL ->parse() function so that
3737 * the config parser can report an appropriate error when a known keyword was
3738 * not enabled.
3739 */
3740static struct srv_kw_list srv_kws = { "SSL", { }, {
Emeric Brunef42d922012-10-11 16:11:36 +02003741 { "ca-file", srv_parse_ca_file, 1, 0 }, /* set CAfile to process verify server cert */
Emeric Brunecc91fe2012-10-11 15:05:10 +02003742 { "check-ssl", srv_parse_check_ssl, 0, 0 }, /* enable SSL for health checks */
3743 { "ciphers", srv_parse_ciphers, 1, 0 }, /* select the cipher suite */
Emeric Brunef42d922012-10-11 16:11:36 +02003744 { "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 +02003745 { "crt", srv_parse_crt, 1, 0 }, /* set client certificate */
Emeric Brunecc91fe2012-10-11 15:05:10 +02003746 { "force-sslv3", srv_parse_force_sslv3, 0, 0 }, /* force SSLv3 */
3747 { "force-tlsv10", srv_parse_force_tlsv10, 0, 0 }, /* force TLSv10 */
3748 { "force-tlsv11", srv_parse_force_tlsv11, 0, 0 }, /* force TLSv11 */
3749 { "force-tlsv12", srv_parse_force_tlsv12, 0, 0 }, /* force TLSv12 */
3750 { "no-sslv3", srv_parse_no_sslv3, 0, 0 }, /* disable SSLv3 */
3751 { "no-tlsv10", srv_parse_no_tlsv10, 0, 0 }, /* disable TLSv10 */
3752 { "no-tlsv11", srv_parse_no_tlsv11, 0, 0 }, /* disable TLSv11 */
3753 { "no-tlsv12", srv_parse_no_tlsv12, 0, 0 }, /* disable TLSv12 */
Emeric Brunf9c5c472012-10-11 15:28:34 +02003754 { "no-tls-tickets", srv_parse_no_tls_tickets, 0, 0 }, /* disable session resumption tickets */
Emeric Brunecc91fe2012-10-11 15:05:10 +02003755 { "ssl", srv_parse_ssl, 0, 0 }, /* enable SSL processing */
Emeric Brunef42d922012-10-11 16:11:36 +02003756 { "verify", srv_parse_verify, 1, 0 }, /* set SSL verify method */
Evan Broderbe554312013-06-27 00:05:25 -07003757 { "verifyhost", srv_parse_verifyhost, 1, 0 }, /* require that SSL cert verifies for hostname */
Willy Tarreau92faadf2012-10-10 23:04:25 +02003758 { NULL, NULL, 0, 0 },
3759}};
3760
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02003761/* transport-layer operations for SSL sockets */
3762struct xprt_ops ssl_sock = {
Emeric Brun46591952012-05-18 15:47:34 +02003763 .snd_buf = ssl_sock_from_buf,
3764 .rcv_buf = ssl_sock_to_buf,
3765 .rcv_pipe = NULL,
3766 .snd_pipe = NULL,
3767 .shutr = NULL,
3768 .shutw = ssl_sock_shutw,
3769 .close = ssl_sock_close,
3770 .init = ssl_sock_init,
3771};
3772
3773__attribute__((constructor))
Willy Tarreau92faadf2012-10-10 23:04:25 +02003774static void __ssl_sock_init(void)
3775{
Emeric Brun46591952012-05-18 15:47:34 +02003776 STACK_OF(SSL_COMP)* cm;
3777
Willy Tarreau610f04b2014-02-13 11:36:41 +01003778#ifdef LISTEN_DEFAULT_CIPHERS
3779 global.listen_default_ciphers = LISTEN_DEFAULT_CIPHERS;
3780#endif
3781#ifdef CONNECT_DEFAULT_CIPHERS
3782 global.connect_default_ciphers = CONNECT_DEFAULT_CIPHERS;
3783#endif
3784 if (global.listen_default_ciphers)
3785 global.listen_default_ciphers = strdup(global.listen_default_ciphers);
3786 if (global.connect_default_ciphers)
3787 global.connect_default_ciphers = strdup(global.connect_default_ciphers);
3788
Emeric Brun46591952012-05-18 15:47:34 +02003789 SSL_library_init();
3790 cm = SSL_COMP_get_compression_methods();
3791 sk_SSL_COMP_zero(cm);
Willy Tarreau7875d092012-09-10 08:20:03 +02003792 sample_register_fetches(&sample_fetch_keywords);
3793 acl_register_keywords(&acl_kws);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02003794 bind_register_keywords(&bind_kws);
Willy Tarreau92faadf2012-10-10 23:04:25 +02003795 srv_register_keywords(&srv_kws);
Emeric Brun46591952012-05-18 15:47:34 +02003796}
3797
3798/*
3799 * Local variables:
3800 * c-indent-level: 8
3801 * c-basic-offset: 8
3802 * End:
3803 */