blob: 9bf4473872b1959c1bb22a22295b29550fb490d9 [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{
Emeric Brun29f037d2014-04-25 19:05:36 +0200188#ifdef TLS1_RT_HEARTBEAT
189 /* test heartbeat received (write_p is set to 0
190 for a received record) */
Willy Tarreauf51c6982014-04-25 20:02:39 +0200191 if ((content_type == TLS1_RT_HEARTBEAT) && (write_p == 0)) {
Willy Tarreau84815002014-04-25 21:40:27 +0200192 struct connection *conn = (struct connection *)SSL_get_app_data(ssl);
Willy Tarreauf51c6982014-04-25 20:02:39 +0200193 const unsigned char *p = buf;
194 unsigned int payload;
195
Emeric Brun29f037d2014-04-25 19:05:36 +0200196 conn->xprt_st |= SSL_SOCK_RECV_HEARTBEAT;
Willy Tarreauf51c6982014-04-25 20:02:39 +0200197
198 /* Check if this is a CVE-2014-0160 exploitation attempt. */
199 if (*p != TLS1_HB_REQUEST)
200 return;
201
202 if (len < 1 + 2 + 16)
203 goto kill_it;
204
205 payload = (p[1] * 256) + p[2];
206 if (1 + 2 + payload + 16 <= len)
207 return; /* OK no problem */
208 kill_it:
209 /* we have a clear heartbleed attack (CVE-2014-0160),
210 * we can't know if the SSL stack is patched, so better
211 * kill the connection before OpenSSL tries to send the
212 * bytes back to the attacker. It will be reported above
213 * as SSL_ERROR_SSL while an other handshake failure with
214 * a heartbeat message will be reported as SSL_ERROR_SYSCALL.
215 */
216 SSLerr(SSL_F_TLS1_HEARTBEAT, SSL_R_SSL_HANDSHAKE_FAILURE);
217 return;
218 }
Emeric Brun29f037d2014-04-25 19:05:36 +0200219#endif
220}
221
Willy Tarreau6c9a3d52012-10-18 18:57:14 +0200222#ifdef OPENSSL_NPN_NEGOTIATED
223/* This callback is used so that the server advertises the list of
224 * negociable protocols for NPN.
225 */
226static int ssl_sock_advertise_npn_protos(SSL *s, const unsigned char **data,
227 unsigned int *len, void *arg)
228{
229 struct bind_conf *conf = arg;
230
231 *data = (const unsigned char *)conf->npn_str;
232 *len = conf->npn_len;
233 return SSL_TLSEXT_ERR_OK;
234}
235#endif
236
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +0100237#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Willy Tarreauab861d32013-04-02 02:30:41 +0200238/* This callback is used so that the server advertises the list of
239 * negociable protocols for ALPN.
240 */
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +0100241static int ssl_sock_advertise_alpn_protos(SSL *s, const unsigned char **out,
242 unsigned char *outlen,
243 const unsigned char *server,
244 unsigned int server_len, void *arg)
Willy Tarreauab861d32013-04-02 02:30:41 +0200245{
246 struct bind_conf *conf = arg;
247
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +0100248 if (SSL_select_next_proto((unsigned char**) out, outlen, (const unsigned char *)conf->alpn_str,
249 conf->alpn_len, server, server_len) != OPENSSL_NPN_NEGOTIATED) {
250 return SSL_TLSEXT_ERR_NOACK;
251 }
Willy Tarreauab861d32013-04-02 02:30:41 +0200252 return SSL_TLSEXT_ERR_OK;
253}
254#endif
255
Emeric Brunfc0421f2012-09-07 17:30:07 +0200256#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
257/* Sets the SSL ctx of <ssl> to match the advertised server name. Returns a
258 * warning when no match is found, which implies the default (first) cert
259 * will keep being used.
260 */
Willy Tarreau2a65ff02012-09-13 17:54:29 +0200261static int ssl_sock_switchctx_cbk(SSL *ssl, int *al, struct bind_conf *s)
Emeric Brunfc0421f2012-09-07 17:30:07 +0200262{
263 const char *servername;
264 const char *wildp = NULL;
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +0200265 struct ebmb_node *node, *n;
Emeric Brunfc0421f2012-09-07 17:30:07 +0200266 int i;
267 (void)al; /* shut gcc stupid warning */
268
269 servername = SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name);
Emmanuel Hocdet65623372013-01-24 17:17:15 +0100270 if (!servername) {
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +0200271 return (s->strict_sni ?
272 SSL_TLSEXT_ERR_ALERT_FATAL :
Emmanuel Hocdet79274e22013-05-31 12:47:44 +0200273 SSL_TLSEXT_ERR_NOACK);
Emmanuel Hocdet65623372013-01-24 17:17:15 +0100274 }
Emeric Brunfc0421f2012-09-07 17:30:07 +0200275
Willy Tarreau19d14ef2012-10-29 16:51:55 +0100276 for (i = 0; i < trash.size; i++) {
Emeric Brunfc0421f2012-09-07 17:30:07 +0200277 if (!servername[i])
278 break;
Willy Tarreau19d14ef2012-10-29 16:51:55 +0100279 trash.str[i] = tolower(servername[i]);
280 if (!wildp && (trash.str[i] == '.'))
281 wildp = &trash.str[i];
Emeric Brunfc0421f2012-09-07 17:30:07 +0200282 }
Willy Tarreau19d14ef2012-10-29 16:51:55 +0100283 trash.str[i] = 0;
Emeric Brunfc0421f2012-09-07 17:30:07 +0200284
285 /* lookup in full qualified names */
Willy Tarreau19d14ef2012-10-29 16:51:55 +0100286 node = ebst_lookup(&s->sni_ctx, trash.str);
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +0200287
288 /* lookup a not neg filter */
289 for (n = node; n; n = ebmb_next_dup(n)) {
290 if (!container_of(n, struct sni_ctx, name)->neg) {
291 node = n;
292 break;
Emmanuel Hocdet65623372013-01-24 17:17:15 +0100293 }
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +0200294 }
295 if (!node && wildp) {
296 /* lookup in wildcards names */
Emeric Brunfc0421f2012-09-07 17:30:07 +0200297 node = ebst_lookup(&s->sni_w_ctx, wildp);
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +0200298 }
299 if (!node || container_of(node, struct sni_ctx, name)->neg) {
300 return (s->strict_sni ?
301 SSL_TLSEXT_ERR_ALERT_FATAL :
302 SSL_TLSEXT_ERR_ALERT_WARNING);
Emeric Brunfc0421f2012-09-07 17:30:07 +0200303 }
304
305 /* switch ctx */
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +0200306 SSL_set_SSL_CTX(ssl, container_of(node, struct sni_ctx, name)->ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +0200307 return SSL_TLSEXT_ERR_OK;
308}
309#endif /* SSL_CTRL_SET_TLSEXT_HOSTNAME */
310
Emeric Bruna4bcd9a2012-09-20 16:19:02 +0200311#ifndef OPENSSL_NO_DH
312/* Loads Diffie-Hellman parameter from a file. Returns 1 if loaded, else -1
313 if an error occured, and 0 if parameter not found. */
Willy Tarreau6e774b42014-04-25 21:35:23 +0200314int ssl_sock_load_dh_params(SSL_CTX *ctx, const char *file)
Emeric Bruna4bcd9a2012-09-20 16:19:02 +0200315{
316 int ret = -1;
317 BIO *in;
318 DH *dh = NULL;
Willy Tarreau6e774b42014-04-25 21:35:23 +0200319 /* If not present, use parameters generated using 'openssl dhparam 1024 -C':
320 * -----BEGIN DH PARAMETERS-----
321 * MIGHAoGBAJJAJDXDoS5E03MNjnjK36eOL1tRqVa/9NuOVlI+lpXmPjJQbP65EvKn
322 * fSLnG7VMhoCJO4KtG88zf393ltP7loGB2bofcDSr+x+XsxBM8yA/Zj6BmQt+CQ9s
323 * TF7hoOV+wXTT6ErZ5y5qx9pq6hLfKXwTGFT78hrE6HnCO7xgtPdTAgEC
324 * -----END DH PARAMETERS-----
325 */
326 static const unsigned char dh1024_p[] = {
327 0x92, 0x40, 0x24, 0x35, 0xC3, 0xA1, 0x2E, 0x44, 0xD3, 0x73, 0x0D, 0x8E,
328 0x78, 0xCA, 0xDF, 0xA7, 0x8E, 0x2F, 0x5B, 0x51, 0xA9, 0x56, 0xBF, 0xF4,
329 0xDB, 0x8E, 0x56, 0x52, 0x3E, 0x96, 0x95, 0xE6, 0x3E, 0x32, 0x50, 0x6C,
330 0xFE, 0xB9, 0x12, 0xF2, 0xA7, 0x7D, 0x22, 0xE7, 0x1B, 0xB5, 0x4C, 0x86,
331 0x80, 0x89, 0x3B, 0x82, 0xAD, 0x1B, 0xCF, 0x33, 0x7F, 0x7F, 0x77, 0x96,
332 0xD3, 0xFB, 0x96, 0x81, 0x81, 0xD9, 0xBA, 0x1F, 0x70, 0x34, 0xAB, 0xFB,
333 0x1F, 0x97, 0xB3, 0x10, 0x4C, 0xF3, 0x20, 0x3F, 0x66, 0x3E, 0x81, 0x99,
334 0x0B, 0x7E, 0x09, 0x0F, 0x6C, 0x4C, 0x5E, 0xE1, 0xA0, 0xE5, 0x7E, 0xC1,
335 0x74, 0xD3, 0xE8, 0x4A, 0xD9, 0xE7, 0x2E, 0x6A, 0xC7, 0xDA, 0x6A, 0xEA,
336 0x12, 0xDF, 0x29, 0x7C, 0x13, 0x18, 0x54, 0xFB, 0xF2, 0x1A, 0xC4, 0xE8,
337 0x79, 0xC2, 0x3B, 0xBC, 0x60, 0xB4, 0xF7, 0x53,
338 };
339 static const unsigned char dh1024_g[] = {
340 0x02,
341 };
Emeric Bruna4bcd9a2012-09-20 16:19:02 +0200342
343 in = BIO_new(BIO_s_file());
344 if (in == NULL)
345 goto end;
346
347 if (BIO_read_filename(in, file) <= 0)
348 goto end;
349
350 dh = PEM_read_bio_DHparams(in, NULL, ctx->default_passwd_callback, ctx->default_passwd_callback_userdata);
Willy Tarreau6e774b42014-04-25 21:35:23 +0200351 if (!dh) {
Emeric Brun41fdb3c2013-04-26 11:05:44 +0200352 /* Clear openssl global errors stack */
353 ERR_clear_error();
354
Willy Tarreau6e774b42014-04-25 21:35:23 +0200355 dh = DH_new();
356 if (dh == NULL)
357 goto end;
358
359 dh->p = BN_bin2bn(dh1024_p, sizeof(dh1024_p), NULL);
360 if (dh->p == NULL)
361 goto end;
362
363 dh->g = BN_bin2bn(dh1024_g, sizeof(dh1024_g), NULL);
364 if (dh->g == NULL)
365 goto end;
366
Emeric Brun41fdb3c2013-04-26 11:05:44 +0200367 ret = 0; /* DH params not found */
Emeric Bruna4bcd9a2012-09-20 16:19:02 +0200368 }
Willy Tarreau6e774b42014-04-25 21:35:23 +0200369 else
370 ret = 1;
371
372 SSL_CTX_set_tmp_dh(ctx, dh);
Emeric Brun644cde02012-12-14 11:21:13 +0100373
Emeric Bruna4bcd9a2012-09-20 16:19:02 +0200374end:
375 if (dh)
376 DH_free(dh);
377
378 if (in)
Emeric Brun41fdb3c2013-04-26 11:05:44 +0200379 BIO_free(in);
Emeric Bruna4bcd9a2012-09-20 16:19:02 +0200380
381 return ret;
382}
383#endif
384
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +0200385static int ssl_sock_add_cert_sni(SSL_CTX *ctx, struct bind_conf *s, char *name, int order)
Emmanuel Hocdetfe616562013-01-22 15:31:15 +0100386{
387 struct sni_ctx *sc;
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +0200388 int wild = 0, neg = 0;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +0100389
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +0200390 if (*name == '!') {
391 neg = 1;
392 name++;
393 }
394 if (*name == '*') {
395 wild = 1;
396 name++;
397 }
398 /* !* filter is a nop */
399 if (neg && wild)
400 return order;
401 if (*name) {
402 int j, len;
403 len = strlen(name);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +0100404 sc = malloc(sizeof(struct sni_ctx) + len + 1);
405 for (j = 0; j < len; j++)
406 sc->name.key[j] = tolower(name[j]);
407 sc->name.key[len] = 0;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +0100408 sc->ctx = ctx;
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +0200409 sc->order = order++;
410 sc->neg = neg;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +0100411 if (wild)
412 ebst_insert(&s->sni_w_ctx, &sc->name);
413 else
414 ebst_insert(&s->sni_ctx, &sc->name);
415 }
416 return order;
417}
418
Emeric Brunfc0421f2012-09-07 17:30:07 +0200419/* Loads a certificate key and CA chain from a file. Returns 0 on error, -1 if
420 * an early error happens and the caller must call SSL_CTX_free() by itelf.
421 */
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +0200422static 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 +0200423{
424 BIO *in;
425 X509 *x = NULL, *ca;
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +0200426 int i, err;
Emeric Brunfc0421f2012-09-07 17:30:07 +0200427 int ret = -1;
428 int order = 0;
429 X509_NAME *xname;
430 char *str;
Emeric Brunfc0421f2012-09-07 17:30:07 +0200431#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
432 STACK_OF(GENERAL_NAME) *names;
433#endif
434
435 in = BIO_new(BIO_s_file());
436 if (in == NULL)
437 goto end;
438
439 if (BIO_read_filename(in, file) <= 0)
440 goto end;
441
442 x = PEM_read_bio_X509_AUX(in, NULL, ctx->default_passwd_callback, ctx->default_passwd_callback_userdata);
443 if (x == NULL)
444 goto end;
445
Emeric Brun50bcecc2013-04-22 13:05:23 +0200446 if (fcount) {
447 while (fcount--)
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +0200448 order = ssl_sock_add_cert_sni(ctx, s, sni_filter[fcount], order);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +0100449 }
450 else {
Emeric Brunfc0421f2012-09-07 17:30:07 +0200451#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Emmanuel Hocdetfe616562013-01-22 15:31:15 +0100452 names = X509_get_ext_d2i(x, NID_subject_alt_name, NULL, NULL);
453 if (names) {
454 for (i = 0; i < sk_GENERAL_NAME_num(names); i++) {
455 GENERAL_NAME *name = sk_GENERAL_NAME_value(names, i);
456 if (name->type == GEN_DNS) {
457 if (ASN1_STRING_to_UTF8((unsigned char **)&str, name->d.dNSName) >= 0) {
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +0200458 order = ssl_sock_add_cert_sni(ctx, s, str, order);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +0100459 OPENSSL_free(str);
Emeric Brunfc0421f2012-09-07 17:30:07 +0200460 }
Emeric Brunfc0421f2012-09-07 17:30:07 +0200461 }
462 }
Emmanuel Hocdetfe616562013-01-22 15:31:15 +0100463 sk_GENERAL_NAME_pop_free(names, GENERAL_NAME_free);
Emeric Brunfc0421f2012-09-07 17:30:07 +0200464 }
Emeric Brunfc0421f2012-09-07 17:30:07 +0200465#endif /* SSL_CTRL_SET_TLSEXT_HOSTNAME */
Emmanuel Hocdetfe616562013-01-22 15:31:15 +0100466 xname = X509_get_subject_name(x);
467 i = -1;
468 while ((i = X509_NAME_get_index_by_NID(xname, NID_commonName, i)) != -1) {
469 X509_NAME_ENTRY *entry = X509_NAME_get_entry(xname, i);
470 if (ASN1_STRING_to_UTF8((unsigned char **)&str, entry->value) >= 0) {
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +0200471 order = ssl_sock_add_cert_sni(ctx, s, str, order);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +0100472 OPENSSL_free(str);
Emeric Brunfc0421f2012-09-07 17:30:07 +0200473 }
Emeric Brunfc0421f2012-09-07 17:30:07 +0200474 }
475 }
476
477 ret = 0; /* the caller must not free the SSL_CTX argument anymore */
478 if (!SSL_CTX_use_certificate(ctx, x))
479 goto end;
480
481 if (ctx->extra_certs != NULL) {
482 sk_X509_pop_free(ctx->extra_certs, X509_free);
483 ctx->extra_certs = NULL;
484 }
485
486 while ((ca = PEM_read_bio_X509(in, NULL, ctx->default_passwd_callback, ctx->default_passwd_callback_userdata))) {
487 if (!SSL_CTX_add_extra_chain_cert(ctx, ca)) {
488 X509_free(ca);
489 goto end;
490 }
491 }
492
493 err = ERR_get_error();
494 if (!err || (ERR_GET_LIB(err) == ERR_LIB_PEM && ERR_GET_REASON(err) == PEM_R_NO_START_LINE)) {
495 /* we successfully reached the last cert in the file */
496 ret = 1;
497 }
498 ERR_clear_error();
499
500end:
501 if (x)
502 X509_free(x);
503
504 if (in)
505 BIO_free(in);
506
507 return ret;
508}
509
Emeric Brun50bcecc2013-04-22 13:05:23 +0200510static 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 +0200511{
512 int ret;
513 SSL_CTX *ctx;
514
515 ctx = SSL_CTX_new(SSLv23_server_method());
516 if (!ctx) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +0200517 memprintf(err, "%sunable to allocate SSL context for cert '%s'.\n",
518 err && *err ? *err : "", path);
Emeric Brunfc0421f2012-09-07 17:30:07 +0200519 return 1;
520 }
521
522 if (SSL_CTX_use_PrivateKey_file(ctx, path, SSL_FILETYPE_PEM) <= 0) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +0200523 memprintf(err, "%sunable to load SSL private key from PEM file '%s'.\n",
524 err && *err ? *err : "", path);
Emeric Brunfc0421f2012-09-07 17:30:07 +0200525 SSL_CTX_free(ctx);
526 return 1;
527 }
528
Emeric Brun50bcecc2013-04-22 13:05:23 +0200529 ret = ssl_sock_load_cert_chain_file(ctx, path, bind_conf, sni_filter, fcount);
Emeric Brunfc0421f2012-09-07 17:30:07 +0200530 if (ret <= 0) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +0200531 memprintf(err, "%sunable to load SSL certificate from PEM file '%s'.\n",
532 err && *err ? *err : "", path);
Emeric Brunfc0421f2012-09-07 17:30:07 +0200533 if (ret < 0) /* serious error, must do that ourselves */
534 SSL_CTX_free(ctx);
535 return 1;
536 }
Emeric Brun61694ab2012-10-26 13:35:33 +0200537
538 if (SSL_CTX_check_private_key(ctx) <= 0) {
539 memprintf(err, "%sinconsistencies between private key and certificate loaded from PEM file '%s'.\n",
540 err && *err ? *err : "", path);
541 return 1;
542 }
543
Emeric Brunfc0421f2012-09-07 17:30:07 +0200544 /* we must not free the SSL_CTX anymore below, since it's already in
545 * the tree, so it will be discovered and cleaned in time.
546 */
Emeric Bruna4bcd9a2012-09-20 16:19:02 +0200547#ifndef OPENSSL_NO_DH
548 ret = ssl_sock_load_dh_params(ctx, path);
549 if (ret < 0) {
550 if (err)
551 memprintf(err, "%sunable to load DH parameters from file '%s'.\n",
552 *err ? *err : "", path);
553 return 1;
554 }
555#endif
556
Emeric Brunfc0421f2012-09-07 17:30:07 +0200557#ifndef SSL_CTRL_SET_TLSEXT_HOSTNAME
Willy Tarreau2a65ff02012-09-13 17:54:29 +0200558 if (bind_conf->default_ctx) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +0200559 memprintf(err, "%sthis version of openssl cannot load multiple SSL certificates.\n",
560 err && *err ? *err : "");
Emeric Brunfc0421f2012-09-07 17:30:07 +0200561 return 1;
562 }
563#endif
Willy Tarreau2a65ff02012-09-13 17:54:29 +0200564 if (!bind_conf->default_ctx)
565 bind_conf->default_ctx = ctx;
Emeric Brunfc0421f2012-09-07 17:30:07 +0200566
567 return 0;
568}
569
Willy Tarreau79eeafa2012-09-14 07:53:05 +0200570int ssl_sock_load_cert(char *path, struct bind_conf *bind_conf, struct proxy *curproxy, char **err)
Emeric Brunfc0421f2012-09-07 17:30:07 +0200571{
572 struct dirent *de;
573 DIR *dir;
574 struct stat buf;
Willy Tarreauee2663b2012-12-06 11:36:59 +0100575 char *end;
576 char fp[MAXPATHLEN+1];
Emeric Brunfc0421f2012-09-07 17:30:07 +0200577 int cfgerr = 0;
578
579 if (!(dir = opendir(path)))
Emeric Brun50bcecc2013-04-22 13:05:23 +0200580 return ssl_sock_load_cert_file(path, bind_conf, curproxy, NULL, 0, err);
Emeric Brunfc0421f2012-09-07 17:30:07 +0200581
582 /* strip trailing slashes, including first one */
583 for (end = path + strlen(path) - 1; end >= path && *end == '/'; end--)
584 *end = 0;
585
Emeric Brunfc0421f2012-09-07 17:30:07 +0200586 while ((de = readdir(dir))) {
Willy Tarreauee2663b2012-12-06 11:36:59 +0100587 snprintf(fp, sizeof(fp), "%s/%s", path, de->d_name);
Emeric Brunfc0421f2012-09-07 17:30:07 +0200588 if (stat(fp, &buf) != 0) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +0200589 memprintf(err, "%sunable to stat SSL certificate from file '%s' : %s.\n",
590 err && *err ? *err : "", fp, strerror(errno));
Emeric Brunfc0421f2012-09-07 17:30:07 +0200591 cfgerr++;
592 continue;
593 }
594 if (!S_ISREG(buf.st_mode))
595 continue;
Emeric Brun50bcecc2013-04-22 13:05:23 +0200596 cfgerr += ssl_sock_load_cert_file(fp, bind_conf, curproxy, NULL, 0, err);
Emeric Brunfc0421f2012-09-07 17:30:07 +0200597 }
Emeric Brunfc0421f2012-09-07 17:30:07 +0200598 closedir(dir);
599 return cfgerr;
600}
601
Thierry Fournier383085f2013-01-24 14:15:43 +0100602/* Make sure openssl opens /dev/urandom before the chroot. The work is only
603 * done once. Zero is returned if the operation fails. No error is returned
604 * if the random is said as not implemented, because we expect that openssl
605 * will use another method once needed.
606 */
607static int ssl_initialize_random()
608{
609 unsigned char random;
610 static int random_initialized = 0;
611
612 if (!random_initialized && RAND_bytes(&random, 1) != 0)
613 random_initialized = 1;
614
615 return random_initialized;
616}
617
Emmanuel Hocdetfe616562013-01-22 15:31:15 +0100618int ssl_sock_load_cert_list_file(char *file, struct bind_conf *bind_conf, struct proxy *curproxy, char **err)
619{
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +0200620 char thisline[LINESIZE];
Emmanuel Hocdetfe616562013-01-22 15:31:15 +0100621 FILE *f;
622 int linenum = 0;
623 int cfgerr = 0;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +0100624
Willy Tarreauad1731d2013-04-02 17:35:58 +0200625 if ((f = fopen(file, "r")) == NULL) {
626 memprintf(err, "cannot open file '%s' : %s", file, strerror(errno));
Emmanuel Hocdetfe616562013-01-22 15:31:15 +0100627 return 1;
Willy Tarreauad1731d2013-04-02 17:35:58 +0200628 }
Emmanuel Hocdetfe616562013-01-22 15:31:15 +0100629
630 while (fgets(thisline, sizeof(thisline), f) != NULL) {
631 int arg;
Emeric Brun50bcecc2013-04-22 13:05:23 +0200632 int newarg;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +0100633 char *end;
634 char *args[MAX_LINE_ARGS + 1];
635 char *line = thisline;
636
637 linenum++;
638 end = line + strlen(line);
639 if (end-line == sizeof(thisline)-1 && *(end-1) != '\n') {
640 /* Check if we reached the limit and the last char is not \n.
641 * Watch out for the last line without the terminating '\n'!
642 */
Willy Tarreauad1731d2013-04-02 17:35:58 +0200643 memprintf(err, "line %d too long in file '%s', limit is %d characters",
644 linenum, file, (int)sizeof(thisline)-1);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +0100645 cfgerr = 1;
Willy Tarreauad1731d2013-04-02 17:35:58 +0200646 break;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +0100647 }
648
Emmanuel Hocdetfe616562013-01-22 15:31:15 +0100649 arg = 0;
Emeric Brun50bcecc2013-04-22 13:05:23 +0200650 newarg = 1;
651 while (*line) {
Emmanuel Hocdetfe616562013-01-22 15:31:15 +0100652 if (*line == '#' || *line == '\n' || *line == '\r') {
653 /* end of string, end of loop */
654 *line = 0;
655 break;
656 }
657 else if (isspace(*line)) {
Emeric Brun50bcecc2013-04-22 13:05:23 +0200658 newarg = 1;
659 *line = 0;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +0100660 }
Emeric Brun50bcecc2013-04-22 13:05:23 +0200661 else if (newarg) {
662 if (arg == MAX_LINE_ARGS) {
663 memprintf(err, "too many args on line %d in file '%s'.",
664 linenum, file);
665 cfgerr = 1;
666 break;
667 }
668 newarg = 0;
669 args[arg++] = line;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +0100670 }
Emeric Brun50bcecc2013-04-22 13:05:23 +0200671 line++;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +0100672 }
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +0200673 if (cfgerr)
674 break;
Willy Tarreauad1731d2013-04-02 17:35:58 +0200675
Emmanuel Hocdetfe616562013-01-22 15:31:15 +0100676 /* empty line */
Emeric Brun50bcecc2013-04-22 13:05:23 +0200677 if (!arg)
Emmanuel Hocdetfe616562013-01-22 15:31:15 +0100678 continue;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +0100679
Emeric Brun50bcecc2013-04-22 13:05:23 +0200680 cfgerr = ssl_sock_load_cert_file(args[0], bind_conf, curproxy, &args[1], arg-1, err);
Willy Tarreauad1731d2013-04-02 17:35:58 +0200681 if (cfgerr) {
682 memprintf(err, "error processing line %d in file '%s' : %s", linenum, file, *err);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +0100683 break;
Willy Tarreauad1731d2013-04-02 17:35:58 +0200684 }
Emmanuel Hocdetfe616562013-01-22 15:31:15 +0100685 }
Emmanuel Hocdetfe616562013-01-22 15:31:15 +0100686 fclose(f);
687 return cfgerr;
688}
689
Emeric Brunfc0421f2012-09-07 17:30:07 +0200690#ifndef SSL_OP_CIPHER_SERVER_PREFERENCE /* needs OpenSSL >= 0.9.7 */
691#define SSL_OP_CIPHER_SERVER_PREFERENCE 0
692#endif
693
694#ifndef SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION /* needs OpenSSL >= 0.9.7 */
695#define SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION 0
Willy Tarreau7d588ee2012-11-26 18:47:31 +0100696#define SSL_renegotiate_pending(arg) 0
Emeric Brunfc0421f2012-09-07 17:30:07 +0200697#endif
Emeric Brun2b58d042012-09-20 17:10:03 +0200698#ifndef SSL_OP_SINGLE_ECDH_USE /* needs OpenSSL >= 0.9.8 */
699#define SSL_OP_SINGLE_ECDH_USE 0
700#endif
Emeric Brun2d0c4822012-10-02 13:45:20 +0200701#ifndef SSL_OP_NO_TICKET /* needs OpenSSL >= 0.9.8 */
702#define SSL_OP_NO_TICKET 0
703#endif
Emeric Brunfc0421f2012-09-07 17:30:07 +0200704#ifndef SSL_OP_NO_COMPRESSION /* needs OpenSSL >= 0.9.9 */
705#define SSL_OP_NO_COMPRESSION 0
706#endif
Emeric Brunc0ff4922012-09-28 19:37:02 +0200707#ifndef SSL_OP_NO_TLSv1_1 /* needs OpenSSL >= 1.0.1 */
708#define SSL_OP_NO_TLSv1_1 0
709#endif
710#ifndef SSL_OP_NO_TLSv1_2 /* needs OpenSSL >= 1.0.1 */
711#define SSL_OP_NO_TLSv1_2 0
712#endif
Emeric Bruna4bcd9a2012-09-20 16:19:02 +0200713#ifndef SSL_OP_SINGLE_DH_USE /* needs OpenSSL >= 0.9.6 */
714#define SSL_OP_SINGLE_DH_USE 0
715#endif
Emeric Brun2b58d042012-09-20 17:10:03 +0200716#ifndef SSL_OP_SINGLE_ECDH_USE /* needs OpenSSL >= 1.0.0 */
717#define SSL_OP_SINGLE_ECDH_USE 0
718#endif
Emeric Brunfc0421f2012-09-07 17:30:07 +0200719#ifndef SSL_MODE_RELEASE_BUFFERS /* needs OpenSSL >= 1.0.0 */
720#define SSL_MODE_RELEASE_BUFFERS 0
721#endif
Willy Tarreau2a65ff02012-09-13 17:54:29 +0200722int ssl_sock_prepare_ctx(struct bind_conf *bind_conf, SSL_CTX *ctx, struct proxy *curproxy)
Emeric Brunfc0421f2012-09-07 17:30:07 +0200723{
724 int cfgerr = 0;
Emeric Brun850efd52014-01-29 12:24:34 +0100725 int verify = SSL_VERIFY_NONE;
Emeric Brunfc0421f2012-09-07 17:30:07 +0200726 int ssloptions =
727 SSL_OP_ALL | /* all known workarounds for bugs */
728 SSL_OP_NO_SSLv2 |
729 SSL_OP_NO_COMPRESSION |
Emeric Bruna4bcd9a2012-09-20 16:19:02 +0200730 SSL_OP_SINGLE_DH_USE |
Emeric Brun2b58d042012-09-20 17:10:03 +0200731 SSL_OP_SINGLE_ECDH_USE |
Emeric Brun3c4bc6e2012-10-04 18:44:19 +0200732 SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION |
733 SSL_OP_CIPHER_SERVER_PREFERENCE;
Emeric Brunfc0421f2012-09-07 17:30:07 +0200734 int sslmode =
735 SSL_MODE_ENABLE_PARTIAL_WRITE |
736 SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER |
737 SSL_MODE_RELEASE_BUFFERS;
738
Thierry Fournier383085f2013-01-24 14:15:43 +0100739 /* Make sure openssl opens /dev/urandom before the chroot */
740 if (!ssl_initialize_random()) {
741 Alert("OpenSSL random data generator initialization failed.\n");
742 cfgerr++;
743 }
744
Emeric Brun89675492012-10-05 13:48:26 +0200745 if (bind_conf->ssl_options & BC_SSL_O_NO_SSLV3)
Emeric Brunfc0421f2012-09-07 17:30:07 +0200746 ssloptions |= SSL_OP_NO_SSLv3;
Emeric Brun89675492012-10-05 13:48:26 +0200747 if (bind_conf->ssl_options & BC_SSL_O_NO_TLSV10)
Emeric Brunfc0421f2012-09-07 17:30:07 +0200748 ssloptions |= SSL_OP_NO_TLSv1;
Emeric Brun89675492012-10-05 13:48:26 +0200749 if (bind_conf->ssl_options & BC_SSL_O_NO_TLSV11)
Emeric Brunc0ff4922012-09-28 19:37:02 +0200750 ssloptions |= SSL_OP_NO_TLSv1_1;
Emeric Brun89675492012-10-05 13:48:26 +0200751 if (bind_conf->ssl_options & BC_SSL_O_NO_TLSV12)
Emeric Brunc0ff4922012-09-28 19:37:02 +0200752 ssloptions |= SSL_OP_NO_TLSv1_2;
Emeric Brun89675492012-10-05 13:48:26 +0200753 if (bind_conf->ssl_options & BC_SSL_O_NO_TLS_TICKETS)
Emeric Brun2d0c4822012-10-02 13:45:20 +0200754 ssloptions |= SSL_OP_NO_TICKET;
Emeric Brun2cb7ae52012-10-05 14:14:21 +0200755 if (bind_conf->ssl_options & BC_SSL_O_USE_SSLV3)
756 SSL_CTX_set_ssl_version(ctx, SSLv3_server_method());
757 if (bind_conf->ssl_options & BC_SSL_O_USE_TLSV10)
758 SSL_CTX_set_ssl_version(ctx, TLSv1_server_method());
759#if SSL_OP_NO_TLSv1_1
760 if (bind_conf->ssl_options & BC_SSL_O_USE_TLSV11)
761 SSL_CTX_set_ssl_version(ctx, TLSv1_1_server_method());
762#endif
763#if SSL_OP_NO_TLSv1_2
764 if (bind_conf->ssl_options & BC_SSL_O_USE_TLSV12)
765 SSL_CTX_set_ssl_version(ctx, TLSv1_2_server_method());
766#endif
Emeric Brunfc0421f2012-09-07 17:30:07 +0200767
768 SSL_CTX_set_options(ctx, ssloptions);
769 SSL_CTX_set_mode(ctx, sslmode);
Emeric Brun850efd52014-01-29 12:24:34 +0100770 switch (bind_conf->verify) {
771 case SSL_SOCK_VERIFY_NONE:
772 verify = SSL_VERIFY_NONE;
773 break;
774 case SSL_SOCK_VERIFY_OPTIONAL:
775 verify = SSL_VERIFY_PEER;
776 break;
777 case SSL_SOCK_VERIFY_REQUIRED:
778 verify = SSL_VERIFY_PEER|SSL_VERIFY_FAIL_IF_NO_PEER_CERT;
779 break;
780 }
781 SSL_CTX_set_verify(ctx, verify, ssl_sock_bind_verifycbk);
782 if (verify & SSL_VERIFY_PEER) {
Emeric Brunfb510ea2012-10-05 12:00:26 +0200783 if (bind_conf->ca_file) {
Emeric Brund94b3fe2012-09-20 18:23:56 +0200784 /* load CAfile to verify */
Emeric Brunfb510ea2012-10-05 12:00:26 +0200785 if (!SSL_CTX_load_verify_locations(ctx, bind_conf->ca_file, NULL)) {
Emeric Brund94b3fe2012-09-20 18:23:56 +0200786 Alert("Proxy '%s': unable to load CA file '%s' for bind '%s' at [%s:%d].\n",
Emeric Brunfb510ea2012-10-05 12:00:26 +0200787 curproxy->id, bind_conf->ca_file, bind_conf->arg, bind_conf->file, bind_conf->line);
Emeric Brund94b3fe2012-09-20 18:23:56 +0200788 cfgerr++;
789 }
790 /* set CA names fo client cert request, function returns void */
Emeric Brunfb510ea2012-10-05 12:00:26 +0200791 SSL_CTX_set_client_CA_list(ctx, SSL_load_client_CA_file(bind_conf->ca_file));
Emeric Brund94b3fe2012-09-20 18:23:56 +0200792 }
Emeric Brun850efd52014-01-29 12:24:34 +0100793 else {
794 Alert("Proxy '%s': verify is enabled but no CA file specified for bind '%s' at [%s:%d].\n",
795 curproxy->id, bind_conf->arg, bind_conf->file, bind_conf->line);
796 cfgerr++;
797 }
Emeric Brun051cdab2012-10-02 19:25:50 +0200798#ifdef X509_V_FLAG_CRL_CHECK
Emeric Brunfb510ea2012-10-05 12:00:26 +0200799 if (bind_conf->crl_file) {
Emeric Brund94b3fe2012-09-20 18:23:56 +0200800 X509_STORE *store = SSL_CTX_get_cert_store(ctx);
801
Emeric Brunfb510ea2012-10-05 12:00:26 +0200802 if (!store || !X509_STORE_load_locations(store, bind_conf->crl_file, NULL)) {
Emeric Brund94b3fe2012-09-20 18:23:56 +0200803 Alert("Proxy '%s': unable to configure CRL file '%s' for bind '%s' at [%s:%d].\n",
Emeric Brunfb510ea2012-10-05 12:00:26 +0200804 curproxy->id, bind_conf->ca_file, bind_conf->arg, bind_conf->file, bind_conf->line);
Emeric Brund94b3fe2012-09-20 18:23:56 +0200805 cfgerr++;
806 }
Emeric Brun561e5742012-10-02 15:20:55 +0200807 else {
808 X509_STORE_set_flags(store, X509_V_FLAG_CRL_CHECK|X509_V_FLAG_CRL_CHECK_ALL);
809 }
Emeric Brund94b3fe2012-09-20 18:23:56 +0200810 }
Emeric Brun051cdab2012-10-02 19:25:50 +0200811#endif
Emeric Brun644cde02012-12-14 11:21:13 +0100812 ERR_clear_error();
Emeric Brund94b3fe2012-09-20 18:23:56 +0200813 }
Emeric Brunfc0421f2012-09-07 17:30:07 +0200814
Emeric Brun4f65bff2012-11-16 15:11:00 +0100815 if (global.tune.ssllifetime)
816 SSL_CTX_set_timeout(ctx, global.tune.ssllifetime);
817
Emeric Brunfc0421f2012-09-07 17:30:07 +0200818 shared_context_set_cache(ctx);
Willy Tarreau2a65ff02012-09-13 17:54:29 +0200819 if (bind_conf->ciphers &&
820 !SSL_CTX_set_cipher_list(ctx, bind_conf->ciphers)) {
Emeric Brunfc0421f2012-09-07 17:30:07 +0200821 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 +0200822 curproxy->id, bind_conf->ciphers, bind_conf->arg, bind_conf->file, bind_conf->line);
Emeric Brunfc0421f2012-09-07 17:30:07 +0200823 cfgerr++;
824 }
825
826 SSL_CTX_set_info_callback(ctx, ssl_sock_infocbk);
Emeric Brun29f037d2014-04-25 19:05:36 +0200827 SSL_CTX_set_msg_callback(ctx, ssl_sock_msgcbk);
828
Willy Tarreau6c9a3d52012-10-18 18:57:14 +0200829#ifdef OPENSSL_NPN_NEGOTIATED
830 if (bind_conf->npn_str)
831 SSL_CTX_set_next_protos_advertised_cb(ctx, ssl_sock_advertise_npn_protos, bind_conf);
832#endif
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +0100833#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Willy Tarreauab861d32013-04-02 02:30:41 +0200834 if (bind_conf->alpn_str)
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +0100835 SSL_CTX_set_alpn_select_cb(ctx, ssl_sock_advertise_alpn_protos, bind_conf);
Willy Tarreauab861d32013-04-02 02:30:41 +0200836#endif
Willy Tarreau6c9a3d52012-10-18 18:57:14 +0200837
Emeric Brunfc0421f2012-09-07 17:30:07 +0200838#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
839 SSL_CTX_set_tlsext_servername_callback(ctx, ssl_sock_switchctx_cbk);
Willy Tarreau2a65ff02012-09-13 17:54:29 +0200840 SSL_CTX_set_tlsext_servername_arg(ctx, bind_conf);
Emeric Brunfc0421f2012-09-07 17:30:07 +0200841#endif
Emeric Brun2b58d042012-09-20 17:10:03 +0200842#if defined(SSL_CTX_set_tmp_ecdh) && !defined(OPENSSL_NO_ECDH)
Emeric Brun6924ef82013-03-06 14:08:53 +0100843 {
Emeric Brun2b58d042012-09-20 17:10:03 +0200844 int i;
845 EC_KEY *ecdh;
846
Emeric Brun6924ef82013-03-06 14:08:53 +0100847 i = OBJ_sn2nid(bind_conf->ecdhe ? bind_conf->ecdhe : ECDHE_DEFAULT_CURVE);
Emeric Brun2b58d042012-09-20 17:10:03 +0200848 if (!i || ((ecdh = EC_KEY_new_by_curve_name(i)) == NULL)) {
849 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 +0100850 curproxy->id, bind_conf->ecdhe ? bind_conf->ecdhe : ECDHE_DEFAULT_CURVE,
851 bind_conf->arg, bind_conf->file, bind_conf->line);
Emeric Brun2b58d042012-09-20 17:10:03 +0200852 cfgerr++;
853 }
854 else {
855 SSL_CTX_set_tmp_ecdh(ctx, ecdh);
856 EC_KEY_free(ecdh);
857 }
858 }
859#endif
860
Emeric Brunfc0421f2012-09-07 17:30:07 +0200861 return cfgerr;
862}
863
Evan Broderbe554312013-06-27 00:05:25 -0700864static int ssl_sock_srv_hostcheck(const char *pattern, const char *hostname)
865{
866 const char *pattern_wildcard, *pattern_left_label_end, *hostname_left_label_end;
867 size_t prefixlen, suffixlen;
868
869 /* Trivial case */
870 if (strcmp(pattern, hostname) == 0)
871 return 1;
872
Evan Broderbe554312013-06-27 00:05:25 -0700873 /* The rest of this logic is based on RFC 6125, section 6.4.3
874 * (http://tools.ietf.org/html/rfc6125#section-6.4.3) */
875
Emeric Bruna848dae2013-10-08 11:27:28 +0200876 pattern_wildcard = NULL;
877 pattern_left_label_end = pattern;
878 while (*pattern_left_label_end != '.') {
879 switch (*pattern_left_label_end) {
880 case 0:
881 /* End of label not found */
882 return 0;
883 case '*':
884 /* If there is more than one wildcards */
885 if (pattern_wildcard)
886 return 0;
887 pattern_wildcard = pattern_left_label_end;
888 break;
889 }
890 pattern_left_label_end++;
891 }
892
893 /* If it's not trivial and there is no wildcard, it can't
894 * match */
895 if (!pattern_wildcard)
Evan Broderbe554312013-06-27 00:05:25 -0700896 return 0;
897
898 /* Make sure all labels match except the leftmost */
899 hostname_left_label_end = strchr(hostname, '.');
900 if (!hostname_left_label_end
901 || strcmp(pattern_left_label_end, hostname_left_label_end) != 0)
902 return 0;
903
904 /* Make sure the leftmost label of the hostname is long enough
905 * that the wildcard can match */
Emeric Brun369da852013-10-08 11:39:35 +0200906 if (hostname_left_label_end - hostname < (pattern_left_label_end - pattern) - 1)
Evan Broderbe554312013-06-27 00:05:25 -0700907 return 0;
908
909 /* Finally compare the string on either side of the
910 * wildcard */
911 prefixlen = pattern_wildcard - pattern;
912 suffixlen = pattern_left_label_end - (pattern_wildcard + 1);
Emeric Bruna848dae2013-10-08 11:27:28 +0200913 if ((prefixlen && (memcmp(pattern, hostname, prefixlen) != 0))
914 || (suffixlen && (memcmp(pattern_wildcard + 1, hostname_left_label_end - suffixlen, suffixlen) != 0)))
Evan Broderbe554312013-06-27 00:05:25 -0700915 return 0;
916
917 return 1;
918}
919
920static int ssl_sock_srv_verifycbk(int ok, X509_STORE_CTX *ctx)
921{
922 SSL *ssl;
923 struct connection *conn;
924 char *servername;
925
926 int depth;
927 X509 *cert;
928 STACK_OF(GENERAL_NAME) *alt_names;
929 int i;
930 X509_NAME *cert_subject;
931 char *str;
932
933 if (ok == 0)
934 return ok;
935
936 ssl = X509_STORE_CTX_get_ex_data(ctx, SSL_get_ex_data_X509_STORE_CTX_idx());
937 conn = (struct connection *)SSL_get_app_data(ssl);
938
939 servername = objt_server(conn->target)->ssl_ctx.verify_host;
940
941 /* We only need to verify the CN on the actual server cert,
942 * not the indirect CAs */
943 depth = X509_STORE_CTX_get_error_depth(ctx);
944 if (depth != 0)
945 return ok;
946
947 /* At this point, the cert is *not* OK unless we can find a
948 * hostname match */
949 ok = 0;
950
951 cert = X509_STORE_CTX_get_current_cert(ctx);
952 /* It seems like this might happen if verify peer isn't set */
953 if (!cert)
954 return ok;
955
956 alt_names = X509_get_ext_d2i(cert, NID_subject_alt_name, NULL, NULL);
957 if (alt_names) {
958 for (i = 0; !ok && i < sk_GENERAL_NAME_num(alt_names); i++) {
959 GENERAL_NAME *name = sk_GENERAL_NAME_value(alt_names, i);
960 if (name->type == GEN_DNS) {
Emeric Bruna33410c2013-09-17 15:47:48 +0200961#if OPENSSL_VERSION_NUMBER < 0x00907000L
962 if (ASN1_STRING_to_UTF8((unsigned char **)&str, name->d.ia5) >= 0) {
963#else
Evan Broderbe554312013-06-27 00:05:25 -0700964 if (ASN1_STRING_to_UTF8((unsigned char **)&str, name->d.dNSName) >= 0) {
Emeric Bruna33410c2013-09-17 15:47:48 +0200965#endif
Evan Broderbe554312013-06-27 00:05:25 -0700966 ok = ssl_sock_srv_hostcheck(str, servername);
967 OPENSSL_free(str);
968 }
969 }
970 }
Emeric Brun4ad50a42013-09-17 15:19:54 +0200971 sk_GENERAL_NAME_pop_free(alt_names, GENERAL_NAME_free);
Evan Broderbe554312013-06-27 00:05:25 -0700972 }
973
974 cert_subject = X509_get_subject_name(cert);
975 i = -1;
976 while (!ok && (i = X509_NAME_get_index_by_NID(cert_subject, NID_commonName, i)) != -1) {
977 X509_NAME_ENTRY *entry = X509_NAME_get_entry(cert_subject, i);
978 if (ASN1_STRING_to_UTF8((unsigned char **)&str, entry->value) >= 0) {
979 ok = ssl_sock_srv_hostcheck(str, servername);
980 OPENSSL_free(str);
981 }
982 }
983
984 return ok;
985}
986
Emeric Brun94324a42012-10-11 14:00:19 +0200987/* prepare ssl context from servers options. Returns an error count */
988int ssl_sock_prepare_srv_ctx(struct server *srv, struct proxy *curproxy)
989{
990 int cfgerr = 0;
991 int options =
992 SSL_OP_ALL | /* all known workarounds for bugs */
993 SSL_OP_NO_SSLv2 |
994 SSL_OP_NO_COMPRESSION;
995 int mode =
996 SSL_MODE_ENABLE_PARTIAL_WRITE |
997 SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER |
998 SSL_MODE_RELEASE_BUFFERS;
Emeric Brun850efd52014-01-29 12:24:34 +0100999 int verify = SSL_VERIFY_NONE;
Emeric Brun94324a42012-10-11 14:00:19 +02001000
Thierry Fournier383085f2013-01-24 14:15:43 +01001001 /* Make sure openssl opens /dev/urandom before the chroot */
1002 if (!ssl_initialize_random()) {
1003 Alert("OpenSSL random data generator initialization failed.\n");
1004 cfgerr++;
1005 }
1006
Emeric Brun94324a42012-10-11 14:00:19 +02001007 /* Initiate SSL context for current server */
1008 srv->ssl_ctx.reused_sess = NULL;
1009 if (srv->use_ssl)
1010 srv->xprt = &ssl_sock;
1011 if (srv->check.use_ssl)
Simon Horman66183002013-02-23 10:16:43 +09001012 srv->check_common.xprt = &ssl_sock;
Emeric Brun94324a42012-10-11 14:00:19 +02001013
1014 srv->ssl_ctx.ctx = SSL_CTX_new(SSLv23_client_method());
1015 if (!srv->ssl_ctx.ctx) {
1016 Alert("config : %s '%s', server '%s': unable to allocate ssl context.\n",
1017 proxy_type_str(curproxy), curproxy->id,
1018 srv->id);
1019 cfgerr++;
1020 return cfgerr;
1021 }
Emeric Bruna7aa3092012-10-26 12:58:00 +02001022 if (srv->ssl_ctx.client_crt) {
1023 if (SSL_CTX_use_PrivateKey_file(srv->ssl_ctx.ctx, srv->ssl_ctx.client_crt, SSL_FILETYPE_PEM) <= 0) {
1024 Alert("config : %s '%s', server '%s': unable to load SSL private key from PEM file '%s'.\n",
1025 proxy_type_str(curproxy), curproxy->id,
1026 srv->id, srv->ssl_ctx.client_crt);
1027 cfgerr++;
1028 }
1029 else if (SSL_CTX_use_certificate_chain_file(srv->ssl_ctx.ctx, srv->ssl_ctx.client_crt) <= 0) {
1030 Alert("config : %s '%s', server '%s': unable to load ssl certificate from PEM file '%s'.\n",
1031 proxy_type_str(curproxy), curproxy->id,
1032 srv->id, srv->ssl_ctx.client_crt);
1033 cfgerr++;
1034 }
1035 else if (SSL_CTX_check_private_key(srv->ssl_ctx.ctx) <= 0) {
1036 Alert("config : %s '%s', server '%s': inconsistencies between private key and certificate loaded from PEM file '%s'.\n",
1037 proxy_type_str(curproxy), curproxy->id,
1038 srv->id, srv->ssl_ctx.client_crt);
1039 cfgerr++;
1040 }
1041 }
Emeric Brun94324a42012-10-11 14:00:19 +02001042
1043 if (srv->ssl_ctx.options & SRV_SSL_O_NO_SSLV3)
1044 options |= SSL_OP_NO_SSLv3;
1045 if (srv->ssl_ctx.options & SRV_SSL_O_NO_TLSV10)
1046 options |= SSL_OP_NO_TLSv1;
1047 if (srv->ssl_ctx.options & SRV_SSL_O_NO_TLSV11)
1048 options |= SSL_OP_NO_TLSv1_1;
1049 if (srv->ssl_ctx.options & SRV_SSL_O_NO_TLSV12)
1050 options |= SSL_OP_NO_TLSv1_2;
Emeric Brunf9c5c472012-10-11 15:28:34 +02001051 if (srv->ssl_ctx.options & SRV_SSL_O_NO_TLS_TICKETS)
1052 options |= SSL_OP_NO_TICKET;
Emeric Brun94324a42012-10-11 14:00:19 +02001053 if (srv->ssl_ctx.options & SRV_SSL_O_USE_SSLV3)
1054 SSL_CTX_set_ssl_version(srv->ssl_ctx.ctx, SSLv3_client_method());
1055 if (srv->ssl_ctx.options & SRV_SSL_O_USE_TLSV10)
1056 SSL_CTX_set_ssl_version(srv->ssl_ctx.ctx, TLSv1_client_method());
1057#if SSL_OP_NO_TLSv1_1
1058 if (srv->ssl_ctx.options & SRV_SSL_O_USE_TLSV11)
1059 SSL_CTX_set_ssl_version(srv->ssl_ctx.ctx, TLSv1_1_client_method());
1060#endif
1061#if SSL_OP_NO_TLSv1_2
1062 if (srv->ssl_ctx.options & SRV_SSL_O_USE_TLSV12)
1063 SSL_CTX_set_ssl_version(srv->ssl_ctx.ctx, TLSv1_2_client_method());
1064#endif
1065
1066 SSL_CTX_set_options(srv->ssl_ctx.ctx, options);
1067 SSL_CTX_set_mode(srv->ssl_ctx.ctx, mode);
Emeric Brun850efd52014-01-29 12:24:34 +01001068
1069 if (global.ssl_server_verify == SSL_SERVER_VERIFY_REQUIRED)
1070 verify = SSL_VERIFY_PEER;
1071
1072 switch (srv->ssl_ctx.verify) {
1073 case SSL_SOCK_VERIFY_NONE:
1074 verify = SSL_VERIFY_NONE;
1075 break;
1076 case SSL_SOCK_VERIFY_REQUIRED:
1077 verify = SSL_VERIFY_PEER;
1078 break;
1079 }
Evan Broderbe554312013-06-27 00:05:25 -07001080 SSL_CTX_set_verify(srv->ssl_ctx.ctx,
Emeric Brun850efd52014-01-29 12:24:34 +01001081 verify,
Evan Broderbe554312013-06-27 00:05:25 -07001082 srv->ssl_ctx.verify_host ? ssl_sock_srv_verifycbk : NULL);
Emeric Brun850efd52014-01-29 12:24:34 +01001083 if (verify & SSL_VERIFY_PEER) {
Emeric Brunef42d922012-10-11 16:11:36 +02001084 if (srv->ssl_ctx.ca_file) {
1085 /* load CAfile to verify */
1086 if (!SSL_CTX_load_verify_locations(srv->ssl_ctx.ctx, srv->ssl_ctx.ca_file, NULL)) {
Willy Tarreau07ba08b2014-02-16 19:22:08 +01001087 Alert("Proxy '%s', server '%s' [%s:%d] unable to load CA file '%s'.\n",
Emeric Brunef42d922012-10-11 16:11:36 +02001088 curproxy->id, srv->id,
1089 srv->conf.file, srv->conf.line, srv->ssl_ctx.ca_file);
1090 cfgerr++;
1091 }
1092 }
Emeric Brun850efd52014-01-29 12:24:34 +01001093 else {
1094 if (global.ssl_server_verify == SSL_SERVER_VERIFY_REQUIRED)
Willy Tarreau07ba08b2014-02-16 19:22:08 +01001095 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 +01001096 curproxy->id, srv->id,
1097 srv->conf.file, srv->conf.line);
1098 else
Willy Tarreau07ba08b2014-02-16 19:22:08 +01001099 Alert("Proxy '%s', server '%s' [%s:%d] verify is enabled but no CA file specified.\n",
Emeric Brun850efd52014-01-29 12:24:34 +01001100 curproxy->id, srv->id,
1101 srv->conf.file, srv->conf.line);
1102 cfgerr++;
1103 }
Emeric Brunef42d922012-10-11 16:11:36 +02001104#ifdef X509_V_FLAG_CRL_CHECK
1105 if (srv->ssl_ctx.crl_file) {
1106 X509_STORE *store = SSL_CTX_get_cert_store(srv->ssl_ctx.ctx);
1107
1108 if (!store || !X509_STORE_load_locations(store, srv->ssl_ctx.crl_file, NULL)) {
Willy Tarreau07ba08b2014-02-16 19:22:08 +01001109 Alert("Proxy '%s', server '%s' [%s:%d] unable to configure CRL file '%s'.\n",
Emeric Brunef42d922012-10-11 16:11:36 +02001110 curproxy->id, srv->id,
1111 srv->conf.file, srv->conf.line, srv->ssl_ctx.crl_file);
1112 cfgerr++;
1113 }
1114 else {
1115 X509_STORE_set_flags(store, X509_V_FLAG_CRL_CHECK|X509_V_FLAG_CRL_CHECK_ALL);
1116 }
1117 }
1118#endif
1119 }
1120
Emeric Brun4f65bff2012-11-16 15:11:00 +01001121 if (global.tune.ssllifetime)
1122 SSL_CTX_set_timeout(srv->ssl_ctx.ctx, global.tune.ssllifetime);
1123
Emeric Brun94324a42012-10-11 14:00:19 +02001124 SSL_CTX_set_session_cache_mode(srv->ssl_ctx.ctx, SSL_SESS_CACHE_OFF);
1125 if (srv->ssl_ctx.ciphers &&
1126 !SSL_CTX_set_cipher_list(srv->ssl_ctx.ctx, srv->ssl_ctx.ciphers)) {
1127 Alert("Proxy '%s', server '%s' [%s:%d] : unable to set SSL cipher list to '%s'.\n",
1128 curproxy->id, srv->id,
1129 srv->conf.file, srv->conf.line, srv->ssl_ctx.ciphers);
1130 cfgerr++;
1131 }
1132
1133 return cfgerr;
1134}
1135
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001136/* Walks down the two trees in bind_conf and prepares all certs. The pointer may
Emeric Brunfc0421f2012-09-07 17:30:07 +02001137 * be NULL, in which case nothing is done. Returns the number of errors
1138 * encountered.
1139 */
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001140int ssl_sock_prepare_all_ctx(struct bind_conf *bind_conf, struct proxy *px)
Emeric Brunfc0421f2012-09-07 17:30:07 +02001141{
1142 struct ebmb_node *node;
1143 struct sni_ctx *sni;
1144 int err = 0;
1145
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001146 if (!bind_conf || !bind_conf->is_ssl)
Emeric Brunfc0421f2012-09-07 17:30:07 +02001147 return 0;
1148
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001149 node = ebmb_first(&bind_conf->sni_ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001150 while (node) {
1151 sni = ebmb_entry(node, struct sni_ctx, name);
1152 if (!sni->order) /* only initialize the CTX on its first occurrence */
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001153 err += ssl_sock_prepare_ctx(bind_conf, sni->ctx, px);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001154 node = ebmb_next(node);
1155 }
1156
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001157 node = ebmb_first(&bind_conf->sni_w_ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001158 while (node) {
1159 sni = ebmb_entry(node, struct sni_ctx, name);
1160 if (!sni->order) /* only initialize the CTX on its first occurrence */
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001161 err += ssl_sock_prepare_ctx(bind_conf, sni->ctx, px);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001162 node = ebmb_next(node);
1163 }
1164 return err;
1165}
1166
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001167/* Walks down the two trees in bind_conf and frees all the certs. The pointer may
Emeric Brunfc0421f2012-09-07 17:30:07 +02001168 * be NULL, in which case nothing is done. The default_ctx is nullified too.
1169 */
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001170void ssl_sock_free_all_ctx(struct bind_conf *bind_conf)
Emeric Brunfc0421f2012-09-07 17:30:07 +02001171{
1172 struct ebmb_node *node, *back;
1173 struct sni_ctx *sni;
1174
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001175 if (!bind_conf || !bind_conf->is_ssl)
Emeric Brunfc0421f2012-09-07 17:30:07 +02001176 return;
1177
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001178 node = ebmb_first(&bind_conf->sni_ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001179 while (node) {
1180 sni = ebmb_entry(node, struct sni_ctx, name);
1181 back = ebmb_next(node);
1182 ebmb_delete(node);
1183 if (!sni->order) /* only free the CTX on its first occurrence */
1184 SSL_CTX_free(sni->ctx);
1185 free(sni);
1186 node = back;
1187 }
1188
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001189 node = ebmb_first(&bind_conf->sni_w_ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001190 while (node) {
1191 sni = ebmb_entry(node, struct sni_ctx, name);
1192 back = ebmb_next(node);
1193 ebmb_delete(node);
1194 if (!sni->order) /* only free the CTX on its first occurrence */
1195 SSL_CTX_free(sni->ctx);
1196 free(sni);
1197 node = back;
1198 }
1199
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001200 bind_conf->default_ctx = NULL;
Emeric Brune1f38db2012-09-03 20:36:47 +02001201}
1202
Emeric Brun46591952012-05-18 15:47:34 +02001203/*
1204 * This function is called if SSL * context is not yet allocated. The function
1205 * is designed to be called before any other data-layer operation and sets the
1206 * handshake flag on the connection. It is safe to call it multiple times.
1207 * It returns 0 on success and -1 in error case.
1208 */
1209static int ssl_sock_init(struct connection *conn)
1210{
1211 /* already initialized */
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02001212 if (conn->xprt_ctx)
Emeric Brun46591952012-05-18 15:47:34 +02001213 return 0;
1214
Willy Tarreau3c728722014-01-23 13:50:42 +01001215 if (!conn_ctrl_ready(conn))
Willy Tarreauf79c8172013-10-21 16:30:56 +02001216 return 0;
1217
Willy Tarreau20879a02012-12-03 16:32:10 +01001218 if (global.maxsslconn && sslconns >= global.maxsslconn) {
1219 conn->err_code = CO_ER_SSL_TOO_MANY;
Willy Tarreau403edff2012-09-06 11:58:37 +02001220 return -1;
Willy Tarreau20879a02012-12-03 16:32:10 +01001221 }
Willy Tarreau403edff2012-09-06 11:58:37 +02001222
Emeric Brun46591952012-05-18 15:47:34 +02001223 /* If it is in client mode initiate SSL session
1224 in connect state otherwise accept state */
Willy Tarreau3fdb3662012-11-12 00:42:33 +01001225 if (objt_server(conn->target)) {
Emeric Brun46591952012-05-18 15:47:34 +02001226 /* Alloc a new SSL session ctx */
Willy Tarreau3fdb3662012-11-12 00:42:33 +01001227 conn->xprt_ctx = SSL_new(objt_server(conn->target)->ssl_ctx.ctx);
Willy Tarreau20879a02012-12-03 16:32:10 +01001228 if (!conn->xprt_ctx) {
1229 conn->err_code = CO_ER_SSL_NO_MEM;
Emeric Brun46591952012-05-18 15:47:34 +02001230 return -1;
Willy Tarreau20879a02012-12-03 16:32:10 +01001231 }
Emeric Brun46591952012-05-18 15:47:34 +02001232
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02001233 SSL_set_connect_state(conn->xprt_ctx);
Willy Tarreau3fdb3662012-11-12 00:42:33 +01001234 if (objt_server(conn->target)->ssl_ctx.reused_sess)
1235 SSL_set_session(conn->xprt_ctx, objt_server(conn->target)->ssl_ctx.reused_sess);
Emeric Brun46591952012-05-18 15:47:34 +02001236
1237 /* set fd on SSL session context */
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02001238 SSL_set_fd(conn->xprt_ctx, conn->t.sock.fd);
Emeric Brun46591952012-05-18 15:47:34 +02001239
Evan Broderbe554312013-06-27 00:05:25 -07001240 /* set connection pointer */
1241 SSL_set_app_data(conn->xprt_ctx, conn);
1242
Emeric Brun46591952012-05-18 15:47:34 +02001243 /* leave init state and start handshake */
Willy Tarreau05737472012-09-04 08:03:39 +02001244 conn->flags |= CO_FL_SSL_WAIT_HS | CO_FL_WAIT_L6_CONN;
Willy Tarreau403edff2012-09-06 11:58:37 +02001245
1246 sslconns++;
Willy Tarreau71b734c2014-01-28 15:19:44 +01001247 totalsslconns++;
Emeric Brun46591952012-05-18 15:47:34 +02001248 return 0;
1249 }
Willy Tarreau3fdb3662012-11-12 00:42:33 +01001250 else if (objt_listener(conn->target)) {
Emeric Brun46591952012-05-18 15:47:34 +02001251 /* Alloc a new SSL session ctx */
Willy Tarreau3fdb3662012-11-12 00:42:33 +01001252 conn->xprt_ctx = SSL_new(objt_listener(conn->target)->bind_conf->default_ctx);
Willy Tarreau20879a02012-12-03 16:32:10 +01001253 if (!conn->xprt_ctx) {
1254 conn->err_code = CO_ER_SSL_NO_MEM;
Emeric Brun46591952012-05-18 15:47:34 +02001255 return -1;
Willy Tarreau20879a02012-12-03 16:32:10 +01001256 }
Emeric Brun46591952012-05-18 15:47:34 +02001257
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02001258 SSL_set_accept_state(conn->xprt_ctx);
Emeric Brun46591952012-05-18 15:47:34 +02001259
1260 /* set fd on SSL session context */
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02001261 SSL_set_fd(conn->xprt_ctx, conn->t.sock.fd);
Emeric Brun46591952012-05-18 15:47:34 +02001262
Emeric Brune1f38db2012-09-03 20:36:47 +02001263 /* set connection pointer */
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02001264 SSL_set_app_data(conn->xprt_ctx, conn);
Emeric Brune1f38db2012-09-03 20:36:47 +02001265
Emeric Brun46591952012-05-18 15:47:34 +02001266 /* leave init state and start handshake */
Willy Tarreau05737472012-09-04 08:03:39 +02001267 conn->flags |= CO_FL_SSL_WAIT_HS | CO_FL_WAIT_L6_CONN;
Willy Tarreau403edff2012-09-06 11:58:37 +02001268
1269 sslconns++;
Willy Tarreau71b734c2014-01-28 15:19:44 +01001270 totalsslconns++;
Emeric Brun46591952012-05-18 15:47:34 +02001271 return 0;
1272 }
1273 /* don't know how to handle such a target */
Willy Tarreau20879a02012-12-03 16:32:10 +01001274 conn->err_code = CO_ER_SSL_NO_TARGET;
Emeric Brun46591952012-05-18 15:47:34 +02001275 return -1;
1276}
1277
1278
1279/* This is the callback which is used when an SSL handshake is pending. It
1280 * updates the FD status if it wants some polling before being called again.
1281 * It returns 0 if it fails in a fatal way or needs to poll to go further,
1282 * otherwise it returns non-zero and removes itself from the connection's
1283 * flags (the bit is provided in <flag> by the caller).
1284 */
1285int ssl_sock_handshake(struct connection *conn, unsigned int flag)
1286{
1287 int ret;
1288
Willy Tarreau3c728722014-01-23 13:50:42 +01001289 if (!conn_ctrl_ready(conn))
Willy Tarreauf79c8172013-10-21 16:30:56 +02001290 return 0;
1291
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02001292 if (!conn->xprt_ctx)
Emeric Brun46591952012-05-18 15:47:34 +02001293 goto out_error;
1294
Emeric Brun674b7432012-11-08 19:21:55 +01001295 /* If we use SSL_do_handshake to process a reneg initiated by
1296 * the remote peer, it sometimes returns SSL_ERROR_SSL.
1297 * Usually SSL_write and SSL_read are used and process implicitly
1298 * the reneg handshake.
1299 * Here we use SSL_peek as a workaround for reneg.
1300 */
1301 if ((conn->flags & CO_FL_CONNECTED) && SSL_renegotiate_pending(conn->xprt_ctx)) {
1302 char c;
1303
1304 ret = SSL_peek(conn->xprt_ctx, &c, 1);
1305 if (ret <= 0) {
1306 /* handshake may have not been completed, let's find why */
1307 ret = SSL_get_error(conn->xprt_ctx, ret);
1308 if (ret == SSL_ERROR_WANT_WRITE) {
1309 /* SSL handshake needs to write, L4 connection may not be ready */
1310 __conn_sock_stop_recv(conn);
Willy Tarreaue1f50c42014-01-22 20:02:06 +01001311 __conn_sock_want_send(conn);
1312 fd_cant_send(conn->t.sock.fd);
Emeric Brun674b7432012-11-08 19:21:55 +01001313 return 0;
1314 }
1315 else if (ret == SSL_ERROR_WANT_READ) {
1316 /* handshake may have been completed but we have
1317 * no more data to read.
1318 */
1319 if (!SSL_renegotiate_pending(conn->xprt_ctx)) {
1320 ret = 1;
1321 goto reneg_ok;
1322 }
1323 /* SSL handshake needs to read, L4 connection is ready */
1324 if (conn->flags & CO_FL_WAIT_L4_CONN)
1325 conn->flags &= ~CO_FL_WAIT_L4_CONN;
1326 __conn_sock_stop_send(conn);
Willy Tarreaue1f50c42014-01-22 20:02:06 +01001327 __conn_sock_want_recv(conn);
1328 fd_cant_recv(conn->t.sock.fd);
Emeric Brun674b7432012-11-08 19:21:55 +01001329 return 0;
1330 }
1331 else if (ret == SSL_ERROR_SYSCALL) {
1332 /* if errno is null, then connection was successfully established */
1333 if (!errno && conn->flags & CO_FL_WAIT_L4_CONN)
1334 conn->flags &= ~CO_FL_WAIT_L4_CONN;
Willy Tarreau20879a02012-12-03 16:32:10 +01001335 if (!conn->err_code) {
Emeric Brun29f037d2014-04-25 19:05:36 +02001336 if (!((SSL *)conn->xprt_ctx)->packet_length) {
1337 if (!errno) {
1338 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
1339 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
1340 else
1341 conn->err_code = CO_ER_SSL_EMPTY;
1342 }
1343 else {
1344 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
1345 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
1346 else
1347 conn->err_code = CO_ER_SSL_ABORT;
1348 }
1349 }
1350 else {
1351 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
1352 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
Willy Tarreau20879a02012-12-03 16:32:10 +01001353 else
Emeric Brun29f037d2014-04-25 19:05:36 +02001354 conn->err_code = CO_ER_SSL_HANDSHAKE;
1355 }
Willy Tarreau20879a02012-12-03 16:32:10 +01001356 }
Emeric Brun674b7432012-11-08 19:21:55 +01001357 goto out_error;
1358 }
1359 else {
1360 /* Fail on all other handshake errors */
1361 /* Note: OpenSSL may leave unread bytes in the socket's
1362 * buffer, causing an RST to be emitted upon close() on
1363 * TCP sockets. We first try to drain possibly pending
1364 * data to avoid this as much as possible.
1365 */
Willy Tarreau46be2e52014-01-20 12:10:52 +01001366 conn_drain(conn);
Willy Tarreau20879a02012-12-03 16:32:10 +01001367 if (!conn->err_code)
Willy Tarreauf51c6982014-04-25 20:02:39 +02001368 conn->err_code = (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT) ?
1369 CO_ER_SSL_KILLED_HB : CO_ER_SSL_HANDSHAKE;
Emeric Brun674b7432012-11-08 19:21:55 +01001370 goto out_error;
1371 }
1372 }
1373 /* read some data: consider handshake completed */
1374 goto reneg_ok;
1375 }
1376
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02001377 ret = SSL_do_handshake(conn->xprt_ctx);
Emeric Brun46591952012-05-18 15:47:34 +02001378 if (ret != 1) {
1379 /* handshake did not complete, let's find why */
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02001380 ret = SSL_get_error(conn->xprt_ctx, ret);
Emeric Brun46591952012-05-18 15:47:34 +02001381
1382 if (ret == SSL_ERROR_WANT_WRITE) {
1383 /* SSL handshake needs to write, L4 connection may not be ready */
1384 __conn_sock_stop_recv(conn);
Willy Tarreaue1f50c42014-01-22 20:02:06 +01001385 __conn_sock_want_send(conn);
1386 fd_cant_send(conn->t.sock.fd);
Emeric Brun46591952012-05-18 15:47:34 +02001387 return 0;
1388 }
1389 else if (ret == SSL_ERROR_WANT_READ) {
1390 /* SSL handshake needs to read, L4 connection is ready */
1391 if (conn->flags & CO_FL_WAIT_L4_CONN)
1392 conn->flags &= ~CO_FL_WAIT_L4_CONN;
1393 __conn_sock_stop_send(conn);
Willy Tarreaue1f50c42014-01-22 20:02:06 +01001394 __conn_sock_want_recv(conn);
1395 fd_cant_recv(conn->t.sock.fd);
Emeric Brun46591952012-05-18 15:47:34 +02001396 return 0;
1397 }
Willy Tarreau89230192012-09-28 20:22:13 +02001398 else if (ret == SSL_ERROR_SYSCALL) {
1399 /* if errno is null, then connection was successfully established */
1400 if (!errno && conn->flags & CO_FL_WAIT_L4_CONN)
1401 conn->flags &= ~CO_FL_WAIT_L4_CONN;
Willy Tarreau20879a02012-12-03 16:32:10 +01001402
Emeric Brun29f037d2014-04-25 19:05:36 +02001403 if (!((SSL *)conn->xprt_ctx)->packet_length) {
1404 if (!errno) {
1405 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
1406 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
1407 else
1408 conn->err_code = CO_ER_SSL_EMPTY;
1409 }
1410 else {
1411 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
1412 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
1413 else
1414 conn->err_code = CO_ER_SSL_ABORT;
1415 }
1416 }
1417 else {
1418 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
1419 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
Willy Tarreau20879a02012-12-03 16:32:10 +01001420 else
Emeric Brun29f037d2014-04-25 19:05:36 +02001421 conn->err_code = CO_ER_SSL_HANDSHAKE;
1422 }
Willy Tarreau89230192012-09-28 20:22:13 +02001423 goto out_error;
1424 }
Emeric Brun46591952012-05-18 15:47:34 +02001425 else {
1426 /* Fail on all other handshake errors */
Willy Tarreau566dc552012-10-19 20:52:18 +02001427 /* Note: OpenSSL may leave unread bytes in the socket's
1428 * buffer, causing an RST to be emitted upon close() on
1429 * TCP sockets. We first try to drain possibly pending
1430 * data to avoid this as much as possible.
1431 */
Willy Tarreau46be2e52014-01-20 12:10:52 +01001432 conn_drain(conn);
Willy Tarreau20879a02012-12-03 16:32:10 +01001433 if (!conn->err_code)
Willy Tarreauf51c6982014-04-25 20:02:39 +02001434 conn->err_code = (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT) ?
1435 CO_ER_SSL_KILLED_HB : CO_ER_SSL_HANDSHAKE;
Emeric Brun46591952012-05-18 15:47:34 +02001436 goto out_error;
1437 }
1438 }
1439
Emeric Brun674b7432012-11-08 19:21:55 +01001440reneg_ok:
1441
Emeric Brun46591952012-05-18 15:47:34 +02001442 /* Handshake succeeded */
Willy Tarreau3fdb3662012-11-12 00:42:33 +01001443 if (objt_server(conn->target)) {
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02001444 if (!SSL_session_reused(conn->xprt_ctx)) {
Emeric Brun46591952012-05-18 15:47:34 +02001445 /* check if session was reused, if not store current session on server for reuse */
Willy Tarreau3fdb3662012-11-12 00:42:33 +01001446 if (objt_server(conn->target)->ssl_ctx.reused_sess)
1447 SSL_SESSION_free(objt_server(conn->target)->ssl_ctx.reused_sess);
Emeric Brun46591952012-05-18 15:47:34 +02001448
Willy Tarreau3fdb3662012-11-12 00:42:33 +01001449 objt_server(conn->target)->ssl_ctx.reused_sess = SSL_get1_session(conn->xprt_ctx);
Emeric Brun46591952012-05-18 15:47:34 +02001450 }
1451 }
1452
1453 /* The connection is now established at both layers, it's time to leave */
1454 conn->flags &= ~(flag | CO_FL_WAIT_L4_CONN | CO_FL_WAIT_L6_CONN);
1455 return 1;
1456
1457 out_error:
Emeric Brun644cde02012-12-14 11:21:13 +01001458 /* Clear openssl global errors stack */
1459 ERR_clear_error();
1460
Emeric Brun9fa89732012-10-04 17:09:56 +02001461 /* free resumed session if exists */
Willy Tarreau3fdb3662012-11-12 00:42:33 +01001462 if (objt_server(conn->target) && objt_server(conn->target)->ssl_ctx.reused_sess) {
1463 SSL_SESSION_free(objt_server(conn->target)->ssl_ctx.reused_sess);
1464 objt_server(conn->target)->ssl_ctx.reused_sess = NULL;
Emeric Brun9fa89732012-10-04 17:09:56 +02001465 }
1466
Emeric Brun46591952012-05-18 15:47:34 +02001467 /* Fail on all other handshake errors */
1468 conn->flags |= CO_FL_ERROR;
Willy Tarreau20879a02012-12-03 16:32:10 +01001469 if (!conn->err_code)
1470 conn->err_code = CO_ER_SSL_HANDSHAKE;
Emeric Brun46591952012-05-18 15:47:34 +02001471 return 0;
1472}
1473
1474/* Receive up to <count> bytes from connection <conn>'s socket and store them
Willy Tarreauabf08d92014-01-14 11:31:27 +01001475 * into buffer <buf>. Only one call to recv() is performed, unless the
Emeric Brun46591952012-05-18 15:47:34 +02001476 * buffer wraps, in which case a second call may be performed. The connection's
1477 * flags are updated with whatever special event is detected (error, read0,
1478 * empty). The caller is responsible for taking care of those events and
1479 * avoiding the call if inappropriate. The function does not call the
1480 * connection's polling update function, so the caller is responsible for this.
1481 */
1482static int ssl_sock_to_buf(struct connection *conn, struct buffer *buf, int count)
1483{
1484 int ret, done = 0;
Willy Tarreauabf08d92014-01-14 11:31:27 +01001485 int try;
Emeric Brun46591952012-05-18 15:47:34 +02001486
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02001487 if (!conn->xprt_ctx)
Emeric Brun46591952012-05-18 15:47:34 +02001488 goto out_error;
1489
1490 if (conn->flags & CO_FL_HANDSHAKE)
1491 /* a handshake was requested */
1492 return 0;
1493
Willy Tarreauabf08d92014-01-14 11:31:27 +01001494 /* let's realign the buffer to optimize I/O */
1495 if (buffer_empty(buf))
Emeric Brun46591952012-05-18 15:47:34 +02001496 buf->p = buf->data;
Emeric Brun46591952012-05-18 15:47:34 +02001497
1498 /* read the largest possible block. For this, we perform only one call
1499 * to recv() unless the buffer wraps and we exactly fill the first hunk,
1500 * in which case we accept to do it once again. A new attempt is made on
1501 * EINTR too.
1502 */
Willy Tarreau00b0fb92014-01-17 11:09:40 +01001503 while (count > 0) {
Willy Tarreauabf08d92014-01-14 11:31:27 +01001504 /* first check if we have some room after p+i */
1505 try = buf->data + buf->size - (buf->p + buf->i);
1506 /* otherwise continue between data and p-o */
1507 if (try <= 0) {
1508 try = buf->p - (buf->data + buf->o);
1509 if (try <= 0)
1510 break;
1511 }
1512 if (try > count)
1513 try = count;
1514
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02001515 ret = SSL_read(conn->xprt_ctx, bi_end(buf), try);
Emeric Brune1f38db2012-09-03 20:36:47 +02001516 if (conn->flags & CO_FL_ERROR) {
1517 /* CO_FL_ERROR may be set by ssl_sock_infocbk */
Emeric Brun644cde02012-12-14 11:21:13 +01001518 goto out_error;
Emeric Brune1f38db2012-09-03 20:36:47 +02001519 }
Emeric Brun46591952012-05-18 15:47:34 +02001520 if (ret > 0) {
1521 buf->i += ret;
1522 done += ret;
1523 if (ret < try)
1524 break;
1525 count -= ret;
Emeric Brun46591952012-05-18 15:47:34 +02001526 }
1527 else if (ret == 0) {
Emeric Brun644cde02012-12-14 11:21:13 +01001528 ret = SSL_get_error(conn->xprt_ctx, ret);
1529 if (ret != SSL_ERROR_ZERO_RETURN) {
Emeric Brun1c646862012-12-14 12:33:41 +01001530 /* error on protocol or underlying transport */
1531 if ((ret != SSL_ERROR_SYSCALL)
1532 || (errno && (errno != EAGAIN)))
1533 conn->flags |= CO_FL_ERROR;
1534
Emeric Brun644cde02012-12-14 11:21:13 +01001535 /* Clear openssl global errors stack */
1536 ERR_clear_error();
1537 }
Emeric Brun46591952012-05-18 15:47:34 +02001538 goto read0;
1539 }
1540 else {
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02001541 ret = SSL_get_error(conn->xprt_ctx, ret);
Emeric Brun46591952012-05-18 15:47:34 +02001542 if (ret == SSL_ERROR_WANT_WRITE) {
Emeric Brun8af8dd12012-11-08 17:56:20 +01001543 /* handshake is running, and it needs to enable write */
Emeric Brun46591952012-05-18 15:47:34 +02001544 conn->flags |= CO_FL_SSL_WAIT_HS;
Emeric Brun8af8dd12012-11-08 17:56:20 +01001545 __conn_sock_want_send(conn);
Emeric Brun46591952012-05-18 15:47:34 +02001546 break;
1547 }
1548 else if (ret == SSL_ERROR_WANT_READ) {
Emeric Brun282a76a2012-11-08 18:02:56 +01001549 if (SSL_renegotiate_pending(conn->xprt_ctx)) {
1550 /* handshake is running, and it may need to re-enable read */
1551 conn->flags |= CO_FL_SSL_WAIT_HS;
1552 __conn_sock_want_recv(conn);
1553 break;
1554 }
Emeric Brun46591952012-05-18 15:47:34 +02001555 /* we need to poll for retry a read later */
Willy Tarreaue1f50c42014-01-22 20:02:06 +01001556 fd_cant_recv(conn->t.sock.fd);
Emeric Brun46591952012-05-18 15:47:34 +02001557 break;
1558 }
1559 /* otherwise it's a real error */
1560 goto out_error;
1561 }
1562 }
1563 return done;
1564
1565 read0:
1566 conn_sock_read0(conn);
1567 return done;
1568 out_error:
Emeric Brun644cde02012-12-14 11:21:13 +01001569 /* Clear openssl global errors stack */
1570 ERR_clear_error();
1571
Emeric Brun46591952012-05-18 15:47:34 +02001572 conn->flags |= CO_FL_ERROR;
1573 return done;
1574}
1575
1576
1577/* Send all pending bytes from buffer <buf> to connection <conn>'s socket.
Willy Tarreau1049b1f2014-02-02 01:51:17 +01001578 * <flags> may contain some CO_SFL_* flags to hint the system about other
1579 * pending data for example, but this flag is ignored at the moment.
Emeric Brun46591952012-05-18 15:47:34 +02001580 * Only one call to send() is performed, unless the buffer wraps, in which case
1581 * a second call may be performed. The connection's flags are updated with
1582 * whatever special event is detected (error, empty). The caller is responsible
1583 * for taking care of those events and avoiding the call if inappropriate. The
1584 * function does not call the connection's polling update function, so the caller
1585 * is responsible for this.
1586 */
1587static int ssl_sock_from_buf(struct connection *conn, struct buffer *buf, int flags)
1588{
1589 int ret, try, done;
1590
1591 done = 0;
1592
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02001593 if (!conn->xprt_ctx)
Emeric Brun46591952012-05-18 15:47:34 +02001594 goto out_error;
1595
1596 if (conn->flags & CO_FL_HANDSHAKE)
1597 /* a handshake was requested */
1598 return 0;
1599
1600 /* send the largest possible block. For this we perform only one call
1601 * to send() unless the buffer wraps and we exactly fill the first hunk,
1602 * in which case we accept to do it once again.
1603 */
1604 while (buf->o) {
Kevin Hestercad82342013-05-30 15:12:41 -07001605 try = bo_contig_data(buf);
Willy Tarreaubfd59462013-02-21 07:46:09 +01001606
Willy Tarreau7bed9452014-02-02 02:00:24 +01001607 if (!(flags & CO_SFL_STREAMER) &&
Willy Tarreau518cedd2014-02-17 15:43:01 +01001608 !(conn->xprt_st & SSL_SOCK_SEND_UNLIMITED) &&
1609 global.tune.ssl_max_record && try > global.tune.ssl_max_record) {
Willy Tarreaubfd59462013-02-21 07:46:09 +01001610 try = global.tune.ssl_max_record;
Willy Tarreau518cedd2014-02-17 15:43:01 +01001611 }
1612 else {
1613 /* we need to keep the information about the fact that
1614 * we're not limiting the upcoming send(), because if it
1615 * fails, we'll have to retry with at least as many data.
1616 */
1617 conn->xprt_st |= SSL_SOCK_SEND_UNLIMITED;
1618 }
Willy Tarreaubfd59462013-02-21 07:46:09 +01001619
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02001620 ret = SSL_write(conn->xprt_ctx, bo_ptr(buf), try);
Willy Tarreau518cedd2014-02-17 15:43:01 +01001621
Emeric Brune1f38db2012-09-03 20:36:47 +02001622 if (conn->flags & CO_FL_ERROR) {
1623 /* CO_FL_ERROR may be set by ssl_sock_infocbk */
Emeric Brun644cde02012-12-14 11:21:13 +01001624 goto out_error;
Emeric Brune1f38db2012-09-03 20:36:47 +02001625 }
Emeric Brun46591952012-05-18 15:47:34 +02001626 if (ret > 0) {
Willy Tarreau518cedd2014-02-17 15:43:01 +01001627 conn->xprt_st &= ~SSL_SOCK_SEND_UNLIMITED;
1628
Emeric Brun46591952012-05-18 15:47:34 +02001629 buf->o -= ret;
1630 done += ret;
1631
Willy Tarreau5fb38032012-12-16 19:39:09 +01001632 if (likely(buffer_empty(buf)))
Emeric Brun46591952012-05-18 15:47:34 +02001633 /* optimize data alignment in the buffer */
1634 buf->p = buf->data;
1635
1636 /* if the system buffer is full, don't insist */
1637 if (ret < try)
1638 break;
1639 }
1640 else {
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02001641 ret = SSL_get_error(conn->xprt_ctx, ret);
Emeric Brun46591952012-05-18 15:47:34 +02001642 if (ret == SSL_ERROR_WANT_WRITE) {
Emeric Brun282a76a2012-11-08 18:02:56 +01001643 if (SSL_renegotiate_pending(conn->xprt_ctx)) {
1644 /* handshake is running, and it may need to re-enable write */
1645 conn->flags |= CO_FL_SSL_WAIT_HS;
1646 __conn_sock_want_send(conn);
1647 break;
1648 }
Emeric Brun46591952012-05-18 15:47:34 +02001649 /* we need to poll to retry a write later */
Willy Tarreaue1f50c42014-01-22 20:02:06 +01001650 fd_cant_send(conn->t.sock.fd);
Emeric Brun46591952012-05-18 15:47:34 +02001651 break;
1652 }
1653 else if (ret == SSL_ERROR_WANT_READ) {
Emeric Brun8af8dd12012-11-08 17:56:20 +01001654 /* handshake is running, and it needs to enable read */
Emeric Brun46591952012-05-18 15:47:34 +02001655 conn->flags |= CO_FL_SSL_WAIT_HS;
Emeric Brun8af8dd12012-11-08 17:56:20 +01001656 __conn_sock_want_recv(conn);
Emeric Brun46591952012-05-18 15:47:34 +02001657 break;
1658 }
1659 goto out_error;
1660 }
1661 }
1662 return done;
1663
1664 out_error:
Emeric Brun644cde02012-12-14 11:21:13 +01001665 /* Clear openssl global errors stack */
1666 ERR_clear_error();
1667
Emeric Brun46591952012-05-18 15:47:34 +02001668 conn->flags |= CO_FL_ERROR;
1669 return done;
1670}
1671
Emeric Brun46591952012-05-18 15:47:34 +02001672static void ssl_sock_close(struct connection *conn) {
1673
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02001674 if (conn->xprt_ctx) {
1675 SSL_free(conn->xprt_ctx);
1676 conn->xprt_ctx = NULL;
Willy Tarreau403edff2012-09-06 11:58:37 +02001677 sslconns--;
Emeric Brun46591952012-05-18 15:47:34 +02001678 }
Emeric Brun46591952012-05-18 15:47:34 +02001679}
1680
1681/* This function tries to perform a clean shutdown on an SSL connection, and in
1682 * any case, flags the connection as reusable if no handshake was in progress.
1683 */
1684static void ssl_sock_shutw(struct connection *conn, int clean)
1685{
1686 if (conn->flags & CO_FL_HANDSHAKE)
1687 return;
1688 /* no handshake was in progress, try a clean ssl shutdown */
Emeric Brun644cde02012-12-14 11:21:13 +01001689 if (clean && (SSL_shutdown(conn->xprt_ctx) <= 0)) {
1690 /* Clear openssl global errors stack */
1691 ERR_clear_error();
1692 }
Emeric Brun46591952012-05-18 15:47:34 +02001693
1694 /* force flag on ssl to keep session in cache regardless shutdown result */
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02001695 SSL_set_shutdown(conn->xprt_ctx, SSL_SENT_SHUTDOWN);
Emeric Brun46591952012-05-18 15:47:34 +02001696}
1697
Willy Tarreauffc3fcd2012-10-12 20:17:54 +02001698/* used for logging, may be changed for a sample fetch later */
1699const char *ssl_sock_get_cipher_name(struct connection *conn)
1700{
1701 if (!conn->xprt && !conn->xprt_ctx)
1702 return NULL;
1703 return SSL_get_cipher_name(conn->xprt_ctx);
1704}
1705
1706/* used for logging, may be changed for a sample fetch later */
1707const char *ssl_sock_get_proto_version(struct connection *conn)
1708{
1709 if (!conn->xprt && !conn->xprt_ctx)
1710 return NULL;
1711 return SSL_get_version(conn->xprt_ctx);
1712}
1713
Willy Tarreau8d598402012-10-22 17:58:39 +02001714/* Extract a serial from a cert, and copy it to a chunk.
1715 * Returns 1 if serial is found and copied, 0 if no serial found and
1716 * -1 if output is not large enough.
1717 */
1718static int
1719ssl_sock_get_serial(X509 *crt, struct chunk *out)
1720{
1721 ASN1_INTEGER *serial;
1722
1723 serial = X509_get_serialNumber(crt);
1724 if (!serial)
1725 return 0;
1726
1727 if (out->size < serial->length)
1728 return -1;
1729
1730 memcpy(out->str, serial->data, serial->length);
1731 out->len = serial->length;
1732 return 1;
1733}
1734
Emeric Brunce5ad802012-10-22 14:11:22 +02001735
1736/* Copy Date in ASN1_UTCTIME format in struct chunk out.
1737 * Returns 1 if serial is found and copied, 0 if no valid time found
1738 * and -1 if output is not large enough.
1739 */
1740static int
1741ssl_sock_get_time(ASN1_TIME *tm, struct chunk *out)
1742{
1743 if (tm->type == V_ASN1_GENERALIZEDTIME) {
1744 ASN1_GENERALIZEDTIME *gentm = (ASN1_GENERALIZEDTIME *)tm;
1745
1746 if (gentm->length < 12)
1747 return 0;
1748 if (gentm->data[0] != 0x32 || gentm->data[1] != 0x30)
1749 return 0;
1750 if (out->size < gentm->length-2)
1751 return -1;
1752
1753 memcpy(out->str, gentm->data+2, gentm->length-2);
1754 out->len = gentm->length-2;
1755 return 1;
1756 }
1757 else if (tm->type == V_ASN1_UTCTIME) {
1758 ASN1_UTCTIME *utctm = (ASN1_UTCTIME *)tm;
1759
1760 if (utctm->length < 10)
1761 return 0;
1762 if (utctm->data[0] >= 0x35)
1763 return 0;
1764 if (out->size < utctm->length)
1765 return -1;
1766
1767 memcpy(out->str, utctm->data, utctm->length);
1768 out->len = utctm->length;
1769 return 1;
1770 }
1771
1772 return 0;
1773}
1774
Emeric Brun87855892012-10-17 17:39:35 +02001775/* Extract an entry from a X509_NAME and copy its value to an output chunk.
1776 * Returns 1 if entry found, 0 if entry not found, or -1 if output not large enough.
1777 */
1778static int
1779ssl_sock_get_dn_entry(X509_NAME *a, const struct chunk *entry, int pos, struct chunk *out)
1780{
1781 X509_NAME_ENTRY *ne;
1782 int i, j, n;
1783 int cur = 0;
1784 const char *s;
1785 char tmp[128];
1786
1787 out->len = 0;
1788 for (i = 0; i < sk_X509_NAME_ENTRY_num(a->entries); i++) {
1789 if (pos < 0)
1790 j = (sk_X509_NAME_ENTRY_num(a->entries)-1) - i;
1791 else
1792 j = i;
1793
1794 ne = sk_X509_NAME_ENTRY_value(a->entries, j);
1795 n = OBJ_obj2nid(ne->object);
1796 if ((n == NID_undef) || ((s = OBJ_nid2sn(n)) == NULL)) {
1797 i2t_ASN1_OBJECT(tmp, sizeof(tmp), ne->object);
1798 s = tmp;
1799 }
1800
1801 if (chunk_strcasecmp(entry, s) != 0)
1802 continue;
1803
1804 if (pos < 0)
1805 cur--;
1806 else
1807 cur++;
1808
1809 if (cur != pos)
1810 continue;
1811
1812 if (ne->value->length > out->size)
1813 return -1;
1814
1815 memcpy(out->str, ne->value->data, ne->value->length);
1816 out->len = ne->value->length;
1817 return 1;
1818 }
1819
1820 return 0;
1821
1822}
1823
1824/* Extract and format full DN from a X509_NAME and copy result into a chunk
1825 * Returns 1 if dn entries exits, 0 if no dn entry found or -1 if output is not large enough.
1826 */
1827static int
1828ssl_sock_get_dn_oneline(X509_NAME *a, struct chunk *out)
1829{
1830 X509_NAME_ENTRY *ne;
1831 int i, n, ln;
1832 int l = 0;
1833 const char *s;
1834 char *p;
1835 char tmp[128];
1836
1837 out->len = 0;
1838 p = out->str;
1839 for (i = 0; i < sk_X509_NAME_ENTRY_num(a->entries); i++) {
1840 ne = sk_X509_NAME_ENTRY_value(a->entries, i);
1841 n = OBJ_obj2nid(ne->object);
1842 if ((n == NID_undef) || ((s = OBJ_nid2sn(n)) == NULL)) {
1843 i2t_ASN1_OBJECT(tmp, sizeof(tmp), ne->object);
1844 s = tmp;
1845 }
1846 ln = strlen(s);
1847
1848 l += 1 + ln + 1 + ne->value->length;
1849 if (l > out->size)
1850 return -1;
1851 out->len = l;
1852
1853 *(p++)='/';
1854 memcpy(p, s, ln);
1855 p += ln;
1856 *(p++)='=';
1857 memcpy(p, ne->value->data, ne->value->length);
1858 p += ne->value->length;
1859 }
1860
1861 if (!out->len)
1862 return 0;
1863
1864 return 1;
1865}
1866
Willy Tarreau7875d092012-09-10 08:20:03 +02001867/***** Below are some sample fetching functions for ACL/patterns *****/
1868
Emeric Brune64aef12012-09-21 13:15:06 +02001869/* boolean, returns true if client cert was present */
1870static int
Emeric Brun2525b6b2012-10-18 15:59:43 +02001871smp_fetch_ssl_fc_has_crt(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02001872 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brune64aef12012-09-21 13:15:06 +02001873{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02001874 struct connection *conn;
1875
1876 if (!l4)
1877 return 0;
1878
1879 conn = objt_conn(l4->si[0].end);
1880 if (!conn || conn->xprt != &ssl_sock)
Emeric Brune64aef12012-09-21 13:15:06 +02001881 return 0;
1882
Willy Tarreaub363a1f2013-10-01 10:45:07 +02001883 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brune64aef12012-09-21 13:15:06 +02001884 smp->flags |= SMP_F_MAY_CHANGE;
1885 return 0;
1886 }
1887
1888 smp->flags = 0;
1889 smp->type = SMP_T_BOOL;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02001890 smp->data.uint = SSL_SOCK_ST_FL_VERIFY_DONE & conn->xprt_st ? 1 : 0;
Emeric Brune64aef12012-09-21 13:15:06 +02001891
1892 return 1;
1893}
1894
Willy Tarreau8d598402012-10-22 17:58:39 +02001895/* bin, returns serial in a binary chunk */
1896static int
1897smp_fetch_ssl_c_serial(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02001898 const struct arg *args, struct sample *smp, const char *kw)
Willy Tarreau8d598402012-10-22 17:58:39 +02001899{
1900 X509 *crt = NULL;
1901 int ret = 0;
1902 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02001903 struct connection *conn;
1904
1905 if (!l4)
1906 return 0;
Willy Tarreau8d598402012-10-22 17:58:39 +02001907
Willy Tarreaub363a1f2013-10-01 10:45:07 +02001908 conn = objt_conn(l4->si[0].end);
1909 if (!conn || conn->xprt != &ssl_sock)
Willy Tarreau8d598402012-10-22 17:58:39 +02001910 return 0;
1911
Willy Tarreaub363a1f2013-10-01 10:45:07 +02001912 if (!(conn->flags & CO_FL_CONNECTED)) {
Willy Tarreau8d598402012-10-22 17:58:39 +02001913 smp->flags |= SMP_F_MAY_CHANGE;
1914 return 0;
1915 }
1916
1917 /* SSL_get_peer_certificate, it increase X509 * ref count */
Willy Tarreaub363a1f2013-10-01 10:45:07 +02001918 crt = SSL_get_peer_certificate(conn->xprt_ctx);
Willy Tarreau8d598402012-10-22 17:58:39 +02001919 if (!crt)
1920 goto out;
1921
Willy Tarreau47ca5452012-12-23 20:22:19 +01001922 smp_trash = get_trash_chunk();
Willy Tarreau8d598402012-10-22 17:58:39 +02001923 if (ssl_sock_get_serial(crt, smp_trash) <= 0)
1924 goto out;
1925
1926 smp->data.str = *smp_trash;
1927 smp->type = SMP_T_BIN;
1928 ret = 1;
1929out:
1930 if (crt)
1931 X509_free(crt);
1932 return ret;
1933}
Emeric Brune64aef12012-09-21 13:15:06 +02001934
James Votha051b4a2013-05-14 20:37:59 +02001935/* bin, returns the client certificate's SHA-1 fingerprint (SHA-1 hash of DER-encoded certificate) in a binary chunk */
1936static int
1937smp_fetch_ssl_c_sha1(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02001938 const struct arg *args, struct sample *smp, const char *kw)
James Votha051b4a2013-05-14 20:37:59 +02001939{
1940 X509 *crt = NULL;
1941 const EVP_MD *digest;
1942 int ret = 0;
1943 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02001944 struct connection *conn;
James Votha051b4a2013-05-14 20:37:59 +02001945
Willy Tarreaub363a1f2013-10-01 10:45:07 +02001946 if (!l4)
James Votha051b4a2013-05-14 20:37:59 +02001947 return 0;
1948
Willy Tarreaub363a1f2013-10-01 10:45:07 +02001949 conn = objt_conn(l4->si[0].end);
1950 if (!conn || conn->xprt != &ssl_sock)
1951 return 0;
1952
1953 if (!(conn->flags & CO_FL_CONNECTED)) {
James Votha051b4a2013-05-14 20:37:59 +02001954 smp->flags |= SMP_F_MAY_CHANGE;
1955 return 0;
1956 }
1957
1958 /* SSL_get_peer_certificate, it increase X509 * ref count */
Willy Tarreaub363a1f2013-10-01 10:45:07 +02001959 crt = SSL_get_peer_certificate(conn->xprt_ctx);
James Votha051b4a2013-05-14 20:37:59 +02001960 if (!crt)
1961 goto out;
1962
1963 smp_trash = get_trash_chunk();
1964 digest = EVP_sha1();
1965 X509_digest(crt, digest, (unsigned char *)smp_trash->str, (unsigned int *)&smp_trash->len);
1966
1967 smp->data.str = *smp_trash;
1968 smp->type = SMP_T_BIN;
1969 ret = 1;
1970out:
1971 if (crt)
1972 X509_free(crt);
1973 return ret;
1974}
1975
Emeric Brunce5ad802012-10-22 14:11:22 +02001976/*str, returns notafter date in ASN1_UTCTIME format */
1977static int
1978smp_fetch_ssl_c_notafter(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02001979 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brunce5ad802012-10-22 14:11:22 +02001980{
1981 X509 *crt = NULL;
1982 int ret = 0;
1983 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02001984 struct connection *conn;
Emeric Brunce5ad802012-10-22 14:11:22 +02001985
Willy Tarreaub363a1f2013-10-01 10:45:07 +02001986 if (!l4)
Emeric Brunce5ad802012-10-22 14:11:22 +02001987 return 0;
1988
Willy Tarreaub363a1f2013-10-01 10:45:07 +02001989 conn = objt_conn(l4->si[0].end);
1990 if (!conn || conn->xprt != &ssl_sock)
1991 return 0;
1992
1993 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunce5ad802012-10-22 14:11:22 +02001994 smp->flags |= SMP_F_MAY_CHANGE;
1995 return 0;
1996 }
1997
1998 /* SSL_get_peer_certificate, it increase X509 * ref count */
Willy Tarreaub363a1f2013-10-01 10:45:07 +02001999 crt = SSL_get_peer_certificate(conn->xprt_ctx);
Emeric Brunce5ad802012-10-22 14:11:22 +02002000 if (!crt)
2001 goto out;
2002
Willy Tarreau47ca5452012-12-23 20:22:19 +01002003 smp_trash = get_trash_chunk();
Emeric Brunce5ad802012-10-22 14:11:22 +02002004 if (ssl_sock_get_time(X509_get_notAfter(crt), smp_trash) <= 0)
2005 goto out;
2006
2007 smp->data.str = *smp_trash;
2008 smp->type = SMP_T_STR;
2009 ret = 1;
2010out:
2011 if (crt)
2012 X509_free(crt);
2013 return ret;
2014}
2015
Emeric Brun87855892012-10-17 17:39:35 +02002016/* str, returns a string of a formatted full dn \C=..\O=..\OU=.. \CN=.. */
2017static int
2018smp_fetch_ssl_c_i_dn(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002019 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brun87855892012-10-17 17:39:35 +02002020{
2021 X509 *crt = NULL;
2022 X509_NAME *name;
2023 int ret = 0;
2024 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002025 struct connection *conn;
Emeric Brun87855892012-10-17 17:39:35 +02002026
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002027 if (!l4)
Emeric Brun87855892012-10-17 17:39:35 +02002028 return 0;
2029
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002030 conn = objt_conn(l4->si[0].end);
2031 if (!conn || conn->xprt != &ssl_sock)
2032 return 0;
2033
2034 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun87855892012-10-17 17:39:35 +02002035 smp->flags |= SMP_F_MAY_CHANGE;
2036 return 0;
2037 }
2038
2039 /* SSL_get_peer_certificate, it increase X509 * ref count */
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002040 crt = SSL_get_peer_certificate(conn->xprt_ctx);
Emeric Brun87855892012-10-17 17:39:35 +02002041 if (!crt)
2042 goto out;
2043
2044 name = X509_get_issuer_name(crt);
2045 if (!name)
2046 goto out;
2047
Willy Tarreau47ca5452012-12-23 20:22:19 +01002048 smp_trash = get_trash_chunk();
Emeric Brun87855892012-10-17 17:39:35 +02002049 if (args && args[0].type == ARGT_STR) {
2050 int pos = 1;
2051
2052 if (args[1].type == ARGT_SINT)
2053 pos = args[1].data.sint;
2054 else if (args[1].type == ARGT_UINT)
2055 pos =(int)args[1].data.uint;
2056
2057 if (ssl_sock_get_dn_entry(name, &args[0].data.str, pos, smp_trash) <= 0)
2058 goto out;
2059 }
2060 else if (ssl_sock_get_dn_oneline(name, smp_trash) <= 0)
2061 goto out;
2062
2063 smp->type = SMP_T_STR;
2064 smp->data.str = *smp_trash;
2065 ret = 1;
2066out:
2067 if (crt)
2068 X509_free(crt);
2069 return ret;
2070}
2071
Emeric Brunce5ad802012-10-22 14:11:22 +02002072/*str, returns notbefore date in ASN1_UTCTIME format */
2073static int
2074smp_fetch_ssl_c_notbefore(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002075 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brunce5ad802012-10-22 14:11:22 +02002076{
2077 X509 *crt = NULL;
2078 int ret = 0;
2079 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002080 struct connection *conn;
2081
2082 if (!l4)
2083 return 0;
Emeric Brunce5ad802012-10-22 14:11:22 +02002084
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002085 conn = objt_conn(l4->si[0].end);
2086 if (!conn || conn->xprt != &ssl_sock)
Emeric Brunce5ad802012-10-22 14:11:22 +02002087 return 0;
2088
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002089 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunce5ad802012-10-22 14:11:22 +02002090 smp->flags |= SMP_F_MAY_CHANGE;
2091 return 0;
2092 }
2093
2094 /* SSL_get_peer_certificate, it increase X509 * ref count */
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002095 crt = SSL_get_peer_certificate(conn->xprt_ctx);
Emeric Brunce5ad802012-10-22 14:11:22 +02002096 if (!crt)
2097 goto out;
2098
Willy Tarreau47ca5452012-12-23 20:22:19 +01002099 smp_trash = get_trash_chunk();
Emeric Brunce5ad802012-10-22 14:11:22 +02002100 if (ssl_sock_get_time(X509_get_notBefore(crt), smp_trash) <= 0)
2101 goto out;
2102
2103 smp->data.str = *smp_trash;
2104 smp->type = SMP_T_STR;
2105 ret = 1;
2106out:
2107 if (crt)
2108 X509_free(crt);
2109 return ret;
2110}
2111
Emeric Brun87855892012-10-17 17:39:35 +02002112/* str, returns a string of a formatted full dn \C=..\O=..\OU=.. \CN=.. */
2113static int
2114smp_fetch_ssl_c_s_dn(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002115 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brun87855892012-10-17 17:39:35 +02002116{
2117 X509 *crt = NULL;
2118 X509_NAME *name;
2119 int ret = 0;
2120 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002121 struct connection *conn;
Emeric Brun87855892012-10-17 17:39:35 +02002122
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002123 if (!l4)
Emeric Brun87855892012-10-17 17:39:35 +02002124 return 0;
2125
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002126 conn = objt_conn(l4->si[0].end);
2127 if (!conn || conn->xprt != &ssl_sock)
2128 return 0;
2129
2130 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun87855892012-10-17 17:39:35 +02002131 smp->flags |= SMP_F_MAY_CHANGE;
2132 return 0;
2133 }
2134
2135 /* SSL_get_peer_certificate, it increase X509 * ref count */
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002136 crt = SSL_get_peer_certificate(conn->xprt_ctx);
Emeric Brun87855892012-10-17 17:39:35 +02002137 if (!crt)
2138 goto out;
2139
2140 name = X509_get_subject_name(crt);
2141 if (!name)
2142 goto out;
2143
Willy Tarreau47ca5452012-12-23 20:22:19 +01002144 smp_trash = get_trash_chunk();
Emeric Brun87855892012-10-17 17:39:35 +02002145 if (args && args[0].type == ARGT_STR) {
2146 int pos = 1;
2147
2148 if (args[1].type == ARGT_SINT)
2149 pos = args[1].data.sint;
2150 else if (args[1].type == ARGT_UINT)
2151 pos =(int)args[1].data.uint;
2152
2153 if (ssl_sock_get_dn_entry(name, &args[0].data.str, pos, smp_trash) <= 0)
2154 goto out;
2155 }
2156 else if (ssl_sock_get_dn_oneline(name, smp_trash) <= 0)
2157 goto out;
2158
2159 smp->type = SMP_T_STR;
2160 smp->data.str = *smp_trash;
2161 ret = 1;
2162out:
2163 if (crt)
2164 X509_free(crt);
2165 return ret;
2166}
Emeric Brun9143d372012-12-20 15:44:16 +01002167
2168/* integer, returns true if current session use a client certificate */
2169static int
2170smp_fetch_ssl_c_used(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002171 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brun9143d372012-12-20 15:44:16 +01002172{
2173 X509 *crt;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002174 struct connection *conn;
Emeric Brun9143d372012-12-20 15:44:16 +01002175
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002176 if (!l4)
Emeric Brun9143d372012-12-20 15:44:16 +01002177 return 0;
2178
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002179 conn = objt_conn(l4->si[0].end);
2180 if (!conn || conn->xprt != &ssl_sock)
2181 return 0;
2182
2183 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun9143d372012-12-20 15:44:16 +01002184 smp->flags |= SMP_F_MAY_CHANGE;
2185 return 0;
2186 }
2187
2188 /* SSL_get_peer_certificate returns a ptr on allocated X509 struct */
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002189 crt = SSL_get_peer_certificate(conn->xprt_ctx);
Emeric Brun9143d372012-12-20 15:44:16 +01002190 if (crt) {
2191 X509_free(crt);
2192 }
2193
2194 smp->type = SMP_T_BOOL;
2195 smp->data.uint = (crt != NULL);
2196 return 1;
2197}
2198
Emeric Bruna7359fd2012-10-17 15:03:11 +02002199/* integer, returns the client certificate version */
2200static int
2201smp_fetch_ssl_c_version(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002202 const struct arg *args, struct sample *smp, const char *kw)
Emeric Bruna7359fd2012-10-17 15:03:11 +02002203{
2204 X509 *crt;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002205 struct connection *conn;
2206
2207 if (!l4)
2208 return 0;
Emeric Bruna7359fd2012-10-17 15:03:11 +02002209
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002210 conn = objt_conn(l4->si[0].end);
2211 if (!conn || conn->xprt != &ssl_sock)
Emeric Bruna7359fd2012-10-17 15:03:11 +02002212 return 0;
2213
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002214 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Bruna7359fd2012-10-17 15:03:11 +02002215 smp->flags |= SMP_F_MAY_CHANGE;
2216 return 0;
2217 }
2218
2219 /* SSL_get_peer_certificate returns a ptr on allocated X509 struct */
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002220 crt = SSL_get_peer_certificate(conn->xprt_ctx);
Emeric Bruna7359fd2012-10-17 15:03:11 +02002221 if (!crt)
2222 return 0;
2223
2224 smp->data.uint = (unsigned int)(1 + X509_get_version(crt));
2225 X509_free(crt);
2226 smp->type = SMP_T_UINT;
2227
2228 return 1;
2229}
2230
Emeric Brun7f56e742012-10-19 18:15:40 +02002231/* str, returns the client certificate sig alg */
2232static int
2233smp_fetch_ssl_c_sig_alg(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002234 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brun7f56e742012-10-19 18:15:40 +02002235{
2236 X509 *crt;
2237 int nid;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002238 struct connection *conn;
Emeric Brun7f56e742012-10-19 18:15:40 +02002239
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002240 if (!l4)
Emeric Brun7f56e742012-10-19 18:15:40 +02002241 return 0;
2242
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002243 conn = objt_conn(l4->si[0].end);
2244 if (!conn || conn->xprt != &ssl_sock)
2245 return 0;
2246
2247 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun7f56e742012-10-19 18:15:40 +02002248 smp->flags |= SMP_F_MAY_CHANGE;
2249 return 0;
2250 }
2251
2252 /* SSL_get_peer_certificate increase X509 * ref count */
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002253 crt = SSL_get_peer_certificate(conn->xprt_ctx);
Emeric Brun7f56e742012-10-19 18:15:40 +02002254 if (!crt)
2255 return 0;
2256
2257 nid = OBJ_obj2nid((ASN1_OBJECT *)(crt->cert_info->signature->algorithm));
2258
2259 smp->data.str.str = (char *)OBJ_nid2sn(nid);
Emeric Brun9bf3ba22013-10-07 14:31:44 +02002260 if (!smp->data.str.str) {
2261 X509_free(crt);
Emeric Brun7f56e742012-10-19 18:15:40 +02002262 return 0;
Emeric Brun9bf3ba22013-10-07 14:31:44 +02002263 }
Emeric Brun7f56e742012-10-19 18:15:40 +02002264
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01002265 smp->type = SMP_T_STR;
2266 smp->flags |= SMP_F_CONST;
Emeric Brun7f56e742012-10-19 18:15:40 +02002267 smp->data.str.len = strlen(smp->data.str.str);
2268 X509_free(crt);
2269
2270 return 1;
2271}
2272
Emeric Brun521a0112012-10-22 12:22:55 +02002273/* str, returns the client certificate key alg */
2274static int
2275smp_fetch_ssl_c_key_alg(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002276 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brun521a0112012-10-22 12:22:55 +02002277{
2278 X509 *crt;
2279 int nid;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002280 struct connection *conn;
Emeric Brun521a0112012-10-22 12:22:55 +02002281
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002282 if (!l4)
Emeric Brun521a0112012-10-22 12:22:55 +02002283 return 0;
2284
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002285 conn = objt_conn(l4->si[0].end);
2286 if (!conn || conn->xprt != &ssl_sock)
2287 return 0;
2288
2289 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun521a0112012-10-22 12:22:55 +02002290 smp->flags |= SMP_F_MAY_CHANGE;
2291 return 0;
2292 }
2293
2294 /* SSL_get_peer_certificate increase X509 * ref count */
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002295 crt = SSL_get_peer_certificate(conn->xprt_ctx);
Emeric Brun521a0112012-10-22 12:22:55 +02002296 if (!crt)
2297 return 0;
2298
2299 nid = OBJ_obj2nid((ASN1_OBJECT *)(crt->cert_info->key->algor->algorithm));
2300
2301 smp->data.str.str = (char *)OBJ_nid2sn(nid);
Emeric Brun9bf3ba22013-10-07 14:31:44 +02002302 if (!smp->data.str.str) {
2303 X509_free(crt);
Emeric Brun521a0112012-10-22 12:22:55 +02002304 return 0;
Emeric Brun9bf3ba22013-10-07 14:31:44 +02002305 }
Emeric Brun521a0112012-10-22 12:22:55 +02002306
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01002307 smp->type = SMP_T_STR;
2308 smp->flags |= SMP_F_CONST;
Emeric Brun521a0112012-10-22 12:22:55 +02002309 smp->data.str.len = strlen(smp->data.str.str);
2310 X509_free(crt);
2311
2312 return 1;
2313}
2314
Emeric Brun2525b6b2012-10-18 15:59:43 +02002315/* boolean, returns true if front conn. transport layer is SSL */
Willy Tarreau7875d092012-09-10 08:20:03 +02002316static int
Emeric Brun2525b6b2012-10-18 15:59:43 +02002317smp_fetch_ssl_fc(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002318 const struct arg *args, struct sample *smp, const char *kw)
Willy Tarreau7875d092012-09-10 08:20:03 +02002319{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002320 struct connection *conn = objt_conn(l4->si[0].end);
2321
Willy Tarreau7875d092012-09-10 08:20:03 +02002322 smp->type = SMP_T_BOOL;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002323 smp->data.uint = (conn && conn->xprt == &ssl_sock);
Willy Tarreau7875d092012-09-10 08:20:03 +02002324 return 1;
2325}
2326
Emeric Brun2525b6b2012-10-18 15:59:43 +02002327/* boolean, returns true if client present a SNI */
Willy Tarreau7875d092012-09-10 08:20:03 +02002328static int
Emeric Brun2525b6b2012-10-18 15:59:43 +02002329smp_fetch_ssl_fc_has_sni(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002330 const struct arg *args, struct sample *smp, const char *kw)
Willy Tarreau7875d092012-09-10 08:20:03 +02002331{
2332#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002333 struct connection *conn = objt_conn(l4->si[0].end);
2334
Willy Tarreau7875d092012-09-10 08:20:03 +02002335 smp->type = SMP_T_BOOL;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002336 smp->data.uint = (conn && conn->xprt == &ssl_sock) &&
2337 conn->xprt_ctx &&
2338 SSL_get_servername(conn->xprt_ctx, TLSEXT_NAMETYPE_host_name) != NULL;
Willy Tarreau7875d092012-09-10 08:20:03 +02002339 return 1;
2340#else
2341 return 0;
2342#endif
2343}
2344
Willy Tarreau8d598402012-10-22 17:58:39 +02002345/* bin, returns serial in a binary chunk */
2346static int
2347smp_fetch_ssl_f_serial(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002348 const struct arg *args, struct sample *smp, const char *kw)
Willy Tarreau8d598402012-10-22 17:58:39 +02002349{
2350 X509 *crt = NULL;
2351 int ret = 0;
2352 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002353 struct connection *conn;
2354
2355 if (!l4)
2356 return 0;
Willy Tarreau8d598402012-10-22 17:58:39 +02002357
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002358 conn = objt_conn(l4->si[0].end);
2359 if (!conn || conn->xprt != &ssl_sock)
Willy Tarreau8d598402012-10-22 17:58:39 +02002360 return 0;
2361
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002362 if (!(conn->flags & CO_FL_CONNECTED)) {
Willy Tarreau8d598402012-10-22 17:58:39 +02002363 smp->flags |= SMP_F_MAY_CHANGE;
2364 return 0;
2365 }
2366
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002367 crt = SSL_get_certificate(conn->xprt_ctx);
Willy Tarreau8d598402012-10-22 17:58:39 +02002368 if (!crt)
2369 goto out;
2370
Willy Tarreau47ca5452012-12-23 20:22:19 +01002371 smp_trash = get_trash_chunk();
Willy Tarreau8d598402012-10-22 17:58:39 +02002372 if (ssl_sock_get_serial(crt, smp_trash) <= 0)
2373 goto out;
2374
2375 smp->data.str = *smp_trash;
2376 smp->type = SMP_T_BIN;
2377 ret = 1;
2378out:
2379 return ret;
2380}
Emeric Brunce5ad802012-10-22 14:11:22 +02002381/*str, returns notafter date in ASN1_UTCTIME format */
2382static int
2383smp_fetch_ssl_f_notafter(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002384 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brunce5ad802012-10-22 14:11:22 +02002385{
2386 X509 *crt = NULL;
2387 int ret = 0;
2388 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002389 struct connection *conn;
Emeric Brunce5ad802012-10-22 14:11:22 +02002390
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002391 if (!l4)
Emeric Brunce5ad802012-10-22 14:11:22 +02002392 return 0;
2393
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002394 conn = objt_conn(l4->si[0].end);
2395 if (!conn || conn->xprt != &ssl_sock)
2396 return 0;
2397
2398 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunce5ad802012-10-22 14:11:22 +02002399 smp->flags |= SMP_F_MAY_CHANGE;
2400 return 0;
2401 }
2402
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002403 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brunce5ad802012-10-22 14:11:22 +02002404 if (!crt)
2405 goto out;
2406
Willy Tarreau47ca5452012-12-23 20:22:19 +01002407 smp_trash = get_trash_chunk();
Emeric Brunce5ad802012-10-22 14:11:22 +02002408 if (ssl_sock_get_time(X509_get_notAfter(crt), smp_trash) <= 0)
2409 goto out;
2410
2411 smp->data.str = *smp_trash;
2412 smp->type = SMP_T_STR;
2413 ret = 1;
2414out:
2415 return ret;
2416}
2417
2418/*str, returns notbefore date in ASN1_UTCTIME format */
2419static int
2420smp_fetch_ssl_f_notbefore(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002421 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brunce5ad802012-10-22 14:11:22 +02002422{
2423 X509 *crt = NULL;
2424 int ret = 0;
2425 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002426 struct connection *conn;
Emeric Brunce5ad802012-10-22 14:11:22 +02002427
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002428 if (!l4)
Emeric Brunce5ad802012-10-22 14:11:22 +02002429 return 0;
2430
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002431 conn = objt_conn(l4->si[0].end);
2432 if (!conn || conn->xprt != &ssl_sock)
2433 return 0;
2434
2435 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunce5ad802012-10-22 14:11:22 +02002436 smp->flags |= SMP_F_MAY_CHANGE;
2437 return 0;
2438 }
2439
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002440 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brunce5ad802012-10-22 14:11:22 +02002441 if (!crt)
2442 goto out;
2443
Willy Tarreau47ca5452012-12-23 20:22:19 +01002444 smp_trash = get_trash_chunk();
Emeric Brunce5ad802012-10-22 14:11:22 +02002445 if (ssl_sock_get_time(X509_get_notBefore(crt), smp_trash) <= 0)
2446 goto out;
2447
2448 smp->data.str = *smp_trash;
2449 smp->type = SMP_T_STR;
2450 ret = 1;
2451out:
2452 return ret;
2453}
Willy Tarreau8d598402012-10-22 17:58:39 +02002454
Emeric Bruna7359fd2012-10-17 15:03:11 +02002455/* integer, returns the frontend certificate version */
2456static int
2457smp_fetch_ssl_f_version(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002458 const struct arg *args, struct sample *smp, const char *kw)
Emeric Bruna7359fd2012-10-17 15:03:11 +02002459{
2460 X509 *crt;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002461 struct connection *conn;
Emeric Bruna7359fd2012-10-17 15:03:11 +02002462
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002463 if (!l4)
Emeric Bruna7359fd2012-10-17 15:03:11 +02002464 return 0;
2465
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002466 conn = objt_conn(l4->si[0].end);
2467 if (!conn || conn->xprt != &ssl_sock)
2468 return 0;
2469
2470 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Bruna7359fd2012-10-17 15:03:11 +02002471 smp->flags |= SMP_F_MAY_CHANGE;
2472 return 0;
2473 }
2474
2475 /* SSL_get_certificate returns a ptr on an SSL * internal sub struct */
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002476 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Bruna7359fd2012-10-17 15:03:11 +02002477 if (!crt)
2478 return 0;
2479
2480 smp->data.uint = (unsigned int)(1 + X509_get_version(crt));
2481 smp->type = SMP_T_UINT;
2482
2483 return 1;
2484}
2485
Emeric Brun7f56e742012-10-19 18:15:40 +02002486/* str, returns the client certificate sig alg */
2487static int
2488smp_fetch_ssl_f_sig_alg(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002489 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brun7f56e742012-10-19 18:15:40 +02002490{
2491 X509 *crt;
2492 int nid;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002493 struct connection *conn;
Emeric Brun7f56e742012-10-19 18:15:40 +02002494
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002495 if (!l4)
Emeric Brun7f56e742012-10-19 18:15:40 +02002496 return 0;
2497
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002498 conn = objt_conn(l4->si[0].end);
2499 if (!conn || conn->xprt != &ssl_sock)
2500 return 0;
2501
2502 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun7f56e742012-10-19 18:15:40 +02002503 smp->flags |= SMP_F_MAY_CHANGE;
2504 return 0;
2505 }
2506
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002507 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brun7f56e742012-10-19 18:15:40 +02002508 if (!crt)
2509 return 0;
2510
2511 nid = OBJ_obj2nid((ASN1_OBJECT *)(crt->cert_info->signature->algorithm));
2512
2513 smp->data.str.str = (char *)OBJ_nid2sn(nid);
2514 if (!smp->data.str.str)
2515 return 0;
2516
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01002517 smp->type = SMP_T_STR;
2518 smp->flags |= SMP_F_CONST;
Emeric Brun7f56e742012-10-19 18:15:40 +02002519 smp->data.str.len = strlen(smp->data.str.str);
2520
2521 return 1;
2522}
2523
Emeric Brun521a0112012-10-22 12:22:55 +02002524/* str, returns the client certificate key alg */
2525static int
2526smp_fetch_ssl_f_key_alg(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002527 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brun521a0112012-10-22 12:22:55 +02002528{
2529 X509 *crt;
2530 int nid;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002531 struct connection *conn;
2532
2533 if (!l4)
2534 return 0;
Emeric Brun521a0112012-10-22 12:22:55 +02002535
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002536 conn = objt_conn(l4->si[0].end);
2537 if (!conn || conn->xprt != &ssl_sock)
Emeric Brun521a0112012-10-22 12:22:55 +02002538 return 0;
2539
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002540 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun521a0112012-10-22 12:22:55 +02002541 smp->flags |= SMP_F_MAY_CHANGE;
2542 return 0;
2543 }
2544
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002545 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brun521a0112012-10-22 12:22:55 +02002546 if (!crt)
2547 return 0;
2548
2549 nid = OBJ_obj2nid((ASN1_OBJECT *)(crt->cert_info->key->algor->algorithm));
2550
2551 smp->data.str.str = (char *)OBJ_nid2sn(nid);
2552 if (!smp->data.str.str)
2553 return 0;
2554
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01002555 smp->type = SMP_T_STR;
2556 smp->flags |= SMP_F_CONST;
Emeric Brun521a0112012-10-22 12:22:55 +02002557 smp->data.str.len = strlen(smp->data.str.str);
2558
2559 return 1;
2560}
2561
Emeric Brun87855892012-10-17 17:39:35 +02002562/* str, returns a string of a formatted full dn \C=..\O=..\OU=.. \CN=.. */
2563static int
2564smp_fetch_ssl_f_i_dn(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002565 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brun87855892012-10-17 17:39:35 +02002566{
2567 X509 *crt = NULL;
2568 X509_NAME *name;
2569 int ret = 0;
2570 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002571 struct connection *conn;
2572
2573 if (!l4)
2574 return 0;
Emeric Brun87855892012-10-17 17:39:35 +02002575
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002576 conn = objt_conn(l4->si[0].end);
2577 if (!conn || conn->xprt != &ssl_sock)
Emeric Brun87855892012-10-17 17:39:35 +02002578 return 0;
2579
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002580 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun87855892012-10-17 17:39:35 +02002581 smp->flags |= SMP_F_MAY_CHANGE;
2582 return 0;
2583 }
2584
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002585 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brun87855892012-10-17 17:39:35 +02002586 if (!crt)
2587 goto out;
2588
2589 name = X509_get_issuer_name(crt);
2590 if (!name)
2591 goto out;
2592
Willy Tarreau47ca5452012-12-23 20:22:19 +01002593 smp_trash = get_trash_chunk();
Emeric Brun87855892012-10-17 17:39:35 +02002594 if (args && args[0].type == ARGT_STR) {
2595 int pos = 1;
2596
2597 if (args[1].type == ARGT_SINT)
2598 pos = args[1].data.sint;
2599 else if (args[1].type == ARGT_UINT)
2600 pos =(int)args[1].data.uint;
2601
2602 if (ssl_sock_get_dn_entry(name, &args[0].data.str, pos, smp_trash) <= 0)
2603 goto out;
2604 }
2605 else if (ssl_sock_get_dn_oneline(name, smp_trash) <= 0)
2606 goto out;
2607
2608 smp->type = SMP_T_STR;
2609 smp->data.str = *smp_trash;
2610 ret = 1;
2611out:
2612 return ret;
2613}
2614
2615/* str, returns a string of a formatted full dn \C=..\O=..\OU=.. \CN=.. */
2616static int
2617smp_fetch_ssl_f_s_dn(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002618 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brun87855892012-10-17 17:39:35 +02002619{
2620 X509 *crt = NULL;
2621 X509_NAME *name;
2622 int ret = 0;
2623 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002624 struct connection *conn;
2625
2626 if (!l4)
2627 return 0;
Emeric Brun87855892012-10-17 17:39:35 +02002628
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002629 conn = objt_conn(l4->si[0].end);
2630 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
Emeric Brun87855892012-10-17 17:39:35 +02002631 return 0;
2632
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002633 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun87855892012-10-17 17:39:35 +02002634 smp->flags |= SMP_F_MAY_CHANGE;
2635 return 0;
2636 }
2637
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002638 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brun87855892012-10-17 17:39:35 +02002639 if (!crt)
2640 goto out;
2641
2642 name = X509_get_subject_name(crt);
2643 if (!name)
2644 goto out;
2645
Willy Tarreau47ca5452012-12-23 20:22:19 +01002646 smp_trash = get_trash_chunk();
Emeric Brun87855892012-10-17 17:39:35 +02002647 if (args && args[0].type == ARGT_STR) {
2648 int pos = 1;
2649
2650 if (args[1].type == ARGT_SINT)
2651 pos = args[1].data.sint;
2652 else if (args[1].type == ARGT_UINT)
2653 pos =(int)args[1].data.uint;
2654
2655 if (ssl_sock_get_dn_entry(name, &args[0].data.str, pos, smp_trash) <= 0)
2656 goto out;
2657 }
2658 else if (ssl_sock_get_dn_oneline(name, smp_trash) <= 0)
2659 goto out;
2660
2661 smp->type = SMP_T_STR;
2662 smp->data.str = *smp_trash;
2663 ret = 1;
2664out:
2665 return ret;
2666}
2667
Emeric Brun589fcad2012-10-16 14:13:26 +02002668static int
2669smp_fetch_ssl_fc_cipher(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002670 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brun589fcad2012-10-16 14:13:26 +02002671{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002672 struct connection *conn;
2673
Emeric Brun589fcad2012-10-16 14:13:26 +02002674 smp->flags = 0;
2675
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002676 if (!l4)
2677 return 0;
2678
2679 conn = objt_conn(l4->si[0].end);
2680 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
Emeric Brun589fcad2012-10-16 14:13:26 +02002681 return 0;
2682
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002683 smp->data.str.str = (char *)SSL_get_cipher_name(conn->xprt_ctx);
Emeric Brun589fcad2012-10-16 14:13:26 +02002684 if (!smp->data.str.str)
2685 return 0;
2686
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01002687 smp->type = SMP_T_STR;
2688 smp->flags |= SMP_F_CONST;
Emeric Brun589fcad2012-10-16 14:13:26 +02002689 smp->data.str.len = strlen(smp->data.str.str);
2690
2691 return 1;
2692}
2693
2694static int
2695smp_fetch_ssl_fc_alg_keysize(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002696 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brun589fcad2012-10-16 14:13:26 +02002697{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002698 struct connection *conn;
2699
Emeric Brun589fcad2012-10-16 14:13:26 +02002700 smp->flags = 0;
2701
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002702 if (!l4)
Emeric Brun589fcad2012-10-16 14:13:26 +02002703 return 0;
2704
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002705 conn = objt_conn(l4->si[0].end);
2706 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
Emeric Brun589fcad2012-10-16 14:13:26 +02002707 return 0;
2708
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002709 if (!SSL_get_cipher_bits(conn->xprt_ctx, (int *)&smp->data.uint))
2710 return 0;
2711
Emeric Brun589fcad2012-10-16 14:13:26 +02002712 smp->type = SMP_T_UINT;
2713
2714 return 1;
2715}
2716
2717static int
2718smp_fetch_ssl_fc_use_keysize(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002719 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brun589fcad2012-10-16 14:13:26 +02002720{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002721 struct connection *conn;
2722
Emeric Brun589fcad2012-10-16 14:13:26 +02002723 smp->flags = 0;
2724
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002725 if (!l4)
Emeric Brun589fcad2012-10-16 14:13:26 +02002726 return 0;
2727
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002728 conn = objt_conn(l4->si[0].end);
2729 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
2730 return 0;
2731
2732 smp->data.uint = (unsigned int)SSL_get_cipher_bits(conn->xprt_ctx, NULL);
Emeric Brun589fcad2012-10-16 14:13:26 +02002733 if (!smp->data.uint)
2734 return 0;
2735
2736 smp->type = SMP_T_UINT;
2737
2738 return 1;
2739}
2740
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02002741#ifdef OPENSSL_NPN_NEGOTIATED
Willy Tarreau7875d092012-09-10 08:20:03 +02002742static int
Emeric Brun2525b6b2012-10-18 15:59:43 +02002743smp_fetch_ssl_fc_npn(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002744 const struct arg *args, struct sample *smp, const char *kw)
Willy Tarreaua33c6542012-10-15 13:19:06 +02002745{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002746 struct connection *conn;
2747
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01002748 smp->flags = SMP_F_CONST;
2749 smp->type = SMP_T_STR;
Willy Tarreaua33c6542012-10-15 13:19:06 +02002750
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002751 if (!l4)
Willy Tarreaua33c6542012-10-15 13:19:06 +02002752 return 0;
2753
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002754 conn = objt_conn(l4->si[0].end);
2755 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
2756 return 0;
2757
Willy Tarreaua33c6542012-10-15 13:19:06 +02002758 smp->data.str.str = NULL;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002759 SSL_get0_next_proto_negotiated(conn->xprt_ctx,
Willy Tarreaua33c6542012-10-15 13:19:06 +02002760 (const unsigned char **)&smp->data.str.str, (unsigned *)&smp->data.str.len);
2761
2762 if (!smp->data.str.str)
2763 return 0;
2764
2765 return 1;
Willy Tarreaua33c6542012-10-15 13:19:06 +02002766}
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02002767#endif
Willy Tarreaua33c6542012-10-15 13:19:06 +02002768
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01002769#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Willy Tarreauab861d32013-04-02 02:30:41 +02002770static int
2771smp_fetch_ssl_fc_alpn(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002772 const struct arg *args, struct sample *smp, const char *kw)
Willy Tarreauab861d32013-04-02 02:30:41 +02002773{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002774 struct connection *conn;
2775
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01002776 smp->flags = SMP_F_CONST;
2777 smp->type = SMP_T_STR;
Willy Tarreauab861d32013-04-02 02:30:41 +02002778
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002779 if (!l4)
2780 return 0;
2781
2782 conn = objt_conn(l4->si[0].end);
2783 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
Willy Tarreauab861d32013-04-02 02:30:41 +02002784 return 0;
2785
2786 smp->data.str.str = NULL;
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01002787 SSL_get0_alpn_selected(conn->xprt_ctx,
Willy Tarreauab861d32013-04-02 02:30:41 +02002788 (const unsigned char **)&smp->data.str.str, (unsigned *)&smp->data.str.len);
2789
2790 if (!smp->data.str.str)
2791 return 0;
2792
2793 return 1;
2794}
2795#endif
2796
Willy Tarreaua33c6542012-10-15 13:19:06 +02002797static int
Emeric Brun589fcad2012-10-16 14:13:26 +02002798smp_fetch_ssl_fc_protocol(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002799 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brun589fcad2012-10-16 14:13:26 +02002800{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002801 struct connection *conn;
2802
Emeric Brun589fcad2012-10-16 14:13:26 +02002803 smp->flags = 0;
2804
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002805 if (!l4)
Emeric Brun589fcad2012-10-16 14:13:26 +02002806 return 0;
2807
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002808 conn = objt_conn(l4->si[0].end);
2809 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
2810 return 0;
2811
2812 smp->data.str.str = (char *)SSL_get_version(conn->xprt_ctx);
Emeric Brun589fcad2012-10-16 14:13:26 +02002813 if (!smp->data.str.str)
2814 return 0;
2815
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01002816 smp->type = SMP_T_STR;
2817 smp->flags = SMP_F_CONST;
Emeric Brun589fcad2012-10-16 14:13:26 +02002818 smp->data.str.len = strlen(smp->data.str.str);
2819
2820 return 1;
2821}
2822
2823static int
Emeric Brunfe68f682012-10-16 14:59:28 +02002824smp_fetch_ssl_fc_session_id(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002825 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brunfe68f682012-10-16 14:59:28 +02002826{
2827#if OPENSSL_VERSION_NUMBER > 0x0090800fL
2828 SSL_SESSION *sess;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002829 struct connection *conn;
Emeric Brunfe68f682012-10-16 14:59:28 +02002830
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01002831 smp->flags = SMP_F_CONST;
2832 smp->type = SMP_T_BIN;
Emeric Brunfe68f682012-10-16 14:59:28 +02002833
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002834 if (!l4)
Emeric Brunfe68f682012-10-16 14:59:28 +02002835 return 0;
2836
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002837 conn = objt_conn(l4->si[0].end);
2838 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
2839 return 0;
2840
2841 sess = SSL_get_session(conn->xprt_ctx);
Emeric Brunfe68f682012-10-16 14:59:28 +02002842 if (!sess)
2843 return 0;
2844
2845 smp->data.str.str = (char *)SSL_SESSION_get_id(sess, (unsigned int *)&smp->data.str.len);
2846 if (!smp->data.str.str || !&smp->data.str.len)
2847 return 0;
2848
2849 return 1;
2850#else
2851 return 0;
2852#endif
2853}
2854
2855static int
Emeric Brun2525b6b2012-10-18 15:59:43 +02002856smp_fetch_ssl_fc_sni(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002857 const struct arg *args, struct sample *smp, const char *kw)
Willy Tarreau7875d092012-09-10 08:20:03 +02002858{
2859#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002860 struct connection *conn;
2861
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01002862 smp->flags = SMP_F_CONST;
2863 smp->type = SMP_T_STR;
Willy Tarreau7875d092012-09-10 08:20:03 +02002864
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002865 if (!l4)
Willy Tarreau7875d092012-09-10 08:20:03 +02002866 return 0;
2867
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002868 conn = objt_conn(l4->si[0].end);
2869 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
2870 return 0;
2871
2872 smp->data.str.str = (char *)SSL_get_servername(conn->xprt_ctx, TLSEXT_NAMETYPE_host_name);
Willy Tarreau3e394c92012-09-14 23:56:58 +02002873 if (!smp->data.str.str)
2874 return 0;
2875
Willy Tarreau7875d092012-09-10 08:20:03 +02002876 smp->data.str.len = strlen(smp->data.str.str);
2877 return 1;
2878#else
2879 return 0;
2880#endif
2881}
2882
David Sc1ad52e2014-04-08 18:48:47 -04002883static int
2884smp_fetch_ssl_fc_unique_id(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
2885 const struct arg *args, struct sample *smp, const char *kw)
2886{
2887#if OPENSSL_VERSION_NUMBER > 0x0090800fL
2888 struct connection *conn;
2889 int finished_len;
2890 int b64_len;
2891 struct chunk *finished_trash;
2892 struct chunk *smp_trash;
2893
2894 smp->flags = 0;
2895
2896 if (!l4)
2897 return 0;
2898
2899 conn = objt_conn(l4->si[0].end);
2900 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
2901 return 0;
2902
2903 if (!(conn->flags & CO_FL_CONNECTED)) {
2904 smp->flags |= SMP_F_MAY_CHANGE;
2905 return 0;
2906 }
2907
2908 finished_trash = get_trash_chunk();
2909 if (!SSL_session_reused(conn->xprt_ctx))
2910 finished_len = SSL_get_peer_finished(conn->xprt_ctx, finished_trash->str, finished_trash->size);
2911 else
2912 finished_len = SSL_get_finished(conn->xprt_ctx, finished_trash->str, finished_trash->size);
2913
2914 if (!finished_len)
2915 return 0;
2916
2917 smp_trash = get_trash_chunk();
2918 b64_len = a2base64(finished_trash->str, finished_len, smp_trash->str, smp_trash->size);
2919 if (b64_len < 0)
2920 return 0;
2921
2922 smp->data.str.str = smp_trash->str;
Willy Tarreau073edf32014-04-09 15:40:42 +02002923 smp->type = SMP_T_STR;
2924 smp->flags |= SMP_F_CONST;
David Sc1ad52e2014-04-08 18:48:47 -04002925 smp->data.str.len = b64_len;
2926
2927 return 1;
2928#else
2929 return 0;
2930#endif
2931}
2932
Emeric Brun2525b6b2012-10-18 15:59:43 +02002933/* integer, returns the first verify error in CA chain of client certificate chain. */
Emeric Brunf282a812012-09-21 15:27:54 +02002934static int
Emeric Brun2525b6b2012-10-18 15:59:43 +02002935smp_fetch_ssl_c_ca_err(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002936 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brunf282a812012-09-21 15:27:54 +02002937{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002938 struct connection *conn;
2939
2940 if (!l4)
Emeric Brunf282a812012-09-21 15:27:54 +02002941 return 0;
2942
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002943 conn = objt_conn(l4->si[0].end);
2944 if (!conn || conn->xprt != &ssl_sock)
2945 return 0;
2946
2947 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunf282a812012-09-21 15:27:54 +02002948 smp->flags = SMP_F_MAY_CHANGE;
2949 return 0;
2950 }
2951
2952 smp->type = SMP_T_UINT;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002953 smp->data.uint = (unsigned int)SSL_SOCK_ST_TO_CA_ERROR(conn->xprt_st);
Emeric Brunf282a812012-09-21 15:27:54 +02002954 smp->flags = 0;
2955
2956 return 1;
2957}
2958
Emeric Brun2525b6b2012-10-18 15:59:43 +02002959/* integer, returns the depth of the first verify error in CA chain of client certificate chain. */
Emeric Brunf282a812012-09-21 15:27:54 +02002960static int
Emeric Brun2525b6b2012-10-18 15:59:43 +02002961smp_fetch_ssl_c_ca_err_depth(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002962 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brunf282a812012-09-21 15:27:54 +02002963{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002964 struct connection *conn;
2965
2966 if (!l4)
2967 return 0;
2968
2969 conn = objt_conn(l4->si[0].end);
2970 if (!conn || conn->xprt != &ssl_sock)
Emeric Brunf282a812012-09-21 15:27:54 +02002971 return 0;
2972
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002973 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunf282a812012-09-21 15:27:54 +02002974 smp->flags = SMP_F_MAY_CHANGE;
2975 return 0;
2976 }
2977
2978 smp->type = SMP_T_UINT;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002979 smp->data.uint = (unsigned int)SSL_SOCK_ST_TO_CAEDEPTH(conn->xprt_st);
Emeric Brunf282a812012-09-21 15:27:54 +02002980 smp->flags = 0;
2981
2982 return 1;
2983}
2984
Emeric Brun2525b6b2012-10-18 15:59:43 +02002985/* integer, returns the first verify error on client certificate */
Emeric Brunf282a812012-09-21 15:27:54 +02002986static int
Emeric Brun2525b6b2012-10-18 15:59:43 +02002987smp_fetch_ssl_c_err(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002988 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brunf282a812012-09-21 15:27:54 +02002989{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002990 struct connection *conn;
2991
2992 if (!l4)
Emeric Brunf282a812012-09-21 15:27:54 +02002993 return 0;
2994
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002995 conn = objt_conn(l4->si[0].end);
2996 if (!conn || conn->xprt != &ssl_sock)
2997 return 0;
2998
2999 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunf282a812012-09-21 15:27:54 +02003000 smp->flags = SMP_F_MAY_CHANGE;
3001 return 0;
3002 }
3003
3004 smp->type = SMP_T_UINT;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003005 smp->data.uint = (unsigned int)SSL_SOCK_ST_TO_CRTERROR(conn->xprt_st);
Emeric Brunf282a812012-09-21 15:27:54 +02003006 smp->flags = 0;
3007
3008 return 1;
3009}
3010
Emeric Brun2525b6b2012-10-18 15:59:43 +02003011/* integer, returns the verify result on client cert */
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02003012static int
Emeric Brun2525b6b2012-10-18 15:59:43 +02003013smp_fetch_ssl_c_verify(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003014 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02003015{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003016 struct connection *conn;
3017
3018 if (!l4)
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02003019 return 0;
3020
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003021 conn = objt_conn(l4->si[0].end);
3022 if (!conn || conn->xprt != &ssl_sock)
3023 return 0;
3024
3025 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02003026 smp->flags = SMP_F_MAY_CHANGE;
3027 return 0;
3028 }
3029
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003030 if (!conn->xprt_ctx)
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02003031 return 0;
3032
3033 smp->type = SMP_T_UINT;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003034 smp->data.uint = (unsigned int)SSL_get_verify_result(conn->xprt_ctx);
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02003035 smp->flags = 0;
3036
3037 return 1;
3038}
3039
Emeric Brunfb510ea2012-10-05 12:00:26 +02003040/* parse the "ca-file" bind keyword */
3041static 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 +02003042{
3043 if (!*args[cur_arg + 1]) {
3044 if (err)
3045 memprintf(err, "'%s' : missing CAfile path", args[cur_arg]);
3046 return ERR_ALERT | ERR_FATAL;
3047 }
3048
Emeric Brunef42d922012-10-11 16:11:36 +02003049 if ((*args[cur_arg + 1] != '/') && global.ca_base)
3050 memprintf(&conf->ca_file, "%s/%s", global.ca_base, args[cur_arg + 1]);
3051 else
3052 memprintf(&conf->ca_file, "%s", args[cur_arg + 1]);
Emeric Brunc8e8d122012-10-02 18:42:10 +02003053
Emeric Brund94b3fe2012-09-20 18:23:56 +02003054 return 0;
3055}
3056
Willy Tarreau79eeafa2012-09-14 07:53:05 +02003057/* parse the "ciphers" bind keyword */
Willy Tarreau4348fad2012-09-20 16:48:07 +02003058static 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 +02003059{
3060 if (!*args[cur_arg + 1]) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02003061 memprintf(err, "'%s' : missing cipher suite", args[cur_arg]);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02003062 return ERR_ALERT | ERR_FATAL;
3063 }
3064
Emeric Brun76d88952012-10-05 15:47:31 +02003065 free(conf->ciphers);
Willy Tarreau4348fad2012-09-20 16:48:07 +02003066 conf->ciphers = strdup(args[cur_arg + 1]);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02003067 return 0;
3068}
3069
3070/* parse the "crt" bind keyword */
Willy Tarreau4348fad2012-09-20 16:48:07 +02003071static 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 +02003072{
Willy Tarreau38011032013-08-13 16:59:39 +02003073 char path[MAXPATHLEN];
Willy Tarreaub75d6922014-04-14 18:05:41 +02003074
Willy Tarreau79eeafa2012-09-14 07:53:05 +02003075 if (!*args[cur_arg + 1]) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02003076 memprintf(err, "'%s' : missing certificate location", args[cur_arg]);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02003077 return ERR_ALERT | ERR_FATAL;
3078 }
3079
Emeric Brunc8e8d122012-10-02 18:42:10 +02003080 if ((*args[cur_arg + 1] != '/' ) && global.crt_base) {
Willy Tarreau38011032013-08-13 16:59:39 +02003081 if ((strlen(global.crt_base) + 1 + strlen(args[cur_arg + 1]) + 1) > MAXPATHLEN) {
Emeric Brunc8e8d122012-10-02 18:42:10 +02003082 memprintf(err, "'%s' : path too long", args[cur_arg]);
3083 return ERR_ALERT | ERR_FATAL;
3084 }
Willy Tarreaub75d6922014-04-14 18:05:41 +02003085 snprintf(path, sizeof(path), "%s/%s", global.crt_base, args[cur_arg + 1]);
Emeric Brunc8e8d122012-10-02 18:42:10 +02003086 if (ssl_sock_load_cert(path, conf, px, err) > 0)
3087 return ERR_ALERT | ERR_FATAL;
3088
3089 return 0;
3090 }
3091
Willy Tarreau4348fad2012-09-20 16:48:07 +02003092 if (ssl_sock_load_cert(args[cur_arg + 1], conf, px, err) > 0)
Willy Tarreau79eeafa2012-09-14 07:53:05 +02003093 return ERR_ALERT | ERR_FATAL;
Emeric Brund94b3fe2012-09-20 18:23:56 +02003094
3095 return 0;
3096}
3097
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01003098/* parse the "crt-list" bind keyword */
3099static int bind_parse_crt_list(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
3100{
3101 if (!*args[cur_arg + 1]) {
3102 memprintf(err, "'%s' : missing certificate location", args[cur_arg]);
3103 return ERR_ALERT | ERR_FATAL;
3104 }
3105
Willy Tarreauad1731d2013-04-02 17:35:58 +02003106 if (ssl_sock_load_cert_list_file(args[cur_arg + 1], conf, px, err) > 0) {
3107 memprintf(err, "'%s' : %s", args[cur_arg], *err);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01003108 return ERR_ALERT | ERR_FATAL;
Willy Tarreauad1731d2013-04-02 17:35:58 +02003109 }
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01003110
3111 return 0;
3112}
3113
Emeric Brunfb510ea2012-10-05 12:00:26 +02003114/* parse the "crl-file" bind keyword */
3115static 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 +02003116{
Emeric Brun051cdab2012-10-02 19:25:50 +02003117#ifndef X509_V_FLAG_CRL_CHECK
3118 if (err)
3119 memprintf(err, "'%s' : library does not support CRL verify", args[cur_arg]);
3120 return ERR_ALERT | ERR_FATAL;
3121#else
Emeric Brund94b3fe2012-09-20 18:23:56 +02003122 if (!*args[cur_arg + 1]) {
3123 if (err)
3124 memprintf(err, "'%s' : missing CRLfile path", args[cur_arg]);
3125 return ERR_ALERT | ERR_FATAL;
3126 }
Emeric Brun2b58d042012-09-20 17:10:03 +02003127
Emeric Brunef42d922012-10-11 16:11:36 +02003128 if ((*args[cur_arg + 1] != '/') && global.ca_base)
3129 memprintf(&conf->crl_file, "%s/%s", global.ca_base, args[cur_arg + 1]);
3130 else
3131 memprintf(&conf->crl_file, "%s", args[cur_arg + 1]);
Emeric Brunc8e8d122012-10-02 18:42:10 +02003132
Emeric Brun2b58d042012-09-20 17:10:03 +02003133 return 0;
Emeric Brun051cdab2012-10-02 19:25:50 +02003134#endif
Emeric Brun2b58d042012-09-20 17:10:03 +02003135}
3136
3137/* parse the "ecdhe" bind keyword keywords */
3138static int bind_parse_ecdhe(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
3139{
3140#if OPENSSL_VERSION_NUMBER < 0x0090800fL
3141 if (err)
3142 memprintf(err, "'%s' : library does not support elliptic curve Diffie-Hellman (too old)", args[cur_arg]);
3143 return ERR_ALERT | ERR_FATAL;
3144#elif defined(OPENSSL_NO_ECDH)
3145 if (err)
3146 memprintf(err, "'%s' : library does not support elliptic curve Diffie-Hellman (disabled via OPENSSL_NO_ECDH)", args[cur_arg]);
3147 return ERR_ALERT | ERR_FATAL;
3148#else
3149 if (!*args[cur_arg + 1]) {
3150 if (err)
3151 memprintf(err, "'%s' : missing named curve", args[cur_arg]);
3152 return ERR_ALERT | ERR_FATAL;
3153 }
3154
3155 conf->ecdhe = strdup(args[cur_arg + 1]);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02003156
3157 return 0;
Emeric Brun2b58d042012-09-20 17:10:03 +02003158#endif
Willy Tarreau79eeafa2012-09-14 07:53:05 +02003159}
3160
Emeric Brun81c00f02012-09-21 14:31:21 +02003161/* parse the "crt_ignerr" and "ca_ignerr" bind keywords */
3162static int bind_parse_ignore_err(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
3163{
3164 int code;
3165 char *p = args[cur_arg + 1];
3166 unsigned long long *ignerr = &conf->crt_ignerr;
3167
3168 if (!*p) {
3169 if (err)
3170 memprintf(err, "'%s' : missing error IDs list", args[cur_arg]);
3171 return ERR_ALERT | ERR_FATAL;
3172 }
3173
3174 if (strcmp(args[cur_arg], "ca-ignore-err") == 0)
3175 ignerr = &conf->ca_ignerr;
3176
3177 if (strcmp(p, "all") == 0) {
3178 *ignerr = ~0ULL;
3179 return 0;
3180 }
3181
3182 while (p) {
3183 code = atoi(p);
3184 if ((code <= 0) || (code > 63)) {
3185 if (err)
3186 memprintf(err, "'%s' : ID '%d' out of range (1..63) in error IDs list '%s'",
3187 args[cur_arg], code, args[cur_arg + 1]);
3188 return ERR_ALERT | ERR_FATAL;
3189 }
3190 *ignerr |= 1ULL << code;
3191 p = strchr(p, ',');
3192 if (p)
3193 p++;
3194 }
3195
Emeric Brun2cb7ae52012-10-05 14:14:21 +02003196 return 0;
3197}
3198
3199/* parse the "force-sslv3" bind keyword */
3200static int bind_parse_force_sslv3(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
3201{
3202 conf->ssl_options |= BC_SSL_O_USE_SSLV3;
3203 return 0;
3204}
3205
3206/* parse the "force-tlsv10" bind keyword */
3207static int bind_parse_force_tlsv10(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
3208{
3209 conf->ssl_options |= BC_SSL_O_USE_TLSV10;
Emeric Brun2d0c4822012-10-02 13:45:20 +02003210 return 0;
3211}
3212
Emeric Brun2cb7ae52012-10-05 14:14:21 +02003213/* parse the "force-tlsv11" bind keyword */
3214static int bind_parse_force_tlsv11(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
3215{
3216#if SSL_OP_NO_TLSv1_1
3217 conf->ssl_options |= BC_SSL_O_USE_TLSV11;
3218 return 0;
3219#else
3220 if (err)
3221 memprintf(err, "'%s' : library does not support protocol TLSv1.1", args[cur_arg]);
3222 return ERR_ALERT | ERR_FATAL;
3223#endif
3224}
3225
3226/* parse the "force-tlsv12" bind keyword */
3227static int bind_parse_force_tlsv12(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
3228{
3229#if SSL_OP_NO_TLSv1_2
3230 conf->ssl_options |= BC_SSL_O_USE_TLSV12;
3231 return 0;
3232#else
3233 if (err)
3234 memprintf(err, "'%s' : library does not support protocol TLSv1.2", args[cur_arg]);
3235 return ERR_ALERT | ERR_FATAL;
3236#endif
3237}
3238
3239
Emeric Brun2d0c4822012-10-02 13:45:20 +02003240/* parse the "no-tls-tickets" bind keyword */
3241static int bind_parse_no_tls_tickets(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
3242{
Emeric Brun89675492012-10-05 13:48:26 +02003243 conf->ssl_options |= BC_SSL_O_NO_TLS_TICKETS;
Emeric Brun81c00f02012-09-21 14:31:21 +02003244 return 0;
3245}
3246
Emeric Brun2d0c4822012-10-02 13:45:20 +02003247
Emeric Brun9b3009b2012-10-05 11:55:06 +02003248/* parse the "no-sslv3" bind keyword */
3249static 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 +02003250{
Emeric Brun89675492012-10-05 13:48:26 +02003251 conf->ssl_options |= BC_SSL_O_NO_SSLV3;
Willy Tarreau79eeafa2012-09-14 07:53:05 +02003252 return 0;
3253}
3254
Emeric Brun9b3009b2012-10-05 11:55:06 +02003255/* parse the "no-tlsv10" bind keyword */
3256static 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 +02003257{
Emeric Brun89675492012-10-05 13:48:26 +02003258 conf->ssl_options |= BC_SSL_O_NO_TLSV10;
Emeric Brunc0ff4922012-09-28 19:37:02 +02003259 return 0;
3260}
3261
Emeric Brun9b3009b2012-10-05 11:55:06 +02003262/* parse the "no-tlsv11" bind keyword */
3263static 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 +02003264{
Emeric Brun89675492012-10-05 13:48:26 +02003265 conf->ssl_options |= BC_SSL_O_NO_TLSV11;
Emeric Brunc0ff4922012-09-28 19:37:02 +02003266 return 0;
3267}
3268
Emeric Brun9b3009b2012-10-05 11:55:06 +02003269/* parse the "no-tlsv12" bind keyword */
3270static 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 +02003271{
Emeric Brun89675492012-10-05 13:48:26 +02003272 conf->ssl_options |= BC_SSL_O_NO_TLSV12;
Willy Tarreau79eeafa2012-09-14 07:53:05 +02003273 return 0;
3274}
3275
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02003276/* parse the "npn" bind keyword */
3277static int bind_parse_npn(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
3278{
3279#ifdef OPENSSL_NPN_NEGOTIATED
3280 char *p1, *p2;
3281
3282 if (!*args[cur_arg + 1]) {
3283 memprintf(err, "'%s' : missing the comma-delimited NPN protocol suite", args[cur_arg]);
3284 return ERR_ALERT | ERR_FATAL;
3285 }
3286
3287 free(conf->npn_str);
3288
3289 /* the NPN string is built as a suite of (<len> <name>)* */
3290 conf->npn_len = strlen(args[cur_arg + 1]) + 1;
3291 conf->npn_str = calloc(1, conf->npn_len);
3292 memcpy(conf->npn_str + 1, args[cur_arg + 1], conf->npn_len);
3293
3294 /* replace commas with the name length */
3295 p1 = conf->npn_str;
3296 p2 = p1 + 1;
3297 while (1) {
3298 p2 = memchr(p1 + 1, ',', conf->npn_str + conf->npn_len - (p1 + 1));
3299 if (!p2)
3300 p2 = p1 + 1 + strlen(p1 + 1);
3301
3302 if (p2 - (p1 + 1) > 255) {
3303 *p2 = '\0';
3304 memprintf(err, "'%s' : NPN protocol name too long : '%s'", args[cur_arg], p1 + 1);
3305 return ERR_ALERT | ERR_FATAL;
3306 }
3307
3308 *p1 = p2 - (p1 + 1);
3309 p1 = p2;
3310
3311 if (!*p2)
3312 break;
3313
3314 *(p2++) = '\0';
3315 }
3316 return 0;
3317#else
3318 if (err)
3319 memprintf(err, "'%s' : library does not support TLS NPN extension", args[cur_arg]);
3320 return ERR_ALERT | ERR_FATAL;
3321#endif
3322}
3323
Willy Tarreauab861d32013-04-02 02:30:41 +02003324/* parse the "alpn" bind keyword */
3325static int bind_parse_alpn(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
3326{
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01003327#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Willy Tarreauab861d32013-04-02 02:30:41 +02003328 char *p1, *p2;
3329
3330 if (!*args[cur_arg + 1]) {
3331 memprintf(err, "'%s' : missing the comma-delimited ALPN protocol suite", args[cur_arg]);
3332 return ERR_ALERT | ERR_FATAL;
3333 }
3334
3335 free(conf->alpn_str);
3336
3337 /* the ALPN string is built as a suite of (<len> <name>)* */
3338 conf->alpn_len = strlen(args[cur_arg + 1]) + 1;
3339 conf->alpn_str = calloc(1, conf->alpn_len);
3340 memcpy(conf->alpn_str + 1, args[cur_arg + 1], conf->alpn_len);
3341
3342 /* replace commas with the name length */
3343 p1 = conf->alpn_str;
3344 p2 = p1 + 1;
3345 while (1) {
3346 p2 = memchr(p1 + 1, ',', conf->alpn_str + conf->alpn_len - (p1 + 1));
3347 if (!p2)
3348 p2 = p1 + 1 + strlen(p1 + 1);
3349
3350 if (p2 - (p1 + 1) > 255) {
3351 *p2 = '\0';
3352 memprintf(err, "'%s' : ALPN protocol name too long : '%s'", args[cur_arg], p1 + 1);
3353 return ERR_ALERT | ERR_FATAL;
3354 }
3355
3356 *p1 = p2 - (p1 + 1);
3357 p1 = p2;
3358
3359 if (!*p2)
3360 break;
3361
3362 *(p2++) = '\0';
3363 }
3364 return 0;
3365#else
3366 if (err)
3367 memprintf(err, "'%s' : library does not support TLS ALPN extension", args[cur_arg]);
3368 return ERR_ALERT | ERR_FATAL;
3369#endif
3370}
3371
Willy Tarreau79eeafa2012-09-14 07:53:05 +02003372/* parse the "ssl" bind keyword */
Willy Tarreau4348fad2012-09-20 16:48:07 +02003373static 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 +02003374{
Willy Tarreau81796be2012-09-22 19:11:47 +02003375 struct listener *l;
3376
Willy Tarreau4348fad2012-09-20 16:48:07 +02003377 conf->is_ssl = 1;
Emeric Brun76d88952012-10-05 15:47:31 +02003378
3379 if (global.listen_default_ciphers && !conf->ciphers)
3380 conf->ciphers = strdup(global.listen_default_ciphers);
3381
Willy Tarreau81796be2012-09-22 19:11:47 +02003382 list_for_each_entry(l, &conf->listeners, by_bind)
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02003383 l->xprt = &ssl_sock;
Willy Tarreau81796be2012-09-22 19:11:47 +02003384
Willy Tarreau79eeafa2012-09-14 07:53:05 +02003385 return 0;
3386}
3387
Emmanuel Hocdet65623372013-01-24 17:17:15 +01003388/* parse the "strict-sni" bind keyword */
3389static int bind_parse_strict_sni(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
3390{
3391 conf->strict_sni = 1;
3392 return 0;
3393}
3394
Emeric Brund94b3fe2012-09-20 18:23:56 +02003395/* parse the "verify" bind keyword */
3396static int bind_parse_verify(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
3397{
3398 if (!*args[cur_arg + 1]) {
3399 if (err)
3400 memprintf(err, "'%s' : missing verify method", args[cur_arg]);
3401 return ERR_ALERT | ERR_FATAL;
3402 }
3403
3404 if (strcmp(args[cur_arg + 1], "none") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01003405 conf->verify = SSL_SOCK_VERIFY_NONE;
Emeric Brund94b3fe2012-09-20 18:23:56 +02003406 else if (strcmp(args[cur_arg + 1], "optional") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01003407 conf->verify = SSL_SOCK_VERIFY_OPTIONAL;
Emeric Brund94b3fe2012-09-20 18:23:56 +02003408 else if (strcmp(args[cur_arg + 1], "required") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01003409 conf->verify = SSL_SOCK_VERIFY_REQUIRED;
Emeric Brund94b3fe2012-09-20 18:23:56 +02003410 else {
3411 if (err)
3412 memprintf(err, "'%s' : unknown verify method '%s', only 'none', 'optional', and 'required' are supported\n",
3413 args[cur_arg], args[cur_arg + 1]);
3414 return ERR_ALERT | ERR_FATAL;
3415 }
3416
3417 return 0;
3418}
3419
Willy Tarreau92faadf2012-10-10 23:04:25 +02003420/************** "server" keywords ****************/
3421
Emeric Brunef42d922012-10-11 16:11:36 +02003422/* parse the "ca-file" server keyword */
3423static int srv_parse_ca_file(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
3424{
3425 if (!*args[*cur_arg + 1]) {
3426 if (err)
3427 memprintf(err, "'%s' : missing CAfile path", args[*cur_arg]);
3428 return ERR_ALERT | ERR_FATAL;
3429 }
3430
3431 if ((*args[*cur_arg + 1] != '/') && global.ca_base)
3432 memprintf(&newsrv->ssl_ctx.ca_file, "%s/%s", global.ca_base, args[*cur_arg + 1]);
3433 else
3434 memprintf(&newsrv->ssl_ctx.ca_file, "%s", args[*cur_arg + 1]);
3435
3436 return 0;
3437}
3438
Willy Tarreau92faadf2012-10-10 23:04:25 +02003439/* parse the "check-ssl" server keyword */
3440static int srv_parse_check_ssl(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
3441{
3442 newsrv->check.use_ssl = 1;
3443 if (global.connect_default_ciphers && !newsrv->ssl_ctx.ciphers)
3444 newsrv->ssl_ctx.ciphers = strdup(global.connect_default_ciphers);
3445 return 0;
3446}
3447
3448/* parse the "ciphers" server keyword */
3449static int srv_parse_ciphers(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
3450{
3451 if (!*args[*cur_arg + 1]) {
3452 memprintf(err, "'%s' : missing cipher suite", args[*cur_arg]);
3453 return ERR_ALERT | ERR_FATAL;
3454 }
3455
3456 free(newsrv->ssl_ctx.ciphers);
3457 newsrv->ssl_ctx.ciphers = strdup(args[*cur_arg + 1]);
3458 return 0;
3459}
3460
Emeric Brunef42d922012-10-11 16:11:36 +02003461/* parse the "crl-file" server keyword */
3462static int srv_parse_crl_file(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
3463{
3464#ifndef X509_V_FLAG_CRL_CHECK
3465 if (err)
3466 memprintf(err, "'%s' : library does not support CRL verify", args[*cur_arg]);
3467 return ERR_ALERT | ERR_FATAL;
3468#else
3469 if (!*args[*cur_arg + 1]) {
3470 if (err)
3471 memprintf(err, "'%s' : missing CRLfile path", args[*cur_arg]);
3472 return ERR_ALERT | ERR_FATAL;
3473 }
3474
3475 if ((*args[*cur_arg + 1] != '/') && global.ca_base)
3476 memprintf(&newsrv->ssl_ctx.crl_file, "%s/%s", global.ca_base, args[*cur_arg + 1]);
3477 else
3478 memprintf(&newsrv->ssl_ctx.crl_file, "%s", args[*cur_arg + 1]);
3479
3480 return 0;
3481#endif
3482}
3483
Emeric Bruna7aa3092012-10-26 12:58:00 +02003484/* parse the "crt" server keyword */
3485static int srv_parse_crt(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
3486{
3487 if (!*args[*cur_arg + 1]) {
3488 if (err)
3489 memprintf(err, "'%s' : missing certificate file path", args[*cur_arg]);
3490 return ERR_ALERT | ERR_FATAL;
3491 }
3492
3493 if ((*args[*cur_arg + 1] != '/') && global.crt_base)
3494 memprintf(&newsrv->ssl_ctx.client_crt, "%s/%s", global.ca_base, args[*cur_arg + 1]);
3495 else
3496 memprintf(&newsrv->ssl_ctx.client_crt, "%s", args[*cur_arg + 1]);
3497
3498 return 0;
3499}
Emeric Brunef42d922012-10-11 16:11:36 +02003500
Willy Tarreau92faadf2012-10-10 23:04:25 +02003501/* parse the "force-sslv3" server keyword */
3502static int srv_parse_force_sslv3(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
3503{
3504 newsrv->ssl_ctx.options |= SRV_SSL_O_USE_SSLV3;
3505 return 0;
3506}
3507
3508/* parse the "force-tlsv10" server keyword */
3509static int srv_parse_force_tlsv10(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
3510{
3511 newsrv->ssl_ctx.options |= SRV_SSL_O_USE_TLSV10;
3512 return 0;
3513}
3514
3515/* parse the "force-tlsv11" server keyword */
3516static int srv_parse_force_tlsv11(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
3517{
3518#if SSL_OP_NO_TLSv1_1
3519 newsrv->ssl_ctx.options |= SRV_SSL_O_USE_TLSV11;
3520 return 0;
3521#else
3522 if (err)
3523 memprintf(err, "'%s' : library does not support protocol TLSv1.1", args[*cur_arg]);
3524 return ERR_ALERT | ERR_FATAL;
3525#endif
3526}
3527
3528/* parse the "force-tlsv12" server keyword */
3529static int srv_parse_force_tlsv12(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
3530{
3531#if SSL_OP_NO_TLSv1_2
3532 newsrv->ssl_ctx.options |= SRV_SSL_O_USE_TLSV12;
3533 return 0;
3534#else
3535 if (err)
3536 memprintf(err, "'%s' : library does not support protocol TLSv1.2", args[*cur_arg]);
3537 return ERR_ALERT | ERR_FATAL;
3538#endif
3539}
3540
3541/* parse the "no-sslv3" server keyword */
3542static int srv_parse_no_sslv3(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
3543{
3544 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_SSLV3;
3545 return 0;
3546}
3547
3548/* parse the "no-tlsv10" server keyword */
3549static int srv_parse_no_tlsv10(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
3550{
3551 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_TLSV10;
3552 return 0;
3553}
3554
3555/* parse the "no-tlsv11" server keyword */
3556static int srv_parse_no_tlsv11(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
3557{
3558 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_TLSV11;
3559 return 0;
3560}
3561
3562/* parse the "no-tlsv12" server keyword */
3563static int srv_parse_no_tlsv12(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
3564{
3565 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_TLSV12;
3566 return 0;
3567}
3568
Emeric Brunf9c5c472012-10-11 15:28:34 +02003569/* parse the "no-tls-tickets" server keyword */
3570static int srv_parse_no_tls_tickets(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
3571{
3572 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_TLS_TICKETS;
3573 return 0;
3574}
3575
Willy Tarreau92faadf2012-10-10 23:04:25 +02003576/* parse the "ssl" server keyword */
3577static int srv_parse_ssl(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
3578{
3579 newsrv->use_ssl = 1;
3580 if (global.connect_default_ciphers && !newsrv->ssl_ctx.ciphers)
3581 newsrv->ssl_ctx.ciphers = strdup(global.connect_default_ciphers);
3582 return 0;
3583}
3584
Emeric Brunef42d922012-10-11 16:11:36 +02003585/* parse the "verify" server keyword */
3586static int srv_parse_verify(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
3587{
3588 if (!*args[*cur_arg + 1]) {
3589 if (err)
3590 memprintf(err, "'%s' : missing verify method", args[*cur_arg]);
3591 return ERR_ALERT | ERR_FATAL;
3592 }
3593
3594 if (strcmp(args[*cur_arg + 1], "none") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01003595 newsrv->ssl_ctx.verify = SSL_SOCK_VERIFY_NONE;
Emeric Brunef42d922012-10-11 16:11:36 +02003596 else if (strcmp(args[*cur_arg + 1], "required") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01003597 newsrv->ssl_ctx.verify = SSL_SOCK_VERIFY_REQUIRED;
Emeric Brunef42d922012-10-11 16:11:36 +02003598 else {
3599 if (err)
3600 memprintf(err, "'%s' : unknown verify method '%s', only 'none' and 'required' are supported\n",
3601 args[*cur_arg], args[*cur_arg + 1]);
3602 return ERR_ALERT | ERR_FATAL;
3603 }
3604
Evan Broderbe554312013-06-27 00:05:25 -07003605 return 0;
3606}
3607
3608/* parse the "verifyhost" server keyword */
3609static int srv_parse_verifyhost(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
3610{
3611 if (!*args[*cur_arg + 1]) {
3612 if (err)
3613 memprintf(err, "'%s' : missing hostname to verify against", args[*cur_arg]);
3614 return ERR_ALERT | ERR_FATAL;
3615 }
3616
3617 newsrv->ssl_ctx.verify_host = strdup(args[*cur_arg + 1]);
3618
Emeric Brunef42d922012-10-11 16:11:36 +02003619 return 0;
3620}
3621
Willy Tarreau7875d092012-09-10 08:20:03 +02003622/* Note: must not be declared <const> as its list will be overwritten.
3623 * Please take care of keeping this list alphabetically sorted.
3624 */
Willy Tarreaudc13c112013-06-21 23:16:39 +02003625static struct sample_fetch_kw_list sample_fetch_keywords = {ILH, {
Willy Tarreau80aca902013-01-07 15:42:20 +01003626 { "ssl_c_ca_err", smp_fetch_ssl_c_ca_err, 0, NULL, SMP_T_UINT, SMP_USE_L5CLI },
3627 { "ssl_c_ca_err_depth", smp_fetch_ssl_c_ca_err_depth, 0, NULL, SMP_T_UINT, SMP_USE_L5CLI },
3628 { "ssl_c_err", smp_fetch_ssl_c_err, 0, NULL, SMP_T_UINT, SMP_USE_L5CLI },
3629 { "ssl_c_i_dn", smp_fetch_ssl_c_i_dn, ARG2(0,STR,SINT), NULL, SMP_T_STR, SMP_USE_L5CLI },
3630 { "ssl_c_key_alg", smp_fetch_ssl_c_key_alg, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
3631 { "ssl_c_notafter", smp_fetch_ssl_c_notafter, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
3632 { "ssl_c_notbefore", smp_fetch_ssl_c_notbefore, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
3633 { "ssl_c_sig_alg", smp_fetch_ssl_c_sig_alg, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
3634 { "ssl_c_s_dn", smp_fetch_ssl_c_s_dn, ARG2(0,STR,SINT), NULL, SMP_T_STR, SMP_USE_L5CLI },
3635 { "ssl_c_serial", smp_fetch_ssl_c_serial, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
James Votha051b4a2013-05-14 20:37:59 +02003636 { "ssl_c_sha1", smp_fetch_ssl_c_sha1, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Willy Tarreau80aca902013-01-07 15:42:20 +01003637 { "ssl_c_used", smp_fetch_ssl_c_used, 0, NULL, SMP_T_BOOL, SMP_USE_L5CLI },
3638 { "ssl_c_verify", smp_fetch_ssl_c_verify, 0, NULL, SMP_T_UINT, SMP_USE_L5CLI },
3639 { "ssl_c_version", smp_fetch_ssl_c_version, 0, NULL, SMP_T_UINT, SMP_USE_L5CLI },
3640 { "ssl_f_i_dn", smp_fetch_ssl_f_i_dn, ARG2(0,STR,SINT), NULL, SMP_T_STR, SMP_USE_L5CLI },
3641 { "ssl_f_key_alg", smp_fetch_ssl_f_key_alg, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
3642 { "ssl_f_notafter", smp_fetch_ssl_f_notafter, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
3643 { "ssl_f_notbefore", smp_fetch_ssl_f_notbefore, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
3644 { "ssl_f_sig_alg", smp_fetch_ssl_f_sig_alg, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
3645 { "ssl_f_s_dn", smp_fetch_ssl_f_s_dn, ARG2(0,STR,SINT), NULL, SMP_T_STR, SMP_USE_L5CLI },
3646 { "ssl_f_serial", smp_fetch_ssl_f_serial, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
3647 { "ssl_f_version", smp_fetch_ssl_f_version, 0, NULL, SMP_T_UINT, SMP_USE_L5CLI },
3648 { "ssl_fc", smp_fetch_ssl_fc, 0, NULL, SMP_T_BOOL, SMP_USE_L5CLI },
3649 { "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 +01003650 { "ssl_fc_cipher", smp_fetch_ssl_fc_cipher, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Willy Tarreau80aca902013-01-07 15:42:20 +01003651 { "ssl_fc_has_crt", smp_fetch_ssl_fc_has_crt, 0, NULL, SMP_T_BOOL, SMP_USE_L5CLI },
3652 { "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 +02003653#ifdef OPENSSL_NPN_NEGOTIATED
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01003654 { "ssl_fc_npn", smp_fetch_ssl_fc_npn, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Willy Tarreaua33c6542012-10-15 13:19:06 +02003655#endif
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01003656#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01003657 { "ssl_fc_alpn", smp_fetch_ssl_fc_alpn, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Willy Tarreauab861d32013-04-02 02:30:41 +02003658#endif
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01003659 { "ssl_fc_protocol", smp_fetch_ssl_fc_protocol, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Willy Tarreau073edf32014-04-09 15:40:42 +02003660 { "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 +01003661 { "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 +01003662 { "ssl_fc_session_id", smp_fetch_ssl_fc_session_id, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
3663 { "ssl_fc_sni", smp_fetch_ssl_fc_sni, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Willy Tarreau7875d092012-09-10 08:20:03 +02003664 { NULL, NULL, 0, 0, 0 },
3665}};
3666
3667/* Note: must not be declared <const> as its list will be overwritten.
3668 * Please take care of keeping this list alphabetically sorted.
3669 */
Willy Tarreaudc13c112013-06-21 23:16:39 +02003670static struct acl_kw_list acl_kws = {ILH, {
Thierry FOURNIERc5a4e982014-03-05 16:07:08 +01003671 { "ssl_c_i_dn", NULL, PAT_MATCH_STR },
3672 { "ssl_c_key_alg", NULL, PAT_MATCH_STR },
3673 { "ssl_c_notafter", NULL, PAT_MATCH_STR },
3674 { "ssl_c_notbefore", NULL, PAT_MATCH_STR },
3675 { "ssl_c_sig_alg", NULL, PAT_MATCH_STR },
3676 { "ssl_c_s_dn", NULL, PAT_MATCH_STR },
3677 { "ssl_c_serial", NULL, PAT_MATCH_BIN },
3678 { "ssl_f_i_dn", NULL, PAT_MATCH_STR },
3679 { "ssl_f_key_alg", NULL, PAT_MATCH_STR },
3680 { "ssl_f_notafter", NULL, PAT_MATCH_STR },
3681 { "ssl_f_notbefore", NULL, PAT_MATCH_STR },
3682 { "ssl_f_sig_alg", NULL, PAT_MATCH_STR },
3683 { "ssl_f_s_dn", NULL, PAT_MATCH_STR },
3684 { "ssl_f_serial", NULL, PAT_MATCH_BIN },
3685 { "ssl_fc_cipher", NULL, PAT_MATCH_STR },
Willy Tarreaua33c6542012-10-15 13:19:06 +02003686#ifdef OPENSSL_NPN_NEGOTIATED
Thierry FOURNIERc5a4e982014-03-05 16:07:08 +01003687 { "ssl_fc_npn", NULL, PAT_MATCH_STR },
Willy Tarreaua33c6542012-10-15 13:19:06 +02003688#endif
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01003689#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Thierry FOURNIERc5a4e982014-03-05 16:07:08 +01003690 { "ssl_fc_alpn", NULL, PAT_MATCH_STR },
Willy Tarreauab861d32013-04-02 02:30:41 +02003691#endif
Thierry FOURNIERc5a4e982014-03-05 16:07:08 +01003692 { "ssl_fc_protocol", NULL, PAT_MATCH_STR },
3693 { "ssl_fc_sni", "ssl_fc_sni", PAT_MATCH_STR },
3694 { "ssl_fc_sni_end", "ssl_fc_sni", PAT_MATCH_END },
3695 { "ssl_fc_sni_reg", "ssl_fc_sni", PAT_MATCH_REG },
Willy Tarreau8ed669b2013-01-11 15:49:37 +01003696 { /* END */ },
Willy Tarreau7875d092012-09-10 08:20:03 +02003697}};
3698
Willy Tarreau79eeafa2012-09-14 07:53:05 +02003699/* Note: must not be declared <const> as its list will be overwritten.
3700 * Please take care of keeping this list alphabetically sorted, doing so helps
3701 * all code contributors.
3702 * Optional keywords are also declared with a NULL ->parse() function so that
3703 * the config parser can report an appropriate error when a known keyword was
3704 * not enabled.
3705 */
Willy Tarreau51fb7652012-09-18 18:24:39 +02003706static struct bind_kw_list bind_kws = { "SSL", { }, {
Willy Tarreauab861d32013-04-02 02:30:41 +02003707 { "alpn", bind_parse_alpn, 1 }, /* set ALPN supported protocols */
Emeric Brunfb510ea2012-10-05 12:00:26 +02003708 { "ca-file", bind_parse_ca_file, 1 }, /* set CAfile to process verify on client cert */
Emeric Brun2d0c4822012-10-02 13:45:20 +02003709 { "ca-ignore-err", bind_parse_ignore_err, 1 }, /* set error IDs to ignore on verify depth > 0 */
3710 { "ciphers", bind_parse_ciphers, 1 }, /* set SSL cipher suite */
Emeric Brunfb510ea2012-10-05 12:00:26 +02003711 { "crl-file", bind_parse_crl_file, 1 }, /* set certificat revocation list file use on client cert verify */
Emeric Brun2d0c4822012-10-02 13:45:20 +02003712 { "crt", bind_parse_crt, 1 }, /* load SSL certificates from this location */
3713 { "crt-ignore-err", bind_parse_ignore_err, 1 }, /* set error IDs to ingore on verify depth == 0 */
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01003714 { "crt-list", bind_parse_crt_list, 1 }, /* load a list of crt from this location */
Emeric Brun2d0c4822012-10-02 13:45:20 +02003715 { "ecdhe", bind_parse_ecdhe, 1 }, /* defines named curve for elliptic curve Diffie-Hellman */
Emeric Brun2cb7ae52012-10-05 14:14:21 +02003716 { "force-sslv3", bind_parse_force_sslv3, 0 }, /* force SSLv3 */
3717 { "force-tlsv10", bind_parse_force_tlsv10, 0 }, /* force TLSv10 */
3718 { "force-tlsv11", bind_parse_force_tlsv11, 0 }, /* force TLSv11 */
3719 { "force-tlsv12", bind_parse_force_tlsv12, 0 }, /* force TLSv12 */
Emeric Brun9b3009b2012-10-05 11:55:06 +02003720 { "no-sslv3", bind_parse_no_sslv3, 0 }, /* disable SSLv3 */
3721 { "no-tlsv10", bind_parse_no_tlsv10, 0 }, /* disable TLSv10 */
3722 { "no-tlsv11", bind_parse_no_tlsv11, 0 }, /* disable TLSv11 */
3723 { "no-tlsv12", bind_parse_no_tlsv12, 0 }, /* disable TLSv12 */
Emeric Brun2d0c4822012-10-02 13:45:20 +02003724 { "no-tls-tickets", bind_parse_no_tls_tickets, 0 }, /* disable session resumption tickets */
Emeric Brun2d0c4822012-10-02 13:45:20 +02003725 { "ssl", bind_parse_ssl, 0 }, /* enable SSL processing */
Emmanuel Hocdet65623372013-01-24 17:17:15 +01003726 { "strict-sni", bind_parse_strict_sni, 0 }, /* refuse negotiation if sni doesn't match a certificate */
Emeric Brun2d0c4822012-10-02 13:45:20 +02003727 { "verify", bind_parse_verify, 1 }, /* set SSL verify method */
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02003728 { "npn", bind_parse_npn, 1 }, /* set NPN supported protocols */
Willy Tarreau79eeafa2012-09-14 07:53:05 +02003729 { NULL, NULL, 0 },
3730}};
Emeric Brun46591952012-05-18 15:47:34 +02003731
Willy Tarreau92faadf2012-10-10 23:04:25 +02003732/* Note: must not be declared <const> as its list will be overwritten.
3733 * Please take care of keeping this list alphabetically sorted, doing so helps
3734 * all code contributors.
3735 * Optional keywords are also declared with a NULL ->parse() function so that
3736 * the config parser can report an appropriate error when a known keyword was
3737 * not enabled.
3738 */
3739static struct srv_kw_list srv_kws = { "SSL", { }, {
Emeric Brunef42d922012-10-11 16:11:36 +02003740 { "ca-file", srv_parse_ca_file, 1, 0 }, /* set CAfile to process verify server cert */
Emeric Brunecc91fe2012-10-11 15:05:10 +02003741 { "check-ssl", srv_parse_check_ssl, 0, 0 }, /* enable SSL for health checks */
3742 { "ciphers", srv_parse_ciphers, 1, 0 }, /* select the cipher suite */
Emeric Brunef42d922012-10-11 16:11:36 +02003743 { "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 +02003744 { "crt", srv_parse_crt, 1, 0 }, /* set client certificate */
Emeric Brunecc91fe2012-10-11 15:05:10 +02003745 { "force-sslv3", srv_parse_force_sslv3, 0, 0 }, /* force SSLv3 */
3746 { "force-tlsv10", srv_parse_force_tlsv10, 0, 0 }, /* force TLSv10 */
3747 { "force-tlsv11", srv_parse_force_tlsv11, 0, 0 }, /* force TLSv11 */
3748 { "force-tlsv12", srv_parse_force_tlsv12, 0, 0 }, /* force TLSv12 */
3749 { "no-sslv3", srv_parse_no_sslv3, 0, 0 }, /* disable SSLv3 */
3750 { "no-tlsv10", srv_parse_no_tlsv10, 0, 0 }, /* disable TLSv10 */
3751 { "no-tlsv11", srv_parse_no_tlsv11, 0, 0 }, /* disable TLSv11 */
3752 { "no-tlsv12", srv_parse_no_tlsv12, 0, 0 }, /* disable TLSv12 */
Emeric Brunf9c5c472012-10-11 15:28:34 +02003753 { "no-tls-tickets", srv_parse_no_tls_tickets, 0, 0 }, /* disable session resumption tickets */
Emeric Brunecc91fe2012-10-11 15:05:10 +02003754 { "ssl", srv_parse_ssl, 0, 0 }, /* enable SSL processing */
Emeric Brunef42d922012-10-11 16:11:36 +02003755 { "verify", srv_parse_verify, 1, 0 }, /* set SSL verify method */
Evan Broderbe554312013-06-27 00:05:25 -07003756 { "verifyhost", srv_parse_verifyhost, 1, 0 }, /* require that SSL cert verifies for hostname */
Willy Tarreau92faadf2012-10-10 23:04:25 +02003757 { NULL, NULL, 0, 0 },
3758}};
3759
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02003760/* transport-layer operations for SSL sockets */
3761struct xprt_ops ssl_sock = {
Emeric Brun46591952012-05-18 15:47:34 +02003762 .snd_buf = ssl_sock_from_buf,
3763 .rcv_buf = ssl_sock_to_buf,
3764 .rcv_pipe = NULL,
3765 .snd_pipe = NULL,
3766 .shutr = NULL,
3767 .shutw = ssl_sock_shutw,
3768 .close = ssl_sock_close,
3769 .init = ssl_sock_init,
3770};
3771
3772__attribute__((constructor))
Willy Tarreau92faadf2012-10-10 23:04:25 +02003773static void __ssl_sock_init(void)
3774{
Emeric Brun46591952012-05-18 15:47:34 +02003775 STACK_OF(SSL_COMP)* cm;
3776
Willy Tarreau610f04b2014-02-13 11:36:41 +01003777#ifdef LISTEN_DEFAULT_CIPHERS
3778 global.listen_default_ciphers = LISTEN_DEFAULT_CIPHERS;
3779#endif
3780#ifdef CONNECT_DEFAULT_CIPHERS
3781 global.connect_default_ciphers = CONNECT_DEFAULT_CIPHERS;
3782#endif
3783 if (global.listen_default_ciphers)
3784 global.listen_default_ciphers = strdup(global.listen_default_ciphers);
3785 if (global.connect_default_ciphers)
3786 global.connect_default_ciphers = strdup(global.connect_default_ciphers);
3787
Emeric Brun46591952012-05-18 15:47:34 +02003788 SSL_library_init();
3789 cm = SSL_COMP_get_compression_methods();
3790 sk_SSL_COMP_zero(cm);
Willy Tarreau7875d092012-09-10 08:20:03 +02003791 sample_register_fetches(&sample_fetch_keywords);
3792 acl_register_keywords(&acl_kws);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02003793 bind_register_keywords(&bind_kws);
Willy Tarreau92faadf2012-10-10 23:04:25 +02003794 srv_register_keywords(&srv_kws);
Emeric Brun46591952012-05-18 15:47:34 +02003795}
3796
3797/*
3798 * Local variables:
3799 * c-indent-level: 8
3800 * c-basic-offset: 8
3801 * End:
3802 */